pax_global_header00006660000000000000000000000064146427314440014523gustar00rootroot0000000000000052 comment=18524c6e89071fbaf0592790f0f1da7a64107959 faraday-2.10.0/000077500000000000000000000000001464273144400132125ustar00rootroot00000000000000faraday-2.10.0/.editorconfig000066400000000000000000000002231464273144400156640ustar00rootroot00000000000000root = true [*] indent_style = space indent_size = 2 end_of_line = lf charset = utf-8 trim_trailing_whitespace = true insert_final_newline = true faraday-2.10.0/.github/000077500000000000000000000000001464273144400145525ustar00rootroot00000000000000faraday-2.10.0/.github/CODE_OF_CONDUCT.md000066400000000000000000000062401464273144400173530ustar00rootroot00000000000000# Contributor Covenant Code of Conduct ## Our Pledge In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation. ## Our Standards Examples of behavior that contributes to creating a positive environment include: * Using welcoming and inclusive language * Being respectful of differing viewpoints and experiences * Gracefully accepting constructive criticism * Focusing on what is best for the community * Showing empathy towards other community members Examples of unacceptable behavior by participants include: * The use of sexualized language or imagery and unwelcome sexual attention or advances * Trolling, insulting/derogatory comments, and personal or political attacks * Public or private harassment * Publishing others' private information, such as a physical or electronic address, without explicit permission * Other conduct which could reasonably be considered inappropriate in a professional setting ## Our Responsibilities Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior. Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful. ## Scope This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers. ## Enforcement Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project maintainer at giuffrida.mattia AT gmail.com. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately. Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership. ## Attribution This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version] [homepage]: http://contributor-covenant.org [version]: http://contributor-covenant.org/version/1/4/ faraday-2.10.0/.github/CONTRIBUTING.md000066400000000000000000000071211464273144400170040ustar00rootroot00000000000000## Contributing In Faraday we always welcome new ideas and features, however we also have to ensure that the overall code quality stays on reasonable levels. For this reason, before adding any contribution to Faraday, we highly recommend reading this quick guide to ensure your PR can be reviewed and approved as quickly as possible. We are past our 1.0 release, and follow [Semantic Versioning][semver]. If your patch includes changes that break compatibility, note that in the Pull Request, so we can add it to the [Changelog][]. ### Policy on inclusive language You have read our [Code of Conduct][], which includes a note about **inclusive language**. This section tries to make that actionable. Faraday has a large and diverse userbase. To make Faraday a pleasant and effective experience for everyone, we use inclusive language. These resources can help: - Google's tutorial [Writing inclusive documentation](https://developers.google.com/style/inclusive-documentation) teaches by example, how to reword non-inclusive things. - Linux kernel mailing list's [Coding Style: Inclusive Terminology](https://lkml.org/lkml/2020/7/4/229) said "Add no new instances of non-inclusive words, here is a list of words not include new ones of." - Linguistic Society of America published [Guidelines for Inclusive Language](https://www.linguisticsociety.org/resource/guidelines-inclusive-language) which concluded: "We encourage all linguists to consider the possible reactions of their potential audience to their writing and, in so doing, to choose expository practices and content that is positive, inclusive, and respectful." This project attempts to improve in these areas. Join us in doing that important work. If you want to privately raise any breach to this policy with the Faraday team, feel free to reach out to [@iMacTia](https://twitter.com/iMacTia) and [@olleolleolle](https://twitter.com/olleolleolle) on Twitter. ### Required Checks Before pushing your code and opening a PR, we recommend you run the following checks to avoid our GitHub Actions Workflow to block your contribution. ```bash # Run unit tests and check code coverage $ bundle exec rspec # Check code style $ bundle exec rubocop ``` ### New Features When adding a feature in Faraday: 1. also add tests to cover your new feature. 2. if the feature is for an adapter, the **attempt** must be made to add the same feature to all other adapters as well. 3. start opening an issue describing how the new feature will work, and only after receiving the green light by the core team start working on the PR. ### New Middleware & Adapters We prefer new adapters and middlewares to be added **as separate gems**. We can link to such gems from this project. This goes for the [faraday_middleware][] project as well. We encourage adapters that: 1. support SSL & streaming; 1. are proven and may have better performance than existing ones; or 1. have features not present in included adapters. ### Changes to the Faraday Docs The Faraday Docs are included in the Faraday repository, under the `/docs` folder and deployed to [GitHub Pages][website]. If you want to apply changes to it, please test it locally before opening your PR. You can find more information in the [Faraday Docs README][docs], including how to preview changes locally. [semver]: https://semver.org/ [changelog]: https://github.com/lostisland/faraday/releases [faraday_middleware]: https://github.com/lostisland/faraday_middleware [website]: https://lostisland.github.io/faraday [docs]: ../docs/README.md [Code of Conduct]: ./CODE_OF_CONDUCT.md faraday-2.10.0/.github/ISSUE_TEMPLATE.md000066400000000000000000000014401464273144400172560ustar00rootroot00000000000000## Basic Info * Faraday Version: * Ruby Version: ## Issue description Please provide a description of the issue you're experiencing. Please also provide the exception message/stacktrace or any other useful detail. ## Steps to reproduce If possible, please provide the steps to reproduce the issue. ## CHECKLIST (delete before creating the issue) * If you're not reporting a bug/issue, you can ignore this whole template. * Are you using the latest Faraday version? If not, please check the [Releases](https://github.com/lostisland/faraday/releases) page to see if the issue has already been fixed. * Provide the Faraday and Ruby Version you're using while experiencing the issue. * Fill the `Issue description` and `Steps to Reproduce` sections. * Delete this checklist before posting the issue. faraday-2.10.0/.github/PULL_REQUEST_TEMPLATE.md000066400000000000000000000004201464273144400203470ustar00rootroot00000000000000## Description A few sentences describing the overall goals of the pull request's commits. Link to related issues if any. (As `Fixes #XXX`) ## Todos List any remaining work that needs to be done, i.e: - [ ] Tests - [ ] Documentation ## Additional Notes Optional section faraday-2.10.0/.github/dependabot.yml000066400000000000000000000004461464273144400174060ustar00rootroot00000000000000version: 2 updates: - package-ecosystem: "bundler" directory: "/" schedule: interval: "weekly" - package-ecosystem: "github-actions" directory: "/" schedule: interval: "weekly" - package-ecosystem: "npm" directory: / schedule: interval: "weekly" faraday-2.10.0/.github/workflows/000077500000000000000000000000001464273144400166075ustar00rootroot00000000000000faraday-2.10.0/.github/workflows/ci.yml000066400000000000000000000027111464273144400177260ustar00rootroot00000000000000name: CI on: pull_request: push: branches: [ main, 1.x, 0.1x ] env: GIT_COMMIT_SHA: ${{ github.sha }} GIT_BRANCH: ${{ github.ref }} COVERALLS_REPO_TOKEN: ${{ secrets.COVERALLS_REPO_TOKEN }} permissions: contents: read # to fetch code (actions/checkout) jobs: linting: runs-on: ubuntu-latest env: BUNDLE_WITH: lint BUNDLE_WITHOUT: development:test steps: - uses: actions/checkout@v4 - name: Setup Ruby 3.x uses: ruby/setup-ruby@v1 with: ruby-version: 3 bundler-cache: true - name: Rubocop run: bundle exec rubocop --format progress - name: Yard-Junk run: bundle exec yard-junk --path lib build: needs: [ linting ] runs-on: ubuntu-latest name: build ${{ matrix.ruby }} strategy: fail-fast: false matrix: ruby: [ '3.0', '3.1', '3.2', '3.3' ] experimental: [false] include: - ruby: head experimental: true - ruby: truffleruby-head experimental: true steps: - uses: actions/checkout@v4 - uses: ruby/setup-ruby@v1 with: ruby-version: ${{ matrix.ruby }} bundler-cache: true - name: RSpec continue-on-error: ${{ matrix.experimental }} run: bundle exec rake - name: Test External Adapters continue-on-error: ${{ matrix.experimental }} run: bundle exec bake test:external faraday-2.10.0/.github/workflows/publish.yml000066400000000000000000000006701464273144400210030ustar00rootroot00000000000000name: Publish on: release: types: [published] jobs: build: name: Publish to Rubygems runs-on: ubuntu-latest permissions: contents: write id-token: write steps: - uses: actions/checkout@v4 - name: Setup Ruby 3.x uses: ruby/setup-ruby@v1 with: bundler-cache: true ruby-version: 3 - name: Publish to RubyGems uses: rubygems/release-gem@v1 faraday-2.10.0/.github/workflows/refresh_team_page.yml000066400000000000000000000004561464273144400227770ustar00rootroot00000000000000name: Refresh Team Page on: push: branches: [ main ] permissions: {} jobs: build: name: Refresh Contributors Stats runs-on: ubuntu-latest steps: - name: Call GitHub API run: | curl "https://api.github.com/repos/${{ github.repository }}/stats/contributors" faraday-2.10.0/.gitignore000066400000000000000000000003421464273144400152010ustar00rootroot00000000000000## PROJECT::GENERAL coverage rdoc doc log pkg/* tmp .rvmrc .ruby-version .yardoc .DS_Store ## BUNDLER *.gem .bundle Gemfile.lock vendor/bundle external ## NPM node_modules ## PROJECT::SPECIFIC .rbx ## IDEs .idea/ .yardoc/ faraday-2.10.0/.rspec000066400000000000000000000000651464273144400143300ustar00rootroot00000000000000--require spec_helper --format documentation --color faraday-2.10.0/.rubocop.yml000066400000000000000000000124141464273144400154660ustar00rootroot00000000000000inherit_from: .rubocop_todo.yml require: - rubocop-packaging - rubocop-performance AllCops: DisplayCopNames: true DisplayStyleGuide: true TargetRubyVersion: 3.0 # Custom config Gemspec/RequireMFA: # we don't know if this works with auto-deployments yet Enabled: false Layout/LineLength: Exclude: - spec/**/*.rb - examples/**/*.rb Metrics/BlockLength: Exclude: - lib/faraday/options/env.rb - spec/**/*.rb - examples/**/*.rb Metrics/ModuleLength: Exclude: - lib/faraday/options/env.rb Style/Documentation: Exclude: - 'spec/**/*' - 'examples/**/*' Style/DoubleNegation: Enabled: false Style/IfUnlessModifier: Enabled: false # New cops Gemspec/DeprecatedAttributeAssignment: # new in 1.30 Enabled: true Layout/LineContinuationLeadingSpace: # new in 1.31 Enabled: true Layout/LineContinuationSpacing: # new in 1.31 Enabled: true Layout/LineEndStringConcatenationIndentation: # new in 1.18 Enabled: true Layout/SpaceBeforeBrackets: # new in 1.7 Enabled: true Lint/AmbiguousAssignment: # new in 1.7 Enabled: true Lint/AmbiguousOperatorPrecedence: # new in 1.21 Enabled: true Lint/AmbiguousRange: # new in 1.19 Enabled: true Lint/ConstantOverwrittenInRescue: # new in 1.31 Enabled: true Lint/DeprecatedConstants: # new in 1.8 Enabled: true Lint/DuplicateBranch: # new in 1.3 Enabled: true Lint/DuplicateRegexpCharacterClassElement: # new in 1.1 Enabled: true Lint/EmptyBlock: # new in 1.1 Enabled: true Lint/EmptyClass: # new in 1.3 Enabled: true Lint/EmptyInPattern: # new in 1.16 Enabled: true Lint/IncompatibleIoSelectWithFiberScheduler: # new in 1.21 Enabled: true Lint/LambdaWithoutLiteralBlock: # new in 1.8 Enabled: true Lint/NoReturnInBeginEndBlocks: # new in 1.2 Enabled: true Lint/NonAtomicFileOperation: # new in 1.31 Enabled: true Lint/NumberedParameterAssignment: # new in 1.9 Enabled: true Lint/OrAssignmentToConstant: # new in 1.9 Enabled: true Lint/RedundantDirGlobSort: # new in 1.8 Enabled: true Lint/RefinementImportMethods: # new in 1.27 Enabled: true Lint/RequireRangeParentheses: # new in 1.32 Enabled: true Lint/RequireRelativeSelfPath: # new in 1.22 Enabled: true Lint/SymbolConversion: # new in 1.9 Enabled: true Lint/ToEnumArguments: # new in 1.1 Enabled: true Lint/TripleQuotes: # new in 1.9 Enabled: true Lint/UnexpectedBlockArity: # new in 1.5 Enabled: true Lint/UnmodifiedReduceAccumulator: # new in 1.1 Enabled: true Lint/UselessRuby2Keywords: # new in 1.23 Enabled: true Naming/BlockForwarding: # new in 1.24 Enabled: true Security/CompoundHash: # new in 1.28 Enabled: true Security/IoMethods: # new in 1.22 Enabled: true Style/ArgumentsForwarding: # new in 1.1 Enabled: true Style/CollectionCompact: # new in 1.2 Enabled: true Style/DocumentDynamicEvalDefinition: # new in 1.1 Enabled: true Style/EmptyHeredoc: # new in 1.32 Enabled: true Style/EndlessMethod: # new in 1.8 Enabled: true Style/EnvHome: # new in 1.29 Enabled: true Style/FetchEnvVar: # new in 1.28 Enabled: true Style/FileRead: # new in 1.24 Enabled: true Style/FileWrite: # new in 1.24 Enabled: true Style/HashConversion: # new in 1.10 Enabled: true Style/HashExcept: # new in 1.7 Enabled: true Style/IfWithBooleanLiteralBranches: # new in 1.9 Enabled: true Style/InPatternThen: # new in 1.16 Enabled: true Style/MapCompactWithConditionalBlock: # new in 1.30 Enabled: true Style/MapToHash: # new in 1.24 Enabled: true Style/MultilineInPatternThen: # new in 1.16 Enabled: true Style/NegatedIfElseCondition: # new in 1.2 Enabled: true Style/NestedFileDirname: # new in 1.26 Enabled: true Style/NilLambda: # new in 1.3 Enabled: true Style/NumberedParameters: # new in 1.22 Enabled: true Style/NumberedParametersLimit: # new in 1.22 Enabled: true Style/ObjectThen: # new in 1.28 Enabled: true Style/OpenStructUse: # new in 1.23 Enabled: true Style/QuotedSymbols: # new in 1.16 Enabled: true Style/RedundantArgument: # new in 1.4 Enabled: true Style/RedundantInitialize: # new in 1.27 Enabled: true Style/RedundantSelfAssignmentBranch: # new in 1.19 Enabled: true Style/SelectByRegexp: # new in 1.22 Enabled: true Style/StringChars: # new in 1.12 Enabled: true Style/SwapValues: # new in 1.1 Enabled: true Performance/AncestorsInclude: # new in 1.7 Enabled: true Performance/BigDecimalWithNumericArgument: # new in 1.7 Enabled: true Performance/BlockGivenWithExplicitBlock: # new in 1.9 Enabled: true Performance/CollectionLiteralInLoop: # new in 1.8 Enabled: true Performance/ConcurrentMonotonicTime: # new in 1.12 Enabled: true Performance/ConstantRegexp: # new in 1.9 Enabled: true Performance/MapCompact: # new in 1.11 Enabled: true Performance/MethodObjectAsBlock: # new in 1.9 Enabled: true Performance/RedundantEqualityComparisonBlock: # new in 1.10 Enabled: true Performance/RedundantSortBlock: # new in 1.7 Enabled: true Performance/RedundantSplitRegexpArgument: # new in 1.10 Enabled: true Performance/RedundantStringChars: # new in 1.7 Enabled: true Performance/ReverseFirst: # new in 1.7 Enabled: true Performance/SortReverse: # new in 1.7 Enabled: true Performance/Squeeze: # new in 1.7 Enabled: true Performance/StringIdentifierArgument: # new in 1.13 Enabled: true Performance/StringInclude: # new in 1.7 Enabled: true Performance/Sum: # new in 1.8 Enabled: true faraday-2.10.0/.rubocop_todo.yml000066400000000000000000000043271464273144400165170ustar00rootroot00000000000000# This configuration was generated by # `rubocop --auto-gen-config` # on 2023-12-27 11:12:52 UTC using RuboCop version 1.59.0. # The point is for the user to remove these configuration records # one by one as the offenses are removed from the code base. # Note that changes in the inspected code, or installation of new # versions of RuboCop, may require this file to be generated again. # Offense count: 6 # Configuration parameters: AllowedMethods. # AllowedMethods: enums Lint/ConstantDefinitionInBlock: Exclude: - 'spec/faraday/options/options_spec.rb' - 'spec/faraday/rack_builder_spec.rb' - 'spec/faraday/request/instrumentation_spec.rb' # Offense count: 11 # Configuration parameters: AllowComments, AllowEmptyLambdas. Lint/EmptyBlock: Exclude: - 'spec/faraday/connection_spec.rb' - 'spec/faraday/rack_builder_spec.rb' - 'spec/faraday/response_spec.rb' # Offense count: 13 # Configuration parameters: AllowedMethods, AllowedPatterns, CountRepeatedAttributes. Metrics/AbcSize: Max: 42 # Offense count: 3 # Configuration parameters: CountComments, CountAsOne. Metrics/ClassLength: Max: 225 # Offense count: 9 # Configuration parameters: AllowedMethods, AllowedPatterns. Metrics/CyclomaticComplexity: Max: 13 # Offense count: 27 # Configuration parameters: CountComments, CountAsOne, AllowedMethods, AllowedPatterns. Metrics/MethodLength: Max: 33 # Offense count: 1 # Configuration parameters: CountKeywordArgs, MaxOptionalParameters. Metrics/ParameterLists: Max: 6 # Offense count: 7 # Configuration parameters: AllowedMethods, AllowedPatterns. Metrics/PerceivedComplexity: Max: 14 # Offense count: 19 # This cop supports safe autocorrection (--autocorrect). # Configuration parameters: AllowOnlyRestArgument, UseAnonymousForwarding, RedundantRestArgumentNames, RedundantKeywordRestArgumentNames, RedundantBlockArgumentNames. # RedundantRestArgumentNames: args, arguments # RedundantKeywordRestArgumentNames: kwargs, options, opts # RedundantBlockArgumentNames: blk, block, proc Style/ArgumentsForwarding: Exclude: - 'lib/faraday.rb' - 'lib/faraday/rack_builder.rb' # Offense count: 3 Style/DocumentDynamicEvalDefinition: Exclude: - 'lib/faraday/connection.rb' - 'lib/faraday/options.rb' faraday-2.10.0/.yardopts000066400000000000000000000002411464273144400150550ustar00rootroot00000000000000--no-private --exclude test --exclude .github --exclude coverage --exclude doc --exclude script --markup markdown --readme README.md lib/**/*.rb - CHANGELOG.md faraday-2.10.0/CHANGELOG.md000066400000000000000000000577741464273144400150470ustar00rootroot00000000000000# Faraday Changelog ## The changelog has moved! This file is not being updated anymore. Instead, please check the [Releases](https://github.com/lostisland/faraday/releases) page. ## [2.2.0](https://github.com/lostisland/faraday/compare/v2.1.0...v2.2.0) (2022-02-03) * Reintroduce the possibility to register middleware with symbols, strings or procs in [#1391](https://github.com/lostisland/faraday/pull/1391) ## [2.1.0](https://github.com/lostisland/faraday/compare/v2.0.1...v2.1.0) (2022-01-15) * Fix test adapter thread safety by @iMacTia in [#1380](https://github.com/lostisland/faraday/pull/1380) * Add default adapter options by @hirasawayuki in [#1382](https://github.com/lostisland/faraday/pull/1382) * CI: Add Ruby 3.1 to matrix by @petergoldstein in [#1374](https://github.com/lostisland/faraday/pull/1374) * docs: fix regex pattern in logger.md examples by @hirasawayuki in [#1378](https://github.com/lostisland/faraday/pull/1378) ## [2.0.1](https://github.com/lostisland/faraday/compare/v2.0.0...v2.0.1) (2022-01-05) * Re-add `faraday-net_http` as default adapter by @iMacTia in [#1366](https://github.com/lostisland/faraday/pull/1366) * Updated sample format in UPGRADING.md by @vimutter in [#1361](https://github.com/lostisland/faraday/pull/1361) * docs: Make UPGRADING examples more copyable by @olleolleolle in [#1363](https://github.com/lostisland/faraday/pull/1363) ## [2.0.0](https://github.com/lostisland/faraday/compare/v1.8.0...v2.0.0) (2022-01-04) The next major release is here, and it comes almost 2 years after the release of v1.0! This release changes the way you use Faraday and embraces a new paradigm of Faraday as an ecosystem, rather than a library. What does that mean? It means that Faraday is less of a bundled tool and more of a framework for the community to build on top of. As a result, all adapters and some middleware have moved out and are now shipped as standalone gems 🙌! But this doesn't mean that upgrading from Faraday 1.x to Faraday 2.0 should be hard, in fact we've listed everything you need to do in the [UPGRADING.md](https://github.com/lostisland/faraday/blob/main/UPGRADING.md) doc. Moreover, we've setup a new [awesome-faraday](https://github.com/lostisland/awesome-faraday) repository that will showcase a curated list of adapters and middleware 😎. This release was the result of the efforts of the core team and all the contributors, new and old, that have helped achieve this milestone 👏. ## What's Changed * Autoloading, dependency loading and middleware registry cleanup by @iMacTia in [#1301](https://github.com/lostisland/faraday/pull/1301) * Move JSON middleware (request and response) from faraday_middleware by @iMacTia in [#1300](https://github.com/lostisland/faraday/pull/1300) * Remove deprecated `Faraday::Request#method` by @olleolleolle in [#1303](https://github.com/lostisland/faraday/pull/1303) * Remove deprecated `Faraday::UploadIO` by @iMacTia in [#1307](https://github.com/lostisland/faraday/pull/1307) * [1.x] Deprecate Authorization helpers in `Faraday::Connection` by @iMacTia in [#1306](https://github.com/lostisland/faraday/pull/1306) * Drop deprecated auth helpers from Connection and refactor auth middleware by @iMacTia in [#1308](https://github.com/lostisland/faraday/pull/1308) * Add Faraday 1.x examples in authentication.md docs by @iMacTia in [#1320](https://github.com/lostisland/faraday/pull/1320) * Fix passing a URL with embedded basic auth by @iMacTia in [#1324](https://github.com/lostisland/faraday/pull/1324) * Register JSON middleware by @mollerhoj in [#1331](https://github.com/lostisland/faraday/pull/1331) * Retry middleware should handle string exception class name consistently by @jrochkind in [#1334](https://github.com/lostisland/faraday/pull/1334) * Improve request info in exceptions raised by RaiseError Middleware by @willianzocolau in [#1335](https://github.com/lostisland/faraday/pull/1335) * Remove net-http adapter and update docs by @iMacTia in [#1336](https://github.com/lostisland/faraday/pull/1336) * Explain plan for faraday_middleware in UPGRADING.md by @iMacTia in [#1339](https://github.com/lostisland/faraday/pull/1339) * Scripts folder cleanup by @iMacTia in [#1340](https://github.com/lostisland/faraday/pull/1340) * Replace `Hash#merge` with `Utils#deep_merge` for connection options by @xkwd in [#1343](https://github.com/lostisland/faraday/pull/1343) * Callable authorizers by @sled in [#1345](https://github.com/lostisland/faraday/pull/1345) * Default value for exc error by @DariuszMusielak in [#1351](https://github.com/lostisland/faraday/pull/1351) * Don't call `retry_block` unless a retry is going to happen by @jrochkind in [#1350](https://github.com/lostisland/faraday/pull/1350) * Improve documentation for v2 by @iMacTia in [#1353](https://github.com/lostisland/faraday/pull/1353) * Remove default `default_adapter` (yes, you read that right) by @iMacTia in [#1354](https://github.com/lostisland/faraday/pull/1354) * Remove retry middleware by @iMacTia in [#1356](https://github.com/lostisland/faraday/pull/1356) * Remove multipart middleware and all its documentation and tests by @iMacTia in [#1357](https://github.com/lostisland/faraday/pull/1357) ## [1.9.3](https://github.com/lostisland/faraday/compare/v1.9.2...v1.9.3) (2022-01-06) * Re-add support for Ruby 2.4+ by @iMacTia in [#1371](https://github.com/lostisland/faraday/pull/1371) ## [1.9.2](https://github.com/lostisland/faraday/compare/v1.9.1...v1.9.2) (2022-01-06) * Add alias with legacy name to gemified middleware by @iMacTia in [#1372](https://github.com/lostisland/faraday/pull/1372) ## [1.9.1](https://github.com/lostisland/faraday/compare/v1.9.0...v1.9.1) (2022-01-06) * Update adapter dependencies in Gemspec by @iMacTia in [#1370](https://github.com/lostisland/faraday/pull/1370) ## [1.9.0](https://github.com/lostisland/faraday/compare/v1.8.0...v1.9.0) (2022-01-06) * Use external multipart and retry middleware by @iMacTia in [#1367](https://github.com/lostisland/faraday/pull/1367) ## [1.8.0](https://github.com/lostisland/faraday/releases/tag/v1.8.0) (2021-09-18) ### Features * Backport authorization procs (#1322, @jarl-dk) ## [v1.7.0](https://github.com/lostisland/faraday/releases/tag/v1.7.0) (2021-08-09) ### Features * Add strict_mode to Test::Stubs (#1298, @yykamei) ## [v1.6.0](https://github.com/lostisland/faraday/releases/tag/v1.6.0) (2021-08-01) ### Misc * Use external Rack adapter (#1296, @iMacTia) ## [v1.5.1](https://github.com/lostisland/faraday/releases/tag/v1.5.1) (2021-07-11) ### Fixes * Fix JRuby incompatibility after moving out EM adapters (#1294, @ahorek) ### Documentation * Update YARD to follow RackBuilder (#1292, @kachick) ## [v1.5.0](https://github.com/lostisland/faraday/releases/tag/v1.5.0) (2021-07-04) ### Misc * Use external httpclient adapter (#1289, @iMacTia) * Use external patron adapter (#1290, @iMacTia) ## [v1.4.3](https://github.com/lostisland/faraday/releases/tag/v1.4.3) (2021-06-24) ### Fixes * Silence warning (#1286, @gurgeous) * Always dup url_prefix in Connection#build_exclusive_url (#1288, @alexeyds) ## [v1.4.2](https://github.com/lostisland/faraday/releases/tag/v1.4.2) (2021-05-22) ### Fixes * Add proxy setting when url_prefix is changed (#1276, @ci) * Default proxy scheme to http:// if necessary, fixes #1282 (#1283, @gurgeous) ### Documentation * Improve introduction page (#1273, @gurgeous) * Docs: add more middleware examples (#1277, @gurgeous) ### Misc * Use external `em_http` and `em_synchrony` adapters (#1274, @iMacTia) ## [v1.4.1](https://github.com/lostisland/faraday/releases/tag/v1.4.1) (2021-04-18) ### Fixes * Fix dependencies from external adapter gems (#1269, @iMacTia) ## [v1.4.0](https://github.com/lostisland/faraday/releases/tag/v1.4.0) (2021-04-16) ### Highlights With this release, we continue the work of gradually moving out adapters into their own gems 🎉 Thanks to @MikeRogers0 for helping the Faraday team in progressing with this quest 👏 And thanks to @olleolleolle efforts, Faraday is becoming more inclusive than ever 🤗 Faraday's `master` branch has been renamed into `main`, we have an official policy on inclusive language and even a rubocop plugin to check for non-inclusive words ❤️! Checkout the "Misc" section below for more details 🙌 ! ### Fixes * Fix NoMethodError undefined method 'coverage' (#1255, @Maroo-b) ### Documentation * Some docs on EventMachine adapters. (#1232, @damau) * CONTRIBUTING: Fix grammar and layout (#1261, @olleolleolle) ### Misc * Replacing Net::HTTP::Persistent with faraday-net_http_persistent (#1250, @MikeRogers0) * CI: Configure the regenerated Coveralls token (#1256, @olleolleolle) * Replace Excon adapter with Faraday::Excon gem, and fix autoloading issue with Faraday::NetHttpPersistent (#1257, @iMacTia) * Drop CodeClimate (#1259, @olleolleolle) * CI: Rename default branch to main (#1263, @olleolleolle) * Drop RDoc support file .document (#1264, @olleolleolle, @iMacTia) * CONTRIBUTING: add a policy on inclusive language (#1262, @olleolleolle) * Add rubocop-inclusivity (#1267, @olleolleolle, @iMacTia) ## [v1.3.1](https://github.com/lostisland/faraday/releases/tag/v1.3.1) (2021-04-16) ### Fixes * Escape colon in path segment (#1237, @yarafan) * Handle IPv6 address String on Faraday::Connection#proxy_from_env (#1252, @cosmo0920) ### Documentation * Fix broken Rubydoc.info links (#1236, @nickcampbell18) * Add httpx to list of external adapters (#1246, @HoneyryderChuck) ### Misc * Refactor CI to remove duplicated line (#1230, @tricknotes) * Gemspec: Pick a good ruby2_keywords release (#1241, @olleolleolle) ## [v1.3.0](https://github.com/lostisland/faraday/releases/tag/v1.3.0) (2020-12-31) ### Highlights Faraday v1.3.0 is the first release to officially support Ruby 3.0 in the CI pipeline 🎉 🍾! This is also the first release with a previously "included" adapter (Net::HTTP) being isolated into a [separate gem](https://github.com/lostisland/faraday-net_http) 🎊! The new adapter is added to Faraday as a dependency for now, so that means full backwards-compatibility, but just to be safe be careful when upgrading! This is a huge step towards are Faraday v2.0 objective of pushing adapters and middleware into separate gems. Many thanks to the Faraday Team, @JanDintel and everyone who attended the [ROSS Conf remote event](https://www.rossconf.io/event/remote/) ### Features * Improves consistency with Faraday::Error and Faraday::RaiseError (#1229, @qsona, @iMacTia) ### Fixes * Don't assign to global ::Timer (#1227, @bpo) ### Documentation * CHANGELOG: add releases after 1.0 (#1225, @olleolleolle) * Improves retry middleware documentation. (#1228, @iMacTia) ### Misc * Move out Net::HTTP adapter (#1222, @JanDintel, @iMacTia) * Adds Ruby 3.0 to CI Matrix (#1226, @iMacTia) ## [v1.2.0](https://github.com/lostisland/faraday/releases/tag/v1.2.0) (2020-12-23) ### Features * Introduces `on_request` and `on_complete` methods in `Faraday::Middleware`. (#1194, @iMacTia) ### Fixes * Require 'date' to avoid retry exception (#1206, @rustygeldmacher) * Fix rdebug recursion issue (#1205, @native-api) * Update call to `em_http_ssl_patch` (#1202, @kylekeesling) * `EmHttp` adapter: drop superfluous loaded? check (#1213, @olleolleolle) * Avoid 1 use of keyword hackery (#1211, @grosser) * Fix #1219 `Net::HTTP` still uses env proxy (#1221, @iMacTia) ### Documentation * Add comment in gemspec to explain exposure of `examples` and `spec` folders. (#1192, @iMacTia) * Adapters, how to create them (#1193, @olleolleolle) * Update documentation on using the logger (#1196, @tijmenb) * Adjust the retry documentation and spec to align with implementation (#1198, @nbeyer) ### Misc * Test against ruby head (#1208, @grosser) ## [v1.1.0](https://github.com/lostisland/faraday/releases/tag/v1.1.0) (2020-10-17) ### Features * Makes parameters sorting configurable (#1162 @wishdev) * Introduces `flat_encode` option for multipart adapter. (#1163 @iMacTia) * Include request info in exceptions raised by RaiseError Middleware (#1181 @SandroDamilano) ### Fixes * Avoid `last arg as keyword param` warning when building user middleware on Ruby 2.7 (#1153 @dgholz) * Limits net-http-persistent version to < 4.0 (#1156 @iMacTia) * Update `typhoeus` to new stable version (`1.4`) (#1159 @AlexWayfer) * Properly fix test failure with Rack 2.1+. (#1171 @voxik) ### Documentation * Improves documentation on how to contribute to the site by using Docker. (#1175 @iMacTia) * Remove retry_change_requests from documentation (#1185 @stim371) ### Misc * Link from GitHub Actions badge to CI workflow (#1141 @olleolleolle) * Return tests of `Test` adapter (#1147 @AlexWayfer) * Add 1.0 release to wording in CONTRIBUTING (#1155 @olleolleolle) * Fix linting bumping Rubocop to 0.90.0 (#1182 @iMacTia) * Drop `git ls-files` in gemspec (#1183 @utkarsh2102) * Upgrade CI to ruby/setup-ruby (#1187 @gogainda) ## [v1.0.1](https://github.com/lostisland/faraday/releases/tag/v1.0.1) (2020-03-29) ### Fixes * Use Net::HTTP#start(&block) to ensure closed TCP connections (#1117) * Fully qualify constants to be checked (#1122) * Allows `parse` method to be private/protected in response middleware (#1123) * Encode Spaces in Query Strings as '%20' Instead of '+' (#1125) * Limits rack to v2.0.x (#1127) * Adapter Registry reads also use mutex (#1136) ### Documentation * Retry middleware documentation fix (#1109) * Docs(retry): precise usage of retry-after (#1111) * README: Link the logo to the website (#1112) * Website: add search bar (#1116) * Fix request/response mix-up in docs text (#1132) ## [v1.0](https://github.com/lostisland/faraday/releases/tag/v1.0.0) (2020-01-22) Features: * Add #trace support to Faraday::Connection #861 (@technoweenie) * Add the log formatter that is easy to override and safe to inherit #889 (@prikha) * Support standalone adapters #941 (@iMacTia) * Introduce Faraday::ConflictError for 409 response code #979 (@lucasmoreno) * Add support for setting `read_timeout` option separately #1003 (@springerigor) * Refactor and cleanup timeout settings across adapters #1022 (@technoweenie) * Create ParamPart class to allow multipart posts with JSON content and file upload at the same time #1017 (@jeremy-israel) * Copy UploadIO const -> FilePart for consistency with ParamPart #1018, #1021 (@technoweenie) * Implement streaming responses in the Excon adapter #1026 (@technoweenie) * Add default implementation of `Middleware#close`. #1069 (@ioquatix) * Add `Adapter#close` so that derived classes can call super. #1091 (@ioquatix) * Add log_level option to logger default formatter #1079 (@amrrbakry) * Fix empty array for FlatParamsEncoder `{key: []} -> "key="` #1084 (@mrexox) Bugs: * Explicitly require date for DateTime library in Retry middleware #844 (@nickpresta) * Refactor Adapter as final endpoints #846 (@iMacTia) * Separate Request and Response bodies in Faraday::Env #847 (@iMacTia) * Implement Faraday::Connection#options to make HTTP requests with the OPTIONS verb. #857 (@technoweenie) * Multipart: Drop Ruby 1.8 String behavior compat #892 (@olleolleolle) * Fix Ruby warnings in Faraday::Options.memoized #962 (@technoweenie) * Allow setting min/max SSL version for a Net::HTTP::Persistent connection #972, #973 (@bdewater, @olleolleolle) * Fix instances of frozen empty string literals #1040 (@BobbyMcWho) * remove temp_proxy and improve proxy tests #1063 (@technoweenie) * improve error initializer consistency #1095 (@technoweenie) Misc: * Convert minitest suite to RSpec #832 (@iMacTia, with help from @gaynetdinov, @Insti, @technoweenie) * Major effort to update code to RuboCop standards. #854 (@olleolleolle, @iMacTia, @technoweenie, @htwroclau, @jherdman, @Drenmi, @Insti) * Rubocop #1044, #1047 (@BobbyMcWho, @olleolleolle) * Documentation tweaks (@adsteel, @Hubro, @iMacTia, @olleolleolle, @technoweenie) * Update license year #981 (@Kevin-Kawai) * Configure Jekyll plugin jekyll-remote-theme to support Docker usage #999 (@Lewiscowles1986) * Fix Ruby 2.7 warnings #1009 (@tenderlove) * Cleanup adapter connections #1023 (@technoweenie) * Describe clearing cached stubs #1045 (@viraptor) * Add project metadata to the gemspec #1046 (@orien) ## v0.17.4 Fixes: * NetHttp adapter: wrap Errno::EADDRNOTAVAIL (#1114, @embs) * Fix === for subclasses of deprecated classes (#1243, @mervync) ## v0.17.3 Fixes: * Reverts changes in error classes hierarchy. #1092 (@iMacTia) * Fix Ruby 1.9 syntax errors and improve Error class testing #1094 (@BanzaiMan, @mrexox, @technoweenie) Misc: * Stops using `&Proc.new` for block forwarding. #1083 (@olleolleolle) * Update CI to test against ruby 2.0-2.7 #1087, #1099 (@iMacTia, @olleolleolle, @technoweenie) * require FARADAY_DEPRECATE=warn to show Faraday v1.0 deprecation warnings #1098 (@technoweenie) ## v0.17.1 Final release before Faraday v1.0, with important fixes for Ruby 2.7. Fixes: * RaiseError response middleware raises exception if HTTP client returns a nil status. #1042 (@jonnyom, @BobbyMcWho) Misc: * Fix Ruby 2.7 warnings (#1009) * Add `Faraday::Deprecate` to warn about upcoming v1.0 changes. (#1054, #1059, #1076, #1077) * Add release notes up to current in CHANGELOG.md (#1066) * Port minimal rspec suite from main branch to run backported tests. (#1058) ## v0.17.0 This release is the same as v0.15.4. It was pushed to cover up releases v0.16.0-v0.16.2. ## v0.15.4 * Expose `pool_size` as a option for the NetHttpPersistent adapter (#834) ## v0.15.3 * Make Faraday::Request serialisable with Marshal. (#803) * Add DEFAULT_EXCEPTIONS constant to Request::Retry (#814) * Add support for Ruby 2.6 Net::HTTP write_timeout (#824) ## v0.15.2 * Prevents `Net::HTTP` adapters to retry request internally by setting `max_retries` to 0 if available (Ruby 2.5+). (#799) * Fixes `NestedParamsEncoder` handling of empty array values (#801) ## v0.15.1 * NetHttpPersistent adapter better reuse of SSL connections (#793) * Refactor: inline cached_connection (#797) * Logger middleware: use $stdout instead of STDOUT (#794) * Fix: do not memoize/reuse Patron session (#796) Also in this release: * Allow setting min/max ssl version for Net::HTTP (#792) * Allow setting min/max ssl version for Excon (#795) ## v0.15.0 Features: * Added retry block option to retry middleware. (#770) * Retry middleware improvements (honour Retry-After header, retry statuses) (#773) * Improve response logger middleware output (#784) Fixes: * Remove unused class error (#767) * Fix minor typo in README (#760) * Reuse persistent connections when using net-http-persistent (#778) * Fix Retry middleware documentation (#781) * Returns the http response when giving up on retrying by status (#783) ## v0.14.0 Features: * Allow overriding env proxy #754 (@iMacTia) * Remove legacy Typhoeus adapter #715 (@olleolleolle) * External Typhoeus Adapter Compatibility #748 (@iMacTia) * Warn about missing adapter when making a request #743 (@antstorm) * Faraday::Adapter::Test stubs now support entire urls (with host) #741 (@erik-escobedo) Fixes: * If proxy is manually provided, this takes priority over `find_proxy` #724 (@iMacTia) * Fixes the behaviour for Excon's open_timeout (not setting write_timeout anymore) #731 (@apachelogger) * Handle all connection timeout messages in Patron #687 (@stayhero) ## v0.13.1 * Fixes an incompatibility with Addressable::URI being used as uri_parser ## v0.13.0 Features: * Dynamically reloads the proxy when performing a request on an absolute domain (#701) * Adapter support for Net::HTTP::Persistent v3.0.0 (#619) Fixes: * Prefer #hostname over #host. (#714) * Fixes an edge-case issue with response headers parsing (missing HTTP header) (#719) ## v0.12.2 * Parse headers from aggregated proxy requests/responses (#681) * Guard against invalid middleware configuration with warning (#685) * Do not use :insecure option by default in Patron (#691) * Fixes an issue with HTTPClient not raising a `Faraday::ConnectionFailed` (#702) * Fixes YAML serialization/deserialization for `Faraday::Utils::Headers` (#690) * Fixes an issue with Options having a nil value (#694) * Fixes an issue with Faraday.default_connection not using Faraday.default_connection_options (#698) * Fixes an issue with Options.merge! and Faraday instrumentation middleware (#710) ## v0.12.1 * Fix an issue with Patron tests failing on jruby * Fix an issue with new `rewind_files` feature that was causing an exception when the body was not an Hash * Expose wrapped_exception in all client errors * Add Authentication Section to the ReadMe ## v0.12.0.1 * Hotfix release to address an issue with TravisCI deploy on Rubygems ## v0.12.0 Features: * Proxy feature now relies on Ruby `URI::Generic#find_proxy` and can use `no_proxy` ENV variable (not compatible with ruby < 2.0) * Adds support for `context` request option to pass arbitrary information to middlewares Fixes: * Fix an issue with options that was causing new options to override defaults ones unexpectedly * Rewind `UploadIO`s on retry to fix a compatibility issue * Make multipart boundary unique * Improvements in `README.md` ## v0.11.0 Features: * Add `filter` method to Logger middleware * Add support for Ruby2.4 and Minitest 6 * Introduce block syntax to customise the adapter Fixes: * Fix an issue that was allowing to override `default_connection_options` from a connection instance * Fix a bug that was causing newline escape characters ("\n") to be used when building the Authorization header ## v0.10.1 - Fix an issue with HTTPClient adapter that was causing the SSL to be reset on every request - Rescue `IOError` instead of specific subclass - `Faraday::Utils::Headers` can now be successfully serialised in YAML - Handle `default_connection_options` set with hash ## v0.10.0 Breaking changes: - Drop support for Ruby 1.8 Features: - Include wrapped exception/reponse in ClientErrors - Add `response.reason_phrase` - Provide option to selectively skip logging request/response headers - Add regex support for pattern matching in `test` adapter Fixes: - Add `Faraday.respond_to?` to find methods managed by `method_missing` - em-http: `request.host` instead of `connection.host` should be taken for SSL validations - Allow `default_connection_options` to be merged when options are passed as url parameter - Improve splitting key-value pairs in raw HTTP headers ## v0.9.2 Adapters: - Enable gzip compression for httpclient - Fixes default certificate store for httpclient not having default paths. - Make excon adapter compatible with 0.44 excon version - Add compatibility with Patron 0.4.20 - Determine default port numbers in Net::HTTP adapters (Addressable compatibility) - em-http: wrap "connection closed by server" as ConnectionFailed type - Wrap Errno::ETIMEDOUT in Faraday::Error::TimeoutError Utils: - Add Rack-compatible support for parsing `a[][b]=c` nested queries - Encode nil values in queries different than empty strings. Before: `a=`; now: `a`. - Have `Faraday::Utils::Headers#replace` clear internal key cache - Dup the internal key cache when a Headers hash is copied Env and middleware: - Ensure `env` stored on middleware response has reference to the response - Ensure that Response properties are initialized during `on_complete` (VCR compatibility) - Copy request options in Faraday::Connection#dup - Env custom members should be copied by Env.from(env) - Honour per-request `request.options.params_encoder` - Fix `interval_randomness` data type for Retry middleware - Add maximum interval option for Retry middleware ## v0.9.1 * Refactor Net:HTTP adapter so that with_net_http_connection can be overridden to allow pooled connections. (@Ben-M) * Add configurable methods that bypass `retry_if` in the Retry request middleware. (@mike-bourgeous) ## v0.9.0 * Add HTTPClient adapter (@hakanensari) * Improve Retry handler (@mislav) * Remove autoloading by default (@technoweenie) * Improve internal docs (@technoweenie, @mislav) * Respect user/password in http proxy string (@mislav) * Adapter options are structs. Reinforces consistent options across adapters (@technoweenie) * Stop stripping trailing / off base URLs in a Faraday::Connection. (@technoweenie) * Add a configurable URI parser. (@technoweenie) * Remove need to manually autoload when using the authorization header helpers on `Faraday::Connection`. (@technoweenie) * `Faraday::Adapter::Test` respects the `Faraday::RequestOptions#params_encoder` option. (@technoweenie) faraday-2.10.0/Gemfile000066400000000000000000000015321464273144400145060ustar00rootroot00000000000000# frozen_string_literal: true source 'https://rubygems.org' # Even though we don't officially support JRuby, this dependency makes Faraday # compatible with it, so we're leaving it in for jruby users to use it. gem 'jruby-openssl', '~> 0.11.0', platforms: :jruby group :development, :test do gem 'bake-test-external' gem 'coveralls_reborn', require: false gem 'pry' gem 'rack', '~> 3.0' gem 'rake' gem 'rspec', '~> 3.7' gem 'rspec_junit_formatter', '~> 0.4' gem 'simplecov' gem 'webmock', '~> 3.4' end group :development, :lint do gem 'racc', '~> 1.7' # for RuboCop, on Ruby 3.3 gem 'rubocop' gem 'rubocop-packaging', '~> 0.5' gem 'rubocop-performance', '~> 1.0' gem 'yard-junk' end group :deployment do gem 'rubygems-await', github: 'segiddins/rubygems-await', ref: 'f5e2b0413ec6f17e35d9bb7902dcb28b31804701' end gemspec faraday-2.10.0/LICENSE.md000066400000000000000000000020601464273144400146140ustar00rootroot00000000000000Copyright (c) 2009-2023 Rick Olson, Zack Hobson 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. faraday-2.10.0/README.md000066400000000000000000000066301464273144400144760ustar00rootroot00000000000000# [![Faraday](./docs/_media/home-logo.svg)][website] [![Gem Version](https://badge.fury.io/rb/faraday.svg)](https://rubygems.org/gems/faraday) [![GitHub Actions CI](https://github.com/lostisland/faraday/workflows/CI/badge.svg)](https://github.com/lostisland/faraday/actions?query=workflow%3ACI) [![GitHub Discussions](https://img.shields.io/github/discussions/lostisland/faraday?logo=github)](https://github.com/lostisland/faraday/discussions) Faraday is an HTTP client library abstraction layer that provides a common interface over many adapters (such as Net::HTTP) and embraces the concept of Rack middleware when processing the request/response cycle. Take a look at [Awesome Faraday][awesome] for a list of available adapters and middleware. ## Why use Faraday? Faraday gives you the power of Rack middleware for manipulating HTTP requests and responses, making it easier to build sophisticated API clients or web service libraries that abstract away the details of how HTTP requests are made. Faraday comes with a lot of features out of the box, such as: * Support for multiple adapters (Net::HTTP, Typhoeus, Patron, Excon, HTTPClient, and more) * Persistent connections (keep-alive) * Parallel requests * Automatic response parsing (JSON, XML, YAML) * Customization of the request/response cycle with middleware * Support for streaming responses * Support for uploading files * And much more! ## Getting Started The best starting point is the [Faraday Website][website], with its introduction and explanation. Need more details? See the [Faraday API Documentation][apidoc] to see how it works internally, or take a look at [Advanced techniques for calling HTTP APIs in Ruby](https://mattbrictson.com/blog/advanced-http-techniques-in-ruby) blog post from [@mattbrictson](https://github.com/mattbrictson) 🚀 ## Supported Ruby versions This library aims to support and is [tested against][actions] the currently officially supported Ruby implementations. This means that, even without a major release, we could add or drop support for Ruby versions, following their [EOL](https://endoflife.date/ruby). Currently that means we support Ruby 3.0+ If something doesn't work on one of these Ruby versions, it's a bug. This library may inadvertently work (or seem to work) on other Ruby implementations and versions, however support will only be provided for the versions listed above. If you would like this library to support another Ruby version, you may volunteer to be a maintainer. Being a maintainer entails making sure all tests run and pass on that implementation. When something breaks on your implementation, you will be responsible for providing patches in a timely fashion. If critical issues for a particular implementation exist at the time of a major release, support for that Ruby version may be dropped. ## Contribute Do you want to contribute to Faraday? Open the issues page and check for the `help wanted` label! But before you start coding, please read our [Contributing Guide][contributing] ## Copyright © 2009 - 2023, the Faraday Team. Website and branding design by [Elena Lo Piccolo](https://elelopic.design). [awesome]: https://github.com/lostisland/awesome-faraday/#adapters [website]: https://lostisland.github.io/faraday [contributing]: https://github.com/lostisland/faraday/blob/main/.github/CONTRIBUTING.md [apidoc]: https://www.rubydoc.info/github/lostisland/faraday [actions]: https://github.com/lostisland/faraday/actions faraday-2.10.0/Rakefile000066400000000000000000000003211464273144400146530ustar00rootroot00000000000000# frozen_string_literal: true require 'rspec/core/rake_task' require 'bundler' Bundler::GemHelper.install_tasks RSpec::Core::RakeTask.new(:spec) do |task| task.ruby_opts = %w[-W] end task default: :spec faraday-2.10.0/UPGRADING.md000066400000000000000000000245611464273144400150640ustar00rootroot00000000000000## Faraday 2.0 ### Adapters have moved! With this release, we've officially moved all adapters, except for the `net_http` one, out of Faraday. What that means, is that they won't be available out-of-the-box anymore, and you'll instead need to add them to your Gemfile. **NOTE: the `net_http` adapter was originally removed as well in version `2.0`, but quickly reintroduced in version `2.0.1`. We strongly suggest you to skip version `2.0` and instead use version `2.0.1` or greater.** #### Why was this decision made? We've taken this decision for the following technical reasons: * We wanted the Faraday gem to focus on providing a clean, standardized, middleware-stack-based API. * We wanted to free the core team from maintaining all the different adapters, relying more on the community to maintain them based on the broad interest. This will allow the core team to focus on implementing features focused on the Faraday API more quickly, without having to push it on all adapters immediately. * With the community creating more and more adapters, we wanted to avoid having first and second-class adapters by having some of them included with the gem and others available externally. * Moving adapters into separate gems allow to solve the dependency issues once and for all. Faraday will remain a dependency-free gem, while adapter gems will be able to automatically pull any necessary dependency, without having to rely on the developer to do so. #### So what will this mean for me? We did our best to make this transition as painless as possible for you, so here is what we did. * All adapters, except for the `net_http` one, have already been moved out and released as separate gems. They've then been re-added into Faraday's v1 dependencies so that you wouldn't notice. This means that immediately after v2.0 will be released, all the adapters that were previously available will be already compatible with Faraday 2.0! * We've setup an [Awesome Faraday](https://github.com/lostisland/awesome-faraday) repository, where you can find and discover adapters. We also highlighted their unique features and level of compliance with Faraday's features. #### That's great! What should I change in my code immediately after upgrading? * If you just use the default `net_http` adapter, then you don't need to do anything! * Otherwise, add the corresponding adapter gem to your Gemfile (e.g. `faraday-net_http_persistent`). Then, simply require them after you require `faraday`. ```ruby # Gemfile gem 'faraday' gem 'faraday-net_http_persistent' # Code require 'faraday' require 'faraday/net_http_persistent' ``` ### Faraday Middleware Deprecation In case you never used it, [Faraday Middleware](https://github.com/lostisland/faraday_middleware) is a handy collection of middleware that have so far been maintained by the Faraday core team. With Faraday 2.0 focusing on becoming an ecosystem, rather than an out-of-the-box solution, it only made sense to take the same approach for middleware as we did for adapters. For this reason, `faraday_middleware` will not be updated to support Faraday 2.0. Instead, we'll support the transition from centralised-repo collection of middleware to individual middleware gems, effectively replicating what we did with adapters. Each middleware will have its own repository and gem, and it will allow developers to only add the ones they require to their Gemfile. So don't fret yet! We're doing our best to support our `faraday_middleware` users out there, so here are the steps we've taken to make this work: * We've promoted the highly popular JSON middleware (both request encoding and response parsing) to a core middleware and it will now be shipped together with Faraday. We expect many `faraday_middleware` users will be able to just stop using the extra dependency thanks to this. * We've created a [faraday-middleware-template](https://github.com/lostisland/faraday-middleware-template) repository that will make creating a new middleware gem simple and straightforward. * We've added a middleware section to the [awesome-faraday](https://github.com/lostisland/awesome-faraday) repo, so you can easily find available middleware when you need it. It will obviously take time for some of the middleware in `faraday_middleware` to make its way into a separate gem, so we appreciate this might be an upgrade obstacle for some. However this is part of an effort to focus the core team resources tackling the most requested features. We'll be listening to the community and prioritize middleware that are most used, and will be welcoming contributors who want to become owners of the middleware when these become separate from the `faraday_middleware` repo. ### Bundled middleware moved out Moving middleware into its own gem makes sense not only for `faraday_middleware`, but also for middleware bundled with Faraday. As of v2.0, the `retry` and `multipart` middleware have been moved to separate `faraday-retry` and `faraday-multipart` gems. These have been identified as good candidates due to their complexity and external dependencies. Thanks to this change, we were able to make Faraday 2.0 completely dependency free 🎉 (the only exception being `ruby2_keywords`, which will be necessary only while we keep supporting Ruby 2.6). #### So what should I do if I currently use the `retry` or `multipart` middleware? Upgrading is pretty simple, because the middleware was simply moved out to external gems. All you need to do is to add them to your gemfile (either `faraday-retry` or `faraday-multipart` and require them before usage: ```ruby # Gemfile gem 'faraday-multipart' gem 'faraday-retry' # Connection initializer require 'faraday/retry' require 'faraday/multipart' conn = Faraday.new(url) do |f| f.request :multipart f.request :retry # ... end ``` ### Autoloading and dependencies Faraday has until now provided and relied on a complex dynamic dependencies system. This would allow to reference classes and require dependencies only when needed (e.g. when running the first request) based on the middleware/adapters used. As part of Faraday v2.0, we've removed all external dependencies, which means we don't really need this anymore. This change should not affect you directly, but if you're registering middleware then be aware of the new syntax: ```ruby # `name` here can be anything you want. # `klass` is your custom middleware class. # This method can also be called on `Faraday::Adapter`, `Faraday::Request` and `Faraday::Response` Faraday::Middleware.register_middleware(name: klass) ``` The `register_middleware` method also previously allowed to provide a symbol, string, proc, or array but this has been removed from the v2.0 release to simplify the interface. (EDIT: symbol/string/proc have subsequently been reintroduced in v2.2, but not the array). ### Authentication helper methods in Connection have been removed You were previously able to call `authorization`, `basic_auth` and `token_auth` against the `Connection` object, but this helper methods have now been dropped. Instead, you should be using the equivalent middleware, as explained in [this page](https://lostisland.github.io/faraday/#/middleware/included/authentication). For more details, see https://github.com/lostisland/faraday/pull/1306 ### The `dependency` method in middlewares has been removed In Faraday 1, a deferred require was used with the `dependency` method. In Faraday 2, that method has been removed. In your middleware gems, use a regular `require` at the top of the file, ### Others * Rename `Faraday::Request#method` to `#http_method`. * Remove `Faraday::Response::Middleware`. You can now use the new `on_complete` callback provided by `Faraday::Middleware`. * `Faraday.default_connection_options` will now be deep-merged into new connections to avoid overriding them (e.g. headers). * `Faraday::Builder#build` method is not exposed through `Faraday::Connection` anymore and does not reset the handlers if called multiple times. This method should be used internally only. ## Faraday 1.0 ### Errors * Removes sub-class constants definition from `Faraday::Error`. A sub-class (e.g. `ClientError`) was previously accessible either through the `Faraday` module (e.g. `Faraday::ClientError`) or through the `Faraday::Error` class (e.g. `Faraday::Error::ClientError`). The latter is no longer available and the former should be used instead, so check your `rescue`s. * Introduces a new `Faraday::ServerError` (5xx status codes) alongside the existing `Faraday::ClientError` (4xx status codes). Please note `Faraday::ClientError` was previously used for both. * Introduces new Errors that describe the most common REST status codes: * Faraday::BadRequestError (400) * Faraday::UnauthorizedError (401) * Faraday::ForbiddenError (403) * Faraday::ProxyAuthError (407). Please note this raised a `Faraday::ConnectionFailed` before. * Faraday::ConflictError (409) * Faraday::UnprocessableEntityError (422) * The following error classes have changed the hierarchy to better mirror their real-world usage and semantic meaning: * TimeoutError < ServerError (was < ClientError) * ConnectionFailed < Error (was < ClientError) * SSLError < Error (was < ClientError) * ParsingError < Error (was < ClientError) * RetriableResponse < Error (was < ClientError) ### Custom adapters If you have written a custom adapter, please be aware that `env.body` is now an alias to the two new properties `request_body` and `response_body`. This should work without you noticing if your adapter inherits from `Faraday::Adapter` and calls `save_response`, but if it doesn't, then please ensure you set the `status` BEFORE the `body` while processing the response. ### Others * Dropped support for jruby and Rubinius. * Officially supports Ruby 2.4+ * In order to specify the adapter you now MUST use the `#adapter` method on the connection builder. If you don't do so and your adapter inherits from `Faraday::Adapter` then Faraday will raise an exception. Otherwise, Faraday will automatically push the default adapter at the end of the stack causing your request to be executed twice. ```ruby class OfficialAdapter < Faraday::Adapter ... end class MyAdapter ... end # This will raise an exception conn = Faraday.new(...) do |f| f.use OfficialAdapter end # This will cause Faraday inserting the default adapter at the end of the stack conn = Faraday.new(...) do |f| f.use MyAdapter end # You MUST use `adapter` method conn = Faraday.new(...) do |f| f.adapter AnyAdapter end ``` faraday-2.10.0/bin/000077500000000000000000000000001464273144400137625ustar00rootroot00000000000000faraday-2.10.0/bin/console000077500000000000000000000005641464273144400153570ustar00rootroot00000000000000#!/usr/bin/env ruby # frozen_string_literal: true require 'bundler/setup' require 'faraday' # You can add fixtures and/or initialization code here to make experimenting # with your gem easier. You can also use a different console, if you like. # (If you use this, don't forget to add pry to your Gemfile!) # require "pry" # Pry.start require 'irb' IRB.start(__FILE__) faraday-2.10.0/bin/setup000077500000000000000000000001471464273144400150520ustar00rootroot00000000000000#!/usr/bin/env bash set -euo pipefail IFS=$'\n\t' set -vx gem install bundler bundle install --jobs 4 faraday-2.10.0/bin/test000077500000000000000000000001661464273144400146720ustar00rootroot00000000000000#!/usr/bin/env bash set -euo pipefail IFS=$'\n\t' set -vx bundle exec rubocop -a --format progress bundle exec rspec faraday-2.10.0/config/000077500000000000000000000000001464273144400144575ustar00rootroot00000000000000faraday-2.10.0/config/external.yaml000066400000000000000000000001511464273144400171620ustar00rootroot00000000000000faraday-net_http: url: https://github.com/lostisland/faraday-net_http.git command: bundle exec rspec faraday-2.10.0/docs/000077500000000000000000000000001464273144400141425ustar00rootroot00000000000000faraday-2.10.0/docs/.nojekyll000066400000000000000000000000001464273144400157600ustar00rootroot00000000000000faraday-2.10.0/docs/README.md000066400000000000000000000005251464273144400154230ustar00rootroot00000000000000# Faraday Docs Faraday Docs are powered by [Docsify](https://docsify.js.org/#/). ## Development ### Setup From the Faraday project root, run the following: ```bash npm install # this will install the necessary dependencies ``` ### Running the Docs Locally To preview your changes locally, run the following: ```bash npm run docs ``` faraday-2.10.0/docs/_media/000077500000000000000000000000001464273144400153605ustar00rootroot00000000000000faraday-2.10.0/docs/_media/favicon.png000066400000000000000000000012741464273144400175170ustar00rootroot00000000000000PNG  IHDR szzgAMA asIDATX ՗?n16P$BB!"R 7  7(@"Jvv D41߷Y/YXJ*$;~#,y~I7JDth`r#TB(FAuq5&j}J]>#֞>d fSC[}K\dp8HerՔLS%W!b)@x, V<bx(D`U!sUBLbűS(FlڢE\ 4e6!+7d>&E Custom Preset Created with Sketch. faraday-2.10.0/docs/_media/logo.png000066400000000000000000000321771464273144400170400ustar00rootroot00000000000000PNG  IHDR4,MOisRGBPeXIfMM*i&4,;zYiTXtXML:com.adobe.xmp 1 ^2xIDATx|ewv vv9)5BB HAPC褐(^ϻSD ل);y7ٸ ɖy}3wޙy\@H $@H $@H $@H $@H $@H $@H $@H $@H $@H $@H $PSEhJBˆAIDr#7Kw1l2P,jeeii6g02,bu$@@XzPZFQB_/Fv&$ +4YqZϘ4󻯗1F睃^Yw" չ9G< <8}9k2H@ 4)԰&Α}R1VWe@P%lT% f6N/WK#P3^컈2:ks𫌼[:KWHi(hM= lTI vIA_Vk! ]4ATٌM얺yvK74o$QfQF٥d PЬc,{LJ!U/ELU!Pѽޅ35t]lx> ՏØ fj^{jKJ|R >]V f,K9:-1*jUɁ=}jcX\P̕OYq&n#J0M[^2`XYB#!fThT~%SpR!fD& 5COp?A(hx 8Ǧ> Z_: ]4%D wONvjvmc `y,fQ(hM'l縔0V5YmpbCIAt#14ecSǙ>҇ ۶$PԂf(hJwRd$fAȆ'lHCCBzQ7n/Ija@A 8ǧ[ 1U<'L,yb`gE(h:RA:PMa}c@A3FzY>{_3 VH"¶f(h&{3{̮gV_̬}Vy=G9-/ a43x( Z䗦x@мP4jguv3](%Cy.b(h)ݻ(mZ  nGyAIUh P hԮ0<5iКDVP2 vc@A3XNMIJDa_13X\Èxxwi664*a|Jc0Sx>w8yH4!w6U AU6o@Hl7 )eFql Zlt.Ǚr1@q%ی F" XNP:ʞ+ʄ\Y $\4yb:$äx\rNK| TeۈԆ(-CAaRK(9-uYj+R!DBAavӺ<,0!t114٥W;P$Ӱ kԌn Z5Dkܢ<Zfd &DLOrcb؋&DxC3"i?z/CP,OQܭ"MhgmE?uqbS I'g5&,iZ& NE)׿:3r1_KhEF J{J+]P3RDwMʉɛ;Fn$uԕFkr@Advμx`#yP->ȪX\[7jRTEM44: Z\zihC8^v ’ncP4+ DpRy.f+ʊT^neBU#0S =My-B9C_vCWפּ(jJѕ`M4)UN͌"8 e)Z򎥌űPM$eS_p M캛^U}7jo&ȵN2g䂪O;P4 bF+&UMZlCٽ\Nw{ _So6Q$H ]Qx^'>1( x5M.{u1^1Y[px̚"o&szǽ6*Є&f6V4.fQaͲzSqq q. )|dY[›10"H@mO||l54#-"F:e8f5.r#V5͈ﱴEI^b;`E* saYAcw=jhxҧN9RXf-AHr#Lp96DQɒzhn1kr'smps;Jޛpbch=LH| & ^M9E;顱FD퀑To^14S}Xq>q1;wʾ+@.X c]3JjzAc;l f`o .65;ȴ_v3hjAswG7iERLQ#YVjCH@$+8p -hd@ɌLxqH ClD.X $Ǯ_7l!8n:AsGQ†Uq y\|ĉJj*4NG] b6YA瑀 {^aLF$krJ0WQCS탨ĉ/Q4l/}fcefị^4M@>1lK8qZsY3D y:m 2&C [_Bo`0H@YSiݘ4/i&膦n i! M# >ɴC Z-{f >(QL*j Ljnw׈ߘ (j#T %&M6]pvnA0 荨{QHXG<6\G)QsDȩaB_+kibvabUvo3+-j;LQr)0֔yZD]X 37fiUOo=lJ슬% [WRWf T^[Ï̸_^.hV0 PW\͜2[XZF`4=]*GX E_b@s3=AMd4fނ|\Dz,ZO\̜ʶ&jx[pKGj`ml6YMe4Wjm'b6#ny3q1+ 6X%g&lS凍rQs8 Nsv%T&/hV#/-˞THYz{Yk5z9[0D:03`*6˞jJ)٢[̎1H9fS`QV<@~$T\EvAs+aEYcfϔXFb]DgHD-#:1- z_ TS'isֲ8p`,m%peiځ'Ecʢ};bDseOA#Ug٠xaң/ƝOEMLzb%9oz>*_,cf[~HKig_ܢfW.Gb@Uo?+"h<S;(˶إ9+[̪KC}%"UM23+yRwJBUؿm ffQ4L[ (j*dN.U6R3BH-C/pKG#p;IYJRU+14@1_D_pE t~JXtY˪p17i3xXs2--c_ɿ\NWQ#(jʁ^YN&[V\и -cxP_e bL Nb֪j\]j[D5Q9wqEE42|,0aQeK"h=12<2Ou7*jbn>z Y {'(?~< =(Á RX_8W&Z_/GYT)jDIWUu'8u{C I9X90ߒYE`*EŬllִږ? pQ>>6qQ#vYE<\UO1|Up9VSkN7nsZ(UjZOpQ|QbnW*Kj4N-rRES/;4u Wo!R%.jE%}\F\loմ9c}.Hb}U3qzQS>_cj5J VWTʟMÚ23 uP-Q]?}ˋE { C8|Έ \fg̃LT ڽ +*IpVt3[kq_QE )hl?  AI.fmø2[\0 ZkVb)jv#p06.)4A8jXA1FM|c5#x5+ [L쑐^|N)'Օ3{@6toFԊJӆ]2h/6*i\t8D;nhATq.n c[RQ1;5>9FtU@u,a.jQUQh`yW«$]8[>h5[!PhʧՕI9Uۤ[b}1S1ؽY&EξV+sA֏jd fߵKg4N߀?o*|&7WTNNr0nYVC % G~=v)!!oͿK)`^I.fi/> ՀF8uN9NK=?\̪CV ؽN\S^F, 뿡M/V1,[b1񌵜`f}A\]g&Sf9;=1-fd C0\kHZY/'~爺`SYm[3q-x,؛+/fU63kZ4 ^rQiqO<15|t\O5S;F{ pamM)h#kT(DFVBHUz IT()£de[J8&(x[( ]̠;Kں\L5Qse|C)Ol╅+CaQ ZNxbl<U&^]pUL rg.j? WJrCGDWw% @ɤ62:Q ZXR8\NĖ7^= zehFb)Х QǓR^6~F DԠgF&_qxpe jy5#(db^rwLĞdVLjSB$0K$P#y jd҂ƙsQp4zC"trgT^R9*ӵH chq2R#j=Fl51شQbBJEoK?5-/h<nQaН3u~oJ3j`̌\ThW"UC7rc8._js8c6\o Z-ڞPqu? \.Qy12bK%Otʜs W}7s _ B7;(,bf+ۇ)inڧi[_pmq&[P{zִޟ㗾K?۪konخ{w]u^3_7ms=m֖ExMumxzY[n=; ڨg׻{WVFK@ZOtӍ6*َl|4-2szFכ r1Թ?%q= Ϻ\cmuo=L<֕]Y\Wۮz]׻}nFڨgAu|;>J_w,ZKt{N)ʉpUͪ3ys,f-(>jPTLݙ:jLwF .&;WY ɂѿ{fꈙt"QԃM`M%)A3velKُ ǁmj֡&1!xQΎ[DR)wh-0M\ym.xI3114[gFԒF?\W4#z 4 @!&>dMOPW]Y343CS Ml.(Ix%pPdF3~I[M9KW! y-="I}ɘ݀MEp ,(4PwW !0/I4c\(jM&0Y?0b&OY: C&SZU*<"Ӽf(LCpDa4QdX?~ fh24Sx34~kgj&D(h5U; ~nrKx2y MzW`w0IPK3P4=] ֗FM7)~N=[ #׎A16(h y5l·iCGvxV=bNͽjO ! _4xxN#o%)LSk_]<clV6^4Rgӆ/zFb-W&mǮ褶\=;|>ڭ3QxM;#!w8(<%"مAs/d֢%+Qj45JyO AV$=3}&MD:hn,ЈPx̜e/% WJY6Q$@J{?Δ=C )Up`nuC+7F1*ly|P0E 7lR#ClFQt9+S%4J.%t#kW%y|@AEG}s VRFA(Gsd`/C(h2@D $iڼZ8\j@WI@A EZEiۄ (fL\Qy j!5tBG Gֆ7*tMM!$z^jxXp{j z;|ѤP4l%1P/8Q14ߨyͱv3 J &Ub䯅I5-5DUNJ\Q!H`H1sF٫ Qc(h_삃[a:o.j[i{%aF_1(w @z;6b([p ~}9a| t}*ft.: Z`N- +JͨnBj=5C lc.&fF/705O&ݴ0D;X P (_nF/< ݐP^9k) {6.? I8w'5d0 0y&aA'fz_+j?Ԭ9nZ׭Ady[ N@X[@ؤ=Z,n DO@h& @Ȥݛ5U IsDоD&`", `hҬD~yh/)k `Q@A3ib=a.eUD8صy'^km(hܲ悗ɌߵC C Z^-j8p邞JGAS^Mƭc]ԫld-(E,Fb [v 1Y3Fgnha@A ŭ_O!sFvld U \/Ŭ1<" A\x3>MQ1.jD{@Kz5fcN x^E ČudnbX"P,h_aƮwJ2g}Sy_\HsغUv9@A3pt=6o@"j\̞߶m1-@A30vOURJ6,E f';̥vFJ[ՠmlPLDC[SJhZY urTqk|&2 *UQZa9m/:B5PHhcEBB& &4b:H@ > EM x;tw" v! 0pƁ &'gf Y Ĭ'&]yS2 ܢ&P{jqԸMNMun0f/Q+BXj$*H/4@CnQԂ pnJ杇H@.(hr{b6}%2bܤ)zFOHk+0%3<`n눍 7f~k=1@H $@H $@H $@H $@H $@H $@H $@H $@H $@H $@H $@H $7_Iy+LIENDB`faraday-2.10.0/docs/_media/middleware.png000066400000000000000000007012231464273144400202100ustar00rootroot00000000000000PNG  IHDR g GiCCPICC ProfileHWXS[RIhH ҫZJ AĮ,El誈kdk]ky(ʺX&tos̽@'桺K e i,R@/cMh 嚋UB9$LARTVgJx22 R%VR%T*MRi<,g!m]%2A|Oqģ+1_d3sZTB˥yg;)bAɢ5þΝ4{%qCN,PCREd=jʗs`bW/,bS#$y1}f8 1\!h],'j8kep6dJӊdH]"JJUQ)kC̔&Fm0'vFHPoPǦf"4|PbՅ( n>O-B ;yG(3T@"$k: ߗҼx=NE*Vʋ5xP!\j~ BB1F,[qG| $A4$F$,B*UH5G~B#'Hry /(P CǠ(F)h6Z2 CwMI"zD0&f`ұ,LʱJkZ| z8g,(<\|)^ě5!އ& g?KH& * gMxC$D{|ӈ9Yĥ ĽbD"I8TH*#'&']%uޑdwr9,!/$Ww([?%"̤,lR.S)T==5D͡.VQg&hkUi:P=MD&e;Wt:ݎBOҗڣy5MWPtlu:SuJt*u\եrtysuktc-ۥw^>IN?\__U~cX38 >cc ۀh`o510cngoibXlXcx԰1\fs9s?&KF4:H#Q^FYƹ+&N&Lfl49c;`dHGf:&2jzɴ,LjY9<<|1 Ebq?X,6+U:4TXnlJZh5:zuux6 6Rl}mElھKޮ=׾ľ!ء#1q'ITtuv;opE7J2n- ۥȥh G7~>fLcΎ8nn/ݝ5=;MN~#i7~{8Ǎ[w?> j& Z4;0{uv(XT)s9Q9rKۛO?,їJNO7^O2~?zmb*oBf65;[Z:;z?8byǨJ /9BzdɮimwOMvzw}ңGw]~1q'OݟǤ?I gs Rľ/2~o -gn{g?~x20#c'O?d8B 7ʭzR@=_*=*x>F I;~2> pHYs%%IR$iTXtXML:com.adobe.xmp 3300 1024 (.iDOT(uL%@IDATx݇\}lEA,$*ز;Zd)OIȔdY988EboA@$+:b{H۝fg~s;2 @ @ @ @ @ @ 0%@Δ4"@ @ @ @ @ @ P1 @ @ @ @ @ @Ɂ) @ @ @ @ @ @s @ @ @ @ @ @@X @ @ @ @ @ @1 @ @ @ @ @ @Ɂ) @ @ @ @ @ @s @ @ @ @ @ @@X @ @ @ @ @ @1 @ @ @ @ @ @Ɂ) @ @ @ @ @ @s @ @ @ @ @ @@X @ @ @ @ @ @1 @ @ @ @ @ @Ɂ) @ @ @ @ @ @s @ @ @ @ @ @@X @ @ @ @ @ @1 @ @ @ @ @ @Ɂ) @ @ @ @ @ @s @ @ @ @ @ @@X @ @ @ @ @ @1 @ @ @ @ @ @Ɂ) @ @ @ @ @ @s @ @ @ @ @ @@X @ @ @ @ @ @1 @ @ @ @ @ @Ɂ) @ @ @ @ @ @s @ @ @ @ @ @@X @ @ @ @ @ @1 @ @ @ @ @ @Ɂ) @ @ @ @ @ @s @ @ @ @ @ @@X @ @ @ @ @ @1 @ @ @ @ @ @Ɂ) @ @ @ @ @ @s @ @ @ @ @ @@X @ @ @ @ @ @1 @ @ @ @ @ @Ɂ) @ @ @ @ @ @s @ @ @ @ @ @@X @ @ @ @ @ @1 @ @ @ @ @ @Ɂ) @ @ @ @ @ @s @ @ @ @ @ @@X @ @ @ @ @ @1 @ @ @ @ @ @Ɂ) @ @ @ @ @ @s @ @ @ @ @ @@X @ @ @ @ @ @1 @ @ @ @ @ @Ɂ) @ @ @ @ @ @s @ @ @ @ @ @@X @ @ @ @ @ @1 @ @ @ @ @ @Ɂ) @ @ @ @ @ @s @ @ @ @ @ @@X @ @ @ @ @ @1 @ @ @ @ @ @Ɂ) @ @ @ @ @ @s @ @ @ @ @ @@X @ @ @ @ @ @1 @ @ @ @ @ @Ɂ) @ @ @ @ @ @s @ @ @ @ @ @@X @ @ @ @ @ @1 @ @ @ @ @ @Ɂ) @ @ @ @ @ @s @ @ @ @ @ @@X @ @ @ @ @ @1 @ @ @ @ @ @Ɂ) @ @ @ @ @ @s @ @ @ @ @ @@X @ @ @ @ @ @1 @ @ @ @ @ @Ɂ) @ @ @ @ @ @s @ @ @ @ @ @@X @ @ @ @ @ @1 @ @ @ @ @ @Ɂ) @ @ @ @ @ @s @ @ @ @ @ @@X @ @ @ @ @ @1 @ @ @ @ @ @Ɂ) @ @ @ @ @ @s @ @ @ @ @ @@X @ @ @ @ @ @1 @ @ @ @ @ @Ɂ) @ @ @ @ @ @s @ @ @ @ @ @@X @ @ @ @ @ @1 @ @ @ @ @ @Ɂ) @ @ @ @ @ @s @ @ @ @ @ @@X @ @ @ @ @ @1 @ @ @ @ @ @Ɂ) @ @ @ @ @ @s @ @ @ @ @ @@X @ @ @ @ @ @1 @ @ @ @ @ @Ɂ) @ @ @ @ @ @s @ @ @ @ @ @@X @ @ @ @ @ @1 @ @ @ @ @ @Ɂ) @ @ @ @ @ @s @ @ @ @ @ @@X @ @ @ @ @ @1 @ @ @ @ @ @Ɂ) @ @ @ @ @ @s @ @ @ @ @ @@X @ @ @ @ @ @1 @ @ @ @ @ @Ɂ) @ @ @ @ @ @s @ @ @ @ @ @@X @ @ @ @ @ @1 @ @ @ @ @ @Ɂ) @ @ @ @ @ @s @ @ @ @ @ @@X @ @ @ @ @ @1 @ @ @ @ @ @Ɂ) @ @ @ @ @ @s @ @ @ @ @ @@X @ @ @ @ @ @1 @ @ @ @ @ @Ɂ) @ @ @ @ @ @s @ @ @ @ @ @@X @ @ @ @ @ @1 @ @ @ @ @ @Ɂ) @ @ @ @ @ @s @ @ @ @ @ @@X @ @ @ @ @ @1 @ @ @ @ @ @Ɂ) @ @ @ @ @ @s @ @ @ @ @ @@X @ @ @ @ @ @1 @ @ @ @ @ @Ɂ) @ @ @ @ @ @s @ @ @ @ @ @@X @ @ @ @ @ @1 @ @ @ @ @ @Ɂ) @ @ @ @ @ @s @ @ @ @ @ @@X @ @ @ @ @ @1 @ @ @ @ @ @Ɂ) @ @ @ @ @ @s @ @ @ @ @ @@X @ @ @ @ @ @1 @ @ @ @ @ @Ɂ) @ @ @ @ @ @s @ @ @ @ @ @@X @ @ @ @ @ @1 @ @ @ @ @ @Ɂ) @ @ @ @ @ @s @ @ @ @ @ @@X @ @ @ @ @ @1 @ @ @ @ @ @Ɂ) @ @ @ @ @ @s @ @ @ @ @ @@X @ @ @ @ @ @1 @ @ @ @ @ @Ɂ) @ @ @ @ @ @s @ @ @ @ @ @@X @ @ @ @ @΍DLNF5 @ @@  @ @ @ @ @ z=و-#z{V @hAT]"@ @ @ @ @@]ј(*쉸n}DOw]N @(@NGH} @ @ @ @(??kF[#6,Ju @ @@rFD @ @ @ @(@u+Ͽ.yהO @<9y%@ @ @ @ @@; \LNFtGl{F^ёB:6 @@N n @ @@&&chtLg\zdg"~NϿ׃2 tT*_zN?Wӿͧ:uu@GO;V6>)0>>#122#czz-8!ȮkAv1|(7.LA<_kBڐ\=YAE: dkkAzNc2|>]x.Mw2TF:m8-Ng׀\:] Zf HMGcd(?8=ck@v18-Hׅ~YT t,Gg͟Yf㣿t@O>wGgwgi0 d'델|vOĊձmX-ND @& 4ߩ  @ @&NOƻGXOcX<7)3Myw]d>'Pk&t,xrM}If9M7\E]0=|Nw ;Zx$0p<N~Ng١8144\9Mwu 9{eڪS%h] g?+5. 龭5?fgs̊Ƽ%$tLɓDz|xu  j@'Ÿ>.d;3_ :ҵz3Ǯ=Pk…kZ;6,0~3xr0y"N{*=gDZC1:<8)]R9{]6dPI H~N_̒5`Ѭ<椟筘 W/Y #md '+-]c|zw҅*V) @@NlƇcr\X7tZ馄mP/\~U )n>uY:[;?泎=Q>"{Hg @ @v)lxx⭳s1%olZ\ [gyqլzao t-> s)lޏW_'?VAH˲hqf+WN+Ň]."~sć;Gtxݣ1tn"-EkUҵ`E\84gG[kտ7=v,GƯ.hذ{mݹ:m\)]#lX '++icusĢy(T  @@N}}#1yTL;O19aL >g@re/0^6=l @.roL7?U8G9^U3+*}w^TzFGz~ATηo7F%@@ o<v:^>v.{6&Й=q9wX7zevl@`lly[ocw[Ѻ F^?)00,YV,쵍@;d7`N߼{ͷ?}GȂ9Y@kT9l5Kcoy5^ci^ݒSVYva\{Ƹ xJ+ؚ,p@NVւwD̟B @ȩ7I`rl~7Ə7͘:25iE 9WE缵ѹ`]t-צNZ>  @c#iCGyd<83FyіiĖו6-,0VCx#̳`#7`/Z8/o:ߴ6N_`#YqWƩϴpoukckbիLmOS`tx,yx+##숪 P;ݴ&nmjU]ã;Tnr-YVɩ1'c#@ @@ k&džb÷c샃11z䅘9ݮM'sWFU{ŎZxu _g @ Ρ#Oa3V1'@ZζqE}@t[)wtJcGѧx7lV_}bg{[ M'O})}p Rh-7mVi8cCGcT~u4DI"fǪbUߚ6vW dUN+q i; @ZQ@ G49gRl;J3(@3*z=+oI+欋J_ėcTI@ۭ_?1?=p<8ad+@WG%v_ݾ(])c#RY#O_~+&&R35X`ny]p5AuB <{9R9;TC(KJ9xC\{͚*JY P?z2^zw:HK tvu{ޯ.KDMr,gD@m6e @ !0>c'_Wɂ96 @Z9z7ޛVٙV˙_UI:xdO:! @wGܳq^ܷma,FU pxb{dt۞ -˷ݲ5֯]ҙcүHSe U ekUFlׂz;xcN9O3HcOlJ$3[?w}Z)昻lN*oRɮWF垽7DfB @DHa/Ћo=c  @@ t_}=i9]`lb2~tcjZ%FV/n[^3/z:} |Zt^?'O)K$Ύ؜Vȹ=r͝ݔ@=Uz@zz1 @wWWlM7޺kK̙=R}ә~~(8։sSռj go)YNbtڨ|.r]a  @ |揁 +01c_#o<96 @DuJo3+Hf4~XߗNF@Ś߼iq{>&PNC)| sbo { pe.-J 0VF{S0:'_!Sb/oJ7Z%# Dƻ  ""e__!@(ӳ1+1{yfxhss187uӒX:R LO1VǙvZ4M=oD M‰   } 6tAY_߹8 -5mؙW^};~x :;:bMǝ{GGF i=T.@bOvoI_6N?b3=  @ o_XjGi ˧O#gǦ} ;hW[vlE~L J@nv]ܕQy~6%x#koXC& laC gٳ\} Ї{hSykb}7@]@NVEQ戴]hR @ș 09>,?br 8% h;_D͍> @a‰N ;QtwVK7n\2}ґǞz>xh_d?'qʸ3r-'uNg,(uפkXpnijV( <ӧxA` ]=]+7iZkR3ZrV.ʧwGx}@_t  @[@ Ž_31(@ѿkѻb:LS gw8nž]?q}쨴;T`tt,y`<؁@+vcXn޲(K/|x_=~]P7 \neܱw[H߮o#PFxGO/HW3 T*8wmzڦZr2+rO Vm6:J @@r=~mUїb[Uu@w^or̠d񽧎p/u@}]K vz G8X]%^p\,jŒ}϶Xnܲ(/HΔ &TW9l@8G> ǧ_WEs{#c<= @h@Nŝo#)3{1viÎ @@*)g1~^S.S876?<~ZkBݵ/ 9s:/^xA @IDAT}/V(@{XLIg^#>.vG gf2 }x.Ia~TW3Bָ?}s QO[Q@NבtڵQֈkDtuN @ P^]U>|_bĠnuZw)_:O@k N??JY/3=A{5[١j /5'PJKmlMW.e& <{x s6]lXVK#3ׯ* P?x<3F )T9ف2V]@Nfѕ~w)Vɾ|e"j&@ .92ed{S ;19>Rި!г 9KSC@ b |~Ӽ9-#K >;rRMOe@9QBA2'rZڶ SQєO@9S҈9o 3Uۓ~׷mST>B9*x96 @P@ ;CCzhiۣף{ٶ ОCi?{<~J9p˴Bμ>+1/œx}gll&k6oM(/ 9 &\UW-^ ֯YB4Nr~DsKE)Ә9  @* 3U)*0~zobnjNN4^s?3 @?9p,: ܰ kIu (v @xɃQ#P'" a*¡׫'O7NFU֭^w5FC@C嫙@!nq={ QO[Ѩ@N9gVD V9bI @# SjJNN @vX9_kЎgZ\`b2r 9iֽz G^z2;vGrPW.M+lfl u]ukǝ)r@NQDF}ȹ_ '~+pO@NW@oUS#9YW̍mGT1b:w  @ 0u[iD/O4 &@!P[،;'* SW^o6@N 5D@ !NRg:;| |rZ~u9 @)ΟsMQٳ=bnZ5F @`pecWn RRoZKKg f. 3sCGh@Ns9C=1 L@ gf~n@N@i6#us|jWĮq$@ @r>UAF}&s}p*@GW53u; @Y9͒wVilϾurjgHi3@Nkc;B G_k% S+iV '+q|fOĎk#{s) @j/ S{SG;O9b @@*)s_ VT# 35@=*@NL)xfz9s 9$+w@ @ZB1.0vZ!g_rr @pBc@ p# f. 3sCG c]@ #f 4{9Ptvio 8Esr@NΎƩ{kի#: @@Nπbp_y$+@#7ߗ9ߪ!E)H9e=g9 )89;1\@ g憹P@NVtWZgC9k:; @ @`9ӷgF{&lY(@GwZ!'rv|(ȩc@N|[ uRO# wg@Nm=ro[96 &%u;bQgoĪe&8% @* Ӯ#_~ ?FWʕKT}[۾6Cٟ)ܐ(9%4%L@ c^- )(T9.^D@ "("S@ ''X-)7["V,b @+ \Hy| 睧 P @F Tzfr_ji i@NptO Y* SW^o@NerZvhۦc9m3:ZG:^E duؽ%*t*> @j* SSN@b'u %@ *PQ 羂V,L_@ gv$pA@ 炄 u]:f" 3=1 . STr0 E d fGnX8 0NI @@ ۈ9%8e @!(@NaFa%)`)9e&) LJ xpV R "/# s@j٬Yr뎈)c#@ @@rеȩ# @ mK@|^Z@'E.@NFLEi¨9q,]qQekĜ&9% @" .#]~ |Of 3< PxK SARer.CWȹ"%) )9MA@ g H@q9YZOz(8& @B $(@N)I @.9uauP " SPFrJ=|O9 )89;1\@ g憹P@N֩5+["oM; @ @J9Wy!r 1 @Mi  A;MK Erbu9uu 4ډZT@ E%Fuȩ\@NaeT>wk "z/' @ @`9@Kro @(9E u Pz:f ۈ^rZoL9vQG@ }ƺU{*Ӫ#_iG*K '+#r6=I0$@ @UrZud[_9-6CrҔ n\@r Ҙ 7J( SASrr 5@4B9i2r2δBܛVٰF89 @-/ Ciq  0هeYd"ڦ" 3%m\Z@ 6>)@NyJ)渨j9SҒr.%S(q^B9{#֬H+tȡ  @hvS | 0ٕ ~X /+ sY@4(@N I)(n 9S@҄rTz{"v^{D\QC1  @h#62wU ̣v 03ٛb {|TWr*/- si@T)@NGH}E)J9W9+ \٨- "nXH(  @@N{wi{+SڡS8@Ό  xpV B/! s o@4+@NGq%) )9!) L$ Dܲ-*wdAmm @i.ogr;v*'@3ș (@NGGme)HR9> LIb {|TW|⏑ // sy@Tjܦ쁜c[wD#̭1 @ .92%@NP @`93+))9%$%^V@ <>$pE+iP  - SQr +\B 'sY4?"r*n;RI @@ JrZe$of# SRiqr;6*@Ԝ"p)KxL9e-Q@ <9y%pqV dHE]D+ @ z97-#V"@SșFT@ B j83 iمK+ SڡSxAr 2ʘ@δH79hV-gvG.qD @@rJ?g$@ȹhVIh@N39Ptvio XgO㨮lTŒeywn LI ٿG$$$L&$$/}޻sKQݥ.f:ussea>!>9cH%Ӆ܇Mȱ%b=[dL P @" f-1#D0, pB[30guBNH3Wr"˸Q!L{9/B[9eh@B&Z9-C{D֯I%)!@ @ Z"/BNDϲ!@J!mBN:E!S+9^eܨ@ȉJýNpyO!{-o2z4 t!ar XLeb=vȚ"x2% @ $9AVcEȉpY: DBN j9N/f x#B!'"2rB`93r< Ӆ4U1(6RJ: @@if@W> I9\@ t8BN5!D+߬rϔ;O!̙1\r•(!'Yg&n-f!,?ٺVG,[8Q9,t @G!'z9r6 BN[02 S9>M aBNE  4B\@q%X@ $QٔBNS4\@rZFվar LZd-xXIJǏ @ @ M*ýpA 8 t9A B@ !3z r;dE@` 6u9>Ia̘BΌq#n@ȹso Y6]" :Ǘ @ @ L(BN!@ rV@ {Y_' t2sxI!K9Qr׈Bo x˗ѽ'=cf?.8*BA;WdV%2o  @3?gn@ȹ7 @ȉ\Y0"E!'Rf@,vBNP3QH 4[BNrN!Hr: BI! icΝ#r&2L @ B_3C\urpp@HB rr"r2dG t7BN%!D0,rڊ@! Й2trҨ 9"Z%ڽE_p@ @P9l@@ D O2( 9>IaBNGJ!m@ș?(K!'# 9̞B!BxX)sHo56n @G!'|9 rBV@hBNKBN@Gؾ"t  @`I0xX9MBOA3&3ctrnܛ 9Eb=ru"t3 @ K9L AM%3 @ȉNY)H!'Yg&ni9&|a#Fs=9;nd@wf .3Be="VS]HSB @~!L#G<\ BN y9h6@d@*~&$%B#3;~}9BNre!fXnH2х$0% @ 9~1LK!gZDt BNhS %6 ̞!#tBNw3{ ?@r%Y@z  rĨ 9y<&aXR)g2D `J@ @roBNK@%PEA  0{9g%]|9!+@a@`rfKM!`0@Br&8oW)rJ: @@ D*],BNpsG @ș-AL!!@ Jfdh@krZD/8Qyo{QJt)&Z&2*:B)h>tJd:J9# Tʱ޿;@ @ rBp,!'yd @ș )EJ; -"3&"A;J:?tG"!\dX_=,=ձ$xO`٢awYiz@@ z@ BNH2r< _@(=ժȑ")@TŒe[ !pc2˞tE^x5 X8fC`>tAYf@W 6.Ϟ,ЌɃK`eOFӟK3 ,HTҿ<FO];/d S9&r:5c{X)2n&D@ @rA1<'9b& BG)iuY&`X@Fue[ZN@ϼ%8OJ4A u#!"-&9af4ׂͼ@iKFgp@ G (gBNH2'b1u+TʹGdrD“i @pgVr\B9ӬT)_|SJgIRTsse@~#QFr<˰pG!/zCFTh  eXH!ǏY!&r? ,xr3"儈HE6&ևRΪs@ @ 49ϱԪ{ٯʕR+kU@ b eJ,=฾J{W-;b x2,@qNjhD!ڂD!'H"V?@cV-z9<8 匈G!9!RZgZRE"r @ x9Oa4rX;9x 4B[ )[G9~ 1%!PO!g# /'D@'#r&\0O\ @|O!)"@C! 8BaR%w'R:*&B@e9- LGRX;9x 4B[ )[G9~ 1%!PO!g# /'D4 ^w.i:s @3?gn@ȹ·o%(ZUJ'_W߂%0@5|BG)B,Bw FrQ-Hr-b#?f@qK'Sσ@ ^Έr"j`Ƚźoy@ BN rVZ Fg(KZqR"X^͠&_HJxͭ|L!əah937m9::B!#$rB,!'If@/wBN@3Mh 6YBNdRB=$!\sNvoUs8 @ @ \ʢ0BުSvZ G~'g(qdX)}$>gD+$ַHb>vTi(=Ur'S/Л.@ !KbDqǫ9-#$%]Ǝ d:D onYYg t3xK![~9qW N@eaSM"YϦa`@ @9pe6@i3PkUȩ\zGrѿ5 +=GJrvI.%*ĦVJ3"Bs6BZ쏐"(A[9eh@ȉFüJ0guBN'(3r&a' }91+Bc"֋dO @@; 䴓&cyF!3mB΍XɬV/ٍՊ9Ko4;~-{[R;؏@0 #OnDqCE_  xǖC!':JršY)9"<^@.cGBN5";3r:ÙY<$`Y"+ͷSN @@; 䴓&cyF!3m/BYP,3(5"uXϼiX:{@r~OJ^/ @FXrZE7xK![ 9sW첶N@eBׄ?rž!'9f@13tr,1r֯I&:0)S@ @%3[9"_Xqe ;_c?.B <! -}r\+#[F:+E kfYW t4xI!K9Qr׈@ gfV|RΊ%*p@ @%d9iŔKz}E8B#qDV̀X^i}엩S+V)TWVYj3}X 3=~̉GVɩV-TƤ싘۷zWX_ns{'uKny{'w=}܎hrA9 @5\I13qgzQtᰔg}Rnڡbo3>&CK,SԝwՉZwQOcg%/xoS/qa9G,Bw FrQ-Hr-b#?f@qK'Sσ@ ^Έr"jެ]z.Cma @ v@i'MBgh6?uݪBOZyU<#C?VP1B^~$P`nZ93J?ڒIuTq-V521it8s_5wAŅ5?I[vJ϶F G~+|{1BNvggךv1J'^߱e&ǎ-\4"Qo\*ٯ"Fl%0GLv$nQI,ڰ:MUNlsx6OSuIj||` w_+L; ;TrSnof8BNHN!g N!9ά"|Fq59Q:kn'vdn@y d2@ȉnYy 䴏%#@ȞbݿSdh @M!'r*? 9:K϶/t`igczJbpVܯœ;6֤r}V='+iᙢ-]T$޿D,^VqRj1*5FI. !))?sl6|Ճg9jVת*v/uϋVit 46rX;9x 4B[ )[G9~ 1%!PO!g# /'DfFĹwX.2 @ 9I8@qk~rR**ŎL5ܾҋc)xJCKf'b)=sZ+K˒? )k#ŊYve+?㡚X 'lJvEVՔs<2#>j1]?jGoi-S"܂$ 9!# wr7@iD @ RՏrbrK!-1CBN=΂G!'x9#b@_N D%[D{BmUPxIv㧧yؿ)/cIvS-PTI01NuzR]Ҫ>O=S;L=_$o;$%^\+TFOJRT| Wn7ykuܝObeO:c_8|dl-ܺr]=/Koc OG Hj^dWjzc?ص];tͶo̾4R+>xjrR)%ywK9E,Bw FrQ-Hr-b#?f@qK'Sσ@ ^Έr"@L+&*Ʉ2< @ ЌBN32B0 9 %9ARP9dVp.[P+`A4EiJ8Ig71ѦZM Q*M%iƏ%13*eQ>{PE-ϔ{l9aY])gSS|M)k,^Pjf'Vz@)i ׻r"#lUgN7?VǮ2fiMнIfRItNߕNn^3;_o5zS8[\BG@,Bw FrQ-Hr-b#?f@qK'Sσ@ ^Έr"x\+CZ)gRs@ tBNǑ3L ̄ZgiYQ9%wGZ5oPEpDVח~5KrVqM;WT _`?E&Ԥ|/rӊ*kRKz#ץqF(ozӳ+vǎ*H?ET,1se7}֖-t!'h'ֻ`BjYQ4mswEKgI֧$p'T?PQWZEi&Wr<BG` Eo4"ӈ mA"l 1+B[b@=zBNrF#㿜Q8[h="+-͞eP.f9K$9V\~W}_>t+8P⋶Դ^091T_U)9umz͊ݣIZ@r+ԗ$6~UfMjcFMeHV+8I,٨fk?T+MݸsDx"xK2,@qNjhD!ڂD!'H"V?@cV-z9<8 匈G!9!HD"# } @f@IDAT@ș ۪әhR+\Bg68劑2>Ti%ʥwT烙푬2wuk^=OaCFH-~$w3vyF_sٕU*"HEA7?񹫤tO+|K6#5ro1…Q<9g!g:BQr<˰pG!/zCFTh  eXH!ǏY!&r? ,xr3"儈:L'#kX-pRN3 @@ D;Y=BS{!Gei)xɮR+Ʌ[%)I.}GmDjZ JfZ 6/HæWi_X†o4Ͽ.>|qi_c IVzjj4#EAyBċw޸%K%Z*]k_V]c(41>RzVZER+- '_ԵO=\zǖqG<ҌϭxRd>)1Lv!{gXj3ÍKjk*;I:NR<7~{YߟZኘn9ݠ9E,Bw FrQ-Hr-b#?f@qK'Sσ@ ^Έr"^vo_+̟ۅ @$ͼn9O_bysDgI+Rrԕ(k8 J TӦT1PV4TF۶1y*d<)%&7Oy_S!sSc* s(BNwu|J7Lb>k ]Fz*%\~WgKYLu*Sb\xMc'NP9F,Bw FrQ-Hr-b#?f@qK'Sσ@ ^Έr"0ެ b=t @ m9`VTVșVBNҹZ꤫ߦFK5/[PJ'^j>+VL2k?6Q$nzw^;*Zb*uu'*Px.$1^$9p]Yp^[I[2?#bx%SLjjFЩ\>*kT2wU5_MU6UBdxQr<˰pG!/zCFTh  eXH!ǏY!&r? ,xr3"儈:H ϓܱVGv,_  @0r 4,h #*-J%%2xJu?nD/_|[.1͑^ ?ErOC3ӌ.ZzXަ7=k];Ӽq5YEg$ێrA(U9v!߲n$-1F2Z)l=ͮ~TFOsJWZꂾ.JM\ B !8E(9eX#!ЈBN#*BNE~$Ǭ[9nryp<9BrBD"f6="-ФL@ L&3}K!ǷXBNU/zYʗ޾y7NT6e$;_busZsKnUHBfGUlVs׭ձsZoO]uqSYii&G bvR%C]9{}q{*`d|N lmkfWɩ\yO*]EH:WٕtfS9!m2!ǣ!xa!B;^@#9$9ABBLn %F@ȩY /gD?9 u@J~ 8VL"c @ DBN"?w 9K\ G2EΕܕYIb@ِj^MZ$v d6|Rzw~Ӯrכ+׫tR,d6^HLM7l/41f#e7}ή4J腜@:WIҊT%$ 1UdSJgtV-IzWUygbBΌRr3mܥS])=zg$Svu!͎P 9?*f) Z~V(%9S|XjeD@ tBN39nhuoN (eJdn47ZHߑZj>V<%͟/7rTx7Ù[l}f[7_f˳nhEZ](ar9i*و%n^} '8iT)_|Sϥxƛvz!g*#xC2,@qNjhD!ڂD!'H"V?@cV-z9<8 匈G!9!"J8#zXeDR͟( @@șS@g^&G!G,KwH( ;J'_Rn2rS!jܧ˭ձ3B|?V+~uBΙۮw7c؜] iaX~JN 6I|R'2\ OtI!~lW˩U -݉@uB(]9eX#!ЈBN#*BNE~$Ǭ[9nryp<9BrBDad<K"0$ @ B[b `w5oڈKfJfQ}_ >۴]eVy5djTJ;MB5YUJ^"S*'._xC]6yy[hr.B.<)g,S)g$殖 sH,=GL|M>LV*ګRΏtVΙ@șP#x32,@qNjhD!ڂD!'H"V?@cV-z9<8 匈G!9!60:jъx3k)rjZEgVY*9#*hgU{r"BGiC,Bw FrQ-Hr-b#?f@qK'Sσ@ ^Έr"j#>LUw q` @A!s9#~rd*#Vj>cINW%>Y^;-(7մO/홈[fGS'v$fc4kO."mOIrѶf]օ#|qHh%rۊ^3rEbI-G +X*^T"8 E҆X;9x 4B[ )[G9~ 1%!PO!g# /'D&}wm;E iP @I!439m~r2k?&=;\C7B֔EbhVzyR=MԊcv܁gz)I/fm.5ݲ$*|Ů4@KBgW ʡbWUQf6bd̚;ӊ6]e%do{DMb%Ҏ#N(Îr"BGiC,Bw FrQ-Hr-b#?f@qK'Sσ@ ^Έr"jb=|Ȃ6  @rʘm'vmЏBNzCҳuD?iV!&kWKlx97S_R+6+=ǹʏ@UV7zW;RGڧ+N2Ҍcld7~R$p%!GG0{w+;$#nH]$f_;9??t=iZPLNG5wQ*DenTJ.!=*%ot[>wPIˎr"BGiC,Bw FrQ-Hr-b#?f@qK'Sσ@ ^Έr"%~zt%!@ / xIF!m(=ȏBhc*ȿ_*Rw*|Bz}ͱAr*g)T I.)ɑ]*To4TN>BdlO:J,%ɿ?_ʠP? ϒK`i 3|BN *WInfmI*d?qV;?Ҕ'iu\KR;oFrX;9x 4B[ )[G9~ 1%!PO!g# /'D4 ȆU*}>1 @B爙rA1($o4U7[_7ƛB{rϪ}j]%'+4҅mZII-@F0<g$ֿm/Jm3}cz% *Y4GBNt-Z(;tDS)(wM9]qnYҒ#tg>Qg30eĴ*SVO9fS柎ZYQҊ>MŷJo֤DsBۿW!۳b[ 㭃 ʄtBN3e .[BNR΂L!@+rICD!'DɌRr"xV9m`$L8*刅t07 @Z! %tBNS0mrޡBS\1rThv`y/ XnRV~Ê5Mojp,f.#E2sh*+㯪Hs@>sǗ$o4%ii7gRޛmQ 9FLUh>J8fW]L埙Ʌ[$U͢mުӝa?~lbIɨPe9B3?[*4M oJSg W*5;J_=uM[(Zq~ţV!ߥrc?.vBG9@,Bw FrQ-Hr-b#?f@qK'Sσ@ ^Έr"D\dV-eH)3[ @  xaK!<͏BNb& TXqɅwBηdQB"FV)y?'R6Wͺ6m)1 3;UR02ѾҰ{2?aWJZMiY~#Fi8t] [&2зr*$ґ%͙ޗJl|BN~B:>7?iXӫt5RHg5'WmZf:ٍV"*5;LeߑʥwucA[lc?Sr@(9eX#!ЈBN#*Bloؗ._'K,d2p 七w!' Yr_V9,0ͲEb=2ζu"R @ 9HA"R^?!pxCGR勒^AǪ!¨OC oJߔZ98䋶3N2>)w,KoxeObD0q G~Z*N^DX|[:h'iij 9v; ?.9!-$IHDBtbNbd6Ӣ?E{l|WR]a5#xa!B;^@#9$9[Ly^jFo^zMחO"CI"cVrg;^Q荐,{9/ pf3`H[D&aH@ @K9^e@iJc*%IЊ66==m3Dwd7|®b*{85}=r>c,$"8Y|hu-ZC/rHkC)|9W 6)'J$b~3a9J')JpU-df+#Fڈ Dy&4S/*Lՠ춯Jb趩rn8?;L![(lakˈ*s$?"I7x>~F1fv~owAIz+hɍ֦_ [Se|)_xˮbc1[fuĕ{RMF6 N/FWqV̚Kώs97{r-)@gĢ#X}iް?#{2,@qNjhD!ڂD!]x(FȉBÿFw9g;^Q荐,{9/ pf"l` @&5ao `t_ 9˴Îk74cdr$k/Jj.7Ǫդ,&ezT#\cenJ>WKO[a*$-_PaA\12E)rʹ "٫2ƭӨxD>F1U[~ĎcJ O`Q;MO%kNv#e8Uq+rCoBhxJ5,7ޮ.3UTQ J| VDZ76SѪ;?=-I*o=:kĥ[:/GW x!# wr7@iD @q-v+ r!]YWz#D!^#BN:C!3źw}Z Xs@ @$̼E.jܗBNb[I!GBFInwUPPq`Cł]*|VCkZ v5KK_J_j+2Y1-Mv olZp#'>n}JEN %l'hc9FLɿ?Rx[?IdD n:}Ts5_œyaħ'zLk}9gjX;9x 4B[ a9Qr׈.,p+ rp!'eu!FszڽE~6P @@ t8͈BΌu&? 9Kv (mt}uS5%xdB7Ra1\UR);[}7:j!& 17VK+Z珒\Y2>8+!GG2yͬW{\SaG1kcE 9f{UnV<%II9̡Z}֖qLe(7 OqJG39rfB͛{r*9eX#!ЈBN#*Bl;^Q荐,9rw!' Yr_V9,m"Ы~kX%hM2  @ -9"ϼ Օ~r8)*GܑKY=-c;N P1cW/3SzL G~'E\T IbjIk̩e{TnVQ9)9 C?*D}N 9&m:ZGTJ7*R1ғVc)k[B5On'JFF*[rq\+v.7)^C_-KeY}ˢIg/i z9GiD;m9qG,Bw FrQ-HreBo(d9kDqc~9Qr׈@ gfilFdZ[d٢6  @@ t;0u$au*;F ϵ2H4طԪTX&b%gVn\sb.J'_Z-7X3")^i՜YW=V:~Ne}@a*2<rIJ^I--ىEO;ѿJ5P1yWϩYk%a[%ַXMsCjT.%j rU;Yqd.ļ۵2MGn2,y&%I}___RrU쯥J!ЄBN04BT;^Q荐,9rw!' Yr_V9,$NlMGv^: @ d8 8E 9F%i9qcqpMB*WNHY{w "wj* iuA1[ -OP*Uu+WI_T9Z>ӓzQ7=>bNV27cqv;dV+ZZYog3sZΎ9޿hB?*+{W{R.#Z x!# w"h1͢ &d~OBIɒឤJ:~O*䜼ZWrL_GKrq,gJr~,EV B>~&.;\"+8ddp_+~ !5N7wg;^Q荐,{9/ pfHs"ZzL[x~xdK@ tBNa3 ̜wvT ]=QEK%+Bc$!吪V\9):j+UZj9=BYsTĩT(ڢB5SBMP*;)HEF20$nAS|m|wi܇&]`AT.#H8kEόu]@3ҙ]UKlJM\Vf@! G/.Rl<_B!$4BN \K-t*)sT™p̟+K̗5rL!Ɖ^&? Z]2rg t3BNZ.qp@ @#rE9L+ 99! 9e!# w&\3x 铘1[tT*Uy_mӈ!'rm~/_9 #!ЈBN#*uXs @/6T+C U:YLD D$, d2,3'!;Fz=bwD6Ή+EۣףrL+ :@aB3ٙJ8}244G/'KU;GC:ժr2:&/ko+G9ѮC;BNhS!?,wrB LG%04 };D.@ BN!&,$Br"l  x\ R_«幗/D,~㌯@XwmyN? @:O!̙qrf[ e9]NC DrBLBx$?wAs\a0WϑoЇSѧGU93VWrbA^.ђ+ɸ8ntV1",Lׅ}Ivv5'ErqǾr|ޮԟk%ƹ;,t+ *Ͽx~u A;HH__֖peɢyү+LuvbYFk5krN%˩3-'R,Y CV.[4 > p荣ڕ|N$CgAӾr"`J/?xQ?uC`v}jٽO+dd ogN?*?z-6Dž@ on2e:?J8}24_-gK8*$J*c9n¥VùxyT* ߙr"kBNfۓ%rjBN fr!gnZoX%֣*ܾC @ B_3C\urpp@@ D 4$ 0Crg Wx_g4hH0gR̤Dr%yl<3q<>g^^9>Ϟqx<Gٲ%+1%Q ȱo5M ``Wo=Uo)_z@Yg5h-ݞoOR??hn{wܶz4`wq\?6)k6o V8[9\;"XLI55榙"m˚_&Lgpx\#T2.R/4TWmrJ[1 TBC!r \)Ozm}t`PD@@8MW ߎ3(r/ 㾚2#xG@Np޻3=ޢ ߄du{2\MW&3P'GzĬMYo{Fued~b9..GF 4NCLզEpeeE IMY!ȄzF4b/,j[ѠqU)MƵ[%SUaLvX KIz=4bV1a#{$4  +@ rkV YKD@Na"PrH p:)o{vkXK E=m8}kJXm6C[c&m,wY\ʌZ)gʼfڭ3%S0V1SkK;[m8 WYۻYLLgNi &gV±Vę_A@NirWųTSzrSa*^Lfk 㜕f6@@ϖ&N hs S,IAJp2cX>Q;Ѣƚ? +KzƴRƹ[HЧ{bfoʗ +í<"@ #v4 V܀ymmmM&tW NSca]~xyB?2Q1+;ШY)牽 zʄrisؼ!@ uv, دϤ25a‰e7nS[KE&^&'g5:>LgrzFE"TDDrr-o3丹ޘoԙYV@Ni}m݋)Q-=zFzKN@@oջjgK jK=, ١!@IDAT*qD*Tj%6=@r[{f O@[46gޚ?b畴;_?Ь`NMП5fFuex>3vS@;YȱWx}:[֔Y ÄqjxҒf495) Ψj8iYUʫ #/@ Ǟ{^^8@9qw}3rq^Ӌ9q){5>A@@L{r~@Bǹ PNrЂȉEY,-fU?ܜQ5qYOkZ%'mP|%4*O%WӘTSzrSxӇ#'7> OVVV4&31!&̱9PP{\ yyh9^H evqyM/^ c;*Ԓ;5.A@@ \ɫsrn@b)"m @ 8MG;k(z'YQ?ޘwӗNiWs$kL 絑>9fD ^ ,&S&3䌆G&gV0+pͰW9@NԂ/@ Ǟ{^^8@9qw}3rq^ӋW91;Ӈ{e o@@@K@?U!@ * @((To|z:cƌj+7&>>{EOkVki6G99BqX ȱW|nN̜S3pF504yY! ScwIZ` GB=G9/sF@3kzB F:_z:L7   ]9w%^r*< @ ))/#@ |s{U BzY߿4aVUrnH}&}Dj5I.;;丳^{ն{ֵ7o4 肾򨞽5Y58]/lhpyBOJU?Ya}ܗ*\@ٽ {u8ӳШF&3N*^}(H@Nn(@ gCu?Z.wt]1y9(#(2PPڽU0]=*4]"  @ ȩ1;rI@@r[{f~k'wg^_+sYUÎmQ}dIJ%F4;%@ ]lثz!7aiiɄs&ggVɄsƧ4eVΙW*M8gU&Sb|Ecc;rIv9^A_ rP7riGYt<*/,]"  @ ȩytr{F_5kjv4E-z߮xu}*Ne}w qW=89~`69qP :/tzIИ&4i9s>cl9]Fܜŵ ȹ+j Scܕ$@ p[ BO <$;Z) @@A@NHR~9#@@\r%O 6DEO֔~ִN&>x>!k4a#3&>c丫^ {UCjmiTOw:ۛXo91Ek|[hkuqȹxp[ ȩ0"rq-兣 x#wח9#@ 5)c>ULa)^3U    L*F@NŔ  p"VRW [iMMjnnAK˄s\q$S\OZ+ݹo3 丩ޜ o֝YW@Nq=sj-+c~{tdVeC@@ȱűe S6z:F@r^%p"PPSmPwfͤWL Ysݍ 97չOքر iJ^(keXT]bhҤ w`ZX\Lid,aVȄ&sL8(6B '_9Ϋ$9WkAjcs@r 7݂[9- 2H    ~B@NUA" P9%aQ'9ѐ_;ٓ5fFuex>jqV_8٪YS{tu5!vl(@ gC>9-T WCC 799(7r峂8>)5ŋCc   9ީuUϔ@NU# P8*\@N`/_/=V/O|Roߵ=/jӎHրڤˆ&Y]rUO/Ά@N WOw:;bni0hMD~q9s s9# ML ,,$B8t}e9Xz䔮v\ Jg[I-ȩj0|9 Ñw1>    ;丳ו ! 8P@]@N86cckUm>ݦq[?ՉL g>3޸O@jq5 6=m0ߛSpkτW ݬ܂78ф2+jq1E8PM' UgJŵrB YL9Ԥ- )C9SNJ]meK@@p7Us!25@#@ >@|U-d 盟ޭXhWjiE?4Ur,œmYA#+WF k qaQ=6%9֨%ikmRcCLX|Gfsff504?s&f553dZ9'ߖ9o=9며8[1z;'飔rJK^ SJWk 'jV[?OJ:G   69nKC ǥeZ  @ '$Ap2>MǺjpkF_}qD>= a}xӐ5̾ʘ~dgpk3"SMZ%U[ZҨxL1`0P- K XTQz#r)_Ͼ=)&mC@N9mrPj Uruh|Ov.@@@rXUΉ@ ʔ@Q@NPU)d }w>/;20?^ϮM*m q}DW3084sU0XB9r];55̪9hQKsut~QYΨF&3pN*.J^l@9ȩr-:3 9qN% ȩj0j SU[ Zwv>`VٿCMdC@@ @ 4Qz97@*U@NVq!@1 X|X037MeDUṈ}h_cMHѯޜߛUYybXā)"&ME@NY74lni5+ѬL8'Z1םMå%ΙQpLXgfvp&n}D g=Uʫׂʫf#"Ujct9eP5rUpw0YnH(:]"  @ ȩ0l9&A@+rRi所7 X+|T0˽lZ?<\Mh.|>`n~z}d66\.UƔZ&[rlqqp ȩlo֖6u5^YUzN/ibrڬcs46a9S&37/3lç!@ ĵc@N׈n.@ gs>E 9(j ̪ۺ{¬slds@@@" )"&MN@Nli@J Sb| PMYwg|/;&R߬d$bB8Om{tb?R\7^g ) V**C]W@κ,Z'VUwgtQc Eo*ĴY9gDWޡֆ丵ޚ7ׂʭʭ #M@NnNfr6)gȱV.I'JfE\6@@@r-J{% SVE@*TE$)d 'Cjf?p žL(ʰy"5 ڬMW}Xߠ'46gkҨ4zRJ9ԥm'8\>憞L0U j0᜺klW߽9@gJȩr-ȩz0rq ȹWā1֐yJ> p@@@R)*m]@NIi@ S5b kx{[ky9-hS~^]|jyiqz8ߨXƱ48ҷϏꧯM:=D+2uQlA57ݦxj' @NnNUr*>ׂ s97 )/{C@N\Ɂk&wZ:wL2+޲!P1++ZI/ie1;yȘG#se}_u>c6@V֪;M>w۟ͪHX~E/81O@9qcr#@*N@Nŕ!@*9&c믒cMZeм~z-W4>ͧӶTФq5许#<\ZoO@Θz' ScD[3ᜎf57+n95fT6J '7099qTe ȩ;Z;@N,i<rN SzVr 9.߻OJ̊lU$gĔf-Ok󵼰 --kѲ<0_wUhs@ zzB5/kߝw/V`֗ 447gvƆ丩. ! p9cj9ƈ>yYUOfZ1gus"Ăڐ_P&z5ԅ57W;3f gxg#ZurU6jVW[c$6{dVjS{[cPc @z*dث{^^8@9qw}3rq^KrbYܰfȼAQB8A%o)y| *?;8: :C@<VH'hV/ t)K[֭`Gkf^(zZraQbzY@T_N2_!2.@ orr%uohgT6l)̍E=w{FWG45:Zx⒞?_הy-9ުgK ^U;TƣPSKKNv69i͉*[@p-兣 x#wח9#@ 5Tb < C> ߣg5  q >-\/ ΀VRidž@G TZN==~H5w*&$\CflW@}8RC5J 0@pPf8ѣ`t8#P@5pwSZ)i:>m:j8oUh[TTR&3Z\:uL31mmgy61X8k ;](@ DžEؔ+Ӈ#'TGɭprrs c>\ yyh9^H evqyM/ȱV=q@*opJ`y~!B8sϟWVV~@*@}jUC5kU5]9w%^5g9=N %=)d/qD+P@5놚G6DŽ_99lVfф`&O7o&5iYa/nSG,SS̈́qY!rN|ycRrr,x$wr<ШrVs) #Iޝk;Ҋ./O3*=y/@ 5` ȱMp4/Ts$c\ yyh9^H evqyM/ȱnxȾ&Ʉ\)@ ǕeuߤR/rUM! > 2/o~"U(P)tMѠNnӹm1ZNZks,%_L756;l{\@\0}9Mp4/Ts$c\ yyh9^H evqyM/ X᛭=~V:_VaCaE>?7@p/V 5~/މ23W qU9;˚?u/w @ 96O@bJ X>錅֘v֪+R{]H2^1n&88fu˼N[plY@? .@ ^ ۞&*r՘k=//M Uv 主98\]m=tdndCqe_yS! nc?| n.s SH]o(5@@`/X+sp@%rZƚDt=]`NsbzYПY=G㇛1m'Mi`:r8wUrVa*+7arPeϑ@s-兣 x#wח9#@ 5#cҺYGHgHњ5C N ǔhJ2T ۺ3>%_0੹3 S}5ӣWdߟ<9& |zE^ooh XaɤisIKN"jsr:ulWҋ_;7l9YSسZ` GB=G9/sF@3kz)G Qu\ծopJ`%3k~ШS ;{BMO=pOόJ@NU˻] R3E` xT_b9QF7 TK gL |3%Xf='^@N顴rת1wR===L޹aqΚJ'@ Ǟ-{^^8@9qw}3rq^ӋӁz9!Yڽ~PxAM|栗NvK_ xR ҤƏ=_۬9Q'Ϗri_7  5@|G?Ȯǽ6u@D@Nan(@ gC>@ '991qP ȩ1 S%b s >F 99 '9:{F2!P6eMOJmt g|>uJ͟+<3m&Z}rf/}G W~3i@,lޣ)a/30wpi9*@ Qn:+Ҥxܮ,ז9$@ !h){5Abr #@ ?Nrꢦ{Rgk&J#dV2N|gJ< ik;2B@tmj3B&@ 0?vH`%oCt @E:*z !n 㶊2r):}S@N15iˋrXu͙@jʌ 7_@=]nWN ^D_BS#3Jͧ5Ѯ S:ȉHC2L.X+p&/{x %G#j'7/(Y?4@!r \V8?4ZYJ:/]! @qjO|QƝ #E StReS&㲂28NN% STOە%cg:ÚV~5J Li619rPRr"a=~VS %3ϾoXك %?QJ #PB8Qa9_ܨ W /L ?m.@(Ҥx䮛0ו 9,@ ap+Ҩx.*{9G>ZgƘnAߞдf䔡 C=a8K>_&H#ĿJVy=:E@cGTWIq 9.{^s/M@@L?a9_l !  XP,Pؼ>scCL$tkoP9sJ8]v7hWTڣj eVɇ `Υy]׍E ͤdÆ@Kv%@ \9nA g )ܐ+@ Ǟ.-.LG1[4xmX ML+5Z}\@N X@/Y)*ä^Ds/A| %6l鿔|Xd-H@NA|JzQ ~Osf- @B]'T{ .(@rUpNtLOը>RZ⌛r.Y]0߇fZ6!PB9r]v9^Ao  cv9w[_6V~^1%'52T 䔡t X7Uv؃ҙp&Dl.0M|i 6?O@@$ O_-p&@ *x6X 󤁯hyvd@\ +=Ek[\0!d TB 'n7J80N̬cDXms~sZ|sJ5br{i9('I erq.J.@ tr9./G ^ 21nV!ߞf%j^)Cȱp,ߣsGh&C_`9@.5 NJ6 "PB9Q7+$o=ht  X!OfGr9# pG܁{F~VwN.-м~ڤ^䂷VAmR iV)79ԥm'SnwRNJLhzfnuyo%f4>1+@ ߫Y@q-兣 x#{-F MZ!ʠn_#0̌*,3/"@ ()V Aw9!썁pP`/h[?VjH;NW -PjGli|{/9R ƑJz,_,8@j0pC{qIֺ>Qߠ6)vcbQ?$s8 T@9рӠlRg}n|jYJ+mvZ| }﹯l؂wq\59ӾOmߝiT?4\ҹ))/; @ Ӈ#ɹY<%ƺ#=}g c^կ~Һ9Xzث{^^8@9ȱW߃٧N)W4^#_ |^YԐY-> ^xoBJΧ  ;ȩ#HM+*T`j?RHWh ΝT[:\>SWrjRJɛokiL@ Qw>R}dF *rrjM`=fOiֶȪdLN̥5<ָ>4Ҩy=\|zYi1xM@͊;͵fEϫ΅1;++@Nq+L {܄m GB?G9j̵&*{rշ!}9ܥ=mjj0zET֣cY+LLz/kQ%'5;1e1 SZȩJ'2 ./0ߙ@dVEfC@UY \7\6a+ JjzqiS07>X+hP{T׎ZL@ǿM&̍}QJ,ݖ[_)ne ד֜ cϜyyh9^H ^rPewϑ@N~VƉԩ@G&ӶU ]qշ &g9[f՜=)-$b=qro 'jud|wat@~S[@|~ p $P{?Evn-NFrJJ,%nhr~Ԝ#}  PWiFvF @e8ȱ2}Y;ܔYf=Ʌ%]M@Yq݂ƈxHmm1nQ4_1?_WZpF #N9yqbȱWn¶兣 x#{5Z` GB=G9oVnn0tRNhQcg< FwMirn_#Khf̬Vwkr|F> )=HYp hQɟZcVP1Ga @jOٽ=38 8gMOEXQz |O?i%Ph@0+&{TszLPC  P^'95gM(s'ZcݬxMJ51b=3eV3+#&5J!w?a@ν?}'Sg_@p=//M Uv ث1{^^8@9)n}᠚49ۚLX'ZBvd*4^]ԨYAgr`JZ~Ǩn 'd~'w|0a; VS^!PY? @+Te  dVȩٻ#3f$@ XV+?Tj󏞙c؃ -0 _HCe!Ep2lB0>ڬjR\s68O&k M/qQok gθ57@&3|]J8)xQryyh9^H ^rPewϑ@N u{pNvhVcw"uf"o3zsDiڰ{'45<7nzRڝv9A[sd_(L`_~y'b5$9@jTSOf,J(@ 4퐀 ^?SE-K+y̡  c Ud {fL NXWm~pq~FJǤ}H^h(3+|QL,f-;דN[]H]Lix&B [0'nrJKӎȱMp4/Ts$c\ yyh9^H ǙG:rd_MΨRz/kf՜YY+강F@Ni\7m5@Nxk 㜕믞i_|@L>;4U@9 G)B9,O@Nŗ*<7??hi⺖&L0es8@kV";ޫ`Y) 𚀓oЗNZ)g6B0zeL7& 6:bBBno/ꛯoMk7ԮC&Ğ>~Y{EJ__Kžق>GLh{c$-9Y$@ K@Nɦ;٫sgozL%|8==Ͽ&&#v>2Ǜ_kruξUrVaj+{^^8@9qZ/<HŴnUszuHc&498%k5e(j 3r X+wCCR8AuQ_ _h?0ψ&Sj0@/ rs ȩ1<i-MsRC2`) DUK*NxC&sĬ/I_4T{M|%+;ԷϏ?ޘtfekOmQܬzK-{3V9&=+|͗G"SZ5V9Y$@ K@Nɦ;:ښն1a2ƧN[kt^- U%@ ^rPewϑ@s_ Ǫ Մa*W\s9 6[4ƈtҦ?nhrGvG?zFz~>92 )#>]# `cPr*:-o VE-nVIh%9e󵒜JjބtX:o`ND@>!±;_z̪8j?d8 m@ 8ߢwm_Cj7'G54ZYX|ެsjK]VW?}R_yqDܐcs`@.]%@ UdxLHrI3e 9f5[e[:k6 }L!#^J/+10 }< O+3?9eN7-?~ NKKhp&"x+y(ta xL@ ^e%Sec62+9-ύhivX3CZ5_sfY8')Uu<zβЙ]io7_tfp@W'XYOK}ZI 2@<*=vPO=<*+Y@N%WNpVZNsҋ&pc^`lrݯ?79rJWZFL+7G&'Y˼g6pݝUq\6@  ?ߡ5kb^򨞽9fo ·7˧dsVh@IDAToFuqpnn^!@ '4NAa9ӝ丮OIQ@N1i,rc5s޷Ed mWӖ95q`2qb~I8=:Y1~\ͬ3;1+1]M^Tmȉ;wTz)< qI! @ Ԛ@NS1U;^9-3C@@p'9_.ukD^5+ьHyVyx{tU;;Ցyf8!@ ep7W;s#Z3)+:'@ 9|9Ggӱ=iݦni Yzyv^5nV_KvNrP9ZaFh)à )--# \8\r%O   p2ݿݣhp37UȹHԛu nĢʘ~s}j~ cߌ3pZ@69n7C Ǜug S?\*UVrjL큽=~V]Nh  S9`$  ͺWˬ TK'    |3{RvߴV"M9[Sm:fj>nVyyT >l )̏pB@ʛepesa^Y1f*9UU. `͵AtE 4KY=@(2te[:kS0A95d6)=qNڻ]2fCrXU PMrZ+՜#  T]i0O*\?4KC:=;L q]ό녾YҞ临LUrJ_NIۄ BQh4HX`P$@ 9%KZZZ|i/,jvnA)Y.`dPrJ_7.grʩO S (u g(B5A5omRסpNmcAC7|M gCd~y7Ү>`8wI~8r )<" pG@? ,@ @@@\-d m]M27_ӯO94}@xU'ZA2(arJKI@N iƺ 44ԩ>xbjj7TSQ؄tA+s!ku+JL $&g4:>Ĵg45=nv*C@NeԁQ&@ 0Zq_M6#9U@YEjj9]vG;U]}Ⱥ ˲N9범v/ʋW{ttdz丹 @TC;F9ޭ=3G@@(m:Ufeq}RK+k>+ֺ>sUu1go/-b+L@Na~rlzUKS\ndV)d2i VﰆG5i9֊:l S^z/8mk] |'Zurl9HP󰀮Ge[}'N Do@ m ^z]5+/ se S&xE@rQd9\Ɔ   j'9ۣ[]Yޜ߿8_uN 'Zu}@-]Kd41/; ȱC@Nkuwj׎neVÉ/zrn[72ɩ-u#@ uYqbz2c [Ӻ24)DṈ{OQ-z]f~ `"@ >{MMX'ˬj`yy٬^d2T*Z2PO0P(4_{(yo=Ζ^Zҥ+o]S96O9yqZE ȱ_|7Ws#\s \2:5tղ٬ӥw(+pS J Lj/d8V(g) z""2*\@N!^@K\$Sc   ,t DzZܶغ+7>fu}|AKJ,,i6inbN(eoj#s HЯH@&VNvjKC8sݶ>Z_?]Lޏy_8؃z#ٚz57)M܂f͗zL51(n+G#EU37Tks\gJޒ7[i֗֝ cϙk=//M Uv 8Wr֫lR];2AB?&ߑ'SxoB^ >Vה@Nr U@(ҸjqǑV@@@-`ݣ c/>7̙:}ڄr՘6Ygqz'SkQ#iYI/k+ tBUqòV߶`xoN5aKCs;m ȱ A@=XΞ:eV쥥ekd,a]9QڟfsZզ6u5gB:];͊;_gpAS3t1)S+F@Rp-兣 x#{@R i" FEزlbNI\Uկ)̱Va+L@Na~ s#@@rJKۅ )T@@@SkOo\WLV'Y|Ҋ. ?/@ g}"PIrUc-zϹhDkQeB8oDg.tMڻGvo5&Bߜ7:>?wQ`[i֗֝ cϙk=//M Uv 8Wr= f)ݞ!27V.7bj'@ g=! ɾf   @Qȱ_kVyz}P7F 䙪Sb>+ѫzwVK< 4OO#"P rrB שc٣C8=3'ސ)]'v= ot*/]<6 ٔD@NZ$jsrJ_WWM}ѩӶ=%4LkflV} 9eP]*x9]+@ @(knrrs(@@@.P@5:9]'6PGTHsAkq^6+ 9)82=Q% ;mc<|@سI8_}S/]ɩ k=tꐬ<{ތc&8/99 qH ɽD\ rґrTmwΕ@Nij{$V^M jӦGcojbwb~5?΍1: LMh<rJK @ )?o.@ gs>E@@@dXv7G؞YRD̙n'zִ~}}ZSɒ9$ PrruSOWۺ'imK{L1vZ7ޥw=xD[Ze_o7n\cI@N irrZ$jsr[pmXm15vնU[w@b-u{!#75[{5 ism ȱ  `[@m2N@@rIcE SdPC@@@ WJkS4ݵ:NL@>YA~8ɤ[sguihN<4_R[ȱE@N>xnݓF&.7ny1wBiV9w֬ؤ~E]yƺ8rH+ ?ׂܭt$/U۝s%Sx]C`&pՠ>iQ/_x^\b^}kT׀&d Zř/ @ ȩ0rVk@@@*)swH@ۣ:]MaYA\Vαn9X47%L.,eҙ ΋}zs|Q qR;q}pSf%p$[99g6%\LX~ϵawa ^aa'5IiQΩ[{ͨ-Mԡ]OwW:u"gՉ>׫K.ݬFk⿐o׺/{Y-& 6^$I@}ͣUPwĄ|fEرdQڡ$쾷oP'M 39rH/ cߟ{}+?$j{srV@("/*SJ-ٴHK-V Yǒ?z_]j4NNY5dˬsu @ Uf n 069|@@@Ȑ9VfAIH++<_KB0kz(hV'2La3y1a±Vi=cB9uIt>/45\ZثZ+{x<ș 0E@WzԯO掿R_`n2/&@ VE{ؤN]U[GjzN-ZPcgWNwcG$ϒ2'@ Ǟ={N~lE ǏU֜ 8g9Vϓ^?T'jD}Va9Q'F@6 1v@/B;9ޭ-3C@@p,?P >30:>HF '9ެV 75W~Ihvf9VS'\56 I-=O@}kԒ@͹qVפrLfthTOحOpY:46v6 ZB@+ O!d,(H g    Y 9ިgA ~wm[7Vaa~I m:a9MO㎥rǦ+],̃Zwx}2=9 ͽZS9W9:@xx\nQÎJ8Onc h:9+ Bsr."  G@{jHW@N֎? cq~٩;{tuY_jOז[ )**Ą.]q9ƛ I'eF@}wԒ@͹qVWgp#iUg}nU8V@rQGf丹: @rP##G@@r9Y^@ 9(xTءZfYIV:s"| ?Om5-9Sa:Cޝ) TL [%?Uۛs%㬮v9k@t5ֺv5N뽧qvAZg(D du< x!  [ !-. Čn,LO~`~0WEAUU@97qk c0 =K?9YZ8B@ W0n`rss=lG;X*v,]\cwhͪ%q74=3d=V@Nj}==r;s/o姖rTmoΕ@șPϰzZzSM7[tz8o+l 23"@ -` ~ gǼ dG%   rϭW胻=:Y?&k&f{?=Ϣ!;eC9P%8tmݴZo٥⸃}Cp厮\X8x2w煴kz2k[c8sᖆ!TLg y5?Ts$㬾qS>u5ŬpI;56Ch:v*@ UEaAn̿ Mm:qq5Tw8^ ޞ#g 䌇55'=j{aViVVwy$.H ebd.GS 25@@@w ȉ9VMS*,/{zLGj9er,-7h˂8ֹ*;ןYq{T־ldcT9S5^:77G.ױ۵&~ =oѹ˷esȫ;u ,^X7ke bCA:w.]p$;]uኦr\Q1O98Ck9~H Y}w}zvf:v6Kc3Io&z2(@ ǍUaL ~ jg\ d_1   G/\L_^%sLmhV %L@6j;MOu?ڇ/69T-ƚH@N"k &I 45j4VHff}Єqmj]TAΙ N].\ީxB9)ĥ qNͽ cnryT^{Lk li R0@ idrP @@@{rk@EEZRpOPD?ޥ0+匍'șTYLNs)C gj,QzD" :? */T(/< ,[R]:AǺވY \Q>o<9~I g^0w;/I K\䤾9fPAHeQ| G0/ MĬD3xHD}#h4rș 9Nh @$ߔ'@ 'y   #trZ[lt4>'wQ Iy/6[mfU{HSu5_|88[mÉNľ 5YЊ3n>c<"&(Qi~@ "L;Ow?o(`;k0C }ե澱rT 29JUQςzܯ1E, l!Zr}r*bh7+-j{Ƣ30Ҳ6ju2IA TK|byӷ틊]ڹHD)'tpϿ芆{F" 1 / 両 a>rm߲Fwo9)k旮 cyZ/+9?m\O\J%<7O #ZC=G9ɭMIuWTjZkmX]G3pN^5lQ&oW DF͏Ͱe\@NKϗ "\@ #  dN LZ) ]Y"+J /9fsMѰY}fsET͗­ίÇ}U+*_6羶L%BNaj>0MJC:D[L=TyԚX+%.6K+ITAeg:o:IYښ@ȱD+w qVμК@9I^} d"9J.;oQIKY%Rtz[4Ia :!TD91A@ rNqES@@@)@ΤUYe"YUj$Iqn'׻tɐWʱ58ŭn^f'm-ЗvT X+Ln&߽ءMV j_W+KgIL߬*9?3u: d֟_@3C ޟ#g5^ ޞ#7hVm\ZVk_oԂ55y 49{A# ׹A g.jN8Ѣ-  |SzLY   șDVdغr}rc[&7+sa@?ҩ#qL³RL g Lݬς*{sf99fbgcMAL=Ӈl„r w+uhE C9V_\hWC}vt#eJ9t3/?&*{r՘{3/?&*{{rWP~PK,ҮOoךTP?JFyoa4Od(&@ g6! z97 s 3w;D@@@`^~ XXEA}zS>e~fEFWdi=,|aj5Zo0S~rK?%s(m?r v۰C'wlzmuQ7}Qݮ{M u%a@8KμК@9qVcμК@9ș{}&lbY˿̽Wg>3i{С ?ht`y'1/9d!@ M@H̛@@@9Ԫ!7HHY:{J{Fzkm6f k@wڇ%A#+K6ɭ݄~ugr׬Vo̪E֘j FS uW;FHh|M '\+r%lg^~hM U 81g^~hM U ̭nY_ܣfe`f8SGryY9-}rg͕Vy#E@[*8 I>@@@ @_`MdQi腴^s]'7VjU^x1oŅAk}}$flomF*},syJUD TTQ\+t6ttʺ6[ޘ+ w9~0@L tlrf   )s bj1E?%0ӉKYQjuU~q|9'm \llo޴B{k,/مA{]w{b:H9i@) ㌷ ?O:!{Zixd4{b>X?ޥw.uh/&ZiZmrv^ $M/ ˤL@Nh'r|RhO@ R.@ '\ rW,.ӑOm!]-]5>M3rlZ_+k`~pƱ;Rok1E}z@O ϴH4bs)@I.qM)   9Do@7<7}*|DtEM)l3Dcr;]z>۫^hSY-ζoYho6ƮV 9~p;丹:-dCJ.@ gv_@ڻB}m[hDw\?ǝ $cYo~nY,}zN|_jLt}I DLBr@ I59q    { cʢP gȹܡz3ݬd ˬ4uQ޹خF*-|s[_80aר4ᨽZU^YȬsq fqS5\Esx)@ W@N֎C@;(.@ Ǿֿ٤7%2$ X/nfeVR`)km]uYfA`ӭᅦ zjOU{[\~24O '%` 3O$+ ogϒ#]S@N:VJ~ [%7V19 c_kguT-[=LՇ}pS͊4]{rE:!=*a>9]ٙ<9ɳ'H,@ ' {@HtIsș    ?r]5Ć8OY|y"niرgiaVٲ&̗?νdw;e4j^~?tz_MI~@J_QܗDϻ<qF ǭa\vؕ{ *,Saa  G@A9qE">‘GF584Ѱ L}29)4 I=6g r2ϵ!@ Ǧo_أ7sL8<{c@~p^yurWʟKuЗ)0GW&/<=]sn@@@ #r2Em ȱ E3@@@-@N֖K;pʪ.guLܳ }a{J^~k(_Vȸy[Aѡ%/' 匍Ͼ\ɎNU޹خG]\L u%a@8)//VyiˊUQ^ʊRX3!` [6wqGo$rWS͈@B> OxrU'9g'<;?̈́叮L^kg89KxN-  dD@NFعM96h   @h"D^J2^޹Ю}d&TJx4h Z-gա`4w++7ӕw \OzCx9&A@ rҩ͵ q*F{@@@$@NMqPVӛ*UJoQܬ`.wϏ'w=o^P]]gpf9nVqJrʎ, ܂iڵ},V HLorN?: ̋ ܺp/Hg6F 'g 3c ѯ'?P@/OJëuGouqWj֩ގ;Ǝ I'!@x  N9ZN8=   IHg gY芒$^7!K Ԙ\ NY~@Vxdm$2W;5Yf\[F 9֊Aj b|A]jӁz͊AcOSXSc⢘aэ7[!`* ѕzm֛smas79nc#@ ǎm&tSYQjƕZPc6f87ƝfŜ#wJOK9q* 3_7ds%@ `vuLP|G9um;LB˵W5Yqa\o-wĻgd-rRK S @fd֟.@ gv"   2trJٿ esoVv۰7+kowYq~Q(W&d=^[]*+S 􏩩wLZM|"'{.,̈́yn7:+"_k󣯧|q@UzP79nc#@ ǎmBY &"ΚUKT7sNCSY1y~\.g 3DzE@*Ž`~~^8@9ȱ_]ަ7sThڬV&&7oQʸyjސP@|@Ȱ #^@? 08@@@/ yY]k5_ohPY-* iYf ,, UB`N~0+:ر0+FzFEn丹:͎;JMgZ߳YkV.Q,%!9{:zt}ШѱtL/b̽@ n3 x uhfeUI:u򽳺ὸca̹S[?QQE)㚎F șR%@ 'U =9h9q   @dì~sWQPՕJ[UkseH_!׍oL} ș[.YkV͝[GI9V1ƛH@N"W^j# J{wr ǽLn0>_w>)=5VpI9#-rRo? @d\69p @@@ 1c͹ot\Oz5fVc9~ض.(hbMZI_XuG]׫q׍1р$Ra_6 q^<ٱ!:NaA&&&5 +h<>+  <999G:yK șgK@zp/pn3xgu7?Q²u߯ʯktp,x2wiקp^Utm]Ù]Pp1ޤF@Nj\^ yi+@2!@ '\ӮRC@@@  |zS:3;kMkuшD؄twF93#.{k<5 I=ՇtqVՅ@k>J dr嚀Ktv-]Tc kB2CC#4kz,Q(n+Sh=櫤P%*/+Vyks%Nsfwɺ6[j֗#@ Ǚ3g^~hM U 8oj~mzk ViբsFV]Kc&`isݳ#7rRK S @fd֟.@ gv"   2trh_LL pqGYq }Olзժ0Zf"9ULVa15~Lj.4b~6mrZ5D*3+-)ҡ[{+2& :085=iu~;Ω.גŵZV k!WͱVy޾;<S]#@ Y)8Ck9~H Y}sZt}鏛y|^~zYV8'<vvW87./#kd tO./*<z) B\F> dV@Nfrf(   )?֩Оkб>rrF̗E{g4b2V(䚒Yya VXDŽz6NY(!i :9JvR~x-}7k'zdB8ZoM?9fUʊR_L.7JBYիg 氥V@Nj}==r9s/prPeoϑ@Ujgk?Vaya\V(zͳ0YA"-޴PfZ`^lgoDwT ~Y]:  X@c2N@@ rIgI dPC@@@Ri2}soLA~lY'βjb&7r2%*@ >g|n΍:vhB3?0$WoܗIbٱQ+s~~SGtm{msgY@Μ8l ȱ E3@R$@ 'Et9Ia@@@ qng[Zo@Φ_o=_߻ԡlbO '\0rVȁmڹm݌'Y+\@SozZ-gɢjܻE `/bOGfSw:r Jw c{}+?$j{sr^׊% 6!@(ϭ2;pIХ eهG"7+ [PAHyAgC*-ѲK+XטıF?bVƩ;PW~u#g{fĄb{;953E Sr2%u@x.@ O丹: @@@r<]ބ[V֗pk9u# crfHvȱ_'˶ީekDtQ/TGgO6irV\kYmm:q7&:̾$ I$dT@}~Ԓ@͹qVײ8[AIX Sqe&8Yߥ> p164m_BGELK+T4ag"=-}&Өޖi|E/5N^Ŷ!H0  s 3g:NL4 s @@@ I}@,՛kʔ; c>=$@ ǩ&@ ~EnZ7RYYq“w{!d eV9 v٫ 39rH/ cߟ{}+?$j{sru'hwǜ檸Xe<7 :rI`tiM2̏.DƮM&MbdFҋ3!Ū2'@@@ eJ 9* ̊ /7ͷ? qEc ȱ_ͣUPwĄ|fEرdQڡ$쾷oP'M 39rH/ cߟ{}+?$j{srЗ}IYښ@ȱoEKq  ,IIT'   6@  ^@سYoۭ@nnIC:u.^w,U;tpfڷ5Ft |'UC_#@ د"V~jI O\ 8+g^~iM /fdN@N2 >n 06@@@O ty\ ˤL@=@  ~xGvY' jm̪=TTXwa+sS.ݎ;Ǝ I%=eN@={؊@9qVO9μҚ@_*<Ȝse@,9|,@ al    24 I4I{yy!6+9- Zt55'<7Gv,:u\;Ǝ I%=eN@={؊@9qVO9μҚ@_*<Ȝse@,9|,@ al   Hg gAqHB<Ӂ#+twԁQ]@=WPIn{&KZ*ή^<{]7>;Ǝ I%=eN@={؊@9qVO9μҚ@_*<Ȝse@,9|,@ al   Hg ?V޳c(d:./ӚFL8gT]s."35qؿ{:[@nI5W+X*w]D@qiyکg[Ζ'@ Ǿ5V~jI O\ 8+g^~iM /fdN@N2 >n 06@@@O 3U_o~sU[jzzk5+j~WכkBr9n cӛGw0>ܦ&S~Ihi ~d+z{PkCBq9/OG ~طSK9~7J Y] 8Kk9~4D sr2gϕ@9p7W!  xZ@N|y!_!3=uUظ TMUyIfue}=][NNvn]7L tNMHhdt,o+@ '9ݹطSK9~7J Y]7^>IYt7t6zs5(@ ǏUg n j0r@@@4 ȉ&o=R 9pd ȱ/hAڡkŝd^_3o);y:oylΙ xݼNe'^`O- ޜ+gu-(WayHFt6zs5(@ ǏUg n j0r@@@4 ȉΖHaVvZȱD7 ȱ_+sph&777ĺMUutKŎktY$:~暬g I/G@}gԒ@͹f]Uzכ!G9~:sFp7UL 3]   Iρg4>mrZ~W#{$rIo |z.ǝ? W:'sG~^H!***ں53nih_I9)@˴ qFνZC=G9ޮ/K8s,@ g n *0$~@@@R,@[kM)QnQQ^B*4@k8"={٢wt\umNrC k( na+@ ap6@ҤBoզ +HJNsKNO4(9 Z|QtVdNt,LuIk9ԥt q&ͽZC=G9ޮ/K8s,@ g n *0$~@@@R,@NUaP5(h7yUVUQP-*Ӳ}_ͽcX>َ,_+OlS 'GA05B F% EY =c:$kUDVX^{F2TuB 'U.9Τs?j.ױ۵&>h:>1-:wpN8lIܬ0Uڿ{֯Y Num]zWCNmZ8^ ޞ#oח٥G@Nz ~ 3w@7qCLrfa?   )Hg 'SIؽRB5틊,+9߬siPۣ#eslf5dlfeqS C-( 0TȘiq_P^4Dѣ~3#q9$G&8/*L(f ijn՛h̄7wqQ TkZz<Ș;9ƛ I-=O@skͼ|/Ws#:3 I/#D O  Y>}8   @ș+h"YUja`2 JOw򓡄+Ló3pN4ل "/jdOQ_gM8Z(<]ș&*@ gn0ڰnJK:y왺{I4ѣAǫLqVjZj*˔c#;eQ&]vOm]S2rR-L 37essYrXU͉@NrcY=8T0/(D"F4n~ z=9ޫ)3BmrVƃ 79~xv͗@NvՋ"  xH/ɒu -. Mp4 W:usD|-M^P[kʴkIj͊9S1ZQvgU0@J:̽jںq6mXrJa7vCjhzVuviddTc#b7|P(`Pk+lImtEAz#fe+sF]cHd<:ޞ'ח{t&/Uӟs!3[!|/*S2@EyPϰO}oPmX f좖ы􏪵MWx퉞oH+*DF9&?8p+;A䤜 {9 a9.U@ά<D@@@ u~ X*zcuL'~|S׫q~t% JE*E HM݆:Y?`B9z=l(u6 qV[hM1'r*..PaA~~;o 9`)iks-}xRڮ"cSLxk6[ 9~K g5-,Ҫ˵㛵|2c1SGIkӵӏޯٖlX\ܢś}ӯ.u<ꌮ36̏dr%u֞#C@;( I^@@@R.@N 'GL_SE/Wid^s]탑KUغr^,k6uV+z:/'s'㬎m[8;)K[ȱW89hn9ýZC=G9soQE6A{?S+I>]M]f4h3S'VG~@[?0b5G3aI91@r|@ r2\.?Yy8   @ȱDWVvW5e1;G˝fˤl)"8W{j*~E'}aj~WgLbd@ȱ _~ir$xA@*r/prPeoϑ@ B:>լv3zϯY-gd`tʑ/9/i$UiTV=/@ '\ [ř/ 中"gF@@@ ~r۪] \e(<芆A]Ig%* ۫w+JθpW]P琻W+"O}S@3m ޟ#g5^ ޞ#]i}^g<ժóUtrrK&3(o 䤜 {9 a9.U@ά<D@@@ u~X__oU LO߻خ~0%jmVJCq[}rNs9ncgj| ۙZC?G9j̽ZC=G9k3tTT^ZGF#+:Y =jr&| <ˍLL9 rҀ%> @d `9p@@@T =sxE6a5U1Yc$f?o/eAFu>b8NYݺqke]9vKμК@9qVcμК@9qVEqi䬎3yuvv9VckuHs.@  i9ןM@l:C@@@ ~YRoіfzuX]jוӵ%PcV'}vsEB?=4]hVD 'aؙEr/a;Ck9~H Y8Ck9~H ~}CAvY"I{Iܲ_g޿qMlv9)#˫:o520:^R@N*u,9|@ȬsQ@@@R&@E XTcsD߿ܩ1y|`n*RyV+ء&n丵2ˮR%lg^~hM U 81g^~hM U دoJ5amE@@@ e~X^M g}"ĔgL_MT XoUA07W*E^VVD 'l29 iJڶIYv]޸O߰ Ϛ+N@3[μК@9ȱ_;굷ke3464M;zr#**Vr-ٺHkR |E'=c>m$y3jpWtG46860S @ 't1rb8x @䤝 :    $S+ӷժ8Zor.wÇrb`R+mS@[uZ)ǭVq cWy<;;)K[ixd4KGaI5WJg y5?Ts$c돭:55 OJN>-\Wi[+9]՘Su_VE=KUlB>mVwOɝٚq,IrI7 0i8@rA嘿s0}XK>3gpXҳgI.!@vɎ:urZy   q?r99JVZu<npo$fYS*Ur=:4YqmiM96h rfawV ɪr1X qaQ#9vjQT't6ttw4Hq ܪ#_=Od43?]%i[~QWUiѵ/.SWG'Ns+a%Y@NA|ș^dHwHtݹebl6fmf[X@e%-)R4-ȗɷ~rLgpѳ1M i_}4vf@ d} ==9./C@@p9KCʮ}bCy\n<{:t{C q JBZ]Pn,z3\qiam9h@B9 Yؙer` ur\WP@=0+󻢁`^0g˨{[)#/ ;Gv@XJΥ_^ӟ ]crMVIYs?d=geÖZ9wȱV([Dy˗ :41Hg&X[˕[T˙x:Y%aD`D@td4VߤH{W2/ҾrL&XUg+o2*Ze% x\̀L=&GiTC'O5DcM }V`'R%@ 'U 9P@@@ @N ~|lmZ Mdvq@^P]CG N@N ;L@NN@J€ @ gh9S0xr-/ӱ%@ gFd,)tז9 $ ]Y%@ ^r͗9r)OJܤVf[֮ѱԦ7ǴZצyVTG_>]99=}o+S@<9^)@Nna?WO('/Jh~7+ŤzZI8Х:wU#&3ӯ]v@NN(UKUځh'X[5+eԈY-gyOS6:Fr^P…r\X   trGI}wR+LR`B7em^PcJ,on;uq`6^;P`8󴱶@k ) 0Π zFu}Du#zl^\E X7)ȳh+rRI΃@k̓#@ '9Y9/@ 'kȱ z;@(o\O?_@PGi|qOL>9]Ս䘿}w*kbqNsFcGr$ד@ ^o5+T;1f3z~$4K!\I'&4fV8~^.)b/ٝ99y*ذZex]{`ߠ^'m-)tV Nl r~^=W!  V =KutEIZ-B&RnVũ1T w{㫝[EzˬìT}#kT>\j kgeco{GPXO"4ej;r^丼@ r\_"hC@ $ 0Yp8riקE/E&L3};@j1P֊;q^aY'1y~Ywi\HHr؉%u{?MY7w;ͽKw*D; >3gΜ=`fLK$LIZh,)mI۸"X-O 0d%հ7@[]Ikp Bd9Q*Yuu{=Ԉ=zt"GJVBqGƗQ5m"TdZ1>6:㨔iico;`$BN13`!'!`L 0&`L O )la[qrKO_;=g%8'YeSMEŔlr!d}2S((J/;$mKW1yK`jMhrvEI; Y0 k1zÇ#9sLH"PIBNՌIIc8(?n;ILIg2mJ+2]dS)9{!+)JVBv`=DK rX 1b )a)H*J2T PoZ TzҮvaJ)rm'ޔ1` 7,r`L 0&`L@`!鹘_ HE8_gc֐>W0[))'M-ӤrĜcyŅkӟrWW,drytg2/_3X#I;RoXn ;^КJX# 9Ro`3vr>tIi4w_JږbX2ePBkob?N{B}'cC}rn>ߞJ+ 99]1&@9Br]"lA]]EʮHp~Q/S^oW*#B(1of6`*t:IQ`2f%>nEW40JVjBhe"X\m-~J) Q҃ZDBW^7bb0Bc1CC7j`;QáXuJre8݁k*,W2&g,!wG,.w`L 0&`L@@ 9:C~!8 $a*sO߉_/= (-,zh ȃ1&`L 0&(JrĜ;QXJq40 'wóhtb-dk԰6B[gm*R:E5GWwD"OY )!g*Hb$ .L /,ѲSi+eL 0&`L 0!PH!g$Ȓ|| FC.ISD)%(9C)ӨZ|DBJ4DhpjB#IZĆ*Pk$+xMG,UYu9TFO$p!=Ab!'na$BNvagǫZS \sd!'5ςxUBkr*a{,d3?s^|#/IDAT5%Oǿn©- gh6`nwpd t|Iz-e^dy]jơώ;IrEn [`*AQa}}&&"s@a^6*0p|"&Ҋʠi4XXønjq:b>ܖŞ[2hV^ڵYtuswb-ZM28X$瀞޵7JUJkۘ(-,zh ȃ1&`L 0&(B 9)eέ J[P‹H?ΨRo⃙89`Q: !$W\{n_$Ҍ]6f}IfJl;v]u'A 7c =j-见RKxM}T.J7 9%4<0XQf|vv*5 9?Gr[c,ȎW%f!VBNv뫢]X ڄ軕۔sxt ̢o͒ntFݳ_Ogp_G |`RK ; 1ĄvwQb1<𨻊 9y2&@%9Ic`wfN~6"m8؍P^MB {DI$;=Գz C;;^КJX# 9٭1dǫZS \sd!'aâa+'~Fp- O"Fre²xKP?*"{GqÔkt_2K>lsMnO+sGܱ䞘HM܅cYTr4Tg.6}zTϝֽ)Hعw!L׊RV`Om4N+ v27AhZ4$cKͻ壤\z)%f:h/&L<D>㝙`L 0&`L 9g_>3D"^ "V<"1Gh !3;I;r )Lj',#̨5&^"}}؊{nSm,2#XɎ._JhBN%rϑ֘? U YȩU.9(ExQN'H/!ę$ߜ>̊Ǵ5S~Kĩ-p&tz/"8ޟAM7@I*]]%m`!'<7& mWQYc~8ЄWg̓OC0w5u})I+yadeuu!ۮ&;иaR qMRW_*zM֬~_by؄g\?삛1.L ,đSsfL 0&`L 0 BNI,CA!Rm>[$g o9E"S֩Tޥ*z].6|B:,m}mg=%[PX_JhBN%rϑ֘? U YȩU.9ӻW1m$))vpMR'@/7;p C8un>1'\rŭȞ@ 9B(yo# c %VJwޣ@5hԧis ({9RJҊ~ YDtpS$%vK&F\3.PVoݗmכU3'KbqhcM(")I]KݪP~ık+HqD= R2|QI*V4ZUPh.3QLs@~ҦhSהx+$X)ۥ1&`L 0&@`!W([1ۀ <)"ْmN=FT]Z}a|yۯd gոZiL&mB[8FP;Onؚ=s:6^쏣/Y)(n>XX,ȎW%f!VBN+q &=o¨#v% G$]֩b!!w$DaUc 0 IVvW_y"BNrL <#PBȼv˰*Czw@b4ۦu0-Sp:Hq| Q;is_*JIZQa{k o8%h"!#])czd y& I8wEYF {\4[~z][r& )H;AmjSTKbb^$Ĥ'{$-Kv`+,Rtr]wmvgR*qHƍ~PhT::<5OڿgW䝮h< OAx#P/Ot̺hMݔ)+oSh|l -n`L 0&`L X!~իǼ5 #n|gMڙP/D|4FY5 G$DDОY<?_rN )]# 9٭ nn~ںŁ͕s. 9%r[ ,ȎW%f!VBNv+mm=oF\gʮ9= 9 IBc#rqU+oN,TޚsK Ȯ WS[vmqF\= 9͇bJ\)g#Ǧ]Xn" TVW2$_o~Ji{w8Fb Uߏ}ȥÔ/8i,lﮧ2D3u^ DM̻B N!Ծ"L fʾ2^ }RLl;IBQ!Rf)?@.b2x;uqZ_O?ԐhWJa\P hMYI L #r2"L 0&`L 0&CT 7*-uUi0~cI'9&fCJ:IcA2N3uB/'ް$ J/Ts1m`u ׳H'ͧ;(- Q \|BrܓAS|`!'x BN,rL Xdb^ WyuS,{{eGM?ř)ݛDBN@(G!G\^v9ﬣo߇۝iCSm"tro#Q~3҆RV vIƩYܐ%E)!?'M;%X;ע敥S~蜡s~O-vkCpg.IiBk!GJHY 5AScV}w#!o]!otWykݗ2+kMդM8ߛ/SZ5mLȊ]6!N]1@:,#L 0&`L 0&L!f7lLPI3Ԣ٠Κpo<(Bďq Z9c(YX6ڒ|r?>ߨ;l;~,]C=(4rδI >RZ KojxN,Q%BN];yi`!4ցG{,(c慛HBZwUʎһV]]~/ݬ&);"Փ 9=s&rMݐ󪔊l㫭?iKLQ?gO/?-e?V4id qmWJshF UKĥlĎX {#@#%w"?TI 뛫Q={ l7b,DIVX8;+_BaO]x*ܸ& ϿJ5w7@7d@RlBvD:Te1JWnJt9TMK;H$Q9&Е\SrҾx%B,`L 0&`L JES"0JARƜ!&qBFm&.GS|)99;@?LBfرi<3zvQ"胙uX?"|zM*iGt@퐐ۍ _X?;zSx|`!'<#BNy9Θr\US! SH||`!GUQҿ.TCZ G$iǕqyulìCS̓dE%PvBEa{m J6C\ ]KN"1Ķi=U$)[~.υhQ*ҊbB͚n\ 5=+ výk\Jh#IZӼirFݞ>d OisJBE !EHy,*u`}c5,+fL nq %й:Zwi" :tޞQ")I =hBi߼5+Nh5w%㏣p|E7b(K7lpچ}~7:v˿Df] r6&`L 0&`y$Pl!G F Q*ʱ53Ԅj]O;<$C#VLkI6O#^Ψ\v]u_-pQZ2P\< 􄅜RZ KojGEG|/GfZp]4_oXK.!BNqQ@%(7!GmWH0XE2s=4x6=7%<3M 0vDB}'ރ'i;==/!GTϟA,W0fpmNIk\ s_mBβ,_ %/iԥk>DGO BKH* ɣEmڍ@k=[? פTQ*ކYS$0n$u,^;J4IrE o~x U~Dډyb=P$-TF=|GNIrq7mL:|ultVs]G=" @'6}t`(,mܼ@X)h>L^ WRY< 9ŤrQ4X\,bw {SRMV]~DIɹC 'I cc{Ā`!'L #.fճ_Zygq}]LߎWQb`?s{g!W8IHibK+B>:7WjDE<' y ۾s\Bĩ]@ScZf6JiM"5G?F]]".7/~YQiEJq+|'Bgb=E;{iђ#dJ?LB rs$H 䍮pDJb'/Q;y7H%B"j#43 ;I,ZJsJWZTEI; ;%0IJWļ:8k4-"o`! %B,`L 0&`L %rqJ)9eE2Υ~DC$(i6>܏;=݈ )fݠ/NħLE[3^A=Չw;9HKLvr ;rX\xmYom~̰,[k`;D$!㈶D"!䭏N&:nmn8鮆?\n/t'@!p),ZHzO޳ۓ? 6rk=+q6,(_9oĊ] }>i8$F2Ne% FVSSf&PNB.춬\롱OIi-E5$aHUiWGt1#m/O7KZ :DŅ"I0T{E!"w Akn2Cj~Ԯ{ sH0e]=nA :iu k7E7]Eڭ$%%e}qZ_3SKSԀU/L'qvKiAi݉ 6I U$ q{ $SGǓMF"NcVJ9H9JӼ61Iu-š+6rE 9J(q&`L 0&`y P,!g 'YvB-"W 7N:7t4 If=[iD9~ c6)YefNcӌ:\2!KT 92<.XQJJY;ݡ^!0r lhPAV½ xHw9lwtHN, yG4X!LhX-z,- 9axrXȑmK? 8ϣhՖ+ʟ 9tF,dD `L 0&`L @1ZkHCyJ ';o@ABv*I$"YgmgSy ,:Iک7i1SEO"rNY$}d R'$(uRwq#~Ņpw*{q>]E#HC?RЗ$d&6<wwt6#]UrY)%eI,47҉A0f`9hHUg`Ӎ[wνh.c]S+SB%eʭ 9嶢7rЩ'0fȤABu$m'BN1ϐ @9 9s8C)𒮈toz;%Yx5K҅?E"w{ۢTZe(/Jҷ5->rYwRb8Q~1SQ:re^:fJ  5H);[?ssW($i'"ֽW`ݰ^%pDD*ez]$`$GMM IRNZFq ³8bmZ톗I[>9Ͳ(;#!n`=y5)!F9\ U\"i:Ŭg!ؙogL 0&`L 0&'r4fal]/E}wZǕր$#X1׀$ėTӾ $⌧̣41TFg])ebCޛiǂaf҆$" *SiEͬm 7;LsKFZ95u7EBN/Ɲ,$S,,>[j,;j(O$刺|ą˷qN;trRŵ[r_)`!}g؟{`!?]`!G\g´Փ1v褝^|s;/+ʟ 9a}+֢16a\"i2ְS\|ty,L 0&`L 0&FBh!r4).T,Bwg8ɔ9PJΒ,eta۵Py !UBђ 5dw1RtqR]W siZmnDRwi%K%,JY:Ҍ71֞|MS$Y$R-,`!G)DN}]$L?suyѝ|oI^e1ê.Yȩ%/ ӷeς+Y)U9|U]nٞw' N{BrYI(]"G }:͖-E_mC[zn :禄B$p~ 0&`L 0&@R ,/1GqD"˖KN#z#6PRN#Ry*.)!GH9Nwq"hzé~D2'q85 9e7irzY{v' 9崚9r*syֹ%BNnyroL $( !?X-K5]:yiۥڠjԾES5bt׶ŒJΔJ+=+s: nn ϾY([r;\; FI҉npXk$Eu7ps+:~#)B#"Z!!X 7;@9HmZHW1t''@gr,䍧?|/ʢFӢv틔*^6)JXMsVr57.iM.V= 9"UB% `L 0&`L 0<(3Ffaڤw=38b9P%c04q FE4 Hɩ֩QW~HrI<ᦛXǞChԛP #GWSVa2%,"}RK#J/Jn5`lAzܳ}R:UzJSʫcSB%ۈ7fMƴIӉ#'Dd{8x"J'D 9cGrzǖ? zǭb!WBNe76?XW 0AZ`} /2'mp~ ߏ<Z%OSEH+gI(؊нGrnS* (I;d{$ެtnQȉ"iK8a9amKu-OJ6R~Pc84f:~ [k`}meZH{ /PSk򑳐7:݆"jd)%8qLt!G9ܪQ5}c2.myϥm#6u--Fr @IDATW{#W'@4JJIUՒJRs7s7`ySNJeK>$A <@ڑb DiDرͻ oA)`!      (9_u}S6i~8t37vȭ`ʱl;jִc˜]8S}«+[1ٚrq߉=cRLv+&:hf9hu`5Օ2 X9E$>Ps6ykۅ]}&'&FsqU-ɹZ>+̅ݞ}R \t[]i2̘:tr$03C wAu7͘67.ƶ$P6bvu/lĉ@Xxlbs$@Bo?0WȌӧi_2_>jև\TӶ`6Z^z sى?]rty*,̓g:<6ur/ۇ8w-yz|w?A`+vlԉAۅ&ou /v~}ٯE:V/A/:{Z"/gs&hz>4ꬖ>u>01G;}ĽSkp?JCfkrAx -' }=|?ˌJ+O6rP~w5DB)vBڭQFjjzVmBY03 i4 "|Zw{Cm?I֣4A([?8xgw&Ν%;YϏ^{#Pz`$ ߿B30|J(R[4*}rwj"s~=.g)J ~0K !|"Za :*6cӬKBNsD(gŖ$@$@$@$@$@$@$`(R 9=e'mkYmuӎe(TQ.hWڰnJaw.݂PycK$%#ے8H0_U_7"EtJZc9w 9cIcABNۚi2,C&B_B$@0@ \l3s .5qe4:lh\U|ؽ8TR|rϘ# f|jnmքgk#Z4W}&X$^;)_2RP$P*]1O OTY2VXƕ:4n\gB}cvGM$|,|9^i%ӹ}1 ]^DD,t@B޵U3a8l1֙Sa,t[EiF<|IoQXGhrgM݇_=?gXFS}Imi}7ⷻO. Е%Kę/iYmP[kقlM>y4RظqLGZrJE㌆P9$@$@$@$@$@$@$`R 9SvJcʬUFFo1BqJ[ڊ4,eʎ/삅qvMDZ=95CTf}1|rƇ)d(+"ey._2.фlg=n{q \tC2+l\6,KnAMکW73mx̟3 '٘Ʉ35-c6QVh(P (E~ǫZSȩ(WkMși6ֽ ԇT[nqGp3ն\ 'EUEZ ԉ9Dl7A2m GKm|R䈯2SJ+* HgTYxgP$Aɺ=(YU&!%r*T`(lwm&$C3`ܙP҆m,'N2)'Gy"BXzLSވ\"ٰ>A`. %Qɒp,YJ`yCN<\?v=-lHۨTw+$|m++6cdcM!g,sP @RLBA/*h>"b{|-] H֞Nԟ'e3]vLu Pa_$Ї~)6b 9FPdcIBN~'EVg)YO[tSg1R%B)urB MS*744NyWwlou"?4QA1;9M97§,#rŹyZ_yV֬]ǻ}ddj8<&LECĤϾt8Z1M9F;r),- 9^pg9b\2 nνDƹ!21Wb1cXj!&~1aattzN{P)Xv[RrxBk 9^#/ƕBNiys4E,΀gX,C2 k~,T r>EذΞgc2Ȕvo q/e:?I9PF;j="7BGN!'2̩+[r!$;b]-/=- ?tw?$27G eZ1Mf9VrƊNO3z'YJd̓DO/b"aؗ/D|mg8L`Q x5m]}d 9J,YRN<JeQBKZ)odȹi]ZQo!@RwhyYdQTvc 0C+:eQ[ J)չpRpя?U2)F 9&84!gWDLyP9ߗϴ*; 4ɒ2-r~Ĕ1âݨذL PflZ NxR ơgie;W)DQzN f,x"NcFcs@r ɮƌ]U-SKѮεRȩθR)m\)䔖7G#Z$PB/@:lC'D uϳR JjX)kw6pnZ4̛]w"]E270в4?dDI6yyc%~!gPQ!z&]cT}]:r*Kr!BT"leڤ9XAE,\Ģ;P1lkx~Vd ovf.k݅>I}(lfr#~ m)D/D.(aʝ5ɚS3*lǟ$[eY;K~(Njˏ13k 6o\힌'9[wm7R)TQF5c2۰ ǷfN燝xc G2(j%ZvuBNuƕBNiJ!9 "JrK-Ι^awѫnיARр۬0'G\]/Ľ-9缢n ؛֮ϣ1 ChBHlgL W&yxφsF_eJ$:s*I=N=t-[k4 h+(8ˋp1 GB;/A#)N:Sr6tIvLqf9"^'Ja4mZ_YފG!r-/"ʝ ܸKB]ܨPrnYxޕp6Jfع:.*1e,ƚQ aڍNluvFc$M5V('j%ZvuBNuƕBNiJ!9 "Jr~P!^e]sw zCj9;p6g:\ԉT ߇_/0(ٰG*$+imks0kd>;@] -bi\2< ˴I9G\v'Íd^i]-~@ I}f˪ajO}E)W&|dAo&nZH;;ևwbZF1R) g2:rFǍg @J)OLɍ)sx<%- 9*KiN-MR _8wJlW(pdrR 4,}2_=:~yn{uuh3{dl޸Ƶcq;t*+#@!8iPǞ8b+ 9Zs 9-S1i_ҳL&MS5)'SJ B0=A "BF holm]^5Ή)4zZǬ΋]8)\w]߷+*h<VOBL# @*JrhcZ KS7܊?FߟtĸMqZ ׃F40*H2x%;d><|Es/#u`owiEK=f<ةMhy948SF#o$O?8&M$yM${ mHeJy߰>2e$o#jr`ە6աw#O_HB&+>OظQLmt[ 9FeFc$ME$@$@$@$@$@$@y(n'fQ{l47#?mlhi 93%S[q̦!ExW{# ͍GBNżVL!G_D36]{.x™W5!K\Y3&iBO šɌsf1(Ñ- 9@ZlE!^]k5!ٜVL_%y~9.zyLrQ"N@ě΋ݸz:ﺈKHDݸ2No30udlQIǿ:ߞWğ@T]dr ݓ ҄$Ēy9o-gB֙Mp?ydy[ήb:(q#W$i%:2ZU~|s (Ck^ d߾_DHJfQ2GKhQs ? B  2Y*T;#x2 zWc)rLoNsPN h'e&oFKO.VEwhy#/ëY*6e<֜Ba(QP)TvI$@$@$@$@$@$@zRyeE+]2Ҩ4ZooW$C|C"m xfA3~Mֆ.kpfn70ɓZr#bf*ͻ_\=}U>XqyE⒲]^yB!Z[k/f!GM3gȹx&ܸեCsa=N/{бsiXa 9ƱdOcGB>.ǩ[QȩŨWך).6 s6꟭2EK/;qiջ"@|tp?:rFǍg 'PIB`$BӒeÙsJ"!".lWANJEZ 92|!{N+IZɱ*jm"4=2< )g2J"yD.^d5ov+YY=Ѹn.ʁp}30 ˔uTS%fE1]JL7c27]? Q'sT"<fԒvɴ$BhJEƵb:FC!X(,%      Rȹo [ӎԧ8,4[/!yR/"Rãr-gKd洦?M #2$,T6f70eddIH96sNw$6t?}Q-Rg VcE!gs\PG,N~ vK7tuh|r82:[gnN:˟Z΃=Ӏ78<"NxԸ_$rݒ %PIByB;:e_JUrfq"܈GeP ]K=q _?TS SMj2cNJk Gzv8y;c!\Z_ pܴ&)no/K6.Ta[EZuf:u=,#@!xlsPϚYRK 9\+2Ճ{^]%II0?}D;qFD7V= KXG=팛;㍽8a2P H!@!'wH@Y-LDm-SHQR'_n=9K } 5#[4i%:2WڔkNbY4̘:_ %d*%[֝q87f(bԫorǔYRK 9\+j5f+k2$7 /a{pԭ:γm"s2$DZ/Oa_vV_!n"e$@w TSﰣyÒ1ԙwiC ޷>DL /'b3PTF*[ڴҤ pf_"};͐|2X>w >u]wĜ LG8 n,3&q y-˙Yf܁`eZߕsɒq)87#4AKh"lBΑ[Awċ+m&40YLkĂv{1"AC{` _Sߖ[DZ"p"pqɘ>D# ,)E8Poo̙WÎiBG.[K͂9zyM/ #.Pȩ@,B@@?ZjI!]k_\'M݀9gڃ݋c_*zfzycois8׉Υc(ϔ= !:gZ^zJn_a{"!>=J(Einɢ #'*yѮeZ2:gQ2u"3RQRG1G*Jqݿ_x[2:vx"Su9v|l]Nn!{ NvP)TvYrr#w~VԒBN-E:J!G\GO.oDcKjAACe(zg:~YvJ$ Y<= >$bIɬț < T#hӃyOП+FFl.רʳPrN2DpƦ(d\HJ]yx4?סޖߵĀH&F_^MQg@;bA8VL2i!'WxnIf/пu/"(V~M*g =ˈ{}orLI8V+dȶh.<5gH쳔(m].4/嫷sq\љS0w^>=Y'MɎsovfmc G2(j%ZvuBڛlZ*RpTv{;%產A4^X{ rfo)ScPȩs$P 4H 7oh*y$͛)Z&lC'dI7Wm63&=ےy"d8`zK}~/O~6˿;Yl/m ,9ݽ"zM8244NT/"Q4Oue*o( }=~3WL\4#Grތ%@!XHHHHHHt !GMn\Owyhk4eo1@t';CO2eOٞu~@62Id- q "$1C^^uڻE*LY?q܋R J癍ld2+fזYIEM%=x WoFL.e* 9Xpt;sl}y'Kq P)._^rxBk 9^#8<6vlvҭ3/pvcŬX"_L]tj1VKB< @:Jr+3ML^/,!fqkp5(ܒE.w_kH+$/2v%N25΁{ð/_R1qohr& X?iZ >-(O$Kߩ_))[Z,;9mĶ2鈐 l@!@pr GIHHHHHH@r&xX2<8 d;Q !G'|v;B4O-ҵMZfh8*v?pJhMz4Y6%vdV2xJUN4)'ەP(TB8\(䢓~2,[<Y\Wr7Os9îeÙ?g*a10wE9s7ݥG 93e'@!'?.ȏW-S Q5R߃i邾^i'CZEBNȲ_      X 9jjM"mC"mѐ#^G.Dpz.qʼEw,okUuq궼$Ѝ("(OQn ٴ&3lI'[z r7 9#J=^/͟6,!;W ¸r'N_9'e%䜻x' Os$3N{{3"T0Kv}N!fvxqBX_]ZhM!\k?+,u/M7q?q'nߡ-gc#Tw_߃#~c0PvG$F܅˴IN{Jn!ޔCڱΜ ϋOqTPϻ#Ati%bm"XgNK,do2Oh2thlP+ѿmwЗ]fL&K}ܢFј/QֽHFY27z^ nWҤoA>.F)qLl}RF@BN9Ds      IuxH77 $Vqfrtcj"4HBPf"®+(RN%ɜޞfS54ltc8*̶sfHakptCb2y4g;!+ݸ Ml)mh81( \.|*fvBGgݦ\'' uY(i#Hkرnw4VRn"@e%'@!'.ȟY5A![k?k_X^4w 9fb9K[HĎ7`ҎXrH #_97A/<=}I5 $}5F|WyFn;lpoy=:KnAc B̵_@ ɥ*%mW$;}B5YLGǍ: YrV'B'"g/+r(97}|'C-Z.CD" >%U\PٓZ^ze t-+zzj?F2騙y"j?8 [ӎ %*J<1do '?qhG)hTv4KvVE~^Z}O4}&=>ύi"`))kxQ{:S~3͜> 6,dd nq`/yνqU rS(䌎/ FǭϢSQ5Q=ekd<ʡk]rZŪ\|l{N"7bϻҎXrH GDtO|RM9x#jKٸq%Z^yF<0@2Hi[MJd&ߚ'cb$yx[P@' c0 8wy|4!g?5J.i\Bm&e=uFPY;Èݼ=i䒿Yrήy䑙Rڲk4+LP1(3Cq3      OY7Z1dTQmnSՓ%-"v@"("dQG 9*KOTv_y';OwgBK:ك/_`Vo{0WL+;?GS)Hp%@!gt̅cݪEh4Bʦ݋OCT2찔ұH#@!gtl]0:nxjjmBx[flxe-պ't2/Fe٥$ds?;؃-3$$( rrLmM͛9U us{7bb6PrFfLq.-IVYWLq%WCtwBDTJ5]"̀]Dԉhhv٨${9r]r0ʠfߏnD/]CEM;L&%Yln޸f16mX6T}pph }Z/@gre PpS8]L6)FyrGwڊ)޳A~\E@hv̽gV= E$1h?vxr^H @)P)e1ZrFK @]ȩl)K4`7P0Q'"GBnF=q & $'Y^ެ<3r&nM&7YRZ T;̒ynäa:2/)\ r 祗kg[1̓['p ME 9dž53^* N4 'H$P8oOd@h  9eN r —d~dESu(T]HknArڈ痣!"ɽ(ʡA\=rHQm[f'6aֺX"lO8|vύ߯iƦJˁNf,G{.""t }c1-]cRхʘG6l7CE}M؎iSƣǗ|DAr"tP|/r#Ea(O.CrPȩqwPIPϗ>6g[Sp3v:|7z F<-ig50ud8i+Tߜ?DC. 9EnIs7HHH`LPT' 9:A M@na_]ݟT 83)/m)s9$Yrܸ&MJ}JʔSBNFKB^RٮNڳt:$/O =۬8u2M,%@!|{iP) bb/ز< P]\{SMFtke8g'd_SH P) p $@$@5MBNMO!C T+r:,K[|C{X0>|qڐrmX#bNrQq8؅%6Kgzk ,&$Q 9K/ 9zIOzp6 \ӈVOƏ`¸V4hh;gU: 9U[ 8 +fr+M(La0g,}a%&WxvMY?8?>#x(P4B$ 9ybc  0ÑC P1&"      |䋅"D Q7)jAD@\*MҟMBjw[佡^_j"||ʇD6fO/lF2%$yQp%,*+Ϋ+eϥ!@!g3s LZ8&iA}Le9 -32(Qtd (&$@$@$PDr]LBN X93y^qMQ2 ;NK0Yޕ\j2ѧ緫SѨ5o8߉+h7Lu72٭֔qOw=$rRƝ $@!|f25aQ24Ƿ-)cA 9dgcDB1, t@*&r BA(Oˌ3}Txz ,Ge[Ta#tv4En N}wq~bS- 9&HPȩs$@$@EBNyŃI%@!'HHHHHHHdJ-8xzA3^Z !: 7÷8v+'I?P;()gZlkN % ʠpT+d,٦WzMi\\n_LD4 ɖeG**7"H~KYnr-"O(K-3v-v&*qrLoT(ΐ== 9c FelSȩ8q PF:yJ,.fIƜ-8,zOϻ݀nǕCpӸzxP1%{"LBNf.%  RS*g4(䌆!      RQŒ je+VNj8LpUNip26Yğ8ͅhwS'AɌi9EOo`PrNR4(&)Z5&<6 SDWtK=Q@M=]Ӝ6jmn\E(>DO|qoFW( 9)!T  9Z}}=6 \.ܮFzܒEᴠIB B ?B~VlY(>6.(=bH!tw)P1ъq0e$Lcw٠QGOI#uW_7 mJDBN@sarj8\: @YSa$ IHHHHHHJ),g8mX;%=;0] oǼZVbeDqYy ϋ4Ó*(J>XB_$QlcڿB&I).EQ;Ó=8F4al%g\%Q3yR2#p\K($z](&j86-͚3̓F<т&F! |yL!'/\l\(&0.( BXPFc$ԾTFZ2ՃInڜ0YLh07A2 :0%$dpCύ^tx^J6(FJKrƒ>&  B?LBN9Gs#     jrӄ߭nx9񎠖f J>yb-S\ԎځN6M rK9*SA|u';CL5f˱4a˂xHoK=.=Q| "w((bP% 9%1 9vl6h$ %Lߊ7l!BN1M!'*ōc[N=S)hp.!@!g4FaAc6U˖2%@ b׀FR(8Ctr*=? @SSȩru$@$@$@$@$@$@eLBίW0ץ{S>3 3mZH!fD@ o'}06/L(屭2iѹndl9DιĜ= &8Rf{GxH7j2%,Ӛ-xuE[$!/ZnfF!`` P/fLjG{%N{[36k~:O ʂ hNd!Cɒ,cGBرK~ǫZSȩ(W)Tn|v\;NH[D/{/iXa< 93e$@( Rx-%       R 0ɒ27"tx؈/q?Va3)d>˼P16rJOBN~W-]%#^NHPX 8G^@o2ᨺ8 9cCNBN~H]ZhM!\kSLnƽZO,J[f/v?9vctvDBڰ/ 9L? 9Y.ȏW-S Q5RȩR)Q)Xp&$P(Tkd.  J!@!R"USqIHHHHHʀ@)\ )B&\ԗjgFfU y77v})ղC!HR1'{+= 91/&An*N^Z^#O7)Sr?7@ ?^КBN-DH!rK!|bG!|b@SHH*JTmΓBNmƝ&     (r\mBή+s':krMp 9D9G!'LsċvQgN!xy Pr7a+'pDۯ 8>|,غP)hp.%@!'?r.ȏW-S Q5RȩR)Q)Xp&$P(Tkd.  J!@!R"USqIHHHHHʀ@)7_qNsʪu.H/ΆNfuR ɐ?Zv/TrcP|q?ƈr>ƒ [<Ca(馳K^x{# eMBNYIBNP?6wA~j5ZruBNƗBNĎBNĂ3!j%@!Z#u T  9ڜ'ڌ;WM$@$@$@$@$@$PJ)faے>%t c9M5hoLNu9{̷Zv&7Y0ݓjYu\A}ΊY(.. 9Q }8{nvtDP2(I'*sXe-BN~wA~j5ZruB7l5Ԁ:㻿ۣ{Rֽ nhÏ=/O U><$#eTrRypHxrgIHH rŶ&@!9 HB ,hOD nxT6R:E^$\P|XH`$rF"NBN~{P*'W2jNo_?JΡ3)Tt8 PxBk 9^#kluʫj*6MۮS?Bؚll2iO!qvڱl}~\9t=}ٚ>  9YH0r CɎñDg l]qr\nw%rbGqek{N.\Yq @p̙SH&`󿎶 ŗ,Bd* rA&jäG[9=k\ޙWLX (wr=\?mB^<[JxBȠ3>5tϲ:tS+s 9&?rq@/+c(W)houM5Z4cg;fx<)r ٱ' :rqb+  0r\=Pу"       <)Hi[qTTJ8RyNҮu\kÛ~ÎFؤLG <$ PY  9kF=n\n'l55XsAGdyAg晠 EAg~ŸL!9(h#{6^VhM! Q=R_&Av"N 9BNؓH@ 98 EBQd9(Ac @r[՝ґ`o<9ф 㽫c̸ FBN6*+'rE΃&455sj=.]Bб-褔L92Igr JR0ߚBL9(hc{6^VhM! Q=R_ӆݍuȌ3OB< r3c m(h$@$@$7 9zxz'ME$@$@$@$@$@$@)4mrR^פgKîi|x"SN<#z|rd=»Bș%2 ʉUSS Pɋf|RЩUgt :a!$x?{RΌ=Jc{A*'J5B!G[[65䷏bk[u,rٱ' :rqb+  0r\=Pу"       <)彴9؂ M2pu ? 1{"px9N[V;pdm^X88~-ZrԒbR%@!Gȇj9tDZAݨ :"{x Qgj&D&H49RVrbae_x/Џe9D!ŵf#@!'v hZݸt2B!'Qɟ{ #@!G'"  P1,Ճ=(r       ȃBNc>'2|v{#5YWCtBx<U2 QfDBBRV58o-.luc8ϖGy=GcU+Od3uT!2ՈB2sI$19ʗ8W> 5/)tdQ HR Ft`o?“!]`(d2aMc\x/0m)L!CBzjB—+?SW ZRɟ-ٱ' :rqb+  0r\=Pу"       <-%nmvk{8&,%oE .S7B9Kkh"YYV^JNɇ]87AHf6U#I9J=5cx6`wBNcFBNa ]-zK :^xoijp~z7 ҴQ:>3cξw7ZX'@!xƜNB?? @ P)v8.rr5      0@1-`׉7ȚZktB"BT=fDh<8R),9i9X7c*nY,Cܚ/EX2L3?Ȏso9$Pș"˕ҋVKSqޣdi2NKsX S"PBwֈ F5JfD8n +[5B3Oîi1c)s 9%.J 9`Ԉ/Bb"ƝS1-G6X{HĒY]I!GoG!'vI$u؊HH"@!(Wr1HHHHHHH &,܂[dqi+rd)HFKY@s C3qEȑX^5U6/)&-L p<@Lb9 gu-nllr+DE=3wW[\:Vx}~]AǙ?rnO(rO$.w 9%.L% 9*Ǎ/Bb"ƝS1-G6Y^`q~էvY[BylWX+A{u wG.T  9y@[K1KJRF# Fg ,Z^.B )x/Пi)H!õ!@!G gm0pNW!' d؝B09 @Vrba% FBi9Q(]HHHHHHH@Vr\"3Ȍ1 KJH)x MG 52;n[9B/LwƖLWqT6 Iv)}e 0[D-~'ǁUԋ;L4DnM|,(,ˍ#V"ј"BØKb7r/  9r9z\$@!GZ|t{qkP2Ƚ܏/cvlVh/ǎ׶f2=2K?;q?SH$NBN: (Mi!@!G -%       XYicAV78҈JP"irұƒo !G}aWF1 Ĝ\Fw4غ:x]Rˣ=VpB!9(hYGb Ff a"0)E™"Oh{DBNAعDP 3r*9mq^ކ{WZ24O󽒫ΉջVeR wb{,+'@!GH t<#   P18BBZlK$@$@$@$@$@$@:խ)ԦYb޿>ߊ,1XdV6cap?9wN@~.+{5 _rx kc48_]f^?^X),,'x_3 KBNɅ HB6`[xo{o-{PۈK'#ěP8 gFp1>!^Ә "!ڰ#xY5+DH!ݙCB99 X+G{' (rJ! \R(,E$@$@$@$@$@$@$`0 9Ͱ|` V>]FU"|b}=sT3_FqXMNh'x55QC񔐄S! u6B9!(hz~r;O$'qp3!ěyGfIRֆc8bN` 9 ^ZSȱB+{r*;ܝ9(Ù Pȱrw  R @!5,EBRdXO$@$@$@$@$@$@c=!x]5iA{eF#iNdvoo7' EII#znmv)ي{>ܙ4ht 9{-rBmN,P2H&(2LO72q0R*fU&chNc( 9^ZSȱB+{r*k%5U|B/ݯ@ gSHPȩ r $@$@eMBNYO!C * 9r'EBΩ#@LǵQ7ˇSˣ%r{8_W`~1Sx[V7VΉ H! 4r!pq%okjz315ǀ+(m y/ )X!ʕG 9ǷJ|pnt#^Z'ljwæ@<@"&^$b0!De}U r Ǯ$@PQHHH0r Cˁu @!GHHHHHH!@!zB]!䬬}d>38O_3"|f9;wk\}2|(7^Znz_7Qg6 9ڈ}[z5l0d!LLL G 8G&g$@!$Ei$@!G0 Bk 9VreB1o\ .4l˷ 5omB Rؑ%O!)2Np"I=dGfBx*Bߘ4*3 rT@b  0r P)!       Pȱsb]s}δ)!H!Grb@x#a'+9r&EXHkvi^ŽQrO&P120mx?=,zt 9mˢ5  9ZtE@x 9; 9FV&|XcX--p׻&Y4#3Qtɵ>wbɄ9'L'@!xƜNB?? @ P)v8.rr5      0@A~ xհTACx6A3Bxyc=6-S$`HS$z&%T)VZ(jd.(%u$gDSSAE GH׭"+c 9e*.4 99d{A(c@lBNABCk=6݀OmuFT*d̹xt1l9FV7.u؊H rgǞ$@$@$ 9zPFcYK$@$@$@$@$@$@0[ȑ2>!^|ng!a3e#ϲ\*!Q7fOO/O)MlZ^?~{~ ޹:(2nOe!;l;*ӵ ]qr" za/%) ct\fϙ4gBE'CJ<,OBNLj+\-l{B<(sP(Ay_q-u wp"gpK9G0 |6+NF$,PXE$@$@&c"lN؁HHHHHH!`#3,GՉ4SIȑ?͋jL4_"k㈫hd_Ǐ7D5Zu[i{&ek73䤁 HB6G',k&f9GJ:a'(`8y4 P)͸pUPƋmКB\{|e-8h2⻖G3Kz.5G"wFPrQH&@!gi6B$@$@fceΑ/ 9c?      (B no72Q^nBN }YVpc=;WF'Ҩ-y/)sAƣsXQUC9؂ Mδ"xOd97V_J'̐SJZ!@!G-Wc_V4עӁǴLF1>1Ƨ}='"LeZ P19'4mPy/ )X!ʕG 9WJM8}v8<ҡWRJ^\e<=d\05~H&@!hHHr$@$@$@$@$@$@&`7Dv74TrrDf݄lV<qq伱ŋ@IDAT6uc kc4n)|rCdZB8BKu/z= (mCwun6aE-FxSDMF^u*RdQ!HAg|r 3!%{l(h49i`: (xY5+DH!'ַbgwM߈r/^!in[ (M @nrrS\HHHHHHr[B8&X-!l}HJ<}g?izdL_L-:g Û{XdJPY|JP)p]j PQK* .ZM9⽱Nsj.l5tJ)D`3a E GBy9q(ϖURO 9MkB6|/}WyU %z)C1Dqu.(Fh* Wz'l0qE<@.ajhzf7rH 4rpHHL'@!tP 9`) IL!M J -̊EvPq(3~AH l1 K$“f sOY#9ەE)|nG#GE6 _ w'1IZֽx$O睓rbY[?E+x<*w 9%.H# 9ht*rNksQ_Q2h$DQOL+rx@ufDȞ^41?'@!9 1 9XHr)Z\k6rQ]ײ'}_ۚ'13:'$.'DFt|rg=ƽN$@$P (BPY IHHHHHH`f 9Ջjߓ@7."JdX te{A)fa]8~p.r)uyo ׇ#ki>.2Rȑrӯ; !|X!4jI&>B $reJB1lrm-M5=uᰋ `긄T*`}ø~z8:FBN6*+7rp-Q)bT&-(h8v8Ê0TїY =KЃYkd֛_?o/o/ "QTlnZwDO|ԿR喙/ཡYa  9p$@/PyG$@$@$P rAs%@!G-)#       )5XvƣȢrZfn%5B3SlUv RΓ@T=lAYnCi;[|ܙ;A!Z-."KK]>l9_V~xu 3&e@]uتt P1>6556aEOy} hU\C,^ߠgc@lBxŜBN1sn=PFqŶV!֗6/1.2 YnK8)C.?@VșDJuM6>_|3N;~v ~r, 6rbk (hg$@$@$' 9zXz7QG$@$@$@$@$@$@* )nrYTţjÏ)lEC}tJ$@$@$@$@$@$@(!OQHibe!Gf)ZQo>fhh1iK`dfL5+2$~rkDjᥒ;Sr!4]NȘӨdimnBNdn43M jL! |\"(H 2x/(XhY -ض PQM8֬!\[BYW"1kpD9>vg/$w+W~q߹X™ߣ)X)+ p$@$@$0OB< " 9HHHHHHJA)EȑW,Vr669M86̌Cd!}r?ur&&@!Go+ht| "suun8e',"P %*" 9Ecj r)KrJ, \fr#rb^qmi4<8ӅSoHXE5 92ڦwae{ۢџ>8݅F/R5 9Q! @( HHH@'rta !@!HHHHHH'P2BQ(,[;knq 185xR֔vS'@!gyFna[~rNxL AŅBb"ƝS1-G6X;3s8sPQ϶S;?:mFX( ?s_DREBZ_->Tȋ"Cy<ܻu&@!GgH $   S P17'HBF`lN$@$@$@$@$@$@z0St{#X'3ILr6eXI[h0_ TLZ}ju[qpu#ޣ̌30ǯG9)I{I槐 0 9%,KL9ȒNϋ)xv9P]]AUr aM%@!TO{AuBH9(~ {| N#X8NAƵlz9R9=x'sfL35^f\c(˓ dɄ5$@$@$`& 9f\Z PJIHHHHHH@'f 9뛜|0`p&GDfBjIH9~-fX㉘Cbirz|` z3)p:ܣ{g %˥P)HqKүqj=.4asסރX, WFHBNWP); 9"rԱs|倒!g8%w5E!Gγ[۔1m`` g޻̸ } Pї'G#$@!' kHHHLr̤͹ۓ NrtZ2)5Z:RK!!È"ǍR0JX%/B!ŵf#@!'sh{ۅ!fhr(X\(,.^PQ)wΪ 9X6!cY;t>#Y/K|l#^qֺx '8%\kЗ}yr4 Lr2HH$@!LڜK+ 9Z= D@?9<ӈ |jW9BNDd bFd3g#}p<$t*ٸa1c4ao4 9F.5%q8 BN 9B P)~ XFP>&\X[>(䨋o VRl3r6٠9+e !ҿ_͸ } Pї'G#$@!' kHHHLr̤͹ۓ N(ymS{i߄u e&m#E8SRWrt,HB^[SAL%@!TܜrA;e8Ѭ_z~pw^_\h^[<qGqW3B_rH2 Pd  03is.(h%$@$@$@$@$@$@$ 9:,a[BN[LFy< 93b&@!Օ> 9#pyrg$\txPQ*!'PUUѩ Ns{2eCȑkr:ro !XvSKSq*'@!'vzl55ٞH$W2J$@$@$@$@$@$@cڒ^Sڦ,|Nw*?wMkBQJK#"v96*Z\."DqDQQLO1%^HrNKb 9%.@r (^P8rBN9Gk(zc!֐)<ş^+HĒW*HgÁxGv+]zps?:+#@!G?H ; 9ٹHH"@!,Ҝ'r>$@$@$@$@$@$@$3*")DKB܇mͲR-NCxh brݱddn%^QyGIBNaqsmh7bݚ6嵢ՇZ+렑h C#{:a N"em.h@GcR!&$q(?\A(ƐUBo 9EkB߿/ؒ̃]_vBU^At|j'Y2)9̎]FBNa؛H`yrg$@$@$`$ 9F؅S(A'      < )]uyԼn3$ q4{5^Ek}E byaisjdž8'bQ̽B!\ޜMrg*ś kW`MXvM`)! 1.؇HHHHHHt @!'"L&FgY%l9͍+9 (,͆WHHH r̠9%@!'_rG$@$@$@$@$@$@ p9 B5xEWgq~ '2NȆFdiovcJOl8ֹ\,)FbPzVXnZ2 Թr5BLg.axn 9尦 7xY5+DH!G{|+p̓]brѹ~8i.!'!%ꜨZ" $bI<<Ӆ?XД:3PG$ABNV (䘊i$@!G#06'      )|nG߯ gd6wNîsH>lmNb6I/#ʧyC-hr?q} ^íjJdé ɩdٵL6lPFu$? 9m";Nǖ,}P?⋖3!܉k7 %,,j'ʍxrpCB1\9({zVVjI!JѮ̽R#"CqcXsŲL!r7p~RhjΦS @v'Xe JBx9x(IHHHHHH _f 9;ZeGwf _{"uvE0{҅q}P1F~SpB PQOP/ߋkږtc`x I`quX7BScťpLi ]jjDZCбsjb W9qGXr!@!G=g ԳRK 9VveBNq4z8ŽhXr #.e{Lq!b!8K r ˡIrA   S\=7 9* FBah ^#!-X |$2\Ȭ9^gY} gopb9LNo BĹ+ l? !-B!-KBβ7غy ^=-͍H0^/&n'm^{I-Ordfoʍi]evMW g{jG|r):wC㹚(C!@=++chW^)׆zzc;:>MQ])%Hf(ꂌ%KqP)wJV"@!J^IHJR 4OB< ( \-Bru wY*5"̆ގ"NpZjrkʹ3$S1<s8>qMprq9>j{DW_گdk|bZd- Jek͆=6đ$IrGɒ37 g vloCݒ'38snκVGB~,9RPQϞԒB]{Sx\^7 {> [Zp[I8#3xr)>n Ms P17g#+cŨs$@$@DBN)EkYLBb"<'      /%JC: P)|P  & Z?njڰQdivap\^KhBx#!tODf-*-B  PQvEȱj2:In|tffCV ;/2\9} QkK:gؿg-'[D"W􅛐{X#@!8<rԱ@'+cŨW֞)OS|w{v6޵+u%?ۇa ?3]xt1ffG)3 rT@b  0r P)!       >clZ(_T[[1fe"!8n rf{ gg-mpd~mFq N=)3Pd 9P(TB 9/%v=Y;D1)^w-N55Bنvr. )ȁ8]d2;_^_VJ[O4; {Jp.Sqdr*\\lr@)k4q R9C8ֱ/1L Oc?>C*)ya)rJ! \ T6 9_HH P)Yyr}HHHHH\{1sT}usl%GBNɅdYjϏ65*yBr~p FBI@i)pVy M[63.']{ 1G㒴,(m);'Ցu0v8qdw#c8s=X|E XQ)zzp <Mve"hkiv=ぬY 9p(%@!G qb+ 9VzeB1t{h܌mHDУ56ǽ8C_(/Sfb+t}xz{w1;%DBN K! %@!Bm  9e*K.B%M N@vA8WAep"@!f5*f/!.óq\*rNayPdY '&~u2pz1!qG8R*-RSQᚴVx@Ȑ}Y;N G4˕Zо--.=M./,s(gŖKB^[Qȱb+krmd[+%"s+njc(=K 8,fkztᩈ"Rΐ/ 9c? (%v$@$@$`  9pGB$@$@$@$@$@ 0狀xP(rrU 9:;çy̑F123͡0G00Ldc:> gl8R$1$S1<s8>qMhS(kyrI,~xv~jCrˣB~)Ԩ)nSiؑ|j:oGiNsh_;^}i6[F)>O3B?rcɑGBzger+ʌ+we. 9l$`EruHHP)hp- PYL$@$@$@$@$@$7Y̝ 05rf\㕃#39jAq.Em]fRH\dgH"hSB SHMV`ٻ҃7ӱ)*2sMXs}0%dDGh!3BQ%YXfޑϣ(:GB螈ē}򯥐S1(۽E/2PdrF, G+Aϗh,snW|UrjF&qFd۹7+#@!G?x(g{zVVjI!JѮ̽Rȩ̸rWc.oFV$@!NJQIHJRײDxN$@$@$@$@$@z˝Ȏ3%XU '33ˬ9RΑ5:ʑaga7Ka4tݓ2NEF`nB!ѯSQm{ow?8qm[L.yy_x.r:RڷSy3}mʸ Pя%G* 9^ZRȱR+sr*3ܕ(˛ PȱbԹg  R"@!,&@!g1[xIy>L"9 XEwps>I@h s?<|ёB ?*%!GupV6رžnE8i+q tb-đCaLF.2N)*ŋ걪>VKƃ ɩ'ŝ0,;cB̩ i 0 9ꃳ͏`p-tg\[bǶBه&7:)BN(Ivi*eg/ϊl;_|:#LU4rԣ@=++chW^)Tf\+s P17g#+cŨs$@$@DBN)EkYLBb"tMDMTd 9FftMu5k"#nK2pmc5E8'v`;}#8u& -;̶kEh7f X518rcˑ#@!G=k ԳRK 9VveBV/a}ݢmZ+C#ҙ aP1 -&~HHH(?gMBNn>ZRq$CHNt!1rHN_& @9՞f؛akMԯFH $` ?ax"4s2 9L,ZSl!G $'[w."Zp?ALE*6nscs6XU@ȢSpR|(Np} cxd6@8deFBm Ŋ6F'8u&?)MxH:vnJk>613nl'wlk'ޓqYf9sQ8Yըذ P Bk 9VreBlce{NEh 05"n))X/1 MB9 ΃gEBNiŃ)\JdDb>WԌK>TV%   T=Bc 9Z9" T _.gpmQłrkmԶF|݋!LFI`f%H.[Ȕlkqa׉:BTPgكFwFx4Eu#(IxO?0HoHH,LY7Y^(jd.b@ᯕdLu_6$  (>Upn[86-RT`!r$Wb;Ca r9i'C ";˘8ƒ'R&#lL0njp(`ZE),< .siN+`8.? V|pV5ؕ9[J V )Y@I [d̹3Fs"s39'%ZPȱX+prԠdٹ}B3CL9ãBwqxU9~oBz !zGOjju8܁֦]} y/ 9h!@!G;w 3r*9mqUZSȱJO(r&r[g&   pWr,1(٭S)pajŃ=_ 1vOM!  (AUF8EϡAH9̔SQr_N݅ߟl\<#0[ȑ^̞|k3JLdM^)2_dd"rF|e MNlu0nq_:򳟥HT,~xu hYU'$-~"lZdiۮ.Ð||*#'9[drNBZJ!bBiٍPzaUxHV 94' e7*2L$qn޹)>q҉H$IڷE_^G0vu:HSTr@;JA!kQg 9xY5D$c!'NRUrf  \τ!g$wV(mD+w~H' 9)6B|7\_|V8w5)CB)TH - 9ڃ/Qp`޷֭\r5F 5x_0u9wnK?I10=Ø̈Kªr$;tD¤wUYޛ.﫫 Eqh$M"99?u:#HD}y_YJ;;]i0^DΌߒZm39'}y]vwf^BN2rGε f^>!r3BN~!/fBE}4@l'0!@șI 9pTb7ߒRqGHP FujKU/:\ ;Xw?QͣRgEɝ{) 敝mVURu6p_]7VUF4&5TE*9<߫ϪLaűĥFٱN"PX ꂲ\[ҜdV]Q]1s,9s8nKΉ{BNgJ!'XmZH8W. P_ e6&usGΩT硕BNy2=r̵ ?^~荐,{{9!'?^~鍐LNTҦ 3   ڢjAȱ>3G!g>BwS V* " T^~@N9C͕NJF!'?^mH߻P o?w2ƌ%ܰֈ%ѦV761BϏNvNl>nϗ5dpˢZjhIcHMjV͉)aN'FıXrΝq#3t\, ̙rvBN25kjS%'6ՑtU=rʊm";hSO?eۛkE/NrRf"<[ұ_Tt!@IDAT:rʎ {xgB狣}2*BnV#"Td~&@69y̷K+#"@JB*bnUlUK2&@,|yROC#̣G)|ySvYr&7KҰ$TO\w/3rО/ӫgxo4~A$#l\XjN{}pV)0+dLWk(rNuYu"lf 䞥ښޤgnqLt=}d*(vu91wB ESO?eۛkE/ۿYjw~;PP P0TPmH5 5 L!=P. scs_~(@! PB`?U|y4_&6 o @6ۻ=S!'~M32 r';+z:@*6d""@E x=k劗q}D`e8"=xRr rׁv}sYv`\?=ۣ7|-TʖsAIGM_MLq mVHKٶ6XưZjeUɧ'z88s99'9cszCqzo>9t :mdæ:us}9pyQ~9gRD)%Mƪ7-jT˲]Y%Ԅ22N}KZ6ɚ<4A'2c2N~g_ܣЈN3eBvwvq`w@=\ rg姞9~ʶ7׊㼼TgĜ%kZunSmI_?ԥwsO6rl#7>T﫿Srh؏g ?Km«U<t9Ӊ޹)EFOҦR  jwPՍKXV|ɤtsTUro"N_?*WVk`&XR8׫_)ꔞ?FͦzN:0#.{U'znH93 qBN24 !0!S!9ܳ)@{&K*1=sB +x$:~?sRX@@ mWݮ)tOgah@'JqX:uQ9S =Ok}c4~%tݱa7k%LngOuɛyY}YSH;eQV :Kj2sP\?9ӣ?]cf"ϜKK!'7PPoӋzY"U _ѥkw5:Lj)S L@-q\ r^9~̺֌|ַ/olWvEѡMsF]%ےcj&o wT?}e!@$~}k -^X0@ș H 98?QƛN @(eEyFgHAIoby8GW9oB?s]Zd'J4]U_XݨoֶF&e3PJ9 4ZF;os<Bd@ 6c{a"0J5d*R܌?n#czl>'޺~AQTBr"]SO?eۛkEq_^[6j9U|ɉ%\z>Q/݇ʶrlCD-W-2` 04krfQbb|L!S5bTt51( @r~@cC j*9r93I;-Z!;VnYi*/B&BnY|h'b*lnՎuZ eM̹;OL?]/Eg C!P99߼q>.68ڍz=vϬh9E#d@= \ rg姞9~ʶ7׊㾼L_ٮxp*9Ot'uL$ݷHE㲄.\Hq~sFO w ?W۷g x6[X:1QOR*ű@8?Pmcn@i g+~de !H:B?:0UP&G/iAU}fm~hq]z2ă D)]6T,jP@V.F!rrzZzٌ\Qw/_37 x<>YBNZ;+?DSVwu!gs.9N@ D;rJa 9 tW@C|Q[_YL(BN9:~?gBf @1nZ11 $SJnds׌nޗ!䔚kdzSFNDsTyT@ %|es~w"SD6Ѕ BSp@KBh(h 9N@!'Hwi-~L!n븮~N=rG!'3kA!OZrܙזez{\ 2|ӜsB?Ϊ!`'Ј2 @@|Q[7B /I!Ǒi!RFW}.C qխT?^JY#.<"(&tG A)JLmO(4翍ma}PkeƬ G'tC4G!g>Bw:3Te>CרvA1mxdLq!Wr|n.!'r-ȝz")\+B;ZT}VϽ2 attܹHEd*\J moW:6U6 @jwmQ۷Mܹ<ϧ L3BO7* @ș@qv|G _:B`Js\:tF<̼"̋/rsg=tgHt[m_LV{jˢ7U[L^ڟog$ 3 @@qYqr*BN8 LKW@qe w?7FGu:saGi 䔆#@ :rd^@JG_ݯ*6>K7#Ap9H $zkܫ{Y  'ԶvǷUNL``X鏌 +E)/_n ]  X:̧k$K>QWAնV}Bw:gN!"\ B>Bl9(õ!=gLpLr\G~f~L++ep@ck?hTL @@F-_3UU=B`K!g^DtpDEO:!b @FUn%qZΉ JyT)r%3)|a}v-j͠s^=ݣ cJقªFbm\ǧu}llrf67@qSՉrbʗBNr /gVu-::=s.`l0rT9%0@VɁ!NgYb' @«[`,ѭrܚ9|Vcyg+g TUG&] @l\긮뇥3Qr{;-ޞzve ޣ>5_wNliBUںVѦgW4hZYq޹1ң8 Fmn"_稩;ޮO,ڵ'σ[rr%5яkA~!Yrܙez{i痷ιazNT9%0@vtү.V,dr{;j}c[j[jC3K9Œz~_ƕ+aܴF_ڪn㘹^>%K< P#㰄NrC־EK/ Iwz+0DWZ2˵ ?^~荐,{{9oӢFm-۲dʇu94rJÑQ {IRTə= @_RgP @)-OF+BN2 8j}Ku{cC$0~I~s-!>N!B{iwv,%77jwTbݴ i*Los~r[7zcws@ș ;\B!'D=>@M:t )ro!'r-ȏz#!^#BkUnzХΛvߟm҉*9Ozl @~#PV{7_Vx2-BpkmnA ;!gn,LIy=QQR2N69@&p@_ܪohS3[*\[C90b&fUDU-ҚF-o 9C3kJ;ٜreo!'rv~!Yr1ׂx7B5"x;9pf@`@[KCV*q^@A rZR8`̘#S:TFr! \Bv*87?.w@wM)NKc/!~n!°qasjRSTcntnF7T4iMVU/䛐yD5Fbd6j:-og<{h<7 W{9J!'+vBN~I&x7B5"cCo?dkDv~Y=r,̗]_QQN@@@ T75_VK82CA<rÕQKL 𔩐cK% @p< !g*Ј҇ISSNB%<^)gs{lͪV3`Dqk$a,ag<qjC2ΒP*ư<Q8ug?f@ș .#_¸ ;?^~荐,{9kA~!Yr_Vg{83  )x\#O__G[  jkTn|^6@ȱ2SO  @p@H5_Q*nu(tovU.Hʱw̕r,`^XݨohIߗS6Lsꡑ{U!} BO@/܄/?FCFr̵ ?^~荐,{{9/B=J ipݣ;?鞺w M*Vg/v3yJg޼$t 9?V鼎3 @'P5y|a%`Jo(aƂSYRBTyyM,auKDySdLاG` Pq nΏz#!_#BN~9Z/?FCFoC!$ۇ5ƇJt@r"P6_ؼiZ&9G'8B@ Ht]4BΫ?<1o_:@ -U՚ 9փ $ҍFH97+_6!TzJ 9z#[V/nlŵjTUg,Ӧ"3r8e r] !'?|X4A {LIuTmWŏ$XG x$^_B3 @s@ș {r 7cADCIBSMjmYT=굦5,KiVٞK˃%R&3DF9`D7zc"&u;BQh(?sY]N8=XGP2}w$ksYnrrD/d# H'嘪9iK1R)L~62'ی Iǩ+#.@ O!#٘Ȥֶd)Ս8>@!Yrk @~t4 tEȩtgN̼ +_D;BL&N߲ha^xn6oX*sݴfI8=޾i{y[j9&x S ɵ8~>!Dn9vg>/@bVY @ w@qG|%BO@ 8,}`HOK92}r*݁"80):9KO#3 Uڽ}^>TɉШ)JάJ!D r*ɹl! -D!&Li9N/ @ h9N=% @_^ȘtCLu'y^r*݉)- .&3B%.\\]^9%'Sׂ `eP &{a9bmMDݦms:t^1gvO!xPy9A!p-(ZyA)WFB}ɻr[V@ @r!@D Bsuɔt硩sX:{UJnj9nVYcEș!g&d'{O!9-P(v̶;md4;t9x93d@ȩ| kA!s BNy2}rcL%ܲ2@ @N' _B' @r9W6pu+i<>gW@qlj !g&qLؒBNv>u>hFyzvgEcFȹ#'gVZ -H!F%kA a9BN9r*$%@ @p)&oa#- )OYc=JsB:tFs'w Q#̄3 [@·'a]mئ{̶;m,9GO^;'S]9-+ @ t9Ne p"@K!ǿu#J["λF+6""Mvi}qCsYBET :S&Rz0דḒIH\҅N wK{ ÙYG!|ls|. u5JRܨۮ[yЩsWÎ ϐ*O!9ZPY!r*IB!+d @G!}9e9L; d p"|B`4*oOyTzfW@qeBN2a#ʔYsX"NcZZ֪VL<7ANJ` #ΐM(s'g1.3nv7w%֍PPM]mDHHjUzNO$ɤj|3'GXMVjْ7Oy=2:+ރ'SrJ˓*C!ܹq%g@ȩ$}.RPd @!@ TBN3srEW@ x,.'.\Wҭr GbS54jz4rNv,v߸޿=CF̹?| KN#SX7^ԄԠzhP[kZPH8t,kc8Fd^Sg@}CUƢ)rcg[%O!rØkAy:qT'f!-B`v9sa+ @ BN3C  "C@\J!ǥ+e[uү.2U4^!S< $SDZx֭^)IF)UK&Sۏt#=XT3Nr a"Stp-(K7llrf6G!'?^ @ @)KF*#2eh@ 8\k#3!;BNajl]h6H *ܼPGN\J%@F}n!SX͋G!x1ZBjC!<\ @'3?#z8B@ @ȩJLknbԍF9$]!sc%gN{8`)\]ަ۳PjҏNvNE<rn@?E`nZPKsCNX%Ⱥ{zjTm3k\Z<ЅKt r}J@!rOׂy/gkCGYey 䔗/C @rf@qP2 `3Wj:JxЩ2ΩK2wKV*{Eȱ fAșH7۵!pT>uA r*/BNvjUL44<ށ$32ȘqmXB;1[tը!#4f`uv9`XGO^Թ7g*!2ܙrɵ f^>!rgVY^9 @ 07ٰAr B L!fIo;RQ7/B}>BDjk}[$FoLTqx rB(BN~¡vmߠn3sJY"Θϙ>3Iw;?sG3N|nĜU+kӆUZ] Olzgl,-d@ɏ;ׂx7B5"x;9pf@ @I!g&8BBH  ))Ҥ$+RF);bL3= m ΝqLx-$ @ȩ |. 0.YԖq94ջqMSqrUyzLڤ-Ϭ֦+YՁ<[w'M 䔞)#O!'?\ 9~Ȳ׈:{ ÙY @ @`&L@9L !Al"cJMc\+W(!~!g"1Fٱ.a 7a9BA,@ɏ-v~Sq02C#L3q>>*_!dpH.s{hO7x~?tV]\f)e@;ׂx7B5"x;9pf@ @I!g&8BBH  Dc٫JqDTnNʱw9 9A?طP,lKd#Qa禛AqSu69Q}%]@լz3i:.RTʙ*XE"aڶ^ϙX'MTȈ/ޜ%&Sb W9cZ;+?DSVoUK!^@ @@L!!4@@ p'$sdҵ;r"TfFșHg6ڵ99OW1q"'f!;-z鹝ڼqլFu58{EuVcImS%Ispκ7{ k 9ǹukwjsF0P64K;њ%D0 JGzT)<^kX5YPٱQP%&}s #E^>Z5KL%9v @(5Re@) V B+Ҕ{K7Le%RuEZ̏g͓X:/RI[ra]P{哅_:|׿'0x1/nEd14@|>:yвرu>5hU9zP2X! qp6߽IU37{?E pկFlAQϔn\1Cs V-Ϝ#UW_h @@ 䔟13BN 2 @r\V{'z #w!gqCHѦ/ojQoLr9C1 (`9@G@-r`iN}`XϹR9<79mM37y?2{]1cJG!t,rrrcϵ 7N~셐Ǭ{k9' pgV@qhb  Xf@IDAT@rY !c e9 < ]o>qALu'GJluAن&}es4~Z` K!ǽ# 9 @mzpo0>~TBdQیFgC/ę3trJǒ*G!'7\ r^9~̺֌|@ȩ wfu(& @J!ǫغrrHP[[3med|J!K)a#,%@t&X2#Xِr5=hTr[g3 @Ʌ}L!'D!=6Yz^Fur֭Yr.^0} E3BSfcC 䔎%#UBNnɏruo![d5!SP9M aA xBW3u!dOh~mTޱ{IS <ҩW:>tlHA| ~:U |J!剏 *!-!|p5)ghϲzm2ϖ3 o=FA 99@ 䖞U!9/=7{[F*<|ܝӀr6mXϼK ۚg;08CLP:9cH#{qc/?f[kFV>YMe T;:BCCX @^%zl]9^PM+w,^#ۤ- '3hÏ2Уsz||ݷXD!N͍U#rsIe"`^RSƎLH8*F h}IVD,i-JQL::O@rrE7@-5U:/zz{[=N5R9Vm01R]]͌yj==dž@)KFs-ȍ{!1Z3Bj*C!2ܙաr‚ @*fcBɞЊ9CTI^SW쿭Xb< @3 d-k`֝U!KU36}C5v7JO{@'r>Ats2+R94@ 'v 99D'B FS L1L+04O 9.G!"XքUWWiJ\HP(k##\q/k?vBNi82Je ǟkA~!Yr_Vg{83K $Q @ 9^ɤׁ= 9NJxS'uoUFĩ թ*lfU7-Wuj(n0_:mē JΏtjB>%) G <1G%sӡpGK!ǹ!2@qOtv9skk Pwʺ!;[N]rTTtglB[tҤ2N{{3_ꤩseETǙW)#䔂"cTBN~Z/?FCFoC!9.IaB xBW2u dOpBNν؝ުH QhWer󎒎ho4s)? @rA;)}hۡQKxp儈G!}9#r]sS۷Em%,CgIlBNlNjT*m^>~AWoS:mA!Qn9ZP7/ŬkM97-peT@qi @rܚ9ō=Nr(5-l5d?+}@$мŤ3~C$,8BsD'av9̵7i˦:w6-BUMg@'^ѥwdUءG!>T>9ZP7/ŬkM97-peT@qi @rܚ9ō=NrHvwYg2_Q5b7ڏ _9̽u[JvH~ρC!="R@qnn,79qW]]vlY}6~.mrF882Μy(re\; NkAt$Bϵ 3ךּrJ˓\N! $|@ @q[|/BN;MQU@5B{~@1ku\˿ڏ _9}2)|0!\. p .9:B3BT@ɝl=mڌҤ@`ÔKȱή^>]WoS<-DBN3-r̵8~^8! YrV_9(!D @ @qK|'BNqB 7v@6B/2 YUUMG811zN)T:>jfMŁjUg& )iDt"n"1ϕ@H&UE `TɸYǸdd_\ٻ=T qyPuh✱('M5){&~sތ)m7)S%©qUFIT Lmd"T*2X쿭#YU{2Nψ6U/2.Tqyns,ȒCc,#L OHFl #Jf}b^w},1Vֺ2U*6L(#U&gV% dr0(9p螐f\lug网 7P\W4g9O[VgLْ\!A {ҫǤ#1K A@) C@B,p;d0֊e-_ڮY۬V*!qF`*εu [_B$JgR@) IQrܘ5bL!g2 ^C09q(@hbY @S 8535B38R1qjw+ΈwKnT9ɛ~Llߪy7O bK.-JddēŻ.)sռ`llUd`z6be!8b6"Nq͒e&*LӛUFh^mFL:YMmB*x?V,9ħ;?FI^`u.>TWF dMsZ%X7,%#\3/)}ٜ7&Ş7F%lƜXPڟO7X\M%;rҰ$SNs2,'Ogr2T)*~i+#;\g=ͿU#gK91r~#}pJz<M3 P9% >'G)mjf[L ۚXG=٬ߦtӬix\#3ny~2;kdl|J!) L!ZPZn ! Y"lrar#'zBO2!@B!) r3Mee >e*Hu\Kߜ;`UvDȪ2bUfUqww7Nj .fHsxb*HJ%3q9'gb6BݏPq:SuFyYgLO"jST3bQ+ Ey5EbS `cVj>%℗0ͪ<{'(rYWA9۾=?2[UuT'Z#+Eͪ3~Cnm*B0|޿]E5}=&3-ϖ{3U>_l) 〤Xo!@;rKVR99c̥!SGhV-]ܦD"f,!g߮Mz~VSL꓇Ug|jW)zcU}I^Sd×Z|e*Ȓ7r rB -ٕgsۭ̅5V+n*Q*:9 9ы?ۿm-$BNG 2Drzǭ@!+ \ @BNY9& egdίj..His*\ݓxUe dhSo|!Hۍըcd!9ttj*U14n eeq=Ī,XSr}E3 RJ>jO2cUt\ߋ8]EᆻkԤY/+Px"ڑưnu̻td <1a0u^3Mvb9vcRaa7I߷9FRMR1L}h'){ߛXged`jό$vxk֪dY2L)0մ}ia}|e硿=.?tZ̖>y.OvowYؽK}ow8Kc=Sy_ 1g-] 'BN>vJwT\Zd>"Y,U;"䤳dXRprc :9K4W"iID !@C!'=Lu&9卋c^/Lgř_*SI>uռ=p}ߵ{TH9-봃BZc Uv0rIQJqv.F0ԩte.'ȋ3:0nike~v0g[t}pٲG-]-*4ϖ]xyhG+q5y Uyoȩ.:M @ rYW BNY93el@VӚ-BNZ+K^a@ 4E!'(̛%9Y6v$ @ '?i2W`rF.<`Ė ٢B0$R+=Y_7̐v1"A}vxGL'k3>ř_x!?D^:u(34) +{L-ӡ"&>5dJ٤~drDPݻX*^⺆}\?qfJ{G7iǓm`3@MP%4jR?S;5*w--]3vF6UW[a骛!vtT>zd;UPi󺏆\Y^G)oֹvlk?/lg']){jUů}o:'ߣֳ!i-*8Ul1ݠj-cl, [KE{{KA rRYV BNYw9#eŒ@XS.BNJ KZ@ 5 D!' L)9*7v"Ӊ!@ +_q2YPrzrTN)~}F*,+ /8^ _3fU9-#*ph~2xļ@~r-p]EgoRQ3T^[ U<{TZ˾}{/>[er2-gBNUEE"w׾\2G!'s%' )C%*nK!5)!d+_q2Yr"Β#P/rzǽ @BNȸ! 9Խ 9ժv1NG6x^?st~Q>e8cj>%C\xjhǖͦc */o2BN-tiLj F&?ca+b^Vw;۝Bܤn#=]TVeq(e?Bv'.-*\8V}D*[]T^7{9Ld! Fk1uEF.v^;3`ϥ+ϖOV?gl;/gwQIlDG~# bhĈRNըȦHyb*^1J~ӶSS۹ۜ_3]]ksҩ!#87~t';iW\[-JOgՍH%(lyI;POI;`J#bB" i#G4\g9Q10rbZJ Ĕ@] <@!&\B $Pp8  @.@a+$B{*4'U6Y&k`Uvry%%B-[p'wCk'l~bJW2x7gU|јgKuB[1i1yyxrjդJw[x SdhSL#㼍3ZJvvL%*B\nGyuVvyV Su&o$eLy[n3>[8ߔ+9Jm}#cjdBNfJM@ .SB!',b9).nRCPI59`e RK!'%@5 @ 7I!ǝv\iֵ1퐳]G6I*iݕhR| 1uM%l;.nz<^j߳;Q~v:: 9־}o=[~z(߭کƧl~Rgt#]GWG}J#irDTuvPd]fs@@ 7BNJ r2TlR BN X4d9!g@I]I3BNJN@ *S&BNrkG @$Ȳe/hVȹ"lV#Ԏn0gǵˌÝǷi㘮/0x7Z> -Ȇ1c7jo韯ad#Aqj4j9Ͱk+O)uEȱ#KWli]泴sߥWG$(?k}1j޿m~+ :N8{gxrǶ[Lע^{#k"^ X{oϖU;n}.BϖUZ>[9WRYI7S΁]w 8:@ 䤾$ Dr "g E %(^&BNY"rR_bBN7 @ NٳVc5*:]53}a_>a4*BOPoRݳP,awMyv8O*$2~GOH8qZOy mCHMr4|IԮ|Bq4?D FN"ڍhd˫WDKn넕z*)>|7qK[*psZ͞qҦ֫2/xrjWj6nl?Ogr̒}݀{^{^},ٲ]-w|tQT E "K։RcBX% r.'O!g3rQH.֎/@ȹ̂OP8@ȉS5%rZ9BN X @Nrp>VrUia^௟>\NT%'K~zO"IxsLW#uTK: V]/GіS&м8}LGOpֲN9{IG:s7AawJ1~k_u\տs=p/cdF_ttF^S|F+oP)hxrT)MǷ~ 9Y`uOwߛP1~A}gK9!vJ>X%r4RT,@I}I09!@f@ 3@!'E@9(2)J!'PL D 䤾$ nh1 @=@!A!ǝW!qrͥzrN~hJs8ef,¤[$MҴ])yAt# Lxvgvף>9}ɟCюBřнOqy+V& j֨kAS?IJkځj-. {2x7.\Lﻮ3ދieh*wjVFXc%]1+<{<˾I/blnTN]zdrB%C׋FB\ ]9٭=G!? hjz 䤧Y!''w? A9$%}N T<|! F& @W9^I1.R9#r)W ]_YW)s7ƙRs7RY>r6umэH͏joLsDe'%oJ3+~bXճ]E1sYmx?Um)8ʫڑuc ާCWȆTݢ8 !C#gί%>vǽ&'r.,*φ_m{N,ثg 9+؅2;BNȅ}P7&R8A {rWs2BL1\9f@I_MBNN~@&sEA!' ꬙69i(D!'| @ n tK@qs1wIM\a?Cr\_vLyJx8l/ooOᘗʋSOj{i-E@4A*yO|qM{U+1!տ3't-^ݕT9z̊CsU1B -Gq]7G3ӛڔVXq 9kt"}¾_[ϖ!lYϖ-ޞ-Kr|ivڶ[l-Rot@rzǭ@!t9I GM!' rY&#wtԑ,%-Vp @N!'NI~9#g<${a}Aځli?6'C* ?3k?&Gl^" LԮBwKq\v'(%?8y%KG7IyE{㊹9vw#۝抩t1~zsb۶c:8[Uy"4)ؿřsƲRZ;DLȹAuﵣS[)ϖ!' g6rSv̑f3 X :er@ 1+BN뛕rRi BNPd7,9af4@Isuɭk9]#@ B!zwԱr4L=}ߕ\q5Ʃ]R^{zqOȄI8Y>)/W: BsT| ƹDN]RMR|* S%?p_ډt){YjG uy9뎩YuvMIԗ&0`BNY r2PdRN!;+FB @9>@d 3c"-xKHN28nkǓ_y^ȋ fӐkH.*rh#'ΐ>L_3]ED;&Kްq^#iH(So"4|<㽐0MFF*m\nv-w8Mb$u8 |i ?rǪe#=R/ʺþ뾷]Ϙv>sϖQȓ!'Š+,^#DN0@z 䤷dXR0rʬ!Z9S4W eBNt;+rRiD!&A @/9~d@ ㍛7&+~ }5p[J0bv q:Z 7: k˚wG=@IDAT$_3Usl_;>raO5Kldd˫*5E1]M^i;G/'Mw?9wm)43Ϩ SʘNXvyEJkS{0]zDf*îǺĮGAYr0hiv({Ը c_)g6))HDVpHՔ'>sVB<-{rW4fƪSr¤ZA@ *sfBN*Nr\p @~@(B!k܄\qH~ϖr$w jTe? ;ɖ`qmc-*7TqL. S>%itr}EUѮ6U!ETg)}tM1OkU=<+F& \+]~T*gtf칾1MLnG|Bg:3#⌇TBu{h;Ϋ8Gʦ#wv}ծJw,sfjǒj;N5VvөɗC;~uOsWTZ { 9{DTr_OՏnP!Oֳ/_u/V[yM)Wϖ-tgUe BNL Կ7뵅"i4ba@ r]?xԁ(O!gB rPErBNY9~Pd@  \/ @BNЄ9()Z)L5%RD\0m^30TxA ÏÈKq#|_)5[n[_~i>?t U]8[U1k\qHUfj8ĪkOlo1ڣ/R9 9F xK%Y:fOnG%)쥳m_Q[*e- ?ӝEZ{4St\)o!BN~͟*_کid|3q}㳥ϖZ|zf91vM%ҵ[[rEI(HD`cJ!'!,r45]阔7P^K-׽Y;~,}nq]~lQϋ$ 9׎3=阖7t7#lC-?l).T-`S~!'f.kgzSc@ yrW3"Մ#/FC`4DD9I1ljBNA,!3j \̓o' @ @a@ 8덋B;X 9櫐RĴ\ϖS98t}[|pX?nD߫puNsA{-#'; ڡRZjL._:wJi۝RL+;\5/#ϰ 9Fr:jת򜘟nVbIvy:g:/!U=v4K02z%?AΩvr>,{&;zA~ ])cs"QG۝ܤ"g:kKI%{= ?R_vxJ]34ih,5fB'LG#{y=Ѻ<7phy}|^#W?[yEzw31 9ɩƗBN|kCd x(8@q"$@IR5rXbBN7 rslF d @ ȳnWrqQ)L/櫐3!+;UXk1f}Q~/ۂK~FaV"W~f߸>bAq.kUbd/5rz8/X z_qf,YLQݻXJ++!Gok;R?MXsD? C6k#T띵+5~ntg.MF*tdUΊك#";n@~z[?ͽ{|.B ~@;LxP; 8wjjnMþ_dKKm}7]юJ=[]x8?>[t{\$z;%2vι]L',ĆBNlJA &M! ƏA!'u @In툼E! ΐRD!'E$@ $@IB~c X 97rf}lLW0lʦljWo242p\oCBO&Vue{,$W8E֝ĬcUXU NR&Z>!a:Ati=]R#?a vX];mW|G2! rL-[~k~}]]ֲkvg(}7 ϖG=<[>yg˓lxOW)?"[ڙnfJ%4ėBN|kCd!Zi{9p^ x%Ÿ8@ȉsu- rP%bt#FkF!'FeBNF M @q!J+:X 97ܡ/Hok#1]Y/?5\Z*>ԏl;muo&5(F"r4cG^r c.;g!}hg(UF)ϖ/ϖK{$crb\pK'D6c,A rYJdՋh@˄3BN7W9q q%BNR*ENrp xg @@I @ NrT bq$ƾG!tCaK k_p4s ӴɷWUp6U8W{k7-ڽ嘊"%u, 9}Q^sJ0TLv_3]QIvt׾ޱI%[>/ ~SfS&6%~hԏdw1UnܜS(&)Jq#ڥeՓ@u")~N]^>^!L`b*TY#+BΤdH hWÈ2v- tt[psSR?%TkK =*\Z&KJ8Inqϙ}2R,<yB(.#9tmi1Rv.W!ql[>F6,#;w.$4jbcl7UN[r&w,yScR#u}=̚w}CKu3v V4@cr֮8fЧrX0c5 *ygdß/vT!G2ཏˠv@vb!(6t3]=[l|xuTwݒ.OBN6B&zKS#4Q"bA!'e @Ix _rBNo;rQH.֎[r BN !ErRTLR @H$T!}Rȹf- [*xl{ݽu^T1ǵSgN7*i?&me/'aCv/9BIe?3druj/B-ۨT[;\lִV)oxERL;^n c~O*4yn8+}G{_:BI8u-f<Ѿ?qa߿q_*y ^$ϖטRBFD_>z2!A&'} r_ìg@@ ǁBN@ I&!>@rzg )"b  @@ $JĈaQMViSFRZLz0 ="WrhwRvxS?<$SzO{hTţl^Ʃ]2RRo@iq]NAedv ٳPe-7f+2pEzۭ{Jm߇6zF3*BNk?"}GLW+{y3e}yhܡ>[ް3croΊ|JWc@G91 tDĀ@ȉy/rb_"@!$@B .%BN"D1'^rj @'- tqS}Or[ۤ]6k͢8m8 gnګti+oIu;޻m\S-̕\+YكT/O2«S^{$wL'X4NPbյG~TK2p%:L,EmKOcn߿nlg.rZ-*Uwm tnevd{gXK׉/',x…@rgΊ#f-#U|&7Q拂BNY3MrTl悐ͺrl '> @@ $b!ǽqrLF~~:8`UΪ|7)oXWry)\ / olFw|TQ)v`X}ɿp]6$ [X_pwY*OIC;TcOw#TNb^͟¤9>F)Yg a'bIvǢ?cÖT~0{F4N|$}Ki?:S ؉}[{^Am.<[ngˬ`-rgKw!'5{H7"R&0B@xrcJ%f%3T<"Y BNY+rXl儐zm0rʬ %6 @@R $r!ǽqr !CgЫ#]rbY_9 W ũsu 7ޭT}y~X[tZ,vרZ//N=ePn:BYu\U;挻ÌJEEvTPQ /!]ӭcnTlG|N|]蘣"gSe׻/EemDŻo͒ k!g,#>iE75}SZ ̾}_uߏ\~^+Ƶ݊g[i*˷E"w_ &3ntKr.CB $p9)@!x %6H:W@!'U @ȉM) @ rQg^Ȁ \6ꞅR?u_QIS:a:.t4s”{}wl3O~PE #)tTfiP1B9n1!H^][`fUkpzYEvub~Olyh#\LfBNq~3F0䔽CiCsGPl5R?Qw].'ڙRę ֖sr}"3&~F֒˫b2`%UUqHEKνC923Ru7R>c#s8ډ~l@s3ҥ5}`X'L>#Pd̞1bquhVKZqBa .}`-rg1qDl*Fȉ#TEVnE"Ew BN`T@IE3BNO>@"SDN!'@ $/9lN!w̐"9)*&@ $BNDvҚv`94 0~uCL#Whv4bXFbn8AwEiJ n3*hbsWZ2QNE;"Kҳŗß!'|澮x^[V}(rS3@!' U$ D]BN?rґ?BN:H@ȉ=+C!̒m9ٮ?ُ"3 _!@ ,`2OH 5@ /b>WJ3!v9ƒ!>@rzg @ȉ?'BNkH"9F!7~=k@'r|T @L!3#FĀBN @' K!':Cz{Ȳ "%:rBN !Z9g@I~ !=^ J&uX? rPErBo( @^ xĘ D^ !P9 -\wE"붉TkFp#prʔ@ 7BN 萓r|d@ȉ:KBNJJB@B @k9]#( DA5F!'k'_$BNrj1Ҧ%uX} mH@ r^a BNY#H9Ae,@Bӟ#BNkL@ /O!'xƬ~91vA! X  @@rzg !@ 2KdBN [9-3vȱ^[(砈tz\3,r턬fO4',tL qx>2`($@%'x_@{7l* w;bC`S |>61D`HUf5_T7bLְd,]|O@W'^q+n N)O= 9r$ @ 8rp'·@trc#zcȡc-䁻D>67a\ iBZ <~%є^HkSWE_],w8  pJyr gNB`Sr};[fȬ']XU] Dq$Ǫ ` |8*[KDVn)WR!\#r]B?%:9ѱgt@IGBNwJ!W5+i * @ d@If25BNJN@ȉ:KB x”AsX/ٰCVKn.D TEIuyI.$9!f 3B!'#Ny9)/0N!'p,03}& d$ @ @ rbYM!g4C93eF@9p,ͦbS{D=BN+9?ϨG9h9 )aƖBNlKC`]@C!ІBN(JD`cJ!'!,@ @ "!E4TN!'">dBNFj_٪r=,b9)>rR\RC!ЎBN;*K$UXH!'U!n tKB<<9ɫǏBNjBD @B!'+Nx9 / '@? 6NWG;p@BNHL"lXo-9|"BNpl63BN F$˲TrP! G!'q%#@ȉYAk9]#!3 ' @ @ $9!f Ə!@aRÎÛ#vh4Nr@~@h;sNb\٘Cx9=K׭9'DC!'X2S6 di!'m% M&7Q",V!@ ăBN<@ te@@ 䤸N=)r9Wv9ɮ#2K!'OM9)%DD!'",+_q2Y d)K!'e%H DE!@ @@ A!'e"H@@ rI%"7To"tK,rR[Z BNY*9`e @PS*BNKj@ 3H!'@L9)5B @ؕ@iGs l@FdiY"B;Ej1C}!'3x?i2WV d!'=$h DÝU%/Of5#䤦$!4 @ @HJ9IqB'?XYN-9z2q !-,Dbo9~e MF!'mf>9٬;YG!? hj 䤫d@ @ IrT NJ: dBN@ ""% BNkS9>dL@tSKF!7LQ9-|FIQ1I%29ga@ @'- 9ɨQB Մy;Z^TNhFIv|!GLY9-}jGIM)I$"9gY_ 2H!'EOY9)+(DB!', @ @J!m9(AB!NXo,YERKn9ɭϑ# 2I!'eOU9*'D@!',;ߑ2a d)L!'E% 䄎!@ @B" $L @BN X;el#k E7 BN2@9@e@\S0BNJJB!@ 8B!'L!9*vJSEIiaI+T9f1@ @B0_9 A&4o$E%1BN@`6Sr2UT&ʲTrBR@ -gBNF 4rR\\R BNhY @F@$Ϻ @ 9aPNȊMbXQm!'Q 2X 2wV d!'%p ÙU%,_fO?8"䤽0( @ #ӎ bG!'v%! @@hrBCΕDENV9ɪW"3C!'3Nm9--D!'$,(@2y d)O!'&P 䄂E @ @ 6P8?9 A"鄮sBEW*瓓BNrjp9fL@DS$BNKr!@ 2KN!'p,r9)/pC@I1p9#f@ @p "z  @ L9aNZi"6GBN2B9!@f@I}S BNKL@ 0ӇB!',b9).nFRCHI3P9er@ @p!K!Z  @ l9aOzbTkO!'5 )B@L 䤺H!'e& C#jJ)6Ci!dؤ21 @ t A!'u @@r5M-zmȶ="F@ȉw}B!'D,Z9-mfCLI4 9eP 䄊RH!'EXJ9+8B!'L @ @ xĐ D_" DE!'* \^Y%=$bL9qLq!䄎SH!'EXJ9+8N!wLd 䤪L!'e'i @ @3Ϩ%(6 @ Z9O#zsȡ !' 92\* 䤲J !'S& )C':rL4 d;ߑ2! @ x$â%-V DI!'J ]yEkzg3L!'u *d 䤮K!'s%'a "! vM3 d+_q2 @ tA! X BNtY 5+ywX*ȹR@ȉ_M"!'",*9*g&AdIG9>d DSB!'%p9.>F!7L@ @]@ã! wV āBN뭥"+7TBNa49g@IM)3BNfKO>@ $DJ!'R,9)(bS@ }_ I @ @`r['>sV ąBN\*8,y>^_$qH$rS#Aȉ, 9(c@tI9>@d D^H8!M ΐ @ @`|rǍB&2p ĈBNPMM;zm" !'UE 9(A$BN H&@orz :Er $vD"N@rzg  @ 0>9]!@ 8AbD!'FHj(3-N9XuNBN9$BNrkG-9F!7~9Q$BNrkG-9N!w@ @#3>n2 @ FrbT$RY^9}&9 & Ĥh9.+z#?xԁ(K!'#vz';Cf @ @7 @)y^jW2A 5\}tԡ~ >'pX9u6lrrbT BI,Ė/@a+@79x@ȉG"r[;"o@a'@w93d@ @q㮐 vxm+ @Qmgh@IwDsrt!D>f+#Ĭ H9,A_A! |8 ĎBNJB@ #9cp]@7@ @Or|40qJэ. ď@BS2񋍈I`a\,zHM9p91, !%BNJF WtI!K` %XD!'A"Զrb$".C @r|TXrmnf @ T\BCg|D<%^^[(yH~9391- a%BNEm 䴁)tA! X -ؖB!'!"LG9hrȸ  g<( ”A/L\Id^&r~}BdAI| I rbPBBNO&H4T$%}B#r @@trc]VXrw2 $Qr~*}nJrĞDFyoX W=o9Ll ˒?=!^~4Y:%&/?6E hauv[l,Ya3pM`)'˜gd'ƭE䩳΃!97MG?8 DrU\>a'fĂ#Y Jqx @C!';N|]Jioq`s!@`@IDAT2$?p <*ֿ,(R5B,>Saks+%<‡@tyu r&E+C-|rSp+K`O̗.2O< w{*>?x2$on=͖3O$ȹ,2Y$O=_? @ @ ;rSgZ;RJQ} l+}9Ϫz0˝z}Ȇ"՚?"1kM 9/>lH*<2E& "DSVeYlXש$0} O/w6;t:۸C]J @=3,~a|xF4H߸_е P!@ @ rPŌ8CJk_21iB A=#| @)yX-hH{,93L jKyi BNJJJ]*L*D:KBwgϕl!g嚭O  iSn)ٓrZ݅| !'-5%p ̚1E>[.yV%Cβ?kJ@#QC @@b $t gVVwgYCD(w}CHr9ƙ"[.9yf"䌟]7-[튣)ˌt o;Y~BP1ޢ GtFge*d 92#;IilܲKyFB-7Mӿ fM c9ր%/.E/|LxrCŬL @ 91)ax#8_ oXMo71  D&KSL)wxxboRtם\~T*p@̻r y#P5dv`g @kh7#v!F~W[Z?!p!1]8 D Bբ$O@N?!'?yA @@ dOYwyi;tH }2p;$ ʱ%NGI`Z"rHHrg;^tJ~̤b_NZi!<˲dMU{wdՙ;4 VIBha2ljgjU\2N&8T~L23EH"Eľ@{{nku EM]>Gu~99oӷ9ZXbi$EO{jU$pӋޮU*M!P;ϭz*~뵍3ov4ZK |U } {㝿c>U <@K[slWͿ0j @ @ L*M݋1xYrcpT46 @o%8ߣ1Bԇ@Skg=zth>:-P\~r.\Ma4s,905.w-]o>(xv~GhY&zG3]ť+7JFJRlyζQ*]Fwf'}C<hmm7l|r%p7g+.6[Zu-7Xme-4W  @ @rl6Rwnɷc[1dFJ)-^La?to!P3EG\py8:;e'wǺI`^^:3[5"a6Ivf^]nZSrI`tt,s$cAa/@쮙uQ̘f!PWN^;NlE`;-Y4-۷Q @hl5b(rN"n|t4@%3Mt'ѶtsDSsRw ލؾ/ͽf38Aih$ W3[&iVC`zn߹;?8}<= U5*gNe}<fR`Ύ}188 7gW.ZYb9P6U)עkAWUO @ @r{6DCg~F:IEuf,x>:V/ږQjG \Ma_}# <9i?s=G}iݯBrݼ7/͏o&o%0##{ؑ~w,=" tZivS]Շyk%jŲk/sz[wã;F:Dq 46o7b[- @ @`rZxt{7F{Dycَ @(PjҌѶxSY8dj:]ߏxj,3{l_ \S7Gu7Ώ?X]M,pQ̖c!@K3 1sf7A*v7`VyK5@47Ǧ GG[4LK<__qB#4%6dž?|: @ P9U4b2ʣC1zX%3rP]7\|26l @@@Ss:F˼UѺts=[jU*P.G<H'}f)S;puH݁1f̱ `49NtW(͎bn@'bPM'b),ԃ!'bs!HG*3x<6r5xH4GSkgH?OK=2u 㬏Yqq#L9p?:J vT5hu7譸=xٕ1Cf⟭ﯛ S0Bn ·ŁßаYӾ՗hJK/YԓfYV,[*Kx8f]ݑfLqvHT@)\DXEH"wލ=kP uіGdh{. @ @@ TѮI(`FyVnJH=rd:QiM."@" O)A}Sskڻsn Kt1wy۬RKtZ; |{{/> |ó/Nyff'fW)/-?X/,lL{ǮSiQͺ:-0oؼiM{~e,M^`|t+WZ@wʞyckcђfM7Kǯ'>u:FmϷhmo>[XB @L@4t5Lpʕ@Nm""9հ״V q&f)M)}y^/-Lܺ(oqޗ*9_Zx5Oތ |MǓF(8k?I3㼺lVb[ԥx|z.HxU(.N=@+tYqݳ Č!Pzƾ'бqO(&FN@ƙ=+^zXmSa[!08|=q)3:-9+Pq[XB9M@T;K @ 9 u @i|#ʿt"3M;66;N8B9o}ր.jci\̉W 9-Nx]ccE(r=x"_CU*M 0}-1wnWeVukVĬfIaS%p3]Sqq;]lZ4@1Nϼذve}nyl}r8wB5>>XsvGWFh 9 q[ o:c̖Jg˓bΘfɱhD,9 Wwދ(fѱG^oK'ZwYpYq^(VXsR=-Lh^y;N Wv_%3B9 6}{{k eΈc cX0tC¡Kqr|Jܽbld"ԙ@sks3~+> Vm]8묧C @. S{P  @ i;"]̐S{*ZYsNcW\-X `z}(ݧ\r:EW.WWE/4QS'>L7k)RtlmYgzڣKQ~#"Sr.]7o݉3??c}(Q,I8z"K3qP/4@q,hIFw׬x" YҊc>tr-V@:ONJr7ʗg >cQqvz+'`LKkmĉ9$/Ny[aifmB}`:n rb`h(FS(/> kB9,0qu:/'ޥcA/fęّnљn--UVO"?0T h3 :+ǃq86Tno]/>?;'`~,(E{q,^9tvW:c-'M1sN)nwc8Y+ǃ" ?P'$rαO }W~/T|q_wⵖJǁ93*ab&Rx @T@N!#@ @U.[/W @ @ @ @ " ;Z7  @"[wT&isQB @ @ @ @+ R @ @ @ @ @ @$À @ @ @ @ @ @@@NR @ @ @ @ @ @9 @ @ @ @ @ @  , @ @ @ @ @ @r @ @ @ @ @ @9XJ  @ @ @ @ @ @ @ @ @ @ @ @2r2 @ @ @ @ @ @1 @ @ @ @ @ @dd`)%@ @ @ @ @ @ c  @ @ @ @ @ @RJ @ @ @ @ @ @@  @ @ @ @ @ @ !  @ @ @ @ @ @@1@ @ @ @ @ @ @ C@ 'K) @ @ @ @ @ @c @ @ @ @ @ @@@NR @ @ @ @ @ @9 @ @ @ @ @ @  , @ @ @ @ @ @r @ @ @ @ @ @9XJ  @ @ @ @ @ @ @ @ @ @ @ @2r2 @ @ @ @ @ @1 @ @ @ @ @ @dd`)%@ @ @ @ @ @ c  @ @ @ @ @ @RJ @ @ @ @ @ @@  @ @ @ @ @ @ !  @ @ @ @ @ @@1@ @ @ @ @ @ @ C@ 'K) @ @ @ @ @ @c @ @ @ @ @ @@@NR @ @ @ @ @ @9 @ @ @ @ @ @  , @ @ @ @ @ @r @ @ @ @ @ @9XJ  @ @ @ @ @ @ @ @ @ @ @ @2r2 @ @ @ @ @ @1 @ @ @ @ @ @dd`)%@ @ @ @ @ @ c  @ @ @ @ @ @RJ @ @ @ @ @ @@  @ @ @ @ @ @ !  @ @ @ @ @ @@1@ @ @ @ @ @ @ C@ 'K) @ @ @ @ @ @c @ @ @ @ @ @@@NR @ @ @ @ @ @9 @ @ @ @ @ @  , @ @ @ @ @ @r @ @ @ @ @ @9XJ  @ @ @ @ @ @ @ @ @ @ @ @2r2 @ @ @ @ @ @1 @ @ @ @ @ @dd`)%@ @ @ @ @ @ c  @ @ @ @ @ @RJ @ @ @ @ @ @@  @ @ @ @ @ @ !  @ @ @ @ @ @@1@ @ @ @ @ @ @ C@ 'K) @ @ @ @ @ @c @ @ @ @ @ @@@NR @ @ @ @ @ @9 @ @ @ @ @ @  , @ @ @ @ @ @r @ @ @ @ @ @9XJ  @ @ @ @ @ @ @ @ @ @ @ @2r2 @ @ @ @ @ @1 @ @ @ @ @ @dd`)%@ @ @ @ @ @ c  @ @ @ @ @ @RJ @ @ @ @ @ @@  @ @ @ @ @ @ !  @ @ @ @ @ @@1@ @ @ @ @ @ @ C@ 'K) @ @ @ @ @ @c @ @ @ @ @ @@@NR @ @ @ @ @ @9 @ @ @ @ @ @  , @ @ @ @ @ @r @ @ @ @ @ @9XJ  @ @ @ @ @ @ @ @ @ @ @ @2r2 @ @ @ @ @ @1 @ @ @ @ @ @dd`)%@ @ @ @ @ @ c  @ @ @ @ @ @RJ @ @ @ @ @ @@  @ @ @ @ @ @ !  @ @ @ @ @ @@1@ @ @ @ @ @ @ C@ 'K) @ @ @ @ @ @c @ @ @ @ @ @@@NR @ @ @ @ @ @9 @ @ @ @ @ @  , @ @ @ @ @ @r @ @ @ @ @ @9XJ  @ @ @ @ @ @ @ @ @ @ @ @2r2 @ @ @ @ @ @1 @ @ @ @ @ @dd`)%@ @ @ @ @ @ c  @ @ @ @ @ @RJ @ @ @ @ @ @@  @ @ @ @ @ @ !  @ @ @ @ @ @@1@ @ @ @ @ @ @ C@ 'K) @ @ @ @ @ @c @ @ @ @ @ @@@NR @ @ @ @ @ @9 @ @ @ @ @ @  , @ @ @ @ @ @r @ @ @ @ @ @9XJ  @ @ @ @ @ @ @ @ @ @ @ @2r2 @ @ @ @ @ @1 @ @ @ @ @ @dd`)%@ @ @ @ @ @ c  @ @ @ @ @ @RJ @ @ @ @ @ @@  @ @ @ @ @ @ !  @ @ @ @ @ @@1@ @ @ @ @ @ @ C@ 'K) @ @ @ @ @ @c @ @ @ @ @ @@@NR @ @ @ @ @ @9 @ @ @ @ @ @  , @ @ @ @ @ @r @ @ @ @ @ @9XJ  @ @ @ @ @ @ @ @ @ @ @ @2r2 @ @ @ @ @ @1 @ @ @ @ @ @dd`)%@ @ @ @ @ @ c  @ @ @ @ @ @RJ @ @ @ @ @ @@  @ @ @ @ @ @ !  @ @ @ @ @ @@1@ @ @ @ @ @ @ C@ 'K) @ @ @ @ @ @c @ @ @ @ @ @@@NR @ @ @ @ @ @9 @ @ @ @ @ @  , @ @ @ @ @ @r @ @ @ @ @ @9XJ  @ @ @ @ @ @ @ @ @ @ @ @2r2 @ @ @ @ @ @1 @ @VLIDAT @ @ @ @dd`)%@ @ @ @ @ @ c  @ @ @ @ @ @RJ @ @ @ @ @ @@  @ @ @ @ @ @ !  @ @ @ @ @ @@1@ @ @ @ @ @ @ C@ 'K) @ @ @ @ @ @c @ @ @ @ @ @@@NR @ @ @ @ @ @9 @ @ @ @ @ @  , @ @ @ @ @ @r @ @ @ @ @ @9XJ  @ @ @ @ @ @ @ @ @ @ @ @2r2 @ @ @ @ @ @1 @ @ @ @ @ @dszEHvRIENDB`faraday-2.10.0/docs/_media/overview.png000066400000000000000000007012231464273144400177410ustar00rootroot00000000000000PNG  IHDR g GiCCPICC ProfileHWXS[RIhH ҫZJ AĮ,El誈kdk]ky(ʺX&tos̽@'桺K e i,R@/cMh 嚋UB9$LARTVgJx22 R%VR%T*MRi<,g!m]%2A|Oqģ+1_d3sZTB˥yg;)bAɢ5þΝ4{%qCN,PCREd=jʗs`bW/,bS#$y1}f8 1\!h],'j8kep6dJӊdH]"JJUQ)kC̔&Fm0'vFHPoPǦf"4|PbՅ( n>O-B ;yG(3T@"$k: ߗҼx=NE*Vʋ5xP!\j~ BB1F,[qG| $A4$F$,B*UH5G~B#'Hry /(P CǠ(F)h6Z2 CwMI"zD0&f`ұ,LʱJkZ| z8g,(<\|)^ě5!އ& g?KH& * gMxC$D{|ӈ9Yĥ ĽbD"I8TH*#'&']%uޑdwr9,!/$Ww([?%"̤,lR.S)T==5D͡.VQg&hkUi:P=MD&e;Wt:ݎBOҗڣy5MWPtlu:SuJt*u\եrtysuktc-ۥw^>IN?\__U~cX38 >cc ۀh`o510cngoibXlXcx԰1\fs9s?&KF4:H#Q^FYƹ+&N&Lfl49c;`dHGf:&2jzɴ,LjY9<<|1 Ebq?X,6+U:4TXnlJZh5:zuux6 6Rl}mElھKޮ=׾ľ!ء#1q'ITtuv;opE7J2n- ۥȥh G7~>fLcΎ8nn/ݝ5=;MN~#i7~{8Ǎ[w?> j& Z4;0{uv(XT)s9Q9rKۛO?,їJNO7^O2~?zmb*oBf65;[Z:;z?8byǨJ /9BzdɮimwOMvzw}ңGw]~1q'OݟǤ?I gs Rľ/2~o -gn{g?~x20#c'O?d8B 7ʭzR@=_*=*x>F I;~2> pHYs%%IR$iTXtXML:com.adobe.xmp 3300 1024 (.iDOT(uL%@IDATx݇\}lEA,$*ز;Zd)OIȔdY988EboA@$+:b{H۝fg~s;2 @ @ @ @ @ @ 0%@Δ4"@ @ @ @ @ @ P1 @ @ @ @ @ @Ɂ) @ @ @ @ @ @s @ @ @ @ @ @@X @ @ @ @ @ @1 @ @ @ @ @ @Ɂ) @ @ @ @ @ @s @ @ @ @ @ @@X @ @ @ @ @ @1 @ @ @ @ @ @Ɂ) @ @ @ @ @ @s @ @ @ @ @ @@X @ @ @ @ @ @1 @ @ @ @ @ @Ɂ) @ @ @ @ @ @s @ @ @ @ @ @@X @ @ @ @ @ @1 @ @ @ @ @ @Ɂ) @ @ @ @ @ @s @ @ @ @ @ @@X @ @ @ @ @ @1 @ @ @ @ @ @Ɂ) @ @ @ @ @ @s @ @ @ @ @ @@X @ @ @ @ @ @1 @ @ @ @ @ @Ɂ) @ @ @ @ @ @s @ @ @ @ @ @@X @ @ @ @ @ @1 @ @ @ @ @ @Ɂ) @ @ @ @ @ @s @ @ @ @ @ @@X @ @ @ @ @ @1 @ @ @ @ @ @Ɂ) @ @ @ @ @ @s @ @ @ @ @ @@X @ @ @ @ @ @1 @ @ @ @ @ @Ɂ) @ @ @ @ @ @s @ @ @ @ @ @@X @ @ @ @ @ @1 @ @ @ @ @ @Ɂ) @ @ @ @ @ @s @ @ @ @ @ @@X @ @ @ @ @ @1 @ @ @ @ @ @Ɂ) @ @ @ @ @ @s @ @ @ @ @ @@X @ @ @ @ @ @1 @ @ @ @ @ @Ɂ) @ @ @ @ @ @s @ @ @ @ @ @@X @ @ @ @ @ @1 @ @ @ @ @ @Ɂ) @ @ @ @ @ @s @ @ @ @ @ @@X @ @ @ @ @ @1 @ @ @ @ @ @Ɂ) @ @ @ @ @ @s @ @ @ @ @ @@X @ @ @ @ @ @1 @ @ @ @ @ @Ɂ) @ @ @ @ @ @s @ @ @ @ @ @@X @ @ @ @ @ @1 @ @ @ @ @ @Ɂ) @ @ @ @ @ @s @ @ @ @ @ @@X @ @ @ @ @ @1 @ @ @ @ @ @Ɂ) @ @ @ @ @ @s @ @ @ @ @ @@X @ @ @ @ @ @1 @ @ @ @ @ @Ɂ) @ @ @ @ @ @s @ @ @ @ @ @@X @ @ @ @ @ @1 @ @ @ @ @ @Ɂ) @ @ @ @ @ @s @ @ @ @ @ @@X @ @ @ @ @ @1 @ @ @ @ @ @Ɂ) @ @ @ @ @ @s @ @ @ @ @ @@X @ @ @ @ @ @1 @ @ @ @ @ @Ɂ) @ @ @ @ @ @s @ @ @ @ @ @@X @ @ @ @ @ @1 @ @ @ @ @ @Ɂ) @ @ @ @ @ @s @ @ @ @ @ @@X @ @ @ @ @ @1 @ @ @ @ @ @Ɂ) @ @ @ @ @ @s @ @ @ @ @ @@X @ @ @ @ @ @1 @ @ @ @ @ @Ɂ) @ @ @ @ @ @s @ @ @ @ @ @@X @ @ @ @ @ @1 @ @ @ @ @ @Ɂ) @ @ @ @ @ @s @ @ @ @ @ @@X @ @ @ @ @ @1 @ @ @ @ @ @Ɂ) @ @ @ @ @ @s @ @ @ @ @ @@X @ @ @ @ @ @1 @ @ @ @ @ @Ɂ) @ @ @ @ @ @s @ @ @ @ @ @@X @ @ @ @ @ @1 @ @ @ @ @ @Ɂ) @ @ @ @ @ @s @ @ @ @ @ @@X @ @ @ @ @ @1 @ @ @ @ @ @Ɂ) @ @ @ @ @ @s @ @ @ @ @ @@X @ @ @ @ @ @1 @ @ @ @ @ @Ɂ) @ @ @ @ @ @s @ @ @ @ @ @@X @ @ @ @ @ @1 @ @ @ @ @ @Ɂ) @ @ @ @ @ @s @ @ @ @ @ @@X @ @ @ @ @ @1 @ @ @ @ @ @Ɂ) @ @ @ @ @ @s @ @ @ @ @ @@X @ @ @ @ @ @1 @ @ @ @ @ @Ɂ) @ @ @ @ @ @s @ @ @ @ @ @@X @ @ @ @ @ @1 @ @ @ @ @ @Ɂ) @ @ @ @ @ @s @ @ @ @ @ @@X @ @ @ @ @ @1 @ @ @ @ @ @Ɂ) @ @ @ @ @ @s @ @ @ @ @ @@X @ @ @ @ @ @1 @ @ @ @ @ @Ɂ) @ @ @ @ @ @s @ @ @ @ @ @@X @ @ @ @ @ @1 @ @ @ @ @ @Ɂ) @ @ @ @ @ @s @ @ @ @ @ @@X @ @ @ @ @ @1 @ @ @ @ @ @Ɂ) @ @ @ @ @ @s @ @ @ @ @ @@X @ @ @ @ @ @1 @ @ @ @ @ @Ɂ) @ @ @ @ @ @s @ @ @ @ @ @@X @ @ @ @ @΍DLNF5 @ @@  @ @ @ @ @ z=و-#z{V @hAT]"@ @ @ @ @@]ј(*쉸n}DOw]N @(@NGH} @ @ @ @(??kF[#6,Ju @ @@rFD @ @ @ @(@u+Ͽ.yהO @<9y%@ @ @ @ @@; \LNFtGl{F^ёB:6 @@N n @ @@&&chtLg\zdg"~NϿ׃2 tT*_zN?Wӿͧ:uu@GO;V6>)0>>#122#czz-8!ȮkAv1|(7.LA<_kBڐ\=YAE: dkkAzNc2|>]x.Mw2TF:m8-Ng׀\:] Zf HMGcd(?8=ck@v18-Hׅ~YT t,Gg͟Yf㣿t@O>wGgwgi0 d'델|vOĊձmX-ND @& 4ߩ  @ @&NOƻGXOcX<7)3Myw]d>'Pk&t,xrM}If9M7\E]0=|Nw ;Zx$0p<N~Ng١8144\9Mwu 9{eڪS%h] g?+5. 龭5?fgs̊Ƽ%$tLɓDz|xu  j@'Ÿ>.d;3_ :ҵz3Ǯ=Pk…kZ;6,0~3xr0y"N{*=gDZC1:<8)]R9{]6dPI H~N_̒5`Ѭ<椟筘 W/Y #md '+-]c|zw҅*V) @@NlƇcr\X7tZ馄mP/\~U )n>uY:[;?泎=Q>"{Hg @ @v)lxx⭳s1%olZ\ [gyqլzao t-> s)lޏW_'?VAH˲hqf+WN+Ň]."~sć;Gtxݣ1tn"-EkUҵ`E\84gG[kտ7=v,GƯ.hذ{mݹ:m\)]#lX '++icusĢy(T  @@N}}#1yTL;O19aL >g@re/0^6=l @.roL7?U8G9^U3+*}w^TzFGz~ATηo7F%@@ o<v:^>v.{6&Й=q9wX7zevl@`lly[ocw[Ѻ F^?)00,YV,쵍@;d7`N߼{ͷ?}GȂ9Y@kT9l5Kcoy5^ci^ݒSVYva\{Ƹ xJ+ؚ,p@NVւwD̟B @ȩ7I`rl~7Ə7͘:25iE 9WE缵ѹ`]t-צNZ>  @c#iCGyd<83FyіiĖו6-,0VCx#̳`#7`/Z8/o:ߴ6N_`#YqWƩϴpoukckbիLmOS`tx,yx+##숪 P;ݴ&nmjU]ã;Tnr-YVɩ1'c#@ @@ k&džb÷c샃11z䅘9ݮM'sWFU{ŎZxu _g @ Ρ#Oa3V1'@ZζqE}@t[)wtJcGѧx7lV_}bg{[ M'O})}p Rh-7mVi8cCGcT~u4DI"fǪbUߚ6vW dUN+q i; @ZQ@ G49gRl;J3(@3*z=+oI+欋J_ėcTI@ۭ_?1?=p<8ad+@WG%v_ݾ(])c#RY#O_~+&&R35X`ny]p5AuB <{9R9;TC(KJ9xC\{͚*JY P?z2^zw:HK tvu{ޯ.KDMr,gD@m6e @ !0>c'_Wɂ96 @Z9z7ޛVٙV˙_UI:xdO:! @wGܳq^ܷma,FU pxb{dt۞ -˷ݲ5֯]ҙcүHSe U ekUFlׂz;xcN9O3HcOlJ$3[?w}Z)昻lN*oRɮWF垽7DfB @DHa/Ћo=c  @@ t_}=i9]`lb2~tcjZ%FV/n[^3/z:} |Zt^?'O)K$Ύ؜Vȹ=r͝ݔ@=Uz@zz1 @wWWlM7޺kK̙=R}ә~~(8։sSռj go)YNbtڨ|.r]a  @ |揁 +01c_#o<96 @DuJo3+Hf4~XߗNF@Ś߼iq{>&PNC)| sbo { pe.-J 0VF{S0:'_!Sb/oJ7Z%# Dƻ  ""e__!@(ӳ1+1{yfxhss187uӒX:R LO1VǙvZ4M=oD M‰   } 6tAY_߹8 -5mؙW^};~x :;:bMǝ{GGF i=T.@bOvoI_6N?b3=  @ o_XjGi ˧O#gǦ} ;hW[vlE~L J@nv]ܕQy~6%x#koXC& laC gٳ\} Ї{hSykb}7@]@NVEQ戴]hR @ș 09>,?br 8% h;_D͍> @a‰N ;QtwVK7n\2}ґǞz>xh_d?'qʸ3r-'uNg,(uפkXpnijV( <ӧxA` ]=]+7iZkR3ZrV.ʧwGx}@_t  @[@ Ž_31(@ѿkѻb:LS gw8nž]?q}쨴;T`tt,y`<؁@+vcXn޲(K/|x_=~]P7 \neܱw[H߮o#PFxGO/HW3 T*8wmzڦZr2+rO Vm6:J @@r=~mUїb[Uu@w^or̠d񽧎p/u@}]K vz G8X]%^p\,jŒ}϶Xnܲ(/HΔ &TW9l@8G> ǧ_WEs{#c<= @h@Nŝo#)3{1viÎ @@*)g1~^S.S876?<~ZkBݵ/ 9s:/^xA @IDAT}/V(@{XLIg^#>.vG gf2 }x.Ia~TW3Bָ?}s QO[Q@NבtڵQֈkDtuN @ P^]U>|_bĠnuZw)_:O@k N??JY/3=A{5[١j /5'PJKmlMW.e& <{x s6]lXVK#3ׯ* P?x<3F )T9ف2V]@Nfѕ~w)Vɾ|e"j&@ .92ed{S ;19>Rި!г 9KSC@ b |~Ӽ9-#K >;rRMOe@9QBA2'rZڶ SQєO@9S҈9o 3Uۓ~׷mST>B9*x96 @P@ ;CCzhiۣף{ٶ ОCi?{<~J9p˴Bμ>+1/œx}gll&k6oM(/ 9 &\UW-^ ֯YB4Nr~DsKE)Ә9  @* 3U)*0~zobnjNN4^s?3 @?9p,: ܰ kIu (v @xɃQ#P'" a*¡׫'O7NFU֭^w5FC@C嫙@!nq={ QO[Ѩ@N9gVD V9bI @# SjJNN @vX9_kЎgZ\`b2r 9iֽz G^z2;vGrPW.M+lfl u]ukǝ)r@NQDF}ȹ_ '~+pO@NW@oUS#9YW̍mGT1b:w  @ 0u[iD/O4 &@!P[،;'* SW^o6@N 5D@ !NRg:;| |rZ~u9 @)ΟsMQٳ=bnZ5F @`pecWn RRoZKKg f. 3sCGh@Ns9C=1 L@ gf~n@N@i6#us|jWĮq$@ @r>UAF}&s}p*@GW53u; @Y9͒wVilϾurjgHi3@Nkc;B G_k% S+iV '+q|fOĎk#{s) @j/ S{SG;O9b @@*)s_ VT# 35@=*@NL)xfz9s 9$+w@ @ZB1.0vZ!g_rr @pBc@ p# f. 3sCG c]@ #f 4{9Ptvio 8Esr@NΎƩ{kի#: @@Nπbp_y$+@#7ߗ9ߪ!E)H9e=g9 )89;1\@ g憹P@NVtWZgC9k:; @ @`9ӷgF{&lY(@GwZ!'rv|(ȩc@N|[ uRO# wg@Nm=ro[96 &%u;bQgoĪe&8% @* Ӯ#_~ ?FWʕKT}[۾6Cٟ)ܐ(9%4%L@ c^- )(T9.^D@ "("S@ ''X-)7["V,b @+ \Hy| 睧 P @F Tzfr_ji i@NptO Y* SW^o@NerZvhۦc9m3:ZG:^E duؽ%*t*> @j* SSN@b'u %@ *PQ 羂V,L_@ gv$pA@ 炄 u]:f" 3=1 . STr0 E d fGnX8 0NI @@ ۈ9%8e @!(@NaFa%)`)9e&) LJ xpV R "/# s@j٬Yr뎈)c#@ @@rеȩ# @ mK@|^Z@'E.@NFLEi¨9q,]qQekĜ&9% @" .#]~ |Of 3< PxK SARer.CWȹ"%) )9MA@ g H@q9YZOz(8& @B $(@N)I @.9uauP " SPFrJ=|O9 )89;1\@ g憹P@N֩5+["oM; @ @J9Wy!r 1 @Mi  A;MK Erbu9uu 4ډZT@ E%Fuȩ\@NaeT>wk "z/' @ @`9@Kro @(9E u Pz:f ۈ^rZoL9vQG@ }ƺU{*Ӫ#_iG*K '+#r6=I0$@ @UrZud[_9-6CrҔ n\@r Ҙ 7J( SASrr 5@4B9i2r2δBܛVٰF89 @-/ Ciq  0هeYd"ڦ" 3%m\Z@ 6>)@NyJ)渨j9SҒr.%S(q^B9{#֬H+tȡ  @hvS | 0ٕ ~X /+ sY@4(@N I)(n 9S@҄rTz{"v^{D\QC1  @h#62wU ̣v 03ٛb {|TWr*/- si@T)@NGH}E)J9W9+ \٨- "nXH(  @@N{wi{+SڡS8@Ό  xpV B/! s o@4+@NGq%) )9!) L$ Dܲ-*wdAmm @i.ogr;v*'@3ș (@NGGme)HR9> LIb {|TW|⏑ // sy@Tjܦ쁜c[wD#̭1 @ .92%@NP @`93+))9%$%^V@ <>$pE+iP  - SQr +\B 'sY4?"r*n;RI @@ JrZe$of# SRiqr;6*@Ԝ"p)KxL9e-Q@ <9y%pqV dHE]D+ @ z97-#V"@SșFT@ B j83 iمK+ SڡSxAr 2ʘ@δH79hV-gvG.qD @@rJ?g$@ȹhVIh@N39Ptvio XgO㨮lTŒeywn LI ٿG$$$L&$$/}޻sKQݥ.f:ussea>!>9cH%Ӆ܇Mȱ%b=[dL P @" f-1#D0, pB[30guBNH3Wr"˸Q!L{9/B[9eh@B&Z9-C{D֯I%)!@ @ Z"/BNDϲ!@J!mBN:E!S+9^eܨ@ȉJýNpyO!{-o2z4 t!ar XLeb=vȚ"x2% @ $9AVcEȉpY: DBN j9N/f x#B!'"2rB`93r< Ӆ4U1(6RJ: @@if@W> I9\@ t8BN5!D+߬rϔ;O!̙1\r•(!'Yg&n-f!,?ٺVG,[8Q9,t @G!'z9r6 BN[02 S9>M aBNE  4B\@q%X@ $QٔBNS4\@rZFվar LZd-xXIJǏ @ @ M*ýpA 8 t9A B@ !3z r;dE@` 6u9>Ia̘BΌq#n@ȹso Y6]" :Ǘ @ @ L(BN!@ rV@ {Y_' t2sxI!K9Qr׈Bo x˗ѽ'=cf?.8*BA;WdV%2o  @3?gn@ȹ7 @ȉ\Y0"E!'Rf@,vBNP3QH 4[BNrN!Hr: BI! icΝ#r&2L @ B_3C\urpp@HB rr"r2dG t7BN%!D0,rڊ@! Й2trҨ 9"Z%ڽE_p@ @P9l@@ D O2( 9>IaBNGJ!m@ș?(K!'# 9̞B!BxX)sHo56n @G!'|9 rBV@hBNKBN@Gؾ"t  @`I0xX9MBOA3&3ctrnܛ 9Eb=ru"t3 @ K9L AM%3 @ȉNY)H!'Yg&ni9&|a#Fs=9;nd@wf .3Be="VS]HSB @~!L#G<\ BN y9h6@d@*~&$%B#3;~}9BNre!fXnH2х$0% @ 9~1LK!gZDt BNhS %6 ̞!#tBNw3{ ?@r%Y@z  rĨ 9y<&aXR)g2D `J@ @roBNK@%PEA  0{9g%]|9!+@a@`rfKM!`0@Br&8oW)rJ: @@ D*],BNpsG @ș-AL!!@ Jfdh@krZD/8Qyo{QJt)&Z&2*:B)h>tJd:J9# Tʱ޿;@ @ rBp,!'yd @ș )EJ; -"3&"A;J:?tG"!\dX_=,=ձ$xO`٢awYiz@@ z@ BNH2r< _@(=ժȑ")@TŒe[ !pc2˞tE^x5 X8fC`>tAYf@W 6.Ϟ,ЌɃK`eOFӟK3 ,HTҿ<FO];/d S9&r:5c{X)2n&D@ @rA1<'9b& BG)iuY&`X@Fue[ZN@ϼ%8OJ4A u#!"-&9af4ׂͼ@iKFgp@ G (gBNH2'b1u+TʹGdrD“i @pgVr\B9ӬT)_|SJgIRTsse@~#QFr<˰pG!/zCFTh  eXH!ǏY!&r? ,xr3"儈HE6&ևRΪs@ @ 49ϱԪ{ٯʕR+kU@ b eJ,=฾J{W-;b x2,@qNjhD!ڂD!'H"V?@cV-z9<8 匈G!9!RZgZRE"r @ x9Oa4rX;9x 4B[ )[G9~ 1%!PO!g# /'D@'#r&\0O\ @|O!)"@C! 8BaR%w'R:*&B@e9- LGRX;9x 4B[ )[G9~ 1%!PO!g# /'D4 ^w.i:s @3?gn@ȹ·o%(ZUJ'_W߂%0@5|BG)B,Bw FrQ-Hr-b#?f@qK'Sσ@ ^Έr"j`Ƚźoy@ BN rVZ Fg(KZqR"X^͠&_HJxͭ|L!əah937m9::B!#$rB,!'If@/wBN@3Mh 6YBNdRB=$!\sNvoUs8 @ @ \ʢ0BުSvZ G~'g(qdX)}$>gD+$ַHb>vTi(=Ur'S/Л.@ !KbDqǫ9-#$%]Ǝ d:D onYYg t3xK![~9qW N@eaSM"YϦa`@ @9pe6@i3PkUȩ\zGrѿ5 +=GJrvI.%*ĦVJ3"Bs6BZ쏐"(A[9eh@ȉFüJ0guBN'(3r&a' }91+Bc"֋dO @@; 䴓&cyF!3mB΍XɬV/ٍՊ9Ko4;~-{[R;؏@0 #OnDqCE_  xǖC!':JršY)9"<^@.cGBN5";3r:ÙY<$`Y"+ͷSN @@; 䴓&cyF!3m/BYP,3(5"uXϼiX:{@r~OJ^/ @FXrZE7xK![ 9sW첶N@eBׄ?rž!'9f@13tr,1r֯I&:0)S@ @%3[9"_Xqe ;_c?.B <! -}r\+#[F:+E kfYW t4xI!K9Qr׈@ gfV|RΊ%*p@ @%d9iŔKz}E8B#qDV̀X^i}엩S+V)TWVYj3}X 3=~̉GVɩV-TƤ싘۷zWX_ns{'uKny{'w=}܎hrA9 @5\I13qgzQtᰔg}Rnڡbo3>&CK,SԝwՉZwQOcg%/xoS/qa9G,Bw FrQ-Hr-b#?f@qK'Sσ@ ^Έr"jެ]z.Cma @ v@i'MBgh6?uݪBOZyU<#C?VP1B^~$P`nZ93J?ڒIuTq-V521it8s_5wAŅ5?I[vJ϶F G~+|{1BNvggךv1J'^߱e&ǎ-\4"Qo\*ٯ"Fl%0GLv$nQI,ڰ:MUNlsx6OSuIj||` w_+L; ;TrSnof8BNHN!g N!9ά"|Fq59Q:kn'vdn@y d2@ȉnYy 䴏%#@ȞbݿSdh @M!'r*? 9:K϶/t`igczJbpVܯœ;6֤r}V='+iᙢ-]T$޿D,^VqRj1*5FI. !))?sl6|Ճg9jVת*v/uϋVit 46rX;9x 4B[ )[G9~ 1%!PO!g# /'DfFĹwX.2 @ 9I8@qk~rR**ŎL5ܾҋc)xJCKf'b)=sZ+K˒? )k#ŊYve+?㡚X 'lJvEVՔs<2#>j1]?jGoi-S"܂$ 9!# wr7@iD @ RՏrbrK!-1CBN=΂G!'x9#b@_N D%[D{BmUPxIv㧧yؿ)/cIvS-PTI01NuzR]Ҫ>O=S;L=_$o;$%^\+TFOJRT| Wn7ykuܝObeO:c_8|dl-ܺr]=/Koc OG Hj^dWjzc?ص];tͶo̾4R+>xjrR)%ywK9E,Bw FrQ-Hr-b#?f@qK'Sσ@ ^Έr"@L+&*Ʉ2< @ ЌBN32B0 9 %9ARP9dVp.[P+`A4EiJ8Ig71ѦZM Q*M%iƏ%13*eQ>{PE-ϔ{l9aY])gSS|M)k,^Pjf'Vz@)i ׻r"#lUgN7?VǮ2fiMнIfRItNߕNn^3;_o5zS8[\BG@,Bw FrQ-Hr-b#?f@qK'Sσ@ ^Έr"x\+CZ)gRs@ tBNǑ3L ̄ZgiYQ9%wGZ5oPEpDVח~5KrVqM;WT _`?E&Ԥ|/rӊ*kRKz#ץqF(ozӳ+vǎ*H?ET,1se7}֖-t!'h'ֻ`BjYQ4mswEKgI֧$p'T?PQWZEi&Wr<BG` Eo4"ӈ mA"l 1+B[b@=zBNrF#㿜Q8[h="+-͞eP.f9K$9V\~W}_>t+8P⋶Դ^091T_U)9umz͊ݣIZ@r+ԗ$6~UfMjcFMeHV+8I,٨fk?T+MݸsDx"xK2,@qNjhD!ڂD!'H"V?@cV-z9<8 匈G!9!HD"# } @f@IDAT@ș ۪әhR+\Bg68劑2>Ti%ʥwT烙푬2wuk^=OaCFH-~$w3vyF_sٕU*"HEA7?񹫤tO+|K6#5ro1…Q<9g!g:BQr<˰pG!/zCFTh  eXH!ǏY!&r? ,xr3"儈:L'#kX-pRN3 @@ D;Y=BS{!Gei)xɮR+Ʌ[%)I.}GmDjZ JfZ 6/HæWi_X†o4Ͽ.>|qi_c IVzjj4#EAyBċw޸%K%Z*]k_V]c(41>RzVZER+- '_ԵO=\zǖqG<ҌϭxRd>)1Lv!{gXj3ÍKjk*;I:NR<7~{YߟZኘn9ݠ9E,Bw FrQ-Hr-b#?f@qK'Sσ@ ^Έr"^vo_+̟ۅ @$ͼn9O_bysDgI+Rrԕ(k8 J TӦT1PV4TF۶1y*d<)%&7Oy_S!sSc* s(BNwu|J7Lb>k ]Fz*%\~WgKYLu*Sb\xMc'NP9F,Bw FrQ-Hr-b#?f@qK'Sσ@ ^Έr"0ެ b=t @ m9`VTVșVBNҹZ꤫ߦFK5/[PJ'^j>+VL2k?6Q$nzw^;*Zb*uu'*Px.$1^$9p]Yp^[I[2?#bx%SLjjFЩ\>*kT2wU5_MU6UBdxQr<˰pG!/zCFTh  eXH!ǏY!&r? ,xr3"儈:H ϓܱVGv,_  @0r 4,h #*-J%%2xJu?nD/_|[.1͑^ ?ErOC3ӌ.ZzXަ7=k];Ӽq5YEg$ێrA(U9v!߲n$-1F2Z)l=ͮ~TFOsJWZꂾ.JM\ B !8E(9eX#!ЈBN#*BNE~$Ǭ[9nryp<9BrBD"f6="-ФL@ L&3}K!ǷXBNU/zYʗ޾y7NT6e$;_busZsKnUHBfGUlVs׭ձsZoO]uqSYii&G bvR%C]9{}q{*`d|N lmkfWɩ\yO*]EH:WٕtfS9!m2!ǣ!xa!B;^@#9$9ABBLn %F@ȩY /gD?9 u@J~ 8VL"c @ DBN"?w 9K\ G2EΕܕYIb@ِj^MZ$v d6|Rzw~Ӯrכ+׫tR,d6^HLM7l/41f#e7}ή4J腜@:WIҊT%$ 1UdSJgtV-IzWUygbBΌRr3mܥS])=zg$Svu!͎P 9?*f) Z~V(%9S|XjeD@ tBN39nhuoN (eJdn47ZHߑZj>V<%͟/7rTx7Ù[l}f[7_f˳nhEZ](ar9i*و%n^} '8iT)_|Sϥxƛvz!g*#xC2,@qNjhD!ڂD!'H"V?@cV-z9<8 匈G!9!"J8#zXeDR͟( @@șS@g^&G!G,KwH( ;J'_Rn2rS!jܧ˭ձ3B|?V+~uBΙۮw7c؜] iaX~JN 6I|R'2\ OtI!~lW˩U -݉@uB(]9eX#!ЈBN#*BNE~$Ǭ[9nryp<9BrBDad<K"0$ @ B[b `w5oڈKfJfQ}_ >۴]eVy5djTJ;MB5YUJ^"S*'._xC]6yy[hr.B.<)g,S)g$殖 sH,=GL|M>LV*ګRΏtVΙ@șP#x32,@qNjhD!ڂD!'H"V?@cV-z9<8 匈G!9!60:jъx3k)rjZEgVY*9#*hgU{r"BGiC,Bw FrQ-Hr-b#?f@qK'Sσ@ ^Έr"j#>LUw q` @A!s9#~rd*#Vj>cINW%>Y^;-(7մO/홈[fGS'v$fc4kO."mOIrѶf]օ#|qHh%rۊ^3rEbI-G +X*^T"8 E҆X;9x 4B[ )[G9~ 1%!PO!g# /'D&}wm;E iP @I!439m~r2k?&=;\C7B֔EbhVzyR=MԊcv܁gz)I/fm.5ݲ$*|Ů4@KBgW ʡbWUQf6bd̚;ӊ6]e%do{DMb%Ҏ#N(Îr"BGiC,Bw FrQ-Hr-b#?f@qK'Sσ@ ^Έr"jb=|Ȃ6  @rʘm'vmЏBNzCҳuD?iV!&kWKlx97S_R+6+=ǹʏ@UV7zW;RGڧ+N2Ҍcld7~R$p%!GG0{w+;$#nH]$f_;9??t=iZPLNG5wQ*DenTJ.!=*%ot[>wPIˎr"BGiC,Bw FrQ-Hr-b#?f@qK'Sσ@ ^Έr"%~zt%!@ / xIF!m(=ȏBhc*ȿ_*Rw*|Bz}ͱAr*g)T I.)ɑ]*To4TN>BdlO:J,%ɿ?_ʠP? ϒK`i 3|BN *WInfmI*d?qV;?Ҕ'iu\KR;oFrX;9x 4B[ )[G9~ 1%!PO!g# /'D4 ȆU*}>1 @B爙rA1($o4U7[_7ƛB{rϪ}j]%'+4҅mZII-@F0<g$ֿm/Jm3}cz% *Y4GBNt-Z(;tDS)(wM9]qnYҒ#tg>Qg30eĴ*SVO9fS柎ZYQҊ>MŷJo֤DsBۿW!۳b[ 㭃 ʄtBN3e .[BNR΂L!@+rICD!'DɌRr"xV9m`$L8*刅t07 @Z! %tBNS0mrޡBS\1rThv`y/ XnRV~Ê5Mojp,f.#E2sh*+㯪Hs@>sǗ$o4%ii7gRޛmQ 9FLUh>J8fW]L埙Ʌ[$U͢mުӝa?~lbIɨPe9B3?[*4M oJSg W*5;J_=uM[(Zq~ţV!ߥrc?.vBG9@,Bw FrQ-Hr-b#?f@qK'Sσ@ ^Έr"D\dV-eH)3[ @  xaK!<͏BNb& TXqɅwBηdQB"FV)y?'R6Wͺ6m)1 3;UR02ѾҰ{2?aWJZMiY~#Fi8t] [&2зr*$ґ%͙ޗJl|BN~B:>7?iXӫt5RHg5'WmZf:ٍV"*5;LeߑʥwucA[lc?Sr@(9eX#!ЈBN#*Bloؗ._'K,d2p 七w!' Yr_V9,0ͲEb=2ζu"R @ 9HA"R^?!pxCGR勒^AǪ!¨OC oJߔZ98䋶3N2>)w,KoxeObD0q G~Z*N^DX|[:h'iij 9v; ?.9!-$IHDBtbNbd6Ӣ?E{l|WR]a5#xa!B;^@#9$9[Ly^jFo^zMחO"CI"cVrg;^Q荐,{9/ pf3`H[D&aH@ @K9^e@iJc*%IЊ66==m3Dwd7|®b*{85}=r>c,$"8Y|hu-ZC/rHkC)|9W 6)'J$b~3a9J')JpU-df+#Fڈ Dy&4S/*Lՠ춯Jb趩rn8?;L![(lakˈ*s$?"I7x>~F1fv~owAIz+hɍ֦_ [Se|)_xˮbc1[fuĕ{RMF6 N/FWqV̚Kώs97{r-)@gĢ#X}iް?#{2,@qNjhD!ڂD!]x(FȉBÿFw9g;^Q荐,{9/ pf"l` @&5ao `t_ 9˴Îk74cdr$k/Jj.7Ǫդ,&ezT#\cenJ>WKO[a*$-_PaA\12E)rʹ "٫2ƭӨxD>F1U[~ĎcJ O`Q;MO%kNv#e8Uq+rCoBhxJ5,7ޮ.3UTQ J| VDZ76SѪ;?=-I*o=:kĥ[:/GW x!# wr7@iD @q-v+ r!]YWz#D!^#BN:C!3źw}Z Xs@ @$̼E.jܗBNb[I!GBFInwUPPq`Cł]*|VCkZ v5KK_J_j+2Y1-Mv olZp#'>n}JEN %l'hc9FLɿ?Rx[?IdD n:}Ts5_œyaħ'zLk}9gjX;9x 4B[ a9Qr׈.,p+ rp!'eu!FszڽE~6P @@ t8͈BΌu&? 9Kv (mt}uS5%xdB7Ra1\UR);[}7:j!& 17VK+Z珒\Y2>8+!GG2yͬW{\SaG1kcE 9f{UnV<%II9̡Z}֖qLe(7 OqJG39rfB͛{r*9eX#!ЈBN#*Bl;^Q荐,9rw!' Yr_V9,m"Ы~kX%hM2  @ -9"ϼ Օ~r8)*GܑKY=-c;N P1cW/3SzL G~'E\T IbjIk̩e{TnVQ9)9 C?*D}N 9&m:ZGTJ7*R1ғVc)k[B5On'JFF*[rq\+v.7)^C_-KeY}ˢIg/i z9GiD;m9qG,Bw FrQ-HreBo(d9kDqc~9Qr׈@ gfilFdZ[d٢6  @@ t;0u$au*;F ϵ2H4طԪTX&b%gVn\sb.J'_Z-7X3")^i՜YW=V:~Ne}@a*2<rIJ^I--ىEO;ѿJ5P1yWϩYk%a[%ַXMsCjT.%j rU;Yqd.ļ۵2MGn2,y&%I}___RrU쯥J!ЄBN04BT;^Q荐,9rw!' Yr_V9,$NlMGv^: @ d8 8E 9F%i9qcqpMB*WNHY{w "wj* iuA1[ -OP*Uu+WI_T9Z>ӓzQ7=>bNV27cqv;dV+ZZYog3sZΎ9޿hB?*+{W{R.#Z x!# w"h1͢ &d~OBIɒឤJ:~O*䜼ZWrL_GKrq,gJr~,EV B>~&.;\"+8ddp_+~ !5N7wg;^Q荐,{9/ pfHs"ZzL[x~xdK@ tBNa3 ̜wvT ]=QEK%+Bc$!吪V\9):j+UZj9=BYsTĩT(ڢB5SBMP*;)HEF20$nAS|m|wi܇&]`AT.#H8kEόu]@3ҙ]UKlJM\Vf@! G/.Rl<_B!$4BN \K-t*)sT™p̟+K̗5rL!Ɖ^&? Z]2rg t3BNZ.qp@ @#rE9L+ 99! 9e!# w&\3x 铘1[tT*Uy_mӈ!'rm~/_9 #!ЈBN#*uXs @/6T+C U:YLD D$, d2,3'!;Fz=bwD6Ή+EۣףrL+ :@aB3ٙJ8}244G/'KU;GC:ժr2:&/ko+G9ѮC;BNhS!?,wrB LG%04 };D.@ BN!&,$Br"l  x\ R_«幗/D,~㌯@XwmyN? @:O!̙qrf[ e9]NC DrBLBx$?wAs\a0WϑoЇSѧGU93VWrbA^.ђ+ɸ8ntV1",Lׅ}Ivv5'ErqǾr|ޮԟk%ƹ;,t+ *Ͽx~u A;HH__֖peɢyү+LuvbYFk5krN%˩3-'R,Y CV.[4 > p荣ڕ|N$CgAӾr"`J/?xQ?uC`v}jٽO+dd ogN?*?z-6Dž@ on2e:?J8}24_-gK8*$J*c9n¥VùxyT* ߙr"kBNfۓ%rjBN fr!gnZoX%֣*ܾC @ B_3C\urpp@@ D 4$ 0Crg Wx_g4hH0gR̤Dr%yl<3q<>g^^9>Ϟqx<Gٲ%+1%Q ȱo5M ``Wo=Uo)_z@Yg5h-ݞoOR??hn{wܶz4`wq\?6)k6o V8[9\;"XLI55榙"m˚_&Lgpx\#T2.R/4TWmrJ[1 TBC!r \)Ozm}t`PD@@8MW ߎ3(r/ 㾚2#xG@Np޻3=ޢ ߄du{2\MW&3P'GzĬMYo{Fued~b9..GF 4NCLզEpeeE IMY!ȄzF4b/,j[ѠqU)MƵ[%SUaLvX KIz=4bV1a#{$4  +@ rkV YKD@Na"PrH p:)o{vkXK E=m8}kJXm6C[c&m,wY\ʌZ)gʼfڭ3%S0V1SkK;[m8 WYۻYLLgNi &gV±Vę_A@NirWųTSzrSa*^Lfk 㜕f6@@ϖ&N hs S,IAJp2cX>Q;Ѣƚ? +KzƴRƹ[HЧ{bfoʗ +í<"@ #v4 V܀ymmmM&tW NSca]~xyB?2Q1+;ШY)牽 zʄrisؼ!@ uv, دϤ25a‰e7nS[KE&^&'g5:>LgrzFE"TDDrr-o3丹ޘoԙYV@Ni}m݋)Q-=zFzKN@@oջjgK jK=, ١!@IDAT*qD*Tj%6=@r[{f O@[46gޚ?b畴;_?Ь`NMП5fFuex>3vS@;YȱWx}:[֔Y ÄqjxҒf495) Ψj8iYUʫ #/@ Ǟ{^^8@9qw}3rq^Ӌ9q){5>A@@L{r~@Bǹ PNrЂȉEY,-fU?ܜQ5qYOkZ%'mP|%4*O%WӘTSzrSxӇ#'7> OVVV4&31!&̱9PP{\ yyh9^H evqyM/^ c;*Ԓ;5.A@@ \ɫsrn@b)"m @ 8MG;k(z'YQ?ޘwӗNiWs$kL 絑>9fD ^ ,&S&3䌆G&gV0+pͰW9@NԂ/@ Ǟ{^^8@9qw}3rq^ӋW91;Ӈ{e o@@@K@?U!@ * @((To|z:cƌj+7&>>{EOkVki6G99BqX ȱW|nN̜S3pF504yY! ScwIZ` GB=G9/sF@3kzB F:_z:L7   ]9w%^r*< @ ))/#@ |s{U BzY߿4aVUrnH}&}Dj5I.;;丳^{ն{ֵ7o4 肾򨞽5Y58]/lhpyBOJU?Ya}ܗ*\@ٽ {u8ӳШF&3N*^}(H@Nn(@ gCu?Z.wt]1y9(#(2PPڽU0]=*4]"  @ ȩ1;rI@@r[{f~k'wg^_+sYUÎmQ}dIJ%F4;%@ ]lثz!7aiiɄs&ggVɄsƧ4eVΙW*M8gU&Sb|Ecc;rIv9^A_ rP7riGYt<*/,]"  @ ȩytr{F_5kjv4E-z߮xu}*Ne}w qW=89~`69qP :/tzIИ&4i9s>cl9]Fܜŵ ȹ+j Scܕ$@ p[ BO <$;Z) @@A@NHR~9#@@\r%O 6DEO֔~ִN&>x>!k4a#3&>c丫^ {UCjmiTOw:ۛXo91Ek|[hkuqȹxp[ ȩ0"rq-兣 x#wח9#@ 5)c>ULa)^3U    L*F@NŔ  p"VRW [iMMjnnAK˄s\q$S\OZ+ݹo3 丩ޜ o֝YW@Nq=sj-+c~{tdVeC@@ȱűe S6z:F@r^%p"PPSmPwfͤWL Ysݍ 97չOքر iJ^(keXT]bhҤ w`ZX\Lid,aVȄ&sL8(6B '_9Ϋ$9WkAjcs@r 7݂[9- 2H    ~B@NUA" P9%aQ'9ѐ_;ٓ5fFuex>jqV_8٪YS{tu5!vl(@ gC>9-T WCC 799(7r峂8>)5ŋCc   9ީuUϔ@NU# P8*\@N`/_/=V/O|Roߵ=/jӎHրڤˆ&Y]rUO/Ά@N WOw:;bni0hMD~q9s s9# ML ,,$B8t}e9Xz䔮v\ Jg[I-ȩj0|9 Ñw1>    ;丳ו ! 8P@]@N86cckUm>ݦq[?ՉL g>3޸O@jq5 6=m0ߛSpkτW ݬ܂78ф2+jq1E8PM' UgJŵrB YL9Ԥ- )C9SNJ]meK@@p7Us!25@#@ >@|U-d 盟ޭXhWjiE?4Ur,œmYA#+WF k qaQ=6%9֨%ikmRcCLX|Gfsff504?s&f553dZ9'ߖ9o=9며8[1z;'飔rJK^ SJWk 'jV[?OJ:G   69nKC ǥeZ  @ '$Ap2>MǺjpkF_}qD>= a}xӐ5̾ʘ~dgpk3"SMZ%U[ZҨxL1`0P- K XTQz#r)_Ͼ=)&mC@N9mrPj Uruh|Ov.@@@rXUΉ@ ʔ@Q@NPU)d }w>/;20?^ϮM*m q}DW3084sU0XB9r];55̪9hQKsut~QYΨF&3pN*.J^l@9ȩr-:3 9qN% ȩj0j SU[ Zwv>`VٿCMdC@@ @ 4Qz97@*U@NVq!@1 X|X037MeDUṈ}h_cMHѯޜߛUYybXā)"&ME@NY74lni5+ѬL8'Z1םMå%ΙQpLXgfvp&n}D g=Uʫׂʫf#"Ujct9eP5rUpw0YnH(:]"  @ ȩ0l9&A@+rRi所7 X+|T0˽lZ?<\Mh.|>`n~z}d66\.UƔZ&[rlqqp ȩlo֖6u5^YUzN/ibrڬcs46a9S&37/3lç!@ ĵc@N׈n.@ gs>E 9(j ̪ۺ{¬slds@@@" )"&MN@Nli@J Sb| PMYwg|/;&R߬d$bB8Om{tb?R\7^g ) V**C]W@κ,Z'VUwgtQc Eo*ĴY9gDWޡֆ丵ޚ7ׂʭʭ #M@NnNfr6)gȱV.I'JfE\6@@@r-J{% SVE@*TE$)d 'Cjf?p žL(ʰy"5 ڬMW}Xߠ'46gkҨ4zRJ9ԥm'8\>憞L0U j0᜺klW߽9@gJȩr-ȩz0rq ȹWā1֐yJ> p@@@R)*m]@NIi@ S5b kx{[ky9-hS~^]|jyiqz8ߨXƱ48ҷϏꧯM:=D+2uQlA57ݦxj' @NnNUr*>ׂ s97 )/{C@N\Ɂk&wZ:wL2+޲!P1++ZI/ie1;yȘG#se}_u>c6@V֪;M>w۟ͪHX~E/81O@9qcr#@*N@Nŕ!@*9&c믒cMZeм~z-W4>ͧӶTФq5许#<\ZoO@Θz' ScD[3ᜎf57+n95fT6J '7099qTe ȩ;Z;@N,i<rN SzVr 9.߻OJ̊lU$gĔf-Ok󵼰 --kѲ<0_wUhs@ zzB5/kߝw/V`֗ 447gvƆ丩. ! p9cj9ƈ>yYUOfZ1gus"Ăڐ_P&z5ԅ57W;3f gxg#ZurU6jVW[c$6{dVjS{[cPc @z*dث{^^8@9qw}3rq^KrbYܰfȼAQB8A%o)y| *?;8: :C@<VH'hV/ t)K[֭`Gkf^(zZraQbzY@T_N2_!2.@ orr%uohgT6l)̍E=w{FWG45:Zx⒞?_הy-9ުgK ^U;TƣPSKKNv69i͉*[@p-兣 x#wח9#@ 5Tb < C> ߣg5  q >-\/ ΀VRidž@G TZN==~H5w*&$\CflW@}8RC5J 0@pPf8ѣ`t8#P@5pwSZ)i:>m:j8oUh[TTR&3Z\:uL31mmgy61X8k ;](@ DžEؔ+Ӈ#'TGɭprrs c>\ yyh9^H evqyM/ȱV=q@*opJ`y~!B8sϟWVV~@*@}jUC5kU5]9w%^5g9=N %=)d/qD+P@5놚G6DŽ_99lVfф`&O7o&5iYa/nSG,SS̈́qY!rN|ycRrr,x$wr<ШrVs) #Iޝk;Ҋ./O3*=y/@ 5` ȱMp4/Ts$c\ yyh9^H evqyM/ȱnxȾ&Ʉ\)@ ǕeuߤR/rUM! > 2/o~"U(P)tMѠNnӹm1ZNZks,%_L756;l{\@\0}9Mp4/Ts$c\ yyh9^H evqyM/ X᛭=~V:_VaCaE>?7@p/V 5~/މ23W qU9;˚?u/w @ 96O@bJ X>錅֘v֪+R{]H2^1n&88fu˼N[plY@? .@ ^ ۞&*r՘k=//M Uv 主98\]m=tdndCqe_yS! nc?| n.s SH]o(5@@`/X+sp@%rZƚDt=]`NsbzYПY=G㇛1m'Mi`:r8wUrVa*+7arPeϑ@s-兣 x#wח9#@ 5#cҺYGHgHњ5C N ǔhJ2T ۺ3>%_0੹3 S}5ӣWdߟ<9& |zE^ooh XaɤisIKN"jsr:ulWҋ_;7l9YSسZ` GB=G9/sF@3kz)G Qu\ծopJ`%3k~ШS ;{BMO=pOόJ@NU˻] R3E` xT_b9QF7 TK gL |3%Xf='^@N顴rת1wR===L޹aqΚJ'@ Ǟ-{^^8@9qw}3rq^ӋӁz9!Yڽ~PxAM|栗NvK_ xR ҤƏ=_۬9Q'Ϗri_7  5@|G?Ȯǽ6u@D@Nan(@ gC>@ '991qP ȩ1 S%b s >F 99 '9:{F2!P6eMOJmt g|>uJ͟+<3m&Z}rf/}G W~3i@,lޣ)a/30wpi9*@ Qn:+Ҥxܮ,ז9$@ !h){5Abr #@ ?Nrꢦ{Rgk&J#dV2N|gJ< ik;2B@tmj3B&@ 0?vH`%oCt @E:*z !n 㶊2r):}S@N15iˋrXu͙@jʌ 7_@=]nWN ^D_BS#3Jͧ5Ѯ S:ȉHC2L.X+p&/{x %G#j'7/(Y?4@!r \V8?4ZYJ:/]! @qjO|QƝ #E StReS&㲂28NN% STOە%cg:ÚV~5J Li619rPRr"a=~VS %3ϾoXك %?QJ #PB8Qa9_ܨ W /L ?m.@(Ҥx䮛0ו 9,@ ap+Ҩx.*{9G>ZgƘnAߞдf䔡 C=a8K>_&H#ĿJVy=:E@cGTWIq 9.{^s/M@@L?a9_l !  XP,Pؼ>scCL$tkoP9sJ8]v7hWTڣj eVɇ `Υy]׍E ͤdÆ@Kv%@ \9nA g )ܐ+@ Ǟ.-.LG1[4xmX ML+5Z}\@N X@/Y)*ä^Ds/A| %6l鿔|Xd-H@NA|JzQ ~Osf- @B]'T{ .(@rUpNtLOը>RZ⌛r.Y]0߇fZ6!PB9r]v9^Ao  cv9w[_6V~^1%'52T 䔡t X7Uv؃ҙp&Dl.0M|i 6?O@@$ O_-p&@ *x6X 󤁯hyvd@\ +=Ek[\0!d TB 'n7J80N̬cDXms~sZ|sJ5br{i9('I erq.J.@ tr9./G ^ 21nV!ߞf%j^)Cȱp,ߣsGh&C_`9@.5 NJ6 "PB9Q7+$o=ht  X!OfGr9# pG܁{F~VwN.-м~ڤ^䂷VAmR iV)79ԥm'SnwRNJLhzfnuyo%f4>1+@ ߫Y@q-兣 x#{-F MZ!ʠn_#0̌*,3/"@ ()V Aw9!썁pP`/h[?VjH;NW -PjGli|{/9R ƑJz,_,8@j0pC{qIֺ>Qߠ6)vcbQ?$s8 T@9рӠlRg}n|jYJ+mvZ| }﹯l؂wq\59ӾOmߝiT?4\ҹ))/; @ Ӈ#ɹY<%ƺ#=}g c^կ~Һ9Xzث{^^8@9ȱW߃٧N)W4^#_ |^YԐY-> ^xoBJΧ  ;ȩ#HM+*T`j?RHWh ΝT[:\>SWrjRJɛokiL@ Qw>R}dF *rrjM`=fOiֶȪdLN̥5<ָ>4Ҩy=\|zYi1xM@͊;͵fEϫ΅1;++@Nq+L {܄m GB?G9j̵&*{rշ!}9ܥ=mjj0zET֣cY+LLz/kQ%'5;1e1 SZȩJ'2 ./0ߙ@dVEfC@UY \7\6a+ JjzqiS07>X+hP{T׎ZL@ǿM&̍}QJ,ݖ[_)ne ד֜ cϜyyh9^H ^rPewϑ@N~VƉԩ@G&ӶU ]qշ &g9[f՜=)-$b=qro 'jud|wat@~S[@|~ p $P{?Evn-NFrJJ,%nhr~Ԝ#}  PWiFvF @e8ȱ2}Y;ܔYf=Ʌ%]M@Yq݂ƈxHmm1nQ4_1?_WZpF #N9yqbȱWn¶兣 x#{5Z` GB=G9oVnn0tRNhQcg< FwMirn_#Khf̬Vwkr|F> )=HYp hQɟZcVP1Ga @jOٽ=38 8gMOEXQz |O?i%Ph@0+&{TszLPC  P^'95gM(s'ZcݬxMJ51b=3eV3+#&5J!w?a@ν?}'Sg_@p=//M Uv ث1{^^8@9)n}᠚49ۚLX'ZBvd*4^]ԨYAgr`JZ~Ǩn 'd~'w|0a; VS^!PY? @+Te  dVȩٻ#3f$@ XV+?Tj󏞙c؃ -0 _HCe!Ep2lB0>ڬjR\s68O&k M/qQok gθ57@&3|]J8)xQryyh9^H ^rPewϑ@N u{pNvhVcw"uf"o3zsDiڰ{'45<7nzRڝv9A[sd_(L`_~y'b5$9@jTSOf,J(@ 4퐀 ^?SE-K+y̡  c Ud {fL NXWm~pq~FJǤ}H^h(3+|QL,f-;דN[]H]Lix&B [0'nrJKӎȱMp4/Ts$c\ yyh9^H ǙG:rd_MΨRz/kf՜YY+강F@Ni\7m5@Nxk 㜕믞i_|@L>;4U@9 G)B9,O@Nŗ*<7??hi⺖&L0es8@kV";ޫ`Y) 𚀓oЗNZ)g6B0zeL7& 6:bBBno/ꛯoMk7ԮC&Ğ>~Y{EJ__Kžق>GLh{c$-9Y$@ K@Nɦ;٫sgozL%|8==Ͽ&&#v>2Ǜ_kruξUrVaj+{^^8@9qZ/<HŴnUszuHc&498%k5e(j 3r X+wCCR8AuQ_ _h?0ψ&Sj0@/ rs ȩ1<i-MsRC2`) DUK*NxC&sĬ/I_4T{M|%+;ԷϏ?ޘtfekOmQܬzK-{3V9&=+|͗G"SZ5V9Y$@ K@Nɦ;:ښն1a2ƧN[kt^- U%@ ^rPewϑ@s_ Ǫ Մa*W\s9 6[4ƈtҦ?nhrGvG?zFz~>92 )#>]# `cPr*:-o VE-nVIh%9e󵒜JjބtX:o`ND@>!±;_z̪8j?d8 m@ 8ߢwm_Cj7'G54ZYX|ެsjK]VW?}R_yqDܐcs`@.]%@ UdxLHrI3e 9f5[e[:k6 }L!#^J/+10 }< O+3?9eN7-?~ NKKhp&"x+y(ta xL@ ^e%Sec62+9-ύhivX3CZ5_sfY8')Uu<zβЙ]io7_tfp@W'XYOK}ZI 2@<*=vPO=<*+Y@N%WNpVZNsҋ&pc^`lrݯ?79rJWZFL+7G&'Y˼g6pݝUq\6@  ?ߡ5kb^򨞽9fo ·7˧dsVh@IDAToFuqpnn^!@ '4NAa9ӝ丮OIQ@N1i,rc5s޷Ed mWӖ95q`2qb~I8=:Y1~\ͬ3;1+1]M^Tmȉ;wTz)< qI! @ Ԛ@NS1U;^9-3C@@p'9_.ukD^5+ьHyVyx{tU;;Ցyf8!@ ep7W;s#Z3)+:'@ 9|9Ggӱ=iݦni Yzyv^5nV_KvNrP9ZaFh)à )--# \8\r%O   p2ݿݣhp37UȹHԛu nĢʘ~s}j~ cߌ3pZ@69n7C Ǜug S?\*UVrjL큽=~V]Nh  S9`$  ͺWˬ TK'    |3{RvߴV"M9[Sm:fj>nVyyT >l )̏pB@ʛepesa^Y1f*9UU. `͵AtE 4KY=@(2te[:kS0A95d6)=qNڻ]2fCrXU PMrZ+՜#  T]i0O*\?4KC:=;L q]ό녾YҞ临LUrJ_NIۄ BQh4HX`P$@ 9%KZZZ|i/,jvnA)Y.`dPrJ_7.grʩO S (u g(B5A5omRסpNmcAC7|M gCd~y7Ү>`8wI~8r )<" pG@? ,@ @@@\-d m]M27_ӯO94}@xU'ZA2(arJKI@N iƺ 44ԩ>xbjj7TSQ؄tA+s!ku+JL $&g4:>Ĵg45=nv*C@NeԁQ&@ 0Zq_M6#9U@YEjj9]vG;U]}Ⱥ ˲N9범v/ʋW{ttdz丹 @TC;F9ޭ=3G@@(m:Ufeq}RK+k>+ֺ>sUu1go/-b+L@Na~rlzUKS\ndV)d2i VﰆG5i9֊:l S^z/8mk] |'Zurl9HP󰀮Ge[}'N Do@ m ^z]5+/ se S&xE@rQd9\Ɔ   j'9ۣ[]Yޜ߿8_uN 'Zu}@-]Kd41/; ȱC@Nkuwj׎neVÉ/zrn[72ɩ-u#@ uYqbz2c [Ӻ24)DṈ{OQ-z]f~ `"@ >{MMX'ˬj`yy٬^d2T*Z2PO0P(4_{(yo=Ζ^Zҥ+o]S96O9yqZE ȱ_|7Ws#\s \2:5tղ٬ӥw(+pS J Lj/d8V(g) z""2*\@N!^@K\$Sc   ,t DzZܶغ+7>fu}|AKJ,,i6inbN(eoj#s HЯH@&VNvjKC8sݶ>Z_?]Lޏy_8؃z#ٚz57)M܂f͗zL51(n+G#EU37Tks\gJޒ7[i֗֝ cϙk=//M Uv 8Wr֫lR];2AB?&ߑ'SxoB^ >Vה@Nr U@(ҸjqǑV@@@-`ݣ c/>7̙:}ڄr՘6Ygqz'SkQ#iYI/k+ tBUqòV߶`xoN5aKCs;m ȱ A@=XΞ:eV쥥ekd,a]9QڟfsZզ6u5gB:];͊;_gpAS3t1)S+F@Rp-兣 x#{@R i" FEزlbNI\Uկ)̱Va+L@Na~ s#@@rJKۅ )T@@@SkOo\WLV'Y|Ҋ. ?/@ g}"PIrUc-zϹhDkQeB8oDg.tMڻGvo5&Bߜ7:>?wQ`[i֗֝ cϙk=//M Uv 8Wr= f)ݞ!27V.7bj'@ g=! ɾf   @Qȱ_kVyz}P7F 䙪Sb>+ѫzwVK< 4OO#"P rrB שc٣C8=3'ސ)]'v= ot*/]<6 ٔD@NZ$jsrJ_WWM}ѩӶ=%4LkflV} 9eP]*x9]+@ @(knrrs(@@@.P@5:9]'6PGTHsAkq^6+ 9)82=Q% ;mc<|@سI8_}S/]ɩ k=tꐬ<{ތc&8/99 qH ɽD\ rґrTmwΕ@Nij{$V^M jӦGcojbwb~5?΍1: LMh<rJK @ )?o.@ gs>E@@@dXv7G؞YRD̙n'zִ~}}ZSɒ9$ PrruSOWۺ'imK{L1vZ7ޥw=xD[Ze_o7n\cI@N irrZ$jsr[pmXm15vնU[w@b-u{!#75[{5 ism ȱ  `[@m2N@@rIcE SdPC@@@ WJkS4ݵ:NL@>YA~8ɤ[sguihN<4_R[ȱE@N>xnݓF&.7ny1wBiV9w֬ؤ~E]yƺ8rH+ ?ׂܭt$/U۝s%Sx]C`&pՠ>iQ/_x^\b^}kT׀&d Zř/ @ ȩ0rVk@@@*)swH@ۣ:]MaYA\Vαn9X47%L.,eҙ ΋}zs|Q qR;q}pSf%p$[99g6%\LX~ϵawa ^aa'5IiQΩ[{ͨ-Mԡ]OwW:u"gՉ>׫K.ݬFk⿐o׺/{Y-& 6^$I@}ͣUPwĄ|fEرdQڡ$쾷oP'M 39rH/ cߟ{}+?$j{srV@("/*SJ-ٴHK-V Yǒ?z_]j4NNY5dˬsu @ Uf n 069|@@@Ȑ9VfAIH++<_KB0kz(hV'2La3y1a±Vi=cB9uIt>/45\ZثZ+{x<ș 0E@WzԯO掿R_`n2/&@ VE{ؤN]U[GjzN-ZPcgWNwcG$ϒ2'@ Ǟ={N~lE ǏU֜ 8g9Vϓ^?T'jD}Va9Q'F@6 1v@/B;9ޭ-3C@@p,?P >30:>HF '9ެV 75W~Ihvf9VS'\56 I-=O@}kԒ@͹qVפrLfthTOحOpY:46v6 ZB@+ O!d,(H g    Y 9ިgA ~wm[7Vaa~I m:a9MO㎥rǦ+],̃Zwx}2=9 ͽZS9W9:@xx\nQÎJ8Onc h:9+ Bsr."  G@{jHW@N֎? cq~٩;{tuY_jOז[ )**Ą.]q9ƛ I'eF@}wԒ@͹qVWgp#iUg}nU8V@rQGf丹: @rP##G@@r9Y^@ 9(xTءZfYIV:s"| ?Om5-9Sa:Cޝ) TL [%?Uۛs%㬮v9k@t5ֺv5N뽧qvAZg(D du< x!  [ !-. Čn,LO~`~0WEAUU@97qk c0 =K?9YZ8B@ W0n`rss=lG;X*v,]\cwhͪ%q74=3d=V@Nj}==r;s/o姖rTmoΕ@șPϰzZzSM7[tz8o+l 23"@ -` ~ gǼ dG%   rϭW胻=:Y?&k&f{?=Ϣ!;eC9P%8tmݴZo٥⸃}Cp厮\X8x2w煴kz2k[c8sᖆ!TLg y5?Ts$㬾qS>u5ŬpI;56Ch:v*@ UEaAn̿ Mm:qq5Tw8^ ޞ#g 䌇55'=j{aViVVwy$.H ebd.GS 25@@@w ȉ9VMS*,/{zLGj9er,-7h˂8ֹ*;ןYq{T־ldcT9S5^:77G.ױ۵&~ =oѹ˷esȫ;u ,^X7ke bCA:w.]p$;]uኦr\Q1O98Ck9~H Y}w}zvf:v6Kc3Io&z2(@ ǍUaL ~ jg\ d_1   G/\L_^%sLmhV %L@6j;MOu?ڇ/69T-ƚH@N"k &I 45j4VHff}Єqmj]TAΙ N].\ީxB9)ĥ qNͽ cnryT^{Lk li R0@ idrP @@@{rk@EEZRpOPD?ޥ0+匍'șTYLNs)C gj,QzD" :? */T(/< ,[R]:AǺވY \Q>o<9~I g^0w;/I K\䤾9fPAHeQ| G0/ MĬD3xHD}#h4rș 9Nh @$ߔ'@ 'y   #trZ[lt4>'wQ Iy/6[mfU{HSu5_|88[mÉNľ 5YЊ3n>c<"&(Qi~@ "L;Ow?o(`;k0C }ե澱rT 29JUQςzܯ1E, l!Zr}r*bh7+-j{Ƣ30Ҳ6ju2IA TK|byӷ틊]ڹHD)'tpϿ芆{F" 1 / 両 a>rm߲Fwo9)k旮 cyZ/+9?m\O\J%<7O #ZC=G9ɭMIuWTjZkmX]G3pN^5lQ&oW DF͏Ͱe\@NKϗ "\@ #  dN LZ) ]Y"+J /9fsMѰY}fsET͗­ίÇ}U+*_6羶L%BNaj>0MJC:D[L=TyԚX+%.6K+ITAeg:o:IYښ@ȱD+w qVμК@9I^} d"9J.;oQIKY%Rtz[4Ia :!TD91A@ rNqES@@@)@ΤUYe"YUj$Iqn'׻tɐWʱ58ŭn^f'm-ЗvT X+Ln&߽ءMV j_W+KgIL߬*9?3u: d֟_@3C ޟ#g5^ ޞ#7hVm\ZVk_oԂ55y 49{A# ׹A g.jN8Ѣ-  |SzLY   șDVdغr}rc[&7+sa@?ҩ#qL³RL g Lݬς*{sf99fbgcMAL=Ӈl„r w+uhE C9V_\hWC}vt#eJ9t3/?&*{r՘{3/?&*{{rWP~PK,ҮOoךTP?JFyoa4Od(&@ g6! z97 s 3w;D@@@`^~ XXEA}zS>e~fEFWdi=,|aj5Zo0S~rK?%s(m?r v۰C'wlzmuQ7}Qݮ{M u%a@8KμК@9qVcμК@9ș{}&lbY˿̽Wg>3i{С ?ht`y'1/9d!@ M@H̛@@@9Ԫ!7HHY:{J{Fzkm6f k@wڇ%A#+K6ɭ݄~ugr׬Vo̪E֘j FS uW;FHh|M '\+r%lg^~hM U 81g^~hM U ̭nY_ܣfe`f8SGryY9-}rg͕Vy#E@[*8 I>@@@ @_`MdQi腴^s]'7VjU^x1oŅAk}}$flomF*},syJUD TTQ\+t6ttʺ6[ޘ+ w9~0@L tlrf   )s bj1E?%0ӉKYQjuU~q|9'm \llo޴B{k,/مA{]w{b:H9i@) ㌷ ?O:!{Zixd4{b>X?ޥw.uh/&ZiZmrv^ $M/ ˤL@Nh'r|RhO@ R.@ '\ rW,.ӑOm!]-]5>M3rlZ_+k`~pƱ;Rok1E}z@O ϴH4bs)@I.qM)   9Do@7<7}*|DtEM)l3Dcr;]z>۫^hSY-ζoYho6ƮV 9~p;丹:-dCJ.@ gv_@ڻB}m[hDw\?ǝ $cYo~nY,}zN|_jLt}I DLBr@ I59q    { cʢP gȹܡz3ݬd ˬ4uQ޹خF*-|s[_80aר4ᨽZU^YȬsq fqS5\Esx)@ W@N֎C@;(.@ Ǿֿ٤7%2$ X/nfeVR`)km]uYfA`ӭᅦ zjOU{[\~24O '%` 3O$+ ogϒ#]S@N:VJ~ [%7V19 c_kguT-[=LՇ}pS͊4]{rE:!=*a>9]ٙ<9ɳ'H,@ ' {@HtIsș    ?r]5Ć8OY|y"niرgiaVٲ&̗?νdw;e4j^~?tz_MI~@J_QܗDϻ<qF ǭa\vؕ{ *,Saa  G@A9qE">‘GF584Ѱ L}29)4 I=6g r2ϵ!@ Ǧo_أ7sL8<{c@~p^yurWʟKuЗ)0GW&/<=]sn@@@ #r2Em ȱ E3@@@-@N֖K;pʪ.guLܳ }a{J^~k(_Vȸy[Aѡ%/' 匍Ͼ\ɎNU޹خG]\L u%a@8)//VyiˊUQ^ʊRX3!` [6wqGo$rWS͈@B> OxrU'9g'<;?̈́叮L^kg89KxN-  dD@NFعM96h   @h"D^J2^޹Ю}d&TJx4h Z-gա`4w++7ӕw \OzCx9&A@ rҩ͵ q*F{@@@$@NMqPVӛ*UJoQܬ`.wϏ'w=o^P]]gpf9nVqJrʎ, ܂iڵ},V HLorN?: ̋ ܺp/Hg6F 'g 3c ѯ'?P@/OJëuGouqWj֩ގ;Ǝ I'!@x  N9ZN8=   IHg gY芒$^7!K Ԙ\ NY~@Vxdm$2W;5Yf\[F 9֊Aj b|A]jӁz͊AcOSXSc⢘aэ7[!`* ѕzm֛smas79nc#@ ǎm&tSYQjƕZPc6f87ƝfŜ#wJOK9q* 3_7ds%@ `vuLP|G9um;LB˵W5Yqa\o-wĻgd-rRK S @fd֟.@ gv"   2trJٿ esoVv۰7+kowYq~Q(W&d=^[]*+S 􏩩wLZM|"'{.,̈́yn7:+"_k󣯧|q@UzP79nc#@ ǎmBY &"ΚUKT7sNCSY1y~\.g 3DzE@*Ž`~~^8@9ȱ_]ަ7sThڬV&&7oQʸyjސP@|@Ȱ #^@? 08@@@/ yY]k5_ohPY-* iYf ,, UB`N~0+:ر0+FzFEn丹:͎;JMgZ߳YkV.Q,%!9{:zt}ШѱtL/b̽@ n3 x uhfeUI:u򽳺ὸca̹S[?QQE)㚎F șR%@ 'U =9h9q   @dì~sWQPՕJ[UkseH_!׍oL} ș[.YkV͝[GI9V1ƛH@N"W^j# J{wr ǽLn0>_w>)=5VpI9#-rRo? @d\69p @@@ 1c͹ot\Oz5fVc9~ض.(hbMZI_XuG]׫q׍1р$Ra_6 q^<ٱ!:NaA&&&5 +h<>+  <999G:yK șgK@zp/pn3xgu7?Q²u߯ʯktp,x2wiקp^Utm]Ù]Pp1ޤF@Nj\^ yi+@2!@ '\ӮRC@@@  |zS:3;kMkuшD؄twF93#.{k<5 I=ՇtqVՅ@k>J dr嚀Ktv-]Tc kB2CC#4kz,Q(n+Sh=櫤P%*/+Vyks%Nsfwɺ6[j֗#@ Ǚ3g^~hM U 8oj~mzk ViբsFV]Kc&`isݳ#7rRK S @fd֟.@ gv"   2trh_LL pqGYq }Olзժ0Zf"9ULVa15~Lj.4b~6mrZ5D*3+-)ҡ[{+2& :085=iu~;Ω.גŵZV k!WͱVy޾;<S]#@ Y)8Ck9~H Y}sZt}鏛y|^~zYV8'<vvW87./#kd tO./*<z) B\F> dV@Nfrf(   )?֩Оkб>rrF̗E{g4b2V(䚒Yya VXDŽz6NY(!i :9JvR~x-}7k'zdB8ZoM?9fUʊR_L.7JBYիg 氥V@Nj}==r9s/prPeoϑ@Ujgk?Vaya\V(zͳ0YA"-޴PfZ`^lgoDwT ~Y]:  X@c2N@@ rIgI dPC@@@Ri2}soLA~lY'βjb&7r2%*@ >g|n΍:vhB3?0$WoܗIbٱQ+s~~SGtm{msgY@Μ8l ȱ E3@R$@ 'Et9Ia@@@ qng[Zo@Φ_o=_߻ԡlbO '\0rVȁmڹm݌'Y+\@SozZ-gɢjܻE `/bOGfSw:r Jw c{}+?$j{sr^׊% 6!@(ϭ2;pIХ eهG"7+ [PAHyAgC*-ѲK+XטıF?bVƩ;PW~u#g{fĄb{;953E Sr2%u@x.@ O丹: @@@r<]ބ[V֗pk9u# crfHvȱ_'˶ީekDtQ/TGgO6irV\kYmm:q7&:̾$ I$dT@}~Ԓ@͹qVײ8[AIX Sqe&8Yߥ> p164m_BGELK+T4ag"=-}&Өޖi|E/5N^Ŷ!H0  s 3g:NL4 s @@@ I}@,՛kʔ; c>=$@ ǩ&@ ~EnZ7RYYq“w{!d eV9 v٫ 39rH/ cߟ{}+?$j{sru'hwǜ檸Xe<7 :rI`tiM2̏.DƮM&MbdFҋ3!Ū2'@@@ eJ 9* ̊ /7ͷ? qEc ȱ_ͣUPwĄ|fEرdQڡ$쾷oP'M 39rH/ cߟ{}+?$j{srЗ}IYښ@ȱoEKq  ,IIT'   6@  ^@سYoۭ@nnIC:u.^w,U;tpfڷ5Ft |'UC_#@ د"V~jI O\ 8+g^~iM /fdN@N2 >n 06@@@O ty\ ˤL@=@  ~xGvY' jm̪=TTXwa+sS.ݎ;Ǝ I%=eN@={؊@9qVO9μҚ@_*<Ȝse@,9|,@ al    24 I4I{yy!6+9- Zt55'<7Gv,:u\;Ǝ I%=eN@={؊@9qVO9μҚ@_*<Ȝse@,9|,@ al   Hg gAqHB<Ӂ#+twԁQ]@=WPIn{&KZ*ή^<{]7>;Ǝ I%=eN@={؊@9qVO9μҚ@_*<Ȝse@,9|,@ al   Hg ?V޳c(d:./ӚFL8gT]s."35qؿ{:[@nI5W+X*w]D@qiyکg[Ζ'@ Ǿ5V~jI O\ 8+g^~iM /fdN@N2 >n 06@@@O 3U_o~sU[jzzk5+j~WכkBr9n cӛGw0>ܦ&S~Ihi ~d+z{PkCBq9/OG ~طSK9~7J Y] 8Kk9~4D sr2gϕ@9p7W!  xZ@N|y!_!3=uUظ TMUyIfue}=][NNvn]7L tNMHhdt,o+@ '9ݹطSK9~7J Y]7^>IYt7t6zs5(@ ǏUg n j0r@@@4 ȉ&o=R 9pd ȱ/hAڡkŝd^_3o);y:oylΙ xݼNe'^`O- ޜ+gu-(WayHFt6zs5(@ ǏUg n j0r@@@4 ȉΖHaVvZȱD7 ȱ_+sph&777ĺMUutKŎktY$:~暬g I/G@}gԒ@͹f]Uzכ!G9~:sFp7UL 3]   Iρg4>mrZ~W#{$rIo |z.ǝ? W:'sG~^H!***ں53nih_I9)@˴ qFνZC=G9ޮ/K8s,@ g n *0$~@@@R,@[kM)QnQQ^B*4@k8"={٢wt\umNrC k( na+@ ap6@ҤBoզ +HJNsKNO4(9 Z|QtVdNt,LuIk9ԥt q&ͽZC=G9ޮ/K8s,@ g n *0$~@@@R,@NUaP5(h7yUVUQP-*Ӳ}_ͽcX>َ,_+OlS 'GA05B F% EY =c:$kUDVX^{F2TuB 'U.9Τs?j.ױ۵&>h:>1-:wpN8lIܬ0Uڿ{֯Y Num]zWCNmZ8^ ޞ#oח٥G@Nz ~ 3w@7qCLrfa?   )Hg 'SIؽRB5틊,+9߬siPۣ#eslf5dlfeqS C-( 0TȘiq_P^4Dѣ~3#q9$G&8/*L(f ijn՛h̄7wqQ TkZz<Ș;9ƛ I-=O@skͼ|/Ws#:3 I/#D O  Y>}8   @ș+h"YUja`2 JOw򓡄+Ló3pN4ل "/jdOQ_gM8Z(<]ș&*@ gn0ڰnJK:y왺{I4ѣAǫLqVjZj*˔c#;eQ&]vOm]S2rR-L 37essYrXU͉@NrcY=8T0/(D"F4n~ z=9ޫ)3BmrVƃ 79~xv͗@NvՋ"  xH/ɒu -. Mp4 W:usD|-M^P[kʴkIj͊9S1ZQvgU0@J:̽jںq6mXrJa7vCjhzVuviddTc#b7|P(`Pk+lImtEAz#fe+sF]cHd<:ޞ'ח{t&/Uӟs!3[!|/*S2@EyPϰO}oPmX f좖ы􏪵MWx퉞oH+*DF9&?8p+;A䤜 {9 a9.U@ά<D@@@ u~ X*zcuL'~|S׫q~t% JE*E HM݆:Y?`B9z=l(u6 qV[hM1'r*..PaA~~;o 9`)iks-}xRڮ"cSLxk6[ 9~K g5-,Ҫ˵㛵|2c1SGIkӵӏޯٖlX\ܢś}ӯ.u<ꌮ36̏dr%u֞#C@;( I^@@@R.@N 'GL_SE/Wid^s]탑KUغr^,k6uV+z:/'s'㬎m[8;)K[ȱW89hn9ýZC=G9soQE6A{?S+I>]M]f4h3S'VG~@[?0b5G3aI91@r|@ r2\.?Yy8   @ȱDWVvW5e1;G˝fˤl)"8W{j*~E'}aj~WgLbd@ȱ _~ir$xA@*r/prPeoϑ@ B:>լv3zϯY-gd`tʑ/9/i$UiTV=/@ '\ [ř/ 中"gF@@@ ~r۪] \e(<芆A]Ig%* ۫w+JθpW]P琻W+"O}S@3m ޟ#g5^ ޞ#]i}^g<ժóUtrrK&3(o 䤜 {9 a9.U@ά<D@@@ u~X__oU LO߻خ~0%jmVJCq[}rNs9ncgj| ۙZC?G9j̽ZC=G9k3tTT^ZGF#+:Y =jr&| <ˍLL9 rҀ%> @d `9p@@@T =sxE6a5U1Yc$f?o/eAFu>b8NYݺqke]9vKμК@9qVcμК@9qVEqi䬎3yuvv9VckuHs.@  i9ןM@l:C@@@ ~YRoіfzuX]jוӵ%PcV'}vsEB?=4]hVD 'aؙEr/a;Ck9~H Y8Ck9~H ~}CAvY"I{Iܲ_g޿qMlv9)#˫:o520:^R@N*u,9|@ȬsQ@@@R&@E XTcsD߿ܩ1y|`n*RyV+ء&n丵2ˮR%lg^~hM U 81g^~hM U دoJ5amE@@@ e~X^M g}"ĔgL_MT XoUA07W*E^VVD 'l29 iJڶIYv]޸O߰ Ϛ+N@3[μК@9ȱ_;굷ke3464M;zr#**Vr-ٺHkR |E'=c>m$y3jpWtG46860S @ 't1rb8x @䤝 :    $S+ӷժ8Zor.wÇrb`R+mS@[uZ)ǭVq cWy<;;)K[ixd4KGaI5WJg y5?Ts$c돭:55 OJN>-\Wi[+9]՘Su_VE=KUlB>mVwOɝٚq,IrI7 0i8@rA嘿s0}XK>3gpXҳgI.!@vɎ:urZy   q?r99JVZu<npo$fYS*Ur=:4YqmiM96h rfawV ɪr1X qaQ#9vjQT't6ttw4Hq ܪ#_=Od43?]%i[~QWUiѵ/.SWG'Ns+a%Y@NA|ș^dHwHtݹebl6fmf[X@e%-)R4-ȗɷ~rLgpѳ1M i_}4vf@ d} ==9./C@@p9KCʮ}bCy\n<{:t{C q JBZ]Pn,z3\qiam9h@B9 Yؙer` ur\WP@=0+󻢁`^0g˨{[)#/ ;Gv@XJΥ_^ӟ ]crMVIYs?d=geÖZ9wȱV([Dy˗ :41Hg&X[˕[T˙x:Y%aD`D@td4VߤH{W2/ҾrL&XUg+o2*Ze% x\̀L=&GiTC'O5DcM }V`'R%@ 'U 9P@@@ @N ~|lmZ Mdvq@^P]CG N@N ;L@NN@J€ @ gh9S0xr-/ӱ%@ gFd,)tז9 $ ]Y%@ ^r͗9r)OJܤVf[֮ѱԦ7ǴZצyVTG_>]99=}o+S@<9^)@Nna?WO('/Jh~7+ŤzZI8Х:wU#&3ӯ]v@NN(UKUځh'X[5+eԈY-gyOS6:Fr^P…r\X   trGI}wR+LR`B7em^PcJ,on;uq`6^;P`8󴱶@k ) 0Π zFu}Du#zl^\E X7)ȳh+rRI΃@k̓#@ '9Y9/@ 'kȱ z;@(o\O?_@PGi|qOL>9]Ս䘿}w*kbqNsFcGr$ד@ ^o5+T;1f3z~$4K!\I'&4fV8~^.)b/ٝ99y*ذZex]{`ߠ^'m-)tV Nl r~^=W!  V =KutEIZ-B&RnVũ1T w{㫝[EzˬìT}#kT>\j kgeco{GPXO"4ej;r^丼@ r\_"hC@ $ 0Yp8riקE/E&L3};@j1P֊;q^aY'1y~Ywi\HHr؉%u{?MY7w;ͽKw*D; >3gΜ=`fLK$LIZh,)mI۸"X-O 0d%հ7@[]Ikp Bd9Q*Yuu{=Ԉ=zt"GJVBqGƗQ5m"TdZ1>6:㨔iico;`$BN13`!'!`L 0&`L O )la[qrKO_;=g%8'YeSMEŔlr!d}2S((J/;$mKW1yK`jMhrvEI; Y0 k1zÇ#9sLH"PIBNՌIIc8(?n;ILIg2mJ+2]dS)9{!+)JVBv`=DK rX 1b )a)H*J2T PoZ TzҮvaJ)rm'ޔ1` 7,r`L 0&`L@`!鹘_ HE8_gc֐>W0[))'M-ӤrĜcyŅkӟrWW,drytg2/_3X#I;RoXn ;^КJX# 9Ro`3vr>tIi4w_JږbX2ePBkob?N{B}'cC}rn>ߞJ+ 99]1&@9Br]"lA]]EʮHp~Q/S^oW*#B(1of6`*t:IQ`2f%>nEW40JVjBhe"X\m-~J) Q҃ZDBW^7bb0Bc1CC7j`;QáXuJre8݁k*,W2&g,!wG,.w`L 0&`L@@ 9:C~!8 $a*sO߉_/= (-,zh ȃ1&`L 0&(JrĜ;QXJq40 'wóhtb-dk԰6B[gm*R:E5GWwD"OY )!g*Hb$ .L /,ѲSi+eL 0&`L 0!PH!g$Ȓ|| FC.ISD)%(9C)ӨZ|DBJ4DhpjB#IZĆ*Pk$+xMG,UYu9TFO$p!=Ab!'na$BNvagǫZS \sd!'5ςxUBkr*a{,d3?s^|#/IDAT5%Oǿn©- gh6`nwpd t|Iz-e^dy]jơώ;IrEn [`*AQa}}&&"s@a^6*0p|"&Ҋʠi4XXønjq:b>ܖŞ[2hV^ڵYtuswb-ZM28X$瀞޵7JUJkۘ(-,zh ȃ1&`L 0&(B 9)eέ J[P‹H?ΨRo⃙89`Q: !$W\{n_$Ҍ]6f}IfJl;v]u'A 7c =j-见RKxM}T.J7 9%4<0XQf|vv*5 9?Gr[c,ȎW%f!VBNv뫢]X ڄ軕۔sxt ̢o͒ntFݳ_Ogp_G |`RK ; 1ĄvwQb1<𨻊 9y2&@%9Ic`wfN~6"m8؍P^MB {DI$;=Գz C;;^КJX# 9٭1dǫZS \sd!'aâa+'~Fp- O"Fre²xKP?*"{GqÔkt_2K>lsMnO+sGܱ䞘HM܅cYTr4Tg.6}zTϝֽ)Hعw!L׊RV`Om4N+ v27AhZ4$cKͻ壤\z)%f:h/&L<D>㝙`L 0&`L 9g_>3D"^ "V<"1Gh !3;I;r )Lj',#̨5&^"}}؊{nSm,2#XɎ._JhBN%rϑ֘? U YȩU.9(ExQN'H/!ę$ߜ>̊Ǵ5S~Kĩ-p&tz/"8ޟAM7@I*]]%m`!'<7& mWQYc~8ЄWg̓OC0w5u})I+yadeuu!ۮ&;иaR qMRW_*zM֬~_by؄g\?삛1.L ,đSsfL 0&`L 0 BNI,CA!Rm>[$g o9E"S֩Tޥ*z].6|B:,m}mg=%[PX_JhBN%rϑ֘? U YȩU.9ӻW1m$))vpMR'@/7;p C8un>1'\rŭȞ@ 9B(yo# c %VJwޣ@5hԧis ({9RJҊ~ YDtpS$%vK&F\3.PVoݗmכU3'KbqhcM(")I]KݪP~ık+HqD= R2|QI*V4ZUPh.3QLs@~ҦhSהx+$X)ۥ1&`L 0&@`!W([1ۀ <)"ْmN=FT]Z}a|yۯd gոZiL&mB[8FP;Onؚ=s:6^쏣/Y)(n>XX,ȎW%f!VBN+q &=o¨#v% G$]֩b!!w$DaUc 0 IVvW_y"BNrL <#PBȼv˰*Czw@b4ۦu0-Sp:Hq| Q;is_*JIZQa{k o8%h"!#])czd y& I8wEYF {\4[~z][r& )H;AmjSTKbb^$Ĥ'{$-Kv`+,Rtr]wmvgR*qHƍ~PhT::<5OڿgW䝮h< OAx#P/Ot̺hMݔ)+oSh|l -n`L 0&`L X!~իǼ5 #n|gMڙP/D|4FY5 G$DDОY<?_rN )]# 9٭ nn~ںŁ͕s. 9%r[ ,ȎW%f!VBNv+mm=oF\gʮ9= 9 IBc#rqU+oN,TޚsK Ȯ WS[vmqF\= 9͇bJ\)g#Ǧ]Xn" TVW2$_o~Ji{w8Fb Uߏ}ȥÔ/8i,lﮧ2D3u^ DM̻B N!Ծ"L fʾ2^ }RLl;IBQ!Rf)?@.b2x;uqZ_O?ԐhWJa\P hMYI L #r2"L 0&`L 0&CT 7*-uUi0~cI'9&fCJ:IcA2N3uB/'ް$ J/Ts1m`u ׳H'ͧ;(- Q \|BrܓAS|`!'x BN,rL Xdb^ WyuS,{{eGM?ř)ݛDBN@(G!G\^v9ﬣo߇۝iCSm"tro#Q~3҆RV vIƩYܐ%E)!?'M;%X;ע敥S~蜡s~O-vkCpg.IiBk!GJHY 5AScV}w#!o]!otWykݗ2+kMդM8ߛ/SZ5mLȊ]6!N]1@:,#L 0&`L 0&L!f7lLPI3Ԣ٠Κpo<(Bďq Z9c(YX6ڒ|r?>ߨ;l;~,]C=(4rδI >RZ KojxN,Q%BN];yi`!4ցG{,(c慛HBZwUʎһV]]~/ݬ&);"Փ 9=s&rMݐ󪔊l㫭?iKLQ?gO/?-e?V4id qmWJshF UKĥlĎX {#@#%w"?TI 뛫Q={ l7b,DIVX8;+_BaO]x*ܸ& ϿJ5w7@7d@RlBvD:Te1JWnJt9TMK;H$Q9&Е\SrҾx%B,`L 0&`L JES"0JARƜ!&qBFm&.GS|)99;@?LBfرi<3zvQ"胙uX?"|zM*iGt@퐐ۍ _X?;zSx|`!'<#BNy9Θr\US! SH||`!GUQҿ.TCZ G$iǕqyulìCS̓dE%PvBEa{m J6C\ ]KN"1Ķi=U$)[~.υhQ*ҊbB͚n\ 5=+ výk\Jh#IZӼirFݞ>d OisJBE !EHy,*u`}c5,+fL nq %й:Zwi" :tޞQ")I =hBi߼5+Nh5w%㏣p|E7b(K7lpچ}~7:v˿Df] r6&`L 0&`y$Pl!G F Q*ʱ53Ԅj]O;<$C#VLkI6O#^Ψ\v]u_-pQZ2P\< 􄅜RZ KojGEG|/GfZp]4_oXK.!BNqQ@%(7!GmWH0XE2s=4x6=7%<3M 0vDB}'ރ'i;==/!GTϟA,W0fpmNIk\ s_mBβ,_ %/iԥk>DGO BKH* ɣEmڍ@k=[? פTQ*ކYS$0n$u,^;J4IrE o~x U~Dډyb=P$-TF=|GNIrq7mL:|ultVs]G=" @'6}t`(,mܼ@X)h>L^ WRY< 9ŤrQ4X\,bw {SRMV]~DIɹC 'I cc{Ā`!'L #.fճ_Zygq}]LߎWQb`?s{g!W8IHibK+B>:7WjDE<' y ۾s\Bĩ]@ScZf6JiM"5G?F]]".7/~YQiEJq+|'Bgb=E;{iђ#dJ?LB rs$H 䍮pDJb'/Q;y7H%B"j#43 ;I,ZJsJWZTEI; ;%0IJWļ:8k4-"o`! %B,`L 0&`L %rqJ)9eE2Υ~DC$(i6>܏;=݈ )fݠ/NħLE[3^A=Չw;9HKLvr ;rX\xmYom~̰,[k`;D$!㈶D"!䭏N&:nmn8鮆?\n/t'@!p),ZHzO޳ۓ? 6rk=+q6,(_9oĊ] }>i8$F2Ne% FVSSf&PNB.춬\롱OIi-E5$aHUiWGt1#m/O7KZ :DŅ"I0T{E!"w Akn2Cj~Ԯ{ sH0e]=nA :iu k7E7]Eڭ$%%e}qZ_3SKSԀU/L'qvKiAi݉ 6I U$ q{ $SGǓMF"NcVJ9H9JӼ61Iu-š+6rE 9J(q&`L 0&`y P,!g 'YvB-"W 7N:7t4 If=[iD9~ c6)YefNcӌ:\2!KT 92<.XQJJY;ݡ^!0r lhPAV½ xHw9lwtHN, yG4X!LhX-z,- 9axrXȑmK? 8ϣhՖ+ʟ 9tF,dD `L 0&`L @1ZkHCyJ ';o@ABv*I$"YgmgSy ,:Iک7i1SEO"rNY$}d R'$(uRwq#~Ņpw*{q>]E#HC?RЗ$d&6<wwt6#]UrY)%eI,47҉A0f`9hHUg`Ӎ[wνh.c]S+SB%eʭ 9嶢7rЩ'0fȤABu$m'BN1ϐ @9 9s8C)𒮈toz;%Yx5K҅?E"w{ۢTZe(/Jҷ5->rYwRb8Q~1SQ:re^:fJ  5H);[?ssW($i'"ֽW`ݰ^%pDD*ez]$`$GMM IRNZFq ³8bmZ톗I[>9Ͳ(;#!n`=y5)!F9\ U\"i:Ŭg!ؙogL 0&`L 0&'r4fal]/E}wZǕր$#X1׀$ėTӾ $⌧̣41TFg])ebCޛiǂaf҆$" *SiEͬm 7;LsKFZ95u7EBN/Ɲ,$S,,>[j,;j(O$刺|ą˷qN;trRŵ[r_)`!}g؟{`!?]`!G\g´Փ1v褝^|s;/+ʟ 9a}+֢16a\"i2ְS\|ty,L 0&`L 0&FBh!r4).T,Bwg8ɔ9PJΒ,eta۵Py !UBђ 5dw1RtqR]W siZmnDRwi%K%,JY:Ҍ71֞|MS$Y$R-,`!G)DN}]$L?suyѝ|oI^e1ê.Yȩ%/ ӷeς+Y)U9|U]nٞw' N{BrYI(]"G }:͖-E_mC[zn :禄B$p~ 0&`L 0&@R ,/1GqD"˖KN#z#6PRN#Ry*.)!GH9Nwq"hzé~D2'q85 9e7irzY{v' 9崚9r*syֹ%BNnyroL $( !?X-K5]:yiۥڠjԾES5bt׶ŒJΔJ+=+s: nn ϾY([r;\; FI҉npXk$Eu7ps+:~#)B#"Z!!X 7;@9HmZHW1t''@gr,䍧?|/ʢFӢv틔*^6)JXMsVr57.iM.V= 9"UB% `L 0&`L 0<(3Ffaڤw=38b9P%c04q FE4 Hɩ֩QW~HrI<ᦛXǞChԛP #GWSVa2%,"}RK#J/Jn5`lAzܳ}R:UzJSʫcSB%ۈ7fMƴIӉ#'Dd{8x"J'D 9cGrzǖ? zǭb!WBNe76?XW 0AZ`} /2'mp~ ߏ<Z%OSEH+gI(؊нGrnS* (I;d{$ެtnQȉ"iK8a9amKu-OJ6R~Pc84f:~ [k`}meZH{ /PSk򑳐7:݆"jd)%8qLt!G9ܪQ5}c2.myϥm#6u--Fr @IDATW{#W'@4JJIUՒJRs7s7`ySNJeK>$A <@ڑb DiDرͻ oA)`!      (9_u}S6i~8t37vȭ`ʱl;jִc˜]8S}«+[1ٚrq߉=cRLv+&:hf9hu`5Օ2 X9E$>Ps6ykۅ]}&'&FsqU-ɹZ>+̅ݞ}R \t[]i2̘:tr$03C wAu7͘67.ƶ$P6bvu/lĉ@Xxlbs$@Bo?0WȌӧi_2_>jև\TӶ`6Z^z sى?]rty*,̓g:<6ur/ۇ8w-yz|w?A`+vlԉAۅ&ou /v~}ٯE:V/A/:{Z"/gs&hz>4ꬖ>u>01G;}ĽSkp?JCfkrAx -' }=|?ˌJ+O6rP~w5DB)vBڭQFjjzVmBY03 i4 "|Zw{Cm?I֣4A([?8xgw&Ν%;YϏ^{#Pz`$ ߿B30|J(R[4*}rwj"s~=.g)J ~0K !|"Za :*6cӬKBNsD(gŖ$@$@$@$@$@$@$`(R 9=e'mkYmuӎe(TQ.hWڰnJaw.݂PycK$%#ے8H0_U_7"EtJZc9w 9cIcABNۚi2,C&B_B$@0@ \l3s .5qe4:lh\U|ؽ8TR|rϘ# f|jnmքgk#Z4W}&X$^;)_2RP$P*]1O OTY2VXƕ:4n\gB}cvGM$|,|9^i%ӹ}1 ]^DD,t@B޵U3a8l1֙Sa,t[EiF<|IoQXGhrgM݇_=?gXFS}Imi}7ⷻO. Е%Kę/iYmP[kقlM>y4RظqLGZrJE㌆P9$@$@$@$@$@$@$`R 9SvJcʬUFFo1BqJ[ڊ4,eʎ/삅qvMDZ=95CTf}1|rƇ)d(+"ey._2.фlg=n{q \tC2+l\6,KnAMکW73mx̟3 '٘Ʉ35-c6QVh(P (E~ǫZSȩ(WkMși6ֽ ԇT[nqGp3ն\ 'EUEZ ԉ9Dl7A2m GKm|R䈯2SJ+* HgTYxgP$Aɺ=(YU&!%r*T`(lwm&$C3`ܙP҆m,'N2)'Gy"BXzLSވ\"ٰ>A`. %Qɒp,YJ`yCN<\?v=-lHۨTw+$|m++6cdcM!g,sP @RLBA/*h>"b{|-] H֞Nԟ'e3]vLu Pa_$Ї~)6b 9FPdcIBN~'EVg)YO[tSg1R%B)urB MS*744NyWwlou"?4QA1;9M97§,#rŹyZ_yV֬]ǻ}ddj8<&LECĤϾt8Z1M9F;r),- 9^pg9b\2 nνDƹ!21Wb1cXj!&~1aattzN{P)Xv[RrxBk 9^#/ƕBNiys4E,΀gX,C2 k~,T r>EذΞgc2Ȕvo q/e:?I9PF;j="7BGN!'2̩+[r!$;b]-/=- ?tw?$27G eZ1Mf9VrƊNO3z'YJd̓DO/b"aؗ/D|mg8L`Q x5m]}d 9J,YRN<JeQBKZ)odȹi]ZQo!@RwhyYdQTvc 0C+:eQ[ J)չpRpя?U2)F 9&84!gWDLyP9ߗϴ*; 4ɒ2-r~Ĕ1âݨذL PflZ NxR ơgie;W)DQzN f,x"NcFcs@r ɮƌ]U-SKѮεRȩθR)m\)䔖7G#Z$PB/@:lC'D uϳR JjX)kw6pnZ4̛]w"]E270в4?dDI6yyc%~!gPQ!z&]cT}]:r*Kr!BT"leڤ9XAE,\Ģ;P1lkx~Vd ovf.k݅>I}(lfr#~ m)D/D.(aʝ5ɚS3*lǟ$[eY;K~(Njˏ13k 6o\힌'9[wm7R)TQF5c2۰ ǷfN燝xc G2(j%ZvuBNuƕBNiJ!9 "JrK-Ι^awѫnיARр۬0'G\]/Ľ-9缢n ؛֮ϣ1 ChBHlgL W&yxφsF_eJ$:s*I=N=t-[k4 h+(8ˋp1 GB;/A#)N:Sr6tIvLqf9"^'Ja4mZ_YފG!r-/"ʝ ܸKB]ܨPrnYxޕp6Jfع:.*1e,ƚQ aڍNluvFc$M5V('j%ZvuBNuƕBNiJ!9 "Jr~P!^e]sw zCj9;p6g:\ԉT ߇_/0(ٰG*$+imks0kd>;@] -bi\2< ˴I9G\v'Íd^i]-~@ I}f˪ajO}E)W&|dAo&nZH;;ևwbZF1R) g2:rFǍg @J)OLɍ)sx<%- 9*KiN-MR _8wJlW(pdrR 4,}2_=:~yn{uuh3{dl޸Ƶcq;t*+#@!8iPǞ8b+ 9Zs 9-S1i_ҳL&MS5)'SJ B0=A "BF holm]^5Ή)4zZǬ΋]8)\w]߷+*h<VOBL# @*JrhcZ KS7܊?FߟtĸMqZ ׃F40*H2x%;d><|Es/#u`owiEK=f<ةMhy948SF#o$O?8&M$yM${ mHeJy߰>2e$o#jr`ە6աw#O_HB&+>OظQLmt[ 9FeFc$ME$@$@$@$@$@$@y(n'fQ{l47#?mlhi 93%S[q̦!ExW{# ͍GBNżVL!G_D36]{.x™W5!K\Y3&iBO šɌsf1(Ñ- 9@ZlE!^]k5!ٜVL_%y~9.zyLrQ"N@ě΋ݸz:ﺈKHDݸ2No30udlQIǿ:ߞWğ@T]dr ݓ ҄$Ēy9o-gB֙Mp?ydy[ήb:(q#W$i%:2ZU~|s (Ck^ d߾_DHJfQ2GKhQs ? B  2Y*T;#x2 zWc)rLoNsPN h'e&oFKO.VEwhy#/ëY*6e<֜Ba(QP)TvI$@$@$@$@$@$@zRyeE+]2Ҩ4ZooW$C|C"m xfA3~Mֆ.kpfn70ɓZr#bf*ͻ_\=}U>XqyE⒲]^yB!Z[k/f!GM3gȹx&ܸեCsa=N/{бsiXa 9ƱdOcGB>.ǩ[QȩŨWך).6 s6꟭2EK/;qiջ"@|tp?:rFǍg 'PIB`$BӒeÙsJ"!".lWANJEZ 92|!{N+IZɱ*jm"4=2< )g2J"yD.^d5ov+YY=Ѹn.ʁp}30 ˔uTS%fE1]JL7c27]? Q'sT"<fԒvɴ$BhJEƵb:FC!X(,%      Rȹo [ӎԧ8,4[/!yR/"Rãr-gKd洦?M #2$,T6f70eddIH96sNw$6t?}Q-Rg VcE!gs\PG,N~ vK7tuh|r82:[gnN:˟Z΃=Ӏ78<"NxԸ_$rݒ %PIByB;:e_JUrfq"܈GeP ]K=q _?TS SMj2cNJk Gzv8y;c!\Z_ pܴ&)no/K6.Ta[EZuf:u=,#@!xlsPϚYRK 9\+2Ճ{^]%II0?}D;qFD7V= KXG=팛;㍽8a2P H!@!'wH@Y-LDm-SHQR'_n=9K } 5#[4i%:2WڔkNbY4̘:_ %d*%[֝q87f(bԫorǔYRK 9\+j5f+k2$7 /a{pԭ:γm"s2$DZ/Oa_vV_!n"e$@w TSﰣyÒ1ԙwiC ޷>DL /'b3PTF*[ڴҤ pf_"};͐|2X>w >u]wĜ LG8 n,3&q y-˙Yf܁`eZߕsɒq)87#4AKh"lBΑ[Awċ+m&40YLkĂv{1"AC{` _Sߖ[DZ"p"pqɘ>D# ,)E8Poo̙WÎiBG.[K͂9zyM/ #.Pȩ@,B@@?ZjI!]k_\'M݀9gڃ݋c_*zfzycois8׉Υc(ϔ= !:gZ^zJn_a{"!>=J(Einɢ #'*yѮeZ2:gQ2u"3RQRG1G*Jqݿ_x[2:vx"Su9v|l]Nn!{ NvP)TvYrr#w~VԒBN-E:J!G\GO.oDcKjAACe(zg:~YvJ$ Y<= >$bIɬț < T#hӃyOП+FFl.רʳPrN2DpƦ(d\HJ]yx4?סޖߵĀH&F_^MQg@;bA8VL2i!'WxnIf/пu/"(V~M*g =ˈ{}orLI8V+dȶh.<5gH쳔(m].4/嫷sq\љS0w^>=Y'MɎsovfmc G2(j%ZvuBڛlZ*RpTv{;%產A4^X{ rfo)ScPȩs$P 4H 7oh*y$͛)Z&lC'dI7Wm63&=ےy"d8`zK}~/O~6˿;Yl/m ,9ݽ"zM8244NT/"Q4Oue*o( }=~3WL\4#Grތ%@!XHHHHHHt !GMn\Owyhk4eo1@t';CO2eOٞu~@62Id- q "$1C^^uڻE*LY?q܋R J癍ld2+fזYIEM%=x WoFL.e* 9Xpt;sl}y'Kq P)._^rxBk 9^#8<6vlvҭ3/pvcŬX"_L]tj1VKB< @:Jr+3ML^/,!fqkp5(ܒE.w_kH+$/2v%N25΁{ð/_R1qohr& X?iZ >-(O$Kߩ_))[Z,;9mĶ2鈐 l@!@pr GIHHHHHH@r&xX2<8 d;Q !G'|v;B4O-ҵMZfh8*v?pJhMz4Y6%vdV2xJUN4)'ەP(TB8\(䢓~2,[<Y\Wr7Os9îeÙ?g*a10wE9s7ݥG 93e'@!'?.ȏW-S Q5R߃i邾^i'CZEBNȲ_      X 9jjM"mC"mѐ#^G.Dpz.qʼEw,okUuq궼$Ѝ("(OQn ٴ&3lI'[z r7 9#J=^/͟6,!;W ¸r'N_9'e%䜻x' Os$3N{{3"T0Kv}N!fvxqBX_]ZhM!\k?+,u/M7q?q'nߡ-gc#Tw_߃#~c0PvG$F܅˴IN{Jn!ޔCڱΜ ϋOqTPϻ#Ati%bm"XgNK,do2Oh2thlP+ѿmwЗ]fL&K}ܢFј/QֽHFY27z^ nWҤoA>.F)qLl}RF@BN9Ds      IuxH77 $Vqfrtcj"4HBPf"®+(RN%ɜޞfS54ltc8*̶sfHakptCb2y4g;!+ݸ Ml)mh81( \.|*fvBGgݦ\'' uY(i#Hkرnw4VRn"@e%'@!'.ȟY5A![k?k_X^4w 9fb9K[HĎ7`ҎXrH #_97A/<=}I5 $}5F|WyFn;lpoy=:KnAc B̵_@ ɥ*%mW$;}B5YLGǍ: YrV'B'"g/+r(97}|'C-Z.CD" >%U\PٓZ^ze t-+zzj?F2騙y"j?8 [ӎ %*J<1do '?qhG)hTv4KvVE~^Z}O4}&=>ύi"`))kxQ{:S~3͜> 6,dd nq`/yνqU rS(䌎/ FǭϢSQ5Q=ekd<ʡk]rZŪ\|l{N"7bϻҎXrH GDtO|RM9x#jKٸq%Z^yF<0@2Hi[MJd&ߚ'cb$yx[P@' c0 8wy|4!g?5J.i\Bm&e=uFPY;Èݼ=i䒿Yrήy䑙Rڲk4+LP1(3Cq3      OY7Z1dTQmnSՓ%-"v@"("dQG 9*KOTv_y';OwgBK:ك/_`Vo{0WL+;?GS)Hp%@!gt̅cݪEh4Bʦ݋OCT2찔ұH#@!gtl]0:nxjjmBx[flxe-պ't2/Fe٥$ds?;؃-3$$( rrLmM͛9U us{7bb6PrFfLq.-IVYWLq%WCtwBDTJ5]"̀]Dԉhhv٨${9r]r0ʠfߏnD/]CEM;L&%Yln޸f16mX6T}pph }Z/@gre PpS8]L6)FyrGwڊ)޳A~\E@hv̽gV= E$1h?vxr^H @)P)e1ZrFK @]ȩl)K4`7P0Q'"GBnF=q & $'Y^ެ<3r&nM&7YRZ T;̒ynäa:2/)\ r 祗kg[1̓['p ME 9dž53^* N4 'H$P8oOd@h  9eN r —d~dESu(T]HknArڈ痣!"ɽ(ʡA\=rHQm[f'6aֺX"lO8|vύ߯iƦJˁNf,G{.""t }c1-]cRхʘG6l7CE}M؎iSƣǗ|DAr"tP|/r#Ea(O.CrPȩqwPIPϗ>6g[Sp3v:|7z F<-ig50ud8i+Tߜ?DC. 9EnIs7HHH`LPT' 9:A M@na_]ݟT 83)/m)s9$Yrܸ&MJ}JʔSBNFKB^RٮNڳt:$/O =۬8u2M,%@!|{iP) bb/ز< P]\{SMFtke8g'd_SH P) p $@$@5MBNMO!C T+r:,K[|C{X0>|qڐrmX#bNrQq8؅%6Kgzk ,&$Q 9K/ 9zIOzp6 \ӈVOƏ`¸V4hh;gU: 9U[ 8 +fr+M(La0g,}a%&WxvMY?8?>#x(P4B$ 9ybc  0ÑC P1&"      |䋅"D Q7)jAD@\*MҟMBjw[佡^_j"||ʇD6fO/lF2%$yQp%,*+Ϋ+eϥ!@!g3s LZ8&iA}Le9 -32(Qtd (&$@$@$PDr]LBN X93y^qMQ2 ;NK0Yޕ\j2ѧ緫SѨ5o8߉+h7Lu72٭֔qOw=$rRƝ $@!|f25aQ24Ƿ-)cA 9dgcDB1, t@*&r BA(Oˌ3}Txz ,Ge[Ta#tv4En N}wq~bS- 9&HPȩs$@$@EBNyŃI%@!'HHHHHHHdJ-8xzA3^Z !: 7÷8v+'I?P;()gZlkN % ʠpT+d,٦WzMi\\n_LD4 ɖeG**7"H~KYnr-"O(K-3v-v&*qrLoT(ΐ== 9c FelSȩ8q PF:yJ,.fIƜ-8,zOϻ݀nǕCpӸzxP1%{"LBNf.%  RS*g4(䌆!      RQŒ je+VNj8LpUNip26Yğ8ͅhwS'AɌi9EOo`PrNR4(&)Z5&<6 SDWtK=Q@M=]Ӝ6jmn\E(>DO|qoFW( 9)!T  9Z}}=6 \.ܮFzܒEᴠIB B ?B~VlY(>6.(=bH!tw)P1ъq0e$Lcw٠QGOI#uW_7 mJDBN@sarj8\: @YSa$ IHHHHHHJ),g8mX;%=;0] oǼZVbeDqYy ϋ4Ó*(J>XB_$QlcڿB&I).EQ;Ó=8F4al%g\%Q3yR2#p\K($z](&j86-͚3̓F<т&F! |yL!'/\l\(&0.( BXPFc$ԾTFZ2ՃInڜ0YLh07A2 :0%$dpCύ^tx^J6(FJKrƒ>&  B?LBN9Gs#     jrӄ߭nx9񎠖f J>yb-S\ԎځN6M rK9*SA|u';CL5f˱4a˂xHoK=.=Q| "w((bP% 9%1 9vl6h$ %Lߊ7l!BN1M!'*ōc[N=S)hp.!@!g4FaAc6U˖2%@ b׀FR(8Ctr*=? @SSȩru$@$@$@$@$@$@eLBίW0ץ{S>3 3mZH!fD@ o'}06/L(屭2iѹndl9DιĜ= &8Rf{GxH7j2%,Ӛ-xuE[$!/ZnfF!`` P/fLjG{%N{[36k~:O ʂ hNd!Cɒ,cGBرK~ǫZSȩ(W)Tn|v\;NH[D/{/iXa< 93e$@( Rx-%       R 0ɒ27"tx؈/q?Va3)d>˼P16rJOBN~W-]%#^NHPX 8G^@o2ᨺ8 9cCNBN~H]ZhM!\kSLnƽZO,J[f/v?9vctvDBڰ/ 9L? 9Y.ȏW-S Q5RȩR)Q)Xp&$P(Tkd.  J!@!R"USqIHHHHHʀ@)\ )B&\ԗjgFfU y77v})ղC!HR1'{+= 91/&An*N^Z^#O7)Sr?7@ ?^КBN-DH!rK!|bG!|b@SHH*JTmΓBNmƝ&     (r\mBή+s':krMp 9D9G!'LsċvQgN!xy Pr7a+'pDۯ 8>|,غP)hp.%@!'?r.ȏW-S Q5RȩR)Q)Xp&$P(Tkd.  J!@!R"USqIHHHHHʀ@)7_qNsʪu.H/ΆNfuR ɐ?Zv/TrcP|q?ƈr>ƒ [<Ca(馳K^x{# eMBNYIBNP?6wA~j5ZruBNƗBNĎBNĂ3!j%@!Z#u T  9ڜ'ڌ;WM$@$@$@$@$@$PJ)faے>%t c9M5hoLNu9{̷Zv&7Y0ݓjYu\A}ΊY(.. 9Q }8{nvtDP2(I'*sXe-BN~wA~j5ZruB7l5Ԁ:㻿ۣ{Rֽ nhÏ=/O U><$#eTrRypHxrgIHH rŶ&@!9 HB ,hOD nxT6R:E^$\P|XH`$rF"NBN~{P*'W2jNo_?JΡ3)Tt8 PxBk 9^#kluʫj*6MۮS?Bؚll2iO!qvڱl}~\9t=}ٚ>  9YH0r CɎñDg l]qr\nw%rbGqek{N.\Yq @p̙SH&`󿎶 ŗ,Bd* rA&jäG[9=k\ޙWLX (wr=\?mB^<[JxBȠ3>5tϲ:tS+s 9&?rq@/+c(W)houM5Z4cg;fx<)r ٱ' :rqb+  0r\=Pу"       <)Hi[qTTJ8RyNҮu\kÛ~ÎFؤLG <$ PY  9kF=n\n'l55XsAGdyAg晠 EAg~ŸL!9(h#{6^VhM! Q=R_&Av"N 9BNؓH@ 98 EBQd9(Ac @r[՝ґ`o<9ф 㽫c̸ FBN6*+'rE΃&455sj=.]Bб-褔L92Igr JR0ߚBL9(hc{6^VhM! Q=R_ӆݍuȌ3OB< r3c m(h$@$@$7 9zxz'ME$@$@$@$@$@$@)4mrR^פgKîi|x"SN<#z|rd=»Bș%2 ʉUSS Pɋf|RЩUgt :a!$x?{RΌ=Jc{A*'J5B!G[[65䷏bk[u,rٱ' :rqb+  0r\=Pу"       <)彴9؂ M2pu ? 1{"px9N[V;pdm^X88~-ZrԒbR%@!Gȇj9tDZAݨ :"{x Qgj&D&H49RVrbae_x/Џe9D!ŵf#@!'v hZݸt2B!'Qɟ{ #@!G'"  P1,Ճ=(r       ȃBNc>'2|v{#5YWCtBx<U2 QfDBBRV58o-.luc8ϖGy=GcU+Od3uT!2ՈB2sI$19ʗ8W> 5/)tdQ HR Ft`o?“!]`(d2aMc\x/0m)L!CBzjB—+?SW ZRɟ-ٱ' :rqb+  0r\=Pу"       <-%nmvk{8&,%oE .S7B9Kkh"YYV^JNɇ]87AHf6U#I9J=5cx6`wBNcFBNa ]-zK :^xoijp~z7 ҴQ:>3cξw7ZX'@!xƜNB?? @ P)v8.rr5      0@1-`׉7ȚZktB"BT=fDh<8R),9i9X7c*nY,Cܚ/EX2L3?Ȏso9$Pș"˕ҋVKSqޣdi2NKsX S"PBwֈ F5JfD8n +[5B3Oîi1c)s 9%.J 9`Ԉ/Bb"ƝS1-G6X{HĒY]I!GoG!'vI$u؊HH"@!(Wr1HHHHHHH &,܂[dqi+rd)HFKY@s C3qEȑX^5U6/)&-L p<@Lb9 gu-nllr+DE=3wW[\:Vx}~]AǙ?rnO(rO$.w 9%.L% 9*Ǎ/Bb"ƝS1-G6Y^`q~էvY[BylWX+A{u wG.T  9y@[K1KJRF# Fg ,Z^.B )x/Пi)H!õ!@!G gm0pNW!' d؝B09 @Vrba% FBi9Q(]HHHHHHH@Vr\"3Ȍ1 KJH)x MG 52;n[9B/LwƖLWqT6 Iv)}e 0[D-~'ǁUԋ;L4DnM|,(,ˍ#V"ј"BØKb7r/  9r9z\$@!GZ|t{qkP2Ƚ܏/cvlVh/ǎ׶f2=2K?;q?SH$NBN: (Mi!@!G -%       XYicAV78҈JP"irұƒo !G}aWF1 Ĝ\Fw4غ:x]Rˣ=VpB!9(hYGb Ff a"0)E™"Oh{DBNAعDP 3r*9mq^ކ{WZ24O󽒫ΉջVeR wb{,+'@!GH t<#   P18BBZlK$@$@$@$@$@$@:խ)ԦYb޿>ߊ,1XdV6cap?9wN@~.+{5 _rx kc48_]f^?^X),,'x_3 KBNɅ HB6`[xo{o-{PۈK'#ěP8 gFp1>!^Ә "!ڰ#xY5+DH!ݙCB99 X+G{' (rJ! \R(,E$@$@$@$@$@$@$`0 9Ͱ|` V>]FU"|b}=sT3_FqXMNh'x55QC񔐄S! u6B9!(hz~r;O$'qp3!ěyGfIRֆc8bN` 9 ^ZSȱB+{r*;ܝ9(Ù Pȱrw  R @!5,EBRdXO$@$@$@$@$@$@c=!x]5iA{eF#iNdvoo7' EII#znmv)ي{>ܙ4ht 9{-rBmN,P2H&(2LO72q0R*fU&chNc( 9^ZSȱB+{r*k%5U|B/ݯ@ gSHPȩ r $@$@eMBNYO!C * 9r'EBΩ#@LǵQ7ˇSˣ%r{8_W`~1Sx[V7VΉ H! 4r!pq%okjz315ǀ+(m y/ )X!ʕG 9ǷJ|pnt#^Z'ljwæ@<@"&^$b0!De}U r Ǯ$@PQHHH0r Cˁu @!GHHHHHH!@!zB]!䬬}d>38O_3"|f9;wk\}2|(7^Znz_7Qg6 9ڈ}[z5l0d!LLL G 8G&g$@!$Ei$@!G0 Bk 9VreB1o\ .4l˷ 5omB Rؑ%O!)2Np"I=dGfBx*Bߘ4*3 rT@b  0r P)!       Pȱsb]s}δ)!H!Grb@x#a'+9r&EXHkvi^ŽQrO&P120mx?=,zt 9mˢ5  9ZtE@x 9; 9FV&|XcX--p׻&Y4#3Qtɵ>wbɄ9'L'@!xƜNB?? @ P)v8.rr5      0@A~ xհTACx6A3Bxyc=6-S$`HS$z&%T)VZ(jd.(%u$gDSSAE GH׭"+c 9e*.4 99d{A(c@lBNABCk=6݀OmuFT*d̹xt1l9FV7.u؊H rgǞ$@$@$ 9zPFcYK$@$@$@$@$@$@0[ȑ2>!^|ng!a3e#ϲ\*!Q7fOO/O)MlZ^?~{~ ޹:(2nOe!;l;*ӵ ]qr" za/%) ct\fϙ4gBE'CJ<,OBNLj+\-l{B<(sP(Ay_q-u wp"gpK9G0 |6+NF$,PXE$@$@&c"lN؁HHHHHH!`#3,GՉ4SIȑ?͋jL4_"k㈫hd_Ǐ7D5Zu[i{&ek73䤁 HB6G',k&f9GJ:a'(`8y4 P)͸pUPƋmКB\{|e-8h2⻖G3Kz.5G"wFPrQH&@!gi6B$@$@fceΑ/ 9c?      (B no72Q^nBN }YVpc=;WF'Ҩ-y/)sAƣsXQUC9؂ Mδ"xOd97V_J'̐SJZ!@!G-Wc_V4עӁǴLF1>1Ƨ}='"LeZ P19'4mPy/ )X!ʕG 9WJM8}v8<ҡWRJ^\e<=d\05~H&@!hHHr$@$@$@$@$@$@&`7Dv74TrrDf݄lV<qq伱ŋ@IDAT6uc kc4n)|rCdZB8BKu/z= (mCwun6aE-FxSDMF^u*RdQ!HAg|r 3!%{l(h49i`: (xY5+DH!'ַbgwM߈r/^!in[ (M @nrrS\HHHHHHr[B8&X-!l}HJ<}g?izdL_L-:g Û{XdJPY|JP)p]j PQK* .ZM9⽱Nsj.l5tJ)D`3a E GBy9q(ϖURO 9MkB6|/}WyU %z)C1Dqu.(Fh* Wz'l0qE<@.ajhzf7rH 4rpHHL'@!tP 9`) IL!M J -̊EvPq(3~AH l1 K$“f sOY#9ەE)|nG#GE6 _ w'1IZֽx$O睓rbY[?E+x<*w 9%.H# 9ht*rNksQ_Q2h$DQOL+rx@ufDȞ^41?'@!9 1 9XHr)Z\k6rQ]ײ'}_ۚ'13:'$.'DFt|rg=ƽN$@$P (BPY IHHHHHH`f 9Ջjߓ@7."JdX te{A)fa]8~p.r)uyo ׇ#ki>.2Rȑrӯ; !|X!4jI&>B $reJB1lrm-M5=uᰋ `긄T*`}ø~z8:FBN6*+7rp-Q)bT&-(h8v8Ê0TїY =KЃYkd֛_?o/o/ "QTlnZwDO|ԿR喙/ཡYa  9p$@/PyG$@$@$P rAs%@!G-)#       )5XvƣȢrZfn%5B3SlUv RΓ@T=lAYnCi;[|ܙ;A!Z-."KK]>l9_V~xu 3&e@]uتt P1>6556aEOy} hU\C,^ߠgc@lBxŜBN1sn=PFqŶV!֗6/1.2 YnK8)C.?@VșDJuM6>_|3N;~v ~r, 6rbk (hg$@$@$' 9zXz7QG$@$@$@$@$@$@* )nrYTţjÏ)lEC}tJ$@$@$@$@$@$@(!OQHibe!Gf)ZQo>fhh1iK`dfL5+2$~rkDjᥒ;Sr!4]NȘӨdimnBNdn43M jL! |\"(H 2x/(XhY -ض PQM8֬!\[BYW"1kpD9>vg/$w+W~q߹X™ߣ)X)+ p$@$@$0OB< " 9HHHHHHJA)EȑW,Vr669M86̌Cd!}r?ur&&@!Go+ht| "suun8e',"P %*" 9Ecj r)KrJ, \fr#rb^qmi4<8ӅSoHXE5 92ڦwae{ۢџ>8݅F/R5 9Q! @( HHH@'rta !@!HHHHHH'P2BQ(,[;knq 185xR֔vS'@!gyFna[~rNxL AŅBb"ƝS1-G6X;3s8sPQ϶S;?:mFX( ?s_DREBZ_->Tȋ"Cy<ܻu&@!GgH $   S P17'HBF`lN$@$@$@$@$@$@z0St{#X'3ILr6eXI[h0_ TLZ}ju[qpu#ޣ̌30ǯG9)I{I槐 0 9%,KL9ȒNϋ)xv9P]]AUr aM%@!TO{AuBH9(~ {| N#X8NAƵlz9R9=x'sfL35^f\c(˓ dɄ5$@$@$`& 9f\Z PJIHHHHHH@'f 9뛜|0`p&GDfBjIH9~-fX㉘Cbirz|` z3)p:ܣ{g %˥P)HqKүqj=.4asסރX, WFHBNWP); 9"rԱs|倒!g8%w5E!Gγ[۔1m`` g޻̸ } Pї'G#$@!' kHHHLr̤͹ۓ NrtZ2)5Z:RK!!È"ǍR0JX%/B!ŵf#@!'sh{ۅ!fhr(X\(,.^PQ)wΪ 9X6!cY;t>#Y/K|l#^qֺx '8%\kЗ}yr4 Lr2HH$@!LڜK+ 9Z= D@?9<ӈ |jW9BNDd bFd3g#}p<$t*ٸa1c4ao4 9F.5%q8 BN 9B P)~ XFP>&\X[>(䨋o VRl3r6٠9+e !ҿ_͸ } Pї'G#$@!' kHHHLr̤͹ۓ N(ymS{i߄u e&m#E8SRWrt,HB^[SAL%@!TܜrA;e8Ѭ_z~pw^_\h^[<qGqW3B_rH2 Pd  03is.(h%$@$@$@$@$@$@$ 9:,a[BN[LFy< 93b&@!Օ> 9#pyrg$\txPQ*!'PUUѩ Ns{2eCȑkr:ro !XvSKSq*'@!'vzl55ٞH$W2J$@$@$@$@$@$@cڒ^Sڦ,|Nw*?wMkBQJK#"v96*Z\."DqDQQLO1%^HrNKb 9%.@r (^P8rBN9Gk(zc!֐)<ş^+HĒW*HgÁxGv+]zps?:+#@!G?H ; 9ٹHH"@!,Ҝ'r>$@$@$@$@$@$@$3*")DKB܇mͲR-NCxh brݱddn%^QyGIBNaqsmh7bݚ6嵢ՇZ+렑h C#{:a N"em.h@GcR!&$q(?\A(ƐUBo 9EkB߿/ؒ̃]_vBU^At|j'Y2)9̎]FBNa؛H`yrg$@$@$`$ 9F؅S(A'      < )]uyԼn3$ q4{5^Ek}E byaisjdž8'bQ̽B!\ޜMrg*ś kW`MXvM`)! 1.؇HHHHHHt @!'"L&FgY%l9͍+9 (,͆WHHH r̠9%@!'_rG$@$@$@$@$@$@ p9 B5xEWgq~ '2NȆFdiovcJOl8ֹ\,)FbPzVXnZ2 Թr5BLg.axn 9尦 7xY5+DH!G{|+p̓]brѹ~8i.!'!%ꜨZ" $bI<<Ӆ?XД:3PG$ABNV (䘊i$@!G#06'      )|nG߯ gd6wNîsH>lmNb6I/#ʧyC-hr?q} ^íjJdé ɩdٵL6lPFu$? 9m";Nǖ,}P?⋖3!܉k7 %,,j'ʍxrpCB1\9({zVVjI!JѮ̽R#"CqcXsŲL!r7p~RhjΦS @v'Xe JBx9x(IHHHHHH _f 9;ZeGwf _{"uvE0{҅q}P1F~SpB PQOP/ߋkږtc`x I`quX7BScťpLi ]jjDZCбsjb W9qGXr!@!G=g ԳRK 9VveBNq4z8ŽhXr #.e{Lq!b!8K r ˡIrA   S\=7 9* FBah ^#!-X |$2\Ȭ9^gY} gopb9LNo BĹ+ l? !-B!-KBβ7غy ^=-͍H0^/&n'm^{I-Ordfoʍi]evMW g{jG|r):wC㹚(C!@=++chW^)׆zzc;:>MQ])%Hf(ꂌ%KqP)wJV"@!J^IHJR 4OB< ( \-Bru wY*5"̆ގ"NpZjrkʹ3$S1<s8>qMprq9>j{DW_گdk|bZd- Jek͆=6đ$IrGɒ37 g vloCݒ'38snκVGB~,9RPQϞԒB]{Sx\^7 {> [Zp[I8#3xr)>n Ms P17g#+cŨs$@$@DBN)EkYLBb"<'      /%JC: P)|P  & Z?njڰQdivap\^KhBx#!tODf-*-B  PQvEȱj2:In|tffCV ;/2\9} QkK:gؿg-'[D"W􅛐{X#@!8<rԱ@'+cŨW֞)OS|w{v6޵+u%?ۇa ?3]xt1ffG)3 rT@b  0r P)!       >clZ(_T[[1fe"!8n rf{ gg-mpd~mFq N=)3Pd 9P(TB 9/%v=Y;D1)^w-N55Bنvr. )ȁ8]d2;_^_VJ[O4; {Jp.Sqdr*\\lr@)k4q R9C8ֱ/1L Oc?>C*)ya)rJ! \ T6 9_HH P)Yyr}HHHHH\{1sT}usl%GBNɅdYjϏ65*yBr~p FBI@i)pVy M[63.']{ 1G㒴,(m);'Ցu0v8qdw#c8s=X|E XQ)zzp <Mve"hkiv=ぬY 9p(%@!G qb+ 9VzeB1t{h܌mHDУ56ǽ8C_(/Sfb+t}xz{w1;%DBN K! %@!Bm  9e*K.B%M N@vA8WAep"@!f5*f/!.óq\*rNayPdY '&~u2pz1!qG8R*-RSQᚴVx@Ȑ}Y;N G4˕Zо--.=M./,s(gŖKB^[Qȱb+krmd[+%"s+njc(=K 8,fkztᩈ"Rΐ/ 9c? (%v$@$@$`  9pGB$@$@$@$@$@ 0狀xP(rrU 9:;çy̑F123͡0G00Ldc:> gl8R$1$S1<s8>qMhS(kyrI,~xv~jCrˣB~)Ԩ)nSiؑ|j:oGiNsh_;^}i6[F)>O3B?rcɑGBzger+ʌ+we. 9l$`EruHHP)hp- PYL$@$@$@$@$@$7Y̝ 05rf\㕃#39jAq.Em]fRH\dgH"hSB SHMV`ٻ҃7ӱ)*2sMXs}0%dDGh!3BQ%YXfޑϣ(:GB螈ē}򯥐S1(۽E/2PdrF, G+Aϗh,snW|UrjF&qFd۹7+#@!G?x(g{zVVjI!JѮ̽Rȩ̸rWc.oFV$@!NJQIHJRײDxN$@$@$@$@$@z˝Ȏ3%XU '33ˬ9RΑ5:ʑaga7Ka4tݓ2NEF`nB!ѯSQm{ow?8qm[L.yy_x.r:RڷSy3}mʸ Pя%G* 9^ZRȱR+sr*3ܕ(˛ PȱbԹg  R"@!,&@!g1[xIy>L"9 XEwps>I@h s?<|ёB ?*%!GupV6رžnE8i+q tb-đCaLF.2N)*ŋ걪>VKƃ ɩ'ŝ0,;cB̩ i 0 9ꃳ͏`p-tg\[bǶBه&7:)BN(Ivi*eg/ϊl;_|:#LU4rԣ@=++chW^)Tf\+s P17g#+cŨs$@$@DBN)EkYLBb"tMDMTd 9FftMu5k"#nK2pmc5E8'v`;}#8u& -;̶kEh7f X518rcˑ#@!G=k ԳRK 9VveBV/a}ݢmZ+C#ҙ aP1 -&~HHH(?gMBNn>ZRq$CHNt!1rHN_& @9՞f؛akMԯFH $` ?ax"4s2 9L,ZSl!G $'[w."Zp?ALE*6nscs6XU@ȢSpR|(Np} cxd6@8deFBm Ŋ6F'8u&?)MxH:vnJk>613nl'wlk'ޓqYf9sQ8Yըذ P Bk 9VreBlce{NEh 05"n))X/1 MB9 ΃gEBNiŃ)\JdDb>WԌK>TV%   T=Bc 9Z9" T _.gpmQłrkmԶF|݋!LFI`f%H.[Ȕlkqa׉:BTPgكFwFx4Eu#(IxO?0HoHH,LY7Y^(jd.b@ᯕdLu_6$  (>Upn[86-RT`!r$Wb;Ca r9i'C ";˘8ƒ'R&#lL0njp(`ZE),< .siN+`8.? V|pV5ؕ9[J V )Y@I [d̹3Fs"s39'%ZPȱX+prԠdٹ}B3CL9ãBwqxU9~oBz !zGOjju8܁֦]} y/ 9h!@!G;w 3r*9mqUZSȱJO(r&r[g&   pWr,1(٭S)pajŃ=_ 1vOM!  (AUF8EϡAH9̔SQr_N݅ߟl\<#0[ȑ^̞|k3JLdM^)2_dd"rF|e MNlu0nq_:򳟥HT,~xu hYU'$-~"lZdiۮ.Ð||*#'9[drNBZJ!bBiٍPzaUxHV 94' e7*2L$qn޹)>q҉H$IڷE_^G0vu:HSTr@;JA!kQg 9xY5D$c!'NRUrf  \τ!g$wV(mD+w~H' 9)6B|7\_|V8w5)CB)TH - 9ڃ/Qp`޷֭\r5F 5x_0u9wnK?I10=Ø̈Kªr$;tD¤wUYޛ.﫫 Eqh$M"99?u:#HD}y_YJ;;]i0^DΌߒZm39'}y]vwf^BN2rGε f^>!r3BN~!/fBE}4@l'0!@șI 9pTb7ߒRqGHP FujKU/:\ ;Xw?QͣRgEɝ{) 敝mVURu6p_]7VUF4&5TE*9<߫ϪLaűĥFٱN"PX ꂲ\[ҜdV]Q]1s,9s8nKΉ{BNgJ!'XmZH8W. P_ e6&usGΩT硕BNy2=r̵ ?^~荐,{{9!'?^~鍐LNTҦ 3   ڢjAȱ>3G!g>BwS V* " T^~@N9C͕NJF!'?^mH߻P o?w2ƌ%ܰֈ%ѦV761BϏNvNl>nϗ5dpˢZjhIcHMjV͉)aN'FıXrΝq#3t\, ̙rvBN25kjS%'6ՑtU=rʊm";hSO?eۛkE/NrRf"<[ұ_Tt!@IDAT:rʎ {xgB狣}2*BnV#"Td~&@69y̷K+#"@JB*bnUlUK2&@,|yROC#̣G)|ySvYr&7KҰ$TO\w/3rО/ӫgxo4~A$#l\XjN{}pV)0+dLWk(rNuYu"lf 䞥ښޤgnqLt=}d*(vu91wB ESO?eۛkE/ۿYjw~;PP P0TPmH5 5 L!=P. scs_~(@! PB`?U|y4_&6 o @6ۻ=S!'~M32 r';+z:@*6d""@E x=k劗q}D`e8"=xRr rׁv}sYv`\?=ۣ7|-TʖsAIGM_MLq mVHKٶ6XưZjeUɧ'z88s99'9cszCqzo>9t :mdæ:us}9pyQ~9gRD)%Mƪ7-jT˲]Y%Ԅ22N}KZ6ɚ<4A'2c2N~g_ܣЈN3eBvwvq`w@=\ rg姞9~ʶ7׊㼼TgĜ%kZunSmI_?ԥwsO6rl#7>T﫿Srh؏g ?Km«U<t9Ӊ޹)EFOҦR  jwPՍKXV|ɤtsTUro"N_?*WVk`&XR8׫_)ꔞ?FͦzN:0#.{U'znH93 qBN24 !0!S!9ܳ)@{&K*1=sB +x$:~?sRX@@ mWݮ)tOgah@'JqX:uQ9S =Ok}c4~%tݱa7k%LngOuɛyY}YSH;eQV :Kj2sP\?9ӣ?]cf"ϜKK!'7PPoӋzY"U _ѥkw5:Lj)S L@-q\ r^9~̺֌|ַ/olWvEѡMsF]%ےcj&o wT?}e!@$~}k -^X0@ș H 98?QƛN @(eEyFgHAIoby8GW9oB?s]Zd'J4]U_XݨoֶF&e3PJ9 4ZF;os<Bd@ 6c{a"0J5d*R܌?n#czl>'޺~AQTBr"]SO?eۛkEq_^[6j9U|ɉ%\z>Q/݇ʶrlCD-W-2` 04krfQbb|L!S5bTt51( @r~@cC j*9r93I;-Z!;VnYi*/B&BnY|h'b*lnՎuZ eM̹;OL?]/Eg C!P99߼q>.68ڍz=vϬh9E#d@= \ rg姞9~ʶ7׊㾼L_ٮxp*9Ot'uL$ݷHE㲄.\Hq~sFO w ?W۷g x6[X:1QOR*ű@8?Pmcn@i g+~de !H:B?:0UP&G/iAU}fm~hq]z2ă D)]6T,jP@V.F!rrzZzٌ\Qw/_37 x<>YBNZ;+?DSVwu!gs.9N@ D;rJa 9 tW@C|Q[_YL(BN9:~?gBf @1nZ11 $SJnds׌nޗ!䔚kdzSFNDsTyT@ %|es~w"SD6Ѕ BSp@KBh(h 9N@!'Hwi-~L!n븮~N=rG!'3kA!OZrܙזez{\ 2|ӜsB?Ϊ!`'Ј2 @@|Q[7B /I!Ǒi!RFW}.C qխT?^JY#.<"(&tG A)JLmO(4翍ma}PkeƬ G'tC4G!g>Bw:3Te>CרvA1mxdLq!Wr|n.!'r-ȝz")\+B;ZT}VϽ2 attܹHEd*\J moW:6U6 @jwmQ۷Mܹ<ϧ L3BO7* @ș@qv|G _:B`Js\:tF<̼"̋/rsg=tgHt[m_LV{jˢ7U[L^ڟog$ 3 @@qYqr*BN8 LKW@qe w?7FGu:saGi 䔆#@ :rd^@JG_ݯ*6>K7#Ap9H $zkܫ{Y  'ԶvǷUNL``X鏌 +E)/_n ]  X:̧k$K>QWAնV}Bw:gN!"\ B>Bl9(õ!=gLpLr\G~f~L++ep@ck?hTL @@F-_3UU=B`K!g^DtpDEO:!b @FUn%qZΉ JyT)r%3)|a}v-j͠s^=ݣ cJقªFbm\ǧu}llrf67@qSՉrbʗBNr /gVu-::=s.`l0rT9%0@VɁ!NgYb' @«[`,ѭrܚ9|Vcyg+g TUG&] @l\긮뇥3Qr{;-ޞzve ޣ>5_wNliBUںVѦgW4hZYq޹1ң8 Fmn"_稩;ޮO,ڵ'σ[rr%5яkA~!Yrܙez{i痷ιazNT9%0@vtү.V,dr{;j}c[j[jC3K9Œz~_ƕ+aܴF_ڪn㘹^>%K< P#㰄NrC־EK/ Iwz+0DWZ2˵ ?^~荐,{{9oӢFm-۲dʇu94rJÑQ {IRTə= @_RgP @)-OF+BN2 8j}Ku{cC$0~I~s-!>N!B{iwv,%77jwTbݴ i*Los~r[7zcws@ș ;\B!'D=>@M:t )ro!'r-ȏz#!^#BkUnzХΛvߟm҉*9Ozl @~#PV{7_Vx2-BpkmnA ;!gn,LIy=QQR2N69@&p@_ܪohS3[*\[C90b&fUDU-ҚF-o 9C3kJ;ٜreo!'rv~!Yr1ׂx7B5"x;9pf@`@[KCV*q^@A rZR8`̘#S:TFr! \Bv*87?.w@wM)NKc/!~n!°qasjRSTcntnF7T4iMVU/䛐yD5Fbd6j:-og<{h<7 W{9J!'+vBN~I&x7B5"cCo?dkDv~Y=r,̗]_QQN@@@ T75_VK82CA<rÕQKL 𔩐cK% @p< !g*Ј҇ISSNB%<^)gs{lͪV3`Dqk$a,ag<qjC2ΒP*ư<Q8ug?f@ș .#_¸ ;?^~荐,{9kA~!Yr_Vg{83  )x\#O__G[  jkTn|^6@ȱ2SO  @p@H5_Q*nu(tovU.Hʱw̕r,`^XݨohIߗS6Lsꡑ{U!} BO@/܄/?FCFr̵ ?^~荐,{{9/B=J ipݣ;?鞺w M*Vg/v3yJg޼$t 9?V鼎3 @'P5y|a%`Jo(aƂSYRBTyyM,auKDySdLاG` Pq nΏz#!_#BN~9Z/?FCFoC!$ۇ5ƇJt@r"P6_ؼiZ&9G'8B@ Ht]4BΫ?<1o_:@ -U՚ 9փ $ҍFH97+_6!TzJ 9z#[V/nlŵjTUg,Ӧ"3r8e r] !'?|X4A {LIuTmWŏ$XG x$^_B3 @s@ș {r 7cADCIBSMjmYT=굦5,KiVٞK˃%R&3DF9`D7zc"&u;BQh(?sY]N8=XGP2}w$ksYnrrD/d# H'嘪9iK1R)L~62'ی Iǩ+#.@ O!#٘Ȥֶd)Ս8>@!Yrk @~t4 tEȩtgN̼ +_D;BL&N߲ha^xn6oX*sݴfI8=޾i{y[j9&x S ɵ8~>!Dn9vg>/@bVY @ w@qG|%BO@ 8,}`HOK92}r*݁"80):9KO#3 Uڽ}^>TɉШ)JάJ!D r*ɹl! -D!&Li9N/ @ h9N=% @_^ȘtCLu'y^r*݉)- .&3B%.\\]^9%'Sׂ `eP &{a9bmMDݦms:t^1gvO!xPy9A!p-(ZyA)WFB}ɻr[V@ @r!@D Bsuɔt硩sX:{UJnj9nVYcEș!g&d'{O!9-P(v̶;md4;t9x93d@ȩ| kA!s BNy2}rcL%ܲ2@ @N' _B' @r9W6pu+i<>gW@qlj !g&qLؒBNv>u>hFyzvgEcFȹ#'gVZ -H!F%kA a9BN9r*$%@ @p)&oa#- )OYc=JsB:tFs'w Q#̄3 [@·'a]mئ{̶;m,9GO^;'S]9-+ @ t9Ne p"@K!ǿu#J["λF+6""Mvi}qCsYBET :S&Rz0דḒIH\҅N wK{ ÙYG!|ls|. u5JRܨۮ[yЩsWÎ ϐ*O!9ZPY!r*IB!+d @G!}9e9L; d p"|B`4*oOyTzfW@qeBN2a#ʔYsX"NcZZ֪VL<7ANJ` #ΐM(s'g1.3nv7w%֍PPM]mDHHjUzNO$ɤj|3'GXMVjْ7Oy=2:+ރ'SrJ˓*C!ܹq%g@ȩ$}.RPd @!@ TBN3srEW@ x,.'.\Wҭr GbS54jz4rNv,v߸޿=CF̹?| KN#SX7^ԄԠzhP[kZPH8t,kc8Fd^Sg@}CUƢ)rcg[%O!rØkAy:qT'f!-B`v9sa+ @ BN3C  "C@\J!ǥ+e[uү.2U4^!S< $SDZx֭^)IF)UK&Sۏt#=XT3Nr a"Stp-(K7llrf6G!'?^ @ @)KF*#2eh@ 8\k#3!;BNajl]h6H *ܼPGN\J%@F}n!SX͋G!x1ZBjC!<\ @'3?#z8B@ @ȩJLknbԍF9$]!sc%gN{8`)\]ަ۳PjҏNvNE<rn@?E`nZPKsCNX%Ⱥ{zjTm3k\Z<ЅKt r}J@!rOׂy/gkCGYey 䔗/C @rf@qP2 `3Wj:JxЩ2ΩK2wKV*{Eȱ fAșH7۵!pT>uA r*/BNvjUL44<ށ$32ȘqmXB;1[tը!#4f`uv9`XGO^Թ7g*!2ܙrɵ f^>!rgVY^9 @ 07ٰAr B L!fIo;RQ7/B}>BDjk}[$FoLTqx rB(BN~¡vmߠn3sJY"Θϙ>3Iw;?sG3N|nĜU+kӆUZ] Olzgl,-d@ɏ;ׂx7B5"x;9pf@ @I!g&8BBH  ))Ҥ$+RF);bL3= m ΝqLx-$ @ȩ |. 0.YԖq94ջqMSqrUyzLڤ-Ϭ֦+YՁ<[w'M 䔞)#O!'?\ 9~Ȳ׈:{ ÙY @ @`&L@9L !Al"cJMc\+W(!~!g"1Fٱ.a 7a9BA,@ɏ-v~Sq02C#L3q>>*_!dpH.s{hO7x~?tV]\f)e@;ׂx7B5"x;9pf@ @I!g&8BBH  Dc٫JqDTnNʱw9 9A?طP,lKd#Qa禛AqSu69Q}%]@լz3i:.RTʙ*XE"aڶ^ϙX'MTȈ/ޜ%&Sb W9cZ;+?DSVoUK!^@ @@L!!4@@ p'$sdҵ;r"TfFșHg6ڵ99OW1q"'f!;-z鹝ڼqլFu58{EuVcImS%Ispκ7{ k 9ǹukwjsF0P64K;њ%D0 JGzT)<^kX5YPٱQP%&}s #E^>Z5KL%9v @(5Re@) V B+Ҕ{K7Le%RuEZ̏g͓X:/RI[ra]P{哅_:|׿'0x1/nEd14@|>:yвرu>5hU9zP2X! qp6߽IU37{?E pկFlAQϔn\1Cs V-Ϝ#UW_h @@ 䔟13BN 2 @r\V{'z #w!gqCHѦ/ojQoLr9C1 (`9@G@-r`iN}`XϹR9<79mM37y?2{]1cJG!t,rrrcϵ 7N~셐Ǭ{k9' pgV@qhb  Xf@IDAT@rY !c e9 < ]o>qALu'GJluAن&}es4~Z` K!ǽ# 9 @mzpo0>~TBdQیFgC/ę3trJǒ*G!'7\ r^9~̺֌|@ȩ wfu(& @J!ǫغrrHP[[3med|J!K)a#,%@t&X2#Xِr5=hTr[g3 @Ʌ}L!'D!=6Yz^Fur֭Yr.^0} E3BSfcC 䔎%#UBNnɏruo![d5!SP9M aA xBW3u!dOh~mTޱ{IS <ҩW:>tlHA| ~:U |J!剏 *!-!|p5)ghϲzm2ϖ3 o=FA 99@ 䖞U!9/=7{[F*<|ܝӀr6mXϼK ۚg;08CLP:9cH#{qc/?f[kFV>YMe T;:BCCX @^%zl]9^PM+w,^#ۤ- '3hÏ2Уsz||ݷXD!N͍U#rsIe"`^RSƎLH8*F h}IVD,i-JQL::O@rrE7@-5U:/zz{[=N5R9Vm01R]]͌yj==dž@)KFs-ȍ{!1Z3Bj*C!2ܙաr‚ @*fcBɞЊ9CTI^SW쿭Xb< @3 d-k`֝U!KU36}C5v7JO{@'r>Ats2+R94@ 'v 99D'B FS L1L+04O 9.G!"XքUWWiJ\HP(k##\q/k?vBNi82Je ǟkA~!Yr_Vg{83K $Q @ 9^ɤׁ= 9NJxS'uoUFĩ թ*lfU7-Wuj(n0_:mē JΏtjB>%) G <1G%sӡpGK!ǹ!2@qOtv9skk Pwʺ!;[N]rTTtglB[tҤ2N{{3_ꤩseETǙW)#䔂"cTBN~Z/?FCFoC!9.IaB xBW2u dOpBNν؝ުH QhWer󎒎ho4s)? @rA;)}hۡQKxp儈G!}9#r]sS۷Em%,CgIlBNlNjT*m^>~AWoS:mA!Qn9ZP7/ŬkM97-peT@qi @rܚ9ō=Nr(5-l5d?+}@$мŤ3~C$,8BsD'av9̵7i˦:w6-BUMg@'^ѥwdUءG!>T>9ZP7/ŬkM97-peT@qi @rܚ9ō=NrHvwYg2_Q5b7ڏ _9̽u[JvH~ρC!="R@qnn,79qW]]vlY}6~.mrF882Μy(re\; NkAt$Bϵ 3ךּrJ˓\N! $|@ @q[|/BN;MQU@5B{~@1ku\˿ڏ _9}2)|0!\. p .9:B3BT@ɝl=mڌҤ@`ÔKȱή^>]WoS<-DBN3-r̵8~^8! YrV_9(!D @ @qK|'BNqB 7v@6B/2 YUUMG811zN)T:>jfMŁjUg& )iDt"n"1ϕ@H&UE `TɸYǸdd_\ٻ=T qyPuh✱('M5){&~sތ)m7)S%©qUFIT Lmd"T*2X쿭#YU{2Nψ6U/2.Tqyns,ȒCc,#L OHFl #Jf}b^w},1Vֺ2U*6L(#U&gV% dr0(9p螐f\lug网 7P\W4g9O[VgLْ\!A {ҫǤ#1K A@) C@B,p;d0֊e-_ڮY۬V*!qF`*εu [_B$JgR@) IQrܘ5bL!g2 ^C09q(@hbY @S 8535B38R1qjw+ΈwKnT9ɛ~Llߪy7O bK.-JddēŻ.)sռ`llUd`z6be!8b6"Nq͒e&*LӛUFh^mFL:YMmB*x?V,9ħ;?FI^`u.>TWF dMsZ%X7,%#\3/)}ٜ7&Ş7F%lƜXPڟO7X\M%;rҰ$SNs2,'Ogr2T)*~i+#;\g=ͿU#gK91r~#}pJz<M3 P9% >'G)mjf[L ۚXG=٬ߦtӬix\#3ny~2;kdl|J!) L!ZPZn ! Y"lrar#'zBO2!@B!) r3Mee >e*Hu\Kߜ;`UvDȪ2bUfUqww7Nj .fHsxb*HJ%3q9'gb6BݏPq:SuFyYgLO"jST3bQ+ Ey5EbS `cVj>%℗0ͪ<{'(rYWA9۾=?2[UuT'Z#+Eͪ3~Cnm*B0|޿]E5}=&3-ϖ{3U>_l) 〤Xo!@;rKVR99c̥!SGhV-]ܦD"f,!g߮Mz~VSL꓇Ug|jW)zcU}I^Sd×Z|e*Ȓ7r rB -ٕgsۭ̅5V+n*Q*:9 9ы?ۿm-$BNG 2Drzǭ@!+ \ @BNY9& egdίj..His*\ݓxUe dhSo|!Hۍըcd!9ttj*U14n eeq=Ī,XSr}E3 RJ>jO2cUt\ߋ8]EᆻkԤY/+Px"ڑưnu̻td <1a0u^3Mvb9vcRaa7I߷9FRMR1L}h'){ߛXged`jό$vxk֪dY2L)0մ}ia}|e硿=.?tZ̖>y.OvowYؽK}ow8Kc=Sy_ 1g-] 'BN>vJwT\Zd>"Y,U;"䤳dXRprc :9K4W"iID !@C!'=Lu&9卋c^/Lgř_*SI>uռ=p}ߵ{TH9-봃BZc Uv0rIQJqv.F0ԩte.'ȋ3:0nike~v0g[t}pٲG-]-*4ϖ]xyhG+q5y Uyoȩ.:M @ rYW BNY93el@VӚ-BNZ+K^a@ 4E!'(̛%9Y6v$ @ '?i2W`rF.<`Ė ٢B0$R+=Y_7̐v1"A}vxGL'k3>ř_x!?D^:u(34) +{L-ӡ"&>5dJ٤~drDPݻX*^⺆}\?qfJ{G7iǓm`3@MP%4jR?S;5*w--]3vF6UW[a骛!vtT>zd;UPi󺏆\Y^G)oֹvlk?/lg']){jUů}o:'ߣֳ!i-*8Ul1ݠj-cl, [KE{{KA rRYV BNYw9#eŒ@XS.BNJ KZ@ 5 D!' L)9*7v"Ӊ!@ +_q2YPrzrTN)~}F*,+ /8^ _3fU9-#*ph~2xļ@~r-p]EgoRQ3T^[ U<{TZ˾}{/>[er2-gBNUEE"w׾\2G!'s%' )C%*nK!5)!d+_q2Yr"Β#P/rzǽ @BNȸ! 9Խ 9ժv1NG6x^?st~Q>e8cj>%C\xjhǖͦc */o2BN-tiLj F&?ca+b^Vw;۝Bܤn#=]TVeq(e?Bv'.-*\8V}D*[]T^7{9Ld! Fk1uEF.v^;3`ϥ+ϖOV?gl;/gwQIlDG~# bhĈRNըȦHyb*^1J~ӶSS۹ۜ_3]]ksҩ!#87~t';iW\[-JOgՍH%(lyI;POI;`J#bB" i#G4\g9Q10rbZJ Ĕ@] <@!&\B $Pp8  @.@a+$B{*4'U6Y&k`Uvry%%B-[p'wCk'l~bJW2x7gU|јgKuB[1i1yyxrjդJw[x SdhSL#㼍3ZJvvL%*B\nGyuVvyV Su&o$eLy[n3>[8ߔ+9Jm}#cjdBNfJM@ .SB!',b9).nRCPI59`e RK!'%@5 @ 7I!ǝv\iֵ1퐳]G6I*iݕhR| 1uM%l;.nz<^j߳;Q~v:: 9־}o=[~z(߭کƧl~Rgt#]GWG}J#irDTuvPd]fs@@ 7BNJ r2TlR BN X4d9!g@I]I3BNJN@ *S&BNrkG @$Ȳe/hVȹ"lV#Ԏn0gǵˌÝǷi㘮/0x7Z> -Ȇ1c7jo韯ad#Aqj4j9Ͱk+O)uEȱ#KWli]泴sߥWG$(?k}1j޿m~+ :N8{gxrǶ[Lע^{#k"^ X{oϖU;n}.BϖUZ>[9WRYI7S΁]w 8:@ 䤾$ Dr "g E %(^&BNY"rR_bBN7 @ NٳVc5*:]53}a_>a4*BOPoRݳP,awMyv8O*$2~GOH8qZOy mCHMr4|IԮ|Bq4?D FN"ڍhd˫WDKn넕z*)>|7qK[*psZ͞qҦ֫2/xrjWj6nl?Ogr̒}݀{^{^},ٲ]-w|tQT E "K։RcBX% r.'O!g3rQH.֎/@ȹ̂OP8@ȉS5%rZ9BN X @Nrp>VrUia^௟>\NT%'K~zO"IxsLW#uTK: V]/GіS&м8}LGOpֲN9{IG:s7AawJ1~k_u\տs=p/cdF_ttF^S|F+oP)hxrT)MǷ~ 9Y`uOwߛP1~A}gK9!vJ>X%r4RT,@I}I09!@f@ 3@!'E@9(2)J!'PL D 䤾$ nh1 @=@!A!ǝW!qrͥzrN~hJs8ef,¤[$MҴ])yAt# Lxvgvף>9}ɟCюBřнOqy+V& j֨kAS?IJkځj-. {2x7.\Lﻮ3ދieh*wjVFXc%]1+<{<˾I/blnTN]zdrB%C׋FB\ ]9٭=G!? hjz 䤧Y!''w? A9$%}N T<|! F& @W9^I1.R9#r)W ]_YW)s7ƙRs7RY>r6umэH͏joLsDe'%oJ3+~bXճ]E1sYmx?Um)8ʫڑuc ާCWȆTݢ8 !C#gί%>vǽ&'r.,*φ_m{N,ثg 9+؅2;BNȅ}P7&R8A {rWs2BL1\9f@I_MBNN~@&sEA!' ꬙69i(D!'| @ n tK@qs1wIM\a?Cr\_vLyJx8l/ooOᘗʋSOj{i-E@4A*yO|qM{U+1!տ3't-^ݕT9z̊CsU1B -Gq]7G3ӛڔVXq 9kt"}¾_[ϖ!lYϖ-ޞ-Kr|ivڶ[l-Rot@rzǭ@!t9I GM!' rY&#wtԑ,%-Vp @N!'NI~9#g<${a}Aځli?6'C* ?3k?&Gl^" LԮBwKq\v'(%?8y%KG7IyE{㊹9vw#۝抩t1~zsb۶c:8[Uy"4)ؿřsƲRZ;DLȹAuﵣS[)ϖ!' g6rSv̑f3 X :er@ 1+BN뛕rRi BNPd7,9af4@Isuɭk9]#@ B!zwԱr4L=}ߕ\q5Ʃ]R^{zqOȄI8Y>)/W: BsT| ƹDN]RMR|* S%?p_ډt){YjG uy9뎩YuvMIԗ&0`BNY r2PdRN!;+FB @9>@d 3c"-xKHN28nkǓ_y^ȋ fӐkH.*rh#'ΐ>L_3]ED;&Kްq^#iH(So"4|<㽐0MFF*m\nv-w8Mb$u8 |i ?rǪe#=R/ʺþ뾷]Ϙv>sϖQȓ!'Š+,^#DN0@z 䤷dXR0rʬ!Z9S4W eBNt;+rRiD!&A @/9~d@ ㍛7&+~ }5p[J0bv q:Z 7: k˚wG=@IDAT$_3Usl_;>raO5Kldd˫*5E1]M^i;G/'Mw?9wm)43Ϩ SʘNXvyEJkS{0]zDf*îǺĮGAYr0hiv({Ը c_)g6))HDVpHՔ'>sVB<-{rW4fƪSr¤ZA@ *sfBN*Nr\p @~@(B!k܄\qH~ϖr$w jTe? ;ɖ`qmc-*7TqL. S>%itr}EUѮ6U!ETg)}tM1OkU=<+F& \+]~T*gtf칾1MLnG|Bg:3#⌇TBu{h;Ϋ8Gʦ#wv}ծJw,sfjǒj;N5VvөɗC;~uOsWTZ { 9{DTr_OՏnP!Oֳ/_u/V[yM)Wϖ-tgUe BNL Կ7뵅"i4ba@ r]?xԁ(O!gB rPErBNY9~Pd@  \/ @BNЄ9()Z)L5%RD\0m^30TxA ÏÈKq#|_)5[n[_~i>?t U]8[U1k\qHUfj8ĪkOlo1ڣ/R9 9F xK%Y:fOnG%)쥳m_Q[*e- ?ӝEZ{4St\)o!BN~͟*_کid|3q}㳥ϖZ|zf91vM%ҵ[[rEI(HD`cJ!'!,r45]阔7P^K-׽Y;~,}nq]~lQϋ$ 9׎3=阖7t7#lC-?l).T-`S~!'f.kgzSc@ yrW3"Մ#/FC`4DD9I1ljBNA,!3j \̓o' @ @a@ 8덋B;X 9櫐RĴ\ϖS98t}[|pX?nD߫puNsA{-#'; ڡRZjL._:wJi۝RL+;\5/#ϰ 9Fr:jת򜘟nVbIvy:g:/!U=v4K02z%?AΩvr>,{&;zA~ ])cs"QG۝ܤ"g:kKI%{= ?R_vxJ]34ih,5fB'LG#{y=Ѻ<7phy}|^#W?[yEzw31 9ɩƗBN|kCd x(8@q"$@IR5rXbBN7 rslF d @ ȳnWrqQ)L/櫐3!+;UXk1f}Q~/ۂK~FaV"W~f߸>bAq.kUbd/5rz8/X z_qf,YLQݻXJ++!Gok;R?MXsD? C6k#T띵+5~ntg.MF*tdUΊك#";n@~z[?ͽ{|.B ~@;LxP; 8wjjnMþ_dKKm}7]юJ=[]x8?>[t{\$z;%2vι]L',ĆBNlJA &M! ƏA!'u @In툼E! ΐRD!'E$@ $@IB~c X 97rf}lLW0lʦljWo242p\oCBO&Vue{,$W8E֝ĬcUXU NR&Z>!a:Ati=]R#?a vX];mW|G2! rL-[~k~}]]ֲkvg(}7 ϖG=<[>yg˓lxOW)?"[ڙnfJ%4ėBN|kCd!Zi{9p^ x%Ÿ8@ȉsu- rP%bt#FkF!'FeBNF M @q!J+:X 97ܡ/Hok#1]Y/?5\Z*>ԏl;muo&5(F"r4cG^r c.;g!}hg(UF)ϖ/ϖK{$crb\pK'D6c,A rYJdՋh@˄3BN7W9q q%BNR*ENrp xg @@I @ NrT bq$ƾG!tCaK k_p4s ӴɷWUp6U8W{k7-ڽ嘊"%u, 9}Q^sJ0TLv_3]QIvt׾ޱI%[>/ ~SfS&6%~hԏdw1UnܜS(&)Jq#ڥeՓ@u")~N]^>^!L`b*TY#+BΤdH hWÈ2v- tt[psSR?%TkK =*\Z&KJ8Inqϙ}2R,<yB(.#9tmi1Rv.W!ql[>F6,#;w.$4jbcl7UN[r&w,yScR#u}=̚w}CKu3v V4@cr֮8fЧrX0c5 *ygdß/vT!G2ཏˠv@vb!(6t3]=[l|xuTwݒ.OBN6B&zKS#4Q"bA!'e @Ix _rBNo;rQH.֎[r BN !ErRTLR @H$T!}Rȹf- [*xl{ݽu^T1ǵSgN7*i?&me/'aCv/9BIe?3druj/B-ۨT[;\lִV)oxERL;^n c~O*4yn8+}G{_:BI8u-f<Ѿ?qa߿q_*y ^$ϖטRBFD_>z2!A&'} r_ìg@@ ǁBN@ I&!>@rzg )"b  @@ $JĈaQMViSFRZLz0 ="WrhwRvxS?<$SzO{hTţl^Ʃ]2RRo@iq]NAedv ٳPe-7f+2pEzۭ{Jm߇6zF3*BNk?"}GLW+{y3e}yhܡ>[ް3croΊ|JWc@G91 tDĀ@ȉy/rb_"@!$@B .%BN"D1'^rj @'- tqS}Or[ۤ]6k͢8m8 gnګti+oIu;޻m\S-̕\+YكT/O2«S^{$wL'X4NPbյG~TK2p%:L,EmKOcn߿nlg.rZ-*Uwm tnevd{gXK׉/',x…@rgΊ#f-#U|&7Q拂BNY3MrTl悐ͺrl '> @@ $b!ǽqrLF~~:8`UΪ|7)oXWry)\ / olFw|TQ)v`X}ɿp]6$ [X_pwY*OIC;TcOw#TNb^͟¤9>F)Yg a'bIvǢ?cÖT~0{F4N|$}Ki?:S ؉}[{^Am.<[ngˬ`-rgKw!'5{H7"R&0B@xrcJ%f%3T<"Y BNY+rXl儐zm0rʬ %6 @@R $r!ǽqr !CgЫ#]rbY_9 W ũsu 7ޭT}y~X[tZ,vרZ//N=ePn:BYu\U;挻ÌJEEvTPQ /!]ӭcnTlG|N|]蘣"gSe׻/EemDŻo͒ k!g,#>iE75}SZ ̾}_uߏ\~^+Ƶ݊g[i*˷E"w_ &3ntKr.CB $p9)@!x %6H:W@!'U @ȉM) @ rQg^Ȁ \6ꞅR?u_QIS:a:.t4s”{}wl3O~PE #)tTfiP1B9n1!H^][`fUkpzYEvub~Olyh#\LfBNq~3F0䔽CiCsGPl5R?Qw].'ڙRę ֖sr}"3&~F֒˫b2`%UUqHEKνC923Ru7R>c#s8ډ~l@s3ҥ5}`X'L>#Pd̞1bquhVKZqBa .}`-rg1qDl*Fȉ#TEVnE"Ew BN`T@IE3BNO>@"SDN!'@ $/9lN!w̐"9)*&@ $BNDvҚv`94 0~uCL#Whv4bXFbn8AwEiJ n3*hbsWZ2QNE;"Kҳŗß!'|澮x^[V}(rS3@!' U$ D]BN?rґ?BN:H@ȉ=+C!̒m9ٮ?ُ"3 _!@ ,`2OH 5@ /b>WJ3!v9ƒ!>@rzg @ȉ?'BNkH"9F!7~=k@'r|T @L!3#FĀBN @' K!':Cz{Ȳ "%:rBN !Z9g@I~ !=^ J&uX? rPErBo( @^ xĘ D^ !P9 -\wE"붉TkFp#prʔ@ 7BN 萓r|d@ȉ:KBNJJB@B @k9]#( DA5F!'k'_$BNrj1Ҧ%uX} mH@ r^a BNY#H9Ae,@Bӟ#BNkL@ /O!'xƬ~91vA! X  @@rzg !@ 2KdBN [9-3vȱ^[(砈tz\3,r턬fO4',tL qx>2`($@%'x_@{7l* w;bC`S |>61D`HUf5_T7bLְd,]|O@W'^q+n N)O= 9r$ @ 8rp'·@trc#zcȡc-䁻D>67a\ iBZ <~%є^HkSWE_],w8  pJyr gNB`Sr};[fȬ']XU] Dq$Ǫ ` |8*[KDVn)WR!\#r]B?%:9ѱgt@IGBNwJ!W5+i * @ d@If25BNJN@ȉ:KB x”AsX/ٰCVKn.D TEIuyI.$9!f 3B!'#Ny9)/0N!'p,03}& d$ @ @ rbYM!g4C93eF@9p,ͦbS{D=BN+9?ϨG9h9 )aƖBNlKC`]@C!ІBN(JD`cJ!'!,@ @ "!E4TN!'">dBNFj_٪r=,b9)>rR\RC!ЎBN;*K$UXH!'U!n tKB<<9ɫǏBNjBD @B!'+Nx9 / '@? 6NWG;p@BNHL"lXo-9|"BNpl63BN F$˲TrP! G!'q%#@ȉYAk9]#!3 ' @ @ $9!f Ə!@aRÎÛ#vh4Nr@~@h;sNb\٘Cx9=K׭9'DC!'X2S6 di!'m% M&7Q",V!@ ăBN<@ te@@ 䤸N=)r9Wv9ɮ#2K!'OM9)%DD!'",+_q2Y d)K!'e%H DE!@ @@ A!'e"H@@ rI%"7To"tK,rR[Z BNY*9`e @PS*BNKj@ 3H!'@L9)5B @ؕ@iGs l@FdiY"B;Ej1C}!'3x?i2WV d!'=$h DÝU%/Of5#䤦$!4 @ @HJ9IqB'?XYN-9z2q !-,Dbo9~e MF!'mf>9٬;YG!? hj 䤫d@ @ IrT NJ: dBN@ ""% BNkS9>dL@tSKF!7LQ9-|FIQ1I%29ga@ @'- 9ɨQB Մy;Z^TNhFIv|!GLY9-}jGIM)I$"9gY_ 2H!'EOY9)+(DB!', @ @J!m9(AB!NXo,YERKn9ɭϑ# 2I!'eOU9*'D@!',;ߑ2a d)L!'E% 䄎!@ @B" $L @BN X;el#k E7 BN2@9@e@\S0BNJJB!@ 8B!'L!9*vJSEIiaI+T9f1@ @B0_9 A&4o$E%1BN@`6Sr2UT&ʲTrBR@ -gBNF 4rR\\R BNhY @F@$Ϻ @ 9aPNȊMbXQm!'Q 2X 2wV d!'%p ÙU%,_fO?8"䤽0( @ #ӎ bG!'v%! @@hrBCΕDENV9ɪW"3C!'3Nm9--D!'$,(@2y d)O!'&P 䄂E @ @ 6P8?9 A"鄮sBEW*瓓BNrjp9fL@DS$BNKr!@ 2KN!'p,r9)/pC@I1p9#f@ @p "z  @ L9aNZi"6GBN2B9!@f@I}S BNKL@ 0ӇB!',b9).nFRCHI3P9er@ @p!K!Z  @ l9aOzbTkO!'5 )B@L 䤺H!'e& C#jJ)6Ci!dؤ21 @ t A!'u @@r5M-zmȶ="F@ȉw}B!'D,Z9-mfCLI4 9eP 䄊RH!'EXJ9+8B!'L @ @ xĐ D_" DE!'* \^Y%=$bL9qLq!䄎SH!'EXJ9+8N!wLd 䤪L!'e'i @ @3Ϩ%(6 @ Z9O#zsȡ !' 92\* 䤲J !'S& )C':rL4 d;ߑ2! @ x$â%-V DI!'J ]yEkzg3L!'u *d 䤮K!'s%'a "! vM3 d+_q2 @ tA! X BNtY 5+ywX*ȹR@ȉ_M"!'",*9*g&AdIG9>d DSB!'%p9.>F!7L@ @]@ã! wV āBN뭥"+7TBNa49g@IM)3BNfKO>@ $DJ!'R,9)(bS@ }_ I @ @`r['>sV ąBN\*8,y>^_$qH$rS#Aȉ, 9(c@tI9>@d D^H8!M ΐ @ @`|rǍB&2p ĈBNPMM;zm" !'UE 9(A$BN H&@orz :Er $vD"N@rzg  @ 0>9]!@ 8AbD!'FHj(3-N9XuNBN9$BNrkG-9F!7~9Q$BNrkG-9N!w@ @#3>n2 @ FrbT$RY^9}&9 & Ĥh9.+z#?xԁ(K!'#vz';Cf @ @7 @)y^jW2A 5\}tԡ~ >'pX9u6lrrbT BI,Ė/@a+@79x@ȉG"r[;"o@a'@w93d@ @q㮐 vxm+ @Qmgh@IwDsrt!D>f+#Ĭ H9,A_A! |8 ĎBNJB@ #9cp]@7@ @Or|40qJэ. ď@BS2񋍈I`a\,zHM9p91, !%BNJF WtI!K` %XD!'A"Զrb$".C @r|TXrmnf @ T\BCg|D<%^^[(yH~9391- a%BNEm 䴁)tA! X -ؖB!'!"LG9hrȸ  g<( ”A/L\Id^&r~}BdAI| I rbPBBNO&H4T$%}B#r @@trc]VXrw2 $Qr~*}nJrĞDFyoX W=o9Ll ˒?=!^~4Y:%&/?6E hauv[l,Ya3pM`)'˜gd'ƭE䩳΃!97MG?8 DrU\>a'fĂ#Y Jqx @C!';N|]Jioq`s!@`@IDAT2$?p <*ֿ,(R5B,>Saks+%<‡@tyu r&E+C-|rSp+K`O̗.2O< w{*>?x2$on=͖3O$ȹ,2Y$O=_? @ @ ;rSgZ;RJQ} l+}9Ϫz0˝z}Ȇ"՚?"1kM 9/>lH*<2E& "DSVeYlXש$0} O/w6;t:۸C]J @=3,~a|xF4H߸_е P!@ @ rPŌ8CJk_21iB A=#| @)yX-hH{,93L jKyi BNJJJ]*L*D:KBwgϕl!g嚭O  iSn)ٓrZ݅| !'-5%p ̚1E>[.yV%Cβ?kJ@#QC @@b $t gVVwgYCD(w}CHr9ƙ"[.9yf"䌟]7-[튣)ˌt o;Y~BP1ޢ GtFge*d 92#;IilܲKyFB-7Mӿ fM c9ր%/.E/|LxrCŬL @ 91)ax#8_ oXMo71  D&KSL)wxxboRtם\~T*p@̻r y#P5dv`g @kh7#v!F~W[Z?!p!1]8 D Bբ$O@N?!'?yA @@ dOYwyi;tH }2p;$ ʱ%NGI`Z"rHHrg;^tJ~̤b_NZi!<˲dMU{wdՙ;4 VIBha2ljgjU\2N&8T~L23EH"Eľ@{{nku EM]>Gu~99oӷ9ZXbi$EO{jU$pӋޮU*M!P;ϭz*~뵍3ov4ZK |U } {㝿c>U <@K[slWͿ0j @ @ L*M݋1xYrcpT46 @o%8ߣ1Bԇ@Skg=zth>:-P\~r.\Ma4s,905.w-]o>(xv~GhY&zG3]ť+7JFJRlyζQ*]Fwf'}C<hmm7l|r%p7g+.6[Zu-7Xme-4W  @ @rl6Rwnɷc[1dFJ)-^La?to!P3EG\py8:;e'wǺI`^^:3[5"a6Ivf^]nZSrI`tt,s$cAa/@쮙uQ̘f!PWN^;NlE`;-Y4-۷Q @hl5b(rN"n|t4@%3Mt'ѶtsDSsRw ލؾ/ͽf38Aih$ W3[&iVC`zn߹;?8}<= U5*gNe}<fR`Ύ}188 7gW.ZYb9P6U)עkAWUO @ @r{6DCg~F:IEuf,x>:V/ږQjG \Ma_}# <9i?s=G}iݯBrݼ7/͏o&o%0##{ؑ~w,=" tZivS]Շyk%jŲk/sz[wã;F:Dq 46o7b[- @ @`rZxt{7F{Dycَ @(PjҌѶxSY8dj:]ߏxj,3{l_ \S7Gu7Ώ?X]M,pQ̖c!@K3 1sf7A*v7`VyK5@47Ǧ GG[4LK<__qB#4%6dž?|: @ P9U4b2ʣC1zX%3rP]7\|26l @@@Ss:F˼UѺts=[jU*P.G<H'}f)S;puH݁1f̱ `49NtW(͎bn@'bPM'b),ԃ!'bs!HG*3x<6r5xH4GSkgH?OK=2u 㬏Yqq#L9p?:J vT5hu7譸=xٕ1Cf⟭ﯛ S0Bn ·ŁßаYӾ՗hJK/YԓfYV,[*Kx8f]ݑfLqvHT@)\DXEH"wލ=kP uіGdh{. @ @@ TѮI(`FyVnJH=rd:QiM."@" O)A}Sskڻsn Kt1wy۬RKtZ; |{{/> |ó/Nyff'fW)/-?X/,lL{ǮSiQͺ:-0oؼiM{~e,M^`|t+WZ@wʞyckcђfM7Kǯ'>u:FmϷhmo>[XB @L@4t5Lpʕ@Nm""9հ״V q&f)M)}y^/-Lܺ(oqޗ*9_Zx5Oތ |MǓF(8k?I3㼺lVb[ԥx|z.HxU(.N=@+tYqݳ Č!Pzƾ'бqO(&FN@ƙ=+^zXmSa[!08|=q)3:-9+Pq[XB9M@T;K @ 9 u @i|#ʿt"3M;66;N8B9o}ր.jci\̉W 9-Nx]ccE(r=x"_CU*M 0}-1wnWeVukVĬfIaS%p3]Sqq;]lZ4@1Nϼذve}nyl}r8wB5>>XsvGWFh 9 q[ o:c̖Jg˓bΘfɱhD,9 Wwދ(fѱG^oK'ZwYpYq^(VXsR=-Lh^y;N Wv_%3B9 6}{{k eΈc cX0tC¡Kqr|Jܽbld"ԙ@sks3~+> Vm]8묧C @. S{P  @ i;"]̐S{*ZYsNcW\-X `z}(ݧ\r:EW.WWE/4QS'>L7k)RtlmYgzڣKQ~#"Sr.]7o݉3??c}(Q,I8z"K3qP/4@q,hIFw׬x" YҊc>tr-V@:ONJr7ʗg >cQqvz+'`LKkmĉ9$/Ny[aifmB}`:n rb`h(FS(/> kB9,0qu:/'ޥcA/fęّnљn--UVO"?0T h3 :+ǃq86Tno]/>?;'`~,(E{q,^9tvW:c-'M1sN)nwc8Y+ǃ" ?P'$rαO }W~/T|q_wⵖJǁ93*ab&Rx @T@N!#@ @U.[/W @ @ @ @ " ;Z7  @"[wT&isQB @ @ @ @+ R @ @ @ @ @ @$À @ @ @ @ @ @@@NR @ @ @ @ @ @9 @ @ @ @ @ @  , @ @ @ @ @ @r @ @ @ @ @ @9XJ  @ @ @ @ @ @ @ @ @ @ @ @2r2 @ @ @ @ @ @1 @ @ @ @ @ @dd`)%@ @ @ @ @ @ c  @ @ @ @ @ @RJ @ @ @ @ @ @@  @ @ @ @ @ @ !  @ @ @ @ @ @@1@ @ @ @ @ @ @ C@ 'K) @ @ @ @ @ @c @ @ @ @ @ @@@NR @ @ @ @ @ @9 @ @ @ @ @ @  , @ @ @ @ @ @r @ @ @ @ @ @9XJ  @ @ @ @ @ @ @ @ @ @ @ @2r2 @ @ @ @ @ @1 @ @ @ @ @ @dd`)%@ @ @ @ @ @ c  @ @ @ @ @ @RJ @ @ @ @ @ @@  @ @ @ @ @ @ !  @ @ @ @ @ @@1@ @ @ @ @ @ @ C@ 'K) @ @ @ @ @ @c @ @ @ @ @ @@@NR @ @ @ @ @ @9 @ @ @ @ @ @  , @ @ @ @ @ @r @ @ @ @ @ @9XJ  @ @ @ @ @ @ @ @ @ @ @ @2r2 @ @ @ @ @ @1 @ @ @ @ @ @dd`)%@ @ @ @ @ @ c  @ @ @ @ @ @RJ @ @ @ @ @ @@  @ @ @ @ @ @ !  @ @ @ @ @ @@1@ @ @ @ @ @ @ C@ 'K) @ @ @ @ @ @c @ @ @ @ @ @@@NR @ @ @ @ @ @9 @ @ @ @ @ @  , @ @ @ @ @ @r @ @ @ @ @ @9XJ  @ @ @ @ @ @ @ @ @ @ @ @2r2 @ @ @ @ @ @1 @ @ @ @ @ @dd`)%@ @ @ @ @ @ c  @ @ @ @ @ @RJ @ @ @ @ @ @@  @ @ @ @ @ @ !  @ @ @ @ @ @@1@ @ @ @ @ @ @ C@ 'K) @ @ @ @ @ @c @ @ @ @ @ @@@NR @ @ @ @ @ @9 @ @ @ @ @ @  , @ @ @ @ @ @r @ @ @ @ @ @9XJ  @ @ @ @ @ @ @ @ @ @ @ @2r2 @ @ @ @ @ @1 @ @ @ @ @ @dd`)%@ @ @ @ @ @ c  @ @ @ @ @ @RJ @ @ @ @ @ @@  @ @ @ @ @ @ !  @ @ @ @ @ @@1@ @ @ @ @ @ @ C@ 'K) @ @ @ @ @ @c @ @ @ @ @ @@@NR @ @ @ @ @ @9 @ @ @ @ @ @  , @ @ @ @ @ @r @ @ @ @ @ @9XJ  @ @ @ @ @ @ @ @ @ @ @ @2r2 @ @ @ @ @ @1 @ @ @ @ @ @dd`)%@ @ @ @ @ @ c  @ @ @ @ @ @RJ @ @ @ @ @ @@  @ @ @ @ @ @ !  @ @ @ @ @ @@1@ @ @ @ @ @ @ C@ 'K) @ @ @ @ @ @c @ @ @ @ @ @@@NR @ @ @ @ @ @9 @ @ @ @ @ @  , @ @ @ @ @ @r @ @ @ @ @ @9XJ  @ @ @ @ @ @ @ @ @ @ @ @2r2 @ @ @ @ @ @1 @ @ @ @ @ @dd`)%@ @ @ @ @ @ c  @ @ @ @ @ @RJ @ @ @ @ @ @@  @ @ @ @ @ @ !  @ @ @ @ @ @@1@ @ @ @ @ @ @ C@ 'K) @ @ @ @ @ @c @ @ @ @ @ @@@NR @ @ @ @ @ @9 @ @ @ @ @ @  , @ @ @ @ @ @r @ @ @ @ @ @9XJ  @ @ @ @ @ @ @ @ @ @ @ @2r2 @ @ @ @ @ @1 @ @ @ @ @ @dd`)%@ @ @ @ @ @ c  @ @ @ @ @ @RJ @ @ @ @ @ @@  @ @ @ @ @ @ !  @ @ @ @ @ @@1@ @ @ @ @ @ @ C@ 'K) @ @ @ @ @ @c @ @ @ @ @ @@@NR @ @ @ @ @ @9 @ @ @ @ @ @  , @ @ @ @ @ @r @ @ @ @ @ @9XJ  @ @ @ @ @ @ @ @ @ @ @ @2r2 @ @ @ @ @ @1 @ @ @ @ @ @dd`)%@ @ @ @ @ @ c  @ @ @ @ @ @RJ @ @ @ @ @ @@  @ @ @ @ @ @ !  @ @ @ @ @ @@1@ @ @ @ @ @ @ C@ 'K) @ @ @ @ @ @c @ @ @ @ @ @@@NR @ @ @ @ @ @9 @ @ @ @ @ @  , @ @ @ @ @ @r @ @ @ @ @ @9XJ  @ @ @ @ @ @ @ @ @ @ @ @2r2 @ @ @ @ @ @1 @ @VLIDAT @ @ @ @dd`)%@ @ @ @ @ @ c  @ @ @ @ @ @RJ @ @ @ @ @ @@  @ @ @ @ @ @ !  @ @ @ @ @ @@1@ @ @ @ @ @ @ C@ 'K) @ @ @ @ @ @c @ @ @ @ @ @@@NR @ @ @ @ @ @9 @ @ @ @ @ @  , @ @ @ @ @ @r @ @ @ @ @ @9XJ  @ @ @ @ @ @ @ @ @ @ @ @2r2 @ @ @ @ @ @1 @ @ @ @ @ @dszEHvRIENDB`faraday-2.10.0/docs/_media/repo-card-slim.png000066400000000000000000005644661464273144400207310ustar00rootroot00000000000000PNG  IHDRvgAMA aYiTXtXML:com.adobe.xmp 1 L'Y@IDATxYuq2 mQH--K/]ݚivU۔k蛢-.TLZՏ*58d̨[kG dfs $"v9޽#wV]yB@ @ /_.gݣŕO|tt#hj څ?=쨯uU7USWUoOu&M1C @ @` H}nB}Ny5gΡ;YamEwh~=cwS?\ @ @H:l>~\ϡ?{RSY@*݌Fs7>wZsU@aqvG>y# YM @ @Oi~g>Sm_{Bz046\̟uj9>>Ya=k#@ @ B󼑭?9>u0YaIϩ>Fx޸䚅tYE @ @yY :&;2NqR#G#`2=.8f{|:@ @ "P>]tV:򉏎N?pTMv^ Q7SwI缂fnn{P'{<wЇ @ @CSSmE}*nt)F;inF} =A!@ @@}.]ksbwaRy3qn=a"!@ @@Qs {H)QkMc=X@Og@ @ ~X}WWwϭR\mh=:1b=1CAG @ @&/_,S_9Wlgڇg c9xޘy}hR; @ @lH.GJhiq~`6nZ}qvAq*عc< @ @ p>?7TF NzY|?:b|slVs"@r] @ @C4M]x(Jq5cޟ}>7zC @ %s)m G9-n,h* @ @HY ׋ +ܚB:O'1:@ @ ҕhqqszް0hn}UiF>\SV 99&W@5 @s @ @7#`Ͼ\_ZOeu{ސ,\vY%FIs>l^ 3zUC @ ܘ@lY[mσWPGB>7IdUQ {X @ @8TKßD=ZkYDfKi,):'7l9MnsзD2 @ @@t~UBԠ' sb>d{F)@ @ "ЪϗXuPs8cc+yz3! @ @`XZJ3&L9#:XupX=]-=a @ @hg>gyިB}L,C6KU:8+w]ѱf@ @ I'0>1ϝgJaBk_Q{>Ӟs ፹ @ @ 0WKWJ|!9Ws+=;WVyCj :~sΝgyޘC}" @ @`\W>fB肮v!bZp%̣>R2u; @ @AU;KWUSt޶ޑy#+w @ @MUyC7;;):wSxޘy_cO @ @KUelP?6dhtsIwjkh>'wOQ @ @` X}WyC>]}nv<[):+ܩNXu ^ Q @ @SEU[gs=o7]=6B2 @ @SDU;硯:TV] 7hOlW'vh @ @!ae5K}nlM*:y:#޽ pwv @ @d ҵ.}\Df;C/l>>!p?z @ @PשZup7F~9ebUQ } @ @`zvjUyCgY=I:8S~nT>vEEz @ @&@>w7n,ζtt, zF1p1gг6\ @ @2σ}>kV6yOz(yȷQ^;.8.uC @ #qع>ɳn(5ohߩώG}GP @*N* @ @lhI7mRSwpѤtJҊ&=?ga`;"8"T @ @ p|>?Ju9>7>kwYCb;;竇}Fz`B @ #Pl:8hg}wv$1wi{Ej^M\pL`@ @ %y#,{ѭ:؉έpP5sw;h @ @lâw8lϯ_X)=F};N`=a"!@ @(+vh,Ϩz獦w |E<8t  @ @&ۍ"StN y2fz˅ @ @L`ﳮ"O yOֻaRmZf~T?P'A @#l @ @E}|%]Jyضk_?U_Mc9q"t@}IG% %Hy@ @ c >B}|=x%O gN @ @wGj}*^;a,ٛ>ٚss??<7n0 `}4  @ @ ϪZ~!<7k;[gDHG4 @ @ p >oﳄfsAIv>;m~6sc!},i @ @ >3v6;<ǩrk1Bqj&> @ @>SiXX6xgoڇFbTOٺ"= @ @8@y?=[Z}OV9DgZ{獹摇FZ/No#@F!@ @nJyM>K}+g:هМ9Nu>#v v!@ @n@ +6ZZ\N?pJYZYvΝgoznTI}~7Ʉ} >G!@ @ _Z`PN-:I>1<>H z~StcA @ @{Zg3}NCb\LmZtݠ>M"B=(ںh~-/ @<$4@ @  jgGى{a\y37~E`O}||W]@ @ B@s~ b~ nD#ߵ\Jr@ط_[x1e@ @ }{}^_?kW0%gDfnNϨC@@{%ښb<k"@O@ @ 0Pi\]bժFKRn5@"i\ۍz[?KD^ruUs8Yhi u&DqÞ7!NT[gB7} 虀&4n!@ @ @ pB}~}^Z]}޶)%s~c~Ɲ9=ox-/us&y @ @@Q9հ}|gP#e iYXupwf;>g$_>=yOC @ @H X} KU-b<~S@ @ "P>omZupNjiyIwC =ob}Z.y!@ @@Q/窃hYZupжRH;:(wd&:B @ $P+ŕ_7Φﳷy9ltrs=+l;"&.C >&sRF,; @ @AyvZs}fCTqm5EY}V_c@ @ @ TXul*% tϪ @ @`F@}反N˻˸zr2ktx}.>ѽzݡ @ @ pPusg)=gdI#Z/NH_ܧs^t/CI @ @`>g>+r\qd,xq@y#'Ϻ^FF!@ @8>~omwr;Ź;S s}i]=䬗|#s  j @ @,Ͽ2lߴ6{σg&}QuX@Oހ#@ @ 0%>WϽT_դl>lui'BoWa.gU=!M7 @ @HB}qfi_nCZZxסb=k @ @GDyU>o綠dh3)s˃Dttضy1t @ L7Zu>񹓡4J`獺:"Y88 @ @6#ssmǑp.̣ԠG}N('獘G>Z'` @ @}Ng%5!EL`獣}Dyi @ L J έs'=gr88½HmB{p @ @SBڪ{Z_W~cӧbSZq3m~yr{8f.!@ @g_>{:st𜢴,z&`=F~Mr yX@<4@ @&@}*ϫx1 ̟s@_gVxzg7-m|=Т|獻ld?">3G܁j @ @(>>lu]uu!Xt >s#M1S8m'a@ @ 0q7Ͼ؁>_\ YjY; Ip0琤Sc#PV0--y.CA @ @R}7ʠm>?S]6 !=[г[}vb@3>vei|Y{ 4@ @&@Q7l5)CW/H}n> mts:%獇YѤ3$ 9ߪϒ|c[us@8 @ @%`/_>Rn7F{[Y@ýi&m|ۍmhIϽϾ9& @ @@>Pol-yj{8&SNEڠ#f?}{VE = @ @h=o\5}~z\}ᳶ\KZ>9 m_X@ @  @}^lu4l9=oY[J:8 ف4cӧ{RM_{bYutN\h'@>> UuE @  @/qɨپ6ik:9Z }B&ln5-YѬM >; @ @}n}^3Zu0|= mu<e/>yݡ @ @BUUyj{'tc`ɹuLS@ @ 0>Wϥ 몣ŕ_ذ>K}ݳwKrNѹVT3?ٰMiQ /t @ P_gyސos?wv>w<M`gGS!@ @N} Zup;~ڃ'櫇WY>18fS>1O @ @=N}^ :(~[_ϱD286| xa L ƒ(@ @ 0KS}睱!?%9nO@}DOS> }چ @ @GMF3v~_紀νǤF}>IwL`zg]"3!@ @@}ksYqR99YS>.8&`@ @ pPǡ^{=>T޴>7ڣb<p]}<^gC @ !<ε}SF1 qp{%0ႣID @ @yc#-j}~&VL3g F=X&#U#PGK +~tn{be@ @ plç_B}N4t?=1W}rL}h;$ϟ4 fB @ 'g%R}[8}-MC>Z`0l;sW,Me'pcyqZb\ @ @! yz ־74B󼑺sNҪ?<;etg$7@ @g_9{o<>amCt:g/ՈW~Q @ @8 lU;Kgqp3χ10Ϟ3>Z> B @ @'>7yG곶4y΁pC9~%Y`wv: @ @wE}s ?UǕ}tPaOc곺1k. E @ @ Ϫs:x-mo >lö%ЪϹ`3cxA @ >W|#g}<ݹbUcR!rl:x > @ L:fcyZ7bcyC4:#pO}Ny6ms0̤B!@ @ ?6pz&./}N A}!" _}O=:8w1tS6!@ @=8>/>?SI}Y9@m{o: ,Lz!@w(@ @ &<><:rc VxF腀_U7ےPg9 F @ @4K}NjVLS;9Ϭw7}ͫ}>&N) @ @B@R+V Y곶4vN׳F} 1=r:( yÌݡ @ @&@/TҠc szHϲt y@}nY<>4C @ "7PsT}N93GA>ODtod}w& 9t @ @,79EЉII'NT|U~ >{--,#sq>:h  @ @ vygybgq8{%Ю:g9H @ @FEyhRZ\Zcs 7>oGZOВN>>NE}U:x8p @ @z& Zhq!J{g;GInW3\YCG@ @:/[Ϗc)TS}A:L}ތ~h}q!@ @@s7xIѹ+}~}RA}{F]dtzkk*. @ @O/.>F2K Q%z"`g/a@K}~=MF @ @>Xo7#Vu&NeUW`<>Cټ{Z~k>'ィH @ @`t^6֛XYyf곐u7D>!B=W;g>nliT{4@ @ ll>|>K[BƔLx޸ |>ڡyC-y2 @ @'Vycq㏍1>oF}NgD?VֶUQAG]i&-C @ 0p}~ֶu[ZZϷ>ߞ9LתRdQl#4i @ # Q׍<...=`f?le U؇:@8@zިV>sϾ{5\p7?i @ -4>yj{'&HQ`@yްo5Z^?9/&9(y SZ @ @`>֦>]Fŕ_z|tz~s ) (~]Oд>*Z @ @"7F^unF>W}MyHgMOʱ<`+~?=p\qՃߪ}@ィJ @  ls4E} Og͂ndDx_4N$=瘭sK˟`s.LlyWDNd:@ @h66v{~f_PwdZKxR}^A}N$`_'Q3a}ن >,mC @ 0R_774PVKZupО7YUZ='q*@iL{8UM(b apEd@ @ pT>W>*gg{ސWd*)W 'BjW>Մ{ ~_74=̪VslGC99tK# @ @8nK^uϞylM#R% gMZROޱ^:~UFz_ 1@5s t/D @  @>:hѐ=o3յm}bAƱـ<gŨ^u0sm>MVGZb@ @,8>>?k:*e >gY`}JϚrg~nu݈ĝ/%lG>+:\D@ @ &~G*UFZupa퍋k!gY4|2PW-ܜs̪Zu0g=պW޿ *܇l# g2 @ @`\mnA`egσ=oH*6!W),e T'OVx_Rt6#z s}"K*~QDR!Tu2tAl@}b.JkyC}/7 `qNnV I}}hq @ @M !g{v>m֬B*2*{TpXY7Tf*Zu7f"݉g @ 9IqHjb׉V!CL2>4@gSs>K}έ=,6FY:9 @ @ESSWsZIkVuв}F}n1q@i,aN1)= mVϭ0 B @ 'Q=wpL =o䪃 ;Oy=4sF8^7>3A @ {&'tOf!@ @ >窃 ZuZ}o:U} '{!`V}L7-zs,=G[>gn @ =1g~x곤S'<@B`Y[ZXԣs^uPƖPܚ:ww>tǎfujgKޟ @ *fuzմ}F#cg-@ҢC?W~` >?RuUmkzYLG"ڱO{7/\i" W/?+ P][v @h=o:Nߑ3t[>|R7d|ƲlSce\u0[Njntw~Gn4~BnRwUz6hk:Bu;_(3 @ ?/xIϨ7}87P Rh7;Ϛর;7loA>SL-k_U-J3o~^! @ 0>?|>Ϸ|-=y}(ҎV뾋5=Qϒ:Y|t~GzaL-k~khuiW3 @&@V媃#}:x[Nd8}>jYtե!:YCP Itbnms4aV@wFyX +hd/UWOT@ @` ֖޸eϏ?Gx޸=*r5TYwm?@o}YCP<>4C` H}W^>xXާXW6F6 6@ @wL@<|}uK^B}^X3nVLg癚Sz1U8lySϴcP#iK>}Ϫ :voUwd ;lLv~Z\N@% ]}NFJ9'\u"@)翏 KgҠT!:t~cXG @ @yF~e%{@}9|[Dd8.>^}^-~BPE}=3 l C`z\sO߱su6-C9A)6{-;Rur @hץ>z ?0>oot9L@y#Οoy#%}ꔦWU%tOf!p?kYӏ5eۯBbVc?*_ly6?q[_F6@ @\|xђa|=1pWy#-}\up~7ﳈBј~>g9O7ZO4RcxTXUZ4f+im@q[\E52v = @ B@s U4zZXg3"1HPBn;l}n2E.jgՈb sIK>mla\NُB+Cex/U.M: @32@IDAT @-ptG~|~J7GlH9fҝnV}sč7s;ڇ>5h3gtlr焍oאa&ZTEƷ}9v :0 @N`O}Ju=Zg^"DžN#sϚ}^saxA0ڔsgGw:i6B A(Jg A{#cki첶bE>Cd]e%]*7\;tQכ'@.8@ @#~yȗŁya;_!o>߈ qHW6sy㝧9&};ЦnUgG³vފ ,jdc@ @`l u}n>_o~ܷI}}@뛻`1cn$|XH`s7gu-fk}gޜ=W,G;CM>Q"+qRFgʚ vxA @ &F/I}yg/ڴ gtl"> 3>bU2>Ǫ[A##yM>s!!@|w<nL@_H@[%ڲé[M:Ϝ/~gm %"DZxB*6@ @`v ,|Yy~yӚI{>Ə#۩ܒ?Ņa>kj+6xΛZ?zhg5=B pz~7%"=_S X0vf8PH1/;cʯ#W mx◱6_6@ @`ƞ7 l_c:pOgK;OBsMcpc>8g5BgyԂWPzq[]Ѳ):9E>7cE\/X~睶v @fz ٗŵ?1|lUdר-}ؐW>--sE ǣ{9o,M Lu}=>EĴ)T"@|6veYW~T6]j|]ƨ̎gQ…OToA @ 0 B}Ng](lG]u0>oo0ؾ0u2}?+װsj곦h4=oƅ-rO1~ʌ: 0>?Kg?/c#ad8#%3?A&)X㳂7 _5Xxv]Y%RVmo\l@ L59_ycy~="㫷|KgUI}9ɰ@>[C>/|Oޯ^:S皍{uƟL[uɓy8 ƕ?IrMp_ 84+ 1KkgM9r.Oް}N9M'dļ=o9.CA=F$ sԛW-YHX lŋG$Ņi3E'~~͏%Xp#f=Y,QTjNd?GTR ,h?hDn@%^1d5E}v6|SWno~  @"c_}yQa> kURN>vh7>s* #𼡁wr}h[81{zQh z#OX^3!~ψd)%Ņ;koKxRV)Q5آQJ{*?"ԛo~M젓{@ @`^x#畡}~:׽˦NUil[>睜Ϸ =`ݤ>lo;ĉ%~z~,7aH:S'I|O>Qԑ9 (2uRQ"ag>\Il XΎt'/fu͉K @ hgg?OYq| UIG?ߏ,; p\ltIxCΝ~+)XqEL{c+gRUqr%kJGNɀzLvC @L | >~Ay_m1>'!@@ssU)}޳}{|d/wIa,BZմ}sNC =:4|S$wV>QiL;6Q">]9*DrFO#%hi N|KvO`A @I@K/T~Ks .xl'r:Si\mlIf1'Ɓ)wt+'L}f@?E>~8xRdr %:߰8spg U֑3c)Q2JVE8XtV"d݁R}U#.F;@ @DYRh9}Pg S5{yc0]Iz}Kj7nlM6tNt7: p,.s}Gj,d%ꗿzp~Bi\>(:anBp xj)';sc:+QNqџHS Uql @&@sEV}UpB/Xup?$#>J!YϿ[dĨ-T*˫W>8~[oacB9qn!wjq>SׄF367eGۄt ;K_ւߧNhp{Ε!ky(s\b7*+q81tZ#N!:z[ռA @=fycndA药P;6&uR$|k9ofgu B;Wz󵐐}{;O9DcG"s@["2gԎyBA*겑1gmYaFЛI[%Oq\4|qFt @ g{cy#Ѿr>ߜ)L@suTtS\h>q!p4>V_[c6yG84ݒЛlm\ (hvvfEԍqVm]k]Q/KWv?젃=;@ @ yCo(%[CYH/3 lokL9y ZKVmCq>IHM7(eכJ3zK=RJJw oOSVQ>R?Uctb}^8TYUsKnw>6*8{@ @X hAfU{|naX;11]px7tM@}!~gy`Ƥ>go?=o\|-j(*mVk8`wBsƤ"Z?C#9ʪrGY"W&Eak{՗DQ-Ǘık&;h~ _ @ pr&VTk1hgQs`"d@ρ;Q=~ZEHdX -׺DZ[[xbBr\gtDxHՑљ3BҧT"+f+I]^GElErbg![ϢX[n*+@wrkM}y @H}IUalZxH"7cToN<>W}S'pgM!㻏hiX>ooa)6T,l'!G9uBzCck.h8 ˅^ %W0Y}VĪqٟ>SJ">"GQR3D_UW_[WA8B @G@yސ9 ,*wϫd7BWUv?<:_~NH2= @ C#0^KP!Q&"+ilEb4sqgӠ>kj @AY܈~ mG&:Z Gġ;^!O]J?)7k(,ȩ wRtԜ;ܸ_VE}v6d?vU\BYIf : @@y#묱}| k>>ߌK }Sge> Lsvq!P^כ9eKƩZ**O"".]J ]uIqGG^ջϱeoR(U21/c }\F+^Go+:W;GA  @ pH7V𼑫; y?$zy:sq6egu9zE)zHXM[MeVYZa7D6@ @I`}yy:j s:(~m}./n-n \ϵ>/sX=~kusc~ܺc}6Y]G?\gBџ%.8dg±U^gwzJՑ)+ʴ9I[Q}=;lb{ֵeRjTBȑtR6e*޸Gqr'G0iwc@ @ x#U3Ug׽ QOyCs}1" |BY}$wK Z% ;j((٧&l:bbX sDE>%qecE(7EK(C+Ң9)Y3%~82FUg {Q27eiпS :ȱ @Y sum /t4G{Ss`? Y F>8M+Ap"|f~K a+Vb~莑h)Zs"/ެ-X?M7?kWMn8͏tGfgd$ȞO_MnفR9WT1*^֠= @ .T΂ yސ_S{':g=T5O곽 J6oi}tbs4Zu H}Cg׽V[Vq8H{t258]|WX<]Rw#%돫s(s%+V]V]v-ʢ(]D΂ DtS]YVa` @,~E[Xxȷ4,w:wZT>`c/حO7Cƴ#2곮Ho>ko5\ FjV_35>##$%ZuGf)a&u}]}|k鹋W&9793Qp]J菛8"mmVz 66hA @ p{}~\ ˏ=>ZX}Yqŵ}ΫW{9m5=ZYumܻ wo{O@{~O-ϿބC塡GF$h[N5({q:2,JCf"wQS>\kJRF{:-)ܝKٟVȎz\S!;>s6@ @ `fs,,@e[L(z gϱvO(ow* BSy ^goY aRn<+Hi]R2oZJ=9~ޔyhg^ʾlR%{%/3e(Y8w>.ًmkhdJtFWU?r\ f3QG|ߡAv @M,*_gbAXu0] OZ}cMJaPu >>uUuߦZ]`>OV,ix'3>N RkJ)̭6Rnd+fj3"EKv~רZWٜ;dddsJ~b"^T[[Gn=͌  @8H`lsAy>`op!N{! :J<=Q]sX2}9թ]uLC>S܎[?WN T1jO̚pQXuQKqvǑ#5ܔhT5u5QS'it%٫nEv:^|j :kD#֚\;o9Uepdt @ @0/j2^>>ܠ>?]V<0?,տ#N!`3nZ '%~[_0 @sG>"!9\?$A nKݵP;\gN2-O'Ԗ*JrVX0\6Ti"..uQ}' :Ws(\ νı:%lA'> @eTڭfޮs(v9xnL$TDʈ f6>O4q!pKoxGV]~;D[=l2kXWvw^Ƴ%NqL 9:%2-heܨ:GnI6tk躕"JlJl DfRMt6QݖOц+)q5?/yb\?A @&\ R€7>W#)A>AzWV^uPkq8urf/ƀm;coa Xz4@mc9yhAOnm`>#8  ?l ~ㇲ GE%ZGfLvemn-͙ٝڂ"oDE3-Z9Z[ȟ*reS{тOZWc8ZٕN="[NK+(WX.qleGʷ D6?K @/ԛ6|]u{ӛMloFc'`oRǪzTgӖRl}w4C?RW`4.dj5ǂgC#ΐOPn}SD"Cm]J?Rus6І/.9URٸurpBZէM/h?Q*Ԟ8jCE"l*(EGfwssOS: @ 0(>?oxn,V;oW}>lxP>>u}6 Eiy3}G?\Y TI)pϡ@V?@Uw'gK: Qy?XGjp ˜:c݅xF.QMi/ZTg_ ZEb@44?ڹџ#.:js1*Afs?|/RA @ `竭cC}.7╩7 ycc+gmy#>wC"QD?"ofZ}"@wO X}62"ƵaGQ8  jmxեm .[ЭdCT$*t\Ua vKcnגŶ(=+qZqVutpLs%9ՙ WvI9ͬYJc:l^5㻮  @u{J>7>?]m{ Nyp#Ty}]-K=6֪lw76b\3~#@ =߯yccrHnbjp*iV(QEУC &Kzj{SzR`[qf,gc}zz)pJB>,m+]KBVNKUdg[[_}4hc @L(7nU@iϿ40}Ӌ۾}zDsQaX G>uDZ,"Oy՜a'{MKs:Y3%hWWEΤHv-=)hZ>]=*!ڵ/kϑ @AE}x|…U}VyWԩ?[/.^@@ϕ>],Wͫ1 I0)X/NW?zyez'io ԯVm^J3.uTIH&zr,%o9FUOT>W,+kp#VȗTՉoGfܻI%"'!";.-ѓ\s:Gy}|2pkOdQizuGvO] @S>~򋜷|RP0jF69lz%Wdm=o̾z~{uOyO*qKRK{Ys>@}#@p9`o|O7Qt ԿTOu;:ڣ\4ĨUDJ)+wKQrȮ?ι@&#p(Ů+RP+Gg)=FW(q-D"ҭLkd޺ůAZv @>KX >siרԾiŋyvn鿒+ͭ!}l.ϹnnU]<]flgC!')CRSQ$+yqT7Z3ElN]c-Z+J*g66е؉n*K奋-wGʟF#"R쪺εsL\+,TX'Wj“d @ 0>bdž9翐xTPɗ(6YM~g}.48KFV*y|^獵}1iI}>QF7=;N~fxrJ Xg 'nPZw/$\>Q* 8nڝby6UΘ>FF(Ix{Ps\Dݒ=kTG6FΔ5k_]SMX'nl?6:>ǦSjWWyM¿R @ 0\_~+ >E#~׫xË$G;Nm(z'>#R斆>Sgw7l\ԏVRʆSE:;X} kLds9w],:b+*-ԖCIJI!V9J]+ѡR"2g8 ] Ү.jeKoiDZzBlrҊrm]v6.tG_Wu9Obh.wJD4h[4hCa @rUBذmӲ}KO4!)?4Usbt{xGפ>Ko|XDdž"ȟ1m(W{֙q C)LQ*}}yc==6k#}Iꇤ'J5`ңȋLR5v o-U}5` Ȋ$TJd".724'(-,Jv|!oK!=8gUhŜse\e#4Ҳvxy78"гsk:xh}3$,K\mۨy.t7&zjח76_|lg"ɴT&gDu=}D@zuE@~2΅:5RNz 9"0'l)W-, pK޹Gڥ@rZgFWxJۊ 1xpݻ2]0foC&A[rVֱ,9knaPH¼Mw=========='Bzy,::(eed/gUe ͠$FD@f > n "M]T5m6Ҹ4SԯIxYjR)XD*6q21;62g S-6PMh@v^-]Nx ǥo =]@@@@@@@@q};A>QyshǏ;<ʗ7`mdC4>ow ^\ŏx Wv\9۲&U,9+A-Y4\el0RU}!ǟb$ְvyPn[mZOK--n|\Iط 8nOAqkuxOʂ!v |q?=ϝew{T>빆G"lP?-O<##########pFgN }Η7@?|yM\zq#wGzYCT?= YcNp#1۞B %n]/Ze>IT;ɺ"Mdm4n@ B<୯](:Ƃtm7NTSnDZ(EEueXKcV :$ R1sGuv _N7> ~yiwS2_GDyRӳwG;6ub֋Aڗ7qg?_dfj ;SY 'i;S.Ɵ[>#}y D8{n;iF\ێDiIN!ȪMrtTMF6cLCZ0L.=O;V0]5 `~TUHt%1_ 92}CU}_rj"Dtpi֖ڛw==========Gzy<yRj4jÓL{G`c"0ݻzU< n>?kd9pB9 퓵ئ쳾ܳ5n{zc&p!{'3w,$6Y-H䒱ɂfɯ&[<)JFk{5jkC0Ft#Y& ~+o[7c #ӷjw wP?&.x$5Cn!TEmP"oSc4If-}7Lw==========};Wg{T%sSQ۶=<^ܰ}j}y#w8UzP|iE--"y󓜧~ts2{_7?0Y"|'IJMZ*F%blZZ7,jjI"\u . -M=)e9S?jzaYuwf.Rs27 Aʄnj+7)o` WVV~O{Ħo=========龽+::Ty;N/nWzg7=hxIF>o+>.z|5h}>}3gW1He$yǎ hܿ\#hա'WWpW>sodi sJ:4/Z"Vm2y_@{I2.NنuQ ~Sض*&iJJW/hk@5ȞM8i9eAl/jÌ[pԨ&{Ueծ:\l̆G*vmX{Ph4"c=hzzzzzzzzz60>gs f}&>ə0{=ITd}oO@?YTgE_zP:( *"OZ,te~#O”OL#d;Z,h(*b` [4M"ܬp(o!n AWf&%h3`ukV h- 3qZ2zhmZ+]rp(d% Ū8 c}v}~0˳fxٺgC|ke"67ڻ5YvMDJa(wXBO@Gs§yKy*UV$9:ՃmNtym>`.No!8mG񰫠F@#-[dEk'I8 l~ 0lAӤPTbfצ )2T8n`BPp!-oꞃ,GGGGGGGGGEgC='i$7_|l쳓>C;%}':>+|y# ˺s͟UmբAs;i=]KOԹS+CPr""Y^Rhiچ?Po.Clva zڪ1WaFRZK^%+:c GpBt@?M@UxjyoٍP@SO&++ozzzzzzzzzz1`}֗7Q?葦^>A 3O=DnVr <)LnmLZ7f6=,/xzi'o䊞C@@@@@@@@zD`ܡsӻ!ǽ= gc8vΣh|ycń]TP5O 觊No;Q#p[>Õe.@IDAT rS"ꋾ'hjl;9gSWTJI63"fRߚ_Mn׸csnhS@E[CCܖxhF+??PB`*j,Nv5rk8B0X%Q+F̃`2Mv},}@@@@@@@@@F`}B>>i{q|ܿcm}֗3J{9u(T>3zDcNnٿ:]:U4|,,՞L&)Ϩ$UڜG*R"=uҧ6&%LdOf7Isyi)f1}&fs(Ȋ:~gXHw#f o(*O!Vu֘ǽZF$-d;1砇 =========kaP6y9}֗7\R)PNۧoxǎ9 GYD_޸jh?^ bz.QcU;H!^?4z5I[O+bރ>uf5@eg߅o쳾w C?zl'liĻ=bҏ}G^=:pXn0h7ξ`r@EIo۷s>'ROcO#HrD`|5ms$Ws#D*RYJ2*y Iv%ޓIźV4U$FۛwZ%mٙFcZ$ dx7xWNDIDդR,50$e$TTN+-6 )̛Yڰ3}?6p"l}p=j bNi2|#=Mx##########@ʽΝ7+>F{0zo>? "O/:_}֗7&a ڶo]!(OO/NuG`|ՋW2I':ʲ/h3 {':,bit&5 4'"?gMɨu x* DCU 9WB+݊7L(H]WZxGL¾m1?MP D\?V[?O7H oW&+/_A;L}#########pޚwzSg>+Kٷǚ>}t)G#vطrUCy}VyO$ЙH&}wH g?.#@ >һɎ:OI`pd#Zt0GiuvԔsx '{mrCr#PqW`6ĀhBҬp_^mde`v~E8$ 3o XZ+:g+0˟DƏ{W"h*ރZ##########pȻK~Op<>}V < پ}ܳG1޺zD>׳}yy~Vd䮏wQ_qtyIArTg!}вad(p@S{5U#mG?,{c5jzyY7)$Iz${dUD·-I eےvHdCl)ڤd+6a hͯ䵊nǿ ma8k Zw踍,j)[m9$.8윚ւ`HKeY:3.o?|dz5[@@@@@@@@@ӌ篎"msoxg4F]!hgFh7ϻϾ@!:-CUergv[Nkqhbg7%O.8/IӹQ)HR5(5S?_ 5O.\Cj!SpKWJoll@|^[lGB̘]AXclFᏻ$~c8x¼hԝM:`BE~4^tb|sAa|hx$%;R i(h6 aى5:0ǧ_Mo==========O/o|yg6_\~aR= cM ҳO1z1@>Y̻=|;LjUs>q9BO@mކF` lUpN\( QZ$ذH)h67ʐR-h1g_\P#^UVҨ_.ېM܌jMԩ߬t@iWK/hkȞ :˶Qд$ TLU:MnǨC%uE+;YP`i'0$I쿉hYOL.9h"ӷ' g/祇uι%=sщB~TDQO>G oɃ[7yjO@Q ;1ۗ/寏In__Ѥ6}Uߟ >B AN:mfCxswbX$U XI 7ru0h ( a{̝ /v ODVŒ<.DeCY7,Ck\gFZ1=y Ipmt/`19~55Qpe{\x{zzzzzzzzzZ*:8m:Ȼ;PGDjxHIA_6q#P}>c77>gW FZݞ^Hvc񷾺ZNpI֊;RNaJZ8xA D؁HjPnu[bo!{>bBe+R^@uQ%E[eEX@ʹ{& k:}u [_TJB aqyn}fr! $GS8d%î 6ć6M zڱ!}.عɿw3A)$rCh>A[?ξ`rPNM%\񄞛۷^`vu7/rοUuֆJO:a2iVfxt@b8։"disG cTd6͏G v~GloVM&A6KbQ[aX?p /ŋel2:"ǍWo9!>Kxh nVh~;&uF߿||bHbz##########}|tXS>s~PLx@Y5PxFHyUTzeC#в<#>o/o眒Lag;6=st>;¹n:mNWF:]*I /I>R& 7y} V'Qk<<MxkM i}VcjN3+> J`Z@I rc0io.C zE&3+Zhxsۥ Ɗk!':l# ތ+xhүQI*-5: x3@Kc('_Zzzzzzzzzz6{烎}g}yƊl=( )Tu0 ӽ\/QXɋ;wn}gjm='4l"Kc}y4^%md9{Ahɍ -V휹 ^a^}Szv 1 `@j VF&GUG :֣\Ƭc j/qKࢷb al-!-o&~ =ts oM$v-UQskQH5᧧_9~؜}yw{ti)O$=MN9e& tѥ_!iw}N #Q=>qk/^< $L.7IqM[&HFRYHȥܔHuuGj1H<Lm;9gS'i'ˌʐ\u,]ܱ#w̨ ['zDr+q$lH6nҗ0`Z8iA[?VI'  qeÄז}᧦4[@@@@@@@&tѕ_7&>]3]ĭG,,H"Tpy?Nmhҫdy.u0$;rff=n'-x"@˿9/CdIfFPrPZQ3I C0X)L,*{vsaښ:&6}ѡXn afMcPz92\nFv0ӿ8fc#_zڀ8!āF 0&!\NJ-:h=U='^n}#########"|^o2_8g?=C\xQn>}z |MFۥ>;$:+5[}~oN՞}±^vʵ _ \Y,HXyD|p35nrCpRv@Dvpw'4S:L2Rr5<.[#쳋 @i[! FE_w5nyݶFc 8mVn5@j&"1vO+bGg6Huصh>;9#%"SIXzy>n>_g<+L$4DR_lY~w=x;g-+3\>TY]ZfP^p6 iUa7.cU6͏ը_$:fZ-U:BH|zzy>}^^pGxN>}ZxҖygzy]#z.<"5d@;Hϗ}}/ohҗ7y|˪FUS@BVxGOk^vϮh ISUyܳϳ K/jN#0+ C/G@@ %ni) %#Y! 5h 4ͺ~a3M:- 6&? T`BS\džt.bj!ءOt0t~|`kY̏]3<6GBi'G4֯6X5ʾ0U|74ȠTvgny]`8_pJE@#^J@W|pހ1T~=`˰>>v_ I[G;_ GI"?s##Bl; MRB L]f"zq7Y `5q(TB5Yo臢X;/{🸤/}kkLzt1XϘ~z<Qml.nt\R0] JG9o߾}tG;#Fg}k'h?0>7ӫ'oCB!&6;*О" V=-` 𹽚 3Hdzxikỿ{}\W+?>ZXX|NVc|>s|Ҫէ:T'Ǎ'w|̷=Rֵ4'w#2Lx,d{n'eY $zc_c7>V㝧S] w&JL'iJ<:@CpU׾_׭a*|/o mOiC|ֻ#p/t59Dȷ ‘,C dOg Pxt>`X:e@*WY(7w_ 4ǀ 70jS9OAJWν0OiMhڢ ~[{g%Nt 0IxzCc 4*GGcwOB 27FZ!ЃA8Fk]L.)1͆cP R ~|7 D`ϟ1ewW3Cː}Zzd=xۧ,(XBO@g[SYR-T^X@ &Ff%X\ OfYcwJ[O:魯_ꖩ>gM^O,=Vf|fvqvOބ,Ml܋` V+>~;--/=c=ݳ>/˗7W9-:%:)9i?y}.i]/{};68/ac#'Mߌ ag^U}cAK{*(=xﮗ'8f_ް \wշ .u77LKE@?sda~MgTSNݟ`z`Q%M=~= ա-.^u+첄gGR6nvB?r_8bȳb'Ðὒ XdSΚ/Z =o1P6ϰ(? FGaP5BH>p:'W *'q6f1@m-lw) ieguboV o%7L?pp1=s޵06kDSծCW#l_Q?̔ȋZ54VacT9Pf /ڳbFsD'M7Єcݶ>2}؃u3ub|h=w2R=k31}p%Œg0xNyMi;?sC9bѬ6C\2~Y/_&ϡm?9~qS }C;o~7O-i>z^K53q#.gN"}6Š\(^* DPWa}nYyxֳQm, }=k Z9|/ϲCOu {a;n~N'`0뉧gҠo?`Z֗[~pŖw}nk 6m ~ޏ^wO3 aE Vro^X%*TY$9'n/ʮB"bA~,,D[,NK Wׂu [[Yڃg5W}67٭@PM%r**Q\+'`6%p\\򍦟_y\93B>(EfP >699~"0y{YsG}6~4kE4 ) 1Wi-D@zd mP~[APUnӲ0P,؆v`?4~?8:uvҞ. JG20N:%}6]@)P͗40BpmOxJ׼nYHO{O/6So<щx'_~hiYSo4,$1=klwàRژ,Ċדmm6>,7[WKw=_񶓶s|߳1ӗ7{}ΩO4;i%,_~7[^wY>OWӱk%zv$X:xp?.-A>.>ᕧuzy5-z./F, 4WFgh^^|3)iYY~ NPվ'U-_Zwhh Y-^,Ƣrל#frFBi~tCe/_F}giXzaCs.FYaOi{V7S, 4;$P/̵C=EV"%MFUTYR)!SBBk2 9rB8+$6l\ QQ ^pCh?S&joo]@"0So]wOF\\!QLa8 ƚm^M)+4:fEo}UyjfpȉwoMTM^ֿ=x +?; 9u=>wnv|ms)Z=_GgHbN-p= 0iRc4Z'pf؞Gs|̗_`݉>XG?jk[YX;.c_G+\y8L{w/꩐Ë~>dߺC.)WH;OZǽ\wYKF#}yoqR_CF mTmٲ7cY>7UF%T]?8wg[ݱQź[^eYؼiU5mfXY@!-2?dPHQa 8q\ ;q* _xkyVFFnW4/f@0_}68Zt<ē$B ]N,Wk6zP5&6z/vljxU;oq4s~h+}xO&3m(fX9-#et<5/Bh2 h[e9xBٞ U-O&ž_,_w95oٻ?:y21a@&~oL(zk!54jXv4=LkVi'UH<*6=C~?>Yߟc+odyi@>ڽ N_ڼ0Auj$>g`$sc]}& oΪ3Gt^\j=AU^0pǞP}>g?+v滐=mU*Ŷc?uH>#6 <ʋMRɣӡ'e۶u>Cyhح[%۱xaM[t&<#1{Y posy߷qe/jtX>_k-:":1/X%"LuY׾kKUN>;&o@oHػYn%Pe,א,g*zig )(nxTՂD;V?>XɚF&6VI,-*}b3v-<8+D5v<` 1Hg\@.uu*m.3gRthVUG(TS:uˀ38EKPMAAgE/ [aW#v ʍeWF{–Y^xF$H-<ߖj-PHA{v|PKmmc|OKvr7X8Q,kZ_[PѢ}7sMMd'uzqiL3?6= ϸ8:ud1$!nlʹݲʛf73}֛Go| +'H&[wDa|KW[o+'H'Sn.[|5?h<lzyǺ#>V&COGWm!MOj_4ٳ:2R 83z9qؠ}z: 7a˥%ִ:jQ=zmYJxfh^!׈RKw,LTΙE1}[bq]lVMU .;"(Ѫ*1ޤ&(+B]˚_qRV,;"/ŋU$'E=ڛ>܅&>aQAЭp~Ǜ"MmvF h t.-`>e{g_ZE}@"0ݲcje5!(04k1\0WP1j U!0OM,W`iio4Cv߯QӅ a8IEg+FόvHe8:pG\X'f`:0Hff=7$׏۹֨܄B'C6dB&[p؍Gw5׿F&o'\=g}p`ECkN sf y# :QD0hV[V*{]vgξ|\9 OWjgmYr;u smoRO#z? o_9p%־/+?rVJӝKI9qcQL<~^߳sqB单?sab]xk?~ 0hn*wmϭ/jscZ68Գ,lԱ'7*h/^b{bbqbbikqO ^WfT@5u%}#Pn;OѶVR)"&RGZYky Ci )T ' 44\ aI,d&3no,q){{wkm'ꔰM\}?m|[4GQjk{-B M|4ʋ' 3?UkU )@̖>*ݻo7};"0W3ztȵ?3-_ͧ{5<|l3ӱ]u<==#SbZ)4ՊP0θcxR) voV&~O;e}֧ͱɳngDsj {Oh6~g/U9W"QV Ɖ}}ûnc絧 y Al+5C{MW'_X\=xh>{N;N9RfG⣣^E _7} |4?dbM*[G۠BO@oP7م^wY*daIŒ-w9|*f Ր+MS/,6-#bZ\hͰ 2 *Ӌҧb ri:XhW;؃VDRvu70xAL8?:u-DiOۉP :샵"(3͋eZ᷊ڐ~Kɚu>V7ܻ0 X$$Dc9lo/|B3]@E`zKԿn=գš<I副Yc*Q*bv#9$a20"(6AЮ"J֞6D?>"ΐqBj7]<ڿYy=睡yY=tJCb_ S.+' N|`e \ 3McPj:b$\),-Lo'D'zyzmN򲑾ѷ Q-3u_ݞ}Lȶ b\ eRgCHKfVfa=S*9Դqs~}.g}suvϔE()緯oy}㡘mU|@MǠIy9)gYYh)U&K,/}Sa0pDaѥWv>7W}^ԳD=vCE놵T!:Wyxg/<,Y 63۷.ZZE<,-X#*0x l֎-+\=qUKr(H$<`}PVvF#"+;Ko"*ؑxa٤f`Vة"'Xf5j1G:P/ F{BKscjM[condxnJF̫0#+>ł4n{OOjQH2ahH4sǰ-{0([~#hE`z+G[NրAZCPC#= Ԍ[\}+d&eb{W;q6J\uw465tv /|/--^ul|q[ /:їI@d-n2~<B 1f UeՂ抧@o07m0pu}yfBUp9oC޷prhAE@ <RQc;Zܸ1ZgnV03.xz7&~*;b~6봗f?>otDw}ޤNupy L"H&}̓}&} 9䞯:c/-/?ϐuΚQd v5g)i9n;o?^\:>u{-OW,7xt|,li[iaK }b}ϸ}~q]whO@{,ůA]S+Vd^ i΀EśaTƣe ohE9SYZ*ֺG`% |-]oTCX27Kۂ>ngؔ"Bےxc Vc]1\4yG[O]i JpӘ-u~jM;o&:@ؚ>3 :% v Dk# ؟'.9hշL^?/jfi_Y/S{kpnJDaXhaLɚϼLU⏨Qxam"o_"١N {_6K,^Sc6F7o/j- *{aQLi)Q*"U}(?s64<@-E.6Tu*NwvYwiW0}:>sChr}({ dEJP_n{~g8xcptWFsϛ7sFr\.'>{Ydx1^wY:G?CO9IFv;㜫F41isb!t6}y>{x}W_ڝw屇a֫#7VwR@iNם񼓟Nûϟ`JH#()M=Q߬6oPk]V'`/IueQSīၥü~}㠢W"d^l`|@*o3nu?J,3/]CJv6`ݯrn*EUJqg?tIBQ*m V?S@d2of2wbwaEU(?#fBŇcT4t\sa\Œ1P'>q{ЉXW&gk{U4J42;Ԕ8!xUr3fu@gx#iԿTo:XK]m*C_\(~8,|SĖ:udu֡9 -=W5'/{%QR4h}#n "X{@F ZPUYghXhyx'awb&vo#}Ù};"0%Qg>]t|9;ZLd>5eW=Z2Oٻ;w-}]9" 4q^{RP`?C/7Shs'\H<п|A^?^vUXWǬYrKlզUke5'x/:)J3 ]ۊ+[Yg?Z J8iG$aˍ"WM{m$IiVҷ1?LCSh7qH!+% j1aM1}ۀC|IEqЂ6i@r\mO CaU[VX l4_7BOW=0K`c_z$+(N#BAP܃SEHՂ@ 4`%Q-!q)yc F8 D`c[Oc@-mǷ|d0Om;m5'2sAΠ7UOOiL a cqdigjOfT%5{]wMvE`oMuN#c!lrwubsy4޺Lw'ӳMLǺβ/X5#&H SF6Ow2NC?d4{w_xh&>Õ}NORP(l~ sWoc 3>5H$romX㙯/wV>W4f tl"Aj?Tۆy ?&9c}_ Wړpw(nj=nsXW'9AjiŃ/XABUf[kqH!b |10:0G2B6M~3phw3;WnT9؏4i6*5Ҡ=K3npVrr^UXOfB`񞲯G_Do7e7NIH 5a><.A?bt"qSQD`F~M4h0GF2"=_IIxs~1&>_\kǹGƯz}/4l`xp#.9g.>:)_/Ԛ^| V!✶ tom ح2Ըa/ ɢR/( &{?p}{77瑾TSu۶cWs^&K+_KP}ԫ_S,>/xe/;Nd8Riv~=ꮇ2ݳO_c9<Ⱦ8m7%{K ac'?m[q@6#<4p2EW'7]XW*\LYȸl{E+o 0gA)]h EX6y{exr6aZWEv00D`ÛW2B3!=U?Xio }#Y⫿EA 7gj#c0| NU;Ux%͐҃wrVG`:N[TUD@659O0Zi -j|1C`ZAB5씥`~a n"P(CL}hz>58${ G<~t`pڎxiÙiz2a}8'.@pB;/Fx@|(1UM{فX4?  '쳾L7GNx۶;9:Ky8Vm } {.pFt_orrhhs2<-"YR~<5 Ϲ'JeWO X77nyɤ+3>TgmFwǝD"^N[0QRvvhmхyݵzzC ,-W |U575,vT{fȃej3Pntn"D)4kڙ}_"mdYHpq>$5 !ő]v9QcM+U QODev5hl#02:a>uJypvv|^yQj*B˨F&U) c)Ev?kjQF 7{Z^6hgˇg f컍 XM}u=^38>B4RWiK6n=XxifS|rsqzۜDim F@k+YE k U(R+8d/}/}V>qlԦjˏ}>gپ+bYί'NրHݕVGu9W2^'s0N™Ӽ_/'f@Aҽ~#->_vu,c}޽_  N}ŪڦWyǫQ} 3[ɢPo:~w>EJO@@oN3d?%"+W/^#h ^ko༬ƪ'/BdZ> &2eڿ7kWKNln~rؔGw^XBV !kЍt듎tzLWV/?&,A7ǫcF}pc2c܈!p쪆": j-jGy3e0fvU5'Y H # e^C}O]_Wmo @|K9G"0^kPM#ă' 2vm\14Jaȯ?rpM!dGO|i1Bi41Qjnۂ=6P<옻_dvU8L杻j/啳/[ },l97;wIU@L@$h& Iw`⤓t'NwtvbOfbMHH!OeyS7ýuɴL,gńwjۛN` >ۜ]&ti}`e /Fji>ݝ?Du o])S ăǣK?3o^#=. ̝zҺ}i܍k{ƿmzqG0zwqVaѶDgKxx&gdb>w?uvs0w|Ys8~,ћ7=~C28ſoƿw^2 @Fo u(EK/{ ڃ^lChh׮yc[g>_g w]^|L%O^fKWCI-7מzbȳh}Bc+F۲ڣzo|=@C zvl;{;~Y{'iŘ $>'XSwInM2Hz5/PekϰSאW9Ofd5(ag#ӒQV|QV$,Te83.Sn 2bbZxaoZ(<`6W?򼦦 pqG,!ްzU{0֞ThZFX75 Qim|4n,H1@_}ʏ F^J (`Bʌ'd9)=C#LvH?D\x </}q93fcX>NLf[lvRB$:缅3]yQ2/>,ظm=5B}U>_l:LܵSMo۬_1Bo#!"-(mS\z}zvs~4\=sM`9v@=o.p[ع?-6?UsWwwc o1@~FR48lh8T%>3+m4:f@/wm OW5s֛7|,m~}t}AV)njo]6aUؽ7_#| \/|+'DXˢX[ &9~>1|=ڙ =U'<[Q1sa7޼\J7oXu*^X JϿ4>?#z q0?0ɖ?LD\@U`Ԍ#E$MEErN ʓ!EU@͘,S#ʪ97Ĉ <8Tic+-XczSK@"ҨX'T27^^@ɤq}Id@ݴAiТ4 WO8K8 3cHoiޘDP@@[֧jD͠dx" aoy+>8/u`fs{sxKgPL>~a=8Oqjw5Ͽ1 )й1n}ٯ8Z@ |s|U+хBuEnjЬE:_ū/lMVGQ¾ 'Dd2 Plvvw?;\P||1U0t^?>? = {Z`?{bJNl*HEu]QsjxWř(RJ>Ɉj<ڰI4%aKUIHKmB<Z']dJϑCU=cs|njh_:2ۚ/iL\ݴi#b`kg$K(@MU{Fupo}06z5z+j r^[Ov.== Cx& ?%-zxW}N6} ,0X i?w듌3,7H}WS?8l ,wUMoft =l~2ruv4oox R |׌^^Pٟ7Ma|U솷/qvtlţ\FP֭;蕯:a͹sWcя>݉,Dr ztG)˻JZ4Sľes]{򉍶ӧϚI&[7Rl-^fڑbݲiyܪeO:7?-oM;#Zvrs.u=UG=\s]^v*=3 V-O诟?k[e4:]'湾|}D~"ub ϱWK^ n3rl]oJtv":<^ 9%)%#zG%Hzj< 6I bUaDNEf  "84 OkͪT6y'WM0M^}l'd>UWy%)T}-F|f-vz|` [Am@ e\Kxx3?J8%(\Oq ݜAo>{)2\ ,\'G%$H!\RȢw8'gC \=>nf1%o5u1: ֛@e-h$j芓:ǏW#LoQ#3=T~ F/Xҙkt̚U{w9A@J`zOtGN=ՋG89~WF{ηݻ/[g[rV،j睛UbfIM]+9dJjc}[Wgp90Xrcz˫UC"ؿz95K0hǣG{_}}}/ٳU?K`p}p ?^g?&P5JLd[yV6y|P+8k#LE30#hQ-R)դSŠTz8g>D Q=QBF=لhkcFN@a`D1XiR,d(G3nBީz}4Ip|j0Z]#S(tZ ],ߣ$Ƀu'`Tѵ|oHUW<Wc" 619 8j|[ g|( t3{JP@ltn2nQ݋_eieX`7ucǿѾO0M :[SioV^>8H4~y$붞p"=O_= hk|4~訃44U=g|~pwV*(9D"qDHsZXB9O-?Erhn+gOu0xΏ6@\b➸ryWX/:k']IG{="56&?Tu(5ǟ'?ۜ,G[cu9+F׭] +W>dN7Aa3Uu=ivktU!3Uv%D0ζ8LdWid_+/9chJZb|Nj[ʓ=!*S#zPI6:qaHŪ-?Gȧ9LP5@=ɠ Nb7@!\(|Vk*tJHLCXŖgt B 4}9 +Dk:T&j6߃A@e!lKSw-dOrT -؉cUI6\3;>F]S?ɧt^{CG E\n:t86jھWN6 x4+3W(qɣaǷμm&"+Zhֽ묹c} [wxppjVMRЭSq/[H]ݞsN x;+>,F5W:}[Xܑt!%& m" +[yI/z,pK_p-mߺ6~7_ o}OXs}:o_xOoĐ֣ƊS'|w"^g:j@U >g;d].[v.[r Ϯ1HC)C[j}Ji-炆ob;|wRx\v!QFS^I"-=U/*b-3ꁚ*pdl42qY/8jO,+w2X`!km(o9-5 MUiFIR4b,C пMv=3`pwX`4mcGe-C+,soV\` M)0kO?Ye|͍]Zk{iOwꅿ𙔄_>?m*(>߾ѫo,euw9}nb)/0=^z淎.TM wrt.oruxPfgg׬X9~}՚*F M5JPa_\o+]-]C0lUtcpu/Ϸ}ҩz.">&y|K~N"&zaN?"هùJb U)h c3ϝf)A<"]3B2f/"<" Y-+:? ls@X0^q>,S Úi^BƶQ%P{Hr<=^xm"~1#r9I /1*x͇!fg>@~O!LA7]F3C]mǶY>%up{WTA]ϝ~;}Y_'uA#IgJu ̩< vDz xAwݦ{޷Gڶmח|(ӋPИ(4Qk^~q/Zw/w?y [<%5G8{8}~F^",qIJTcvG% R9|f)sn3GFr4"9Pq]+svWT3G"TdNx<B62D?Ucjy9RLoIԓ<+(qm0QN$4z% ЁÈ3 vgiOff@1R7Ī *_w"<ZgDІL&.pjAaPA1HU[?2zoF|h2=`Cyt"UAݪB4VJz` Πc:X݆ohIAOlj}K7Ve7ޛ;z Gn-E7D`*Fذw@Br52\=g,XjY~û8~Cnpyj@/v)iCqg=*Kto'ǧp~[+i|`wgu)dYܿ[wuay*Gy0^jFotǥ74a@ZWBϚ(&|vVrKR[7޿/f\u H(>QL"QGss#g)5=̿!iHq90ep,ͻ:>}fWs'9Rz p@#d4QB4)ř.śz%JW=(?%sqm RڠlyGMCMWTĥ 0>6R㪂}3wzȠ tPQϿi=1f'(YBrt1nc3k+} #BQu+f!'x @$OVS2,@eZmzDx5Dkay Ք D kiz6L#,>[:O}7U#+(9SZ X&Tg_)0 !m{hsk?P𺆄 - = 7B[dz&,@&}2}B+*xĦO4R^ kަ. ?kʁ^8*Ot0L&{>}v(jU'|QS(1~Am" 3- ,|K>}nz[Y&ƺz耾يt]pQԴk*2i4;t=%`+ggf9fQIyʿQloݲ/ϴi /1ImLt&ڠKD4@2F7%ox{7HE6*~p-vRUm?_# )ΩINyGS'0dX^Ċ tw (q,ɲs;5`>N4,#h5+RGmPلfk1'A dZ1b;M >i|Q"ϴb}̈}>D¯@5${ Q p(GVzJq౓B?H< 7#R({%thIhe}" iB7kp]nz ndAg'gZ' M Lҝ[۹-5Җ¹9~0| ZZe>9ҡ72 $:,1Rc6Ex9nyybh?%,R癇,/!y2_Q?0uuw\L,1,09lgyIy$[p-[}J4o4"&Uq}In^-L5W7ƾݚ5ӽ~~m5P|.:3Go{p]7~ -q֛_Z~޳of9!{x~=j2lWܺWf5?/lߣW?UQО-aeU0Yh%wm$ڤ{K8=>}e z\UWM[Xx]n@'{Πm2X࠷hW4S2JB$&#YE P$ OݖG<-_l7vzmjͦvC?[oCe_Y`箅 lz<$ٓuně=[d/-{ܥowUχku33/G_o%X1`LÂ"0B&hm[E%XgYS|X0T`P9K|;ov@^?D1EjcN4z4Xu%oyv U} ߸!xx%X1Gᚏn[}赇Ygzɛ7 TKݓ?ggjesW˙P>$G0N(gR,$ً4g|z<)0)B I$"!<}x %Mz'{(@@IDATRQj|~ =~UG] m=HX4-8'>ӽlt:&MGf3 a_2zژ( E@50֌ 53qSG B)s Ap/[4:$m5_7=:ڨ ns!:ڢZx{l P 8-0mhӭI%8o gF-0I'B3?rxwJL0`wlǃśx80mG6vdw1ud k7G7/\7 ve/ ώsOqN?_FCWH(nv>II(Ͼ+>}~렧`HOY֒ҍ捥g)vGՖt GbHMݫfmYb:TuWҷחd&tozY_\/?p}l[9?x%N {gͪue%b/^Ȥ;IJ'?hR4'Ӥ<'5ӀOٌFMUȦ;#uO{*aϰWCI%6L.gBc mxʞ!y50xp|o u,Ʊl̪2=Hi:g`w϶hP:n7q( dZIN$ġA4clnu :I0H\{httY_-*rO"6?xxnp$/cgaa`ؿ# n/0k} ΊJG]C@NuxsLOw_}g⧏"o D0<p!)8 C!o`7omKS+k78=(Q!$t X^dUU4[>o9t#) EMi<<#ΓE}E U}kJC>ܰ9@/O`=t6IJ??Gbrr^JHz|~m2F e(JePm/UoБO2Z|&\t4PG}L*Y[~2^5]RpAu$hI3C#LfgzƙoYo>5 v gluDmA.wQw2@O/@iןi``H2pZ,+3͐0. s!ml.S.0'n-%y=h,4F41rXOMv 2N6,g NvLo@6 lM=uu ,\acYV-^.noJf:hi@??^?쐹}&Oy ⏿wxSg|f>ERxH4E^˗uI\owMIZ5t,z[x*=1t#R}6w*@Nr)Lݷ[_X:mY+9"{ ]x.T\LR|LW5Wݶ粧Ka >Do 0kM|.B\97>ڙ_|O%I?Ԍ&&f_le;@/SW~ܤ>rU3Mr䏜[Resfutimr,Y?J6ȇ`bUhldZbRX0@"?X`_v^vDtvH!է@LȶB"I21>)ǃ; 3W](mZ`KOo#\9\gq_YzGFSH~4bo@YI y#+8 ~F _C94,0~|sw 41I֞r?Rq0"*@ٞ~d4$t]rvK~էgX-c.7oH[?݈<+(m~³wStDٽ+6Ұ9?U&g(e_IX}] [<f䒍wKbND{gGSOg>._}iGU/ k_t~s/;Z6f޼ =wjF~מWjYJKX4ԓ̢s##ܳ[fG@,pTvg.хµ3AOueVn'OZFsGF]T}<uN5:  2n7o|k^ٗ}; K3*5)tO f,"zo(݁ a&6Cdz0]aB![UaKe/OgpD! DPϨH|>@#0R;7]4w_ j8H,0$/$hb,{/}g)f\ՉJ%W1J]Q{c,g Q QEpE Ac(kovw c9D*<_r x;LBiBΊ70nm}3AҲNG/ "Y~/Ts47^HT0Ȕ, .ZL{_8w[Y^"m3+ϊ,>4\rzvj[ VwkjyVLKpOt y={5uyyY3TU޳W<V}u+۷: 럈z䒋FBM!K#WRg38 g񙕜>}lעe>wo|fV]z9zm84*M~ M:$1/JhX~ 8;ȆWN2Y&xccE,UMdZ8BDsr|Y:ԡíts}QaF3A(v$8U*VT,.pZB-|1T)|iԦ:2ȃ5. KKG_`FWyQ;sE9+RZ/ERS&ix"6v;ħ0>a axfCW$#PyᾛWݽ}G̚烳k= Ϯ[_Ϭ!*D$8x\BYgwOyUg.5/Qezo]"u0*ٹ{oV{&EvSӄ|g3mwV YjC9sw]GX8|sQ8[nzյCQ+bΊV[e3);w DٯwƯ LggNTȎO:wzwNzN2 ϣuO?XJ7.sWOccOtRn$ '%씞4^*~}|0~c5tI rJ4s7xmMV”GO؏ ֓|:*N%I&`z0@-@QfWt\w{嵯g*>a1 x.1V;S$Ռo_S Vx>qP=zJ~$J5xKN%qi@EԾE ֵFfIEWUV1'{cEdh?G_Πc:X`y[`3_ϺύlӨER.zS%)\$GdT,0z˻+Q`l4Ze877b?j؆˲rVuũ.P@F<^W]?wi^8k=\ygNLOĚ 'N~Lpˇ2Es0˜?"yqv{[W=KAu<__Zr0^mKYmr6 L n&¡& ?H:J8 XKv"wiǯ~ի^q"|| 9Yp\*_x}>LvWcۑLP6Q (jFfpQ3333#]z&%}v9x+7@.PHD*)Z = 4,AP2 uu.P Oγ sJHRd%G , 6T3zhok)ebUkaT3JY0E'f)(r7rU^{ofT{w&mH`cK0o ש)02C!HIK>},oj ^jN(V'Cx͊t&0SPc<JI\㣚f] b>sI~ӧ}[pm{ 3~}kfP>5 OB$+$'OvdrA'5-፮ ,_ h8oW5{J#SĦ֑1h܊HoS#Wk^=ҘF{<%m~YNw"Þs,ם5$ WXc)3xuxt2ܗW=rH tiFP>:D,",=a'/,.Oa&vB'F(YQnsOyЮ{͙3;ޫAO)P>֥caqk@ZiOe75|a`(aBr,Unu58Kі`#t#Y#"F}@*kY iMKBqO]1p,<-0kt7H }%M/srD28!ϥZN1<^P;oiAhaĀ=N|-\{l \>k^c>?7o</{[.A-.pV3.㝏<؏o}~nG}?TRɚ͒4~`í;济EXv~쮶ȝ=mCq!n.dnFue[Nw9}]vgt&R~COQqhE8ѥBuy-ڏz+?2fv%т,Db NzQ~ K}y c wX3~ԣt䴤D|NΆuhs iBD|#S?Nz6ڠT@Pgtdc.B?qo+a3LGA>sѽC.^wD?A`O"j r>ҍR"K@ d4P`z{H`z_@aY|3U==?erpX`reo|ϲ ֽo؊xuiR3hIuF_iov'I|Kճ`o{/ll mNDPg_2hyS~-cy#~wuN|1o~iWY_BA݊4qiY <$~7pKkvh*ukۋX~ uWGL{r3}wՕ#(>iY5|.>b#QTU#)h{1tVrI[{}F4o.$CK)Leæ"1bOD e"eNCE\_+"0x3^%Ozg.S/H(] d_'N7 As=e(KNo]æk?v_ޝ[`M1pOŃ.2z j6=c=hm2"kbi!(5i0[~J:&ŷHio ܥ,zǖ?Πc:X`YY@VֶrEj)u}SڶuQEpO.JK6^=ԟO]e %rܭb/g!D!G<ͥmO>լeoX`%Wcd,7 ^y=g3,R& ;QU)ōk>y;}Y^x޹k^z,!EP/~ApAU}ʟA˺y(ѡwB꬛ի%[me.x{&:f|$ќ=JnjB"u/Q _ӵ+z޼џ>GO:&ܫ̮WwkJI_;͏']xý¶z#4x?z*ol9Tg0O>o| .04ɠX9`i953;݊'`Ux[_=d1 B-95-6uR"_bᯈ xQ41,r2`D訖 Pjї{o !Pu]'Ztf-Aァ X>zGk -dgV=+>Eu~ndKc>#,s~PF3S1 ~Wt%Dekk;"7,XjY~ޓ?iZ)ۛO䎶%~-s pU9yo>cc"=yq/ϟAEo{tƈڧW޼g37.zNGk4ҺzeOyZWX `эnH&"-?~ }g}:#tj5X^ى((&iRM$-`O9/\CtM[oy cKfI4VW+0:zT"4r\438?׊mp}кYNl:{۷q F@oox p*Or!Gah ~&x$©ާ"#A86|F 0rל m5hR9-xj ]K(Dɟ&œICDvN2wqne^Ofwx\8O7zx2S5(j]efX $iY0"CYۿ5JGIy?h2!Jou5|Mb`\K Q}D@7jQ5)SwƞUpmS Evgp VHP:g܎Q,<ݖh3r_R tUur({|,WLmcghow.&V/>r/t\I'D~ _tib:}ַ}]WyΩT=|Jr9L#aFxv"C-~s޼RU水OclVeپy%!]1 R<x xPL5㲛lC K8}O~Ï\_{KܥGTw|l᱄;oضmW|%و:\cx`P| }9z yڒ>w;vjHT<ťJ_[ȡTI%o3w|?ҔjW3Kd?I#rRٝCc-T$\$vxT1L},o.5~n^_Oo=ߴ0g+Ճ 9BQ4re;54[9ΠP[ԋݤLUTؿ  " X~=lIֳf^`Phax%BPy2Q> Mz3; - E8T:o{4,YѮn|_~QC,0X`i[`tOFnv:ւBGig/qђ X^"Oi݆$<߳UEGW8 eyZ`~ l.jCPrnvơ% /a"3n)W/*5kOמ9#-^vˮц>}UkREC!*hn 3t=]}>>VF[f7.>K{.I\P>wqw& ]x|@bzՓH*5MOkp'yy5q ?*q>1X/_j9蠪*;?x1evnڙ+W<X.5{plt)?I$(e>Uٷ2Oɭ[Gx[ n9=6J &Nqԇ-/ɓQ$D%^sa C)u)"6( Oddfޑ;V; eti:|fFU#?V̬fL(8[uX&} sNmt1Kjz# O“a?͖VAb~f$D<3 Ph(gAk5`P% i-(n;2gMi0Ms5YjsU8tF>9VfЙv>%[y,Fp ;4\ Z!Z 4nK'փ~ei񺥋Ug>P|@el1KE՟f_(mPV:}> &gПh]Q͚gAF{qi}]bk=h⋈#ޚD|tR4wgnЉKsSErZliB'8{b#dmOUp<;/7;wH3H)Sx-%iG YmWV"u`| YYT$ l+QBu_|~ 3\ ,E \E-T!2kQS*-8{8/dKೊ*" DM =׆ƖMݶm}]CC"W<=͎]cݺe4%kYg2qkjhʎ38SD?;q|Yv9򍧭~1j""E%c x{ޫN[A=.צի7;֤,,mu%Q k'?}=QX ı?EFUuC'v<(]w^y3C٫hohoow>A^x:5o\,j }<40̎[o}pϼ^LXp-K#Nu=ϓ$㵇~_Cm;,FWm8}Ip}zg;/+!%U(Uz K'~3[j)@5#YUOD~)E#E}S)5x弒H*% (h8xԈ !}OγEt߽#Wu+WiӝLOzTkʞ1Q@!Elm'XynSR( t~bZwHh-DwWW` 1 n{ƞmd*lb€QZo57/t{B ,! l}R*IWiÊ:uLX^`*}'Ybؤ؀@5F~&J.,h/c, o<,ɢv9 Dsv@j:ֻ6#l_WfۿTJ5Uz"6x;ԩX.woPs s;"3xM8RX9jٿo[ow{ozgpI|DRKQ7D-?0 zיZm5W)j{Ro7o:=h7UXn<ńCNjT@ ?C)=`0 a8}䃯=|*CN3d$D{G|损kCc8>4Y$d7IHd;89zlxLk{dfFA*aDRn !|b=)Pϧ5jA!=񡣹1 ;G}GzȳJay=[Pub7tXm򁿼gwJGmɾU]9+k>vW&Yrc q!9C2"6yd/&D CͱU(%'s20g@QO ELlSVe熟=6A4uRhB>rf4د̢2E7> |p|/AN6,: TTɴ|C+j|,hmm8Ew6G/<."+PKLfao?m6y$zI?^w}o%؅D1GB|1ο %ou,3+6=W%qD7Q{ϖ{<&Ͻ[LW5->kϽ? {&kk.B -ҝlbcㆭq[_zV]x xa ҆O [vܻvK.{̬=9>G>GqEoG|Z'jNVfz(X`8>x:}=e9s>R]Ta(G[W5͕h:<툭glgÆ79 b :ӰIRB&B0_@*nB[ v$PS[1D|:}~R:}>gK=<2WO);Nۘm1/8|sXص}͎߮uS˘-bȄ?܍f~SҊE ' &7"k-x, ~vc\98hɳ'ѳ@<0%ݛko;׳J-.qrz#TX^3~f;w ~yn4?cfrh򯸮aCY82̪9'd!7_`Cԥ$buo)N=2#^=~[olwpV_kY 3}16}j[9w›N;lg">2'xɠ)zHȏ0n PyN<>Yy 9lsF3D|Mw X>>M3akb >z&<̀ Q]$0,""}Ѻ4'm~ﳹ9pg NyS3Sw4Hpo8=Tg΂J DzD Q K[jBB:Y3H 7(hed#'6@%F?Ӵ-ק>}8fYFR1V7g Rm$]U\!Wq7o/y:vaSجޥ?>;ہu~wjrUW/JFc@7j lk,Ne#y#AǛĮ'mjyq?ϣ<Vd{x u׌]&]u|xK/SIBi cN9%v*33'yǞyL1i,QHl ؋&s@{nҾўwy/~Ko[`؟(wㄎI^}޾3yA#jT'nhЇL pOfX@ԐTS$W8g8%ɒ?'F3[/N@N9a vRZwБo}Hce I xܒ;nⰮfc2n ,fpjw/#.uGv }T$ 5nr Hx:")5'yj7--8ӊ}| S["HѮnygj(f~zx#ZZYEѨesNowX9t+㗞JgG~70)\f$I /A7.'(* iףsD񽴫$r @njU N8E'_E&5sI|T)r3ՙxuIRP1C@IDAT#uGQC`~#AUfi<|qȝc]IW:% ̷=X{2h {9Ć6C6.ԁՉxaX/:h_D͂N@_W fI\M`23-}gH9xՌ ["_W=Qx],Y`-лSP k6}t p LNy^s޼Kο'Ž"×>x3$O⡍CW!b0t4-+Jjsg\d&Lw:f nz?=|{߈(lt$`S?S1}v1DUi'?]?xPovBa>RfT*|PEp 0u8!(Z8' ևVjE`[ ,rbR0pN1-Dpv{]tإ;v\ ԏڼTO/J 2g"6B9u?j>:?yBd&ɃAt*B-HMteZ[XřndLs_xxϯja 'cnYeX*$}_SSĢc^x W}Sσ^ƍEgv:NC61#yc$g'摟QL!x .W[2@yl >?_ZB7I pzh@j.x)&sV:BF`M@ڞGLohlȇP| {J@#APwh?۬O'stS'kɹ˶dfʆME` #!@q=N<åSR|+; ^$ԂATx'^j v;4@+sA…h̶ N"YCrsӽ.n:; Lz1F#ĚU^*fS ˜rk%+.uϛ!!9EHti|f[s]S?Z}qrƊ,?:FC .EBՍ^jtSgׯZ^ӱlaE(Kx Wy{i#;#0SkۮP@㾳@>oճ8e*>K'I1Et9I'wk9k5zMs/Z-XUX[FYx `Ъwβ+\itX `:dNafkuAzdтW|`d`C/?uA~?O|ȳ]B^:ĒYKDAD P 5-_9裖xD<9.5j0.Q]׺7۰ٷx9fI![DSE(QЕ-~z٘SgnAbnEQX[Jb$ҧ(bITxCm ^PCg~}NBHlѯ>Ï)|QO;9~fZb1Sae ٜaܫ@)DT NqBg/kjQ"׵Hg^cO)z/t?8,D@] "LۿiJY`OoRJc*Fh& zCBX/PY_ʼrjpN@lqq]f.{n:ϵQchF|$dCq-ޝzy#e>z 4P E|FhuȚ* 7b\oszww54}AdHdžd=zUi#=mPL* 6IC\ޝ~U>? T @Henb# t;̠̾WG|䣚4]3"R2Y^>0^hnsմ}dU>ic^N\0 tڰt=4pq& "al*GJ<ӌ Ng䣝$hHD[Ck3 Y- P\A?1Mh XXĐ`2V#:|vN&#}cjazBF\'׼W|#|5o&UC~#ITNzַSeQ/-?fݫ\5)AI8x_P𣣀f@qxw=@kea@6,2VCpU-?1\[q`SouqC!?4KFԍq#gcQzHuFSG2sgq5Fhx8/ІQMWŦK)i矯Vdsit4`1W]왝 >8UD~Q/ x0`ɰ#=o%,vDMܡCJP[!˚ 11 UU $Sƞa=k "a4[E-M?oYD[gne),ᕪ 5iD'm](ۼGȉ!,_|sxTkw1P5ض?C! G9PGuƏ#D\nig˺7Ƿ<=}~~^eBg9KX!.xxD' 1"1K?xҁH~9FvVQ,*y6wji1g[▔Eq %&Y*hNY0@_ީ@)e+k//:5-eΌCk+ǵƛ+ޞ}h  O_ ZhaδW= 29w+bR꣎gy##+{7,kC lwڲ(;J8dćE1WTO NjPm[V$B<\x:F)x}W<B!K?!Ct$e UBj2im~k: t@ "KP7T{j 5=~QOGVG++*ȓGQ%Omř g櫵ge-ysG|N'r+kN 3b6u(u{jUyab 8"j;U-݅*Q+{'N6 oNr@zYωkv1P5-qGULgۉ;^۠upJЌx)Dqwﱆay9ÄlmҰ'"?!g3ktϥO"Ig"=eE`'ٺyӷvL#oިr[8oҞ}鲏k¹**Q"~5 "]n)ȢN>O]B;>:@KT\inL@ӱ{F/I\||ylI䥸V]Yx0d/pi)BdG!fF!Fdi Ύ&ރ1&>jK+ 'B4N@[BJh"y: `c"8P۪9-YSCn~`3lW: t J}5ZpXȚu%/x/dga,3/z$4'!>:AYzI]uN6lh෫ t9p${ьxkC~Gؕ=ÏW?˺Dx}U5^xn8GH] #w߹-_% ^ρ7H|v=V;`Λ*}렼]|D2DŬӋ"F"LLjhn׻gܶy+FחZ 9ilkӳ0 :^8wGy5:г Fj`V~U8J.up;u[ۀޱ]5uɫ $.\\ZE&jz^3ӵ+MpYp9 xЀ;U~@ocJ.4OUc'fE;[oOZ#)-Yӭ YX4gks7# A;/MRf& dz}H*}%Z@x$@n7eLTU]%84_WJQ-9zE HAAGK:}bvC e Guu=cg @ﮫm[0?΁ i3KDv"$#}SYyqH]}NKGr)oj=ݕ}koiQ=H^/xִh@֌K||rleo;]F_p?c{2?c7SVO;Zb(79 A((ZkН&sͷi}b >#<,3ؑ$Ɖ6'ϊ*'6h9ovsTڃun|V`-F n~i{9;/+;Cy +uA+8 +udAuЛ70Zo}s#^~yMFCaWkq0ZDF/}O5(Jg@/.7Obu)kBO_柿2#Lx}_}7c0H*U#i1%BΈ,^#Z[GQ.j:?/ёpdZ!uTWVP G|J! kQ*y\Mj>|iu[6|Mϫ=3KJ.sm*ppM@DiμRS,T 0$(C4s㳏VOG+ogi~7?j:BDŵP }Y|qoBέ/f&<'N#Z2{,pӁ;|]ݴ.C6mnz{7[}>L{s8 &['KQItU[CeYE>Og;ۼ~'ɂW=]rTD T"Qȶ?=s3-8$y ;AP'VLO^}kyupo؆Е?x=B!8rDV~AހxH\9Շ |O8XAy}}kK և]J:B/Uۖs-_8+!E>J{ZR'a¨Z}(ibLC:U  \3<op^xK>2@RM>$DԆu^/TeK󥿩Xӗ'x837Y 9 (E=(V`ưukl~׫80@xUھyIm wťcxpWW_%.:f%F?XU ч~h[sz^E`EJĈwA^:ۚO)i-7oܨ7oD͛SĈ6c9Ø0v|yPu[]>swe{\^Y5Z%?`bb;,W50!g;2w6QVG_E#].JE70#>jWdA-{_~Ȣ6zBCͻG̒Z@\tD+8Pm8*M\J 9$U\xocg cD% QvmW_ogu/~uRI<իWUzo^۸\)#Rl_V\qN){hѩ&T v xуh}tmIQ"|'r4 +ElYD=AX. !rrJ2 Iz&#~ _e'ު oF#EԮI0{P11c,:"ہE,`wlfgBxtxF[ﮫX^,0hY8c|sƏTѻ[κ~~'8dj:-Q҉pz'wl^}tͯtUe{$\Ͻj R1Ӧꕗ~bO^. UQp&EƂ}/LǮW+vS<0/f%{Y#e"?F߼uW]@ ޛ`>KO&x8W Gbpht#MڧA)ϲv a{ }~{Om|a2X]{ j7uoO@;o_}页iHQQMzↇo |lsԛ7xy >>KXKOTT`5p:ȐA"̼s>Ӏ-{E6Õc[7oZۀ~ᗍLT6B7 Q3>=x% '> ȅ1b#%сGx j;AkdM;`jTJ3m >w-aq"vOWuL&TՕ/HUՇ3~pPq ç*'2g1z0u13RZbK se0ƁCx[  gSQVscd(Vm ^c)b"3H`>RSc@̴d q",0_XǛj9'#‡ ~"A8%N?9Nа|JG<p! P!!ؠq?6' k~E̩E+&blӑA&Kg71殺l^x[ aX}֘nrO)lh_>wqU{epu8 3@;'")TTď>SNtWׯnD^V"rf=TxŷQm9?"XpI:F@n!&T6nGK+duzy~9ip J8%0/HވclUsy(&~wRffǟuԢ wZ`a2-ˆXŝXJoz׆(;'>.kg^~Wzqg1}BʳϼTޮ88d!?v8&0tT嗟DP7o46%T'tcK^%߽yt]u-нcm5m{_PtZI*KE`0o&7\\ՐQ.:Q- ہf! @r|cgg/",Q#1rK' 6#ډietBt=EsPٟV_o„}\jg>,X}9Oۤ]8o= I錏gn>0UۇP ZC }1#fWt@a)aEX~XsxC'f&5kE2$;乧X!+hkCeg\8]oH3%nEW۾qK3_rGMp|c N5,qR0ִu/0Ӷ'Օ^1o۵^$ԑնX-rBzKow pQ}4bP*,1lP<Ub4|l ٳ܄h6njuSoXݟcr~ÿG.g s2 !e8~*&rCV_suՖNopz>Wն k JCq5W0qg pתF"vk}^=C^;:hX/f}XN ?W?.=jCM~uz=:@U/t)=~CH_wo6}޼>O7o ;~'?SF`Wf0~ Tt־Y!J_M_ߚny;uݶ@ۦVg|;(.ŧ pI0wu%9UF>2!W:\H^cPȷj9aãNc>DIhW;RU/22Pߵfޢ$=wQti4櫗r|oU+]-\`ŰqlO'g Z&`g"&<KoOg~›HR1S oo샨.HqbD#8U $0C/%B,Q%Ň KW/d;M"BغmJutLJ>B#CD%*)s4t,!dB>CYIٹĝOck&Vbey?xygw_kN:Zxr gHb DU'Neꛯ/>̛/ҳ62}CAJAY4!y dF%:v=o} =<=sxa}@T##b@$1]O\%p|kwL4sΛl/Uz)M 6ƳW8B8ֽ1/,m[#Sv;3cYZ{V^Z |]Ɣ66!'+5,m̸@T9RByo>N7o;ֿk_\&:ۋ7*#6yOA^l|g") {w zU: 3m{g߼/;Uǿ$_`j/*9W\ۨ"9XP/1F C !P@ҭ @ V”]+-'yS>#MA_n}+qDgz"عY==5dO)&LAšAx6 Z_?# |j1cDU[RXӢb}w~IK갛}h@_2/kD={֛"'h1݅܈zY"‹f"FO@ 8+ސ>@LZ= $4r[̜UatdѰd^,RhzLǟ,Yu?x&>z ws(xSjrW{Ϋ/+.hu"<~G J,voWBw3:ބm=Fʰ?]gcu7"*KH%ex}y՜1t)NNl"H6Cz3Dt% #wjyٲBϛ7 h_)6_ 3SEuWJvOv ?LVP,⎖A mH cfpdP"B (䔟$#dBS P$iyr- !qX?h{tB7X6gI؄8C{n_Γ2 :4³51mRW[6ַ}}O8{ox%_5YK.X8}JĢ)֑{ Ͷ*懿|T;!)PFYz?լ-tW+,>/Wlc/ӻdS #&BtX:)gSK(El3;7o ]|޿1>'EJFS'XsWe%w$8 2"NsJ3gki>SmWiX!H.0",^}#><Ɖə@!ܟ~Onz3f}b7\O+FPv,2W6]O8?9xmjbryszg[t=@gv&\ڃ>:u9<g]/M.*"{Ά*Ed"/rO†tijv$  j+j*]NZ>HFsH_`@L5 KC,>Kܯo [{ZSbRUpmD&h>+ qt&;@xO -v>)V'TWo5 h b$G !Z/ZTԢeY-.`EK-T$yHхsVxsgX 7D ;A86Dπ{ ]TNL*nŷ3J$^4bZ&ɷ:"4P]e1u){*i.5= }mJ7Sc5?D_GD6~LH)ZշA-{~8{N^baK "oMcbۚ&aK 8 t%0.Z`g}ЇsOws rm3k2`ķM}YՂ{ǪOQ4x,.GcY9ƦIU/^[yo-g}޼oFoh'#B`?G1OCu~>j4>Tf^뱘^X)c2V"T9ry]yA[W9gkKf@))mp\f6۶ACτ|̓/x탎tKurt2sݮ$C( cYqYG {yx9&zUrO,au@ƛA[\OpB m.ZJZT|ta﹅%s0|%O\-р9?E0w#e{t|/xqO@뢓5oG? j Ӟ=boLƳ>_q ~hA i)oOa塽Lxàě ?<ήppJ'Xpް0 ď\-P|5c!  ;]PۡPU!PpFO9%E9T[- 1\U~QK~Q8[mXE "TE=<~]8S{'Σ;a4 IbJ^D80@!pccfϗ~Wu|dҲ:aQ VqU9МyY=zosYE6X ? ^n ox::h|q. ÔΖ#ӎ(hnh+! '^ǀThw\te/,@aRVk)̭$>.;0ǽ.YA )N 5^@:?d{e}y3`=K6,! Wode/!,[W`Ӕn&>kFks_u-qrj'lP0m.y-Yv^gّٳVs\I@_HXCchSR?uc[7˕3 >㠑)Rl-WmM?=ըȻXfI,L'(VOUpXogxsZpkg擿,_/fM"f\DŽYkMi!txX 06;=&)kA@*Q `,=j UȘC )^](ZD>D8CQ"gPk׈f(5産Ǻg`2# qgt"IO1rd˔㓚sfW@"YڰACK›( >118Ϲf["R-(3-EU_0w8:bGsâ'K`t҅lQQWfa >_- e{ Y?XpGQGm#+ EO&{w 4W[uN0lC`>,Żֽ!}Dٿq)Q8P3Wiiz!G¡~2XUg,ѕq@=n҂Fn>]y?JwdHm&FzS!琲[A+8d7a1' 8`EG,Ia|QDVP‡VѶ"mNda#C'"THLC!QVYa$SCK?K߯۶UݷRVP̚j 9<斛B8ű(3$ퟰ^Ϸ3Mh*b&U7CJUQ]Tܲ>% 4;u:ZP ~b@w.0k1$˟cgdQ nkSCN :AfK m8PGN)Ql jSS>@p9J;(C#3RGٸ#>BuԝF3:̽}9Vg"#F]t#tڿ/ݤs qvs*TaccYDpd]VvFcڲYODzhQEZzpEtc@^IVM`#W\ X{W^|u DNVE0_੨^Usͳ?jofgͻƦ^ J(sVo/j/>g"2}>w|`[ж~ aAeXu4NLR52-̰W F9(mW#jئ]uF>ſ{ ~sQ\_o"_3߈;#\%޼o4S.mB ᶢg/<{s\w t`!blhN[I+W).6%".n$|wa |6u;.@IDAT 'o{@- ;K%T/F˘ϿOC3բEF8 pL9A4\b-KCxyIF@(dPR: [|_ 3=-O9TE~UQ2tOh 7㎞v=OO4✁j}㗡te/h۾^XuuvQF:9D !\=)6{]Oګ2\Wd/36`xX&ԎK^?r;V.lFy˧*Jh@f K1_wxhֽRqҳwYSxJ,cl">΃x6(tGxS͚u#i}$m(l?ғ%| sa56c}R9 ȗ/a7f hPq$+4oX8GX,2' C"l_4ma-×\+m0ǃ#DzWqս/Ј O C*q}a^ռn򖛙Ngn9H1>>hQGGϡME<@/HEsNKhiG}ꁻqg<19b42C sO?_^A/NEcZᰢ+і w1# Adj‡Tjn |niTgXVGwB^jFQBEӎYUB~w|K2)-a-"x22(?a*T22`W(RQ^6R%.ޙEJ~bqQDc_%|jČmEa#<,YsƥYs87hCT/o֨M;_foN8EcI}f;Ve1az,~2ɦO?MOzo\5 /`ӠE59,TzP'ʐF@U_٘0 N;@>׺x9Ѧy#3y}W$)S -vPudV+8`6+h0>Yo<3SLaCfU8XZ\1l=;='{W䈃'1ȷ`GY gGdoxxԚ}g#>w׭!"p+j#}Â}m* P4T }uq@=&Gl^9['/="Drt%+x:|_Tuvz#ŝ:X fw”TZ+Hnjùfڨj|#ZƷ)A>W'gu U=xðI3`׷ KphMuw?}OK>hB=tEGZ;/q'PYd~#ۀO`8D&,?W2-N@xr1ܰ|t@Z|3fc|}Ƣҳ%TfTEs -jhT8 <=/G0T(1VvByp*naQ)L?Ss%6 aAw3$ۥQ҉jg֜fi,o1i1#HP!oVQAdVe <>dhYW :fY)'9:;^?e}#E}wrg /p޹l'wɚzN=;CD[VQe}azæl'kavo\d*K~)q~iG.Qs\?ArdЁJ5L,ΊE8־2.*s!kuw(9X?aUG-J^=ղe .`"$L$޼&fnzL;ٲh:t£+%w) gBWI;j 4Hg1dd%>|p4J OCQu)xk` B!_:cZ8>}U@ڧ4L? v"-&|S}LzY^gꥋ3`V1P.>ƍڦOlœaC5 P8t4戠r-W7~y` 1Ibge9Θg[@RF;Nc< FxqQW?_ 쳌//oz6;@1Zm@ZMeUNw.;q2([?~D]i^}PM7uK7՗ 6K쭸J 937C f1'>w͞ҷ}81`≐FuDuPfʄZۀPNmڃ>=;ҕGzڤ8rHRAIE:'Nf$1ӅWdC繂.qA`1%E5 L4S]BLx&H((0 ciԅtrv7U_գJӠZU Y|]}Al8Ʌ=_szGTbGg &Jkd* 2E+&GioS5lǀ$ִħ`4*-ǡ,+?aǎE .zyK4,Dj zMOx?Y2HhTB!ӊNDgՁ7?f:!1 Ceg~]ӲFH_'p,RLgy&Pͩ.PC>9aWGW֯M3J?TzejcM ӢF\sZ}n3?_-_n0>/~ZO3=oY/š:R*SU7AO'2X\fh^^߿qH~Y6/Xt# Όr=Lh' F\r1wY9R?c}~v+0+ofi֎'"_<BxF #w8IIC bs!<^~-l3L窺z9AϬ.L<(v>U ļ65.v}M'(+b)CPA`!?fU_cRx0вyc}BceGZ G%u("b_OdN|Oo^>ϪDP3&3v 6`y9#*C9>ڀBSzԽ IuQ=b<*@u_ϐpSK軎_>w.lW94ٔ^T7q:^ J MҌS'V_SGSFI"+{PH*1«AکR-dAsĞ=g2 <+4^L]7ǟ,Y1Q=i=sěрƔ@w|ڼa1r\}>kUt#crLz4!7ԛ.f_OVB~}7׾#;}-U.֋+xL ;e_q4.93QީY;%~'I>]K>CROg٧^άGVV܌kze_qh^V}Q2P4A>ta86'S_Z5I]Im:ظZEF3Nȏ]2GFAsna(P<*%wfU1XgKY[Utn!`̍Kic߬8(vl\;<_ B]QҌ g<`{~]CANzӻ8 &[oUS;ͬxrL}2&of<ݞPC|,hXRj @1p_#KIҡ4X]c5Ԙ{ gӌS<t gUW4;0l":C&'zD01B n &F̰|AA)X~ RH m16jOSž"f)iUI[F{۸#3g:_l'3ѕqK+RȬ#?;YE9zܙAk^ (aρff6 ?pQRejͱRH:c4qS(qT-oW}{ /⒑E L6m忹u6;eغn{Á^gpՂW~tϺ@\_]^iwh tm mۡf#%*G~oTHeHiS` oef@}'AS̀,x`" JIj ݩI ?2xj_NୃF#a2OWb!B5,m4[h IV$/Ic?}qbf)/󤍿= 1 d܆" iX!ߘzϨKD+?ETGu@#vYpuk0.HG:i?Բ@x6mTr8"lKti+e >B#DKD3q([>5VC(aP"TjҐx}.+r,=8HY)CsG9/XҜrDLj?ihd뛿Z-P/Yڜ^Y YŒQO Y)dN<_ŏV'm/kWglLNy];?3/wYՂj{KCPV069l=}Fw(>/Ao ,n{ڻ%0~ H%1׻ڍf}>[_C9n}}Ӌ?ꩲgs0"¼0lLQV^_gԄVu̬9#L3/8ҲCQJ{ۖmO؄8B}ք©,c|w{ UED:pdZ^$*~GN?W"HZ+2LW&zJԛ=h#tU#)2"4R^_;E*3`Y<"0#r 4s|HAdJZ"K3B,-x[˚_'ezJ:> zʶzDUWLQin<Տ<G>jcD]mdLZ/(c^$"UTѲNw#b9G18\ o0vk1Ň>BQyO}1؁ңqFŠng9x"5|{8#M0$STN*b7j GrW7R"sI &-_|éAQMg뇯 `03M' ,Y4,NT *Y;U1nO80T1 O\ !Էv,P_|i5wa&XR^Dj*KC>Sա+j-H.۟OHhOǨ@O^=T!$ "i8,HmĻR,;ol_@7ṵzn~y=W'%!w񝙊(RNU Q7}p۶oh~d!xaRhD56`AKDهy4i M }B;җf0JOmCO,{g7s|~EJ :~0OFmT45uA}~}W Ļzyf?Ss>S(8OY _h9NN^NxO*०RT-/"ctGx!3pa^w|T;eUdGN+gs9}pSȕvڅKqn=MX4JD$HNf##~jxg`2" 4 qIzFqGNqfzw]Um([^ikL4jÁVhptR諿6ނ5;9we /e&9="9Wh} |[hn>V1$f ~b ̐Zt$~IJE#\ϡyqKhE|qOIⵓb+vM[0u0]4?u%4",K% (X"JHW8jZRf޼߼L G 2S0Na `rי= 0 ̤s9H$HdْOm?z啴o?+i,ْsP(RAR$R g?݀H1=30SԩsԩꚋgJG>s5}= 7LJAT BM cDpЖ<_wx7.7o@͵7rCG?PUTV4Ulw߼o..~9:=7ļJmF:n3};A>tEAEحV~r598w)T(WRCha\c!o'&.NG9 w-IU2W7g #l%('{d jx$)bd-ͦ4TdI/fs=?'dǗT|}"Ca$ۆ:qQ)uCj#Q(dLjy_$!YjT 1g`ft*YQ4S>^@N: ]Nɤ8ُ[R}C&THj _F^'kLlui #7$!D&lE~ Umr9ԡЂ$Ha(fyW?eV/A ?|4l'5W}r MQwOr/Wfxiy^L9(@j!pq88$1/cФ<#޶d j}PM*ۡk>-VIbo Fy=S"}|Uvp1D39i&Ncf-P%*D!'V1t@ Jĩ4׾i8joaИy VAA*OPÏ ޱy>o׷g Y7a/x@q|b8Ȃh }c6g>@=ܒ˄}'fc92:Ge4u{JKB^,h;^2>ifC-u v~FXPT_Јd~ERk *P8V/-I2Uw73(bnHf_ɾWŲ牌u>z@(樃*ٕThGU$_F#%ZE mbmwwq>QA:56rcd.(>FI,3K]yӸ}5wG(џ]$$n Pu.&vޚCPϒCYU0<2r y|& TE ,psaa#}$9QGe /SQfTH-!] ČUqkAzH!뛉@p2j>n>'HRӸ[P84-^v1DMg C,=:v/G8m̆XG|o$J̯Ȯ:UGq-)g'g;aٙv>w~!vqi*>(FJUY47gOZq|x``{ϲmwn8kWZ3gC oCl|NWcτ  6^@eA\KDesTr/Mi3ZGt2Y/k_+6xtiuoSl|%[x_68h7p}/ox1T9ZT ӑu c-X/9rj>>g/oE&٭>՛7NJ; 3:a-P^YrTFk+>  A?w{Wd{Rf-[^|R#e=et/X>fg*UցhdRVJ1l?^`o݅<fTy^Ny/)9vΓ>S5[o&m2ެpg \~~ @*T֠DNc0fr ey[8]7A +$u"Ji+V.iP]^s[o6ǀ4Y3- AGsfŃ/f{o?{^ժa`G9RQ\ۗz{j﹤nS++#$w#M'2 h:p=kqA2o cg욟.2"Dl؇YAI&I*{ g!%m"ƒ"#ZO_S~mLCn̑Kgp~6/8}ߐn8}~y {r9xN)v'K GuSqgɋ#1Ix:}2U6 TУzgg ;%-FTs$Tet?E#ز4?A#?%$~Euk:К r)Z)_=m~3tAOiK=?oUk C4(PC~G`#r.k6DaJx6y Ňg0P>$!,Ⱑ*EZiGQPuCFO`8V~Ѯ":OՉu`u_^U=Zi}+U;z䫫r+TT#ۛ[g8Wru~si@҈i{ؔҖR~Ʊ=gۖ[ݛ1|6dI;2,Z\ L?ǢGj7~8xY,*{O( >elLƶ\xd5Z7J>wMۯ",3^a8dD9?|"y`ɝ3g_p>۶Ky(MTNGk >SaM=CEcώ%@l meTS-HcV~PL4]ׁѢݓQW=Vw3!+"ԒྖXfuҕE1k`!=u\>܎?z{n϶SG%.aA$$JEI,9$++@m|_ZMԱ=H,N4j+w}t_J&+ j#7@R#IDIM2Q~"S+ӫgNP!7 +}BWh.@R7**e!=cޚMKeN+vCC5.Z`MuGnb8>-yn,5*mָQA> i4=wO΂_KF*u|Fvك O[wx8?%:`8/48'DfOE$=W:@eКV^ڼ3",]@>Y~l1\" lIW}Z-䂃b6s[N]xsuL4TУ ߜg+9jz* B$Beڲ32WğzY˲N*BS/cĪ7ܝ\96>^A'̄ Պj3A@$M3 *`)1!YJ0r"/tMb[2liޫ>3hi6A($D`b}şL!nv CMևxD>'~dQphD6#gFd99#F~"=Y4Rv&sf^d)@U84W ȃ~uƱoL+v1y-$j2$r9Ɂ+t# Ncc<).Vo܋+n^Wdb991Ѧf3#eO>zeķևw>va,}84#Mrg4[EMR3}VQ$#XlW'21Mk XNze?Yaς#GèMيT9$8,>IfFN瀢*7UuA#q1@q-!)T4'wbW,C䥻|A%Ѽ]Y(`CwQtm V!&~@~>Tth7S2>?5&zR|҂$Kgmp^wDK`Vh9.a|p'I;ꃖˋlKhk>kF*|','mך;ڌv6,]{9%?򸐞x"H:Hr6ጣ?xU*|4t?=.9 #[坉@m0cL5r㣂W4"9sV:sG@@]܈>hy9~xPqn/xjs}A8r| Ϊގ]nweCUz}3ƥ? OcD_\xEN0^vDek7:u&/wMr=nS)\L/[$0l X__,֏t>szcZ.\.MQ%z"CwY=6TCf=M%q@Kl`2ќcUkFP0;ɥ|"O/omH յ?i[UCLŬ`*O/OQո`|I{1^f{5/Ns|!pi<)/Z5#<(*x8qf2=K~^3)k;6AEi,VA@/LhҏGQnA:ϘYUy z&kw痷 ?}'@\Amۗ4+?GϧKxd,~3T]@>nFwlī+H*|;&&^oUfpKq\}!G:1 im>$ sd&ONA;,j~V5?ua&i**Q!P 4)?{~=VTv5Б%+iI$xT lBgUfrxOv[nH}ęXwqmxяdsw#2 QU*?Gxh$XoA`F?y5"U%1 H"QQ=dR$ܻx1g"mIL5iU<*VqځKzU@jgLNEkr5эdnb4Ri89u Khl\9|z/9UzFpp8}Re[Dp~W9f׋&iu*mBxe}aF<>M?;[@̌F W"HE6i9ړA\y݃PwD$Z#osp*%t3oXE3,x)V#~lg.'wㆳt3Kp'n!<⊢/NI:SFV< b~ cAc$]$VЀ+%(*ew'~u+C+x60>o|:[ƆLx#|d1 \sAMeOZ$IH\imǂDO[4U~![m*3ծH砓MԚH Ѱj1jTWl4#.tsOh. W-9V.q:?|αY҄*uv!%Ǔ.q 2)rT/˗+Sp(G騨8rbsR]kxOa;J]@Jupx&>3-KoD]w5(=R|IѸH,-I!O<=z`[>qB~ioNws|xcʟc|[5j:_dy?'8߾;ѢS<pY+祟x*" 8 HIfS=m=HҮ@O}'zQI3ʛXn8Eȁ\` +d2_m UNXGU)LNwV2v%Ds砽2.zSÅWEAAekVdL3e^rE#թ7XA 99H-MF9ɒruׄ e> nE^0-c%c7T)jg?YKMiU4͖>̩WNBFX@IDATF7|USBZ2ufR¬w 9 ˝[ܖ(C. 7՛7I7fФ#lr'ډ4GljҘ\iPAhzQux1@xC`#儠ҏ]գKEs119Q.i;/%?lYsm1scs <.XEaa<$\͙9p7>$)d w*x s?2k6|ba+DQqr d^fLNA3E]'!BIٙ{wVvBr|ȉ3 ӴA|C/CC+"cpP(VFEF$uO)E (֡oN!d֞w-|+"%K'AeDvQJ[ 4H`G UҭBt ]sЫטμ<WRO/wпE9&ԦA2MZ$IǬ]tQoAa"pq|J݋ƚÎ)TtRS{ ӚoY_{&-~ "0cp4,19^+UeK{ȇ ^ pwIo@2fGf U Ԓ%h99߹8x;PZ풳XR#ggO}s? LTmƟePymkPB6(m|w>>mӟ*%;ZI>rsVDذ1[x_68d9i .lԋuР^uϪi™xvj9{jy3[tTFHճv*4.;mP:_|Rp!M˭ Dȉ6DuTAUOGw ow(V\YYZ@}oAN (e)pXf2o"f5C~ޙ2fPP>'Xҗ82fyfko8Fr6k+<"{AHSؘw8>\ 8o p%LZ! mzV+qV7@㺟Մ?DŽӕs#_1^*ģ=f\Fx?}β?aqP ?VaaFN˕sN.viZوݦM=]]1\_qw΃IP6C.Sn ]w3ZWf`{\K/8Xϓn=!(f;96P= V@ܲbt E_7D4G.+YNKog oYI "fM= z_%<.yOKo~:ߴJhq hTHH0bwv%dWOcPubѓp:*IFAiqE\zJ,(勄-B-q< C&;[A; b%+󊗲o~*{eUB4XnYhSN{t:*5ćI,p;s)鶗@#떎 YG?KFޢ:@~4-n'r /(iԞ>w ݙ*=1~Ig;hd⏚ԸŪF\roټ'py+iu+~Y8kv;X,^m x3u0tjx1"-rIU1%1[Ԋ!8+ /D^Gp~W]Hf_S} 7Mf@K iPsCk]O}[zP$H*yGv챀_&`qc_̖-KtAa3i5DFheTMy q&P2\1]0 'w/ q]tI6q"0tDb=9pB`+5=YVj"ŠV~Q[pY>o~>_30eC/|kn;Rz3ݷܒb M= C?|1;Vq\dyaW`jLw@p>YFaɌ\;Cv`*os;}?ν[6m?13.Y- 3<93ĴӅ ruR'Uo#Oq-|:YǺ|goy+&#h*x7F󣙁$ːMX[)ˋ-Kg [RMq鎳qv>oelTr>*,3Z W+~sh ԃC*ź.PCm'<*62M[?x6nKҗ3}8kO4@;mW\hlg"[P1D I$ ̑pщ}Ԕ*z8Ğ";='AIr7~LP{|4\5,%)] j"{|ٮ ' 7}.*TqE=%($*thWj{Ñg[5o gud8qAцC x4Qs󣫣7>m7o[9fY>O91|Ǔx }WU$dvAcYQSOԁ([x:}XUI M\@wt.CAЫ:SBO$Pj+[_5+,1ѧbC?L;RP dalf>A!P+M|){iͦMCsaa@JC9Q1(:1$ht>#@d?_5Y} Ƹ4WE':}&*c$ٵUEc1cF9RYP* #苳 LV/&M*h_9MZzZY{o pOm*D_/۶? ̜ZFd!,YeC.=WU֡g{tnd8s !d>_>rS4q姐c|Mϭؼߦh@$>j\}LHin|@sFʖ7oZy`ڂz F@e[}A`nTbJ,=~!zѤμQ?zٰUyG!^,.S'Ϻƨ[D q5G< v_^1IMl[FAg/~m:}^L+Dl Q̈́ KSEEj3 ()2u:ґu/|ԃ[ƋZMCAow% 77>⅗vhoOgP3hHI7ۢ@s_54%%z7=Ʉo^"*K4}C?/}M Xmy 9<59Tq[މc0u+r'gRez(r?zVJr%̭[nkj[ζn~b2 p,^̜z̯_1J>ss1\_?y7nKϕvlV[D_?C~UYO2o?gdGZ~:?BV.R&sv}^쳿d>OuOT-mBϝv7ƽp yvެ$SIJN8}FcFϼܞtgSjS?sU#42lW/Ҍiuҝ)Fhjg}+~sSlx6yğ_zOY۾de2JAi&?Tlq,^^B@e(~Р*~uAQeK93BRWvlIU6>m_ϿX60mė>2Wh@5g"u2hC$.p?O=T2_O!LԉGuLLVmT@[O*>7g>Hq Ʊ2hr8HQsL5UY@ u~6}VRR:\x+5DP4&}:Wk"h4n m霶 Ѣݔ TtoŬ~s6<8-OҊo\+#H E-H^JGgAF'/y$yGڶjÆ^Ƒx-G~`?وX B7o\]>C^x$RV9#{G0!Xy~>&Qnoķ֪7o*(rYQs<}tGTw+S?O-}< [bser>J(",G7~wD,f?5{'b۶dv$4XW@Uhl|b՟ԃ-%D`fC O^&ӊ5ŒC : t(2O1ms_.{>q:usId˭$?hN/$0Ťl* WĄ"w𒖤\O䴉9R]?Ngz[&`o:|ճR2ư9>*1cPŠFQAC! WXe-L_x <\%;뱏ot/-"t-o/n1٪K(^]OOO@'n>ORlll[qF_ j59°bS[30O+[}g>խ/`$?fy,/rp^ 9ZBUPtlN[ !kS&{ߴQ[&儧԰R7@!isVbo xvO>w5AZVO^O<.&'Q?B~K훐V4&Oꩾu LUb'u*VН2NcC>}e2c(ݤ%[w#r"B;Erg*-{w|"4;dz6EEBkMr*|h&ԑL )9Fy#5}t.1G}tJ MjH EW9-u[d,!i@>=WsKM܆%!<'yf޲ yp.9Mb>& v&e 8BA5j{ijZe@m<… %"9iFlNҡ8bliE_SqHkp1Z\~b5h\+=M<#< @U5(1C ":jMX5qņD>OX{ Bc˶rW]بczdo`oa!k{uvmگmܲg"ĂBİ +|8zlU;gy޼6|adksO2ɞOk{r*E68scS$'>WJ@:}Zt۝NI0+u\?d(^`NrGCDWo dоo~.p\'I#}?nÊdղ]t4#T%! Q|`g+~XyRif B#҇}soP~3}O҈(=xt9 q݈S>'/(Ν}bU@zaR!rLg;NJGgЍC/+̘autM5͉_&k6DHo_{x'6>?H_>g p?ĄRQ*䋪QVM-0AM hij!")M%T5"eh%z@tx-mɥ哼翚=4ڜx{B&F H0& Hk!(ȶW]$FsWϥxF쳀FTC|*!bB=j_.>,Qaim62Nٗ>*9%Yj9e 7f;5V=)G vQAZ>3@} ihӥx؛ 0  Wj/L'g/;cVφmLt% v!R!(#7s"k àQ91 vjaPx(Rݾ@J&[$"k Ď +6; P,y ˂:[R"Bוֹ`f/=gU(6>c˺k~x}翵O7uxz1=;. 'NlB)~%Q0×!'۸Iky}  +pg >zq.3XoGs~vݷBY'- aa lأpU(bN_iÔ"N;/ٶA`QCƢ';iڻSV*OH/B#?tFL冞 .ۈьȢ0C=]YLҒڙv?v>4H1[þ-XY$ aFwwuNA aijzcvypKW.[}٪O4_>qw?a"\{J$V.tȟ{&__?୸C8xzy 4&νHs84_^?|AC>w߷ޭh{LTp(d]IȅoW+Νݮ'$02<| IUy@ PvYSv}T?W?}Fku!66>ýk|QW?K]IvHbM!T$wNNZ}uhBmas,'QF1! vF!$N>YQUEJ)?Љ 9( m7P%{#&׮@5]*O_5Bf[ ;& Q{Y~:}&"[1eM>!ςxf  Z)jrE]@CmIh\7l{+9h&ߢVnoq%?|RT't|g^Hxƪ~^[0t-OG`ܜ`hy_$46ɦ1pX' J0=I~ex#:o%U8SrV~G],&7Ҝ"xD<ր%_1n8mS_Y]MH* 6YG)M=]{|_y``ڥu0޻mIHR>{}(gGdzt$uz9a]];>/ƳHt_~ ZXUو!0|t}큸)aՍUP0KhqgtNa725]||(JйoG'KE;EÇ2{*#aX\~}=fQ_J|ЗG{[ 3V wM59$C74J[wvċL]kZR_`+} REe>r$dd"F)LؑW)(zݙ.<W7{܊7EkBH/٤;7>k=`FL|,bҧ*Fkz~mP7}]*M Yh 1dx}v!Mg)+{oiV,`47 #ѡ~ؘU%Ua#Du0eT&j^Ҹ=&\Z&?*6Esmy{j"y*A/+H2+FZKf&d*(q/tIhCZf*PryRY#p)cMHtF,=&O8/) Bp Xelr'$Nu[|/AwxTƱ+o>1aSvxeO?ݕ wfCz/l8 '~9k\Inkn~Lɏ=${ WN'qoF$+ 3js/5*o,b!8}&N6yu fءx2YC4m J|dZnFB,pyn>΂d¿sz0SL$J;D#jeo&#K IJP7}4@v^;%`15ʨ@xT%1ʒ2,{As{g3}N#Y5S#9C,3s_1U=\hyIlN'tP8u Vy\"4Z0rCbѡ; 1 ߜoJz/ ыNo" 40;o\[=-7-fuS63(φZx|0psY6fo,ߴ3;Kh| g:؎>o];#R'ĄӒ34[FzgG-|!%(|QЀ ̥ Z'?6^MF>m~q+OL@bD.O~8ygSng3 }ؓ Q3H׋~&Q^<}}{gXpՋ֮g@ph}#f܌$Ie ӆgOm%y?9;gQNBb?}t'Xץ~G+7-eef*Z,~2rWA{pMw? HZOvZr|m.feV4RB!+od2.(L*FB>uIT@BP$?bq)!7sWGWͫn 6SQx&܇3hz0/@ p¦|uܤt)td,Ӱ$RQB _p 8XȌQ1S9l2i!VDKƱ=QςFᤋҚm}7X׃sO OvѹΦFZEnC̳٣x΋m )ø$>IJn3Sj$ӏgMvYhibbklnbG ycB|  zxe?:xaJoJF66| Yt$wd#DW7f;8*$NPY-yľsZ߄S^y@KЦW29}fvm.m<BƇVً o;Y3f1޼qI>?Ћ-zH 0"D'2\@ }#s]>\>"];O,uyT:. @~׏~⪣3wWQ%Ia!OMHTYWMl&D9h ,$ix-K N[7!QKnMU4XXyC`oͳo2߾fڟ?G<p*$ߘ"q dyar͘n4OF!AC-3+s:{-:Nvuotί?4։'hNpA^6:RO|/ճDJN<}}v.]%˫k!P?}KYk3.dechpD-U);żCW| كWmϼ\>XVf9CTu.Rd5: xw'A=2kO*OHCBP=qI0~`:h}:' "sx5؂_ L4W~kg3菾??d_jEd#\89,6Nj氤kﬞ}nu޽<'8m"Zm [lk#ƄbP@S5u)ْ(Oq͗6MՊ{09s6HW3& Gݞ%7Tͦ+^(?膦p{V.) DP3nBX'JM}RfU]prw,sdrZ8N\)~Y œ/Ymx8}um}|nٲwm<"P۽'1c5am8 < 7ďI%֥FR0WAѣzas> ieW<ᚕF[C,ЃVnϛwu?<$8ߓ{FULxÌ8s|ɽ6^ Ky|co3rM3Z2%5kV_3!R!g;*5N٫̪OzowyÚ \1:؜x^x7׮K( }t=BRY.I(4k:S(U2Rw?${,rWV!;/o_2o!Y4,u`'׺Ɲ("Th4_wֻs|ڟA~ȾIgSi/!FzuA;km:'zmrNIo5jjV[}r:I6~6C#r&,A E"SBJҍ vR.t׏vc₷e}N'k>4hPqd@v<#_n)pL+<,6R[oDF7]xz7&ލ?)djp!>e|Vn oM6]8}V›7vPܔD ϕP="hi\}B^ȵᖈ$hxSՁOcQG4$N-IH(F$NugԢ@0eќR&Ԭ+n׶Π??d&iu,Qkw.Xq$l> 8TJa|X :A ݼ"DvsJ>"&Ԥ6?<Ir( @I{S<z9$lf|1z@~b8Hob6u9./{:M#d hY٤*?c fųw?#$1 Xٕv HqRoD$[ * LYI,:}NUB'>}v\i3~;(N^iK!\7e.@IDAT+6JX TTA{<6ך\v 9Iאʔi"ɿd/_vtڀb!Ewn<%'(6uMJF#/{go~]eiߋ3hCBfIЄj$@ĭ\yNTnhSiO W$ӏKlVEϛpaČAQøzz/֖lp&b BO!;;%f-#~J1"l0p\?6o֝uƏ~JtZp @&WlaiH)/6"l9h,ܭs~G?R%9PV1CRNָ>76nuDc%>sx[ (Q$Mj d񓉠H*{&Xu'&T.;L:hO ǩ18h 1D(!:XqՄf9cg5悔&Md3큀IQ=۴eH: mdx`Ba bTN"=nf<=k{X(ݪg Dw>}/kƿgXV@w3u'nw343˥W>l#I# U~߄2^34Bю/+?{E[4B]@zt$ [rk~"q5bXg*MX<%섲,qa[57siBhnqBۚ ߗ Cmo3m=ᄄV>u:fx :9 (+52clƚv#{3&Y7åh"$gsSpA1Q+ҰU4#&ڴfy=/BUz=}xU^CNݖ|.Jdw2zA_~(aBQts( B7PUC/{Y犳a0-ٜ* t@t*5;,ֽ2ҸXXӛ7a;OW^C^9&O `jOΎ7D-;Pop>>V*@%bguӿ߻iVُe٩ ɀT,.T׃dӦUaaO~{P^ &*tP`gT jh ,'|~ʱ٬c }֎:>csiK2VBB!0kQpxN<*в,БMH#"(TM;xԍxC+$Q}Mͅ I䫧 ">S\w~+ SQeŁ&jjx4|ǟ ϞNhWE,T">4z&`oxyꇖdwߗ.\M+c0KJLk#FozYUY!7oW)38gftxԧ~'҇ (sPyTg}#Q~յWL9%qN W#5 }ԍ%v.XU;z6%PZhnHҤ[2x`䝭{bIh~)Ut򩞡 hFf\4͙$+?mbio3?wM*IオvX{HXŻ77'Ǧ,bGCT=t tRl"G-xQ?5Me op[=Sކo":ȎJxrFhdDn=|%[ׅ [G'\YN?< 4KOX۰!}4k۟]_-JgxksXl6M@@XbU[5?73#pٚL=wANB? ܒPƒ`(t<IrJ}Ό%~ٕUt,4R02],4:Ķ}k4WvC2[sk7p^bn4S%`|Qn遶S'v8Ro_'O `h)IϪ;E!={#cy͊ w^ ?Š"Jhĵ"<M8 lY:}6 Uq }8T(#8w'Cx EP/6>-%puUR
-Lڳ=6lSwsGv6NҼ$,k($(Jɲy#ˤhFYhH{nڂ]q̶HQ.D$Z'4yS6n۟& @KjW#=F΍N^]6ڷ`?ZK;=qKe q ,ֽ?OO8 R# o*R*@QHJCG>(ߋ6Qg\ط[fl$*`#;4zL/Ⱥ1ԫQIkcE(kl>G}M.|ƻx/fI352UXq멍IwI@3Gb.jYN`g\O-K:u!@Tpb$@+pB@kzuuѳoV?bY}y]^ܘiѓ#?-K羝xT/Qsք}ԟCNt;tx$QIq({q^[pɖ~H(U=7aU̫ʃkC".e'*0DWfTRSDٻw?\w^#`332mTLyGI{<]yoi`O/AcQ[?qDDPRe8BbWn \V^Jʋ46O ʯ@b蟶}$O.:CdZrG曗^O~|#JinwW0`U rLY'&\ܞfb˜=?kSCw!T̍pvR&HiWl:  y K'(b¯dŞu9TP832q`ۚUX-*}FMm`*⃵uk{+Sk .:FJ_J/GO)܍!m!яN .>t?uBu‹uk':1!&܆Gw_o]YT{;۠yi΁A~}u~p,go>mD#Rݐ=)QP1aFه" D$ JT*|By=CP>}_\7wt>کB )/d .]S5(?P͘XL]Uי,EF z2SYnZ(#LqhLfA@)˙aKЊ5N@"T3] xTG D-hIPq?T'/lw֧$È].ϵσ!M-ˊ)`Vk@ǎ@@>p)Sh,JZF~ %/#Xh.@^bv\ӑH #SD~Uds0s/10Er2UTw'|l|/bUlqχnbaNĈ$\JY= f ^{ Ô-} g>0QS>.)s|u?<)Dc 5Pdsy–xbEXˤ^"_k7_xwUgve7៞pҠF(@Vmt?RJpG]]=.}Y[e_)6#?՝$F@_^BRP#_ચ-=l(שjf{>ˮ&:F \-g^?]9r5u>7~u˟r4pW(YoP(bݾQG{g~Չ7/{({=@ ݤ)~ñ2N9@K!7PTšH QE̋MGUG.;@<ȷor{'20wGMa |<l$+oxٝGA@8BAFSݷrjߞFo`׫ %1NyHV}{{$[(22Fxҫ~n5ao[? Iqyh6SgrJ`ypL٨&)VĐ a,rM`Ȑ>MP SuQqm>=jg1~ur4,y`SK8TЕ YL핤jqCi mc&^`\Dg /ꀓJgоm!BS|jhX)v,p3 mW1 x;NuvsxH< p`c(i8&>/_w_ng|v ^;Fw~A @(RIgy1f v`kMF .\ϽgϜ_kHԂr4uHH5p9&X_W!Κ`s2\R;KPjK !B5Ws!MvPU@2 jH]z!ƤfcWD2OqP$Vʲ͎0>w/*#ϫ@]=XX{0CA]}eէC߬SG^ q}[uOQkj3ߘ9u{3%ɹΌx˧=wscOONyfTԉ(^H;,q'g\K|PU6Z|柾t&dGB9)8?3\}Çe۫MSF@7GD+`  @[fo|.Mupm_oW@tK@X|*0\ę>ؐb))|lD#z ö.sѿg[O~g|ƻ>oƛ7W'h]ko#}'l=|hXǟBHe'rCbƗk7}u E~}vWW\6⹀^KN0yV]D&=y+ лwQ (8pLsHJXb)Ar>SE49I'@"J4c\hG6鐘*=*dj$D9U)Y5@ ePR\C]on¡^i m5 }nq홺Ouq2Cя,>v<*ܻ攋Yrq^KpNsp0%R&"_W7 /N#jDr+\8 n(7q`~x<VTH5]v|>lwHH} pt Fƣ_>'4Y]|ݻzyÍW7`{: GuIhuƗkF6U(lDjvK؛9~ᰗuU'>SyᇲjO=y/uG;H}z,Jn )r٠y13"NHx3x sIqoϣU=>,t]\?1da1?ؗ޿ Jr#k9z.Nz}>_S5aN?󇌰g=hP"K yH (ق&r1BǠ(mg;!$ň hv鵊Zg:#ITa{ҨDY \Qѽf |j[lQV@6[E_|_L$Bx >1u\۔24qpk%z 6}t|Ü.&>p GW\SL{s- /3 B90m~cvqm1Vg*88ˣ9(Yx8QyO_Bo>}zu7TM!pS؇lJϤ2ndyo !M]Z#EF繋/ztW,t]5 $-B̧!ē`G<|@2U2}KK?#g[~Hu֍NM_YĽA2oS̉] -Mq@ϝ9RLQWo?]5ǮJ<&ᙣ@Ç/xwp?rO]C@ge8 !g?gmir``}f=34vAGw\v8YzTɦL#>9Is.cBdi(]ls P3Ɏz9I3$; K$'mJ=(6"bŌ]HXU+NWva5"OqP-tHs+.J(/ B37z~H3&8{mXhw@>GKGz_tTMmCw7(yv9͡GXK[? Y_n/dD:%olsd1}qzکW4_2fS?>(0 sbEו w5Ї{x|3- ނm x< qڮkQ z˫n}sz/=+oew]gGT e@ҧwnz*ą. GCTIS?u~)>?6}=17Z|~;m"#Gizw@W[|jŝY #Cb+gE+Q^$''bő#W.E %(# Ӧn=E樢] m2 B\+° ֥(+=t'ʵHOB AbwZe2BF%d -UԭlZKPUeN[E`i5BF2+eYij醝G)D HD HqE@kodt}~r0sNy\<;w/ixvOE-#@hnǼ ̡W T~o1& 251)T=,U*Eb{ňJaʫNW\(s'ݤV5 ͪRyF# -,#HRi|Z"6,7`z˗\ݖ$^Md'xԌ}7oCxj}6&I@sHۆ~3D$Q5Ab,^.t#`W(~rE#E2IS_%bgLq!5#$Rzڳ=jPrac5!Dԣ&ڈZA *A= (* F50PjZtAd?Ae$HD H1AkE};o<syL:p>m^z3yy:8NY?afz~y$c;pFk׊}I@A/H6~U&S $ҝ\󋔳Up"ʥC8;G"V~E`LG3CPE(͛UbBPbŲA #V"kCP^"EdKjIѩB [Ȯ>)HD H@Li=3>?ɾy#zM>L}(n'IqZzՍFLu9> g30rZ}64%8zz$ +Іt֑C3J2@==B{ʊ8xUHpH]e%%& Xb, ֦!.sphj$ե~6 |m"TW [@Z[dqCU5jf\qUvVv){ R† Q=P;o$@"$@"yic\_}^o6&]>o❌_l:((6U> yCg|up >\=F}"M>Kgsd )Iq7MnsjqL2<4#EX lG+-zi"J2h~2Ȋ$)5(@lX@ʼNU"RQ  XD/ڿ}}O~#fdX  od1|!i"|it Pe8.}W ͒}^X}($E# S49BN5Hj IRR, ¬r^a]&yʕɧAuYUa JL)jD4&)Ud.w6PHڪ,]z M Â&VS.XCŢ]jj]eRUQAʆ Bi>.~X),WnJ+yND HD XCMZאַSkh5<'0-''g9]8hğzNk}^=)y{⫃X|hgޯX}kLv5R0=q$O$YWdrݸwK6VIfNm՜[}־X4=kEx/w!’@}nyfr+XƫߖQhS9><&`ske ؒ)q%ks$hd|C oꣿ^f-ũB*/ PΒ ECIh^f6O]TFU: a3Lլ.4HLիTYbيuT!HiauliǏ,bk8(릨" .֑aն@)[4?Z-zب!ϸtJ7oclT=j<<D HD H:}ǎs>hǹ>?0Xw/}uҩdZ\O}ƾ|cp g%":7kᖥ +gQ&!lsvhmK"#{꿿$.'#&0}8 q' -VCkRXV)hmU3MhAX(*A35K(Kk jUf 5%ҶXY#pu>.e˭=aa/ʙSQezne}0 Ԡ&w $ASSFo7~z)G5A"$@"$3C>S>_>>}^c* }"Y Cl~u} 4hn~ Wp50 ._õpʖHń*Sd;p&Z@n /S9) KysBAJ{ 2W`Z m\ Sn+bIvJ]d!ejfK#4(d'1i7>":4T0PizXD!Rүkyk&L_}d$@"$@"0t>wTag#7|RhУj`ra]42>R:ka}N_['_P7b„wљi}#cgwYFX|Ⱦ:¼$Wuo?~Ur0mɫtg$,-oq{eK% ,)K$j~ ad{e$!ᓳ)n YB(Ԡ, %Guh.b* -,T,C*R6 A-̈́!YPUeȎ"*zTRͺ{pй:S"$@"$CDsԲ l~k}b/LUCϱ_yo6}Wv1~BM 9;S]xNޗ:b4&`JԎ40 #i"R'D -+yY,t⒕CF8"R<(`srقg2dZ1JisJQ(KXJCvޘYl}~\X9r{'6}N1@eƈ0fƊ}I#F(O@eoi̐{ &{+Sp0"Nd/YLz&1Tّw]GS)SԹ4E4LUPRhA0ք']Jl('M̃ԭl`@u)$&`5kCA+<>+"^)[+w)ʕ #3ӽ75"#@"$@"$G@ ;E,o8u*-=5g|uZ^vU:>fB7߃1)>ö$t2o"yR nΒ(IǩKn;ĥrBYyx33ל޺mD`DtgXk͵{8l[^99L}A1^>>`;m˱qyc`XH"hsb ̉"-KHF D8HHr1X^"Z &$+yI*F=T6E[Y#+YA%%yBRE[ TEAR24G (Ί QB":PvXƩpPtBmʭh"Ҭ+:5B@ 4"GiH2k=6gQ2]27'><D HD HVwޜ쳱\|ig[c,dSjX>gv=,3!ij{^?8W+NH#B?\mG=0q/UFT,-zN1G%/MR JCiGQRzYJy3iY]B IۊX}c{S-%! FD4hܢ AqҞGO0? C6,a֫9M~ 8a"$@"$H"Gn߿O~gtM[FG@]w3_?)m}ε]2>&#%=&&ͳ_zӇCQ'< s>Xa6SBWdvQrier,BiJ:ORBn2 ҠiW [^"UjP.hlaSО|| )DPp&t0K4۠ҀB6@bZ ¢tuU0?X\f$@"$@"0}hٿuI*_`ssd/gQwOJ-S?}_~n~u^>$ǡۤ CFyqop3{( d9q+eɰR"ѯ %1f5 *yI1*b1OS#)ARe{Ur,JD*Q 0Wlg-&tH~P %),6[.2[քDֆa,rstMsG:<.ORED*RDp:?=HD HD  >w`ȌE]FY2:j}ށ.Q~b<;i[oڭD`;%=n5f#BPQa4ﴒ2 &CYFaTfVZ\_l?hJME.` jqjjil;g O^[nhbYqC{OdQP)6_+Gʙ:Tj2ףHIB!uɄuC[x<}99&@"$@" d; }$>+UvLa\\-Eyꖝ,\vhUboGp.>eO@.:*^H&7=w4࠵>3 YQ:FCf>UN>ȓ7%LMևr,*48 !q JUEf+D*0G,-V8@IDAT;QGHO@"$@"$@ ^̯>أO%rQG/$켁|U.7$B&ٙyc7 q"nEУ؋cKD/Z[4"Z)%zf&dޖ-G U(+J1(4hhZ&J,# "׈&'!H"sYAm0CX 2ddBTTPəfTLUp8D`ITE տ`s!_P}Գ#D HD H! sIJSMYv>޺e&#D >/kr }~w$/o y|̵# g\WOpsh Fn,v $HJțܐV(uX(O%EKHQVakB48HJl>.3]LyɅvHi.{,XYP uEA&2 3WS 졡E6,AKYjxVg >lӯX2$@"$@"Jv?Xys/WLZs]P:a[ڟMy"8^>f}}柒r8v紩Z3naُ'fi=DټQ(N$2 y/f (edHEu@Bi9K9pPo]rvQ\ЖfK tĜbYp($ڥ۶2V!,".٧L(j/Й-~+K-/yY7ϵ<g;o(#cf͝7Qc`gcթҘ@37:(8Hr<ѫz;g"'Ur_fm"ɋ,KX3KW.@b )Hebj~&ahɐO&0쇀jQ0U=Vkri  h&,k䒏,G%]A͐Zd_h,p:9"ga"$@"$Ck>˫KvqrqlkUԴ*}ndwz}.#vL-TM57[]pNmr2H>$ǥKk;ms,_s FO'XN YO,.ĮJE; ,(UQ=5؆6vPtɺSVVV.SZl4$j&+aKJՁ=dJ^\/ uGJ -6aGKc"?Lj#zyC#D HD H ϋyU}yN*I\7s SFF@}(^ 켱sO:|UQ]$A)@sUwZ}UL-̶9(:Yi0;ײq:R19ɲ05UyL(ڨoXË%۫$$)zyVHqg2P2A9U)!"d2x^M?nįA:ԫ"(aвF7ShMf _UPH8/}>l%y$@"$@" Y~Zof}^y^=֙d;dt,[3 3}~Ql}.87>?-`;kmX3" Vfdb=tk3)3V\tX$6ԢBb61䬰YLnȳEmQDu-4Ҁ(*Z{`aIj΢稈Ke"eG~C><D HD ϯg; g}RL5E R>/<4}^M&>3ߵ4 q[iǚ"0sHyqrDƆIUӐHO Bj0ѐUJSC^NURZ(q\ `3)Z$R" ̲P- (/{2 P6H3ժ. +XD;Pu 4$(( Kأz)@YUE΂EM}ѽ_`uȄ~=PS"$@"$E`Go3$ ǿYi|Ll!sGW+^6>drϞٰ&=m͵Zu"mIjS ne\Nt<ŕ*Ge0cY,1Q_)/FU:+e$gyH[p_ƙi* ![a*ի6mOXô*PivAD4*!eXW O9ϵ|q %+ىk}==.l}6ͽ7U7gX4fDl^z/9\KyҚejTH:(-ywU Z+sD,0 #VewY2P.ZDBIPjPP*:$ fQZ9f^BmƯ ='yRA{XG1pȡ!Z&O"j}نd@"$@"$An>7m3ﳿ:h^*Q;8>',@29+;o`z$moWoH-& >^ۛHk qc҈#y[s/5Ǟ0l)|% ՖԲAM@:GD HD  do.;o4鹹udAm۫&d[\22jVX<_/e򀷨εD&3Gw޸2oMz,['l_ A?YK;$3YVNn$~ɨ]1.kq<ϯtj~nF]s= ƭn;;v5s3u~uHFqOw>_<GtcҌ@`9T2t)Q'T\,engUW ) V|4Z,M^4(QaIV9OC)j0O16kAS&%F>r|i|Ų'+qVtDyVP z?*c0HD H 3vސ67&zw0@^NXs$ϣE`%7&}\V37s#c>' No;olLW7F)8 ykM?_?%v[򤅉\LXd/33,1 5YCIEEob 2LD HD ]zzf~?֮/}`L7RC|b8}Ѳo+0y80 |ukm}rAKz'Um6mYz6/8SVLXPCТ D*9Y(֙m]xYESRfd,+(&)΃ ԴD;ʘBDu]dRJZPB|DJRPċ=4#=WMD HD H` 9>j>LH?HG@Cnے:8^Y1->'{^*yz3\}f}ӖA`jsƟtVtG* Y,ƙD-r+[Ѐ50r"E=TBiUp%54ճ&PbR*v)涭 *f\O .FD U@Ѫ`/9勇l D HD H}kVOͿI`^{ra*C>m1ޗ:@?gds>c͒PXy(/ }qy0 wTQݜtxd3HZ^jyUhyʵT|q![,ZCԉZ1Q&*PuhJ$9l9cW8kDxE4-~6N\9c/Q8Ph9>e 8{?jsρTD HD 7ӳ|jvaס ȵt ۏ]:ς"#m"vogIyeH `d 5>B}V7 Xl>PwȼDLmjϕ,;[zan(o Q`iR6m32S@J]ˍՌ&۫f]iW٪4RȚF!\/ z鈮@؞BdK+X-#ſS{?jӦD HD HU#k3:8ndO43[<^S_\uKA@3vuY춅F\"D^V J3UrĽzsA2e)һ&o!"M!듳)JS!K(%SbZDBNjg;n¡^)F Іy;D6}ZYmb:D HD H 0yr }ҿ 9ʛ{}}JL%G}^[>ϭ^zppWL}&G@k'^7m@qOEh-R*ne$@"$PX>O` ?VM-ӪJy(/ >0pRYrp+qs EF |!Zʍ'L&B5W9h&oI_՘eNYbb_)lW,J!HFu䩚Շ8u0JW2c {tERie変#h1*Q'1و$__{ Z!a^AD HD HV>>yrwx;o Su@}}<>c ϰ73p٥ۢWxl L `{=dϸKwL;sЧ< g[d{bDDS"ژ*FBЬɓ%hyqĭRvC3jR A~dsiUأT--lu9ip;EAi nQ e>Vt˴e"HD HD"EAhɥG,/x:3qYo`sůoHXћ>db}.s]42 /E}a:U=k Dc@w 7^kx|V>?PY63'e}#E{s+yI:bWү%N'W0u T8S:e!@BȀVib>Ro/- a=lmО6Ga}K{i3$@"$@":;oKY>ӧuprRZО[蟾ޒ++yttv>'qoH9ゔ#D_6$t EF@V(Zzɓ=\R^.f#@y'w;T];;]kd|ly? yBw Yܵ; hCa"h.{Ws]G.V"B6V ok)GX`|ՂRrjd)~(P"*T)b,bjP8*2[:$?-jq7BJ *FegsGDֆʭuջ;q D HD H}WqEj~8twK^+WϹy80 ۚ ߠU)]w={g /&sG@󵿭Sn}nH"h^e ZpdC!w?IzMМ@– x18 \VH:g - MQ>Ck ![-R4*5přbr}&HD HD ?PyS|u>į}W ]rJ+}dS* [W.\;oۡ:2Y>/#KdAc7q?iG"m^{||1^b 0YVu㉂_Rj~JKd%lXCU'妛S6OVS%W]\je$@"$@"0$>\7KTlۤ}ҿ_zF^6^:(yH}0լ`^^=_ܣ h=hqB%Fg!N;o,\} f{R-F7zksU&`@Tcs!+\>X}~,&3}6ED>r$Ǡ k  l2ZLNe AXChnERGK%tQ "V5ʹ܃qbڼ03Q)+N5NDQը|4E*j]4k6k약kd@"$@"$CBs_ktM<=}u8pXG]s \<>jV>7Mfs 7U'|`\2wk`g|upQ<8 wl~ \rM7bPq▉V/ԣN09bJ%,&Z4 Q RK52! yGctiAֿ. QdRuH:#&@Ub9 IS׽+G"$@"$&}W6Ad4of>gLj jQk6pff5Cu嫃5z<-JdٔvjI٣' Ĺzԝ4(4xC44\b"oLkIr3^&-qRK,ީ<K]qE8n3[{VmUav&[E@bK%+JX Ux\yY)#D HD H!!eMW>㫃t]ҫ- .?U-}W}R7L5Ae"&ywgJSdJ{A"̶C}>&L;jZqxUͿxxgp}98XÈ1;Rhd#⸄d1#qm RjٍBD#=n"R&Y')]i w%((LkH]@@"$@"$CB`<=_\WPxtR|fz!݆Tw\|\o!`وFrWgs f׮ ;%tR>OW}\Ư`V%<> ?`(k۝7H/qd{JOԓ,x4]ֿ_j6A:!AVF Mw+']̻Ay@D,i_@IhljrBmr`ZVRu4S僡|jǍBg1 i5W՗JMf$@"$@"0$}i\R{Cﺻ^`L]FGg\/-Ūϓ>zx'>HTbT y)v2Ŕ+CjU[-⟹ĉ`k08J. #՗P D HD Ha!sIeg{Zhz>wph0̵욹7FHd K}gtU`soH{%]d1؊c,N0Fhb IUjn02#UDU. WbI(nZU\?|3]8(n?Y Y{?U0D HD H s]d3'Wss켱V~zI]̝7kmx#1B}aͦݴ}A>wƯ'!u,KV@s%Օ63+=vdiM%q,vqk$0 *(0.Y A() J]9Hrjaq+l]w_6*栐0' F@s_cqrEY6XϷReJJ IG#LXŌ HufrC^UPP4P?uqGe+UȶpQ#EdD HD H@><9p"El1}N'G9X9^KUi,`\u9#|"khtL8y#gaK\ &47?2 ])S81rE "{R$;T`ʰ4άWUO|qKL|[/z@+.i<lԻG+h10ע u@o/<%@"$@" 7}芩''-W}~2SWƤuq޲myxK3`g}~=}~1# zǰa$'i#9% hG"pp8zr~(c ETYzvEbFE~L̈.VK +qP*i4ĭUfH!m><D HD o>kfqby8˓f8Wsgw G>c\ZQ˗ nsƹyOϜ4 freg]@ ď#T2<N;yZ 3[LgIF+.stI37!Τ$}9,~C@ҪjVNalvŢUWy/u*D HD H r獙^ gKؾ-Ig F_NL-E;oૃPΙk3>s [A̗:}^m>}:}g δ[ d}>3$CGഗ5I[ά1UJ=T$=)Sp9Of9)gzt%5uD~ibG(rH:TV u{;ꗞc D HD Hwh[%+'w]|}:BGN:}NK-CA`CXlrs-z[_JlB1Bk KRMaIg;oD"#7I@ Asx55+HD!gZȉ?$6Ŝ5ǬTfljDydEpqn,tS.R Jbm`ZUY]{6$@"$@"0,bzz>}_^9+{ |Թ&>U"Ν=}Ƌ>ϿҩUj]s}@k)7~s cx!>꫃ AϏ&ycTIDA:vh!D`8?YOmR{MsM%:i +Hw.A:+; )/1^!YFȦMSufGFD HD HVCߩtsq˯N6:h󰆰uwqGMC%$WD#3T 렽Z𿞈_23YԪE4S6PUNPu]q3ӊSEA n|z{3N/yND HD `ᆬ/{Sǵϓ>s]Sz=+'<:>c `+>h}k;;B>}pynga1rϏa!4chN~IUobVX47O,X×YtYn!\*0R`f*c8KE-A+$iSGW4#HD HD`X}溿do-g켁pBF#lglϵ(Q#urpjD3,X 0kJ;}$aQ0XkyOWpKM;faMnnNq(SL"^ m,…CAGaY:#N Wm}G^&@"$@" yCW=3ky~869st2gwN>{hP `䅹\|2k6W'{ }&m/a~~|yN&ڼI DCY fbx$YFGPqFKF 2SzqcPeKVf$@"$@"0$N7%_150$Lg^ Kpn!wXgwwY._\s{끎F`AFMM<ܮ}nGf>&=6}< LNb5I9eg4(-6پ;zLyi5#tMՇ>Xr y#HD HD#@j >SE==k=)\\ tz#@@k۝7r4\wMsqBsycvza>q8'> t'@/j3ihsm{2ȣ(Eq@1ȥTr:+e]2L+)Ńjh~ ~ɮa"$@"$p0}t%|aߗ^e>dR0}zff>wx<7:=>wX | ;ok#!D!>C: hbG"0baSo-`7n{!#L1 K:(1*qա ~h/<D HD H@>s1ACywW[t1Xf.Ҝq~~u*#D`׮֝Ғ_rycMdW#}sL7yc7<ta1;& OI@w`h"0:c_мg3MF@gD XrY%7E7JU|oN:y$@"$@" `/r}ngrb CzX-B%ۓ}4];%Z%4\<Λ?}7<4}WR\@UOu$[2cOs6r88fq,t ,,qL %v(5X\ g۶'~:DG"$@"$xX>c yewSME`Oϵ-*% >k~up!wxJ;oq獭[GyD1}gAX<>cjϣrAyND~8XS9za ŀ>8!OYi@f ZU,VYeu`I`CKV~?H9HD HD`}3ϓs랮ᕫ:$N\z>&>'<@e=}Iw^'_\u+d"0j9:Yqd5_koiY]2MfN,fm5Ӓ"h֪ >"D HD Ha s]x ]톖>wHga#z3ӹɵ#jhg(C3L"]lI@ qBc|5;C#o]ʳߪnҜ%@lc`;b' m;&o^q2 6>dIҌ,Ќ4lAӑ?^[{tuҧJڦew ]яj @`>PV;WXLUU DF>id攼:/}`[VsټϫI}VEWdJSπ]6Gf{[wپ7qU=~}6h=Hfݧ?$6LR5sb @vs ws%e96k ; H6xk>7yk$:9%o\Hr rkϔ!@iP@|_@b.{ѹ9}e%*zӘFKگ6.ه?" @sax/}-aomgrK86LԩBm{p寅ySc/ @`9\OHޘ81U[A/ &\~-RE+K}[,oه>dY @vsdϣ՝2c?ؾQFYJ(T@{ssK_Rד7ήN^A\IKʙup34J gBz}t\}8WMuR6VR?h+B2^<{M}gÃu'>"f}ly"Tc5y+]zҁa[n< @@}1r ﴵ*sņ xF~a<lɋ EpgSB}0xS=׬>97eFg$ogzr%e?뻐kva~^OW]n?ж7@ &\q}5շэoH۫΁U+9pA'~zR;}^YVj| m>o;$Pyv]}>Y&oxbQwD}#@O@f${-V~LͮHwzKv|Jo>'r@ "vܑ|t!/[XӇ zzY_Lpv>OWў:=g;ڬVUቖ<vg/ˇ8ѣյ#zkKިBA&pFA[Ot$m,'ͥl;m;' ܴ@>˽_tfr-<v(^W'`KRR{;>)KB'Oq3̡8kYHR6)zCFYY @v۽L}gD}~4(+ihvbiXѽ v&x&\->疼aBg,s,wS'<΃I}~፪v :x DƯ*ƀݒa@h6¿A}PM[-?@$&@IDATނ:J1>qKԍ{nQ @GgyL BCK}Q/]&Pzmϧ1OH ~zs.Pk0(7t<ޣm7s{y$'WvxXbk%zt%vz/ׂN ҠZaaI-j"*,zޟ|=;q(< @@ILވmg~􏖼~o1ҍA#q0>T<{]}^>-ښU9:跱j BAMB}Rưlx@zߣ>hu!0%? 1`%5~\q= L0!@>C}skeՕ0F$4Y%>OIa_0}*yK}2y#!m ܉1}oxxU:{e`^aU GSTX- Zߎ,'7t|pAZoЧ|; @` G~ժ?}0WJwP Dg3&K}zCMRW+~ĐރS35 >[?RC2NiN}s/n' !/n}Zw)}O? yz# @`jĬ>_>HsپV2tB*sf l$oegOX=*)VȶDЪPm6}֬3.߉~I)u꒠H韼w*w-3!w&e+a>4@ \,9F߾P|N곖|km|- @@qr#yCn{C}^rY@}vFM}/+GsK.qBdhy.z @p<B _;gQ+$Gۙ, @;H`칟dRKgyL ˤ{#J*+qMV>;Z>w^}a9ʼÆ8xI޸ֆHވ?zRޓJ]kkϮ>+:۔!$_Ho,hO4_W|3fY @v̋QPD o rC3M;]yysY<'9UTO?+߷ !0F@s'o~}Wvv:N;|S;PpY!gOK_#&d@ =D=kx;>`]}+"y"4U<?7 WA ϕLi:XyM%nn jq1"s٭vbgacVSKkڬ% lB @؞y5ϦXJl?FRa9!ű :>/}/+Yu0xX.s꿩rPRO :X*ŹC +J(ήE7\vgK,53  @ |,|TGZ+mUQ,Pw]W@ ϽZFgyC}l}\Qн#0zfg!sgy}^][;$K|7p]U@ @ yg03}loU oDiŒWY<X5N 7}u}V͔F!)WVk ύ^`3 {{գQ> 0['y#稢0#֭"&_@}zyN{Vy~zwuFuTLBX@ @`orupZ}vnzGy$I}6 yy\}*A/>7lyج}jOC>o.7_,JƩ(P=!䍧=yÅ՞!}^x+[ud=Wxh7>[|~Y'稠g/n0yj3  @@M}!?E簣etlr$y[iP @:O^ sY\J}VI:{I|iSY>Vu^I怖=O(5I7,S~lHޘu0Eg+FǶY?ɚ6t E@ @4 Gb x/C}&t`Ӟ },y1 )s$F gT拨[UsIY6!@ H*Tϗ}tp/}ji:2ϖ8\1R3:ޢ-z?Xlq\YysҬHި]@ t@J |$~e>>w]{F~BYά>r*2mpGtNrg>Yt}׆ @ZAuŒڿ.]5$o\#wjK_+ԸKJސs LF'I7[0y󬃛kJYlj@ t>?g >>G}R과 }VGْ7.>癢 P;ٽzsyЃ$o\۪>ȉt@ @`f Tg%oYoҟ~?n!Y~/x/·{ca|X>oםM}&y[*/uy _|Ív}F}^$<%oZ\?fu!@ .9k2'ss}I޲9>oM7͚Nސ|vun&k^ϙ)s:x:8Q@؄ @A@ O2uĚ}x܍N0r#y;1u*h,@>O{ӟYsHz=>sFJ6!@ 0-J8fBvU4 u T곎E}Rȕ][>#\+}^<9妖{!@q@ @p$Ƞ>gQIW\UVF\q>gC_E}6Ye ):"ʭ! f/̓<٣[nyh{ڶ@ &y_|Ҽ-,g:%hBU˪\|B1RfcsR#Bscm2y#~r=y#Mz@ @`,s4`GPCq>~Ϭ>z_FB}nr[(JsVy=,n߷~rLިzoUS>q@[ @8#E>$oX|Vv'@m<b*W}}6guНFڣR'w7 l3|R3Mb=yL=^lA @3I|r KJƚWnC}V1y&{ôdO|AǏgǑi3T,焃vp 鴳gWUM=yP}@E @ #PM#!A'xSFUר H?牊 9zq܅lץ>H곒777jxQ V8Nܼh{ r_j'1sE :oV֞R7*FB 8hݳDqVot`?bO;8p@_!0@ LWgg~grhx#zsc@{I>R}yr\nm[>oI:|a?\JVp@O( @g%os>k(;Pgۨ%oX䍯}ޢn{:&v5L}3V7VyǦE!vYt} @v@9`4u0%oH}hVDEK}v>;V `rmq36g^XZG}֑}~XU:pUY5u @@:Fz\Q7r+6 qMX:X|$oT(4I@g,[~UDWrþF ^|#?|ڼUs%:I9z]A @z1`6C}6YPB qLjzpp<V@:Q>kAc:;lHo$ gS yPg%o]רIw8YQp@7yi@ @` M#}1gV*Ѯ A3 n7qg#[U`}[a_s"Y,'WV,YIm+ٗ[n)Pgc=Ȼ @@ $ B}^bAKވ%F ZϨω70ߎeR]qZFM*ũB}f;:29ο,\٨?LzkK  @V Sh/>{XضVޛ_wY ( n7j&jA}ޚ {&Py84`lOqv(h>K}dÕ / PyJ@ @`/ ,[FLOCz}gUIr=Kޛ>e[嵶!"y#滜qayٓ74G RIMJ46-9N9ZY=YbTԓ}v]74{x5 @ 0"Efa0oZz}D9`b,yΈr6<]}xFmJB}nz{,!:r<5 @ @h7^>YuRϖQmb%Vyt-CG7ߢiGC}ޫ[uЪ %VnqnЃ4;Vu>Gֺ*(}8wYL @^ғŅ^3i%oT5Q tV>GFB67NՍ-y'oĬC轮A;TUy`奷' 9{鍸ߴ7:>?QDZAq[g7xV7Ƃ]@ LS_:[1}|G>TYQ7aG6gzu}ٴ2sChXIҪ\PKܶ[cr֛gA>⬊IZwagz!c7@ $pזQ٢}#qǼ|1Lܷw9۱,fbms>J%*UH~t`)] 7]MJ 痎KwV5yaϚGT@;Kv>Sow  @ 0% Wgqgjx+0IupJZx'Y>5תsM:slm2yF}D7)xxwX>sc\g%oN'8Cܑ=#@W((@ @&RMlPUo!XU2t}vݭ{DGh!yCٚkUHKkCcM}z m! 9Sr>K}a:XhÒnuٽ\oDpiP @J@|$\Ye>+; M}3jr`{Эڰ;u\ϵgyV?O}yѺmX3svl>;7L}.StʋJV_q,y"@ @@ H}~鈻&Mo->]- tñn{O?YBz|lTup"@Oa @h:hsaٷi/lj YC[rQ+D'\>i.~ҕgYk(@%o9iA'0A!0-7wve=M@ @Msz&-j(ƹ[@bW3P_Zj`~UFFy$a|6%/-q5)+R ~n! >tܤg?y=, ֕'߯WQRP*^Wg{=o  @ pN:+6Ke=l CUugy?CƌԾXhu5Wf27֯&|Nm\:_|CsW'Y:$Ӟ- C[n,*X @ 䍞'oر%3xEUpmy[ (PkӬ>W VI{n>2`Ŷ5R?Xs?QH}䕤VuF(@ @"P}ց?~d,yB}Nx'ٿC_(ylSb 1Bb2S:l|XZEϞaG%~Jyt6ϓWo:}f|]ܰ @ 5ٔU7.> pPіqdFp!r]}k{L\=~ɁϨux[A 7_;!ycEgZ3{F*Kw3:-yG+@nx}@ @Nݚupf$yΨVv->רPlsX κ7]95JZ7>Qnײ4ُ upu?]HW]yNf>'Dp7s @zsKި @}eF\0JghS>Qn /Q#Uw>ټϞrwHK~χZi @@;xF6ѐ|ƒ7_n>{_~~$.(y犱7NsRXZZ^+y&y"G->>NYO䍱*+縮Ի#}kDp` @h@-Y@.]R?|iNoφ{v9Wz ]_٘r}VSPorW7r1VT@ ϯX6,U>\> ϛ>kxV+ﳡdKիDy`X\X@չGssOaW_GwV%Or>oߒq@oφ{ @ ]% 67fa'_WsRCRƏZ3#a1("yC}֬}VH J3x%Yk^YzQ`s֟G][Ϩ7+p/ @ ;B}Fi'W4렏kO:UmkU\AaRl 5rFx>{.RmTm6R@ H}.^>Osl@us&ߏ|9P1 @>ۓJqlWy T>.>9XGE7=*p!Ysx7lUیYiQ' @ 2P W%^YyWI3U]R]ϻ0y+  briyœ7*Y$%Nfف}p@43WB}֫uuPf Q IvzuoHثZA!@ 0e*Gqx-y]\[e,C}Qh@$oH}6swY}:XzNp}w~uN'sb}RQ7nC}֋}x( @ pML}>bjQj1sLj[ %`fշż&o5yB>lkK͑'VeY[r#9yQ6KR @_, @ \%*y>.ΝѬ$9/tK#t>_ev@qgGsjR>gk-"ލ]*{=%n[E@sʛjPoa>6wL7e+g_@ @WDk}>wCr1ڒ Bʲܛ_w})BRF#oR;!󻏙Y4Muc9jYNEAg'oi2>z~$#yBs%2 @@=Y#]ϡ>1VЦ<'9똯Nr3\}>.VN>?YP|Lg:>篼gUP}nkӞXrU"@_4 @<x#}ޚW.š >K}\9g;}& ͬ m" 'oYJh ,9| -kǟB @!0}Vax#Y>\rDjO>`Pl@M}6uS9> J?iB} so<,M>VΣG!ma`uAV= @ 0I^>,}>?hf,4r:0D}vHE rG7`{>?qyt֮ oYQ.2Py}y@ @N^~Th4"eFSi m S}uH"0>w}} })|#UB^K}. 5[^v[RW~]}y'>i8Y-U drΐg @JR_x>l%Nƹ\6!n&\%o~Y%QYsڌ7sv {*>ѓ+vVzgyl @0S}l Fy[M8v(s}vbURMzD)~ sކ7N]-w\}> Kz䅠z4s5 @ aI}&Px;iZO>"V$ۙJe^؟%4n[EހMV/w<97u4z_3>Tz" @.J}vej,E68Hsw{M9sF|G>> qiо me>LXWWު<~JP~Viq.5c]B @3> yHY$~fL?iE}ՏWMw6لf-9TvmHFa.^_{ڬsotzA%ohAeEE7.Rsd ;' @@9'o|0zyx l&\HPvH϶mϾsL}kM0ozf%oĬ&CO(ֵoH;=X @@nO>ROٿ~᾽%\#W y>$e)5]:;pFb[ɩ}xF>{-{+ÝUnoK-q @b @ "yC0[XOP;J}6ﳻGu_%-|#ٟ#cx\CG%y=0q'2OP\C}~ϻ߂w1@ #P>`.G}aڮ>oG{O\ue).pt*D un=}RWi}uӹϕY5Btu24a=̋@ @`fw|&琞ˡB4,i/=h6,WKi[Ww>أ,*Tp+|u%vBb|ejէ{}4#ycwfzv=̋@ @`fH}~LI[X"k6u -+$mv 9*11Z!^`32yòbt/sxC?3윣>onLkC @3G@+>IQƈ֜g[U:VTSA}N+slS{pl^HsE/I@7r,*gW_hA:EK}fK|SA @` \'GdTk\+Vm'}uח;@cƼR[w=ycGЧ*fpMz7}n0]}\ϛ)goWYWU}MoN?fv9dY vpM]#)ϝu0ϒubpյ՗Ouj7c @s֗OY+skP>$m@R//S:xڽϪFJ7^` >֢٬]WG_^feEcړ]{ @@}]>ضoG\Z7HR}>ZEW̆{ɯ'?˫O\(OB:uZ}^yqqN,R=<ٔnzXJ @>ϵ:+g;9Ue#^S|݃@XdFϑ1gUNeS=U?WY[x9-by}guP@tFNe?Wyƴ6/@ "\/Ͽg>]ҮBPk(6L`L}VceMm&P>Pm ٫o(9듼!ټFCK҉9hIKC @PkSz/i:# }w+U`ŧ˯7%n$pٿ$::xay9gB:->~,/}1^_{++y8{Df=ePt7JF "@7 @@[ >jyr]wY+-QK6Oo-Y,?R5e=ڗ|xnrKܶ@: N>uϫ*Ozk#uJtVeyγoER,J}>c(2Z>B}VDٷ8@ V@}UOaz{}^ztDF f Sw雰j~4hzu%o٪iUsT5 gtݞuВ7 ԣC7K϶ܖ&l$m  @@}\:Ϻ2a/rb9y;>K}~U{L%=Nٖ˫oI@sgOjf|lr+zC`?,ɤg]xC}6ӞG@ F >ג7WY o5lSHX@>#:oفz͗$P>^gTFv)ιvlsӚu6+ @@+>תT$/Guz>UUi7j(6L`C}m96z;"E,gۣ> Kg5]yx?XjߑZY9`n0Վ(vܦx+!}%x, @f^y*F _Va8o*9MBrJ`@6B}$Mg^lw(r щ=9G}6*,#:h}χ(~&9]lyFH+W Sֵt@Dpf8.@  >qg'}v!iV=-u o&{7Mc}Y?R듒JU]?r]CLxb8}}8{.7NQ\tnmHވvӾ5 G@ =#y>r"Rb?͊Oߗ_wU/|g8-V]}6.4ۭ)HخAa9.v>+8kg l"cY\yy3 ދ<Ep @f痎'oADOg}v94ⵆ8 >ߏ<}cj\}c ރ M%:eAx s4Zi_le ~Rvsh&=B>96 @ >?ik];b̆S6 %sij@}Nj과ϙ>'aJ7:udף0fwߓ_/o!uP󰻳&Cǜ.'CgU>>n @R8$@ 2/@uyęKρ>IzesQ}_>R}/L~4gG*9՛JL*].F}QhY&ټV-=fymN9`$# @;J>과ϋ_Va15OJp#ks2X|^7jg@k>/t\}ftY:ש\ >tߘ7W_XG}^9rK9۟2Cpe>OQ{=EšB @ $s5%yIOpKUHW^Ӭ x"I}%R}F}ީVJ}S>Ϧ7ug/%kL8w1@ 8txdJU*#c]Y{Gx[҆;ePKސ&oH}~gTpuGmfAc:R3>ԫ$o~}qԙn$:Ƕ&"̔O:9 @oφ{ @ 0K9R[tr}Pc[Z{IިhPh@lqYϡ>'1ޥ(G5EVV36ty- \5Z>Xz@ɼϷ Fi:DpLG=q @&}~mzS_v:Z]iVe alE5:xg M1MBkv,_Zuvr&jPuD}.fvӳ q:zQԌ/X/ @tH7is:x~-ܑZGAU+~[}]}YQMyJޘrSתZշԩr m"PKm:ƽ;S+?>:kדl/)XD:6#ycjf'_ z'i\ @h>q)yg>>k,Uee[[sf $9*%o,t\}֬Ϫ "T'?'IDAT6ry- TFv\}VZyUs J?1-[TDj !@ pU6&]u=y:pƸ*U&hۛe:xU ?c곒74Ww;> UIcփOOFۛwGO3JƪwSsR @1W>;Vm# PO~Bs|,,Uڳ4sUuW7  @ v곎T uJ0+Dg+ K7?3Pj{y|~a@Ϯ>Sam`ls p9.htF- ZUMza7ӆHp@_< @$0>}>qƽϕD5QTҳs;s7} Ϛu]Kް9ꋉS \]{e[:8>k½.,٢dJ43 T"o @5sg YMipk*UYNcxk-bs*7|rge`ӤRW*Uue7kQ~jERܫ{Bnfv>׸M{_M{ r @T°W׆}F}Ph[-u1Kq1gD}N6IZax :T7NZ+{ }ڂΙ9g#B4гQ @ dsgT_ش6E}Y>}%ox\lRU 5-I\}ZpN{`/m|_}`1#% HE6 @N}<:ojU[kOh1\FaRghqgp:[?vzpxSv3s͗Dj}sfVJ&yÚ-8gJyC @$\H(Jvc+#>VHhdG#{~>u=6Дb8Ts ۶jx>>w:y#rh&Cvn,}hi6yGa̷.{GURN `ܺex덠>t"v ѶCwAQfzvw@ AWlWyYyӭl(Fۨʨ,}eF}myyc/ƬSMV }[lxﳣ`.R OfJJ]:G>)Q< @+>x(YIU.WiбgSe}FC{Xym$pYgJX ﳐpOƻ2۴(v7K Fueup"y:GvNx[uǫ*л' @nHnZYskT  9ysǽϖ곙!QѦ_y}.pcϨϧVV<?{/ILFi6 \z]A 6 ﳿ|t+y>뢚ǺsՕ6]^}K> 5ܸ.ܓK[>xw*#g>ެMi˼Ϩ3"2ٯc! @(N{#y,0*,IUՠi~;>C}:PcFev"wj7\HۏV}Vsv~MNI5j-@grg3LA}WUsHϩZ'v&"e8d ]4렼jn- `]ﳒ7 >;TWQ^]-Ȁ@%!@fX}f+B:z{ggr(_g,y곒7nQtZkIegѝ5 @` j _t<\?gjgӠևm]7ѣ>׫ӼϚuR]JHJUAutBv[l?7:}յoH^UѡU^^>q @k^  @WO ><:fHRsWQg7;J3%oLUCkK+'Ώr H}~Uu}A%of,\~e@܂!t^ @WFԿ>PN"}.,-U>,7$\;> s2I/>ױQnKxKMZkݞuPϦ2{[l>mMx/z/iZ @ruY$o<<Ҭf,\m*h.W]"\;>KJ:8!7uarӬmu ZEmw|hO5r${I߰%m^  @WH7A9pv~=g >Mݣ٧w] \:>>ȶ4h/QF=g_ʎR>Q,sTPǞ~l[R?}[{#c88/@ &Qrb$Z•aVFQ/]$PcYQ_/ v%[[џu!V|-NZsW =>+yóYmBׂrp\=ֿw|_Y KdZ Ӝ}\Vf&-QPuGު2tqv- >j7}NgQ,oc_+ۦmeo{p{ @8ޫGrBRG%*!Y3@/i7Y1|or7C9E/VWoUdב5*6E ~C>~fH)F4m @m#`SnQ]Dg1+O>5wxɟ=Z>/lsN$]8݅^m?Q,wO(yctgcbY+/o{51Uόz @u_M}.c-,_~R}Y- i˽υϨAu,rS=lQR>Or kEf q>^\VkG~;sI 4 @!`kGbঃ->K}#I5h+#C}Nli%o$__6(焇 ,(A @>K|}V$I45OgFZ,/y>.]Kyu3=@l R}Sϝu07دL.}IV3mi:vG@ 5!S}S2tm%oܛtǴJ}~hVJ<*s+*u9N;6`+<^us}]c(,(m"׵MH@ "P%oH]uBPA^/fy)s }}X%:QϗhXS/n:g%o-sRt2I~T[sa5譹 @M>[Fq>Uaۯ翰r"7Js'6M{] %f?0;o9yәy>]+`Ued~sӷQ$I"lC @`/Uuuulƫ1΅٣7\/W>͵H^ Lzg%oTЦs@ˋ. skl{sT2o @mNx{E%!n*\}F>1wxL}>F s]Wax_JS>+>{KC7< ]`n!@ 0N@G,uÕŅ/|7 ZHڐ}:8ޘj3?KHsϫg]X|1:̬ٗ}t"%oD搒7PkSʽ);^ @SMԯoBgWL{OkuU3Vf%o>\mGMPO'wܪn#MH >g5ڮ9yVφáĹD*J$oNA@!@'o$dV}vSR}k+7Z;}@xٳ>[3?^Ǐud]>Oa\}Uy,R`TZk 4MF[; @ 2 z:(\RCn0}Au$#Pɦ?7 WM4DՃ {@Tsgrv~uTy$oO1 @OW}q @IT+%oeRF6e\-g7_4dM,Uws gk]WGgBkzr.ϷE5.ϊGB @e\o?,(>_@} >JzU?g%oXU-;[Pp}{ Ĭլ9mFFv{ϭiu U_- @]}?0Ug*j2!镃؝1Y>*y#Y}|UIqqmRz6Vf'P/eǥ>H(O~vFsf Dp\4 @G/ןڌ:H vV#J 'oX#E}U뭑lƺ.-#K_1Ƚ$oXF,UA;9s"URU @ pq>K}I4\7oXܻ 5\gSdѥ>a奮/g%o,~<`řyW>_Q3[@ފ @ pJ9Fq=f'oTlctkx5x_^z4E jыQO0"da|V絜!xj%$9uhJ6gPn?ykmE\ 諡@ @bN_&o$w$LVbRJ}PK 6HRu pҠCj/,\‘T%4,H V/SwX5k$oc]f3Y9f!O@ :uЇo>#yüRm*0W _ޔ(7F_g^l 7ƎvKِDGG6z/B`,yCkKkT=y#SWw>p;${ @arϘU n[ PŰjygjLP|v㺑Ցg@rOtQ(ys /,!g%o X'_3s)Zz- @6Ĭ[^)y#Uc[|Ѩ׋焄 8JY֮!E2?OF# P!ac< @>^U>\KzsVB}&yBi}^c鑼Q:Q5̗h}>ARkm}8V @,ڋ,,;MN @G #վ/e@H;rL>z87y(}%uX6שUV}nf>g >u$[>ʝς+w+O @ U޾/Ugy+*0`f Y%V>]!^re$omHHG$yhss#vCP|lWsmqs9Y"@,& @` X/,3'o$ϱ]H>GaR#9hl,$yǻXgD}nC  rӒw\}ri9)pp@4Q @3~.ƒ7:}^?Wm2&c}!0:>/}Pz :dh .>7ty- V>;'x]kO?[3ly&"C y@ }v YBwU/V<(4M@s1X>yJZwޝ(7O q5IN'oYfv- {P%@!@f#iT'$69>חЪ' &yrlg$oV}6B^Yb8>7vyϾC:hG9Rr>oՠطb@y:@ '/O!(~7bܖv+k QM}}Y?-wzۖ!]5-EN;x#s[wL?eYYy<;*}Y?'7ty}bi=#@7Aׄ @ZIS0qZFiʭ4(mv>>j/,_Y 3~\gy W%:_;J2tC>yK[.˳C Ϟkﳩϑ1fV]W@}^0Eg}֏"}܀Yf\ޝJ}t,OSMk͢".iq6m[r {@ =K@ S_?ӰMJ䍘uPY(7ƽ^,YyH޸ Pt{I},Drg;/;8='tg3Z!@'gu F}9Q;!ꅭ4i-R}:'`g>b|ه{ŚkUr/·{"}@}r,ljqupCn\v @k^  @`Z E :hM;oX5^F좌]7!y+.˳}nG(l֟|nn؃:~jEsxHjy#E:>wU"@F8@ vzQS_J iLw%\,y㨩T?Zi؂#kl/G}\}&:%/Nx_Ǩ_w^}^Ytrtg~…{wл' @r/l+94 FŐ)o3t>??+:>|v5]@ھ r= Sy#g r:Kiy/0V_n&yvK〦 @ @`k>oI!=d=_8g}[Ϧ6KRb}Y_-#C|J97J9~߉y;ykg+B LPu:sҝNy wg1)\ u06-y0nJ$o$YN]NAJ6PnM; @$*Yw<>˄ y5>gHZ*{udh+/{ c3guвtΡ<'nKan}Kn>лϘW @*>G޾7rU[źT$oLUCլ#t>Us7}c7ơssY=k I>{-h@@ @`'o<ߒ}\oa*DgdU >0獆DAJȟ;YڧooXv-Ȯn!r84˟W @hZFqJIsL۳mS/3`fyS0-9r*eXsJ>|:hW-x64=h'oR[hf @m!P>A͹u<ͦ H}=u(Ϟ&Qj]ѨM\^ku.lrNb Zov ֨upAt;ꁣ @h;oǟC(N$o\,R$В7>7xys]}.%J?cfpvb2Uig'ªuPUZ9 mg{fZP+ZCX;ݚ@ @"[OAP|gaB}n[ eL}>+yKFiVonrjSks%o_3Dp.8@ '꽙:R>7fyIg }|aœ7V;}_sUdkby>:|nnAS>ޣu(,, eb sZƔY?~X>~GIENDB`faraday-2.10.0/docs/_media/repo-card.png000066400000000000000000013150021464273144400177440ustar00rootroot00000000000000PNG  IHDR  1gAMA a@IDATxۗ$Wy'읙sW 1x16 l$1k =7j!ml'2g##밳 3#ٙQ7]%  @ @ @ @ҽw~f~Jn\gN|\\{WÏR2u~tzsL!yG @ @ @ @@F/֡9մ('"7 v_߲"0>) @ @ @ @ pd'Q/%WrO 'mF} @ @ @ @J m#>v/8ö1lXGد $ xgg#@ @ @ @X W.Fr/F-zx cC'U@άE @ @ @ .7*tM_z߽q;F@g~l6dž@῞ < @ @ @ @Th?O?Wk#g}o=ҥFy]_T uVk!҇$@ @ @ @ pX}7z3R6=7"aBy1W3%O}iv4>s῏-D/9W*FFP?_!s @ @ @ @Y`[/῿ho9K)fRyꂀ>4A+} @ @ @ @"JΥ._Qa_o[ |<xʚ, @ @ @ @z !JEߨ'W-X_c_ಈ} @ @ @ @Q]& Fu JuYYts*UÜ@-OH @ @ @ @{Q]&s/r%7ʘMſ\ vݓ%k +' @ @ @ @N@m}?Ῠ'Ws·΅|Rky~TS" 8N @ @ @ p2r^=Y}j5/ݥ!_W/?~c)}Siϴ= ;֮4 @ @ @ @8q%῏]yEdk?Mi"__i0$ @ @ @ @9j6wrEmm_I3U{z;Ö_~62%z&xz8J6# @ @ @ @8aM/Mf7* ՛?E/<)-ㄼ?%S  @ @ @ @=Ǎ>&WK_F-E+}?jol3c3}O_f} O0 @ @ @ @o_T_=kJ/b Plo]T\י  @ @ @ @'P嶿M-?l\=ջc;€RH`DC @ @ @ @<|>mmU?/ ~.9a\  @ @ @ @'B\>+i|C/T,\oOS* V4  @ @ @ @?OboxPoxc &PO@ @ @ @ @Xf^܄T=jl5XGk @ @ @ @H?ٰ\֜*՜cY`aG  @ @ @ @_Vw!m#w};kWS~|[y@ AXC @ @ @ @G&T{m9m+maӹO"@`,}ܷ @ @ @ @<4Ŷ]O1E-a:B߃Aѿn%-he @ @ @ @G+І~+].WF$W\ H [+ů/h; űqci}&J͉ M߂aM`M_wo>m8԰M @ @ @ p496}m[.FB/gbiVaP~|,7;9ohYP [km忯})M< I @ @ @ @tPOj@}/uKզ31w+_"~Q+)X$  @ @ @ @ ,ߛrB)BB`u^Y"aM @ @ @ PW Wfguc6Ε+&QoP6 v1`2 @ @ @ @@V_,9l&R|U+οߧDow78 7~.mm=z= @ @ @ @.J/?9t1]J=p )×yTˇN}*+ ߨA?E|.C&(8@ YV+vlX @ @ @ @ؗ@iJrYNFirb|4>{z_C9ywM[vG(h[Q(9T9"@ @ @ @@M,wsYr߆+p^/!W)80WF8_\S"oM @ @ @ '4Mߎ_n,9E= roF9l=g98z`%@´;AC/޻Ag @ @ @ @k(0olj["7n5CCOǟG@'p\v}-  @ @ @ @$0}{IQWsi7ۻ3 D ῤ{j_s<>cP^L @ @ @ 嶿k_,QrHǶ_ږQ/p8vZvRq@=m< '7F"@ @ @ @H6ikgMjOv7m"c 5l/Їu%N]|x'HX @ @ @ @lZDК۬s`jjyvGXuO]z*֜ic @ @ @ @N@ rXEm+_E快)MKok+FT+6 (Wy2 G`I sJT+oS"aM @ @ @ ,QoSިFS#׶- yKM# ( ՘c]l~49/zY7*7/əsD#xD.C @ @ @xG߇9W*~e߭'X.?{CB @ @ @8G3 Ὸ估_bYTk<X@{C k @ @ @ @ ;Iߍ7b_ u9VB:טy *j\6  @ @ @ @N4ͮ4k76޼.4>{?fp߬ba+A|^  Np/W14 @ @ @ @ To%7+ſϵ  _io  @ @ @ @I@HRoS+;)ruX_L %  @ @ @ @' w$so^Mi7P*G2I.k \߯ON @ @ @4#M%׿4`w4k?(rZW @ @ @ P"OSzft31(ῶ_ǒk䇅V]@{5 Y/=uPpfg$@ @ @ @N@_fyfI.Jį_Jowχ ,tΏnl-+5 @ @ @ @8 l _9yR[5Wƿm6Wp~޿F9qS:V+0* k @ @ @ @q[?M;Ta#^"J0o.퍵mQ<Xo\b.[_8  @ @ @ @qh*$nw֚SdΎ)M_,%7\p9+yV P*`Te+e"aM @ @ @8n ῶ_I^o+K6|TG?sbD@OM.6Ty{  @ @ @ @c$Їn(7%mῸV vk@BB`'k/ə+3y) @ @ @ @`MOQmny>]~+i|̚ cn5Kb߆e!:OpV[0Wp @ @ @ @! r i[NvtH0`lJ;A9Fl:M/mpcBz/,b @ @ @ f[[iVTٽh_9l9-]bK'C .0˿ 5ƥsH 0 @ @ @ @([MW8}/W97׆J _0%&w_w1] -l @ @ @ @@Y_omf5'=U#*-'PQ`{?m;I!@ @ @ @X@7j[tͷ(W Z>Xg]L1w鼶{`VpHN!@ @ @ @B }')+EXƛ׿oQ [),r}]} ړ= "m#U @ @ @ @uJ4x_]T٠_ۖl]9ٴ<%# ߽n6zlE9 @ @ @ @}忦o;p{U忊w~u-|#Yu vKIvq@*I :F!@ @ @ @Ifi+mj'nVQ,kƺوSߓێ;@@:1`=K# @ @ @ @+ki˶'K4Aro]?J( G=&G( @ @ @ @#P뷛JtQn|b|+vM7嶿_iX n(S aml\:49sz%<  @ @ @ @.ЄiJot%* KYWE1qϨ+q/;- @ @ @ pMﭟjt_]6+ׅb/fc^I uDŽ΅, /Te  A @ @ @((J WU+H9ZJ[؍ @l7ϤsO6x @@\f~/Wq E @ @ @XkxSbj}+uHoN_ob _\" Ŏ_?H*u5 @ @ @ öQj.*JaK2%5(WWx Tn籛m^Rv m}xG @ @ @ @5j2/"Q/~%fg#8ʕ5m+ յ.iŢp]_ @ @ @ @k&PuE޺ }'iTh %W.7U#k* l*pwr_嶿Q^!  @ @ @ @5J$R@;|!m^7`0Kf$5Xf9?xUoNT߽i[wX  @ @ @ @ D6|{u ;5"lʑ@XgA`My6+W_Tm-/˝O  @ @ @ @.*z+Jex_Ѳ& 6"HcmFu?#@ @ @ @N@mEs6/˯k[sߛI)׻K_7}"}j;V!X#roQQ5曝Pl< @ @ @ @,ЅFo_🶿}o+[ `p?R 'wH^W_<ws @ @ @ M s/MJḁT^;g ՝ XUƥP_d蒶n |+/< @ @ @ @'Mk;m#t?ɥo|pYJ/q?K PIo>l_Wq3LuKPtُ al @ @ @ @k.Ӯ_,bkj>_-A.)~ln&/}V YX@{qQ6J +ˬ @ @ @ @'^`_Tmvn[ї`{bM@eʠ 7 m@;_Ya9i6K{W.+X$  @ @ @ @-Po53gK+3'ojWqSOo.e@]Ync^xk/1߯.vYC>سo;|wZ:y=@IDAT5l @ @ @ @'R 魟tv|q ՜oT+ٖ@lǿn)%542m/v@{=Yqtxl>#c   @ @ @ @*T%rNx"~j++So7' V`_OQmrژ߬o˝/.[ʕ_yZ k @ @ @ @ "|_iދ92̷bW\SbD6O0wN߁Qaox+rl~rmT"@ @ @ @N0Wb*՟6픦KXʺk6 @`^OCqcm4(Upa @ @ @8KKmU? YKl2 )y 2yVFܸ_m_㚳nDoێ> 5l @ @ @ @_|cD믦3;.o6KkVvICG_Fiir.v.qݭ{rO: vV @ @ @ @/0 _ymo~'\ [_,V>tˡjkj"@ @ @ @Z 魟_~ iʫi|Q{lNsD[uۥ `.K 8+V"P*rE8w+=_U aLN_|qOi0 @ @ @ @ Dot'iFX_kQ뱄F度.5rإ/`_90J?Yۍ߇Koi ƿxVS\R"aM @ @ @<2sūɕn C^"7.s;%u^XX@{F_yir*.c6῿~(a0^Mg^Nm @ @ @ @ _[/bm˯k[s_f_@K_S۪ŕ۹_͙0_bnTȎ|.].t!W[u/.-8L @ @ @?&7h[*i[w߭K9KsiZ`>^J_Cm/~~{省h{sb7E/.)[ @ @ @ @[g'uT"RFfQَ8o0E~6ϧg]:^~n;RsenʳGU\olX @ @ @ @4ʕCgSbRتͷֿ_J8_L=d7d4z_ 埣=Oc6Aݥ򱣬W>`&@ @ @ @@qݸ Z^6/ U&W%Hq)ῗ8}9_~3*U.mMK2&F/p(X @ @ @ @)ЅRE/K*՞%2̻῜ir1QT=#0F[6. Z|/M?s+p~|aM8 [ @ @ @ @qw~"K91>C;"}]q4E8&1㗅B`Ui1MK|&/ӫڍX}kӀ<_dzb @ @ @ G<A hv _3H,ݺ }V#4w~ц q)W݇_w+6 ]x `&@ @ @ @@T{Git#^7/W^Mg{<b_|o^b;B1Qo'+#cm^76=em綿wN{/p+7#X$  @ @ @ @/0hѿQ.<3 /Շa2Xi_L=4T˿kVdNm{i E{˼Xy =䶿}Zpa @ @ @xx\Y_U5K˜Q'+C 0߇ö&ۋῸ{\3j~lozͱfMT+Eš @ @ @xx97mӍM"BKQO'-cSO|P`[C:}/_ Gi(fyuU˸]y$@ @ @ @<$_AiqW7Wda 5!gsi=Ǻi<{CB @ @ @<7cTZl^L: Eqn;|P`kh_2z{_S/)hC ǬCpa @ @ @8:ArѨy4>{>AzH3v߇E^ Єv:3;blEo ,q/>F#WMTEw G_ӂ>#9x J=syxVM7D @ @ @N_ \՟ÄT?F$0+"7b bNs"؇Iַ8 @ @ @ @RTZ\u߾LHJokp-VkLߥ /|*zxW+bZ k @ @ @ @`9QJ]+p ըj~ЅSϟƗ0Fk/_斿7wYT, @ @ @ @ߏ4W_,*ojD?h;j OkUQ Ż&ϊ @ @ @X@wzVS*"Wz˕䶗?F=W9}˿m>t~1V^xҩgC-  @ @ @ @Rv3nTvW^Mg^k4|,:߳O Lz$@ @ @ @* ߬ wW*Z/k"Wq. E`Y`Xurh+lu~xg_DG9Vp_Sd @ @ @ @`/{Q9m5"ʲAoTWk+ƯS2rnk{F{O=mP ࡆm @ @ @ @4cEbҴUиJew=xQ[G`_{klr=K%u{y7G~ } @ @ @ p|ῶUF'h #|=Eo.lr_ea/x% y'%UA3y @ @ @ @`O嶿oLjo'=4ERCR`vo+}/ư_9hz'M?۶/\褅=M @ @ @x@r/Q;;ao_T~QH`;J_Z_)\$;IG, @ @ @ @J ߁(y/*t{^3|?Ig$@;綿/Yῃ.~QD7gm{'5Tpt;@ @ @ @UoMJ_NiT }ia@/ U-C Ѩ7f _9{Nb 5 @ @ @ /a¨ͯ_!9zK c{y f6wh}}j=[,s~Ig7s @ @ @ @,W+XBQm=o1YWj[{0LO6"]@o*4o"7Rk\$W+]HX @ @ @ @{(h[{I_ڐ_Rf`݆D@`5q]}t7sh!p)w8^TzLJm9> @ @ @X@ _,&VǞ_,%2߭i㗅BB`U}%o7&gϬk7n˕K7@`~v'0 yV @ @ @ @ D/]q%;Г_Qn_.*V+.V#Є4繱)W[ .7l/w`\8WwiCB @ @ @W 4/فחHK U.P`0?oj9w 域U+~!j_/? >6`&@ @ @ @v(J/;R<׶ڭel2_׊x$J}N]Wo}TE/Fr'ίa/XCB @ @ @(P)W%bK74<^`T Ўxp*|Fh&R-އ>. U_8Z_h  @ @ @ @@ 5rcshKHv#c%D/Ǘ4X{G n-@ЄirVx[WFu75Wt5 @ @ @ 4ῷ_W4zj_TeUkCXu 5VKq7.G>W* .cpx"8&@ @ @ @R{/9wvxտm)mMso^l7mH T-MmkCPi<q8m[Qpa @ @ @oPDb$W[фvm5cwuv &28  U 44mTţz_ >6ƒt5\/O @ @ @@ E忨xt_Msg-o %Vj}NpX@i;R|nrQ oqf"Qwq6Ƌ @ @ @ @uho8n䶿9mcQIZh[ va|F|,N /<״Kjr;;ۦ8B @ @ @K8+yh_ݯA 6В5b=6D7d4z!_ 'ΧjlD߿N0qq:'J P"@ @ @ @"0l&y!mOmk~J/mmzic0_|X^F/Ws.E`Y #.K/E/YJ/z;ꎖ_S 0F/#0+Pӛun\:KῚچm[r?u;4lz @ @ @ @N`vnJWT7 iS\5῿vJ6 F_CyR<N8cTIpwkEo,xv&7:Ė! @ @ @Gͺ_ ]D?ῺW6ҍt2ݱ8^F@/=zzmFWnvq~yl6Όa+ @ @ @ @ ~T+ы_7ҽ\/[u))|N>+^ UX[Xμߝ|a _ J~?dJ @ @ @]/ݣDi$YZ'@!!$LBbXlwC.k=Bb,L?wꙑ4\>娫zWgOo{-}8V->U>WD0"wUQ穯Ymr/% Sbr@0^E*50{+2m}z]ߞb{FzЅb-b\JB~OoϦw @ @ @ @E9*- ?;}/*,r.`\T.H`@)f}}/uWr6 :e0MH @ @ @T_[?-7T2~% ˝ y?/7|P@忡߽-tb+K G4  @ @ @x_\̴}*Z/_sn7)/]0$^YX_6.^4p~KљS֍N[o[_8~\; @ @ @ @QZ/_[L8߭7Mö-lmc&9|md@@7٩zփ˷h\k]PVDp'@ @ @ @ _T-3mŘ|s-ۉ>3Έ_c'0@ m涿=,}/WwFL[ھ0I\g >+ @ @ @ @X _TULP EaֵZ4둅Rn+i1&"P~XOo5OnyT n׼o:Qⷿs`F! @ @ @ @(5oBgmJ?v~a/~ȼ[ϕ|#o'0@uS忱m[7f[E0~* IaZ\; @ @ @ @C Do.3mE#wwST\y-UkNV!ЇqSVײ~-/텲Oj?'dj$ @ @ @ @g%P_T]7tmῖsi7`l|Tm'# _b*(F\-0V)7Tk b @ @ @ ptߝr5w-[忖qK t8.mV0#$+嶿mkymn~˩AIZƛ}ɼ @ @ @^ >|1]y4]?pF_#hx0QO&dO`5}wy|[ou.־N_w/'t{ne= g* @ @ @ @VM'i_ KlsC>$]en2 f e]u8ylE t(׃=; @ @ @ @ȽD_v@Dnnjm[QÀZTh;drL`t6&1~_ċO.W3TO@ @ @ @_w_a6lXG%a֥i4 N}m2{_ܥ݂kb9P|V:2T<7 @ @ @ @qZ/ݼC5&7q=W.|r# w0%y5}!g0K3]g:.*9 @ @ @ @ 6&1޾&ep8%H LvG_م+YiXbk_KCs; f*| @ @ @8_7ȿ -r/.-imsῊ 7Yw]o,>UޱLEwRG8+> @ @ @ M9Isbߤh_ -8oɗ Y`7Y^_PoT齄7u0OEJ9]v/Tc-ی< @ @ @ p&j4lΎ*7o@ E#W.ݽk_/tT+"'=r/VayDwMݑYD @ @ @ pvJ>I;_ѧ/嶿k[oZھ`>G忩߈3a(;;{f9#Zx1W{qxU8̂@ @ @ @gFUK]yM/otm/Uo!$W}J HX Eټ._L/4p"_oH[?ڊVÝK9mw3ksX @ @ @ @T [9QC*?_b.K;7|]ˆ ,V/۽|QA7p|[WoI)zbF\"ڹ"_@`e{xWM{R/FծŞV[up;_wYD<<C @ @ @ @IhIn[BhtI ':vU?Z[ .( LUE_[?l[ w~uBT{✣# xb%@ @ @ @&Ї>F"7d>_o&_nQou>sezik#~C 0Vk߿􂶿CC?[7VWW.tυȉ ة  @ @ @ @8 D/嶿9sIT{M1TwJ߈DL]w}{Ὴ ZUG?߼䵮jW[o'hv @ @ @Kɭ]m+EO1',|7_ b/q4* Ym[m%Fnq&; -N '|}| @ @ @8^ߝR.*MK?1ga#mG/8$7drL`tVomMcm7sbk^X^(W߂x &я@ @ @ @C W*.MrߍKcuƻ)mmak꯶K2N秃K9 "@ Ezd+.ct]cED> i텫3c6!> @ @ @LK.7*_vo DԥO_T`㓷U@-kp˯ŪQp 7-O @ @ @ @hΏzZfuax˾lǥH/_eVOe>+~r#mumcvOg `^(߷a'_ND @ @ @'G VfW6y KMiQo5%Z/c]8^&{ṸF "L7'*i;.v_^ȱ/փE/.V־o9]k>4 @ @ @ p$-gQk[;)muJe2Ks )mN/ 4?-%"׶wNŮ,D$0?!vmF< @ @ @ p$-7h;> Uٖa{ aALBF`e_$Bhso _Od_/.s?gv|>OB @ @ @N@kZ FwwSzm_WB.\]/i;B`{/^[uԷ}+eoܤ[ ΰPN~2h A|yq8ZyhĒA @ @ @Z>$sl9mQ+ 9q涿eO[J0w7K bs忔+ 9", 챪g}{]忲滵ů8?k`}i2\vX;? @ @ @J}&E[oQ)gy_/?'"&a#B~[Wo5lۂeQ>XQNG63W M @ @ @/yῖPoO{Gi+7#7ɡ+9bO]p8""EU@]lz opARclY  @ @ @ @`_$bJKbԇ{'M6J2KTG%O}{-i:KmG .wI+Ῠ WkϜr?0 @ @ @E_l+>_*Ῠ+v_iB]Z0(7<n_TUpnPT'À }ۆ4b~5XqKJ@Zs) @ @ @ @Y+4Z/*W{vr>& Wku$ȞJrԨSG*mkӾ0w'3* @ @ @ @3-aߙ-bVUΖJGTð#E}%Nk6/@VUKwk-x S8 @ @ @ @&P*}ӥDo_a]-W+gsÀ}h3h^^^-UuZU}[7y  ]s @ @ @8-7u'W_[J_8GC_:^~óVĶ]^fJ_ZZyEῑkieaد T ਗ਼N?  @ @ @E͕ 7 ݾ߭7I7.U _ , GV%W4Wb#߃)sЬD_f4~9#~55Z C@}` @ @ @N@ ͻ7|.ѿKD^ZF^j40&C"ῇ97uToE;qVo9+b[ьaO @ @ @ @ _Tk hִZV;0`r?˕Ɵ#%A YjUwd_!ֻo6x27@l77 @ @ @ @I7>`kῈ|Qlb/iկg_M?)F$ >͕mz9kk/ֿE .w^.'g=S @ @ @N@7F(MoY,7I[HmwULFeO`%˗2ῶ&>ZVƞ34Y @ @ @ pZ/*mrR+i~?@{Y"--㶯|7U;x@_f毡O;kOŘ-WW̏{KWvc" @ @ @ @?<?FB9r忔o5їz\*N,vymG<=7]g! h|@8o#@ @ @ @)yO3Ɵwaȯ-j]4`ro ,#~##k+a‹Sr>LN @ @ @SUlk{UQ'|7^D[mxKtV* u(vV #1Pol{FzRлިyLɃ T @ @ @ @X _Z/K_"*?F$05w%^~^}ZzǸ텼2N&;|8~ @ @ @x}YJtEQ禅&9"-qݎk^Q`v5wYoWCO+V\.طɼ @ @ @@~JYmV[/*~];@`*m,i;LNi~Y^Wo,Z-|OT{. xp;$@ @ @ @g,P*$MoƘ7_yi7mx5&m=OV#\G߯ߺÅoxMŹG4 @ @ @@kWɳ7D֛f uȼ ~qӗUk.V! ՝covn ,W w-/tEvqn<2 @ @ @89_QhSFoy |6Kw1 bG-7 c.q-i+y8 A @ @ @ @_ma\!c N-WvE[ ۾]Ӈ3V&h L @ @ @c ߍOR}TЅ)$*uծ"Z8m7=/RE<_`_wg/_~98@~֍bkZr-m' <:kw"@ @ @ @CΊw!@7umK%_[-!K4/V`;޼6_i5/oxCv R@(݋ @ @ @$P4;U:]J_8И޴Suyű;1!0@}6xʕbܱ\[;jQ @ @ @ @~"7+!>So?{vLKT*bϻax 5X@kՅ8_ u0vvNwf_|)1TK @ @ @ @;cFnNln֡#]ԅ[J%sAW<XčEῑkôCep50߳Wo0~+z @ @ @8kw@Fh;.0*]_.K%۹vw= H[7kyN7wy&y,bm-Qbx|VJ}  @ @ @ @_s7"2ZMrha }/s2(P~4&;q1]{i~~i}.W b%J9h~D# @ @ @ @= Do)E&mDZoQ/-m_-yrͅ*G+~k.V%0 @*+_I>鼕:Xzx<*߹ @ @ @ pZo~NJv{5Mm#wwRZܥw.eG(bTSo|1~,xu `vm1 x|'#@ @ @ @ht%ῑg_GJ;~["_6ӵ/̈́G[o8_4ҕ8i#pl` @ @ @8ߝwWTq[ߔu\m}5mUq" E`>i򖿈(бmEe> @ @ @ @4 ,wtc#Ws[/V*A[Z0q{t]ߠX@m>._̕4|oDD":翫ߘsa Z_ @ @ @ @@'m%imKot >! oϩ7WNrKI9|d @ @ @8K%.#h1[Fɠ_MyՅ"ضEߙ_#'_-7-& VŲ2֫J?ǒy )  @ @ @ p2Z/nyl\JW^{%M/~a/"--uq1PT h[j[)|Ѿ]n1|5Ӥ.JN,5_>- @ @ @N"7l!7쵶`׺ <#S`ot3͛'VޥC'R * @ @ @ @x_T.FjyuqbWž+o嶿Sm=,;O9pN'\rT<# @ @ @ @,Q1sWq[U[p_?mF`ui~ko5?ʹ? ~u1x[˚ݦSmwsq ة  @ @ @ pJtE6. 3s @ @ @ @ ,OU#gOP EEo>-w3(Vc[_yۏˋÇ;CǧC@1~  @ @ @<3EoXo#W{Eg%7|'_*UZūM;};V*P*4ǘF7Ѕ_O9 pZOL9 @ @ @ jo`cNG &[; mDJK3'00cGM῱Sj῭\{5qG `FcJ>"@ @ @ @t'mWom#7/Ѣ*cviG &Զ6h῔+=B107o ^/6%ONW? @ @ @V*mo#ʷ|Q LJ(BFy me M]$mSmha/_ ḿ @ @ @N`ߥt5mǜ7mna[e)_Z;?m/3 6V"0 S)zv> rS>~< @ @ @)};?zjmckZzkΈ_H`EG,E>[SotE-土6?.h @ @ @ @p_IS7嶿E/-OJܥDG(ZE~4[۞q߽\.5$JyrY}񥯥WڕNک  @ @ @ ph_T;4`_M,K_j$7pL`%-W+臨Shex?Vo;gD@32~L @ @ @T@r{_ R/B-_r/uAjK/!Nu18)ta  @ @ @ ?_Po{:7|;M6JU-#W#mcvkkirս5@`Q]῿{K }]K⹚w嵲9m<G$@ @ @ @AJßtn}{N\D-*E௅J०a9Iɸ^%pHEU$C_7~q}]KTk/uWv)gC@l̳ @ @ @+"ŭ$dK ž~J+ E o5q6|1=49O+aAZ.0~1W{WΆl~J @ @ @ث@]Coz{曏!xe阯r?´KZo~+mvy]a+ݻ֕_tqAQͦ#́aN ' @ @ @MoҥtWth9=կӭ7NishUZx!s`X@ "_I4fuvW-;i_xUm& tT<3 @ @ @ @`$>ws/#)7N7W+ᖈժqi}+&R`QNMֶca#׭ `s;O @ @ @ @ *ik+Wy+-/_k;qH`|E/6ɕ.j;2u+mj|YQ%FÝ-O$ @ @ @ p>m#lh9#m+\oUts ,";wt唖mſx>Bq*f3mG;TA @ @ @Ύ@7Ei+W=FzlIZnx-B*4!_\ῨR~i+*UkAHG0*}WFfO` E<'@ @ @ @^So_wF%r.e_\_<[ 0`&׿&׮ < 0_Λ *_[sB޻t? 2~ @ @ @C.o1w{|'KL݅J/\b_k$'^8ߡaj :U/v%]ߞ]x>ÓG'@ @ @ @l , g/]hmӣGK0Ǔ< ]ߵKb_`a|i~o-MK`4`T{Q忞'>K @ @ @8mS]mzY忱yw3gYr弫׷̓Pkv7{BG` PLo`RkbϭiW]Ԕ۟񥯧b^y>}s'"@ @ @ @%irzYwWÜm߮mqb`D]JpB/_y=Wڕxj#@`{޿t+P[oރ2x[b5j֛q~_;Զ״=,  @ @ @ pfkRT#G0^/A@mfL \|4 7/0o \Z0_z>/t G@ h @ @ @'H@h&+7x;MjrTٖx#Mk{[iܕB __ROo߆ῲ;oc/涿·Ζٚo?- @ @ @gD@h&U_D]&.r؂Zyb{G3MrFZߔF,~k/=7[K,݋|Tr9&p -M @ @ @85QӍKʏ^M 9hpQ!şV n>T+,@UmMcnῺ# =':(7qL*;  @ @ @ pMfu Ra,'j௝̭# wsFMR04w7- C- ^cm,=<#@ @ @ @XƟka4;F5^OaDC>ϙḃDžh8ϣ_ 6ch  @ @ @.Π_|9K*ʹ?7iw%'%\O/h*E?OkosG @`7YE~#g/նv{s+JuO0*]z^>AKFPp4J @ @ @ @`}ݾlm .[DqKü\Hy E忼-*🶿{mk'&* =KPp|S# @ @ @ @`t{t?1\nw'70ע.mўs& Do?I7'7z EߨV= ῿4j܃K"WK*Bi @ @ @NV(MJRWo,K_Wy*_c'0@k[uxFgN9 \lmW[?%ORoo;? T66 @ @ @)Ї|V+7ҕKo"ǛK4,Msoe T x?w u^Dw<ص5@! DO#\zw28 @ @ @X߁Mw{cnv_ ۹_k+ 0"wvc XJտ_\V(7pHh"w U<ww!@ @ @ @{]"Wx-fi0pq7؆Ql$cO`e^_׋ i~o] * )\mMž @ @ @D ?JrrczIbK W׿7l@6nw`R{V97ɅPQ /^ Ff|]pmC w @ @ @Mn_DϺߏTۛޮjh۶URBE.7D/P*-37*ῼq]c x @7)U9Qz_L @ @ @ @}nxF?ῧ07T8&VoW_#y81Ε S8 pTv+773.Ikj"܇ @ @ @O+$Q/.__w~< ݻQ`sO={_ ś[ ƣ#%('_SosOQq_ ŽƼ @ @ @ @`;yixuݿ1 UkqqT V%*\sg#ߘh](*~i=6M_4vy̏c, n\廚O0 @ @ @ @`ߨ)*mGmQ/ 5{+^/S[#SuˏqIK7dS\/%b`z @ @ @5?RoLVo-qǑ)Mž&U_Y.50?vbySaDO(῟VvFεm5 @ @ @ @SohV˼BW^\UZ] &X_Fߋ{n;C  @ @ @I@o$ȧ S*4Uok-2<'X/A`GvO m>6MӹDrx$p$;滮]+,ZHM @ @ @8KG3-7Va9"Be_'2_s9#k>bD ,?X9~;5 @ @ @ @Kk;ȵ`Kc{vC7!9o)|897K =i+hItZjƈP1 @ @ @! w}.ևU[r*v_J9rs/5Ɵ#]pyn)*oA9_  s%~4n~* $ nsGk;ATj8&@ @ @ @>vTЋۥONͭ>!ݪmh4 D_Lkyy=OJw{* -;{J]'.]H_ḕVI @ @ @ @`}A忍Kʏ^M}' _z+t_%Jq_(TnυV~F 2]?n9vizm)zw5, @IDATn4' @ @ @xR߸3/z* =n_+U-'Àh+MU86<*_Mi߈h[I^8ghMoW' R`߹# Ϧ*g @ @ @ ImOm E>Wz{FIt~)k5sbDMTy t#* 51ZV``{,71Kon;{JQis1 @ @ @gMV܆lcmm/kU[lR<_6🶿MĞJZIW|C/ *؋_3\]%uRo0 O#zQ~@  @ @ @ 0X96x1]wt_)m 1|˾c/>;<_ ῑ'q7*~5g"W"0{mF`ofJ8PivJ}O[k]!'J; j7WmR| *֩H @ @ @^`~~~v/ m{ZoQ7f^. pwW%\8c#@`_m77rTQm#l^׺oM~XQWq@Jo4Yu/> `#@ @ @ @@'P7%ahii$wȹUTˁa话+s#MaW@]{O;8@_//8<Дz @ @ @Q>*O+^ >[[a={W/ 96RboTb1C_u&5q*桯'W<8*_NkW~bZ[?T|, @ @ @8K;+ͅV P+s-5ҲM 3챵_x%WI<X@ }_}&ek` 0.Qo0"߿/]u @ @ @΢"w6rWEPiZ媫k5L m#x>m/|_'ptwmᄉfAqi;ɦ'  @ @ @ p"n%ῑ῭qL @ @ @( w4Zwg/BҒ0]?fL {97\Zy |r-* , *ZFV[ ;6{ ᶿ7w?;L֧\9qqS|q& @ @ @ PMt_ Dx^P SA7B k tsojRwB?L'- -hNN [7  @ @ @ np0_zA k%vԇT-pQiմuߚ2 +r9m19j"Wao "2 DN #闉n @ @ @ O" Օ#mG|_Z$/iC5^'!ICךzƥ7PnoѼ;_ EI @@ @ @ @%m+_ _hϊd>3V^',/>{OߖyOAOydA !p<_|\c %O{,-}<8^xL @ @ @hO]?Sao{Νƍjyq" vFm[zɲ~~N$)TwB\%>`'B'x7|@ @ @ @&ЉMW_2}{雷:Un*" hF`V'b/3I$!p<NOT@ @ @ @ ̈dՕƶ )y6rT)(E)D]vx;R ? ^F643%"`  @ @ @n 3j _Kwҷt3̌O-#&[  Ў@+m?}7dlN _t~zNFNoo ;NOmE @ @ @ p{oH/q4gйl=̬io(N!Д@/xk =]9!~NhɃ=6!9NO88痂,@ @ @ @#0WǶ/T'mS_O#D9L`/??Ňwd^wf?M1s,ĶAqnS%O{,-}CyBc@ @ @ @VV@fz|(2d@5~+YhI̊ox#yOgT⿇*`#[[@Γ&g ` @ @ @ [2_X.}{ܸԻҥa}έu$ $+OR0á Z)*#Wq>2 pl_|\2w>9''_F$!@ @ @ [t}ϔxKbUԼ E=#KXƵ2u_zq?[v!o@O/_WLMkF{LxRX~ @ @ @8,y ;,CjZ\۲]7oH4B Ϛ?9^]fƴ2: ِHtB\i<@YZxs6E0 @ @ @ tB⿎bz7#Ns4'mOHm#pOWG|4{fqc7H< Vά#<ї7@ @ @ [@x{MjY{2Y>{k E/nBk;^N`@-yb86Wp66:ߕs hxi݋o5 (>OA~1,.1`@ @ @ Yotm7fVlKM/?zzƞ:&{mE4%Nnz[l?yT @`V.u"^ i@ @ @ @J@OQ<5RTİoë)'L7A#.ƓE}N>w*`ilo2 @!q)[ubXyc@!  @ @ @8&/#Wڶx)=5IN?Od7)|,@O⿘3G o  @ @ @ tv+#?O}V;]m?f`j?c nw~K͓%O`Fa]>翽hp/:A @ @ @ 20nD/&[_SHB=`sxkzA05ym;:@.fl[]V}_)70q!L>m aGoËƐ!@ @ @ p0_yiBWF7LNg"@BC5O_1`ŏ r@ it;"܁ @ @ @ @mMu15wK#lw r)!?oUs:<ͶsrκrxC׌vӟ/Bsa ] AFYg߃ڷ[  @ @ @M^ IZ߄mo F8}]t6 B=r_}Mx6^?̀Oΐw?BϷ1qn]21FGC@ @ @ @`Wi߫6r3Yܕ! zukYEOS0m@8@{O+n\[Vϖs_xtCܝ?6S:#YR|2~j&L@+&+&ˏ"⿣CGxtX @ @ @궿cI1ٶ&?CPGK_r[7=^>NWלo Ж*Zܑy:$'ߵ0=~u2V ؂o_l@@ @ @ <7RkZ?.z9${eǫ9tȂ@3Grj"/#*s9Q{ yGL`m%b+vc%@ @ @ h2=TKWI?w¶~7: y%i(-md8@3S7˱> ^föwK[ ҭZ^lA`R'NG_eiLf#) @ @ @ R*yZm-/.s|'++嬙.s_dߖwRTdArKaߖ[8;T%Ee@ @ @ @`;y/ho;ψ,M?ڗڥ BJbCM/ k |V.OW!Dמy.76?u7CprnAߖ@ pg2C__rTOe!@ @ f${R66Gġ]=m4+eijed>E<:e@!#X4/^ضc(?Vϔ_ d{3H'lut鑬^^lq'[ + @L7?.ӿ6_\S:/~f") @ @H3+Ӷxkw%Sv. [O>WJo#g&3?oz.Q߽x;N@/liLy?⿃C<@5O`fy# S i @ 0Fue6q.=?+叿p>Qr!@ @EFWv?f16Ve=Qd1 И{33Y]m50m%Ӳ[om:t͟] i-&vnMp @ @8~+W?mm0^Y)kxkz15ʼn14%J'"vcOmftzʅE`O"kO?=moh?nhi)Z\޳O @'}J;goOK97v|NPɩf2ï" @ @8fΗu Z뙬s>Rxkv55C!4' _y27Z].pmI5ƥ TKtS=RX8y?M=^k2OZk?ݝ0}s@ !@%pϾVل2uҩsFmNWl[roOk0<}2' @ @ H7z2z-tZ1ߪyCr kKhM q[5R\{oxkOz/֮w@)$A @NukN4ms}[ _dyzsqԦ t[m iߏL>}n/o7fQ9춿C4HC @5O |Bd4+6 Rv̄U2`-3s5r/\_"@a!@ @ FBTjX)vfr\mǺW,5⿝Lȁ@ke f֐mseaX_ ^qs1@p"kO6ؓSYm;=!  @N' ߟ~bTSM{_BUL;|JW 2-7VNmUۊG@ @ pjFl~/oi,2v"C=u=\ahoضܡ՛_|k^ICX\>]Z9[O32I6y_gKo^'Oo W_)ge)E^.HOA@%%խ YyjZEPupЫ,O&|-o @ @OٶoZ&+e a"-庉|+μE}2Z[H@ 翭'+7lۘ O-[E%=K>`P׷DSeelb p<ou_MZ٧OoyT,:xmӚbC!@J?|߶ɥ旾 Ina$V1Bg2_ڜz~j@"B%v*<"- @ @8=]F1|fe>H,/w'ozV/2oueKhI@mM }eO'ږo}SMx~7?Xyo%4by۸9ԇgxkN~( ;,V6gȞ?I ܩ6m/aBgY۾/E~"]8U㭼T ,W_9~ŋek_+SD# @ @87uX53Ur\z<ݸaK\eq,Ųlբ, ,<ٶ!JӚ_soe⿇>TF vp p $z>xk~7z/C{c@IDATkG7m+F8A i$3_C}g9/ZT:S<ϊ!hr_jE2دvk#BC mqWJAXA @ Org̶{C{zοU_S޼&h$0}4W rKYm즗D Q>es&L)شm%N &+MK{ꥠOv ܉6ض_.%\oN/˸vT~z+PHO㬶j[Wԋe.p{_`eL@ @b?O?UoLw.d翺o,aZ9y]K}eĶGO[M֢wod7S'\OnэzAg"K(X<m_YewO w!}I I$Ӷ_:|9 )i'Ƴ zQ= ?/}Q'|b}ݰ>ܠB yJk^ oZD @ @_IǶIqxm7m_6 Xwc,3z Y7?cܞ_Seim?;[+=Q@ p|R7Dמtq7AZqmyi @wu[us1Ŀ{-Ij]J\gAh{)FlÀXmwj\XWV! @ @T_zq7^^P#Oj1T lNx @ж?Yo˷ m_:w @F ?^Wwn cSWci?up?' @6' ׿TF/;M,;|I\:i_k%}7x1= }%]jϛ*XQkA+Td? ޿%ݞ\?! π]W^-G8@ @ ?-h%F=h__}F}!?k^ G,@7r׵^~g뉳⿩[s^]vvtm;.$ p $۰mCm މ7~?KzhiQI Ca@ p/?}'ah$M3N;=_{.t ٬,SٗϿgGZIj@s Ć*mL_}l} # @ @8??<=I.r!L.<؉^%b,n|yuEP[%N-ŶV @`R7 |o{SP7Hu7HPYc{@ @;*^g_Z٧ҹXXŖ"> f9'_MkGfTj#2$ӰNmS^D HA @ B` [z Fqqm{c񙅫5whpdA ymGb YpXotS[3IvLU7F4-L gD8A nR˟m)a{sƗ:U^$";Jo qm_,OŠ*Ԡ翀!0#Q-1?ϻs//Ws؝^/~Tm[Dݩ>Pv.},ɶ;E8X @%pR_ciO e=)GCc|_u FkQvKgtoYŲͭ涞W-̃W{:W -y0YI)o+PʫE!@ @H` kxkzg2u-_aXuyC<8B`A\el*}lY.vYP'<GO9TƟbߤC χNW\翦;߆m; &KJB(S$ @m\6m[^xhQ9|Evkg(/u2_ky5WUٷmjE+փ#OTՕ{9\U^cݠMmp @ @#⿫ݥX,h_ycS퐫b/Ջ?"@`$>\_oMV~?w?= ;Dls+=@`.{r\םY^z*>n:j]hڹ+ɶW7*7l"JD @ @%0rC$V;#Ͳ?->)dň G,@z] Z1okeZ5|? 'Љ|Nbebei?)o?]n󽓒tZssib<-OAW @ V)/ >Ǻ)͝d4Ws]\rH,.·/9U?1'-|qQK}HgyX ;AZoWW.*@ @nK=]m 1ar/';Q`-J})]&-b&0$.<}g[wwbV'PO";;'Љ AoӋnl\ '%f]áή:Mʐ @0lm5%ә/GZ:ϕ OJ=?楞߽MkjWW|X% b_=!kz Se<3 ОEvm[E!ׅ ܲ6yJ5HM0mZz 5 u{zJ B5tf։ds3G'}*6j@>kYwvN͞7/L_ @ @=2^6 ^tl _<\I9 L7f؋Kdٶ'򙽚RvCf1~٤ %S~L}f~G -Wri)Fj{ap0#z?}R 0hq @ @%պض]EN}!wLt<z)T_ߵϟ_ϨEfxkA86VgghٱN /Dž0IC [@']B(GM8@&ӹٙ梞)Kj kv6ښV[JMj M||Vc@,D^iї=z]PͳW5hGg"" @ @#0|LW6m'&[3dy:_-n)Z\' * ۇ8:oVm?\,͊ +[EBlɾfQ_I 戓{d0IC [oĶ/O7=8MASW5v^MH-3cOV\zu4W@ٖ@oܞ -uL=t0=y72YXn^cx QR"X< @ ߅/F8 L.mV@7 YhK mnv߈m%|Llے<_W?^Yo{R  @mcb8j6/zּ|UŖBh}}kVsUņBU{ޕ90\iʠz, k#2&FJ`؏@n;nyUMY&6AÕ& +T)Z{WnmcqD8A KF^/?R^{9o)pfNJY¹:AJu(L֕NeW\d^*|)i$ҋ*\tRQիb/uj7\TK˸2`qGvTʋrs @ @A =궿Z@מ=WKJ_/v%DNS?}Y.j/Mh1.+V!@zն2}&s/yR!kirVQ:fQSx&Uì],@Lps,*NA-Ԏ,R&뙷VU3_i"XvQCmcue-O7~D/ % @ @`\)9cߦԻm7M7/KfypEl NkI|=o;!pZzy{ɲ|f"SDc]철^O^7wލoۀp p߳!n6a,oSrղ|y#L @8 od?u,Z l^)SqHb8U1rW&jg2"O¹HuVX:wFW)SiTqR~ 1 @ @hGRy6z1_;IJԉZV4Os궿uճxkyoh⿽P F1OO!Ë{}m"C8A 7/yٽ$ՍsWJ:F'>ȍhiT+ӏ{fYn}XT7v+އ^ݦH' @ @hDOwduL'?\c )A::,@W?mOo{o8A`1RϷYdLy%vw i@ hob*KZlxM4YB z%-?+-wzb}3^}d'jZ_۫V:࣭c3_eы?2ž,xj,82tq`/u+2T*j&տ,~`cg6F\ ^V% @ @nm+wͱܣU'?- ŒlX.;}Rl= _Qd{xGƼ " !0+S"kyNO M @؋&ҫWo[5-(NQtbAڧث)כ!TGAw2f]US Y/?#qsiQr}[U'=,|`9H/rٯُb꫷t['/R @ @Ioyi__(UI5PkmHe{_  <咭>irq,˳$Q<2I}m[^m_2D$!@" rodR'Z't}7zu~]חv{:IŲ붫mYPjRoMut_.]{K!wqj$Srfzau8h94 ,ɼ-hlAlp*O&"1 @ @%.#:,/G6wX! Q]B0|qN%b,<=q?}⿖%'t]b WtVӈ G#E8oI   Fu~L붿.R3m t|/NWm.vpS66@ ̤t CJfzCij^=άvm\WcJ9S+FJ>Ƙ|^=9 @ @`.;_V7V&$;cws$+Jϵ裗 @`aO*Go˖^zgwV#/Clrln@?[Ww`  @ Keow^5- m;}10[JU?˽rfuBqg)B r@ V[P.U3c̚Wx߿UCiUΤ%FԶVp3:x0ΦaMcx'Ǖ2 @ @ pU'KWa@lO!d1 И2Ɛ\!rɵi!؇&~2'+g'}ZS|P)QjOщ&wly'{]9 @A_n?"74 Bk19STBbrlo n\tݔ 鲍j.K>A%fE5+u}R10Oܢ*lgA a q̌*^7o_L[Sn}ɶ)C @ 0˥61f~'Ǭ*^'ss[x/KzUPy7Ym^kgn_lMk]Ek}YƯqk ymIB @ JOvZJk&6we6 ksy߹ڷ׆%<醧Ws=}_N{.m,y#Sz]q @QHoO3M{Oqy?QMfʩ56u\FUVh,wL7;gcenPeXWTݛ$ ڹG/kfoMjWϺ.ʐչ2 K%ٶky^=VjD @  y9~3K=&z Q 7M =籞+n܆Ofs[ ׳4o5ͶA@w<;u|:8ѝ,D8ڤ!@Q ~wk;ɴ&)DSZEڏ!JpMjūe- A7 π 56$tc^h!BgՅ}saX,Ƞz<ۆe/j+ٱ_ ;Hke4PS_4UMr @ @d^K N̊rg~X݇]P R}_-6rb[Fsllж?g_FNߖzwiFN #zW4 @8 蝷B8m9i2MD-/4jJDUGX;׏r /97ס>: ^E{eciJ]q7ɮ^}XkzKe5 ؽ/mxJlPR~܈DfXEC@T0O/'  !@ @'.Y'm+Qt_2ѓ E5 @^}f3|JXff:YY^hٔr27E3ϲcLdBVRy^*c,C5YtV"U`d ֶ2Ќ^YF*.YMiiXQ5/Ǭ.-i XPy6jjg:-'wg @ @od⿑u"<=f"aoi]iE5<g>ȟr?U'&>M.s+~X85Z"k< {yQvԷsK(wj"  @ \CG[Pж_isn9~ϫ)<@BZ5E~'Zcvߥo}@my]}?b)OO" @'on\&UYpSJQϩ|Ze6[0Ěot*^-{rdؗN*,ۙ Q,=qXc TT+=+߳%~xE=uܞFn6ӼVu/;޽s5ߡxdkƵrL1$ @ ܑfZ*emwuu> } hO ׃+eإ}'bzZmsMCQ9WZ*ס!c LS'+g>ɲ|Fp2L.YxݟųE϶jD?@Q @ C2Ҷ&&HihLD%Hj3}5U_&5V(YiEvVk:ִFǾgZUSao2B̴TI9PT'U1W5ѝ[nڙ G@ @G^|3eb"@B_-6md{W^=Ov ϻUy}UQ`UyW"B֑ν⦕Sx-D8# d*X,YUߒ*zLۉ><:6(+{eŸU7=[[iJvP,K||y|3 @ ;@'Ӷu9_ +o=UuXcWsv/]* @mGˢcmhgڧt" 㿠ȋ\,e}DzK1 @؏+?-hn/,}!Q/C.Yx'^+,tcڷ3 zwC*X6C[Q7+!)WCY9riXSN婚GlUy2ZX;/|x-/ͣLRYPǯlߕYke `@ @m =6lߥ/_t̉8k*",'k]9p_W6?s[U'"ob⿲̹#,,Tb.0CꅅѵeKU[D @ ._. <^e`$.N膶--ĪM.ZUpOX?u%*ָ}o|l\gϳG9ugň 1拯k>D}qL'l)g>-{:=s_J  @vp_l[5fV& L-biokuRGE'H 2*emf=F҈qh=.߈l׷Yf< >jFuu5f;߿UCiuf֗7!߈7ftrGdɈ)kNru38]W|_#t4 @ @:o]vl¹/b]FkZ: 0<m _#>n_7x0s糎T#]2Z[>h o>jl}dS.?vx ߎ p2 @@%ߗym\߷-1ąXL\88D4DnVnm?}ЂNbQ Gkjdaf,:C[ D8U:zBTщX*3[g;Z XXb`nY@>3Pj:Р,8׫V:{ZuMxl;[o @ [PW?mz_~k3xjEk-2r:<$ U~L=h翩qB0mYqrqnx1kp)>_ K:_6m8Džp>r!@8^\H 曽 BHjLʦWʖakj;(n*n (EnʳL*nVj[2jΊÖ1Y}Ծ2/mj?ѿ74)< 3Ym۵vն'hdDrpCmIQ}d_g&uմS u\|Vtm?G(~@ @H߱\͋˥ǿSʍX7ɥ_U_PrEid? @`a궿[摮.k羀翖̵o~LsXX=RVo@$M@^}og?LV枞nN wBAJ&ݶv"C okRˏ!ky+4MHYP }m?G5rj},}D*3[דf]՛haΎu4!ۃZJ@/U&?{odqjt7z*ҔH"e %n&ő 8qaG8#h5HQHpHDw twu󷜓jWU'̓gʗu:/+ueI6볬vNE{$Po('cFؒ]Jr&7En13Wn3@!P@!P@!P@66W!5@IDATQފ6jS}WR+UWSݐSFuF >yʓk39e]\s;^]xZw̉O굿O I6>MoBUDž B( BDo[O"z_@~d@2>}a!@ q|/Afe5h^3dBN%S7TĜ| 'R.L{'I?oxE}"aWAԁmMmY?zrYMy5Q8@K*:!0HVz$Riæ5A<ͷmW+PX֥( B( B( B8T߆dFTi܀&u0K!nk?k"-_S^{Muj|^']SڶgW7O3oJphejJ B( BEp!~)z Xh\xse$Q/ffB(H]EmGDJKLAM4tڗ8/";Czh /2Q26Л|zmSHH=Ws(Omr3сpB'9mRcK/}mt*/֦8 (^ܾr*@!P@!P@!PB6y@ߔ'q3ov3} Ee\F`߄a*/јOr9cko.yfw]8 ?*$Z|rt-l/NJ@!P@!P@!P@!T߆ ~4_m SDҾ굿r{ȹ@x"cPi?X=';wk~7Ja!v&7W:;#L2*٤~(]j+U`@]Y!P@!P@!P@!aT߆@͓<{%SbaRh:T( k94,+o`gA9i6`!UmrT B`m;049#jVl6VC%̙7g`Pߥ/`_cS-@!P@!p 0˭\_cř_ E.B{clB g2~2$HK\Aض`E`W-emT4(-U~*iB( B8{{[x?NcSVZ򃤀.3XAcJ>TCiW\ʦM}eScogf8J0TX@!Pg{'鵿ѳ$Vވt8 g%Tj_̟r S.oɔ@ K>yr#UC[_SWi50NAc=qeHSrE85?}JqYuPg_Ƃ)l']d,<{>QmD,#wN$D B( B( B( u@`A/ 8en/ou?򵿑{2ܫ&^Ν u@ qcV\k?tMg\ ޹G*){#vm 焍!'d~EZSVVR@!P@!p߯:+R}T]J4d)A\C᨝4SP_Qnb8ESHyuB]ai'Id(l-} ubդRsU䄩e%ڌ)e$&dkr)zH`$g4RdK=a~t EF,:?PI&T۩4[Bw=um*%Y=#i Ԥ |_bY-_nӛ+ V* B( B( B(N ;eNJp|_lqhWJ2VIp.BTT'y^w5mq>3ͨ?TB`86s~o>̞7Z RrHˤ1oOT19T^@!PA`rmxśyVoz5`\A42)tڷ0C2+>57ӶԯЅFG z(95b׭ b(p@*CwACSU-j(6xIFLک9R! %,cTf10/uq8řOInSB( B( B( B81^{bh:WF'Q[swQ@$]i6 uA OxWU=2?{91,fT9T4>}X=*o7'qsbcL".Võb( B( ͍J9Eed&\efRuD7rte3 L.Yd)O/?dSBaPQ K} ۿAGʤT! ,pBlBDIcTd#wbn@X'xVGfRcbq_؊O*4 zVyYtJ%&>mV#1YYAM_ܩR!P@!P@!P@!P wo-"4?wr;"J߾A_wX #0>O0Qy} &_wlo7kGJc!p|wМZfOҜgˤ:/U,M@!P@!+:ortM9q 3Ph)ؤt-bX 2+l˓Li0SZ4E4"fWzX:VW.ule}"SH9BC wCCX0А쇱*Q/CׅvE&RFٻ*&(NXL=VPA@!P@!P@!P#Ѓ6^O٩2UW77N5VQ_ %Sy_:/јO>σ2\ 81*p:]ٓrr^Ee> ( B(6#J_mӣG`ŵ֛2ˈ`-5*pˋR_Z4˸Ց *iĦힲ)OMY-t5 TqlJ8R*9fB\od' 6QQh` >Q0}`AJ!M=lӿ"ʶ@k_'f;A'JS\RK<Ѿ)_h*@!P@!P@!P }7v'^4U106hq=bBKۤ^|Cx_?+ުO'\yMc%rsֳ?俷 oo^ե2o gWohېW mczYZZZE+ B( B`![•בn)9u#B[m=k͚h<>)Q<'ٶ=,ILs-ޙPH~7h$f#.1t)%ҵ@AOf}RߗPLn+fJևa׌WJ q?MIm!rzf^ Ÿy@ſ~_iզr( B( B( B(@;t(\W:<y_pϣ{첍I'Uk!^? D~Y ;uODO) B( -; &  Nn^;ČX*q  R ,t_/Gf 5#Ac u ,Ve?zQR&v\KuOBrbyd>Rz3(eCM契 ؈hFP|!:c[GB+kW'Pn0/I8}/ y70 QJ$w SB( B( B( B( kmtž=m/ouܞw 19sXMY'k5: Rqczn13oTXwwdZX1+oC7k?y֙~Jxo{eW%$sG+ ൖ7_ڪ]>?mGEvN[XU Cy8yV+=d/>'^&w4v*CQB( B(#OCq۹{ɌjK%2\C> 8 $cѮ}*rBFr+ա`fՁl(S TN.8YZI DSi|`/(BͰdcY=vNZPFCz9)j`l(0>ArYW㛶R7 Iyrֈ2 : _R!P@!P@!P@!p"m“$&|pdU->EZͽ7࿄B`}&7oCyj]Gr.qoLu "pc0?\_sĽxmץ7;r <@!PC`}m#ަG9"*@3C# }Mo ֦b@5~Oyڰv!ONDL,YYceA}`$EYoc[+&` ;+|j9rr6]u/e_L05v][tŬ#.֢+s{VȥY5(/djtY'奓VO}'mZA9u- B( B( B8w@_F? 9'/s}x]Lav};U_ RY!^w*俹V_YsCGzoBUy!!,#oi̋ mJA ? +"1gI['Ob* B( ͊;(O; 5~*@*.4MWPB>w4ǁXҹ{)lXHf,xf#$ɐ/ Cj$*E|GkpfʎTlI<4WA\nTFMr@38@2?N(%v lvv?Ts,$zoq5n;nK5@!P@!| Mu9< M5EMi b8גjҥ3#a:}RdMy GkF^2pGrf9SF mD\~G롎Ȗ#îBw8 [%BmQx')zԛlhѴ5"oBkۡ4eԉ6I (+PCm%~`LѪt8ȣi йPR!P@!P@!P@!pv"կ~wxQw#4ŴTמc\z1ϓ9T? m#omo9Xow9&yEu\Mn{fRGBk/uC^ B( B`8'u}\`b,7|J_wS\kSRV+pkEY}2(r6 >?嬆)n]@ KQ<&!ԭխ`8~+]M<4Bz :A 9)ŕSV&d_>2~Hd;$,<{ۨ)~1vJ7Ji[7'B( B( B( BB O⻲^ >O[rr#wDXOҴ_QR!yP'U?0gq{J7DT4bu/)Jٷle M8&`m7z,IrXM Jһqg $M]Xgd?MMhaq/yOUfixZm'm䩪۷|BR#ݴNۗo?y$1DUJyiT?z_[UU- B( B( B((=ku)jm9dO.X ő}qPWZZTO$g7RX.##WFJʟ}~;^U( B( B( B?c:o'Dti[ oa2/:wtekW+/ 9#0}֮"ͱX'dq~c<̓. Vu)6!V7 J7m{jM2{t~X佸^;{0/=8/$KO!P@!PmW?)@ JQ\S#.)J"m\*A~Bd}ˤ [fMy/2N-t"s@z_BoJSOZ<)3Prpx Y&_? _2uAYd\? atǞ$ß0+y:\ y6DUe_%>X"S.m/J<ԙRe+֖ 4:u- B( B( BجL?M D6r_rۃ4U.L_MvJe@!0ox_6UW735m>, } K$*/6 {ߎ\Ġ\s~7ϛz9_:6Y3bYRݍr'ʏB( BA@wYBΠ)oFƲ3%\v0RޛE]rȇfu !m5佃J.i[D=$^N&dvWlWˊnFXٔudN=S?B2[oƤۇ.z{cĔ}]uw ~b,DH[AM_G6t%OT# O^yy++&C>2N\FhT@!P@!P@!Pl>7هG;<&GDއ}5375h9 W{څW yFW>υֵufU*n=X'c4OE!NpO9ފAY B( B`^0oᓿox/\T 9 3%MwX.=X7sfNaleNYYo_dT>_;,41tIG%/jL&z=%Ll5C)ɅAVYeKC6̤g):ʺlxhO)]ix6w ւR$\}A%+7Uz&4fH~| P] B( B( B(6 1wWὗ>;ܟA-'ODB`}Z+O֞`ك ە6[ Iz#ЃFkQ_7WO$smzofQgsT[ B( B85L[d\1tk(KV0U|UY V&6L̯j+r.b?-o 55E}1rMGVPE ciI1L\1>O)nc;Lg8 AY] 0R{ټ¸鲶+~0`OMÌ>9mTA%6+)!a>W+!n2C|ZTӄ)cy+ϼ>++.AveS=i쟬T~gj9ARl0ycѼSp鮋 %sQizӶK™AY~'+k߻籶}cߖǶM(θO VcC=f[Z7ʅ ;` 3O,LxELyފ!-@!P@!pL-~w6<|o5h9ud>EV&,?.T]!? <`]ѣQYWGE,$HL!GFܞglw Vd͓9o lG>$]Yΰ I<룄JV`cd7w14~HQuI%u pR~ʐ>WuV/i(搑"oT3rQV:BtygWV` g oWz=8kڒ&VGB5)CvtF Yɔ)4E|'d_#5}S.{=gGl? F_ӕ g6}ūp o+ϭm߼;{Ў־EX 3\VX՘b$7eDI \ī{ݶgK_(M*ocn>࿣xz\s5oSvy=vߍw5 U:kϼKmh|..sOϋ#6صrq cyDS9Aӣ/fY >vuS[xm'8Y{TK˕ѐ,fSǾHp<1Ȫ!SG0cA1 f(%SLj6}6gpB+ӟkb.yEk/Tq7|M|Gr{3O9Lp_/o߯9R맜?1i78u)yv85)}idPiЀU9|EQ6.'O#y@fBb‹ڎ}Qʗ?Mwb` l=K~'C>Gk]1'=wۋvޮ:‹Wemߧ+{NO8GxhC:?Gif A8vw͑OBK'w]q ~?G@IDW7Y4iƟm;KP?/$qS)Zvqzk!Q8NN(\4m,b^ށhCqm<³_sSyT@!P9l}WBs?P*{7`u]f&˧k+x4ZK5SܖhC!5GbCnJ^![}XO&La%MvDCrl?uJXL&=$onmPd $e$gKI !>ӉXBg A%$!/@7IBlĤv|ӧ_ &/{Q2V^ly<3c!FG,wޠI  +ǷD0jj%Nr ٧۶Ҳ;/b/9ة3gVmzqA$ZgKp͟mk~NuCmm0絎'[9wqL#J#ys3a#69).}\1?ˌB>:6z`kVk7}}o0y8ehggB!LoZ{`>v-m?~I[]mAt9oi~;σ"s~9s'jHKKI V!d1b<]6wX}شT [~+hﺯ=ǯ}<&̞\y77g|=,gA@IDAT?xbzm.jݥu?ʛB( BC`ᎫǓ&>sC27p$" hJy%Je]F@gc&0[4lpd-C ='|vZR"3ybD'T4P`AV{4n?ExAԸ=6ilN:8&9IMdF9ը2>".$@\:Vs%i8}C-˜]d[ȳIHn+u-83w1&=d<*È@4x&Q+u򲍋lgRR'٩s}X$0S|+Pp:5[+L?gGom-og8/cNA`e+gUC$ ۭ ,)G3AW#{?jS;6zLhަ8 F+w (foV~ gAp{~_b r9z`tܧTtАstkˆ2*yIkS-q̸9Tv+nsM{пyw{گK2 k}*!gG4,N` cO+$_+C8gzӃEf=Ú =rs){(^*q:z `2}FtAI2) _CU?)N2jIIwɏIVe[ɑm;1'x04> 1YES񸍡!/o0azc܃7Tk|xS. #1d)7 Cg?9b8?(ٖsu l.|=݇y?z6uqs|q=hG&GmB_52#f-\Qv, ʹdf3?@ϕ 'v%JHCp])I"QoHk꓄.+"c١%Gũ3R=}SI Bm"Xm΅l#ei S ^ejdQ*&E5]GLd :Fi,i.*h4)[4SR#s44"/ L*<6ypE<|GϿ9gp@xXLyiFs )~$M W[tfL9<#0?Lo1Ո7쇈o^yk Us]:>6YNTZj-|v[Cwp:_ܞiƈ btn)%RȤ\kϻxO+^8+ջr&ҙ&|/j h@ZlyG V!yNr˙pvⱕjVZ@!P%,?Y mTA; ;kQ S2LFbֲC&B^F@<?kݡL2*Q*-\S?,'jQ _$%.(z97X*F-kjrW5VR$r*?;c_A܃SmQ<9$zPn52bga#*O >ꇍ*d~ N+ p6y;G G~Mp }>S>9(dXZռ m;9ɫ7++T㱛Eأ%1`& H釨#TEիO8/XMl~=sן'k{Y-҅;;0fc~gG?֘?NnFf%6s|Os jcC-Z ''j|s885jJÒNX}_ _&!R!Ň9x6rMrm_ʬ{3r=/(gCF>rĿ>-xJ'S8~P|mzYNDS_-4PxY>'a|;;-{٦^&7ī)Nc7.=u ܕ ~l~>/;O3ZosK hĬyĘ8/&g^ G}:O;+ކ6v .\C_m(/DsO=ٿs:!Zܧm_^Wf_-ӕc}c 퉾G,*˓lp;h/6RF+[@!P@!PiiL'E&p@Wn [`vR9>l`Q 6b}F9u FXP3ow|$?N%~&do۶tCWPGO5†LQǰ)U/lVVH_Gr7en龪μd k A RpVv3\sSl'RȓGcy>&-U| 6ʫ*qip_3^ĝJVF`-VˉϺFZ/M GS\GMI71!iɱC>7 [79GoC]s~FRtSS1k kF[#m3u=8ywƥhP~9{hT`|pN 2׾Y'a&\);9؆uF) ICm!P*1k+֎W*m&NK\yJ^¶6]\g"f$lxp-6'K&/d0m#CΜq]AZxi34[ tߠ>>Y]M}+ۃm߳ӹ>~M݈?:.5{gӍ.;>w9jYwlqFC_N;'!u/Nݟ S]Z&xO+6XCLb@kLw7K͟44%DJ^'6h}8> 3K 0"1 U &Xi<{}.wC4WBNL3 G$*_+o+r$`*ob5VF#^ B( s?a]w@5pbo˔!3R$VUGY|ć&$pLh#:-C^N,6x&99F30SYzg 6jdK5En* ]&7h JKvPĬǡmti+ݑye-\b 8[?tRLȧ SXbl e+ nF& ":2)? Ԥ ƘYmʻ #iiżR^5+L+ $f6;~\R> L0jL0|zhf;5[cmQ !/ĆHԓ7M M:.va}X4vRP\ٖE`r'9d9˅/|0*3_?4{g & ӈ'pncY9Q VNf ^lZ}'jȨ)Ȗ!lowmrW^6+ ^ʓ#ǧr|ml=?'݃=@/E,6ӜtИ@\HDPM_tJVzO`,}={N# [wR3㵿ӣGOuTYs<׽nOK\w Ex~T\A`7^|/M<-gGg1{ ۡqp(7^|'6 +8#p='=O_?9'nI1PNJ_Cd:+O⣠{>$>7Oߜ-9)S{%[;}B( B` pGڶsF޿yyndǴ6.cGB\B(V`)!dɇ9DY4.ksh'yˌ! Ab-nKZf[tb1^* ) ARSrcC'Ntb] (UƂKĖEJuVvKbe? ISGҥBP:XqeeH5v <;:e8ԙY6g:~6<peIzuPm/FRlUvz~A>J>,ʠkܲ"cĸACgSi$+Y="c̦~Kq;%sJzu1iK t*z6S4EìnQ ,8?<3yEtZ{a[sr4!\qOV j6g"髴>s 2P?fvHej Fv4C& 0 S~Z{Q`]iI<_S'<|&$o@|?m{#f4 ֙dk^a ]_:_f;XARs2JhYUНq+oD2O,1 ;wbН WMog(fӜ&ek}O:^_C*o>>g/zsã9O-X>$,"y~hJ\ 7H)m ՛s/>^w^?.l(xCFX`[bQXvllX%LBԕ@j>ھ7YHPa[_)OzY :c]vfU9eqR, %ayI9)df#.i :V'2rx$*SؿC d/c Iƒϒk)ju44+O<[ӾtYR ./żj$5<__Ֆ$V*,jG~߶㢡x5<X(1nf11F)ȑ9vEtJLTdO3Q1y:[>>ud H^&D7*dgQ܉??zn+LרMʦ7[cw!4!!)q˴B]`g08!6G R/ZK@G>% Ѥ R |5HvҲ@lCVUZ"ӏ!x=~|>!hqbϧo:E %W]UsF_lsYa29*s\P̻lAHe,CqsfFQ G0m.$!2v'?X Nv9^p?Ynzy+֝X3Gy|k>sãx=@b<-/k<3SGv/ghV 4e`Q[nN{Shn'~c箺CfX!tK)@ƟEw݇|6wڹ-?W~Jգ;}DNgn kDB`ȓ b7ј_(>8-91#Wߥ/݊3(e( B8XڕC,)g_kz9\SpJfTQo.X[s3'7(6WA^ 4@9f]>ʢ[FHJPjVd( ƔfiurtÕt\Z>'+-O)BC2#n2񇐱aq%;BYْy_Ю;!yI}Ss(T k"(B]AnRg# aj7)OÂ}/G!%{ PO:++&]m߶@cX`8vKZamP9(t#ˡ1n 9' N 16"I.ʧ}I~%{Ac+ے?L<{ۓ]ړdӗg< ctX{ -,td\P V^mCGML˼(R2s9?TOBgeI"tN_M?I*_=))"=,:m<7X<̍Ybn-(4Z$ ,v2Y-Z@|l a]GrG=m6=xKJrOӗݻג() k}?*{C5}oPxMrN ?J Opv<3e ۇ9.,!-\rfx"g>~{;t'k%Y! Ggۍ; O0l0H`gI ϛ.}Q=c5]+}6Kl!ox'JU!#0ybA惀N?9srFY?_ DKnQn@!Pg# _`vk߸rߛbNӸ:.^e j ̼ 6 jTJ%})>e<ˇ_kSJmCG1uC_A^u6*X@[LgD_>W_fy@Mխ ?jx.~g,BV–2 Jfw 6(CM֬k :&(3"/ii$m6#Nޫ$tۑ)q>;k=$ jYcup%]+y \fMYxITSlGN>ˏy-PQ9Ќ7X)d@n@8nrFۤ: *~t'b2'37z&w)5r#mzO\yqu oi;s!ќ3jOwzĬL,xfdu%pP|(I-i#i_h!VWVځOjGx0~/ o Ej*%O̩T cԅFMeY$O.iQT 򒶼.k"K[W @X [9K4΃l'GSnY^j| ]R>4 3TO(4Q0}dcES 9yn 4m$QaK| k}՗ iٚUFyyۗ]^?DئF#_fҎAT(ؚLyI;rٿ_ xspd?`rոU$k/P}cfydHʳLj訊n UK<#2%*QKTٖC`rӕx8x_y}ou5I|[jmЖv5?E{43~Ek, ˒&_;BCMrL2Eb;eSm#aϘ]$z)B>˫?Ԧ8{TP81|:35~ IG">|NM?|.ϴ{g&'6Ryǵ'0RO3!JH)FxL]8ʽBٔOsG҃~=/},k?i JYNyH(3_u_u5[A=7ƺS\l{ɳg={J"9o'`l߹xj9_{><^6P[O8($~=*_f <d %۷W5NqOF'Qg{Oh7S$ D ()z/јo cPt͜Y\>X"-^;۱)Uস D!P@!pv!p߷#//>bs'j,V(JpH.qm\cM:XS>TD&ɼwQAG?&ad?}m_)=0,K\TtIG?: /?W3j0??{omU ޓ6f2`l I& I +YIuW*ݝkuUj@JUb x`oDҷriWhgOW.8Bd(\H(.=)Ph@)cT}cq cWMAP=0ww)̏ISD}S$8p6򣜅9C 9uHS+ˢALa Wдݶemlm i28}LSNSvo끧/nDAMt5>~<+ܒOyu9G''z8K#4W8#59Х^<;Kl84K"-,=dhCPG"Νe/OsbD;6Û(c9x?Td=C }z/~,=tLUʅrͣ@][NiL"UW8BQK DMXUa/k|?kN5(SH Q&Bjg _<իJRuck俶[o8/)hƀRVd-{]F++GnezǜV/#ge+hN??O e9_6oٯ0yzh 7=n`k~ttO01̢Y]io.' O}w:D;>ka $^"&y`o#(7N{wbptcy22jam{Cx6恗w~R?}J,<}SK}/;s%2qAAj5ٮw)͟Kݰ@(.t(7Ɂ7b X@nH]|'-h8nGb$8(2BD4-t2Iٓz##(d{2&F%2v8}LU $5pÒ Y)+?i8qՔ" hF?Hpt8:$[K/mc@8U!Cg Fx𒫟GjC- ˒3^Tp ATTc!ND|k2e֫!3q `re)~O*)MSg[䡑iarՏ)!?e>|˽/Κ_=l'^h]emOf 5U'&nEe+X_?&bT" +'w͔ail+ywa'o+W\OPO:?MOqC;ﬓ{9U%zK/MJݶ%G&cX7_i/12ǰL}Oӎ 3}L󻶞`W{Hx9s]G9PgCb sm~فI0j'Y5?hInr9׎ =]w)<, `Vt;"RlnC?sk8:m_MX3(KF-y]!F;UMʀ.ʢFɬ-O?ECHѳ? yh^<_V]|`,:|p>en^ix̿2q+ ̐ /O .Ec\)V,pR I,n[H/eĉA h(O mB 46%:;7(O\x)K1}terj$(8u+|ٲRҿ2;=mCk)ůG?oO*r";u'߅׌LF;TyyD ~5a#O{v#gkc_r.O)_2=ù3zCW9]kI"(y-H㖗O}<|_1,`]7j,|,=mlF<?RO,8] 絎퉶/uDm}zz寱-RkQoz]`_ECh/J 㵎%-+5W 7UIU6IlO86tB *PFOnٮce_$p 2?Ԫ;_rVC8)X_"Pxd Q_LXm;dyOd Ԙ 10j-G:0"i|D,9D~Kddq@ʔ]v2QP{ Z i=ͫ?Pڡy`z`MZ0i9_0M4?6snǖM"D1=ydM5)<<勇(#~[[%?3l*_4U+ U` q l4ʡig@~Ss;BI%ePidCl! $lYNPNb`GPxuB}H,I=laa}s1ib<h:dDt}@;~ $qQ@A %Y6xQi5Z~/bXǼ\\ fb_ڂ&{D5<ŹZsSnXP)ݾ{d8ȧy&1#\]ʆ AѪ7DF!IʌZ"͘Gȋ鄶֢ر+˱?+';7"1:GY5+b-I+#U9cvk+])/)ȦJ) {X6Ra{un'qNN7j;yaf>2W;7nAxgn>vӄHؠg%lD:b'sPV~ Jf&ebM ƔgId,9OaƮC<0* xrrF4{:p_~ubE濋>TƱ .wdbDa Ǐ?,7ȁ+>?Guy.!l|x RYz}΁6HrxR>6)iꁶoWnOS &G%H2-9/8m?CiYnclhhhhx=0~WĪ/k!XU o(hE( {1Ch^KQ  SŐ=󙟺 O~?fUX+xj( @4LelӕXr Ϻ @[%mdGu'|†ʨ\A :$VA:S!]8ɮ?C.UQRS*~MGO*`El/h$Gח^t Gp9,yIg]}~ɥ|ShDnCS]U)jqC[?b߷'5`=0?,3Q(1r.ed ??%Dp.%#O ~O:S\HvXT UI' hq4#Bm/흥^'_=82z즋;uheIc ae,N@#zT$ dz|~M+ڷa]{'Us#N;A5~,O, ZwMQ¦}m'{ee@w;}cq8b,^uK)O928_Y;2mgLR @?QŐ>J8q1O<XRSgJ&EOL5̶rv71fVє,?X鎇Χ?Xb.#kF;.JS M]0K0^\"]"RgcɏG.Ok-2doiHIXsrxLTo/yHgAYlI"y;vey'' wt{<&y`?<6퇓duLNK|߲?bQpQ67S6?6UT1tKJZU UX7d O_ {ⷠ&Lj05TB>/f%.n!o/ZHRlyCD7J*i4Aw0 24nXgWR AO_qܖ`}qbPr{u$MwF :⪡yb ?, ՠK 1Oք[EA?$)0aѸFSjG3@".zi@)3__Kv{&MMŹ&'auhynx9E4 4"1(Zd3h&IzHQ<.6d+JFw akJyZN\W^)z'cI1#nܞ9N}])cgq897סH3FOsqC!=?b\NefdIROu\)~<ӛ ʢ;הB +?8V1ny@6ٮ2my@8rKe%+7)~IDIZE(OsxH L!4eފ_#/B NC8˚@_"i: F>S>WT&7m1O SAʽߦǯXR`7_ly$oez}s9e?s$kD-5[Gc\kZ2Dte떝|_H8G#cpBfF{SΉϜ8ҳ9Y;&6KrpǤ+7è:4+xGwIho" ߹"'  \~ȖϢ/ alE$:% mP<Ҥ>')[G~#(Bh&HHr3 S2Ҏ*8bh%m OY=4AɐC&I7o`1u(y@7@$\E.'ɂ#4oO,5__r?djaKdgąՍ(IbǸs쐌=?*|r?rXV}%{~3&3Ň#n7~"wo~x`זS?d?e/Ġ=kčDO*f'%03eҘstROH.aS`IbZyLmT⵿z|%__GWǓܿl{|svr.B9#+Qb%}Ču_ᖈKhP&'߿nS,㵿$pymz4󊄚ltuGͿ uS9ggh?6M`c9W9rRo; [i8"=6ӚOo 681C?>oŨv\l޸J@@@@@@~y`|+6֒~p:E@A?jD|ZBhq\ v0qR0`){]4!딁qQ-‰t'~Q 4ofR%?;R)46Vʓݓ/Teî5g<Cc(;l+:nKI8:!_<٦ 8'}{LKJOiE8Ū>ZU+J?~( p)uǟ|Y7m_`~⃭ н,^ \ѩ &>3e;4,D vl.}st@r޲S'0I8hVh'd LOts=.5ϙ#uW _Uƾ:R+t9s0{GknG>59 g63Nj;@1Cr]#mt.ŀ&w{OO &/S bRר4"68?R^x,. /Ъ񧸊/\8#>Uzrf>=kͽe3Sڋ26wO[F>Œ*۶!._ PG I2-xw'u$^8\m5_M}ۛʛ3Ȟ-2b{N u2{qTaęJ~|;wa濝;˟eVب1c41>cњ&A\*?h?9rO y;o}鑣#煬|_֢j t644442~wIqIȟqE|9m:&T%I]KzʢRw7߭L1`iGvtvj!nAE0m$IQSa  YAQm'lXh4=Q}bNn04KD4tBA:O'5}~SVRI=!|FIȸ?ٯ6cկFY\쐝쬓_vf_Ρ<BAm)Z96ȪEvzBI t4c9K~eg?ZEF@@@_`ݽd^ 皼a5uBx\O&w,?Dpdy`3y2mM)<`̠t9>O$E(8$g,F`cY> [G+9K^8 kSN,eюO)3O>U?]&{Ѣ'_:ʔf\e*o p|a2 X|($$P8UJ/'{k>qѴC災n<d d9G{rۿ G/o2u)aD|;^_FX[=_݈6v?x/ 296/;+=6Ѿ}r띗3Q䜛3f5.dF %b43>>^gUN=rK+o[ ,͓Nn4!yO@ƙ(5 P㵿ړ?<<<<<<<0o $o$Ír\d+Q, ?pAo&",`s/4 UMO?)zT {>~x-Tĭ L馄NrB~j=dioB›$MO"> XP}YxKh"xxsNfB+ ;8u:X*9X2.*aa_a@B/KR0Uu'J$rO r T%'M}?'f{ܰFc@@@W~nڼD5#r(M. S/xk~QЄXoeA( 8izaDֵ1y/Ѧ %n3^9x6^E5썷E8(r-MWM?Op3CyCJQ|􃧗'iQ-D}] TX;OڬdW#1OT_ GSv5Y\QD@,"6mbQDDij JbIҾN8gY);Yn?Csmkq,c{*eE*aZɄU?1@ucb,ņR e[X!"ҫ:enV~HuO&a5`%+O &vd<<<e+jySDe~ |-;d%ԛb]2և0JNS\@r,V:j- X}0A6mCkMȻ:Y-6I!jzOCěaN;0k.S"=ATONpy !^R^x0k;+HWhiT6A}v-,EN}2^$<ݿ:Grlkk$jVYp6d}^ ;WJySJ?,~G;=؍bbi3%ڷZ>}ᚻJy|)02>h#|f3cU?vlc?rʟN9>]Cil$PhB=WgyӃo9IkI;3S_ Ge,8< '6u]fqXb@qe8q+ ΀ #AYwezVʢ?W#45f!g%_+xnr =ag^76S' >OA<ytCZ}O$+ʉ}L}|Νyyw俶oZp6}y`|_;kn6u˛<c[U.0'F߁% TfyihvE .kq$P Ҁ͑- < 4k6t0YHg5<02VVTSO%;mT ҏ̓OHA1Cs\FxхдELzMW 8&Fnen%e5ajȟ2O\8t*QmL> ׹0`FM$@M)eٍQL#d` c\v}GZihhh_lǓT:V_Iҙǧ,ޛh8hxģD@ B"A)&Ŕ.efEՋ>T=:E亶>"r]lKZs, o?=>n8=^3)_ #ɢ`Nc|Qqfπᇫ3EV굿zzn,φ|j|Y1={ˬHu4llGemw=vOaCqz`Ozk&ﶜ Ra{^$aSmF8 ~W{CC^U~^-;!AQKa wtR?}DMj;>Tϗ 1+d@U%,ϼR/,'Qʍe_,q4\+q^V~ѤZ?jgtG$q3F2ԝKldm߶0XUv~Rc@@@x`Vl,n"k.$B05 Mw[?ghKoy_[ʿW|HLvRG& `+7p ʼn`nVf-ϔCub[eW+ f??r(c(~pkn'yA4{I{ PGY昏|,}ӫ0JD4oVN^-vHJ|2)Ro-/Sd!8p7^ê:r6 s?gf˺Q|thR ~9hٍp& תThܶ<ie{㗗?xzd-;c4q"1Fk! '~p[߾]_d;lX gbov@RO؈[mȃ|_7/ i/ߐJfj ,2% e䆋M.T߻"B]o:ZN{A%?)5'>5la oG4 YdGi :b7%5ɖDGl?eи0 VZ/+2PGC)5qK:~/8} 0Ѫ恃Rn0:ۻ0-ˆKM%xId^Hݱxڣ?Ij N> >gA2و̠8c~h\M>=0|rc]ùr+01K&L4)Sז!^JBX9]<<9(Dr> ZxI./s5馷n/~➔#9[݄^fU hmް2.aDv qaiGVrJ9'娩NQ9}Ƹ *]Y+şc3y|g7=PoCUsߺ6ˆnh\1,ݢEltd7G~ y-( ^#濲Ûi9VZ [t.ܦJ=m;H77M񓚕$ƏY6I7j];[$t'8was@@@@@L5¾.-uTD,!)oY$}OpD^EWz=a0'I_V)nvFt}MvUDÓ h.v:«-UD9& ?CiYUHx7/E.S>! j9$ :Gu2!UW=){(0:ؔzɒT_ pLqα_nɯhgOz*?utS7Nx/@Ee!uNZq"ldM]Mݞs[k644  aLn3ʻDF2%G#IڑHy\W@Z. M{lC3.?iM `aK.c[k=ŐyjmFKΕ?PDp0VZ='?aJ"j|u&ie8=S]'vhXpxWWX>rO+39NL+;[<{?yfe˭?I)Gd=~Z={?ھ:lH91E!"k8d@%zIoV6D[=}Q ş NScԙ<5{pUc=Ζ˾u[U}m9'hy٥sNѹha؁|gTNzJI8_{^k_ZEn5ĽK߾gZyO&LRcΣϯMΏ[Չ8-c_{o{@4p@@@@b(wCJ-6ח@,6YEu T#o/)!zB, 2(a ~&޲BLesy* ZQ`釱 雚`ASB6xQ󑌺K])`:K4l "񏏗/xß{w'=zx˷m?&e?:f]%m]4/ZSTr#74B[%h0>ڐK:LEZJ"oO ݥjnYk?9y f_ y<'EC3'w68rE Gm#khhhhoLRuC?y/ 8Euh,F׍E˛ G0WOz3mr?Uɤ`<kTC&ET~ 1l^~LTKonr?XK4 ƘpC7LvXe'1;I'"gdA瞎.ex%sL.1-dnYgt)~'leP,I4/EMB 5R=F>j7-e~J3S/u<;`CKvʋ|\'~Ԟ(_ü{`k+nxࢁ1ڭ=^@561zx?^c :ioW.c;ı("L<Gi%/#f򛤱o͍śh1be9ˉ>yZ83 EAДȠ% '6 =7m7 lu%O罥,_,ֺk4`?? GD1|A82ϲy~)+^yl9ݯS)L? 265$$ z>Jy':Ebg7y[R9@& D:;Xa9zsk%~kLj&%qlsLC=V^% ]w1IV.+/xvv31ΉʅȎΕ|ʲoÑ.m<0˘XRzYoo ÈT/D& E{!A(&1@C^ohP} ,t}Њ޽>@X+F(P)nޠ~t[F-Om.C)&o8>m Q0 "6^]e_/D0٦HY-kFt-b')ț9!Axbv"/NU.J:nPpjGO~@i| T*p2_L ԛr41+2 n-;&@y5ּJ\(לG`#;iܭNWa٧CA+|?!.c3Zh- &7Ijfka5Yf9מ?s>@h3f2VԆKVHp4@$?*h5xp+FgkOx9k~S39w2, 4)O cs+j}2m :zo> gblَ Ѧ 7 m߶6odDƙWBd#-b?#ԺY6\R[.Y2 *TF*RevrB|Iz6?*Q{ $YrtUHC7.6 >o6l&@8/Z"Dߞi/6qJhL8ow?YnQdۭ!^2H}90h$zfKC5R/HtxDC)B(@uu{?oSF:gc+qUT:/EQ "I6џ液/:|m=0ʝJ@+ |<],&A\WBPr׵ Zyې`HȦP+``[igu?ç*Fȸ'K̀MM<6{Ζ< DEGcqee_A.X)x5µCaMi({gl)Gɟ8z?'9!h+b! ACW)of_?/q£Sȁ.;6n-O/)*&d[xрWatx#&Ȏ¸ Hz*w vXXriyG΄A?#e$~1D5a6>[ޝ[wK.#dZ:2Qvq|1,2 ?H UW>|Dpdт /퍱yy B2ƱOh}A>HˍɛrLm/ F<<<<qMԁ~5F\̖'}Q '}OG?b?iݵwTcXqo]u@qw*t]1'o{L=^'^˙#d`E! ;N\# v),efXߺr=ޤG]Sas8rNiXC%h:#^t/7BG4k,'[R? GF<0i9:ryyy{,rndbKekҶkr}^,Ў.u5=o8x\Yy-5jkReEK O=%px`k#&xg>CEs(2^fƕrd3 Dv#2{GsH a/g. d8 М,zрuuݓ#f:sGxO$ Գ;FlӹE_\'ZG'Y@ek. >]w_yѧ5͞4_04sb'>|f9?^rE,=3j;m$~kVF6Q3&1xo7aϛP=r< m_U/m \khhhhX. n?+B;x@KG?ō>?1}bQʔ~f!¶e'?ԛG#z A#`31"C3IDQ7wɾI 7T? ?&QP&q.WaHk%A uϾ~wKy 6SO <^<6ٚe'ڴ󟐦Vh͗o)Q?%I5z%_>O1L"=~;Il3<;~)X1K?oCkF"!q2!Eɠҍ `й!wMV544=0غ#dPLQ&t}=0Ed]Q'R7(}!: pQw^KVghٹtM\zDk.d,/[K$_{5^~3*g<$Ǿ5~jMG|MĤrCex#BCKn|Ca18r~7/oϔN}&yIxxN9xh̖'/ G9]pKY8u]f9.NozA>AaRKt:^HEnYvg @QllI^jgkʅ'Nߑxs(&s:hu'%\WAtLv| ΧoZ俣oݳt=6]@@@@Īߏ9X72j;AUo`G?;f2 f~ ~l?o4 U$ (%WFiԙG}' BY"/k}XM[.3c;6̳gdrMy)~LXO<$<1*Ԍs?+|}Z#LA\#_>!p) d_[Դ_x+/GSc˱C/G1~?gel $g@ ΊџD5 5efN7,_ygq6 p^wⵗ{ 9ג~͑GZTU߲[%H4ÁZSoX.Hg}[զ8 WpvgS֑[2,_%Lc LlROE I&e%,} )ovhhXرu5G7,k0ab;ZZט?(R 5nz ;[Xv;6z`JY4bї R$;ӹnq&cV6:z俻PPL3O2v5,u.G1 4Υ?WUOlLV7rwOkםRNXgsSNT|Es0οR%dLҔ2cgUq?</Af0DǀY ~jAox|_ ?Ǒ0z%ԁAi( v'咔#8tKP;,6h  Ι,+o|I O"XG<ˊ?ˠM1B ^qwy-K([P|Sۛ3.*;&a!3ollpNYv7w@ 7mk g#hlUV먏shƵN߻xewnӏR7@s଑ֳr$ǔ<3dȬveIn-?9?{==pz`2u>+# ό 4 LGV>fhf$% a!%d|'ѓKz`vcSk g4I"X,MBbzY: ͿCp\9焷e?ޯ&)hX"kR?K3?Q7Ճṭ&Q/bX;3?&nl:K?FPŚƱդ*)q\6jGYpeϗWrx|+ʓ8_Hټ "r|O˜K"ΟJvS@Ã+d/B ZpyHAzOcaLukUgB<HN!EQHOˆ4!'^+{}/^甦x. ǥ9HJ&W젽6@x(p $'XȥfO/yoܼW6 Z'5Ǟ)[Lԓ9z/bwiT“.<ƬvDy#wuqῩGGܨ&ڠʹ'El SL|&;L2RU2w?b%A~j1Q4I,Ov5/˴iRV< c4=gt~`L,w%5;S1E-Tkʗ[U'j? Fj`lldRiQ'#A#Pj甆ux/1VA_zrqЛ::K@@Խ?(7_Qu~l %>4ɓY0YOҷ\F69x!CĪC6tB2uV_`l'^/<\{ a/=uqǁ,;t]9_m]X|ŽC hݦT2QyQ݂*[_῿)e+9.$c&LoN7Q8҉y<`//_1 E$ӧ-HLի/Y񫯕qWaV|e9#ŗ.C'&Gh"5  "q”rOT]W*omjO&w2BbIC=Qox\9enw.<7W?43Ee5 _\/ }߄;椣\f6!/f2z:vᣎ;{======5بoOnNdƄqPw<-gb~RNmlE3Sj@9A?JŪe{(pS۩mKOauJqIu=k`-*R:bT%B"~s\Pu}%@ˢp[n8" b q͘\'Gh;jO3=m$ ay 0MҨZۢBO} Ȱ^/:~0ԫȁ;<~1=?ʧ]9ZIZ3 M?!p5pE/(]Q+I{=>fڠLůCT\'h϶-TFx6约?Cߌ?- dHZZp`t|ID2'[ʘ{`?{`ua'xǧ/*O8RkpƼ KTufH?uk"ݷnwpOs\}C8x\t_5hERDHɖy7Xs]MbSgqy`俈bvo|r܉GdL(ŏB+}@QYjFpJ?.a2mވ=xA\,ӷۢ=+XΣ2x}?}Қ’N-_O>BSؓ "'! qKgZ:A54c[ѩu/y"no~*PBB8^삚pU@"٭BFe,u$Lc<Կk!@OBvtzGe 5d&G̩9yտ|B?ɂBMI ܸدs,A6cDuF;y/&5^/*fS`40oD!@mwC^K J7gY_а 2z}S/:w'6ټ|X:,=@ͻ&x?bjAQqmEq zo!u|`WAZըHy#cS b~gJ(q @ŬH)sMb{ʫOzD='qUh! tWEx% -Yǡ#&zRUΎ_.xkxŸI~˭N~ -KJYʞi7.3߸:zO2/B N+{ ~-/dÅUןVVP/*x r@a'br02S +pFQc H%J2Me5 /s偅rY{ e'ky ( /â\+2Wz [E' Cɬ']RM/V^cM|`p51wtF|y5b ])GD\0/s4Cx`23ex skw6~rđq3b*c2 \C ѥv'k_[G/"cU`‘K|@k:"~˱Gs__>.xOc{{`~<͏ėNa.0ѬYe]d@@@@yǿxа(CܸF7uŎBo V'^2̆ir[B*'-Mv}I@վD0{c|E[nDKe#Xh'ǃUc;@.ՔE̼ʱ_ d:c~+;bqђ+ ?d/~gW+"63zڄ Iuڢl=02zYΘ="CE툑f?s~26jC%Kq6O~MYU~q=L)?|Qtῴ_r-xI{2[uǢMNzњ2qmP9LEh 7 b"z؞v.鋜+\O~Ϟ׎}wտvQYl'Û4'C9cvc5}_~s{wJhjuKiU{ֵ⿱Vr(^|r ڭZ[,F\'Et̫qwHJ~fԄh@+SI9@?8俩ǾmfS_&h2Bc407$*T͔)}@/7! ';ٯ F +Z))0ϱҖWoo)ݪlo[g$?OSrBl_B(4)P%j#RV,~)-4etYxr q#:%$ 8:6#CPD-MТ7騗P' Cchyv혟RdQzuy!5"Q7? ! ,)'^4P6q[dhIz N0]Sm \, =]q^YûY|_l7F+?.M?wcϔ5@h?7?{[Dvd+Gӻ~wqW=====02B6n0s󁚴9o:ٔƂQiR6^J|#+'?e/M˯`s/ S t8\Fmr\HJ=m~o4mI=V^| ~F\}#)7G*Q,?qf@:$@ԈW4Ydi}o?|Cec?(_K@k72r%ddǚ'j (3¬HNL`%LIO|7/e[^ux0QW! p`{bB7z{iPg;1Ǿfb<(hxݦKzSW.8>uIz0 3@ qU7)C? Uk~(xt?KGGwX7m6% +z\̞[kh' &ؾl"j<]g>cd8`'voG|)}r%g@NN[T Yg)_T"@{)<9:o=dutB/C,,ba] CrZV EpNG3S=0][@@@@ynO>ӛqǩx_ԕހ6شExkbi/0lj rKd&"oT0Wa, 8T.Me_æ Xk0FTc_( ҧ%pd9X! s-?mӈdm_٬]I#4Oj- >NYćb#,__xɟj&le_U`sott,:lyL;ϕN#:O3EA3?O24h, F/J4sw֚k)r0eF{~ګ=6}hb/jda6ه:^|s<\l94cug~O8$ceꏨ?9@AR#~~ ֟Kx`1pV}DYsZ/tb-DIx0N'?Q`SZU%s?EيWkИc_8&OuU,ZbY9ekVwc #'ҲF?ʉA_Mԏ`tz2uo_ѯr+UhD[s?M!HFQԘƑǚ?ˤ2L 1GmaN9ʧ?1^˒rڶt =Kx?}ŕ[m6!3yO 0"/L(C8]s@@@@y@2zz\۶)q^7J-B:ojYLB,yskinRa Ia1td2m态'¶ֻӊPBҪ Pn!%7`U!`m' y6dh&9CBEiycw pq:^C| @?)Ĝ&0hUsa40W o'XAIZd H nXj熺ie?͔rN U@:5l,9Trhlrsr(-qMOYim"r tfSVtOpO!tt,6L2/3!Ҵ\ȃWm%iܟl3Ǣ^_}2>2s*^v/k-™|*堿O3{`owSsg}l_5 Os6]>x`>AAgup+nS7hSA㋷ön8E/dBvq̓w;AEZm@܁rCqhMj↙wfFyc'z aIT"$I%E`C~2YNQP:K{d!/4p515ao oгGOOR:/3ԗPOb 9p}RƬN鹄I&+)}B )SwN;,AmI85J ɫ?іASQXfIpVLaZIB )Y 7`:x~m.\̯3S:3?fu>堕7E<*3t),z (NyNU)¥-G:^T D;iށQNj%<6yʆCJY΂uQx`RnS4LVapxgKnsvpfx_b7:m/ɜA'n<7-sٴbMگ=?<0<9:k俙M[Y Y3)f fex\Mإt}c bm*/C(oIUŝ(oPs!6pJ9)%6q5(y#m?.Y E)o/doCeXL2=B\<_ЋQ}mP6:⪬ĢJ~u4x'e0PbV.ZgD G_Au)kg:p%sy.7Զ JJDJF'l09{$UCo4̔jB'ڄK UdU<.Z&Hb<,RK H2Hj;WSZ[BcT!p[_{9 R-r`>s_U7A Y1 |Y(clsJ9T4I1Lv0cyE?Ou=p'yd*؍XfMcŌ6NSN};:7m^db¸f1~"v$w %`~_):΄.6JSM@gQsRʅn 3Q"{=C ī(Sk֖L]Wβ55V8iT\HPN%[/Zfph.mm/-'^ ٹdyT^LYD.\,?Y˶ ӟ&v;$?0ueHT V,/SSS品JhQ !.jCwnd^Ưn,;oeEp/#OTahpMxpqxR gs/}5ȖP_>S^{E9cU?VLYO|Ζˡ*B\"+ز%MyC+Հ@b^'=npɫލ8B$E :"ڸv#TWزԈ NZoJ TT\~UU!3h.8NTU+Wevqtt̩=t_;.x"rnJ2'>"'-CJ|{]GelwF6o6MKv% aCi"ɛ ÆvЮACt'! 6Ad7 tz$EԟRDL0#:(,u& RY`~KC ~S{\nW~0r`l~ҧ-^"_.U~aї`;ڰ͍+?1w"#f~k2\.-_EOj? ҤL4U,+o8+\MQRHaWD@-5U$L'!y* $drE?NyBϬ̵bLWoC&=0~"PqUk%,qPP06]C?Z?*34z %uƂY+_T3*2nToXΘ%z8cZ hSseSjR)Irk8xG{=P=xB[tYwI;fVr^TZdh2kH˦9:[hSWY./氟1:/rN~쉅8Osk8 ɜxYǖ5Gn <XzC?ᲈUF+|AB@z+<0 |>o?>r{)&@]k_ hvQ/n]:ʊoI$MA7qo5+<7QBUVA%>mw= fi/W40fe.}K?׺<]}@@@@=>_P}܃~3 $RIM@/}ZI/cܘ 16ʀRӢ_A 씁CMpO23E4-XĄ(KBuPyq'2Y/5ǛFn[!5$X,7ă&ᵅC|qoGdz؏usN+yh{41f0 qeMJ=ְ)`$j _ \ص6N2VfiQ'#Tk~0#oO_P#ۨ䐲/~RY=C^ut,4LjRd6g[:N8!+p̋Y#:YEW+ZS7σI!Y9IXK=å|W|Eh;OQ7@ƫ)㓩 [oߨy¹[[?I\RKJvX)q;[)?v rLvAzo+96?NຳO<(SPk>deė@1*O^([مu0ypUǽUG]/yp\9N6j|ZZX-l{ud~sR g0/L3q*{=tb;!^9y'AEԥ67)Ȳ$6n7_POU6?<0~7^F[xn?GK.W}2NwDÐ:Kf]w'~ۊWGmƻB#1Go(șn'<ǧ,{eQ9(R_ k>;̳6jL~Ypܔtj̼A~Z۶o6yMTQ_ zTfS6<̍1@CH^hV-A8*)Ҍ_M^Z6#)"堗O4$lp m͔S3 yhen рL;:_95*\WO;cӛcpMG>NSrDJ 3#RTS즤&FV I@[GOz12*~K~OnB/$\6JhilBFdLX#*RIi[J[{` ?juem0y)/,&P1/N`;j-[Qfi)Q~l+aTe]Y[??c*7opt^=_2~e#'qlDfU1@x(~\?D(<0+/4=$">X99 ǿ܄JGsy^Wz?y7ʋ?{|Ø͕/Z'̤%.bMN#/8\}Q8&bC1/5W WO$ ff7?r=8;wÕ;~Z4?.YkUIgD+Asُ9Xb?([(z&M'{ĘPI-H@~5|" \ hhBGg[' zssSiB@e?I @>[e<'S\gmbj [Ϡ!D@O/ɼ,;Eq0ľێ?ffeLRN6AOgE?/3O>goyubIX5>;g>[]yYJ54!B?I!3> qyWe|/^AAgdNoZ;4rR)GM3>\phs6`[E z3s8քi \‰+eNpf;kals*[~KL+ZjZiLɀdZܑ~ROiY|1:[Dh3HJ-m`0&+dOtttHL5'x̐LTռwNQr‡JkӎltUZٔW)D6OCAMӃ@uػm% ^7{ȤVM[` xLqtC}1SDM]sq>/ih+=/_<6DSn ~_2]ImI([p `"HzL)lNd(8BAe` Qح0ʐ.~#)BdSʡLk lԛ_6PZ/}C/r%rzm,ПcLpL|\QC ω~w/3^CRA?e-J8ޟa4()6kVo/K.BOZX?oKI[.DrexGKyM?syY?o2ثs/lj!tŻUI[XbSbvܒ>gt[11fMYӶrǪdG~&ҹ>8'.d*y[xr=8m8in;ER1Rcg/3(rz{NQ{w.V.+\tzpB.4i-9ar,d0Cef[O*|9_ _֬YQEXdRc]Oɣ$+}4FžJ V8o`A+*~(c)c\va)k<7vPx`cOmwSkΌv?Jo22#%]vaeEO o{=====0~HNRysif;_*GRUD Go7 a xsa \!!"򂰎)(xɀMw>P¯nHP6x8ɧ~pE g<%WcOXv/?3eTe|G9ܜFd֜C'R18xݡ]A]-&"RhDM b }0ZA6GIA귔4N] 7{む&~(:UȬMWYÏ=F) &7C^\L|ǜ͜y??/3PƇYq pN~r&_mH'6uڥ;n+/3uݴ @?bMqGB(Q}3\6ke#ǔ6 /KyuL!֬]2OٛZ"ր׏ׄ%TjZdϰ~,yO۝2!=(|znzGʖW qBl_Ϳigh!@mL/.>C=\EJզԌKR biHg\ow;2s9RGUaQ^EljvHP;^-_7eOQ)(#hJ`xE3 4{" 28 Ogeqx54?e!EAFÅ E`?:2:wa)Sb]Q!/:b9}ae[ko],]?kÈxǗΓry} $#?@,XZGRrm*X̖RNis피"t7ü)wp#ؐ XϵiGZo[8LZ^NƪbY!/t^u~_?4?OԺ82~eeIwrZ7;~l`h*o2~)AS%Q V.蒯eG:vomi=~s}kfEo/O'ၝ?xq߭XpZ|b w-E%8o"xn.~T ށiu:oX5dS\S}S,1]͟#{h29W ߕ4}f\\pK^ƯjJ{n_IŘb3^7,c@I\`M6(E&JS&gm6@2O]I"#C!=eodyl;Hȇ^I']Jd=#N,#AW*_e'ed<0#rH =(a:24:vGCfoɍ-f\ҭ5ba-B{"|{=WVƹ 2Fu9C#xn=oIϬ{?]{oEWVpő k.f,VCA=eybE㉌O0?ڶ^Glw'A3FWYnf/ܳ:7Ca+q;E7KgQR|Vu,|_~tӗb#nr d;s{:G12^ܛR>{il *j<df0 |e ^Z7vzEalLƓ?OODy_ @^UOuqkHLٶv^3SYJyOM JNpK&ٕox yj{fߋ#78ӞVv^/ѴQE;?⌂_'-C.|3k.j@w<{%>ckW8`[n-U  4jf@iTO|?8XY{TqIk@f %ESH87;ʅM(.$x $t-Sq%IE9? ,xmݚSL?xܲɜD&Ͼ"H_:.ڷ{..~7H_ak/Aq5i3߾L}#UZo,[Ǥ^DiָPX2fM6v>3<aDW+~DRW;dm _-f#%mS/U'Pv~ZUR/  uyaaHzq `3lS])L*W_ "PN?d3I2?R!,L̵AѤd վ$^Fw~!~fp#LsB#ઢ=WZf.Z:D먟NZ%iAo s{qο/X.$q8[h v0 A+g2=hrO?KtF(K렅M^86-!P/g1|@ +f9V(e7z-ֵSפ~k=ſ́1 #bͥU~Y <0.k-'mAY.-Ž@g^p 4V;(>wC {>\y_փsYL}-V̖@Z⎻+ۇ롧Ys{HW@u6iZZe7͚=()̭|x[.̃=]~rc6UI:E52]1-|_=IῙ浿ikF%O~/< k>ooo:8Κ~_?c?ub@?Xf=====^9O&Ѝ?oK}k =@5QE_ER,vmw;,k̢"oAYRm?P?ט_dZ?{oQ ƗYUY{T*TZhC *0B/}cL{/=>3m2nۧiӶ{q $ІV@ $ڥT2-{_֢ʥ"2E/n22=^}=)ggdvl`BZ*}St곞hڴZ>R7iCzYSS?s87NR_ ɿn9J ^1C$ uXf@4pQ)PLTE?,&hgmAe5tMpm^/ڧ<ϡِ:b φ³ KX-2 4ܣض/)3+P -O|lYAcid1ÞQq";(TFʔa+ƟTq|缲e\MWҳ} h0 j_6Oj]fn/c߽ƄLb,s&rzL{D0f a jP5óޛf|xE`qkƟcQ}#ONx2< Oniv]elG !eJ!nNxXcT(nw4/R.`= ,+#'?RŅBwrad:W߄toO2PPq2=~~R0Ɵ* WgoiBInNZ`JZRd eEF~eD+/}.NS;|0cbPg4?}3#퉻+[z^R#0zx'=ܶO}E )~;&J# n.92~]8m[֭,@IDATSU~|_&ڶ}I~ErYG)RC!0LXks|{bLkӟ5ot1am{^qj@;8Fh4 EK2үqk߈&6,WqXC I'7bsr6G%txTHTfOit6iT6wЪa&ۢ՗e\[Ydۆ"E wM=}O }oXdڊ K}ڳ>}3پO>RǨY?x)8g{ŏUoK_6nll,O\n5ٗ6{$$zC_Hos)Cei%I5;}S"W0@A) ÓISryGAmmV$)<CQ(B))پr]!@D(;qʱe?edX`)."X HqVUIǠO)G!h#g32TR SB/}%d5 Yjޚ-~yʒ-a)kK3icPi;r|qd[/I0bYsep)ٗ _WJu,ֿRvleځE`2r- 9̵ `FBäk@q3;#x;ǂ0 >2 "ȦSk$ۦ|#-v0|f}{P10!Kxψ\va)Kv?4Z]]Uh܂Or'}vrLEũ:1+7;=/Z]7p:rBx﹫Px;8l62G"-5,:w1qbR' ?&}N^-_A{jy@;8/9h4 ,S Ijk[`DEW0n-/2kXޤ Oi~.Uo[bVTơٰ)붐2ĕJֳCf؊e!}}hOh]}$fMx~4%g7ѩ?Rn+)wxF x5//}~Ϯ/>X_ǻ_ ˺d@I`X|G$GVSvCګY,T/܃NA:R'Ǘ6e=_e@yQmBƇ>iĒ6*K-N=@ZIİ#M1W )b#v9R@zIlazr:=ȯEaʉہTi,DZbafFO|=|{'aF;?(csj,}e0f(;e0bhxl46傇:ե?Dg2hi6^a&ǓkHğ34t?ʊ,QNzH5Ffa&sEe~-7QS*V&.?ϵ)Lq0-~M,)c]"3wqxsD:5*c-[!2?7{0W]zł_wjvs* ?'X̩rSpxwmBg8Q<6 XC+ ?5QAdҔq|N j\W{XY} \tb4q庚k+㧺` ʆ=o@؏8mTWmE-ӟG^mmw4CcEXMmZ $lV?CMQ_.SV+M~H :O=@ w 8c0!.c"_)($e"Xƺc|3Ʃm}^ʈMfj>&F&09#Ѯ@s&O_n_^cyYfulh(昐clyLsGE d9 x9v&)d/8}JH unS{vZ]gKWE:#ܟ1vA5*V?^?)cƄZ@Ê/3I-+Wƍly_wWxp,:.MƢq.9amFGrIh7dL.ӇL#!$)i>ymGhy n8a' Ԏ'Qh\!( {Mƾ?;#%a_yJمLb!PɑD緕q_%5}jr4"`=1Zz19Gm+KkKoIRFvr]S塛 F^-;~e #>]nH5l,3bu&$e sᇺq syn0uZUoOK8Z8`Lޏ_&LP=KDf$x_cy_ɇړQ?7f@C!8!'j*r˂~;Z 4"L qc@ݪ.=nP]mjcB=sbT?ܠi$٤T!}d'y%TD!]Zh@C["Ș)=Jɂ˦qo8'cvtqVj@'%$̏:uի4D#s:3AdiG@Ȝ5V#+qS/fh7-Ki&HIjK6u)yf'ؽ7VX4v7&lc1 MchYkyM~f3x fP xAc*Z]ιwo7gsL1g=C"h_ b#,Izz7w\Ė_f)> O=u %5Get476Ot`1%5k2փexTmi!|"Gt=cފYGzoɚ$E:of+Ɩ,)?”#ZXGR1ơ}(] BbHAJQ ~I[F8~[S֝2oGtL /|ddoUyw"RK 0=̧'œrpoAxö'7X%P(O?SvǗ-.[oxz0 i_.{vuK%'w*O~^C.\54+*_܄d炕:3,GXf}C_<87^aۧ}#$(®m/Gn/-POZ(أ~m&$!bAb,/$z=)dʃ^/Ӻ{)Ue;y/AAۃ'˃?RC"P_V9?3Q{k>o OcJf9s ĥ vphOC!h,,ƗoqۊU޼{0ᐛY)IЧen]룼gF#/C1ˍꑻo},SGuMgȍyAWr zHs6YMɶ!KE;2vԒ6C+)S?f;MPŸRzKofx^>rs`OТ[L0_ \Mq:U줽TPf7c ӻ ( ƏLY漥gm8~Yپ8Nv--t[}ҷ)u$Rv;] ~d;AmTRn[:n3/zm"&_eK|B{p;.$WHE܈߿8͗Ls!j"cCM@/e:CuXuAVGYKe[j׾y֫|)wЦg7,9;YkC`eWC#䜘:+pҨ$i&E;{z'i@csde82xt?c_c[C5C¹BWg#LR6+/Dd,ZTK9d-Z'  ׷~&EQk4wfFh+.ٯhO}6hg UQvW>$UZ^{0>C5uGٵEgszsI, u<׹ ^|JWfY9QʜB8W=#)UL䉻>ҍC[j֓I)gkqfWL g>hcy^dE#,#?p#Hfv!t+_#֯rtlO3Hg4(^rq\kwW҂"2XA* Mks^<3[[9=h/T:_ @C!pXןmV7 soZTܠS$s.a,7|ZP*>K@OB{=D駒7V(jmIC@ /i:z|K4ڪe O+ͅxɟ~)w/^7/96ueȳ9%/|rs#?!@KþzLjCD#5B,KjÖmQDHeHY%DCkۢXl(`? LCIZ(iE¶U v_<[E(DLa.$kڿPD" $$-M9)g\dm1f%{>~̅' <.oG'…oMQEd$@ݾe[|) ?`^n??:rnp"^xrQɒ(er8S u!Kp/K?3ºbe&MGp,_jf6)a<ip]2_"@;G!h4x(#ފ>m+f v@6D8zCۘ0=7 S/䴩͂~6ԧI֛ GSw!"n:| >lyhd,=Ѿv:.lqs/Օ&Mߧ^ 05bIlY'ۿ;?Rq14ܘbnPeK}qI}~&bQUzsC_!5ݠ2hiӴb{l*a4kÔpLYZ"=8c6W3W3}k4--h9g46~A6XݽayZ6 ܾ>+U,~ eO@;; gpE, ׅLJ Uq@|73#Z/WW˙A ӽ,c^ۏ6!C|HtkC`Ke/ S 16b`6`[U }j>Wї~_%堯6z#*[qV8{C'^cyi<ǟ RhRqK(U]Rj,V' /Oq_Vzl8q] ACGqMl_֫~N"R_5hH4KDzآ}j;! ig+[vK?I5(g>ee'C~=/ Ea`1fHcYuHGJ٨*$=O[|O} fkumZ @ʧnd7Hµd6DSiG_DgYڲׂ7P6QcqC1v RbeŵW3<OXpz/# 밚W';ːuTA= ~\~)m9j%Ƞe쒳&ܠW᝺0f'\ VQ=,G8`ҜC`?+swFs7wFt^yJSoXX+!,a4ǮFJC D0%Ĥx )Ka\c #}C!ƔB>_z>潄rpH߽,s{gi {poG^.Olƫޙ"evF/PȾcU_[T^#~7UV-R\Qid|W wHOumڀ [7n[nکqmDu-%8WPJmHj ŧ߇?B610283ދs.T<7]PVeDfy2@Lh=d׾#O9&gkmdS6xMbwâ}+RtMEK~pǧ4^ ";4f!9S񓱘4wcH={|WفhFb^29h}}BwzN:MäK '/zj]AL]gNሉ0vIK>‹@hi!8uݭpk9#d8bAd]/X3gKz%e]i]c>f%V=cX,+=d(lo* ˬ"a|W@ayជ\p{laQ R8?Io|f;6 yA$1˹痲;@Cs|lpl3uH@gn*Zo;ŢC˚fWѾ)zo#kMptr]+:w=>G}厛WLe<0\+*TLj@ޜa(JY@CXvp;P P?RUIgNh@m_FlQ'!ˁfFWart )\#}=27ԗ&WIM$4c@*)*/6ze@Xh&FڧALj?le_I8 e q( "VH& 1tT;%SgsIaˎZf!9c! EmM$+HV_hI}lc&yBS&oQ}Ԓ׀ؽ7)cl?>2g1 _[􇋖3phW_]d,FW\R*T,xUXkl"fq F3ҷƟa?^R )CRmR,_Z0uzRP~~^]cXg!Dg(>C9o]vA ݾD17?Y=9Xǭl#vxی@/'x.pN[ ,L7En( >KrN;)xZt-‸+u+O]X}`_29_OVws!Gº}O-=KjK@`9–y u1Db.B({rkC_ n݊wS۶f;^KE^+ڥ!p 2yݵIq<俊L)\UGr;v=8hqnl4 !5nTv 7\uwmDVuط>,T}jx˂_ؚxKOiIFKմNrKӴÉ~4V7+f|"K48pտ5i ЉN+9H"tUחN]9St`HyOg|W \s;psƿdc^?*x PR?ˋ?UAxjs;k|B_*8KT+뺓6q_w[1ϙӵwC4_EInsq$>jt_Rm{DLY0ҼѤ'.LxDəŋF|yM=c]M?BRC!'I1Q[៣t ]ä_J+4P6 C/!#$FPfsnbIR17 !]>efT6s#BPOu7Eۣ%6C<+e&&AӨxu&Vu>}o^K4GV˲jPw/GRs'f4trwC9.u q,S?`ЯN/I8hP*Ft",[3(E"b3@jfA.S<"~6e-Ys*bOOdјd.}ԑM#SeX櫚Yj]_v򒷾?l >$gJ~>|;,d0z3&3 J4EvS_k&XI~42>uiR=}zW;{!DSc 0SSuD(v1κ2B÷ |@}>H}}&$D$SsUfw!ꠔ#?Y D`EYm Qr?_z|@@2pѲe`'῀wAx<mM (!UO'>;yr9b{_َ}ܐu1DMu8S:w^'fh|nEsw桯庨nuUkK2$3?AlU!h4#0؇7;js"6Bu;wE +0pzms҉( #nFks,e|?caCXuA6(Dt'MK|;p'E,C;$/z\g4ꁧ|ajͻJ?"*1lwh Io(9)e aBV[ڬI2GZ@~($!ʃhA 6VuFXdǟzE:l~x߇L4#"]kDӀbŷ(^i)#ns~C]x>KL8g$d0H钼 %u/l-wm#0/%#N4-A1 7##+ UgŊƔ }Sx*{?6Se.GV>`+vSW@F Bn kЗ{ק $E 37۔t7UYށnʦmm3ɜn퓘Qt}fi+}K鉓Ҷz>ʪ8TQdQ4J! 1b.9ol)A1Qg4[B֧TL.?|-  ߓ^(+_4嘂L,vyO=X]R?R/+!k<4geؿᙗ/J>;9kTu)[qo'Whd38F*sA ccW\89U?r92_+ji#0O{u' y#! r8dL篡Ē2vb\I>;;?%?#չ>1v_?aexi<'a8N{D_ XiL"mG̅lhx9_I(ݲlEϋWǮzL5e˕ЬòCgTo87(Mqݮax2{z]㷔Gx܊YO]`72.cr'n.Ɵ񱏎RcAighʉ.?+P_Yrl) vi &L~Z| 'z. HL}1PfzhZܞG8 C<u!h4(z௕#Tuwº \qvI2e\v;e2DFq-)6 ݸӰ飞$v..z/5MK%/ t^"?jj>6VZ?Ƨu2[~[ &v? p^%?dK7rǧNiJx4`;d* . {UxpL=O!r!C]%)C"JBʁ˂0T+qrו mx@CԵ1i*~h-9,gPd]4Hkn"D: 3XҡgQ8甲C?V˭HK#.KAY SrY"Œ(-'-6hȂOr\Fg ]fvǺ)/YdLD0F4[zYjL9n+_?ȱ}o)#^30 kM3T)*O =V\+ 5o aQl1?eH!0)'ZR񏔲x҂@`W+rskC\1څW|"qR砌]?|0l)-kA_猺͚WO’!ڭS+wܠk&w7&ޡ9YRvaBU |ͅi?'fFԭߩc5uwtr<.ZcQ6lT:焲hɸGtcHE䀓}=eFL$NXL,|k}N#8OÓZ'(['gl ~sa>(*x818Py]F-6(W|Bn?qGN7h_dgi^!pῩFK9H{ߌ#??Z8 s.Li}4 @C` 0GxW,j u$3ͲJljjڊd=6#4ޜ5Z$ڒ jپrɔ4Y}%&[l>gl /GGe2_#?UgnL?"2hʉrR,5dCߞ?R҉jDcD'@IDAT&bI y|_Sֳ}Ќ Peacʬ) G9ǔ#9LT>Pl}h'?خ{BAAh2ߌR8cZ)" 1>Iq 7Ǡ쒆JURCR%]$d\B5%irg7Ė^/'ee=/|4EWX FKt;gXڵ!@ @C!XHCOhmDQQp ^ٛӏij&[vӗfإ6C$MES_L|knf>e4)붐Sfɲ 1`Cx\kuotfRߔ#m%]8$%]> /,O`Zە):Pf5ۗf:e,e/.x_Ti=9P% qόÏ+O#K9O@wȾ'NPĊ w n f+peua.Ǘ)P v o= On*:pyr kD_8WxoΈIeŊ=oÎ9إX$E܃uIVa2e (P>m˦v'nr7FN",zb N,cx0Grd0Ջ1jZOaέ/G*Fk߳^=՟%h^yQ#YAS-,(b~Ƶw'_َAS _AqLCOokC!%38#OXu֋q] yhYrek!h[ 4 @C`!CWx1w/"i#)QU0&DD9UHO1ލG3 7 exkoLۧ*"l?QWBHз-U/ ZVi x/ o_SC .wtcȤe@!oXcӵ;ˇ->߽˚sK mI>ֺC)] rk P7knFG\/p WU=Pg2Q8ajEVҙC!ўWi=#AP1Gg8eK+lTg)rjy6C>8#ɤ]摤C%F=ɲ,z5ƪ>}[fWSs45F$/~dj./७eӓ2[xkd"+ "i?s9knjy27'M K  j7޺0{ѷ;~AݨOMv>QZ*Y} 9"H'Ob&J$rGj37qhK~ f/y<_MGW\pDNf% l|B$Dqbh+2n$H>-z1vR[(,!x\Mx҈^Oƍq }V_3X ?L{3f,eM&U$vF=dA_$dpc*B] ~G_I1OѶn!0@H5=y,P*r~OD< 3.- 2EȋLɹiNGD: Sga5ھcNRra#痚 k"H+Y&C`5ܤ$vN]25*t5Ǩ2Q۫חs)m|C}=] A;UI{}Do\^Wkr\hb>$אN%BO@`ꪫ^r^B]:q^?:,vbqN!53`jExZi _sA H u$_S}^(xh=o 6jˠ9{Yr~K'C\|ohOP- <nw ~~UJo"w.:)Gv^Ovr#?wDmϼX#[h+^K)/_`S\\h}sw{Ne 5? bW,c$/aC?]VV v-' zlĞ8ggA{n@;"z؞7wžZ] \o1vofǡY[8ߧNZO @C!HtW=r],c@X&w*j5Uf;}=!qΛu۾% ^{ ^B.~nC@:lSU ;)[ណʶw [ټR_] ؅t;FwpJ %kܖ d zpAL'ٷt9O!qܒtI,n}r+;( lO'O cqlBWqc"U%1:zE;g(^_vZXOvOѽG<='yگ5ux-^dDצ[o#mVk/ͨfkz{6ok~3˅H+N|ZNLF cO$=)ǬῩ~qqG+l-Փe @wyfkg^Δ7j%,^mO3@;8Vo4 BB/CIA@i;7Lo}]5t3 iޗ0L[Clb !?G>r:]MQLss8Bv'|b'eC!kU)O[`Ag+A u eO=eҔTcn1Hp{vcmp)_ަC>rri2xi!N2sƒ:qk&p(O`@r3~,1 ɪ6m؂u/ҧlA(`+ɚRAǂR䇩ζdT]ʦbHfBL\' @`,vw#CCoge6Fc߼ԞqŚT iDcMɱFQRҼJx.{JgzݝK}|3ߋZ#Ha?cB?y ]_QNq#Sp~li#0՛Vwp`S`!K0^Lzts>2 {x/{To8Is3˽> RZ&?Y_=eѺ5xo{_jX dIcc/}~Řp4~}Ĺ'SjN?sݙz弄ߋ/(gDŝ惧Jy~7HrsM+ڵ;/uonm=̪I}|FIkem:S&l&A۪>=KO% ~ߜ8,^8G-!f6Pg03h0ĥ`ǖ!3+S"%Cl(|8ɐ}~w/6?n)/u!xOC]ذH_O=0Xr'` e]-O-)ķ4}l(*5h~@1Oe XEm==h[#'c#*M9)W ;>iAV͈\s %_]~hE_WLjG\{ 7wH2y_^:' 2xU%k<~|1lvIVך Ȭ:v dXy񡧄47ҝƉ\24>]k7eĮX%ѱrNBxqKيC|_gB1rnpJidR.ˎ%3 5}W=,S&?EK Ml&?ő&z5Œ v/AjyC`{Ǧq @C!p!_SZ.Qry 1mb:"C}ݚKfrc137D:}mkЦXߒiu$S^SmoKFoo[K66]6qo2Kؤu}6>}A#xwV@ٓ7$P\N4eܧeo-ϫsC>SC7s՜cdD! xysYbiĊƟVe59@6 De)H:ѯ vXf?{ĒNkOZP`A + >]Ӻ#50lyCews)pJ?>L\J 0ČL^-0V_=o?^Bw{Ess3{aUr/8︲[0PJO0ʗĢ p}r蕗׭@+hMtkrC`/{ @C!!8 nb~:7>|݄SxhIZG:9"MmG}p<|הX=]fE}>?ǿW5> sOFdW, 7@3-5^X~1 D2H)U۵! ԋ7/|5׹Uy_~0p|w"?^4|o S瘍kʩ D~ˮ=×\!s9Yµ]vonD[ZAŒ9iۓf~,Ņ@;pǶ!h4#C.!׽]wu vxoBoH'9)ި@޸g6)W59hTǮN!%˛.n(] 3H.H?H<V΁ gf>Dv[xP4&]]YKՈwFsOyx)׵-Ȓܐ|1v2loN>;w֮)cCֳ+@Gѣ_8%?|_S<$9v)k~PP6i^%D] vNc^KY 6ҍe WøN4z\/S }!0|w/[{1=gW缯k Z6G1~~}#g]Ca0S@s@$\ ?eֺ\֜,߀34o8XcW̟\&'}\+*j`x6xx T4@D>1lZQ.@UڡlCᵿضzC`?"Ovo7DYYW+ړf~4Ņ@;G!h4{BuGj›fC_F@&߆1 ޥ~H;j&2m}~`IFGm,Ss3O~SvXuع>i,BbWS#.SrI )~+Ɋ),o]M(Ougx!u&x71Bɋ0)q#֧u?i ,~`;"郢dmjf-k2X4 a/tzYl{D)N' ĐS|c= !onqA׋?}Fk n-R/ֲUF/C6ۉm'?'h_zZ ~re!#8V KrWֲ] %G\5ϢuQauRTwhDu첋JX-k:wHU׫W w~2kG7^6[^o4 BD< jRpEngQ M.[lWl{Pjէi) Һ~_HQLn,WKY1'OTvu㏊cfh8`HQht< Na7B$r'4%Yd`=rYvA@ trn«?eF4H_T#7gM*3j@BL` 3`f A@p8q<;wwV׫$N^׫[tV^cǯa%l19f0fA {}߷suuOU{Wշw9nE̮\u{_&DM!`>lV@Tr@祧J[+ٶ_1_)1gn{IOq)k,ː ek꤯қs~|qLD>6 `1Ђl@e S-[@9Nz:N)MϧυL1hi:?rV-1 g,sNB:+n,|_|wp57>by䏾9$c(pq{!7E>ޑ8jjcV#{Jϟ W tJ Ȧ A*llF҂}J@`:oʏ|D6bTҬXb0Ѹhɪq#r@ Y biưeD`*4xe (# MeSu޺ 1טgE8zQla/08Brl@"$[n|o$XC6"MEm+:p[`^ mQ|҃tH,mήjYW#vyăX\\y*tIXr0|wJllƧ#.Jqg߄qm?_2mv?z\?D4KXPh$=$]%J͇&U<ɠou l~fH6=S:Jgv6&ַ6b旘p% ?˒Qebq V iQl<$vhG˘DIϯҡۛٸ_!~k@'( ¸F0AY1OK>vxBU 5HD Uѫ8u`3?!Lr<&bbi;cMxȖsI5<bW,GLw>!ec :wRDCqSED`8"-+S}r|guDyR|G Î~lnc 6lߟ92kd'Y:#=45 < 7'm?WJd#yߤ[ 6O8O1b5s%o7I8mLMD H^NOs -nUx"ע{TWv=uGUC pw9ॻO?j=*.d24 +v\- :]%+-h7 Iē@Tt'ubIG@?}~ۑ ߲t15ѯm4W04Ľ%o+YFÌ}J9'!n|,0v6ͿJJ5|7d5#>'{3N0.Q 6TuC~ۓ, qG5Bb?62:?7m!~d{,/t3Ġxx8to'm  "kSm^ywKb䖞 ۄ7*C6x۴Gs\weS:exA2p$~ ;9`CY2JrC˓^,I<6irH-󳿓 xlg5GOsd鑽v-3?4?K02$ۈ@nFR,HD xk!)h#$p |z't>N_i. rAe*-!(0~CGȓdҫu<+o4Nj<|w6u}t֮V[_! f >CWW* 00m,ڛrU"4b^jDUI6kSDhI+?dYrE0D H8 _z_ƹ@UyhMlÙj ZL-TyjLҒp1E#W  0dPpBni}̮G](c3_}t^q"LDNf(ƍ餰j@|pgH&GQLՐrn9Y.ą8[x%:BYSjxY㐆]b3vð=ӻTn+E4y(2@Z:\i';4BҖ Zj/e9EFj|AF^D'#] /;՚̇ܓ `~Tݮ1F`uJhlW7~sÍ~_L:ʹ 茽3D;*+vCG*j'>*|3ncv0 Έaz%]v&J3$[@lgcFg]PF2%Әi<_-ObBͼ@sXq66 ç[&[w?V?䈫͡~-(=Ap!_̿VGY3ғ$ / i-v& :H3$^t |e3o(#'Dm O٥{O %bk8`߮MM#A-7m˜9㑥^IK-L"$@"F'r;>^6 ^%?4 m/V L,W߸6#OEʛh@)pn Ҷ…pׅA '>#O*U$ZT_%ž]Ifm ɓe!ɰ!M*p:1'ahi6Sۏ3c94&DѶjhEâΚe''MwO9GFc?Cf`+E3I!gZ+A<ʢ o 6~Sd~:O타|Z=*C\KV;ibjݹw]}^ne=M_p̘,oWl?TKfWgޑ e' w)Sa|AԳ,uHC#׮)\M ז2 kOfږ] OElNd'km9*7 ه9p#idt>>{~nmZ//vٙ#CǸƯh6~6E೒5 Jw92kݤ&/[3BD?ޡhm%;f&Nr( lXʰs l H?o,\vn?=6v}/*E>'s:4T3~H:o)G⳿{W !!Ye0(:?)D`J]8;?7M6?i_?^m;>7M%A 7R6HD x #W>^O-|W4ԮA۶bL|g|qM^#) !KF:^)(̠|~濅*ڡu>y/ "TWvi8 'QU ocLlFHҤ.ׯŭ42!XteՅh``S$/ʬѤ;ڵē^>돚Y׸;=3̘4q2b:|UNvCC'0:~^#]sy_f<75ej!PIoHzaeb|Qq" Ys(mǡYTK"sQG / s琘x5Еx>a7b]|'do(ߨha[`<.\ =L(xc!*o,=ZO+|R.Ehr>ۜ~o#[b|[͙UvV->sylb^ b!E,>{zXep#0_Zcl޼i٧^*7|nֳʛ[H"AkP04KfcwT:L %b[s?%D`q4p5+]&٠wy_n#<IE 7N*,HD xk!0~QgJE<x&\yXdeȂDOv>)ԒebuIaժQ^zgߓW?jg=Pg Q4.jɘtmp  ER۹J<%kY\)x5Hꍆ>k n hqn >쉆eRۿ^8D%Dc7W۟ pJ~J:Moa|!ln[U?2$StUuдˣlڛ,t[^5!h>Eo a@IDATyټ 䍘@Kwf*fi.^y>#q>&4ڂ*?)qUlħ3 o*e6eFy|'[G. ϟfLS3ⅥsһEK"FK_''7B)돍ggli~1c9ƱƯ5TP'\)ӎJyMnq07g$]d" ;#7 vA 7nXSi"$@"A`]'jOuCd4( Z'.c5iy=- 㕠ʫN+Ђ umV\Fa񢁂(=,:OZdM3`VFyT`/}r ]b2'V >Ǚm~"U WSDV4)e'(ENكcL:@>(,yIe N yO3ү'6Ć;q0Od|"YuŚEƴWFnM>63&UCO,/Ί@4|xE9с'\R4X?F2^k_ Nz0zwu+&AKӎAs߫,| nȠ% ~w|End_rӲW>7<|AYGHE(zQfrA` -2z3F?,<(x+XG Ӱ_;` v"oU;w#Ð#7VF~WV|&%+Kh,~$2m4WQh/pbm,̈͆*5Kr_~k"05 l!p7ؚ12yd"u%82$@"$C`?"_h@6 iC.+ԩ)%0. rcLCc*Ew!೿Y/큓 X/MRn S0$_Wlt 2Qh-&VճKP?vկFRb#Y`[W~4(/??h*"o2XOEC}ĹjƁyg(f^կZz:2c/2$SKo3Gg'pfsΓw pAWϫr/9ԧ[=~EJ%ة5t9>GpPx>RGuهx4~6W|dCߴ^6~(/nZ3)H>C6vr/yA?wN霙5DzNq+ZVFz_-O}[|YJ4lLr 65k>Ʋq;yl pSWwǰq<6# cBB|$6ˆΧr"؝o߳gWhX076{e>L3: coW+1YarY.i?+iT"K3#6>N7?oaז޺ ?Q7gYZd$7 $=M݉@"$[ GZHzǂl1W #ZDǡ.'%"b_38(XǘULHP~)sv:[R6WSh#VDIh\mі`#閸qEiunT_ il TgYZC&d1.F6)vt;,~4Yq! p$@|2[Z&ӈ[ C>IZ%JIR$KUs7*Ll1L%C:,#4BM xq]5ͽklN-  Nr?-;Nt >ۺbOn9Xop!;"5pm^ud}=slJTc@O(Jytw2fS(C"Yڛq#@oVf{/+roKo(qGcѦ_qk:W\ACu=ԙ[=4 ۆ5o{p.5m@n|6BGDaC@s6ɮl^iVJ\PMkƋb.)NhHei͋NdHf&?|U[T%o&LD HD`:!0~ow..cW x!_R͘j|Z*rgEɴ*]ԛ0ן3 xGB"DZaU0e?|b dY|\N"˝r/\X.pK&GR?Cw8"KY{h~*2Nv~Ffy~hZcxN"c,^+>oNeȰa2mqdiͳ+#AeBЏ=u..>˓iw~nZ<{?qk dqO*h5Dm$mSfadI8oU:6"{Jg}Ey?0u}0^k5)GcJ.]\T2qXs{Nl^|+7MVϱ':ptĺ|f;/Cz3l(djX#򳿂'/"0hn|4x%t-)yIA 7N $HD >p` :-sՄK\,2Va EHd},ym>YqqA838Ebtu:/JďVuHH~bAQ(nJ&34*p-,cE[ f-KET_KQ.LRPBy㠬䝾~#6~Ek௕X[-/#M00!Kg$oS&s1]Qo9͓T93bM6Q bs:LLw_WmkAk2SsjZo&ᒤ> [cN(ecsuFt92|`ѳ/I(b)CJy9u_~5:YmT~<>W tj;S:v 8y~_MXqSyWY1^<"XcCWDC5yqXg0eإ,C0m@`|Xy>4D 7nid 'y>mhYLuv+ M<ċn όc# ,j`XQ%?^8VkKE?/D` h6Ɖ YF՝ 6]o|ofhts[# #mrpL-@"$B`Sz]>"/x'%d@br,``+/!/:m0& 8/JY5lew>O=/{Y_dp2| vW +GvLD6SSB6qmU V!S*qe◑b0}AfXn~h`~]l?:H1zc"P&yۿVʁIHJ/?mdAe"RF_QXU1Z!$vRfbn3+u" _h0>n~\Ae׽ D`˥{Us&?8ʥ~BW4Νztq#.m9y}Co ??]V}W垏׸a 26UƳb i2泐?bqiq:eO]X2y&V2_h<4s(n[= bɠ<ӴݬEʒoIdr迴n*P9 XCZx9eSxgC͗cIF4%׻hI ʬƏk{X'}v<ќC @"0?d-xJ:7'{Iua'C ʌIєJD HD`!0v*3@ع-hїikiANl^i$6B Yjk\'τ@Fj<qƩvt8g̺l~٥藗b@6}3Ylb-U95O`a(ɢ,<'M``ƘEgdTI#YɸI~j5P- JKi?B)C6lys6c`-gAqy,bAw2Sٌ̏puz8~]E(`!pw^ 5/6!Δs DZO_t&M({$?ǡ [#*eJy:% K>d+ux'k34|r>,0 eG%2 Tzd;D1e&xC{ᥳT!@ N}.i]p2lZ}2{{/YU6<|eSϕu#v*&-=V@6'/?/R/b`ӟ,_(To=I0|FU:n`$T!TOo"C θ2s!ס@@>`s$sbeml en#0yM?6\*J¯PLvF) 7S{sɟ m@LM l}?WnK2#C||@%dP . ™l8$cO7~tbn ';Ao8>^^z,f?OSïhC0.}&d(`Uiuab#]Kȇ>7{F 롦\VZF8 X3F^XPٴ=gLĻ;ǯ贁#[!l߬4ctV㄃CtZī<~CxQ[р%~6&nC~ }rǓ;=iwn)k_֪|91{cPL>Qmx { eތvIX6d.h 9 ?18FhNk?+%C6=P6>Rn|sPt"$@" xHy@H_CN#vA4SBɈٺPzY!>f V:T?Vb͐WVoDe`"˄D4{%WmjT 7mBcr"MP؆t**WU Txhe=_lD)Gt?NO`~Ĕ1e1 JryFEH0mX;&:f\|zsxaF `8>Ǻ 4=O?7/7:x8Tڐt'_ZC}4zS g}rE[g?Qs[ʜO#W67`:xYl=pu+w6gqHrXGg06f||Bdu^;X㏕L.޷)g#O ^Ll#_L{聥cNx\=NkuRi 5pZcE|nBA) N Ns>'Söo\^^u\˭~)510 ow xK%\:.ՃW~ *ﺊ!jr +0.KtӍ_rD圣CCo]1nL hZ揖?@u=O~g5Mp]W+cӮ1ˀ_ǘ gs){_۶TZ7 ;:=?~QjPI($g6PzT QFtB獕G)u .Vv(+Ce6:scߜK9ayKnPd"ڛX!V`3$@"$@";*=| kKb^Bb4%_ Cyg ǷM2چPf#ǔqآ AE U+iXP'M}F⺠U.+(#\:*y :D30RQh6k.}RYNN&Md2kCҿ*I;,ކ~y_RuW'{gLȅHo@Yv߆VMOY)3>tFn#hE^$FM7yhз8F -ݠ;Xp}A)#돫yn4pEx+aoyx Ro(]kFCk3l&/CtGOp0%t+/RF2TʆF|x5fҟ!O2iv^x76&D${P,wQڿs#NC ח.6{N/eWk<\n3yCj2YTV%] k2l9]kI7䃧(viB^x[T 3T4c7}˒? 色-Gj|y[5M=ݙ3ʞ}kꄙ/߭ib`ipc1lCށA†m uOS%xc)kѼi7Gu$9*NO5,^tG,sޑpi-ڣNh:M!iVd=`t㙃^r5nvUngh' >-ێUח84KXɉW%= rh[Iwރ 7oۓDO40)C?VBdj쿰v+7unAl'?s65W\ҷutjzrfe(wMWs/OT`P s\|Œ?ܧ ZZ@ 4A4&;K˞?Ano&~暻$n%J896cbҊyys'g+>aQ L9!&STçQ~Ac1:.c1gD%T]MH;Uyc_O[0[: E&)A 613ה$@"$ I?=o"b0 1z_2 i>lV>z6Ystŝo,Y)~b!֢CAx_1R )+M'iϺR&}"A}˪ ިR}AJA*<"-9V>~I:\FfA5EQi[fx_w 4>mxо̪x&d1GS~̏eFn3:pn_3I58E#3]VM_tJ߱J2>"]fN?IWD$tܣWY..+׽ y iљmWΆuf)4ˏ60 .&ns25ހ2>\{)@l:Nf 3LWo+@"R5S|U 7@4geƇ&)C"0hhWǦ#ӉqxϳAHĬ ΓwsN̝_41rO2QP.{f* g?0W{?AX,4k 8"ՊŷԷ~ozb;c9$3#k* u%~F3/yR92lK)k_MMq` +Ô43;mqnNwή +>Œ8^()9z8g|oש鳿+n(Jإ.Nwx}6\61>/Gl TOH0cichcjW1T1vP'הZȌ|uKZ9G߿o.*3!7W?+-@K"oVc1/'2{Tp!obЌ+}.q典e)c-m;i_Bv-5q|՘9H6HR'wٽr;yjQ &S@O[󳿓wm 9aɒUj33i$,z^D` xv~6yspZD H\ƏG|B&mёb"ڿ*“/Pӹҹ}v/K71Ƥϱ4;tJ1Wf_R&#f]BWP'45`9/<v~DV~ t"VGoP礘jÅ:{_&W >d?/a2_OA4plG Z_ ?sVYCE6*gtz 8IWYЙӐ3q#_ݴ>F7^Tӷ+ie3K]4!MA2l GݳmÚWǓ- +q3MWa2 0bƒxm Lcg΢X0)?Ùarklղ-l"#U2f:8o_ڏ9?R3ct; _ӭ͵m^S↘ i FMW(Npv;o>G? mm3-e2Əx|(cv!O] ؒAEH6_ihFr/Yө,t9#,{𳿳fdFo ֔~|A4TI5KivNH ѥgf/\nćX?Q0wT"}|Xyև%FKKRpnoܤWU_|ꞈe!Yh>z>d/s$ho;&_u/jc CsQqq>TaDtpDnh߿h+kŷvuqݴx:x9qNs 4?`ڇqFҿ}xrogGvj 2рdIYip(f;;R9la#+?H*t1rcC r/#CoO_zm4wF@4h|O$}02aA-Gxzy\*M-dl#[Cv?[paeO-+lh0yj̅J"v6+Xl%G&retkN4w y}FnNy䖇JopJhX;_l`"ͣ ߆sH~F0pa.:VF5)'U3L=s_?yΥ2[#{/ɓ&1x]?|/h:u˂D HD Ə8>u'4X DX>^\#.>th7knQWe_hW nڂTZ 7^n/!@},e3RN7>CGS; do]vw_~U[ezeٯ{{')lĄ9~ y ͆CE*w,}Z6LW?;eedނ xSϕ'/JujGu$l2Tn01P i`<EȈc!f~뾩 m8G)rQH y< *'x.eO_if֮//VakFi"DK闶r{N&} }:%*Xh!S($C?dp^>^h,b镍;7 7ݻ3rwv;8?1nӚ):$4Wp>ۤ;yD` *s_IK~f͡Wu#!&E%N;Hɓ!Hq_TD HD` 0~/wc JI{kh+/$sУ -*cpl[;z9M~[ZW-Z YvY/[V&e-Jzį:+Å1ElQZjIܦإT|KI헬Re"ڪ+ԁDMɐWP= psS͐l/cf vW6;~"8icϟ[F~F$S#撤_/{-r!ʪ}ZN q -R@AWu4xԖ?b΋#p)8k߉ ݛ\cb84=z{$ ] Jz`5̭18UF8Adg)[?o;S 5aF:#1>()I~U٥{. ]ŷK[ 0a˪*z\O>&tl`_wN{6^ d݁iGXJM>R>֘{][ʼiʔ1׏lObV"HG3i 1u=# G^.&Qӱ D<|1T#K>2$B{҄ʕVg+:>Wk73`Tw639Y l=O 82NbΜ7x_4%7'@"$vC@9{[M-`Ӷ0 |Q>_ۮ?>p镈4VK}Lh4.&’-օ)rS>hɓI;:Z񫠘濋ϨHvtg-@ZT=4P#;.)q;A(C F̠(G1ʂU8}>(pRAg:.A m<#0&qgJpieip 2om e>~,%Z )ÌOrdzyfz_cI87k (MHMK-ϧ>~Iqs@gׅsґo3"ŎYy̙bokxWnp_vNyE6|QĘq diYra>1H )9v&r*g*L(=atTVD&*K? e@aFqp``nGMf 3#ߪ̋ >3c3tJ.=r2gN,F9s4>TDvW_\[)(ѓ.ui^׿\Ugܞux#[.(_] f?c*y8ft;]7B/J?O# )E 6q,oayS͉jUwB2D ^Lcsdg6ND HXz~VR+7=Ԑa#俙sۡsK/doߓCZAAgʥ!O+mHee!tKWE5zKaɚLc TV *y([ż jXFƴOvWvPh-X0߅ט=vP굆xHi*nE8[(ŭ]bO3& #%N}nMߎΎLy^Lki@g+{7sW)\lNB;TK︟Xnm'Ǿg3 @> ef0s-XWe2i=PVhd:HD H+md-zU"XiɦƖaweݿV"Ķ'=)--9w>F‡bo1 .E(vP+ 큙#]Bݘ|ɱ.[} ]TYO呶)XMzd9Pˌ6Ѩ O $>IdBkùeTa8Rb-h27t#k,:Oب175pҼn <Hd aL{d-o$Ml49=:~{ʄjㅊxb{ۯMwc]o:MPFg.+#V V߸zvs~5wT_8l)ܠfB\i?q3O{}śedqEh%a%7O.H)7݊3?PA{ˉIVF*A f r?+H8O yI1;Gĉ&9`W92VI6v.l1YmI=@" nG2u>֔hd:HD H;| V?X^,  .h/}g'EItnt[i_mk⋒'xh$0[6Ayb&eoKbHzt4fP/5B&AfQa7 O/V  l 3_ HơfTElڍtQUy6%qw(16~t }w1l(OaBfs]>&e<5u&΍ҽ[7ty9>$3 (,GT!#uO 6Ƣk-|>썏" &gDcseH9,3EhGVsiwEbwaHWr 6t /-?lZH"1SIO96SΌ7@1;g`+󸐛*Hw[s_iv#q_2 h_g>We]xOld8z?@LoyI R{&o8`!0 MaFfQA 9o^/{vxe kUQm*Trko1f-[v;@d4lMƃq.B[WI um=t6x?!ӾZ\Whϰ6Sas "{z)nq!*H mZcWᘴDS!33 aΛHwޭ:!71t"=濵/WYRdsD HD Bz|?2"pcߣ8O7~t{,v5M+J$g3B\l"HS9 eM !Odt9챇ȌSTc΍1,!:gh~j08o@ gqSmt!Ɵ'}̉<6nÈSy<#Q:,x[Bg[XlA"߀oV~*/ΐGLW^@C%fgd(.^]_d!}rXT[$]Ȱ} %HA2(:,p$^0meчN)3<e;4gng7lv$YehЦSfU:#Aza06WF$l۶ -yPi)Ͽ<^V3<Ϭ0jظpeMX,c\T=#py5.ԜdSCA\όD` cjl73̢6MAs%j=-O'M-RY"FM?*ge&ǟ)'!@"$@"]seՅ3h….h!gwd \:3}5 i9<˒ޖ*%bɅ֢, UNu&/fčS]J m ]v6hXРP*C!c^g͖oĽ,?ZX+m1v7PHZkX'LWO&xͻ2 Q4.6=[`h_H__.媫Bi[JƟ(WGK|`;rٖ"нtfƚ(;^RAcV=8p򋥃b濡:mzsT\ܑ_߰fI*(ǤҸX1]QZIH$  xL>ʽg4yo?X~e_8>Zf盶Me^#/TY* 4P\ L21] 1º?d@3~"0{ȷ Xj mam 7&_7Vg kr }/l(P ʞszNn;ҙ;GyI17M>*f&<*h╙((""5h+s#,VF0iVKFAinZ' fu r葂VN h ~Z?^^zч<@NnFejbsfАp[#R'5snKThwnbW܁ byagF.7B`J9g]-uV?I 2`1Zcd$6cOW<~df2q^v2\*vRLeRdO)O600H%a۱ aЫ_{۷[8n:{{o>CR|n]o =Ce"DvBेb+tl~g̶z"ē\2ǗaL9yogGNg}/iJQ4Ll^whOrfPuɇƫlpb&׽ KEїl؉XP+V|69zkn/wyGcؿGsB%))` yةypV_4~>u7]8 +U;ghI({D /m/>wMZ 9'#`4/oZi:<.@`ö"uGos#`0F)A`29 ³/iGKMbzdSM LO',ب4VK5r[5}exQI[}ϾԣxMƁlUG}Tl<ߢ'#mݿ3ixNgB?{7NewC]. ^l=kGґJ;oRs@c? {|\X"9MbKk h1'HWdF?HAiMePBcսܿviz_ⲵG):&R>Ͱ/hv^tD| Ó#zv/*vQvʀ7.X&uZ*ЕC_k3Rr'f#z0|hza?XuM@9V58R0࿩F``G3mXDe?(Wi%nx 9+_aN!F٩'s#`0Fw12z+, 6:'QdJ!P-UM/^6Wm[w8#pQ9n3q;u;Mӣ/N&跀+}W&9C0zsTOs^f]xe֪:zex.\PEi!v'kw䴝X9RqA޿{CeNC9+h_Oce~?]B?:_v_vRΙ]~INWƖa} h~ǬhO6R%g_jwKj19WXFpimWc;LQZ`^-?4:UQЪ/$2juA\ASR>g Atߥ?7mS7@ťo17UW,oROou.3:Kz.^N LǼ~%,l __|ԝPw>Z<L~?n{껯 X hhURLS]w+Ju g{["\va}ժlk0 E`>'ĶozEѧx#`X /vn;r6 ?]o&LFRHH-x1ſ9IP\|MhS$3ۃ媗mM_)>Ȕ Jl@Yh+CyhLѡh! hX8`"d)ɾ$($`1EuMgQGQtNH'4 mq#p'Vn#<}q.` _}eB?Gzɭo~ԫ̪Z8 3%}Qa?q~sּMn~̀j4L'ΝNH#8&17Y]89u s$' ݉ᇾ޾1RE+qdA5|]JѬ,ꗾ慥I"pU. uo`?^itGgbq]d?#'3=K!=ANXcBV۳w +y_B2z,}aS 1^``!oo ܢ#`0FXnlI V3b cR'azs)FGP#J-'i20ʢ`_0-ar?j RHuTQiڒYUE2-22E~tJe1t2&kʫ^M#˄֑ˆv2X_AkJ\z{U1JzيCYL-w_{|F UPB[l6;p>eSxB g'˨w=rQ(! Vr^<'Vֹ:VҥVOnpY^[<;J9gp&R/tfD 8~5t@O ?6yK:ͅG`ruDJ~nKm;x@E_@g6Fmqfk me Gc/$gh@2 :~Zw) >`9EF46B?~ ؎] HMas(\.og=Ͽ"?ށe;;`vk>>g炵pO;}7"g~؏:/TD;J23Jl?/o4. {1!),q#5Ry`\Y{`_w=.^:࿼}t/k4# r_Yr`!#`0=&\󙋓1 Bebu|)&@bRMhI\* /v'MեZX?t$ ϚXP,*bR ͤ-akab8ԉ@EhODyJ[pR~癈.NJ*G>[D@ /x}4F`kٯ(m0<a ً='߁ѩ_hÿE=)Zߣ7 t~LWZ{->:֡cq`5 A#FN3-LEBل7\C;uB]+36)P9l*'ͯN49`(#/|X}-(Q2gL ~9GAW}+mַa ?fX@y*~+rM!j4(2Ƣ%O GʋA~ov+.i97]־mi p'ڗ_`bwA_{'jJA6Z/ S?> V)˒g}nat0ʠGo_6;G{~wҸvuVna]'#`sNu??$]_vznw؀@=?4ܵV+3y)$#`0;m -#FEV4 %n6#f [ЄԱEֱT4;P%]/;s^J!?U $v\0}`P +!H8Y,# EB: bI_A 1R* )q2F`"/ mE_7 8`{ Ng'|M>>u{|19~#oA.r x P2&3u:mf>-hgWWxq[C:_|M>uZ_KGC?t c,4 EMA ?6{A)q0i=$[ ZȂ->CAk(9&7J(1{@WW%R=Gk?Bv{ֵ"!omgoO4ߏwt} @DYzK-ڐpA^vd`#dvvy<6Ydds$g\8L?r hv??0xz{ၣ^`45[|WۗJZy"P=N6/~MNF#`ؙ6m% 1{BҤ盒3Nu̸ 2l&e=2J!Y$$Z5ԥ|T׌PgsT.g6G_vY8 Y>GO{ GseEs^Y#Sڙ~"F#`0F +1 #Lmۭtȗ}/Oz>F:OHh졇[ݱM7]r`myw#_y}7f>3)8hNi~4xm>(F\y]No lNk忰F`w]ȶcG 0F@iM_'oy[1MQ\SE#|LM%'0W`)lLhvX :(>hfEB7K$.QQ !?/8 ]߳a-:a!e&(Ƒ^#a7?P mQ?zJMNv I# ĐeP@91}OhSXeSp &mw_KoRM/Oԭ:0@)An[[#`0F#`M#G 0։ omOF[:#(xɫ1vޛ#/r P࿍o*gCt#*ŝ+VWE#j}F#`G>;|dxFM SA{1Lvۂ.h'V^g 0Љl]Upn0FmѦɱ(3G=BɥTcm*@AmД/KZPWm^rMzٯa }\Ҝ-T .:[ma!Fir[U ! qN<%t${&+s~'X]_MJ@'ŷ >|OX{[[Yl0F#`(#'(y<࿶Ks";úwWkG &ow6@uFa_AD#\a͏-A/s_l}|9W{]$w|Ƕ|u>fQmU#dcS+[{^pF#`ً#m cXcH :C(A4~qp&dEځs,Vl|CXi! 7{t|@͓6T#,6˲hl0F=Vsm,:K h!` @DA2I6|/>ɶ/Cl+gȐF#`0Fm=51ڇmom+OW\YdO'i#0l?L@a{X{FXa_lo9Ɏ{0Aspk7Vs߱b}n\M[$ `D@tӻ8֢#L6R-{y9pF#`ه[G 8MV媃 SPWQd$1 "DP)h &NRUh'X6J@˺a$UhA! 3,fu"iqX*(/1PQU UDfCݣH L?l SprS?4K,$R:ZiLllJaj!:-T߱m?S3#`0F#`@ɕb,3[h ]N„N$3C`X1@0LzmkNpaW9oF`6?k{ѯ/'Ի>@Ma Xd͂`w`@#`8;8|ss $Q J1` #&$42x3.,򥏌 A~$ OA4"y֕TKL( :±0$ 0P>EHBL^. /GKݲPŸ|]A%ؐ*=8xcԼ\έ1#7+F``忖yuƵmc|_ #(UgF`8&//ȧb:e΍0FÏ[z5jBWUzq$R`5tE%塃7y9rS2$?jhV@ [( @g,'M!p ?G у+qEYUTR@)xMT"8OpB=ȑdgQG;"y֓ MR}&3р6@N?OJY!HW-F`A̯W[f_pO\$zyuy߂ѹE9mw{bwz]DO+-'cS0F'8( f#Y,0bꈀ2+ .ty(.Zĩ&xd/ġ6e0!1ʨadWs]к{c#~TY )C[,#9S^ޔ.hkOD)탼NU섪(t? OGE#`0F# orJX\ޕ8k: BaGcc,:HL0F`~?h8o >';gЂug}\ooo#dj忺29 xC[9m?6ށ/)d@FɕuX+c _xhk3%#`0F@7&S=8(c8X\b9V -xFyu9iBR0A9<{@M_O(}4F#`0F`q]47{ȑS kZɑup,!pu8] 9Ar0>_Շ 3G_=L7:rK_ қB32VD_8e0F bhص]v+~*Jm#`X(+6A!(SHqRz0XDa ``^+J>e8 >KfSW_H% r(s%U?q MexZ?H<V*Q2=$Q?/Mk/ 3ɗ2)2? iķ*+:R@ZWOC8&\e? f~r>#`0F#`̓V wm#O)[ֈ1hq, ?X#mڲ8{7'^r?mF`T_=4[X{#3Pȇ5_(:emF#Ѓ,as#`0Fi+ُ9! `UarR9F\DP+Et+E4(jɗ> J|TMn.dڳ. 1 ùJK/"G)1 2.3_DHB3H[E#2vd?f ZY´W}ć%Bu(P*7h?t)+ًvhj@IDATْө(A1?*t eQ*)M[sRUDŽ;=%#`0F#`nm+k|il^cd 9HE0At_, ?8opk&r*&ee0N; XVNi6m! yti"n1#pv{GhN@#`8+=ymfUL"itRpxP|< UGRճzlFʇ7JMT{Jrts4EtV> ~Sz1z9f1q, !Omga!LJ:Z!P"Te:˜JGqH#[ ZJFlȟآ'v@"ųēHLJόaJPP:h6Y[mӟ6y`0F#`X*K5}wP1G92i9BKk/sߒw8)wߊ!/\xä>U.9S?R5p?l;~ ;z'#@Zml{VÅ/n^0kk0Fu wڪ#.z-rՃR&U#_tX(ya4_|j$X9Z:HuT [ )"v[JQ~+ =+0.J$i 9Uy+9llwEP0'htAD|4v|ڃ f+zA 6DVEȝjphRtQRZ@.C'=5)Rs,G8DAEIxfcA*u(a8??s0F#`0F`I8oIΫU߻VFCG 8QIXnCw93MW7X+3D@m M sjPZ!}l)Yk?gs+[9+ܶuCD^e*DC%"ƶ%oc4\6F#`Nο c# :mSQAb@WAc |4O3l-ʔ+X>5 L4#@mڏErL2*F/@tSpG* ʼNdM80EC, ͤyUy ✐G ) DfNR$6My5;ۦ#`0F#dd_ Oqak(1c\#nIE{Wx >iF8g :oWV fw}zΔXHaqnk^?7e#\fkCq%"߳::pF#`ًo6;8Gam2[1?-%7M^b"ӣ1m/2'5"AXփ Zp WW/*<5B?,KyCˇi5_>A=Xйį"L'J{QfOOt Uv/%5.h0F#`0F`Y8oY魕39bЊhhp_, }KfjVb)rf bNF`[5qp1L.ǀbX"GoGD_ [^ <\Ī0Fmyul|0j OqU U@֠)S0T8A&M$,ȗ hY@aD&!b"`5HZ QWl) SHt/JR.!hdlD=y2U=xU'(=&`3He>Y:?d'#`0F#`rprMW+͍xWcT+q$^z]ٻ%~ڈ؉V-b C߰Uqb c9A; ^o`mFpItLG7Ƿư:I^Ae] Wh6" lgM>m K tTr:&]AB%ۂGqԋV~[ @'#`0F#`@=w44,iS- 9*s|-KU^#VhVkog^oh8ug`ʓUo[p97[_l;U6 P]F,O?XH87F#`vhGmŶ N#p["hc͘≰A6<xP`!GL(0RHC@'w?]T:UiNO.MRF#`0F"P+mch#^wjlQ'Z463Zh3!s,_қyE=9'?M1 mU#dfQ }}Ӎm`:-Zo=VC;\ȹ#Elisp Pp2F#`v.k+Wy$UW$T3L|@hTXHR/Si02-%:dwʦc|L]yNH3yRd'Pr cc;u'-͓?VC)Cdf<S~i/jσ,vCK) wiԏ0F#`0KCG+_mk7VV,NS࿯V<56X5Vs<>E#pa+r VtZCx忍k wH͛}wWF` ovs7B*Wz> Ε?"2?-*ِ0F#mX=/60襡d,0CF. r,=sp( (XMu1 2":JҡTU2h|r@( [il$S_xaG |/FY]˞?&90F#`0E`/, +} |>ZFeg\d F`IW[4'K98&-+<)C_]q_O۩2TXwB?t}Րud\0[%_%1F#`=mO"Yj b0Z? xm8ȯ2X΀3G.2A/RQY`/Յh5J`VR%( W0GnldPڑЌ4D[Q$- b#`0F#\6  Ǽh؇E"1V_\mg}B#`ܶy1r[b5 6{lu%JbQn#pR `࿓rT{avCWxSF @#y9Mgör 0F͞ }Šn ת60F{X2藕"N(ID1EY8тXtJgW<[gB_YD#.2t!O`l 2NS !ѱ8(e(]v(HlE˨F=myZ!remDAO. 0F#`X*w$V4EW+81ư1mks@q2KBW@s?- ߣ`2bCWhh?gsp,R+!i;FF]࿅tD'00F#C@[q] A0X~HHȰQgPX*m  7A >W$)<Gd[tUҐn*B*"9JHemR#xID%|(-Ky< I# Đe UW(@f'#`0F#`ɽw29oW_m;5dİqL+ F`)u{|3kD%!0WO'3ovV uTLްJ#p|vRPp n1F#`v*{W,%#5Ɓgjf%@"+m(W+F -h&*oi!<8"NBz43o . y2)@6,}W+8e 0"o`7JQr_l} W4>M7Oa!(Z6|_9F ߟ,1Fx?}L7F#`v4=mrxYmK~!,,ĄEXA wv <PČ0@m:qPEU= P4]~׊wF3Y6pSo2 w,HSPP`/**hsB&噳vY-Uij٥g‡*<+b} ;#`0F#`+!hډp+~9$M+54dcߗ^&YOVh4o5m.kW{lrscu4OjWy F` GmvOm .a?< gOr{-/<xoی0F9"zb0L#N0h-4&>rVd4zh :2'|Qr +Pv:%VZP>)`DL mGe@A<)T* ԣIO! e2g>'t $&Xovf0F#`X"Fmnm+x*o5 !F9LLs#p6 7;rSfXɕy1,.%#=XItmW ;zPo:D嫄W ^oa=`EFة@'10F#Sؽ76jC1P8܋ʑ"hhRHa(B+A<,)iEc>C(0륝)(Pp_BBT(xGye綿bD8N5Rfm0lqn-NU؃mqӫ_囀3o 2&!m uqa mB~öXأAs#5Tߑ3kuo?#`0FX pͮz"Ŋ-Fr^IȈ6\)0I.zRIc@iE35PJWтAyf!P AUij $HA cfq4&”^bH7:?{tMlmp;#`0F#`@;v4`ö^o-@FB^=Pl+H iuB>uP$V .&e"K.XŶ[$öÓf7Dz$W^vzAR΍X푻kd#`0g#{m 2I }zC"̖+ݱ g9p(_:Jd>an&HI#3A؁AW(JYAMD1HJ&MeT:Ca (#`0F#`>47%w Pƨ6p8P8"p?l}_L uCT7(jC%`}fh?]Z.V}n009EmEm[`/Xxr}՘)東_B¹0F#`N]紣mܗp`4>L #< r1Eې%=x- +ALɃ:U/(2ma lgӈ#JyS UVwJiV?|4 Ѧv0u܂̖) >.r?Jo~~?ܚFh0F#`+ 8oh-j<1vڪPei k4=[}֎-S࿎" =+mL*k0uF\7KD`v.H]wxjq-鳞Ve }X/*Ev#`0FlD`ew}i{2=-haSz`35(J`PZM8[QQduHΆ^Al Qf]Ƞ?IJyN:ɗ I9:l`Sbe68E1$< mj$M6?9C0F#`0F`a`}k߭m[:- H bxY!gk`zx7 r kl\υ=\@k?-6]$V^WYdu# ;%w~;ps#`0F kS=e}@`!L^͕P/4 d.|Jq-ЦܲfIBhPuv(.:TP`eU㘺88*d)`$($`!EuMgQGQtNH'S?nn0F#`X.sb|};\;H{;0&DB^_tem gF`y oc忣aD^m_7??hBYz?"`$ ߢ+ˊp/f+-A}_;X-:]bSW+XH87F#`"+V DŽdkrf0! v0P2*),@B8!#B ^dTo5@E9 ETa> "OQP1@^ .wو仞Bhe'sJ}DMyaw?ڮ]#`0F#`+v1a@+b@fRŘ^&QF,a_ t+Զ^uQ7}QØc1'W+/mo࿱Z< VS!+x F`k]oD#/pxKo>kنV ;.#`0O#+m6{+FN0ǃu!r25 #RiIt8r< mTORK 0)ԕNU ]#0[  "mҒL3iep _Gb8ԉ@6(@q^SA" #af›MGߊ>#`0F#`@CЋ-$WOpX'S09sk2A`XHNӌ֎#e"p?(7M^6X*Zs9 mmɃFȞrl5K:zI ࿏׎Dnv|yTP`Q2C6la)ZJIāR.,{zQ#G(ZJ%(Ƒ^ڧxh, 6F!6 SO#Bɳ )O'] @ɫu_#`0F#`@(ֶ}3Ɓ}!ƥ;F3H, +-' hn^uM0B`.cEs_-࿺c`ܠ29L0KB`.6/x9oF#`8cwH]Zۢ VÛŨve@BS =; tQLC18XI d!>WhʐSoY[6Y6k)d*~wg%J9҉ﭰ ;T,j_6:wI0F#`0Aj8oP2!rkX.l/MqKA,m)[d?X8f}>-nyBcQy ]σꯛ"#$xWqwqq0F#` -?ڡeB_>#eV#@CzUhP 7ĩ'";9h|ax ²(X Oſ!l T6R2Pك=6V>CE/Ct∓\d'/u~{b#`0F#*fǶ^XD࿿|;.Tg>TCV4D'q,ݩm5_s5wHR| +4'D{? {w=X* $'Y}}`v_V-NWT B<n❅6T#$ K;wcd#`0FWܲAG,9"뙁m5DPܐ IXTl\ڠl^/4 y`#c`Vz8О|QF ,?vKv@CsQG)JauqMR>驁MhomJs#`0F#`rxK{{kXc1mט9DБ@?d>|WCpnim ER:u/<~7e ^ zo +^3l4࿍nmO]'f.#`0F3A`uCxlǠ9Q&ʘcG%rB6S ]P(auCFh8uPH6U~8o峘?h?l&- H"(Gu&8&U'Soߡ;(&fh0F#`X6 MfGe ØW[(~8uX2*/kc4r9/m2#0F瘳k+3)ꆧڦGm F`Tm$t5o+- ö=}A>V࿎ F`K4/,mOIe6#`0F1m7dMIXF? dR'*Stpo"Qݲ2ȳe8`2☔zUm:OB,? lC'S?1o'G#`0F#`}|6mw׶*PkQ1E{,2F`&o_53*oy1̸!D?:o׌ P59tył_" nrXU2؞<뒶rbdr8n_l~-׷/YgYt0FƷFSpp9 hIz5HAq8@xgN09qvzEToNQhvėuI΍BLH_1 }0y@~ڀA7M7}3#}j IC b7F~didm%J${8EJই$$@RElQ-=VU}Yh}2"###޼7"wϱ= @ %ߴX&-=$50yV燚g+4fo7!# <5UIa{svQ @ :OY%џZ/PiE).w\%"x6]_5"]q &ϧ'Zk>ԔSB^ aTM\1˂Obnv륬vUP~,fuJ͂_^ne&0Tٞ*L_g*;; r~v'*`uN}dw}O~4~ӱK @ @`X? |f<{>udO+]+?,2bT'ǟH…jx5a_x#3gz枯qqLȁ:_yD|;".kڷG._Au؅@'{չ. %@ TB@-@Zlj[f%H{|_vi?OdUGTXTF%n.z* ɥaE S).Ӿʩ~Oئ["s=*bAsta;>ɜ @^6p[LwͳTW.hW,ߓUAO/wAI78nv,it>p׀oWD@u?=@z2zgx^Z,%8 Kkח*MǣeJw Gdž&jq@IDATVCIE @`>pj? Yf٨ U1 &|'V^{yje_Ź0TmlU,S':^<=;s4:5f'ZQ[:W_L][>Kըrvge-O=6 @'o?46s:Boftu#Mo3HAU dw"Z]Z`H~]FJz0HB`9do_c,U?'S mxX"~ATlI L3fnXמ3!@@}}J~1nc]vR($E~|N'lKYO[-e%BPu,yv=*۟,u9u]:# .X9rQ]=]vӪ-_P)4t%@ @@7 X Zl=z-y/@A/]5u746@`9B'KGj @#SKOK٩&y ,̛jAC/8Ks9rF^$ۍ6YI Ϗ|͐_͵rN uoYyݿIf`ntvm^_@t|;?W @ X  y69Szm@Ch!0?kEgWEl.ϳ jn~_Eo7p;>'B"n%1,@_WRoĽ銍ե\ @xsϦSڮf>ryk6suU=t劊H/Qa(sB3R}1'h\AۊJ5u'*1^G+}GS{,vK%}OK&>iS'(Ҫk™ @H]?CKb|- ielg8{/ttgA{Ҽ>1Y'1Y > T-򹹼/谅'e/&rW?Ov @  F`h?H /ꓧ[*m5=,!s8l 0YOn$bQTݸGӥ_#z {! _k? Tiø YOe=P\>LwJ"@`h}N%nEn@X'A Ch'joKiHz{O[-9r%b0K2U.x^6|ͩzK{]?UZa}U[קv\ԆyoGW.4i"5?}_C @ 7*wߟ>yΘdcF. 1#n%4vMwD.]h/2ŕҽwEgڿ?tu̙OQK*J%#lw!;(w΃~ HwgΝn?unn+'c @`85auK㼭,*WaQ82Os1KY}OaYЏ|]Q%Ivܦ_ki>toΎck&NXG,X_H} @&of-^fe-m\pmϝE[dcSDgިp,@`P= Q/v.3K0w@n|}_@M}evF-zOX@̔ x]4K1JCଉ+#Z @>p_j7Mb/Yg{ ﲌ;;GW5seJb廈Oqi3<?\ԶVW1(Ԗ_0yqR2K_ @@go5CQ-q]8S1Zվ)UT_[W8Y]M?۝F> OneO;:afXa" 1VW),UE?~QY=4[ ",L'SKLyx T$7h,e{-nџPSTb^-VrvkSҮף:iQr}:I.:_)б-SΌ(5|胳Z[1,TOQo75qwYP:7_={XsU73,\e,0:E/t(E@$y '抛PL7:Sݍߎ  L`&?=9Hw'oKߋOT @xOf˼9uzק\\knlڝrN, ,9sUD{ *ZΉU;6zÑ>9䃣|$ @ 0,pJRfC!V$/ߛtsܲ/P+\UA`/BRc,m~=#sethnHC`_Z8ͭ)UoW}_{Y!z/ ;fT~zNp\]0 b@ p)ɻR FOX?)y?/$1`蕢%ay^DT-te+=կS-l{Z5̮U.6QZu;5Q]5i+M; @ojn}d3,&9[yآ2EvۮooA`?F=no/:@$Lo!2OmiV?w]Gh/%,! bꝠ2L`^gn}X߾~t*@/ @o ݙ_Ԍ(/,@O;q&^#urXFγ.Sh/9V䜥r̕{j9N/U?a0_en? B?v,5oRvb@ @`p<_=6/Q?,eu!k?l5vKZBi!slIjox 0z,e[vuwLi=x+ BuyHM >0F`⿻n各$0'+k>7=[hNM_FF@ 0oK>coJl]}]&QR\ߺ%>K"9sb\un8Ksq;#_Y`'+k& ,&stmqf0*D @ 0<fj9CjE{ھ!lF~*Mտ!>bOn)7sV5ݚ:Gu;SsDW 00g~6.7iBwXvT9 6Xƈx6]x<6)9֧/_XK7{?,'N @``{oM/nj8s] OB9_5Wr'6U |\J_Ir/ QrF‹r);Ev-MVJ2C^%D.e/ 1o'jVktVK{~xLTF#^fp뿖QTH @ @`X!2IiVO&M_ڼԑ|?TLYq[&P#г:p?լ7!::L!p@=QC@Q-[/WAme_!RH fOA8{4n$o_~W|Gpū:g&[(~RmYw?)?T @ @0_#Y+-}i6,C?_pls>T!m*s&.g:tZ*v ξXJ&kw @'Rڼ.b_2e: Z[P}C&koA`@w;;{xiY_ /-5X8 UYO_t葛mn.b M@'{emO,7]Z(.i9/.1OD:zC @2oN6J}X9Kn7Q>'@P{V./a^ ;miܼvW|9g%\phe'Rw]' @ @,iR#_-DGs˂㚃"~/X .t،=XK,-baChy.&osKO|ZޭExӳ\ F`^g͖ ,^Uﴉ4). c-a@nxOJL8b_DB¾XhXnIuWF]V~c\W)g)۷}WWlfn2[lM{; @ ,@_=*o?hn衛C^ y.:9忂x唞x,n=r;oU⿪7 I=7])q,i(2,k~L؇ Ǐ?xU?,d߹-Qz؟/AۏR 5uA 7@w҉Uj 0ҰRe)b@Y!`'5/B\O<ץ+6Bz҉i[һ]A @@'ln⿇xm2pGE_ܲC 7i6&iz==:?*|7OZ_q(j3?_,\7Ɔ>ƈ^u פ?q΀<6Mˆ8Dw0۞NgGso%cO+~M3  @2!ΛR?Hd[`pyH 1`(^)?볃>IjLnȩe ,`՗ϵ'S[M @ASc)o`>_0Ѳ:J{b @uO,Ç>CNQlI_WF& ےA3_*|W* u}؃#n߅_uYF&Nw$9:H[nnסܔN\5ouA K"bGN'qtB<^X Xd>YG2>_izUh{z`P%tN.eٹYHXܦiͨy?6EpC- @ a6 l3 B _q-VՃK㍍">$X"Oj p>|':aFlMY1 m03gEL-`ꇬ:Ͱm#  @r#p;4`~iy5AcV $,9O.3,SZ"RNˇUr$o2$lLؘv@ @ oS_Wfn!cBFZG@`@N4+&{_E*¤* L}G)9wH2 }ܼ!THC`xaosk<1nßY3]=_ccnS,O4 @\~Dϖmdqonyu(HEDYܷR\rr-TnLs};  @XK\8O?Kb~UsMKN$йt5+X6Qp>&q ;fKbo@'{Qsyld ~&(z~6P:ǩemuW`I@ pY~?ԕ $c̘D~9~V*g +-|>GJw܆JB @⿡ {a/ 9a<8n{HB` &kwB~dvkXM_jjϜ_)sWjN 8JC$k⿨eN=@O$T!pn8_bv'%u-ك9BᨕoWq'm:` @ ؟TyY{@AlA bxaŁ*S (RCVj?RYs|ߧtu@ @@78b5yn:f/,Q9_XDB`r>xxu32n+",6_tz{^(QU O*U9w7/>lYƌy˖eɄXųgsVy̎#JXn,1 @ 0ҩv\ZF3_Q!N(f9*5D:r*CKΕw}jk!@ @Xˠ܉?5|^=-'P6SMiVWc bG 1>;p5upA 0EZҳ8_u!*ke֍,E1 @8 6'PHKfKYClPRT.Ysi;}*S]E@ߚ-^ٷiu kLD|}Y̧g[?A#Q DUA!bsSb@ ,+ϧͮfe-m|![̘ty$G y~Zc~rgG,?a!@`X&KO<:6t?I,/D!0O1S-}ыr_ R [ fo$S@bIwYٖ^, b@ p\l jhOb>%OAKoibE\5蘟\*P%W]1[MxH @ =XJ& S{W^fMM7˔ ) Gw!p,.nO[1A 0(RhL7A7;.ïe_{I7^I@`H;_w_7*:^,ж޺qMuWWw!@ pYM'6AepʄOgqv@UR[ޒ^JoA @ %0,z]$2kL1Bq*75OD1 P@׸_ix,*N'+1_ˍ"!08Oܣ5YZA #Vt5B`'.{sp;V\9w@o|כ1}EQ@ p8ey]"k}&D~1 PCN{Z.c8jGʆ`0Oc5mc @GXӂFA^ni5A $߭ 8@_~pv#_)n@xmD؇$kLŔFXKW>lOh}cjU~_i Noh/;m/޵o (C K䔉E@}04&݂)% Pid諾1q} @%N7_On}2X1Yz3n.)Sn5A`+n\ bu ^=ݟEĄ<^Eo_i,@Ur{ U/|reAiqB^fltpjDZ_trPBP @\i 5׾7 Fn@j=VQO{9eu @ ,c-sg`;1n&7!H'QhubiH [3_/[D!43ϥdqT,GScCNwM7O4'0/=3pT7#} g,bޘong @6[P%,GEA:xJ]2*H @ EL_4kisUt?9`1X7Ic'+-%@,UO%ؑ@W6z2}mu,%SE@ 0#_,/@)>5lOhR׿=[A @ e(ZYE*,{J,|W> @ȭiyȱy?|j~)I0H @ =Դ?"VB'ZX HטO#  ^WOFj$]9yHA`8_{6fnBYQsW:- &O;nz-TlO ^F/*H';3-Uz:uz 'C #B?'VJYLLI @ ex1yZ?de]eΖ?[E0a<]I{Ss˞_oݘYeh)z_XL` ݃/(C`B'Yy07,?AÎ#汢 ؃$;邉dOs5ω|\8bٸj( @ @ @&<\t_c-EKpYsYiO6C5YO⿍=C4y$뜹5{'/ K܁"=$!3ϥ)gh+ii<1A. pۚO_s?tnea,96Xm_<#w{_bo^nƜoJ3CFC @ @.In_BEԼO% E%®ݓ L-#F nE>Ntlʲ-_Amm?Y׺?{"a/uBqy#}lXHn84p+_y2NF{Q.ҷWB=Wc @ @ @$WEY5\{kܳ//jArW"y# [pwXL5bV;?1a%hM~zVOhm5z5oAd/z?^`yO͑C  L ,M%1Qs{2]{1,U忳&:Ë[`i@ @ @t_N}]WL-fL.|_v?AϋG]iڦ@&\@¦zտq3R饕CJ_A}9Գ9Z]AW_}OC2h[I@ nemށm-r˶%SX @ @ @o(WOo$Yq[l+SSMiqWM_5BNAdOui|bOX*MOM')\WnކE_ H:E܄`E ep߷N/ͅc./]j!6Ϟ9 gy%>˰#  @ @ pipHڼIߪgG_ג[(?%? @`8/5%!&,yhc팭:K"ʮ>~7 K& _c? /Iqhuv?5`NF%|cnz'$,7ix$*Ng$5/.}_+7B@( @ @ @xc tneO+{e _廲/ [pGWNP -nD{0768^ׯ-+[wĉ~AW⿬DN=忚wE;u$io4n1' o?6y\o ϙeH)YkWa(?  @ @ X:n+ߐn Ѯ_܋ 0G@nM.T=w8^E7Ǩjk鍵>t * Wws_{Er.΍aBp߷Jӗ^kLn89(򟅶TnEn[ @ @ @%PM`?]:0߭*@Y4=CT'/}5gPx%wQ(iY_DdY](6jO=a!&&Љ^,`jR2nTCDO{7ZAػ'$!@ @ @`L@OLKB`?5qsk@`ws?/:q&kWB=inlp?{qiX/81 @ @ @`):SoNћkixmK8 \' $Prj؃i,*hkV߮(_ skզA>VGWfP#v pvC!?ЄRBw:ESۭtyI,^ @ @ pD_cM,\OFW'p{WfP/wFr[J|05=1!o@%Yk_X]rksk+X=:O1!PgT\u5}t /[5M}wÒ.J[@ @ @$ˮte_U2T%?YD_U^տ# O_c"S}c}@6]')Zn_A&Gom?EevY@Q @ @ @_k|⿇q[S{S8Կ!X *@$k{$nVGq{P[/}5g~0 mlOX Y@+f\Xjl&="UA`wtO,i𒒋> D_2lV>~a'췔~QKo# @ @ @ \tBՄ݉ΙO!8lE5r!P@Xx4U\O#ӑ[C8! GGW)B`1_۹#Fq/f-dmΕ%@;KڱgA @ @j"@Wt'n vml#?wkDWo4)_K$ OMKߺ7_]ojpՓmX}{_n&UeotB$!43Gud&=Ɠ]Lg=}g{D!"uPHfg/? !5i6]{uk2,I!@ @ 5&/M%z),! u,bZ-|-b dw\-"1 W~/bc_ =H䡏 xAZ [4o (dA`83߫H8gQ5? y/?!,KwMb/n)1 @ @ 35<ڞnqy;][h- n?Xۂ&YLgO?-2cnNWAo%*DY_ݩ9TK _z9o)?/b:~zi @؅B>N E}o_U{o7cO4 @ @ @5&%Z0ntf?uS(Cx /}W6 Ð< A ? :7/),U?Uwh p8B7-,kұ,U}*> @ @Q#Кod#O…W^Hg۸7Pb[ J]f/-6b81F g$b) re)C?oMj/8HC @ @ H7Fon=**ep3^0_'R9Z]K>Q>OK?ep[&P H 1$QPv#tl[#mxEf/¬O_["  @ @ 55|eokVȝ"-]rzTg1"ЉrkA.Vd_Rg-IwZKdb⿻Rs;PVkVUE Ab?~ӎx}j_4 0 ]_fy{H?2;"\Aa @ @z:5/+ox*.X̍t4K/C`0.$_YQ?քw;-[5o+*A`Pa?RuKMib񬧼K;]ą  D`N7{DxUnW{X=ol)i/:j.@ @ @tih^,!{/uP?v{+W{Ssj@go'sf _GA`aOO> 6,MOoPL?Bnx%TD`Neo'j;Y~zBWb{Ø>GGD0n:1 @ @ vZu:JNwaѭ["ZP+]]QJX$Y =~*nArWk_3H}]|YE#B%x>U忙O}>QwAN[ Oz*M_|m1s8t?Y+sk1BIǯ˺.  @ @Ao^U/he=߇߃Nw/e!hI_YC!P@gOn׬H忚?N[~Y<} B`x}_RwGx>_3q.) KTz,QDWLgWQNg Я>2?}g,g@ @ @N,},5fm0\EWcN۹`YQ)v 0z-![׿\s}(-i5ouA`Oz:o--{}%}P(Os?Ui$ó]aKzĞW{AxT4 @ @n$3̖ms6lR;rWZ̰_iT&Љ.r&+izW,se֮f8HA`I$Kاi,Y4Ixj,?O)A[/C`)$;msB=wߗg忞OBhq? @ @2}OaD';W5mZqE (!PO5#*h*nbnZo:KY)|l=#o`rLaj}U.Sz$V=3z{qsb  N #ixdz'O&k_Qi'__yg.~rG_L`0HC @ @8Ln۩+*<̹Sy7m\oO(CxwR?{e53ߙ0ڒaw A`^C~?ޕ$ K\ ی⿺]GS[,m_o*Vƶ7]Iro{i,?'S-4{C;@s @ @ @h/Mm_iOAg/vގo;B0_P&oҡ實lvݵĥs_B؅0nnT5_f% X'ϙQӈ>jB+/tQsB `Q @ @ @8L7~NI,QrX1zyx)>\L`+ ⿋A.-} WZq[kAZ_89ál@')O$'\!ܡ[c~_G&qgB[ nRV߀n忸1 @ @ D'_^h_j".E:/7!HH#7Hԋo:[D.Z?o".1+ .+$@`xg󆤭"=&'+"jg)5uA`wa5'  @ @5>^\\K=k@`)߱/jc-f(D^KiފA A b?s+QK7]u!0y! ?i*B26U>sE]hj2_w掛^ AȖL/*+v#ۊT]tJnFkj;', b@ @ @G!,-_Uyk/ŬlAaގꝠ2L 틯L?Oa/ӨV醉iQ9:qԂ2| @ @ @hCfw.n}|[_,\h1C؏߾YsM߾N'ϩS0Q^r(w,[@`pİpլb6xxj'fsMכO M|2IϠ_4o}/~3MϘŠniZet5W61 @ @ po$&w#mVoE7@Dn' F`[߃ia.g UHZͪ 0ΰ_y. J[wx>pGzRc?Jr+,Nz\[?忚7([ [ u]f}>4  @ @.K&KE;.˯F|}_,bEb B`G񟹜%T!L7=sӸ٭]/\_f5u.YyA%ڧϞMi+iiEដtil~E2+*b96X y2־WũEm1VPnw.` @ @ ː@q;*nvպ;He.jZ۲y mu-.xQ?:N_͛A]؅@XǰQd.yX>JW[ 'iCpkfSX;_[,|+\忠mp[4 @ @ &'PrA(Ż-_ϒ}:!P{OfWVrZCLhk;nѪ?$xLRLZz WzY{/vaozz&R ]*,"+bA 5O'D~֞ƄxpMwsC^/-tr #^l"Έ @ @<dy߾,Bjϟ_fojncW`oL9׊_esX6y! _c"lVJ|Wӫ=߬ wk.xn3: 0<M]7 Ͼ/ScWϓpZ^C}>`Q @ @%Kn%[GWWX3JC` 'չH{l_FS&~S%)/|-eY۰%T2!0yҳ n+^EJ7w}`p8 @ @%FॿK3oy=//{D!asXް+ ^FIXC`@` bOc<# _X/q&/⿺7 0LgKwxX Zx0n@ @ @ i"Hom:ff/R.m!!pxfo`jo:sƏmJBS3ce51ZQ,{_mYw- uA`g 췞JomxG8K37ˡ)/F~c,gB @ @xc \ө.:G= LK;7ߝqBJ_;V!ojX%~oi?;r  (ST *0vv#Ab_d߇ӱ2.H1/Wsw^ =0Flj @ @@=cZ5ԬN5sHB+?gM]+z_jr;DCL׆&?X;4Ջ*aO =Ҿk⿄忋x! O0%A"⿠Q/^t5_E>L~\tn1'pOMfYCW+ժonh ,ͳ9\@ @ @oPa{ռYԺV'ۖ,oٺ9[s!5 H=sڬ{ˏ>.e\-*D&LHC`$k}ΟK=zԧH2.HxX:Ciď_"ERgEsXFݤ,!{+Im @ @% ߳fO?{q忌fsZUXȈxU @؅+*؜*4_Y/0k9eޕEICȖj -eǣށHw_,տ!mHw[OK͕@7͛N/Fj"g!mv VQ  A @ @ @R'?U ṣҶ]EBF4CP!0Kn_M /F$y+  Գ`O8Op7#nY@` Bop3YDGn2_JwU_QkQ|_@ @ @oJ}_YuR{իeãX^ױR_"pDۢ4Yք.5^0/qIK ߶|Xh;]hME HwO*;36oV^We/_T34  @ @\Xj8_}НY0Pi"/ZbB'Z K-=nQ%OnE7ގzA -H@b,M>@O6x%wSe/!Eg8 z$5X/C @ @8_V={8NndR{^JZ+﷡/hC`8wj^6'GWJNtj+b潠.F}Sco7j?nTmyβ 453Grz2SN&kK˽מ-:F=mZ݂!J @ @jZZowsᾨ,neW‹ *NO/HzM۬w'f93~zt\"96@`$kM>zD۶&[MW?U>(;c3?Q @`iB7-YDWtΔys sc{C ߍkDx1r @ @ -t?YӺXe\˷ZRh4}9vE9M@/DXJg-q[,lO%\octS}2Xә$cw/^fQ}aQ࿦FzGJ <@o_<}@,{V={>JP[3i:HY8A)! $XYk~_;տ>/ž0ZU~_ R'_}!ke;G9݁R`4J+ߌjDA @ @X:zsroDQjeOʢ`sYv/|A u?,!c Yz%n+UiNϺ::/#Ss*v!0YnYZ3\>Ԟ>F~Z W #//ZMr{WvX#p @ @ td*^"%^LwujVV8AD!0yjFn/jB/9g$31uqZhKk(x -H@?Y,6k'UaoZ:&D׻5oZBҴX ៿Ц_;!@ @  CtkwO?5_,^._Ur>1I`&6+fgoErꗿٳ.kϓO>[_Ż@UOϧ\`,GxJ(+˨ύ~P;yݕ- P@Z)[ױ?Q'bHտ>`Q @ @ L7zԴ(⮋_Re/JRYJ,1!0/S_,.kwVrNn=B{YoK">nO?{7Ɋ*7vfAץ33ހ24(^F<#gFDqJEƯ rkg}"bRUYI] ;%#2ߨ+㭵_>p#B7N5C ?Y狮E:rknX8&hMaۚdHrY| pi @ @@Kߙt<ﭖOZ??ʰ `]gB}!oNlC`\oZ߭=ES-MjKCEy9^ *W>P|,ŗsK1oW7 zq ['o E̟@#)ߨXpc_ KkǤW^E8톇uHG߆GW@2 @ @ p H{6q!AE$ub@E؆6` Ll]I՟Rc&r㤮l5H@`a\:W\\hԵuDx4i#4F;W#1P"QԶ7L?'?.@ @ @ǒ@O_R-W'a:oBD](L7BgBxs WrI[JkJ*&nS9sEwB`G‹4JIyjbt"O%@Oi;%iF8俈?ӆWDOD?cZ @ @ 0L\z4k4?֐C俙Sv%`_@Ӭ'Hif5VaJ.mvB  "俗󵪫 6W< GVD^m#uIQ 4ߟK> GQOuOx7D#mw>~ZK5 @ @ ]OߠDw?8{ a/!Do!? 7L{߿H[E%ͩ튴5F`B֞CVZ[&_$Qa4H'ډZm7D#o)]0`m%݁Q]a?tx  @ @ %U?Mdo?^ɺ/"ͣSNIu-,E&n?m֛kP9&`߯^#j;Dgk?\> . >.?FʳM8P`"-"[Xr @ @ #J#Ѵ߰n&\!W#@`>uVO[om\ 8s[Mnѵc/T7u)W:VW;iI2`#?,j؎@YΑ'm}),mmTn_S Q-I;pp @ @ @G1_zZ8俒] 6To*L ̈́o''aO,=[(e PڌSB<"W"OWdm_fTˣ^>mGOeX qF-r<_.FkBxmߊK%h]EqR @ @ W͹- D#ʱ&'W 7Es')`/ BMIHH^nBcB'K-ݵʾu? !0.ٕh @ @ '"E?Sn=/VLQ?)ߌ{"快&)ͯZ,\Mnl M P+ʌ8MrY[bWG[p>B+ :/v`C߹݋v(G>-nT&w{@)` @ @ CL@ߋYېhqt6߇irǰrr D9係H'VՍ'HKӹi)&M2b P&EED=i Bٳ-h<.Ce ҡvKDg(?~pBU]D<}+ @ @ H;?_hmNX3!`K7M8.@v]Vˤ-[w-_./=z?'hc]!QիZV FS'!;Fv#e -{h_ ekҴm3yڔw.T7XCs& /JnD\/8uO[[쿜w6oI"uW-_N𴿃W7hY)G @ @ H  MR(~A,L"u^CXBz`c//ղ|B}wZՌc1t[خJä;mi&F@[nK"(A`\S?-2u3V?!)wCQVY_*$bJEK: @ @   $=nY{\jx@ @ ,Bpo/y܈2R%!,(A`n\/Iu՚w_ e,@W]6W?'):ńND.Sk ^P =PtH?in1!m\ᦿ8fy%x@;@ @ 0 O[[4YR<-5)/ḱ@+TCԢp>Ḷ~`ҭ;w.T7|{ 0]O-HDڸx!DikKo!m`OlEڎ UA`w]{vE."eO;b34UԠmUrߝa㧋*9Xzj @ @ @ \.)e@M 9-R?K;b$SҨ׮Ք:lnZ??`H 7^֨ު"(=Ibq<4I3RODNJvuA`WH]w/ iY4 o:,"ڮC @ @ !iդq7nXN#iŃs&$_q1V*}0~iߍW+'$=L]M Wg#~q}E0VFEɀ3I1s&f&0*B]XM߫udsS,8g7m"@ @ @ cCM&1R'.4.IEB "0$yVYݒkIe't#xZ .k5G+N#&>Z\hF'o_!  D`w@o#5_"ݤq|_I|{@ @ |]AZp߰If_V+e$oC;φTO`J$Tt"]J56c_.tvѰBgN@ WuuWpI.fBCE/F_zLo΀;7i=>(._$c! @ @ W18OEs.4?Mr@M؆@BxPE/."mk1+)8ꎓRC7fS!? /W6Oe_%oPOr^0}Q@mD Ы@`7*w<McZǢ42ڸ Irpk""^  @ @ Pz1y|| E }L`<~: y0TK7QDI{6I@+_mRkב~8__ΠFB/_0&ߕc?0َ3lޱ&y Q|}y٤Qdc?Ԋmd:T!*A<\ū @ @I@/.ڗO=‡9&rmIݒӾvE?at]+a 9zE[4eŵ%!@ϯM]"=po/P_7lc,Yݎw2xw@#Kc_ K'c_/ljԶFUX9w S@<>}; @ @v" yy保"}p1EܭYf.nq3,_MG̉@/]jD+N#4. *k<X6/w.T75 ЍPcM`(_T=2t`׷Ju@` S`1Oѵ>? < v*o  @ @#u{("{ahQ%m'" 0OIsV,bFV,Z$\kcoO4X PԸX_7b?OE~}Ӂ@b]@ET4Q۩xXI;ә;{A @ @؝&ؕl^qd8oE[b)B@޿*jBO^,F7n _ o#B`8o,_aڣ46㡵%q[ն=sNg'$,X_ׯ27W~7 jKD9_miz!oޠFlO`XK&/#4(Zmͽ*,#ѕn "͡G-6v=HZo'R@WSE>w-'!:H;w r?=_#~HO[_jcb{D55PJw@1mNAA+S?~b7g"vrWT{  @ @ p4rNwR߁EӜypoϻcS Ob۔=,0Ac3=Z"śݠG俒俧-8'P{q$6  @ @&.NZ&Պţ:Ms9 +̇@#ra NB=UKqa_ᾠ:F+\]=ݰxjP#c%89tx_wϴyO,_sڸBSLw=K/C#by$a=Jp @ @#*=}^X#_vo?֔E$7i]mܳ|YR?}@_\z>1a@g{ZūL#&` Zvny%{!h,rM%[0@w/Q| %7*D؆ @ @!OoKid'{?O rGR9o dwP EUKAͶtݚng:0(B`A[g8n0.)ڕFt+֤-TwRjxMZ_保XJ{1 RD92떵e (LAS@@ @ @s$uŖIe" !0F`4]1/YvJ5MT24D^\ 7Z^<P:\Ңc)Fw5B`w`?_4.iYOBbeZxL: @ @ cE`w"}F?M^hʢ;4CNK係AU%t Z^ -7Ff{$W:{>r7#5G aݍ#NK{B1 @C4VaTi=׫FkV8qٰD_z0 @ @ pLdOF"dch}kѴlYE^n}) /w.TKL9)7俐#%,icFV>Vt*S(Cs$iN_ҦqeOo~ϘCo΃H<-)΃ @ @>mo`IA_v:Mc4QjN$l; 0@3O.P!ovxW-M`S,rKQ _@?Od/]qXqq%lJ?aa\ H.h@KfC- >Eq0n0MOQd7P"P?~Z<ׯH"MnO'u#9gUGX~m'9:  H忁񚴋R/͓ |5GqOW64>ڱ^/,3I0'D.N @ @$俅t;ߤ5J:NIo0HkB,dM߻9_[OjOS$@?RonƴDs&!0.uP""%e ;&o Nޱy5Cs֓?^Եd^?N"E6<C@ @ @M-Z8y$WKwק0_]ǔW_}-_G A )iWwLak+#>M۞2Cu߹W; ;pO'} vDݴ~}D!jB&ON@ χZi}Z!(YS+1?6OC @ @@#)[!%%׮ƉDvt,#D?"Md5Δ7yyMVi>υ \V@#)N}a2i(C`&`o7ȸ};6Bz}w%"m#{"@=d@ @ @&)R|9Z87C̈́ "$!|x-ElQ<jHhm_ #a C..N?F.{qL쎆& ik,@~Z@Cbo:!FΓ!䴿W#/}dL?G !WoˤfpVH3 @ @b oY_Y_ٵhG ;2E)4ۤ[#"a $YhjŒ&uU_,ڸyƗCـB<$ŘGL=/_.pojDd%m{V#_qC؊D qpώgB @ @ $#I]k; x@M"LCoJeUE̟P&-;{F̉R- @ @ Pzcב*\\l"EK>XFH 3Tc'o}ZK#(yt>gf- >IjQf;7틀W S@ S&EG?gT+ݲDeH4@ @ 샀UW/בqbP+='.|uv0 @+q*?=r>M(+,@LjFej5C+ qcávCy俒@]ؕ/</[]rX<9p/Fjا -ۑa *UB @ @3j3R{7J oӌ/iX &:O/#M^̓@.|}QH[Gq1^.uLO޽k  Q ͝vW?z݁Q@^ l @ @ vAN7-p4$!> 陞X[:HWNg 6n -_/OÙs LT /]˥Sg@`F_oc-G 3Bn?? v;e"Lwg)!9ߜA[c}>6zq`̯/`HD\$mڂ @ @v&<EG  4(YZ{? wXOP o>T3O`Ͼl+ZUְ購fI# K~>6}Io%%_FSCxU&U5NvH[7{1 ,b |kj{Wp:q,@ @ @`wZq¾`'_q7,iM-tZ?yX.WxP!R俟0R|R}T>w.%"vbߤnEEXi#ITK^\t! G.[Ԟ_Nh俜]}L>zWG@@gB @ @"šڑp𴿒|] &:6WH?P &Ok$&iߎ_vdy:TE" y$7V䲁W?_Meg~mkW^-K2Nmײ(UÍ+[θ8 G#8ִ@ @ L"忧HZg M5۾]g3$ P77 o>c_7iwcS#X S QkE&[] !_Q:;F}a s=j\Wߛ[=n9尴yrZ8eIWMNG(άq[Yϝ =# >"x @ @LxI_Gz!o [AL5ϦB`@Cܳ#*($phMZ俊3OZ/ 6%w?#Ւ yput9$0xx?Ҳ_A+:455& Xn"@+ T_% @ @ DWi:q2|9S<%ЕQ ڲMũ$MhߴyZ 01?EIy$oq{z c?A؉@~ۜ?J譙~ p#ymJ*7"`%U~Og ̙GS[IIM俲=`j{}Lm"I["_Π}X׳x @ @ HU7mE"/*ljf@ĉ^?`\ MWhbZo̵T Liw~Zx9o~k"&]d_񴿵$rtxVud!0w.ڞ!oQm?hkFg俢}@e@!5@ @ @{ P H=TEs KZ8qfԿ&w=>_gT P,򟮹dY*"oi vUA`:&&i]Nc8Y/(?ߎ'"!5X(@`wP~ u!Vq\D+Kgisn:7E` @ @  I4 {O%QoRJ"p(A`Nb?D\ⴑ#B̏@G{$=ŸV<]ԭk=*nZrTc,:x+mgKο5*~_aa廴FiL @ @@h"wu:i`l'&K.v<~廄!xzMdV+m )!H%X FvEpe{`Ĵy2&? N@ڡV+ECbI bn;(SK?d['Wbr nEA @ @hh?}k=?N>_1i_<1係@UD@_ҳv=a-C"M} Qh"w(U" O+ }2.] {>M#V{N;+_F+ȾGica>Fy @ @ @HxKE[#_Nv<&>17nC낡 9.=cޟMgi׿J俒֞OYϞ Sf{!,\Gۍ?~m팂k۩rtdFh $$Vk#67 tӝv[udPR3 @ @7__]r &G俒?.Z_,tI`yE EZY?俄cBW)@`^KB]A=_-blIMr^&M=BL O] OK.`} ?m i#wK{пTCm9@J@ @ {^h_<- k8E0^OaOoh[ Uk&K6BD+ut;7C保p P_E#_Qw#uo <xwP!%0$Ei'E@th 'G7tpH @ @&`_"IE_;Y׍gF?m7P؉@Ю?N{l8_6#m#E /f-"՝"\ä-#'ʉtZ% nKH+4,XF{Ϯr8s+ai^Qoh׌}tvo&`}X uB @ @0ik,Y6/_.J#<t "uPo>GKiZYƜZ=~զiml ms$;-$Oi5jX?/{1oވ2?:;(]VJß,_t7ny>4MWB!@ @ p d/~g{$okkY3y 6+]"!P@.VVH[u#]qX70Au@+VW=B)M{G]itԶ볟@,@YӅhKo俯/(׭?w߷p !"x: @ @ K#E¾GOi%T5<\F.ԦB+ H ZD> 68R76!_XZKIVMF+J忁fO &sy$(1M呲3n"9ևҡ{ż`@ @ @`x뷡m2`-JvԶܘƭ͓D+ < -U俉fP{?}VZZAB E׌OD+7dOUHعEl5D! . ogn9_5u.|o{Ce`@ @ UiQ c*Y]]>P@`\%^D+μ\IuGF; 77̃-,@mM _ˣD#)ov)ͽ:JLM`(_vAƴI;5)Nto#f ))C/!@ @ p WY?>!$V+m t@ ѴjY'{޲qP] ae4ׁA"`_kt"=B係}з7hXC`!"颴K{ AX8ZgdDF֡&@C}x@ @ |4O_/W3ZOF14o] ',+aBWy+8:z>>h:gυjB؎6Oi}s_?'Rbi=Lh[ġ~"۔r8C俩9Nshx{{U8ݡ۩8~9ċ @ @"Б4/{&h' ]_u_ U?IJ| %1$Hm{Oc_'0F6 ׌s BN&4ҏ;'Cuקm | HqPs95.TJuN㠯'G俉Xy C @ @`LwjCivC5ׯYőrn[·:MY *!P@WSB}lcǸa(G6\-QSwӱzt>w.>S`)]!+aQ"e(EV.)o{(W?@`ZQ{0p/?1rX<9mU 7*ħo"v~sw@ @ 0G߹n#IN6e7?ڌ;7!0o>KXIpQ U#mΡYe-[[-\S? 5NZE  #Dk[쭮Po;)D`<i (Ly2J`(?.ȔWcu |:;uߓQ#X<zGm. @ @ e"$oQҋV3f8|_ю2L Ut"M56Nx'7h X"I#"j~pOi0}yKe5ul/b"_biW$ą>uBGN_N @ @ 0Es%6Wp_;r^|6S5F*B?'Ql#tWS&Y>ϒXGP P?^Q_W#MoSx;@ @ R$y_}qJߖ%W?d_5@SHs&}ܹZb8IM?Eca򾡲7?pOd0RA @ @`?b ޹MթkgQI[p[G#)jXLCa߅hj~/,wABx@<̻ @ @\"=~N](_C}]itf1|6#ȏiVo   ZݚQLW_)ҵgBB.)'Fӥ/$$6I.ZtE@tF@p~x5G+e7/( }yM;W/p '^% @ @J@_Ekzř7m%rZˉ2CbY 7q@IDATS ">&}̳7  *nK+/G&l>woWfH(r.{%Ԗ{!͹@WQרo6n?> |T&l_  Nj"uw @ @ qz-T/?>N86Αw4߇g2N] ߶IC8τv$Pj#^5y?G "志Defon;5Կ0;?z-!m|F0$=[׬ #6;JRo^ @ @ G[IK:Nux_|63kL덏#ME ,b.!nܿwo7@aשP#JGa+t?лS^@HߥV[x#]1/ON}+V{GQY @ @v! /)G^D>7u(՝ȓ })#EL&iqg.YS`!Z?-D#_Q1O<\Kw͖$~*TE 6w6保X1?CcӀ"=6L(_y @ @8닡IF_b-5a_=:"^s%^J7$ʭ.mO+_&NolMݹ O;Vznǭ?Կi_}{E@+)ow&FӸAQ@5Bڢ}qVYO1 @ @q##)+?C*ԎO^xȱ俏xoP! ϛWIˉУ{XHfeNBiYq hN}/(oӒF]biHD+ T) zBN{ˤ^Ni"mY_-0#>ڵBlXA%ز@ @ OoӗpNs SG/N|nWc ̈́o:Huk8W"ٸx4_Π>B`H++aчCscgsxZ.y>2n veS&ߴ9E$RQ_-8&%Ϥߑ?*A俛IDXC!ؠ@ @ M (z{}HS>_:i%` xpx]K6$(=PIW? n~« _T1M'9VզNER]@=F俩6yC3w6RNj-4JHz @ @W_zD"1ϛ$~ֱ͠$b yP:sE+KH.b=R>ci(B`L{"h*d(`F~C$ـ| l/_ K}Ǩas(ѯҎŕs?c[" 'C @ @P*Gӫ_X 'I[3w:s8k%Mn~UP (=u)?tF7eƍmbf_/wF< 1l* @ @ >җ9_QSkſ5Go1]DOB q L"`ԶFi L7.ݰq8ܱZw+wAlC`i @ @ z/??r|YK(A=Bh Ĵ?{6J.W"*Rj#]MC' ~qov|@H,B0~L0E>lhbV .g_ ".)=o=Y#:x*$ʭ%Yu5A`6o4XY俍>l_&^ZU֜.h@`~QڸW:鸎֟+/&G9]'E=  <_vJӺN}ogz{;:Ivte{CH @ @"N8A❶ooxgP!Fi俖ED/Ξ[>mIu?%ʼnW$ē650:JGqB0]=KW F?"i=l'P۱'@c#@ @ F@$ſo+M2"=M=d싀Gk¸8[^!߾hn$}7[#`2[Y\U᳻*_,@+XVmbF+TO9 @ @!!ФoŹ"^w-.-o@@ &(Y4\_eW -Phv#9 8._K"CE/䩕n9nQbzX(}?hEw DR X'A @ @`. Kc›<0O_i򟍋N俒5mK2GcK @ @g5]俙Nzr/)fo|<oV:n(~ Y6Z( 0MxbٺZYE+A'莆~hFH=Auؙ@~?k#wgx{<( t"PG/!A,"Im @ @(B@_PNm嵰vi;Hf.&ipzоfƙ ^Hi%_qʡXAZR[_" 3a &#|kt蛏>L係]SѯWY_@`1ZkvBoV&yN !0#t@ @ &PP,V$Fw:7oֶO}.)7_0 V@qP'v{D+yXڻ/.gn >%k̛@_fz,jazyċ5O*w}&Tw~Ы@`70x*LW$v##uGRM!-8rnK r<  @ @3iMZH;ƍ X$Iyby1` 0/<$}7[ݴ䭂;!uoY!;P?$()[FEC&,@ms$ E+ܽ_ܥoN@!.?"`!T@ @ t4Fub-]Mtxb$O.[U[] H[O> iw!'0_A,!@ @ w՟^ O}a'{g3/&ymn"II .vC,l>7^-[ɰ KwBWePw 2@t)˱ՊEC+Jt#pbwS(O mDkY*%Ga#Q;8NjoA`n_/ZC @ @ʏ FM4"Mn/gE0lŐe.R_?ax_&=iN:i}&m{Yk-"%FGHӿ`Q',X aOWf_I?żcЊix3ZG /`pb".?@ @ @`@L;"H;i_0JFD5J{;f!#v$wu4@}&TLm!Y޶ciji_KeRW#^˾QR(}zK+a,o=ai\pOQѷo/E{~nߟӈQ8_@ @ $WEʎQʹs\SucSy_n&:2 V'Oi kjX꣡NR4i" !E&0&Y{IZwTt%C+?i{ >yQoĶsQoyGxG]|s ,@ @ @'/Mbho>q\o!V$o/a9DkZ1oQ0&f1@D/P#0Q[!t?#>&/kTRVg7=i΄l\ WSf:O̵ EkŁG!0"+ (1E"7_@ @ H"U1O'^^V话R!*-n/Bhx< d/vhWD/u1}vBwB`{۳)y?EϡФ=俒]A]ؑN'u0OE &$@U -Db ypo`tI6]K&_&8؀@ @ 9P俞ml3n$_yn;n 뎴VCwO $I+QKliFF۲Pz۪;'w[J ͋p#k?۷} k,j"[ju9範Hp/E6I2HJ1Ԙ"8h}?{^rn^  @ @,JwZ̓$(L Gj۫Fsc_ۚ3P;_>"LKoZR$08V cH;x =~=$#yt?7RFOUҎ3{H޿zFh ؐ ! 6'<`C8 b8'!91 9y0}oU5h$U^i{/S%}J]}DcL F4G?_XC @ @Ԇ={.Z|c-o Xx -e_â˯&B)C=𴿊+oQ俚=j ? E@;CJ`ic NeOD]-;-ﲥ-"4(C @ @2(4ј{jOSR6W  NtT;&"({!tmb@[ RSŇE_ǑJL!;BZT?俺]S?+^Rd1d"0W?俺AmAw+^d4=ߤ3g@ @ @BïU!ߛ ;&ikF 5W6l" yi5kI(ga$;(C=@nQ[E_?s>$jcb (忲D+<&6 ]K94SﶍOb俧,|)BgNDZI$XC @ @"6E謼%ߓ"V{c/v:$6NTAU'PDy qD5!Ok/%5Gy K`qr%%"& ۠6Dʶ͑pSA쩟gϷw7-WF@' @ @JgK*NՌ .ɩMhlގ )C^9ʳ!qe-op"+*阏Zt@[ R/ܯq$_ˇA`RSDEEKUW+;z ~[w<&`nj @ @LM1KK-*S_ 7'~",)B:W^ A- 5'uOj:vFF'n%_ݮ6JoWDUNIE9CsL!?]6lXX_q&`h|5ٝb?Mx}wv_q W-gGI @ @ 4g:G֣8` ߕsQa*tYj/V~b]俒 e,B0R8hܛX %6!/iZWF[k~s_۱I+R,X$K֞JCٛ/@ @ _*w@oK;~hhKK俙8) 3?^L%Xя~o-*j4a㋟ Í^!0&YEZ}Sr@Kx$TktnQEA؁@t҄#͗A @ @{$0&w87q5B`:?-I @ @L#sj+ѥukE?PEOy sK J[\D/߷'p⭡}! ;@.俺P7vB~B<_8+aU-yꋥa8i?G}$/oY K!@ @ 09 U8eL+ ]@b?1v/A@뷆6b?_ yx@Bh6_JI[cݰqqEI"͋ pPefFC,iP @ @vSyw']dQۄ')/_z!VUʰV]{YZ *[h+ Uxp\ z{{jJW_"z'0&kTbCȧOweڑgř@ i:s]>7+ p5T@ @ p@[Lvjvb)wlcoK@&qcEFwDH:EC 6輐I[7 Z?~W s$ٛ S<oxDÕeK[WӷΥ@ @ boşi݅!P@g|"uW a8XC=h?EC+btEWՋk!o+Dt>+F3׮I"O3["L<@m?۔AO'(@ @ @` )Pz;D6}n'}7NTG W4"F%_E'ATڴѲ֬/ &w1qhd)"m/eOeChΆ DgCxBG1 G>*e_N>#B `' @ @@~1c'>  t4*N{7 {!P+EJWHs zG܆7*΂@5IQK=k_Qg(sN;%-xP 0ݭڢkyQ?]q1ZyܛU=,:@uWVEj$O @ @0Dѥ.4F쀢i !?H忿#oE)ca+޴H@XC`ޖ.͊I.Ds"U]?I)ͯW"/%a3Ί5&E'gZ]5"f-x ^! ;j~ie9OC_ZK3 @ @ 7Sc_'*tZ-B֚Y1/Q#` ~FiW-_M)7-_mk,UnR^P_,f{ oDH"uZc&E?Y"`CW_dTVmRI"lCW信Xov5C @ 0J/7".SD@؄@?qMhV&1/y;?W zLפh{V'$wWn~!ysjp/~!Vhj#O/owPs-,6hO/@ @ p}[l~u"^̭?!-}AF`Bia:=oѕ:W俎%, "Uv_[$1S7!,Ep""U6_+%Oh(3"A`7wΞo0R׀[q @ @$vi#Ek俚hrIiRψe?g=@nW#ZE_Zl-@?_aZk,w/ J[ _|n/S<$}"C̕+j̳6V6/uAiu+r?Y"n߅"6*/I"q2Ǐ-a8Hi_[?]kO()v7A @ }*ۓjE)Kf/M誙T>iw7@mQs!\\;vKڰַpϽ<Hik/J,VWL_E]?y̛t܅W p] FlnV$j{~+y~2oapƜp pm?IKz y/ @ @ G+j8D8WT}:E{!UO%M`pI?F y,Z!zԍd1@[俗r[X.%DP:b<ǡIW3iO]"_I=J#! r?0JqT]7YN@=w#V׋/PX @ @$Y_=k'! 8 Mz_EKjUSyiw GڏXCG;_B]|+.^uHߊQ,¶Fa{[?k‘?[HK_+ ;غF8=K{_['O` @ @]s"!UeOY+IzI=-/֕vV *S._Kl!{-Q6ʹ-(胣w5B`p*"zlCc+#CrGPv!0)8'ÖiسUcZ?*sP俳Qtxt9O(:VN @ @ ti;,~;Fʐ v#V)OlH{_~*L%7K.y$Y+> hۭ hasikwA`G;~Ksiŝ:i k,niuD5NAX"u(AWw? ~bc}"9@' @ @$>hїf"sQ}~Wk^PۚB K_v"B/=@ˌXA`1Yt?i+LpMKuPl@IDATZ!'6,{ñ1n!-h "pҕp俭Bg\c?5R;  @ @7.2j,iN5Bo!c#hhԐK*"9ɰBH;\rٝ}v=Be@ @ o)~"@ߊߨL"q]E{p;-C3Vj #L{t oP iU&%GV*=@%|j5Us*'9GJ76s!~~fm%l>` m"K61ݸYZ G(iK^!#72ϟ_鹖ʃ׵',D񇃪!@ @;5xJ7r;;eA@ϐ@[YFIlVmE@Bk,B0FGK"KTfoqDKU(IE0n!q4"-sh@ Ow)J,{BkgrZH8 ^[;}KOr\q?"~hh @ @g=NK;WV* ۚаN"%$B?.Oq/7ibJ`;qDAA^DʡqϧU/&/ņW?@`^Q{^??fm%l>`ngc?U36MWǗaG7 q/ݿKpkxƈl$XC @ ܸZOz\gĖY_"TMFzpjMKOfgP& iň7 ے~#Mbxۈwp ~bn,ä' ^Ӣ; M)o=ۊʅkǴ&Rfq{w@<֬]{ASǿi !?1h.E+8.xhh ?fG?7 JWcU:Ç@7o $4/ɁE?"p?4T @ @ 3ӭ$}9 S)D@A6"ې L_upR[/3w_h} iK%{hQ:?7Ce? !̱ƓA_ylT#J-f?7Q?}@ @ ph^Gߍ ڧ%Nt؆^%_+")6GW|) 7j[NJ|'oZb5_.5mp!ަ:BK ^!("G# 7?FL@o;jwr$q-!4(C @ $ ~~׹Hmj'4|O}AFW'"mt5Y_a4L˄z$0& 0*oѥ."FDK:blj7MK@_x^kY[ >c?7򟏇T@z3N5B`|4@ @ JWFո7"i\E係$E@gXv *&ԼRGn}k܇W?;&qѮǕհAߝke5>B]}%(x<(ZѻN]áaR{€;!0am#N|vA @ \zp?'Qo-S_ |bZo&A.( iW7e&hgf].#\u-L>V"u(A`pb俇??[‡ ]üqOohDjd~Nn$3!" N@ @ ZO51(jʑڧpr2#M'Yw5!~IUy{-KoّNMLt$mDTZ݉v16kcR7وFEAwA!lҝ _}I{"(򟖑<}K$oZ4 '$#in@ @ *ڴY >0!>$ؾ8A?~| ?6_lչNZ49#V*Nv2v"QwFH[v>~wg" 'q54_$_u]+En u #`F8lH'j @ @@TW[DvgYE/")D &z FSݺ z\ WH|Z?B*/fG.ڸXc7D#&0]+:./1 GY;$z_P!v"p?@' @ @מ{j@QeCiϝZ柢ąVBŸJ 0߆gSҔbJwa1俳3FzjzBiE #0UI[ =.cs62~Dۑ P@~ rC+!gEюԮGBB`ҕp{? [RzrOrMSFio @ dLT(ikr,#^¯> 俟K6Ϟ}po$vuG/ܼ &6&߾NycO_y)bt@ew1לo`Wt8'#[kh=ceW?H; I7op @ @ /瓌axuE_Ff3"%.v .D+P@?g\&W#_BT]E[ "D(BI^<=XL7m6yoUqY #%i#^ (]$!Uhc{ݞܼCETiR_E; N` @ @#_QxS_5 />k\Ĺ^ߕ *@`:&s[3׿Fi7JeE>sbl)eE@)%4*ct/mҍ#T9 t1_ˣV!ONT`,澨nϱBLm~"9d>:  @ @מ4o;FΟZzbhsZYڽef0%Q ZO;E#!97Cog41[D;(z=p9'p8y,_~}c*E_x{|5 3N`-u2Z6}0 7{ Obκ OtiQ9.X0oS' @ @ ]$wp{;NcmgC6|#? gC6]50\G3SH-29iw+s$5D4XA1BEK_v6H[Zb;ܩunj7Pv%0.u$iwE~lB i̙7@ $7UӺ4^@ @ :pܥE;o\ O&U[]4,Oi-a \q;og)戺/Iyhqp]_3/><."U s)墌W+3 tF,7۾vߕ}`{_E,s{!l]dRV }U:XYw<|"".& @ @v&м0| oA77RMT8H~i7C`w3tzowߖE⟽ǻ(۪%p@`a\k+Q E6_Pe{y_ 2'pVtNߊ]cr TYeiOۼB[-}2'Q9 @ @,CŨƱ$}-m+LGI)(jZZ EE)uئE=7uVys'_.E ABWkM0%Oovc<#eN ϚwZLeY[ >WP m0 _n*$WڴZ, (@ @ ,@kc8lx俭7(#i=F`[lcJ艀?E+$}) בjQA$YiSA-io;@G/~Z.LЧ=t5w DTw#٬EJl;?b9jo[YwB`gi_L?vO(ȓ!@ @ p`]?= W'"^MtTh.i떷~P#v E,t=Vv ;e r]}1!_I2z%Bt1ګ,i#:/;}0k:sh?EKر@ @ 3.o>tO;R27JvIGc(WGO]y(D+T*zߑEZ/ZL'=to}ρ@\S<[. 7H^ ԘFDpE60oi\pfowKK}艀s{!.XDwݛpzEIĮ$6 @ @@/?5a±r;KRgIok*}qi&d2w-#Hϥ k~ub#H؍16Z?_+@ ? ik-]Z7k-cc>L]AuI`\  Lz{;忯?$ť=;Sذ b3}x=xSays/7XB @  ߝ/^Uʝ""_5K&kF?5a}) 7{kU\_ۄQ0ow~\~!(?L{)]pmi,_٪M俒eN`ׄANKz]ļ]ʛi;cap [< #(}?GvthaI@<؂ @ @MaTq^Wr.)HyF _ޠFL8Rie_R絔ГqQc__tnC,@+iߊ'oŎ[FD T Dg-|rKww{8c,_œn ֑~?o*"vB#Y#&i!_0S @ @ (=5@UȎU" QIGwb  ,XUY{eѰ<jb$@H[+ 3 DyKtuJU_俙|pnO5wC&L7@`F"g[E>.Zi">J߃1Xl؄@j`$_4iw" @ @$.6|:vN}5\r8u?Mpx:Le,ن@u.4WrHcar֩VW쥹vjtkiG7-n;2=E#G>]IKv֣_9l?o)Ғp؂@ovpL3p @ @`_$x*5Dəor/(_ܝ.4_6-C$Q@eFتJO[)D6ڀJ,sχ˺,-kkC#o~ҽ<#Cs P@/m$1_=!L5?#[WSj:FCYvMu; @ @jh#Z,Z俯5Z#iÛg)$K_@gl-H{B|9.y2JBt#5XC`!\|&7}W!3l>@m1?Bʰ'"ѿ 0n[1*nH{apb=m J`z4H;G's@@ @ 9 z5HKjزy %j}]ɔ@WIOmݝ' ZM 4sl',#-L 葀/k%m i7@A_Lck&쮮"U&fywD΅@MӒo_c6.>BΫ*)FtEXP<B@>Mɮ%]q @ @n/J GE ۞j֤Ѵ)x|'ߞitgcߔ\#`hg[JooyGB,$~9EXR-vVH?;^M#bK=:7!P@ӡ[zK?'RgQ1Z個m@ڸuS $PFf>{ũ @ @ 4w*H! e"m'u=e2U>/9DQN"a #V[S4yF( T!M>Gt$wϑ".xGkr)5wo@m?vY6_*Q֤YL~5.b+$?Q`LFS_px' @ @8;OpE+]vB;WAA$7I6o1j'ڧwOַ/ "PW$#U(}atz~74Z`_ H OX,D(4V,_Mc_~Gy(t/Q?2 >'k~)@`╘w4rCͷ?gA @ L*-c0:5A`7w?]mNb2s7H6D+g·A$atJƯIm(A莿p[ @ @;xa⩱c8le_`Tk^7ʀyq *Lm?YDk]2%f1OKG=y/ړn=h EFÏ7MRtK;zsmpXC`!.Z 'SG$o^Hq/\MھxOW "%Oo%/qX&uA @ C{Q jHQN+}*)H@_g~_>Ѕ?͛GH+Ckm)펰u_y@F?].iOUvB$:P..wRz$_p/ߤ b_俚2貁h_ -QQ@_:O>˯ R# @ @ -?]>WmأSwh 9$@W^ o $ɥ^Ma{,~P#v"P:Eץ/F+?~qu俊@U"WפQ,G:;Fsex}j|4&OڴhooH;=ur* N @ @8l/wO?.)_Z-ۚL޹W37ImE;cAiR~q,0S_Z:оVXF*u3XvΛ!WO_E"w4g]:D[wMDs!;<_פ;鰼I$ΎJW/]!Pn@ @ p("t]]DY:fiGv7b^rE"'?K+/bοt'K0on?!rlI[+ICo3yIZJ/v"_D E?/K]oINTT.yEyx &}%-@~#70"D^KYS< !@ @M@俥O}#c8lH;?E|DZ}W6,l!92d?vot9jA~Kt\T10m[i "`V"?&ĢfbY/w5B` 86 f@N%_s̍(>6@w2o8w}?}"98 @ .M xF@,}JI|qFNўb fp}zsB[?.ʾP&5'J,X , &"U1On,FA1{[! Ht=L2սKW׾Den?i; RI[Hߧ,~3O b2@ @ pc7 _荋cmb*noJ#ast*<_0O\p/׋MiÈ(:T&mjl.HQ8b$J;>#o"Q5]+=VH[  $Kqkzf(Y俭W[") @ @7tiR_([.ۅfWҢ \k/<%_eQ g%H[+ 8ETkECnGw>vDjaWԜpW6XCs֞72Rc{\$@`L;? YV-vڻ]{bN?'N5 @ @8\+D'V?-;ձE{OZyb^Mh~C&`Wd?,i$Lbįne#I#@`ALkT_USq@̅!|0 H[?;)hs?ݿhITzu/XnɃ_1vN9r$G;޽ Vueژw{_[.ѐ'S @ @4e>lc]إEzL8*'3@P@_b?K.(Z .,oĹ(iÆ{ ѰbX&'n%(!0?EiOoDg˱@(VT?b},K$ ˛D.]gr }!@ @ߝJ3t?QW荋E}ۋ{ P@[:J:˱ nNZ]@=维5H=>06?A g΅A xPոD;(K{G \5U|Fh&[@+YC]O,2RK7xV"VOu @ @F!_Ξ!6z$i'1|q@6HK/~> vko4F3V:X=K/;t"է?5&jQ %B`AJ/E5 Uļ쟞u=kG@EM+/.v=xEnJ?'k^e k@ @ p4ZS_>0e/N"~f~8󔆧u ((@7g34|vjXKa9㏅`iZʉmo?PX 8zМy%IxZ V'/o P]U*v&0`.OZ/;Dپצ5/oy0=ap![6&^ )B]+G}k5?5vA`:-߯éz俲fy$俒e,M{9֬'_؟g_N"U * Q{6N,AmJ<*?CǴ'N@ڴezAnL;O2h?D{RY;q, ^!@ @nz^|*~E|g]gu˴t П؍S#"j4ӨT(U.Fl/"# "^Jר]ZEA؉MN۞g#. #0)形Zcr5x`y7'#OB0/.8E98*dX$ wrq/|Z9wmq'O )#^ @ @MN_iC,GG,_}% ɿ}{ş)oJ_xI:t^9[o[w"4W蓀?E;rCxb"m*y俪8 ([C'忲u,n#(Cw)OBxm^ MW:O x^4v76&Ei33/V @ @%?}tRYOn[{@$=\LnSLӵuW=_m~DѹSZ?^cD1_}ZJ,!;LW񳛽DD ]7R'mJ,[#XC @ EEepXXK1OguygoF3E/cuYiBw}Mgf I@Μ?*v Z|nlPu7 L`<,WWco<Fr?5(W^@*46( *XY'h luǏMbT= ;!@ @M@N?m߄^^Eܭ?o;]~"%PB'=6O<F/qtQYse?G!` g 3/;mVeW5"CeC]{yB 0)NkSfpv@@JlF,_INK+OZrr PX @ @MD@SHOr?c'n~+S忱tQnk%׶h'.\ox8$=lh^y7QBRB@`U?ݛhG7=ȃaix DO.W|jo?>wNZ.I[:/Qמ:+򟟌$XC @ R,<`y rNԆ&3ĆGTigh~ؑZXKa9h?%IIvh &&(B`\;c-)]+a㡇H["MhGw8C@Mo45)ZOeYyJS7 Y`e9 '&ik@']*4@z hw7K&}r紿.K!@ @ Ly1򟾋v<@IDATlR-_&_~Q6YŎHF'<\}/kBJ{7sS'.4y8a7mGs9s&(oϮUGH<~_C[;a7z"_?oFF|=|LQNQ恏 d8jvW*~*\$ϗ7b6fi8)k@ @ p7<}ʞDw/b-7wv}}r}r#M_Ļ;?mQwxw}(_ME@/-_=LYst;9F{1P?m#S6翓od_}v*`Ɉ2z#љ ?7a`iWzJ/a$/Oض-}a+ u,(A`ʴ~imVj?=nD_#a/"lIqw=ߛY>+kk+}| KǏgr" @ @uI O?"俲(s;俒 eC'V$Tq9:+!9X Bhn18i^ַDzhƐv"~C#bG1o~>&;&Y+-QEWE"ŸkIWFK__qoYAj>G9/o"4(C @ @J{*>6HGZݹ'@\3s]Fk1*1ح2>6@B:$D">?swNDۉ !ZR(_UQ+Z3vq{{ۙ=h Qi%?C9]ԕ|T4O]ӗKJF5 @ @`< br]^{a{7:u!2on>6?MZ',|*]E~gP#fJLWZ߇pccֻ9Ո ; +FE?5"Ue^)K-&EWD #0=oqA j4j~piS%  @ @F! 不WN(uuKj)92u|7.z6)}'jX5;u<_0(b~ 7B  dO<*f(iw3R 9G}H>G?yמd@`JOeI3oOo<ҡxX>FjW t&6"_<7BI #uxwlT}Fy$XC @ KYKMW$bWP8Ho; vm⢵NǐJC`tq>\g7zWD#]NoKJ4\d=&5T؆@o$LP?-#:sw8m㘨[T^Z >'}?Ed^#էߛO?{)__ k@ @ pi%'Gzd4 o;GA#gl  U:j>CDk7MG Hν?$-G>hMtiL1?}k} @ @`!"0zc|h&H!C(*JUi*h˒r2 (S1;B^{ ɇ}podxIz{y߲4yr<}v n"9.XX6h6}0,m/R>'(Gn*^pIZcD;t =H$u2ߤo08VPo+ojFK-֑T/`G @ @~ 7(Fu-W}}]ӹ]"A GX"B?Re=)-1_d/K6B""c;}Xֵ_5`I2 @ @HNi}qpVWE"ͱN+\M2m\3i^I?35Ukσ-ڟˍmAQ@b?WD'I[}/UQZA`7hWZ't>H+U6'( փ (iI??]w4'qn?cRYK_?  @ @uEOY kJCYv%O#MpaU 0J]yj*bU6[ilqb]"e: /EFGE;N_!$&%Ԏ-D T9לv~rMrYsFYD"탢,g>FΈ5$PMI(4+ۇvoOل @ @ך@􆴿ջWX?ݼEЮWWט.Ci-iW!qrW>rm0PSS~{:خ$kD:q׸D`XA`1$Lh_L]#j[E(Br0E_;M{5; 0@Ϗ-=w[v-C"%_ W/]IoZEj{i>@ @ kC^ IGWrdzvn$#=;~IFKaYC]\򟦍 /}'o~JOm,&mjwt?-mм](/@\ .?LH"&C҂磟n S9O;m\D;$?!|6_Dw0FߪMz ;, oaig͟cIM @ @@ڴ 7GOA.᝖r_2V@+'J[E;gˇ?!=EtۑO & y]3.vnKyf> 1o+])oW#\^q^}rh>skL.Ht q:mi'[H۽([ @ @#M/ep{d\?NsiC;[9#LMI[ yHԤYp7i+vUA`&Fgk1w4m?hj\ o?yOࢧ,ոz:.y??GC}hb_?&oXCWm_E˷&~Ҭ,-ߑ^Ty^p@}M6{CK @ @`>/=J7Yw1&)4Qg2fڙ^]k'{˃!:,_gr]."աֲ}JK jMס2،N`؆@Lz]Y.,ja R++ͣ_oq?O%1@buQX?Ģk*o3_Gv( , @ @7xغO3"0]벜! j61'=Dk;.A1I<3Mv)ʯo~s]7MrC?YC}P'K#YviVWNh%}TVG;1ćWM/L[8iWot C#|?} |b@ @ p ύⳣeqO5i&m~EB m_9ΣzZ*_>C,ߢhroz{;ggO7*{8(,]Hn Wǿ ʷx,GE6S aH )B_m_ 4_8Id[1OZy,MY oYprz%`I2 @ @XRSqZ:NhcK~R#-Ne=˓wI_A@\~v#]!o-6"U lvĢz8 76fWѹ ̖T ` plh;gi?b|YrTVLli O@*ߦH{O")/K.[fs6ZFI @ @"`i9Ӌri $Jm)H=w~C|781Ͼ츄`_ޝ-⳹~h(Be w!~`nLٿ?ECoov|$O!@s6@@$i[0O_V ]Wy`?}9@ @Dgݿ$9;꙾͵G> \t 9 G.,"taϋ@b|4fg4'3+Ii2"#3#>TTķ=96 +N®:z@܍vi֎Ż !y"4awZ$~ޑ}쬸%amM5<`u-U>:W?,{C;U,?~)Tȋ=%"aKOd ,ox0_=p_?(x+ Cf8bڶwXzEe @ @蕀y?@WZ!+|T}vN-+D,YO7a~_e?=~qTNE1ys!vKsPR-o' ;0i7/3w=E7cI#5lz4@tV,ncqHi _ yJ`Ͽ0efa%:k8N{M~~KNڿp?N݌~;<~=@ @  da_}&;u_SF9:0?URLlsn!LAO&[(6n3QGR2G= il<~g=?.h}i|??xt @ @V_TfO5k.ņH^:iI"@wpe8[-"F+<Ͽ6'־Vۉ>OtV_o!@ @@~bZ0q<^ma"0*?t^ҋ>PV$z1T0 R{LQL5? y:P`?mȈ<]~ME]]y@FguWg_ATHk!yK24omי,v˿:+ώZ;a 8hӽOR1 @ @Ǖ@ SMEуN(߇9e杦tXki:/zC7ƆC&GSfl%X_\"5>v7o7J #'KHd7d_O".vX}{b"(jX!o@W %A7/\fm$O>dAWBd\dɕCvi @ @ /5ٟ&l樲x[Quu/iݫC'?_ +Ϻ"_ΠFA+eh_Pr?A$l$RJ? 66'-v׭v!@o'D4ݵO}<}3S"  @ @ .cXOm60"߂Twx6I׫|4 )z$ŧ?yQ?*j;!.r}p'ʙ^<F:e՟Rp,@+{ݚGڌ;̭4$?P}/!_e|ʍDl*lZaܧ*4hOc~[qKQOSQwK @ @8KNODUk(wgM[M {E.r]۳T{5t@`)jTDxd}8iY/CץBpW8 yyC73*.@ /= ƊVyN|tz {vt @ @`^1/۪(°_o^^߈ P @ @Ǐ@/ϧKcV"o?y ^nd o#8Jzv.ox?P H!'O\<%?Qׅ>ޜ:C8!+?=>L6#_%oAOa(BB$zXY<G?z& K< @ @ +9o3~皉?_\UerPZ@'P!sQvQ7@_N"@`\\B=FzD_"" 56_q]~C}U⿮H5/4,'zks9X_'o.8 +gnN  @ @3v&~'0C \2 npM0C$N4釟 -ڰ<L˹鄔XJ`Tr4V翲]1Q&Nk42C R\IԈ0O<翂G=b7vrÈ2,nU_Gߒ=q\b_uA @ p H7͋=Jg۪?C8ן C @ pT:aLf(7YT?]3~QH8Y"-ЊcbKn\߭%*rc_6P;Pw Po.+dC=D@*K*Ad/⿮翮TkU0"+} LƋYG}AxTQN @ i!3z޲ ]Z~{Fj%=lo3Y!+0*]ia)C z3)LgEoaewם_BSo;bIMvb[ǰ]nUmٰGyŒ:7A`N6xC7'֩8Y4o]GYpBS@ @! ^iQ~_^8zCW{hhݦkpo`;MwyӂnJ {0Ȟ$nUuv,oJOvc\10BGY|R翳O +I~_ۿ4cv  [NQw? Ýgu  @ @"0IW!+DZbg7>.(N_&OV7釟+g7w\+l<]DCFOGr7>Vkk_ eܨ0Vp]v/1*B_&Ix⿢%߇{DMmnv2`'Yq}E{ 0l8ڼuuOuo @ @߲Ei6{J z{;K?őv;q/.[?a/jDdB4F'Z\L $cx+ȻE @!C,,;?⿲6;l1alMu-@4kVڱc@ vQgu*ows" < @ @8u妴/n}*xb"`ASVӈFۜȴQEC ߫/8u o5%#j=sފC?ww 蕀'8Sm_X pw*vϑBgIsЙ_yQYlXC|#M'2!sǓ@ @ p [NԦOѾ]wwJ~caM2/k]H Q߄"Q\K)_z{?E<9"RMoO6Kpxp?09t`Q;mJw@?y*Y VHwism5{;)$ E@⿝Lcϩ?9EWzO?4-%gʙ/HC1,@ @G xiju3lrH9'Њ^!WBj ~e⿸>#;()5mpU NbEma5p@jev_Y T:HlGP#=y_i/"[Mn%pIc⿆ H y.<|AW|#۹nCC}eع8^'O( H @ @8~Bm/|*xW@`&[+V/1[̽Oa n-&ߗaIpߛ7{V+:bx_X–dv?GE ǿg_ Y!8nxg, ]2E<*^$&$"ws/d`O[#إA @ cE`?x[^QWxUo7J PFgquc'N^O}ح*vɐ@<<54j}-|[xD-Aae #T1(EإA @ #M ~qNnV6/7׈]II:Q4]3]ox׃67ZN[8^eb| 󶶎pOϝ̜ؔob@_&Y$rAWz'Nп2|]cQ!Un݅翢Ae؃@(l_t?A=}*FU$_L\fB΄_<JeWD_css#Th}A(A؁A @ I zO5Y'_R`׈Y_m ] q/b`~ tjHO$a#*6?b:B_yL`xcB ϶,xbزsQwgCd. W]_df-⿿m-:P*6`Dׂ"%p O=`Oo`fG 8!@ @8R*yW(mE隉fS $E my5as! +ÐE" Y@.?mag<l`1G.̞ 0n_[67 6.o^ۄںd.s6ݗ+@$Wõ_ 7ϩ(o ?Nn-䱮koJpWé?8#D2@ @Vxދ&V L#ЈLGҿ 67Aˣ? %&ѕ>"NC* 6mx(#N~l?o?Pv  @ @_jfؼ;ae.H`o^_Iʩ^T-2d @%o45uŵpoلVSNf1ITwWѭxWC`A8.6׳Qv@ڥ8$$쐹bV?Wr߾ޕ?ض@IDAT$Fh&t ܏qNC'O:;#*⿲]MMn&@ @ pH⿗G^yuTؼY`.ׂ$l_N VOկL| ! &^5o!nӨ}T.."k2d_0_|Mω,(Sm_Vq=PA`i$G] C; ,/Q*5?]sQtS)&Šݍp  @ >QfgK⿸P1CC@7).?Uc(xNwm;](,4~ee|ah)Dpܻ:{SnYcOHW`3b!oNp_7w#K;?*^o/v9/U[F 65zƍ)/RA @ A|ʓv_<^ͧtNٔ"z!0.F'݈vdJ7x0+_<9$R,@ RgF){=ǃEIw r`ۀ]EhlFv616{*7+25VPt4 o pR @ @4?9jTؼ/[sp_}W?:e"1z HF8ʙrN`Tz"01⿃#N@w1K7=EӯsT/7& ߻WP|$&x0)@)=ac-WÉs:b+@`\*yj}5GsR@G Ű$oy< 6D?~4*aG=`QT@ @@)M|QXOW8-tj.$@<_Z^⿇k6 8b\xsVX[HMV/Y?汛'TwYQ# 0@'.7E7ځJ'Oc/Tj77A@?}BMQ= m?Y@.W_VNoY/'Nq' @ @=h#sFQwwWy]a}zxID8@\* +Ϲw%W-E]#({3>\VuQ# 0J y{9ygӞj<\oւG?YEz>F$B d_}j|F\F=!+ ^O>ӈz~VD'xH!,R#+oj1*')F^R9 @ @\Ei 4_d6o' rZ5Dž)M b$xIs%z]<[@JV !^ D- Mϧ=z8g7Q)W:aU }詗+/ +Tt<(1>z6+3碮IOu=tKys-&T?VaIߟ󧓋x+ D,B @ QH⿗ڦmƮZ x= $ݫz뿄w>`z\WMhda"ՍpSdd6=xOxsJX$h7s)ۈ~`aܶ78Jm9,@GϥEW~WGx5綒c`8@\74z9U_yw7x*yS_Ϊv@ @f$0"ӌE}xL6_v.;U;D (H SDQMee#`vQ: V]iaa7iyӡ޶db2yXޤ^k:R,@3W41WB'&*/ˢ_K">ZXZ_ =p8uvI7x6enǿ?3l+x[ @ @F`D/"4Z/olȶܸR,mwZ  xs?5KF9mYC,/B@5؟/_EE?9p{˦]m+)a[8 3g_ Ž ks|4:+8>ջ6_6wښ2 {,{ӏg_DRtzZs!M0Ƃ4DW̕pfT\@ @@&EqKw_Z?enZtFU_<  4?=LaVloָo1$̗pE@afmQ@Wu=5obټkĝ8f 7yf"$XٗB%KTq56/RoFj ~6_ButCnk? ?BϬފ?GR$ay-ki:@|{<~i @ H`$ohaTĩ9_Pq"ۡ< o>h&FA-v4,c-!0$o)o.{,; Ɖd,W@`\'/R_ S)翡y˿k Ȼ`$aˠ?P-x<6n @ @`Q%8IkHcD˓t<_%l|  ^UIDaMfټz$[Iߢ@e؏@+{.щs~9ŽyI?_,"XwB p_{\>W![[%3!G~%s^&/W]\!+_ⴖ=x+~L?{rjxaFC3@8&. @ @$kaywl:4d]WϣmT+鰛"KU&\ !⿈$P տgSK՚}%7kZw}feu(A_ !/{"ngIF6z!fU(D {ɞMOm{YUGh[GHH!QCs= L\g#+⿦3y0eqAt2SoZ @ @Gt=$z% yqrV7(7idur_"Rl?eD?_̝id(@?uR6A6#%zOg>{ ;&UI +zӀr6 0}$'E ,)km_w9g/`J1M'TM78.`h <4]  @ =K/fؼ;aerN 9yKMG5;!0#yZa֌p~߶tW^X⿉X(@o$ KoQJ( Hn8DU1h*;R?{-!0/}gK)8?1?2_? S3Eb#t4X7ˡK @ @8-}w$Ԃx}|IonqqW׳A 4_y/ijE*ݵG 蕀*rV]PF៉RLe%{)qh JϾCtAp7 '-uV\:aLJ~i@w 2x?hR{j/_5 +oA~%NQ=0τ:piÏ5dS_K 0O/0.%Ĭ? yC@xW@ @$vi_.Ֆ-\FmY\֍ C WC#?ÈP ;&ۯz<@W^{NaE?}qUv^X9?|56сyCW&KߏϚٱ'o>6G ^5{IP;y CA% a @ @\y6asNnV6oI&Y*Lo˽^Oؓ.-\ فN&Oz T?N_Y,@R o0nҖ$_~-n+w-@% ߏ_S⿖QO[E*Mx;|`H ZMǩ$Y FA#Kg竵po3[cWsxPZ5s/6m+Z 翷iZXX9w~#MOcB7:y?m=;b JH{+⿐j ڿܒ,62FKI=D kb<6M[~`3Q_MnG}y;Ʉ_)!_ @ @7W?[)t1} -i;_MKZLJ -[5 "@/&N"+ +#GkE} Ci2Md x[ ؈FprllTJwA`O] =j{hk#)^^xiZT{4n_Z@ @" ʛ/'QE^ĈNXټP֛tKFip_(H!?eIlջ_oF7NcG/?d"%{wLBn^"-Dߋaxu;~%Vyϵ?cmmb2L<"+"ef(O5bd%pϽ /?kIVk SϘ]Ԝ\#DEȞ;,j|_q.^EB"]_@؋_gE`0 eml]h}Bx:@ @8ZG&[=pIw&Tg{ ߱;~$ O?m{d.#o!N*Q /UEE  ;fB}o oXߡSN?󰿟'oQ"<*= @ @rM$Sx$<08Aj;M%/&o>&L#=FNW+gF9887ܹEdoltϝa5VY7ߣŹOF,vlűbDhe"$X%AZ {QLFϬ`e9^?H y?TgOA"?=>^EhA&(qd (}??:@ @GF`T^FyGZ. 7qPy>70ぱ;8J@W餺?ׂE@o!e Jn3Ԉ"!vX կ4%E/1)wYge;Cl+ v79r_0KRl/zQ?Ie] (f 90s)" [4 tۧa?;č?I0H#ґ @ @@I h+Oƅ kCi ;I6G߂@UB gSh=Wb%.s_ ubZ=x J jBZ erNxO[(䋹qA77st@`F.%H[p?Nlb HwgB}Y@eYh'vIs; 6S|[A(aw$j5}Wx+BxxW@ @H [v)|ƅ]wc뿆"iǔ@{ a1/t,lb&0Pj4vm -@3}~nx aOaMϣz8/(w[&3|]O5{Wɭb ⿿.)mih'惟_rt @ @Yuq#P<𰿵幹] +Um/` g ]WϷLl¸ $)F`DO]Y;j?3z>S^6P*~?&Vx=<:hsmFn7 ;7gn"-Bo{GvoRG:]oݫQ'mA @ 0'V.!ܗ?զ"m|sE [*BDo]\Edu3~aVo%{'C`Z$c_ շ݅h 47uh_'oQp' cm;-#rc>9 R,yeWG!\Ɔq3(sZ^qX[<ӵ!^ GP5@vqk~H<ݾA @f&o#/tj p,i"-r@,U@y[GWxgᶅ5E-٦E@ `H <j"}.[:mCWJ--U$>Ow"6J?翟6 47Kf8$ak)yZm;-Lv0-"kRD\H$\lI{,@#moG$Q^Eږ8J.Q5<fBW?u@`&]{} ⿙yQ+۱;[#tw#x฾q7 @ @8⿷翬>CW/!^n^Qe1UIwo/r;wÛ{! -|y.8qu3 @ K<fؼ/-ǒIo=^m/b4K<!ІmVMGߖ9Õ-y(xoqy4޴hEo]WmMΎcѽ{)) 3["_H]^z6/W՟agN! <]<ŭ +O\O H f{m?]0E  @ c@";OӢV+wWsuU|_P# $Mg ;NiOvN[6͚|AW5=EVY oRdvz毓7 @ @{+@'ᅦVfl.f6ӈZ. ?{* [[Z΋oWCv=~GKOhjs`v_YIa}0?kCw/ڎ<nM@ @vz5 .]lO"cw79>hUV8_}wƅO,J`T$vX95>NGOw'#1/^ļG/"k1@6,c-H=I4Éo Oi '/%ߝՙSM@?+s??}yKn`b\eٻac;jLVl'x:@ @V~eaGp9O\.hHW#lA/,6 }5{= _F Y +Y&6}_o՟?/uy'o\bDs9̀%Sf&P/Xa%KOfn/4a$vim#]@ؗa9G?/p\*yGɭHLt O4]?a۟q @ @Ha%k1&Ra ZL&l)Ɱ@@G+dh~Ǐw DuZJ#oɢYbn>BLcsF{_nG'lX({VxE=h8un/X:Y1Z% _^w,~_y)o9j^ej[>'W;S :#⿩|"/UD-in߁s#%ښ1 yQ{{f1ƋDU&;Ym!ۗ,@->?R&-zOd 5S'9"ҹ pnd@ @8^ nQ(׊}B`CR:v<%:!_~4g}ߚ翿ZZ8W |6ʦE]Qe@oFVu`F|nśRnB`)'/?= 7{E=,$oisXͦE M"ۋ&&*l-4w46(@ @nIj~y_-S].:N05+.>?a@\zW7V\cUw=.iB C3?B HW!x_=@Vk&rya_±]mFmcѻU!o7z8?I/ _q{KߐPyOF|GP# ߇ϙ 溉NnݣNC`O5ܢ"%,"p!| @ @X>,l䩰y_T}"{s` <*$W #I+q??Q/NЗ-h;Fyp A{8'w*oki)ݏu&K;!O3LjkKg? ՙS/(Nεb.F,x0]׭3~x!P} @ ,@+Sy;m]Аg_];1t"ka@!s({06;he'+iJR9⿖ 9,D=ӏ~`,οV0@$ɍg'n/HePmw F> wv՜#?j /]h8dJop%0C @Fjyyٻ6Oe8iuc"+Ti*Uiӊ=Db ڶ[$pN,#7?P: ?Z'>>=,sEKƄ>i)bO7@#ϿN3F3I߃.LZJӱf#EE%Sy3_.hn w5}Q V@ @T^ _IFK_q.o~_ޠB([5ߗV\HaOC:{p"Y|H?Fw`(߁pyS44fb !:Na퉕(N yQWw5ڢfXE,E`/yC ͗]wl} B\$@ @"Poq)%@_gA 4?=yu1zCW< O ~SE /? ߾ ~hJ jQJ'c/󟠰A`iR|m|=u~yTw5B` ?]kS-P<"۳ ߞ8<.[!@ @}⿷LYtz*lWmwAcx<%ЈTQ~+<-u7VUDq|+J%Hĥ&6ą'uh\FD~D4(zΙ9s߯sL7ws{O3ߞ?,fV1iX! 'oi6O#+I7r$NvLE6ikWñ>~\~i"pi!E D| !+z?uq8w ]~/NϽ,Kx @ @``]l"S1x+i͏\I3 P@O "+Aob__,1G"_#g⿡ "m5w;lH=AiE-860/(:))S7F%oC Oz?0ǘ_?FYy. @ #_Rb/Iqy/D{<㾖76'.(@_0iٺi7nݶ]zK5$1D蛺zp +sSǓi;A1i9B8u!b4o[ѴoHDT"ìTƏRоV!mEƁ"8ݒIzu"սI+8W-C @ML1⿒w7Nиƛ Ka;b!O5].IPϴJzTnz6(qb~^EOKwP?JRG /F L,_{ЉD2W.1wo ⿅xwv?M=$1f@iD+F!@ @ ˱\.L`.'B{HQD/Wx@+;1 )>R$"1p_̖K?AuzKD"кo"i}cܟ;l|"i3:B`xgeӝשA` ʌ@ @8_DQi_/-t19!0 FQd2EzSjF4oҁ/a@%*a:9-.y6U' i5Y(D+G"b=kt:N!U|' L}oxn?i$ϮNa9oWӡT?Z:ut8D`% @ @XD@#JS!uH794i'p!?":aUE,x%Fs ;}W6t=D`|+@ vٙ?wZsD=Ց5_ 4A`0(Ҧ$06ap`CN"?d}2BmLo ɑ\J_+z5 pPc1 @ @3 eNqE:o?Sj@`ND+:=MDOv./ڳBP_E@`3 4ScM:<+J `,@ O+‹4eS`ioH?/*nQhM1#cE@&#ߡ-yvKĖ{g;sFe KmG&@## @ @`ygwwv⿝,Zd t$!0.m%ǟ7 0jN_Y ~! }?E+j-_&>5jpg6E&gR""_;Oi-#j=Jц@S<WxquaY?/F',B`D @  lnO/eq4`qz{iׇJkwȣۈ8 Y?5c ֑[Ri%F@u YGWLG.y@5FRFjM AYE}avDik-;8"oǦ)dzA7.(}An&Epq1 @ @ e8g% Ӹ*+tZtW뼶B @#b.ӞnH"l߾Z acs\D.W? ko VdY6ȏ @ i?p%2eV6G|"XD"t+cOt$"ro3cgBh%oE x}~6_Gat@ @͌SaW`ŋ#YcS@`Htb5 /gE$_,OX)!P~ A template for writing your own middleware is available in the [faraday-adapter-template](https://github.com/lostisland/faraday-adapter-template) repository. Adapters have methods that can help you implement support for a new backend. This example will use a fictional HTTP backend gem called `FlorpHttp`. It doesn't exist. Its only function is to make this example more concrete. ## An Adapter _is_ a Middleware When you subclass `Faraday::Adapter`, you get helpful methods defined and all you need to do is to extend the `call` method (remember to call `super` inside it!): ```ruby module Faraday class Adapter class FlorpHttp < Faraday::Adapter def call(env) super # Perform the request and call `save_response` end end end end ``` Now, there are only two things which are actually mandatory for an adapter middleware to function: - a `#call` implementation - a call to `#save_response` inside `#call`, which will keep the Response around. These are the only two things, the rest of this text is about methods which make the authoring easier. Like any other middleware, the `env` parameter passed to `#call` is an instance of [Faraday::Env][env-object]. This object will contain all the information about the request, as well as the configuration of the connection. Your adapter is expected to deal with SSL and Proxy settings, as well as any other configuration options. ## Connection options and configuration block Users of your adapter have two main ways of configuring it: * connection options: these can be passed to your adapter initializer and are automatically stored into an instance variable `@connection_options`. * configuration block: this can also be provided to your adapter initializer and it's stored into an instance variable `@config_block`. Both of these are automatically managed by `Faraday::Adapter#initialize`, so remember to call it with `super` if you create an `initialize` method in your adapter. You can then use them in your adapter code as you wish, since they're pretty flexible. Below is an example of how they can be used: ```ruby # You can use @connection_options and @config_block in your adapter code class FlorpHttp < Faraday::Adapter def call(env) # `connection` internally calls `build_connection` and yields the result connection do |conn| # perform the request using configured `conn` end end def build_connection(env) conn = FlorpHttp::Client.new(pool_size: @connection_options[:pool_size] || 10) @config_block&.call(conn) conn end end # Then your users can provide them when initializing the connection Faraday.new(...) do |f| # ... # in this example, { pool_size: 5 } will be provided as `connection_options` f.adapter :florp_http, pool_size: 5 do |client| # this block is useful to set properties unique to HTTP clients that are not # manageable through the Faraday API client.some_fancy_florp_http_property = 10 end end ``` ## Implementing `#close` Just like middleware, adapters can implement a `#close` method. It will be called when the connection is closed. In this method, you should close any resources that you opened in `#initialize` or `#call`, like sockets or files. ```ruby class FlorpHttp < Faraday::Adapter def close @socket.close if @socket end end ``` ## Helper methods `Faraday::Adapter` provides some helper methods to make it easier to implement adapters. ### `#save_response` The most important helper method and the only one you're expected to call from your `#call` method. This method is responsible for, among other things, the following: * Take the `env` object and save the response into it. * Set the `:response` key in the `env` object. * Parse headers using `Utils::Headers` and set the `:response_headers` key in the `env` object. * Call `#finish` on the `Response` object, triggering the `#on_complete` callbacks in the middleware stack. ```ruby class FlorpHttp < Faraday::Adapter def call(env) super # Perform the request using FlorpHttp. # Returns a FlorpHttp::Response object. response = FlorpHttp.perform_request(...) save_response(env, response.status, response.body, response.headers, response.reason_phrase) end end ``` `#save_response` also accepts a `finished` keyword argument, which defaults to `true`, but that you can set to false if you don't want it to call `#finish` on the `Response` object. ### `#request_timeout` Most HTTP libraries support different types of timeouts, like `:open_timeout`, `:read_timeout` and `:write_timeout`. Faraday let you set individual values for each of these, as well as a more generic `:timeout` value on the request options. This helper method knows about supported timeout types, and falls back to `:timeout` if they are not set. You can use those when building the options you need for your backend's instantiation. ```ruby class FlorpHttp < Faraday::Adapter def call(env) super # Perform the request using FlorpHttp. # Returns a FlorpHttp::Response object. response = FlorpHttp.perform_request( # ... other options ..., open_timeout: request_timeout(:open, env[:request]), read_timeout: request_timeout(:read, env[:request]), write_timeout: request_timeout(:write, env[:request]) ) # Call save_response end end ``` ## Register your adapter Like middleware, you may register a nickname for your adapter. People can then refer to your adapter with that name when initializing their connection. You do that using `Faraday::Adapter.register_middleware`, like this: ```ruby class FlorpHttp < Faraday::Adapter # ... end Faraday::Adapter.register_middleware(florp_http: FlorpHttp) ``` [env-object]: /getting-started/env-object.md faraday-2.10.0/docs/adapters/custom/parallel-requests.md000066400000000000000000000027071464273144400232540ustar00rootroot00000000000000# Adding support for parallel requests !> This is slightly more involved, and this section is not fully formed. Vague example, excerpted from [the test suite about parallel requests](https://github.com/lostisland/faraday/blob/main/spec/support/shared_examples/request_method.rb#L179) ```ruby response_1 = nil response_2 = nil conn.in_parallel do response_1 = conn.get('/about') response_2 = conn.get('/products') end puts response_1.status puts response_2.status ``` First, in your class definition, you can tell Faraday that your backend supports parallel operation: ```ruby class FlorpHttp < ::Faraday::Adapter dependency do require 'florp_http' end self.supports_parallel = true end ``` Then, implement a method which returns a ParallelManager: ```ruby class FlorpHttp < ::Faraday::Adapter dependency do require 'florp_http' end self.supports_parallel = true def self.setup_parallel_manager(_options = nil) FlorpParallelManager.new # NB: we will need to define this end end class FlorpParallelManager def add(request, method, *args, &block) # Collect the requests end def run # Process the requests end end ``` Compare to the finished example [em-synchrony](https://github.com/lostisland/faraday-em_synchrony/blob/main/lib/faraday/adapter/em_synchrony.rb) and its [ParallelManager implementation](https://github.com/lostisland/faraday-em_synchrony/blob/main/lib/faraday/adapter/em_synchrony/parallel_manager.rb). faraday-2.10.0/docs/adapters/custom/streaming.md000066400000000000000000000063511464273144400215770ustar00rootroot00000000000000# Adding support for streaming Faraday supports streaming responses, which means that the response body is not loaded into memory all at once, but instead it is read in chunks. This can be particularly useful when dealing with large responses. Not all HTTP clients support this, so it is not required for adapters to support it. However, if you do want to support it in your adapter, you can do so by leveraging helpers provided by the env object. Let's see an example implementation first with some comments, and then we'll explain it in more detail: ```ruby module Faraday class Adapter class FlorpHttp < Faraday::Adapter def call(env) super if env.stream_response? # check if the user wants to stream the response # start a streaming response. # on_data is a block that will let users consume the response body http_response = env.stream_response do |&on_data| # perform the request using FlorpHttp # the block will be called for each chunk of data FlorpHttp.perform_request(...) do |chunk| on_data.call(chunk) end end # the body is already consumed by the block # so it's good practice to set it to nil http_response.body = nil else # perform the request normally, no streaming. http_response = FlorpHttp.perform_request(...) end save_response(env, http_response.status, http_response.body, http_response.headers, http_response.reason_phrase) end end end end ``` ## How it works ### `#stream_response?` The first helper method we use is `#stream_response?`. This method is provided by the env object and it returns true if the user wants to stream the response. This is controlled by the presence of an `on_data` callback in the request options. ### `#stream_response` The second helper is `#stream_response`. This method is also provided by the env object and it takes a block. The block will be called with a single argument, which is a callback that the user can use to consume the response body. All your adapter needs to do, is to call this callback with each chunk of data that you receive from the server. The `on_data` callback will internally call the callback provided by the user, so you don't need to worry about that. It will also keep track of the number of bytes that have been read, and pass that information to the user's callback. To see how this all works together, let's see an example of how a user would use this feature: ```ruby # A buffer to store the streamed data streamed = [] conn = Faraday.new('http://httpbingo.org') conn.get('/stream/100') do |req| # Set a callback which will receive tuples of chunk Strings, # the sum of characters received so far, and the response environment. # The latter will allow access to the response status, headers and reason, as well as the request info. req.options.on_data = proc do |chunk, overall_received_bytes, env| puts "Received #{overall_received_bytes} characters" streamed << chunk end end # Joins all response chunks together streamed.join ``` For more details on the user experience, check the [Streaming Responses] page. [Streaming Responses]: /advanced/streaming-responses.md faraday-2.10.0/docs/adapters/custom/testing.md000066400000000000000000000060351464273144400212620ustar00rootroot00000000000000# Test your custom adapter Faraday puts a lot of expectations on adapters, but it also provides you with useful tools to test your adapter against those expectations. This guide will walk you through the process of testing your adapter. ## The adapter test suite Faraday provides a test suite that you can use to test your adapter. The test suite is located in the `spec/external_adapters/faraday_specs_setup.rb`. All you need to do is to `require 'faraday_specs_setup'` in your adapter's `spec_helper.rb` file. This will load the `an adapter` shared example group that you can use to test your adapter. ```ruby require 'faraday_specs_setup' RSpec.describe Faraday::Adapter::FlorpHttp do it_behaves_like 'an adapter' # You can then add any other test specific to this adapter here... end ``` ## Testing optional features By default, `an adapter` will test your adapter against the required behaviour for an adapter. However, there are some optional "features" that your adapter can implement, like parallel requests or streaming. If your adapter implements any of those optional features, you can test it against those extra expectations by calling the `features` method: ```ruby RSpec.describe Faraday::Adapter::MyAdapter do # Since not all adapters support all the features Faraday has to offer, you can use # the `features` method to turn on only the ones you know you can support. features :request_body_on_query_methods, :compression, :streaming # Runs the tests provide by Faraday, according to the features specified above. it_behaves_like 'an adapter' # You can then add any other test specific to this adapter here... end ``` ### Available features | Feature | Description | |----------------------------------|----------------------------------------------------------------------------------------------------------| | `:compression` | Tests that your adapter can handle `gzip` and `deflate` compressions. | | `:local_socket_binding` | Tests that your adapter supports binding to a local socket via the `:bind` request option. | | `:parallel` | Tests that your adapter supports parallel requests. See [Parallel requests][parallel] for more details. | | `:reason_phrase_parse` | Tests that your adapter supports parsing the `reason_phrase` from the response. | | `:request_body_on_query_methods` | Tests that your adapter supports sending a request body on `GET`, `HEAD`, `DELETE` and `TRACE` requests. | | `:streaming` | Tests that your adapter supports streaming responses. See [Streaming][streaming] for more details. | | `:trace_method` | Tests your adapter against the `TRACE` HTTP method. | [streaming]: /adapters/custom/streaming.md [parallel]: /adapters/custom/parallel-requests.md faraday-2.10.0/docs/adapters/index.md000066400000000000000000000032721464273144400174020ustar00rootroot00000000000000# Adapters The Faraday Adapter interface determines how a Faraday request is turned into a Faraday response object. Adapters are typically implemented with common Ruby HTTP clients, but can have custom implementations. Adapters can be configured either globally or per Faraday Connection through the configuration block. For example, consider using `httpclient` as an adapter. Note that [faraday-httpclient](https://github.com/lostisland/faraday-httpclient) must be installed beforehand. If you want to configure it globally, do the following: ```ruby require 'faraday' require 'faraday/httpclient' Faraday.default_adapter = :httpclient ``` If you want to configure it per Faraday Connection, do the following: ```ruby require 'faraday' require 'faraday/httpclient' conn = Faraday.new do |f| f.adapter :httpclient end ``` ## Fantastic adapters and where to find them Except for the default [Net::HTTP][net_http] adapter and the [Test Adapter][testing] adapter, which is for _test purposes only_, adapters are distributed separately from Faraday and need to be manually installed. They are usually available as gems, or bundled with HTTP clients. While most adapters use a common Ruby HTTP client library, adapters can also have completely custom implementations. If you're just getting started you can find a list of featured adapters in [Awesome Faraday][awesome]. Anyone can create a Faraday adapter and distribute it. If you're interested learning more, check how to [build your own][build_adapters]! [testing]: /adapters/test-adapter.md [net_http]: /adapters/net-http.md [awesome]: https://github.com/lostisland/awesome-faraday/#adapters [build_adapters]: /adapters/custom/index.md faraday-2.10.0/docs/adapters/net-http.md000066400000000000000000000010721464273144400200320ustar00rootroot00000000000000# Net::HTTP Adapter Faraday's Net::HTTP adapter is the default adapter. It uses the `Net::HTTP` library that ships with Ruby's standard library. Unless you have a specific reason to use a different adapter, this is probably the adapter you want to use. With the release of Faraday 2.0, the Net::HTTP adapter has been moved into a [separate gem][faraday-net_http], but it has also been added as a dependency of Faraday. That means you can use it without having to install it or require it explicitly. [faraday-net_http]: https://github.com/lostisland/faraday-net_http faraday-2.10.0/docs/adapters/test-adapter.md000066400000000000000000000067601464273144400206750ustar00rootroot00000000000000# Test Adapter The built-in Faraday Test adapter lets you define stubbed HTTP requests. This can be used to mock out network services in an application's unit tests. The easiest way to do this is to create the stubbed requests when initializing a `Faraday::Connection`. Stubbing a request by path yields a block with a `Faraday::Env` object. The stub block expects an Array return value with three values: an Integer HTTP status code, a Hash of key/value headers, and a response body. ```ruby conn = Faraday.new do |builder| builder.adapter :test do |stub| # block returns an array with 3 items: # - Integer response status # - Hash HTTP headers # - String response body stub.get('/ebi') do |env| [ 200, { 'Content-Type': 'text/plain', }, 'shrimp' ] end # test exceptions too stub.get('/boom') do raise Faraday::ConnectionFailed end end end ``` You can define the stubbed requests outside of the test adapter block: ```ruby stubs = Faraday::Adapter::Test::Stubs.new do |stub| stub.get('/tamago') { |env| [200, {}, 'egg'] } end ``` This Stubs instance can be passed to a new Connection: ```ruby conn = Faraday.new do |builder| builder.adapter :test, stubs do |stub| stub.get('/ebi') { |env| [ 200, {}, 'shrimp' ]} end end ``` It's also possible to stub additional requests after the connection has been initialized. This is useful for testing. ```ruby stubs.get('/uni') { |env| [ 200, {}, 'urchin' ]} ``` You can also stub the request body with a string or a proc. It would be useful to pass a proc if it's OK only to check the parts of the request body are passed. ```ruby stubs.post('/kohada', 'where=sea&temperature=24') { |env| [ 200, {}, 'spotted gizzard shad' ]} stubs.post('/anago', -> (request_body) { JSON.parse(request_body).slice('name') == { 'name' => 'Wakamoto' } }) { |env| [200, {}, 'conger eel'] } ``` If you want to stub requests that exactly match a path, parameters, and headers, `strict_mode` would be useful. ```ruby stubs = Faraday::Adapter::Test::Stubs.new(strict_mode: true) do |stub| stub.get('/ikura?nori=true', 'X-Soy-Sauce' => '5ml' ) { |env| [200, {}, 'ikura gunkan maki'] } end ``` This stub expects the connection will be called like this: ```ruby conn.get('/ikura', { nori: 'true' }, { 'X-Soy-Sauce' => '5ml' } ) ``` If there are other parameters or headers included, the Faraday Test adapter will raise `Faraday::Test::Stubs::NotFound`. It also raises the error if the specified parameters (`nori`) or headers (`X-Soy-Sauce`) are omitted. You can also enable `strict_mode` after initializing the connection. In this case, all requests, including ones that have been already stubbed, will be handled in a strict way. ```ruby stubs.strict_mode = true ``` Finally, you can treat your stubs as mocks by verifying that all of the stubbed calls were made. NOTE: this feature is still fairly experimental. It will not verify the order or count of any stub. ```ruby stubs.verify_stubbed_calls ``` After the test case is completed (possibly in an `after` hook), you should clear the default connection to prevent it from being cached between different tests. This allows for each test to have its own set of stubs ```ruby Faraday.default_connection = nil ``` ## Examples Working [RSpec] and [test/unit] examples for a fictional JSON API client are available. [RSpec]: https://github.com/lostisland/faraday/blob/main/examples/client_spec.rb [test/unit]: https://github.com/lostisland/faraday/blob/main/examples/client_test.rb faraday-2.10.0/docs/advanced/000077500000000000000000000000001464273144400157075ustar00rootroot00000000000000faraday-2.10.0/docs/advanced/parallel-requests.md000066400000000000000000000032451464273144400217020ustar00rootroot00000000000000# Parallel Requests Some adapters support running requests in parallel. This can be achieved using the `#in_parallel` method on the connection object. ```ruby # Install the Typhoeus adapter with `gem install faraday-typhoeus` first. require 'faraday/typhoeus' conn = Faraday.new('http://httpbingo.org') do |faraday| faraday.adapter :typhoeus end now = Time.now conn.in_parallel do conn.get('/delay/3') conn.get('/delay/3') end # This should take about 3 seconds, not 6. puts "Time taken: #{Time.now - now}" ``` ## A note on Async You might have heard about [Async] and its native integration with Ruby 3.0. The good news is that you can already use Async with Faraday (thanks to the [async-http-faraday] gem) and this does not require the use of `#in_parallel` to run parallel requests. Instead, you only need to wrap your Faraday code into an Async block: ```ruby # Install the Async adapter with `gem install async-http-faraday` first. require 'async/http/faraday' conn = Faraday.new('http://httpbingo.org') do |faraday| faraday.adapter :async_http end now = Time.now # NOTE: This is not limited to a single connection anymore! # You can run parallel requests spanning multiple connections. Async do Async { conn.get('/delay/3') } Async { conn.get('/delay/3') } end # This should take about 3 seconds, not 6. puts "Time taken: #{Time.now - now}" ``` The big advantage of using Async is that you can now run parallel requests *spanning multiple connections*, whereas the `#in_parallel` method only works for requests that are made through the same connection. [Async]: https://github.com/socketry/async [async-http-faraday]: https://github.com/socketry/async-http-faraday faraday-2.10.0/docs/advanced/streaming-responses.md000066400000000000000000000024551464273144400222470ustar00rootroot00000000000000# Streaming Responses Sometimes you might need to receive a streaming response. You can do this with the `on_data` request option. The `on_data` callback is a receives tuples of chunk Strings, and the total of received bytes so far. This example implements such a callback: ```ruby # A buffer to store the streamed data streamed = [] conn = Faraday.new('http://httpbingo.org') conn.get('/stream/100') do |req| # Set a callback which will receive tuples of chunk Strings, # the sum of characters received so far, and the response environment. # The latter will allow access to the response status, headers and reason, as well as the request info. req.options.on_data = Proc.new do |chunk, overall_received_bytes, env| puts "Received #{overall_received_bytes} characters" streamed << chunk end end # Joins all response chunks together streamed.join ``` The `on_data` streaming is currently only supported by some adapters. To see which ones, please refer to [Awesome Faraday][awesome] comparative table or check the adapter documentation. Moreover, the `env` parameter was only recently added, which means some adapters may only have partial support (i.e. only `chunk` and `overall_received_bytes` will be passed to your block). [awesome]: https://github.com/lostisland/awesome-faraday/#adapters faraday-2.10.0/docs/customization/000077500000000000000000000000001464273144400170525ustar00rootroot00000000000000faraday-2.10.0/docs/customization/connection-options.md000066400000000000000000000052151464273144400232270ustar00rootroot00000000000000# Connection Options When initializing a new Faraday connection with `Faraday.new`, you can pass a hash of options to customize the connection. All these options are optional. | Option | Type | Default | Description | |---------------------|-------------------|-----------------|---------------------------------------------------------------------------------------------------------------| | `:request` | Hash | nil | Hash of request options. Will be use to build [RequestOptions]. | | `:proxy` | URI, String, Hash | nil | Proxy options, either as a URL or as a Hash of [ProxyOptions]. | | `:ssl` | Hash | nil | Hash of SSL options. Will be use to build [SSLOptions]. | | `:url` | URI, String | nil | URI or String base URL. This can also be passed as positional argument. | | `:parallel_manager` | | nil | Default parallel manager to use. This is normally set by the adapter, but you have the option to override it. | | `:params` | Hash | nil | URI query unencoded key/value pairs. | | `:headers` | Hash | nil | Hash of unencoded HTTP header key/value pairs. | | `:builder_class` | Class | RackBuilder | A custom class to use as the middleware stack builder. | | `:builder` | Object | Rackbuilder.new | An instance of a custom class to use as the middleware stack builder. | ## Example ```ruby options = { request: { open_timeout: 5, timeout: 5 }, proxy: { uri: 'https://proxy.com', user: 'proxy_user', password: 'proxy_password' }, ssl: { ca_file: '/path/to/ca_file', ca_path: '/path/to/ca_path', verify: true }, url: 'https://example.com', params: { foo: 'bar' }, headers: { 'X-Api-Key' => 'secret', 'X-Api-Version' => '2' } } conn = Faraday.new(options) do |faraday| # ... end ``` [RequestOptions]: /customization/request-options.md [ProxyOptions]: /customization/proxy-options.md [SSLOptions]: /customization/ssl-options.md faraday-2.10.0/docs/customization/index.md000066400000000000000000000060541464273144400205100ustar00rootroot00000000000000# Configuration Faraday is highly configurable and allows you to customize the way requests are made. This applies to both the connection and the request, but can also cover things like SSL and proxy settings. Below are some examples of how to customize Faraday requests. Configuration can be set up with the connection and/or adjusted per request. As connection options: ```ruby conn = Faraday.new('http://httpbingo.org', request: { timeout: 5 }) conn.get('/ip') ``` Or as per-request options: ```ruby conn.get do |req| req.url '/ip' req.options.timeout = 5 end ``` You can also inject arbitrary data into the request using the `context` option. This will be available in the `env` on all middleware. ```ruby conn.get do |req| req.url '/get' req.options.context = { foo: 'foo', bar: 'bar' } end ``` ## Changing how parameters are serialized Sometimes you need to send the same URL parameter multiple times with different values. This requires manually setting the parameter encoder and can be done on either per-connection or per-request basis. This applies to all HTTP verbs. Per-connection setting: ```ruby conn = Faraday.new request: { params_encoder: Faraday::FlatParamsEncoder } conn.get('', { roll: ['california', 'philadelphia'] }) ``` Per-request setting: ```ruby conn.get do |req| req.options.params_encoder = Faraday::FlatParamsEncoder req.params = { roll: ['california', 'philadelphia'] } end ``` ### Custom serializers You can build your custom encoder, if you like. The value of Faraday `params_encoder` can be any object that responds to: * `#encode(hash) #=> String` * `#decode(string) #=> Hash` The encoder will affect both how Faraday processes query strings and how it serializes POST bodies. The default encoder is `Faraday::NestedParamsEncoder`. ### Order of parameters By default, parameters are sorted by name while being serialized. Since this is really useful to provide better cache management and most servers don't really care about parameters order, this is the default behaviour. However you might find yourself dealing with a server that requires parameters to be in a specific order. When that happens, you can configure the encoder to skip sorting them. This configuration is supported by both the default `Faraday::NestedParamsEncoder` and `Faraday::FlatParamsEncoder`: ```ruby Faraday::NestedParamsEncoder.sort_params = false # or Faraday::FlatParamsEncoder.sort_params = false ``` ## Proxy Faraday will try to automatically infer the proxy settings from your system using [`URI#find_proxy`][ruby-find-proxy]. This will retrieve them from environment variables such as http_proxy, ftp_proxy, no_proxy, etc. If for any reason you want to disable this behaviour, you can do so by setting the global variable `ignore_env_proxy`: ```ruby Faraday.ignore_env_proxy = true ``` You can also specify a custom proxy when initializing the connection: ```ruby conn = Faraday.new('http://www.example.com', proxy: 'http://proxy.com') ``` [ruby-find-proxy]: https://ruby-doc.org/stdlib-2.6.3/libdoc/uri/rdoc/URI/Generic.html#method-i-find_proxy faraday-2.10.0/docs/customization/proxy-options.md000066400000000000000000000016411464273144400222500ustar00rootroot00000000000000# Proxy Options Proxy options can be provided to the connection constructor or set on a per-request basis via [RequestOptions](/customization/request-options.md). All these options are optional. | Option | Type | Default | Description | |-------------|-------------|---------|-----------------| | `:uri` | URI, String | nil | Proxy URL. | | `:user` | String | nil | Proxy user. | | `:password` | String | nil | Proxy password. | ## Example ```ruby # Proxy options can be passed to the connection constructor and will be applied to all requests. proxy_options = { uri: 'http://proxy.example.com:8080', user: 'username', password: 'password' } conn = Faraday.new(proxy: proxy_options) do |faraday| # ... end # You can then override them on a per-request basis. conn.get('/foo') do |req| req.options.proxy.update(uri: 'http://proxy2.example.com:8080') end ``` faraday-2.10.0/docs/customization/request-options.md000066400000000000000000000053601464273144400225610ustar00rootroot00000000000000# Request Options Request options can be provided to the connection constructor or set on a per-request basis. All these options are optional. | Option | Type | Default | Description | |-------------------|-------------------|----------------------------------------------------------------|-------------------------------------------------------------------------| | `:params_encoder` | Class | `Faraday::Utils.nested_params_encoder` (`NestedParamsEncoder`) | A custom class to use as the params encoder. | | `:proxy` | URI, String, Hash | nil | Proxy options, either as a URL or as a Hash of [ProxyOptions]. | | `:bind` | Hash | nil | Hash of bind options. Requires the `:host` and `:port` keys. | | `:timeout` | Integer, Float | nil (adapter default) | The max number of seconds to wait for the request to complete. | | `:open_timeout` | Integer, Float | nil (adapter default) | The max number of seconds to wait for the connection to be established. | | `:read_timeout` | Integer, Float | nil (adapter default) | The max number of seconds to wait for one block to be read. | | `:write_timeout` | Integer, Float | nil (adapter default) | The max number of seconds to wait for one block to be written. | | `:boundary` | String | nil | The boundary string for multipart requests. | | `:context` | Hash | nil | Arbitrary data that you can pass to your request. | | `:on_data` | Proc | nil | A callback that will be called when data is received. See [Streaming] | ## Example ```ruby # Request options can be passed to the connection constructor and will be applied to all requests. request_options = { params_encoder: Faraday::FlatParamsEncoder, timeout: 5 } conn = Faraday.new(request: request_options) do |faraday| # ... end # You can then override them on a per-request basis. conn.get('/foo') do |req| req.options.timeout = 10 end ``` [ProxyOptions]: /customization/proxy-options.md [SSLOptions]: /advanced/streaming-responses.md faraday-2.10.0/docs/customization/ssl-options.md000066400000000000000000000072471464273144400217000ustar00rootroot00000000000000# SSL Options Faraday supports a number of SSL options, which can be provided while initializing the connection. | Option | Type | Default | Description | |--------------------|----------------------------------------|---------|--------------------------------------------------------------------------------------------------------------------------------------------------| | `:verify` | Boolean | true | Verify SSL certificate. Defaults to `true`. | | `:verify_hostname` | Boolean | true | Verify SSL certificate hostname. Defaults to `true`. | | `:ca_file` | String | nil | Path to a CA file in PEM format. | | `:ca_path` | String | nil | Path to a CA directory. | | `:verify_mode` | Integer | nil | Any `OpenSSL::SSL::` constant (see [SSL docs](https://ruby-doc.org/3.2.2/exts/openssl/OpenSSL/SSL.html)). | | `:cert_store` | OpenSSL::X509::Store | nil | OpenSSL certificate store. | | `:client_cert` | OpenSSL::X509::Certificate | nil | Client certificate. | | `:client_key` | OpenSSL::PKey::RSA, OpenSSL::PKey::DSA | nil | Client private key. | | `:certificate` | OpenSSL::X509::Certificate | nil | Certificate (Excon only). | | `:private_key` | OpenSSL::PKey::RSA | nil | Private key (Excon only). | | `:verify_depth` | Integer | nil | Maximum depth for the certificate chain verification. | | `:version` | Integer | nil | SSL version (see [SSL docs](https://ruby-doc.org/3.2.2/exts/openssl/OpenSSL/SSL/SSLContext.html#method-i-ssl_version-3D)). | | `:min_version` | Integer | nil | Minimum SSL version (see [SSL docs](https://ruby-doc.org/3.2.2/exts/openssl/OpenSSL/SSL/SSLContext.html#method-i-min_version-3D)). | | `:max_version` | Integer | nil | Maximum SSL version (see [SSL docs](https://ruby-doc.org/3.2.2/exts/openssl/OpenSSL/SSL/SSLContext.html#method-i-max_version-3D)). | ## Example ```ruby ssl_options = { ca_file: '/path/to/ca_file', min_version: :TLS1_2 } conn = Faraday.new(ssl: options) do |faraday| # ... end ``` faraday-2.10.0/docs/getting-started/000077500000000000000000000000001464273144400172475ustar00rootroot00000000000000faraday-2.10.0/docs/getting-started/env-object.md000066400000000000000000000103761464273144400216340ustar00rootroot00000000000000# The Env Object Inspired by Rack, Faraday uses an `env` object to pass data between middleware. This object is initialized at the beginning of the request and passed down the middleware stack. The adapter is then responsible to run the HTTP request and set the `response` property on the `env` object, which is then passed back up the middleware stack. You can read more about how the `env` object is used in the [Middleware - How it works](/middleware/index?id=how-it-works) section. Because of its nature, the `env` object is a complex structure that holds a lot of information and can therefore be a bit intimidating at first. This page will try to explain the different properties of the `env` object. ## Properties Please also note that these properties are not all available at the same time: while configuration and request properties are available at the beginning of the request, response properties are only available after the request has been performed (i.e. in the `on_complete` callback of middleware). | Property | Type | Request | Response | Description | |---------------------|----------------------------|:------------------:|:------------------:|-----------------------------| | `:method` | `Symbol` | :heavy_check_mark: | :heavy_check_mark: | The HTTP method to use. | | `:request_body` | `String` | :heavy_check_mark: | :heavy_check_mark: | The request body. | | `:url` | `URI` | :heavy_check_mark: | :heavy_check_mark: | The request URL. | | `:request` | `Faraday::RequestOptions` | :heavy_check_mark: | :heavy_check_mark: | The request options. | | `:request_headers` | `Faraday::Utils::Headers` | :heavy_check_mark: | :heavy_check_mark: | The request headers. | | `:ssl` | `Faraday::SSLOptions` | :heavy_check_mark: | :heavy_check_mark: | The SSL options. | | `:parallel_manager` | `Faraday::ParallelManager` | :heavy_check_mark: | :heavy_check_mark: | The parallel manager. | | `:params` | `Hash` | :heavy_check_mark: | :heavy_check_mark: | The request params. | | `:response` | `Faraday::Response` | :x: | :heavy_check_mark: | The response. | | `:response_headers` | `Faraday::Utils::Headers` | :x: | :heavy_check_mark: | The response headers. | | `:status` | `Integer` | :x: | :heavy_check_mark: | The response status code. | | `:reason_phrase` | `String` | :x: | :heavy_check_mark: | The response reason phrase. | | `:response_body` | `String` | :x: | :heavy_check_mark: | The response body. | ## Helpers The `env` object also provides some helper methods to make it easier to work with the properties. | Method | Description | |-------------------------|--------------------------------------------------------------------------------------------------| | `#body`/`#current_body` | Returns the request or response body, based on the presence of `#status`. | | `#success?` | Returns `true` if the response status is in the 2xx range. | | `#needs_body?` | Returns `true` if there's no body yet, and the method is in the set of `Env::MethodsWithBodies`. | | `#clear_body` | Clears the body, if it's present. That includes resetting the `Content-Length` header. | | `#parse_body?` | Returns `true` unless the status indicates otherwise (e.g. 204, 304). | | `#parallel?` | Returns `true` if a parallel manager is available. | | `#stream_response?` | Returns `true` if the `on_data` streaming callback has been provided. | | `#stream_response` | Helper method to implement streaming in adapters. See [Support streaming in your adapter]. | [Support streaming in your adapter]: /adapters/custom/streaming.md faraday-2.10.0/docs/getting-started/errors.md000066400000000000000000000024101464273144400211020ustar00rootroot00000000000000# Dealing with Errors As an abstraction layer between the user and the underlying HTTP library, it's important that Faraday provides a consistent interface for dealing with errors. This is especially important when dealing with multiple adapters, as each adapter may raise different errors. Below is a list of errors that Faraday may raise, and that you should be prepared to handle. | Error | Description | |-----------------------------|--------------------------------------------------------------------------------| | `Faraday::Error` | Base class for all Faraday errors, also used for generic or unexpected errors. | | `Faraday::ConnectionFailed` | Raised when the connection to the remote server failed. | | `Faraday::TimeoutError` | Raised when the connection to the remote server timed out. | | `Faraday::SSLError` | Raised when the connection to the remote server failed due to an SSL error. | If you add the `raise_error` middleware, Faraday will also raise additional errors for 4xx and 5xx responses. You can find the full list of errors in the [raise_error middleware](/middleware/included/raising-errors) page. faraday-2.10.0/docs/getting-started/quick-start.md000066400000000000000000000201671464273144400220460ustar00rootroot00000000000000# Quick Start ## Installation Add this line to your application’s `Gemfile`: ```ruby gem 'faraday' ``` And then execute: ```bash $ bundle ``` Or install it yourself as: ```bash $ gem install faraday ``` ## Usage ### Quick requests Let's fetch the home page for the wonderful [httpbingo.org](https://httpbingo.org) service. You can make a simple `GET` request using `Faraday.get`: ```ruby response = Faraday.get('http://httpbingo.org') ``` This returns a `Faraday::Response` object with the response status, headers, and body. ```ruby response.status # => 200 response.headers # => {"server"=>"Fly/c375678 (2021-04-23)", "content-type"=> ... response.body # => " ... ``` ### Faraday Connection The recommended way to use Faraday, especially when integrating to 3rd party services and APIs, is to create a `Faraday::Connection`. The connection initializer allows you to set: - default request headers & query parameters - network settings like proxy or timeout - common URL base path - Faraday adapter & middleware (see below) Create a `Faraday::Connection` by calling `Faraday.new`. You can then call each HTTP verb (`get`, `post`, ...) on your `Faraday::Connection` to perform a request: ```ruby conn = Faraday.new( url: 'http://httpbingo.org', params: {param: '1'}, headers: {'Content-Type' => 'application/json'} ) response = conn.post('/post') do |req| req.params['limit'] = 100 req.body = {query: 'chunky bacon'}.to_json end # => POST http://httpbingo.org/post?param=1&limit=100 ``` ### GET, HEAD, DELETE, TRACE Faraday supports the following HTTP verbs that typically don't include a request body: - `get(url, params = nil, headers = nil)` - `head(url, params = nil, headers = nil)` - `delete(url, params = nil, headers = nil)` - `trace(url, params = nil, headers = nil)` You can specify URI query parameters and HTTP headers when making a request. ```ruby response = conn.get('get', { boom: 'zap' }, { 'User-Agent' => 'myapp' }) # => GET http://httpbingo.org/get?boom=zap ``` ### POST, PUT, PATCH Faraday also supports HTTP verbs with bodies. Instead of query parameters, these accept a request body: - `post(url, body = nil, headers = nil)` - `put(url, body = nil, headers = nil)` - `patch(url, body = nil, headers = nil)` ```ruby # POST 'application/x-www-form-urlencoded' content response = conn.post('post', 'boom=zap') # POST JSON content response = conn.post('post', '{"boom": "zap"}', "Content-Type" => "application/json") ``` #### Posting Forms Faraday will automatically convert key/value hashes into proper form bodies thanks to the `url_encoded` middleware included in the default connection. ```ruby # POST 'application/x-www-form-urlencoded' content response = conn.post('post', boom: 'zap') # => POST 'boom=zap' to http://httpbingo.org/post ``` ### Detailed HTTP Requests Faraday supports a longer style for making requests. This is handy if you need to change many of the defaults, or if the details of the HTTP request change according to method arguments. Each of the HTTP verb helpers can yield a `Faraday::Request` that can be modified before being sent. This example shows a hypothetical search endpoint that accepts a JSON request body as the actual search query. ```ruby response = conn.post('post') do |req| req.params['limit'] = 100 req.headers['Content-Type'] = 'application/json' req.body = {query: 'chunky bacon'}.to_json end # => POST http://httpbingo.org/post?limit=100 ``` ### Using Middleware Configuring your connection or request with predefined headers and parameters is a good start, but the real power of Faraday comes from its middleware stack. Middleware are classes that allow you to hook into the request/response cycle and modify the request. They can help you with things like: * adding authentication headers * parsing JSON responses * logging requests and responses * raise errors on 4xx and 5xx responses * and much more! For example, let's say you want to call an API that: * requires an authentication token in the `Authorization` header * expects JSON request bodies * returns JSON responses and on top of that, you want to automatically raise errors on 4xx and 5xx responses, as well as log all requests and responses. You can easily achieve all of the above by adding the necessary middleware to your connection: ```ruby conn = Faraday.new(url: 'http://httpbingo.org') do |builder| # Calls MyAuthStorage.get_auth_token on each request to get the auth token # and sets it in the Authorization header with Bearer scheme. builder.request :authorization, 'Bearer', -> { MyAuthStorage.get_auth_token } # Sets the Content-Type header to application/json on each request. # Also, if the request body is a Hash, it will automatically be encoded as JSON. builder.request :json # Parses JSON response bodies. # If the response body is not valid JSON, it will raise a Faraday::ParsingError. builder.response :json # Raises an error on 4xx and 5xx responses. builder.response :raise_error # Logs requests and responses. # By default, it only logs the request method and URL, and the request/response headers. builder.response :logger end # A simple example implementation for MyAuthStorage class MyAuthStorage def self.get_auth_token rand(36 ** 8).to_s(36) end end ``` The connection can now be used to make requests. ```ruby begin response = conn.post('post', { payload: 'this ruby hash will become JSON' }) rescue Faraday::Error => e # You can handle errors here (4xx/5xx responses, timeouts, etc.) puts e.response[:status] puts e.response[:body] end # At this point, you can assume the request was successful puts response.body # I, [2023-06-30T14:27:11.776511 #35368] INFO -- request: POST http://httpbingo.org/post # I, [2023-06-30T14:27:11.776646 #35368] INFO -- request: User-Agent: "Faraday v2.7.8" # Authorization: "Bearer wibzjgyh" # Content-Type: "application/json" # I, [2023-06-30T14:27:12.063897 #35368] INFO -- response: Status 200 # I, [2023-06-30T14:27:12.064260 #35368] INFO -- response: access-control-allow-credentials: "true" # access-control-allow-origin: "*" # content-type: "application/json; encoding=utf-8" # date: "Fri, 30 Jun 2023 13:27:12 GMT" # content-encoding: "gzip" # transfer-encoding: "chunked" # server: "Fly/a0b91024 (2023-06-13)" # via: "1.1 fly.io" # fly-request-id: "01H467RYRHA0YK4TQSZ7HS8ZFT-lhr" # cf-team: "19ae1592b8000003bbaedcf400000001" ``` Faraday ships with a number of useful middleware, and you can also write your own. To learn more about middleware, please check the [Middleware] section. ### Swapping Adapters Faraday does not make HTTP requests itself, but instead relies on a Faraday adapter to do so. By default, it will use the `Net::HTTP` adapter, which is part of the Ruby standard library. Although `Net::HTTP` is the only adapter that ships with Faraday, there are [many other adapters available as separate gems](https://github.com/lostisland/awesome-faraday#adapters). Once you have installed an adapter, you can use it by passing the `adapter` option to `Faraday.new`: ```ruby conn = Faraday.new(url: 'http://httpbingo.org') do |builder| builder.adapter :async_http end ``` To learn more about adapters, including how to write your own, please check the [Adapters] section. ### Default Connection, Default Adapter Remember how we said that Faraday will automatically encode key/value hash bodies into form bodies? Internally, the top level shortcut methods `Faraday.get`, `post`, etc. use a simple default `Faraday::Connection`. The only middleware used for the default connection is `:url_encoded`, which encodes those form hashes, and the `default_adapter`. You can change the default adapter or connection. Be careful because they're set globally. ```ruby Faraday.default_adapter = :async_http # defaults to :net_http # The default connection has only `:url_encoded` middleware. # Note that if you create your own connection with middleware, it won't encode # form bodies unless you too include the :url_encoded middleware! Faraday.default_connection = Faraday.new do |conn| conn.request :url_encoded conn.response :logger conn.adapter Faraday.default_adapter end ``` [Adapters]: /adapters/index.md [Middleware]: /middleware/index.md faraday-2.10.0/docs/index.html000066400000000000000000000115221464273144400161400ustar00rootroot00000000000000 Faraday Docs
faraday-2.10.0/docs/index.md000066400000000000000000000022521464273144400155740ustar00rootroot00000000000000# ![Faraday](_media/home-logo.svg) Faraday is an HTTP client library abstraction layer that provides a common interface over many adapters (such as Net::HTTP) and embraces the concept of Rack middleware when processing the request/response cycle. ## Why use Faraday? Faraday gives you the power of Rack middleware for manipulating HTTP requests and responses, making it easier to build sophisticated API clients or web service libraries that abstract away the details of how HTTP requests are made. Faraday comes with a lot of features out of the box, such as: * Support for multiple adapters (Net::HTTP, Typhoeus, Patron, Excon, HTTPClient, and more) * Persistent connections (keep-alive) * Parallel requests * Automatic response parsing (JSON, XML, YAML) * Customization of the request/response cycle with middleware * Support for streaming responses * Support for uploading files * And much more! ## Who uses Faraday? Faraday is used by many popular Ruby libraries, such as: * [Signet](https://github.com/googleapis/signet) * [Octokit](https://github.com/octokit/octokit.rb) * [Oauth2](https://bestgems.org/gems/oauth2) * [Elasticsearch](https://github.com/elastic/elasticsearch-ruby) faraday-2.10.0/docs/middleware/000077500000000000000000000000001464273144400162575ustar00rootroot00000000000000faraday-2.10.0/docs/middleware/custom-middleware.md000066400000000000000000000060521464273144400222310ustar00rootroot00000000000000# Writing custom middleware !> A template for writing your own middleware is available in the [faraday-middleware-template](https://github.com/lostisland/faraday-middleware-template) repository. The recommended way to write middleware is to make your middleware subclass `Faraday::Middleware`. `Faraday::Middleware` simply expects your subclass to implement two methods: `#on_request(env)` and `#on_complete(env)`. * `#on_request` is called when the request is being built and is given the `env` representing the request. * `#on_complete` is called after the response has been received (that's right, it already supports parallel mode!) and receives the `env` of the response. For both `env` parameters, please refer to the [Env Object](getting-started/env-object.md) page. ```ruby class MyMiddleware < Faraday::Middleware def on_request(env) # do something with the request # env[:request_headers].merge!(...) end def on_complete(env) # do something with the response # env[:response_headers].merge!(...) end end ``` ## Having more control For the majority of middleware, it's not necessary to override the `#call` method. You can instead use `#on_request` and `#on_complete`. However, in some cases you may need to wrap the call in a block, or work around it somehow (think of a begin-rescue, for example). When that happens, then you can override `#call`. When you do so, remember to call either `app.call(env)` or `super` to avoid breaking the middleware stack call! ```ruby def call(request_env) # do something with the request # request_env[:request_headers].merge!(...) @app.call(request_env).on_complete do |response_env| # do something with the response # response_env[:response_headers].merge!(...) end end ``` It's important to do all processing of the response only in the `#on_complete` block. This enables middleware to work in parallel mode where requests are asynchronous. The `request_env` and `response_env` are both [Env Objects](getting-started/env-object.md) but note the amount of information available in each one will differ based on the request/response lifecycle. ## Accepting configuration options `Faraday::Middleware` also allows your middleware to accept configuration options. These are passed in when the middleware is added to the stack, and can be accessed via the `options` getter. ```ruby class MyMiddleware < Faraday::Middleware def on_request(_env) # access the foo option puts options[:foo] end end conn = Faraday.new(url: 'http://httpbingo.org') do |faraday| faraday.use MyMiddleware, foo: 'bar' end ``` ## Registering your middleware Users can use your middleware using the class directly, but you can also register it with Faraday so that it can be used with the `use`, `request` or `response` methods as well. ```ruby # Register for `use` Faraday::Middleware.register_middleware(my_middleware: MyMiddleware) # Register for `request` Faraday::Request.register_middleware(my_middleware: MyMiddleware) # Register for `response` Faraday::Response.register_middleware(my_middleware: MyMiddleware) ``` faraday-2.10.0/docs/middleware/included/000077500000000000000000000000001464273144400200465ustar00rootroot00000000000000faraday-2.10.0/docs/middleware/included/authentication.md000066400000000000000000000033611464273144400234120ustar00rootroot00000000000000# Authentication The `Faraday::Request::Authorization` middleware allows you to automatically add an `Authorization` header to your requests. It also features a handy helper to manage Basic authentication. **Please note the way you use this middleware in Faraday 1.x is different**, examples are available at the bottom of this page. ```ruby Faraday.new(...) do |conn| conn.request :authorization, 'Bearer', 'authentication-token' end ``` ### With a proc You can also provide a proc, which will be evaluated on each request: ```ruby Faraday.new(...) do |conn| conn.request :authorization, 'Bearer', -> { MyAuthStorage.get_auth_token } end ``` If the proc takes an argument, it will receive the forwarded `env` (see [The Env Object](getting-started/env-object.md)): ```ruby Faraday.new(...) do |conn| conn.request :authorization, 'Bearer', ->(env) { MyAuthStorage.get_auth_token(env) } end ``` ### Basic Authentication The middleware will automatically Base64 encode your Basic username and password: ```ruby Faraday.new(...) do |conn| conn.request :authorization, :basic, 'username', 'password' end ``` ### Faraday 1.x usage In Faraday 1.x, the way you use this middleware is slightly different: ```ruby # Basic Auth request # Authorization: Basic dXNlcm5hbWU6cGFzc3dvcmQ= Faraday.new(...) do |conn| conn.request :basic_auth, 'username', 'password' end # Token Auth request # `options` are automatically converted into `key=value` format # Authorization: Token authentication-token Faraday.new(...) do |conn| conn.request :token_auth, 'authentication-token', **options end # Generic Auth Request # Authorization: Bearer authentication-token Faraday.new(...) do |conn| conn.request :authorization, 'Bearer', 'authentication-token' end ``` faraday-2.10.0/docs/middleware/included/index.md000066400000000000000000000036561464273144400215110ustar00rootroot00000000000000# Included middleware Faraday ships with some useful middleware that you can use to customize your request/response lifecycle. Middleware are separated into two macro-categories: **Request Middleware** and **Response Middleware**. The former usually deal with the request, encoding the parameters or setting headers. The latter instead activate after the request is completed and a response has been received, like parsing the response body, logging useful info or checking the response status. ### Request Middleware **Request middleware** can modify Request details before the Adapter runs. Most middleware set Header values or transform the request body based on the content type. * [`Authorization`][authentication] allows you to automatically add an Authorization header to your requests. * [`UrlEncoded`][url_encoded] converts a `Faraday::Request#body` hash of key/value pairs into a url-encoded request body. * [`Json Request`][json-request] converts a `Faraday::Request#body` hash of key/value pairs into a JSON request body. * [`Instrumentation`][instrumentation] allows to instrument requests using different tools. ### Response Middleware **Response middleware** receives the response from the adapter and can modify its details before returning it. * [`Json Response`][json-response] parses response body into a hash of key/value pairs. * [`Logger`][logger] logs both the request and the response body and headers. * [`RaiseError`][raise_error] checks the response HTTP code and raises an exception if it is a 4xx or 5xx code. [authentication]: middleware/included/authentication.md [url_encoded]: middleware/included/url-encoding [json-request]: middleware/included/json#json-requests [instrumentation]: middleware/included/instrumentation [json-response]: middleware/included/json#json-responses [logger]: middleware/included/logging [raise_error]: middleware/included/raising-errors faraday-2.10.0/docs/middleware/included/instrumentation.md000066400000000000000000000021251464273144400236330ustar00rootroot00000000000000# Instrumentation The `Instrumentation` middleware allows to instrument requests using different tools. Options for this middleware include the instrumentation `name` and the `instrumenter` you want to use. They default to `request.faraday` and `ActiveSupport::Notifications` respectively, but you can provide your own: ```ruby conn = Faraday.new(...) do |f| f.request :instrumentation, name: 'custom_name', instrumenter: MyInstrumenter ... end ``` ### Example Usage The `Instrumentation` middleware will use `ActiveSupport::Notifications` by default as instrumenter, allowing you to subscribe to the default event name and instrument requests: ```ruby conn = Faraday.new('http://example.com') do |f| f.request :instrumentation ... end ActiveSupport::Notifications.subscribe('request.faraday') do |name, starts, ends, _, env| url = env[:url] http_method = env[:method].to_s.upcase duration = ends - starts $stdout.puts '[%s] %s %s (%.3f s)' % [url.host, http_method, url.request_uri, duration] end conn.get('/search', { a: 1, b: 2 }) #=> [example.com] GET /search?a=1&b=2 (0.529 s) ``` faraday-2.10.0/docs/middleware/included/json.md000066400000000000000000000046261464273144400213510ustar00rootroot00000000000000# JSON Encoding/Decoding ## JSON Requests The `JSON` request middleware converts a `Faraday::Request#body` hash of key/value pairs into a JSON request body. The middleware also automatically sets the `Content-Type` header to `application/json`, processes only requests with matching Content-Type or those without a type and doesn't try to encode bodies that already are in string form. ### Example Usage ```ruby conn = Faraday.new(...) do |f| f.request :json ... end conn.post('/', { a: 1, b: 2 }) # POST with # Content-Type: application/json # Body: {"a":1,"b":2} ``` ### Using custom JSON encoders By default, middleware utilizes Ruby's `json` to generate JSON strings. Other encoders can be used by specifying `encoder` option for the middleware: * a module/class which implements `dump` * a module/class-method pair to be used ```ruby require 'oj' Faraday.new(...) do |f| f.request :json, encoder: Oj end Faraday.new(...) do |f| f.request :json, encoder: [Oj, :dump] end ``` ## JSON Responses The `JSON` response middleware parses response body into a hash of key/value pairs. The behaviour can be customized with the following options: * **parser_options:** options that will be sent to the JSON.parse method. Defaults to {}. * **content_type:** Single value or Array of response content-types that should be processed. Can be either strings or Regex. Defaults to `/\bjson$/`. * **preserve_raw:** If set to true, the original un-parsed response will be stored in the `response.env[:raw_body]` property. Defaults to `false`. ### Example Usage ```ruby conn = Faraday.new('http://httpbingo.org') do |f| f.response :json, **options end conn.get('json').body # => {"slideshow"=>{"author"=>"Yours Truly", "date"=>"date of publication", "slides"=>[{"title"=>"Wake up to WonderWidgets!", "type"=>"all"}, {"items"=>["Why WonderWidgets are great", "Who buys WonderWidgets"], "title"=>"Overview", "type"=>"all"}], "title"=>"Sample Slide Show"}} ``` ### Using custom JSON decoders By default, middleware utilizes Ruby's `json` to parse JSON strings. Other decoders can be used by specifying `decoder` parser option for the middleware: * a module/class which implements `load` * a module/class-method pair to be used ```ruby require 'oj' Faraday.new(...) do |f| f.response :json, parser_options: { decoder: Oj } end Faraday.new(...) do |f| f.response :json, parser_options: { decoder: [Oj, :load] } end ```faraday-2.10.0/docs/middleware/included/logging.md000066400000000000000000000071451464273144400220250ustar00rootroot00000000000000# Logging The `Logger` middleware logs both the request and the response body and headers. It is highly customizable and allows to mask confidential information if necessary. ### Basic Usage ```ruby conn = Faraday.new(url: 'http://httpbingo.org') do |faraday| faraday.response :logger # log requests and responses to $stdout end conn.get # => INFO -- request: GET http://httpbingo.org/ # => DEBUG -- request: User-Agent: "Faraday v1.0.0" # => INFO -- response: Status 301 # => DEBUG -- response: date: "Sun, 19 May 2019 16:05:40 GMT" ``` ### Customize the logger By default, the `Logger` middleware uses the Ruby `Logger.new($stdout)`. You can customize it to use any logger you want by providing it when you add the middleware to the stack: ```ruby conn = Faraday.new(url: 'http://httpbingo.org') do |faraday| faraday.response :logger, MyLogger.new($stdout) end ``` ### Include and exclude headers/bodies By default, the `logger` middleware logs only headers for security reasons, however, you can configure it to log bodies and errors as well, or disable headers logging if you need to. To do so, simply provide a configuration hash when you add the middleware to the stack: ```ruby conn = Faraday.new(url: 'http://httpbingo.org') do |faraday| faraday.response :logger, nil, { headers: true, bodies: true, errors: true } end ``` You can also configure the `logger` middleware with a little more complex settings like "do not log the request bodies, but log the response bodies". ```ruby conn = Faraday.new(url: 'http://httpbingo.org') do |faraday| faraday.response :logger, nil, { bodies: { request: false, response: true } } end ``` Please note this only works with the default formatter. ### Filter sensitive information You can filter sensitive information from Faraday logs using a regex matcher: ```ruby conn = Faraday.new(url: 'http://httpbingo.org') do |faraday| faraday.response :logger do | logger | logger.filter(/(api_key=)([^&]+)/, '\1[REMOVED]') end end conn.get('/', api_key: 'secret') # => INFO -- request: GET http://httpbingo.org/?api_key=[REMOVED] # => DEBUG -- request: User-Agent: "Faraday v1.0.0" # => INFO -- response: Status 301 # => DEBUG -- response: date: "Sun, 19 May 2019 16:12:36 GMT" ``` ### Change log level By default, the `logger` middleware logs on the `info` log level. It is possible to configure the severity by providing the `log_level` option: ```ruby conn = Faraday.new(url: 'http://httpbingo.org') do |faraday| faraday.response :logger, nil, { bodies: true, log_level: :debug } end ``` ### Customize the formatter You can also provide a custom formatter to control how requests, responses and errors are logged. Any custom formatter MUST implement the `request` and `response` method, with one argument which will be passed being the Faraday environment. Any custom formatter CAN implement the `exception` method, with one argument which will be passed being the exception (StandardError). If you make your formatter inheriting from `Faraday::Logging::Formatter`, then the methods `debug`, `info`, `warn`, `error` and `fatal` are automatically delegated to the logger. ```ruby class MyFormatter < Faraday::Logging::Formatter def request(env) # Build a custom message using `env` info('Request') { 'Sending Request' } end def response(env) # Build a custom message using `env` info('Response') { 'Response Received' } end def exception(exc) # Build a custom message using `exc` info('Error') { 'Error Raised' } end end conn = Faraday.new(url: 'http://httpbingo.org/api_key=s3cr3t') do |faraday| faraday.response :logger, nil, formatter: MyFormatter end ``` faraday-2.10.0/docs/middleware/included/raising-errors.md000066400000000000000000000076461464273144400233530ustar00rootroot00000000000000# Raising Errors The `RaiseError` middleware raises a `Faraday::Error` exception if an HTTP response returns with a 4xx or 5xx status code. This greatly increases the ease of use of Faraday, as you don't have to check the response status code manually. These errors add to the list of default errors [raised by Faraday](getting-started/errors.md). All exceptions are initialized with a hash containing the response `status`, `headers`, and `body`. ```ruby conn = Faraday.new(url: 'http://httpbingo.org') do |faraday| faraday.response :raise_error # raise Faraday::Error on status code 4xx or 5xx end begin conn.get('/wrong-url') # => Assume this raises a 404 response rescue Faraday::ResourceNotFound => e e.response_status #=> 404 e.response_headers #=> { ... } e.response_body #=> "..." end ``` Specific exceptions are raised based on the HTTP Status code of the response. ## 4xx Errors An HTTP status in the 400-499 range typically represents an error by the client. They raise error classes inheriting from `Faraday::ClientError`. | Status Code | Exception Class | |---------------------------------------------------------------------|-------------------------------------| | [400](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/400) | `Faraday::BadRequestError` | | [401](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/401) | `Faraday::UnauthorizedError` | | [403](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/403) | `Faraday::ForbiddenError` | | [404](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/404) | `Faraday::ResourceNotFound` | | [407](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/407) | `Faraday::ProxyAuthError` | | [408](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/408) | `Faraday::RequestTimeoutError` | | [409](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/409) | `Faraday::ConflictError` | | [422](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/422) | `Faraday::UnprocessableEntityError` | | [429](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/429) | `Faraday::TooManyRequestsError` | | 4xx (any other) | `Faraday::ClientError` | ## 5xx Errors An HTTP status in the 500-599 range represents a server error, and raises a `Faraday::ServerError` exception. It's important to note that this exception is only returned if we receive a response and the HTTP status in such response is in the 500-599 range. Other kind of errors normally attributed to errors in the 5xx range (such as timeouts, failure to connect, etc...) are raised as specific exceptions inheriting from `Faraday::Error`. See [Faraday Errors](getting-started/errors.md) for more information on these. ### Missing HTTP status The HTTP response status may be nil due to a malformed HTTP response from the server, or a bug in the underlying HTTP library. This is considered a server error and raised as `Faraday::NilStatusError`, which inherits from `Faraday::ServerError`. ## Middleware Options The behavior of this middleware can be customized with the following options: | Option | Default | Description | |---------------------|---------|-------------| | **include_request** | true | When true, exceptions are initialized with request information including `method`, `url`, `url_path`, `params`, `headers`, and `body`. | ### Example Usage ```ruby conn = Faraday.new(url: 'http://httpbingo.org') do |faraday| faraday.response :raise_error, include_request: true end begin conn.get('/wrong-url') # => Assume this raises a 404 response rescue Faraday::ResourceNotFound => e e.response[:status] #=> 404 e.response[:headers] #=> { ... } e.response[:body] #=> "..." e.response[:request][:url_path] #=> "/wrong-url" end ``` faraday-2.10.0/docs/middleware/included/url-encoding.md000066400000000000000000000015161464273144400227610ustar00rootroot00000000000000# URL Encoding The `UrlEncoded` middleware converts a `Faraday::Request#body` hash of key/value pairs into a url-encoded request body. The middleware also automatically sets the `Content-Type` header to `application/x-www-form-urlencoded`. The way parameters are serialized can be customized in the [Request Options](customization/request-options.md). ### Example Usage ```ruby conn = Faraday.new(...) do |f| f.request :url_encoded ... end conn.post('/', { a: 1, b: 2 }) # POST with # Content-Type: application/x-www-form-urlencoded # Body: a=1&b=2 ``` Complex structures can also be passed ```ruby conn.post('/', { a: [1, 3], b: { c: 2, d: 4} }) # POST with # Content-Type: application/x-www-form-urlencoded # Body: a%5B%5D=1&a%5B%5D=3&b%5Bc%5D=2&b%5Bd%5D=4 ``` [customize]: ../usage/customize#changing-how-parameters-are-serialized faraday-2.10.0/docs/middleware/index.md000066400000000000000000000143571464273144400177220ustar00rootroot00000000000000# Middleware Under the hood, Faraday uses a Rack-inspired middleware stack for making requests. Much of Faraday's power is unlocked with custom middleware. Some middleware is included with Faraday, and others are in external gems. Here are some of the features that middleware can provide: - authentication - caching responses on disk or in memory - cookies - following redirects - JSON encoding/decoding - logging To use these great features, create a `Faraday::Connection` with `Faraday.new` and add the correct middleware in a block. For example: ```ruby require 'faraday' conn = Faraday.new do |f| f.request :json # encode req bodies as JSON f.response :logger # logs request and responses f.response :json # decode response bodies as JSON f.adapter :net_http # Use the Net::HTTP adapter end response = conn.get("http://httpbingo.org/get") ``` ### How it Works A `Faraday::Connection` uses a `Faraday::RackBuilder` to assemble a Rack-inspired middleware stack for making HTTP requests. Each middleware runs and passes an Env object around to the next one. After the final middleware has run, Faraday will return a `Faraday::Response` to the end user. The order in which middleware is stacked is important. Like with Rack, the first middleware on the list wraps all others, while the last middleware is the innermost one. If you want to use a custom [adapter](adapters/index.md), it must therefore be last. ![Middleware](../_media/middleware.png) This is what makes things like the "retry middleware" possible. It doesn't really matter if the middleware was registered as a request or a response one, the only thing that matter is how they're added to the stack. Say you have the following: ```ruby Faraday.new(...) do |conn| conn.request :authorization conn.response :json conn.response :parse_dates end ``` This will result into a middleware stack like this: ```ruby authorization do # authorization request hook json do # json request hook parse_dates do # parse_dates request hook response = adapter.perform(request) # parse_dates response hook end # json response hook end # authorization response hook end ``` In this example, you can see that `parse_dates` is the LAST middleware processing the request, and the FIRST middleware processing the response. This is why it's important for the adapter to always be at the end of the middleware list. ### Using Middleware Calling `use` is the most basic way to add middleware to your stack, but most middleware is conveniently registered in the `request`, `response` or `adapter` namespaces. All four methods are equivalent apart from the namespacing. For example, the `Faraday::Request::UrlEncoded` middleware registers itself in `Faraday::Request` so it can be added with `request`. These two are equivalent: ```ruby # add by symbol, lookup from Faraday::Request, # Faraday::Response and Faraday::Adapter registries conn = Faraday.new do |f| f.request :url_encoded f.response :logger f.adapter :net_http end ``` or: ```ruby # identical, but add the class directly instead of using lookups conn = Faraday.new do |f| f.use Faraday::Request::UrlEncoded f.use Faraday::Response::Logger f.use Faraday::Adapter::NetHttp end ``` This is also the place to pass options. For example: ```ruby conn = Faraday.new do |f| f.request :logger, bodies: true end ``` ### DEFAULT_OPTIONS `DEFAULT_OPTIONS` improve the flexibility and customizability of new and existing middleware. Class-level `DEFAULT_OPTIONS` and the ability to set these defaults at the application level compliment existing functionality in which options can be passed into middleware on a per-instance basis. #### Using DEFAULT_OPTIONS Using `RaiseError` as an example, you can see that `DEFAULT_OPTIONS` have been defined at the top of the class: ```ruby DEFAULT_OPTIONS = { include_request: true }.freeze ``` These options will be set at the class level upon instantiation and referenced as needed within the class. From our same example: ```ruby def response_values(env) ... return response unless options[:include_request] ... ``` If the default value provides the desired functionality, no further consideration is needed. #### Setting Alternative Options per Application In the case where it is desirable to change the default option for all instances within an application, it can be done by configuring the options in a `/config/initializers` file. For example: ```ruby # config/initializers/faraday_config.rb Faraday::Response::RaiseError.default_options = { include_request: false } ``` After app initialization, all instances of the middleware will have the newly configured option(s). They can still be overriden on a per-instance bases (if handled in the middleware), like this: ```ruby Faraday.new do |f| ... f.response :raise_error, include_request: true ... end ``` ### Available Middleware The following pages provide detailed configuration for the middleware that ships with Faraday: * [Authentication](middleware/included/authentication.md) * [URL Encoding](middleware/included/url-encoding.md) * [JSON Encoding/Decoding](middleware/included/json.md) * [Instrumentation](middleware/included/instrumentation.md) * [Logging](middleware/included/logging.md) * [Raising Errors](middleware/included/raising-errors.md) The [Awesome Faraday](https://github.com/lostisland/awesome-faraday/) project has a complete list of useful, well-maintained Faraday middleware. Middleware is often provided by external gems, like the [faraday-retry](https://github.com/lostisland/faraday-retry) gem. ### Detailed Example Here's a more realistic example: ```ruby Faraday.new(...) do |conn| # POST/PUT params encoder conn.request :url_encoded # Logging of requests/responses conn.response :logger # Last middleware must be the adapter conn.adapter :net_http end ``` This request middleware setup affects POST/PUT requests in the following way: 1. `Request::UrlEncoded` encodes as "application/x-www-form-urlencoded" if not already encoded or of another type. 2. `Response::Logger` logs request and response headers, can be configured to log bodies as well. Swapping middleware means giving the other priority. Specifying the "Content-Type" for the request is explicitly stating which middleware should process it. faraday-2.10.0/examples/000077500000000000000000000000001464273144400150305ustar00rootroot00000000000000faraday-2.10.0/examples/client_spec.rb000066400000000000000000000064421464273144400176530ustar00rootroot00000000000000# frozen_string_literal: true # Requires Ruby with rspec and faraday gems. # rspec client_spec.rb require 'faraday' require 'json' # Example API client class Client def initialize(conn) @conn = conn end def httpbingo(jname, params: {}) res = @conn.get("/#{jname}", params) data = JSON.parse(res.body) data['origin'] end def foo(params) res = @conn.post('/foo', JSON.dump(params)) res.status end end RSpec.describe Client do let(:stubs) { Faraday::Adapter::Test::Stubs.new } let(:conn) { Faraday.new { |b| b.adapter(:test, stubs) } } let(:client) { Client.new(conn) } it 'parses origin' do stubs.get('/ip') do |env| # optional: you can inspect the Faraday::Env expect(env.url.path).to eq('/ip') [ 200, { 'Content-Type': 'application/javascript' }, '{"origin": "127.0.0.1"}' ] end # uncomment to trigger stubs.verify_stubbed_calls failure # stubs.get('/unused') { [404, {}, ''] } expect(client.httpbingo('ip')).to eq('127.0.0.1') stubs.verify_stubbed_calls end it 'handles 404' do stubs.get('/api') do [ 404, { 'Content-Type': 'application/javascript' }, '{}' ] end expect(client.httpbingo('api')).to be_nil stubs.verify_stubbed_calls end it 'handles exception' do stubs.get('/api') do raise Faraday::ConnectionFailed end expect { client.httpbingo('api') }.to raise_error(Faraday::ConnectionFailed) stubs.verify_stubbed_calls end context 'When the test stub is run in strict_mode' do let(:stubs) { Faraday::Adapter::Test::Stubs.new(strict_mode: true) } it 'verifies the all parameter values are identical' do stubs.get('/api?abc=123') do [ 200, { 'Content-Type': 'application/javascript' }, '{"origin": "127.0.0.1"}' ] end # uncomment to raise Stubs::NotFound # expect(client.httpbingo('api', params: { abc: 123, foo: 'Kappa' })).to eq('127.0.0.1') expect(client.httpbingo('api', params: { abc: 123 })).to eq('127.0.0.1') stubs.verify_stubbed_calls end end context 'When the Faraday connection is configured with FlatParamsEncoder' do let(:conn) { Faraday.new(request: { params_encoder: Faraday::FlatParamsEncoder }) { |b| b.adapter(:test, stubs) } } it 'handles the same multiple URL parameters' do stubs.get('/api?a=x&a=y&a=z') { [200, { 'Content-Type' => 'application/json' }, '{"origin": "127.0.0.1"}'] } # uncomment to raise Stubs::NotFound # expect(client.httpbingo('api', params: { a: %w[x y] })).to eq('127.0.0.1') expect(client.httpbingo('api', params: { a: %w[x y z] })).to eq('127.0.0.1') stubs.verify_stubbed_calls end end context 'When you want to test the body, you can use a proc as well as string' do it 'tests with a string' do stubs.post('/foo', '{"name":"YK"}') { [200, {}, ''] } expect(client.foo(name: 'YK')).to eq 200 stubs.verify_stubbed_calls end it 'tests with a proc' do check = ->(request_body) { JSON.parse(request_body).slice('name') == { 'name' => 'YK' } } stubs.post('/foo', check) { [200, {}, ''] } expect(client.foo(name: 'YK', created_at: Time.now)).to eq 200 stubs.verify_stubbed_calls end end end faraday-2.10.0/examples/client_test.rb000066400000000000000000000070101464273144400176700ustar00rootroot00000000000000# frozen_string_literal: true # Requires Ruby with test-unit and faraday gems. # ruby client_test.rb require 'faraday' require 'json' require 'test/unit' # Example API client class Client def initialize(conn) @conn = conn end def httpbingo(jname, params: {}) res = @conn.get("/#{jname}", params) data = JSON.parse(res.body) data['origin'] end def foo(params) res = @conn.post('/foo', JSON.dump(params)) res.status end end # Example API client test class ClientTest < Test::Unit::TestCase def test_httpbingo_name stubs = Faraday::Adapter::Test::Stubs.new stubs.get('/api') do |env| # optional: you can inspect the Faraday::Env assert_equal '/api', env.url.path [ 200, { 'Content-Type': 'application/javascript' }, '{"origin": "127.0.0.1"}' ] end # uncomment to trigger stubs.verify_stubbed_calls failure # stubs.get('/unused') { [404, {}, ''] } cli = client(stubs) assert_equal '127.0.0.1', cli.httpbingo('api') stubs.verify_stubbed_calls end def test_httpbingo_not_found stubs = Faraday::Adapter::Test::Stubs.new stubs.get('/api') do [ 404, { 'Content-Type': 'application/javascript' }, '{}' ] end cli = client(stubs) assert_nil cli.httpbingo('api') stubs.verify_stubbed_calls end def test_httpbingo_exception stubs = Faraday::Adapter::Test::Stubs.new stubs.get('/api') do raise Faraday::ConnectionFailed end cli = client(stubs) assert_raise Faraday::ConnectionFailed do cli.httpbingo('api') end stubs.verify_stubbed_calls end def test_strict_mode stubs = Faraday::Adapter::Test::Stubs.new(strict_mode: true) stubs.get('/api?abc=123') do [ 200, { 'Content-Type': 'application/javascript' }, '{"origin": "127.0.0.1"}' ] end cli = client(stubs) assert_equal '127.0.0.1', cli.httpbingo('api', params: { abc: 123 }) # uncomment to raise Stubs::NotFound # assert_equal '127.0.0.1', cli.httpbingo('api', params: { abc: 123, foo: 'Kappa' }) stubs.verify_stubbed_calls end def test_non_default_params_encoder stubs = Faraday::Adapter::Test::Stubs.new(strict_mode: true) stubs.get('/api?a=x&a=y&a=z') do [ 200, { 'Content-Type': 'application/javascript' }, '{"origin": "127.0.0.1"}' ] end conn = Faraday.new(request: { params_encoder: Faraday::FlatParamsEncoder }) do |builder| builder.adapter :test, stubs end cli = Client.new(conn) assert_equal '127.0.0.1', cli.httpbingo('api', params: { a: %w[x y z] }) # uncomment to raise Stubs::NotFound # assert_equal '127.0.0.1', cli.httpbingo('api', params: { a: %w[x y] }) stubs.verify_stubbed_calls end def test_with_string_body stubs = Faraday::Adapter::Test::Stubs.new do |stub| stub.post('/foo', '{"name":"YK"}') { [200, {}, ''] } end cli = client(stubs) assert_equal 200, cli.foo(name: 'YK') stubs.verify_stubbed_calls end def test_with_proc_body stubs = Faraday::Adapter::Test::Stubs.new do |stub| check = ->(request_body) { JSON.parse(request_body).slice('name') == { 'name' => 'YK' } } stub.post('/foo', check) { [200, {}, ''] } end cli = client(stubs) assert_equal 200, cli.foo(name: 'YK', created_at: Time.now) stubs.verify_stubbed_calls end def client(stubs) conn = Faraday.new do |builder| builder.adapter :test, stubs end Client.new(conn) end end faraday-2.10.0/faraday.gemspec000066400000000000000000000031351464273144400161700ustar00rootroot00000000000000# frozen_string_literal: true require_relative 'lib/faraday/version' Gem::Specification.new do |spec| spec.name = 'faraday' spec.version = Faraday::VERSION spec.summary = 'HTTP/REST API client library.' spec.authors = ['@technoweenie', '@iMacTia', '@olleolleolle'] spec.email = 'technoweenie@gmail.com' spec.homepage = 'https://lostisland.github.io/faraday' spec.licenses = ['MIT'] spec.required_ruby_version = '>= 3.0' # faraday-net_http is the "default adapter", but being a Faraday dependency it can't # control which version of faraday it will be pulled from. # To avoid releasing a major version every time there's a new Faraday API, we should # always fix its required version to the next MINOR version. # This way, we can release minor versions of the adapter with "breaking" changes for older versions of Faraday # and then bump the version requirement on the next compatible version of faraday. spec.add_dependency 'faraday-net_http', '>= 2.0', '< 3.2' spec.add_dependency 'logger' # Includes `examples` and `spec` to allow external adapter gems to run Faraday unit and integration tests spec.files = Dir['CHANGELOG.md', '{examples,lib,spec}/**/*', 'LICENSE.md', 'Rakefile', 'README.md'] spec.require_paths = %w[lib spec/external_adapters] spec.metadata = { 'homepage_uri' => 'https://lostisland.github.io/faraday', 'changelog_uri' => "https://github.com/lostisland/faraday/releases/tag/v#{spec.version}", 'source_code_uri' => 'https://github.com/lostisland/faraday', 'bug_tracker_uri' => 'https://github.com/lostisland/faraday/issues' } end faraday-2.10.0/lib/000077500000000000000000000000001464273144400137605ustar00rootroot00000000000000faraday-2.10.0/lib/faraday.rb000066400000000000000000000123311464273144400157140ustar00rootroot00000000000000# frozen_string_literal: true require 'cgi' require 'date' require 'set' require 'forwardable' require 'faraday/version' require 'faraday/methods' require 'faraday/error' require 'faraday/middleware_registry' require 'faraday/utils' require 'faraday/options' require 'faraday/connection' require 'faraday/rack_builder' require 'faraday/parameters' require 'faraday/middleware' require 'faraday/adapter' require 'faraday/request' require 'faraday/response' require 'faraday/net_http' # This is the main namespace for Faraday. # # It provides methods to create {Connection} objects, and HTTP-related # methods to use directly. # # @example Helpful class methods for easy usage # Faraday.get "http://faraday.com" # # @example Helpful class method `.new` to create {Connection} objects. # conn = Faraday.new "http://faraday.com" # conn.get '/' # module Faraday CONTENT_TYPE = 'Content-Type' class << self # The root path that Faraday is being loaded from. # # This is the root from where the libraries are auto-loaded. # # @return [String] attr_accessor :root_path # Gets or sets the path that the Faraday libs are loaded from. # @return [String] attr_accessor :lib_path # @overload default_adapter # Gets the Symbol key identifying a default Adapter to use # for the default {Faraday::Connection}. Defaults to `:net_http`. # @return [Symbol] the default adapter # @overload default_adapter=(adapter) # Updates default adapter while resetting {.default_connection}. # @return [Symbol] the new default_adapter. attr_reader :default_adapter # Option for the default_adapter # @return [Hash] default_adapter options attr_accessor :default_adapter_options # Documented below, see default_connection attr_writer :default_connection # Tells Faraday to ignore the environment proxy (http_proxy). # Defaults to `false`. # @return [Boolean] attr_accessor :ignore_env_proxy # Initializes a new {Connection}. # # @param url [String,Hash] The optional String base URL to use as a prefix # for all requests. Can also be the options Hash. Any of these # values will be set on every request made, unless overridden # for a specific request. # @param options [Hash] # @option options [String] :url Base URL # @option options [Hash] :params Hash of unencoded URI query params. # @option options [Hash] :headers Hash of unencoded HTTP headers. # @option options [Hash] :request Hash of request options. # @option options [Hash] :ssl Hash of SSL options. # @option options [Hash] :proxy Hash of Proxy options. # @return [Faraday::Connection] # # @example With an URL argument # Faraday.new 'http://faraday.com' # # => Faraday::Connection to http://faraday.com # # @example With an URL argument and an options hash # Faraday.new 'http://faraday.com', params: { page: 1 } # # => Faraday::Connection to http://faraday.com?page=1 # # @example With everything in an options hash # Faraday.new url: 'http://faraday.com', # params: { page: 1 } # # => Faraday::Connection to http://faraday.com?page=1 def new(url = nil, options = {}, &block) options = Utils.deep_merge(default_connection_options, options) Faraday::Connection.new(url, options, &block) end # Documented elsewhere, see default_adapter reader def default_adapter=(adapter) @default_connection = nil @default_adapter = adapter end def respond_to_missing?(symbol, include_private = false) default_connection.respond_to?(symbol, include_private) || super end # @overload default_connection # Gets the default connection used for simple scripts. # @return [Faraday::Connection] a connection configured with # the default_adapter. # @overload default_connection=(connection) # @param connection [Faraday::Connection] # Sets the default {Faraday::Connection} for simple scripts that # access the Faraday constant directly, such as # Faraday.get "https://faraday.com". def default_connection @default_connection ||= Connection.new(default_connection_options) end # Gets the default connection options used when calling {Faraday#new}. # # @return [Faraday::ConnectionOptions] def default_connection_options @default_connection_options ||= ConnectionOptions.new end # Sets the default options used when calling {Faraday#new}. # # @param options [Hash, Faraday::ConnectionOptions] def default_connection_options=(options) @default_connection = nil @default_connection_options = ConnectionOptions.from(options) end private # Internal: Proxies method calls on the Faraday constant to # .default_connection. def method_missing(name, *args, &block) if default_connection.respond_to?(name) default_connection.send(name, *args, &block) else super end end end self.ignore_env_proxy = false self.root_path = File.expand_path __dir__ self.lib_path = File.expand_path 'faraday', __dir__ self.default_adapter = :net_http self.default_adapter_options = {} end faraday-2.10.0/lib/faraday/000077500000000000000000000000001464273144400153675ustar00rootroot00000000000000faraday-2.10.0/lib/faraday/adapter.rb000066400000000000000000000056101464273144400173360ustar00rootroot00000000000000# frozen_string_literal: true module Faraday # Base class for all Faraday adapters. Adapters are # responsible for fulfilling a Faraday request. class Adapter extend MiddlewareRegistry CONTENT_LENGTH = 'Content-Length' # This module marks an Adapter as supporting parallel requests. module Parallelism attr_writer :supports_parallel def supports_parallel? @supports_parallel end def inherited(subclass) super subclass.supports_parallel = supports_parallel? end end extend Parallelism self.supports_parallel = false def initialize(_app = nil, opts = {}, &block) @app = lambda(&:response) @connection_options = opts @config_block = block end # Yields or returns an adapter's configured connection. Depends on # #build_connection being defined on this adapter. # # @param env [Faraday::Env, Hash] The env object for a faraday request. # # @return The return value of the given block, or the HTTP connection object # if no block is given. def connection(env) conn = build_connection(env) return conn unless block_given? yield conn end # Close any persistent connections. The adapter should still be usable # after calling close. def close # Possible implementation: # @app.close if @app.respond_to?(:close) end def call(env) env.clear_body if env.needs_body? env.response = Response.new end private def save_response(env, status, body, headers = nil, reason_phrase = nil, finished: true) env.status = status env.body = body env.reason_phrase = reason_phrase&.to_s&.strip env.response_headers = Utils::Headers.new.tap do |response_headers| response_headers.update headers unless headers.nil? yield(response_headers) if block_given? end env.response.finish(env) unless env.parallel? || !finished env.response end # Fetches either a read, write, or open timeout setting. Defaults to the # :timeout value if a more specific one is not given. # # @param type [Symbol] Describes which timeout setting to get: :read, # :write, or :open. # @param options [Hash] Hash containing Symbol keys like :timeout, # :read_timeout, :write_timeout, or :open_timeout # # @return [Integer, nil] Timeout duration in seconds, or nil if no timeout # has been set. def request_timeout(type, options) key = TIMEOUT_KEYS.fetch(type) do msg = "Expected :read, :write, :open. Got #{type.inspect} :(" raise ArgumentError, msg end options[key] || options[:timeout] end TIMEOUT_KEYS = { read: :read_timeout, open: :open_timeout, write: :write_timeout }.freeze end end require 'faraday/adapter/test' faraday-2.10.0/lib/faraday/adapter/000077500000000000000000000000001464273144400170075ustar00rootroot00000000000000faraday-2.10.0/lib/faraday/adapter/test.rb000066400000000000000000000225401464273144400203160ustar00rootroot00000000000000# frozen_string_literal: true require 'timeout' module Faraday class Adapter # @example # test = Faraday::Connection.new do # use Faraday::Adapter::Test do |stub| # # Define matcher to match the request # stub.get '/resource.json' do # # return static content # [200, {'Content-Type' => 'application/json'}, 'hi world'] # end # # # response with content generated based on request # stub.get '/showget' do |env| # [200, {'Content-Type' => 'text/plain'}, env[:method].to_s] # end # # # A regular expression can be used as matching filter # stub.get /\A\/items\/(\d+)\z/ do |env, meta| # # in case regular expression is used, an instance of MatchData # # can be received # [200, # {'Content-Type' => 'text/plain'}, # "showing item: #{meta[:match_data][1]}" # ] # end # # # Test the request body is the same as the stubbed body # stub.post('/bar', 'name=YK&word=call') { [200, {}, ''] } # # # You can pass a proc as a stubbed body and check the request body in your way. # # In this case, the proc should return true or false. # stub.post('/foo', ->(request_body) do # JSON.parse(request_body).slice('name') == { 'name' => 'YK' } }) { [200, {}, ''] # end # # # You can set strict_mode to exactly match the stubbed requests. # stub.strict_mode = true # end # end # # resp = test.get '/resource.json' # resp.body # => 'hi world' # # resp = test.get '/showget' # resp.body # => 'get' # # resp = test.get '/items/1' # resp.body # => 'showing item: 1' # # resp = test.get '/items/2' # resp.body # => 'showing item: 2' # # resp = test.post '/bar', 'name=YK&word=call' # resp.status # => 200 # # resp = test.post '/foo', JSON.dump(name: 'YK', created_at: Time.now) # resp.status # => 200 class Test < Faraday::Adapter attr_accessor :stubs # A stack of Stubs class Stubs class NotFound < StandardError end def initialize(strict_mode: false) # { get: [Stub, Stub] } @stack = {} @consumed = {} @strict_mode = strict_mode @stubs_mutex = Monitor.new yield(self) if block_given? end def empty? @stack.empty? end # @param env [Faraday::Env] def match(env) request_method = env[:method] return false unless @stack.key?(request_method) stack = @stack[request_method] consumed = (@consumed[request_method] ||= []) @stubs_mutex.synchronize do stub, meta = matches?(stack, env) if stub removed = stack.delete(stub) consumed << removed unless removed.nil? return stub, meta end end matches?(consumed, env) end def get(path, headers = {}, &block) new_stub(:get, path, headers, &block) end def head(path, headers = {}, &block) new_stub(:head, path, headers, &block) end def post(path, body = nil, headers = {}, &block) new_stub(:post, path, headers, body, &block) end def put(path, body = nil, headers = {}, &block) new_stub(:put, path, headers, body, &block) end def patch(path, body = nil, headers = {}, &block) new_stub(:patch, path, headers, body, &block) end def delete(path, headers = {}, &block) new_stub(:delete, path, headers, &block) end def options(path, headers = {}, &block) new_stub(:options, path, headers, &block) end # Raises an error if any of the stubbed calls have not been made. def verify_stubbed_calls failed_stubs = [] @stack.each do |method, stubs| next if stubs.empty? failed_stubs.concat( stubs.map do |stub| "Expected #{method} #{stub}." end ) end raise failed_stubs.join(' ') unless failed_stubs.empty? end # Set strict_mode. If the value is true, this adapter tries to find matched requests strictly, # which means that all of a path, parameters, and headers must be the same as an actual request. def strict_mode=(value) @strict_mode = value @stack.each_value do |stubs| stubs.each do |stub| stub.strict_mode = value end end end protected def new_stub(request_method, path, headers = {}, body = nil, &block) normalized_path, host = if path.is_a?(Regexp) path else [ Faraday::Utils.normalize_path(path), Faraday::Utils.URI(path).host ] end path, query = normalized_path.respond_to?(:split) ? normalized_path.split('?') : normalized_path headers = Utils::Headers.new(headers) stub = Stub.new(host, path, query, headers, body, @strict_mode, block) (@stack[request_method] ||= []) << stub end # @param stack [Hash] # @param env [Faraday::Env] def matches?(stack, env) stack.each do |stub| match_result, meta = stub.matches?(env) return stub, meta if match_result end nil end end # Stub request Stub = Struct.new(:host, :path, :query, :headers, :body, :strict_mode, :block) do # @param env [Faraday::Env] def matches?(env) request_host = env[:url].host request_path = Faraday::Utils.normalize_path(env[:url].path) request_headers = env.request_headers request_body = env[:body] # meta is a hash used as carrier # that will be yielded to consumer block meta = {} [(host.nil? || host == request_host) && path_match?(request_path, meta) && params_match?(env) && body_match?(request_body) && headers_match?(request_headers), meta] end def path_match?(request_path, meta) if path.is_a?(Regexp) !!(meta[:match_data] = path.match(request_path)) else path == request_path end end # @param env [Faraday::Env] def params_match?(env) request_params = env[:params] params = env.params_encoder.decode(query) || {} if strict_mode return Set.new(params) == Set.new(request_params) end params.keys.all? do |key| request_params[key] == params[key] end end def headers_match?(request_headers) if strict_mode headers_with_user_agent = headers.dup.tap do |hs| # NOTE: Set User-Agent in case it's not set when creating Stubs. # Users would not want to set Faraday's User-Agent explicitly. hs[:user_agent] ||= Connection::USER_AGENT end return Set.new(headers_with_user_agent) == Set.new(request_headers) end headers.keys.all? do |key| request_headers[key] == headers[key] end end def body_match?(request_body) return true if body.to_s.empty? case body when Proc body.call(request_body) else request_body == body end end def to_s "#{path} #{body}" end end def initialize(app, stubs = nil, &block) super(app) @stubs = stubs || Stubs.new configure(&block) if block end def configure yield(stubs) end # @param env [Faraday::Env] def call(env) super env.request.params_encoder ||= Faraday::Utils.default_params_encoder env[:params] = env.params_encoder.decode(env[:url].query) || {} stub, meta = stubs.match(env) unless stub raise Stubs::NotFound, "no stubbed request for #{env[:method]} " \ "#{env[:url]} #{env[:body]} #{env[:headers]}" end block_arity = stub.block.arity params = if block_arity >= 0 [env, meta].take(block_arity) else [env, meta] end timeout = request_timeout(:open, env[:request]) timeout ||= request_timeout(:read, env[:request]) status, headers, body = if timeout ::Timeout.timeout(timeout, Faraday::TimeoutError) do stub.block.call(*params) end else stub.block.call(*params) end # We need to explicitly pass `reason_phrase = nil` here to avoid keyword args conflicts. # See https://github.com/lostisland/faraday/issues/1444 # TODO: remove `nil` explicit reason_phrase once Ruby 3.0 becomes minimum req. version save_response(env, status, body, headers, nil) @app.call(env) end end end end Faraday::Adapter.register_middleware(test: Faraday::Adapter::Test) faraday-2.10.0/lib/faraday/adapter_registry.rb000066400000000000000000000011251464273144400212630ustar00rootroot00000000000000# frozen_string_literal: true require 'monitor' module Faraday # AdapterRegistry registers adapter class names so they can be looked up by a # String or Symbol name. class AdapterRegistry def initialize @lock = Monitor.new @constants = {} end def get(name) klass = @lock.synchronize do @constants[name] end return klass if klass Object.const_get(name).tap { |c| set(c, name) } end def set(klass, name = nil) name ||= klass.to_s @lock.synchronize do @constants[name] = klass end end end end faraday-2.10.0/lib/faraday/connection.rb000066400000000000000000000435361464273144400200660ustar00rootroot00000000000000# frozen_string_literal: true module Faraday # Connection objects manage the default properties and the middleware # stack for fulfilling an HTTP request. # # @example # # conn = Faraday::Connection.new 'http://httpbingo.org' # # # GET http://httpbingo.org/nigiri # conn.get 'nigiri' # # => # # class Connection # A Set of allowed HTTP verbs. METHODS = Set.new %i[get post put delete head patch options trace] USER_AGENT = "Faraday v#{VERSION}".freeze # @return [Hash] URI query unencoded key/value pairs. attr_reader :params # @return [Hash] unencoded HTTP header key/value pairs. attr_reader :headers # @return [String] a URI with the prefix used for all requests from this # Connection. This includes a default host name, scheme, port, and path. attr_reader :url_prefix # @return [Faraday::RackBuilder] Builder for this Connection. attr_reader :builder # @return [Hash] SSL options. attr_reader :ssl # @return [Object] the parallel manager for this Connection. attr_reader :parallel_manager # Sets the default parallel manager for this connection. attr_writer :default_parallel_manager # @return [Hash] proxy options. attr_reader :proxy # Initializes a new Faraday::Connection. # # @param url [URI, String] URI or String base URL to use as a prefix for all # requests (optional). # @param options [Hash, Faraday::ConnectionOptions] # @option options [URI, String] :url ('http:/') URI or String base URL # @option options [Hash String>] :params URI query unencoded # key/value pairs. # @option options [Hash String>] :headers Hash of unencoded HTTP # header key/value pairs. # @option options [Hash] :request Hash of request options. # @option options [Hash] :ssl Hash of SSL options. # @option options [Hash, URI, String] :proxy proxy options, either as a URL # or as a Hash # @option options [URI, String] :proxy[:uri] # @option options [String] :proxy[:user] # @option options [String] :proxy[:password] # @yield [self] after all setup has been done def initialize(url = nil, options = nil) options = ConnectionOptions.from(options) if url.is_a?(Hash) || url.is_a?(ConnectionOptions) options = Utils.deep_merge(options, url) url = options.url end @parallel_manager = nil @headers = Utils::Headers.new @params = Utils::ParamsHash.new @options = options.request @ssl = options.ssl @default_parallel_manager = options.parallel_manager @manual_proxy = nil @builder = options.builder || begin # pass an empty block to Builder so it doesn't assume default middleware options.new_builder(block_given? ? proc { |b| } : nil) end self.url_prefix = url || 'http:/' @params.update(options.params) if options.params @headers.update(options.headers) if options.headers initialize_proxy(url, options) yield(self) if block_given? @headers[:user_agent] ||= USER_AGENT end def initialize_proxy(url, options) @manual_proxy = !!options.proxy @proxy = if options.proxy ProxyOptions.from(options.proxy) else proxy_from_env(url) end end # Sets the Hash of URI query unencoded key/value pairs. # @param hash [Hash] def params=(hash) @params.replace hash end # Sets the Hash of unencoded HTTP header key/value pairs. # @param hash [Hash] def headers=(hash) @headers.replace hash end extend Forwardable def_delegators :builder, :use, :request, :response, :adapter, :app # Closes the underlying resources and/or connections. In the case of # persistent connections, this closes all currently open connections # but does not prevent new connections from being made. def close app.close end # @!method get(url = nil, params = nil, headers = nil) # Makes a GET HTTP request without a body. # @!scope class # # @param url [String, URI, nil] The optional String base URL to use as a prefix for # all requests. Can also be the options Hash. # @param params [Hash, nil] Hash of URI query unencoded key/value pairs. # @param headers [Hash, nil] unencoded HTTP header key/value pairs. # # @example # conn.get '/items', { page: 1 }, :accept => 'application/json' # # # ElasticSearch example sending a body with GET. # conn.get '/twitter/tweet/_search' do |req| # req.headers[:content_type] = 'application/json' # req.params[:routing] = 'kimchy' # req.body = JSON.generate(query: {...}) # end # # @yield [Faraday::Request] for further request customizations # @return [Faraday::Response] # @!method head(url = nil, params = nil, headers = nil) # Makes a HEAD HTTP request without a body. # @!scope class # # @param url [String, URI, nil] The optional String base URL to use as a prefix for # all requests. Can also be the options Hash. # @param params [Hash, nil] Hash of URI query unencoded key/value pairs. # @param headers [Hash, nil] unencoded HTTP header key/value pairs. # # @example # conn.head '/items/1' # # @yield [Faraday::Request] for further request customizations # @return [Faraday::Response] # @!method delete(url = nil, params = nil, headers = nil) # Makes a DELETE HTTP request without a body. # @!scope class # # @param url [String, URI, nil] The optional String base URL to use as a prefix for # all requests. Can also be the options Hash. # @param params [Hash, nil] Hash of URI query unencoded key/value pairs. # @param headers [Hash, nil] unencoded HTTP header key/value pairs. # # @example # conn.delete '/items/1' # # @yield [Faraday::Request] for further request customizations # @return [Faraday::Response] # @!method trace(url = nil, params = nil, headers = nil) # Makes a TRACE HTTP request without a body. # @!scope class # # @param url [String, URI, nil] The optional String base URL to use as a prefix for # all requests. Can also be the options Hash. # @param params [Hash, nil] Hash of URI query unencoded key/value pairs. # @param headers [Hash, nil] unencoded HTTP header key/value pairs. # # @example # conn.connect '/items/1' # # @yield [Faraday::Request] for further request customizations # @return [Faraday::Response] # @!visibility private METHODS_WITH_QUERY.each do |method| class_eval <<-RUBY, __FILE__, __LINE__ + 1 def #{method}(url = nil, params = nil, headers = nil) run_request(:#{method}, url, nil, headers) do |request| request.params.update(params) if params yield request if block_given? end end RUBY end # @overload options() # Returns current Connection options. # # @overload options(url, params = nil, headers = nil) # Makes an OPTIONS HTTP request to the given URL. # @param url [String, URI, nil] String base URL to sue as a prefix for all requests. # @param params [Hash, nil] Hash of URI query unencoded key/value pairs. # @param headers [Hash, nil] unencoded HTTP header key/value pairs. # # @example # conn.options '/items/1' # # @yield [Faraday::Request] for further request customizations # @return [Faraday::Response] def options(*args) return @options if args.empty? url, params, headers = *args run_request(:options, url, nil, headers) do |request| request.params.update(params) if params yield request if block_given? end end # @!method post(url = nil, body = nil, headers = nil) # Makes a POST HTTP request with a body. # @!scope class # # @param url [String, URI, nil] The optional String base URL to use as a prefix for # all requests. Can also be the options Hash. # @param body [String, nil] body for the request. # @param headers [Hash, nil] unencoded HTTP header key/value pairs. # # @example # conn.post '/items', data, content_type: 'application/json' # # # Simple ElasticSearch indexing sample. # conn.post '/twitter/tweet' do |req| # req.headers[:content_type] = 'application/json' # req.params[:routing] = 'kimchy' # req.body = JSON.generate(user: 'kimchy', ...) # end # # @yield [Faraday::Request] for further request customizations # @return [Faraday::Response] # @!method put(url = nil, body = nil, headers = nil) # Makes a PUT HTTP request with a body. # @!scope class # # @param url [String, URI, nil] The optional String base URL to use as a prefix for # all requests. Can also be the options Hash. # @param body [String, nil] body for the request. # @param headers [Hash, nil] unencoded HTTP header key/value pairs. # # @example # conn.put '/products/123', data, content_type: 'application/json' # # # Star a gist. # conn.put 'https://api.github.com/gists/GIST_ID/star' do |req| # req.headers['Accept'] = 'application/vnd.github+json' # req.headers['Authorization'] = 'Bearer ' # req.headers['X-GitHub-Api-Version'] = '2022-11-28' # end # # @yield [Faraday::Request] for further request customizations # @return [Faraday::Response] # @!visibility private METHODS_WITH_BODY.each do |method| class_eval <<-RUBY, __FILE__, __LINE__ + 1 def #{method}(url = nil, body = nil, headers = nil, &block) run_request(:#{method}, url, body, headers, &block) end RUBY end # Check if the adapter is parallel-capable. # # @yield if the adapter isn't parallel-capable, or if no adapter is set yet. # # @return [Object, nil] a parallel manager or nil if yielded # @api private def default_parallel_manager @default_parallel_manager ||= begin adapter = @builder.adapter.klass if @builder.adapter if support_parallel?(adapter) adapter.setup_parallel_manager elsif block_given? yield end end end # Determine if this Faraday::Connection can make parallel requests. # # @return [Boolean] def in_parallel? !!@parallel_manager end # Sets up the parallel manager to make a set of requests. # # @param manager [Object] The parallel manager that this Connection's # Adapter uses. # # @yield a block to execute multiple requests. # @return [void] def in_parallel(manager = nil) @parallel_manager = manager || default_parallel_manager do warn 'Warning: `in_parallel` called but no parallel-capable adapter ' \ 'on Faraday stack' warn caller[2, 10].join("\n") nil end yield @parallel_manager&.run ensure @parallel_manager = nil end # Sets the Hash proxy options. # # @param new_value [Object] def proxy=(new_value) @manual_proxy = true @proxy = new_value ? ProxyOptions.from(new_value) : nil end def_delegators :url_prefix, :scheme, :scheme=, :host, :host=, :port, :port= def_delegator :url_prefix, :path, :path_prefix # Parses the given URL with URI and stores the individual # components in this connection. These components serve as defaults for # requests made by this connection. # # @param url [String, URI] # @param encoder [Object] # # @example # # conn = Faraday::Connection.new { ... } # conn.url_prefix = "https://httpbingo.org/api" # conn.scheme # => https # conn.path_prefix # => "/api" # # conn.get("nigiri?page=2") # accesses https://httpbingo.org/api/nigiri def url_prefix=(url, encoder = nil) uri = @url_prefix = Utils.URI(url) self.path_prefix = uri.path params.merge_query(uri.query, encoder) uri.query = nil with_uri_credentials(uri) do |user, password| set_basic_auth(user, password) uri.user = uri.password = nil end @proxy = proxy_from_env(url) unless @manual_proxy end def set_basic_auth(user, password) header = Faraday::Utils.basic_header_from(user, password) headers[Faraday::Request::Authorization::KEY] = header end # Sets the path prefix and ensures that it always has a leading # slash. # # @param value [String] # # @return [String] the new path prefix def path_prefix=(value) url_prefix.path = if value value = "/#{value}" unless value[0, 1] == '/' value end end # Takes a relative url for a request and combines it with the defaults # set on the connection instance. # # @param url [String, URI, nil] # @param extra_params [Hash] # # @example # conn = Faraday::Connection.new { ... } # conn.url_prefix = "https://httpbingo.org/api?token=abc" # conn.scheme # => https # conn.path_prefix # => "/api" # # conn.build_url("nigiri?page=2") # # => https://httpbingo.org/api/nigiri?token=abc&page=2 # # conn.build_url("nigiri", page: 2) # # => https://httpbingo.org/api/nigiri?token=abc&page=2 # def build_url(url = nil, extra_params = nil) uri = build_exclusive_url(url) query_values = params.dup.merge_query(uri.query, options.params_encoder) query_values.update(extra_params) if extra_params uri.query = if query_values.empty? nil else query_values.to_query(options.params_encoder) end uri end # Builds and runs the Faraday::Request. # # @param method [Symbol] HTTP method. # @param url [String, URI, nil] String or URI to access. # @param body [String, Hash, Array, nil] The request body that will eventually be converted to # a string; middlewares can be used to support more complex types. # @param headers [Hash, nil] unencoded HTTP header key/value pairs. # # @return [Faraday::Response] def run_request(method, url, body, headers) unless METHODS.include?(method) raise ArgumentError, "unknown http method: #{method}" end request = build_request(method) do |req| req.options.proxy = proxy_for_request(url) req.url(url) if url req.headers.update(headers) if headers req.body = body if body yield(req) if block_given? end builder.build_response(self, request) end # Creates and configures the request object. # # @param method [Symbol] # # @yield [Faraday::Request] if block given # @return [Faraday::Request] def build_request(method) Request.create(method) do |req| req.params = params.dup req.headers = headers.dup req.options = options.dup yield(req) if block_given? end end # Build an absolute URL based on url_prefix. # # @param url [String, URI, nil] # @param params [Faraday::Utils::ParamsHash] A Faraday::Utils::ParamsHash to # replace the query values # of the resulting url (default: nil). # # @return [URI] def build_exclusive_url(url = nil, params = nil, params_encoder = nil) url = nil if url.respond_to?(:empty?) && url.empty? base = url_prefix.dup if url && !base.path.end_with?('/') base.path = "#{base.path}/" # ensure trailing slash end # Ensure relative url will be parsed correctly (such as `service:search` ) url = "./#{url}" if url.respond_to?(:start_with?) && !url.start_with?('http://', 'https://', '/', './', '../') uri = url ? base + url : base if params uri.query = params.to_query(params_encoder || options.params_encoder) end uri.query = nil if uri.query && uri.query.empty? uri end # Creates a duplicate of this Faraday::Connection. # # @api private # # @return [Faraday::Connection] def dup self.class.new(build_exclusive_url, headers: headers.dup, params: params.dup, builder: builder.dup, ssl: ssl.dup, request: options.dup) end # Yields username and password extracted from a URI if they both exist. # # @param uri [URI] # @yield [username, password] any username and password # @yieldparam username [String] any username from URI # @yieldparam password [String] any password from URI # @return [void] # @api private def with_uri_credentials(uri) return unless uri.user && uri.password yield(Utils.unescape(uri.user), Utils.unescape(uri.password)) end def proxy_from_env(url) return if Faraday.ignore_env_proxy uri = nil case url when String uri = Utils.URI(url) uri = if uri.host.nil? find_default_proxy else URI.parse("#{uri.scheme}://#{uri.host}").find_proxy end when URI uri = url.find_proxy when nil uri = find_default_proxy end ProxyOptions.from(uri) if uri end def find_default_proxy uri = ENV.fetch('http_proxy', nil) return unless uri && !uri.empty? uri = "http://#{uri}" unless uri.match?(/^http/i) uri end def proxy_for_request(url) return proxy if @manual_proxy if url && Utils.URI(url).absolute? proxy_from_env(url) else proxy end end def support_parallel?(adapter) adapter.respond_to?(:supports_parallel?) && adapter&.supports_parallel? end end end faraday-2.10.0/lib/faraday/encoders/000077500000000000000000000000001464273144400171715ustar00rootroot00000000000000faraday-2.10.0/lib/faraday/encoders/flat_params_encoder.rb000066400000000000000000000060071464273144400235110ustar00rootroot00000000000000# frozen_string_literal: true module Faraday # FlatParamsEncoder manages URI params as a flat hash. Any Array values repeat # the parameter multiple times. module FlatParamsEncoder class << self extend Forwardable def_delegators :'Faraday::Utils', :escape, :unescape end # Encode converts the given param into a URI querystring. Keys and values # will converted to strings and appropriately escaped for the URI. # # @param params [Hash] query arguments to convert. # # @example # # encode({a: %w[one two three], b: true, c: "C"}) # # => 'a=one&a=two&a=three&b=true&c=C' # # @return [String] the URI querystring (without the leading '?') def self.encode(params) return nil if params.nil? unless params.is_a?(Array) unless params.respond_to?(:to_hash) raise TypeError, "Can't convert #{params.class} into Hash." end params = params.to_hash params = params.map do |key, value| key = key.to_s if key.is_a?(Symbol) [key, value] end # Only to be used for non-Array inputs. Arrays should preserve order. params.sort! if @sort_params end # The params have form [['key1', 'value1'], ['key2', 'value2']]. buffer = +'' params.each do |key, value| encoded_key = escape(key) if value.nil? buffer << "#{encoded_key}&" elsif value.is_a?(Array) if value.empty? buffer << "#{encoded_key}=&" else value.each do |sub_value| encoded_value = escape(sub_value) buffer << "#{encoded_key}=#{encoded_value}&" end end else encoded_value = escape(value) buffer << "#{encoded_key}=#{encoded_value}&" end end buffer.chop end # Decode converts the given URI querystring into a hash. # # @param query [String] query arguments to parse. # # @example # # decode('a=one&a=two&a=three&b=true&c=C') # # => {"a"=>["one", "two", "three"], "b"=>"true", "c"=>"C"} # # @return [Hash] parsed keys and value strings from the querystring. def self.decode(query) return nil if query.nil? empty_accumulator = {} split_query = (query.split('&').map do |pair| pair.split('=', 2) if pair && !pair.empty? end).compact split_query.each_with_object(empty_accumulator.dup) do |pair, accu| pair[0] = unescape(pair[0]) pair[1] = true if pair[1].nil? if pair[1].respond_to?(:to_str) pair[1] = unescape(pair[1].to_str.tr('+', ' ')) end if accu[pair[0]].is_a?(Array) accu[pair[0]] << pair[1] elsif accu[pair[0]] accu[pair[0]] = [accu[pair[0]], pair[1]] else accu[pair[0]] = pair[1] end end end class << self attr_accessor :sort_params end # Useful default for OAuth and caching. @sort_params = true end end faraday-2.10.0/lib/faraday/encoders/nested_params_encoder.rb000066400000000000000000000120261464273144400240430ustar00rootroot00000000000000# frozen_string_literal: true module Faraday # Sub-module for encoding parameters into query-string. module EncodeMethods # @param params [nil, Array, #to_hash] parameters to be encoded # # @return [String] the encoded params # # @raise [TypeError] if params can not be converted to a Hash def encode(params) return nil if params.nil? unless params.is_a?(Array) unless params.respond_to?(:to_hash) raise TypeError, "Can't convert #{params.class} into Hash." end params = params.to_hash params = params.map do |key, value| key = key.to_s if key.is_a?(Symbol) [key, value] end # Only to be used for non-Array inputs. Arrays should preserve order. params.sort! if @sort_params end # The params have form [['key1', 'value1'], ['key2', 'value2']]. buffer = +'' params.each do |parent, value| encoded_parent = escape(parent) buffer << "#{encode_pair(encoded_parent, value)}&" end buffer.chop end protected def encode_pair(parent, value) if value.is_a?(Hash) encode_hash(parent, value) elsif value.is_a?(Array) encode_array(parent, value) elsif value.nil? parent else encoded_value = escape(value) "#{parent}=#{encoded_value}" end end def encode_hash(parent, value) value = value.map { |key, val| [escape(key), val] }.sort buffer = +'' value.each do |key, val| new_parent = "#{parent}%5B#{key}%5D" buffer << "#{encode_pair(new_parent, val)}&" end buffer.chop end def encode_array(parent, value) return "#{parent}%5B%5D" if value.empty? buffer = +'' value.each_with_index do |val, index| new_parent = if @array_indices "#{parent}%5B#{index}%5D" else "#{parent}%5B%5D" end buffer << "#{encode_pair(new_parent, val)}&" end buffer.chop end end # Sub-module for decoding query-string into parameters. module DecodeMethods # @param query [nil, String] # # @return [Array] the decoded params # # @raise [TypeError] if the nesting is incorrect def decode(query) return nil if query.nil? params = {} query.split('&').each do |pair| next if pair.empty? key, value = pair.split('=', 2) key = unescape(key) value = unescape(value.tr('+', ' ')) if value decode_pair(key, value, params) end dehash(params, 0) end protected SUBKEYS_REGEX = /[^\[\]]+(?:\]?\[\])?/ def decode_pair(key, value, context) subkeys = key.scan(SUBKEYS_REGEX) subkeys.each_with_index do |subkey, i| is_array = subkey =~ /[\[\]]+\Z/ subkey = Regexp.last_match.pre_match if is_array last_subkey = i == subkeys.length - 1 context = prepare_context(context, subkey, is_array, last_subkey) add_to_context(is_array, context, value, subkey) if last_subkey end end def prepare_context(context, subkey, is_array, last_subkey) if !last_subkey || is_array context = new_context(subkey, is_array, context) end if context.is_a?(Array) && !is_array context = match_context(context, subkey) end context end def new_context(subkey, is_array, context) value_type = is_array ? Array : Hash if context[subkey] && !context[subkey].is_a?(value_type) raise TypeError, "expected #{value_type.name} " \ "(got #{context[subkey].class.name}) for param `#{subkey}'" end context[subkey] ||= value_type.new end def match_context(context, subkey) context << {} if !context.last.is_a?(Hash) || context.last.key?(subkey) context.last end def add_to_context(is_array, context, value, subkey) is_array ? context << value : context[subkey] = value end # Internal: convert a nested hash with purely numeric keys into an array. # FIXME: this is not compatible with Rack::Utils.parse_nested_query # @!visibility private def dehash(hash, depth) hash.each do |key, value| hash[key] = dehash(value, depth + 1) if value.is_a?(Hash) end if depth.positive? && !hash.empty? && hash.keys.all? { |k| k =~ /^\d+$/ } hash.sort.map(&:last) else hash end end end # This is the default encoder for Faraday requests. # Using this encoder, parameters will be encoded respecting their structure, # so you can send objects such as Arrays or Hashes as parameters # for your requests. module NestedParamsEncoder class << self attr_accessor :sort_params, :array_indices extend Forwardable def_delegators :'Faraday::Utils', :escape, :unescape end # Useful default for OAuth and caching. @sort_params = true @array_indices = false extend EncodeMethods extend DecodeMethods end end faraday-2.10.0/lib/faraday/error.rb000066400000000000000000000120361464273144400170470ustar00rootroot00000000000000# frozen_string_literal: true # Faraday namespace. module Faraday # Faraday error base class. class Error < StandardError attr_reader :response, :wrapped_exception def initialize(exc = nil, response = nil) @wrapped_exception = nil unless defined?(@wrapped_exception) @response = nil unless defined?(@response) super(exc_msg_and_response!(exc, response)) end def backtrace if @wrapped_exception @wrapped_exception.backtrace else super end end def inspect inner = +'' inner << " wrapped=#{@wrapped_exception.inspect}" if @wrapped_exception inner << " response=#{@response.inspect}" if @response inner << " #{super}" if inner.empty? %(#<#{self.class}#{inner}>) end def response_status return unless @response @response.is_a?(Faraday::Response) ? @response.status : @response[:status] end def response_headers return unless @response @response.is_a?(Faraday::Response) ? @response.headers : @response[:headers] end def response_body return unless @response @response.is_a?(Faraday::Response) ? @response.body : @response[:body] end protected # Pulls out potential parent exception and response hash, storing them in # instance variables. # exc - Either an Exception, a string message, or a response hash. # response - Hash # :status - Optional integer HTTP response status # :headers - String key/value hash of HTTP response header # values. # :body - Optional string HTTP response body. # :request - Hash # :method - Symbol with the request HTTP method. # :url - URI object with the url requested. # :url_path - String with the url path requested. # :params - String key/value hash of query params # present in the request. # :headers - String key/value hash of HTTP request # header values. # :body - String HTTP request body. # # If a subclass has to call this, then it should pass a string message # to `super`. See NilStatusError. def exc_msg_and_response!(exc, response = nil) if @response.nil? && @wrapped_exception.nil? @wrapped_exception, msg, @response = exc_msg_and_response(exc, response) return msg end exc.to_s end # Pulls out potential parent exception and response hash. def exc_msg_and_response(exc, response = nil) return [exc, exc.message, response] if exc.respond_to?(:backtrace) return [nil, "the server responded with status #{exc[:status]}", exc] \ if exc.respond_to?(:each_key) [nil, exc.to_s, response] end end # Faraday client error class. Represents 4xx status responses. class ClientError < Error end # Raised by Faraday::Response::RaiseError in case of a 400 response. class BadRequestError < ClientError end # Raised by Faraday::Response::RaiseError in case of a 401 response. class UnauthorizedError < ClientError end # Raised by Faraday::Response::RaiseError in case of a 403 response. class ForbiddenError < ClientError end # Raised by Faraday::Response::RaiseError in case of a 404 response. class ResourceNotFound < ClientError end # Raised by Faraday::Response::RaiseError in case of a 407 response. class ProxyAuthError < ClientError end # Raised by Faraday::Response::RaiseError in case of a 408 response. class RequestTimeoutError < ClientError end # Raised by Faraday::Response::RaiseError in case of a 409 response. class ConflictError < ClientError end # Raised by Faraday::Response::RaiseError in case of a 422 response. class UnprocessableEntityError < ClientError end # Raised by Faraday::Response::RaiseError in case of a 429 response. class TooManyRequestsError < ClientError end # Faraday server error class. Represents 5xx status responses. class ServerError < Error end # A unified client error for timeouts. class TimeoutError < ServerError def initialize(exc = 'timeout', response = nil) super(exc, response) end end # Raised by Faraday::Response::RaiseError in case of a nil status in response. class NilStatusError < ServerError def initialize(exc, response = nil) exc_msg_and_response!(exc, response) super('http status could not be derived from the server response') end end # A unified error for failed connections. class ConnectionFailed < Error end # A unified client error for SSL errors. class SSLError < Error end # Raised by middlewares that parse the response, like the JSON response middleware. class ParsingError < Error end # Raised by Faraday::Middleware and subclasses when invalid default_options are used class InitializationError < Error end end faraday-2.10.0/lib/faraday/logging/000077500000000000000000000000001464273144400170155ustar00rootroot00000000000000faraday-2.10.0/lib/faraday/logging/formatter.rb000066400000000000000000000060441464273144400213510ustar00rootroot00000000000000# frozen_string_literal: true require 'pp' # This require is necessary for Hash#pretty_inspect to work, do not remove it, people rely on it. module Faraday module Logging # Serves as an integration point to customize logging class Formatter extend Forwardable DEFAULT_OPTIONS = { headers: true, bodies: false, errors: false, log_level: :info }.freeze def initialize(logger:, options:) @logger = logger @options = DEFAULT_OPTIONS.merge(options) unless %i[debug info warn error fatal].include?(@options[:log_level]) @options[:log_level] = :info end @filter = [] end def_delegators :@logger, :debug, :info, :warn, :error, :fatal def request(env) public_send(log_level, 'request') do "#{env.method.upcase} #{apply_filters(env.url.to_s)}" end log_headers('request', env.request_headers) if log_headers?(:request) log_body('request', env[:body]) if env[:body] && log_body?(:request) end def response(env) public_send(log_level, 'response') { "Status #{env.status}" } log_headers('response', env.response_headers) if log_headers?(:response) log_body('response', env[:body]) if env[:body] && log_body?(:response) end def exception(exc) return unless log_errors? public_send(log_level, 'error') { exc.full_message } log_headers('error', exc.response_headers) if exc.respond_to?(:response_headers) && log_headers?(:error) return unless exc.respond_to?(:response_body) && exc.response_body && log_body?(:error) log_body('error', exc.response_body) end def filter(filter_word, filter_replacement) @filter.push([filter_word, filter_replacement]) end private def dump_headers(headers) return if headers.nil? headers.map { |k, v| "#{k}: #{v.inspect}" }.join("\n") end def dump_body(body) if body.respond_to?(:to_str) body.to_str else pretty_inspect(body) end end def pretty_inspect(body) body.pretty_inspect end def log_headers?(type) case @options[:headers] when Hash @options[:headers][type] else @options[:headers] end end def log_body?(type) case @options[:bodies] when Hash @options[:bodies][type] else @options[:bodies] end end def log_errors? @options[:errors] end def apply_filters(output) @filter.each do |pattern, replacement| output = output.to_s.gsub(pattern, replacement) end output end def log_level @options[:log_level] end def log_headers(type, headers) public_send(log_level, type) { apply_filters(dump_headers(headers)) } end def log_body(type, body) public_send(log_level, type) { apply_filters(dump_body(body)) } end end end end faraday-2.10.0/lib/faraday/methods.rb000066400000000000000000000002321464273144400173540ustar00rootroot00000000000000# frozen_string_literal: true module Faraday METHODS_WITH_QUERY = %w[get head delete trace].freeze METHODS_WITH_BODY = %w[post put patch].freeze end faraday-2.10.0/lib/faraday/middleware.rb000066400000000000000000000041121464273144400200270ustar00rootroot00000000000000# frozen_string_literal: true require 'monitor' module Faraday # Middleware is the basic base class of any Faraday middleware. class Middleware extend MiddlewareRegistry attr_reader :app, :options DEFAULT_OPTIONS = {}.freeze def initialize(app = nil, options = {}) @app = app @options = self.class.default_options.merge(options) end class << self # Faraday::Middleware::default_options= allows user to set default options at the Faraday::Middleware # class level. # # @example Set the Faraday::Response::RaiseError option, `include_request` to `false` # my_app/config/initializers/my_faraday_middleware.rb # # Faraday::Response::RaiseError.default_options = { include_request: false } # def default_options=(options = {}) validate_default_options(options) lock.synchronize do @default_options = default_options.merge(options) end end # default_options attr_reader that initializes class instance variable # with the values of any Faraday::Middleware defaults, and merges with # subclass defaults def default_options @default_options ||= DEFAULT_OPTIONS.merge(self::DEFAULT_OPTIONS) end private def lock @lock ||= Monitor.new end def validate_default_options(options) invalid_keys = options.keys.reject { |opt| self::DEFAULT_OPTIONS.key?(opt) } return unless invalid_keys.any? raise(Faraday::InitializationError, "Invalid options provided. Keys not found in #{self}::DEFAULT_OPTIONS: #{invalid_keys.join(', ')}") end end def call(env) on_request(env) if respond_to?(:on_request) app.call(env).on_complete do |environment| on_complete(environment) if respond_to?(:on_complete) end rescue StandardError => e on_error(e) if respond_to?(:on_error) raise end def close if app.respond_to?(:close) app.close else warn "#{app} does not implement \#close!" end end end end faraday-2.10.0/lib/faraday/middleware_registry.rb000066400000000000000000000042041464273144400217610ustar00rootroot00000000000000# frozen_string_literal: true require 'monitor' module Faraday # Adds the ability for other modules to register and lookup # middleware classes. module MiddlewareRegistry def registered_middleware @registered_middleware ||= {} end # Register middleware class(es) on the current module. # # @param mappings [Hash] Middleware mappings from a lookup symbol to a middleware class. # @return [void] # # @example Lookup by a constant # # module Faraday # class Whatever < Middleware # # Middleware looked up by :foo returns Faraday::Whatever::Foo. # register_middleware(foo: Whatever) # end # end def register_middleware(**mappings) middleware_mutex do registered_middleware.update(mappings) end end # Unregister a previously registered middleware class. # # @param key [Symbol] key for the registered middleware. def unregister_middleware(key) registered_middleware.delete(key) end # Lookup middleware class with a registered Symbol shortcut. # # @param key [Symbol] key for the registered middleware. # @return [Class] a middleware Class. # @raise [Faraday::Error] if given key is not registered # # @example # # module Faraday # class Whatever < Middleware # register_middleware(foo: Whatever) # end # end # # Faraday::Middleware.lookup_middleware(:foo) # # => Faraday::Whatever def lookup_middleware(key) load_middleware(key) || raise(Faraday::Error, "#{key.inspect} is not registered on #{self}") end private def middleware_mutex(&block) @middleware_mutex ||= Monitor.new @middleware_mutex.synchronize(&block) end def load_middleware(key) value = registered_middleware[key] case value when Module value when Symbol, String middleware_mutex do @registered_middleware[key] = const_get(value) end when Proc middleware_mutex do @registered_middleware[key] = value.call end end end end end faraday-2.10.0/lib/faraday/options.rb000066400000000000000000000111301464273144400174030ustar00rootroot00000000000000# frozen_string_literal: true module Faraday # Subclasses Struct with some special helpers for converting from a Hash to # a Struct. class Options < Struct # Public def self.from(value) value ? new.update(value) : new end # Public def each return to_enum(:each) unless block_given? members.each do |key| yield(key.to_sym, send(key)) end end # Public def update(obj) obj.each do |key, value| sub_options = self.class.options_for(key) if sub_options new_value = sub_options.from(value) if value elsif value.is_a?(Hash) new_value = value.dup else new_value = value end send(:"#{key}=", new_value) unless new_value.nil? end self end # Public def delete(key) value = send(key) send(:"#{key}=", nil) value end # Public def clear members.each { |member| delete(member) } end # Public def merge!(other) other.each do |key, other_value| self_value = send(key) sub_options = self.class.options_for(key) new_value = if self_value && sub_options && other_value self_value.merge(other_value) else other_value end send(:"#{key}=", new_value) unless new_value.nil? end self end # Public def merge(other) dup.merge!(other) end # Public def deep_dup self.class.from(self) end # Public def fetch(key, *args) unless symbolized_key_set.include?(key.to_sym) key_setter = "#{key}=" if !args.empty? send(key_setter, args.first) elsif block_given? send(key_setter, yield(key)) else raise self.class.fetch_error_class, "key not found: #{key.inspect}" end end send(key) end # Public def values_at(*keys) keys.map { |key| send(key) } end # Public def keys members.reject { |member| send(member).nil? } end # Public def empty? keys.empty? end # Public def each_key(&block) return to_enum(:each_key) unless block keys.each(&block) end # Public def key?(key) keys.include?(key) end alias has_key? key? # Public def each_value(&block) return to_enum(:each_value) unless block values.each(&block) end # Public def value?(value) values.include?(value) end alias has_value? value? # Public def to_hash hash = {} members.each do |key| value = send(key) hash[key.to_sym] = value unless value.nil? end hash end # Internal def inspect values = [] members.each do |member| value = send(member) values << "#{member}=#{value.inspect}" if value end values = values.empty? ? '(empty)' : values.join(', ') %(#<#{self.class} #{values}>) end # Internal def self.options(mapping) attribute_options.update(mapping) end # Internal def self.options_for(key) attribute_options[key] end # Internal def self.attribute_options @attribute_options ||= {} end def self.memoized(key, &block) unless block raise ArgumentError, '#memoized must be called with a block' end memoized_attributes[key.to_sym] = block class_eval <<-RUBY, __FILE__, __LINE__ + 1 remove_method(key) if method_defined?(key, false) def #{key}() self[:#{key}]; end RUBY end def self.memoized_attributes @memoized_attributes ||= {} end def [](key) key = key.to_sym if (method = self.class.memoized_attributes[key]) super(key) || (self[key] = instance_eval(&method)) else super end end def symbolized_key_set @symbolized_key_set ||= Set.new(keys.map(&:to_sym)) end def self.inherited(subclass) super subclass.attribute_options.update(attribute_options) subclass.memoized_attributes.update(memoized_attributes) end def self.fetch_error_class @fetch_error_class ||= if Object.const_defined?(:KeyError) ::KeyError else ::IndexError end end end end require 'faraday/options/request_options' require 'faraday/options/ssl_options' require 'faraday/options/proxy_options' require 'faraday/options/connection_options' require 'faraday/options/env' faraday-2.10.0/lib/faraday/options/000077500000000000000000000000001464273144400170625ustar00rootroot00000000000000faraday-2.10.0/lib/faraday/options/connection_options.rb000066400000000000000000000013011464273144400233140ustar00rootroot00000000000000# frozen_string_literal: true module Faraday # @!parse # # ConnectionOptions contains the configurable properties for a Faraday # # connection object. # class ConnectionOptions < Options; end ConnectionOptions = Options.new(:request, :proxy, :ssl, :builder, :url, :parallel_manager, :params, :headers, :builder_class) do options request: RequestOptions, ssl: SSLOptions memoized(:request) { self.class.options_for(:request).new } memoized(:ssl) { self.class.options_for(:ssl).new } memoized(:builder_class) { RackBuilder } def new_builder(block) builder_class.new(&block) end end end faraday-2.10.0/lib/faraday/options/env.rb000066400000000000000000000133361464273144400202050ustar00rootroot00000000000000# frozen_string_literal: true module Faraday # @!parse # # @!attribute method # # @return [Symbol] HTTP method (`:get`, `:post`) # # # # @!attribute body # # @return [String] The request body that will eventually be converted to a # # string. # # # # @!attribute url # # @return [URI] URI instance for the current request. # # # # @!attribute request # # @return [Hash] options for configuring the request. # # Options for configuring the request. # # # # - `:timeout` - time limit for the entire request (Integer in # # seconds) # # - `:open_timeout` - time limit for just the connection phase (e.g. # # handshake) (Integer in seconds) # # - `:read_timeout` - time limit for the first response byte received from # # the server (Integer in seconds) # # - `:write_timeout` - time limit for the client to send the request to the # # server (Integer in seconds) # # - `:on_data` - Proc for streaming # # - `:proxy` - Hash of proxy options # # - `:uri` - Proxy server URI # # - `:user` - Proxy server username # # - `:password` - Proxy server password # # # # @!attribute request_headers # # @return [Hash] HTTP Headers to be sent to the server. # # # # @!attribute ssl # # @return [Hash] options for configuring SSL requests # # # # @!attribute parallel_manager # # @return [Object] sent if the connection is in parallel mode # # # # @!attribute params # # @return [Hash] # # # # @!attribute response # # @return [Response] # # # # @!attribute response_headers # # @return [Hash] HTTP headers from the server # # # # @!attribute status # # @return [Integer] HTTP response status code # # # # @!attribute reason_phrase # # @return [String] # class Env < Options; end Env = Options.new(:method, :request_body, :url, :request, :request_headers, :ssl, :parallel_manager, :params, :response, :response_headers, :status, :reason_phrase, :response_body) do const_set(:ContentLength, 'Content-Length') const_set(:StatusesWithoutBody, Set.new([204, 304])) const_set(:SuccessfulStatuses, (200..299)) # A Set of HTTP verbs that typically send a body. If no body is set for # these requests, the Content-Length header is set to 0. const_set(:MethodsWithBodies, Set.new(Faraday::METHODS_WITH_BODY.map(&:to_sym))) options request: RequestOptions, request_headers: Utils::Headers, response_headers: Utils::Headers extend Forwardable def_delegators :request, :params_encoder # Build a new Env from given value. Respects and updates `custom_members`. # # @param value [Object] a value fitting Option.from(v). # @return [Env] from given value def self.from(value) env = super(value) if value.respond_to?(:custom_members) env.custom_members.update(value.custom_members) end env end # @param key [Object] def [](key) return self[current_body] if key == :body if in_member_set?(key) super(key) else custom_members[key] end end # @param key [Object] # @param value [Object] def []=(key, value) if key == :body super(current_body, value) return end if in_member_set?(key) super(key, value) else custom_members[key] = value end end def current_body !!status ? :response_body : :request_body end def body self[:body] end def body=(value) self[:body] = value end # @return [Boolean] true if status is in the set of {SuccessfulStatuses}. def success? Env::SuccessfulStatuses.include?(status) end # @return [Boolean] true if there's no body yet, and the method is in the # set of {Env::MethodsWithBodies}. def needs_body? !body && Env::MethodsWithBodies.include?(method) end # Sets content length to zero and the body to the empty string. def clear_body request_headers[Env::ContentLength] = '0' self.body = +'' end # @return [Boolean] true if the status isn't in the set of # {Env::StatusesWithoutBody}. def parse_body? !Env::StatusesWithoutBody.include?(status) end # @return [Boolean] true if there is a parallel_manager def parallel? !!parallel_manager end def inspect attrs = [nil] members.each do |mem| if (value = send(mem)) attrs << "@#{mem}=#{value.inspect}" end end attrs << "@custom=#{custom_members.inspect}" unless custom_members.empty? %(#<#{self.class}#{attrs.join(' ')}>) end def stream_response? request.stream_response? end def stream_response(&block) size = 0 yielded = false block_result = block.call do |chunk| if chunk.bytesize.positive? || size.positive? yielded = true size += chunk.bytesize request.on_data.call(chunk, size, self) end end request.on_data.call(+'', 0, self) unless yielded block_result end # @private def custom_members @custom_members ||= {} end # @private if members.first.is_a?(Symbol) def in_member_set?(key) self.class.member_set.include?(key.to_sym) end else def in_member_set?(key) self.class.member_set.include?(key.to_s) end end # @private def self.member_set @member_set ||= Set.new(members) end end end faraday-2.10.0/lib/faraday/options/proxy_options.rb000066400000000000000000000021251464273144400223430ustar00rootroot00000000000000# frozen_string_literal: true module Faraday # @!parse # # ProxyOptions contains the configurable properties for the proxy # # configuration used when making an HTTP request. # class ProxyOptions < Options; end ProxyOptions = Options.new(:uri, :user, :password) do extend Forwardable def_delegators :uri, :scheme, :scheme=, :host, :host=, :port, :port=, :path, :path= def self.from(value) case value when '' value = nil when String # URIs without a scheme should default to http (like 'example:123'). # This fixes #1282 and prevents a silent failure in some adapters. value = "http://#{value}" unless value.include?('://') value = { uri: Utils.URI(value) } when URI value = { uri: value } when Hash, Options if (uri = value.delete(:uri)) value[:uri] = Utils.URI(uri) end end super(value) end memoized(:user) { uri&.user && Utils.unescape(uri.user) } memoized(:password) { uri&.password && Utils.unescape(uri.password) } end end faraday-2.10.0/lib/faraday/options/request_options.rb000066400000000000000000000012521464273144400226520ustar00rootroot00000000000000# frozen_string_literal: true module Faraday # @!parse # # RequestOptions contains the configurable properties for a Faraday request. # class RequestOptions < Options; end RequestOptions = Options.new(:params_encoder, :proxy, :bind, :timeout, :open_timeout, :read_timeout, :write_timeout, :boundary, :oauth, :context, :on_data) do def []=(key, value) if key && key.to_sym == :proxy super(key, value ? ProxyOptions.from(value) : nil) else super(key, value) end end def stream_response? on_data.is_a?(Proc) end end end faraday-2.10.0/lib/faraday/options/ssl_options.rb000066400000000000000000000052171464273144400217700ustar00rootroot00000000000000# frozen_string_literal: true module Faraday # @!parse # # SSL-related options. # # # # @!attribute verify # # @return [Boolean] whether to verify SSL certificates or not # # # # @!attribute verify_hostname # # @return [Boolean] whether to enable hostname verification on server certificates # # during the handshake or not (see https://github.com/ruby/openssl/pull/60) # # # # @!attribute ca_file # # @return [String] CA file # # # # @!attribute ca_path # # @return [String] CA path # # # # @!attribute verify_mode # # @return [Integer] Any `OpenSSL::SSL::` constant (see https://ruby-doc.org/stdlib-2.5.1/libdoc/openssl/rdoc/OpenSSL/SSL.html) # # # # @!attribute cert_store # # @return [OpenSSL::X509::Store] certificate store # # # # @!attribute client_cert # # @return [String, OpenSSL::X509::Certificate] client certificate # # # # @!attribute client_key # # @return [String, OpenSSL::PKey::RSA, OpenSSL::PKey::DSA] client key # # # # @!attribute certificate # # @return [OpenSSL::X509::Certificate] certificate (Excon only) # # # # @!attribute private_key # # @return [OpenSSL::PKey::RSA, OpenSSL::PKey::DSA] private key (Excon only) # # # # @!attribute verify_depth # # @return [Integer] maximum depth for the certificate chain verification # # # # @!attribute version # # @return [String, Symbol] SSL version (see https://ruby-doc.org/stdlib-2.5.1/libdoc/openssl/rdoc/OpenSSL/SSL/SSLContext.html#method-i-ssl_version-3D) # # # # @!attribute min_version # # @return [String, Symbol] minimum SSL version (see https://ruby-doc.org/stdlib-2.5.1/libdoc/openssl/rdoc/OpenSSL/SSL/SSLContext.html#method-i-min_version-3D) # # # # @!attribute max_version # # @return [String, Symbol] maximum SSL version (see https://ruby-doc.org/stdlib-2.5.1/libdoc/openssl/rdoc/OpenSSL/SSL/SSLContext.html#method-i-max_version-3D) # class SSLOptions < Options; end SSLOptions = Options.new(:verify, :verify_hostname, :ca_file, :ca_path, :verify_mode, :cert_store, :client_cert, :client_key, :certificate, :private_key, :verify_depth, :version, :min_version, :max_version) do # @return [Boolean] true if should verify def verify? verify != false end # @return [Boolean] true if should not verify def disable? !verify? end # @return [Boolean] true if should verify_hostname def verify_hostname? verify_hostname != false end end end faraday-2.10.0/lib/faraday/parameters.rb000066400000000000000000000002251464273144400200560ustar00rootroot00000000000000# frozen_string_literal: true require 'forwardable' require 'faraday/encoders/nested_params_encoder' require 'faraday/encoders/flat_params_encoder' faraday-2.10.0/lib/faraday/rack_builder.rb000066400000000000000000000160671464273144400203540ustar00rootroot00000000000000# frozen_string_literal: true require 'faraday/adapter_registry' module Faraday # A Builder that processes requests into responses by passing through an inner # middleware stack (heavily inspired by Rack). # # @example # Faraday::Connection.new(url: 'http://httpbingo.org') do |builder| # builder.request :url_encoded # Faraday::Request::UrlEncoded # builder.adapter :net_http # Faraday::Adapter::NetHttp # end class RackBuilder # Used to detect missing arguments NO_ARGUMENT = Object.new attr_accessor :handlers # Error raised when trying to modify the stack after calling `lock!` class StackLocked < RuntimeError; end # borrowed from ActiveSupport::Dependencies::Reference & # ActionDispatch::MiddlewareStack::Middleware class Handler REGISTRY = Faraday::AdapterRegistry.new attr_reader :name ruby2_keywords def initialize(klass, *args, &block) @name = klass.to_s REGISTRY.set(klass) if klass.respond_to?(:name) @args = args @block = block end def klass REGISTRY.get(@name) end def inspect @name end def ==(other) if other.is_a? Handler name == other.name elsif other.respond_to? :name klass == other else @name == other.to_s end end def build(app = nil) klass.new(app, *@args, &@block) end end def initialize(&block) @adapter = nil @handlers = [] build(&block) end def initialize_dup(original) super @adapter = original.adapter @handlers = original.handlers.dup end def build raise_if_locked block_given? ? yield(self) : request(:url_encoded) adapter(Faraday.default_adapter, **Faraday.default_adapter_options) unless @adapter end def [](idx) @handlers[idx] end # Locks the middleware stack to ensure no further modifications are made. def lock! @handlers.freeze end def locked? @handlers.frozen? end ruby2_keywords def use(klass, *args, &block) if klass.is_a? Symbol use_symbol(Faraday::Middleware, klass, *args, &block) else raise_if_locked raise_if_adapter(klass) @handlers << self.class::Handler.new(klass, *args, &block) end end ruby2_keywords def request(key, *args, &block) use_symbol(Faraday::Request, key, *args, &block) end ruby2_keywords def response(key, *args, &block) use_symbol(Faraday::Response, key, *args, &block) end ruby2_keywords def adapter(klass = NO_ARGUMENT, *args, &block) return @adapter if klass == NO_ARGUMENT || klass.nil? klass = Faraday::Adapter.lookup_middleware(klass) if klass.is_a?(Symbol) @adapter = self.class::Handler.new(klass, *args, &block) end ## methods to push onto the various positions in the stack: ruby2_keywords def insert(index, *args, &block) raise_if_locked index = assert_index(index) handler = self.class::Handler.new(*args, &block) @handlers.insert(index, handler) end alias insert_before insert ruby2_keywords def insert_after(index, *args, &block) index = assert_index(index) insert(index + 1, *args, &block) end ruby2_keywords def swap(index, *args, &block) raise_if_locked index = assert_index(index) @handlers.delete_at(index) insert(index, *args, &block) end def delete(handler) raise_if_locked @handlers.delete(handler) end # Processes a Request into a Response by passing it through this Builder's # middleware stack. # # @param connection [Faraday::Connection] # @param request [Faraday::Request] # # @return [Faraday::Response] def build_response(connection, request) app.call(build_env(connection, request)) end # The "rack app" wrapped in middleware. All requests are sent here. # # The builder is responsible for creating the app object. After this, # the builder gets locked to ensure no further modifications are made # to the middleware stack. # # Returns an object that responds to `call` and returns a Response. def app @app ||= begin lock! ensure_adapter! to_app end end def to_app # last added handler is the deepest and thus closest to the inner app # adapter is always the last one @handlers.reverse.inject(@adapter.build) do |app, handler| handler.build(app) end end def ==(other) other.is_a?(self.class) && @handlers == other.handlers && @adapter == other.adapter end # ENV Keys # :http_method - a symbolized request HTTP method (:get, :post) # :body - the request body that will eventually be converted to a string. # :url - URI instance for the current request. # :status - HTTP response status code # :request_headers - hash of HTTP Headers to be sent to the server # :response_headers - Hash of HTTP headers from the server # :parallel_manager - sent if the connection is in parallel mode # :request - Hash of options for configuring the request. # :timeout - open/read timeout Integer in seconds # :open_timeout - read timeout Integer in seconds # :proxy - Hash of proxy options # :uri - Proxy Server URI # :user - Proxy server username # :password - Proxy server password # :ssl - Hash of options for configuring SSL requests. def build_env(connection, request) exclusive_url = connection.build_exclusive_url( request.path, request.params, request.options.params_encoder ) Env.new(request.http_method, request.body, exclusive_url, request.options, request.headers, connection.ssl, connection.parallel_manager) end private LOCK_ERR = "can't modify middleware stack after making a request" MISSING_ADAPTER_ERROR = "An attempt to run a request with a Faraday::Connection without adapter has been made.\n" \ "Please set Faraday.default_adapter or provide one when initializing the connection.\n" \ 'For more info, check https://lostisland.github.io/faraday/usage/.' def raise_if_locked raise StackLocked, LOCK_ERR if locked? end def raise_if_adapter(klass) return unless is_adapter?(klass) raise 'Adapter should be set using the `adapter` method, not `use`' end def ensure_adapter! raise MISSING_ADAPTER_ERROR unless @adapter end def adapter_set? !@adapter.nil? end def is_adapter?(klass) # rubocop:disable Naming/PredicateName klass <= Faraday::Adapter end ruby2_keywords def use_symbol(mod, key, *args, &block) use(mod.lookup_middleware(key), *args, &block) end def assert_index(index) idx = index.is_a?(Integer) ? index : @handlers.index(index) raise "No such handler: #{index.inspect}" unless idx idx end end end faraday-2.10.0/lib/faraday/request.rb000066400000000000000000000074661464273144400174210ustar00rootroot00000000000000# frozen_string_literal: true module Faraday # Used to setup URLs, params, headers, and the request body in a sane manner. # # @example # @connection.post do |req| # req.url 'http://localhost', 'a' => '1' # 'http://localhost?a=1' # req.headers['b'] = '2' # Header # req.params['c'] = '3' # GET Param # req['b'] = '2' # also Header # req.body = 'abc' # end # # @!attribute http_method # @return [Symbol] the HTTP method of the Request # @!attribute path # @return [URI, String] the path # @!attribute params # @return [Hash] query parameters # @!attribute headers # @return [Faraday::Utils::Headers] headers # @!attribute body # @return [String] body # @!attribute options # @return [RequestOptions] options Request = Struct.new(:http_method, :path, :params, :headers, :body, :options) do extend MiddlewareRegistry alias_method :member_get, :[] private :member_get alias_method :member_set, :[]= private :member_set # @param request_method [String] # @yield [request] for block customization, if block given # @yieldparam request [Request] # @return [Request] def self.create(request_method) new(request_method).tap do |request| yield(request) if block_given? end end remove_method :params= # Replace params, preserving the existing hash type. # # @param hash [Hash] new params def params=(hash) if params params.replace hash else member_set(:params, hash) end end remove_method :headers= # Replace request headers, preserving the existing hash type. # # @param hash [Hash] new headers def headers=(hash) if headers headers.replace hash else member_set(:headers, hash) end end # Update path and params. # # @param path [URI, String] # @param params [Hash, nil] # @return [void] def url(path, params = nil) if path.respond_to? :query if (query = path.query) path = path.dup path.query = nil end else anchor_index = path.index('#') path = path.slice(0, anchor_index) unless anchor_index.nil? path, query = path.split('?', 2) end self.path = path self.params.merge_query query, options.params_encoder self.params.update(params) if params end # @param key [Object] key to look up in headers # @return [Object] value of the given header name def [](key) headers[key] end # @param key [Object] key of header to write # @param value [Object] value of header def []=(key, value) headers[key] = value end # Marshal serialization support. # # @return [Hash] the hash ready to be serialized in Marshal. def marshal_dump { http_method: http_method, body: body, headers: headers, path: path, params: params, options: options } end # Marshal serialization support. # Restores the instance variables according to the +serialised+. # @param serialised [Hash] the serialised object. def marshal_load(serialised) self.http_method = serialised[:http_method] self.body = serialised[:body] self.headers = serialised[:headers] self.path = serialised[:path] self.params = serialised[:params] self.options = serialised[:options] end # @return [Env] the Env for this Request def to_env(connection) Env.new(http_method, body, connection.build_exclusive_url(path, params), options, headers, connection.ssl, connection.parallel_manager) end end end require 'faraday/request/authorization' require 'faraday/request/instrumentation' require 'faraday/request/json' require 'faraday/request/url_encoded' faraday-2.10.0/lib/faraday/request/000077500000000000000000000000001464273144400170575ustar00rootroot00000000000000faraday-2.10.0/lib/faraday/request/authorization.rb000066400000000000000000000035121464273144400223050ustar00rootroot00000000000000# frozen_string_literal: true module Faraday class Request # Request middleware for the Authorization HTTP header class Authorization < Faraday::Middleware KEY = 'Authorization' # @param app [#call] # @param type [String, Symbol] Type of Authorization # @param params [Array] parameters to build the Authorization header. # If the type is `:basic`, then these can be a login and password pair. # Otherwise, a single value is expected that will be appended after the type. # This value can be a proc or an object responding to `.call`, in which case # it will be invoked on each request. def initialize(app, type, *params) @type = type @params = params super(app) end # @param env [Faraday::Env] def on_request(env) return if env.request_headers[KEY] env.request_headers[KEY] = header_from(@type, env, *@params) end private # @param type [String, Symbol] # @param env [Faraday::Env] # @param params [Array] # @return [String] a header value def header_from(type, env, *params) if type.to_s.casecmp('basic').zero? && params.size == 2 Utils.basic_header_from(*params) elsif params.size != 1 raise ArgumentError, "Unexpected params received (got #{params.size} instead of 1)" else value = params.first if (value.is_a?(Proc) && value.arity == 1) || (value.respond_to?(:call) && value.method(:call).arity == 1) value = value.call(env) elsif value.is_a?(Proc) || value.respond_to?(:call) value = value.call end "#{type} #{value}" end end end end end Faraday::Request.register_middleware(authorization: Faraday::Request::Authorization) faraday-2.10.0/lib/faraday/request/instrumentation.rb000066400000000000000000000035711464273144400226550ustar00rootroot00000000000000# frozen_string_literal: true module Faraday class Request # Middleware for instrumenting Requests. class Instrumentation < Faraday::Middleware # Options class used in Request::Instrumentation class. Options = Faraday::Options.new(:name, :instrumenter) do remove_method :name # @return [String] def name self[:name] ||= 'request.faraday' end remove_method :instrumenter # @return [Class] def instrumenter self[:instrumenter] ||= ActiveSupport::Notifications end end # Instruments requests using Active Support. # # Measures time spent only for synchronous requests. # # @example Using ActiveSupport::Notifications to measure time spent # for Faraday requests. # ActiveSupport::Notifications # .subscribe('request.faraday') do |name, starts, ends, _, env| # url = env[:url] # http_method = env[:method].to_s.upcase # duration = ends - starts # $stderr.puts '[%s] %s %s (%.3f s)' % # [url.host, http_method, url.request_uri, duration] # end # @param app [#call] # @param options [nil, Hash] Options hash # @option options [String] :name ('request.faraday') # Name of the instrumenter # @option options [Class] :instrumenter (ActiveSupport::Notifications) # Active Support instrumenter class. def initialize(app, options = nil) super(app) @name, @instrumenter = Options.from(options) .values_at(:name, :instrumenter) end # @param env [Faraday::Env] def call(env) @instrumenter.instrument(@name, env) do @app.call(env) end end end end end Faraday::Request.register_middleware(instrumentation: Faraday::Request::Instrumentation) faraday-2.10.0/lib/faraday/request/json.rb000066400000000000000000000036321464273144400203610ustar00rootroot00000000000000# frozen_string_literal: true require 'json' module Faraday class Request # Request middleware that encodes the body as JSON. # # Processes only requests with matching Content-type or those without a type. # If a request doesn't have a type but has a body, it sets the Content-type # to JSON MIME-type. # # Doesn't try to encode bodies that already are in string form. class Json < Middleware MIME_TYPE = 'application/json' MIME_TYPE_REGEX = %r{^application/(vnd\..+\+)?json$} def on_request(env) match_content_type(env) do |data| env[:body] = encode(data) end end private def encode(data) if options[:encoder].is_a?(Array) && options[:encoder].size >= 2 options[:encoder][0].public_send(options[:encoder][1], data) elsif options[:encoder].respond_to?(:dump) options[:encoder].dump(data) else ::JSON.generate(data) end end def match_content_type(env) return unless process_request?(env) env[:request_headers][CONTENT_TYPE] ||= MIME_TYPE yield env[:body] unless env[:body].respond_to?(:to_str) end def process_request?(env) type = request_type(env) body?(env) && (type.empty? || type.match?(MIME_TYPE_REGEX)) end def body?(env) body = env[:body] case body when true, false true when nil # NOTE: nil can be converted to `"null"`, but this middleware doesn't process `nil` for the compatibility. false else !(body.respond_to?(:to_str) && body.empty?) end end def request_type(env) type = env[:request_headers][CONTENT_TYPE].to_s type = type.split(';', 2).first if type.index(';') type end end end end Faraday::Request.register_middleware(json: Faraday::Request::Json) faraday-2.10.0/lib/faraday/request/url_encoded.rb000066400000000000000000000033161464273144400216720ustar00rootroot00000000000000# frozen_string_literal: true module Faraday class Request # Middleware for supporting urlencoded requests. class UrlEncoded < Faraday::Middleware unless defined?(::Faraday::Request::UrlEncoded::CONTENT_TYPE) CONTENT_TYPE = 'Content-Type' end class << self attr_accessor :mime_type end self.mime_type = 'application/x-www-form-urlencoded' # Encodes as "application/x-www-form-urlencoded" if not already encoded or # of another type. # # @param env [Faraday::Env] def call(env) match_content_type(env) do |data| params = Faraday::Utils::ParamsHash[data] env.body = params.to_query(env.params_encoder) end @app.call env end # @param env [Faraday::Env] # @yield [request_body] Body of the request def match_content_type(env) return unless process_request?(env) env.request_headers[CONTENT_TYPE] ||= self.class.mime_type return if env.body.respond_to?(:to_str) || env.body.respond_to?(:read) yield(env.body) end # @param env [Faraday::Env] # # @return [Boolean] True if the request has a body and its Content-Type is # urlencoded. def process_request?(env) type = request_type(env) env.body && (type.empty? || (type == self.class.mime_type)) end # @param env [Faraday::Env] # # @return [String] def request_type(env) type = env.request_headers[CONTENT_TYPE].to_s type = type.split(';', 2).first if type.index(';') type end end end end Faraday::Request.register_middleware(url_encoded: Faraday::Request::UrlEncoded) faraday-2.10.0/lib/faraday/response.rb000066400000000000000000000034771464273144400175650ustar00rootroot00000000000000# frozen_string_literal: true require 'forwardable' module Faraday # Response represents an HTTP response from making an HTTP request. class Response extend Forwardable extend MiddlewareRegistry def initialize(env = nil) @env = Env.from(env) if env @on_complete_callbacks = [] end attr_reader :env def status finished? ? env.status : nil end def reason_phrase finished? ? env.reason_phrase : nil end def headers finished? ? env.response_headers : {} end def_delegator :headers, :[] def body finished? ? env.body : nil end def finished? !!env end def on_complete(&block) if finished? yield(env) else @on_complete_callbacks << block end self end def finish(env) raise 'response already finished' if finished? @env = env.is_a?(Env) ? env : Env.from(env) @on_complete_callbacks.each { |callback| callback.call(@env) } self end def success? finished? && env.success? end def to_hash { status: env.status, body: env.body, response_headers: env.response_headers, url: env.url } end # because @on_complete_callbacks cannot be marshalled def marshal_dump finished? ? to_hash : nil end def marshal_load(env) @env = Env.from(env) end # Expand the env with more properties, without overriding existing ones. # Useful for applying request params after restoring a marshalled Response. def apply_request(request_env) raise "response didn't finish yet" unless finished? @env = Env.from(request_env).update(@env) self end end end require 'faraday/response/json' require 'faraday/response/logger' require 'faraday/response/raise_error' faraday-2.10.0/lib/faraday/response/000077500000000000000000000000001464273144400172255ustar00rootroot00000000000000faraday-2.10.0/lib/faraday/response/json.rb000066400000000000000000000041151464273144400205240ustar00rootroot00000000000000# frozen_string_literal: true require 'json' module Faraday class Response # Parse response bodies as JSON. class Json < Middleware def initialize(app = nil, parser_options: nil, content_type: /\bjson$/, preserve_raw: false) super(app) @parser_options = parser_options @content_types = Array(content_type) @preserve_raw = preserve_raw process_parser_options end def on_complete(env) process_response(env) if parse_response?(env) end private def process_response(env) env[:raw_body] = env[:body] if @preserve_raw env[:body] = parse(env[:body]) rescue StandardError, SyntaxError => e raise Faraday::ParsingError.new(e, env[:response]) end def parse(body) return if body.strip.empty? decoder, method_name = @decoder_options decoder.public_send(method_name, body, @parser_options || {}) end def parse_response?(env) process_response_type?(env) && env[:body].respond_to?(:to_str) end def process_response_type?(env) type = response_type(env) @content_types.empty? || @content_types.any? do |pattern| pattern.is_a?(Regexp) ? type.match?(pattern) : type == pattern end end def response_type(env) type = env[:response_headers][CONTENT_TYPE].to_s type = type.split(';', 2).first if type.index(';') type end def process_parser_options @decoder_options = @parser_options&.delete(:decoder) @decoder_options = if @decoder_options.is_a?(Array) && @decoder_options.size >= 2 @decoder_options.slice(0, 2) elsif @decoder_options&.respond_to?(:load) # rubocop:disable Lint/RedundantSafeNavigation # In some versions of Rails, `nil` responds to `load` - hence the safe navigation check above [@decoder_options, :load] else [::JSON, :parse] end end end end end Faraday::Response.register_middleware(json: Faraday::Response::Json) faraday-2.10.0/lib/faraday/response/logger.rb000066400000000000000000000020371464273144400210330ustar00rootroot00000000000000# frozen_string_literal: true require 'forwardable' require 'logger' require 'faraday/logging/formatter' module Faraday class Response # Logger is a middleware that logs internal events in the HTTP request # lifecycle to a given Logger object. By default, this logs to STDOUT. See # Faraday::Logging::Formatter to see specifically what is logged. class Logger < Middleware def initialize(app, logger = nil, options = {}) super(app) logger ||= ::Logger.new($stdout) formatter_class = options.delete(:formatter) || Logging::Formatter @formatter = formatter_class.new(logger: logger, options: options) yield @formatter if block_given? end def call(env) @formatter.request(env) super end def on_complete(env) @formatter.response(env) end def on_error(exc) @formatter.exception(exc) if @formatter.respond_to?(:exception) end end end end Faraday::Response.register_middleware(logger: Faraday::Response::Logger) faraday-2.10.0/lib/faraday/response/raise_error.rb000066400000000000000000000054451464273144400220760ustar00rootroot00000000000000# frozen_string_literal: true module Faraday class Response # RaiseError is a Faraday middleware that raises exceptions on common HTTP # client or server error responses. class RaiseError < Middleware # rubocop:disable Naming/ConstantName ClientErrorStatuses = (400...500) ServerErrorStatuses = (500...600) # rubocop:enable Naming/ConstantName DEFAULT_OPTIONS = { include_request: true }.freeze def on_complete(env) case env[:status] when 400 raise Faraday::BadRequestError, response_values(env) when 401 raise Faraday::UnauthorizedError, response_values(env) when 403 raise Faraday::ForbiddenError, response_values(env) when 404 raise Faraday::ResourceNotFound, response_values(env) when 407 # mimic the behavior that we get with proxy requests with HTTPS msg = %(407 "Proxy Authentication Required") raise Faraday::ProxyAuthError.new(msg, response_values(env)) when 408 raise Faraday::RequestTimeoutError, response_values(env) when 409 raise Faraday::ConflictError, response_values(env) when 422 raise Faraday::UnprocessableEntityError, response_values(env) when 429 raise Faraday::TooManyRequestsError, response_values(env) when ClientErrorStatuses raise Faraday::ClientError, response_values(env) when ServerErrorStatuses raise Faraday::ServerError, response_values(env) when nil raise Faraday::NilStatusError, response_values(env) end end # Returns a hash of response data with the following keys: # - status # - headers # - body # - request # # The `request` key is omitted when the middleware is explicitly # configured with the option `include_request: false`. def response_values(env) response = { status: env.status, headers: env.response_headers, body: env.body } # Include the request data by default. If the middleware was explicitly # configured to _not_ include request data, then omit it. return response unless options[:include_request] response.merge( request: { method: env.method, url: env.url, url_path: env.url.path, params: query_params(env), headers: env.request_headers, body: env.request_body } ) end def query_params(env) env.request.params_encoder ||= Faraday::Utils.default_params_encoder env.params_encoder.decode(env.url.query) end end end end Faraday::Response.register_middleware(raise_error: Faraday::Response::RaiseError) faraday-2.10.0/lib/faraday/utils.rb000066400000000000000000000055621464273144400170640ustar00rootroot00000000000000# frozen_string_literal: true require 'uri' require 'faraday/utils/headers' require 'faraday/utils/params_hash' module Faraday # Utils contains various static helper methods. module Utils module_function def build_query(params) FlatParamsEncoder.encode(params) end def build_nested_query(params) NestedParamsEncoder.encode(params) end def default_space_encoding @default_space_encoding ||= '+' end class << self attr_writer :default_space_encoding end ESCAPE_RE = /[^a-zA-Z0-9 .~_-]/ def escape(str) str.to_s.gsub(ESCAPE_RE) do |match| "%#{match.unpack('H2' * match.bytesize).join('%').upcase}" end.gsub(' ', default_space_encoding) end def unescape(str) CGI.unescape str.to_s end DEFAULT_SEP = /[&;] */n # Adapted from Rack def parse_query(query) FlatParamsEncoder.decode(query) end def parse_nested_query(query) NestedParamsEncoder.decode(query) end def default_params_encoder @default_params_encoder ||= NestedParamsEncoder end def basic_header_from(login, pass) value = ["#{login}:#{pass}"].pack('m') # Base64 encoding value.delete!("\n") "Basic #{value}" end class << self attr_writer :default_params_encoder end # Normalize URI() behavior across Ruby versions # # url - A String or URI. # # Returns a parsed URI. def URI(url) # rubocop:disable Naming/MethodName if url.respond_to?(:host) url elsif url.respond_to?(:to_str) default_uri_parser.call(url) else raise ArgumentError, 'bad argument (expected URI object or URI string)' end end def default_uri_parser @default_uri_parser ||= Kernel.method(:URI) end def default_uri_parser=(parser) @default_uri_parser = if parser.respond_to?(:call) || parser.nil? parser else parser.method(:parse) end end # Receives a String or URI and returns just # the path with the query string sorted. def normalize_path(url) url = URI(url) (url.path.start_with?('/') ? url.path : "/#{url.path}") + (url.query ? "?#{sort_query_params(url.query)}" : '') end # Recursive hash update def deep_merge!(target, hash) hash.each do |key, value| target[key] = if value.is_a?(Hash) && (target[key].is_a?(Hash) || target[key].is_a?(Options)) deep_merge(target[key], value) else value end end target end # Recursive hash merge def deep_merge(source, hash) deep_merge!(source.dup, hash) end def sort_query_params(query) query.split('&').sort.join('&') end end end faraday-2.10.0/lib/faraday/utils/000077500000000000000000000000001464273144400165275ustar00rootroot00000000000000faraday-2.10.0/lib/faraday/utils/headers.rb000066400000000000000000000066211464273144400204740ustar00rootroot00000000000000# frozen_string_literal: true module Faraday module Utils # A case-insensitive Hash that preserves the original case of a header # when set. # # Adapted from Rack::Utils::HeaderHash class Headers < ::Hash def self.from(value) new(value) end def self.allocate new_self = super new_self.initialize_names new_self end def initialize(hash = nil) super() @names = {} update(hash || {}) end def initialize_names @names = {} end # on dup/clone, we need to duplicate @names hash def initialize_copy(other) super @names = other.names.dup end # need to synchronize concurrent writes to the shared KeyMap keymap_mutex = Mutex.new # symbol -> string mapper + cache KeyMap = Hash.new do |map, key| value = if key.respond_to?(:to_str) key else key.to_s.split('_') # user_agent: %w(user agent) .each(&:capitalize!) # => %w(User Agent) .join('-') # => "User-Agent" end keymap_mutex.synchronize { map[key] = value } end KeyMap[:etag] = 'ETag' def [](key) key = KeyMap[key] super(key) || super(@names[key.downcase]) end def []=(key, val) key = KeyMap[key] key = (@names[key.downcase] ||= key) # join multiple values with a comma val = val.to_ary.join(', ') if val.respond_to?(:to_ary) super(key, val) end def fetch(key, ...) key = KeyMap[key] key = @names.fetch(key.downcase, key) super(key, ...) end def delete(key) key = KeyMap[key] key = @names[key.downcase] return unless key @names.delete key.downcase super(key) end def dig(key, *rest) key = KeyMap[key] key = @names.fetch(key.downcase, key) super(key, *rest) end def include?(key) @names.include? key.downcase end alias has_key? include? alias member? include? alias key? include? def merge!(other) other.each { |k, v| self[k] = v } self end alias update merge! def merge(other) hash = dup hash.merge! other end def replace(other) clear @names.clear update other self end def to_hash {}.update(self) end def parse(header_string) return unless header_string && !header_string.empty? headers = header_string.split("\r\n") # Find the last set of response headers. start_index = headers.rindex { |x| x.start_with?('HTTP/') } || 0 last_response = headers.slice(start_index, headers.size) last_response .tap { |a| a.shift if a.first.start_with?('HTTP/') } .map { |h| h.split(/:\s*/, 2) } # split key and value .reject { |p| p[0].nil? } # ignore blank lines .each { |key, value| add_parsed(key, value) } end protected attr_reader :names private # Join multiple values with a comma. def add_parsed(key, value) if key?(key) self[key] = self[key].to_s self[key] << ', ' << value else self[key] = value end end end end end faraday-2.10.0/lib/faraday/utils/params_hash.rb000066400000000000000000000021621464273144400213430ustar00rootroot00000000000000# frozen_string_literal: true module Faraday module Utils # A hash with stringified keys. class ParamsHash < Hash def [](key) super(convert_key(key)) end def []=(key, value) super(convert_key(key), value) end def delete(key) super(convert_key(key)) end def include?(key) super(convert_key(key)) end alias has_key? include? alias member? include? alias key? include? def update(params) params.each do |key, value| self[key] = value end self end alias merge! update def merge(params) dup.update(params) end def replace(other) clear update(other) end def merge_query(query, encoder = nil) return self unless query && !query.empty? update((encoder || Utils.default_params_encoder).decode(query)) end def to_query(encoder = nil) (encoder || Utils.default_params_encoder).encode(self) end private def convert_key(key) key.to_s end end end end faraday-2.10.0/lib/faraday/version.rb000066400000000000000000000001071464273144400173770ustar00rootroot00000000000000# frozen_string_literal: true module Faraday VERSION = '2.10.0' end faraday-2.10.0/package-lock.json000066400000000000000000002261321464273144400164340ustar00rootroot00000000000000{ "name": "faraday-docs", "version": "0.1.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "faraday-docs", "version": "0.1.0", "license": "MIT", "dependencies": { "docsify-cli": "^4.4.4" } }, "node_modules/@sindresorhus/is": { "version": "0.14.0", "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.14.0.tgz", "integrity": "sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ==", "engines": { "node": ">=6" } }, "node_modules/@szmarczak/http-timer": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-1.1.2.tgz", "integrity": "sha512-XIB2XbzHTN6ieIjfIMV9hlVcfPU26s2vafYWQcZHWXHOxiaRZYEDKEwdl129Zyg50+foYV2jCgtrqSA6qNuNSA==", "dependencies": { "defer-to-connect": "^1.0.1" }, "engines": { "node": ">=6" } }, "node_modules/ansi-align": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-3.0.1.tgz", "integrity": "sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w==", "dependencies": { "string-width": "^4.1.0" } }, "node_modules/ansi-colors": { "version": "4.1.3", "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz", "integrity": "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==", "engines": { "node": ">=6" } }, "node_modules/ansi-regex": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", "engines": { "node": ">=8" } }, "node_modules/ansi-styles": { "version": "3.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", "dependencies": { "color-convert": "^1.9.0" }, "engines": { "node": ">=4" } }, "node_modules/anymatch": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", "dependencies": { "normalize-path": "^3.0.0", "picomatch": "^2.0.4" }, "engines": { "node": ">= 8" } }, "node_modules/binary-extensions": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", "engines": { "node": ">=8" } }, "node_modules/boxen": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/boxen/-/boxen-4.2.0.tgz", "integrity": "sha512-eB4uT9RGzg2odpER62bBwSLvUeGC+WbRjjyyFhGsKnc8wp/m0+hQsMUvUe3H2V0D5vw0nBdO1hCJoZo5mKeuIQ==", "dependencies": { "ansi-align": "^3.0.0", "camelcase": "^5.3.1", "chalk": "^3.0.0", "cli-boxes": "^2.2.0", "string-width": "^4.1.0", "term-size": "^2.1.0", "type-fest": "^0.8.1", "widest-line": "^3.1.0" }, "engines": { "node": ">=8" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/boxen/node_modules/ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dependencies": { "color-convert": "^2.0.1" }, "engines": { "node": ">=8" }, "funding": { "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, "node_modules/boxen/node_modules/chalk": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" }, "engines": { "node": ">=8" } }, "node_modules/boxen/node_modules/color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dependencies": { "color-name": "~1.1.4" }, "engines": { "node": ">=7.0.0" } }, "node_modules/boxen/node_modules/color-name": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" }, "node_modules/boxen/node_modules/has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "engines": { "node": ">=8" } }, "node_modules/boxen/node_modules/supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dependencies": { "has-flag": "^4.0.0" }, "engines": { "node": ">=8" } }, "node_modules/braces": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", "dependencies": { "fill-range": "^7.0.1" }, "engines": { "node": ">=8" } }, "node_modules/cacheable-request": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-6.1.0.tgz", "integrity": "sha512-Oj3cAGPCqOZX7Rz64Uny2GYAZNliQSqfbePrgAQ1wKAihYmCUnraBtJtKcGR4xz7wF+LoJC+ssFZvv5BgF9Igg==", "dependencies": { "clone-response": "^1.0.2", "get-stream": "^5.1.0", "http-cache-semantics": "^4.0.0", "keyv": "^3.0.0", "lowercase-keys": "^2.0.0", "normalize-url": "^4.1.0", "responselike": "^1.0.2" }, "engines": { "node": ">=8" } }, "node_modules/cacheable-request/node_modules/get-stream": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", "dependencies": { "pump": "^3.0.0" }, "engines": { "node": ">=8" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/cacheable-request/node_modules/lowercase-keys": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==", "engines": { "node": ">=8" } }, "node_modules/camelcase": { "version": "5.3.1", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", "engines": { "node": ">=6" } }, "node_modules/chalk": { "version": "2.4.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", "dependencies": { "ansi-styles": "^3.2.1", "escape-string-regexp": "^1.0.5", "supports-color": "^5.3.0" }, "engines": { "node": ">=4" } }, "node_modules/chokidar": { "version": "3.5.3", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", "funding": [ { "type": "individual", "url": "https://paulmillr.com/funding/" } ], "dependencies": { "anymatch": "~3.1.2", "braces": "~3.0.2", "glob-parent": "~5.1.2", "is-binary-path": "~2.1.0", "is-glob": "~4.0.1", "normalize-path": "~3.0.0", "readdirp": "~3.6.0" }, "engines": { "node": ">= 8.10.0" }, "optionalDependencies": { "fsevents": "~2.3.2" } }, "node_modules/ci-info": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==" }, "node_modules/cli-boxes": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-2.2.1.tgz", "integrity": "sha512-y4coMcylgSCdVinjiDBuR8PCC2bLjyGTwEmPb9NHR/QaNU6EUOXcTY/s6VjGMD6ENSEaeQYHCY0GNGS5jfMwPw==", "engines": { "node": ">=6" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/cliui": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==", "dependencies": { "string-width": "^4.2.0", "strip-ansi": "^6.0.0", "wrap-ansi": "^6.2.0" } }, "node_modules/clone-response": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.3.tgz", "integrity": "sha512-ROoL94jJH2dUVML2Y/5PEDNaSHgeOdSDicUyS7izcF63G6sTc/FTjLub4b8Il9S8S0beOfYt0TaA5qvFK+w0wA==", "dependencies": { "mimic-response": "^1.0.0" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/color-convert": { "version": "1.9.3", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", "dependencies": { "color-name": "1.1.3" } }, "node_modules/color-name": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" }, "node_modules/configstore": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/configstore/-/configstore-5.0.1.tgz", "integrity": "sha512-aMKprgk5YhBNyH25hj8wGt2+D52Sw1DRRIzqBwLp2Ya9mFmY8KPvvtvmna8SxVR9JMZ4kzMD68N22vlaRpkeFA==", "dependencies": { "dot-prop": "^5.2.0", "graceful-fs": "^4.1.2", "make-dir": "^3.0.0", "unique-string": "^2.0.0", "write-file-atomic": "^3.0.0", "xdg-basedir": "^4.0.0" }, "engines": { "node": ">=8" } }, "node_modules/connect": { "version": "3.7.0", "resolved": "https://registry.npmjs.org/connect/-/connect-3.7.0.tgz", "integrity": "sha512-ZqRXc+tZukToSNmh5C2iWMSoV3X1YUcPbqEM4DkEG5tNQXrQUZCNVGGv3IuicnkMtPfGf3Xtp8WCXs295iQ1pQ==", "dependencies": { "debug": "2.6.9", "finalhandler": "1.1.2", "parseurl": "~1.3.3", "utils-merge": "1.0.1" }, "engines": { "node": ">= 0.10.0" } }, "node_modules/connect-history-api-fallback": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/connect-history-api-fallback/-/connect-history-api-fallback-1.6.0.tgz", "integrity": "sha512-e54B99q/OUoH64zYYRf3HBP5z24G38h5D3qXu23JGRoigpX5Ss4r9ZnDk3g0Z8uQC2x2lPaJ+UlWBc1ZWBWdLg==", "engines": { "node": ">=0.8" } }, "node_modules/connect-livereload": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/connect-livereload/-/connect-livereload-0.6.1.tgz", "integrity": "sha512-3R0kMOdL7CjJpU66fzAkCe6HNtd3AavCS4m+uW4KtJjrdGPT0SQEZieAYd+cm+lJoBznNQ4lqipYWkhBMgk00g==", "engines": { "node": "*" } }, "node_modules/cp-file": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/cp-file/-/cp-file-7.0.0.tgz", "integrity": "sha512-0Cbj7gyvFVApzpK/uhCtQ/9kE9UnYpxMzaq5nQQC/Dh4iaj5fxp7iEFIullrYwzj8nf0qnsI1Qsx34hAeAebvw==", "dependencies": { "graceful-fs": "^4.1.2", "make-dir": "^3.0.0", "nested-error-stacks": "^2.0.0", "p-event": "^4.1.0" }, "engines": { "node": ">=8" } }, "node_modules/crypto-random-string": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-2.0.0.tgz", "integrity": "sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA==", "engines": { "node": ">=8" } }, "node_modules/debug": { "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "dependencies": { "ms": "2.0.0" } }, "node_modules/decamelize": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==", "engines": { "node": ">=0.10.0" } }, "node_modules/decompress-response": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz", "integrity": "sha512-BzRPQuY1ip+qDonAOz42gRm/pg9F768C+npV/4JOsxRC2sq+Rlk+Q4ZCAsOhnIaMrgarILY+RMUIvMmmX1qAEA==", "dependencies": { "mimic-response": "^1.0.0" }, "engines": { "node": ">=4" } }, "node_modules/deep-extend": { "version": "0.6.0", "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", "engines": { "node": ">=4.0.0" } }, "node_modules/defer-to-connect": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-1.1.3.tgz", "integrity": "sha512-0ISdNousHvZT2EiFlZeZAHBUvSxmKswVCEf8hW7KWgG4a8MVEu/3Vb6uWYozkjylyCxe0JBIiRB1jV45S70WVQ==" }, "node_modules/depd": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", "engines": { "node": ">= 0.8" } }, "node_modules/destroy": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", "engines": { "node": ">= 0.8", "npm": "1.2.8000 || >= 1.4.16" } }, "node_modules/docsify": { "version": "4.13.1", "resolved": "https://registry.npmjs.org/docsify/-/docsify-4.13.1.tgz", "integrity": "sha512-BsDypTBhw0mfslw9kZgAspCMZSM+sUIIDg5K/t1hNLkvbem9h64ZQc71e1IpY+iWsi/KdeqfazDfg52y2Lmm0A==", "hasInstallScript": true, "dependencies": { "marked": "^1.2.9", "medium-zoom": "^1.0.6", "opencollective-postinstall": "^2.0.2", "prismjs": "^1.27.0", "strip-indent": "^3.0.0", "tinydate": "^1.3.0", "tweezer.js": "^1.4.0" } }, "node_modules/docsify-cli": { "version": "4.4.4", "resolved": "https://registry.npmjs.org/docsify-cli/-/docsify-cli-4.4.4.tgz", "integrity": "sha512-NAZgg6b0BsDuq/Pe+P19Qb2J1d+ZVbS0eGkeCNxyu4F9/CQSsRqZqAvPJ9/0I+BCHn4sgftA2jluqhQVzKzrSA==", "dependencies": { "chalk": "^2.4.2", "connect": "^3.6.0", "connect-history-api-fallback": "^1.6.0", "connect-livereload": "^0.6.0", "cp-file": "^7.0.0", "docsify": "^4.12.2", "docsify-server-renderer": ">=4.10.0", "enquirer": "^2.3.6", "fs-extra": "^8.1.0", "get-port": "^5.0.0", "livereload": "^0.9.2", "lru-cache": "^5.1.1", "open": "^6.4.0", "serve-static": "^1.12.1", "update-notifier": "^4.1.0", "yargonaut": "^1.1.2", "yargs": "^15.3.0" }, "bin": { "docsify": "bin/docsify" }, "engines": { "node": ">= 10", "npm": ">= 6" } }, "node_modules/docsify-server-renderer": { "version": "4.13.1", "resolved": "https://registry.npmjs.org/docsify-server-renderer/-/docsify-server-renderer-4.13.1.tgz", "integrity": "sha512-XNJeCK3zp+mVO7JZFn0bH4hNBAMMC1MbuCU7CBsjLHYn4NHrjIgCBGmylzEan3/4Qm6kbSzQx8XzUK5T7GQxHw==", "dependencies": { "debug": "^4.3.3", "docsify": "^4.12.4", "node-fetch": "^2.6.6", "resolve-pathname": "^3.0.0" } }, "node_modules/docsify-server-renderer/node_modules/debug": { "version": "4.3.4", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", "dependencies": { "ms": "2.1.2" }, "engines": { "node": ">=6.0" }, "peerDependenciesMeta": { "supports-color": { "optional": true } } }, "node_modules/docsify-server-renderer/node_modules/ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" }, "node_modules/dot-prop": { "version": "5.3.0", "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.3.0.tgz", "integrity": "sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==", "dependencies": { "is-obj": "^2.0.0" }, "engines": { "node": ">=8" } }, "node_modules/duplexer3": { "version": "0.1.5", "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.5.tgz", "integrity": "sha512-1A8za6ws41LQgv9HrE/66jyC5yuSjQ3L/KOpFtoBilsAK2iA2wuS5rTt1OCzIvtS2V7nVmedsUU+DGRcjBmOYA==" }, "node_modules/ee-first": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" }, "node_modules/emoji-regex": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" }, "node_modules/encodeurl": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", "engines": { "node": ">= 0.8" } }, "node_modules/end-of-stream": { "version": "1.4.4", "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", "dependencies": { "once": "^1.4.0" } }, "node_modules/enquirer": { "version": "2.3.6", "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==", "dependencies": { "ansi-colors": "^4.1.1" }, "engines": { "node": ">=8.6" } }, "node_modules/escape-goat": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/escape-goat/-/escape-goat-2.1.1.tgz", "integrity": "sha512-8/uIhbG12Csjy2JEW7D9pHbreaVaS/OpN3ycnyvElTdwM5n6GY6W6e2IPemfvGZeUMqZ9A/3GqIZMgKnBhAw/Q==", "engines": { "node": ">=8" } }, "node_modules/escape-html": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==" }, "node_modules/escape-string-regexp": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", "engines": { "node": ">=0.8.0" } }, "node_modules/etag": { "version": "1.8.1", "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", "engines": { "node": ">= 0.6" } }, "node_modules/figlet": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/figlet/-/figlet-1.6.0.tgz", "integrity": "sha512-31EQGhCEITv6+hi2ORRPyn3bulaV9Fl4xOdR169cBzH/n1UqcxsiSB/noo6SJdD7Kfb1Ljit+IgR1USvF/XbdA==", "bin": { "figlet": "bin/index.js" }, "engines": { "node": ">= 0.4.0" } }, "node_modules/fill-range": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", "dependencies": { "to-regex-range": "^5.0.1" }, "engines": { "node": ">=8" } }, "node_modules/finalhandler": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==", "dependencies": { "debug": "2.6.9", "encodeurl": "~1.0.2", "escape-html": "~1.0.3", "on-finished": "~2.3.0", "parseurl": "~1.3.3", "statuses": "~1.5.0", "unpipe": "~1.0.0" }, "engines": { "node": ">= 0.8" } }, "node_modules/find-up": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", "dependencies": { "locate-path": "^5.0.0", "path-exists": "^4.0.0" }, "engines": { "node": ">=8" } }, "node_modules/fresh": { "version": "0.5.2", "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", "engines": { "node": ">= 0.6" } }, "node_modules/fs-extra": { "version": "8.1.0", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", "dependencies": { "graceful-fs": "^4.2.0", "jsonfile": "^4.0.0", "universalify": "^0.1.0" }, "engines": { "node": ">=6 <7 || >=8" } }, "node_modules/fsevents": { "version": "2.3.2", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", "hasInstallScript": true, "optional": true, "os": [ "darwin" ], "engines": { "node": "^8.16.0 || ^10.6.0 || >=11.0.0" } }, "node_modules/get-caller-file": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", "engines": { "node": "6.* || 8.* || >= 10.*" } }, "node_modules/get-port": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/get-port/-/get-port-5.1.1.tgz", "integrity": "sha512-g/Q1aTSDOxFpchXC4i8ZWvxA1lnPqx/JHqcpIw0/LX9T8x/GBbi6YnlN5nhaKIFkT8oFsscUKgDJYxfwfS6QsQ==", "engines": { "node": ">=8" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/get-stream": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", "dependencies": { "pump": "^3.0.0" }, "engines": { "node": ">=6" } }, "node_modules/glob-parent": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", "dependencies": { "is-glob": "^4.0.1" }, "engines": { "node": ">= 6" } }, "node_modules/global-dirs": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-2.1.0.tgz", "integrity": "sha512-MG6kdOUh/xBnyo9cJFeIKkLEc1AyFq42QTU4XiX51i2NEdxLxLWXIjEjmqKeSuKR7pAZjTqUVoT2b2huxVLgYQ==", "dependencies": { "ini": "1.3.7" }, "engines": { "node": ">=8" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/got": { "version": "9.6.0", "resolved": "https://registry.npmjs.org/got/-/got-9.6.0.tgz", "integrity": "sha512-R7eWptXuGYxwijs0eV+v3o6+XH1IqVK8dJOEecQfTmkncw9AV4dcw/Dhxi8MdlqPthxxpZyizMzyg8RTmEsG+Q==", "dependencies": { "@sindresorhus/is": "^0.14.0", "@szmarczak/http-timer": "^1.1.2", "cacheable-request": "^6.0.0", "decompress-response": "^3.3.0", "duplexer3": "^0.1.4", "get-stream": "^4.1.0", "lowercase-keys": "^1.0.1", "mimic-response": "^1.0.1", "p-cancelable": "^1.0.0", "to-readable-stream": "^1.0.0", "url-parse-lax": "^3.0.0" }, "engines": { "node": ">=8.6" } }, "node_modules/graceful-fs": { "version": "4.2.11", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==" }, "node_modules/has-ansi": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", "integrity": "sha512-C8vBJ8DwUCx19vhm7urhTuUsr4/IyP6l4VzNQDv+ryHQObW3TTTp9yB68WpYgRe2bbaGuZ/se74IqFeVnMnLZg==", "dependencies": { "ansi-regex": "^2.0.0" }, "engines": { "node": ">=0.10.0" } }, "node_modules/has-ansi/node_modules/ansi-regex": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", "integrity": "sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==", "engines": { "node": ">=0.10.0" } }, "node_modules/has-flag": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", "engines": { "node": ">=4" } }, "node_modules/has-yarn": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/has-yarn/-/has-yarn-2.1.0.tgz", "integrity": "sha512-UqBRqi4ju7T+TqGNdqAO0PaSVGsDGJUBQvk9eUWNGRY1CFGDzYhLWoM7JQEemnlvVcv/YEmc2wNW8BC24EnUsw==", "engines": { "node": ">=8" } }, "node_modules/http-cache-semantics": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz", "integrity": "sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ==" }, "node_modules/http-errors": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", "dependencies": { "depd": "2.0.0", "inherits": "2.0.4", "setprototypeof": "1.2.0", "statuses": "2.0.1", "toidentifier": "1.0.1" }, "engines": { "node": ">= 0.8" } }, "node_modules/http-errors/node_modules/statuses": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", "engines": { "node": ">= 0.8" } }, "node_modules/import-lazy": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-2.1.0.tgz", "integrity": "sha512-m7ZEHgtw69qOGw+jwxXkHlrlIPdTGkyh66zXZ1ajZbxkDBNjSY/LGbmjc7h0s2ELsUDTAhFr55TrPSSqJGPG0A==", "engines": { "node": ">=4" } }, "node_modules/imurmurhash": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", "engines": { "node": ">=0.8.19" } }, "node_modules/inherits": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" }, "node_modules/ini": { "version": "1.3.7", "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.7.tgz", "integrity": "sha512-iKpRpXP+CrP2jyrxvg1kMUpXDyRUFDWurxbnVT1vQPx+Wz9uCYsMIqYuSBLV+PAaZG/d7kRLKRFc9oDMsH+mFQ==" }, "node_modules/is-binary-path": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", "dependencies": { "binary-extensions": "^2.0.0" }, "engines": { "node": ">=8" } }, "node_modules/is-ci": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-2.0.0.tgz", "integrity": "sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w==", "dependencies": { "ci-info": "^2.0.0" }, "bin": { "is-ci": "bin.js" } }, "node_modules/is-extglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", "engines": { "node": ">=0.10.0" } }, "node_modules/is-fullwidth-code-point": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", "engines": { "node": ">=8" } }, "node_modules/is-glob": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", "dependencies": { "is-extglob": "^2.1.1" }, "engines": { "node": ">=0.10.0" } }, "node_modules/is-installed-globally": { "version": "0.3.2", "resolved": "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.3.2.tgz", "integrity": "sha512-wZ8x1js7Ia0kecP/CHM/3ABkAmujX7WPvQk6uu3Fly/Mk44pySulQpnHG46OMjHGXApINnV4QhY3SWnECO2z5g==", "dependencies": { "global-dirs": "^2.0.1", "is-path-inside": "^3.0.1" }, "engines": { "node": ">=8" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/is-npm": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/is-npm/-/is-npm-4.0.0.tgz", "integrity": "sha512-96ECIfh9xtDDlPylNPXhzjsykHsMJZ18ASpaWzQyBr4YRTcVjUvzaHayDAES2oU/3KpljhHUjtSRNiDwi0F0ig==", "engines": { "node": ">=8" } }, "node_modules/is-number": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", "engines": { "node": ">=0.12.0" } }, "node_modules/is-obj": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz", "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==", "engines": { "node": ">=8" } }, "node_modules/is-path-inside": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", "engines": { "node": ">=8" } }, "node_modules/is-typedarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==" }, "node_modules/is-wsl": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-1.1.0.tgz", "integrity": "sha512-gfygJYZ2gLTDlmbWMI0CE2MwnFzSN/2SZfkMlItC4K/JBlsWVDB0bO6XhqcY13YXE7iMcAJnzTCJjPiTeJJ0Mw==", "engines": { "node": ">=4" } }, "node_modules/is-yarn-global": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/is-yarn-global/-/is-yarn-global-0.3.0.tgz", "integrity": "sha512-VjSeb/lHmkoyd8ryPVIKvOCn4D1koMqY+vqyjjUfc3xyKtP4dYOxM44sZrnqQSzSds3xyOrUTLTC9LVCVgLngw==" }, "node_modules/json-buffer": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.0.tgz", "integrity": "sha512-CuUqjv0FUZIdXkHPI8MezCnFCdaTAacej1TZYulLoAg1h/PhwkdXFN4V/gzY4g+fMBCOV2xF+rp7t2XD2ns/NQ==" }, "node_modules/jsonfile": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", "optionalDependencies": { "graceful-fs": "^4.1.6" } }, "node_modules/keyv": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/keyv/-/keyv-3.1.0.tgz", "integrity": "sha512-9ykJ/46SN/9KPM/sichzQ7OvXyGDYKGTaDlKMGCAlg2UK8KRy4jb0d8sFc+0Tt0YYnThq8X2RZgCg74RPxgcVA==", "dependencies": { "json-buffer": "3.0.0" } }, "node_modules/latest-version": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/latest-version/-/latest-version-5.1.0.tgz", "integrity": "sha512-weT+r0kTkRQdCdYCNtkMwWXQTMEswKrFBkm4ckQOMVhhqhIMI1UT2hMj+1iigIhgSZm5gTmrRXBNoGUgaTY1xA==", "dependencies": { "package-json": "^6.3.0" }, "engines": { "node": ">=8" } }, "node_modules/livereload": { "version": "0.9.3", "resolved": "https://registry.npmjs.org/livereload/-/livereload-0.9.3.tgz", "integrity": "sha512-q7Z71n3i4X0R9xthAryBdNGVGAO2R5X+/xXpmKeuPMrteg+W2U8VusTKV3YiJbXZwKsOlFlHe+go6uSNjfxrZw==", "dependencies": { "chokidar": "^3.5.0", "livereload-js": "^3.3.1", "opts": ">= 1.2.0", "ws": "^7.4.3" }, "bin": { "livereload": "bin/livereload.js" }, "engines": { "node": ">=8.0.0" } }, "node_modules/livereload-js": { "version": "3.4.1", "resolved": "https://registry.npmjs.org/livereload-js/-/livereload-js-3.4.1.tgz", "integrity": "sha512-5MP0uUeVCec89ZbNOT/i97Mc+q3SxXmiUGhRFOTmhrGPn//uWVQdCvcLJDy64MSBR5MidFdOR7B9viumoavy6g==" }, "node_modules/locate-path": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", "dependencies": { "p-locate": "^4.1.0" }, "engines": { "node": ">=8" } }, "node_modules/lowercase-keys": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz", "integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==", "engines": { "node": ">=0.10.0" } }, "node_modules/lru-cache": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", "dependencies": { "yallist": "^3.0.2" } }, "node_modules/make-dir": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", "dependencies": { "semver": "^6.0.0" }, "engines": { "node": ">=8" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/marked": { "version": "1.2.9", "resolved": "https://registry.npmjs.org/marked/-/marked-1.2.9.tgz", "integrity": "sha512-H8lIX2SvyitGX+TRdtS06m1jHMijKN/XjfH6Ooii9fvxMlh8QdqBfBDkGUpMWH2kQNrtixjzYUa3SH8ROTgRRw==", "bin": { "marked": "bin/marked" }, "engines": { "node": ">= 8.16.2" } }, "node_modules/medium-zoom": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/medium-zoom/-/medium-zoom-1.0.8.tgz", "integrity": "sha512-CjFVuFq/IfrdqesAXfg+hzlDKu6A2n80ZIq0Kl9kWjoHh9j1N9Uvk5X0/MmN0hOfm5F9YBswlClhcwnmtwz7gA==" }, "node_modules/mime": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", "bin": { "mime": "cli.js" }, "engines": { "node": ">=4" } }, "node_modules/mimic-response": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz", "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==", "engines": { "node": ">=4" } }, "node_modules/min-indent": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==", "engines": { "node": ">=4" } }, "node_modules/minimist": { "version": "1.2.8", "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" }, "node_modules/nested-error-stacks": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/nested-error-stacks/-/nested-error-stacks-2.1.1.tgz", "integrity": "sha512-9iN1ka/9zmX1ZvLV9ewJYEk9h7RyRRtqdK0woXcqohu8EWIerfPUjYJPg0ULy0UqP7cslmdGc8xKDJcojlKiaw==" }, "node_modules/node-fetch": { "version": "2.6.12", "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.12.tgz", "integrity": "sha512-C/fGU2E8ToujUivIO0H+tpQ6HWo4eEmchoPIoXtxCrVghxdKq+QOHqEZW7tuP3KlV3bC8FRMO5nMCC7Zm1VP6g==", "dependencies": { "whatwg-url": "^5.0.0" }, "engines": { "node": "4.x || >=6.0.0" }, "peerDependencies": { "encoding": "^0.1.0" }, "peerDependenciesMeta": { "encoding": { "optional": true } } }, "node_modules/normalize-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", "engines": { "node": ">=0.10.0" } }, "node_modules/normalize-url": { "version": "4.5.1", "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-4.5.1.tgz", "integrity": "sha512-9UZCFRHQdNrfTpGg8+1INIg93B6zE0aXMVFkw1WFwvO4SlZywU6aLg5Of0Ap/PgcbSw4LNxvMWXMeugwMCX0AA==", "engines": { "node": ">=8" } }, "node_modules/on-finished": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", "integrity": "sha512-ikqdkGAAyf/X/gPhXGvfgAytDZtDbr+bkNUJ0N9h5MI/dmdgCs3l6hoHrcUv41sRKew3jIwrp4qQDXiK99Utww==", "dependencies": { "ee-first": "1.1.1" }, "engines": { "node": ">= 0.8" } }, "node_modules/once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", "dependencies": { "wrappy": "1" } }, "node_modules/open": { "version": "6.4.0", "resolved": "https://registry.npmjs.org/open/-/open-6.4.0.tgz", "integrity": "sha512-IFenVPgF70fSm1keSd2iDBIDIBZkroLeuffXq+wKTzTJlBpesFWojV9lb8mzOfaAzM1sr7HQHuO0vtV0zYekGg==", "dependencies": { "is-wsl": "^1.1.0" }, "engines": { "node": ">=8" } }, "node_modules/opencollective-postinstall": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/opencollective-postinstall/-/opencollective-postinstall-2.0.3.tgz", "integrity": "sha512-8AV/sCtuzUeTo8gQK5qDZzARrulB3egtLzFgteqB2tcT4Mw7B8Kt7JcDHmltjz6FOAHsvTevk70gZEbhM4ZS9Q==", "bin": { "opencollective-postinstall": "index.js" } }, "node_modules/opts": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/opts/-/opts-2.0.2.tgz", "integrity": "sha512-k41FwbcLnlgnFh69f4qdUfvDQ+5vaSDnVPFI/y5XuhKRq97EnVVneO9F1ESVCdiVu4fCS2L8usX3mU331hB7pg==" }, "node_modules/p-cancelable": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-1.1.0.tgz", "integrity": "sha512-s73XxOZ4zpt1edZYZzvhqFa6uvQc1vwUa0K0BdtIZgQMAJj9IbebH+JkgKZc9h+B05PKHLOTl4ajG1BmNrVZlw==", "engines": { "node": ">=6" } }, "node_modules/p-event": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/p-event/-/p-event-4.2.0.tgz", "integrity": "sha512-KXatOjCRXXkSePPb1Nbi0p0m+gQAwdlbhi4wQKJPI1HsMQS9g+Sqp2o+QHziPr7eYJyOZet836KoHEVM1mwOrQ==", "dependencies": { "p-timeout": "^3.1.0" }, "engines": { "node": ">=8" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/p-finally": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", "integrity": "sha512-LICb2p9CB7FS+0eR1oqWnHhp0FljGLZCWBE9aix0Uye9W8LTQPwMTYVGWQWIw9RdQiDg4+epXQODwIYJtSJaow==", "engines": { "node": ">=4" } }, "node_modules/p-limit": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", "dependencies": { "p-try": "^2.0.0" }, "engines": { "node": ">=6" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/p-locate": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", "dependencies": { "p-limit": "^2.2.0" }, "engines": { "node": ">=8" } }, "node_modules/p-timeout": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-3.2.0.tgz", "integrity": "sha512-rhIwUycgwwKcP9yTOOFK/AKsAopjjCakVqLHePO3CC6Mir1Z99xT+R63jZxAT5lFZLa2inS5h+ZS2GvR99/FBg==", "dependencies": { "p-finally": "^1.0.0" }, "engines": { "node": ">=8" } }, "node_modules/p-try": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", "engines": { "node": ">=6" } }, "node_modules/package-json": { "version": "6.5.0", "resolved": "https://registry.npmjs.org/package-json/-/package-json-6.5.0.tgz", "integrity": "sha512-k3bdm2n25tkyxcjSKzB5x8kfVxlMdgsbPr0GkZcwHsLpba6cBjqCt1KlcChKEvxHIcTB1FVMuwoijZ26xex5MQ==", "dependencies": { "got": "^9.6.0", "registry-auth-token": "^4.0.0", "registry-url": "^5.0.0", "semver": "^6.2.0" }, "engines": { "node": ">=8" } }, "node_modules/parent-require": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/parent-require/-/parent-require-1.0.0.tgz", "integrity": "sha512-2MXDNZC4aXdkkap+rBBMv0lUsfJqvX5/2FiYYnfCnorZt3Pk06/IOR5KeaoghgS2w07MLWgjbsnyaq6PdHn2LQ==", "engines": { "node": ">= 0.4.0" } }, "node_modules/parseurl": { "version": "1.3.3", "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", "engines": { "node": ">= 0.8" } }, "node_modules/path-exists": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", "engines": { "node": ">=8" } }, "node_modules/picomatch": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", "engines": { "node": ">=8.6" }, "funding": { "url": "https://github.com/sponsors/jonschlinkert" } }, "node_modules/prepend-http": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-2.0.0.tgz", "integrity": "sha512-ravE6m9Atw9Z/jjttRUZ+clIXogdghyZAuWJ3qEzjT+jI/dL1ifAqhZeC5VHzQp1MSt1+jxKkFNemj/iO7tVUA==", "engines": { "node": ">=4" } }, "node_modules/prismjs": { "version": "1.29.0", "resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.29.0.tgz", "integrity": "sha512-Kx/1w86q/epKcmte75LNrEoT+lX8pBpavuAbvJWRXar7Hz8jrtF+e3vY751p0R8H9HdArwaCTNDDzHg/ScJK1Q==", "engines": { "node": ">=6" } }, "node_modules/pump": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", "dependencies": { "end-of-stream": "^1.1.0", "once": "^1.3.1" } }, "node_modules/pupa": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/pupa/-/pupa-2.1.1.tgz", "integrity": "sha512-l1jNAspIBSFqbT+y+5FosojNpVpF94nlI+wDUpqP9enwOTfHx9f0gh5nB96vl+6yTpsJsypeNrwfzPrKuHB41A==", "dependencies": { "escape-goat": "^2.0.0" }, "engines": { "node": ">=8" } }, "node_modules/range-parser": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", "engines": { "node": ">= 0.6" } }, "node_modules/rc": { "version": "1.2.8", "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", "dependencies": { "deep-extend": "^0.6.0", "ini": "~1.3.0", "minimist": "^1.2.0", "strip-json-comments": "~2.0.1" }, "bin": { "rc": "cli.js" } }, "node_modules/readdirp": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", "dependencies": { "picomatch": "^2.2.1" }, "engines": { "node": ">=8.10.0" } }, "node_modules/registry-auth-token": { "version": "4.2.2", "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-4.2.2.tgz", "integrity": "sha512-PC5ZysNb42zpFME6D/XlIgtNGdTl8bBOCw90xQLVMpzuuubJKYDWFAEuUNc+Cn8Z8724tg2SDhDRrkVEsqfDMg==", "dependencies": { "rc": "1.2.8" }, "engines": { "node": ">=6.0.0" } }, "node_modules/registry-url": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/registry-url/-/registry-url-5.1.0.tgz", "integrity": "sha512-8acYXXTI0AkQv6RAOjE3vOaIXZkT9wo4LOFbBKYQEEnnMNBpKqdUrI6S4NT0KPIo/WVvJ5tE/X5LF/TQUf0ekw==", "dependencies": { "rc": "^1.2.8" }, "engines": { "node": ">=8" } }, "node_modules/require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", "engines": { "node": ">=0.10.0" } }, "node_modules/require-main-filename": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==" }, "node_modules/resolve-pathname": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/resolve-pathname/-/resolve-pathname-3.0.0.tgz", "integrity": "sha512-C7rARubxI8bXFNB/hqcp/4iUeIXJhJZvFPFPiSPRnhU5UPxzMFIl+2E6yY6c4k9giDJAhtV+enfA+G89N6Csng==" }, "node_modules/responselike": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/responselike/-/responselike-1.0.2.tgz", "integrity": "sha512-/Fpe5guzJk1gPqdJLJR5u7eG/gNY4nImjbRDaVWVMRhne55TCmj2i9Q+54PBRfatRC8v/rIiv9BN0pMd9OV5EQ==", "dependencies": { "lowercase-keys": "^1.0.0" } }, "node_modules/semver": { "version": "6.3.0", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", "bin": { "semver": "bin/semver.js" } }, "node_modules/semver-diff": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/semver-diff/-/semver-diff-3.1.1.tgz", "integrity": "sha512-GX0Ix/CJcHyB8c4ykpHGIAvLyOwOobtM/8d+TQkAd81/bEjgPHrfba41Vpesr7jX/t8Uh+R3EX9eAS5be+jQYg==", "dependencies": { "semver": "^6.3.0" }, "engines": { "node": ">=8" } }, "node_modules/send": { "version": "0.18.0", "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==", "dependencies": { "debug": "2.6.9", "depd": "2.0.0", "destroy": "1.2.0", "encodeurl": "~1.0.2", "escape-html": "~1.0.3", "etag": "~1.8.1", "fresh": "0.5.2", "http-errors": "2.0.0", "mime": "1.6.0", "ms": "2.1.3", "on-finished": "2.4.1", "range-parser": "~1.2.1", "statuses": "2.0.1" }, "engines": { "node": ">= 0.8.0" } }, "node_modules/send/node_modules/ms": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" }, "node_modules/send/node_modules/on-finished": { "version": "2.4.1", "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", "dependencies": { "ee-first": "1.1.1" }, "engines": { "node": ">= 0.8" } }, "node_modules/send/node_modules/statuses": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", "engines": { "node": ">= 0.8" } }, "node_modules/serve-static": { "version": "1.15.0", "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz", "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==", "dependencies": { "encodeurl": "~1.0.2", "escape-html": "~1.0.3", "parseurl": "~1.3.3", "send": "0.18.0" }, "engines": { "node": ">= 0.8.0" } }, "node_modules/set-blocking": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==" }, "node_modules/setprototypeof": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==" }, "node_modules/signal-exit": { "version": "3.0.7", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==" }, "node_modules/statuses": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", "integrity": "sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==", "engines": { "node": ">= 0.6" } }, "node_modules/string-width": { "version": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", "strip-ansi": "^6.0.1" }, "engines": { "node": ">=8" } }, "node_modules/strip-ansi": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "dependencies": { "ansi-regex": "^5.0.1" }, "engines": { "node": ">=8" } }, "node_modules/strip-indent": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz", "integrity": "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==", "dependencies": { "min-indent": "^1.0.0" }, "engines": { "node": ">=8" } }, "node_modules/strip-json-comments": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==", "engines": { "node": ">=0.10.0" } }, "node_modules/supports-color": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", "dependencies": { "has-flag": "^3.0.0" }, "engines": { "node": ">=4" } }, "node_modules/term-size": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/term-size/-/term-size-2.2.1.tgz", "integrity": "sha512-wK0Ri4fOGjv/XPy8SBHZChl8CM7uMc5VML7SqiQ0zG7+J5Vr+RMQDoHa2CNT6KHUnTGIXH34UDMkPzAUyapBZg==", "engines": { "node": ">=8" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/tinydate": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/tinydate/-/tinydate-1.3.0.tgz", "integrity": "sha512-7cR8rLy2QhYHpsBDBVYnnWXm8uRTr38RoZakFSW7Bs7PzfMPNZthuMLkwqZv7MTu8lhQ91cOFYS5a7iFj2oR3w==", "engines": { "node": ">=4" } }, "node_modules/to-readable-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/to-readable-stream/-/to-readable-stream-1.0.0.tgz", "integrity": "sha512-Iq25XBt6zD5npPhlLVXGFN3/gyR2/qODcKNNyTMd4vbm39HUaOiAM4PMq0eMVC/Tkxz+Zjdsc55g9yyz+Yq00Q==", "engines": { "node": ">=6" } }, "node_modules/to-regex-range": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", "dependencies": { "is-number": "^7.0.0" }, "engines": { "node": ">=8.0" } }, "node_modules/toidentifier": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", "engines": { "node": ">=0.6" } }, "node_modules/tr46": { "version": "0.0.3", "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" }, "node_modules/tweezer.js": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/tweezer.js/-/tweezer.js-1.5.0.tgz", "integrity": "sha512-aSiJz7rGWNAQq7hjMK9ZYDuEawXupcCWgl3woQQSoDP2Oh8O4srWb/uO1PzzHIsrPEOqrjJ2sUb9FERfzuBabQ==" }, "node_modules/type-fest": { "version": "0.8.1", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", "engines": { "node": ">=8" } }, "node_modules/typedarray-to-buffer": { "version": "3.1.5", "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", "dependencies": { "is-typedarray": "^1.0.0" } }, "node_modules/unique-string": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-2.0.0.tgz", "integrity": "sha512-uNaeirEPvpZWSgzwsPGtU2zVSTrn/8L5q/IexZmH0eH6SA73CmAA5U4GwORTxQAZs95TAXLNqeLoPPNO5gZfWg==", "dependencies": { "crypto-random-string": "^2.0.0" }, "engines": { "node": ">=8" } }, "node_modules/universalify": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", "engines": { "node": ">= 4.0.0" } }, "node_modules/unpipe": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", "engines": { "node": ">= 0.8" } }, "node_modules/update-notifier": { "version": "4.1.3", "resolved": "https://registry.npmjs.org/update-notifier/-/update-notifier-4.1.3.tgz", "integrity": "sha512-Yld6Z0RyCYGB6ckIjffGOSOmHXj1gMeE7aROz4MG+XMkmixBX4jUngrGXNYz7wPKBmtoD4MnBa2Anu7RSKht/A==", "dependencies": { "boxen": "^4.2.0", "chalk": "^3.0.0", "configstore": "^5.0.1", "has-yarn": "^2.1.0", "import-lazy": "^2.1.0", "is-ci": "^2.0.0", "is-installed-globally": "^0.3.1", "is-npm": "^4.0.0", "is-yarn-global": "^0.3.0", "latest-version": "^5.0.0", "pupa": "^2.0.1", "semver-diff": "^3.1.1", "xdg-basedir": "^4.0.0" }, "engines": { "node": ">=8" }, "funding": { "url": "https://github.com/yeoman/update-notifier?sponsor=1" } }, "node_modules/update-notifier/node_modules/ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dependencies": { "color-convert": "^2.0.1" }, "engines": { "node": ">=8" }, "funding": { "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, "node_modules/update-notifier/node_modules/chalk": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" }, "engines": { "node": ">=8" } }, "node_modules/update-notifier/node_modules/color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dependencies": { "color-name": "~1.1.4" }, "engines": { "node": ">=7.0.0" } }, "node_modules/update-notifier/node_modules/color-name": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" }, "node_modules/update-notifier/node_modules/has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "engines": { "node": ">=8" } }, "node_modules/update-notifier/node_modules/supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dependencies": { "has-flag": "^4.0.0" }, "engines": { "node": ">=8" } }, "node_modules/url-parse-lax": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-3.0.0.tgz", "integrity": "sha512-NjFKA0DidqPa5ciFcSrXnAltTtzz84ogy+NebPvfEgAck0+TNg4UJ4IN+fB7zRZfbgUf0syOo9MDxFkDSMuFaQ==", "dependencies": { "prepend-http": "^2.0.0" }, "engines": { "node": ">=4" } }, "node_modules/utils-merge": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", "engines": { "node": ">= 0.4.0" } }, "node_modules/webidl-conversions": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==" }, "node_modules/whatwg-url": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", "dependencies": { "tr46": "~0.0.3", "webidl-conversions": "^3.0.0" } }, "node_modules/which-module": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.1.tgz", "integrity": "sha512-iBdZ57RDvnOR9AGBhML2vFZf7h8vmBjhoaZqODJBFWHVtKkDmKuHai3cx5PgVMrX5YDNp27AofYbAwctSS+vhQ==" }, "node_modules/widest-line": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-3.1.0.tgz", "integrity": "sha512-NsmoXalsWVDMGupxZ5R08ka9flZjjiLvHVAWYOKtiKM8ujtZWr9cRffak+uSE48+Ob8ObalXpwyeUiyDD6QFgg==", "dependencies": { "string-width": "^4.0.0" }, "engines": { "node": ">=8" } }, "node_modules/wrap-ansi": { "version": "6.2.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", "strip-ansi": "^6.0.0" }, "engines": { "node": ">=8" } }, "node_modules/wrap-ansi/node_modules/ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dependencies": { "color-convert": "^2.0.1" }, "engines": { "node": ">=8" }, "funding": { "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, "node_modules/wrap-ansi/node_modules/color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dependencies": { "color-name": "~1.1.4" }, "engines": { "node": ">=7.0.0" } }, "node_modules/wrap-ansi/node_modules/color-name": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" }, "node_modules/wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" }, "node_modules/write-file-atomic": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==", "dependencies": { "imurmurhash": "^0.1.4", "is-typedarray": "^1.0.0", "signal-exit": "^3.0.2", "typedarray-to-buffer": "^3.1.5" } }, "node_modules/ws": { "version": "7.5.9", "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.9.tgz", "integrity": "sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q==", "engines": { "node": ">=8.3.0" }, "peerDependencies": { "bufferutil": "^4.0.1", "utf-8-validate": "^5.0.2" }, "peerDependenciesMeta": { "bufferutil": { "optional": true }, "utf-8-validate": { "optional": true } } }, "node_modules/xdg-basedir": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-4.0.0.tgz", "integrity": "sha512-PSNhEJDejZYV7h50BohL09Er9VaIefr2LMAf3OEmpCkjOi34eYyQYAXUTjEQtZJTKcF0E2UKTh+osDLsgNim9Q==", "engines": { "node": ">=8" } }, "node_modules/y18n": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==" }, "node_modules/yallist": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==" }, "node_modules/yargonaut": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/yargonaut/-/yargonaut-1.1.4.tgz", "integrity": "sha512-rHgFmbgXAAzl+1nngqOcwEljqHGG9uUZoPjsdZEs1w5JW9RXYzrSvH/u70C1JE5qFi0qjsdhnUX/dJRpWqitSA==", "dependencies": { "chalk": "^1.1.1", "figlet": "^1.1.1", "parent-require": "^1.0.0" } }, "node_modules/yargonaut/node_modules/ansi-regex": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", "integrity": "sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==", "engines": { "node": ">=0.10.0" } }, "node_modules/yargonaut/node_modules/ansi-styles": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", "integrity": "sha512-kmCevFghRiWM7HB5zTPULl4r9bVFSWjz62MhqizDGUrq2NWuNMQyuv4tHHoKJHs69M/MF64lEcHdYIocrdWQYA==", "engines": { "node": ">=0.10.0" } }, "node_modules/yargonaut/node_modules/chalk": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", "integrity": "sha512-U3lRVLMSlsCfjqYPbLyVv11M9CPW4I728d6TCKMAOJueEeB9/8o+eSsMnxPJD+Q+K909sdESg7C+tIkoH6on1A==", "dependencies": { "ansi-styles": "^2.2.1", "escape-string-regexp": "^1.0.2", "has-ansi": "^2.0.0", "strip-ansi": "^3.0.0", "supports-color": "^2.0.0" }, "engines": { "node": ">=0.10.0" } }, "node_modules/yargonaut/node_modules/strip-ansi": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", "integrity": "sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg==", "dependencies": { "ansi-regex": "^2.0.0" }, "engines": { "node": ">=0.10.0" } }, "node_modules/yargonaut/node_modules/supports-color": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", "integrity": "sha512-KKNVtd6pCYgPIKU4cp2733HWYCpplQhddZLBUryaAHou723x+FRzQ5Df824Fj+IyyuiQTRoub4SnIFfIcrp70g==", "engines": { "node": ">=0.8.0" } }, "node_modules/yargs": { "version": "15.4.1", "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz", "integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==", "dependencies": { "cliui": "^6.0.0", "decamelize": "^1.2.0", "find-up": "^4.1.0", "get-caller-file": "^2.0.1", "require-directory": "^2.1.1", "require-main-filename": "^2.0.0", "set-blocking": "^2.0.0", "string-width": "^4.2.0", "which-module": "^2.0.0", "y18n": "^4.0.0", "yargs-parser": "^18.1.2" }, "engines": { "node": ">=8" } }, "node_modules/yargs-parser": { "version": "18.1.3", "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz", "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==", "dependencies": { "camelcase": "^5.0.0", "decamelize": "^1.2.0" }, "engines": { "node": ">=6" } } } } faraday-2.10.0/package.json000066400000000000000000000011761464273144400155050ustar00rootroot00000000000000{ "name": "faraday-docs", "version": "0.1.0", "description": "Faraday Docs", "main": "index.js", "directories": { "doc": "docs", "example": "examples", "lib": "lib" }, "scripts": { "docs": "docsify serve ./docs" }, "repository": { "type": "git", "url": "git+https://github.com/lostisland/faraday.git" }, "keywords": [ "docs", "faraday" ], "author": "Mattia Giuffrida", "license": "MIT", "bugs": { "url": "https://github.com/lostisland/faraday/issues" }, "homepage": "https://github.com/lostisland/faraday#readme", "dependencies": { "docsify-cli": "^4.4.4" } } faraday-2.10.0/spec/000077500000000000000000000000001464273144400141445ustar00rootroot00000000000000faraday-2.10.0/spec/external_adapters/000077500000000000000000000000001464273144400176515ustar00rootroot00000000000000faraday-2.10.0/spec/external_adapters/faraday_specs_setup.rb000066400000000000000000000006731464273144400242300ustar00rootroot00000000000000# frozen_string_literal: true require 'webmock/rspec' WebMock.disable_net_connect!(allow_localhost: true) require_relative '../support/helper_methods' require_relative '../support/disabling_stub' require_relative '../support/streaming_response_checker' require_relative '../support/shared_examples/adapter' require_relative '../support/shared_examples/request_method' RSpec.configure do |config| config.include Faraday::HelperMethods end faraday-2.10.0/spec/faraday/000077500000000000000000000000001464273144400155535ustar00rootroot00000000000000faraday-2.10.0/spec/faraday/adapter/000077500000000000000000000000001464273144400171735ustar00rootroot00000000000000faraday-2.10.0/spec/faraday/adapter/test_spec.rb000066400000000000000000000350521464273144400215160ustar00rootroot00000000000000# frozen_string_literal: true RSpec.describe Faraday::Adapter::Test do let(:stubs) do described_class::Stubs.new do |stub| stub.get('http://domain.test/hello') do [200, { 'Content-Type' => 'text/html' }, 'domain: hello'] end stub.get('http://wrong.test/hello') do [200, { 'Content-Type' => 'text/html' }, 'wrong: hello'] end stub.get('http://wrong.test/bait') do [404, { 'Content-Type' => 'text/html' }] end stub.get('/hello') do [200, { 'Content-Type' => 'text/html' }, 'hello'] end stub.get('/method-echo') do |env| [200, { 'Content-Type' => 'text/html' }, env[:method].to_s] end stub.get(%r{\A/resources/\d+(?:\?|\z)}) do [200, { 'Content-Type' => 'text/html' }, 'show'] end stub.get(%r{\A/resources/(specified)\z}) do |_env, meta| [200, { 'Content-Type' => 'text/html' }, "show #{meta[:match_data][1]}"] end end end let(:connection) do Faraday.new do |builder| builder.adapter :test, stubs end end let(:response) { connection.get('/hello') } context 'with simple path sets status' do subject { response.status } it { is_expected.to eq 200 } end context 'with simple path sets headers' do subject { response.headers['Content-Type'] } it { is_expected.to eq 'text/html' } end context 'with simple path sets body' do subject { response.body } it { is_expected.to eq 'hello' } end context 'with host points to the right stub' do subject { connection.get('http://domain.test/hello').body } it { is_expected.to eq 'domain: hello' } end describe 'can be called several times' do subject { connection.get('/hello').body } it { is_expected.to eq 'hello' } end describe 'can handle regular expression path' do subject { connection.get('/resources/1').body } it { is_expected.to eq 'show' } end describe 'can handle single parameter block' do subject { connection.get('/method-echo').body } it { is_expected.to eq 'get' } end describe 'can handle regular expression path with captured result' do subject { connection.get('/resources/specified').body } it { is_expected.to eq 'show specified' } end context 'with get params' do subject { connection.get('/param?a=1').body } before do stubs.get('/param?a=1') { [200, {}, 'a'] } end it { is_expected.to eq 'a' } end describe 'ignoring unspecified get params' do before do stubs.get('/optional?a=1') { [200, {}, 'a'] } end context 'with multiple params' do subject { connection.get('/optional?a=1&b=1').body } it { is_expected.to eq 'a' } end context 'with single param' do subject { connection.get('/optional?a=1').body } it { is_expected.to eq 'a' } end context 'without params' do subject(:request) { connection.get('/optional') } it do expect { request }.to raise_error( Faraday::Adapter::Test::Stubs::NotFound ) end end end context 'with http headers' do before do stubs.get('/yo', 'X-HELLO' => 'hello') { [200, {}, 'a'] } stubs.get('/yo') { [200, {}, 'b'] } end context 'with header' do subject do connection.get('/yo') { |env| env.headers['X-HELLO'] = 'hello' }.body end it { is_expected.to eq 'a' } end context 'without header' do subject do connection.get('/yo').body end it { is_expected.to eq 'b' } end end describe 'different outcomes for the same request' do def make_request connection.get('/foo') end subject(:request) { make_request.body } before do stubs.get('/foo') { [200, { 'Content-Type' => 'text/html' }, 'hello'] } stubs.get('/foo') { [200, { 'Content-Type' => 'text/html' }, 'world'] } end context 'the first request' do it { is_expected.to eq 'hello' } end context 'the second request' do before do make_request end it { is_expected.to eq 'world' } end end describe 'yielding env to stubs' do subject { connection.get('http://foo.com/foo?a=1').body } before do stubs.get '/foo' do |env| expect(env[:url].path).to eq '/foo' expect(env[:url].host).to eq 'foo.com' expect(env[:params]['a']).to eq '1' expect(env[:request_headers]['Accept']).to eq 'text/plain' [200, {}, 'a'] end connection.headers['Accept'] = 'text/plain' end it { is_expected.to eq 'a' } end describe 'params parsing' do subject { connection.get('http://foo.com/foo?a[b]=1').body } context 'with default encoder' do before do stubs.get '/foo' do |env| expect(env[:params]['a']['b']).to eq '1' [200, {}, 'a'] end end it { is_expected.to eq 'a' } end context 'with nested encoder' do before do stubs.get '/foo' do |env| expect(env[:params]['a']['b']).to eq '1' [200, {}, 'a'] end connection.options.params_encoder = Faraday::NestedParamsEncoder end it { is_expected.to eq 'a' } end context 'with flat encoder' do before do stubs.get '/foo' do |env| expect(env[:params]['a[b]']).to eq '1' [200, {}, 'a'] end connection.options.params_encoder = Faraday::FlatParamsEncoder end it { is_expected.to eq 'a' } end end describe 'raising an error if no stub was found' do describe 'for request' do subject(:request) { connection.get('/invalid') { [200, {}, []] } } it { expect { request }.to raise_error described_class::Stubs::NotFound } end describe 'for specified host' do subject(:request) { connection.get('http://domain.test/bait') } it { expect { request }.to raise_error described_class::Stubs::NotFound } end describe 'for request without specified header' do subject(:request) { connection.get('/yo') } before do stubs.get('/yo', 'X-HELLO' => 'hello') { [200, {}, 'a'] } end it { expect { request }.to raise_error described_class::Stubs::NotFound } end end describe 'for request with non default params encoder' do let(:connection) do Faraday.new(request: { params_encoder: Faraday::FlatParamsEncoder }) do |builder| builder.adapter :test, stubs end end let(:stubs) do described_class::Stubs.new do |stubs| stubs.get('/path?a=x&a=y&a=z') { [200, {}, 'a'] } end end context 'when all flat param values are correctly set' do subject(:request) { connection.get('/path?a=x&a=y&a=z') } it { expect(request.status).to eq 200 } end shared_examples 'raise NotFound when params do not satisfy the flat param values' do |params| subject(:request) { connection.get('/path', params) } context "with #{params.inspect}" do it { expect { request }.to raise_error described_class::Stubs::NotFound } end end it_behaves_like 'raise NotFound when params do not satisfy the flat param values', { a: %w[x] } it_behaves_like 'raise NotFound when params do not satisfy the flat param values', { a: %w[x y] } it_behaves_like 'raise NotFound when params do not satisfy the flat param values', { a: %w[x z y] } # NOTE: The order of the value is also compared. it_behaves_like 'raise NotFound when params do not satisfy the flat param values', { b: %w[x y z] } end describe 'strict_mode' do let(:stubs) do described_class::Stubs.new(strict_mode: true) do |stubs| stubs.get('/strict?a=12&b=xy', 'Authorization' => 'Bearer m_ck', 'X-C' => 'hello') { [200, {}, 'a'] } stubs.get('/with_user_agent?a=12&b=xy', authorization: 'Bearer m_ck', 'User-Agent' => 'My Agent') { [200, {}, 'a'] } end end context 'when params and headers are exactly set' do subject(:request) { connection.get('/strict', { a: '12', b: 'xy' }, { authorization: 'Bearer m_ck', x_c: 'hello' }) } it { expect(request.status).to eq 200 } end context 'when params and headers are exactly set with a custom user agent' do subject(:request) { connection.get('/with_user_agent', { a: '12', b: 'xy' }, { authorization: 'Bearer m_ck', 'User-Agent' => 'My Agent' }) } it { expect(request.status).to eq 200 } end shared_examples 'raise NotFound when params do not satisfy the strict check' do |params| subject(:request) { connection.get('/strict', params, { 'Authorization' => 'Bearer m_ck', 'X-C' => 'hello' }) } context "with #{params.inspect}" do it { expect { request }.to raise_error described_class::Stubs::NotFound } end end it_behaves_like 'raise NotFound when params do not satisfy the strict check', { a: '12' } it_behaves_like 'raise NotFound when params do not satisfy the strict check', { b: 'xy' } it_behaves_like 'raise NotFound when params do not satisfy the strict check', { a: '123', b: 'xy' } it_behaves_like 'raise NotFound when params do not satisfy the strict check', { a: '12', b: 'xyz' } it_behaves_like 'raise NotFound when params do not satisfy the strict check', { a: '12', b: 'xy', c: 'hello' } it_behaves_like 'raise NotFound when params do not satisfy the strict check', { additional: 'special', a: '12', b: 'xy', c: 'hello' } shared_examples 'raise NotFound when headers do not satisfy the strict check' do |path, headers| subject(:request) { connection.get(path, { a: 12, b: 'xy' }, headers) } context "with #{headers.inspect}" do it { expect { request }.to raise_error described_class::Stubs::NotFound } end end it_behaves_like 'raise NotFound when headers do not satisfy the strict check', '/strict', { authorization: 'Bearer m_ck' } it_behaves_like 'raise NotFound when headers do not satisfy the strict check', '/strict', { 'X-C' => 'hello' } it_behaves_like 'raise NotFound when headers do not satisfy the strict check', '/strict', { authorization: 'Bearer m_ck', 'x-c': 'Hi' } it_behaves_like 'raise NotFound when headers do not satisfy the strict check', '/strict', { authorization: 'Basic m_ck', 'x-c': 'hello' } it_behaves_like 'raise NotFound when headers do not satisfy the strict check', '/strict', { authorization: 'Bearer m_ck', 'x-c': 'hello', x_special: 'special' } it_behaves_like 'raise NotFound when headers do not satisfy the strict check', '/with_user_agent', { authorization: 'Bearer m_ck' } it_behaves_like 'raise NotFound when headers do not satisfy the strict check', '/with_user_agent', { authorization: 'Bearer m_ck', user_agent: 'Unknown' } it_behaves_like 'raise NotFound when headers do not satisfy the strict check', '/with_user_agent', { authorization: 'Bearer m_ck', user_agent: 'My Agent', x_special: 'special' } context 'when strict_mode is disabled' do before do stubs.strict_mode = false end shared_examples 'does not raise NotFound even when params do not satisfy the strict check' do |params| subject(:request) { connection.get('/strict', params, { 'Authorization' => 'Bearer m_ck', 'X-C' => 'hello' }) } context "with #{params.inspect}" do it { expect(request.status).to eq 200 } end end it_behaves_like 'does not raise NotFound even when params do not satisfy the strict check', { a: '12', b: 'xy' } it_behaves_like 'does not raise NotFound even when params do not satisfy the strict check', { a: '12', b: 'xy', c: 'hello' } it_behaves_like 'does not raise NotFound even when params do not satisfy the strict check', { additional: 'special', a: '12', b: 'xy', c: 'hello' } shared_examples 'does not raise NotFound even when headers do not satisfy the strict check' do |path, headers| subject(:request) { connection.get(path, { a: 12, b: 'xy' }, headers) } context "with #{headers.inspect}" do it { expect(request.status).to eq 200 } end end it_behaves_like 'does not raise NotFound even when headers do not satisfy the strict check', '/strict', { authorization: 'Bearer m_ck', 'x-c': 'hello' } it_behaves_like 'does not raise NotFound even when headers do not satisfy the strict check', '/strict', { authorization: 'Bearer m_ck', 'x-c': 'hello', x_special: 'special' } it_behaves_like 'does not raise NotFound even when headers do not satisfy the strict check', '/strict', { authorization: 'Bearer m_ck', 'x-c': 'hello', user_agent: 'Special Agent' } it_behaves_like 'does not raise NotFound even when headers do not satisfy the strict check', '/with_user_agent', { authorization: 'Bearer m_ck', user_agent: 'My Agent' } it_behaves_like 'does not raise NotFound even when headers do not satisfy the strict check', '/with_user_agent', { authorization: 'Bearer m_ck', user_agent: 'My Agent', x_special: 'special' } end describe 'body_match?' do let(:stubs) do described_class::Stubs.new do |stubs| stubs.post('/no_check') { [200, {}, 'ok'] } stubs.post('/with_string', 'abc') { [200, {}, 'ok'] } stubs.post( '/with_proc', ->(request_body) { JSON.parse(request_body, symbolize_names: true) == { x: '!', a: [{ m: [{ a: true }], n: 123 }] } }, { content_type: 'application/json' } ) do [200, {}, 'ok'] end end end context 'when trying without any args for body' do subject(:without_body) { connection.post('/no_check') } it { expect(without_body.status).to eq 200 } end context 'when trying with string body stubs' do subject(:with_string) { connection.post('/with_string', 'abc') } it { expect(with_string.status).to eq 200 } end context 'when trying with proc body stubs' do subject(:with_proc) do connection.post('/with_proc', JSON.dump(a: [{ n: 123, m: [{ a: true }] }], x: '!'), { 'Content-Type' => 'application/json' }) end it { expect(with_proc.status).to eq 200 } end end end describe 'request timeout' do subject(:request) do connection.get('/sleep') do |req| req.options.timeout = timeout end end before do stubs.get('/sleep') do sleep(0.01) [200, {}, ''] end end context 'when request is within timeout' do let(:timeout) { 1 } it { expect(request.status).to eq 200 } end context 'when request is too slow' do let(:timeout) { 0.001 } it 'raises an exception' do expect { request }.to raise_error(Faraday::TimeoutError) end end end end faraday-2.10.0/spec/faraday/adapter_registry_spec.rb000066400000000000000000000014601464273144400224630ustar00rootroot00000000000000# frozen_string_literal: true RSpec.describe Faraday::AdapterRegistry do describe '#initialize' do subject(:registry) { described_class.new } it { expect { registry.get(:FinFangFoom) }.to raise_error(NameError) } it { expect { registry.get('FinFangFoom') }.to raise_error(NameError) } it 'looks up class by string name' do expect(registry.get('Faraday::Connection')).to eq(Faraday::Connection) end it 'looks up class by symbol name' do expect(registry.get(:Faraday)).to eq(Faraday) end it 'caches lookups with implicit name' do registry.set :symbol expect(registry.get('symbol')).to eq(:symbol) end it 'caches lookups with explicit name' do registry.set 'string', :name expect(registry.get(:name)).to eq('string') end end end faraday-2.10.0/spec/faraday/adapter_spec.rb000066400000000000000000000021641464273144400205350ustar00rootroot00000000000000# frozen_string_literal: true RSpec.describe Faraday::Adapter do let(:adapter) { Faraday::Adapter.new } let(:request) { {} } context '#request_timeout' do it 'gets :read timeout' do expect(timeout(:read)).to eq(nil) request[:timeout] = 5 request[:write_timeout] = 1 expect(timeout(:read)).to eq(5) request[:read_timeout] = 2 expect(timeout(:read)).to eq(2) end it 'gets :open timeout' do expect(timeout(:open)).to eq(nil) request[:timeout] = 5 request[:write_timeout] = 1 expect(timeout(:open)).to eq(5) request[:open_timeout] = 2 expect(timeout(:open)).to eq(2) end it 'gets :write timeout' do expect(timeout(:write)).to eq(nil) request[:timeout] = 5 request[:read_timeout] = 1 expect(timeout(:write)).to eq(5) request[:write_timeout] = 2 expect(timeout(:write)).to eq(2) end it 'attempts unknown timeout type' do expect { timeout(:unknown) }.to raise_error(ArgumentError) end def timeout(type) adapter.send(:request_timeout, type, request) end end end faraday-2.10.0/spec/faraday/connection_spec.rb000066400000000000000000000605201464273144400212540ustar00rootroot00000000000000# frozen_string_literal: true class CustomEncoder def encode(params) params.map { |k, v| "#{k.upcase}-#{v.to_s.upcase}" }.join(',') end def decode(params) params.split(',').to_h { |pair| pair.split('-') } end end shared_examples 'initializer with url' do context 'with simple url' do let(:address) { 'http://httpbingo.org' } it { expect(subject.host).to eq('httpbingo.org') } it { expect(subject.port).to eq(80) } it { expect(subject.scheme).to eq('http') } it { expect(subject.path_prefix).to eq('/') } it { expect(subject.params).to eq({}) } end context 'with complex url' do let(:address) { 'http://httpbingo.org:815/fish?a=1' } it { expect(subject.port).to eq(815) } it { expect(subject.path_prefix).to eq('/fish') } it { expect(subject.params).to eq('a' => '1') } end context 'with IPv6 address' do let(:address) { 'http://[::1]:85/' } it { expect(subject.host).to eq('[::1]') } it { expect(subject.port).to eq(85) } end end shared_examples 'default connection options' do after { Faraday.default_connection_options = nil } it 'works with implicit url' do conn = Faraday.new 'http://httpbingo.org/foo' expect(conn.options.timeout).to eq(10) end it 'works with option url' do conn = Faraday.new url: 'http://httpbingo.org/foo' expect(conn.options.timeout).to eq(10) end it 'works with instance connection options' do conn = Faraday.new 'http://httpbingo.org/foo', request: { open_timeout: 1 } expect(conn.options.timeout).to eq(10) expect(conn.options.open_timeout).to eq(1) end it 'default connection options persist with an instance overriding' do conn = Faraday.new 'http://nigiri.com/bar' conn.options.timeout = 1 expect(Faraday.default_connection_options.request.timeout).to eq(10) other = Faraday.new url: 'https://httpbingo.org/foo' other.options.timeout = 1 expect(Faraday.default_connection_options.request.timeout).to eq(10) end it 'default connection uses default connection options' do expect(Faraday.default_connection.options.timeout).to eq(10) end end RSpec.describe Faraday::Connection do let(:conn) { Faraday::Connection.new(url, options) } let(:url) { nil } let(:options) { nil } describe '.new' do subject { conn } context 'with implicit url param' do # Faraday::Connection.new('http://httpbingo.org') let(:url) { address } it_behaves_like 'initializer with url' end context 'with explicit url param' do # Faraday::Connection.new(url: 'http://httpbingo.org') let(:url) { { url: address } } it_behaves_like 'initializer with url' end context 'with custom builder' do let(:custom_builder) { Faraday::RackBuilder.new } let(:options) { { builder: custom_builder } } it { expect(subject.builder).to eq(custom_builder) } end context 'with custom params' do let(:options) { { params: { a: 1 } } } it { expect(subject.params).to eq('a' => 1) } end context 'with custom params and params in url' do let(:url) { 'http://httpbingo.org/fish?a=1&b=2' } let(:options) { { params: { a: 3 } } } it { expect(subject.params).to eq('a' => 3, 'b' => '2') } end context 'with basic_auth in url' do let(:url) { 'http://Aladdin:open%20sesame@httpbingo.org/fish' } it { expect(subject.headers['Authorization']).to eq('Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==') } end context 'with custom headers' do let(:options) { { headers: { user_agent: 'Faraday' } } } it { expect(subject.headers['User-agent']).to eq('Faraday') } end context 'with ssl false' do let(:options) { { ssl: { verify: false } } } it { expect(subject.ssl.verify?).to be_falsey } end context 'with verify_hostname false' do let(:options) { { ssl: { verify_hostname: false } } } it { expect(subject.ssl.verify_hostname?).to be_falsey } end context 'with empty block' do let(:conn) { Faraday::Connection.new {} } it { expect(conn.builder.handlers.size).to eq(0) } end context 'with block' do let(:conn) do Faraday::Connection.new(params: { 'a' => '1' }) do |faraday| faraday.adapter :test faraday.url_prefix = 'http://httpbingo.org/omnom' end end it { expect(conn.builder.handlers.size).to eq(0) } it { expect(conn.path_prefix).to eq('/omnom') } end end describe '#close' do before { Faraday.default_adapter = :test } after { Faraday.default_adapter = nil } it 'can close underlying app' do expect(conn.app).to receive(:close) conn.close end end describe '#build_exclusive_url' do context 'with relative path' do subject { conn.build_exclusive_url('sake.html') } it 'uses connection host as default host' do conn.host = 'httpbingo.org' expect(subject.host).to eq('httpbingo.org') expect(subject.scheme).to eq('http') end it do conn.path_prefix = '/fish' expect(subject.path).to eq('/fish/sake.html') end it do conn.path_prefix = '/' expect(subject.path).to eq('/sake.html') end it do conn.path_prefix = 'fish' expect(subject.path).to eq('/fish/sake.html') end it do conn.path_prefix = '/fish/' expect(subject.path).to eq('/fish/sake.html') end end context 'with absolute path' do subject { conn.build_exclusive_url('/sake.html') } after { expect(subject.path).to eq('/sake.html') } it { conn.path_prefix = '/fish' } it { conn.path_prefix = '/' } it { conn.path_prefix = 'fish' } it { conn.path_prefix = '/fish/' } end context 'with complete url' do subject { conn.build_exclusive_url('http://httpbingo.org/sake.html?a=1') } it { expect(subject.scheme).to eq('http') } it { expect(subject.host).to eq('httpbingo.org') } it { expect(subject.port).to eq(80) } it { expect(subject.path).to eq('/sake.html') } it { expect(subject.query).to eq('a=1') } end it 'overrides connection port for absolute url' do conn.port = 23 uri = conn.build_exclusive_url('http://httpbingo.org') expect(uri.port).to eq(80) end it 'does not add ending slash given nil url' do conn.url_prefix = 'http://httpbingo.org/nigiri' uri = conn.build_exclusive_url expect(uri.path).to eq('/nigiri') end it 'does not add ending slash given empty url' do conn.url_prefix = 'http://httpbingo.org/nigiri' uri = conn.build_exclusive_url('') expect(uri.path).to eq('/nigiri') end it 'does not use connection params' do conn.url_prefix = 'http://httpbingo.org/nigiri' conn.params = { a: 1 } expect(conn.build_exclusive_url.to_s).to eq('http://httpbingo.org/nigiri') end it 'allows to provide params argument' do conn.url_prefix = 'http://httpbingo.org/nigiri' conn.params = { a: 1 } params = Faraday::Utils::ParamsHash.new params[:a] = 2 uri = conn.build_exclusive_url(nil, params) expect(uri.to_s).to eq('http://httpbingo.org/nigiri?a=2') end it 'handles uri instances' do uri = conn.build_exclusive_url(URI('/sake.html')) expect(uri.path).to eq('/sake.html') end it 'always returns new URI instance' do conn.url_prefix = 'http://httpbingo.org' uri1 = conn.build_exclusive_url(nil) uri2 = conn.build_exclusive_url(nil) expect(uri1).not_to equal(uri2) end context 'with url_prefixed connection' do let(:url) { 'http://httpbingo.org/get/' } it 'parses url and changes scheme' do conn.scheme = 'https' uri = conn.build_exclusive_url('sake.html') expect(uri.to_s).to eq('https://httpbingo.org/get/sake.html') end it 'joins url to base with ending slash' do uri = conn.build_exclusive_url('sake.html') expect(uri.to_s).to eq('http://httpbingo.org/get/sake.html') end it 'used default base with ending slash' do uri = conn.build_exclusive_url expect(uri.to_s).to eq('http://httpbingo.org/get/') end it 'overrides base' do uri = conn.build_exclusive_url('/sake/') expect(uri.to_s).to eq('http://httpbingo.org/sake/') end end context 'with colon in path' do let(:url) { 'http://service.com' } it 'joins url to base when used absolute path' do conn = Faraday.new(url: url) uri = conn.build_exclusive_url('/service:search?limit=400') expect(uri.to_s).to eq('http://service.com/service:search?limit=400') end it 'joins url to base when used relative path' do conn = Faraday.new(url: url) uri = conn.build_exclusive_url('service:search?limit=400') expect(uri.to_s).to eq('http://service.com/service:search?limit=400') end it 'joins url to base when used with path prefix' do conn = Faraday.new(url: url) conn.path_prefix = '/api' uri = conn.build_exclusive_url('service:search?limit=400') expect(uri.to_s).to eq('http://service.com/api/service:search?limit=400') end end context 'with a custom `default_uri_parser`' do let(:url) { 'http://httpbingo.org' } let(:parser) { Addressable::URI } around do |example| with_default_uri_parser(parser) do example.run end end it 'does not raise error' do expect { conn.build_exclusive_url('/nigiri') }.not_to raise_error end end end describe '#build_url' do let(:url) { 'http://httpbingo.org/nigiri' } it 'uses params' do conn.params = { a: 1, b: 1 } expect(conn.build_url.to_s).to eq('http://httpbingo.org/nigiri?a=1&b=1') end it 'merges params' do conn.params = { a: 1, b: 1 } url = conn.build_url(nil, b: 2, c: 3) expect(url.to_s).to eq('http://httpbingo.org/nigiri?a=1&b=2&c=3') end end describe '#build_request' do let(:url) { 'https://ahttpbingo.org/sake.html' } let(:request) { conn.build_request(:get) } before do conn.headers = { 'Authorization' => 'token abc123' } request.headers.delete('Authorization') end it { expect(conn.headers.keys).to eq(['Authorization']) } it { expect(conn.headers.include?('Authorization')).to be_truthy } it { expect(request.headers.keys).to be_empty } it { expect(request.headers.include?('Authorization')).to be_falsey } end describe '#to_env' do subject { conn.build_request(:get).to_env(conn).url } let(:url) { 'http://httpbingo.org/sake.html' } let(:options) { { params: @params } } it 'parses url params into query' do @params = { 'a[b]' => '1 + 2' } expect(subject.query).to eq('a%5Bb%5D=1+%2B+2') end it 'escapes per spec' do @params = { 'a' => '1+2 foo~bar.-baz' } expect(subject.query).to eq('a=1%2B2+foo~bar.-baz') end it 'bracketizes nested params in query' do @params = { 'a' => { 'b' => 'c' } } expect(subject.query).to eq('a%5Bb%5D=c') end it 'bracketizes repeated params in query' do @params = { 'a' => [1, 2] } expect(subject.query).to eq('a%5B%5D=1&a%5B%5D=2') end it 'without braketizing repeated params in query' do @params = { 'a' => [1, 2] } conn.options.params_encoder = Faraday::FlatParamsEncoder expect(subject.query).to eq('a=1&a=2') end end describe 'proxy support' do it 'accepts string' do with_env 'http_proxy' => 'http://env-proxy.com:80' do conn.proxy = 'http://proxy.com' expect(conn.proxy.host).to eq('proxy.com') end end it 'accepts uri' do with_env 'http_proxy' => 'http://env-proxy.com:80' do conn.proxy = URI.parse('http://proxy.com') expect(conn.proxy.host).to eq('proxy.com') end end it 'accepts hash with string uri' do with_env 'http_proxy' => 'http://env-proxy.com:80' do conn.proxy = { uri: 'http://proxy.com', user: 'rick' } expect(conn.proxy.host).to eq('proxy.com') expect(conn.proxy.user).to eq('rick') end end it 'accepts hash' do with_env 'http_proxy' => 'http://env-proxy.com:80' do conn.proxy = { uri: URI.parse('http://proxy.com'), user: 'rick' } expect(conn.proxy.host).to eq('proxy.com') expect(conn.proxy.user).to eq('rick') end end it 'accepts http env' do with_env 'http_proxy' => 'http://env-proxy.com:80' do expect(conn.proxy.host).to eq('env-proxy.com') end end it 'accepts http env with auth' do with_env 'http_proxy' => 'http://a%40b:my%20pass@proxy.com:80' do expect(conn.proxy.user).to eq('a@b') expect(conn.proxy.password).to eq('my pass') end end it 'accepts env without scheme' do with_env 'http_proxy' => 'localhost:8888' do uri = conn.proxy[:uri] expect(uri.host).to eq('localhost') expect(uri.port).to eq(8888) end end it 'fetches no proxy from nil env' do with_env 'http_proxy' => nil do expect(conn.proxy).to be_nil end end it 'fetches no proxy from blank env' do with_env 'http_proxy' => '' do expect(conn.proxy).to be_nil end end it 'does not accept uppercase env' do with_env 'HTTP_PROXY' => 'http://localhost:8888/' do expect(conn.proxy).to be_nil end end it 'allows when url in no proxy list' do with_env 'http_proxy' => 'http://proxy.com', 'no_proxy' => 'example.com' do conn = Faraday::Connection.new('http://example.com') expect(conn.proxy).to be_nil end end it 'allows when url in no proxy list with url_prefix' do with_env 'http_proxy' => 'http://proxy.com', 'no_proxy' => 'example.com' do conn = Faraday::Connection.new conn.url_prefix = 'http://example.com' expect(conn.proxy).to be_nil end end it 'allows when prefixed url is not in no proxy list' do with_env 'http_proxy' => 'http://proxy.com', 'no_proxy' => 'example.com' do conn = Faraday::Connection.new('http://prefixedexample.com') expect(conn.proxy.host).to eq('proxy.com') end end it 'allows when subdomain url is in no proxy list' do with_env 'http_proxy' => 'http://proxy.com', 'no_proxy' => 'example.com' do conn = Faraday::Connection.new('http://subdomain.example.com') expect(conn.proxy).to be_nil end end it 'allows when url not in no proxy list' do with_env 'http_proxy' => 'http://proxy.com', 'no_proxy' => 'example2.com' do conn = Faraday::Connection.new('http://example.com') expect(conn.proxy.host).to eq('proxy.com') end end it 'allows when ip address is not in no proxy list but url is' do with_env 'http_proxy' => 'http://proxy.com', 'no_proxy' => 'localhost' do conn = Faraday::Connection.new('http://127.0.0.1') expect(conn.proxy).to be_nil end end it 'allows when url is not in no proxy list but ip address is' do with_env 'http_proxy' => 'http://proxy.com', 'no_proxy' => '127.0.0.1' do conn = Faraday::Connection.new('http://localhost') expect(conn.proxy).to be_nil end end it 'allows in multi element no proxy list' do with_env 'http_proxy' => 'http://proxy.com', 'no_proxy' => 'example0.com,example.com,example1.com' do expect(Faraday::Connection.new('http://example0.com').proxy).to be_nil expect(Faraday::Connection.new('http://example.com').proxy).to be_nil expect(Faraday::Connection.new('http://example1.com').proxy).to be_nil expect(Faraday::Connection.new('http://example2.com').proxy.host).to eq('proxy.com') end end it 'test proxy requires uri' do expect { conn.proxy = { uri: :bad_uri, user: 'rick' } }.to raise_error(ArgumentError) end it 'uses env http_proxy' do with_env 'http_proxy' => 'http://proxy.com' do conn = Faraday.new expect(conn.instance_variable_get(:@manual_proxy)).to be_falsey expect(conn.proxy_for_request('http://google.co.uk').host).to eq('proxy.com') end end it 'uses processes no_proxy before http_proxy' do with_env 'http_proxy' => 'http://proxy.com', 'no_proxy' => 'google.co.uk' do conn = Faraday.new expect(conn.instance_variable_get(:@manual_proxy)).to be_falsey expect(conn.proxy_for_request('http://google.co.uk')).to be_nil end end it 'uses env https_proxy' do with_env 'https_proxy' => 'https://proxy.com' do conn = Faraday.new expect(conn.instance_variable_get(:@manual_proxy)).to be_falsey expect(conn.proxy_for_request('https://google.co.uk').host).to eq('proxy.com') end end it 'uses processes no_proxy before https_proxy' do with_env 'https_proxy' => 'https://proxy.com', 'no_proxy' => 'google.co.uk' do conn = Faraday.new expect(conn.instance_variable_get(:@manual_proxy)).to be_falsey expect(conn.proxy_for_request('https://google.co.uk')).to be_nil end end it 'gives priority to manually set proxy' do with_env 'https_proxy' => 'https://proxy.com', 'no_proxy' => 'google.co.uk' do conn = Faraday.new conn.proxy = 'http://proxy2.com' expect(conn.instance_variable_get(:@manual_proxy)).to be_truthy expect(conn.proxy_for_request('https://google.co.uk').host).to eq('proxy2.com') end end it 'ignores env proxy if set that way' do with_env_proxy_disabled do with_env 'http_proxy' => 'http://duncan.proxy.com:80' do expect(conn.proxy).to be_nil end end end context 'performing a request' do let(:url) { 'http://example.com' } let(:conn) do Faraday.new do |f| f.adapter :test do |stubs| stubs.get(url) do [200, {}, 'ok'] end end end end it 'dynamically checks proxy' do with_env 'http_proxy' => 'http://proxy.com:80' do expect(conn.proxy.uri.host).to eq('proxy.com') conn.get(url) do |req| expect(req.options.proxy.uri.host).to eq('proxy.com') end end conn.get(url) expect(conn.instance_variable_get(:@temp_proxy)).to be_nil end it 'dynamically check no proxy' do with_env 'http_proxy' => 'http://proxy.com', 'no_proxy' => 'example.com' do expect(conn.proxy.uri.host).to eq('proxy.com') conn.get('http://example.com') do |req| expect(req.options.proxy).to be_nil end end end end end describe '#dup' do subject { conn.dup } let(:url) { 'http://httpbingo.org/foo' } let(:options) do { ssl: { verify: :none }, headers: { 'content-type' => 'text/plain' }, params: { 'a' => '1' }, request: { timeout: 5 } } end it { expect(subject.build_exclusive_url).to eq(conn.build_exclusive_url) } it { expect(subject.headers['content-type']).to eq('text/plain') } it { expect(subject.params['a']).to eq('1') } context 'after manual changes' do before do subject.headers['content-length'] = 12 subject.params['b'] = '2' subject.options[:open_timeout] = 10 end it { expect(subject.builder.handlers.size).to eq(1) } it { expect(conn.builder.handlers.size).to eq(1) } it { expect(conn.headers.key?('content-length')).to be_falsey } it { expect(conn.params.key?('b')).to be_falsey } it { expect(subject.options[:timeout]).to eq(5) } it { expect(conn.options[:open_timeout]).to be_nil } end end describe '#respond_to?' do it { expect(Faraday.respond_to?(:get)).to be_truthy } it { expect(Faraday.respond_to?(:post)).to be_truthy } end describe 'default_connection_options' do context 'assigning a default value' do before do Faraday.default_connection_options = nil Faraday.default_connection_options.request.timeout = 10 end it_behaves_like 'default connection options' end context 'assigning a hash' do before { Faraday.default_connection_options = { request: { timeout: 10 } } } it_behaves_like 'default connection options' end context 'preserving a user_agent assigned via default_conncetion_options' do around do |example| old = Faraday.default_connection_options Faraday.default_connection_options = { headers: { user_agent: 'My Agent 1.2' } } example.run Faraday.default_connection_options = old end context 'when url is a Hash' do let(:conn) { Faraday.new(url: 'http://example.co', headers: { 'CustomHeader' => 'CustomValue' }) } it { expect(conn.headers).to eq('CustomHeader' => 'CustomValue', 'User-Agent' => 'My Agent 1.2') } end context 'when url is a String' do let(:conn) { Faraday.new('http://example.co', headers: { 'CustomHeader' => 'CustomValue' }) } it { expect(conn.headers).to eq('CustomHeader' => 'CustomValue', 'User-Agent' => 'My Agent 1.2') } end end end describe 'request params' do context 'with simple url' do let(:url) { 'http://example.com' } let(:stubs) { Faraday::Adapter::Test::Stubs.new } before do conn.adapter(:test, stubs) stubs.get('http://example.com?a=a&p=3') do [200, {}, 'ok'] end end after { stubs.verify_stubbed_calls } it 'test_overrides_request_params' do conn.get('?p=2&a=a', p: 3) end it 'test_overrides_request_params_block' do conn.get('?p=1&a=a', p: 2) do |req| req.params[:p] = 3 end end it 'test_overrides_request_params_block_url' do conn.get(nil, p: 2) do |req| req.url('?p=1&a=a', 'p' => 3) end end end context 'with url and extra params' do let(:url) { 'http://example.com?a=1&b=2' } let(:options) { { params: { c: 3 } } } let(:stubs) { Faraday::Adapter::Test::Stubs.new } before do conn.adapter(:test, stubs) end it 'merges connection and request params' do expected = 'http://example.com?a=1&b=2&c=3&limit=5&page=1' stubs.get(expected) { [200, {}, 'ok'] } conn.get('?page=1', limit: 5) stubs.verify_stubbed_calls end it 'allows to override all params' do expected = 'http://example.com?b=b' stubs.get(expected) { [200, {}, 'ok'] } conn.get('?p=1&a=a', p: 2) do |req| expect(req.params[:a]).to eq('a') expect(req.params['c']).to eq(3) expect(req.params['p']).to eq(2) req.params = { b: 'b' } expect(req.params['b']).to eq('b') end stubs.verify_stubbed_calls end it 'allows to set params_encoder for single request' do encoder = CustomEncoder.new expected = 'http://example.com/?A-1,B-2,C-3,FEELING-BLUE' stubs.get(expected) { [200, {}, 'ok'] } conn.get('/', a: 1, b: 2, c: 3, feeling: 'blue') do |req| req.options.params_encoder = encoder end stubs.verify_stubbed_calls end end context 'with default params encoder' do let(:stubs) { Faraday::Adapter::Test::Stubs.new } before do conn.adapter(:test, stubs) stubs.get('http://example.com?color%5B%5D=blue&color%5B%5D=red') do [200, {}, 'ok'] end end after { stubs.verify_stubbed_calls } it 'supports array params in url' do conn.get('http://example.com?color[]=blue&color[]=red') end it 'supports array params in params' do conn.get('http://example.com', color: %w[blue red]) end end context 'with flat params encoder' do let(:options) { { request: { params_encoder: Faraday::FlatParamsEncoder } } } let(:stubs) { Faraday::Adapter::Test::Stubs.new } before do conn.adapter(:test, stubs) stubs.get('http://example.com?color=blue&color=red') do [200, {}, 'ok'] end end after { stubs.verify_stubbed_calls } it 'supports array params in params' do conn.get('http://example.com', color: %w[blue red]) end context 'with array param in url' do let(:url) { 'http://example.com?color[]=blue&color[]=red' } it do conn.get('/') end end end end end faraday-2.10.0/spec/faraday/error_spec.rb000066400000000000000000000071421464273144400202470ustar00rootroot00000000000000# frozen_string_literal: true RSpec.describe Faraday::Error do describe '.initialize' do subject { described_class.new(exception, response) } let(:response) { nil } context 'with exception only' do let(:exception) { RuntimeError.new('test') } it { expect(subject.wrapped_exception).to eq(exception) } it { expect(subject.response).to be_nil } it { expect(subject.message).to eq(exception.message) } it { expect(subject.backtrace).to eq(exception.backtrace) } it { expect(subject.inspect).to eq('#>') } it { expect(subject.response_status).to be_nil } it { expect(subject.response_headers).to be_nil } it { expect(subject.response_body).to be_nil } end context 'with response hash' do let(:exception) { { status: 400 } } it { expect(subject.wrapped_exception).to be_nil } it { expect(subject.response).to eq(exception) } it { expect(subject.message).to eq('the server responded with status 400') } it { expect(subject.inspect).to eq('#400}>') } it { expect(subject.response_status).to eq(400) } it { expect(subject.response_headers).to be_nil } it { expect(subject.response_body).to be_nil } end context 'with string' do let(:exception) { 'custom message' } it { expect(subject.wrapped_exception).to be_nil } it { expect(subject.response).to be_nil } it { expect(subject.message).to eq('custom message') } it { expect(subject.inspect).to eq('#>') } it { expect(subject.response_status).to be_nil } it { expect(subject.response_headers).to be_nil } it { expect(subject.response_body).to be_nil } end context 'with anything else #to_s' do let(:exception) { %w[error1 error2] } it { expect(subject.wrapped_exception).to be_nil } it { expect(subject.response).to be_nil } it { expect(subject.message).to eq('["error1", "error2"]') } it { expect(subject.inspect).to eq('#>') } it { expect(subject.response_status).to be_nil } it { expect(subject.response_headers).to be_nil } it { expect(subject.response_body).to be_nil } end context 'with exception string and response hash' do let(:exception) { 'custom message' } let(:response) { { status: 400 } } it { expect(subject.wrapped_exception).to be_nil } it { expect(subject.response).to eq(response) } it { expect(subject.message).to eq('custom message') } it { expect(subject.inspect).to eq('#400}>') } it { expect(subject.response_status).to eq(400) } it { expect(subject.response_headers).to be_nil } it { expect(subject.response_body).to be_nil } end context 'with exception and response object' do let(:exception) { RuntimeError.new('test') } let(:body) { { test: 'test' } } let(:headers) { { 'Content-Type' => 'application/json' } } let(:response) { Faraday::Response.new(status: 400, response_headers: headers, response_body: body) } it { expect(subject.wrapped_exception).to eq(exception) } it { expect(subject.response).to eq(response) } it { expect(subject.message).to eq(exception.message) } it { expect(subject.backtrace).to eq(exception.backtrace) } it { expect(subject.response_status).to eq(400) } it { expect(subject.response_headers).to eq(headers) } it { expect(subject.response_body).to eq(body) } end end end faraday-2.10.0/spec/faraday/middleware_registry_spec.rb000066400000000000000000000020771464273144400231650ustar00rootroot00000000000000# frozen_string_literal: true RSpec.describe Faraday::MiddlewareRegistry do before do stub_const('CustomMiddleware', custom_middleware_klass) end let(:custom_middleware_klass) { Class.new(Faraday::Middleware) } let(:dummy) { Class.new { extend Faraday::MiddlewareRegistry } } after { dummy.unregister_middleware(:custom) } it 'allows to register with constant' do dummy.register_middleware(custom: custom_middleware_klass) expect(dummy.lookup_middleware(:custom)).to eq(custom_middleware_klass) end it 'allows to register with symbol' do dummy.register_middleware(custom: :CustomMiddleware) expect(dummy.lookup_middleware(:custom)).to eq(custom_middleware_klass) end it 'allows to register with string' do dummy.register_middleware(custom: 'CustomMiddleware') expect(dummy.lookup_middleware(:custom)).to eq(custom_middleware_klass) end it 'allows to register with Proc' do dummy.register_middleware(custom: -> { custom_middleware_klass }) expect(dummy.lookup_middleware(:custom)).to eq(custom_middleware_klass) end end faraday-2.10.0/spec/faraday/middleware_spec.rb000066400000000000000000000210361464273144400212310ustar00rootroot00000000000000# frozen_string_literal: true RSpec.describe Faraday::Middleware do subject { described_class.new(app) } let(:app) { double } describe 'options' do context 'when options are passed to the middleware' do subject { described_class.new(app, options) } let(:options) { { field: 'value' } } it 'accepts options when initialized' do expect(subject.options[:field]).to eq('value') end end end describe '#on_request' do subject do Class.new(described_class) do def on_request(env) # do nothing end end.new(app) end it 'is called by #call' do expect(app).to receive(:call).and_return(app) expect(app).to receive(:on_complete) is_expected.to receive(:call).and_call_original is_expected.to receive(:on_request) subject.call(double) end end describe '#on_error' do subject do Class.new(described_class) do def on_error(error) # do nothing end end.new(app) end it 'is called by #call' do expect(app).to receive(:call).and_raise(Faraday::ConnectionFailed) is_expected.to receive(:call).and_call_original is_expected.to receive(:on_error) expect { subject.call(double) }.to raise_error(Faraday::ConnectionFailed) end end describe '#close' do context "with app that doesn't support \#close" do it 'should issue warning' do is_expected.to receive(:warn) subject.close end end context "with app that supports \#close" do it 'should issue warning' do expect(app).to receive(:close) is_expected.to_not receive(:warn) subject.close end end end describe '::default_options' do let(:subclass_no_options) { FaradayMiddlewareSubclasses::SubclassNoOptions } let(:subclass_one_option) { FaradayMiddlewareSubclasses::SubclassOneOption } let(:subclass_two_options) { FaradayMiddlewareSubclasses::SubclassTwoOptions } def build_conn(resp_middleware) Faraday.new do |c| c.adapter :test do |stub| stub.get('/success') { [200, {}, 'ok'] } end c.response resp_middleware end end RSpec.shared_context 'reset @default_options' do before(:each) do FaradayMiddlewareSubclasses::SubclassNoOptions.instance_variable_set(:@default_options, nil) FaradayMiddlewareSubclasses::SubclassOneOption.instance_variable_set(:@default_options, nil) FaradayMiddlewareSubclasses::SubclassTwoOptions.instance_variable_set(:@default_options, nil) Faraday::Middleware.instance_variable_set(:@default_options, nil) end end after(:all) do FaradayMiddlewareSubclasses::SubclassNoOptions.instance_variable_set(:@default_options, nil) FaradayMiddlewareSubclasses::SubclassOneOption.instance_variable_set(:@default_options, nil) FaradayMiddlewareSubclasses::SubclassTwoOptions.instance_variable_set(:@default_options, nil) Faraday::Middleware.instance_variable_set(:@default_options, nil) end context 'with subclass DEFAULT_OPTIONS defined' do include_context 'reset @default_options' context 'and without application options configured' do let(:resp1) { build_conn(:one_option).get('/success') } it 'has only subclass defaults' do expect(Faraday::Middleware.default_options).to eq(Faraday::Middleware::DEFAULT_OPTIONS) expect(subclass_no_options.default_options).to eq(subclass_no_options::DEFAULT_OPTIONS) expect(subclass_one_option.default_options).to eq(subclass_one_option::DEFAULT_OPTIONS) expect(subclass_two_options.default_options).to eq(subclass_two_options::DEFAULT_OPTIONS) end it { expect(resp1.body).to eq('ok') } end context "and with one application's options changed" do let(:resp2) { build_conn(:two_options).get('/success') } before(:each) do FaradayMiddlewareSubclasses::SubclassTwoOptions.default_options = { some_option: false } end it 'only updates default options of target subclass' do expect(Faraday::Middleware.default_options).to eq(Faraday::Middleware::DEFAULT_OPTIONS) expect(subclass_no_options.default_options).to eq(subclass_no_options::DEFAULT_OPTIONS) expect(subclass_one_option.default_options).to eq(subclass_one_option::DEFAULT_OPTIONS) expect(subclass_two_options.default_options).to eq({ some_option: false, some_other_option: false }) end it { expect(resp2.body).to eq('ok') } end context "and with two applications' options changed" do let(:resp1) { build_conn(:one_option).get('/success') } let(:resp2) { build_conn(:two_options).get('/success') } before(:each) do FaradayMiddlewareSubclasses::SubclassOneOption.default_options = { some_other_option: true } FaradayMiddlewareSubclasses::SubclassTwoOptions.default_options = { some_option: false } end it 'updates subclasses and parent independent of each other' do expect(Faraday::Middleware.default_options).to eq(Faraday::Middleware::DEFAULT_OPTIONS) expect(subclass_no_options.default_options).to eq(subclass_no_options::DEFAULT_OPTIONS) expect(subclass_one_option.default_options).to eq({ some_other_option: true }) expect(subclass_two_options.default_options).to eq({ some_option: false, some_other_option: false }) end it { expect(resp1.body).to eq('ok') } it { expect(resp2.body).to eq('ok') } end end context 'with FARADAY::MIDDLEWARE DEFAULT_OPTIONS and with Subclass DEFAULT_OPTIONS' do before(:each) do stub_const('Faraday::Middleware::DEFAULT_OPTIONS', { its_magic: false }) end # Must stub Faraday::Middleware::DEFAULT_OPTIONS before resetting default options include_context 'reset @default_options' context 'and without application options configured' do let(:resp1) { build_conn(:one_option).get('/success') } it 'has only subclass defaults' do expect(Faraday::Middleware.default_options).to eq(Faraday::Middleware::DEFAULT_OPTIONS) expect(FaradayMiddlewareSubclasses::SubclassNoOptions.default_options).to eq({ its_magic: false }) expect(FaradayMiddlewareSubclasses::SubclassOneOption.default_options).to eq({ its_magic: false, some_other_option: false }) expect(FaradayMiddlewareSubclasses::SubclassTwoOptions.default_options).to eq({ its_magic: false, some_option: true, some_other_option: false }) end it { expect(resp1.body).to eq('ok') } end context "and with two applications' options changed" do let(:resp1) { build_conn(:one_option).get('/success') } let(:resp2) { build_conn(:two_options).get('/success') } before(:each) do FaradayMiddlewareSubclasses::SubclassOneOption.default_options = { some_other_option: true } FaradayMiddlewareSubclasses::SubclassTwoOptions.default_options = { some_option: false } end it 'updates subclasses and parent independent of each other' do expect(Faraday::Middleware.default_options).to eq(Faraday::Middleware::DEFAULT_OPTIONS) expect(FaradayMiddlewareSubclasses::SubclassNoOptions.default_options).to eq({ its_magic: false }) expect(FaradayMiddlewareSubclasses::SubclassOneOption.default_options).to eq({ its_magic: false, some_other_option: true }) expect(FaradayMiddlewareSubclasses::SubclassTwoOptions.default_options).to eq({ its_magic: false, some_option: false, some_other_option: false }) end it { expect(resp1.body).to eq('ok') } it { expect(resp2.body).to eq('ok') } end end describe 'default_options input validation' do include_context 'reset @default_options' it 'raises error if Faraday::Middleware option does not exist' do expect { Faraday::Middleware.default_options = { something_special: true } }.to raise_error(Faraday::InitializationError) do |e| expect(e.message).to eq('Invalid options provided. Keys not found in Faraday::Middleware::DEFAULT_OPTIONS: something_special') end end it 'raises error if subclass option does not exist' do expect { subclass_one_option.default_options = { this_is_a_typo: true } }.to raise_error(Faraday::InitializationError) do |e| expect(e.message).to eq('Invalid options provided. Keys not found in FaradayMiddlewareSubclasses::SubclassOneOption::DEFAULT_OPTIONS: this_is_a_typo') end end end end end faraday-2.10.0/spec/faraday/options/000077500000000000000000000000001464273144400172465ustar00rootroot00000000000000faraday-2.10.0/spec/faraday/options/env_spec.rb000066400000000000000000000035321464273144400214000ustar00rootroot00000000000000# frozen_string_literal: true RSpec.describe Faraday::Env do subject(:env) { described_class.new } it 'allows to access members' do expect(env.method).to be_nil env.method = :get expect(env.method).to eq(:get) end it 'allows to access symbol non members' do expect(env[:custom]).to be_nil env[:custom] = :boom expect(env[:custom]).to eq(:boom) end it 'allows to access string non members' do expect(env['custom']).to be_nil env['custom'] = :boom expect(env['custom']).to eq(:boom) end it 'ignores false when fetching' do ssl = Faraday::SSLOptions.new ssl.verify = false expect(ssl.fetch(:verify, true)).to be_falsey end it 'handle verify_hostname when fetching' do ssl = Faraday::SSLOptions.new ssl.verify_hostname = true expect(ssl.fetch(:verify_hostname, false)).to be_truthy end it 'retains custom members' do env[:foo] = 'custom 1' env[:bar] = :custom2 env2 = Faraday::Env.from(env) env2[:baz] = 'custom 3' expect(env2[:foo]).to eq('custom 1') expect(env2[:bar]).to eq(:custom2) expect(env[:baz]).to be_nil end describe '#body' do subject(:env) { described_class.from(body: { foo: 'bar' }) } context 'when response is not finished yet' do it 'returns the request body' do expect(env.body).to eq(foo: 'bar') end end context 'when response is finished' do before do env.status = 200 env.body = { bar: 'foo' } env.response = Faraday::Response.new(env) end it 'returns the response body' do expect(env.body).to eq(bar: 'foo') end it 'allows to access request_body' do expect(env.request_body).to eq(foo: 'bar') end it 'allows to access response_body' do expect(env.response_body).to eq(bar: 'foo') end end end end faraday-2.10.0/spec/faraday/options/options_spec.rb000066400000000000000000000205201464273144400222770ustar00rootroot00000000000000# frozen_string_literal: true RSpec.describe Faraday::Options do SubOptions = Class.new(Faraday::Options.new(:sub_a, :sub_b)) ParentOptions = Faraday::Options.new(:a, :b, :c) do options c: SubOptions end describe '#merge' do it 'merges options with hashes' do options = ParentOptions.new(1) expect(options.a).to eq(1) expect(options.b).to be_nil dup = options.merge a: 2, b: 3 expect(dup.a).to eq(2) expect(dup.b).to eq(3) expect(options.a).to eq(1) expect(options.b).to be_nil end it 'deeply merges two options' do sub_opts1 = SubOptions.from(sub_a: 3) sub_opts2 = SubOptions.from(sub_b: 4) opt1 = ParentOptions.from(a: 1, c: sub_opts1) opt2 = ParentOptions.from(b: 2, c: sub_opts2) merged = opt1.merge(opt2) expected_sub_opts = SubOptions.from(sub_a: 3, sub_b: 4) expected = ParentOptions.from(a: 1, b: 2, c: expected_sub_opts) expect(merged).to eq(expected) end it 'deeply merges options with hashes' do sub_opts1 = SubOptions.from(sub_a: 3) sub_opts2 = { sub_b: 4 } opt1 = ParentOptions.from(a: 1, c: sub_opts1) opt2 = { b: 2, c: sub_opts2 } merged = opt1.merge(opt2) expected_sub_opts = SubOptions.from(sub_a: 3, sub_b: 4) expected = ParentOptions.from(a: 1, b: 2, c: expected_sub_opts) expect(merged).to eq(expected) end it 'deeply merges options with nil' do sub_opts = SubOptions.new(3, 4) options = ParentOptions.new(1, 2, sub_opts) expect(options.a).to eq(1) expect(options.b).to eq(2) expect(options.c.sub_a).to eq(3) expect(options.c.sub_b).to eq(4) options2 = ParentOptions.from(b: 5, c: nil) merged = options.merge(options2) expect(merged.b).to eq(5) expect(merged.c).to eq(sub_opts) end it 'deeply merges options with options having nil sub-options' do options = ParentOptions.from(a: 1) sub_opts = SubOptions.new(3, 4) options2 = ParentOptions.from(b: 2, c: sub_opts) expect(options.a).to eq(1) expect(options2.b).to eq(2) expect(options2.c.sub_a).to eq(3) expect(options2.c.sub_b).to eq(4) merged = options.merge(options2) expect(merged.c).to eq(sub_opts) end describe '#dup' do it 'duplicate options but not sub-options' do sub_opts = SubOptions.from(sub_a: 3) opts = ParentOptions.from(b: 1, c: sub_opts) duped = opts.dup duped.b = 2 duped.c.sub_a = 4 expect(opts.b).to eq(1) expect(opts.c.sub_a).to eq(4) end end describe '#deep_dup' do it 'duplicate options and also suboptions' do sub_opts = SubOptions.from(sub_a: 3) opts = ParentOptions.from(b: 1, c: sub_opts) duped = opts.deep_dup duped.b = 2 duped.c.sub_a = 4 expect(opts.b).to eq(1) expect(opts.c.sub_a).to eq(3) end end describe '#clear' do it 'clears the options' do options = SubOptions.new(1) expect(options.empty?).not_to be_truthy options.clear expect(options.empty?).to be_truthy end end describe '#empty?' do it 'returns true only if all options are nil' do options = SubOptions.new expect(options.empty?).to be_truthy options.sub_a = 1 expect(options.empty?).not_to be_truthy options.delete(:sub_a) expect(options.empty?).to be_truthy end end describe '#each_key' do it 'allows to iterate through keys' do options = ParentOptions.new(1, 2, 3) enum = options.each_key expect(enum.next.to_sym).to eq(:a) expect(enum.next.to_sym).to eq(:b) expect(enum.next.to_sym).to eq(:c) end end describe '#key?' do it 'returns true if the key exists and is not nil' do options = SubOptions.new expect(options.key?(:sub_a)).not_to be_truthy options.sub_a = 1 expect(options.key?(:sub_a)).to be_truthy end end describe '#each_value' do it 'allows to iterate through values' do options = ParentOptions.new(1, 2, 3) enum = options.each_value expect(enum.next).to eq(1) expect(enum.next).to eq(2) expect(enum.next).to eq(3) end end describe '#value?' do it 'returns true if any key has that value' do options = SubOptions.new expect(options.value?(1)).not_to be_truthy options.sub_a = 1 expect(options.value?(1)).to be_truthy end end describe '#update' do it 'updates options from hashes' do options = ParentOptions.new(1) expect(options.a).to eq(1) expect(options.b).to be_nil updated = options.update a: 2, b: 3 expect(options.a).to eq(2) expect(options.b).to eq(3) expect(updated).to eq(options) end end describe '#delete' do it 'allows to remove value for key' do options = ParentOptions.new(1) expect(options.a).to eq(1) expect(options.delete(:a)).to eq(1) expect(options.a).to be_nil end end describe '#from' do it { expect { ParentOptions.from invalid: 1 }.to raise_error(NoMethodError) } it 'works with options' do options = ParentOptions.new(1) value = ParentOptions.from(options) expect(value.a).to eq(1) expect(value.b).to be_nil end it 'works with options with sub object' do sub = SubOptions.new(1) options = ParentOptions.from a: 1, c: sub expect(options).to be_a_kind_of(ParentOptions) expect(options.a).to eq(1) expect(options.b).to be_nil expect(options.c).to be_a_kind_of(SubOptions) expect(options.c.sub_a).to eq(1) end it 'works with hash' do options = ParentOptions.from a: 1 expect(options).to be_a_kind_of(ParentOptions) expect(options.a).to eq(1) expect(options.b).to be_nil end it 'works with hash with sub object' do options = ParentOptions.from a: 1, c: { sub_a: 1 } expect(options).to be_a_kind_of(ParentOptions) expect(options.a).to eq(1) expect(options.b).to be_nil expect(options.c).to be_a_kind_of(SubOptions) expect(options.c.sub_a).to eq(1) end it 'works with deep hash' do hash = { b: 1 } options = ParentOptions.from a: hash expect(options.a[:b]).to eq(1) hash[:b] = 2 expect(options.a[:b]).to eq(1) options.a[:b] = 3 expect(hash[:b]).to eq(2) expect(options.a[:b]).to eq(3) end it 'works with nil' do options = ParentOptions.from(nil) expect(options).to be_a_kind_of(ParentOptions) expect(options.a).to be_nil expect(options.b).to be_nil end it 'respects inheritance' do subclass = Class.new(ParentOptions) options = subclass.from(c: { sub_a: 'hello' }) expect(options.c).to be_a_kind_of(SubOptions) expect(options.c.sub_a).to eq('hello') end end describe '#memoized' do subject(:options_class) { Class.new(ParentOptions) } it 'requires block' do expect { options_class.memoized(:a) }.to raise_error(ArgumentError) end it 'accepts block' do options_class.memoized(:a) { :foo } expect(options_class.new.a).to eql(:foo) end end describe '#fetch' do subject { SubOptions.new } context 'when the fetched key has no value' do it 'uses falsey default' do expect(subject.fetch(:sub_a, false) { |_| :blah }).to be_falsey end it 'accepts block' do expect(subject.fetch(:sub_a) { |k| "yo #{k.inspect}" }).to eq('yo :sub_a') end it 'needs a default if key is missing' do expect { subject.fetch(:sub_a) }.to raise_error(Faraday::Options.fetch_error_class) end end context 'when the fetched key has a value' do before do subject.sub_a = 1 end it 'grabs value' do expect(subject.fetch(:sub_a, false) { |_| :blah }).to eq(1) end it 'works with key' do expect(subject.fetch(:sub_a)).to eq(1) end end end end end faraday-2.10.0/spec/faraday/options/proxy_options_spec.rb000066400000000000000000000033531464273144400235450ustar00rootroot00000000000000# frozen_string_literal: true RSpec.describe Faraday::ProxyOptions do describe '#from' do it 'works with string' do options = Faraday::ProxyOptions.from 'http://user:pass@example.org' expect(options.user).to eq('user') expect(options.password).to eq('pass') expect(options.uri).to be_a_kind_of(URI) expect(options.path).to eq('') expect(options.port).to eq(80) expect(options.host).to eq('example.org') expect(options.scheme).to eq('http') expect(options.inspect).to match('#') end it 'works with no auth' do proxy = Faraday::ProxyOptions.from 'http://example.org' expect(proxy.user).to be_nil expect(proxy.password).to be_nil end it 'treats empty string as nil' do proxy = nil proxy_string = proxy.to_s # => empty string options = Faraday::ProxyOptions.from proxy_string expect(options).to be_a_kind_of(Faraday::ProxyOptions) expect(options.inspect).to eq('#') end end it 'allows hash access' do proxy = Faraday::ProxyOptions.from 'http://a%40b:pw%20d@example.org' expect(proxy.user).to eq('a@b') expect(proxy[:user]).to eq('a@b') expect(proxy.password).to eq('pw d') expect(proxy[:password]).to eq('pw d') end end faraday-2.10.0/spec/faraday/options/request_options_spec.rb000066400000000000000000000010761464273144400240540ustar00rootroot00000000000000# frozen_string_literal: true RSpec.describe Faraday::RequestOptions do subject(:options) { Faraday::RequestOptions.new } it 'allows to set the request proxy' do expect(options.proxy).to be_nil expect { options[:proxy] = { booya: 1 } }.to raise_error(NoMethodError) options[:proxy] = { user: 'user' } expect(options.proxy).to be_a_kind_of(Faraday::ProxyOptions) expect(options.proxy.user).to eq('user') options.proxy = nil expect(options.proxy).to be_nil expect(options.inspect).to eq('#') end end faraday-2.10.0/spec/faraday/params_encoders/000077500000000000000000000000001464273144400207205ustar00rootroot00000000000000faraday-2.10.0/spec/faraday/params_encoders/flat_spec.rb000066400000000000000000000022051464273144400232040ustar00rootroot00000000000000# frozen_string_literal: true require 'rack/utils' RSpec.describe Faraday::FlatParamsEncoder do it_behaves_like 'a params encoder' it 'decodes arrays' do query = 'a=one&a=two&a=three' expected = { 'a' => %w[one two three] } expect(subject.decode(query)).to eq(expected) end it 'decodes boolean values' do query = 'a=true&b=false' expected = { 'a' => 'true', 'b' => 'false' } expect(subject.decode(query)).to eq(expected) end it 'encodes boolean values' do params = { a: true, b: false } expect(subject.encode(params)).to eq('a=true&b=false') end it 'encodes boolean values in array' do params = { a: [true, false] } expect(subject.encode(params)).to eq('a=true&a=false') end it 'encodes empty array in hash' do params = { a: [] } expect(subject.encode(params)).to eq('a=') end it 'encodes unsorted when asked' do params = { b: false, a: true } expect(subject.encode(params)).to eq('a=true&b=false') Faraday::FlatParamsEncoder.sort_params = false expect(subject.encode(params)).to eq('b=false&a=true') Faraday::FlatParamsEncoder.sort_params = true end end faraday-2.10.0/spec/faraday/params_encoders/nested_spec.rb000066400000000000000000000115061464273144400235440ustar00rootroot00000000000000# frozen_string_literal: true require 'rack/utils' RSpec.describe Faraday::NestedParamsEncoder do it_behaves_like 'a params encoder' it 'decodes arrays' do query = 'a[1]=one&a[2]=two&a[3]=three' expected = { 'a' => %w[one two three] } expect(subject.decode(query)).to eq(expected) end it 'decodes hashes' do query = 'a[b1]=one&a[b2]=two&a[b][c]=foo' expected = { 'a' => { 'b1' => 'one', 'b2' => 'two', 'b' => { 'c' => 'foo' } } } expect(subject.decode(query)).to eq(expected) end it 'decodes nested arrays rack compat' do query = 'a[][one]=1&a[][two]=2&a[][one]=3&a[][two]=4' expected = Rack::Utils.parse_nested_query(query) expect(subject.decode(query)).to eq(expected) end it 'decodes nested array mixed types' do query = 'a[][one]=1&a[]=2&a[]=&a[]' expected = Rack::Utils.parse_nested_query(query) expect(subject.decode(query)).to eq(expected) end it 'decodes nested ignores invalid array' do query = '[][a]=1&b=2' expected = { 'a' => '1', 'b' => '2' } expect(subject.decode(query)).to eq(expected) end it 'decodes nested ignores repeated array notation' do query = 'a[][][]=1' expected = { 'a' => ['1'] } expect(subject.decode(query)).to eq(expected) end it 'decodes nested ignores malformed keys' do query = '=1&[]=2' expected = {} expect(subject.decode(query)).to eq(expected) end it 'decodes nested subkeys dont have to be in brackets' do query = 'a[b]c[d]e=1' expected = { 'a' => { 'b' => { 'c' => { 'd' => { 'e' => '1' } } } } } expect(subject.decode(query)).to eq(expected) end it 'decodes nested final value overrides any type' do query = 'a[b][c]=1&a[b]=2' expected = { 'a' => { 'b' => '2' } } expect(subject.decode(query)).to eq(expected) end it 'encodes rack compat' do params = { a: [{ one: '1', two: '2' }, '3', ''] } result = Faraday::Utils.unescape(Faraday::NestedParamsEncoder.encode(params)).split('&') escaped = Rack::Utils.build_nested_query(params) expected = Rack::Utils.unescape(escaped).split('&') expect(result).to match_array(expected) end it 'encodes empty string array value' do expected = 'baz=&foo%5Bbar%5D=' result = Faraday::NestedParamsEncoder.encode(foo: { bar: '' }, baz: '') expect(result).to eq(expected) end it 'encodes nil array value' do expected = 'baz&foo%5Bbar%5D' result = Faraday::NestedParamsEncoder.encode(foo: { bar: nil }, baz: nil) expect(result).to eq(expected) end it 'encodes empty array value' do expected = 'baz%5B%5D&foo%5Bbar%5D%5B%5D' result = Faraday::NestedParamsEncoder.encode(foo: { bar: [] }, baz: []) expect(result).to eq(expected) end it 'encodes boolean values' do params = { a: true, b: false } expect(subject.encode(params)).to eq('a=true&b=false') end it 'encodes boolean values in array' do params = { a: [true, false] } expect(subject.encode(params)).to eq('a%5B%5D=true&a%5B%5D=false') end it 'encodes unsorted when asked' do params = { b: false, a: true } expect(subject.encode(params)).to eq('a=true&b=false') Faraday::NestedParamsEncoder.sort_params = false expect(subject.encode(params)).to eq('b=false&a=true') Faraday::NestedParamsEncoder.sort_params = true end it 'encodes arrays indices when asked' do params = { a: [0, 1, 2] } expect(subject.encode(params)).to eq('a%5B%5D=0&a%5B%5D=1&a%5B%5D=2') Faraday::NestedParamsEncoder.array_indices = true expect(subject.encode(params)).to eq('a%5B0%5D=0&a%5B1%5D=1&a%5B2%5D=2') Faraday::NestedParamsEncoder.array_indices = false end shared_examples 'a wrong decoding' do it do expect { subject.decode(query) }.to raise_error(TypeError) do |e| expect(e.message).to eq(error_message) end end end context 'when expecting hash but getting string' do let(:query) { 'a=1&a[b]=2' } let(:error_message) { "expected Hash (got String) for param `a'" } it_behaves_like 'a wrong decoding' end context 'when expecting hash but getting array' do let(:query) { 'a[]=1&a[b]=2' } let(:error_message) { "expected Hash (got Array) for param `a'" } it_behaves_like 'a wrong decoding' end context 'when expecting nested hash but getting non nested' do let(:query) { 'a[b]=1&a[b][c]=2' } let(:error_message) { "expected Hash (got String) for param `b'" } it_behaves_like 'a wrong decoding' end context 'when expecting array but getting hash' do let(:query) { 'a[b]=1&a[]=2' } let(:error_message) { "expected Array (got Hash) for param `a'" } it_behaves_like 'a wrong decoding' end context 'when expecting array but getting string' do let(:query) { 'a=1&a[]=2' } let(:error_message) { "expected Array (got String) for param `a'" } it_behaves_like 'a wrong decoding' end end faraday-2.10.0/spec/faraday/rack_builder_spec.rb000066400000000000000000000214751464273144400215510ustar00rootroot00000000000000# frozen_string_literal: true RSpec.describe Faraday::RackBuilder do # mock handler classes (Handler = Struct.new(:app)).class_eval do def call(env) env[:request_headers]['X-Middleware'] ||= '' env[:request_headers]['X-Middleware'] += ":#{self.class.name.split('::').last}" app.call(env) end end class Apple < Handler end class Orange < Handler end class Banana < Handler end subject { conn.builder } before { Faraday.default_adapter = :test } after { Faraday.default_adapter = nil } context 'with default stack' do let(:conn) { Faraday::Connection.new } it { expect(subject[0]).to eq(Faraday::Request.lookup_middleware(:url_encoded)) } it { expect(subject.adapter).to eq(Faraday::Adapter.lookup_middleware(Faraday.default_adapter)) } end context 'with custom empty block' do let(:conn) { Faraday::Connection.new {} } it { expect(subject[0]).to be_nil } it { expect(subject.adapter).to eq(Faraday::Adapter.lookup_middleware(Faraday.default_adapter)) } end context 'with custom adapter only' do let(:conn) do Faraday::Connection.new do |builder| builder.adapter :test do |stub| stub.get('/') { |_| [200, {}, ''] } end end end it { expect(subject[0]).to be_nil } it { expect(subject.adapter).to eq(Faraday::Adapter.lookup_middleware(:test)) } end context 'with custom handler and adapter' do let(:conn) do Faraday::Connection.new do |builder| builder.use Apple builder.adapter :test do |stub| stub.get('/') { |_| [200, {}, ''] } end end end it 'locks the stack after making a request' do expect(subject.locked?).to be_falsey conn.get('/') expect(subject.locked?).to be_truthy expect { subject.use(Orange) }.to raise_error(Faraday::RackBuilder::StackLocked) end it 'dup stack is unlocked' do expect(subject.locked?).to be_falsey subject.lock! expect(subject.locked?).to be_truthy dup = subject.dup expect(dup).to eq(subject) expect(dup.locked?).to be_falsey end it 'allows to compare handlers' do expect(subject.handlers.first).to eq(Faraday::RackBuilder::Handler.new(Apple)) end end context 'when having a single handler' do let(:conn) { Faraday::Connection.new {} } before { subject.use(Apple) } it { expect(subject.handlers).to eq([Apple]) } it 'allows use' do subject.use(Orange) expect(subject.handlers).to eq([Apple, Orange]) end it 'allows insert_before' do subject.insert_before(Apple, Orange) expect(subject.handlers).to eq([Orange, Apple]) end it 'allows insert_after' do subject.insert_after(Apple, Orange) expect(subject.handlers).to eq([Apple, Orange]) end it 'raises an error trying to use an unregistered symbol' do expect { subject.use(:apple) }.to raise_error(Faraday::Error) do |err| expect(err.message).to eq(':apple is not registered on Faraday::Middleware') end end end context 'when having two handlers' do let(:conn) { Faraday::Connection.new {} } before do subject.use(Apple) subject.use(Orange) end it 'allows insert_before' do subject.insert_before(Orange, Banana) expect(subject.handlers).to eq([Apple, Banana, Orange]) end it 'allows insert_after' do subject.insert_after(Apple, Banana) expect(subject.handlers).to eq([Apple, Banana, Orange]) end it 'allows to swap handlers' do subject.swap(Apple, Banana) expect(subject.handlers).to eq([Banana, Orange]) end it 'allows to delete a handler' do subject.delete(Apple) expect(subject.handlers).to eq([Orange]) end end context 'when adapter is added with named options' do after { Faraday.default_adapter_options = {} } let(:conn) { Faraday::Connection.new {} } let(:cat_adapter) do Class.new(Faraday::Adapter) do attr_accessor :name def initialize(app, name:) super(app) @name = name end end end let(:cat) { subject.adapter.build } it 'adds a handler to construct adapter with named options' do Faraday.default_adapter = cat_adapter Faraday.default_adapter_options = { name: 'Chloe' } expect { cat }.to_not output( /warning: Using the last argument as keyword parameters is deprecated/ ).to_stderr expect(cat.name).to eq 'Chloe' end end context 'when middleware is added with named arguments' do let(:conn) { Faraday::Connection.new {} } let(:dog_middleware) do Class.new(Faraday::Middleware) do attr_accessor :name def initialize(app, name:) super(app) @name = name end end end let(:dog) do subject.handlers.find { |handler| handler == dog_middleware }.build end it 'adds a handler to construct middleware with options passed to use' do subject.use dog_middleware, name: 'Rex' expect { dog }.to_not output( /warning: Using the last argument as keyword parameters is deprecated/ ).to_stderr expect(dog.name).to eq('Rex') end end context 'when a middleware is added with named arguments' do let(:conn) { Faraday::Connection.new {} } let(:cat_request) do Class.new(Faraday::Middleware) do attr_accessor :name def initialize(app, name:) super(app) @name = name end end end let(:cat) do subject.handlers.find { |handler| handler == cat_request }.build end it 'adds a handler to construct request adapter with options passed to request' do Faraday::Request.register_middleware cat_request: cat_request subject.request :cat_request, name: 'Felix' expect { cat }.to_not output( /warning: Using the last argument as keyword parameters is deprecated/ ).to_stderr expect(cat.name).to eq('Felix') end end context 'when a middleware is added with named arguments' do let(:conn) { Faraday::Connection.new {} } let(:fish_response) do Class.new(Faraday::Middleware) do attr_accessor :name def initialize(app, name:) super(app) @name = name end end end let(:fish) do subject.handlers.find { |handler| handler == fish_response }.build end it 'adds a handler to construct response adapter with options passed to response' do Faraday::Response.register_middleware fish_response: fish_response subject.response :fish_response, name: 'Bubbles' expect { fish }.to_not output( /warning: Using the last argument as keyword parameters is deprecated/ ).to_stderr expect(fish.name).to eq('Bubbles') end end context 'when a plain adapter is added with named arguments' do let(:conn) { Faraday::Connection.new {} } let(:rabbit_adapter) do Class.new(Faraday::Adapter) do attr_accessor :name def initialize(app, name:) super(app) @name = name end end end let(:rabbit) do subject.adapter.build end it 'adds a handler to construct adapter with options passed to adapter' do Faraday::Adapter.register_middleware rabbit_adapter: rabbit_adapter subject.adapter :rabbit_adapter, name: 'Thumper' expect { rabbit }.to_not output( /warning: Using the last argument as keyword parameters is deprecated/ ).to_stderr expect(rabbit.name).to eq('Thumper') end end context 'when handlers are directly added or updated' do let(:conn) { Faraday::Connection.new {} } let(:rock_handler) do Class.new do attr_accessor :name def initialize(_app, name:) @name = name end end end let(:rock) do subject.handlers.find { |handler| handler == rock_handler }.build end it 'adds a handler to construct adapter with options passed to insert' do subject.insert 0, rock_handler, name: 'Stony' expect { rock }.to_not output( /warning: Using the last argument as keyword parameters is deprecated/ ).to_stderr expect(rock.name).to eq('Stony') end it 'adds a handler with options passed to insert_after' do subject.insert_after 0, rock_handler, name: 'Rocky' expect { rock }.to_not output( /warning: Using the last argument as keyword parameters is deprecated/ ).to_stderr expect(rock.name).to eq('Rocky') end it 'adds a handler with options passed to swap' do subject.insert 0, rock_handler, name: 'Flint' subject.swap 0, rock_handler, name: 'Chert' expect { rock }.to_not output( /warning: Using the last argument as keyword parameters is deprecated/ ).to_stderr expect(rock.name).to eq('Chert') end end end faraday-2.10.0/spec/faraday/request/000077500000000000000000000000001464273144400172435ustar00rootroot00000000000000faraday-2.10.0/spec/faraday/request/authorization_spec.rb000066400000000000000000000067551464273144400235170ustar00rootroot00000000000000# frozen_string_literal: true RSpec.describe Faraday::Request::Authorization do let(:conn) do Faraday.new do |b| b.request :authorization, auth_type, *auth_config b.adapter :test do |stub| stub.get('/auth-echo') do |env| [200, {}, env[:request_headers]['Authorization']] end end end end shared_examples 'does not interfere with existing authentication' do context 'and request already has an authentication header' do let(:response) { conn.get('/auth-echo', nil, authorization: 'OAuth oauth_token') } it 'does not interfere with existing authorization' do expect(response.body).to eq('OAuth oauth_token') end end end let(:response) { conn.get('/auth-echo') } describe 'basic_auth' do let(:auth_type) { :basic } context 'when passed correct params' do let(:auth_config) { %w[aladdin opensesame] } it { expect(response.body).to eq('Basic YWxhZGRpbjpvcGVuc2VzYW1l') } include_examples 'does not interfere with existing authentication' end context 'when passed very long values' do let(:auth_config) { ['A' * 255, ''] } it { expect(response.body).to eq("Basic #{'QUFB' * 85}Og==") } include_examples 'does not interfere with existing authentication' end end describe 'authorization' do let(:auth_type) { :Bearer } context 'when passed a string' do let(:auth_config) { ['custom'] } it { expect(response.body).to eq('Bearer custom') } include_examples 'does not interfere with existing authentication' end context 'when passed a proc' do let(:auth_config) { [-> { 'custom_from_proc' }] } it { expect(response.body).to eq('Bearer custom_from_proc') } include_examples 'does not interfere with existing authentication' end context 'when passed a callable' do let(:callable) { double('Callable Authorizer', call: 'custom_from_callable') } let(:auth_config) { [callable] } it { expect(response.body).to eq('Bearer custom_from_callable') } include_examples 'does not interfere with existing authentication' end context 'with an argument' do let(:response) { conn.get('/auth-echo', nil, 'middle' => 'crunchy surprise') } context 'when passed a proc' do let(:auth_config) { [proc { |env| "proc #{env.request_headers['middle']}" }] } it { expect(response.body).to eq('Bearer proc crunchy surprise') } include_examples 'does not interfere with existing authentication' end context 'when passed a lambda' do let(:auth_config) { [->(env) { "lambda #{env.request_headers['middle']}" }] } it { expect(response.body).to eq('Bearer lambda crunchy surprise') } include_examples 'does not interfere with existing authentication' end context 'when passed a callable with an argument' do let(:callable) do Class.new do def call(env) "callable #{env.request_headers['middle']}" end end.new end let(:auth_config) { [callable] } it { expect(response.body).to eq('Bearer callable crunchy surprise') } include_examples 'does not interfere with existing authentication' end end context 'when passed too many arguments' do let(:auth_config) { %w[baz foo] } it { expect { response }.to raise_error(ArgumentError) } include_examples 'does not interfere with existing authentication' end end end faraday-2.10.0/spec/faraday/request/instrumentation_spec.rb000066400000000000000000000036121464273144400240470ustar00rootroot00000000000000# frozen_string_literal: true RSpec.describe Faraday::Request::Instrumentation do class FakeInstrumenter attr_reader :instrumentations def initialize @instrumentations = [] end def instrument(name, env) @instrumentations << [name, env] yield end end let(:config) { {} } let(:options) { Faraday::Request::Instrumentation::Options.from config } let(:instrumenter) { FakeInstrumenter.new } let(:conn) do Faraday.new do |f| f.request :instrumentation, config.merge(instrumenter: instrumenter) f.adapter :test do |stub| stub.get '/' do [200, {}, 'ok'] end end end end it { expect(options.name).to eq('request.faraday') } it 'defaults to ActiveSupport::Notifications' do res = options.instrumenter rescue NameError => e expect(e.to_s).to match('ActiveSupport') else expect(res).to eq(ActiveSupport::Notifications) end it 'instruments with default name' do expect(instrumenter.instrumentations.size).to eq(0) res = conn.get '/' expect(res.body).to eq('ok') expect(instrumenter.instrumentations.size).to eq(1) name, env = instrumenter.instrumentations.first expect(name).to eq('request.faraday') expect(env[:url].path).to eq('/') end context 'with custom name' do let(:config) { { name: 'custom' } } it { expect(options.name).to eq('custom') } it 'instruments with custom name' do expect(instrumenter.instrumentations.size).to eq(0) res = conn.get '/' expect(res.body).to eq('ok') expect(instrumenter.instrumentations.size).to eq(1) name, env = instrumenter.instrumentations.first expect(name).to eq('custom') expect(env[:url].path).to eq('/') end end context 'with custom instrumenter' do let(:config) { { instrumenter: :custom } } it { expect(options.instrumenter).to eq(:custom) } end end faraday-2.10.0/spec/faraday/request/json_spec.rb000066400000000000000000000111251464273144400215530ustar00rootroot00000000000000# frozen_string_literal: true RSpec.describe Faraday::Request::Json do let(:middleware) { described_class.new(->(env) { Faraday::Response.new(env) }) } def process(body, content_type = nil) env = { body: body, request_headers: Faraday::Utils::Headers.new } env[:request_headers]['content-type'] = content_type if content_type middleware.call(Faraday::Env.from(env)).env end def result_body result[:body] end def result_type result[:request_headers]['content-type'] end context 'no body' do let(:result) { process(nil) } it "doesn't change body" do expect(result_body).to be_nil end it "doesn't add content type" do expect(result_type).to be_nil end end context 'empty body' do let(:result) { process('') } it "doesn't change body" do expect(result_body).to be_empty end it "doesn't add content type" do expect(result_type).to be_nil end end context 'string body' do let(:result) { process('{"a":1}') } it "doesn't change body" do expect(result_body).to eq('{"a":1}') end it 'adds content type' do expect(result_type).to eq('application/json') end end context 'object body' do let(:result) { process(a: 1) } it 'encodes body' do expect(result_body).to eq('{"a":1}') end it 'adds content type' do expect(result_type).to eq('application/json') end end context 'empty object body' do let(:result) { process({}) } it 'encodes body' do expect(result_body).to eq('{}') end end context 'true body' do let(:result) { process(true) } it 'encodes body' do expect(result_body).to eq('true') end it 'adds content type' do expect(result_type).to eq('application/json') end end context 'false body' do let(:result) { process(false) } it 'encodes body' do expect(result_body).to eq('false') end it 'adds content type' do expect(result_type).to eq('application/json') end end context 'object body with json type' do let(:result) { process({ a: 1 }, 'application/json; charset=utf-8') } it 'encodes body' do expect(result_body).to eq('{"a":1}') end it "doesn't change content type" do expect(result_type).to eq('application/json; charset=utf-8') end end context 'object body with vendor json type' do let(:result) { process({ a: 1 }, 'application/vnd.myapp.v1+json; charset=utf-8') } it 'encodes body' do expect(result_body).to eq('{"a":1}') end it "doesn't change content type" do expect(result_type).to eq('application/vnd.myapp.v1+json; charset=utf-8') end end context 'object body with incompatible type' do let(:result) { process({ a: 1 }, 'application/xml; charset=utf-8') } it "doesn't change body" do expect(result_body).to eq(a: 1) end it "doesn't change content type" do expect(result_type).to eq('application/xml; charset=utf-8') end end context 'with encoder' do let(:encoder) do double('Encoder').tap do |e| allow(e).to receive(:dump) { |s, opts| JSON.generate(s, opts) } end end let(:result) { process(a: 1) } context 'when encoder is passed as object' do let(:middleware) { described_class.new(->(env) { Faraday::Response.new(env) }, { encoder: encoder }) } it 'calls specified JSON encoder\'s dump method' do expect(encoder).to receive(:dump).with({ a: 1 }) result end it 'encodes body' do expect(result_body).to eq('{"a":1}') end it 'adds content type' do expect(result_type).to eq('application/json') end end context 'when encoder is passed as an object-method pair' do let(:middleware) { described_class.new(->(env) { Faraday::Response.new(env) }, { encoder: [encoder, :dump] }) } it 'calls specified JSON encoder' do expect(encoder).to receive(:dump).with({ a: 1 }) result end it 'encodes body' do expect(result_body).to eq('{"a":1}') end it 'adds content type' do expect(result_type).to eq('application/json') end end context 'when encoder is not passed' do let(:middleware) { described_class.new(->(env) { Faraday::Response.new(env) }) } it 'calls JSON.generate' do expect(JSON).to receive(:generate).with({ a: 1 }) result end it 'encodes body' do expect(result_body).to eq('{"a":1}') end it 'adds content type' do expect(result_type).to eq('application/json') end end end end faraday-2.10.0/spec/faraday/request/url_encoded_spec.rb000066400000000000000000000062501464273144400230700ustar00rootroot00000000000000# frozen_string_literal: true require 'stringio' RSpec.describe Faraday::Request::UrlEncoded do let(:conn) do Faraday.new do |b| b.request :url_encoded b.adapter :test do |stub| stub.post('/echo') do |env| posted_as = env[:request_headers]['Content-Type'] body = env[:body] if body.respond_to?(:read) body = body.read end [200, { 'Content-Type' => posted_as }, body] end end end end it 'does nothing without payload' do response = conn.post('/echo') expect(response.headers['Content-Type']).to be_nil expect(response.body.empty?).to be_truthy end it 'ignores custom content type' do response = conn.post('/echo', { some: 'data' }, 'content-type' => 'application/x-foo') expect(response.headers['Content-Type']).to eq('application/x-foo') expect(response.body).to eq(some: 'data') end it 'works with no headers' do response = conn.post('/echo', fruit: %w[apples oranges]) expect(response.headers['Content-Type']).to eq('application/x-www-form-urlencoded') expect(response.body).to eq('fruit%5B%5D=apples&fruit%5B%5D=oranges') end it 'works with with headers' do response = conn.post('/echo', { 'a' => 123 }, 'content-type' => 'application/x-www-form-urlencoded') expect(response.headers['Content-Type']).to eq('application/x-www-form-urlencoded') expect(response.body).to eq('a=123') end it 'works with nested params' do response = conn.post('/echo', user: { name: 'Mislav', web: 'mislav.net' }) expect(response.headers['Content-Type']).to eq('application/x-www-form-urlencoded') expected = { 'user' => { 'name' => 'Mislav', 'web' => 'mislav.net' } } expect(Faraday::Utils.parse_nested_query(response.body)).to eq(expected) end it 'works with non nested params' do response = conn.post('/echo', dimensions: %w[date location]) do |req| req.options.params_encoder = Faraday::FlatParamsEncoder end expect(response.headers['Content-Type']).to eq('application/x-www-form-urlencoded') expected = { 'dimensions' => %w[date location] } expect(Faraday::Utils.parse_query(response.body)).to eq(expected) expect(response.body).to eq('dimensions=date&dimensions=location') end it 'works with unicode' do err = capture_warnings do response = conn.post('/echo', str: 'eé cç aã aâ') expect(response.body).to eq('str=e%C3%A9+c%C3%A7+a%C3%A3+a%C3%A2') end expect(err.empty?).to be_truthy end it 'works with nested keys' do response = conn.post('/echo', 'a' => { 'b' => { 'c' => ['d'] } }) expect(response.body).to eq('a%5Bb%5D%5Bc%5D%5B%5D=d') end it 'works with files' do response = conn.post('/echo', StringIO.new('str=apple')) expect(response.body).to eq('str=apple') end context 'customising default_space_encoding' do around do |example| Faraday::Utils.default_space_encoding = '%20' example.run Faraday::Utils.default_space_encoding = nil end it 'uses the custom character to encode spaces' do response = conn.post('/echo', str: 'apple banana') expect(response.body).to eq('str=apple%20banana') end end end faraday-2.10.0/spec/faraday/request_spec.rb000066400000000000000000000073241464273144400206100ustar00rootroot00000000000000# frozen_string_literal: true RSpec.describe Faraday::Request do let(:conn) do Faraday.new(url: 'http://httpbingo.org/api', headers: { 'Mime-Version' => '1.0' }, request: { oauth: { consumer_key: 'anonymous' } }) end let(:http_method) { :get } let(:block) { nil } subject { conn.build_request(http_method, &block) } context 'when nothing particular is configured' do it { expect(subject.http_method).to eq(:get) } it { expect(subject.to_env(conn).ssl.verify).to be_falsey } it { expect(subject.to_env(conn).ssl.verify_hostname).to be_falsey } end context 'when HTTP method is post' do let(:http_method) { :post } it { expect(subject.http_method).to eq(:post) } end context 'when setting the url on setup with a URI' do let(:block) { proc { |req| req.url URI.parse('foo.json?a=1') } } it { expect(subject.path).to eq(URI.parse('foo.json')) } it { expect(subject.params).to eq('a' => '1') } it { expect(subject.to_env(conn).url.to_s).to eq('http://httpbingo.org/api/foo.json?a=1') } end context 'when setting the url on setup with a string path and params' do let(:block) { proc { |req| req.url 'foo.json', 'a' => 1 } } it { expect(subject.path).to eq('foo.json') } it { expect(subject.params).to eq('a' => 1) } it { expect(subject.to_env(conn).url.to_s).to eq('http://httpbingo.org/api/foo.json?a=1') } end context 'when setting the url on setup with a path including params' do let(:block) { proc { |req| req.url 'foo.json?b=2&a=1#qqq' } } it { expect(subject.path).to eq('foo.json') } it { expect(subject.params).to eq('a' => '1', 'b' => '2') } it { expect(subject.to_env(conn).url.to_s).to eq('http://httpbingo.org/api/foo.json?a=1&b=2') } end context 'when setting a header on setup with []= syntax' do let(:block) { proc { |req| req['Server'] = 'Faraday' } } let(:headers) { subject.to_env(conn).request_headers } it { expect(subject.headers['Server']).to eq('Faraday') } it { expect(headers['mime-version']).to eq('1.0') } it { expect(headers['server']).to eq('Faraday') } end context 'when setting the body on setup' do let(:block) { proc { |req| req.body = 'hi' } } it { expect(subject.body).to eq('hi') } it { expect(subject.to_env(conn).body).to eq('hi') } end context 'with global request options set' do let(:env_request) { subject.to_env(conn).request } before do conn.options.timeout = 3 conn.options.open_timeout = 5 conn.ssl.verify = false conn.proxy = 'http://proxy.com' end it { expect(subject.options.timeout).to eq(3) } it { expect(subject.options.open_timeout).to eq(5) } it { expect(env_request.timeout).to eq(3) } it { expect(env_request.open_timeout).to eq(5) } context 'and per-request options set' do let(:block) do proc do |req| req.options.timeout = 10 req.options.boundary = 'boo' req.options.oauth[:consumer_secret] = 'xyz' req.options.context = { foo: 'foo', bar: 'bar' } end end it { expect(subject.options.timeout).to eq(10) } it { expect(subject.options.open_timeout).to eq(5) } it { expect(env_request.timeout).to eq(10) } it { expect(env_request.open_timeout).to eq(5) } it { expect(env_request.boundary).to eq('boo') } it { expect(env_request.context).to eq(foo: 'foo', bar: 'bar') } it do oauth_expected = { consumer_secret: 'xyz', consumer_key: 'anonymous' } expect(env_request.oauth).to eq(oauth_expected) end end end it 'supports marshal serialization' do expect(Marshal.load(Marshal.dump(subject))).to eq(subject) end end faraday-2.10.0/spec/faraday/response/000077500000000000000000000000001464273144400174115ustar00rootroot00000000000000faraday-2.10.0/spec/faraday/response/json_spec.rb000066400000000000000000000130541464273144400217240ustar00rootroot00000000000000# frozen_string_literal: true RSpec.describe Faraday::Response::Json, type: :response do let(:options) { {} } let(:headers) { {} } let(:middleware) do described_class.new(lambda { |env| Faraday::Response.new(env) }, **options) end def process(body, content_type = 'application/json', options = {}) env = { body: body, request: options, request_headers: Faraday::Utils::Headers.new, response_headers: Faraday::Utils::Headers.new(headers) } env[:response_headers]['content-type'] = content_type if content_type yield(env) if block_given? middleware.call(Faraday::Env.from(env)) end context 'no type matching' do it "doesn't change nil body" do expect(process(nil).body).to be_nil end it 'nullifies empty body' do expect(process('').body).to be_nil end it 'parses json body' do response = process('{"a":1}') expect(response.body).to eq('a' => 1) expect(response.env[:raw_body]).to be_nil end end context 'with preserving raw' do let(:options) { { preserve_raw: true } } it 'parses json body' do response = process('{"a":1}') expect(response.body).to eq('a' => 1) expect(response.env[:raw_body]).to eq('{"a":1}') end end context 'with default regexp type matching' do it 'parses json body of correct type' do response = process('{"a":1}', 'application/x-json') expect(response.body).to eq('a' => 1) end it 'ignores json body of incorrect type' do response = process('{"a":1}', 'text/json-xml') expect(response.body).to eq('{"a":1}') end end context 'with array type matching' do let(:options) { { content_type: %w[a/b c/d] } } it 'parses json body of correct type' do expect(process('{"a":1}', 'a/b').body).to be_a(Hash) expect(process('{"a":1}', 'c/d').body).to be_a(Hash) end it 'ignores json body of incorrect type' do expect(process('{"a":1}', 'a/d').body).not_to be_a(Hash) end end it 'chokes on invalid json' do expect { process('{!') }.to raise_error(Faraday::ParsingError) end it 'includes the response on the ParsingError instance' do process('{') { |env| env[:response] = Faraday::Response.new } raise 'Parsing should have failed.' rescue Faraday::ParsingError => e expect(e.response).to be_a(Faraday::Response) end context 'HEAD responses' do it "nullifies the body if it's only one space" do response = process(' ') expect(response.body).to be_nil end it "nullifies the body if it's two spaces" do response = process(' ') expect(response.body).to be_nil end end context 'JSON options' do let(:body) { '{"a": 1}' } let(:result) { { a: 1 } } let(:options) do { parser_options: { symbolize_names: true } } end it 'passes relevant options to JSON parse' do expect(::JSON).to receive(:parse) .with(body, options[:parser_options]) .and_return(result) response = process(body) expect(response.body).to eq(result) end end context 'with decoder' do let(:decoder) do double('Decoder').tap do |e| allow(e).to receive(:load) { |s, opts| JSON.parse(s, opts) } end end let(:body) { '{"a": 1}' } let(:result) { { a: 1 } } context 'when decoder is passed as object' do let(:options) do { parser_options: { decoder: decoder, option: :option_value, symbolize_names: true } } end it 'passes relevant options to specified decoder\'s load method' do expect(decoder).to receive(:load) .with(body, { option: :option_value, symbolize_names: true }) .and_return(result) response = process(body) expect(response.body).to eq(result) end end context 'when decoder is passed as an object-method pair' do let(:options) do { parser_options: { decoder: [decoder, :load], option: :option_value, symbolize_names: true } } end it 'passes relevant options to specified decoder\'s method' do expect(decoder).to receive(:load) .with(body, { option: :option_value, symbolize_names: true }) .and_return(result) response = process(body) expect(response.body).to eq(result) end end context 'when decoder is not passed' do let(:options) do { parser_options: { symbolize_names: true } } end it 'passes relevant options to JSON parse' do expect(JSON).to receive(:parse) .with(body, { symbolize_names: true }) .and_return(result) response = process(body) expect(response.body).to eq(result) end it 'passes relevant options to JSON parse even when nil responds to :load' do original_allow_message_expectations_on_nil = RSpec::Mocks.configuration.allow_message_expectations_on_nil RSpec::Mocks.configuration.allow_message_expectations_on_nil = true allow(nil).to receive(:respond_to?) .with(:load) .and_return(true) expect(JSON).to receive(:parse) .with(body, { symbolize_names: true }) .and_return(result) response = process(body) expect(response.body).to eq(result) ensure RSpec::Mocks.configuration.allow_message_expectations_on_nil = original_allow_message_expectations_on_nil end end end end faraday-2.10.0/spec/faraday/response/logger_spec.rb000066400000000000000000000213421464273144400222310ustar00rootroot00000000000000# frozen_string_literal: true require 'stringio' require 'logger' RSpec.describe Faraday::Response::Logger do let(:string_io) { StringIO.new } let(:logger) { Logger.new(string_io) } let(:logger_options) { {} } let(:conn) do rubbles = ['Barney', 'Betty', 'Bam Bam'] Faraday.new do |b| b.response :logger, logger, logger_options do |logger| logger.filter(/(soylent green is) (.+)/, '\1 tasty') logger.filter(/(api_key:).*"(.+)."/, '\1[API_KEY]') logger.filter(/(password)=(.+)/, '\1=[HIDDEN]') end b.adapter :test do |stubs| stubs.get('/hello') { [200, { 'Content-Type' => 'text/html' }, 'hello'] } stubs.post('/ohai') { [200, { 'Content-Type' => 'text/html' }, 'fred'] } stubs.post('/ohyes') { [200, { 'Content-Type' => 'text/html' }, 'pebbles'] } stubs.get('/rubbles') { [200, { 'Content-Type' => 'application/json' }, rubbles] } stubs.get('/filtered_body') { [200, { 'Content-Type' => 'text/html' }, 'soylent green is people'] } stubs.get('/filtered_headers') { [200, { 'Content-Type' => 'text/html' }, 'headers response'] } stubs.get('/filtered_params') { [200, { 'Content-Type' => 'text/html' }, 'params response'] } stubs.get('/filtered_url') { [200, { 'Content-Type' => 'text/html' }, 'url response'] } stubs.get('/connection_failed') { raise Faraday::ConnectionFailed, 'Failed to open TCP connection' } end end end before do logger.level = Logger::DEBUG end it 'still returns output' do resp = conn.get '/hello', nil, accept: 'text/html' expect(resp.body).to eq('hello') end context 'without configuration' do let(:conn) do Faraday.new do |b| b.response :logger b.adapter :test do |stubs| stubs.get('/hello') { [200, { 'Content-Type' => 'text/html' }, 'hello'] } end end end it 'defaults to stdout' do expect(Logger).to receive(:new).with($stdout).and_return(Logger.new(nil)) conn.get('/hello') end end context 'with default formatter' do let(:formatter) { instance_double(Faraday::Logging::Formatter, request: true, response: true, filter: []) } before { allow(Faraday::Logging::Formatter).to receive(:new).and_return(formatter) } it 'delegates logging to the formatter' do expect(formatter).to receive(:request).with(an_instance_of(Faraday::Env)) expect(formatter).to receive(:response).with(an_instance_of(Faraday::Env)) conn.get '/hello' end context 'when no route' do it 'delegates logging to the formatter' do expect(formatter).to receive(:request).with(an_instance_of(Faraday::Env)) expect(formatter).to receive(:exception).with(an_instance_of(Faraday::Adapter::Test::Stubs::NotFound)) expect { conn.get '/noroute' }.to raise_error(Faraday::Adapter::Test::Stubs::NotFound) end end end context 'with custom formatter' do let(:formatter_class) do Class.new(Faraday::Logging::Formatter) do def request(_env) info 'Custom log formatter request' end def response(_env) info 'Custom log formatter response' end end end let(:logger_options) { { formatter: formatter_class } } it 'logs with custom formatter' do conn.get '/hello' expect(string_io.string).to match('Custom log formatter request') expect(string_io.string).to match('Custom log formatter response') end end it 'logs method and url' do conn.get '/hello', nil, accept: 'text/html' expect(string_io.string).to match('GET http:/hello') end it 'logs status' do conn.get '/hello', nil, accept: 'text/html' expect(string_io.string).to match('Status 200') end it 'does not log error message by default' do expect { conn.get '/noroute' }.to raise_error(Faraday::Adapter::Test::Stubs::NotFound) expect(string_io.string).not_to match(%(no stubbed request for get http:/noroute)) end it 'logs request headers by default' do conn.get '/hello', nil, accept: 'text/html' expect(string_io.string).to match(%(Accept: "text/html)) end it 'logs response headers by default' do conn.get '/hello', nil, accept: 'text/html' expect(string_io.string).to match(%(Content-Type: "text/html)) end it 'does not log request body by default' do conn.post '/ohai', 'name=Unagi', accept: 'text/html' expect(string_io.string).not_to match(%(name=Unagi)) end it 'does not log response body by default' do conn.post '/ohai', 'name=Toro', accept: 'text/html' expect(string_io.string).not_to match(%(fred)) end it 'logs filter headers' do conn.headers = { 'api_key' => 'ABC123' } conn.get '/filtered_headers', nil, accept: 'text/html' expect(string_io.string).to match(%(api_key:)) expect(string_io.string).to match(%([API_KEY])) expect(string_io.string).not_to match(%(ABC123)) end it 'logs filter url' do conn.get '/filtered_url?password=hunter2', nil, accept: 'text/html' expect(string_io.string).to match(%([HIDDEN])) expect(string_io.string).not_to match(%(hunter2)) end context 'when not logging request headers' do let(:logger_options) { { headers: { request: false } } } it 'does not log request headers if option is false' do conn.get '/hello', nil, accept: 'text/html' expect(string_io.string).not_to match(%(Accept: "text/html)) end end context 'when not logging response headers' do let(:logger_options) { { headers: { response: false } } } it 'does not log response headers if option is false' do conn.get '/hello', nil, accept: 'text/html' expect(string_io.string).not_to match(%(Content-Type: "text/html)) end end context 'when logging request body' do let(:logger_options) { { bodies: { request: true } } } it 'log only request body' do conn.post '/ohyes', 'name=Tamago', accept: 'text/html' expect(string_io.string).to match(%(name=Tamago)) expect(string_io.string).not_to match(%(pebbles)) end end context 'when logging response body' do let(:logger_options) { { bodies: { response: true } } } it 'log only response body' do conn.post '/ohyes', 'name=Hamachi', accept: 'text/html' expect(string_io.string).to match(%(pebbles)) expect(string_io.string).not_to match(%(name=Hamachi)) end end context 'when logging request and response bodies' do let(:logger_options) { { bodies: true } } it 'log request and response body' do conn.post '/ohyes', 'name=Ebi', accept: 'text/html' expect(string_io.string).to match(%(name=Ebi)) expect(string_io.string).to match(%(pebbles)) end it 'log response body object' do conn.get '/rubbles', nil, accept: 'text/html' expect(string_io.string).to match(%([\"Barney\", \"Betty\", \"Bam Bam\"]\n)) end it 'logs filter body' do conn.get '/filtered_body', nil, accept: 'text/html' expect(string_io.string).to match(%(soylent green is)) expect(string_io.string).to match(%(tasty)) expect(string_io.string).not_to match(%(people)) end end context 'when logging errors' do let(:logger_options) { { errors: true } } it 'logs error message' do expect { conn.get '/noroute' }.to raise_error(Faraday::Adapter::Test::Stubs::NotFound) expect(string_io.string).to match(%(no stubbed request for get http:/noroute)) end end context 'when logging headers and errors' do let(:logger_options) { { headers: true, errors: true } } it 'logs error message' do expect { conn.get '/connection_failed' }.to raise_error(Faraday::ConnectionFailed) expect(string_io.string).to match(%(Failed to open TCP connection)) end end context 'when using log_level' do let(:logger_options) { { bodies: true, log_level: :debug } } it 'logs request/request body on the specified level (debug)' do logger.level = Logger::DEBUG conn.post '/ohyes', 'name=Ebi', accept: 'text/html' expect(string_io.string).to match(%(name=Ebi)) expect(string_io.string).to match(%(pebbles)) end it 'logs headers on the debug level' do logger.level = Logger::DEBUG conn.get '/hello', nil, accept: 'text/html' expect(string_io.string).to match(%(Content-Type: "text/html)) end it 'does not log request/response body on the info level' do logger.level = Logger::INFO conn.post '/ohyes', 'name=Ebi', accept: 'text/html' expect(string_io.string).not_to match(%(name=Ebi)) expect(string_io.string).not_to match(%(pebbles)) end it 'does not log headers on the info level' do logger.level = Logger::INFO conn.get '/hello', nil, accept: 'text/html' expect(string_io.string).not_to match(%(Content-Type: "text/html)) end end end faraday-2.10.0/spec/faraday/response/raise_error_spec.rb000066400000000000000000000251771464273144400233000ustar00rootroot00000000000000# frozen_string_literal: true RSpec.describe Faraday::Response::RaiseError do let(:conn) do Faraday.new do |b| b.response :raise_error b.adapter :test do |stub| stub.get('ok') { [200, { 'Content-Type' => 'text/html' }, ''] } stub.get('bad-request') { [400, { 'X-Reason' => 'because' }, 'keep looking'] } stub.get('unauthorized') { [401, { 'X-Reason' => 'because' }, 'keep looking'] } stub.get('forbidden') { [403, { 'X-Reason' => 'because' }, 'keep looking'] } stub.get('not-found') { [404, { 'X-Reason' => 'because' }, 'keep looking'] } stub.get('proxy-error') { [407, { 'X-Reason' => 'because' }, 'keep looking'] } stub.get('request-timeout') { [408, { 'X-Reason' => 'because' }, 'keep looking'] } stub.get('conflict') { [409, { 'X-Reason' => 'because' }, 'keep looking'] } stub.get('unprocessable-entity') { [422, { 'X-Reason' => 'because' }, 'keep looking'] } stub.get('too-many-requests') { [429, { 'X-Reason' => 'because' }, 'keep looking'] } stub.get('4xx') { [499, { 'X-Reason' => 'because' }, 'keep looking'] } stub.get('nil-status') { [nil, { 'X-Reason' => 'nil' }, 'fail'] } stub.get('server-error') { [500, { 'X-Error' => 'bailout' }, 'fail'] } end end end it 'raises no exception for 200 responses' do expect { conn.get('ok') }.not_to raise_error end it 'raises Faraday::BadRequestError for 400 responses' do expect { conn.get('bad-request') }.to raise_error(Faraday::BadRequestError) do |ex| expect(ex.message).to eq('the server responded with status 400') expect(ex.response[:headers]['X-Reason']).to eq('because') expect(ex.response[:status]).to eq(400) expect(ex.response_status).to eq(400) expect(ex.response_body).to eq('keep looking') expect(ex.response_headers['X-Reason']).to eq('because') end end it 'raises Faraday::UnauthorizedError for 401 responses' do expect { conn.get('unauthorized') }.to raise_error(Faraday::UnauthorizedError) do |ex| expect(ex.message).to eq('the server responded with status 401') expect(ex.response[:headers]['X-Reason']).to eq('because') expect(ex.response[:status]).to eq(401) expect(ex.response_status).to eq(401) expect(ex.response_body).to eq('keep looking') expect(ex.response_headers['X-Reason']).to eq('because') end end it 'raises Faraday::ForbiddenError for 403 responses' do expect { conn.get('forbidden') }.to raise_error(Faraday::ForbiddenError) do |ex| expect(ex.message).to eq('the server responded with status 403') expect(ex.response[:headers]['X-Reason']).to eq('because') expect(ex.response[:status]).to eq(403) expect(ex.response_status).to eq(403) expect(ex.response_body).to eq('keep looking') expect(ex.response_headers['X-Reason']).to eq('because') end end it 'raises Faraday::ResourceNotFound for 404 responses' do expect { conn.get('not-found') }.to raise_error(Faraday::ResourceNotFound) do |ex| expect(ex.message).to eq('the server responded with status 404') expect(ex.response[:headers]['X-Reason']).to eq('because') expect(ex.response[:status]).to eq(404) expect(ex.response_status).to eq(404) expect(ex.response_body).to eq('keep looking') expect(ex.response_headers['X-Reason']).to eq('because') end end it 'raises Faraday::ProxyAuthError for 407 responses' do expect { conn.get('proxy-error') }.to raise_error(Faraday::ProxyAuthError) do |ex| expect(ex.message).to eq('407 "Proxy Authentication Required"') expect(ex.response[:headers]['X-Reason']).to eq('because') expect(ex.response[:status]).to eq(407) expect(ex.response_status).to eq(407) expect(ex.response_body).to eq('keep looking') expect(ex.response_headers['X-Reason']).to eq('because') end end it 'raises Faraday::RequestTimeoutError for 408 responses' do expect { conn.get('request-timeout') }.to raise_error(Faraday::RequestTimeoutError) do |ex| expect(ex.message).to eq('the server responded with status 408') expect(ex.response[:headers]['X-Reason']).to eq('because') expect(ex.response[:status]).to eq(408) expect(ex.response_status).to eq(408) expect(ex.response_body).to eq('keep looking') expect(ex.response_headers['X-Reason']).to eq('because') end end it 'raises Faraday::ConflictError for 409 responses' do expect { conn.get('conflict') }.to raise_error(Faraday::ConflictError) do |ex| expect(ex.message).to eq('the server responded with status 409') expect(ex.response[:headers]['X-Reason']).to eq('because') expect(ex.response[:status]).to eq(409) expect(ex.response_status).to eq(409) expect(ex.response_body).to eq('keep looking') expect(ex.response_headers['X-Reason']).to eq('because') end end it 'raises Faraday::UnprocessableEntityError for 422 responses' do expect { conn.get('unprocessable-entity') }.to raise_error(Faraday::UnprocessableEntityError) do |ex| expect(ex.message).to eq('the server responded with status 422') expect(ex.response[:headers]['X-Reason']).to eq('because') expect(ex.response[:status]).to eq(422) expect(ex.response_status).to eq(422) expect(ex.response_body).to eq('keep looking') expect(ex.response_headers['X-Reason']).to eq('because') end end it 'raises Faraday::TooManyRequestsError for 429 responses' do expect { conn.get('too-many-requests') }.to raise_error(Faraday::TooManyRequestsError) do |ex| expect(ex.message).to eq('the server responded with status 429') expect(ex.response[:headers]['X-Reason']).to eq('because') expect(ex.response[:status]).to eq(429) expect(ex.response_status).to eq(429) expect(ex.response_body).to eq('keep looking') expect(ex.response_headers['X-Reason']).to eq('because') end end it 'raises Faraday::NilStatusError for nil status in response' do expect { conn.get('nil-status') }.to raise_error(Faraday::NilStatusError) do |ex| expect(ex.message).to eq('http status could not be derived from the server response') expect(ex.response[:headers]['X-Reason']).to eq('nil') expect(ex.response[:status]).to be_nil expect(ex.response_status).to be_nil expect(ex.response_body).to eq('fail') expect(ex.response_headers['X-Reason']).to eq('nil') end end it 'raises Faraday::ClientError for other 4xx responses' do expect { conn.get('4xx') }.to raise_error(Faraday::ClientError) do |ex| expect(ex.message).to eq('the server responded with status 499') expect(ex.response[:headers]['X-Reason']).to eq('because') expect(ex.response[:status]).to eq(499) expect(ex.response_status).to eq(499) expect(ex.response_body).to eq('keep looking') expect(ex.response_headers['X-Reason']).to eq('because') end end it 'raises Faraday::ServerError for 500 responses' do expect { conn.get('server-error') }.to raise_error(Faraday::ServerError) do |ex| expect(ex.message).to eq('the server responded with status 500') expect(ex.response[:headers]['X-Error']).to eq('bailout') expect(ex.response[:status]).to eq(500) expect(ex.response_status).to eq(500) expect(ex.response_body).to eq('fail') expect(ex.response_headers['X-Error']).to eq('bailout') end end describe 'request info' do let(:conn) do Faraday.new do |b| b.response :raise_error, **middleware_options b.adapter :test do |stub| stub.post(url, request_body, request_headers) do [400, { 'X-Reason' => 'because' }, 'keep looking'] end end end end let(:middleware_options) { {} } let(:request_body) { JSON.generate({ 'item' => 'sth' }) } let(:request_headers) { { 'Authorization' => 'Basic 123' } } let(:url_path) { 'request' } let(:query_params) { 'full=true' } let(:url) { "#{url_path}?#{query_params}" } subject(:perform_request) do conn.post url do |req| req.headers['Authorization'] = 'Basic 123' req.body = request_body end end it 'returns the request info in the exception' do expect { perform_request }.to raise_error(Faraday::BadRequestError) do |ex| expect(ex.response[:request][:method]).to eq(:post) expect(ex.response[:request][:url]).to eq(URI("http:/#{url}")) expect(ex.response[:request][:url_path]).to eq("/#{url_path}") expect(ex.response[:request][:params]).to eq({ 'full' => 'true' }) expect(ex.response[:request][:headers]).to match(a_hash_including(request_headers)) expect(ex.response[:request][:body]).to eq(request_body) end end describe 'DEFAULT_OPTION: include_request' do before(:each) do Faraday::Response::RaiseError.instance_variable_set(:@default_options, nil) Faraday::Middleware.instance_variable_set(:@default_options, nil) end after(:all) do Faraday::Response::RaiseError.instance_variable_set(:@default_options, nil) Faraday::Middleware.instance_variable_set(:@default_options, nil) end context 'when RaiseError DEFAULT_OPTION (include_request: true) is used' do it 'includes request info in the exception' do expect { perform_request }.to raise_error(Faraday::BadRequestError) do |ex| expect(ex.response.keys).to contain_exactly( :status, :headers, :body, :request ) end end end context 'when application sets default_options `include_request: false`' do before(:each) do Faraday::Response::RaiseError.default_options = { include_request: false } end context 'and when include_request option is omitted' do it 'does not include request info in the exception' do expect { perform_request }.to raise_error(Faraday::BadRequestError) do |ex| expect(ex.response.keys).to contain_exactly( :status, :headers, :body ) end end end context 'and when include_request option is explicitly set for instance' do let(:middleware_options) { { include_request: true } } it 'includes request info in the exception' do expect { perform_request }.to raise_error(Faraday::BadRequestError) do |ex| expect(ex.response.keys).to contain_exactly( :status, :headers, :body, :request ) end end end end end end end faraday-2.10.0/spec/faraday/response_spec.rb000066400000000000000000000046431464273144400207570ustar00rootroot00000000000000# frozen_string_literal: true RSpec.describe Faraday::Response do subject { Faraday::Response.new(env) } let(:env) do Faraday::Env.from(status: 404, body: 'yikes', url: Faraday::Utils.URI('https://lostisland.github.io/faraday'), response_headers: { 'Content-Type' => 'text/plain' }) end it { expect(subject.finished?).to be_truthy } it { expect { subject.finish({}) }.to raise_error(RuntimeError) } it { expect(subject.success?).to be_falsey } it { expect(subject.status).to eq(404) } it { expect(subject.body).to eq('yikes') } it { expect(subject.headers['Content-Type']).to eq('text/plain') } it { expect(subject['content-type']).to eq('text/plain') } describe '#apply_request' do before { subject.apply_request(body: 'a=b', method: :post) } it { expect(subject.body).to eq('yikes') } it { expect(subject.env[:method]).to eq(:post) } end describe '#to_hash' do let(:hash) { subject.to_hash } it { expect(hash).to be_a(Hash) } it { expect(hash[:status]).to eq(subject.status) } it { expect(hash[:response_headers]).to eq(subject.headers) } it { expect(hash[:body]).to eq(subject.body) } it { expect(hash[:url]).to eq(subject.env.url) } end describe 'marshal serialization support' do subject { Faraday::Response.new } let(:loaded) { Marshal.load(Marshal.dump(subject)) } before do subject.on_complete {} subject.finish(env.merge(params: 'moo')) end it { expect(loaded.env[:params]).to be_nil } it { expect(loaded.env[:body]).to eq(env[:body]) } it { expect(loaded.env[:response_headers]).to eq(env[:response_headers]) } it { expect(loaded.env[:status]).to eq(env[:status]) } it { expect(loaded.env[:url]).to eq(env[:url]) } end describe '#on_complete' do subject { Faraday::Response.new } it 'parse body on finish' do subject.on_complete { |env| env[:body] = env[:body].upcase } subject.finish(env) expect(subject.body).to eq('YIKES') end it 'can access response body in on_complete callback' do subject.on_complete { |env| env[:body] = subject.body.upcase } subject.finish(env) expect(subject.body).to eq('YIKES') end it 'can access response body in on_complete callback' do callback_env = nil subject.on_complete { |env| callback_env = env } subject.finish({}) expect(subject.env).to eq(callback_env) end end end faraday-2.10.0/spec/faraday/utils/000077500000000000000000000000001464273144400167135ustar00rootroot00000000000000faraday-2.10.0/spec/faraday/utils/headers_spec.rb000066400000000000000000000076371464273144400217020ustar00rootroot00000000000000# frozen_string_literal: true RSpec.describe Faraday::Utils::Headers do subject { Faraday::Utils::Headers.new } context 'when Content-Type is set to application/json' do before { subject['Content-Type'] = 'application/json' } it { expect(subject.keys).to eq(['Content-Type']) } it { expect(subject['Content-Type']).to eq('application/json') } it { expect(subject['CONTENT-TYPE']).to eq('application/json') } it { expect(subject['content-type']).to eq('application/json') } it { is_expected.to include('content-type') } end context 'when Content-Type is set to application/xml' do before { subject['Content-Type'] = 'application/xml' } it { expect(subject.keys).to eq(['Content-Type']) } it { expect(subject['Content-Type']).to eq('application/xml') } it { expect(subject['CONTENT-TYPE']).to eq('application/xml') } it { expect(subject['content-type']).to eq('application/xml') } it { is_expected.to include('content-type') } end describe '#fetch' do before { subject['Content-Type'] = 'application/json' } it { expect(subject.fetch('Content-Type')).to eq('application/json') } it { expect(subject.fetch('CONTENT-TYPE')).to eq('application/json') } it { expect(subject.fetch(:content_type)).to eq('application/json') } it { expect(subject.fetch('invalid', 'default')).to eq('default') } it { expect(subject.fetch('invalid', false)).to eq(false) } it { expect(subject.fetch('invalid', nil)).to be_nil } it { expect(subject.fetch('Invalid') { |key| "#{key} key" }).to eq('Invalid key') } it 'calls a block when provided' do block_called = false expect(subject.fetch('content-type') { block_called = true }).to eq('application/json') expect(block_called).to be_falsey end it 'raises an error if key not found' do expected_error = defined?(KeyError) ? KeyError : IndexError expect { subject.fetch('invalid') }.to raise_error(expected_error) end end describe '#delete' do before do subject['Content-Type'] = 'application/json' @deleted = subject.delete('content-type') end it { expect(@deleted).to eq('application/json') } it { expect(subject.size).to eq(0) } it { is_expected.not_to include('content-type') } it { expect(subject.delete('content-type')).to be_nil } end describe '#dig' do before { subject['Content-Type'] = 'application/json' } it { expect(subject&.dig('Content-Type')).to eq('application/json') } it { expect(subject&.dig('CONTENT-TYPE')).to eq('application/json') } it { expect(subject&.dig(:content_type)).to eq('application/json') } it { expect(subject&.dig('invalid')).to be_nil } end describe '#parse' do context 'when response headers leave http status line out' do let(:headers) { "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n" } before { subject.parse(headers) } it { expect(subject.keys).to eq(%w[Content-Type]) } it { expect(subject['Content-Type']).to eq('text/html') } it { expect(subject['content-type']).to eq('text/html') } end context 'when response headers values include a colon' do let(:headers) { "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\nLocation: http://httpbingo.org/\r\n\r\n" } before { subject.parse(headers) } it { expect(subject['location']).to eq('http://httpbingo.org/') } end context 'when response headers include a blank line' do let(:headers) { "HTTP/1.1 200 OK\r\n\r\nContent-Type: text/html\r\n\r\n" } before { subject.parse(headers) } it { expect(subject['content-type']).to eq('text/html') } end context 'when response headers include already stored keys' do let(:headers) { "HTTP/1.1 200 OK\r\nX-Numbers: 123\r\n\r\n" } before do h = subject h[:x_numbers] = 8 h.parse(headers) end it do expect(subject[:x_numbers]).to eq('8, 123') end end end end faraday-2.10.0/spec/faraday/utils_spec.rb000066400000000000000000000063321464273144400202560ustar00rootroot00000000000000# frozen_string_literal: true RSpec.describe Faraday::Utils do describe 'headers parsing' do let(:multi_response_headers) do "HTTP/1.x 500 OK\r\nContent-Type: text/html; charset=UTF-8\r\n" \ "HTTP/1.x 200 OK\r\nContent-Type: application/json; charset=UTF-8\r\n\r\n" end it 'parse headers for aggregated responses' do headers = Faraday::Utils::Headers.new headers.parse(multi_response_headers) result = headers.to_hash expect(result['Content-Type']).to eq('application/json; charset=UTF-8') end end describe 'URI parsing' do let(:url) { 'http://example.com/abc' } it 'escapes safe buffer' do str = FakeSafeBuffer.new('$32,000.00') expect(Faraday::Utils.escape(str)).to eq('%2432%2C000.00') end it 'parses with default parser' do with_default_uri_parser(nil) do uri = normalize(url) expect(uri.host).to eq('example.com') end end it 'parses with URI' do with_default_uri_parser(::URI) do uri = normalize(url) expect(uri.host).to eq('example.com') end end it 'parses with block' do with_default_uri_parser(->(u) { "booya#{'!' * u.size}" }) do expect(normalize(url)).to eq('booya!!!!!!!!!!!!!!!!!!!!!!') end end it 'replaces headers hash' do headers = Faraday::Utils::Headers.new('authorization' => 't0ps3cr3t!') expect(headers).to have_key('authorization') headers.replace('content-type' => 'text/plain') expect(headers).not_to have_key('authorization') end end describe '.deep_merge!' do let(:connection_options) { Faraday::ConnectionOptions.new } let(:url) do { url: 'http://example.com/abc', headers: { 'Mime-Version' => '1.0' }, request: { oauth: { consumer_key: 'anonymous' } }, ssl: { version: '2' } } end it 'recursively merges the headers' do connection_options.headers = { user_agent: 'My Agent 1.0' } deep_merge = Faraday::Utils.deep_merge!(connection_options, url) expect(deep_merge.headers).to eq('Mime-Version' => '1.0', user_agent: 'My Agent 1.0') end context 'when a target hash has an Options Struct value' do let(:request) do { params_encoder: nil, proxy: nil, bind: nil, timeout: nil, open_timeout: nil, read_timeout: nil, write_timeout: nil, boundary: nil, oauth: { consumer_key: 'anonymous' }, context: nil, on_data: nil } end let(:ssl) do { verify: nil, ca_file: nil, ca_path: nil, verify_mode: nil, cert_store: nil, client_cert: nil, client_key: nil, certificate: nil, private_key: nil, verify_depth: nil, version: '2', min_version: nil, max_version: nil, verify_hostname: nil } end it 'does not overwrite an Options Struct value' do deep_merge = Faraday::Utils.deep_merge!(connection_options, url) expect(deep_merge.request.to_h).to eq(request) expect(deep_merge.ssl.to_h).to eq(ssl) end end end end faraday-2.10.0/spec/faraday_spec.rb000066400000000000000000000024001464273144400171060ustar00rootroot00000000000000# frozen_string_literal: true RSpec.describe Faraday do it 'has a version number' do expect(Faraday::VERSION).not_to be nil end context 'proxies to default_connection' do let(:mock_connection) { double('Connection') } before do Faraday.default_connection = mock_connection end it 'proxies methods that exist on the default_connection' do expect(mock_connection).to receive(:this_should_be_proxied) Faraday.this_should_be_proxied end it 'uses method_missing on Faraday if there is no proxyable method' do expected_message = if RUBY_VERSION >= '3.4' "undefined method 'this_method_does_not_exist' for module Faraday" elsif RUBY_VERSION >= '3.3' "undefined method `this_method_does_not_exist' for module Faraday" else "undefined method `this_method_does_not_exist' for Faraday:Module" end expect { Faraday.this_method_does_not_exist }.to raise_error(NoMethodError, expected_message) end it 'proxied methods can be accessed' do allow(mock_connection).to receive(:this_should_be_proxied) expect(Faraday.method(:this_should_be_proxied)).to be_a(Method) end after do Faraday.default_connection = nil end end end faraday-2.10.0/spec/spec_helper.rb000066400000000000000000000130041464273144400167600ustar00rootroot00000000000000# frozen_string_literal: true # This file was generated by the `rspec --init` command. Conventionally, all # specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`. # The generated `.rspec` file contains `--require spec_helper` which will cause # this file to always be loaded, without a need to explicitly require it in any # files. # # Given that it is always loaded, you are encouraged to keep this file as # light-weight as possible. Requiring heavyweight dependencies from this file # will add to the boot time of your test suite on EVERY test run, even for an # individual file that may not need all of that loaded. Instead, consider making # a separate helper file that requires the additional dependencies and performs # the additional setup, and require it from the spec files that actually need # it. # # See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration require 'simplecov' require 'coveralls' require 'webmock/rspec' WebMock.disable_net_connect!(allow_localhost: true) SimpleCov.formatters = [SimpleCov::Formatter::HTMLFormatter, Coveralls::SimpleCov::Formatter] SimpleCov.start do add_filter '/spec/' minimum_coverage 84 minimum_coverage_by_file 26 end require 'faraday' require 'pry' # Ensure all /lib files are loaded # so they will be included in the test coverage report. Dir['./lib/**/*.rb'].each { |file| require file } # Load all Rspec support files Dir['./spec/support/**/*.rb'].each { |file| require file } RSpec.configure do |config| # rspec-expectations config goes here. You can use an alternate # assertion/expectation library such as wrong or the stdlib/minitest # assertions if you prefer. config.expect_with :rspec do |expectations| # This option will default to `true` in RSpec 4. It makes the `description` # and `failure_message` of custom matchers include text for helper methods # defined using `chain`, e.g.: # be_bigger_than(2).and_smaller_than(4).description # # => "be bigger than 2 and smaller than 4" # ...rather than: # # => "be bigger than 2" expectations.include_chain_clauses_in_custom_matcher_descriptions = true end # rspec-mocks config goes here. You can use an alternate test double # library (such as bogus or mocha) by changing the `mock_with` option here. config.mock_with :rspec do |mocks| # Prevents you from mocking or stubbing a method that does not exist on # a real object. This is generally recommended, and will default to # `true` in RSpec 4. mocks.verify_partial_doubles = true end # This option will default to `:apply_to_host_groups` in RSpec 4 (and will # have no way to turn it off -- the option exists only for backwards # compatibility in RSpec 3). It causes shared context metadata to be # inherited by the metadata hash of host groups and examples, rather than # triggering implicit auto-inclusion in groups with matching metadata. config.shared_context_metadata_behavior = :apply_to_host_groups # This allows you to limit a spec run to individual examples or groups # you care about by tagging them with `:focus` metadata. When nothing # is tagged with `:focus`, all examples get run. RSpec also provides # aliases for `it`, `describe`, and `context` that include `:focus` # metadata: `fit`, `fdescribe` and `fcontext`, respectively. # config.filter_run_when_matching :focus # Allows RSpec to persist some state between runs in order to support # the `--only-failures` and `--next-failure` CLI options. We recommend # you configure your source control system to ignore this file. # config.example_status_persistence_file_path = "spec/examples.txt" # Limits the available syntax to the non-monkey patched syntax that is # recommended. For more details, see: # - http://rspec.info/blog/2012/06/rspecs-new-expectation-syntax/ # - http://www.teaisaweso.me/blog/2013/05/27/rspecs-new-message-expectation-syntax/ # - http://rspec.info/blog/2014/05/notable-changes-in-rspec-3/#zero-monkey-patching-mode # config.disable_monkey_patching! # This setting enables warnings. It's recommended, but in some cases may # be too noisy due to issues in dependencies. # config.warnings = true # Many RSpec users commonly either run the entire suite or an individual # file, and it's useful to allow more verbose output when running an # individual spec file. # if config.files_to_run.one? # # Use the documentation formatter for detailed output, # # unless a formatter has already been configured # # (e.g. via a command-line flag). # config.default_formatter = "doc" # end # Print the 10 slowest examples and example groups at the # end of the spec run, to help surface which specs are running # particularly slow. # config.profile_examples = 10 # Run specs in random order to surface order dependencies. If you find an # order dependency and want to debug it, you can fix the order by providing # the seed, which is printed after each run. # --seed 1234 config.order = :random # Seed global randomization in this process using the `--seed` CLI option. # Setting this allows you to use `--seed` to deterministically reproduce # test failures related to randomization by passing the same `--seed` value # as the one that triggered the failure. Kernel.srand config.seed config.include Faraday::HelperMethods end # Extends RSpec DocumentationFormatter to hide skipped tests. module FormatterOverrides def example_pending(_arg); end def dump_pending(_arg); end RSpec::Core::Formatters::DocumentationFormatter.prepend self end faraday-2.10.0/spec/support/000077500000000000000000000000001464273144400156605ustar00rootroot00000000000000faraday-2.10.0/spec/support/disabling_stub.rb000066400000000000000000000003151464273144400211750ustar00rootroot00000000000000# frozen_string_literal: true # Allows to disable WebMock stubs module DisablingStub def disable @disabled = true end def disabled? @disabled end WebMock::RequestStub.prepend self end faraday-2.10.0/spec/support/fake_safe_buffer.rb000066400000000000000000000004701464273144400214430ustar00rootroot00000000000000# frozen_string_literal: true # emulates ActiveSupport::SafeBuffer#gsub FakeSafeBuffer = Struct.new(:string) do def to_s self end def gsub(regex) string.gsub(regex) do match, = Regexp.last_match(0), '' =~ /a/ # rubocop:disable Performance/StringInclude yield(match) end end end faraday-2.10.0/spec/support/faraday_middleware_subclasses.rb000066400000000000000000000012331464273144400242370ustar00rootroot00000000000000# frozen_string_literal: true module FaradayMiddlewareSubclasses class SubclassNoOptions < Faraday::Middleware end class SubclassOneOption < Faraday::Middleware DEFAULT_OPTIONS = { some_other_option: false }.freeze end class SubclassTwoOptions < Faraday::Middleware DEFAULT_OPTIONS = { some_option: true, some_other_option: false }.freeze end end Faraday::Response.register_middleware(no_options: FaradayMiddlewareSubclasses::SubclassNoOptions) Faraday::Response.register_middleware(one_option: FaradayMiddlewareSubclasses::SubclassOneOption) Faraday::Response.register_middleware(two_options: FaradayMiddlewareSubclasses::SubclassTwoOptions) faraday-2.10.0/spec/support/helper_methods.rb000066400000000000000000000035071464273144400212140ustar00rootroot00000000000000# frozen_string_literal: true module Faraday module HelperMethods def self.included(base) base.extend ClassMethods end module ClassMethods def features(*features) @features = features end def on_feature(name) yield if block_given? && feature?(name) end def feature?(name) if @features.nil? superclass.feature?(name) if superclass.respond_to?(:feature?) elsif @features.include?(name) true end end def method_with_body?(method) METHODS_WITH_BODY.include?(method.to_s) end end def ssl_mode? ENV['SSL'] == 'yes' end def normalize(url) Faraday::Utils::URI(url) end def with_default_uri_parser(parser) old_parser = Faraday::Utils.default_uri_parser begin Faraday::Utils.default_uri_parser = parser yield ensure Faraday::Utils.default_uri_parser = old_parser end end def with_env(new_env) old_env = {} new_env.each do |key, value| old_env[key] = ENV.fetch(key, false) ENV[key] = value end begin yield ensure old_env.each do |key, value| value == false ? ENV.delete(key) : ENV[key] = value end end end def with_env_proxy_disabled Faraday.ignore_env_proxy = true begin yield ensure Faraday.ignore_env_proxy = false end end def capture_warnings old = $stderr $stderr = StringIO.new begin yield $stderr.string ensure $stderr = old end end def method_with_body?(method) self.class.method_with_body?(method) end def big_string kb = 1024 (32..126).map(&:chr).cycle.take(50 * kb).join end end end faraday-2.10.0/spec/support/shared_examples/000077500000000000000000000000001464273144400210245ustar00rootroot00000000000000faraday-2.10.0/spec/support/shared_examples/adapter.rb000066400000000000000000000045711464273144400230000ustar00rootroot00000000000000# frozen_string_literal: true shared_examples 'an adapter' do |**options| before { skip } if options[:skip] context 'with SSL enabled' do before { ENV['SSL'] = 'yes' } include_examples 'adapter examples', options end context 'with SSL disabled' do before { ENV['SSL'] = 'no' } include_examples 'adapter examples', options end end shared_examples 'adapter examples' do |**options| include Faraday::StreamingResponseChecker let(:adapter) { described_class.name.split('::').last } let(:conn_options) { { headers: { 'X-Faraday-Adapter' => adapter } }.merge(options[:conn_options] || {}) } let(:adapter_options) do return [] unless options[:adapter_options] if options[:adapter_options].is_a?(Array) options[:adapter_options] else [options[:adapter_options]] end end let(:protocol) { ssl_mode? ? 'https' : 'http' } let(:remote) { "#{protocol}://example.com" } let(:stub_remote) { remote } let(:conn) do conn_options[:ssl] ||= {} conn_options[:ssl][:ca_file] ||= ENV.fetch('SSL_FILE', nil) conn_options[:ssl][:verify_hostname] ||= ENV['SSL_VERIFY_HOSTNAME'] == 'yes' Faraday.new(remote, conn_options) do |conn| conn.request :url_encoded conn.response :raise_error conn.adapter described_class, *adapter_options end end let!(:request_stub) { stub_request(http_method, stub_remote) } after do expect(request_stub).to have_been_requested unless request_stub.disabled? end describe '#delete' do let(:http_method) { :delete } it_behaves_like 'a request method', :delete end describe '#get' do let(:http_method) { :get } it_behaves_like 'a request method', :get end describe '#head' do let(:http_method) { :head } it_behaves_like 'a request method', :head end describe '#options' do let(:http_method) { :options } it_behaves_like 'a request method', :options end describe '#patch' do let(:http_method) { :patch } it_behaves_like 'a request method', :patch end describe '#post' do let(:http_method) { :post } it_behaves_like 'a request method', :post end describe '#put' do let(:http_method) { :put } it_behaves_like 'a request method', :put end on_feature :trace_method do describe '#trace' do let(:http_method) { :trace } it_behaves_like 'a request method', :trace end end end faraday-2.10.0/spec/support/shared_examples/params_encoder.rb000066400000000000000000000007661464273144400243440ustar00rootroot00000000000000# frozen_string_literal: true shared_examples 'a params encoder' do it 'escapes safe buffer' do monies = FakeSafeBuffer.new('$32,000.00') expect(subject.encode('a' => monies)).to eq('a=%2432%2C000.00') end it 'raises type error for empty string' do expect { subject.encode('') }.to raise_error(TypeError) do |error| expect(error.message).to eq("Can't convert String into Hash.") end end it 'encodes nil' do expect(subject.encode('a' => nil)).to eq('a') end end faraday-2.10.0/spec/support/shared_examples/request_method.rb000066400000000000000000000177211464273144400244110ustar00rootroot00000000000000# frozen_string_literal: true shared_examples 'proxy examples' do it 'handles requests with proxy' do res = conn.public_send(http_method, '/') expect(res.status).to eq(200) end it 'handles proxy failures' do request_stub.to_return(status: 407) expect { conn.public_send(http_method, '/') }.to raise_error(Faraday::ProxyAuthError) end end shared_examples 'a request method' do |http_method| let(:query_or_body) { method_with_body?(http_method) ? :body : :query } let(:response) { conn.public_send(http_method, '/') } unless http_method == :head && feature?(:skip_response_body_on_head) it 'retrieves the response body' do res_body = 'test' request_stub.to_return(body: res_body) expect(conn.public_send(http_method, '/').body).to eq(res_body) end end it 'handles headers with multiple values' do request_stub.to_return(headers: { 'Set-Cookie' => 'name=value' }) expect(response.headers['set-cookie']).to eq('name=value') end it 'retrieves the response headers' do request_stub.to_return(headers: { 'Content-Type' => 'text/plain' }) expect(response.headers['Content-Type']).to match(%r{text/plain}) expect(response.headers['content-type']).to match(%r{text/plain}) end it 'sends user agent' do request_stub.with(headers: { 'User-Agent' => 'Agent Faraday' }) conn.public_send(http_method, '/', nil, user_agent: 'Agent Faraday') end it 'represents empty body response as blank string' do expect(response.body).to eq('') end it 'handles connection error' do request_stub.disable expect { conn.public_send(http_method, 'http://localhost:4') }.to raise_error(Faraday::ConnectionFailed) end on_feature :local_socket_binding do it 'binds local socket' do stub_request(http_method, 'http://example.com') host = '1.2.3.4' port = 1234 conn_options[:request] = { bind: { host: host, port: port } } conn.public_send(http_method, '/') expect(conn.options[:bind][:host]).to eq(host) expect(conn.options[:bind][:port]).to eq(port) end end # context 'when wrong ssl certificate is provided' do # let(:ca_file_path) { 'tmp/faraday-different-ca-cert.crt' } # before { conn_options.merge!(ssl: { ca_file: ca_file_path }) } # # it do # expect { conn.public_send(http_method, '/') }.to raise_error(Faraday::SSLError) # do |ex| # expect(ex.message).to include?('certificate') # end # end # end on_feature :request_body_on_query_methods do it 'sends request body' do request_stub.with({ body: 'test' }) res = if query_or_body == :body conn.public_send(http_method, '/', 'test') else conn.public_send(http_method, '/') do |req| req.body = 'test' end end expect(res.env.request_body).to eq('test') end end it 'sends url encoded parameters' do payload = { name: 'zack' } request_stub.with({ query_or_body => payload }) res = conn.public_send(http_method, '/', payload) if query_or_body == :query expect(res.env.request_body).to be_nil else expect(res.env.request_body).to eq('name=zack') end end it 'sends url encoded nested parameters' do payload = { name: { first: 'zack' } } request_stub.with({ query_or_body => payload }) conn.public_send(http_method, '/', payload) end # TODO: This needs reimplementation: see https://github.com/lostisland/faraday/issues/718 # Should raise Faraday::TimeoutError it 'supports timeout option' do conn_options[:request] = { timeout: 1 } request_stub.to_timeout exc = adapter == 'NetHttp' ? Faraday::ConnectionFailed : Faraday::TimeoutError expect { conn.public_send(http_method, '/') }.to raise_error(exc) end # TODO: This needs reimplementation: see https://github.com/lostisland/faraday/issues/718 # Should raise Faraday::ConnectionFailed it 'supports open_timeout option' do conn_options[:request] = { open_timeout: 1 } request_stub.to_timeout exc = adapter == 'NetHttp' ? Faraday::ConnectionFailed : Faraday::TimeoutError expect { conn.public_send(http_method, '/') }.to raise_error(exc) end on_feature :reason_phrase_parse do it 'parses the reason phrase' do request_stub.to_return(status: [200, 'OK']) expect(response.reason_phrase).to eq('OK') end end on_feature :compression do # Accept-Encoding header not sent for HEAD requests as body is not expected in the response. unless http_method == :head it 'handles gzip compression' do request_stub.with(headers: { 'Accept-Encoding' => /\bgzip\b/ }) conn.public_send(http_method, '/') end it 'handles deflate compression' do request_stub.with(headers: { 'Accept-Encoding' => /\bdeflate\b/ }) conn.public_send(http_method, '/') end end end on_feature :streaming do describe 'streaming' do let(:streamed) { [] } context 'when response is empty' do it 'handles streaming' do env = nil conn.public_send(http_method, '/') do |req| req.options.on_data = proc do |chunk, size, block_env| streamed << [chunk, size] env ||= block_env end end expect(streamed).to eq([['', 0]]) # TODO: enable this after updating all existing adapters to the new streaming API # expect(env).to be_a(Faraday::Env) # expect(env.status).to eq(200) end end context 'when response contains big data' do before { request_stub.to_return(body: big_string) } it 'handles streaming' do env = nil response = conn.public_send(http_method, '/') do |req| req.options.on_data = proc do |chunk, size, block_env| streamed << [chunk, size] env ||= block_env end end expect(response.body).to eq('') check_streaming_response(streamed, chunk_size: 16 * 1024) # TODO: enable this after updating all existing adapters to the new streaming API # expect(env).to be_a(Faraday::Env) # expect(env.status).to eq(200) end end end end on_feature :parallel do context 'with parallel setup' do before do @resp1 = nil @resp2 = nil @payload1 = { a: '1' } @payload2 = { b: '2' } request_stub .with({ query_or_body => @payload1 }) .to_return(body: @payload1.to_json) stub_request(http_method, remote) .with({ query_or_body => @payload2 }) .to_return(body: @payload2.to_json) conn.in_parallel do @resp1 = conn.public_send(http_method, '/', @payload1) @resp2 = conn.public_send(http_method, '/', @payload2) expect(conn.in_parallel?).to be_truthy expect(@resp1.body).to be_nil expect(@resp2.body).to be_nil end expect(conn.in_parallel?).to be_falsey end it 'handles parallel requests status' do expect(@resp1&.status).to eq(200) expect(@resp2&.status).to eq(200) end unless http_method == :head && feature?(:skip_response_body_on_head) it 'handles parallel requests body' do expect(@resp1&.body).to eq(@payload1.to_json) expect(@resp2&.body).to eq(@payload2.to_json) end end end end context 'when a proxy is provided as option' do before do conn_options[:proxy] = 'http://env-proxy.com:80' end include_examples 'proxy examples' end context 'when http_proxy env variable is set' do let(:proxy_url) { 'http://env-proxy.com:80' } around do |example| with_env 'http_proxy' => proxy_url do example.run end end include_examples 'proxy examples' context 'when the env proxy is ignored' do around do |example| with_env_proxy_disabled(&example) end include_examples 'proxy examples' end end end faraday-2.10.0/spec/support/streaming_response_checker.rb000066400000000000000000000020471464273144400236030ustar00rootroot00000000000000# frozen_string_literal: true module Faraday module StreamingResponseChecker def check_streaming_response(streamed, options = {}) opts = { prefix: '', streaming?: true }.merge(options) expected_response = opts[:prefix] + big_string chunks, sizes = streamed.transpose # Check that the total size of the chunks (via the last size returned) # is the same size as the expected_response expect(sizes.last).to eq(expected_response.bytesize) start_index = 0 expected_chunks = [] chunks.each do |actual_chunk| expected_chunk = expected_response[start_index..((start_index + actual_chunk.bytesize) - 1)] expected_chunks << expected_chunk start_index += expected_chunk.bytesize end # it's easier to read a smaller portion, so we check that first expect(expected_chunks[0][0..255]).to eq(chunks[0][0..255]) [expected_chunks, chunks].transpose.each do |expected, actual| expect(actual).to eq(expected) end end end end