Mail-DMARC-1.20260306000755000765000024 015152630466 13064 5ustar00mattstaff000000000000Mail-DMARC-1.20260306/.perltidyrc000444000765000024 123215152630466 15401 0ustar00mattstaff000000000000-l=78 # Max line width is 78 cols -i=4 # Indent level is 4 cols -ci=4 # Continuation indent is 4 cols #-st # Output to STDOUT -b # edit in place and backup -se # Errors to STDERR -vt=2 # Maximal vertical tightness -cti=0 # No extra indentation for closing brackets -pt=1 # Medium parenthesis tightness -bt=1 # Medium brace tightness -sbt=1 # Medium square bracket tightness -bbt=1 # Medium block brace tightness -nsfs # No space before semicolons -nolq # Don't outdent long quoted strings -wbb="% + - * / x != == >= <= =~ !~ < > | & >= < = **= += *= &= <<= &&= -= /= |= >>= ||= .= %= ^= x=" # Break before all operators Mail-DMARC-1.20260306/Build.PL000444000765000024 1167515152630466 14547 0ustar00mattstaff000000000000use strict; use warnings; use Module::Build 0.3601; my $module_build_args = { "build_requires" => { "Module::Build" => "0.3601" }, "configure_requires" => { "File::ShareDir::Install" => "0.06", "Module::Build" => "0.3601" }, "dist_abstract" => "Perl implementation of DMARC", "dist_author" => [ "Matt Simerson ", "Davide Migliavacca ", "Marc Bradshaw " ], "dist_name" => "Mail-DMARC", "license" => "perl", "module_name" => "Mail::DMARC", "release_status" => "stable", "add_to_cleanup" => [ "dmarc_reports.sqlite", "t/reports-test.sqlite"], "recommends" => { "Mail::DKIM" => 0, # "MIME::Lite" => 0, "Net::IMAP::Simple" => 0, "Net::SMTPS" => 0, }, "requires" => { "perl" => "5.10.0", "Carp" => 0, "Config::Tiny" => 0, "DBD::SQLite" => "1.31", "DBIx::Simple" => "1.35", "Data::Dumper" => 0, "Email::MIME" => 0, "Email::Sender" => 0, "Email::Sender::Simple" => "1.300032", "Email::Simple" => 0, "Encode" => 0, "English" => 0, "File::ShareDir" => 0, "Getopt::Long" => 0, "HTTP::Tiny" => 0, "IO::Compress::Gzip" => 0, "IO::Compress::Zip" => 0, "IO::File" => 0, "IO::Socket::SSL" => 0, "IO::Uncompress::Gunzip" => 0, "IO::Uncompress::Unzip" => 0, "Module::Load" => 0, "Net::DNS::Resolver" => 0, "Net::IDN::Encode" => 0, "Net::IP" => 0, "Net::SSLeay" => 0, "POSIX" => 0, "Pod::Usage" => 0, "Regexp::Common" => "2013031301", "Socket" => 0, "Socket6" => "0.23", "Sys::Hostname" => 0, "Sys::Syslog" => 0, "Test::File::ShareDir" => 0, "URI" => 0, "XML::LibXML" => 0, }, "auto_features" => { "mysql" => { "description" => "MySQL backend storage", "prereqs" => { "runtime" => { "requires" => { 'DBD::mysql' => '4.001', } } } }, "postgres" => { "description" => "PostgresQL backend storage", "prereqs" => { "runtime" => { "requires" => { 'DBD::Pg' => '0' } } } }, "web_services" => { "description" => "HTTP API and web UI to DMARC reports", "prereqs" => { "runtime" => { "requires" => { "CGI" => 0, "HTTP::Request" => 0, "JSON" => 0, "LWP::UserAgent" => 0, "Net::HTTP" => 0, "Net::Server::HTTP" => 0, "Net::Server" => 2, } } } }, "smtp_sending" => { "description" => "Send DMARC reports via SMTP", "prereqs" => { "runtime" => { "Net::SMTPS" => 0, "Mail::DKIM::PrivateKey" => 0, "Mail::DKIM::Signer" => 0, "Mail::DKIM::TextWrap" => 0, } } }, "imap_fetch" => { "description" => "Retrieve DMARC reports from an IMAP account", "prereqs" => { "runtime" => { "Net::IMAP::Simple" => 0, } } } }, "recursive_test_files" => 1, "script_files" => [ "bin/dmarc_update_public_suffix_list", "bin/dmarc_send_reports", "bin/dmarc_httpd", "bin/dmarc_lookup", "bin/dmarc_receive", "bin/dmarc_http_client", "bin/dmarc_view_reports" ], "share_dir" => { "dist" => "share" }, "test_requires" => { "Test::Exception" => 0, "Test::File::ShareDir" => 0, "Test::More" => 0, "Test::Output" => 0, "Net::DNS::Resolver::Mock" => 0 }, "develop_requires" => { "Test::Pod" => "1.41" }, "meta_add" => { }, "meta_merge" => { "prereqs" => { "test" => { "recommends" => { "XML::SAX::ParserFactory" => "0", "XML::Validator::Schema" => "0" }, }, "develop" => { "requires" => { "Test::Pod" => "1.41" }, "suggests" => { "Test::Perl::Critic" => "0" } }, }, "resources" => { "bugtracker" => "https://github.com/msimerson/mail-dmarc/issues", "homepage" => "https://github.com/msimerson/mail-dmarc/wiki", "repository" => "https://github.com/msimerson/mail-dmarc", }, "x_contributors" => [ "Benny Pedersen ", "Jean Paul Galea ", "Marisa Clardy ", "Priyadi Iman Nurcahyo ", "Ricardo Signes " ], } }; my $fallback_build_requires = { "Module::Build" => "0.3601", "Test::Exception" => 0, "Test::File::ShareDir" => 0, "Test::More" => 0, "Test::Output" => 0 }; unless ( eval { Module::Build->VERSION(0.4004) } ) { delete $module_build_args->{test_requires}; $module_build_args->{build_requires} = $fallback_build_requires; } my $build = Module::Build->new(%$module_build_args); # if ( $build->prompt( "Database engine", "sqlite" ) ) { # $build->notes( 'DB_ENGINE' => $build->args('db_engine') ); # } $build->create_build_script; Mail-DMARC-1.20260306/Changes.md000444000765000024 3056715152630466 15146 0ustar00mattstaff000000000000### 1.20260306 - dmarc_sqlite_to_mysql: added new script - mysql: enable SSL for newer MySQL. Fix schema for new import. - dmarc_receive: eval un(g)zip, so imperfect archives don't interrupt loop - dmarc_view_reports: --geoip fixed - dmarc_view_reports: add --limit and --sort options ### 1.20260301 - dmarc_receive: support gzip, zip, and XML files #277 - dmarc_view_reports: add --rid filter #276 - dmarc_view_reports: add negation support in filters #275 - fix(sp): base effective policy on request domain #273 ### 1.20260226 - feat: replace jqGrid with DataTables in web UI #269 - doc: remove invalid reference to evalated #267 - doc: bump copyright to 2026 - updated PSL ### 1.20250805 - if XML declares a namespace, remove it - silence warnings for text/html parts - silence most "Unknown message part" warnings ### 1.20250610 - Fix end of line characters in message-id for reports ### 1.20250203 - consider localhost as invalid domain #255 - add a stringify method to the Policy class #253 - lower case domains passed to is_valid_domain #252 - lower case match from and envelope-from domains #249 - Change validation result for RFC7489 6.6.3 step 6.2 #248 - point README links to search.cpan.org #240 - sender: set options when creating new sender object #239 - permit storage of UTF-8 chars in MySQL DB #238 - load report_store modules using Module::Load #237 - create an email message with a proper Message-ID #236 - imap: only use port 143 if requested #235 - find_psl_file: fix duplicate share in path #232 ### 1.20240313 - Fix error email sent when reports are too large - Delete reports after sending error emails - Make sending of error emails optional ### 1.20240214 - feat: add imap option to specify port #195 - feat: add configurable DNS retrans option #214 - ignore empty/wrong lines on whitelist_dmarc file #219 - test: mock DNS during testing #213 - ci: restore CI tests to working order - Force lower case for SPF domain input #212 ### 1.20230215 - Fix error when logging a report which was skipped for size ### 1.20211209 - Properly delete sent reports when the database does not support cascade ### 1.20210927 - Fix reporting for selectors whose name evaluates to false - Use maybestarttls for opportunistic encryption when sending reports using Email::Sender v2.0 or greater - Remove dead domain dmarc-qa.com from tests - Print full syntax guide with "--help" option (Jeremiah Morris) ### 1.20210427 - Fix report sending issues with SSL/TLS ### 1.20210220 - Fix db connection cache - use Email::Sender for report sending ### 1.20200214 - move HTTP::Tiny into deps (used for PSL updates) ### 1.20200116 - skip HTTP tests when optional JSON not installed #171 ### 1.20200114 - skip HTTP tests when optional deps not installed #171 - update PSL - auto update PSL as part of release ### 1.20200113 - lazy load Net::SMTPS #168 ### 1.20200108 - NEW FEATURE: Postgres support #150 - removed dist::zilla - additional tests enabled - html UI: use https URLS everywhere - SPF: don't warn when scope is missing from reports - receive: permit other MIME types that have xml.gz filename - DKIM: when message has no result, add "none" - sqlite: add default current_timestamp - bin/install_deps.pl: apt improvements ### 1.20191004 - updated PSL - update jQuery, jQuery grid - empty ENV FROM when missing #144 ### 1.20190831 - improve aggregate report docs #142 - added dmarc_whitelist hosts #119 ### 1.20190308 - Lower memory usage when sending reports ### 1.20181001 - Check author when saving a new report record - Fix bug in RUA filtering when recipient had a size filter - Fix TLS fails for report sending to certain domains - Fix report sending loop problem ### 1.20180125 - Allow domains listed in the public suffix list to align. ### 1.20170911 - STARTTLS workaround for Net::SMTPS issue. ### 1.20170906 - Ignore the case of tag keys when parsing DMARC records ### 1.20170222 - Ensure entities in XML agg reports are properly escaped #104 - geoip v6 support and field selection #103 - use a larger integer type for report_record.count #102 - improved apt package lookups in install_deps.pl #98 ### 1.20160612 - fix aggregrate schema test #96 - Do not reject NXDOMAIN as per rfc #94 - added none result for no policy #93 - avoid deadlock with some invalid rua data #92 - avoid loop when sending reports via http #92 ### 1.20150908 - Optionally log sending of reports to syslog ### 1.20150527 - check for an updated PSL file and load if necessary - handle domains with missing rua/ruf - add timeout to sending script ### 1.20150317 - squash subdomains w/o DMARC records into parent report (#59) - add batch reporting (suppress throttling until...) - align reports with hour/UTC day - swap git contributors plugin ### 1.20150310 - lower case domain names at entry points (resolves #53) - tolerate substitution of = with : in DMARC DNS rec ### 1.20150228 - fix the policy_evaluated fields in outbound reports - accommodate a common DMARC error substiting = with : - initialized config file first (was non-deterministic) - tolerate missing SPF auth type scope ### 1.20150222 - remove ./mail-dmarc.ini (sample in share/mail-dmarc.ini) - load PSL before dmarc_httpd forks, so we only load it once - quieter report sending output unless --verbose ### 1.20150211 - optionally DKIM sign sent reports - warn when DMARC record format is invalid - accept callbacks (lazy eval) for SPF & DKIM results - make the report record building consistent for eval and reporting - rewrite DKIM result invalid -> temperror - capture test warnings, so 'make test' is prettier ### 1.20150123 - enable lazy evaluation of SPF & DKIM (Ricardo Signes) - check ShareDir for mail-dmarc.ini, if not in a standard location - map DKIM status=invalid to status->temperror - add config arg to dmarc_update_public_suffix_list (Ricardo Signes) - Send only a single cc email (Marc Bradshaw) - DMARC: update docs to show SPF one-shot syntax - PurePerl: one shot accepts a Mail::DKIM::Verifier - trap errors thrown by is_dkim_aligned - INSTALL: added 'install mail-dmarc.ini' step - Show "new record" output only in verbose mode. (Marc Bradshaw) - require DBIx::Simple 1.35 (was any) ### 1.20141230 - Add script to update the public suffix list file (Marc Bradshaw) ### 1.20141206 - Delete reports with no valid rua (Marc Bradshaw) - Ignore DomainKeys signatures (Marc Bradshaw) - allow configurable delay between sending emails (Marc Bradshaw) - permit absolute paths for public suffix list file location (Marc Bradshaw) - fix lookup for *.foo entries (Marc Bradshaw) ### 1.20141119 - added auto_save option for validation reports - updated bin/install_deps.pl ### 1.20141030 - percent policy logic wasn't being applied correctly - fix for reasons not stored in SQL ### 1.20140711 - Store/SQL: use full sql name in WHERE clause - DMARC/HTTP: added error handling and tests - removed excess comma in mail_dmarc_schema.mysql - added quotes around ($commit || ''), just in case - try IMAP fetch without SORT if no results, for IMAP servers like Gmail that don't support SORT - warn but still pass test if DNS query fails ### 1.20140623 - updated tests to accomodate the cached PSL ### 1.20140622 - load PSL into hash to speed subsequent lookups (esp for daemon) - uncommented Net::Server in Prereqs/Recommended section - added INSTALL - updated dmarc_httpd description to note validation feature - updated public_suffix_list ### 1.20140210 - NEW FEATURE: added HTTP validation service (see dmarc_httpd) - install_deps: install optional prereqs by default - added Best Current Practices link on main page - minor tweaks to Pod (Ricardo Signes) - PurePerl: added comments about Sender header when message has multiple-address format used in the From header - updated public_suffix_list ### 1.20130906 - handle errors encountered when reporting address is illegal - delete reports that return a SMTP 5XX code for the recipient - delete reports after encountering 12 errors - added 'too big' notices when report size exceeds limit - updated install_deps.pl ### 1.20130625 - added a bunch of tests from http://dmarc-qa.com - URI: supress undef error if URI scheme not defined - policy->parse: properly parse records with unnecessary trailing ; - reporting is 'external' based on Org Domain (was email domain) ### 1.20130616 - combined update/replace SQL methods - dmarc_view_reports: fix duplicated variable name ### 1.20130615 - bug fixes and purge unused classes ### 1.20130614 - Added whitelist feature - SMTP: remove Subject: Report-ID - SMTP: more types of SMTP errors are stored and reported - dmarc_send_reports: added verbose option - dmarc_view_reports: fix for searches with MySQL backend ### 1.20130612 - dmarc_view_reports: improve gentoo support by adding /usr to search path for GeoIP DBs on gentoo - Benny Pedersen ### 1.20130610 - tolerate receiving reports with no records (ahem, hotmail.com) - simplify SMTP flow-of-control, additional SMTP tests - avoid the join/split of binip in SQL::populate_agg_records - replace carp with warn in several places (more legible warning) - added RUA validity checks to dmarc_lookup ### 1.20130605 - in aggregate reports, group by IP and auth results (was only IP) - refactored SQL::retrieve_todo into 3 methods, added tests - SQL: added unique constraint on domain.domain ### 1.20130604 - main branches are master (devel) and releases (more obvious) - added mailing list impact FAQ - SQL: removed record.rcpt_dom - corrected a XML schema error - index.html - widened disposition column - only show rcpt domain in record (subgrid) - corrected subgrid row_id - additional validation of aggregate reports ### 1.20130601 - make sure a report record exists when fetching SMTP todo - added insecure SMTP fallback if STARTTLS fails - added color coded results to HTTP grid ### 1.20130531 - added gzip support to HTTP server, compressed JS files - reason is internally an arrayref of hashrefs (was a single hashref) - documentation additions - removed unused JS files - add validation and fixup of SPF result for incoming reports - normalized domain columns in spf & dkim tables ### 1.20130528 - bump major version to 1 - normalized domain columns in report_record - fixups to handle reports with invalid formatting - improved handling for IMAP SSL connections - made internal represention of Mail::DMARC::dkim & spf consistent with their aggregate report representation ### 0.20130528 - updated Send/SMTP to use report::aggregate - switched back to gzip reports (instead of zip) - dmarc_view_reports, added filtering ability, GeoIP location ### 0.20130524 - added bin/dmarc_httpd - added bin/dmarc_view_reports - renamed: dmarc_report -> dmarc_send_reports ### 0.20130521 - check for report_record existence before insertion - SQL: added report_record.count column - subclassed aggregreate reports into Report::Aggregate - consolidates two agg. rep. generation methods to one - SQL: added table report_error - updated SQLite schema with native column types ### 0.20130520 - added bin/dmarc_receive (via IMAP, mbox, or message file) - added report retrieval via IMAP - extract sender domain from subject or MIME metadata - SQL: added author.extra_contact - SQL: removed 'NOT NULL' requirements for values often missing from incoming reports. ### 0.20130517 - send reports with zip until 7/1, gzip after - replace Socket 2 with Socket6 (better Windows compatibility) - added parsing of incoming email reports - added author and domain tables - added three related columns from/rcpt/author ids to report table - add email hostname to MX list when attempting SMTP delivery - during report delivery, check report URI max size ### 0.20130515 - use File::ShareDir to access share/* - added external reporting verification ### 0.20130514 - moved DNS settings into config file - fixed a case where disposition was not set - added bin/dmarc_report - sends email reports with Email::MIME & Net::SMTPS - deletes reports after successful delivery - required Socket 2 (correct IPv6 handling) - several SQL schema changes - has_valid_reporting_uri does validation now ### 0.20130510 ### 0.20130507 - added sql and MySQL schema - added bin/dmarc_lookup - replaced Regexp::Common IP validation with Net::IP (perl 5.8 compat) - added Results.pm tests - added full section numbers to Draft quotes ### 0.20130506 - added Result and Result/Evaluated.pm - consolidated DNS functions into DNS.pm - uses Regexp::Common, requiring perl 5.10. - Mail::DMARC::Policy is well defined and tested - setting up package Mail-DMARC-1.20260306/DEVELOP.md000444000765000024 332515152630466 14644 0ustar00mattstaff000000000000# Find the source [The source code is hosted on GitHub](https://github.com/msimerson/mail-dmarc) # Download the source To make changes or submit patches, visit the GitHub URL and click the ***Fork*** button. Then clone your fork to your local disk: git clone git@github.com:YOUR-USER-NAME/mail-dmarc.git # Use the source Use git in the normal way: cd mail-dmarc .... make a change or two ... git status ( see changes ) git diff ( show diffs ) git add ... ( stage changes ) git commit If your changes are significant and might possibly involve more than one commit, create a branch first: git checkout -b fix-knob-handle ... make changes ... git commit ... make more related changes ... git commit When you are done making changes, push them to GitHub: git push origin (push to your GitHub account) When the new feature branch is no longer useful, delete it: git branch -d fix-knob-handle # Submit your changes git push origin master (push to your GitHub account) Visit your fork on the GitHub web site. On the main page of your fork is a ***Pull Request*** button. That is how you submit your changes to the main repo. A collaborator will review your PR and either comment or merge it. # Check build status: [![Build Status](https://github.com/msimerson/mail-dmarc/actions/workflows/ci.yml/badge.svg)](https://github.com/msimerson/mail-dmarc/actions/workflows/ci.yml) GitHub Actions automatically runs build tests when commits are pushed to GitHub, and sends notifications to the author(s) in case of failure. For everyone else, checking the build status after a push request is merged is a good idea. # Release ````sh .release/do.sh ```` Mail-DMARC-1.20260306/FAQ.md000444000765000024 17515152630466 14135 0ustar00mattstaff000000000000 The Mail::DMARC [FAQ is here](https://github.com/msimerson/mail-dmarc/wiki). https://github.com/msimerson/mail-dmarc/wiki Mail-DMARC-1.20260306/INSTALL.md000444000765000024 174015152630466 14653 0ustar00mattstaff000000000000 # Install Mail::DMARC's dependencies ## The fast way, using your systems package manager (yum, apt, ports): perl bin/install_deps.pl If your system doesn't have a package manager, or the package version fails, or the version installed by your systems package manager isn't new enough, install_deps will also attempt to install the latest version via CPAN. Once the dependencies are installed, install Mail::DMARC as any other perl module: perl Makefile.PL make make install clean Copy the mail-dmarc.ini file to your systems preferred local etc directory (/etc, /usr/local/etc, opt/local/etc) and edit at least the settings in the [organization] block: cp mail-dmarc.ini /etc/ $EDITOR /etc/mail-dmarc.ini NOTE: Most of the dependencies are optionally required for the DMARC reporting features. Mail::DMARC will perform validation with only these modules: Regexp::Common Config::Tiny File::ShareDir Net::DNS::Resolver Net::IP Socket6 Mail-DMARC-1.20260306/LICENSE000444000765000024 4366015152630466 14257 0ustar00mattstaff000000000000This software is copyright (c) 2026 by Matt Simerson. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. Terms of the Perl programming language system itself a) the GNU General Public License as published by the Free Software Foundation; either version 1, or (at your option) any later version, or b) the "Artistic License" --- The GNU General Public License, Version 1, February 1989 --- This software is Copyright (c) 2018 by Matt Simerson. This is free software, licensed under: The GNU General Public License, Version 1, February 1989 GNU GENERAL PUBLIC LICENSE Version 1, February 1989 Copyright (C) 1989 Free Software Foundation, Inc. 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The license agreements of most software companies try to keep users at the mercy of those companies. By contrast, our General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. The General Public License applies to the Free Software Foundation's software and to any other program whose authors commit to using it. You can use it for your programs, too. When we speak of free software, we are referring to freedom, not price. Specifically, the General Public License is designed to make sure that you have the freedom to give away or sell copies of free software, that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of a such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must tell them their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License Agreement applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any work containing the Program or a portion of it, either verbatim or with modifications. Each licensee is addressed as "you". 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this General Public License and to the absence of any warranty; and give any other recipients of the Program a copy of this General Public License along with the Program. You may charge a fee for the physical act of transferring a copy. 2. You may modify your copy or copies of the Program or any portion of it, and copy and distribute such modifications under the terms of Paragraph 1 above, provided that you also do the following: a) cause the modified files to carry prominent notices stating that you changed the files and the date of any change; and b) cause the whole of any work that you distribute or publish, that in whole or in part contains the Program or any part thereof, either with or without modifications, to be licensed at no charge to all third parties under the terms of this General Public License (except that you may choose to grant warranty protection to some or all third parties, at your option). c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the simplest and most usual way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this General Public License. d) You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. Mere aggregation of another independent work with the Program (or its derivative) on a volume of a storage or distribution medium does not bring the other work under the scope of these terms. 3. You may copy and distribute the Program (or a portion or derivative of it, under Paragraph 2) in object code or executable form under the terms of Paragraphs 1 and 2 above provided that you also do one of the following: a) accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Paragraphs 1 and 2 above; or, b) accompany it with a written offer, valid for at least three years, to give any third party free (except for a nominal charge for the cost of distribution) a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Paragraphs 1 and 2 above; or, c) accompany it with the information you received as to where the corresponding source code may be obtained. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form alone.) Source code for a work means the preferred form of the work for making modifications to it. For an executable file, complete source code means all the source code for all modules it contains; but, as a special exception, it need not include source code for modules which are standard libraries that accompany the operating system on which the executable file runs, or for standard header files or definitions files that accompany that operating system. 4. You may not copy, modify, sublicense, distribute or transfer the Program except as expressly provided under this General Public License. Any attempt otherwise to copy, modify, sublicense, distribute or transfer the Program is void, and will automatically terminate your rights to use the Program under this License. However, parties who have received copies, or rights to use copies, from you under this General Public License will not have their licenses terminated so long as such parties remain in full compliance. 5. By copying, distributing or modifying the Program (or any work based on the Program) you indicate your acceptance of this license to do so, and all its terms and conditions. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. 7. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of the license which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of the license, you may choose any version ever published by the Free Software Foundation. 8. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 9. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 10. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS Appendix: How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to humanity, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) 19yy This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 1, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) 19xx name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (a program to direct compilers to make passes at assemblers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice That's all there is to it! --- The Artistic License 1.0 --- This software is Copyright (c) 2018 by Matt Simerson. This is free software, licensed under: The Artistic License 1.0 The Artistic License Preamble The intent of this document is to state the conditions under which a Package may be copied, such that the Copyright Holder maintains some semblance of artistic control over the development of the package, while giving the users of the package the right to use and distribute the Package in a more-or-less customary fashion, plus the right to make reasonable modifications. Definitions: - "Package" refers to the collection of files distributed by the Copyright Holder, and derivatives of that collection of files created through textual modification. - "Standard Version" refers to such a Package if it has not been modified, or has been modified in accordance with the wishes of the Copyright Holder. - "Copyright Holder" is whoever is named in the copyright or copyrights for the package. - "You" is you, if you're thinking about copying or distributing this Package. - "Reasonable copying fee" is whatever you can justify on the basis of media cost, duplication charges, time of people involved, and so on. (You will not be required to justify it to the Copyright Holder, but only to the computing community at large as a market that must bear the fee.) - "Freely Available" means that no fee is charged for the item itself, though there may be fees involved in handling the item. It also means that recipients of the item may redistribute it under the same conditions they received it. 1. You may make and give away verbatim copies of the source form of the Standard Version of this Package without restriction, provided that you duplicate all of the original copyright notices and associated disclaimers. 2. You may apply bug fixes, portability fixes and other modifications derived from the Public Domain or from the Copyright Holder. A Package modified in such a way shall still be considered the Standard Version. 3. You may otherwise modify your copy of this Package in any way, provided that you insert a prominent notice in each changed file stating how and when you changed that file, and provided that you do at least ONE of the following: a) place your modifications in the Public Domain or otherwise make them Freely Available, such as by posting said modifications to Usenet or an equivalent medium, or placing the modifications on a major archive site such as ftp.uu.net, or by allowing the Copyright Holder to include your modifications in the Standard Version of the Package. b) use the modified Package only within your corporation or organization. c) rename any non-standard executables so the names do not conflict with standard executables, which must also be provided, and provide a separate manual page for each non-standard executable that clearly documents how it differs from the Standard Version. d) make other distribution arrangements with the Copyright Holder. 4. You may distribute the programs of this Package in object code or executable form, provided that you do at least ONE of the following: a) distribute a Standard Version of the executables and library files, together with instructions (in the manual page or equivalent) on where to get the Standard Version. b) accompany the distribution with the machine-readable source of the Package with your modifications. c) accompany any non-standard executables with their corresponding Standard Version executables, giving the non-standard executables non-standard names, and clearly documenting the differences in manual pages (or equivalent), together with instructions on where to get the Standard Version. d) make other distribution arrangements with the Copyright Holder. 5. You may charge a reasonable copying fee for any distribution of this Package. You may charge any fee you choose for support of this Package. You may not charge a fee for this Package itself. However, you may distribute this Package in aggregate with other (possibly commercial) programs as part of a larger (possibly commercial) software distribution provided that you do not advertise this Package as a product of your own. 6. The scripts and library files supplied as input to or produced as output from the programs of this Package do not automatically fall under the copyright of this Package, but belong to whomever generated them, and may be sold commercially, and may be aggregated with this Package. 7. C or perl subroutines supplied by you and linked into this Package shall not be considered part of this Package. 8. The name of the Copyright Holder may not be used to endorse or promote products derived from this software without specific prior written permission. 9. THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. The End Mail-DMARC-1.20260306/MANIFEST000444000765000024 441715152630466 14360 0ustar00mattstaff000000000000.perltidyrc bin/dmarc_http_client bin/dmarc_httpd bin/dmarc_lookup bin/dmarc_receive bin/dmarc_send_reports bin/dmarc_sqlite_to_mysql.pl bin/dmarc_update_public_suffix_list bin/dmarc_view_reports bin/install_deps.pl Build.PL Changes.md DEVELOP.md example/report_cgi.png FAQ.md INSTALL.md lib/Mail/DMARC.pm lib/Mail/DMARC/Base.pm lib/Mail/DMARC/HTTP.pm lib/Mail/DMARC/Policy.pm lib/Mail/DMARC/PurePerl.pm lib/Mail/DMARC/Report.pm lib/Mail/DMARC/Report/Aggregate.pm lib/Mail/DMARC/Report/Aggregate/Metadata.pm lib/Mail/DMARC/Report/Aggregate/Record.pm lib/Mail/DMARC/Report/Aggregate/Record/Auth_Results.pm lib/Mail/DMARC/Report/Aggregate/Record/Auth_Results/DKIM.pm lib/Mail/DMARC/Report/Aggregate/Record/Auth_Results/SPF.pm lib/Mail/DMARC/Report/Aggregate/Record/Identifiers.pm lib/Mail/DMARC/Report/Aggregate/Record/Row.pm lib/Mail/DMARC/Report/Aggregate/Record/Row/Policy_Evaluated.pm lib/Mail/DMARC/Report/Receive.pm lib/Mail/DMARC/Report/Send.pm lib/Mail/DMARC/Report/Send/HTTP.pm lib/Mail/DMARC/Report/Send/SMTP.pm lib/Mail/DMARC/Report/Sender.pm lib/Mail/DMARC/Report/Store.pm lib/Mail/DMARC/Report/Store/SQL.pm lib/Mail/DMARC/Report/Store/SQL/Grammars/MySQL.pm lib/Mail/DMARC/Report/Store/SQL/Grammars/PostgreSQL.pm lib/Mail/DMARC/Report/Store/SQL/Grammars/SQLite.pm lib/Mail/DMARC/Report/URI.pm lib/Mail/DMARC/Result.pm lib/Mail/DMARC/Result/Reason.pm lib/Mail/DMARC/Test/Transport.pm LICENSE Makefile.PL MANIFEST This list of files MANIFEST.SKIP META.json META.yml README.md share/dmarc_whitelist share/html/index.html share/mail-dmarc.cron share/mail-dmarc.ini share/mail_dmarc_schema.mysql share/mail_dmarc_schema.pgsql share/mail_dmarc_schema.sqlite share/public_suffix_list share/rua-schema.xsd t/00.Dmarc.t t/01.Policy.t t/03.Base.t t/04.PurePerl.t t/06.Result.t t/09.HTTP.t t/10.Report.t t/11.Report.Store.t t/12.Report.Store.SQL.t t/13.Report.Aggregate.t t/14.Report.Aggregate.Metadata.t t/15.Report.Aggregate.Record.t t/16.Report.Aggregate.Record.Auth_Results.t t/17.Report.Aggregate.Schema.t t/20.Report.URI.t t/21.Report.Send.t t/22.Report.Send.SMTP.t t/23.Report.Send.HTTP.t t/25.Report.Receive.t t/26.Report.Sender.t t/backends/mail-dmarc.sql.mysql.ini t/backends/mail-dmarc.sql.Pg.ini t/backends/mail-dmarc.sql.SQLite.ini t/mail-dmarc.ini t/whitelist TODO.md xt/author-critic.t xt/perlcritic.rc Mail-DMARC-1.20260306/MANIFEST.SKIP000444000765000024 26515152630466 15102 0ustar00mattstaff000000000000.DS_Store .coveralls.yml .git .test .release .tar.gz .travis.yml ^_build ^blib ^Makefile$ ^Makefile.old$ ^Build$ ^MANIFEST\.bak$ ^MYMETA. dmarc_reports.sqlite t/reports-test.sqlite Mail-DMARC-1.20260306/META.json000444000765000024 1640515152630466 14670 0ustar00mattstaff000000000000{ "abstract" : "Perl implementation of DMARC", "author" : [ "Matt Simerson ", "Davide Migliavacca ", "Marc Bradshaw " ], "dynamic_config" : 1, "generated_by" : "Module::Build version 0.4234", "license" : [ "perl_5" ], "meta-spec" : { "url" : "http://search.cpan.org/perldoc?CPAN::Meta::Spec", "version" : 2 }, "name" : "Mail-DMARC", "prereqs" : { "build" : { "requires" : { "Module::Build" : "0.3601" } }, "configure" : { "requires" : { "File::ShareDir::Install" : "0.06", "Module::Build" : "0.3601" } }, "runtime" : { "recommends" : { "Mail::DKIM" : "0", "Net::IMAP::Simple" : "0", "Net::SMTPS" : "0" }, "requires" : { "Carp" : "0", "Config::Tiny" : "0", "DBD::SQLite" : "1.31", "DBIx::Simple" : "1.35", "Data::Dumper" : "0", "Email::MIME" : "0", "Email::Sender" : "0", "Email::Sender::Simple" : "1.300032", "Email::Simple" : "0", "Encode" : "0", "English" : "0", "File::ShareDir" : "1.00", "Getopt::Long" : "0", "HTTP::Tiny" : "0", "IO::Compress::Gzip" : "0", "IO::Compress::Zip" : "0", "IO::File" : "0", "IO::Socket::SSL" : "0", "IO::Uncompress::Gunzip" : "0", "IO::Uncompress::Unzip" : "0", "Module::Load" : "0", "Net::DNS::Resolver" : "0", "Net::IDN::Encode" : "0", "Net::IP" : "0", "Net::SSLeay" : "0", "POSIX" : "0", "Pod::Usage" : "0", "Regexp::Common" : "2013031301", "Socket" : "0", "Socket6" : "0.23", "Sys::Hostname" : "0", "Sys::Syslog" : "0", "Test::File::ShareDir" : "0", "URI" : "0", "XML::LibXML" : "0", "perl" : "v5.10.0" } }, "test" : { "requires" : { "Net::DNS::Resolver::Mock" : "0", "Test::Exception" : "0", "Test::File::ShareDir" : "0", "Test::More" : "0", "Test::Output" : "0" } } }, "provides" : { "Mail::DMARC" : { "file" : "lib/Mail/DMARC.pm", "version" : "1.20260306" }, "Mail::DMARC::Base" : { "file" : "lib/Mail/DMARC/Base.pm", "version" : "1.20260306" }, "Mail::DMARC::HTTP" : { "file" : "lib/Mail/DMARC/HTTP.pm", "version" : "1.20260306" }, "Mail::DMARC::Policy" : { "file" : "lib/Mail/DMARC/Policy.pm", "version" : "1.20260306" }, "Mail::DMARC::PurePerl" : { "file" : "lib/Mail/DMARC/PurePerl.pm", "version" : "1.20260306" }, "Mail::DMARC::Report" : { "file" : "lib/Mail/DMARC/Report.pm", "version" : "1.20260306" }, "Mail::DMARC::Report::Aggregate" : { "file" : "lib/Mail/DMARC/Report/Aggregate.pm", "version" : "1.20260306" }, "Mail::DMARC::Report::Aggregate::Metadata" : { "file" : "lib/Mail/DMARC/Report/Aggregate/Metadata.pm", "version" : "1.20260306" }, "Mail::DMARC::Report::Aggregate::Record" : { "file" : "lib/Mail/DMARC/Report/Aggregate/Record.pm", "version" : "1.20260306" }, "Mail::DMARC::Report::Aggregate::Record::Auth_Results" : { "file" : "lib/Mail/DMARC/Report/Aggregate/Record/Auth_Results.pm", "version" : "1.20260306" }, "Mail::DMARC::Report::Aggregate::Record::Auth_Results::DKIM" : { "file" : "lib/Mail/DMARC/Report/Aggregate/Record/Auth_Results/DKIM.pm", "version" : "1.20260306" }, "Mail::DMARC::Report::Aggregate::Record::Auth_Results::SPF" : { "file" : "lib/Mail/DMARC/Report/Aggregate/Record/Auth_Results/SPF.pm", "version" : "1.20260306" }, "Mail::DMARC::Report::Aggregate::Record::Identifiers" : { "file" : "lib/Mail/DMARC/Report/Aggregate/Record/Identifiers.pm", "version" : "1.20260306" }, "Mail::DMARC::Report::Aggregate::Record::Row" : { "file" : "lib/Mail/DMARC/Report/Aggregate/Record/Row.pm", "version" : "1.20260306" }, "Mail::DMARC::Report::Aggregate::Record::Row::Policy_Evaluated" : { "file" : "lib/Mail/DMARC/Report/Aggregate/Record/Row/Policy_Evaluated.pm", "version" : "1.20260306" }, "Mail::DMARC::Report::Receive" : { "file" : "lib/Mail/DMARC/Report/Receive.pm", "version" : "1.20260306" }, "Mail::DMARC::Report::Send" : { "file" : "lib/Mail/DMARC/Report/Send.pm", "version" : "1.20260306" }, "Mail::DMARC::Report::Send::HTTP" : { "file" : "lib/Mail/DMARC/Report/Send/HTTP.pm", "version" : "1.20260306" }, "Mail::DMARC::Report::Send::SMTP" : { "file" : "lib/Mail/DMARC/Report/Send/SMTP.pm", "version" : "1.20260306" }, "Mail::DMARC::Report::Sender" : { "file" : "lib/Mail/DMARC/Report/Sender.pm" }, "Mail::DMARC::Report::Store" : { "file" : "lib/Mail/DMARC/Report/Store.pm", "version" : "1.20260306" }, "Mail::DMARC::Report::Store::SQL" : { "file" : "lib/Mail/DMARC/Report/Store/SQL.pm", "version" : "1.20260306" }, "Mail::DMARC::Report::Store::SQL::Grammars::MySQL" : { "file" : "lib/Mail/DMARC/Report/Store/SQL/Grammars/MySQL.pm", "version" : "1.20260306" }, "Mail::DMARC::Report::Store::SQL::Grammars::PostgreSQL" : { "file" : "lib/Mail/DMARC/Report/Store/SQL/Grammars/PostgreSQL.pm", "version" : "1.20260306" }, "Mail::DMARC::Report::Store::SQL::Grammars::SQLite" : { "file" : "lib/Mail/DMARC/Report/Store/SQL/Grammars/SQLite.pm", "version" : "1.20260306" }, "Mail::DMARC::Report::URI" : { "file" : "lib/Mail/DMARC/Report/URI.pm", "version" : "1.20260306" }, "Mail::DMARC::Result" : { "file" : "lib/Mail/DMARC/Result.pm", "version" : "1.20260306" }, "Mail::DMARC::Result::Reason" : { "file" : "lib/Mail/DMARC/Result/Reason.pm", "version" : "1.20260306" }, "Mail::DMARC::Test::Transport" : { "file" : "lib/Mail/DMARC/Test/Transport.pm" } }, "release_status" : "stable", "resources" : { "bugtracker" : { "web" : "https://github.com/msimerson/mail-dmarc/issues" }, "homepage" : "https://github.com/msimerson/mail-dmarc/wiki", "license" : [ "http://dev.perl.org/licenses/" ], "repository" : { "url" : "https://github.com/msimerson/mail-dmarc" } }, "version" : "1.20260306", "x_contributors" : [ "Benny Pedersen ", "Jean Paul Galea ", "Marisa Clardy ", "Priyadi Iman Nurcahyo ", "Ricardo Signes " ], "x_serialization_backend" : "JSON::PP version 4.06" } Mail-DMARC-1.20260306/META.yml000444000765000024 1212615152630466 14514 0ustar00mattstaff000000000000--- abstract: 'Perl implementation of DMARC' author: - 'Matt Simerson ' - 'Davide Migliavacca ' - 'Marc Bradshaw ' build_requires: Module::Build: '0.3601' Net::DNS::Resolver::Mock: '0' Test::Exception: '0' Test::File::ShareDir: '0' Test::More: '0' Test::Output: '0' configure_requires: File::ShareDir::Install: '0.06' Module::Build: '0.3601' dynamic_config: 1 generated_by: 'Module::Build version 0.4234, CPAN::Meta::Converter version 2.150013' license: perl meta-spec: url: http://module-build.sourceforge.net/META-spec-v1.4.html version: '1.4' name: Mail-DMARC provides: Mail::DMARC: file: lib/Mail/DMARC.pm version: '1.20260306' Mail::DMARC::Base: file: lib/Mail/DMARC/Base.pm version: '1.20260306' Mail::DMARC::HTTP: file: lib/Mail/DMARC/HTTP.pm version: '1.20260306' Mail::DMARC::Policy: file: lib/Mail/DMARC/Policy.pm version: '1.20260306' Mail::DMARC::PurePerl: file: lib/Mail/DMARC/PurePerl.pm version: '1.20260306' Mail::DMARC::Report: file: lib/Mail/DMARC/Report.pm version: '1.20260306' Mail::DMARC::Report::Aggregate: file: lib/Mail/DMARC/Report/Aggregate.pm version: '1.20260306' Mail::DMARC::Report::Aggregate::Metadata: file: lib/Mail/DMARC/Report/Aggregate/Metadata.pm version: '1.20260306' Mail::DMARC::Report::Aggregate::Record: file: lib/Mail/DMARC/Report/Aggregate/Record.pm version: '1.20260306' Mail::DMARC::Report::Aggregate::Record::Auth_Results: file: lib/Mail/DMARC/Report/Aggregate/Record/Auth_Results.pm version: '1.20260306' Mail::DMARC::Report::Aggregate::Record::Auth_Results::DKIM: file: lib/Mail/DMARC/Report/Aggregate/Record/Auth_Results/DKIM.pm version: '1.20260306' Mail::DMARC::Report::Aggregate::Record::Auth_Results::SPF: file: lib/Mail/DMARC/Report/Aggregate/Record/Auth_Results/SPF.pm version: '1.20260306' Mail::DMARC::Report::Aggregate::Record::Identifiers: file: lib/Mail/DMARC/Report/Aggregate/Record/Identifiers.pm version: '1.20260306' Mail::DMARC::Report::Aggregate::Record::Row: file: lib/Mail/DMARC/Report/Aggregate/Record/Row.pm version: '1.20260306' Mail::DMARC::Report::Aggregate::Record::Row::Policy_Evaluated: file: lib/Mail/DMARC/Report/Aggregate/Record/Row/Policy_Evaluated.pm version: '1.20260306' Mail::DMARC::Report::Receive: file: lib/Mail/DMARC/Report/Receive.pm version: '1.20260306' Mail::DMARC::Report::Send: file: lib/Mail/DMARC/Report/Send.pm version: '1.20260306' Mail::DMARC::Report::Send::HTTP: file: lib/Mail/DMARC/Report/Send/HTTP.pm version: '1.20260306' Mail::DMARC::Report::Send::SMTP: file: lib/Mail/DMARC/Report/Send/SMTP.pm version: '1.20260306' Mail::DMARC::Report::Sender: file: lib/Mail/DMARC/Report/Sender.pm Mail::DMARC::Report::Store: file: lib/Mail/DMARC/Report/Store.pm version: '1.20260306' Mail::DMARC::Report::Store::SQL: file: lib/Mail/DMARC/Report/Store/SQL.pm version: '1.20260306' Mail::DMARC::Report::Store::SQL::Grammars::MySQL: file: lib/Mail/DMARC/Report/Store/SQL/Grammars/MySQL.pm version: '1.20260306' Mail::DMARC::Report::Store::SQL::Grammars::PostgreSQL: file: lib/Mail/DMARC/Report/Store/SQL/Grammars/PostgreSQL.pm version: '1.20260306' Mail::DMARC::Report::Store::SQL::Grammars::SQLite: file: lib/Mail/DMARC/Report/Store/SQL/Grammars/SQLite.pm version: '1.20260306' Mail::DMARC::Report::URI: file: lib/Mail/DMARC/Report/URI.pm version: '1.20260306' Mail::DMARC::Result: file: lib/Mail/DMARC/Result.pm version: '1.20260306' Mail::DMARC::Result::Reason: file: lib/Mail/DMARC/Result/Reason.pm version: '1.20260306' Mail::DMARC::Test::Transport: file: lib/Mail/DMARC/Test/Transport.pm recommends: Mail::DKIM: '0' Net::IMAP::Simple: '0' Net::SMTPS: '0' requires: Carp: '0' Config::Tiny: '0' DBD::SQLite: '1.31' DBIx::Simple: '1.35' Data::Dumper: '0' Email::MIME: '0' Email::Sender: '0' Email::Sender::Simple: '1.300032' Email::Simple: '0' Encode: '0' English: '0' File::ShareDir: '1.00' Getopt::Long: '0' HTTP::Tiny: '0' IO::Compress::Gzip: '0' IO::Compress::Zip: '0' IO::File: '0' IO::Socket::SSL: '0' IO::Uncompress::Gunzip: '0' IO::Uncompress::Unzip: '0' Module::Load: '0' Net::DNS::Resolver: '0' Net::IDN::Encode: '0' Net::IP: '0' Net::SSLeay: '0' POSIX: '0' Pod::Usage: '0' Regexp::Common: '2013031301' Socket: '0' Socket6: '0.23' Sys::Hostname: '0' Sys::Syslog: '0' Test::File::ShareDir: '0' URI: '0' XML::LibXML: '0' perl: v5.10.0 resources: bugtracker: https://github.com/msimerson/mail-dmarc/issues homepage: https://github.com/msimerson/mail-dmarc/wiki license: http://dev.perl.org/licenses/ repository: https://github.com/msimerson/mail-dmarc version: '1.20260306' x_contributors: - 'Benny Pedersen ' - 'Jean Paul Galea ' - 'Marisa Clardy ' - 'Priyadi Iman Nurcahyo ' - 'Ricardo Signes ' x_serialization_backend: 'CPAN::Meta::YAML version 0.020' Mail-DMARC-1.20260306/Makefile.PL000444000765000024 1411715152630466 15217 0ustar00mattstaff000000000000use strict; use warnings FATAL => 'all'; use 5.008; use ExtUtils::MakeMaker; use File::ShareDir::Install; $File::ShareDir::Install::INCLUDE_DOTFILES = 1; $File::ShareDir::Install::INCLUDE_DOTDIRS = 1; install_share dist => "share"; my %META = ( "prereqs" => { "configure" => { "requires" => { "ExtUtils::MakeMaker" => 0, "File::ShareDir::Install" => "0.06", } }, "build" => { "requires" => { } }, "test" => { "recommends" => { "XML::SAX::ParserFactory" => "0", "XML::Validator::Schema" => "0" }, "requires" => { "Test::Exception" => 0, "Test::File::ShareDir" => 0, "Test::More" => 0, "Test::Output" => 0, "Net::DNS::Resolver::Mock" => 0 } }, "runtime" => { "recommends" => { "CGI" => 0, "GeoIP2" => 0, "HTTP::Request" => 0, "JSON" => 0, "LWP::UserAgent" => 0, "Mail::DKIM::PrivateKey" => 0, "Mail::DKIM::Signer" => 0, "Mail::DKIM::TextWrap" => 0, "Net::HTTP" => 0, "Net::SMTPS" => 0, "Net::Server::HTTP" => 0, }, "requires" => { "perl" => "5.10.0", "CPAN" => 0, "Carp" => 0, "Config::Tiny" => 0, "DBD::SQLite" => "1.31", "DBIx::Simple" => "1.35", "Data::Dumper" => 0, "Email::MIME" => 0, "Email::Sender" => 0, "Email::Sender::Simple" => "1.300032", "Email::Simple" => 0, "Encode" => 0, "English" => 0, "File::ShareDir" => 0, "Getopt::Long" => 0, "HTTP::Tiny" => 0, "IO::Compress::Gzip" => 0, "IO::Compress::Zip" => 0, "IO::File" => 0, "IO::Socket::SSL" => 0, "IO::Uncompress::Gunzip" => 0, "IO::Uncompress::Unzip" => 0, "Module::Load" => 0, "Net::DNS::Resolver" => 0, "Net::IDN::Encode" => 0, "Net::IP" => 0, "Net::SSLeay" => 0, "POSIX" => 0, "Pod::Usage" => 0, "Regexp::Common" => "2013031301", "Socket" => 0, "Socket6" => "0.23", "Sys::Hostname" => 0, "Sys::Syslog" => 0, "URI" => 0, "XML::LibXML" => 0, } }, "develop" => { "requires" => { }, "suggests" => { } }, }, "resources" => { "bugtracker" => { "web" => "https://github.com/msimerson/mail-dmarc/issues" }, "homepage" => "https://github.com/msimerson/mail-dmarc/wiki", "repository" => { "type" => "git", "url" => "git://github.com/msimerson/mail-dmarc.git", "web" => "https://github.com/msimerson/mail-dmarc" }, "license" => [ 'http://dev.perl.org/licenses/' ], }, "optional_features" => { "MySQL" => { "description" => "MySQL backend storage", "prereqs" => { "runtime" => { "requires" => { 'DBD::mysql' => '4.001', } } } }, "Postgres" => { "description" => "PostgresQL backend storage", "prereqs" => { "runtime" => { "requires" => { 'DBD::Pg' => '0' } } } }, "web_service" => { "description" => "HTTP web UI to DMARC reports", "prereqs" => { "runtime" => { "requires" => { "CGI" => 0, "HTTP::Request" => 0, "JSON" => 0, "Net::HTTP" => 0, "Net::Server::HTTP" => 0, } } } }, "smtp_sending" => { "description" => "Send DMARC reports via SMTP", "prereqs" => { "runtime" => { "requires" => { "Email::Sender" => 0, "Net::SMTPS" => 0, "Mail::DKIM::PrivateKey" => 0, "Mail::DKIM::Signer" => 0, "Mail::DKIM::TextWrap" => 0 } } } }, "imap_fetch" => { "description" => "Retrieve DMARC reports from an IMAP account", "prereqs" => { "runtime" => { "requires" => { "Net::IMAP::Simple" => 0, } } } } }, ); my %MM_ARGS = ( "NAME" => "Mail::DMARC", "ABSTRACT" => "Perl implementation of DMARC", "AUTHOR" => "Matt Simerson , Davide Migliavacca , Marc Bradshaw ", "DISTNAME" => "Mail-DMARC", "VERSION_FROM" => "lib/Mail/DMARC.pm", "EXE_FILES" => [ "bin/dmarc_update_public_suffix_list", "bin/dmarc_send_reports", "bin/dmarc_httpd", "bin/dmarc_lookup", "bin/dmarc_receive", "bin/dmarc_http_client", "bin/dmarc_view_reports" ], "META_MERGE" => { "meta-spec" => { version => 2 }, "x_contributors" => [ "Benny Pedersen ", "Jean Paul Galea ", "Marisa Clardy ", "Priyadi Iman Nurcahyo ", "Ricardo Signes " ], }, "MIN_PERL_VERSION" => "5.008", "test" => { "TESTS" => "t/*.t" }, "clean" => { "FILES" => [ "dmarc_reports.sqlite", "t/reports-test.sqlite", 'MANIFEST.bak' ] }, ); # some nifty boilerplate from local::lib my $requires = $MM_ARGS{PREREQ_PM} = { %{$META{prereqs}{runtime}{requires}} }; $MM_ARGS{META_ADD} = { 'meta-spec' => { version => 2 }, %META }; for (qw(configure build test runtime)) { my $key = $_ eq 'runtime' ? 'PREREQ_PM' : uc $_.'_REQUIRES'; my $r = $MM_ARGS{$key} = { %{$META{prereqs}{$_}{requires} || {}}, %{delete $MM_ARGS{$key} || {}}, }; defined $r->{$_} or delete $r->{$_} for keys %$r; } my $eumm_version = eval $ExtUtils::MakeMaker::VERSION; if ( $eumm_version < 6.47_01 ) { delete $MM_ARGS{MIN_PERL_VERSION}; } if ( $eumm_version < 6.51_03 ) { delete $MM_ARGS{CONFIGURE_REQUIRES}; } if ( $eumm_version < 6.63_03 ) { $MM_ARGS{BUILD_REQUIRES} = {%{$MM_ARGS{BUILD_REQUIRES}}, %{delete $MM_ARGS{TEST_REQUIRES}}}; } if ( $eumm_version < 6.55_01 ) { $MM_ARGS{PREREQ_PM} = {%{$MM_ARGS{PREREQ_PM}}, %{delete $MM_ARGS{BUILD_REQUIRES}}} } my %WriteMakefileArgs = (%MM_ARGS); WriteMakefile(%WriteMakefileArgs); { package MY; use File::ShareDir::Install qw(postamble); } Mail-DMARC-1.20260306/README.md000444000765000024 2614115152630466 14524 0ustar00mattstaff000000000000# Status Badges [![Build Status](https://github.com/msimerson/mail-dmarc/actions/workflows/ci.yml/badge.svg)](https://github.com/msimerson/mail-dmarc/actions/workflows/ci.yml) [![Coverage Status](https://coveralls.io/repos/msimerson/mail-dmarc/badge.svg)](https://coveralls.io/r/msimerson/mail-dmarc) # NAME Mail::DMARC - Perl implementation of DMARC # VERSION version 1.20260306 # SYNOPSIS DMARC: Domain-based Message Authentication, Reporting and Conformance my $dmarc = Mail::DMARC::PurePerl->new( ... # see the documentation for the "new" method for required args ); my $result = $dmarc->validate(); if ( $result->result eq 'pass' ) { ...continue normal processing... return; }; # any result that did not pass is a fail. Now for disposition if ( $result->disposition eq 'reject' ) { ...treat the sender to a 550 ... }; if ( $result->disposition eq 'quarantine' ) { ...assign a bunch of spam points... }; if ( $result->disposition eq 'none' ) { ...continue normal processing... }; # DESCRIPTION This module is a suite of tools for implementing DMARC. It adheres to the 2013 DMARC draft, intending to implement every MUST and every SHOULD. This module can be used by... - MTAs and filtering tools like SpamAssassin to validate that incoming messages are aligned with the purported sender's policy. - email senders, to receive DMARC reports from other mail servers and display them via CLI and web interfaces. - MTA operators to send DMARC reports to DMARC author domains. When a message arrives via SMTP, the MTA or filtering application can pass in a small amount of metadata about the connection (envelope details, SPF and DKIM results) to Mail::DMARC. When the **validate** method is called, Mail::DMARC will determine if: a. the header_from domain exists b. the header_from domain publishes a DMARC policy c. if a policy is published... d. does the message conform to the published policy? e. did the policy request reporting? If so, save details. The validation results are returned as a [Mail::DMARC::Result](http://search.cpan.org/perldoc?Mail%3A%3ADMARC%3A%3AResult) object. If the author domain requested a report, it was saved to the [Report Store](http://search.cpan.org/perldoc?Mail%3A%3ADMARC%3A%3AReport%3A%3AStore). The Store class includes a SQL implementation that is tested with SQLite, MySQL and PostgreSQL. There is more information available in the $result object. See [Mail::DMARC::Result](http://search.cpan.org/perldoc?Mail%3A%3ADMARC%3A%3AResult) for complete details. Reports are viewed with the [dmarc\_view\_reports](http://search.cpan.org/perldoc?dmarc_view_reports) program or with a web browser and the [dmarc\_httpd](http://search.cpan.org/perldoc?dmarc_httpd) program. Aggregate reports are sent to their requestors with the [dmarc\_send\_reports](http://search.cpan.org/perldoc?dmarc_send_reports) program. For aggregate reports that you have been sent, the [dmarc\_receive](http://search.cpan.org/perldoc?dmarc_receive) program will parse the email messages (from IMAP, Mbox, or files) and save the report results into the [Report Store](http://search.cpan.org/perldoc?Mail%3A%3ADMARC%3A%3AReport%3A%3AStore). The report store can use the same database to store reports you have received as well as reports you will send. There are several ways to identify the difference, including: - received reports will have a null value for report\_policy\_published.rua - outgoing reports will have null values for report.uuid and report\_record.count # CLASSES [Mail::DMARC](http://search.cpan.org/perldoc?Mail%3A%3ADMARC) - the perl interface for DMARC [Mail::DMARC::Policy](http://search.cpan.org/perldoc?Mail%3A%3ADMARC%3A%3APolicy) - a DMARC policy [Mail::DMARC::PurePerl](http://search.cpan.org/perldoc?Mail%3A%3ADMARC%3A%3APurePerl) - Pure Perl implementation of DMARC [Mail::DMARC::Result](http://search.cpan.org/perldoc?Mail%3A%3ADMARC%3A%3AResult) - the results of applying policy [Mail::DMARC::Report](http://search.cpan.org/perldoc?Mail%3A%3ADMARC%3A%3AReport) - Reporting: the R in DMARC > [Mail::DMARC::Report::Send](http://search.cpan.org/perldoc?Mail%3A%3ADMARC%3A%3AReport%3A%3ASend) - send reports via SMTP & HTTP > > [Mail::DMARC::Report::Receive](http://search.cpan.org/perldoc?Mail%3A%3ADMARC%3A%3AReport%3A%3AReceive) - receive and store reports from email, HTTP > > [Mail::DMARC::Report::Store](http://search.cpan.org/perldoc?Mail%3A%3ADMARC%3A%3AReport%3A%3AStore) - a persistent data store for aggregate reports > > [Mail::DMARC::Report::View](http://search.cpan.org/perldoc?Mail%3A%3ADMARC%3A%3AReport%3A%3AView) - CLI and CGI methods for viewing reports [Mail::DMARC::libopendmarc](http://search.cpan.org/~shari/Mail-DMARC-opendmarc) - an XS implementation using libopendmarc # METHODS ## new Create a DMARC object. my $dmarc = Mail::DMARC::PurePerl->new; Populate it. $dmarc->source_ip('192.0.1.1'); $dmarc->envelope_to('recipient.example.com'); $dmarc->envelope_from('sender.example.com'); $dmarc->header_from('sender.example.com'); $dmarc->dkim( $dkim_verifier ); $dmarc->spf([ { domain => 'example.com', scope => 'mfrom', result => 'pass', }, { scope => 'helo', domain => 'mta.example.com', result => 'fail', }, ]); Run the request: my $result = $dmarc->validate(); Alternatively, pass in all the required parameters in one shot: my $dmarc = Mail::DMARC::PurePerl->new( source_ip => '192.0.1.1', envelope_to => 'example.com', envelope_from => 'cars4you.info', header_from => 'yahoo.com', dkim => $dkim_results, # same format spf => $spf_results, # as previous example ); my $result = $dmarc->validate(); ## source\_ip The remote IP that attempted sending the message. DMARC only uses this data for reporting to domains that request DMARC reports. ## envelope\_to The domain portion of the RFC5321.RcptTo, (aka, the envelope recipient), and the bold portion in the following example: > RCPT TO:&lt;user@**example.com**> ## envelope\_from The domain portion of the RFC5321.MailFrom, (aka, the envelope sender). That is the the bold portion in the following example: > MAIL FROM:&lt;user@**example.com**> ## header\_from The domain portion of the RFC5322.From, aka, the From message header. > From: Ultimate Vacation &lt;sweepstakes@**example.com**> You can instead pass in the entire From: header with header\_from\_raw. ## header\_from\_raw Retrieve the header\_from domain by parsing it from a raw From field/header. The domain portion is extracted by [get\_dom\_from\_header](http://search.cpan.org/perldoc?Mail%3A%3ADMARC%3A%3APurePerl%23get_dom_from_header), which is fast, generally effective, but also rather crude. It has limits, so read the description. ## dkim If Mail::DKIM::Verifier was used to validate the message, just pass in the Mail::DKIM::Verifier object that processed the message: $dmarc->dkim( $dkim_verifier ); Otherwise, pass in an array reference. Each member of the DKIM array results represents a DKIM signature in the message and consists of the 4 keys shown in this example: $dmarc->dkim( [ { domain => 'example.com', selector => 'apr2013', result => 'fail', human_result=> 'fail (body has been altered)', }, { # 2nd signature, if present }, ] ); The dkim results can also be build iteratively by passing in key value pairs or hash references for each signature in the message: $dmarc->dkim( domain => 'sig1.com', result => 'fail' ); $dmarc->dkim( domain => 'sig2.com', result => 'pass' ); $dmarc->dkim( { domain => 'example.com', result => 'neutral' } ); Each hash or hashref is appended to the dkim array. Finally, you can pass a coderef which won't be called until the dkim method is used to read the dkim results. It must return an array reference as described above. The dkim result is an array reference. ### domain The d= parameter in the DKIM signature ### selector The s= parameter in the DKIM signature ### result The validation results of this signature. One of: none, pass, fail, policy, neutral, temperror, or permerror ### human result Additional information about the DKIM result. This is comparable to Mail::DKIM::Verifier->result\_detail. ## spf The spf method works exactly the same as dkim. It accepts named arguments, a hashref, an arrayref, or a coderef: $dmarc->spf( domain => 'example.com', scope => 'mfrom', result => 'pass', ); The SPF domain and result are required for DMARC validation and the scope is used for reporting. ### domain The SPF checked domain ### scope The scope of the checked domain: mfrom, helo ### result The SPF result code: none, neutral, pass, fail, softfail, temperror, or permerror. # DESIGN & GOALS ## Correct The DMARC spec is lengthy and evolving, making correctness a moving target. In cases where correctness is ambiguous, options are generally provided. ## Easy to use Providing an implementation of DMARC that SMTP utilities can utilize will aid DMARC adoption. The list of dependencies appears long because of reporting. If this module is used without reporting, the number of dependencies not included with perl is about 5. ## Maintainable Since DMARC is evolving, this implementation aims to be straight forward and easy to alter and extend. The programming style is primarily OO, which carries a small performance penalty but dividends in maintainability. When multiple options are available, such as when sending reports via SMTP or HTTP, calls should be made to the parent Send class to broker the request. When storing reports, calls are made to the Store class which dispatches to the SQL class. The idea is that if someone desired a data store other than those provided by perl's DBI class, they could easily implement their own. If you do, please fork it on GitHub and share. ## Fast If you deploy this in an environment where performance is insufficient, please profile the app and submit a report and preferably, patches. # SEE ALSO [Mail::DMARC on GitHub](https://github.com/msimerson/mail-dmarc) 2015-03 [RFC 7489](https://tools.ietf.org/html/rfc7489) DMARC [Best Current Practices](http://tools.ietf.org/html/draft-crocker-dmarc-bcp-03) # HISTORY The daddy of this perl module was a [DMARC module for the qpsmtpd MTA](https://github.com/smtpd/qpsmtpd/blob/master/plugins/dmarc). # AUTHORS - Matt Simerson - Davide Migliavacca - Marc Bradshaw # CONTRIBUTORS - Benny Pedersen - Jean Paul Galea - Marisa Clardy - Priyadi Iman Nurcahyo - Ricardo Signes # COPYRIGHT AND LICENSE This software is copyright (c) 2026 by Matt Simerson. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. Mail-DMARC-1.20260306/TODO.md000444000765000024 104515152630466 14310 0ustar00mattstaff000000000000 ### Planned Features * [ ] Forensic reports * [ ] HTTP report delivery * [ ] more SMTP error reporting * [ ] Report SPF records in dmarc\_lookup output * [ ] add a 'cron' mode for dmarc\_send and dmarc\_receive, if no controlling TTY, don't output status messages * [ ] skip DMARC reporting for incoming DMARC reports destined to config->organization->email ### Maybe TODO: * [ ] detect > 1 From recipient, apply strongest policy ### Done * [x] automatically delete reports after 12 delivery errors * [x] send a 'too big' notification email Mail-DMARC-1.20260306/bin000755000765000024 015152630466 13634 5ustar00mattstaff000000000000Mail-DMARC-1.20260306/bin/dmarc_http_client000555000765000024 453715152630466 17413 0ustar00mattstaff000000000000#!/usr/bin/perl use strict; use warnings; use Data::Dumper; use Getopt::Long; use HTTP::Request; use JSON; use LWP::UserAgent; my %command_line_options = ( 'host:s' => \my $host, 'port:s' => \my $port, 'data:s' => \my $data, ); GetOptions (%command_line_options); if (!$host) { $host = 'localhost'; warn "using default: --host=$host\n"; }; if (!$port) { $port = '8080'; warn "using default: --port=$port\n"; }; if (!$data) { $data = get_json_request(); warn "using sample --data\n"; }; if ($data eq '-') { $data = ''; while ($_ = <>) { chomp; $data .= $_; }; } my $url = "http://$host:$port/dmarc/json/validate"; my $ua = LWP::UserAgent->new; my $req = HTTP::Request->new(POST => $url); $req->content_type('application/json'); $req->content($data); my $response = $ua->request($req)->decoded_content; #print Dumper($response); # raw JSON response my $result; eval { $result = JSON->new->utf8->decode($response) }; if ($result) { print Dumper($result); # pretty formatted struct exit; }; die $response; sub get_json_request { return JSON->new->encode ({ source_ip => '192.0.1.1', envelope_to => 'example.com', envelope_from => 'cars4you.info', header_from => 'yahoo.com', dkim => [ { domain => 'example.com', selector => 'apr2013', result => 'fail', human_result => 'fail (body has been altered)', } ], spf => [ { domain => 'example.com', scope => 'mfrom', result => 'pass', } ], }); }; __END__ =pod =head1 NAME dmarc_http_client: an HTTP client for submitting a DMARC validation request =head1 SYNOPSIS Send JSON encoded HTTP requests to the DMARC validation service provided by dmarc_httpd. dmarc_http_client --host=localhost --port=8080 --data='{"envelope_from":"cars4you.info"...}' The data option accepts a special '-' value that will read the JSON encoded data from STDIN. Use it like this: cat /path/to/data.json | dmarc_http_client --data=- =head1 AUTHORS =over 4 =item * Matt Simerson =item * Davide Migliavacca =item * Marc Bradshaw =back =cut Mail-DMARC-1.20260306/bin/dmarc_httpd000555000765000024 411015152630466 16204 0ustar00mattstaff000000000000#!/usr/bin/perl use strict; use warnings; use Mail::DMARC; use Mail::DMARC::HTTP; my $dmarc = Mail::DMARC->new(); $dmarc->is_public_suffix('tnpi.net'); my $report = $dmarc->report; my $http = Mail::DMARC::HTTP->new; $http->dmarc_httpd($report); exit; __END__ =pod =head1 NAME dmarc_httpd: a web server for DMARC validation and report viewing =head1 SYNOPSIS A HTTP interface for: =over 4 =item * local DMARC reports =item * DMARC validator service =back Start the HTTP server: dmarc_httpd Connect with a web browser to L. =head1 DESCRIPTION The HTTP server handles 4 types of requests: =over 4 =item * / Serves files stored in the perl share directory of the Mail::DMARC module. This presently entails one HTML file and a handful of CSS and JS files for the report viewing feature. =item * /dmarc/json/validate - DMARC validation requests Accepts a JSON encoded HTTP POST request. Validates the request, performs a DMARC validation and returns a JSON encoded result object. This is the API for non-perl applications to utilize Mail::DMARC. See the dmarc_http_client app for a usage example. =item * /dmarc/json/report Accepts AJAX requests from the browser and returns JSON encoded DMARC reports. =item * /dmarc/json/row Accepts AJAX requests from the browser and returns JSON encoded DMARC report rows. =back An implementation that uses the http validation service is the included and another is the dmarc plugin in the . A L is available which shows the web interface. It is implemented almost entirely in JavaScript, using jQuery, jQueryUI, and jqGrid. Web server settings are in the [http] and [https] sections of mail-dmarc.ini. =head1 THANKS jQuery - http://www.jquery.com/ jqGrid - http://www.trirand.com/blog/ =head1 AUTHORS =over 4 =item * Matt Simerson =item * Davide Migliavacca =item * Marc Bradshaw =back =cut Mail-DMARC-1.20260306/bin/dmarc_lookup000555000765000024 422315152630466 16377 0ustar00mattstaff000000000000#!/usr/bin/perl use strict; use warnings; use Data::Dumper; use Getopt::Long; use Pod::Usage; $Data::Dumper::Sortkeys = 1; $Data::Dumper::Quotekeys = 0; use Mail::DMARC::PurePerl; my %command_line_options = ( 'domain:s' => \my $domain, 'verbose' => \my $verbose, ); GetOptions (%command_line_options); $verbose = 1 if ! defined $verbose; $domain ||= $ARGV[0]; $domain or pod2usage; my $dmarc = Mail::DMARC::PurePerl->new; $dmarc->verbose($verbose); $dmarc->header_from($domain); my $policy = $dmarc->discover_policy() or die "no DMARC policy published for $domain\n"; print Dumper( $policy ); if ( $policy->rua ) { print "\n"; my $uri_count = $dmarc->has_valid_reporting_uri( $policy->rua ); print "valid report URI: "; print $uri_count ? "yes\n" : "no\n"; }; exit; __END__ =pod =head1 NAME dmarc_lookup: look up DMARC policy for a domain =head1 SYNOPSIS dmarc_lookup example.com [ --verbose ] =head1 DESCRIPTION Query the DNS for a DMARC policy for a (sub)domain. Displays any found results as the DNS record as a perl object. In the simplest case, where the domain name in the email From header matches the I, this is roughly equivalent to the following commands: dig +short _dmarc.example.com TXT print $_->txtdata."\n" for Net::DNS::Resolver->new(dnsrch=>0)->send('_dmarc.example.com','TXT')->answer; When the domain name in the email From header (header_from) is not an Organizational Domain (ex: www.example.com), an attempt is made to determine the O.D. using the Mozilla Public Suffix List. When the O.D. differs from the header_from, a second DNS query is sent to _dmarc.[O.D.]. =head1 EXAMPLES A DMARC record in DNS format looks like this: v=DMARC1; p=reject; adkim=s; aspf=s; rua=mailto:dmarc@example.com; pct=100; DMARC records are stored as TXT resource records in the DNS, at _dmarc.example.com. Other ways to retrieve a DMARC record for a domain are: =head1 SEE ALSO L =head1 AUTHORS =over 4 =item * Matt Simerson =item * Davide Migliavacca =item * Marc Bradshaw =back =cut Mail-DMARC-1.20260306/bin/dmarc_receive000555000765000024 364415152630466 16516 0ustar00mattstaff000000000000#!/usr/bin/perl use strict; use warnings; use Data::Dumper; use Getopt::Long; use Pod::Usage; use Mail::DMARC::Report::Receive; $|++; my %command_line_options = ( 'file:s' => \my $file, 'imap' => \my $imap, 'mbox' => \my $mbox, 'verbose+' => \my $verbose, ); GetOptions (%command_line_options); pod2usage(0) if ! $imap && ! $mbox && ! $file; ## no critic (Carp) my $recv = Mail::DMARC::Report::Receive->new() or die; $recv->verbose($verbose) if $verbose; $recv->from_imap if $imap; $recv->from_mbox($mbox) if $mbox; $recv->from_file($file) if $file; exit; __END__ =head1 NAME dmarc_receive: receive aggregate reports via IMAP, mbox, or message file(s) =head1 USAGE dmarc_receive [ --imap | --mbox | --file ] =head1 DESCRIPTION This script processes incoming DMARC reports from IMAP, files, or a mbox formatted file. =head2 IMAP To process reports with IMAP, you must configure the [imap] settings in mail-dmarc.ini. This program will: * log into the IMAP account * select the specified folder (INBOX, dmarc, etc) * for every unread (Unseen) message, search for DMARC reports =head3 IMAP Aggregate report IMAP aggregate reports are detected by the presence of zip or gzip attachments. When an aggregate report is detected: * the attachment is decompressed * the XML is parsed * the report is saved to the report store * the message is marked as read/seen * move message to [imap][a_done] folder (if defined) =head3 IMAP Forensic report IMAP forensic reports are detected by the presence of the content-types message/feedback-report and text/rfc822-headers. When a forensic report is detected it is moved to the [imap][f_done] IMAP folder. =head2 File as message Accepts the filename of a file containing a mail message. The message is parsed and stored. =head2 Mbox Accepts the filename of a mbox format file containing mail messages. The messages are parsed and stored. =cut Mail-DMARC-1.20260306/bin/dmarc_send_reports000555000765000024 60115152630466 17551 0ustar00mattstaff000000000000#!/usr/bin/perl use strict; use warnings; use Mail::DMARC::Report::Sender; my $sender = Mail::DMARC::Report::Sender->new; $sender->run; __END__ =pod =head1 NAME dmarc_send_reports: send aggregate reports =head1 AUTHORS =over 4 =item * Matt Simerson =item * Davide Migliavacca =item * Marc Bradshaw =back =cut Mail-DMARC-1.20260306/bin/dmarc_sqlite_to_mysql.pl000555000765000024 2113215152630466 20746 0ustar00mattstaff000000000000#!/usr/bin/env perl use strict; use warnings; use DBI; use Getopt::Long; use Pod::Usage; my ($help, $verbose); GetOptions( 'help|h' => \$help, 'verbose|v' => \$verbose, ) or pod2usage(2); pod2usage(1) if $help; pod2usage("$0: Missing required argument: sqlite_db_path") unless @ARGV; my $sqlite_db = shift @ARGV; my $output_file = shift @ARGV; unless (-f $sqlite_db) { die "Error: SQLite database file '$sqlite_db' not found\n"; } my $fh; if ($output_file) { open($fh, '>', $output_file) or die "Error: Cannot open '$output_file' for writing: $!\n"; } else { $fh = \*STDOUT; } # Connect to SQLite database # sqlite_unicode is disabled to prevent corruption of binary data (source_ip) my $dbh = DBI->connect("dbi:SQLite:dbname=$sqlite_db", '', '', { RaiseError => 1, PrintError => 0, sqlite_unicode => 0, }) or die "Cannot connect to SQLite database: $DBI::errstr\n"; print $fh "-- MySQL import file exported from SQLite database\n"; print $fh "-- Generated by dmarc_sqlite_to_mysql\n"; print $fh "-- Source: $sqlite_db\n"; print $fh "-- \n"; print $fh "-- IMPORTANT: Create the MySQL schema FIRST using mail_dmarc_schema.mysql\n"; print $fh "-- before importing this data file. Foreign key lookup tables (fk_*) are\n"; print $fh "-- pre-populated by the schema and are NOT included in this export.\n"; print $fh "-- \n"; print $fh "SET FOREIGN_KEY_CHECKS=0;\n\n"; # Track domain id mappings for handling case-insensitive duplicates my %domain_id_map = (); # Define table export order (respecting foreign key dependencies) my @tables = ( 'author', 'domain', 'report', 'report_error', 'report_policy_published', 'report_record', 'report_record_reason', 'report_record_dkim', 'report_record_spf', ); # Special handling for domain table to normalize case and handle collisions export_domain_table($dbh, $fh, \%domain_id_map, $verbose); # Export remaining tables foreach my $table (@tables) { next if $table eq 'domain'; # Already exported export_table($dbh, $fh, $table, $verbose, \%domain_id_map); } print $fh "SET FOREIGN_KEY_CHECKS=1;\n"; $dbh->disconnect(); close($fh) if $output_file; print STDERR "Export complete" . ($output_file ? " to $output_file" : "") . "\n" if $verbose; exit 0; sub export_domain_table { my ($dbh, $fh, $domain_id_map, $verbose) = @_; print STDERR "Exporting table: domain (with case normalization)\n" if $verbose; # Get all domains from SQLite with their ids my $sth = $dbh->prepare("SELECT id, domain FROM domain ORDER BY id"); $sth->execute(); my %seen_lower = (); # Track lowercase domains we've already exported my $new_id = 1; print $fh "-- Table domain: normalized for case-insensitive collisions\n"; while (my $row = $sth->fetchrow_hashref()) { my $orig_id = $row->{id}; my $domain = $row->{domain}; my $domain_lower = lc($domain); if (exists $seen_lower{$domain_lower}) { # Collision: map this id to the one we already exported $domain_id_map->{$orig_id} = $seen_lower{$domain_lower}; print STDERR " Domain collision: '$domain' (id $orig_id) -> normalized to id $seen_lower{$domain_lower}\n" if $verbose; } else { # First time seeing this domain (case-insensitive) $seen_lower{$domain_lower} = $new_id; $domain_id_map->{$orig_id} = $new_id; # Export normalized domain my $escaped_domain = $domain_lower; $escaped_domain =~ s/\\/\\\\/g; $escaped_domain =~ s/'/\\'/g; print $fh "INSERT INTO `domain` (`id`, `domain`) VALUES ($new_id, '$escaped_domain');\n"; $new_id++; } } $sth->finish(); print $fh "\n"; } sub export_table { my ($dbh, $fh, $table, $verbose, $domain_id_map) = @_; print STDERR "Exporting table: $table\n" if $verbose; # Get column information my $sth = $dbh->prepare("PRAGMA table_info($table)"); $sth->execute(); my @columns; while (my $row = $sth->fetchrow_hashref()) { push @columns, $row->{name}; } $sth->finish(); unless (@columns) { print STDERR "Warning: Table '$table' has no columns or doesn't exist\n"; return; } # Get row count my $count_sth = $dbh->prepare("SELECT COUNT(*) FROM $table"); $count_sth->execute(); my ($row_count) = $count_sth->fetchrow_array(); $count_sth->finish(); if ($row_count == 0) { print $fh "-- Table $table: 0 rows\n\n"; return; } print $fh "-- Table $table: $row_count rows\n"; # Get all rows my $query = "SELECT " . join(', ', map { "`$_`" } @columns) . " FROM `$table`"; my $data_sth = $dbh->prepare($query); $data_sth->execute(); my $col_names = '`' . join('`, `', @columns) . '`'; while (my @row = $data_sth->fetchrow_array()) { my @values; for my $i (0 .. $#row) { if (!defined $row[$i]) { push @values, 'NULL'; } elsif ($columns[$i] eq 'source_ip') { # Handle binary IP data - convert to hex format if ($row[$i] eq '' || length($row[$i]) == 0) { push @values, "0x"; } else { # Convert binary data to hexadecimal my $hex = unpack('H*', $row[$i]); push @values, "0x$hex"; } } else { my $val = $row[$i]; # Remap domain IDs if this column references the domain table if (($columns[$i] eq 'from_domain_id' || $columns[$i] eq 'rcpt_domain_id' || $columns[$i] eq 'domain_id' || $columns[$i] eq 'envelope_to_did' || $columns[$i] eq 'envelope_from_did' || $columns[$i] eq 'header_from_did') && defined $val && exists $domain_id_map->{$val}) { $val = $domain_id_map->{$val}; } # Escape single quotes and handle special characters $val =~ s/\\/\\\\/g; # Backslash first $val =~ s/'/\\'/g; # Single quotes push @values, "'$val'"; } } print $fh "INSERT INTO `$table` ($col_names) VALUES (" . join(', ', @values) . ");\n"; } $data_sth->finish(); print $fh "\n"; } __END__ =head1 NAME dmarc_sqlite_to_mysql - Export SQLite database to MySQL SQL format =head1 SYNOPSIS dmarc_sqlite_to_mysql [options] [output_file] =head1 OPTIONS =over 4 =item B<-h, --help> Print help message and exit. =item B<-v, --verbose> Print status messages to STDERR during export. =back =head1 ARGUMENTS =over 4 =item B Path to the SQLite database file to export. =item B (optional) Output file for the SQL statements. If omitted, writes to STDOUT. =back =head1 DESCRIPTION This script exports data from a SQLite database into MySQL-compatible SQL INSERT statements. It respects foreign key dependencies by exporting tables in the correct order. B The script automatically normalizes domain names to lowercase and handles case-insensitive collisions. Since MySQL's default collation is case-insensitive, domains like "Example.com" and "example.com" would cause UNIQUE constraint violations. The script deduplicates these by: - Normalizing all domains to lowercase - Tracking id mappings for case-insensitive duplicates - Automatically remapping all foreign key references Binary IP address data (source_ip varbinary field) are converted to hexadecimal format for safe import into MySQL. B Foreign key lookup tables (fk_disposition, fk_disposition_reason, fk_dkim_result, fk_spf_result, fk_spf_scope) are NOT exported as they are pre-populated by the MySQL schema file. You must create the MySQL database schema FIRST using mail_dmarc_schema.mysql before importing the data. The output is suitable for importing directly into MySQL using: mysql -u user -p database < share/mail_dmarc_schema.mysql mysql -u user -p database < export.sql =head1 EXAMPLE Export to file: dmarc_sqlite_to_mysql mail_dmarc.db mail_dmarc_export.sql Complete migration workflow: # 1. Create the MySQL database and schema first mysql -u root -p -e "CREATE DATABASE mail_dmarc" mysql -u root -p mail_dmarc < share/mail_dmarc_schema.mysql # 2. Export SQLite data dmarc_sqlite_to_mysql mail_dmarc.db mail_dmarc_export.sql # 3. Import the data mysql -u root -p mail_dmarc < mail_dmarc_export.sql Export directly to MySQL: dmarc_sqlite_to_mysql mail_dmarc.db | mysql -u user -p database =cut Mail-DMARC-1.20260306/bin/dmarc_update_public_suffix_list000555000765000024 350615152630466 22330 0ustar00mattstaff000000000000#!/usr/bin/perl use strict; use warnings; use Getopt::Long; use HTTP::Tiny; use Mail::DMARC; use Pod::Usage; my $dryrun = 0; my $random = 0; GetOptions ( 'dryrun' => \$dryrun, 'help' => \my $help, 'random' => \$random, 'config-file=s' => \my $config_file, ); pod2usage if $help; if ( $random ) { my $sleep_for = int(rand(60*60)); sleep $sleep_for; } Mail::DMARC->new( (defined $config_file ? (config_file => $config_file) : ()) )->update_psl_file($dryrun); __END__ =pod =head1 NAME dmarc_update_public_suffix_list: command line tool to download updated public suffix list =head1 SYNOPSIS dmarc_update_public_suffix_list [ --option=value ] =head1 DESCRIPTION Downloads a new Public Suffix List to the location specified by /etc/mail-dmarc.ini The PSL is maintained by the Mozilla Foundation. It is updated a few times per month, you are requested to download no more than once per day. The URL of the file is https://publicsuffix.org/list/effective_tld_names.dat More details can be found at https://publicsuffix.org/ =head2 Options dmarc_update_public_suffix_list [ --dryrun --help ] dryrun - show what would be done without overwriting file random - introduce a random delay to spread server load intended for use when running from crontab config-file - alternate config file path help - print this syntax guide =head1 EXAMPLES To check that a new file can be downloaded without error but not download the file: dmarc_update_public_suffix_list --dryrun To download a new Public Suffix List to the location specified my mail-dmarc.ini dmarc_update_public_suffix_list =head1 AUTHORS =over 4 =item * Matt Simerson =item * Davide Migliavacca =item * Marc Bradshaw =back =cut Mail-DMARC-1.20260306/bin/dmarc_view_reports000555000765000024 2357415152630466 17650 0ustar00mattstaff000000000000#!/usr/bin/perl use strict; use warnings; use Data::Dumper; use Getopt::Long; use Pod::Usage; $|++; my %command_line_options = ( 'rid:s' => \my $rid, 'author:s' => \my $author, 'from_dom:s' => \my $from, 'begin:s' => \my $begin, 'end:s' => \my $end, 'sort:s' => \my $sort, 'limit:s' => \my $limit, 'disposition:s' => \my $disposition, 'dkim:s' => \my $dkim, 'spf:s' => \my $spf, 'dns' => \my $dns_opt, 'geoip' => \my $geoip_opt, 'help' => \my $help, 'verbose' => \my $verbose, ); GetOptions (%command_line_options); use Mail::DMARC::Report; my $report = Mail::DMARC::Report->new; my $gip; pod2usage if $help; $limit = 100 if !defined $limit; if ( defined $limit && ( $limit !~ /^\d+$/ || $limit < 1 ) ) { die "--limit must be a positive integer\n"; } my ( $sort_by, $sort_order ) = parse_sort_option($sort); my $reports = $report->store->retrieve( (defined $rid ? (rid => $rid ) : () ), (defined $from ? (from_domain => $from ) : () ), (defined $author ? (author => $author ) : () ), (defined $begin ? (begin => $begin ) : () ), (defined $end ? (end => $end ) : () ), (defined $limit ? (limit => $limit ) : () ), (sort_by => $sort_by), (sort_order => $sort_order), ); print_header(); foreach my $r ( @$reports ) { my $rows = $report->store->backend->get_rr( rid => $r->{rid} )->{data}; next if $disposition && ! grep { _matches($disposition, $_->{disposition}) } @$rows; next if $dkim && ! grep { _matches($dkim, $_->{dkim}) } @$rows; next if $spf && ! grep { _matches($spf, $_->{spf }) } @$rows; print_record($r); print_rows( $rows ); print "\n"; } sub _matches { my ($filter, $value) = @_; no warnings; ## no critic (NoWarn) if ( substr($filter, 0, 1) eq '!' ) { return $value ne substr($filter, 1); } return $value eq $filter; } sub parse_sort_option { my ($sort) = @_; $sort //= 'rid:desc'; $sort =~ s/^\s+|\s+$//g; return ('rid', 'DESC') if lc $sort eq 'newest'; return ('rid', 'ASC') if lc $sort eq 'oldest'; my ($sort_by, $sort_order) = split /:/, $sort, 2; $sort_by ||= 'rid'; $sort_order ||= 'desc'; $sort_by = lc $sort_by; $sort_order = uc $sort_order; $sort_by = 'rid' if $sort_by eq 'id'; my %allowed_sort = map { $_ => 1 } qw( rid author from_domain begin end ); die "--sort field must be one of: rid, author, from_domain, begin, end\n" if !$allowed_sort{$sort_by}; die "--sort order must be ASC or DESC\n" if $sort_order ne 'ASC' && $sort_order ne 'DESC'; return ($sort_by, $sort_order); } sub print_record { my $rec = shift; printf "%3s %26s %15s\n", @$rec{qw/ rid author begin /}; return; }; sub print_rows { my $rows = shift; foreach my $row ( @$rows ) { no warnings; ## no critic (NoWarn) next if $disposition && !_matches($disposition, $row->{disposition}); next if $dkim && !_matches($dkim, $row->{dkim}); next if $spf && !_matches($spf, $row->{spf}); printf " | -- %3s %20s %39s %13s %7s %7s", @$row{qw/ count header_from source_ip disposition dkim spf /}; foreach my $r ( @{ $row->{reasons} } ) { print ' ' . $r->{type}; print "( $r->{comment} )" if $r->{comment}; }; my $geoip_details = get_geoip_details( $row->{source_ip} ); print " $geoip_details"; my $dns_hostname = get_dns_hostname( $row->{source_ip} ); print " $dns_hostname\n"; } return; }; sub print_header { printf "%3s %26s %15s\n", qw[ ID Author Report-Start ]; printf " | -- %3s %20s %39s %13s %7s %7s\n", 'Qty','From','IP','Disposition','DKIM','SPF'; return; }; sub get_geoip_details { my $ip = shift; return if ! defined $geoip_opt; $gip ||= get_geoip_db(); return if ! $gip; my $city = $gip->city(ip => $ip) or return ''; my $result = ''; if ($city->continent->code) { $result .= $city->continent->code; } if ($city->country->iso_code) { $result .= ', ' .$city->country->iso_code; } if ($city->most_specific_subdivision->name) { $result .= ', ' . $city->most_specific_subdivision->name; } if ($city->city->name) { $result .= ', ' . $city->city->name; } return $result; } sub get_geoip_db { return $gip if $gip; eval "require GeoIP2::Database::Reader"; ## no critic (Eval) if ($@) { warn "unable to load GeoIP2\n"; return; }; foreach my $local ( '/usr/local', '/opt/local', '/usr' ) { my $db_dir = "$local/share/GeoIP"; foreach my $db (qw/ GeoLite2-City GeoLite2-Country /) { if (-f "$db_dir/$db.mmdb") { print "using db $db" if $verbose; $gip = GeoIP2::Database::Reader->new( file => "$db_dir/$db.mmdb" ); } last if $gip; } last if $gip; }; return $gip; } sub get_dns_hostname { my $ip = shift; return if ! $dns_opt; my @answers = $report->has_dns_rr('PTR', $ip); return '' if 0 == scalar @answers; return $answers[0] if scalar @answers >= 1; print Dumper(\@answers); return; }; exit; __END__ =head1 SYNOPSIS dmarc_view_reports [ --option=value ] Dumps the contents of the DMARC data store to your terminal. The most recent records are show first. =head2 Search Options rid - report ID (internal database ID) author - report author (Yahoo! Inc, google.com, etc..) from_dom - message sender domain begin - epoch start time to display messages after end - epoch end time to display messages before disposition - DMARC disposition (none,quarantine,reject) dkim - DKIM alignment result (pass/fail) spf - SPF alignment result (pass/fail) limit - limit number of reports returned (defaults to 100) sort - sort by: rid, author, from_domain, begin, end (append :asc or :desc) The default sort is C (newest reports first). You can also use C<--sort=newest> or C<--sort=oldest>. Prefix a value with C to negate the match (exclude matching records). This is supported for C, C, C, C, and C. For example, C<--author=!google.com> will exclude reports authored by google.com. =head2 Other Options dmarc_view_reports [ --geoip --dns --help --verbose ] geoip - do GeoIP lookups (requires the free Maxmind GeoCityLitev6 database). dns - do reverse DNS lookups and display hostnames help - print this syntax guide verbose - print additional debug info =head1 EXAMPLES To view a specific report by its ID: dmarc_view_reports --rid=560 To search for all reports from google.com that failed DMARC alignment: dmarc_view_reports --author=google.com --dkim=fail --spf=fail Note that we don't use --disposition. That would only tell us the result of applying DMARC policy, not necessarily if the messages failed DMARC alignment. To exclude reports from google.com: dmarc_view_reports --author=!google.com To exclude rows with a specific disposition: dmarc_view_reports --disposition=!none To show only the newest 50 reports: dmarc_view_reports --limit=50 To view oldest reports first: dmarc_view_reports --sort=oldest To display GeoIP lookup data for the source ip: dmarc_view_reports --geoip By default; city, country_code & continent_code are shown. You can optionally pass a comma delimited string to --geoip= with any of the following fields: country_code country_code3 country_name region region_name city postal_code latitude longitude time_zone area_code continent_code metro_code dmarc_view_reports --geoip=country_name,continent_code dmarc_view_reports --geoip=continent_code,country_name # keep order dmarc_view_reports --geoip=city,city,city # repeat =head1 SAMPLE OUTPUT ID Recipient From/Sender Report-Start | -- Qty Source IP Disposition DKIM SPF 570 theartfarm.com simerson.net 2013-05-20 09:40:50 | -- 1 75.126.200.152 quarantine fail fail 568 yeah.net tnpi.net 2013-05-21 09:00:00 | -- 1 111.176.77.138 reject fail fail 567 126.com tnpi.net 2013-05-21 09:00:00 | -- 1 49.73.135.125 reject fail fail 565 google.com mesick.us 2013-05-20 17:00:00 | -- 88 208.75.177.101 none pass pass 564 google.com theartfarm.com 2013-05-20 17:00:00 | -- 3 208.75.177.101 none pass pass 563 google.com lynboyer.com 2013-05-20 17:00:00 | -- 1 2a00:1450:4010:c03::235 none pass fail forwarded | -- 12 208.75.177.101 none pass pass | -- 1 209.85.217.174 none pass fail forwarded 561 google.com simerson.net 2013-05-20 17:00:00 | -- 1 208.75.177.101 none pass pass 560 google.com tnpi.net 2013-05-20 17:00:00 | -- 1 208.75.177.101 none pass pass | -- 1 27.20.110.240 reject fail fail 559 hotmail.com lynboyer.com 2013-05-20 20:00:00 | -- 6 208.75.177.101 none pass pass =head1 AUTHORS =over 4 =item * Matt Simerson =item * Davide Migliavacca =item * Marc Bradshaw =back =cut Mail-DMARC-1.20260306/bin/install_deps.pl000555000765000024 3355515152630466 17045 0ustar00mattstaff000000000000#!/usr/bin/perl # VERSION 1.12 use strict; use warnings; use CPAN; use Data::Dumper; use English qw( -no_match_vars ); my $apps = [ # { app => 'mysql-server-8', info => { port => 'mysql82-server', dport=>'mysql82', yum =>'mysql-server'} }, # { app => 'apache24' , info => { port => 'apache24', dport=>'', yum => 'httpd' } }, ]; $EUID == 0 or die "You will have better luck if you run me as root.\n"; ## no critic (Carp) my @failed; foreach ( @$apps ) { my $name = $_->{app} or die 'missing app name'; ## no critic (Carp) install_app( $name, $_->{info} ); }; foreach ( get_perl_modules() ) { my $module = $_->{module} or die 'missing module name'; ## no critic (Carp) next if $module eq 'perl'; my $info = $_->{info}; my $version = $info->{version} || ''; print "checking for $module $version\n"; eval "use $module $version"; ## no critic (Eval) next if ! $EVAL_ERROR; next if $info->{ships_with} && $info->{ships_with} eq 'perl'; install_module( $module, $info, $version ); eval "use $module $version"; ## no critic (Eval) if ($EVAL_ERROR) { push @failed, $module; } } if ( scalar @failed > 0 ) { print "The following modules failed installation:\n"; print join( "\n", @failed ); print "\n"; } exit; sub get_perl_modules { if ( -f 'dist.ini' ) { return get_perl_modules_from_ini(); }; if ( -f 'Makefile.PL' ) { return get_perl_modules_from_Makefile_PL(); }; die "unable to find module list. Run this script in the dist dir\n"; ## no critic (Carp) } sub get_perl_modules_from_Makefile_PL { my $fh = IO::File->new( 'Makefile.PL', 'r' ) or die "unable to read Makefile.PL\n"; ## no critic (Carp) my $depth = 0; my @modules; while ( my $line = <$fh> ) { chomp $line; if ( $line =~ /"(PREREQ_PM|prereqs)"\s*=>\s*{/ ) { $depth++; # print "$depth: $line (" . scalar @modules . ")\n"; next; } next if $depth < 1; if ($line =~ /(prereqs|configure|build|test|runtime|develop|requires|recommends|suggests).*{/){ $depth++; # print "$depth: $line (" . scalar @modules . ")\n"; next; } if ($line =~ /}/) { # print "$depth: $line (" . scalar @modules . ")\n"; $depth--; last if $depth == 0; next; }; if ($line !~ /=/) { # no = char means not a module print "$line\n"; next; } my ($mod, $ver) = split /\s*=\s*/, $line; $mod =~ s/[\s'"\#]*//xg; # strip whitespace & quotes ## no critic (Regex) next if ! $mod; push @modules, name_overrides($mod); # print "module: .$mod.\n"; } $fh->close; return @modules; } sub get_perl_modules_from_ini { my $fh = IO::File->new( 'dist.ini', 'r' ) or die "unable to read dist.ini\n"; ## no critic (Carp) my $in = 0; my @modules; while ( my $line = <$fh> ) { # install all prepreqs if ( '[Prereqs' eq substr($line,0,8) ) { # except for ones needed only by devs next if $line =~ /(?:BuildRequires|TestRequires)/i; $in++; next; }; next if ! $in; # print "line: $line\n"; next if ';' eq substr($line,0,1); # comment last if '[' eq substr($line,0,1); # [...] starts a new section my ($mod,$ver) = split /\s*=\s*/, $line; $mod =~ s/\s*//g; # remove whitespace next if ! $mod || ! defined $ver; push @modules, name_overrides($mod); print "module: $mod\n"; } $fh->close; # print Dumper(\@modules); return @modules; } sub install_app { my ( $app, $info ) = @_; if ( lc($OSNAME) eq 'darwin' ) { install_app_darwin( $app, $info ); } elsif ( lc($OSNAME) eq 'freebsd' ) { install_app_freebsd( $app, $info ); } elsif ( lc($OSNAME) eq 'linux' ) { install_app_linux( $app, $info ); }; return; } sub install_app_darwin { my ($app, $info ) = @_; my $port = $info->{dport} || $info->{port} || $app; if ( ! -x '/opt/local/bin/port' ) { print "MacPorts is not installed! Consider installing it.\n"; return; } system "/opt/local/bin/port install $port" and warn "install failed for Darwin port $port"; ## no critic (Carp) return; } sub install_app_freebsd { my ( $app, $info ) = @_; if ( -x '/usr/sbin/pkg' ) { if ( `/usr/sbin/pkg info -x $app` ) { ## no critic (Backtick) return print "$app is installed.\n"; } print "installing $app"; return if install_app_freebsd_pkg($info, $app); } print " from ports..."; if ( -x '/usr/sbin/pkg_info' ) { if ( `/usr/sbin/pkg_info | /usr/bin/grep $app` ) { ## no critic (Backtick) return print "$app is installed.\n"; }; } print "installing $app"; return install_app_freebsd_port($app, $info); } sub install_app_freebsd_port { my ( $app, $info ) = @_; my $name = $info->{port} || $app; my $category = $info->{category} || '*'; my ($portdir) = glob "/usr/ports/$category/$name"; ## no critic (Backtick) if ( $portdir && -d $portdir ) { print " from ports ($portdir)\n"; system "make -C $portdir install clean" and do { warn "'make install clean' failed for port $app\n"; ## no critic (Carp) }; }; return; } sub install_app_freebsd_pkg { my ( $info, $app ) = @_; my $pkg = get_freebsd_pkgng() or return; my $name = $info->{port} || $app; print "installing $name\n"; system "$pkg install -y $name"; return 1 if is_freebsd_port_installed($name); return 0 if ($app eq $name); system "$pkg install -y $app"; return 1 if is_freebsd_port_installed($app); return 0; } sub install_app_linux { my ($app, $info ) = @_; if ( -x '/usr/bin/yum' ) { my $rpm = $info->{yum} || $app; system "/usr/bin/yum -y install $rpm"; } elsif ( -x '/usr/bin/apt-get' ) { my $package = lc($info->{apt} || $app); system "/usr/bin/apt-get -y install $package"; } else { warn "no Linux package manager detected\n"; ## no critic (Carp) }; return; } sub install_module { my ($module, $info, $version) = @_; if ( lc($OSNAME) eq 'darwin' ) { install_module_darwin($module, $info, $version); } elsif ( lc($OSNAME) eq 'freebsd' ) { install_module_freebsd($module, $info, $version); } elsif ( lc($OSNAME) eq 'linux' ) { install_module_linux( $module, $info, $version); }; eval "require $module" or print ''; ## no critic (Stringy) return 1 if ! $EVAL_ERROR; install_module_cpan($module, $version); return; } sub install_module_cpan { my ($module, $version) = @_; print " from CPAN..."; sleep 1; # this causes problems when CPAN is not configured. #local $ENV{PERL_MM_USE_DEFAULT} = 1; # supress CPAN prompts local $ENV{FTP_PASSIVE} = 1; # for FTP behind NAT/firewalls # some Linux distros break CPAN by auto/preconfiguring it with no URL mirrors. # this works around that annoying little habit $CPAN::Config = get_cpan_config(); ## no critic (PackageVars) # a hack to grab the latest version on CPAN before its hits the mirrors if ( $module eq 'Provision::Unix' && $version ) { $module =~ s/\:\:/\-/g; $module = "M/MS/MSIMERSON/$module-$version.tar.gz"; } CPAN::Shell->install($module); ## no critic (PackageVars) return; } sub install_module_darwin { my ($module, $info, $version) = @_; my $dport = '/opt/local/bin/port'; if ( ! -x $dport ) { print "MacPorts is not installed! Consider installing it.\n"; return; } my $port = "p5-$module"; $port =~ s/::/-/g; system "$dport install $port" and warn "install failed for Darwin port $module"; ## no critic (Carp) return; } sub install_module_freebsd { my ($module, $info, $version) = @_; my $name = $info->{port} || $module; my $portname = substr($name, 0, 3) eq 'p5-' ? $name : "p5-$name"; $portname =~ s/::/-/g; if (is_freebsd_port_installed($portname)) { return print "$module is installed.\n"; }; return 1 if install_module_freebsd_pkg($portname); return install_module_freebsd_port($portname, $info, $module); } sub install_module_freebsd_port { my ($portname, $info, $module) = @_; print " from ports...$portname..."; if (is_freebsd_port_installed($module, $portname)) { return print "$module is installed.\n"; } print "installing $module ..."; my $category = $info->{category} || '*'; my ($portdir) = glob "/usr/ports/$category/$portname"; if ( ! $portdir || ! -d $portdir ) { print "no match at /usr/ports/$category/$portname\n"; return; }; print " from ports ($portdir)\n"; system "make -C $portdir install clean" and warn "'make install clean' failed for port $module\n"; ## no critic (Carp) return; } sub install_module_freebsd_pkg { my ( $module ) = @_; my $pkg = get_freebsd_pkgng() or return 0; print "installing $module\n"; system "$pkg install -y $module"; return is_freebsd_port_installed($module); } sub is_freebsd_port_installed { my ( $module, $portname ) = @_; my $pkg = get_freebsd_pkgng(); if ($pkg) { return 1 if `$pkg info -x $module`; ## no critic (Backtick) } my $pkg_info = get_freebsd_pkgng(); if ($pkg_info) { $portname ||= $module; if ( `$pkg_info | /usr/bin/grep $portname` ) { ## no critic (Backtick) return print "$module is installed.\n"; } } return 0; } sub get_freebsd_pkgng { my $pkg = '/usr/local/sbin/pkg'; # port version is likely newest if (! -x $pkg) { $pkg = '/usr/sbin/pkg'; }; # fall back if (! -x $pkg) { warn "pkg not installed!\n"; return 0; } return $pkg; } sub install_module_linux { my ($module, $info, $version) = @_; my $package; if ( -x '/usr/bin/yum' ) { ## no critic (Backtick) return install_module_linux_yum($module, $info); } elsif ( -x '/usr/bin/apt-get' ) { ## no critic (Backtick) return install_module_linux_apt($module, $info); } warn "no Linux package manager detected\n"; ## no critic (Carp) return; } sub install_module_linux_yum { my ($module, $info) = @_; my $package; if ( $info->{yum} ) { $package = $info->{yum}; } else { $package = "perl-$module"; $package =~ s/::/-/g; }; system "/usr/bin/yum -y install $package"; return; } sub install_module_linux_apt { my ($module, $info) = @_; my $package; if ( $info->{apt} ) { $package = $info->{apt}; } else { $package = 'lib' . lc $module . '-perl'; $package =~ s/::/-/g; }; system "/usr/bin/apt-get -y install $package"; return; } sub get_cpan_config { my $ftp = `which ftp`; chomp $ftp; ## no critic (Backtick) my $gzip = `which gzip`; chomp $gzip; ## no critic (Backtick) my $unzip = `which unzip`; chomp $unzip; ## no critic (Backtick) my $tar = `which tar`; chomp $tar; ## no critic (Backtick) my $make = `which make`; chomp $make; ## no critic (Backtick) my $wget = `which wget`; chomp $wget; ## no critic (Backtick) return { 'build_cache' => q[10], 'build_dir' => qq[$ENV{HOME}/.cpan/build], 'cache_metadata' => q[1], 'cpan_home' => qq[$ENV{HOME}/.cpan], 'ftp' => $ftp, 'ftp_proxy' => q[], 'getcwd' => q[cwd], 'gpg' => q[], 'gzip' => $gzip, 'histfile' => qq[$ENV{HOME}/.cpan/histfile], 'histsize' => q[100], 'http_proxy' => q[], 'inactivity_timeout' => q[5], 'index_expire' => q[1], 'inhibit_startup_message' => q[1], 'keep_source_where' => qq[$ENV{HOME}/.cpan/sources], 'lynx' => q[], 'make' => $make, 'make_arg' => q[], 'make_install_arg' => q[], 'makepl_arg' => q[], 'ncftp' => q[], 'ncftpget' => q[], 'no_proxy' => q[], 'pager' => q[less], 'prerequisites_policy' => q[follow], 'scan_cache' => q[atstart], 'shell' => q[/bin/csh], 'tar' => $tar, 'term_is_latin' => q[1], 'unzip' => $unzip, 'urllist' => [ 'http://www.perl.com/CPAN/', 'http://mirrors.kernel.org/pub/CPAN/', 'ftp://cpan.cs.utah.edu/pub/CPAN/', 'ftp://mirrors.kernel.org/pub/CPAN', 'ftp://osl.uoregon.edu/CPAN/', 'http://cpan.yahoo.com/', 'ftp://ftp.funet.fi/pub/languages/perl/CPAN/' ], 'wget' => $wget, }; } sub name_overrides { my $mod = shift; # Package and port managers have naming conventions for perl modules. The # methods will typically work out the name based on the module name and a # couple rules. When that doesn't work, add entries here for FreeBSD (port), # MacPorts ($dport), yum, and apt. my @modules = ( { module=>'LWP::UserAgent' , info => { cat=>'www', port=>'p5-libwww', dport=>'p5-libwww-perl', yum=>'perl-libwww-perl' }, }, { module=>'Mail::Send' , info => { port => 'Mail::Tools', } }, { module=>'Date::Parse' , info => { port => 'TimeDate', } }, { module=>'LWP' , info => { port => 'p5-libwww', } }, { module=>'Net::DNS::Resolver', info => { apt => 'libnet-dns-perl', } }, { module=>'DBD::SQLite' , info => { apt => 'libdbd-sqlite3-perl', } }, ); my ($match) = grep { $_->{module} eq $mod } @modules; return $match if $match; return { module=>$mod, info => { } }; } __END__ =pod =head1 NAME install_deps.pl: install dependencies with package manager or CPAN =head1 AUTHORS =over 4 =item * Matt Simerson =back =cut Mail-DMARC-1.20260306/example000755000765000024 015152630466 14517 5ustar00mattstaff000000000000Mail-DMARC-1.20260306/example/report_cgi.png000444000765000024 134023715152630466 17611 0ustar00mattstaff000000000000‰PNG  IHDR–Ìî´# iCCPICC ProfileH ­Ww\SÉž[’@HB D@JèM”"]z   l„$$¡Ä*ö²¨àÚElÈRDÁµ²Ä®,‚½o,¨(ëbÁ†Ê›KQ÷íÛÿÞÍoæ~ùæ›sΜ™;¿\©4U S’#‹ öc'$&±)÷¨ð§̸¼l©odd8ø×çÝu€Wl [ÿ*ûß ê|A6$6§ð³y™kâIe9{¦³r¤^ ±¦ q…C¸‰À)C¸mPå5 ”h\®L½òì\žÚaÐ ¶“ðň'@ìÅqùσxLfæLWCl™òƒá˜ËMùf“Ë~ÃCc=¡ãq¶4ƒ;gðÏÿ³ÊÌÃ| >°¦e§G‡Á7 æm6 ±6Ä«ENø0_)Íñ‹æˆs81kBÍU‘<$v?“§ÇúB¬ùÏé3Ã=̪-I™±Ħ¼l˜{Âêœ'ЉÖ„óÃU„&ÈfFèEÙ¹Ñ#|^žÈÒˆ>JÌ7ê ¸2ˆãA‹Á„_cÈï‘æDq¾Ú%“†Ç‚>N•‚ÿ$È/›(Gy3¦–#‹!4pŒ˜^ª8ˆ1Œ ³ÉBFxiÆàš†}±™<ŠÈƒ)Ä©I,‘C‚/àsˆÜœ`e p @ €nÀáÀ ×lÈK Ç3A,2¶êH é ©“ôt¤ Ýá`Ïa>ÄC¶~èùhþ„V {Ä®‹{áx8¬}`qÀ]q·‘¶öžÆž<«öµ¶í7}.´øeD7C¼D6‚‡û¤|ëñϘ‚Àc˜áˆÂ®Ö®ÛîóHÿï#&’È!ä ²¶;€ÅN`ç±#X#`cDZ&¬ ;Jàá¸F¼p!Cd…Èp6ƒYùà?Ɉ¿¿eIþM1laÍpQ°—¤Ã6ñ7qƒQ‹ÿaE)ÐcÔ†}›á¸ps˜]'Ü÷„y†9ÆY¸.°ÅÇÃŒûâÞpœ û}ÿ>[:˜íÜÁ±¤ƒ'p™9‚Ù9p-ÿ™Ò92±P”Ãö…»¥` ›#áÃv°³wÄÞKhxÃÜSÖ…ï\V nðû$¶=6¡€kÀá'0ß}çL^ÃÏî•G;xrYî'^$¸£«Â¯B` 3âœð D€¦Ã5,™0âY`X òA!X 6°ìÕ`/ØÁpœA¸îè/@/xú¡ t„‰è †ˆbƒ8 ®ˆˆ„#QH"’Œ "Gæ!K‘Bd=R‚ìDj_‘ÃÈ ä<Ò‰ÜB ÝÈk䊡4TÕGÍÑq¨+ꋆ¡1è4Tˆf¡yè2t5ZŒ–£{Ðôz½†*Ðh0Œ…a¶˜+æE`IX*&Ã`XVŽÕaÍp-^ÁXö'ãLœÛ™ Ácqž…/ÀWá%x5Þ€ŸÂ¯àð^ü+‰NÒ#ÙÜIRIHšEÊ'‘*I‡H§á÷ÜEzG&“Yd ² \í‰ä4ò\ò*òVr=¹…ÜI~Dî£P(:Š'%‚Â¥äPò)[({(Ç)—)]”J*J†JJAJIJ¥%JEJ»•Ž)]VzªÔ¯¬¦l¦ì®¡ÌWž£¼F¹B¹Yù’r—r?UjAõ¤ÆPÓ¨‹©ÅÔ:êiê]êc7•É*b•E*Å*ûTΩýƒÉËà0øŒ…ŒRFã2㥪²ª™ª¯êtÕ<Õ"Õª—T{Ô”ÕÌÕüÕ¸j ÔJÕ«ÝPëSgªÛ«G¨gª¯Rß­~^ý™EÃ\#Pƒ¯±Lc—ÆIGLŒiÂôgò˜K™ÌÓÌ.M²¦…&G3M³Ps¯f»f¯–†Öx­8­ÙZ¥ZGµ,ŒeÎâ°2XkXûY×YŸFéò%µrTݨˣÞkÖöÑhh×k_Óþ¤ÃÖ ÔI×Y§Ó¨sO×µÖ¬;Kw›îiݞњ£=FóFŒÞ?ú¶ªg­¥7Wo—^›^Ÿ¾~°¾T‹þIý–AšÁFƒc݆LC/C±áFÃã†ÏÙZl_v»˜}ŠÝk¤gb$7ÚiÔnÔolak¼Ä¸Þøž ÕÄÕ$Õd£I«I¯©¡éDÓy¦µ¦·Í”Í\ÍDf›ÍΚ½7·07_nÞhþÌBÛ‚c‘gQkq×’ném™eYnyÕŠlåj•nµÕªÃµv²Y—Z_²AmœmÄ6[m:ÇÆ¸‘Œ)sÖfëk›k[kû`,kløØ%cǾg:.iܺqgÇ}µs²Ë°«°»c¯aj¿Ä¾ÙþµƒµÏ¡Ôáª#Ý1Èq¡c“ã«ñ6ãã·¿éÄtšè´Ü©Õ鋳‹³Ì¹Î¹ÛÅÔ%Ù¥Ì冫¦k¤ë*×sn$7?·…nGÜ>º;»ç¸ïwÿËÃÖ#Ýc·Ç³ *&<ò4öäzîôTx±½’½vx)¼¼¹ÞåÞ}L|ø>•>O}­|Ó|÷ø¾ô³ó“ùò{ïïî?ß¿% (hÔŒ , ¼d$ ª ê v žÜB Yrƒ£Ïáqj8½¡.¡óCO…Ñ¢ÃJ†[‡Ë›'¢C'n˜xw’Ù$ɤÆÁ‰Øq/Ò"2+ò·ÉäÉ‘“K'?‰²šu6š=#zwô»¿˜51wb-cå±­qªqSãjâÞÇįW$ŒK˜Ÿp1Q7QœØ”DIŠKªLê›8eÓ”®©NSó§^Ÿf1mö´óÓu§gL?:CuwÆdRr|òîäÏÜn9·/…“R–ÒËóçmæ½àûð7ò»ž‚õ‚§©ž©ëSŸ =…„Ý"oQ‘¨Gì/.¿J IÛžö>="½*} #>£>S)39ó°DC’.95Ó`æì™Ri¾T‘åžµ)«W&«ÌF²§e7åhÂCn›ÜRþ“üA®Wniî‡Yq³ÌVŸ-™Ý6ÇzÎÊ9Oó‚ò~™‹ÏåÍmg4oñ¼ó}çï\€,HYкÐdá²…]‹‚U/¦.N_üû»%ë—¼]¿´y™þ²EËýüSm>#_–c¹Çòí+ðâí+WnYùµ€_p¡Ð®°¨ðó*Þª ?Ûÿ\üóÀêÔÕíkœ×l[K^+Y{}÷ºêõêëóÖ?Ú0qCÃFöÆ‚o7ÍØt¾h|ÑöÍÔÍòÍŠâðâ¦-¦[Önù\"*¹VêWZ_¦W¶²ìýVþÖËÛ|¶Õm×ß^¸ýÓñŽ›;ƒw6”›—í"ïÊÝõ¤"®âì/®¿ÔTêVV~©’T)ª£ªOÕ¸ÔÔìÖÛ½¦­•×v§coÀÞ¦:Ûºõ¬úÂ}`Ÿ|ßó_“½¾?lë×uÍ–b*h@æ4ô6ŠM‰M‡C·6{4úmìoUGŒŽ”Õ:ºæõزcÇóŽ÷µH[zNO12\ú¿ðÐý‰h€gPå@ì"Â[Ø‹Ä4ø&Žù1>utüV C<Ù©Žƒ¡ÉàÑäÃÀÀ}(Í|‘ ôoøRÏÝ·hɺ“j2<ÇïP%ÐùöU‹ˆ÷Ïþ`b±™O pHYs%%IR$ðŸiTXtXML:com.adobe.xmp 1686 1228 £ÌÔL@IDATxìÝ|ÕÚð'¤7RH€$$‘^¤…&Ò¤(Eª ØED± ^¼bÃO®*¢ØPŠ( D   HG H A$! )»!ß93;»³›dÓh>sagÏœ6ÿÝõλç·yóž¾tðàqÌxc¸Q€ (@ P€ (@ P€ (@ PÀH ’ѦS€ (@ P€ (@ P€ (@ P@/ÀÀ’^ƒû (@ P€ (@ P€ (@ P€† ,Òð(@ P€ (@ P€ (@ P€ €^€%½÷)@ P€ (@ P€ (@ P€  X2¤á P€ (@ P€ (@ P€ (@½Kz îS€ (@ P€ (@ P€ (@  0°dHà(@ P€ (@ P€ (@ P€z–ôܧ(@ P€ (@ P€ (@ P€0``Ɇ(@ P€ (@ P€ (@ P€ ô ,é5¸O P€ (@ P€ (@ P€ (`(ÀÀ’! P€ (@ P€ (@ P€ (@ èXÒkpŸ (@ P€ (@ P€ (@ PÀP€%C (@ P€ (@ P€ (@ P€Ð 0°¤×à>(@ P€ (@ P€ (@ P€ €¡K†4<@ P€ (@ P€ (@ P€ ( ``I¯Á} P€ (@ P€ (@ P€ (@C– ix€ (@ P€ (@ P€ (@ P@/ÀÀ’^ƒû (@ P€ (@ P€ (@ P€† ,Òð(@ P€ (@ P€ (@ P€ €^€%½÷)@ P€ (@ P€ (@ P€  X2¤á P€ (@ P€ (@ P€ (@½Kz îS€ (@ P€ (@ P€ (@  \‘ÀRÌHO>¬ü‚ÂËÏFÒ‰t‘ƒ[Y̹y0ççr¤kYTËV¶È÷}Ùªfi \yüL¤¦å¸Ôœ¬T¤æº”µ\3•ûuñ_ú}•+¾_rsó­¯MA~žuŸ; (@ P€ (@ P€׿€‡vŠ«Ÿ˜ƒ/öz"2ÂÈ4¡ê î˜4´–v¸ðcnæŒø'D~±¥îOGÓ©C0¾OõÂyRŽ/_†'=܇Ï?m¯3Ž$lFü7G°+>Ùh‚yI=ä$îäP•ÃÓl¬~â|qLœ‡¥_ò\R3L"Ÿ'B‡¢ÁM5ФM4© ëÉ‹•rxþIË`Ò¢Úø|Y{x;žWþY|8d~CB,§$ú“!ö=Q­~U4l[mn«jÞnçl{Z`NÇÆEëñõ;‡‘tÊ–Ú6· ¿Y‹¶O݇û[kØò¹WNý+²ká [V?>+ÄûËö:]Dj­›1ëÍ6Ö×5÷ȯ˜8ôw„4ôge©äʘ?¾«ìß÷…ÞWÌÀÙçæ"NeTÃÔøˆõ1aísóñùv¨×¥Ÿâ¼öû£s—<ì> øˆ´ñž•›öÙçž“)Äs± Ðáç“®ço›½Ë }ž_Ëç¢e¯›Ð±C”Õ^éÿ¹l2Xzè§o¿& ¦Ï^ß‚ÝO¶uÞ¾[*6.]‚ïVcú¼x‘õ<žjâ‰Ç[–÷_è8L›r¢d SœwÇ)w¡úO¿`ÚXq—YnÝš`ÚŠ›ñû„O‘´U|‚Dð²køçžÅ’éG-yê`d¿$n=„-ñFY¨˜R‚ü¹xrÉP„/°õ+v|k ªü¹öÖ[> S÷Aã`µYþ{ùÜÄ•ÚSü¶ uÿVìÍöóñ*¢q3²RŽa«*ɭȬEÔR’Cv],—ï«’œ‰AÞ]Ïœ}Î[cêܨ%ƒJrŸõ6ãÂ7æ'¼1Y|Ž#£ñØç·áæZ^È=ô ÆõØ"2ù¡ÏÜnh_ØõùÏX2y§Rôï#™"°TÔŠþT*á? (@ P€ (@ P€ׄ€u*~ ډѽÞyøá5TZÌŒ{úÔEl½ºøòxoI%ÝÓ«èh}q߃J%ü‡ (@ P€ (@ Pàš°–doÝt ðøF{ýINnÖ¦oÛŽm*Q.ªs »Åž¹{ê·n€Øív±Z"×,¦Ë*§ÍÇRÉd¿öCPLc<óÃtW‚KÀú1‹°!Y]+¢BÎ_ÜüÛðú‹nÙ¥ì9[°3ËùIšõç¯{-<"ã¡,¡}'p"Çö¢ÈÙ¸– £ñÚ¼.¨æ8ÒKŽ8yö.t¯©2"ÌyóŦ–¦ÅVz3$.þŸˆ‘F!AEªp¡CÁ pßx9Íð\ò 6[Þ?ú’Ǿÿ]ŒV €º©! Þ÷úrWzßès£ôËl[S¥zí¸å#kŸ'îìWËÖm]S¶í³y[+ŒËFÖ’å7É÷rhÄ[WÙôŸgÿzmðØ$õuÀšÃ8êÚò>¶¾rïŠD÷ÓšC*h»×Åòü¾* CY®gE~ÎEgÜàñ¡‹­¯~ïTBX]uÿŸdû_~Tép+FŠÙ¿ß”l|%ø4®„G(@ P€ (@ P€ ®m@‚ÒŸäCÞ› më‡ó[ÅÔU8Š?ÇøÎÚø ™-kÿOLzÔ­:ão¬_ë,”Ë7àË÷âTª˜&«fu zåvt«g™&'7·ìÀêÍÞxð¹Öð/°Jd Ž[˜9í7xwi‡ ÷ÔµŽ¢0Jw,_øy(„®òØ&|½ì:=#&ß+¯ó·µXpv?Ä cbê Žø{ìFì /E{ÍïÑÝŒ·e7Ü˾ 2Á,ƒNÞêó »¶bå>u?öÕˆõpné&‚}_ŽÆ¾?µz#?£t[ÉÂ{FýÓrf9€eÿŽçÅ$„5ÂÑuh{´ŠÁ ±^É™CGðãç{~w7ÔNþ_}yéâíÝ¥ î½·¾ÝûÜ–„5 ~ÆßÄËϱmcÑk`KD©„”æÒ“áçO~ƒßШóׯ˜¿èÜ+àåç”ãßÏZ 4 @“¡Ñ8̽TÍG·†ïœõâÓ`¢E¢Ó ´S甎5oŠÑ~£º¡±®_(â}oä³ó³ï°å,Äm^ OœrÜípzÑñÉôµ¤e Z¯Û0 }eüöY¶‹¼È @ÿ':!,©|?7úÀ«É”·‚Ü}èA¸ëÏѪ`¿ãæƒY‡F‹Äüäkñ>/ȵ´ìk×–Ê2°$¯UbMÝçÂ1_©žçÇÒÙoâÝÕ rT[tíP Í{BÇhå}›,¦ŸŒŸ¿‘÷>Žº§Vaîk‘"ºR¯ÛC˜4ªt×5sÚA|óùWøfÛ!ñ¾ CÓv]0tP?ÔÔìÜrp*q­@è½/ ËÅõb”×rõuè3cûª£B”ó(¢_Úy۞Șš¼«?Z„€áO¡Ñá%x}Á&D÷~S†µ@ΑøøÃϱM|d¢càð»Ñ1ƶ’9e>|óm,Yu•ÛöÂÿÒšvùÑ+ïl]ö1¾HØ+^Á*è|÷ýÞAŒ™[—~ƒy^Ê{yàU¿µ‰„9y+>Œ?ˆÊ>9ðŠíAj:m¯,×EY¡+×§ [].ŸvñbA£ŸtDe4êÒ}‡ÜdYKÏø{ôàK0u²¸ÆˆÍñz&ÓŒ®'ò˜«›úÍnùÑ…ø|Û¡N}›ôârL€ÉCcÔïbñÃ…[žCVšñ\”åõ=èjß™ (@ P€ (@ P bìF,ɦ䈖[&uBœ¥Ýõ¯mGº.Va>²K¶w>Öµýœ•âG½+ÖjÚƒè wàÿ¾èŽŽŸÀ]çbõ‰llxu©#·aËÏ™"¬ «ÜÒ¦ãÃá¯7`ÇÚlYxTܲ·mFé¶Æ{ÞõZàNñ+k¹%}+êµt£ìç¯Ö©ý»ë‹Íb·nïÓ½F©¿ÐO|v+Žß+ù=á¡ý¤\<Ë:ô+Þši9ó¶õPG·ŒÅ‰MÇ-Mù¡oï(˾ó‡j݇`¦ i›‘ŸQºV®$ý“e’V`t§U؉´÷wÌÙƒ7:ÍÅÌðz·0¡k<¾þô¨xÌÃñ¾ØŸ‚Dñz¯vF?¾Í:ÅÙ¹]0¼ñb|2=q£Ú ®Æ$<»“êÍBü>1½]þi̬1´ú æˆúDOŽÙ‰½¢®?¾·Mç{1Çö§áB¶ú"¯Qº<'Ȧjyq~æ¯Ø«…–'¡rDßaõdVq£\ŒZ+â}oè³ò,"ë`ýÌýHëýj¢nhšv ǯ–´!±hÛ(@|Š<ss’wýIoûÀ¨ÿFéjgÕ== ê*ð)<Õ•·¿¯5Ы/ïlßÛ_¬mUÂü…ëÑõÁí,VÏS×$CdMˆ8eùm¢îÙ­kaðÓÀ´â…;ü0qÜ8l9•‚üDLªä‰¨q7}:ú7¨Š]GcÖ¼…X¸p!¦Žî„ÀÇ–!ÇM²òìÎOáÚƒ'Bï1¡wôQ<=º?j6Å¢½"Z()‹Fú"êÆ8Œž*êëÓ zaê¬yX8oÆõoŠÿÛ$#†b+¢_j ¸ödÿ§TrChTSŒí‰µñnì5ódß§¯Å^Bà°-ÐíF`ÖÔ‰è$òLùV½ÖdZŠU›Šs÷ÃÓŸÎÆ¸§0zâ<­y—ÇÅ݈¸Á…Û<Ì›7#:݈‘ïï‘D„œÁè#0Bþ½yõjVVêõÃh6ƈÑãéhØVY®‹Å^g [U¸Z>k߯¸·ñ,HðÁà×»¡C•sâz¶:®Æ?nÙ(ê{ôL’í»×ñzVÔõ¤˜®qØÝ'Õ±ß1y9†Z†íâ;]nAÍÚc˜ÝP¬Y•Ò}Ú×Ág (@ P€ (@ P€W@¡À’Òµ°X x5Líå¾=X±ÓvS~ÛÇEzônŠ‹gœœH~&Nî—éµÑ¿o-T‹i€a¨umÿå<Ú==o[Öd¹<Äoÿ‹Û":ª7èC#@‡2J/®>í¸õÖ¹¸?iײœ¿V¹|ÌM—Ó/"vFKñ{| é˜––£'°j£ºc¸¥`ÓŠ]XûÅ:Ì?O¬Ÿ´Q øÉ…Ô§Ìmo7í ‡·m:)_û™ k×ù¥kå×û‡ä]˜4æ0φ™/wÅÀ'FâÙÑJU[þƒmÓ¢mC¼vh¾<6L R›[²+f£ ëO¼Üg›H ÔC£Ð¯sô{ö<¦LIg‚KqÐ\ã÷CwKÀPæ}rÝÜ9$ ½ƒ-é·°û‹ßľÑ×Èò‚ˆ¼†ïû¢|Æþ€Ìñˆ% %Fçø{{!ªu'1œê“ D«çªc{dZe”—QÿÒ­' v¾~|¦?±ÓÆkKðÒ}«¨ÏtöóÒD0ZŒüJÚwÞ;_zÔNtþ¿V*þRâr rÎa¯˜‰ú‰‘:‘h1ð?øýõ&xzM"ÜÜcñ–) ¯w¶T×ïuÈ0á’égµØ¥UiÝ_žœŒ¹ÿkcT1J·+\Ôƒe:]{Ik6‰ña¸w°*éÛ #»©G‚éŠ)» ®Å“wbK¼:RéÎå÷bѶ!h.¦ns¾]Ĺì’Ý44ò3J×·ëjÿ®Ü¥ÛûÉOj â‰%xëÑ–ªN#)#m©A’>ÏߊXq~b-¢ŽOˆ5¡©Ù6­IÆ¡e›!C7¡“Ú¡¹å³<ÚnbOËû4߬9+žÂ­ýÔ@f‹¹·£U½ ûß(L}¤Ž§núuzdŠÑù¥[ª_ãècécâ³›pL|&Ÿ„åsLÖ`¢–×è}_¬OšÚÜÝ\©&iúvëH·˜Žê`r´ÔAËî]‹~ÚÆ¡M¸ÚªQÿÒµ¾*¨,"•¡ÚŸýlAL»¼—ñIÂÈù.Fj1ò-¬¸Ý2 Í=݆¨ÑY/ŒG}p Aϧ>´œ¾Nø{–¾1&:¿þÚêÞ·]&ýjé…ø(AŒ£t¢j©×‰~lžrø•HërÏýÊÉTV'…#ÓŠî—«íù×G¿;G*uO\ñ*:Šœcg.À„pM§=ïM¼|Nz ž¥¤‰TlY4Wü«žO ù†W·Æ½zi».?~õªp €‡,]²(%÷àû-êȨ¶£ÿ%¬? öX†žÝŒ …Ã[¹ØNÉ®‹®^gŒwµ|âו m÷©m•ÈúÜÂâÉW"nRkÄ„ý=ê&¦¦Ó¾õ×3W®'F}w%½þÐødË툳\÷d™½b”Ûè HR€ª¦,߃…*c(@ P€ (@ P€ ÀU!`áɃ›w] £AÞ˜#‚Bk¶àÇSmÑðç_q^޹]ܸ/k\8=…P ›3C³NãÛWæ‹)ÉÄÏϯÖ-ÓÒ± ±¦†¸ekÛÊrþj-ruo«”ù/,CXÆÛ×»ÄÍpe#ÁÖîí„Ú¨K²ú†iÇFÏÃÔÕÀÒî?R1¬µ%b`—×dy†ê¾ús°ËTÎO\í_6öý¢¾þq#êãf±T—r3ôÖzðož¼<Ô ,@*´€…íΤ\ªÃ 0$ìSˋɕsð­ìð–õ@kñËý¯ÅôŒÿ-^H„Ãd ´Ôª-nÎë6çïW]†îÊ5†nŸR+G%Å(´M™¸×ÿqÃØOöTƒEWéšWØM"ȶMXˆ6¶¦c|_¬Ó ª[ VÿœŽzÝ3ñÙLº/¿É.øZtûÆGï|ñ. kd/V g⿺¢£–ZÌŒq‘cêÐ1‚Ë(Ðjn9'¾Ç‹o~/eÒ†õ‰)¼"zâ…G{ÀG·’µ”O4zuâ×ÓGĉ¿~ødÃ{Õ!ÄšÅÚTlÚgP*G¯!#ðôzý›§x/È­reË€ºè%"Kñ"êôÇßò=®[+(OWŸã”„Åô«$í™rÔ@týÚâƒ)¶·Lü¾Ií÷3÷öÁ-ÚçµKOŒS>¯b*ÃÃj©W\¬R¦ôÿôCLUÝkç#Fø¡+ѼæQÖ ÿ÷Lôš¾ã^ÇýŸDZ5Ÿˆ&_Çm±bt^‘qtͰd×Å’\gœ»«å/äªSÈù‹é!­›ÙØêžÞPBfâÜŠûÕ•´TáÚõÄÚ^1;òª¬¯ôYý£à±ê ×ÊL« O¶îÁ¤§ª`ÑÿZÚMY¶ïA}«Ü§(@ P€ (@ P€¸šœŽXÒ:Øjt;h·a¿˜²oMNAÔ ë]tãàË0¤žX;âçej³×^­®UyÕ<ä&ã7Œ[h÷h§Óh•öüeyûþÀÊ}bt×ø†ˆõ£?ªøÀ[Ô då¦Jú=êêõDöW|½(›§§.¸gISDñô)[‚üü¬N°½æòµ©ß§7m¿µl“pÎ!ÚW¶ïA­b>R€ (@ P€ (@ \mE– "ãî!òwË@öZ1m™øõýðÁ1…ÏA7jÀ|äL|Tä©™ ý•©ÍL¹ú;ˆ…‹_î”ÎÙøÒ÷–‘žt× N»Pšó—)õ¿+ÖŠl‚'žë…ûŸíñ–¿ûŸˆ‡&©£ÿ 6ËÁ N6©.o>œ?Àzãný˜EX}Äþu;­­Sny~«¸±Wô–•e|#³è’öG]韜®)y‡œÑ„¯¿øÓ¾ñ,}×:Lÿì˜.Ýþ&gÆYVØê";Eý…Òg"°¢+·<ݩޤõ©l_^Ÿ­ÂöÅþ3,Ó­'°EÄî|¸‘ݯöÚ.‰Oäm­++ŠßˆqqEðª=&=×M}oÄoÁT1j*öÕ¶ˆ*r‡QOJžî‰Ëgí¦k«´ÁBÿæã‘‘ììlõOîo¯‚ÜD,ýþFÍü g¬†e©#,÷vd9R¯‘šbÚ…$e·mÝ0\LùGÙÿp-Ίéô¬›[íØ­< ¬l_ÞšÇÉNqý*S{¢OÇ[/Z݃÷ÄôŽ[êιx5á°’¿irtçãÇì%z.¯™úC)Ó¾umkYÏš}°P‰¿íA¯¨(ŒÛÓõR> Ö<ÎvJ{],ëuƵò¨ßWþ3á=Ë4³º“øgý:¬ú~}‰¿G]½žÈÏ“öjÞ£^;uÍ+»æ‹8$ö¼,Ÿ½Ü“á“1ß[§âÔò{D4Àm=ÆSgp*˨-ïA­>R€ (@ P€ (@ \]ö%wu„’åWÌòWÉnií±ï¨Nhåd$FÒæ“êL"gÒ®“jþH_u%ñ,û‚åñº”’)Ðà†ª6ÔZÌiIˆç‡9mIQŒÒõ7¢=§’c¶Ìûï|ª-b_½Ý¢-?S/‡óWz&Pÿ ˆ{¹üü²¾ùpm$˜ ‹æÛ.¶IÞL8ÁòÁÓëâ,çmÂ'¾ÄÞ,ƒ›]‹w{}¨ƒÂëõÄÌÝÇ0­‰šKL”i—=G?u]þA|þôzq¼wˆFí½Ô¼{žÆ*m1,%%§«ÓÞÕ½šÇÉ¿žZ@=X\¿JÒž§vêuX²»Ü=Qi(~bfÿ”híQæ‘ïqËÍãpCóºjšˆö|ºÃv!:sT†!J¸éùÝÎ`û*éñz5 ±U$F2õ{ú=ÛóFœí’aKwØ+íu±$×k“ºï+WËW´ŒËÓÌþ÷ƒÖï϶mÀ„‘;‘qÜr­,â{Ôö Ô®gî®]o}"×MíýÞ7Ab®.ài9©C_mÓÞ¡EõZæWçFñ†¼öú®B£lµ©GYri0ëVÊïAYþÔ¯ñ˜;?‰…‚¸ÖÚ¹C P€ (@ P€ (p¬%ùëâ#«w‰QIÀæÅûn¹çèÓÂ:ÛЇl7@ÍYçñ\ÒFnbœ“™j $¸†å.›<ÿxm ýºö°5@©—Ƕ7¤ÕíØžd›¿%ÍñÁ•ü‰[E8XÝN=_lŽm”깇—˜¢n:&ÍÝdiÏÞUdMÕlëÁÓ¾ˆ­É©ÈIKÄÜQ 0OäšøÕ›há°Â2Üiô]/â åFùÁ¥/bâz ó´ è!",b´PÒ1yõ.äØ.rûׯUÒâ¿Þ¤Žx*¦_®·—Š›ÿPêþzÕ6«itŸ±"´£n»Þˆ¦w<ˆï¾7öž¾Â “žÃ3–ããnn‡—æ/ÅÒù/¡VÿéJjüÄ›ÑôîÙ8n»÷!>°Œ´’冬{…¶ý³íW¼õÈF$jÃ;´â1vRG<òHDénÚö3pÍÿGø,pð‘•»Ö?sò¼Úöêú;©ž™ÜL¹ypž¸‘i¹9©ë2:ÏŒñjé’Ĩ+|gúi]šXÇê…žâæ~cxç$aZ¬²f#ˆÞØÒµÄKµoF÷Øf9©{‡ ±ýಃÃHkb§ e†4[‹ÇvMF;‡œ®oíãâµ3x磵Sà–‰¢æ+ÇâþfÚЀl,ný.Rß‹ñ­µ4µ„ëçeô¹©.®#Qß'«ÇÍÆ'bžý†©‡F)?äŠÏ°·¿†Èܺ<úÂ.åÏ6ø<[ú¥{/ë«.—ý¬èx3ìOyV˜‹žõTç=ïDÓq 57í«ÝøÏ@Ëð&qT¾n?Ì~½&Ê“m{à½u˜=öVqÃ>KôÅ`ÝáÎϬÀk7ÿˆ¸Á³lF,DÆÜúQL¿ŠkÏ;çòU`ÖÊ›LÃ_¿?X7˜“7b|ÏN˜'Y¶¯¯ÆÛOõT¦,HÛƒ—G5ÅT+N?<3ñ‚XÃê&¾þ8öꎸƑ† ³{—bÒ£Ó°p½®&#ðÕ™ÔX^ o‰‹ïÆ#|ñWÞûJ ç0N)éuQŒ±-ú:#FIõy.¶¼|É:ÏŸ\Ž•ñ¶ï=ùc‡ Ccà‘¶ÈïÑØgnÇ“·žÅX'×3W¯'éû~ŬÇ7bï>G;OtžÑÊ~Xeã3qÙܱ6B6uøŽñCŸàžî–)A…ß²Aï–ê{P~§ ¨ϺÕa] ý o Œµö‚; (@ P€ (@ P€W‡€5°4ãEåÚ£¬´LÀ×þÚôw¹yÈë5XŸ—°5YŸG`´ê´âFéÚñÛ£Yt!9Éçó(Ö2›¼V+þî¶`z#?£t}Ùí‹àʹS™ÊÈŸÊAò·õD%Z`iÈ"PV8—š'^k‘Ç p GË%‰óó0‰¿Ð0T ¶Ýþ,®O¹âWù™&wûênšŠ S9¼¿ÒS2fÜ)®?ÖãEøXóˆ³%oû¾;KÓÊ”ÇyiuýÛÍb€™‡I”šš³‡/BÄ7ý;M ,}²;b Φf‹÷m8B ß·§p켞&“xßÖBd Þ·zûâú¥å5g•¡=qÞgO«£‰Ëxåªñן¹ÚBfÚYd›=¬Ç2s¼àíü:£õIÿ˜“•*Ö»2;µÕ瓲ùýñfû-Øýd[ý!—÷Kz]”—å:S’òòšd–kyøˆïG{?ùù-ê{Ôèz&ƒÙF×[G´Ü´t¤dd‹ï ±öRe_Tװ¯¶øIr:ü#‚”cY¢LZ†øˆA¤üàı޲ kåêèƒ0Ÿ"9räQ÷„TôðDl)ß·ú¸Ú¯2µ'Ö6 ˆÔ7[h? 8JUã#‚J…²™àã"Ö½2È’Ÿ‰Sg. rÕdÿö1F‹ÑQ+Þki¹øä’^ee¹Î”¤¼Ñ5IÖQèsêð=jXÖÅë‰lÃ;8Q⯸-H•´Í_ä÷×Öº²ŒÀÒŽ•Ç£›w"]ü+öX(@ P€ (@ P€ @ɬ¥»jÌ(YIæ¦@9 |Ýã]|]Îu²º—À—''_––#`ölR§Á;(Ö}BãRŽT»,½½ö9þÝóbÝ&Ý4€W ·\‹ÊÅßg.B]eÙ.×ç÷*;mv‡ (@ P€ (@ \s•®¹³Ã ®¤@þ)ÌŸ4bÉ#e›Õ¿F>û)Žç^ÉN]_m_Ì<§;¡‰Øýr?N‰¦á.(@ P€ (@ P€ ®¤@…­±t%OŠm_+ÙHÜ•ŒlOwËMã|d›¼Q·y$ü ì×¹VΈý¼þäš?‡vü‰‹žžðTNׄ,“·¨‡¾oËç Öx:¾g?N™<Û´1 ֈ+ŸÆX (@ P€ (@ P€ (P×ç*I­ÌK—|Û,¦pÎ X³£p#L¡@éÜ P¿y‹Â…ù¾-lRÚ±ÆSÍÆ-P³´åYŽ (@ P€ (@ P€¨0N…Wa´¬˜ (@ P€ (@ P€ (@ \_ ,]_¯'φ (@ P€ (@ P€ (@ T˜KFËŠ)@ P€ (@ P€ (@ P€ Àõ%ÀÀÒõõzòl(@ P€ (@ P€ (@ P€ @… 0°Ta´¬˜ (@ P€ (@ P€ (@ \_ ,]_¯'φ (@ P€ (@ P€ (@ T˜KFËŠ)@ P€ (@ P€ (@ P€ Àõ%ÀÀÒõõzòl(@ P€ (@ P€ (@ P€ @… 0°Ta´¬˜ (@ P€ (@ P€ (@ \_ ,]_¯'φ (@ P€ (@ P€ (@ T˜KFËŠ)@ P€ (@ P€ (@ P€ Àõ%ÀÀÒõõzòl(@ P€ (@ P€ (@ P€ @… 0°Ta´¬˜ (@ P€ (@ P€ (@ \_ ,]_¯'φ (@ P€ (@ P€ (@ T˜KFËŠ)@ P€ (@ P€ (@ P€ Àõ%ÀÀÒõõzòl(@ P€ (@ P€ (@ P€ @… 0°Ta´¬˜ (@ P€ (@ P€ (@ \_ ,]_¯'φ (@ P€ (@ P€ (@ T˜KFËŠ)@ P€ (@ P€ (@ P€ Àõ%ÀÀÒõõzòl(@ P€ (@ P€ (@ P€ @… x¸R³ÉdBNnrss•¿¼¼<¸R”y(@ P€ (@ P€ (@ P€ ÊIÀÍÍ ^^^ðööVþ|¼}àééYNµ_M‘%s¾©©©ÈÈÈ(¾&æ (@ P€ (@ P€ (@ P€¨P9ðG¤5ˆx¸öѲ—éѰ…̬L¤¤¤àÒ¥Kp«T þ~þ"æ «$:–_à†Kòâ‘(@ P€ (@ P€ (@ P€ @Å ¸‹Œ°\ÊG~^.òÄLsY³”BYYY C€@…vÂi`)ýB:Î;§4ìëë‹ *ȇ;Ì" f’©—ä?r*<•¤7 P€ (@ P€ (@ P€ (PÑù24£¬TäxùÁÏÛ•ƒžzÙÙÙ8sæ ò«ä#H¤UÔVɱâ‹Ù­A¥àPW©Š¼‚JJPÉ1/ŸS€ (@ P€ (@ P€ (@ \“2ÉŽŒåȘŽÜäÀ!멨Í.°”ÉŒ³gÏ*m‡À[ —Êá/%øUQ=`½ (@ P€ (@ P€ (@ P€¥1Ë‘1Û‘›ŒõȘOElvSá?ŸŠüü|øˆéï|*#ÛÌRE ³N P€ (@ P€ (@ P€ (Pž¹"Ž$c;9¹9ÈÓâɘOxXxy6¡Ôe±dÎ7+‹;¹‰UŸ‚ÅšJ2ºÅ (@ P€ (@ P€ (@ PàÚ±㑱žŒŒ ÈØOyoÖK²¹ùùùÁ w\*``©¼±Y(@ P€ (@ P€ (@ P€¨(Ú1»¹+±ž¬¬,%¸b™¯¼Ú´–.^Tròsðå]bP©¼€Y(@ P€ (@ P€ (@ P€ÿN9ˆÇ,F™/]‚)_ü™/!Wüå‹çÎ6÷J•àíQ žòϽ<Äsw7T#\ÝL"Æ#c=2°$c?X2™LjŸÜ½PÀÀ’«¯óQ€ (@ P€ (@ P€ (@§2”•kBfŽ ²MH½˜‡s¹¸˜ç|Š:?/T ôFˆŸ*ûz"ÀÇþÞžð¦m"Ö#7kì§D…‹Îl±tÉ3s°RÑbd ,i%óÅcKš)@ P€ (@ P€ (@ P€ @Éätw2˜t:=ÇR2•}“˜O›rÍ2ã|“ÇdàIŽnòSàÉÀR-S>ªù*û¾^îÎ :¤·à±O –äÂNÜ(@ P€ (@ P€ (@ P€ J& ­©”‘“§•’Îgá\J"W69ÒIN“'fÌS6ˆò°ŒR’k-¹WòviÍ¥ŠŒõ0°äÊ+É< (@ P€ (@ P€ (@ P “˜ƒN®§t&=ÇÎfâô…l$*ýø¡,QödêE˜Åh'/w1ž[%eÝ%/צÄ+¦»¥:\8°TT59'ðËúÝ0{ª‹>9Ëꎪ5n@êÁ(T¹,àX‡)‘-оi„³ês2~Y»ÃÚfžÉ-ºµC§•Ë*Ì8¸á'œÁ?ÙËâóI»ÆþSyðò,Ü «Y ëDûðaûsöþœ€u?&`Û”cþâÑU¢« V­º¨Û7·m…jþöE=+·~9«œi (@ P€ (@ P€ (@ ”«€)ÿ.ˆÀÒù¬<ñ§NiW–̲¾ìKJPIÖé/ÖZòöt‡§XoéJm…Â3E Ê:´O>=˵¾†5Çøgÿ‹]êÙåw^Ç,ßõ"ªÙåTŸü³y®hs‰îH¼óË·5 ̤ü‚''LÀ9]‰{>ÜŠ‡ZëRô»™øaÒCø0EŸæl¿ž[4½:¯ç¯?ÂG•iØÝ-_ùôK« (@ P€ (@ P€ (@ T¬@žÊCFvd©¼6Y—¬óB¶'‚ü¼à{—5*YHËÃx¤R!œ”˜óxŒ|i²ôÖ±çèsYös°u±>¨$“àd`‘µìÁ5ŸÛ•äϯ㘌·€(ãc¶#›ðÊðqØ™fKQ÷2±æ¥¾¸×IP©Jl4Ž­êX^.2–­_…š½†ÄH°kðݲxÆ øê·äkø\Øu P€ (@ P€ (@ P€¸^LbM¤t±@Ršø“A&£MŽ:ªVÙ5«ø+r_¦m².Y§¬[¶q%·Â#–`æ*p8Våö1gBœ˜}΄œ pòÀ¬xo6¶éFÿ]öž¿ñF¼9¬®ržŽuh'ÿÍ÷»1¨N+í©ú˜ö;¾ÜlŸ$ŸÉ:œ÷òV¼¾©puaGZ´r:ØÈ¡¦°»0÷Ó±Ìþû~ZŒWçÄëêÛ‰­¥¢™nôSÒ÷Óðße‡uy€*]'ãÍ)#棦›ÍHOKƉ¿ã»Å«PÕ×Ýð l•­_¶z®ƒ=óQ¼&F¡ým9•*ßA-«_'ÆS (@ P€ (@ P€ (@ëI לs™¹8'¦ÁË+"ä뉆5BP5P#œÉÈÁ¾“©8cr¾“¬KÖéçíÙ†Q”ärX ,•¤Ñˆ:U=ÚZ$¶a3Ü2p0Žïˆ÷t¡m¯¿ƒwÎC}KœÅZ@·ó÷G+‘4¡ôƒ‡’6¬°tY w³v'@ …‰,ºàp‹×ý‰VÕà–aò@TMÔ®!VEŠ@­:ÍpSM yæKk‘M;þÆØ–ÍÔçæ?ñÑ3úÀÐxüG˜û`;k~eÇÃAaÑêÆï°?æê³’ôKWgnÊlýù'8•oï@V©‚ئмŽD²ßÒîÑ “:"Ì·׉@úÑ]Xÿó$gäŠÌhÚµ7Ú54XKäøçðvlýå7K~À;0[Ç¡yÃèÂkn‰5©îÿ[M&³ oÜ Õ<Ò°sCví;D¶ÆðÛëâèöß‘¡ëêß»~ÇÞÃbÜZ¶/ê4±_û*';7oÂþ¿þFF®·8g/„V@dd-ÔmÜAE¼uMp— (@ P€ (@ P€ (PbK— -‚CÙyÎDrT’ *E‹õ~ä_¸©$7™~AŒF’[z¶ ¹¦|Y¯¨SÖ-Û¸’[¡ÀRQk,9+È5Á1 Ãðÿ-ÆoqðÝzf›ðödÔëaË_(øó%Öï{ÃXJ¥aý2´ g•´*â_¹v’l³p»fl^2_É'ƒJ#Ÿ;_~ûÔl{ïkœð´Óuœì^‚LKý–rUbêXöÔ‡š¡~Ö¶Ïmÿ vGïÂó´³·;TŠ'¥í—Ú”;?‡GÿÏ>ð¥u£Ñ¸¹xçÁ[tÁžL¬|`ÞÓr±á…ÉxѱüG3Ðè¾¹˜õÈ-ö´}xÿ±AX [KJkKy¼é.Ìžñ4³½å²ö-Æý÷ζf<í5¤Ïž‚­aÞèq㸂-’yó ŒU—u0{S<š[ÖÛ:öã[ùÄûÖúwF~¸ÝìtØšcV>§(@ P€ (@ P€ (@ ”X@¹¯owsß¾ Tj‚"¨èãi'Èý†"½²¯ö%\’Ó¹Éê ÇHìÛ©Èg%[cÉÕžø4ÃÝ÷5·Ë½ýÀ?vÏíG©‡V·Û–çôoøR R¨A%y@• ·¬XºJË{î8ý»êr§|ŠûEÔ¨¸M‹k)ùÌØ¸Ä6ZI&5oZÓZCòîmÖ}¹Ó«6¢W@IDATéùv#®ì–õI ú%›ÚùÎ=†A%y|ß{cñÚ÷'ä®uóÒ†‹É _âû…ƒJ–œû>‹iß±–CÖv<~«cP)2hÝþøÞv¶kA#yÀa½­¯¦ê‚JòxüǵÍ|ò›ÂA¥0”äF P€ (@ P€ (@ P€¸²rDRU1:I”䟩¤_SIîË4í¸Ì«?~e{oߺmøˆ%½ˆ@š³/®FÆÓäó:]DTç£ÖCrP‰E³¦ˆ¸G11r5fYÖ(ú{¡˜úî±v¨%z•øÓK ©F<Ö«ßúçueûyìÇ¥ÖÑI»UÅXœ¸aël#X>_¾vÓÕâd7é8NœN†GÒ>|÷Ñ4|µE V‰¼7=‡nu|lÞöå6ˆ´³?Tög%è—ùäwø¯Î7=Š/æŽE¤ÇI|zw|lU”ðáJLè9®püFü¹áöÉÛ'¿Ìxß&ÚNcÃÔ¯pºïSbX>6Ì|B7: ko}ôò]"°”†µ/߃iÖ5¨vâñéßàÇw(#¥_C­öÖE‹ª§q Ò°=¾]^ØÖX ø6æOj)–öò€X×L1Oû'Y+®<Ž¿ÛÊ™Y)Éøã·=¨Pq¯]ë|B P€ (@ P€ (@ P€ÿF£ûÞÊšJÚH%1jÉ(_ \{É2ri¿ÁÈ%YÖ¨üå0/XºÚÚ¨‚–ýúËfX’âñÓþÿ`TÓ¬ýx“šÛ ÝZb¡­“½|?[›ò-Ãz4VòÝÔÝñ¾uººóË>ƾIÝÐHF¹Œ¶”/ñ@/ûQJJÖ°»ðÉ»#íƒ0^ö#bòÌf£ZËž^‚~%®[  Â…cêôqˆT¦iŒÆÈ§&ããïÄ8™%KÝŸ_Šç6RúÞî‹‘Þª?6XÏä$¦¸¡ZÀ^,^vÖš !þ¿ÿÊ ’Ü‚Ñíùw±sYw|«åX÷%ö¦ÝfNg¤ Çä…ñè×Ðþ wD˜2!âß–:"¢ÃDŸíó˜/^ÐZPO؆®u{£šüÅúVízÚÖ³ËÈ' (@ P€ (@ P€ (@Ë$kÎÇÙ çë/]¦.”¹™B¥¢æås3Êïî¤k2¯]Yy¨ÖàVtÄ l´äÿ&ᆆŸÅB˨™Ö{ ÊGYPÇZ£R®¢ÜÃ?Zó£éƒh]ÍC_Ð=wŒkŽ„÷´‘S;±|à 4t2ƒµAÖø8áEĈ}Þ¼}@ð*°´k+X¦=}[Î+rÖ¯9|R—ý,¦½óΈüò¼¼pf¥Ä“Yvâ@R&Ö PòÛµû(ÐÈv¾îu1pLsløX³<Œ?“ÒÐ*ôôc…n11âÅ·Õnâ5øV÷ì:–†›‚‚íß ¢}f,Dß"]÷Ú*sü'W_¿z0¨Š6Ÿú|ûÂ'0Xüµð(¼q "kás P€ (@ P€ (@ P€ @¹ ÝßNÏ6aÿÉT—§·Ë5å#=Çä´o² £vœ(çÄB¥òª?=ùxñUe‰G nŽËÕ Íùà \´” GÏÎ1pÏø©ÈºvÄ/°ßý †þHI"xq>ñ°í˜Ø[ó‘ÁôoÖ\ÍñÄŒ18öÙ,µ.ùt‹ÅšBÏ÷•¡%Ûæèo{"öRÒsÄ¿jÆî@¹·Û£¨äïêÝðÒÄxxÖ&Ë᳘:á],ûj¢eý à†Ö=ı5¶â»g`áÖ~x°­“sµå*ÝžËý @ÓöÍݶ‘;ž{ë”ð¥öwÚ“ƒ?·iònDÝÈ`ø{4A#ñlŸå¬ömÛÜ{A_úü‰Ó–£ò!Õƒ\ºÃ®ìzgªÕvÞH‚3‡·á›÷§cѶ×»×áhÖ4+ŸÈŸq'x„ (@ P€ (@ P€ þ•2TY€D`éb®9e¥¤ôõÊ ’¬[¶q%·Âц¢Œ8óÅõi¹)زd¦ÌŠ·;§FF#?‘$óêókÏÅú=½‡ßˆ‹tA¸èÝQL=§åÑ×hMKÃ:ÝȨ'^Ÿ#F">%˜÷áÉ6ƒ­¨c/Aâýí«~hõ[ëÝó úÌꃕڱÄ÷1u~g¼{ÏMJŠ{Tw<Ó˜þ£–X4¾0ãÜwk]^g*‰›¾GRåèÔ´„Á§ô+$ºŽè-°ôö+ó7o"hòs3E-ÀI?EñÝÛpøì4³t3ÿè÷ød‹í<¨$ŸWA¤øW ,aË;øéH_ôÔF„¥mÇ‚åú×µêÔ%ÝùXku–&Ši$µÉåÓäÃgíßG"-?7 ™Fòšz êíðàñhòJ?LÑ·oÔ†¬˜(@ P€ (@ P€ (@ P  ž•D`ÉÇÄßÙr yˆºE²nÙ†]¬¥ ý-MQ‡PCɪØ7k0ÞÖA)ä—uÛwë–ºb –@LQµ7í}‡ˆḚ̂e‰»-Љ½äŸÜl3œ•d0D®¶[Wk°z{2éakÏé^ ø`V>h™¦OäÙ7k–µÚ† äZJèùô{Xüã8Ó•_4ù,й ÝÓ!&9Þ*؆—¯Q¦Ö 3¿ä%]ý@ÑýŠìñ=û%–jev¿ámVcÐÄ»QKv;/‡~_‡•?îÄèO¶áÞ¦2Ñq[ƒÇzôÃðçÆ¢¾ÿi,yv†uZ@™³ÑÄÁ–@U F¿ÚkžÕ‚‰g1}Ð}0Íz u}“°àÙɶ “(×êɇ[Òw‡/ôãÐÎ÷(^©ù*:Ö @T›Îˆ öÀÁÏîÁÃsÿBÇоÝM¨]= æs`ùû÷¤§ãiò9(@ P€ (@ P€ (@ P œ´Pˆ¿—2uÉœlÓ%˜/]*U "ˆäë©Nƒ'ë”Á%ÙÆ•Ü Ýâ—:Œ6gÇömÙd” ‡ÏÀ«OôV¦³ÓÊjZ!1E ¬ù5¸ cf`Ù…p@¬4phÈÏd~Ç2ZÚîÚbL@·ûû ²“¼"IÙ¸[®^ОŠõ~Ĩ#”õr­©êŽÖ'ù¬òÍ£ñt—·ñºnTÒÛ#_ÆM›§«#žÂnÁû+ÞÃËýÇÁNâȼÿ_Ý4ym8ž“Ãaåiéû±¢OûEŸö[+þ KgÙÎßš,&þ3îË_XôÊd[Vm/lžÞÈZ.¢Çóxþ·ýxÙ:2h'þ7q˜–ÛöØå9<7´®µœ³v¥Á».Œ#Ú>¶‰ÖÌ}V™„pø›ss°¨3Pig£X«kãr[“ú½Ͻ€†b<§mè3rŸ (@ P€ (@ P€ (P w±þ‘¿þT¹ä£LƒWÉÍ ÿ¤_DFnéK2¨T-È!¾¨"–™‘uË6®ä}î…µ<<Ô›÷EZ†ÝˆÃ'cæŠmx×TÒç·«£š·ó£mÑxä«ýøé‡ŸñÓïûíFÙ•QBA²Lv¯×¦{ë€;:Dk9}ô®}+FÇèíþËÁD¢!a"˜¥mv}’‰>bTÒ‡h¨Wãñéª?­)Þ5nÁK¿oÆ«O޲YcÍ ÛiÕ{&w—SÕ·•­_î¢Oïn^‡çÇô3l(TŒªªj°ÞQX?<þä]…ÊÖêý"–¬zÊaZ½t}.Θìà¤oŽg|…µoŒP‚ŒZªýë xzÚÞ Zí±Ù߉sQGÇiiòÑÛR&¢Eo44áÖÞ]‰—ÔÕå>(@ P€ (@ P€ (@ P \d ÉËC¶®je_% .Cý½•ÑFÞžî¨TÉͰMyLæ‘#“dYV•d]2MÖ-Û¸’›Û¼yO_:xð8ÆYé‡{HÔ•ìÏuÐvÎüˆSÿ¤‹áNa𽘳_BBBQ%, ÞÆ±“Š;ws&Μ>ƒˆ!râ>>¾ðvèK&–iwv[ºÑô9¬þx¼ÅÚEgÎfÀl6Á#8Uƒ QÖÞ›‘~:Yð…ùrÿ÷äeêÎõT.Lº§Ü¥(@ P€ (@ P€ (@ P dêšKêºK%+yõæf`éê}m.sÏpçëÐ)Ó¶6QÐe(@ P€ (@ P€ (@ Pàê``éê~}.k##i¼|Ñeí £(@ P€ (@ P€ (@ Pàê(X*0˜×ïêë:{D P€ (@ P€ (@ P€ (p9*]ÎÆØ(@ P€ (@ P€ (@ P€ Àµ+ÀÀÒµûÚ±ç (@ P€ (@ P€ (@ Pಠ0°tY¹Ù(@ P€ (@ P€ (@ P€¸vXºv_;öœ (@ P€ (@ P€ (@ \V–.+7£(@ P€ (@ P€ (@ P€×®€‡c×wÈpLâs P€ (@ P€ (@ P€ (@kHà¦ÀŠé,G,UŒ+k¥(@ P€ (@ P€ (@ P€×@¡K­cB®é“Üv$Uéÿµ~åõ"У¼$Yþ½¼Žü{_{ž9ÊK€×‘ò’d= T^WùNø7ð}þox•yŽ|Ÿó=@ëGàjý<çž­˜ê8béúyïòL(@ P€ (@ P€ (@ P€ @… 0°T¡¼¬œ (@ P€ (@ P€ (@ \? ,]?¯%Ï„ (@ P€ (@ P€ (@ T¨KÊËÊ)@ P€ (@ P€ (@ P€ Àõ#ÀÀÒõóZòL(@ P€ (@ P€ (@ P€ @… 0°T¡¼¬œ (@ P€ (@ P€ (@ \? ,]?¯%Ï„ (@ P€ (@ P€ (@ T¨€G…ÖÎÊ-—¸çv¥_‚—Hñ ªŠnMÂA|¾A(@ P€ (@ P€ ®i̳øþ·30É]æJ¨Û²êð·ì×ôkÊÎS€(F€±b€ìç¥aËò‹Ò&s>ªÜpš…ËPQq››~:ˆÏ2-ù¼r'KAÅs8^ ŸÀ|©y¦|ä_º„Ê~Þ¹ø´¢N9Šç.ÁÓɧÇ$¯^ jãJ¼2¹'÷¡÷gZ îz;†Å¸òµqºSQõ:mŒ‰ @™ŠºFY+ßažU"hMâ(@’ œK>‰õ¿ý¦#ËZØÑÕÃq[ËXtŠ ¶¦^M;¶ëd>à†N CvÏœ~›ÿLUŽùED£e _§ù˜H \>ÛçסMùß6þ¨U3‘NþšCöŠ{jÆ·ó¿Å[I–Bb?®)ü+®AÖü/0ü<èMÄgãr|‡e9Ž76·¶<$òÔ«ËïM+w®*sæyl>(÷wÔF¬“@¨õ3†|T®fÚ{úŽýy‰ÿöÇà‚v È÷‘÷ªWüвy ë½`kÝù0!m›Gؾ+t÷ŸàüüýŒ¨P_\0Bbz… \Éÿâªð“+ï²N&âù5¶/Ê&~XÚ·†KÍxê²ùW*݇^•.‰¿ì\3ÎedãbžXÒÁ^ŽÝ<¬Y¾ Ÿå×V žÑ=ki_:Åå/Ÿãæ|ûŽåÉ/¸rØ*ªÞrè« ì\½F‰B^X>ùfëØÚUÃ' ŠÈ>Å_n‡IÎÿ;ãÄ_DZYü!¤:foƒFAWÓ/– _'Çûߎµ ÿ'÷Üq¼hùoå¿ûk¸ößýEÑñ(PŸ_gµEß‹ÿÒUÝ­è´Kȼ¨oÃùuRŸƒû(€kŸY÷eùs·ÿ®÷æÝÆÒ½¬,uYrϵþ7žlpHP$b Bí?cö÷€ÍX¿ûÿÙ;ø˜®öÿHd‘0±'$HJì[-E mÑjK[/Õ¾hKU•.ºë«}»ÿU¥UÚ¢ªTß—¶Z¼¥(j_"öÄÄ$’È.ÿçÞ¹û,™Lf"3y®Ì¹çžå9ß³ÜsÏsulЯ!–’bɸ€ ëœvÙÓš…£­8L¨›>ÎéÙÝÒ3À8þlŠ_ žèÓÃÚÕ²ëŒ2wзüîˆÁ›Â4¼(ëTq²§*,k)Á%¬T*"…R~á dåàÚõ\¤Óá—¯²'ìÐt³ L]øâåUje/¦£»Jˆ»ÂuSÖ¥sذãþ»f;>Zvù[Ílì¦p¬2áï½ T08©LÀE ®œÀÓŸüe©T D³`CßøêyL˜ù–ŸÌvQì® ÆØN~±p;NZëOhúþN÷û]#2‡Â˜€DÀX­9| Ãþ{ÂÚ£²±Ó~ïgÝ@AÙÄʱT@ŽÔ‡ ˆ…“ÌŠ' éã Žm)BµuÌØÔ>ƒ­ºx|hu“¸•(ŸÎ?ôÏ óWLrò²ñõÊM¹$Q³ƒ@1~ø1pSrÈâ‚ѯ#)εṴR)'¯©×®ãZvòh93_倀_-LÑÁ¹™8´?Sw_Ñ•íg³ÑÖbփƉ‹AÚ`é„fæP©ˆÐ +.w…ëŒl)»vã­Ýr Dÿ»[ܤوÎHÏ~˜@YðÁ³C»£sµÊÈ.¸¡‹¼JÕêêR{ݾaL€ Ø"Y߯ã°îq5Lùçmè)m—u%_~¿+•É5…øtá߈™Ô·X. Ò…tón.aʯ'0oPÔÍcfL ä„o±ÇÚ í*âwÄG5Jì£gp¶0 õ úî’GRR~xhl?ÜIŸ+¾ ¾—¿Å ö’†Ècl÷û«Uw,vŘ€s´ œ Á®¯‘1˜Þ¯èLdÓ"ƒ3§ÏbùÖSP†ÆÈ÷é£ðæú˜Ú‹W.Ù…É]J€K.ÅIåeaçîcØ})‡n|P¯nÄuª`'>¤å3•„•J‚RIX¡$(•²i <¾Ê   DÖªFƒ³´Ÿwx=´®¹ ®¾¤·ùxÆXQ,å¦_Á¶}'qøj>ü«TAppšD6DÛp;Ë¡ ³qàài$$§!ƒÊ–•Êä/ê×@t8-¹ÊXa.R/¦¡€f7ºÇZ~þ¨(-L$ÿGNÒ3A:úS+².jÓy_ö$cgJ„UHÕjÔBŸ[#ɾ’àJ½ì…«¸* =fObóñËÈ —ªPLë…×GßN겊S«²âȾ$ü•œ!:«V«.îìÔ55ƒ—Ï]Àî Z¥j6Žœƒ/a ¨Y Lܤ)ŒÙÀDUÑ8<”ê´}éT·NdÓÙq‚3¿`´¯†t:;eà 8GU²}÷6èXKS¿²3¿ÿöžÏÛóû®:´l€úšJ+E«†_ßÀš¸…ö¦¾œr¿í9Oþýà€6mÓ¹…’2œö¢Þ°íSc"´‘Q¡[L¨sÛÈÚO:?eL .îÙ‹eòÜÑŸ ÓŸëj¿!(4“&#`ú:,S”K˜¾áfö­gŽÍZ?À'ñ DZ7…6«§-ô†vo¨žWi¥Ý­=õ/è ðý— ĶË7°:µ-vúQŤóô¡x,jS—ΦttRÎ \¾t'RRqòòudRÇ+Wèû‡„ ¦I}Ü"·gšxÝÛ– ¦‘‰LÀ£ ßb¡ô-Fÿ›4®‹Ìé¿«ç#©½ª¯«ÒNÔ'ÚŸ¬ôLœÏ¸aV,Q¿ÊDý*ùRÛ²‘ú\é°fG NeÓwõ{Ú·Œ¡3ÝœoÏ䏸·¢p¬ßkï`¿â¿Åµ4/§œÂúýçq™¾ûýƒÐ¦E4¢}ŠùàÐÀf&ÀJD Ní0ÔUÏ.mÒ¨zvo†Eßü¯/¨AíÞ¼Gº•çÉ\ª¬lòšQ"ïHÐÍLEî¹Dgê‰síõ{æÓt²,º¶ÉØ'ŠÄ}|0î?j[)Hü#õ{ââºãõ.<ë\ÍA6O €ŽO(Þ•ñìØ·¸n6,[‹·iV ¨Ï`n$`Ø}ÄS†=Ú»?Ú ¡Wl¾2°úHni¥NhŸð/pi)ƒ;‚®`afžÂ“F¥R)Ü(RÎT’W*’_刀8½_–ç6mÖ { md ù¡ø¿üëJ%ÉÕáÝñøpGšÎÏ‘õk0ÆŽRIçØ°«nŸXóekJ%9$ðó·þ¬ƒ_]¸Tö'Î2(•t“•ÒñòÌÍ8+/üÂûîg£RIv|Ó gùòÓ…+Ûšƒ=óL ß1/#à _ã D+)ô“'Å u,óŒ^©DVþ’ŸkÖX(•jаöZ¹a+žX®*¸…gºð¯ž²T*Iüøó`T*IÏvoß‹Ùü”pð({´’p»²IˆÞ„A-l´ú‡Gaî½]€ y Õаè“ÈþÒé<'£RII¹aôÌÖÞöŠ{G WðòiªmûÉ”Ó"8¡J„,³äe÷öøé¤Ö‘›ÚBgúa¶“ÅO˜€Ç$¦UE.Ûˆ5U®[÷(Ô”SãL=)Eû£ô{„ø m“îÙÕd ¥’,òÚµ»¸ß#Ãà_‡ 8ôIlx;ú-.¿|µ¥RÉaéØ!`.'àWÃ[ifQP;Ïè:ì.’dZ¼bIK£æøuûô3)iFö‚Ç; >mZöçïÛðÞ!óö^%‰"¦›\ÎÈF:mÇg*•„\ºÍÊBÊ• ø¦^¤Y¼°L»M[&è®V±‚K‰xgŸff\F|Ò0ö:|'-GZ»åÆwê îÅ]på^߬/;í[µÆ+wE!˜¶§»|9 ‡Ï£n˜<ì[Ò´â‰;nAíôSxo»vÕü”Iíl™cº ¿êÏZøçÀÞÑ*g÷mÇ£ËåU —°:1#¬l ¨•¸·h™‘‚©ûÒëÃÏ#V)˜h»,a¿ò¿ 3¤ä¯F?¼6ªºT%ç´Ÿ/&ÀŒhƵ)WhÅ`¾f–SÍð´¨e¼ÊUK0ûUÃ?;ÖÄ¥“×U­ ­L<†)۵푰{ l„ô”C˜øÝaå=xzß.¬êXýê©m ¤6üˆÈH<Ú8_®=£_$¸£m9Ç5ÄÖú}£ó í­¼<òŘ€ÛÐ@”ðºU®a¨k¥Qž#Mk‘âùŒ¬¢-}/f££óÛ7mˆöÕ³q¡‹·¬5ô¯ëDbÑ£mélÅlX½…Î\Tû 0¬"Wå°gòÁ?ãš`ÿÚDe¦çÕ£ ø6±.­·×¯¨Œ5«aP«&Ü6õ¥ê÷Ð q²Ò¦JJ%ñÝ] }õÄÅÓ¿ãk'”Æ•*UB_ñEÃêéÍ»„q³ÖXŠJ[/ÌÙJwP뱽Ǖá<’×þ!—‘ ‰ï&›Ã¡óRhV¾‰Î+8¶;Iã‡ÆZ›¶ÅÔQR|¨Oe×§³œ»BñÅs·ãqrC"ÖbÌu€fkr*Pœb‰ÊþÉò€ÉÙZT* òÔoÕOl¢íì$…Ùv:oʶb‰¨‡÷“:¼¸pb•º?:uŒå†Ê×/uª J4¹C냺5ƒT|?Ù9Dì‹ xe°ÌŽ­üínY£A ¾ÑB׆Y£oºõì**•„ MáÍñÞéŒ9UA½xï%R,YoŸºuë‚·{™ŸÕM[… »U¥»6î~õ qïdu6öÒ t[;ƒÒ†dò-`.${‘Î9Ô†Wì~;¾ˆnDª¨3Z…´6­Yè_š—ÔÇXzHícÐ L˜”Jâ*Ì@ôì×Oœ þµ­}‚µÁÛ4Â/ü¼Øÿ*†­¼¤¸úñ?[pûË}ÑD±1|ÑoH_£%jÇ4B¨Š¥+i¹n´¥n ]ÖÓJÅf&àYd¥’°O„Ø4o§ºk¶¡t¦ž”Iûcæ\#²æ?ÜœÎì:ea°Òïñ¬|`iË ÌlýÑ $Ö•Bí»ÔšœŽ}‹ÛyT™D&„A[Ñ J…«v£¼94÷j¶Þð&À˜ðjòx­W'Òý‰»¡¢A#´ Ö[ùifèŸØ¾ó§u̵ª"ô†³«Ql‡ÍOÜIÀ‡Îº#´3ë pB8=V¹ ñÞª]¸H“Xó|+ãÒÁdå @A:³­vº óム}iÜ•ÎøÏo•”Jæpš´mŠˆ »”ÎâÕÓWèÈÛ(ÝÀ²1Æ\Z1uXcy59ó×\£ÍÎoÐú¢LÝ`Ïá3W…zâG“Æ‹hŒ»£§f•‚µõ¥¸Y~ÅžcŒï™”Û6/RŒO7(•€HѵG~ÐJ¿ïý–MÐŒKr›púÄyëu>¸!&IJ%A__mW$“‡hZþÚÆÀ¦Äü€ 02 à_-Ïi9.ªgFŽzú‰ìÍÚoÿþB?@£T²æ(²1õ[´}+ZXiÍ] íòòn v»[1nëïøBQReàõÿžÀ7=Љ!;ñ‡Oa{R*NgÐÀ5gYŽÆï‚¶ÐUý0GEfwL <ˆ¨H+–²E¥’°=ïÕC ¸÷P^ûçíèC“ð\ROÜÔþµ0MR* l}¹ßS‹˜gÉD°ÚÓûùº$5m°‚P;ý~rçè·xf÷!ø:Ö•b‘~ [ìéò`î" ýšvW.°E€ËŸ-2%°/ȼuŽ#ЬA¨rE ‚±pêK/fá?_å™@ ží“[iE€2QˆÅ[¯Òa«Ú­Onàjºa¦Pò)|l=m—¯›ÝžÑù©Šš†ë¾´5Ö~Ò~ ÃÄꀕ¿b‚*ÈαpñÝöd ;ÑâjŽÍ3 ×Öm®cÝ?Û2&à:úÁ®èJ»Zfkš j5kÚ+(ÈŠB¹u푪û çiyé£UW“m)…«Øo[ªÀ®mIù `eI °Š~rHþ ›ïu³Xy8tB](Ø…RÖ®&]ë!:ɽœª[!Õ¬¶É¢_¢²c-\Çì„Æ1<ÜËgj&ØÇG¶·>°i&lÐ~8›âÊm¡«úaŠLl`žF 8_=Õþ…Ùˆß6œ—R÷¾[ ÓÓw£¹ß+eÖþÔB˜§1gyË1ZÙK[Ç·(fN„1Ž~‹ë§ŠTCãšÅcâ{&P~ ø£€-Vrë]Üb½¹ÂAú‡§5¹":ƒ èð›@‡Ã¹›Ü´4u0^Â0“ùPÙ—G¨Qw¶kZH´~V‚²mÝÚµ›Ð#æô µ£¬Šþ5³‡ ‘ží‡[ë«Ôô]7ñÞG3ˆër@Y‹0"Œâ“U\óZð7 (çäÁT¿Ž~@J#^±Ëó5ŽÙȘ@ TE³ÈZÒÖ¬z3Ô_뾨û`ÑÚòhlÅİ ßz¬l˘ÀM$àãK'i.:kaË¥vèW˲²/c“2éF° Dã+z’æ[ôL }ƒ¬cãQÙ%+–äè`jH[zž¢-=UeÑædëÛø]>¸ÝB©Ô>².Ú×öÁ¦ø38ìˆÆË˜E¬àt¦V‚Ù)(w„inþ>hÛ½+¾ÈYƒqÊyy˜»åþ¯¹¥ÈÅՓ²j\ÑX&m*0bw©µÂÆÑoñümϞ̆CxpÑ \¶òÇ/Ò:?Î"³™ «Yæaúf¾†A³|íÄL›•äAþܪö]ŸÍV/Iì– ”Š€EÛ_xð­[©‚¿yžÝ‘ŽBš¢¢"ñÔ©‡[p G¤äNÕ_m½1Æiô#ÔyµÎ™]Û£ <Ÿfášžóµ ×]³*ªHáèÚMr£ __§Íí\Ölµ=ÚhØìYä¼õ,©YZ‘@¥šè×Ô›ªJ 9ëŽãŽ[”¸u¿²5¦è 8 µiÞŒP©Û¾bã˜ÒÇ8½ï4ÎÝÙµ¥>Fá¥cøA§¸Ò·-V…-õmžÜ§ÕéÐ ö®Àô‹–¾å~?Å‚M›Ïh„â“ñ=ÐBÜ»U“I±$ùWýÎõñ 6¥m í‡ qóå=*V»j¿EÅÔÅÕ:únp¦ž”®ý±'£½gB› /—ÚöIÿ¤âÝU¬rîhþZ–§âwº½~qåÌ2Lù]å¯[Ñ‘gòЬ±ºLãÊeýª .¿Žæ£êŽË¹ÊÂݦšïXŠl÷étv0*d²p\Ó׬WÝOìÇše+‚~ÿžtœ¸V„:&}ý»rŽŠP®@˜è»\¨SÖû…Bý4¿,ÞÒø³”d¸¸?^wŒžtÆ©ŽÑ=ß—Š’¾F]E®ú­Xv´Ý“;Ò‘'V~UXá¥mާ2Tk 3 öFbTKµ øiñFü¢D BÍî°ÐêiÃИϦecó¡38ªmÌ& ºUãÒ¶ÑCaMsõóç5Ñ[Z?K~Ù…Ž { ¹®ÀÉÒŒ_C-Pʨå³]‰1(¼ä¹«7膄U¿ºT¾-ý*áÒìÀ†‚¬TÅÕcøî@nFe_wÝÀuJVU?ó¬f{r /X[Œ… ónh©l¤d¡i —ûëD㇠p;â0ª›èÐPH’|M;`]0ƒM»¦uolQ›ÑïÑʬ„mG‘¦ñp«0ñÞu¹ÅÖi'2jåµßVèýñgàvÄ3òÉ–”ízÅÂttÁh¾ÒÈüÎÆ`¼Øs5×¹ý»1~‹<ÙÆü`X?:œ^lìô+4aÀØÇÈ?·–Ãä¾áÈ:yïþœ„4a±4ÒGx>y¸–‡ôÌdç©+—,d²ô.Ú8êΆw¶Ö ¬Ó]j^†âÑû"°úõƒ&i×v,kÜ÷6ô£ƒ¡[aÀÚµX!ûN;1_À€ö!(Šh»¸£§/âÏsÙ2¸?ŽòCýŽ-Ðã¯Ø(ûÁ¼ôùJÜßít¨Q.]†=Ðæþ;ñÅaÌgQ6I`ã³½»v⑳gñX›šHO<ŠoOiKd0ú“bTö#ÿÊb(áV ÅÃýêbõ*y?s`ÑòõX±µ.†¶¬Eç­äàÌÅ4ìI¼„$¿Føal[ñ ›áIØfL'ºø Z$YAWˆi‹6"·[RZ… s³Pe[–•]GÀ˜o® ™Cr%«õÇhiˆÐøX¬ã7Æö(ýÔA¼øk>k†«Gâÿäz)x4á¡aJb/|zÅé.¥}![c™Ó>Óyâ!`ÌSœ505Æ+íâÕÝj}ßð÷êGàÉöa¨æ{‰û±à¸ú\ôØ0÷7 Tê´±X¯Û& ¸5«·« ª¤û0‚þ+— TÒ(—Äp”‡¶ Ú6É"îª ñÒ)­ÙO Iî÷Ó®ÙJ;Žý7m‚óñkÂ%]¿?éØQlläÎQ&±¢WS+¯Sm¡“ý01=üÇkå¨"]ºäfÄÄy—Qõz6’²´ß2f"u«û£Ð©zRºöG'#‰¢­ëöžóRôgôP‘2[“V#Í£ mÔl¼ôõhMïEÃ[×óƒñìãÝMÏŒ,åL¦Z~·ˆ‚i›:¹Ygi¡ÿÆëî;:"ÖO-¡F¿ÚpC[vÄë§ÿÄ»Ôòž~é<¾Z§*›Äðýhë©ÜÛ Ro—qãÖMÐ`ónµ®e]ÁŒÕô¯Ík¸xÙ˜6¾wž€1ßœ‰}º€±þPÇUlìÅhôcnKÔ@ökÙ%I«ô_ùàñº FiC,×ÛÁ‰§»´òËœ¶íÑyâ!`ÌSœUÄÆÝw*ý…ɻԩSéçNãÿ~W'Ö(ŽÉ}K,þ50F·ºßXlÕíÆ=;ãþÄšo%ì*~h@Ögå’pU±Õv™«õm’µ¸k·éŒ±~Ã,mIégùã¶ö¡X°VlH8~ jª)íþVY-˜Øú'úx…þŽ+ÚBgúaª€lòÆúä i²c=Î\R¿uþB"1¦sMñ›Û™zâ|ûc”QÛ6Ù{&ô‰ô"kí“.èÆÈ¦%ÝNR剜fe[Ñ£ÜBY,®œÃÔ¼«B›àÙGðÖí²ÝÙ=ôNÈq0žÖÏ&\¹ªú8¼ žà'п Âê#º~(šÔ«z¡Áôst#=%V6¸„@e„Pþ)—E^ú¢ï=íiI­öº‚v¥Š>a‘øhB<ßBwüµÖ1LA&DVS RÕÍðÝøîx¼±°-žµË5üÌ2˨Ÿnd½ßšàî½p°öã÷õÁ˜6úöÃõÅ­ýïÂ×ÄâÖ cxÒ}ÜYt´‚xÙøˆ”JÆ\cݶÝ_©†‡Ÿº /· ¥uòE}Š[¢ñõS½ÑOÛ]!“º¦_vkíWß&YÛýwD÷ª¾j¿¿^ûn˜ÒÁØ—óÁ ¸®˜õ@¬€Ò?ÑÇ —µ…%ï‡i’ÅF&àa õÈŠô j…âñ;ºbÉm5m3õÄÙöÇ £®_eïàcøv 6Ü[I.[Uh†òd—…ú­\Ü;ØÞ·xûþwZyÿmZ´Â,𫾫i$ŒË¯Ýá‡å€€_Lzî¼Ü¡–®ìê$ ÅËÃîÂÈfÖ»¢ºöÄÜ!­ÐÃNŸ¸G‡VXðT:]{ë¯ýï`­OÅL“¬n½%ïŒ`µ¿­¸cp#Jsæ¼|ãðáS7î1šS¸£sÐR̳'[„k_iîW¡Wè,$ab¥/)¢j×¢­/tf¨N4U‚p¸y&m…w!- ‰g¯ˆ+—ÎÑÊ¥¯žîg7”›Ïîxûaa>.]ͤÍâ*Ó «üIYÛå¥0/¯ÐÊ apƒ:jA¨®”µôú©½º$YqðÏ!÷àARx^»–‰¬¼|Œ¡ò¬(‡%4\§ð._χ/É(Ôÿ@‡e,YTE¸võÒiqÅS½z]v% ›]k p;¢¥Áf™@aµGi¹ð'åoÖõB˜BªS]×Ïâ’Ýò/àvÄ{ËÀõké8CgûV¥é)9È(ðA½:5Q¯ºkÁ×3óQ5Ø2¬Â31h‘ºb²A‹öø²D™‚.̹Ní i´|}`ªQæÂH}8꯻–K²P_ú'Õ•œî¯ìúaîO Ç`Ÿ·«öùØ{êh=)Ïí½ôyÓ3.çå37Íï?zÏÑ7¿pu„ò7@©2ŠËy©ð¹Æ3Ï;—®ß@µª•‘A¿µè¦z5,û ¶"ûÄ—3QàßÂø£QݵhË#Û{òZŸ}ÓSDΣ»”7Oðw)N!°J 3i4Ѷ•ŽF]©R|h¬.8Ð~ÒŒ§«Y9àUKŽ",ŸîHR+¬†A6ûåÅÇ/õê 2•þÊ¥§0àQ½z°f6_éíJáU5NM.}°VB¨„ê5LÙí³³[1&P >j{Z&u¾²W&ÀÜF ju¢é¿[®ÂËøxÖ&l1á- U]ªù'Å7Û4‡!SäÝ›Ör‹öõ ¨Jý2Ù…¦"ô×Â\Ó_“Cwô·ìúaŽJÄî˜@ù#àP=)çíOù£ÊU$æ÷_ÕŠ”dN«· ñ¹z j£^)Òi½O¬é–"löÊÊ+ Å’·ìè-éПÊEð'ÅR]ZÕ%¦>2sò,öaֺך½‘‡6}l.ž€aËnT&e%—‹â¹± •—•›˜pŽ·#Îq«°¾ òqUH|Z:~ü›þÛÒƒc5ûÖÛrÈöLÀûp»ê¦<åöÇM` –˹sÜØ—gàrîYùÅÒ2{*J}¶P,ÙƒÂÏn.¡PjW.Þ¸qsâØ=š@®cxtYx&À˜`LÀƒ T D+:GÉÖÁàBÊzvh‹'ã"Áó¦=8ŸYt&P pûSs…ebL€ 0&ÀÊ Å’qUC9’µD¢xK:¬%Ú‡–š+—ŠŠ*ÓŠk.,íugé“m¼…@P£–˜;*’ö{¥ÒY¡4³×Áòã- 8¥#Àå¥tüØ7`ÂJY¦ÀJ@À7¹Ã3³pöÊU\¼š‹ì:\‘®ÀꡈnT¡ex~Q $g§L Ìp»ê&ÔÜþ¸ ¬sÁr9wŽûò,\Î=+¿XZ&`@E©Ï–Š%{T<è™7[…³²XBO¥ã.=(“YÔðEíZ4í—/&à$nGœÇÞ˜Pp;¢ `C ¡±ð¿a <±S&PAp»êÞŒæöǽ| ˹£¤Ø'àrîɹDz3=ŠRŸY±¤Ïw¯½«(Úk3ÆÊnGÊA&°LÀà p;âáÈâ3&Pîp»Zr.çn€ÊA–;\ÎË]–°@LÀi¥>Wvš{dL€ 0&À˜`L€ 0&À˜`L€ 0&À˜¨P,W,yÉ&€•¼$®*ÌÃU$9&Pq p;RqóžSÎ\E€ÛW‘äp˜`fÜ®rI¨¸œW„\æ4r9ç2À¼‡@y«ÏEnBk©XrSDelEYræ(Wæá()vǘ€-ÜŽØ"ÃöL€ 8J€ÛGI±;&À˜€c¸]uŒ»òl\Î=;ÿXzÇp9wŒ»bž@ ¼Õç²S,•·”;YZxÁ’óÐóà;&ÀJN€Û‘’3cL€ è p;¢çÁwL€ 0Òàvµ´Ù¿'àrî ¹Ä2––—óÒdÿL ü¨(õ™W,•Ÿ2çVI¼D_èVF8`ö p;bŸ?eL xÜŽψ]0&ÀJB€ÛÕ’Ðb·žJ€Ë¹§æË]\ÎKB‹Ý2òM ¢ÔgKÅ’—¤¼¢h­FÌÃQRìŽ 0[¸±E†í™p”·#Ž’bwL€ 0Çp»ê'våÙ¸œ{vþ±ôŽàrî'vÅ<@E©Ï•=!3XF&À˜`L€ 0&À˜`L€ 0&À˜`L€ 0›O€W,Ýü<( *Ц´L`r$L ‚àv¤‚f<'› ¸·#.„ÉA1&Àˆ·ùNCê@IDAT«\ *.ç!—9\ι 0ï!PQê³¥bÉKòÐKvôsYn0—¡ä€˜@…%ÀíH…ÍzN8pnG\†’bL€ ˆ¸]å‚Pp9¯¹ÌiärÎe€ xŠRŸ}?>Z whò­’—¨Ô¼%š¬)•‘y” {fL€p;ÂÅ€ 0Òàv¤´Ù?`L@O€ÛU=¾óN\ν3_9Uz\Îõ<øŽ x2ŠRŸ}¯ç74'-UB‘'ç›"»·¤CIP) Ì£”Ù;`àv„ `¥%ÀíHi ²&À˜€ž·«z|縜{g¾rªô¸œëyððd¥>WšñåË7N=…qãÞókoF5OÎ7– 0&À˜`L€ 0&À˜`L€ 0&À˜`ž@›j"ƒÆQ]Ê¢²¿Å)K. ŸcL€ 0&À˜`L€ 0&À˜`L€ 0&À˜ðj¥{ZÔðè¤>uJ”?¢aCN‡«„g®"Éá0ŠK€Û‘Š›÷œr&à*ÜŽ¸Š$‡Ã˜0àv•KBE Àå¼"ä2§‘Ë9—&à=äúQ®•rÚ¼bÉÕBiNWruÐ`L€ 0&À˜`L€ 0&À˜`L€ 0&À˜€7°X±äM‰ã´0&À˜`L€ 0&À˜`L€ 0&À˜`L ,¡RYDsÓãàK7= X&À˜`L€ 0&À˜`L€ 0&À˜`L€ x^±äùÄR2&À˜`L€ 0&À˜`L€ 0&À˜`å™@QyÎu²±bÉu,9$&À˜`L€ 0&À˜`7@AæeÄo]­ÇãpR R3¯“LUѲ÷=øÇðûæcGÆt¬ýök,øu;²EWUÑé¡'1vxW¡˜‘’‚\œ?uwmÇÊ_v ç¿§a`cëqå\ÆÎµ$ãYF 0 Çmw>„{´)>>ë!Û´MK\‹Ó`ÿÅy+žœ0]Y÷“y7ìC¾ŸŸÕçyyUÐ2®'ŠábշƲ¨©'âñ×ú-ˆßv).‰ì#[ãžACpßí1ðµË¾y¦ÃÓŒ\έç˜÷–sJoIÚëxØ– 0&À\D Òœ9/ß8|øÆ{G 2¢aC}s‚9}ê”W¤ÃUô˜‡«Hr8L âàv¤âæ=§œ ¸Š·#®"Éá0&ÀÌì¶«9‡0¾Ëˆ·kègK0þö–.r’0mÀH,»bù‘ðø?Ï Ü×R‰Rpn#ÞzsÖmKÑy1F·1éì䛬½sp׈yò­åoè`,øãD¹h:ì‰ïâÑ×VXÆC6¶x+£àwÎ Œïd=V#³bypáxŒ™ºÇÊɪ%±Ÿg=œÌ3Û‘•Ÿ'\ÎKžÞZÎicJNïæø°[ÎoŽH+`Nësýð'Cp·³)§Å€G5vi|Æ’Kqr`L€ 0&À˜`L€ 0&Àn"‚ëH£7¡ßØgðÑ|Z}´äK<÷p;E¨ÅŸÇÖ4ãÁÒé˜ÿ„ªTêýâX¼r þ=¡›Ù_ò" }ú?Ȳr uîŽJ%%2[_ó* Þ£Æàß_|‰Ëâ‹ÏžAÛPÉÕ¥˜¶,É–ïÙ§í¯*•Bãðþ’%X¼ðmt•âZÏ4x¦‘˹E¾yo9œjc,±`L€ ¸’€‹æþ¸R$‹ 0&À˜`L€ 0&À˜pŠ@pSLúl:"oëˆ0Íꢨ—f yyeL ¾_ˆ.E+Q¤n^€9ûÍ·m_üoo.Þ„?6ÕóÆãÙY´¢fÛÇøao?Z…¤ß:οAO<ýbS´éÙ¡ç—àÁÑóÌÙùûÖ쉌ˆˆÄçK#1¬× Ö>e]6oÆg']Æ÷ÏÍ–Üuÿ¾ƒÖÁª«˜ºÔ„ñ½&ˆ«»f¾ôÜûóHÛïÅàÓMóÐQôç@”%tÒäΗðQ\$ºÄÔT}6ŽÄŒ­Ñ´úì)Q¾”¹ÿEÒ“]­Ùv¯4y¦Fä¡&.熌óÞr.$Ô™6ƈo™`eF ¨Èruw™E^†ñŠ¥2„ÍQ1&À˜`L€ 0&À˜p/:ÞÞA§T’ã‹}` dU’^i“‹-KIÎâðÂðXÙ‹øÛñ‰‰è*Ùü¼x «–|ÃZcØð~ˆ0¡ZUëçén*ùè•J’ƒJ!­Ð¿¥…k§-rޝÇbik¿Þo=+)•¤àB:`âëòЬ±ñ\ÍxL•Mÿö5î W*ÉŽZcÌØé.é:ñJ—gržûËå\›wÞ[ÎÍ©tªÑb3`L€ ¸œ+–\Ž”dL€ 0&À˜`L€ 0&Pþ\: «›ËåÇÿÖ›å5 ê ‹“|¢g/óóô•Kq0ÇlvÇߢÔÝX"­œ‚_•RGq|Ë:) n»µ®ExºHvéøqe¢ÅsÙ·ô;ÞÉA•à7'Û©åY T&N¹œ{Q9/“Ñ0&À˜€3X±ä 5öØ`L€ 0&À˜`LÀÃ\ý?Eâ)f\M•Îej× ƒ/Œ[¸ø£IkùŒ&:‹H·rF ¦´¦´Ó[ñî¯ ] ¨ž¢_9Uâð‹ qùŒùü" êW³<  ~¬z–Q^¾(®ãï?6`ëŽCHIËµáÆ Ö™G…"»¡i°&Žr’g‰Ê‘˹•órSªX&À˜0°|Û]ð=`L€ 0&À˜`L€ 0&àÑrŽ/ǸétN’xuC\s“’ž¬‹‡Å3‹nZ…“âB0BI¼®#=‡OZ%‡ô¤Ä?9ɘñÖL\ )‡6#)Y !r0fÏ›„ØÒžiT)‡7 §5ÑEŠ™†Öd.ÈWR–}íºÙ­ü· O2¥`þk¯È¶ï< “&BÇýYSŠ—r±|²ù|%!¸¶uGˆFáwÓòÌ%is_ \ν«œ»¯¤pÈL€ 0÷¨ G,W,¹¯ qÈL€ 0&À˜`L€ 0&Àn:‚sñÔà$9Lxyé;¤´Ñˆå«9AHcÔ¸@`Ípé6{O˜×iŸ;g¾†M+7cýW”JB@×ÒpùbšsAj}£Uo錢`?XÝX/ JÊ6ïCšæü(ÿÚÍеe;ô-eW¤Û¶Ï¼sv\ÖÆæ:3­´ÚøÙX|¸^ ²ÿøÈpînZž¹.™®‰Ë9õ¶rîêBÂá1&À˜€ËðŠ%—¡ä€˜`L€ 0&À˜`L€ ”/Y–cÈð¤í倧ç/ÂÀÆþ6…ôóµ>L}ùªâ§¦ÉºÅ£ÿ˜±| rkçãïK1­ªº²¯Y‹AŸ-Å ·×QC+HÆœ7¾Á©€ØJAnNüÝ‹Ic{" RNì°qF‘jA6””Õ Õ)Ÿ|ëõÀÔï{È.QvkŠwfmíæž‚Λf¢µfeUÊš9øì·S0Õ°}(S.EØû…Iˆ‹°–Št,m>\))ïz=ƒßÞïÍj%E ÉP¦yfŒ¼œÜs9÷þr^NŠ‹Á˜(–€qCáb=x¨õ=4õ,6`L€ 0&À˜`L€ 0/%ò× ¸HJ] þ½|– e†ªà8z’Î$jao‹·vh!î)ç‚a“J>‹h`–/"±âðð0R„ 1+–MœÁ;ßF”ý~R´cÉ‘-é¼B˜·€µá?e m;I~穎„²´Žþ˜ó+Fwª©Ù1ÿ2&àQhà™/ï%Plûî½I÷Ž”ÔÅý½ÚÑüý@]z²“ >YR7E¶CïÈ@ñ#ÕìˆÖÖ×oj{û)]He|S„e¥’uòl¬=ýFh‡ŸJ*S)úhÅ›0°ßµ HÓB!²³Áä–¯1% 6TP9‰ËðázMâÏÇcëù|O{±ÕŒi¯›-ÝêÁÇ`šõ )œÓñÎSŸâ–Å“E;u¥%à!ŸKþc0òî2†Lhf{Z& iùàê¹T%®ÔK—“Y€Ú:/ 8šI“iÖbåIz÷l‰ºÁò`%ÍLŸõ:>Ù&Ñ¡¥kÜO>ŽI?¤ }Ù˜v[c¼Ð7RŒ aád%®ð±C­Ý™„\ä¤Á¹ì`DÕS¿ÑR6ÏdzïÒ÷ºx™"™ýÉÂïÓ>V<§SzîØ‚ëº,ËG>©óÛwÓŸUªÔ]XOݼ@³ÔöO.ìŸ „?6ÕóÆÓŒ%zIlû?ìí‡Ñ†åú¢CþãrNâßã^gü†ŠÆâ‰­½#]R*Nþþ&^¶ñC8õìJuÊ2yÂŒç$úß)VX™Å`^CÀ¿¾Yó«8–" ºh?v¼&•6!Ž´ïŽ'$Ü·F:ÃBÒ‚ÄÅè% ~wF´{µNË_]NýûWlÑŠHæ…Kã1pbƒm n]ÔG‹ž0 S3÷ó-c/,-edO#P˜Ÿ«9Ž› ¹W¦QÓñ»¦ŽT ë¯>@³™i€)y)íò'¢[ÖÁÅý‰ÊêÆ¡Ÿ}€ŽºÁKsxY¾S¾yÕ€e“†c™d>öK,«~ëœÚø•¸Ý÷LznŠŒAld®ß£Ä%x=¼Kvðèòü‡´Šd¡NA¦µ-cP;ó’’eEú0|:¶#Ũ¯“‰‹Ÿ§³žè[&4m[7$.›Iù.Hf¾º¾þâ4+»dû’þffi|,ûãdhkAI-¬rÔ~O•&ÏtA{à —sËLóÖr.¤Ô™6Æ’Ú7ŤϦ#ò¶Žº­s£^šæ ÆcÌT7¤Ñ¤ïW'¢‹FiSšñFÿ=ñô‹MцÆoBÏ/Áƒ£ç .(ö¬Ù9R7y‘ø|i$†õzAïʺl#.60ÉAiÒ Ça|ïÈöæ_}{¯¦¹s2„³Ï„±âa¾ú¾´w üGa’xN_®[KÖDoa, Fç‰Ï n­6èÑ:?=2ó“-\YXÛ¾Jo<¼ÿëGè!wGÇ¼Ž–us0ôµµä‡Æíy$m;òÕB0¶ðhnQ, +•¥ÒñK™ œØüêŠÙS ~%”Š«4S±`ʇ´¬,šÍXõšwBÇu9¬¾°Ïìù«ÂÌÄ`„Ó,¾œÔ$¬ÿ;â!™n»|Sqì‚’:œ;y©¡4c‘^Vuë…!7- ÇþúI:}òRë„"‡úaõh‰é=Ki².aµÂP·AC„+ûÆË¡äâÄ=8ròåÙU A³vímm^‹4—QzdQù·B( Á˜ø]p.-K,Ë!¦0Ô oB3zõûDççˆ}SúQ:¨0cû:dçß;(<ª…ÔNµìØ á!rHmÞ_qˆž ‚6jß­#ôñh3ÁÑ6Ï(ƒ± S΄ën¼¹îRüAA!bÕ¤q‚4í”*CéêoÖ¹CØ¶ç¨ØNÕjŠÎ†ÙÉj<ÖMÆtQ Z¢wh/í„m;p’x W­¦·¢K‹:ºÈ²h?o{í;÷Yt¸<ê&W3 W`{Ë}¢Ìà•]Ê™>{wYX=g©…ƒ”¹‹‘ôtGuÖ¥Ö…Å»ÓÐ_è\©NõÑ´‘HæiaBÇÛ;ä–ã±Ð1SŸ'éê•6¥oô kMçíí3}E\spd´’nüFôL*…´Bÿ–P&ÕËöÅÿ–. røúuù²mIÉ)ƒRI޹Uß^€¨X’mJðK¬[ßG«D/Y¶2yÛZhUä÷t8L†q´°FMÉ‹ XÊ¡11Íåò|Õ„ÍF¯ `¥[âérI"h±Q©¯¿| iŽM˜üùcÊj%äÇÿÖ›ƒ7 ê ‹³=}¢g/` ¹I_¹§ôAkÈcŽ‘ÿ– ó3Ï€“J_ù\i¾1Î më#;u'Þì;AQÆÈié÷ÖúáW0õÅ{VIÓ±¼ é±"[U I¿¼‹QSÌËåuÉ6”ešZˆ±R}4žO¨¶Ïà?_FâÕþ/X”ù§Ò ¯FGðƽOaÝ]LèMmÞÛ¥lóT¬´asºšÏ„Ê<„w¡¶)Y¿pgL“`Wªú»p)ÚÅ„qSK׿¨éz?}güçw,Æã£?Wf³ i®p:ïaÖû÷šß9 x¼—¹5?5¶ïKt³©Ínø¯7ÌAÂÂ7.»•³ÎøžŠ…«ëëÓÑçàxg™Ð÷ÙŒ_·§â…n–“c„öÉ^¡Ú5xY\q-KýñbúhfgÎÿõ’þŽóا+ µŠMñC2ªïx¬ßôº€@S¤SuŠlÕÜrB—&gâ ð:ÖÇGꥫ¸r%Uh0=¶è o¤ÛzNMéŒÑ¿`¤‰^)ù¨zýP3±…6BÓ·ÖÄýiø9î.^¼†ë¤$.  &5ë6 mžÂ”IhçNiVûWc˜C¾­ËéLž9]9väL™Ó&ÇfÎÄÉå\¦^ºrî {9foý-¸tÒâûILk9o,JÝ%R ~úÉvóÅUi(Iœv²þÐfXw®Øîþ]þ–²:a@qèBƒ¯2¥=ŸÌü3&ö‘Ž]ÉÅêï4ÇD«‡ë;0öìt¾º0=å=¨¢"ëïëò.wIåcÅ’Mb×ñ÷pV„G7¦Yӎ͆ÑW”¶¯N1E}ý´{¼_M•öIj×±Ö)õG“ÖíÚ @˜i,N÷ÖÎf¯ PM3KON)2œ¶XHAlý겕úK[#ÞßW½ÕšVM™ŒÛoû=Âäþ´íÈÁÊÌð^Ч~æÿ ”Iz‘ ƒ†}x3Nm—‚4¡mÿÛЬFVþ°V`L_ÿ9¦­è·4P¢õõ“fðÑ9£FÈÖ‚’'Õª™Ð2’bJ–íé—ö¶ §d¥\‹_žu;SZW¦hÐóÈj¢ŸzRóD3šwHa˜Z¶C×NÍ»cÖ‰³'Ó1sÄ tÙùºz$y £…PçŒIÍ—p^Zzýjô)H—ÖÍYÙ%lÁŽtb/^ĺo[UQ&Èa/^Ẳïý0smnkcv&ÿMÛ;Ÿ¶™-ßÒo ú=ܹg÷c÷zÚZ¤º°Ã| nï׸ ï5}šÑÐØ¬¥b§1é‡pÂü¼`¤ª\*ãôH¢òO%Ppz¹F©Dç"<Ü!WÏcǶÍHÑ”e¦lúûé©íÇçx°¿þ™|7sxfÊ7ôNõX> tÝ”Ïpð.í~Ô%oóT¬´a”`ZѰj²ªT2uŽCÿ&8™€-ûS`LS©ë¯¢|§ÄÚœg§÷Äï/õÐаmTÓõy Þ€ ÿƒ£å¶*ýFõ@îºEX—LÜiP}lÝZ´]kjC«Û¾Û–ŽŸx#™CîU“ULÙu¸œ©!k:øË’2Ô„{ïèˆN1ƒH±4Oô·lþz<ÝíAZ+mø¸Ó´OÖú 5JÚG³'¥#ƒ^Ðß±‡€Ÿyßà:hÝÉÆê$&Ç7À„ºÂj/(š}]7¦5­Nrð¢Ùæaõ"é¿Ñ½¡M1>¾ ÷e•g7!in‹²¬˜q9w[V耮þŸ’þ)f”“ñÆ´Ó[1ãáÜ>á¢UžCäœTQmš\”†‹ ›°qs:Laˆ‰ ·ìÚÀ±6óÀ–÷‚tì\6¯Ò™Â=aL ÏW²pñö!­îBoз9MšûîÚq³§>„óK^Á‡ÒdôçÞ¢›Ln-ÔR嫵ÙΣ Ð'_:yÒm æ¿öŠò(¼ó0Lš< íl½£8 ¹øíMó>¢@7¼öDG²U;ŸY‹ß‚ÓnÚ€èWþC %ñºŽôòëàòFÙ7ÿ–Q4KoSÜ@Œêb^¾MûŽÏÕì;n+¦þÏà«×B8m•wð—70fаd5‡Od’bIPìЬù¿¾V”JÚÕLÞ¿ ù€^î)øjñ^tÑÄW»Ã#xù‹V¸£[”òÂ}úÑÞ¸§ÿbg éÔe YU,‰iþô¦Y¯?ÔQñ‹ŸÿÆàoGaÌôDrƒ/~‡ÖšsËbßÿqÌÇ]ÃÍ™#æÿdyžX@8†¿ø šÝ}'¢ïh¬z•Ä—ßQ\Ω„(M¸‘hpv>]8 ëÉÊaµªîºáý¥“Ñ£1mçwœø øÈW8žžó1† Û\¤íÂø^O’ÖîEÖcŽl‰wßhEƒhÖÿiÖ¿Bš•ã+͹€ož“ui»‘9 0¢“y–õè±#ñßWÅ'Bš÷ÏÆ¬?ûbr_[yáÎôÈ\ø·¢H=’ %=ï¯ù‘Úé–”09t¤ƒÅà­ƒ ºŽý¯?Ñ!¾™XõÖc4(lîl ÞÍmÞPj󀳤3±;Že"¶…yïgÚ<£hmµW³Í®Âž†Å/‘REº ÄÄ Ó¹ä6ÅUõWÓæÐj©7î}B\­•¾ù0Ò@|”ødIŠÿuähäVeþJ«2…vuâ(,õ!ñc#eîWØù¸pV^$&Ûmße&ÅËÆ.¼‰€#e·$åÌÁrTŒŸf ý º:?ŽNtœ[@ÈôÃ<ó*èmß`ó¹é ³›-ú pªf-ü¤µbm³Tàz¾ú¸Š íoï¨Öiïï¨Ic`L€ 0&à^¸ŸéÂDtáꆸææq áî¦7æ$cÆ[3é«‚F§m¦3ìi芌Ùó&!ÖÖ˜Ù•îoiÓ—i.}ý<¼º^:ƒ^ ciÌ*ȉo*9ù×^Èn„ß+æà‹§Ä-U·l“ú¬d?è­¯ñÂ}͵NÝk¦U»o¯™†¡}¥±êý‹0¦ÿ"%Η—ü1Vöeua¾*‘±ÁkT.MJròoÐY98Aç¼hÿ ç+ ç,É—|æ’Ö`ü a”§ËŸÎ`éJ«"z÷CÛ–´šBºR¶-³ïÄœÂÀzñWÚŽ9øp½Ù]¿&Yîíî«™º­1jC¬)ÇŸ‚½'Ôan­6{+M·Í„™½ÿ¾?LT* Ž7mªºUÊ’æ¬Ða{oŒâ& f žée¾MZµ*+)ÏêvˆÝ"uÕêuÀý‘f'ŠKKCÛ¿ÆÛuÐù5»*Iê ,ö­ƒÃj”J‚ôúÅ­’lÅF6t#eÖdRI¶×þÆaö¦©¢RI° hØ Â<óŽÉË¿3+•‹–¸­¥ô(3W¿÷¬dmüÉ9°F9°¡ƒñ©V©$8¦YAÒYZ9V‰ Öá£ÞV”JÂ=íÓ¦|€¶æ¬š·†Ö2ªy'YÓ{Ó£ÆÃ¦ŠJ@­¥)øëïC*aÿåyŤj툩ëë_cêØ¤T’éŒ¶Ø†Š·ð‡ßÆ/b›g¶j×]y–W Kã\›§D[mXž4Ç#eóß8˜¦Ö9ßÝ8®©¿´mîRM›ÜV¯JR«+µrgvìA»i'®SÚŸASÆ›•JbàA8á))šDì9–¦‰²$í»Æ½€ce×¹rfWêößÄ™—‚«¡Oô•ú! 0xB;Éc:¬Ýwã[¯¦~¯n5SvkŠwfm#?z :oš©[ua!MA¦–´¾Â ~a¡½0Xfýòóµž Ù—¯*jš¬»Q°¡‚€¯¦ô×)oµC4¥>IG gåw•Eøpº?–-Ü9,/8°1P)ü~úì\8—NÊ“4$ê«®9í_*ço>\‚eÍZ¿Žši5DêùÓ8›ré4ã7íÐþb}úâûu•B:G˜9£ Ê·>Ú“òh =öuÚÂR^é$¸‘±Íîåíë4¾-Œi©©Š]ïIC­ ,;ÈLÍèÓK£0”mšˆŠ­x!é´ ×Å‚"u @É»Ó#‹Â¿—@Ý[ZSâÍ{B¯šBÛÄÍÃsÏ=Œ~·;²‚Ï ·È‘´ÒQß~DÄR%¤³Q„•ޝMè£SàæKm™.¨Òµy°Õ†#4LŠ(y)ÆôZŠÞ£žÇ°!ý[O?ÜìŠúÛï½9è×XÛæ¡E\ ÕwšÙ–©K°ƒ7޾3èÃæÜ%ÌeßAõ±ôÖQ§Vž± X#àhÙu}9ËÂ_tÖ¢xÑä¡i¹’ÔçŽ2 Ñ4“Wè%M_Š”Ç&ÓÀ‚õþ¸#ýs$Îþ5¡kÿ€æ“)›zfu¬uï=´¿ã,öǘ`L€ 8N ‹În2\ÝaE8sz îûAV™Ž7ú·ÀŒåKC£H×ÎÇß+–bþ²=´Rg-^²ƒ>[Šn¯£л§&<ö ãH”‘]ê[¥$¬ÆgϽ-W(BÚæÍ¹í0ã1á»¶äWIó ö‘/°àΊèNìÛ„¥ŸÍÏÞ^7ý¬û~¯}ÆfµäÒÙöQpzø¶ywžÈ8<ýP|?u‘²[ÏüI#±wÂtâÒAˆ›òU ßy*kŸ3§E^‰tü’ýÑÑ]šæKJCl~uÍ]ù3ú†4@¿±S’; “æ K÷`ÍÖmÝÆdSØ_¿§Ìœñá£ê9(:êÀÑÑ“—i+å¦Z4F¾­ +ÎØàýh] c*©ë‡7ÉAæì^˜Òµeî>yK×â;³æ,¹¢ýp¦ÍÓ bO†æ˜¼öôûåÌül’$SÒàê¬ùô^q©+꯺µŸV¸R˜í¥Ë¬¶­ §UYOÓ„Íâs³ë| a”òÖ0„À·™€£e×ÕålßÊÊ,Kÿ²YólfÃü…0ªÓ½ºªc7¿;ó¨òsyz§˜äñc&À˜`L ÒvÌW•Jt.äì__×ï¼¢ »<7ÑQ ï]Šqâ8i"RhG¼¨0°6ŒîHC¥v¸“6ÆHÚO‘&ïÀÉœ‘ˆ-Á§MIòÀF²$kÚjüõ·±tåQÉuúÈy²´ï¥”O‹R°RH7]ƒ>ÓììÜÃèìó-ßÀ¸©ÂÙítÆèŽd½bI´Õÿq6_õ¡ð7(•b) Š„í쌗¼žð+\‚»Ð ?ñWëVð+<ó´+5ÃöÇᦙï+¸#^h[ûMë–¡Ô ÑUÒ&Ò”5jÊ/cç/)f4¡ÄË=Ë{ Жiè…)n™Ú·÷éccåœ £y†Æ‰e³¥Ò â…¾‘RrQ_œ]!Ý–å)»¾•J‘ð`ñ3ˆ 0Ë›ƒ&e)‰Óq5êЉüÒòoºÖo<†-Z‹fkêwèFÖæÕbçÒ…¥Òê,³ûtì[§¶ ‘Žë¬¬EÇvL T‚wÁè÷»`ÔËÉøéוYN?-ß&–Ï—*&<;Ñæ9ªÆI:Þ7sï} '¶ü„WÇ}±&®ÿñi÷¢ Í!ñôú«m«:µí…·kf©iH°‘ ”†€KËYµ=ÓÍïLÐv£j? á2ðÇTR öT_wJõÕÂÙͶð‚þÎÍFÈñ3&À˜ðZi»ðÜèÙRòÌçBÆÛYiSÎÆ«É)8~! =Âä{;9æ–4h'eáºöÖŽ(⣒æAqáùVUö¥HIH¦ó³»Ú?..,ž_?sØüýJnÃÂ,µi­‡EoR,­£ç)ëv#mbG„XY$¡Ê©|ÕÀf¯ P¹4©¨AÊ"ጤ¾Íëèþ v‚"I¾³-wBžpÞ+oQtïÐÀªÈÂj¥™ËÒ¥gп½Ñø¸cHŒÙíþ±ñœ¾EËI\ÅÒ¬è¶ße÷\«Â°¥ç ¬—ΆwÌtXaD„´Ý m ³l'M )æÊÎHU\ÜÚ%J1Ó‘îÈTf½ÛVªj<茚Ôåéž8rSu#%wÍ;*J%Á¦0=Cz€r±¢¯ 'çÏ]ÿ§å¨yù×®yã¤YŸ`kªí=ª‘¶Yº/ÝB;€ÜžÞ‚Ÿ“%Ñõlx,ûå_&P–|C"i–Ó*_±#j,»îȉ6Ï)‘h€¨nC1ë‹Á’÷ìK2·¯e]mµ9N¥‹<ù‡ªmÕ²O–:tléÚwg%ežLÀ™rf+½i{~S'ļô,F ŠaÿGã¹±R›>§¿_-)¢lj´wG͇xï9ý«â³%`L€ 0&à&¹Xþ¦ye hdáå¥{Ž´°å𫯵KühÝwɯ,$l0O´ÎÏm×H?Njû›ÆuiPd.¸„cÒªDvƒn¢.Ô&眧³Æõc1Îä«UCΩ½ˆ—žDw7œUlW«Á™-õhõÕí5°ÿà%ý3ñNë3µk{A™=ÛÏW+°•—(•b) JeÔ @T­ ÝãJ$ye“ÑàW£<]9igp‚핲y>ž}w³deBl8MM¶rùûEþpŸb_kõàcÒ€s:ÞyêSœÈ1¥%à!ŸK1Ä`äÝò±•HÙÊó TWÖÞ$Íú iªRÂéÄÑàgÜ “…ÆüÑ0ã—d˜ËXANRlÅò Ê ³@£õùã—-HËÉEêéÌyvæ'›%IZ²©E%Óf„Ö —’‘ˆWîUâs(m9—±_ŠÛ~ÇÖÓéÈɼŒ„s0dô<)ˆDl=¨*Å$Ë2ÿ98o ì?Xü?vÞ%~ßzýðÊÿ³w&ðQUgÿÿiö,LH!$„`‘„D¡4Aƒþ ÅÆšVpƒ¢ÒºU,µj)_pÃjAQ±ÅB¥ ¯"bA‘­Äׄ²D$Æ „„„¬cÿÏ]çÎÌÉÌͲ<‡¹çž{–ç|ï¹sÏ=Ï9Ï™®¨–Žà‘Üû°ùài‘ƒÐ‰*-ÚŒ×ßÜAê»+8p2%'ýx!s7©å$Þ§¾ÂÊF‹åžyDó[jAìa—ˆ@éÿ.ÂýO¯Åþï΢QþM©Ü·Ë“!âG_Ýæì&¯‹jà7Ï-KðÇüû±fû~˜ëš¤$­§ñ釟ÊÉãquŠÔ'¸Ôϯ³ß·ê¥É·¿æ·ªl&翌ý§äiôqSOý£=›>Ä~³õÕ®ßw8¨û0ÒÎô©4áÓ•käK×cê5&ýhšöÿ~ªö‡ ÿò*=Q|wDMOÒ.ÔßÑŸÃ:7óG>ÃgÏBÞ´ŸŠÿgýú9ì9ÞÆ´¶º2|¸|fÉiò¦ÍÂso~³üÞ÷FÍô-²yÓflÞJß(.ŸË|öæs¶²¼³§4Î%¬(ÚAå~†Ï¶êü'yvvšØK§¹ño0to¸ëÞC,usâ@oh<²ÏnÓäTYˆ=»öØüß±})ýv9j»Æ[›pþ| ÎÓ÷Ï©SÖ±sUÇP8]S¾ÉÎü k6}…Jå›I¼@¿ßËà Ê~˜„(»Å2®¾iŒ×¡ GÊp^ûÎj<·ï»›eÇ'#B;´ÕtsäñœŸL¼…êäjšjmðgñÙ;ï¡àøiq¼Geuü3<¢ŽùÉ ½•KÒÑ…,JDå>Ô×UáäI9ô¤ghV¸xïÎËß®ò¥ÃÅíX„ÓÝ‹æbÍ>Í»Ž¾oß{ú1uÂVZZÕt´Ñû*ˇ@Àˆº¹[c9²ö!²ýIn¢â‘9,ìnîBa™µÊ×-x ×÷Õêì•kM8°Çºªé†qC” NW˜ÆbÅÒIÈ{„6@/{?¿öS¤¤ÇàÌ#ª9½¼—#+ÂÅW§¹ó….CÀ7Ù¤xØ,®vû ss>@Ò]‰%··ÝŽœÖÓt=µ¯CÔ¾¤—µOþkŸ¤9.Qá¨9'+O£fbì¤ ¦—ÙXÚGLÞìó%ãó%:9ÓÆ‚Ó†oÂïÞ_ nî¡Í8ªÏgb›Þ½è—ÈY$ä;¯íYJölÛhۡɸ‘-%BGä½|§H6_í%[;w*>žþÞ{r¢¸gTŸÊbrwâØ—#œkôo°Îé|ý£éªh Av Ç>ö*¦o¿ëÅ÷¯ñÇÛoƵqè≯óG${nYô>Ï}Xœ½²{Ùøi™6¢äO™µ·æXùy»>Ž¥r\8u…ë7aîú—Å€pZ©T#+•„€Û2\Š(ÿ5Ú6•L´Ïœ¦{ôð7O7ûÀÖZ8ð56ÿê—xE¸F¿ŸP~?…óœ|dªsM:þùu÷7G͈»àuä}}+Ö–Qêk0w"½?¨ÎáTgù­¼×„a&IYÞ®ßw#ršNGÀÝç[Ûv=mgz•þï©xS苟3 )¾Ö÷¡jýëÛw,òÓW„ª´Šû“ƒsÈ,­d‚¥MùÛÙGk3EÌ.ÔßQDæc× Pºi~þ[úÖÔº² <²í}ä½ô.îÏî§½"úϽ‡Ûïx^ýÝW"T,{ë—}ŽW·Ñ†ßíü>,}Üû|¹ç¿|YB×ÖÞÑç&Í”ûÐÖ‹ô­²~ÝmXûÏïâù·¦P|õøøÁùx[ÓoQ®¨Gê—oüì^‡I2FXªy²§C ¹7Üιwh£ôbæ–­‚ ÏΧ›{ø¬eøHc޼=ãõÿŠÉw¬r(gý#4¦!‡ÆÏù ÖΦÆ)ß±¯ÐXªðÍž8i´èж¯mÞ%÷¼}¿Ão¶«qÃu¨;@Š›yâ;&>}8úÓü£Ý$‹ÕÆ’ÇnP•'J¸u'X FïHyýÚ’çIŽç)Ÿp¤ŒŠúƒ´e…òeEÁéàþIÂdlÛ¾¬3YDhjÅ?ò'áõ2éLýKýÜŸÿð}ù4¯Ò»u˜b21t]0÷Š‹&jðÊ=7cuâpºO°½O‰3ñØO’(I£÷U•‰=Ýž@çZ.Ô p…EKRœ«@á6R)j8|ý],™‘âDÊVT«ƒM´¼sˆ:Òä$¾Ÿ»[z›§†6‘S”Já¸çÕ÷©³ã2=_ì„A–{r¤:¡FÂkæ;í^^òkEïƒKƒÀß×VWŸ{?>¡¥Òãh@EqªR‰R&$‹ŠáZÈÐÀc³†[3ÒøR²û«÷¦kñç/ßÁ=­u³FŒ{^zoýj¬]'Èûõ±–É>&`K jÈhÄ[[«R‰Ì üîÝM˜b£tvÑ6•gÆåïZˆÃž)>~Ö¡íøÍkÕ– ±¸!Gó,ªïyàº9 ±ñÅ©ôìj>:âù ù‡¸ÿ›ÓV½ä,~s}ûáþ ÿŸæM²ÞtR ÔÔ[3Ͱßwk&ìëZ”FØ?c¶õpñ| •lìÚ.Ù0“&eÑ$ êWïøÃ<.ZQˆÇ>þ»¥Žýo>йËv‰•™°ô}ü.·ÍQ-ÝŠ,Ÿ…_ËV¤ƒI¾UVùäTæ]Æ´¹kijL²äðg%‡‚å÷SÒìó;ÞþîÉpwœ¡kòoW0Ú϶×V 4ÀÒyf|ÅCÜι{Ødºdt×í¼ýUê¨ñF{ÉSÿæªjœ;×?÷©©iAïøHêë¨P²OÛÖ¹§u¶P8uò .4\Ds} üÃc—ÜŸÆY/ñ˜½[ÏŸ5ÓB„shh¡oI²ˆÑêÛ ÉIm~O¶ÅÄøõ&T9ŽŠšLáÛ‚šÖ $^•ât º#ï«ñ:tÞ”Êó«™ÉÒ Ä­ª<)J10i W¥±ÑÁz+geO%%?û=—”ðNyô €©o"ý·—N3#Ùþ’Î}Cc0l¤±Î¹Šç,: ˆ¾ZsÞms!¦u%T]'ù†#¾¿òâ×Ä íxu¡€&Ü]v¾Ú|ÝMd'°qXHûª˜l˜YãwVŸ¯ GAJç,#ˆ¹\iiƊ󸵾,W÷%ŽXõ7¡óÕÓíߌ#ÅÒçäß¼ês<˜{›¤.ªJb_˜ú +~ôß“Âê[¥’XÏ5a÷»’R ¸ßžF‘¬yfÝý+\·|&vS膵{1+CcÒÈMYd{z…Û„bi“ŸtC÷†Û¹îí0ÄR7'ìŒ.Õx£/%ÅÒXRlïSð´4î’4Ønï"ï‹ÕvŽ4f%|GÚ~K ɬﴶ3ñvŒÄ‚X7³íÈûꦭèSx‘!þøÁ€Hq•RîÑ/„±cL€ 0&À˜`L€ 0&À:ŽÀñÝ‚úGpásãÐQÿ×J—ɨä?>>"ùëNà«2É[S-_Ö|úcÜDyòÙOpX2N"ƨ?øwüdÊ­È›r3þVt^›Êê¯ÛßÝñšt>ŠL½ûõš½¯ñ8>Ù&†O‡1Jßü(Gº^óñû8Ô(ù…¿nÉ"DÔ1y-Û;C,í3áó!`èÞp;×½†XêæÄL€ 0&Гtˆb)ÐïJô„`úNø/ø…0vL€ 0&À˜`L€ 0&À˜@ ³;gOTÉ™Ç .ÌÑHI`\ÔÝÉÈü»½K X/Ð\¡Y×±)Vó)Φ65kÒ¨^2A÷ð/%ó{ŽW_ú b[4š)5žì©6Ã,{ûÄ虤@ò°ár Ú'J°Ûªãôe‘"žÙÿ%vìÚƒýGÈ9®ÐIMA^`©Ÿ1‡¶›€î ·sù.xe»ï'gÀ˜`]’€c/³KVƒ…fL€ 0&À˜`L€ 0&Ðà \Q‡â]„ÄÑHÐ3[ÛÚRLj®¡ö¢ä í‡Q@É9úÿî˜ggØlà œÅg«¿–SÙB’'aéÒd\D0qTJ•¬{ ¯ì•ÒÜñú" £} •òms’ÎêÏC®F …”.¢¦‘L ÉõlK–fYŸU³mߦdé ~ƒ93²¬æý„KFY*Ùò±ã½7Üιw\«äœ™`=Ž/#êq·œ+̘`L€ 0&À˜`Ý’ÀCqõ¸ÁRÕBýá§WÉÀ ÄËá»þƒóâŠÞ¸öÿÉ¡çÞÇSoí¦…@ÊJžz|ö?¨û69dIƒõ׿^ës¯ÕìÉ*Åj<òž´Ÿ¦ÌY†{F:*ž9ùjÖCi¼Úrƒz«5@Q©´7”xÝ…,øo N¸™9×c\Îp•Hµ~Ñ<Ü”¿ æÿ*u¦Ü ³ÔJÊþ!`øÞp;çvÞ!-’3eL€ ôH¼b©GÞv®4`L€ 0&À˜`L€ t;W4¢tŸ¼o’³Êµ6 Z¹¥*Ÿ²f?…ëÞº»éZᲇ‘óÙhLÿ»I\ɤ$qûØX‚E·>/Eõþ<'‹ü´ºˆ\€_€xþø»•ð÷Õ¿ØpV­z‡ëÇQ P›¥ìk8¬2Ò)àÐߟÁçJøÞõXüëûpÿìûéÿ£¸gÎËò•#˜›7³f?‡’FeµUétô[e¿(%#ûãp Õµ÷gOçœMñð?ï?‡ùrá_“‘=E 4ÊR§8ò2£÷†Û9¸{¹-rvL€ 0JÀÍ©==”W› 0&À˜`L€ 0&À˜@—!‚ŒQd o¯°jé(Î’²&)ÔV¹ôߺ˜åú44·ØÖ,b^½·ß²ïjÐâç‡ØþW#¥¿/Þž¶XŽÞ´OR[®µYÞ¿IŒXÏ·Uè');‚’²Ó¨i}D¼2 MTô”ÐYEy­nšÚ ŠÂ©Í­ºQܼ"b8n$eZÉJR¶ß6ÎDZ ¼,Ý–€#zN ÷†Û9·sϧ`L€ 0;¬X²§L€ 0&À˜`L€ 0&Àº*¨„A$º X:‚ƒÇê•¡,íjTs¤ˆv’ÜÈ!1²Ïö;pbZÃþkÞwˤóøŸýInŒ$$Üø<Ö· ¤›²uþþ¨?ú1^X¾K ŸðèÈŠŒÀ Q™CA¡½‘EŠ2OWò%­ š“a]U%¦8‹‚ÿ•k5Âa_'ÛÂÜ9Ój¦êqQsê –îHÀq<'à{Ãí\âî –žßANÁ˜`]€ÝÁ®^E–Ÿ 0&À˜`L€ 0&À˜@Ï {íZñC&쨺ïnØ‹;2®×T¼ Ÿ¾½F>©£bÉßöê£/ßü3jäT3~b5‰§ÉØÁ1p¦h”SÚ­ gdÅÒpÜüÓ‰HódPäè‡ñ·Æúå¤;ðì8• }}ÔäG¶`­°'¹Ì»nB¬šN óøokŽ «•—8‰=\G°” â¿í%Ð÷†Û¹÷~3Ú{9=`L€ t~¼ÇRç¿G,!`L€ 0&À˜`L€ 0÷„ÃìŸÅ‹qkÖ?ç¶–©éö¿ó;¼°W:Ÿ“‡­I»Æ³Ø¿¯ç-j|ÐŽCï<ŠÇÿ.¯Ê™T–IÑZOíÁs/Â{NiÓj²±ó6µ4É!õhm´»H§WÿäN„‹Á5øã/_D©¼ÿÒÏïÇ·*û3 ÆÌ“Ù?s-K*Ž”á|«f¥Æxû¾Û±YÎ#|x2"4—a”¥F&öv£÷†Û9¸wP›äl™`=Œ¯Xêa7œ«Ë˜`L€ 0&À˜`Ý›Àµ=‹é›oÇzZÙ³þ‘ÛñYú`ô©;M{ÉëŽoËs²‚²JˆTHß¼¹÷¬Á„'F-ÝùnÛתÙ<¤ÏÄ?—NE &¹ḛ́þãMbºˆ›ïƵ}%•àÆŸf8W˜ÆbÅÒIÈ{„ò-{?¿öS¤¤ÇàÌ#êÊ©¼—#+Â*¿KYêà‘[ç‰õ‰OŽþ&`7ÕÏêFcÉc7À×®~FXZód_G0ro¸s;ïÈ6Éy3&Àz^±Ô“î6ו 0&À˜`L€ 0&Àº?ßD<¼iòÒ¥ªÖBFQ*…çÜ‹þórQ‚Y<9~ÙQé"¯SÂusbãê{+š¬SbIGŸ 05 w¸§sWMv’$>wþ¶ô69J¥pÜóêû¸?Ûq(—²øƒtI¢«8ðµR)óga힥HÓ®à’ãÂK%);˜€{ÃíœÛy·JΞ 0&Ðc\ñúë}_\\޹sÿ(VºBB—®üwååÝ¢Þº ÌÃ[$9&Ðs ðïHϽ÷\s&à-ü;â-’œ`L@"àöïê-¨,9ˆŠ– _¬z'"m`oçëQYU…sçjq±ù"ZÉ ]bÊ`ÄFX÷8rž¸c®´ÒJ«C‡O#(Ü5´à*ñê!0ÙZãs»àƺ³8uò .4\Ds} üÃc—ÜŸòs£~ž²t[*ŽèŒ·sgd\‡s;wͧ³]u»w6ÁY&À(ÏstlœÃµËPUyR,~`’“Í/ çdnÁÜ8`L€ 0&À˜`L€ 0&Ð9\áƒØÁÃhu’›.0±ý…ÿnÆ¿Ñ|Cc0l¤ãê$#E†öFÒ`Š5W™zÊÒU^|Í»<½7ÜÎó÷”¥óœø `L€ tsl ¯›ß`®`L€ 0&À˜`L€ 0&À˜`L€ 0&À¼E€KÞ"Éù0&À˜`L€ 0&À˜`L€ 0&À˜`L ›p0…§Øìêõî.õðÖ}`Þ"Éù0žK€Gzî½çš3oàßo‘ä|˜`þ]å–Ðp;ï w™ëÈíœÛ`]¯XêjwŒåeL€ 0&À˜`L€ 0&À˜`L€ 0&À˜Àe"à°b©_|ÂeÅ;ÅVU3ŠŽîã »x.Ì£‹ß@Ÿ tü;Ò n‹Àº8þéâ7ÅgL ÓàßÕNwKX  Àí¼ r–Ž·óNwKX &`˜€ò<Π‹%äK]솱¸L€ 0&À˜`L€ 0&À˜`L€ 0&À˜¸\X±t¹Ès¹L€ 0&À˜`L€ 0&À˜`L€ 0&À˜èbX±ÔÅn‹Ë˜`L€ 0&À˜`L€ 0&À˜`L€ 0ËE€K—‹<—˘`L€ 0&À˜`L€ 0&À˜`L€ 0.FÀ·‹ÉËâ2&À˜`L€ 0&À˜`.Xkp¼ø¾).EÅ 3j)v  ‰±9×"®—‹Ôu(Úò/lÛ{Mb¬@¤üp&æ\E9\á"]²4£ºªåÇŽàÿöÅÐÛïÄ5±þúiZjPRD2Ud‚è¸ C2Ç`TVbÛåéçì4´îd!>Ú° ßžxPY±ƒqÓä‰H¥‚õ\£”¡ÕW褵Õ2ÒaòÓKìI˜µ•ÇñŸÿ£´äΞ;/²ˆMDÖµcqmz?¸ºcbIž°÷D´N—Û¹þÍé~íÜ Ï‡>*eL€ 0vÐïµ#CNʘ`L€ 0&À˜`L€ \&-åxýÑe8¦S|Õ– lYìÙó19Ýä£åÖ?ùv]°½TõÞJìú2=>& ‡¥úÖ¬Ùˆ¢Ãf›„q Ít®¯Xj¬Ø×ÞÞj_:©À±¢Bl|4^x3buÊÓIÔfPeÁZ<÷vm¼Óf¼Q´Ë)ÆSX¥+£5›ìyOarJ¨5À€¯|Ûëxù½£Ž)I¾Š¢lH$ö¿ö{Ç‚º`·sÝ›ÖÛy{ž]HȘ`^!ÀŠ%¯`äL˜`L€ 0&À˜`L€ t–&ÔŠb#kÒ ÈHMBD€Çv‚ Û$åÅö+1hñ|¤†hå­Ã§Ë¬J¥Œ[fbBF,N|€ÕNodz+¢°pîh‡•D-çK”JÚœuý>ÒpDÆø ¸zp2bLAh¨üŸüýC[vaÞQ˜3¦ŸnrOëJ·Z•Ja™˜yÿÄ´VàÃå«qˆÊÚ¾b1Â_ˆì8»•K²ŒRYÁ ³-µžÒö ÓWœÙÆt}fi8/F’…q×d")>ó1|²b½¤ ,ÛŽ7?JÁo¦¦:ddˆ½C.]0€Û¹ÃMë®í¼=χ$`L€ 0¯`Å’×PrFL€ 0&À˜`L€ 0&À.3À¾˜>{6b†¤@kñ.ö–9èß{¹¼2ÆŒm…'ªQÚÔŽÍe’ìÉ·ÌC~N‚xb'‚[—ãµM¤”:¼ÛK€›’l0~½Ó1ù–¾HJOEXõ—xf™ÞJ$[. ã°èÅàï£1¯gŠÅœ1øŸù+QEÑ›j…Oíu5Øöúf9“4Ìý}>’…Sf-Áòù+DåÍÆ7wbÔïnpPšI ãqï’_#EL'gåÅCßá·à®Œ>H ·æK,žÃò‡^å«Ú² ''¦"ÎÎìžöÖBº°Û¹ÝÍë¾í¼=χ$>eL€ 0/¸Ò‹yqVL€ 0&À˜`L€ 0&À˜Àe%Š”t[¥’"N˜›/ŸØ*mšQüåvùJ&¦ÉJ%%]ÊS&ŸìÞñ ,ÊùèÓ+ Ù9YH0…"(ÀÝù«>¶J%%Ï‘¨œ´ÿØ\yÛeÓ~ùSe¥’œoH ¦æÉ5;ýVï´@wkå4cSl•JJ\¿$Ü4I¹cµ¨·OñŒ±W èÊGnçÚ»×Ûy{ž-#ö3&À˜€w tdßÈ»’rnL€ 0&Àz0_ž ÒƒïW­zSs«óº®Z)–› 0&Ð… XjΠBOþ–Jü_‘t!dL:¢íãøDchpˆâÔïÛƒòÛÈ\›ÝÊû$†ÏkaG™œÚ·ý,UÿGÎ,CG:ˆeJ¾ŠÂÈÔ.âË‚1^Z©eѧ£êk_Íy3ªNèÞ1›X|bK€ÛyOiçü|ض|>cL€ \Z1þ”óé’ ×b|ßlU&E…Éʧ+Ä4>‘é˜õpºšÞRoFá`í&aO&`ë²5¼d’4+¡Ì…›ñaÁ¡Î‡[ZåÕÓnF†Iï>Ôáßý¬ÛwQ*7c žüEÕ…+ÜÎ{J;ççÃÕsÀט`—’€óžÎ¥”‚ËbL€ 0&À˜`L€ 0&À¼JÀ|àC<»b»œg<òŸœëD™aUÓœ:C«p\™x„„hW×=©‚z™ä•@¦X$¤d"ûG¤û“¤Ûµâ#\÷b>b=VËìÞW¨*Éœ—‹Š%Š¡ˆZfÆyËÖ¼tǧô' ’RIç2|BL1ñN„´¼ˆ7¶ùGqäT’’¬Fê.”ï¡"Y)¤—‰’=Ùñ^XÌØøâbl/“"ÅŸ‰_Ndì\àvNtzB;ççÃÕcÀט`—œ+–.9r. t>uåðÕñ³ð MÀȬ$þpqv‹,58¸çÌ-ô­1I‘ü‰ç ‡3&À˜è6„÷ÿŽ/°ãÐ1ªR BC—< ¹cR Œuw›ºrEºº’­V¥RXø}ž­ù;Mmû$@0'¨JÎV5h®X½„׈V ¬º(1Ô[ãFáŽI»ñê&Aš œ­b{ɹÆãŽûfâ"­+rúüµÒ¾H!±ò~DAHJ¡šòªÄêÇ«J*Eà†zÔÊþ&±bÊçÇYÃQ±”~{Ð(–úŽž…™ëáãë|¸Eغ)¦¿¢ PÊ©Á§¥RFþ<äJP.òÑ n瘞ÐÎùùpò¸ ®=yŸný7Ê«šîÐÐ8Œºéz¤ðX†Kn|±›08–Çc¥m·ç=¶ÓvÏf½œö–•Ä|dí'Pup#6n¢MmÃr‘ÁŠ%Z‡’ÂbÔÒó=øj$(bË|´v½¸±qv¿ V,µ¿éqL€ 0&àMôÑTüŸêORŸVƒã‡"%Ö~àRS`K5û½­ÁUWB¨2SßÉ»P“¼Gxivôú'c×ÛÚ*6a )–¬kl¯{zVM“|þ½ëß(>zFü"VP/„FE oÿ~è×&ÄòäOÁöäøõ%xcÙf™@æºP*‰‘ÃFjjë¤Dmœ˜h·r§G÷Ð÷‚àÂ’aÒ˜~“½ûWx$gFåù í¥ü–ÑzjºG……EÇR|A±TòS HIRò’²©;Y*öï…³”þR k-›Õš’0Ôº“õB¾’ßÂæ2)Rò-÷±R© ^âenç*¥îÞÎ{îóaAeÉaœ¨ozw.œ PGFŠð{'9sáûxö]Ê©|<„ˆ?$Å’±|iü²èýž:3U ôûýÒ¯Fl <¨ÙRƒ’¢øæh)*N˜QKóè§8 Ü„!™c0*Ëþ£ä˜KàÛ³T=Toïd M²kmGyÖ’­¾Úòb”œ!¦¾½14Ó¹¬Ömû Õ‹²5š®m‰ÚŽÑÚ.U?FÝÉB|´a¾=×(FˆŒ›&ODªÞ·Á±<+Õg¯ Õ{,µ×{œ¿ñTV½½Õe½³ç=…É)ŽŸ‘–êbüõ÷+!Y[–² ÉU¨:]cE…ؾ£O>3Áæ´®t'–>¿Þa)Õ«±ëƒ˜»8I!.Åá‹L Ý||…(úP V6´U•Úu×Ì ñÖ¿±VR ÑóžÐK~ÞiSca²dý÷ã_Ï®yoYj&À˜@w&@MÈï/±šCf`ÑÜQN•梨ß[(1áÞ%ó‘¢Ljrö.ìÎütêfþz³ªTŠÏ™Ž©#ãP{êŸö’’§¾—/SÍ^鈀"10˜îÏ¢ŒµëEä0& hƿ׬U)ÂTÇ î°ÙHfã1!slþ¨;§–j©ÏßÜhA3ïBcÖ luå…øêL†¥@d bbºE¯Æ†ÃJ±sf-D‰ÒÖ10 7å˜ðÆ63êw®ÆúÔXLÏ”fõ—n³–=i,âìÊj®7ã\s b#­ß,æâ­xm­24ýMÖkm‰¢½û6¬W/ÕŠò’b4ÙܲVXhŠ[rªÎPØ«…ua·s»›×mÛy;Ÿ;L]ñ4°7IMc‘m:mW¡ñ‚hEIH“üãiC¿{‚KJUë 0”¯Ñþ¡œ.cü\=81¦ 4T~ƒOþþ!Ž u»° öŒÂœ1Žï­œ!aÚJ éh?»ÔHÇITí(Oàdu5ød™¢TBíúËÖˆû ÕK@ÓÜæá±tö :Žƒ}Imוnµ*•Â21óþ ˆi­À‡ËWãµ¥í+#ìñ…ÈŽ³öoÚÊ“¯' Õ¢ÏÅ.¥ T:FKÏ]¤Ž%¹¨`$÷ ETˆuÆ“]’NxO³íæ¬@ ŠÞû›ªTÊž½€´£òL'Úˆ4.)#ÆLéÛ4v -8¸éïªÆ;ÿ Cžfºå׈îõ&^ý€:«ôãú¯Âqøi¦{3§:!H‰ Øh©¢UéÅ=>©SÛû!f›½WÎü0oÑ4‡‡>€C:¡|^©$g˜`ÝŸ@ H)‘še7kO¨xõAì(sA€ß…‡ÌÏ|{R‚”ØW\µlC¬]}šj|´L£T2Ý“«1·ÑÚ×ø)¸Ì¹”;‡ÞvÞ6²ð Ðø¾•6RÝE¬{e…z¦õ„ŒŸ§¦¦Xƒz¥ãþ»²ÈtRpzž{¨ñ‰Q¨.«P-ldϾ):ÊêÆòÏðôóŽ–?v½±»ä¢'݇ßL´®Ä©:¸Y4ǽ‘®‡ÄÄc@l ¾-:ª–%$›ðÐd˜¼0Œ:m&FE²Ð “ SQb<"Ρâ4 J .&÷LÔ°Bqâ‹•´×“™Ìÿ™<°mÓtÇNËé–7[ýŽ·†zîkÔnkµs^Ý©—‡þÊE#ìõrïjaÜÎïXwmçíy>)uµ dÿú\'ÍÛ·þJ?4—¢þö&ÿ0ÍÆB’²5]JÿpÛtâ™±|r±èùéäGc'~ øô ±YüLðþÖ±”À„qXôâ 6“ `ŠÅœ1øŸù+űѦZi Y7s ´‡8‹'„{£9qšbš–TŸ:Cs %wñüT×FÀBSýC#ÑK´¿kAmuµ8«10¼7Bý®@me JhS\ ©f{õI$»è&UIÛ\{%GN¡ž4·>!}14]gŸPœ…Ê®ªÂió9Ô76‘œ>ˆìŸ‚”8½NmMaùžÊ£ã÷ÿ%Ö™•’äFÿZP}²å'ÏŠ3}h¶ð^ˆì “j7^ÉÛM¦bôb¦ˆÂG&À˜è’„•÷ª¤Ÿd9~X•Ø ÞêU°­w¡¥¾åß}‹sbÁ¡áë‰>1&(&õ-5¨®£AnŸ@˜hÆ¿ðÞþÏá2zÇRÿbÈpë>†¢ž¼û$‰-Õ8~ô[T×7Q—%!!ሠŠXû>ˆ\ÁæÚJ?^Zy)@HT<’SâûÙÔo¨¥¸GŠä^ËÙS¨¬®A˜…êB{EúÓ;½Í>U)¬öÀ窉=a@û·ssZ(ðñ §ÆúýÁ”[}0±XûþB NïGéY Ãã‘™ÞúWöq„~X)J+„¾ ݵð¾¸JoÅ„óªò•ËBÀ=-dl¯éL™yxø®<÷ÆvºveJÏ=î{7ÐÌp]çÓöÌà^A¶¢°èDÊŠ”6äêÉ|ü!íà]L&òŒ8ëÀ¤ÑèZ¥ôôƒð[ö‚hz²^£, ɘ€_ÍÒ‚"¨D’ñ‚™ÌÛK²Š"¦¥fýcRt÷dôm嚈[„RIر&ávîpSºi;o×óá© ÐJP½gŸLÛ}þެÐÉE~N‚X¹Æú:œ:°SݦÃ|¦ µah&½M¯È«rÇÃ|rþ~Ê S%D:Ö"+•€Üy·"ÁÆ\œ~B`D"Ôýåls´=s|cÙ^·=kyÂÊÅD©mÞÎÏ„>SÉ·gı$ê4!eh*"Ûø©ò¬^Ö² ¥£ÉJ¥ß” ª^ZÛ«ï`¤&8y¯ËEyÌÁñ7±7åj®< šåÍÈŸjkæ7$SóÒð‚°¢ø´£I_+9éa2Ô¿äѸzd0Š…UÙ×ø®1ÛÍÕSöñ9ð€@T øÅš+ÔNˆ’:+ÿAüt”ã²äZÚ'ì-2é¨<J|áŸ3³n¹†føJŠ™Ò­/I3þäHõûÖá™}Ò‰:c²±ËÿŠ8ceÂC Яøxc“bc]N8d:í1ßny¯ +û´., >gcÆ¢²à}Z*«Ì•ÔF¦Ù‘SðÈÝÙ63{@2¼*Ë µ l›Ò³³ºò½X½|´ÌÛ>©M`O˜ŠYu3{ùœ 0&ÀºÁ„3.|oh¯ee¼T‹j|õônN4¡ªL3XªTÓå»°ÿ~o ™n¶{?ËiµïÎòÏÿ"½ûc&àÁÛƒðõ—=/UÝÇÐãwerrïZ¼°º@ÉÎz´{¯Jj°sí[ذS·Ç‚ÍÂ5IVåMcùv,Ô®¾¸P€—/—EùÏ[ˆ·„U ²ÓíÓ(Ž øúk¿$û'ãœ*•’j ÙXòr¶ab3§`ñ’’âø<Èêˆð½“˜€^.¾”iÊÊÃâŒÉd.¯.4×FÉêi°+ÌmczÎpEìúõÃ䇟ÅšèenõG@}k‡õAB¬õÙ·O7öN<‘qçÏ7 ‰ÌZÈhh¯È(2ã®Nt³Oãù9­˜»Fï˜öžËØùR´·ÞÜέ÷´s·óö=ÖZv?_åÞ÷äÕ4ÁÈ›3^ÓhÀöEOÙìÉTðö2ÚeNrÙÑžñI¡.aèçë2 Mä=A«c… äFæ!Wg_zé¢ÝßÚcÖô¾mô+Úºn—µî©»å5–bõóòÊzlð쟬}X‡¼-ÕØþÎ ØèÐg2aÚ£÷cL‚ æFëåaºê’íxiهˢi_¿¹¿e;&¦TÐC½Q9žÈUYüY²` ì¨3Ѥxˆ£™ñeÁ Œ/)[•êGßÖ*ì\Iý[eò˜zÑEÿ6ÊgJ¾À›:üÒ¦Þ_ŒOõbŸ@¨Kx®¬ûÆ-õÒ o—ø’ ÙˆÃ_@q u:ë]/Çl¨U>*aØÀP˜‹÷â+ßÄòW—ã­•«ñÉÎbÔYhÕƒ­cK€šddß85…¯êcè@‡×c¡ŽRI(±`õßp°VšÕ H Ì\X¨Q*EgŒFî¤Ñ´9®ä*¶­ÃÂç>E-¤ö$ÎJTRKÇšÕ,<z˶r©/¡,ÙÞüü"U©$ÄSɹàG¬J%­]øY·­\*xªŽÈçÁH™…ìœL±L!°¾èCl(Pža9šF?/<|§§—h•JñÈÊŒŒxIŽ`_yÿ5ÀS¦¢Äy½ÅL&Á&À˜è’‚‘¡¾ë.bwÑ ›Z4—ï—MS BÎ Y6×ÔÍ»Åö]X‡OŸ[h£TŠÎÈÂè1™ˆ‘Þå~š]iÓ[ÊõôfRIŠ$O½7ò÷j”JB}GcôÈ4D û£jÞ«R}ê°d¶*•â1zR.ÅW{,X÷üB|RR£VÿÊ€0D«g’'„La «À¢iÅF/wú4vé­§¸pV9ËB–»ƒ/J:a&|ñª},Zµ¡(•Ä=e{Ë{Ájâl}e™U©¤íkÑû¿_ƒ“¶ÝBtìí|#‘”’„¸¸¤¤¸V*µ§¾>~¡ˆ¤U† I rYI£TR…¤ïì¸$¤$ôCBJŠK¥’˜„fô÷Šä£4?U`âU¥’*{.nç2tnç—¡õµ³Èúbüuµ4É6~ÒÏ1Bc342U3v"Œhq<Å„HÝeY\䫉åà-ùèoòädÚVä–,·ÙëÌÅøí_$͵„©c•Ú‚ª¿=„ƒÅÅ(=i·-Ð^sÇï~y¤œ{óѤ0sïƒÈV­½RûÒ¨oüâ"U©$ô‹ssÒäHflXògë-(c­—'é„~ã3ªRÄ„¬ñÙȈ‘¨¢ ߯~Pl_):÷”ƒçcožÉe¡þóyYÎ(DÙ­‚.ø÷îd9™!R|6ÇÍ˨«(•Üíßþ/«üh‚ºð½!»C¬Ä_÷V*§=îè[»ÞR®ìqwZaK«|ÉŒ­o¯R£EÉÆô[s‘¢³Ä ÈñŽâÍ£ÞnÖç¡¢Bl]k§ù ŒB25Ä šIZ±ãkÔNLTWuH™Õ`ÿçú³@U¡ØÃ:ˆ@ÈÈ)¸ÿÖÂDvlÊ÷®ÆË« ©$3Ù oÀÐ^ÊL‹jlQm›’iŒyã†i¶ßMoÀο>' F”mÆÇ…™´O˜ ±4+qIÆ(¼ôÐ+â §x²³þ+uýê¤aæ‚[14–ÌçTîÅ3‹ÖifX˜0yÞÝÈLPÔ—¨öT+ö—¢q¼Õ$^Ä q˜qßdÒ†•Ê¢íÉ×§ã©ß¯ó:Y%Lé¶ï|éKãy¨[”™.”8z ÍÉÓÌ¡Ív[„_AÁï9S}yÚÏL?_eL€ 0®Aà"ú…¯ EskÇþU„j2¢Ìë+Ùõ©T úðMíCfo=pÕ…5æJL˜A³0¯ÑÌÂl¦|›„È ýHn“¢¾¾ûj+Je©M˜¹h>õO”JXÐLÖêüåÕÒBhõac™|V*?q÷ä~÷Œ»Ki’Œð½¿uÙÇñržØ#ðƒß¼üR¢=!Õ—V\Í·±Õ>Ê@ŸF–¡ñ¼u3­‹ð&àx2ÑÏKýZå}ï£7#%RéÉòi‰£qï7Ò7õÿO`ýÒ°K4WVˆÏ¾ž€|½ý»´éÙϘ`L€ x™@3þ½FÚ—HXE<ãÆMþA¸æó1,g+žX"­¸É}èqÜ”ä¼ofMì*_k,{Ÿ…Æi^Û"MÖMË›¡»Ÿ˜¦¥×l‚ 8[~ˆÆ—äœbFão¶3g-EÑéÔmÅ*e¥5õÖFçÝ‚‰c9š3V’,ïäÎ5ØxXÊ$wíáC«u­½(™[µÔÏÜ\&k-ýŒ»ŽÆ¯þ$Œ_™ñÉ¥Hµû2Z/ÏÓiú‚…Ÿß“…a{j.ÿõOXG«¬ª¶lFÉ©6–²<å ðlìÍS¹PA{ÇŠ.&ÑÊP¼"ý%³ÍÊ—MÓEŧ û öoGÓwÌÄkSD“ß'É2Ò ²e¤C«·ÁW Š¥£bôSgj¹¯.¥·þÕë[X¯zæSçPº3Ø.k£Ì´ÙŒ¾ï›ïí5Å?öÆ‘Žöö#SKs¶ ³Œí&ò(éøÈ˜`L€ tÚËhòíRæ‚"#3Â;Ì·rï‡ò>O4aé¾h‘ ç—€9OÎ'3v­¸X]‰Ã_íÁÖÔÿºPˆU*ÄèÙ 0==Ò. ˜¡j¨æÒ¯ñáëkqHP–…œ¿oIÆœñB¿ÐÎyZ^Ë ¼«ì£Dc»³' ýCÉùùZ7ÔX|¦‹š¾1ù¾÷)¿ä¾5%©8.g *B”1*£õò<]½µóŽ]+ÞEð$’Péþ_Y$dN™Š÷­¥alàÀ7•¤X’ðèGnÖâyX¿|v•ÑŲCÒ‘¼ñãgà:|u[¤ÜV cÇ:œ­Ò µWÈ2HU«àìwÇä³`˜ÂôFE´ÏF%.ЋËSÅ’vMÑž{Ét˧ï®Ãæ}m¼„<ϹÍ翳΢îÛGØMʹóS¯1s.&_aL€ 0®@@ø¸1Ѥ¥°õâ,Ū-_¡zê@”|!­£ ɹFœáêºoWQ2áV.Ïx„^ŸÁ.ºÍ)íᣢ\3úîó1Âù¥d®WR.át!6¬ ÿ4fÆ£w[WRiÌÎ… 2ÁO³¢Y‘!P3‰æl•uâŒr½#Žjߪ¡Uw%”«22Óæ w7´1@¦é…Ƀöñh¥µ¦ÛçMe›mé|Ƙ`L€ Ø(ù×:È‹•;kœÍ*lû¸žœÊ—¶#ø‡¸m•“‹œÔ¶&ù —IV= {ë¥d"ûG{±X4Rz|„ë^ÌocÜȦ¤,ÌZŠ—æ¯·X8¶÷m…¨cϳòÊip…-ïÆ?WF¸ŽÂMÒbaeϫϾˆø¨̸çfÄY4}cÂphËV}ìgÛêïyR/mm§ÓŽI Ö´¶nÒ¦·ú[ägC½›cožÊ%JªôAݘ¼Ÿb?ÙLª«¡þ-M¦úÞ~¬”²ó P²rìi>ßžVa£õ˜5K@é·çU±Dƒî¾ŠaÇ8D‡;.Éð Ò¨šì5D! ˜þðRäT–â´™VQøúÒæ¥hCP|úGe9© aÊCj´œŽ ¸CÀƒ±õ×ã"›…ÕBŽm¿©Å£á* …|ÛéhæÍêG_P;Ñ£‘síÕH þÌî•+ä}ÚY†‹ä>êHò%ï0õ³¶EåL€ 0&Ðé ïƒHŒ7»>8Jþü» ?JK‚».ùÒÖÀI£=ï¾²e¾p@&¶ÿk3¶ª“G*°nÉShYð ÆÄÚ*Eêë„Ë:=–æz«=öKA…Vu§$âªîÓ[qÈ<×h6ÝnK„ö0³æíþ‚Öô°5oö1&À˜`^'P{ïÈ+Ñ‘8…¶p=qÕíò æ{pó{¢bG(gm§ ùt»è@2wǤÝxU¬WÎÒŒüXußLÙ„ Df"©yÊ(Îé£8Ó’‹7ÆM]•giÕŽ_™QTdÖàt™ò;‡zËÍb§R,D“›¦Ý•ƒÀVû_Ê&°ÃTÝÌ Ö .ÒiǤ¢ÇOÇ 12&‰AÝÂè©ßlˆƒÀÞñ7Oå‚”® ÂœL^o¨‡b3¨©Õx_×Ýþí•4e­§;uhØ2m'˜³³wŠ)cL€ 0&À  ÉçíT6‰Î»uCy ‰ æ[üÙfuÌ2#;Síx.GJIqiàû8Á·Ï˜&ºT–É1©òDfûHzçÎË MÁ5£ˆ-Fzö’@IDATMʲùŸ™‰k3”•þƒpÝXáz*B}® h²P4MÜ…]Ø]âØw’.ºù×h½\¤ó ³ŽIíÚ°Ûº‘‘Œq 6ÇÞ<•K72u”¸¼àß±×~ü½EŸm.‘Kè«"%¯Ý_Oú·jÒ³µÄM¸ßZW‡¢Ï‰iÒÏͶ«Í¢ø­Ú•ñ'm\Tˆ½*WÊè;Íê$eeSlxç‡Ü\oƹæ@ÄF†ªDÌÅ[ñÚZ¥±£¿ÉzMŒ’‚2€µdŒSø0\Ý?·Içø5Wcõ²­r^YÈÐnÜRƒÒ²:D'Æ"ÔOáØ€’mk°JÑügÌÀH;3ª`ìa—‘€ìHL²“´‡Ø_û†â¶ñW‰Šæê¼û´´¯˜ â„É?°.ûõ ‚:Ç`ÓN”þ(IN~G¼Q=‹Fgôõžb Eí÷5'°{Ã[ê&“;ŠQK3örxQ¸/AùÖ?ÓòmiÆNô¤ûð›‰IbbŸÈ,ÌóV‰À ¼±`9òý)2è%GʨªŠb ĸñé0ÌÔ}19&`L€ ô84 l|&6+6ðiýuý SH¸ö‡À¦µbúª-+ñòð‹‡#’f‰ÖÕVᛂBø^}=2Üì¿}÷Uî]‹ ¥}qSn&úEö‚?}ÜW—¢@V EI”M²øàêIS¨Ÿþ!É|ëž~½ž¼ ©&ỤÅ[Ö`õ>y †fÜŽŠssº«@ =}êÌÌ¡þÁ6©ì‚ÕËðí7S?ö¾’•[–Fê'œ*CÑŽ­¢©¿ì‡žÂd2Çm”™ ²'®àŸ8u&nÉ‚^ô­ÒXYˆÏ+ß5&\—imGÎúAž”Çq½K@Ø8ûxñ|S\ŠŠfÔ64R0l$Ææ\KíLùþÔ+—K¶ü Ûö‘'„"å‡01Gêëë¥h;ÌhžFÓ¹’ÈXžu' ñцmøöœÀ’LâÇÆM“'"5¶ós¸¢Ñ•¯q;wu÷¸»¢ÓÕ®™ªÖ£s2!ïTÔîjÊ×R‰eÌ’$ÉÒ¶4u41å«3!–>‘еj£¯–ƔĚÄêlÒ óÉsŒ‰‘9±ÅŒO__JFž%2(–&óÚú/OÎÔîÐÒJ›†‹®Á«¾Bi²Ð´›±~ßjQѶu™cο¹YI¤8––TŸúÇÏ2J'–ò1V/a‚´§<|Lš1)2Áüôs-˜{g.’"…w—õÕ(;| ƒ³ä²o@èr œ<{3$W`nÊ1á jÂøûzš<®X%*ÝfmKÑ“ÆÂY—Þ“þ­t¯è/) ŸýíEäß?éqátûpðãwÕ1ÅèñTžÚ&ÔT=Âã[s²]‹–º¤_¬”‡ÃLH؇Ì6±ÓÖj¦åÍFF¤}kñÁúáØ_ô mƒ­}…´–ƒÛˆCEÂ=ÉMxh²I»Æ ²#*+Bbâ1 6UEGÕ—sñÛY£¬òJF|d‚€?Æäßÿ,X‰c$Ï¡V≋?9Z…*-NŒQÑRˆWçŠ+zÜ2³rÄ Œ®hÒ¼ÇÔ°ûN`ÒsXôÞJ½ç(#.lÇÂö!oÁï0Bs&ƒ³p_a™­¤X²ÚØ•ÊzË\ŒÞ¿TÜ<]0‹·vÉ"HCr²,a¹#(–èŸ!¦”3¹äœô˜9̘`L ÓÐ{˜ÒG!…¨Vó ¼ WEê÷ÿµï¡¢zy &Ì?ŠVKŸó[Öâú¯uÙ‰?t[±$Ìô4òîk8W‰c; ðêNAa„PÝê5«²r4+þýã²qï¤ÃxmÓQŠyo<ý„˜ÆöOÄ ôß©S…1ÆLÈWïž:-.ú`ý'¾1Á¨?}Qš‘ÿs¤*K²)ÔU?HMÄžKG ¥¯?ºLì£ÛZEûlYìÙó19]g0°åÖ?ù‚Üoµ¦®¢~ô®/³ñØãSàÁ–`RFó4šÎ*¶£Ï`ž•kñÜÛÊ0¦œíi3Þ(Ú圥céâMÜÎÓävîœM—¼ÒL“Oލ’g ‹WýíóË×Rõ­ºz1™ˆ×ôœÉSup36ÒDÜAÿü–Æ?µë{„1S‡÷Kã·xóO+ÄqÒèÄA´¯=õM(Õ¥áÎ[2­zù‚áò¬;õ©Ý1%F¯LÜ×wxö iµÌöÕ¯`ûj¡oJ}§ r߉Æ|ÒH±ª¤1X/L7tÆf±Î̳ɞ´¦³–ÌÃèD9”6S•J”6ïñ§pÍ0Ô:¿0ë²¼zÚüMøqTLæ¥MÊÇ“O€ƒK›û™€·øÉ3FÚ˜lç`3´W*æ,yFêulâ1aö#øÕÔt‡—¼ðò˜!/¦:/²*uï2(Š]Û§r|í¼4S‘Ÿ6Oò…°§…%dãỲåTÊ!Yy÷áÉ?ÌT—Ñ ³˜Í ÂÎ ‚s&ƒ³p²§ª0¤ÔAv²Ñ&ÝÓŸy3Æs·ÿ?ÌdU bê\.mYî2Ó¦a?`L€ t-Ê;44@™ JòÓêú9//ÅSÏÐÿ»ÇØ)O”:ôîÔ:çï–¸QyxâÑHU.}Â4e+ïGåíŸ ¼ûÂú§"ZS¾ªTŠIûÝר­˜J™8Ïž š¯ÖŠ?r\òk uèxû ,\û iS®û4¶qÏB1"o>›7Ý K9EÌ äÒdžœš‘Ìœ÷o%BFçç#wˆT«R)¹Ô¿ËeûM䲤Ÿ=‡v$K“¼y5õyiÅÞ]ÍÃÃ߇i9Ö¾èö+Q¬Œ&©²ÔáÓeV¥RÆ-3ñØæ#jšãôv<»b'å~¶šÌ¥ÇhžFÓ¹ÆXžu¥[­J¥°LÌ|œžÛGó‘&ÿm_Aƒu'yPÅù¹ÆíÜ VnçNÀtá` êê”Éd.®¿íØ¢^Å®ô·v’ÆqÔžç+$mi–Vm þøWY•%B€¨^QÆ?ÕW)§òuÆLÅ>dYFrUeÂ8«U©”œ3='”®¬Z‚°O¢zæQyj*gž^°îbš2§`á‚™ÈH´¦S•J?"Ö:æ#D1X/ãéL˜ü»…˜95Ë* F©·î«í¿[c9ñ9r04öæc@.šØ5ýé‘(‰V_V¡*•B2&à·4Æ:Ún_™\•åAÿÔã]Ìhäß‘+ms¡á&”÷ðóyNWGYKï¾¾+žN~úûãßÃï·>)Ö²_¼´b =U®¬i@QÅyœ®‘n@Lx ¸Ó¥0…WUuF=:º±*XšQ[{çiø¦ÖVZè‹^‘Qˆ1 KÝÜqTŸ,‡¹Þ!4Ñ*†~q‘¶? Úl„e‘55¸pA(¯‰Ê FL\?DzÉ4X»yhee?pA ¹¾†Ll|O¦h,¸hñC=3ša%Ý”uÕf´øP/ÀBc^½$36º½HfçÌÂo™ð í).K³%3!æó-ð A/2=ãÞsn\ Á\Cuq"8Ú]2$$D4ߣ—£¦zù´7ŒGÚKÐ;黲ì˜@#ÐÔÜú½ 2ÿŽt±綸ÔÒþ‚ñ]þ=Y† ¡}VÛzû»ÎÜÓw_3™‹«§É)>>ß“q?˜ÚœiI}}s-,þ~°\l€DzµSf¡FÞèÓÔ™+qÊ|C}“X‚Ð;œä qÍÔSf.ï@K)–?ôЏÒe£Ïà†2qhF8÷Æ‘š>”ËŒøbGpý»Z‡’§3$öVmÊ·-ÇËïIsÉybŽfâdmñ‡XøŠ4ã:™¬ Ì‘­ u)ùx¹¼ê6h!nrs£yM犻±ÿ@ÚsÈÍ÷ªTqêë›d™{9ÿøô’7ú4¡Ô!I1Ð)ñ”™»uk¥iÁTah/“[³‘ÝÍ—ã] ¡HI×7“0æ&Ä“b©‚ÄhªUVë 25£øKI©dÒê&Û §)7NAÚ¦DÓï»w|ƒÜ$é!u0ˆ~LÚI•Fó4šŽªáeYš+ÈJ% #ªU©$ £Õ SóÒð‚°óé/p°zF8¬|"²ëÜÎiZ…Wž9nçÓB9W[>4&Ic2žvýi %–öµñÔ-ÏÓrìã ™íuÎÖËh:UiZ=÷¶ÇèØ›Çry6þ8’*ìVÿVP(igŸ;«›·v¡ü®ì=£½ªíP¶_úÐ@_$÷¡‚ã#Äÿ‚_cǘ`L€ 0&À˜`L€ \–š3¢RÉ¡ô–Jü_‘2&ÝÑl¤O4†fH×ë÷íA¹°y¹ìË·ã™§ãÙ§áóÒ:%˜ì%ÌÓh:*ÙÛ²TÿG®O0† vœ}jJ¾J¾~_œ°Ö}—•·sÒ{zðs;¿¬Í• gL€ tY¢Y+¼l\ÇŸLME…@0}'üüB;&À˜`L€ 0&À˜è¤ÈÚG­,ZKk'•‘Åjò¯¿VÓ'ŠVýdF½÷‘ázfàý;@Ù£‰ÌK 6ttœM»1š§Ñtvò´_ .œ%󔢋B”ý>ªîß»?’åhuE¹ÎÇKF€Û9àþsÌíü’5L.ˆ 0&ÐÍð2¢nvC¹:L€ 0&À˜`L€ 0C0çó!l .Û86”'ꌚ+÷âÕ”ÏÓ0L³|ãù TÉB§jN6‘öP6³¾(=‘mýöÍÂ]wÅ¢‰úy!ÏÎ#K*›%1©ˆÖ³md¡}•eFMŸ 4>¹Ä¸KÀÝ޹_â&ÊÅ1&Àº /¯Uê6\¸"L€ 0&À˜`L€ 0F@Ú7ËDûP…úywÞ²ÓU×R}Y´N–+3ä#A«(ñÑÌ9Õxµñ§ý¶$gFéiÉ»@R33‘‘™j»—¨Ñ<¦„óª,A0,^ªr/|AûSÛ;?ô–ê—ACÅ>&Ÿ_ÜÎ5¯Æ«Eïøs;×òa?`L€ ¸OÀÉ«Æý 8&`L€ 0&À˜`L€ 0&Ð9 4–ïÅâ%ëP/‹7ù¡ßàšX§Âú:1cß\kU›„…xfêÞhžFÓ9­]p?Ïfœ.©p•ð}³U™&+ŸX)ëZÇ\åvn˕۹->cL€ 0ïàKÞgÊ92&À˜`L€ 0&À˜¸ìÌ>ĪR)ùO>ƒì¤P¹üÔ°SgjT¿¾g¢ƒô/Ù„ÍÓh:›ÂíN æ©T³ÌŒó× £ø”þd Ðu;¡øÔK¸+ ¹+$øÈ˜`O€KϘK`L€ 0&À˜`L€ 0&pI Ô•lų+¶Ke†eá%¿F†I¥R`ŸÈFßp¶ªAW΋ çåðF´Ò>\m9£yMçJcy!)E¡R‰ -:%4Ô£VnrŠNÔ>Üέü¸[Y° 0&ðÿÙ;øšŽôÿ¬ $šˆ¨à†É)±(Òª—Ú--ÅRúG·AUU‹­í¶´ÕÅ.ª­ÒVl«RÝb«õÒÚHKƒ¥+Qo•"Õ $HH¸"ê?çíÞsß’{Onäíw>ŸäΙ3óÌ3ß3sΜyæ…JŸ K¥Ï˜) À­#Ÿ†oVӋ„—†Ùî©d¯‰o]4­«xf:³Ã~B¹øyW¶ n Û½”ìeiçFe§¥ëìנ̺ BTi8yÆÑà–wú²Ô¡ÎR¦_i`9·¥Ërn˃g$@$@¥J€†¥RÅKá$@$@$@$@$@$@$p+ ࿫߃²;P ™1 á¾Å¥Œ˜nêìœôïpðâo6 N§àÛËŠW‹ûþ€z6W]•i4ž+=$c2ëµêl™Éµ}÷Ov  5Q†(tþ½{Tì„ðÔ0–sGt,çŽLèC$@$PZ|JK0å’ xÀµ‚BÛ$   JD àôN|–ªËPÎqɱ]»îFa!ê6i¦õ´M„€ð»zÃoc<òq oÿMž„iË–üXõÆU  ÷vj¢ܸx_lHAj¢]ÿ‡Ðª^uËu£2Æóº.¾á¸¿G0>HÊFþ÷c]« ŒQf1Húë+YmЯ[··±äŸŽÒ#ÀrîÅ:Çr^z•’I€H  a©ß\fH€H€H€H€H€H jø­P¿Ð|öö{Nøýqþ: Âzí¶hLüsG¼ùÁ^àl2<—SX.¦gc“rt7 ~Ö(’ëzN:’÷ˆ8âðëzŸ0,ùËnùŸA™0¯4tiõðhÄþ0ÉbÆVòó‘fB½«qöŠ’Ï†Ý×WÇÑš{ºJ‘˹wëËy)VŠ& JJ€KáUÒËl‘ TEîM ¹­–œà˜a˜òçîªÿdXŒJuÐç©x0Úq¹·ßÕ²Îzªëg­¤ 7"SŠk$^©èR]ÌRzåYtSr”/˜hF%¿v}ðâ ýÝ\P‰ÏÿÞ"Àr.‘ôZc9÷VÁ¤ ¨2ª-_þüoGŽœÄ„ säL715­Ð™ÏÊ:'ëß Áí:ÞRž<¼E’rH êàs¤êÞ{朼E€Ïo‘¤ P”ösõ†ù"NþšƒZÂP”/¦+5 kŠÛÜëÇwy‹ŒÊ4Ï¥"â‚1™7pñôIdÖD­kb¶RÝÛÑ4$ ¨dx­„XÎKå¼dünUìÒ.ç·*L‡HÐês@½ r…#+ó´¬Oóðæ^Õ‹Káy'…‘ @Å&PÝ·Â#g'•$WFeW”®ÆdVG½ÆáœTØ vÍX9(:“FeW”6Æd²œÅ”×H€H€¬¸ž•]$@$@$@$@$@$@$@$@$@$@$@$@E a©8¼D$@$@$@$@$@$@$@$@$@$@$@$`%à°ž¶ 5HÅtU–|x‹>yx‹$å@Õ%ÀçHÕ½÷Ì9 x‹Ÿ#Þ"I9$@$ às•%¡*`9¯ w™yd9g ¨h8c©¢Ý1êK$@$@$@$@$@$@$@$@$@$@$@eDÀaÆRÆ·—‘*ÞIöד'eA¡M›zG`—BüR}(ø)7*@'ÀçH¿TŸH ÜàsµÜÝ*T XÎK*E–;,çåî–P!0L@«Ï†T°ˆœ±TÁnÕ%           ²"@ÃRY‘gº$@$@$@$@$@$@$@$@$@$@$@$PÁаTÁnÕ%           ²"@ÃRY‘gº$@$@$@$@$@$@$@$@$@$@$@$PÁøT0}©. @ óÎ#eWv}Ÿ‚#iÈλ"B×AtÏñ§#"¸z±s‘øáûøè‹ÿ⪪: ‡ñ#ºÂ7‹ˆ'.^CæÉã8ôñéß{pÏ« пy-çqÌç±7Qè¸GÓ¨íø›p×}C0 _»âÓs.Ù¥oÎÑD,Yðœ•xˆôÂîĸIãÑ¥¹Ÿó8y§°ý»q½fM§× j º×=0ùÃÅilçÍÈ>‘‚o“v"e÷dœÍ’Ù×k‹ÅCÝ#áãMöº¤+²“åÜùÝ«tåÜõÃ9*ú’ ”€@µåËŸÿíÈ‘“˜0aŽ,&´iÓˆ+û¨¿žZó.ž}´½E©„gžÃ®œj–sÅ‘‹•OXJ=§ÍE¦5xuR¬r9}5†=õ/äÃ>pí\ªƒQÉN¸ã©2 ¨ç˜±xõwñцUxgÑÓˆ Rƒ^X‹ëÒãðÉI]i5*õÂkÖ aÕltUÓJxf(VÍw”¬ê¨\@@í€fõ}ãyèSx9KŽйžz}–­•X<‡MÎÕ˜úöNíÌæ×{ ô„åÜáÆUÖr^’úá‰$@$@^#ॱ?^Ó‡‚H€H€H€H€H€H€H€Œðo‰©‹#쮎ÖÍ. ÿË´n¢ÍŒÉÀÇßE—!–T²“?ÂòÊiÌ´÷1{DkùÄôø<ÜV0“—Š5»ÿŽORûˆYH¶KÇÕjržšÖíî銠Ì5¯*â¿_ÔHlÝ;¾:†·Ö†ax)æ>åŸWã+BŒ—Îããg—©ábñÎsÐÖ_šuÕóÖ`bIòì®·ÿò/ X?ÚÅò{‘X¸#åxn$éa÷ýó{…¡Kd}kÌæaX²+BÌ>{RÖ/cÅçH×vËîaoM¤»XÎín^å-ç%©vxJ$@$àEœ±äE˜E$@$@$@$@$@$@eK »w°1*iúD=2š)ÉÖhs ;׬Vƒõ”QZù·ãÏ «ê³>a7 íf-ù·Åð}€ºuœïGd#P:©VÝÖ¨¤¨xúF;„6ìa>ž„ui¿ž¯LVJª¸Àxf†6#ëSl?Sè27så2~Qüšw°5*i}ÛbìøHõ,¹NÔ3Ä^“_¡YÎõ·¯2—ó’Ô=#ºI€H€¼K€†%ïò¤4      (— ³~ÓÅåÌDZ%IQ9``O„ÚkïÓ÷ôP´Qwί»ðÚÓ‘+ hg‡ÚΜòXîÍ8JÙ¿hˆÆuwðmeÝ˨຋$®àû¯¿Ã®=‡‘‘sÍE˜RðÎûÉbðCX,Zú—B•P$Ëy)笕°ö2K$@‰€Ï™¾¸ö@ER™º’ xBÀ||&,û$ÉG,zµ°DÏ?wDÞÓHòˆÕœ,!$‡0(ÉÇäš…áÉFs:–¼ò6Î ¹‡“‘–®¤€°AX?Q%ÝÓ¨ZŽ$K»5‰Cfš:Ó¹ðº%gW/]QÂjÿ TWV¾8]ó…©ópL9Cm÷š²ðŠã6ÌTöW’ÄÅ ¹?¯$T©„°œW•rÎúQ©*.3C$P! ˆ¥ð~«ŠSi       â žÙŽ'ÍUàùµs„ÑFÏG·ƒÎ© ÚõMêiRO(sŠô×¹/aǦdl£’$èRΟË1&Rë¦?îè©îQä_NÖó­ KÎ’DŽnÿ¨Z··B×èöèÙ·b¢µP¶{5&÷¿Ë÷œ×§æ=·˜iµ}Ñx¼™¤Šì; óíö½ò^b•G˹¸—U¡œ³~TžJËœ Th>§_Ã¥#:TžH€H€H€H€H€H€HÀ üƒ0tÄ\uy9à©•«Ñ¿y-'!¯š>ŽËhIW®ž¿h‰S?ÀyKwµÚ`Ɇ50ã:.eÇ÷×bå:1«êB"^šˆ‹ÖbJ÷†Vi…éX>ëœôõ…«\3ç V³˜:þøV3ãÄžbö(*¼ KÎÙŸ|uü»YÒ/Ì9…­ 1gi²ì·2îetÞñ6ÚêfVel]ŽE_žD@=×›2] öœ2½Bå"^Ž77©Æ»OãË7ú—³•,÷Á™ƒå¼ª”sÖgåŸ~$@$P¼Ô, Õ™& €+ß.Á°gV«—#ñꆥ.ŒVÇÏ¿ˆ=‰ÚµÄ[{´‘×”³ß‡É•EøW«ŽàÐ&J€Ð0Duê…G‡ CØPŶî™%´w6µž óy¬ß”h1’¹–Ü %Ã’@ËÊ œ+¼i•å$rDç(Üu¾|› Ïøy¼6SWHùû°ûXÚ¶ °H»ppv&?£+pÄDÇ{Qx KFEÂE\ƹx÷)®u²$\…,çâæW…rÎúQ…k9³N$P hͳò¨u" òM ð<¶¯KB†Xz½M¯Ѷ‘õƒ¼|+NíH€H€H êÈ9¸›RN¡f½(<Я;l«nQ¨ô9ÏÙ³ÒjT ê‡e_̰]þNGÀ¯Y"ÄyšøË8yIwÅê¼tYœä#…Vo»ü"ûãñk1a©d¸9Š ±"^x°šŠ+¼ñŽdtªa3³ÈF‡ë×Àæê~D~h×Y,…·[’õ3Λ«!\7»HŠw3/Ùª€«"®GLßûÙ°¤8 è K-Ä’ƒoÄ k8]xO–.©ÞZ¿¡ä}+uF¥ž¯¼Ùµþ4*ÉÐ\üc9—ÊGU(ç¬.ª½I€H Ìаd>ï¶÷#®×¬iE>/(¨è^÷Àäë¢qW˜+:š?§«¶ã„ˆQufB«Vmб[Oti£›ÆoIám]‡ÕŸmAÚYe³ÐÚ #qߣb`÷(~ìZ8ÑA匀9o¿öwy£ãa‘½iX*g·‡ê@e süì:’…š~-pO÷Hø°s©2ÜV桌 œÜ¾o/Í‚Fã^Ù°TÆ 1y( 9?àÙ¸eªäX¼óÅLaTrñ +…ò¯è aXº þvìCþøvv3wÎcï¿E½‘Ž 0ÙÛD”+^û_»®6ý"ÇÏæ£[°v±Ö¥éÜI0¨iKL1R<–‡Ží4YJìÜ£©r{^:ëÔÚÙ÷ºÎÕÿì˶Æ(¿Ð¶èê*´kÿ½K§b¹:S)fÚ»ªQÉux^XÎ-Å ²—sÖË­¦ƒÊ1\ìݺÙ5ÑôÎîˆ ®^Žu-¡jb¯·ì)ø6i'RvAÆÙ,\"ç-žWBÁ+: Kv÷+ÿØF¼ðb¼¯íé°å1±“uª»vµðÌ.¼Ðw vjâWšŸ‘~)I‰HXs_&ŽUGN©¤©¼ƒÅT÷tõ\ûIÏ@ÚîD¼=ë?àjE|hqøK$pk øÔ€4xRúÄ®åÜ}kõaj$@•ŽÀɯÿ&öqOÑþeb¤hCð ()Ÿš „Q¯n«ézÆCIa|(SװᯓäÙG@ž_;×f çª5Á‡Fb4KèÀ§Ø~f$ú4²v™~ƒat’Ž˜?ß":Xc5ÅÏ|ìÿnŸ-í›IV,ãßÃ!]ú‹ÙXekÖïÆ¨v½t*]ÃÄžSÊ‹CÜJë×Ô,2îîÐÄâ6ê0ý“åZâŽõŽ…#Ú¹¥‡}z%go/±<Ÿ³œëïNe.çÞªz^t“ ”¼Ÿ1êl¹Lê; vì;/…TËDä¡OžÁØyZ[¥LT(‰i嫸ùúo¸˜_óõrXßÕQϯ&|kü®Ø¸eÀGß;€1jKäŠÆt³úN6á#eâ„Q)M ÜsÒl<þÇߣðB&Žýþ³*;ýë:|¼nÿûs£R×1ÏáO½Û¢Î•cX»h66K£•,Û_tǼ‡ÂTÉü! ’Èÿõ0þ÷Ó/8W(Fkwµ5x—\<%@…%Àºáþ­#+÷Y1$ x‡@.%ïÇɬs¼£7º4¯¼ëÞáUu¥˜®Ã›Iºüg¦`W¦í¬šëb-¶ú‘@T#ëì;?Ž€¥ÓÅàÈ\Ìyr!~Ÿ0áb¥Ž›9û1kè[ªÀHŒ~ R¸í =…דg||qñŒ¶°•s^!Ìbé<_ÿ@øúXãåLĦ_Ðóžh„økKJç"qé üc·¦K9ùüÖ®ºõëßã5aê'È]7 îjŽ)½Ãä¨ûWÍ´¤e? v+“˜sNáÌU„7²Ö·Œä•˜üZ²št¢L%ö‘¯üÝ’•\‘ßC{vâŠÍ-»ŽëbHÛbìe€½%± ì`9·»y•¶œ—°~Øaâ) ”=o¶ç¼)Ë dÄàëò{x—U¡º[¸c“C»Ý{±ô„åÜñÆUÖr^’úáH‰>$PƼٞó¦,o`©ÕlýB^®v 4èÂöê$ Ëð2«÷ýó{…¡Kd}«JÍÃðëÉ“Öó*à*Ã’4SI2*Ïʳ Œº~›Å]Qú¹KEꜟ‚6© Ò¾³­F%»H>ö b±ŸSrº(8ØžO´ˆפYKý»÷à—eØ_ƒ–wºØïL‘—Ÿ}¿œ8̬ä‹Ñœ5›¡cç¶.Ò6®´èî¼»aÎGæ±_`y{gþ‚Ìì†(¼Zßz!ö×µ{,‚騺´Ù?E®ãÀÔ{>š€Ç¦JËÃå"í€ú+Œqï¬À¨Xu¥}LŸºö>çÁumG25•ŒLÒ@'‘’X>~gºäR°^xõoSÑ+Ò:SH»dè×' S6Æ£Ö£‘ ¾±suƲ€cñÁüÑN—÷«]W]:óB†XÞ^ÑUN?¨=ž}ó<Ò©‰!uì#ÕtÒ°´Ag=8Ø;Ê®ˆ>,çw­’–óÕHÓÃH;'óèH9|Z´£jˆfT3¥oœ£´Í,ý v<Ìg±w÷>œ}'5j¢ébf«øF±öµ(ß?Z,ûïsv’¾ß/Òß7wýÑã=v<’çF߇¤§½L¹ÝåÎw˜–I\ɃûðÓ/YÝC¢_&­Úÿº¿– mB3Ò’·aÿ)AäöVèݹ1²½Õžs³mèwÚ½ù¸ ©]¾ÿÈi¹¬¨¾®ëâÛUúr•?a½³,°T‡“´Üù¾Ö‹)ö›ÁMVz™Å¹ýšw@—âUëÕ–/þ·#GNb„9rvC›ŠQ8%&±vùÒ7Ø.W˜ŽƒÅHÆt}HÍ€§ÄúëÃõuѼ»<‰ä©5_ Í1ºpž¶,†/¨Vlœé°¬†&ÕþwÿÒ?)£"ÞÆú÷#ðfïI6û¶Iáû¼™)ùÓÇw+¯BçaBç }D‹Û$FA®q˜©É爕™€»u#OÔ¡»•:·j-Ú§Ìw«Þ[ëöX,›Q Óœ<—ºNZ€7ïjÓ±n‰$í±d·O£‹ûa‰Ãçˆ Bô¾U26Nð•÷b×WÖˆ¥;`wý­ŸXžJz{·Çнo#Bj{žÅêYcð¶6pË¢° Ï®Z†GÚèÚÅž¾»…¬CNÄØÅû€ÎÏaýka½k-ªèŸ ’·ÞÝ"œ¥^ëÓUÝö³Nœ¡W%$PÚí³B1›çø¦¯P¹¢Š†ÝѺ˜AVÆ  ãrvÖE\¸p5j ƒO®X¢ÏÔÌfé9c’]ÄX™i‘q½¶X‚^¬ R? QÍu£í£‰eæ²³ÎàܹK¸Rp]t–Õ@ý&å`,{T¥qÎrn*˹Ape­Èrn ±—ûÊ©qXž$µ¯tGX{Ĥï“û/”ý[m¿-2Å2Ÿž°Ì¡ï$¦o$R6‰ý÷ÄaßçiiŸ„ÅŠWü1fÔß- Ú‡µ\(Âá®Ü~w‹„ëÊ3;l53‰9$@Tcû•lÃñŒŒðñoˆ¶Ú""²5:v*£’¤—oBB…q§]k5­¶¥gT’¬V!‘mѱX~¾S‡¢J²‚µÜHÒOÄá»HLBëÛ ‘‚ñ¨˜XÎÕûæÃr^nK°ÇíœóX>x¨Î¨‰c¡«Ô¯¡•¤ÌÚ}[dïYŽÁ:£RDßA60VnghF%)Z­šÒëaýîX¦3*)ý!uN±´ÆuærGž'í') ½LO¾Ã¤tÖ•L=aÔøA–¶mÚ'sñðcñȾ©k—êÛ„qV£’üÍ׸.êy±=çnÛКú˜tùX9á «QIß×…dLíûW¤éû»uñìËŠ³û-ûéâxò}-ͪv÷›Á]V.uä—hX²GSX úd`å‹Ó15î ëÑ ÃÆ-ÁÞ_õ [#úˆ)žÊ±ÓFŰ s±9I¬½,¦îLJÄÊצàÁŽS±ëŒmG°'bð\ÌcRã‹õž_|ƒ©û5‰[¶Qa I T-QýInÔH¹^¹j§-¨{yãÖÎÛ§é;F¬û.9Ïâƒg—)~Ò¬!1gæ31{ý×x¾¯ÒÐÉXñöæéäøš0bÚt¬õö«—(á?^‡™jxàgœ7ëÂ+ÒuÿMxjùìH܈;ÞGOµÃ87ùˆcgš.VQ΀¾O#aÇwØ‘ò=–½ÒK š#'¬Kz”WŸ0Ì\/dMÒ u‘xç‹MHX/tNœ(K ¥#¯‘@¥ `¸n«÷g,Æ–½Éø*ñ{¬x}áΗW‰…Nž3ú*o 힃Ï÷81T)ð‹ÁcÚ;4=Û‹¥^uGFâeÔ¬ð1(F¾’ýíûX.–©’i†nˆûËKÚ¡í¹¤#¹¥¸’ŒòtÔk^v3zöí…˜hëÃ3c÷jLî–ï9o§n>R¥m¥£:÷€¨Pb=èçÅTÁkcTÅ’%wĻȴï,ªVˆ+×´ÕÒíD_ÈÄ9›‡½Ýuž’@"àÓ¨FJûŽIGÒ§Ø«›´”³g6+W7¬›<‚Ð|t›¼9¯ä=ð剈ðצ'û¡ÿ¤'ÕÐG±ï˜NOCôÑúõºk¡Ç°?©á»:é0sí?1\[gÝ¿©A¬^öw¦N ÎÂço ‡IÝ7¡yË–ÖË:E åÕb·Š¤‹H@"àÉ‘z/-«¹S†t°ì7ÑoŠÎ€½ÛzïåÏçKu™3:´¾CWmP-F²Rç±iÙFE½è±èê#ÜùøFtfÈGÐpŒ  ‚ö£Èþxº‡r)món뀽»ÅÛÛÍw­’²;ÿÝ{.{w{ö„rG[†!  (ÇîfQ¡0ç¶&,Äœ¥É²ßʸ—ÑyÇÛhk餔œ*k—t~«Þn™e±pB_ˆ9ÒZ”VcËÁ1°Zí¯!ñ•xi·çø§ÑðÈ?‘¤œcw<»; ·¾ŽÁZ§¸E5:H ŠðCÏÑýðöT©¡tŸ{] îkøÏû«Aƒp;á¾)o.©xŠ™€ÏÌÁmã›áš6x çˆvÉù¯x!dgþŠÓ™È½r9‡õaΣôy}9ú4×7üЦ—èÃPq?¼÷r_›F™o³örƒÎ~}_i#Míð8¯ZDþ’ xLÀP½þ? ”—¸µ}¯wÔؤ<Ëò =ÖÅy>Gœs¡ï­$àצ-“?Î3V¬Ç‰§: \|˜&YFÔö‰ë#>ô¤:‘‡Ó§UíD»ùÍŵ ÞÞŠ‡xÅÙ¯^s6`ÃÀ»p¿Ž¨)ûãîsïîbQ2 €FÀ­vN޵Ö­µÈú_Ç®õœlk½÷·ÖVÜâÓÄ1–]01 è¯F OÛo»PW¢ö“ßayÙÖ ÷öÐ ðÕràÛw‰Ï)RW‘˜`p®ð¦Ü¾Õ.K¿ß™nÓw¬¿V6ncíÞ¡qZú¸-z7ê„Qab5¡tá“w ×-Jæp·]¢o†’©è"v.6¼8oоÿÕ]©¤Þ%2,i3‘ŽgÝk*‡Ë±5>i<£®—ï5Á}› Ïøy¼6SWˆbìÃn1ám;m&’è<¾[í<3žž9Ä®ÂÕBïI“ðÖ¦Ùòþ/I» ÃR[9ûù© £RWɲ?Bz€ÃÃÉ ˜:á-±ŽtìÃäÉñÂ:<ÚN®|‘ÿH J¹{²Q^6gçŠoóÐXœùîV0Ä<9!jCæœ1(+Uã°=°kV¸|)mëJ¼>u™ÓÍíãêÏC›9¶Ú¬ËdêCºé3&ëÙOlg :£yµÏs Ϫ÷¢ámÓmM¯FºÖo¹øñIÊ)†ðçöX'/Y+–ùïTLŒ ÀžÕ¨Rcñ§Î!Â-:"òÎâÀkb;WÄc§õÔê:]`ókôÝ êˆ5ñ¢]î>øî.š#¯’ (Ünçä·´£Ú‡BrëÎam“˜ÐâvwcÙIûÕv6iÇ.˜Û§.äYu•$¹ßÏ#§ëÁwØéÃ?¨ª 4È}_°²eB¸n‚ù6¿ò3‰BÎŒÁvoA¡´”µáesøÂ_‡¥†Í5ã'î¶£~3׬ˆ˜…§°Dl‹“Püxô"„TÜK%2,UÜl{®yLßûÙ°¤C)-†% NM­«·9š6ÚZè}êê:œuØ?nQ§¨ Küó:˾4=5akf „mÒÇõø1{º{®7c@¥"àÛ#5!åavM{5œy­6­•¶bÛoŒü£0òªõÏÇR/¥ ÁŸÃSb}_ÝDJ‹VÑ4Üú²?ñïYór¢ŠÌ„ÓF¢{§;€Ã«0ùemJ¹s¢^›a Ê/Ú^o£„‘¼Úà €!Þ¬÷Õë†T²Äçˆ-ž•–÷ÿ &aXoo$¬Ù‰ñw6ÇêŒ}Ó˜aˆÐö÷Íh­U DâÙùÁ¯@×xÖrà×LÌèUŽ’¼»Í(Ö”pþëîsïnçüèK$@$@$`%`´“{ú¢Ø—b›Û£†½}@º\S “³—…¡‘µ5¦\qÃlàÁw‡–Z‘¿.ä•FûÉÙw˜…I.ò¯J$«;¨{åÚ?[)^9:\0õ††Þš±än;Z*ØÖRêÞ7ƒ7òé(ã%jžéźíæsÄmT h€@µà;1¤3ði†±Ø'qÑ߃-3ƒG бJËŠtŠV— ŠF÷{ïEp5Û[ÖÀŸïn+ºH€H€H€*OÛ9þM¤¥ »ÓÅ~”+ºè|ìÿNí?Ñy7½#Vœ•}މ>MØõišO¦Ê«Æè¢”™³Dß,|‡5î`er&×ÙŒ\ü¸MíÓ ê€0ûnà2#äý)àÅ@IDAT„k:˜'E…Y8t@MË¿Ü0=zW1O¿¼›ºEÚÞ¥S±\å3í]Ì~¨5~=yÒr½*8~W’LÖÆ"i¤Þ­ÚüI~’!I;$·«p’ŒŠpüšjíð¹»C•[þñ1WB9>^-}1Û9‡ÿ§.k'žÏ‘Õ‹¢ÓH{¨8ˆÓN Ù×-ö+¢LZ`[Ù<#ªFÀ7²†…)¹N³•vªKæÄ ë&^wÖΧZA Åâ”ʱîk­›|«~Ž?u¦ú¶îh1*I>7r­ëë8©«j,· ͹ÈõGFòJL~Mëð Fž@ýeT è„Ñ=¯Üu³0ë³ý–‡ŽùÌ.ÌŒ‹W.Š ‚{‹å¸”ÃzEªîDLžº™fë“(;õs¼ Íž@S„ÊKì©ÁùCUš@}<0¦—- A¸¿mG¬OhL¨6ªÄ²yŽ| ûϨÝ1¢s(_Ôõ]7`¶jØ1‹õˆÓU±»¿Â®_sakï߸CãâÕ G±ëP¶ê6þs(~,÷$ÿ?h\Ó㼊xA!&5öQ|º)ÕòÌ*±2@œ@©× ÑY>¬×L$=¯Ö»|l_:GÙøT°“—ó)¾aÎçH/hUPýÀ;DO»|÷‰ëcû!Z­:zM™jéÜX×Kþ½ù…J¹ÐœŒƒ»°a£ÚÖ¾…ïn\;ˆñê»{pß±H)ár"FÞÝð½Í2‡:még¢ã§äƒSìn O+!œ£‰˜3n †=ü'ùoÌäØu¼e^:6,} cÔ8Ã&"[­‹Æ0å"ñö2WíÆRë7°s¹Fã9—¦ø“iˆeQjðš×»7×phkféëǸYXýía˜‹-—Žªg¤nÇæ‰HÜêäoãflO=ëIóñr+‰.'’78<3ž×4åï­$ài;G´£zÇ=iÑpçkOà‘1qÜD<Ðe(ÞÞdÛשôitÆ÷ÐÎ1¡G_L{a¦ì‡Áqo©[h×Ëö×PûISÙƒï0ßæâY1Û^>6ÍÆ î´¼¯Ìg~À¬þ³-\â&õK4ÿý¦©áÕöÜ-hnž:Ó>ÜŽluPtþñDL¯fÇ„Gä-),¹séðê÷«§ß ’V^e•¯(+)I¢sÅ݇öìÄ®ä]Òi•:tC«T¾]föhÂs˜°4CôºšÓ¶©ØÇ%)éÖà]g,B¯FvË÷‰ÝgλøÏÝOÊ o{íIl[Õ]Ãò±3I±^JâVND¸ŽxÔ£A×ÅOÈqr“ÞÂà.ÿDL6"̓"MëÔ;ÓáF'“UKºH rïþ0"hYF'æÉbŠ·ã‹¼ÛŒå¶Ol¢—.xX }W‹º€€ ¹–FÀ°å÷ ­´Ì¤ Ü'iҤà ‰˜Ú_ÛkÉ–e„Ø4p>¹¯¼¿C1Ÿå–È– ˆÂǧfñ_’äÎǦg§c¥]· %Þ]_&ŽE Ý{ÏûuΨ.¹øü…áø‡½ñA0yI<3¶ÍË< ik“%ž”2#íœæýñÑëGų­¬\î}ÖeìÂú!.ö –²ÏNñZè?7G‡‰çtºt);7YûCúL‹ÌÅˬrìbßêSÛOzÝþ«…G^[€m½§ÈùÞ¹x î_¬¤¸#ÆÌň6Ò gë{±Ø6¡7ÛsÞ”å˜=‹ÏÎÅÓñ°È@˜h§[û«{¾2]ìÚ®ò_Ô÷««8T‡¾_ ž|3Hñ½Ì*O¯ôº¹˜°NQrõÊ7Œªr¥ÿ)_Ó…ÊîÚu(Z\È@J’ΨÔÏ._ƒyC"œkéßóv¼Ñêåô}V£’ˆ;sÍFŒj':¯õ‡ok'q}µ™¹jšj% ‹ÅÌU_ˆ}},ºI€bð§Z}2a¤«>M0qý×xcR?+3Q ¢n¶¬¯mÿí‡á â1L«ÃjŒ€èAX¸i#æÑfŠfÖ·¿B#\òa Óugµ1íÖœ­QËÚ5åW·†U7É¥]“Ú&E{°x”W!Xz /+wHY“9‰+bz0¨ÒŠ­Æê½…iôp¼úúh¥îéžG=Æâ£]3aoØuñLàsÄB”Ž D æAmåÙyöå]½jê=[ÖÎEOÝ;ÙbTa"ú´wHÛözþî\Ô+‹rªÃö][Á–Á¨£,±²¼¶&'íxúîéK)q–6²‡ë¯vû¿ZÔ¤£JÈI]i5*õÂkÖ aÕltUW÷Ixf(VÕ÷Š\Ù»0ÞbTŠÄS‹ÞG†x<ÿ¨ÖÍAó‘éÑlŽ\¬|ÂjTê9m.6­Á«“b•û“¾Þú—e$¸õ¦g•àè2&ÓKÇÄéS ŒÞ›íN|(tê:æ9,\eËg¡öÞ9° o~qÂ#ý[ƒKƒ!lþÄ¥1˜Bûò´„,•:'ÆLÐe—ø6ÔŒJ¦OcÙÚ5XñÎsb@§rH¨çl=kQŽ[AÀX;'¼ßlÙ°qöCŸ1£1pà <õúblY?mjÙ=÷µløF`Šè;YøúXô3´G„cžÆÂ ‰˜94ÙZ8û_7ÛTöÑ\ž»#Ï@ûINÏÓï°à.X²c•è³ÕÞz­#·hVÒRïÕrºOY9#àщ6F%)ZÛÿ{ =…ai›poŽß†g{W RÒEKÇž‚Cõƒ*¯açŨô”Q"°µ¼v|ât]:Z^~}ÂnŒiw¯j86Ïûºb)1áQê ß›¼SHNWÔ ¾ÍNÏh!ÍZ"‡Ãe9· i]›ÂÖßá¬Têœm*îê’{âºü¥ O=®3*IâÄ깊Ðm,ëöçJ¶äoP¦Q–E©ÂkÞ!`ðÞä§&XŒJ]§½Ùã‡aâÂHxçiy&Ÿ¢Ü>Lž/fóU3¦«0î˜ÚõÁßÖ.°ÌþHùbŸX‚ÒNž×ëœuÝÔ%bÈ<,{eEÀÎukU£R{<;º¼/›tñª%$@$@U€ã ªN„ù'      IÀí:‹¥ðvK³ ~Æys5±¤—­qéf^®eSî«×msØS>þ#ŽïGú¯¹b_Ž ½¡>Xùð\5¬ õ6~·#ù5‹’;Õå%÷N^r |.]Ö Nb±—ƒt§Ävþߘ̲t® }½BÀø½ùqËFEƒ áxþÑ(áVê‡)v¶F`ÖÐIØ&Ï2Úˆ³G‰å+\-°=î†Ú´BFúüb(_;y^¬sv’mNÝÑ%ê¡)Ø~ïHü¸ÿrÅþ:5CpG»HT?¨Ò"šÞf#—'$@$@U—g,UÝ{Ïœ“ T2AM[ª9:ŠƒÇÄf1vGîÑTuÿ Së†vW•ÓæmÑ¥{7t‹í"ŒJ~¸™ý_¬IW®™}áî Qû F)qÒv8™­óØûï %@Pë^„Fã)’œÿ7(Ó,+Dß’0vorñS²Z棶Ý"wÀ¸©½TÕ”}¿J¦§j-•…äãŠþÔN°WêœLÛS}â®u©æßmE½ï&ê—vòŒÆ”¯Tcœ˜Óõ@l¸­Xž‘ TY4,UÙ[ÏŒ“ T6!]ú[–ßZ³~·]ö®á?+W«~±Ð9ÄîºóÓ.º † ¶.‰ç<´æÛ*fOIÇO±ýŒ¾c0ý ÒÌqÄüù~„¨3G£ñYÎÿ“Y,ëG_O »7Â"ꯦtà NÛIù‚˜¨£&D™´ÀšŸ‡¿…Y8&ÍV’ްX„iË÷)>Eþ7VçŠiP—›g±ðÕ×y$b‹Hƒ—H€H€ª–ªÔíffI€H€H€H€H€H€*5ÿ¶÷¨IÎbîºYX°5Ý’Ýý«f⪭É$ö–‰Ð/ig>ý{Òc¾a ±+ÌÞUÓð‚Ö±Üc:hn»–Wá™]XðÂk˜óÂì:£ Ü1øq(š`Γ qB,Í'7sö‹%ÇÞ’Ý@$F?  T£ñ¼®‹Q–j>øSŠ Ý?t꥕µDLžº™j™”4ÍNý/¼œ¨*Ý¡ „!J=Š*[À5dMGN¡n ”ùV>5›Õøí[ PwYö.…:gT—ì£ûqH,Y¨Û*ÿ×íxºï,Ë Ç矿¾°F†¿$@$@U•€õ-YU 0ß$@$@$@$@$@$@$P‰tyîM Ü<ëÄŒ uSG 1:·çEZº:ï(l8Žï(rlÝ)ÿ§µ˜/S‹D”˜^ñkÒ>K§2¢Gã_ó8t,_;÷#ÖmR–Ê ôº4RLI’ jÁÝðÞü~6U\O_‹ÇºüÑ qîÀQË ¨a‹æ¢c U’Ä+ ]Œ°”!ò_©0ro¢ý º.~;…v¹Ioap—"¦GQ>"E«âÚ¨w¦#ÂÇZ.‹*[È;€©bo&i^)º=Bƒ¢îXXÌ{þ^øèê›t­4êœ1]r±nü“X)Ï @Dç6ÆIìÜ­ÎTº{g-ú7¯eÍ]$@$@Užg,Uù"@$@$@$@$@$@$@•Š€O¦lŒÇ°h%W¹Â£•zŒÅ¿þõ´né9%L­ ë²x¹éGåŽq­[¹ëøÙøòã±Ñu´k¼ª×®«9Q?Àq쪩÷ |4¸&i£RâDgõÄîÎ÷y2¯Tt1ÀÒ„ŽÒ%`äÞø¶Æ¼ñˆë«Ìêæ%¤$%[Jbɺ™«¾@\l}Ý‹,[>u„!F92ì³1*Å<úvÍG”~v ¶Têœ!]|ÚY3‹:º;ÙjT ŠÅ«k6bb¬ózj‰'$@$@UŠ@µåËŸÿíÈ‘“˜0aŽœñЦM+4€_Ož¬ùðÖM o‘¤¨ºø©º÷ž9'oàsÄ[$)‡H€n?WoÞ@fÚAd\¯:W.õÃÕܶÃ܆©9™YY¸pá®\Ëb ,"!Õm‚9)3¦>‹Ú5+&N…ÝÑÁ¶«ê9k4žSaª§!™ž²,J^s‹@©•s5usÎYOæÓ€ÛP˜{ µCÂZDý(BksÞyœ9}—¯^AAþuÔ Aã¡¢ŒSwJ¡ÎÕ%_ð8wî.ç^Á±ÙTàpDE†8Ì´*/ àv97 ›QH€n-­>7i|k.&µ¬ÌÓrˆæáÍ‹ éÙeÇáDžÅgh       òH Zu„D¶³“Ü<|ý*ý¹Þƒ`>þ Ѷ“糌Æ+J5C2=eY”¼æ]ïo`CD(“Δ÷õ¯ðHF©R¨sFuñ<ÂÅŸía]ÐÖŸg$@$@U—«ê%€ù'           7 аä&(#           ªNÀa)G*ø ¤ú$@原«åî–P¡R Àr^ P)²Ü`9/w·„ ‘€aZ}6, ‚E䌥 vè. ”–ÊŠ<Ó%           F€†¥ vè. ”–ÊŠ<Ó%           FÀ§‚éKuI€H€H€H€H€H€H€Š pÜ‹ãGà§#'q*—®šEh_4kÛ ÝztAãÛª;©ß|¤ÝGqM勈»û oß ÕŠˆ'.Ý(ÀŬLœ†-ï­S „éßâï"ð—­bï ¥z°œ;Ü´ÊZÎKR? уH€HÀkhXòJ "      2&àÛÇCÃÖЯxòÈx„Ö_ªÎŒÉFRÊ)´Òm.Ù†ÍéŠî-™„‘=šÊ'Á|u —bÙFa”:¼ßžøî·5ÀÔ¨i„ðèV¨{q^_ìl&’-ߦ=ñÚÂ{Q³ºny½àŒŸÑ›þ>²Dðk—¤O%=r‘´|³*$ ^‰p_é4cføaéô÷dãÍ—~Î3ïu0š)M;o2"äxª(/þ4jÿþÜîv´j`•"Xü½1–>÷¶¬_Ö7É8Ý·Û-»g„½5‘ ìb9·»y•·œ—¤~ØAâ) € ü΋²(ŠH€H€H€H€H€H€H L ø#"ÚÖ¨¤©Óô®ûaROl68²ã[õJ VJZ¼ˆûú#J=Ù¹ý'ÜÐ.¨¿Õo G÷Ñ4صk¹;~µº­QI“é× ´“’ÿdÀ·êÒ~íFPJª\¿ ¦æììw8xñ7— º›+—ЏàakTÒÂÖÇýý´;v ùöàE8cìµ*ò/˹þîUær^’ú¡gD7 €w аä]ž”F$@$@$@$@$@$@å’ÀÜsÈp¦ÙõLü/U¹àwW4؇©ÞmÚ)žù{váäuû^<¿t ÛÓUy>%ß`)óȪ°:hYÏAÑà¿Wý®`ÇÞS×5êv3…4ÿÒý-@Ö)§w¬t“­àÒYΫJ9gý¨àU•ê“ Tp4,UðHõI€H€H€H€H€H€HÀ'÷í³kÑRg>Ê»¤îËÔ €£9§&BšµTãšá0eÉ"µd޼ì#øtq<òe1-1 ›²Ÿq©7pù¼²„ ÚNrV?-´ L ’¯™qxßI;‰ì|o,ϧ%X̯ù”Åà‡†­Ð¨”–â+F‹ w™å¼Š”sÖ W7©0 @å"àS¹²ÃÜ Ø(ÈÜw¾û$ÉGÚ†ú[‚˜s2ä=$Vzƒ“%„ä%ù0ãŠd[ñ†‘CÌ”úrõFH¦Ÿó'!㬒Æâég¡i‰Ó¸ŠŒÃÙŠPa˜iàLÞ¸¦&{íŠæR=nªŽll]¯º­»càÐÞˆ¶ÝkÊÀ+Žü÷ce%I\‹»£`½c^I R a9¯*åœõ£RV`fŠH BàŒ¥ u»¨, xFàÆÅx÷µÏÔHu0dÆH[£MuݘSSŸJÍÛ‚ÕÓlœ8›§¿T÷UÚs©âÏbT’¤]¹‚˹ÞH£6šµU÷(ªíÜtÔµFMÔW}³§CŸj@¢ÂZ¢]§´ÓòdþË^™…-i¹Žò¼âs¿xŸ©Ë¢Ó0äá¿ÿü>ÛsEI·]¼üE^xE€å¼ª”s֢ꯑ À­$ລs+µ`Z$@$@$@$@$@$@$@^%}`Þ|ï[U¦ #_žà˜a5Óœ9'fá4-j‰·–hÚ ¨ëžd¡:n Vg‡ iD ºß# ao(†°ä÷¾B×…#¢Ù±®_ÆÎ=)#™ë”àÙ°$Bhª¦g#çF5«,'‘M¡b…?Ũää2ªû£CßÇáw}!>øFêÈÿGÏä!<ܺHÝå“É8”ª…œ Qýüº?èx/ndãË…sñmºÈôÇÑxr€d ãQ–sA§*”sÖ¢ª¯‘ À-'@ÃÒ-GÎI€H€H€H€H€H€H t ä¥mµ•êvÄÓ/ ³]þN—¼ïíM!-'™JÎg]Õ]±:¯\•vB’3 oˆ«-JöõÖ?߯1ªßN¼³QÒ&çóÛTé¾&Œzj4®ˆyEš­É!ÝB±/’_ˆºQm„Gˆœ–deâòu!Ë>âÕ|\R…\“3æ ÑÁ£yÇö€lXNürЖŎÁèæù¨î㺻EÚº©a¨f ÐÄçâ?:£R»‘“0²sSí"]`9—ÀT…rÎúᢠЛH€ÊŒ€ë–N™©TÆ ›³qð@: ]4 }Ь]4‚]5¢oäáà®mؾí h¶uÄx§ÛB‚ajŠ–mÚ¢USÝ4~s&Rˆ®‹´4R»¸Iôñµok!øKU„À\ÌÊÄÉcGñ¿]?£ÍˆÇ‹XÆã.eÇ?Á‰´S8!GÞ”·VH:vé†.ÑM\Œª8óN@ÒÖ8tä´¨ÌuP«v ê7i‚ЖhÝ õtK^T‘;Àl’ Üby™iø)#>¾íÆsë«ÇäHÀ}|‡»ÏŠ!IÀòÓðÁâͪ¤(L(¨$ò­‹¦u…ç²ø;t æ¾av3wrñó®lE^Ý.åvp­ÚZÙÈ̹Š6·iFÑÞʺ4;¨ê6Á$ÃRNž¹ŠˆpM–;ïô d©‚"BU—û?—®JV6ëáŽ6Ö혬Šq¥mZÍéJ ³ñ+·ÚùÚžvŸôW<aê®]½qñþùÒûPV[V|Åà*dÍÀ±Ô|»ý*^~½:rJŒó:“‚‹IK“í*Mí:I 26a]½úK¤V?fÕÌ6¾Z \Ά8™´o}þ³#–³ÙÈHÝ‹õaÝñüäþvúž»#߬Ä_èjóei9 7ýg¤~ÿ-.»x8&H 0N kßçbñì«Û[´!šXÚÆ%2& ÜZ|‡ßZÞLøïê÷dSŠ4ÔqÈŒQ6{9§Œ˜n&$K³„Ò¿ÃÁ‹=Ñ¡žµ¡\pZ|Ï £“t´¸ïÐ —Tð¥Q[Ú­‚>¦;ù[éȦ‘2¯“Q‰>ÃÅ-nÜd$ß Ç/—‹qþÜIþf2¼½M¥¹ñZÑfLÀš’l £’¤jtìªÃ·O†ÝH}ÔÄ—«6BlæìÆ;ÿŽÂ£ã¢ÕþeL å0åâdÞ”Ôú!.!š 9õœRfU>¤àw¸Š‚Lન>·Ÿ¦kŠ+9…ÌÓY5uäÿkO„6‘ƒ“á»u-­_tVþ ]›€PÁSGE6>xa‹,Pºj„ËAš•Xn A_nž(¿¤8–ÊJKQm¨C5ïéåK}Æõ‹ÊsÓðÓ_òÐ<(mìr¤o[MÇ”"BáoË[ˆ’¤¡_¯HÜ:T‡5»ŠP±g=6F‡b|¼0‹‰ÜØí2–2zÂÌʪ®(Â¥j/„;ÇŠ2wà­ Ê4tÓ5¤Šõã•8°i£z¨‚Päfe¢Êä”Õ¢ème ('Ø«…µà_çf'¯Õ^ç¼?Ì0ñ.¸öÊ‘›™ƒBz?úvCthcÞ!®”å2ͺŸÛµ¬lõ9º€b‹Ñ$– Á¨tòB9.]fÁ>žèÙÉÁ¾-©#Vû–þQÊ üzOkÒ?{_5*%Ý¿cbå‘N´iXdúNÙÛL\oy…'ã¹—n¶*ÙÓ£_?»Û „Ã1è×­1«Ep$h1<:ÆbÌÄ.ˆ$÷sþÅßãùõÏ**Ö冉¸;®¢Ãõ ÅŒ—ÂðæÃ+EãRáW{qnT´I²®è :ZÉxbnŠ:"SÚQ± ¸õ6áfnIÏ3#1&P? >ÄZa†tè;ßÎï€úe6æhxòCX4Xê¨kn_ÍUc8sÞ¦#Àïð¦cË’™€-¿ÔÒBBêvŸ®\¥îi¾#ïÇS㢌Q±˜uw^\s(Ø‹å§AŒâœ<26I[ÒýSåkÌ¢„ ¹;ñôK–ßè{×,Ã^9QÈèðè(ãLœÂ£Ûñ½s¿ ã¾õèê…Óé'Ô²„l)±áa@jçOômS‘øéBEÒ#ôª¼„¼Á+m“pï( )g¿}›Öz¢ïzöèDË4eà¤ØF—ĤÞ8ÍÌ.9›Ã?í²V{>Å{¬‰ð¡>Šg,¾MœaoMzK‹ãëÜòŒµÖë¼1÷‡%%Žaט@M! ÞX+Îê †èqhå¹R–+°x„cös‹ úòmD½\¡‹¹ ³²ÕçXXxÁ¼äV½ß$†%a¦’`T*(5¨ðºÉ³—Ôˆ°Žáv?HL6•Ìêh­ÚÓC™eš¸<óKÙ¨$Ï¾Ýæ"«¦¹x ´Nn‘H’ÝA®Øwgz…FÁr.ññ ‹£õòbÀe¨FjF&æø^†èƒÔé·ªF%²Önf“¶vhÖÓ¹\äž»(Ž@tkOk° ¨ctªßx%o5òsOáì…RÑ( 7_è{öD˜fT©’4~±¬¸X êØ~íh}©,dÑBÂudÎèA¾äuªa»ºì,²ŽŸ§ºÓQß.èkeä£Q8‡˜@›!`¨(F~©ü>§ÑÚÅŠQæO£¬é!(ßC–÷›¡8?Ÿ7/è„QÏ5¥È>™K¥U¨skЈë®3ŽW¡Ó}ZW'Ì7¶¬¶°( •4*îgª[•Oeõ¤²¬>Kdi‚n?g¡P|@]z›®IÉìceM;ŽkkøNgœßámí²oõÕ|ÜÖ£Mh@{‹£ºøT̽ÛË×îá®hå½èƒ”æ`D´ WqnVÞafÒ¼Mfù‡DP 2ÚÐVAîã34t&¯ÓoC\˜‹:¦Üh–ÒÓsà±âeìΡò4Æ2߸<4-Ùêw¿°Æª¨ãå"ro/é*è ÿ^¸mÚ18ʉŔD¦ÜÆG"`Õi‚ìMKo©{|[œ¹Vz7êþ°€Ô2# eŸPP€âÒrjsíøNˆº.õÜÅç²pêŒÔ'Ð>°“ÔF©©@‘ÐW«´IÌqÔ#ëç“(¦v€}¿„DÐÌVj£”&ŸBéoP²™·;„¾†ÿË¡– µ9úÜàð;ɳ£Í"èi.Óîv˜RIj :ß7Sƒs™‡‘}±ŽØé]0ÊÎ_ ·«´])¹€â2ò®CÓz=ý‚àeúžTU°¨©D±²,êoWÛвÍ[–Ÿì<¡/‹Î®6¯ f-µ]…–kí/¿Òufœ¥l­ RœeYö´¯µòݲN_ZÌíÕ—ÖD×Þv²ÒÊl(l³Ï±¡Œ­ì¸}=´­¬ÒöVÇM{Ö“)?}¿q¶Ò ^õ¤´óPÝYU&|ÈÓ6 ÉVÖs’ò_&À'P³yÖ³Õåcâ¯s"® ²ç%h]”ylyî~¬óSœ¤Q’›¸vŠqýµ²ì=x÷¥êsE›^?t¦M¼‘aht3äâÍ¿­G¼¤<¼]3?&W~Š_z9wŸñxnæ`œþê¼¥];J8쟀9O§šÌÜÒ–Éa&Ð&ÔdcÅ|é>’êK#¼—>'W]G#„åÙKÚûí‘èqj#Þø,Ñ•{*÷›H#ž;§àÁ;<ðΊ-&#²1ãîÁÿŒVÀB\î7¯Ë#¥…5–ŒÏ ᘭÍXÖX,š†Ï¬2YÿQÈ—0yîhéʨ8k7^µ¢[­÷0óÿJ®íeeKAŽgNàw8¿Ã¾xÚTF¯ð$,}-Éé:‡ÆÅ’¥¿Cî™´'¯#4]©sDx½˜Î”©KHÅ’¸1ä.¯—/WÃì\Ô™é¯ 1q=çtEÌ3ztŘ¹/b0 ô*ªõDû*êÚóï„ðP‡³À˜€} gñ_åÅÞ9]´î.iÃEYJÏß]?ú ûñ?;p4»Uð„_pnþ¹×3ûpk äòìäd»&• CÃQC³N¤“kwuý5!íbMÚ¸DÄQßoæÖ½¢¡)o×§Xœs‹æŽ0—hPKI/¤ÿÛ_R:—":ý)?ŸŽmÄ‚yð÷.Ëš—âÓ]‰xhd¸FG26Fà7ÞèÞ™î#m£î“ºU ¯è#„µ÷›jx"Vf÷Ô[›cñÔÄX¢›»<â¹`;^[¡F‹k9 ë7 [Ææ·ñ^À¥Q`…_mGÖ-Ñ´¶ƒ³¬Ò”3úð;\Xûßáõ]#|Œ 0&À˜@+#à¡ÃЉ“ pÂÔï·¢Ï{Ïbƒ8K#—ÉÛ¶bX*NÛf4*õIÁ37Ÿhün¼³r‹ÔÇaÒ¶ N+ŒF¥”Ù ¨B²¦™X„ݽM3BLû9mQŽ£6Î탣hX®k6KyŽ´Y¬ë`_;LSʜvÕ}L@T‘ÈÒ¸x•Öý[œ´öàCšµ­kl=6”fý:#˾¶¡Y™‰¸oÊ-Ô'NmGèµqÙËò,º4ì<”‚É ­W3Žìj¾wëi_—ùjTÒzã6ˆúÀ^úÀŠðå·Ùˆ&¾Î²rDk)­°ºTÛÚ~Ó˜êV“_ÅKU䳿Òä¿°¾’°Î’²)k.Y¤£¼‚Œæ´ytÐ#†FÄ ˆGÏãQxl7Þzz¾Ì*5S·Ù‡—S’eY4*‘?èI4UpÎã÷#9N±8“%wéVê6®o+ÅŽ·?•$bì`K5õåæcL€ ÔG G7¿OÓå4äfr:ÍÒn†ó'E# h M2*Åž„ŸC/ÑdHñÀÉÍ«°ñHýw³"·:7M]°þ‰¸WkTÑè0/ÙnuîOâ‚ÂBtÈÈ?«F%aÄà;§¡§´ƒƒ_§ÁòYk±ÅãÁ¥ÓE£’pÈ3„BVÓèúäÃ’QIˆóíŽ>òÁÊÔjÝëÉÑüÃÚ-I$´ÛÍ=å‚nåÃÞÊ !· H@IDAT#Mr1(¸¬x ã©Á%ßúK˜€ÔÊ÷ÂAÍ5ié™ phßwp*žø¿$Ѩ$d íbœ ES%Õ­úÜaõù“ø§1’QI<êÇþ^N—‡SçËÕ<äe]æ hJüŒJüoÊkŒe3&À˜h†Ü‚pãУ’ £'®r³ª¬ñ“¾‡¿>(Çëp7õah'[ꢓ:N¯æSÕ¹GÕ>‹¡÷¨F%ñ8¶’†Ü5¼õœ8“]hT²&Ϲ6‹¢»ýí0×ôÍÄÐ@ÅT£’¢‰2 YÙo̯#²ìmjõñ'ç’qL0* ›WWŒ U ÓßôÝGmôM©IØÛ¾®Ä¡/¥™ðO¨ajža16NÚÍûégìiÜaeÌeoHj¯Ø›ºµ¤3>œ¨Q¹¡'/”C0$i7Á$S6%ÝwS;V°'zvòC0ùmn.›[P,¦ÍUÕ©«(BÚ·›±ak†·cÅGè½t†Éf©¦’K)ß>c1of’:B9ìž…Ð)# .ïÆs“1"Ü[•¯ äïߢŽ,Hz`5ycLÀ5Êñã{GÜ‹òâÆâÉÿK°E#Û¹ÉnÂÍ&vê9`(3v&Ç]ßÅü0Í; A'sèÍŒ,©k§ŽLR'; áÚ¾^·`ôˆ ¹V”G?úô×GÊÐt)%›øë.ª4k7™å&ÀÌ $L™þ¡Ú{Êáý¨Ù•CãÏŒ·³i¶ˆ¤ë<;õ†¤¡ÉVqIq ì]õ |F‡ †F?ŠÛ•³&iy‡ \]üçwøÕ½â¸4&À˜`Í@ÊŠ q±¨WªjQq&׊ŠP?é;'@¯ŒŒ5I©í,T”Ûq¿µbB¢y vÈSçþŸ†v3)©Q;6ä5ªÍâ@;Ì}3‰L4é;n—d¶¿m¨-nÈ-Ô>n5>( É!õa»p²ýíkƒñZ§¾öÏ6{€Z¯’z@Þ)YSu°gS÷sÛ+R)µ‰@£ KÊL¤‚RC½°jê~Aq…©ñIÉÐM3³I‰kN¿n¾:ô5¾5¯`ÍWB7Ì §Ñº‘j§u"ÅÈHÔ=–\ÍÈ6\¹žˆ;[l]Qù9Ÿ K‘–U$—T‹®ièPçd –Ü_Y&ä&À"@ë$}A.*wçH¹ô#§â/ãb-JtØ«SwµÃÕwÀ8 Uïs)¯ghÍ2ø7Öï!CrA..Õ´C½´êÛJ4|]:Yý²S³_„…•÷Z–¼Pœ†OwI#R0ØÄ•±1&à¬m懲ùõœø@ýF%Aôo< ‘—uÕ#Ã-^Bî>Á”Bp}€öv|_uêÕ‹Òž¥9jcÆ¢xîM¡«¢zÄ¢o,Ïœv1bç ~‡;Œ“3&À˜`­‹@ÝYlSŒJ“0÷±±• CÕ°â:ß+Ñ©G¡€0+û M{hø ©oB *$ÂØ‘²šõiVf‹kQkó\«p£Ú,´Ã¸oÆx†Ý­ xF])ÎäÈi¼=héÞ«Ü7EËDDEÐúç‚þá¸>>Žzè4^:dÕšúÇZ{¥°ðBSÛ¬ä›ZzTM0 k$Åé;˜üâ„cÊfo:%}sü-Ê>©ªÓKèX6nañ‰äËQÚ¾ùögã9TNE…r8,Ì4¯¹s»øÀÂqIñ ®Ù"¤ã ´UÚ‡–Õœ ¦úܼµU2Òø˜„{‡ZqAiÑ­+~7R^ÝìØ—ø_±ðrÔnå8þ“$ÃÑÉÃx¼®¦ÅÅÅâÿò£ñÙ£C(ðò¶þ ™Æ%—´‚ۧ·¿·{_¦Ù Ht¨(û„DaÓó³B"Á™€K ÔÑÒ£ÊfeÌ“rÈùß‹e´€¨ùGo9Ò¿ÉeÆ OW­M©¶ž9š$=üϪ½›ö™,rjKP“³²U0Ç·Xü—O¿Ã[ì5ÌŠ3&À˜¸zÚ£ŠÄ-râÃèã®…y™H?á…a#iݧи­ÏFécÖe{¯‹îy¨_uq>yZZ«!eÌo-fS ñ¼1&Ð8þAÂ{X0 çáûŸ²ÑC~Ÿ7Nª&7}ø¾øÄLž5±aô­P‰£Û>QŸ-!#‡ Ìú§•F=ÓlÛAÃ'œÑÅ)–õ©ÁÇ\FÀ¹sSÜ´}øvï!œSî`=âo¾ƒb-=W4¤lQöœ¦õ<Ü­õ²‘‹&÷Ž=Ñ7’Ú€Ö6ßsÑ%?s?vïÜgòÌzËêËâÙìÖN]“ÆÕКIr ™‘Y¤G¿:œ=²ëÖ)ýŒyøùL)¢ÄuÚÝËï±á€ÐŸAëÎlX§~èáqŸì„: ]–¨þ¸Å`4õi~*Z ÒðÆüãˆÐ(<ŽŒ¡£ùlδYTíh‡5iߌ‡7BI)±Å¹u²oG¤¾uUw[WʲQÆÁ5KpeÜTLÚn0ä§aÕKÊõ§Ã ø®6ršF»¶ýꆸÛ&`ãõâu½cÅS¨™ü’"áEm麚JŸ?SÚ£?ʼnÍk—²²ÝçØ±£å„S­kÏÚ+¯uÕÐÁÚœýöm©sØ_‡ž=:ÑÓ7'•9ÉŠI½qAæ=>nèOðáô•´t¾a%<î…˜P2Ò…G…´¥<<¡fYë O«V^tއ^™Ú dâ_&À`È݉§Õ—ÈÞ5ËhŽ´i9BŒÁ8€Øó)ÞØ#'4ùñÁ}KŸA”²LsÓ ÄƒâµÏèn¾LU ÒÐ3.U§2'/„‰>cq[‚©ØÍ½å– KF_¯Ra}'ÎDâaÒUÌ‚ VÏaƒVÿd  Kôoðä{ð¿o‹SÍ36¿E›µ ¥°~äT 53R;;âE;#ÃU~q-5æ&ÐrèzÇÒˆ½4ñ5ƒÞçóÅ›5¾4á²ë {ï7›÷=[Ö¿F–ø^¾¢iä%`ò¨(»`Õ÷̱K€•D}'ÍFÒ Z—NøîÉÙ7þ¶ÛBǤÙ}ɰ$ °±‡••b8ªàw¸é çw¸)ÞkZù7`ùºƒ¦…aMú^$Ý?cbM¿g…„åÙ{°ì¥šw“”½pózìÝ|3—L¦0S‘ îÕœÅÆ'_–¿…© ?{{¿OÂc…ά,¦r6Ÿ±Ë“2aiY8Ç4§Î°Øú ò7V)º?òŽ¥á Z¢`ÑܸVªÄO«×b‡Ò^ÔÊTÂÔæ{òù‹õ´]Ï9«K9ö¼÷wl:pEÑXú%&ëé™ñ¿Tr-O®x»Š¼B߇ Â,#j?¬yšÚV¶Ý+ãààT<‘š@ƒUbôì—zJ*rNÝØuN@JŸlßuÂLŠ'nœ2g_¤ç´ØÿyŒe%ŒKAñæíF9f¹¯ö®£mýìn‡5aߌ[(bûà 8øX0䥉3ƺOœiCëYܤ"òŽ+eY“/Çel^‹ ê›òí샊ã3"nòŸmöM`«­\_ûÕVs•LÚ×ñ˜u÷¼¸†Ú¬´í^¿’þ“ŽÔÆ® 6¶¸Ñs7† KbëÕŬlõ9>ú·G¥²ÛÈ_­GŠ6Råú«ÙÞ[è¦írN¦kŒJþ½pÛìù˜6؆%Ö+Ó–ÎFb„˜(8a4*QÞÔǟˆH©#FN!þÔT]îèû_gñ‘¡MËa&Ðf ¸y7XõoÓÖ¨{ÃYHf„Õu’‡Nǃ“Õ2…gbTê9r2žœ™dq¯º{xªéÛ›éòÿ:þùE˜4²—šFÐ÷ÓgDcÆÒyH ×&‘Ãz¤Ü?‹5órë¦.\XŸ{Àö¡^ §`oÙ/®•b9Š ´%Âêý)ª;©ê43¸ßdãT_Ófð"’0yJ²$_cTòKÁÜ—R¦äW²)Ïå^•ãëæÈÏ#³<ŠHå×b-'7Æ,\Œ©ã”$ô=¤1|Ñ÷Lã³ ²2ŠáP&Àïpùäó;¼ ßפêåÙ;ŒF%ÿxL}|>{d2bdÏË»WQ§ú9íH,R³,o¨F%=ÆÜ?=9“†*ߥÔöÜç(v¨Fåøz…Ѩ7q*{f>&‹‘¤ìÆ‹«ö#Z£‹i逳ùêSÎ9™N±¬O >æ2Ξ›£›Þ–Ò&1#Çã¾GæàÁÙ©HˆUËÙŽÏö8¤§WGcr¡cÓä?ò2¶ù”¤MrÏQÏ ]27¿®•BŃ æcÎã¡ÜýÂêÓ»û•jò¯³¼‘4}’"LóûF$â¾gžÂÝ#•³CÞ“h-æ_äçhhÂ,~ò~¤ M@ÂÈd$NĘ)÷cñÂ;h œ±ÒDªGWŒ§vÀ}SR0 É#‘8r,î{òyÜ1¤;Œ~cLr6Ú*f©ìßµGž£m¥tGÛaMØ7#ÇRâ·…tþHÇÂJ;ŠÖ þ6(˦TŠEÛP.9qòd$÷‘t5•|L}S“š÷‘Ûn+Ûn¿ÚÎ#ª ´­´¯uñc±xÁTÄEÈÊÒjT¢°¾¨És·AVF1 †ìëslPL‹OÐnõêÇ~ÉÌÌÅ̙ϊ•éªwÐ:jA~i%ÒóJPP*=°:z‰k0] WxÊ"Y!!¬hfG¹ë(+»„’’JTÑtå:êj  Fgà®Æž­ÅçrQTáßöu¨¢Y ]ì|@Ø#ÊiÍÃ:°&ÐR üj ×OgŠàæëƒºŠ:ø‡…Bç«éTu¢bu†R—ÿOSøúj]ø™ ¬®(EY%¥u«Ã•:Ós¨q¥›Ê·wŸ#ö’ât­Š@]9ŠŠkÄ{ž¾ðjÜÝ—ûÕ›xmó  s ž[˜ Or…Y$|'Ñ·†›O ‚°]m¸uä> ¸B\ëÍÍÍÞ~~ð"×V7;XñsÄ*9ŽlBüoB¸,ºY¨ÿ¹ZŠ/žXŒÝâì‰Ì\:‘Ê ýŠ,¼9•4òœÞI‹ŽÝB×á膧e÷Í:L~æOÙ_½ƒ76gˆuO¸{áÒËŒNYæ,^)&îI£±ghFcgm{“ÖD¥w#mÉ/Æ­‘Æw¡³ùÌŠ7ÙuN¦3,MŠåFpýu.(SŠ/Ÿ],º!y?§-ž\ažŸžÜ›?$»7o¸ •ؽ|¾ÈÌ=iØÎÛ4÷ÈͲú§á©¿I.¥B†NÅ£cj²ñæ#+åÙ*‰xâµ °ïî7ŠàPýê¿Î¥¼åÅE Uàæí‹ _åYY‡2Z繺Π^ð³õ­®_D×÷ñúÚ$Æç¿šÀj øàz<¿NšÁ4æñÅH SÊ·šüêFÚÑfqE;¬©úf„óZCm-¡Ñå YÞÁqŒ®”…ºï–îû”GžÇˆpZ–¢¬å´B]…è$ºœs\˦Ëa(+&ýãœ<½½¨¯ÍÛf?¾KY™UI¹ŸɖМ¶Âüs¢:="{¸T-w—J“…)k*)²ƒ}ÈÁ“fÍ%%¾YþÒ.A¡ôßYíÜÉ/Zgñq>&ÐŒ´ó Bd”Ó«5qó „NiØ[MaŒôô¥´ò´âc4‡˜¸Ühñ[KA.)YMè!È·œÉì’\!„f™éìl46!+WT…e´Müo›çk-¨Î?"•h]ÐÉãŒF%á0­<.5/ k|‹£ÅÃÐ_tõ^ŽìWD¾Cǘ•„ÈÈá£G†¥t üú0þ³qRµcÏ :í JZ£ô{ɨÄã6QIuËXÄl}Yt'¿ï»Ÿ‘/w9›„ºXçX µã­© 8}n —Y i`œ1 Å"4‚B9ÒžÉ_›×–I*Õ“„i¬µ½¦¸çLË1wÑnzÔ¸W^pFv©ÃïÉE»ÉFÞyn›åëÃÂ^ü7wu2Ûùh"ˆwCÀÖ6µl9Ð3W\óT+¹Ùihßã:„™ \£µåÈ¥éA9i g/´S3ÖgãH'®‹êjb0(?wïÉF%á9~F¥âÜLäÊë—©Ù¸v·½™)ç,B­¹ Úé­®Azäh>–"­¤â¨fA îö¬Y/ðíÜ ½Â¥çñEZ3)OU0#~ªî â“{°^4 ùÐÓ½e#VÒÓ‹Ôt=S‡Á4—zÈJ ?.};¬±•„'_kÅxf=µS±Í¼fÈûkäõ‚ì©_âì§0>J~ßÚ“ÓØ Ð ¯Uš6Çè&±öxº¹!Ø×†»”æHubL€ 0&À˜@¨«-‘¤_¬¥»qt`É¢™`L M¨Ãå‹ò;Á6_û“˜xv솞ô+v%× ncL7}ˆÙJÜâaòÌÑ%ŒB’ë:[ 5Ú^éò2u]Ž @k®å=Ú½.È$÷°‚*‚aÉÙ|”U»5^—ƳÔêÃaWh̹ñCŸa1Ø.ÌÚ£®öõÏ-©)³1T ï=÷©4s'n<+R+j›\[fÇ‹OgàhæøÐèþ®ašµtÍÒiw]vÏi…RØq]ô°âýÙ-°“hPPÌOfÅðn3# Lb© µßÓÉ€ªÝ|û$c:­£®$R*Oõ+´Þ¼äöN=$ÑMcÌ×Ó1¦° y£wj ÏTÀWYãÇ2‘S]sž¡Ñh*»OKi‡ytŒFÒ€ TÐò VnC ½jTWø’¼©ˆQQô>VÖÕªïy§Qª›ÏµÚ!*OŽ–¨;ë̘`L€ 0A |Ø_ðØ€rùìÕ´#ñZ V’ 0&ÀšŽ@%òŽÉ#Ì;G#Äš_˜:Z XV êŠò FOêf§u™ò¾;„²Q0QŠÃßHF%sݽº$àî»CI&¹æéf=m(ÉC¡œ8º—éì£ 2(‰›Wo;¤¯³ù1®ÕÅI–b}øOÓhܹ <w_\Š5_I÷ÊÞu+ÈÉ›¼ ˜„Åÿw£…K%[×–’­¶R U¤ïÀZy¦ CbêDŒÜ‹ä™ ,j‚{ÎY]:F ¦æ<ñÚ‰RDÆ*¢Äß²ŸÊk,™DóNs$àŠ;^YŒ[ /¡¨¤WÊ ¨¥g~›/¹yŒ@¸ Wܺ„T,îs+.](Bqi šó”Ï7¸ º÷è?7³ë·Áº»!rðXD6˜®é´”v˜[@Æü_TÓ±§¯pÌxf>­ßEïÕ@kƒMìÒRÒ4Ÿkµ¥Óêù퇙`L€ 0&À\O@\_mÒ;Ü\_ KdL€ 0&àîýôow¸ãWK$4z¼£[x,åb8×Ý$¯õpy/>üêgq‘”¬韽«®Ûd!ÐK‡èøxÄÅÓzZC–›f«&¨ÍïI³:¤­Ù’&p6Ÿ È¥º8ËR®ÿ4!Æž2®Ò, «[y1J V:Ñm][¢š}×?ž\ˆÑ}×Kãö±{7¬Â¢å_Óèó{± î9'u è¥ê¼wÕGÈ,¦J›!? ï®RÍnJ4ÿ6gºC¡]‹¸„ô87&ÄÚ4*)Uñò BXdúÒó¼?廑òõ w¨¤Hl¿Üs檛ÑE—G8¦-™ÄMNö~%•ô#'aÒÈ^*3íRJj¤EÀ¸ˆÇù ¥GM#z!&Ì2ÈÇeZÞ/Ô|²Pe…º(wU­Ñå•ÈÁ7ãç.ÃÐülU ÎÝAºîÓ¹áëg?•Qéào´ÓØÄçÕ)\ìT4¹X(/@c–úJe‰#¬BA’ël>3Ñ&»ÎÉl$K xǵœ?79ÿ=(©âŸ„‰C»©j颓ðèsaX¿dÒÅYFqº,}ížµ¤Š2|{ >‚V/Ê¡¨‚¸P“Œpó{Ç…÷œ±`+!;t 8†œœ\¡5vÜÈ5ZDd~“û56É"ÃT°•28Š 0&ÀÚž±Ô¦N7W– 0&À˜`L€ 0&ÀZ3ÿP¹zyÈ=oiÐ)?—B9ET·VQ…F":6}££É¨DSCÊŽã»)iÈÐKc•5)^þ÷—äeX™­Rœø¡HJàßÓ¸>“³ù¬é Ä9)Ó,ø×µœ;7å8{L¾æ:ÀÓ\¥€(¤Lˆ—c5ë~™§³{_k¸5 J»k&Ã%÷œ™LÓ]má¶uiç„HºïûÒýÙUœÑxê€lŒƒ }”ç‹©tÞcL€ 0¶G€ Kmïœs™`L€ 0&À˜`L •ЍºßúnÿÏfµ¤õevî–ãb0𺠳ãÖw~õ*äCƒ÷°žÈ"V‡ø!²#°œoq´ø“ÕçÒ°[˜B[Ï[~ £&Îæ“dYÿëœÌ¦`i]?Žu”€s熦ï©.ôÎà’W‘ÆI|:tŒªÙêJ‘Ÿ# èÎ^f®ðê‘íÜ=W@gu)NÃæ]²1®Ï0ôð­§ >Ę`mŠ–ÚÔéæÊ2&À˜`L€ 0&À˜@«&à‰[‡êÄ*VìYiùju³w­Ç¦cÒnÈè!Óºåª)EvÖY”×hg6T"k×;X«t,ÇM€PÓyuÅ™ØøÞ|üÞçÈ,Öæ"'Cꇾ‚ +ÿ…|rÍ'nÙøà…-òŽ#t•ÃÒ³ù\®‹³,MjÃ;MBÀ©sã¨~ʪGixëÝÝ(V®IR²,{Þ[Ÿ&«Û !F?’õ][@5ŠÎ壼Nc8ª)Â׫–A™ëãÛ+”î³5ÏšàžsV—2šÉ˜[Tíl(:‚7ÿ¶^á8i –³¼šää²P&À˜h x¥–p–XG&À˜`L€ 0&À˜`vˆ¾m*Z†½4#hïšeHÐ#¨òò ®H:'áÞQQ&Ò yûðÆŠbœog=º‡z¡0ý„Ú©Œˆd<1m EÇrMIöÊ®²|Ý‚è ?£Ü€X̺;/®¡îõ‚½XþpôÁ(ÎÉSg@%Ý?Qæ³ œÌ׺8ÃÒ€CMIÀ™s>tb6¯@)V‘¾Ï?ü5zÆEÐ’d98©Üt,ù‰3Ú•Pïµe8w^X%Þ+!½dнcÜb0}b<4âÄCMrÏ9¥K9ö½¾;Ä„>Ð÷‰@. CqHÚ&=°7š•õã`L€ ´E²·F“uH³Õ{m¹µ'CŒ´æœ01*õ:½4áÚÙrÚ&¹çœÒźhY+ºGeJþ1˜üøSmý>•3ñ`L€ ´AíV¯~ì—ÌÌ\Ìœù¬Xý®úð¡°ð‚¨HH§]W)Ï<\E’å0¶K€Ÿ#m÷ÜsÍ™€«ðsÄU$Y`L@"`ÿsµÅçrQTë‰öU4[É¿ÂCM;ÌM˜ÖT¢¸´—/W¢ª¶ŠÜbù sXWY1™ä³c§ÎPŒÜ3%hO²*hÁ¦Îá°ÒÙn.ÊÙ|ær´ûÎÉt¥¶@;E É®sY›êŠb䟣õƒ|}PWqíƒ:!LWÏýQO-ª ¥¸t©•UU¨­ªƒ»OtìB׸¥±ÕDLÜsÎêb %¥—QYQ…ªº:´èŒð° ‹™V&úóN£ Ø7º(À˜@PîçÀ à&.É1ñ…ùçÄ ="í]'Ó>ùì Ï>NœŠ 0&À˜`L€ 0&À˜@ #à† °H‹ÙI6+áá ðßf §¸y!2ÊñYÎæ«OQçd:Ȳ>ø˜‹ 8wn<}ƒîÄ5iMyO¯@„†9a”j‚{ÎY]¼ˆG(ýç 0&À˜€=Øž=”8 `L€ 0&À˜`L€ 0&À˜`L€ 0&À˜Ø°Ä`L€ 0&À˜`L€ 0&À˜`L€ 0&À˜€],\á)¾íÊÝŒµ–z¸ 1ópI–ÃÚ.~Ž´ÝsÏ5g®"ÀÏW‘d9L€ 0‰?WùJh ø:o g™ëÈ×9_L€ ´4hø9Ò N«ÀZ8~Ž´ðÈê3&ÐìðsµÙV¨ ðuÞPYd³#À×y³;%¬pš€r?;- …eäK-성ºL€ 0&À˜`L€ 0&À˜`L€ 0&À˜¸Vذt­Ès¹L€ 0&À˜`L€ 0&À˜`L€ 0&À˜haذÔÂN«Ë˜`L€ 0&À˜`L€ 0&À˜`L€ 0kE€ K׊<—˘`L€ 0&À˜`L€ 0&À˜`L€ 0FÀ½…éËê2&À˜`L€ 0&À˜`õ¨-¿ˆ´vá‡=iÈÌÊCQùJíƒØacpÇ]·!JçVOîRì|çm¼¿ùGTŠ©|0`Òý˜q× øâ×zòÑ¡Ú*äçžBÆO?bÛ¿àæg–clöÖó.âàNÒñ€¢#àíøêô|Ë$Œ×pyÖ%ÛŒ-9¾¯/G T^ĸö ÜÔÃ×zžò³øîÛÿ¡ÆÓÓêñêjÄ¿z¯¸XÍ­‰üµEÙiؽkÒög"¯ PdïÑcÆßŽ?$õ†{½ìqÎ4j´´ _çÖÏXë½Î©¾Ž êBº…QÉL¸å®»4 hØ´ûðÌÿÀû[>À¯>ˆø`9é¥Ï±|c–e>'bJÒ×JÁÃñÂ'Ÿ`Ë1H.kÃC·ã£ã–’e¥ 6ý¢{G/Ë|ÆÔ^.sž_Ž·>X<ŒxEΑ0oå>eOóëü9Ói™A¾Î-Î[ë½Î|ÆXâ&À˜p%ýq¥J,‹ 0&À˜@Ë&àáîÎ7Zö)dí]D ¦¶ö‰b1L€ 0&`/¿^˜÷ê D N€N3»(òÑ×ѧ«23&ë¿:Ž›&E©R‹ö¾ÕG¤ÝøGÞÆâ»úˆ;úéKP= }“fÔì ¦§Ð,$S×qí»ÞŒé…¸›!8ÿüñÞµ’ zþúÆLÆŽƒSá¥ÑÝ"ðÚç¸sè\sŸ*.JÎøêcÇ¡‹X?ç-9]"ÞØü,úù ³®ºbéç˜5t¶8»kå£ÿĸMSm¸ßëW¾_‹1ŸE:˜¤ç-bÙðÜÔ»£1g¼þCÍ>û‹¨_Þ»Ÿ!ëþAˆÒ¸ÝkÌ93ÔBC|›¸Ö{ uæcˆw™`LÀŸãËÅ@Y`L€ 0&À˜`L€ 0kG  IýMŒJŠ.1ïƒbJ25ÚTaß'ÉɆcî]1Jñ7ជ0HŽÙ´a?jÍf-¹ëúáλRÓ-þ>Ö×#2(ì´s35*É Úu¸£b-R;a8µ d×~Þþ«lT’Åuè‡(3²>Æwçkm–cg­læ¯ï€oþ¦F%%±W?Ü7£·¼W„RõwΔ"Zî/_çÚs×z¯s©–N=c´€8̘`.'À†%—#eL€ 0&À˜`L€ 0&ÀšÚÂÓ°ê\Îp _î’ô ? ÝÌUwÇÍC¥ÈÒmŸ#Ã`žÀuû¿ýŸÈ3§àéÑhÁ§ö}#ËÄàC-äuë“WŠ··8®D¸7Þã"Êß*œÎ´¡S3:gTèª$åë¼]çWåŠáB˜`LÀlXr†çaL€ 0&À˜`L€ 0&ÐÂd|õ¥ªqÿþÝÕ0Š‹äu™€Nup‡à*N»µGÏ~ÊM´‘ÉÌmºÆ…KÎü€çî™RQÌ ˜s»éÌ)‡¥ÿZ‡‹g¥õ‹€Îó·\ À+,Ƹ–Qu"®`ϾŎ!¯¤ÊFš&ˆ.ÿY5ø!"½ü4e4“s¦Ñ¨Ùù:oE×y³¹ªX&À˜0'`ù¶1OÁûL€ 0&À˜`L€ 0&À˜@‹&`8µ3WÐ:Iâ–ˆá}ÕúT\È×4"µ'5… ƒ’¸]A© OZ#‡|ÄáC^z% (cÞ±½ÈÊ‘%DLÀ[kç!¦±kµ+Gæ^aµ&ÚÈ0nMçÚµf•eW¤´ÊßÚj9”‡uOÌWb¡x'æ-œ†„n¦kM© \¨Â–…ÒúJ‚¸øI¿CÁïš3—Ô­é„ðuÞº®ó¦»RX2`L€ 4–ÏXj,AÎϘ`L€ 0&À˜`L ¨=ÿþ2a‰¬a ûüY2Úhv׬ ¤ jRÀ»£^ÞÍCz¶4§H{ܹp¾ß¶ßÐÕ¨$*+ÁÅ %Î‰ÔæúÕד×(òó„UÇz^ÞPk¶÷(ѬÕ¾S4ÅÞ€a£†#>VIEF°ýá¯coÁêµ¥¹.L3­¾{u^Ü%‹µËÌÖ½Â5;g®«¦«%ñuND[Ûuîê‹„å1&À˜€ËðŒ%—¡dAL€ 0&À˜`L€ 0&ÀšŠ£[pû]Kd÷rÀë>ÂØím*één½› òb±š§c õ4j{íûâõ-ŸÀ€”åŸÂž­ŸcÝFšUui'¿}'Æ¿ú9æ&u6J«ÍÁêEkëå[5¨2” }÷q˜7ãfxµ3 û€5Š©µ•PkÖ9ØÄøäÞe–®¢¤DmÉYìØð ž}s¯·îÞ'1ðû•è§™Y•·c5^ý"A¶eª¢‡Í‡áݬբ[ž¸/n“wCÄ/Œ‚—f¶’ª¸ªç̼ðf²Ï×yë¿Î›É¥Æj0&À˜€LÀE_ƒÌ“ 0&À˜`L€ 0&À˜hNòv¿ŽÔ‡>’Uêg¶¼iØa4pœ8Mkõ­ÏÅÛ è+ú”3_‡É‰š·sƒ®[W)c·Ä Ž?ÝI†°Û%CØÆ‡^Ç„ƒ‹©ô\.bÓ¶ª‘Ìv‰Ý1K0, ”ªÉÃ…Ú_²¬dŽCÉm×˽CW¤ÌXŠUÓ0ï]¡#ÿöŸ,A¿¸@UÚ¥£±oWÃ3º:Ü5Ëò\ÔžÅëSodž#’¸¨iKð‡„zXÓé3µ¦Í'À×9‹V{7ŸëŒ5aL€ 0SÊç™i,ï1&À˜`L€ 0&À˜`-–@ÉuF£Rðh¼µy©û;MÍ|»Ç Šö³è^n™æˆ1Xv™ NâVêZc¼«C¾½Çâ…Ÿc曂áæ8òÈ#^¤N.Å//¼!~5Y9Ș`L€ 0&À\N ÿèwØòÏÍØ{(•$ÝÛϾ¾:……¢WLo\s=âûFÚIïruX `Ž(ù sî}KΑˆ76/$£’6¬Ê¯#bƒÉ°t‰þ3âÌfî\ÄÁåIò‚ûCon‘KrÕ·¿2ý"§ *0D§ìû¢_¢Ñ5=å‡÷¢d’‘êèÉr$Ä)²¤Ü¥ÇÓ!× úXo¯×WNÑeSc”o·~Ò­¾Ö|sVË3•âù‡lT²žVŒmfç¬M›î_ç*ÛV{«5䀡è6~ð!þóÍqñ» Ôß5l î¼k btö"ŠŽþ€ƒ§ÉZï†!ÉæÏy3ƵUÈÏ=…ŒŸ~ĶÀÍÏ,¯×ªYnqסò¬ 0£õ犲Ӱ{×>¤íÏD^A¡ôÑcÆßŽ?$õ†» c¼¹(aß~ýJ±ó·ñþæUö&Ýw 2{WZ+ÅŽ8CV>÷’ø.Jíì”aÉéëÃÉ~l;jåÒ$öŸ+Ç‹5”àTÆQø~TŽÀ²'ëw?+–`ƒÛcßë¸-8–ÌN^ÅÉ­xü‰µf±¦»©«·bÖãTwåhíùðø¨¹Ø§DЯ0>/ç8ÒvíĆO.ã‹÷É#§äDôPüáÝù˜·BòÑ,Æ^s!ëÈ!|³ñ#\´Qž,˜`L€ 0&À˜€ë”Ãë³îQ]1™ :gAߨÂß@¼B °„&î`Jâ 0GTaËS³ÅÙGÂ}úØçKLÖ².©+FÞÞ…YBG>Æwç'#¥‹›šÔpü+l £“°Åß}+Bëé¸3梾Kêâs|«ÀáoÉÙzã†îÂC¦£X„Þ4–fcmy|²i?¦Ä ×ä¨Â×´æ”´%bÜÀP 6\Ö™ôŸT¿ëßU ;0ÿ ghÑ5¯Üg‡®;gÎê}móñu®åßz¯sm-¥pãŸ1–2›{LÞrk:OyVµÍ{÷%|Cÿ§¬ÞŒ{t4°úµè;̺k¾lH×Ó7Ü'V¿ájχ§ŸzßìWLî’°Þ— °Ï€%ä°·|÷-UÞš<9yxy×V¼{'6¬}z÷†ŸãvëgÈÂòÑS±Q~*¥æ-‹ŸRyÿ´¯<%ŸÕ_wsâí­Ïs°šM‰töúpª[)ô*þÚ}®Ò© ?¼³ ¯¬ßŠ<í¹ˆ¥u!¹Òµ!¯>n`Ã’ jDj~AqE5 5ub./7ùzÂËã7H¹FIݵwp iÔ–v+¥‹­{G+‹pÒH™{ɨ”%'6{1¦¼µ—òqòøñõk±ÏÏßbºþÁU÷`žü‰àáxæå»ÑÛ¿ùgNâÐþ¯±îýð÷qæc\«5‡™¸š*ÎÃ> Õ0bô ScòÕT¤ž²Z‚Žõ¨Ï‡˜`L ‰NmÇÔ ‹åN¡@ŒŸý$õïN‹ÖŸCöÉÈØÿÜÙàßDZ´±¥ÈØ{¹…ÐáúdÜÔ#°V¬%èØ ±5s• Ç7âÅ]%óÓðC¾é¬šòÅÖ±÷oÓÅ8{çú?NGà›óipd)žýË+¸nØ­©@³Žv¾¸H5*¥¾ú9f%ÉSèi!Ò¨¸þH™t/jkÛ™Lɬ=³]•„Ø©øçúûÔ‘_úQHHJÁ½“qÎ];Úǘ@s"púßOáñ7…±&zt'W–Íq$wKб9SÖ… 0&Ð6`å=£ÒÀû°áÕ©ÐýpS‘˜> µ†‹ÈøïY„µ¤Ïû«} §ñÌL©G?-Š:9ú]m .¯%èØp-8…ºš*ML)^œ9[³o N[?Ô_h§‚UËFÓ¨xê¨Ìù¾ékDÅvÆ…#ÇEOBÂÔW— ¡ƒe¹âè{3e­*K lœw6Ê;úÿÀ†Æû ÷»UXIßÌ+éx`DoÄDø"c×!µ,!Û½ëfÙ5ò\.ÂæÏM¿ˆñÛI—K€ ÓÎØÞèT^€¬Á[mwâ• 0­Ûñ ÓZOô]¬G|¿pâ²i9Bi´àU ×ÌìRâý-¯Ð䨏3hšhÁÐo>K´1çÌDt ÜáëÜò¤µÖë\¨©3ÏKB-3Fp×)?©ðÂæe"÷SFõ^€ØPRŸØI£2aí;½¼‚«Íu9öÕ¿}×›ñÀ#½G}ÁùŸà÷®µ/£&•#åi²5ìyË£X6<7õÖÌÎê׈¬›þ"—òÞý Y÷²( n¯~E{ß׸(¥uïîÖ½£žžéKP=‹útÑ~/áÃtê¿5s³ª-¯)ÃN]Nöc7e=lɶ÷\ÙÊo3þW? |èA„†ÄaH¿`|:yBÃ÷ˆÜÎäæÚ,²5°ñÈi\U…™J‚QéTa¹*(¦&@ ·”€-ë½…þix›ü˜µØhT2Kèn6r ãßË)±p©Ñ¨d’J&8xç* ‡f~ÖQdœ8‡ 1çáë ]ˆ¡]áWýœ+:U!ûè!ü|ºÂb´ðè€è~‹(Í(H%¥ð[[~ùŨF?è…€´XáÁ=p¾¤†Ê AlÂè;(FÕ dìþÇè˜'ÍûëþÛ!è×Í8ºR+W”MþQ3È?ê¹Bj¡Ñ¢¹¾BÐQŠî=ôðÕ܇E8üª•Û¡;öƒÎF'Y-5>Ó~:J:Vˆ,:êÐYß“F0u© ²O\–UºŒó§óQL£4éC/´‹Îĸl®·¨»9PÝ÷îÇI±.¾èyÃ@“‘¥2¨£ïðþ8M¬„-¤×k»5VG‹29‚ 0&ÀZ¢Ýën>¨“õŸ«¦ªƒžÌ+èîÕ‘Ö9õ¦°R:¾ è[£(?_œÍà¢Gš-Ptê'üß9ïˆëi=½úþ4eáÀ'Q"¾·{aH’éè}=íýŽ©­ 5r‘sæ ôÉ ðþ²@üY_JîÙ•îÌ@ÜûÆ»˜’( 4ÏéÞð F¿éààpÁÈ$ Æ"òä>~_Ž’·òæñ÷yÞ›Ú ®ØÜ#0wëZ´§‘çh£R±,pè}X³ÌúóÎÛ?„J'/å‘{{IWQà0çÅÇ1q@WWhOcs¢y}aÍ™‰Ó笞’ZÆ!¾Î-ÎS+¾ÎáÄ3Æ‚O ¨õPž¯zšõUèº÷¢Z †%ƒô¾·RÇ’tše©xJ²rÜ<Ê]×Öm’T”ÙÝ3ªŠq´<8ðæÛ£?¬ÎEòê‡ûfô¦‚Ëæ"” F6›ýúUaß'ÉR†cî]16~÷&Üó½9U\eÓ†ý˜7Bý^µQ´Ñîb:á;îp¦ÐWCŸq¶¿ûœº>œìÇV+`G¿“š¶ûÏ•¦{¿ÿfÅ«@IDATÛ¹¡ßhöŸ˜µ~ö¸ö¶“›F›V”®ÖV_Mç*H³øíÚ²¿Þdœ­4¡¿]yP›ƒO•{ÄxÜÔžlœŠ \-%G·`áƒKvÉJ‰ÁSMÖ +Jÿ LyI½´9¢þ4K];ã X8ž±~¦4ú/âAüóâúdYÚŒ~àƒ¸³ûÏX4î/øÆLaO¯¥m£Ìr\Ä–¿?‰?¤Q#V6u}4ºÿ–ÿ‘F,æXID# ?ëwÆ™6b³þõ¦=)M37É¥ea8Œ»‡þEã>ˆFˆÞ5ANnÛ‡±Vž–˦·£ðbòl“uÛ„´)T÷…uòlÀÝ÷¾¦ŽfRäêÉOû›/Œ“\ò¹@GE.ÿ2&À˜@k"P¯V®V(õÑ?Û4*©‰¬þ&¨8ŠY£¤wç½ë>Çuû“›h³÷øÀ‡±ƒ\Œygþª]—T(?x4ÞݺÐbTª½ß1Ù[—ãÏOë­­RàÐñÁ+wZ¸´µç›àðÚéÒwŽ,°tÛüq›´c>KD[¦Örùàsܶ 3—îU‹uGm>Z4 +•oj.=æ|ð&ö•¾q­£*—Í€oßT|Ÿ–ê´Z‘ɳ°ëûIÈ8Vï@”’m)âú>6_ 9S¦~ôì> E…Ÿt©Þdð)%}úî&®çœ®ˆyF/Ñþþ·ø# œË«ñ†Ï•2 cbzØ2’Qw,ǦáçqáB®T×Єt íŠÈn 3/Þö¾/î\µwÚN 9bÚ¦R8sΔ¼-õ×™kN[Wg˜9S&_ç õÆ]çΰWJné¿îê0ZGhå×xý¡²Ûµ*|µ^°N³>­Î"/?Œ…SÞ’Ð÷Ô†¹4óôö—š‰ƒå9óf]ù*œÎŒJ lŽèg8…/wIòÇC7sÑîá¸y(°Ò”nûOŽ@?;û‘ÍEi÷=«sñÙ_çÒšQÊÀåh"–Ñ÷äMf³d¹>œêÇ–Õ°«ßIQ¹1¿Žœ+¹{¿ÿU«1Üœ-³¹çcÃ’Í3t{þó-Êhv†>ªÍœ°=æòÅÀ\H@0FùøåöFÊŸbQuîþ»‹\aó†¤MH{›&­~茈ö¾ù¹hhÊúp n;| ›ÞŸjb\r÷”Gÿ弆?Ž’…™ý¬¼k¸èC‰ÖÓxAÙÀôÍ“¯"ãÖ•ˆQGÞ’ïÛÉãÔiÊBýÐÑdÀ‘C?‰n.Ú{Ê<]q G’{ ˆFÕ­øF‘YŠ•S^ÇM RN^{f‹Æ¨D~àÿ4Šóq`ÿ^äiXÀ=±¤£,[,!8úŠ+ëmu„¡¤…ñ¯–ËmÉÆxmhû“ ‘4øC ÑG; çá÷ÊŒä‚/eÚT}ó¾É¡²éãcFhˆägØ:juá0`L€ ´å¸xN©ËhüþFÇ¿Aú& w­²Xñê)Ê` Á-–žf0äI ‘‹‘äxM'½[qInl_ÚŠç?œ€w§÷Q”‡#ß1—s”ó"~Ô`DÓwöwŠƒ4Jw½†å[‡`ñ讪l{¿ ü531”ÌB@uŠ £ƒ†6-u e2«û_WÜŒ?:D#¾‡¦NP¿‡„o¡a%⺭ôE€—ïº]w}‚›È•Y£uÔ”ÊÁÖGÀݯ3ú °1;É…Õu÷ Dh7á¿ …Ö'ŠF(‡öîG†s;7÷öÐu‰ ÿæé­xÌS]Íý«uήfšº¬«ÅŒ¯ó¦>“­[~‡ëoÅ0PÛžª™õî"Üz o-„üOæãEyÉœçn·CñÑ\É=pÞxõ=¹¶ a9^ž£ßa6•/ÿY5!"½¬Î>qP¿â"šû$m:[LÐ=ûÝ WµèŠÐ¦‚öX}ï=ÆÄÚï>ìżQOá݃Ϛ¬¥åÌõáT?6iew¿“±N†t޼…7¿NÆÂdcÇŒ˜HógÐŒ%XpÏÍd€-Çö§§ãÙÆû(pÔƒXµ zú88ø¦ìLJpàd9búJwRþŽ×ÕNam£ÇhDîXyD®PŒ—»‹s[Io/=îzd>¢ ¢T£ñ½Øþøx<+~˜ÀEC;Dʾ‹‹~>,kªÇ ;>&ƒŽ¼KSl U‚7c¹aI®nÚƒ ïLÃ}+ŽS¢ÞxcóZôS×j“ÓÉÙíù‘ê>‰ê-Â}O ÓÜó™]Nz(~šó Œ^ÞL#·…2š†-O?6óÞ]…ƒw ë=¹^G{êÁi˜`L ™ ×n?Ƀ7«G'÷v¤°#ï-Í»ˆfÿ:ÿMˆ>_ˆ!=a8µ',ÑÌÄÕãÕ/áNÁõ-œ;kèlÑ—~ÖÎtTLW\â9òtê?½q=F&Fªïóþ< cF-ËÍʽHŒß/ö~DÒLŒï‡Å4ò÷ŸE¢hm™w5kË8~5hê^~Œfsß#Îæ.Ý›‰Ð÷“|®Šv¿­~ig8ÿù6by»À2«6¤ã&ÒÅõ::^+ÎÁ˜`L€ 4@€f[.Þ±©És¥~Ã#á¾QŠ‹6à±Oþƒ±½•F£¬¬OŸÂÊýÒþ”ÕÏÑlš_óG“mΔçèw˜uå«°e¡b@â'ýNý.Ò¦wT¿Š ™j?mbÿîZQš°Bô J ôÝlÕ ¥Ino0v^yáꃦ>Ÿò,,ŸœêÇÖöÿ5ØïäHŠ£ç pìûß²Dûbìá–²ÙxoÚ'µe§úMcÔ7ÔüBkMkhÿ ë+ ë,)›²æ’6ò 2šÓÖ¾S4Ñ †a£†#žÕÊ–·ÿ#üuì-X}@h\j· ¤ï¬ÓR¯hT"нñ6Þýd¦ •âiþæÝõäCh¤“-ûä!±!,•ŒJÃfÌÇ[Ÿ¬Å+ÏO•¥i+fcùî1ÿaWƒ€áèu]ÓËLkT Q{¾òº†£ÛÕµôÓ«F%IÏŽ˜øäÄËJo_»ƒ>b¤ë_ŽR-xKg ‘gõÑ:B1áê1ýŸã_/Ü)•„ÈØá¿SU×ÖÊá |³Öè¦nü«o˜•„D^~¾F·î1ö®±£’¢=†¦Þ!ÄMëIX)E0èìÞsLIЈG//ã¬!ãË:ã1ûCãá3±îR=zõ2fÖ(h8þzÆ?9K2*‰)}1vö_ä<Çqèd‰1¿jÚÖDq 0&ÀÚ.Í '—Iµ›‡k¾ †ã­ï—ŠF%¡`¯ðhÞì¥M…[Þ“ŒJBD‡X Ž••W©ë 8ò#ä0c#T£’×®KÜ!„@~L7G¿ \ôE€…ÿÏÞ™ÀUY¥ü×°ˆ‚zD@P1E1M30­ÔÑJ ÓµMÇÊm²1§iÊ–¿6•SŽK‹ÎØH9‰c¥6šbêd †H¢BˆŠr•E+ËôÞý½\^žãß÷=ës¾çÜ÷ž{žsž³IWwŸ0Úõ$Ëå£í"V˪æ ;OÅœ;û¨Â{õ™€Ç¤ÇìíH¥ÉGFµ(¾aL€ 0&À™€¥â²jÏ6ë‚ë]ñÙÓêcòã/¡ãœ¸¢`*ÎRÃø† 0&À˜@m”5—FV[6Ƙ qÍDéWzºã—4$ØG_Ï‘saL¨Þ4µ¦âêä!W¬>ã=‹ê² 8uæ4Î-!%U1ŽYÿlQ£^1Á˜—×`LO}ݽÑÿÖ>4¶¢ÝÑeªht£ÑïŽ×–·¤”µ“'¼(íঅìL Äú¥ÔÝëÌDºÞÚ‘%K”s”hŽòí9qT%i~¤‡6žPN hp}¡ï…Žœ¿· ã|ƒmetü/ð«s…[}òk q2\¬™²éd¡Õ/»Ôb¼bkå“)ªÊãJä«pu÷ïŽ1s–ÂÿÊ,,ø€~¼‘ù­´ê€¢"uOÿ›åv´Ïè±ç¦Ø¼Úaô¼yøë6éK åÀ R, €whu‚Øoì]°z{¦þí«¦å&À˜`L  ”àÃge¥†aÅú—Ä…îS KžÂ;ÛòEYkGo÷Ý‚G‡uAæ?_Ïc$ãÕ'¾F‘8%ÛåÙ©²ìÇ07q&"£ñ‡·Ð|£6YßÊ5¨¼zŽÃTÙªOãm:Š$‰ .rÖ«øÛãöJ!̸|šZèøO…€| ƒ§½ˆþaœq¤3½7o“Îë´§÷éGEÅ’Þ”>Õ4l§’ò‚x²ƒUYPR/Ö·³JFæ±õclWç.IƾIe]Kë'ÿiŠŠ%£m¥—Í¥ñ¿uñ.>¹Æíl•‹Ùµ’h R,µ.U#v쀨XÒ3Ϊb èà©ü ©õ ÙÝW79¯Lìzi¯®‘=4]Š4db«£j{ÃŒW&ו´|e à®öçº3Ñv— ¼Bè¤öfá._¹\{Fµë¥kOk04‡Î*š%žU$d‚‰OOGüà€£â Eyd“wÔ]‹ðÅ £ðÏ5«°N|:†×¦Cå¦]˜lµ’Ø&±‘ÇzpÑ·YȬ§ð xt›F¥ÒéË-,‚µÓFš‚Ó0&ÀÚÚe<˜v‰»Œs×bï©û1!Ôþ{Ý‹F¸´šÄ™’¿þ;±ö˜ZÅ7ÏT'_B&aÚÄD‡›žš'Û²·Ï¥¹Çšé_{Y¬|¬ ôÁ“Ë~ïJåLJ.¦wZËŽ 0&À˜hé~6Æ6Yy2ñ­…šõ$Ÿî˜úÊGè½s— ç0_›+*–ª+õs0ùØ")Ÿìêš{ Ù¹çh¾q]P}< —gp\À:Riä ïâÅ»ú‘ÈÖs±JŒÊçÝ#JÝŸçx+{é%R8‰®œBò­O_¼²B8×ÒCÝQ/‡h—*š ñïi³1A ®ëNÑ]éBÞFæ±õclWçzÑY©¯Ä mܶnŠˆ~ÒBu£m¥—Í6ÿÆ|v‰›²è½1 nÁy5H±äåáÁœ­SLá WÁ ñ:{{ŠW}\!­v­9ó%å#,Iîá«08„ô¼2DÙšç_Š*èhM]ä¸îía¢çláï@&,tà°—ÍKгc ’ ÔR” ;&à"ƒSÌCb씽Ò;gIƒ £ cbðÙG«*JðÃnyÓy¬³ úûô@B8}–r)ƒŒ-›‰8é{É>G¼¬P”JáSñ¤Ç!¯Î± —}|wÏ¡xè•¡˜õL.6¾öŒº:h㧘üø ]Ìæ½Õ·ÙàØŒˆïÒ¼piL€ 0&píøÙ ¡‘~ô=*­*\ùþLxþV—ëÕRÆúïĺÆ19É«U¥ÒÄebþèp¹¾Wìl!Çh‘c½r°s4âG‚é:Ç“,Î&_\npŽÈ˜`L€ 49˧³è¤gÉ™LöËBL›ƒ‘¤XÚMQòwâÇãvûïñL·BšÌ·ÏÓåÇ·á ÙÂɘ§#®“?zÛgk“°öG£å‡\¹kde[ìÓ“•JÎe4*|º º3Í3‘¢ ûëC(ŸC{}ô㪠8øom¾+D;zcÀ0íˆç’9ñ¤­v®º™ráÓNUXéþT#óØú1¶«óNÞ¡0‚l¹êŒ¶•^¶ºÆÿ®Êâ(ž+Ü¥kÍ~¿hHå:‘²H8#it¿@«?ÁOP$)N¸wOÈãZp§Ò“_À̓º[‰Üû¶É´çArë7° Š~¯~ôé,…»GâÞYrªï!å¬m²Ø.MØ#<=ø¢·ÍŸ™€3íº’QGÉe¯|ûÍÚáζi¼|é[VvI›öÑ:c›¸§öas®!²|l‚•´ ¿úaà˜>r6ǰì=‡†_äð —oûÅ©J%Á§¦D;3J]m"GÕ_ÜýÃiuÐ $ÊÕpººWÓQŠŠ«Tnt×jK ΞÿŠ-’^\ïÛvµ6K~c“ÕÜÎ2«KFgéØŸ 0&ÀZ)Ú-ëÃóÔÊ•$/ÆKÿ>ª>;º)7_@yµôåÞRÆõÇT\2«Õºqh„zO6LPV¦ ;n»GžgÊø{ÏÒ Iç,Çv IÞûÀµžO®KVçí©Bûñ[ù‘êb¨›î¤)¸ ôA#óØFæê¬¬M£mUŸñ¿M‘öª‚Ð>Ènö©Z·OƒK^¿@7/Dx[ýÙîDRv6ÙÆÒ y´$g)>:´WïòS×á‰%©²—¢Bt¦íÈ÷:¿Á˜™  ?Âo<¬N°[ÎîÇs­•1£u69c'M—ýKðÒ´çpجL0_Áþ•‹¤CÙ(ÆÈ‡Gk/ 9_˜@Spï6 '*ª¥cX0úl?rNìÓÂäGNúv¬y/M¹\¯žãñäY:GìÙ÷÷ÑŠ4Ád9û+LR”‡æ±Û•טuˆºë^5»üæcÖ[ÛQPFŸ©êŸÍÅö÷×`×I:ÀšìÝfäÊQ|Žý§J`¡»o]C‡$®•Ža¦6Ù”óï%xô…$>uy­àÛØ&"B†Ý`µ…¹sPˆšÏGÛÒÕ÷ì‰Ìµã×c'‰sÖQ¼ _ÝCumFæ‹ÆOÿ+Ÿ•§²~®A9½×öoýT÷Žê’Ѱ0œ 0&À®]4xå>e lþA$>›„l³¦©.Æ{±æÙY¸côøàˆôã·¥Œ ê3ީ֭þøÏ¿÷¡ØræS‡±æ‰©ê8<ûã}0ÿ¬­Œ©×˜À«£º:{åF.VÆúZiÔ1 ¤Ã•\÷Ð8¼ýïêò¯ÚRŽü#ûñéVí· \Q“–ï®U–âsÈLÝ…uÿ÷4i·‹ãx‡u)ËÅ®­Û±kç®Zÿ¶oÝ…aœ]/W‚]ᅫYwß‹Dño^ÿp¿úÛÁyVFÓ9ÏQ°%bD–âc»ðÒìY²ü÷bÖ¯cÿIíýX[‰Öô\îç:QŠíÅÛÏ>ŠÄ[ljí:kú£XüÂÛØ°u?ý–ÔÞýº$Noóé»Qøl8üüÐçjoú9§iAŸ½OW.±þ|¼¿ fù·§ó„ŽC"KNê§vý|ב Ž bß&'àÝc hŽM(hß’¹Øð­®UŸÃ'/<£*¢¢BíÙ°‘ðJ͉ˆ®âQ>6áâcõ— ¸ì ÎžÕæEÌ……4wBþ¦Ì‹8J®÷«­¼úÃÊñùëQ³/¡ø™ßîÃþÔýº¿½Ø›zÔ…ï)›ÚäbÜðëûåqÍÛþîMäX¤÷ÂÏұøž¿Ê²ôÁÌ_) e¯\¶/¸OÓœ›Y^„\~r±VÎ1“oÓÊ2Ú?ŒÌc™wj»¤µµU}ÆÿúŒ•þ\^Vˆ3gä3fœ§fâg Xù¼Ha®sÓ—Òºïì¯kÝ®«vÇ’žÂÜ•´•±sb„¹©HËÕRÝ´è-ÜÚÍÆ|ýˆóÒßðåÍ¿ÈݽäwØýá@Ü^N‡”Išt!‡‡Ö=Šqñðß§¿ÂÃKIiuqæŽÞ…Ø„a(?œ*nµKòæ&©¯ ãñL  Œxf&dQqrˆŸ“ð’>ÿÎ31å~á`Äv˜¼äuì=i¾où|ܱ\QºRœÖ_Pû׿ëæ|ì3Öù_$¼ð´UôÍþàEüšþô.ñ†{pkÏ^¸”aÙÂæBúÜ-˜ Ù#ÖÇî“æÞ‰mã“çÇâÒÙãHKÞŠ¹ÉÒÀÁv*•ÈJ%!î´_.ª ¹q$ >¤Ã÷Ñû a‰4 «÷/C™Ýs÷  gzÏk/þßðÿF,ZƒÄCtxe.啱sÇn ÷˜ü.–ˆf8…×Ü‚&iº©.…øì˜`L íñû x®âa¼”,}Oåoû+fÑŸS§~Q–U‹&á´õº€«ã˜^#è UyÕëî¥ó±{©ƒZ^Ü€»nÅs›’1†ÎS¬×˜À=ñ´Xg{²°hÆú »Äɉ¨§ßÅÒiýÄÂj¸ÊE_w˜nŪe™H\@ãrIÏÿŽþ?”И@t4Ž1.†ÅsAF)ÿí ÅŠï/Ûë·"_7n¬a¬Ä(?±üÃZ—ªš¸f+¬¨1ëHbÉÆëãfÊ¿-´¸ùô¹KÞ8Iÿz !ŽVÌM§ag0Ïœ­Kð›?H¿3ÔLsó± eßúÆwW½ù¦9 Ô¿Ÿ‹ÒÑâ»ý,Ä‚å4£8ñ™ìŒCؼêÓÇi{Û“ ±NÿYSòU®ôîýl×ÃV … âôO0mÆ_ÔßlJôüå‹‘¼|7V¤¼„þõùmT–|òìT¼±Mþ®P¡~þGê绑ɱ)_¾6ŸxzÑ0<,.v/Á;MÂúðˆ '¥JÊ!­ß„ÏÄ3¿Ž ©\ï+úq”¾:åGþŽñ3Öê½Äûä4G$û†Ìù’æÔ¯?Ø–WÿqP¦%¿Js4vb’‡Þüz›óã%!?[ù„h×™FиŠÏ èýŸ» ¿ú%"£q>ã˜Ê>ñ­WW¯Ï¨tÞû–/ÄÝ4·æNã·\í39ò…—0T_–Ñþap»¾óNº*5ê­£¶ruü¯ÊñÑôqX“k#íúÿÍÍ›dϬøúcíl3¹ÙäØª[Öv¡€º½¯0áKîb>ÒRtJ¥Îñäš±tJ¤nû?}˜—~ý.&F˹‡4¥¥}îã­˜c?ðŽš¶«_˜¤æ&”)Øï\ì¬ñÙª©v)”ÿgMHÀ+ówmÁ3³:,$2>Tû1jŠ·¿þÕVMh‰úà¡·>İ_9ÓNV©ú&§Îž6anZw¦–âEÞµ›?\ˆXRüØ»>èÑEø ñÆÔ××"Qù¬Êý¢'áÍm[±l–V’=§ ¬ÅìÜoBtyªJ¥ðaâg{M4Y9aRç­‡ÅÉ#Í?—«¥'¥îôèíë¡Eî”0­šÖáò“§MÝáÞnþ^™7N‹¯S*ÞC½ÅúËÁuȨeÂwL€ 0&жøaÌó!iÍSN¾Oe4©1ã…×1} n'¿¡1}3KΙ‰!ÔÛÓæû’ü|”„>ª­y1'Ç1ÞýñeSÅ$ÚTš<ûlÛ«ê aawéKÂT|ýÇÂð‡´ßÂÔÀ)Ýy­ÎÇupQ†:;û¢€ô_ÈèGñŦW1R7ÖQ•J9¦—6Ž£çºdTòåëµFÀ‚l•Jrì?Mr€Î¤NãÕ¶ëÔ”J#Ÿ~IÛ>ÆŸç “ŠÈÝ€ÄGþå`u¹ÑtµIn,ÏâôušR©ó­xåã‘ôዸIþ}ôø=ØpL?ÛY› Ö¸ ôsààª5¥µéŸ×}ˆ¤Mkñæ[‹1ã>©oúÖó kŸ`­f‚2ßê‚ü†Y½{ÅØæý˜£*•úà‘·ÞEÒ§kñÌ}ÊoRZ”0i tf×µRœß‘e?ý~U”J!ÃêMãƒO©ß…Âê—vžs^(‡4¨)KñÁ²‡Õ#8JÄùFM©tÓœÅØœüp-ç*:Íäü,wwá”øÚÉv£öèj_ž‘q˜§2ö«µ¼þÎëæ4½|JÔÑ‹tãÅR>+J%?<´b-,T¢6èª|‹ŒyáEÌ"5¥’fÐÜÚ‹wÙÏIîFæ±ë;ïÔ "Î;i+Çÿú\=ëlº0ØN½¡núüÛÂýukÖ<󿬬<Ì+íG £]: t9…åØyôNJÆÉ{øˆg0 ¦ðšÚÊË‹0\Úòi.<‹óçKq¹²ŠLXy KPwD„šì'ÆU†V¾dA~‰ü:T¡Â#}úˆÚW ü\v?͇»_GT—T£sdO„ø+¿äš_ƒy¸V ÇjŪÉL\AQ5¼HDÿÃßß^ŽVKñ˜/Q,÷j\ªöB7úÜÔÕ÷›}ͨö ERÉãëšx±uÅgO£Œ”=îä/¿Ÿä´–jwø˜àï¥íP·ÉRýÜ=ªi¥§BäÝ?¶ùªÏÕ%È?K1‰¼üar ƒ·1oªËéü¦bj/ª›»|é@No]=¬ŠrAF~XséÁÃÝn¸DŠ#µvUÕÕÿêÈï‘k·¥‹Oåâø©šë‚Õ¨nßÁ]»ÁTÇ8µ¥Œ \Ç©ß|áw ýrìoeœCc üó¸w¤ïp“ÕoúŽ „1‡E—ÐY4¾p6–jìžRn>‡¢ qD@ã!ÇY×C_ÞÕ’Q/ß»N Î÷*ioÙˆŸb0b@glœ>I2ñþ0¾Ø<Ó©©u ™„t似ʰîî;啽´ÿ륈ªc!”9õmÜ=wƒ˜e,íÖ{[Þ­'x\ù(•qH ›±î?x(F›/0šNÌÌÉÆò¼€·o½S>Gc­\^¦­\.þ&Ì-7 ®NDbï:4E?¯>µ d²]tÑ3ñ¯õÛŸBæÔá®ý¬CL .džé·ã R“ƒ>£{ÿ<ÏŠ»ZCðçmÿ´²Žsøý§1WÞQ5fÙ&<7ºÎPYÌúËòóÙ]?v±¸#ä>Rþþ~„Vå²Ãx”¬óJ€IøWÚ{^Zl¾3@ Î~®æyÇN"¿‚†eîU(©nðë#aÖÏ^ËÎÀ8ìjT·šæm3i®»½ŸJh¥Pø ý•½…¶c ›ÛùHcµbóià 5uG×nºñ©ÓÊìô.22úÌ;9•¹i\ÿ7´h'Ü ó~sÒ­6hhY¾°àŒ˜Kψž›–…õrÍ¿AwÊ™JJ&¶g.)þ-òêÞ¦náôg+]íŠ!56m‹ ê3€¾hõ®î´×ùbÀ`W ú¼ùž 4-wŸ.±úÑè¼?{ùS\yá²IËyÜ&•š>‡¦nu›£ð§8ºuÖ’Hµ¤õòñC‹:jáî‡åí:¢6j°»7‚Bµæµæ}µd¬U(dL€ 0–BÀ?4qôW_×RÆ.c¼ôß׺±‹ÕHçO0ê;&Æš³ÎKóoü;oS º#LÊÝyÙWKÆÆ¯5ç( 1퀻!**ÍS¹ä¼¼ìc ‹Sרæbf¬yÎZ©¤N.¹Ãª_Tyû>–”JÀ­˜?-ŠrÒú`܃㦕3Esò›“`VÌ(Yk4eßȲXN¦¨‡³|á M©$@ñ„ÇÉDÕ,ÁDU®p°ûtŒ±5›/Äc×t ôóÌÏ?’åñÃsK(•„PGJ%§}˺zšB—ÜuÅH?$™¸ò»ïQ+¥’~ÀoÁHR,í¦ûíkwãÉÑS5…p#ËR’“)›õ Á#÷ë”J‚ ´:þ ·â7Ï &ä7á‹#s0Cwv¸…]shGóýl曫ì&,ÇÀ8¬ ¥qšµ{ÏÛz©[ñ¥ïI“~¾Jûît* Ua¨Ð{ÔÈ<6ê3ïä\è& qiüßÐ’rkh¹-,}“¬¨îäí‰_öè$îRÝ/P¼üØ1&À˜`L€ 0&À˜`×êl,‘wv5Ìl½4«üÈ?ñë ÷ qÂ$ü#½X«˜å$¾H‘ý&ŽD¨"ݹ‡á–é¶dÛ&dJ'É ‚Át”UcËrrŸ0­/8? ¿Ñzù¨à:h¨p!W‚¶“nùÿ–K :å³õ>Cí;Ýiß²MâÀt«mñ¹ì4¾Ë•BJŠÄp Åȱ’9,d|£’A 1bcË’wø;Y€|:³ð:;aB9\5óž²÷„]8{0&À˜@Û$ÐD;–~nþ×ú^̶Ù!¸ÖL€ 0&À˜`L€ 0&ÀßyNÜUôÁ›ÏŒµ2 ©ÄQ®W*•;º™a–»:2-ß½Й®t½`JL´ã,Ä7šN.K¹4X2ssát¡œ] ‚}…éëUã^ÁQˆ%ß4!™Òg× XJ‘/‹;%þÕùøôݵøêÐYT =:÷Á¯¦Þƒ¡}d…Ž“êXõ-›8罩%ð3…Ò±!.™†ìá ù)žø@šŠ¿iÑço­XªçÝk–-ë…Ëè€>ý´ òòóYê$þ°A=œPŽ+¿Œ åM&ûŒ¦k|YÊ•*«!‡!Ì‘9Áê*A%&ºŠÒËò_Z,šS †§-}‰KóÕ>*ÉL¦ç’×"vÞr¼}ÿ «j8ëçJ¤JyGQIÊZ<›¢ø†`â¢ßcΔ8ÍŒäÓƒ:Ùéïã0ÏŽé:ýçëv­—”JJåÚØ²ê*ì¸;†ß™1 ¾‹R”x5ØÊJ%+"üÀ˜`&1…Çh™`L€ 0&À˜`L€ 0k™À|ðÔ«r&áñ)}W†&È‡Ž¾·Žj}6«»Î¾îVŸIû.!òc>Òs¤óf`4ScÊò³n)×ÙÇzÁ•{¯öPkúŠ˜S¢òõê(?qHTHêOI©4rÎB¬þx-Þ|y¦jî-mù<¼¾çœµÀÎú–ëg/ôs+bnÅÈ„jŸ©­’—ÌÃÓ×Âü³­‰¹.z—Ü{.nŸ>ØG›ö”8åØõ Ô󽬡§F–¥KTœ*sòãÏcÿÙµÈò“»ðôã›Ôg¾aL€ 0& àK ¾2&À˜`L€ 0&À˜`"œ¿‰u¹ŒÄ3iâY¿›¢~<ÝO=T\(R3êâgÇh:5S7.çy9ßÖqnRuÔvv¬|r {]%ÕR¹’ Ó­Û€1’š }"ñIß Lžô*˜$¿±sâgÚï4r$:™­1çEŒPÂÈŒbþáxëɱv$!c5)ŽÒ.¨J ñ7ûO¸éƒES“iËç#a×0L¤3Ì2þ½UÜÉdÙÕ²\ç?/.†YKR©”CX0öÜ4qüŠ2°=¥ŽÏ€«rq<&À˜huxÇR«kR®`L€ 0&À˜`L€ 0(þ~~—”AøLLf2Y;5ÍñŸ”³ŠT/››è¯Úš3šÎ&K«Gƒy*vÓ2òq¾ºvÅZä(×”VrñCsðîH¹@¿±ó0-Æßªx¯ˆq˜?QV4åfàŒÅ*ØõRî„ÄŒÁÿmz]-/mË!2›¨ìH’³òꇥ)ïbb´üœ‘Šä$¥R䬅xfA&;ýñeŠŸKWe‰œ²«_˜¤f¹/y“¬Tˆ'—-Ï+Ô|Ø`m€ý’ ¶N„ëϘ`L ªª«ÿ×À,89`L€ 0&À®½«ÿÙré-¹þv+y÷ˆ'Õ…|òóJÖ¥ô’¢p*G¥¼›Äh:‡ÈžÆòôFÌ2…w@رq,×!ÂÇZ¹ôsY Ìr•Uµ‰Àa-€—fаkd¸ÛökRÂtl¯jF‰Ü'Ÿú^¯óˆÛIi”A)s¿ÅO–™ˆò²ÉÅ¿æ¯ÿÓNFî©Tyx (ôD†ºcÝÝŠ)Êtñ²î{6¹ÔùèŠ,QwÍÇÞQÓñÃá”TUÁÃ?7ÄôÛ‘µxC.!2¬ceq&À˜hxÇRÛhg®%`L€ 0&À˜`L€ 0: ü|v^ýg¾/úaüº¿OiFðé‚èÎRHö×vkàþ[.§ó í|&£é !{̳sXo9ƒc8r¢Ì®„’cétŠŽä÷ ´ gFÀ½=”½wÙ2a±ÝADâzvTÚÑ„î •_¯™*Çeý£MÖA=`hüŒ6””JÞøÙü_|œ+E ¹ïWˆh&Y®ó Ä’aÉ24&RÜ…—öùVYÚüjX„äüȘ`m•+–ÚjËs½™`L€ 0&À˜`L mpAGtà«Ä3f0#ïÝónÝqÛ=´ãGpaïYëYu˱HΟ!ûÀRwM'ååøcy  š2ûx󛬯àK:£GrÃpç ›p~¼jœõs÷HÜ;+DëÀ{H9k+a l—Ï FÛÝE¶Ñëz®.Ä a·’à‡!\1­(ùÔúÿ×ï¿­~§üZ3‰Wk¢Ú Ê"(šßTÍC¦#ÖÚz`m%r`L€ ´r¬Xjå ÌÕcL€ 0&À˜`L€ 0¶GÀBfÚŠ‹KP^Vˆ3gäúŸ1ã|Y™è_\|ÅJu.>W&‘!ìN'áícª>Õg÷ãõg—à¥g_Çþ³5ª¿psïï‡tbM ^úÝ›È!sr‚û¹ø0ßóWñ胙¿’P²Ñt.‹Ï̾ObP’¼¯ïÌ•%øÞuM!sÙ@SejÆ|S/õí籓¦ËùSŸœö›•>{ûW.º\)xäÃÖJÕÚúpùÇrQ\­;CÉr뙆íri~{Á_,z[.àð·Ù(¶(2¾å8øáÓxVù&,įzZk¸šBó±ÃÈ$S|Õº]\å§öâ±±‹Õ]yÏ}]ØpåüHÞ&™ÊòŸô †v“TIB6×™F`Õ²qH\@á¹TöÐ/ˆóÇÔ݉o½Š8ëócŒ¦k Y†>õ&nŸ†dÚ]•¼`vE÷AײsÈÎ-‘H…OÅ›sâèÞºR ÿß´êßÏÝC'`õÓ_áᥩÀÅ]˜;zb†¡üp*²åtòæŠZ›ÖÖ·P–÷Ì0!ÑJööö¥ÒU}–>3ÊîL§ò7aîCkÅx~á}E[šNQ:ż"¢gâ_Ëî´Sæ4¾,%Hžó;¬ëï‡È!ýÉd`öP%AâŠM˜Ð³®N|˘`mïXjë=€ëϘ`L€ 0&À˜`­Ž€§rTŒÓš…ÁÝf©é•Šr5vä˜!ð×M¬«67ní}UŸ.~6RHÈèEøÇ²©rœd«J%?[5Õ®ï×Ú·Ü;¨g7åg²R*ÅÞ÷’ö/C”ƒmí:kæKr‰éUÎMsHŽõ#È]Sn)7¾,^¢(„é3z US*u†?¼sü9Udâ+`L€ ´=×­YóÌÿ²²ò0wîKbíCîi §òòZE=«˜Gc‘ä|˜@Û%Àï‘¶Ûö\s&ÐXø=ÒX$9&À˜€DàZ|¯VÓ.ŸÌ£çÐÞÏ%´Ù'ü†~0Y[ørؼFÓ9ÌLö4”çÏ5(È>‚üªöèp¹èލž]j+†ÃH ©ûùÏÔ'8šw¿Ž¨.©FçÈžñ7¶+ÇRvgϜǥŠË¨,¯‚§_‚{…Rw«‚¥……¸x±—+/“):?„GöAéjÉÕ¨,åÅçpþüE\*¹ŒËUUè`Š@TŸ »VµÍA4u?7 'aLÀ åól0‡¦IVX ÙDîѳQ °_NÔ¨ÙsfL€ 0&À˜`L€ 0&À˜@['àë¿ëÁhºÚxÊó:7õ@»“ص×쓎êïåÓ} (½¼*ü9ÊÕ˜ŸQY¼ýAÖÎ~Ç”u8?1&À˜@[%À¦ðÚjËs½™`L€ 0&À˜`L€ 0&À˜`L€ 0&PO¬Xª'0ŽÎ˜`L€ 0&À˜`L€ 0&À˜`L€ 0¶JÀΞb ðZÒZêÑXíÀ<‹$çÃÚ.~´Ý¶çš3Æ"Àï‘Æ"Éù0&À$ü^åžÐp?o ­Ìuä~Î}€ 0kïXºÖZŒåeL€ 0&À˜`L€ 0&À˜`L€ 0&À˜ÀU"`·c©{HØU¥qŠ-,Úd£ê4’Ÿ©—¬ƒ ?y©_Çã™g'Àä@ÃQS” >CúQ³UÂàŠJzv¬X²äïÃêu;­âKù8‘ž†Ï6 Ãü'!ÈAyÕéUp0 ¯¯;hïœ不:åa9{kʨe?ïOé£y¸ËKYƒ¿~rÜ>%É—Ÿ~›Ã‰ýŽÙÃ`›Ùvùp?wØ`­µŸyÇ8ÄžL€ 0&ÐhX±Ôh(9#&À˜`L€ 0&À˜`W™@Í”Š"t@ܸQˆéÿv58±ï lN‘”{V½‹Þ¯.D_o½¬eør¹¦TŠ™<cb‚púà¬ß’ œÛƒ×VuÆ‹s‡Ùí$ª*αS*ésvxï&MGÄÜ67ôé…@S{Tüˆ/þù)NŠ­K©Ø¼æ ïî0y}<ËrvjJ%ßXÌ|t «óñéÊõȤ²ö¬z¾Ï¾ˆø`›K²ŒRYàík]j9¥íêëXqf³ö§šŠb1‚w¿8Œ¼1!þ¨1ŸÀ«’%aî¼ÿy$~g_›ŒŒ·™MF×Þ#÷s»6k½ý0ôޱ#ÄL€ 0&ИX±Ô˜49/&À˜`L€ 0&À˜`W“€W7Lœ=ý"¡·x4yB»¬”wƘ‘’v}uJ›Ò¬ÝØž+ Þkò!a&´oçêúU7k¥’’§w W~­,ÈÀÙ´_Ìô;e¥’œ¯w$îL”kvî+)úŸÓ]­•Ó j ð Š´V*)q="pÇ8¥ÅJQn¾am¦qí^¹ŸëÛ®õös©–ÆÞ1zB|Ϙ`M )ÇF-+çǘ`L Åhçé΋6Z|+±€MMàJeµó™¹¦.œógL€ 0§jJÎ#ßQhU¾O—¼‡G#À6Ž[úÇ™§üÛýÈ›JæÚt;gl£7è¹ôöæÊ9¸7ü€¥‚¬äÌ: _ŸNv¢™z]O~dê—ñõÁÓt›´SË6¢[SÕ×¶ «çJžvØbd¬µ™•ÌWÿûy+êçW¿;±L€ 0&à„O~9ÃÞL€ 0&À˜`L€ 0&ÀZ¼C‡Ôêôê­S••Êç2üü`¯ÎñDPÞrZ ì¶,©¹6ì¦Ìœ…–¯E¹˜MoÜ9±’ÇõRjpé‚t~ÐÛ;¨Y—PôR2¬¶Ú¤øÒÕ‚£‡2•syc˜çÓe]Û­å´ªðC`_tÓ›âk!mV›øW+Œûy+êçW«q¹L€ 0&P'÷:cp&À˜`L€ 0&À˜`Làš&PYp+¶Ð9I¢‹Â€Pµ>–â|ñL#Á£¯^á¤ÆnH¡$: . º½’C©÷…vÝ|¶a+ÕÏ…¼L䟓s†Çžœ„°—Qü£f)SRÌ8ʯ¦Wäb¯\VîdšjùÆŒëÖÊ÷@@¿xL¼g4"MÖgM©å¦ÿ]/¯$d×ëæ(h-F­qµÚ¬QêÖt™p?o]ý¼éz ç̘` %À;–JÓ3&À˜`L€ 0&À˜hÁjŠ2ð·%e ;`Ê¢éÖJ7ÝšSÝ­¾JžMò£9çÊôA ¸¯@æ·™H§?U©$ävù2.•4FíÑc€|FQ{w¸ãg{Y=<ÑEö-<š }©þ!ˆ ï˜Á±è®Ô(<º«_XŒ/²KìókŸÙ²Éô è'â~›s¯pÕÚ¬Q*Ø$™p?'¬­­Ÿ7IOáL™`L 1826FÖœ`L€ 0&À˜`L€ 0&p5 XòàÕ¥eórÀø§~ƒ<ŠäîfoFKˆ\Yª©\|½Çqš©³0Ìy~!*QËE8úÝ~ìü†vU]JÃÚWÒ0lö"LŒÖSS€/>܉BOw8;ò¨ªò2<nÄıÑð¤œÏeç;+]òÿ_¥¦Lêì++Ÿ®ÃÜ:EcÖüh5}M¹i_mAÒVáL&`çò è³t"t;¡ÌiÛñéA3:ø8Ÿn©"”7Ü= 1&GíP†ÿþýÿ°ñÛËR¹1ðüoã¨.Î]³¶™s1®j÷óÖßϯjã™`LÀŽ€ó‘Ž]Tö`L€ 0&À˜`L€ 0&À®æŒOñÚª=²¸!˜þü\'Ê MMsö<í «ÍÄ[o„Ô^:nèh’w™‚‹ø[HöФK]õ9nzs:‚=VÕ%¥ˆŠ@IDATìû6MU’9/)¿KC5׌âšë´¼$‰ % ’RÉA0ܼM4ö~xW½‰÷vùÇqìl""4#u—òR‘™.+…e"ûyÇ·o‹3>{óUìÉ•"…Ü6¿»SP9rW«ÍÉruý¸ŸÿVÛϯnßâÒ™`LÀ9V,9gÃ!L€ ´v5%8²?æ*úí3ÿdkí¸~L€ 0&ÀÚ²¼ |wòÜ}Â08.Âɤm[£ÂõmmʲwjJ%ß8<öÇDkówº {u ƒ`0NP•\(¬Ð…h·—+„“gAu ]4½†èÛXÿyÁŒqû°b« M>.”AåܽB0ã‘™¸LûŠ]“]¹Õt.’w|Q{DDRÍŽ yàûU%•’°¢¥òý±bJ€ókϸ€¨Xr~ºèK݆ÍÂÌžåd©Îùt‹ptS`¨¢ PÊ)Á—:¥RÌôy˜>$L ´»¶¤6³®=¸Ÿ °[o?oÆ®ÄE1&À˜@= 8éÔ3£VÝbÆ‘Œ\T;VW»£GL4LÎÑ5e4Q½{w¡a+ÐÖ;u 2!¤{(z÷€¾aºmünÎÉÀOªá°8»wé…þÖiZ k®¸ÚªÎãó¤dñ âøî1¬XºÚíÁå3&À˜h&…G>Ãg[Í€ïhİb©™¨s1ÍJ <ï-ß.…¹µ(•ÄH^¾ó%5Î%úË<ËØp›;%8¾Ÿ>3‚óí“Îô›äÙ¸ÿ·k¯`FAqúwT”04ÞW3MçJ©¾AMRRå­@d„’—”ºìLŽø{@xŠ õ—<ëñi… eÓœ—)ýµã˜´€:î²·}€í¹R¤^“©U©$ÆjamVGõš&˜û¹ÊµÕösµ†|SYš‡})_!íp>®ˆ8¼<`0nIŒ°ŽÎÉV"/m¾J=„3-bªvC{Ë-¸):Ì~a¥éô¾t8I©µ ¿ï}‚¼lUüeHßñ¤8¦ÊyóŒM¸Þæ;EËKº3šÎ:ŸÒ¼,dŸ'[£î]Ð?Öö{Ì:ney Ný„ì#ß#»jîO¬Ýä¨ÚXO‡zÎ1«5¬gºK NfeàǬäŸ6£´Bè+^tFá`ŒHŠàŽ¶í¬–dwSŸ6@M%Š wâ¾ßý§Ý_«©^±0ê£ÿÝ‚}ßåj}lHFÝ‹ZÅlîtvdZ§+–lÚÕrö Ö®Ûiãký?ïO©muWBkвð÷?¾ ÉÚ²äK‹«Px.'ÒÓ°gožyŒ¼rJ¯ÀwkÖb' Þ:ú±kÆiL`L ¾èÀ[añc!ýyðÛ°¾ô8>`L€ 0k–€›»0yL“äÜ­ÎS¹f+Ä‚3+•øï†U¢*EXê8eÑ «3€¬¢ª&ÄŽAª°K(÷+)‰A´‰¤Ê3ô{VþÝÚëö_¢¶¥¿Pó¤¹=çûŠt±lo+“y\ö AϮ֊ ÛØu=wê;„vcyì=ð#FEÄê’T"}—b*0 C®¯­fZ2sÎ õ!ªwgõÞèMå™o°ZÜ¡E›­OÁC .dÕxmæBa-0 ÷s}£´Þ~®¯¥tßðwŒ}ž-ÝÇœFfMßSÞUš´…´s2}G2FÏ[Œ;"ý´áN0­ù ™ÖV ÌK©øOÚHÜ«ì>nîtÖR·…§&Q, ;•¥Ò¹É~§2TÞ½t-AuŽå$R¾•¤ƒ§kJ%›ÊÖ¶a«M\~d-’@U²<¢ò¸¹y# œV9šÚ£¬È Zˆ/¿.ðñ°_áQYZ€“'óQ*/»ó&›¾½"ƒmVªØÖ¸y'qú|‰¨”•Ò«‚u«*mSÏEg²qòÔEúÚqC;¿®¸^XÕWU³ð>ró‚I·ÚÐQz[¿Ò‚dÿtžò#×Αýû¢“ÍJFÛ4ΟkH¾<ä¹ ®@tkGg°ùuD§.0©vã•Ôõ© J‹ŠÄ• J”d“܇Ž]ÃÉ–¼IcV–žFö±³('m·›w7ô¶^ù¨HÀW&À˜` £ß¯<Öÿ<²ã±„NE ^>~ðíØ ]M°;ž€Œ±¸>â1€ÒGùª'àÚ`5¨£ý¯PSl"æ?à×ÅÕñ—‘Ÿ+ÿÎ%“zcy£È¢†Cç¦í|rNžÛ«3žb߀pºJŸåd>>S?)‹é÷ߘ`mâRLdô?7Ú¥ô“ð õ{ri–NYæ3Ïm½ÂY.§]{Ùlæ%3™·—dƒ|{ãîY¿ÆðHL¹ ³{Ýø(Úm`PÌÙp›¹ WËŽÂýÜ®}Zq?‡wŒŸkÔãjÝMè`Óí;vUvU¢Z_?ËEdÉïÔŽm¬#ÁAá9WŸ@»÷ô %•W–õ…¬T™Þ»aª™92/÷õ9E,î–•JJ‘·O@ÔÖ7ÄcCöíý£É©ô*3šNÉYº–åÐ.RÙ”¨uˆ£'7D ‰‡´¬¿^.½{Igg¤ ¨xCéŒÎ1MG¶DFG:‚…°áw „KÂ~ +¥ÒæGë×4îxÙä«å²+³ïeÈ9.G¼Æ«J%E–ˆ[Ç!†KéäqðËø+öy¾±¹Ó)µ«+­×vhØÔÔÍæ…m¬>¤?d‚GüM½Uÿzݸ;!Ö+ŽÌš–@™|xëíêJ¥´^ƒCpâ[ák†ú¿Ýùc%ø&élþF WÒH×LyjnŒ°±L¥d7õÚâê0UÂÌš|£•`1?²üå˱=]ùñ+—ؽΗìÅÖç̲š"ìùð |¦(åìî~úQ «ßܲ¼X¿r#NÐ*I;g#W½ëoÉÃÊ?¾#®ÞóÔ"tÏúï +‚ô®ßD,™;?íx«…•zç‡'_H´3ý¡Â÷L€ 0&ÐF þ~å1€ÔcJðßO6‰›ïe¹;ÙŽx ÐF?g\m¯°x,ýk¼á\ƒb'àÕ¥7“2´íÈêH9-• CÇZ~)Ó—ˆWcÆ“¹¼2\ºT wÒs•Ó6_S€•é9ñMèÑã翆á´ÐË\íI&¡èwƒoW„ÙÿQ’¸‹c.¢¸¸WÈ|` WêØ©3M~ê¢-%®ñk{ÄÏ]ã-i3ãò¶Œ”Fúœ^r#ÌŒ”Éý\¡Þ°~n„½Ròµ~ýÏ.93¶|ž†ÙwÆÈ“æ•HKùJ Fgý;Ú+Ñ ]™À‰O6"½/í® ’´(•‡±;WJÖ·o€tS×ÿ5§i÷«¬<œˆÑúsç« ð½0£OÎ{x4ìrt @ÿ “â”»ySc!Èj4X’üŸ%ëÿ²]z 9gî^{E3-ªÚ{Cm@IgtŽÙhºÚ¸Ô”œw8/g•¦9Ú€¥ÊnaaLbç¨Ý0¸Ò…ù»ÜC8e‰—v÷6w:;ÁZ¿‡{믢ÑZpôP.ÓnSpLÞŽ5öBî¥ÊÊ¥ÞÐÓæ¬øòë#(ª¬D;O÷‹Ãð¡×ÃGgOÚVª¢Ÿ2q$ë2:t4¡{°‰ÏU²ÄÏW•@iöv¼ü޶55dð0ôò,ÆÁoÈ„¬Tô°z£”aÏë/â³\Eô ×(ÌBª˜&ÿò"Šl™V:¼¨ (i@Ì0ÄÐnÛ¬­©âZ~ÊF¼˜{ÉæI²åJ‡Rj[Ÿ©¬ÛÂPœ†Ì\Y©$ˆÑÅÕºÉÎï›KÔ­Ü1q´"â2v¦ 36/}]ê´/+(9¡N/èê:>8ŽVñTåáx:™Ñn¨þ¤—îHEÒßö¿,‘KLŠ˜PNsŠŽ¶/zL7ÀÎt»D_º‚»t&¼†áqbÆŽ 0&À˜€FÀè÷+$†4ž ±Ðö\¨0¦ˆô©FÞñc¢ .Ýâ2hœøîêpóꄈH'»“Q<7t¢3Š:5ÎÆ$sC§à‡»“&¦3£:v ¢?‡¡-ʳ¹Ú¬EUºÂ43îç l¨6žÜ'ü—ˆÁq7FþŽõXœ} Ý3Šö®ÃFy!ìÝ¿½™öèúŒÂvñ<¸|¬_²'gÌCBÈEü}ÉFiÁpÌD °N¥ÏAŸýù?ÄGÂ\ÆÃ“ã¬ëe¥ò= sŽ”îžêÑ S§dÔP°jF“Gôg4*Xö¼ÿŽ´ˆ½1÷¡áètV›·R£5±6Œ¤3:Çl4]mxòRƒ{õ¶SRXóµ"HH€{¼Ô#;u ¦(ÒB.«©I9as§SämíWG¬[{k¯_MµnÆÎukÕ¸ýâ1ñžÑˆ$³_¶ŽŒYÈ^Çñþ›¯Ò¶zEÑ$yg¦§agRøó ôµ±¿\-/<(O߉µ²†_Ø1,q2Æï]‡©0[Iø™ 4Ú ¤³w:fÞ"Œ’dŽŸlÆž ïÒ®ë>/HQ”ñM©3‹¼EÞe4·øËäC÷v.߆AM¤^/¦ÂŽ5òjÁÜÆ¼ùT–ŸrÇØQøæï¯c³¸a;¶¥Å’ÝT9UÚ6M©Ôo þ0W1e1‰½{ðþ;ŸJ¶X•…>bŽÎÿ+%Ù•I ¸éOâÞ!’Ù‘7À˯ƒ03¾ø*}]:ÍŒ:¥RÀð)˜›8DôÑ!¤–*á-r Td¨þö5‰ÂÌE÷ÐA†>¨, ™•£Ñ„ñóD¼`¶ƒv\¹p•8Ë?œËmlÏž%û0&ÀÚ."ƒß¯<úLQÚgêxBßO¡Ï7êv¨¬/ʾ&<0CQ*I^¦¾ñH¼Ó^B9ƒK)²ûÆcìaÕƒä<ƒ‡`BŒtŸÿÝ(Sj¹V楩üà; é•JB:Zé%®`¬þ¶…Çâ±¥t ')•ç@!«QLH|þ)I©$øy÷@¿p9°¢Šl2 Ê-vL€ 0&ÀF¿_y õ=?`ØìßY)•„8ž¤TRŒaó@¢Æÿ3&À˜`ö*+I!cï-ú¿è$¤Wªœ¤*+B±Å•ßÿ%ØùîF9ÿa˜0\ZtkU ›nÏ‚îVÇ“¬3IÎŒœsòLŠÑt”Qå™oð†¸‹öP›;ô¦ùä’ªåkc]ŒµÉZ¯¶3:Çl4c:5Eø-P–\LY4]w¦–äÛ¼mà‡ë‡Ê}èR*þ¹ãGétQ” ¤òö8:v‚ÎkÞt2²6tqò‘w@™¥'ΗAP$é H§Ä;ån­ÇêÜÁ½ºú 3Ùmn)έS4fÍVÅ©)7#í«-HÚ*˜Àv.߀>Kç BÙ¤D~RM¥—µw¿ X07^Ýüàs0ýý%$ »,.íÁ÷y£1*LYIà†þc§£¿˜³ð_ Ì9‡ðéš$d ˆÜíôaé…9·E¨1ø† 47òÒ j‘1¿t  !²ý±¿\R’F#Ü[PYZº^/(–Ž‹yŸ=O [ú\XJµ-E17tSËUo<‚DEȉ\ò¡Å5×!È­Õ²ââhW¬Këp”R,Z~ô™ýd‹)}«¤@Ú®RŽ×Þ5³z奥Jƈ™tK­f7ŒÕ_Í^¼‰Ÿw·õ¾[gô '{ƹ€ë^ 2éÍzZ+öÝEEu;YçÎOL€ 0&Ðvý~å1€ÔGtã ÄaD´´ÛYÿá1€32ìϘ`L m¨1ÄË/$Iæëh!ûø›ý°û“=êù×;ß{9wΦ¹ÃH¨J¤'½„õßHs•1ã&Àÿô—Ø£œI}t'^:/™ƒHÁ®¾WpàSÕ:Lü#£dK3N"“·»›ãùÝÊRmY®¯ƒ9àz¥«:•s”hvöXanIrî‚=Éé¬ +^†¯ÆÚ€fy ´Ñ9f£él¡Xè|ðW—Êæ)püS¿ÇAúy$ò¼ m9ö>DíX.šd<±å],<…a‘·ÿ ¸“ɶÊss§SÊm+WkMO=k­ìD:Wbþ¯¨¼U5ÚŽ%á^ðÓÇîmw6Õ³øf‰îæm ±÷ãÛ” õã8vV{!í¥„uÀ„{líšz"vÂPæº3~,¨En7˜"â0kуêNÈ»2jIÆAL  ŸÊ“s7!È_QŠÖQ ¥'äÕÞ½Md>×^YáÕµ—ÚÏ/J ¥ §NÈw€É×QYúÏ[. úË%äéÊr”ªi­ƒIv%?! sÇNìÙ±GúÛºG­.T»´ÃGãt몼 ¬‹Tž Õ_I,_õg5Øñ#`L€ 0× ý~å1€ÄX?ž +>uX!à1€ë]“c2&À˜h;ʲNV*‘9²¹ ¦#>aþ´t!Æ–wpŒ[Vá³,ÍÂ’%ç+U©5y¦ÇøÿŒg™ ³–t«×ìtn‰…Lç´>MB8 }-’Ñ”9â¢áZ§7”YcéòèÜít¥Œ£ûð¯wWa劕ô÷>Þ~ûS9$+^{o­Ø„3ò:a%Iý¯ÆÚ€‘2Ðvú9¯úÌ1MgMÜñ)«J¥LþeÄ;8‡«ùÛ€äôìWçaX¸,sn&RwHJ¥Û¦`Êmš‚QR²Éñš;\l[¹4hÇR[$Ô³gÜ@`G¾X土h›©îƒÕÎ]Ù¾Œ?{í¼[{É$•˜Øªw‹>öÿy÷Dl8íŒÈ¥ sÇq¾j4´÷­}|öaMI@}KС ÚØI(…Ú÷y%D¸–—•‹[TíbU–ãŠQ¹j;¡/ÃR)즱KE[¹[Í-¿è¸,Ý¢¹ÄZ.T¤¶+w?¯j\¯®°Y³á0S7õýà0ØÊ³¡õ—2³Þ…dU?0&À˜0@Àè÷k[Ô5êC‹ã2&À˜h#Jsñ]®T×a³'kÖ“¼èX‚ß.DXØz¬øDRþd;ñ²ò'÷{ù¸2ï?9!T…%ðû%ÁXÿê*¤‹–’â§ÒÑèï`×Ò‘íŸ@šÆüV³Ì¤f&ßxu  q•Eöq.WË^T S4Çi4]Mµ~NÈŒôt³mqÒó¹|䟻ˆòšIbyŽ#¹àk° `0Ñ9f£éeÙ;ñÚª=Ò£oûc¢µ5%"]›½ ”²½Ã0qþ2$äàœ™æÿÜÝÑÉÔÁ&7|ùÒF9– ¾¶sèÍN‘· \Õ)c#uõ$Óv‚9;[§˜ÂSv-y¸ý>^îâëÖÖOÞRïK+¬'nÝUÇ‘C;/ÂìÍsO`*§ uìhÏ˾žúü-¸"¿tíã±hzá}©i8Qpž¾ÀmúweaNØŠAäõ ¤Tç( àc™¶=ßrA;à12¢³˜CçÞZYÂ.GûTeøé°GŽ !•]Qö¼üвÕXñ®> d’;—ŠL³^Y*yÿ¸7UŽ@ª¡ŽÒ.(Ïö4‘Ýž}YºÃødOsöÉ_é,V¨¬°r„TlþF1ÝG^Ufìùû+Ø|Tvéâ S€œ ¸/[WáZÒ×T•¡¨¨Hü+«Òêëáï¯òËßúod•:ÏÄXýçÇ!L€ 0&ÀŒ0úýÚÖÆ5(“¿ÿ‹ŠÊtcô"ãÏGò²jm ÔŠ‡™`L€ ´MÚ–fä*qÀ@³®âÝ;„ëͪK7t6õ)\¤³©m¸kHô4!Ô¤DÖbeíÚ®žák£(ÒâIw&ÄŽÇ<¹_áH‘v4Š^y& {„ÝQäzÝþKÝ¹ÓÆÒùEâÆ!qgó‹¡1½¤‚Ð7ÂûÂÇ;þr$íb@ 3Ô”Ü`:£sÌFÓQ á¿VÉËÉ;`Ê¢ÚÎ8‚Õ]c¶^1áîÀj‘UÁNŽìøLí¯Ã‡÷tËÞ»¹ÓÙKpíûhÚuñ$õpg‡® YÒíNRv6ùÕöI5 @$©,7ãb¥‚:iÚzsÖN¬NÊ”Kë@/]-LôôŽÄ¨ ‰–”³ëCý0ux„øq¨,ÊÂúå;å´qˆ Ó3¨„ùÌExj/:šÿrÍ2”Sx÷&õ]x Êñù›€[§(Œ£þ½QXƒ4¬Xx QƒûÐr˜cÈÌ•‚´/Ó 7ÐáIé‚Òé26¾°ŸŸŠ¾â€¥Y;6`ý·rZZý2$XÚ§ê4w÷K–Aß&áïÝ|0õ¶ëÅALeQ6>V¬¤\ÇŒÿ¥¼òÆ ±·ÿ IßJÛ^3“–ãOû{#ˆ>jG«_.ö2:óqCÌÝ“üíz1íÎåBÕôG0:.^4>«©ª@ÑÙŸpò|;¤HŸs!§¼ocÅViNÀ¸Gðû±bnâ0eø¬ÍÌÇ{‹V"ñé{Ö‰_e(ÌÏBúq/Œ¼-Æêï¬ìϘ`L !Œ~¿¶±1@UVüñy™ Ó™ÊΤ°¡7[“ÄF(Üñ.ÞB"~{û@t¢aOYi!~<˜÷nE ˆÌc€†ôUN[Êò"œú ÙG¾GvÕÜŸg¿‚]ÈÄR€ôŒ|Z.]û4`%º{ô Ç.»2¤ïøR“Ía{!òæ1› õgc4ó…s/ŒÈRF“£ŸoNÁO-bæí‚úàŽñcÑWøáÁîªp¹Ÿë$-;“”_#3ë СÚµ÷G—îÝÚ;¢û¢“²³B—ÆÙ­9'?Ñ9¼?>ô¡qïÒ ý#è7 #GŸ½ÿîNÁ>²y&™‰§ÏÇŒº5ëó1“ónˆ,Y°g×>«~žpû(šËrv¾Ž£ ±_cPΦ¦732“V`O×')÷£š"|³q­zÞPP“<-ß‘B°=WH•†Õ„âññâøC«4çü]9; ]`ÛÉj pPÙ­âúig9 鹈á£á½u-Í¡\FÒ;ÿF÷g&!H˜æ)ÏÁ‡êbäŒÜÝ*¹ÑtV™èªª••,4wC>?•–2'/¸»•áâ9ñ…R[,ð© {ÂÇ[³ƒc¬ SÒ¹âõk;*Þè³Át•göÉó}2‹â“È*ÖK ¾5ôóíÞ avGcÈitWÚ5•(³•"7O”]ÔV_—–” ÒR#¶§—7<õJÁªää–! <>JÃV ;eÖ*ý5f Ó¸ÚÊ5w:«Â[ÿCí#ÆÖ_»žþê]irØ×„^=»ÒÌt&NœÓ¢E%ÎFL'¥+þnDχÓßA&y¥'½ƒôݽdAfºð ‘ܘ§Æ[odzü„÷_Y%þ ïMç3ÑEúq%:]£pÿäXGïA]¾eMMÀ7Îx§_{©âgá22¿•p¤¢ã-ÛíÌáyÇãáqG±z«Ð§3ñÞ ‹‚™÷Ô­~ñÄðéâ‡EïŠùeny‹·Ø' ¹m&tJZ· !˜?ã4^_—*F.Ï=®É‡1ýб=EÿÙÒòTÎwÒ|è®c,}à^{oè½gý;سž¾ß}; üÒe)ªïhD‘bIQ3»¹û“¿¤XÒÎh’¢öŸ<Ã/Cª¸Jç8’–.4Í$…ƒò.(–蟑ú ¹8¬‡œ}mšP]5+±U|Ø`ô[Ïà÷ëµ2pØÆÆÚ÷¾õ ¤°¸äÉéÇñÆziÉXþŽ$¼Lz~³¨X&1x  'Ã÷ 'PI‹¹6aËîƒ(”WŠ‹y†94S-„YΦaýº.?ïÿÙ»øžŽìÿµ"BBˆˆŸH,‘+Q¶¡Õ¥ñèÝÒTÑJ‹í­.Z«´•,*ÕVºtÑ­†. –.QR+%A$$üB²þgîëw¯üøÃOȪծׯëõ}èÞg6-¶´ŠÕ„ºd«rë6³gâËu´(]&Ò„JtjêäkõÂr©ey}Õ®c33#¿Mß™…f›Öã‹ï~•™éþMí½-¼ õßy?tÕ ¶‹M»(Ó­ŽR«\P6ÛÃúº8Î0Œ#P=0ö~­sõ½­¾u—«ts€šÒ|^&¯Ú6¯Z¿.јÕ4Ÿ­ø'ìMhRÏ206â9€îÒqÔ ›8e+TRòÎùtf{¬X•é$ß/±•: ¨¾8{`ÖŠEý ?³p/Ì¡Ûl&*4JWTcñÌMÛn*Õ Ãè Qð)ÈÀæk‘B÷õÍC½×f£§/Ú¢ZÂyå…€qNU§nýŸlQ¾5階ÛÍêâJÖyœüïalß™‚:¶ôbšìÖˆ (Ïy±!Ñ*¡U›†–o>5óê1,ׄJ&<úÜ ´#ç 'ø‚üÛˆö‘Źuñú;ƒtæÃTbçG#m9¶i©&TjÜ}¢#ÛÁ%û¿´ÈœÑ±º–û <æDëÊys8§Œøw/»oÇÚOäu•<ýz#ñéÁý:Yû†®åOk”/ÓºÊZWÉ¢R×i“ž¹jð Aôÿ F'šh·nÊZ™¢¨©Óïí„¡* Û£wX4&ÿÉ ¥ º×IHKã^ uõÂËèC÷€£`”Î/KšýœLÍsñ¢˜º^«&Z›Øùo2t ˆ§Q:!”*õ³èƒ!º’-<ûÖWWϬÀ*âÄù5@MpNõmÖÕjÕ³ŒŸ¼ –5w¢ é?Cú…9«wšÎ¦Õþ´ÆªUÓþwìØiŒ?Gêl3“™;™sÉÙ¸#?Œ|<Ý$LwÂÞÅ‹¿Iíoܸ‰±~:ÞÕ«—‘}ù¤êWHK­õzÁÇÛ³„šC49wYy5á^»ù¤ÅÐÌÏÁBiÝMs._ÎÁü|äSmuIõºicÔ×ÔúŒuC¥*3*#>2N¸r`-Þ‘œ>:ý ¢û*ë* ]k¡ðú ¸6ðB}7ÝBŠÞ7órpõÆÿHýµ× kÁ‹îÃâ©l™eáó‰ódó’>Q˜=³ÍG«myûsóÕ+ȺÒôp­ãw÷:%|Øó*¤{þJ.õ‰:RˆZÄËF½WGR>ý×14åçH逫-ì¿r`îqòoXWççHu%}¿ò@¾ú…¸J¾˜ kÒÇ{áÿP«Ž;ù¤u>«©,s€ê8r«KŸŠ®"mßn\ô DH@=ü¸`.¶‹…´bæÃ7o‘iÁµÖ |?g¶²Ë;ç?ƒ¢|¹«,®ÛŒÙËd+­OBL¤e½!uë źíše6´,4¥Sëut4Æ3ß¼>[ñBÍ©ßÚ.vrv¾búG²¥„bpuÔN+Šç…Y0L¬KAìpŸe/´æ°ÈõCÉà ü°p¾I'Çñ:³èEÓâhü[ŠÉtoŒ|{ª•uœ´ï>ÅrE£*üO¥èhË•Cxóϲ)øÆ‘£ñêàPKÓÍiX1u™b$¯X:!—…Çœ!Pü8W)oÒzc&²È\‰;­‘äºÂÇÔŒÖÕ|ÇGÉLä9.¹×EaÞuÔnØ~´¶RQ¡Ð|…üAe£6¹NÉ#u%ŸÿbÛ(Úb”®¢úᘯ±k ü¹vbÕ¨4kÌ–6¥³p¨”1áš‚Ìå]»&Öìó ºðñk††NÜôh}¸ƒtêýìI²„Ê.fž“šÓ2°ä>¨JÒ~—’*mÕ§’JçU— è¡ÙòdªiÏ®ÿ¢o jÞ(1-ç¶ÜÌ<¢9ï0ò1‹PIt€üY&ª.‡õ½ÐÉÎl¾(È¡â(ý8?½·Òœºˆ~æaÇk7Ž„JNÇ–uïJ¾§?i¿Êî‘Z •ÇÀÞýÑKÉ?ðýa<ö€å[¶œÛ’{áŒb®ÌÐ7³U ˆ'F†a¡ä“' ÿ9Ý}tfé­ÊòI#àJëþŽÇl5»º7„¿ê—©ˆrå•UÓ­! Ôg”®¼Ú]2>Æ®0yläÚ‰ÍÍ¥Yc¶ôÁ(…C¥ŒÕªƒ†ä»½Sj¹wš®R‚W1ªÁ’‡› Z5ñ@se³ª*‰4Œ#P5¸râG²·~ˆ_—ìò+ê¥HÖ™‹lÝ öêîP /ãÇOÖJ“nw²7ÜÚßCªøù‚ÊК‚>¸k-ÔZÁF€`F Ê PÞ¯U¡Uæ‚sC'ž%sXŠ€¨s4úÚøV2Ÿþï(¾ú¾ò&iÉsqÜÊÄĪ8÷î¡h,G-ÿ5£]ág˜ü»ïß‹ÓÃÂ(vÞ¥#ÒònK江•öÖEÛ`ûݧޭ~Où$X"3S»œE§-Y !*…™øQ5çß7¬QâÖ9[¶˜·-"›/kþ¼…V‡] ûã¾Îu‘,|¥ÄsO)Ë»-ÓN(ÕgÁ‘O”Æ­ÚÀÌò‰f9šI‚%Ydm×fN`F€¸§¨i+íîð*N íž‚™;ËTuÔG…°Ë+LúP=G=‡GÛéïx\Õþö†“…™]poÛÏŒŠ‚¿ZH—ÇQF€`F€pŽ€úê¬ÌïתÐFçs#PùHýÇItBÞ60npx‘&¡oéW¥s¯âªÒ½†žŽL˻·EkrÞ"|’}ayZÜÐF锺ÔCÙÛRˆk—²v^ð²ñ÷ 2\5G+:JËò¢*5dé’ÒÀV÷ßÂ,üûŸÛq4-ù¤Qàáå‡ðîG[ÿØ6²[6yWN¥àè±ë¨[ß›Ü"è|éÚ”ÓŸš+f:ô‰BS¡©¥È>zÕ/r«"tR¾m1¡¾+­5=›H›HUñ“møœ`FàÞDÀÙ»éÞDƒ{Í0ðÆì¶ãòoYdÏ4fáŒìN»{5E‹–ÍáQ³ä;½VPÖÄš¾xjÑlmÐØ‘9kúæ w'RÈ¿®Æ”>T>Èm’jªîÄWk𗯲´1*7–LÏý¸­{1YµßÙØR ÜcyÉÛ«hêÞˆˆŒ~Ý[[ÌØ©n^hUȸF¿]qµ_ê[™mÏÁá²PI%QåÝ–FB<š!ýýšƒÀPkóõWÿ{@ñ±¤¶€Œ#À0ŒÀ‚%Œ#P"ÜÈ.¯_ ýJTú.ªIvV}Éiý80Œ#À0Œ@9!PÞ¯U¡åt9˜ #pgÈÁö¿PªŒÀ€îNæÙnÞhæÀ‡XMÝrƒ.ªïƒ+iuÈ ÚYH»‹võI0e”N0.×¶ÔA‹ö&à;Zp¯ãB‹'·©› u䓪‘Òƒ‹¿¤#m³á¢1*æó'$‰æA*uè?t0!ÿÜÏX·]2÷vbÓGHh:Cuæ-©“¤}×) ­Î‚®.Αž,TÍBRüGHÚ…Y“ûØŽ<ñû®ÞøAn¯%á³ïB0öÁ6ŠFà $µZóïe‡c9·¥~ó 2UùƒÔæ¤Ö£íÛcÑFñfÎ<„Õ%Ù5F€`'Ó;†`F€`F€`F€`îU2÷mÆvÅÄtÏúî…ñàBæò…›WsµäzÌé¥Ó˜:ˆ”œçM\H%¡RQá7IŒ ¯zŽ…Oj>ï>еBÙ¥Q]D½ò*ú¨>ÁüšáuSC¼3÷ I¸”ôõOèÚÇ^ÓÈa/j¢]¿‘h§å"+í 6¯ŠG i$!} ŽZ‘”µo¢ ~ÃòÝÉÔä‰McúáDÕÅé½$M&]©"ÚâÞ#£CðA¼ðö+>ùó4„t@ÝÜÓ8\Ì=Pª¶qaF€`ê„ÀïªSg¸/Œ#À0Œ#À0Œ#À0Œ#PFòRñùZÅ·ªO_D¶±6U2îª4àüo9Å´†ã:J£tEUa§Ú¤ô,dÚh+ÙTg j^B!„ !ŸÞ1Üš´ Oarpïü"U¡’’æêŽÝëÊgNãò­¢¯¹BæàPÞá3ãY­¾ûNÁG¡õ¦ µü1fÞ$D(ié)HúN*™‚!¶Ö h±ÒFJÖ¿îÏ`âÈyÊIŠP©5žøÓÉ—˜ÈdƒDaFàžG€5–îù!À0Œ#À0Œ#À0Œ#À0ŽnûJò¸"R¢þ¯§!ónnMü¥Eu¡ïpé¢â€ÆR…»~#[I>R)Jò£t6¬­Nñ¬ƒÀ Cü"z‰k·_[Å«y¸ªÔ”/uÀªZ>©l¸Z–À6m¢˜Ó7²&êj2È«ÈSƤ¾D©âî-@ÆÓ‰ê¯øíV_øküNîþ8y"3Óp!+…..hèÝ~Þ5ñýÕ¥7êÙÒ)ä%>” -þ]á/z!=ý®“_åšd? п;ý=¾V*òÓÀ%®™ 2Œ#ÀTSXc©š^Xî#À0Œ#À0Œ#À0Œ#Pj®Â;Éï‹Qèîï&ÇKûïVþõd¢ŒÚÈÁ¯{•z굂·ZQº¢Úgg½Æ¾ × œ>o/Ë=—¦øÒ‚š7(ªœWø+ù9’CFêÜtÐ&—º^Jj}Ô¶$:(_t’b{O*dF¾þÔ†°¡o Ú„†¢]›6$T"U¹«Ç±K1EÙ82Ü^¨iC_ü©¾rçm©áÖÔ†vÔ–6Í$-¼“û(ì½ÞV½'Н‘K0Œ#ÀToX°T½¯/÷Ž`F€`F€`F€PM»DZÄm’Q¤Cϰ2˜wóFXÅðXú¿pôÊÿ¬j½yî~þg(´zèh(Géß(ÆÀAÄφmºh¦Ìvíû¯ ß›HNüAI A—ß[z`SOï4ÎÆyÍf¸ÿAÅ[Ø/ßâç+6¦éÈcÖñŸ„†4©e›/g•ø¿0™éJiŸ6ðq+9¿£ß}£Ý‡Ý»·,q•N m š7©‚æ¶½ÐÒÝi œÁ0Œ#p!`ѾÇ:ÎÝeF€`*ü›Ö«&Q ódF€`F nšsq“”\jæâò%¥ð¥«È6›áQ(´\ááîjÍ¥0ÔEdð„·Uá­KY^9†M›‘ö‡+: xmZÔ<»÷…û–XZ ¿ŽøeG³iƒà+Lzå¥aÝ»›>&ôéÜÌŠ§Qºro‹[ ŽôÆ'„IÞk‘ÐÆÃd´kñõ/r³÷￲š*³B€OJŠ@iÇyˈ^ÀwÂÄÉùëà5}ë‹1{Ƕ®ÅvEK¨C”µPµ¨±%h³Î]†›­ˆ¶\%í»lׯhæí¡™4gAì[k5­¼!ƒ:Ò]Î`F€`ÁF€`F€`F€`F Z!p»¼‰mÊ"¹ÖµkIX85I9õÆøùÓ¨š £Ô‹§¬ö ƒ©Ú ·²Ó‘¤˜Êrïö –Y€äÞ¸ŒŒ ×å~úôÄØ~A–>sì"Púq^Ó» &>Š¿J®Âò‡ÐªCòO¦ ƒ®±ÚÀáÖBÕ"Ç–ù>}÷#IÓ8 5{)É¿êpÁ3ƒÃ4šaÎØƒåK¶K§î>&´ðuÃE¢»¨è‹×Çt±æ”[r±gé2l—ú_¦¶d2ð7¤ü’¥¶=_˜?Ú¸´LŽ0Œ#ÀÜ“°)¼{ò²s§F€`F€`F€`ª3.ª«§l‚šª’„RæÖM³VÚÔé÷Љˆ´tÛÈïj[ìŽÕs·aH…½Ã¢1ùO=²ëÈЄJuE‹Õ†:6!g„®BÚR“´”Þz=ä.äQûU¡’{‡(¼þÚ?¥›|¸cçþ‘Ï`âÈ­'’-B¥VŽÄã{Úý"ÇVÍښ曆é¿Z •ZEÄ´÷Ÿ¿¶Zõ,c?ïB†D§ •BúS;&GA§¨µ·üÛâ ï6uþtþ’b*Õ ÁÈ×ÞÄ£m,mÕÂF€`{«VMûß±c§1~ü ˆf&ÿ* ÈÅ‹¿IíoܸI•îGy5žñ(/$™#pï"ÀÏ‘{÷ÚsÏòB€Ÿ#å…$óaF@F *>W ÍWpúL6j“ð)/\Øø£¾ƒÅvÛkl”ΖþÜÏB\9wY®¨OÚJõšÀß—TS8T=ÎoÓ˜L?“…šîuQ˜Wˆz~¾ð¶5YÂÞÝ4çàòåÜÈÏGA~!\ê6@£¦iŒÛ [­XÞº+99¸víò òQˆºðñk††„´VtEœm‹9ï ²s®áF^>òÉ\fíú>ð÷kh§iUDÕœeŠçšÄ$Œ#`õ~ölXìîƒ5#»˜yN"lX>ûtM`Sx:08Ê0Œ#À0Œ#À0Œ#À0å@M·† *½ÖƒQº¢z`ŒgM4ô dí¤¢€­by5 ŽIGÝtu󄯟Ac­:hè-~ޏK3Ú7÷†ð¥F€`F $°)¼’ ÄeF€`F€`F€`F€`F€`F€`À‚%Œ#À0Œ#À0Œ#À0Œ#À0Œ#À0Œ#À0%BÀΞj °DÔ•¸PuéGyAÌx”’̇¸wàçȽ{í¹çŒ@y!ÀÏ‘òB’ù0Œ# #ÀÏUhƒ›•@IDAT ÷<Îï…«Ì}äqÎc€`ª¬±TÕ®·—`F€`F€`F€`F€`F€`»„€Æ’O“»Ô”ò©öÌéÓ£æþþåðŠsa<ªøäæ3•~ŽT‚‹ÀM`ª8ü©â›Ï0•~®VºK ªxœW¨Ì²Ò!Àã¼Ò]n#`õ~6Ì Š²ÆR»`Ü\F€`F€`F€`F€`F€`F€`î,Xº[Ès½Œ#À0Œ#À0Œ#À0Œ#À0Œ#À0Œ#ÀT1X°TÅ.7—`F€`F€`F€`F€`F€`»… –îò\/#À0Œ#À0Œ#À0Œ#À0Œ#À0Œ#À0U —*Ö^n.#À0Œ#À0Œ#À0Œ#À@Aî%Ú»{<„c©ÈʽN¥ë"´×£xjÄò®Yu?ýk6ý7¤RuÑyÈsˆÑ î¸]eä#óôI¤üôolýû~<ðöB hYÛ1ù$R÷«mêxîÞ&thëß¡øúsvšš}<K®Á‘ ª/àxnR º¶twL“{»þõ3n¹º:Ì¿y³B{?“[1¸8¤Ö%Þ.DVÚ!ü°sí;†Œ %ìë´Ç£‡âñžÁp)û2\3]3ªZ”ǹã+V}Ç9õ·4ÏÇðp*#À0Œ@9!PcÕªiÿ;vì4ÆŸ#±lîï_N¬ï›3§OW‹~”zŒGy!É|{~ŽÜ»×ž{Δü)/$™#À02E>WÍ¿`B×gq¨°¢oÀ„žÍìK˜S±°ÿh$\¶ÏBÀ0Ä9&{!JÁù]xëͥر/ÊpTÜŒíài•¦žä%¯ÂãbÕSû£× ¬ùçd–ÓvØ´-sñôë[ìë¡gxÛFA»j &tvÜG‡•9HLY7ãæt£$…ö±Ž±‡Ák漲ʓÃã¼ô×¢ºŽs#Ϙңww(Šçw§I\+#ÀD@½ŸûúäP1d3ÏIŒ[¶,× Ø^¹ÂÉÌF€`F€`F€`»ˆ@ÁudIÕ{"*f"Ä‘öц¿âåáµFÅ¿ø öf×ÐÎåHâžµ•zM‡ø­ðö¤9;}=¢_øy°¥òK¶*Ù0·?u‘µ€z‡·—ÿk6¯ÃòÅæ¥½¼ Ríé ¤d'ÇY„J^½ñî† ˆ_7Ý”ºâ_ŠõÇóì9+m”3<áéeý<Ñ¢‘›=])S ®]”(<»ôÇ ï,ÄÊ‹W¦ò9²S–íQÏtGã×LǤjFyœÛ]·ê;Î >cìâF€`òD œöþ”g“˜#À0Œ#À0Œ#À0Œ#ÀBÀ£5¦,^‚€îáðÖi¾ºm›©š1XûÝqt¤U‘•´«ŽÈ§aS?Æìm¥Ó3óQÿæ¼´‚4jö½Ï’£H ÉÚt\ífà…©­ÑánðÊÜ€'ÇÆÊŒŠøw‰íFÃM×F4À‡0,r2„îSÞ%Ù_lJu k_^©”‹ÀòMsÐÞCh]5Ãüž˜9IÒîZöê—xìëÑNÌïcÑîX„Kt%¨²”EZ=ô*ô@×àFÊ–Xº7ˆ´Ïž—Ú—±ú+¤>× A:³{e¹f–ŠªhŒÇ¹Í…«¾ã\tÔÈ3Æ >eF€(gXc©œevŒ#À0Œ#À0Œ#À0ŒÀÝCÀá=;Y •Ô¶„ U”d-´ÉÇž ë•b½1yDˆJ"ß}Ý””¯ã÷¡ÀFkÉÅ»=†ˆBHsOÔ«ëØ‘CqR£¦µPI)P£Á}èjWÚp‚ùäNÄ+¦ýz½õ’"TRØ5è„g¨YŸc×ù§õ”°WNé‹ÊpoÙÉZ¨¤vkq1ÁÊYr¬šW¶k¦VQu<Îõ×®úŽs¹—†ž1z€8Î0Œ#Pî°`©Ü!e†Œ#À0Œ#À0Œ#À0Œ@åC àâ)84.g>‰owÊíõØ Ím›îâ"åÄœ­‘b¶-P~ç·³þƒ Šæ\k•™ñÉ=;žèþG_;~Í;uUÒrðùÖãvùj‚KÙ-Þ©¬JqÌÇ©cNÚT‰®Y):tGŠò8¯FãüŽŒ®„`FÀ,X2‚Ó0Œ#À0Œ#À0Œ#À0U ”ï¾ÕZÜ©S -Ž+YŠ_& ‰7\ LÅéCm´j¯úh"_DVš3úre‹gŸÙ‹¹ÏNGŽÄ¦#^j­9Ujî· qé¬ì¿ð_={on~!_F7o9©â:~üç¿°wÿ/ÈÈÎwR¦’sÿ« üÖº:*É5Óµ¨ÒDyœW£q^iF7„`FÀû·m >gF€`F€`F€`*€ùäfŒ_B~’¤Þm=µþäývLòi$"ô'­„ˆ@I בc&Á“^È¡ä”ú`NÇÒ·–áfü’„Ôt…CÀ ¬Œ‚²ú4ª‘‹cIÂ[Ìø;jsÁ-­g7®^—˪ÿ7•Xâ^Ÿ®¦ÂÔe¦ÌƒðæÖ¾¦´åÉÇæ™²%Á.lÈýh øÝµkV.}«8&<Ϋ×8¯¸‘œF€`ÊŠk,•A¦gF€`F€`F€`*1çwáùAó”zbÚÆ9$´Ñ5ØEçAHÕ•@F&å4Éi²N‘>ßXü*voMÂúiB%Áèj6.ý–mŒ¥žê¶îë¥ø(òp…CÃznu õ,égdëüGÕnÒÝB;¢W¿Þ UK‘lßz¼4à!¬ÚI_[ùÅIÓj×â¼·SaÙoØø½Â]»få×ÍòæÄ㜭nã¼¼ ócF€(7Xc©Ü dFŒ#À0Œ#À0Œ#À0Œ@åB ïèf 1O1/¼·ZÖvÚHWÇË7.]Ñhy:.£(i¤v;,ݼfÜÂÕÌ“øqËFÄ%VÕåD¼64oÄäž>néX5ëœvsƒ³䛳Q»Åc˜óÜj˜‘¶ß‰"•kÁ h=óñ²>¹4íùk{¨%Q}ÛãaΊ$)-nìè²{Úë4«2¶¯ÂâoNó¡s§LùTa¯ÉSл¹£^ä`óëÃðÞVEx9ß¼Ûn:m%­AJäŽ^3ÛÊ+É9óê?Î+ÉPãf0Œ#À(”ÓlñdF€`F€`F€`Ê„@ÆKýâz¥IÁx{ó ' ‹€ã×S䓨]Q&Þ:¢dSÎÖ“ž×¨ ïæÍdÂæéÜÇ‘ l¨,Kxq)˜@uåÂ| _oMÔ„dÎkl B°$ ¨]9’ß n[x9 êBÅ÷Ë¥A3DÅÌGƒü1˜²Z,äľÙhßÁSãvùhöì,^£«Áˆ ö×¢à,–ŽŠø#2» 1óð×E?µé.]3­§•'Â㜮Eµç•gœqKF€`¬P§gÖ©|Æ0ŒÀ½€@Á%ìJ؉ 2Þ®÷£hßÔòqv/tŸûxo!}t¶: ׆!x¤' U“¬ã»·zŽœ¹wï:hØ0û?„ó½]µ/,·ž¨î…gbÀÆ,«Ùûã,B%¯þX¹i†µù;]Ü[„ ˆÎSé—qúª.ǽzNRÈÃÍKzyÇ܃àݘ¿BnŽ#ƒ,âz+µx´Á»Ë…Щ–•f‘UnÝ´Tü¹£C2…·Oðú—Ì5¨Ó.t·ss¥0¸q“hKÂú= H‚% ùÈ9@'XjE&ß £ÖrhxOâ.šØVo‹P$_BœN¨Ôë­1ûñ¶”îH¨Dr„JtͤNÝ¥?çb|Tßq~—†WË0Œ#PX°d RîYìú×ϸåêj›#ß¼Y ¡½€ÉÍñä9´P½Ÿ¯Û…4¢¨‡ºð0¡M›vïÑ ]ÛéÔøÖdÝ‹§höìê‡};¹cÊ Nf’ `NDz¹ïKŽŠ£ƒû²`©$˜q™*‹Àé]K±lEà5}$ÁR•íŠÃ†gl_ˆè)mò’àÓ( –lPáSF€ªû3‘¯1#€ìŸðòØ• X¾i& •œ|ÊRêE‚¥ËôÛ}y1¶ß¡—pàï4Á«L¶29§ÜþëÔSÕ/2pòBzx«çîha1MW’ ½ü[S1YHuôD.Â;¨¼dêœãÉÒ÷€8ëܶøïu™ÊòŸuÍZåÞ¼=z4·ä—4v`ŬR4•¦þU*A]É®Y-­¸,ç¶Õvœk=äˆ@Àœ}'SŽbÿî­Ø£¼Q´™L µ‚|dž>‰”Ÿþ­ßÞ^X¤9T‰&7›×®ÃÆm‡qCJ¨‹Î=Qÿ×Þ.E¼KHìŸøéÇX³éߺ!Ï!fD·b×6³i“àÚÕŸc÷¾“@ýz¨ãѦ 6¤ÉŽ^tƒ¯³wXIûG¾ëÒ$á¿9·àxÅWê(ýÝ<Û wç5¹—phïNìýñŽ¥f +÷:åÕEh¯GñÔˆ'ä]S+«¥SydOÄÒ…kp䂨¨ðG<7)][Z¿ÇÔòê1-i3ÖÅm´¢{zìhôn×H-âðhÎú ë>Ã?w×®_õq؈Gâ]²Ø%_ÓÎGÊö¬ÿâ[¤ªýó ÆCÇc`Ï"6Â¥£.—t¬(èd$4^ ˜›7Q«YGôèPúyƒCð«h" –l.\Þ‰-xíõX›TëÓèU[0¡³EÕ]Í-8¿¯õ›Œ=j…|FúqÚ™ˆø ×ðMâ8eç”®.z;k&Œ˜®LlMX´{Â+xÒ®«ž£ŒÀ½…€K-ˆÍâ¹¶£Ž…÷¶š#àâÚ˜zH£½¾ÇÕUºÿg« •¼:âå9ãh×u~·>œû7¨Ò]æÆ3Œ@™¨ÞÏÄ2AÃÄÕ|l~s’¤}D«c˜¶qž• Ç]l†‡#Ah ù»ÎDTSËB™ùøwˆ'¡“az¾N´hD¾…ŠöJÂÈ’Cÿë `E![ˆâ¢2¥‚Nÿ|» yÁ _ïè½ueóñ=ùœ’CëâKÑâë:“ü“ÆãþNÍ´¸ÑˆùøWxIÒТ+Öo:èP‚v”ß53Úî»KÇã\õçú^Êñ²?cìyVî”|ìýt­Ý‚ å9,µ7 ”üÓà‡‚ó»ðÖ›K±cŸXñ°„àk‚ʹ ;ù+Œõ¾´ži¡¢/É%³°d–ö <'Í©XØ4ôm$ó'#á‹aˆÿr"LŽ„R$ðÙ»z:¦,I²TwYZMEꑃؑ°—¬Ã–ºäsoû´éˆ³iŸ¥R]Œ6cþA]¿5ÿ‚—î‡tÙj4cõûØF¿èÅ0¡§Í»À(´d‰>î ß¨U›0¶sÑ‚©¯i ³¯O’Ù×tK=RŒÚ™º/ËBÇáë5£á]Ãfœ¤+õX‘“‡­/3^hœ·ÎoÓÃjwú»Šè‘ùÖÿp>›œd^Ì“~".ÒªDpѯ.{ÂÓËú'&æ--RÑN™±:¡R¯I³±†œ®Ž[‚™3F£[õÞ¯žsu} œKøøYU¨$ê#E—ˆø`FàžG )I»°íï_aïI1 ¯^!ïÌ/ص}¾Ú²Ù¨aß9ÚAvBI {~ G´§Ý̽1êˆ*Â9¹=#NaF€`ª>æã xo§®™‡°7i¯Õo×»r>OW¸ïÉgèkW„Ìy~ÒÈlœ·³cÖÐ¥¸ôŒ~$X‰ë´ 8;;Ù¹ù8>KËȺxf25'òÌÖïð죉X¿å'd%Ðn÷ÓðÁ>5¥5¼œ­šªEŠ;z´ÇsÃMR©œ„YX¸=]£8¼n¦V—)&A6–IÌÙg‘vÞzn•‘‡—æª  ž15Ðø‹äá ß×Hs¨¿)û÷X]¯½4ÏÛ•ô òlæAeºfZU3ÂãÜæºUãq.õÔÀ3Æ¡*|jÆÏ¶B%¥7Î nù¿%Û •Š!k/bF©B¥`¼°øcÄoŽÅ´áês?ã-@¦Í³H¼7âžµ•zM‡ø­ðö¤¹Êôõˆ~áK»g˜È<ðѳ¡’Wo¼·ñc±hñ,Œ.Ó׫k¿IÁHÿ<üŠE@.P_W®àºb.Õ“|ìMÄ‚8ÒÈÚðW¼<¼£V(þÅW°7Ûú£tÄ5;9Î"T"LÞݰñëf£i‹ÿâP¬?nýé{Ó„J¦±r#­K/E2u+òwÌ}s¶_Q« BÏ©B%¯¼¼` Voø3'õ×ÊŇT›÷¸–)EJ¾¦½ëýW4¡R·1¯`ѺX¬\5 Q¡ Ç#+ñÞ¦4kötf”ÎÈX•ëÇ‹­|@Ì—ZПv,Óéôxºë÷ õÁoGŽk;×£ÏC¸ƒêyGÿ†GGÅj¼ÔH”HPNL1E|ŒeŽrz×G’™Þe”ïŒw¤ì<¨Õ%ÈÆÆMp¼Ã]áYÒC×WÞÃÀmÔ–Ë€hSbh0šä^@jº"4 †E1áÄÎúûÿxü+äë‰æ ^&„µ÷'\’p(ÝRk·‹Ñ[§ÙeÉ)],W¿>˜0ãUЬØxÒÅV«yPY®™ë*xÂãÜþ¢U×q.zjäcPM¹í./N„oãèÑÞ _ŒT¢µÃÚÍÀ S[£}?yenÀ“cc‹€Ö6w-{[ظ `ÂÛ[?Öžo¦WW£…÷TŒZE—7âãí#1³¯²îI¥³’ÖèLy’¸Â?qyf>êßœ@™É×Ýûø,9 cuæH ÎlÓ´5:_®§iÄšZ!¼'•¥pÑë©I¬Qêþ‘1¾a±‰èÈG ‹ÌGWjï±°!÷[¬My´Æ”ÅKÐ=ÜÊ `à«KѶÙŒ›O}#ÔÖ~w]‡o…J0JGþöÖ¾¼Ra"LÙ’†˜´6Ý ó7zbBä$I{jÙ«_ⱯGk&oŸOÄìÕÊÕN‚½W³±-cõî L¸ÿy‰nÛ”µxöÐ gQ‘0 «n¡xwÓôPÖƒ‚g Ô׌èש­é ì\…}(ùšö%KRÚIóùÚ<$!kÛZôl#öYçmý=¥#ý¼ÒÞ 6ݳ¿Xg[æ â­­³«ù™“áP¶^›oJB¥“s5F!·êkñªq-iCóaªfØo¶E¨dCïâHåS)#¤Ñªê» Ÿ2•óØw4o‘3Úð¿ïiîŽìóg‘K/Æ&4°Ùå'oÎJÇ¡CÇp1ï–Ô—~mð‡ÎÁÚ Ðqó‘vô þ{ê"„s[P}m:þAM‹¶%›yü'ú娅poÜ]"BànÎF†x¹xÀÔÔÓquNR³NÆŸO? îÑù~²íë NÈ­“i¢–™z)¿žƒ€¢–»;¼{÷™?LšÝx•¤ý'¾Y™™´ Ôr ²NþDí–qhpÙ’7i‚msV*öÿû² ØZ Z£Ù¯u·ùˆV[ÁÇ*€€9™'NášÒÔk™§™åƒ‚pkè oûI¸\4´œöáiÓ`D«Ž]RÄýUª{¡€Útú4ÒÏœGv^Ýõдmg„7²TØÎ¼Bæ”ûSŒÏ?¦{ŽÚÔýA´pɉ ZïpþT&²¼ Èìƒ|›z#?;'~øB3C{æÔidùxÁ|ðnJ;ˆtïÞ¼¬ 8•–†Ì‹ÙtŠñßá]ÚÃÛvß‹Ý=eFjÒ&ûÊîMÚ oÏ`¸Ü.¸;÷?GìÆ'ÜŒ¾_y _Ÿò‰B>ÎIÏ\š£4hŒFÞ¾hÑÒwÝsJ.Ís€;3ª«s-ÎMé{è]W*ÅM}g`ÍO<-í\Î!3DêR“'Æ._Q–…D+b—zV§ŽN¼ëYï­÷òB&yq)‡ÌÇïI×QЮõ¿LAïàÒÍÝu¬£.˜¼%µiG}üZDÓ Ë<#Çá“£­ÙTâ:õĆjãå 2o/·Uʦwß{ ƒ;7S‹–éèZô'ŽÂ»lÚ‡ákV¦WbçvW¡sxÆØáSUjÔDûÇ£!‹åóàQBw.ÞíÉ7ŽBuµ+œ5²‘|P~æ{Ÿ  •TØÚÿß èE‚¥”°-v^î;LYGÈÇž ë•b½1yDÅ-‹íáϾˆn+FKßk_ÇïØ}´µ‰”|®Ðybæ|‹PII”„J"£Ôý“ˆjÓ÷¡ÌÖú? kÞˆ•“FcŽU¹S3=Ûë­—¬MÙ6è„gD`ŒÐšM·6[›“–¢‡LxáE¨¤¶‡4'¿ÕO¿!ñíÑŒjgyñÔRßá&xÚ|{·hM4‚Î,¯‹©HóUùŒiq 0 C#ëd:Ë"›¾SIý:Õ.>ó§>æÐÖjÜ”±XµSýøUˆ:",ý ´3^¥°ZpëgÁ2Uh¬µÅ„—×­Äàv¥ûÈÍ>º3'ÎáË#KĦ]¥îÞQLè÷¼ôY>–4þ~ÏlL;‚ôž-Û?zG>‚—Ä.#}ðêÕ[fÚ™þÐáxåEàpì3òNZ¥‰9[çáÉ­ò‰íNd)ÕÇ7²à;“4aŒÚ»¨·b1óqÝ.+‘QÊ{!mËBRÛߨ²´:zFNĺEÃ,»¿(7eíx¹ýã°ú-Œ¡{_ ÑËêc÷ S•%'‘šƒ÷F R²…ÂOqpP+;ÙÛ^VÚá$ EÇ‘OÄt¯¤cá“´K9]!µ:xâò­0L”SƒþžZ u£ñÁN%“î×®‰Áh /s‡î;~ލˆw²enìýÊsù:]Âæ¿¼÷>³y/+ÑvîÄs€;:º«meîí¢±ûP´áþö€»‡ å— ¨ãY 94½¸¯­ýF ] Fê4õŸ½' ëâ\¾|µhå&‡œª72µ@`)7ƒéšâ<êF;¶×ü OÒF¯Œ[uP÷:í†n€–â{Ä~ÁP0 zj!¾î}¿ýv×oÞ¢ÍÚµÐÈ·›{k £Î+,ií¢ÿèG +QqÇí4rÍJT]%.ddÌé»c3#uò8WQ/Û87‚½Z3Kˆ-Üÿ”.—͹…fsôêç‰bäÈ·ø%w˜¬Ai>‰owÊå=öBs[R< ì¡29[7"å>h/Ö[éí Å·¢kS[Â;wžö÷yŠ ¸>|Æê{µ¨V\<åpݪ(‘WÝÉ=;rOtÿ£¯«æºRšXÓÉÁç´õL[©ÌéÃªï¿  ³|Öï‹æèNæn¥5½»N`©½D'þ\´mªø`Ù÷XúbMhøÝÚÏår¤Yìçh¼´kÚ-@ÖFÒCóßAb·¥èÝRr™O&b­"TŠèÖB®Wý7J§Ò—åèj½1Æ+q šs–]-ÓY°äô²^Çÿü®’6)¨%L œï†¹v)CáÒ½;6@FÒ&Änø2oÜ@: Üý Ø ìv# ²<¬Ÿ,«#±|ñ“ð=«ðã#P9ÈÚ¿ OŽÕÔo:¹ebk™‚P„J"³¶«V„"9X?ò1,Óvc`Lp* Íq¼7ê1dÚ8;žP­ÄÅ9}ÚÐksÅFé…úÙ<pZåE žn·¯ÚJqíA×>į¾šd9ÒXx¢¯åTÛöÆLôìþzx«ZN¥¿®þ·ÂÒaýº£MC3¶~&O`sv~ˆ…[z`vÿfZµ.®ÊNàô•$TR“i|Ò3¤^=O„Ð]—®¦Ó‘Æ®‰º•q5XÚµëÛ…úºU}‹r”PO¢iZ‡nÌ—°?]ŠÁ3´#ºunƒüý[°CÚ…ƒe£–¢ëTŠÓÌÚrO-Ò¿§µJõ—¨/sî;~Žh—#w£ïWžÈ—‰ž¡4Z¥Í…ļ¦?:ÓsñÈÁŸ$\µ]ÕlO¿Ôs ;ü,º£Ã+»«¸xø }g'ÚIåØ27Oø6¿rdZ+ÚùïÜž´“J\j“týlË[/ØÙæÞó;uÍîFß*ªÎ;…󊺂̷¢j!¾Çl‚x~Òú(¶”2´åŸ+YŠ" ‰#¡{m´jß S§b T2§&8˜¯jÆD¢AA6‹<ZMEC¿`<2l(º–—æªÔjû¿ÛÙ{ñÚb­‡6ÄÌFTsõ[ؾ¬mJÊwßjI:ÙB´ûˆS:²NqéìE…À~õÄ<Ñú}ãæ‚0J•Ö¹hÃ}v¸Ä…,úªt6D î{½°^ÒFK]= ïOÁÊùC¹a:ÞS6[¿¹ø¨UsIj[ÇÒrI°$H¹št‰iËïÃÚ„ë…§{áÑ~³¤IbêéKªE°d‹p¯K0cH¸F‹¯Ä OÇ`Ü¡ùL6¦c­Ì„¼û9zŒÃÃ#VJ¬FÅ}ae·[Jt3aÄÔéhóÈCÒ6ŠŒÅ¶×bŽ4Qþ—ÈAy 3¿Š¤Õ·hÝ„7U7™8šHVä}ÇÏÛqÂçw£ïWžÈ×'sûRm>A"%L#ç:g39Uq‘ìÙðàÎŒh®…`F€`œ"àÑ h#]êeúmøYÏu°±s ‰ke¡’žGÞoÇ4Q„SኺÒy9fš÷s~´"­®¦š?Ñó34>22»—‹°IK°ô™Nú*Ë1žoÞ¤u#‰c^6œb޾õì«k-ã—¨xD w[ùÚ¾¤uJ‘t5r5ÿCˆ€¿#³‡·´uãW¯kÌýÚ ŒÄ7óq|÷SÚ÷”×ÒÔYû¶X6]«‰ê‘4zgo_ˆè¾ GÖc\?Õ¼!0mÃ?1 X½Z*“/Œ­i=9 Î ÇÅ'TYIPÙö›Žoß}LY#Så£Q:k.%?»©¬!æìŒÅk;U:Îx1´faëRB\ƒj±{äø»²ôÓ|ëäkÅŒ4²®ÿ˹ágI ªÏ%}´‚Ge µÉwB7ÚÍÜ«_o„…Ò.h%dì[—<„UûÅ‚˜>ä!9Qº]Ã^ƒ°H/TD´ Ò]ñc¬ÿ¶5÷ÆÊÝó%¡’Èqóoƒ­ˆ 37ÿM*‰´¡è.ì׊›ïÔ^®\€ÿ+;öÓ<ç-ö8 _½;L*‰R-[·¶Ö¶ž»|;À€ˆ‹`ˆ8×hÚ OÈU•§!l*9zÒÉŠV.\šÞØówñÁ€tB%Q¤6"£ŸÒÊjÝÖRÔˆp˜:S'TRÓõÇŠ½ïø9¢Çšãw£ïWžÈ×H0pñr+¡’(ãæá®™Òâ9ÀÙ\#À0Œ#À8B º>®¬ƒ^Þˆ7Wï!å"±æ"BÉï]< ì‚‹îKJÕ—«ÓH]_Í@r™Ò£wB¶.#¯„ÊB¥^1Ó±rC,½3ZYe%Íœ%“°ð‡ zvåÏ&ë<ïí”ÙE-˜‚ ‡–¦ì«+8¿ ÏÓ^9xbÚÆ9q$²!-–î¶îë,SyX,ÛX±q«CÛ•ä‘ô³¶.Õ($\KOxñ ì=oY—Ï#sS_T×謸i'æ×5ƒxZ¢É<}Î6 eZÓ®Q€ëù×ìxJ —3ñ›³MáFé×Ttêm7´Œ"Ù@doôŠì¨a+¬%Ì„‡GÆ"ë¶zȬÄ5¸×ɇ‡+y7ñŸSW Iú I—)O ".Ê¥Ôºª&IG?Ï:øC‹†hÚÀ‘‘F«¢wìÄ¥iÌ_ÛC«¯ û,¶Ç/œIRZÜØ7Ðe÷2«ÝÒrOå£gòñ‘ÅDТ4WwD_^OÒÆÈÒÌ©˜«úQ"š¥1bðÉRñÚµÔÑ€Î:†Ö&Ž0w쬳Zu}n«Åµ­áÚ/ùæâ’úÞ ˆÄ}BƒÕ&´èÒ™RJ©¿žºãÀÜ,Ë‹¥O¤n¡[¥uk% B¡Ò ü­à6™®ÊÆ9­®þhã .G-TYÚs-üèž}oIm´@¾\ŒnÍc‡ g/y†ÙYYZJ¯)Ñ«Œõ_¥–Ñ«¦XOh\üðí!Ì‚bfZ·åùbÑA—ikY³â³j‹@|ôF?+á[‹Ž’€8ÕªÏe» r/á̹³¸p>‡„–Ù8n=°ªI:!Aî›Ã…´d;Äì” …L dežÁ¹ŒLä\§Vý"&E‡Ë§[½ó•®èûŽŸ#ŽPç´ŠGÀèû•çòµÑ=CÑOõô¦dçÏ7žTüˆæF€`F hŸ{ÝV?+ùâ=´d2"#0°sùûI“©hj±†éx™ùÆ¥+i#O¥ ­%‰ ¬¦b,ù½¥ú½ ÂWm|5ë+ lCLÏÑv"2ƒÿ©X8VÑÊ›Šû#©Îçjj-yä?{èÅd% ½Zê×YÔ’ÖÇÑÕ åýB먈Ppš>^𻇠ºböŒEá ¦ô{Ý‚ç•#ØF.Š g¶að€Ùòµ e‰†ø`íüõʵù[d½æX™Ö´ó‘øÖ@ü9A¾ò½b&ÂçØß¿S>ǾX<}2m_†poýõ0JWTÏ‹È#Ó=È4¢&! µ„ŒÃßañ˳±GXÉ’Ò›«;’6]{‰¸¸zZ;¿"Žïøö\ÕD:y1·H ©\¶µðI%¹U_VÊ£KƒfˆŠ™ùcHEO܈±ïD6Ú«;z¬µ»?˜”ÈóÄÄ™C,&®¤ÕFßI“ðáVùݹOv–òÙ;’íJ©È¾Ì{i7®HÕA^ª,Äê‹ã£G#È'¯/&É9™ÉãÀÜi~Ó^MhÕ¤[0Ds/à'ñ ¥àÙ±9éØwÝBvÆiyÅùÜ/ª³AO4÷rT—þ~SLWáŽèêrDe_{)Ôv•Ÿ(µgu¬4©²£8w³D>ü€Ö-J½4Ö†úocºKï«AcÌF@iã6ÔŸ‹8ÍìÄFï…ÜT2ÿúVéü¯ÙVçðœ|Õ±Þðã°˜ÑÄÔíqxgÊÊR;W­ï^üæ—Š¾ïø9bôª3]™ á°ú>ïò¿_y î†:zîÚ\žØÂ§Œ#À0Œ#pçpk‹ù;?ÆÂ dšLìÁ;B>²•½xAc¦c¾Å{«å Â7µÖYV|ÔMÃZ–]¤#ÚIöÝnýE¨¶¹Ñ³ß$Œ°ñ©ãØ“þU@¤Á93m–-þÓÌ®Fg >¶¬ËŽzïi³Ž©2~XŠèa™i{ó ô¶Ú¼[tꇹ¶™Ú1O‘ÔÅÚAÐùXéºÌÜo”ˆö$ÈG #^^ð0vL™'™Ã³^¡ÏÁº×¡ÈZÇÚ9ÒÆÊaÄú¹×Bsli›M˜ÑeYÓÎKŽ×„J݄Œb{4žÐ»± µ÷—^ŠÅ7kGkkìFé$ ÊãM¦QøËÆx&r²´®phÓAr)Ñ¡|žåÑÖ;È£L‚¥;ØÎ»^UX¿‡I°$!õM°ÔuUïú–ðo, µ¹ÔÓ-&+OÞ‚›;˜BnÇÎ Ç}L?NŽ}/ §`Šã|Ne*Wµ‚ \¸Foò¦êxWÓ‹ÖsɹrEòÍhû°¹mÎÑlª/5‹uònˆí+öN¯çëïµ ò1çœãºtJ€ÖŽÎ¨¡–ÓË÷i¸ß´L™4÷¤ñQ|pÑž%)«–1Ö™ZÙö£²â##`‹@Ñ{A,¥Ü ´ëkÖý£µ¦ÈA10¡Í¯LBBº…½]¬¤í²#,>!|H‘|H‰²dyêHôì|ðË:¼ô†jJÓŸ’ÜS%)ãŒñéü)#.Q±}¿Þës€Ò\•²Îäº*öYTšþpYF€`F€¨¢4h‹ÉkĈ“‡‘~†¬OÔªßæ÷!¨¹ ➘§tÊ„FÊæw÷!š€HÝ4lÛó«×.*Iy¸©NWÜ,kIM‚Zhæ5ZZȯ¯ÙQÏ¢uQ-§Ì‘ÛY»ðÆŠã2ŸÐ‰NZY¶k¹¶•dﳕÈïÊM3¬­ÅØ(祣sG‡.¤¼°O´Í±àÛ¹9ÈRx߸yË®ÖÇ'cWŸ‘øùprnÝB­¾¸¯C0jÅJé ÿúÝí¬Ãت.ÖYë Ÿ[ÃÈŸq»ÐY??Q*¿{º$X*ËšöÏß*ßߤ%6Mg±ÄDn,â·aÖÐIØ!6Ù‚Ÿ³F‘ÿg¹©Fé´Ž–S¤FƒŽx(”üK ÌÒ÷ã”y4BJ²8XNõW66¶k½¥jŸ[­šæìlƒj OEå¼Ü]¥£¾¬ yU-d]³¾qkÕS18ˆäÓ¹ ¶,KË}«…zJ}Þä²þ½ŠiM/‚žÏÖÁÕy¿nŊ齨©³Þ°ZßÃÔ >»ÓøßAUÊ/Ü4¾a3¾Í§“íÒ ("€´éDš~$޲Â\?kqðع}3*øu²Ôu>GPYv¾Hè.úyG†õê„q«ÕÐÕµ/ nÌÍéCÿKÞQ£Ou's{é%!™Ûó EÏ>}ŠØ¹b-DvijE'‹É¿»dEGåDš¡þ;cÆéŒ@Y0p/¤%¬Ô„J¬Ãä¾J+òáçQÖ¤'a×rU¨0 kâ'"Pù2£•A¦w–ŒŸ#wo®MA@ÿ./ÍûUOw/Ï‘Qư{Ù»WÁfÔÔÅkœdÿ„—Ç®Tj•}ð†ØXqØ$t^þ­‰•Xƒ;Ž£'rÞÁz9çx2©'È¡s[}¨ááƒöú¼ÛØûuC¥ D‘¼ž¥_›óö¶_|n?"½H°´ƒ(2vüÙ/†Ãøšvþ›¤´ÞÏÛÞb‰w'<7¥7v¼.Y²?®Þž7JG¤åôÎ<\ן–{]•ŸáïÊÒĆ$,>’úÒ@ÖÿDš$©AÄ•<ªB8“¬šèîï$/‚«ínýà`͉×ÚõûÔdí˜ýË´›>8ØOJoв<…¨þ6¿¾½ñxïN mG zª•éŠ%t §UÊF œð0µÒœ&n›²‡³-¶ª2÷ÇcðÐíkºÝÍ”äôì:cÿ¤ÝŸ ÑùyË3 ·z4QBüF½£H%ñÌ|®ÄƒšÂC4EÔÕV¼hD؈…_¤ÈQño>‹õ¯ Áö·¥¥ŒmŒô5o®ð#‡• „¨ªøP@X™ç/H¿l³,TTµ›øhø¥®ø{³,øÙr5Ô[&|~o"@·X^y÷ÜÀ½pãZ–ÖŠ?v“U5˜‘Kri9ÜR#%>èzw³ÄTjÁºð PâmÃ5¡’H)̱øuÓvÎ)EïÆŸ#wu®Ó)F߯÷Ú€ì­g+ïÿLò)gqr퉎Q´ãT DZà“=N¡<(ÎdF€`[Tmºƒsý–~WaÝ@ØýéRM3äÉŽ:ÍðàPeÎsäsì:o½þc>þâ… …°?=lñ;턧ƘäŒ}Ÿ`çy9jùÏÁ¾mBÀB! -ìerý—¦B@¶LñïòƒÙ¯Cq@æcó›““Ꞙ¶q^±>x冣óí:@Ò<6|m»˜•ïɧ“"ðXëmÕJ†ÝáöùD,úLèt‰0¡ ¥‹Ú<ޤ¨šej¦8Z¾ß=;¶‘Ìc_Ó¦±§Â}ä(ÎY©RR²R‚ !)¤A:•—åXš±b¡ÒÅ .â„ÐV! BÞð.ŸÝ“ÿe,¹Õúš6pC`cw«Ÿ­&’ªÙd[NÐ •)˜³Ï"> õ!#)/ÍMR’¿3ÇÆÊ™ôÀêÛÎZÒ¬dXòoå+çy(J»ˆ€KÓTˆñ‘ý0õµY˜:²?žû¡6±PKHGRYŽ?QIÊÁ{¦cïuÙ;{?Š?oUî³Ðqx,Xž!¸µ|/wQÈÈ/ÙkŸî¡ådYc>ÿf©Î©ÈØIQònª«ïØç"ò‰4÷Y<2r&<7tŠej=Z‰b"į÷ä)š0(nl,ýûaäÈí(0ç!ãè^lÞb¹ÏÇ”Øqx²ß é{T«Ä¥i¦T_Ç1¥ï Øvô‚ôŒ‹ÈiÉÛ°êÓ]¤ÕU†ú¯ÕÄ‘{·úšîMêŠ/HlnÆÅÀ½P “úüóï{mÎGÖ™ÃXõÒ0Ä¥Ë-IݰY· Xµ×ËWùà ][ŸoMÖÞ±ŽÊÚ¥™ÉOLº’ºïô,Ê™|ÇÞ² CÇÆ*DZ7Å"SïøŸ#wr®°(Œ¾_‰îžšäEŒòþ²ß8Ò„è@ÈãOig¬žŒ1‹·!3—žÏB•ŽmŸ®BâIyÞÏs *ŽTæì HIJDÜ_¦bÂ[Û¤y§ÃjrÓ‘¸e·'ùÛ¶%ib,—*ä ñÓ…óÄSˆ–~c°pÝ^m®ïœ•Q:çÅÎg#mÉ>žˆ9ÏQÚÿƼ´{Oªß8EÕÇyws]c²ïÂÒ×& ºw麎¡ïÈYo-Åú-{éy]ºùjFò.ˆ{ÃáýC÷Õ®ä ºšm¢tïm^1×úþø4YÊ7¨MébOËÒ–´¤Ívã<ñè¥bëä‹€™ÌŸeg“ÉüÜ‹8wN©ë\~£Ý{"=;[]GÔµ£ _ÎËÍÇùó–o¬‹é{Hæg¶côítx*}ÇéŸñy8°n*^S‘ÓñHKk)Ï}O>£¬¡ä`Îó‹f–ïŸÛهɴهJ£‚1úE¥¤„ ©ÄˆnÄLÎRëÍÇÞ3´oÈ^ãúÚkéÕvöÇj›ÿMÃû¢@Ñ–hÌÇðÞN¥™ây{“öZývý° )ç­ßFéàÑÏ —¿ÅóÂíéZå‡×ÍÔ6N›b¢Éç”uÛ³ŽF }ïZ6:ÑÔ3»0±ß,­ÏÓ¦=d¥¦ú?•ì™;ë÷ëžUðÕ[Ó4«$!!ÍíMj­“#E¯i»£sou $â¥)ë‘©ŒA•ü^S­ÀÍ%w3"Ç( ¥`h¬ä#ã8YEÒß#´y=î…Ø&s%Ÿò­Ð t¯ …²úŒ‰©«Oÿízr<þŒ_AR\/ÂÚû“¯$J·ë6c1z7ÕË7)> £æüßßÿ<Ä^ÄsŸÇŽuÑ- {v*ÒuJ7Á¢*jaYdL·FWd9Îd*Ú0/Ç£G+þQr°g«l_UÔ5i2—¬´3‡çE1»ñÒŠƒT* S<ä ‰ÁxwþHÝ¡6Ï]ˆ}'Küö,™Œ‡—Ø“™‡íÄ6ù%êÒrÖ¼sO¿¾Q*œsä ¥=ý16âAº¹Q:Q¯¡±’{SÈß“@ÏÚͽIðFxXBæOëc#h³´ßR®zÇ*—ºP%ÀºN=±8LáríÔ •¼:âåU0HœoûO7âüÝc`¨’‘~Ð"T"Ú™¶`T‡N¼5ÞÞåjCTcËF ´¸aò×ÿÄ¢wÆ!ŠvåŽ3ÇLĢ͉˜94TshË6WOÍñÊŽ@«06ÒòžSš3zŸ€ê2Ù"‚«‹‹Uniî÷vÑX³`˜=‰dE¢ßl§©ô‹ ù™kŠJnIÚ%zéYbé¨â´fϸf‹MÛö‹ÝMÃÆ"Zw/ jÏÐAX´u Œ±9œ²×¯rÈAܳ¡R¯©ó¿uÞž!H_è¾t ¹d”N­×ÑÑÏìä8‹PÉ«7Þݰñëf£›r_Ç¿8ë;ûÞpÔN+? ŒsªüÀGÏZ„JtMߎ[‡ø±X´x¶èý@IDATF —Çf½R:tñð³ôJlH´úQ–'™¬Ò=ñåÂY{£ •‚ñÂâ¿9–Ú«óSZh´™ŠK EÇŒ´e/͵U¡’iàD¬Ü¸«—¿¢ÍßÅê9Û/]1çV®>űö‡ÍgàR¯8"xÛ¬]ÔöòÕhrÒK éªX¢[Ìl|³v|u‹ýZaŠ˜úÎÐ} æV*yb, 4&ôt܉ó±ò­A+±+ü5‰6†êüh˜@VÊ4Ð?R]Áu³0ÍÃ:¶U· Kü•l3d ·õ#{ŸáŽÙÛÓQ9ZCÚbù†Í!,U¡’gä8|I2|­„J‚7¹uè¢~1þû’,B%¯¼MëÒ¬ü.YÚ2d>V/°¬ÝåHkÚ¡R·˜Yø:a\þÇ-¼,1ûy±”çÖ–ÖÏciÍO])ÌQÖß¡ ™—›¹nmoda%bFé­‘±âRW›ãgІ½P)lø+ˆw¸ÉÕî)/j¯Ö¡ÆªUÓþwìØiŒ?GêhsÒÒ)cH»˜‡í¿\ÀÉ‹²-ˆ–=$LÂ^E‡3§OKUî©Çeý?{gUuöÿÍÂdO`BB!! †I” šHƒ(PbcË[xÝú*µjq-uiÑj©úÅ–VZªPDÄ‚JT‚ÔX„ 2…I2$ý?w;3w’ÉMYžÃ'Ü{Ï=Ës¾÷ÜeÎsÎóTŸÄéÓõhln¡GŽGC©&}ÝnZÖÐÌ—ªÒ¨¬óCX` šü¢0j”ð¡Õ"ëä»@QæqäâbûªmãÇ¢c=àŽü7ŽÒ»ÏsX´˜ÐZ¦!Canÿål«=˹V˜|[q®Õ„¡tvü^:ŽßfÜ -U¿M 5+¤¼» –S¨ij¥Ä¾ä!ááÁÞ=tŠo%\U5Ô&ÒCÑÿTV8µOÿùÐ5í×¢ƒQüé °‹œ¼öäqØü胆– …GÒ=ã¡Óë{Ì¡`£ù¼J“H0¡òÄiœkjDsC üâ“8œxx¾”û92Z3Û@SæÅÚ­®:!V=2ad—Šà<-¹‹ŠV|*)Źú\Râ{äÖw ÌCãéÏU:ý_×T‚Y¼èQcéE« ^æÕfá}&Ѓ´žÜ‡Ë0áŠQŽb’¯öÐv<(+•€àÊQ¯K½þN÷ÕpÙ<„¹ý—„ÒtSø`úޤÙÀze çÏcßÎÝȘ€d³V±EöÓÿøjÿôªE9V* ¥™£(Ÿ6x’C›Fß7˜Úäô#ÜsYÞ·_¿.ŽíŸ‡jM±xî_Fèx}/˜Â;\™-¥‘Á©ÿkâ½ÆW[®·™é6nsÒè½mvbæHßS÷ø9ÒS¯L_”«+Þ¯ü öŒ>kø /ÞOÝÜ&êsc” ÉÀQ‚¾?=Ëb2éâÕæ¿¢šaºé•‡œ•J­4y²–}é›_;©ò<öüCR* ¿–ý,•*v¼ÿ3où®Z½P4‡³yÃ^,JWLÊÍGÅw±,¶£»T§ó×<þ¥’€0|~Aæƒ=‘O&|‡õ 0ÍÕƒŽÃ…#` Ÿ¿ûwYž0<´RG©$œÕS*yì[ÎÍ£ùƒÞ…µ(úRš¡öÓ;”JBc~®!ÅÒG´¿}ÝG¸gÊŽß²],K]Y±lî*w,Ö(•AÈ:ϲÇ€ÿýž¼÷,ÅM^ø²rè¥LAˆ.ü“ß78 cÇ{«uÔ1À`>G }pžqîcÌm·3(< ôçï^çx×£Tßh—1m×4]wl"9S ô£ù:*¹‰Æ/Fy?†ÙÑòûBú ¢XŠòÇå#"Ú*2MB&Àz'ª/7’½uÁ/IÙ>‡±‡ðÑ.šY ‡Œå?G‚懢ß-ÛÖ“ØøË‡Åî0²{ùhIÂJòUª @?ú®ë˜=X5+ï0&À˜èzÃûµ7ÈØû·¹oh-Åòª#Ъ†Eã…iŽAª†ÃoZ'¶ù¦7¶ÑÊ#yr‰í(Þß%F#lÎ5p£ôÃ÷' > ÈHî{o£øÑÉ+Ìj7š²vµ,G÷ÃúBCöÎÓG…Øá㮤ÿI±DÃòï¦--Dsè©Z˱QöŠø9¸ÒmB±gÁ=ö-×,:f]“ˆÇÖãø¢\:SW£“Âg8®™†ŸGûßÇAëÈ”Ä]-KÅ>ÅçL%=@Â8îoA²á—gÓ ù;ÝõÉR,I*k©9Š 0&Àú ¢X2ù}CýXçØ@sS™@ï& ÜÏ‚íSWÇ÷aÈ}ò¸sFòEm¢2·R°ûQ¹³(abåïnCªÉùÙ91&À˜`®zÃûµ7ÈèÊ•™@o"PðâCâª"Á/Øó÷OoÓœÎùfMËj,ª/Ö!Qz¦å"qìe€è ›| –§…`4Ÿ”[ý¿Ó² ¢3Ç«åò¢" Ÿ8ÿž0Ť"ƒb …TdJŸC'`«± RfÌŸ„ðÖJ¼óê:|üåI4!1£ðÃo KÊÊ{ýö8õ-—$§÷}ŠOòëfNnb½2åža¥™Ã{_Š5xšªÝµ²ŒÒ5yå9‚&‘ÊýÜ¥½|Ș`ý—ÀQ,õ_œÜr&Ð7 ÄÎXŽ÷³nÁ‰c•dk· ÍÍh![­á1I¸ô²T„+þS.VóɱáCÿÆ-'PI¾Rêkèw] Zü‘xéX¤Š&¹œ^,Q¹^&À˜`½†@ox¿ö{ÍgA™€;Ö£ïàÿ^—¬\µü×È wÿ¦JœgžID#1j´c€¼át‰:ˆŸ5n„{áb )”ÄЈ:•M+2ŒæŠéZY¬(É—Úr&§gN°µJ šê¥¦ðÿ=—€)&Î W>„Ü••j•„&Ós›Ö!ãîUxañ8§vxê[J¢fr/*„º]ëðà.q—þ‹Åœå¿ÂÒù™3vÊ©àa7(=KÿØË’t˜hï¯3øp½¤TR²(Û®–%f¬ÐÖCâߎ/,›ãlúɲw›ìcI‘€·L€ 0&ÀÈr,C`L€ xC@°Óš,ü¹%Ö~üºì¾_²<2Yüë¾J¹&&À˜`}œ@ox¿öûx7áæõUgðú½OË›‹_ÌEû:ßþ4@~å”aî|5k,4»Ú„ƒcéPЮDQY&šI1e4ŸPpWÊ28—^Cm~ä ö‡ŸP¾k0ê€ôW™ÿjqùsÔaäš/ †#_Š AýYG}NP^³ôÜøƒ4Þ…G½Nô5T¸ên<›ø6–åhü”xê[BK¾3aä´ £d6¾¥´ ORIVbÓwcÓ¿nÃæ¿,tQ Æ•?ŠÅAq{öm<öz6ž_|•¼"°þþ—ª/¡ §ÐŲ Nͤ~ü¦(ó¦_<Šì÷þHf%çô G?Ä}¿xÛ©z>`L€ 0& `Å÷&À˜`L€ 0&À˜`LÀ‰@Ù¿žÇåRTîK iàÙ¸ÂÄßWè¡éLZçà0÷4Fó©…êìx]æÊ>”^m„Ö&R#È!j¾òI9ÏÛ‹O@6·H^‹(„áÖ7ÞÄMŠO°QÉx+%óæ>-*—6=·Ksº¯4Òk™­›¸t&*çÈŒbå¾øã=+°‡V$aÿˤ8ºŒVA9û&Ê\ò®zýÑÔdáªe˜ôaæ³ýÿÚ&®dRŠëÐÖ€,¯Ċå䓸‰|ªêKürú÷qÕœ¹«Ùí»Ú¹:$'fL€ 0¾Dà{}©1Ü&À˜`L€ 0&À˜`L “j¿Ào•}«Æ/Ä‚,³hÀácН"OÅ\†1ª­9£ù<•-Ä,S±›¶¿§[ÛV¬%OHõN Ñ–˜|î‚‘¦Zà›~7~–îTŸ)a–ÍÖ3Q(ß6i·Ãÿ“r'6}~ÿö³j}…[¾$³‰œ‹2ÆÊ]¯bNš½?›^—”JÉ‹Àý‹È™š•Žn½”%yþJ¼üø\µô=›Þ–•J—ážg}‰ '›Ô¼Ã˜`ý€ï7ûjËÒû;n?`L€ 0&À˜`L€ 0þFà“—/šwÚ}ë?5dÞ-hDª8¨.š‰«¨×EXNQ8‘Ty5‰Ñ|ºÈ‘ÆÊ Bú2…·WX±qglì¬\úÎZ‹\GSsK["ð¹ž@Àä0h8$y„lvN#)aB”c êä>©Ätt; ü2\KJ£Òý”³üs³-DªÉ¥”ðÑX¶~7~vtÊ¿©#?Á~ˆ~)’‡ûâëS”±lrî{.¥´{è,©?Z†O&/ÀWûÊPG>‹ý£qiú(øX‡çä’ãBÛ­‹0&À˜@ÿ ð½¦mF]Í·ý£µÜJ&À˜`L€ 0&À˜`LÀ#ïN~ˆ§ÿF~_„v~<&XÚïèÿÁƒ‘6HÊTú©Îj œAÁ¿äzC¬RÑ|mÉg°ÌAqIr©‡pàˆÕ­†ºCE²/`üh?·”Ñ#ø@Y{Wº·6×D$¤¨rÍt·ÎØÁfh5S hÔº”=r,®Ì™ˆ‰YW’R)ßYþƒ”K‰búC$t“,‚£0–d˜H²\™ž,®Â+|w›,m,~˜•à"92&À˜@% šÂ³·³¤»¿Âáv3&À˜`L€ 0&À˜è3åM Úû—5¢!É5?Ò ónÃ0õZñ#„ýÇ''GÕm‡v`ƒà†BÆÍ×!Zõád4ŸT–þÿÆÊŒ¾r–jÊì›÷º})daö„h—ó|xÑxêç¾ÉøÉ¢XI¬½k±ë¤«„uØ»]ö)Ÿ†®«‹\“·wÜZ#Âj%!Äg!^1­(Å´ùÿ§¯½ Þ‡óì0‰×f¦¶N”EP4?¯(š',@†³õÀ¶jäsL€ 0&ÐÇ ˆŠ¥ [Iíã×™›Ç˜`L€ 0&À˜`ýˆ€Ì´ÕÖÖ¡ÁZ'䆟°à´Õ*Æ×Öžw§ÑZŽw•Ad«äAx÷”jLëÉÏðìƒOà·>‹ÏNÚÕxaçÒ/†ä±¦¿ýßçQFæä„ð]í><|ßÄ}`þPV@É1Fóu¹,Ác±ä§ƒºMãÙ岄À¾¿>„çd]SìÒ\$wÒT™Z0ïtˆ@GûyÆÜrùÔ'ööY”>{Ÿ­^Ž7Ê¥Ó×Üæ¬Tm«oçQy¨µ­J¶ãx㎟a»\[Øe‰ל£mg°ïóRÔÚ„Øüõ><¨Ü‡“ÀG:k¸.„,–CûPL¦øZ5«¸¾ùwMX]•wÿýפ*€å†ñ† 0&Àú-q1íwŠ1ã~‹Î˜`L€ 0&À˜`L ¯hÀßÌÀ+å.í9û6þçê·åÈX¼ôé?0Vã7¨µâ+|¤d‰Ÿ‚/V'œ?ý6½'™Ê Ÿ{ ®*©’„b˜'bÍ33ûK:_Nu_ù’Ó¢pzÿ!u5FîŸFf¸³ÿ£ù.„,WÞû;ÌÙþ3l¢ÕU›~ù3|˜6 C¬§PZ^'‘Š¿Ï/ͤ}ç6H'ùÿ K ãýÜwø,¼|ßǸme>pöCÜ>åCdLÊBþ|”Ê+è0á.,›!(×´­¾ë~üò†»ELlÚeNöööìúRÓô,¬¼²›O§†¯ßÆí·®Ó…ÅB*-iú†òU*9ÓâŸÏÌvSæt½,uØ´ôñ†Øþ0$OC&+°g¯* r_z³FT$ã-`L€ 0ˆ+–˜`L€ 0&À˜`L€ 0&Ðwø+®b<6)¾.~[Î75¨©“§M@¸f`]=á²ã¢Æ s)ÎÄNYŽ¿ÅO! Ìu´Ø'þÒÑ0;[øÒ½¼Fóé&G*ó;;ªJ ²%õÀàx¤ŽÜV5|®“.t?ÿŽúäW+áŠÖºV J‰Øpc«rlÖ38yâ4Î55¢¹¡þaшIN}ܧm ¶TUWãìÙz467’)º0Ä'Btx;ùÚ(Õ¨, µ§púôYœ«kDcK Í Hí¶Òªªù”ºŸ‰³0&`€r?GFÇ,áÂd«®’l"LÙ¥¸O'êÒâ¹0&À˜`L€ 0&À˜`L ¿ð ŽÂØñ_õ`4_[¼ •9ÀÑ£ÆÒê$}…Àƒ}R¯ý¦àÁHe@Ñh BôpáO¯TcqFe Bý9÷SÎçùˆ 0&Àú+6…×_¯<·› 0&À˜`L€ 0&À˜`L€ 0&À˜`$ÀŠ¥ãäL€ 0&À˜`L€ 0&À˜`L€ 0&À˜è¯DSxÚ…­Š-ÀÞ¤¯´£«®óè*’\è¿ø9Ò¯=·œ t~ŽtI.‡ 0& àç*÷„þ@€ûy¸ÊÜFîçܘèmÄK¾¡~½Mn–— 0&À˜`L€ 0&À˜`L€ 0&À˜`L › øŽzx!¾-©P«§î÷ÆêêӢؑ‘Cz£ø].3óèr¤\ èwø9Òï.97˜ t9~Žt9R. 0~N€Ÿ«ý¼ô“æs?ï'ºŸ7“ûy?ïÜü>E@¹ŸûT£Úh ûXjŸbL€ 0&À˜`L€ 0&À˜`L€ 0&À˜p`Å’ƒï1&À˜`L€ 0&À˜`L€ 0&À˜`L€ ´A€KmÀáSL€ 0&À˜`L€ 0&À˜`L€ 0&À˜`¬Xr°à=&À˜`L€ 0&À˜`L€ 0&À˜`L€ 06ø¶qŽO1&À˜`L€ 0&À˜`½Œ€ÝV‡£%ûñuI*[Pßd£˜0bìxLœt%bB}Úh‘E;þ]{Ἐʄ䫧aú¤K¨„mä£SöfÔTW¡âÈ!ü÷³Ãó³Å¸"Ú_?OKJ‹HÆÃŠŒÀÀú 3ctF6&dÆ·_Ÿ~Éc­' ñîæ]8vVàAuEÂu3§#%š*Ö 6 ì/G«¯þÐIk«/F¤§Áì§—¹#qvÔWÅW_• ¬ô8Μ­ÙŒŽGæ•qeÚ0´uÅ€N\³ŽˆÙÃÒr?׿ }·ŸS{;òŒÑÇñL€ 0&ÐEô¿Žº¨p.† 0&À˜¸øúûò å‹ú­ç›[¿í·ç†3&À.– ¼rß*Ñ©»zG% vlBÎ’03Í잢å86=úòÏ9Ÿª~ëU䚃ûœ³Ž†Ã^³o¾¹E-NcššéX_±d«Üƒ—ߨé”^:¨Ä‘¢Bl}; ËVÌE´N}:™Úª*Ø€gß(pNwÊ‚µEùyØN`®ŒŽbrî~ 3“ƒö*v½‚?½uØ='ÉWYT€ÍñÄþÿôÙÃà5s¯¬—Åp?×½`}µŸyÆèâH&À˜è2¬Xê2”\`L€ 0&À˜`L€ 0‹LÀ~õ¢Èœ1é) hÇ‘=ïcó.Iy‘·æU$=ýR‚´²ZñÁ*‡R)}ÞBLKÆñ‚-X¿¥8•‡ß­„·g¹­$j©-sS*iKÖÝ÷‘†#Ò§NÃ¥£e@SÕ×xÿoïàˆ Ø:—ÍŸMÀÒìaºÙ;i-ÛéP*…d`áÓÕZ‰wV¯G1Õ•·æi„<¸91.+—d¥ºâ\k墯8sNÙö‘½©VL4:×\‘„ØpØ-GðþšM’‚°<¯½›Œ_ÍNq)Èø5s)¨÷r?w»f}·Ÿ†ž1n„8‚ 0&Àº’+–º’&—Ř`L€ 0&À˜`Làb0 Åœ%K5:Z‹wÑó–bøàÕòÊ vGŠFiS_ò¶—K‚'λ &ʼnæ©‹غ/o#¥ÔÁMÈ+»×%8+`ü§a漡HHKAHͧxr•ÞJ$g(¦¸kðÄó“áï£1¯gŽÆÒåQøý¯¢š’Ÿ¯V“ëe¥’’/ùÚYH•ö|ò5ìÊ y뚀œI™ˆ3#` ·óW}œ•JJ™A#0.^9èü¶¹j?òdÓ~é fËJ%¹Ü dÌΕ[vêc¨ñl½ÕÛV‘Øì¬TR ñKÀu3”+V'ð»fJ½wËý\{íún?—Ziì£%ÄûL€ 0&ÐÕX±ÔÕD¹<&À˜`L€ 0&À˜`=€½î4*õäj©Â‹¤AÙiˆtMã‰1éRdÃ矡¢Å5A×Á'åry¾w°TUò•\X FŠpÔœx‰׈O Ž»W"|4+…”¸ ¿mFõqÝ+F¶ÁzÐ5»ð :T÷ó>ÔÏ;tå91`L€ t'V,u'm®‹ 0&À˜`L€ 0&À˜ÀE"Pñå—j͉Iõ‘µ^öËD„…Á]ãèIr^Ü–,©¥vnÇj)ÁßW­CƒXLfO”Ìñ/ÕŽsg$ÿEÀ ÐiÙàáHT*huZ¤ÄÒÖ†ƒ_îGIi, ]ažOSt[»¶ãªÂQ)ª5Å×C®Y[â_¬sÜÏûP?¿XˆëeL€ 0v ø¶›‚0&À˜`L€ 0&À˜`½š@sÕ^¼´…ü$‰!c‡«í±ÕVŠ>„ˆ­ÂIM!ìBI 64 º­’C>Óá ­ºÙúæ6ªŸ3Ũ<%—•…»î™‹¸N×фʃ©PRÌDê•g·ã¼\íùFeOް·Ê;ì|c¼DŽÎÁœ¦ ÙììkJMÐ%;ÍøÏzÉ¿’P\âÕ©p\1ºëšuIÛ.\!ÜÏûV?¿p=…KfL€ 0ÎàK%Èù™`L€ 0&À˜`L€ ô`öšýøOl”% Äüå œ•6>š9§š]m“üCÍò¡e§¬ÚSØoBñçÅ(¢?U©$”ÖØˆsu]QGFŒ•}øÂß¹ËêçÁrlõÁrhkõ Ej|ÒÇg 1^i?P}0/?þ0Þ/­s/¯Kbì8°å%l”Íb|.»ø½ÂE»f]ÒÀ R÷sÂÚ×úùé)\(`L€ tßš³Ê œ®(ŽË`L€ 0&À˜`L€ 0&Àz [Å^<½r£l^˜yï¯pE´¿Gñ|}ÜÍh ‰›ë*— ý4 õtÂ/K}ÍhEcM~ñvî¦UUç ±î©Bd-YŽ9i1ö*¼ÿרö÷…'—G-Íð‹¼s¦§ÁŸJ>UZé©v)þÛf‡2iPˆ¬| žó‰Hâeij~{ƒ…oÁ†mÅbÜÎUobÔÊ¥HЬ„²nÇ;{ÐÐQÎByéõs‘nÖ»VüçÏ¿ÇÆÏ¥zÓgáÑŸgR[<‡n½fžÅ¸¨g¸Ÿ÷ý~~Q;WΘ`n|φºÅs`L€ 0&À˜`L€ 0&Ћ Xö¿ƒß­É“[‹ÞîA™áPÓœ/T•džkŠÄEÅ¥PD-· Ö>ÀQ–NæØäádáOR*霆Oã¦/FPËóX»CÈ?ŒC'­HHp©;W‘â"Y)¤Wˆ”3ÓýZØ-ØúüÓÈ+—ÅN]ˆÿ-(ÈôÂźfz²\Ü8îçÄ¿Ïöó‹Û·¸v&À˜ðLÀw€çI4žsñ&À˜@_ `¯ÃÏöÃÒB¿ÓÇ#!Bÿ'[_h*· 0&À˜p°VìÇGÏÀ78ã3< Ú:Òó謥;J¥LÜõH®³ù;M£LCâ ŒT%gª›4g»M‚'$!ØÐj§C¯!ÆvÕ¦˜ ¸iƼ´M¦g€èP¹tS,nºc!i]‘¢kr«·•¬²EËþˆL-;(”U…sôݯ*©”ŒM ¨—÷Ï‹ SNxގ̼ K@Ù1š¬«Q, ÍZ„…#ÈRçÁÁuSÔpE ÔS‡4J¥ôwcÁ„8å¤Û¶']37áº1‚û¹»ïöónìJ\`L€ t€oàˆ047*N8;˜»/&·Yp`9Z=|¶¶úbDzÌž>¢íV¨þŸ|t€>[@šïmFì°áH3)qšeü-u(-Ú¯—¡ò¸õôý>¾-†™1:#2ãÛœ-Õñs›˜@·h9w7lç KgÅR·Âçʘ`L€ \<Õ¶bë6 2é¬Xºx‚k¾pJ±vÕv¹üTÜÞ†RILd A\©qÎÑ_ñئ»þ­ÃáÏèžBH"ÌÓoRd×þ?0@©À‚ªÚ&Œ U”04€žâ0MçM­!‘Ñ”LRRUœlBr‚R–”Ûz¢Lü= %—";ð}“ es“9cî˜'ÚÙ+}ïul/—%λ£M¥’˜ª‡]³všwaNs?W¹öÙ~®¶wÍ 5¨úæJü¥-c±8׳™LKÙ~;Ó ÝáMRÀûNĘÍ¥PA'Æ) Õ'Ô)+Švü»öÂyñ؄䫧aú¤KÚµUá?íž/Êù&LÂäd Ôã쪠#c·Br[Ž–Ðøm‰2~+Œ£›È‡ßxLœt%bÚ¬Œ¦5”ìEÞ‡{pì¬4þ>0z&];éqabk=ý×\_=»>Fá¾Jµ}1Tç÷'G\¨ç‰ÑÝ]ŸVþúŠ”ž&{¯¾ƒ1&Ãõ[‚RÒ5+ÚOïdÝŽé(I˜#2,íRD›ä Ù‰¾©–joFMu*ŽÂ?;Œ1?[ìÙ4pWÔ§VÜww|ÍQ[ÑwØÑ–ÙN`Ý;ÛÌ–s÷c˜™ìXê®$¶×”àϼ ÉÚ²K“«P}ªGŠ ‘÷I}ršÙû5&'dh²4£èCÅT`*&\ÒVËÙ,eGÔƒÔ¤Aê¾Ñæ»ñ²¸B‹[Ÿ['%xQT×]3/*ëI¸Ÿk/JßíçÚVJûƸ—Ù³cšQ²ãmlù¨ÕòsX”7*޼ÈÁêë&|ñÊ:ìÔ¦wm$M®ÑŽQ §S«O©å86=úò]d­~ëU䚃ûœ³ãu¤¶ÂZ¶Ïüa“›iÔê-ë‘¿e?nz‚ÔäêNGÇnÑRWî[ÇS_- Õ´rµ`Ç&ä,y3ÓôfX±›|æmV|æ)YOY°¾(_åÒ$‚lýç½¥LÙ®UÞOJF¿¢:‹¨Î)w?Œë’]SÝ]ŸC.q¯~?V¯\'OÖ0ã¶• Y™'"'µ,Äzݱp—²èP;þn¼o’b°f?Þ|s+ŠÊdäªbš<ßAÆê#…Z? ¾Áý¬Åí5—š!A4kKèA7$DG+L3e^ ¥}†‹!}öL¹,ßž«ÁÉG°ï£(pþá*ו>u.•ˆ(sšª¾Æû{G„ê¹|lþl–f“Kå `L€ 0&À˜`L€ 0ÏšOìÁÆ"ÍùÚ£(©u^Uc§©À!ÃáPÚ$dOAжu4H׈ /þ Ãî§IŽ‚¥Ž†2üõ©wäc1y¼ÎïSšlµÑ?¬gÃr@}]šmv4Sõþ¦ øû P³Vâ‹ÓA›6&å76ÍZo=6T’E#Ä“µ%I{[S®›dÆÚ]4ì^M)ј“!¬b"3v»uEΘˆ—ºš,8ÛlBt„cb©¥d'^Þ L' Äp³ã\{¢èŸoÂç›7©§EEi Î;]²VØiJ\bг¨N]3µÆÞ¹ÃýÜåºõá~.¶ÔÀ3Æ…P/>lÆ1W¥’Ü_|G{Žçª¶‘¦Át$Œ-R qü=G~àR"Ü•R§4T¬ø`•C©”>o!¦¥GãxÁ¬ßBÏÙSydÒuVÜžå¼r©¾/©J¥XÌ\2cÈÎéѼظK™-ÄKOâ×OÎužadìÖ~^6—ˆÌ´Ê(%áí8²ç}lÞ%M‚È[ó*’ž~).Ь’-/¨J¥ÈìYÈ4¾µ_cã‹›Äñ㢠/Â/h9~’á2©4/(J¥T\ÃD$ ˆ“ò±aKxMw®z —>¿1¥[w×' ¢þW‡÷W)J%!ÒDcà:ÁiÜ]ç¼§¨NôÍ–Ú27¥’§jÔxCõi.†ZPßÞñÕjúûvS;ÚºXÒ¬þŸ›fU¿;ŠÞú‹ªTÊY²œ4ÕòC‘Æ$$c\ö4ØéÃPÛÅLq×à‰ç';}\ƒ–.]…ß?ðª¨á=_/hO90&À˜`L€ 0&À˜hŸÀ·­äHH 4€µF=ÒîM]‚Çf';¢BÓpçÍ™4Cš­NåãÙ{ ?5å•êŒðœ%7!ÙeàL(ÀVñ!ÿƒ»åüµÏ _®!rÆøÕtÇÌìêÛE“”[é|PT,FD›p¬è°Z—mÚ½3ugªËEz½I¹~!²¾ YhU©(>MgQyŠW…•ƒ[§kXH±8þñ«äëÉBæÿÌH9„ìãÈ)ù$mRs— ]³²Ëq¦c{6­[«ÝñÒn½ü4Fñç1ŠN\3½zS÷s÷«Õgû95ÕÈ3ÆPo À¨ÍBDXRãC°û™'°Sój¯U®ÏÞ¶ÒwÅ8eGê«/ùHc”üÊM’üÊ™§.F`ëjZÉIŠ›ƒ›Wv9®S͘Úq`ÛßÔU1 ~s—ú6Ïû?D†¾†—¥MÖÿwá5¥±±[˜†bÎ’%ˆìd^/zÞR ¼zKP.Y°«ð8R´ j ±a½?(DNZˆ_ÍK÷AîR~±2«ï{Q\U°ö#\û'g˜`¢U°€%„…,ÆyÕOLLFD´âwoÒš…ð-m”æî®ONs®ÞôKSÜ<ñ‡ïkr:výýšðÁoW`»Ø¿S1vx°z²3}ÓopfΊ„´„Ô|Š'W¹¯¨É;Æê&ëÈÚ\×ûè±®ò°¶µÃÍòŽí(v)ËÇ/p(•\jôQnv5Þ‡”Jêc'hÆÅC}¸:Nð¸ÈZjPúõÔ4Øáã„ÈxšåH+í¬5ÐDD˜Â#ØÏ}¶Ls}Ž­D½<í.hP,“cœgœ¸5­UGqüt¨”Õ›˜ˆͬJ·,Qs¢G¿9K3ú|È_Ù\"Ìêki€¥ŽlÙú˜`ÖÌ6ÔËïW_U†Òc§©< Ã<&.3]óx>¶“|¨8qFœè3|°……"bp$̪Ýx%wGÚoG}M8T¹õU¥$·Ä!tH<Ù’7«ßÍõÇQzè$HÛí4cÒœg>*ð– 0&À˜€BÀèû•¿$‚vò‰PA>ÎÖ‘çúQ` CHh†D™¡˜ŽWX“…|ñ7€ƒï9x÷±:БEÞ3gäbÙÍAxVœ)݈ÊrYñB&õ¦Ýq&Ó wÝà# ¦´Bœü†DÆSiЭÌÇkJ£2°`ñõHq *µ]z;g}h•Òã÷ÀfÆç•Ó",²,(}~±hŠó¬v¹¸²ÙÌs2o/É*ž IÂõ‹~Œìd=ÓGíÈ¢sÚ·}|”+Š%¾f:rô®(îçn׫÷sxƸñéµ>H˜I-ß“WÏ GcÝŸôŽsî{§ô¾>2ñ÷iž,B®—•JŠLÉ×ÎBê¶çDw#{>ùSÈŒ©ô´¢ì°ôn š4SU*)ù~0é¤Xî|°?Êø¾4ödxì6ÉiÉJñNÛ¸ìëKŠ%a”ëÂë©odå?œšæ”´Âðúxv½  ÊÇ+¦crœãÂ~«öw3]u¡C¤·Â÷b«¦Ôî®OS5¬e´’W6çª÷´ïïGJ1`-y_V*LýÝ€8'3zÆû¦Ohrd³¶FoGû×§Ó´>å-Í>  ­†ù¸Ü¼žÒVí"Âùœ«’<%ó>¾þ>)—“ûê|9z_§d]F †L>üñÅíê¬ ¥àÄñ±8òy¥x¨µ*¯Ãî ¯cóné¼’GÚÆbþ½‹pE‚«MX2™A¶r_§eͺ¹&ÍÇ¢yW!–Ý‚^_…íEÊ_¹¶¨$$ž:,ÙÃÕ±!ì,“æÈ^ƒ¼¿>‡­ŠÒX=eÆõ÷݉츎ýȵVìÅúÕ%3—jYòŽ‹\n¿­«yQœ±3íÞåVòw¬föhÃè9xâölÛñ^fïhCH&îy<×Íô‡6 ï3&À˜@?%`øýÊßR©ÃÞz“̲¸¼—åîäúíÄßýô>ëâf›âr°òO9†KΘ…§W^MÊÐZ òAM›ŽŠCh¿ÔiÎÌÅÓé3É\žçÎ5×F#h[ˆ9ÒÉôœá†¸fô†™Ë~‡lšèeiõÇÀóô»!dâ¢Ý(Yc&.ÆÃégQ[Û„ód>ÐN†}B#‘û0uÒ–’Öø69·?ãW 0rÍŒËÛ3résZÉ03R'÷s…zçú¹öJÍý~Û㊧ô¶¾–*üWÐþPÊNC¤´ëøß'cÒbJÓðùg¨¸1 Â{ÈvV]9*¼ŸÜå»t| Š„±œò/ñ-G\éÙåc·T±½î´î¸• Sµê‹Ïâ¤RäLLA™ìš°ÿ@)–$Õ¡pþ{P–±Z°åÝB,™.OÌnFᮥ"¢b0Hó^îîú$!è[Öÿa»tHãN÷_üî)‡yW5]{;öã´ÂZV4ŽÏÅ”d/ÇÜ:Ò7Û“Á›óÝ]Ÿ72]Ä4¾±î^µ ¿ÜFZM`މ†9H_›*4¢©^™¹”„±#ƒa)Ù‹>=€šæf ôFÌèLd_y ‚5ö¤=5Þj)Á»«×Ƀ÷I˜=QZê)=Ç3î P_ºO¾èX*;> ‰þµ(ØM¦ d¥’ ‡ŸÓÅŠ¼gW`k¹"a,²f¤ÐÛµùbžJlüà Ը8f:¬P^J”52= édƽd[¾øÂ®Üµ+ÊÏááe“5Ê%²åúÔÓše·T×Ô8Ô–¢¸\V* b öÖA7Ùù}þ uÕ`dz&Í‚iÄÎ]‚BÆ‚Í+_À`û¹BzAhÓãš6ÜgÒlœ–š ."Ó"Çá†ÚOúçPª¸šþ¶ÿá U„ šÝ@N!Å@ËǗߥy¹ 6–Ïч–ÎЀW~AÌ80&À˜p0ú~åo‰!}OзÐörQá›"9¸‡‰&¸ü4ƒ/ü ààÄ{Ÿ€) ÉV'u¡x>~Áˆ E]³ðÇ É|“ »:I73ùŒ ˆ¦?ݳ=*²»®Yjt'…é.fÜÏ;y¡8{§Ô+Æ’F†š1,ÆìîW©Ò;:Néu}ÖzÙwÈÌŸž²ÞÑ#’2‘JÚ ÒâÐF£HÄŽÔ±ÍJjÿˆ¡1tVšÔ£ Su娭P·*¾üRÚ¡ÿ“ÜTcò¹X„ê )û…aíѵÇNpüåHGž¸êªrÇz<\ú îZ|5j>yåÉÏ×ÿüjè«^º³¾&ä½&™ô’pû­Ùˆ8é;t´¨ý½Òwÿ"®NÆËn›—éÕäŽöÍö¥h;Ew××¶4=ã¬rõ iz‚öVY v¾±N•(rtæÜ0ÉdöË51 9ê0^{þiZV¯(š¤èâ¢BìÜŠ›sùÆsYDú­onC-%=SQL?0墢²p×=s]–ýÉçxú•­ÒØv÷rL–dΜgAÞ›¯Òªç>/ˆW³ÿߥRú,<|Ë÷eEÐ4L¸ÏÈŽw®zãþ” é·d v¼"ÏtÌmܽŒê [{ÝôÉØýçg%LJåÛñ^aÙÊ•s¾çP*ž†_ß®˜²˜KŠÞ<¼öâ;’ý]eÒG;üêIve(sÁ=øÉÉAñ5WíÅ“Om$ůï\†xÏEZ°C£TŠÌžÛs'8>È ©­ExŠ+°Œµß½îT,\~9¯ FsÉü„ ³̘y÷-ÈÌvãÊÕ¬?d*÷•Á6•Mâ)”x˘`ôV2ø~åo©÷ÔnU¿'@_:óiÅóšÏÍäTÅGµgÃß|Ï1&À˜`]G Uÿh(Ú‰uòÊ á{$+w¦g'Éc:õ§ìh}¶ÚJÙOâQ)C %1ØÐ(¸ †_MƒT’+›ÊO¾Dýôxͤc!qö}$)•„#%tjìV)D³ÆZ^Ú¢ÔãìHH68!‘þ¯ÿ בilK8'„ú¯ t•JâIZa»à‰[pbù«£ò<üéy5%˜ÿà \ã<>ÝÝõ ržØý&¶%&Óu ÄeÊ“b½ûßN,_–ýQ¥æÎ×õå(–d°oz'…Nªî®OG„žõ½ÎØLþ9Î6œGU]“¡?!¯PFO ~á±ä / éã3ï˜6U}0/?þ0Þ/­s· eû„ Íþ§ *•Èôü;îÆ=.Á”t)žobíÊm4lìšPü9Ùþ¤?U©$$ilÄ92 À \lÍw'Ý¢*•D¹üÌÈùÙOh>kh¾÷óåÈXÜ|cŽÓ‹>8!‹g'Éç PT!}ñ4W|!:ÔNDNýU©$% Cö‹ ¼š…PðA!ÍYùŽö¨® Ä8á#éæ›¥’eNÉAîlw å :›&|©È’ƒé„™.Rð™€YéÒ~å_Û;´¹¢På‡,ܪU* EÑ,H“ì\ÁXû%yÿgகäÜ‘”JBð$GÈêI3r½WR* qäÏmt¼|²©…–g Ê-L€ 0&ÀF߯ü õ-? kÉÿ:)•„4þ¤TR¦œñ7€DÿgL€ 0&Àº‚­öGãšéHOOÒ˜™³ Ã<üì´ZHOÑ FÆ) Ôç£Yë ÙÕJäO«¬¤`AÙ)e& —\)ÇŸËÇßv|-ùÄ6¡è­×‘GJ'çÐÙ±[çÒì5ûñÿh¯1ù·…¡Ã“UîùkÞDIcüÛVUˆ××(cfÎe+GÍͤLS\¶5§ÏºÄ›n®¯ùÄn<·A°êCkŒf,Áu:¦ëZݤԋ¨ÃÎW–Y˜•-MìÖK)ü>éÞ1ôî®O¿Õ=9ÖíëÈV[+Žœ¶â¬¨6ö.6Õ @$ Æ ²ÛÜS‚OD-KSű7XPøñlØ&Ý,;W½‰Q+—"AY¤D)¥EºÝƒFÏÂ/oÏQW#ÄÜòÌþ-6KÏå‘C¶)NÙà‡¥> º\k¬©ÂÁ/>ÃÎ݇)m!Ö=UH?B—cNZ/Xw¯ã¾F ¡þŒÚ¤ôËu4ßîÎm8§d‹JC|ðÁ⬴r‰ X¢¾NáäiRØ’£B[½cIQú¥CÅsNÿùE‹Š#åK+kííÓ€³j]™ˆÕ[ ­®*t*ÍÃÍQݳomñ£)--»®<*g ðά^C}½ZOúÜï·ivÃXûÕâÅœ»¯wþ ñ„‘ñ¤Ú.^ö?Á8³v ¶ãÃFÈì+~X:_'!ž`L€ ôGF߯ü õÍ÷21Ñe–ªkâoW"|̘`L€ 'àƒ1Ó`ŒZ€–²/ñÎ+P,(]È Ìßv$béÔ5…ºchœ²õQž>úãÂÍõŠ2‰\âiÆŽ“§ÿ©;V‰¦ÓŽlyìKEVr *>+W2©mÑìtjìVSŽüg?½Òaf潿ÂÑÚq9qP ä¦ÊÊ—ÃXûÈýHÍÎB µä¡­`·àÉÇ7H–ghñÂÌ«ÃðÑ[yª%škŸCÙì%tý’Åtg}-ÇñŃ/™.ŒïIÁÏ×a¯PcñY9í¶­ÚûŽj(çŽÉ4]¼`¨o¶Q^{§º»¾öäéç;·b©õ[Q©tªÎ#‚Bª™ÊèÉÁ'ÈŒqÓãæ©Ê€úa:éx°ˆKUÎbÖ ®6.ý‘1k69d“Âþ¯«\šëƒP³fs4â’3p]îR¬xp¾š>Í»¨rûuÉχLà¨ý¦B®ÀŒèp祶k¶Õ∈É^Œ»d©§ŠwçËJ¥$\ó|Õ"Ïy5…°cÅ®7d¥Rqû/ gÒ,<¶òÌïP»Ù²[Kœ­juW}äû¼H‘ùàüóÕ5XýÒjú{ /¼ðŽ|¦/ýîyüñ¥·qBž«­dQ·äžáïë ¥Ã¨)˜”âl.PM§îtEßT ób§»ëóB¤–Ä·‡ÉÓcÅ™y°CÒ(—£%‡šÇ@_eùR "Ãܵì>š‡ŒôDk³&2·uÓŒ=xi›P_%Îs”èÐ6³ðI&pá¨O Z!ÔDFm#4/s±V÷>¯¦ÁÚ .KvKÕÜåå©l+¡ak4ªn¹p¾Å³ÅÖ†³úui&LhEÓß§*+°bée? ¦V×4Ä+§—>êóA¿:mlgÛ/•Åšh-SÞgL€ 0Î0ú~íïß!Ïß¡Åi™`L€ 0C‚F"#žFË)÷©Ã8Ý2qýŽÇ" S¶QŸiHœ¨äF>•ÉÆ®46 é…`C«0Ô¡•5(s–=ƒIUe8e¡± __D˜G Æìƒ~»QÌ%¸K‘ótvìÖZº¿[“'•’‰»Éu¶#×躉›0¿O¿åå§ÐHcK>AˆOˆÁ÷*>Àf9qŒViV_Ž/Ê¥YKæ9,f™ÈÅÏ@\Üz¼ô–¤Œ)>t3]”1ÝQŸ½U;.gAQ‘ŵÙÒñ©Jrûr ö¹Î×NN}`û[¢*ápÚÏÖ¿äÓ^m ÷M¯JwOÔÝõ¹KгbÔ!c#bùû~‚9;£AÈ+”ÑÛB}“óÀ­¯Êà0ÊhåEœ‹5ap\ð´Dú!„†zÇk`€¢¬² ª¶ cB]ó{5–··ˆŒO!Ñ…W=Puš^.ý»¹ºÌÝá 9SL‰¢\§„LçÈÔ#ù ÐÛ‡£Æä„Aâ™AIŽºjôrYqlŸü ID”I0±§©ëà)ñ>s®‹léÖÔÜÎ.™ÛKŽÇY†@IDATŽ”Sº8\š‘îäªÜn§‡$%QœTÿþUd Sg©¹œËXûÝWƒ¹ ÁL€ 0&À:J@û.ïÈûU›¯?˜"‘¦| •ïÇ7¶)HV>ïu®è@á(&À˜`L ‹ hÇ3m8窱i£6cã”mÔg A\‘šÊbZ=5=žœhÇ7êpø3ÇøÙÃwTDt"¢5‚×ïÇ'ÂX…ÈI™ä>AÚïÔØ-­¬Y»j»T°ŠÈK¥’œLHH‰PÅmÉçò±™£ ÐŽ•é!'Lš†tR, +†ª÷uv²êŽE©àB×yÙ<ÌT7 †¤Ü³ü/6Ëîd2çå")8CýÜÝc ¦wÉ×7~²ã<\`¥QmlõÍ6 lçTw×׎8õt§´:Á&_ÑGRzl8Œü þ•„2zC°”QÅLM’Á•ˆ˜Œ,Õ!ÛG­D«[+™·ª–bbœóª‰œv´á±9„•JNxø [ ™FÅ€[ÁÚwQ&hHåPSš‡'ŸR–¹*±Â6”M §òQlÑ~LHÑ_’/' Õ¬8õ ¯ 9äí)Ñ8`”#-%Ø# vüÑAuÅ ª[!äcónÅt¶X÷ç§°ù xÒËÿüaŽ”Ë#G{J5 n£{‹555⟵ÅÑ^¿ðp•_å¶¡¤Þs!ÆÚï¹<>Ø`LÀ8£ï×þö `‡U~ÿ×ÔX5ß.Á9.VÆ_‰Mÿ.ióRð7@›xø$`L€ 0&àJÀÈP¡½UårAQ)òd]ׂõŽ ŽS¶YŸåo¥òq ÆÙUJó‰BäÉn¯½¼MÕZ‰ìتú"ÊΩž2>vÛŒÿ¼¹FžnˆùËor¬"RKïà)U¶(J•Ñ×`¤2è&ãXÆŽŠoêt nUã‚’bÉA‹¡‹ë ŽNÆ21.Óå/#W¦'Ê%᪉Âùûh†Òé’·«×)='ÃE©èE›Ô$ë›ZEˆ¯Ž•$µX;«Ïc1}äD§´:þ¤š¤qžÖ˜47Xp¶Ù„èˆ`µ9–’xyC±|ˆáfÇ912(“Ó ¤.nؽ뇇áÆì±{6×”`ýªrÞL¤Ç9nykE!¾8„±i#aRÖXXQôÞzÍ@x´ºlSˆw˜@7ð‰HÅ êß…é(ÄKBêøQ45âŠË=HâƒKgÌ¢{BP:5bãão ôÑ‘búJv¼‰õŸËyif„im²ôx\?z“Ôÿ?߀? ÆS/_0Í5¥ø‡â¼J™6óry”2®ý!6|.-u.Þ° }–„hªªêàaõEåAPh¤_?›>_/æÝ¹ê1´,¸S2`¢™.ö–&Ôœ<†£§Ò RºÏ…B*v¾@æ+¥Ù‘3îÀ¯¦K+“|"21?{ ÖíÚ[‰µËW#÷¾Ÿ #.‚_VTW– è° ×LMƒ±öë4£˜`L€ tš€Ñ÷k?ûh©ÀK¼(O"3ã6²¯¬LŠ»òj`ÛñJTïxD.~~íeˆ Ïk}5¾.(„ï¥?@:9|æo€NwX.  Í 5¨úæJü¥-c±87ÓÍš€˜ÝV…¢ý•äE½íaÁJô°´K-|{èwîŽc×ÞC²9l’¯ž†é“¤o}ÏÅÍç¹DÁ…Y¬4Èùîæ]8vÖ&>0z®›9)€×ý\#©õÄ~ìÚù)ŠKNŽÁÆaxR2Ó¤Ð8&q;»–²ý8F~xuoºi|'bLýÔ tïýç£]ØCö¯$3ñtL˜„É?È@hGn3¹ìÎÈRU²yîqêç“®LcYíù>ÑkÇuf›‚·_+Ξ‘K=SZ› Ávab«?‚ƒ”qEá|3,'ÎÂåÔ§‰·¼ò äìAIÂ$bçãã”ÆêKÈž‚ mëhì¥^ü†Ý?ÑÂðPCþªNbŽÅäñÃd©åMKÊÊ­ˆŒF°Ÿr“4¡t×›X§(lÒçc<}c©ÁàØmó‰=òx˜\RíQ”Ô:& ±vºÇC†%"ÎÅuDý‰2ÔúGb#+RÚ,û±îñõê„ùs/sz'+þÈémŒâ /!oÈ=ÈI–ŸöìÞ¸Nõo4b¸Y-W£»ëêt -­ŠC%ŸÑY¥áÚ„ö*(׉ÌfŽvøŽÒ&Óîï›TнVYEòñ‡õ¬c¶w}]šmvñÞò7Á_£3V_Vä~±ßöc¿@àÜÈã¿* ‡˜‘8rLãÈ)GšÔÜ%Hp½+|0Žž÷½ˆbJZ´áE}”„ÔhŠ‹„G¦Ý;S]‚)ÄTØŽ­4½•öƒ¢b1"Ú„cEÎáB2Ê \Dþ¸â¦{püwÏ!_¼Qü¹ì\¤Êœ= 5[¶»™ÃóÉÁm3âåm‡)U1Ö>þ°Nb±pñ5š™ þÈ^p ¾ZþªX^ñ–Wñð÷l±Sb’FIë=Ën:ŽgßÈ7”vÈ•‰i£k±}— ‡{Pü;9 ÍÀ7ƒß­Í£óÖ¿ˆ¼õtŸ†¢áœ  ¢2©¤XRÔÌ>¾á))–>šÄ”3ïvdí{ùâl›Ãذò HÃLÒy¡¬lA±DÿŒ´_(E·rñmmh\@ ­.•ê ÞaL€ 0~IÀèûµ·|è^Tߎ÷¾ó¤0¹äž‡ñÜzi§rÇ9Mýý¨œ³–íÆ3Øä6!²zËzäoÙÛŸ^€íj%£Ç­QY¬Øýçßc³2T)Ÿúùzêç_åÞ4šÃŠЄOžy Û5c“¢daåÙû¤1Á—Ðí4¹%Aù±ÃkO­•‘ñIäžFeh¼ÑR±x^†Û˜¿áqJƒõ!4Æ^2iì…ž¯díæÙ{ ?5å•ê=‘³ä&$»Ü¶JòK/OâWÆS«©}ÕJã§à׋&8)l ‡‘±ÛoUE‰P8Mœ~qR‹Ó6hêÄãpÿ¾É_KãtrÚ âB”¡úl§)gÿR³bIî@ÊF˜¡"Ÿ³àˆÖùXH®_ôcd'{ø`¤ÑÊ»±éÅUÈ/§"È ^±òЧ¼¹w.À¸çïÈx©.ú¿š©ééX¸±,¾é.y„S˜@·ð†9­@ZÁnü·¸dÝ^§ƒ‘–u’ƒá÷:ÊAÆäéK±løNüyÍvÇ ^>vü4Ì¿a b”¥Q¡)Xºò—øà°ýs‡bV:‹iKr19M±³§d¢3çbEü¥Ø÷,~áðolÄ ¤K1!3 ßlù£#¡Óž”Á ×%°æŒYX±<ÿü+Í)—2©J%:Œíô‘âëç/%¢ÿ¸hƒÉoÓœ'ư-obãíÇœ”%v¬ÙQ–¡ö{n‡*” —¯‹\g S €/tìÞj à}&À˜èwŒ½_{Á7€òÞVÞƒš+Û±o$PB(º¼jc&äâá¡ øÛê8â6à‹!!Žïð7€’·]B Ç\•Jr¹¿ù4æwºD±+>XåP*¥Ï[ˆiéÑ8^°ë…AýSyä }VÜž¥™l&d4š¯-É•i-ÛéP*…d`áÓÕZ‰wV¯G1Ý×ykžFȃ+ãâ‹¶-Iø\W0ÐÏ©êÒ÷þ„µÛäßštMÜ:Ã쨱œÄѯ÷aç®b¸>ÐÛÙ4˜ÈÏyaB¢S”Vä_EóÄ—N×—à%U©‹™Kæb 9„9š·‘|ò‘Å'ñë'çzmL(؈,%[^P•J‘Ù³;i |k¿¦AôM$&Pû-ÇO2<¬º*æpÁø¢¢•1FÝZ†8û»ñ(~ŸŠ–jR–ª :Nœ4?ž ³d8Æ©4Ãã”ë*7gäbÙÍAxVœØÛHÊ]º_Ĉiw܃É.¾‰„S~!Ž~è:žš:cæOÏpSâŠE»¥ÚĬíýªŒ.))ÉÍB = De-µë ½ó”’ŠwÞàqÌ7.{1î Ú‰õk¥±´í3•‘:#ó¦£k¬]qÖÝõ)ñ´uÿ.VR¶4K+…ãØq—è_+%±¼5Ü7…ü>:ü.出ŒãªÏÏáÞÃ¥ø>{8à•Wîÿ¶¤¤·ßþ[±‘Ãbãzuc««í 9h‹b¬´<®¾þ,jk›pž–2Úi¨54b¢Ìanš|ý ècäD, >hÇyZÅ0,FçBÎ,øe©¯³âܹføÒ3¨¡ÁŽs¤“)>ýz¼‹í4ïªáTý˜@MÁz<ùF¡H`¦ÇTt_Yêa÷÷ƒ½± þცšô ¯¹¡õMßÒrT;í~D÷¡ÛǸçìò þ~×ÓÒrï¨iXñÐd—­í[} ¬Âºsz ø˜àåóÀ½l»­5Vj5ÄN(AAÎËmµ9º¦ýÚíósÄ·ž”k ¿¯Ö”pOeéÎ7·~ËÏ‘¾x¡½}¿ò7€tõí¨'_Lvœ° ¿€ ò5ëù«¦§|ôÅžÛWÚÔþsÕŽ²½Ÿ¢:,©ñ!ØýÌØ) J¶ó=ÜÜB¦bt‚¿_>øí yÆ|*îZ¹ÞøÙ®/y+^”¬$λK'9ÆJß[-[7¦Ü»×%8~ŒæÓ]2Vf¶þz…ì烶S»ÕäÌ}õk$K ípU…à¸ýÜn)Àdb] ª†eÓÜ•6‚i17¯ôm‰Þ„¼gÆÖr‹Ò˜Eo+‡ðkðÀ†Çe“éf,øÍ}NÖqÊv¼†—äU™7wD¡c@ò¿òØ#’)øÈI ñ«yiÑmeX}ß‹²E,üúOSr9 â=OÚïçžr¶ßLcgÏÖ¡éüy´ž§ÑÍ@2õ84¡ªé8ýüFÇ)Ö§Ha·ÕO¡Z $—+ äê:*>ŽdUÎêl7dÊìÜ9aüö<ÝQˆŠ†¯\¶tlìV§v¯£ld޶¶îšÎã<=[†F!ŽÆ‰]æ"y(¯™Æ˜«`!5A4.Ö`÷GTì°6¹tw}¿ ÑFû¦QaŒÔ§ÜÏa¤KèI¡ºê„(Îȇ߱®Ï·+ éSe½ÅЈhú3Ú*DÄ$¸˜x(ÎÇ/dk3ÂÃB(Ù8š t+{MöŸòÇ%ÉÃD?CJåÖø³¬T2p‰ÇYzt_™åNêý²Pÿ 0˜å%±ŽÙÀJíÚm3Ê ‹1pä%ˆ uü í§“ ZT-†T27gršÑ¡-Ã󾉮 «<§nûŒ‰ÚäeaÞ·¿í:ù,`L€ 0cºâýÊß{ZÙÔ~þ0Öc9—–€&ä@2\ÕäX¥®M¢³ï¯¬æs9g-y_5Ã4åJvÜ«i A=êçfí¤J2Sö©¤T~+\¯Q* Å'_; ©ÛžÍÉïùäkLIPÌ2ÍG…v±,ÍUûUçñé f;”JBÈ_Çl2Wôœ`®è”àxþŒs3›/$äpát¼ŸW|þ©,N r_§?v£§TòØ·œ[çºfÁù¬öÈŠ²ÃÒÊŒ I3”JBª„Ì@:)–Šh¿àƒ}øQÆ÷¿e»Xë©od³cfü~3;Záqý‚ <»^˜LšÿVLÇdYz§´|УøÓØCtŒ÷ã/ŠðFÇ)Ö§ÖkŠ@‚âKH‰lkë@c©Â_[‰<ëØØ­§R¼‰7E šþŒcŽÓNy(°»ëó Æ‰6Ú7 ÓÝõ•óbæcÅÒŤÏu3^B æÈn²·.|H"1}”¼LµEs‘‰¹×ÀÝ@]75Ð~»×®?ºƒÈölRœdvò ù‚ªTEHÅäË/š„ª¼Ã˜`L ×è ï×Þ c¯¹à,(ð@À~œÌaÉ ¢ñ¹˜ââ[ÉV‘‡'eßSî}ŒVIßâh©Â…Qq AÙiˆ”vÿûDbLºà÷ƒ,w|þ*nÌ@‚0;Ýh>ÊÚÕ²T•|%ˈѣÜ͉—ÐyR,‘¡ðO ŽcÜTÇŠ,9#ozr¿[1•…K"x-ǾåZ‚Žùq×$â±í¬êÏ[Xáèþ¸t| Š3Zå_â[’å Š]-KuÙ¹z ô|¢D&¦ ˆÌò bî?PEŠ%Ieí&3G0&À˜@¿"ÀŠ¥~u¹¹±LÀ(åQÑH¾Ç$³wŽ’‘sÓÌÌ戺{Ê iÁöl‘`æC‚FOÁ⛦!NI¤9Ç»L€ 0&À˜€gÊ«³'¿_{ƒŒž ó&Ðó ”¾ûQuBžpÛ¼Ì6Í÷´hG¥­õ¨—›¦gZÞÑ#’Èy‹àƒ”ü-–§…Úh>¹.eÓyYì8w¦V.n¹ø_NøŽDÚŠÃò­B8ôhd:ëŒ,`âÕ—"ØnÁþ½ÊjqžŒ®ŠAæ÷¯FJ;¾®ú–KƒkŽã@I#CÍäAãK×%ö06RÏs=­¨CÉ$½Ê/rm>a¿ke‰E¨Ž•VŸ°!â$REýä*3&À˜@ÿ$àéÝÔ?ip«™Ð%`ÎÌÅŠÑ×áìi Ù°m€Mð?F¶aƒ ň‘ÃìãýL/Ý :éŸ<¿×VŸ…¥¶VZI>»O¢ããGæ&90&À˜`$ÐÞ¯½AÆbçäL '°WíÅË;,¢H©¹ó‘¬3þmš‰›oަy† w|wÛj+U‡ñ)Inë•äf*¼mhÜ;ÑŠ £ù„»V–&r¶.µQ)ˆÔ3gM¿9Èõ…Î7*{rozrj¢˜ª;òÖ_ðû·,j•„%Ós»w"qö,šì$¿§¾¥$jm’öŠvb¼R0#+w¦g'9ÌØ)LƒH~Þ+ÏÑß'_¢~z– x˘`L`Å÷&À¼" ØiI ?¯R_„D>d[7š5Ò&À˜`L ‹ô†÷ko±‹.ú—@v¾ºQ®2 ³²=|g›ÌHÉÐqrá£nÐìjÛàO«:¤m ÊNY1&”SFó w©,16ØAî¾4xòUà2¡Ž|R –[P}°V¤ÈfÃa8ô4¶“GD‰ m€¤TJŸ1ßOÅù_á¯oìͽÙ²›†.Çœ4ùCO}Kl$­¾—Äã ëoÅ Z…W-Æ[¿a ò?›†‡—MvQ…á’+ÍÈ·çòñ·©¸ujм"° Eo½®ú÷rãØÅ²„O&S•y¢ÌùkÞÄèßÜŠÙ_˜­ª¯¯Éw#˜`L€ xø¼c0L€ 0&À˜`L€ 0&À˜@%Pµ÷ì”MLçÜ1™Ö^¾>´TD'4×[ÕØ ÷4Fó©…êìx_f3N•’R©­ðm3©ä0(D_ù¤œçíÅ' [+”\bÚ½¿ÂdÅ'XÌ0ü:6O>±QT.åoþÓÓ&»¯4Òm…ÆL_€1ê9;,e_âW6 ˜V$¡|;)Ži”³o¢äé?EêŽU¢©É#[^ÅûR‘•ˆŠÏ Ä•LjqÚ1 KP ä¦â¹ ‚¿°ÃXûÈýHÍÎB µEíÜ’3&À˜@_"ð½¾Ôn `L€ 0&À˜`L€ 0&ÐI ¥øûzÙ·jÔLJq6å]éŠ4àäéºv²$!.2@Nc4_[U,S©Ü‚Z»Ëj%—êb“‡{©„pÉȇÝFÀ4dy “BÐøÙ˜¤(•ä8ÿèLÌÉ”ŽNUàlKÛ×\Φ³ñ9!‹–ߢÖwdïò$&¬zÓ¿8,zúndÅËqåÅÈß!)•b§ÎÇü©IjâVu¯£;ÞÉ“½w-ÈR /Þ/+•’pýÍóE_bÂI6ø¨"â&À˜@¿'À+–ú}`L€ 0&À˜`L€ 0&ÀlKô¸"ÄLûyŽ!ón¦!qâ º°ÞáLµì€ÆQ…¸×ØT+Ç>Ri—ô?Fó¹íth¬Ì$$“â Ð‚*œk¢]U55 ^®é¼Ø§jù §ðw E "›Ó éƒ@UY¹OjSth?h$2âÉØc9å:u§[¦ N-_.)(s–=ƒIUe8ei€Ý׿ˆ1ûàƒß*¦(ÍqÍ'g÷zã…,qæâ÷é× ¼üɯ²™ÃOˆÁ÷*>Àf¹¢UìuÍœ 0&Àú(^±ÔG/,7‹ 0&À˜`L€ 0&À˜@‡ Ôbã.òû"„øiÈŽ3Iûýß‚¸)Se±Îj Ôáðgr=!‰0+ÕÍ×–|Ë ‰Œ–K­DÅIwå˜õD™ìKHÞ–|®'øž?ù9’Beé7hÖ‘É7pŠ®ŠDômGɶ÷ÄD6œ×ºdŒˆN@JZƤ¤R‰–ÊÕÂ'²)ÊÈI™îJM—üíj+÷,ËSH†1$KJÂ0qÞÑÏ äâÍÈ­Üí×È)˜`L o`ÅRß¾¾Ü:&À˜`L€ 0&À˜`Å´[Ü.ú˜’¤çdt¼›eÃcåã@Í·Nµ6Ÿ(Džà†Bâµ—#BÚ¥ÿæS ÐÙ1VfDÊÕ”Ù'{¿v)·EæÉq©˜p‰£. ù°» xêç>ÃpõTÙ[ØÁ÷ñU‹i:ò˜uè a……¨8 ñs=/òú{ªÊåÔQ)ˆ2y_Þ[Õû0;{¤×UzLhTR4oQÍ£¯ÁÈ 5ð &À˜ègX±ÔÏ.87— 0&À˜`L€ 0&Àú>f›Ö+l¶:œ=#·÷L=jm61ÞÚ ³^Ã^…e™<™£åAø6pÙkJ°éÏð÷?¿’íª !{ ¤qèFlxñ_¨"srbh(Ã_ŸzG>ˆÅäñÃä}ic4_—ËbJÀu“$ »×cSa•*gÙ®õØ|P:Œœ115U¦–Ì;!ÐÑ~>2ë¹xê“+ÿвz¥Ï6£ä½õØ)¯JŸæ¬Tm«oÖ>YNTÁj×(ŽZ,ø`Í3PÖú%EÓ½à⳩¥e¥ÇamQdDkBé®×°N¹Óçc|´¿’ !K=­¾«°X¡•ÄfÙÕ¬WWåÍŸ{œ%q‹˜`L Ÿp˜íg çæ2&À˜`L€ üöΰŠê|ûOÈNYH I ;aߪˆPQ\*ZE¤ˆZ°Z—¿Z­Õp«[Ūh-H-X©@+"eßD"BX!„ìð¹wfîÌÜ%w™„{“gîÌYÞó¾¿sæÌpÞ9ç @Ã$P†5³ŸÃry\µñü:Ìyl|™€©³ž@e :ZSp;•Ä­z ÍÙ UE¹X'/•5ð:tŒ‹V$Í»bÚ¯ûà•¿Šáõ“¢ìßî@Zf<Îææ«³1®~àn´7–ãe¾ºÐ¥ã“0hël¬³«Öýu6vf¦!®¬ù'/Xílu5îÙÞf3Ïê‘€çí<8¡?ºyþüϽÀùxç©h—Ý÷"_žA‡Ncpc½SÕeÛ*?Œÿô‹&1ó $Æ{wþ¬áÐ÷ÞÜÃnO§òüõxçÍ–tQ­Ò‘‘¯@É™9OÞÓßΙc¾.%XÿÖÛXa±¿)Ò:eŠ%Oaï§MpõožB?ƒƒKä @£$ÀK²Úi4 @C&¢lãÔÈ–6ì!SUY®¦NëÝ‘nä^Å©Ôy”ÐcÆÄÙßR0_—0$tl*ó÷è{mN¥fqçïŸÃèŽ6]Upi‘.ùOTéñC˜µ:OUè¶”¶Â±º«J;<©ÄžÝ¹8Q ñ˜÷è¨9ztì¶ê‘Á®ï{'i«Ä¿BútOCL@Üß•Xµb>)‘ +Ç`áXŠqb[ »ÛWùã³0ySg ¨úõÔG‰,ƒH€H @Tâ›E;ðI¥¢næt¼=,ÿ®7Æ)iŒ¿‘˜zãÜÜ9ÖÁk ²Ì_¸ Uo2+õ² 8YŒ•?‹à °hfï5ÀଔæÀÓߨ¥³„‡Eâ¾kzcbÏDC²‹(¹  ï~Tר Çbi%<³Ù×üˆ÷Ôî­˜¸ÄQ[³Þ{øñ(n‹OÁä,뀶»m³cf;/Á°ó~vŸ{ »P¿cf&~;¶§pé[ƒ‘Ûm1)h'3µ¦¬ÆòÏW`V®’/Ÿöj#_uо‹FÙÖL§0ÿÉ+ÑR§ù=µw§è_ 4!B^W1X°> #i†Ó¸nMñEZš!ÔO/ƒõŽÇð†2jQv ³–ìÁ¯°Km?ÛªWF;Ìäø¾w”Tb&>Ì û;ZëmŽú†Òì­5ã~_åÏBGm‹a$@$@ý™ €†@´2=É&}]yIÕÇ©Á†“2¼óåj|[xÑÎKhÜ*ŽïǤ×ÖÚ;•ŒÖqaÿëg3ô©üîªTšµùGüsÅ&Ì^¼§Üñu]UY†–­Å¤…û!MöÒ–5”äÒ‹ÒjJê¨ÐY[&¾’?€åkwáýÅkñÏýçu±Ž.ôù¥ì°ê˜jçT÷_´þÓvÝ€¶›ms_îÜõåµÍ¹÷¼´òô·DOtß—›‹Éo~åùz'' ÜtL…ÙÖ®Ö8•Âðâo®DЦô:èßEŒ²­ °&ßÑ_›´N%)µAžU@@ý­çPª7>eƒ5 »ñYožÅ†>Å<Á”T—<é«üíYX—\(›H€™ûë@®=êN$@þB : oNìŠ¸ê øqO^Ò ÜÔ`Ѧ“¸fD²¿hK=Hàò¨)ÄìŒ_,㾑1N̼Q–¬N“S§Š°kßáœ@ÄåÕÚ«Òó·nÃóÛ”AæHŒ¼¾ Zz8®—™…7G¤5Qv¡GÃ’ yPÅ ÍŽü¼Ï­ŠÃ¬!ÊÌ¥0Ü:e®E‡@8¶ƒÃül¯¨Œl,šÞÑZO­ùD»¦H|%¿KýJ¾ud nÎÒ/¹æ2¿Wµïß™lËÁYŠƒúõÆÃÓ­Ë%ŠÙ_ÇòOà›yhÓLû ¹&ƒ8yíüª]$Ξ>…%ßîÁ2­ÀŸsðSY[tÑTƒ5w0™p%ú7k‚²jýG¡M›ûùrZÝ«Prövýpü¬uTVbÖ'kÑfæ0t0:Èõø,W¥·còêb5涇`  k?-Ù~7gç”Ã?OªE5ÐméÛWd³æ Ôæ2+¬æÜ5J4~ÏP±œäÙ;1}¥Æé™š…OǤ¢ªB[‡¡H²ëOÈö:TUyOÐó’ $³:Äî£hç}•ÿ? }4ÙI€H  c©U&M! ËF 4™‰ÍÄ€X3¤$·B·ë1qى˦ &&pxó¬Ô)‰§\‡ñú‰ä!b™·±FJZ2FèÒËeç±ã‡<ì×: Ü,1 ×õÕïýpæøIl;©¢T†]?Gˆ(6¢E"2bÜ{ mÕ2)ñ¶å4Ûe$cð•1ÿ¯ÿÅšAâmëvâ§AÃÕÁìÒâœ8ÑêX ‹FŒƒ=ªÎäçcóÏÈ;/vb{ë„ED eL3¤¥%¢C¢fÏ!ƒrìÙž‹-ùç-ü›Å%âš~¶}aìªÌÃúRò»¯cN Gdµø’[Úê.1,-¥½*KñÓO' lÛ É=rôöäKq¡¸¢m¼Õ™Yã$¿¢ˆü{J0Û¸ï$Ž—Yë6<2 ]Ú§¢GF¬ý²=¹ÕÞv EÖÑ¥¶ý…ᆲSI*-8 )é¸[üqu¤¶û)҉?±èÕ³¿ÃbÅ*2VÁºG^FS´M‹÷>40® º''¢Kçv¸nÿvŒÿ"WcB1>XwR8z[iœ–äáw lù:öê‹Émý’ƒnûØ“†MŽc vDsÝ0O uäÄÈbÑ?*{hJñ¢ì"úÇêâ“X±9yÒ½Š^]³ÄžL¶úÐæ©w{û¶â9a'¿‡ˆþÆþ9ñ9¼ÿ0Ö<Ñå¢RÛÐ-ãÑÂ`^‹ ’Ó¯@ 혪ì7ämH—Æ÷‡¶yó<Òæ‘Út³–âÝÀ¾ó®(.ÄÏ'Å›XH$¥µB M)nãîÃØwVzÏEttÚe¦‹}3íï‡z=}—ÐÚ ¾ÃyÖîM·Áb“}•#݃˱c×AìÌóÔã’0áÊtõƒ,I¬G÷„N¾¨»v¢îÄü÷õë÷ckØ]X¼KÇ·J{]%«}Ô±ýðÍOg,ï}áÍZàÚAíäeoÅk h´ÿ¢jÓJ  ó h—œÒ£¢´ƒÉæG‰$¸JñŸµ¶¯ó%;FŽ`çTªÍ¾Ÿ6oÂÔoŽÚ'Û|³#À#W&kú+ñïël{¦…¥ëör‘–æ›þ…Èk9‚1çѱꞥ‡÷bê%øÕƒ¿y^׬<„÷g^v–QÞgšòdÉ,Ù`9‹ëÖ_ˆA_·ìkž(L¼k¶ÍÞ€mªóâûçÑ¡›4§K牥•A~ƒ½¨,ÄûýŸkg˜¨rĉ!½‘ÁMÃ:¢xí>¬Tä[ò «³÷ÇàDý+¶çõ%™à¹Ž“5õtÛ-#,{•æï³_òíd.¦’+*êÚºwžd££üÓ¤¿JNâýO×9f¶i¿àIĜۡGŒpXɇ‘›{mGÉ]·¿ÕÕb„M=*ñò?·ãÍ;{ê–`S£œTÖhŸuM­ƒ‰º6á(£(·FZVÖ‘ÓÉQz s¬{‹¬žx§ßLÝd›¹´mËaœŽ%GûI³ÄîHxÿíا˜—‰—F¸Ù'(y´¿R¿£c_€ïWbb†2Â[†ï·ŠD’ÇÜZoqâÌY ¢ô¨F•¶Y:´Bô¢VûGÁþk‚1õ‹ºÔŸoËŰaWâ©Ö™ [þ»/iúýûî¸^Ãךµº ÷.k5. Kìbô­.ÌÇ+n6ô™"ØÇìoöã•ß AMß¡SÄÑ… ý‘§ý¸é6h쪖ۤäð¹§ÆzÕkr7¼ÓÚx ‹½yUæŠ÷µ—¢3ñÕôž‡êE¬ýò{õÞxäž1“,½\ÄŽUk0cÔïŽÕûбW¼1¢æ=ÍÆÁ¥7ïF»=k÷æÛ`3ËñóÄo_gvº‡ãFűdBŸpÛµÝqîû]X¦{–äáõoS±pfìøû7x)WyŸ¬;„9Ó‡£‡aoA­<' †LÀö/¿†l%m# ¨[Ò‘æÈ?¦}éú1VMJž’@##Pv;u·G3Œìb›ã=+VØ9•âÄ?®µÇ²ÕpŸaÿÝÚöQ†M¡uû„éöS3îaòÉ—F§’Rr!^]}\¹@˜2ž«†ØN¢Åì Ÿ°dÜÑM3«HÜrÔ6/'Lû1°ÎÞ‹øö {§’ݾVZu|€Å+N%%qžŸû?Ö ìzW_¾ëhÜÇFÑÐé¯ÁF]þ²|<ö¦Ñ© i`^=Î`ÆÛÿÅ­ßÔ Óݶ£Ê¬Ã“ÄVú9gæâ®W¾ÆüÝêÞH_y{mÍÏ’U»/¡MVBÂÑ©d³ÀÑY‡Yh­ŽÑceÚÛytX¶,Y…ÏU^Íðæ¤êá¶”œéúUk¾ÿlÓÌœ.ËàY¼H¶›³á9•¬v»Ó½êúdzbðÜàTRȯ\¹{ʬûk’©[~?øß»{å‡ ‡Õ4¿º¦­u&˜™öð{§’îùPŒÇß^‡cjÎZNLê<éÇa¶ µ˜è2Ú[û] ôH7†µ¼x…$¶Ã}Ú]Él(Ð.O(¸•äãSÅáŽÁ§°cÉ;•dÔû¶íÀ+›‹ÜïÝ»„o°Û“vo¶ zcÝxÖ¦»Òx{OäþÑ©$k\yã_úÚàTR¬9¹N*ü% FG€C}®Êi0 Ô1cI|wi9­uÿ{ªlÒŽ,#:*ûžÔAÙID@ü#¶©V߸ÈTþa¬ wr^]xÏjfH_ß?2áŒi…âüñð'ûÔ¥žŽìÞŠå}R0BäЉ4Ì2ÔŹy1rPt=ŸY»m÷û¾½'P<\Z2ĺÇQê×+ñüʈož¼gHÄòifí»‹¥¶Ä’WÊáTªÎÞsØ®ÁLÂÂ'Z–&ª®¬Ä©ãGñciŒƒÜ‘¸ïÚhYœ'ö•Ó~‘\ˆì:™=ÅÒR^×—Y:Ф=±èžX<ü‘m¥¸+ºã¯cRÄ’yÁh¡÷Í)(5¿±zÉ6ÍÌ019Iì{õ—Û»feøváJ¼ô³RÇexüËñŸ»;¹üžÀuÛÑ]‡§-{vÇ}Nàw¡,3ݾ‹Ç‹ãúa Xвöã"N>„¹ÿØ…uÚÄ­ZãŠHG$1³nýŠÙUš¯ì[¤µFK,iEúõ¹ØkqŒ€}GÃÓêX³g0Ñ*œ-QÚŒèÃ~5DìEeŸÎc{[¥cj³xGnG~<„ÃcÓ‘!üØv’g'…á¶~ñøï¦ p¶’D¬ Óß[ŽŽš~JKkpó­×bŒ:{Ë Y1ëðÉqXõí~¬SªGÈÛr¼]ÚFо¤ F"Ë”ì¹9ø¡¬:»5øçnÅ›˜ˆk³¤ûGô_í°ÍL!¿3ww‹Å±Ý›p×eD¾ßì/ÃÝ–ýuo1#¶óÞÿŸÈýäJñ,˜Ö·w­ïÞ¿K8«·ÚÛ½Ù6Økâý³°×éèÕ¼ /ö5ûžØ´EåÞ}øä¨íCEÿa½2‘vî$>ùYéëÄ̪2ÝK¦’”¿$@$Ð(4ÇRÍE×%¢zi¤YØ~Ì"I9Eà’´å½î¨ÖûÁW’‹q/åêÒªñË”`9ŸÊh”.œûi-ÿ­¹xI,‚cý"\åè ùZ S~¥tÒ‘!ÖNÓ†¹”«÷ûXu1f°Šµü-ÉÕʶ varž³…ÊЩ Ik,Æ"Û’,Cn膯æíVA–àªÌÿßNñçÜuýU¸¹cŒ,Ô¾ü1þ­Ó)4Ô²”ž2¬ŠÐ&bæ–/õe‚ŽZ–‚‹®*4œ#uöˆ@ /!ãBq©:ˆ,¥m®·]„…ë½…J^£LOÚŽT–rå(áæü6AVŸþ˜—}߯ڊ×véÝK9;·cMïd N£1±1èÞ\|»,æÍѧc:\‘`¹Ÿµiõm1÷Þ0bâÊ5·st‹x;ùæØg/E«›}¬>D¯»­]èSIWe8&Ú£BnƒÆòî‘cËwâ[5q%^˜·ïNïd5ÌvâJl1¨\ámƒ±é nñÁ,TßB‚1¬K<‚.äÙ„‹3I†NŽ.¶ö _òÖ.½öz>‘øÓ¯¯C'ñl0Z=uyb›Šˆ‚œA›N ’®Õ°˜4Üœ¸*+ƒ•Áºc½0²Y>¾RÂb3Ð[,õ(å©,-7ªù[µëšè¢r1ÃÄúƼž´¥6¤_£mœiçaÍ1亡èÕqžX˜£q:Öàpq%~i§ÇØë®Â-éµýsÊÀ^¸~³2‘âÎ-ošqzAîó4ê®Ü£zyÒÕ…¼\,•gYbCã‘&öM’îf»òšg`ú¤ |ûñ>KRË_U'ðÄ?rðÑø,ÑKj×:èd‡á¢hŒÝzŠåðÊ ?Vc¡²–QT zÅ‹>±DßÇH2ŒmX«Amç:jKlz¼=Ÿš‹µÙcÈS%¥·…í±òQ˜…ãª>Iøp™mãÊŽ¢SÌõžÞ· ¢d A!J>›áWuHD¸¶­ˆ¨ŠêJ4On%fVYõp¦ƒ1Ü—þHo—¤Ÿã~<ÄKl×~fo—µNŒ9íÓ¹ße]®k;¼PÄN†ñ· 3È5Æ{ò<ŠHkƒëCâk¥ÝÏÃö3ñXù“<‹<4 W‹=ÌäÖk(Y\Æ ‡·˜Åª?jp®< }ZEȺÛîAk:k0†ZÚ©Ûï~öý¯ÄAÏÂq»×ë*®Ü²Á.—&ÀhIíÏB½žÂÉd_ÏÆ4¾õ Zù}uÜ q†wjÑ<% O ¶ 5x4H€HÀâ+aiù÷f]˜PE@ KÄÐtñ5}žòm8ðéòÝö`o±”PmG:dGG‘²äX r ªÑ)Uó:WZ"Ò-š:¾/u_³WcÍyV“ÕüSã Šo%ìÙ‰OÕåì$YѸ*3Ê}¡ñ;n8®/?»öáõÕGu3sVþ|F8–ÒÊ3ÎЩ(8š”©i‰b'êË5êØŸjšŒ}¤>¤ibÚ‹V•#çäý}+]»:{V»Dc0ZFê˜^ Ÿ_5Oï‚G{ÇÌ­F‡£½â•5Ò(£0-"Ľ¯ûÔÙ^®?‡8^Öö<~«S»}÷4§}ZexcH舷ŸÂ´Õ¶=áŠóöâåMñxªŸ´#˜‡<èÛ4=C,‡wD]O‘Ô¯Gq_ '˜À_¯Ä·oƒ~±¤,7˜³s Q%EcD§fêUÓ–úþ±íðè˜n硚¼Ö3û#÷úq¡’É6Ôj¤‹fÚï¢FÙh†kûÅàëÿ)3ZËðüÇëÕTÙ½Ú ÑâF—‚ÂÐE÷®üzä•›êh©OU„‹Þ%4ÒÝk÷fÛ Q@=5çYÈ{BÊ ¸,¼}º]e})4HLdå2p· Ûš»ù˜Žm¬aµñ•›áf®­6ÚÇIÈ Ë~¶gÖ§ïmÀp ‰{$†µ×‹¥„îù`3rKÄ—’ÞW*ÏÆ·ëˆ½'€¸ÝBwøâ-cÔJ¾Ý[~Ö9GúµŽ·l\m½w5ŕ┄J¬[ò-þ¬qtI©l÷ºÄÀþPʳ“k—W¢e8%|b¶¼ÚEF¬‰¬qjë‰Ø“@›'¨²›¿[û–Õ%lß» :G(ufµA›ÀfÓEœ?W¦Ê ‰ˆFï~}ð鯻‰—mGSË×ë6y¶`×Sjþ ±LÍZQÚ£mjsK¼÷õ廎’>*7áÈЦŸ*¸`‹SÛœÖë¹%dS$i£ bí‰j[þ’|,<¨u,EãŠÄ9^›Q#ÓR¦ó:2æRíPuUêÅûß²³§‘/bö²/âX⼕5Þk:£fJ¸+=œÛi_¶+9Þǵv¿\{ÝÅ*:fgæbößb±n¼hÜ70Y“ΨUFz¿+ñ[áh×›V¯Å’ÏÚe{.Ëž±ŽìeÚçÑ30Zh°1¬%FÙñµæ‰é…,±ÏŒZfhSˆEÄlGÑ|¾¯È¯ÞÓQV©}Ú²(g™&öGîöãA^Û á Úé,L±Òö«2ÔæõÉ~ge×m¸Í"ë™C»´6ºunj|Op(ÃG\Út©íž¸„¶]ÚXö´—†1Ù­4².!®…XëTsüuÙvœ°¼séY_¬¬Ô¼Ã9×Áûw ©<ýán»÷ν}6¾V=ŒºèûGyõºKWz™"O÷„+ù®ã<·Å‘}öaö¥2„H€ü›€§ŸØù·5ÔŽH€H€H€üœ@pB<×å žÛ£Œ/:Їß;Š~2qejÊÄýU%EØu¸›Š$çL^ìÙÝûuÅU«Wcl£ô…ÿï–Tá¾ìþ´¯ìÔˆÇà¶ÞÒ—ÿVަ4V€‡_[*I*Õå‹d‘¦þ„DHƒ»ŠN5xuÁjTJEdxt¬}Ž–¤LÎÖõ˜‘g¤iZU‰EzK, G¥â‰¡ÉâÔÞYe‰×þUy¿¿G£bpS×dd§Å!.ì"öm;¤sʹšˆ²sëÜuü8~s?ýŒt޹hŒîkÑ¥µ·õe‚ŽZ“Ñ$T·cqÞnÌú¦ ƒZ„"%« ÚD‡H4¹ƒãpç°x¬Y©Ì,©Á›ûU#»‹ÊÏãó¥{ÕÙLR®ìþÝÐ&ØzÐq9NoÙ„ÇwVBÚ'iD‡–bã÷á„­Àú{ñuÖ!†N­$‡®ÿÛT÷Ëðø_ÿƒléK’Ð`œ.*ÁQei(Má7ìNÂÉ[û„!ã¯Â®7Va…FÎ W£ý´ánÊp\J×ìà§\[db²›»£“-K`žÙêHëL–l¹Pßþúhoô¹yah—^‚oŽ]ÎÛ{ îÚCê?F&a…fé¼Ïÿ½ Ë7&áön‰baÈr=Y„mû –‰öûº¨'û#wûq˜mƒ–§ç&ÚïiÑþœ^}O+(èqÑ£¦l¡ öê¢yÆ&îÀ»úx}Kr¯î¸~å·øZ)¨èxí$®ïôX]…œ#'±âXn»yîh#uªÎ¯ß%ˆt·Ý›mƒUÌ â=aGJ! / 4Ç’ÝÚ«^c¶ÆI€í§qÖ;­kY T‹±Gå~0ÆIËéWœ6dç% 4zÊýÓ{Ôux&d ^Ø©,«bE³I „núÉ1&Ë=&6¦Ÿv{Gìúû>Õ ’#÷·à Æ}· @V¸$Kr„áÊ^‰ød¥vDÄæTʾì®ê¨\ô-’½Æ<òkäã¨G¤eb\hi‚MÅ€4i¶¢þhѵžÉû/ìQ>2Š NàÝ•¶}š,9ÂjÄÞtB?é?ƒ­fõGR™îõã€76è)¸¾2Ú+¥vÖ&½µßµõëÌ.O4pÄËÙ{Â…’* Kcm›’Ê6ÞJ[´é‚RñîýsÜ€Lµo±¥m†ûïéýíÐ|xQ‰¯·Ú;c›Õý¬Þ^£’Ζ÷Ñz÷îg½ßmzYÏÜk÷ÞÙ`,K{m´OÛ—kÓ)çµÕ™’ÎÛ{Â¥|ÑWóÚ¶k´Å¾½(Úñ—H€6F³^îFZG$@uA  b›j—¨ C¤úÔ0ĹþЮ.”£Lp!èwÝP|vWŒN¬åóñ(1¦gdJ_¹Š£ijGüíÁ+ñ+Ãà­5hŸž‰W¼7´Ñî&÷îg²µ‹½I9‚1qÌ5xæš %»%Lsà`ý ¬í€(m´è3t_-E§ãÿÝÖÙ:ÃA+4ÌNg,Oe; ³Ìîúã=£ðªêT²EÆ>J£³Xúîj'ì$ ÙÚ㇆ºüªpïv-MJÒ‘¸ïÆkð@¶>«úòBG#7c=u53ºè—ç‘Ô—,®ó‡aȸQxóºL±ß’£#¿ºn ¾¼£›ì೦q-³–¶ã¨Ã""ô÷‡QtLl"ž¸íZLïms€ÚÙãÖN1†¶(œ¼¶g©±T»6êîX¿T1ëëWÃúãódžÛ9•¤vÜ }âÚá…‘©záE¹øÛÎ"fÔAÏO'[×ÿÄâ©7bÉ#c°ä±ñ@WÛ¾?ºwŸ'%ç‘wªçÅ×õqÍšàü…‹hÖ,R,Óø«FWxM¹Ø·¨¨á‘Áâ#õ‘¾9šG¨`]ZåB*«P¤­+ÆÄÄÇ¢y-~-%Ÿo¿q®ðŠE™ÂQÕ<& áâßïîòñ­lg¹/âBI™àV%vI’Ž`ÄÄ4CS<.äíÀø¹–TÒ_wO[ÓCp®ø>q>sÉS½=y—0òöºÝ›lƒ§6»Ÿ>ðî ÷mcJ ð?![N¡ühõ?ÝLÕÈø@5U8…5xl? ¾Ši Ô >O\cöW>ŽôræÚ:ÆzK€¬½%ç8y:æâm(yzK®~ó9ª'Gaõ«Uã+Ìë·ÎñvV¿Z±4  †BÀõZ) ÅJÚA$@$@$@$@&¨Kúñ  \ìǷ÷Øî½gÇœ$@$@ö¬‹7÷RP¿Ë°¯~†¸K€íÇ]RLG$@$àŠŸ'®èþÊ'*£æÝÛÕÒ¾Î5Áˆo*tum cÍ#à¯íÂ< ëWyšË›<ÍåYWÒØ×YÏäò~ñŒ—¯©Ùî}%Èü$@$@®„ O½ˆØàK®Ò4ˆ8þÛ¿ATãe3‚í粡gÁ$@$Рðyâº:ý—OZ%6®}x\×TýÆúo»¨_f•Fžf‘´Ê!OsyÖ4öãuÇÖ}ɼ_ÜgeNJ¶{s8R €#!Ä¿‘÷pÕ°ÂøUiêÏú¶†í§¾‰³< h˜øö?î³bJ  ðwÖ¥ðü]Kôã—1&@lÄ"Ø~qåÓt 0‘Ÿ'®a’k>5–íÂÜš'Oò4—¥‘€ûØÿ¸ÏŠ)I€H€HÀß 4Çß`ü½-úµ~ü²Ê¯«‡Ê‘ @ÀàóÄuU‘k>5–íÂÜš'Oò4—¥‘€ûØÿ¸ÏŠ)I€H€HÀß 4ñw© €àŒ%ÿ¨jáçøe•ŸWÕ# !Àç‰ëŠ"×|k,Û…¹5Ožäi.J#÷ °ÿqŸS’ €¿h<Ž%¯ êç׸’¢_W•# €!Àç‰ëª"×|k,Û…¹5Ožäi.J#÷ °ÿqŸS’ €¿h4Ž¥MÏú{]P??&ÀöãÇ•CÕH€H €ðy⺲ÈÇ5ŸÆËvanÍ“'yšK€ÒHÀ}ìÜgÅ”$@$@$àï¸Ç’¿×õ#           ?!Ðàg,îç'¨©F 8’—gQ·uzz ©M]I€H€üŒŸ'®+„|\ói¬±læÖÚ:(Ëa µºcƒE„uP]y±wë&,û×f þÃŒi[ÛàåÕb²{Ñ–_~[V®Â†Í;°/'§KÄ} 1`™†_\w+ÆŽÊ®¥»§•šÊÛ{×[=}lǪÞ<©>÷mõ¢% !ËC ÅL˜¹ÈPø:´5ÞcÇRÑÁ­Ø°¯aQí0XûÎTž‹·ÿø*òE)²†Ó±d ÍK     À!@ÇRàÔ5%z#°÷ïcò¬íöååæãµUKñZ׉XðñCH qìô°Ïè"¤<sFMÂâB}šüY3°ø¢œ/œ”ãm>}1š« løp6^ÿÛRäkuÉìŠr‘*B“²¶Ó ¯NÅïÿ. 1÷¼‰¯îm—¥ôÀRüþÉíµæ.Å´¾1Ú Ëù¡¥Ä]O.Õ‡‹º™¹j&¼±Ó®NÕÇyqåŽ ð²ª¯ÁóϽ…ï6Z)êe—H»p,yYž"ßç_/Ê/ýiqXÏû±cÕJ¼={>ýï ´1éiìí½ë­ž¾´cŸëƒÜ$`^ßæfLFHà(>VœJñ=ñ苓ѧ±ý›õhÕ“7«éyÿýxñ=ñŒ‹Ÿ„¯ÌB¬B$$ â\zú…;þ®DIÉ_     ðkÜcɯ«‡Ê‘Àå!P}¾ÀRpLÿQøÍKsðþ¢ÏðοEEæcæÛë•+~‹1ï>›Sièc/cÁ²…øÃôAV™¹ó1á7_ˆ™?A†2¼Íg£»,Çn£SIŽÕ¥s}qzÝ[˜)9•â­éZ†;É¢QŠAL¼þpI!ÃÁ`VÑÎy6§Rü0üiáB,øì ”Ë[ððxÌß/Í•òþpÏïë âÔN;§RíÚz_^í²ÝIáeùr=½g2þðλøt‰t/=„r}¡pæ,ÎqG·Òx}ïz«§—íØ-c˜È$æôm&)C1$àŸJÎà€¬YgâæAÝÑ}Ð0ÜýìSQëLZÿ4‰Z‘ @]0ééºT‘²I€ê›@»ë~‡ÙÃ21 «…­è¶™xkC{Lð vˆÐüþ‰œ¢½“¥ÚlŸ^÷)æþ`ïñØxáŽN–‹´{g¡yå4<òž˜5µñUü}çÜŸm[âÍÛ|Î51—¢Ñÿᇔ˜«ºÇãwŽÃ¼\—9ì#‹¶â±©ó­áÚYOö)5!Yx}íÇèíÎì¯3øÛ£ïËyá¯^DwK¾TÌZƒiC¦[êæíß}±_Nòn‰57mð¥ÂSã7]ìÁb!n¹ÿc ǧ¾”çX¢g¡Þ–ÕùN¬Ø2 ÚÙ}­3ñçE™˜8d†å«õÒ3ÒB“æÞÞ»¾ëéI;6ÇVJq“€}››E1 2i&‘äæïÛ9Ñg3:Oú_Þ"fá†DˆÙJî<ß}.’H€H€H€H€H€H ^ бT¯¸Y ¨¶½1À‘ªÝ1yJ¦¾·_ÄžFqµƒDÕ¥bßœ<ä9Ž¢ÒRTU…"¹S_ôÑ:©,Ù*°~¡ì„Á0̸£³µ ¾ô¹ïa |o¤yQ_.؈{²¯‘÷uò6 í/rú|5Bš% )6\¯|P0ºß0Ý-¡¥ˆûàxvˆ-Ó¦[¥<Ëhç.¹Ê[~pÈ«¡Ï?";•ä±½ñðSƒpÏ×¹ŸcÍñ;1"9XçÒv5•»6x_RQ! Ý1ñ™ô9w¬÷¡<©=/‚¨u$´Nr¼W–Ø—èDÎìýùJ«€Ð¨($$Š6’šŽ´É¡éCù¢]éœJ2ë ØnÙªcU¶ý¸ÒÛEœ×÷®·zÚ4v»k²ð´>øÜ·Õ‡’P†´Ù‰(ϽèÄ4ÄŠ*JÿˆÛ¶ôQ‰W ÿ Î.úå§s±cÇ>H8bS:¢Wß,‡yªÅ šg%ÇD4Ò’¥%QK±wÝF(3RC£Ð®gtN¶}pa¨ùëôÁ]زû0,%E%¢ï•‘äÇ Ñ î´´¨¾ÿ‡å}C2îÈá<œnráóOHÏ å÷ßo„êjTWI/IŽ^”¤Rû°kŸbŸ¾]Ûvâ˜hŸURûì&Ú§£ý%%³=á(¥·<£wXŸÑETT¬¥^Úµmƒ(¥n¤tÒáIZkþM$@$@$@$@$à%:–¼Çl$Ð8 Tàð>É©äø8´tŽX¦m‘ÃȘ!á³×'Ú¾Ü-?ˆÿ¬²&¹i(Zs…¤cð`½HS¼lö>{ ºKÛx›O Ê}>iææ bσÿ¬œìp0OÄzuìúð)ÕIðèg 6w<^Yåž(ñA³[ÇÁõßÉébð‹~IvyZ÷–ܱ„b|¾l?FÜk& Hºc»Û6x]v*»àCy¥{þŽ[îþØRÎÝó–Š™oÒ­í(Ú³O?ô2vÈ;[Œ8³ì1±>”¯“§¹¸tzʳõf¿\¢+½]ÅiŠ0œº¾w ‰ÕËÚôTŠwÛ±6ÏI `”îÁ´‘ZfÞÿÙ"ôÜ1SgIý­æˆ…–>í`&ïüóù™xm±£çgŸ7c²53„…Ƚ›*>â˪f>„/?hW†OWJ‰#žÿOßÐ^¹´þVŸÄügîÁÛËŠõáH㟽›»èû@C¢FxYŠ¿…yšgÀò'ïÃr™Äñܘ&ž½ßˆ¼{ÿ6ÙZÊsDóáLC€lkŸ“ñþSáxìþ?‹7ý1púüéÞòGAÖ8O9¢äG¼x§¨\½léÊnJOÒÚ‹c €‡¸Ç’‡À˜œ5’ŸTg2á ìžóy›d<1è1r&Ü>Lìd=ŠWýs–ŠA2å8{ZÌy²-[%謡áh×½§œB|¡­|ôëm>!©òœ,NüX¿·]ûrVºg¦¾¹Ý"¢ýôwÅÀ]Jãj|ÿûïjlØü#ò‹*œ§_áž9Z Ç·BJ3ûï"R:ÛöÁªÔ[X›íÙàC87ÐEŒIåUTêËö«}‡Ö©”…·ÃÐ!YÖvÛ¯Ý1ŠŒ{j²7ÒÓ¤þiËc–)…¥!9Òú¬õèýFäTë/E~ŽJôKÕ¾Ü÷1YãTŠQö®s~ÿ¯C:S=â(Þ{–?ms*Åô&Þ+Ga`Wk}…k'<{’V§/H€H€H€H€H€¼%`?2é­$æ#hà*°äiëþJ’¡=n½Ò6ûH¶¼eï;ñø;Ýpí 6ê’c¿¹k(F|Æ2ˆž“' œ¥ZR—žÚgùò[ºÔ;Ãfÿ—p(YŽ (.¿$Öso¼Ì1?iäksЮàš&v±Óݾl7CÊÄswüÙš¸ëd¼vo¶8/©=sµâåÈǼ'ŸPÓ§õŸˆ™O߃>Æ%d‚J°o]¾5p꥜z–ˆê*17Éz”» ŸI?µØî¡ Þ×F%N})/ªÝ(̞ݢ֑ÕI3Œ£øëÝï«Z¤ÝôÞ{v¬­]TW ´<Ä2«Í—ò-”çâ­ç߯Iq‘ÿã:ääÊÅfŽÃûÏDgûk9×[Ô¦S›d¹v?µß»–,^è OÛ±n @%†ßÌ}ûŠgš˜)ñÌØûð˜õR¼nŠ0XíKN|ÿÞVf'Š™»_¾6 Aây†ûñë ÿÄw¿jy>λÿ=ŒÜñ´peHqöGÌȇð—§nEZt0öþëL~v¥H”}‡JpU‚µo;-ÊRö-ÔÎfºëÆ%¸yüË¢œ|üeÁN ˜Òݾ€F…1úÃ_Þa}&Ü=ïº}%4ž¼ßèPºñ: K 7=õ&¦ÜÔDz4]Ž˜½~<{}ý³Ÿ!ÿ[»öˆ£xï9+oA˜vû,ø4+ÛzT—‹q"¤éÞòýâIZEI€H€H€H€H€|"ÀK>ácfh$Ä— kÞ˜b[ÚM8Šf[öDÒÛŸÔw Æ ÊTJRlProܘiMiý±þ¢ùÔTsªMÙBùŠ8;É‹¬x›ONË€aÇa@v+m1>œ‹û'î“—'ÊÂì·&©ƒ‰ŠÛÈ™ðð–ÅW·=1tä0ô¿¾•ÒæoœGÆ\g÷õ:.E£ÛPù ÷h'_@GDŠAIë‘¿n·Ü´}™îÜv/lð¡dõ<ûñ¥¼èT u>lø1 k+¶|Ï ,V.ãÇáu­SI  G”Àµ¾”opk—­ÃwâêT’ÂÏáÌ©"K »¿œèmIç*Î(ÈÍ{ךÍs==nÇFýxMI O/úÄêT’ôNGçÙ]ÿ\Šïæ.’#Ä3â9Å©d ŠÍ¾³¦+3s—âÛ=޽17=ƒþi¢Å©$ål{ŲLñ£>?KñRVüDL+?/D’ˆ¬1xhˆ5KÎòºgƒ5”ë Të/Å•Gï7v¹r@ ~#– œqkou¿£ö£fàé‘ʇK±FÓ®=åX)-“¿îØ«™mn7ÓÝ“´ ¹Fh ÔÎXª/Ò,‡–@1–<9¯(û5ˆ/®ÿý§‘:ç‘Ñ4iSç#ÇŽâäñb±ä\ök– 3¦•®ÃBwEegΪÉ[ÄØ§ñ6Ÿ*ÔÇ“CÿzQu¶Ý?ï- ˆU¾4±õ9Ø?G*6$ù*ÌúÛUªÕEG±bÁëxñ½u–°y÷?‹þkßFwe6KP9mÞ¯¦wxR]•˜ØxÜ~çû\¾Ø I«ï:0«¼¢Ó¶µ ‡Îœ€$å«g{Dº¯Êï‚·–,D¹¸Î8ˆÿ-]„y‹·…+ñûñ+qÓ‹0ãj³œZu=¼w½ÐÓãv¬Uç$ F¼4#Ú†k´B—a‘óƒè£u¾¡œ9&'Ë‚n±š,òiFÿ¾âLôâøù°Xî´K”åÜö×(üåYý37"£'¤•rl‰ÄY Ž)eÎÇ+o†#òòªBÕ}»äÄ:Ç—N/Ü àéû";I×_á¦l©a+ï?Vsˆ}«°l¾å¢¤ÚÞQçGñAM|‚Œ'w&Y„¡÷üÇ@çdÃ}âIZY$H€H€H€H€H€|#`?Rë›<æ&hHªâ­Iã±à«Qíïyï><عS©$óþøæ.«Åbg”s<˜¦Ù],k¿IÞæÓÊ3á¼|þ`YŠÈ*kÙGÏas™uÍ–H± Ýz™YŽØc`ÚÆVh3êIÌ0n²®Q#$6#¦ÌBlÅ=˜ù‘Äo;6(Bw±i¸z(ã(?äãTõ%´qу·ïßÙ²Œ›š×щ×6Ôw˜_Þ©å \®Èp0Ú«ãåcùAÁHh-–Ë’ŽÖ™èÜwnŸ¸ã-KS‹~ ã¶¼à²>­™=øÛÓ{Wm‚žnµcÌ`RðG­ôÒ™vGÉIlËãIGLÏÖš§—5Lú;Jã$ÊÏsð†˜ÑgKn=}¿]i¢¬䲤Dë?úXžMkÈ|¬ÒÔ= Òî¥Gï7 ƒe%Ðîò¥Ä‡6m¦œê=á(žIcžû;lj}–ä¶ýÝG¯BúÓþö'ðÚï4Ë×z’V¯¯H€H€H€H€H€¼$àbXÒK‰ÌF$Ð@œ›€ÛœJCŸÿ/ÜÐIئÿ*U5¶:Ï\9 ßÉiCÆáŽ›† kk`Ño§cq®šÒr•ÑYýâÚá`šHuî|œ©•ò¯ÞæÓ—n•ØÏÈêF²ÊÊ_µNÝ3J/½;6ãPçs˜¡pxÕcä/‹c Øùƒøü\u,E!»¿ø"~£ätúgʃÐF™Í$KºTR eNYe•Cùº@/m¨ï:¨‹òBÂì†euh´uQ~”XšêOSaê{R}îG¾X¯òe¶¶p¯Î=¼w]”á­žÎÛ±‹ÂEB ÒÁ ŒÚT/>{ÒcÌøâ}©¼X}–hŸ)ª¼õÌõ‰ÎÙ”…Ggß…¨ÊJû´ø}Õ©tÓìÏ0cx¦œ¸)š½mT Ñ-Ð5^,å# rÖnGé”là ›3Øò¯|kòøÞ¶ýq¼Í§lÒIô˜ùÒ3ª#G+5,¬Ë^zë¥ÌQxzZoĦ_¡MâÖùéózçP¼E†Õ±ç@ údë#ÅûwªÎ­¾ÜXZÍ[ê»ê ¼ŒÞ¶å§V­9€»»tw^'uP¾TXd3¥þòqðd)®JP®«âNŒ§÷nm2}ÕÓØŽk+ñ$Ð`ˆýÐeŠg\®°(·P,‡)ö;´Ç…£ûlývwyf£6»çíз+°CšŒßW_s ‚œ|âìwËjdé<~¿iL|½ß ûïݪRP–õžcúÜp?>{/­ÿ~?õÏÖ{fÕß°£h¬X†X-Jœx’V›ç$@$@$@$@$@žhâi¦'høÊ÷ÿXfRˆå{F>×ïÈ®Õè²óÊ\ ß€6šôå(Q¿¸Ö:JRqíx1G:~økŽËS’¬!(ßÿ È_¦öøõ/5{àx›Oìé“AA}FÀ† ^)Ö‚Ú‡ÃG`@–fI;:ÙiŒ¹²·~1iÀË,/)ûÂ/7¤TàÛyóå°AÛ?ÉïèÒ[Ì«ƒ`Zavßò+‘æ•§H oÙJÔ õÈyï5l8¤D9ø5¿|ˆåw­Þ.—•…žNš}œysï:—&Åx§§«vìº<ÆÖsš\½©]Š•V¿´¹‹±æˆþ9'El\°XN¤$øP)—"кµÜ«.Ââ-b$Sxþ~cJ±!äØiÛÞŽªÆÅXñÙ:ùju°¶kŸ9ŠåîÚ š€÷Þ'ËÎÇî'íÜ“´ªÞ2ór­âr®ÇéK¶<Ýn¹WÜ/Æ‹¾ŽCby7é¸T´ ÏŒÿ³5²0ézÙ%‡x•ïR ¶|6Ï<ÿ æ|¶U,IdÓC‹r±”\QQ1JK l› ‹A“SÂ3&…É¡+œþj,IW^t‡Žë$䯛‡Gþ¨ ÆÄ sšî3\ º;¸=Í’§x±°cE®š×gOã5Ù×”6eÚGh¾TwÃvUzâÚ¯ê@‘]]aå)öf8~ü´ŠÓj”WëëÇÛòªoÀœßÿ/þ~6·í’<Oܤ¸–öcæðß`ùž“–vQ-–¦:´s9æ~¸FÌ0°êámùE{VbþÒ­8!lµÅXùÞãj}‰]žo˜ÆàLoI†ó8ïî]I¦·zzÕŽ¥yÔ+óú¶zU;ð ƒÛC¦>$ÛQŒWÆ< GJåëRløð1üß2ù9Ðu2Æf:Oˆ²†Í˜©:ÌçÝ? oýkJå¾´º¼ù{6`ÉÒ]ŸžÕØÒzó~Óh 'æ„aOcåþ3r»*Åš÷^TßûÒîï#!Ö÷9–çàÅ;§aþ÷»pZy†VŸÄ·K¾•ñ¦¡[{ù=É“´¦rh( Ô-.…W·|)’@‰2î%i¿øeLµ}P­±'¯¯]†>òÖí®{ɳœ¾›5ßÍÒ$UN çãÆžKñô¢ÅÑ6A Wá/³GaÂÌ¥b™ E¸kÀ·hßµNý°ŠËeÂ/£O¬ÆI"dy•/¨{þ±ßå ñéøõ} wÛ”âó;Ga®¯=Ä É]W.’CÒðÎÚ…ènØÛH›ÜÝóý ~+ö×Kýŧ¡G÷taÿ:ìȵåøÔ–¬ÏcðÛWpÓò;°XÌæZ<ó¬ìš…–bÓöœ\™XæD¼>¥H¬aV«í¶rÝ=óªdá¥{>Áè»?¶+J²GijiSÞÅ‚)ÝÕ4Þ–Wqj7/íK±bðÉŠ3 ¸êñwpÓ÷V–Àv¼xÇ8¼¨–(Nâ'áÖ{[–®ò¶ü¼5ÁÛ¢žßâb2³Ð93 {WmWÛ·TÜýó¦!Mx“®¥Ã•ޮ⼹w¥ò¼ÕÓÛv,•É£¾ÔoßV_V]Žr´FWåkçæFdM}òZ1 x»È²3Ç\ç kþ4ëNÃr°’Õ”0LÝæ+ÎÝõZ§Ræ0üaáRÜmsv)ЏÒÛUœ7÷®T¦·zzÝŽCù[/ê¢o«ÅýªPáø±—í —#£Ãíž/}¦¼…Oߘ ë|S½QíGNÆGk?ÆUÆ Âåg‡üñ†>—íJÙ¿F I> ÿYô2†ÊÏ)\u*‰óö#Úéú5%_cÿ Ž›>ʇ‘©Wï7N믖v¤((¿]'â/M²Î”Ó8•¤÷‘O7<­›=í1Lj$\3D3c]ãT8åüûõ±¢-ËÑx’6PØRO    ðsAsç>~qß¾T—XF,¿@lª$<0q‰IˆRfb”œAþ©r„4E‚ØG"D ‹ª³nöþx‘1¡(Ÿ»fvë„7Vò6Ÿš“U,wºà8N:‡ b¹¼j1Ù")mZ'رqX XÞîDÎäWE¢é…s@‹LtnÛÂaÒº¬ï:¨‹òªEû‹cÅeÑ)1‘蕇äX76Fq  ƒH€H€H€H€H€H€ü—@ç;ßÁ‚ëËÅö]bï.KÇú¯ÔŒH€H€H€H€HÀW>9–¤™J’Sé`A‰ªGçªæê9OH€H€H€H€H€H€û} Žm´„H€H€H€H€HÀ=\³Î=NLE$@$@$@$@$@$@$@$@$@$@$@žK¾  ¸G€Ž%÷81 4z>í±d¤§ì¹d  F\T"BéÇ2²á5  SK…¥•Øvø,ö†žÓÙŸ‰^qHŽÐ…×ÇÅ‘¼¼ú(†e4Pl? ´bi Ô3>O\'×|k,Û…¹5Ožäi.J#÷ °ÿqŸS’ @ 0Õ±d™±TTæÐöÎU͆3H€H€H€H€H€H€H€H€H€H€H€H 0˜êXòG“[§§û£ZÔÉÏ (_T±ýøyEQ= ðs|ž¸® òqͧ±Æ²]˜[óäIžæ 4pŸû÷Y1% (÷ I @ ðɱ$í$-sWÛ!¥‘Òò            \>9–â¢Â,{'Õ¶ÌäT’Òò            \>9–"B› 96"p­§æ$@$@$@$@$@$@$@$@$@$@$@$@nhâvJ&$           hÔèXjÔÕOãI€H€H€H€H€H€H€H€H€H€H€HÀ}vKá]r?/S’ ˜@€ã²&@¤ z!ÀKõ‚™… @à°›±„Kô~µÒ         €"ÀqÙ€ª.*K™€½c©1Ó í$@ š@uÉìØ° þ·ûròqºä‚°·)ºÛî¸í‚]Ø_Œ•~€O¿Ú„2Kª¦è{ë˜rÇ@DÁ•C¾{W,Æüü9'¥ò€ÈVY¸îöÛqÓÕá2¯%¹í¯’\¬\½ ³…98«¬: ¾m¢möäï\ƒŽV9Î*2„¦öÄUÙ­Hs#¨º'òbïÖMXö¯Íü‡9Ó6Ü>ã¥Ú²? =ìc5!€˜ŽÖ7Óæm>ÄÚNË‹NâàÞ=ؼv6—]ƒÙÏŽ¬µnŠö¯Ä[s>ÅJ½föÃÓ§`@Û¨ÚŠƒ7åÕ*” H@ð¤mùÖ'7 @c%`çXº„ ÆÊ‚v“ 4då?â‘+ïÃ6æô*–‹?ÞXˆiW§Ú§(ÏÁœQ“°¸P•?kÿc"|ñÒB8—ªâ­[ÆcA®>ró‘³q%Þî:_~: Aò²H—¥¾Áÿ=ù±ƒû  s—bZß9¢Ë}ó úërÅO¿WNF¬Ž®êãkðüsoá»ù:QYçËŵÇRP9V<^‹Š$¡O/Eoó)²œþV`dzñúß–"_Ë&³+$ "œæ-ý#îzr©>…¨×™«9oGð¾<}A¼"#/Ú–/}¢±x^“ ˜B€ã²¦`¤ z À=–ê2‹ ðÕpÚ¢F FLy³ç‰ÙG ßÅ£·ÿöήÊ"ÿÿ7T êb¢‚¢›H¨«®Êf!¶-ºiié/­Ú¦‘yM즮]¬t½¤¦fÒ?aÕ$wƒÊV»˜Ò⢮µ¢¡¹°))**((èAOëžó\Îsnpι~æõ‚3Ï<óùÎ{†ç9Ìw¾3=4åR¦?‹½Å¶Æõ$?i1* ˜½)Û·àÕiQ²\ÞfÄ=ó7”90Êg,{V3*õ›ð,–oJºÄyˆPªÌ^‡EŸ×ê¯4âU±ŸOEò¾m-w þXýˆ[†>R,Ò–Xù¹ƒvF%Ë]Ç1½Žs(©·[ßõTκÛ+#¾·5*)YšÚfÕ]L¶•ücðæ–-HÙôúùË™R¦Äæœ2„õ¬>UšŸ$àœ€cËãg¢s-x‡H€H€H€H€H€H€H q°óXrc±zã ÄV’ 4 ¾w!aÅJ„ü¦tÞEŸ[….í¦`Òâ¢ùØøUúŽÕÚ\˜¹‰Ùòe÷Ùïáµ1]ÌAO,Æíצ`ÆZ!·o>8‹‰Ýô[ áh¦ìÉ4a%Oï©”ŠðwÝÇàs‘Rxæ’’^ù‡O×qر7ÎaFoïR$?2‰yÒí(ÄtQ½•¬³Å¿ƒ”øHëDíÊ5Ï)5{óv÷á™Ùw¡Û}ýà_°MLRo9ùôÁ¨¤frpÛËÆÃëðÐ8¹Œî#îÕyOy*ç }Ò _ô™>­º¡¤?þ:v8’óôÅ‹°qæ:åFÖ|º‘¾·vXœjÀ”èif¯¸ÕÏý C?o½M¢Gõ9Òi$`CÀ“±åá3Ѧf^’ T'÷þ-¯ÎšY ¸EÀÞ°ä–83“ @}!`@¯û%ãŽý·´ðG'!tñÓÈwËŠä”äV•cÏ–ÍJc0kL¸•|¯'§£ßÚñØ#R?NÙ‡ ÝÂK-¿ô2ódÑ€÷´BgÉkI1Xɹ\ûííí`‹9!Zœ™¨•€q‰sî븼Ž“=Jõ ˆÄ¨1²‘ªì’‹ÞT^ÍáíðÍSˆ ó“d=BÆc kx*WQ˚܂ȇ㠴¾N˜é‹0KGÊ9eÀ+3£’’ï'¦Ï‰Â„×3¼‘qf,bÛXι‚õéëfœœðhlyòLtªAÿ!Îz+,(€QÆ}[ÁÏûÊÎü€}þ‹²ë€O«»Ð'*ÜÚ˜lCÅX˜‡¬¬£8/ ˆà×önüªw˜Céü«‚‹bSN/_µ‘ ”áHæ>üx^xC6õAç}ÞF¿˜Á\¤ö«ðØ!|ûýO0×äÓ ½ïí‡@¡sc vz%o¥åè2«Ñ0<Ÿ¼CºY)ŽlœŒÉkEm!Sññ{¡XôÀ4ó"UJúŒ}% s¶xØšï™Îbó¼ X½½DŸUă0sÓ:<ÚÕ±7«Mæwiá9 ëæ4Çì‰o‹§´uè7m)Þ|¢Ÿeˆ¸}|ÛR±õiªuFåÊ=›–²~_•þ€cŸÄçyö"ÖgŠûîäµ/®VSȳVñ³r  N€ó² ¼ƒÙ<h@xÆRêL6…HÀ3G¾úBìÙSgè¹X¨œËÜÙ:Àj²IhŽÎ‘êMb¹ÕoD‰RÊÍÁŸ†?ˆ¥Û~@0*==|¡<¡ý,Ft“Œ@U ß®ž«L8†aùóƒèi)ÿÜ¡ÝÈÈÜ‹C9§`tp.”%gÍÅnïÅ‹óå ÚÐø×¬óò©@ Oå*(²â[beyÑ©óJžÖh{›ÝÚ x· Gwµ”k²W‚zÉO¨/œ>ëKn†žâÏ=@)7qÌp‹QIœY§… Û0cå?´K9R‚Íc‡êŒJa?Ã…)ùr°hœØÆt‘•œW³VòuÞÛxÄQIºùùü¹È(üY''Î?\3*EƸÑê{(o™äàAxŽZx®Ã$QÉ œ'5}ÏÊYxñ“ãV.Ÿø—rm@÷Aƒ7:j—¤¿-ÞëÂø§ñŽø|®Å¨dè#òF¿ˆ sŽæÍÔŒâÓ¼:±º%ϺÒÔƒH€H€H€H€j€Ý¬Ø7jOÖL$@5LÀxl+&¯< Ôj}6QÙ¹£æÕéÒÍ(½ÁÉJGaP2‡+(1Šç§n;µÐÇbÉéÑHX/O<¥½ô$ÒTÙA/à‹7‡:ÜIÍâʧIè?C)¿ßœ—ÐËÏñ3üZ©\ZIz^LWK°9Ï!~D¯*ë¡–èþg9>{y–Â9 /=ÙKḠÖe{*g]Š[WMJµs³…öº¾ÖÊ1][Éáê¥+Z2#$P_TôL¬/m¨=ƒðLâ2ŒêÝÎìy2oè“Ø%¶É,É<Šbܧy±|óV+ª.¿5 M¤gÜDü1î#Œ·Ì¼Ð yâZ Êš+üŠ?ÿ ƒ¦âÝ9#ä{ Ž|2“æïeäãèñRôM…¢.õL@½7ÓãlÅ£#¥ ùx7å ú:=g¯fÈÕ…Z†ÍY‰øaâÝ'¶¦Ë^I¯¤=ó7!ÿaK?ÜÙs,ž_s~ÕÞJß<óø<$¼ƒ%§Ü’APŒ)ˆwÄEe7Ý ÑK‘òœäÁ*“±ð–\š•þu'¯ZHþ$Ï:Ü9TH€H Þà¼l½ë2*L–=–m׳á$@¦3fï!™„ϧ.°>›ÈK·¼XÕ“kÑR^‰,MðK»ãÝùƒ¬ Þz@:Y)×’IÄJqZ­ëÂf,ZÙ ¼d¤ ^mGÉQX¾”´Æôñ 3oAký®é;|0°]~•š¬öµ5Ó1•áäéS8{¦×…i.ç’hbñ€’ž—ŠIÑ©0áYŒ‹ð66ýêN^UÕ™$ò¬3]AEH€H€H€H€H ¦ ègAkºnÖG$@µB ÿ›Uˆ›®4†W·®EL°˜y³ –4Ç~zèjÞMž¬*;˜¢•úÍ~¯é"2Çá‘Ì$L~[ÙúífÌHÂgÇkÛ&éK¬0^ü^5o…$r…ŒÇØ(i6Ëz¢Ì©¼04u‹ÅŸSýðDô,óädÖ§PöD·ÝïÛ÷ÞÀ.EÉq‹W¶‡rªµvÃS9­€ªDÔ¹Áì|œ3Ý@Ç Þ¢¡}Âk”gUšEÙÆMÀõgbãæ¤¶>¸ƒ½…ÈKüµÛ…Ò³øN2Þ‹`è,Ùwì‚ÎH”µBœÏs‡­”xîØÕ&êÊVê’²ïYŸ¤œ½g#|úš0Œ4âPZý©T*‰¦·Þ¦F­?Ks‘üúHÜ^É¢IJ¼[‡¼üç,)}±ký2H?¡£_À[Ï µ¼ëÝÉk­Qݺ"ϺÕÔ†H€H€H€H€j€Ý”XªAú¬ŠH Æ ïO¶•ücݧs¬·¿ÓiäÓ!\[îpÂOä½tù¼"Q†kºEÎß±MNž8ÏqÙ臔¡˜7ršù<doÃ÷…ãÄJ1.~d¬û³¶Z}âë£-“U.ÊKÙšøõÀƒbÕ{¶¸ÈÛŸŒã.QáFaæ¯U&ê"¦btoi¢¶rاrÕÓ$të#¼öIzÿEÆ&èèk­óÒ*•]½Ö¨§o«9K¹éÜy&ÞteêI×x´T¦zÉÅ‹^¶_¼oK Ë£}Z•UjuåüÂÊØ†™K‡Ïµköù}:ï'[·82û ïØy÷Ž×@EǘaшRŸ†´<ÛRĵ_ÌÝù%b?ù«W$!W10å~° ²ˇZ¼ÏÜÉë ªºœDžu¹w¨ @]'ÀyÙºÞCÔH@%À3–Tü$hø„—Ï̉ë”vFaͧs•Ì™|["Â_Ξ»[xôØ—S„o?É—3ø÷ç_(E‹#½ÿ“©¤· @ Ë1 r†€žx*!FÉìàl&µ'Ÿ7ÎìÄ”ò#&á±®ZÅN$œ%ë,a¢uWô—ÎDª)}÷ê7ÍŸKÅ›=ÄeÏOåªImø·¿K)*‡´Ÿñ-É9¨x£½»´®®jY Üî>oŽ ·Tßvˆ Qš—wF-½rê¨å™ÙÎA“¼;£·X(`þ¸à@Ä޵ÿ¹¿‹Å°ábÑ *›“×å™#ßiÍT·¾=ž¶N3* [² )ËgaÈý=ѱSÚ:)G.Ľžˆõ_ÿÖLÕÎÝCúFdkÕ(wòÚÊÖk'ȳô U     ›LÀΰ$­½n?7™‹'¨wʱõåiŠ—ϧ.D¤·‰}“Úá·#…‡Š²?DÆkË‹1ç+¤(«‘»ÿñwÔ›Ù­É×ÝQÉëhµrö0ƒº©°¬óÙ^¹-'Î’*VXˆs1Lv†AÛ”ë Ô ì;ÄìÅ&åÜòñ>›Êñµ8«KQÚG:3Ê…PA}.H3 8'PáØòä™è¼*Þq@à†‚C”ô¼4dœ´ìKIÓÛTØaZ>‡‘Þ6È·.¤"í[; †C±F—xºÐržÖøìØ”©\E!ê—r?\½\¨åøuߎZÂDXª­+Ð^æºûJTlw×Qx)¯]3\IÈÇ÷¹Núżö5Õ^ yÖ{ÖL$@$Ð` 4„9Y¶¡aÌ­³ÝïÇû`rÒ0;Ã’“|L& zMÀ˜“†Eéº&daoæ^«ŸŒo2päL™.pÏcO@žª+Á‚§—ã¸ØþL 7ЉíìÞVò†aüï”9Ž¥ƒÜÍa'f$lF"'%ü/ªç#¡=‚[ C”Ž$ ¤AÃÍ?ñI‡Õd˧)W½•Ä:èßGYî9•#?'Å&ë”ñ’ŸƒÏCÎðÓÝ–’+×¥ÅÅ%(g,œ9c™€+<F±%œtϨ¯S©ëÔ?¿ÔVè(Z!}]©<¸-W~ñ ËÇMB–6h©KÕ³¬ô¼åà{1QvNÌšÛV\nÉ,Å|#ñÔh™yIÚ<,Ý‘§Ý?´i.ÞRlMAñqõ¶o—Ûõi¥3BpwlyúL¬X Þµ" ŒÑ“§*I%X4äì=©¾cʰ÷ýÙøÓöù¾ð>V…MêD]1³”÷öu&FI€K²ÛÙhhŒš»ÔèŽöˆ æ`Ã’QŠ| r5£’פbÊýÎÒñî‚Å»“0qêQT‚¬ôL‹QIl=7wÓ§˜ÕÒJ¯¦Í-¦ŸÛšZÝ“.ʯZ¦6CcûˆÉA[ã…ˆ°VÝ aK2‡|1é¥7*uý,Rö.A¸ïšÊt×m*³N °kƒ µ‰¶0ôè¢Î²YËÙ_y"×Tk7DìVû¥hæ ë¬ën/[9¯ÌÚ–„¸9g‰ªQÉ= ûÛTݶˆÖ¥yTŸu¼"‡Ü[ž?*Ðà› Ãn÷©âômÛ'w¯øUذb’ðW±¡Â›r½xWôo£ßPTäSßò®lö‚JŠzš!è)øBlõ:@y>IéšQIÄCc;‹3–qˆ…Wß/{véŒJÒ³{ÃÞ¹Vž¦>]ãtï~•™±sÞÁgÛjÛ¢ Â8yYœ åˆÑª·²È¯½ë€~ñ¯á³åC-ç[¹“W­º.~’g]ìêD$@$@$@$@5B Ibâóÿ;zô&O^`®ðÎ6íj¤â›]ɹ3§ÌU·o³«bù ÀÉ'8~`¿VµI&á•r䇳hahбÄ9äž.pa†ÎX|Çr…¿áv˜J.¡E`Bƒ­ JUÕ­2yciΜ>‡ËW¯àZÙu43¢mç`¡¿Ídfeñ¾…€8é ÷0ò¯·À­W.-CÞ©fûÕ¢ cu•ß'÷Lãâ#m¥VS o˜.]†÷m Q7+”žÅÅ«&Q¼¼oó…ŸŸ¯gêͪ»ªåV÷¸8òþLZ)¼ÆB&aÇÇãám,FþùR@xèu{+¨fCš‹³ÍyÅ*ƒ;ZÂGÙ*⽚Î(äý ÎÇÒ¼~MÒ6±Åâ$&±*Að÷2~o˜kr'¯Õ\M"OWI¹–¯ºyºV+s‘@ý$À¿—úÙoÔºv¨/ e^¶v(²V¨]ª=¢U`ÛÚUĦöó§Í):v²¹SµKÛuØU+Ò$@$Ѐ xù¶FdïJ]\ìxûµF¸rvU!ÁÛ·%:†ÑèQ„ö¢âL“À°HáÄ@$@®hŽ€`eWÀÍû´Ö¼¬dí\ðpu¥õ<ÏÏ’þÞ‹­ê\ Vyu Å{5Hó(Ó¥{5‡Ÿ`o º{–D9æN^[Ù:rMžu¤#¨ Ô0n…WÃÀY @-Ð AµPwC¬’<b¯²M$@$@$@$@$à–\ÂÄL$@$@$@$@$@õ‘€éÚyYíÓ×p½>6 ŽéLžu¬C¨ Ô»­ðnܨ`»†ZPU’ €§ÂÇ®AÊïâ¸)qÖø¿Ž§U9òTIð“H€H€ªŸçe«Ÿ)K$¸9ì K7§–J$@$@$@$@$@5OÀËê<¤š¯¿¡ÕHž ­GÙ    pŸ·ÂsŸ%H€H€H€H€H€H€H€H€H€H€H€H Q a©Qv;M$@$@$@$@$@$@$@$@$@$@$@î aÉ}f”            FI€†¥FÙíl4 ¸OÀË}‘ú%qòĉú¥0µ­S8~êTwP ¨·ø>©¸ëȧb>õ.ÇEõö\gÅœ$@$@$P_Ðc©¾ôõ$           Z&Ðà=–‚Û·¯eĬ¾>PWTqüÔÇÞ£Î$@$Pwð}Rq_OÅ|ë]Ž‹êíyò$Ïê%ÀÒHÀu|þ¸ÎŠ9I@ý{!  ¨/è±T_zŠz’ @- a©–;€Õ“ @}!@ÃR}é)êI$@$@$@$@$@$@$@$@$@$@$@µL€†¥ZîVO$@$@$@$@$@$@$@$@$@$@$@õ… Kõ¥§¨' Ô2_]«eX= @} ð‹âôݸös}P•:’ Ô&/à$J϶«MX7 Ô*œ $¯ÿÙ'¯Â' î¸# Oúzµi^=z™Š‘–Ž|±aDט‡Y]åVv,…H€H€H€H€H€\& KÀÏ—J]`F ¨¯L¥EÈÚ›Ž½ÿÌÂÑÜ|–^M¹Âÿy¡·Tдì|ÿ=løô_¸jÎu+zx ñcúÁ7œË•æaëÆMHýüEnèã÷‡ðª@Îy‰âN9ŽìHÃæ¿~ܳR€­ÃðàèÑv8¼è“0Ù§®£Y3svë_×®¡i»èß­µuzEW7~Fáñ,|“¾YûŽ"ÿìysûZ„Dâ¡a#ñðýaðr ‡¾HcñY;rûwoÇþ«±dþ ‡ºCÔuüÛLü§Dè¯/À..fê w#¦wˆÝÊjMi’ñËý( ¶½§?"ƒ}*S•÷IÀc.sk  Ô_ù;–".!Õ¦™h=x¤Û†¥âcßaïÑóhæÓ÷é߇Æ<¬~}òE-qaаdC›—$@$@$@$@$@õ‡€Ù°ô¿’’ú£15% OÀŒ{ŸD–ÙüõËð¹ø‰[±SîwàÁiÌÅÒÁã‘vÁZ8ñ,¤ýuRþ6AŒDÅ?˜qË`û„Í_9i+waMúDú¹i\2ªÇF"%ÏZäå#wßN¬Ž˜„7ŒG@}¹eØ>ó$ÛèoU‚ÿx|¶sü*1©2G>˜ŽI‹¨—–O¡Ç[éÛðV„à’äˆK9ö¾¿Ë7nC¾^ŸE)Þ–’,±&Fìx¾ýÕÜ¢¿r¹µ¯ËÞe“ñâÒ£°‰MX‰¿Oï©¶„Ÿ$PM<çÕT3‹!úCà’T£’Ì\0 ¡(įö uK‡o¦ ›vâË?cÁZñl7¿[ÃÄ»U ^M ¢ÒS¿yÅ+%T ~’ @$ð ³V‡%1!èÖÒ’±SVí Å”¾O›=Ãòׄܧú!Ô[Wî _ô™>­º¡¤?þ:v8’ó,E8Žù`TÒN 39¸ëå ãáuxh\’ùf÷÷ºìu…ÚÔ¥ø;Ìž¼YnÞsËA™DU"àÑ8¯R&zI@ò$Ê?½Ã[UYÿðñïããÇ„®xG¹ê \åJY Ô /ï–hv^>££ëeU$@$Pà èu¿´Í˜ÎÈ¡hþ¨ØòfñÓæ ¥²"ù%ùV9ölQ&ÿƒYc­ä{=9ýÖŽ‡ä—óqÊ>Lè6P>W¨I1(1a=E3*Ée‘x„ai—Hø0ªâsšTÁÒSÈÌ“/l]sZ¡³äµ¤ÁTÛ϶ ^ûtꉾŽd½#1)> “׿ˆ»…(±55¹‘ÇA6m•Á××Q!Ò¼šÃÛËAº¨cÃü$ùFÈx,°é#GZZ­é"¼à¦L37MFHàfðtœß,}êk¹Ò¹r0Šgšo« ø ƒyÙ™°ïÀQvðiuúD…Wø,7æ!+ë(ÎK"øµ½¿êæPF:°à¢d˜ðEPƒÈ]†#™ûðãyq"[StîÑámœŸÉVxì¾ýþ'˜kòi…Þ÷öC ÞÈoÖ€¿$eÅ%øñ›¿šßåÒõÉŸN °µ?Œâë@@áÍ«nuk*CÁ‰È;yÅee¸~½)Úté^úRR0™`º.½m_‚æ»õþ—Ýø4áпⴟץñyŸÎÎ t‡£DJüíäfáÈO‹¿‚¦ðññ3÷KçNá£öJÔ¼ª ?I€H€H€H€H€<"àõsÃüÇ#"hœLçr<Éo<†/Òe&†al‹Ç«=î‹öˆ<%ÛSqdþ@DJG1ÐwyâS„G¡·cÀ vmƧì/ðCé(ôrÅÀâÛÑ!bEuµø ìì· 1ä‰Eã±Ø¨•¢úuªvšÝìíÖÊñÓQɨT3áø' 'æ¾ýD­® wU—CïÏѼàfnÚ‚f‰#±(½fx±  ”Æ”AO›=Q'nJE¬%˜¼Xxžêƒÿ`¬ß6×ÚKÓ|¿½’€·Ò=Ãð|ò é¦óþ2G6Nzá¡2¿ŠELÓ j•±¯$aîÃ[sºé,6Ï›€ÕÒûÅ*aæ¦ux´«d¤b°(ÃÃ[AøùKOš½¥Êêýsdã$¹ÿüÝ;¿PWlŽZÆç$¬›Ó³'¾mwžd¿iKñæýä7JkÜåˆÒ°`¬è<{q‰¢ozëÆ³;yí‹c €›~qò“¿ãê•ÿ¹)Æì$@$Ðpùê ­1={êŒ2 •s™€;[XMŽÈÍÑ9²‡"+V‘;0Ô‡vÐMz¨µ‚ÀÐNêši±Ê"D‰R2åàOÃÄÒm? @•ž¾PžÔ‰~#ºiÇ„ÛxîÐnddîÅ¡œS0ºy¾“]aŽJÿ£ã…»\1˜9*Ç…´Å{ñâ|yb74þ5ÄËÛ º ZíY\Õ¥ìpŠØñ€¹þÐiïˆIÞ”V»:,H º Ii«4)$Žn1*‰3ë´paf¬ü‡v)GJ°yìPQ) ÃâÇcØ 0%_ŠÄýEVr^Í”íØòÞÆ#ŒJRæÏçÏEF¡þ Tá 9~¸fT ŠŒq£ÕwF>Þ3ÉÁ9‚VÕ6Ê‹À>A6í6 (DJ B›²«ìåÿRòÐ}Ð`ÄŽ'6Ê¡$ýmñ.F@]Ðú¯m3ácÓð‚Ö¾¼u˜¤3*”3¥ïY9 /~rܪñnqÞGŸÏµ• }b÷Áè!÷Wsý—'wòZiÄ      O ˆÿ– Q^*oÉái!”# úJÀxl«6ÑD!¦‹:U$¶Ç9wT9'IÜÑœ¬+ Jæp%Æb$qáÛ=ÅäJ®8;'wËW(|ªšˆ{Z(ÂβqAKr1úØB,9= ëåI¬4±²:M•ô¾xs¨Ãm•®•Ê™JÒ“ðbº*„asžCüˆ^eÔ\®–cë\ù|%IÆ­óŽ\¯DÉYŽÏ^ž¥ôO^z²—H×3v»À*¸¨‹ñ¼<æm¹žˆIxë‰n"®tLj§( @mÂ3‰Ë0ªw;ñgüæ }»Ä3¿$ó(ŠqŸæ½RðÍ{X­è'<[>~k”ò>˜ˆ?Æ}„1ã–™$O\‹AYs…)ÃñsÌ0h*Þ3A¾·àÈ'ó0iþNQh>Ž/Eÿù½U(êRÏÔ{3=þÈV<:RZ|wS¢¯Ósöjƒcm×éƒ!o~ˆ˜±ÉøÝ˜ufeÆ%ÿÕrf¢¢Þ=Çâù5÷à·Qá­ôÑ3ÀCƒæ™û/÷„dcÁ64’Gü°9+?L|—[Óå ï® Šwמù›ÿ°e\»Å±I).*»^Š”ç,ðšŒå€·ä"®ü½¸“×¶xM$@$@$@$@$à_´Œ[7ÜÙÜ#a ‘ @}&`:“aöô‘Û`Àó© ®÷°ñÒ-‡ÕEõmnÑR]霃ÇÕ­‡Z¢ïÃJú…T¼¼~pfj¢ˆ•açŸ"& = ML¸R~ٱ腜s4‰uÃbcÐ=:¢{ˆ‰K5ä#íõiøÝØ$ÞPõSï¹ù)V g¬ˆ·lé&&Û–˜Ï;r³³ïOÔêŠ]’€PÛs\,§:²¹¦‹0º½ð¤²•U–¬¯M<_«%X @ [o¦þE6*Iµú¶Gx[¥z_½‡Jv%ªÛ§‰¿û—U£’œ×¯Û£Xïµ’jÄd×°ÀÞC0$*D3*Iš´é‰GBä¬Õu~¡\Z}úmÀ3b»ÀY#zjç…ž…¹b»_9lC†n\»Ëñš²v'?óŸ8Rl·^ÞÍí¼ÈÝÉ[ŸSW    ¨«¼n»CüGz¶®ªG½H€Hàæ(;¼#Ç(Ûlj*žIÞŒ!œÙ›y OájÑE-µ¥Á’§×S/£ßzÙ%¶ƒ‰Þ…a½ýýÉ6³'“&äV¤;_†?¥É¬ñSÑúè_’®´ö%áñ{bùŽÕè [õ.¶Þë/¶Šë¯Ö%Œ@ù‡¾ÂŠ™¯adàÊ^'Œ_=°ê‰H5‡›Ÿ%ØúÒ(,RÏô«ò?{sÕœ›VœÝ”‹¥7Ëy¤ Ô"®koÅÒÕ{×E]޲@3„ML^…¾~ª¾^–yá›~þUõ6¥‘@c%ûF"b­Þ>è# 9Ù96Nˆ¥(:­P ‰Æ=v)íЧ·ÈpÀœé¿?ºÊçæYØƻ󭟧Þz@:Y)×’IÄJqZ­ëÂf,ZÙ ¼:¤ ^mGÉQX¾”4~¸LÀTZ„“§Oáì™\&ºœK.‹6ÌŒÀ0óö»ê;Mnf_qn¶ËïéR“½¡Î%Ž7|á `ËKŤèT ˜ð,FŒEx›¿wò6Ìž`«H€H€H€H€H Æ XfAk¼jVH$@µC ÿ›Uˆ›®&†W·®EL°˜y³ –4Ç~zèÚ^rwR&W¼»`qú{X:ElU—-’³3åO ð†ã ,Z/O&ºê±Rv0E3*õ›ý^ÓE”‡G2S0ùme[¸˜1# Ÿm´xĈLÖAš‚ºÅâÏ©~x"z–yr2ëÓ([³ù¨ú[K8¿2ªñ#‘"µQ„Ð ñÎôûnžQIÔñí{o`—¹6`Ü¢Çm¶TnÔЇKºáUó¶U²RÛ׿ŒýWåý}Z  {v¹Â9e_ktüf=,M3 ÔEÁì-D^âéiJÏâ;Å;ÕÐ#X²ïØ‘(ÿ„+…8Oæ[)ñíÝ®6QW¶R—”}Ïú$ÅCÒFøô5aap›@i.’_‰Û…ñÁB ´úS¾ÔMo½MZºÃQ|Wòò{88\œ³¤Œí]ë—Aú ýÞzn¨æù wòZkÄ+      аä!8Š‘ ÔOÅû“-F%ÿÁX÷éëíïtÍòé®­ w8á'ò^º|^‘(Ã5ÛE¹~]0kã?1æØ!ä«››6E`ð= öBò# ¹ ´ô¶^é«SÁ*úýÛäká¥óüèp—å‚¢â²#óFN3Ÿñìmø¾pœ8wÃJÜ_<!V½K†¼ýøÉ8áÒ‘.‡"qP¼Å¨4àaìzX2v¹Ö—«Ñe¼Q˜ùk•‰½ˆ©-¼Ànf}ºªí¢.ëbºå˜sù陊жÈdí+ÁñðK˜e{‹×$@u†À5•)Wrñ¢Øbû.ëpÃX¢=ôÏ -W©«8bel ÃÌ%Ã皃e >„áŸÁ-Â3u޽㵠AÑÃ1fX4"‚Ôg§!-Ï­ÒEæ[™Q=á(¾GÍÝù%b?ù«W$iß¹,ÄCÂCoÇò¡–…,îäm½ÀF’ ÀÍ%`ûÿíÍ­¥“ @m(þ3'®S4ˆÂšOç £RFß–ˆð†±R6w·ð艷õè)·ŸäËåù÷ç_8n\`§Hv²Ü“ [òäë Ñ¿GG—žÄ%øO¦RWÛ´°5 ÐO%Ä`×KòîÒyOêî–šmczKX®è/m³:¸þvm‚vP|÷Ùï(F%«1i÷ê7Í¥KEŽ›=Ä}«ÚÐÅ÷.$¼1…ênÖ¬ ÛßX&oI2s§ô„_û»äd @½#àÛQ!âý‘'4Ï»£ø°5ê\9uT34÷Žl'rx¼;£·X(%-ðÀýVàÍYÁ{ÏÃê²Øñ´ušQiØ’M˜õ@ˆÒÜr´uòÞoÈ<¬Úæ¤ýgŽ|§eS·öœ£z=<ë‡>ã{þŠUíôÈ**¶–Õªwòêå'    p—À/Ü`~ ¨ŸʱõåiÊ™<Ÿº‘•Ìl‡ßŽçfH!ûCdœ±¶¼s¾Bв=K÷?þ.zêì~•fñX¹|å·I¬^/8sÖüSlÔo0#¬OêNöaœ¶VÅ,}]Ûß(áά\úÚLçñ£4 )…(„Øì­ä\À˜óf(žC†A/`ù˜nr9žþVÛV¼d[­œ/ Æ n•‰³¤Š–â< “«ÖWR¬¤¢{ºÐkp,büÄ<ð~ÕVntèÐáˆ} }à Pà-¨&.Œójª©ñsÃÁ!JóóÒqÒþÁ½/%MãÓ6  rÃÁÁʳãB*Ò¾-ÖÊe¤j®^.Ô øuߎZ\¼ Qªy”i/`ÝýF=]ˆ‹vÍ,ÁŽM™Jj¢~)ë*sÛÝuÚk× WÊÎÇ÷¹Nƹ;yíôg €+hXr…ó Ô{Æœ4,J×5£ {3÷Zýd|“#gÊt™€{{òT] <½Dz«ÐâCbë¹·•¼aÿ{Å¥J‹ph.¬CeøvÓl¼øâyý~ßÉzýú‘¤IxlÐpóO|Òaµ4ñéƒÞÒáðæ°36£@ÑEJ*<ø^ÔÎñiàVÂ¥…räç䡨¤ss2žBò3cð¹’ÇУ3üt·¥d纔áïK—i¥—ˆ&Ù¿ÇŠåÞÌ ddþ N²)THKKP\\‚²Òó–ÃæÅäÔ91C'¥+Îk5È‘SÿüR[Ù4z ‚*3ä•F¼Âò±A“¥MZ ®1],UÚÄtÍ×éĤ ^V?OÇyõkÒÈJ“ÛÑ“§*.Á¢!/`ïIõS†½ïÏÆŸ¶—È÷#&ah˜õûÀ-Z¢®˜Y Êû Hž8«>9„2å¹o2–!ÿð^lÝvÈu#»[ 4ÜÌ&ÝŽ‚_~²G¼×ËQxògŒBržÜîÜ-{PxÃþ}×p©(-F̸˜¹Ø™S¤Œ«2d¬] q š‡P/ÙCÎmŽÆ\,;›¿9„Bq–“9˜Îâë­_+•ážPÅ]ɼŠ4?H€H€H€H€H€ªF@?óXµ’(M$@u˜ÀÏ×õÆ 1Á7yšCm VâïÓ{j÷šôÇ»K#.Aœo”—ŠÇû~ЈÖ8—£yÅ­Xˆ^~Ö[ •ý'“'&™Ë1„„!\¸L? F1[¢;@©Ñ«Y+“ O-”4õ#|ôsè·òIóì%éoã±¾A÷è®B¯ÃÈÊS&'Eæqk^Ð&r̲¥ÙHç/I¥Eô@p€8Ø]èb QXüü@qö‡u*Ò¥T• I[ˆÉi–Ò,1–ïÞŽ^V‹ðËðáØÁH̳ä2ÇÄäÔã÷¦*‰AX³{‹GY9²÷Z¶Ö8@:Ë©ò`ax«ƒÌ5«‹˜D5@ÀÓq^ªÕ³*ô½ŠT×›ˆ½Ãâ°<~·ð𔞹™Hò Ñ0¼¹x¬X>`ý v±â¤€ñ¾:"ÞW›ÍùRæ?”ù€Á߀’ Ê;Â<úî«ÝÃ*.µÑßíÜÿw€â¡»kñ,ìZìÉ…Íx¤Ç6ÌMMCl§æ2X’\G‰:»°)¶áãÌ Æ™åÛÈ`¼öT/¡¼<®Ýæxç%dgÀçÓŸÆj (ê8–®£Ç¢»:Mnä•dH€H€H€H€H€ªL€KUFÈH€êŠ'zÔ6t °7@=0–ŒR²” W3*0qM*¦ÜßZ×>›ûjñ’¼³!G6ýâ_Ãg'!PYÅ«e‘¦Í-¦ŸÛšêo‰Ã9º`ñî$L¤¤— +=ÓbTÛÙÍÝô)&Fµ´–óº–dùb’FoTê>úY¤ì]‚poû ÍŠtif³mžu…êUWÜê`ùB3{\ª€òÙ^vr&\Ô&”ÂУ‹:›d#juÙTk7D¬vu±RÌáE@KKß;ÌÀDð€gsVÖ`Åš Ú 3¼]P_1¾ÍaóäF¯øUذb’𲴡›r½x®÷os‹õMõ]`e˜·Î"]©çרw‚˜‚/ÄV¯"ÔXŒJ")4¶³Ý9O–œ7vK q ¢l™útÓ}Ps;ç|¶}!BÕ$aR9yY:IK§ýWÉ8’¥ëÏïˆQxõñ²§œÎ¨dˆž„ {ç"T÷ÝÂmŽÞ­zj $Úwå{ÔrÝâwòÖºÔ”H€H€H€H€ê4&‰‰Ïÿïèј K¯½oEÄ€‡ðcAhÀ-´£;ß>ý®šsÝŠÞ#žBü˜~ðÁ äÄ-S9 NÑïþ…íŸìÇ}¯.ÅNÍË‹ðíN¡ã~UG …/à„ß<8Cw«¼>Ç%;M-ÎÙ‰UK7 û¬ÄCÔòk<5-};ù8–)=…Œ|ëÍš9¼íZSDÄ܇ ïJ¸8”Ö%Þø…dzðMúdí;Šü³çÍì[„Dâ¡a#ñðýaðª}úL§F}‹rœ;;ÎE{ÝyÆ8ÆÃT  j"Ð$1ñùÿ=z“'/0ܾ}5];Åœ‰¬ `Å­Ø‚)÷·³ÏaÌÅÒÁã‘vÁþBF!åoSäeoD1ÉÀ+/¯Â®}ùV‚ã’·ab7ƒUšzQv0¿—¤^Úúdž/g¡c5-‡=¾íu<þÒ6ûzDŠ3•ê(É&nÔގÛè°2‰G6MÁ¤ÅÜQ’"û$ÇìáaŸ9¯¬îÜá8w¿/ê8÷äã>½Ú‘¨pœ×ŽJ¬•HÀCêßs«À¶–psÄΜ6Ü©c§j­Àëÿ«ÖòX 4JM½¼¸½l£ìy6Úë&¿a:Ã4 ¨ ¦+(4×c@lüð@¿nhÝâ:þýñ:¼õl¼H™þ,z¥oA_?½‘¨ÉOZŒJf/ÄS1³}9þ´2ÈÛŒ¸gÚà‹w³ó$*?wÐΨTiS½d/ &a@ïè|;.Û‹u¯¼,ɰu!KÓ†bÕˆÐJ‹ª,CñÁd‹QÉ?o®GÇëÿÁŠ©ó°GÔ•2}$Znù£Âl<—åò 0ø[×T"d;´ô¶NôàÊtù¼YÊÐg0Æ><Ýî„éäwX7}™l ÌÞŒ„Õ½„ž}mJ÷¼Ïl ª—çv}ÖpÇ9àÑ3ÆŽH€H€ª“€W~Ö9É#žH€H€H€H€H€H€H ¾ð½ +V"ä7½ ó.êøÜ*ti§zÆäcãW9è«3Úfn@b¶Üøî³ßÃkcº˜/‚žXŒÛ¯MÁŒµÂ(µo>8+¼¬ 0ÍÛ݇gfß…n÷õƒÁ<61I.¨‚ß>ác±ãÛñðÖéˆà¼‚Qѳ ù>•É›ñUPŒ ·Š°qæ:%_Ö|º‘¾’A­§0%zšÙx³ú¹¿aèÇãíŒf²`–ïNB/³œ Uº™¥óƒÏaILú†µ´Hv Áª½¡Âûìi³~ùë?BîSýªÛv¯*}f©¨žÆ8Îm:®áŽs©¡ž¿h¶·yÙáÝ6ÝÕÔk×Õ˜ÍçüóË`ïþ_\nsï&^–þG3ø!$ wùêêª#}¦Ó¨ÎD9ÎÐ8¯3£ŠŠ Ø°ÛØæà5 @½&`<¶“WŠs’Ì! 1] Z{ÊÎ5Ÿi$%Dé NZ)" Jæp%FaxÒ9”;nó°ê•Õ8+óÈDnžRBÈp¬KJ@xUÏ4jRŠ£™ÒiM"ÃL{G:›®k-»z銜Wýmº¦Äò‘üÒ j*‚úŒBÂÜ èl}Ö”–¡Z"åØ:W>_I*®ûˆ{á§3øÕZŸUKÛn^!ç kœß¼‘Â’I€H€ªJ€KU%Hy      ¨ÃLg2ðôð…Š†<Ÿº@mt {éNÒEu9Тer™ƒÇeŸ"ý}Ïâ—°{{&v‰ͨ$t©EçŠ=+R/uÃ÷ PÎ(òm‡ëy·€Ö²ÌïQ¬;?ªùw£_D ƒîj.aÛ·3†<ˆÄýEúÚª/.<­2VÄcQºRä yXbsîj­Ïª¯™Õ]ǹ ÚÐÆyu–G$@$Pmè±Tm(Y Ô-e‡·b䘅ÊörÀ3É›1¤Ss§J6óryµéÅû«9a*>…)˱`m¦9-yâ|ôÙ½‘:Ϫü‰XñÙ îp~(S¹¨pÀ¬Ä;jE ¶¾4 ‹¶+Æ»è©øìÍAðÖy+i )‘í3ÛÊëÈ5ÇyÃçud¨Q   …@5}$O       ºD ÿ›Uˆ›¾YQ) ¯n]ëĘa1pü÷'q&Q׊¶xë®æ=ålÏaò åMnA@p;Y08á½c0z”0„” aiÓWaø·¯¡£:sa,ÂÇÛwjF2ç5vÀɰ$eP›’s¦–²‡ö Ù·Ë˯bãï|ÖKù°ïÇbDv3h¥]8œ†=é•{tù™bߦSX5~$R²åâB',Ä;Ó¥v8Ò©–úLki݉pœ‹¾h°ã¼îŒ3jB$@$`M@ýzfÊ+ h LEÈHKG¾Ø:½kÌCˆlcùç¬14Ÿm$  ÆJ øp¶gB³;ÂñûÁÝœLÚ6V:lwC!P¼?ÙbTòŒuŸÎ±ÞþN×PŸá×¹â'ÿÄ%ÝKôÒeap2‡2\3YÒ«;æ6oƧbòZÉp“ƒ|±#^ǥ߻ñæÉèÔÔʳÈJ‡ë׿NÊyD>èÖGl…·O*ë¿(26AGw‘$w£´…JW¯ YB÷A¿̆%à`öi@gXê,¶|³»Ð°©Ã÷Ì¥K*vì¢ß‹PJ.B²Î¨4à•÷ðÚÃ]Dº#£’°#Ô¡>37ª–~qœKã£áŽóZV¬–H€HÀ4,ÙB*=…Œ|ëÍšÙÞ1__»Ö1÷!ÈÛñ—;˜JÄDõ|¸)Ç…Äm¸!A¸ûî®èÕúvÕ¹ñ‹}“ gá›ô=ÈÚ'K={W…L‹H<4l$¾? ^N¾D:Tމ$@î0æaõëËÌÇ…=@Ã’{ô˜›H€H€ê-«°zm>à?͆¥zÛ*NŽ ‡™×)÷¢°æÓ¹Â¨ääX)—oKDø ÃÒñ³ûÊâ»ÙxîáÛOÄߌü{"ÈÖ&"ß©¶ß-nSÝ/òqìlú¨×>ˆŒ²lMçJ…þíïÙd#ÕáKÑ«›Z–,]’sÐüÿ€tÕ»‹îÿuùv¥¿ /[£|‚#Ñ?¸R1» ß®M@¢â©Ô}ö;ŠQÉ.›%¡Žõ™E±Œqœk°ì8×ZȈ[óNpÞ‹oÖúfmÑÿÛç¼*ÍÃÎ÷ωªÅ^»üò¾û…¡þ9ÉS9µ@!¿uã&¤~~È KÅ|½øîã„ß<8CÅÿy8ku6ð K6\öã6¼øR’Mªõe\â6LémquWïšÎìÅ‹ƒfaš >%øü¼d¥ïDÊ–Ëølç$eåpäƒé˜´ø€.·ÍËÇ[éÛðVÄ(¤$ME“‡¨½ SH€Ü"àÕÒâGé_äæor«Xf&  ¨Û¼šµ Šo·7sîõP·›@íH åØúò4³÷`Àó© ­Îr,Ø¿†4ÉK(ûCdœ‹Ø6Ê„¡0æ|…at’B÷?þ,€´H‰¹I±TÒýP†CÿPÿOC’ËñÄ¢+eö"¼±¶™ylùxÆu‹Ñ‰•ãkq攢0´O ˆV^×ɃßieÜÛ³÷4bÌù3ÌZ¢Ç½€åcº¹ Gõõ™§z×®ǹžÃçúVÊñª?cìˬë)îÎ7:jÏ Ló‚bHÂòÝ[ÐËf‘@Ù_áO•̉ªeëçF=•“Ê*>øÆŒ[f·ÅiþÊyH[¹ kÒ ÒÏö¹\†í3_@²ò^Ru²ú‹‡ôs°ê½ãÛ^Çã/mS/åO1›žŠ¸[0å~ûgzMΫŠåï[Ù&¨ï'5U|{]¿ »ÄϸÄO1±wKË '±½Ë&ãŤY/ñ~™°ŸÞÓINëdWäLg2ðÊË«°kŸ\¾ZBØe£ˆ:3|yÞwžÀ=Ëþ“Šÿä9þÕK†c׳*Ü^WåÑ?=ù–W)ãõÿábÙ5¯ÿlÎëÝôÜáÓ ÞMQ©l­gðÒÏ.`«¶ô¡D<´:´tp§X)3Q•r•̦½†'~ûK˜.àÇœãëMIØã{›Õ?®&e+CŸÁûð@t»;¦“ßaÝôeÈ’ÊÉÞŒ„Õ½2½¯R*?H€H€H€H€H€H€HÀ9cN¥ëîdaoµWÍu±[˰_!¼eåò==ÃÚÄä^ <½¿LI@G±SÇâC˜7òm¥À0Œÿ}˜ˆÛLò‰UÀÅ¥b"ÉËÏj•ž?c© F±už·¯¼u‹&‹ïÄöŸ p_}Õ ¨ì\;oíS‹¸ þþýVïºô鉧F!AL¬•¤ÍÃÒßt¬BÌ¢‡6ÍÕê ŠC¨ÍÎ$ÆâS8sÕÛ´ªò3“1ãõLåÚ€ð ?ížg‘2ü}é2M´D´÷Èþ=¸bÕe×q],‰ûU”õPUê3­Æúá8·é·<ÎÍ-õàcC¨þ^z0ßhߨ"¼÷¤jT’îÞ* ÿ‚Õœ¨ƒûÎ’<•+Ü‹xͨ†gV<‡þ¼p`óXôäiº“‡/Áßv&Ø-hðm+n+†%ƒ¿åmVñ‚Xæ/ ؾ>Š&[ŒJþ1xsm<:^ÿVL‡=¢¬”é#ÑrË—fy7šË³jßÍ+–꓌€O©F%ÿ(Ì|)‘íoÅ»S±`¥lKž¸Ñß.A¨î½jÖU÷«0s•ùÝin[´ïÎæÎ·hÕ‰ÁU¹òsíŒJúrœÅ=é;Ta¬x¤§Òç&L€Þ=Ð1øv\>¶ë^yYÒ¸»Š¥iC±j„´‘pã 7Ű$•þýÓEœ.‘6v®v†øU‡;ÐÆÏöOº.ƒÖû$a½·ùÂìHe±¥ÝÎEó4£RÜŠTaáVÜ-ÅA¤¡Ýz"vÄD˜LM¬¶¶ëüàsX‚¾a: s§¬ÚŠ)}Ÿ6—òׄܧúÙ}Áu¤ÓH€H€H€H€H€H€7Ÿ¯—ë”`ÑäiºkKÔvår“€þxwÉ`±BZLZå¥âñ¾_#4¢5Îeçh+ÉãV,D/»•ã@Ùá¿à¡qI–•XZ¤)ñ øw©å9‘ñ®yKÊÕ"ņðI? Õ%eœ˜<¥Zvðèûì" û\è"&ƒ$vF„áÎÒ³ÈÍ“ö!d–Ç÷ëÿÿsRžg=‰•ØþAèÙ^pÉDVž$ ‡~sV FçÙ¥¦»ûY*íQ¤†´…˜¬BSÓÌŸ1G±ÝÊà*}fUt=¼à8·ï´†:Î¥–zòŒ±'TS<œo´m©´ÕfržmªýµO×qر7Îþ†Hñö.Eò#C‘˜'ÝŽBL‹1Ç#9ѶŒÕ¯jT¯nO{ž=·fcòJaÄøï틹8ÞÖÎöÝ"ig úgz6Î\§Ü’¶ˆžPæ9ßvXœjÀ”èiæyØÕÏý C?ïd›³›?W,)(mѪ¼ðæ§KÐ_™› ›ƒˆ@#â^Ú)r‰9vé¼Cg3û 9{²âñ$B\ nÈ5owž™}ºÝ×þ[ðØÄ$Wk1çs¹ïª8V<ÑÓ'|,v|;ÞjA ‚CðvjFEÏ2Û²¢«nµ·!fv6üªÔVÉSI2*;/6 TBøõÛÕh½ùth½w¤}Y6lWþä½f1*Ùäõ²±"ûtê ‡¾HÞ‘˜¦VZˆéAÁ@u€ñ,¾ÝwgН‹ÃhýÐþ±ÊQìÏZ|æÄBDø¶ ‚ŸÍ*?Imca²²Žâ|™¼ìίíÝøUï0'/jµ¡å8~øþóÓyH‡ÛBÔww_!T·ªRÍ©ÿ,ÈùY?œ+úšÂ§Uô‘Võ‹‘/=¼|¤[m¨—s/ªð“H€H€Tž¾_ù@&h*>‹#Gãôy1{ÜT|Gñk…–èÐ)>6ÿ#ü Ž;~zJ@õþ©X¾cÀ­v‚˜ƒ K xܼRº¹ÙêÔ–׬Ǹ(Ç{ðºÍ®,Û„€Û¬WJû·—ŒLÂh#B‰Ø>~OžSBH ^ýsbÂ,—ê->½B0k[š?9)Ù¢>±Ì= ÿoÉx»ÕðR=-nS¶Í¼/¶·—u5×ïß3½ˆG{·óH[¡f6‹ãmïË×]q«ƒûÌq%õ(•ãÜ®³ð8÷äcǧ>&x8ߨoªä¥£nµ©Ow÷övü·Uœ™¨• ¶a“Îí³.Ám¹&Å8x@~ÇFOÑŒJj©‘x„ai—Hø0ÊáR U ’Oã±tmKׯ̰Þ"Ö¯'¦Ï‰ÂÉ5Ï~;X}Ñ7{®XªËÔT}§Á`ã£Ðá.‘C2,åy*IÀ.” yŠº%®ÝÍ Ü“ó ˆç=Iïraü½ä2­~WûU+éÙäk£’¢u¿{0(Ú™ˆZciÄÁ×’FJÂA³…¿Káø×[¼•†÷tI¦âLåøé¨äòÉ@u‡@Øòá“×i«&Tͺ CÖvy¼ê÷Ø•ïá£WðVš£ñ†ç“—`H7ÇžRh¡Øcw¶p‡ÎU+Ñ}†Ž~‹gE@ýÊ‘Át É ‘˜®þó«…ô@÷¼æ•'ÒÝŽöØÕo‰šÎbó¼ X­µ;A˜¹iíêÞ?¹Å‡·bîÔ…²Ë¬V–±ÑËíö—Æ”AO›ÿ-Ÿ˜œŠ_îy kX×ÒçYìx÷1d¿Ÿ€Òª}ðŒõÛæÒ3RÏ„q  ™€ÇïW~aëŸç‹í\lÞËÊø²ýîÄïüë>]ã°;ËñŠsWÊïøÀ¤ï#?œE CS”ˆ¯×!÷tA@ÿ{RgÐà9H™‚ÂóqáÂU43L%%b‹¾ V[Ϲ¢³Ky¼ÅÎ þÇÄB¯üë-pë•K@Ë„w’þ±ùßB)0ôÿ–âã˜38wî®\».‡7EËÀvbKœmÑ–KuW˜É£Þý'FU˜G½éXOOúL-±¾~z2æômõ„™'urœ«Ô«6Î=a¯Ö\Ÿ?«<ßXzsÇ)^:bN e7r™ûHL¹x]õ~4zK[€:~Y^‘\é)|—'ç.¹h%%_ÜŒƒ Ø%ÍÉdJGYyljͬ-hé6‘c{v))üæ×6wàžÒÒi®¤Š9®Ø'ºØå‘jb®Ø —•ºóñÖ꯱jú@ŨVޝ6~(ßž¾m¼—½?G3|ÌÜ´ÍGZo‘«”nûᩜm9._»Øw¨®±â²bÎ3Þ(ü7¶ˆ*æàªþ΋«÷whXrÚ…WðÏ/ÿK› (´‚ü[ì%ñËEùJ)=ÓÃù™Ÿ"iË?Ppõ*Z´¸a¿ù=F ë?»ÕˆN*/ý¾HWî…Dá.›UN¤˜L7@áþD<69I+?tÐpôô.Àö4±„bT’n6·Z P‚Íc‡bµúÀE†ÅG?e"Í,“ƒEㆢÀæÀAi5Í#êQfPôp ¼[¼Þצš M¹,Ä#‡.àã ãuÆ¥"$>6RçÚ-êš‚ý_cO¶bT’lëêÝb•ÆøáÚ‹8(z0¶-FòÒ— ñb3 íÒ· ¯ƒm@¤jlƒÔ¦‡tm‚`;:å§³ñït±µˆîàpÚ/žä¢RéI”8n¸V½!$H¬þTžOû–áîº/ÒÄÒ¾ÃR¸° o|0ë|q’3ñ7 @ã#àéû•ßä±"¾OˆïB‰Úw!é{Í`ô¾Ãˆìß™·àjÞL¼Ä•Àï* ~Ö^¾­ÙÛ‰wR5*èåm@`°ôS…VT”X)¼“\ ^ÍÐ&DüØæwaBÕVäÿ³w.pYTéÿ¹€¢€ ¾( ¨" ¦¦b†–•šZjºš¶j¥¹VvÑVK]+³ì¯•™¹^*u³ÕÍMÜ,µÕ¼¤a®¶Šá%Q!BEA¹Èå•KþŸ¹Ïû¾ó" xžóù¼ïœ9÷ó33gÎsÎs®óùºf×¹74ùÅŒÛù ½¬µ*³ª7`Ídi›  ð(üO­4ÅçÀG3°WŒIªà¦ö­°`½¢ñÂZÒø„½ž×4‹ÍE›á&]Ø ‡÷`wB.¼-A$qÏgÒòrñL¦«9¼„þ—m8÷€HÄ«¸ç=M$067f¬ØçŽÑ kÄÕZÉ+fâÁýG±lÞPd|1 ïÈ“Ÿ_œ3 >vuÊ\pd-©”˜…MúMж`¶õ¡qµªÏi‚ð¨Ðµ³K§*mÅ.©JŸæüö#='ìE)Z¹<,’޶íHôªCÚ—Lªt¹U--–½Ó±êÕijÐÀ.#0eÆXt"µ_öÆ•äÆ’9ˆ—Ç £eõò@®ìºwçv¬š‹ù›ç¢ë5õ/_ÁÆʃˆz·áƒÂ¾ |ήZ 4n¥šü¸åë1ZþÈ|vê¬yý%ZÕcÛæ…À»>Ö„J=ŸÃ†÷GÈ‚ qxrø—)oиjÜô=4âÃø<>QuÞ’ºåŸQ^ÒŠ¦qÆàËWÇûâl•eXò]oÒ±+©žÈضD*u-UTYÞÓ„µ˜2ñCQè‚|µåZ²¨ìÊ PŸ×WbÆÃabøÇÙˆ!ÃæÒK$K×&¢«NG¼óÏàP)pÐ4,™5P»¯iÒ«ð^Fæêï˜w,Þ^?ƒ6½ô†õ4•y°PfÅâ™åïa„ ¶ƒtç*z„“·'¢à V‰§Pâ#`L€ лÜäû•ûRëÉØ¶HíOH SiÅóÝŠg+mªâê)Ì ã>ßoL€ 0&À˜€#ªŒ7&¯{ í“Ò½|Ú“Jývn޹»”Ҙ +¤1ŸnÓ_5ÜgÏ(æ5ãyÞ†Ž¾@ò%ú}±YOGë& )^ÄöÕ’€Ä(ýby|'wçJ¼²S ˆAÓÿ‚ C;٪ͫ—ã ò¸Mà6šÀ_Z¢ò)Ê+T”Ž7z¬˜VØÎÞö.†÷–öòAÒŒï»F-ÓÔ/þƒáÊX´êLÚñŽáµ‘JQãñþÑd¯À@˜Ùxº¬+c­Ôµ®b[©LÙlÂZS±èõh¤Ž&rK Ia²oÈ`,[9…ÔA }øºmþP•ê[K~§½V¬H!]áúŸ°¿’°Ï’b”=—ôa»WHãV2 šE [TZny/b¢Õ¢¥ï[ƒ<€åû/ªn’¥‰Û…·x* •HôÔÅcÅ 1º§ä.,§œ2òoÈ@=»øºS’ ïþ`‚¶<‘–—Î)H?Ù0›GÀzd·¶áîcïªB%±Dî·aÄìéÄ.ú2`  $Žù¯)B%ÉÅ'zæMê ûoÂwG¤õÈqC]Á#pìlU¨$lŠ!³æŠ3H„ó-+·ÑK_¸Ÿ(¯•´Á°h1ÿE¨$»ÄÇ_'…Ëþ9`«Rvߘ0P‹ë>Ïõ”ÒHÞ²9åÝÏrVÖ#ÛT~ðŒz¡’†fAzxºˆ¡ÍÕ_ÎH=Ü‹e{æ‰B%ÁÉ=8ÚS$36þ]* ž>Qè%XÈä_)G?¯„ÿ™`L .0û~å>€ÔJôü€A,¶* aÜ==ԿܨK÷ו 0&À˜@E˜o´žøRÚ/ˆ² ›°ã:+c“Z¾Ê´zÍÅÈv+^š+{ ÆóCµñ£Ðš[Eâ5Eׇåq×KëñÚŠ½¤nT3-ÀvÚgo- ÍUw´êCã¶=ïE¯žhúŽbÒ?gµYW•´Èïª'îè%—ÝÓ‰&÷†j:é ?ÛŒ÷ÜŒ±bkQ¡ªO©rÌH;«XuGZ¨0í)ueÙüEcÔ Íå_k³ñtYWÆZÙk'¦]…¶R™²9„ÍÞʹÏýT¡’&//ä8„®‹®U©tvA1þ÷k6A’Þ‚¤Kä§Á.„;êF:Œu&À»!îlÙ-|œ(…Ô…½QV×=0ou5»Òœ3ضvÞ\’ º­7 ]ö|d³É›TSi=€w—çðùÒêͶ A¯ ›Â*‹Kkð푱ÝÎ@ªLë 6¾:B]ÒZáñõÛ}—pª¥c ¸þr²Î¨™Ü÷ ŽÙR¨köÔ€4#â¢òž é‰;õ»v¦e—ÎärPt=ùk&@÷E~–¢G¸¯g»têÞZ„J";­ ¼Pz¡®98«æÕy•Ð1qÅ%_KîÙw6@KÚD[4¤óøa9œ³Îˆ’Œ|ÌÉÒÖ÷š2ÜpS`%йú+±¥ãðå¬ ›kî$áÑ^b6a:úéÕzÒÅÓ7­L€ 0&P× ˜}¿r@j9ºþúáqrv>«‘ûuý~ãú3&À˜p$`j¼ÑJû!)û(Ñå¢ (a©ÒÀMÐiãuÌXvIù÷U;ÌðÅcdM3Nƒ«×éé×Ðm…$ 9´p2znÅ Ú¿)éߛĕLj‚öR“×cÂl¨£·4Q?ýðV|ðâlì„QIËHPÕ‹žh/ŬG‹"öŸ°OÅö¼´ÙŠKs_ÚQO37z¬¸ô·-2`¶¤y†/<3´9VÏ[£j¢Y5e '-¤úuT ™òï7Õ… ãV-ÒmÝàŠúJ(ƒ=ÌÆS’¬ô±²×NÎÀt[©tu´Ã¢_ÀJÓ°ó2Nã‡Më±*žÆ1/mÇ+öÓıõ˜wýÕëJtËY«$XRV"ÎÌ/·bb¸[á“!²¤±b½%®>·¡Ï„yð¹2SV¡ƒØw*í£i¿ÚÝN-ÁÏÏͪ •¤ 5@ïI“ðáfé°sß),É6¥Æ´)ò"R¡·–~6v.þöü=,T’pðÿM&pá˜Ü0© Ѻ™^bQNÁòÏã'áeNÆ»C´®‹ä&ü{´ì ®tJ&{zš$t>{ì'9€7‚|òÒßo'qÑZ¡´<:I——Q,9ÑŠ¨ìJzB„½+VÊ3>좟-®Ð Ц¥¡ÔKMØTýí–Þê÷jPf `L€ 0ÊÈ7ù~å>€DZߟ -M®ÁŸû×ÄÞL€ 0&ÀêýøGÅÇþã-qo×¾xÌ}a²Å!Ù†(HN)žÀÄácÖ< ¯~0a¤&ÏÁêü7fm—œCÆ`T¬…ìáì#V&ž{[ÌÛù1Þ}ö)Ä COI´'·:6: ƒñ-ÞY!MH.¶ÏGNŠÀè>ø¿õ>x¢çdqîC_$uÿÑšJ@e˜sX&À˜`·:3ã¥Åú1“tìØ™n\ÍÔ¤Þë[™`L€ Tý»¼2ïW}¼ºÜðl‰ž!r_(i'ŽåA'OçW‡ûÎÙ°`L€ 0ºJÀÌxcðÁÔ™ ùŒ­©_'7ã}y«>/ÏD§&>hc?XC±®žÛ޹ÿÇ^¢ÆãÑvB'æÚãfã õoÕž~‚M2W³vã‹TÉøØC\¢ŸdS€BÝ©opJL9•NѶc·¹'µ1ª¶Í¥Œ+ñ_]cÅú±2‹Åñâ´9½H°´ƒÊ–¾ãÈy¾|<Û`Ê[3UÁ˜¾Øõë`ó[ïI*CúaƳá#² Pfãé3¨6»îbÑ*+ýµ³Ï¢zÚŠ}ª?o襴tœ>_€å¼âiÔ–¨JEš°HØ#©7ÝpúŸà&’#Ø…Ò¨ æ·DEEpwGi\)w›û‡¨¼­^³OqV9Çþ§>œÂÃTwa3½D '© ë; FF«~la· ÏÀÖ¤äQ2[¦,ÂámÄŒýk1d؇ŽE½ê#¬•Lj~ÌÒøÙ§jªþö‰ð9`L€ 0ê `öýZ×ú¤Ó?G~ÿgœËÕm:í}hf¬hN`þ'{˽*Ü({2&À˜¨“ÌŒ7ú´êˆ÷AŸ~v¿Þ÷âá{•=y:`ðûR˜®ðquíûl©ºŸO¯Çzkêä®qÌÆ3Jvϧ‹Ô2 }´ƒQG·ÒLœ’Wû $VšŒ,‡òï:@ÜŽA8ýbƒý Ñ|·j2»ØNW–=×c¬Ú2v$ÍtȺM¼;D@MóF'ûë-ŸßÛ»?¢ÃFŸÞ}Ð5\C3ϱXúe#õt9†wp)çÚ9„µs¨L[©r9Iè¥M^G‡–å̳+gm<­âŠ¥? …£ôTuÔMÚ3E°++›Býn} ž5ç Îy"´…r“‘8a^˜“ T…Œ7"}$«ü_Ï»3ÆôÞÜI«’âgbf¤³†FÓmtÖs?bƸ•L?ôn§0(À7ï¾'»S<Âxtÿ^Ú,†*¡Ç…wÆ–¯ÛSM„-Là:pmÑzBÞp;&öì‹n}©3òÛO¤§UX‡g`HiωÏÑ=!rñ΀iðÛøº í¿?~úþºYŽK³_† Ï‘«poÕ/vyOѾd¯„ùàµ'º‰빟0GÙ¼B›ÔGÚ‡Œòê=îÏxsó\r¥=‘æ<…‡þÝ¡”UʾƒjGDô¬È¥wïä)xwóL1îªqýpåõ¿aìC¤›—:\¥Ödœúm„¾ý¤û\HöèÊñ´VšÑ8áoX;¡½˜›k‹>˜6h!^‰ê{Sz?ƒŸÏ¤guT¬9øí—½Øö“‚öU3S1þcL€ 0&PÍ̾_ëZàÊLèûgyY ìùB]™ùð%³Å “¾b2Æb&Þ~ò~øS·''ó7ü¸y+ê÷üîmÕ€ûÕÜ|99[Öœó8}ôöïÙL{.܇ù³úï盟ŠíßhV{yFÐ}û=qõÔÏ”CðËÅöO?Æg_ýWV×Ó‡> #¥¾¾óØfã9OÑlYrNlÇ¢w?CÒyIÍTûðô¤ èÚJùÆ//Oö»Þ*ÜÎuÉ9±«Wü{ö{¡¡§Ã"hNèuO7øÛ©ÊÒEu°¦'îFÒ™ãÛ‡n·Û: G´“Utïm\ý9Öo9¬ÝÇè?‘ö ƒA‡ÌíªR–”„ø|Õz›vþø¸1¸·]S»\øôF07Þè¼dWJ®Èž4¶AV£1ñÒT|£¬V¢iôÅR@Gá“C.fâY/âðÏ—|G+ø¸+ï”øü5¼¢”¡ç4<ÔJ3Òò¼‚ôçàÙ*TŒÑÄâUÏÄ9w‡ÖðÑÏëõl§ ÄJW»}·{+Lî"†>üù uBrà„á{Nݸ±bÛýÈ÷Ιˆ5!+0¢³üì(=/çLU÷ЊŒ Çž5.F6ÝDï ªø“R©@¼Ò+Èɧ†äêŽìsYjæY™™°æ—ÂJI¸{úÀÝæ9fâÚ )›n+×D9sŽlÇæ_½é]EïE›õI–LWÛ í¤_¡iÖaS%ÁRmävbíKÒà°o bÚ“¯JÕjÚmú¸·…ò°“ÝéºÏ›ÃwwÿÂ\ÄsþŒŸw@·Ú mç 5ò¸UÏÚ,ÝÌ/P½hǯ¹˜¯;W­ÞôºYý@UÙÂn0w%N ƒøT!Ó\ìÝ,oàHg}&GÆÂeêðÜÇcÁ„=´*ï …JÀ”‘íL8Þž7J7û¥†Ìy;zOÓÛK >¸Ð. †‹‘º¥Ø®­à³·NàñW׋s“jå¡¥¾ãbÏaù?„r8ým¨úZîÅÒùG1|Š4ceí¬?cí,+ûz#÷’,óƒ$XRÄÌ®õý(º$X²Ux ô˜ºƒvDü%!‡ƒxsä`¼©fFJk¨ X"Õfê/$eX}Nì4. ¹¶êÊ&À˜¨«̾_kJÀðºšèhïýF6I “KV¼þÆÎÚ$º'¯˜Gé§7Ãï& –õ¿ÜГa{Õ \¡É\ó±`õ&¤‹}P9Å(C5Õ‚oÁ©­øë«+å€å†/ß„g;k“1Ë mMÆ»ýè[B_Š>o2â×ÀÚ=‡@›A'95³ñÊ+ŒÉ4S6Í¡o é^V“OMÇ”ë1üƒ/ðlÜmª3[n$Ê·s±t´ÚôÇÓ0e¡2˜\Åï¼tÚ›å vįÁÅÊ´qúÛüâ4¬²kã6$è›ïëíãö©ÉIü#G¿ç0!2}áLÄ/ÜÅ;ßD{Ÿ ê«™™-K.¾|eÞW&€*éQ;ÿ+µóÓi놡íW>Þ(&Ç+R<ýX€>|iÚϪà!½¡ zèØÍÄ+ø…öª·RLÍ;$‘´ßÁo;Ê#+ä5ÿš?Ðq2D~¦ ›$† Œê€ Úãf/ÅÓL,æM½ÏAèÒõ¥w0h‹46?e$¶G…£YþyÚÆAç AãX(Û{îFŽƒ`/OÅxqC.>7«C:šÐLu”K „ŒÁÔGCʪ1¸þ¶‚#GÿÑ+2ØÆË®ú‰×¢“Ékgº­P¦fÊ™¶{)>¢ÉãQ|¥mÚð'waœß°ÿ"V´nüUI^mDÔÐK&s)‡vê„J¾ðâò/0oh˜äoÿO7þ¼=cP”ì‘zP*QÜ_lÂèhÛŽwý Mlj‡F,þ³§Íç7š€{&oø¼5}úÆè±ƒ1hìsX°q;f ‹2Ôã*±Ó„EøìƒñªªH}±ÃúŽÇŠ=+ÑÃ^PkéŠE{>Ǹ¾áúà²=ã>ø+žïáÐAí7ßn\ˆqõCŸ±c0hÐ`<óÖB|»aÚ5p&vq#¡–dì—êö~ß®Ÿ‹^Ê=MÁT¡ÙÃú´¦ÎfÜhÃJ^vÊŒÝC0yûW˜:¶ƒAg ‹ ÒÒ2UçõÐeúvå"OO@sO8úêc³ 0&Àê"sï×ÐPÞÛ3u+×p#ýб8ôÛÃžŽ ŸOCŒ¦íW LÇp´lªëMp@dž­U'`ÅÏöB%9Q§}>úªç¯¤‹UOiB¥^/ÏÅÚÍ_àI±R€Ô5þÌ¿hX^?­\ð2OÉ×èh.ÍœÄUšPÉ÷^¼ýÅXûùlt“ïëµÏÚξ7ŒÊÁnÕGÀD;§Ì,}J*Ñ5}cÕçX»~%|0£“Ú¦W%b<´Z m~äåMªµtO|)pÖ˜  •ÂñÌcíÆ•˜ú˜ò-LCÏG†Ãý¡åed3S–é»]*zËÖ‹_RU‡ ¨ßÜvÞ(;v»ÞLŒ7^»HŽ}%Ε"íyÖ§‹ƒ0T g4¯¯¿šLnê Q8$M׺M˜¯W‡¿ÑÄ×Fjÿ+„Áz¡RÌc/aíóén+3r¥±™M+1\çÉM:¡ •¼{ŽÇ¿h¢ƒ¿PIˆw#ÇŠ…ü"‡ÎÊùÚXZ®8Ƭ •ºM˜‰ ñãËÙ\HÅÑXšjãV޾Î]œÆsõrIö±Ø™¼v¦ÛŠPåô ÖéJÛÔ„zôÞ0ç¿&ŒZ ÞòåS?~< 'Jó烂i•NMJf¶£åö™ùbJ­ü<Å=˜n„*¼ßÒÒÄÚ+êÑr~³='Iš®ÁÕ 8ìT×£—þ¶=Iźh„ÕÂÀµýxM)í™ëj§©¦Üò`ͨðQà0;ßY<ºGw¿1@V™ˆ76ÿÃF;ÎáO_ÆDyEUŸùë1£·5zéW¾,WÏmGÿ¾’*øÀÇHøû—Zªù‡ñ,iç9$º Æ¿Mq䥅f› ×lçJš·Øx£R¬*…íHuÚ¥KÂ8l!“x#$,þ>å߃V[9wö.¢¸€ÔPzû# u,ªJ½rJ¦°,iˆF…´•KÓD¶*GÝãM+¾‚Œ§‘^DÂi×ä–6DÈíaTÇrêV¼L_;“mÅ,a/õ¬Ìlj›Ep£1¼ÜÜ4 li³}Ž}ÚÊýì篛m`è&œgfœsmÚªZs¿.ka”=•”’x7÷YRÎoé£kXZ„ÐϾ” Ñ2Uÿðöô¢Õ› ÆÕGa;¸…”ž;ŒïS¢Ë]áâ>CJÑrNlÁ+²P ¸—6¾.Ú;ÝWA²zK9/k%aùèîÓÊ–fÒl`£´…ÀWpxÛhÓa½`‹ôŸ~0CÕ±Ûml\¥…JBê–æêÊ&áÜ¸Ž’Ïµþ]=©N6áÎêDºh+\ÿkåÊþL€ 0&Ą̀Ž÷+÷Dòô`iQqUYÜ0Ó^9Ž jsíi¾m¿~RåìýB* ß “GFR^Zß·ÓSÏ£Û’1¢:ù k÷al´¢¶ÈlöÚ„pl®íüè7ÿ”Ëãó „J‚¯‘PÉiÛ²­=VÌÔËAâAiþ»÷cÏÚ•„Úÿéô"ÁÒ²oY¹/ö¡}ËVsYrSŽÊêµñÌ:¡’PZ-3ùõ{ñø,a2éz|{dF«{‡ ØÜ0µu¼ÑÝþ´·PåHºÓØJhxÅÇ—lR7diÂöä¦7 1æ¶vc̶E«‰g¦¯É¶b–‘«»7µKág6…ÚﺖšxÔÇ-› ²¤±HP4 nl˜¨™2®#}ëBGÒ1=;¢‰XرSY¤ ÄLÿBuŠ7´¦¥ç°nÊL±ÓíMºgïl+•0ö‚JV B}Þ\ý³jQØÂ˜`L &¨ ïךPÆšp­¹ŒL <¥É˜#¯:­jÛYØpCù½RLaôªM´òHVo=owŠÎðÔ ã2®Á¸§§°/ÍÞ¼Gg݇öÂ,l³ñ(ju—åô^aX_0Þè~—íôQÁ5¨cWú'Á Ëÿsó ôyB[‘%ø³¹Å”¦bÝ’R¡B¡«Ã„bçåuڶ죨·"žçŸÁO©’On¶A— ôêëžGIßâXþuïíê.KÚáŸä¤£DT»§Ýß‚GÐÝéØ. Ÿvî>E‚%ME”AÉÙ‰ 0&Àêë"XrwûZøÔðuyu¤p5™@Å(÷s.í=&©½Óâycø[àÙ~ašÓM°)s+ݳ;Rm àÝe æ½3ÞXÇ®mP>cL€ 0&ÀtjÂûµ&”Q‡”­L Æ8ðÑ qU‘°/Ø‚©}ËU }¥XW½ì,u/ÖfÍTË7@ëöÚŒœDB‚žhɘ§ËZ°V¹,¤*éâ™L9Õæð†OlÜÝ"C®¢š0R¥Ïæ'`̓252fhOø”¦cãÇ+ñýÁs(BC4 ÇC#†‘&Y8ê¤:6mË.Ì…Ã{°;!Þ– Ú!°BªÜÃZä'¬¨#•E›…ûp6U»zËn¨bËÕT?Q$uxbqø 0&À˜õ Ù0&À®A °ßt|ûÎþšNºosQP\Œ’’ø´Á"ác´™â5Ò¬VoÚ€qÆÿà©´³H§ý òr PLå+qóAë;Ú#’–®ÚVkþœ`L€ 0ÚH &¼_kBkcÛà:Õ¥§7â…ÒP|·é¯¢“­`EáѺæÏoB4Bx[m€¼àÂqu?¶cK'Ì”Mâ ‘k¥´IeŸÙxÕ_–|OÅ!±6R'XZ"ˆÄDS”W(ÛøpË 0Eqú¡y30|^ºÚF¥2“ê¹ø•ˆ™´‹žèhS gí\ T,m1ŽÜ+ñÊNÅ5ƒ¦ÿ†vÒÔØ)^ž·¡£/Lûw%±YOGÃRO]ÄöÕ’PI‰¢«»,í…º +¹N`ëOYhg«^,kß&*)ðùȘ`*,©(ØÂ˜@y<|š#Lø9Òw~Ü„ôí{C5Ôo§'üŒtƒ#ûx|~Sœ:( Hñg.µ9AlØkÂ4Œ¸7…'wbÖ«+Euo‡N»­×cr\s­œÎÚ–âª;Zõ¹1ÇAj㳑L«ð$‘d:âçLBü¿ÇcÃgcìGMÑõá@¬·—Öãµݱà‰nòŠÀlÿ¿)êþ^Z!d[5—¥id'jÇkÄ2Ç?? Ý7@j]ÄÌ NoÇËϯw(;0&À˜`Á·&À˜`L€ 0&À˜`LÀ†@Ê¿`Uªä4|ñx6*ÙÄp~RßÕxè¡èb¶©©·c³ñÔD ,N³ž)û¡W9¦´ˆÄ²iîk,|Rüùxó Èêi×"2Þ·j F+{‚…‡áË m1yõyú0RË¥}‚Ýàt‚\±êEe šºÛ¶=»T®yZ‘²D><»ï…Ÿ§ —ö,vóñÇÑáp9²ïË9„7¾f^€ 0&Àê^±T7®3×’ 0&À˜`L€ 0&À˜À5 \=·sÿ‘.…‹GÛy^3ŽaϦˆò•|’÷¬ÖÀEø·œoG*Ù˜gXÙÑdš¾ÁmäNàÈ©|‡rO$Ê{éÛêöãqÉ·׆PÖÞ%ï; «ý "*dýÆÊu´ Q•§bë%S(ÔŸÚñoÕ]ãz GlW*yàjÖñEª(ð±‡zƒÊRϳ9ÚSzPYºF‡‰«ð}³I.m Š µ+9Ÿ2&À˜@]%À‚¥ºzå¹ÞL€ 0&À˜`L€ 0&P·(›rj½ï³¥â3B^õ®‚z·Ûpÿ0Zñ#˜¤b÷9ÛQu뉭X+ì?C&æÉá¯îád6ž”–ñ¿¹4ý»PU™}±aŸ]ÒWðíÑ#™X ìâoçϧ7€³vî†?Ž ”еïì]à£XW=ì,. ½T—¦Þv ’O`ïéøl¾7Ÿ"¨ËEr’,¡µLã¯ÀèXeO5Ñb&Þu)‹k&oZ‰OÁZRk–«Šy÷OæÑ©ñ³­Ÿ]fÚyäÈyXæù.ÆÏ’„¬‡v’I61cgãÍçïshûå¶-×FâÞM‚&=I'¢ó˜Ç^´I"Ð`E[_M}bnê ìM¥²é6a6¦Op,‡à]ýeqGPoîMºG÷‘M.|cñÆ’¸7œüÙ0&À˜Ð¨·|ùÔßOÃĉoŠÎAÁÁ:ïšgý--­VÔ£ºÈ3ê"Éé0ºK€Ÿ#u÷ÚsÍ™@uàçHu‘ät˜`šø\-¥U>GGCo7äÒøuÈma±ÕðexyÍÆ3LLv4•æÕ2d$AzIC4*Ìš† ²UÓò²a¿*¸Þíü*µÉŸ¥ÃÕ»1JsKáÖ >æVåXó/âÜÙ ¸\Tˆâ‚Ô÷öG@ë jã.åS° #3—.å¡°¸TÑy#$,þ>׈WNªfËRs.\ÂåÜB–” ‘%‘áþ+­ÊÉš½L¸ÞíÜD‘8 `& (÷³Ÿ€É®O´ÌŒ³b­B[UkŽÓ‰ª5yNŒ 0&À˜`L€ 0&À˜¨ë\=›£}gãÕIå±1¯ÚÓ¬çÿðö´:‰Mm!PÏd›4ª¿»gS„†›4º{À?Hø¥jÎÍlY<|š#”~¶FShëÎgL€ 0&P× ü¡®àú3&À˜`L€ 0&À˜`L€ 0&À˜`L€ TŒ –*ƉC1&À˜`L€ 0&À˜`L€ 0&À˜`L ÎpP…§è¬édjK=ªë:0ê"Éé0ºK€Ÿ#u÷ÚsÍ™@uàçHu‘ät˜`~®rK¨ ¸×…«ÌuävÎm€ 0šF€W,Õ´+ÆåeL€ 0&À˜`L€ 0&À˜`L€ 0&À˜ÀM"à°bé¶Àà›T”êÉ63󂘟_³êI°†§ÂŽ”ä3¸x)GdßÀ?ºö@רÛPÞªpÍ*SÌ[,,·sã R{Û9Õ·2Ïc<ìʘ`ÕDÀ¸wTM‰s2L€ 0&À˜`L€ 0&À˜À $P’†å//Ä)ƒ,3·¦ãÀÖxÄ== ý£,Ž!JÎ ~ÖûH¸lë•ùåÇH؇©¯ €Å@ÂQ–„5k¾Fâ±,›ˆEÅtn,X²¦ïŲUÛlÂK'é8•x_¯ÅäÙƒáoŸA¤k:eX‹wW° w> Ÿ$&8åa=w+ ˨%7é5ôóÔLØÒv.LJ_žtŒIåKO<€ !Äþcö0yÍ3«a.ÜÎ /Xmmçfž1†€Ø‘ 0&Àª –ª %'Ę`L€ 0&À˜`Là&(»‚<±Щß}ˆŽ…Oƒ2œÚû-6씄»–~Œ6s§!ÂC_Ö||·P*Eƒ>Ñþ8sà+¬þê(p~ÞYê‹ÙcV•ä¤8•ô)Ú]¤áˆèûûàŽðÖhniˆ¢Œ_ðí?6┠غœ€ ?vÁ„î·F¯Œc~Ê6M¨äƒ1ÏöAóÒtl\²G)¯]KçÂë•Ùˆ °[¹$—QÊ«<¼ls- ¸Í¼Œg¶!Ë?++Êx´í„^wÅ 4ÐeY§ðíÒxI@˜º Ÿ~†¿ Œ°KÈü5³K¨ær;w¸fµ·¦ž1„Ø 0&Àª“ –ª“&§Å˜`L€ 0&À˜`LàfpoAO?æmà×xç?d‚š.‘WÆdaç¡3ˆÐ mòŽïÀ–T©à­‡L¨žÁâ‰åþ'Шt –m"¡Ô±xìJ¹†Ú `ÜšF¡ÿŠ€Wö¼µÐh%’-÷à^˜³à>Ôwѩ׳øcÂôæø¿i#“‚_ÉV]ÒåY­gTšG …^ß-rÍÊ+þÍòãv^‹ÚùÍjDœ/`L€ \“€ë5Cp&À˜`L€ 0&À˜`L F(ÎØ‡Å_Ñ>I¢‰Dû Oµ>ÖœtqO#Á!B/pRC(‰ÆŠBA¶¢rÈ>•>Ъ›¯×l‚ ú¹˜véçåšÇâ¹#¸Êy!ýX–”( füŒÒ++Ã9Û+…ŠMv(+•-Yضj¥lüÚÆaаÞ³Øî5¥¨K1þ»ZÚ_IH®õݑЮ]›uͪ¥n×/n絫_¿–Â)3&À˜@U ðŠ¥ªäøL€ 0&À˜`L€ 0&ÀnaeÙIøÛœur aèôQ¶BÝœSU_¥ú-òiRÎç뽪`/ÂÑýG‘H?U¨$¤VXˆË¹Õ‘GC´l/ïQÔЮ¸êXV·úh*»fK…>W7Ÿ@D†´Atç´QêdÛ…e¯ÏķɹŽéU‹KŽ|µëdõ„è<OØí{…›vͪ¥‚×%n焵¶µóëÒR8Q&À˜¨NºŒÕ‘4§Á˜`L€ 0&À˜`L€ ÜLÖ´}˜;o¬^èÿÒ_p—}§EruqT£%.ÎÓD.^Æaœ&êÌÃ-fMC1JQ˜c?ýˆm?ЪªË‡°òíCˆ}z:Eéö‹)ËÀ·ŸoCf}W8Ûò¨¤¸n~waPß(Ô§”Ï'§;Ë]rÿ½X&ùzɧz¢ŸK“(Œ¥Æ/+È¡ï¿ÂÚMGE·m × |Þ„êVBeÚ‚²ÐÈÓùpK ¡¼ã‘Áˆ¶]‡|ü÷ïÿ‡uû ¥|£`ÖŸ:Q]œ›zÍœã¦úp;¯ýíü¦60Μ 0&À8ïé8e&À˜`L€ 0&À˜`L ¦ÈJÚˆw–î’‹ˆQ³&:fhbšshNpy*ÞÚ Ø¯<ÿÊÐqAc‹¼Èâà°ÄÝC‚°·%AXÂÒoÐmÁ(ø+r¬’ËØ»ÿ*$sž“KB)jjrÊêiiD " ’PÉÀ.tìû’c%þóŠ)›fÜ-¡h§mǤy\Ö¼y¶¤JZy¦\¡’ê»fרÞõñæv®r­µí\­aݵäMÆÏGŽ“û .æZq¥ÈJ²D´Œ¼ݺމà&¶Ï´òHå¥GòÒÅéÚíbìŸóBÌ2äeœÆÏ?S~ɔߥ\!×þ!èÔµºFÝæ\¨/f\Œ´C{ñ}ÂAœ½Dåâú"æž{Ð-*ØùDkþ»c'öþ”*æz…ué‰ûîAùŸ&ó39v›ö¾Ù°¿*uóǃýû"ÂßøTùÚU²œ76¿ª¶j• §6’˜Dïr'ãõbc£?anÉmQwÀßÝ`ì¡2ù) ’²ÜÄ­ÿÁÎ}'´¶ywôíy»]?Iˆ`ÛP“¨Å,Ù]\ë¹X¹j›«íiܤ×Ð?L[ê®ø–eÇßÿú1$mË’+M®BæùtœJ<„]»‹0ë­>òÌ)É_Ø\rÍš¯‘xLî¤Ë‰“WOÈ8øÀ®ÚðV˜ü˜I?7~^ÆœjÝ&`=‡øOÖJÂ[zw7v|wÖm@\{&ÀnWað˜úß\möS¹Yåá|™@õ(Æ×,E)ÂTÇ¡ÓGÛìdœ—1=‘ ¬JýG²{¡cmP¦˜Óv‘ÐI0­¸N¦KŠþÿ¥¿rÖéBÙ[‹rô¤ìˆVÍŒììc9;oÑ…VcyìÞ÷ î Ñ-FâvEU`$ºÜ^^Í´hY)§Ô“È6¾ªÝ¬¥øìX&®Ð¢ÅV‡b\ÏÐ $U}׬™Ý‚A¸ë/JímçúZJöª?cÓ¼u]ò±wÑRl“Ÿ¿Z9³™z6Å£Ó“Óðǘ H³ó’°dÞJYnÁøyÓ¦Èðå„Óv.LJ_*Ï_-7œÏBzâl‰ÃÔÀ¢½´@‚*Ï·I•çyÍI´ qÂ×!}0sò}4c«n4?åÌ/ÞAÅiæW«‘ðU&Î…P»4…S“ù™»²Ë8°ï®: X5Cuû$1qOOCÿ(ûkPµkWùrÞØüªÒVÌŒ…[ÏÂêkŒ×+Æ~ÜÞL~bZ%g?ë}$ØÝ™_~Œ„=t/¼b/cùuËðPªýõ¦fÍ4‚ÍÚÒ›jLͼ >4Sf •¨.šè£Ð»C ~¿œsgOáðŽm8Ú°¡Ã‡kINŠƒPIŸÛ™`L€ ÔX6ïÔ[ .¸Ö¬4œJ¿€œROZña3qÆIvfL€ 0@ øì^¬KÔe”sÇslgÑ–Ñ”^¯ÛZÛÌtíÞ›VÒà^!Ö~ôoÜ6u0üM)øüír‚¸¯ómºÄe+ÍηҀŠK}ä_RËy¹¹(¶–¡˜²¯ïîú.Ú€b~Ú!ütÁí£Z¢‰»òM3ƒ7¯Æ†cJþðr¦-D r­£{(ìiÁ';³PðÃjÄGøcPŒ°Š‰ÔØíÔòòë×vydáR±;ü›h“c²ŽoòµÊtÒF²h~×*бöoˆW½ EZòq\±¹d¥4º1ZGØîU¥k¦æX3-ÜÎí®[-nçbMM²ácU¨yÿ ÜM+¢\9‡½_­ÅT žº_î‹ÂØ.ÒóWL ï8«B¥@ôz0Ú‘¾ÒÓ»ÖaÝNa„õÏi„Wßì0¡ÁT~&ÇnóS¶iB%¯Œy¶š—¦cã’Õ8JãÄ»–Î…×+³ ŸQ…kgªœ76¿ª´ScáU[0•­Tún¡&TŠ2}¢ýqæÀWXýõÎï"uþ˜=1Ö`å’ØºëÄŸÑs¤NTüÚ• $éý Ò{ãxeHüò3U¨÷ôt’TË3h#Ò€Ð0tìÞeÔ1´ê»5Bÿ!-¯ì=xkaù«¥ŒógW&À˜`· ·`Lš3â\ªºÜ‚õ«ãEº°ÿX)¨ƒÍ¢g<Öq<\}&À˜ÀM#ð{)m$¤šB¬ûh©z¦·xÜÿ4^¦95ŽÂ³OvÂ;Ÿ “¼ûÒ!†ø";5]I÷ôh„Ì·¦mÇëï9~Ë&|2 r~ýžÁ_új+q2lUR~MþÍÑÒß¿&žTó¢õy©¿ñÌx9ÍŠ"ƒØŸ¨,4(”)1$MŠ.!ý|¡”Dó8Œë«c!'|æûi¯'z×yYкU3š²~§t³ñ#‡?hÝÊ®Š–Ç>œU¿­Õë°øûÂy#£xÃvŒ¢ ×Ì(‡šäÆíÜñjÕÚvNU5óŒq$T]"î…·GB{½ñ2MÝàq¯7R'¢Ë, ª6·éž]ú´ôö†àÉèfˆðÖœýý1á½,yé#Q¸”¹5gûFØ âsiU’ð]øÑ»e¬ún¹ Á“çæÓºQšlpIÿ°+ÑMÿPWPzã9õyjòüŠÅÂþåüçP/Z•¥_Qj.?sc·¹Ø¹|‹X7@P-K+¨Ä•^Œî%Ó–Š\¾þôt™qŸNÈ`öÚ™c¾±ù™o+ÔTMŒ…»÷Æœ÷ƒí¡¾[¾{s6¶ˆm<íƒ2ò”Y³qúä¯ô<¸— àáá ‹?Íè:Sš)-û]¼J¿J÷ ö|(³æ";Ÿ¾”û²,ÉÇ’¥ç Ýk-ÃÂ`ñP^œEHK:‚ßèÙãF-Ù¯u;„ҳǙ©è}k_áÞøùX*•·üÛvÐí %Ü»§éÞ½Dz•éÙâî‰Æ¾>hÑÜFª›A¢´Š?¿ï_kv~9uN|N4ðn!=ÇìTF8«»àn_/Ьƴ㿠#—4¤»PÝZßn3CÝ!­’\¤ü’ŒLâ-˜Æ-Âöˆ´dSzr߇f¶g_ÈFžÍH§+Ô¤‰·ú¼qH›j,³ïWîH—¼Œî™´ß~Å%ñ>¤¥žÞðjÜÍš[ ž#U{†p ÆÞfÕXðŠuVý7pÈÓ3“ŸôÀ»Ÿì"¿B¤§*ÏúFèóÌ‹¸/B?°§‹îâü½¬„jÜPy¯K.^~!d‘" H}üÑóJH:6Á¨'At€íà.Då¬.´JéõáF³w¥Ò",°Ì#ºžÛÛa6¼AÚÇD,ãå,Ro/•Up‡W<2öQt³W}$úVúÏõÚø(Mšýo‹PÌÇô5«t)oµÜήH-nç0ñŒqàSSì„JJ5Bb¢Q°¤¸…Õ6ŠªMãš«»×"‘¿­üìH‚öt:É£±ÁM‹ë%—Ÿá7ÒyVoÐM´b‰~6&)'¥wŒGÏþªPI zo?D“`)‘|wÇÜ£!™ÉÏäØmqF’ª 6zÔ@[Õ²a8<ï «XÏ;ª‘Vñ™r¯ÉrŠùÜÀüL·*¨Ù±ðúnÆ<ó+ •€Þ“†!ØNÅcåó+Æñ=B?H01xD*Iç´ã¹é}q+œ½»AoR±kðzV‚×ê#K2ʹ¼.ú‡d9á2÷i«•ºµ)'${1šK ›T>|ðÑ›„BmZwÄ©ýBç°×c ä⇵+°áÉ_ ¤þbèKcqW¨n&Œì—G:vWÐrhÃX=‡bì»ôò úu¿[±[•_9±æmÐúüIiÙ6mÐm¿Ï™Z{KY6v}þ>¾V„ƪ¿¼ü,ºWî#7?mV/Y‡SF“ìÊUéú[Ӱ䯉3}ú¼4·ÿ'>fOèMÛA˜3±;~Ýú)– ³~ôÆ«^|}¸ÝŒ#}¶3[g÷­Åû«Ø: gvm™¦b±Ü6íŸi;þ&Ín>¯>Ó\Ü£Ðþžïÿ2ÍÎkv«ßø‰v÷Nô¨iSk;U<•¼oµ2ôÁ‹#â}zî(&nR„´'ÕáŸóâ€~°Kd_'Á¹J÷ïËÓÑêt<Yµ{T«×Ìœ€/§/µÙÿQ(g'â÷G{~äž¼ ,Üèð¬÷£ý&þ©‹¤î®$ §IÏ!-aàqݼ9’•V/ék—=ùP ˜~¿r@ºÜ¹øï—kH‹Ý{Yn öÏ‘*=C¸Pï°ëRf÷à8Ìû0ÎtÚþ10wÞÝ$ ÍAšäQ@7 Fãr¾Íäié4s£û“º¼|\¾\ W’sÐh¥—ÅÏFõœéŠØGt» ý'¿ƒî4Ñ+«´>©h¢ï¯föwüQ¢ôx3£/!'§WH}`)jÜÄÍ-Õ9‰‚f™OœóW 0sÍ”:ÖÔ£™6§¯«ffòäv®P¯Z;7Ã^ɹ¶OíW¾ÇÜ …Îb½­)Xýž¼Ú†Æ¦>¼ó¶öÍSq6ÅÈv½;_§*ÑÛæ¾dG‚'ëÞ›ìI3ñ`˜ö1'̦™­t|(ª_t,¢iìøø¦QД¾sf§^¶Ûô‘ôÓ&‘ÚÒnÊ‹^æ9ɇp”6´<¥¡iE7è&]ª æ¨Ë^ý¢;Ñì™BlÛ) öfaüEh:w" Ô€(YéB^×Õ ´}p'šñPB«N&’jÝÆá¦êOS#S†™ôÛòž2¸+¨± €6“ -Ñþœ®éE³ˆ.SM0—ЀW,ž¯@HŠÀÿu™@YÖ>P©¢{ÆÀ£ ÉÇ"S×–EFº¶iû| YJ®ò àóñÖ_‰~=ïUêqãGûfʦÄÕqÏz]â•¿oµ2l!¡’’‹0î Å)Áeøiµ&TòhƒNÍ]‘™šJÏ–,»gPåûWÎPìîÑe_Eáµ!QJ!Ë=jõÚˆÙÓƒXý¢Ú¾Œvµ¹UBùßZ¨¨y° ÓýíPrxé1s?©åññ–ô©ÿ¡!ZÒ‡c¦^ØFåõ#t™…Î?l‹Â®·4³ïWîH—•žKÔÚ’ª]d¡OæYŠ´“'D\n®¶÷`¥û@ºç,÷4Îl«:÷& s@«zʶ)¸¸y¢ íQÔ¤zþØ&nxæ‚&¡†«“Œƒ×'A’?ý }o)ÇuÍn©JW±07Š·ó*^(ŽnK ,É?~•;¥oýÀ:Ù_©»>•Ô×m0q\w49§ëØ&z3ëu Í#ÐÂnEhúYÛ^‘Ø"î?—ŽÕsfâôèIèx Ÿ³Nš´=ÝC= 3 ô3\¡çu‹ /Mαn2‘Ÿ¹±Û2\¾˜#—Ù¾v+oúMƒÐšŽâ¸S©¤ñAŽàx¨Àµ3WNǬD—Ÿé5ÛŠ“²štNþæ3y%mi3¤Sõ¬ÊÏ£uy’iâm4‘¤>ü[¶H}/U˜T†ÐK2±º~(+• daÛª•* ¿¶q4¬7 Tï2 9ÜI|º`.-«—re×£‰‡°mm$ž|c4"ªAÿ²Z(¶0B€V-Ô:}&MÇ}òGfÿ!YصæcZÕcÛæ…be'ýG*EÓ¬ù§î‘WõÁý=~À|yƒÆm 7£ã‡ÃiŽ» [Uݵ¤ncÒdÊK:=Ø÷>üð÷w±Aœ­²›ÅŽ]9Ö¡ÍšP©m¼:QQe1˜½´¹äG%½½zu¾b~ÆyTveH?«¿W·}xëm¡S”…o¿OA„NG¼qJ‚k¶ê„J~ÝiÖÿpyÖ¿àM›ZK„§H=:É6U![‰1ӇѦ—ž(Π2+91ý'=…8Amm©èN?œëý¬Ï–#ŸÈKO‘-3g &”P¤4ÛÕ¯„Ê6%¦pŒì7ChG“0¬øiíXûƒö\ñè<Ï‹ƒ…^·É›e}Æô‘|®ÁÁÒL¸ê¸o£iŸ„aÝèŠÉG¾°A¿žOá/CH8.›²ò°YŠ_]÷¯î¥ÕR«ßX(®Ö*8–NÛ‡FI+†”BTð(ñ»›ø¹ mßj|¸úÅÌ¢Aí"º~ÊÇ®üÂ*Æ¿Ò*F¡{3°7Âÿþ6Öѳ7së$?A3ýñÇóÑmë|øU: $]ã/ت…¨`Ù8Ø­M Ûäû•ûÒuÍ>ôµÚŸö"J+žïÒ­x.¦MU\Ü¥g÷ní{Kǘ`LàfÈ8@c Géû(? Gé»@1±£&aPã2gXƒ¯I!{O¢}hà›†ÀM˜büwµ" "­5wG~“t'/Σ}Ÿ¤ï¸„U Õ=ö@Úfÿé.uôT,„»/ZÓÄÁtš8˜¾û òú†Øi¦ÉÅá’PɨЕÍÏÜØm‘ºw” Pó¾ì m1@ ÇEs¥P±i*{íÌ•óæå§å,Ø*ÖVlã˜?+£ñ®er{‹>ÔpH3©[sÒ¥1DŠÑÆa½’œ¤r7YQ(Œµ 3™×°8¨Jy‹éæ¹D{+dä™ú q…4n%ãæˆÈ6ˆîƒÖ!Ú´©Ìc»°ìõ™ø69×®¸EH9,<è$¢¢P‰ôA}f^|åiôŽ–Ü…e‘ŸÌÛDÃÆl˜@Í"PœvDí «ŠPI¬…›q#ÿHCŠö¦‡¿Mñäˆ8›‚ghw<1¤û¢9€Ä4IâSœö“¸¡®àìwÿãªPI çî#ÆŠ3A„óߢNÑU²Q^ß‚Р͓£¡’äd‰ˆÃðŽ%”#ŠpP)»WúvfÈH¦~@ ˆ–ìé?ýBƒ¼×6Åi‡T~ðŠÅ8½PIˆN:pÝåMZÌÕß¾ 1xnÞ¢PIð©ïG!«A,>ë%I¨$¸y´DÛÙ³¨¥&r |¨#´·v’Ž¥éjí‚únÚÌ{Ç5­‘Ã'al_šˆ+{¢EP35Ž_ÏQ˜ù'I¨$8¶Œn«ú•ª}ˆªß·­‡Ð†œ6B%)›RY yì(Òt*\H¨¤¯mõÜ¿0|ºî%AMåê6TV\ªÕ¯Å£ûp¼*ò“JëßÂ_‹çªY‹ÏVŸ¿±õ—„J¢wCÜ5à!9`:NŸÓ?ùêhïYÃVËmf߯܆žûôŸm„JB˜ú$TRž#Õó á>@-¿)¹zL€ 0&PG e’6–ýôÓ •yy†ãÅgöý¡0ýž&-1Êd2 `©f-ÇV†#_-Æ:Rù%R5ö„Ý~3Zd°”ÈZQ4GÉ–Ÿ«0™Vo¼q{WyÜõrþ±õqᇢ‰_®P÷6ÒÇÒì•ÉÏìØ-ijh/'9û£ïBå“-óXªÃõ¨Üµ3[NÊÎO˹2mE‹eÞ–‹m¯“£Çb@w;5ùæÔ«h±uVÍ‘úñ™ARÎë¿‘õ¡j¿Ý žŠU<ßZŠSòqIÍU,Ž>”o£úhÝ̾êæÜzß›cwi…±“£ÔÌË ²pèû¯°v“  ضp ÂçM°™•+=Œ¥‡§GÛ˜21N•Þ<5–¿¿‰µÂ*‹Ë»ð¿´Þ¸Ož]­fÂ&p (È»¨–.úNÍï´©­B±Xi¹°lo…AdÛ‰hv{r;):w¶t_Xó´%EÑw´ÐÜüEAÈ©Tr£•9eõàïR€Kj^h´‚ºRS¬ZztÏ~ù•éS¥e‚¡>é§%+ÔN…m½d_õ tô=øžrÕn˜«¿’ºtŒ›ôˆíF….¾hB¢íT¡CùGt´hk1¤õºZ|WQPW~}´Ðl««š†RÕ%aîAMÜVÚÌò‘{Ð1Ê䊷æ½1´»í,;Kp.¼wi/¶¶aþ^*ß6 Š÷- ‘ëd“¢tÒ^Ò¢IÚŒ5NK@ôýƒpO;ÜDYe …¬Žû·©‹è诿G"Xø¡ ÆI†nÂt³Ã;éV`Q¸Ykq2¥hc Ô)°ô 4êGO>uá›°|RW˜}¿r@j!ºç:¡G”ò01n?Õñ á>€1[veL€ 0&PÓ ÷ú3&w:ç…8ÿëQìý÷6qÿæÄ¯V"qG¦¾5€¦ÙÊ¦ä ¾PöQ¢1ʧû c/’qsÕôué´ñ*ÞvÇ|ü÷ïÿ'j.=Hͬ?Ù~[hŠ‘¸öM¬þAî7>g¾Ã.eìcÛðîË©?gÂT@Xßǹu¡øåwê«1íp$bÃ!íÇâJ&-}{[åó37v[ŒóÉö_Nveù½X&ùzÑN|¶ã_•ºv”´¹rjeºÑùI9W¦­he­Š-cßFUsQÜ3÷ií¿*‰ÄuuQ¦ÙzçiÂ$¯[H®a[ÊëæZ•,ŠK…Jçs•å_•O-ˆÒ¸•‹‡û>’´œSx˜œÄ š­ªê¥AŸHyЇV- v·*T’êU1bãþµ¢NѤ_2H°$ ʱa5ƒ@ÎoÊŠ ü}lRÖÀš#vr6’Ç8 +Üuƒ›3¥Ó‹¿’“l‹—Q^úû-—©_å_riòž+B^F±œ–Óȃʮ¤'xݺÍ(p±´B+|4~@‹f†R/5}Sõ·{Çé÷jPf ¨F.–.xnT ©S“W ž?„ Ké'^~ÊaFþ5³6ÒÚô „%RÚ÷qrU½o›6´¾h™¸à®“ršhòs&qk<„_`Ï¡xrˆ¦Ö²:î_‹Á3BS… •ªÂ¶ õIl?l„厓ý³JêmÛdœK‰ô¥cìÉ®µ‹€Õäû•ûR;Ð?—ŒîE»ÖRÏîØAåS&À˜`µ„€‹»7üeÅþþÁˆîGBI]µ0‰}ã¾ÎÛE FûR+ Œpl/þõñ1Y½w}\I&ï &‹ßY€@ß` 7öß[eYøš¶úØ•*FàýcðçQN¾™HÅ^Ê÷ªP)RÐ!®jŠCWýÖ4žºlù6ÌšÜ[7u ÆØ¹“¿„Ôæ y¥•Žd ¼(ºá Öm=)BÿRùüôcI•»U™ÔÉÍbq ÿÃ'[VæÚF´ª:Æ|£óC%ÛŠ!¸Ê:Ò¶ÿÕ»SDš¨Ú3¢ü \•M^?¡L„wžFû)Äy¨ÚêS%ÁRm…bT¯V:¢` Hùõ  –h€ÆUQ?o»Q^JÌ¥¡nÉ©þIh”»1[€ú” BE¤8Ôn–>µðrK\_ .gvU\ é¡•SÐV›ÂZ,Œ&;Ä¢¥ÕÎÙ—ŒóÒMÊ)·¬¢'e© ºâ‘'{½ÔàÆuoæ´S¥ÏÄE}>è]íU­¿”ªÀ ¸¾‚» Çì–1ØõŸ-ض_˜t!˜t¬›÷J¦¿…î6«n$_§ÿ¦VâØ¥VÕû¶¼2xãoÍÆûvaÍ t€ &>Ø^Ïæ<ÕE|TÇý«©ö“ò¨òyõ²K\ÿ¬ò£UY7-L·5ôxñk®_QeëÍgµ—€Ù÷k]ïT¦ETÇ3Ä~%reòç°L€ 0&À˜@M"@ꪇ=޽û—ÒW™žÈ‚¥²Rý˜I³Œ+v>ö\½„‚²Áúqt ›‹ïtB¥hÚÇi”“}œ”„Sÿ'O:$MCtš „­ þ2'«ç.÷Eêüš×[·O/¥@ß[ƒ&ÏGÏŒœÏ¢1WW4±´D€Åß½©¨:³ÀK'ü2“Ÿ¹±Û† D„òäfûaª¢(zj®”Vd<Æùµxš+§r%ŒŽ×3¿Ê·£VÖíÈ–/Åv/ÄëCjßu£î•MÊ0¼{³`Uˇ2Þ>`aÝs¢±B¼ìºöi¶6Ÿ«CÆf*YßõÔÙ™5B\!šfòŠl®*ƒ“H¡•Áö’Jq&ak†ÆÍóªiœ¸¼µƒ€_HUD8θ@»ö]œ™‚SöU¥M#šS¬óä‘q™¶ï#õKva¬µÍðÂB}E_ß6Z^ÙF±òñëa¹SäÕÍÝ…™øº¼ŽWÚæE:jž´Ë½œSR·ˆêöþŸ½3¬¢º÷ÿn²‡„BBB„°$² *(‹ `]jÅÖºW­Z¬Z«O_Ÿµ¶¾ö¹´õUÛºÕ…>Qëò—ª´  Ê*°&„€DB !!ÉÅÿoî,wfî’{o.˜å;f欿ßç,3÷ü朓‘ÅE–ý¡üÄôêÕwð`qWóÿr‹ÿ‹¡éï9Ì« t$0ˆN/ÀùW`úeUøäÍñÏujÛ\µv/&_”æÜÚH.ÌíÖ3·äO˜…;&Ì@Ué'xù©Eêfž%aOÃÈdÄÎÞ~Í}Uþ ÞƲ]žŒèÒ嘟åÁ<_Íñºó;€ì‘6B*ÿûš¦#_ÿÍKeéì}ˆ•èD$@$@$p* 8zÅV—”=¨‡Ê&=vÆe¸<¥+x‰Á¦é«xGÛêcìeó08>ý#­+ìüàoX\® žwÙmm• ÁíߦÓôIôûAb>f]ZŒ’—6I¢ê~4Ã=MÉé¹HV']©™ý+cJr¤M+Û ¨×¡æêØmBš"”2&V‰Š¯‘Ÿkó­?P¦þ6”ùzëBú?û(;%R¨rúÍðå|]ñ+e`žµ›ðÆr­¾åÌÂäl?/Ø¥è*:Ù RâòQiåÖÝhšãj[î€uØõ™&ƒŒM¦žÜyuì«vYuâ£#\{$eõF(ÊþJJá¨)sVÁu¹3Š'É,êñÑÊíº³q®—彪µ»Œ k\#\˜ #ÂËL sX^“Àé"“š}·õÏ¿‡2Óæõµ;Wà‘ÿ^äE”xH4õ}I¶ÖX±ŠÇöWkd@6Q}0GÅHÏ­+>-5mܨ9Ö”âSíÅBælk»ä•«XwVéK÷‰SK VÈôðw¶iÞ¢š¦¥'H~ºÓ¤°ŸøÎ–zÔÖÖºþê[ÜúFöîmð«|ÿÿ¡Tÿ”ÅKZ¡éï%!:‘Ài$àˆKÇ”«Œ)Zó­þb·{éÓ&Ghí6xñH—¯în½m’µ{¨k+Ÿîöë«Ï ^'5Fd‚»¯ZýΧ•¡S~¾ê‡}r“îÎsg&êóµ»½8Q¯=ÿkkëMï.ñ4F¾pu•xûߥ~+ÃéîCü CO   OÀü‘oVa¶1ðŸžñÆbÌXÛ_q1&åiz Æ™g+þˆw¸?Vm>° ϼ¯Qd"ѸËñ£©¹Zx'±øè¶–ò}8,{aÛ÷DžT HÕÛCYï·,ù§ëÃaÅuòäA&ÏÐò uì6¹`‚köŠ"ÀÇkìc¾²×Ó²šl…˜04Ù$§ïK_e§ÄUNß¹§"¿Ðꊧ”ÁŽ…—.[lÔ‹¢)ÅF½÷LÙ»K`ù¥¢ølí=¾|%¶ÔZëGóMX¡­d’7s´ß½Ô½KÑu\ÛeÕ‰ówJÛ ª¹¡‡›£‘žì¶ž×”.Å3 õuHc¥tû¹ªB\>¦ eÓ†U °`@®œœë2 5×–bÁ“Kµ3EÙ¶Ô)›¼5ÉÌ Gê»GœÖÕ¡¹É e5°¨è8D™:ú®Sý¨Ig àH.ÄR¿ßp-Ò» Oß·…ã†È\ëØZ®nÌ詇#e³Æ…%ŠÑé8Þxè%$>x% \/(]ò*¬ÓâÊ´}£ÒÇáâao«† Ù—ìåþñ¸r†úÕMsíN¼þºW™’߬9£µ/a(žy!®S§Ho]ø$~ùÙ`¤KS«Ú¶ËxàxÊèËÅ¢‹/ÅÛë¸â.}R–öºê6L›‹hyq¶4¢ö«½Øs¨—¼„©í\I©béŸðôûê i܆ŸÏV_ÀÉcqùäwñ¢kËJ<ÿÀ_0ïž+Pœ-/bŒª®,EÉ®hœ;CÖ+I_zÐN ª5 ñNYœ?½™ÉòEš<Ÿjwn2ö J–ö©èmkZ»m3]Ùøöµ'!ýüóqÆàL$FË|Hg-JÖ*_Û)G*f¨ï§»ýúêsT¹‚ÿבjê«.ÅC·àÖë§#×µü©˜jQ¾m7z ‹ÜDé åHHV¶V¿ÞûdCiï>.OþÓ„ú|ífï-xú¿žÒ>"KÅMÞgÌLÊžxðþBW]¨^òþˆy¸zæH–¥2êVcûúMˆyŠdùÐÓ݇t J‚ Ð,}xÕ¾½Ø¹e#v¶ŒÂõó|l¾ÞT…’/¥_—¯ÚýÊ*Ñ™#F"]y9ø¨—= ÿåkvhËaG#ÿ¬Y˜=U}×÷L¨ñ|§¨|íŠ,õ2ôÞ;˱÷°úaE¯ô!8Îl(?¥í­ýh9>ÝPîn¦bÚyÅÐ^»LR·}ÙYªJ×`ŲO-õ|êÌi2–•ÔvÆ q Ô¡dù—ˆ-(ÄÀôdc6P}Õ&,0}䛞æþHן-­²Qµëh’± ¹°tãX÷ÎÛš¿ŒoÊOŸŠ¥8áþnVüZå#šDä˜÷’ÕFeÉ,'åwÁ&<ó·¸ãš)®÷%±£e«ð²¾ú"Í\©[êPV^´œtÄGêÂ4bçòWñ¢>+¥èrŒ³,µb~¡ŽÝFçâü©©x^äQÆ|ß.HÇ%Åê—ÔeË2§]p¶m¯ªË.T9e ÃêJHù…ZW”!G¨cáÎ*¬×ë…ü;Lù=ÀB~¹“§#îýe\ð8>õÿyï¥HW–»k(Ãß¶—…iã2 ëñÿÆØuõö©Ùþ•Ï©ƒÃ ©ÈÔWF¦·b÷AwðÂy7£(YïìtwÆÈÀó%OÉv×@ɧPòÑ`¦7ak‰Ò±ªÇ¬»æ˜¦nªnMËðкáI ¬~þ1¬Ön̓Ôî¼"ÓE 㯹û÷{¬vµ…ãØºNTÆ^4 µï.öX/*c nº`›|í²KÝŠçú…³píõçš¾0ˆÂä«nÄæžs¥·õÝçð‹w=£)GN5iép÷5ûñøKj«i(ßå–§ßXÌv‹—+rx'üîyõË“ žÂŠòÅNB,ŽWc$LG¡–t3³#B™ò¬–Ü{4©A‡_v+&}!mÚõEÃ.,|ô7P‡™´Ì%­ÉŠaIþ E%¯zhÉû;ɸ€q´Ê´y$ÐÆÃUؽj=ž^¥Ž•v!ïV®º­Æœjùš,ôº©¦¦üt ð¡Ý¶™²ó8öJ²þ¯»ðO%°ôÐûå¾è\ Ò§tž†ökn£þúE´PŽá—ÏÇ”]²I¯Ò×—¯ÁréEç8ÑYŸ»9eþp1,©=_ê2#s“Ëo«¼ûÜçêØ ñ“'®Gv7]c:î9N¨Ï×Îòà•}}‰û¹oT>.¹óª]øý‚õ®¬*—,Ä#òg>¦äœå2,)‹óÀL†×í'Ð,s½…w?ZjÓsý²½.S­ä×ô• T¾´4 ¬§Ìÿ%æäëoÂmD‘5Þ~P~K˜å(Õo>‡ÕŸLÁ½ÿ1²•†çj<Ï”Ü.!¦Yµ~¡üÖPÛ²‘ØÁ<_²Sn¾sF8¸eDæEx_ÏÕ|Ò>^Âóï*#8ÚázÇ«A¥¼û•¬ZcÁÔq4bó/b©­ŽëI»Îò›ïÁGf¿u¿zt쉷w-ݽúÝXýî—¸õ·W!×xßÔ}ýC•¥«^þ¼£ªg!õ|ÔóÍódI4ùˆˆÇi&Ðtÿzómù€E1øÄ"kXz5–ËÒýÚ¸„"NÎ\\86ø>ÈÛï¬&ó­«Þß|Þô•i~e|H£„Èžz) ß}Ò5&Ú ?rׇÈ+Ê‘1U‘õ [Öé·]† SßTù)žÖ>Æë—%ƳhT—ì2V}BÎtܺ§­Y’Ðò }ì¶àâk1iƒ:¦£Œ×–äd!¹ñ°lÿ éÖo ~4;ß,¢&åhYÜå6*IÜyÿñKLËõòâíhûë¦ÄS¯«%Ï œV‘™¸ä?ÆM×ÌÂØq“0}Æ$Lš17=ø®8{ ±Q¡]¦üÙ·àî›gKEšý³ÆÍÂþÃí†ÚÄÜòèÏ0k\–9¸v…Y7ÿ w\4Âúaø¦½?x3fÉÚ»cgLǤɓ0çš›ñð^!œî嚬‰:Œ5‰íËO¦ÏÅÃ\ å]H? £’8dI—! ÷é¾ëeo³²ÿË%ü—ÏìŽ`ºÊ•êN+$ý}ëaʽ"<û’h½ J‰A”µ•y€  `þ Î0*õ+t=ëÆ[¾&óS7õ6£×A¯ÙFK½´=#Ü¢m ‡ÛnÑ– ‘É(*2õE&£RáWáÁm?rNEûÕ 41‘–6ê¿ÏÑú#7*+Dí.ÂÆŽTÌ‘¾þڋƺÛŒJ÷™þ î¾Îe„—>Þú.}ÈöU£;)^uN¡=_eùŽþà§ý×—8ä»]ýHD/Û£6cÂ<üâžË‘çõCâ,ôµ´©PÞüô³ºXræ;€ F·¹lÆ^»Qsˆ?°@IDATIÓÝç;ŸÃþÔ ¬z|ø¤Û¨TtÙµ¸÷W÷᪋ ÕÄ®ÀïþºJWµ¿‡†ÏŸÌ¡¥Y_¶ÔmTJ(Ƶÿqî½ç*jízÅ_壌æÑX2Ð/¼B¨ç"ÀÎþ×mT’2½ê®ŸáÞîÄM7ÏÃô©jÝŒ±wèmÝÇ@ù Ñò'^qîÙ&FÈ£¥xÚ0*eaÎÍóqïƒwâò©úû§¬ò›·PkDì"YJßý“aTJ›<?yà>ÜyÛ%Æ`ÊÔ¯m V’Àäe(?"0Ðð>ŽÊm2Ni2*]t-¼{ЇÁÒˆâóÂóE jú©å3¦X²<Þw™-c¢wÊ8Žnà:®©ê†ù­xÏ/p~A’%ÝÈ÷,¾†ƒ•2Žê6*¹~oÝ= ö!#W!æ‡ÇneLç¡;1%G¿AŒ ºQ)®hî—$Üšh*¶§ìB‘ó4çr]Qð„8ÞÒìÛË34ðzb~©Åóp÷ S´•ög•b1ë¶ä£R×ÂvŸSgŸ½÷diin½õ×.­3³²;µöÕÕ‡\ò§¥õ M™wôèa9Òˆ2]Ù)Ã8‰É)è—šä1í='jT ¦Á¸^NœY ™^^ ¼G»k»y„]"&ØÕÔ®_€G\›0sþãaLÉð6’)íªæ(œQ‘poDTïuI©6`47ÔáhãIYjˉãÎH¤H;4 i¶[÷®Ák?ù-\ßö›%†¦i¦Rzÿ禣µ¨WÖ¥”^ *&qq1öžé:›êP[/:‰"NDJZ¾—º þž2ëÂ~$XbÝ#|sS=²)ìIùò9©^6`ý6I„³Ýº¦ê74 EÙ ±ù$"“zËR þgøu”ör8eÙÏÚ×~1G$bdcßhcy [ªÎzÔÔ¶¸ú5DÅyíßÙØ˜u‰Û@Ÿ¯|P‹Û‰£²“SÚœÒÄÄÉ^³¾ßj:}Ò%êxÇV¢í~Õ‰²5Ÿ :)…9 XõØo°ô èÔÆûps‹,Óî刊lć¿~‹•4 ³S•Ù©ÖIz^bÉH¥‹ððS2VŽ¼Ëæã–©îñ†üE[ݘ~×Ã8ß´!z¨ñ¼ ¡9†–fþyÿÃÚ^ …¸UôÎÕõn؉¿Ü÷Wu¥„6¸ú“‹~¾ œŠzî¬Yûd‰uס̆P®í"8å·Ÿý{Ë}#V<þ ü³|Å'¶,|H[2=WýêËê8eK^ÀÓÚŒª±7<€+Š=¤´HྠA–ÚMøå©KÁ§M½?¿l„;¹¦2üåž§´A&áþÿ½Ô“—;4¯B H=¯?zõõÇÐÜ*_°Èª NGÒú÷kó7Iâ´;ŠkYÊ5bM…³á8z%÷E†Œåø<”íd;cÇ”qØòû#ý22‘àÖ+Açç$Ô±[-^kz£YB_d§ûÑM´i_Ù+çéÎÏg©v)gS-*öA/©“2,€~9ÙHÔ?µiª·ç$±%t¤£ºê€KœA¹ƒÂ*Ö©ø$)¬žöÄd¯£Äätù 5g’3rù  ãuHÎÚ2|y0 Có3]û éBÖX—5£PŒ¡^JJhiW©Ú—+‰þºzÊê9*. ©Ú§ðaÔ»f”mÚŠ^ƒ†"#ÑlØ’õÓe —QIÊrsÑ!,÷-‚þûÑ[îÁ¸9¢E§ \ÿ`$`X¨èxÙ0tú>$05ê”p w¨ W5˜¥ÞFžQúl>[¸úÒiF%1ÍÿžÕ¨d|Œ õ<ÕüQ¥,Sö‰jTR~+\l2*)ÉçÏœ‹Â÷ïZ:éÓ·czn±öñV¨ñ$Ñ0ËÒ\õ¥±AwÑU¹Jв/ÅEó ñ{e?æƒÊæÞçbŒ×Oë•ÀCÅ•ÅÈU¾5žD ·,U¥›ñåˆÅ°!ž¥©yCÅO K²¹÷'ë÷cÌ ÷Œ,%F@6~_õ¾ö ±ß$ Mö?Ý,½Ïºe¤\{Y~ÜÄußtØØÏ[ùÞãö1r\,J”=Ê?Ǿ¦)Æž6á–¥ºl·–}×ýMÓò Œ}5¿ÜR%†%Õdí!3H€H€º–ºUqSY•€ÞU(ëä*&ó‹)²—Ñœ±>ö3=…×ú,ÔÙ߬ĵD‡;³¸aÓq½ìÅÍäÝLxE$@$@è Ï×Î c ¬†:*ï½â2È.£¸é²±~—„n1ï_ÔØ‹59ÉÛÒòQH8=5Ä$¤¬ Y]²nPhñlÛ/‹Ǿ>¢¥š‚û>ªâÕgòäì–oUàÑ¡ È’[_kæ5ñάý÷Rl);‚²ÊF|JÆžs 24ã¨e,u˦vïVl)=ŽØÄTÙÁ´—®-œù6+ͺc¥ê'3úgÈ¥Ò>Ä^åú×óŸðÊ’o“ôI}]‘êæ'O)èB$@$Ð øz6uGÔ™HÀÔ±óðð°óqøP¬}Û€&eÿ1Yw:.¥?€xGà_zùÈ¢}ÎŽt\ñ‡‡1³ú0jŽÔâx}ZE>§#é99ÈNõÿà}™36 tQáùÚdì¢ÕƒjuΪ5xfIKÙÂy—#ßËøwtÿ±¸á†t˜Fæ÷{wÓ‘JTk˜ §ù¦oÄÝ„ãÊöN²Ìn¨ñ” Â+K#*·©º£_Ò¼-,¿9Nhš8®_i÷†–å$Ììã=;:ÅÚ~ªf¦ïXM—æ Q2«CЮAÙÁz OÃT¨ñ”„Ã*K ŽÊ–È€{L„ÌùF2°}P'{RõÑ4¨ÞVŽzhˆ+Âðèhš¾Úí2(öѨF¥¢ .Ç9EY8q`3þþÒR×^C»ßý+Þîÿ.aZþÐWÝr))³ïÆ#o?¤üëq@fá©FÕ¬^øW¬þl~q÷4›á( C'¦b…b¸=¶ÿ·¤?šQ ÍlDÉ›3ö÷òàfYäËR•+\2¯þë«ö«¡@Û/¬©jþö×Õ"ÐH€H€|¼Þ @w%Pµf–jKLO¹mšÌ½ýˆpÈT/GóÑzÃ5!Î3L¨ñŒD½\žf3¿ãd³˜´#%Á»ñI÷çùÛ' ­V¨ni‹YwýÓô=Á22qV2ùÍ.ãÒêw6`öˆiž3¼jáÀðÙWa¸áçDMÙçXôìBl•I(_,†£<™eÝ›(ö÷Q¸äI×R“»ß}÷}QˆIù±¨øl½k&“‘\P!ÈW€«æâ÷ •ýÂváùÿº…“'!¶¾ëKÚhAÉÆÀ$@$@]‰@Ï®¤ u!      h'†xm¶·j¿é˜Z`]+°ÔõЀ¯Õµe0²Ób´0¡Æó—Eˆiê"•×àˆÓ6[É–]Vþ€¶ˆ¼=m¢û”ÂÔ#nÜE˜ª•4·¨ô±¸dr¬zw°‡[ü—¹ÍËÉÔܱ¸îüv¯Ù-;‰)³ÞLGd6®ûí|LÊÑÜÊ·bõÕ¨”5ãr\>c°¸Õ¸ ö"0Y2&_Ÿ\5ÉH|ëªÕšQi0.¾ár×^bŠ'|4ñ‚H€º=ÎXêöU€H€H€H€H€H€H€HÀM`Ëâ7];®(.³®žÒònÑ}³]ƒêÊ|‡¯«µ hÜY¸®Ž7Ñ\”=RåRì?¡Æ³%m¹ -Íäæ‹b›¢A޵éöIU 8ªåtÂ¥€%[Þt4Qî!°äþ}µeçÌB:kØ ¢A«“æA]Ç BqŽ,öX.±î¡–éÈ6Ò×RŠËÆ%w?†©Ue8XÓgD’S"#Õ­/E™Š{<-zÀ§dÉžp)þ§è\”—ÄqÙWÙ!Ëáçäf gŇxGË(Ã0œ3’ tQœ±ÔE –j‘ @Ðj7áå²ï‹räÌÂäìhõ:Ø£ FªÜêe¶ê°ë3-Ÿ„<¤êÙ„ÏŸ|!¦™–®¥Z‰Š¯Õ¨B½Ód8j©Á‡} ú\Ÿ¸ÁéÒl{6µÔ¡lç~Ô·è2(¢5bçòð¢Þ‹.Ǹô( ’S!ËQ™}WQS³$M5_â/ÿµÀ˜•wù¥gÀ*‰E,Þ t3îf»™âT—H€H€H€H€H€H€º&F|üØ/±X$7t<¶ß³Z»MÅ­Þ‡\} :quVïE‰¸_1²˜Ðr¤«µ¥²âΜ‰‚äx= qn¿a,~÷¼ ¯”¼ïÚ„¬œÔ–W³1¦Ü| òíù„ïTÈRpñµ˜´á1¬–ÙU«Ÿ %9YHn<ŒÊƒÇU=ûMÁfç»uæÕi$|=w¤NÀO.Û‚ÿ}s+plž~`òŠ qbÏVTj3è0l..k5ªú­[M{ñÂÿÕe€IËŒ´$`kÉ.‡B\Y±ÇžNM•Ÿâé'—ºÂÅõËÂÀôhTK¼j=fÎtÜÝcNøe©Ç§z K]úÇ"kXŽ,x[·Õè’`Êm`¼ÍÀexò‚H€H [àŒ¥nYìTšH€H€H€H€H€H +ˆÐ·Šñ©d_8l{È´47¡³Æ …ÉDd¸Û/zör¯;–gKP§ÏÃÝ7LÑ¢G¥aTŠÅ,¬ž3Âûr¡Ä;%²8ÒqÉCwbJŽªBƒÈ¯•âŠfáþÿ˜kZÆOS“§ÓF ”zž=õzüäªI†Œ»KÜF¥¼WáÁ[§xÔ}¿uËÑËØ»©º|—Ũ”7õÜûÄõÈö2£-2Á]÷VºâéF¥Â DŽ»g!Ù³I!ü²D!µ Vã!mtÛV·Q)¡WýÇ/1§À-«Ž$@$@Ýš@gŸ½÷diin½õ×.™YÙHuõ!—üii};µáž<ÂE’é@÷%À~¤û–=5'p`?.’L‡H€T±_u6Õ¢bßôãSCƒla““D/ƒíö25ž=ó}hi:Q{ 5­QèuBf+%ôEvºLMáqÊœêzþÔÉò}5pÄÅÂÙàDBF:RãB[ì­YYròpOœ@ë '"b{£Oÿ4©ã^,Cfb-¨­«Ã±c8ÑzB–¢‹E¿ŒL${1Òš£ù»U–¦†Z©;†Æ†8át¢Wb?dg${Ì´ò—7ý‚'pªëyð1 @¨ôöœ”Üæ×=¡fR¼êª®xƒrðgŸI.…g‚ÁK       ðpD'#7?øY¡Æó§Ahi:œ‘ËÙIþÀv2¿!ÖIojFE'!=#Ccd ’S•?o©†æª,ÑqÉH—?$@$@$.…%†!            K¬$@$@$@$@$@$@$@$@$@$@$@$@ðX O_ 0 Ø8PWÑ#\ˆÉ#\$™ t_ìGºoÙSsö#á"ÉtH€H@%À~•5¡;`=ï¥LYÏYH€:ÎXêl%FyI€H€H€H€H€H€H€H€H€H€H€Hà["à1c©_¿¾ß’(áÍv_E…+Á’c áM˜©‘ @˜ Ìžæ™ Àé" Û#NW~ßv>œ±ôm—ó'           NBÀcÆR'‘;h1Ç¢Å?hhÝ8ÂÚ=µíY,8xC$@$ >Oüƒ"ÿ|º«/ëExKž<É3¼˜ N€ýO଒ìí…DH€H £àŒ¥Ž^B”H€H€H€H€H€H€H€H€H€H€H€:–:HAP            èèhXêè%DùH€H€H€H€H€H€H€H€H€H€H€H ƒ a©ƒÅ            ŽN€†¥Ž^B”H€H€H€H€H€H€H€H€H€H€H€:–:HAP            èèhXêè%DùH€H€H€H€H€H€H€H€H€H€H€H ƒ a©ƒÅ            ŽN€†¥Ž^B”H€H€H€H€H€H€H€H€H€H€H€:ˆ"Å       èîcñ†¯Ð¢ph†œ1 C“øMlw¯]]ÿ½[w`ýáD)ŠÆ¥böýÀ»®^êÔH€:7>§:wùQz 8¥ì)ö¯O"2Â)?î0ñŒþˆÓrtûYEhiu‘ÈJOENÿô²zóŽHÀF ®ú+¬ÜPŽ•e‡QÝ žQÄE±QQèA –“…â¬[Ì.zÛ|Ÿ–BK„炱q±HKíÌ”ƒ.­XôÒ"üa¿–DrÞýñ(£ÿò™p'ö8Q¹¼¼ÃÐàÆyâÊA®á)ÃÍßE{ãûK»#ûµÖƊ϶cñÎ:T·8¥í9\m¯_J ;#oÊL$@§ƒ€õWÏéÈ‘y tÍXòÖ&¼Ü¬‹…Ç .D±ëw½ÝOc?ÇàÖ‹'â²ÂÞvÞ“ 4VãÕ××â¹ýF#S™·ÀÁ:,Û%ΟÇ[?Ó¥|U€†ÊÝøÏ%îE_á\îQ1¸qÚ\yFš-ØIÔ7;‰Á»‹­N£â¸4mFp:·7~gÄ{hó\¹È[]SÛ¶íÇ)¸iˆ: hÝ,ÈÉÃß… —]/Ð祌:ÖÁÚy²‹ø99¸ë¢3Ähd­ vnW$e Ocª†lÅâ×–âÑr=^^«ÝØe0¿‹ö´ÕH‡ðêýg¡¯žœé|hk‰ô/Õ&Io„ ÖwZ›…I5ÛeòÈXü#+ËæÚAoVÃc¯®2jÑx.Ú‚}!aWê~g®«!)í5’÷vï-¨ÂL>Ìé$í;ÞlmC}W©öjÉÞWu¼g¡·ºE7  …€õLH€H€HÀD ^ŸžärS¾®üÆðµúζ‹F<ýÎJ|xø¤Í·$н œøj®ýý'žF%80 9 ò¿õð5ÀªÃÝ5(³±ÖmÛK×â±··àP ¶Û€¢_¥šñÜŸàÚ×w@™ìe9\k(i. '•Õ”ºÕq¢m£|%¿‹?ùϼý ÞÜqÌâëíÆß[ˆÎíÖzx7nõ0*Iû‹·~Únаn––ïÆßÙmÔ¹Àž—*ÏŽ6Œì¥åå¸éÉ÷°¸Òjä„›…©¨½û“•&£R~}ÛYÈ0ƒU뻈=m•b5>®ôÖâ[±f­Ù¨¤„¶¥§&ЩþµòéT¢w?a¦ŠÝý´ŸÆ¶>%| 3¥SI ˜¾ª£= O%¦M$@™ûëÎ\z”H€: øt6æf!Ãã€Áö™î»æ¥­Œ|(Y'ýsY£ì¡©øKÿ8\úÇÖºƒXº®JÛŽŒÄèCdO&wy˜ã´HkÏ$Ï ô[±wOµô7žÏÈSdX½çkH—‹fyžôÏÊÀôq²ŽG:9´¿? ²o·=Ñ'-}lêõ9®ýª ׂLësÏð°]¥¿-nWºµ¿'xÕ-”ç‘9ŽR§úÊ»gç}¢î0v”7±ˆžHÏê‡>¦ ŠßšÍ{QZ«¼gD">>y9Ù²o¦gëñ*·Ý1Øw ³Æ;\põ>ì:¸t  ¯ò&»£ ›¾Øƒ’J™§žœŽyged)ÉÕ&,éKÙåIÙÉü÷O?Ý Õ²»°¼K§ô˽®ú}Ô»±dû×®÷¾^ }0cRž¶ì­½ xO$@݃€ùU÷ИZ’ „Ÿ€yÉ)I=.Î<˜þì˜" t^ ø×'î¯ó=fÏžèaTjK¿íëÖâÖ%û=ƒm®–lÀìs&â§gõ7 ô7㟠W»÷L‹Ê¶ìå¢,Í7ÿ×u8ðø{4ìÝŠ[ê~ÀÕOBÊºÕøƒ%ûýxnYžùÙä¹T$¿¿›òÓR~nÑg®«ä‘ãðô è°ÍêPãÄáÊNÄÆÇ>ÃF#‘còcÿ†ŽTfâ4ãý—d©A}ߦ/šã™çWà5ó #¹°…·3¸ä¼Ô}RŠezú®¸Â`åv<ø£é8'ÍúŠ|y)*/ãM¦rºâ»³\{5T–z.ùv°ó_.W•²V÷ÎStôߥšòOýA<óÊjïÌÖîž4<þýI(Nƒ•vعVwôاöÜÚ*#lÆÑŒß¾ù9ž¼ê Ël†·‹f§ùY«&Zê„·ˆ’¯SYVÖ›ÑÉ[øŽäæ]ö>CÎÀÓã¿Æ­kÝ3—6®ß‹CbXò¶Ï‘2‹@vGÂ3/l@©®^r™`Ÿ Ç1Ÿ•~Ǿ+ö6ãÊúo#V|~X)sµÜ’åÊW ^ôhE‹¹ZzÕBúGéŸþQØ?=Í[ÿ±Ûúµå8ï¼³ðÀDu&èú¯Æ#¦~ÿÆ\hâ«Fm­Þ‰ëj¥š<ïÿx¸kзõp%~÷Â:[Ÿ)qd³§—ìÀïn›Š±¦¾Ã"ˆ·›0ôGÁöãa×Á¤W«V' '¯Ï=Ã7¤þØ»ë]¶ÅK4åyÔz¸\ÞŒ^ ˆÏÁ»óϰTOâ“wVmã§×ÍÅÜþÊ;ÀIlZþ1î^­ô;¶ce) Fã³rMïi¶0^nCy—°ë\½¿nµ¼?OÜþžeæ!{”놥0ô WÌ…£+¾À–gIþða&^ÿY16ýߢúã#M³Š$ÁõûÝór¢Ì[ô=‰ÿáiTòØ×Ê, …ðö2»QI܈‡ž]…½¦ÝÐÊ«ý2Ú÷±Ñ%ôy¶éh‰ßX‰{ž´•P棶w?õo¬7ÛMmiZwŒ4OáEZ?ë‰ÚýåøáïÞ뛫½‘‚ʾ¹[ÝÕÏÕ¼/¡;­DDuF£’[oWC'Á³‡F4šÜ×ñQ'°~Ñr¼fðJÀ“×_„»CqeéWÕxÿÚhš9}X–ÁsY‘ܳë•T½é^-ýc­ žÛŒJ:ùeË6`K£º¿æÄ©9º³ëüܪ}måËÏöa®ž6HI 3Óîø‹Í¨dy>ÔáÞ§V〳‹0õGÁôã·m¨è×;Týý&ÚÙ=Ö áy‘–‡Íºú}ø¬Ú¼<¡p«¯Ä+ºÁ5>縌JÀ¦EÿönTÒP—n܄߭;0øÐÞ%$y›ÞÁÔûpë`U6€ga[²ëýH¨m–þkKìF%MâæýøÞ#ïÙŒJº6ÇðìgõžI€H ÛàP_·+r*L$@§€€ÌX’ïΠ,§µz•쩲Ö<²Ì*Ð÷=9y3IèLäGl¬YÞä>ÈÑ›Ý}\·ÞM³”¯ï:oæŠC]å6Üñr©±ÔӾͰxlfiƒ–$m³ -~ÞÌž4#ŽUâÑÍîö^ºµ uÓ•%CÔ=Ž2ß[†‡¶é#¾Q¸ÿº©˜¨åÓÂqä’¥¶dÉ+ýð™ªEߣøÜ2‚™Ž×ï?Óµ4Qks3}µÛ’äŽÁ3†¢o]…ì+gþ"ù0Þøâ~v†,-ry…KF™A:ð ¼u]oÜñ7÷KɃGáù¹²dž}¬¶9¥é|+m4Í “ÉI²ïÕ_¿?\˜5âÃ×—á‘]z7âÞw¶á_× óû=ÿºcÊú^ö=cnü¬ ÏY¬ Íxn‘Ìtû(¿¾t<Δ¥(Û>NâÐÞ2<ûÆXmÜoÇx3 É̺Owã°ÌÎh1}eß'k†{YbÉœd‡¾–½çÊìÓ&žªaÍ“Á«o-Gm½^g¤»zªìEå.h}ûeãÖ„*<­ÕÇ}Ûʰ÷¢l ;öî/Ê´ÙIQ¸b| þ½¶ª ÎVRˆ5bþ_£ÀôÁOCƒ—]>sÙ[>ÈʬÃû'&cù‡;°Z/IoýWM>(Fú’\ÌF9>У—ïÄ—yÆìV8«ñæfÝš˜†C”ö#ýÇ»›Ü3ÓÄåê¹çâš‘½q`óZüp‘>"_%;q+Žž·s¸û£¶ûñðëàM¯@Ý­ ùvìp¥Wã¶2síDCRž’ç”Ï÷M%ÿÏ£(L“{Ï}P­…–}c7X÷Ýûå.ã½ë¼3ó\ï­Õ;ðk£-HÔäl¼rÙ{/=ó^ÖúÉeò,¸}ܘ6ß7B—ðUnm×ûpëà)IèÏÂу³1:±{"û†»M(l¡yk)^ÞïþA—ÿ¼Ñ9È:z/ïÒû:™YÕhyÉÔƒòL$@Ý‚@·1,9OÚ¾,éÅK%ÃE€õ'\$™Nç"ð²å½åpŠƒÚl~õå¸ô‘rKXãf`!ÎÏphñ W^@·$p¼Jö2k.¿E'¿‘EpÔ/ÂÍ^Þ®wnØi =óì3qANŒ«}Åg ÅÃÓáÚ¥n#ÇÂM‡0£_º$ek³âbÎWiÛæÃÝÖ•pfåÚùWž9•‘Ë,T•ý ¯è3Ä©‡¦Oˆ^H‹W¬fú¥iɱˆŽRt=é%]µ±ç÷Í7ÂÇÇ{œï°~ôm>.{M‰ÆQ5eGqþÀxôˆˆ@¿!æ*Kžö| ƒºã ‰Qtˆì^ËqËÇnÛ§e5pÅ!äò ƒŒß(å p“ñúøä¤Š¤û4ûÊ}|¯^®;­]G#~sî2®$á¿/†Þ’¶Sæ#Lýî$lüír,ÖÒÆþ½øâhŠâ•üuGýXÝÑCëg]Fý><ç|ïæi8ù‡xá-ÅúÃøÏ—ãÌqcñ_Ó²¤Æ«íÓ®ÏË ãe[Týöî9CábäYß^ùÞÖjçÞ#£ðú…™6×Ss8OOÙÞãûkçæ6*)ú9ñu}“¤i1¹›÷®+¶¹Ž}Ó £Gg»Êµø‡ñQÙ üpP‹ì¤-ÓßçÊz¯­ugá['wWÞyø‹N?O>¨o´r”ܾn‘ÅÖNê?ý=ãôX€¿]Y ƒðßàŒ˜¬~K7øÈÓCïKˆ ÇÅãƒuz‡ßˆ~þ5FŠ1J9—–ÆÕ¡g B?¥þ+ýG¹»ÿè=p$®žèªCý†Ÿë?Ù´Aö5»kqÕ`½_r%iücÈÖþ(°~!ê`À…½ø|îµCÿÄ8-AÂÑ^ì¼ÁKkÝý.EZšqBên´þ;Ðw™>Ãá 1,}®Ñ)ݸeÓÒ‘íPž DZØxöÇ`na’«nïÜ´Çô®æÀ}—F¿å™™ˆ+gåàåWËÕÔ꫱·á1¬+iy¶Ký=-äw IÕ“U`õ>4Tµ¼ÿë©_[ÏBOÙ•wˆéòþí΢)œï(Ixôös]ï/(ŒÁš?®Çv#'nùÞt\:HÉ» ßüÉý¬‡OfŠP}W0¢ð‚H€ºýí²Ë«zÂý>Ûåu¥‚á'Àú~¦L±3ø­¶÷ãù¦¶O?o /ÄÏ/È—¯â%¼·t#îF 6Êб1dñ š¥}öBveÍ‘(LÖGk“*He$_ K;5®ûÊä«|gºÌ’²µY1Ö˜óm–¶m>Üm]ÌB6¿sÎ;3²"µ|{²dZ³=]sª@K‹ô!~VÁSú{~'~Çš–r§ º˜wX?ú:R1QVüÜX¦¿ú!ŒÇ•ãó0clìGì2]yñX ™þ~9b2?þÜ(×#û¾Fµs@èå[ÍܤޙÇßOJ9é²ëüì:êñµÇP¥’sæÐWvÇOÂÙE1X\¢ê5bcÕqäÆx”e0uÇ”¥‡¬f¿ö]Çã’kæ¢`í:üf…̶³%öéºõ˜/MªÁÇÎÈ\»ÇÝWLÂÔ‡&·­.z$ƒ÷=O¡žÖLÝegu÷¼ó”ÝÜ7XÃûÛ·WÞZœÏÇødoËYùNWÉß’v³½eæ×x™U£ÛÞ-9„ï$Çë-ª´EÃsaôÀ.Gß:©qÚú7pžm¥Š¿'ÄÅ HŒüǵäŽ7ˆq¹‡¹~Ùã¤á‘ï E„ô'$ÎÉHëIï ”äå"iÝf£­|´® ׎KS{+V¬Ö¹:0gL_W}>Q}Ä40 Ù»[rT¦¸Ÿ”%WŒ™JÚÛ+kÏ+[¹ŠŸ.C8û£Àúñ袊N–z,‘ÜÏ2k íÑßšÒ·wŽöbç¥h“Ÿ&›ÜŒÉËDb$NjuZñ·Ç øyäHÇœ<>ß­(Æû;ëq]~NT•}KRÞ` v½´b‡å]͉ß.Þ€bm‰è‰šÒ½Š8Úш-Õ'08SùÇÖ.÷´ö¼ûyêX½Ï Q]/og›~Þ‚(LÏB{™Í˜©¼F[ž•íiöô/½x ÄȧÖÑžb”t™b¿P ZºŸåÝWÞåÍuÍ‹W$@$Ðõ Xß»°¾ž_;tae©ZØ °þ„)ì$Ì‘ŠÈJ[ÐÛƒÕ/ ã²õtäHÇ™2ø›(%N'Ñ—b’À©&àŒŽ´.…×ЂãÒFÔo´Ûʽ‡Žš[“±2x¨·IWl<4/Luµ[ñ´¶Y·»Ï’†v¯»ég%œr ”µÓÌn~ÓµÚ}TYìÔd]ÿ*éšÓv9JnZœÚÃúЩæ` kÏÆ•¶+X¦~g$Þ}i³ar9·ÔãÕU%ò÷%~xáÙ¸¬ IKÔ3§Œ[dŠŒt-¥§«"²§ÌÜjOy…AF3Káb) ']I‹>âèâ%i¯k0‘•°±q½¬º‹[”Ãj-ÔãÚÓ ¦î(yé‡=Ý=<çž2v^*:†Ë7à÷_XÍK;K>ÇÇcúc’=ìr$õN¨DùvYÚYtb"ÆdcâàTW{6‡µÖE®ÿÎDÈÄ4™šs|ŸôãŸg*fÙ<}­.VÙÝõÂJ¹kÄ1`˜Z´ç÷ÃYE8°¸›ñðKëðçùÐßps_ø“Á’¶ *;{¤`ú ÖîQáÖíى׷Ξ‚Ç+܉˕’†%‹oÛ7í‰Ûvêm‡°ò‰Áß0ÃäÙ`?ÌrZâôŽ•ˆÂ@‹`§8)÷†[R.KÛŒô•ÁöaõјP‰wu·Þ1F–zTâ474ÙÅÀ«Ìë&ï#M2ÃD}ùiÞº áìëÇC×Á¤Y›—v}•ÛÃMRiþm qšxÓ+جíiä>žÛ×3?õ:˜çшqe=Í=Fúo­Ù‡«ó °y­»._4:K+³“¨µ¼«I´Š}xÙÚíiÕÈR•º>"®åPÜb´mÏ»Ÿž¶žp`õ>tô|¼­úµý,´Ëžo}ÿTòhO›°§ÑSYaC“\Ú üo±²”µá'®z0WÓ»¶$@$ÐMtÃR²‘ëOˆà­“衬 d9”¶ v§6¿ÞpÏ÷F88nI’7$ЭôEµÔEƒ4µ[`Yy ¾›«|­ÚÖao‘ôpèmR+nú¥ëÜCZ•öjk³Ê½Ë] ¡6l#¦»­ËJj6¿fYÞÈíæ?][T5O«€FžÊ…š¯-€"§=!W¬f¬\§dªÉ ÉNÒÂú—+Z6ä~úöd¼ûþF<¿G_ÖIMCÆyå½åb)8_ÊE5ÓÙó÷”ÓÆ½E–¼ñ9˜ò’ìÃ*£‡¦¾t´»K¥ó(»ª:{Ü`êŽ^ÊÙžŽÙ/l×Q‰˜:ó\Œ.Ø‚û^ßi2::±·®“Sb<ä¸hæÙønv[?§lìÅô;d`2iòaSΚPà<í²ëmÔšžrw¼¢ïk³‚\¾‘)È’}“”Öì‘_â@Ì¿ö>|±ÔÔõOKî{c'þö½!ÒKšÿ2XÒŽì“RGž!ËáíÑ~l©ÃëúZFq"}b½µQÒ°×a³m][dh+pØý=ù8O¶¥-N‹Þíf×Gå£3녳Ǧã…Üó—}¹Ã’ömfú¸\Äi@{DèñÜŠŸ=4 ½ÌuE¼N´6#±?™Y¥ÊáK»{{ú#«^Š|ÞûñˆupkÜö•§^j™Øcz† ¼?¶§õmÝ{è‚ iȈ¿‡›-]»0Ï£è¬\\¹ïéõö« |þu –m×f‘G¦cŠìa¦Õ^[ÎrÛ[ Þ2‹Õz8q´) cûEk²»Û N­vWW= øÝϳÿU8XYx¯÷VYå. Áœ¾M^ 7›ŸíÚ¤4/I€H Ëhë—P—@I€H€Â@@¾V–O lÖEòc$ÐY D¥áÜlùš¾Bÿ6xeñfœ÷ã1²”P[G†CÇ}ɱzì¬nŰLÓë\C½,e:úÄzo—–¯Ù[ññgÚ ¬)jø/íƒ*íË¡zK ^1–³SÒŠÇÙ9q'‚‹.Ž ›Ž¡ä‹Rüaå~ËÌœe»¾ÃR–×ôì3tNT× Ä23+MvRCyµCF“8ž—¦*ãéiu‰MKE¾ÔªšóΊéïûYêUm­y‰FúÆX*˜5Á~—˜=wŽù ?Û`78z ÞìTFƒ€éJBÚ¾åSgÏt;²‹÷emáõ÷Ê-bçÊòÙ§5;å!µ:çn_éÞ®®b+~»6ŒWv áÐ}c³ÊrxûŒåðô”ÆçJ»#˜îÀsHRòs1^ Kúrƒ;KÖã§FJñ˜5,Á¸‹íkí?Ð;wÎi3ÁÛ¼gX?."…Y‡6•ô œúûɆ^0c|Þ[¥ÏhmÄC/~j„*‹4—]qŠÂpË»pÃì³pQ¦·¥>$ü\„á]”z`õ>Ü:˜0.Ãó,d›0€ò‚H€¾¡>ݾaÛ“i™ÈÊ?2´ØëZ ñŽu¬kÕùÊÍÖ”{UGO?e±kéÏúÌòl°5!i#=0ñ¼|«³,%tÝsëP^/_Jzy_i>Zƒ?Ý-{OÉI–…îðU{\cÔz¼ÍëwYŒ#㤸6®VÛ®)Û# 8$éõ@3V/úÿk2t)¡Üm]aàyèùy¤ëW21ŽF›˜;®y‘5êgDP/dOsœÍ X÷ÑJÜøÁ~KÀü1ÃQ­—™ªƒ9€[§“8v´ÑH3":cÆÅ+7Œ”—ÝG¬ëëuwznà‹Ý‡Œø=d™šO¤ÌÇ ÌD—èåÕ~y nbÈ0¦ª>îö3êœYõÚ?&éf¯ê=ø¤ªÕ¿¾¯ï1–â18-Bó7G4¥éÊÓwÙcz²êåú¹±¶•bóLû$TëÆ[M±¦¨áì’éîþäð­§gÞþÒ ÝÏ.uàùzÊ.«˜9Ô>%, 3•eð´ºgŽeM¯mÎæ¸Êuà<ÛN;ø´<ùØËÈ3MÏ8Vv m:FõÅ|Õ8IC‡`ˆì3cä YDÌ}Ù×J¸ý6}Íæg ;Š~åJ3ŒýQ ýxu0q0ôôå¦ké> ÍqÛ¥¿¯¼O­»[#õÊ«^fº¶¥jOðš†-ŽÜºei«M|ƒAÃs]û z¦…¹EýLi}ƒä>²Ö©éxþƒÏQåzç²²>ÙÜlz‡ó-CèïJ~Ö#ÐzšVýÜ|U9ì²Xûoq­²+wÖ4%N»Ú„¿ôýû¯‹7ý<ÝDbŠíHÆUç¥àãeúÌ'ž\ð!Zf’Êáµ÷·³™”XEF"×@9˜²ø6.÷®_‹{Kš¡ì“4kh_Ùø=IŒ°'ðéš­x¯Úl°~ŠA·ãëtê96âÞçÿ…"åK’HjŽÔc¿¾4”)óKfOÀ01ò¶}ôÀÔï/þ¸KMé<÷úJäß>=À4¼ç2¢(Ø^îöLˆ¢Ä@drGéœWî22“]Ž·Äã®&#ßns AÑᣠß1¿?Z¸›¥ÿ˜Ž¥¦¥ó^ûçr,^“ŽïL“…!›°ÿàlÜQQ9XøãbÙ‡ÐO9…±? ´G¸u0ó ö:Œú›uGo¼'È –CîÇü3ûXœCºIÌÂEi›ðgë ¼€—¾¥ÿèQ¸pÙ‡xOÏèÈ>Üüûƒ¸pÌ@dG‹ck vî;ˆ¥qÅeà¹J§êûù]ÂK’ÖûpëàE”ð8±M„‡#S!  tÃ’ÇÚ«!c´îI€õ§{–;µ–µ¬mZeìQov?e9}ûŠÓ¶è¼%nO@o?c.˜‰_D|Œ‡KôeUT4ke tívï˜\mL6¦¿ýûøâÿJ #ÈNÜ»×c€Ï¿;Cz)i)Fƒ(œ5: //3ˆ¸JE²áKÉw«VóR ʵùè©´u“£;–Ê©ø»òÊCæªnãUÃa<¹D ‘ð÷až†%%]SÒF¶;«}/K–?´¿¼hˆk‰+UW5š].%]—\2f«i¨ÃÛk”?#ÓE~|–̸Ðt×Ϧ¨;°OÈŸý˜3s, î!–Wd´”S¯T|gxÖšŒ™—”º ”—&f`P¾²UsüŒ1q÷Þ¥x|·NµþÀ ¸Œ<üüœT­ô•zâ;MÅGOMe®;º›r6×7³{{®##Ô™2uGêðšÔ_ÇŒó&bŒk*›gÝ43ò_q·ëi~–ú‹wªü‚ái— –e­2Æãî+&cj¶uf¥ÿzÐw\3ÛžÛìî'P{lÂK?*v-§g—ÁÌÏž¶^‡âæ`N\9þÙ,å,ƒËsÆf#Z l£ÜÃĪsûâÚÓ åÞÎÇ_5Iߢèkãb µ\;oõ<:+—FîÄ[&ƒ "311K™­h=úŒ‹_T|ˆ‡·èuÕUøó2÷>M®QNÙ›NäSþ³%b–!\ý‘’g`ý8ŠV þïìú*¡}ÕÉPõ÷/Áéóõ¥W0xãåë=áx}‹‹¥=޹N)yÛÛ„^ÝrE`âÄLüy‘õ¹éÄ£oq‡MÀ®+ÆŽ¿m2}xÑŒ÷6xc{öpŠ|ªµ×.ƒ"³ë½EzÂÐÞýÔöî–K½ ¬Þ‡¦ƒ=/ó½]?s_n§_·Ufz¸PÛ„ßô¥¯´çÍu×®‹g}Ñ¥ã™H€º6n³^×.FjG$@§‚@OôŽ5/Q…ã©aóóÿ¡Ý©Ži’@''ñ3ÏÅßXŒ9im|>'3`&"GùÊUŽØÌ,øñY¸Ú6x«úùÙ9xâÇâ;¹ÖÁÝþc&àEæÅÞ”\9w~1m ÝåfºÃamà‘;#åÅ@IDATs¿Ä™½¥Ï°|µŸÿ¹¢Pá`N4ÊÎägÏÏä後ŒrÍîúÍuà èäöì}”IfYúnŠvJ ECóñôOÎõûUÿ9cò0G™”d9bpãÅÓps‘Õ#¤ò AF;7{9ºà\Ü=ܺ<"~/ÍÀâ?~¦^zžœ™#û-y;bpõÌ3ñÎFj>5Œÿ4Û¨;Þ² £[t´µ}Ø“Nê†û®˜ùcÜP}Ú)ÆVÅÈë~–Úsíh÷vٽ˗)³¾®>o^»gº‡QI‰áÁÍÖ‡ 9Ïδ&~¤ JŽˆ›]+?KÚ–þ§7n¾õb,úé\,ºçbÜ<½ï%N@eh­cÝÙùø“ε»¶Å‘ÙgæÃa+Ÿ8Û½6Ó'¹Û†âvΤ<ûjÉóî‚óñÂw 1Þ×6x"Ãøœ>ÆÞmÖ2R&È™e ­?2ëè’7ˆ~\ÙK-Xìùù»·ë›o~°Úc†G{ªéÞÎËŸì©ÚK‰=޵NöB‡Ë¹§ËˆÕ–ˆ¾ø„K k:=e`'Nþ¬®ÞîìrµÈþ=dxH1Dµ¥“9½àË+pÍùø»vÉÐÆlñ•$ŠARÕÛû—Úþãïkç| ÞcDDE¡OŠò×½>@;U<½Sîú®ä\ÇI¿)5ÂtÞÙË)Ô~\<¼:´Eàú·'—pƵ—C8Óî°i9¢äãß3—‚•;˜w ;ïë}˜uVçÀÃw¾6¸n I$@ K¯L(Q$`!ë€"R$  N@€Ïÿ…ÔQùx“Ë››íè*²•œ÷xäéK¨®ä*¹ÓÏ[9ys;½Ru¿ÜÈüô–¹7ÞÞÜN¯TÌH€H «ð¿VJWÑ’z @˜4Ë’~OüSê¸|"Ð/­{íÃ㿤N¯oÇ­§—C¸r#Ïp‘TÓ!ÏðòÝÕ—õ"¼%Ožä^L'Àþ'pV I$@$@@» KÊL%Ũ´§ºÞг°%ѸîHü2¦#•Fç“…õ§ó•%& ŽH€Ïÿ¥B>þùtW_Ö‹ð–OÌ4<¯ÉÇ“ ]Ö‹ðÖò$Ïð`j$8ö?³bH  èèÂjXÒ÷\²+é@r\¢#¿½ R\Ë×^*¼†ëO0´–H€HÀ>O|‘QÝÉÇ?ŸîêËzÞ’'Oò /¦F`ÿ8+†$  ŽN ¬†¥Ã ÍØ¸·[#ZôÎHŠÁèÉèß;Úâ~:oÖî©=Ù1¯.F€õ§‹(Õ! o‰Ÿ'þÁ“>ÝÕ—õ"¼%Ožä^L'Àþ'pV I$@$@@X K®KG½ê\Ø’èÕŽ$@$@$@$@$@$@$@$@$@$@$@$@ƒ@X KQå9Ó;¢X”©ƒØWQá’p@vv—”â‘ td|žø/òñϧ»ú²^„·äÉ“<ÃK€©‘@àØÿΊ!I@o/Ç1YH€:v–”½“”eîÚ:”0JX$@$@$@$@$@$@$@$@$@$@$@$@—@» KÉqQ®½“ÚZæN1*)ay t^í2,EGöDÿÞÑW{JN$@$@$@$@$@$@$@$@$@$@$@$0ž‡d@            nM€†¥n]üTžH€H€H€H€H€H€H€H€H€H€H€'@ÃR଒H€H€H€H€H€H€H€H€H€H€H€º5–ºuñSy           œ K³bH           èÖ"ºµöTžH [h­ÿ›>[ŽÏVmBéÎJÔÔýc1âÜ9¸â#?Õá‡G–½ð^yw-]¡b1îò›qËÎD¾ñï¶.}¯¾ñ/ì<¨äÄô‚™ßÿ>.™Rˆh¿qmÉÖ—cÙÊR *Êæa½mn†ž3¹ñn}*K>Æ—û[¼G•‘™gàì¢~Ö„½k=ªŠ=غa->øëpίÇÜA½lõª|ôn¼ýÆ•XøŸ +‹q©u?þôÝïaa¹5Ê+±sÍ2<5â&¼óʵHíá%®-ŠrÛ°{ þëþ½øx:Í{ö}Ü>.IóhÀwÞ‡—lò[b¥\‹.» ½ƒ0tµ~õ1úåŸðÑšJKRCŽ5ɽÃR&,½· 9ô”DžÑº<¡ÆÓÓòy>Ï^x Xð>*ÍlrF@Ñ Úg< ìýßà‡÷¿o !åú³åoù®G=?kF¼#`°ÞC‹aI€H€H€H€H€H€H€Ú&À¥ðÚfÄ$@]@ëqÔ¸ôH¬[~‚Ç^’ÙG¯ÿw~ÿ C»…wÜ…ÏŽô0îÕ‹:¼t£Û¨tî=¿ÅÂ^ǯæOR½Ë_żÛþØã?q—aT:óº»ð‡¿¿ˆgžýfвøòüîÝ2í&€S„ÿy>þRˆÏpû&¥$Áò'^IÒýRܱÝW'•x•ܾޯÌrx¡¹&Z}CgMÅ~ׄÍv£’$ÒÔt¤ä%·Q)å<ü÷ë¯cá߯™)j …w|¯îh0ÅÐ/CËOÍ3 „F€õ.4nŒE$@$@$@$@$@$@$à‹g,ù"Cw ®E ~0~öÇ'‘3y,RM³‹rþ' ˼7=ú¹è[‰Kv`âåù†î5«_Á³_ª·Å÷<‡‡0Ìu“uý£Hl¾?ý‹Ä[óþ¯d~Td^ík”®Vgòd]÷$½cŒ–f> Å?Àbq©ùê¨æÞö)nø5XúÙ<¯££ëñÒÅáÙrÅ{ΦÏV²ϺåÏXxË(«£qØÌ)=x¯ÌspÛ=ƒQtΙH©zßýÑ‹º—s®|q.iõâ¦-Ï`Î5jÅ—Ÿeš=jO_UÓý<ÜýƒBKü±7Þ3ÿr->×w®ÁuEÓ¡§_¿«ËÕ¨©©¶é7HCž2kI3X©¡û7:ÚËsõÈêg5£pͳÿ‰ÂxïéÅxwÉ5"u®üj¤j8àlªˆ^ˆöúä©Á+¾¨Ê‘s-~mcPãùÓ¬‡£¾3šˆ÷ÁÌœDÓžåXxXu9÷¡ŸjF%-Dï1¸ãI¸î7«ò×ðñWWaV÷>W!?sÞ¼&°Þ…„Í#’ìõVSU…&1ŒÇ§e¡wô7højÖ|¾ -@\Ú`L˜Th5&Ûiª)ǦM¥¨V"ÈÑ;££Ç ñGÙ°ªV匈GVåCl]½»«e6ddòΘ€Âþæþ?{ç_ó‘þÿƒèI#*8!´ÉVD°X¤U¶%-m´lÜ]ÑTÝJZTT[Ú²hQT±•,*µmÒVm5ÒF#–®KCm²%%$HÈ!ᄳ?ÿç{=ßsKNNryÆKÎ|ç;óÌÌ{æ{›gæQ¤ú§àÔ1úù7ˆ9y´@ÏGúÀ—Ê\_ Oc!Žýû(ÎÏ[ÏÎÄÓÏOS í#x9góPTBño5D«Ž=Ñ#°¹}œÔWò³àÄÏS«5„‡‡|Zùâíá¡™Ø"&®H\û¹Ý•PæyW°s¦L€ 0&À˜`L F°;¼W£JÈ…aL€ T3Ó¥ßD¥’M6ÆSø:U ÕEö‡Ÿu·¶x4 ØOq »’pbÁ„(óx¶C˜?Yú6Rú¬FxiÐÊx*[d¥RhŸv¨´3eã­É²lð|LèéE" 6*ËÈ[¥Kâ²€Ó_,–W é÷þsšÕJe‹t5]ÙRŸ=µ¯|R‡‡ÿàkѯ{o #Å ødW='­p³‰ÈL€ Ô.%Ç1eð ´®ˆÞš„nG–aòRáZ×8ïlÚ‡N!>{#ï%gi"+Þ@ÌNX†!],•'¶LÆäu”›ÿT|¾1KN'1(©„ßAoÄ#î)ó [ñœé¶ÍŸ€5» Ú¨ä×㥭ëñL'û«Y­"×¹C3ÏIX?¯1^Ž~ŸîÒ–®Ï´åxç¹>æ "túôÎådú4É2¢|¤ ›Š­+FZ>¯ŠÁ¢1±;Ç6‰åÞ‡t¾"qmÅÝÕæyWñsæL€ 0&À˜`L Fà=–jD3p!˜¸›N|ûµš}÷îEÏ•y_&àþ–>ƒMR‚Æx DÙ£‰f‘[˜xÓ!tt¨,7 ¯ { Ëwþ‚|R*½0l±4 6ûJ Ê¹CkâäÇ@¬˜=ØN9Íò/Û‡´ô Ë:£}¡Ì1ïœïvQæ.hbbŸf•OÅp5]"Ë>E3Ë Ï]’ã´Dëf¶s3Ü[¡«"妴*A9ä_&Àj1ºÜ}äâo=̬T¢=ëTwy'f¬úA=”<l3T£T DdÌxD”ãeaÉ82cz°Ð"[£ÒqÎûxÚŽRI8¹{AÒ þ§IG{ަ*•ôa7Jyåâ½Ñ“ìì#¨I^‡½fžë1I£TÒÉ{ã Uß¿jæ~qڂµ3ÿ’uè:8Q£Â¡´¸!õ}z®“òOqôŒØgV*éz…Süô Ö‹17R"ÒoEâj’Õ/ó¬)-Áå`L€ 0&À˜`w€í¨ØÝ+ ç̘¸ãŒ§v`òªÃr¾–{•\<)ÎNN†jN¥$…’è®Ã`¼M6’Ì'ž]ŒeçG!v“4ð”üêD$+§ÏÁ×ï µkI‰â̯‰Ê?C–ßgÞ«èáEe°ãnK†ÔxÌMU"è9ïÄ ïQér(+þ[Н^Ÿ%sÅ«{ûu°”íj:K):jP¬î›ÿP´Õ´µ*Çt‹LIîÆÕëj0{˜¨kôxqûÙ³¸òdþЉØKf2 é'Q„GÕU,ùßoÄy…*h…Ëçï„Oá¿D}†ÑãÞ'$D¯Ãà#q´®ÈþýO7x*>œ7zÏ{pâ‹ù˜´ …däâäébôõ‘T”—²' v5ÓØ§wà™„†\|˜x½î³W×ÚÈq}"ç­BL$=ûÈ4]6­Jš ¯JÚ¿`+rŸ2·ÃýÝÇ`öÚÎøch{¸ËmóâØþx’V +ž²Ï Aê‚£gÄÙš®~Ôr$¾"¬`•œÉX ¸ Kšåö­H\EH þež5¸q¸hL€ 0&À˜`L šðŠ¥jËb™¨ùLyiâê!©¤:ÌNZd¹7‘›fz±Æ«­Y“æÒLda€ïèi+Ã: L¸^zMÝ쿜‹²²ÇXQ_!6Í\,'†éÕðVrn»£Ã pt Gÿ°n4p©¸\$¿5 ‰GÁíJàý-:¸KR¥,-‹E€õþJãj:✠¾í‰ÎýeÆžhç ;ν‰Ê77ýg`¾;\플ƒ˜¨2d²3éï’RIéÙA­eá÷†ìÝ ˜Q IJ×¥’׫Ë3X:MYõºß·ÿPÐEÎÇgJBÊ>(gF?곩ß*yyDÌPóóÀ=p¦†II²w¨ç÷%^L؉Yû«ûDÌBÜ`I9ìDš¦|{ÁPU©$PlЪ;žö—xZï[xSžY›þ#N™ïÿn´?¢º£”‰+'©?̳6 ‰ 0&À˜`L€ ܼbéŽ`æL˜¨iJŽïÀˆÑ²I:*Ü‹ Û0¤Cc‡Åläfÿvy£ðŠš¦¹N§)oDâµdIÙÔ?f*Zžü;SeåÓxŒ}ä(VìYƒ>ög¨«‚xN±BÞ—ˆZ;ÞáLw4¸}ÉÄ\_E™àÉ=ö-V¾´ûi†=2×ãõMݰú¹%Æù¥½¡–GË{C ¡„=‹œ`ájºÊÖª§ÚÛ#E#Øtjhém_ù¤‰Î^&ÀjAooÀ ‹ç…:…“"'“bž—ëç†Îv,Ÿ¶ëÕ“"#ý÷72µÙIÚ‹ÏL%.l¡Øpo× ÂÎJÙæHä+Æy%¯ËÛ°dUc´­’=ÚN“¼°P|Éaõé'øÏˆMÐZ>kz‹vIÏ£b“…][‘Ž©¸gÏŸÃ…<n‘j.ëªh4ùÀÛGÏI¤°$ôŸ0#G BP+«v­H\;YÕ˜ æYcš‚ ˜`L€ 0&Àî4í(èΛócL€ ܹ߯FÔtY¡@¼¹cÂýhäÍÆ™ÃìøitC'Ñ6š4XUr4QU*õyy#ŽîH‘£ðtz"b'¿/›~;Œ3âñÕ–ñªÙ$­Ä2ýE?áMÑÅò1¡Âh–å@™Ãô¤hÒw„¿&yá¹°Yâàä‘/£ä¹.wÔ$Þ¡oc¯\ÈqKÆÊæ¡–Z=áj:U@e<ÊØ`f..šn£}OÑ€^Aw”geªÅi™pž€_;[ ‘]í6®ø~”÷ätÝüýŽóÐ(‰rÏØÑVÐþ<÷Y§¢ûŽMn”W¦œ—}ÿ¦xyï=«Äço’b¤»âRhw¥RH4lÚLñZþg#á­·±aW9“ „TôlòúFFû,Ém±wÓ»þŒšƒ÷^j~ÖW$®e‰jÖó¬YíÁ¥aL€ 0&À˜`w@Cbw°œ`Là(:˜`V*yG`ý—ó,ÍßiÊáÑ.HnwÀâ^½vINQ‚›šIÎ?½S §•8³G‘_RúèC£¸'óGL÷ã@æNü\0ŽöÈÅ8ù“¶þ¯êlõè·F™«œL/DkàÕ Ó¬÷L:È9ˆßŒã$lqÜí‚4,X'ÔOŨžÂ@mùŠ1WÓUM•<Ð¥­J8 ”û¿(46@{OË2ß.6 @ÎìÆÍz=|[5ÈY ¨nÚYÑR^1 W®@xDX¿xß6 oË£þZÈ*¶8r|`¡l ÄKËÆÂãæMÛøíhõ;k÷ØSûÑêØùŒW'@èÆatd‚ý€¤™Óœc-…޽:".å úâc¬YlYÁ”ýñb6\Žlgo&EŒƒßÛy)Xü±,?xží¤fì …£`&Œjw]{è(I…ï[óޏñ¹ nÜËCœ^Ùãjº**6¼Û>(‹ÊÂñ_mG| YGåÕh@ÏŽ-«*[–Ø@m$àÙ¡þrÁs.Ãh§×Ï4ß3BÚØ‰ádûèIDçŒ~`PÄ Ûÿý:šNŠ®SÑ<.óNü¤VS1}{:y½ªTŠ\¶‰+faH¿îhß!­È‘„x ÇSÑØôÝؼvªºïR·àH‘šì©H\ë´5àØæYÚ†‹À˜`L€ 0&Àª™+–ª0‹gL ¦(Ŏקɫ|t˜´!V«MlKÚA+T—ù Òò,5/Ƭo‘(ÏFîú—Çá«®¸q£ÍÜ¥dÈ<Žó–ÉÄ·ÔÅ,z™5R0Ñìõü¼ âÿ"£=ƒ=´`fó‡ªR¦ÿ¨N+eä™L—ð«°ZIpþ¡ð·²­äLY¤ÄÀ=Ї~ÙÌÉל$¯°êh¼÷Á]X–ñ¬*œŽö’*’YæÓ¾&Å uòqÅñí=D\Å&ÄÜþù+¥øŽöê’\(†ööŒr•‘Ÿ©9 p÷;׸U$Õm/øùË r’‘vÖöap 1Y•ØÚ§rÛ~~:IÖå$$²Ñ`¨ùÔkÏùó>x*ölM—Bú;©n\+Pcü¡w{ÕR«ó Ô‡¹æ¼ì%swíi•òºµÃä€\üœí ]*×6§»Â<ï{Ι 0&À˜`L€ Üe¬XºË ÀÙ3&pg³’±$U“Wþd¤gXüOû> 'òJ4‘€ÎÏ>i¨Î€E/¬Ài2&¸ÛEÇÈœÝûrÜ@ŒBV@‰!è)lä.º݆̈|9Tpô3ÌUöGB[øµ E”ìNÄÓ ¤ÁÃÄÿ1ñÇ•`ó¯)ÿTV+Ñ<è'Bõæs}¥ÈÍÊA‘I³tÊx /ŽÆn9®ÛðÒœ‚Ë/K)ŠŠ (¢=òòÌp—.ÁH&á„sFmžr^ç~üF¡¯5€jaiNNŽfóSát¥Ç#³|vð$QÍ¢•r–_2o|OeiÔP¬[Q©9²àó Áó£$æ†äùX¾'G=lkÞ“uMú˜(¸ÛÖ«Âù©ÒÙÃ\'ÀýÎuv•JIÊ‚°ÉSe,2g•gL 2>z¯í2HçiõéÐÀJ©£¼ÂgÅÊÏ+ !:«¿8†ùl2– ÷xvì<æ¼’½R•¯¡‰I釔¬B™C ÒÖ-BBŽT^ýºw»I÷n“Æ’à7_ìG‘±gaÃŒ‘jüìíûQp[~x³±hÌlûþ è¹(:Ó|·ã;ÉOO»Î‚ÙWr‰+¥¨™™gÍl.`L€ 0&À˜¸Ì£™w 3΂ 0&p·üï–VA@|“§Ù-ŠnÂ*üszwõ\Ÿ¾øpY¢biϤœ$Œíý‚[âbf–ºj(jåbôð²T"z}VM7O7¤¾g{ÿ]Ã:‘Œã8’#$R.ãÖÎQ±„Lݵ ¿¹‚MÄ¿–Lg~VMóÀ ’Ǩ,cYg"–öt¤êƒ»Áχ6vO=¬‰Š¥³Ð:#Ë:”W–’ãÇ“ãâ5r$orìh$Ë¡ú˜¢‰SŠÌ ³É¡ý;jΕåu-™aS;ÂKðɘlȱ:EecI’õX»o»Åê¶Þ3— r7Õ‘V« uM ÄýÅ­´«ÿH¬ˆéAé-y‚Ì º’ŸUéø T÷» s]Q 9Œ ŸÐ®aqŒ¢ûÁ>ÌX'ÜsÓ;ä1;ÉñÎÒ1®¯>U$ú„Óóê=¯¤•“‰ ^@â@ç­ƒá²üÜñ¾]h_¾zì.§àµ)qÑó9 Ÿ7ß»èû8 ï¸wé,ì]j‡ÙåmxºÛNÄ%%cÐýW‘™y»§¿€5BT’…»p6]ð¦ ÄÒÖdÇýtªÆ,¢¥4—ò³ÁGL Â¸ßU™ Iñ#9»æ>•GŒgcXß¹{Ä¬Ææ•“h½Š­  Õ”›èYÑ·•Ö (ÅSž’U6Û„rˆ²A?p ¾&S¯ýåû“®*•È0èÚc©»à‘xóíñÒÊ.RI¸woΈ³XiêÑ)JóìW˜é0hÞøj×bÕ,*ÆÙk´ƒ–»/„)«•)¾ú¬úÄ,ÄW+†š÷·ªH\%ëšøËîÆ"ä^*hÃC·{[À×GQÚ)9í}(Æ¥Y÷µð…‡l*ô\ͽh¤ô^ð¡ý±ÔU¿&ÁLlíÄD³ˆ¿;¥ñ²3yCÌ©"qíÍÙ æé,)çâU5OçråXL vàë¥v¶—úîàëåîpç\™@UP®ã¾­«Rl¥e]Ê?/ÊèоC¥eiXÏÃÖžc?`L€ h¸y¶DHÏr—¸hRH^w¯–r! J¸{6Gû@VzT¡mRÚÓÄ70„V'±cL€ 8C 1|üÚH}ªÿ~ìáÓR]e%eêÄ WgªQËãüO(¿»z?2U猳ˆ«aHÏU½º¢LîÖ^ÄÞì4çÌ’¯"q­ÓÖcæYC‚‹Á˜`L€ 0&Àî06…w‡svL€ 0&À˜`L€ ܪ"è.ä]³džu±U¹NL€ 0&À˜`LÀ)¬Xr GbL€ 0&À˜`L 60ݼ$ûüMܪ¨aefž5¬A¸8L€ 0&À˜`Là.`Sxw:gɘ`L€ 0&À˜À!4f-Ÿ0ÒvS´×Ê0MwgŠSësažµ¾ ¹L€ 0&À˜`L ÒX±Ti„,€ 0&À˜`L€ 0šJÀÍb?¤šZÊÚS.æY{ÚŠKʘ`L€ 0&Àª‹›Â«.²,— 0&À˜`L€ 0&À˜`L€ 0&À˜`uŒ+–êXƒru˜`L€ 0&À˜`L€ 0&À˜`L€ 0&P]X±T]dY.`L€ 0&À˜`L€ 0&À˜`L€ 0&ÀêV,Õ±åê0&À˜`L€ 0&À˜`L€ 0&À˜`L º¸U—àš"÷ì™35¥(\ŽZH€ûO-l4.2`L àçIÙÂ|ÊæS_Ïr¿¨Ú–gžÌ³j °4&à<¾ÿ8ÏŠc2&À˜¨-xÅRmi).'`L€ 0&À˜`L€ 0&À˜`L€ 0&Àî2›K<“ä.·gϘ`L€ 0&À˜`L€ 0&À˜@½#Àã²õ®É¹ÂL ÖàKµ¶é¸àL€ 0&À˜`L€ 0&À˜`L€ 0&À˜¸³lV,ùµm{gKPŹ)šýÚ^ªÂÂ<ªŠ$Ëaõ—ßGêoÛsÍ™@UàûHU‘d9L€ 0‰ßW¹'ÔÜÏëC+s¹Ÿs`u‡€r=ו]^±T6>˘`L€ 0&À˜`L€ 0&À˜`L€ 0& `Åw&À˜`L€ 0&À˜`L€ 0&À˜`L€ 0§°bÉ)L‰ 0&À˜`L€ 0&À˜`L€ 0&À˜`L€Kܘ`L€ 0&À˜`L€ 0&À˜`L€ 0&Àœ"àæT,ŽÄ˜`L€ 0&À˜`L€ Ô ¦âBÉHEÆGp2;ÅשÜMÜÿIüiôÓð¹§ŒzòÑFlþò_¸!ÆjŠžÃŸGÌè>ðÀí2ÒÑ)S)òϜ‰Ÿþ…]_Ä£o.Çí§1âP •ñ RF ‰'àá£Çà ÇЈ.åçg_²ÃТ¬¬^¾™”Ÿÿðü´ôîàa?Mñ9¤ýð3n5jd÷üÍ› þ(ôîåp±›Zxû(8}ß§îÇ‘'‘{á’Ⱦ‰žŒ§ú­Lö•h3M1j›—û¹ý«»ýœê[‘{Œ}<ʘ`UD Á† ³ÿïäÉ3˜RU$Y`L@"Pæ}Õø ¦ôžˆ#eÀŠZ¹Súµ±aÌÆòˆñH¾l{ þ#‘øéTèÝl•(¦¼4¼ñújì=k‘p\ÂNDwÑY„)%G7àñqñÊ¡í¯÷0lþfÚWÑtØÓ;ßÂØWwÚæC!Žx”[F!톘ÒÓ~íff'ðÄÖ)˜´ô°3rP0±·Ï.¶™ãÌjÎîço‹ºÚÏ]¹ÇTœÞÝIQf?¿;Eâ\™p‘€r=·ðmí¢„êIv)ÿ¼(¸CûUš›Â«Rœ,Œ 0&À˜`L€ 0&À˜À]$`ºŽ1{ÅLŲZ}´ý¼4ª›Z¨Äé3‘QÔ@=–<$L4+•ú¿¼‰»¶ãÍi¡ÒéœmˆzñS”À:Pzñ¨RÉJ¸í¡›´ ¨ÿ„Ixsíؼc+Ö®œŠ®ÞrÔËIXžœm›Î…¢£ f¥’w8ÞÙ¾‰[¢œWâôØ–Ub+Y.£tB·å@‡vÍÝmÓU0Ätí’˜B×+/¾½ë“3ÑU‘“¹ ±kö+Gš_×ÛL#¤vz¹ŸÛ´[Ýíç.Þclq`L€ T%*šûS•EbYL€ 0&À˜`L€ 0&À˜€K<DìÊUð¸|4«‹Ú¿²Û(+cr±åÛ,ô fQ¾2¥Ã®/oÄÂÑÅýsKqïÍ)˜±ŽVÔxD«,MÇ5nó(^|ùAty´¼ó·ãÙèxIP=‚Æ`Ï¡ñp×”~þx?É#ÃfAXûTR(ã+CŒ§ ±å¥õr¼P¬ýrB<…UWm°4I‡)aÓÄÕ]k^ùC?ïÀü^ Vì‹G1YV0ʽ‚eáþèØÜœ²ƒ?VgÐê³Äòånú ÙÏ÷A€Æì^eÚÌœQ-õq?·j¸ºÛÏ…Šºr±ćL€ 0&PÅxÅReqL€ 0&À˜`L€ 0&Àîzôën¡TRÊôÌ$(ª$K¥M)öoß&G ǬÑAJñ·ÇÄéè#‡|žx&«UKn>!9z‚üthÖÔþ~D…ƒ÷X*•ä ¼:cp°Ml—Œ§R‘(›öëÿÆ Y©$‹óêŽéó”YŸ -Ïä0'kå0}Y'<:t·T*)‘ÝC0)&P>*€Á¢x•k3%‹ÚûËý\Ûvu·ŸKµté£Ä~&À˜¨r¬Xªr¤, 0&À˜`L€ 0&À˜@Í#`ºôì—3žÂשRyu‘ýág]t·¶x4L 4ìJ £u„ª;¾]ðol—WN¡QÃJ >µ¯,C‡‡ÿàk#ϯ{o9Ì€OveÙœWÜ*oñNUßRüvÒA™jP›U Bw$*÷ó:ÔÏïHáL˜`LÀ¬Xr…§aL€ 0&À˜`L€ 0&PËœøökµÄÝ»·Sý¸R ïËÜßÒnLÅi]c<¢ìÑD{Y¬œÑÆ«œ¿èlÞš8QL7¼4ÂråT…¥ßþ ÏIû-Ѻ™ínî­ƒÌ{Ý¼å ‹ëøñ›qðä•:ˆS ÁÅÿQ~ðŃžšL.Ô¼Á=ðñk#%ôóGPÏpŒIа’",yúj ;´í•‘ c!>ß•¢*ÉçØSÅ’A©Jf..šn›eÙIÐ+ˆ¢;®—›W ŠY ¯Ò ˆÝ$ äÆ_‹ÒE§J»|<ûSË_Ñå5zŠm[˜ÎaõøHÌ”ÄLXŒ¦ õ°W¦»ÔfjMkއû9µEíç5§ŸqI˜`LÀ’€òzfÊGL€ 0ú@ÀTˆ´äTä’éôNáO"¤•ùã¬>TŸëȘ`L ¾(:ž†]GΡÑ}Ax"¢‹ƒAÛúJ‡ë]WL0+•¼#°þËy–æï4õh„:Φÿ¹g®jΘ½W¯‘ÂIt%¸i2‡WµÏ#pÞ‰IÂäu‚â& ¹d¯½œ‹çCxg­ tjh±²È¢ ·n^äýˆ<Ð¥™Â; Èú/ Ð^³ºHHw»Ø€YÀ›”Ö ×uð〨XŽfž4Š¥Èäà;]©„ íÞ¥ ElßQk‹P.D‚F©ÔÿXøTG ·§T"=B j3±Rwé÷s¡ÔÝ~~—ºg˘`N`Å’5¤âsHûágÜjÔÈúŒx|ófC‡? ½»ý—;˜ 4P½ŸlMÃiJÑ Máã¯ÇCuB¾ýÑ»“f¿šƒ)mÄæ/ÿ…bXSôþʱBBͦéœÉлíƒMRRÿµ=º(²¤Ô†¬£â÷€pÔ³£½ïu)ž£¿×,•Q~!èëç(¶ãðCëb±A^©Ôõåd¥’ãø5­ÍÊ(iõâ~®²­³ý\­!{Æ¢ 8uâ8îÛ…ƒ7`Ùf2iŸ¶‚ÓGð}ê~9p¹.‰ãMüCðdä7' GRS¸ý¾J™$Ïœ’#³±‘—ýÄvA8'aL€ TžÀ™oþJû8Ð]Š¿¿J ¤wvL€ T·F-H ][÷6r¼ê¡*2bLà®(Ŏק‰«hÔ ³“[ìd¿HmðÇHV e~‚´¼1ÔÊ<eÌú‰ò7k׿<ß2&:˜SÅ\r(Á±ËÅ D·v‚Ëþ ýºX†úöB«±vŠ<¶~㺄k"”â;ÚsJr¡ÚË—¼åçuöèOªŒGº·Qý®zŒYŸa†¸B‹Zlð¬ÝʼnrT]›¹Zî»›Žû¹–ÝíçÚZJþÊßcleÖìRd|´ +¶ìD®vìÐ?˜ö§ƒdòÓª'>žŽIK•û¨ædN.ÞK݉÷‚i¼1ÞÞxc v½4 Ú|4ÉE¯ø]b5¶)œ ÿŒMs»*Ýœâ²8*ŠìÌÃØ›¼ …öÆS Ï’ Ðs2ÑGeÍ>‚5Á“ðùæñði`¾7—ü' 3ìŽÝJã¯k– ÃæofÙ1}jÀgsGâ=e;%KÊëµÔ$ìGJýá!J¨æ·âm $viŒ™öÜ3»œ6PJFmñ{eœÙø f<2G”sšßÜMïb7ýZ¹SúÙfÞùƾºS“мÄ%–¸8LçBÛ‰¸Îõ> ý £Ç½kcF7wÕ|$¯Ú‹µ©‹âeî_„J\ –ëôÑÿ«Óµs¥rnÚÑetÞ–ÿ…óvÍílÂI3e¢5J¥þÓb3mBº)aâæG*LëfV®$L4+•ú¿¼‰»¶ãÍi¡RÉs¶!êÅOQ‚®Ô„Ó0&À˜`$Prö¤íÙÏvf ˆŸ¿eÒcVeâá“L€ 0»FÀ˜•Œ%©šìó #=ÃâÚ÷i8‘W¢‰t~ö9úÚœ‹^XÓd6Np·‹Žaþˆ÷E?ˆñOÊ~Í©EE—"/¯@=QpéŒdjN8g4Y~×OÁ¶?!ŸÒ˜YóX7ïPB„·Ïoå¬S¿ž!x~”^ŒjHžå{rÔdǶƩyéc¢`e™ÄXt§ó„Q³ËMOÀŒ·”S‚ô•öQ‚.WÍÀ@õ=qp¿E{e¤§!-ý›±Jµ™šcíôp?·j·:ÜÏÅšºp±"T‹øÙZ©$ׯ‘ÁM“lºT×+/¾½ë“¶bíÊ™èªPÈ܆Ø5ÚiñÊ ZÀÚÚì·ž:RÀÛ»-úp¢Y©äŽ7¶"1)+VÎǸQÒ8g³¦¶“ ÒÞ©*•úL˜‰[ã±~Ã| –Ë‘¹K¾@bŒy&ø™´E“”kè¼Î?Aþ8‘zXÍKH0¥J,xôž¹‘»©,—¡L)Á¸¿ø²sd¥‘ÿH¬ˆéA9ZÎXÎJœI{=Ñ{·]CÚ—tÉJ&¹>óV"\³²K ¯èo±v¼.y1&+Ð,éhŒb—Å»IeÚÌBt-<à~nÛhuµŸ 5uåcK¨–†ÜöD¯éSáÛ¢ ú†xãc†!!§ìº<ðØ+XîÞÓnü±:#Sz¿ ®jÉÝô²Ÿïc£PW$[ß³•pé×ò^i:»[]u‰àñøtË$ue«¾Czô£qÍ™ÿ£oíz3AR!N¦ ß^ôõEϤ¥ê3)A[ºŽÆn:Wg¹÷ŸGÐì94îZ O~þx?É#ÃfAXRxC«ºÛy)X¸IÎkMìE6«ÚálÚG\‘¸ìŽÝ‚‰GbÕò‹\h5cÑS1f2â72>‘öö2¤oBãñõêó¶ëðGÌ߈ž"vå*ø?Üô[ûWV£c›)ò ¶\lù6 ½‡ »**®[^Z/¦siõŽ8ÞK“t˜6Mì/k^ùC?¯11èZÛ¹Úæ.õi¯O[󦨄ïû7wmTŸÙúW6¡Ï˘,¬°#EäÆ=c7о‰ÇŠ\ ÕúòëV_*êJ=9›¨ä6+Ë(/4+•¬Ò»iox(ÅþíÊ’ûpÌD±Í7槣Ϻñ¢Y½Ï`B—J)+Ñ|Èî ã:pyE·h3Z/´íü{ùy (ïŠé¡çÙB/«Y~BÁŒ98rä$.•ÜËéÕú!ü¾g æd¯ø¥8}ü0þóÛ%›Û‚ò{¨ÛïЪ,Û®@~ÖO8òËyP áÑ¢z…ÁÃX„ÜKdt×ÍúV:{™9 +8u ‡~þä‘óhžM`;ut(@{‚jùÙÇqâ¿ç! hèáŸ>ðmÓzÕn¼’ õ'¹ùù4 ÔÜ´/Ë¡Ÿ%-ü;“-y½z1dãà¿~Emèõ ú’Íâ²ì+%â_&P× ”Íò_/\“«y y¿å£ÀÛD&&ÜáÛÊGº†ì\o%y¿àÀáÿŠ×µG‹¥ûŽæ™.ì]ç_Dí½Õ@IDATò}ˆì‚û÷Qœ¿T‚[ =ð@ç^âýÔ†±ÉÓ-á«ÂÞ—…Ml1À&/šß|"ý~¥¼èƃºQ^eÝK…²8ˆßè^/¸þÁfH§X‰©ùO]!àêó•ߤ`¢ûË ÚA¸æé% ^-ÐÜÇí:èáañ Äçw€ºrÝܽz4v*ëö>MmâéÎÃæe:Œ¾U d¾HY­£CôÚMjÐnÍldYø4³œ[ïÝVP2Iƒ|2¿?G“Ÿf»ÿ5á{w×H°ôºùcÖÎx4ž8‰™T3²L6 [6ÞrQNݤY òQ/ç’y{©¬â)ïnxiÉ\<Ó³e>.5*ûG–Ú v&ûÃå6s±¬5'÷s›¶¨ÃýÜ•{Œ ŸÚÐà„<I-_O'&¾ytèŽÞöêë‚I1¤0Ï¢³0”ñ‰ÑÄ^za'þù‰|F‡¸¥f¥’Et¥¥=ˆÒs¤X>>÷ZD§¯< ¬Z¢{¶#&J%9B¯ÎLi”ýê´é §OÈôxñ9«½úhÅ߬7Â1vA %IÂ×Çc0®“æÆìBhóüN1 ‘ÝSýµ+ÀæñR ÿx,²KÖ‘¯;3-+©ƒž™„€¥/ˆ "¬nÆS©ª©Ûþo̰4ëÕÓç…b‚°J7ÇÊL®«mçb:—útƒ"=,½ÇèFMQ•J —?¿ˆþ¤XÚK»ã÷â¥#íŽUäZPd×—_»Ý´¾T¾¼z’"Ø)wú»ÏÍ«•† ±Îx _§Jñt‘ýa³·§[[<ì§8†]I8±`Bœ,$•ÿ2ª%O&þ2y½Å B!‡®ƒqd—ðRB«õlìåâ³7bñ^²t^Œ¤þ Äì„eÒ¥¹¢x ÈþéË´T5[ ÐüŒšƒ¥/µ°¯+ž&­ ±Ñت|üʉü»¡kÎaq†…´G‰[Àùª×tÛæOÀEi¬žÐ㥭ëñL§Š}ä߸©‹q„fIÚ8oaïs¹*\ÿ’ã˜2øñ³<š6 üÝþ…ˆV߀%§Yìÿ($ôF<âžÒÎT“DåLÄ_ì”MOû=¬{g¨4#ÎYVvKÇµŽ€ËÏW~Úº;þºK>¶z.ËÁú݉ßjÝR# ìÑ) ûŽD¹\¶ö§ ußpœøåšèÂ@¯×þ;§ŒïQWòÔGÌCjø\º‚Ë—o !Üh³òæúvh_ÁÉ`NUÖf¤oþÏÒD¯Ü[MÐô:Í€oî Â÷ˆí@œ 3àOËñyx.^¼Šë7oÑ4†hîÛíýä 'Ne\^$šþáY^4ñ¼ýrºÒfNeWƒ#¹Òç´Õq…™+yr?W¨W®Ÿ»Â^É™µJñÛI{ã3Ú8²¿‘åd;1¤ Sþ!ïÿHônå0¦í Ïvó­Ž,})}V#¼ƒ¤Ð1žJÁY©Ú§mZ;!· þíŠ"ʪügŽ){ãåÒÄá”Úò~ê÷û‡ÉlŠø–šö+)–$Užl\ rvŒ¹,á§¿X,¯V#ÞûÏ™W+••ˆÎ™.ýfw|MHvjÿ^9µÿÁWö›üº *Já{×€OhìoÐs¥“®¶«éÌE²ò•ѧI‰õSŽÝpÅ*™pxúÖa¯0î—ù5~)i±*XMaÕ—ÔpöÐØ;®ãÇo~ÀUZM è½—ãÙ0× seÝÞÍ ¹é_"~ûÈ¿qMšÜ‡À‡ŸÀðÈ>ðÒÎF¼R Û¾îoi若1é)ZÀY‘‰ÊêÃÁLÀu7àÙÉñª€€ÁÃÐÝ=»’É„¬TN6n¤F!ÛÆ Åå¡NöØ#cBßÒ‘,¦ÉÂ’qC‘¿áKD÷4+—Û®O[¯ Ò‡ ÃZ¾.I|f¼O»lµyc!6Ðf 9J2ÊkB0ò~‡ý´I¤ºyakg7è¦ýÏÆSg¹èÃ"0 u>¦´ÙåèIh“º½í˜QJ ýêô¤¦N‚múA£‚Qz>ÿN%Ó"šÃ]ª?ÝÉ}Ä’ÑÌœqÊ@¸`RDCŽ|"³š»¾k.íq#M º¼o< ›”s,ö1úCÀí^ûÓž£©2]'zš8—{5Ðå¯FPÓ9}ÿÒæõ>ž¨Š²ðì^‡~Œ¾>fsÂýçÙhåþ«Ç  }Qºwöæƒ]‹ãÛ‰ÓéÃÂYV9òAí$àêó•ߤö¦÷ zÒΚÞ)zÞgDæáŸD\ÑMEvü àßš@Àͳ%Bz:XT…ts×Á×Oø_…BËE³Î}Chu’“Žfû´ò§ÿÖñ-$­ÏÞã;Õfw£nÕ•çbÆý¼ºZåV˜@ñÔIîðŃe¬~ºxlííf€ÎÇz²áàà¾g¼*NrÊÒux¼L¹Ø±1?Ίâ¾Öxbä2ËGc6N‡ÐÑ¡Ø î[—…׆=†ÃooÄè‡ò0wØbi"^ØL ï"ìeç YfÑÙ ¬ž:GJZU:ÂÒ2”9ë@»%ÜÈâM{ФŽ™TÏù1fG™Ý.ÊÀܘMzˆYˆA~æï8Gi”ðß~­xѽ{;Õ²ÆQxî’|Ü­› 稜œÝ[‰{s‰\h‚…Ù¹Úv®¦3çlás²O´³Óÿ„wóǮâH‹!MM&N_ š4õÅkþ’©/5.¯ž¦›rŒ\$¼:G­ï5±qЃÌ~Y;7Z('¹ÃxyüZVŸkej Þ Å2”é-Û_.¹xR½ñ†j/j‹”¤PÝuŒta—q÷HÆL J ÐJ èxUbô†$Œ“?2§Ì>‡mo̤U=–}^ˆœÿýF³R)ŒfÍ¿7R^e¿D}†Ñòæy Ñë0øHY;^ð7Õ¶+™Ûذ™ò’”NÑ1ãñÙܱÒF‹´yãºï’ýSÉôDþžuf¥R¯IøôCÅ”ÙÖMODìä÷¥ë­X­F™ž*»2¤Õ?öéxf„ðr“‹¢·ÆF¼cçð7RII³þȳþ…D´ i‰Q¸‹¸^Û¼CñNRúvÐÁxŠÊ¬¼‰iÙ÷†w1R0ÛQô“j/7;å(Jžc“x¶,9¤Þ Ó!qŸÿˆaMÀ¤UYTí@²/¯1`ù‚m梹¦ŠÁü¡±—E†ô“(£g‘EÎ[…˜È¢ ¬ìË1áÕ$Qäþ[‘û”rO4ç'ï_šªW7x*>œ7zÏ{pâ‹ù˜$šxÈÅÉÓŤXR^°5÷_aã—´ŠQ°­=}vÌŽ%4‹+wÓ‡8ôaß)WY©EbO-!àêó•ߤÎß³Z}ŸìºÏ¦ÏC4+ž´©Š›hφßjÉ%ÁÅdL€ 0&P‹ ”bGœ´P ‹ýy4µº)wRã17U9¡Gä¼W3œ¾_¬Â’eTôÈÒ8D-ÍUÇ;¥Ôdj,9]§­Âêçº+Õ߀gcÙùQˆ•÷?J~u¢º7ÈjÂ×d5Á&O!µ1«ßXC£H4 î—tqÕ“(ÔÖÇÇ"HÜ'H ÿ´ò¾ó²ðíOégžà,D(8°³ê•J.Œ1 e±u¥øêuiï( ¯NìAQ„÷Çò0&4y•¤8Ò†wT¾ÿ(mƒbu+AÑØÖÞ¸³é–°ÜAt7®^—}Ò«mçj:‹ÌŃrú´gt§‰œÙô}ž½ý[<ßÅÊúQ!R¶(ll¥WøZ°QçCþ_ejh¼õ´×ЧÉV¸+ÿ…´‚Œšäßÿúw£¥páè¬W‹–{`f y ªa’§GS„N(]˜¢R‰ìAÏ^»›¶¯Â¸0å‚MGìè/.·¤èn=¨Æ«Þ¤¹’.Žž¦eyì˜À] `<ž¦>Ôõ£–«J%±(îm0rá<Ø”«{I%¹@,{]Q*I!^]žÁÒi´"Ot;ñÝqéÍÅx|·¸¡®¬Ÿ°PU*Iñšã™‹Å™Âñîø=ôp–/S^ñ´Á°èôX¶DQ*É!¡QxmZ |Þ™Ÿ|«”Ý{$b†šÓºÁÔ0IFöî4h,ä_¶3ߣòƒ÷0¬Ð*•„¤4 Òƒ{çZýŤš?áX¿o©¨TÝÛ>ažŽäôˆÛñwI©$xãa²?,ºâRi)ù˜@ý% |9C€L$i®)϶j-§ót´BR‡vbÖðîê¾*³GKð%·iò=Ñ™”G9Ÿ½3RT* q;<ø 9‰æýصW½ÿF.˜")•Ę2í9MÿZdN¯~Bj‚Ø[‡¸ú|åw©hù‘+×Z(•„8éK~¨C—W… 0&À˜@M#@+SÒVÆ`Iª\°Áó±LܟǪ ·ÝÑa‡†…£X7š£¸\$¿5 ‰GÁmËq’_%+1Ò׌¤Tê3ë·ÇcÅÛãåÑRZ ´j–/¨¬\®—^³ ”/çã¢Ã vW±o)­è¿`JOuW‹PxQûÍ"iÔC­OòôÈÈûŸš¤„Ìî½<]ÃRƒ+í©ø³ý,‹ÈŠÒvƒ–Å"@kË~1Ô”—†h¢±ät˜´ˆnš·=ѹ¿<æåèûÕ½‰Ê-7ýgËq0WÛÎÕt𢠫­ÊïÓÍÑû)¹_NÂë›ö“I[¥ÿ– …örL$¥“]çµ ì“Zßé•]wWJnâß¿]Áyà —„´Ö5ÁïÛ݇V^ekvI²ë‰ÜZõÅÒ-æMÜLEç°'q­K…&D/@¯}k43˜›âIñ£ë5[?©ÎPX‘ ¿¹‘X$Øk¼¼6€›`¹¥mäf¿n^Q+Ò\g?Ž=L šœS%x\¶¥ª†Çdžb.FáyùÈ? ½Ìg_»^=É{X<üïo—Ú±¸Àü21 L3ø©$r@T„ɤZxÑtíÝŠp^Í+ÙÉË^ ‘¶¿ÅfytÍ.YÕ픇YÄÝãù×ÑgÓDqÏá#dz>,%‘=½ùÅNq%“Vª…ß…káô‹àÖ-ÚBL]?¨äŠ¥ÿ‰J¥S—ŠáÊA!e¼eÖ×DØn^m0(f)–M "ÑÆ«ÙºQÎé05n¸ªT’â7ÆÀiÓT }ê_e9æ(qP]µÿÓ ì®G´›C™@U¸ø‹ ÅœܯÕXH¡vÿ_ÀO²Ö_×ÍæÞnŽí!n !¹g®Š'Îÿ¢l¦¨ƒŸ·½¼hÐV½Þþ‹B#Í4(.D¦&/{©Ì¹:ᣲ+ò„Øû7Å#qÓ6éÿºm8"ç…ó7Zácæ<ØÎ®ÖK-”KõWSKí^ V§ø 0*&àgçš6›Çu­´÷æÓ°i3 *L+¯ï³NNóTì­ÉÒÞ«„ÍYè~§Þû„4Ù•ÞT|ü[ç ¸ú|åw©khß'ì]‹Vˆß¬€ð!`L€ 0&Py¦sX=&BU*LXŒ=+Ì“áËÍ€×õ]á¯IËUK5G¾<,[‘R{´ VÏéOÃhqY²{ûÌŠ”M9™8o4Ÿ+9š¨*•ú¼¼ c¢0eÅN$®ª®’&$Ϙo¹RFAeóñk½Ÿ?‚z†#zÁj|½}Ž:þš<}5N[Í× ¾ëߦ`r’¬T¢=™–ÍQ-丶|BëÐSþ³mÒC߯^9xÜ’±V¦Ülã !¹ß¯ÆãªR)oîHÁHEÙgDù8”'o[ŸÖô2oŸàjÛ¹šN-GEû´{G,M݈È`YB&íû¾IR*L˜ƒÙº©¢ËüÔ-ïZ0Û¢ÉyU\½ðð2'›¹ëàÇM’÷h&-Ð\M)Wa´m! µÔ»5Ó &˽ԣ]:cXT·.ÊÕk´ŠCt%¸iu3´ŽËÇL Ú4R$çâÂ5zh¥ôw%Ü<_A Ñþ®\'°Xßln ´‘£ä”_³…HJnÞv3Â륖6]-ò:o?¯†ö4[Ú„Z¿Å k ½\Œ…ÇM;v´  |ç¦Þœ‰«Äq­þRj¾Y(ù— T7›U¶²H¸ÛUäFådÍŠŒGÑ´÷*ý„™x‘V‘ÒÂtKG{µ¶mïÌÏ2Õ~Ÿ¯õý "-_Ùw )/~¨sŽË˜`L n(DíŸ(Ïîÿ)nž¬ÐXŽY:àW7¿x¶C˜¿ü.”™Š_ŠÇ£‡ƒë_èüPC¯.`L€ 0ZJàкXlA亾ü¬T’Ž+þW£ ¢õJ×µ‡nM èn²…ÿNÀø\…)n!¯F÷¶¤¿â¨(šª#Ñü']ßiíƒ&ÊÖ7BÁùtÇó±áØûj H{Ï÷õ‘W>‰ìÿiÒL“ÍÅ© %¤ŒRŽÍñx¶DH¨P&ÅÝFÆ?Í{w?ÚžN”?Þ£¤®Ì¯õ³VÖ¾5ïˆÔ„°q/±7ÖÆ”ýE?á¥èõòA(Ö~GJ¥²ëáÝöAŠ/Œùeáø¯ÅèÑÅ’—!ë¨y쮣ÂÌÕ¶s5T¥Êöiß!ðí ã¡Aq·=G:Öz‚¶Ú0ŸsìÓv~͵àù bßžï8Y=S)Sx÷y4÷HHË•ÿÂþJ‚ŒÚàÎ5ø<Ò]WÊýàŸQ—hnÙv@ V‹~ù·z¶–ÃÛà#H+,¸ÌO–§í˜€1ë[u±®y¼Ì}Y$!ü— TOýêRâݱ«q¬Èü´Ï?˜ˆgF¼o›ñm/øùËÁ9ÉH;kÙ¿…3“å4˜â#´¸7#m«ì“´›êÉg÷ãóÙÐ žBQ„¼:*/IXþrú1žÃ¶¹ÃñžíeiŽcí£ úüüdy´¹_ò!AUU¾3Ñ ¬ü¼ âÿ"£ÙÐUãû[ªü²×½‡Œ3?k©.ÕßZ3&P)&úPRÜMÅS•¿ç Ì6ªU¹ìÙš.…"ôweŒ>˱ÝsT‘ô4ö6ß«’ßK²55aG^µ³²“'ÝA®>_ëÛ;í=P$?ÿóó š uè6H~×§õeÛ_fãñ;@™xø$`L€ 0&`M ŒOcÖg˜!¯tÑ žƒ£»X§®Ø±é~••Tð…8ÉW‘à€?MÐKGþ†Ô<å„òkÀ݂ₜ0Ú©³Ži_©Cæqœ·6-(’AN͸×N,D·vJŠû¿·óR°âcYÉÕk º ƒœqΉ·‘TÖ³YPz¬‘÷ží×9¸Ky™•bÇëÓDhjvÒb„”£Tòòí=D5e¸ýsëÁ³R|G{3I.C{)Ó¸]m;WÓ ãäUܧ©Rû>Z­*î†?k6‰'WØþÃkA‡ƒì§©Ã¡Ô¢®;÷†ÿ­¼Ô;‚ë‚jPJcÑ9äÝðDûVÊ@5éÅÓ0CÜÜM(¨Žnf–w˜ºž,J%ý{ò|ÌòÁ‚á]ÄåŸÆ¼ ÄEÇCrH¦e×ùÙç [7‡:±‹^Xß%Æ¢=-»»]tŒ–{*ƒõÿ„ðQZ¶†Y‘É¿L ª ¸µz1aÀ’TAr &‡ FŸÁݳ?a¦0ãÄŽ£¥Îa“§Ò5!ôc– ™ƒ;^Go?¡ÿ— ã£×ñÚ.9mð$ î#·áÞáI¼Ôë]I´k!æxáõçúˆ³2Œy?á­! Õ›~ô´AÒ,Êk`ô X´k±XýoMÄ_tC{ÊêôÃj|ñ¤3H^ø¬X,ß5_L›Ò7>À„'hU¡Ûm˜Œ%Èÿõgþ­)GH×¹ öDü$Zn-½ˆèc>@bŒ´2É­Õ Ì‰\…¹â Ab¾ˆ¸­óé^@dcÎþg?öüä±Ï=êZý©ÇaLÀiÞ¾ÂG‘ðá“…OvEWùyî´€ò"’Â:*¼o®›G}è]¡ië!!GJ¨Ÿ…º×”çÝsÊKçè¼›Ÿæ^•'Ç”bíÒ ÌŸÒÀy‰!?§ÿMÿiµyµ³rTX¿3\}¾Ö·w€Òãˆü‚<‰Lû¶«+“‚žú°n¡Ø^¹›faæã¿ü¾ôÚSté,2v}‹FaF8m¤ìÒ;Ðé œK `,º€S'Žãà¾]8xc–-p°i{qR~8ISË•YkÁJôïí‡öž±>b@ÊG±ùËɦbš¢çðç3Zz×wœ¡«éK¾O\)KQV V/ßŒÌ ’iî&þÀóÓbлƒù¿¬\ù\õpºŸkŠQ”•†-›>Á¾§€{›¡‰g è¢ýZz ÿ£}àëÄ ¬".÷h2ÏݲùÐEÓ°M7ôí¢ÌöWRÉ¿tííØ²I»™¯¡c1îÏd=É÷B+i¨LYN§ïÀÖ„$‹~>6z<Â;5·Î†ï #™#3’⥡Ûœ?/gLÖ.ã>Ñ<·;¼¼‹/%øçòwÕÒè½ãÄÁý¸®*i„S·èŸ~jÞ3GJPŠÜ¬m,ıŸ/£mçðrWÞ[Jphë똫(Ãæà‰BgÑ2víZé×›ŸJ)–ê"¥¬Ä™Òà°·]CÚ’¯tÉ1״ϼ•o¥tD9œ> -úß=òöSÐÞ·^ÀÞ­ÝÐÇ¿ûS…¤ä¢¦X,«kàÓ.‹@T,-·ÌIÂØÞß! ¸%.ÒMU®Z¹=¼´[‘Æ¿LàNhŒ!‹ã‘5É9Bžìß%,E–Ü i“¿j½9<÷À(¬ˆÙG³dSÄtÄyLI¢ù Ä;KÇh^,ã™·–cïÀY¢¼ý«fáñUšè²WØprt'a¶†tm¸u‚Íogaì«Ib Cæasyü#š‡  å°uæµ šs>átmž kS𙑏à$. µ²·†ËòÕé=}I±¤¨™Ýµ ’bI6x© ì;{-"¿äËBÐazцEêYò¬á‚b‰Lÿ¹RA”Ýzhópà§qÕY¾r¨ÁìaõŠ€þýi IŠøÞOÏó°·„ê‡b}Æ2²#.Ýsœ½Þ^S—SðÚºÒ=EG÷å™/ÌD[ø|ʯüç~Y÷W¬ï¼ ˆ:LvØsHBæ6LL÷@«2Fmx”>ubΰrµ,œ®fpõùZ[ÞìRváÀüÜoj!R˜\²éŸ0adZ%{ÓBzÜ»š÷A)UîªùH^µkS!¤BcB®–Å€ÏæŽÄ{ÊP¥ðÔÏ_£~¾w™R¢„òï%P‚OÆD`CŽU¦4amì#Ir kir‹²B¥XûÁ’¼““­ÒЇ:š³K#g"–ö5F6ôÁÝàG6îö§Ö$ÅÒÙT¥ŒrÂÍoÖ¿ü&-¥kоu&LA×°P”KG¶r]ôšŠYÂ$>ó54êôY5QK5ÐÄäg{ÿÒu¢1Òã4kþJ·vŽÅä»3ib Mì]CÒtþ¢%T'¨œæ€0kùl1 9æù:Õ! W'R­ÁþÒ8ŽP—¨µIB~l]ÅÛ@áÒ³˜y)23Ì–³ôïh[$«ÿÝ*Õ„ÐïÉÓ4Çf¯nÂ*üszwsùzÏ\‚ÈÝÒ˜Urìh¤âþâ ´½…LÔ$ïY~§ºÚv®¦sµO—ü‡öÜŠŽë«ô•³ÔWÔVO— µU&ºx-ˆÕ£?•2…W95iÖBªÖå\IÕ(•¼»á¥ Û±tx€ýj“†w龈 –Oç6+•(mÜö×ÅöÅ[?p6/)'2ÐKŒ¢TÒ!šnhSú9˜Ñb¿Êª‡€{f}þ V¼= ƒø Ã9a*VìHA܈`u#?ëÌ{Ä¬Ææ•“hf…­ < ›öÅ£¯µ¢Ö§7VïÛŠèÁ¶‰ˆè•[±iz_›™ö³ðõŽUˆAÆ#2r^|{¾þ<kߪ´b’RKrH¢ÖéNÁ×´t¸¿rMÓIU©Dþ€AX|7llVòhÖP+оÜý1+åKÌžÐÍ2\> èçg–åRý×C›¡G#«rÑIO@KOØžÕ¦f?¨'„AeºoY>±Ïh숗s½)ß!4sÎî5<o¾=^’¯Q*éÂ&asFœf˜Ì[¹·XY>(óžã u 6r³¼ïÁ­ ¦Ð½þi樚2‚Þgl®Š,—•Y ûj/מ¯@(ã:©Ø;@Cq_©…}4ûH!OÍÃç[ç «ÙÚ¯¦3¢Å5åÊ;P9÷$97~Ð`¯7^#~¶V*Éu·û|ι5ª:$L4+•ú¿¼‰»¶ãÍi¡R^9Ûõâ§4,o5ý†]KWV\“Yt4Á¬TòÇ;Û·#qëBô‘¯ëÄé#°-ËÑ÷FYåás•'àB?§L}8ѬT¢6}3a+“â±bå|Œ%õÍfæ`œ*¦gks4aB¢Å:¥#Rš·()rAbT¥R ^\¹‰;â1{”ò-LôÖ!ßæú0çeÏçJY2èýWQ*é#§b}ÒvlZ;S5‘%L ^´ç‚½ì8ìhTîÐ`[h_í)ßùe–­“Í{ Üšªï5¹¤dÕ*•ºŽš‰DÍd;kÑA£—býÃÔ`aLUQ*u°_}8ÒF± ÷Ž4–Oã?ʨ‘A‹U¡dñåKš,l¹bλ­YÉiÈÉË©*•üéš¶;KÛôR¾òhüõ@ºY©ä*¦™b±ï’ZÑSÑ6¹<ÆLÆ•¯ˆÊnA ™ôë¨LiŽ9åCÔÑy)¼½åD(1ÔÆ¬vÆ#Jÿ2ÐØ´¢T¾S?¥ ¾… ˜ÆÅ¶sµÍ]íÓ½ÉZ씾¢(•úÄP¿Ü2 ¾ö&·TâZPò«¿ 6l˜ý'OžÁäÉ‹Äúúµ¥U:µØ=s¦rõ0•¢àR.^¼Šë7oÑ¥ÜÍ}Û =©éݬ/"{œhæK~öqäB×ôn4l‰À@ᬑ·—ÌDšà¿\@]Cènèß¹#|lÞ:ì¥,;¬Ò<ÊÏg™òwÎdzâfŠÀ‹Û¿ÁÈ@{o0t]-€©‰;LW¯ÁýþVðQ—+;†h,*DÁ5ÜÝL¸frG+ºË»–l¥Ã¢®#¤eÛþ“HÑ4^³BÊ6¶½’‚ ¸rÃD§ÜàÞÌ“–˜{:w?°#ÌT\ˆü+T'ÒCÑ_’åEõ³¨šúÛ)Dƒø>RA`½n0›g¯U¸{9uÏ*«â'>š‚I«Ó~öÐ}ÈLaæ^*&+·àvo øÚÙT¶,yÕ~ÎDf?óŠè>Ew>7w4»Ï ªé«Ü`Å÷+fuâÐÙç+¿ˆÍMßùù05¤ü[ôÐÌ ^e¼ Õ”w€:ÑUëh%ʽ¯RŸ;öå?ð[‹.èâŒ&™"*ç}ØhÔÎx6Ãsw/FÂÓCåó´’wßRÚÜ|Þ‘¯ }5žž¼M<ÝõåX=º£õк)²uÚ”<áDk6 w5*ÜŽÇ5™…X>TÞÿ˜6Bß·L]Ú$}JØ4ÉRB9\퇃œ PýÜtv7ÂÈĺè‚i¦º0¨h=^c¢=sݬ,Õ”YÞlóÖdÒ*Yô2“Ð5šöæÙdºoîúØÂ:α^ÆdyEÕ eIˆX®fAήâeö—yr°d ^?Š”¿¯ô5½ø¦už#bÈ0|z$Ö–—96û\ Pn?wAfe’iÌ"ïüE\»q7Kȼ£Î­ð£1J箉Û4¾ùó/¹pÓÝ “Áï€Ыfú—L4g™MCþbº«hâë?K…’6µ°çlÁ¥+¸|ùÒøŠÁ@fÞôí,¶6ÑÆWü%döâÅ˸f¸Næo¡©O{Ѹ­Sc¾Šg+;Æìl>UOÓ¾ÕM¯_šû#¨ƒã6P²­hÛU6’Þé_aK‹K—¨¯cý×éWÿ€@øz•ݧ]¹”ë¹…¯f¶Ó­¾ˆ—òÏ‹Â;´ïP¥™XMU­RÙµS˜[cø´ò§ÿÖÅ·?ðk dÏ70„´ZW~Z7Ï–ééì‹‚V6û™@õ0åç› ×Å}†”‹²vc®¬TÂÑ;Pøº´×ßéºò“ÍCø”ÿPRä»{5§éˆV`“³'[/ű=?¢I×^°œ%»+ãT[À}&ô«°RIîáÓR]Ù$;.‡t¶¬¿nžT'‹pGu¢…NN׿¬ù`.pÓAï§ÌhsI‚ÃD4TAxõÉw˜qEN¸yÀWÜωDÕÈʉÜ9Jµ¨Šç+¿ˆMDßÿŸ½ó¬¢Èÿø7¤À PB ˜¡„NȉÒT@AÁFQ¨àé)þÕ³œXO=8ˉœ*'à!ˆÀÑ{‰@€P!„tøÏ¾-ow_É{//ð’|GÃîNùÍo>3;»o~;3 ›º¿Tß*µa× á¢Íu¼uäoºóaxÿtŽ 4ÔñÏ9kgiË0™5ÍhTÒ>Fïüú*‹°n¾lT’~+L,2¶½ûv?½>k]é›y0.E]^ÉÛtB¼u)<¸R1*}_zÜfT’FvÅäçÒ0îÕµbÙ¦¯°úÄ=h^AŠGWy¼hç{¿ÿJÑÇ‚iÓ•¤PGF%§mËX<1¾íž ÈÁŽmò ˨G F%I@ÇûA_aXúIœ/óž0Òö[ÖǺäÚ«,!‹Gîו$EÄêÀËñÍÐÈÆb3÷ÇEƒÄï©&â÷Z“æf \_‡‹|ÄŸÑÙžMFÿ ^UtŒ¹‚Ù{œÜá˜vùR<­;U¢·éÔônCåß¶ž¶•ŠÞ nëW…#Ò°T…+ª“À•"prÛ¿ÄzëÒ¾J±ÞmWÔ·f¼?­_“(®Ós÷!A÷CQõ¿"ÇÒø×Ôç­/Ý–øÎèÒVÖ0Sì•®) ~ôÝ” ®*é…Aˇ'$@$à‚€›{.$0ˆ®ªð|­ :^¹cN$P9JÓñª2ëbVøîÒ—_¶wêü=ÿÄcæXó3w±˜y¤|˜Qx?¬´zÃ2¬/ìÆþ‚Zàº>ÒþâKó% °÷…þè(­Úám:‘Ô׺\÷“*9 ~×Ãøù¨äÛ¼kªøW–İüWKöcàý¶YR8Ÿ(ÍÀ¿>Ú/+? ©v;××iÛ2'q°ü¸9Šõ:ï¶dÈ!¹çÄl޾ƒ,øIÚóh÷ø%o¤¶ޝu9²SÝË%%Öe÷l÷·¤Yó.¿w€¼éÊÕ„aɶ ™ÍéE$@$PCаTC*šÅ$ŠP×e”Ö»• LzgÁˆ×ÞÅ£ƒõžWü\ý¶2WìoöS†1{Kϱ˜þÆ$‡_±xE$@•G ´8K~¼Xü`§#ªC *<_«‚ŽU§Æ©) ØØüÁ4ë¬"iŸ‡wžär¹ ¢b]úsg´½X5v´´|m´êØ›h “´N´ì¼M§ËZ:­°.bI ³Ç”ç7#¦®4|bü=“ŒNÂ׺L˜XJŸÎÏ ž×6lïtgD–fbÑì9Xµí †ú1I¸yä]b%×³Ö mËTäÓ;×`õÚ\X6Û"ĺµ”{bœƒü¤™b 1,‘î Ä”zé[]’nÉ-–ZÛ¹š1$@$@5ž K5¾  ”O vðsø!m<ŽÎë’æ"¿X ŒŠµh#c®A‡ÎɈt²GPù’}Cl48mó1þÈqdŠý Îçä£XèW‰V:"Ùºœ•ñG r¦ p‹@ò=bÞÍ…bi±O›iPÊ-ŒDWƒ@Ux¾V¯FÝ1OðÒƒ‹ðø'ò*½ž{Ý"íß©Ã[ ÆŒ­puÔÖ6@žzŸ6ˆŸÖ5ΉF du‘[(d‹™½Þ¦“ÄøV—<ì[+—ñiháhÖqi‰d³º‚ó•3ü–€SwÞ>}FLÏÔÚ¨¬³XznátšôÞ¿¿«¡ÎÚ–©Xl)¹Ü•sðÇ•ÖSñO,†=÷L¼³›m;5(¢ºFéÙâoþ2œy0 ô÷×Y¬ø\6*©IÔ£¯u‰é(•UšÉµ˶œAÇëË Ù°˜F%>$@$@–4©á<^}Êr‹b×"á,x`î—£î –”ˆ·i‚Û‡¿n5.-|{)&^?Ö~¦‘£RˆeëzO|½Õ0±ŒbæÎex÷‰—±NÌHÂî™ÂpÔYÌ‚2îMÔíÁÑë“ñÖ¥&·¿7}V¤a˜ØÃl÷·‹­3™Tq½Ð% 2/?'ö$~u­Èj¦º½† ‡åÜn,]YÎ=à‘rŒL$@$PÔªN…aYH€H€H€H€H€H€H€*H g þô‚²·jüXÜ“ÖÐ êhÀo‡Õ½Šœ‰éŒvÚZsÞ¦s&[ò÷R¦ºnÚîLœ.umXKì™ìž•š «Táqíµ8,ƒ&atJ¤!¿Ð„Á˜2LšÏ$\Æn«{å„q'6e þ²àM-¿íßmË&Å…¶Åô•³1¬½â½{-~"•Ç=ƒ§Ç‰=ÈW¬žxztS—Ä;§cæKÃ5éë.PŒJñÄŒg¬{‰IZ ž ÔtöŸÕt",? Ô`«gþź¼›„àWGyµ¼[x\²uPݺLÜ‘óiž¿ œÄ©ÊloÓ9Ì@ñôNf8RzŠ¥ð6H36~ÃÙÂ$DK—órqFÉ£ ¸Ä• ó¡¶ %Æ)ËÎéF˜zaêõä*mRõñôÙ7 £Qún‘2cŽEr¨IJd[Lùü}p'2ŽæŠ}‚ƒÑ¤y$6ÂÜÛÔ¥(cÑ ÔØöLRʽtG—ä[§`uÿ{°kç!äŠ=‹ƒ#› CJ÷ÌÁÛJ‰-ê•›# Ô œ±T3ꙥ$      r \>±¯ÿ3SŽ×~îhQn‡" }”’¾ÆÁl œÅæo•|¢º"VÍÆÛt•P<½”ÕâEÀ~ì9g—CîþÊ^:@÷¶ºýxìbÒÃ/…A{—¾a/ Í3ˆ„’!õÔzlˆ:þ[o™ÊÇEý¥ H“–‘z}oôNKF¥p\>³ó3äH±£nFÂÒ% ¢1: z ]RS­³ð¶¿XÑ67§%˜4ç% @M%@ÃRM­y–›H€H€H€H€H€H fP7.J½á³¿[÷˜‘¢ô5 Ë»5à w‰?’ÛýVŸ0Žªî_†yÒþ3ÂuúýMh¢íáäm:Y–㽓Ù$uˆ¶”Ùüo6˜Da¹Ø£GviÚ³‰)œ—W€³v”ˆ»ÇÅÊjmøVž0k˜‹ K•=…âÛ#Î<»È½¼ëÒ,f+I.> ñêÒŠ²Ë×|ü¾vÞy‡mI<—‰\z©‹dh~G54÷¼Œ«ºÊ‘a$@$@Õœ KÕ¼‚Y<      šG P,Ó–““‹ü¼,?®”ÿøœÎ˳úçäÙC)ÍÀ÷ê 2¤Ù Ê ¼}LͧôÄz¼ùÇWñÊßÄúeš¿tÒáŽû!ïX“‹Wz‡Ärr’»œ³ÏßõWë9„±7+(ÅÇÛt>×%¢#%3È]ø<Þü1CÑØùÅ4¼­Øšb'Ž@b—*ÓóÄ#ž¶óNÃïQä‹69zvžQÛlÖôæfÈÁ}'ª®ÚP„ÌýÈ)Õí¡Tx s¥Jn–έ© ¶zžÅÎMéÈ)Tu|ó±ù‹§ðGõ>ìó nni´pU†.göïÄ^±_©nWþÑÕxlÐóÚ¬¼§Ÿ¾¡šX)$@$@5–@…'ÓÖXr,8 ø%||uÏ`ÌÊ0)—½÷^»@ñŒÅ‡k棣nß Ò#»ð“š$~Ú¸1;¡èô.,\"/•9|›1R‰“‹tͨdÁb°úÑë+êMºJÑ%(SÏÁˆörr…þªQÉÒg¾þú1Ý2~ ž\!Þ´óäÑÓ1ó¥áš†ÛWÚŒJƽŒÿü}¤]ÛwÙ¶‚êh{7eîÞf0*uõ$æ­Ÿd3ÚjGÙ–OÌÍØoM§šrzMz|>M‚lÆ-UaßëŠæ=Uƒ°¸G7¬µ•¢Òð§ù‹ñhšãûTÕ‰G  šG `Ö¬§/íÛw?üеôÍ[´¨ÒŽ9R-Êá«J _‘¤¨¹ØÔܺgÉIÀWØøŠ$å €L *ö«¥b–ÏÞ_N!ÌŒ\1Ù'¾C[44®ðå°z½MçP˜âé•ÌËe8™¾™%a¨sñ<Ð É-¸Ê†a$PÙíü²h“»~ÉD¥JsK•ر‘ÞÍÊ)Ì;‹ÇOãBÁEç— ÄÒ1­š‹6èšBa>Nfe!;û<._KÑYŸ˜„&‘å¤s!Õ[]òsNáôél\Ƚˆ‹%%¨Ó0ÉIMìfZ¹ÈšA^¨ìvî…JLB$à%õ~Žn㥄ÊI–uR^¹eBKŸf`ÿ9‘OÅS @M'Ñ»{>ëÁÛt®x{%3 M’:ŠÙItÕ…@€—mÒQùC# !É Cch8š4—þIõÎÏ[]Â##AüýŒ)c8¯H€H€j*.…WSkžå&            аä!0F'           šJÀn)/Wwñ¼oP?±"a q2ð¯ã&qŠo›€V¦¸e°n«0$ˆû¾¤´:¤Ä£QH€‘Mûwèd[#—ÇQ—¿¤4º´@çÝU¬?ÿcããBKÁ¥NÓæèæ"’ÿåŸ8„髎h ÝÓR–ª†îšÒOбgWN–B<æ=r%"E§ŽU»­zT`W‘Í÷½“¸%âWH·Ž±°T‰û»+܃Oó”„â:aX²8)[Uôv·¯òÇgaUäMI€HàJ0þê¹92  *B ËlǧŪº!x³ÍÍèdý]oSã˜axø¶TÜžià5 @A¾œ¿³i7™ÌD»,NåbÅoÂ{ýE,˜ÚµZ 08kù™0m™m@ÑY<«HÆ÷£MÑ.!ï¢ÞK¼«¹+-Ó޵¤Åð¬ÌM_ñžÞµ#9jkò½‡_Žáî¨LH’´Ým›mâ[á¹;:"Æj×s÷y)†\ð³ûÜÝ…úmâãñäÐÎÂhdl fnw[bÐJa*Ç,ÅÒ¯~Äô 5]4>ë’ \˜uп‹fÙr¢ÓøòÙkÑH§;žÞ»Cô/Y:!¯½¬¯²6 3]ÑL§õ;ÔÁ×±±&_?½ 4kW—Q‹‚Ó˜¾hŽz…]jûU¹­zUh‡‰ß÷Ž¢JÌć9UäþŽÐ[…¡¾º4{¹fÜï«üïYè¨mÑH€H@"`|c#  ЈP§'Yý¤¯+/k¡Æ0ÍÛtR€¿Y…åÙ—Lþ¼$šM èÄ~Œ}{½Q h^?â£s6ÀËï®ò¥ÙX›~Á¿܈ ÷à´;¶Ó€¢ËB`ö’5;?¤É^g]CIñÉ¿$­¦T£\‘¡´â+ùXºf'f.\ƒï¿`utaLï(FÕö+Í>€‡íŒJâþ‹0~ÚnÐv³mîË8€{¿9 µ9÷ž—2OHôD÷}˜ðÞ÷Xši4rÂÄÍÀTûÀšU:£R^yäZÄèªÁ¨ƒñ]Ä,[¦˜…Õ™ŽîøRlب7*I±MòdUê_#Ÿ*¥zÍS6P×°k^é}WbSŸâ;Á”T™<é«üíYX™\(›H€ª2ö×U¹ö¨; ø ˆ&xod{Ô/½ˆ_ö¤ã5ÃÀMl<…þ›ú‹¶Ôƒ®.²lÌøÄüÅr Æê…ábæº|d©0šœ>ƒûãl(B¯®Ö^åž¹e+^Úª2‡aÐÍíÐÈÃqµúñIxo`3 ì .áØÑãX´þ4±B³£¿íÁ‹+ëczuæRîœ87Ьƒ Ûµ«ýl¯ð¸,˜ÔF®'aÀ Ð}¢]–#¾’ß©}%ß<,·'—\s™Þ«Ú÷ïD¶¦ãœNÅ´]ñÌ€òr‰bö×ñÌ“X¶áêê?!×%§ƒnHÅ}­ÂpîÌi,Z¾KôKǯ-ÑNW rê@<>âZô¬[ ¥Æ.‚ëÔóóåõº— ïÜyìÜ}³Ó*‹1ýÓ5H˜Ú­Ír#>ëUþÁm˜°*W ¹û¶>è僵Ÿm;‰ÛͳsòŽãß§´¬ªé‰¾ŽŒí+¬n½jZæ*T¬Æxóë‘§³{‹å$ÏØI+tFÏfIølH3”éë0Mìú“*TöJTU}O0ò’2$³JÄ^AÑÎû*ÿV°èLN$@Õˆ KÕ¨2Y ¸j‚C]W ˆÕELÓÆèÐ`F.9yÕÔaÆ$àÏoÚŽÃðÊÄÑ+Ê8‘6LJÄ"F—â¸0‚Õ]WÏSS9)d®èŸˆ=4¥pÑ?¶ýciî)ü¸)G¤{;8]Ú'‰=™lõ¡OS"îöÄ–â9a'¿‡f‰þÆþ9ñ9¼ÿ0Ö< Ñå¢X;J$ªK ?¬±}/•cРT;£RyåûuÓF<¼ì˜}´]G€e[0èºT<~mSÝ@1þ3o­mÏ´†½\¤¥ù&}-ÒZ] Þ|b¨¶'Aþá½xxžÜw[¢6­Å;†ìaöŠC˜9õz´²¨ˆü¾Ðå§Hž½h½õ¬~‡îøZ úºåL³:ä4áyo*¶ÎX­š âÇþ´î ÍÄ)Æâ¹b©AußT^gcæ?~ÆWú&šqbŠof0¬_ä®Ù‡ª|kZÁ`Õ¯xá¸.ÚøŠíy}IEð\Ç ºzºûŽÖ½ò3÷Ù/ùv*“>Í *êZÞ;O*££ôÖ¢IÿäÂÌÏÖ:f¶q¿à‰Æ›£ÒÐÉ" VŠ3ss¯í¨©+÷XZ*FØ4WŒ×ÿ½ ïÝÓÙ°›ì䤸Lÿ¬«#&Ú„£„"ß2iYYGF'GñýÉÏ±î ’:ãÃgñðFÛÌ¥­›ã´0,9ÚçHšE vGÂÌ·`ŸZ¼úñxm ›}‚šF”úû,ü|¸#ãÔÞü¼-[D’,ær½ÕgκTE])JôÍÒa)Dÿ(úg­ì?숇¿>`ˆýÕÖ ôëw-žK•g‚nþïZ¼¦ë÷ǾYÇWNZš•Žûç)µZ? ‹jgô-ÍÎÄo2õ™"ØÇìÃeûñÆ#}ÐM×wqtáƒþÈÓ~ÜçeЕ«Ti“š—ÃçžêU¬K]ýNËã%JìÍó¨4;C¼ÿh½ï&u6T/aÍ7?k÷Æãã†`HSéද\)k¥~ÇäVíC›.ðîÀÝ{š)ŽƒKoÞ%Ìåö¬Ýû¾ ¶b9~žØÂíëÌN÷@ܦ–|Ð'Ü}CGœÿy'–ž%GðÎòf˜?µ¶ÿs^ËÐçkáÍIÐÉ´· ¾<' êLÀö˯:—’e# ¨\Ò‘Îe׿t‹ã«.&OI †(8†Û£.µ³ÍÆq‡Æž´3*Õ?®õnɪõoÚ?ư¶}¸iShÃ~!†ýÔÌ{˜|úÙ¨¤æœ·VP/¢Žçj>¶“1;¨Â.¤)FwÐÍ*7³ÍË Ñ l(ï%,ÿÚÞ¨d·¯•^A`á ³QI\€—fý‡u»ÞÕWÅu4ïc£jèôh*£!}A&žzÏlT „40¯¹sY˜òÁ±Yo75Ét·íh2+ñ$º±qŽÄ¹c¸÷ïñå®,mo$²/>‡½¶ægMªß—Ð&+A!UѨd+£³Ö©Ih®†ÑãzÛyDH6/Z‰¯4^uñÞØNÚᶘœúU9Ý[u3§³Å2xV+’íæ¬~F%¹Üît¯†þñœ<7•Tò+VlÁžyÍÔ>ñª·õ8ûGíî•ÝëkqîëßRžI f¦MþÈdT2<rñôkq\KYΉú#Oúqøº åÑe°·åw)´ªº1¬åÅó((ºÆëtyG±>K¿<¡à–—‰ÏTƒkD \g5*Ûý×±QIA½oëv¼±)ÇmðÞ½Kñ¦r{Òî}]caÝx–§»Úx{O˜äµÌlTR4.>†»^ûÞdTRKs³ÖŸR/x$ G€C}5®ÊY` ¨bÆ’øî ÒrZkÿ'öTÙ¨Y¶Q÷=©„¼)’ªñ#¶Ž^ßú ¯þ0Öû;9/Í>€t³¤¯ïÑCZ†#7óLþtŸ¶ÔÓÑ][°´[ *ƒ‘¦Y††07/¥µCû ™˜¾Ëv¿ïÛ{¹¤%Cä=Žš}¿/ý¢Žø†àÙq}*˧ùÂ%vKm‰%¯TçTª¡¼ç±Í0‚ÙóŸíe]š¨´¸§OÃ/ù7¹Ã0þ†Öh”{Dì+§ÿ"9ÿÚyS;‹¥¥¼®/_é(fÆuÆ‚q‘˜ü‰m¥ú×tÄ?†Äˆ%óÑÀh›SQꎗ°jÑVÝÌ019Iì{õ÷Qí³,Ÿ¿¯ý¦Öqžþæü0¦­Ëï \·]Ö•xÚ¨sGŒ_³ Ö…bÌ^$fºý…W†÷@/±eùîN>„YÿÚ‰µúÈ›ãš0G$1³nÝd‹Ù%º¯ìÄ6G;K,éEúõ¹Økqˆ€ýPÇS6¬Ù3ørÁJœËSÛŒèÃîë#ö¢²çqy·ÀÃuOâC¥=ýåm8aÇ>°ó2;)w÷ˆÂ7ž¬†³•$b˜ôÑR´Ñ}ð“Ÿ_†Ûï¼C´Ù[NÈŠY‡Ï¦ÖÇÊåû±V­!oó‰B´k&ú’ B–¨É3Ò±» •6»eYø÷.Õš’¤ûGôßm·ÍL>÷ é‹1"q|×FÜ»H‘ϲýcM£fàèèëþ¨ü~Ü÷epT.wý|]~wóõïxû¶®Å#‡ôýuò-ñø@<§œ¾(Erý< A1coö’,%¶Ø7v‹qßØÃ»ÓÞ»úõje}w(ÍÚW´{A$­ßŸý¾«˜›ƒ¹3§J?¹B< íÞµÜ÷ ïß%œÕ[ùíÞ×e°×Äûga—kZ K½D”ØÔ×÷„Ħ%Š÷îçÇl"¨ú÷ëØó§ðéoj_'fV^2Õ¨<’ @ Pc Ke—L_–Ôˆêe!}E€íÇW$)§j¸,myopeÂC¾LayþZ†!®v—Œ›b•tš/OH F¸xRì;¤/¹ø-Zvé²XGþ"\äè<}Kºa0´Wï^f½¿"bZãå§1öG›‘cÞöÓ¸¡q!ÊtÏ }¾Ò½­w¶{]Ч‘Î1iäM¸%N¹ŒÅÉC?à3uæð PÊTÑ’ÕL¡ Dtý: ‘ÊzÉ\¹1çwù²àãä=Îy\å-¾(öš*h.ÇMq Bãæqæ*Cžæ| 3ÞŸ|’¤²Ä¡E하¸Úf`[wè ÊRÂáu}ù@ÇËR=HÜÄx}Dý04šUÊÜH\GÔ®m½Rٚ˨¥/>‰y¿éW,øóm)d—‰ù}îHÃÖ×Wb©"Çcçù6H‰òW=Õ£{mG­UÕkßÃp׃ýqéãåøø´Ib^6¦}º½ºwÃÿõ-^¾?ÍåùtÞR|jJª^N¹% AVFömqáªX¨FTŽ‘B0ÿæf&ßʹtŸ§½îÇéÇ5s³•¤ò•ál^¡i0¹ë î\®5µ¾]®.]b€ß2”ôÙøéPîmY"öR–é‹hŒ¾b½Î¯6Ú²p^&[WgŽy¸JáË0{>È+0r¤ÜΖˆÅÖ.©?ýíÓDƵÁ'#ÛˆAøËè–µ Tƒxz¨} êáæîX²Iíð ðŸmgÑA£$—½ïf\mݹ%Kí_ê?2lýGd\ÜÓ®žµ 5n×÷¯9†•Aö ÎážkÔ~É*RûGÓÁ§ý‘{ý8¼,ƒ¦¼'æ{Äés¯åwC+Å÷‹™—¤ø¾s¶~kAJŠQ$Ún¨“þÛÝw™m[¢³0,mSèìÛº‡ú7A‹@é¹pKµg†$[¬m;}ûAÝ»Z ž¹³ IÏÌz90Ÿ~™!KËËÂáü˰.ɲ¿/Õ÷4¯ß%„T{Vîµ{ïÊ Ëñ¿öå+ïYh¯»ô1@¼†Ú²(ôå;ŠÓík}Ar6¼»¿j9bâ]0¼¥”w!.¿o{÷=z( Ù—š ¡ü® %á ÔêÛeµ/j‘í}¶Ú—•ô=¶ß3¥Äª@à2JMïÇ%âš|?؇9*QJ»düap¢ø*^Äw~$PÓÔ©ièX² ºŒbq¸÷Bv ‡Né-"!жrOÊ ¥DaXJW¸=$¾Ê/k"fI™îYa¬Ñç[,îm½³ÝëÂ,d »®_oܬä[ †%ÓŠÍrõR’ч¸XOê_Ìù]Òú£,éJtÑ;[\å lˆT±úà6mš<¼ùår¼‘=Zá†nñ0O1ë4ò¶nˆ2õý Yû–h¶z›V¯9GÏ"«¬¹÷õåKõÜDÓ¿_õ¤ê®ò3—QM_vîNª‘ıYëxk¶¥· wJ–îPõ °õäE´I³«KOÚŽ.K;]õa;À°1CÐfã&¼ú³˜mg¶nÓfL·Ü[7Ê3#Stå2SîNCŸ¨@EoS[tœH ÞתÄr3µÕÑßþÊ^w}ß`Œï[ð3âÇß„õ-gå\®”¿Avq"Å̯bVj7únÇiÜZï"æ—ÈÚ¦´‹Gà ­¶z:/“œ¦¼ÝçYž$oÂíù < )ÂÈQw1_—ôíËœ&¯ÝÕA¢Ÿ(i.ŸHj_ ‰‹KI€eÓ.í^ùiÓ!Œí^_˜ÚKñóZ•k néÚÈÚž‹²rt³@Îá]ødÙy1Åý’Xr5_›¹!Éþ53[y^™êU„©:ø²?r¯Cm/Ë •É]ghÇ"‘íYf”P‘ò%]½+_Ü/f^Ri£Å&7Úcâe¢^0.)mZ 7§qûyØ·´ Ķê€R6§ça\b8ŠNfh}‹¥Õ5¸Æú^PŠý†wµ2¼¾t Ž ûkIP-œÙwXRGqØ“U„kšIá˜îKí=­"ï~öåv¯Ý7ó² j¹MåsE¢ {šë솥÷ÏPó²"÷„YþðÛz¢0òÉm´–0JÚ\3a¿Y´Ô0û¯x—×·5[*ž‘ @õ'`|k¬ÆåµÿÚ¡–Eó9¶Ÿ#¥À*B@?)©,Ý êý` A÷êº@$4o‚^bð!¡žxÌHiªHy©& T6²Ð`ãRxù%¸(îùíòr/Åéóú»)uÄà¡zOZS‹ÁCýb0ƒ©ÖûVïY›¿”Î C¹VýÔ£Orqbí4½ŸK¹F»¬‹9,Öú¯$W/Ûê)dØù)iÎe«C§Š‡.®9«lk´ ô¹µ¾›»K3Y½Kòðåÿvˆ¿Ý¸÷æÞ¸½EjŸ™ÿ6èl]JOVEp-1s«"õåõ,CUè8©…4”GxZy sóµAd)nðÚÆ² ¿@£µPMk–éIÛ‘òRYŽêï›c-$u뉹)ðóÊ-x{§Ñ¼”¾cVwmŠ4aô0ëa‰´ c=ñí²¸ÏBëÕC·6-zMCëý¬kl‹¸ÿÖTˆ‰(ÔÝÎ ¢ìäû¦|öRôºÙ‡}ŒºÛÚ…1–tU€ã€¡wEJ4çwïÀ_º˵ÈÅxyî&ümRO4Õül'®t0ȃÊeQÐ2Êps¦c¾öˆ~í¢pñˆM¸8“däBË¿¨HÚò¥—ÃÈ' þýh+ž f§×Ó&²Ž˜(( ôñ$/éZó³Äâöè]øX],ÿ(Öï‚Au3ñꇮb©G)Mq~¡Y |¹E?°® Î)3Läç¡–Ÿ¬êàËþȽ~Üû2èJV¼R‡mç'¤T¤üå*q…"8*—§Y›e$vé…é}Ù‹qÑ®=yµï'ÖÓ<¨É_°á(îkÕ»6ÚÚòÐ.±J]Â9ûšHvä(>5v;š¬3b©Jµ+œQû<ͺ«÷¨QžtuñH+³‚¬¡ÁQˆû&Iw³]~õâ0il–ÏÙgjý§ä$žùW:>¹+Iô’zçZƒìà\±Cg±ÞAeáÇ’\ÌW×2 A—(Ñ'æûI†¹ ë5(ïÜ Cy‘}nϧìRyå1¥)‘âÛüÌå‘ù¨Ìj£w·&øx‰mãŠÝÇÐÖrT»gtO@¸4 HMg+xïÖѨ­o+"¨¨´õš63«d=œé`ö¯Hd,—¤Ÿã~<ÈË2ØJ\þ™}¹ä:1§´ç~l–uµ®íÊà…"v2Ĉ¿ŸI®9Ü“çQhln>ˆïÕv{â¶ÂŠ_•YäÁMp½ØÃLi½¦œÅe¤0x‹Y¬FW†ó…!èÖ8TÑÝvÊñä6`öµ¶S·ßýìû_‰ƒ‘…ãvoÔU\¹U»T:sIÊõFÞûz6Ç©XŸ —oÒ×ÀÍfz§Öš§$@$Pí ”÷K¨Ú`I€H€|@@|%,-ŸâÞ¬ äG$PU „D£o ñ5ýõÛpà³¥»Ðï¡®b)¡ò\ZÇ CGŽºäXÒ³JѶ™îu.?O,¥s ê8¾/ _³—bõzeV—Ô÷§æA•Šåµg>Ó–³“dE w|¸ûBC£0tøÜ\x;vîÃ;«Žfæ¬øí¬0,Å:”gž¡S”u;t1›ÅF‹|P_ÐQ§Žý©®ÉØ}êD7D¢hUéŠwú‘3¢¿olhWçÎé—h D£0C3 ôó«z-Úቮ'0u‹Ùàh¯xq™4ÊèL«qï>u¶—ëÏ>Ž—µ½€ùßgÔNìë´O+.o ÛàýëNãÑU¶=árìÅë£ð\iG0/œ2è[§EœX喝ž*©G§q_ #˜êÁ£W¢ÐC–ÔåÓwlÆãš¤ l[W»ªÓÈØ ²žÒÁd<Ô¢—{âËþȽ~\¨äã2”[H|Y~Ù0ÈŽ@]ÜÐÂïÿ§Îh-ÀKsÖi±Rº$ ÚjF—¼BÐÎð®ü~еÚÌÑRŸš'>x—ÐIw¯Ýûº :´Sß< yOh@yB$@W…€·O·«¢lE2 YùGî¶s[s7ã±U¯6 ¾r3Ý Òµ\Fû0i±z•Ÿí™õYñ6`º…Ä=€Ô~‰Fo±”иٛ‘'¾”tð¾R|þ –¯; öžê[ Ýáëÿ´ŽQ«évmþÍ`éÑ<ʺqµ|ïê²ÍÉÇi!/ÅX»h9þª3tI±l÷ºÄÀÞ©ùÙɵK+2Ñ\N ›˜-­~‘9’¦%OÄžú4ÅùØôÓ*Œ_rÌ1±k;$‡ªu&—AÁV¦K¸p¾@“®=ºá³ßw/Û\ë×ë6y¶`çÓZú±LÍQzײY=k¸÷õUq%}4n¡L?uѦµ9} äskú°:h¢Ê:ˆ5'Kméó21ÿ Þ°k¢ƒ”p}BLkžÎëÈœJ+‡¦«Z/Þ ÎA¦0ˆÙ˾„ãYªñVÑDXSäxfÍTWz8/§}Þ®äxfÖÚý|íu«<˜;–ï.ÇBÃ2xß«©.žYYF‹×âIah×»«Ö`Ñ}½Øë`»—%&Fg l€[›§„…àFi<¥íéSå•ÏYŸV:wŸgù²=—eÏÇ\Gö2íÓ˜Kh*cH# ¶ã+§±´NB’ØgFË3¸Ä"b6—s_í˱…k÷ô%럶$ê™U¦û#wûñ¯Ë ã •Ó™ŸZJÛQc¨O[¡ò;Ë»rým%’Ï–K_F·ÎMRÍï e˜ÒˆK›.åÝ—Ѳ]‚uA{)!’ÒX'ë2ê7kêÜ?–lÃIë;—‘õ¥âbÝ;œs¼—ò3:wÛ½we0–ÏÆWÖ싱ßq”Ö¨»te”)ÒTèžp%ßu˜çeqT>{?û\éC$@þMÀÓOìü»4ÔŽH€H€H€üœ@`ÃÖx±ÝA¼¸G7Ÿs “?:†­ãqm³PˆúKòr°óp6æHÆ™¼Ò¹:öhÞ«VaµRFé ÿ?,*Áø”†Èþu/ÞØ¡·àî®Ò—ÿ²G—›ðËÂä·‹A’bmù"E¤OA¡ÒபSÞš· ¥iÍV»>RÛ”?GKR&}Ë:L9"ÒÔ))ÆŽcI¬ ‡7Ã3}›ŠS{c•5\ÿOñ)<=sŽ…[0¬}S¤ÄÖGýKØ·õÁ(çj"ÊŽ-›qï‰ø}JÎÿúf s¸¥}¤U—æÞÖ—tÔµ‚ K0æÙ…éËJÖ 1I Hˆ0‘èRÖÇ=ý¢°z…:³¤ ï}¾%ƒ:ŠÊ/à«Å{µÙLRª”žèF=貸§‡7oÄÓ;Š!í“4°u#±ñ»Ea‹°nÃ^|Ÿ¥7ˆ† mcÉ ëÿeª|Žxú? Eú’$8gròpL]J—ù°A=ÑVyËwèsWoì|w%~ÔÉ™=ঠǹ´O‰~ͰFÇ!¥ž;:Ù’TÍ3[éÉRY.–DàÉßÿ‰f››m×%NðM·K9ª‹à®wRÿ1¨ ~Ô-÷ÕVbé†&Õ!Z, Yˆc§r°uÒCâ1ï¡NbBõäÃþÈÝ~¾.ƒž§ç>,¿§Yûs|í=A¬ `pâ:®SLêÕÀàíÕE½X ÞŽ¿Wàô-M»tÄÍ+–ã{5£œ£xðíS¸¹kZ„ ÏÒ¤=…àîÛct‚Ô©:w^¿K8én»÷u¨â/Þ¾áH)$@$à%cX²[{ÕK`LV3 °ýÔÌzg©ÅZÖ&¥bìQ½ÌaÒrúæ§MÉyI5ž€zÿt|#žZ—w¨ËªÈh6ŠÐ¿:Æd½ÇÄÆôŽjƒÿܧAÒÅàÞÓv|G*’jK²$£A®íOWèGDlF¥±áËŽã¶»ZÎK66HçzWKº×už¶Tr¬2)Üš'вc+4ûßV›ñ*?ï-Šàæø¢­½aI’«­e›žå|Y²ÄÖÉxqh’u‰+¹¬r2³^’\«^b̲Ž%? 7HZ6º ºV̸PÊ®u{üÞfwËݬq÷²¾| £¡žj7Ä­íB°QgÌ\½cŸÕ@9¼^ Z&JûK¢OÓ5Sÿˆ7¨T ð·%ÀŴ®k¨Ô¾ÔNœË”BTij,}ÛQý¤£¾½éý+r$Ï”ÉÍÉÅW¢8s7ôKEWëT6û¶©gä,½äo.§þYê*]e…yÂÓ¬;ò Ë>uŒÀ”»‡>-Œ3+]·ƒHLÓ¿ÌÞeë'‡§?ߎ¹t².§gÖAÏÏ,[mCáqñ¸%<ÿ)õ,—oéÖ¡JdséÚ&Æ2W,­Y–7×f>®ê¨Pô-RyÍi¬ ”;×ÌÇQ;Çðàt,ÐÜ ©±ÒlE£kоž?²/ïQ?2r³Nâo+lû4YS„”‰½é„~Ò&!z|ÕIyº×Þ”ÁHÁõ•¹¼RlgmÒÛò»ÖàÊ…:+—'8âåì=áb^‰•¥9¾MIy›ï µ-Úô Bjj3üm‘ñ¹?<5^ë[lqëâq°ÿ“íº/Šñý{cl­€2¡Ÿlí5ë él}o=¡wï~òýnÓK>s¯Ý{Ws^úksùô}¹>žz^^©ñ¼½'\Ê}¥Ù8¯o»æ²Ø·U;I€H z¨1KáUïjdéH€H 2ÔBdý5!Óž¦0×ÚU†r”IUœ@zÜØ_ÜÛ ·D—óùx¸˜Ó3ñÒW®ÂÕiÖŸ?t-î3 ÞÊ¡@b‹x¼õÐ͸5Á8¸Û´kO<Ÿ¢_ìMJˆ‘Cúãùþqjr«ŸîÆ<8Pß/áú`Ñg¾ZŠh¿Ü,ÏpÐ 1ÅÓ…™óÓÙNƒC¬³»^7oiF%[0`î£t:‹¥ï®wÂN’Ò:>Ö×åWý×um…[¤II†ñ·õǃ)ƯêË ÍÜÌõÔqp_Lig\žGR¿¶b`q>}†Æ{7Æ‹ý–¹0Üwc/|3ºƒbà“㸖YNÛq”ýBC÷‡Y´%2ÏÜ}&uµ@íÊãÖN1¦¶(Œ¼¶g©9W»6ëîX¿fbÖ×}ýzâ«§Ø•¤vÜL}ê·Â˃š…çdàó9ÂϬƒ‘ŸA¶¡ÿ‰Äƒ߆EÁ¢§nÃímûþÒ¸U‡FÕüëÊÌÇ•v»kS1ûLïMõnº–ã†c@šíÞü®Kkåd_-ñ¼|>¾#=œmƒ'tèß@Û»ÍXGÒ9½ŽÞõGú2Zõõ —öRó´ æü\]›Ë[?Bÿ`5§ôMùÍR«Òµ™—+Ý*/%æ4Æ6åÞó(*±®3d…‰Žu`Cñ.6¹¿xîï}r‹˜9WW­k×÷¥WïúÌ”sOÞ_wŸ'Eypät..ˆ¯ëë×­… /¡nÝ0±LW¢B ¦Cæe…bߢœ"Ô ©—‰øõP/T³âªR^Ù"n©X1Ɖz娵Ôt;^ÂùìóÈy† CU=K8j‹ßïîò©XÞÎR_ÂżÁ­Dì’$¹@X,uQÇ‹G¶ã®yÖXÒ?cFÜ‚;[á|îäKéƒÑ(ºn¹ ž×—û:jÊ•sbÕá‚XkQ”·¶hc®Ú—cQr]æ‹2×.+BQ`E…ùtxþJµ‹2±¿EnÞEñW ä KáâBi0¢ÔGS‹ƒ†àˆßû^)ž~ÂG ’gÅ@^ýæYÑïÖ¢©S[<·œ?ç\çæ~ä«~\ÒÇ·ep]Bסî—ßµœÊ åý"Ø–#+;O"P,–ô£# ¨ºØWݺ£æÞ`»÷žS’ ب93–ø]†}õÓÇ]l?î¢b<  øö?î³bL  ðw5ǰäï5Aýüší’~]=TŽH€ª >O\Wù¸æSSCÙ.|[óäIž¾%@i$à>ö?î³bL  ðw5ǰÄ7o‹~­¿¬òëê¡r$@$Peðy⺪ÈÇ5ŸšÊváÛš'Oòô-J#÷ °ÿqŸc’ €¿¨åï R?            ÿ ÀKþQÔÂÏ ðË*?¯ ªG$@U„Ÿ'®+Š|\ó©©¡l¾­yò$Oß 4pŸû÷Y1& ø;šcXò÷š ~~M€+)úuõP9 ¨2ø¡.ÓšÄæe`Ū}@Hˆ)ÀxY\ ´¾îz$DØÊ“¹c5v+qœT$nÖ½S¹{UZ„“Gbï–Xòí&\÷§71¤emûÔ—ËphóZüš+ô°ÕùˆXÚ _÷xÙÏÛt:‰åæœÂÁ½{°iÍl*è/ *·nrö¯Àûo~†Ýj½Æ÷Àƒ“&"µexyÙÁ›üÊÊ$P¶»r1˜H€H€H€H€H€H€HÀ-4,¹…‰‘H€ª<Â_ðøµã±ÝAA2?y KÅ߈wçãÑë›ÙÇ(LÇ›ƒÇba¶1(sú,ü×HÌûú1Ä90.•ÃûwÜ…yÆtÈÈDú†ø ý|óÙX4 pÖ”DºÌ?° ÿ÷ì!ö^#f-Æ£Ý-J@>–<ñ æšô7¤Š‹ÿ¬˜€H ]¥'Vã¥ßÇO2 ¢’.Šk†¥€Büøt9z¨’„>]T}¼M§Êrz,ÂúgàÏ#SÏ&¾=¤„:MZü*î}v±1†¨×©+8oGð>?cF¼"O°ÝyB‹qI€H€H€H€H€H€H€Ê'P¡¥ð K.áDN!eå[ÿ¤sÉŽH€üŽ@éEœ±*eÁÀ‰aÆ\1ûhþßðĨΚªó&?‰õ9Úµ|’‹¹ãmF¥¾O½ŽyKæãO“ÒäàŒ/1⑯‘s:`õ[OjF¥^ãžÄ;_ÌÁÌYÏc`{%‹Ý3ñÆw‡” 7A®çù¸’c µDY`øA–žM\Rl©mgE§wØ•l¡ŽÏôz8Ž¡øÖ3†z›Î(Å|Uˆ]f£’%ØUw³c®Í¨Õž?ó¾x½¢äHó&ß…/÷çëR¨§Þ姦摼#Àvç7¦"      pF B3–Îåcëás8ž+/ c C—¸úhéê;ogªÐŸH€*‘@Ä5˜úî{ˆÿ]74ÔÍ.JøÃûhÛìQL˜¾Mdž‰Ï—íGꉚ"gÖ~†Y»åËNOÍÆË£ÛZ/bzÅâñDº oáŸ;âýhg±o­<“'vÜ{˜>¹«"3ÉŸ·:ÆRásæÄyÅ¿üCx»1øqý‡CCó0÷¶¡˜•!§¡_[u¶’1zìÄ¿aÞÄŽFOíʽ™SjôÚÍ®Ã#O]ƒ”ëz!êä|ÜñÀ5ÈÉ1#ç¬À°RÁA¡(Ü3·Œ‘etºóZÝì)oÓ9ÈGïu9='?†&Ñ)èÝ1 ÿºg8æfè#8:?‹ÏŸ˜©¤áÃï^Alj[3L_`Á£}&YgÅ}ð‡¯1ô›±Æe½ÊÏ‘ô#°Ýy‹QI€H€H€H€H€H€H€Ü!P!ÃRaI™Õ¨t0+OË+¹Äô™¹Â ¸š,èv½dܱ7ž$ß>‰ÓBºÍ?+ÊeM‹°nþ—ŠÒý0et²!}·ñ“Ñ룱X'|¿™·ãRú#H•Ÿw k3ä¤ šûÅh´’f-)+9–{ÿ††:XbN$ÍY;K1*cfMCr„cya޽½ò jØ#GËFªüónΦ ªP‡Ož3øì…9²ñcñЉ5¼Mçªdèxë(%@„fz…Wb^¶ìÓ÷¥Ç£’#²+&?—†q¯®2¾Âê÷``SÛ>Wð"?}Þ<'¯°Ýy…Í.‘ØëíÌÉ“(†ñˆèXD†^Fþ‰_°aÛoÈ/£¯AÏ´d£1Ù$¤ðL¶o߇,)p‘1mÐ¥{’Ã4Òž€'ωE9ƒ"ÛTúP {×nÀ±J‚ÃѪsO$7ÕÌ`©ýsæàNlÞu֜£ÑýÚ^h"t®©ÎŽgáYìܺÇωgÁ³¹ž¥ùbÁ#È8z9ù"~I0š¶íŽnI ãmådúvìýí¸¨µ`„‡G¢aÓ&hÕ2áº[¬‰=‰ë8·«âKžW;3%    ¿"àpxϯ4¤2$@$PÉJ³[JvÙÄ+e_˰¾hnŽÔ×õÖ‰8¹K`ï ýÑQ°‡>ñ@z°}úkXÑë}ôk)Z\Ï£RZ¯8TØ•¦ãՇؠç1®{¤éd1ÄÕ"oÖÄk‡¾}]™-dÁ´¿Þ¯›­äZ¤·é\KuzpÝOJ ¿ëÑÄ.bó®©ÂO–‹¯–ìÇÀûånvéA$PµäïÁ£ƒóZ¾X€ÎÛgàáéÒ½®sQƒñÉâiH´3àœÅ¿_šŠ·î×EVO“ðôÜ’b4Rìýüa<ü‘È-þ1|3;o ˜dýˆAM%¾4ÓnµÍ°µ†•žÂ—ÏÃKrõQÅy,žøb&noçx6«)rµ»´ñœ€™ÏÕÆSüUôÒF×kÒ›øóý½lˆˆàC‹ßKŸ.0FT®,}ÃïŒ4>¯ò~Á+÷ŒÇÒ û$ƽE¸'qíÅ]Uò¼ªø™9 ø í±ä% $@$PA{—ý IèÚUgè9wFÙ— hÔ¸¡a°INP­:ª{4‰¯È K¼Y6:M‘»ÿ7üF¼¹øœF¥‡†¿.hõyw¦HF Š¹ÍLS“ðÎÓƒèi“zç¬^»;÷C¡ƒ}¡l1¯ÜÙåœõøã òmâÄ—1°¹n– 5¼MçB¤ë ñeùÙcYJœÆˆ©kÿmFhL2:©RŠåY ê%$@U˜€¸Ý*êÏ=ÜfT{Öi.{1o•v)ŸäâË{†êŒJI6q,† JRâíÇcÄ2¦›ÎÒ…DË×ÅmŒJRàÒ¦aõ™2]:±'àØášQ)¶Ï`Œ¥>‡2ñöè öÔ%¯Æ§6ž31AgT²({ãIE_÷ÞüñÛC ŽlT®-è4h0FŒêµÆsWþU<×…ñOuâ±tšÍ¨déÙOÄŒ^íc­1j‡¨ÅÑ“¸ºdþrJžþRÔƒH€H€H€H€®ûQ±«§ s& +N ðà"<üÞ6%_ãÞDù§÷Y¿N—Óô'ƒ– du‘[xY¬‘d L¼ãuÌ8> S?‘ž>; ÕàAÏà‡?u¸’Åc©ÐÿqE~¯çžE·H¡ƒW¬¬Xš»rþ¸R‹aÏýïìVa=T‰ž‹ðŸ§(œÓðìønB„ã2e{›Î(Å£«€Pf¨BÌpùæí‘h õqà÷#þÑcÞ²~h0÷0hû41¯Èqÿgôþþ܈ÄÞoŸÇ„V™Øw(½ʦŽ3"/uO@ýl¦{o[„Ûï’>hÈÄßçí@ªÓ}öª[9/ϰçÞÃÄaâÙ'–¦K³’Æ)³’Ö½ð2oµÕC£®÷àé;à†´„*uóȽ}q‹˜,ÍxJ?"EœxFœSVÓõ&æýAšÁ*»ÒÂ" TšÒ¬Ô¯'qU!~|$O?®ªF$@$@$@$@•DÀ§3–Ô=—‰õÊõ'r QXr©’Š@±$@$àÒ«­³‡äÔ<½àãÞDAºÏ‹u§úÜÂÈ_"K|;™Ö (ÅÅ¢ úè¶óì“8­{lžžžÅ'O¾®$ŽÉwª_À›ä\EËýЩO?ôíÓY \ª. _„›î™ƒ3—TÏ+zÌÙ4 o¬”³8c*ÍûO8ÑÆÛtNĹç}9ú*Œ#BÄÎ\h˜Æ7sí.1À|u¸:ÐŒ^$@># –ì\ð©lT’dF´@rŒ"ÜÐ7äã§Yê2jI˜ñ¢jT’ãF¦ÜŽé“ÔY¯‹±|㇂eØóø÷ŸGZJRÊ–×\£d&Ú³)ËÔ¼¢FbâPÛó 4ië#'I_º¡†÷K<2w1¦ÜÙUÛï(qðL$ç€ÅX­«‡&݇`HZ¼fT’(4íŠÛâežæ} ‹•/ 2×þ{slýØQÛƒQN Oâ*Iüð@ž~X)T‰H€H€H€H€®ŸÎXÊÎ/ÆÖÃç°7ø¼AùKºÄÕGÓHuóC0/H€HàŠÈß³wV–¤¹?2÷K iYÛ©!AŽ»Ë‚³ç´4 ,ú8EXñÒ0üßBÙØÔwâch¼ïSÌ[©Ÿ6ÌÁ½×îÀ;?~€n ¡® vrrèÛw”}‰€Žuú¥;Ñ[,1×[•#–àÉܹ ï>ñ2Ö‰/ì±{&^ü¤3Þ¿¿£ãÊÅÞPo> ì % „ö—ö,rƒ…·é*Zª€BÚähàÒh-¢q”cã“.:OI€ª¯ÍÂ@Ãó"íú CÎnÑ?lCy8{\)_|tp°òi\Ïî"Â6k¤ß‹¥6ÛÉ{ñÙ¨ Æß_d0l„Æu†´³Rº-’8ËÃq5¯ì/ñÆ{µ1KFrâѶo§| ƒáKñ«I‡ö÷a˜u Zã³&uø``‰ü<Ê+5¬kk¥SšwGé¹(¦¹ýÆŸ:2AññATCfÆLè³}Ç=‰‘w DrSS½zןë‡<ý¹v¨ T*ý(h…3²ÎXÊQÖ€0IK.©gòá% \™?¿“ƒ’ð§E¡_s1òfçl~Žüô :£um4y°*Ç<ͨÔë©Ùxyt[yn[;Sþ«²ôÛ6<þøüçó±Ú²Iz‰.Ïs¶àOÖ¥D¬ø±¸'MÍ2”9M/ M±)ñ—‘¸¿Ïëàäöï¶!ÿþ”+º$ÞæÙ¯á'EÉ1oÜ«,åTk-ÀÛtš€Šœ¨cƒ»3qºô2\^, #5ØåA¿+•J"¸N]õÔxÌKÇÜW_ì%å|T ¥ÏÖ!/ÎÆŽábŸ%¥.~úä-H‰£žÁÛj{Ö{ר‘]‘§Õµ!    +HÀÅØÔ‚Y‘ À"³i®Í¨53¿{θüNð¸dí«p‡~"îù YJŠ|ë>rÞõÃbÙ_ÌÄyzT²8—>±i#0ïÇD<×$ë~ؽ»ÎŒ{d(bÜ<¬žùíkõ^e¬r3½- ²3nl/¾zß-.26ápáX$_¡‰¥—Ï¬Æ )uíèîÒ@mù†1oÓIå­¸ GJO1+aƒ¤÷o8[€„£Î—órqFɨ ¸FßV7%€Ÿ(v0£¥.ê/¦ñMÀšþlÝø\’6æ©!nÏìñ6o´¢Z\#DI†¥ýØs ÝRŒór÷ïPf£ÝÛ6öU¶”C$P D4CZ¼x~då3²Q(f£ÎÅcûl}FÇf"†—.´º‹¶K DµÇõýû»˜êÍóÂK½ü-™öœ6*vbïÍC]úöЙšQiØŒ/0e@¼§1NäÈÂÑíÖðÉÐûqhÝ¿ðGu–òÊϱ=g(R Þ<‰«©è?'N8§ÿT5!    Ê"P«"‚뇇X÷N Ï\ýIû+IqéH€Hàê(¢')³|,xzÁëèèʨdU´n¸KÌP‘Üú„ÑòR¸æ)_#wúýMh¢w‚Äfîr2ìÞƒãÆdÖ€m2K,’m)”Н×Ož8eýË)t´`˜0óÙß5£LßQÜ6Ê(Ù¥Y8 BJ.> ñF‰[ºÈ‰ý§!vß䫱ä£4ëèeï)`0¥¨°ŒñÌW§{Iå(,OŠ}1Ja¶ð™sP®]¨Ó$uˆu›sþ7Lа\ìÕ%»4 í)íå†s‘Ÿ©…¼#Àvç7OR]ŽDóx%AÆB¬>jÿ0Ø0o¡&1¦a*år(š7·È²²`áæM.OtŽŸ±íƒ§yçâÇ/Ö*WiHk-×CÁ…3ZŒ© Ú9„‰0O›I¦=ÌuáÊ©Xî.AÌRþèÃáŠG&v¥;©OâÚçtõ|Èóê±gÎ$@$@$@$@$p• TȰ\ M#C‘îòOŠ#Å¥# «E pÿB¼±R—ûÉíX¿v½áoõÏ«±÷D¾.ÐáŽû!Õå╇ÞÁ!±ü™ä.çìËÙýU‰›„±7+(«O8ºK¹[Ý <>õKœTÒI^gvüT÷GB 4†(Åí#f ný›8gêm;–fà{u¶bqsZ¬-ÌéY2÷g §TgX)<†¹ŒÆR%¥s+Dê‚%ïòu)BNN.rÄ 'NØàÎde¡P, '…êóTò:ö¿ÿj_èÇŽê/JáÞ×ó§+Úƒ‰ Ë;MÀvm PQDT=óó²lß‹²ÓbÔÐZ¶œ"[dé,¢#%3Ï]ø<Þü1C ßùÅ4¼­Øšb'Ž@b¨}¹<ÎO“ÎðžÛ÷ì*”R ú<ü˜""o yëªÏ˜|¬ÿø)üß’\9\Ì>šdžÏäAî"¯~S¦*Ï+`îƒñþ·;‘¯ôÁ¥…ùÈܳ‹ïtßÈîAöU&ª0ºè7 +öŸU8äcõG¯`n†\‚Øq¢ï’ûîRÝJ‚ÿývr ‹pæèNÌz|¤?}þ:œ¹¬<< ÓñÊ=âËŸwâŒx.Z]é),_´\>O»‰Êt%Oâ*©ýò@ž~Y-TŠH€H€H€H€®Ûhæ•Èy ÀU"PV¢7ˆ¾‡'9ÔÄ2î=|?¹«а7þ>c0FL{&e,À½©Ë‘ؾ1NïÞ¯Íñîëèi4"$úz½7ÞºyzîÊ¿âŽÔOÑ©O;!c¶g(‰"—1>£ bI™…D‹3¥S8Zh´ôÈ.miÄ@Ã’:ÖdöÿäíÆT±§“$5¶}g4o(6v_¹M/ ÓŸî/æËPž.ù{>Å-cæèäȧ §ŽÆBÅ7vâß0obG]œ"ì^o[r¨ß¶º0W§Þ¥³1¬ã@x>¾ºg0fe˜‚Ä@Ù½×.PTîÒuŸ{ÐI_êA\)­?;òôçÚ¡n$@$@$@$@$Pi8¨ÒÐR0 €¨í–: í ±žÃg3F*és‘®•,xàÃxôz{é„¶Åô5sðÀ uFQ.¶¯\k3*‰¥ç¦}ñþŸ½3²8ÿøÏæ dsØBH€`‘ÄA (Ô@Š•Vð¤¨XūųÞ<©RhQ¨´B *  ±… ˜ÈAB–òŸwßcß½’ÝÍæØð{ù„wÞ™gžùλï;;Ï<3·Œîe¥W@7‹)Ä`uM:9SgÚLÌ)mvY„µ*–d>JÄ —Þ¨”vÝ=Xµóy$;ð®iIø‡:(Ì:ÊhW‡FThmƒqáu”Í:Ÿý™'ù´zC„‚L¥tÐtÖeÇÁß6Ÿ<æoX†¬9e•¸T£RøØ[ñÏÞ©[ÑZšGåY‹à ¸M€÷ÛÈd†ùp¸Ü§úŠ éÛ'wúœWñ÷Wnþ*öG¢ð¦|G¼+.í£_PT¤Sßòªlö•u? 5Aìø;ð‰Xêuœò|’â5£’'f´ÛçIÍ{N|¦\‹??=KöìÒ•¤g÷ßw>dåijš¥{÷«t‘¹à¯Xÿñ³Ú²¨‚0~<%vÐ ŠÆcUoe‘^{×Ïyë_ž*Ø+ïlwÒªEwÆOò쌭BH€H€H€H€H ]œ·té?åçcîÜ'Íö‹‹k—‚Ûº‹‹»T}Úšå[àýc̓g2Fá•’·ïº‡ JLqŽ¿`Œ.¬\dª<† „¿Px«ªÑ=:‰ý¬ JmÍØTsGÇ©ºÓ¨¯m@`x4böúÛ f¶µ"]I¾ØÃ©´`/Jº#øt5Ð+ÉÚ·]»ήZ¾OšoÙs‹´”Z9»¡±ú‚z÷Q¢Úê¨-?†ŠºF!ÞA¡!èÑ#ÄÎ3µ­Ên­\oßyoß[ ¯±ø[±yí,™*QRVˆ ýÃ"mT͆4{šÓŠY‘Ñ0(KåA¼WKŽ›Dþ0Šý±4¯ßFi™ØJ±“˜• ø‰<=LÞ0—äNZª¹Ež®’r-·yºV*S‘€oà÷Å7ÛZw ~_:†;K%oP¿Ç‘Ñ1ÞÛjYe¥GÌ2$ hµ,½ÛyØúk “ èø‡Da؈]\t9ä`P(${ÏNP+"‚Bz!a0­@hŸUìi=x˜ðNâA$@®èc¿¾rBcÛ? Æ(ÍËJ.ÔWWªáãiš$ýƒÂÛO,UçÊa•VÇP¼Wc52]¼7ôì-‡îš%R¹“Ö6o'9'ÏNÒTƒH€H€H€H€Ú™—Âkgà,ŽH€H€H€H€H h† (»+Iž]±UY'    p‰ K.ab"     _$ÐX_&«}¤ ¾XN¦3yv²¡:$@$@$@$@$и^@g‘$@$@$@$@$@íC yæb¬ú¥Il7%öšB3KÓµ:>_ yú|²$@$@$@$@$Ðj4,µ! tVþVû!uV-}G/òô¶¢¦$@$@$@$@$ÐV¸^[‘¥\           èbhXêb Êê @[ a©­ÈR. t14,u±euH€H€H€H€H€H€H€H€H€H€H€H ­ø·•àÎ"÷Çââ΢ õðA¼|°Ñ¨2 tB|Ÿ4ß(äÓ<Ÿsõ*ï ï¶Íó9W¯ò¾ðnË“'yz—¥‘€ëøüqS’€ú}!  ðôXò•–¢ž$@$@$@$@$@$@$@$@$@$@$@$ÐÁhXêà`ñ$@$@$@$@$@$@$@$@$@$@$@$à+hXò•–¢ž$@$@$@$@$@$@$@$@$@$@$@$ÐÁhXêà`ñ$@$@$@$@$@$@$@$@$@$@$@$à+hXò•–¢ž$@$@$@$@$@$@$@$@$@$@$@$ÐÁümË?kÁs          6%ÀqÙ6ÅKá$@^$@%/¤(           èÊì<–p–¶ñ®Üଠ€=òýÛ°üuØóc ÆîˆˆŒ_Ýú;¤÷éfŸØ“˜Æضf Jê¡—OÆ0oÉõD—vÈCží™E t=—ízmÊ‘@%`oXê¢eµH€H 95'°{çìܾù%(¯9-’#eÜdüæú«hô³Ï^S„Ïþ›Ú_ÓÅÔ‹¤ó/Ë@BˆºtæàÙ&”îÆÖ-;°{W>JŽ•¡N\è? “§]ƒ_e †?š›P…ÏÞ~_÷¥9ŸT‡3nÜë/†¡Ù|¶ŠØœ7žAiñÈûúK|üï¯pÙŸ_À”-´™*ᇼ½øê‹ñUÝxþщjAÊýŸáÕþŽ=Ǥ6ê~n›7£l”jùÔ£vu&VüÏW¨×c.¸Ãú9×Ç›up¦ãIÀ]ž|Ý-ƒé[&P’» {×"0ò\>¢o˘¢]”l~Y÷~`SV6¢&]ã¶a©ò‡¯±3¿ †¸LÿÞ6áµ§^D‰(%kðø.mX"O›[‰§$@$@$@$@$ÐÅØ–Îâ¼.VEV‡H€Z `Ú‡?\r3v;HVò΋Ø(þ²^ywdXÖÜ„Gþ´ÌA.û¨¬¥pLjpû 61yïÝ…[~c+N‹JðÒ– x)åZ¬Zv'bý—LxaÒ,¬9i½dá|¬Y-òýÓI>ëäVgG·áñÇ^Å绤a0Ë1ø”Iœ83,ÁηŸÇË+6 D¯K| ¤\A1v¡Â Oá·Ú`/ê~ï–¶uB›3ÛÕFŠvºóŹøã{2‡ðÙ‹ðÑ]õkú€Wë Ì0 xDÀóï£GÅ1S jññÝb¹ôlì9 ?ÿìVôhÁØÞ‚@^ö ÃX¦•z^ˆ»Ÿ¼‰(Ç7›v ªWso-Ç…ÿçÿðäëâ}!ÚxýgƒE+‡Œ"(½Iº5?'EÍᣟäé£ GµI€H€:ŽËv‚F  $@.àK.ab" .M ñ´>’ŽpdιÏ/?ïÿw_w¡VíUw݃•6†wï 5ž*“59 ·?ýÞøà],~天šìY‰{_Û¡žé>«°üf‹QiÜ}ÏbÕÇïãÏóFËiŠV"ëö o›:è$8 ž9žkgTr”Î:΄ïlJJ‚ë„Vg•¹Ë-F¥ž—ã™÷ßǪwŸÀÅ=åd«îº+÷KþB.ž¶«ñåÙ¯â^ɨ¤èÒ»›ãšx½ta ¸GÀ³ï£{e0µ;Ã,©?I,×½ªýq¶mÞˆm؉J7ßÞÔ£SÊ^ËÅÒ~/¦†a£/Ç .@¦ Þ¹²N©yv$}–M$@$@$@$@íBÀß®“àíÒ0‚H€ºA¸÷•Eˆ“£Î(áþW1¤ïŠQ VlÚQ3µš†Þ€Í;³´s} (¨˯šŠ¥ERìh\>¤eo%)åÀ_Üç/ǨÁ½¤SùWw&âŽQ¿7{U•¼ó/Üv1ƒ,ìòì¿cé9yÚ}oâ‰ë‡˜Obo\ˆ°ú;ð‡×…Ô®ñ^n&nIu¾„›R¢öÑ­ïe¸ý¾AH½ìbô,}¿¾e™vÍiàlFÞu'¢#Sqé°žX=ój,/ršZ¹p+î~C ÆâuObXˆT¿¾XøA8î;Ï\÷×îÿ'¦®åÚ²~¶«¦•_ã¾¹+åh½–]Â6¨ƒ]Œ 7 xô}t³ &wƒ€× Ãû/Mð qíYæ†ôæ’úè1üQò¢A,ú‹gzzHs©Ï½k’'Qø‘ÙêÊ'Ïzk-|týƒÎY4òlõmD$@$@ç*ËÏüs•ëM$à#ì K>¢8Õ$ ïGz†´¬™}.yºXgáï̓Mµ'¤Ýެ  ÇËÁUf/UŒJÀ KB²‹x†Ã1ʺù,hn3s_ß/ÎËQÕ¨Ot;ÞW ¸ó¯O-uI¿ù.\üú,ì±kWíÂìÔ+ZاÉ"Ûß8 ×^?ÌQ[í¢‡Öy~ö«,(¹âBÝM?lÁ*Åh3îñ?(F%EÃqׂјýT¶XðØvt&2û¸°_•ð@ó´]-„'ØóÌío‰sj›:8.‹±$à2¾.Ëîê ¥=ïJK!l@‰ŒE  ²?Ç·‡`è„ñú½s‹ò¾EÎw‡Ð q1DbÄ%#Z7@ÅÕØØˆÆ!´™^¸«²4™b?»<±ŸÝ‘2áÕCHô2F£ÿ€XÄ„‰Zqýà±SJòS8z¨å=Åò¤Aˆîctù –ו>k+«ppëjó;Rª×‡ŠQÕ&ñÊ7ö‰F:ᤱVì5XŒ¢¢²¶ è3dÒõAT0jÃêe­^íÒŸäÙ¥›—•#    €ÝOÚ³ºÁH-$@$pŽh,;ä’QÁ OcžR=\&>ŒÙ#¤Ý,†«´.ŸœÁ¡|ɨäà0ý€O¶ÈñáÓÆ¡Ÿmÿ8\6Ø!ÒT}üò½ÃÜß2ÂVªWÏØñ¹"/c.ж“Ýo¸dn†%TáïGæ²G–]B#\m×oß^ y‚Ýýîû\z žÛâ¸ö®ƒc-K$à5µ{qÇÄß›÷ùeé2„¼;Kìu§H{çŒR÷Îi<†•ÏÆkWÙ‹»ß}Ó‡ê=VkñYŠ7«ñ‰ØcÉ ?¸%K*î>ü¿GñÜ{Â+ÕÁaÞßï‚C¸i¬\9Iž»þj%u,^þâýsØ{©ï]=IÞóJ!²ñO7c£ÎZ.öGL Gá†ÄR­(±ÖácïÄ»/_kå™”·âV1Dx‡‰6^Ní£EžÖwÏH€H€HÀ}—uŸs t î±Ô1ÜY* €ÈÛô‰¦éðáýµpsœ×Rf>ÆËLôÎLðšï5ãâGcÞ ¨¢\Ù# èåhæy7 v¡¢²˜ÍÞÙ&P ¯€‡å½¥€(Ä„ÚÍy@PL²eŸ©z³?@sMÐâ5WÚµvï*Ì]$Ö&Îû«6¢¦Ü‰è¨ƒMM$à-âQ$-ç%Ko±•Â¥½ÖbB!ï$¼g]­•bÇN ×){Û “ÔK×ßj·?_ úüŽ 4˶üç®,‘~æT+£’Tþ´i—#1^6fu •ðCJ¼¥s¨g8b¥4=#Øþ‘k“¸kŸFŒµ© ÄFŠ‹EŸî2œSÅ_*i‘6q²®»\øÄÊGÕ–¿à… %Ê™üá¨,§'Ú¸=÷ѲR¢ƒNȳƒÀ³X    hgv?%Ïžmí¬úv®‹# 6"`úáCͰàê>I"ÏÞ‘˜.^ð'¤÷ðÆ3õ >|HÞ_IªjÚŒK¬fF×Ï7Ϩ—®vjü%óqU&¡“:°©ÄvèÇy5ÈÏVå„Ñ,Αn PkPW}ºUêºÔ®¦}xìú¿Èå¤ÜŠ—nLáçå¶sœ+Â+$@mF ç$¼üî½Hï£.zå[ßÔ¼3_†‡~%ïÃ÷Û«>Äôkž>–%X²*£æÈ‹ƒZéfóHqWVéæWµ²%#ÈÂ;jŠÎ;ÊTS óZ¤<´v;®~{6n]$y¾ûØ-Ó-9ê÷”UÍ|èÄ€)Ïü—Ï\Ž+¯ì÷ ËWÛíEØ{øL<°øL ”yÝþÛq˜,¼’%?µ‚ââÿ¾öõ¶icû]-†<»Z‹²>$@$@íO€ã²íÏœ%’ xF€Kžqc. .N ñè6üþêg•Z†ãžtaŸ¤xç5ÏÕ¸kÆàÖSž0Û^™cY~M b=oÞCI'Ú_7ë]Ô¥@÷^êŒìäJÃ`è8‚ Æ)¬BœÌîê.†Må£$û;Tâ<*àZ» CÞƒ7k^gÏ¿:K3äÕ;+µëàLÆ“ ´%ÑÂóΨ$•U‹MK•åÑz^‹9S-Ïü ÁSpçXYŸ‚»\xf¹+«Ÿ/Û  þŸöÊb+£’t!(Ä`ã1kÐÒ3ÐF»‹Ñ#¦`Êèxͨ$%8¯Ïp\/'í.ð‡ÈÓ!F’ €°óXòñúP} h5Ú½âšë¥™æòqûò•˜2@¡î\|á¿_Æò"ùzÖâYÂÒÚYàUøðO×â9uß±Ãúg&Z lÙjèïø±^w¢BKÚ+Üq-A{Î3¡ð+i}3Gc´ˆMÕ=YZÈÕv-ü÷“š!ï–å¯b”æuæÍnh£A;Õ¡B¼D$І¦-~Pçá£Tƒ#G”ðÉ•xnQ7ôÇ9B¼2ò¿U®93˜«bÌŸîÊÒ¥Ç$ü&CZ´¯µï+…xâ€@cÍ üxä0Ž­Bƒ0î¯vˆQ. O—Q1! t:lt±Óñ¡B$@ç’­¯"뮕J­ãϾŽËûµlTBå×øó£ŸÉùâgaæèVò5Æ«³®Áª=²ÈÄÙÏâ¯w]æÄ¨dÑïÀ!±WÑÐæf¥_ˆ¡æµæ:Ù¤ªòžo<‹„fÞN‰#“­7»wáu¹]MßZÚQÈýøÇðU]¹„îÂ;a‡Ò‹æãŽ]QH˜ô'ÌW–¾JÉGÕA‘Î  f²/µæöœ´Dïxg™âéh‰3‡ŽÔ #D ‡»²ôéSbÑ‚x^n%š,êi,ý¸…I­,æœÉNžçLS³¢$@$@$@$@]—€ÝзXêºÍš‘ 4O ò«å£’ØKãu \XþN–¹íÿC"þ–§®Ó–Nk¾DgWOˆÍà-F¥q¿‰'~5D$vl 2ôO†´«‡T~I±ãéÓÕ§„ÁÉ|Ô¢Þ~UåZG}:R,!µK°;€¦ób]׳5U(WÔ««oqˆÖª"nµ«ØËI6#É"J¶dkûWY þl»wU¡0¹óÍÚ¶ÖeóŒH ý 8xpŠ^´jO–ö-ºûùßÂP_o¯š¡¿˜ÐÂáMY-ÅËnh,À×ÌÂçJ¶Ø±Wãúic‘ÒøàžyXS䦼s=9yžëwëO$@$Ў˶ˆ—I€: ;ÃR§ÑŒŠ @{Gwßò†R¢¼—F²qÙ:g~†gß+‘/§ÜŠ_ akȳ¼Žâs^¿WÛ=í¾¿*F%G)•¸^Hé) Kbæ|Áß vNªGÏ äü[ѯçpÄJêu²£gÜ ¡‘dXÚ½kžj®•T­ÚŸ«xF ‰’¢\;Üm×A¸÷é‡5#–¾ÀÀZ|üô‹Ø!y(ÄOÂCw G³Þrª6«ƒ^ †I€: ‘ì–<{¦ ãŠ+`<ÏÙ³ßY¼Rwe…ôÇØxñÌ/ù÷lÁ¾šYHï„Ïv¥v>ýQ¸æ ͨ4íùw1|¼RŸ3ˆ!s·Û–<ÝFÆ $@$@$@$@$Ð) üÌV+égoWø³­ÏI€HÀ93øð±yŠÇQ8øàY{i8ϽëïK´ý˜Æ]7ÞÆ¨cŸ¯ÑT…Ò£ÇÌ•¦&«¦ýÿÂ^— ,@øÄñòõ©VןôÅ„k„Çtìù¶µžYoÚ¿ «”åšÒnºÑ:£WsºÈ-ÿûY‚b¯!æ%43=jŠÙëJ*âýµ»t%IÁ3øTìs%£1ud´g›P©°,{^4â<Ë5‘Ïýv Gú¤Ld:ø»|üdü3¿v<õ{Œ}JŠ7v>d½Á^/€a ¼ôJ@ñ$þ|á||¾Ð”“+qÕ…ðÐk©ðvÊÕâ=å,c‰'Ï.Ò¬ @Ûà¸lÛ±¥d ¯ Ç’WqR €oÝZÒ=Áhm¸ÒŸ©³ %fއÖFG2ºYL!†Ð«$Ö[ Y]³œ E°ý´ÄŽ_€¿?­’¬ šQ)·,þwdØïMÔœ.fAþ¡–b„Œ6u’Úe“;þ¶uðÇü Ë•"'­ú«F¥ð±·âŸÿ¼Ój?9UŒšd£ ÏÛUé$`ìeiC«$ÕÁJOHÀë<ú>z] _ –6•æ–ÿŒ>K¨ŽSž]Rͨ$‰™!Píû(we%þjÖ¾û ÒÄ>{öÇ`ôï¥+Y2\½r«æa%§/Æi3¦½Œs#Ư»` ÍËÉ04K÷nUy„#sÁ_±þãgµe\¥‰)?ž2É Ô÷¼]»vO©¥øê'yújËQo    pÀyK—>ðS~~1æÎ}Òœ«wŸ¾®çîÄ)=lÖ®_\\'Ö’ªuV?óþé¬C½Z$Ð(¼|òöC÷ðT‰ óñ Q7¶Ø¢€ŽN öM*-Ø‹’†î>] ôŠGò€^­•{åw…:¸Wc¦vB€ï'`”è®Æ§¶ü*ê$K?‚BCУGˆé'ÔbåÌ_àµ="Iü,¬_{«Ó -ËұϜòÒR4ˆ‡}C£(»z„81®7V¡ä¨ A’}<¨ŒÎÒéÄ·w°SÞbÄ’2±Þª0¯D—xݸy´´C=\4( ø ;ÃÒÙ³üë3­GEI€H€H€H€:1f¼¾©û PZV‰Z¡iÿ¤fÞ7Ž}îNÜpTH€H€H€:„Çe;; %ð€€aÉÌB$@$@$@$@$à€€¿Øƒ'y„øspQ$@$@$@$@$@$@$à‹~æ‹JSg            ö'@ÃRû3g‰$@$@$@$@$@$@$@$@$@$@$@$à“hXòÉf£Ò$@$@$@$@$@$@$@$@$@$@$@$ÐþhXjæ,‘H€H€H€H€H€H€H€H€H€H€H€|’€¿Ojí†Ò?»‘šIIÀšïk<# ðŒß'Ís#Ÿæùœ«Wy_x·åÉ“<½K€ÒHÀu|þ¸ÎŠ)I€H€HÀWÐcÉWZŠz’ @°óX*+=ÒÁ*±x         8·p\öÜjoÖ–|™=–|¹õ¨; ´#;¥¾±qíX¼÷‹*+;nÙÛûÂ}P"yø`£Qeèdøéd BuHÀ ð9âƒF•I€:5>W;uóP9/à}î%Ó© ð>ïÔÍCåHÀ-ê÷Ù­L>œ˜K>ÜxTH€H€H€H€H€H€H€H€H€H€H€Ú“ KíI›e‘ € aɇª“ @{ a©=i³,           ðaþ>¬;U'      °!ÐdªÂù{ð}~!J—£ºÎ$R¡ÿ°¸tì(Ä„ùÙäÐŸÖ wÓ°e×~œ1G!ñ’LL{¾pž>¡}¸©e¥(>¸ÿÛyC¯¿EÚ§“bªP+t< êtë.þÂ’6#Óã[.ϱd§±5Gv㣵[pè¤ÄC”=WNžˆ¤hQ°£ÃT޽{ŠÐèïx褱ÑýSS` p”Ù¸&T—þ€ï¾ËGaÁaœ8Yifß-:é£.Ũ”¾h®Å€V´™;jv²´¼Ï7H×½ÏE}ÝyÆ8ÆÃX  /pÜ;ò’pŠ!      hG ÅXzß"tPdÙ¦älZƒŒÛÄä£}ІÃXóèKÈ>e}©ì_o"û‹ <ðÇ)0:°p4UìÁʕ둻¯Ü*cL]½8wlX2•ìÀË7[¥—OJp0w7Ö0óŸ¸ÑÊs©Å¨ÒœUxayŽuºcåx+7Û)ÓÑ,s¨£ELƼÇ091ÄáA¨xËRüå_ìs ýJrs°6^°ÿƒcöð°Íì ó±Þ笫Þçž]d1*¥NŸ…ÌÔhÎY‡ëò€c[ñÜ’žxbîh;O¢†ÊB;£’^²Ã°Ÿ<‘:! ˆ(cwÔ•~OÞû%ÃÖ©l¬Ý9sÆôu˜ÝÈšÂÍ£RhfÝ‘‰¨Æ|øú 䉲¶.y¡|16žKŠŽrYÁ0„Z—Z+òöul8³NÙüYS]¥9aH:Æ]”†„Øh*?ˆO–¬‘ „E[ñöG‰¸j’ ÏÛÌFïò>·k³®{Ÿ GOž1v„A$@$àM4,y“&e‘ @Gêƒi·Ý†¨!‰Ð¯x=}úõz]ñŒ)ǖ݇‘¤3ÚTçŽE²â§ÏÃ̱qæã„Üø:ÞØ ŒRûÖ`káÏqe‚µ& W &O”$„V|§9òD²†7O½|ýtËë£1gAþïÁ7Q&’Ÿ©–<žZ{TaËÒŠdÌ}d&‚¤S#f/0àõ—˜7ëßÞŽ‘]ag4“3ÆâÖ…@¢9Ÿ"Ê‹}.œŽ›R{#)&Ü"5Z°x1¯ßóšY¿²MÙ821 1ºe÷ZÓf–‚|4Äûܦáºî}.UÔ“gŒ ž’ x™g7{(Å‘ @ÇAbеQIÕ%nÌ•ˆUN¬6õÈÿb«r% W)F%5_â/¦ Y9Ù±í{4©”O¿°dŒMGœ1Ý»¹:ÕÏÚ¨¤Ê4ôÇðxõ¤õŸõ¥{°UYÚ/uæTŨ¤È5$bj–R³cÿÅÞ çµ®Öʃ¢­Jª€\9Im±jÔZo]›©Eøî'ïs}ÛuÝû\®¥gÏ=!†I€H€¼M€†%o¥<      脚ªŽ£Ä‘^ ¥ø_®|Á0&‘¶iü"14Uެýj'Šlxñ¼ú ¶)òü[¿ÁRiþwа` a§¨qàùJÜi|‘sØîºá§óRãÚþ³e‡¶˜X¬µYÛƒp«Þç]è>w«å™˜H€H = аԞ´Y tâo¾ÑJ8Hg>ª©Vöe"ÂÃaoÎ DtÿAJ^ì\–4©­ Ô”çã‹–¡Ö,f¦^*/Çç¹Ô&œ:!ï_ôDÏîjÖ«ª4Z¹©±âÓ„}ßìA~A1Êk½±<ŸNtsAÓaÍà‡¨$ôÑ/Å×IÚ¬9õ;êïó.tŸwÔMÄrI€H€Z$àßb &       ðiõ¥»°xØ'É|$cX¿­>¦ÊóžFRD’Þथ d>L8-ÙVôFåŠÛÂëfýÊ L?'ŠóPrL‘5wÞ}5âZ]FJö•ËB…a&Ò‘¼¦&œQŠ=sZ )MJ ›—/SÂ@ä L»f<Ö{Mi ¼¨Ç—+äý•$q/I†¥ÅDktT›y¥nm'„÷y׺ÏÛîN¡d  Ö ÇRk 2? tbM{ð×§V+cÆ‚™ÖF?ÝœS]P_¥À0£rZŽÂc5úK­×!ï«<äŠ?ͨ$I;}§ª¼QFwô¦ìQÔÝþ8k¯k@ z)±eûŠ /5 G,’ã!uDÆ«õÊömÅ?ŒO ªìåy%¦ {×-ÆjeyBŒÈÂ6û^¡ÃÚÌ+l!¼ÏÖ®vŸ·ÉB¡$@$@Þ à¤Ëè Ñ”A$@$@$@$@$@$@$БLÅ»ðìÂÕÊòrÀä{îÇEÑNUò÷³_FKJ\_m1¹„§q*ÔÙ…€8ÌyôAÔ£§+J±ïëØ¼]xUÚeÏìÆèÛ`ZŠn¿˜¦R|òîf”úÃÙ–G õ§y¦MLA |¬ ÄYérüOõcRÏPÅøtžùš_D fÏOÑò7Õ–c÷×aÕ†ÜÒ P^pÕÕH5:j‡|ù·ÿÃê¯NËå¦NÁ£¿Kuq~´k›9W£C¯ð>ïú÷y‡Þ`,œH€HÀŽ€óžŽ]RF ø ò=â¹%[uc1óѹNŒ3ÍÑã '®¹%Þ!.²¹ëîÐñC˜Qñ2F#.1 — CØ3²!,{ÉG¸øå™ˆVíX §°ã«Ýš‘ÌyI‘ø¥Ù°$R¨ª•£²é<‹,™cû‰þd£’ƒËð31|â04¼Œ·6Iù°ÿh ,‹Ô*ÎF^®br$D‰3dL¶o‹¦r¬ùYl-’ÅN˜…ßO• dŽŽŽj3GºtlïsÁ¿ËÞç{o±t  çhXrΆWHàœ!PS¼_ÿpþ!q‘žàä‡Ë9ƒÃyE›ª°wç”7ˆßÚ©#áø'žs¼B$@$@$às¤÷ÿ¶ÿb[ÞA¡zº…„ fàHŒ“u¬ÛçêD…Ï 5›-F¥ÐtÜùH–õòw: A½ã -'™JN”Õé®X‚§ë¤¤Ã„Æ&ña±k˜c½õ_PÌHÜ0io´)Á‰Z :L‘‹nŸ…Ó¯Èé÷¯Qì‹dˆVö#ꎄDQ³}’¬RœýxÍH¥*\W‹j%|Æ\1õ‚óÏéfÃPxè$ 3,õ=³ÔŠ•êœ·H[7EõS-j9UøTgTJ93GÆ©í>;S›Ù)׎¼Ï%Ø]÷>oÇ[‰E‘€K<?ãX’Kl;,ÛÇcôÎ{:‹ôñŒ¦rìÝS„F'ÀÆFôOMѶíi> —©_~¾;¾.R6 Bâȱ¸âò4„9í-û8gªß©”í]õĦ¶¡ã‘JÃ’h›ìÎGµø¾G¾qê±á8>ZµÆ¼±qFßT–:Õ]LeH€H€ ~åW ú“¢‹/Vƒc‡"1ÚvàRÇ©¡{sšû½0àü !ÄO©ïä]¨Ë~N…÷Àš‡ŸEö)ëÚæå1F–,> Ö×Ý=«“|¾ÌþùŽ›të. XÝÃÒ³úô닾ýúc@\4'ÿ¸ ö\N_[€·mT$cn3F%s¢ PÄ… 3ޏ×K„Õ41ÞÆs§ vŠß Ò:FÝÒor¤wÿ—¾òQŽÒÊ: SŸeb=)Å­ÂB#£EzɰT‚â£uHLPeÉbjŽšû÷ÒYb¿r¤ÿW×IV6ËdLÀPËvL– -„ >~‹äD§ßÞ¬QÉœª“µY Õk›Ë¼Ï5®]ö>×jxZ3Þ(akªGEY)ŠîÇÿvÀÐëolv9T·I{¨_yá:чï¢ëßk †&è–BÕ+Ö㨟57–$ê’»G¼£‚°TZš3Ñ7åDYŠ;Ãêâ|ë»ú÷ÂÐ4Û¾ƒE4Õˆ‰ÚŸcÛç{Å4 Xô2¢ˆíÛƒ†CRœã¶.Íß…­ŸíÀ¡“&³°nу1öW 5.\'ÜAÐòšk¢F)åõ<Òáå®IÃ’MËšŽæ`ÙòÍ6±Ö§óÃäD럑žæ«)ÜŽç_\cçÊ_¶n²×íÁÜgg"Á`]>ÏHÀÛüü¥Pâ‡b°º¡­:¨äí’|Džé(Ö¼µJ6 ‰ï{\˜ò}äJ“%ËÄ_Ÿž>Ò˜T“H€Î!âGÑ:åýe®õxjîH§ÆˆòÜD¿w·Ȉ[>ˆDõ·ª³wá9„Sªjù75£RìØi˜:"ÕG¿Gþ1/yj‹±þõEÚ²WŽðæš#ƒEûü‰êX»£„Œ#@=¾\¹ÄlJ‘†nf,¸Áj -™UÀˆ´Kc‘-y ý{+Æax„ú@û+Ù­Šuà/~ÇÃ?²ÀŸéä6ãW¤Ke¬CaÞ%2z[‚lS·t‘4Rxcå˜ylÛõ=®HHÓe©GîgêRÉy~s5³d+/”<å#yPO5èñgý‘íxÃì¡%œ­FÌÀ-c\å½6s¡°N˜„÷¹¾Qºî}®¯¥ný3Æ^fgŽñt¼±©bV®\Ü}b¬GwÄÔÕ‹3ï­¾â™~uøzé2l¶™¸£SÓ<ñùѧ3í&ñtô8ªGãgÍŒ%™ŽîÆŠÆ¡U.ÖãÑ€aõ¼¾p™29Cù-á ¯ÚT‘¿=ò&äÝ åÚgd”+ÁÁ\Ñ¿ØVû¶®Áv±ßàZu¿A±r¬ÈÍÆwYbÆÇïJ·Ëk¦}Ôb›ûÔ—wÿ#4,5ÇÊ¥kõMM¨15¢¾ñ'sú@ÿŸ!$ÈN6uIh{%7“å†AÌÚÒµâ¡×;ÔÁØ“|ÕùX¬•b1ù¶«1Tøåÿ°u5VozìÆâ§‚ñ§§¯n¶ã®×aèüjPœ_„²ª*ú§")ÚÚHÛ)ô·ú>w ¨ ´L@÷£ÈœxßüP;I')Õ!w«jT’RI~N–ƒïB3‹Ób¦ùHÇõÓÇÀì„—€Ts\ëú4õ¥9xù)y"‹\F0FOý%RõFSí ;z?ìU„‚å$üŸ\ PdVËI9uåȯ´öªiSŸCûD\„Åh“0f< –‰I§±êµ£ïW#ZZ©£¶ï>ó¡Rr,®Ñ×^ 1#¾Æ$+ýQsR]X¨}þzSêEñA1&`™ÀVS¼_7`XJD©¿±kûñ ¬Ý§PÛÕBÔK®~%àʱF¼µ¥µÛW`MR4¦¥I^Lb»-–²"']Š›²êkËq²>Ñ–ß,åù›ñÆ*ux,ýŒ–k®ªd®_­]£EÕ Åù8cÕdhSÜ&YïÕª6ÓJôÍïs›vëÂ÷¹¹¦}ò l4¿w’1¬Ÿãñ©Ž`(-ߺY÷>tXÑ—Îý×ß͆ ézÆm 09E1ˆIHÄð1™þ)Öû&VìÆªMâÝ+ŽÈ±³pÿôsbé¼»Æàõû^ÃA“óÖçøÅ_ôΖ'K÷àûò}Ì‘>–¥M K’§’dT:V%¯(1é§x/ùOḖ¯…äN¬aìd»ÎhÂå“* KÒD³œO¿Å¯Ò.¶_‹åÖ—8RW_$P'¼Š¾GiÕñtï†èç[Íf´¯Q=J‹ÀáãUæü ˆ81ºæ< u¨8z\̔ӕÇQQÝC,ùÛ„À„™×ŠmBuE…yVcPx/„œ‡êÒˆMq›Ä«&¬w¼Xݨ½tê«£`ÿQÔŠ7‘Ÿ¡†¦XÏâÓtme—•áXùIÔšÎ=ýÑ/‰1Ž×emlúI”'¶¨øIÌšÐͬÔäyhBÅ‘b9ažè×M¬)†ˆ^‘0jëÆ«‚]djNÞFÌTUøI$@$à“$Ï{É+é×éWØõ#‹sr¬oU°¥waSmŠ<„“æþ‚‚BÂÞQF¨Ë¿7™ªPQ#~`ùÁ(füKïíïö‰w¬è_ ¹Ð²¡YwÞ}²ÆM¦ üpà*jψ.K7 áèaŒÞ/ }Ýê«KñÃ%¨V\ =c101ÆŽD¿¡Z¤ÝŸ«ôZNEiEB›D]ÄÞGâÞbŸF_²u¸zÏçÚ{Ò€öŸæŽwºB_@¸ØSÆqE,PæZÌ\¼m¡Gò¿Eá‰&…Ç"-¥¯è_Ù¦‘úa…(,‘ú.¢ÕÂûà| ëšñ¬spÍ ÖÍN]cZæßdÀ om×N£¤Hí¹#óö»q…˜AîððsüÓ§ ënm! Œ—å£Z±Nž~€** 3o¼ ©1ŽÑôr] û /¥ÇïFÀ¢—ÌKOÖêŒe†ÔLÜ5Ûñw°[÷²Ž§ÊÅr=²®æòBáªÙ¿Æ˜D†{—²Näß2>‘!ݬš…xÜfÖ*øàïs»FëÂ÷9ƒî£Çêf)æ¬öo"½D}Øã¨îŒÉÅøá¨4­ØÂ£ç¬è›~ŸPîkJãiñÉbÑfLšŠñú#¯™½ù2ïY€¾ùÿÀ[Ô5Ö•ŒC¦‰=#ÆàЦ·ñ†äÙ§?BÓq÷ãYVËX”æ|€–«s%õ‰ÅìÈÔ)¸÷æ ëu{…‹¬×°µÎëÎYMñ.¬x}5*®ÞVyCÇ[­'ëS³œ6`f¥OH€H€|’€´„3Nýß‹½RTÏx¹"øzünŒ7¢¬H7XªÖ´Ùwa¾ü×J±t³ÍûYÉ«wþWùÝ•‰»¯ïŽ—DŸA=2æ%iûºýîBŽìZ…—Vä¨â,Ÿ6ïUùB¶¯zk·;ì±`Æ=³qQ‚Åxc*ÞŠ'ôÞ§rð—G”²„üÙ—îÆ;’ƒr8ìÓ¨í>ëðÍ'–~IƯÇ95*ÙeÕE¸ÍLß_˜w7‚¶¾„µÒ,6éu:ÿé¾Ñ¥û<„|ù¦¶ ‰œPú?7ýù±BƒnK"†:@P\þ%Ãc ¢Ó¦àÙ…—Ãq%º‰UG¤ß«Qñqkæ÷±'eÓ³ðlêd±\^ Nª‡¿«ƒ˜¡ÆH«¥ç<®ˆmÆ€¾˜<ÿ9Œ½ÊÑíŒø­ÚqÑ–ï¾m–˜KoÄé'QYY‡3bùÀ&±XOXDODõ‰n¶yÜ?¹ÏÃóW©·î>÷„½ZrWúti¼±•®(ØŠW}h7)Rìÿ6÷w#­ÇNlÊòH?û­GugLMØúÎKX¯N0Rë5Hô‚÷¥$›»vìŽdö°QŸôÙtXxK“<Ä1" ãCä°£ÿÛ‰¡¹hS!V¼¸QÖBŒÍ=pðÜ3–þ½^½ÒÜ]ÚXaÆÅƒô—š —iû–£ÑAÊÈI0ˆíc¤áô={K…a)ÁœÊÓòôEø7–aû›¢ÿkÛöú¿Þ(O_¶/†iXrÚj&ìûfN ocL4ŒÇÖcûìîç‹t°–€è¦Fô‰âåÊž4cÚ€À¾5xbc¹9+þŽ”!÷ah˜å¥/ÍRxB}¡ˆl‘©£‘*lOù²Í/’-«ñDÑ)<<ÿ ³q©»nV¢ZŠAÌjnDèßKYSWˆËÄ߯ŸR“‰å1Œ¨é̇ÐsÁº—´¯´¯tˆŸÕ[Fã® qò¹ø¿®l¿ÆÀɈ54"g‹üªÍýks†b¦~™ ^øòIœ×q&7¤CCE1䊥E‚ýµõdÝej®˜N_o1Óà1@$@$àƒ‚‘:v0˜ßu§±#÷°8·¼ë‹¿U–¦„±W Âê·”‡úšêÞ-ÖïÂ|ú‚X’£È’825‰!(>°ß¼¬T€îÇ­¶Áñ±Â¨¤æ‘Þù§Ñ]™zïÉ»¯©|—Ψ$Õ7 †ÚJäç¡L÷^•K¬ÁV¡óú"µüXŒž”$:ùÈþªDD–`õ‹O bÞø2Q`þY·PDŠ+RD= b),É»"Xxl„¹Ò§Q3Ú}špê„™Žôæ Ôd6Ÿž0“FÁµ>–ðÚPɳ­¶—²¶½.Íæ×©IÄà»®¯%¦½õÈJÜýòLĈô<º&¿ $$:ñNòb•ýB!ö(о^írˆßÙ1 ®sÅžQaÑâ¯]”kU!íÕf­R²“en/f¼Ï;YÃû¬:î7º[U©ñ´0ŒÈ‡é†¢áÛ­È¥ebbðâḪèC9<<Ó¯âPöæŸFp˜}cŒöû*9(ËÝqT©^®ŽÉl}ù)K¿1*Ãz dg¶p8`7 [UÏdÅ8f4¢ê‹¾æîý])K,18=½ÙÉ íÁPÖ¿[ß–—¡aî-cqt³ÓªÕU«“°aØ€”çï§_ìEE}=º† fH:ÆŒ:!NW ŠE˜ƒáx¿ðÞˆ¥JËáéÖ—'Æ!¹ÞÿuTzÉF.½^]9ì…!Ó.†§Iµ…–cóòeZå"‡d`Ú5ã‘htâ£în¾ ž(~Ä•ˆ™¤%Û¾AõÄxÍ«C.´Jl`æþƒGS˜hÈ)¸ãšK`ëØïZ¿˜]LËÅ`Q0,©³$*°i©ÚáKcÌ›+”Á˜+'^í{AžáZ´ïNû„-f%.L‰WîyÍlxŠë¬ß¥[gݱÊɘµà Ëç”îÂÓO­ÖÍþ0bò¼›‘!-A!6Ì{ýÁ%æKÉ·…0M°,‰×cÐ8̸½?ÒÄF½ê;iòå)xì‘fYGʤ)Ýmõk¶›tF¥È1b–O–n–Ø„ÔÔ –2{u¹Ï´­˜9–ËX  ß pý†„áëÝæåÖþ'°¤Ž‹d*WC„’z‹eoÝ8*v¯×•Œ˜q߸(N툅ÙÄF!~ANúË¢œT±É5cµ÷±˜ÛévBR·º¤PÑÚˆYO=(ú'Ê©ð'¨«Õê–®ØóËà€ðT~øæË”~w&&\ºÏ /*iÆãæEcø_²Ì=‚À˜1¸ÿ/?F´‡åú «Ò/)8Òƒ>¢£©ÒâÁ,<ÆzødïnµÍzÆÌN¦ðò¾õ¾«‘ØÜò,ñ£që ¿¿D›cÍó/![ .AÌýì›Lë‰9v0‚H€H€H ÕÜoô¸@]ÿBZ 汌´ôÚÔñü·g°Z¬¨T¶i# ~‘d½¢’‡ú5*{ËÕænÆ2ÕƒZôÂFgMÇÄ1ƒì—)öxÕ1aV*ø\ë7„—Öƒ¿»HÖeê¯pdÏ&¼±d³nLJ…]…­ïZÆÇ®ºï~ŒQúÇS§Ææ•Çfýrªj6'ŸMbìë e¡ä¬÷6”²¶CYÑ#ÛWbý>9<~ÞL$Of“|êði¤K>àí—ŸE­Í* y¹»±y•½'|¯„"›<ùk÷*±O˜<ñK-¤úû;£’tÍÓòT¹Ú§‹ý_GåÝÿÈýš˜s!ð³ÖT²^¬³}R¬g^ZUgõ'í¯$í³¤êžKvéD^IFg:zÄ"9~RG¤a ø¡§eû¶âÇÆ'Uj”Õ§ûùÂqþ(Eþ©l¼·é{óš²Ð:±¹Ù;Ø*uó v&`“…?ý.ÃlT’ŠŽî#ÍP)º¾økmo€È ¿ÕŒJrÊpŒ¹v6¤Wtä|º[¼l¤Aùp}ý×4ܹðF³QIÊ)6õUdH† ¬Gï‘JRœ¡?†Ä+ë„»¬e€&"q$.Ò•Ì©"áâ(9½ëú(òÝø¨/ƒzjúÐѸEoT’âÅ,È e#ŠÖ0U‹¼ÃÌ"!  Ÿ$ ö~i¬¬ú©­È+­—Ã ÅØ¶]öòÍÈ*–‘P'U¹RË:|ûiŽ–pôm¿·2*I…QÉ™ËÀéó0Óʨ$ Qö',¿ ʱg_±¦“ô“20@¯ÐY[v.7]›a5™+$a nœ:HÉŸƒÜbe”C‰Ñu}¬újõ!„zZ>ëâT±Í~zÊÌZh2抣æŒJ†Ôixt¾0ÂХ̟u(üö€É«™JbÿÄb©å»ÿxƧÊñ<ánSÍ,G˜Ø]Z9@:²—¬D~…¥ço*ËQ/ÑFÙäDæÿ=/O'Dl—ájÿ×qyzYçBXÿ[ÉíúÖ˜qðx $C’þ IÒ5õPÓýèomÇꈽCÐS¬ÛÜY¿ˆÌžŸ¢©ÓT[ŽÝÿ]‡Uä/ÏæE+1xá$¨FW%¥'ù'^‡äM‹Ì®×½‰¿MÆèÄ`ïÌ1{2iJ0@íF wd¥ëf‹¢ÞÍ/ÀLÕ–‘Ô úØ\§ÑfCÏÁ"³*›ÎC´›_õŒyWYoNè×âÅkGÈŒô 7ªþG¢ iV:ó7wB,Æ%s ±xÙI±FúÉZ‘ºGäq5éR›µÕÕšìÔ«/Óf‹k‘º€7˜z›™N=I€H€|ˆ€Iì7b l¬»ýËC35–~Éøù€îh:,Ü{\>L8©[ÂíR›ÙƒÍŠ ÍÀucûÙ%ñôÝ› dÉF®œ‹³) W]u†§X<–åÂtËÎE¥ Þ`ïÔû|ɰ$ýðŽ“ÈÔ €Í1–ÿõ-,WÝ i~bλœ ô”™^àèÛ§ÛýžÑ_——þb„ý> ‰/&æ˜Ol&òØæç9 @ë x2ÞèI©µ–NžÌÁ“"Ñ vOv*Ò3ýü0tâL Õ¤6¡¼ð|¸tò$ã–Xùæ½M1g‚Ôß³žŒ£º3&#–NTÊýÆ~AöýF1ÓÆ¢ª¯³x¤&9é´IEv¹­#Jw}¨©2n¿BL©vv´C4Æûê>JC¦à¶‰RßY>ü-0êVÃ6_”-òÀ›Aä»w®e󘛂ñoOb•ð„ƒ˜÷¿âñb¯$¥clHÂ̬dÅu@,Áü’ÅÒ‚Á5ÅÈÛI8;<.O'Ðþ¯£òêÊŽë¤uý µ¥ÇÍúªžHǪLÐÿUÔÖ£¡Éâ±$…¥8})lëÙäfñí’ÜÏ`Äð‰7⦠±Jy°ßÆ:ïH—òÄaö³ó0:^‘P”‡ìM²Q)v ̘`ù¢Ê7«£’G^$oÏ"³dý¬Z]Q'~<¨œÃêhT¤;â’ÕïM)N©Œ–‚ú=ZJÛìu±t˧{Þ÷^xæ5¼µd–-Y-wXšÍØú‹•?ZfQ÷émhV 7˜zY³šò" @§' ­ `“–ÄÒËÒQ¶ék1° ùÿ•gøÆ^dÞÇÒc—Ó5û¿X­XýÝì¨ÏÐ\f±‡~:ˆšÔÓwŸŸq$®Šû5îÆÚ%‹ðð¯àËbÝLZݲs†AFè<šÕÌAÊ$éüD™eâŒz½->µÁ…ºF‡žPÍ•é)3½ÌànŽZCŸBÌ:ËõÚÂÓZ×í“mö©C$@$@$Ð6\oô hýØ…äE²yÃVlÞ;æ¿í4‰ - Pz¦ŸŒ 阽àfͳçஃöžÑŒ£êëÕÒ˜ LeØsL®ª!®‡Ã~£B8y _9 FDhË},]Vë Øâáæ­(DtÔxŒM²^Î:±íYÛ1,û§k«îÛ¾¹¯/~]ü½W_ýPQ¤‹Ÿ{¯,þGÌãú1Á`LÛmXû8"mÊT±z‚|ìù¾ÔªB1cn}ýÑZ\ÞölŨ4WÝ4C[!I›¬…Ö•§äzÿ·¥òT‰]ûÓ¿kWÏ{µ~!°I¶Šæë믃³’ZÌgˆÃ´ùÏcli!Ž• / ±qiÄýð铪룡°³¢O­'àÆXŠŸöô8 S½ä–jïŽt¦¡¹ÕV]QW’ÛÊ£é0VÜ÷’öŒL±£.@œ˜ö±C¼ å}ZYF3Ùýüíg³8Kî¦^`æLAÆ“ øé}áã!{4ƒ/sú¡pŸ\…qlߺ8éc´æÝ72 OôOÃÖÿlÄæ¯ä~º´ûê…¡aÁÓmýþ¶FòXvÐc©¯…ú£TýlS8«;1^l8\$J9¶yåp‘èû»z´†™¥ ïôôK[d3D$@$@$ÐÖZotSýØEä„iøe\7裒¥‰îCd”uÿÊY1ég€´xÑ›+RÀñ†ñˆ³usU_/gº¶6^ß«òs06æªü½ÿeÞYHJŸ)¶¨pmäÙFz0ljÔí•#×Ù~QÇJÄÞì'QÛtµXÅHxiiãa1ˆ ·ïëúu×ÕÐÁ2näÕø¿Ôq(*:†ÓbYÁÄ'ÄàgÅŸb­Rí˜HËŒ§Ö–gCÒé©Úÿm©<§ºÐmhØ“:Š¥í¤åìlu)<Õk)Àïg ò‡”^Hymãô×;k¸ºNÿÈp]ËæòED' "Z'«z¶)Vòȱén/!¦“Ä ´ žƒ’„\yGòH”¶É¶>jpèÛr9*t ¢º[çh‹³ÒŸhF¥Ñ7Ý‹iiê­=-(Ú,³÷ AâSžÝ³go©píµvåÖì+Lõ:3L$@$й ôMO‡A–j…çÒæåkdeÅžÃbjÑüho½y³(Zûî ŠN•¿KÂøé¥øâ_˰þ+¹ï¡.ý±Ñs’ªsé)±À‰}Åt¢eŠî‰ ==¨…»Yaì+Ö•/’—Ù°ù;\”•æ²Ö2sµ G#MUø±H‘Ð=ÀáÒîÊg:   ïhn¼ÑÕôc‰R0Ô%[(Äuýôã­&œ‘Nm KJY®Ž£êëÕÒ˜ º£—/tÕ—Cš¥3}(%Ût“¬“rFy…È¥îO©&ý™Ÿ6‰I²û¬ØÕ[”1´øL±O“ë“”­eyŸaä…Ó1£gülmCÂ9ÂtôX«l“>= ƒBBÐ'@^BÐ_³@¡X Îî÷‡Ÿy¦ZQ°0Û1E¹VçE !)ªŠù_å(çF¤QÇøÄ–^(ÏþoËåY©Ý%O¬-=nVQ2I{$¥Æö°ú“â¤kêáj:5}gü,/<¨©•<ÈõœžæÛ»i½ØF>ÆŒ •Í tÝ•µu„B[wä›g[éVžŠq±=-Šw\»ÌV”©?mÙãhp’å…#­k’z æÃÁÔõ’‹ŸM 5¨¨¨0ÿÕ4X^ä=zh®½%þ|‹:v’=fj'‰$@$@$ ð‹H¥°u ;ø‹ôf÷üsÎ.†Ç*—K°æ?ùΓºxÅ[ï>?C42~÷{d¨Kÿ}{ò‚x!0ª¯ÿcÙÂ;ÈòŽVUü~[¶DÏ07 n÷iüzåT­ÌÚí+ð]–¥sµ º€©º &Euo1Ó‰w,¯RX.›Šwkv’G ÒúwÎúA–œ ‘ x“€;ãúÁ_‡çB±€PËØEöÚJ?ÊsÝÑO+EL`)-R΢’” ÊÚÕfÎÆQÝ“_8úÅ+ň~ã÷Ö[EÔ—æ`y%kUzöQ;›beœ¯å‰Å–uÈ]û2-ÛkÊÿl£6œš‘¦õ±lÓµxÞ C¢qÑÈt Ö¬þÒÒ0*u ¢Ò \|©t= !~ò~ç1i£©\ýü¿ßÛ©^#¶ØP'wÅĸ8Ö. pëTÜq ®¥'¤{£raÜ„xÌÔU%™ŽH€Hà$ &MHÃFu½v1/ðâÔ¾sˆu °a•9Ù¦7ñ ²ð»_\ˆ1›´¦º ßçì†ÿ—#ÕÅþ«§ï¾Ò]«°¶°®Ÿ†¾a?`+ v#G1 E‰Wf˜úá‚IS°*WZÿý4V?¾a^‹$£ô»¤ù›Vb…´i°tˆÙ¡#cœL‹•SXÿßš>èÌ+ú[ä²sV,¡ï§`æUbï+ŸÕdý„£EÈݶټÔ_Æ=a²XŽÛSfÖÊ·|–óÖ³8=u¦‚0ñ[ÅTºK^ܬd4ââ4Ë}ä¬Ôr)LÑVšLUø!¾Ï/DÉárT×™DQAè?l.;JÜgêïOGÔ wÓ°e×~eBX/ÉÄır_ßQŽ–ã<•éi¾æ4òLfÍ‘Ýøhí:)±KüDÆ•“'")ºós4Gׯñ>o®õxŸ7GÇ—®y4Þ(UPì•Xc¾Ú~¨9i™áZ]U…z1[EÚÑ 0È`îCIÉýŒº± ±Tïã/4`îã‘!=ãš`ª­@Ѿƒè68 ºwˆgúÕ£üÈIEEiF4”ãӥϋśåÃ0(ZLÒ• J”CqÕ­1±OÏù£’±¾(Oy«yAœ†þ!M8ô¿ÍXö/U;M#s °ï$c£Ø™Jx:‰ Cï„ûcú¸xÔ?€OW¯@N‘9™óÿšJ‘£ŽCò‘< Z:Úasš44ªª›Ð$õÝ C"®H…è‡Ë\Vô ǵcÌIê+ò±b‘Ú¯LGjœõ»´úH!*#ÑWŒÁ«"Må{°ìñš1jÆÕZÆ%%[QžZGwú¿ŽÊ»r°ÎÒ¥ ퟭ2,uE.‡ÿû¦<8jÄÀ½Ò<³ÇÆ™xêѤ³!ia÷z¡“ÌX@î¿Þæ õ§¶â‰;¿BÖ‚‡0\s¦ƒ³x?ÿB¦lXÒ6äVJ:}.Fû<²Íƒ]°jáS‡ä”¡ã1F2,‰1bœé¥”àôÃ3§‰yH€H Ópô>0¦ŒÜîF©äÍ3àJœ¡Ÿ·j©’þ Å:’%ý8¿{æ¼´Bþa]²ižú##þ— KÒÂtž¼ûêN–âàö,Þ.ŒÄïHQ·ZŨ$ÕyüÆdàÖIûðƆâJÞzüa)‰Í‹Y7޳›ªg¢®§®et¡O£¥u:ý~d5¼ŠUÛåþCÙWâ%ñçôДñŒ™$×Q›:-O\È[·Lü ¾QÁ¨=vZKš:ó·HÒýnn®¤eb ý4cé}‹Ì}tÛBËľÁ9›Ö ã¶19ÅÁÀUÃa¬yô%¥ßjÉ]&úÑÙ_dà?N[‚É<•éi>‹Úö!e–æ¬Â Ëm•ã­Ülç,íKgŒ7 ð>wN“÷¹s6>xÅ“ñF©š¦âÏð¸6!ÄRñì·ÄØ„rªŸ+E 1žÅVi´h+?² †áÔimâpƼ¡Â°¢H<ÒÏto?³Ä<þ?Hì¿#úb<Ôr$ãÆéišAA÷tÕõ1 zÔ$¤ çù‰Ÿ‡eÏH梿¾˜xC:ò”÷DÞÑÚÐBÝ妲CšG8¢Ò«ëcé’YÛ™¡uáŽÏ´®ªvÙÃgÞŽos_3ÝrW½†ÜÏ!9Ú$Ú[§“’fÞ3Ùf ˜ìxõ5l6÷íƒ+&Œ…á8òöÉ}f)OÆí p‘ÝD6OË“$ZWû¿’Ͷ~W>r¿EÐ9rü«ò¨¸³*vë. ‹ãT9æêŒJ¡ƒpÕ¼1{ŒefžœPþß“|¡ÂcA9jÅgÒC´L9Ož4ÎÏ„–š…Ÿ$à=ÊZ¦ÖìäûÛ.¨–„9 ïEæˆX»´@,2o»wMM±ë H•ÌT±·€rH ­”i{—ùA5Ì8sÑ–²uó·7ð©ú‹Í“ü!»,Åe`þMJIêG0Ò³nÇ£ž%´T±n´ó‚t8ÓÁY¼XËUe(rwën£›Ø¤{ÚÓcÆ„Afé¶ÿÅ3Z È1u®—¾,W™éó0L$@$à[ÔwhH7åÝ.©/fïÍùËóxìiñwóã‰ê¡$ÞúÃù»%fd¾oJ†*»#½Cue«ïGõm—^Dxðî í—„H]ùšQ)*Y|Ìî‡fâÄ9˜[¦¶‡^Ø™¸{á0Ô®ãí‡Ðp¥¿¢í'¤Ï)À8ïÓX§µ? Áð¬ñÀ¼iNX*9¢a¼˜Ì3V¿Ö‡Ìœ÷oì5“bFÏœ‰ñCäú[ŒJÁ/úw3GZÿ&j¶äXÄ~¤Iê˜ái”ì˳•B“1Sä™l³ï’–ߣò,“¯ÒÝèÿšË´-OSäÜœ·té?åçcîÜ'Í5î+{ ´¦ú¥UbýÈ’J«’¿QáAæ=˜Úc)¼²²ãfÕ##{{Vá*Z]}••u8ÓØ(œ=ýÑQÆp»Áq«<Í×P‡ á†zê”TÞQ^0¢bú"ÂKKƒµš‡U%yBÎ Ô×V‰%6~nÔM8Ý€žâ;£Vr˜±¦¢ ~¢·Ð$ƼÂäel&ôF¤Xv®\z& ãXHX‚ÔžX&¤¼²~Á±Y`÷æ¿ç^ÐCZ®¡¢FppšÄ.”ƒÅõÜV¼'LmexãœÏoPl{ݤugÿ¿½3³*÷ÿ¯™Ìd²ïÍž.iºÒ…RJ)‹€ „ÿÅTõ¢ ¸ü¹ ×«pïGqÁ…¿ ‚àGäŠl jU,ÐRSH÷5tÏÖ6û>“Lúž÷w23™$“É$™¦¿Ów;Ës¾çÉ9ç9ÏsHà!àr÷õŸ"¢RÌa xÐ&û zŒ¿åý²ßq²ì³:Ò_ÿa3÷Ò£ëO¸Å]\§,N±Ùúe÷D;rüVІ.Iúú mð8ìðtuÑ‘…´1ʬåD£OÓÑPº† ) 2¶ð$ÈÒé"_òðLGË,4ïÝÞƒxøö K—5_½ï-÷9m è0ÖÞØ‘éׇ6#>oÃ÷Ï:Pµ£y Êáç­ÈéÈ?ÆOo® /ûÈàs~ 'Ûö¼„{”ÕéÊÄ›Àç¼ÞôºjíÃ^«?àÒÛïÁ峂fÔ4Rˆiž‘¦ !‚ïVdy¶âO߸ëŒUÓ qëýÿŽYNo–Uxø¿1-ÃòÖàž»Þ¤¸÷Í“ ð=7¿«ãÿã{á+•dÿçRD¤óc•Î#ó•Í:]#ý,;SRàômãá—y„ò¹en¤©©Ý.ú\2ûš”ì‚\Ãý®_îƒOÇ8:š9íßu€x©ZæÈs\†°ÆÜ“îôGbÚˆý¸Á ÿÎd1 _Bÿ˜4×AC§ É ¸ÄëOQaæ°ó†ê~±¥µÝ.¸<$¤å¡TÒXÓyþ¹>]ynÙ„]¨vY±®ù¾ÿk–×g7U‹é¢Kˆ¥p¢¾Ögö¬ÙQ+pab”²¶öT²²ËJO§Ê|—øMËÌ—%}˜ÇHÓ‰oöLññž A˜%3 ÄGr:r¼K3¬•'# –2‘/¾]6ï±?œ"wþH’Fï¹M˳£#d Ó²äc  ˆ"›ô™£Û‰íß>‡Sö óïªYqéëçxeN¿+Q ÑèÓ¤H‡¤<‚NÉh™…[å>™(RW…)i9á­œ 7cÆ›)(?£ö:v6_Œ³Y>jD†ñ!À÷\–UDå;Ç÷||ÞШåé|ãX‹'¯1D(ŸCæFò #è‹qu4s2Ú¿ ¶¥‘ÇPsO#&}„Éb8zI5… ™…³0šévgr&òåY]yŸ $³´Ñ÷Íò,Eqd2Ÿz©ÆeusŠ3eÓe£àâ ã£çzH€H€H€H€H€H€H`rxZJ¥A¥÷Ö£r«y7ù¼3»´åb‘×Oç¦8¢t{CÏ‘u¸ï[ßÅ÷¾õm¼vPWi{C¤yFšNж,õ{¶{+“„sOnå”Íó>ï›o×xÏy˜l|ÏEï9Šï1ßóÉ~cY> œšÆE±äWSYÉ P×wúÑs½Ç@$@$@$@$@$@$£ÄÝ‹¹7ÐÛ£2R¬18²y³/}Ùœ\ß¹ø|ñµ}fz(7ðäϘã/î¥Õ7RˆðÞDšg¤é‚ä»,´7Š{J#d!+x/¹ïÈ.A™7ú†€b=çqÂð=Âÿó=Ÿ°“‘ À#@3¢)Ö ¬ ÀéI`Â÷¬ñ¹šœ™ÙH±M;åÁ÷´5Ë>"2)dKFNfnNùO\,—ï9q¢²$8½ 8Kñ¹»ÿ úSèLÞ~úôF3jï®ÿzÑܳXˆ%%~zZªqÂ[Éùþ §€Š›{(‹]ºÔ‹ž× ¥³`nº).¹Q…·sdï2ñ;=”JZI§l°¨õ¡R)t“ó. Àé@ÀÜ7Ëøm·Ÿú N‡ ·Žžæøù·ŸóFO‡ïü8Jý%6¿5§~§þù;d¿-34àà1?—wÎÌ_¶ K—ÍÜK4Ò<#M§ÂEU–DÌXRlV91^¶a?ižûÿkw Û{}b÷!øQñÅó "À÷ÜïËëwêð÷˜ï¹?ž“ „O`Ú£~­Ïž#¸õÖ{T[ÛSÃO͘$@$@$@$@$@$@$@$@$@$@$@$@1G`ij»!ÓìY³£*-–¢Š“™‘ ÀÔ%0È8våìÌ©[[ÖŒH€H€H€H€H€H€H€H€H€H€H€N®¦ÅR´«J‹¥he~$@$@$@$@$@$@$@$@$@$@$@$0E P±4E–Õ"           h b)ÚD™ LQƒöXš¢õdµH€H€H€H€H`J8¼½bJÖ+¸R3¯ ¾Åk      I @‹¥I€Î"I€H€H€H€H šÚÛÇgCÖhÊi^S¹n‘2a:     ˜L´XšLú,›H€H€H€H`ÔzÚ[Ò8S3®O·‹iÓ¦!-- yyyˆ‹‹ƒ^O…pòäIô÷÷O™úŒÔ&|¯G"Äç$@$@$@$@$@±B€Š¥Xi ÊA$@$@$@$@c `·Ûa³Ù EÌTP.©RÉãñŒ“’ Œ*–ƃ*ó$    &àp8o(—ÔréT½½½èëë;Õ«Aùc€ZÃyäÝêêêDkK NGsS#:;:ÐÛë6š…!j0© n»Ýä”dfe#'w:Ò32”” ›üFMÅwh˜„H€H€H€¦*–¦Ts²2$@$@$@$@§+U*YÊ¥© Xâäóéú&½U©ÔÞÞ†ºšÔVFnFV-[„¢Â$9Ç_€Ó „®žnÔÔÖ¡jÿAìݵ…Å3PPT„ÔÔ4Ä‹u% À©M€Š¥S»ý(= ÀiN@JÔž*– S†ˆZ–Xõ›2•bE&•€ºXTK¥Úêjœ¨;Š•ËÎÀ‚òòI•i*® ºòÙ³Ïîª*TnÛ ý>—̘Q.Må÷Tl7Ö‰H€H€H€Â%@ÅÒ0¤Ôûv~»\½hlëĬ?7-I \a5 6>"   ˜@Sݲgª×o_%úÄÅbKs3êÄRi噋©Tš€·ÂRÜUlÞŽÔ´48EéäH˜: ð @È"H€H€H€H æP±4L“¨R©ÏÓºæN¼µ§qâ0ú‚EŘ‘KÅÒ0ØøˆH€H€H€H€N)ÕñÔë±»µ_ö‰CFb:®ºt)–eq¸tJ5dºÜ.œ8~ 9™iT*…Á+ZQT¹tàÐaƒ}fv6KÑË|H€H€H€H`’ŒëHI3ž~Óâ§©£Ýîá7ßMtÄ#+ÅiXÙâ¦MÚ¦ž–¥RGw/޵tâHC;:]}HuR¡4Iï)‹%   Èx:ñö¶tÁæ—ÞƒÞ>Ò³Ó0«8Ù¿G§àéT·èïúÕn~ ŸX[?ÐòÍzÚŠÜe GT,ÕeTc?ì¡FU}س pîìÔ¼y6é\==hl8óÎZ2鲜JôŸì7Ä›±Øå³gaý;Û m {-1 œºB ¢VU*©2é¨(f6½[êÆŽaó.ÎNÁÙsòQš›U2ÅÛÄ÷Ü$ËRI•JëÅRIë°¨$3¦§®ð&A$I$@$@$@$ w3~¶v'Ž“võâ%øÊÕeH&MU-ø­¥Tr¤â¶+a¶¨!·í¨ÃôÔ‘•¹ñòó[ð„{6Žv<ÿ•³øn ƒh¢¹].tv´£¸¨p¢‹>¥Ëûå/iÈÿÙÏ|6âz(óÎuë¡mÀ@$@$@$@F@¾õÆN<¿¿IŠŒ‡3ÑŽ9¥e¸áüb¹bˆ”À¸²Ó½‰T©´»º »Ž6A­–2’॑èÅMK§ m]n¤8Í%£%9©HKš¿Ë*·º¿Û]Ó„=òQx³òÒ½–Ÿèõ‰žä°#;Í´°Ò•”“£ó‰Ã    `6råž©X²aõLQuwcñn_Ì Û·á‰IxðÒß=žœ&ä]8è­êòUËqõÂ,ãjѲ°¤$K4¯b)Óáo§÷=@aœaåÄHEÀãñÀår#ÑéÄIùadï¼S‰'Ÿ|Òˆxæ™ËqÖYËGN"†2WöÚ $@$@§î¼µã¸,ÙògÎÆ¢ÜÀùà`uÕØX-±é8qzäúm¹¶;3±zqî)£pÉ–CGŽ£rïaTöãÞëæbrf¸ƒ \^Æn¼þÊ<³« F66¬X²Ÿ¾¨Ú:DšnèGýÄÓ‚Ÿýø5¼´lCm þMK£^\¨JªJõˆ¡ïõLy¯‡vqx×n<÷Öaìè4û>ÉéY¸þ¢%¸pFhj}ÝØ±ç*ªPÕØ½šÎ†3f•àÚ  ,=rËñQs #Áðßè02.Š*’ÔRI•JÍ^¥ÒY³óP¯®©ï8fÄ©¨ªGGÉâvn²Km=ÆžJ»D!ÖÔ®“ÓðúÎjqш«T”_çÎ/”=—Òĺ*nÒ\÷ ×|F$@$@$@$`˜¿òÜsižyáéÆÛ¯½…¯U´×{vÕ£SK½ÔSƒÜ¨\Åyzp¢¶ Û+ÖãÅ?TbÍ}?Áš’ØV}Œª~4™©J–—¤DÚLR²|_CÅdÄ'0a?úzÍÅ‚ê©â¤×Å[TDè“ý›jßÅŽMðâåûu︼4ôTRÇþõxàþ⵪6)ºWÜúøâÏEd(eW'Þüõøá¯Áˆ½ä |á«_Ä9…¡óŽJ]¼™47·à;ß¹‰‰‰Æ=ä‘G™™1ªb¦‰ =ý.+{m  ©O ¯ã8îzy§YÑ<þvÓ‚a”C}xã/›pÿ1žgE±T¿u+î«m€£Ï‹biÔ € E܇·_ÙˆŸm9£þ Œ”Lôˆãÿ;œÊF(£û~ö“7)fŽnx/l«Çÿ~a% ƒÖWÒDš.œªŒ"NmåVŸìóÌŭ˳ÐXW‹Š-{ûÅâ®Ýf#g.NÂï®.!M7^úíËxàPÐbšŽz|ëÉz\rá*Üy~ÐØÁ} _ÿñT†Èíèö}X+Ÿë¯¾7/],DvQ»¨)‰Z¶fFêBNÝßY–Jeù(/Ì@Q– Ú¤Siȩ́ˆ©¥Ë…ýõ-F\M3Ò~LÑU»ì:˜P %U&©ÉQnšÙa'Ýwéȉv#jAf²ÏÚ*œ´ŒC$@$@$@$0Áúü&3m‰XqéÙ¸vË+æ@££Õ2>˜ç]pÖÙÚŽêcÍ8ÖÚƒ.Y]oOÎÀ²yÃîÇt¼ºÛ«ÛÑ+«Ê’ÒÒqÖÂ<$»»QÛ*nŸl (Ì ÝÏl¬«Ã–Ã-’NBB2–/*ÁtGø¶ðá*^öÿþë˜óáï@Ÿ}û÷¦œbÉÕÚ„íÐà2réY9X27wÒ°³£‡vìÃ/‘šãÍhÌH‚T ;+ ¡Èô.NE…ä€ô§ß™Žûûúr9æ°ÿù;1ÿúïä3ë¶ûð¾’ÁSIÍ›é+?wݺßâ7ÿù<ÞúöÕA“ÍøõÓñ™§ü¢¯[‡ßþô7xfÏ[ø@Ùø)†Ut÷Ýw£«« iiæžHmmmƽüàˆ‹ oÕ¬ýU§œ•= ÀéA >w&nÍÛ‰‡TYtì¶t,ÀŠ¡ÖñtÔâiC©¬¾p²%Iý)…©;ƒ•J^ùÇuò}TŒ"‘±Oýr@©tÉêeøô’L¼[Y‰o齎|âñxñ¦EA}íHÓªBaEnoµ¼åâÎk¡PSÍ(À…a¥ŒÔ¸«_S¥’Žåg=`xû¥W}J¥’9eøú¥ˆo®Áþ°{$髯o”aߥøÊ™~{±zzqÂ(Ά+–ÏÄEsóëèǶM;ñÀnSÿðÌKë±|ÖUCÅ÷« y·ÕýZ*©R© 3E¬‘â^ά›lÃdÜ;{!®ïÔri¢‚vjû<ý†Û»·d/%uywÁ¢býZ"e¤8±Á{ÿB¹?#ׯ±EÈ­ÝØy´5íxLXnü&J~–C$@$@$@$0 (P€ €8s¥§ ?{p^µ5èK6Üú‘ËðÁÙA "q¯ðÔo^Çc5Õ†T¯¤b¹¸Â0VéJËà½v<íøý3¯á¡à•lk·ã¶.ÁÕ3‚Ê12üO¸Š¥®†]Fâ>{ž|Ôtk58·Ø»ný Ž9^zö <ðÃÚ$⫹kf[* 7~÷ð_öGZûò¬}ÙLqýGÖàæàvÈlðY|xìƒòÎDÐ1 ¥Üè÷˜JŽh¸ÄëzÓGeÆÔÅÌ ëœžø¿^¥ÒGöûìJôù;n(¿úþp÷‡pïûV°î}â6¯Ré&¼Zýœ—Û‡¿û\}÷Ÿpýü»Q庥ãQÝßíÙ³ééép8L­{JJŠqOŸÝpà a•l9“=”ýù‡•˜‘H€H€Na\°2½¤*"7þ¸£ +VY¶âÕ:¼ã ×uµW.6ãÌ»ä2<{®(lö·VÒº$`ÅùeÈKËù³’ð‡G_Á¡ÆÕžà«ÑËØ¸k;k6Å\¾z5î¼ÈôþPxé%øaß+¸£RÇöáwÊñÉÙÞz=ÒtÑÒƒ5ê´NBfš¡°4/"ø·£ÿó‡3¡1~"¦ýøîv3BÉ‚exüÚYfÄ‚ <8+ _ýñFc|¸víÜx湘ne“˜Û®>% E7᧯šQ\€¹™¯àÖ ª\rãQ`®8_½O~˜ŒîïÔRI•J ¢Í³7™VðªhJx½pVOˆHyk/%µ:Rë£T±œÒ”`7ÜÛ©‚¦öÃz*Iê ÷Õ¢Ifh”/J7D¯„.·¥ýô>âH€H€H€"  ‹^\âKY§;ãe.^:M6Y‘3Ôäº.þî—•àý²Z§O>ùèÄ.˜Ñ>—ºë\®®²KYº‚Ý2L×rƒãM”|aÕ¹õ(žò” n*òu,ÔÝ…·½ƒÀÌÌT¬*Nƒ«º¯6«Òȃ‡ž~+¾v>fø:ûøõƒ¯ù qíât«> Í^¥’ “ìU\é¹dß/^ñ ÔJŠrqqšOìV×|n<ðä«(ørtW£-þÌ“hú¸Sö<®ì’IáSG·äe6Ü¡¿ÿùßñÕžvX.®¦xá*šºqÿÓDZ½Ÿœk*—ò ¥Áù m(I±á¨´Að~IÃ-ÏŽÕTã­].êcNqƤ¹;Ññ͉¶n±º+;Qvéo@²Œ]¤>úý´yaúû¢¿=¯­Ûeü~„Š7Bµ#~®œÁèï£îÏ«c7uŸ®¿oã³àC_ëo“U*YŠ&óNdÿ.úÔã¨ûˆ²ŽkºžÂ'U·$…ç]·î)j§÷ÿ?úÌÙ°I[Éeøé‹ÿ?]sî¿ÿ%Ü~Ùg‘iˆqO|ö·ÆÙ_¿«sl’Ÿ —}ã§øïçÿ„{vÜ+oÇÎ4cG&ùЩ>ö±áã7|Ó¬U¡Þ¨'åïŒþÝ ®Û9ÉU.ẎŒÇ$@$@SŽÀôy³±\KºÐjCÅA4Šb){P-»ñÏŠ&ónÞL,·|Þ‰×üí×>øPaDËŸ÷;¦ËÜtÀ¬³¸Æ®mÏ’Ó3> 1Vé+…zfDø'‹V-Á"ãž)ÖÔq@œÉ¾­Œ}Ø´©Æ+t¾èU*YµXvÙR¬®|Ó°þiãQÜ0»ÌË7ÒtVÎ#ûpøp-Þ=Þ s "'ÊËŠP–Ô€7[ñ޵ø¯³ ‡d;žL± Bb ¦§¼ #*c·ÿÝdX­õ0‡$Ür‰W©d%J,À/É¿¿ªï{=þqØÎ°äNIJšÜê‰WÕ‹0ÃF£ü®Ž>+·I?Ž†àØ…•Yí“êxÆ&>–×oÜ ˜{Iaå`í¥¤“E%Ù˜1=͘èÄRòdÔ}žX.ih7,“Žœh3,šfäÆä¯CXfËܘ1IDATuf$   Ø& J%î•Tj¢Ã˜N”.ªd tr¯W\¼õôš“­:éª×º°G'\ÇK±\®*²Ò“pÚUNU„™ÒÇ›(ùB±Bü@××ÕZ‡G½ÍÛéJfe›îéøÈêù(_QŽ2ß`£«~ûÜgXu Yt–1ÑñÍ›”J2~ê¦3}«ÎjwmÃ7þ°ß\}´©qûŸRéŠKÎÇWV™«Î>rönÜðÄ‘Ë_½Y‡aìÛ3”Òq[ Ä{3NNë€[¼"!œúž>¥RQžýäߤÅ'ìÄMOï3Úú‰ßm–Iùóņk>v.8¼×Å’Ìð«’¦Qö“U ½}žñ¢#Õà\•38¥þ~Ô5wâ°ŒËöÕµ MªÇ‰HÆgÁÊ‘°•$ÁBY×qÂ8IýýèÑ$ô ç@‹¥løÃŒgÿþÑ‹‘®MÆ•¸RYu®Â=øóëàÍšO⪂xôxfì/àòeé~yåáŠOJì¯þ¿ú]>»ô²À‰2ožc=X®î”U¨X·P1Ô¾i¥¤Ç¸~ï@証K$@$0 8òðTªû°Ž#ØP·WËß8ÿÐwBRxv]»²Ô·@gïºWñek¥-ÿ÷oX‡›7è"#îýò58×Ï_ã®wð‰—N¢ Þ/³ ˆƒWåéêË.Æ=gÇξ6þìÆõÜ݈xõJ™sŠeGÈ `ËÄyrsƒÄi>t{ÝeX¤:’HÓeê²Qúõÿ#ýzu'^Þ‚ù æãîkøÆ‡·ãº§­þ¹Ä–=Ÿn}øïf²PÞ$2 ¼ØùÊzߨí¶.†ýŸ¯á~KçÕG¼JRÏ ˜EeÈÅ’*ŸÞÜÝ(Š¥Kõ ¬|—}­-ƒëì{:y'ãÒ³Ót¯ TtRcˆ>èäÕØ¯dµ2R¥‘¨rÓÁ”Z#é<ˆNޤ$Šå’(›JÅ^rBàž_6<%   ¨ðÈDc§Xtt÷V:ù«}++è©ÆÑ‰`Ý“²S,¾ÛºÝhír£­Ó…69ê¹æ¡ñ¢¬rÝR®Z™k9úéìé3&¨­rtõ¿N6N´|VùÃ÷lÙŽ§þ¹?øõ_qåƒýÜÝeá[W–šIm©XsÑ?¥’ÞŽÇù«J|YÛ¥Žfpãæ`Tmïú¥’>/\¸__Êÿ|Óë5ÞQ„O{•Jš&¡x>ïµíÙW µ_)è„m8Ê—‘ò‰Õç#×OÚÁâ)–Jßûà€RIë”>{¾½Òri}ëde`è0ôjØÐñã1sn–eá’¢T ¼!n¼ðú&\óóÍh pÜîª%Ð!Qºì©nÄnù쥑÷Ö4ãà±VY•ÛVùPK%µr´‚þ^¨²fwuvm2âê>¹ª°ŽæïˆU^Ør•ß+¿-íb©tLgd^­«æiPeÒx||ò Ê_¼]x=¿/˜™Xvò \~•¦ÜCõíÆ³ÞÖ3« æ!×(kÙꋌg;*ö¡}P9q#­£G8ôöõ†üè³ÑækV†ÿ’ œn–Ÿ=ÐKúýÛµƒª¿wëï½T\<Ïê³I<>Á¼?„å¿åNZ-ÿo\`™9™–ÿ–‚ófxóö`}•ÿʪ~lÙn)€£ëÅ©ò@p®6”JÚÇ¿rîi¨TR]Þ=dLZRˆE,ñ˜%}`3ˆ×ÅpÄé¼9 uh=°YEJ¥’¢|ܸ<ó½ öìÞƒëüúßñ§_ÿÜŒ”)®}3EùUR˜´§åP¥Š³íÃÛðå óÝ™¿r•¸+OA§×»ÞЩôI¢ìÏ;Ðß¶âÆ‹‹áYÖE˜Ç½[´XKgÇÎû8.ÚuqÒ%V@]2Ù0‘¯Ž_Œ9±TÒ çÆ˜FžÅZÐA¬®ò-¥º‡’jœtå/ L`  nés¹DÙ£ŠUBÉÿ2Ùgö³¢)£U®N@·ÈÄ´*µTá•h×ONÙkÒn¸ÚR‹.0²,¨&J¾°êênÅcU5%3gâ[מéçÚÎÊI¬9šZPßÐ6—­21?8t¡Î¦¢Üoä@ÜPÝm×@:w xéôx•v ÊÒUÙƒÝç äÊ3.4úÚ! B´Cq¹8]ñ—%±3Bû÷÷Ïuäó8œ»æ=8×±µÞÅϟ߉ ª»j>„ï¾’û/y¢/‹(èwÐR 5È"ºô¤äÈ8F]“ÏÈMÃt1­I“ým³SÅ寬\C‘ôöþc†ÂF]æi¼%3sŒ¸þ–NQÏ—ÍHr[ZùFá¤Ï#Ö½¢€Vª Q§xÑ .ôz‚{Ý¢œëéȶgÖþY/"'¥/ð™üx‡È°ÒíÛXa¤]¸PÞ_ÉÇ/'¸,ë9z‚ž  g¦âÛ&ï•Ý.?p $@$@§„âY¸Ö±/Hÿèèöw±_t•ùÜJ·`m…¹?fæœY¦ÅK0¡ 5$£±ü/(Àbë±Vò\»û8n;3ÕTˆõÊ? oÞš¡JÄXæöݽͫË,ÄKg,׿îliòî{¬R™a¹e÷Ên™8~‘¦g;þ÷ùCÞ(6|æCïÅG½î­?¹FöYýí?ð€¶§ô¿µy¾r¦¸¦.^„Ç¿Qާ~þgÓÚ(e&~ýå3GçQÀ} ß}r¿YnæLÜgôë‡Z¤fFË/•qF¥*‚ºñÚ»]X´8Ù+·yhÜ{À܃7àîЮºÝ>Å–,™Ã{JbG71h¤ ºN!Ÿœ<9͘`hír¡¦±‡Žµ«Xµ“®×j ¤Juë":#h¾]VÙªK£î Ô¸*œÆ"KHƒnjÖðÁ¿£Ÿ¤Šío©Ëá>é{éd´º¬>U–¦×¼ÆÚŸ²Üh¹æ„ éî8AöpJON”~›,¥R‡,Ò~ÜDȧu Ãõ_…5°+?k>sÉô€¤Á|ŽV¼[×Yn1xÿ9³pn™¤©Ùƒ;×™¦D[âË»¥µªlóõrÍb,£m ·Èbv¾UYd…D|þ}s$m:($¤cšäé ÊsP¼ÓäFp[ùªíß]¡ÛÝ=ðºîG‡÷»¡éõûeC‰¢¬çaeSÞ ÄCÅÞIÑÑ€ƒÝ'Q®þæG£z¯‡ÈË|âŰ e‘*u]ª×Zi–¸ý^4#©ò]>g^‘¡hZ¿»'Z;±íÐ c#µ`š9=«ã"ÿ|#=TNG¼ÍømT… þæéGóòÝ! Æ×¶žœÓ î9q9øC,,\Á,“ÝëhíÆÝèùÔB¿ß Ý)ÂÒ¬“Sã¨ìGÛf§FÍ(% ÀpŠÌDѺxvÃ!\7wÑo®¬8êM–‹ f8þ¦»­N|@?ºÕV§®·?z)Å–ÚG:Úû{³‹C¿ô½]r9cAð®Z 5acM/òŠâ±më1#bù¼ÙX|ìž—~Ûú½Çñ‰²R¸jjðWã© ï™› “q{Ĥ¯au5d1¡/BÝÖJ<¶£鉾¿ø¾gÖ‰Kô9«/_‰órMï[Q†9Ž,£þ½¶Â4Q2…êoµµXï¤9Í8‘¦³Ê ulj(çüyYƒe±eá,éoÖþ·¯Ô¹O¢Ä@XOëUFð½£ðC}a%Üø¡‹°Xth&Ù7Ò‹¦_ÆÁƒ¸$–à«çíǗ׫"µßøÅ‹XY&JÎnQXÖš K#SùGÇòƒÒ{vÙƒ›ŸÙës®VZåÚ†Œoåê8ô[*vø÷½yþ«öÂÍF;ô:ÑÐ!–GÇZ:QUÛ„ýâóº^Ò =-¦i\ZbÚ»m5¡T’ÁNº¬†ËÅ“C6WŽD«¼pŽ2㛄Ñs«<ë¾®æ;|¼Í¸Ÿ+î"’ÅÅ‹®˜ì‘ÕÁº/Ó‰ÖnÙ×iXb%ˆ+}8e3 „" ýwí‹Xí_èÇwßznô¿¼÷å\ûcþÁH/÷ÆÚ? (_Ë ’Å÷Ü’Ù?Žž{?Ñ”OóôÃÖQâú¢Ë¤ú°q= ø•¥TJ.ÄOo:%jÐ$ÁÕ¯þÃMÅ’Ug8Òp¦Ì Wi—÷D;šû§!W#û‚;X#_³- ½E|6–ÈÀg«|ìéX¹x62}i‚N´ýƒn_Z=Á÷§ÊµU¿!ÛοDÁ×%í<Èéjh2&2”ÉÒâ4ß{àŸ§¯]Ç N¾¾<<èT—óÁùžœŒê½Hp¦ßÏàïZ@¹0žë÷B>¾ß¿ï¯õ}1ŽÏ›Fóöçœïh®Ç$§d±2ê0J¹Œz•ÄQŠëœUWϭ礀vT,§pé*¹ñPÛ>èw ¥Ñü=_!7†Ì)²«gŸ}O<ñDÈÄ7Þx#®»îºÏ†»)s|Æß‘h½KÕÅg$@$@1D µïÏÝŠGôÏ׉èl_ˆ•Îãøã~³§[´d¦ëßt?‘õo†Œ~š^ôt`¯ß´rÅΣ0ÇZ1½ÇNYœ%ùéôRqYZTÉyÅž¼¿ ¯ï5«Îœƒ%bñ|e7jöCóšRÔì¨63I.ÆBDò7KŠöŸì¾;#Ÿ4ÖÔ¢¢ÖŸFè4)M½X•FG3Dò‘dôô¨#Š+iOñ`WÒm”‚²‡Á*Òt!Dôݪõ¹%·!_¬é·‰e¥¢ùcUæ4ŠF±Ð»’o¤zú ñ?é­Ã­q¡ÜÿÇú زÎl)›t'¡ê ÜyÄâùËq³XÏY¡tÕE¸?î_øê¦uRÅ~óYbtËeExë彨&‘»ä\1ÂÙ¹ Ÿÿ«×£Xdýç'/ÁjQ †Šk•9Üq %‡‹5úgƒÞJ¾”è—`Vðx´ß¨WI(Ζnz§2êñèÆã¸óÜ<3š»/þá üÒ;÷«›uíi<µ£0MÒµHºÞzüõÝ|¬\B÷Ô'°ð‹º¥Ô÷½*ø:k±©ñL\šPÊV¿¢ ÒÆþyíc6l@ÚQ_x:qÄ;ØDrŠýÞÁa2ó—E£_“Ô÷ÈH3ðÚúî«Õ‘z…È‘ïr©Œ]òÅ=¹Ž_tü¥.ðÔBIÇ7{kšÐ,ßk»¨4×°PÒsu™§.Â#‘É'„ßI¤rêïžÒô5“ÔUó\£ï'vاº::tH@ÙÜóÄGËz¼Qy·,Y8­¡ /îÒË+pV©hž%$g•ÊnLÀ®õ±¿çSXâ ÑgUßЮ¸ê,˜±Ë¨þó¡};wîÄîÝ»ò]°`ôY$Áâ?š6‹¤¦! ˆ5v¬:'üI'ØÝxeW+d1&×UÒ,Éô÷Ü÷÷Þ¿-ó²I¾ª%âs—‰å¿'„F,ÿÚGи‰Óq¡ü±¬’þÙ6ñ¨Õ°ÄŽy¤ã¬‚$öŠB ò¨ô˰¿½{v›«?V.+Aú€¾RG>ñ–kD4û)!ºgÃf3ó츳ÔtM``ù“{¨á‰P–n™`¨wvûÔRIÜßÕ‰"FƒNDdˆÑé° ™`WrVqêŸ?M⩋‹³S¡›P7´ù¿.fÉ:p©•}ŸTq¦~ÅõeÌÿãVHN°J%ËUžuŸG   ˆ6¸¸iHˆ‹‡]LŽxã W½v·˜ß‹¢©W:ÒY2¦>¼Íè£#MÌû“⌾™–/ƒ9Uau»{qR–é=í3i?Ï..'t_•q¢ä‹N-½¹ôvcŸep_w• ¹X”Ò»öà;¯Ê`ÓÝx§º‹çkŸ0ç_XŽýfñ¤bý[¸qg fЕӡ>·f:ÿã°zÍB¤ÿb»ç™?þ î ÏÁug IôM·Çëë±³ÁŽ‹— ¸¼òÏÂï+e1–ZU¼³¿N2ç‘\„åùaö5–ÿç,-Ã`;šàZ9°xžôÈþ%®ÉZªñô«Þç¥E²ß’üå.(ÄRÙg«ô×®Û ñ–'Á†‹çœspIѺNÊ)€ŸL´²]>ÎDÌ•qM•ð¨:|L-2V ÈA\'ïó*–ìYÈwê(Q4K‘¦ È;ð"o¦(ÿÞ9jÜ”Hc¾ß'K¡ÓÒÒð¹Ï}>ø3#?=×{nY\0¸5i1¶¾ÇÊ^Û ÚïÔà’y‡H€H æزqå<*Ô ]g+^ñ.èZ¹l²Cô—¬¿†Z¿÷ñ–ÿUݸ! sŽå¦b ÝxåˆIæªEf?MÆgËßï­2¨Ø« â{qfä¯|²ËŸéÙͬcåß‘eLÇ… ñç­bÁÕr›š—à¢L_*Ù‹ê^Ð¥Ëgaºq¦}²HÓ„üÇ™8 )zaóQÜX>WT~ý¿†£ø«÷}BF’8œ«&oNÖQ/õ<¼>ˆK–—{s>ˆçŽM¢X ¸òùspÑR³æ¦éà¸A×Íð˜× #rg㌔9uÜ+/¾mXˆ©bóËʺ #   !`ZÙÅ*IV½KŸÊZÀbÁ™6í$ÄhȈ§Ó‰vñ}m÷Z0iܱ`R%®ð×¼¢üËUÅ‘§ßT.©Kã.?+£³.›»ÚâOb"实Öʺ$ÙPvø`Ç5ןÆß¼‰d `…ôŒ||õƒKÑ·ñu|s§é£õ¨îy¢µ•a—Ÿƒ§Kkð—·£V,Äm^ÁÌb\º¼ï® ­œÒ¼ –®ÀÓâ*âÁ?mÁÞò|J%y^>;C,üLšh ¡«~^|ñÉÀ¶¿ˆG·Ë­k.ÅÃON¹«%—½nÅ}k rUQ^:_¼ff ÎlŽAj‚WÙvÅEyš#‘kô# Å¿wfé¼rÜzù"8¢×~áÈ¥ãuu§ßU"奉bI-”DÁ¤.ïTQ£A÷(òÈï„’ä·&T<ëy´áÊ\®º%ON—•RŸyéHu: y&Øâä7Óî@{G¦ûý©4•K‘·W÷ñÝX»öÙ@Qv­Å»äÖ⇾'N¬¹ïOønÄÍ<›oxÂûä:<·õ\´·sÖ5Øÿ†Ä¾àf<ñMùxcø›À_:×—ëxôÊb…3ÎX„5kÖÈ;ã1Î]>·7׬TRæÊ^Û€H€Hàô$°èìÀÞ*¿Ê;ð¾EÚ£ ÷oð4œÂòÿzÃò_¼7ȇ@Ë3_[~>.ÅŸU¹øÇù3tnWŸÛ±x®X4‹&oXzFñˆ‹»¬¸ÖÑÕÓYo‡øønÔYJ± oìq‹•¯.³#-erÿŽVÆçÌCúÖ-²l˃=]²›V¡Dû·õ¸ßð µOÄ‡Ï lÃHÓY,ƒº˜ïó¹Uø¹êýŽìÂw^sâö‹KÅ‚ê$\Í5øÉã»|Þ"n¼XÿgÕë>4Ä-|¨ÐTSÆ„ ÌÎIô)Àºã;o÷S¾|ùœ9]5»ñ˘I3m©EeK`þ:ÎÏ,”=Ã2u¤=ùaÚ£~­Ïž#¸õÖ{ i<%£–J}q¿TQ…}rÔ îΞS`(•¦‹»…éðë ÖÌÞõ§C­‘,Ë$ÿI­GµX2­ß]c¸Â;gn扛>u…—,{0 ÀxðÈ즺¶“.ŠávN•C†%wÏf«líËè$q¿¤S7xúQ7¾šF'‘£©\²ÊÔcp¹zO]áiÏZ™*^4äëíð›Á×rS2´¨¨†¶æcë¤xgrSÔ¥š†~45·Áå±!9-iŽ‘U-øÉýÿÄËš4y&ž¹uYû}`†®Öv¯¥’( H—2Ãvö{×Ȥ¨¨ ¢#ØCŒ8"L7dý[à®_Tx‡±|Ñ2ÜåL¿q”ÔùQi>ÊxìIù¿!²ã–”<“<Ë—žƒ½/¸OÓß>ð7ÊK-xÔÅ‚ ³RMŸÜ²:NWÛêÄF,sE­¬zE‘¿²Èè¨åUQv ô8·Ðô1®j   /¦ÅRøý °3-˜dâx¼„ ‘o¸å†/D“z+-3#Ä #Yr?0ôa÷ÖÃpÎ,Á¬tK¥1º±þ/ÿ2•Jrµr…®¨:$¥‹ëè¡ûDOå0úúÅ#+ÇÛNéã;ùžà”=‹ŠÆ·ŒÑ´­*XÂQ²Xã çèg¢C¸rË¥Š¤›ÃX¸¨VX‘‡(^3²²DÉqsËfùá–§Z.MTÈ,™- a†ÄLÌžvì03 /Z¿(Ý,ƒ>=ç;i)15®õQæÊ^Û€H€Hàt%ŒKWgáùuM€÷¯˜R©d<”9e#„ä,=ϨåÿK[ðº* $ ¶ü7ï[ÿÎ_œì7•Q./ è{Ûò p™½ /«2@Üà-•RÉ,Á¡]“aK²JøÃé¸]ºÆQ.‘Ù‘ „K –á–5b15S qRý¬©Æ±ð ¬ãšwÆÝbiä×!H2¹L’~¦J°$;ì(«+݇IWÇÅš+¿©Â›õ    ±°úncÉc,i-o-x=h•bÆô|óCg›RIå¶&pÇR‡XNkÕo²Ûy¢nõ(¾ ²ÇO¦XÍL/(FEåVÃÞ æß#U*éûFåÒØZÃ÷õZSîØ½ooÙ.ÌK öÚ|¿ÇƘ©I€H€$‹åìØÈ5ÕÎâ©XX>ØåÝHõŒ4Ýpù:S’Q˜bÆÈ.â$>KN‘÷R>S9 ²cÈ?Ýç/(’%çêŸ\;Çd3•¿ ¬ À©B ¸O|=¡õ°eá¶;®ÄÇN´¡¾¥mnôÊ&®½ñNÌ,ÍÃÜÜPn&TÂ)Sؤ¶óP ®_ðõˆpZ¡{¥È ¿¸TöW’ý‚6lÚ‚wÅEÛ‚¹å(*ÌGJrò”WÖNDCwtv¢¦¶»÷UÉ>d­È+*1˜+{m¾ßÑ ,ƒH€H€H€ÆÀ ÅÒøuêä©ÏïS§†””H€H€H€H jdÏ—éù9Æ'jy2# q!  }–23E4ÇXIz¬¾¯¼YN±:t÷º …Ó¸~šd'Š#‡X%%‹{ÐŒ¬lÌž·9Óóž‘a°·,šN¬& LIƒKìäMÉvf¥H€H€H€H`Êî¯_O™Š†Y‘©^«~Ö1L,§\´àú_ŸrŠaÕbÆ){üØâ㑘”„ìÜ\tuuÁír¡¯·ý'ûcXúØ-nZâív8$|“DÁ¤œí¢lŠ‹3½Ä~-(! L â”m\Â`ÅÒ¸ÃLI€H€H€H€H`|Ð¥Òøpµ\O·v>Ýê;‘ï›*í¦‰‚#Α nÏãŲ&ÙØkéd¿±¿÷X[k|-ÆÂÙgƒZ1Y÷Ç–;S“ Œ†ÀÄ)–8‚M»0. Àî®Êü%ƒµ¶P‹©¦z;¿ÆS½¾“ý~šaÓd¿Ÿ8Øå?     ð ²XÒ!èxi±Â‹1I€H€H€H€H 4Að¡£6wÍ rýbqáéóƒzù§­‹~¬ú·û©W£á%®_ðõð©ù”H€H€H€H€H€ è˜BF‡ã 9mq'á9Éa̸Ðf¦$@$@$@$@c'ÔU¥eÐÖÖ6v®1šƒÖ---ML1*`´Ä ªß”¯o´¸1     lÓN¢7䓱ßô)–tM]YåÛØsf$@$@$@$@$@ãN@-zÒÓÓǽœÉ*`*×m²˜²\     ©O@u=T÷íàS,Ùív¸\.LëëÁ´øäh—ÃüH€H€H€H€H *Ó2¢’ÏTÉÄ™7sªTå´®ßëÓºùYy    ˆ:ÕõhPÝO´ƒO±”””d(–z{ºàHMB/ÝáE›5ó#           q%`W7x¢ëÑ ºŸhŸb)55ÍÍÍèééAfJ/<Ó8‰ GßÑ.ù‘ D…À4ÑìØOö¢Ct=T÷íàS,ÅÛâÚÛÛÑÙÖŒ”ŒtŸä^KÑÎüH€H€H€H€H€H€H€H€H€H€H€H`<$Nó £µ8yÒÐù¨î'Ú! Ǭ¬LtuuÁ-{-¹ºÚ‘œwô7vŠv%˜ œÎqýpu¶:›ÍÕùŒGÐÙââ‘››k”ÓÙÞ†¾®68ã<ãQ.ó$           ˆÕå¨NGu;T×£:ŸñƒrMJLBvv6ÑÑÖ ‡X/¥¤eÀgGôPã!ó$           ƒ@<úaë—=•š[ÄRÉÜWIu<ªë¯0H±¤¥§¥Cͤ AšŽÁáH@¼|ìòA¼]bʼn¸º  Àx˜&™ÇZ™~ ¯½nºåã–œœ¤$§Œ§©XÒµ`§Ó‰ææf´·«O¾Ÿ¶k\%bæ$@$@$@$@$@$@$@$@$@$@$@$@aHMMEff&âmCª}ÂÎk¤ˆÃ– äæä<¹\n¸Ä-žõñx¸÷ÒHpùœH€H€H€H€H€H€H€H€H€H€H€¢I@=Î%$$ø}ã¶ŸR(¹‡U,Y tƒ§¤DýŒŸO>«,I€H€H€H€H€H€H€H€H€H€H€H€b“@\lŠE©H€H€H€H€H€H€H€H€H€H€H€H€bK±Ö"”‡H€H€H€H€H€H€H€H€H€H€H€b”K1Ú0‹H€H€H€H€H€H€H€H€H€H€H€bK±Ö"”‡H€H€H€H€H€H€H€H€H€H€H€b”K1Ú0‹H€H€H€H€H€H€H€H€H€H€H€bK±Ö"”‡H€H€H€H€H€H€H€H€H€H€H€b”K1Ú0‹H€H€H€H€H€H€H€H€H€H€H€bK±Ö"”‡H€H€H€H€H€H€H€H€H€H€H€b”K1Ú0‹H€H€H€H€H€H€H€H€H€H€H€bK±Ö"”‡H€H€H€H€H€H€H€H€H€H€H€b”K1Ú0‹H€H€H€H€H€H€H€H€H€H€H€bK±Ö"”‡H€H€H€H€H€H€H€H€H€H€H€b”K1Ú0‹H€H€H€H€H€H€H€H€H€H€H€bK±Ö"”‡H€H€H€H€H€H€H€H€H€H€H€b”K1Ú0‹H€H€H€H€H€H€H€H€H€H€H€bK±Ö"”‡H€H€H€H€H€H€H€H€H€H€H€b”K1Ú0‹H€H€H€H€H€H€H€H€H€H€H€bÀÿH¸”Çû"ÒIEND®B`‚Mail-DMARC-1.20260306/lib000755000765000024 015152630466 13632 5ustar00mattstaff000000000000Mail-DMARC-1.20260306/lib/Mail000755000765000024 015152630466 14514 5ustar00mattstaff000000000000Mail-DMARC-1.20260306/lib/Mail/DMARC.pm000444000765000024 4416215152630466 16064 0ustar00mattstaff000000000000package Mail::DMARC; use strict; use warnings; our $VERSION = '1.20260306'; use Carp; our $psl_loads = 0; use parent 'Mail::DMARC::Base'; require Mail::DMARC::Policy; require Mail::DMARC::Report; require Mail::DMARC::Result; require Mail::DMARC::Report::Aggregate::Record::Auth_Results::SPF; require Mail::DMARC::Report::Aggregate::Record::Auth_Results::DKIM; sub new { my ( $class, @args ) = @_; croak "invalid args" if scalar @args % 2; my %args = @args; my $self = bless { config_file => 'mail-dmarc.ini', }, $class; my @keys = sort { $a eq 'config_file' ? -1 : $b eq 'config_file' ? 1 : ($a cmp $b) } keys %args; foreach my $key ( @keys ) { if ($self->can($key)) { $self->$key( $args{$key} ); } else { $self->{$key} = $args{$key}; } } return $self; } sub source_ip { return $_[0]->{source_ip} if 1 == scalar @_; croak "invalid source_ip" if !$_[0]->is_valid_ip( $_[1] ); return $_[0]->{source_ip} = $_[1]; } sub envelope_to { return $_[0]->{envelope_to} if 1 == scalar @_; croak "invalid envelope_to" if !$_[0]->is_valid_domain( lc $_[1] ); return $_[0]->{envelope_to} = $_[1]; } sub envelope_from { return $_[0]->{envelope_from} if 1 == scalar @_; croak "invalid envelope_from" if !$_[0]->is_valid_domain( lc $_[1] ); return $_[0]->{envelope_from} = $_[1]; } sub header_from { return $_[0]->{header_from} if 1 == scalar @_; croak "invalid header_from" if !$_[0]->is_valid_domain( lc $_[1] ); return $_[0]->{header_from} = lc $_[1]; } sub header_from_raw { return $_[0]->{header_from_raw} if 1 == scalar @_; #croak "invalid header_from_raw: $_[1]" if 'from:' ne lc substr($_[1], 0, 5); return $_[0]->{header_from_raw} = lc $_[1]; } sub local_policy { return $_[0]->{local_policy} if 1 == scalar @_; # TODO: document this, when and why it would be used return $_[0]->{local_policy} = $_[1]; } sub dkim { my ($self, @args) = @_; if (0 == scalar @args) { $self->_unwrap('dkim'); return $self->{dkim}; } # one shot if (1 == scalar @args) { # warn "one argument\n"; if (ref $args[0] eq 'CODE') { return $self->{dkim} = $args[0]; } if ( ref $args[0] eq 'ARRAY') { foreach my $d ( @{ $args[0] }) { push @{ $self->{dkim}}, Mail::DMARC::Report::Aggregate::Record::Auth_Results::DKIM->new($d); } return $self->{dkim}; } if ( ref $args[0] eq 'Mail::DKIM::Verifier' ) { $self->_from_mail_dkim($args[0]); return $self->{dkim}; } }; #warn "iterative\n"; push @{ $self->{dkim}}, Mail::DMARC::Report::Aggregate::Record::Auth_Results::DKIM->new(@args); return $self->{dkim}; } sub _from_mail_dkim { my ( $self, $dkim ) = @_; my $signatures = 0; # A DKIM verifier will have result and signature methods. foreach my $s ( $dkim->signatures ) { next if ref $s eq 'Mail::DKIM::DkSignature'; $signatures++; my $result = $s->result; if ($result eq 'invalid') { # See GH Issue #21 $result = 'temperror'; } push @{ $self->{dkim}}, Mail::DMARC::Report::Aggregate::Record::Auth_Results::DKIM->new( domain => $s->domain, selector => $s->selector, result => $result, human_result => $s->result_detail, ); } if ($signatures < 1) { push @{ $self->{dkim}}, Mail::DMARC::Report::Aggregate::Record::Auth_Results::DKIM->new( domain => '', result => 'none', ); } return; } sub _unwrap { my ( $self, $key ) = @_; if ($self->{$key} and ref $self->{$key} eq 'CODE') { my $code = delete $self->{$key}; $self->$key( $self->$code ); } return; } sub spf { my ($self, @args) = @_; if (0 == scalar @args) { $self->_unwrap('spf'); return $self->{spf}; } if (1 == scalar @args && ref $args[0] eq 'CODE') { return $self->{spf} = $args[0]; } if (1 == scalar @args && ref $args[0] eq 'ARRAY') { # warn "SPF one shot"; foreach my $d ( @{ $args[0] }) { push @{ $self->{spf} }, Mail::DMARC::Report::Aggregate::Record::Auth_Results::SPF->new($d); } return $self->{spf}; } #warn "SPF iterative"; push @{ $self->{spf} }, Mail::DMARC::Report::Aggregate::Record::Auth_Results::SPF->new(@args); return $self->{spf}; } sub policy { my ( $self, @args ) = @_; return $self->{policy} if ref $self->{policy} && 0 == scalar @args; return $self->{policy} = Mail::DMARC::Policy->new(@args); } sub report { my $self = shift; return $self->{report} if ref $self->{report}; return $self->{report} = Mail::DMARC::Report->new(); } sub result { my $self = shift; return $self->{result} if ref $self->{result}; return $self->{result} = Mail::DMARC::Result->new(); } sub is_subdomain { return $_[0]->{is_subdomain} if 1 == scalar @_; croak "invalid boolean" if 0 == grep {/^$_[1]$/ix} qw/ 0 1/; return $_[0]->{is_subdomain} = $_[1]; } sub get_report_window { my ( $self, $interval, $now ) = @_; my $min_interval = $self->config->{'report_sending'}{'min_interval'}; my $max_interval = $self->config->{'report_sending'}{'max_interval'}; $interval = 86400 if ! $interval; # Default to 1 day if ( $min_interval ) { $interval = $min_interval if $interval < $min_interval; } if ( $max_interval ) { $interval = $max_interval if $interval > $max_interval; } if ( ( 86400 % $interval ) != 0 ) { # Interval does not fit into a day nicely, # So don't work out a window, just run with it. return ( $now, $now + $interval - 1); } my $begin = $self->get_start_of_zulu_day( $now ); my $end = $begin + $interval - 1; while ( $end < $now ) { $begin = $begin + $interval; $end = $begin + $interval - 1; } return ( $begin, $end ); } sub get_start_of_zulu_day { my ( $self, $t ) = @_; my $start_of_zulu_day = $t - ( $t % 86400 ); return $start_of_zulu_day; } sub save_aggregate { my ($self) = @_; my $agg = $self->report->aggregate; # put config information in report metadata foreach my $f ( qw/ org_name email extra_contact_info report_id / ) { $agg->metadata->$f( $self->config->{organization}{$f} ); }; my ( $begin, $end ) = $self->get_report_window( $self->result->published->ri, $self->time ); $agg->metadata->begin( $begin ); $agg->metadata->end( $end ); $agg->policy_published( $self->result->published ); my $rec = Mail::DMARC::Report::Aggregate::Record->new(); $rec->row->source_ip( $self->source_ip ); $rec->identifiers( envelope_to => $self->envelope_to, envelope_from => $self->envelope_from, header_from => $self->header_from, ); $rec->auth_results->dkim($self->dkim); $rec->auth_results->spf($self->spf); $rec->row->policy_evaluated( disposition => $self->result->disposition, dkim => $self->result->dkim, spf => $self->result->spf, reason => $self->result->reason, ); $agg->record($rec); return $self->report->save_aggregate; } sub init { # used for testing my $self = shift; map { delete $self->{$_} } qw/ spf spf_ar dkim dkim_ar /; return; } 1; __END__ =pod =head1 Status Badges =for markdown [![Build Status](https://github.com/msimerson/mail-dmarc/actions/workflows/ci.yml/badge.svg)](https://github.com/msimerson/mail-dmarc/actions/workflows/ci.yml) =for markdown [![Coverage Status](https://coveralls.io/repos/msimerson/mail-dmarc/badge.svg)](https://coveralls.io/r/msimerson/mail-dmarc) =head1 NAME Mail::DMARC - Perl implementation of DMARC =head1 VERSION version 1.20260306 =head1 SYNOPSIS DMARC: Domain-based Message Authentication, Reporting and Conformance my $dmarc = Mail::DMARC::PurePerl->new( ... # see the documentation for the "new" method for required args ); my $result = $dmarc->validate(); if ( $result->result eq 'pass' ) { ...continue normal processing... return; }; # any result that did not pass is a fail. Now for disposition if ( $result->disposition eq 'reject' ) { ...treat the sender to a 550 ... }; if ( $result->disposition eq 'quarantine' ) { ...assign a bunch of spam points... }; if ( $result->disposition eq 'none' ) { ...continue normal processing... }; =head1 DESCRIPTION This module is a suite of tools for implementing DMARC. It adheres to the 2013 DMARC draft, intending to implement every MUST and every SHOULD. This module can be used by... =over 4 =item * MTAs and filtering tools like SpamAssassin to validate that incoming messages are aligned with the purported sender's policy. =item * email senders, to receive DMARC reports from other mail servers and display them via CLI and web interfaces. =item * MTA operators to send DMARC reports to DMARC author domains. =back When a message arrives via SMTP, the MTA or filtering application can pass in a small amount of metadata about the connection (envelope details, SPF and DKIM results) to Mail::DMARC. When the B method is called, Mail::DMARC will determine if: a. the header_from domain exists b. the header_from domain publishes a DMARC policy c. if a policy is published... d. does the message conform to the published policy? e. did the policy request reporting? If so, save details. The validation results are returned as a L object. If the author domain requested a report, it was saved to the L. The Store class includes a SQL implementation that is tested with SQLite, MySQL and PostgreSQL. There is more information available in the $result object. See L for complete details. Reports are viewed with the L program or with a web browser and the L program. Aggregate reports are sent to their requestors with the L program. For aggregate reports that you have been sent, the L program will parse the email messages (from IMAP, Mbox, or files) and save the report results into the L. The report store can use the same database to store reports you have received as well as reports you will send. There are several ways to identify the difference, including: =over 4 =item * received reports will have a null value for report_policy_published.rua =item * outgoing reports will have null values for report.uuid and report_record.count =back =head1 CLASSES L - the perl interface for DMARC L - a DMARC policy L - Pure Perl implementation of DMARC L - the results of applying policy L - Reporting: the R in DMARC =over 2 L - send reports via SMTP & HTTP L - receive and store reports from email, HTTP L - a persistent data store for aggregate reports L - CLI and CGI methods for viewing reports =back L - an XS implementation using libopendmarc =head1 METHODS =head2 new Create a DMARC object. my $dmarc = Mail::DMARC::PurePerl->new; Populate it. $dmarc->source_ip('192.0.1.1'); $dmarc->envelope_to('recipient.example.com'); $dmarc->envelope_from('sender.example.com'); $dmarc->header_from('sender.example.com'); $dmarc->dkim( $dkim_verifier ); $dmarc->spf([ { domain => 'example.com', scope => 'mfrom', result => 'pass', }, { scope => 'helo', domain => 'mta.example.com', result => 'fail', }, ]); Run the request: my $result = $dmarc->validate(); Alternatively, pass in all the required parameters in one shot: my $dmarc = Mail::DMARC::PurePerl->new( source_ip => '192.0.1.1', envelope_to => 'example.com', envelope_from => 'cars4you.info', header_from => 'yahoo.com', dkim => $dkim_results, # same format spf => $spf_results, # as previous example ); my $result = $dmarc->validate(); =head2 source_ip The remote IP that attempted sending the message. DMARC only uses this data for reporting to domains that request DMARC reports. =head2 envelope_to The domain portion of the RFC5321.RcptTo, (aka, the envelope recipient), and the bold portion in the following example: =over 8 RCPT TO:<user@B> =back =head2 envelope_from The domain portion of the RFC5321.MailFrom, (aka, the envelope sender). That is the the bold portion in the following example: =over 8 MAIL FROM:<user@B> =back =head2 header_from The domain portion of the RFC5322.From, aka, the From message header. =over 8 From: Ultimate Vacation <sweepstakes@B> =back You can instead pass in the entire From: header with header_from_raw. =head2 header_from_raw Retrieve the header_from domain by parsing it from a raw From field/header. The domain portion is extracted by L, which is fast, generally effective, but also rather crude. It has limits, so read the description. =head2 dkim If Mail::DKIM::Verifier was used to validate the message, just pass in the Mail::DKIM::Verifier object that processed the message: $dmarc->dkim( $dkim_verifier ); Otherwise, pass in an array reference. Each member of the DKIM array results represents a DKIM signature in the message and consists of the 4 keys shown in this example: $dmarc->dkim( [ { domain => 'example.com', selector => 'apr2013', result => 'fail', human_result=> 'fail (body has been altered)', }, { # 2nd signature, if present }, ] ); The dkim results can also be build iteratively by passing in key value pairs or hash references for each signature in the message: $dmarc->dkim( domain => 'sig1.com', result => 'fail' ); $dmarc->dkim( domain => 'sig2.com', result => 'pass' ); $dmarc->dkim( { domain => 'example.com', result => 'neutral' } ); Each hash or hashref is appended to the dkim array. Finally, you can pass a coderef which won't be called until the dkim method is used to read the dkim results. It must return an array reference as described above. The dkim result is an array reference. =head3 domain The d= parameter in the DKIM signature =head3 selector The s= parameter in the DKIM signature =head3 result The validation results of this signature. One of: none, pass, fail, policy, neutral, temperror, or permerror =head3 human result Additional information about the DKIM result. This is comparable to Mail::DKIM::Verifier->result_detail. =head2 spf The spf method works exactly the same as dkim. It accepts named arguments, a hashref, an arrayref, or a coderef: $dmarc->spf( domain => 'example.com', scope => 'mfrom', result => 'pass', ); The SPF domain and result are required for DMARC validation and the scope is used for reporting. =head3 domain The SPF checked domain =head3 scope The scope of the checked domain: mfrom, helo =head3 result The SPF result code: none, neutral, pass, fail, softfail, temperror, or permerror. =head1 DESIGN & GOALS =head2 Correct The DMARC spec is lengthy and evolving, making correctness a moving target. In cases where correctness is ambiguous, options are generally provided. =head2 Easy to use Providing an implementation of DMARC that SMTP utilities can utilize will aid DMARC adoption. The list of dependencies appears long because of reporting. If this module is used without reporting, the number of dependencies not included with perl is about 5. =head2 Maintainable Since DMARC is evolving, this implementation aims to be straight forward and easy to alter and extend. The programming style is primarily OO, which carries a small performance penalty but dividends in maintainability. When multiple options are available, such as when sending reports via SMTP or HTTP, calls should be made to the parent Send class to broker the request. When storing reports, calls are made to the Store class which dispatches to the SQL class. The idea is that if someone desired a data store other than those provided by perl's DBI class, they could easily implement their own. If you do, please fork it on GitHub and share. =head2 Fast If you deploy this in an environment where performance is insufficient, please profile the app and submit a report and preferably, patches. =head1 SEE ALSO L 2015-03 L DMARC L =head1 HISTORY The daddy of this perl module was a L. =head1 AUTHORS =over 4 =item * Matt Simerson =item * Davide Migliavacca =item * Marc Bradshaw =back =head1 CONTRIBUTORS =for stopwords Benny Pedersen Jean Paul Galea Marisa Clardy Priyadi Iman Nurcahyo Ricardo Signes =over 4 =item * Benny Pedersen =item * Jean Paul Galea =item * Marisa Clardy =item * Priyadi Iman Nurcahyo =item * Ricardo Signes =back =head1 COPYRIGHT AND LICENSE This software is copyright (c) 2026 by Matt Simerson. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. =cut Mail-DMARC-1.20260306/lib/Mail/DMARC000755000765000024 015152630466 15342 5ustar00mattstaff000000000000Mail-DMARC-1.20260306/lib/Mail/DMARC/Base.pm000444000765000024 2553315152630466 16737 0ustar00mattstaff000000000000package Mail::DMARC::Base; our $VERSION = '1.20260306'; use strict; use warnings; use 5.10.0; use Carp; use Config::Tiny; use File::ShareDir; use HTTP::Tiny; use IO::File; use Net::DNS::Resolver; use Net::IDN::Encode qw/domain_to_unicode/; use Net::IP; use Regexp::Common 2013031301 qw /net/; use Socket; use Socket6 qw//; # don't export symbols sub new { my ( $class, @args ) = @_; croak "invalid args" if scalar @args % 2 != 0; return bless { config_file => 'mail-dmarc.ini', @args, # this may override config_file }, $class; } my $_fake_time; sub time { ## no critic # Ability to return a fake time for testing my ( $self ) = @_; my $time = defined $Mail::DMARC::Base::_fake_time ? $Mail::DMARC::Base::_fake_time : time; return $time; } sub set_fake_time { my ( $self, $time ) = @_; $Mail::DMARC::Base::_fake_time = $time; return; } sub config { my ( $self, $file, @too_many ) = @_; croak "invalid args" if scalar @too_many; return $self->{config} if ref $self->{config} && !$file; return $self->{config} = $self->get_config($file); } sub get_prefix { my ($self, $subdir) = @_; return map { $_ . ($subdir ? $subdir : '') } qw[ /usr/local/ /opt/local/ / ./ ]; } sub get_sharefile { my ($self, $file) = @_; my $match = File::ShareDir::dist_file( 'Mail-DMARC', $file ); print "using $match for $file\n" if $self->verbose; return $match; } sub get_config { my $self = shift; my $file = shift || $ENV{MAIL_DMARC_CONFIG_FILE} || $self->{config_file} or croak; return Config::Tiny->read($file) if -r $file; # fully qualified foreach my $d ($self->get_prefix('etc')) { next if !-d $d; next if !-e "$d/$file"; croak "unreadable file: $d/$file" if !-r "$d/$file"; my $Config = Config::Tiny->new; return Config::Tiny->read("$d/$file"); } if ($file ne 'mail-dmarc.ini') { croak "unable to find requested config file $file\n"; } return Config::Tiny->read( $self->get_sharefile('mail-dmarc.ini') ); } sub any_inet_ntop { my ( $self, $ip_bin ) = @_; $ip_bin or croak "missing IP in request"; if ( length $ip_bin == 16 ) { return Socket6::inet_ntop( AF_INET6, $ip_bin ); } return Socket6::inet_ntop( AF_INET, $ip_bin ); } sub any_inet_pton { my ( $self, $ip_txt ) = @_; $ip_txt or croak "missing IP in request"; if ( $ip_txt =~ /:/ ) { return Socket6::inet_pton( AF_INET6, $ip_txt ) || croak "invalid IPv6: $ip_txt"; } return Socket6::inet_pton( AF_INET, $ip_txt ) || croak "invalid IPv4: $ip_txt"; } { my $public_suffixes; my $public_suffixes_stamp; sub get_public_suffix_list { my ( $self ) = @_; if ( $public_suffixes ) { return $public_suffixes; } no warnings 'once'; ## no critic $Mail::DMARC::psl_loads++; my $file = $self->find_psl_file(); $public_suffixes_stamp = ( stat( $file ) )[9]; open my $fh, '<:encoding(UTF-8)', $file or croak "unable to open $file for read: $!\n"; # load PSL into hash for fast lookups, esp. for long running daemons my %psl = map { $_ => 1 } grep { $_ !~ /^[\/\s]/ } # weed out comments & whitespace map { chomp($_); $_ } ## no critic, remove line endings <$fh>; close $fh; return $public_suffixes = \%psl; } sub check_public_suffix_list { my ( $self ) = @_; my $file = $self->find_psl_file(); my $new_public_suffixes_stamp = ( stat( $file ) )[9]; if ( $new_public_suffixes_stamp != $public_suffixes_stamp ) { $public_suffixes = undef; $self->get_public_suffix_list(); return 1; } return 0; } } sub is_public_suffix { my ( $self, $zone ) = @_; croak "missing zone name!" if !$zone; my $public_suffixes = $self->get_public_suffix_list(); $zone = domain_to_unicode( $zone ) if $zone =~ /xn--/; return 1 if $public_suffixes->{$zone}; my @labels = split /\./, $zone; $zone = join '.', '*', (@labels)[ 1 .. scalar(@labels) - 1 ]; return 1 if $public_suffixes->{$zone}; return 0; } sub update_psl_file { my ($self, $dryrun) = @_; my $psl_file = $self->find_psl_file(); die "No Public Suffix List file found\n" if ( ! $psl_file ); die "Public suffix list file $psl_file not found\n" if ( ! -f $psl_file ); die "Cannot write to Public Suffix List file $psl_file\n" if ( ! -w $psl_file ); my $url = 'https://publicsuffix.org/list/effective_tld_names.dat'; if ( $dryrun ) { print "Will attempt to update the Public Suffix List file at $psl_file (dryrun mode)\n"; return; } my $response = HTTP::Tiny->new->mirror( $url, $psl_file ); my $content = $response->{'content'}; if ( !$response->{'success'} ) { my $status = $response->{'status'}; die "HTTP Request for Public Suffix List file failed with error $status ($content)\n"; } else { if ( $response->{'status'} eq '304' ) { print "Public Suffix List file $psl_file not modified\n"; } else { print "Public Suffix List file $psl_file updated\n"; } } return; } sub find_psl_file { my ($self) = @_; my $file = $self->config->{dns}{public_suffix_list} || 'share/public_suffix_list'; if ( $file =~ /^\// && -f $file && -r $file ) { print "using $file for Public Suffix List\n" if $self->verbose; return $file; } foreach my $path ($self->get_prefix($file)) { if ( -f $path && -r $path ) { print "using $path for Public Suffix List\n"; # if $self->verbose; return $path; } } # Fallback to included suffic list return $self->get_sharefile('public_suffix_list'); } sub has_dns_rr { my ( $self, $type, $domain ) = @_; my @matches; my $res = $self->get_resolver(); my $query = $res->query( $domain, $type ) or do { return 0 if ! wantarray; return @matches; }; for my $rr ( $query->answer ) { next if $rr->type ne $type; push @matches, $rr->type eq 'A' ? $rr->address : $rr->type eq 'PTR' ? $rr->ptrdname : $rr->type eq 'NS' ? $rr->nsdname : $rr->type eq 'TXT' ? $rr->txtdata : $rr->type eq 'SPF' ? $rr->txtdata : $rr->type eq 'AAAA' ? $rr->address : $rr->type eq 'MX' ? $rr->exchange : $rr->answer; } return scalar @matches if ! wantarray; return @matches; } sub epoch_to_iso { my ($self, $epoch) = @_; my @fields = localtime( $epoch ); my $ss = sprintf( "%02i", $fields[0] ); # seconds my $mn = sprintf( "%02i", $fields[1] ); # minutes my $hh = sprintf( "%02i", $fields[2] ); # hours (24 hour clock) my $dd = sprintf( "%02i", $fields[3] ); # day of month my $mm = sprintf( "%02i", $fields[4] + 1 ); # month my $yy = ( $fields[5] + 1900 ); # year return "$yy-$mm-$dd" .'T'."$hh:$mn:$ss"; } sub get_resolver { my $self = shift; my $timeout = shift || $self->config->{dns}{timeout} || 5; my $retrans = shift || $self->config->{dns}{retrans} || 5; return $self->{resolver} if defined $self->{resolver}; $self->{resolver} = Net::DNS::Resolver->new( dnsrch => 0 ); $self->{resolver}->tcp_timeout($timeout); $self->{resolver}->udp_timeout($timeout); $self->{resolver}->retrans($retrans); return $self->{resolver}; } sub set_resolver { my ($self,$resolver) = @_; $self->{resolver} = $resolver; return; } sub is_valid_ip { my ( $self, $ip ) = @_; # Using Regexp::Common removes perl 5.8 compat # Perl 5.008009 does not support the pattern $RE{net}{IPv6}. # You need Perl 5.01 or later if ( $ip =~ /:/ ) { return Net::IP->new( $ip, 6 ); } return Net::IP->new( $ip, 4 ); } sub is_valid_domain { my ( $self, $domain ) = @_; return 0 if $domain !~ /^$RE{net}{domain}{-rfc1101}{-nospace}$/x; my $tld = ( split /\./, $domain )[-1]; return 1 if $self->is_public_suffix($tld); return 0 if $domain eq 'localhost'; return 0 if $tld eq 'localdomain'; $tld = join( '.', ( split /\./, $domain )[ -2, -1 ] ); return 1 if $self->is_public_suffix($tld); return 0; } sub is_valid_spf_scope { my ($self, $scope ) = @_; return lc $scope if grep { lc $scope eq $_ } qw/ mfrom helo /; carp "$scope is not a valid SPF scope"; return; } sub is_valid_spf_result { my ($self, $result ) = @_; return 1 if grep { lc $result eq $_ } qw/ fail neutral none pass permerror softfail temperror /; carp "$result is not a valid SPF result"; return; } sub slurp { my ( $self, $file ) = @_; open my $FH, '<', $file or croak "unable to read $file: $!"; my $contents = do { local $/; <$FH> }; ## no critic (Local) close $FH; return $contents; } sub verbose { return $_[0]->{verbose} if 1 == scalar @_; return $_[0]->{verbose} = $_[1]; } 1; __END__ =pod =head1 NAME Mail::DMARC::Base - DMARC utility functions =head1 VERSION version 1.20260306 =head1 METHODS =head2 is_public_suffix Determines if part of a domain is a Top Level Domain (TLD). Examples of TLDs are com, net, org, co.ok, am, and us. Determination is made by consulting a Public Suffix List. The included PSL is from mozilla.org. See http://publicsuffix.org/list/ for more information, and a link to download the latest PSL. =head2 update_psl_file Download a new Public Suffix List file from mozilla and update the installed file with the new copy. =head2 has_dns_rr Determine if a DNS Resource Record of the specified type exists at the DNS name provided. =head2 get_resolver Returns a (cached) Net::DNS::Resolver object =head2 set_resolver Set the Net::DNS::Resolver object to be used for lookups =head2 is_valid_ip Determines if the supplied IP address is a valid IPv4 or IPv6 address. =head2 is_valid_domain Determine if a string is a legal RFC 1034 or 1101 host name. Half the reason to test for domain validity is to shave seconds off our processing time by not having to process DNS queries for illegal host names. The other half is to raise exceptions if methods are being called incorrectly. =head1 SEE ALSO Mozilla Public Suffix List: http://publicsuffix.org/list/ =head1 AUTHORS =over 4 =item * Matt Simerson =item * Davide Migliavacca =item * Marc Bradshaw =back =head1 COPYRIGHT AND LICENSE This software is copyright (c) 2026 by Matt Simerson. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. =cut Mail-DMARC-1.20260306/lib/Mail/DMARC/HTTP.pm000444000765000024 1401115152630466 16631 0ustar00mattstaff000000000000package Mail::DMARC::HTTP; our $VERSION = '1.20260306'; use strict; use warnings; use parent 'Net::Server::HTTP'; use CGI; use Data::Dumper; use File::ShareDir; use IO::Uncompress::Gunzip; use JSON -convert_blessed_universally; use URI; our $report; use Mail::DMARC::PurePerl; my %mimes = ( css => 'text/css', html => 'text/html', js => 'application/javascript', json => 'application/json', ); sub new { my $class = shift; return bless {}, $class; } sub dmarc_httpd { my $self = shift; $report = shift; my $port = $report->config->{http}{port} || 8080; my $ports = $report->config->{https}{port}; my $sslkey = $report->config->{https}{ssl_key}; my $sslcrt = $report->config->{https}{ssl_crt}; Net::Server::HTTP->run( app => sub { &dmarc_dispatch }, port => [$port, (($ports && $sslkey && $sslcrt) ? "$ports/ssl" : ()) ], ipv => '*', # IPv6 if available ($sslkey ? (SSL_key_file => $sslkey) : ()), ($sslcrt ? (SSL_cert_file => $sslcrt) : ()), log_file => 'Sys::Syslog', syslog_ident => 'mail_dmarc', syslog_facility => 'MAIL', ); return; } sub dmarc_dispatch { my $self = shift; my $path = $self->{request_info}{request_path}; if ($path) { warn "path: $path\n"; # Parse QUERY_STRING once here via URI (not CGI->new->Vars) to avoid # CGI.pm state issues in persistent Net::Server::HTTP processes. my %vars = URI->new('http://x/?' . ($ENV{QUERY_STRING} // ''))->query_form; return report_json_report(\%vars) if $path eq '/dmarc/json/report'; return report_json_rr(\%vars) if $path eq '/dmarc/json/row'; return serve_validator() if $path eq '/dmarc/json/validate'; return serve_file($path) if $path =~ /\.(?:js|css|html|gz)$/x; }; return serve_file('/dmarc/index.html'); } sub serve_pretty_error { my $error = shift || 'Sorry, that operation is not supported.'; return print <<"EO_ERROR" Content-Type: text/html

$error

EO_ERROR ; } sub return_json_error { my ($err) = @_; #warn $err; print JSON->new->utf8->encode( { err => $err } ); # to HTTP client print "\n"; return $err; # to caller } sub serve_validator { my $cgi = shift || CGI->new(); # passed in $cgi for testing my $resolver = shift; # passed in $resolver for testing my $json = JSON->new->utf8; print $cgi->header("application/json"); my $post = $cgi->param('POSTDATA'); if (!$post) { return return_json_error("missing POST data"); } my ($input, $dmpp, $res); eval { $input = $json->decode( $post ); }; if ($@) { return return_json_error($@); } if (!$input || !ref $input) { return return_json_error("invalid request $post"); } eval { $dmpp = Mail::DMARC::PurePerl->new( %$input ) }; if ($@) { return return_json_error($@); } $dmpp->set_resolver($resolver) if $resolver; eval { $res = $dmpp->validate(); }; if ($@) { return return_json_error($@); } my $return = $json->allow_blessed->convert_blessed->encode( $res ); print "$return\n"; return $return; } sub serve_file { my ($path) = @_; my @bits = split /\//, $path; shift @bits; return serve_pretty_error("file not found") if (!$bits[0] || 'dmarc' ne $bits[0]); shift @bits; $path = join '/', @bits; my $file = $bits[-1]; $file =~ s/[^[ -~]]//g; # strip out any non-printable chars my ($extension) = (split /\./, $file)[-1]; return serve_pretty_error("$extension not recognized") if ! $mimes{$extension}; my $dir = "share/html"; # distribution dir if ( ! -d $dir ) { $dir = File::ShareDir::dist_dir( 'Mail-DMARC' ); # installed loc. $dir .= "/html"; }; return serve_pretty_error("no such path") if ! $dir; return serve_gzip("$dir/$path.gz") if -f "$dir/$path.gz"; return serve_pretty_error("no such file") if ! -f "$dir/$path"; open my $FH, '<', "$dir/$path" or return serve_pretty_error( "unable to read $dir/$path: $!" ); print "Content-Type: $mimes{$extension}\n\n"; print <$FH>; close $FH; return 1; } sub serve_gzip { my $file = shift; open my $FH, '<', "$file" or return serve_pretty_error( "unable to read $file: $!" ); my $contents = do { local $/; <$FH> }; ## no critic (Local) close $FH; my $decomp = substr($file, 0, -3); # remove .gz suffix my ($extension) = (split /\./, $decomp)[-1]; # browser accepts gz encoding, serve compressed if ( grep {/gzip/} $ENV{HTTP_ACCEPT_ENCODING} ) { my $length = length $contents; return print <<"EO_GZ" Content-Length: $length Content-Type: $mimes{$extension} Content-Encoding: gzip $contents EO_GZ ; } # browser doesn't support gzip, decompress and serve my $out; IO::Uncompress::Gunzip::gunzip( \$contents => \$out ) or return serve_pretty_error( "unable to decompress" ); my $length = length $out; return print <<"EO_UNGZ" Content-Length: $length Content-Type: $mimes{$extension} $out EO_UNGZ ; } sub report_json_report { my ($vars) = @_; print "Content-type: application/json\n\n"; my $reports = $report->store->backend->get_report( %$vars ); print encode_json $reports; return; } sub report_json_rr { my ($vars) = @_; print "Content-type: application/json\n\n"; my $row = $report->store->backend->get_rr( rid => $vars->{rid} ); print encode_json $row; return; } 1; __END__ =pod =head1 NAME Mail::DMARC::HTTP - view stored reports via HTTP =head1 VERSION version 1.20260306 =head1 SYNOPSIS See the POD docs / man page for L. =head1 AUTHORS =over 4 =item * Matt Simerson =item * Davide Migliavacca =item * Marc Bradshaw =back =head1 COPYRIGHT AND LICENSE This software is copyright (c) 2026 by Matt Simerson. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. =cut Mail-DMARC-1.20260306/lib/Mail/DMARC/Policy.pm000444000765000024 3620615152630466 17323 0ustar00mattstaff000000000000package Mail::DMARC::Policy; use strict; use warnings; our $VERSION = '1.20260306'; use Carp; use Mail::DMARC::Report::URI; sub new { my ( $class, @args ) = @_; my $package = ref $class ? ref $class : $class; my $self = bless {}, $package; return $self if 0 == scalar @args; # no args, empty pol if (1 == @args) { # a string my $policy = $self->parse( $args[0] ); $self->is_valid($policy); return $policy; } croak "invalid arguments" if @args % 2 != 0; my $policy = {@args}; bless $policy, $package; croak "invalid policy" if !$self->is_valid($policy); return bless $policy, $package; } sub parse { my ( $self, $str, @junk ) = @_; croak "invalid parse request" if 0 != scalar @junk; my $cleaned = $str; $cleaned =~ s/\s//g; # remove whitespace $cleaned =~ s/\\;/;/g; # replace \; with ; $cleaned =~ s/;;/;/g; # replace ;; with ; $cleaned =~ s/;0;/;/g; # replace ;0; with ; chop $cleaned if ';' eq substr $cleaned, -1, 1; # remove a trailing ; my @tag_vals = split /;/, $cleaned; my %policy; my $warned = 0; foreach my $tv (@tag_vals) { my ($tag, $value) = split /=|:|-/, $tv, 2; if ( !defined $tag || !defined $value || $value eq '') { if (!$warned) { #warn "tv: $tv\n"; warn "invalid DMARC record, please post this message to\n" . "\thttps://github.com/msimerson/mail-dmarc/issues/39\n" . "\t$str\n"; } $warned++; next; } $policy{lc $tag} = $value; } return bless \%policy, ref $self; # inherited defaults + overrides } sub stringify { my $self = shift; my %dmarc_record = %{$self}; delete $dmarc_record{domain}; my $dmarc_txt = 'v=' . (delete $dmarc_record{v}); # "v" tag must be first foreach my $key ( keys %dmarc_record ) { $dmarc_txt .= "; $key=$dmarc_record{$key}"; } return $dmarc_txt; } sub apply_defaults { my $self = shift; $self->adkim('r') if !defined $self->adkim; $self->aspf('r') if !defined $self->aspf; $self->fo(0) if !defined $self->fo; $self->ri(86400) if !defined $self->ri; $self->rf('afrf') if !defined $self->rf; # pct # default is 100%, but 100% -vs- not defined is different return 1; } sub v { return $_[0]->{v} if 1 == scalar @_; croak "unsupported DMARC version" if 'DMARC1' ne uc $_[1]; return $_[0]->{v} = $_[1]; } sub p { return $_[0]->{p} if 1 == scalar @_; croak "invalid p" if !$_[0]->is_valid_p( $_[1] ); return $_[0]->{p} = $_[1]; } sub sp { return $_[0]->{sp} if 1 == scalar @_; croak "invalid sp ($_[1])" if !$_[0]->is_valid_p( $_[1] ); return $_[0]->{sp} = $_[1]; } sub adkim { return $_[0]->{adkim} if 1 == scalar @_; croak "invalid adkim" if 0 == grep {/^\Q$_[1]\E$/ix} qw/ r s /; return $_[0]->{adkim} = $_[1]; } sub aspf { return $_[0]->{aspf} if 1 == scalar @_; croak "invalid aspf" if 0 == grep {/^\Q$_[1]\E$/ix} qw/ r s /; return $_[0]->{aspf} = $_[1]; } sub fo { return $_[0]->{fo} if 1 == scalar @_; croak "invalid fo: $_[1]" if $_[1] !~ /^[01ds](:[01ds])*$/ix; return $_[0]->{fo} = $_[1]; } sub rua { return $_[0]->{rua} if 1 == scalar @_; croak "invalid rua" if !$_[0]->is_valid_uri_list( $_[1] ); return $_[0]->{rua} = $_[1]; } sub ruf { return $_[0]->{ruf} if 1 == scalar @_; croak "invalid rua" if !$_[0]->is_valid_uri_list( $_[1] ); return $_[0]->{ruf} = $_[1]; } sub rf { return $_[0]->{rf} if 1 == scalar @_; foreach my $f ( split /,/, $_[1] ) { croak "invalid format: $f" if !$_[0]->is_valid_rf($f); } return $_[0]->{rf} = $_[1]; } sub ri { return $_[0]->{ri} if 1 == scalar @_; croak "not numeric ($_[1])!" if $_[1] =~ /\D/; croak "not an integer!" if $_[1] != int $_[1]; croak "out of range" if ( $_[1] < 0 || $_[1] > 4294967295 ); return $_[0]->{ri} = $_[1]; } sub pct { return $_[0]->{pct} if 1 == scalar @_; croak "not numeric ($_[1])!" if $_[1] =~ /\D/; croak "not an integer!" if $_[1] != int $_[1]; croak "out of range" if $_[1] < 0 || $_[1] > 100; return $_[0]->{pct} = $_[1]; } sub domain { return $_[0]->{domain} if 1 == scalar @_; return $_[0]->{domain} = $_[1]; } sub is_valid_rf { my ( $self, $f ) = @_; return ( grep {/^\Q$f\E$/i} qw/ iodef afrf / ) ? 1 : 0; } sub is_valid_p { my ( $self, $p ) = @_; croak "unspecified p" if !defined $p; return ( grep {/^\Q$p\E$/i} qw/ none reject quarantine / ) ? 1 : 0; } sub is_valid_uri_list { my ( $self, $str ) = @_; $self->{uri} ||= Mail::DMARC::Report::URI->new; my $uris = $self->{uri}->parse($str); return scalar @$uris; } sub is_valid { my ( $self, $obj ) = @_; $obj = $self if !$obj; croak "missing version specifier" if !$obj->{v}; croak "invalid version" if 'DMARC1' ne uc $obj->{v}; if ( !$obj->{p} ) { if ( $obj->{rua} && $self->is_valid_uri_list( $obj->{rua} ) ) { $obj->{p} = 'none'; } else { croak "missing policy action (p=)"; } } croak "invalid policy action" if !$self->is_valid_p( $obj->{p} ); # everything else is optional return 1; } 1; __END__ =pod =head1 NAME Mail::DMARC::Policy - a DMARC policy in object format =head1 VERSION version 1.20260306 =head1 SYNOPSIS my $pol = Mail::DMARC::Policy->new( 'v=DMARC1; p=none; rua=mailto:dmarc@example.com' ); print "not a valid DMARC version!" if $pol->v ne 'DMARC1'; print "take no action" if $pol->p eq 'none'; print "reject that unaligned message" if $pol->p eq 'reject'; print "do not send aggregate reports" if ! $pol->rua; print "do not send forensic reports" if ! $pol->ruf; =head1 EXAMPLES A DMARC record in DNS format looks like this: v=DMARC1; p=reject; adkim=s; aspf=s; rua=mailto:dmarc@example.com; pct=100; DMARC records are stored in TXT resource records in the DNS, at _dmarc.example.com. To retrieve a DMARC record for a domain: =head2 dig dig +short _dmarc.example.com TXT =head2 perlishly print $_->txtdata."\n" for Net::DNS::Resolver->new(dnsrch=>0)->send('_dmarc.example.com','TXT')->answer; =head2 dmarc_lookup dmarc_lookup example.com =head1 METHODS All methods validate their input against the 2013 DMARC specification. Attempts to set invalid values will throw exceptions. =head2 new Create a new empty policy: my $pol = Mail::DMARC::Policy->new; Create a new policy from named arguments: my $pol = Mail::DMARC::Policy->new( v => 'DMARC1', p => 'none', pct => 50, ); Create a new policy from a DMARC DNS resource record: my $pol = Mail::DMARC::Policy->new( 'v=DMARC1; p=reject; rua=mailto:dmarc@example.com; pct=50;' ); If a policy is passed in (the latter two examples), the resulting policy object will be an exact representation of the record as returned from DNS. =head2 apply_defaults Several of the DMARC tags (adkim,aspf,fo,ri,rf) have default values when not specified in the published DNS record. Calling I will apply those default values to the DMARC tags that were not specified in the DNS record. The resulting L object will be a perfect representation of the DMARC policy that is/was applied. =head2 parse Accepts a string containing a DMARC Resource Record, as it would be retrieved via DNS. my $pol = Mail::DMARC::Policy->new; $pol->parse( 'v=DMARC1; p=none; rua=mailto:dmarc@example.com' ); $pol->parse( 'v=DMARC1' ); # external reporting record =head2 stringify Returns the textual representation of the DMARC record. my $pol = Mail::DMARC::Policy->new('v=DMARC1; p=none;'); print $pol->stringify; =head1 Record Tags =head2 Tag Overview v=DMARC1; (version) p=none; (disposition policy : reject, quarantine, none (monitor)) sp=reject; (subdomain policy: same as p) adkim=s; (dkim alignment: s=strict, r=relaxed) aspf=r; (spf alignment: s=strict, r=relaxed) rua=mailto:dmarc-feedback@example.com; (aggregate reports) ruf=mailto:dmarc-feedback@example.com; (forensic reports) rf=afrf; (report format: afrf, iodef) ri=8400; (report interval) pct=50; (percent of messages to filter) =head2 Tags in Detail The descriptions of each DMARC record tag and its corresponding values is from the March 31, 2013 draft of the DMARC spec: https://datatracker.ietf.org/doc/draft-kucherawy-dmarc-base/?include_text=1 Each tag has a mutator that's a setter and getter. To set any of the tag values, pass in the new value. Examples: $pol->p('none'); set policy action to none print "do nothing" if $pol->p eq 'none'; get policy action =head2 v Version (plain-text; REQUIRED). Identifies the record retrieved as a DMARC record. It MUST have the value of "DMARC1". The value of this tag MUST match precisely; if it does not or it is absent, the entire retrieved record MUST be ignored. It MUST be the first tag in the list. =head2 p Requested Mail Receiver policy (plain-text; REQUIRED for policy records). Indicates the policy to be enacted by the Receiver at the request of the Domain Owner. Policy applies to the domain queried and to sub-domains unless sub-domain policy is explicitly described using the "sp" tag. This tag is mandatory for policy records only, but not for third-party reporting records (see Section 8.2). =head2 sp {R6} Requested Mail Receiver policy for subdomains (plain-text; OPTIONAL). Indicates the policy to be enacted by the Receiver at the request of the Domain Owner. It applies only to subdomains of the domain queried and not to the domain itself. Its syntax is identical to that of the "p" tag defined above. If absent, the policy specified by the "p" tag MUST be applied for subdomains. =head2 adkim (plain-text; OPTIONAL, default is "r".) Indicates whether or not strict DKIM identifier alignment is required by the Domain Owner. If and only if the value of the string is "s", strict mode is in use. See Section 4.3.1 for details. =head2 aspf (plain-text; OPTIONAL, default is "r".) Indicates whether or not strict SPF identifier alignment is required by the Domain Owner. If and only if the value of the string is "s", strict mode is in use. See Section 4.3.2 for details. =head2 fo Failure reporting options (plain-text; OPTIONAL, default "0")) Provides requested options for generation of failure reports. Report generators MAY choose to adhere to the requested options. This tag's content MUST be ignored if a "ruf" tag (below) is not also specified. The value of this tag is a colon-separated list of characters that indicate failure reporting options as follows: 0: Generate a DMARC failure report if all underlying authentication mechanisms failed to produce an aligned "pass" result. 1: Generate a DMARC failure report if any underlying authentication mechanism failed to produce an aligned "pass" result. d: Generate a DKIM failure report if the message had a signature that failed evaluation, regardless of its alignment. DKIM- specific reporting is described in [AFRF-DKIM]. s: Generate an SPF failure report if the message failed SPF evaluation, regardless of its alignment. SPF-specific reporting is described in [AFRF-SPF]. =head2 rua Addresses to which aggregate feedback is to be sent (comma- separated plain-text list of DMARC URIs; OPTIONAL). {R11} A comma or exclamation point that is part of such a DMARC URI MUST be encoded per Section 2.1 of [URI] so as to distinguish it from the list delimiter or an OPTIONAL size limit. Section 8.2 discusses considerations that apply when the domain name of a URI differs from that of the domain advertising the policy. See Section 15.6 for additional considerations. Any valid URI can be specified. A Mail Receiver MUST implement support for a "mailto:" URI, i.e. the ability to send a DMARC report via electronic mail. If not provided, Mail Receivers MUST NOT generate aggregate feedback reports. URIs not supported by Mail Receivers MUST be ignored. The aggregate feedback report format is described in Section 8.3. =head2 ruf Addresses to which message-specific failure information is to be reported (comma-separated plain-text list of DMARC URIs; OPTIONAL). {R11} If present, the Domain Owner is requesting Mail Receivers to send detailed failure reports about messages that fail the DMARC evaluation in specific ways (see the "fo" tag above). The format of the message to be generated MUST follow that specified in the "rf" tag. Section 8.2 discusses considerations that apply when the domain name of a URI differs from that of the domain advertising the policy. A Mail Receiver MUST implement support for a "mailto:" URI, i.e. the ability to send a DMARC report via electronic mail. If not provided, Mail Receivers MUST NOT generate failure reports. See Section 15.6 for additional considerations. =head2 rf Format to be used for message-specific failure reports (comma- separated plain-text list of values; OPTIONAL; default "afrf"). The value of this tag is a list of one or more report formats as requested by the Domain Owner to be used when a message fails both [SPF] and [DKIM] tests to report details of the individual failure. The values MUST be present in the registry of reporting formats defined in Section 14; a Mail Receiver observing a different value SHOULD ignore it, or MAY ignore the entire DMARC record. Initial default values are "afrf" (defined in [AFRF]) and "iodef" (defined in [IODEF]). See Section 8.4 for details. =head2 ri Interval requested between aggregate reports (plain-text, 32-bit unsigned integer; OPTIONAL; default 86400). {R14} Indicates a request to Receivers to generate aggregate reports separated by no more than the requested number of seconds. DMARC implementations MUST be able to provide daily reports and SHOULD be able to provide hourly reports when requested. However, anything other than a daily report is understood to be accommodated on a best- effort basis. =head2 pct (plain-text integer between 0 and 100, inclusive; OPTIONAL; default is 100). {R8} Percentage of messages from the DNS domain's mail stream to which the DMARC mechanism is to be applied. However, this MUST NOT be applied to the DMARC-generated reports, all of which must be sent and received unhindered. The purpose of the "pct" tag is to allow Domain Owners to enact a slow rollout enforcement of the DMARC mechanism. The prospect of "all or nothing" is recognized as preventing many organizations from experimenting with strong authentication-based mechanisms. See Section 7.1 for details. =head1 AUTHORS =over 4 =item * Matt Simerson =item * Davide Migliavacca =item * Marc Bradshaw =back =head1 COPYRIGHT AND LICENSE This software is copyright (c) 2026 by Matt Simerson. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. =cut Mail-DMARC-1.20260306/lib/Mail/DMARC/PurePerl.pm000444000765000024 6517115152630466 17625 0ustar00mattstaff000000000000package Mail::DMARC::PurePerl; our $VERSION = '1.20260306'; use strict; use warnings; use Carp; use parent 'Mail::DMARC'; sub init { my $self = shift; $self->is_subdomain(0); $self->{header_from} = undef; $self->{header_from_raw} = undef; $self->{envelope_to} = undef; $self->{envelope_from} = undef; $self->{source_ip} = undef; $self->{policy} = undef; $self->{result} = undef; $self->{report} = undef; $self->{spf} = undef; $self->{dkim} = undef; return; } sub validate { my $self = shift; my $policy = shift; $self->result->result('fail'); # set a couple $self->result->disposition('none'); # defaults # 11.2.1 Extract RFC5322.From domain my $from_dom = $self->get_from_dom() or return $self->result; # 9.6. reject email if the domain appears to not exist $self->exists_in_dns() or return $self->result; $policy ||= $self->discover_policy(); # 11.2.2 Query DNS for DMARC policy if (!$policy) { # RFC7489 section 4.3 step 8: # If a policy is found, it is combined with the Author's domain # and the SPF and DKIM results to produce a DMARC policy result (a # "pass" or "fail") # Hence, if no (valid) policy has been found, produce "none" instead. $self->result->result('none'); return $self->result; } # 3.5 Out of Scope DMARC has no "short-circuit" provision, such as # specifying that a pass from one authentication test allows one # to skip the other(s). All are required for reporting. eval { $self->is_dkim_aligned; }; # 11.2.3. DKIM signature verification checks eval { $self->is_spf_aligned; }; # 11.2.4. SPF validation checks my $aligned = $self->is_aligned(); # 11.2.5. identifier alignment checks if ($self->config->{report_store}{auto_save}) { eval { $self->save_aggregate(); }; } return $self->result if $aligned; my $effective_p = defined $policy->sp && $self->result->published && $self->result->published->domain ne $from_dom ? $policy->sp : $policy->p; # 11.2.6 Apply policy. Emails that fail the DMARC mechanism check are # disposed of in accordance with the discovered DMARC policy of the # Domain Owner. See Section 6.2 for details. if ( lc $effective_p eq 'none' ) { return $self->result; } return $self->result if $self->is_whitelisted; # 7.1. Policy Fallback Mechanism # If the "pct" tag is present in a policy record, application of policy # is done on a selective basis. if ( !defined $policy->pct ) { $self->result->disposition($effective_p); return $self->result; } # The stated percentage of messages that fail the DMARC test MUST be # subjected to whatever policy is selected by the "p" or "sp" tag if ( int( rand(100) ) < $policy->pct ) { $self->result->disposition($effective_p); return $self->result; } $self->result->reason( type => 'sampled_out' ); # Those that are not thus selected MUST instead be subjected to the next # policy lower in terms of severity. In decreasing order of severity, # the policies are "reject", "quarantine", and "none". $self->result->disposition( ( $effective_p eq 'reject' ) ? 'quarantine' : 'none' ); return $self->result; } sub save_aggregate { my ( $self ) = @_; my $pol; eval { $pol = $self->result->published; }; if ( $pol && $self->has_valid_reporting_uri($pol->rua) ) { my @valid_report_uris = $self->get_valid_reporting_uri($pol->rua); my $filtered_report_uris = join( ',', map { $_->{'uri'} . ( ( $_->{'max_bytes'} > 0 ) ? ( '!' . $_->{'max_bytes'} ) : q{} ) } @valid_report_uris ); $self->result->published->rua( $filtered_report_uris ); return $self->SUPER::save_aggregate(); } return; } sub discover_policy { my $self = shift; my $from_dom = shift || $self->header_from or croak; print "Header From: $from_dom\n" if $self->verbose; my $org_dom = $self->get_organizational_domain($from_dom); $self->is_subdomain($org_dom eq $from_dom ? 0 : 1); # 9.1 Mail Receivers MUST query the DNS for a DMARC TXT record my ($matches, $at_dom) = $self->fetch_dmarc_record( $from_dom, $org_dom ); if (0 == scalar @$matches ) { $self->result->result('none'); $self->result->reason( type => 'other', comment => 'no policy' ); return; }; # 9.5. If the remaining set contains multiple records, processing # terminates and the Mail Receiver takes no action. if ( scalar @$matches > 1 ) { $self->result->reason( type => 'other', comment => "too many policies" ); print "Too many DMARC records\n" if $self->verbose; return; } my $policy; if (!$at_dom) { $at_dom = $from_dom; } my $policy_str = "domain=$at_dom;" . $matches->[0]; # prefix with domain eval { $policy = $self->policy( $policy_str ) } or return; if ($@) { $self->result->reason( type => 'other', comment => "policy parse error: $@" ); return; }; $self->result->published($policy); # 9.6 If a retrieved policy record does not contain a valid "p" tag, or # contains an "sp" tag that is not valid, then: if ( !$policy->p || !$policy->is_valid_p( $policy->p ) || ( defined $policy->sp && !$policy->is_valid_p( $policy->sp ) ) ) { # A. if an "rua" tag is present and contains at least one # syntactically valid reporting URI, the Mail Receiver SHOULD # act as if a record containing a valid "v" tag and "p=none" # was retrieved, and continue processing; # B. otherwise, the Mail Receiver SHOULD take no action. if ( !$policy->rua || !$self->has_valid_reporting_uri( $policy->rua ) ) { $self->result->reason( type => 'other', comment => "no valid rua" ); return; } $policy->v('DMARC1'); $policy->p('none'); } return $policy; } sub is_aligned { my $self = shift; # 11.2.5 Conduct identifier alignment checks. With authentication checks # and policy discovery performed, the Mail Receiver checks if # Authenticated Identifiers fall into alignment as decribed in # Section 4. If one or more of the Authenticated Identifiers align # with the RFC5322.From domain, the message is considered to pass # the DMARC mechanism check. All other conditions (authentication # failures, identifier mismatches) are considered to be DMARC # mechanism check failures. if ( 'pass' eq $self->result->spf || 'pass' eq $self->result->dkim ) { $self->result->result('pass'); $self->result->disposition('none'); return 1; } return 0; } sub is_dkim_aligned { my $self = shift; $self->result->dkim('fail'); # our 'default' result $self->get_dkim_pass_sigs() or return; # 11.2.3 Perform DKIM signature verification checks. A single email may # contain multiple DKIM signatures. The results MUST include the # value of the "d=" tag from all DKIM signatures that validated. my $from_dom = $self->header_from or croak "header_from not set!"; my $policy = $self->policy or croak "no policy!?"; my $from_org = $self->get_organizational_domain(); # Required in report: DKIM-Domain, DKIM-Identity, DKIM-Selector foreach my $dkim_ref ( $self->get_dkim_pass_sigs() ) { my $dkim_dom = lc $dkim_ref->{domain}; my $dkmeta = { domain => $dkim_ref->{domain}, selector => $dkim_ref->{selector}, identity => '', # TODO, what is this? }; if ( $dkim_dom eq $from_dom ) { # strict alignment requires exact match $self->result->dkim('pass'); $self->result->dkim_align('strict'); $self->result->dkim_meta($dkmeta); last; } # don't try relaxed if policy specifies strict next if $policy->adkim && 's' eq lc $policy->adkim; # don't try relaxed if we already got a strict match next if 'pass' eq $self->result->dkim; # relaxed policy (default): Org. Dom must match a DKIM sig my $dkim_org = $self->get_organizational_domain($dkim_dom); if ( $dkim_org eq $from_org ) { $self->result->dkim('pass'); $self->result->dkim_align('relaxed'); $self->result->dkim_meta($dkmeta); } } return 1 if 'pass' eq lc $self->result->dkim; return; } sub is_spf_aligned { my $self = shift; my $spf_dom = shift; if ( !$spf_dom && !$self->spf ) { croak "missing SPF!"; } if ( !$spf_dom ) { my @passes = grep { $_->{result} && $_->{result} =~ /pass/i } @{ $self->spf }; if (scalar @passes == 0) { $self->result->spf('fail'); return 0; }; my ($ref) = grep { $_->{scope} && $_->{scope} eq 'mfrom' } @passes; if (!$ref) { ($ref) = grep { $_->{scope} && $_->{scope} eq 'helo' } @passes; } if (!$ref) { ($ref) = $passes[0]; }; $spf_dom = $ref->{domain}; }; # 11.2.4 Perform SPF validation checks. The results of this step # MUST include the domain name from the RFC5321.MailFrom if SPF # evaluation returned a "pass" result. $self->result->spf('fail'); return 0 if !$spf_dom; my $from_dom = lc $self->header_from or croak "header_from not set!"; $spf_dom = lc $spf_dom; if ( $spf_dom eq $from_dom ) { $self->result->spf('pass'); $self->result->spf_align('strict'); return 1; } # don't try relaxed match if strict policy requested if ( $self->policy->aspf && 's' eq lc $self->policy->aspf ) { return 0; } if ( $self->get_organizational_domain($spf_dom) eq $self->get_organizational_domain($from_dom) ) { $self->result->spf('pass'); $self->result->spf_align('relaxed'); return 1; } return 0; } sub is_whitelisted { my $self = shift; my $s_ip = shift || $self->source_ip; return if ! defined $s_ip; if ( ! $self->{_whitelist} ) { my $white_file = $self->config->{smtp}{whitelist} or return; return if ! -f $white_file || ! -r $white_file; foreach my $line ( split /\n/, $self->slurp($white_file) ) { next if $line =~ /^#/; # ignore comments my ($lip,$reason) = split /\s+/, $line, 2; next if not defined $lip; $self->{_whitelist}{$lip} = $reason; }; }; return if ! $self->{_whitelist}{$s_ip}; my ($type, $comment) = split /\s+/, $self->{_whitelist}{$s_ip}, 2; $self->result->disposition('none'); $self->result->reason( type => $type, ($comment && $comment =~ /\S/ ? ('comment' => $comment) : () ), ); return $type; } sub has_valid_reporting_uri { my ( $self, $rua ) = @_; my @valid_reporting_uris = $self->get_valid_reporting_uri( $rua ); return scalar @valid_reporting_uris; } sub get_valid_reporting_uri { my ( $self, $rua ) = @_; return unless $rua; my $recips_ref = $self->report->uri->parse($rua); my @has_permission; foreach my $uri_ref (@$recips_ref) { if ( !$self->external_report( $uri_ref->{uri} ) ) { push @has_permission, $uri_ref; next; } my $ext = $self->verify_external_reporting($uri_ref); push @has_permission, $uri_ref if $ext; } return @has_permission; } sub get_dkim_pass_sigs { my $self = shift; my $dkim_sigs = $self->dkim or return (); # message not signed if ( 'ARRAY' ne ref $dkim_sigs ) { croak "dkim needs to be an array reference!"; } return grep { 'pass' eq lc $_->{result} } @$dkim_sigs; } sub get_organizational_domain { my $self = shift; my $from_dom = shift || $self->header_from or croak "missing header_from!"; # 4.1 Acquire a "public suffix" list, i.e., a list of DNS domain # names reserved for registrations. http://publicsuffix.org/list/ # 4.2 Break the subject DNS domain name into a set of "n" ordered # labels. Number these labels from right-to-left; e.g. for # "example.com", "com" would be label 1 and "example" would be # label 2.; my @labels = reverse split /\./, lc $from_dom; # 4.3 Search the public suffix list for the name that matches the # largest number of labels found in the subject DNS domain. Let # that number be "x". my $greatest = 0; for ( my $i = 0; $i <= scalar @labels; $i++ ) { next if !$labels[$i]; my $tld = join '.', reverse( (@labels)[ 0 .. $i ] ); if ( $self->is_public_suffix($tld) ) { $greatest = $i + 1; } } if ( $greatest == scalar @labels ) { # same return $from_dom; } # 4.4 Construct a new DNS domain name using the name that matched # from the public suffix list and prefixing to it the "x+1"th # label from the subject domain. This new name is the # Organizational Domain. my $org_dom = join '.', reverse( (@labels)[ 0 .. $greatest ] ); print "Organizational Domain: $org_dom\n" if $self->verbose; return $org_dom; } sub exists_in_dns { my $self = shift; my $from_dom = shift || $self->header_from or croak "no header_from!"; # rfc7489 6.6.3 # If the set produced by the mechanism above contains no DMARC policy # record (i.e., any indication that there is no such record as opposed # to a transient DNS error), Mail Receivers SHOULD NOT apply the DMARC # mechanism to the message. my $org_dom = $self->get_organizational_domain($from_dom); my @todo = $from_dom; if ( $from_dom ne $org_dom ) { push @todo, $org_dom; $self->is_subdomain(1); } my $matched = 0; foreach (@todo) { last if $matched; $matched++ and next if $self->has_dns_rr( 'MX', $_ ); $matched++ and next if $self->has_dns_rr( 'NS', $_ ); $matched++ and next if $self->has_dns_rr( 'A', $_ ); $matched++ and next if $self->has_dns_rr( 'AAAA', $_ ); } if ( !$matched ) { $self->result->result('none'); $self->result->disposition('none'); $self->result->reason( type => 'other', comment => "$from_dom not in DNS" ); } return $matched; } sub fetch_dmarc_record { my ( $self, $zone, $org_dom ) = @_; # 1. Mail Receivers MUST query the DNS for a DMARC TXT record at the # DNS domain matching the one found in the RFC5322.From domain in # the message. A possibly empty set of records is returned. my @matches = (); my $query = $self->get_resolver->send( "_dmarc.$zone", 'TXT' ) or return (\@matches, $zone); for my $rr ( $query->answer ) { next if $rr->type ne 'TXT'; # 2. Records that do not start with a "v=" tag that identifies the # current version of DMARC are discarded. next if 'v=dmarc1' ne lc substr( $rr->txtdata, 0, 8 ); print "\n" . $rr->txtdata . "\n\n" if $self->verbose; push @matches, join( '', $rr->txtdata ); # join long records } if (scalar @matches) { return \@matches, $zone; # found one! (at least) } # 3. If the set is now empty, the Mail Receiver MUST query the DNS for # a DMARC TXT record at the DNS domain matching the Organizational # Domain in place of the RFC5322.From domain in the message (if # different). This record can contain policy to be asserted for # subdomains of the Organizational Domain. if ( defined $org_dom ) { # <- recursion break if ( $org_dom ne $zone ) { return $self->fetch_dmarc_record($org_dom); # <- recursion } } return \@matches, $zone; } sub get_from_dom { my ($self) = @_; return $self->header_from if $self->header_from; my $header = $self->header_from_raw or do { $self->result->reason( type => 'other', comment => "no header_from" ); return; }; # TODO: the From header can contain multiple addresses and should be # parsed as described in RFC 2822. If From has multiple-addresses, # then parse and use the domain in the Sender header. # This returns only the domain in the last email address. # Caller can pass in pre-parsed from_dom if this doesn't suit them. # # I care only about the domain. This is way faster than RFC2822 parsing my ($from_dom) = ( split /@/, $header )[-1]; # grab everything after the @ ($from_dom) = split /(\s+|>)/, lc $from_dom; # remove trailing cruft if ( !$from_dom ) { $self->result->reason( type => 'other', comment => "invalid header_from: ($header)" ); return; } return $self->header_from($from_dom); } sub external_report { my ( $self, $uri ) = @_; my $dmarc_dom = $self->result->published->domain or croak "published policy not tagged!"; if ( 'mailto' eq $uri->scheme ) { my $dest_email = lc $uri->path; my ($dest_host) = ( split /@/, $dest_email )[-1]; if ( $self->get_organizational_domain( $dest_host ) eq $self->get_organizational_domain( $dmarc_dom ) ) { print "$dest_host not external for $dmarc_dom\n" if $self->verbose; return 0; }; print "$dest_host is external for $dmarc_dom\n" if $self->verbose; } if ( 'http' eq $uri->scheme ) { if ($uri->host eq $dmarc_dom ) { print $uri->host ." not external for $dmarc_dom\n" if $self->verbose; return 0; }; print $uri->host ." is external for $dmarc_dom\n" if $self->verbose; } return 1; } sub verify_external_reporting { my $self = shift; my $uri_ref = shift or croak "missing URI"; # 1. Extract the host portion of the authority component of the URI. # Call this the "destination host". my $dmarc_dom = $self->result->published->domain or croak "published policy not tagged!"; my $dest_email = $uri_ref->{uri}->path or croak("invalid URI"); my ($dest_host) = ( split /@/, $dest_email )[-1]; # 2. Prepend the string "_report._dmarc". # 3. Prepend the domain name from which the policy was retrieved, # after conversion to an A-label if needed. my $dest = join '.', $dmarc_dom, '_report._dmarc', $dest_host; # 4. Query the DNS for a TXT record at the constructed name. my $query = $self->get_resolver->send( $dest, 'TXT' ) or do { print "\tquery for $dest failed\n" if $self->verbose; return; }; # 5. For each record, parse the result...same overall format: # "v=DMARC1" tag is mandatory and MUST appear first in the list. my @matches; for my $rr ( $query->answer ) { next if $rr->type ne 'TXT'; next if 'v=dmarc1' ne lc substr( $rr->txtdata, 0, 8 ); my $policy = undef; my $dmarc_str = join( '', $rr->txtdata ); # join parts eval { $policy = $self->policy->parse($dmarc_str) }; ## no critic (Eval) push @matches, $policy ? $policy : $dmarc_str; } # 6. If the result includes no TXT resource records...stop if ( !scalar @matches ) { print "\tno TXT match for $dest\n" if $self->verbose; return; }; # 7. If > 1 TXT resource record remains, external reporting authorized # 8. If a "rua" or "ruf" tag is discovered, replace the # corresponding value with the one found in this record. my @overrides = grep { ref $_ && $_->{rua} } @matches; foreach my $or (@overrides) { my $recips_ref = $self->report->uri->parse( $or->{rua} ) or next; if ( ( split /@/, $recips_ref->[0]{uri} )[-1] eq ( split /@/, $uri_ref->{uri} )[-1] ) { # the overriding URI MUST use the same destination host from the first step. print "found override RUA: $or->{rua}\n" if $self->verbose; $self->result->published->rua( $or->{rua} ); } } return @matches; } 1; __END__ =pod =head1 NAME Mail::DMARC::PurePerl - Pure Perl implementation of DMARC =head1 VERSION version 1.20260306 =head1 METHODS =head2 init Reset the Mail::DMARC object, preparing it for a fresh request. =head2 validate This method does the following: =over 4 * check if the RFC5322.From domain exists (exists_in_dns) * query DNS for a DMARC policy (discover_policy) * check DKIM alignment (is_dkim_aligned) * check SPF alignment (is_spf_aligned) * determine DMARC alignment (is_aligned) * calculate the I DMARC policy * apply the DMARC policy (see L) =back =head2 discover_policy Query the DNS to determine if a DMARC policy exists. When the domain name in the email From header (header_from) is not an Organizational Domain (ex: www.example.com), an attempt is made to determine the O.D. using the Mozilla Public Suffix List. When the O.D. differs from the header_from, a second DNS query is sent to _dmarc.[O.D.]. If a DMARC DNS record is found, it is parsed as a L object and returned. =head2 is_aligned Determine if this message is DMARC aligned. To pass this test, the message must pass at least one of the alignment test (DKIM or SPF). =head2 is_dkim_aligned Determine if a valid DKIM signature in the message is aligned with the message's From header domain. This match can be in strict (exact match) or relaxed (subdomains match) alignment. =head2 is_spf_aligned Same as DKIM, but for SPF. =head2 has_valid_reporting_uri Check for the presence of a valid reporting URI in the rua or ruf DMARC policy tags. =head2 get_organizational_domain From the 2013 DMARC spec, section 4: Organizational Domain: ..is the domain that was registered with a domain name registrar. Heuristics are used to determine this... =head2 exists_in_dns Determine if a domain exists, reliably. The DMARC draft says: 9.6 If the RFC5322.From domain does not exist in the DNS, Mail Receivers SHOULD direct the receiving SMTP server to reject the message {R9}. And in Appendix A.4: A common practice among MTA operators, and indeed one documented in [ADSP], is a test to determine domain existence prior to any more expensive processing. This is typically done by querying the DNS for MX, A or AAAA resource records for the name being evaluated, and assuming the domain is non-existent if it could be determined that no such records were published for that domain name. The original pre-standardization version of this protocol included a mandatory check of this nature. It was ultimately removed, as the method's error rate was too high without substantial manual tuning and heuristic work. There are indeed use cases this work needs to address where such a method would return a negative result about a domain for which reporting is desired, such as a registered domain name that never sends legitimate mail and thus has none of these records present in the DNS. I went back to the ADSP (which led me to the ietf-dkim email list where some 'experts' failed to agree on The Right Way to test domain validity. They pointed out: MX records aren't mandatory, and A or AAAA aren't reliable. Some experimentation proved both arguments in real world usage. This module tests for existence by searching for a MX, NS, A, or AAAA record. Since this search may be repeated for the Organizational Name, if the NS query fails, there is no delegation from the TLD. That has proven very reliable. =head2 fetch_dmarc_record Query the DNS for the presence of a DMARC record at the header from domain name and the Organizational Domain name. Returns the discovered DNS record answers. =head2 get_from_dom Returns the header_from attribute, if defined. When header_from is not defined, crudely, and very quickly parse a From header and return the domain name (aka, the header_from domain). The From header format is defined in RFC 822 and is very complex. The From header can contain multiple email addresses, each with different domains. This method returns the last one. If you want to handle this differently, parse the From header yourself and set header_from. =head2 external_report Determine if a report URL is external. If the domain name portion of the URI is not the same as the domain where the DMARC record was discovered, the report address is considered external. =head2 verify_external_reporting =head3 8.2. Verifying External Destinations It is possible to specify destinations for the different reports that are outside the domain making the request. This is enabled to allow domains that do not have mail servers to request reports and have them go someplace that is able to receive and process them. Without checks, this would allow a bad actor to publish a DMARC policy record that requests reports be sent to a victim address, and then send a large volume of mail that will fail both DKIM and SPF checks to a wide variety of destinations, which will in turn flood the victim with unwanted reports. Therefore, a verification mechanism is included. When a Mail Receiver discovers a DMARC policy in the DNS, and the domain at which that record was discovered is not identical to the host part of the authority component of a [URI] specified in the "rua" or "ruf" tag, the following verification steps SHOULD be taken: 1. Extract the host portion of the authority component of the URI. Call this the "destination host". 2. Prepend the string "_report._dmarc". 3. Prepend the domain name from which the policy was retrieved, after conversion to an A-label if needed. 4. Query the DNS for a TXT record at the constructed name. 5. For each record, parse the result...same overall format: "v=DMARC1" tag is mandatory and MUST appear first in the list. 6. If the result includes no TXT resource records...stop 7. If > 1 TXT resource record remains, external reporting authorized 8. If a "rua" or "ruf" tag is discovered, replace the corresponding value with the one found in this record. The overriding URI MUST use the same destination host from the first step. =head1 AUTHORS =over 4 =item * Matt Simerson =item * Davide Migliavacca =item * Marc Bradshaw =back =head1 COPYRIGHT AND LICENSE This software is copyright (c) 2026 by Matt Simerson. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. =cut Mail-DMARC-1.20260306/lib/Mail/DMARC/Report.pm000444000765000024 1547015152630466 17337 0ustar00mattstaff000000000000package Mail::DMARC::Report; use strict; use warnings; our $VERSION = '1.20260306'; use Carp; use IO::Compress::Gzip; use IO::Compress::Zip; use parent 'Mail::DMARC::Base'; require Mail::DMARC::Report::Aggregate; require Mail::DMARC::Report::Send; require Mail::DMARC::Report::Store; require Mail::DMARC::Report::Receive; require Mail::DMARC::Report::URI; sub compress { my ( $self, $xml_ref ) = @_; croak "xml is not a reference!" if 'SCALAR' ne ref $xml_ref; my $shrunk; my $zipper = { gz => \&IO::Compress::Gzip::gzip, # 2013 draft zip => \&IO::Compress::Zip::zip, # legacy format }; # WARNING: changes here MAY require updates in SMTP::assemble_message my $cf = 'gz'; $zipper->{$cf}->( $xml_ref, \$shrunk ) or croak "unable to compress: $!"; return $shrunk; } sub init { my $self = shift; delete $self->{dmarc}; delete $self->{aggregate}; return; } sub aggregate { my $self = shift; return $self->{aggregate} if ref $self->{aggregate}; return $self->{aggregate} = Mail::DMARC::Report::Aggregate->new(); } sub dmarc { my $self = shift; return $self->{dmarc}; } sub receive { my $self = shift; return $self->{receive} if ref $self->{receive}; return $self->{receive} = Mail::DMARC::Report::Receive->new; } sub sendit { my $self = shift; return $self->{sendit} if ref $self->{sendit}; return $self->{sendit} = Mail::DMARC::Report::Send->new(); } sub store { my $self = shift; return $self->{store} if ref $self->{store}; return $self->{store} = Mail::DMARC::Report::Store->new(); } sub uri { my $self = shift; return $self->{uri} if ref $self->{uri}; return $self->{uri} = Mail::DMARC::Report::URI->new(); } sub save_aggregate { my $self = shift; return $self->store->backend->save_aggregate( $self->aggregate ); } 1; __END__ =pod =head1 NAME Mail::DMARC::Report - A DMARC report interface =head1 VERSION version 1.20260306 =head1 DESCRIPTION DMARC reports are information that a DMARC implementing Mail Transfer Agent (MTA) sends to Author Domains and also something that an Author Domain owner receives from other DMARC implementing MTAs. Mail::DMARC supports both roles, as a sender and a receiver. There are two report types, L and forensic. =head1 Aggregate Reports See L =head2 Forensic Reports TODO =head2 Report Sender See L 1. store reports 2. bundle aggregated reports 3. format report in XML 4. gzip the XML 5. deliver report to Author Domain =head2 Report Receiver See L 1. accept reports via HTTP or SMTP 2. parse the compressed XML message 3. store the report 4. present stored data =head2 Verify External Destinations 1. Extract the host portion of the authority component of the URI. Call this the "destination host". 2. Prepend the string "_report._dmarc". 3. Prepend the domain name from which the policy was retrieved. 4. Query the DNS for a TXT record at the constructed name. If the result of this request is a temporary DNS error of some kind (e.g., a timeout), the Mail Receiver MAY elect to temporarily fail the delivery so the verification test can be repeated later. 5. If the result includes no TXT resource records or multiple TXT resource records, a positive determination of the external reporting relationship cannot be made; stop. 6. Parse the result, if any, as a series of "tag=value" pairs, i.e., the same overall format as the policy record. In particular, the "v=DMARC1" tag is mandatory and MUST appear first in the list. If at least that tag is present and the record overall is syntactically valid per Section 6.3, then the external reporting arrangement was authorized by the destination ADMD. 7. If a "rua" or "ruf" tag is thus discovered, replace the corresponding value extracted from the domain's DMARC policy record with the one found in this record. This permits the report receiver to override the report destination. However, to prevent loops or indirect abuse, the overriding URI MUST use the same destination host from the first step. =head1 ERROR REPORTS 12.2.4. Error Reports When a Mail Receiver is unable to complete delivery of a report via any of the URIs listed by the Domain Owner, the Mail Receiver SHOULD generate an error message. An attempt MUST be made to send this report to all listed "mailto" URIs and MAY also be sent to any or all other listed URIs. The error report MUST be formatted per [MIME]. A text/plain part MUST be included that contains field-value pairs such as those found in Section 2 of [DSN]. The fields required, which may appear in any order, are: Report-Date: A [MAIL]-formatted date expression indicating when the transport failure occurred. Report-Domain: The domain-name about which the failed report was generated. Report-ID: The Report-ID: that the report tried to use. Report-Size: The size, in bytes, of the report that was unable to be sent. This MUST represent the number of bytes that the Mail Receiver attempted to send. Where more than one transport system was attempted, the sizes may be different; in such cases, separate error reports MUST be generated so that this value matches the actual attempt that was made. For example, a "mailto" error report would be sent to the "mailto" URIs with one size, while the "https" reports might be POSTed to those URIs with a different size, as they have different transport and encoding requirements. Submitter: The domain-name representing the Mail Receiver that generated, but was unable to submit, the report. Submitting-URI: The URI(s) to which the Mail Receiver tried, but failed, to submit the report. An additional text/plain part MAY be included that gives a human- readable explanation of the above, and MAY also include a URI that can be used to seek assistance. [NOTE: A more rigorous syntax specification, including ABNF and possible registration of a new media type, will be added here when more operational experience is acquired.] =head1 AFRF reports =head1 IODEF reports https://datatracker.ietf.org/doc/draft-kucherawy-dmarc-base/?include_text=1 Section 3.5 Out of Scope: This first version of DMARC supports only a single reporting format. =head1 AUTHORS =over 4 =item * Matt Simerson =item * Davide Migliavacca =item * Marc Bradshaw =back =head1 COPYRIGHT AND LICENSE This software is copyright (c) 2026 by Matt Simerson. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. =cut Mail-DMARC-1.20260306/lib/Mail/DMARC/Result.pm000444000765000024 1316515152630466 17341 0ustar00mattstaff000000000000package Mail::DMARC::Result; our $VERSION = '1.20260306'; use strict; use warnings; use Carp; require Mail::DMARC::Result::Reason; sub new { my $class = shift; return bless { dkim => '', spf => '', reason => [], }, $class; } sub published { my ( $self, $policy ) = @_; if ( !$policy ) { if ( !defined $self->{published} ) { croak "no policy discovered. Did you validate(), or at least fetch_dmarc_record() first? Or inspected results to detect a 'No Results Found' type error?"; } return $self->{published}; } $policy->{domain} or croak "tag the policy object with a domain indicating where the DMARC record was found!"; return $self->{published} = $policy; } sub disposition { return $_[0]->{disposition} if 1 == scalar @_; croak "invalid disposition ($_[1]" if 0 == grep {/^$_[1]$/ix} qw/ reject quarantine none /; return $_[0]->{disposition} = $_[1]; } sub dkim { return $_[0]->{dkim} if 1 == scalar @_; croak "invalid dkim" if 0 == grep {/^$_[1]$/ix} qw/ pass fail /; return $_[0]->{dkim} = $_[1]; } sub dkim_align { return $_[0]->{dkim_align} if 1 == scalar @_; croak "invalid dkim_align" if 0 == grep {/^$_[1]$/ix} qw/ relaxed strict /; return $_[0]->{dkim_align} = $_[1]; } sub dkim_meta { return $_[0]->{dkim_meta} if 1 == scalar @_; return $_[0]->{dkim_meta} = $_[1]; } sub spf { return $_[0]->{spf} if 1 == scalar @_; croak "invalid spf" if 0 == grep {/^$_[1]$/ix} qw/ pass fail /; return $_[0]->{spf} = $_[1]; } sub spf_align { return $_[0]->{spf_align} if 1 == scalar @_; croak "invalid spf_align" if 0 == grep {/^$_[1]$/ix} qw/ relaxed strict /; return $_[0]->{spf_align} = $_[1]; } sub result { return $_[0]->{result} if 1 == scalar @_; croak "invalid result" if 0 == grep {/^$_[1]$/ix} qw/ pass fail none /; return $_[0]->{result} = $_[1]; } sub reason { my ($self, @args) = @_; return $self->{reason} if ! scalar @args; push @{ $self->{reason}}, Mail::DMARC::Result::Reason->new(@args); return $self->{reason}; } 1; __END__ =pod =head1 NAME Mail::DMARC::Result - an aggregate report result object =head1 VERSION version 1.20260306 =head1 OVERVIEW A L object is the product of instantiating a L object, populating the variables, and running $dmarc->validate. The results object looks like this: result => 'pass', # pass, fail disposition => 'none', # reject, quarantine, none reason => [ # there can be many reasons... { type => '', # forwarded, sampled_out, trusted_forwarder, comment => '', # mailing_list, local_policy, other }, ], dkim => 'pass', # pass, fail dkim_align => 'strict', # strict, relaxed spf => 'pass', # pass, fail spf_align => 'strict', # strict, relaxed published => L, Reasons are optional and may not be present. The dkim_align and spf_align fields will only be present if the corresponding test value equals pass. They are additional info not specified by the DMARC spec. =head1 METHODS =head2 published Published is a L tagged with a domain. The domain attribute is the DNS domain name where the DMARC record was found. This may not be the same as the header_from domain (ex: bounces.amazon.com -vs- amazon.com). =head2 result Whether the message passed the DMARC test. Possible values are: pass, fail. In order to pass, at least one authentication alignment must pass. The 2013 draft defines two authentication methods: DKIM and SPF. The list is expected to grow. =head2 disposition When the DMARC result is not I, disposition is the results of applying DMARC policy to a message. Generally this is the same as the header_from domains published DMARC L. When it is not, the reason SHOULD be specified. =head2 dkim Whether the message passed or failed DKIM alignment. In order to pass the DMARC DKIM alignment test, a DKIM signature that matches the RFC5322.From domain must be present. An unsigned messsage, a message with an invalid signature, or signatures that don't match the RFC5322.From field are all considered failures. =head2 dkim_align If the message passed the DKIM alignment test, this indicates whether the alignment was strict or relaxed. =head2 spf Whether the message passed or failed SPF alignment. To pass SPF alignment, the RFC5321.MailFrom domain must match the RFC5322.From field. =head2 spf_align If the message passed the SPF alignment test, this indicates whether the alignment was strict or relaxed. =head2 reason If the applied policy differs from the sites published policy, the result policy should contain a reason and optionally a comment. A DMARC result reason has two attributes, type, and comment. reason => { type => '', comment => '', }, =head3 type The following reason types are defined and valid: forwarded sampled_out trusted_forwarder mailing_list local_policy other =head3 comment Comment is a free form text field. =head1 AUTHORS =over 4 =item * Matt Simerson =item * Davide Migliavacca =item * Marc Bradshaw =back =head1 COPYRIGHT AND LICENSE This software is copyright (c) 2026 by Matt Simerson. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. =cut Mail-DMARC-1.20260306/lib/Mail/DMARC/Report000755000765000024 015152630466 16615 5ustar00mattstaff000000000000Mail-DMARC-1.20260306/lib/Mail/DMARC/Report/Aggregate.pm000444000765000024 2447715152630466 21234 0ustar00mattstaff000000000000package Mail::DMARC::Report::Aggregate; use strict; use warnings; our $VERSION = '1.20260306'; use Carp; use Data::Dumper; use XML::LibXML; use parent 'Mail::DMARC::Base'; use Mail::DMARC::Report::Aggregate::Metadata; sub metadata { my $self = shift; return $self->{metadata} if ref $self->{metadata}; return $self->{metadata} = Mail::DMARC::Report::Aggregate::Metadata->new; } sub policy_published { my ( $self, $policy ) = @_; return $self->{policy_published} if ! $policy; croak "not a policy object!" if 'Mail::DMARC::Policy' ne ref $policy; return $self->{policy_published} = $policy; } sub record { ## no critic (Ambiguous) my ($self, $record, @extra) = @_; if ( !$record) { return $self->{record} || []; } if (@extra) { croak "invalid args"; } if ('Mail::DMARC::Report::Aggregate::Record' ne ref $record) { croak "not a record object"; } $self->{record} ||= []; push @{ $self->{record} }, $record; return $self->{record}; }; sub dump_report { my $self = shift; carp Dumper( $self->{metadata}, $self->{policy_published}, $self->{record} ); return; } sub as_xml { my $self = shift; my $meta = $self->metadata->as_xml; my $pubp = $self->get_policy_published_as_xml; my $reco = $self->get_record_as_xml; return <<"EO_XML" \t1.0 $meta $pubp $reco EO_XML ; } sub get_record_as_xml { my $self = shift; my $rec_xml = ''; foreach my $rec ( @{ $self->{record} } ) { $rec_xml .= "\t\n"; my $ip = $rec->{row}{source_ip} or croak "no source IP!?"; my $count = $rec->{row}{count} or croak "no count!?"; $rec->{row}{policy_evaluated}{disposition} or croak "no disposition?"; $ip = XML::LibXML::Text->new( $ip )->toString(); $count = XML::LibXML::Text->new( $count )->toString(); $rec_xml .="\t\t\n" . "\t\t\t$ip\n" . "\t\t\t$count\n" . $self->get_policy_evaluated_as_xml( $rec ) . "\t\t\n" . $self->get_identifiers_as_xml($rec) . $self->get_auth_results_as_xml($rec); $rec_xml .= "\t\n"; } return $rec_xml; } sub get_identifiers_as_xml { my ( $self, $rec ) = @_; my $id = "\t\t\n"; foreach my $f (qw/ envelope_to envelope_from header_from /) { if ( $f eq 'header_from' ) { # min occurs = 1 croak "missing header_from!" if ! $rec->{identifiers}{$f}; } elsif ( $f eq 'envelope_from') { # min occurs = 1 $rec->{identifiers}{$f} = '' if ! $rec->{identifiers}{$f}; } elsif ( $f eq 'envelope_to' ) { # min occurs = 0 next if ! $rec->{identifiers}{$f}; }; my $val = XML::LibXML::Text->new( $rec->{identifiers}{$f} )->toString(); $id .= "\t\t\t<$f>$val\n"; } $id .= "\t\t\n"; return $id; } sub get_auth_results_as_xml { my ( $self, $rec ) = @_; my $ar = "\t\t\n"; foreach my $dkim_sig ( @{ $rec->{auth_results}{dkim} } ) { $ar .= "\t\t\t\n"; foreach my $g (qw/ domain selector result human_result /) { next if !defined $dkim_sig->{$g}; my $val = XML::LibXML::Text->new( $dkim_sig->{$g} )->toString(); $ar .= "\t\t\t\t<$g>$val\n"; } $ar .= "\t\t\t\n"; } foreach my $spf ( @{ $rec->{auth_results}{spf} } ) { $ar .= "\t\t\t\n"; foreach my $g (qw/ domain scope result /) { next if !defined $spf->{$g}; my $val = XML::LibXML::Text->new( $spf->{$g} )->toString(); $ar .= "\t\t\t\t<$g>$val\n"; } $ar .= "\t\t\t\n"; } $ar .= "\t\t\n"; return $ar; } sub get_policy_published_as_xml { my $self = shift; my $pp = $self->policy_published or return ''; my $xml = "\t\n\t\t$pp->{domain}\n"; foreach my $f (qw/ adkim aspf p sp pct fo /) { my $v = $pp->{$f}; # Set some default values for missing optional fields if necessary if ( $f eq 'sp' && !defined $v ) { $v = $pp->{'p'}; } if ( $f eq 'pct' && !defined $v ) { $v = '100'; } if ( $f eq 'fo' && !defined $v ) { $v = '0'; } next if !defined $v; $v = XML::LibXML::Text->new( $v )->toString(); $xml .= "\t\t<$f>$v\n"; } $xml .= "\t"; return $xml; } sub get_policy_evaluated_as_xml { my ( $self, $rec ) = @_; my $pe = "\t\t\t\n"; foreach my $f (qw/ disposition dkim spf /) { my $val = XML::LibXML::Text->new( $rec->{row}{policy_evaluated}{$f} )->toString(); $pe .= "\t\t\t\t<$f>$val\n"; } my $reasons = $rec->{row}{policy_evaluated}{reason}; if ( $reasons && scalar @$reasons ) { foreach my $reason ( @$reasons ) { my $typeval = XML::LibXML::Text->new( $reason->{type} )->toString(); my $commentval = XML::LibXML::Text->new( $reason->{comment} )->toString(); $pe .= "\t\t\t\t\n"; $pe .= "\t\t\t\t\t$typeval\n"; $pe .= "\t\t\t\t\t$commentval\n"; $pe .= "\t\t\t\t\n"; } }; $pe .= "\t\t\t\n"; return $pe; } 1; __END__ =pod =head1 NAME Mail::DMARC::Report::Aggregate - aggregate report object =head1 VERSION version 1.20260306 =head1 DESCRIPTION This class is used as the canonization of an aggregate report. When reports are received, the XML is parsed into an L object, which then gets passed to the Report::Store and saved. When sending DMARC reports, data is extracted from the L as an Aggregate object, exported as XML, and sent. =head1 2013 Draft Description AGGREGATE REPORTS The report SHOULD include the following data: o Enough information for the report consumer to re-calculate DMARC disposition based on the published policy, message disposition, and SPF, DKIM, and identifier alignment results. {R12} o Data for each sender subdomain separately from mail from the sender's organizational domain, even if no subdomain policy is applied. {R13} o Sending and receiving domains {R17} o The policy requested by the Domain Owner and the policy actually applied (if different) {R18} o The number of successful authentications {R19} o The counts of messages based on all messages received even if their delivery is ultimately blocked by other filtering agents {R20} Aggregate reports are most useful when they all cover a common time period. By contrast, correlation of these reports from multiple generators when they cover incongruous time periods is difficult or impossible. Report generators SHOULD, wherever possible, adhere to hour boundaries for the reporting period they are using. For example, starting a per-day report at 00:00; starting per-hour reports at 00:00, 01:00, 02:00; et cetera. Report Generators using a 24-hour report period are strongly encouraged to begin that period at 00:00 UTC, regardless of local timezone or time of report production, in order to facilitate correlation. =head1 Report Structure This is a translation of the XML report format in the 2013 Draft, converted to perl data structures. feedback => { version => 1.0, # decimal report_metadata => { # info about DMARC reporter report_id => string org_name => 'Art Farm', email => 'no-reply@theartfarm.com', extra_contact_info => string # min 0 date_range => { begin => epoch time, end => epoch time, }, error => string, # min 0, max unbounded }, policy_published => { domain => string adkim => r, s aspf => r, s p => none, quarantine, reject sp => none, quarantine, reject pct => integer fo => string }, record => [ { row => { source_ip => # IPAddress count => # integer policy_evaluated => { # min=1 disposition => # none, quarantine, reject dkim => # pass, fail spf => # pass, fail reason => [ # min 0, max unbounded { type => # forwarded sampled_out, trusted_forwarder, mailing_list, local_policy, other comment => # string, min 0 }, ], } }, identifiers => { envelope_to min=0 envelope_from min=1 header_from min=1 }, auth_results => { spf => [ # min 1, max unbounded { domain => # min 1 scope => # min 1, helo, mfrom result => # min 1, none neutral pass fail softfail temperror permerror } ] # ( unknown -> temperror, error -> permerror ) dkim => [ # min 0, max unbounded { domain => , # min 1, the d= parameter in the signature selector => , # min 0, string result => , # none pass fail policy neutral temperror permerror human_result => # min 0, string }, ], }, ] }, }; =head1 AUTHORS =over 4 =item * Matt Simerson =item * Davide Migliavacca =item * Marc Bradshaw =back =head1 COPYRIGHT AND LICENSE This software is copyright (c) 2026 by Matt Simerson. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. =cut Mail-DMARC-1.20260306/lib/Mail/DMARC/Report/Receive.pm000444000765000024 4242215152630466 20716 0ustar00mattstaff000000000000package Mail::DMARC::Report::Receive; use strict; use warnings; our $VERSION = '1.20260306'; use Carp; use Data::Dumper; use Email::MIME; use Email::Simple; use Encode; use File::Basename; use IO::Uncompress::Unzip; use IO::Uncompress::Gunzip; use Module::Load; use XML::LibXML; use parent 'Mail::DMARC::Base'; require Mail::DMARC::Policy; require Mail::DMARC::Report; require Mail::DMARC::Report::Aggregate::Record; sub from_imap { my $self = shift; load "Net::IMAP::Simple"; croak "Net::IMAP::Simple seems to not work, is it installed?" if $@; my $server = $self->config->{imap}{server} or croak "no imap server conf"; my $folder = $self->config->{imap}{folder} or croak "no imap folder conf"; my $a_done = $self->config->{imap}{a_done}; my $f_done = $self->config->{imap}{f_done}; my $port = $self->config->{imap}{port} // 993; if ($port != 143) { eval "use IO::Socket::SSL"; ## no critic (Eval) if ( $@ ) { croak "Can't load IO::Socket::SSL: $!\n"; }; if (defined $self->config->{imap}{SSL_verify_mode}) { IO::Socket::SSL::set_ctx_defaults( SSL_verifycn_scheme => 'imap', SSL_verify_mode => $self->config->{imap}{SSL_verify_mode}, ); } } no warnings qw(once); ## no critic (Warn) my $imap = Net::IMAP::Simple->new( $server, port => $port, use_ssl => $port != 143, ) or do { ## no critic (PackageVar) my $err = $port == 143 ? $Net::IMAP::Simple::errstr : $Net::IMAP::Simple::SSL::errstr; croak "Unable to connect to IMAP: $err\n"; }; print "connected to IMAP server $server:$port\n" if $self->verbose; $imap->login( $self->config->{imap}{user}, $self->config->{imap}{pass} ) or croak "Login failed: " . $imap->errstr . "\n"; print "\tlogged in\n" if $self->verbose; my $nm = $imap->select( $self->config->{imap}{folder} ); $imap->expunge_mailbox( $self->config->{imap}{folder} ); my @mess = $imap->search( 'UNSEEN', 'DATE' ); if (! scalar @mess) { # imap server might not support SORT extension *Gmail* @mess = $imap->search( 'UNSEEN' ); } print "\tfound " . scalar @mess . " messages\n" if $self->verbose; foreach my $i (@mess) { print $imap->seen($i) ? '*' : ' '; printf "[%03d] ", $i; my $message = $imap->get($i) or do { carp "unable to get message $i\n"; next; }; my $type = $self->from_email_simple( Email::Simple->new("$message") ); next if !$type; my $done_box = $type eq 'aggregate' ? $a_done : $type eq 'forensic' ? $f_done : croak "unknown type!"; $imap->add_flags( $i, '\Seen' ); if ( $done_box ) { $imap->copy( $i, $done_box ) or do { carp $imap->errstr; next; }; $imap->add_flags( $i, '\Deleted' ); }; } $imap->quit; return 1; } sub from_file { my ( $self, $file ) = @_; croak "missing message" if !$file; croak "No such file $file: $!" if !-f $file; my $contents = $self->slurp($file); # Detect gzip by magic bytes \x1f\x8b if ( substr($contents, 0, 2) eq "\x1f\x8b" ) { my $xml; IO::Uncompress::Gunzip::gunzip( \$contents, \$xml ) or croak "gunzip failed: $IO::Uncompress::Gunzip::GunzipError"; $self->_init_for_file($file); return $self->handle_body($xml) ? 'aggregate' : undef; } # Detect zip by magic bytes PK\x03\x04 if ( substr($contents, 0, 4) eq "PK\x03\x04" ) { my $xml; IO::Uncompress::Unzip::unzip( \$contents, \$xml ) or croak "unzip failed: $IO::Uncompress::Unzip::UnzipError"; $self->_init_for_file($file); return $self->handle_body($xml) ? 'aggregate' : undef; } # Detect XML by content (starts with optional BOM/whitespace then '<') if ( $contents =~ /\A(?:\xef\xbb\xbf)?\s*_init_for_file($file); return $self->handle_body($contents) ? 'aggregate' : undef; } return $self->from_email_simple(Email::Simple->new($contents)); } sub _init_for_file { my ( $self, $file ) = @_; $self->report->init(); $self->{_envelope_to} = undef; $self->{_header_from} = undef; $self->get_submitter_from_filename( File::Basename::basename($file) ); return; } sub from_mbox { my ( $self, $file_name ) = @_; croak "missing mbox file" if !$file_name; # TODO: replace this module # commented out due to build test failures # load "Mail::Mbox::MessageParser"; # croak "is Mail::Mbox::MessageParser installed?" if $@; # my $file_handle = FileHandle->new($file_name); my $folder_reader; # = Mail::Mbox::MessageParser->new( # { 'file_name' => $file_name, # 'file_handle' => $file_handle, # 'enable_cache' => 1, # 'enable_grep' => 1, # } # ); croak $folder_reader unless ref $folder_reader; my $prologue = $folder_reader->prologue; print $prologue; while ( !$folder_reader->end_of_file() ) { $self->from_email_simple( Email::Simple->new( $folder_reader->read_next_email() ) ); } return 1; } sub from_email_simple { my ( $self, $email ) = @_; $self->report->init(); $self->{_envelope_to} = undef; $self->{_header_from} = undef; $self->get_submitter_from_subject( $email->header('Subject') ); my $unzipper = { gz => \&IO::Uncompress::Gunzip::gunzip, # 2013 draft zip => \&IO::Uncompress::Unzip::unzip, # legacy format }; my $rep_type; foreach my $part ( Email::MIME->new( $email->as_string )->parts ) { my ($c_type, @ignore) = split ';', ($part->content_type || ''); next if $c_type =~ m{^text/(plain|html)$}; if ( $c_type eq 'text/rfc822-headers' ) { warn "TODO: handle forensic reports\n"; ## no critic (Carp) $rep_type = 'forensic'; next; } if ( $c_type eq 'message/feedback-report' ) { warn "TODO: handle forensic reports\n"; ## no critic (Carp) $rep_type = 'forensic'; next; } my $bigger; my $filename = $part->{ct}{attributes}{name} || ''; if ( $c_type eq 'application/zip' || $c_type eq 'application/x-zip-compressed' ) { eval { $self->get_submitter_from_filename( $filename ); $unzipper->{zip}->( \$part->body, \$bigger ); $self->handle_body($bigger); $rep_type = 'aggregate'; } or do { warn "failure processing $filename: $@"; }; next; } if ( $c_type eq 'application/gzip' ) { eval { $self->get_submitter_from_filename( $filename ); $unzipper->{gz}->( \$part->body, \$bigger ); $self->handle_body($bigger); $rep_type = 'aggregate'; } or do { warn "failure processing $filename: $@"; }; next; } if ( $filename =~ /xml\.gz$/ ) { if ( $c_type eq 'application/octet-stream' || $c_type eq 'multipart/alternative' ) { eval { $self->get_submitter_from_filename( $filename ); $unzipper->{gz}->( \$part->body, \$bigger ); $self->handle_body($bigger); $rep_type = 'aggregate'; } or do { warn "failure processing $filename: $@"; }; next; } } if ($c_type eq 'multipart/alternative') { } elsif ($c_type eq 'multipart/related') { } else { warn "Unknown message part $c_type\n"; ## no critic (Carp) } } return $rep_type; } sub get_submitter_from_filename { my ( $self, $filename ) = @_; return if $self->{_envelope_to}; # already parsed from Subject: my ( $submitter_dom, $report_dom, $begin, $end ) = split /!/, $filename; $self->{_header_from} ||= $report_dom; return $self->{_envelope_to} = $submitter_dom; } sub get_submitter_from_subject { my ( $self, $subject ) = @_; # The 2013 DMARC spec section 12.2.1 suggests that the header SHOULD conform # to a supplied ABNF. Rather than "require" such conformance, this method is # more concerned with reliably extracting the submitter domain. Quickly. $subject = lc Encode::decode( 'MIME-Header', $subject ); print $subject . "\n"; $subject = substr( $subject, 8 ) if 'subject:' eq substr( $subject, 0, 8 ); $subject =~ s/(?:report\sdomain|submitter|report-id)//gx; # strip keywords $subject =~ s/\s+//g; # remove white space my ( undef, $report_dom, $sub_dom, $report_id ) = split /:/, $subject; my $meta = $self->report->aggregate->metadata; if ( $report_id && !$meta->uuid ) { # remove if present $report_id = substr($report_id,1) if '<' eq substr($report_id,0,1); chop $report_id if '>' eq substr($report_id,-1,1); $meta->uuid($report_id); }; $self->{_header_from} ||= $report_dom; return $self->{_envelope_to} = $sub_dom; } sub handle_body { my ( $self, $body ) = @_; print "handling decompressed body\n" if $self->{verbose}; if ($body =~ /xmlns=/) { # gmx.net added an invalid namespace ("urn:ietf:params:xml:ns:dmarc-2.0") # which breaks the findnodes parsing. print "NOTICE: removing xmlns from XML document\n" if $self->{verbose}; $body =~ s/\s+xmlns="[^"]*"//g; } my $dom = XML::LibXML->load_xml( string => $body ); $self->do_node_report_metadata( $dom->findnodes("/feedback/report_metadata") ); $self->do_node_policy_published( $dom->findnodes("/feedback/policy_published") ); foreach my $record ( $dom->findnodes("/feedback/record") ) { $self->do_node_record($record); } return $self->report->save_aggregate(); } sub report { my $self = shift; return $self->{report} if ref $self->{report}; return $self->{report} = Mail::DMARC::Report->new(); } sub do_node_report_metadata { my ( $self, $node ) = @_; foreach my $n (qw/ org_name email extra_contact_info /) { $self->report->aggregate->metadata->$n( $node->findnodes("./$n")->string_value ); } my $rid = $node->findnodes("./report_id")->string_value; $rid = substr($rid,1) if '<' eq substr($rid,0,1); # remove < chop $rid if '>' eq substr($rid,-1,1); # remove > $self->report->aggregate->metadata->report_id( $rid ); if ( ! $self->report->aggregate->metadata->uuid ) { $self->report->aggregate->metadata->uuid( $rid ); }; foreach my $n (qw/ begin end /) { $self->report->aggregate->metadata->$n( $node->findnodes("./date_range/$n")->string_value ); } foreach my $n ( $node->findnodes("./error") ) { $self->report->aggregate->metadata->error( $n->string_value ); } return $self->report->aggregate->metadata; } sub do_node_policy_published { my ( $self, $node ) = @_; my $pol = Mail::DMARC::Policy->new(); foreach my $n (qw/ domain adkim aspf p sp pct /) { my $val = $node->findnodes("./$n")->string_value or next; $val =~ s/\s*//g; # remove whitespace $pol->$n($val); } $self->report->aggregate->policy_published($pol); return $pol; } sub do_node_record { my ( $self, $node ) = @_; my $rec = Mail::DMARC::Report::Aggregate::Record->new; $self->do_node_record_auth(\$rec, $node); foreach my $r (qw/ source_ip count /) { $rec->row->$r( $node->findnodes("./row/$r")->string_value ); }; # policy_evaluated foreach my $pe (qw/ disposition dkim spf /) { my $ResultType = $node->findnodes("./row/policy_evaluated/$pe")->string_value; if ($pe eq 'disposition') { if ($ResultType !~ /^(none|quarantine|reject)$/) { $ResultType = 'none'; # invalid DispositionType (Facebook) } } else { if ($ResultType !~ /^(pass|fail)$/) { $ResultType = 'pass'; # invalid ResultType (also FaceBook) } } $rec->row->policy_evaluated->$pe($ResultType); } # reason $self->do_node_record_reason( \$rec, $node ); # identifiers foreach my $i (qw/ envelope_to envelope_from header_from /) { $rec->identifiers->$i( $node->findnodes("./identifiers/$i")->string_value ); } # for reports from junc.org with mis-labeled identifiers if ( !$rec->identifiers->header_from ) { $rec->identifiers->header_from( $node->findnodes("./identities/header_from")->string_value ); }; # last resort... if (!$rec->identifiers->envelope_to) { $rec->identifiers->envelope_to($self->{_envelope_to}); } if (!$rec->identifiers->header_from) { $rec->identifiers->header_from($self->{_header_from}); } print Data::Dumper::Dumper($rec) if $self->verbose; $self->report->aggregate->record($rec); return $rec; } sub do_node_record_auth { my ($self, $row, $node) = @_; my @spf = qw/ domain scope result /; foreach ( $node->findnodes("./auth_results/spf") ) { my %spf = map { $_ => $node->findnodes("./auth_results/spf/$_")->string_value } @spf; if ( $spf{scope} && ! $self->is_valid_spf_scope( $spf{scope} ) ) { carp "invalid scope: $spf{scope}, ignoring"; delete $spf{scope}; }; # this is for reports from ivenue.com with result=unknown if ( $spf{result} && ! $self->is_valid_spf_result( $spf{result} ) ) { carp "invalid SPF result: $spf{result}, setting to temperror"; $spf{result} = 'temperror'; }; $$row->auth_results->spf(\%spf); }; my @dkim = qw/ domain selector result human_result /; foreach ( $node->findnodes("./auth_results/dkim") ) { my %dkim = map { $_ => $node->findnodes("./auth_results/dkim/$_")->string_value } @dkim; $$row->auth_results->dkim(\%dkim); }; return; } sub do_node_record_reason { my ($self, $row, $node) = @_; # my @types = qw/ forwarded sampled_out trusted_forwarder mailing_list # local_policy other /; foreach my $r ( $node->findnodes("./row/policy_evaluated/reason") ) { my $type = $r->findnodes('./type')->string_value or next; my $comment = $r->findnodes('./comment')->string_value; $$row->row->policy_evaluated->reason( { type => $type, comment => $comment } ); } return; } 1; __END__ =pod =head1 NAME Mail::DMARC::Report::Receive - process incoming DMARC reports =head1 VERSION version 1.20260306 =head1 DESCRIPTION Receive DMARC reports and save them to the report store/database. =head1 METHODS =head2 from_imap, from_file, from_mbox These methods are called by L program, which has its own documentation and usage instructions. C accepts a file path and auto-detects the file type: =over 4 =item * B (magic bytes C<\x1f\x8b>) - decompresses with L and parses as XML =item * B (magic bytes C) - decompresses with L and parses as XML =item * B (content starting with C>) - parses directly =item * B - falls back to passing the file to from_email_simple =back C and C accept a message (or list of messages) and create an Email::Simple object from each, passing that object to from_email_simple. =head2 from_email_simple Accepts an Email::Simple message object. Returns the type of DMARC report detected or undef if no DMARC report was detected. When forensic reports are detected, no further processing is done. When an aggregate report is detected, the report details are extracted from the message body as well as the Subject field/header and attachment metadata. Parsing of the Subject and MIME metadata is necessary because the 2013 draft DMARC specification does not REQUIRE the envelope_to domain name to be included in the XML report. For example, the only way to B that the email which generated this particular report was sent to hotmail.com is to extract the envelope_to domain from the message metadata (Org Name=Microsoft, hotmail.com is not in the XML). So far, every messsage I have seen has had the envelope_to domain in one location or the other. To extract messages from the message body, the MIME attachments are decompressed and passed to L. =head2 handle_body Accepts a XML message, parsing it with XML::LibXML and XPath expressions. The parsed data is stored in a L object. When the parsing is complete, the report object is saved to the report store. =head1 AUTHORS =over 4 =item * Matt Simerson =item * Davide Migliavacca =item * Marc Bradshaw =back =head1 COPYRIGHT AND LICENSE This software is copyright (c) 2026 by Matt Simerson. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. =cut Mail-DMARC-1.20260306/lib/Mail/DMARC/Report/Send.pm000444000765000024 446315152630466 20210 0ustar00mattstaff000000000000package Mail::DMARC::Report::Send; use strict; use warnings; our $VERSION = '1.20260306'; use parent 'Mail::DMARC::Base'; use Mail::DMARC::Report::Send::SMTP; use Mail::DMARC::Report::Send::HTTP; sub http { my $self = shift; return $self->{http} if ref $self->{http}; return $self->{http} = Mail::DMARC::Report::Send::HTTP->new(); } sub smtp { my $self = shift; return $self->{smtp} if ref $self->{smtp}; return $self->{smtp} = Mail::DMARC::Report::Send::SMTP->new(); } sub too_big_report { my ( $self, $arg_ref ) = @_; my $OrgName = $self->config->{organization}{org_name}; my $Domain = $self->config->{organization}{domain}; my $ver = $Mail::DMARC::Base::VERSION || ''; # undef in author environ my $uri = $arg_ref->{uri}; my $bytes = $arg_ref->{report_bytes}; my $report_id = $arg_ref->{report_id}; my $rep_domain= $arg_ref->{report_domain}; my $date = $self->smtp->get_timestamp_rfc2822; return <<"EO_TOO_BIG" This is a 'too big' DMARC notice. The aggregate report was NOT delivered. Report-Date: $date Report-Domain: $rep_domain Report-ID: $report_id Report-Size: $bytes Submitter: $Domain Submitting-URI: $uri Submitted by $OrgName Generated with Mail::DMARC $ver EO_TOO_BIG ; } 1; __END__ =pod =head1 NAME Mail::DMARC::Report::Send - report sending dispatch class =head1 VERSION version 1.20260306 =head1 DESCRIPTION Send DMARC reports, via SMTP or HTTP. =head2 Report Sender A report sender needs to: 1. store reports 2. bundle aggregated reports 3. format report in XML 4. gzip the XML 5. deliver report to Author Domain This class and subclasses provide methods used by L. =head1 12.2.1 Email L =head1 12.2.2. HTTP L =head1 12.2.3. Other Methods Other registered URI schemes may be explicitly supported in later versions. =head1 AUTHORS =over 4 =item * Matt Simerson =item * Davide Migliavacca =item * Marc Bradshaw =back =head1 COPYRIGHT AND LICENSE This software is copyright (c) 2026 by Matt Simerson. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. =cut Mail-DMARC-1.20260306/lib/Mail/DMARC/Report/Sender.pm000444000765000024 4012115152630466 20546 0ustar00mattstaff000000000000package Mail::DMARC::Report::Sender; use strict; use warnings; use Data::Dumper; use Carp; use Encode; use Getopt::Long; use Sys::Syslog qw(:standard :macros); use Mail::DMARC::Report; use Email::Sender; use Email::Sender::Simple qw{ sendmail }; use Email::Sender::Transport::SMTP; use Email::Sender::Transport::SMTP::Persistent; use Module::Load; sub new { my $class = shift; my $args = shift; my $self = { send_delay => $args->{delay} // 5, batch_size => $args->{batch} // 1, alarm_at => $args->{timeout} // 120, syslog => $args->{syslog} // 0, smarthost => $args->{smarthost} // undef, transports_method => $args->{transports_method} // undef, transports_object => $args->{transports_object} // undef, dkim_key => $args->{dkim_key} // undef, verbose => $args->{verbose} // 0, }; return bless $self, $class; }; sub set_transports_object { my ( $self,$transports_object ) = @_; $self->{transports_object} = $transports_object; return; } sub set_transports_method { my ( $self,$transports_method ) = @_; $self->{transports_method} = $transports_method; return; # Transports method is a sub which returns # a list of transports for the given args. } # Return a list of transports to try in order. sub get_transports_for { my ( $self, $args ) = @_; # Have we passed a custom transports generation class? if ( $self->{transports_method} ) { my @transports = &{$self->{transports_method}}( $args ); return @transports; } if ( $self->{transports_object} ) { my @transports = $self->{transports_object}->get_transports_for( $args ); return @transports; } my $report = $args->{report}; my $transport_can_maybetls = $Email::Sender::VERSION > 2.0; # Do we have a smart host? if ( $report->config->{smtp}{smarthost} ) { return ($self->{smarthost}) if $self->{smarthost}; my $transport_data = { host => $report->config->{smtp}->{smarthost}, ssl => 'starttls', port => 587, helo => $report->sendit->smtp->get_helo_hostname, timeout => 32, }; $transport_data->{sasl_username} = $report->config->{smtp}->{smartuser} if $report->config->{smtp}->{smartuser}; $transport_data->{sasl_password} = $report->config->{smtp}->{smartpass} if $report->config->{smtp}->{smartpass}; my $transport = Email::Sender::Transport::SMTP::Persistent->new($transport_data); $self->{smarthost} = $transport; return ($self->{smarthost}); } my @smtp_hosts = $report->sendit->smtp->get_smtp_hosts($args->{to}); my $log_data = $args->{log_data}; my @transports; $log_data->{smtp_host} = join( ',', @smtp_hosts ); if ( Email::Sender::Transport::SMTP->can('hosts') ) { if ( $transport_can_maybetls ) { push @transports, Email::Sender::Transport::SMTP->new({ hosts => \@smtp_hosts, ssl => 'maybestarttls', port => 25, helo => $report->sendit->smtp->get_helo_hostname, timeout => 32, }); } else { push @transports, Email::Sender::Transport::SMTP->new({ hosts => \@smtp_hosts, ssl => 'starttls', port => 25, helo => $report->sendit->smtp->get_helo_hostname, timeout => 32, }); push @transports, Email::Sender::Transport::SMTP->new({ hosts => \@smtp_hosts, ssl => 0, port => 25, helo => $report->sendit->smtp->get_helo_hostname, timeout => 32, }); } } else { # We can't pass hosts to the transport, so pass a list of transports # for each possible host. if ( $transport_can_maybetls ) { foreach my $host ( @smtp_hosts ) { push @transports, Email::Sender::Transport::SMTP->new({ host => $host, ssl => 'maybestarttls', port => 25, helo => $report->sendit->smtp->get_helo_hostname, timeout => 32, }); } } else { foreach my $host ( @smtp_hosts ) { push @transports, Email::Sender::Transport::SMTP->new({ host => $host, ssl => 'starttls', port => 25, helo => $report->sendit->smtp->get_helo_hostname, timeout => 32, }); } foreach my $host ( @smtp_hosts ) { push @transports, Email::Sender::Transport::SMTP->new({ host => $host, ssl => 0, port => 25, helo => $report->sendit->smtp->get_helo_hostname, timeout => 32, }); } } } return @transports; } sub get_dkim_key { my ( $self ) = @_; my $report = $self->{report}; return $self->{dkim_key} if $self->{dkim_key}; if ( $report->config->{report_sign}->{keyfile} ) { eval { require Mail::DKIM::PrivateKey; require Mail::DKIM::Signer; require Mail::DKIM::TextWrap; }; if ( UNIVERSAL::can( 'Mail::DKIM::Signer', "new" ) ) { my $file = $report->config->{report_sign}->{keyfile}; $self->{dkim_key} = Mail::DKIM::PrivateKey->load( 'File' => $file, ); if ( ! $self->{dkim_key} ) { die "Could not load DKIM key $file"; } } else { die 'DKIM signing requested but Mail::DKIM could not be loaded. Please check that Mail::DKIM is installed.'; } $self->log_output( 'DKIM signing key loaded' ); return $self->{dkim_key}; } } sub run { my ( $self ) = @_; GetOptions ( 'verbose+' => \$self->{verbose}, 'delay=i' => \$self->{send_delay}, 'batch=i' => \$self->{batch_size}, 'timeout=i' => \$self->{alarm_at}, 'syslog+' => \$self->{syslog}, ); openlog( 'dmarc_send_reports', 'pid', LOG_MAIL ) if $self->{syslog}; $self->log_output( 'dmarc_send_reports starting up' ); $|++; my $report = Mail::DMARC::Report->new(); $self->{report} = $report; $report->verbose($self->{verbose}) if defined $self->{verbose}; # If we have defined a custom transports generation class then # load and instantiate it here. if ( $report->config->{smtp}->{transports} ) { load $report->config->{smtp}->{transports}; my $package = $report->config->{smtp}->{transports}; my $transports_object = $package->new(); $self->set_transports_object( $transports_object ); } local $SIG{'ALRM'} = sub{ die "timeout\n" }; my $batch_do = 1; # 1. get reports, one at a time REPORT: while ( my $aggregate = $report->store->next_todo() ) { eval { $self->send_report( $aggregate, $report ); }; if ( my $error = $@ ) { $self->log_output( 'error sending report: ' . $error ); } if ( $batch_do++ > $self->{batch_size} ) { $batch_do = 1; if ( $self->{send_delay} > 0 ) { print "sleeping ".$self->{send_delay} if $self->{verbose}; foreach ( 1 .. $self->{send_delay} ) { print '.' if $self->{verbose}; sleep 1; }; print "done.\n" if $self->{verbose}; } } } alarm(0); $self->log_output( 'dmarc_send_reports done' ); closelog() if $self->{syslog}; return; } # PODNAME: dmarc_send_reports # ABSTRACT: send aggregate reports sub send_report { my ( $self, $aggregate, $report ) = @_; alarm($self->{alarm_at}); $self->log_output({ 'id' => $aggregate->metadata->report_id, 'domain' => $aggregate->policy_published->domain, 'rua' => $aggregate->policy_published->rua, }); # Generate the list of report receivers my $report_receivers = eval{ $report->uri->parse( $aggregate->policy_published->rua ) }; if ( my $error = $@ ) { $self->log_output({ 'id' => $aggregate->metadata->report_id, 'error' => 'No valid ruas found - deleting report - ' . $error, }); $report->store->delete_report($aggregate->metadata->report_id); alarm(0); return; } # Check we have some receivers if ( scalar @$report_receivers == 0 ) { $self->log_output({ 'id' => $aggregate->metadata->report_id, 'error' => 'No valid ruas found - deleting report', }); $report->store->delete_report($aggregate->metadata->report_id); alarm(0); return; } # Generate the XML data and associated metadata my $xml = $aggregate->as_xml(); my $xml_compressed = $report->compress(\$xml); my $xml_compressed_bytes = length Encode::encode_utf8($xml_compressed); my $sent = 0; my $cc_sent = 0; my @too_big; URI: foreach my $receiver (@$report_receivers) { my $method = $receiver->{uri}; my $max = $receiver->{max_bytes}; if ( $max && $xml_compressed_bytes > $max ) { $self->log_output({ 'id' => $aggregate->metadata->report_id, 'info' => "skipping $method: report size ($xml_compressed_bytes) larger than $max", }); push @too_big, $method; next URI; } elsif ( 'mailto:' eq substr( $method, 0, 7 ) ) { my ($to) = ( split /:/, $method )[-1]; my $cc = $report->config->{smtp}{cc}; if ( $cc && $cc ne 'set.this@for.a.while.example.com' && ! $cc_sent ) { $self->email({ to => $cc, compressed => $xml_compressed, aggregate => \$aggregate }); $cc_sent = 1; }; $self->email({ to => $to, compressed => $xml_compressed, aggregate => \$aggregate }) and $sent++; } # http(s) sending not yet enabled in module, skip this send and # increment sent to avoid looping elsif ( 'http:' eq substr( $method, 0, 5 ) ) { #$report->sendit->http->post( $method, \$aggregate, $shrunk ); $sent++; } elsif ( 'https:' eq substr( $method, 0, 6 ) ) { #$report->sendit->http->post( $method, \$aggregate, $shrunk ); $sent++; } } if ( $sent ) { $report->store->delete_report($aggregate->metadata->report_id); } else { my $send_errors = $report->config->{smtp}->{send_errors} // 1; $self->send_too_big_email(\@too_big, $xml_compressed_bytes, $aggregate) if $send_errors; $report->store->delete_report($aggregate->metadata->report_id); }; alarm(0); return; } sub send_too_big_email { my ($self, $too_big, $bytes, $aggregate) = @_; my $report = $self->{report}; BIGURI: foreach my $uri (@$too_big) { next BIGURI if 'mailto:' ne substr( $uri, 0, 7 ); my ($to) = ( split /:/, $uri )[-1]; my $body = $report->sendit->too_big_report( { uri => $uri, report_bytes => $bytes, report_id => $aggregate->metadata->report_id, report_domain=> $aggregate->policy_published->domain, } ); my $mime_object = $report->sendit->smtp->assemble_too_big_message_object($to, $body); $self->email({ to => $to, mime => $mime_object }); }; return; }; sub email { my ($self, $args) = @_; my $to = $args->{to}; if ( !$to ) { $self->log_output({ 'error' => 'No recipient for email' }); croak 'No recipient for email'; } my $mime = $args->{mime} // undef; my $compressed = $args->{compressed} // undef; my $agg_ref = $args->{aggregate} // undef; my $report = $self->{report}; my $rid; $rid = $$agg_ref->metadata->report_id if $agg_ref; my $log_data = { deliver_to => $to, }; my $body; if ( $rid ) { my $mime_object = $report->sendit->smtp->assemble_message_object($agg_ref, $to, $compressed); $body = $mime_object->as_string; $log_data->{id} = $rid; $log_data->{to_domain} = $$agg_ref->policy_published->domain; } elsif ( $mime ) { $body = $mime->as_string; } else { croak 'No email content'; } my $dkim_key = $self->get_dkim_key(); if ( $dkim_key ) { my $dkim_algorithm = $report->config->{report_sign}{algorithm}; my $dkim_method = $report->config->{report_sign}{method}; my $dkim_domain = $report->config->{report_sign}{domain}; my $dkim_selector = $report->config->{report_sign}{selector}; eval { my $dkim = Mail::DKIM::Signer->new( Algorithm => $dkim_algorithm, Method => $dkim_method, Domain => $dkim_domain, Selector => $dkim_selector, Key => $dkim_key, ); $body =~ s/\015?\012/\015\012/g; $dkim->PRINT( $body ); $dkim->CLOSE; my $signature = $dkim->signature; $body = $signature->as_string . "\015\012" . $body; $log_data->{dkim} = 1; }; if ( my $error = $@ ) { print "DKIM Signing error\n\t$error\n" if $self->{verbose}; $log_data->{error} = 'DKIM Signing error'; $log_data->{error_detail} = $error; $self->log_output($log_data); return; } } my @transports = $self->get_transports_for({ report => $report, log_data => $log_data, to => $to, }); my $success; while ( my $transport = shift @transports ) { my $done = 0; eval { $success = sendmail( $body, { from => $report->config->{organization}{email}, to => $to, transport => $transport, } ); if ( $success ) { $log_data->{success} = $success->{message}; $done = 1; } }; if ( my $error = $@ ) { next if scalar @transports; my $code; my $message; if (ref $error eq 'Email::Sender::Failure') { $code = $error->code; $message = $error->message; } else { $code = 'error'; $message = $error; chomp $message; } $code = join( ', ', $log_data->{send_error_code}, $code ) if exists $log_data->{send_error_code}; $message = join( ', ', $log_data->{send_error}, $message ) if exists $log_data->{send_error}; $log_data->{send_error} = $message; $log_data->{send_error_code} = $code; if ( $error->code && $error->code =~ /^5/ ) { # Perma error $log_data->{deleted} = 1; $report->store->delete_report($rid); $success = 0; last; } $report->store->error($rid, $error->message); } last if $done; } $self->log_output( $log_data ); if ( $success ) { return 1; } return 0; } sub log_output { my ( $self, $args ) = @_; my $log_level = LOG_INFO; my $log_entry = ''; if ( ref $args eq 'HASH' ) { if ( $args->{'log_level'} ) { $log_level = $args->{'log_level'}; delete $args->{'log_level'}; } my @parts; foreach my $key ( sort keys %$args ) { my $value = $args->{ $key } // ''; $value =~ s/,/#044/g; # Encode commas push @parts, join( '=', $key, $value ); } $log_entry = join( ', ', @parts ); } else { $log_entry = $args; } syslog( $log_level, $log_entry ) if $self->{syslog}; print "$log_entry\n" if $self->{verbose}; return; } 1; Mail-DMARC-1.20260306/lib/Mail/DMARC/Report/Store.pm000444000765000024 375215152630466 20413 0ustar00mattstaff000000000000package Mail::DMARC::Report::Store; our $VERSION = '1.20260306'; use strict; use warnings; use Carp; use Module::Load; use parent 'Mail::DMARC::Base'; sub delete_report { my $self = shift; return $self->backend->delete_report(@_); } sub error { my $self = shift; return $self->backend->insert_error(@_); } sub retrieve { my $self = shift; return $self->backend->retrieve(@_); } sub next_todo { my $self = shift; return $self->backend->next_todo(@_); } sub retrieve_todo { my $self = shift; return $self->backend->retrieve_todo(@_); } sub backend { my $self = shift; my $backend = $self->config->{report_store}{backend}; croak "no backend defined?!" if !$backend; return $self->{$backend} if ref $self->{$backend}; my $module = "Mail::DMARC::Report::Store::$backend"; load $module; if ($@) { croak "Unable to load backend $backend: $@\n"; } return $self->{$backend} = $module->new; } 1; __END__ =pod =head1 NAME Mail::DMARC::Report::Store - persistent storage broker for reports =head1 VERSION version 1.20260306 =head1 SYNOPSIS =head1 DESCRIPTION At present, the only storage module is L. I experimented with perl's AnyDBM storage backend, but chose to deploy with SQL because a single SQL implementation supports many DBD drivers, including SQLite, MySQL, and DBD (same as AnyDBM). This Store class provides a layer of indirection, allowing one to write a new Mail::DMARC::Report::Store::MyGreatDB module, update their config file, and not alter the innards of Mail::DMARC. Much. =head1 AUTHORS =over 4 =item * Matt Simerson =item * Davide Migliavacca =item * Marc Bradshaw =back =head1 COPYRIGHT AND LICENSE This software is copyright (c) 2026 by Matt Simerson. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. =cut Mail-DMARC-1.20260306/lib/Mail/DMARC/Report/URI.pm000444000765000024 1103015152630466 17762 0ustar00mattstaff000000000000package Mail::DMARC::Report::URI; use strict; use warnings; our $VERSION = '1.20260306'; use Carp; use URI; sub new { my $class = shift; return bless {}, $class; } sub parse { my $self = shift; my $str = shift or croak "URI string is required!"; my @valids = (); foreach my $raw ( split /,/, $str ) { # warn "raw: $raw\n"; my ( $u, $size_f ) = split /!/, $raw; my $bytes = $self->get_size_limit($size_f); my $uri = URI->new($u) or do { carp "can't parse URI from $u"; next; }; my $scheme = $uri->scheme or next; if ( $scheme eq 'mailto' && lc substr( $u, 0, 7 ) eq 'mailto:' ) { push @valids, { max_bytes => $bytes, uri => $uri }; next; } if ( $scheme =~ /^http(s)?/x && lc substr( $u, 0, 4 ) eq 'http' ) { push @valids, { max_bytes => $bytes, uri => $uri }; next; } # print "invalid URI scheme: $scheme in $u\n"; # 12.1 Discovery - URI schemes found in "rua" tag that are not implemented by # a Mail Receiver MUST be ignored. } return \@valids; } sub get_size_limit { my ( $self, $size ) = @_; return 0 if !defined $size; # no limit return $size if $size =~ /^\d+$/; # no units, raw byte count # 6.3 Formal Definition # units are considered to be powers of two; a kilobyte is 2^10, a megabyte is 2^20, my $unit = lc chop $size; return $size * ( 2**10 ) if 'k' eq $unit; return $size * ( 2**20 ) if 'm' eq $unit; return $size * ( 2**30 ) if 'g' eq $unit; return $size * ( 2**40 ) if 't' eq $unit; croak "unrecognized unit ($unit) in size ($size)"; } 1; __END__ =pod =head1 NAME Mail::DMARC::Report::URI - a DMARC report URI =head1 VERSION version 1.20260306 =head1 SYNOPSIS use Mail::DMARC::URI; my $duri = Mail::DMARC::URI->new; my $uri_ref = $duri->parse('mailto:rua@example.com,mailto:rua@external.otherdomain.com'); foreach my $u ( @$uri_ref ) { my $method = $u->{uri}; my $max = $u->{max_bytes}; ... do some URI stuff ... }; =head1 DESCRIPTION defines a generic syntax for identifying a resource. The DMARC mechanism uses this as the format by which a Domain Owner specifies the destination for the two report types that are supported. The place such URIs are specified (see Section 6.2) allows a list of these to be provided. A report is to be sent to each listed URI. Mail Receivers MAY impose a limit on the number of URIs that receive reports, but MUST support at least two. The list of URIs is separated by commas (ASCII 0x2C). Each URI can have associated with it a maximum report size that may be sent to it. This is accomplished by appending an exclamation point (ASCII 0x21), followed by a maximum size indication, before a separating comma or terminating semi-colon. Thus, a DMARC URI is a URI within which any commas or exclamation points are percent-encoded per [URI], followed by an OPTIONAL exclamation point and a maximum size specification, and, if there are additional reporting URIs in the list, a comma and the next URI. For example, the URI "mailto:reports@example.com!50m" would request a report be sent via email to "reports@example.com" so long as the report payload does not exceed 50 megabytes. A formal definition is provided in Section 6.3. =head1 ABNF dmarc-uri = URI [ "!" 1*DIGIT [ "k" / "m" / "g" / "t" ] ] ; "URI" is imported from [URI]; commas (ASCII 0x2c) ; and exclamation points (ASCII 0x21) MUST be encoded URI is imported from RFC 3986: https://www.ietf.org/rfc/rfc3986.txt Only mailto, http, and https URIs are currently supported, examples: https://www.ietf.org/rfc/rfc3986.txt mailto:John.Doe@example.com With an optional size limit (see SIZE LIMIT). =head1 SIZE LIMIT A size limitation in a dmarc-uri, if provided, is interpreted as a count of units followed by an OPTIONAL unit size ("k" for kilobytes, "m" for megabytes, "g" for gigabytes, "t" for terabytes). Without a unit, the number is presumed to be a basic byte count. Note that the units are considered to be powers of two; a kilobyte is 2^10, a megabyte is 2^20, etc. =head1 AUTHORS =over 4 =item * Matt Simerson =item * Davide Migliavacca =item * Marc Bradshaw =back =head1 COPYRIGHT AND LICENSE This software is copyright (c) 2026 by Matt Simerson. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. =cut Mail-DMARC-1.20260306/lib/Mail/DMARC/Report/Aggregate000755000765000024 015152630466 20503 5ustar00mattstaff000000000000Mail-DMARC-1.20260306/lib/Mail/DMARC/Report/Aggregate/Metadata.pm000444000765000024 505215152630466 22720 0ustar00mattstaff000000000000package Mail::DMARC::Report::Aggregate::Metadata; use strict; use warnings; our $VERSION = '1.20260306'; use XML::LibXML; use parent 'Mail::DMARC::Base'; sub org_name { return $_[0]->{org_name} if 1 == scalar @_; return $_[0]->{org_name} = $_[1]; } sub email { return $_[0]->{email} if 1 == scalar @_; return $_[0]->{email} = $_[1]; } sub extra_contact_info { return $_[0]->{extra_contact_info} if 1 == scalar @_; return $_[0]->{extra_contact_info} = $_[1]; } sub report_id { return $_[0]->{report_id} if 1 == scalar @_; return $_[0]->{report_id} = $_[1]; } sub date_range { return $_[0]->{date_range} if 1 == scalar @_; # croak "invalid date_range" if ('HASH' ne ref $_->[1]); return $_[0]->{date_range} = $_[1]; } sub begin { return $_[0]->{date_range}{begin} if 1 == scalar @_; return $_[0]->{date_range}{begin} = $_[1]; } sub end { return $_[0]->{date_range}{end} if 1 == scalar @_; return $_[0]->{date_range}{end} = $_[1]; } sub error { return $_[0]->{error} if 1 == scalar @_; return push @{ $_[0]->{error} }, $_[1]; } sub uuid { return $_[0]->{uuid} if 1 == scalar @_; return $_[0]->{uuid} = $_[1]; } sub as_xml { my $self = shift; my $meta = "\t\n"; foreach my $f (qw/ org_name email extra_contact_info report_id /) { my $val = $self->$f or next; $val = XML::LibXML::Text->new( $val )->toString(); $meta .= "\t\t<$f>$val\n"; } my $begin = XML::LibXML::Text->new( $self->begin )->toString(); my $end = XML::LibXML::Text->new( $self->end )->toString(); $meta .= "\t\t\n\t\t\t" . $begin . "\n" . "\t\t\t" . $end . "\n\t\t\n"; my $errors = $self->error; if ( $errors && @$errors ) { foreach my $err ( @$errors ) { $err = XML::LibXML::Text->new( $err )->toString(); $meta .= "\t\t$err\n"; }; }; $meta .= "\t"; return $meta; } 1; __END__ =pod =head1 NAME Mail::DMARC::Report::Aggregate::Metadata - metadata section of aggregate report =head1 VERSION version 1.20260306 =head1 AUTHORS =over 4 =item * Matt Simerson =item * Davide Migliavacca =item * Marc Bradshaw =back =head1 COPYRIGHT AND LICENSE This software is copyright (c) 2026 by Matt Simerson. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. =cut Mail-DMARC-1.20260306/lib/Mail/DMARC/Report/Aggregate/Record.pm000444000765000024 431115152630466 22413 0ustar00mattstaff000000000000package Mail::DMARC::Report::Aggregate::Record; our $VERSION = '1.20260306'; use strict; use warnings; use Carp; use parent 'Mail::DMARC::Base'; require Mail::DMARC::Report::Aggregate::Record::Identifiers; require Mail::DMARC::Report::Aggregate::Record::Auth_Results; require Mail::DMARC::Report::Aggregate::Record::Row; sub new { my ( $class, @args ) = @_; croak "invalid arguments" if @args % 2; my $self = bless {}, $class; return $self if 0 == scalar @args; my %args = @args; foreach my $key ( keys %args ) { $self->$key( $args{$key} ); } return $self; } sub identifiers { my ($self, @args) = @_; if ( !scalar @args ) { return $self->{identifiers} if $self->{identifiers}; } if ('HASH' eq ref $args[0]) { @args = %{ $args[0] }; } return $self->{identifiers} = Mail::DMARC::Report::Aggregate::Record::Identifiers->new(@args); } sub auth_results { my ($self, @args) = @_; if ( !scalar @args ) { return $self->{auth_results} if $self->{auth_results}; } if ( 1 == scalar @args && 'HASH' eq ref $args[0] ) { @args = %{ $args[0] }; } return $self->{auth_results} = Mail::DMARC::Report::Aggregate::Record::Auth_Results->new(@args); } sub row { my ($self, @args) = @_; if ( 0 == scalar @args ) { return $self->{row} if $self->{row}; } if ( 1 == scalar @args && 'HASH' eq ref $args[0] ) { @args = %{ $args[0] }; } return $self->{row} = Mail::DMARC::Report::Aggregate::Record::Row->new(@args); } 1; __END__ =pod =head1 NAME Mail::DMARC::Report::Aggregate::Record - record section of aggregate report =head1 VERSION version 1.20260306 =head1 DESCRIPTION An aggregate report record, with object methods for identifiers, auth_results, and each row. =head1 AUTHORS =over 4 =item * Matt Simerson =item * Davide Migliavacca =item * Marc Bradshaw =back =head1 COPYRIGHT AND LICENSE This software is copyright (c) 2026 by Matt Simerson. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. =cut Mail-DMARC-1.20260306/lib/Mail/DMARC/Report/Aggregate/Record000755000765000024 015152630466 21721 5ustar00mattstaff000000000000Mail-DMARC-1.20260306/lib/Mail/DMARC/Report/Aggregate/Record/Auth_Results.pm000444000765000024 443515152630466 25044 0ustar00mattstaff000000000000package Mail::DMARC::Report::Aggregate::Record::Auth_Results; our $VERSION = '1.20260306'; use strict; use warnings; use Carp; require Mail::DMARC::Report::Aggregate::Record::Auth_Results::SPF; require Mail::DMARC::Report::Aggregate::Record::Auth_Results::DKIM; sub new { my ( $class, @args ) = @_; croak "invalid arguments" if @args % 2; my $self = bless { spf => [], dkim => [] }, $class; return $self if 0 == scalar @args; my %args = @args; foreach my $key ( keys %args ) { $self->$key( $args{$key} ); } return $self; } sub spf { my ($self, @args) = @_; return $self->{spf} if 0 == scalar @args; # one shot if (1 == scalar @args && ref $args[0] eq 'ARRAY') { #warn "SPF one shot"; my $iter = 0; foreach my $d ( @{ $args[0] }) { $self->{spf}->[$iter] = Mail::DMARC::Report::Aggregate::Record::Auth_Results::SPF->new($d); $iter++; } return $self->{spf}; } #warn "SPF iterative"; push @{ $self->{spf} }, Mail::DMARC::Report::Aggregate::Record::Auth_Results::SPF->new(@args); return $self->{spf}; } sub dkim { my ($self, @args) = @_; return $self->{dkim} if 0 == scalar @args; if (1 == scalar @args && ref $args[0] eq 'ARRAY') { #warn "dkim one shot"; my $iter = 0; foreach my $d ( @{ $args[0] }) { $self->{dkim}->[$iter] = Mail::DMARC::Report::Aggregate::Record::Auth_Results::DKIM->new($d); $iter++; } return $self->{dkim}; } #warn "dkim iterative"; push @{ $self->{dkim}}, Mail::DMARC::Report::Aggregate::Record::Auth_Results::DKIM->new(@args); return $self->{dkim}; } 1; __END__ =pod =head1 NAME Mail::DMARC::Report::Aggregate::Record::Auth_Results - auth_results section of a DMARC aggregate record =head1 VERSION version 1.20260306 =head1 AUTHORS =over 4 =item * Matt Simerson =item * Davide Migliavacca =item * Marc Bradshaw =back =head1 COPYRIGHT AND LICENSE This software is copyright (c) 2026 by Matt Simerson. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. =cut Mail-DMARC-1.20260306/lib/Mail/DMARC/Report/Aggregate/Record/Identifiers.pm000444000765000024 240215152630466 24657 0ustar00mattstaff000000000000package Mail::DMARC::Report::Aggregate::Record::Identifiers; our $VERSION = '1.20260306'; use strict; use warnings; use Carp; sub new { my ( $class, @args ) = @_; croak "invalid arguments" if @args % 2; my %args = @args; my $self = bless {}, $class; foreach my $key ( keys %args ) { $self->$key( $args{$key} ); } return $self; } sub envelope_to { return $_[0]->{envelope_to} if 1 == scalar @_; return $_[0]->{envelope_to} = $_[1]; } sub envelope_from { return $_[0]->{envelope_from} if 1 == scalar @_; return $_[0]->{envelope_from} = $_[1]; } sub header_from { return $_[0]->{header_from} if 1 == scalar @_; return $_[0]->{header_from} = $_[1]; } 1; __END__ =pod =head1 NAME Mail::DMARC::Report::Aggregate::Record::Identifiers - identifiers section of a DMARC aggregate record =head1 VERSION version 1.20260306 =head1 AUTHORS =over 4 =item * Matt Simerson =item * Davide Migliavacca =item * Marc Bradshaw =back =head1 COPYRIGHT AND LICENSE This software is copyright (c) 2026 by Matt Simerson. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. =cut Mail-DMARC-1.20260306/lib/Mail/DMARC/Report/Aggregate/Record/Row.pm000444000765000024 307715152630466 23172 0ustar00mattstaff000000000000package Mail::DMARC::Report::Aggregate::Record::Row; our $VERSION = '1.20260306'; use strict; use warnings; use Carp; require Mail::DMARC::Report::Aggregate::Record::Row::Policy_Evaluated; sub new { my ( $class, @args ) = @_; croak "invalid arguments" if @args % 2; my %args = @args; my $self = bless {}, $class; foreach my $key ( keys %args ) { $self->$key( $args{$key} ); } return $self; } sub source_ip { return $_[0]->{source_ip} if 1 == scalar @_; return $_[0]->{source_ip} = $_[1]; } sub policy_evaluated { my ($self, @args) = @_; if (0 == scalar @args) { return $self->{policy_evaluated} if $self->{policy_evaluated}; } if (1 == scalar @args) { if ('HASH' eq ref $args[0]) { @args = %{ $args[0] }; } } return $self->{policy_evaluated} = Mail::DMARC::Report::Aggregate::Record::Row::Policy_Evaluated->new(@args); } sub count { return $_[0]->{count} if 1 == scalar @_; return $_[0]->{count} = $_[1]; } 1; __END__ =pod =head1 NAME Mail::DMARC::Report::Aggregate::Record::Row - row section of a DMARC aggregate record =head1 VERSION version 1.20260306 =head1 AUTHORS =over 4 =item * Matt Simerson =item * Davide Migliavacca =item * Marc Bradshaw =back =head1 COPYRIGHT AND LICENSE This software is copyright (c) 2026 by Matt Simerson. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. =cut Mail-DMARC-1.20260306/lib/Mail/DMARC/Report/Aggregate/Record/Auth_Results000755000765000024 015152630466 24343 5ustar00mattstaff000000000000Mail-DMARC-1.20260306/lib/Mail/DMARC/Report/Aggregate/Record/Auth_Results/DKIM.pm000444000765000024 412215152630466 25561 0ustar00mattstaff000000000000package Mail::DMARC::Report::Aggregate::Record::Auth_Results::DKIM; our $VERSION = '1.20260306'; use strict; use Carp; sub new { my ( $class, @args ) = @_; croak "missing arguments" if 0 == scalar @args; my $self = bless {}, $class; # a bare hash return $self->_from_hash(@args) if scalar @args > 1; my $dkim = shift @args; croak "dkim argument not a ref" if ! ref $dkim; return $dkim if ref $dkim eq $class; # been here before... return $self->_from_hashref($dkim) if 'HASH' eq ref $dkim; croak "invalid dkim argument"; } sub domain { return $_[0]->{domain} if 1 == scalar @_; return $_[0]->{domain} = $_[1]; } sub selector { return $_[0]->{selector} if 1 == scalar @_; return $_[0]->{selector} = $_[1]; } sub result { return $_[0]->{result} if 1 == scalar @_; croak "invalid DKIM result" if ! grep { $_ eq $_[1] } qw/ pass fail neutral none permerror policy temperror /; return $_[0]->{result} = $_[1]; } sub human_result { return $_[0]->{human_result} if 1 == scalar @_; return $_[0]->{human_result} = $_[1]; } sub _from_hash { my ($self, %args) = @_; foreach my $key ( keys %args ) { $self->$key( $args{$key} ); } $self->is_valid; return $self; } sub _from_hashref { return $_[0]->_from_hash(%{ $_[1] }); } sub is_valid { my $self = shift; foreach my $f (qw/ domain result /) { if ( ! defined $self->{$f} ) { croak "DKIM value $f is required!"; } } return; } 1; __END__ =pod =head1 NAME Mail::DMARC::Report::Aggregate::Record::Auth_Results::DKIM - auth_results/dkim section of a DMARC aggregate record =head1 VERSION version 1.20260306 =head1 AUTHORS =over 4 =item * Matt Simerson =item * Davide Migliavacca =item * Marc Bradshaw =back =head1 COPYRIGHT AND LICENSE This software is copyright (c) 2026 by Matt Simerson. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. =cut Mail-DMARC-1.20260306/lib/Mail/DMARC/Report/Aggregate/Record/Auth_Results/SPF.pm000444000765000024 441415152630466 25471 0ustar00mattstaff000000000000package Mail::DMARC::Report::Aggregate::Record::Auth_Results::SPF; our $VERSION = '1.20260306'; use strict; use Carp; use parent 'Mail::DMARC::Base'; sub new { my ( $class, @args ) = @_; my $self = bless {}, $class; if (0 == scalar @args) { return $self; } # a bare hash return $self->_from_hash(@args) if scalar @args > 1; my $spf = shift @args; return $spf if ref $spf eq $class; return $self->_from_hashref($spf) if 'HASH' eq ref $spf; croak "invalid spf argument"; } sub domain { return $_[0]->{domain} if 1 == scalar @_; return $_[0]->{domain} = lc $_[1]; } sub result { return $_[0]->{result} if 1 == scalar @_; croak if !$_[0]->is_valid_spf_result( $_[1] ); return $_[0]->{result} = $_[1]; } sub scope { return $_[0]->{scope} if 1 == scalar @_; croak if ! $_[0]->is_valid_spf_scope( $_[1] ); return $_[0]->{scope} = $_[1]; } sub _from_hash { my ($self, %args) = @_; foreach my $key ( keys %args ) { # scope is frequently absent on received reports next if ($key eq 'scope' && !$args{$key}); $self->$key( $args{$key} ); } $self->is_valid; return $self; } sub _from_hashref { return $_[0]->_from_hash(%{ $_[1] }); } sub is_valid { my $self = shift; foreach my $f (qw/ domain result scope /) { next if $self->{$f}; if ($f ne 'scope') { # quite a few DMARC reporters don't include scope warn "SPF $f is required but missing!\n"; } return 0; } if ( $self->{result} =~ /^pass$/i && !$self->{domain} ) { warn "SPF pass MUST include the RFC5321.MailFrom domain!\n"; return 0; } return 1; } 1; __END__ =pod =head1 NAME Mail::DMARC::Report::Aggregate::Record::Auth_Results::SPF - auth_results/spf section of a DMARC aggregate record =head1 VERSION version 1.20260306 =head1 AUTHORS =over 4 =item * Matt Simerson =item * Davide Migliavacca =item * Marc Bradshaw =back =head1 COPYRIGHT AND LICENSE This software is copyright (c) 2026 by Matt Simerson. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. =cut Mail-DMARC-1.20260306/lib/Mail/DMARC/Report/Aggregate/Record/Row000755000765000024 015152630466 22470 5ustar00mattstaff000000000000Mail-DMARC-1.20260306/lib/Mail/DMARC/Report/Aggregate/Record/Row/Policy_Evaluated.pm000444000765000024 312715152630466 26417 0ustar00mattstaff000000000000package Mail::DMARC::Report::Aggregate::Record::Row::Policy_Evaluated; our $VERSION = '1.20260306'; use strict; use warnings; use Carp; sub new { my ( $class, @args ) = @_; croak "invalid arguments" if @args % 2; my %args = @args; my $self = bless { reason => [] }, $class; foreach my $key ( keys %args ) { $self->$key( $args{$key} ); } return $self; } sub disposition { return $_[0]->{disposition} if 1 == scalar @_; croak "invalid disposition ($_[1]" if 0 == grep {/^$_[1]$/ix} qw/ reject quarantine none /; return $_[0]->{disposition} = $_[1]; } sub dkim { return $_[0]->{dkim} if 1 == scalar @_; return $_[0]->{dkim} = $_[1]; } sub spf { return $_[0]->{spf} if 1 == scalar @_; return $_[0]->{spf} = $_[1]; } sub reason { return $_[0]->{reason} if 1 == scalar @_; if ('ARRAY' eq ref $_[1]) { # one shot argument $_[0]->{reason} = $_[1]; } else { push @{ $_[0]->{reason} }, $_[1]; } return $_[0]->{reason}; } 1; __END__ =pod =head1 NAME Mail::DMARC::Report::Aggregate::Record::Row::Policy_Evaluated - row/policy_evaluated section of a DMARC aggregate record =head1 VERSION version 1.20260306 =head1 AUTHORS =over 4 =item * Matt Simerson =item * Davide Migliavacca =item * Marc Bradshaw =back =head1 COPYRIGHT AND LICENSE This software is copyright (c) 2026 by Matt Simerson. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. =cut Mail-DMARC-1.20260306/lib/Mail/DMARC/Report/Send000755000765000024 015152630466 17506 5ustar00mattstaff000000000000Mail-DMARC-1.20260306/lib/Mail/DMARC/Report/Send/HTTP.pm000444000765000024 377215152630466 20771 0ustar00mattstaff000000000000package Mail::DMARC::Report::Send::HTTP; use strict; use warnings; our $VERSION = '1.20260306'; use Carp; #use Data::Dumper; #use HTTP::Tiny; # a possibility #use Net::HTTP; # lazy loaded in 'post' use parent 'Mail::DMARC::Base'; sub post { my ( $self, $uri, $report, $gz ) = @_; carp "http send feature not complete!"; return; ## no critic (Unreachable,Eval) # TODO: test against real HTTP server, validate HTTP response eval "require Net::HTTP" or return; my $ver = $Mail::DMARC::Base::VERSION; my $s = Net::HTTP->new( Host => $uri->host ) or croak $@; $s->write_request( POST => $uri->path, 'User-Agent' => "Mail::DMARC/$ver" ); my ( $code, $mess, %h ) = $s->read_response_headers; while (1) { my $buf; my $n = $s->read_entity_body( $buf, 1024 ); croak "read failed: $!" unless defined $n; last unless $n; print $buf; return 1; } return 0; } 1; __END__ =pod =head1 NAME Mail::DMARC::Report::Send::HTTP - utility methods to send reports by HTTP =head1 VERSION version 1.20260306 =head1 12.2.2. HTTP Where an "http" or "https" method is requested in a Domain Owner's URI list, the Mail Receiver MAY encode the data using the "application/gzip" media type ([GZIP]) or MAY send the Appendix C data uncompressed or unencoded. The header portion of the POST or PUT request SHOULD contain a Subject field as described in Section 12.2.1. HTTP permits the use of Content-Transfer-Encoding to upload gzip content using the POST or PUT instruction after translating the content to 7-bit ASCII. =head1 AUTHORS =over 4 =item * Matt Simerson =item * Davide Migliavacca =item * Marc Bradshaw =back =head1 COPYRIGHT AND LICENSE This software is copyright (c) 2026 by Matt Simerson. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. =cut Mail-DMARC-1.20260306/lib/Mail/DMARC/Report/Send/SMTP.pm000444000765000024 2144015152630466 21005 0ustar00mattstaff000000000000package Mail::DMARC::Report::Send::SMTP; use strict; use warnings; our $VERSION = '1.20260306'; use Carp; use English '-no_match_vars'; use Email::MIME; #use Mail::Sender; # something to consider use Sys::Hostname; use POSIX; use parent 'Mail::DMARC::Base'; sub get_domain_mx { my ( $self, $domain ) = @_; print "getting MX for $domain\n"; my $query; eval { $query = $self->get_resolver->send( $domain, 'MX' ) or return []; } or print $@; if ( ! $query ) { print "\terror:\n\t$@"; return []; }; my @mx; for my $rr ( $query->answer ) { next if $rr->type ne 'MX'; push @mx, { pref => $rr->preference, addr => $rr->exchange }; print $rr->exchange if $self->verbose; } if ( $self->verbose ) { print "found " . scalar @mx . "MX exchanges\n"; }; return \@mx; } sub get_smtp_hosts { my $self = shift; my $email = shift or croak "missing email!"; my ($domain) = ( split /@/, $email )[-1]; my @mx = map { $_->{addr} } sort { $a->{pref} <=> $b->{pref} } @{ $self->get_domain_mx($domain) }; push @mx, $domain; print "\tfound " . scalar @mx . " MX for $email\n" if $self->verbose; return @mx; } sub get_subject { my ( $self, $agg_ref ) = @_; my $rid = $$agg_ref->metadata->report_id || $self->time; my $id = POSIX::strftime( "%Y.%m.%d.", localtime $self->time ) . $rid; my $us = $self->config->{organization}{domain}; if ($us eq 'example.com') { die "Please update mail-dmarc.ini"; } my $pol_dom = $$agg_ref->policy_published->domain; return "Report Domain: $pol_dom Submitter: $us Report-ID:$id"; } sub human_summary { my ( $self, $agg_ref ) = @_; my $records = scalar @{ $$agg_ref->{record} }; my $OrgName = $self->config->{organization}{org_name}; my $pass = grep { 'pass' eq $_->{row}{policy_evaluated}{dkim} || 'pass' eq $_->{row}{policy_evaluated}{spf} } @{ $$agg_ref->{record} }; my $fail = grep { 'pass' ne $_->{row}{policy_evaluated}{dkim} && 'pass' ne $_->{row}{policy_evaluated}{spf} } @{ $$agg_ref->{record} }; my $ver = $Mail::DMARC::Base::VERSION || ''; # undef in author environ my $from = $$agg_ref->{policy_published}{domain} or croak; return <<"EO_REPORT" This is a DMARC aggregate report for $from $records records. $pass passed. $fail failed. Submitted by $OrgName Generated with Mail::DMARC $ver EO_REPORT ; } sub get_filename { my ( $self, $agg_ref ) = @_; # 2013 DMARC Draft, 12.2.1 Email # # filename = receiver "!" policy-domain "!" begin-timestamp "!" # end-timestamp [ "!" unique-id ] "." extension # filename="mail.receiver.example!example.com!1013662812!1013749130.gz" return join( '!', $self->config->{organization}{domain}, $$agg_ref->policy_published->domain, $$agg_ref->metadata->begin, $$agg_ref->metadata->end, $$agg_ref->metadata->report_id || $self->time, ) . '.xml'; } sub assemble_too_big_message_object { my ( $self, $to, $body ) = @_; my @parts = Email::MIME->create( attributes => { content_type => "text/plain", disposition => "inline", charset => "US-ASCII", }, body => $body, ) or croak "unable to add body!"; my $email = Email::MIME->create( header_str => [ From => $self->config->{organization}{email}, To => $to, Date => $self->get_timestamp_rfc2822, Subject => 'DMARC too big report', ], parts => [@parts], ) or croak "unable to assemble message\n"; return $email; } sub assemble_message_object { my ( $self, $agg_ref, $to, $shrunk ) = @_; my $filename = $self->get_filename($agg_ref); # WARNING: changes made here MAY affect Send::compress. Check it! # my $cf = ( time > 1372662000 ) ? 'gzip' : 'zip'; # gz after 7/1/13 my $cf = 'gzip'; $filename .= $cf eq 'gzip' ? '.gz' : '.zip'; my @parts = Email::MIME->create( attributes => { content_type => "text/plain", disposition => "inline", charset => "US-ASCII", }, body => $self->human_summary( $agg_ref ), ) or croak "unable to add body!"; push @parts, Email::MIME->create( attributes => { filename => $filename, content_type => "application/$cf", encoding => "base64", name => $filename, }, body => $shrunk, ) or croak "unable to add report!"; my $email = Email::MIME->create( header_str => [ From => $self->config->{organization}{email}, To => $to, Date => $self->get_timestamp_rfc2822, Subject => $self->get_subject( $agg_ref ), ], parts => [@parts], ) or croak "unable to assemble message\n"; $email->header_str_set( 'Message-ID' => $self->get_message_id ); return $email; } sub get_timestamp_rfc2822 { my ($self, @args) = @_; my @ts = scalar @args ? @args : localtime $self->time; my $locale = setlocale(LC_CTYPE); setlocale(LC_ALL, 'C'); my $timestamp = POSIX::strftime( '%a, %d %b %Y %H:%M:%S %z', @ts ); setlocale(LC_ALL, $locale); return $timestamp; } sub get_helo_hostname { my $self = shift; my $host = $self->config->{smtp}{hostname}; return $host if $host && $host ne 'mail.example.com'; return Sys::Hostname::hostname; }; sub get_message_id { my $self = shift; my $host = $self->get_helo_hostname; my ($ss, $mm, $hh, $mday, $mon, $year, $wday, $yday, $isdst) = localtime(time); # Generate a "random" Message-ID return sprintf("<%04d%02d%02d%02d%02d.%s\@%s>", $year + 1900, $mon + 1, $mday, $hh, $mm, rand(), $host ); } 1; __END__ =pod =head1 NAME Mail::DMARC::Report::Send::SMTP - utility methods for sending reports via SMTP =head1 VERSION version 1.20260306 =head2 SUBJECT FIELD The RFC5322.Subject field for individual report submissions SHOULD conform to the following ABNF: dmarc-subject = %x52.65.70.6f.72.74 1*FWS ; "Report" %x44.6f.6d.61.69.6e.3a 1*FWS ; "Domain:" domain-name 1*FWS ; from RFC6376 %x53.75.62.6d.69.74.74.65.72.3a ; "Submitter:" 1*FWS domain-name 1*FWS %x52.65.70.6f.72.74.2d.49.44.3a ; "Report-ID:" msg-id ; from RFC5322 The first domain-name indicates the DNS domain name about which the report was generated. The second domain-name indicates the DNS domain name representing the Mail Receiver generating the report. The purpose of the Report-ID: portion of the field is to enable the Domain Owner to identify and ignore duplicate reports that might be sent by a Mail Receiver. =head1 12.2.1 Email In the case of a "mailto" URI, the Mail Receiver SHOULD communicate reports using the method described in [STARTTLS]. The message generated by the Mail Receiver must be a [MIME] formatted [MAIL] message. The aggregate report itself MUST be included in one of the parts of the message. A human-readable portion MAY be included as a MIME part (such as a text/plain part). The aggregate data MUST be an XML file subjected to GZIP compression. The aggregate data MUST be present using the media type "application/ gzip", and the filenames SHOULD be constructed using the following ABNF: filename = receiver "!" policy-domain "!" begin-timestamp "!" end-timestamp [ "!" unique-id ] "." extension unique-id = token ; "token" is imported from [MIME] receiver = domain ; imported from [MAIL] policy-domain = domain begin-timestamp = 1*DIGIT ; seconds since 00:00:00 UTC January 1, 1970 ; indicating start of the time range contained ; in the report end-timestamp = 1*DIGIT ; seconds since 00:00:00 UTC January 1, 1970 ; indicating end of the time range contained ; in the report extension = "xml" / "gzip" For the GZIP file itself, the extension MUST be "gz"; for the XML report, the extension MUST be "xml". =head1 AUTHORS =over 4 =item * Matt Simerson =item * Davide Migliavacca =item * Marc Bradshaw =back =head1 COPYRIGHT AND LICENSE This software is copyright (c) 2026 by Matt Simerson. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. =cut Mail-DMARC-1.20260306/lib/Mail/DMARC/Report/Store000755000765000024 015152630466 17711 5ustar00mattstaff000000000000Mail-DMARC-1.20260306/lib/Mail/DMARC/Report/Store/SQL.pm000444000765000024 5426515152630466 21077 0ustar00mattstaff000000000000package Mail::DMARC::Report::Store::SQL; our $VERSION = '1.20260306'; use strict; use warnings; use Carp; use Data::Dumper; use DBIx::Simple; use File::ShareDir; use Mail::DMARC::Report::Store::SQL::Grammars::MySQL; use Mail::DMARC::Report::Store::SQL::Grammars::SQLite; use Mail::DMARC::Report::Store::SQL::Grammars::PostgreSQL; use parent 'Mail::DMARC::Base'; use Mail::DMARC::Report::Aggregate; sub save_aggregate { my ( $self, $agg ) = @_; $self->db_connect(); croak "policy_published must be a Mail::DMARC::Policy object" if 'Mail::DMARC::Policy' ne ref $agg->policy_published; #warn Dumper($meta); ## no critic (Carp) foreach my $f ( qw/ org_name email begin end / ) { croak "meta field $f required" if ! $agg->metadata->$f; } my $rid = $self->get_report_id( $agg ) or croak "failed to create report!"; # on 6/8/2013, Microsoft spat out a bunch of reports with zero records. if ( ! $agg->record ) { warn "\ta report with ZERO records! Illegal.\n"; ## no critic (Carp) return $rid; }; foreach my $rec ( @{ $agg->record } ) { $self->insert_agg_record($rid, $rec); }; return $rid; } sub retrieve { my ( $self, %args ) = @_; my $query = $self->grammar->select_report_query; my @params; if ( $args{rid} ) { $query .= $self->grammar->and_arg('r.id'); push @params, $args{rid}; }; if ( $args{begin} ) { $query .= $self->grammar->and_arg('r.begin', '>='); push @params, $args{begin}; }; if ( $args{end} ) { $query .= $self->grammar->and_arg('r.end', '<='); push @params, $args{end}; }; if ( $args{author} ) { my ( $op, $val ) = $self->_negate_arg( $args{author} ); $query .= $self->grammar->and_arg('a.org_name', $op); push @params, $val; }; if ( $args{from_domain} ) { my ( $op, $val ) = $self->_negate_arg( $args{from_domain} ); $query .= $self->grammar->and_arg('fd.domain', $op); push @params, $val; }; my $sort_by = lc( $args{sort_by} || 'rid' ); $sort_by = 'rid' if $sort_by eq 'id'; my %allowed_sort = map { $_ => 1 } qw( rid author from_domain begin end ); $sort_by = 'rid' if !$allowed_sort{$sort_by}; my $sort_order = uc( $args{sort_order} || 'DESC' ); $sort_order = 'DESC' if $sort_order ne 'ASC' && $sort_order ne 'DESC'; $query .= $self->grammar->order_by( $sort_by, $sort_order ); if ( defined $args{limit} ) { croak "limit must be a positive integer" if $args{limit} !~ /^\d+$/ || $args{limit} < 1; $query .= $self->grammar->limit( $args{limit} ); } my $reports = $self->query( $query, \@params ); foreach (@$reports ) { $_->{begin} = join(" ", split(/T/, $self->epoch_to_iso( $_->{begin} ))); $_->{end} = join(" ", split(/T/, $self->epoch_to_iso( $_->{end} ))); }; return $reports; } sub _negate_arg { my ( $self, $val ) = @_; if ( substr($val, 0, 1) eq '!' ) { return ( '!=', substr($val, 1) ); } return ( '=', $val ); } sub next_todo { my ( $self ) = @_; if ( ! exists $self->{ _todo_list } ) { $self->{_todo_list} = $self->query( $self->grammar->select_todo_query, [ $self->time ] ); return if ! $self->{_todo_list}; } my $next_todo = shift @{ $self->{_todo_list} }; if ( ! $next_todo ) { delete $self->{_todo_list}; return; } my $agg = Mail::DMARC::Report::Aggregate->new(); $self->populate_agg_metadata( \$agg, \$next_todo ); my $pp = $self->get_report_policy_published( $next_todo->{rid} ); $pp->{domain} = $next_todo->{from_domain}; $agg->policy_published( Mail::DMARC::Policy->new( %$pp ) ); $self->populate_agg_records( \$agg, $next_todo->{rid} ); return $agg; } sub retrieve_todo { my ( $self, @args ) = @_; # this method extracts the data from the SQL tables and populates a # list of Aggregate report objects with them. my $reports = $self->query( $self->grammar->select_todo_query, [ $self->time ] ); my @reports_todo; return \@reports_todo if ! scalar @$reports; foreach my $report ( @{ $reports } ) { my $agg = Mail::DMARC::Report::Aggregate->new(); $self->populate_agg_metadata( \$agg, \$report ); my $pp = $self->get_report_policy_published( $report->{rid} ); $pp->{domain} = $report->{from_domain}; $agg->policy_published( Mail::DMARC::Policy->new( %$pp ) ); $self->populate_agg_records( \$agg, $report->{rid} ); push @reports_todo, $agg; } return \@reports_todo; } sub delete_report { my $self = shift; my $report_id = shift or croak "missing report ID"; print "deleting report $report_id\n" if $self->verbose; # deletes with FK don't cascade in SQLite? Clean each table manually my $rows = $self->query( $self->grammar->report_record_id, [$report_id] ); my @row_ids = map { $_->{id} } @$rows; if (scalar @row_ids) { foreach my $table (qw/ report_record_spf report_record_dkim report_record_reason /) { print "deleting $table rows " . join(',', @row_ids) . "\n" if $self->verbose; eval { $self->query( $self->grammar->delete_from_where_record_in($table), \@row_ids); }; # warn $@ if $@; } } foreach my $table (qw/ report_policy_published report_record report_error /) { print "deleting $table rows for report $report_id\n" if $self->verbose; eval { $self->query( $self->grammar->delete_from_where_report($table), [$report_id] ); }; # warn $@ if $@; } # In MySQL, where FK constraints DO cascade, this is the only query needed $self->query( $self->grammar->delete_report, [$report_id] ); return 1; } sub get_domain_id { my ( $self, $domain ) = @_; croak "missing domain calling " . ( caller(0) )[3] if !$domain; my $r = $self->query( $self->grammar->select_domain_id, [$domain] ); if ( $r && scalar @$r ) { return $r->[0]{id}; } return $self->query( $self->grammar->insert_domain, [$domain]); } sub get_author_id { my ( $self, $meta ) = @_; croak "missing author name" if !$meta->org_name; my $r = $self->query( $self->grammar->select_author_id, [ $meta->org_name ] ); if ( $r && scalar @$r ) { return $r->[0]{id}; } carp "missing email" if !$meta->email; return $self->query( $self->grammar->insert_author, [ $meta->org_name, $meta->email, $meta->extra_contact_info ] ); } sub get_report_id { my ( $self, $aggr ) = @_; my $meta = $aggr->metadata; my $pol = $aggr->policy_published; # check if report exists my $author_id = $self->get_author_id( $meta ) or croak; my $from_dom_id = $self->get_domain_id( $pol->domain ) or croak; my $ids; if ( $meta->report_id ) { # reports arriving via the wire will have an author ID & report ID $ids = $self->query( $self->grammar->select_report_id, [ $meta->report_id, $author_id ] ); } else { # Reports submitted by our local MTA will not have a report ID # They aggregate on the From domain, where the DMARC policy was discovered $ids = $self->query( $self->grammar->select_id_with_end, [ $from_dom_id, $self->time, $author_id ] ); }; if ( scalar @$ids ) { # report already exists return $self->{report_id} = $ids->[0]{id}; } my $rid = $self->{report_id} = $self->query( $self->grammar->insert_report, [ $from_dom_id, $meta->begin, $meta->end, $author_id, $meta->uuid ] ) or return; $self->insert_policy_published( $rid, $pol ); return $rid; } sub get_report { my ($self,@args) = @_; croak "invalid parameters" if @args % 2; my %args = @args; my @known = qw/ r.id a.org_name fd.domain r.begin r.end /; my %known = map { $_ => 1 } @known; my $where = ''; my @where_params; # Per-column LIKE searches for my $pair ( [ search_domain => 'fd.domain' ], [ search_author => 'a.org_name' ] ) { my ($param, $col_name) = @$pair; next unless $args{$param}; my $safe = $args{$param}; $safe =~ s/([%_!])/!$1/g; # escape LIKE metacharacters using ! $where .= " AND $col_name LIKE ? ESCAPE '!'"; push @where_params, '%' . $safe . '%'; } foreach my $known ( @known ) { next if ! defined $args{$known}; $where .= $self->grammar->and_arg($known); push @where_params, $args{$known}; } my $total_recs = $self->dbix->query($self->grammar->count_reports)->list; my $filtered_recs = $total_recs; if ( $where ) { $filtered_recs = $self->dbix->query( $self->grammar->count_filtered_report_query . $where, @where_params )->list; } my $order = ''; if ( $args{sort_col} && $known{$args{sort_col}} ) { if ( $args{sort_dir} ) { $order = $self->grammar->order_by($args{sort_col}, $args{sort_dir} eq 'desc' ? ' DESC' : ' ASC'); }; }; my $query = $self->grammar->select_report_query . $where . $order; my @params = @where_params; if ( $args{length} ) { my $start = $args{start} || 0; $start = 0 if $start < 0; $query .= $self->grammar->limit_args(2); push @params, $start, $args{length}; }; # warn "query: $query\n" . join(", ", @params) . "\n"; my $reports = $self->query($query, \@params); foreach (@$reports ) { $_->{begin} = $self->epoch_to_iso( $_->{begin} ); $_->{end} = $self->epoch_to_iso( $_->{end} ); }; return { recordsTotal => $total_recs, recordsFiltered => $filtered_recs, data => $reports, }; } sub get_report_policy_published { my ($self, $rid) = @_; my $pp = $self->query($self->grammar->select_report_policy_published, [ $rid ] )->[0]; $pp->{p} ||= 'none'; $pp = Mail::DMARC::Policy->new( v=>'DMARC1', %$pp ); return $pp; } sub get_rr { my ($self, @args) = @_; croak "invalid parameters" if @args % 2; my %args = @args; # warn Dumper(\%args); croak "missing report ID (rid)!" if ! defined $args{rid}; my $rows = $self->query( $self->grammar->select_rr_query, [ $args{rid} ] ); foreach ( @$rows ) { $_->{source_ip} = $self->any_inet_ntop( $_->{source_ip} ) if $self->grammar->language ne 'postgresql'; $_->{reasons} = $self->query($self->grammar->select_report_reason, [ $_->{id} ] ); }; return { data => $rows, }; } sub populate_agg_metadata { my ($self, $agg_ref, $report_ref) = @_; $$agg_ref->metadata->report_id( $$report_ref->{rid} ); foreach my $f ( qw/ org_name email extra_contact_info / ) { $$agg_ref->metadata->$f( $self->config->{organization}{$f} ); }; foreach my $f ( qw/ begin end / ) { $$agg_ref->metadata->$f( $$report_ref->{$f} ); }; my $errors = $self->query($self->grammar->select_report_error, [ $$report_ref->{rid} ] ); foreach ( @$errors ) { $$agg_ref->metadata->error( $_->{error} ); }; return 1; } sub populate_agg_records { my ($self, $agg_ref, $rid) = @_; my $recs = $self->query( $self->grammar->select_rr_query, [ $rid ] ); # aggregate the connections per IP-Disposition-DKIM-SPF uniqueness my (%ips, %uniq, %pe, %auth, %ident, %reasons, %other); foreach my $rec ( @$recs ) { my $ip = $rec->{source_ip}; $ip = $self->any_inet_ntop($rec->{source_ip}) if $self->grammar->language ne 'postgresql'; my $key = join('-', $ip, @$rec{ qw/ disposition dkim spf / }); # hash slice $uniq{ $key }++; $ips{$key} = $rec->{source_ip}; $ident{$key}{header_from} ||= $rec->{header_from}; $ident{$key}{envelope_from} ||= $rec->{envelope_from}; $ident{$key}{envelope_to} ||= $rec->{envelope_to}; $pe{$key}{disposition} ||= $rec->{disposition}; $pe{$key}{dkim} ||= $rec->{dkim}; $pe{$key}{spf} ||= $rec->{spf}; $auth{$key}{spf} ||= $self->get_row_spf($rec->{id}); $auth{$key}{dkim} ||= $self->get_row_dkim($rec->{id}); my $reasons = $self->get_row_reason( $rec->{id} ); foreach my $reason ( @$reasons ) { my $type = $reason->{type} or next; $reasons{$key}{$type} = $reason->{comment}; # flatten reasons } } foreach my $u ( keys %uniq ) { my $record = Mail::DMARC::Report::Aggregate::Record->new( identifiers => $ident{$u}, auth_results => $auth{$u}, row => { source_ip => $self->grammar->language eq 'postgresql' ? $ips{$u} : $self->any_inet_ntop( $ips{$u} ), count => $uniq{ $u }, policy_evaluated => { %{ $pe{$u} }, $reasons{$u} ? ( reason => [ map { { type => $_, comment => $reasons{$u}{$_} } } sort keys %{ $reasons{$u} } ] ) : (), }, } ); $$agg_ref->record( $record ); } return $$agg_ref->record; } sub row_exists { my ($self, $rid, $rec ) = @_; if ( ! defined $rec->{row}{count} ) { print "new record\n" if $self->verbose; return; }; my $rows = $self->query( $self->grammar->select_report_record, [ $rid, $rec->{row}{source_ip}, $rec->{row}{count}, ] ); return 1 if scalar @$rows; return; } sub insert_agg_record { my ($self, $report_id, $rec) = @_; return 1 if $self->row_exists( $report_id, $rec); my $row_id = $self->insert_rr( $report_id, $rec ) or croak "failed to insert report row"; my $reasons = $rec->row->policy_evaluated->reason; if ( $reasons ) { foreach my $reason ( @$reasons ) { next if !$reason || !$reason->{type}; $self->insert_rr_reason( $row_id, $reason->{type}, $reason->{comment} ); }; } my $spf_ref = $rec->auth_results->spf; if ( $spf_ref ) { foreach my $spf (@$spf_ref) { $self->insert_rr_spf( $row_id, $spf ); } } my $dkim = $rec->auth_results->dkim; if ($dkim) { foreach my $sig (@$dkim) { next if ! $sig || ! $sig->{domain}; $self->insert_rr_dkim( $row_id, $sig ); } } return 1; } sub insert_error { my ( $self, $rid, $error ) = @_; # wait >5m before trying to deliver this report again $self->query($self->grammar->insert_error(0), [$self->time + (5*60), $rid]); return $self->query( $self->grammar->insert_error(1), [ $rid, $error ] ); } sub insert_rr_reason { my ( $self, $row_id, $type, $comment ) = @_; return $self->query( $self->grammar->insert_rr_reason, [ $row_id, $type, ($comment || '') ] ); } sub insert_rr_dkim { my ( $self, $row_id, $dkim ) = @_; my (@fields, @values); foreach ( qw/ domain selector result human_result / ) { next if ! defined $dkim->{$_}; if ( 'domain' eq $_ ) { push @fields, 'domain_id'; push @values, $self->get_domain_id( $dkim->{domain} ); next; }; push @fields, $_; push @values, $dkim->{$_}; }; my $query = $self->grammar->insert_rr_dkim(\@fields); $self->query( $query, [ $row_id, @values ] ); return 1; } sub insert_rr_spf { my ( $self, $row_id, $spf ) = @_; my (@fields, @values); for ( qw/ domain scope result / ) { next if ! defined $spf->{$_}; if ( 'domain' eq $_ ) { push @fields, 'domain_id'; push @values, $self->get_domain_id( $spf->{domain} ); next; }; push @fields, $_; push @values, $spf->{$_}; }; my $query = $self->grammar->insert_rr_spf(\@fields); $self->query( $query, [ $row_id, @values ]); return 1; } sub insert_rr { my ( $self, $report_id, $rec ) = @_; $report_id or croak "report ID required?!"; my $query = $self->grammar->insert_rr; my $ip = $rec->row->source_ip; $ip = $self->any_inet_pton( $ip ) if $self->grammar->language ne 'postgresql'; my @args = ( $report_id, $ip, $rec->{row}{count}, ); foreach my $f ( qw/ header_from envelope_to envelope_from / ) { push @args, $rec->identifiers->$f ? $self->get_domain_id( $rec->identifiers->$f ) : undef; }; push @args, map { $rec->row->policy_evaluated->$_ } qw/ disposition dkim spf /; my $rr_id = $self->query( $query, \@args ) or croak; return $self->{report_row_id} = $rr_id; } sub insert_policy_published { my ( $self, $id, $pub ) = @_; my $query = $self->grammar->insert_policy_published; $self->query( $query, [ $id, @$pub{ qw/ adkim aspf p sp pct rua /} ] ); return 1; } sub db_connect { my $self = shift; my $dsn = $self->config->{report_store}{dsn} or croak; my $user = $self->config->{report_store}{user}; my $pass = $self->config->{report_store}{pass}; # cacheing if ($self->{grammar} && $self->{dbix}) { my $cached_grammar_type = $self->{grammar}->dsn; if ( $dsn =~ /$cached_grammar_type/ ) { return $self->{dbix}; # caching } } my $needs_tables; $self->{grammar} = undef; my %opts; if ($dsn =~ /sqlite/i) { my ($db) = ( split /=/, $dsn )[-1]; if ( !$db || $db eq ':memory:' || !-e $db ) { my $schema = 'mail_dmarc_schema.sqlite'; $needs_tables = $self->get_db_schema($schema) or croak "can't locate DB $db AND can't find $schema! Create $db manually.\n"; } $self->{grammar} = Mail::DMARC::Report::Store::SQL::Grammars::SQLite->new(); } elsif ($dsn =~ /mysql/i) { $opts{'mysql_enable_utf8mb4'} = 1; $self->{grammar} = Mail::DMARC::Report::Store::SQL::Grammars::MySQL->new(); } elsif ($dsn =~ /pg/i) { $self->{grammar} = Mail::DMARC::Report::Store::SQL::Grammars::PostgreSQL->new(); } else { croak "can't determine database type, so unable to load grammar.\n"; } $self->{dbix} = DBIx::Simple->connect( $dsn, $user, $pass, \%opts ) or return $self->error( DBIx::Simple->error ); if ($needs_tables) { $self->apply_db_schema($needs_tables); } return $self->{dbix}; } sub db_check_err { my ( $self, $err ) = @_; ## no critic (PackageVars) return if !defined $DBI::errstr; return if !$DBI::errstr; return if $DBI::errstr eq 'DBI error: '; croak $err . $DBI::errstr; } sub dbix { return $_[0]->{dbix} if $_[0]->{dbix}; return $_[0]->db_connect(); } sub apply_db_schema { my ( $self, $file ) = @_; my $setup = $self->slurp($file); foreach ( split /;/, $setup ) { # warn "$_\n"; $self->dbix->query($_); } return; } sub get_db_schema { my ( $self, $file ) = @_; return "share/$file" if -f "share/$file"; # when testing return File::ShareDir::dist_file( 'Mail-DMARC', $file ); # when installed } sub query { my ( $self, $query, $params, @extra ) = @_; my @c = caller; my $err = sprintf( "query called by %s, %s\n", $c[0], $c[2] ) . "\t$query\n\t"; my @params; if ( defined $params ) { @params = ref $params eq 'ARRAY' ? @$params : $params; no warnings; ## no critic (NoWarnings) $err .= join( ', ', @params ); } croak "too many arguments to exec_query!" if @extra; my $dbix = $self->db_connect() or croak DBIx::Simple->error; return $self->query_insert( $query, $err, @params ) if $query =~ /^INSERT/ix; return $self->query_replace( $query, $err, @params ) if $query =~ /^(?:REPLACE|UPDATE)/ix; return $self->query_delete( $query, $err, @params ) if $query =~ /^(?:DELETE|TRUNCATE)/ix; return $self->query_any( $query, $err, @params ); } sub query_any { my ( $self, $query, $err, @params ) = @_; # warn "query: $query\n" . join(", ", @params) . "\n"; my $r; eval { $r = $self->dbix->query( $query, @params )->hashes; } or print ''; $self->db_check_err($err); die "something went wrong with: $err\n" if ! $r; ## no critic (Carp) return $r; } sub query_insert { my ( $self, $query, $err, @params ) = @_; eval { $self->dbix->query( $query, @params ) } or do { warn DBIx::Simple->error . "\n"; croak $err; }; $self->db_check_err($err); # If the table has no autoincrement field, last_insert_id is zero my ( undef, undef, $table ) = split /\s+/, $query; ($table) = split( /\(/, $table ) if $table =~ /\(/; $table =~ s/^"|"$//g; croak "unable to determine table in query: $query" if !$table; return $self->dbix->last_insert_id( undef, undef, $table, undef ); } sub query_replace { my ( $self, $query, $err, @params ) = @_; $self->dbix->query( $query, @params ) or croak $err; $self->db_check_err($err); return 1; # sorry, no indication of success } sub query_delete { my ( $self, $query, $err, @params ) = @_; my $affected = $self->dbix->query( $query, @params )->rows or croak $err; $self->db_check_err($err); return $affected; } sub get_row_spf { my ($self, $rowid) = @_; return $self->query( $self->grammar->select_row_spf, [ $rowid ] ); } sub get_row_dkim { my ($self, $rowid) = @_; return $self->query( $self->grammar->select_row_dkim, [ $rowid ] ); } sub get_row_reason { my ($self, $rowid) = @_; return $self->query( $self->grammar->select_row_reason, [ $rowid ] ); } sub grammar { my $self = shift; $self->db_connect(); return $self->{grammar}; } 1; __END__ =pod =head1 NAME Mail::DMARC::Report::Store::SQL - store and retrieve reports from a SQL RDBMS =head1 VERSION version 1.20260306 =head1 DESCRIPTION Uses ANSI SQL syntax, keeping the SQL as portable as possible. DB engine specific features are to be avoided. =head1 SYPNOSIS Store and retrieve DMARC reports from SQL data store. Tested with SQLite, MySQL and PostgreSQL. =head1 AUTHORS =over 4 =item * Matt Simerson =item * Davide Migliavacca =item * Marc Bradshaw =back =head1 COPYRIGHT AND LICENSE This software is copyright (c) 2026 by Matt Simerson. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. =cut Mail-DMARC-1.20260306/lib/Mail/DMARC/Report/Store/SQL000755000765000024 015152630466 20350 5ustar00mattstaff000000000000Mail-DMARC-1.20260306/lib/Mail/DMARC/Report/Store/SQL/Grammars000755000765000024 015152630466 22121 5ustar00mattstaff000000000000Mail-DMARC-1.20260306/lib/Mail/DMARC/Report/Store/SQL/Grammars/MySQL.pm000444000765000024 1556215152630466 23612 0ustar00mattstaff000000000000package Mail::DMARC::Report::Store::SQL::Grammars::MySQL; our $VERSION = '1.20260306'; use strict; use warnings; sub new { my $class = shift; my $self = { }; bless $self, $class; return $self; } sub language { return 'mysql'; } sub dsn { return 'mysql'; } sub and_arg { my ($self, $column, $operator) = @_; $operator //= '='; return " AND $column $operator ?"; } sub report_record_id { return 'SELECT id FROM report_record WHERE report_id=?'; } sub delete_from_where_record_in { my ($self, $table) = @_; return "DELETE FROM $table WHERE report_record_id IN (??)" } sub delete_from_where_report { my ($self, $table) = @_; return "DELETE FROM $table WHERE report_id=?"; } sub delete_report { return "DELETE FROM report WHERE id=?"; } sub select_domain_id { return 'SELECT id FROM domain WHERE domain=?'; } sub insert_domain { return 'INSERT INTO domain (domain) VALUES (?)'; } sub select_author_id { return 'SELECT id FROM author WHERE org_name=?'; } sub insert_author { return 'INSERT INTO author (org_name,email,extra_contact) VALUES (?,?,?)'; } sub select_report_id { return 'SELECT id FROM report WHERE uuid=? AND author_id=?'; } sub select_id_with_end { return 'SELECT id FROM report WHERE from_domain_id=? AND end > ? AND author_id=?'; } sub insert_report { return 'INSERT INTO report (from_domain_id, begin, end, author_id, uuid) VALUES (?,?,?,?,?)'; } sub order_by { my ($self, $arg, $order) = @_; return " ORDER BY $arg $order"; } sub count_reports { return 'SELECT COUNT(*) FROM report'; } sub limit { my ($self, $number_of_entries) = @_; $number_of_entries //= 1; return " LIMIT $number_of_entries"; } sub limit_args { my ($self, $number_of_entries) = @_; my $return = ' LIMIT '; $number_of_entries //= 1; for (my $i = 1; $i <= $number_of_entries; $i++) { $return .= '?'; $return .= ',' if $i < $number_of_entries; } return $return; } sub select_report_policy_published { return 'SELECT * from report_policy_published WHERE report_id=?'; } sub select_report_reason { return 'SELECT type,comment FROM report_record_reason WHERE report_record_id=?'; } sub select_report_error { return 'SELECT error FROM report_error WHERE report_id=?'; } sub select_report_record { return 'SELECT id FROM report_record WHERE report_id=? AND source_ip=? AND count=?' } sub select_todo_query { return <<'EO_TODO_QUERY' SELECT r.id AS rid, r.begin AS begin, r.end AS end, a.org_name AS author, fd.domain AS from_domain FROM report r LEFT JOIN report_record rr ON r.id=rr.report_id LEFT JOIN author a ON r.author_id=a.id LEFT JOIN domain fd ON r.from_domain_id=fd.id WHERE rr.count IS NULL AND rr.report_id IS NOT NULL AND r.end < ? GROUP BY r.id ORDER BY r.id ASC EO_TODO_QUERY ; } sub select_row_spf { return <<"EO_SPF_ROW" SELECT d.domain AS domain, s.result AS result, s.scope AS scope FROM report_record_spf s LEFT JOIN domain d ON s.domain_id=d.id WHERE s.report_record_id=? EO_SPF_ROW ; } sub select_row_dkim { return <<"EO_DKIM_ROW" SELECT d.domain AS domain, k.selector AS selector, k.result AS result, k.human_result AS human_result FROM report_record_dkim k LEFT JOIN domain d ON k.domain_id=d.id WHERE report_record_id=? EO_DKIM_ROW ; } sub select_row_reason { return <<"EO_ROW_QUERY" SELECT type,comment FROM report_record_reason WHERE report_record_id=? EO_ROW_QUERY ; } sub select_rr_query { return <<'EO_ROW_QUERY' SELECT rr.*, etd.domain AS envelope_to, efd.domain AS envelope_from, hfd.domain AS header_from FROM report_record rr LEFT JOIN domain etd ON etd.id=rr.envelope_to_did LEFT JOIN domain efd ON efd.id=rr.envelope_from_did LEFT JOIN domain hfd ON hfd.id=rr.header_from_did WHERE report_id = ? ORDER BY id ASC EO_ROW_QUERY ; } sub select_report_query { return <<'EO_REPORTS' SELECT r.id AS rid, r.uuid, r.begin AS begin, r.end AS end, a.org_name AS author, fd.domain AS from_domain FROM report r LEFT JOIN author a ON r.author_id=a.id LEFT JOIN domain fd ON r.from_domain_id=fd.id WHERE 1=1 EO_REPORTS ; } sub count_filtered_report_query { return <<'EO_SQL' SELECT COUNT(*) FROM report r LEFT JOIN author a ON r.author_id=a.id LEFT JOIN domain fd ON r.from_domain_id=fd.id WHERE 1=1 EO_SQL ; } sub select_from { my ($self, $columns, $table) = @_; my $colStr = join( ', ', @$columns ); return "SELECT $colStr FROM $table WHERE 1=1"; } sub insert_error { my ( $self, $which ) = @_; if ( $which == 0 ) { return 'UPDATE report SET end=? WHERE id=?'; } else { return 'INSERT INTO report_error (report_id, error) VALUES (?,?)'; } } sub insert_rr_reason { return 'INSERT INTO report_record_reason (report_record_id, type, comment) VALUES (?,?,?)' } sub insert_rr_dkim { my ( $self, $fields ) = @_; my $fields_str = join ', ', @$fields; return <<"EO_DKIM" INSERT INTO report_record_dkim (report_record_id, $fields_str) VALUES (??) EO_DKIM ; } sub insert_rr_spf { my ( $self, $fields ) = @_; my $fields_str = join ', ', @$fields; return "INSERT INTO report_record_spf (report_record_id, $fields_str) VALUES(??)"; } sub insert_rr { return <<'EO_ROW_INSERT' INSERT INTO report_record (report_id, source_ip, count, header_from_did, envelope_to_did, envelope_from_did, disposition, dkim, spf) VALUES (??) EO_ROW_INSERT ; } sub insert_policy_published { return <<"EO_RPP" INSERT INTO report_policy_published (report_id, adkim, aspf, p, sp, pct, rua) VALUES (??) EO_RPP ; } sub insert_into { my ($self, $table, $cols) = @_; my $columns = join ', ', @$cols; return "INSERT INTO $table ($columns) VALUES (??)"; } sub replace_into { my ($self, $table, $cols) = @_; my $columns = join ', ', @$cols; return "REPLACE INTO $table ($columns) VALUES (??)"; } sub update { my ($self, $table, $cols) = @_; my $columns = join( ' = ?, ') . ' = ?'; return "UPDATE $table SET $columns WHERE 1=1"; } sub delete_from { my ($self, $table) = @_; return "DELETE FROM $table WHERE 1=1"; } 1; __END__ =pod =head1 NAME Mail::DMARC::Report::Store::SQL::Grammars::MySQL - Grammar for working with mysql databases. =head1 VERSION version 1.20260306 =head1 SYPNOSIS Allow DMARC to be able to speak to MySQL databases. =head1 DESCRIPTION Uses ANSI SQL syntax, keeping the SQL as portable as possible. =head1 AUTHORS =over 4 =item * Matt Simerson =item * Davide Migliavacca =item * Marc Bradshaw =back =head1 COPYRIGHT AND LICENSE This software is copyright (c) 2026 by Matt Simerson. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. =cut Mail-DMARC-1.20260306/lib/Mail/DMARC/Report/Store/SQL/Grammars/PostgreSQL.pm000444000765000024 1775515152630466 24656 0ustar00mattstaff000000000000package Mail::DMARC::Report::Store::SQL::Grammars::PostgreSQL; our $VERSION = '1.20260306'; use strict; use warnings; sub new { my $class = shift; my $self = { }; bless $self, $class; return $self; } sub language { return 'postgresql'; } sub dsn { return 'Pg'; } sub and_arg { my ($self, $column, $operator) = @_; $operator //= '='; $column =~ s/(\w+)\.(\w+)/"$1"."$2"/ if $column =~ /\./; return " AND $column $operator ?"; } sub report_record_id { return 'SELECT "id" FROM "report_record" WHERE "report_id"=?'; } sub delete_from_where_record_in { my ($self, $table, $row_ids) = @_; return "DELETE FROM \"$table\" WHERE \"report_record_id\" IN (??)" } sub delete_from_where_report { my ($self, $table) = @_; return "DELETE FROM \"$table\" WHERE \"report_id\"=?"; } sub delete_report { return "DELETE FROM \"report\" WHERE \"id\"=?"; } sub select_domain_id { return 'SELECT "id" FROM "domain" WHERE "domain"=?'; } sub select_report_id { return 'SELECT "id" FROM "report" WHERE "uuid"=? AND "author_id"=?'; } sub select_id_with_end { return 'SELECT "id" FROM "report" WHERE "from_domain_id"=? AND "end" > ? AND "author_id"=?'; } sub insert_domain { return 'INSERT INTO "domain" ("domain") VALUES (?)'; } sub select_author_id { return 'SELECT "id" FROM "author" WHERE "org_name"=?'; } sub insert_author { return 'INSERT INTO "author" ("org_name", "email", "extra_contact") VALUES (?,?,?)'; } sub insert_report { return 'INSERT INTO "report" ("from_domain_id", "begin", "end", "author_id", "uuid") VALUES (?,?,?,?,?)'; } sub order_by { my ($self, $arg, $order) = @_; return " ORDER BY \"$arg\" $order"; } sub count_reports { return 'SELECT COUNT(*) FROM "report"'; } sub limit { my ($self, $number_of_entries) = @_; $number_of_entries //= 1; return " LIMIT $number_of_entries"; } sub limit_args { my ($self, $number_of_entries) = @_; my $return = ' LIMIT ?'; $number_of_entries //= 1; if ($number_of_entries > 1) { $return = " OFFSET ? $return"; } return $return; } sub select_report_policy_published { return 'SELECT * from "report_policy_published" WHERE "report_id"=?'; } sub select_report_reason { return 'SELECT "type","comment" FROM "report_record_reason" WHERE "report_record_id"=?'; } sub select_report_error { return 'SELECT "error" FROM "report_error" WHERE "report_id"=?'; } sub select_report_record { return 'SELECT "id" FROM "report_record" WHERE "report_id"=? AND "source_ip"=? AND "count"=?' } sub select_todo_query { return <<'EO_TODO_QUERY' SELECT "r"."id" AS "rid", "r"."begin" AS "begin", "r"."end" AS "end", "a"."org_name" AS "author", "fd"."domain" AS "from_domain" FROM "report" "r" LEFT JOIN "report_record" "rr" ON "r"."id"="rr"."report_id" LEFT JOIN "author" "a" ON "r"."author_id"="a"."id" LEFT JOIN "domain" "fd" ON "r"."from_domain_id"="fd"."id" WHERE "rr"."count" IS NULL AND "rr"."report_id" IS NOT NULL AND "r"."end" < ? GROUP BY "r"."id", "r"."begin", "r"."end", "a"."org_name", "fd"."domain" ORDER BY "r"."id" ASC EO_TODO_QUERY ; } sub select_row_spf { return <<"EO_SPF_ROW" SELECT "d"."domain" AS "domain", "s"."result" AS "result", "s"."scope" AS "scope" FROM "report_record_spf" "s" LEFT JOIN "domain" "d" ON "s"."domain_id"="d"."id" WHERE "s"."report_record_id"=? ORDER BY "s"."id" ASC EO_SPF_ROW ; } sub select_row_dkim { return <<"EO_DKIM_ROW" SELECT "d"."domain" AS "domain", "k"."selector" AS "selector", "k"."result" AS "result", "k"."human_result" AS "human_result" FROM "report_record_dkim" "k" LEFT JOIN "domain" "d" ON "k"."domain_id"="d"."id" WHERE "report_record_id"=? ORDER BY "k"."id" ASC EO_DKIM_ROW ; } sub select_row_reason { return <<"EO_ROW_QUERY" SELECT "type","comment" FROM "report_record_reason" WHERE "report_record_id"=? EO_ROW_QUERY ; } sub select_rr_query { return <<'EO_ROW_QUERY' SELECT "rr".*, "etd"."domain" AS "envelope_to", "efd"."domain" AS "envelope_from", "hfd"."domain" AS "header_from" FROM "report_record" "rr" LEFT JOIN "domain" "etd" ON "etd"."id"="rr"."envelope_to_did" LEFT JOIN "domain" "efd" ON "efd"."id"="rr"."envelope_from_did" LEFT JOIN "domain" "hfd" ON "hfd"."id"="rr"."header_from_did" WHERE "report_id" = ? ORDER BY "id" ASC EO_ROW_QUERY ; } sub select_report_query { return <<'EO_REPORTS' SELECT "r"."id" AS "rid", "r"."uuid", "r"."begin" AS "begin", "r"."end" AS "end", "a"."org_name" AS "author", "fd"."domain" AS "from_domain" FROM "report" "r" LEFT JOIN "author" "a" ON "r"."author_id"="a"."id" LEFT JOIN "domain" "fd" ON "r"."from_domain_id"="fd"."id" WHERE 1=1 EO_REPORTS ; } sub count_filtered_report_query { return <<'EO_SQL' SELECT COUNT(*) FROM "report" "r" LEFT JOIN "author" "a" ON "r"."author_id"="a"."id" LEFT JOIN "domain" "fd" ON "r"."from_domain_id"="fd"."id" WHERE 1=1 EO_SQL ; } sub insert_error { my ( $self, $which ) = @_; if ( $which == 0 ) { return 'UPDATE "report" SET "end"=? WHERE "id"=?'; } else { return 'INSERT INTO "report_error" ("report_id", "error") VALUES (?,?)'; } } sub insert_rr_reason { return 'INSERT INTO "report_record_reason" ("report_record_id", "type", "comment") VALUES (?,?,?)' } sub insert_rr_dkim { my ( $self, $fields ) = @_; my $fields_str = join '", "', @$fields; return <<"EO_DKIM" INSERT INTO "report_record_dkim" ("report_record_id", \"$fields_str\") VALUES (??) EO_DKIM ; } sub insert_rr_spf { my ( $self, $fields ) = @_; my $fields_str = join '", "', @$fields; return "INSERT INTO \"report_record_spf\" (\"report_record_id\", \"$fields_str\") VALUES(??)"; } sub insert_rr { return <<'EO_ROW_INSERT' INSERT INTO report_record (report_id, source_ip, count, header_from_did, envelope_to_did, envelope_from_did, disposition, dkim, spf) VALUES (??) EO_ROW_INSERT ; } sub insert_policy_published { return <<"EO_RPP" INSERT INTO report_policy_published (report_id, adkim, aspf, p, sp, pct, rua) VALUES (??) EO_RPP ; } sub select_from { my ($self, $columns, $table) = @_; my $colStr = '*'; if ( @{$columns}[0] ne '*' ) { my @cols; foreach my $col (@$columns) { if ( $col =~ /(\w+)(?:\s+as\s+(\w+))/i ) { $col = "$1\" AS \"$2"; } $col = "\"$col\""; push @cols, $col; } $colStr = join( ', ', @cols ); } return "SELECT $colStr FROM \"$table\" WHERE 1=1"; } sub insert_into { my ($self, $table, $cols) = @_; my $columns = '"' . join( '", "', @$cols ) . '"'; return "INSERT INTO \"$table\" ($columns) VALUES (??)"; } sub update { my ($self, $table, $cols) = @_; my $columns = '"' . join( '" = ?, "') . '" = ?'; return "UPDATE \"$table\" SET $columns WHERE 1=1"; } sub delete_from { my ($self, $table) = @_; return "DELETE FROM \"$table\" WHERE 1=1"; } sub replace_into { my ($self, $table, $cols) = @_; my $insertColumns = '"' . join( '", "', @$cols ) . '"'; my @ucols; foreach my $col (@$cols) { push @ucols, "\"$col\" = EXCLUDED.\"$col\"" } my $updateColumns = join ', ', @ucols; return "INSERT INTO \"$table\" ($insertColumns) VALUES (??) ON CONFLICT ($insertColumns) DO UPDATE SET $updateColumns"; } 1; __END__ =pod =head1 NAME Mail::DMARC::Report::Store::SQL::Grammars::PostgreSQL - Grammar for working with pgsql databases. =head1 VERSION version 1.20260306 =head1 SYPNOSIS Allow DMARC to be able to speak to PostgreSQL databases. =head1 DESCRIPTION =head1 AUTHORS =over 4 =item * Matt Simerson =item * Davide Migliavacca =item * Marc Bradshaw =back =head1 COPYRIGHT AND LICENSE This software is copyright (c) 2026 by Matt Simerson. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. =cut Mail-DMARC-1.20260306/lib/Mail/DMARC/Report/Store/SQL/Grammars/SQLite.pm000444000765000024 1565015152630466 24004 0ustar00mattstaff000000000000package Mail::DMARC::Report::Store::SQL::Grammars::SQLite; our $VERSION = '1.20260306'; use strict; use warnings; sub new { my $class = shift; my $self = { }; bless $self, $class; return $self; } sub language { return 'sqlite'; } sub dsn { return 'SQLite'; } sub and_arg { my ($self, $column, $operator) = @_; $operator //= '='; return " AND $column $operator ?"; } sub report_record_id { return 'SELECT id FROM report_record WHERE report_id=?'; } sub delete_from_where_record_in { my ($self, $table) = @_; return "DELETE FROM $table WHERE report_record_id IN (??)" } sub delete_from_where_report { my ($self, $table) = @_; return "DELETE FROM $table WHERE report_id=?"; } sub delete_report { return "DELETE FROM report WHERE id=?"; } sub select_domain_id { return 'SELECT id FROM domain WHERE domain=?'; } sub insert_domain { return 'INSERT INTO domain (domain) VALUES (?)'; } sub select_author_id { return 'SELECT id FROM author WHERE org_name=?'; } sub insert_author { return 'INSERT INTO author (org_name,email,extra_contact) VALUES (?,?,?)'; } sub select_report_id { return 'SELECT id FROM report WHERE uuid=? AND author_id=?'; } sub select_id_with_end { return 'SELECT id FROM report WHERE from_domain_id=? AND end > ? AND author_id=?'; } sub insert_report { return 'INSERT INTO report (from_domain_id, begin, end, author_id, uuid) VALUES (?,?,?,?,?)'; } sub order_by { my ($self, $arg, $order) = @_; return " ORDER BY $arg $order"; } sub count_reports { return 'SELECT COUNT(*) FROM report'; } sub limit { my ($self, $number_of_entries) = @_; $number_of_entries //= 1; return " LIMIT $number_of_entries"; } sub limit_args { my ($self, $number_of_entries) = @_; my $return = ' LIMIT '; $number_of_entries //= 1; for (my $i = 1; $i <= $number_of_entries; $i++) { $return .= '?'; $return .= ',' if $i < $number_of_entries; } return $return; } sub select_report_policy_published { return 'SELECT * from report_policy_published WHERE report_id=?'; } sub select_report_reason { return 'SELECT type,comment FROM report_record_reason WHERE report_record_id=?'; } sub select_report_error { return 'SELECT error FROM report_error WHERE report_id=?'; } sub select_report_record { return 'SELECT id FROM report_record WHERE report_id=? AND source_ip=? AND count=?' } sub select_todo_query { return <<'EO_TODO_QUERY' SELECT r.id AS rid, r.begin AS begin, r.end AS end, a.org_name AS author, fd.domain AS from_domain FROM report r LEFT JOIN report_record rr ON r.id=rr.report_id LEFT JOIN author a ON r.author_id=a.id LEFT JOIN domain fd ON r.from_domain_id=fd.id WHERE rr.count IS NULL AND rr.report_id IS NOT NULL AND r.end < ? GROUP BY r.id ORDER BY r.id ASC EO_TODO_QUERY ; } sub select_row_spf { return <<"EO_SPF_ROW" SELECT d.domain AS domain, s.result AS result, s.scope AS scope FROM report_record_spf s LEFT JOIN domain d ON s.domain_id=d.id WHERE s.report_record_id=? EO_SPF_ROW ; } sub select_row_dkim { return <<"EO_DKIM_ROW" SELECT d.domain AS domain, k.selector AS selector, k.result AS result, k.human_result AS human_result FROM report_record_dkim k LEFT JOIN domain d ON k.domain_id=d.id WHERE report_record_id=? EO_DKIM_ROW ; } sub select_row_reason { return <<"EO_ROW_QUERY" SELECT type,comment FROM report_record_reason WHERE report_record_id=? EO_ROW_QUERY ; } sub select_rr_query { return <<'EO_ROW_QUERY' SELECT rr.*, etd.domain AS envelope_to, efd.domain AS envelope_from, hfd.domain AS header_from FROM report_record rr LEFT JOIN domain etd ON etd.id=rr.envelope_to_did LEFT JOIN domain efd ON efd.id=rr.envelope_from_did LEFT JOIN domain hfd ON hfd.id=rr.header_from_did WHERE report_id = ? ORDER BY id ASC EO_ROW_QUERY ; } sub select_report_query { return <<'EO_REPORTS' SELECT r.id AS rid, r.uuid, r.begin AS begin, r.end AS end, a.org_name AS author, fd.domain AS from_domain FROM report r LEFT JOIN author a ON r.author_id=a.id LEFT JOIN domain fd ON r.from_domain_id=fd.id WHERE 1=1 EO_REPORTS ; } sub count_filtered_report_query { return <<'EO_SQL' SELECT COUNT(*) FROM report r LEFT JOIN author a ON r.author_id=a.id LEFT JOIN domain fd ON r.from_domain_id=fd.id WHERE 1=1 EO_SQL ; } sub insert_error { my ( $self, $which ) = @_; if ( $which == 0 ) { return 'UPDATE report SET end=? WHERE id=?'; } else { return 'INSERT INTO report_error (report_id, error) VALUES (?,?)'; } } sub insert_rr_reason { return 'INSERT INTO report_record_reason (report_record_id, type, comment) VALUES (?,?,?)' } sub insert_rr_dkim { my ( $self, $fields ) = @_; my $fields_str = join ', ', @$fields; return <<"EO_DKIM" INSERT INTO report_record_dkim (report_record_id, $fields_str) VALUES (??) EO_DKIM ; } sub insert_rr_spf { my ( $self, $fields ) = @_; my $fields_str = join ', ', @$fields; return "INSERT INTO report_record_spf (report_record_id, $fields_str) VALUES(??)"; } sub insert_rr { return <<'EO_ROW_INSERT' INSERT INTO report_record (report_id, source_ip, count, header_from_did, envelope_to_did, envelope_from_did, disposition, dkim, spf) VALUES (??) EO_ROW_INSERT ; } sub insert_policy_published { return <<"EO_RPP" INSERT INTO report_policy_published (report_id, adkim, aspf, p, sp, pct, rua) VALUES (??) EO_RPP ; } sub select_from { my ($self, $columns, $table) = @_; my $colStr = join( ', ', @$columns ); return "SELECT $colStr FROM $table WHERE 1=1"; } sub insert_into { my ($self, $table, $cols) = @_; my $columns = join ', ', @$cols; return "INSERT INTO $table ($columns) VALUES (??)"; } sub update { my ($self, $table, $cols) = @_; my $columns = join( ' = ?, ') . ' = ?'; return "UPDATE $table SET $columns WHERE 1=1"; } sub replace_into { my ($self, $table, $cols) = @_; my $columns = join ', ', @$cols; return "REPLACE INTO $table ($columns) VALUES (??)"; } sub delete_from { my ($self, $table) = @_; return "DELETE FROM $table WHERE 1=1"; } 1; __END__ =pod =head1 NAME Mail::DMARC::Report::Store::SQL::Grammars::SQLite - Grammar for working with sqlite databases. =head1 VERSION version 1.20260306 =head1 SYPNOSIS Allow DMARC to be able to speak to SQLite databases. =head1 DESCRIPTION Uses ANSI SQL syntax, keeping the SQL as portable as possible. DB engine specific features are to be avoided. =head1 AUTHORS =over 4 =item * Matt Simerson =item * Davide Migliavacca =item * Marc Bradshaw =back =head1 COPYRIGHT AND LICENSE This software is copyright (c) 2026 by Matt Simerson. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. =cut Mail-DMARC-1.20260306/lib/Mail/DMARC/Result000755000765000024 015152630466 16620 5ustar00mattstaff000000000000Mail-DMARC-1.20260306/lib/Mail/DMARC/Result/Reason.pm000444000765000024 265115152630466 20546 0ustar00mattstaff000000000000package Mail::DMARC::Result::Reason; our $VERSION = '1.20260306'; use strict; use warnings; use Carp; sub new { my ( $class, @args ) = @_; croak "invalid arguments" if @args % 2; my %args = @args; my $self = bless {}, $class; foreach my $key ( keys %args ) { $self->$key( $args{$key} ); } return $self; } sub type { return $_[0]->{type} if 1 == scalar @_; croak "invalid type" if 0 == grep {/^$_[1]$/ix} qw/ forwarded sampled_out trusted_forwarder mailing_list local_policy other /; return $_[0]->{type} = $_[1]; } sub comment { return $_[0]->{comment} if 1 == scalar @_; # comment is optional and requires no validation return $_[0]->{comment} = $_[1]; } 1; __END__ =pod =head1 NAME Mail::DMARC::Result::Reason - policy override reason =head1 VERSION version 1.20260306 =head1 METHODS =head2 type Type is the type of override used, and is one of a number of fixed strings. =head2 comment Comment may or may not be present, and may be anything. =head1 AUTHORS =over 4 =item * Matt Simerson =item * Davide Migliavacca =item * Marc Bradshaw =back =head1 COPYRIGHT AND LICENSE This software is copyright (c) 2026 by Matt Simerson. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. =cut Mail-DMARC-1.20260306/lib/Mail/DMARC/Test000755000765000024 015152630466 16261 5ustar00mattstaff000000000000Mail-DMARC-1.20260306/lib/Mail/DMARC/Test/Transport.pm000444000765000024 73015152630466 20730 0ustar00mattstaff000000000000package Mail::DMARC::Test::Transport; # VERSION use strict; use warnings; use Email::Sender::Transport::Test; sub new { my $class = shift; my $self = {}; return bless $self, $class; }; { my $global_transport = Email::Sender::Transport::Test->new; sub get_test_transport { return $global_transport; } } sub get_transports_for { my ( $self,$args ) = @_; my @transports; push @transports, $self->get_test_transport; return @transports; } 1; Mail-DMARC-1.20260306/share000755000765000024 015152630466 14166 5ustar00mattstaff000000000000Mail-DMARC-1.20260306/share/dmarc_whitelist000444000765000024 171615152630466 17435 0ustar00mattstaff000000000000# Format: IP *whitespace* type *whitespace* comment # # Reason types: forwarded sampled_out trusted_forwarder mailing_list local_policy other # any IP without a type specified will default to 'other' # # Comment is a free form text entry 127.0.0.3 trusted_forwarder Test Comment 127.0.0.1 local_policy 140.211.11.3 mailing_list apache.org 141.42.206.35 mailing_list charite.de 146.112.225.21 mailing_list phishtank.com 168.100.1.1 mailing_list cloud9.net 168.100.1.3 mailing_list cloud9.net 168.100.1.4 mailing_list cloud9.net 168.100.1.7 mailing_list cloud9.net 2604:8d00:0:1::3 mailing_list cloud9.net 2604:8d00:0:1::4 mailing_list cloud9.net 2604:8d00:0:1::7 mailing_list cloud9.net 198.148.79.53 mailing_list clamav.net 208.69.40.157 mailing_list blackops.org 95.128.36.21 mailing_list kolabsys.com 95.128.36.22 mailing_list kolabsys.com 95.128.36.23 mailing_list kolabsys.com 199.185.178.25 mailing_list openbsd.org 199.247.13.58 mailing_list opensmtpd.org Mail-DMARC-1.20260306/share/mail-dmarc.cron000444000765000024 45715152630466 17202 0ustar00mattstaff000000000000# /etc/cron.d/dmarc_update_public_suffix_list: crontab entries for the Mail::DMARC package SHELL=/bin/sh PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin # Periodically (once a week) check for updates of the public suffix list 0 4 * * 0 root dmarc_update_public_suffix_list --random Mail-DMARC-1.20260306/share/mail-dmarc.ini000444000765000024 465515152630466 17044 0ustar00mattstaff000000000000; This is YOU. DMARC reports include information about the reports. Enter it here. [organization] domain = example.com org_name = My Great Company email = noreply@example.com extra_contact_info = http://www.example.com/dmarc-policy/ ; aggregate DMARC reports need to be stored somewhere. Any database ; with a DBI module (MySQL, SQLite, DBD, etc.) should work. ; SQLite, MySQL and Postgresql are supported. ; Default is sqlite. [report_store] backend = SQL dsn = dbi:SQLite:dbname=dmarc_reports.sqlite ;dsn = dbi:mysql:database=dmarc_report;host=db;port=3306;mysql_ssl=1 ;dsn = dbi:Pg:database=dmarc_report;port=5432 user = pass = ; when validating DMARC messages, reports are not saved by default. This ; enables 'save by default' auto_save = 0 ; Sign outgoing report emails with DKIM ; Options match those which would be passed ; to Mail::DKIM::Signer [report_sign] algorithm = rsa-sha1 method = relaxed domain = signer.example.com selector = dkim keyfile = /path/to/private.key [report_sending] ; minimum reporting interval in seconds: default: none ; min_interval = 3600 ; ; maximum reporting interval in seconds: default: none ; max_interval = 86400 ; backend can be perl or libopendmarc [dmarc] backend = perl [dns] timeout = 5 retrans = 5 public_suffix_list = share/public_suffix_list [smtp] ; hostname is the external FQDN of this MTA hostname = mail.example.com cc = set.this@for.a.while.example.com ; list IP addresses to whitelist (bypass DMARC reject/quarantine) ; see sample whitelist in share/dmarc_whitelist whitelist = /path/to/etc/dmarc_whitelist ; By default, we attempt to email directly to the report recipient. ; Set these to relay via a SMTP smart host. smarthost = smartuser = smartpass = ; Send error report emails, if set, we will send a simple report to ; any report handler when we were unable to send an aggregate report ; This currently covers errors where the report was too large to send. send_errors = 1 [imap] server = mail.example.com port = 993 user = pass = ; SSL_verify_mode = 0 ; setting to 0 disables TLS certificate validation ; the imap folder where new dmarc messages will be found folder = INBOX ; the folders to store processed reports (a=aggregate, f=forensic) f_done = dmarc.forensic a_done = dmarc.aggregate [http] port = 8080 [https] port = 8443 ssl_crt = ssl_key = Mail-DMARC-1.20260306/share/mail_dmarc_schema.mysql000444000765000024 2225315152630466 21046 0ustar00mattstaff000000000000# Drop dependent tables first (reverse dependency order) before dropping report DROP TABLE IF EXISTS `report_record_spf`; DROP TABLE IF EXISTS `report_record_dkim`; DROP TABLE IF EXISTS `report_record_reason`; DROP TABLE IF EXISTS `report_record`; DROP TABLE IF EXISTS `report_policy_published`; DROP TABLE IF EXISTS `report_error`; DROP TABLE IF EXISTS `report`; DROP TABLE IF EXISTS `fk_spf_scope`; DROP TABLE IF EXISTS `fk_spf_result`; DROP TABLE IF EXISTS `fk_dkim_result`; DROP TABLE IF EXISTS `fk_disposition_reason`; DROP TABLE IF EXISTS `fk_disposition`; DROP TABLE IF EXISTS `domain`; DROP TABLE IF EXISTS `author`; # Dump of table author # ------------------------------------------------------------ CREATE TABLE `author` ( `id` int(11) unsigned NOT NULL AUTO_INCREMENT, `org_name` varchar(253) NOT NULL DEFAULT '', `email` varchar(255) DEFAULT NULL, `extra_contact` varchar(255) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE utf8mb4_unicode_ci; # Dump of table domain # ------------------------------------------------------------ CREATE TABLE `domain` ( `id` int(11) unsigned NOT NULL AUTO_INCREMENT, `domain` varchar(253) NOT NULL DEFAULT '', PRIMARY KEY (`id`), UNIQUE KEY `domain` (`domain`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE utf8mb4_unicode_ci; # Dump of table report # ------------------------------------------------------------ CREATE TABLE `report` ( `id` int(11) unsigned NOT NULL AUTO_INCREMENT, `begin` int(11) unsigned NOT NULL, `end` int(11) unsigned NOT NULL, `author_id` int(11) unsigned NOT NULL, `rcpt_domain_id` int(11) unsigned DEFAULT NULL, `from_domain_id` int(11) unsigned NOT NULL, `uuid` varchar(253) DEFAULT NULL, PRIMARY KEY (`id`), KEY `author_id` (`author_id`), KEY `from_domain_id` (`from_domain_id`), CONSTRAINT `report_ibfk_3` FOREIGN KEY (`from_domain_id`) REFERENCES `domain` (`id`) ON UPDATE CASCADE, CONSTRAINT `report_ibfk_1` FOREIGN KEY (`author_id`) REFERENCES `author` (`id`) ON DELETE NO ACTION ON UPDATE CASCADE ) ENGINE=InnoDB DEFAULT CHARSET=ascii; CREATE TABLE `report_error` ( `id` int(11) unsigned NOT NULL AUTO_INCREMENT, `report_id` int(11) unsigned NOT NULL, `error` varchar(255) NOT NULL DEFAULT '', `time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (`id`), KEY `report_id` (`report_id`), CONSTRAINT `report_error_ibfk_1` FOREIGN KEY (`report_id`) REFERENCES `report` (`id`) ON DELETE CASCADE ON UPDATE CASCADE ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE utf8mb4_unicode_ci; # Dump of table fk_disposition # ------------------------------------------------------------ CREATE TABLE `fk_disposition` ( `disposition` varchar(10) NOT NULL DEFAULT '', PRIMARY KEY (`disposition`) ) ENGINE=InnoDB DEFAULT CHARSET=ascii; LOCK TABLES `fk_disposition` WRITE; /*!40000 ALTER TABLE `fk_disposition` DISABLE KEYS */; INSERT INTO `fk_disposition` (`disposition`) VALUES ('none'), ('quarantine'), ('reject'); /*!40000 ALTER TABLE `fk_disposition` ENABLE KEYS */; UNLOCK TABLES; # Dump of table fk_disposition_reason # ------------------------------------------------------------ CREATE TABLE `fk_disposition_reason` ( `type` varchar(24) NOT NULL DEFAULT '', PRIMARY KEY (`type`) ) ENGINE=InnoDB DEFAULT CHARSET=ascii; LOCK TABLES `fk_disposition_reason` WRITE; /*!40000 ALTER TABLE `fk_disposition_reason` DISABLE KEYS */; INSERT INTO `fk_disposition_reason` (`type`) VALUES ('forwarded'), ('local_policy'), ('mailing_list'), ('other'), ('sampled_out'), ('trusted_forwarder'); /*!40000 ALTER TABLE `fk_disposition_reason` ENABLE KEYS */; UNLOCK TABLES; # Dump of table fk_dkim_result # ------------------------------------------------------------ CREATE TABLE `fk_dkim_result` ( `result` varchar(9) NOT NULL DEFAULT '', PRIMARY KEY (`result`) ) ENGINE=InnoDB DEFAULT CHARSET=ascii; LOCK TABLES `fk_dkim_result` WRITE; /*!40000 ALTER TABLE `fk_dkim_result` DISABLE KEYS */; INSERT INTO `fk_dkim_result` (`result`) VALUES ('fail'), ('neutral'), ('none'), ('pass'), ('permerror'), ('policy'), ('temperror'); /*!40000 ALTER TABLE `fk_dkim_result` ENABLE KEYS */; UNLOCK TABLES; # Dump of table fk_spf_result # ------------------------------------------------------------ CREATE TABLE `fk_spf_result` ( `result` varchar(9) NOT NULL DEFAULT '', PRIMARY KEY (`result`) ) ENGINE=InnoDB DEFAULT CHARSET=ascii; LOCK TABLES `fk_spf_result` WRITE; /*!40000 ALTER TABLE `fk_spf_result` DISABLE KEYS */; INSERT INTO `fk_spf_result` (`result`) VALUES ('fail'), ('neutral'), ('none'), ('pass'), ('permerror'), ('softfail'), ('temperror'); /*!40000 ALTER TABLE `fk_spf_result` ENABLE KEYS */; UNLOCK TABLES; # Dump of table fk_spf_scope # ------------------------------------------------------------ CREATE TABLE `fk_spf_scope` ( `scope` varchar(5) NOT NULL DEFAULT '', PRIMARY KEY (`scope`) ) ENGINE=InnoDB DEFAULT CHARSET=ascii; LOCK TABLES `fk_spf_scope` WRITE; /*!40000 ALTER TABLE `fk_spf_scope` DISABLE KEYS */; INSERT INTO `fk_spf_scope` (`scope`) VALUES ('helo'), ('mfrom'); /*!40000 ALTER TABLE `fk_spf_scope` ENABLE KEYS */; UNLOCK TABLES; # Dump of table report_policy_published # ------------------------------------------------------------ CREATE TABLE `report_policy_published` ( `id` int(11) unsigned NOT NULL AUTO_INCREMENT, `report_id` int(11) unsigned NOT NULL, `adkim` char(1) DEFAULT NULL, `aspf` char(1) DEFAULT NULL, `p` varchar(10) DEFAULT NULL, `sp` varchar(10) DEFAULT NULL, `pct` tinyint(1) unsigned DEFAULT NULL, `rua` varchar(255) DEFAULT NULL, PRIMARY KEY (`id`), KEY `report_id` (`report_id`), CONSTRAINT `report_policy_published_ibfk_1` FOREIGN KEY (`report_id`) REFERENCES `report` (`id`) ON DELETE CASCADE ON UPDATE CASCADE ) ENGINE=InnoDB DEFAULT CHARSET=ascii; # Dump of table report_record # ------------------------------------------------------------ CREATE TABLE `report_record` ( `id` int(11) unsigned NOT NULL AUTO_INCREMENT, `report_id` int(11) unsigned NOT NULL, `source_ip` varbinary(16) NOT NULL DEFAULT '', `count` int(11) unsigned DEFAULT NULL, `disposition` varchar(10) NOT NULL DEFAULT '', `dkim` char(4) NOT NULL DEFAULT '', `spf` char(4) NOT NULL DEFAULT '', `envelope_to_did` int(11) unsigned DEFAULT NULL, `envelope_from_did` int(11) unsigned DEFAULT NULL, `header_from_did` int(11) unsigned NOT NULL, PRIMARY KEY (`id`), KEY `report_id` (`report_id`), KEY `disposition` (`disposition`), CONSTRAINT `report_record_ibfk_2` FOREIGN KEY (`disposition`) REFERENCES `fk_disposition` (`disposition`) ON DELETE CASCADE ON UPDATE CASCADE, CONSTRAINT `report_record_ibfk_1` FOREIGN KEY (`report_id`) REFERENCES `report` (`id`) ON DELETE CASCADE ON UPDATE CASCADE ) ENGINE=InnoDB DEFAULT CHARSET=ascii; # Dump of table report_record_reason # ------------------------------------------------------------ CREATE TABLE `report_record_reason` ( `id` int(11) unsigned NOT NULL AUTO_INCREMENT, `report_record_id` int(11) unsigned NOT NULL, `type` varchar(24) NOT NULL DEFAULT '', `comment` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL, PRIMARY KEY (`id`), KEY `report_record_id` (`report_record_id`), KEY `type` (`type`), CONSTRAINT `report_record_reason_ibfk_3` FOREIGN KEY (`report_record_id`) REFERENCES `report_record` (`id`) ON DELETE CASCADE ON UPDATE CASCADE, CONSTRAINT `report_record_reason_ibfk_4` FOREIGN KEY (`type`) REFERENCES `fk_disposition_reason` (`type`) ON DELETE NO ACTION ON UPDATE CASCADE ) ENGINE=InnoDB DEFAULT CHARSET=ascii; # Dump of table report_record_dkim # ------------------------------------------------------------ CREATE TABLE `report_record_dkim` ( `id` int(11) unsigned NOT NULL AUTO_INCREMENT, `report_record_id` int(11) unsigned NOT NULL, `domain_id` int(11) unsigned NOT NULL, `selector` varchar(253) DEFAULT NULL, `result` varchar(9) NOT NULL DEFAULT '', `human_result` varchar(64) DEFAULT NULL, PRIMARY KEY (`id`), KEY `report_record_id` (`report_record_id`), KEY `result` (`result`), CONSTRAINT `report_record_dkim_ibfk_2` FOREIGN KEY (`result`) REFERENCES `fk_dkim_result` (`result`), CONSTRAINT `report_record_dkim_ibfk_1` FOREIGN KEY (`report_record_id`) REFERENCES `report_record` (`id`) ON DELETE CASCADE ON UPDATE CASCADE ) ENGINE=InnoDB DEFAULT CHARSET=ascii; # Dump of table report_record_spf # ------------------------------------------------------------ CREATE TABLE `report_record_spf` ( `id` int(11) unsigned NOT NULL AUTO_INCREMENT, `report_record_id` int(11) unsigned NOT NULL, `domain_id` int(11) unsigned NOT NULL, `scope` varchar(5) DEFAULT NULL, `result` varchar(9) NOT NULL DEFAULT '', PRIMARY KEY (`id`), KEY `report_record_id` (`report_record_id`), KEY `scope` (`scope`), KEY `result` (`result`), CONSTRAINT `report_record_spf_ibfk_1` FOREIGN KEY (`report_record_id`) REFERENCES `report_record` (`id`) ON DELETE CASCADE ON UPDATE CASCADE, CONSTRAINT `report_record_spf_ibfk_2` FOREIGN KEY (`scope`) REFERENCES `fk_spf_scope` (`scope`) ON DELETE CASCADE ON UPDATE CASCADE, CONSTRAINT `report_record_spf_ibfk_3` FOREIGN KEY (`result`) REFERENCES `fk_spf_result` (`result`) ON DELETE CASCADE ON UPDATE CASCADE ) ENGINE=InnoDB DEFAULT CHARSET=ascii; Mail-DMARC-1.20260306/share/mail_dmarc_schema.pgsql000444000765000024 730315152630466 21006 0ustar00mattstaff000000000000-- $Id$ -- Dump of table author -- ------------------------------------------------------------ DROP TABLE IF EXISTS author CASCADE; CREATE TABLE author ( id serial unique, org_name varchar(253) NOT NULL DEFAULT '', email varchar(255) DEFAULT NULL, extra_contact varchar(255) DEFAULT NULL ); -- Dump of table domain -- ------------------------------------------------------------ DROP TABLE IF EXISTS domain CASCADE; CREATE TABLE domain ( id serial unique, domain varchar(253) NOT NULL DEFAULT '', UNIQUE (domain) ); -- Dump of table report -- ------------------------------------------------------------ DROP TABLE IF EXISTS report CASCADE; CREATE TABLE report ( id serial unique, "begin" int NOT NULL, "end" int NOT NULL, author_id int NOT NULL REFERENCES author (id) ON DELETE NO ACTION, rcpt_domain_id int DEFAULT NULL, from_domain_id int NOT NULL REFERENCES domain (id), uuid varchar(253) DEFAULT NULL ); DROP TABLE IF EXISTS report_error CASCADE; CREATE TABLE report_error ( id serial unique, report_id int REFERENCES report(id) ON DELETE CASCADE, error varchar(255) NOT NULL DEFAULT '', time timestamp NOT NULL DEFAULT now() ); -- Dump of table report_policy_published -- ------------------------------------------------------------ DROP TABLE IF EXISTS report_policy_published CASCADE; CREATE TABLE report_policy_published ( id serial unique, report_id int NOT NULL REFERENCES report (id) ON DELETE CASCADE, adkim varchar(1) DEFAULT NULL, aspf varchar(1) DEFAULT NULL, p varchar(10) DEFAULT NULL, sp varchar(10) DEFAULT NULL, pct int DEFAULT NULL, rua varchar(255) DEFAULT NULL ); -- Dump of table report_record -- ------------------------------------------------------------ DROP TABLE IF EXISTS report_record CASCADE; CREATE TABLE report_record ( id serial unique, report_id int NOT NULL REFERENCES report (id) ON DELETE CASCADE, source_ip INET NOT NULL, count int DEFAULT NULL, disposition varchar(10) NOT NULL, dkim varchar(4) NOT NULL DEFAULT '', spf varchar(4) NOT NULL DEFAULT '', envelope_to_did int DEFAULT NULL, envelope_from_did int DEFAULT NULL, header_from_did int NOT NULL ); DROP TABLE IF EXISTS report_record_reason CASCADE; CREATE TABLE report_record_reason ( id serial unique, report_record_id int NOT NULL REFERENCES report_record (id) ON DELETE CASCADE, type varchar(24) NOT NULL, comment varchar(255) DEFAULT NULL ); -- Dump of table report_record_dkim -- ------------------------------------------------------------ DROP TABLE IF EXISTS report_record_dkim CASCADE; CREATE TABLE report_record_dkim ( id serial unique, report_record_id int NOT NULL REFERENCES report_record (id) ON DELETE CASCADE, domain_id int NOT NULL, selector varchar(253) DEFAULT NULL, result varchar(9) NOT NULL DEFAULT '', human_result varchar(64) DEFAULT NULL ); -- Dump of table report_record_spf -- ------------------------------------------------------------ DROP TABLE IF EXISTS report_record_spf CASCADE; CREATE TABLE report_record_spf ( id serial unique, report_record_id int NOT NULL REFERENCES report_record (id) ON DELETE CASCADE, domain_id int NOT NULL, scope varchar(5) DEFAULT NULL, result varchar(9) NOT NULL ); -- Indexes -- ----------------------------------------------------------- CREATE INDEX report_record_spf_report_record_id_idx ON report_record_spf(report_record_id); CREATE INDEX report_record_dkim_report_record_id_idx ON report_record_dkim(report_record_id); CREATE INDEX report_record_report_id_idx ON report_record(report_id); CREATE INDEX report_record_reason_report_record_id_idx ON report_record_reason(report_record_id); CREATE INDEX report_policy_published_report_id_idx ON report_policy_published(report_id); Mail-DMARC-1.20260306/share/mail_dmarc_schema.sqlite000444000765000024 1175715152630466 21211 0ustar00mattstaff000000000000 DROP TABLE IF EXISTS `author`; CREATE TABLE `author` ( `id` INTEGER PRIMARY KEY AUTOINCREMENT, `org_name` TEXT NOT NULL, `email` TEXT DEFAULT NULL, `extra_contact` TEXT DEFAULT NULL ); CREATE UNIQUE INDEX "org_name_idx" ON "author" ("org_name"); DROP TABLE IF EXISTS `domain`; CREATE TABLE `domain` ( `id` INTEGER PRIMARY KEY AUTOINCREMENT, `domain` TEXT NOT NULL ); CREATE UNIQUE INDEX "domain_idx" ON "domain" ("domain"); DROP TABLE IF EXISTS `fk_disposition`; CREATE TABLE `fk_disposition` ( `disposition` TEXT NOT NULL, PRIMARY KEY (`disposition`) ); INSERT INTO "fk_disposition" VALUES ('none'); INSERT INTO "fk_disposition" VALUES ('quarantine'); INSERT INTO "fk_disposition" VALUES ('reject'); DROP TABLE IF EXISTS `fk_disposition_reason`; CREATE TABLE `fk_disposition_reason` ( `type` TEXT NOT NULL, PRIMARY KEY (`type`) ); INSERT INTO "fk_disposition_reason" VALUES ('forwarded'); INSERT INTO "fk_disposition_reason" VALUES ('local_policy'); INSERT INTO "fk_disposition_reason" VALUES ('mailing_list'); INSERT INTO "fk_disposition_reason" VALUES ('other'); INSERT INTO "fk_disposition_reason" VALUES ('sampled_out'); INSERT INTO "fk_disposition_reason" VALUES ('trusted_forwarder'); DROP TABLE IF EXISTS `fk_dkim_result`; CREATE TABLE `fk_dkim_result` ( `result` TEXT NOT NULL, PRIMARY KEY (`result`) ); INSERT INTO "fk_dkim_result" VALUES ('fail'); INSERT INTO "fk_dkim_result" VALUES ('neutral'); INSERT INTO "fk_dkim_result" VALUES ('none'); INSERT INTO "fk_dkim_result" VALUES ('pass'); INSERT INTO "fk_dkim_result" VALUES ('permerror'); INSERT INTO "fk_dkim_result" VALUES ('policy'); INSERT INTO "fk_dkim_result" VALUES ('temperror'); DROP TABLE IF EXISTS `fk_spf_result`; CREATE TABLE `fk_spf_result` ( `result` TEXT NOT NULL, PRIMARY KEY (`result`) ); INSERT INTO "fk_spf_result" VALUES ('fail'); INSERT INTO "fk_spf_result" VALUES ('neutral'); INSERT INTO "fk_spf_result" VALUES ('none'); INSERT INTO "fk_spf_result" VALUES ('pass'); INSERT INTO "fk_spf_result" VALUES ('permerror'); INSERT INTO "fk_spf_result" VALUES ('softfail'); INSERT INTO "fk_spf_result" VALUES ('temperror'); DROP TABLE IF EXISTS `fk_spf_scope`; CREATE TABLE `fk_spf_scope` ( `scope` TEXT NOT NULL, PRIMARY KEY (`scope`) ); INSERT INTO "fk_spf_scope" VALUES ('helo'); INSERT INTO "fk_spf_scope" VALUES ('mfrom'); DROP TABLE IF EXISTS `report`; CREATE TABLE `report` ( `id` INTEGER PRIMARY KEY AUTOINCREMENT, `begin` INTEGER NOT NULL, `end` INTEGER NOT NULL, `author_id` INTEGER NOT NULL REFERENCES `author`(`id`) ON UPDATE CASCADE ON DELETE CASCADE, `rcpt_domain_id` INTEGER DEFAULT NULL, `from_domain_id` INTEGER NOT NULL REFERENCES `domain`(`id`) ON UPDATE CASCADE ON DELETE CASCADE, `uuid` TEXT DEFAULT NULL ); DROP TABLE IF EXISTS `report_error`; CREATE TABLE "report_error" ( `report_id` INTEGER NOT NULL REFERENCES "report"("id") ON UPDATE CASCADE ON DELETE CASCADE, `error` TEXT NOT NULL, `time` TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL ); DROP TABLE IF EXISTS `report_policy_published`; CREATE TABLE `report_policy_published` ( `report_id` INTEGER NOT NULL REFERENCES "report"("id") ON UPDATE CASCADE ON DELETE CASCADE, `adkim` TEXT DEFAULT NULL, `aspf` TEXT DEFAULT NULL, `p` TEXT DEFAULT NULL, `sp` TEXT DEFAULT NULL, `pct` INTEGER DEFAULT NULL, `rua` TEXT DEFAULT NULL ); DROP TABLE IF EXISTS `report_record`; CREATE TABLE `report_record` ( `id` INTEGER PRIMARY KEY AUTOINCREMENT, `report_id` INTEGER NOT NULL REFERENCES "report"("id") ON UPDATE CASCADE ON DELETE CASCADE, `source_ip` varbinary(16) NOT NULL, `count` INTEGER DEFAULT NULL, `disposition` TEXT NOT NULL REFERENCES "fk_disposition"("disposition") ON UPDATE CASCADE ON DELETE NO ACTION, `dkim` TEXT DEFAULT NULL, `spf` TEXT DEFAULT NULL, `envelope_to_did` INTEGER DEFAULT NULL, `envelope_from_did` INTEGER DEFAULT NULL, `header_from_did` INTEGER NOT NULL ); DROP TABLE IF EXISTS `report_record_reason`; CREATE TABLE `report_record_reason` ( `report_record_id` INTEGER NOT NULL REFERENCES "report_record"("id") ON UPDATE CASCADE ON DELETE CASCADE, `type` TEXT NOT NULL REFERENCES "fk_disposition_reason"("type") ON UPDATE CASCADE ON DELETE CASCADE, `comment` TEXT DEFAULT NULL ); DROP TABLE IF EXISTS `report_record_dkim`; CREATE TABLE `report_record_dkim` ( `report_record_id` INTEGER NOT NULL REFERENCES "report_record"("id") ON UPDATE CASCADE ON DELETE CASCADE, `domain_id` INTEGER NOT NULL, `selector` TEXT DEFAULT NULL, `result` TEXT DEFAULT NULL REFERENCES "fk_dkim_result"("result") ON UPDATE CASCADE ON DELETE CASCADE, `human_result` TEXT DEFAULT NULL ); DROP TABLE IF EXISTS `report_record_spf`; CREATE TABLE `report_record_spf` ( `report_record_id` INTEGER NOT NULL REFERENCES "report_record"("id") ON UPDATE CASCADE ON DELETE CASCADE, `domain_id` INTEGER NOT NULL, `scope` TEXT DEFAULT NULL REFERENCES "fk_spf_scope"("scope") ON UPDATE CASCADE ON DELETE RESTRICT, `result` TEXT NOT NULL REFERENCES "fk_spf_result"("result") ON UPDATE CASCADE ON DELETE CASCADE ); Mail-DMARC-1.20260306/share/public_suffix_list000444000765000024 120623015152630466 20227 0ustar00mattstaff000000000000// This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at https://mozilla.org/MPL/2.0/. // Please pull this list from, and only from https://publicsuffix.org/list/public_suffix_list.dat, // rather than any other VCS sites. Pulling from any other URL is not guaranteed to be supported. // VERSION: 2026-03-06_02-20-37_UTC // COMMIT: a7621207f34b3a739a5cfb2c47a518b0b9054fe6 // Instructions on pulling and using this list can be found at https://publicsuffix.org/list/. // ===BEGIN ICANN DOMAINS=== // ac : http://nic.ac/rules.htm ac com.ac edu.ac gov.ac mil.ac net.ac org.ac // ad : https://www.iana.org/domains/root/db/ad.html // Confirmed by Amadeu Abril i Abril (CORE) 2024-11-17 ad // ae : https://www.iana.org/domains/root/db/ae.html ae ac.ae co.ae gov.ae mil.ae net.ae org.ae sch.ae // aero : https://information.aero/registration/policies/dmp aero // 2LDs airline.aero airport.aero // 2LDs (currently not accepting registration, seemingly never have) // As of 2024-07, these are marked as reserved for potential 3LD // registrations (clause 11 "allocated subdomains" in the 2006 TLD // policy), but the relevant industry partners have not opened them up // for registration. Current status can be determined from the TLD's // policy document: 2LDs that are open for registration must list // their policy in the TLD's policy. Any 2LD without such a policy is // not open for registrations. accident-investigation.aero accident-prevention.aero aerobatic.aero aeroclub.aero aerodrome.aero agents.aero air-surveillance.aero air-traffic-control.aero aircraft.aero airtraffic.aero ambulance.aero association.aero author.aero ballooning.aero broker.aero caa.aero cargo.aero catering.aero certification.aero championship.aero charter.aero civilaviation.aero club.aero conference.aero consultant.aero consulting.aero control.aero council.aero crew.aero design.aero dgca.aero educator.aero emergency.aero engine.aero engineer.aero entertainment.aero equipment.aero exchange.aero express.aero federation.aero flight.aero freight.aero fuel.aero gliding.aero government.aero groundhandling.aero group.aero hanggliding.aero homebuilt.aero insurance.aero journal.aero journalist.aero leasing.aero logistics.aero magazine.aero maintenance.aero marketplace.aero media.aero microlight.aero modelling.aero navigation.aero parachuting.aero paragliding.aero passenger-association.aero pilot.aero press.aero production.aero recreation.aero repbody.aero res.aero research.aero rotorcraft.aero safety.aero scientist.aero services.aero show.aero skydiving.aero software.aero student.aero taxi.aero trader.aero trading.aero trainer.aero union.aero workinggroup.aero works.aero // af : https://www.nic.af/domain-price af com.af edu.af gov.af net.af org.af // ag : http://www.nic.ag/prices.htm ag co.ag com.ag net.ag nom.ag org.ag // ai : http://nic.com.ai/ ai com.ai net.ai off.ai org.ai // al : http://www.ert.gov.al/ert_alb/faq_det.html?Id=31 al com.al edu.al gov.al mil.al net.al org.al // am : https://www.amnic.net/policy/en/Policy_EN.pdf // Confirmed by ISOC AM 2024-11-18 am co.am com.am commune.am net.am org.am // ao : https://www.iana.org/domains/root/db/ao.html // https://www.dns.ao/ao/ ao co.ao ed.ao edu.ao gov.ao gv.ao it.ao og.ao org.ao pb.ao // aq : https://www.iana.org/domains/root/db/aq.html aq // ar : https://nic.ar/es/nic-argentina/normativa ar bet.ar com.ar coop.ar edu.ar gob.ar gov.ar int.ar mil.ar musica.ar mutual.ar net.ar org.ar seg.ar senasa.ar tur.ar // arpa : https://www.iana.org/domains/root/db/arpa.html // Confirmed by registry 2008-06-18 arpa e164.arpa home.arpa in-addr.arpa ip6.arpa iris.arpa uri.arpa urn.arpa // as : https://www.iana.org/domains/root/db/as.html as gov.as // asia : https://www.iana.org/domains/root/db/asia.html asia // at : https://www.iana.org/domains/root/db/at.html // Confirmed by registry 2008-06-17 at ac.at sth.ac.at co.at gv.at or.at // au : https://www.iana.org/domains/root/db/au.html // https://www.auda.org.au/ // Confirmed by registry 2025-07-16 au // 2LDs asn.au com.au edu.au gov.au id.au net.au org.au // Historic 2LDs (closed to new registration, but sites still exist) conf.au oz.au // CGDNs : https://www.auda.org.au/au-domain-names/the-different-au-domain-names/state-and-territory-domain-names/ act.au nsw.au nt.au qld.au sa.au tas.au vic.au wa.au // 3LDs act.edu.au catholic.edu.au // eq.edu.au - Removed at the request of the Queensland Department of Education nsw.edu.au nt.edu.au qld.edu.au sa.edu.au tas.edu.au vic.edu.au wa.edu.au // act.gov.au - Bug 984824 - Removed at request of Greg Tankard // nsw.gov.au - Bug 547985 - Removed at request of // nt.gov.au - Bug 940478 - Removed at request of Greg Connors qld.gov.au sa.gov.au tas.gov.au vic.gov.au wa.gov.au // 4LDs // education.tas.edu.au - Removed at the request of the Department of Education Tasmania // schools.nsw.edu.au - Removed at the request of the New South Wales Department of Education. // aw : https://www.iana.org/domains/root/db/aw.html aw com.aw // ax : https://www.iana.org/domains/root/db/ax.html ax // az : https://www.iana.org/domains/root/db/az.html // Confirmed via https://whois.az/?page_id=10 2024-12-11 az biz.az co.az com.az edu.az gov.az info.az int.az mil.az name.az net.az org.az pp.az // No longer available for registration, however domains exist as of 2024-12-11 // see https://whois.az/?page_id=783 pro.az // ba : https://www.iana.org/domains/root/db/ba.html ba com.ba edu.ba gov.ba mil.ba net.ba org.ba // bb : https://www.iana.org/domains/root/db/bb.html bb biz.bb co.bb com.bb edu.bb gov.bb info.bb net.bb org.bb store.bb tv.bb // bd : https://www.iana.org/domains/root/db/bd.html // Confirmed by registry bd ac.bd ai.bd co.bd com.bd edu.bd gov.bd id.bd info.bd it.bd mil.bd net.bd org.bd sch.bd tv.bd // be : https://www.iana.org/domains/root/db/be.html // Confirmed by registry 2008-06-08 be ac.be // bf : https://www.iana.org/domains/root/db/bf.html bf gov.bf // bg : https://www.iana.org/domains/root/db/bg.html // https://www.register.bg/user/static/rules/en/index.html bg 0.bg 1.bg 2.bg 3.bg 4.bg 5.bg 6.bg 7.bg 8.bg 9.bg a.bg b.bg c.bg d.bg e.bg f.bg g.bg h.bg i.bg j.bg k.bg l.bg m.bg n.bg o.bg p.bg q.bg r.bg s.bg t.bg u.bg v.bg w.bg x.bg y.bg z.bg // bh : https://www.iana.org/domains/root/db/bh.html bh com.bh edu.bh gov.bh net.bh org.bh // bi : https://www.iana.org/domains/root/db/bi.html // http://whois.nic.bi/ bi co.bi com.bi edu.bi or.bi org.bi // biz : https://www.iana.org/domains/root/db/biz.html biz // bj : https://nic.bj/bj-suffixes.txt // Submitted by registry bj africa.bj agro.bj architectes.bj assur.bj avocats.bj co.bj com.bj eco.bj econo.bj edu.bj info.bj loisirs.bj money.bj net.bj org.bj ote.bj restaurant.bj resto.bj tourism.bj univ.bj // bm : https://www.bermudanic.bm/domain-registration/index.php bm com.bm edu.bm gov.bm net.bm org.bm // bn : http://www.bnnic.bn/faqs bn com.bn edu.bn gov.bn net.bn org.bn // bo : https://nic.bo // Confirmed by registry 2024-11-19 bo com.bo edu.bo gob.bo int.bo mil.bo net.bo org.bo tv.bo web.bo // Social Domains academia.bo agro.bo arte.bo blog.bo bolivia.bo ciencia.bo cooperativa.bo democracia.bo deporte.bo ecologia.bo economia.bo empresa.bo indigena.bo industria.bo info.bo medicina.bo movimiento.bo musica.bo natural.bo nombre.bo noticias.bo patria.bo plurinacional.bo politica.bo profesional.bo pueblo.bo revista.bo salud.bo tecnologia.bo tksat.bo transporte.bo wiki.bo // br : http://registro.br/dominio/categoria.html // Submitted by registry br 9guacu.br abc.br adm.br adv.br agr.br aju.br am.br anani.br aparecida.br api.br app.br arq.br art.br ato.br b.br barueri.br belem.br bet.br bhz.br bib.br bio.br blog.br bmd.br boavista.br bsb.br campinagrande.br campinas.br caxias.br cim.br cng.br cnt.br com.br contagem.br coop.br coz.br cri.br cuiaba.br curitiba.br def.br des.br det.br dev.br ecn.br eco.br edu.br emp.br enf.br eng.br esp.br etc.br eti.br far.br feira.br flog.br floripa.br fm.br fnd.br fortal.br fot.br foz.br fst.br g12.br geo.br ggf.br goiania.br gov.br // gov.br 26 states + df https://en.wikipedia.org/wiki/States_of_Brazil ac.gov.br al.gov.br am.gov.br ap.gov.br ba.gov.br ce.gov.br df.gov.br es.gov.br go.gov.br ma.gov.br mg.gov.br ms.gov.br mt.gov.br pa.gov.br pb.gov.br pe.gov.br pi.gov.br pr.gov.br rj.gov.br rn.gov.br ro.gov.br rr.gov.br rs.gov.br sc.gov.br se.gov.br sp.gov.br to.gov.br gru.br ia.br imb.br ind.br inf.br jab.br jampa.br jdf.br joinville.br jor.br jus.br leg.br leilao.br lel.br log.br londrina.br macapa.br maceio.br manaus.br maringa.br mat.br med.br mil.br morena.br mp.br mus.br natal.br net.br niteroi.br *.nom.br not.br ntr.br odo.br ong.br org.br osasco.br palmas.br poa.br ppg.br pro.br psc.br psi.br pvh.br qsl.br radio.br rec.br recife.br rep.br ribeirao.br rio.br riobranco.br riopreto.br salvador.br sampa.br santamaria.br santoandre.br saobernardo.br saogonca.br seg.br sjc.br slg.br slz.br social.br sorocaba.br srv.br taxi.br tc.br tec.br teo.br the.br tmp.br trd.br tur.br tv.br udi.br vet.br vix.br vlog.br wiki.br xyz.br zlg.br // bs : http://www.nic.bs/rules.html bs com.bs edu.bs gov.bs net.bs org.bs // bt : https://www.iana.org/domains/root/db/bt.html bt com.bt edu.bt gov.bt net.bt org.bt // bv : No registrations at this time. // Submitted by registry bv // bw : https://www.iana.org/domains/root/db/bw.html // https://nic.net.bw/bw-name-structure bw ac.bw co.bw gov.bw net.bw org.bw // by : https://www.iana.org/domains/root/db/by.html // http://tld.by/rules_2006_en.html // list of other 2nd level tlds ? by gov.by mil.by // Official information does not indicate that com.by is a reserved // second-level domain, but it's being used as one (see www.google.com.by and // www.yahoo.com.by, for example), so we list it here for safety's sake. com.by // http://hoster.by/ of.by // bz : https://www.iana.org/domains/root/db/bz.html // http://www.belizenic.bz/ bz co.bz com.bz edu.bz gov.bz net.bz org.bz // ca : https://www.iana.org/domains/root/db/ca.html ca // ca geographical names ab.ca bc.ca mb.ca nb.ca nf.ca nl.ca ns.ca nt.ca nu.ca on.ca pe.ca qc.ca sk.ca yk.ca // gc.ca: https://en.wikipedia.org/wiki/.gc.ca // see also: http://registry.gc.ca/en/SubdomainFAQ gc.ca // cat : https://www.iana.org/domains/root/db/cat.html cat // cc : https://www.iana.org/domains/root/db/cc.html cc // cd : https://www.iana.org/domains/root/db/cd.html // https://www.nic.cd cd gov.cd // cf : https://www.iana.org/domains/root/db/cf.html cf // cg : https://www.iana.org/domains/root/db/cg.html cg // ch : https://www.iana.org/domains/root/db/ch.html ch // ci : https://www.iana.org/domains/root/db/ci.html ci ac.ci aéroport.ci asso.ci co.ci com.ci ed.ci edu.ci go.ci gouv.ci int.ci net.ci or.ci org.ci // ck : https://www.iana.org/domains/root/db/ck.html *.ck !www.ck // cl : https://www.nic.cl // Confirmed by .CL registry cl co.cl gob.cl gov.cl mil.cl // cm : https://www.iana.org/domains/root/db/cm.html plus bug 981927 cm co.cm com.cm gov.cm net.cm // cn : https://www.iana.org/domains/root/db/cn.html // Submitted by registry cn ac.cn com.cn edu.cn gov.cn mil.cn net.cn org.cn å…¬å¸.cn 網絡.cn 网络.cn // cn geographic names ah.cn bj.cn cq.cn fj.cn gd.cn gs.cn gx.cn gz.cn ha.cn hb.cn he.cn hi.cn hk.cn hl.cn hn.cn jl.cn js.cn jx.cn ln.cn mo.cn nm.cn nx.cn qh.cn sc.cn sd.cn sh.cn sn.cn sx.cn tj.cn tw.cn xj.cn xz.cn yn.cn zj.cn // co : https://www.iana.org/domains/root/db/co.html // https://www.cointernet.com.co/como-funciona-un-dominio-restringido // Confirmed by registry 2024-11-18 co com.co edu.co gov.co mil.co net.co nom.co org.co // com : https://www.iana.org/domains/root/db/com.html com // coop : https://www.iana.org/domains/root/db/coop.html coop // cr : https://nic.cr/capitulo-1-registro-de-un-nombre-de-dominio/ cr ac.cr co.cr ed.cr fi.cr go.cr or.cr sa.cr // cu : https://www.iana.org/domains/root/db/cu.html cu com.cu edu.cu gob.cu inf.cu nat.cu net.cu org.cu // cv : https://www.iana.org/domains/root/db/cv.html // https://ola.cv/domain-extensions-under-cv/ // Confirmed by registry 2024-11-26 cv com.cv edu.cv id.cv int.cv net.cv nome.cv org.cv publ.cv // cw : https://www.uoc.cw/cw-registry // Confirmed by registry 2024-11-19 cw com.cw edu.cw net.cw org.cw // cx : https://www.iana.org/domains/root/db/cx.html // list of other 2nd level tlds ? cx gov.cx // cy : http://www.nic.cy/ // Submitted by Panayiotou Fotia // https://nic.cy/wp-content/uploads/2024/01/Create-Request-for-domain-name-registration-1.pdf cy ac.cy biz.cy com.cy ekloges.cy gov.cy ltd.cy mil.cy net.cy org.cy press.cy pro.cy tm.cy // cz : https://www.iana.org/domains/root/db/cz.html // Confirmed by registry 2025-08-06 cz gov.cz // de : https://www.iana.org/domains/root/db/de.html // Confirmed by registry (with technical // reservations) 2008-07-01 de // dj : https://www.iana.org/domains/root/db/dj.html dj // dk : https://www.iana.org/domains/root/db/dk.html // Confirmed by registry 2008-06-17 dk // dm : https://www.iana.org/domains/root/db/dm.html // https://nic.dm/policies/pdf/DMRulesandGuidelines2024v1.pdf // Confirmed by registry 2024-11-19 dm co.dm com.dm edu.dm gov.dm net.dm org.dm // do : https://www.iana.org/domains/root/db/do.html do art.do com.do edu.do gob.do gov.do mil.do net.do org.do sld.do web.do // dz : http://www.nic.dz/images/pdf_nic/charte.pdf dz art.dz asso.dz com.dz edu.dz gov.dz net.dz org.dz pol.dz soc.dz tm.dz // ec : https://www.nic.ec/ // Submitted by registry ec abg.ec adm.ec agron.ec arqt.ec art.ec bar.ec chef.ec com.ec cont.ec cpa.ec cue.ec dent.ec dgn.ec disco.ec doc.ec edu.ec eng.ec esm.ec fin.ec fot.ec gal.ec gob.ec gov.ec gye.ec ibr.ec info.ec k12.ec lat.ec loj.ec med.ec mil.ec mktg.ec mon.ec net.ec ntr.ec odont.ec org.ec pro.ec prof.ec psic.ec psiq.ec pub.ec rio.ec rrpp.ec sal.ec tech.ec tul.ec tur.ec uio.ec vet.ec xxx.ec // edu : https://www.iana.org/domains/root/db/edu.html edu // ee : https://www.internet.ee/domains/general-domains-and-procedure-for-registration-of-sub-domains-under-general-domains ee aip.ee com.ee edu.ee fie.ee gov.ee lib.ee med.ee org.ee pri.ee riik.ee // eg : https://www.iana.org/domains/root/db/eg.html // https://domain.eg/en/domain-rules/subdomain-names-types/ eg ac.eg com.eg edu.eg eun.eg gov.eg info.eg me.eg mil.eg name.eg net.eg org.eg sci.eg sport.eg tv.eg // er : https://www.iana.org/domains/root/db/er.html *.er // es : https://www.dominios.es/en es com.es edu.es gob.es nom.es org.es // et : https://www.iana.org/domains/root/db/et.html et biz.et com.et edu.et gov.et info.et name.et net.et org.et // eu : https://www.iana.org/domains/root/db/eu.html eu // fi : https://www.iana.org/domains/root/db/fi.html fi // aland.fi : https://www.iana.org/domains/root/db/ax.html // This domain is being phased out in favor of .ax. As there are still many // domains under aland.fi, we still keep it on the list until aland.fi is // completely removed. aland.fi // fj : https://www.iana.org/domains/root/db/fj.html fj ac.fj biz.fj com.fj edu.fj gov.fj id.fj info.fj mil.fj name.fj net.fj org.fj pro.fj // fk : https://www.iana.org/domains/root/db/fk.html *.fk // fm : https://www.iana.org/domains/root/db/fm.html fm com.fm edu.fm net.fm org.fm // fo : https://www.iana.org/domains/root/db/fo.html fo // fr : https://www.afnic.fr/ https://www.afnic.fr/wp-media/uploads/2022/12/afnic-naming-policy-2023-01-01.pdf fr asso.fr com.fr gouv.fr nom.fr prd.fr tm.fr // Other SLDs now selfmanaged out of AFNIC range. Former "domaines sectoriels", still registration suffixes avoues.fr cci.fr greta.fr huissier-justice.fr // ga : https://www.iana.org/domains/root/db/ga.html ga // gb : This registry is effectively dormant // Submitted by registry gb // gd : https://www.iana.org/domains/root/db/gd.html gd edu.gd gov.gd // ge : https://nic.ge/en/administrator/the-ge-domain-regulations // Confirmed by registry 2024-11-20 ge com.ge edu.ge gov.ge net.ge org.ge pvt.ge school.ge // gf : https://www.iana.org/domains/root/db/gf.html gf // gg : https://www.channelisles.net/register-1/register-direct // Confirmed by registry 2013-11-28 gg co.gg net.gg org.gg // gh : https://www.iana.org/domains/root/db/gh.html // https://www.nic.gh/ // Although domains directly at second level are not possible at the moment, // they have been possible for some time and may come back. gh biz.gh com.gh edu.gh gov.gh mil.gh net.gh org.gh // gi : http://www.nic.gi/rules.html gi com.gi edu.gi gov.gi ltd.gi mod.gi org.gi // gl : https://www.iana.org/domains/root/db/gl.html // http://nic.gl gl co.gl com.gl edu.gl net.gl org.gl // gm : http://www.nic.gm/htmlpages%5Cgm-policy.htm gm // gn : http://psg.com/dns/gn/gn.txt // Submitted by registry gn ac.gn com.gn edu.gn gov.gn net.gn org.gn // gov : https://www.iana.org/domains/root/db/gov.html gov // gp : http://www.nic.gp/index.php?lang=en gp asso.gp com.gp edu.gp mobi.gp net.gp org.gp // gq : https://www.iana.org/domains/root/db/gq.html gq // gr : https://www.iana.org/domains/root/db/gr.html // Submitted by registry gr com.gr edu.gr gov.gr net.gr org.gr // gs : https://www.iana.org/domains/root/db/gs.html gs // gt : https://www.gt/sitio/registration_policy.php?lang=en gt com.gt edu.gt gob.gt ind.gt mil.gt net.gt org.gt // gu : http://gadao.gov.gu/register.html // University of Guam : https://www.uog.edu // Submitted by uognoc@triton.uog.edu gu com.gu edu.gu gov.gu guam.gu info.gu net.gu org.gu web.gu // gw : https://www.iana.org/domains/root/db/gw.html // gw : https://nic.gw/regras/ gw // gy : https://www.iana.org/domains/root/db/gy.html // http://registry.gy/ gy co.gy com.gy edu.gy gov.gy net.gy org.gy // hk : https://www.hkirc.hk // Submitted by registry hk com.hk edu.hk gov.hk idv.hk net.hk org.hk 个人.hk 個人.hk å…¬å¸.hk 政府.hk 敎育.hk 教育.hk 箇人.hk 組織.hk 組织.hk 網絡.hk 網络.hk 组織.hk 组织.hk 网絡.hk 网络.hk // hm : https://www.iana.org/domains/root/db/hm.html hm // hn : https://www.iana.org/domains/root/db/hn.html hn com.hn edu.hn gob.hn mil.hn net.hn org.hn // hr : http://www.dns.hr/documents/pdf/HRTLD-regulations.pdf hr com.hr from.hr iz.hr name.hr // ht : http://www.nic.ht/info/charte.cfm ht adult.ht art.ht asso.ht com.ht coop.ht edu.ht firm.ht gouv.ht info.ht med.ht net.ht org.ht perso.ht pol.ht pro.ht rel.ht shop.ht // hu : https://www.iana.org/domains/root/db/hu.html // Confirmed by registry 2008-06-12 hu 2000.hu agrar.hu bolt.hu casino.hu city.hu co.hu erotica.hu erotika.hu film.hu forum.hu games.hu hotel.hu info.hu ingatlan.hu jogasz.hu konyvelo.hu lakas.hu media.hu news.hu org.hu priv.hu reklam.hu sex.hu shop.hu sport.hu suli.hu szex.hu tm.hu tozsde.hu utazas.hu video.hu // id : https://www.iana.org/domains/root/db/id.html id ac.id biz.id co.id desa.id go.id kop.id mil.id my.id net.id or.id ponpes.id sch.id web.id // xn--9tfky.id (.id, Und-Bali) ᬩᬮᬶ.id // ie : https://www.iana.org/domains/root/db/ie.html ie gov.ie // il : http://www.isoc.org.il/domains/ // see also: https://en.isoc.org.il/il-cctld/registration-rules // ISOC-IL (operated by .il Registry) il ac.il co.il gov.il idf.il k12.il muni.il net.il org.il // xn--4dbrk0ce ("Israel", Hebrew) : IL ישר×ל // xn--4dbgdty6c.xn--4dbrk0ce. ×קדמיה.ישר×ל // xn--5dbhl8d.xn--4dbrk0ce. ישוב.ישר×ל // xn--8dbq2a.xn--4dbrk0ce. צהל.ישר×ל // xn--hebda8b.xn--4dbrk0ce. ממשל.ישר×ל // im : https://www.nic.im/ // Submitted by registry im ac.im co.im ltd.co.im plc.co.im com.im net.im org.im tt.im tv.im // in : https://www.iana.org/domains/root/db/in.html // see also: https://registry.in/policies // Please note, that nic.in is not an official eTLD, but used by most // government institutions. // Confirmed by Gaurav Kansal 2025-11-06 in 5g.in 6g.in ac.in ai.in am.in bank.in bihar.in biz.in business.in ca.in cn.in co.in com.in coop.in cs.in delhi.in dr.in edu.in er.in fin.in firm.in gen.in gov.in gujarat.in ind.in info.in int.in internet.in io.in me.in mil.in net.in nic.in org.in pg.in post.in pro.in res.in travel.in tv.in uk.in up.in us.in // info : https://www.iana.org/domains/root/db/info.html info // int : https://www.iana.org/domains/root/db/int.html // Confirmed by registry 2008-06-18 int eu.int // io : http://www.nic.io/rules.htm io co.io com.io edu.io gov.io mil.io net.io nom.io org.io // iq : http://www.cmc.iq/english/iq/iqregister1.htm iq com.iq edu.iq gov.iq mil.iq net.iq org.iq // ir : http://www.nic.ir/Terms_and_Conditions_ir,_Appendix_1_Domain_Rules // Also see http://www.nic.ir/Internationalized_Domain_Names // Two .ir entries added at request of , 2010-04-16 ir ac.ir co.ir gov.ir id.ir net.ir org.ir sch.ir // xn--mgba3a4f16a.ir (.ir, Persian YEH) ایران.ir // xn--mgba3a4fra.ir (.ir, Arabic YEH) ايران.ir // is : http://www.isnic.is/domain/rules.php // Confirmed by registry 2024-11-17 is // it : https://www.iana.org/domains/root/db/it.html // https://www.nic.it/ it edu.it gov.it // Regions (3.3.1) // https://www.nic.it/en/manage-your-it/forms-and-docs -> "Assignment and Management of domain names" abr.it abruzzo.it aosta-valley.it aostavalley.it bas.it basilicata.it cal.it calabria.it cam.it campania.it emilia-romagna.it emiliaromagna.it emr.it friuli-v-giulia.it friuli-ve-giulia.it friuli-vegiulia.it friuli-venezia-giulia.it friuli-veneziagiulia.it friuli-vgiulia.it friuliv-giulia.it friulive-giulia.it friulivegiulia.it friulivenezia-giulia.it friuliveneziagiulia.it friulivgiulia.it fvg.it laz.it lazio.it lig.it liguria.it lom.it lombardia.it lombardy.it lucania.it mar.it marche.it mol.it molise.it piedmont.it piemonte.it pmn.it pug.it puglia.it sar.it sardegna.it sardinia.it sic.it sicilia.it sicily.it taa.it tos.it toscana.it trentin-sud-tirol.it trentin-süd-tirol.it trentin-sudtirol.it trentin-südtirol.it trentin-sued-tirol.it trentin-suedtirol.it trentino.it trentino-a-adige.it trentino-aadige.it trentino-alto-adige.it trentino-altoadige.it trentino-s-tirol.it trentino-stirol.it trentino-sud-tirol.it trentino-süd-tirol.it trentino-sudtirol.it trentino-südtirol.it trentino-sued-tirol.it trentino-suedtirol.it trentinoa-adige.it trentinoaadige.it trentinoalto-adige.it trentinoaltoadige.it trentinos-tirol.it trentinostirol.it trentinosud-tirol.it trentinosüd-tirol.it trentinosudtirol.it trentinosüdtirol.it trentinosued-tirol.it trentinosuedtirol.it trentinsud-tirol.it trentinsüd-tirol.it trentinsudtirol.it trentinsüdtirol.it trentinsued-tirol.it trentinsuedtirol.it tuscany.it umb.it umbria.it val-d-aosta.it val-daosta.it vald-aosta.it valdaosta.it valle-aosta.it valle-d-aosta.it valle-daosta.it valleaosta.it valled-aosta.it valledaosta.it vallee-aoste.it vallée-aoste.it vallee-d-aoste.it vallée-d-aoste.it valleeaoste.it valléeaoste.it valleedaoste.it valléedaoste.it vao.it vda.it ven.it veneto.it // Provinces (3.3.2) ag.it agrigento.it al.it alessandria.it alto-adige.it altoadige.it an.it ancona.it andria-barletta-trani.it andria-trani-barletta.it andriabarlettatrani.it andriatranibarletta.it ao.it aosta.it aoste.it ap.it aq.it aquila.it ar.it arezzo.it ascoli-piceno.it ascolipiceno.it asti.it at.it av.it avellino.it ba.it balsan.it balsan-sudtirol.it balsan-südtirol.it balsan-suedtirol.it bari.it barletta-trani-andria.it barlettatraniandria.it belluno.it benevento.it bergamo.it bg.it bi.it biella.it bl.it bn.it bo.it bologna.it bolzano.it bolzano-altoadige.it bozen.it bozen-sudtirol.it bozen-südtirol.it bozen-suedtirol.it br.it brescia.it brindisi.it bs.it bt.it bulsan.it bulsan-sudtirol.it bulsan-südtirol.it bulsan-suedtirol.it bz.it ca.it cagliari.it caltanissetta.it campidano-medio.it campidanomedio.it campobasso.it carbonia-iglesias.it carboniaiglesias.it carrara-massa.it carraramassa.it caserta.it catania.it catanzaro.it cb.it ce.it cesena-forli.it cesena-forlì.it cesenaforli.it cesenaforlì.it ch.it chieti.it ci.it cl.it cn.it co.it como.it cosenza.it cr.it cremona.it crotone.it cs.it ct.it cuneo.it cz.it dell-ogliastra.it dellogliastra.it en.it enna.it fc.it fe.it fermo.it ferrara.it fg.it fi.it firenze.it florence.it fm.it foggia.it forli-cesena.it forlì-cesena.it forlicesena.it forlìcesena.it fr.it frosinone.it ge.it genoa.it genova.it go.it gorizia.it gr.it grosseto.it iglesias-carbonia.it iglesiascarbonia.it im.it imperia.it is.it isernia.it kr.it la-spezia.it laquila.it laspezia.it latina.it lc.it le.it lecce.it lecco.it li.it livorno.it lo.it lodi.it lt.it lu.it lucca.it macerata.it mantova.it massa-carrara.it massacarrara.it matera.it mb.it mc.it me.it medio-campidano.it mediocampidano.it messina.it mi.it milan.it milano.it mn.it mo.it modena.it monza.it monza-brianza.it monza-e-della-brianza.it monzabrianza.it monzaebrianza.it monzaedellabrianza.it ms.it mt.it na.it naples.it napoli.it no.it novara.it nu.it nuoro.it og.it ogliastra.it olbia-tempio.it olbiatempio.it or.it oristano.it ot.it pa.it padova.it padua.it palermo.it parma.it pavia.it pc.it pd.it pe.it perugia.it pesaro-urbino.it pesarourbino.it pescara.it pg.it pi.it piacenza.it pisa.it pistoia.it pn.it po.it pordenone.it potenza.it pr.it prato.it pt.it pu.it pv.it pz.it ra.it ragusa.it ravenna.it rc.it re.it reggio-calabria.it reggio-emilia.it reggiocalabria.it reggioemilia.it rg.it ri.it rieti.it rimini.it rm.it rn.it ro.it roma.it rome.it rovigo.it sa.it salerno.it sassari.it savona.it si.it siena.it siracusa.it so.it sondrio.it sp.it sr.it ss.it südtirol.it suedtirol.it sv.it ta.it taranto.it te.it tempio-olbia.it tempioolbia.it teramo.it terni.it tn.it to.it torino.it tp.it tr.it trani-andria-barletta.it trani-barletta-andria.it traniandriabarletta.it tranibarlettaandria.it trapani.it trento.it treviso.it trieste.it ts.it turin.it tv.it ud.it udine.it urbino-pesaro.it urbinopesaro.it va.it varese.it vb.it vc.it ve.it venezia.it venice.it verbania.it vercelli.it verona.it vi.it vibo-valentia.it vibovalentia.it vicenza.it viterbo.it vr.it vs.it vt.it vv.it // je : https://www.iana.org/domains/root/db/je.html // Confirmed by registry 2013-11-28 je co.je net.je org.je // jm : http://www.com.jm/register.html *.jm // jo : https://www.dns.jo/JoFamily.aspx // Confirmed by registry 2024-11-17 jo agri.jo ai.jo com.jo edu.jo eng.jo fm.jo gov.jo mil.jo net.jo org.jo per.jo phd.jo sch.jo tv.jo // jobs : https://www.iana.org/domains/root/db/jobs.html jobs // jp : https://www.iana.org/domains/root/db/jp.html // http://jprs.co.jp/en/jpdomain.html // Confirmed by registry 2024-11-22 jp // jp organizational type names ac.jp ad.jp co.jp ed.jp go.jp gr.jp lg.jp ne.jp or.jp // jp prefecture type names aichi.jp akita.jp aomori.jp chiba.jp ehime.jp fukui.jp fukuoka.jp fukushima.jp gifu.jp gunma.jp hiroshima.jp hokkaido.jp hyogo.jp ibaraki.jp ishikawa.jp iwate.jp kagawa.jp kagoshima.jp kanagawa.jp kochi.jp kumamoto.jp kyoto.jp mie.jp miyagi.jp miyazaki.jp nagano.jp nagasaki.jp nara.jp niigata.jp oita.jp okayama.jp okinawa.jp osaka.jp saga.jp saitama.jp shiga.jp shimane.jp shizuoka.jp tochigi.jp tokushima.jp tokyo.jp tottori.jp toyama.jp wakayama.jp yamagata.jp yamaguchi.jp yamanashi.jp 三é‡.jp 京都.jp ä½è³€.jp 兵庫.jp 北海é“.jp åƒè‘‰.jp 和歌山.jp 埼玉.jp 大分.jp 大阪.jp 奈良.jp 宮城.jp 宮崎.jp 富山.jp å±±å£.jp 山形.jp 山梨.jp å²é˜œ.jp 岡山.jp 岩手.jp å³¶æ ¹.jp 広島.jp 徳島.jp 愛媛.jp 愛知.jp 新潟.jp æ±äº¬.jp 栃木.jp 沖縄.jp 滋賀.jp 熊本.jp 石å·.jp 神奈å·.jp ç¦äº•.jp ç¦å²¡.jp ç¦å³¶.jp ç§‹ç”°.jp 群馬.jp 茨城.jp é•·å´Ž.jp 長野.jp é’æ£®.jp é™å²¡.jp 香å·.jp 高知.jp é³¥å–.jp 鹿å…å³¶.jp // jp geographic type names // http://jprs.jp/doc/rule/saisoku-1.html // 2024-11-22: JPRS confirmed that jp geographic type names no longer accept new registrations. // Once all existing registrations expire (marking full discontinuation), these suffixes // will be removed from the PSL. *.kawasaki.jp !city.kawasaki.jp *.kitakyushu.jp !city.kitakyushu.jp *.kobe.jp !city.kobe.jp *.nagoya.jp !city.nagoya.jp *.sapporo.jp !city.sapporo.jp *.sendai.jp !city.sendai.jp *.yokohama.jp !city.yokohama.jp // 4th level registration aisai.aichi.jp ama.aichi.jp anjo.aichi.jp asuke.aichi.jp chiryu.aichi.jp chita.aichi.jp fuso.aichi.jp gamagori.aichi.jp handa.aichi.jp hazu.aichi.jp hekinan.aichi.jp higashiura.aichi.jp ichinomiya.aichi.jp inazawa.aichi.jp inuyama.aichi.jp isshiki.aichi.jp iwakura.aichi.jp kanie.aichi.jp kariya.aichi.jp kasugai.aichi.jp kira.aichi.jp kiyosu.aichi.jp komaki.aichi.jp konan.aichi.jp kota.aichi.jp mihama.aichi.jp miyoshi.aichi.jp nishio.aichi.jp nisshin.aichi.jp obu.aichi.jp oguchi.aichi.jp oharu.aichi.jp okazaki.aichi.jp owariasahi.aichi.jp seto.aichi.jp shikatsu.aichi.jp shinshiro.aichi.jp shitara.aichi.jp tahara.aichi.jp takahama.aichi.jp tobishima.aichi.jp toei.aichi.jp togo.aichi.jp tokai.aichi.jp tokoname.aichi.jp toyoake.aichi.jp toyohashi.aichi.jp toyokawa.aichi.jp toyone.aichi.jp toyota.aichi.jp tsushima.aichi.jp yatomi.aichi.jp akita.akita.jp daisen.akita.jp fujisato.akita.jp gojome.akita.jp hachirogata.akita.jp happou.akita.jp higashinaruse.akita.jp honjo.akita.jp honjyo.akita.jp ikawa.akita.jp kamikoani.akita.jp kamioka.akita.jp katagami.akita.jp kazuno.akita.jp kitaakita.akita.jp kosaka.akita.jp kyowa.akita.jp misato.akita.jp mitane.akita.jp moriyoshi.akita.jp nikaho.akita.jp noshiro.akita.jp odate.akita.jp oga.akita.jp ogata.akita.jp semboku.akita.jp yokote.akita.jp yurihonjo.akita.jp aomori.aomori.jp gonohe.aomori.jp hachinohe.aomori.jp hashikami.aomori.jp hiranai.aomori.jp hirosaki.aomori.jp itayanagi.aomori.jp kuroishi.aomori.jp misawa.aomori.jp mutsu.aomori.jp nakadomari.aomori.jp noheji.aomori.jp oirase.aomori.jp owani.aomori.jp rokunohe.aomori.jp sannohe.aomori.jp shichinohe.aomori.jp shingo.aomori.jp takko.aomori.jp towada.aomori.jp tsugaru.aomori.jp tsuruta.aomori.jp abiko.chiba.jp asahi.chiba.jp chonan.chiba.jp chosei.chiba.jp choshi.chiba.jp chuo.chiba.jp funabashi.chiba.jp futtsu.chiba.jp hanamigawa.chiba.jp ichihara.chiba.jp ichikawa.chiba.jp ichinomiya.chiba.jp inzai.chiba.jp isumi.chiba.jp kamagaya.chiba.jp kamogawa.chiba.jp kashiwa.chiba.jp katori.chiba.jp katsuura.chiba.jp kimitsu.chiba.jp kisarazu.chiba.jp kozaki.chiba.jp kujukuri.chiba.jp kyonan.chiba.jp matsudo.chiba.jp midori.chiba.jp mihama.chiba.jp minamiboso.chiba.jp mobara.chiba.jp mutsuzawa.chiba.jp nagara.chiba.jp nagareyama.chiba.jp narashino.chiba.jp narita.chiba.jp noda.chiba.jp oamishirasato.chiba.jp omigawa.chiba.jp onjuku.chiba.jp otaki.chiba.jp sakae.chiba.jp sakura.chiba.jp shimofusa.chiba.jp shirako.chiba.jp shiroi.chiba.jp shisui.chiba.jp sodegaura.chiba.jp sosa.chiba.jp tako.chiba.jp tateyama.chiba.jp togane.chiba.jp tohnosho.chiba.jp tomisato.chiba.jp urayasu.chiba.jp yachimata.chiba.jp yachiyo.chiba.jp yokaichiba.chiba.jp yokoshibahikari.chiba.jp yotsukaido.chiba.jp ainan.ehime.jp honai.ehime.jp ikata.ehime.jp imabari.ehime.jp iyo.ehime.jp kamijima.ehime.jp kihoku.ehime.jp kumakogen.ehime.jp masaki.ehime.jp matsuno.ehime.jp matsuyama.ehime.jp namikata.ehime.jp niihama.ehime.jp ozu.ehime.jp saijo.ehime.jp seiyo.ehime.jp shikokuchuo.ehime.jp tobe.ehime.jp toon.ehime.jp uchiko.ehime.jp uwajima.ehime.jp yawatahama.ehime.jp echizen.fukui.jp eiheiji.fukui.jp fukui.fukui.jp ikeda.fukui.jp katsuyama.fukui.jp mihama.fukui.jp minamiechizen.fukui.jp obama.fukui.jp ohi.fukui.jp ono.fukui.jp sabae.fukui.jp sakai.fukui.jp takahama.fukui.jp tsuruga.fukui.jp wakasa.fukui.jp ashiya.fukuoka.jp buzen.fukuoka.jp chikugo.fukuoka.jp chikuho.fukuoka.jp chikujo.fukuoka.jp chikushino.fukuoka.jp chikuzen.fukuoka.jp chuo.fukuoka.jp dazaifu.fukuoka.jp fukuchi.fukuoka.jp hakata.fukuoka.jp higashi.fukuoka.jp hirokawa.fukuoka.jp hisayama.fukuoka.jp iizuka.fukuoka.jp inatsuki.fukuoka.jp kaho.fukuoka.jp kasuga.fukuoka.jp kasuya.fukuoka.jp kawara.fukuoka.jp keisen.fukuoka.jp koga.fukuoka.jp kurate.fukuoka.jp kurogi.fukuoka.jp kurume.fukuoka.jp minami.fukuoka.jp miyako.fukuoka.jp miyama.fukuoka.jp miyawaka.fukuoka.jp mizumaki.fukuoka.jp munakata.fukuoka.jp nakagawa.fukuoka.jp nakama.fukuoka.jp nishi.fukuoka.jp nogata.fukuoka.jp ogori.fukuoka.jp okagaki.fukuoka.jp okawa.fukuoka.jp oki.fukuoka.jp omuta.fukuoka.jp onga.fukuoka.jp onojo.fukuoka.jp oto.fukuoka.jp saigawa.fukuoka.jp sasaguri.fukuoka.jp shingu.fukuoka.jp shinyoshitomi.fukuoka.jp shonai.fukuoka.jp soeda.fukuoka.jp sue.fukuoka.jp tachiarai.fukuoka.jp tagawa.fukuoka.jp takata.fukuoka.jp toho.fukuoka.jp toyotsu.fukuoka.jp tsuiki.fukuoka.jp ukiha.fukuoka.jp umi.fukuoka.jp usui.fukuoka.jp yamada.fukuoka.jp yame.fukuoka.jp yanagawa.fukuoka.jp yukuhashi.fukuoka.jp aizubange.fukushima.jp aizumisato.fukushima.jp aizuwakamatsu.fukushima.jp asakawa.fukushima.jp bandai.fukushima.jp date.fukushima.jp fukushima.fukushima.jp furudono.fukushima.jp futaba.fukushima.jp hanawa.fukushima.jp higashi.fukushima.jp hirata.fukushima.jp hirono.fukushima.jp iitate.fukushima.jp inawashiro.fukushima.jp ishikawa.fukushima.jp iwaki.fukushima.jp izumizaki.fukushima.jp kagamiishi.fukushima.jp kaneyama.fukushima.jp kawamata.fukushima.jp kitakata.fukushima.jp kitashiobara.fukushima.jp koori.fukushima.jp koriyama.fukushima.jp kunimi.fukushima.jp miharu.fukushima.jp mishima.fukushima.jp namie.fukushima.jp nango.fukushima.jp nishiaizu.fukushima.jp nishigo.fukushima.jp okuma.fukushima.jp omotego.fukushima.jp ono.fukushima.jp otama.fukushima.jp samegawa.fukushima.jp shimogo.fukushima.jp shirakawa.fukushima.jp showa.fukushima.jp soma.fukushima.jp sukagawa.fukushima.jp taishin.fukushima.jp tamakawa.fukushima.jp tanagura.fukushima.jp tenei.fukushima.jp yabuki.fukushima.jp yamato.fukushima.jp yamatsuri.fukushima.jp yanaizu.fukushima.jp yugawa.fukushima.jp anpachi.gifu.jp ena.gifu.jp gifu.gifu.jp ginan.gifu.jp godo.gifu.jp gujo.gifu.jp hashima.gifu.jp hichiso.gifu.jp hida.gifu.jp higashishirakawa.gifu.jp ibigawa.gifu.jp ikeda.gifu.jp kakamigahara.gifu.jp kani.gifu.jp kasahara.gifu.jp kasamatsu.gifu.jp kawaue.gifu.jp kitagata.gifu.jp mino.gifu.jp minokamo.gifu.jp mitake.gifu.jp mizunami.gifu.jp motosu.gifu.jp nakatsugawa.gifu.jp ogaki.gifu.jp sakahogi.gifu.jp seki.gifu.jp sekigahara.gifu.jp shirakawa.gifu.jp tajimi.gifu.jp takayama.gifu.jp tarui.gifu.jp toki.gifu.jp tomika.gifu.jp wanouchi.gifu.jp yamagata.gifu.jp yaotsu.gifu.jp yoro.gifu.jp annaka.gunma.jp chiyoda.gunma.jp fujioka.gunma.jp higashiagatsuma.gunma.jp isesaki.gunma.jp itakura.gunma.jp kanna.gunma.jp kanra.gunma.jp katashina.gunma.jp kawaba.gunma.jp kiryu.gunma.jp kusatsu.gunma.jp maebashi.gunma.jp meiwa.gunma.jp midori.gunma.jp minakami.gunma.jp naganohara.gunma.jp nakanojo.gunma.jp nanmoku.gunma.jp numata.gunma.jp oizumi.gunma.jp ora.gunma.jp ota.gunma.jp shibukawa.gunma.jp shimonita.gunma.jp shinto.gunma.jp showa.gunma.jp takasaki.gunma.jp takayama.gunma.jp tamamura.gunma.jp tatebayashi.gunma.jp tomioka.gunma.jp tsukiyono.gunma.jp tsumagoi.gunma.jp ueno.gunma.jp yoshioka.gunma.jp asaminami.hiroshima.jp daiwa.hiroshima.jp etajima.hiroshima.jp fuchu.hiroshima.jp fukuyama.hiroshima.jp hatsukaichi.hiroshima.jp higashihiroshima.hiroshima.jp hongo.hiroshima.jp jinsekikogen.hiroshima.jp kaita.hiroshima.jp kui.hiroshima.jp kumano.hiroshima.jp kure.hiroshima.jp mihara.hiroshima.jp miyoshi.hiroshima.jp naka.hiroshima.jp onomichi.hiroshima.jp osakikamijima.hiroshima.jp otake.hiroshima.jp saka.hiroshima.jp sera.hiroshima.jp seranishi.hiroshima.jp shinichi.hiroshima.jp shobara.hiroshima.jp takehara.hiroshima.jp abashiri.hokkaido.jp abira.hokkaido.jp aibetsu.hokkaido.jp akabira.hokkaido.jp akkeshi.hokkaido.jp asahikawa.hokkaido.jp ashibetsu.hokkaido.jp ashoro.hokkaido.jp assabu.hokkaido.jp atsuma.hokkaido.jp bibai.hokkaido.jp biei.hokkaido.jp bifuka.hokkaido.jp bihoro.hokkaido.jp biratori.hokkaido.jp chippubetsu.hokkaido.jp chitose.hokkaido.jp date.hokkaido.jp ebetsu.hokkaido.jp embetsu.hokkaido.jp eniwa.hokkaido.jp erimo.hokkaido.jp esan.hokkaido.jp esashi.hokkaido.jp fukagawa.hokkaido.jp fukushima.hokkaido.jp furano.hokkaido.jp furubira.hokkaido.jp haboro.hokkaido.jp hakodate.hokkaido.jp hamatonbetsu.hokkaido.jp hidaka.hokkaido.jp higashikagura.hokkaido.jp higashikawa.hokkaido.jp hiroo.hokkaido.jp hokuryu.hokkaido.jp hokuto.hokkaido.jp honbetsu.hokkaido.jp horokanai.hokkaido.jp horonobe.hokkaido.jp ikeda.hokkaido.jp imakane.hokkaido.jp ishikari.hokkaido.jp iwamizawa.hokkaido.jp iwanai.hokkaido.jp kamifurano.hokkaido.jp kamikawa.hokkaido.jp kamishihoro.hokkaido.jp kamisunagawa.hokkaido.jp kamoenai.hokkaido.jp kayabe.hokkaido.jp kembuchi.hokkaido.jp kikonai.hokkaido.jp kimobetsu.hokkaido.jp kitahiroshima.hokkaido.jp kitami.hokkaido.jp kiyosato.hokkaido.jp koshimizu.hokkaido.jp kunneppu.hokkaido.jp kuriyama.hokkaido.jp kuromatsunai.hokkaido.jp kushiro.hokkaido.jp kutchan.hokkaido.jp kyowa.hokkaido.jp mashike.hokkaido.jp matsumae.hokkaido.jp mikasa.hokkaido.jp minamifurano.hokkaido.jp mombetsu.hokkaido.jp moseushi.hokkaido.jp mukawa.hokkaido.jp muroran.hokkaido.jp naie.hokkaido.jp nakagawa.hokkaido.jp nakasatsunai.hokkaido.jp nakatombetsu.hokkaido.jp nanae.hokkaido.jp nanporo.hokkaido.jp nayoro.hokkaido.jp nemuro.hokkaido.jp niikappu.hokkaido.jp niki.hokkaido.jp nishiokoppe.hokkaido.jp noboribetsu.hokkaido.jp numata.hokkaido.jp obihiro.hokkaido.jp obira.hokkaido.jp oketo.hokkaido.jp okoppe.hokkaido.jp otaru.hokkaido.jp otobe.hokkaido.jp otofuke.hokkaido.jp otoineppu.hokkaido.jp oumu.hokkaido.jp ozora.hokkaido.jp pippu.hokkaido.jp rankoshi.hokkaido.jp rebun.hokkaido.jp rikubetsu.hokkaido.jp rishiri.hokkaido.jp rishirifuji.hokkaido.jp saroma.hokkaido.jp sarufutsu.hokkaido.jp shakotan.hokkaido.jp shari.hokkaido.jp shibecha.hokkaido.jp shibetsu.hokkaido.jp shikabe.hokkaido.jp shikaoi.hokkaido.jp shimamaki.hokkaido.jp shimizu.hokkaido.jp shimokawa.hokkaido.jp shinshinotsu.hokkaido.jp shintoku.hokkaido.jp shiranuka.hokkaido.jp shiraoi.hokkaido.jp shiriuchi.hokkaido.jp sobetsu.hokkaido.jp sunagawa.hokkaido.jp taiki.hokkaido.jp takasu.hokkaido.jp takikawa.hokkaido.jp takinoue.hokkaido.jp teshikaga.hokkaido.jp tobetsu.hokkaido.jp tohma.hokkaido.jp tomakomai.hokkaido.jp tomari.hokkaido.jp toya.hokkaido.jp toyako.hokkaido.jp toyotomi.hokkaido.jp toyoura.hokkaido.jp tsubetsu.hokkaido.jp tsukigata.hokkaido.jp urakawa.hokkaido.jp urausu.hokkaido.jp uryu.hokkaido.jp utashinai.hokkaido.jp wakkanai.hokkaido.jp wassamu.hokkaido.jp yakumo.hokkaido.jp yoichi.hokkaido.jp aioi.hyogo.jp akashi.hyogo.jp ako.hyogo.jp amagasaki.hyogo.jp aogaki.hyogo.jp asago.hyogo.jp ashiya.hyogo.jp awaji.hyogo.jp fukusaki.hyogo.jp goshiki.hyogo.jp harima.hyogo.jp himeji.hyogo.jp ichikawa.hyogo.jp inagawa.hyogo.jp itami.hyogo.jp kakogawa.hyogo.jp kamigori.hyogo.jp kamikawa.hyogo.jp kasai.hyogo.jp kasuga.hyogo.jp kawanishi.hyogo.jp miki.hyogo.jp minamiawaji.hyogo.jp nishinomiya.hyogo.jp nishiwaki.hyogo.jp ono.hyogo.jp sanda.hyogo.jp sannan.hyogo.jp sasayama.hyogo.jp sayo.hyogo.jp shingu.hyogo.jp shinonsen.hyogo.jp shiso.hyogo.jp sumoto.hyogo.jp taishi.hyogo.jp taka.hyogo.jp takarazuka.hyogo.jp takasago.hyogo.jp takino.hyogo.jp tamba.hyogo.jp tatsuno.hyogo.jp toyooka.hyogo.jp yabu.hyogo.jp yashiro.hyogo.jp yoka.hyogo.jp yokawa.hyogo.jp ami.ibaraki.jp asahi.ibaraki.jp bando.ibaraki.jp chikusei.ibaraki.jp daigo.ibaraki.jp fujishiro.ibaraki.jp hitachi.ibaraki.jp hitachinaka.ibaraki.jp hitachiomiya.ibaraki.jp hitachiota.ibaraki.jp ibaraki.ibaraki.jp ina.ibaraki.jp inashiki.ibaraki.jp itako.ibaraki.jp iwama.ibaraki.jp joso.ibaraki.jp kamisu.ibaraki.jp kasama.ibaraki.jp kashima.ibaraki.jp kasumigaura.ibaraki.jp koga.ibaraki.jp miho.ibaraki.jp mito.ibaraki.jp moriya.ibaraki.jp naka.ibaraki.jp namegata.ibaraki.jp oarai.ibaraki.jp ogawa.ibaraki.jp omitama.ibaraki.jp ryugasaki.ibaraki.jp sakai.ibaraki.jp sakuragawa.ibaraki.jp shimodate.ibaraki.jp shimotsuma.ibaraki.jp shirosato.ibaraki.jp sowa.ibaraki.jp suifu.ibaraki.jp takahagi.ibaraki.jp tamatsukuri.ibaraki.jp tokai.ibaraki.jp tomobe.ibaraki.jp tone.ibaraki.jp toride.ibaraki.jp tsuchiura.ibaraki.jp tsukuba.ibaraki.jp uchihara.ibaraki.jp ushiku.ibaraki.jp yachiyo.ibaraki.jp yamagata.ibaraki.jp yawara.ibaraki.jp yuki.ibaraki.jp anamizu.ishikawa.jp hakui.ishikawa.jp hakusan.ishikawa.jp kaga.ishikawa.jp kahoku.ishikawa.jp kanazawa.ishikawa.jp kawakita.ishikawa.jp komatsu.ishikawa.jp nakanoto.ishikawa.jp nanao.ishikawa.jp nomi.ishikawa.jp nonoichi.ishikawa.jp noto.ishikawa.jp shika.ishikawa.jp suzu.ishikawa.jp tsubata.ishikawa.jp tsurugi.ishikawa.jp uchinada.ishikawa.jp wajima.ishikawa.jp fudai.iwate.jp fujisawa.iwate.jp hanamaki.iwate.jp hiraizumi.iwate.jp hirono.iwate.jp ichinohe.iwate.jp ichinoseki.iwate.jp iwaizumi.iwate.jp iwate.iwate.jp joboji.iwate.jp kamaishi.iwate.jp kanegasaki.iwate.jp karumai.iwate.jp kawai.iwate.jp kitakami.iwate.jp kuji.iwate.jp kunohe.iwate.jp kuzumaki.iwate.jp miyako.iwate.jp mizusawa.iwate.jp morioka.iwate.jp ninohe.iwate.jp noda.iwate.jp ofunato.iwate.jp oshu.iwate.jp otsuchi.iwate.jp rikuzentakata.iwate.jp shiwa.iwate.jp shizukuishi.iwate.jp sumita.iwate.jp tanohata.iwate.jp tono.iwate.jp yahaba.iwate.jp yamada.iwate.jp ayagawa.kagawa.jp higashikagawa.kagawa.jp kanonji.kagawa.jp kotohira.kagawa.jp manno.kagawa.jp marugame.kagawa.jp mitoyo.kagawa.jp naoshima.kagawa.jp sanuki.kagawa.jp tadotsu.kagawa.jp takamatsu.kagawa.jp tonosho.kagawa.jp uchinomi.kagawa.jp utazu.kagawa.jp zentsuji.kagawa.jp akune.kagoshima.jp amami.kagoshima.jp hioki.kagoshima.jp isa.kagoshima.jp isen.kagoshima.jp izumi.kagoshima.jp kagoshima.kagoshima.jp kanoya.kagoshima.jp kawanabe.kagoshima.jp kinko.kagoshima.jp kouyama.kagoshima.jp makurazaki.kagoshima.jp matsumoto.kagoshima.jp minamitane.kagoshima.jp nakatane.kagoshima.jp nishinoomote.kagoshima.jp satsumasendai.kagoshima.jp soo.kagoshima.jp tarumizu.kagoshima.jp yusui.kagoshima.jp aikawa.kanagawa.jp atsugi.kanagawa.jp ayase.kanagawa.jp chigasaki.kanagawa.jp ebina.kanagawa.jp fujisawa.kanagawa.jp hadano.kanagawa.jp hakone.kanagawa.jp hiratsuka.kanagawa.jp isehara.kanagawa.jp kaisei.kanagawa.jp kamakura.kanagawa.jp kiyokawa.kanagawa.jp matsuda.kanagawa.jp minamiashigara.kanagawa.jp miura.kanagawa.jp nakai.kanagawa.jp ninomiya.kanagawa.jp odawara.kanagawa.jp oi.kanagawa.jp oiso.kanagawa.jp sagamihara.kanagawa.jp samukawa.kanagawa.jp tsukui.kanagawa.jp yamakita.kanagawa.jp yamato.kanagawa.jp yokosuka.kanagawa.jp yugawara.kanagawa.jp zama.kanagawa.jp zushi.kanagawa.jp aki.kochi.jp geisei.kochi.jp hidaka.kochi.jp higashitsuno.kochi.jp ino.kochi.jp kagami.kochi.jp kami.kochi.jp kitagawa.kochi.jp kochi.kochi.jp mihara.kochi.jp motoyama.kochi.jp muroto.kochi.jp nahari.kochi.jp nakamura.kochi.jp nankoku.kochi.jp nishitosa.kochi.jp niyodogawa.kochi.jp ochi.kochi.jp okawa.kochi.jp otoyo.kochi.jp otsuki.kochi.jp sakawa.kochi.jp sukumo.kochi.jp susaki.kochi.jp tosa.kochi.jp tosashimizu.kochi.jp toyo.kochi.jp tsuno.kochi.jp umaji.kochi.jp yasuda.kochi.jp yusuhara.kochi.jp amakusa.kumamoto.jp arao.kumamoto.jp aso.kumamoto.jp choyo.kumamoto.jp gyokuto.kumamoto.jp kamiamakusa.kumamoto.jp kikuchi.kumamoto.jp kumamoto.kumamoto.jp mashiki.kumamoto.jp mifune.kumamoto.jp minamata.kumamoto.jp minamioguni.kumamoto.jp nagasu.kumamoto.jp nishihara.kumamoto.jp oguni.kumamoto.jp ozu.kumamoto.jp sumoto.kumamoto.jp takamori.kumamoto.jp uki.kumamoto.jp uto.kumamoto.jp yamaga.kumamoto.jp yamato.kumamoto.jp yatsushiro.kumamoto.jp ayabe.kyoto.jp fukuchiyama.kyoto.jp higashiyama.kyoto.jp ide.kyoto.jp ine.kyoto.jp joyo.kyoto.jp kameoka.kyoto.jp kamo.kyoto.jp kita.kyoto.jp kizu.kyoto.jp kumiyama.kyoto.jp kyotamba.kyoto.jp kyotanabe.kyoto.jp kyotango.kyoto.jp maizuru.kyoto.jp minami.kyoto.jp minamiyamashiro.kyoto.jp miyazu.kyoto.jp muko.kyoto.jp nagaokakyo.kyoto.jp nakagyo.kyoto.jp nantan.kyoto.jp oyamazaki.kyoto.jp sakyo.kyoto.jp seika.kyoto.jp tanabe.kyoto.jp uji.kyoto.jp ujitawara.kyoto.jp wazuka.kyoto.jp yamashina.kyoto.jp yawata.kyoto.jp asahi.mie.jp inabe.mie.jp ise.mie.jp kameyama.mie.jp kawagoe.mie.jp kiho.mie.jp kisosaki.mie.jp kiwa.mie.jp komono.mie.jp kumano.mie.jp kuwana.mie.jp matsusaka.mie.jp meiwa.mie.jp mihama.mie.jp minamiise.mie.jp misugi.mie.jp miyama.mie.jp nabari.mie.jp shima.mie.jp suzuka.mie.jp tado.mie.jp taiki.mie.jp taki.mie.jp tamaki.mie.jp toba.mie.jp tsu.mie.jp udono.mie.jp ureshino.mie.jp watarai.mie.jp yokkaichi.mie.jp furukawa.miyagi.jp higashimatsushima.miyagi.jp ishinomaki.miyagi.jp iwanuma.miyagi.jp kakuda.miyagi.jp kami.miyagi.jp kawasaki.miyagi.jp marumori.miyagi.jp matsushima.miyagi.jp minamisanriku.miyagi.jp misato.miyagi.jp murata.miyagi.jp natori.miyagi.jp ogawara.miyagi.jp ohira.miyagi.jp onagawa.miyagi.jp osaki.miyagi.jp rifu.miyagi.jp semine.miyagi.jp shibata.miyagi.jp shichikashuku.miyagi.jp shikama.miyagi.jp shiogama.miyagi.jp shiroishi.miyagi.jp tagajo.miyagi.jp taiwa.miyagi.jp tome.miyagi.jp tomiya.miyagi.jp wakuya.miyagi.jp watari.miyagi.jp yamamoto.miyagi.jp zao.miyagi.jp aya.miyazaki.jp ebino.miyazaki.jp gokase.miyazaki.jp hyuga.miyazaki.jp kadogawa.miyazaki.jp kawaminami.miyazaki.jp kijo.miyazaki.jp kitagawa.miyazaki.jp kitakata.miyazaki.jp kitaura.miyazaki.jp kobayashi.miyazaki.jp kunitomi.miyazaki.jp kushima.miyazaki.jp mimata.miyazaki.jp miyakonojo.miyazaki.jp miyazaki.miyazaki.jp morotsuka.miyazaki.jp nichinan.miyazaki.jp nishimera.miyazaki.jp nobeoka.miyazaki.jp saito.miyazaki.jp shiiba.miyazaki.jp shintomi.miyazaki.jp takaharu.miyazaki.jp takanabe.miyazaki.jp takazaki.miyazaki.jp tsuno.miyazaki.jp achi.nagano.jp agematsu.nagano.jp anan.nagano.jp aoki.nagano.jp asahi.nagano.jp azumino.nagano.jp chikuhoku.nagano.jp chikuma.nagano.jp chino.nagano.jp fujimi.nagano.jp hakuba.nagano.jp hara.nagano.jp hiraya.nagano.jp iida.nagano.jp iijima.nagano.jp iiyama.nagano.jp iizuna.nagano.jp ikeda.nagano.jp ikusaka.nagano.jp ina.nagano.jp karuizawa.nagano.jp kawakami.nagano.jp kiso.nagano.jp kisofukushima.nagano.jp kitaaiki.nagano.jp komagane.nagano.jp komoro.nagano.jp matsukawa.nagano.jp matsumoto.nagano.jp miasa.nagano.jp minamiaiki.nagano.jp minamimaki.nagano.jp minamiminowa.nagano.jp minowa.nagano.jp miyada.nagano.jp miyota.nagano.jp mochizuki.nagano.jp nagano.nagano.jp nagawa.nagano.jp nagiso.nagano.jp nakagawa.nagano.jp nakano.nagano.jp nozawaonsen.nagano.jp obuse.nagano.jp ogawa.nagano.jp okaya.nagano.jp omachi.nagano.jp omi.nagano.jp ookuwa.nagano.jp ooshika.nagano.jp otaki.nagano.jp otari.nagano.jp sakae.nagano.jp sakaki.nagano.jp saku.nagano.jp sakuho.nagano.jp shimosuwa.nagano.jp shinanomachi.nagano.jp shiojiri.nagano.jp suwa.nagano.jp suzaka.nagano.jp takagi.nagano.jp takamori.nagano.jp takayama.nagano.jp tateshina.nagano.jp tatsuno.nagano.jp togakushi.nagano.jp togura.nagano.jp tomi.nagano.jp ueda.nagano.jp wada.nagano.jp yamagata.nagano.jp yamanouchi.nagano.jp yasaka.nagano.jp yasuoka.nagano.jp chijiwa.nagasaki.jp futsu.nagasaki.jp goto.nagasaki.jp hasami.nagasaki.jp hirado.nagasaki.jp iki.nagasaki.jp isahaya.nagasaki.jp kawatana.nagasaki.jp kuchinotsu.nagasaki.jp matsuura.nagasaki.jp nagasaki.nagasaki.jp obama.nagasaki.jp omura.nagasaki.jp oseto.nagasaki.jp saikai.nagasaki.jp sasebo.nagasaki.jp seihi.nagasaki.jp shimabara.nagasaki.jp shinkamigoto.nagasaki.jp togitsu.nagasaki.jp tsushima.nagasaki.jp unzen.nagasaki.jp ando.nara.jp gose.nara.jp heguri.nara.jp higashiyoshino.nara.jp ikaruga.nara.jp ikoma.nara.jp kamikitayama.nara.jp kanmaki.nara.jp kashiba.nara.jp kashihara.nara.jp katsuragi.nara.jp kawai.nara.jp kawakami.nara.jp kawanishi.nara.jp koryo.nara.jp kurotaki.nara.jp mitsue.nara.jp miyake.nara.jp nara.nara.jp nosegawa.nara.jp oji.nara.jp ouda.nara.jp oyodo.nara.jp sakurai.nara.jp sango.nara.jp shimoichi.nara.jp shimokitayama.nara.jp shinjo.nara.jp soni.nara.jp takatori.nara.jp tawaramoto.nara.jp tenkawa.nara.jp tenri.nara.jp uda.nara.jp yamatokoriyama.nara.jp yamatotakada.nara.jp yamazoe.nara.jp yoshino.nara.jp aga.niigata.jp agano.niigata.jp gosen.niigata.jp itoigawa.niigata.jp izumozaki.niigata.jp joetsu.niigata.jp kamo.niigata.jp kariwa.niigata.jp kashiwazaki.niigata.jp minamiuonuma.niigata.jp mitsuke.niigata.jp muika.niigata.jp murakami.niigata.jp myoko.niigata.jp nagaoka.niigata.jp niigata.niigata.jp ojiya.niigata.jp omi.niigata.jp sado.niigata.jp sanjo.niigata.jp seiro.niigata.jp seirou.niigata.jp sekikawa.niigata.jp shibata.niigata.jp tagami.niigata.jp tainai.niigata.jp tochio.niigata.jp tokamachi.niigata.jp tsubame.niigata.jp tsunan.niigata.jp uonuma.niigata.jp yahiko.niigata.jp yoita.niigata.jp yuzawa.niigata.jp beppu.oita.jp bungoono.oita.jp bungotakada.oita.jp hasama.oita.jp hiji.oita.jp himeshima.oita.jp hita.oita.jp kamitsue.oita.jp kokonoe.oita.jp kuju.oita.jp kunisaki.oita.jp kusu.oita.jp oita.oita.jp saiki.oita.jp taketa.oita.jp tsukumi.oita.jp usa.oita.jp usuki.oita.jp yufu.oita.jp akaiwa.okayama.jp asakuchi.okayama.jp bizen.okayama.jp hayashima.okayama.jp ibara.okayama.jp kagamino.okayama.jp kasaoka.okayama.jp kibichuo.okayama.jp kumenan.okayama.jp kurashiki.okayama.jp maniwa.okayama.jp misaki.okayama.jp nagi.okayama.jp niimi.okayama.jp nishiawakura.okayama.jp okayama.okayama.jp satosho.okayama.jp setouchi.okayama.jp shinjo.okayama.jp shoo.okayama.jp soja.okayama.jp takahashi.okayama.jp tamano.okayama.jp tsuyama.okayama.jp wake.okayama.jp yakage.okayama.jp aguni.okinawa.jp ginowan.okinawa.jp ginoza.okinawa.jp gushikami.okinawa.jp haebaru.okinawa.jp higashi.okinawa.jp hirara.okinawa.jp iheya.okinawa.jp ishigaki.okinawa.jp ishikawa.okinawa.jp itoman.okinawa.jp izena.okinawa.jp kadena.okinawa.jp kin.okinawa.jp kitadaito.okinawa.jp kitanakagusuku.okinawa.jp kumejima.okinawa.jp kunigami.okinawa.jp minamidaito.okinawa.jp motobu.okinawa.jp nago.okinawa.jp naha.okinawa.jp nakagusuku.okinawa.jp nakijin.okinawa.jp nanjo.okinawa.jp nishihara.okinawa.jp ogimi.okinawa.jp okinawa.okinawa.jp onna.okinawa.jp shimoji.okinawa.jp taketomi.okinawa.jp tarama.okinawa.jp tokashiki.okinawa.jp tomigusuku.okinawa.jp tonaki.okinawa.jp urasoe.okinawa.jp uruma.okinawa.jp yaese.okinawa.jp yomitan.okinawa.jp yonabaru.okinawa.jp yonaguni.okinawa.jp zamami.okinawa.jp abeno.osaka.jp chihayaakasaka.osaka.jp chuo.osaka.jp daito.osaka.jp fujiidera.osaka.jp habikino.osaka.jp hannan.osaka.jp higashiosaka.osaka.jp higashisumiyoshi.osaka.jp higashiyodogawa.osaka.jp hirakata.osaka.jp ibaraki.osaka.jp ikeda.osaka.jp izumi.osaka.jp izumiotsu.osaka.jp izumisano.osaka.jp kadoma.osaka.jp kaizuka.osaka.jp kanan.osaka.jp kashiwara.osaka.jp katano.osaka.jp kawachinagano.osaka.jp kishiwada.osaka.jp kita.osaka.jp kumatori.osaka.jp matsubara.osaka.jp minato.osaka.jp minoh.osaka.jp misaki.osaka.jp moriguchi.osaka.jp neyagawa.osaka.jp nishi.osaka.jp nose.osaka.jp osakasayama.osaka.jp sakai.osaka.jp sayama.osaka.jp sennan.osaka.jp settsu.osaka.jp shijonawate.osaka.jp shimamoto.osaka.jp suita.osaka.jp tadaoka.osaka.jp taishi.osaka.jp tajiri.osaka.jp takaishi.osaka.jp takatsuki.osaka.jp tondabayashi.osaka.jp toyonaka.osaka.jp toyono.osaka.jp yao.osaka.jp ariake.saga.jp arita.saga.jp fukudomi.saga.jp genkai.saga.jp hamatama.saga.jp hizen.saga.jp imari.saga.jp kamimine.saga.jp kanzaki.saga.jp karatsu.saga.jp kashima.saga.jp kitagata.saga.jp kitahata.saga.jp kiyama.saga.jp kouhoku.saga.jp kyuragi.saga.jp nishiarita.saga.jp ogi.saga.jp omachi.saga.jp ouchi.saga.jp saga.saga.jp shiroishi.saga.jp taku.saga.jp tara.saga.jp tosu.saga.jp yoshinogari.saga.jp arakawa.saitama.jp asaka.saitama.jp chichibu.saitama.jp fujimi.saitama.jp fujimino.saitama.jp fukaya.saitama.jp hanno.saitama.jp hanyu.saitama.jp hasuda.saitama.jp hatogaya.saitama.jp hatoyama.saitama.jp hidaka.saitama.jp higashichichibu.saitama.jp higashimatsuyama.saitama.jp honjo.saitama.jp ina.saitama.jp iruma.saitama.jp iwatsuki.saitama.jp kamiizumi.saitama.jp kamikawa.saitama.jp kamisato.saitama.jp kasukabe.saitama.jp kawagoe.saitama.jp kawaguchi.saitama.jp kawajima.saitama.jp kazo.saitama.jp kitamoto.saitama.jp koshigaya.saitama.jp kounosu.saitama.jp kuki.saitama.jp kumagaya.saitama.jp matsubushi.saitama.jp minano.saitama.jp misato.saitama.jp miyashiro.saitama.jp miyoshi.saitama.jp moroyama.saitama.jp nagatoro.saitama.jp namegawa.saitama.jp niiza.saitama.jp ogano.saitama.jp ogawa.saitama.jp ogose.saitama.jp okegawa.saitama.jp omiya.saitama.jp otaki.saitama.jp ranzan.saitama.jp ryokami.saitama.jp saitama.saitama.jp sakado.saitama.jp satte.saitama.jp sayama.saitama.jp shiki.saitama.jp shiraoka.saitama.jp soka.saitama.jp sugito.saitama.jp toda.saitama.jp tokigawa.saitama.jp tokorozawa.saitama.jp tsurugashima.saitama.jp urawa.saitama.jp warabi.saitama.jp yashio.saitama.jp yokoze.saitama.jp yono.saitama.jp yorii.saitama.jp yoshida.saitama.jp yoshikawa.saitama.jp yoshimi.saitama.jp aisho.shiga.jp gamo.shiga.jp higashiomi.shiga.jp hikone.shiga.jp koka.shiga.jp konan.shiga.jp kosei.shiga.jp koto.shiga.jp kusatsu.shiga.jp maibara.shiga.jp moriyama.shiga.jp nagahama.shiga.jp nishiazai.shiga.jp notogawa.shiga.jp omihachiman.shiga.jp otsu.shiga.jp ritto.shiga.jp ryuoh.shiga.jp takashima.shiga.jp takatsuki.shiga.jp torahime.shiga.jp toyosato.shiga.jp yasu.shiga.jp akagi.shimane.jp ama.shimane.jp gotsu.shimane.jp hamada.shimane.jp higashiizumo.shimane.jp hikawa.shimane.jp hikimi.shimane.jp izumo.shimane.jp kakinoki.shimane.jp masuda.shimane.jp matsue.shimane.jp misato.shimane.jp nishinoshima.shimane.jp ohda.shimane.jp okinoshima.shimane.jp okuizumo.shimane.jp shimane.shimane.jp tamayu.shimane.jp tsuwano.shimane.jp unnan.shimane.jp yakumo.shimane.jp yasugi.shimane.jp yatsuka.shimane.jp arai.shizuoka.jp atami.shizuoka.jp fuji.shizuoka.jp fujieda.shizuoka.jp fujikawa.shizuoka.jp fujinomiya.shizuoka.jp fukuroi.shizuoka.jp gotemba.shizuoka.jp haibara.shizuoka.jp hamamatsu.shizuoka.jp higashiizu.shizuoka.jp ito.shizuoka.jp iwata.shizuoka.jp izu.shizuoka.jp izunokuni.shizuoka.jp kakegawa.shizuoka.jp kannami.shizuoka.jp kawanehon.shizuoka.jp kawazu.shizuoka.jp kikugawa.shizuoka.jp kosai.shizuoka.jp makinohara.shizuoka.jp matsuzaki.shizuoka.jp minamiizu.shizuoka.jp mishima.shizuoka.jp morimachi.shizuoka.jp nishiizu.shizuoka.jp numazu.shizuoka.jp omaezaki.shizuoka.jp shimada.shizuoka.jp shimizu.shizuoka.jp shimoda.shizuoka.jp shizuoka.shizuoka.jp susono.shizuoka.jp yaizu.shizuoka.jp yoshida.shizuoka.jp ashikaga.tochigi.jp bato.tochigi.jp haga.tochigi.jp ichikai.tochigi.jp iwafune.tochigi.jp kaminokawa.tochigi.jp kanuma.tochigi.jp karasuyama.tochigi.jp kuroiso.tochigi.jp mashiko.tochigi.jp mibu.tochigi.jp moka.tochigi.jp motegi.tochigi.jp nasu.tochigi.jp nasushiobara.tochigi.jp nikko.tochigi.jp nishikata.tochigi.jp nogi.tochigi.jp ohira.tochigi.jp ohtawara.tochigi.jp oyama.tochigi.jp sakura.tochigi.jp sano.tochigi.jp shimotsuke.tochigi.jp shioya.tochigi.jp takanezawa.tochigi.jp tochigi.tochigi.jp tsuga.tochigi.jp ujiie.tochigi.jp utsunomiya.tochigi.jp yaita.tochigi.jp aizumi.tokushima.jp anan.tokushima.jp ichiba.tokushima.jp itano.tokushima.jp kainan.tokushima.jp komatsushima.tokushima.jp matsushige.tokushima.jp mima.tokushima.jp minami.tokushima.jp miyoshi.tokushima.jp mugi.tokushima.jp nakagawa.tokushima.jp naruto.tokushima.jp sanagochi.tokushima.jp shishikui.tokushima.jp tokushima.tokushima.jp wajiki.tokushima.jp adachi.tokyo.jp akiruno.tokyo.jp akishima.tokyo.jp aogashima.tokyo.jp arakawa.tokyo.jp bunkyo.tokyo.jp chiyoda.tokyo.jp chofu.tokyo.jp chuo.tokyo.jp edogawa.tokyo.jp fuchu.tokyo.jp fussa.tokyo.jp hachijo.tokyo.jp hachioji.tokyo.jp hamura.tokyo.jp higashikurume.tokyo.jp higashimurayama.tokyo.jp higashiyamato.tokyo.jp hino.tokyo.jp hinode.tokyo.jp hinohara.tokyo.jp inagi.tokyo.jp itabashi.tokyo.jp katsushika.tokyo.jp kita.tokyo.jp kiyose.tokyo.jp kodaira.tokyo.jp koganei.tokyo.jp kokubunji.tokyo.jp komae.tokyo.jp koto.tokyo.jp kouzushima.tokyo.jp kunitachi.tokyo.jp machida.tokyo.jp meguro.tokyo.jp minato.tokyo.jp mitaka.tokyo.jp mizuho.tokyo.jp musashimurayama.tokyo.jp musashino.tokyo.jp nakano.tokyo.jp nerima.tokyo.jp ogasawara.tokyo.jp okutama.tokyo.jp ome.tokyo.jp oshima.tokyo.jp ota.tokyo.jp setagaya.tokyo.jp shibuya.tokyo.jp shinagawa.tokyo.jp shinjuku.tokyo.jp suginami.tokyo.jp sumida.tokyo.jp tachikawa.tokyo.jp taito.tokyo.jp tama.tokyo.jp toshima.tokyo.jp chizu.tottori.jp hino.tottori.jp kawahara.tottori.jp koge.tottori.jp kotoura.tottori.jp misasa.tottori.jp nanbu.tottori.jp nichinan.tottori.jp sakaiminato.tottori.jp tottori.tottori.jp wakasa.tottori.jp yazu.tottori.jp yonago.tottori.jp asahi.toyama.jp fuchu.toyama.jp fukumitsu.toyama.jp funahashi.toyama.jp himi.toyama.jp imizu.toyama.jp inami.toyama.jp johana.toyama.jp kamiichi.toyama.jp kurobe.toyama.jp nakaniikawa.toyama.jp namerikawa.toyama.jp nanto.toyama.jp nyuzen.toyama.jp oyabe.toyama.jp taira.toyama.jp takaoka.toyama.jp tateyama.toyama.jp toga.toyama.jp tonami.toyama.jp toyama.toyama.jp unazuki.toyama.jp uozu.toyama.jp yamada.toyama.jp arida.wakayama.jp aridagawa.wakayama.jp gobo.wakayama.jp hashimoto.wakayama.jp hidaka.wakayama.jp hirogawa.wakayama.jp inami.wakayama.jp iwade.wakayama.jp kainan.wakayama.jp kamitonda.wakayama.jp katsuragi.wakayama.jp kimino.wakayama.jp kinokawa.wakayama.jp kitayama.wakayama.jp koya.wakayama.jp koza.wakayama.jp kozagawa.wakayama.jp kudoyama.wakayama.jp kushimoto.wakayama.jp mihama.wakayama.jp misato.wakayama.jp nachikatsuura.wakayama.jp shingu.wakayama.jp shirahama.wakayama.jp taiji.wakayama.jp tanabe.wakayama.jp wakayama.wakayama.jp yuasa.wakayama.jp yura.wakayama.jp asahi.yamagata.jp funagata.yamagata.jp higashine.yamagata.jp iide.yamagata.jp kahoku.yamagata.jp kaminoyama.yamagata.jp kaneyama.yamagata.jp kawanishi.yamagata.jp mamurogawa.yamagata.jp mikawa.yamagata.jp murayama.yamagata.jp nagai.yamagata.jp nakayama.yamagata.jp nanyo.yamagata.jp nishikawa.yamagata.jp obanazawa.yamagata.jp oe.yamagata.jp oguni.yamagata.jp ohkura.yamagata.jp oishida.yamagata.jp sagae.yamagata.jp sakata.yamagata.jp sakegawa.yamagata.jp shinjo.yamagata.jp shirataka.yamagata.jp shonai.yamagata.jp takahata.yamagata.jp tendo.yamagata.jp tozawa.yamagata.jp tsuruoka.yamagata.jp yamagata.yamagata.jp yamanobe.yamagata.jp yonezawa.yamagata.jp yuza.yamagata.jp abu.yamaguchi.jp hagi.yamaguchi.jp hikari.yamaguchi.jp hofu.yamaguchi.jp iwakuni.yamaguchi.jp kudamatsu.yamaguchi.jp mitou.yamaguchi.jp nagato.yamaguchi.jp oshima.yamaguchi.jp shimonoseki.yamaguchi.jp shunan.yamaguchi.jp tabuse.yamaguchi.jp tokuyama.yamaguchi.jp toyota.yamaguchi.jp ube.yamaguchi.jp yuu.yamaguchi.jp chuo.yamanashi.jp doshi.yamanashi.jp fuefuki.yamanashi.jp fujikawa.yamanashi.jp fujikawaguchiko.yamanashi.jp fujiyoshida.yamanashi.jp hayakawa.yamanashi.jp hokuto.yamanashi.jp ichikawamisato.yamanashi.jp kai.yamanashi.jp kofu.yamanashi.jp koshu.yamanashi.jp kosuge.yamanashi.jp minami-alps.yamanashi.jp minobu.yamanashi.jp nakamichi.yamanashi.jp nanbu.yamanashi.jp narusawa.yamanashi.jp nirasaki.yamanashi.jp nishikatsura.yamanashi.jp oshino.yamanashi.jp otsuki.yamanashi.jp showa.yamanashi.jp tabayama.yamanashi.jp tsuru.yamanashi.jp uenohara.yamanashi.jp yamanakako.yamanashi.jp yamanashi.yamanashi.jp // ke : http://www.kenic.or.ke/index.php/en/ke-domains/ke-domains ke ac.ke co.ke go.ke info.ke me.ke mobi.ke ne.ke or.ke sc.ke // kg : http://www.domain.kg/dmn_n.html kg com.kg edu.kg gov.kg mil.kg net.kg org.kg // kh : https://trc.gov.kh // Submitted by khnic@trc.gov.kh kh com.kh edu.kh gov.kh net.kh org.kh // ki : https://www.iana.org/domains/root/db/ki.html ki biz.ki com.ki edu.ki gov.ki info.ki net.ki org.ki // km : https://www.iana.org/domains/root/db/km.html // http://www.domaine.km/documents/charte.doc km ass.km com.km edu.km gov.km mil.km nom.km org.km prd.km tm.km // These are only mentioned as proposed suggestions at domaine.km, but // https://www.iana.org/domains/root/db/km.html says they're available for registration: asso.km coop.km gouv.km medecin.km notaires.km pharmaciens.km presse.km veterinaire.km // kn : https://www.iana.org/domains/root/db/kn.html // http://www.dot.kn/domainRules.html kn edu.kn gov.kn net.kn org.kn // kp : http://www.kcce.kp/en_index.php kp com.kp edu.kp gov.kp org.kp rep.kp tra.kp // kr : https://www.iana.org/domains/root/db/kr.html // see also: https://krnic.kisa.or.kr/jsp/infoboard/law/domBylawsReg.jsp kr ac.kr ai.kr co.kr es.kr go.kr hs.kr io.kr it.kr kg.kr me.kr mil.kr ms.kr ne.kr or.kr pe.kr re.kr sc.kr // kr geographical names busan.kr chungbuk.kr chungnam.kr daegu.kr daejeon.kr gangwon.kr gwangju.kr gyeongbuk.kr gyeonggi.kr gyeongnam.kr incheon.kr jeju.kr jeonbuk.kr jeonnam.kr seoul.kr ulsan.kr // kw : https://www.nic.kw/policies/ // Confirmed by registry kw com.kw edu.kw emb.kw gov.kw ind.kw net.kw org.kw // ky : http://www.icta.ky/da_ky_reg_dom.php // Confirmed by registry 2008-06-17 ky com.ky edu.ky net.ky org.ky // kz : https://www.iana.org/domains/root/db/kz.html // see also: http://www.nic.kz/rules/index.jsp kz com.kz edu.kz gov.kz mil.kz net.kz org.kz // la : https://www.iana.org/domains/root/db/la.html // Submitted by registry la com.la edu.la gov.la info.la int.la net.la org.la per.la // lb : https://www.iana.org/domains/root/db/lb.html // Submitted by registry lb com.lb edu.lb gov.lb net.lb org.lb // lc : https://www.iana.org/domains/root/db/lc.html // see also: http://www.nic.lc/rules.htm lc co.lc com.lc edu.lc gov.lc net.lc org.lc // li : https://www.iana.org/domains/root/db/li.html li // lk : https://www.iana.org/domains/root/db/lk.html lk ac.lk assn.lk com.lk edu.lk gov.lk grp.lk hotel.lk int.lk ltd.lk net.lk ngo.lk org.lk sch.lk soc.lk web.lk // lr : http://psg.com/dns/lr/lr.txt // Submitted by registry lr com.lr edu.lr gov.lr net.lr org.lr // ls : http://www.nic.ls/ // Confirmed by registry ls ac.ls biz.ls co.ls edu.ls gov.ls info.ls net.ls org.ls sc.ls // lt : https://www.iana.org/domains/root/db/lt.html lt // gov.lt : http://www.gov.lt/index_en.php gov.lt // lu : http://www.dns.lu/en/ lu // lv : https://www.iana.org/domains/root/db/lv.html lv asn.lv com.lv conf.lv edu.lv gov.lv id.lv mil.lv net.lv org.lv // ly : http://www.nic.ly/regulations.php ly com.ly edu.ly gov.ly id.ly med.ly net.ly org.ly plc.ly sch.ly // ma : https://www.iana.org/domains/root/db/ma.html // http://www.anrt.ma/fr/admin/download/upload/file_fr782.pdf ma ac.ma co.ma gov.ma net.ma org.ma press.ma // mc : http://www.nic.mc/ mc asso.mc tm.mc // md : https://www.iana.org/domains/root/db/md.html md // me : https://www.iana.org/domains/root/db/me.html me ac.me co.me edu.me gov.me its.me net.me org.me priv.me // mg : https://nic.mg mg co.mg com.mg edu.mg gov.mg mil.mg nom.mg org.mg prd.mg // mh : https://www.iana.org/domains/root/db/mh.html mh // mil : https://www.iana.org/domains/root/db/mil.html mil // mk : https://www.iana.org/domains/root/db/mk.html // see also: http://dns.marnet.net.mk/postapka.php mk com.mk edu.mk gov.mk inf.mk name.mk net.mk org.mk // ml : https://www.iana.org/domains/root/db/ml.html // Confirmed by Boubacar NDIAYE 2024-12-31 ml ac.ml art.ml asso.ml com.ml edu.ml gouv.ml gov.ml info.ml inst.ml net.ml org.ml pr.ml presse.ml // mm : https://www.iana.org/domains/root/db/mm.html *.mm // mn : https://www.iana.org/domains/root/db/mn.html mn edu.mn gov.mn org.mn // mo : http://www.monic.net.mo/ mo com.mo edu.mo gov.mo net.mo org.mo // mobi : https://www.iana.org/domains/root/db/mobi.html mobi // mp : http://www.dot.mp/ // Confirmed by registry 2008-06-17 mp // mq : https://www.iana.org/domains/root/db/mq.html mq // mr : https://www.iana.org/domains/root/db/mr.html mr gov.mr // ms : https://www.iana.org/domains/root/db/ms.html ms com.ms edu.ms gov.ms net.ms org.ms // mt : https://www.nic.org.mt/go/policy // Submitted by registry mt com.mt edu.mt net.mt org.mt // mu : https://www.iana.org/domains/root/db/mu.html mu ac.mu co.mu com.mu gov.mu net.mu or.mu org.mu // museum : https://welcome.museum/wp-content/uploads/2018/05/20180525-Registration-Policy-MUSEUM-EN_VF-2.pdf https://welcome.museum/buy-your-dot-museum-2/ museum // mv : https://www.iana.org/domains/root/db/mv.html // "mv" included because, contra Wikipedia, google.mv exists. mv aero.mv biz.mv com.mv coop.mv edu.mv gov.mv info.mv int.mv mil.mv museum.mv name.mv net.mv org.mv pro.mv // mw : http://www.registrar.mw/ mw ac.mw biz.mw co.mw com.mw coop.mw edu.mw gov.mw int.mw net.mw org.mw // mx : http://www.nic.mx/ // Submitted by registry mx com.mx edu.mx gob.mx net.mx org.mx // my : http://www.mynic.my/ // Available strings: https://mynic.my/resources/domains/buying-a-domain/ my biz.my com.my edu.my gov.my mil.my name.my net.my org.my // mz : http://www.uem.mz/ // Submitted by registry mz ac.mz adv.mz co.mz edu.mz gov.mz mil.mz net.mz org.mz // na : http://www.na-nic.com.na/ na alt.na co.na com.na gov.na net.na org.na // name : http://www.nic.name/ // Regarding 2LDs: https://github.com/publicsuffix/list/issues/2306 name // nc : http://www.cctld.nc/ nc asso.nc nom.nc // ne : https://www.iana.org/domains/root/db/ne.html ne // net : https://www.iana.org/domains/root/db/net.html net // nf : https://www.iana.org/domains/root/db/nf.html nf arts.nf com.nf firm.nf info.nf net.nf other.nf per.nf rec.nf store.nf web.nf // ng : http://www.nira.org.ng/index.php/join-us/register-ng-domain/189-nira-slds ng com.ng edu.ng gov.ng i.ng mil.ng mobi.ng name.ng net.ng org.ng sch.ng // ni : http://www.nic.ni/ ni ac.ni biz.ni co.ni com.ni edu.ni gob.ni in.ni info.ni int.ni mil.ni net.ni nom.ni org.ni web.ni // nl : https://www.iana.org/domains/root/db/nl.html // https://www.sidn.nl/ nl // no : https://www.norid.no/en/om-domenenavn/regelverk-for-no/ // Norid geographical second level domains : https://www.norid.no/en/om-domenenavn/regelverk-for-no/vedlegg-b/ // Norid category second level domains : https://www.norid.no/en/om-domenenavn/regelverk-for-no/vedlegg-c/ // Norid category second-level domains managed by parties other than Norid : https://www.norid.no/en/om-domenenavn/regelverk-for-no/vedlegg-d/ // RSS feed: https://teknisk.norid.no/en/feed/ no // Norid category second level domains : https://www.norid.no/en/om-domenenavn/regelverk-for-no/vedlegg-c/ fhs.no folkebibl.no fylkesbibl.no idrett.no museum.no priv.no vgs.no // Norid category second-level domains managed by parties other than Norid : https://www.norid.no/en/om-domenenavn/regelverk-for-no/vedlegg-d/ dep.no herad.no kommune.no mil.no stat.no // Norid geographical second level domains : https://www.norid.no/en/om-domenenavn/regelverk-for-no/vedlegg-b/ // counties aa.no ah.no bu.no fm.no hl.no hm.no jan-mayen.no mr.no nl.no nt.no of.no ol.no oslo.no rl.no sf.no st.no svalbard.no tm.no tr.no va.no vf.no // primary and lower secondary schools per county gs.aa.no gs.ah.no gs.bu.no gs.fm.no gs.hl.no gs.hm.no gs.jan-mayen.no gs.mr.no gs.nl.no gs.nt.no gs.of.no gs.ol.no gs.oslo.no gs.rl.no gs.sf.no gs.st.no gs.svalbard.no gs.tm.no gs.tr.no gs.va.no gs.vf.no // cities akrehamn.no Ã¥krehamn.no algard.no Ã¥lgÃ¥rd.no arna.no bronnoysund.no brønnøysund.no brumunddal.no bryne.no drobak.no drøbak.no egersund.no fetsund.no floro.no florø.no fredrikstad.no hokksund.no honefoss.no hønefoss.no jessheim.no jorpeland.no jørpeland.no kirkenes.no kopervik.no krokstadelva.no langevag.no langevÃ¥g.no leirvik.no mjondalen.no mjøndalen.no mo-i-rana.no mosjoen.no mosjøen.no nesoddtangen.no orkanger.no osoyro.no osøyro.no raholt.no rÃ¥holt.no sandnessjoen.no sandnessjøen.no skedsmokorset.no slattum.no spjelkavik.no stathelle.no stavern.no stjordalshalsen.no stjørdalshalsen.no tananger.no tranby.no vossevangen.no // communities aarborte.no aejrie.no afjord.no Ã¥fjord.no agdenes.no nes.akershus.no aknoluokta.no ákÅ‹oluokta.no al.no Ã¥l.no alaheadju.no álaheadju.no alesund.no Ã¥lesund.no alstahaug.no alta.no áltá.no alvdal.no amli.no Ã¥mli.no amot.no Ã¥mot.no andasuolo.no andebu.no andoy.no andøy.no ardal.no Ã¥rdal.no aremark.no arendal.no Ã¥s.no aseral.no Ã¥seral.no asker.no askim.no askoy.no askøy.no askvoll.no asnes.no Ã¥snes.no audnedaln.no aukra.no aure.no aurland.no aurskog-holand.no aurskog-høland.no austevoll.no austrheim.no averoy.no averøy.no badaddja.no bÃ¥dÃ¥ddjÃ¥.no bærum.no bahcavuotna.no báhcavuotna.no bahccavuotna.no báhccavuotna.no baidar.no báidár.no bajddar.no bájddar.no balat.no bálát.no balestrand.no ballangen.no balsfjord.no bamble.no bardu.no barum.no batsfjord.no bÃ¥tsfjord.no bearalvahki.no bearalváhki.no beardu.no beiarn.no berg.no bergen.no berlevag.no berlevÃ¥g.no bievat.no bievát.no bindal.no birkenes.no bjerkreim.no bjugn.no bodo.no bodø.no bokn.no bomlo.no bømlo.no bremanger.no bronnoy.no brønnøy.no budejju.no nes.buskerud.no bygland.no bykle.no cahcesuolo.no Äáhcesuolo.no davvenjarga.no davvenjárga.no davvesiida.no deatnu.no dielddanuorri.no divtasvuodna.no divttasvuotna.no donna.no dønna.no dovre.no drammen.no drangedal.no dyroy.no dyrøy.no eid.no eidfjord.no eidsberg.no eidskog.no eidsvoll.no eigersund.no elverum.no enebakk.no engerdal.no etne.no etnedal.no evenassi.no evenášši.no evenes.no evje-og-hornnes.no farsund.no fauske.no fedje.no fet.no finnoy.no finnøy.no fitjar.no fjaler.no fjell.no fla.no flÃ¥.no flakstad.no flatanger.no flekkefjord.no flesberg.no flora.no folldal.no forde.no førde.no forsand.no fosnes.no fræna.no frana.no frei.no frogn.no froland.no frosta.no froya.no frøya.no fuoisku.no fuossko.no fusa.no fyresdal.no gaivuotna.no gáivuotna.no galsa.no gálsá.no gamvik.no gangaviika.no gáŋgaviika.no gaular.no gausdal.no giehtavuoatna.no gildeskal.no gildeskÃ¥l.no giske.no gjemnes.no gjerdrum.no gjerstad.no gjesdal.no gjovik.no gjøvik.no gloppen.no gol.no gran.no grane.no granvin.no gratangen.no grimstad.no grong.no grue.no gulen.no guovdageaidnu.no ha.no hÃ¥.no habmer.no hábmer.no hadsel.no hægebostad.no hagebostad.no halden.no halsa.no hamar.no hamaroy.no hammarfeasta.no hámmárfeasta.no hammerfest.no hapmir.no hápmir.no haram.no hareid.no harstad.no hasvik.no hattfjelldal.no haugesund.no os.hedmark.no valer.hedmark.no vÃ¥ler.hedmark.no hemne.no hemnes.no hemsedal.no hitra.no hjartdal.no hjelmeland.no hobol.no hobøl.no hof.no hol.no hole.no holmestrand.no holtalen.no holtÃ¥len.no os.hordaland.no hornindal.no horten.no hoyanger.no høyanger.no hoylandet.no høylandet.no hurdal.no hurum.no hvaler.no hyllestad.no ibestad.no inderoy.no inderøy.no iveland.no ivgu.no jevnaker.no jolster.no jølster.no jondal.no kafjord.no kÃ¥fjord.no karasjohka.no kárášjohka.no karasjok.no karlsoy.no karmoy.no karmøy.no kautokeino.no klabu.no klæbu.no klepp.no kongsberg.no kongsvinger.no kraanghke.no krÃ¥anghke.no kragero.no kragerø.no kristiansand.no kristiansund.no krodsherad.no krødsherad.no kvæfjord.no kvænangen.no kvafjord.no kvalsund.no kvam.no kvanangen.no kvinesdal.no kvinnherad.no kviteseid.no kvitsoy.no kvitsøy.no laakesvuemie.no lærdal.no lahppi.no láhppi.no lardal.no larvik.no lavagis.no lavangen.no leangaviika.no leaÅ‹gaviika.no lebesby.no leikanger.no leirfjord.no leka.no leksvik.no lenvik.no lerdal.no lesja.no levanger.no lier.no lierne.no lillehammer.no lillesand.no lindas.no lindÃ¥s.no lindesnes.no loabat.no loabát.no lodingen.no lødingen.no lom.no loppa.no lorenskog.no lørenskog.no loten.no løten.no lund.no lunner.no luroy.no lurøy.no luster.no lyngdal.no lyngen.no malatvuopmi.no málatvuopmi.no malselv.no mÃ¥lselv.no malvik.no mandal.no marker.no marnardal.no masfjorden.no masoy.no mÃ¥søy.no matta-varjjat.no mátta-várjjat.no meland.no meldal.no melhus.no meloy.no meløy.no meraker.no merÃ¥ker.no midsund.no midtre-gauldal.no moareke.no moÃ¥reke.no modalen.no modum.no molde.no heroy.more-og-romsdal.no sande.more-og-romsdal.no herøy.møre-og-romsdal.no sande.møre-og-romsdal.no moskenes.no moss.no muosat.no muosát.no naamesjevuemie.no nååmesjevuemie.no nærøy.no namdalseid.no namsos.no namsskogan.no nannestad.no naroy.no narviika.no narvik.no naustdal.no navuotna.no návuotna.no nedre-eiker.no nesna.no nesodden.no nesseby.no nesset.no nissedal.no nittedal.no nord-aurdal.no nord-fron.no nord-odal.no norddal.no nordkapp.no bo.nordland.no bø.nordland.no heroy.nordland.no herøy.nordland.no nordre-land.no nordreisa.no nore-og-uvdal.no notodden.no notteroy.no nøtterøy.no odda.no oksnes.no øksnes.no omasvuotna.no oppdal.no oppegard.no oppegÃ¥rd.no orkdal.no orland.no ørland.no orskog.no ørskog.no orsta.no ørsta.no osen.no osteroy.no osterøy.no valer.ostfold.no vÃ¥ler.østfold.no ostre-toten.no østre-toten.no overhalla.no ovre-eiker.no øvre-eiker.no oyer.no øyer.no oygarden.no øygarden.no oystre-slidre.no øystre-slidre.no porsanger.no porsangu.no porsáŋgu.no porsgrunn.no rade.no rÃ¥de.no radoy.no radøy.no rælingen.no rahkkeravju.no ráhkkerávju.no raisa.no ráisa.no rakkestad.no ralingen.no rana.no randaberg.no rauma.no rendalen.no rennebu.no rennesoy.no rennesøy.no rindal.no ringebu.no ringerike.no ringsaker.no risor.no risør.no rissa.no roan.no rodoy.no rødøy.no rollag.no romsa.no romskog.no rømskog.no roros.no røros.no rost.no røst.no royken.no røyken.no royrvik.no røyrvik.no ruovat.no rygge.no salangen.no salat.no sálat.no sálát.no saltdal.no samnanger.no sandefjord.no sandnes.no sandoy.no sandøy.no sarpsborg.no sauda.no sauherad.no sel.no selbu.no selje.no seljord.no siellak.no sigdal.no siljan.no sirdal.no skanit.no skánit.no skanland.no skÃ¥nland.no skaun.no skedsmo.no ski.no skien.no skierva.no skiervá.no skiptvet.no skjak.no skjÃ¥k.no skjervoy.no skjervøy.no skodje.no smola.no smøla.no snaase.no snÃ¥ase.no snasa.no snÃ¥sa.no snillfjord.no snoasa.no sogndal.no sogne.no søgne.no sokndal.no sola.no solund.no somna.no sømna.no sondre-land.no søndre-land.no songdalen.no sor-aurdal.no sør-aurdal.no sor-fron.no sør-fron.no sor-odal.no sør-odal.no sor-varanger.no sør-varanger.no sorfold.no sørfold.no sorreisa.no sørreisa.no sortland.no sorum.no sørum.no spydeberg.no stange.no stavanger.no steigen.no steinkjer.no stjordal.no stjørdal.no stokke.no stor-elvdal.no stord.no stordal.no storfjord.no strand.no stranda.no stryn.no sula.no suldal.no sund.no sunndal.no surnadal.no sveio.no svelvik.no sykkylven.no tana.no bo.telemark.no bø.telemark.no time.no tingvoll.no tinn.no tjeldsund.no tjome.no tjøme.no tokke.no tolga.no tonsberg.no tønsberg.no torsken.no træna.no trana.no tranoy.no tranøy.no troandin.no trogstad.no trøgstad.no tromsa.no tromso.no tromsø.no trondheim.no trysil.no tvedestrand.no tydal.no tynset.no tysfjord.no tysnes.no tysvær.no tysvar.no ullensaker.no ullensvang.no ulvik.no unjarga.no unjárga.no utsira.no vaapste.no vadso.no vadsø.no værøy.no vaga.no vÃ¥gÃ¥.no vagan.no vÃ¥gan.no vagsoy.no vÃ¥gsøy.no vaksdal.no valle.no vang.no vanylven.no vardo.no vardø.no varggat.no várggát.no varoy.no vefsn.no vega.no vegarshei.no vegÃ¥rshei.no vennesla.no verdal.no verran.no vestby.no sande.vestfold.no vestnes.no vestre-slidre.no vestre-toten.no vestvagoy.no vestvÃ¥gøy.no vevelstad.no vik.no vikna.no vindafjord.no voagat.no volda.no voss.no // np : http://www.mos.com.np/register.html *.np // nr : http://cenpac.net.nr/dns/index.html // Submitted by registry nr biz.nr com.nr edu.nr gov.nr info.nr net.nr org.nr // nu : https://www.iana.org/domains/root/db/nu.html nu // nz : https://www.iana.org/domains/root/db/nz.html // Submitted by registry nz ac.nz co.nz cri.nz geek.nz gen.nz govt.nz health.nz iwi.nz kiwi.nz maori.nz mÄori.nz mil.nz net.nz org.nz parliament.nz school.nz // om : https://www.iana.org/domains/root/db/om.html om co.om com.om edu.om gov.om med.om museum.om net.om org.om pro.om // onion : https://tools.ietf.org/html/rfc7686 onion // org : https://www.iana.org/domains/root/db/org.html org // pa : http://www.nic.pa/ // Some additional second level "domains" resolve directly as hostnames, such as // pannet.pa, so we add a rule for "pa". pa abo.pa ac.pa com.pa edu.pa gob.pa ing.pa med.pa net.pa nom.pa org.pa sld.pa // pe : https://www.nic.pe/InformeFinalComision.pdf pe com.pe edu.pe gob.pe mil.pe net.pe nom.pe org.pe // pf : http://www.gobin.info/domainname/formulaire-pf.pdf pf com.pf edu.pf org.pf // pg : https://www.iana.org/domains/root/db/pg.html *.pg // ph : https://www.iana.org/domains/root/db/ph.html // Submitted by registry ph com.ph edu.ph gov.ph i.ph mil.ph net.ph ngo.ph org.ph // pk : https://pk5.pknic.net.pk/pk5/msgNamepk.PK // Contact Email: staff@pknic.net.pk pk ac.pk biz.pk com.pk edu.pk fam.pk gkp.pk gob.pk gog.pk gok.pk gop.pk gos.pk gov.pk net.pk org.pk web.pk // pl : https://www.dns.pl/en/ // Confirmed by registry 2024-11-18 pl com.pl net.pl org.pl // pl functional domains : https://www.dns.pl/en/list_of_functional_domain_names agro.pl aid.pl atm.pl auto.pl biz.pl edu.pl gmina.pl gsm.pl info.pl mail.pl media.pl miasta.pl mil.pl nieruchomosci.pl nom.pl pc.pl powiat.pl priv.pl realestate.pl rel.pl sex.pl shop.pl sklep.pl sos.pl szkola.pl targi.pl tm.pl tourism.pl travel.pl turystyka.pl // Government domains : https://www.dns.pl/informacje_o_rejestracji_domen_gov_pl // In accordance with the .gov.pl Domain Name Regulations : https://www.dns.pl/regulamin_gov_pl gov.pl ap.gov.pl griw.gov.pl ic.gov.pl is.gov.pl kmpsp.gov.pl konsulat.gov.pl kppsp.gov.pl kwp.gov.pl kwpsp.gov.pl mup.gov.pl mw.gov.pl oia.gov.pl oirm.gov.pl oke.gov.pl oow.gov.pl oschr.gov.pl oum.gov.pl pa.gov.pl pinb.gov.pl piw.gov.pl po.gov.pl pr.gov.pl psp.gov.pl psse.gov.pl pup.gov.pl rzgw.gov.pl sa.gov.pl sdn.gov.pl sko.gov.pl so.gov.pl sr.gov.pl starostwo.gov.pl ug.gov.pl ugim.gov.pl um.gov.pl umig.gov.pl upow.gov.pl uppo.gov.pl us.gov.pl uw.gov.pl uzs.gov.pl wif.gov.pl wiih.gov.pl winb.gov.pl wios.gov.pl witd.gov.pl wiw.gov.pl wkz.gov.pl wsa.gov.pl wskr.gov.pl wsse.gov.pl wuoz.gov.pl wzmiuw.gov.pl zp.gov.pl zpisdn.gov.pl // pl regional domains : https://www.dns.pl/en/list_of_regional_domain_names augustow.pl babia-gora.pl bedzin.pl beskidy.pl bialowieza.pl bialystok.pl bielawa.pl bieszczady.pl boleslawiec.pl bydgoszcz.pl bytom.pl cieszyn.pl czeladz.pl czest.pl dlugoleka.pl elblag.pl elk.pl glogow.pl gniezno.pl gorlice.pl grajewo.pl ilawa.pl jaworzno.pl jelenia-gora.pl jgora.pl kalisz.pl karpacz.pl kartuzy.pl kaszuby.pl katowice.pl kazimierz-dolny.pl kepno.pl ketrzyn.pl klodzko.pl kobierzyce.pl kolobrzeg.pl konin.pl konskowola.pl kutno.pl lapy.pl lebork.pl legnica.pl lezajsk.pl limanowa.pl lomza.pl lowicz.pl lubin.pl lukow.pl malbork.pl malopolska.pl mazowsze.pl mazury.pl mielec.pl mielno.pl mragowo.pl naklo.pl nowaruda.pl nysa.pl olawa.pl olecko.pl olkusz.pl olsztyn.pl opoczno.pl opole.pl ostroda.pl ostroleka.pl ostrowiec.pl ostrowwlkp.pl pila.pl pisz.pl podhale.pl podlasie.pl polkowice.pl pomorskie.pl pomorze.pl prochowice.pl pruszkow.pl przeworsk.pl pulawy.pl radom.pl rawa-maz.pl rybnik.pl rzeszow.pl sanok.pl sejny.pl skoczow.pl slask.pl slupsk.pl sosnowiec.pl stalowa-wola.pl starachowice.pl stargard.pl suwalki.pl swidnica.pl swiebodzin.pl swinoujscie.pl szczecin.pl szczytno.pl tarnobrzeg.pl tgory.pl turek.pl tychy.pl ustka.pl walbrzych.pl warmia.pl warszawa.pl waw.pl wegrow.pl wielun.pl wlocl.pl wloclawek.pl wodzislaw.pl wolomin.pl wroclaw.pl zachpomor.pl zagan.pl zarow.pl zgora.pl zgorzelec.pl // pm : https://www.afnic.fr/wp-media/uploads/2022/12/afnic-naming-policy-2023-01-01.pdf pm // pn : https://www.iana.org/domains/root/db/pn.html pn co.pn edu.pn gov.pn net.pn org.pn // post : https://www.iana.org/domains/root/db/post.html post // pr : http://www.nic.pr/index.asp?f=1 pr biz.pr com.pr edu.pr gov.pr info.pr isla.pr name.pr net.pr org.pr pro.pr // these aren't mentioned on nic.pr, but on https://www.iana.org/domains/root/db/pr.html ac.pr est.pr prof.pr // pro : http://registry.pro/get-pro pro aaa.pro aca.pro acct.pro avocat.pro bar.pro cpa.pro eng.pro jur.pro law.pro med.pro recht.pro // ps : https://www.iana.org/domains/root/db/ps.html // http://www.nic.ps/registration/policy.html#reg ps com.ps edu.ps gov.ps net.ps org.ps plo.ps sec.ps // pt : https://www.dns.pt/en/domain/pt-terms-and-conditions-registration-rules/ pt com.pt edu.pt gov.pt int.pt net.pt nome.pt org.pt publ.pt // pw : https://www.iana.org/domains/root/db/pw.html // Confirmed by registry in private correspondence with @dnsguru 2024-12-09 pw gov.pw // py : https://www.iana.org/domains/root/db/py.html // Submitted by registry py com.py coop.py edu.py gov.py mil.py net.py org.py // qa : http://domains.qa/en/ qa com.qa edu.qa gov.qa mil.qa name.qa net.qa org.qa sch.qa // re : https://www.afnic.fr/wp-media/uploads/2022/12/afnic-naming-policy-2023-01-01.pdf // Confirmed by registry 2024-11-18 re // Closed for registration on 2013-03-15 but domains are still maintained asso.re com.re // ro : http://www.rotld.ro/ ro arts.ro com.ro firm.ro info.ro nom.ro nt.ro org.ro rec.ro store.ro tm.ro www.ro // rs : https://www.rnids.rs/en/domains/national-domains rs ac.rs co.rs edu.rs gov.rs in.rs org.rs // ru : https://cctld.ru/files/pdf/docs/en/rules_ru-rf.pdf // Submitted by George Georgievsky ru // rw : https://www.iana.org/domains/root/db/rw.html rw ac.rw co.rw coop.rw gov.rw mil.rw net.rw org.rw // sa : http://www.nic.net.sa/ sa com.sa edu.sa gov.sa med.sa net.sa org.sa pub.sa sch.sa // sb : http://www.sbnic.net.sb/ // Submitted by registry sb com.sb edu.sb gov.sb net.sb org.sb // sc : http://www.nic.sc/ sc com.sc edu.sc gov.sc net.sc org.sc // sd : https://www.iana.org/domains/root/db/sd.html // Submitted by registry sd com.sd edu.sd gov.sd info.sd med.sd net.sd org.sd tv.sd // se : https://www.iana.org/domains/root/db/se.html // https://data.internetstiftelsen.se/barred_domains_list.txt -> Second level domains & Sub-domains // Confirmed by Registry Services 2024-11-20 se a.se ac.se b.se bd.se brand.se c.se d.se e.se f.se fh.se fhsk.se fhv.se g.se h.se i.se k.se komforb.se kommunalforbund.se komvux.se l.se lanbib.se m.se n.se naturbruksgymn.se o.se org.se p.se parti.se pp.se press.se r.se s.se t.se tm.se u.se w.se x.se y.se z.se // sg : https://www.sgnic.sg/domain-registration/sg-categories-rules // Confirmed by registry 2024-11-19 sg com.sg edu.sg gov.sg net.sg org.sg // sh : http://nic.sh/rules.htm sh com.sh gov.sh mil.sh net.sh org.sh // si : https://www.iana.org/domains/root/db/si.html si // sj : No registrations at this time. // Submitted by registry sj // sk : https://www.iana.org/domains/root/db/sk.html // https://sk-nic.sk/ sk org.sk // sl : http://www.nic.sl // Submitted by registry sl com.sl edu.sl gov.sl net.sl org.sl // sm : https://www.iana.org/domains/root/db/sm.html sm // sn : https://www.iana.org/domains/root/db/sn.html sn art.sn com.sn edu.sn gouv.sn org.sn univ.sn // so : http://sonic.so/policies/ so com.so edu.so gov.so me.so net.so org.so // sr : https://www.iana.org/domains/root/db/sr.html sr // ss : https://registry.nic.ss/ // Submitted by registry ss biz.ss co.ss com.ss edu.ss gov.ss me.ss net.ss org.ss sch.ss // st : http://www.nic.st/html/policyrules/ st co.st com.st consulado.st edu.st embaixada.st mil.st net.st org.st principe.st saotome.st store.st // su : https://www.iana.org/domains/root/db/su.html su // sv : https://www.iana.org/domains/root/db/sv.html sv com.sv edu.sv gob.sv org.sv red.sv // sx : https://www.iana.org/domains/root/db/sx.html // Submitted by registry sx gov.sx // sy : https://www.iana.org/domains/root/db/sy.html sy com.sy edu.sy gov.sy mil.sy net.sy org.sy // sz : https://www.iana.org/domains/root/db/sz.html // http://www.sispa.org.sz/ sz ac.sz co.sz org.sz // tc : https://www.iana.org/domains/root/db/tc.html tc // td : https://www.iana.org/domains/root/db/td.html td // tel : https://www.iana.org/domains/root/db/tel.html // http://www.telnic.org/ tel // tf : https://www.afnic.fr/wp-media/uploads/2022/12/afnic-naming-policy-2023-01-01.pdf tf // tg : https://www.iana.org/domains/root/db/tg.html // http://www.nic.tg/ tg // th : https://www.iana.org/domains/root/db/th.html // Submitted by registry th ac.th co.th go.th in.th mi.th net.th or.th // tj : http://www.nic.tj/policy.html tj ac.tj biz.tj co.tj com.tj edu.tj go.tj gov.tj int.tj mil.tj name.tj net.tj nic.tj org.tj test.tj web.tj // tk : https://www.iana.org/domains/root/db/tk.html tk // tl : https://www.iana.org/domains/root/db/tl.html tl gov.tl // tm : https://www.nic.tm/local.html // Confirmed by registry 2024-11-19 tm co.tm com.tm edu.tm gov.tm mil.tm net.tm nom.tm org.tm // tn : http://www.registre.tn/fr/ // https://whois.ati.tn/ tn com.tn ens.tn fin.tn gov.tn ind.tn info.tn intl.tn mincom.tn nat.tn net.tn org.tn perso.tn tourism.tn // to : https://www.iana.org/domains/root/db/to.html // Submitted by registry to com.to edu.to gov.to mil.to net.to org.to // tr : https://nic.tr/ // https://nic.tr/forms/eng/policies.pdf // https://nic.tr/index.php?USRACTN=PRICELST tr av.tr bbs.tr bel.tr biz.tr com.tr dr.tr edu.tr gen.tr gov.tr info.tr k12.tr kep.tr mil.tr name.tr net.tr org.tr pol.tr tel.tr tsk.tr tv.tr web.tr // Used by Northern Cyprus nc.tr // Used by government agencies of Northern Cyprus gov.nc.tr // tt : https://www.nic.tt/ // Confirmed by registry 2024-11-19 tt biz.tt co.tt com.tt edu.tt gov.tt info.tt mil.tt name.tt net.tt org.tt pro.tt // tv : https://www.iana.org/domains/root/db/tv.html // Not listing any 2LDs as reserved since none seem to exist in practice, // Wikipedia notwithstanding. tv // tw : https://www.iana.org/domains/root/db/tw.html // https://twnic.tw/dnservice_catag.php // Confirmed by registry 2024-11-26 tw club.tw com.tw ebiz.tw edu.tw game.tw gov.tw idv.tw mil.tw net.tw org.tw // tz : http://www.tznic.or.tz/index.php/domains // Submitted by registry tz ac.tz co.tz go.tz hotel.tz info.tz me.tz mil.tz mobi.tz ne.tz or.tz sc.tz tv.tz // ua : https://hostmaster.ua/policy/?ua // Submitted by registry ua // ua 2LD com.ua edu.ua gov.ua in.ua net.ua org.ua // ua geographic names // https://hostmaster.ua/2ld/ cherkassy.ua cherkasy.ua chernigov.ua chernihiv.ua chernivtsi.ua chernovtsy.ua ck.ua cn.ua cr.ua crimea.ua cv.ua dn.ua dnepropetrovsk.ua dnipropetrovsk.ua donetsk.ua dp.ua if.ua ivano-frankivsk.ua kh.ua kharkiv.ua kharkov.ua kherson.ua khmelnitskiy.ua khmelnytskyi.ua kiev.ua kirovograd.ua km.ua kr.ua kropyvnytskyi.ua krym.ua ks.ua kv.ua kyiv.ua lg.ua lt.ua lugansk.ua luhansk.ua lutsk.ua lv.ua lviv.ua mk.ua mykolaiv.ua nikolaev.ua od.ua odesa.ua odessa.ua pl.ua poltava.ua rivne.ua rovno.ua rv.ua sb.ua sebastopol.ua sevastopol.ua sm.ua sumy.ua te.ua ternopil.ua uz.ua uzhgorod.ua uzhhorod.ua vinnica.ua vinnytsia.ua vn.ua volyn.ua yalta.ua zakarpattia.ua zaporizhzhe.ua zaporizhzhia.ua zhitomir.ua zhytomyr.ua zp.ua zt.ua // ug : https://www.registry.co.ug/ // https://www.registry.co.ug, https://whois.co.ug // Confirmed by registry 2025-01-20 ug ac.ug co.ug com.ug edu.ug go.ug gov.ug mil.ug ne.ug or.ug org.ug sc.ug us.ug // uk : https://www.iana.org/domains/root/db/uk.html // Submitted by registry uk ac.uk co.uk gov.uk ltd.uk me.uk net.uk nhs.uk org.uk plc.uk police.uk *.sch.uk // us : https://www.iana.org/domains/root/db/us.html // Confirmed via the .us zone file by William Harrison 2024-12-10 us dni.us isa.us nsn.us // Geographic Names ak.us al.us ar.us as.us az.us ca.us co.us ct.us dc.us de.us fl.us ga.us gu.us hi.us ia.us id.us il.us in.us ks.us ky.us la.us ma.us md.us me.us mi.us mn.us mo.us ms.us mt.us nc.us nd.us ne.us nh.us nj.us nm.us nv.us ny.us oh.us ok.us or.us pa.us pr.us ri.us sc.us sd.us tn.us tx.us ut.us va.us vi.us vt.us wa.us wi.us wv.us wy.us // The registrar notes several more specific domains available in each state, // such as state.*.us, dst.*.us, etc., but resolution of these is somewhat // haphazard; in some states these domains resolve as addresses, while in others // only subdomains are available, or even nothing at all. We include the // most common ones where it's clear that different sites are different // entities. k12.ak.us k12.al.us k12.ar.us k12.as.us k12.az.us k12.ca.us k12.co.us k12.ct.us k12.dc.us k12.fl.us k12.ga.us k12.gu.us // k12.hi.us - Bug 614565 - Hawaii has a state-wide DOE login k12.ia.us k12.id.us k12.il.us k12.in.us k12.ks.us k12.ky.us k12.la.us k12.ma.us k12.md.us k12.me.us k12.mi.us k12.mn.us k12.mo.us k12.ms.us k12.mt.us k12.nc.us // k12.nd.us - Bug 1028347 - Removed at request of Travis Rosso k12.ne.us k12.nh.us k12.nj.us k12.nm.us k12.nv.us k12.ny.us k12.oh.us k12.ok.us k12.or.us k12.pa.us k12.pr.us // k12.ri.us - Removed at request of Kim Cournoyer k12.sc.us // k12.sd.us - Bug 934131 - Removed at request of James Booze k12.tn.us k12.tx.us k12.ut.us k12.va.us k12.vi.us k12.vt.us k12.wa.us k12.wi.us // k12.wv.us - Bug 947705 - Removed at request of Verne Britton cc.ak.us lib.ak.us cc.al.us lib.al.us cc.ar.us lib.ar.us cc.as.us lib.as.us cc.az.us lib.az.us cc.ca.us lib.ca.us cc.co.us lib.co.us cc.ct.us lib.ct.us cc.dc.us lib.dc.us cc.de.us cc.fl.us lib.fl.us cc.ga.us lib.ga.us cc.gu.us lib.gu.us cc.hi.us lib.hi.us cc.ia.us lib.ia.us cc.id.us lib.id.us cc.il.us lib.il.us cc.in.us lib.in.us cc.ks.us lib.ks.us cc.ky.us lib.ky.us cc.la.us lib.la.us cc.ma.us lib.ma.us cc.md.us lib.md.us cc.me.us lib.me.us cc.mi.us lib.mi.us cc.mn.us lib.mn.us cc.mo.us lib.mo.us cc.ms.us cc.mt.us lib.mt.us cc.nc.us lib.nc.us cc.nd.us lib.nd.us cc.ne.us lib.ne.us cc.nh.us lib.nh.us cc.nj.us lib.nj.us cc.nm.us lib.nm.us cc.nv.us lib.nv.us cc.ny.us lib.ny.us cc.oh.us lib.oh.us cc.ok.us lib.ok.us cc.or.us lib.or.us cc.pa.us lib.pa.us cc.pr.us lib.pr.us cc.ri.us lib.ri.us cc.sc.us lib.sc.us cc.sd.us lib.sd.us cc.tn.us lib.tn.us cc.tx.us lib.tx.us cc.ut.us lib.ut.us cc.va.us lib.va.us cc.vi.us lib.vi.us cc.vt.us lib.vt.us cc.wa.us lib.wa.us cc.wi.us lib.wi.us cc.wv.us cc.wy.us k12.wy.us // lib.wv.us - Bug 941670 - Removed at request of Larry W Arnold lib.wy.us // k12.ma.us contains school districts in Massachusetts. The 4LDs are // managed independently except for private (PVT), charter (CHTR) and // parochial (PAROCH) schools. Those are delegated directly to the // 5LD operators. chtr.k12.ma.us paroch.k12.ma.us pvt.k12.ma.us // Merit Network, Inc. maintains the registry for =~ /(k12|cc|lib).mi.us/ and the following // see also: https://domreg.merit.edu : domreg@merit.edu // see also: whois -h whois.domreg.merit.edu help ann-arbor.mi.us cog.mi.us dst.mi.us eaton.mi.us gen.mi.us mus.mi.us tec.mi.us washtenaw.mi.us // uy : http://www.nic.org.uy/ uy com.uy edu.uy gub.uy mil.uy net.uy org.uy // uz : http://www.reg.uz/ uz co.uz com.uz net.uz org.uz // va : https://www.iana.org/domains/root/db/va.html va // vc : https://www.iana.org/domains/root/db/vc.html // Submitted by registry vc com.vc edu.vc gov.vc mil.vc net.vc org.vc // ve : https://registro.nic.ve/ // https://nic.ve/site/user-agreement -> under "III. Clasificación de Nombres de Dominio" // Submitted by registry nic@nic.ve and nicve@conatel.gob.ve ve arts.ve bib.ve co.ve com.ve e12.ve edu.ve emprende.ve firm.ve gob.ve gov.ve ia.ve info.ve int.ve mil.ve net.ve nom.ve org.ve rar.ve rec.ve store.ve tec.ve web.ve // vg : https://www.iana.org/domains/root/db/vg.html // Confirmed by registry 2025-01-10 vg edu.vg // vi : https://www.iana.org/domains/root/db/vi.html vi co.vi com.vi k12.vi net.vi org.vi // vn : https://www.vnnic.vn/en/domain/cctld-vn // https://vnnic.vn/sites/default/files/tailieu/vn.cctld.domains.txt vn ac.vn ai.vn biz.vn com.vn edu.vn gov.vn health.vn id.vn info.vn int.vn io.vn name.vn net.vn org.vn pro.vn // vn geographical names angiang.vn bacgiang.vn backan.vn baclieu.vn bacninh.vn baria-vungtau.vn bentre.vn binhdinh.vn binhduong.vn binhphuoc.vn binhthuan.vn camau.vn cantho.vn caobang.vn daklak.vn daknong.vn danang.vn dienbien.vn dongnai.vn dongthap.vn gialai.vn hagiang.vn haiduong.vn haiphong.vn hanam.vn hanoi.vn hatinh.vn haugiang.vn hoabinh.vn hue.vn hungyen.vn khanhhoa.vn kiengiang.vn kontum.vn laichau.vn lamdong.vn langson.vn laocai.vn longan.vn namdinh.vn nghean.vn ninhbinh.vn ninhthuan.vn phutho.vn phuyen.vn quangbinh.vn quangnam.vn quangngai.vn quangninh.vn quangtri.vn soctrang.vn sonla.vn tayninh.vn thaibinh.vn thainguyen.vn thanhhoa.vn thanhphohochiminh.vn thuathienhue.vn tiengiang.vn travinh.vn tuyenquang.vn vinhlong.vn vinhphuc.vn yenbai.vn // vu : https://www.iana.org/domains/root/db/vu.html // http://www.vunic.vu/ vu com.vu edu.vu net.vu org.vu // wf : https://www.afnic.fr/wp-media/uploads/2022/12/afnic-naming-policy-2023-01-01.pdf wf // ws : https://www.iana.org/domains/root/db/ws.html // http://samoanic.ws/index.dhtml ws com.ws edu.ws gov.ws net.ws org.ws // yt : https://www.afnic.fr/wp-media/uploads/2022/12/afnic-naming-policy-2023-01-01.pdf yt // IDN ccTLDs // When submitting patches, please maintain a sort by ISO 3166 ccTLD, then // U-label, and follow this format: // // A-Label ("", [, variant info]) : // // [sponsoring org] // U-Label // xn--mgbaam7a8h ("Emerat", Arabic) : AE // http://nic.ae/english/arabicdomain/rules.jsp امارات // xn--y9a3aq ("hye", Armenian) : AM // ISOC AM (operated by .am Registry) Õ°Õ¡Õµ // xn--54b7fta0cc ("Bangla", Bangla) : BD বাংলা // xn--90ae ("bg", Bulgarian) : BG бг // xn--mgbcpq6gpa1a ("albahrain", Arabic) : BH البحرين // xn--90ais ("bel", Belarusian/Russian Cyrillic) : BY // Operated by .by registry бел // xn--fiqs8s ("Zhongguo/China", Chinese, Simplified) : CN // CNNIC // https://www.cnnic.cn/11/192/index.html 中国 // xn--fiqz9s ("Zhongguo/China", Chinese, Traditional) : CN // CNNIC // https://www.cnnic.com.cn/AU/MediaC/Announcement/201609/t20160905_54470.htm 中國 // xn--lgbbat1ad8j ("Algeria/Al Jazair", Arabic) : DZ الجزائر // xn--wgbh1c ("Egypt/Masr", Arabic) : EG // http://www.dotmasr.eg/ مصر // xn--e1a4c ("eu", Cyrillic) : EU // https://eurid.eu ею // xn--qxa6a ("eu", Greek) : EU // https://eurid.eu ευ // xn--mgbah1a3hjkrd ("Mauritania", Arabic) : MR موريتانيا // xn--node ("ge", Georgian Mkhedruli) : GE გე // xn--qxam ("el", Greek) : GR // Hellenic Ministry of Infrastructure, Transport, and Networks ελ // xn--j6w193g ("Hong Kong", Chinese) : HK // https://www.hkirc.hk // Submitted by registry // https://www.hkirc.hk/content.jsp?id=30#!/34 香港 個人.香港 å…¬å¸.香港 政府.香港 教育.香港 組織.香港 網絡.香港 // xn--2scrj9c ("Bharat", Kannada) : IN // India ಭಾರತ // xn--3hcrj9c ("Bharat", Oriya) : IN // India ଭାରତ // xn--45br5cyl ("Bharatam", Assamese) : IN // India ভাৰত // xn--h2breg3eve ("Bharatam", Sanskrit) : IN // India भारतमॠ// xn--h2brj9c8c ("Bharot", Santali) : IN // India भारोत // xn--mgbgu82a ("Bharat", Sindhi) : IN // India ڀارت // xn--rvc1e0am3e ("Bharatam", Malayalam) : IN // India ഭാരതം // xn--h2brj9c ("Bharat", Devanagari) : IN // India भारत // xn--mgbbh1a ("Bharat", Kashmiri) : IN // India بارت // xn--mgbbh1a71e ("Bharat", Arabic) : IN // India بھارت // xn--fpcrj9c3d ("Bharat", Telugu) : IN // India భారతౠ// xn--gecrj9c ("Bharat", Gujarati) : IN // India ભારત // xn--s9brj9c ("Bharat", Gurmukhi) : IN // India ਭਾਰਤ // xn--45brj9c ("Bharat", Bengali) : IN // India ভারত // xn--xkc2dl3a5ee0h ("India", Tamil) : IN // India இநà¯à®¤à®¿à®¯à®¾ // xn--mgba3a4f16a ("Iran", Persian) : IR ایران // xn--mgba3a4fra ("Iran", Arabic) : IR ايران // xn--mgbtx2b ("Iraq", Arabic) : IQ // Communications and Media Commission عراق // xn--mgbayh7gpa ("al-Ordon", Arabic) : JO // National Information Technology Center (NITC) // Royal Scientific Society, Al-Jubeiha الاردن // xn--3e0b707e ("Republic of Korea", Hangul) : KR 한국 // xn--80ao21a ("Kaz", Kazakh) : KZ қаз // xn--q7ce6a ("Lao", Lao) : LA ລາວ // xn--fzc2c9e2c ("Lanka", Sinhalese-Sinhala) : LK // https://nic.lk ලංක෠// xn--xkc2al3hye2a ("Ilangai", Tamil) : LK // https://nic.lk இலஙà¯à®•ை // xn--mgbc0a9azcg ("Morocco/al-Maghrib", Arabic) : MA المغرب // xn--d1alf ("mkd", Macedonian) : MK // MARnet мкд // xn--l1acc ("mon", Mongolian) : MN мон // xn--mix891f ("Macao", Chinese, Traditional) : MO // MONIC / HNET Asia (Registry Operator for .mo) 澳門 // xn--mix082f ("Macao", Chinese, Simplified) : MO 澳门 // xn--mgbx4cd0ab ("Malaysia", Malay) : MY مليسيا // xn--mgb9awbf ("Oman", Arabic) : OM عمان // xn--mgbai9azgqp6j ("Pakistan", Urdu/Arabic) : PK پاکستان // xn--mgbai9a5eva00b ("Pakistan", Urdu/Arabic, variant) : PK پاكستان // xn--ygbi2ammx ("Falasteen", Arabic) : PS // The Palestinian National Internet Naming Authority (PNINA) // http://www.pnina.ps Ùلسطين // xn--90a3ac ("srb", Cyrillic) : RS // https://www.rnids.rs/en/domains/national-domains Ñрб ак.Ñрб обр.Ñрб од.Ñрб орг.Ñрб пр.Ñрб упр.Ñрб // xn--p1ai ("rf", Russian-Cyrillic) : RU // https://cctld.ru/files/pdf/docs/en/rules_ru-rf.pdf // Submitted by George Georgievsky рф // xn--wgbl6a ("Qatar", Arabic) : QA // http://www.ict.gov.qa/ قطر // xn--mgberp4a5d4ar ("AlSaudiah", Arabic) : SA // http://www.nic.net.sa/ السعودية // xn--mgberp4a5d4a87g ("AlSaudiah", Arabic, variant): SA السعودیة // xn--mgbqly7c0a67fbc ("AlSaudiah", Arabic, variant) : SA السعودیۃ // xn--mgbqly7cvafr ("AlSaudiah", Arabic, variant) : SA السعوديه // xn--mgbpl2fh ("sudan", Arabic) : SD // Operated by .sd registry سودان // xn--yfro4i67o Singapore ("Singapore", Chinese) : SG æ–°åŠ å¡ // xn--clchc0ea0b2g2a9gcd ("Singapore", Tamil) : SG சிஙà¯à®•பà¯à®ªà¯‚ர௠// xn--ogbpf8fl ("Syria", Arabic) : SY سورية // xn--mgbtf8fl ("Syria", Arabic, variant) : SY سوريا // xn--o3cw4h ("Thai", Thai) : TH // http://www.thnic.co.th ไทย ทหาร.ไทย ธุรà¸à¸´à¸ˆ.ไทย เน็ต.ไทย รัà¸à¸šà¸²à¸¥.ไทย ศึà¸à¸©à¸².ไทย องค์à¸à¸£.ไทย // xn--pgbs0dh ("Tunisia", Arabic) : TN // http://nic.tn تونس // xn--kpry57d ("Taiwan", Chinese, Traditional) : TW // https://twnic.tw/dnservice_catag.php å°ç£ // xn--kprw13d ("Taiwan", Chinese, Simplified) : TW // http://www.twnic.net/english/dn/dn_07a.htm å°æ¹¾ // xn--nnx388a ("Taiwan", Chinese, variant) : TW è‡ºç£ // xn--j1amh ("ukr", Cyrillic) : UA укр // xn--mgb2ddes ("AlYemen", Arabic) : YE اليمن // xxx : http://icmregistry.com xxx // ye : http://www.y.net.ye/services/domain_name.htm ye com.ye edu.ye gov.ye mil.ye net.ye org.ye // za : https://www.iana.org/domains/root/db/za.html ac.za agric.za alt.za co.za edu.za gov.za grondar.za law.za mil.za net.za ngo.za nic.za nis.za nom.za org.za school.za tm.za web.za // zm : https://zicta.zm/ // Submitted by registry zm ac.zm biz.zm co.zm com.zm edu.zm gov.zm info.zm mil.zm net.zm org.zm sch.zm // zw : https://www.potraz.gov.zw/ // Confirmed by registry 2017-01-25 zw ac.zw co.zw gov.zw mil.zw org.zw // newGTLDs // List of new gTLDs imported from https://www.icann.org/resources/registries/gtlds/v2/gtlds.json on 2026-02-18T15:51:43Z // This list is auto-generated, don't edit it manually. // aaa : American Automobile Association, Inc. // https://www.iana.org/domains/root/db/aaa.html aaa // aarp : AARP // https://www.iana.org/domains/root/db/aarp.html aarp // abb : ABB Ltd // https://www.iana.org/domains/root/db/abb.html abb // abbott : Abbott Laboratories, Inc. // https://www.iana.org/domains/root/db/abbott.html abbott // abbvie : AbbVie Inc. // https://www.iana.org/domains/root/db/abbvie.html abbvie // abc : Disney Enterprises, Inc. // https://www.iana.org/domains/root/db/abc.html abc // able : Able Inc. // https://www.iana.org/domains/root/db/able.html able // abogado : Registry Services, LLC // https://www.iana.org/domains/root/db/abogado.html abogado // abudhabi : Abu Dhabi Systems and Information Centre // https://www.iana.org/domains/root/db/abudhabi.html abudhabi // academy : Binky Moon, LLC // https://www.iana.org/domains/root/db/academy.html academy // accenture : Accenture plc // https://www.iana.org/domains/root/db/accenture.html accenture // accountant : dot Accountant Limited // https://www.iana.org/domains/root/db/accountant.html accountant // accountants : Binky Moon, LLC // https://www.iana.org/domains/root/db/accountants.html accountants // aco : ACO Severin Ahlmann GmbH & Co. KG // https://www.iana.org/domains/root/db/aco.html aco // actor : Dog Beach, LLC // https://www.iana.org/domains/root/db/actor.html actor // ads : Charleston Road Registry Inc. // https://www.iana.org/domains/root/db/ads.html ads // adult : ICM Registry AD LLC // https://www.iana.org/domains/root/db/adult.html adult // aeg : Aktiebolaget Electrolux // https://www.iana.org/domains/root/db/aeg.html aeg // aetna : Aetna Life Insurance Company // https://www.iana.org/domains/root/db/aetna.html aetna // afl : Australian Football League // https://www.iana.org/domains/root/db/afl.html afl // africa : ZA Central Registry NPC trading as Registry.Africa // https://www.iana.org/domains/root/db/africa.html africa // agakhan : Fondation Aga Khan (Aga Khan Foundation) // https://www.iana.org/domains/root/db/agakhan.html agakhan // agency : Binky Moon, LLC // https://www.iana.org/domains/root/db/agency.html agency // aig : American International Group, Inc. // https://www.iana.org/domains/root/db/aig.html aig // airbus : Airbus S.A.S. // https://www.iana.org/domains/root/db/airbus.html airbus // airforce : Dog Beach, LLC // https://www.iana.org/domains/root/db/airforce.html airforce // airtel : Bharti Airtel Limited // https://www.iana.org/domains/root/db/airtel.html airtel // akdn : Fondation Aga Khan (Aga Khan Foundation) // https://www.iana.org/domains/root/db/akdn.html akdn // alibaba : Alibaba Group Holding Limited // https://www.iana.org/domains/root/db/alibaba.html alibaba // alipay : Alibaba Group Holding Limited // https://www.iana.org/domains/root/db/alipay.html alipay // allfinanz : Allfinanz Deutsche Vermögensberatung Aktiengesellschaft // https://www.iana.org/domains/root/db/allfinanz.html allfinanz // allstate : Allstate Fire and Casualty Insurance Company // https://www.iana.org/domains/root/db/allstate.html allstate // ally : Ally Financial Inc. // https://www.iana.org/domains/root/db/ally.html ally // alsace : Region Grand Est // https://www.iana.org/domains/root/db/alsace.html alsace // alstom : ALSTOM // https://www.iana.org/domains/root/db/alstom.html alstom // amazon : Amazon Registry Services, Inc. // https://www.iana.org/domains/root/db/amazon.html amazon // americanexpress : American Express Travel Related Services Company, Inc. // https://www.iana.org/domains/root/db/americanexpress.html americanexpress // americanfamily : AmFam, Inc. // https://www.iana.org/domains/root/db/americanfamily.html americanfamily // amex : American Express Travel Related Services Company, Inc. // https://www.iana.org/domains/root/db/amex.html amex // amfam : AmFam, Inc. // https://www.iana.org/domains/root/db/amfam.html amfam // amica : Amica Mutual Insurance Company // https://www.iana.org/domains/root/db/amica.html amica // amsterdam : Gemeente Amsterdam // https://www.iana.org/domains/root/db/amsterdam.html amsterdam // analytics : Campus IP LLC // https://www.iana.org/domains/root/db/analytics.html analytics // android : Charleston Road Registry Inc. // https://www.iana.org/domains/root/db/android.html android // anquan : Beijing Qihu Keji Co., Ltd. // https://www.iana.org/domains/root/db/anquan.html anquan // anz : Australia and New Zealand Banking Group Limited // https://www.iana.org/domains/root/db/anz.html anz // aol : Yahoo Inc. // https://www.iana.org/domains/root/db/aol.html aol // apartments : Binky Moon, LLC // https://www.iana.org/domains/root/db/apartments.html apartments // app : Charleston Road Registry Inc. // https://www.iana.org/domains/root/db/app.html app // apple : Apple Inc. // https://www.iana.org/domains/root/db/apple.html apple // aquarelle : Aquarelle.com // https://www.iana.org/domains/root/db/aquarelle.html aquarelle // arab : League of Arab States // https://www.iana.org/domains/root/db/arab.html arab // aramco : Aramco Services Company // https://www.iana.org/domains/root/db/aramco.html aramco // archi : Identity Digital Domains Limited // https://www.iana.org/domains/root/db/archi.html archi // army : Dog Beach, LLC // https://www.iana.org/domains/root/db/army.html army // art : UK Creative Ideas Limited // https://www.iana.org/domains/root/db/art.html art // arte : Association Relative à la Télévision Européenne G.E.I.E. // https://www.iana.org/domains/root/db/arte.html arte // asda : Asda Stores Limited // https://www.iana.org/domains/root/db/asda.html asda // associates : Binky Moon, LLC // https://www.iana.org/domains/root/db/associates.html associates // athleta : The Gap, Inc. // https://www.iana.org/domains/root/db/athleta.html athleta // attorney : Dog Beach, LLC // https://www.iana.org/domains/root/db/attorney.html attorney // auction : Dog Beach, LLC // https://www.iana.org/domains/root/db/auction.html auction // audi : AUDI Aktiengesellschaft // https://www.iana.org/domains/root/db/audi.html audi // audible : Amazon Registry Services, Inc. // https://www.iana.org/domains/root/db/audible.html audible // audio : XYZ.COM LLC // https://www.iana.org/domains/root/db/audio.html audio // auspost : Australian Postal Corporation // https://www.iana.org/domains/root/db/auspost.html auspost // author : Amazon Registry Services, Inc. // https://www.iana.org/domains/root/db/author.html author // auto : XYZ.COM LLC // https://www.iana.org/domains/root/db/auto.html auto // autos : XYZ.COM LLC // https://www.iana.org/domains/root/db/autos.html autos // aws : AWS Registry LLC // https://www.iana.org/domains/root/db/aws.html aws // axa : AXA Group Operations SAS // https://www.iana.org/domains/root/db/axa.html axa // azure : Microsoft Corporation // https://www.iana.org/domains/root/db/azure.html azure // baby : XYZ.COM LLC // https://www.iana.org/domains/root/db/baby.html baby // baidu : Baidu, Inc. // https://www.iana.org/domains/root/db/baidu.html baidu // banamex : Citigroup Inc. // https://www.iana.org/domains/root/db/banamex.html banamex // band : Dog Beach, LLC // https://www.iana.org/domains/root/db/band.html band // bank : fTLD Registry Services LLC // https://www.iana.org/domains/root/db/bank.html bank // bar : Punto 2012 Sociedad Anonima Promotora de Inversion de Capital Variable // https://www.iana.org/domains/root/db/bar.html bar // barcelona : Municipi de Barcelona // https://www.iana.org/domains/root/db/barcelona.html barcelona // barclaycard : Barclays Bank PLC // https://www.iana.org/domains/root/db/barclaycard.html barclaycard // barclays : Barclays Bank PLC // https://www.iana.org/domains/root/db/barclays.html barclays // barefoot : Gallo Vineyards, Inc. // https://www.iana.org/domains/root/db/barefoot.html barefoot // bargains : Binky Moon, LLC // https://www.iana.org/domains/root/db/bargains.html bargains // baseball : MLB Advanced Media DH, LLC // https://www.iana.org/domains/root/db/baseball.html baseball // basketball : Fédération Internationale de Basketball (FIBA) // https://www.iana.org/domains/root/db/basketball.html basketball // bauhaus : Werkhaus GmbH // https://www.iana.org/domains/root/db/bauhaus.html bauhaus // bayern : Bayern Connect GmbH // https://www.iana.org/domains/root/db/bayern.html bayern // bbc : British Broadcasting Corporation // https://www.iana.org/domains/root/db/bbc.html bbc // bbt : BB&T Corporation // https://www.iana.org/domains/root/db/bbt.html bbt // bbva : BANCO BILBAO VIZCAYA ARGENTARIA, S.A. // https://www.iana.org/domains/root/db/bbva.html bbva // bcg : The Boston Consulting Group, Inc. // https://www.iana.org/domains/root/db/bcg.html bcg // bcn : Municipi de Barcelona // https://www.iana.org/domains/root/db/bcn.html bcn // beats : Beats Electronics, LLC // https://www.iana.org/domains/root/db/beats.html beats // beauty : XYZ.COM LLC // https://www.iana.org/domains/root/db/beauty.html beauty // beer : Registry Services, LLC // https://www.iana.org/domains/root/db/beer.html beer // berlin : dotBERLIN GmbH & Co. KG // https://www.iana.org/domains/root/db/berlin.html berlin // best : BestTLD Pty Ltd // https://www.iana.org/domains/root/db/best.html best // bestbuy : BBY Solutions, Inc. // https://www.iana.org/domains/root/db/bestbuy.html bestbuy // bet : Identity Digital Domains Limited // https://www.iana.org/domains/root/db/bet.html bet // bharti : Bharti Enterprises (Holding) Private Limited // https://www.iana.org/domains/root/db/bharti.html bharti // bible : American Bible Society // https://www.iana.org/domains/root/db/bible.html bible // bid : dot Bid Limited // https://www.iana.org/domains/root/db/bid.html bid // bike : Binky Moon, LLC // https://www.iana.org/domains/root/db/bike.html bike // bing : Microsoft Corporation // https://www.iana.org/domains/root/db/bing.html bing // bingo : Binky Moon, LLC // https://www.iana.org/domains/root/db/bingo.html bingo // bio : Identity Digital Domains Limited // https://www.iana.org/domains/root/db/bio.html bio // black : Identity Digital Domains Limited // https://www.iana.org/domains/root/db/black.html black // blackfriday : Registry Services, LLC // https://www.iana.org/domains/root/db/blackfriday.html blackfriday // blockbuster : Dish DBS Corporation // https://www.iana.org/domains/root/db/blockbuster.html blockbuster // blog : Knock Knock WHOIS There, LLC // https://www.iana.org/domains/root/db/blog.html blog // bloomberg : Bloomberg IP Holdings LLC // https://www.iana.org/domains/root/db/bloomberg.html bloomberg // blue : Identity Digital Domains Limited // https://www.iana.org/domains/root/db/blue.html blue // bms : Bristol-Myers Squibb Company // https://www.iana.org/domains/root/db/bms.html bms // bmw : Bayerische Motoren Werke Aktiengesellschaft // https://www.iana.org/domains/root/db/bmw.html bmw // bnpparibas : BNP Paribas // https://www.iana.org/domains/root/db/bnpparibas.html bnpparibas // boats : XYZ.COM LLC // https://www.iana.org/domains/root/db/boats.html boats // boehringer : Boehringer Ingelheim International GmbH // https://www.iana.org/domains/root/db/boehringer.html boehringer // bofa : Bank of America Corporation // https://www.iana.org/domains/root/db/bofa.html bofa // bom : Núcleo de Informação e Coordenação do Ponto BR - NIC.br // https://www.iana.org/domains/root/db/bom.html bom // bond : ShortDot SA // https://www.iana.org/domains/root/db/bond.html bond // boo : Charleston Road Registry Inc. // https://www.iana.org/domains/root/db/boo.html boo // book : Amazon Registry Services, Inc. // https://www.iana.org/domains/root/db/book.html book // booking : Booking.com B.V. // https://www.iana.org/domains/root/db/booking.html booking // bosch : Robert Bosch GMBH // https://www.iana.org/domains/root/db/bosch.html bosch // bostik : Bostik SA // https://www.iana.org/domains/root/db/bostik.html bostik // boston : Registry Services, LLC // https://www.iana.org/domains/root/db/boston.html boston // bot : Amazon Registry Services, Inc. // https://www.iana.org/domains/root/db/bot.html bot // boutique : Binky Moon, LLC // https://www.iana.org/domains/root/db/boutique.html boutique // box : Intercap Registry Inc. // https://www.iana.org/domains/root/db/box.html box // bradesco : Banco Bradesco S.A. // https://www.iana.org/domains/root/db/bradesco.html bradesco // bridgestone : Bridgestone Corporation // https://www.iana.org/domains/root/db/bridgestone.html bridgestone // broadway : Celebrate Broadway, Inc. // https://www.iana.org/domains/root/db/broadway.html broadway // broker : Dog Beach, LLC // https://www.iana.org/domains/root/db/broker.html broker // brother : Brother Industries, Ltd. // https://www.iana.org/domains/root/db/brother.html brother // brussels : DNS.be vzw // https://www.iana.org/domains/root/db/brussels.html brussels // build : Plan Bee LLC // https://www.iana.org/domains/root/db/build.html build // builders : Binky Moon, LLC // https://www.iana.org/domains/root/db/builders.html builders // business : Binky Moon, LLC // https://www.iana.org/domains/root/db/business.html business // buy : Amazon Registry Services, Inc. // https://www.iana.org/domains/root/db/buy.html buy // buzz : DOTSTRATEGY CO. // https://www.iana.org/domains/root/db/buzz.html buzz // bzh : Association www.bzh // https://www.iana.org/domains/root/db/bzh.html bzh // cab : Binky Moon, LLC // https://www.iana.org/domains/root/db/cab.html cab // cafe : Binky Moon, LLC // https://www.iana.org/domains/root/db/cafe.html cafe // cal : Charleston Road Registry Inc. // https://www.iana.org/domains/root/db/cal.html cal // call : Amazon Registry Services, Inc. // https://www.iana.org/domains/root/db/call.html call // calvinklein : PVH gTLD Holdings LLC // https://www.iana.org/domains/root/db/calvinklein.html calvinklein // cam : Cam Connecting SARL // https://www.iana.org/domains/root/db/cam.html cam // camera : Binky Moon, LLC // https://www.iana.org/domains/root/db/camera.html camera // camp : Binky Moon, LLC // https://www.iana.org/domains/root/db/camp.html camp // canon : Canon Inc. // https://www.iana.org/domains/root/db/canon.html canon // capetown : ZA Central Registry NPC trading as ZA Central Registry // https://www.iana.org/domains/root/db/capetown.html capetown // capital : Binky Moon, LLC // https://www.iana.org/domains/root/db/capital.html capital // capitalone : Capital One Financial Corporation // https://www.iana.org/domains/root/db/capitalone.html capitalone // car : XYZ.COM LLC // https://www.iana.org/domains/root/db/car.html car // caravan : Caravan International, Inc. // https://www.iana.org/domains/root/db/caravan.html caravan // cards : Binky Moon, LLC // https://www.iana.org/domains/root/db/cards.html cards // care : Binky Moon, LLC // https://www.iana.org/domains/root/db/care.html care // career : dotCareer LLC // https://www.iana.org/domains/root/db/career.html career // careers : Binky Moon, LLC // https://www.iana.org/domains/root/db/careers.html careers // cars : XYZ.COM LLC // https://www.iana.org/domains/root/db/cars.html cars // casa : Registry Services, LLC // https://www.iana.org/domains/root/db/casa.html casa // case : Digity, LLC // https://www.iana.org/domains/root/db/case.html case // cash : Binky Moon, LLC // https://www.iana.org/domains/root/db/cash.html cash // casino : Binky Moon, LLC // https://www.iana.org/domains/root/db/casino.html casino // catering : Binky Moon, LLC // https://www.iana.org/domains/root/db/catering.html catering // catholic : Pontificium Consilium de Comunicationibus Socialibus (PCCS) (Pontifical Council for Social Communication) // https://www.iana.org/domains/root/db/catholic.html catholic // cba : COMMONWEALTH BANK OF AUSTRALIA // https://www.iana.org/domains/root/db/cba.html cba // cbn : The Christian Broadcasting Network, Inc. // https://www.iana.org/domains/root/db/cbn.html cbn // cbre : CBRE, Inc. // https://www.iana.org/domains/root/db/cbre.html cbre // center : Binky Moon, LLC // https://www.iana.org/domains/root/db/center.html center // ceo : XYZ.COM LLC // https://www.iana.org/domains/root/db/ceo.html ceo // cern : European Organization for Nuclear Research ("CERN") // https://www.iana.org/domains/root/db/cern.html cern // cfa : CFA Institute // https://www.iana.org/domains/root/db/cfa.html cfa // cfd : ShortDot SA // https://www.iana.org/domains/root/db/cfd.html cfd // chanel : Chanel International B.V. // https://www.iana.org/domains/root/db/chanel.html chanel // channel : Charleston Road Registry Inc. // https://www.iana.org/domains/root/db/channel.html channel // charity : Public Interest Registry // https://www.iana.org/domains/root/db/charity.html charity // chase : JPMorgan Chase Bank, National Association // https://www.iana.org/domains/root/db/chase.html chase // chat : Binky Moon, LLC // https://www.iana.org/domains/root/db/chat.html chat // cheap : Binky Moon, LLC // https://www.iana.org/domains/root/db/cheap.html cheap // chintai : CHINTAI Corporation // https://www.iana.org/domains/root/db/chintai.html chintai // christmas : XYZ.COM LLC // https://www.iana.org/domains/root/db/christmas.html christmas // chrome : Charleston Road Registry Inc. // https://www.iana.org/domains/root/db/chrome.html chrome // church : Binky Moon, LLC // https://www.iana.org/domains/root/db/church.html church // cipriani : Hotel Cipriani Srl // https://www.iana.org/domains/root/db/cipriani.html cipriani // circle : Amazon Registry Services, Inc. // https://www.iana.org/domains/root/db/circle.html circle // cisco : Cisco Technology, Inc. // https://www.iana.org/domains/root/db/cisco.html cisco // citadel : Citadel Domain LLC // https://www.iana.org/domains/root/db/citadel.html citadel // citi : Citigroup Inc. // https://www.iana.org/domains/root/db/citi.html citi // citic : CITIC Group Corporation // https://www.iana.org/domains/root/db/citic.html citic // city : Binky Moon, LLC // https://www.iana.org/domains/root/db/city.html city // claims : Binky Moon, LLC // https://www.iana.org/domains/root/db/claims.html claims // cleaning : Binky Moon, LLC // https://www.iana.org/domains/root/db/cleaning.html cleaning // click : Waterford Limited // https://www.iana.org/domains/root/db/click.html click // clinic : Binky Moon, LLC // https://www.iana.org/domains/root/db/clinic.html clinic // clinique : The Estée Lauder Companies Inc. // https://www.iana.org/domains/root/db/clinique.html clinique // clothing : Binky Moon, LLC // https://www.iana.org/domains/root/db/clothing.html clothing // cloud : Aruba PEC S.p.A. // https://www.iana.org/domains/root/db/cloud.html cloud // club : Registry Services, LLC // https://www.iana.org/domains/root/db/club.html club // clubmed : Club Méditerranée S.A. // https://www.iana.org/domains/root/db/clubmed.html clubmed // coach : Binky Moon, LLC // https://www.iana.org/domains/root/db/coach.html coach // codes : Binky Moon, LLC // https://www.iana.org/domains/root/db/codes.html codes // coffee : Binky Moon, LLC // https://www.iana.org/domains/root/db/coffee.html coffee // college : XYZ.COM LLC // https://www.iana.org/domains/root/db/college.html college // cologne : dotKoeln GmbH // https://www.iana.org/domains/root/db/cologne.html cologne // commbank : COMMONWEALTH BANK OF AUSTRALIA // https://www.iana.org/domains/root/db/commbank.html commbank // community : Binky Moon, LLC // https://www.iana.org/domains/root/db/community.html community // company : Binky Moon, LLC // https://www.iana.org/domains/root/db/company.html company // compare : Registry Services, LLC // https://www.iana.org/domains/root/db/compare.html compare // computer : Binky Moon, LLC // https://www.iana.org/domains/root/db/computer.html computer // comsec : VeriSign, Inc. // https://www.iana.org/domains/root/db/comsec.html comsec // condos : Binky Moon, LLC // https://www.iana.org/domains/root/db/condos.html condos // construction : Binky Moon, LLC // https://www.iana.org/domains/root/db/construction.html construction // consulting : Dog Beach, LLC // https://www.iana.org/domains/root/db/consulting.html consulting // contact : Dog Beach, LLC // https://www.iana.org/domains/root/db/contact.html contact // contractors : Binky Moon, LLC // https://www.iana.org/domains/root/db/contractors.html contractors // cooking : Registry Services, LLC // https://www.iana.org/domains/root/db/cooking.html cooking // cool : Binky Moon, LLC // https://www.iana.org/domains/root/db/cool.html cool // corsica : Collectivité de Corse // https://www.iana.org/domains/root/db/corsica.html corsica // country : Internet Naming Company LLC // https://www.iana.org/domains/root/db/country.html country // coupon : Amazon Registry Services, Inc. // https://www.iana.org/domains/root/db/coupon.html coupon // coupons : Binky Moon, LLC // https://www.iana.org/domains/root/db/coupons.html coupons // courses : Registry Services, LLC // https://www.iana.org/domains/root/db/courses.html courses // cpa : American Institute of Certified Public Accountants // https://www.iana.org/domains/root/db/cpa.html cpa // credit : Binky Moon, LLC // https://www.iana.org/domains/root/db/credit.html credit // creditcard : Binky Moon, LLC // https://www.iana.org/domains/root/db/creditcard.html creditcard // creditunion : DotCooperation LLC // https://www.iana.org/domains/root/db/creditunion.html creditunion // cricket : dot Cricket Limited // https://www.iana.org/domains/root/db/cricket.html cricket // crown : Crown Equipment Corporation // https://www.iana.org/domains/root/db/crown.html crown // crs : Federated Co-operatives Limited // https://www.iana.org/domains/root/db/crs.html crs // cruise : Viking River Cruises (Bermuda) Ltd. // https://www.iana.org/domains/root/db/cruise.html cruise // cruises : Binky Moon, LLC // https://www.iana.org/domains/root/db/cruises.html cruises // cuisinella : SCHMIDT GROUPE S.A.S. // https://www.iana.org/domains/root/db/cuisinella.html cuisinella // cymru : Nominet UK // https://www.iana.org/domains/root/db/cymru.html cymru // cyou : ShortDot SA // https://www.iana.org/domains/root/db/cyou.html cyou // dad : Charleston Road Registry Inc. // https://www.iana.org/domains/root/db/dad.html dad // dance : Dog Beach, LLC // https://www.iana.org/domains/root/db/dance.html dance // data : Dish DBS Corporation // https://www.iana.org/domains/root/db/data.html data // date : dot Date Limited // https://www.iana.org/domains/root/db/date.html date // dating : Binky Moon, LLC // https://www.iana.org/domains/root/db/dating.html dating // datsun : NISSAN MOTOR CO., LTD. // https://www.iana.org/domains/root/db/datsun.html datsun // day : Charleston Road Registry Inc. // https://www.iana.org/domains/root/db/day.html day // dclk : Charleston Road Registry Inc. // https://www.iana.org/domains/root/db/dclk.html dclk // dds : Registry Services, LLC // https://www.iana.org/domains/root/db/dds.html dds // deal : Amazon Registry Services, Inc. // https://www.iana.org/domains/root/db/deal.html deal // dealer : Intercap Registry Inc. // https://www.iana.org/domains/root/db/dealer.html dealer // deals : Binky Moon, LLC // https://www.iana.org/domains/root/db/deals.html deals // degree : Dog Beach, LLC // https://www.iana.org/domains/root/db/degree.html degree // delivery : Binky Moon, LLC // https://www.iana.org/domains/root/db/delivery.html delivery // dell : Dell Inc. // https://www.iana.org/domains/root/db/dell.html dell // deloitte : Deloitte Touche Tohmatsu // https://www.iana.org/domains/root/db/deloitte.html deloitte // delta : Delta Air Lines, Inc. // https://www.iana.org/domains/root/db/delta.html delta // democrat : Dog Beach, LLC // https://www.iana.org/domains/root/db/democrat.html democrat // dental : Binky Moon, LLC // https://www.iana.org/domains/root/db/dental.html dental // dentist : Dog Beach, LLC // https://www.iana.org/domains/root/db/dentist.html dentist // desi // https://www.iana.org/domains/root/db/desi.html desi // design : Registry Services, LLC // https://www.iana.org/domains/root/db/design.html design // dev : Charleston Road Registry Inc. // https://www.iana.org/domains/root/db/dev.html dev // dhl : Deutsche Post AG // https://www.iana.org/domains/root/db/dhl.html dhl // diamonds : Binky Moon, LLC // https://www.iana.org/domains/root/db/diamonds.html diamonds // diet : XYZ.COM LLC // https://www.iana.org/domains/root/db/diet.html diet // digital : Binky Moon, LLC // https://www.iana.org/domains/root/db/digital.html digital // direct : Binky Moon, LLC // https://www.iana.org/domains/root/db/direct.html direct // directory : Binky Moon, LLC // https://www.iana.org/domains/root/db/directory.html directory // discount : Binky Moon, LLC // https://www.iana.org/domains/root/db/discount.html discount // discover : Discover Financial Services // https://www.iana.org/domains/root/db/discover.html discover // dish : Dish DBS Corporation // https://www.iana.org/domains/root/db/dish.html dish // diy : Internet Naming Company LLC // https://www.iana.org/domains/root/db/diy.html diy // dnp : Dai Nippon Printing Co., Ltd. // https://www.iana.org/domains/root/db/dnp.html dnp // docs : Charleston Road Registry Inc. // https://www.iana.org/domains/root/db/docs.html docs // doctor : Binky Moon, LLC // https://www.iana.org/domains/root/db/doctor.html doctor // dog : Binky Moon, LLC // https://www.iana.org/domains/root/db/dog.html dog // domains : Binky Moon, LLC // https://www.iana.org/domains/root/db/domains.html domains // dot : Dish DBS Corporation // https://www.iana.org/domains/root/db/dot.html dot // download : dot Support Limited // https://www.iana.org/domains/root/db/download.html download // drive : Charleston Road Registry Inc. // https://www.iana.org/domains/root/db/drive.html drive // dtv : Dish DBS Corporation // https://www.iana.org/domains/root/db/dtv.html dtv // dubai : Dubai Smart Government Department // https://www.iana.org/domains/root/db/dubai.html dubai // dupont : DuPont Specialty Products USA, LLC // https://www.iana.org/domains/root/db/dupont.html dupont // durban : ZA Central Registry NPC trading as ZA Central Registry // https://www.iana.org/domains/root/db/durban.html durban // dvag : Deutsche Vermögensberatung Aktiengesellschaft DVAG // https://www.iana.org/domains/root/db/dvag.html dvag // dvr : DISH Technologies L.L.C. // https://www.iana.org/domains/root/db/dvr.html dvr // earth : Interlink Systems Innovation Institute K.K. // https://www.iana.org/domains/root/db/earth.html earth // eat : Charleston Road Registry Inc. // https://www.iana.org/domains/root/db/eat.html eat // eco : Big Room Inc. // https://www.iana.org/domains/root/db/eco.html eco // edeka : EDEKA Verband kaufmännischer Genossenschaften e.V. // https://www.iana.org/domains/root/db/edeka.html edeka // education : Binky Moon, LLC // https://www.iana.org/domains/root/db/education.html education // email : Binky Moon, LLC // https://www.iana.org/domains/root/db/email.html email // emerck : Merck KGaA // https://www.iana.org/domains/root/db/emerck.html emerck // energy : Binky Moon, LLC // https://www.iana.org/domains/root/db/energy.html energy // engineer : Dog Beach, LLC // https://www.iana.org/domains/root/db/engineer.html engineer // engineering : Binky Moon, LLC // https://www.iana.org/domains/root/db/engineering.html engineering // enterprises : Binky Moon, LLC // https://www.iana.org/domains/root/db/enterprises.html enterprises // epson : Seiko Epson Corporation // https://www.iana.org/domains/root/db/epson.html epson // equipment : Binky Moon, LLC // https://www.iana.org/domains/root/db/equipment.html equipment // ericsson : Telefonaktiebolaget L M Ericsson // https://www.iana.org/domains/root/db/ericsson.html ericsson // erni : ERNI Group Holding AG // https://www.iana.org/domains/root/db/erni.html erni // esq : Charleston Road Registry Inc. // https://www.iana.org/domains/root/db/esq.html esq // estate : Binky Moon, LLC // https://www.iana.org/domains/root/db/estate.html estate // eurovision : European Broadcasting Union (EBU) // https://www.iana.org/domains/root/db/eurovision.html eurovision // eus : Puntueus Fundazioa // https://www.iana.org/domains/root/db/eus.html eus // events : Binky Moon, LLC // https://www.iana.org/domains/root/db/events.html events // exchange : Binky Moon, LLC // https://www.iana.org/domains/root/db/exchange.html exchange // expert : Binky Moon, LLC // https://www.iana.org/domains/root/db/expert.html expert // exposed : Binky Moon, LLC // https://www.iana.org/domains/root/db/exposed.html exposed // express : Binky Moon, LLC // https://www.iana.org/domains/root/db/express.html express // extraspace : Extra Space Storage LLC // https://www.iana.org/domains/root/db/extraspace.html extraspace // fage : Fage International S.A. // https://www.iana.org/domains/root/db/fage.html fage // fail : Binky Moon, LLC // https://www.iana.org/domains/root/db/fail.html fail // fairwinds : FairWinds Partners, LLC // https://www.iana.org/domains/root/db/fairwinds.html fairwinds // faith : dot Faith Limited // https://www.iana.org/domains/root/db/faith.html faith // family : Dog Beach, LLC // https://www.iana.org/domains/root/db/family.html family // fan : Dog Beach, LLC // https://www.iana.org/domains/root/db/fan.html fan // fans : ZDNS International Limited // https://www.iana.org/domains/root/db/fans.html fans // farm : Binky Moon, LLC // https://www.iana.org/domains/root/db/farm.html farm // farmers : Farmers Insurance Exchange // https://www.iana.org/domains/root/db/farmers.html farmers // fashion : Registry Services, LLC // https://www.iana.org/domains/root/db/fashion.html fashion // fast : Amazon Registry Services, Inc. // https://www.iana.org/domains/root/db/fast.html fast // fedex : Federal Express Corporation // https://www.iana.org/domains/root/db/fedex.html fedex // feedback : Top Level Spectrum, Inc. // https://www.iana.org/domains/root/db/feedback.html feedback // ferrari : Fiat Chrysler Automobiles N.V. // https://www.iana.org/domains/root/db/ferrari.html ferrari // ferrero : Ferrero Trading Lux S.A. // https://www.iana.org/domains/root/db/ferrero.html ferrero // fidelity : Fidelity Brokerage Services LLC // https://www.iana.org/domains/root/db/fidelity.html fidelity // fido : Rogers Communications Canada Inc. // https://www.iana.org/domains/root/db/fido.html fido // film : Motion Picture Domain Registry Pty Ltd // https://www.iana.org/domains/root/db/film.html film // final : Núcleo de Informação e Coordenação do Ponto BR - NIC.br // https://www.iana.org/domains/root/db/final.html final // finance : Binky Moon, LLC // https://www.iana.org/domains/root/db/finance.html finance // financial : Binky Moon, LLC // https://www.iana.org/domains/root/db/financial.html financial // fire : Amazon Registry Services, Inc. // https://www.iana.org/domains/root/db/fire.html fire // firestone : Bridgestone Licensing Services, Inc // https://www.iana.org/domains/root/db/firestone.html firestone // firmdale : Firmdale Holdings Limited // https://www.iana.org/domains/root/db/firmdale.html firmdale // fish : Binky Moon, LLC // https://www.iana.org/domains/root/db/fish.html fish // fishing : Registry Services, LLC // https://www.iana.org/domains/root/db/fishing.html fishing // fit : Registry Services, LLC // https://www.iana.org/domains/root/db/fit.html fit // fitness : Binky Moon, LLC // https://www.iana.org/domains/root/db/fitness.html fitness // flickr : Flickr, Inc. // https://www.iana.org/domains/root/db/flickr.html flickr // flights : Binky Moon, LLC // https://www.iana.org/domains/root/db/flights.html flights // flir : FLIR Systems, Inc. // https://www.iana.org/domains/root/db/flir.html flir // florist : Binky Moon, LLC // https://www.iana.org/domains/root/db/florist.html florist // flowers : XYZ.COM LLC // https://www.iana.org/domains/root/db/flowers.html flowers // fly : Charleston Road Registry Inc. // https://www.iana.org/domains/root/db/fly.html fly // foo : Charleston Road Registry Inc. // https://www.iana.org/domains/root/db/foo.html foo // food : Internet Naming Company LLC // https://www.iana.org/domains/root/db/food.html food // football : Binky Moon, LLC // https://www.iana.org/domains/root/db/football.html football // ford : Ford Motor Company // https://www.iana.org/domains/root/db/ford.html ford // forex : Dog Beach, LLC // https://www.iana.org/domains/root/db/forex.html forex // forsale : Dog Beach, LLC // https://www.iana.org/domains/root/db/forsale.html forsale // forum : Waterford Limited // https://www.iana.org/domains/root/db/forum.html forum // foundation : Public Interest Registry // https://www.iana.org/domains/root/db/foundation.html foundation // fox : FOX Registry, LLC // https://www.iana.org/domains/root/db/fox.html fox // free : Amazon Registry Services, Inc. // https://www.iana.org/domains/root/db/free.html free // fresenius : Fresenius Immobilien-Verwaltungs-GmbH // https://www.iana.org/domains/root/db/fresenius.html fresenius // frl : FRLregistry B.V. // https://www.iana.org/domains/root/db/frl.html frl // frogans : OP3FT // https://www.iana.org/domains/root/db/frogans.html frogans // frontier : Frontier Communications Corporation // https://www.iana.org/domains/root/db/frontier.html frontier // ftr : Frontier Communications Corporation // https://www.iana.org/domains/root/db/ftr.html ftr // fujitsu : Fujitsu Limited // https://www.iana.org/domains/root/db/fujitsu.html fujitsu // fun : Radix Technologies Inc SEZC // https://www.iana.org/domains/root/db/fun.html fun // fund : Binky Moon, LLC // https://www.iana.org/domains/root/db/fund.html fund // furniture : Binky Moon, LLC // https://www.iana.org/domains/root/db/furniture.html furniture // futbol : Dog Beach, LLC // https://www.iana.org/domains/root/db/futbol.html futbol // fyi : Binky Moon, LLC // https://www.iana.org/domains/root/db/fyi.html fyi // gal : Asociación puntoGAL // https://www.iana.org/domains/root/db/gal.html gal // gallery : Binky Moon, LLC // https://www.iana.org/domains/root/db/gallery.html gallery // gallo : Gallo Vineyards, Inc. // https://www.iana.org/domains/root/db/gallo.html gallo // gallup : Gallup, Inc. // https://www.iana.org/domains/root/db/gallup.html gallup // game : XYZ.COM LLC // https://www.iana.org/domains/root/db/game.html game // games : Dog Beach, LLC // https://www.iana.org/domains/root/db/games.html games // gap : The Gap, Inc. // https://www.iana.org/domains/root/db/gap.html gap // garden : Registry Services, LLC // https://www.iana.org/domains/root/db/garden.html garden // gay : Registry Services, LLC // https://www.iana.org/domains/root/db/gay.html gay // gbiz : Charleston Road Registry Inc. // https://www.iana.org/domains/root/db/gbiz.html gbiz // gdn : Joint Stock Company "Navigation-information systems" // https://www.iana.org/domains/root/db/gdn.html gdn // gea : GEA Group Aktiengesellschaft // https://www.iana.org/domains/root/db/gea.html gea // gent : Easyhost BV // https://www.iana.org/domains/root/db/gent.html gent // genting : Resorts World Inc Pte. Ltd. // https://www.iana.org/domains/root/db/genting.html genting // george : Wal-Mart Stores, Inc. // https://www.iana.org/domains/root/db/george.html george // ggee : GMO Internet, Inc. // https://www.iana.org/domains/root/db/ggee.html ggee // gift : DotGift, LLC // https://www.iana.org/domains/root/db/gift.html gift // gifts : Binky Moon, LLC // https://www.iana.org/domains/root/db/gifts.html gifts // gives : Public Interest Registry // https://www.iana.org/domains/root/db/gives.html gives // giving : Public Interest Registry // https://www.iana.org/domains/root/db/giving.html giving // glass : Binky Moon, LLC // https://www.iana.org/domains/root/db/glass.html glass // gle : Charleston Road Registry Inc. // https://www.iana.org/domains/root/db/gle.html gle // global : Identity Digital Domains Limited // https://www.iana.org/domains/root/db/global.html global // globo : Globo Comunicação e Participações S.A // https://www.iana.org/domains/root/db/globo.html globo // gmail : Charleston Road Registry Inc. // https://www.iana.org/domains/root/db/gmail.html gmail // gmbh : Binky Moon, LLC // https://www.iana.org/domains/root/db/gmbh.html gmbh // gmo : GMO Internet, Inc. // https://www.iana.org/domains/root/db/gmo.html gmo // gmx : 1&1 Mail & Media GmbH // https://www.iana.org/domains/root/db/gmx.html gmx // godaddy : Go Daddy East, LLC // https://www.iana.org/domains/root/db/godaddy.html godaddy // gold : Binky Moon, LLC // https://www.iana.org/domains/root/db/gold.html gold // goldpoint : YODOBASHI CAMERA CO.,LTD. // https://www.iana.org/domains/root/db/goldpoint.html goldpoint // golf : Binky Moon, LLC // https://www.iana.org/domains/root/db/golf.html golf // goodyear : The Goodyear Tire & Rubber Company // https://www.iana.org/domains/root/db/goodyear.html goodyear // goog : Charleston Road Registry Inc. // https://www.iana.org/domains/root/db/goog.html goog // google : Charleston Road Registry Inc. // https://www.iana.org/domains/root/db/google.html google // gop : Republican State Leadership Committee, Inc. // https://www.iana.org/domains/root/db/gop.html gop // got : Amazon Registry Services, Inc. // https://www.iana.org/domains/root/db/got.html got // grainger : Grainger Registry Services, LLC // https://www.iana.org/domains/root/db/grainger.html grainger // graphics : Binky Moon, LLC // https://www.iana.org/domains/root/db/graphics.html graphics // gratis : Binky Moon, LLC // https://www.iana.org/domains/root/db/gratis.html gratis // green : Identity Digital Domains Limited // https://www.iana.org/domains/root/db/green.html green // gripe : Binky Moon, LLC // https://www.iana.org/domains/root/db/gripe.html gripe // grocery : Wal-Mart Stores, Inc. // https://www.iana.org/domains/root/db/grocery.html grocery // group : Binky Moon, LLC // https://www.iana.org/domains/root/db/group.html group // gucci : Guccio Gucci S.p.a. // https://www.iana.org/domains/root/db/gucci.html gucci // guge : Charleston Road Registry Inc. // https://www.iana.org/domains/root/db/guge.html guge // guide : Binky Moon, LLC // https://www.iana.org/domains/root/db/guide.html guide // guitars : XYZ.COM LLC // https://www.iana.org/domains/root/db/guitars.html guitars // guru : Binky Moon, LLC // https://www.iana.org/domains/root/db/guru.html guru // hair : XYZ.COM LLC // https://www.iana.org/domains/root/db/hair.html hair // hamburg : Hamburg Top-Level-Domain GmbH // https://www.iana.org/domains/root/db/hamburg.html hamburg // hangout : Charleston Road Registry Inc. // https://www.iana.org/domains/root/db/hangout.html hangout // haus : Dog Beach, LLC // https://www.iana.org/domains/root/db/haus.html haus // hbo : HBO Registry Services, Inc. // https://www.iana.org/domains/root/db/hbo.html hbo // hdfc : HDFC BANK LIMITED // https://www.iana.org/domains/root/db/hdfc.html hdfc // hdfcbank : HDFC BANK LIMITED // https://www.iana.org/domains/root/db/hdfcbank.html hdfcbank // health : Registry Services, LLC // https://www.iana.org/domains/root/db/health.html health // healthcare : Binky Moon, LLC // https://www.iana.org/domains/root/db/healthcare.html healthcare // help : Innovation service Limited // https://www.iana.org/domains/root/db/help.html help // helsinki : City of Helsinki // https://www.iana.org/domains/root/db/helsinki.html helsinki // here : Charleston Road Registry Inc. // https://www.iana.org/domains/root/db/here.html here // hermes : HERMES INTERNATIONAL // https://www.iana.org/domains/root/db/hermes.html hermes // hiphop : Dot Hip Hop, LLC // https://www.iana.org/domains/root/db/hiphop.html hiphop // hisamitsu : Hisamitsu Pharmaceutical Co.,Inc. // https://www.iana.org/domains/root/db/hisamitsu.html hisamitsu // hitachi : Hitachi, Ltd. // https://www.iana.org/domains/root/db/hitachi.html hitachi // hiv : Internet Naming Company LLC // https://www.iana.org/domains/root/db/hiv.html hiv // hkt : PCCW-HKT DataCom Services Limited // https://www.iana.org/domains/root/db/hkt.html hkt // hockey : Binky Moon, LLC // https://www.iana.org/domains/root/db/hockey.html hockey // holdings : Binky Moon, LLC // https://www.iana.org/domains/root/db/holdings.html holdings // holiday : Binky Moon, LLC // https://www.iana.org/domains/root/db/holiday.html holiday // homedepot : Home Depot Product Authority, LLC // https://www.iana.org/domains/root/db/homedepot.html homedepot // homegoods : The TJX Companies, Inc. // https://www.iana.org/domains/root/db/homegoods.html homegoods // homes : XYZ.COM LLC // https://www.iana.org/domains/root/db/homes.html homes // homesense : The TJX Companies, Inc. // https://www.iana.org/domains/root/db/homesense.html homesense // honda : Honda Motor Co., Ltd. // https://www.iana.org/domains/root/db/honda.html honda // horse : Registry Services, LLC // https://www.iana.org/domains/root/db/horse.html horse // hospital : Binky Moon, LLC // https://www.iana.org/domains/root/db/hospital.html hospital // host : Radix Technologies Inc SEZC // https://www.iana.org/domains/root/db/host.html host // hosting : XYZ.COM LLC // https://www.iana.org/domains/root/db/hosting.html hosting // hot : Amazon Registry Services, Inc. // https://www.iana.org/domains/root/db/hot.html hot // hotel : HOTEL Top-Level-Domain S.a.r.l // https://www.iana.org/domains/root/db/hotel.html hotel // hotels : Booking.com B.V. // https://www.iana.org/domains/root/db/hotels.html hotels // hotmail : Microsoft Corporation // https://www.iana.org/domains/root/db/hotmail.html hotmail // house : Binky Moon, LLC // https://www.iana.org/domains/root/db/house.html house // how : Charleston Road Registry Inc. // https://www.iana.org/domains/root/db/how.html how // hsbc : HSBC Global Services (UK) Limited // https://www.iana.org/domains/root/db/hsbc.html hsbc // hughes : Hughes Satellite Systems Corporation // https://www.iana.org/domains/root/db/hughes.html hughes // hyatt : Hyatt GTLD, L.L.C. // https://www.iana.org/domains/root/db/hyatt.html hyatt // hyundai : Hyundai Motor Company // https://www.iana.org/domains/root/db/hyundai.html hyundai // ibm : International Business Machines Corporation // https://www.iana.org/domains/root/db/ibm.html ibm // icbc : Industrial and Commercial Bank of China Limited // https://www.iana.org/domains/root/db/icbc.html icbc // ice : IntercontinentalExchange, Inc. // https://www.iana.org/domains/root/db/ice.html ice // icu : ShortDot SA // https://www.iana.org/domains/root/db/icu.html icu // ieee : IEEE Global LLC // https://www.iana.org/domains/root/db/ieee.html ieee // ifm : ifm electronic gmbh // https://www.iana.org/domains/root/db/ifm.html ifm // ikano : Ikano S.A. // https://www.iana.org/domains/root/db/ikano.html ikano // imamat : Fondation Aga Khan (Aga Khan Foundation) // https://www.iana.org/domains/root/db/imamat.html imamat // imdb : Amazon Registry Services, Inc. // https://www.iana.org/domains/root/db/imdb.html imdb // immo : Binky Moon, LLC // https://www.iana.org/domains/root/db/immo.html immo // immobilien : Dog Beach, LLC // https://www.iana.org/domains/root/db/immobilien.html immobilien // inc : Intercap Registry Inc. // https://www.iana.org/domains/root/db/inc.html inc // industries : Binky Moon, LLC // https://www.iana.org/domains/root/db/industries.html industries // infiniti : NISSAN MOTOR CO., LTD. // https://www.iana.org/domains/root/db/infiniti.html infiniti // ing : Charleston Road Registry Inc. // https://www.iana.org/domains/root/db/ing.html ing // ink : Registry Services, LLC // https://www.iana.org/domains/root/db/ink.html ink // institute : Binky Moon, LLC // https://www.iana.org/domains/root/db/institute.html institute // insurance : fTLD Registry Services LLC // https://www.iana.org/domains/root/db/insurance.html insurance // insure : Binky Moon, LLC // https://www.iana.org/domains/root/db/insure.html insure // international : Binky Moon, LLC // https://www.iana.org/domains/root/db/international.html international // intuit : Intuit Administrative Services, Inc. // https://www.iana.org/domains/root/db/intuit.html intuit // investments : Binky Moon, LLC // https://www.iana.org/domains/root/db/investments.html investments // ipiranga : Ipiranga Produtos de Petroleo S.A. // https://www.iana.org/domains/root/db/ipiranga.html ipiranga // irish : Binky Moon, LLC // https://www.iana.org/domains/root/db/irish.html irish // ismaili : Fondation Aga Khan (Aga Khan Foundation) // https://www.iana.org/domains/root/db/ismaili.html ismaili // ist : Istanbul Metropolitan Municipality // https://www.iana.org/domains/root/db/ist.html ist // istanbul : Istanbul Metropolitan Municipality // https://www.iana.org/domains/root/db/istanbul.html istanbul // itau : Itau Unibanco Holding S.A. // https://www.iana.org/domains/root/db/itau.html itau // itv : ITV Services Limited // https://www.iana.org/domains/root/db/itv.html itv // jaguar : Jaguar Land Rover Ltd // https://www.iana.org/domains/root/db/jaguar.html jaguar // java : Oracle Corporation // https://www.iana.org/domains/root/db/java.html java // jcb : JCB Co., Ltd. // https://www.iana.org/domains/root/db/jcb.html jcb // jeep : FCA US LLC. // https://www.iana.org/domains/root/db/jeep.html jeep // jetzt : Binky Moon, LLC // https://www.iana.org/domains/root/db/jetzt.html jetzt // jewelry : Binky Moon, LLC // https://www.iana.org/domains/root/db/jewelry.html jewelry // jio : Reliance Industries Limited // https://www.iana.org/domains/root/db/jio.html jio // jll : Jones Lang LaSalle Incorporated // https://www.iana.org/domains/root/db/jll.html jll // jmp : Matrix IP LLC // https://www.iana.org/domains/root/db/jmp.html jmp // jnj : Johnson & Johnson Services, Inc. // https://www.iana.org/domains/root/db/jnj.html jnj // joburg : ZA Central Registry NPC trading as ZA Central Registry // https://www.iana.org/domains/root/db/joburg.html joburg // jot : Amazon Registry Services, Inc. // https://www.iana.org/domains/root/db/jot.html jot // joy : Amazon Registry Services, Inc. // https://www.iana.org/domains/root/db/joy.html joy // jpmorgan : JPMorgan Chase Bank, National Association // https://www.iana.org/domains/root/db/jpmorgan.html jpmorgan // jprs : Japan Registry Services Co., Ltd. // https://www.iana.org/domains/root/db/jprs.html jprs // juegos : Dog Beach, LLC // https://www.iana.org/domains/root/db/juegos.html juegos // juniper : JUNIPER NETWORKS, INC. // https://www.iana.org/domains/root/db/juniper.html juniper // kaufen : Dog Beach, LLC // https://www.iana.org/domains/root/db/kaufen.html kaufen // kddi : KDDI CORPORATION // https://www.iana.org/domains/root/db/kddi.html kddi // kerryhotels : Kerry Trading Co. Limited // https://www.iana.org/domains/root/db/kerryhotels.html kerryhotels // kerryproperties : Kerry Trading Co. Limited // https://www.iana.org/domains/root/db/kerryproperties.html kerryproperties // kfh : Kuwait Finance House // https://www.iana.org/domains/root/db/kfh.html kfh // kia : KIA MOTORS CORPORATION // https://www.iana.org/domains/root/db/kia.html kia // kids : DotKids Foundation Limited // https://www.iana.org/domains/root/db/kids.html kids // kim : Identity Digital Domains Limited // https://www.iana.org/domains/root/db/kim.html kim // kindle : Amazon Registry Services, Inc. // https://www.iana.org/domains/root/db/kindle.html kindle // kitchen : Binky Moon, LLC // https://www.iana.org/domains/root/db/kitchen.html kitchen // kiwi : DOT KIWI LIMITED // https://www.iana.org/domains/root/db/kiwi.html kiwi // koeln : dotKoeln GmbH // https://www.iana.org/domains/root/db/koeln.html koeln // komatsu : Komatsu Ltd. // https://www.iana.org/domains/root/db/komatsu.html komatsu // kosher : Kosher Marketing Assets LLC // https://www.iana.org/domains/root/db/kosher.html kosher // kpmg : KPMG International Cooperative (KPMG International Genossenschaft) // https://www.iana.org/domains/root/db/kpmg.html kpmg // kpn : Koninklijke KPN N.V. // https://www.iana.org/domains/root/db/kpn.html kpn // krd : KRG Department of Information Technology // https://www.iana.org/domains/root/db/krd.html krd // kred : KredTLD Pty Ltd // https://www.iana.org/domains/root/db/kred.html kred // kuokgroup : Kerry Trading Co. Limited // https://www.iana.org/domains/root/db/kuokgroup.html kuokgroup // kyoto : Academic Institution: Kyoto Jyoho Gakuen // https://www.iana.org/domains/root/db/kyoto.html kyoto // lacaixa : Fundación Bancaria Caixa d’Estalvis i Pensions de Barcelona, “la Caixa†// https://www.iana.org/domains/root/db/lacaixa.html lacaixa // lamborghini : Automobili Lamborghini S.p.A. // https://www.iana.org/domains/root/db/lamborghini.html lamborghini // lamer : The Estée Lauder Companies Inc. // https://www.iana.org/domains/root/db/lamer.html lamer // land : Binky Moon, LLC // https://www.iana.org/domains/root/db/land.html land // landrover : Jaguar Land Rover Ltd // https://www.iana.org/domains/root/db/landrover.html landrover // lanxess : LANXESS Corporation // https://www.iana.org/domains/root/db/lanxess.html lanxess // lasalle : Jones Lang LaSalle Incorporated // https://www.iana.org/domains/root/db/lasalle.html lasalle // lat : XYZ.COM LLC // https://www.iana.org/domains/root/db/lat.html lat // latino : Dish DBS Corporation // https://www.iana.org/domains/root/db/latino.html latino // latrobe : La Trobe University // https://www.iana.org/domains/root/db/latrobe.html latrobe // law : Registry Services, LLC // https://www.iana.org/domains/root/db/law.html law // lawyer : Dog Beach, LLC // https://www.iana.org/domains/root/db/lawyer.html lawyer // lds : IRI Domain Management, LLC // https://www.iana.org/domains/root/db/lds.html lds // lease : Binky Moon, LLC // https://www.iana.org/domains/root/db/lease.html lease // leclerc : A.C.D. LEC Association des Centres Distributeurs Edouard Leclerc // https://www.iana.org/domains/root/db/leclerc.html leclerc // lefrak : LeFrak Organization, Inc. // https://www.iana.org/domains/root/db/lefrak.html lefrak // legal : Binky Moon, LLC // https://www.iana.org/domains/root/db/legal.html legal // lego : LEGO Juris A/S // https://www.iana.org/domains/root/db/lego.html lego // lexus : TOYOTA MOTOR CORPORATION // https://www.iana.org/domains/root/db/lexus.html lexus // lgbt : Identity Digital Domains Limited // https://www.iana.org/domains/root/db/lgbt.html lgbt // lidl : Schwarz Domains und Services GmbH & Co. KG // https://www.iana.org/domains/root/db/lidl.html lidl // life : Binky Moon, LLC // https://www.iana.org/domains/root/db/life.html life // lifeinsurance : American Council of Life Insurers // https://www.iana.org/domains/root/db/lifeinsurance.html lifeinsurance // lifestyle : Internet Naming Company LLC // https://www.iana.org/domains/root/db/lifestyle.html lifestyle // lighting : Binky Moon, LLC // https://www.iana.org/domains/root/db/lighting.html lighting // like : Amazon Registry Services, Inc. // https://www.iana.org/domains/root/db/like.html like // lilly : Eli Lilly and Company // https://www.iana.org/domains/root/db/lilly.html lilly // limited : Binky Moon, LLC // https://www.iana.org/domains/root/db/limited.html limited // limo : Binky Moon, LLC // https://www.iana.org/domains/root/db/limo.html limo // lincoln : Ford Motor Company // https://www.iana.org/domains/root/db/lincoln.html lincoln // link : Nova Registry Ltd // https://www.iana.org/domains/root/db/link.html link // live : Dog Beach, LLC // https://www.iana.org/domains/root/db/live.html live // living : Internet Naming Company LLC // https://www.iana.org/domains/root/db/living.html living // llc : Identity Digital Domains Limited // https://www.iana.org/domains/root/db/llc.html llc // llp : Intercap Registry Inc. // https://www.iana.org/domains/root/db/llp.html llp // loan : dot Loan Limited // https://www.iana.org/domains/root/db/loan.html loan // loans : Binky Moon, LLC // https://www.iana.org/domains/root/db/loans.html loans // locker : Orange Domains LLC // https://www.iana.org/domains/root/db/locker.html locker // locus : Locus Analytics LLC // https://www.iana.org/domains/root/db/locus.html locus // lol : XYZ.COM LLC // https://www.iana.org/domains/root/db/lol.html lol // london : Dot London Domains Limited // https://www.iana.org/domains/root/db/london.html london // lotte : Lotte Holdings Co., Ltd. // https://www.iana.org/domains/root/db/lotte.html lotte // lotto : Identity Digital Domains Limited // https://www.iana.org/domains/root/db/lotto.html lotto // love : Waterford Limited // https://www.iana.org/domains/root/db/love.html love // lpl : LPL Holdings, Inc. // https://www.iana.org/domains/root/db/lpl.html lpl // lplfinancial : LPL Holdings, Inc. // https://www.iana.org/domains/root/db/lplfinancial.html lplfinancial // ltd : Binky Moon, LLC // https://www.iana.org/domains/root/db/ltd.html ltd // ltda : InterNetX, Corp // https://www.iana.org/domains/root/db/ltda.html ltda // lundbeck : H. Lundbeck A/S // https://www.iana.org/domains/root/db/lundbeck.html lundbeck // luxe : Registry Services, LLC // https://www.iana.org/domains/root/db/luxe.html luxe // luxury : Luxury Partners, LLC // https://www.iana.org/domains/root/db/luxury.html luxury // madrid : Comunidad de Madrid // https://www.iana.org/domains/root/db/madrid.html madrid // maif : Mutuelle Assurance Instituteur France (MAIF) // https://www.iana.org/domains/root/db/maif.html maif // maison : Binky Moon, LLC // https://www.iana.org/domains/root/db/maison.html maison // makeup : XYZ.COM LLC // https://www.iana.org/domains/root/db/makeup.html makeup // man : MAN Truck & Bus SE // https://www.iana.org/domains/root/db/man.html man // management : Binky Moon, LLC // https://www.iana.org/domains/root/db/management.html management // mango : PUNTO FA S.L. // https://www.iana.org/domains/root/db/mango.html mango // map : Charleston Road Registry Inc. // https://www.iana.org/domains/root/db/map.html map // market : Dog Beach, LLC // https://www.iana.org/domains/root/db/market.html market // marketing : Binky Moon, LLC // https://www.iana.org/domains/root/db/marketing.html marketing // markets : Dog Beach, LLC // https://www.iana.org/domains/root/db/markets.html markets // marriott : Marriott Worldwide Corporation // https://www.iana.org/domains/root/db/marriott.html marriott // marshalls : The TJX Companies, Inc. // https://www.iana.org/domains/root/db/marshalls.html marshalls // mattel : Mattel IT Services, Inc. // https://www.iana.org/domains/root/db/mattel.html mattel // mba : Binky Moon, LLC // https://www.iana.org/domains/root/db/mba.html mba // mckinsey : McKinsey Holdings, Inc. // https://www.iana.org/domains/root/db/mckinsey.html mckinsey // med : Medistry LLC // https://www.iana.org/domains/root/db/med.html med // media : Binky Moon, LLC // https://www.iana.org/domains/root/db/media.html media // meet : Charleston Road Registry Inc. // https://www.iana.org/domains/root/db/meet.html meet // melbourne : The Crown in right of the State of Victoria, represented by its Department of State Development, Business and Innovation // https://www.iana.org/domains/root/db/melbourne.html melbourne // meme : Charleston Road Registry Inc. // https://www.iana.org/domains/root/db/meme.html meme // memorial : Dog Beach, LLC // https://www.iana.org/domains/root/db/memorial.html memorial // men : Exclusive Registry Limited // https://www.iana.org/domains/root/db/men.html men // menu : Dot Menu Registry, LLC // https://www.iana.org/domains/root/db/menu.html menu // merck : Merck Registry Holdings, Inc. // https://www.iana.org/domains/root/db/merck.html merck // merckmsd : MSD Registry Holdings, Inc. // https://www.iana.org/domains/root/db/merckmsd.html merckmsd // miami : Registry Services, LLC // https://www.iana.org/domains/root/db/miami.html miami // microsoft : Microsoft Corporation // https://www.iana.org/domains/root/db/microsoft.html microsoft // mini : Bayerische Motoren Werke Aktiengesellschaft // https://www.iana.org/domains/root/db/mini.html mini // mint : Intuit Administrative Services, Inc. // https://www.iana.org/domains/root/db/mint.html mint // mit : Massachusetts Institute of Technology // https://www.iana.org/domains/root/db/mit.html mit // mitsubishi : Mitsubishi Corporation // https://www.iana.org/domains/root/db/mitsubishi.html mitsubishi // mlb : MLB Advanced Media DH, LLC // https://www.iana.org/domains/root/db/mlb.html mlb // mls : The Canadian Real Estate Association // https://www.iana.org/domains/root/db/mls.html mls // mma : MMA IARD // https://www.iana.org/domains/root/db/mma.html mma // mobile : Dish DBS Corporation // https://www.iana.org/domains/root/db/mobile.html mobile // moda : Dog Beach, LLC // https://www.iana.org/domains/root/db/moda.html moda // moe : Interlink Systems Innovation Institute K.K. // https://www.iana.org/domains/root/db/moe.html moe // moi : Amazon Registry Services, Inc. // https://www.iana.org/domains/root/db/moi.html moi // mom : XYZ.COM LLC // https://www.iana.org/domains/root/db/mom.html mom // monash : Monash University // https://www.iana.org/domains/root/db/monash.html monash // money : Binky Moon, LLC // https://www.iana.org/domains/root/db/money.html money // monster : XYZ.COM LLC // https://www.iana.org/domains/root/db/monster.html monster // mormon : IRI Domain Management, LLC // https://www.iana.org/domains/root/db/mormon.html mormon // mortgage : Dog Beach, LLC // https://www.iana.org/domains/root/db/mortgage.html mortgage // moscow : Foundation for Assistance for Internet Technologies and Infrastructure Development (FAITID) // https://www.iana.org/domains/root/db/moscow.html moscow // moto : Motorola Trademark Holdings, LLC // https://www.iana.org/domains/root/db/moto.html moto // motorcycles : XYZ.COM LLC // https://www.iana.org/domains/root/db/motorcycles.html motorcycles // mov : Charleston Road Registry Inc. // https://www.iana.org/domains/root/db/mov.html mov // movie : Binky Moon, LLC // https://www.iana.org/domains/root/db/movie.html movie // msd : MSD Registry Holdings, Inc. // https://www.iana.org/domains/root/db/msd.html msd // mtn : MTN Dubai Limited // https://www.iana.org/domains/root/db/mtn.html mtn // mtr : MTR Corporation Limited // https://www.iana.org/domains/root/db/mtr.html mtr // music : DotMusic Limited // https://www.iana.org/domains/root/db/music.html music // nab : National Australia Bank Limited // https://www.iana.org/domains/root/db/nab.html nab // nagoya : GMO Registry, Inc. // https://www.iana.org/domains/root/db/nagoya.html nagoya // navy : Dog Beach, LLC // https://www.iana.org/domains/root/db/navy.html navy // nba : NBA REGISTRY, LLC // https://www.iana.org/domains/root/db/nba.html nba // nec : NEC Corporation // https://www.iana.org/domains/root/db/nec.html nec // netbank : COMMONWEALTH BANK OF AUSTRALIA // https://www.iana.org/domains/root/db/netbank.html netbank // netflix : Netflix, Inc. // https://www.iana.org/domains/root/db/netflix.html netflix // network : Binky Moon, LLC // https://www.iana.org/domains/root/db/network.html network // neustar : NeuStar, Inc. // https://www.iana.org/domains/root/db/neustar.html neustar // new : Charleston Road Registry Inc. // https://www.iana.org/domains/root/db/new.html new // news : Dog Beach, LLC // https://www.iana.org/domains/root/db/news.html news // next : Next plc // https://www.iana.org/domains/root/db/next.html next // nextdirect : Next plc // https://www.iana.org/domains/root/db/nextdirect.html nextdirect // nexus : Charleston Road Registry Inc. // https://www.iana.org/domains/root/db/nexus.html nexus // nfl : NFL Reg Ops LLC // https://www.iana.org/domains/root/db/nfl.html nfl // ngo : Public Interest Registry // https://www.iana.org/domains/root/db/ngo.html ngo // nhk : Japan Broadcasting Corporation (NHK) // https://www.iana.org/domains/root/db/nhk.html nhk // nico : DWANGO Co., Ltd. // https://www.iana.org/domains/root/db/nico.html nico // nike : NIKE, Inc. // https://www.iana.org/domains/root/db/nike.html nike // nikon : NIKON CORPORATION // https://www.iana.org/domains/root/db/nikon.html nikon // ninja : Dog Beach, LLC // https://www.iana.org/domains/root/db/ninja.html ninja // nissan : NISSAN MOTOR CO., LTD. // https://www.iana.org/domains/root/db/nissan.html nissan // nissay : Nippon Life Insurance Company // https://www.iana.org/domains/root/db/nissay.html nissay // nokia : Nokia Corporation // https://www.iana.org/domains/root/db/nokia.html nokia // norton : Gen Digital Inc. // https://www.iana.org/domains/root/db/norton.html norton // now : Amazon Registry Services, Inc. // https://www.iana.org/domains/root/db/now.html now // nowruz // https://www.iana.org/domains/root/db/nowruz.html nowruz // nowtv : Starbucks (HK) Limited // https://www.iana.org/domains/root/db/nowtv.html nowtv // nra : National Rifle Association of America // https://www.iana.org/domains/root/db/nra.html nra // nrw : Minds + Machines GmbH // https://www.iana.org/domains/root/db/nrw.html nrw // ntt : NIPPON TELEGRAPH AND TELEPHONE CORPORATION // https://www.iana.org/domains/root/db/ntt.html ntt // nyc : The City of New York by and through the New York City Department of Information Technology & Telecommunications // https://www.iana.org/domains/root/db/nyc.html nyc // obi : OBI Group Holding SE & Co. KGaA // https://www.iana.org/domains/root/db/obi.html obi // observer : Fegistry, LLC // https://www.iana.org/domains/root/db/observer.html observer // office : Microsoft Corporation // https://www.iana.org/domains/root/db/office.html office // okinawa : BRregistry, Inc. // https://www.iana.org/domains/root/db/okinawa.html okinawa // olayan : Competrol (Luxembourg) Sarl // https://www.iana.org/domains/root/db/olayan.html olayan // olayangroup : Competrol (Luxembourg) Sarl // https://www.iana.org/domains/root/db/olayangroup.html olayangroup // ollo : Dish DBS Corporation // https://www.iana.org/domains/root/db/ollo.html ollo // omega : The Swatch Group Ltd // https://www.iana.org/domains/root/db/omega.html omega // one : One.com A/S // https://www.iana.org/domains/root/db/one.html one // ong : Public Interest Registry // https://www.iana.org/domains/root/db/ong.html ong // onl : Jolly Host, LLC // https://www.iana.org/domains/root/db/onl.html onl // online : Radix Technologies Inc SEZC // https://www.iana.org/domains/root/db/online.html online // ooo : INFIBEAM AVENUES LIMITED // https://www.iana.org/domains/root/db/ooo.html ooo // open : American Express Travel Related Services Company, Inc. // https://www.iana.org/domains/root/db/open.html open // oracle : Oracle Corporation // https://www.iana.org/domains/root/db/oracle.html oracle // orange : Orange Brand Services Limited // https://www.iana.org/domains/root/db/orange.html orange // organic : Identity Digital Domains Limited // https://www.iana.org/domains/root/db/organic.html organic // origins : The Estée Lauder Companies Inc. // https://www.iana.org/domains/root/db/origins.html origins // osaka : Osaka Registry Co., Ltd. // https://www.iana.org/domains/root/db/osaka.html osaka // otsuka : Otsuka Holdings Co., Ltd. // https://www.iana.org/domains/root/db/otsuka.html otsuka // ott : Dish DBS Corporation // https://www.iana.org/domains/root/db/ott.html ott // ovh : MédiaBC // https://www.iana.org/domains/root/db/ovh.html ovh // page : Charleston Road Registry Inc. // https://www.iana.org/domains/root/db/page.html page // panasonic : Panasonic Holdings Corporation // https://www.iana.org/domains/root/db/panasonic.html panasonic // paris : City of Paris // https://www.iana.org/domains/root/db/paris.html paris // pars // https://www.iana.org/domains/root/db/pars.html pars // partners : Binky Moon, LLC // https://www.iana.org/domains/root/db/partners.html partners // parts : Binky Moon, LLC // https://www.iana.org/domains/root/db/parts.html parts // party : Blue Sky Registry Limited // https://www.iana.org/domains/root/db/party.html party // pay : Amazon Registry Services, Inc. // https://www.iana.org/domains/root/db/pay.html pay // pccw : PCCW Enterprises Limited // https://www.iana.org/domains/root/db/pccw.html pccw // pet : Identity Digital Domains Limited // https://www.iana.org/domains/root/db/pet.html pet // pfizer : Pfizer Inc. // https://www.iana.org/domains/root/db/pfizer.html pfizer // pharmacy : National Association of Boards of Pharmacy // https://www.iana.org/domains/root/db/pharmacy.html pharmacy // phd : Charleston Road Registry Inc. // https://www.iana.org/domains/root/db/phd.html phd // philips : Koninklijke Philips N.V. // https://www.iana.org/domains/root/db/philips.html philips // phone : Dish DBS Corporation // https://www.iana.org/domains/root/db/phone.html phone // photo : Registry Services, LLC // https://www.iana.org/domains/root/db/photo.html photo // photography : Binky Moon, LLC // https://www.iana.org/domains/root/db/photography.html photography // photos : Binky Moon, LLC // https://www.iana.org/domains/root/db/photos.html photos // physio : PhysBiz Pty Ltd // https://www.iana.org/domains/root/db/physio.html physio // pics : XYZ.COM LLC // https://www.iana.org/domains/root/db/pics.html pics // pictet : Banque Pictet & Cie SA // https://www.iana.org/domains/root/db/pictet.html pictet // pictures : Binky Moon, LLC // https://www.iana.org/domains/root/db/pictures.html pictures // pid : Top Level Spectrum, Inc. // https://www.iana.org/domains/root/db/pid.html pid // pin : Amazon Registry Services, Inc. // https://www.iana.org/domains/root/db/pin.html pin // ping : Ping Registry Provider, Inc. // https://www.iana.org/domains/root/db/ping.html ping // pink : Identity Digital Domains Limited // https://www.iana.org/domains/root/db/pink.html pink // pioneer : Pioneer Corporation // https://www.iana.org/domains/root/db/pioneer.html pioneer // pizza : Binky Moon, LLC // https://www.iana.org/domains/root/db/pizza.html pizza // place : Binky Moon, LLC // https://www.iana.org/domains/root/db/place.html place // play : Charleston Road Registry Inc. // https://www.iana.org/domains/root/db/play.html play // playstation : Sony Interactive Entertainment Inc. // https://www.iana.org/domains/root/db/playstation.html playstation // plumbing : Binky Moon, LLC // https://www.iana.org/domains/root/db/plumbing.html plumbing // plus : Binky Moon, LLC // https://www.iana.org/domains/root/db/plus.html plus // pnc : PNC Domain Co., LLC // https://www.iana.org/domains/root/db/pnc.html pnc // pohl : Deutsche Vermögensberatung Aktiengesellschaft DVAG // https://www.iana.org/domains/root/db/pohl.html pohl // poker : Identity Digital Domains Limited // https://www.iana.org/domains/root/db/poker.html poker // politie : Politie Nederland // https://www.iana.org/domains/root/db/politie.html politie // porn : ICM Registry PN LLC // https://www.iana.org/domains/root/db/porn.html porn // praxi : Praxi S.p.A. // https://www.iana.org/domains/root/db/praxi.html praxi // press : Radix Technologies Inc SEZC // https://www.iana.org/domains/root/db/press.html press // prime : Amazon Registry Services, Inc. // https://www.iana.org/domains/root/db/prime.html prime // prod : Charleston Road Registry Inc. // https://www.iana.org/domains/root/db/prod.html prod // productions : Binky Moon, LLC // https://www.iana.org/domains/root/db/productions.html productions // prof : Charleston Road Registry Inc. // https://www.iana.org/domains/root/db/prof.html prof // progressive : Progressive Casualty Insurance Company // https://www.iana.org/domains/root/db/progressive.html progressive // promo : Identity Digital Domains Limited // https://www.iana.org/domains/root/db/promo.html promo // properties : Binky Moon, LLC // https://www.iana.org/domains/root/db/properties.html properties // property : Digital Property Infrastructure Limited // https://www.iana.org/domains/root/db/property.html property // protection : XYZ.COM LLC // https://www.iana.org/domains/root/db/protection.html protection // pru : Prudential Financial, Inc. // https://www.iana.org/domains/root/db/pru.html pru // prudential : Prudential Financial, Inc. // https://www.iana.org/domains/root/db/prudential.html prudential // pub : Dog Beach, LLC // https://www.iana.org/domains/root/db/pub.html pub // pwc : PricewaterhouseCoopers LLP // https://www.iana.org/domains/root/db/pwc.html pwc // qpon : dotQPON LLC // https://www.iana.org/domains/root/db/qpon.html qpon // quebec : PointQuébec Inc // https://www.iana.org/domains/root/db/quebec.html quebec // quest : XYZ.COM LLC // https://www.iana.org/domains/root/db/quest.html quest // racing : Premier Registry Limited // https://www.iana.org/domains/root/db/racing.html racing // radio : Digity, LLC // https://www.iana.org/domains/root/db/radio.html radio // read : Amazon Registry Services, Inc. // https://www.iana.org/domains/root/db/read.html read // realestate : dotRealEstate LLC // https://www.iana.org/domains/root/db/realestate.html realestate // realtor : Real Estate Domains LLC // https://www.iana.org/domains/root/db/realtor.html realtor // realty : Waterford Limited // https://www.iana.org/domains/root/db/realty.html realty // recipes : Binky Moon, LLC // https://www.iana.org/domains/root/db/recipes.html recipes // red : Identity Digital Domains Limited // https://www.iana.org/domains/root/db/red.html red // redumbrella : Travelers TLD, LLC // https://www.iana.org/domains/root/db/redumbrella.html redumbrella // rehab : Dog Beach, LLC // https://www.iana.org/domains/root/db/rehab.html rehab // reise : Binky Moon, LLC // https://www.iana.org/domains/root/db/reise.html reise // reisen : Binky Moon, LLC // https://www.iana.org/domains/root/db/reisen.html reisen // reit : National Association of Real Estate Investment Trusts, Inc. // https://www.iana.org/domains/root/db/reit.html reit // reliance : Reliance Industries Limited // https://www.iana.org/domains/root/db/reliance.html reliance // ren : ZDNS International Limited // https://www.iana.org/domains/root/db/ren.html ren // rent : XYZ.COM LLC // https://www.iana.org/domains/root/db/rent.html rent // rentals : Binky Moon, LLC // https://www.iana.org/domains/root/db/rentals.html rentals // repair : Binky Moon, LLC // https://www.iana.org/domains/root/db/repair.html repair // report : Binky Moon, LLC // https://www.iana.org/domains/root/db/report.html report // republican : Dog Beach, LLC // https://www.iana.org/domains/root/db/republican.html republican // rest : Punto 2012 Sociedad Anonima Promotora de Inversion de Capital Variable // https://www.iana.org/domains/root/db/rest.html rest // restaurant : Binky Moon, LLC // https://www.iana.org/domains/root/db/restaurant.html restaurant // review : dot Review Limited // https://www.iana.org/domains/root/db/review.html review // reviews : Dog Beach, LLC // https://www.iana.org/domains/root/db/reviews.html reviews // rexroth : Robert Bosch GMBH // https://www.iana.org/domains/root/db/rexroth.html rexroth // rich : iRegistry GmbH // https://www.iana.org/domains/root/db/rich.html rich // richardli : Pacific Century Asset Management (HK) Limited // https://www.iana.org/domains/root/db/richardli.html richardli // ricoh : Ricoh Company, Ltd. // https://www.iana.org/domains/root/db/ricoh.html ricoh // ril : Reliance Industries Limited // https://www.iana.org/domains/root/db/ril.html ril // rio : Empresa Municipal de Informática SA - IPLANRIO // https://www.iana.org/domains/root/db/rio.html rio // rip : Dog Beach, LLC // https://www.iana.org/domains/root/db/rip.html rip // rocks : Dog Beach, LLC // https://www.iana.org/domains/root/db/rocks.html rocks // rodeo : Registry Services, LLC // https://www.iana.org/domains/root/db/rodeo.html rodeo // rogers : Rogers Communications Canada Inc. // https://www.iana.org/domains/root/db/rogers.html rogers // room : Amazon Registry Services, Inc. // https://www.iana.org/domains/root/db/room.html room // rsvp : Charleston Road Registry Inc. // https://www.iana.org/domains/root/db/rsvp.html rsvp // rugby : World Rugby Strategic Developments Limited // https://www.iana.org/domains/root/db/rugby.html rugby // ruhr : dotSaarland GmbH // https://www.iana.org/domains/root/db/ruhr.html ruhr // run : Binky Moon, LLC // https://www.iana.org/domains/root/db/run.html run // rwe : RWE AG // https://www.iana.org/domains/root/db/rwe.html rwe // ryukyu : BRregistry, Inc. // https://www.iana.org/domains/root/db/ryukyu.html ryukyu // saarland : dotSaarland GmbH // https://www.iana.org/domains/root/db/saarland.html saarland // safe : Amazon Registry Services, Inc. // https://www.iana.org/domains/root/db/safe.html safe // safety : Safety Registry Services, LLC. // https://www.iana.org/domains/root/db/safety.html safety // sakura : SAKURA Internet Inc. // https://www.iana.org/domains/root/db/sakura.html sakura // sale : Dog Beach, LLC // https://www.iana.org/domains/root/db/sale.html sale // salon : Binky Moon, LLC // https://www.iana.org/domains/root/db/salon.html salon // samsclub : Wal-Mart Stores, Inc. // https://www.iana.org/domains/root/db/samsclub.html samsclub // samsung : SAMSUNG SDS CO., LTD // https://www.iana.org/domains/root/db/samsung.html samsung // sandvik : Sandvik AB // https://www.iana.org/domains/root/db/sandvik.html sandvik // sandvikcoromant : Sandvik AB // https://www.iana.org/domains/root/db/sandvikcoromant.html sandvikcoromant // sanofi : Sanofi // https://www.iana.org/domains/root/db/sanofi.html sanofi // sap : SAP AG // https://www.iana.org/domains/root/db/sap.html sap // sarl : Binky Moon, LLC // https://www.iana.org/domains/root/db/sarl.html sarl // sas : Research IP LLC // https://www.iana.org/domains/root/db/sas.html sas // save : Amazon Registry Services, Inc. // https://www.iana.org/domains/root/db/save.html save // saxo : Saxo Bank A/S // https://www.iana.org/domains/root/db/saxo.html saxo // sbi : STATE BANK OF INDIA // https://www.iana.org/domains/root/db/sbi.html sbi // sbs : ShortDot SA // https://www.iana.org/domains/root/db/sbs.html sbs // scb : The Siam Commercial Bank Public Company Limited ("SCB") // https://www.iana.org/domains/root/db/scb.html scb // schaeffler : Schaeffler Technologies AG & Co. KG // https://www.iana.org/domains/root/db/schaeffler.html schaeffler // schmidt : SCHMIDT GROUPE S.A.S. // https://www.iana.org/domains/root/db/schmidt.html schmidt // scholarships : Scholarships.com, LLC // https://www.iana.org/domains/root/db/scholarships.html scholarships // school : Binky Moon, LLC // https://www.iana.org/domains/root/db/school.html school // schule : Binky Moon, LLC // https://www.iana.org/domains/root/db/schule.html schule // schwarz : Schwarz Domains und Services GmbH & Co. KG // https://www.iana.org/domains/root/db/schwarz.html schwarz // science : dot Science Limited // https://www.iana.org/domains/root/db/science.html science // scot : Dot Scot Registry Limited // https://www.iana.org/domains/root/db/scot.html scot // search : Charleston Road Registry Inc. // https://www.iana.org/domains/root/db/search.html search // seat : SEAT, S.A. (Sociedad Unipersonal) // https://www.iana.org/domains/root/db/seat.html seat // secure : Amazon Registry Services, Inc. // https://www.iana.org/domains/root/db/secure.html secure // security : XYZ.COM LLC // https://www.iana.org/domains/root/db/security.html security // seek : Seek Limited // https://www.iana.org/domains/root/db/seek.html seek // select : Registry Services, LLC // https://www.iana.org/domains/root/db/select.html select // sener : Sener Ingeniería y Sistemas, S.A. // https://www.iana.org/domains/root/db/sener.html sener // services : Binky Moon, LLC // https://www.iana.org/domains/root/db/services.html services // seven : Seven West Media Ltd // https://www.iana.org/domains/root/db/seven.html seven // sew : SEW-EURODRIVE GmbH & Co KG // https://www.iana.org/domains/root/db/sew.html sew // sex : ICM Registry SX LLC // https://www.iana.org/domains/root/db/sex.html sex // sexy : Internet Naming Company LLC // https://www.iana.org/domains/root/db/sexy.html sexy // sfr : Societe Francaise du Radiotelephone - SFR // https://www.iana.org/domains/root/db/sfr.html sfr // shangrila : Shangriâ€La International Hotel Management Limited // https://www.iana.org/domains/root/db/shangrila.html shangrila // sharp : Sharp Corporation // https://www.iana.org/domains/root/db/sharp.html sharp // shell : Shell Information Technology International Inc // https://www.iana.org/domains/root/db/shell.html shell // shia // https://www.iana.org/domains/root/db/shia.html shia // shiksha : Identity Digital Domains Limited // https://www.iana.org/domains/root/db/shiksha.html shiksha // shoes : Binky Moon, LLC // https://www.iana.org/domains/root/db/shoes.html shoes // shop : GMO Registry, Inc. // https://www.iana.org/domains/root/db/shop.html shop // shopping : Binky Moon, LLC // https://www.iana.org/domains/root/db/shopping.html shopping // shouji : Beijing Qihu Keji Co., Ltd. // https://www.iana.org/domains/root/db/shouji.html shouji // show : Binky Moon, LLC // https://www.iana.org/domains/root/db/show.html show // silk : Amazon Registry Services, Inc. // https://www.iana.org/domains/root/db/silk.html silk // sina : Sina Corporation // https://www.iana.org/domains/root/db/sina.html sina // singles : Binky Moon, LLC // https://www.iana.org/domains/root/db/singles.html singles // site : Radix Technologies Inc SEZC // https://www.iana.org/domains/root/db/site.html site // ski : Identity Digital Domains Limited // https://www.iana.org/domains/root/db/ski.html ski // skin : XYZ.COM LLC // https://www.iana.org/domains/root/db/skin.html skin // sky : Sky UK Limited // https://www.iana.org/domains/root/db/sky.html sky // skype : Microsoft Corporation // https://www.iana.org/domains/root/db/skype.html skype // sling : DISH Technologies L.L.C. // https://www.iana.org/domains/root/db/sling.html sling // smart : Smart Communications, Inc. (SMART) // https://www.iana.org/domains/root/db/smart.html smart // smile : Amazon Registry Services, Inc. // https://www.iana.org/domains/root/db/smile.html smile // sncf : Société Nationale SNCF // https://www.iana.org/domains/root/db/sncf.html sncf // soccer : Binky Moon, LLC // https://www.iana.org/domains/root/db/soccer.html soccer // social : Dog Beach, LLC // https://www.iana.org/domains/root/db/social.html social // softbank : SoftBank Group Corp. // https://www.iana.org/domains/root/db/softbank.html softbank // software : Dog Beach, LLC // https://www.iana.org/domains/root/db/software.html software // sohu : Sohu.com Limited // https://www.iana.org/domains/root/db/sohu.html sohu // solar : Binky Moon, LLC // https://www.iana.org/domains/root/db/solar.html solar // solutions : Binky Moon, LLC // https://www.iana.org/domains/root/db/solutions.html solutions // song : Amazon Registry Services, Inc. // https://www.iana.org/domains/root/db/song.html song // sony : Sony Group Corporation // https://www.iana.org/domains/root/db/sony.html sony // soy : Charleston Road Registry Inc. // https://www.iana.org/domains/root/db/soy.html soy // spa : Asia Spa and Wellness Promotion Council Limited // https://www.iana.org/domains/root/db/spa.html spa // space : Radix Technologies Inc SEZC // https://www.iana.org/domains/root/db/space.html space // sport : SportAccord // https://www.iana.org/domains/root/db/sport.html sport // spot : Amazon Registry Services, Inc. // https://www.iana.org/domains/root/db/spot.html spot // srl : InterNetX, Corp // https://www.iana.org/domains/root/db/srl.html srl // stada : STADA Arzneimittel AG // https://www.iana.org/domains/root/db/stada.html stada // staples : Staples, Inc. // https://www.iana.org/domains/root/db/staples.html staples // star : Star India Private Limited // https://www.iana.org/domains/root/db/star.html star // statebank : STATE BANK OF INDIA // https://www.iana.org/domains/root/db/statebank.html statebank // statefarm : State Farm Mutual Automobile Insurance Company // https://www.iana.org/domains/root/db/statefarm.html statefarm // stc : Saudi Telecom Company // https://www.iana.org/domains/root/db/stc.html stc // stcgroup : Saudi Telecom Company // https://www.iana.org/domains/root/db/stcgroup.html stcgroup // stockholm : Stockholms kommun // https://www.iana.org/domains/root/db/stockholm.html stockholm // storage : XYZ.COM LLC // https://www.iana.org/domains/root/db/storage.html storage // store : Radix Technologies Inc SEZC // https://www.iana.org/domains/root/db/store.html store // stream : dot Stream Limited // https://www.iana.org/domains/root/db/stream.html stream // studio : Dog Beach, LLC // https://www.iana.org/domains/root/db/studio.html studio // study : Registry Services, LLC // https://www.iana.org/domains/root/db/study.html study // style : Binky Moon, LLC // https://www.iana.org/domains/root/db/style.html style // sucks : Vox Populi Registry Ltd. // https://www.iana.org/domains/root/db/sucks.html sucks // supplies : Binky Moon, LLC // https://www.iana.org/domains/root/db/supplies.html supplies // supply : Binky Moon, LLC // https://www.iana.org/domains/root/db/supply.html supply // support : Binky Moon, LLC // https://www.iana.org/domains/root/db/support.html support // surf : Registry Services, LLC // https://www.iana.org/domains/root/db/surf.html surf // surgery : Binky Moon, LLC // https://www.iana.org/domains/root/db/surgery.html surgery // suzuki : SUZUKI MOTOR CORPORATION // https://www.iana.org/domains/root/db/suzuki.html suzuki // swatch : The Swatch Group Ltd // https://www.iana.org/domains/root/db/swatch.html swatch // swiss : Swiss Confederation // https://www.iana.org/domains/root/db/swiss.html swiss // sydney : State of New South Wales, Department of Premier and Cabinet // https://www.iana.org/domains/root/db/sydney.html sydney // systems : Binky Moon, LLC // https://www.iana.org/domains/root/db/systems.html systems // tab : Tabcorp Holdings Limited // https://www.iana.org/domains/root/db/tab.html tab // taipei : Taipei City Government // https://www.iana.org/domains/root/db/taipei.html taipei // talk : Amazon Registry Services, Inc. // https://www.iana.org/domains/root/db/talk.html talk // taobao : Alibaba Group Holding Limited // https://www.iana.org/domains/root/db/taobao.html taobao // target : Target Domain Holdings, LLC // https://www.iana.org/domains/root/db/target.html target // tatamotors : Tata Motors Ltd // https://www.iana.org/domains/root/db/tatamotors.html tatamotors // tatar : Limited Liability Company "Coordination Center of Regional Domain of Tatarstan Republic" // https://www.iana.org/domains/root/db/tatar.html tatar // tattoo : Registry Services, LLC // https://www.iana.org/domains/root/db/tattoo.html tattoo // tax : Binky Moon, LLC // https://www.iana.org/domains/root/db/tax.html tax // taxi : Binky Moon, LLC // https://www.iana.org/domains/root/db/taxi.html taxi // tci // https://www.iana.org/domains/root/db/tci.html tci // tdk : TDK Corporation // https://www.iana.org/domains/root/db/tdk.html tdk // team : Binky Moon, LLC // https://www.iana.org/domains/root/db/team.html team // tech : Radix Technologies Inc SEZC // https://www.iana.org/domains/root/db/tech.html tech // technology : Binky Moon, LLC // https://www.iana.org/domains/root/db/technology.html technology // temasek : Temasek Holdings (Private) Limited // https://www.iana.org/domains/root/db/temasek.html temasek // tennis : Binky Moon, LLC // https://www.iana.org/domains/root/db/tennis.html tennis // teva : Teva Pharmaceutical Industries Limited // https://www.iana.org/domains/root/db/teva.html teva // thd : Home Depot Product Authority, LLC // https://www.iana.org/domains/root/db/thd.html thd // theater : Binky Moon, LLC // https://www.iana.org/domains/root/db/theater.html theater // theatre : XYZ.COM LLC // https://www.iana.org/domains/root/db/theatre.html theatre // tiaa : Teachers Insurance and Annuity Association of America // https://www.iana.org/domains/root/db/tiaa.html tiaa // tickets : XYZ.COM LLC // https://www.iana.org/domains/root/db/tickets.html tickets // tienda : Binky Moon, LLC // https://www.iana.org/domains/root/db/tienda.html tienda // tips : Binky Moon, LLC // https://www.iana.org/domains/root/db/tips.html tips // tires : Binky Moon, LLC // https://www.iana.org/domains/root/db/tires.html tires // tirol : punkt Tirol GmbH // https://www.iana.org/domains/root/db/tirol.html tirol // tjmaxx : The TJX Companies, Inc. // https://www.iana.org/domains/root/db/tjmaxx.html tjmaxx // tjx : The TJX Companies, Inc. // https://www.iana.org/domains/root/db/tjx.html tjx // tkmaxx : The TJX Companies, Inc. // https://www.iana.org/domains/root/db/tkmaxx.html tkmaxx // tmall : Alibaba Group Holding Limited // https://www.iana.org/domains/root/db/tmall.html tmall // today : Binky Moon, LLC // https://www.iana.org/domains/root/db/today.html today // tokyo : GMO Registry, Inc. // https://www.iana.org/domains/root/db/tokyo.html tokyo // tools : Binky Moon, LLC // https://www.iana.org/domains/root/db/tools.html tools // top : Hong Kong Zhongze International Limited // https://www.iana.org/domains/root/db/top.html top // toray : Toray Industries, Inc. // https://www.iana.org/domains/root/db/toray.html toray // toshiba : TOSHIBA Corporation // https://www.iana.org/domains/root/db/toshiba.html toshiba // total : TotalEnergies SE // https://www.iana.org/domains/root/db/total.html total // tours : Binky Moon, LLC // https://www.iana.org/domains/root/db/tours.html tours // town : Binky Moon, LLC // https://www.iana.org/domains/root/db/town.html town // toyota : TOYOTA MOTOR CORPORATION // https://www.iana.org/domains/root/db/toyota.html toyota // toys : Binky Moon, LLC // https://www.iana.org/domains/root/db/toys.html toys // trade : Elite Registry Limited // https://www.iana.org/domains/root/db/trade.html trade // trading : Dog Beach, LLC // https://www.iana.org/domains/root/db/trading.html trading // training : Binky Moon, LLC // https://www.iana.org/domains/root/db/training.html training // travel : Dog Beach, LLC // https://www.iana.org/domains/root/db/travel.html travel // travelers : Travelers TLD, LLC // https://www.iana.org/domains/root/db/travelers.html travelers // travelersinsurance : Travelers TLD, LLC // https://www.iana.org/domains/root/db/travelersinsurance.html travelersinsurance // trust : Internet Naming Company LLC // https://www.iana.org/domains/root/db/trust.html trust // trv : Travelers TLD, LLC // https://www.iana.org/domains/root/db/trv.html trv // tube : Latin American Telecom LLC // https://www.iana.org/domains/root/db/tube.html tube // tui : TUI AG // https://www.iana.org/domains/root/db/tui.html tui // tunes : Amazon Registry Services, Inc. // https://www.iana.org/domains/root/db/tunes.html tunes // tushu : Amazon Registry Services, Inc. // https://www.iana.org/domains/root/db/tushu.html tushu // tvs : T V SUNDRAM IYENGAR & SONS LIMITED // https://www.iana.org/domains/root/db/tvs.html tvs // ubank : National Australia Bank Limited // https://www.iana.org/domains/root/db/ubank.html ubank // ubs : UBS AG // https://www.iana.org/domains/root/db/ubs.html ubs // unicom : China United Network Communications Corporation Limited // https://www.iana.org/domains/root/db/unicom.html unicom // university : Binky Moon, LLC // https://www.iana.org/domains/root/db/university.html university // uno : Radix Technologies Inc SEZC // https://www.iana.org/domains/root/db/uno.html uno // uol : UBN INTERNET LTDA. // https://www.iana.org/domains/root/db/uol.html uol // ups : UPS Market Driver, Inc. // https://www.iana.org/domains/root/db/ups.html ups // vacations : Binky Moon, LLC // https://www.iana.org/domains/root/db/vacations.html vacations // vana : D3 Registry LLC // https://www.iana.org/domains/root/db/vana.html vana // vanguard : The Vanguard Group, Inc. // https://www.iana.org/domains/root/db/vanguard.html vanguard // vegas : Dot Vegas, Inc. // https://www.iana.org/domains/root/db/vegas.html vegas // ventures : Binky Moon, LLC // https://www.iana.org/domains/root/db/ventures.html ventures // verisign : VeriSign, Inc. // https://www.iana.org/domains/root/db/verisign.html verisign // versicherung : tldbox GmbH // https://www.iana.org/domains/root/db/versicherung.html versicherung // vet : Dog Beach, LLC // https://www.iana.org/domains/root/db/vet.html vet // viajes : Binky Moon, LLC // https://www.iana.org/domains/root/db/viajes.html viajes // video : Dog Beach, LLC // https://www.iana.org/domains/root/db/video.html video // vig : VIENNA INSURANCE GROUP AG Wiener Versicherung Gruppe // https://www.iana.org/domains/root/db/vig.html vig // viking : Viking River Cruises (Bermuda) Ltd. // https://www.iana.org/domains/root/db/viking.html viking // villas : Binky Moon, LLC // https://www.iana.org/domains/root/db/villas.html villas // vin : Binky Moon, LLC // https://www.iana.org/domains/root/db/vin.html vin // vip : Registry Services, LLC // https://www.iana.org/domains/root/db/vip.html vip // virgin : Virgin Enterprises Limited // https://www.iana.org/domains/root/db/virgin.html virgin // visa : Visa Worldwide Pte. Limited // https://www.iana.org/domains/root/db/visa.html visa // vision : Binky Moon, LLC // https://www.iana.org/domains/root/db/vision.html vision // viva : Saudi Telecom Company // https://www.iana.org/domains/root/db/viva.html viva // vivo : Telefonica Brasil S.A. // https://www.iana.org/domains/root/db/vivo.html vivo // vlaanderen : DNS.be vzw // https://www.iana.org/domains/root/db/vlaanderen.html vlaanderen // vodka : Registry Services, LLC // https://www.iana.org/domains/root/db/vodka.html vodka // volvo : Volvo Holding Sverige Aktiebolag // https://www.iana.org/domains/root/db/volvo.html volvo // vote : Monolith Registry LLC // https://www.iana.org/domains/root/db/vote.html vote // voting : Valuetainment Corp. // https://www.iana.org/domains/root/db/voting.html voting // voto : Monolith Registry LLC // https://www.iana.org/domains/root/db/voto.html voto // voyage : Binky Moon, LLC // https://www.iana.org/domains/root/db/voyage.html voyage // wales : Nominet UK // https://www.iana.org/domains/root/db/wales.html wales // walmart : Wal-Mart Stores, Inc. // https://www.iana.org/domains/root/db/walmart.html walmart // walter : Sandvik AB // https://www.iana.org/domains/root/db/walter.html walter // wang : Zodiac Wang Limited // https://www.iana.org/domains/root/db/wang.html wang // wanggou : Amazon Registry Services, Inc. // https://www.iana.org/domains/root/db/wanggou.html wanggou // watch : Binky Moon, LLC // https://www.iana.org/domains/root/db/watch.html watch // watches : Identity Digital Domains Limited // https://www.iana.org/domains/root/db/watches.html watches // weather : The Weather Company, LLC // https://www.iana.org/domains/root/db/weather.html weather // weatherchannel : The Weather Company, LLC // https://www.iana.org/domains/root/db/weatherchannel.html weatherchannel // webcam : dot Webcam Limited // https://www.iana.org/domains/root/db/webcam.html webcam // weber : Saint-Gobain Weber SA // https://www.iana.org/domains/root/db/weber.html weber // website : Radix Technologies Inc SEZC // https://www.iana.org/domains/root/db/website.html website // wed // https://www.iana.org/domains/root/db/wed.html wed // wedding : Registry Services, LLC // https://www.iana.org/domains/root/db/wedding.html wedding // weibo : Sina Corporation // https://www.iana.org/domains/root/db/weibo.html weibo // weir : Weir Group IP Limited // https://www.iana.org/domains/root/db/weir.html weir // whoswho : Who's Who Registry // https://www.iana.org/domains/root/db/whoswho.html whoswho // wien : domainworx Service & Management GmbH // https://www.iana.org/domains/root/db/wien.html wien // wiki : Registry Services, LLC // https://www.iana.org/domains/root/db/wiki.html wiki // williamhill : William Hill Organization Limited // https://www.iana.org/domains/root/db/williamhill.html williamhill // win : First Registry Limited // https://www.iana.org/domains/root/db/win.html win // windows : Microsoft Corporation // https://www.iana.org/domains/root/db/windows.html windows // wine : Binky Moon, LLC // https://www.iana.org/domains/root/db/wine.html wine // winners : The TJX Companies, Inc. // https://www.iana.org/domains/root/db/winners.html winners // wme : William Morris Endeavor Entertainment, LLC // https://www.iana.org/domains/root/db/wme.html wme // woodside : Woodside Petroleum Limited // https://www.iana.org/domains/root/db/woodside.html woodside // work : Registry Services, LLC // https://www.iana.org/domains/root/db/work.html work // works : Binky Moon, LLC // https://www.iana.org/domains/root/db/works.html works // world : Binky Moon, LLC // https://www.iana.org/domains/root/db/world.html world // wow : Amazon Registry Services, Inc. // https://www.iana.org/domains/root/db/wow.html wow // wtc : World Trade Centers Association, Inc. // https://www.iana.org/domains/root/db/wtc.html wtc // wtf : Binky Moon, LLC // https://www.iana.org/domains/root/db/wtf.html wtf // xbox : Microsoft Corporation // https://www.iana.org/domains/root/db/xbox.html xbox // xerox : Xerox DNHC LLC // https://www.iana.org/domains/root/db/xerox.html xerox // xihuan : Beijing Qihu Keji Co., Ltd. // https://www.iana.org/domains/root/db/xihuan.html xihuan // xin : Elegant Leader Limited // https://www.iana.org/domains/root/db/xin.html xin // xn--11b4c3d : VeriSign Sarl // https://www.iana.org/domains/root/db/xn--11b4c3d.html कॉम // xn--1ck2e1b : Amazon Registry Services, Inc. // https://www.iana.org/domains/root/db/xn--1ck2e1b.html セール // xn--1qqw23a : Guangzhou YU Wei Information Technology Co., Ltd. // https://www.iana.org/domains/root/db/xn--1qqw23a.html 佛山 // xn--30rr7y : Excellent First Limited // https://www.iana.org/domains/root/db/xn--30rr7y.html 慈善 // xn--3bst00m : Eagle Horizon Limited // https://www.iana.org/domains/root/db/xn--3bst00m.html 集团 // xn--3ds443g : Beijing TLD Registry Technology Limited // https://www.iana.org/domains/root/db/xn--3ds443g.html 在线 // xn--3pxu8k : VeriSign Sarl // https://www.iana.org/domains/root/db/xn--3pxu8k.html 点看 // xn--42c2d9a : VeriSign Sarl // https://www.iana.org/domains/root/db/xn--42c2d9a.html คอม // xn--45q11c : Zodiac Gemini Ltd // https://www.iana.org/domains/root/db/xn--45q11c.html å…«å¦ // xn--4gbrim : Helium TLDs Ltd // https://www.iana.org/domains/root/db/xn--4gbrim.html موقع // xn--55qw42g : China Organizational Name Administration Center // https://www.iana.org/domains/root/db/xn--55qw42g.html 公益 // xn--55qx5d : China Internet Network Information Center (CNNIC) // https://www.iana.org/domains/root/db/xn--55qx5d.html å…¬å¸ // xn--5su34j936bgsg : Shangriâ€La International Hotel Management Limited // https://www.iana.org/domains/root/db/xn--5su34j936bgsg.html 香格里拉 // xn--5tzm5g : Global Website TLD Asia Limited // https://www.iana.org/domains/root/db/xn--5tzm5g.html 网站 // xn--6frz82g : Identity Digital Domains Limited // https://www.iana.org/domains/root/db/xn--6frz82g.html 移动 // xn--6qq986b3xl : Tycoon Treasure Limited // https://www.iana.org/domains/root/db/xn--6qq986b3xl.html 我爱你 // xn--80adxhks : Foundation for Assistance for Internet Technologies and Infrastructure Development (FAITID) // https://www.iana.org/domains/root/db/xn--80adxhks.html моÑква // xn--80aqecdr1a : Pontificium Consilium de Comunicationibus Socialibus (PCCS) (Pontifical Council for Social Communication) // https://www.iana.org/domains/root/db/xn--80aqecdr1a.html католик // xn--80asehdb : CORE Association // https://www.iana.org/domains/root/db/xn--80asehdb.html онлайн // xn--80aswg : CORE Association // https://www.iana.org/domains/root/db/xn--80aswg.html Ñайт // xn--8y0a063a : China United Network Communications Corporation Limited // https://www.iana.org/domains/root/db/xn--8y0a063a.html è”通 // xn--9dbq2a : VeriSign Sarl // https://www.iana.org/domains/root/db/xn--9dbq2a.html ×§×•× // xn--9et52u : RISE VICTORY LIMITED // https://www.iana.org/domains/root/db/xn--9et52u.html æ—¶å°š // xn--9krt00a : Sina Corporation // https://www.iana.org/domains/root/db/xn--9krt00a.html å¾®åš // xn--b4w605ferd : Temasek Holdings (Private) Limited // https://www.iana.org/domains/root/db/xn--b4w605ferd.html 淡马锡 // xn--bck1b9a5dre4c : Amazon Registry Services, Inc. // https://www.iana.org/domains/root/db/xn--bck1b9a5dre4c.html ファッション // xn--c1avg : Public Interest Registry // https://www.iana.org/domains/root/db/xn--c1avg.html орг // xn--c2br7g : VeriSign Sarl // https://www.iana.org/domains/root/db/xn--c2br7g.html नेट // xn--cck2b3b : Amazon Registry Services, Inc. // https://www.iana.org/domains/root/db/xn--cck2b3b.html ストア // xn--cckwcxetd : Amazon Registry Services, Inc. // https://www.iana.org/domains/root/db/xn--cckwcxetd.html アマゾン // xn--cg4bki : SAMSUNG SDS CO., LTD // https://www.iana.org/domains/root/db/xn--cg4bki.html 삼성 // xn--czr694b : Internet DotTrademark Organisation Limited // https://www.iana.org/domains/root/db/xn--czr694b.html 商标 // xn--czrs0t : Binky Moon, LLC // https://www.iana.org/domains/root/db/xn--czrs0t.html 商店 // xn--czru2d : Zodiac Aquarius Limited // https://www.iana.org/domains/root/db/xn--czru2d.html 商城 // xn--d1acj3b : The Foundation for Network Initiatives “The Smart Internet†// https://www.iana.org/domains/root/db/xn--d1acj3b.html дети // xn--eckvdtc9d : Amazon Registry Services, Inc. // https://www.iana.org/domains/root/db/xn--eckvdtc9d.html ãƒã‚¤ãƒ³ãƒˆ // xn--efvy88h : Guangzhou YU Wei Information Technology Co., Ltd. // https://www.iana.org/domains/root/db/xn--efvy88h.html æ–°é—» // xn--fct429k : Amazon Registry Services, Inc. // https://www.iana.org/domains/root/db/xn--fct429k.html å®¶é›» // xn--fhbei : VeriSign Sarl // https://www.iana.org/domains/root/db/xn--fhbei.html كوم // xn--fiq228c5hs : Beijing TLD Registry Technology Limited // https://www.iana.org/domains/root/db/xn--fiq228c5hs.html 中文网 // xn--fiq64b : CITIC Group Corporation // https://www.iana.org/domains/root/db/xn--fiq64b.html 中信 // xn--fjq720a : Binky Moon, LLC // https://www.iana.org/domains/root/db/xn--fjq720a.html å¨±ä¹ // xn--flw351e : Charleston Road Registry Inc. // https://www.iana.org/domains/root/db/xn--flw351e.html è°·æ­Œ // xn--fzys8d69uvgm : PCCW Enterprises Limited // https://www.iana.org/domains/root/db/xn--fzys8d69uvgm.html 電訊盈科 // xn--g2xx48c : Nawang Heli(Xiamen) Network Service Co., LTD. // https://www.iana.org/domains/root/db/xn--g2xx48c.html 购物 // xn--gckr3f0f : Amazon Registry Services, Inc. // https://www.iana.org/domains/root/db/xn--gckr3f0f.html クラウド // xn--gk3at1e : Amazon Registry Services, Inc. // https://www.iana.org/domains/root/db/xn--gk3at1e.html 通販 // xn--hxt814e : Zodiac Taurus Limited // https://www.iana.org/domains/root/db/xn--hxt814e.html 网店 // xn--i1b6b1a6a2e : Public Interest Registry // https://www.iana.org/domains/root/db/xn--i1b6b1a6a2e.html संगठन // xn--imr513n : Internet DotTrademark Organisation Limited // https://www.iana.org/domains/root/db/xn--imr513n.html é¤åŽ… // xn--io0a7i : China Internet Network Information Center (CNNIC) // https://www.iana.org/domains/root/db/xn--io0a7i.html 网络 // xn--j1aef : VeriSign Sarl // https://www.iana.org/domains/root/db/xn--j1aef.html ком // xn--jlq480n2rg : Amazon Registry Services, Inc. // https://www.iana.org/domains/root/db/xn--jlq480n2rg.html 亚马逊 // xn--jvr189m : Amazon Registry Services, Inc. // https://www.iana.org/domains/root/db/xn--jvr189m.html é£Ÿå“ // xn--kcrx77d1x4a : Koninklijke Philips N.V. // https://www.iana.org/domains/root/db/xn--kcrx77d1x4a.html 飞利浦 // xn--kput3i : Beijing RITT-Net Technology Development Co., Ltd // https://www.iana.org/domains/root/db/xn--kput3i.html 手机 // xn--mgba3a3ejt : Aramco Services Company // https://www.iana.org/domains/root/db/xn--mgba3a3ejt.html ارامكو // xn--mgba7c0bbn0a : Competrol (Luxembourg) Sarl // https://www.iana.org/domains/root/db/xn--mgba7c0bbn0a.html العليان // xn--mgbab2bd : CORE Association // https://www.iana.org/domains/root/db/xn--mgbab2bd.html بازار // xn--mgbca7dzdo : Abu Dhabi Systems and Information Centre // https://www.iana.org/domains/root/db/xn--mgbca7dzdo.html ابوظبي // xn--mgbi4ecexp : Pontificium Consilium de Comunicationibus Socialibus (PCCS) (Pontifical Council for Social Communication) // https://www.iana.org/domains/root/db/xn--mgbi4ecexp.html كاثوليك // xn--mgbt3dhd // https://www.iana.org/domains/root/db/xn--mgbt3dhd.html همراه // xn--mk1bu44c : VeriSign Sarl // https://www.iana.org/domains/root/db/xn--mk1bu44c.html ë‹·ì»´ // xn--mxtq1m : Net-Chinese Co., Ltd. // https://www.iana.org/domains/root/db/xn--mxtq1m.html 政府 // xn--ngbc5azd : International Domain Registry Pty. Ltd. // https://www.iana.org/domains/root/db/xn--ngbc5azd.html شبكة // xn--ngbe9e0a : Kuwait Finance House // https://www.iana.org/domains/root/db/xn--ngbe9e0a.html بيتك // xn--ngbrx : League of Arab States // https://www.iana.org/domains/root/db/xn--ngbrx.html عرب // xn--nqv7f : Public Interest Registry // https://www.iana.org/domains/root/db/xn--nqv7f.html 机构 // xn--nqv7fs00ema : Public Interest Registry // https://www.iana.org/domains/root/db/xn--nqv7fs00ema.html 组织机构 // xn--nyqy26a : Stable Tone Limited // https://www.iana.org/domains/root/db/xn--nyqy26a.html å¥åº· // xn--otu796d : Jiang Yu Liang Cai Technology Company Limited // https://www.iana.org/domains/root/db/xn--otu796d.html æ‹›è˜ // xn--p1acf : Rusnames Limited // https://www.iana.org/domains/root/db/xn--p1acf.html Ñ€ÑƒÑ // xn--pssy2u : VeriSign Sarl // https://www.iana.org/domains/root/db/xn--pssy2u.html 大拿 // xn--q9jyb4c : Charleston Road Registry Inc. // https://www.iana.org/domains/root/db/xn--q9jyb4c.html ã¿ã‚“㪠// xn--qcka1pmc : Charleston Road Registry Inc. // https://www.iana.org/domains/root/db/xn--qcka1pmc.html グーグル // xn--rhqv96g : Stable Tone Limited // https://www.iana.org/domains/root/db/xn--rhqv96g.html 世界 // xn--rovu88b : Amazon Registry Services, Inc. // https://www.iana.org/domains/root/db/xn--rovu88b.html æ›¸ç± // xn--ses554g : KNET Co., Ltd. // https://www.iana.org/domains/root/db/xn--ses554g.html ç½‘å€ // xn--t60b56a : VeriSign Sarl // https://www.iana.org/domains/root/db/xn--t60b56a.html ë‹·ë„· // xn--tckwe : VeriSign Sarl // https://www.iana.org/domains/root/db/xn--tckwe.html コム // xn--tiq49xqyj : Pontificium Consilium de Comunicationibus Socialibus (PCCS) (Pontifical Council for Social Communication) // https://www.iana.org/domains/root/db/xn--tiq49xqyj.html 天主教 // xn--unup4y : Binky Moon, LLC // https://www.iana.org/domains/root/db/xn--unup4y.html æ¸¸æˆ // xn--vermgensberater-ctb : Deutsche Vermögensberatung Aktiengesellschaft DVAG // https://www.iana.org/domains/root/db/xn--vermgensberater-ctb.html vermögensberater // xn--vermgensberatung-pwb : Deutsche Vermögensberatung Aktiengesellschaft DVAG // https://www.iana.org/domains/root/db/xn--vermgensberatung-pwb.html vermögensberatung // xn--vhquv : Binky Moon, LLC // https://www.iana.org/domains/root/db/xn--vhquv.html ä¼ä¸š // xn--vuq861b : Beijing Tele-info Technology Co., Ltd. // https://www.iana.org/domains/root/db/xn--vuq861b.html ä¿¡æ¯ // xn--w4r85el8fhu5dnra : Kerry Trading Co. Limited // https://www.iana.org/domains/root/db/xn--w4r85el8fhu5dnra.html 嘉里大酒店 // xn--w4rs40l : Kerry Trading Co. Limited // https://www.iana.org/domains/root/db/xn--w4rs40l.html 嘉里 // xn--xhq521b : Guangzhou YU Wei Information Technology Co., Ltd. // https://www.iana.org/domains/root/db/xn--xhq521b.html 广东 // xn--zfr164b : China Organizational Name Administration Center // https://www.iana.org/domains/root/db/xn--zfr164b.html 政务 // xyz : XYZ.COM LLC // https://www.iana.org/domains/root/db/xyz.html xyz // yachts : XYZ.COM LLC // https://www.iana.org/domains/root/db/yachts.html yachts // yahoo : Yahoo Inc. // https://www.iana.org/domains/root/db/yahoo.html yahoo // yamaxun : Amazon Registry Services, Inc. // https://www.iana.org/domains/root/db/yamaxun.html yamaxun // yandex : YANDEX, LLC // https://www.iana.org/domains/root/db/yandex.html yandex // yodobashi : YODOBASHI CAMERA CO.,LTD. // https://www.iana.org/domains/root/db/yodobashi.html yodobashi // yoga : Registry Services, LLC // https://www.iana.org/domains/root/db/yoga.html yoga // yokohama : GMO Registry, Inc. // https://www.iana.org/domains/root/db/yokohama.html yokohama // you : Amazon Registry Services, Inc. // https://www.iana.org/domains/root/db/you.html you // youtube : Charleston Road Registry Inc. // https://www.iana.org/domains/root/db/youtube.html youtube // yun : Beijing Qihu Keji Co., Ltd. // https://www.iana.org/domains/root/db/yun.html yun // zappos : Amazon Registry Services, Inc. // https://www.iana.org/domains/root/db/zappos.html zappos // zara : Industria de Diseño Textil, S.A. (INDITEX, S.A.) // https://www.iana.org/domains/root/db/zara.html zara // zero : Amazon Registry Services, Inc. // https://www.iana.org/domains/root/db/zero.html zero // zip : Charleston Road Registry Inc. // https://www.iana.org/domains/root/db/zip.html zip // zone : Binky Moon, LLC // https://www.iana.org/domains/root/db/zone.html zone // zuerich : Kanton Zürich (Canton of Zurich) // https://www.iana.org/domains/root/db/zuerich.html zuerich // ===END ICANN DOMAINS=== // ===BEGIN PRIVATE DOMAINS=== // (Note: these are in alphabetical order by company name) // .KRD : https://nic.krd co.krd edu.krd // .pl domains (grandfathered) art.pl gliwice.pl krakow.pl poznan.pl wroc.pl zakopane.pl // 1GB LLC : https://www.1gb.ua/ // Submitted by 1GB LLC cc.ua inf.ua ltd.ua // 611 blockchain domain name system : https://sixone.one/ 611.to // A2 Hosting // Submitted by Tyler Hall a2hosted.com cpserver.com // Acorn Labs : https://acorn.io // Submitted by Craig Jellick *.on-acorn.io // ActiveTrail : https://www.activetrail.biz/ // Submitted by Ofer Kalaora activetrail.biz // Adaptable.io : https://adaptable.io // Submitted by Mark Terrel adaptable.app // addr.tools : https://addr.tools/ // Submitted by Brian Shea myaddr.dev myaddr.io dyn.addr.tools myaddr.tools // Adobe : https://www.adobe.com/ // Submitted by Ian Boston and Lars Trieloff adobeaemcloud.com *.dev.adobeaemcloud.com aem.live hlx.live adobeaemcloud.net aem.network aem.page hlx.page aem.reviews // Adobe Developer Platform : https://developer.adobe.com // Submitted by Jesse MacFadyen adobeio-static.net adobeioruntime.net // Africa.com Web Solutions Ltd : https://registry.africa.com // Submitted by Gavin Brown africa.com // AgentbaseAI Inc. : https://assistant-ui.com // Submitted by Simon Farshid *.auiusercontent.com // Agnat sp. z o.o. : https://domena.pl // Submitted by Przemyslaw Plewa beep.pl // Aiven : https://aiven.io/ // Submitted by Aiven Security Team aiven.app aivencloud.com // Akamai : https://www.akamai.com/ // Submitted by Akamai Team akadns.net akamai.net akamai-staging.net akamaiedge.net akamaiedge-staging.net akamaihd.net akamaihd-staging.net akamaiorigin.net akamaiorigin-staging.net akamaized.net akamaized-staging.net edgekey.net edgekey-staging.net edgesuite.net edgesuite-staging.net // alboto.ca : http://alboto.ca // Submitted by Anton Avramov barsy.ca // Alces Software Ltd : http://alces-software.com // Submitted by Mark J. Titorenko *.compute.estate *.alces.network // Alibaba Cloud API Gateway // Submitted by Alibaba Cloud Security alibabacloudcs.com ms.fun ms.show // all-inkl.com : https://all-inkl.com // Submitted by Werner Kaltofen kasserver.com // Altervista : https://www.altervista.org // Submitted by Carlo Cannas altervista.org // alwaysdata : https://www.alwaysdata.com // Submitted by Cyril alwaysdata.net // Amaze Software : https://amaze.co // Submitted by Domain Admin myamaze.net // Amazon : https://www.amazon.com/ // Submitted by AWS Security // Subsections of Amazon/subsidiaries will appear until "concludes" tag // Amazon API Gateway // Submitted by AWS Security // Reference: 6a4f5a95-8c7d-4077-a7af-9cf1abec0a53 execute-api.cn-north-1.amazonaws.com.cn execute-api.cn-northwest-1.amazonaws.com.cn execute-api.af-south-1.amazonaws.com execute-api.ap-east-1.amazonaws.com execute-api.ap-northeast-1.amazonaws.com execute-api.ap-northeast-2.amazonaws.com execute-api.ap-northeast-3.amazonaws.com execute-api.ap-south-1.amazonaws.com execute-api.ap-south-2.amazonaws.com execute-api.ap-southeast-1.amazonaws.com execute-api.ap-southeast-2.amazonaws.com execute-api.ap-southeast-3.amazonaws.com execute-api.ap-southeast-4.amazonaws.com execute-api.ap-southeast-5.amazonaws.com execute-api.ca-central-1.amazonaws.com execute-api.ca-west-1.amazonaws.com execute-api.eu-central-1.amazonaws.com execute-api.eu-central-2.amazonaws.com execute-api.eu-north-1.amazonaws.com execute-api.eu-south-1.amazonaws.com execute-api.eu-south-2.amazonaws.com execute-api.eu-west-1.amazonaws.com execute-api.eu-west-2.amazonaws.com execute-api.eu-west-3.amazonaws.com execute-api.il-central-1.amazonaws.com execute-api.me-central-1.amazonaws.com execute-api.me-south-1.amazonaws.com execute-api.sa-east-1.amazonaws.com execute-api.us-east-1.amazonaws.com execute-api.us-east-2.amazonaws.com execute-api.us-gov-east-1.amazonaws.com execute-api.us-gov-west-1.amazonaws.com execute-api.us-west-1.amazonaws.com execute-api.us-west-2.amazonaws.com // Amazon CloudFront // Submitted by Donavan Miller // Reference: 54144616-fd49-4435-8535-19c6a601bdb3 cloudfront.net // Amazon Cognito // Submitted by AWS Security // Reference: d7d4a954-976e-403e-a010-de9ed0cfbbd1 auth.af-south-1.amazoncognito.com auth.ap-east-1.amazoncognito.com auth.ap-northeast-1.amazoncognito.com auth.ap-northeast-2.amazoncognito.com auth.ap-northeast-3.amazoncognito.com auth.ap-south-1.amazoncognito.com auth.ap-south-2.amazoncognito.com auth.ap-southeast-1.amazoncognito.com auth.ap-southeast-2.amazoncognito.com auth.ap-southeast-3.amazoncognito.com auth.ap-southeast-4.amazoncognito.com auth.ap-southeast-5.amazoncognito.com auth.ap-southeast-7.amazoncognito.com auth.ca-central-1.amazoncognito.com auth.ca-west-1.amazoncognito.com auth.eu-central-1.amazoncognito.com auth.eu-central-2.amazoncognito.com auth.eu-north-1.amazoncognito.com auth.eu-south-1.amazoncognito.com auth.eu-south-2.amazoncognito.com auth.eu-west-1.amazoncognito.com auth.eu-west-2.amazoncognito.com auth.eu-west-3.amazoncognito.com auth.il-central-1.amazoncognito.com auth.me-central-1.amazoncognito.com auth.me-south-1.amazoncognito.com auth.mx-central-1.amazoncognito.com auth.sa-east-1.amazoncognito.com auth.us-east-1.amazoncognito.com auth-fips.us-east-1.amazoncognito.com auth.us-east-2.amazoncognito.com auth-fips.us-east-2.amazoncognito.com auth-fips.us-gov-east-1.amazoncognito.com auth-fips.us-gov-west-1.amazoncognito.com auth.us-west-1.amazoncognito.com auth-fips.us-west-1.amazoncognito.com auth.us-west-2.amazoncognito.com auth-fips.us-west-2.amazoncognito.com auth.cognito-idp.eusc-de-east-1.on.amazonwebservices.eu // Amazon EC2 // Submitted by Luke Wells // Reference: 4c38fa71-58ac-4768-99e5-689c1767e537 *.compute.amazonaws.com.cn *.compute.amazonaws.com *.compute-1.amazonaws.com us-east-1.amazonaws.com // Amazon EMR // Submitted by AWS Security // Reference: 82f43f9f-bbb8-400e-8349-854f5a62f20d emrappui-prod.cn-north-1.amazonaws.com.cn emrnotebooks-prod.cn-north-1.amazonaws.com.cn emrstudio-prod.cn-north-1.amazonaws.com.cn emrappui-prod.cn-northwest-1.amazonaws.com.cn emrnotebooks-prod.cn-northwest-1.amazonaws.com.cn emrstudio-prod.cn-northwest-1.amazonaws.com.cn emrappui-prod.af-south-1.amazonaws.com emrnotebooks-prod.af-south-1.amazonaws.com emrstudio-prod.af-south-1.amazonaws.com emrappui-prod.ap-east-1.amazonaws.com emrnotebooks-prod.ap-east-1.amazonaws.com emrstudio-prod.ap-east-1.amazonaws.com emrappui-prod.ap-northeast-1.amazonaws.com emrnotebooks-prod.ap-northeast-1.amazonaws.com emrstudio-prod.ap-northeast-1.amazonaws.com emrappui-prod.ap-northeast-2.amazonaws.com emrnotebooks-prod.ap-northeast-2.amazonaws.com emrstudio-prod.ap-northeast-2.amazonaws.com emrappui-prod.ap-northeast-3.amazonaws.com emrnotebooks-prod.ap-northeast-3.amazonaws.com emrstudio-prod.ap-northeast-3.amazonaws.com emrappui-prod.ap-south-1.amazonaws.com emrnotebooks-prod.ap-south-1.amazonaws.com emrstudio-prod.ap-south-1.amazonaws.com emrappui-prod.ap-south-2.amazonaws.com emrnotebooks-prod.ap-south-2.amazonaws.com emrstudio-prod.ap-south-2.amazonaws.com emrappui-prod.ap-southeast-1.amazonaws.com emrnotebooks-prod.ap-southeast-1.amazonaws.com emrstudio-prod.ap-southeast-1.amazonaws.com emrappui-prod.ap-southeast-2.amazonaws.com emrnotebooks-prod.ap-southeast-2.amazonaws.com emrstudio-prod.ap-southeast-2.amazonaws.com emrappui-prod.ap-southeast-3.amazonaws.com emrnotebooks-prod.ap-southeast-3.amazonaws.com emrstudio-prod.ap-southeast-3.amazonaws.com emrappui-prod.ap-southeast-4.amazonaws.com emrnotebooks-prod.ap-southeast-4.amazonaws.com emrstudio-prod.ap-southeast-4.amazonaws.com emrappui-prod.ca-central-1.amazonaws.com emrnotebooks-prod.ca-central-1.amazonaws.com emrstudio-prod.ca-central-1.amazonaws.com emrappui-prod.ca-west-1.amazonaws.com emrnotebooks-prod.ca-west-1.amazonaws.com emrstudio-prod.ca-west-1.amazonaws.com emrappui-prod.eu-central-1.amazonaws.com emrnotebooks-prod.eu-central-1.amazonaws.com emrstudio-prod.eu-central-1.amazonaws.com emrappui-prod.eu-central-2.amazonaws.com emrnotebooks-prod.eu-central-2.amazonaws.com emrstudio-prod.eu-central-2.amazonaws.com emrappui-prod.eu-north-1.amazonaws.com emrnotebooks-prod.eu-north-1.amazonaws.com emrstudio-prod.eu-north-1.amazonaws.com emrappui-prod.eu-south-1.amazonaws.com emrnotebooks-prod.eu-south-1.amazonaws.com emrstudio-prod.eu-south-1.amazonaws.com emrappui-prod.eu-south-2.amazonaws.com emrnotebooks-prod.eu-south-2.amazonaws.com emrstudio-prod.eu-south-2.amazonaws.com emrappui-prod.eu-west-1.amazonaws.com emrnotebooks-prod.eu-west-1.amazonaws.com emrstudio-prod.eu-west-1.amazonaws.com emrappui-prod.eu-west-2.amazonaws.com emrnotebooks-prod.eu-west-2.amazonaws.com emrstudio-prod.eu-west-2.amazonaws.com emrappui-prod.eu-west-3.amazonaws.com emrnotebooks-prod.eu-west-3.amazonaws.com emrstudio-prod.eu-west-3.amazonaws.com emrappui-prod.il-central-1.amazonaws.com emrnotebooks-prod.il-central-1.amazonaws.com emrstudio-prod.il-central-1.amazonaws.com emrappui-prod.me-central-1.amazonaws.com emrnotebooks-prod.me-central-1.amazonaws.com emrstudio-prod.me-central-1.amazonaws.com emrappui-prod.me-south-1.amazonaws.com emrnotebooks-prod.me-south-1.amazonaws.com emrstudio-prod.me-south-1.amazonaws.com emrappui-prod.sa-east-1.amazonaws.com emrnotebooks-prod.sa-east-1.amazonaws.com emrstudio-prod.sa-east-1.amazonaws.com emrappui-prod.us-east-1.amazonaws.com emrnotebooks-prod.us-east-1.amazonaws.com emrstudio-prod.us-east-1.amazonaws.com emrappui-prod.us-east-2.amazonaws.com emrnotebooks-prod.us-east-2.amazonaws.com emrstudio-prod.us-east-2.amazonaws.com emrappui-prod.us-gov-east-1.amazonaws.com emrnotebooks-prod.us-gov-east-1.amazonaws.com emrstudio-prod.us-gov-east-1.amazonaws.com emrappui-prod.us-gov-west-1.amazonaws.com emrnotebooks-prod.us-gov-west-1.amazonaws.com emrstudio-prod.us-gov-west-1.amazonaws.com emrappui-prod.us-west-1.amazonaws.com emrnotebooks-prod.us-west-1.amazonaws.com emrstudio-prod.us-west-1.amazonaws.com emrappui-prod.us-west-2.amazonaws.com emrnotebooks-prod.us-west-2.amazonaws.com emrstudio-prod.us-west-2.amazonaws.com // Amazon Managed Workflows for Apache Airflow // Submitted by AWS Security // Reference: bfd043cc-2816-451d-894e-612c6b61a438 *.airflow.af-south-1.on.aws *.airflow.ap-east-1.on.aws *.airflow.ap-northeast-1.on.aws *.airflow.ap-northeast-2.on.aws *.airflow.ap-northeast-3.on.aws *.airflow.ap-south-1.on.aws *.airflow.ap-south-2.on.aws *.airflow.ap-southeast-1.on.aws *.airflow.ap-southeast-2.on.aws *.airflow.ap-southeast-3.on.aws *.airflow.ap-southeast-4.on.aws *.airflow.ap-southeast-5.on.aws *.airflow.ca-central-1.on.aws *.airflow.ca-west-1.on.aws *.airflow.eu-central-1.on.aws *.airflow.eu-central-2.on.aws *.airflow.eu-north-1.on.aws *.airflow.eu-south-1.on.aws *.airflow.eu-south-2.on.aws *.airflow.eu-west-1.on.aws *.airflow.eu-west-2.on.aws *.airflow.eu-west-3.on.aws *.airflow.il-central-1.on.aws *.airflow.me-central-1.on.aws *.airflow.me-south-1.on.aws *.airflow.sa-east-1.on.aws *.airflow.us-east-1.on.aws *.airflow.us-east-2.on.aws *.airflow.us-west-1.on.aws *.airflow.us-west-2.on.aws *.cn-north-1.airflow.amazonaws.com.cn *.cn-northwest-1.airflow.amazonaws.com.cn *.airflow.cn-north-1.on.amazonwebservices.com.cn *.airflow.cn-northwest-1.on.amazonwebservices.com.cn *.af-south-1.airflow.amazonaws.com *.ap-east-1.airflow.amazonaws.com *.ap-northeast-1.airflow.amazonaws.com *.ap-northeast-2.airflow.amazonaws.com *.ap-northeast-3.airflow.amazonaws.com *.ap-south-1.airflow.amazonaws.com *.ap-south-2.airflow.amazonaws.com *.ap-southeast-1.airflow.amazonaws.com *.ap-southeast-2.airflow.amazonaws.com *.ap-southeast-3.airflow.amazonaws.com *.ap-southeast-4.airflow.amazonaws.com *.ap-southeast-5.airflow.amazonaws.com *.ap-southeast-7.airflow.amazonaws.com *.ca-central-1.airflow.amazonaws.com *.ca-west-1.airflow.amazonaws.com *.eu-central-1.airflow.amazonaws.com *.eu-central-2.airflow.amazonaws.com *.eu-north-1.airflow.amazonaws.com *.eu-south-1.airflow.amazonaws.com *.eu-south-2.airflow.amazonaws.com *.eu-west-1.airflow.amazonaws.com *.eu-west-2.airflow.amazonaws.com *.eu-west-3.airflow.amazonaws.com *.il-central-1.airflow.amazonaws.com *.me-central-1.airflow.amazonaws.com *.me-south-1.airflow.amazonaws.com *.sa-east-1.airflow.amazonaws.com *.us-east-1.airflow.amazonaws.com *.us-east-2.airflow.amazonaws.com *.us-west-1.airflow.amazonaws.com *.us-west-2.airflow.amazonaws.com // Amazon Relational Database Service // Submitted by: AWS Security // Reference: 5aa87906-fd4f-4831-8727-4ffca6094159 *.rds.cn-north-1.amazonaws.com.cn *.rds.cn-northwest-1.amazonaws.com.cn *.af-south-1.rds.amazonaws.com *.ap-east-1.rds.amazonaws.com *.ap-east-2.rds.amazonaws.com *.ap-northeast-1.rds.amazonaws.com *.ap-northeast-2.rds.amazonaws.com *.ap-northeast-3.rds.amazonaws.com *.ap-south-1.rds.amazonaws.com *.ap-south-2.rds.amazonaws.com *.ap-southeast-1.rds.amazonaws.com *.ap-southeast-2.rds.amazonaws.com *.ap-southeast-3.rds.amazonaws.com *.ap-southeast-4.rds.amazonaws.com *.ap-southeast-5.rds.amazonaws.com *.ap-southeast-6.rds.amazonaws.com *.ap-southeast-7.rds.amazonaws.com *.ca-central-1.rds.amazonaws.com *.ca-west-1.rds.amazonaws.com *.eu-central-1.rds.amazonaws.com *.eu-central-2.rds.amazonaws.com *.eu-west-1.rds.amazonaws.com *.eu-west-2.rds.amazonaws.com *.eu-west-3.rds.amazonaws.com *.il-central-1.rds.amazonaws.com *.me-central-1.rds.amazonaws.com *.me-south-1.rds.amazonaws.com *.mx-central-1.rds.amazonaws.com *.sa-east-1.rds.amazonaws.com *.us-east-1.rds.amazonaws.com *.us-east-2.rds.amazonaws.com *.us-gov-east-1.rds.amazonaws.com *.us-gov-west-1.rds.amazonaws.com *.us-northeast-1.rds.amazonaws.com *.us-west-1.rds.amazonaws.com *.us-west-2.rds.amazonaws.com // Amazon S3 // Submitted by AWS Security // Reference: 6f374c1c-1cc9-47de-8b2a-69ca56a3a3b6 s3.dualstack.cn-north-1.amazonaws.com.cn s3-accesspoint.dualstack.cn-north-1.amazonaws.com.cn s3-website.dualstack.cn-north-1.amazonaws.com.cn s3.cn-north-1.amazonaws.com.cn s3-accesspoint.cn-north-1.amazonaws.com.cn s3-deprecated.cn-north-1.amazonaws.com.cn s3-object-lambda.cn-north-1.amazonaws.com.cn s3-website.cn-north-1.amazonaws.com.cn s3.dualstack.cn-northwest-1.amazonaws.com.cn s3-accesspoint.dualstack.cn-northwest-1.amazonaws.com.cn s3.cn-northwest-1.amazonaws.com.cn s3-accesspoint.cn-northwest-1.amazonaws.com.cn s3-object-lambda.cn-northwest-1.amazonaws.com.cn s3-website.cn-northwest-1.amazonaws.com.cn s3.dualstack.af-south-1.amazonaws.com s3-accesspoint.dualstack.af-south-1.amazonaws.com s3-website.dualstack.af-south-1.amazonaws.com s3.af-south-1.amazonaws.com s3-accesspoint.af-south-1.amazonaws.com s3-object-lambda.af-south-1.amazonaws.com s3-website.af-south-1.amazonaws.com s3.dualstack.ap-east-1.amazonaws.com s3-accesspoint.dualstack.ap-east-1.amazonaws.com s3.ap-east-1.amazonaws.com s3-accesspoint.ap-east-1.amazonaws.com s3-object-lambda.ap-east-1.amazonaws.com s3-website.ap-east-1.amazonaws.com s3.dualstack.ap-northeast-1.amazonaws.com s3-accesspoint.dualstack.ap-northeast-1.amazonaws.com s3-website.dualstack.ap-northeast-1.amazonaws.com s3.ap-northeast-1.amazonaws.com s3-accesspoint.ap-northeast-1.amazonaws.com s3-object-lambda.ap-northeast-1.amazonaws.com s3-website.ap-northeast-1.amazonaws.com s3.dualstack.ap-northeast-2.amazonaws.com s3-accesspoint.dualstack.ap-northeast-2.amazonaws.com s3-website.dualstack.ap-northeast-2.amazonaws.com s3.ap-northeast-2.amazonaws.com s3-accesspoint.ap-northeast-2.amazonaws.com s3-object-lambda.ap-northeast-2.amazonaws.com s3-website.ap-northeast-2.amazonaws.com s3.dualstack.ap-northeast-3.amazonaws.com s3-accesspoint.dualstack.ap-northeast-3.amazonaws.com s3-website.dualstack.ap-northeast-3.amazonaws.com s3.ap-northeast-3.amazonaws.com s3-accesspoint.ap-northeast-3.amazonaws.com s3-object-lambda.ap-northeast-3.amazonaws.com s3-website.ap-northeast-3.amazonaws.com s3.dualstack.ap-south-1.amazonaws.com s3-accesspoint.dualstack.ap-south-1.amazonaws.com s3-website.dualstack.ap-south-1.amazonaws.com s3.ap-south-1.amazonaws.com s3-accesspoint.ap-south-1.amazonaws.com s3-object-lambda.ap-south-1.amazonaws.com s3-website.ap-south-1.amazonaws.com s3.dualstack.ap-south-2.amazonaws.com s3-accesspoint.dualstack.ap-south-2.amazonaws.com s3-website.dualstack.ap-south-2.amazonaws.com s3.ap-south-2.amazonaws.com s3-accesspoint.ap-south-2.amazonaws.com s3-object-lambda.ap-south-2.amazonaws.com s3-website.ap-south-2.amazonaws.com s3.dualstack.ap-southeast-1.amazonaws.com s3-accesspoint.dualstack.ap-southeast-1.amazonaws.com s3-website.dualstack.ap-southeast-1.amazonaws.com s3.ap-southeast-1.amazonaws.com s3-accesspoint.ap-southeast-1.amazonaws.com s3-object-lambda.ap-southeast-1.amazonaws.com s3-website.ap-southeast-1.amazonaws.com s3.dualstack.ap-southeast-2.amazonaws.com s3-accesspoint.dualstack.ap-southeast-2.amazonaws.com s3-website.dualstack.ap-southeast-2.amazonaws.com s3.ap-southeast-2.amazonaws.com s3-accesspoint.ap-southeast-2.amazonaws.com s3-object-lambda.ap-southeast-2.amazonaws.com s3-website.ap-southeast-2.amazonaws.com s3.dualstack.ap-southeast-3.amazonaws.com s3-accesspoint.dualstack.ap-southeast-3.amazonaws.com s3-website.dualstack.ap-southeast-3.amazonaws.com s3.ap-southeast-3.amazonaws.com s3-accesspoint.ap-southeast-3.amazonaws.com s3-object-lambda.ap-southeast-3.amazonaws.com s3-website.ap-southeast-3.amazonaws.com s3.dualstack.ap-southeast-4.amazonaws.com s3-accesspoint.dualstack.ap-southeast-4.amazonaws.com s3-website.dualstack.ap-southeast-4.amazonaws.com s3.ap-southeast-4.amazonaws.com s3-accesspoint.ap-southeast-4.amazonaws.com s3-object-lambda.ap-southeast-4.amazonaws.com s3-website.ap-southeast-4.amazonaws.com s3.dualstack.ap-southeast-5.amazonaws.com s3-accesspoint.dualstack.ap-southeast-5.amazonaws.com s3-website.dualstack.ap-southeast-5.amazonaws.com s3.ap-southeast-5.amazonaws.com s3-accesspoint.ap-southeast-5.amazonaws.com s3-deprecated.ap-southeast-5.amazonaws.com s3-object-lambda.ap-southeast-5.amazonaws.com s3-website.ap-southeast-5.amazonaws.com s3.dualstack.ca-central-1.amazonaws.com s3-accesspoint.dualstack.ca-central-1.amazonaws.com s3-accesspoint-fips.dualstack.ca-central-1.amazonaws.com s3-fips.dualstack.ca-central-1.amazonaws.com s3-website.dualstack.ca-central-1.amazonaws.com s3.ca-central-1.amazonaws.com s3-accesspoint.ca-central-1.amazonaws.com s3-accesspoint-fips.ca-central-1.amazonaws.com s3-fips.ca-central-1.amazonaws.com s3-object-lambda.ca-central-1.amazonaws.com s3-website.ca-central-1.amazonaws.com s3.dualstack.ca-west-1.amazonaws.com s3-accesspoint.dualstack.ca-west-1.amazonaws.com s3-accesspoint-fips.dualstack.ca-west-1.amazonaws.com s3-fips.dualstack.ca-west-1.amazonaws.com s3-website.dualstack.ca-west-1.amazonaws.com s3.ca-west-1.amazonaws.com s3-accesspoint.ca-west-1.amazonaws.com s3-accesspoint-fips.ca-west-1.amazonaws.com s3-fips.ca-west-1.amazonaws.com s3-object-lambda.ca-west-1.amazonaws.com s3-website.ca-west-1.amazonaws.com s3.dualstack.eu-central-1.amazonaws.com s3-accesspoint.dualstack.eu-central-1.amazonaws.com s3-website.dualstack.eu-central-1.amazonaws.com s3.eu-central-1.amazonaws.com s3-accesspoint.eu-central-1.amazonaws.com s3-object-lambda.eu-central-1.amazonaws.com s3-website.eu-central-1.amazonaws.com s3.dualstack.eu-central-2.amazonaws.com s3-accesspoint.dualstack.eu-central-2.amazonaws.com s3-website.dualstack.eu-central-2.amazonaws.com s3.eu-central-2.amazonaws.com s3-accesspoint.eu-central-2.amazonaws.com s3-object-lambda.eu-central-2.amazonaws.com s3-website.eu-central-2.amazonaws.com s3.dualstack.eu-north-1.amazonaws.com s3-accesspoint.dualstack.eu-north-1.amazonaws.com s3.eu-north-1.amazonaws.com s3-accesspoint.eu-north-1.amazonaws.com s3-object-lambda.eu-north-1.amazonaws.com s3-website.eu-north-1.amazonaws.com s3.dualstack.eu-south-1.amazonaws.com s3-accesspoint.dualstack.eu-south-1.amazonaws.com s3-website.dualstack.eu-south-1.amazonaws.com s3.eu-south-1.amazonaws.com s3-accesspoint.eu-south-1.amazonaws.com s3-object-lambda.eu-south-1.amazonaws.com s3-website.eu-south-1.amazonaws.com s3.dualstack.eu-south-2.amazonaws.com s3-accesspoint.dualstack.eu-south-2.amazonaws.com s3-website.dualstack.eu-south-2.amazonaws.com s3.eu-south-2.amazonaws.com s3-accesspoint.eu-south-2.amazonaws.com s3-object-lambda.eu-south-2.amazonaws.com s3-website.eu-south-2.amazonaws.com s3.dualstack.eu-west-1.amazonaws.com s3-accesspoint.dualstack.eu-west-1.amazonaws.com s3-website.dualstack.eu-west-1.amazonaws.com s3.eu-west-1.amazonaws.com s3-accesspoint.eu-west-1.amazonaws.com s3-deprecated.eu-west-1.amazonaws.com s3-object-lambda.eu-west-1.amazonaws.com s3-website.eu-west-1.amazonaws.com s3.dualstack.eu-west-2.amazonaws.com s3-accesspoint.dualstack.eu-west-2.amazonaws.com s3.eu-west-2.amazonaws.com s3-accesspoint.eu-west-2.amazonaws.com s3-object-lambda.eu-west-2.amazonaws.com s3-website.eu-west-2.amazonaws.com s3.dualstack.eu-west-3.amazonaws.com s3-accesspoint.dualstack.eu-west-3.amazonaws.com s3-website.dualstack.eu-west-3.amazonaws.com s3.eu-west-3.amazonaws.com s3-accesspoint.eu-west-3.amazonaws.com s3-object-lambda.eu-west-3.amazonaws.com s3-website.eu-west-3.amazonaws.com s3.dualstack.il-central-1.amazonaws.com s3-accesspoint.dualstack.il-central-1.amazonaws.com s3-website.dualstack.il-central-1.amazonaws.com s3.il-central-1.amazonaws.com s3-accesspoint.il-central-1.amazonaws.com s3-object-lambda.il-central-1.amazonaws.com s3-website.il-central-1.amazonaws.com s3.dualstack.me-central-1.amazonaws.com s3-accesspoint.dualstack.me-central-1.amazonaws.com s3-website.dualstack.me-central-1.amazonaws.com s3.me-central-1.amazonaws.com s3-accesspoint.me-central-1.amazonaws.com s3-object-lambda.me-central-1.amazonaws.com s3-website.me-central-1.amazonaws.com s3.dualstack.me-south-1.amazonaws.com s3-accesspoint.dualstack.me-south-1.amazonaws.com s3.me-south-1.amazonaws.com s3-accesspoint.me-south-1.amazonaws.com s3-object-lambda.me-south-1.amazonaws.com s3-website.me-south-1.amazonaws.com s3.amazonaws.com s3-1.amazonaws.com s3-ap-east-1.amazonaws.com s3-ap-northeast-1.amazonaws.com s3-ap-northeast-2.amazonaws.com s3-ap-northeast-3.amazonaws.com s3-ap-south-1.amazonaws.com s3-ap-southeast-1.amazonaws.com s3-ap-southeast-2.amazonaws.com s3-ca-central-1.amazonaws.com s3-eu-central-1.amazonaws.com s3-eu-north-1.amazonaws.com s3-eu-west-1.amazonaws.com s3-eu-west-2.amazonaws.com s3-eu-west-3.amazonaws.com s3-external-1.amazonaws.com s3-fips-us-gov-east-1.amazonaws.com s3-fips-us-gov-west-1.amazonaws.com mrap.accesspoint.s3-global.amazonaws.com s3-me-south-1.amazonaws.com s3-sa-east-1.amazonaws.com s3-us-east-2.amazonaws.com s3-us-gov-east-1.amazonaws.com s3-us-gov-west-1.amazonaws.com s3-us-west-1.amazonaws.com s3-us-west-2.amazonaws.com s3-website-ap-northeast-1.amazonaws.com s3-website-ap-southeast-1.amazonaws.com s3-website-ap-southeast-2.amazonaws.com s3-website-eu-west-1.amazonaws.com s3-website-sa-east-1.amazonaws.com s3-website-us-east-1.amazonaws.com s3-website-us-gov-west-1.amazonaws.com s3-website-us-west-1.amazonaws.com s3-website-us-west-2.amazonaws.com s3.dualstack.sa-east-1.amazonaws.com s3-accesspoint.dualstack.sa-east-1.amazonaws.com s3-website.dualstack.sa-east-1.amazonaws.com s3.sa-east-1.amazonaws.com s3-accesspoint.sa-east-1.amazonaws.com s3-object-lambda.sa-east-1.amazonaws.com s3-website.sa-east-1.amazonaws.com s3.dualstack.us-east-1.amazonaws.com s3-accesspoint.dualstack.us-east-1.amazonaws.com s3-accesspoint-fips.dualstack.us-east-1.amazonaws.com s3-fips.dualstack.us-east-1.amazonaws.com s3-website.dualstack.us-east-1.amazonaws.com s3.us-east-1.amazonaws.com s3-accesspoint.us-east-1.amazonaws.com s3-accesspoint-fips.us-east-1.amazonaws.com s3-deprecated.us-east-1.amazonaws.com s3-fips.us-east-1.amazonaws.com s3-object-lambda.us-east-1.amazonaws.com s3-website.us-east-1.amazonaws.com s3.dualstack.us-east-2.amazonaws.com s3-accesspoint.dualstack.us-east-2.amazonaws.com s3-accesspoint-fips.dualstack.us-east-2.amazonaws.com s3-fips.dualstack.us-east-2.amazonaws.com s3-website.dualstack.us-east-2.amazonaws.com s3.us-east-2.amazonaws.com s3-accesspoint.us-east-2.amazonaws.com s3-accesspoint-fips.us-east-2.amazonaws.com s3-deprecated.us-east-2.amazonaws.com s3-fips.us-east-2.amazonaws.com s3-object-lambda.us-east-2.amazonaws.com s3-website.us-east-2.amazonaws.com s3.dualstack.us-gov-east-1.amazonaws.com s3-accesspoint.dualstack.us-gov-east-1.amazonaws.com s3-accesspoint-fips.dualstack.us-gov-east-1.amazonaws.com s3-fips.dualstack.us-gov-east-1.amazonaws.com s3-website.dualstack.us-gov-east-1.amazonaws.com s3.us-gov-east-1.amazonaws.com s3-accesspoint.us-gov-east-1.amazonaws.com s3-accesspoint-fips.us-gov-east-1.amazonaws.com s3-fips.us-gov-east-1.amazonaws.com s3-object-lambda.us-gov-east-1.amazonaws.com s3-website.us-gov-east-1.amazonaws.com s3.dualstack.us-gov-west-1.amazonaws.com s3-accesspoint.dualstack.us-gov-west-1.amazonaws.com s3-accesspoint-fips.dualstack.us-gov-west-1.amazonaws.com s3-fips.dualstack.us-gov-west-1.amazonaws.com s3-website.dualstack.us-gov-west-1.amazonaws.com s3.us-gov-west-1.amazonaws.com s3-accesspoint.us-gov-west-1.amazonaws.com s3-accesspoint-fips.us-gov-west-1.amazonaws.com s3-fips.us-gov-west-1.amazonaws.com s3-object-lambda.us-gov-west-1.amazonaws.com s3-website.us-gov-west-1.amazonaws.com s3.dualstack.us-west-1.amazonaws.com s3-accesspoint.dualstack.us-west-1.amazonaws.com s3-accesspoint-fips.dualstack.us-west-1.amazonaws.com s3-fips.dualstack.us-west-1.amazonaws.com s3-website.dualstack.us-west-1.amazonaws.com s3.us-west-1.amazonaws.com s3-accesspoint.us-west-1.amazonaws.com s3-accesspoint-fips.us-west-1.amazonaws.com s3-fips.us-west-1.amazonaws.com s3-object-lambda.us-west-1.amazonaws.com s3-website.us-west-1.amazonaws.com s3.dualstack.us-west-2.amazonaws.com s3-accesspoint.dualstack.us-west-2.amazonaws.com s3-accesspoint-fips.dualstack.us-west-2.amazonaws.com s3-fips.dualstack.us-west-2.amazonaws.com s3-website.dualstack.us-west-2.amazonaws.com s3.us-west-2.amazonaws.com s3-accesspoint.us-west-2.amazonaws.com s3-accesspoint-fips.us-west-2.amazonaws.com s3-deprecated.us-west-2.amazonaws.com s3-fips.us-west-2.amazonaws.com s3-object-lambda.us-west-2.amazonaws.com s3-website.us-west-2.amazonaws.com // Amazon SageMaker Ground Truth // Submitted by AWS Security // Reference: 98dbfde4-7802-48c3-8751-b60f204e0d9c labeling.ap-northeast-1.sagemaker.aws labeling.ap-northeast-2.sagemaker.aws labeling.ap-south-1.sagemaker.aws labeling.ap-southeast-1.sagemaker.aws labeling.ap-southeast-2.sagemaker.aws labeling.ca-central-1.sagemaker.aws labeling.eu-central-1.sagemaker.aws labeling.eu-west-1.sagemaker.aws labeling.eu-west-2.sagemaker.aws labeling.us-east-1.sagemaker.aws labeling.us-east-2.sagemaker.aws labeling.us-west-2.sagemaker.aws // Amazon SageMaker Notebook Instances // Submitted by AWS Security // Reference: b5ea56df-669e-43cc-9537-14aa172f5dfc notebook.af-south-1.sagemaker.aws notebook.ap-east-1.sagemaker.aws notebook.ap-northeast-1.sagemaker.aws notebook.ap-northeast-2.sagemaker.aws notebook.ap-northeast-3.sagemaker.aws notebook.ap-south-1.sagemaker.aws notebook.ap-south-2.sagemaker.aws notebook.ap-southeast-1.sagemaker.aws notebook.ap-southeast-2.sagemaker.aws notebook.ap-southeast-3.sagemaker.aws notebook.ap-southeast-4.sagemaker.aws notebook.ca-central-1.sagemaker.aws notebook-fips.ca-central-1.sagemaker.aws notebook.ca-west-1.sagemaker.aws notebook-fips.ca-west-1.sagemaker.aws notebook.eu-central-1.sagemaker.aws notebook.eu-central-2.sagemaker.aws notebook.eu-north-1.sagemaker.aws notebook.eu-south-1.sagemaker.aws notebook.eu-south-2.sagemaker.aws notebook.eu-west-1.sagemaker.aws notebook.eu-west-2.sagemaker.aws notebook.eu-west-3.sagemaker.aws notebook.il-central-1.sagemaker.aws notebook.me-central-1.sagemaker.aws notebook.me-south-1.sagemaker.aws notebook.sa-east-1.sagemaker.aws notebook.us-east-1.sagemaker.aws notebook-fips.us-east-1.sagemaker.aws notebook.us-east-2.sagemaker.aws notebook-fips.us-east-2.sagemaker.aws notebook.us-gov-east-1.sagemaker.aws notebook-fips.us-gov-east-1.sagemaker.aws notebook.us-gov-west-1.sagemaker.aws notebook-fips.us-gov-west-1.sagemaker.aws notebook.us-west-1.sagemaker.aws notebook-fips.us-west-1.sagemaker.aws notebook.us-west-2.sagemaker.aws notebook-fips.us-west-2.sagemaker.aws notebook.cn-north-1.sagemaker.com.cn notebook.cn-northwest-1.sagemaker.com.cn // Amazon SageMaker Studio // Submitted by AWS Security // Reference: 475f237e-ab88-4041-9f41-7cfccdf66aeb studio.af-south-1.sagemaker.aws studio.ap-east-1.sagemaker.aws studio.ap-northeast-1.sagemaker.aws studio.ap-northeast-2.sagemaker.aws studio.ap-northeast-3.sagemaker.aws studio.ap-south-1.sagemaker.aws studio.ap-southeast-1.sagemaker.aws studio.ap-southeast-2.sagemaker.aws studio.ap-southeast-3.sagemaker.aws studio.ca-central-1.sagemaker.aws studio.eu-central-1.sagemaker.aws studio.eu-central-2.sagemaker.aws studio.eu-north-1.sagemaker.aws studio.eu-south-1.sagemaker.aws studio.eu-south-2.sagemaker.aws studio.eu-west-1.sagemaker.aws studio.eu-west-2.sagemaker.aws studio.eu-west-3.sagemaker.aws studio.il-central-1.sagemaker.aws studio.me-central-1.sagemaker.aws studio.me-south-1.sagemaker.aws studio.sa-east-1.sagemaker.aws studio.us-east-1.sagemaker.aws studio.us-east-2.sagemaker.aws studio.us-gov-east-1.sagemaker.aws studio-fips.us-gov-east-1.sagemaker.aws studio.us-gov-west-1.sagemaker.aws studio-fips.us-gov-west-1.sagemaker.aws studio.us-west-1.sagemaker.aws studio.us-west-2.sagemaker.aws studio.cn-north-1.sagemaker.com.cn studio.cn-northwest-1.sagemaker.com.cn // Amazon SageMaker with MLflow // Submited by: AWS Security // Reference: c19f92b3-a82a-452d-8189-831b572eea7e *.experiments.sagemaker.aws // Analytics on AWS // Submitted by AWS Security // Reference: 955f9f40-a495-4e73-ae85-67b77ac9cadd analytics-gateway.ap-northeast-1.amazonaws.com analytics-gateway.ap-northeast-2.amazonaws.com analytics-gateway.ap-south-1.amazonaws.com analytics-gateway.ap-southeast-1.amazonaws.com analytics-gateway.ap-southeast-2.amazonaws.com analytics-gateway.eu-central-1.amazonaws.com analytics-gateway.eu-west-1.amazonaws.com analytics-gateway.us-east-1.amazonaws.com analytics-gateway.us-east-2.amazonaws.com analytics-gateway.us-west-2.amazonaws.com // AWS Amplify // Submitted by AWS Security // Reference: c35bed18-6f4f-424f-9298-5756f2f7d72b amplifyapp.com // AWS App Runner // Submitted by AWS Security // Reference: 6828c008-ba5d-442f-ade5-48da4e7c2316 *.awsapprunner.com // AWS Cloud9 // Submitted by: AWS Security // Reference: 30717f72-4007-4f0f-8ed4-864c6f2efec9 webview-assets.aws-cloud9.af-south-1.amazonaws.com vfs.cloud9.af-south-1.amazonaws.com webview-assets.cloud9.af-south-1.amazonaws.com webview-assets.aws-cloud9.ap-east-1.amazonaws.com vfs.cloud9.ap-east-1.amazonaws.com webview-assets.cloud9.ap-east-1.amazonaws.com webview-assets.aws-cloud9.ap-northeast-1.amazonaws.com vfs.cloud9.ap-northeast-1.amazonaws.com webview-assets.cloud9.ap-northeast-1.amazonaws.com webview-assets.aws-cloud9.ap-northeast-2.amazonaws.com vfs.cloud9.ap-northeast-2.amazonaws.com webview-assets.cloud9.ap-northeast-2.amazonaws.com webview-assets.aws-cloud9.ap-northeast-3.amazonaws.com vfs.cloud9.ap-northeast-3.amazonaws.com webview-assets.cloud9.ap-northeast-3.amazonaws.com webview-assets.aws-cloud9.ap-south-1.amazonaws.com vfs.cloud9.ap-south-1.amazonaws.com webview-assets.cloud9.ap-south-1.amazonaws.com webview-assets.aws-cloud9.ap-southeast-1.amazonaws.com vfs.cloud9.ap-southeast-1.amazonaws.com webview-assets.cloud9.ap-southeast-1.amazonaws.com webview-assets.aws-cloud9.ap-southeast-2.amazonaws.com vfs.cloud9.ap-southeast-2.amazonaws.com webview-assets.cloud9.ap-southeast-2.amazonaws.com webview-assets.aws-cloud9.ca-central-1.amazonaws.com vfs.cloud9.ca-central-1.amazonaws.com webview-assets.cloud9.ca-central-1.amazonaws.com webview-assets.aws-cloud9.eu-central-1.amazonaws.com vfs.cloud9.eu-central-1.amazonaws.com webview-assets.cloud9.eu-central-1.amazonaws.com webview-assets.aws-cloud9.eu-north-1.amazonaws.com vfs.cloud9.eu-north-1.amazonaws.com webview-assets.cloud9.eu-north-1.amazonaws.com webview-assets.aws-cloud9.eu-south-1.amazonaws.com vfs.cloud9.eu-south-1.amazonaws.com webview-assets.cloud9.eu-south-1.amazonaws.com webview-assets.aws-cloud9.eu-west-1.amazonaws.com vfs.cloud9.eu-west-1.amazonaws.com webview-assets.cloud9.eu-west-1.amazonaws.com webview-assets.aws-cloud9.eu-west-2.amazonaws.com vfs.cloud9.eu-west-2.amazonaws.com webview-assets.cloud9.eu-west-2.amazonaws.com webview-assets.aws-cloud9.eu-west-3.amazonaws.com vfs.cloud9.eu-west-3.amazonaws.com webview-assets.cloud9.eu-west-3.amazonaws.com webview-assets.aws-cloud9.il-central-1.amazonaws.com vfs.cloud9.il-central-1.amazonaws.com webview-assets.aws-cloud9.me-south-1.amazonaws.com vfs.cloud9.me-south-1.amazonaws.com webview-assets.cloud9.me-south-1.amazonaws.com webview-assets.aws-cloud9.sa-east-1.amazonaws.com vfs.cloud9.sa-east-1.amazonaws.com webview-assets.cloud9.sa-east-1.amazonaws.com webview-assets.aws-cloud9.us-east-1.amazonaws.com vfs.cloud9.us-east-1.amazonaws.com webview-assets.cloud9.us-east-1.amazonaws.com webview-assets.aws-cloud9.us-east-2.amazonaws.com vfs.cloud9.us-east-2.amazonaws.com webview-assets.cloud9.us-east-2.amazonaws.com webview-assets.aws-cloud9.us-west-1.amazonaws.com vfs.cloud9.us-west-1.amazonaws.com webview-assets.cloud9.us-west-1.amazonaws.com webview-assets.aws-cloud9.us-west-2.amazonaws.com vfs.cloud9.us-west-2.amazonaws.com webview-assets.cloud9.us-west-2.amazonaws.com // AWS Directory Service // Submitted by AWS Security // Reference: a13203e8-42dc-4045-a0d2-2ee67bed1068 awsapps.com // AWS Elastic Beanstalk // Submitted by AWS Security // Reference: e4e02a54-eaf9-4fe7-b662-39ccbc011a04 cn-north-1.eb.amazonaws.com.cn cn-northwest-1.eb.amazonaws.com.cn elasticbeanstalk.com af-south-1.elasticbeanstalk.com ap-east-1.elasticbeanstalk.com ap-northeast-1.elasticbeanstalk.com ap-northeast-2.elasticbeanstalk.com ap-northeast-3.elasticbeanstalk.com ap-south-1.elasticbeanstalk.com ap-southeast-1.elasticbeanstalk.com ap-southeast-2.elasticbeanstalk.com ap-southeast-3.elasticbeanstalk.com ap-southeast-5.elasticbeanstalk.com ap-southeast-7.elasticbeanstalk.com ca-central-1.elasticbeanstalk.com eu-central-1.elasticbeanstalk.com eu-north-1.elasticbeanstalk.com eu-south-1.elasticbeanstalk.com eu-south-2.elasticbeanstalk.com eu-west-1.elasticbeanstalk.com eu-west-2.elasticbeanstalk.com eu-west-3.elasticbeanstalk.com il-central-1.elasticbeanstalk.com me-central-1.elasticbeanstalk.com me-south-1.elasticbeanstalk.com sa-east-1.elasticbeanstalk.com us-east-1.elasticbeanstalk.com us-east-2.elasticbeanstalk.com us-gov-east-1.elasticbeanstalk.com us-gov-west-1.elasticbeanstalk.com us-west-1.elasticbeanstalk.com us-west-2.elasticbeanstalk.com // (AWS) Elastic Load Balancing // Submitted by Luke Wells // Reference: 12a3d528-1bac-4433-a359-a395867ffed2 *.elb.amazonaws.com.cn *.elb.amazonaws.com // AWS Global Accelerator // Submitted by Daniel Massaguer // Reference: d916759d-a08b-4241-b536-4db887383a6a awsglobalaccelerator.com // AWS Lambda Function URLs // Submitted by AWS Security // Reference: 57df74ca-0820-46a5-89ea-0f0d0c4714b7 lambda-url.af-south-1.on.aws lambda-url.ap-east-1.on.aws lambda-url.ap-northeast-1.on.aws lambda-url.ap-northeast-2.on.aws lambda-url.ap-northeast-3.on.aws lambda-url.ap-south-1.on.aws lambda-url.ap-southeast-1.on.aws lambda-url.ap-southeast-2.on.aws lambda-url.ap-southeast-3.on.aws lambda-url.ca-central-1.on.aws lambda-url.eu-central-1.on.aws lambda-url.eu-north-1.on.aws lambda-url.eu-south-1.on.aws lambda-url.eu-west-1.on.aws lambda-url.eu-west-2.on.aws lambda-url.eu-west-3.on.aws lambda-url.me-south-1.on.aws lambda-url.sa-east-1.on.aws lambda-url.us-east-1.on.aws lambda-url.us-east-2.on.aws lambda-url.us-west-1.on.aws lambda-url.us-west-2.on.aws // AWS re:Post Private // Submitted by AWS Security // Reference: 83385945-225f-416e-9aa0-ad0632bfdcee *.private.repost.aws // AWS Transfer Family web apps // Submitted by AWS Security // Reference: 9265cdd3-f017-42ab-98bb-08bf427d3fc9 transfer-webapp.af-south-1.on.aws transfer-webapp.ap-east-1.on.aws transfer-webapp.ap-northeast-1.on.aws transfer-webapp.ap-northeast-2.on.aws transfer-webapp.ap-northeast-3.on.aws transfer-webapp.ap-south-1.on.aws transfer-webapp.ap-south-2.on.aws transfer-webapp.ap-southeast-1.on.aws transfer-webapp.ap-southeast-2.on.aws transfer-webapp.ap-southeast-3.on.aws transfer-webapp.ap-southeast-4.on.aws transfer-webapp.ap-southeast-5.on.aws transfer-webapp.ap-southeast-7.on.aws transfer-webapp.ca-central-1.on.aws transfer-webapp.ca-west-1.on.aws transfer-webapp.eu-central-1.on.aws transfer-webapp.eu-central-2.on.aws transfer-webapp.eu-north-1.on.aws transfer-webapp.eu-south-1.on.aws transfer-webapp.eu-south-2.on.aws transfer-webapp.eu-west-1.on.aws transfer-webapp.eu-west-2.on.aws transfer-webapp.eu-west-3.on.aws transfer-webapp.il-central-1.on.aws transfer-webapp.me-central-1.on.aws transfer-webapp.me-south-1.on.aws transfer-webapp.mx-central-1.on.aws transfer-webapp.sa-east-1.on.aws transfer-webapp.us-east-1.on.aws transfer-webapp.us-east-2.on.aws transfer-webapp.us-gov-east-1.on.aws transfer-webapp-fips.us-gov-east-1.on.aws transfer-webapp.us-gov-west-1.on.aws transfer-webapp-fips.us-gov-west-1.on.aws transfer-webapp.us-west-1.on.aws transfer-webapp.us-west-2.on.aws transfer-webapp.cn-north-1.on.amazonwebservices.com.cn transfer-webapp.cn-northwest-1.on.amazonwebservices.com.cn // eero // Submitted by Yue Kang // Reference: 264afe70-f62c-4c02-8ab9-b5281ed24461 eero.online eero-stage.online // concludes Amazon // Antagonist B.V. : https://www.antagonist.nl/ // Submitted by Sander Hoentjen antagonist.cloud // Apigee : https://apigee.com/ // Submitted by Apigee Security Team apigee.io // Apis Networks : https://apisnetworks.com // Submitted by Matt Saladna panel.dev // Apphud : https://apphud.com // Submitted by Alexander Selivanov siiites.com // Apple : https://www.apple.com // Submitted by Apple DNS int.apple *.cloud.int.apple *.r.cloud.int.apple *.ap-north-1.r.cloud.int.apple *.ap-south-1.r.cloud.int.apple *.ap-south-2.r.cloud.int.apple *.eu-central-1.r.cloud.int.apple *.eu-north-1.r.cloud.int.apple *.us-central-1.r.cloud.int.apple *.us-central-2.r.cloud.int.apple *.us-east-1.r.cloud.int.apple *.us-east-2.r.cloud.int.apple *.us-west-1.r.cloud.int.apple *.us-west-2.r.cloud.int.apple *.us-west-3.r.cloud.int.apple // Appspace : https://www.appspace.com // Submitted by Appspace Security Team appspacehosted.com appspaceusercontent.com // Appudo UG (haftungsbeschränkt) : https://www.appudo.com // Submitted by Alexander Hochbaum appudo.net // Appwrite : https://appwrite.io // Submitted by Steven Nguyen appwrite.global appwrite.network *.appwrite.run // Aptible : https://www.aptible.com/ // Submitted by Thomas Orozco on-aptible.com // Aquapal : https://aquapal.net/ // Submitted by Aki Ueno f5.si // ArvanCloud EdgeCompute // Submitted by ArvanCloud CDN arvanedge.ir // ASEINet : https://www.aseinet.com/ // Submitted by Asei SEKIGUCHI user.aseinet.ne.jp gv.vc d.gv.vc // Asociación Amigos de la Informática "Euskalamiga" : http://encounter.eus/ // Submitted by Hector Martin user.party.eus // Association potager.org : https://potager.org/ // Submitted by Lunar pimienta.org poivron.org potager.org sweetpepper.org // ASUSTOR Inc. : http://www.asustor.com // Submitted by Vincent Tseng myasustor.com // Atlassian : https://atlassian.com // Submitted by Sam Smyth cdn.prod.atlassian-dev.net // AVM : https://avm.de // Submitted by Andreas Weise myfritz.link myfritz.net // AW AdvisorWebsites.com Software Inc : https://advisorwebsites.com // Submitted by James Kennedy *.awdev.ca *.advisor.ws // AZ.pl sp. z.o.o : https://az.pl // Submitted by Krzysztof Wolski ecommerce-shop.pl // b-data GmbH : https://www.b-data.io // Submitted by Olivier Benz b-data.io // Balena : https://www.balena.io // Submitted by Petros Angelatos balena-devices.com // BASE, Inc. : https://binc.jp // Submitted by Yuya NAGASAWA base.ec official.ec buyshop.jp fashionstore.jp handcrafted.jp kawaiishop.jp supersale.jp theshop.jp shopselect.net base.shop // BeagleBoard.org Foundation : https://beagleboard.org // Submitted by Jason Kridner beagleboard.io // Bear Blog : https://bearblog.dev // Submitted by Herman Martinus bearblog.dev // Beget LLC : https://beget.com // Submitted by Lev Nekrasov & Nikita Radchenko *.beget.app *.begetcdn.cloud // Besties : https://besties.house // Submitted by Hazel Cora pages.gay // BinaryLane : http://www.binarylane.com // Submitted by Nathan O'Sullivan bnr.la // Bitbucket : http://bitbucket.org // Submitted by Andy Ortlieb bitbucket.io // Blackbaud, Inc. : https://www.blackbaud.com // Submitted by Paul Crowder blackbaudcdn.net // Blatech : http://www.blatech.net // Submitted by Luke Bratch of.je // Block, Inc. : https://block.xyz // Submitted by Jonathan Boice square.site // Blue Bite, LLC : https://bluebite.com // Submitted by Joshua Weiss bluebite.io // Boomla : https://boomla.com // Submitted by Tibor Halter boomla.net // Boutir : https://www.boutir.com // Submitted by Eric Ng Ka Ka boutir.com // Boxfuse : https://boxfuse.com // Submitted by Axel Fontaine boxfuse.io // bplaced : https://www.bplaced.net/ // Submitted by Miroslav Bozic square7.ch bplaced.com bplaced.de square7.de bplaced.net square7.net // Brave : https://brave.com // Submitted by Andrea Brancaleoni brave.app *.s.brave.app brave.dev *.s.brave.dev brave.io *.s.brave.io // Brendly : https://brendly.rs // Submitted by Dusan Radovanovic shop.brendly.ba shop.brendly.hr shop.brendly.rs // BrowserSafetyMark // Submitted by Dave Tharp browsersafetymark.io // BRS Media : https://brsmedia.com/ // Submitted by Gavin Brown radio.am radio.fm // Bubble : https://bubble.io/ // Submitted by Merlin Zhao cdn.bubble.io bubbleapps.io // bwCloud-OS : https://bwcloud-os.de/ // Submitted by Klara Mall *.bwcloud-os-instance.de // Bytemark Hosting : https://www.bytemark.co.uk // Submitted by Paul Cammish uk0.bigv.io dh.bytemark.co.uk vm.bytemark.co.uk // Caf.js Labs LLC : https://www.cafjs.com // Submitted by Antonio Lain cafjs.com // Canva Pty Ltd : https://canva.com/ // Submitted by Joel Aquilina canva-apps.cn my.canvasite.cn canva-apps.com canva-hosted-embed.com canvacode.com rice-labs.com canva.run my.canva.site // Carrd : https://carrd.co // Submitted by AJ drr.ac uwu.ai carrd.co crd.co ju.mp // CDDO : https://www.gov.uk/guidance/get-an-api-domain-on-govuk // Submitted by Jamie Tanna api.gov.uk // CDN77.com : http://www.cdn77.com // Submitted by Jan Krpes cdn77-storage.com rsc.contentproxy9.cz r.cdn77.net cdn77-ssl.net c.cdn77.org rsc.cdn77.org ssl.origin.cdn77-secure.org // CentralNic : https://teaminternet.com/ // Submitted by registry za.bz br.com cn.com de.com eu.com jpn.com mex.com ru.com sa.com uk.com us.com za.com com.de gb.net hu.net jp.net se.net uk.net ae.org com.se // Cityhost LLC : https://cityhost.ua // Submitted by Maksym Rivtin cx.ua // Civilized Discourse Construction Kit, Inc. : https://www.discourse.org/ // Submitted by Rishabh Nambiar, Michael Brown, Rafael dos Santos Silva discourse.diy discourse.group discourse.team // Clerk : https://www.clerk.dev // Submitted by Colin Sidoti clerk.app clerkstage.app *.lcl.dev *.lclstage.dev *.stg.dev *.stgstage.dev // Clever Cloud : https://www.clever-cloud.com/ // Submitted by Quentin Adam cleverapps.cc *.services.clever-cloud.com cleverapps.io cleverapps.tech // ClickRising : https://clickrising.com/ // Submitted by Umut Gumeli clickrising.net // Cloud DNS Ltd : http://www.cloudns.net // Submitted by Aleksander Hristov & Boyan Peychev cloudns.asia cloudns.be cloud-ip.biz cloudns.biz cloud-ip.cc cloudns.cc cloudns.ch cloudns.cl cloudns.club abrdns.com dnsabr.com ip-ddns.com cloudns.cx cloudns.eu cloudns.in cloudns.info ddns-ip.net dns-cloud.net dns-dynamic.net cloudns.nz cloudns.org ip-dynamic.org cloudns.ph cloudns.pro cloudns.pw cloudns.us // Cloud66 : https://www.cloud66.com/ // Submitted by Khash Sajadi c66.me cloud66.ws // CloudAccess.net : https://www.cloudaccess.net/ // Submitted by Pawel Panek jdevcloud.com wpdevcloud.com cloudaccess.host freesite.host cloudaccess.net // Cloudbees, Inc. : https://www.cloudbees.com/ // Submitted by Mohideen Shajith cloudbeesusercontent.io // Cloudera, Inc. : https://www.cloudera.com/ // Submitted by Kedarnath Waikar *.cloudera.site // Cloudflare, Inc. : https://www.cloudflare.com/ // Submitted by Cloudflare Team cloudflare.app cf-ipfs.com cloudflare-ipfs.com trycloudflare.com pages.dev r2.dev workers.dev cloudflare.net cdn.cloudflare.net cdn.cloudflareanycast.net cdn.cloudflarecn.net cdn.cloudflareglobal.net // cloudscale.ch AG : https://www.cloudscale.ch/ // Submitted by Gaudenz Steinlin cust.cloudscale.ch objects.lpg.cloudscale.ch objects.rma.cloudscale.ch lpg.objectstorage.ch rma.objectstorage.ch // Clovyr : https://clovyr.io // Submitted by Patrick Nielsen wnext.app // CNPY : https://cnpy.gdn // Submitted by Angelo Gladding cnpy.gdn // Co & Co : https://co-co.nl/ // Submitted by Govert Versluis *.otap.co // co.ca : http://registry.co.ca/ co.ca // co.com Registry, LLC : https://registry.co.com // Submitted by Gavin Brown co.com // Codeberg e. V. : https://codeberg.org // Submitted by Moritz Marquardt codeberg.page // CodeSandbox B.V. : https://codesandbox.io // Submitted by Ives van Hoorne csb.app preview.csb.app // CoDNS B.V. co.nl co.no // Cognition AI, Inc. : https://cognition.ai // Submitted by Philip Papurt *.devinapps.com // Combell.com : https://www.combell.com // Submitted by Combell Team webhosting.be prvw.eu hosting-cluster.nl // Contentful GmbH : https://www.contentful.com // Submitted by Contentful Developer Experience Team ctfcloud.net // Convex : https://convex.dev/ // Submitted by James Cowling convex.app convex.cloud eu-west-1.convex.cloud us-east-1.convex.cloud convex.site eu-west-1.convex.site us-east-1.convex.site // Coordination Center for TLD RU and XN--P1AI : https://cctld.ru/en/domains/domens_ru/reserved/ // Submitted by George Georgievsky ac.ru edu.ru gov.ru int.ru mil.ru // CoreSpeed, Inc. : https://corespeed.io // Submitted by CoreSpeed Team corespeed.app // COSIMO GmbH : http://www.cosimo.de // Submitted by Rene Marticke dyn.cosidns.de dnsupdater.de dynamisches-dns.de internet-dns.de l-o-g-i-n.de dynamic-dns.info feste-ip.net knx-server.net static-access.net // Craft Docs Ltd : https://www.craft.do/ // Submitted by Zsombor Fuszenecker craft.me // Craynic, s.r.o. : http://www.craynic.com/ // Submitted by Ales Krajnik realm.cz // Crisp IM SAS : https://crisp.chat/ // Submitted by Baptiste Jamin on.crisp.email // Cryptonomic : https://cryptonomic.net/ // Submitted by Andrew Cady *.cryptonomic.net // cyber_Folks S.A. : https://cyberfolks.pl // Submitted by Bartlomiej Kida cfolks.pl // cyon GmbH : https://www.cyon.ch/ // Submitted by Dominic Luechinger cyon.link cyon.site // Dansk.net : http://www.dansk.net/ // Submitted by Anani Voule biz.dk co.dk firm.dk reg.dk store.dk // dappnode.io : https://dappnode.io/ // Submitted by Abel Boldu / DAppNode Team dyndns.dappnode.io // Dark, Inc. : https://darklang.com // Submitted by Paul Biggar builtwithdark.com darklang.io // DataDetect, LLC. : https://datadetect.com // Submitted by Andrew Banchich demo.datadetect.com instance.datadetect.com // Datawire, Inc : https://www.datawire.io // Submitted by Richard Li edgestack.me // Datto, Inc. : https://www.datto.com/ // Submitted by Philipp Heckel dattolocal.com dattorelay.com dattoweb.com mydatto.com dattolocal.net mydatto.net // ddnss.de : https://www.ddnss.de/ // Submitted by Robert Niedziela ddnss.de dyn.ddnss.de dyndns.ddnss.de dyn-ip24.de dyndns1.de home-webserver.de dyn.home-webserver.de myhome-server.de ddnss.org // Debian : https://www.debian.org/ // Submitted by Peter Palfrader / Debian Sysadmin Team debian.net // Definima : http://www.definima.com/ // Submitted by Maxence Bitterli definima.io definima.net // Deno Land Inc : https://deno.com/ // Submitted by Luca Casonato deno.dev deno-staging.dev deno.net sandbox.deno.net // deSEC : https://desec.io/ // Submitted by Peter Thomassen dedyn.io // Deta : https://www.deta.sh/ // Submitted by Aavash Shrestha deta.app deta.dev // Deuxfleurs : https://deuxfleurs.fr // Submitted by Aeddis Desauw deuxfleurs.eu deuxfleurs.page // Developed Methods LLC : https://methods.dev // Submitted by Patrick Lorio *.at.ply.gg d6.ply.gg joinmc.link playit.plus *.at.playit.plus with.playit.plus // Dfinity Foundation: https://dfinity.org/ // Submitted by Dfinity Team icp0.io *.raw.icp0.io icp1.io *.raw.icp1.io *.icp.net caffeine.site caffeine.xyz // dhosting.pl Sp. z o.o. : https://dhosting.pl/ // Submitted by Szczepan Redzioch mybox.company intouch.email mybox.me mybox.page dfirma.pl dkonto.pl you2.pl // DigitalOcean App Platform : https://www.digitalocean.com/products/app-platform/ // Submitted by Braxton Huggins ondigitalocean.app // DigitalOcean Spaces : https://www.digitalocean.com/products/spaces/ // Submitted by Robin H. Johnson *.digitaloceanspaces.com // DigitalPlat : https://www.digitalplat.org/ // Submitted by Edward Hsing qzz.io us.kg xx.kg dpdns.org // Discord Inc : https://discord.com // Submitted by Sahn Lam discordsays.com discordsez.com // DNS Africa Ltd : https://dns.business // Submitted by Calvin Browne jozi.biz // DNSHE : https://www.dnshe.com // Submitted by DNSHE Team ccwu.cc cc.cd us.ci de5.net // DNShome : https://www.dnshome.de/ // Submitted by Norbert Auler dnshome.de // DotArai : https://www.dotarai.com/ // Submitted by Atsadawat Netcharadsang online.th shop.th // dotScot Domains : https://domains.scot/ // Submitted by DNS Team co.scot me.scot org.scot // DrayTek Corp. : https://www.draytek.com/ // Submitted by Paul Fang drayddns.com // DreamCommerce : https://shoper.pl/ // Submitted by Konrad Kotarba shoparena.pl // DreamHost : http://www.dreamhost.com/ // Submitted by Andrew Farmer dreamhosters.com // Dreamyoungs, Inc. : https://durumis.com // Submitted by Infra Team durumis.com // DuckDNS : http://www.duckdns.org/ // Submitted by Richard Harper duckdns.org // dy.fi : http://dy.fi/ // Submitted by Heikki Hannikainen dy.fi tunk.org // DynDNS.com : http://www.dyndns.com/services/dns/dyndns/ dyndns.biz for-better.biz for-more.biz for-some.biz for-the.biz selfip.biz webhop.biz ftpaccess.cc game-server.cc myphotos.cc scrapping.cc blogdns.com cechire.com dnsalias.com dnsdojo.com doesntexist.com dontexist.com doomdns.com dyn-o-saur.com dynalias.com dyndns-at-home.com dyndns-at-work.com dyndns-blog.com dyndns-free.com dyndns-home.com dyndns-ip.com dyndns-mail.com dyndns-office.com dyndns-pics.com dyndns-remote.com dyndns-server.com dyndns-web.com dyndns-wiki.com dyndns-work.com est-a-la-maison.com est-a-la-masion.com est-le-patron.com est-mon-blogueur.com from-ak.com from-al.com from-ar.com from-ca.com from-ct.com from-dc.com from-de.com from-fl.com from-ga.com from-hi.com from-ia.com from-id.com from-il.com from-in.com from-ks.com from-ky.com from-ma.com from-md.com from-mi.com from-mn.com from-mo.com from-ms.com from-mt.com from-nc.com from-nd.com from-ne.com from-nh.com from-nj.com from-nm.com from-nv.com from-oh.com from-ok.com from-or.com from-pa.com from-pr.com from-ri.com from-sc.com from-sd.com from-tn.com from-tx.com from-ut.com from-va.com from-vt.com from-wa.com from-wi.com from-wv.com from-wy.com getmyip.com gotdns.com hobby-site.com homelinux.com homeunix.com iamallama.com is-a-anarchist.com is-a-blogger.com is-a-bookkeeper.com is-a-bulls-fan.com is-a-caterer.com is-a-chef.com is-a-conservative.com is-a-cpa.com is-a-cubicle-slave.com is-a-democrat.com is-a-designer.com is-a-doctor.com is-a-financialadvisor.com is-a-geek.com is-a-green.com is-a-guru.com is-a-hard-worker.com is-a-hunter.com is-a-landscaper.com is-a-lawyer.com is-a-liberal.com is-a-libertarian.com is-a-llama.com is-a-musician.com is-a-nascarfan.com is-a-nurse.com is-a-painter.com is-a-personaltrainer.com is-a-photographer.com is-a-player.com is-a-republican.com is-a-rockstar.com is-a-socialist.com is-a-student.com is-a-teacher.com is-a-techie.com is-a-therapist.com is-an-accountant.com is-an-actor.com is-an-actress.com is-an-anarchist.com is-an-artist.com is-an-engineer.com is-an-entertainer.com is-certified.com is-gone.com is-into-anime.com is-into-cars.com is-into-cartoons.com is-into-games.com is-leet.com is-not-certified.com is-slick.com is-uberleet.com is-with-theband.com isa-geek.com isa-hockeynut.com issmarterthanyou.com likes-pie.com likescandy.com neat-url.com saves-the-whales.com selfip.com sells-for-less.com sells-for-u.com servebbs.com simple-url.com space-to-rent.com teaches-yoga.com writesthisblog.com ath.cx fuettertdasnetz.de isteingeek.de istmein.de lebtimnetz.de leitungsen.de traeumtgerade.de barrel-of-knowledge.info barrell-of-knowledge.info dyndns.info for-our.info groks-the.info groks-this.info here-for-more.info knowsitall.info selfip.info webhop.info forgot.her.name forgot.his.name at-band-camp.net blogdns.net broke-it.net buyshouses.net dnsalias.net dnsdojo.net does-it.net dontexist.net dynalias.net dynathome.net endofinternet.net from-az.net from-co.net from-la.net from-ny.net gets-it.net ham-radio-op.net homeftp.net homeip.net homelinux.net homeunix.net in-the-band.net is-a-chef.net is-a-geek.net isa-geek.net kicks-ass.net office-on-the.net podzone.net scrapper-site.net selfip.net sells-it.net servebbs.net serveftp.net thruhere.net webhop.net merseine.nu mine.nu shacknet.nu blogdns.org blogsite.org boldlygoingnowhere.org dnsalias.org dnsdojo.org doesntexist.org dontexist.org doomdns.org dvrdns.org dynalias.org dyndns.org go.dyndns.org home.dyndns.org endofinternet.org endoftheinternet.org from-me.org game-host.org gotdns.org hobby-site.org homedns.org homeftp.org homelinux.org homeunix.org is-a-bruinsfan.org is-a-candidate.org is-a-celticsfan.org is-a-chef.org is-a-geek.org is-a-knight.org is-a-linux-user.org is-a-patsfan.org is-a-soxfan.org is-found.org is-lost.org is-saved.org is-very-bad.org is-very-evil.org is-very-good.org is-very-nice.org is-very-sweet.org isa-geek.org kicks-ass.org misconfused.org podzone.org readmyblog.org selfip.org sellsyourhome.org servebbs.org serveftp.org servegame.org stuff-4-sale.org webhop.org better-than.tv dyndns.tv on-the-web.tv worse-than.tv is-by.us land-4-sale.us stuff-4-sale.us dyndns.ws mypets.ws // Dynu.com : https://www.dynu.com/ // Submitted by Sue Ye 1cooldns.com bumbleshrimp.com ddnsfree.com ddnsgeek.com ddnsguru.com dynuddns.com dynuhosting.com giize.com gleeze.com kozow.com loseyourip.com ooguy.com pivohosting.com theworkpc.com wiredbladehosting.com casacam.net dynu.net dynuddns.net mysynology.net opik.net spryt.net accesscam.org camdvr.org freeddns.org mywire.org roxa.org webredirect.org myddns.rocks // dynv6 : https://dynv6.com // Submitted by Dominik Menke dynv6.net // E4YOU spol. s.r.o. : https://e4you.cz/ // Submitted by Vladimir Dudr e4.cz // Easypanel : https://easypanel.io // Submitted by Andrei Canta easypanel.app easypanel.host // EasyWP : https://www.easywp.com // Submitted by *.ewp.live // eDirect Corp. : https://hosting.url.com.tw/ // Submitted by C.S. chang twmail.cc twmail.net twmail.org mymailer.com.tw url.tw // Electromagnetic Field : https://www.emfcamp.org // Submitted by at.emf.camp // Elefunc, Inc. : https://elefunc.com // Submitted by Cetin Sert rt.ht // Elementor : Elementor Ltd. // Submitted by Anton Barkan elementor.cloud elementor.cool // Emergent : https://emergent.sh // Submitted by Emergent Security Team emergent.cloud preview.emergentagent.com emergent.host // Enalean SAS : https://www.enalean.com // Submitted by Enalean Security Team mytuleap.com tuleap-partners.com // Encoretivity AB : https://encore.cloud // Submitted by André Eriksson encr.app frontend.encr.app encoreapi.com lp.dev api.lp.dev objects.lp.dev // encoway GmbH : https://www.encoway.de // Submitted by Marcel Daus eu.encoway.cloud // EU.org : https://eu.org/ // Submitted by Pierre Beyssac eu.org al.eu.org asso.eu.org at.eu.org au.eu.org be.eu.org bg.eu.org ca.eu.org cd.eu.org ch.eu.org cn.eu.org cy.eu.org cz.eu.org de.eu.org dk.eu.org edu.eu.org ee.eu.org es.eu.org fi.eu.org fr.eu.org gr.eu.org hr.eu.org hu.eu.org ie.eu.org il.eu.org in.eu.org int.eu.org is.eu.org it.eu.org jp.eu.org kr.eu.org lt.eu.org lu.eu.org lv.eu.org me.eu.org mk.eu.org mt.eu.org my.eu.org net.eu.org ng.eu.org nl.eu.org no.eu.org nz.eu.org pl.eu.org pt.eu.org ro.eu.org ru.eu.org se.eu.org si.eu.org sk.eu.org tr.eu.org uk.eu.org us.eu.org // Eurobyte : https://eurobyte.ru // Submitted by Evgeniy Subbotin eurodir.ru // Evennode : http://www.evennode.com/ // Submitted by Michal Kralik eu-1.evennode.com eu-2.evennode.com eu-3.evennode.com eu-4.evennode.com us-1.evennode.com us-2.evennode.com us-3.evennode.com us-4.evennode.com // Evervault : https://evervault.com // Submitted by Hannah Neary relay.evervault.app relay.evervault.dev // Expo : https://expo.dev/ // Submitted by James Ide expo.app staging.expo.app // Fabrica Technologies, Inc. : https://www.fabrica.dev/ // Submitted by Eric Jiang onfabrica.com // FAITID : https://faitid.org/ // Submitted by Maxim Alzoba // https://www.flexireg.net/stat_info ru.net adygeya.ru bashkiria.ru bir.ru cbg.ru com.ru dagestan.ru grozny.ru kalmykia.ru kustanai.ru marine.ru mordovia.ru msk.ru mytis.ru nalchik.ru nov.ru pyatigorsk.ru spb.ru vladikavkaz.ru vladimir.ru abkhazia.su adygeya.su aktyubinsk.su arkhangelsk.su armenia.su ashgabad.su azerbaijan.su balashov.su bashkiria.su bryansk.su bukhara.su chimkent.su dagestan.su east-kazakhstan.su exnet.su georgia.su grozny.su ivanovo.su jambyl.su kalmykia.su kaluga.su karacol.su karaganda.su karelia.su khakassia.su krasnodar.su kurgan.su kustanai.su lenug.su mangyshlak.su mordovia.su msk.su murmansk.su nalchik.su navoi.su north-kazakhstan.su nov.su obninsk.su penza.su pokrovsk.su sochi.su spb.su tashkent.su termez.su togliatti.su troitsk.su tselinograd.su tula.su tuva.su vladikavkaz.su vladimir.su vologda.su // Fancy Bits, LLC : http://getchannels.com // Submitted by Aman Gupta channelsdvr.net u.channelsdvr.net // Fastly Inc. : http://www.fastly.com/ // Submitted by Fastly Security edgecompute.app fastly-edge.com fastly-terrarium.com freetls.fastly.net map.fastly.net a.prod.fastly.net global.prod.fastly.net a.ssl.fastly.net b.ssl.fastly.net global.ssl.fastly.net fastlylb.net map.fastlylb.net // Fastmail : https://www.fastmail.com/ // Submitted by Marc Bradshaw *.user.fm // FASTVPS EESTI OU : https://fastvps.ru/ // Submitted by Likhachev Vasiliy fastvps-server.com fastvps.host myfast.host fastvps.site myfast.space // FearWorks Media Ltd. : https://fearworksmedia.co.uk // Submitted by Keith Fairley conn.uk copro.uk hosp.uk // Fedora : https://fedoraproject.org/ // Submitted by Patrick Uiterwijk fedorainfracloud.org fedorapeople.org cloud.fedoraproject.org app.os.fedoraproject.org app.os.stg.fedoraproject.org // Fermax : https://fermax.com/ // Submitted by Koen Van Isterdael mydobiss.com // FH Muenster : https://www.fh-muenster.de // Submitted by Robin Naundorf fh-muenster.io // Figma : https://www.figma.com // Submitted by Nick Frost figma.site figma-gov.site preview.site // Filegear Inc. : https://www.filegear.com // Submitted by Jason Zhu filegear.me // Firebase, Inc. // Submitted by Chris Raynor firebaseapp.com // FlashDrive : https://flashdrive.io // Submitted by Eric Chan fldrv.com // Fleek Labs Inc : https://fleek.xyz // Submitted by Parsa Ghadimi on-fleek.app // FlutterFlow : https://flutterflow.io // Submitted by Anton Emelyanov flutterflow.app // fly.io : https://fly.io // Submitted by Kurt Mackey sprites.app fly.dev // FoundryLabs, Inc : https://e2b.dev/ // Submitted by Jiri Sveceny e2b.app // Framer : https://www.framer.com // Submitted by Koen Rouwhorst framer.ai framer.app framercanvas.com framer.media framer.photos framer.website framer.wiki // Frederik Braun : https://frederik-braun.com // Submitted by Frederik Braun *.0e.vc // Freebox : http://www.freebox.fr // Submitted by Romain Fliedel freebox-os.com freeboxos.com fbx-os.fr fbxos.fr freebox-os.fr freeboxos.fr // freedesktop.org : https://www.freedesktop.org // Submitted by Daniel Stone freedesktop.org // freemyip.com : https://freemyip.com // Submitted by Cadence freemyip.com // Frusky MEDIA&PR : https://www.frusky.de // Submitted by Victor Pupynin *.frusky.de // FunkFeuer - Verein zur Förderung freier Netze : https://www.funkfeuer.at // Submitted by Daniel A. Maierhofer wien.funkfeuer.at // Future Versatile Group. : https://www.fvg-on.net/ // T.Kabu daemon.asia dix.asia mydns.bz 0am.jp 0g0.jp 0j0.jp 0t0.jp mydns.jp pgw.jp wjg.jp keyword-on.net live-on.net server-on.net mydns.tw mydns.vc // Futureweb GmbH : https://www.futureweb.at // Submitted by Andreas Schnederle-Wagner *.futurecms.at *.ex.futurecms.at *.in.futurecms.at futurehosting.at futuremailing.at *.ex.ortsinfo.at *.kunden.ortsinfo.at *.statics.cloud // Gadget Software Inc. : https://gadget.dev // Submitted by Harry Brundage gadget.app gadget.host // GCom Internet : https://www.gcom.net.au // Submitted by Leo Julius aliases121.com // GDS : https://www.gov.uk/service-manual/technology/managing-domain-names // Submitted by Stephen Ford campaign.gov.uk service.gov.uk independent-commission.uk independent-inquest.uk independent-inquiry.uk independent-panel.uk independent-review.uk public-inquiry.uk royal-commission.uk // Gehirn Inc. : https://www.gehirn.co.jp/ // Submitted by Kohei YOSHIDA gehirn.ne.jp usercontent.jp // Gentlent, Inc. : https://www.gentlent.com // Submitted by Tom Klein gentapps.com gentlentapis.com cdn-edges.net // GignoSystemJapan : http://gsj.bz // Submitted by GignoSystemJapan gsj.bz // GitBook Inc. : https://www.gitbook.com/ // Submitted by Samy Pesse gitbook.io // GitHub, Inc. // Submitted by Patrick Toomey github.app githubusercontent.com githubpreview.dev github.io // GitLab, Inc. : https://about.gitlab.com/ // Submitted by Alex Hanselka gitlab.io // Gitplac.si : https://gitplac.si // Submitted by Aljaž Starc gitapp.si gitpage.si // Global NOG Alliance : https://nogalliance.org/ // Submitted by Sander Steffann nog.community // Globe Hosting SRL : https://www.globehosting.com/ // Submitted by Gavin Brown co.ro shop.ro // GMO Pepabo, Inc. : https://pepabo.com/ // Submitted by Hosting Div lolipop.io angry.jp babyblue.jp babymilk.jp backdrop.jp bambina.jp bitter.jp blush.jp boo.jp boy.jp boyfriend.jp but.jp candypop.jp capoo.jp catfood.jp cheap.jp chicappa.jp chillout.jp chips.jp chowder.jp chu.jp ciao.jp cocotte.jp coolblog.jp cranky.jp cutegirl.jp daa.jp deca.jp deci.jp digick.jp egoism.jp fakefur.jp fem.jp flier.jp floppy.jp fool.jp frenchkiss.jp girlfriend.jp girly.jp gloomy.jp gonna.jp greater.jp hacca.jp heavy.jp her.jp hiho.jp hippy.jp holy.jp hungry.jp icurus.jp itigo.jp jellybean.jp kikirara.jp kill.jp kilo.jp kuron.jp littlestar.jp lolipopmc.jp lolitapunk.jp lomo.jp lovepop.jp lovesick.jp main.jp mods.jp mond.jp mongolian.jp moo.jp namaste.jp nikita.jp nobushi.jp noor.jp oops.jp parallel.jp parasite.jp pecori.jp peewee.jp penne.jp pepper.jp perma.jp pigboat.jp pinoko.jp punyu.jp pupu.jp pussycat.jp pya.jp raindrop.jp readymade.jp sadist.jp schoolbus.jp secret.jp staba.jp stripper.jp sub.jp sunnyday.jp thick.jp tonkotsu.jp under.jp upper.jp velvet.jp verse.jp versus.jp vivian.jp watson.jp weblike.jp whitesnow.jp zombie.jp heteml.net // GoDaddy Registry : https://registry.godaddy // Submitted by Rohan Durrant graphic.design // GoIP DNS Services : http://www.goip.de // Submitted by Christian Poulter goip.de // Google, Inc. // Submitted by Shannon McCabe *.hosted.app *.run.app *.mtls.run.app web.app *.0emm.com appspot.com *.r.appspot.com blogspot.com codespot.com googleapis.com googlecode.com pagespeedmobilizer.com withgoogle.com withyoutube.com *.gateway.dev cloud.goog translate.goog *.usercontent.goog cloudfunctions.net // Goupile : https://goupile.fr // Submitted by Niels Martignene goupile.fr // GOV.UK Pay : https://www.payments.service.gov.uk/ // Submitted by Richard Baker pymnt.uk // GOV.UK Platform as a Service : https://www.cloud.service.gov.uk/ // Submitted by Tom Whitwell cloudapps.digital london.cloudapps.digital // Government of the Netherlands : https://www.government.nl // Submitted by gov.nl // Grafana Labs : https://grafana.com/ // Submitted by Platform Engineering grafana-dev.net // GrayJay Web Solutions Inc. : https://grayjaysports.ca // Submitted by Matt Yamkowy grayjayleagues.com // Grebedoc : https://grebedoc.dev // Submitted by Catherine Zotova grebedoc.dev // GünstigBestellen : https://günstigbestellen.de // Submitted by Furkan Akkoc günstigbestellen.de günstigliefern.de // GV.UY : https://nic.gv.uy // Submitted by cheng gv.uy // Hackclub Nest : https://hackclub.app // Submitted by Cyteon hackclub.app // Häkkinen.fi : https://www.häkkinen.fi/ // Submitted by Eero Häkkinen häkkinen.fi // Hashbang : https://hashbang.sh hashbang.sh // Hasura : https://hasura.io // Submitted by Shahidh K Muhammed hasura.app hasura-app.io // Hatena Co., Ltd. : https://hatena.co.jp // Submitted by Masato Nakamura hatenablog.com hatenadiary.com hateblo.jp hatenablog.jp hatenadiary.jp hatenadiary.org // Heilbronn University of Applied Sciences - Faculty Informatics (GitLab Pages) : https://www.hs-heilbronn.de // Submitted by Richard Zowalla pages.it.hs-heilbronn.de pages-research.it.hs-heilbronn.de // HeiyuSpace : https://lazycat.cloud // Submitted by Xia Bin heiyu.space // Helio Networks : https://heliohost.org // Submitted by Ben Frede helioho.st heliohost.us // Hepforge : https://www.hepforge.org // Submitted by David Grellscheid hepforge.org // Hercules : https://hercules.app // Submitted by Brendan Falk onhercules.app hercules-app.com hercules-dev.com // Heroku : https://www.heroku.com/ // Submitted by Shumon Huque herokuapp.com // Heyflow : https://www.heyflow.com // Submitted by Mirko Nitschke heyflow.page heyflow.site // Hibernating Rhinos // Submitted by Oren Eini ravendb.cloud ravendb.community development.run ravendb.run // HiDNS : https://www.hidoha.net // Submitted by ifeng hidns.co hidns.vip // home.pl S.A. : https://home.pl // Submitted by Krzysztof Wolski homesklep.pl // Homebase : https://homebase.id/ // Submitted by Jason Babo *.kin.one *.id.pub *.kin.pub // Hoplix : https://www.hoplix.com // Submitted by Danilo De Franco hoplix.shop // HOSTBIP REGISTRY : https://www.hostbip.com/ // Submitted by Atanunu Igbunuroghene orx.biz biz.ng co.biz.ng dl.biz.ng go.biz.ng lg.biz.ng on.biz.ng col.ng firm.ng gen.ng ltd.ng ngo.ng plc.ng // HostyHosting : https://hostyhosting.com hostyhosting.io // Hugging Face : https://huggingface.co // Submitted by Eliott Coyac hf.space static.hf.space // Hypernode B.V. : https://www.hypernode.com/ // Submitted by Cipriano Groenendal hypernode.io // I-O DATA DEVICE, INC. : http://www.iodata.com/ // Submitted by Yuji Minagawa iobb.net // i-registry s.r.o. : http://www.i-registry.cz/ // Submitted by Martin Semrad co.cz // Ici la Lune : http://www.icilalune.com/ // Submitted by Simon Morvan *.moonscale.io moonscale.net // iDOT Services Limited : http://www.domain.gr.com // Submitted by Gavin Brown gr.com // iki.fi // Submitted by Hannu Aronsson iki.fi // iliad italia : https://www.iliad.it // Submitted by Marios Makassikis ibxos.it iliadboxos.it // Imagine : https://imagine.dev // Submitted by Steven Nguyen imagine.diy imagine-proxy.work // Incsub, LLC : https://incsub.com/ // Submitted by Aaron Edwards smushcdn.com wphostedmail.com wpmucdn.com tempurl.host wpmudev.host // Individual Network Berlin e.V. : https://www.in-berlin.de/ // Submitted by Christian Seitz dyn-berlin.de in-berlin.de in-brb.de in-butter.de in-dsl.de in-vpn.de in-dsl.net in-vpn.net in-dsl.org in-vpn.org // Inferno Communications : https://inferno.co.uk // Submitted by Connor McFarlane oninferno.net // info.at : http://www.info.at/ biz.at info.at // info.cx : http://info.cx // Submitted by June Slater info.cx // Interlegis : http://www.interlegis.leg.br // Submitted by Gabriel Ferreira ac.leg.br al.leg.br am.leg.br ap.leg.br ba.leg.br ce.leg.br df.leg.br es.leg.br go.leg.br ma.leg.br mg.leg.br ms.leg.br mt.leg.br pa.leg.br pb.leg.br pe.leg.br pi.leg.br pr.leg.br rj.leg.br rn.leg.br ro.leg.br rr.leg.br rs.leg.br sc.leg.br se.leg.br sp.leg.br to.leg.br // intermetrics GmbH : https://pixolino.com/ // Submitted by Wolfgang Schwarz pixolino.com // Internet-Pro, LLP : https://netangels.ru/ // Submitted by Vasiliy Sheredeko na4u.ru // Inventor Services : https://inventor.gg/ // Submitted by Inventor Team botdash.app botdash.dev botdash.gg botdash.net botda.sh botdash.xyz // IONOS SE : https://www.ionos.com/ // IONOS Group SE : https://www.ionos-group.com/ // Submitted by Henrik Willert apps-1and1.com live-website.com webspace-host.com apps-1and1.net websitebuilder.online app-ionos.space // iopsys software solutions AB : https://iopsys.eu/ // Submitted by Roman Azarenko iopsys.se // IPFS Project : https://ipfs.tech/ // Submitted by Interplanetary Shipyard *.inbrowser.dev *.dweb.link *.inbrowser.link // IPiFony Systems, Inc. : https://www.ipifony.com/ // Submitted by Matthew Hardeman ipifony.net // ir.md : https://nic.ir.md // Submitted by Ali Soizi ir.md // is-a-good.dev : https://is-a-good.dev // Submitted by William Harrison is-a-good.dev // IServ GmbH : https://iserv.de // Submitted by Kim Brodowski iservschule.de mein-iserv.de schuldock.de schulplattform.de schulserver.de test-iserv.de iserv.dev iserv.host // Ispmanager : https://www.ispmanager.com/ // Submitted by Ispmanager infrastructure team ispmanager.name // Jelastic, Inc. : https://jelastic.com/ // Submitted by Ihor Kolodyuk mel.cloudlets.com.au cloud.interhostsolutions.be alp1.ae.flow.ch appengine.flow.ch es-1.axarnet.cloud diadem.cloud vip.jelastic.cloud jele.cloud it1.eur.aruba.jenv-aruba.cloud it1.jenv-aruba.cloud keliweb.cloud cs.keliweb.cloud oxa.cloud tn.oxa.cloud uk.oxa.cloud primetel.cloud uk.primetel.cloud ca.reclaim.cloud uk.reclaim.cloud us.reclaim.cloud ch.trendhosting.cloud de.trendhosting.cloud jele.club dopaas.com paas.hosted-by-previder.com rag-cloud.hosteur.com rag-cloud-ch.hosteur.com jcloud.ik-server.com jcloud-ver-jpc.ik-server.com demo.jelastic.com paas.massivegrid.com jed.wafaicloud.com ryd.wafaicloud.com j.scaleforce.com.cy jelastic.dogado.eu fi.cloudplatform.fi demo.datacenter.fi paas.datacenter.fi jele.host mircloud.host paas.beebyte.io sekd1.beebyteapp.io jele.io jc.neen.it jcloud.kz cloudjiffy.net fra1-de.cloudjiffy.net west1-us.cloudjiffy.net jls-sto1.elastx.net jls-sto2.elastx.net jls-sto3.elastx.net fr-1.paas.massivegrid.net lon-1.paas.massivegrid.net lon-2.paas.massivegrid.net ny-1.paas.massivegrid.net ny-2.paas.massivegrid.net sg-1.paas.massivegrid.net jelastic.saveincloud.net nordeste-idc.saveincloud.net j.scaleforce.net sdscloud.pl unicloud.pl mircloud.ru enscaled.sg jele.site jelastic.team orangecloud.tn j.layershift.co.uk phx.enscaled.us mircloud.us // Jino : https://www.jino.ru // Submitted by Sergey Ulyashin myjino.ru *.hosting.myjino.ru *.landing.myjino.ru *.spectrum.myjino.ru *.vps.myjino.ru // Jotelulu S.L. : https://jotelulu.com // Submitted by Daniel Fariña jote.cloud jotelulu.cloud eu1-plenit.com la1-plenit.com us1-plenit.com // JouwWeb B.V. : https://www.jouwweb.nl // Submitted by Camilo Sperberg webadorsite.com jouwweb.site // Joyent : https://www.joyent.com/ // Submitted by Brian Bennett *.triton.zone // JS.ORG : http://dns.js.org // Submitted by Stefan Keim js.org // KaasHosting : http://www.kaashosting.nl/ // Submitted by Wouter Bakker kaas.gg khplay.nl // Kapsi : https://kapsi.fi // Submitted by Tomi Juntunen kapsi.fi // KataBump : https://katabump.com // Submitted by Thibault Lapeyre kdns.fr // Katholieke Universiteit Leuven : https://www.kuleuven.be // Submitted by Abuse KU Leuven ezproxy.kuleuven.be kuleuven.cloud // Keenetic : https://keenetic.com // Submitted by Alexey Nikitin keenetic.io keenetic.link keenetic.name keenetic.pro // Kevin Service : https://kevsrv.me // Submitted by Kevin Service Team ae.kg // Keyweb AG : https://www.keyweb.de // Submitted by Martin Dannehl keymachine.de // Kilo Code, Inc. : https://kilo.ai // Submitted by Remon Oldenbeuving kiloapps.ai kiloapps.io // KingHost : https://king.host // Submitted by Felipe Keller Braz kinghost.net uni5.net // KnightPoint Systems, LLC : http://www.knightpoint.com/ // Submitted by Roy Keene knightpoint.systems // KoobinEvent, SL : https://www.koobin.com // Submitted by Iván Oliva koobin.events // Krellian Ltd. : https://krellian.com // Submitted by Ben Francis webthings.io krellian.net // KUROKU LTD : https://kuroku.ltd/ // Submitted by DisposaBoy oya.to // KV GmbH : https://www.nic.co.de // Submitted by KV GmbH // Abuse reports to co.de // Laravel Holdings, Inc. : https://laravel.com // Submitted by André Valentin & James Brooks shiptoday.app shiptoday.build laravel.cloud on-forge.com on-vapor.com // LCube - Professional hosting e.K. : https://www.lcube-webhosting.de // Submitted by Lars Laehn git-repos.de lcube-server.de svn-repos.de // Leadpages : https://www.leadpages.net // Submitted by Greg Dallavalle leadpages.co lpages.co lpusercontent.com // Leapcell : https://leapcell.io/ // Submitted by Leapcell Team leapcell.app leapcell.dev leapcell.online // Liara : https://liara.ir // Submitted by Amirhossein Badinloo liara.run iran.liara.run // libp2p project : https://libp2p.io // Submitted by Interplanetary Shipyard libp2p.direct // Libre IT Ltd : https://libre.nz // Submitted by Tomas Maggio runcontainers.dev // Lifetime Hosting : https://Lifetime.Hosting/ // Submitted by Mike Fillator co.business co.education co.events co.financial co.network co.place co.technology // linkyard ldt : https://www.linkyard.ch/ // Submitted by Mario Siegenthaler linkyard-cloud.ch linkyard.cloud // Linode : https://linode.com // Submitted by members.linode.com *.nodebalancer.linode.com *.linodeobjects.com ip.linodeusercontent.com // LiquidNet Ltd : http://www.liquidnetlimited.com/ // Submitted by Victor Velchev we.bs // Listen53 : https://www.l53.net // Submitted by Gerry Keh filegear-sg.me ggff.net // Localcert : https://localcert.dev // Submitted by Lann Martin *.user.localcert.dev // Localtonet : https://localtonet.com/ // Submitted by Burak Isleyici localtonet.com *.localto.net // Lodz University of Technology LODMAN regional domains : https://www.man.lodz.pl/dns // Submitted by Piotr Wilk lodz.pl pabianice.pl plock.pl sieradz.pl skierniewice.pl zgierz.pl // Log'in Line : https://www.loginline.com/ // Submitted by Rémi Mach loginline.app loginline.dev loginline.io loginline.services loginline.site // Lõhmus Family, The : https://lohmus.me/ // Submitted by Heiki Lõhmus lohmus.me // Lovable : https://lovable.dev // Submitted by Fabian Hedin lovable.app lovableproject.com lovable.run lovable.sh // LubMAN UMCS Sp. z o.o : https://lubman.pl/ // Submitted by Ireneusz Maliszewski krasnik.pl leczna.pl lubartow.pl lublin.pl poniatowa.pl swidnik.pl // Lug.org.uk : https://lug.org.uk // Submitted by Jon Spriggs glug.org.uk lug.org.uk lugs.org.uk // Lukanet Ltd : https://lukanet.com // Submitted by Anton Avramov barsy.bg barsy.club barsycenter.com barsyonline.com barsy.de barsy.dev barsy.eu barsy.gr barsy.in barsy.info barsy.io barsy.me barsy.menu barsyonline.menu barsy.mobi barsy.net barsy.online barsy.org barsy.pro barsy.pub barsy.ro barsy.rs barsy.shop barsyonline.shop barsy.site barsy.store barsy.support barsy.uk barsy.co.uk barsyonline.co.uk // Lutra : https://lutra.ai // Submitted by Joshua Newman *.lutrausercontent.com // Luyani Inc. : https://luyani.com/ // Submitted by Umut Gumeli luyani.app luyani.net // Magento Commerce // Submitted by Damien Tournoud *.magentosite.cloud // Magic Patterns : https://www.magicpatterns.com // Submitted by Teddy Ni magicpatterns.app magicpatternsapp.com // Mail.Ru Group : https://hb.cldmail.ru // Submitted by Ilya Zaretskiy hb.cldmail.ru // MathWorks : https://www.mathworks.com/ // Submitted by Emily Reed matlab.cloud modelscape.com mwcloudnonprod.com polyspace.com // May First - People Link : https://mayfirst.org/ // Submitted by Jamie McClelland mayfirst.info mayfirst.org // McHost : https://mchost.ru // Submitted by Evgeniy Subbotin mcdir.me mcdir.ru vps.mcdir.ru mcpre.ru // Mediatech : https://mediatech.by // Submitted by Evgeniy Kozhuhovskiy mediatech.by mediatech.dev // Medicom Health : https://medicomhealth.com // Submitted by Michael Olson hra.health // MedusaJS, Inc : https://medusajs.com/ // Submitted by Stevche Radevski medusajs.app // Memset hosting : https://www.memset.com // Submitted by Tom Whitwell miniserver.com memset.net // Messerli Informatik AG : https://www.messerli.ch/ // Submitted by Ruben Schmidmeister messerli.app // Meta Platforms, Inc. : https://meta.com/ // Submitted by Jacob Cordero atmeta.com apps.fbsbx.com // MetaCentrum, CESNET z.s.p.o. : https://www.metacentrum.cz/en/ // Submitted by ZdenÄ›k Å ustr and Radim JanÄa *.cloud.metacentrum.cz custom.metacentrum.cz flt.cloud.muni.cz usr.cloud.muni.cz // Meteor Development Group : https://www.meteor.com/hosting // Submitted by Pierre Carrier meteorapp.com eu.meteorapp.com // Michau Enterprises Limited : http://www.co.pl/ co.pl // Microsoft Corporation : http://microsoft.com // Submitted by Public Suffix List Admin // Managed by Corporate Domains // Microsoft Azure : https://home.azure *.azurecontainer.io azure-api.net azure-mobile.net azureedge.net azurefd.net azurestaticapps.net 1.azurestaticapps.net 2.azurestaticapps.net 3.azurestaticapps.net 4.azurestaticapps.net 5.azurestaticapps.net 6.azurestaticapps.net 7.azurestaticapps.net centralus.azurestaticapps.net eastasia.azurestaticapps.net eastus2.azurestaticapps.net westeurope.azurestaticapps.net westus2.azurestaticapps.net azurewebsites.net cloudapp.net trafficmanager.net blob.core.usgovcloudapi.net file.core.usgovcloudapi.net web.core.usgovcloudapi.net servicebus.usgovcloudapi.net usgovcloudapp.net usgovtrafficmanager.net blob.core.windows.net file.core.windows.net web.core.windows.net servicebus.windows.net azure-api.us azurewebsites.us // MikroTik : https://mikrotik.com // Submitted by MikroTik SysAdmin Team routingthecloud.com sn.mynetname.net routingthecloud.net routingthecloud.org // Million Software, Inc : https://million.dev/ // Submitted by Rayhan Noufal Arayilakath same-app.com same-preview.com // minion.systems : http://minion.systems // Submitted by Robert Böttinger csx.cc // Miren, Inc. : https://miren.dev // Submitted by Miren Product Team miren.app miren.systems // Mittwald CM Service GmbH & Co. KG : https://mittwald.de // Submitted by Marco Rieger mydbserver.com webspaceconfig.de mittwald.info mittwaldserver.info typo3server.info project.space // Mocha : https://getmocha.com // Submitted by Ben Reinhart mocha.app mochausercontent.com mocha-sandbox.dev // MODX Systems LLC : https://modx.com // Submitted by Elizabeth Southwell modx.dev // Mozilla Foundation : https://mozilla.org/ // Submitted by glob bmoattachments.org // MSK-IX : https://www.msk-ix.ru/ // Submitted by Khannanov Roman net.ru org.ru pp.ru // MyOwn srl : https://www.myown.eu/ // Submitted by Stephane Bouvard my.be // Mythic Beasts : https://www.mythic-beasts.com // Submitted by Paul Cammish hostedpi.com caracal.mythic-beasts.com customer.mythic-beasts.com fentiger.mythic-beasts.com lynx.mythic-beasts.com ocelot.mythic-beasts.com oncilla.mythic-beasts.com onza.mythic-beasts.com sphinx.mythic-beasts.com vs.mythic-beasts.com x.mythic-beasts.com yali.mythic-beasts.com cust.retrosnub.co.uk // Nabu Casa : https://www.nabucasa.com // Submitted by Paulus Schoutsen ui.nabu.casa // Needle Tools GmbH : https://needle.tools // Submitted by Felix Herbst needle.run // Neo : https://www.neo.space // Submitted by Ankit Kulkarni co.site // Net at Work Gmbh : https://www.netatwork.de // Submitted by Jan Jaeschke cloud.nospamproxy.com o365.cloud.nospamproxy.com // Net libre : https://www.netlib.re // Submitted by Philippe PITTOLI netlib.re // Netlify : https://www.netlify.com // Submitted by Jessica Parsons netlify.app // Neustar Inc. // Submitted by Trung Tran 4u.com // NFSN, Inc. : https://www.NearlyFreeSpeech.NET/ // Submitted by Jeff Wheelhouse nfshost.com // NFT.Storage : https://nft.storage/ // Submitted by Vasco Santos or ipfs.nftstorage.link // NGO.US Registry : https://nic.ngo.us // Submitted by Alstra Solutions Ltd. Networking Team ngo.us // ngrok : https://ngrok.com/ // Submitted by Alan Shreve ngrok.app ngrok-free.app ngrok.dev ngrok-free.dev ngrok.io ap.ngrok.io au.ngrok.io eu.ngrok.io in.ngrok.io jp.ngrok.io sa.ngrok.io us.ngrok.io ngrok.pizza ngrok.pro // Nicolaus Copernicus University in Torun - MSK TORMAN : https://www.man.torun.pl torun.pl // Nimbus Hosting Ltd. : https://www.nimbushosting.co.uk/ // Submitted by Nicholas Ford nh-serv.co.uk nimsite.uk // No-IP.com : https://noip.com/ // Submitted by Deven Reza mmafan.biz myftp.biz no-ip.biz no-ip.ca fantasyleague.cc gotdns.ch 3utilities.com blogsyte.com ciscofreak.com damnserver.com ddnsking.com ditchyourip.com dnsiskinky.com dynns.com geekgalaxy.com health-carereform.com homesecuritymac.com homesecuritypc.com myactivedirectory.com mysecuritycamera.com myvnc.com net-freaks.com onthewifi.com point2this.com quicksytes.com securitytactics.com servebeer.com servecounterstrike.com serveexchange.com serveftp.com servegame.com servehalflife.com servehttp.com servehumour.com serveirc.com servemp3.com servep2p.com servepics.com servequake.com servesarcasm.com stufftoread.com unusualperson.com workisboring.com dvrcam.info ilovecollege.info no-ip.info brasilia.me ddns.me dnsfor.me hopto.me loginto.me noip.me webhop.me bounceme.net ddns.net eating-organic.net mydissent.net myeffect.net mymediapc.net mypsx.net mysecuritycamera.net nhlfan.net no-ip.net pgafan.net privatizehealthinsurance.net redirectme.net serveblog.net serveminecraft.net sytes.net cable-modem.org collegefan.org couchpotatofries.org hopto.org mlbfan.org myftp.org mysecuritycamera.org nflfan.org no-ip.org read-books.org ufcfan.org zapto.org no-ip.co.uk golffan.us noip.us pointto.us // NodeArt : https://nodeart.io // Submitted by Konstantin Nosov stage.nodeart.io // Noop : https://noop.app // Submitted by Nathaniel Schweinberg *.developer.app noop.app // Northflank Ltd. : https://northflank.com/ // Submitted by Marco Suter *.northflank.app *.build.run *.code.run *.database.run *.migration.run // Noticeable : https://noticeable.io // Submitted by Laurent Pellegrino noticeable.news // Notion Labs, Inc : https://www.notion.so/ // Submitted by Jess Yao notion.site // Now-DNS : https://now-dns.com // Submitted by Steve Russell dnsking.ch mypi.co myiphost.com forumz.info soundcast.me tcp4.me dnsup.net hicam.net now-dns.net ownip.net vpndns.net dynserv.org now-dns.org x443.pw ntdll.top freeddns.us // nsupdate.info : https://www.nsupdate.info/ // Submitted by Thomas Waldmann nsupdate.info nerdpol.ovh // O3O.Foundation : https://o3o.foundation/ // Submitted by the prvcy.page Registry Team prvcy.page // Observable, Inc. : https://observablehq.com // Submitted by Mike Bostock observablehq.cloud static.observableusercontent.com // OMG.LOL : https://omg.lol // Submitted by Adam Newbold omg.lol // Omnibond Systems, LLC. : https://www.omnibond.com // Submitted by Cole Estep cloudycluster.net // OmniWe Limited : https://omniwe.com // Submitted by Vicary Archangel omniwe.site // One.com : https://www.one.com/ // Submitted by Jacob Bunk Nielsen 123webseite.at 123website.be simplesite.com.br 123website.ch simplesite.com 123webseite.de 123hjemmeside.dk 123miweb.es 123kotisivu.fi 123siteweb.fr simplesite.gr 123homepage.it 123website.lu 123website.nl 123hjemmeside.no service.one website.one simplesite.pl 123paginaweb.pt 123minsida.se // ONID : https://get.onid.ca // Submitted by ONID Engineering Team onid.ca // Open Domains : https://open-domains.net // Submitted by William Harrison is-a-fullstack.dev is-cool.dev is-not-a.dev localplayer.dev is-local.org // Open Social : https://www.getopensocial.com/ // Submitted by Alexander Varwijk opensocial.site // OpenAI : https://openai.com // Submitted by Thomas Shadwell *.oaiusercontent.com // OpenCraft GmbH : http://opencraft.com/ // Submitted by Sven Marnach opencraft.hosting // OpenHost : https://registry.openhost.uk // Submitted by OpenHost Registry Team 16-b.it 32-b.it 64-b.it // OpenResearch GmbH : https://openresearch.com/ // Submitted by Philipp Schmid orsites.com // Opera Software, A.S.A. // Submitted by Yngve Pettersen operaunite.com // Oracle Dyn : https://cloud.oracle.com/home https://dyn.com/dns/ // Submitted by Gregory Drake // Note: This is intended to also include customer-oci.com due to wildcards implicitly including the current label *.customer-oci.com *.oci.customer-oci.com *.ocp.customer-oci.com *.ocs.customer-oci.com *.oraclecloudapps.com *.oraclegovcloudapps.com *.oraclegovcloudapps.uk // Orange : https://www.orange.com // Submitted by Alexandre Linte tech.orange // OsSav Technology Ltd. : https://ossav.com/ // Submitted by OsSav Technology Ltd. // https://nic.can.re can.re // Oursky Limited : https://authgear.com/ // Submitted by Authgear Team & Skygear Developer authgear-staging.com authgearapps.com // OutSystems // Submitted by Duarte Santos outsystemscloud.com // OVHcloud : https://ovhcloud.com // Submitted by Vincent Cassé *.hosting.ovh.net *.webpaas.ovh.net // OwnProvider GmbH : http://www.ownprovider.com // Submitted by Jan Moennich ownprovider.com own.pm // OwO : https://whats-th.is/ // Submitted by Dean Sheather *.owo.codes // OX : http://www.ox.rs // Submitted by Adam Grand ox.rs // oy.lc // Submitted by Charly Coste oy.lc // Pagefog : https://pagefog.com/ // Submitted by Derek Myers pgfog.com // PageXL : https://pagexl.com // Submitted by Yann Guichard pagexl.com // Pantheon Systems, Inc. : https://pantheon.io/ // Submitted by Gary Dylina gotpantheon.com pantheonsite.io // Paywhirl, Inc : https://paywhirl.com/ // Submitted by Daniel Netzer *.paywhirl.com // pcarrier.ca Software Inc : https://pcarrier.ca/ // Submitted by Pierre Carrier *.xmit.co xmit.dev madethis.site srv.us gh.srv.us gl.srv.us // Peplink | Pepwave : http://peplink.com/ // Submitted by Steve Leung mypep.link // Perspecta : https://perspecta.com/ // Submitted by Kenneth Van Alstyne perspecta.cloud // Ping Identity : https://www.pingidentity.com // Submitted by Ping Identity forgeblocks.com id.forgerock.io // Plain : https://www.plain.com/ // Submitted by Jesús Hernández support.site // Planet-Work : https://www.planet-work.com/ // Submitted by Frédéric VANNIÈRE on-web.fr // Platform.sh : https://platform.sh // Submitted by Nikola Kotur *.upsun.app upsunapp.com ent.platform.sh eu.platform.sh us.platform.sh *.platformsh.site *.tst.site // Pley AB : https://www.pley.com/ // Submitted by Henning Pohl pley.games // Porter : https://porter.run/ // Submitted by Rudraksh MK onporter.run // Positive Codes Technology Company : http://co.bn/faq.html // Submitted by Zulfais co.bn // Postman, Inc : https://postman.com // Submitted by Rahul Dhawan postman-echo.com pstmn.io mock.pstmn.io httpbin.org // prequalifyme.today : https://prequalifyme.today // Submitted by DeepakTiwari deepak@ivylead.io prequalifyme.today // prgmr.com : https://prgmr.com/ // Submitted by Sarah Newman xen.prgmr.com // priv.at : http://www.nic.priv.at/ // Submitted by registry priv.at // PROJECT ELIV : https://eliv.kr/ // Submitted by PROJECT ELIV DomainName Team c01.kr eliv-api.kr eliv-cdn.kr eliv-dns.kr mmv.kr vki.kr // project-study : https://project-study.com // Submitted by yumenewa dev.project-study.com // Protonet GmbH : http://protonet.io // Submitted by Martin Meier protonet.io // PSL Sandbox : https://github.com/groundcat/PSL-Sandbox // Submitted by groundcat platter-app.dev // PT Ekossistim Indo Digital : https://e.id // Submitted by Eid Team e.id // Publication Presse Communication SARL : https://ppcom.fr // Submitted by Yaacov Akiba Slama chirurgiens-dentistes-en-france.fr byen.site // PublicZone : https://publiczone.org/ // Submitted by PublicZone NOC Team nyc.mn *.cn.st // pubtls.org : https://www.pubtls.org // Submitted by Kor Nielsen pubtls.org // PythonAnywhere LLP : https://www.pythonanywhere.com // Submitted by Giles Thomas pythonanywhere.com eu.pythonanywhere.com // QA2 // Submitted by Daniel Dent : https://www.danieldent.com/ qa2.com // QCX // Submitted by Cassandra Beelen qcx.io *.sys.qcx.io // QNAP System Inc : https://www.qnap.com // Submitted by Nick Chang myqnapcloud.cn alpha-myqnapcloud.com dev-myqnapcloud.com mycloudnas.com mynascloud.com myqnapcloud.com // QOTO, Org. // Submitted by Jeffrey Phillips Freeman qoto.io // Qualifio : https://qualifio.com/ // Submitted by Xavier De Cock qualifioapp.com // Quality Unit : https://qualityunit.com // Submitted by Vasyl Tsalko ladesk.com // Qualy : https://qualyhq.com // Submitted by Raphael Arias *.qualyhqpartner.com *.qualyhqportal.com // QuickBackend : https://www.quickbackend.com // Submitted by Dani Biro qbuser.com // Quip : https://quip.com // Submitted by Patrick Linehan *.quipelements.com // Qutheory LLC : http://qutheory.io // Submitted by Jonas Schwartz vapor.cloud vaporcloud.io // Rackmaze LLC : https://www.rackmaze.com // Submitted by Kirill Pertsev rackmaze.com rackmaze.net // Rad Web Hosting : https://radwebhosting.com // Submitted by Scott Claeys cloudsite.builders myradweb.net servername.us // Radix FZC : http://domains.in.net // Submitted by Gavin Brown web.in in.net // Raidboxes GmbH : https://raidboxes.de // Submitted by Auke Tembrink myrdbx.io site.rb-hosting.io // Railway Corporation : https://railway.com // Submitted by Phineas Walton up.railway.app // Rancher Labs, Inc : https://rancher.com // Submitted by Vincent Fiduccia *.on-rancher.cloud *.on-k3s.io *.on-rio.io // RavPage : https://www.ravpage.co.il // Submitted by Roni Horowitz ravpage.co.il // Read The Docs, Inc : https://www.readthedocs.org // Submitted by David Fischer readthedocs-hosted.com readthedocs.io // Red Hat, Inc. OpenShift : https://openshift.redhat.com/ // Submitted by Tim Kramer rhcloud.com // Redgate Software : https://red-gate.com // Submitted by Andrew Farries instances.spawn.cc // Redpanda Data : https://redpanda.com // Submitted by Infrastructure Team *.clusters.rdpa.co *.srvrless.rdpa.co // Render : https://render.com // Submitted by Anurag Goel onrender.com app.render.com // Repl.it : https://repl.it // Submitted by Lincoln Bergeson replit.app id.replit.app firewalledreplit.co id.firewalledreplit.co repl.co id.repl.co replit.dev archer.replit.dev bones.replit.dev canary.replit.dev global.replit.dev hacker.replit.dev id.replit.dev janeway.replit.dev kim.replit.dev kira.replit.dev kirk.replit.dev odo.replit.dev paris.replit.dev picard.replit.dev pike.replit.dev prerelease.replit.dev reed.replit.dev riker.replit.dev sisko.replit.dev spock.replit.dev staging.replit.dev sulu.replit.dev tarpit.replit.dev teams.replit.dev tucker.replit.dev wesley.replit.dev worf.replit.dev repl.run // Resin.io : https://resin.io // Submitted by Tim Perry resindevice.io devices.resinstaging.io // RethinkDB : https://www.rethinkdb.com/ // Submitted by Chris Kastorff hzc.io // Rico Developments Limited : https://adimo.co // Submitted by Colin Brown adimo.co.uk // Riseup Networks : https://riseup.net // Submitted by Micah Anderson itcouldbewor.se // Roar Domains LLC : https://roar.basketball/ // Submitted by Gavin Brown aus.basketball nz.basketball // ROBOT PAYMENT INC. : https://www.robotpayment.co.jp/ // Submitted by Kentaro Takamori subsc-pay.com subsc-pay.net // Rochester Institute of Technology : http://www.rit.edu/ // Submitted by Jennifer Herting git-pages.rit.edu // Rocky Enterprise Software Foundation : https://resf.org // Submitted by Neil Hanlon rocky.page // Ruhr University Bochum : https://www.ruhr-uni-bochum.de/ // Submitted by Andreas Jobs rub.de ruhr-uni-bochum.de io.noc.ruhr-uni-bochum.de // Rusnames Limited : http://rusnames.ru/ // Submitted by Sergey Zotov биз.Ñ€ÑƒÑ ÐºÐ¾Ð¼.Ñ€ÑƒÑ ÐºÑ€Ñ‹Ð¼.Ñ€ÑƒÑ Ð¼Ð¸Ñ€.Ñ€ÑƒÑ Ð¼Ñк.Ñ€ÑƒÑ Ð¾Ñ€Ð³.Ñ€ÑƒÑ Ñамара.Ñ€ÑƒÑ Ñочи.Ñ€ÑƒÑ Ñпб.Ñ€ÑƒÑ Ñ.Ñ€ÑƒÑ // Russian Academy of Sciences // Submitted by Tech Support ras.ru // Sakura Frp : https://www.natfrp.com // Submitted by Bobo Liu nyat.app // SAKURA Internet Inc. : https://www.sakura.ad.jp/ // Submitted by Internet Service Department 180r.com dojin.com sakuratan.com sakuraweb.com x0.com 2-d.jp bona.jp crap.jp daynight.jp eek.jp flop.jp halfmoon.jp jeez.jp matrix.jp mimoza.jp ivory.ne.jp mail-box.ne.jp mints.ne.jp mokuren.ne.jp opal.ne.jp sakura.ne.jp sumomo.ne.jp topaz.ne.jp netgamers.jp nyanta.jp o0o0.jp rdy.jp rgr.jp rulez.jp s3.isk01.sakurastorage.jp s3.isk02.sakurastorage.jp saloon.jp sblo.jp skr.jp tank.jp uh-oh.jp undo.jp rs.webaccel.jp user.webaccel.jp websozai.jp xii.jp squares.net jpn.org kirara.st x0.to from.tv sakura.tv // Salesforce.com, Inc. : https://salesforce.com/ // Submitted by Salesforce Public Suffix List Team *.builder.code.com *.dev-builder.code.com *.stg-builder.code.com *.001.test.code-builder-stg.platform.salesforce.com *.aa.crm.dev *.ab.crm.dev *.ac.crm.dev *.ad.crm.dev *.ae.crm.dev *.af.crm.dev *.ci.crm.dev *.d.crm.dev *.pa.crm.dev *.pb.crm.dev *.pc.crm.dev *.pd.crm.dev *.pe.crm.dev *.pf.crm.dev *.w.crm.dev *.wa.crm.dev *.wb.crm.dev *.wc.crm.dev *.wd.crm.dev *.we.crm.dev *.wf.crm.dev // Sandstorm Development Group, Inc. : https://sandcats.io/ // Submitted by Asheesh Laroia sandcats.io // Sav.com, LLC : https://marketing.sav.com/ // Submitted by Mukul Kudegave sav.case // SBE network solutions GmbH : https://www.sbe.de/ // Submitted by Norman Meilick logoip.com logoip.de // Scaleway : https://www.scaleway.com/ // Submitted by Scaleway PSL Maintainer fr-par-1.baremetal.scw.cloud fr-par-2.baremetal.scw.cloud nl-ams-1.baremetal.scw.cloud cockpit.fr-par.scw.cloud ddl.fr-par.scw.cloud dtwh.fr-par.scw.cloud fnc.fr-par.scw.cloud functions.fnc.fr-par.scw.cloud ifr.fr-par.scw.cloud k8s.fr-par.scw.cloud nodes.k8s.fr-par.scw.cloud kafk.fr-par.scw.cloud mgdb.fr-par.scw.cloud rdb.fr-par.scw.cloud s3.fr-par.scw.cloud s3-website.fr-par.scw.cloud scbl.fr-par.scw.cloud whm.fr-par.scw.cloud priv.instances.scw.cloud pub.instances.scw.cloud k8s.scw.cloud cockpit.nl-ams.scw.cloud ddl.nl-ams.scw.cloud dtwh.nl-ams.scw.cloud ifr.nl-ams.scw.cloud k8s.nl-ams.scw.cloud nodes.k8s.nl-ams.scw.cloud kafk.nl-ams.scw.cloud mgdb.nl-ams.scw.cloud rdb.nl-ams.scw.cloud s3.nl-ams.scw.cloud s3-website.nl-ams.scw.cloud scbl.nl-ams.scw.cloud whm.nl-ams.scw.cloud cockpit.pl-waw.scw.cloud ddl.pl-waw.scw.cloud dtwh.pl-waw.scw.cloud ifr.pl-waw.scw.cloud k8s.pl-waw.scw.cloud nodes.k8s.pl-waw.scw.cloud kafk.pl-waw.scw.cloud mgdb.pl-waw.scw.cloud rdb.pl-waw.scw.cloud s3.pl-waw.scw.cloud s3-website.pl-waw.scw.cloud scbl.pl-waw.scw.cloud scalebook.scw.cloud smartlabeling.scw.cloud dedibox.fr // schokokeks.org GbR : https://schokokeks.org/ // Submitted by Hanno Böck schokokeks.net // Scottish Government : https://www.gov.scot // Submitted by Martin Ellis gov.scot service.gov.scot // Scry Security : http://www.scrysec.com // Submitted by Shante Adam scrysec.com // Scrypted : https://scrypted.app // Submitted by Koushik Dutta client.scrypted.io // Securepoint GmbH : https://www.securepoint.de // Submitted by Erik Anders firewall-gateway.com firewall-gateway.de my-gateway.de my-router.de spdns.de spdns.eu firewall-gateway.net my-firewall.org myfirewall.org spdns.org // Seidat : https://www.seidat.com // Submitted by Artem Kondratev seidat.net // Sellfy : https://sellfy.com // Submitted by Yuriy Romadin sellfy.store // Sendmsg : https://www.sendmsg.co.il // Submitted by Assaf Stern minisite.ms // Senseering GmbH : https://www.senseering.de // Submitted by Felix Mönckemeyer senseering.net // Servebolt AS : https://servebolt.com // Submitted by Daniel Kjeserud servebolt.cloud // Service Online LLC : http://drs.ua/ // Submitted by Serhii Bulakh biz.ua co.ua pp.ua // Shanghai Accounting Society : https://www.sasf.org.cn // Submitted by Information Administration as.sh.cn // Sheezy.Art : https://sheezy.art // Submitted by Nyoom sheezy.games // Shopblocks : http://www.shopblocks.com/ // Submitted by Alex Bowers myshopblocks.com // Shopify : https://www.shopify.com // Submitted by Alex Richter myshopify.com // Shopit : https://www.shopitcommerce.com/ // Submitted by Craig McMahon shopitsite.com // shopware AG : https://shopware.com // Submitted by Jens Küper shopware.shop shopware.store // Siemens Mobility GmbH // Submitted by Oliver Graebner mo-siemens.io // SinaAppEngine : http://sae.sina.com.cn/ // Submitted by SinaAppEngine 1kapp.com appchizi.com applinzi.com sinaapp.com vipsinaapp.com // Siteleaf : https://www.siteleaf.com/ // Submitted by Skylar Challand siteleaf.net // Small Technology Foundation : https://small-tech.org // Submitted by Aral Balkan small-web.org // Smallregistry by Promopixel SARL : https://www.smallregistry.net // Former AFNIC's SLDs // Submitted by Jérôme Lipowicz aeroport.fr avocat.fr chambagri.fr chirurgiens-dentistes.fr experts-comptables.fr medecin.fr notaires.fr pharmacien.fr port.fr veterinaire.fr // Smoove.io : https://www.smoove.io/ // Submitted by Dan Kozak vp4.me // Snowflake Inc : https://www.snowflake.com/ // Submitted by Sam Haar *.snowflake.app *.privatelink.snowflake.app streamlit.app streamlitapp.com // Snowplow Analytics : https://snowplowanalytics.com/ // Submitted by Ian Streeter try-snowplow.com // Software Consulting Michal Zalewski : https://www.mafelo.com // Submitted by Michal Zalewski mafelo.net // Solana Name Service : https://sns.id // Submitted by Solana Name Service sol.site // Sony Interactive Entertainment LLC : https://sie.com/ // Submitted by David Coles playstation-cloud.com // SourceHut : https://sourcehut.org // Submitted by Drew DeVault srht.site // SourceLair PC : https://www.sourcelair.com // Submitted by Antonis Kalipetis apps.lair.io *.stolos.io // sourceWAY GmbH : https://sourceway.de // Submitted by Richard Reiber 4.at my.at my.de *.nxa.eu nx.gw // Spawnbase : https://spawnbase.ai // Submitted by Alexander Zuev spawnbase.app // SpeedPartner GmbH : https://www.speedpartner.de/ // Submitted by Stefan Neufeind customer.speedpartner.de // Spreadshop (sprd.net AG) : https://www.spreadshop.com/ // Submitted by Martin Breest myspreadshop.at myspreadshop.com.au myspreadshop.be myspreadshop.ca myspreadshop.ch myspreadshop.com myspreadshop.de myspreadshop.dk myspreadshop.es myspreadshop.fi myspreadshop.fr myspreadshop.ie myspreadshop.it myspreadshop.net myspreadshop.nl myspreadshop.no myspreadshop.pl myspreadshop.se myspreadshop.co.uk // StackBlitz : https://stackblitz.com // Submitted by Dominic Elm & Albert Pai w-corp-staticblitz.com w-credentialless-staticblitz.com w-staticblitz.com bolt.host // Stackhero : https://www.stackhero.io // Submitted by Adrien Gillon stackhero-network.com // STACKIT GmbH & Co. KG : https://www.stackit.de/en/ // Submitted by STACKIT-DNS Team (Simon Stier) runs.onstackit.cloud stackit.gg stackit.rocks stackit.run stackit.zone // Stackryze : https://stackryze.com // Submitted by Sudheer Bhuvana indevs.in // Staclar : https://staclar.com // Submitted by Q Misell // Submitted by Matthias Merkel musician.io novecore.site // Standard Library : https://stdlib.com // Submitted by Jacob Lee api.stdlib.com // statichost.eu : https://www.statichost.eu // Submitted by Eric Selin statichost.page // stereosense GmbH : https://www.involve.me // Submitted by Florian Burmann feedback.ac forms.ac assessments.cx calculators.cx funnels.cx paynow.cx quizzes.cx researched.cx tests.cx surveys.so // Storacha Network : https://storacha.network // Submitted by Alan Shaw ipfs.storacha.link ipfs.w3s.link // Storebase : https://www.storebase.io // Submitted by Tony Schirmer storebase.store // Storj Labs Inc. : https://storj.io/ // Submitted by Philip Hutchins storj.farm // Strapi : https://strapi.io/ // Submitted by Florent Baldino strapiapp.com media.strapiapp.com // Strategic System Consulting (eApps Hosting) : https://www.eapps.com/ // Submitted by Alex Oancea vps-host.net atl.jelastic.vps-host.net njs.jelastic.vps-host.net ric.jelastic.vps-host.net // Streak : https://streak.com // Submitted by Blake Kadatz streak-link.com streaklinks.com streakusercontent.com // Student-Run Computing Facility : https://www.srcf.net/ // Submitted by Edwin Balani soc.srcf.net user.srcf.net // Studenten Net Twente : http://www.snt.utwente.nl/ // Submitted by Silke Hofstra utwente.io // Sub 6 Limited : http://www.sub6.com // Submitted by Dan Miller temp-dns.com // Supabase : https://supabase.io // Submitted by Supabase Security supabase.co realtime.supabase.co storage.supabase.co supabase.in supabase.net // Syncloud : https://syncloud.org // Submitted by Boris Rybalkin syncloud.it // Synology, Inc. : https://www.synology.com/ // Submitted by Rony Weng dscloud.biz direct.quickconnect.cn dsmynas.com familyds.com diskstation.me dscloud.me i234.me myds.me synology.me dscloud.mobi dsmynas.net familyds.net dsmynas.org familyds.org direct.quickconnect.to vpnplus.to // Tabit Technologies Ltd. : https://tabit.cloud/ // Submitted by Oren Agiv mytabit.com mytabit.co.il tabitorder.co.il // TAIFUN Software AG : http://taifun-software.de // Submitted by Bjoern Henke taifun-dns.de // Tailor Inc. : https://www.tailor.tech // Submitted by Ryuzo Yamamoto erp.dev web.erp.dev // Tailscale Inc. : https://www.tailscale.com // Submitted by David Anderson ts.net *.c.ts.net // TASK geographical domains : https://task.gda.pl/en/services/for-entrepreneurs/ gda.pl gdansk.pl gdynia.pl med.pl sopot.pl // Tave Creative Corp : https://tave.com/ // Submitted by Adrian Ziemkowski taveusercontent.com // tawk.to, Inc : https://www.tawk.to // Submitted by tawk.to developer team p.tawk.email p.tawkto.email // Tche.br : https://tche.br // Submitted by Bruno Lorensi tche.br // team.blue : https://team.blue // Submitted by Cedric Dubois site.tb-hosting.com directwp.eu // TechEdge Limited: https://www.nic.uk.cc/ // Submitted by TechEdge Developer ec.cc eu.cc gu.cc uk.cc us.cc // Teckids e.V. : https://www.teckids.org // Submitted by Dominik George edugit.io s3.teckids.org // Telebit : https://telebit.cloud // Submitted by AJ ONeal telebit.app telebit.io *.telebit.xyz // Teleport : https://goteleport.com // Submitted by Rob Picard teleport.sh // Thingdust AG : https://thingdust.com/ // Submitted by Adrian Imboden *.firenet.ch *.svc.firenet.ch reservd.com thingdustdata.com cust.dev.thingdust.io reservd.dev.thingdust.io cust.disrec.thingdust.io reservd.disrec.thingdust.io cust.prod.thingdust.io cust.testing.thingdust.io reservd.testing.thingdust.io // ticket i/O GmbH : https://ticket.io // Submitted by Christian Franke tickets.io // Tlon.io : https://tlon.io // Submitted by Mark Staarink arvo.network azimuth.network tlon.network // Tor Project, Inc. : https://torproject.org // Submitted by Antoine Beaupré torproject.net pages.torproject.net // TownNews.com : http://www.townnews.com // Submitted by Dustin Ward townnews-staging.com // TrafficPlex GmbH : https://www.trafficplex.de/ // Submitted by Phillipp Röll 12hp.at 2ix.at 4lima.at lima-city.at 12hp.ch 2ix.ch 4lima.ch lima-city.ch trafficplex.cloud de.cool 12hp.de 2ix.de 4lima.de lima-city.de 1337.pictures clan.rip lima-city.rocks webspace.rocks lima.zone // TransIP : https://www.transip.nl // Submitted by Rory Breuk and Cedric Dubois *.transurl.be *.transurl.eu site.transip.me *.transurl.nl // Tunnelmole: https://tunnelmole.com // Submitted by Robbie Cahill tunnelmole.net // TuxFamily : http://tuxfamily.org // Submitted by TuxFamily administrators tuxfamily.org // Typedream : https://typedream.com // Submitted by Putri Karunia typedream.app // Typeform : https://www.typeform.com // Submitted by Typeform pro.typeform.com // Uberspace : https://uberspace.de // Submitted by Moritz Werner uber.space // UDR Limited : http://www.udr.hk.com // Submitted by registry hk.com inc.hk ltd.hk hk.org // UK Intis Telecom LTD : https://it.com // Submitted by ITComdomains it.com // Umso Software Inc. : https://www.umso.com // Submitted by Alexis Taylor umso.co // Unison Computing, PBC : https://unison.cloud // Submitted by Simon Højberg unison-services.cloud // United Gameserver GmbH : https://united-gameserver.de // Submitted by Stefan Schwarz virtual-user.de virtualuser.de // United States Writing Corporation : https://uswriting.co // Submitted by Andrew Sampson obj.ag // UNIVERSAL DOMAIN REGISTRY : https://www.udr.org.yt/ // see also: whois -h whois.udr.org.yt help // Submitted by Atanunu Igbunuroghene name.pm sch.tf biz.wf sch.wf org.yt // University of Banja Luka : https://unibl.org // Domains for Republic of Srpska administrative entity. // Submitted by Marko Ivanovic rs.ba // University of Bielsko-Biala regional domain : http://dns.bielsko.pl/ // Submitted by Marcin bielsko.pl // urown.net : https://urown.net // Submitted by Hostmaster urown.cloud dnsupdate.info // US REGISTRY LLC : http://us.org // Submitted by Gavin Brown us.org // V.UA Domain Registry: https://www.v.ua/ // Submitted by Serhii Rostilo v.ua // Val Town, Inc : https://val.town/ // Submitted by Tom MacWright val.run web.val.run // Vercel, Inc : https://vercel.com/ // Submitted by Laurens Duijvesteijn vercel.app v0.build vercel.dev vusercontent.net vercel.run now.sh // VeryPositive SIA : http://very.lv // Submitted by Danko Aleksejevs 2038.io // Virtual-Info : https://www.virtual-info.info/ // Submitted by Adnan RIHAN v-info.info // VistaBlog : https://vistablog.ir/ // Submitted by Hossein Piri vistablog.ir // Viva Republica, Inc. : https://toss.im/ // Submitted by Deus Team deus-canvas.com // Voorloper.com : https://voorloper.com // Submitted by Nathan van Bakel voorloper.cloud // Vultr Objects : https://www.vultr.com/products/object-storage/ // Submitted by Niels Maumenee *.vultrobjects.com // Waffle Computer Inc., Ltd. : https://docs.waffleinfo.com // Submitted by Masayuki Note wafflecell.com // Walrus : https://walrus.xyz // Submitted by Max Spector wal.app // Wasmer: https://wasmer.io // Submitted by Lorentz Kinde wasmer.app // Webflow, Inc. : https://www.webflow.com // Submitted by Webflow Security Team webflow.io webflowtest.io // WebHare bv : https://www.webhare.com/ // Submitted by Arnold Hendriks *.webhare.dev // WebHotelier Technologies Ltd : https://www.webhotelier.net/ // Submitted by Apostolos Tsakpinis bookonline.app hotelwithflight.com reserve-online.com reserve-online.net // WebPros International, LLC : https://webpros.com/ // Submitted by Nicolas Rochelemagne cprapid.com pleskns.com wp2.host pdns.page plesk.page cpanel.site wpsquared.site // WebWaddle Ltd : https://webwaddle.com/ // Submitted by Merlin Glander *.wadl.top // Western Digital Technologies, Inc : https://www.wdc.com // Submitted by Jung Jin remotewd.com // Whatbox Inc. : https://whatbox.ca/ // Submitted by Anthony Ryan box.ca // WIARD Enterprises : https://wiardweb.com // Submitted by Kidd Hustle pages.wiardweb.com // Wikimedia Foundation : https://wikitech.wikimedia.org // Submitted by Timo Tijhof toolforge.org wmcloud.org beta.wmcloud.org wmflabs.org // William Harrison : https://wharrison.com.au // Submitted by William Harrison vps.hrsn.au hrsn.dev is-a.dev localcert.net // Windsurf : https://windsurf.com // Submitted by Douglas Chen windsurf.app windsurf.build // WirelessCar : https://wirelesscar.com // Submitted by Martin Lindberg drive-platform.com drive-platform.io // WISP : https://wisp.gg // Submitted by Stepan Fedotov panel.gg daemon.panel.gg // Wix.com, Inc. : https://www.wix.com // Submitted by Shahar Talmi / Alon Kochba base44.app base44-sandbox.com wixsite.com wixstudio.com editorx.io wixstudio.io wix.run // Wizard Zines : https://wizardzines.com // Submitted by Julia Evans messwithdns.com // WoltLab GmbH : https://www.woltlab.com // Submitted by Tim Düsterhus woltlab-demo.com myforum.community community-pro.de diskussionsbereich.de community-pro.net meinforum.net // Woods Valldata : https://www.woodsvalldata.co.uk/ // Submitted by Chris Whittle affinitylottery.org.uk raffleentry.org.uk weeklylottery.org.uk // WP Engine : https://wpengine.com/ // Submitted by Michael Smith // Submitted by Brandon DuRette wpenginepowered.com js.wpenginepowered.com // XenonCloud GbR : https://xenoncloud.net // Submitted by Julian Uphoff *.xenonconnect.de half.host // XnBay Technology : http://www.xnbay.com/ // Submitted by XnBay Developer xnbay.com u2.xnbay.com u2-local.xnbay.com // XS4ALL Internet bv : https://www.xs4all.nl/ // Submitted by Daniel Mostertman cistron.nl demon.nl xs4all.space // xTool : https://xtool.com // Submitted by Echo xtooldevice.com // Yandex.Cloud LLC : https://cloud.yandex.com // Submitted by Alexander Lodin yandexcloud.net storage.yandexcloud.net website.yandexcloud.net sourcecraft.site // YesCourse Pty Ltd : https://yescourse.com // Submitted by Atul Bhouraskar official.academy // Yola : https://www.yola.com/ // Submitted by Stefano Rivera yolasite.com // Yunohost : https://yunohost.org // Submitted by Valentin Grimaud ynh.fr nohost.me noho.st // ZaNiC : http://www.za.net/ // Submitted by registry za.net za.org // ZAP-Hosting GmbH & Co. KG : https://zap-hosting.com // Submitted by Julian Alker zap.cloud // Zeabur : https://zeabur.com/ // Submitted by Zeabur Team zeabur.app // Zerops : https://zerops.io/ // Submitted by Zerops Team *.zerops.app // Zine EOOD : https://zine.bg/ // Submitted by Martin Angelov bss.design // Zitcom A/S : https://www.zitcom.dk // Submitted by Emil Stahl basicserver.io virtualserver.io enterprisecloud.nu // Zone.ID: https://zone.id // Submitted by Gx1.org zone.id nett.to // ZoneABC : https://zoneabc.net // Submitted by ZoneABC Team zabc.net // ===END PRIVATE DOMAINS=== Mail-DMARC-1.20260306/share/rua-schema.xsd000444000765000024 2301115152630466 17105 0ustar00mattstaff000000000000 Mail-DMARC-1.20260306/share/html000755000765000024 015152630466 15132 5ustar00mattstaff000000000000Mail-DMARC-1.20260306/share/html/index.html000444000765000024 1344615152630466 17314 0ustar00mattstaff000000000000 Mail::DMARC
DMARC Reports

by Mail::DMARC.

Mail-DMARC-1.20260306/t000755000765000024 015152630466 13327 5ustar00mattstaff000000000000Mail-DMARC-1.20260306/t/00.Dmarc.t000444000765000024 2533515152630466 15145 0ustar00mattstaff000000000000use strict; use warnings; use Data::Dumper; use Test::More; use Test::File::ShareDir -share => { -dist => { 'Mail-DMARC' => 'share' } }; use lib 'lib'; use_ok('Mail::DMARC'); my $dmarc = Mail::DMARC->new(); isa_ok( $dmarc, 'Mail::DMARC' ); my %sample_dmarc = ( config_file => 'mail-dmarc.ini', source_ip => '192.0.1.1', envelope_to => 'example.com', envelope_from => 'cars4you.info', header_from => 'yahoo.com', dkim => [ { domain => 'example.com', selector => 'apr2015', result => 'fail', human_result => 'fail (body has been altered)', } ], spf => [ { domain => 'example.com', scope => 'mfrom', result => 'pass', } ], ); test_new(); test_config_file_first(); test_header_from(); test_setter_values(); test_spf(); test_dkim(); test_zulu_time(); test_report_window(); test_interval_limits(); test_public_suffix_list(); done_testing(); exit; sub test_public_suffix_list { my $data = { 'com' => 1, 'examplebogusdomainname' => 0, 'xn--55qx5d.cn' => 1, 'xn--zfr164b' => 1, }; foreach my $domain ( keys %$data ) { my $result = $dmarc->is_public_suffix( $domain ); is( $result, $data->{ $domain }, "Public Suffix: $domain" ); } } sub test_zulu_time { my $data = [ [ 'Day Start' , 1426032000, 1426032000 ], [ 'Day Middle' , 1426032050, 1426032000 ], [ 'Day End' , 1426118399, 1426032000 ], [ 'Day Next' , 1426118400, 1426118400 ], ]; foreach my $test ( @$data ) { my ( $name, $now, $begin ) = @$test; my $c_begin = $dmarc->get_start_of_zulu_day( $now ); is( $c_begin, $begin, "Zulu Day: $name" ); } } sub test_report_window { my $data = [ [ 'Daily Start' , 86400, 1426032000, 1426032000, 1426118399 ], [ 'Daily Middle' , 86400, 1426032050, 1426032000, 1426118399 ], [ 'Daily End' , 86400, 1426118399, 1426032000, 1426118399 ], [ 'Hourly First Start' , 3600, 1426032000, 1426032000, 1426035599 ], [ 'Hourly First Middle' , 3600, 1426032050, 1426032000, 1426035599 ], [ 'Hourly First End' , 3600, 1426035599, 1426032000, 1426035599 ], [ 'Hourly Second Start' , 3600, 1426035600, 1426035600, 1426039199 ], [ 'Hourly Second Middle' , 3600, 1426035650, 1426035600, 1426039199 ], [ 'Hourly Second End' , 3600, 1426039199, 1426035600, 1426039199 ], [ 'Irregular Interval' , 3604, 1426034321, 1426034321, 1426037924 ], ]; foreach my $test ( @$data ) { my ( $name, $interval, $now, $begin, $end ) = @$test; my ( $c_begin, $c_end ) = $dmarc->get_report_window( $interval, $now ); is_deeply( [ $c_begin, $c_end ] , [ $begin, $end ] , "Report Window: $name" ); } } sub test_interval_limits { my $data = [ [ 'Below Limit' , 3600, 86400, 3000, 3600 ], [ 'Lower Limit' , 3600, 86400, 3600, 3600 ], [ 'Between Limits' , 3600, 86400, 30000, 30000 ], [ 'Upper Limit' , 3600, 86400, 86400, 86400 ], [ 'Above Limit' , 3600, 86400, 87000, 86400 ], ]; my $now = 1426035650; foreach my $test ( @$data ) { my ( $name, $min, $max, $interval, $expect ) = @$test; $dmarc->config->{'report_sending'}->{'min_interval'} = $min; $dmarc->config->{'report_sending'}->{'max_interval'} = $max; my ( $c_begin, $c_end ) = $dmarc->get_report_window( $interval, $now ); is_deeply( ( $c_end - $c_begin ), $expect - 1, "Interval Limit: $name" ); } delete $dmarc->config->{'report_sending'}->{'min_interval'}; delete $dmarc->config->{'report_sending'}->{'max_interval'}; } sub test_dkim { # set DKIM with key=>val pairs $dmarc->{dkim} = undef; my %test_dkim1 = ( domain => 'a.c', result => 'fail', selector => undef, human_result => undef ); my %test_dkim2 = ( domain => 'a.b.c', result => 'pass' ); ok( $dmarc->dkim(%test_dkim1), "dkim, hash set" ); is_deeply($dmarc->dkim, [ \%test_dkim1 ], "dkim, hash set result"); # set with a hashref $dmarc->{dkim} = undef; ok( $dmarc->dkim(\%test_dkim1), "dkim, hashref set" ); is_deeply($dmarc->dkim, [ \%test_dkim1 ], "dkim, hashref set, result"); # set with an arrayref $dmarc->{dkim} = undef; ok( $dmarc->dkim([ \%test_dkim1 ]), "dkim, arrayref set" ); is_deeply($dmarc->dkim, [ \%test_dkim1 ], "dkim, arrayref set result"); # set with arrayref, two values $dmarc->{dkim} = undef; ok( $dmarc->dkim([ \%test_dkim1, \%test_dkim2 ]), "dkim, arrayref set" ); is_deeply($dmarc->dkim, [ \%test_dkim1, \%test_dkim2 ], "dkim, arrayref set result"); # set with hashes, iterative $dmarc->{dkim} = undef; ok( $dmarc->dkim(%test_dkim1), "dkim, hash set 1" ); ok( $dmarc->dkim(%test_dkim2), "dkim, hash set 2" ); is_deeply($dmarc->dkim, [ \%test_dkim1, \%test_dkim2 ], "dkim, iterative hashes"); # set with a Mail::DKIM::Verifier $dmarc->{dkim} = undef; my $dkv = Mail::DKIM::Verifier->new( %test_dkim1 ); $dmarc->dkim( $dkv ); is_deeply( $dmarc->dkim, [ \%test_dkim1 ], "dkim, as Mail::DKIM::Verifier"); # set with a callback $dmarc->{dkim} = undef; my $counter = 0; my $callback = sub { $counter++; [ \%test_dkim1 ] }; ok( $dmarc->dkim($callback), "dkim, arrayref set" ); is($counter, 0, "callback not yet called"); is_deeply($dmarc->dkim, [ \%test_dkim1 ], "dkim, callback-derived result"); is_deeply($dmarc->dkim, [ \%test_dkim1 ], "dkim, callback-cached result"); is($counter, 1, "callback exactly once"); # set DKIM with invalid key=>val pairs eval { $dmarc->dkim( dom => 'foo', 'blah' ) }; chomp $@; ok( $@, "dkim, neg, $@" ); eval { $dmarc->dkim( { domain => 'foo.com', result => 'non-existent' } ) }; chomp $@; ok( $@, "dkim, neg, $@" ); } sub test_spf { # set SPF with key=>val pairs $dmarc->init; my %test_spf = ( domain => 'a.c', scope => 'mfrom', result => 'fail' ); ok( $dmarc->spf(%test_spf), "spf, hash set" ); is_deeply($dmarc->spf, [ \%test_spf ], "spf, hash set result"); # set with a hashref $dmarc->init; ok( $dmarc->spf(\%test_spf), "spf, hashref set" ); is_deeply($dmarc->spf, [ \%test_spf ], "spf, hashref set, result"); # set with an arrayref $dmarc->init; ok( $dmarc->spf([ \%test_spf ]), "spf, arrayref set" ); is_deeply($dmarc->spf, [ \%test_spf ], "spf, arrayref set result"); # set with arrayref, two values $dmarc->init; ok( $dmarc->spf([ \%test_spf, \%test_spf ]), "spf, arrayref set" ); is_deeply($dmarc->spf, [ \%test_spf, \%test_spf ], "spf, arrayref set result"); # set with a callback $dmarc->init; my $counter = 0; my $callback = sub { $counter++; [ \%test_spf ] }; ok( $dmarc->spf($callback), "spf, callback set" ); is($counter, 0, "callback not yet called"); is_deeply($dmarc->spf, [ \%test_spf ], "spf, callback-derived result"); is_deeply($dmarc->spf, [ \%test_spf ], "spf, callback-cached result"); is($counter, 1, "callback exactly once"); # set SPF with invalid key=>val pairs eval { $dmarc->spf( dom => 'foo', 'blah' ) }; chomp $@; ok( $@, "spf, neg, $@" ); } sub test_header_from { my @good_vals = (qw/ spam-example.com bar.com test.co.UK test.CO.za /); foreach my $k (@good_vals) { ok( $dmarc->header_from($k), "header_from, $k" ); } my @bad_vals = (qw/ a.b a@b.c f*ct.org /); foreach my $k (@bad_vals) { eval { $dmarc->header_from($k); }; chomp $@; ok( $@, "header_from, $k, $@" ); } } sub test_setter_values { my %good_vals = ( source_ip => [qw/ 0.0.0.0 1.1.1.1 255.255.255.255 /], envelope_to => [qw/ example.com /], envelope_from => [qw/ example.com /], header_from => [qw/ spam-example.com /], dkim => [ $sample_dmarc{dkim} ], spf => [ $sample_dmarc{spf} ], ); foreach my $k ( keys %good_vals ) { foreach my $t ( @{ $good_vals{$k} } ) { ok( defined $dmarc->$k($t), "$k, $t" ); } } my %bad_vals = ( source_ip => [qw/ 0.257.0.25 255.255.255.256 /], envelope_to => [qw/ 3.a /], envelope_from => [qw/ /], header_from => [qw/ /], dkim => [qw/ /], spf => [qw/ /], ); foreach my $k ( keys %bad_vals ) { foreach my $t ( @{ $bad_vals{$k} } ) { eval { $dmarc->$k($t); }; ok( $@, "neg, $k, $t" ) or diag $dmarc->$k($t); } } } sub test_new { # empty policy my $dmarc = Mail::DMARC->new(); isa_ok( $dmarc, 'Mail::DMARC' ); my $expected = { config_file => 'mail-dmarc.ini' }; is_deeply( $dmarc, $expected, "new, empty" ); # new, one shot request $dmarc = cleanup_obj( Mail::DMARC->new(%sample_dmarc) ); isa_ok( $dmarc, 'Mail::DMARC' ); is_deeply( $dmarc, \%sample_dmarc, "new, one shot" ); # new, individual accessors $dmarc = Mail::DMARC->new(); foreach my $key ( keys %sample_dmarc ) { next if grep {/$key/} qw/ config config_file public_suffixes /; my $val = $sample_dmarc{$key}; $dmarc->$key( $val ) or diag "error running $key with $val arg: $@"; } $dmarc = cleanup_obj($dmarc); is_deeply($dmarc, \%sample_dmarc, "new, individual accessors" ); } sub test_config_file_first { # config file loaded before any other attr initialization my $new_dmarc = Mail::DMARC::Testing->new( config_file => 't/mail-dmarc.ini', assert_ok => 1, ); }; sub cleanup_obj { my $obj = shift; foreach my $k ( qw/ config public_suffixes dkim_ar spf_ar / ) { delete $obj->{$k}; } return $obj; } package Mail::DKIM::Verifier; sub new { my ($class, %args) = @_; my $self = bless { signatures => [] }, $class; $self->signatures(%args); return $self; } sub signatures { my $self = shift; return shift @{ $self->{signatures}} if 0 == scalar @_; push @{ $self->{signatures} }, Mail::DKIM::Signature->new(@_); $self->{signatures}; } 1; package Mail::DKIM::Signature; sub new { my $class = shift; return bless { @_ }, $class; }; sub result { return $_[0]->{result}; } sub domain { return $_[0]->{domain}; } sub selector { return $_[0]->{selector}; } sub result_detail { return $_[0]->{result_detail} || $_[0]->{human_result}; } 1; package Mail::DMARC::Testing; use parent 'Mail::DMARC'; sub assert_ok { my ($self) = @_; Test::More::is( $self->config->{organization}{domain}, 'example-test.com', 'config file is initialized before assert_ok', ); } 1; Mail-DMARC-1.20260306/t/01.Policy.t000444000765000024 3250515152630466 15354 0ustar00mattstaff000000000000use strict; use warnings; use Data::Dumper; use Test::More; use Test::Output; use lib 'lib'; use_ok('Mail::DMARC::Policy'); my $pol = Mail::DMARC::Policy->new(); isa_ok( $pol, 'Mail::DMARC::Policy' ); ok( !$pol->v, "policy, version, neg" ); ok( $pol->v('DMARC1'), "policy, set" ); cmp_ok( $pol->v, 'eq', 'DMARC1', "policy, version, pos" ); my $expected_parse_warning = __expected_parse_warning(); test_new(); test_is_valid_p(); test_is_valid_rf(); stderr_is { test_parse() } $expected_parse_warning, 'STDERR yields parse warnings'; test_setter_values(); test_apply_defaults(); test_is_valid(); test_stringify(); handles_common_record_errors(); done_testing(); exit; sub __expected_parse_warning { return <<'EO_PARSE_WARN' invalid DMARC record, please post this message to https://github.com/msimerson/mail-dmarc/issues/39 v=DMARC1;p=reject;rua=mailto:dmarc-feedback@theartfarm.com;pct=;ruf=mailto:dmarc-feedback@theartfarm.com invalid DMARC record, please post this message to https://github.com/msimerson/mail-dmarc/issues/39 domain=tnpi.net;v=DMARC1;p=reject;rua=mailto:dmarc-feedback@theartfarm.com;pct=;ruf=mailto:dmarc-feedback@theartfarm.com EO_PARSE_WARN ; } sub test_apply_defaults { # empty policy my $pol = Mail::DMARC::Policy->new(); isa_ok( $pol, 'Mail::DMARC::Policy' ); is_deeply( $pol, {}, "new, empty policy" ); # default policy $pol = Mail::DMARC::Policy->new( v => 'DMARC1', p => 'reject' ); ok( $pol->apply_defaults(), "apply_defaults" ); my $expected = { v => 'DMARC1', p => 'reject', rf => 'afrf', fo => 0, adkim => 'r', aspf => 'r', ri => 86400 }; is_deeply( $pol, $expected, "new, with defaults" ); } sub test_setter_values { my %good_vals = ( p => [qw/ none reject quarantine NONE REJEcT Quarantine /], v => [qw/ DMARC1 dmarc1 /], sp => [qw/ none reject quarantine NoNe REjEcT QuarAntine /], adkim => [qw/ r s R S /], aspf => [qw/ r s R S /], fo => [qw/ 0 1 d s D S 0:d 0:1:d:s /], rua => [ qw{ http://example.com/pub/dmarc!30m mailto:dmarc-feed@example.com!10m } ], ruf => [qw{ https://example.com/dmarc?report!1m }], rf => [qw/ iodef afrf IODEF AFRF /], ri => [ 0, 1, 1000, 4294967295 ], pct => [ 0, 10, 50, 99, 100 ], ); foreach my $k ( keys %good_vals ) { foreach my $t ( @{ $good_vals{$k} } ) { ok( defined $pol->$k($t), "$k, $t" ); } } my %bad_vals = ( p => [qw/ nonense silly example /], v => ['DMARC2'], sp => [qw/ nones rejection quarrantine /], adkim => [qw/ relaxed strict /], aspf => [qw/ relaxed strict /], fo => [qw/ 00 11 dd ss /], rua => [qw{ ftp://example.com/pub torrent://piratebay.net/dmarc }], ruf => [qw{ mail:msimerson@cnap.org }], rf => [qw/ iodef2 rfrf2 rfrf /], ri => [ -1, 'a', 4294967296 ], pct => [ -1, 'f', 101, 1.1, '1.0', '5.f1' ], ); foreach my $k ( keys %bad_vals ) { foreach my $t ( @{ $bad_vals{$k} } ) { eval { $pol->$k($t); }; ok( $@, "neg, $k, $t" ); } } } sub test_new { # empty policy my $pol = Mail::DMARC::Policy->new(); isa_ok( $pol, 'Mail::DMARC::Policy' ); is_deeply( $pol, {}, "new, empty policy" ); # default policy $pol = Mail::DMARC::Policy->new( v => 'DMARC1', p => 'reject', pct => 90, rua => 'mailto:u@d.co' ); isa_ok( $pol, 'Mail::DMARC::Policy' ); is_deeply( $pol, { v => 'DMARC1', p => 'reject', pct => 90, rua => 'mailto:u@d.co' }, "new, with args" ); # text record $pol = Mail::DMARC::Policy->new( 'v=DMARC1; p=reject; rua=mailto:u@d.co; pct=90'); isa_ok( $pol, 'Mail::DMARC::Policy' ); is_deeply( $pol, { v => 'DMARC1', p => 'reject', pct => 90, rua => 'mailto:u@d.co' }, "new, with args" ); } sub test_parse { $pol = $pol->parse( 'v=DMARC1; p=reject; rua=mailto:dmarc@example.co; pct=90'); isa_ok( $pol, 'Mail::DMARC::Policy' ); my $expected = { v => 'DMARC1', p => 'reject', pct => 90, rua => 'mailto:dmarc@example.co', }; is_deeply( $pol, $expected, 'parse'); is_deeply( $pol->parse( 'v=DMARC1;p=reject;rua=mailto:dmarc-feedback@theartfarm.com;pct=;ruf=mailto:dmarc-feedback@theartfarm.com' ), { v => 'DMARC1', p => 'reject', rua => 'mailto:dmarc-feedback@theartfarm.com', ruf => 'mailto:dmarc-feedback@theartfarm.com', }, "parse, warns of invalid DMARC record format" ); is_deeply( $pol->parse( 'domain=tnpi.net;v=DMARC1;p=reject;rua=mailto:dmarc-feedback@theartfarm.com;pct=;ruf=mailto:dmarc-feedback@theartfarm.com' ), { v => 'DMARC1', p => 'reject', domain => 'tnpi.net', rua => 'mailto:dmarc-feedback@theartfarm.com', ruf => 'mailto:dmarc-feedback@theartfarm.com', }, "parse, warns of invalid DMARC record format, with location" ); $pol = $pol->parse('v=DMARC1'); isa_ok( $pol, 'Mail::DMARC::Policy' ); $expected = { v => 'DMARC1' }; is_deeply( $pol, $expected, 'parse'); } sub test_is_valid_p { foreach my $p (qw/ none reject quarantine /) { ok( $pol->is_valid_p($p), "policy->is_valid_p, pos, $p" ); } foreach my $p (qw/ other gibberish non-policy words /) { ok( !$pol->is_valid_p($p), "policy->is_valid_p, neg, $p" ); } } sub test_is_valid_rf { foreach my $f (qw/ afrf iodef /) { ok( $pol->is_valid_rf($f), "policy->is_valid_rf, pos, $f" ); } foreach my $f (qw/ ffrf i0def report /) { ok( !$pol->is_valid_rf($f), "policy->is_valid_rf, neg, $f" ); } } sub test_is_valid { # empty policy my $pol = Mail::DMARC::Policy->new(); eval { $pol->is_valid(); }; chomp $@; ok( $@, "is_valid, $@" ); eval { $pol = Mail::DMARC::Policy->new('v=DMARC1') }; chomp $@; ok( $@, "is_valid, 1.4.1 meaningless, $@" ); eval { $pol = Mail::DMARC::Policy->new('v=DMARC1\; p=reject\;') }; ok( $pol, "is_valid, 1.4.3 extra backslashes" ); eval { $pol = Mail::DMARC::Policy->new('v=DMARC1; p=reject; newtag=unknown') }; ok( $pol, "is_valid, 1.4.4 unknown tag" ); eval { $pol = Mail::DMARC::Policy->new('v=DMARC1; p=bogus') }; chomp $@; ok( $@, "is_valid, 1.4.5 bogus p value, $@" ); # policy, minimum $pol = Mail::DMARC::Policy->new( 'v=DMARC1; p=reject' ); ok( $pol->is_valid, "is_valid, 1.4.2 smallest record" ); # policy, min + defaults $pol->apply_defaults(); ok( $pol->is_valid, "is_valid, pos, w/defaults" ); # 9.6 policy discovery $pol = undef; eval { $pol = Mail::DMARC::Policy->new( v => 'DMARC1' ); }; # or diag $@; ok( !$pol, "is_valid, neg, missing p, no rua" ); eval { $pol = Mail::DMARC::Policy->new( v => 'DMARC1', rua => 'ftp://www.example.com' ); }; # or diag $@; ok( !$pol, "is_valid, neg, missing p, invalid rua" ); $pol = undef; eval { $pol = Mail::DMARC::Policy->new( v => 'DMARC1', rua => 'mailto:test@example.com' ); }; ok( $pol && $pol->is_valid, "is_valid, pos, implicit p=none w/rua" ); } sub test_stringify { $pol = Mail::DMARC::Policy->new( 'v=DMARC1; p=reject' ); cmp_ok($pol->stringify, 'eq', 'v=DMARC1; p=reject'); } sub handles_common_record_errors { foreach my $d () { chomp $d; my $pol = Mail::DMARC::Policy->new($d); eval { ok( $pol->is_valid(), "policy is valid: $d"); }; } } # unhandled errors #domain=caasco.ca;v=DMARC1;p=none;sp=none;rua=mailto:dmarc_agg@auth.returnpath.net;ruf=mailto:dmarc_afrf@auth.returnpath.net;rf=afrf;pct100 #domain=edm.groceryrun.com.au;v=dmarc1;p=none;rua=mailto:dmarc_feedback@inxmail.de&amp;amp;amp;lt;dmarc_feedback@inxmail.de&amp;amp;amp;gt #domain=reply.myphotobook.de;v=DMARC1;p=reject;adkim=s;aspf=r;rf�rf;pct0 #domain=email.ex.kbhmaui.com;v=DMARC1;p=none;rua=mailto:dmarc-reports@email.ex.kbhmaui.com;pct=100;†__DATA__ domain=accuquote.com;v=DMARC1;p=none;fo:0;adkim=r;aspf=r;sp=none;rua=mailto:accu_postmaster@accuquote.com domain=targetselect.net;v=DMARC1;p=none;rua=mailto:postmaster@targetselect.net;ruf=mailto:postmaster@targetselect.net;adkim=r;aspf=r;pct=100;rf:afrf;ri=86400;sp=none domain=1105insight.com;v=DMARC1;p=none;rua=mailto:postmaster@1105insight.com;ruf=mailto:postmaster@1105insight.com;adkim=r;aspf=r;pct=100;rf:afrf;ri=86400;sp=none domain=borsheims.net;v=DMARC1;p=none;rua=mailto:postmaster@borsheims.net;ruf=mailto:postmaster@borsheims.net;adkim=r;aspf=r;pct=100;rf:afrf;ri=86400;sp=none domain=consumersilver.com;v=DMARC1;p=none;rua=mailto:postmaster@consumersilver.com;ruf=mailto:postmaster@consumersilver.com;adkim=r;aspf=r;pct=100;rf:afrf;ri=86400;sp=none domain=coppermail-usa.com;v=DMARC1;p=none;rua=mailto:postmaster@coppermail-usa.com;ruf=mailto:postmaster@coppermail-usa.com;adkim=r;aspf=r;pct=100;rf:afrf;ri=86400;sp=none domain=eglancesender.com;v=DMARC1;p=none;rua=mailto:postmaster@eglancesender.com;ruf=mailto:postmaster@eglancesender.com;adkim=r;aspf=r;pct=100;rf:afrf;ri=86400;sp=none domain=egroupconsumer.com;v=DMARC1;p=none;rua=mailto:postmaster@egroupconsumer.com;ruf=mailto:postmaster@egroupconsumer.com;adkim=r;aspf=r;pct=100;rf:afrf;ri=86400;sp=none domain=eselectsender.com;v=DMARC1;p=none;rua=mailto:postmaster@eselectsender.com;ruf=mailto:postmaster@eselectsender.com;adkim=r;aspf=r;pct=100;rf:afrf;ri=86400;sp=none domain=filemail.com;v=DMARC1;p=none;rua=mailto:admin@filemail.com;ruf=mailto:admin@filemail.com;fo:0;adkim=r;aspf=r domain=fisherprograms.com;v=DMARC1;p=none;rua=mailto:postmaster@fisherprograms.com;ruf=mailto:postmaster@fisherprograms.com;adkim=r;aspf=r;pct=100;rf:afrf;ri=86400;sp=none domain=mail-peninsula.com;v=DMARC1;p=none;rua=mailto:umesh@force24.co.uk;ruf=mailto:umesh@force24.co.uk;fo:0;adkim=r;aspf=r;pct=100;rf=afrf;ri=86000;sp=none domain=sendergroup.com;v=DMARC1;p=none;rua=mailto:postmaster@sendergroup.com;ruf=mailto:postmaster@sendergroup.com;adkim=r;aspf=r;pct=100;rf:afrf;ri=86400;sp=none domain=targetselection.com;v=DMARC1;p=none;rua=mailto:postmaster@targetselection.com;ruf=mailto:postmaster@targetselection.com;adkim=r;aspf=r;pct=100;rf:afrf;ri=86400;sp=none domain=trondheim-redcross.no;v=DMARC1;p=none;rua=mailto:postmaster@trondheim-redcross.no;ruf=mailto:johess@trondheim-redcross.no;fo:0;adkim=r;aspf=r;pct=100;rf=afrf;ri=86400;sp=none domain=vsender-2.com;v=DMARC1;p=none;rua=mailto:postmaster@vsender-2.com;ruf=mailto:postmaster@vsender-2.com;adkim=r;aspf=r;pct=100;rf:afrf;ri=86400;sp=none domain=vsender-3.com;v=DMARC1;p=none;rua=mailto:postmaster@vsender-3.com;ruf=mailto:postmaster@vsender-3.com;adkim=r;aspf=r;pct=100;rf:afrf;ri=86400;sp=none domain=wfyi.org;v=DMARC1;p=none;rua=mailto:dmarc1630@wfyi.org;ruf=mailto:dmarc1630@wfyi.org;fo:0;adkim=r;aspf=r;pct=100;rf=afrf;ri=86400;sp=none domain=wk1business.com;v=DMARC1;p=none;rua=mailto:postmaster@wk1business.com;ruf=mailto:postmaster@wk1business.com;adkim=r;aspf=r;pct=100;rf:afrf;ri=86400;sp=none domain=teogenes.com.br;v=DMARC1;p=quarantine;rua=mailto:retorno@teogenes.com.br;fo:1:d;adkim=r;aspf=r;rf=afrf;sp=quarantine domain=wkcplatnium.com;v=DMARC1;p=none;rua=mailto:postmaster@wkcplatnium.com;ruf=mailto:postmaster@wkcplatnium.com;adkim=r;aspf=r;pct=100;rf:afrf;ri=86400;sp=none domain=brightworksgroup.net;v=DMARC1;p=none;0;adkim=r;aspf=r domain=bronzemail-usa.com;v=DMARC1;p=none;rua=mailto:postmaster@bronzemail-usa.com;ruf=mailto:postmaster@bronzemail-usa.com;adkim=r;aspf=r;pct=100;rf:afrf;ri=86400;sp=none domain=driveconsumer.com;v=DMARC1;p=none;rua=mailto:postmaster@driveconsumer.com;ruf=mailto:postmaster@driveconsumer.com;adkim=r;aspf=r;pct=100;rf:afrf;ri=86400;sp=none domain=econnect1.com;v=DMARC1;p=none;rua=mailto:postmaster@econnect1.com;ruf=mailto:postmaster@econnect1.com;adkim=r;aspf=r;pct=100;rf:afrf;ri=86400;sp=none domain=esender1.com;v=DMARC1;p=none;rua=mailto:postmaster@esender1.com;ruf=mailto:postmaster@esender1.com;adkim=r;aspf=r;pct=100;rf:afrf;ri=86400;sp=none domain=esender3.com;v=DMARC1;p=none;rua=mailto:postmaster@esender3.com;ruf=mailto:postmaster@esender3.com;adkim=r;aspf=r;pct=100;rf:afrf;ri=86400;sp=none domain=lns.com;v=DMARC1;p=none;rua=mailto:dmarc@lns.com;ruf=mailto:dmarc@lns.com;0;adkim=r;aspf=r;pct=100;rf=afrf;ri=86400;sp=none domain=my-dear-lady.com;v=DMARC1;p=none;rua=mailto:postmaster@my-dear-lady.com;ruf=mailto:postmaster@my-dear-lady.com;adkim=r;aspf=r;pct=100;rf:afrf;ri=86400;sp=none domain=theluxurycloset.info;v=DMARC1;p=reject;adkim=s;aspf=r;rf=afrf;;pct=100 domain=newsletter.ironpony.net;v=DMARC1;p=none;rua=mailto:postmaster@newsletter.ironpony.net;ruf=mailto:postmaster@newsletter.ironpony.net;adkim=r;aspf=r;pct=100;rf:afrf;ri=86400;sp=none domain=cmnet.org;v=DMARC1;p=none;sp=none;rua=mailto:postmaster@cmnet.org!10m;;pct=100;ri=86400 domain=coachingcompass.com;v=DMARC1;p=quarantine;rua=mailto:dan@darau.com;ruf=mailto:dan@darau.com;1:d:s;adkim=r;aspf=r;rf=afrf;sp=quarantine domain=genetex.com;v=DMARC1;p=none;sp-none;rua=mailto:postmaster@genetex.com!1m;ruf=mailto:postmaster@genetex.com!1m;rf=afrf;pct=100;ri=86400 Mail-DMARC-1.20260306/t/03.Base.t000444000765000024 1221115152630466 14761 0ustar00mattstaff000000000000use strict; use warnings; use Data::Dumper; use Net::DNS::Resolver::Mock; use Test::More; use Test::File::ShareDir -share => { -dist => { 'Mail-DMARC' => 'share' } }; use lib 'lib'; my $mod = 'Mail::DMARC::Base'; use_ok($mod); my $base = $mod->new; isa_ok( $base, $mod ); isa_ok( $base->config, 'Config::Tiny' ); isa_ok( $base->get_resolver(), 'Net::DNS::Resolver' ); # invalid config file $base = $mod->new( config_file => 'no such config' ); eval { $base->config }; chomp $@; ok( $@, "invalid config file" ); # alternate config file $base = $mod->new(); eval { $base->config('t/mail-dmarc.ini'); }; chomp $@; ok( !$@, "alternate config file" ); my $resolver = new Net::DNS::Resolver::Mock(); $base->set_resolver($resolver); __any_inet_to(); __is_public_suffix(); __has_dns_rr(); __is_valid_ip(); __is_valid_domain(); __epoch_to_iso(); __get_prefix(); __get_sharefile(); __psl_cached(); __psl_cached_reload(); done_testing(); exit; #warn Dumper($base); sub __epoch_to_iso { my $iso = $base->epoch_to_iso(time); ok( $iso, "epoch_to_iso, $iso" ); }; sub __any_inet_to { my @test_ips = ( '1.1.1.1', '10.0.1.1', '2002:4c79:6240::1610:9fff:fee5:fb5', '2607:f060:b008:feed::6', ); foreach my $ip (@test_ips) { my $bin = $base->any_inet_pton($ip); ok( $bin, "any_inet_pton, $ip" ); my $pres = $base->any_inet_ntop($bin); ok( $pres, "any_inet_ntop, $ip" ); if ( $pres eq $ip ) { cmp_ok( $pres, 'eq', $ip, "any_inet_ntop, $ip" ); } else { # on some systems, a :: pattern gets a zero inserted. Mimic that my $zero_filled = $ip; $zero_filled =~ s/::/:0:/g; cmp_ok( $pres, 'eq', $zero_filled, "any_inet_ntop, $ip" ) or diag "presentation: $zero_filled\nresult: $pres"; } } } sub __is_valid_ip { # positive tests foreach (qw/ 0.0.0.0 1.1.1.1 255.255.255.255 2607:f060:b008:feed::2 /) { ok( $base->is_valid_ip($_), "is_valid_ip, $_" ); } # negative tests foreach (qw/ 256.1.1.1 a 1.1.1.256 /) { ok( !$base->is_valid_ip($_), "is_valid_ip, neg, $_" ); } } sub __is_valid_domain { # positive tests foreach (qw/ test.sch.uk example.com bbc.co.uk 3.am /) { ok( $base->is_valid_domain($_), "is_valid_domain, $_" ); } # negative tests foreach (qw/ example.m bbc.co.k 3.a /) { ok( !$base->is_valid_domain($_), "is_valid_domain, $_" ); } } sub __has_dns_rr { my %tests = ( 'NS:tnpi.net' => 1, 'NS:fake.mail-dmarc.tnpi.net' => 0, 'A:www.tnpi.net' => 1, 'MX:tnpi.net' => 1, 'MX:gmail.com' => 1, ); foreach my $dom ( keys %tests ) { my $r = $base->has_dns_rr( split /:/, $dom ); # no need to raise test errors for CPAN test systems with unreliable DNS next if !$r && $tests{$dom}; ok( $r >= $tests{$dom}, "has_dns_rr, $dom" ); } } sub __is_public_suffix { my %tests = ( 'www.tnpi.net' => 0, 'tnpi.net' => 0, 'net' => 1, 'com' => 1, 'co.uk' => 1, '*.uk' => 0, 'google.com' => 0, 'a' => 0, 'z' => 0, 'test.sch.uk' => 1, 'sch.uk' => 0, ); foreach my $dom ( keys %tests ) { my $t = $tests{$dom} == 0 ? 'neg' : 'pos'; cmp_ok( $tests{$dom}, '==', $base->is_public_suffix($dom), "is_public_suffix, $t, $dom" ); } } sub __get_prefix { is_deeply( [ $base->get_prefix() ], [ '/usr/local/', '/opt/local/', '/', './' ], "get_prefix: /usr/local/, /opt/local/, /, ./", ); is_deeply( [ $base->get_prefix('etc') ], [ '/usr/local/etc', '/opt/local/etc', '/etc', './etc' ], "get_prefix(etc): /usr/local/etc, /opt/local/etc, /etc, ./etc", ); is_deeply( [ $base->get_prefix('share') ], [ '/usr/local/share', '/opt/local/share', '/share', './share' ], "get_prefix(share): /usr/local/share, /opt/local/share, /share, ./share", ); } sub __get_sharefile { # throws an exception until after 'make install' has been run my $r; eval { $r = $base->get_sharefile('mail-dmarc.ini'); }; SKIP: { skip '"make install" not yet run', 1 if $@; ok($r, "get_sharefile: $r"); }; } sub __psl_cached { no warnings 'once'; cmp_ok($Mail::DMARC::psl_loads, '==', 1, 'Public Suffix List cached'); } sub __psl_cached_reload { no warnings 'once'; cmp_ok($Mail::DMARC::psl_loads, '==', 1, 'Public Suffix List loaded'); my $file = $base->find_psl_file(); my $future = time() + 3600; utime ( $future, $future, $file ); my $check = $base->check_public_suffix_list(); cmp_ok($Mail::DMARC::psl_loads, '==', 2, 'Public Suffix List reloaded'); cmp_ok($check, '==', 1, 'Public Suffix List reloaded true return'); $check = $base->check_public_suffix_list(); cmp_ok($check, '==', 0, 'Public Suffix List reloaded false return'); } Mail-DMARC-1.20260306/t/04.PurePerl.t000444000765000024 4011415152630466 15651 0ustar00mattstaff000000000000use strict; use warnings; use Data::Dumper; use Net::DNS::Resolver::Mock; use Test::More; use URI; use Test::File::ShareDir -share => { -dist => { 'Mail-DMARC' => 'share' } }; use lib 'lib'; use_ok('Mail::DMARC::PurePerl'); my $resolver = new Net::DNS::Resolver::Mock(); $resolver->zonefile_parse(join("\n", '_dmarc.mail-dmarc.tnpi.net. 600 TXT "v=DMARC1; p=reject; rua=mailto:invalid@theartfarm.com; ruf=mailto:invalid@theartfarm.com; pct=90"', '_dmarc.tnpi.net. 600 TXT "v=DMARC1; p=reject; rua=mailto:dmarc-feedback@theartfarm.com; ruf=mailto:dmarc-feedback@theartfarm.com; pct=100" ', 'tnpi.net. 600 MX 10 mail.theartfarm.com.', 'tnpi.net._report._dmarc.theartfarm.com. 600 TXT "v=DMARC1"', 'cadillac.net._report._dmarc.theartfarm.com. 600 TXT "v=DMARC1"', 'mail-dmarc.tnpi.net._report._dmarc.theartfarm.com. 600 TXT "v=DMARC1; rua=mailto:invalid-test@theartfarm.com;"', 'invalid-sp-and-with-rua.example.com. 600 MX 10 mail.example.com.', 'invalid-sp-and-without-rua.example.com. 600 MX 10 mail.example.com.', '_dmarc.invalid-sp-and-with-rua.example.com. 600 TXT "v=DMARC1; p=reject; sp=invalid; rua=mailto:rua@example.com"', '_dmarc.invalid-sp-and-without-rua.example.com. 600 TXT "v=DMARC1; p=reject; sp=invalid"', '')); my @test_policy = ( 'v', 'DMARC1', # Section 6.2, Formal Definition 'p', 'reject', # the v(ersion) and request(p) are ordered 'rua', 'mailto:invalid@theartfarm.com', 'ruf', 'mailto:invalid@theartfarm.com', 'pct', 90, ); my %test_policy = @test_policy; my $n; my $test_rec = join( '; ', map { $_ . '=' . $test_policy{$_} } grep { !( $n++ % 2 ) } @test_policy ); # extract keys my $dmarc = Mail::DMARC::PurePerl->new; $dmarc->config('t/mail-dmarc.ini'); $dmarc->set_resolver($resolver); isa_ok( $dmarc, 'Mail::DMARC::PurePerl' ); test_get_from_dom(); test_fetch_dmarc_record(); test_get_organizational_domain(); test_exists_in_dns(); test_is_spf_aligned(); test_is_dkim_aligned(); test_is_aligned(); test_is_whitelisted(); test_discover_policy(); test_validate(); test_validate_invalid_sp(); test_has_valid_reporting_uri(); test_external_report(); test_verify_external_reporting( 'tnpi.net', 'theartfarm.com', 1 ); test_verify_external_reporting( 'cadillac.net', 'theartfarm.com', 1 ); test_verify_external_reporting( 'mail-dmarc.tnpi.net', 'theartfarm.com', 1 ); _test_reason(); done_testing(); exit; sub _test_reason { $dmarc->init(); $dmarc->source_ip('66.128.51.165'); $dmarc->envelope_to('recipient.example.com'); $dmarc->envelope_from('dmarc-nonexist.tnpi.net'); $dmarc->header_from('mail-dmarc.tnpi.net'); $dmarc->dkim([ { domain => 'tnpi.net', selector => 'jan2015', result => 'fail', human_result=> 'fail (body has been altered)', } ]); $dmarc->spf([ { domain => 'tnpi.net', scope => 'mfrom', result => 'pass', }, { scope => 'helo', domain => 'mail.tnpi.net', result => 'fail', }, ]); my $policy = $dmarc->discover_policy; ok( $policy, "discover_policy" ); my $result = $dmarc->validate($policy); ok( ref $result, "result is a ref"); ok( $result->{result} eq 'pass', "result=pass"); ok( $result->{spf} eq 'pass', "spf=pass"); ok( $result->{disposition} eq 'none', "disposition=none"); $result->disposition('reject'); ok( $result->{disposition} eq 'reject', "disposition changed to reject"); ok( $result->reason( type => 'local_policy' ), "added reason" ); ok( $result->reason( type => 'local_policy', comment => 'testing' ), "added reason 2" ); #warn Data::Dumper::Dumper($result->reason); ok( $dmarc->save_aggregate(), "save aggregate"); } sub test_verify_external_reporting { my ( $dmarc_dom, $dest_dom, $outcome ) = @_; my $ver = 'verify_external_reporting'; my $policy; eval { $policy = $dmarc->policy->parse( "v=DMARC1; p=none; rua=mailto:dmarc-feedback\@$dest_dom"); }; $policy->{domain} = $dmarc_dom; ok( $policy, "new policy" ); $dmarc->result->published($policy); my $uri = URI->new("mailto:test\@$dest_dom"); cmp_ok( $outcome, 'eq', $dmarc->$ver( { uri => $uri } ), "$ver, $dmarc_dom, $dest_dom" ); # a DMARC record with a RUA override return if $dmarc_dom ne 'mail-dmarc.tnpi.net'; my $uri_should_be = $dmarc->report->uri->parse( URI->new("mailto:invalid-test\@theartfarm.com") ); my $uri_via_net = $dmarc->report->uri->parse( $dmarc->result->published->rua ); is_deeply( $uri_via_net->[0], $uri_should_be->[0], "$ver, override rua" ); } sub test_external_report { my @test_doms = qw/ example.com silly.com /; foreach my $dom (@test_doms) { my $policy = $dmarc->policy->parse('v=DMARC1'); $policy->{domain} = $dom; ok( $policy, "new policy" ); $dmarc->result->published($policy); my $uri = URI->new("mailto:test\@$dom"); # warn "path: " . $uri->path; ok( $uri, "new URI" ); ok( !$dmarc->external_report($uri), "external_report, $uri for $dom" ); } foreach my $dom (@test_doms) { my $policy = $dmarc->policy->parse('v=DMARC1'); $policy->{domain} = "$dom.com"; ok( $policy, "new policy" ); $dmarc->result->published($policy); my $uri = URI->new("mailto:test\@$dom"); # warn "path: " . $uri->path; ok( $uri, "new URI" ); ok( $dmarc->external_report($uri), "external_report, $uri for $dom.com" ); } } sub test_has_valid_reporting_uri { my @valid = ( 'mailto:dmarc@example.com', # canonical example 'mailto:dmarc@example.com,http://example.com/dmarc', # two matches 'ftp://dmarc.example.com,http://example.com/dmarc', # http only ); $dmarc->result->published->{domain} = 'example.com'; foreach my $v (@valid) { my $r_ref = $dmarc->has_valid_reporting_uri($v); ok( $r_ref, "has_valid_reporting_uri, $v" ); } my $uris; $uris = $dmarc->has_valid_reporting_uri( 'mailto:invalid@no-premission.example.com' ); ok( 1 == $uris, "has_valid_reporting_uri, single filtered"); # invalid tests my @invalid = ( 'ftp://ftp.example.com', # invalid schemes 'gopher://www.example.com/dmarc', 'scp://secure.example.com', 'http://www.example.com/dmarc', # host doesn't match ); $dmarc->result->published->{domain} = 'example.com'; foreach my $v (@invalid) { my $r = $dmarc->has_valid_reporting_uri($v); ok( !$r, "has_valid_reporting_uri, neg, $v" ) or diag Dumper($r); } my %real = (); # real life tests foreach my $dom ( keys %real ) { $dmarc->result->published->{domain} = $dom; my $r_ref = $dmarc->has_valid_reporting_uri($real{$dom}); ok( $r_ref, "has_valid_reporting_uri, $dom" ); }; } sub test_discover_policy { $dmarc->init(); $dmarc->header_from('mail-dmarc.tnpi.net'); my $policy = $dmarc->discover_policy; ok( $policy, "discover_policy" ) or return diag Data::Dumper::Dumper($dmarc); $policy->apply_defaults; my $expected = { %test_policy, aspf => 'r', # $pol->new adds the defaults that are adkim => 'r', # implied in all DMARC records ri => 86400, rf => 'afrf', fo => 0, domain => 'mail-dmarc.tnpi.net', }; is_deeply( $policy, $expected, 'discover_policy, deeply' ); is( $dmarc->is_subdomain(), 1, "discover_policy, is_subdomain" ); $dmarc->init(); $dmarc->header_from('tnpi.net'); $policy = $dmarc->discover_policy; is( $dmarc->is_subdomain(), 0, "fetch_dmarc_record, is_subdomain" ); } sub get_test_headers { return ( 'From: Sample User ' => 'example.com', 'From: Sample Middle User ' => 'example.com', 'From: "Sample User" ' => 'example.com', 'From: "Sample Middle User" ' => 'example.com', 'Sample User ' => 'example.com', 'user@example.com' => 'example.com', '' => 'example.com', ' ' => 'example.com', 'Sample User ,Sample2' => 'example2.com', 'From: "Test 1.1.5"' => '', ); } sub test_is_spf_aligned { ok( $dmarc->header_from('example.com'), "spf, set header_from" ); ok( $dmarc->spf( domain => 'example.COM', scope => 'mfrom', result => 'pass' ), 'spf, set spf' ); ok( $dmarc->is_spf_aligned(), "is_spf_aligned" ); ok( 'strict' eq $dmarc->result->spf_align, "is_spf_aligned, strict" ) or diag Dumper( $dmarc->result ); $dmarc->header_from('mail.example.com'); ok( $dmarc->spf( domain => 'example.com', scope => 'mfrom', result => 'pass' ), 'spf, set spf' ); ok( $dmarc->policy->aspf('r'), "spf alignment->r" ); ok( $dmarc->is_spf_aligned(), "is_spf_aligned, relaxed" ); ok( 'relaxed' eq $dmarc->result->spf_align, "is_spf_aligned, relaxed" ); $dmarc->header_from('mail.exUmple.com'); ok( $dmarc->spf( domain => 'example.com', scope => 'mfrom', result => 'pass' ), 'spf, set spf' ); ok( !$dmarc->is_spf_aligned(), "is_spf_aligned, neg" ); } sub test_is_dkim_aligned { ok( $dmarc->header_from('example.com'), "dkim, set header_from" ); ok( $dmarc->dkim( [ { domain => 'mailing-list.com', selector => 'apr2013', result => 'fail', human_result => 'fail (body has been altered)', }, { domain => 'example.com', selector => 'apr2013', result => 'pass', human_result => 'pass', }, ] ), "dkim, setup" ); ok( $dmarc->is_dkim_aligned(), "is_dkim_aligned, strict" ); ok( $dmarc->header_from('mail.example.com'), "dkim, set header_from" ); ok( $dmarc->is_dkim_aligned(), "is_dkim_aligned, relaxed" ); # negative test ok( $dmarc->header_from('mail.exaNple.com'), "dkim, set header_from" ); ok( !$dmarc->is_dkim_aligned(), "is_dkim_aligned, miss" ); # no DKIM signatures ok( $dmarc->dkim( [] ), "dkim, no signatures" ); ok( !$dmarc->is_dkim_aligned(), "is_dkim_aligned, empty" ); # PSL listed domains ok( $dmarc->dkim( [ { domain => 'net', selector => 'apr2013', result => 'pass', human_result => 'pass', }, ] ), "dkim, setup" ); ok( $dmarc->header_from('net'), "dkim, set header_from" ); ok( $dmarc->is_dkim_aligned(), "is_dkim_aligned, relaxed" ); # negative test ok( $dmarc->header_from('example.net'), "dkim, set header_from" ); ok( !$dmarc->is_dkim_aligned(), "is_dkim_aligned, miss" ); } sub test_is_aligned { $dmarc->result->spf('pass'); $dmarc->result->dkim('pass'); ok( $dmarc->is_aligned(), "is_aligned, both" ); $dmarc->result->dkim('fail'); ok( $dmarc->is_aligned(), "is_aligned, spf" ); $dmarc->result->dkim('pass'); $dmarc->result->spf('fail'); ok( $dmarc->is_aligned(), "is_aligned, dkim" ); $dmarc->result->dkim('fail'); ok( !$dmarc->is_aligned(), "is_aligned, none" ) or diag Data::Dumper::Dumper( $dmarc->is_aligned() ); } sub test_is_whitelisted { my %good = ( '127.0.0.1' => 'local_policy', '127.0.0.3' => 'trusted_forwarder', ); foreach ( keys %good ) { cmp_ok( $dmarc->is_whitelisted($_), 'eq', $good{$_}, "is_whitelisted, $_, $good{$_}"); }; my @bad = qw/ 127.0.0.2 10.0.0.0 /; foreach ( @bad ) { ok( ! $dmarc->is_whitelisted($_), "is_whitelisted, neg, $_"); }; }; sub test_validate { my %sample_dmarc = ( config_file => 'mail-dmarc.ini', source_ip => '192.0.1.1', envelope_to => 'example.com', envelope_from => 'cars4you.info', header_from => 'tnpi.net', dkim => [ { domain => 'example.com', selector => 'apr2013', result => 'fail', human_result => 'fail (body has been altered)', } ], spf => [ { domain => 'tnpi.net', scope => 'mfrom', result => 'pass', } ], ); $dmarc = Mail::DMARC::PurePerl->new(%sample_dmarc); $dmarc->set_resolver($resolver); eval { $dmarc->validate(); }; #print Dumper($dmarc->result); ok($dmarc->is_spf_aligned(), "validate, one-shot, is_spf_aligned, yes" ); ok(!$dmarc->is_dkim_aligned(), "validate, one-shot, is_dkim_aligned, no" ); } sub test_validate_invalid_sp { my %subtests = ( 'invalid-sp-and-with-rua.example.com' => 'pass', 'invalid-sp-and-without-rua.example.com' => 'none', ); while (my ($header_from, $expected_result) = each %subtests) { my %sample_dmarc = ( config_file => 'mail-dmarc.ini', source_ip => '192.0.1.1', envelope_to => 'example.com', envelope_from => 'cars4you.info', header_from => $header_from, dkim => [], spf => [ { domain => $header_from, scope => 'mfrom', result => 'pass', } ], ); $dmarc = Mail::DMARC::PurePerl->new(%sample_dmarc); $dmarc->set_resolver($resolver); eval { $dmarc->validate(); }; is($dmarc->result->result, $expected_result, "DMARC result is ${expected_result}") or diag Dumper($dmarc->result); } } sub test_exists_in_dns { my %tests = ( 'tnpi.net' => 1, 'fake.mail-dmarc.tnpi.net' => 1, # organizational name exists 'no-such-made-up-name-should-exist.com.uk.nonsense' => 0, ); foreach my $dom ( keys %tests ) { $dmarc->init; my $r = $dmarc->exists_in_dns($dom); ok( $r >= $tests{$dom}, "exists_in_dns, $dom, $r" ); } } sub test_get_organizational_domain { my %domains = ( 'tnpi.net' => 'tnpi.net', 'www.tnpi.net' => 'tnpi.net', 'plus.google.com' => 'google.com', 'bbc.co.uk' => 'bbc.co.uk', 'www.bbc.co.uk' => 'bbc.co.uk', ); foreach ( keys %domains ) { cmp_ok( $domains{$_}, 'eq', $dmarc->get_organizational_domain($_), "get_organizational_domain, $_" ); } } sub test_fetch_dmarc_record { my ($matches) = $dmarc->fetch_dmarc_record('mail-dmark.tnpi.net'); is_deeply( $matches, [], 'fetch_dmarc_record, non-exist' ); #warn Dumper($matches); ($matches) = $dmarc->fetch_dmarc_record('mail-dmarc.tnpi.net'); is_deeply( $matches, [$test_rec], 'fetch_dmarc_record' ); ($matches) = $dmarc->fetch_dmarc_record('com'); is_deeply( $matches, [], 'fetch_dmarc_record, 1.2.4 TLD lookup not allowed' ); } sub test_get_from_dom { my %froms = get_test_headers(); foreach my $h ( keys %froms ) { $dmarc->init; $dmarc->header_from_raw($h); my $s; eval { $s = $dmarc->get_from_dom() }; if ( $froms{$h} ) { ok( $s eq $froms{$h}, "get_from_dom, $s eq $froms{$h}" ); } else { chomp $@; ok( 1, "get_from_dom, $h, $@" ); }; } } Mail-DMARC-1.20260306/t/06.Result.t000444000765000024 2213315152630466 15374 0ustar00mattstaff000000000000use strict; use warnings; use Data::Dumper; use Net::DNS::Resolver::Mock; use Test::More; use Test::File::ShareDir -share => { -dist => { 'Mail-DMARC' => 'share' } }; use lib 'lib'; use_ok('Mail::DMARC::PurePerl'); use_ok('Mail::DMARC::Result'); my $resolver = new Net::DNS::Resolver::Mock(); $resolver->zonefile_parse(join("\n", 'tnpi.net. 600 A 66.128.51.170', '_dmarc.tnpi.net. 600 TXT "v=DMARC1; p=reject; rua=mailto:dmarc-feedback@theartfarm.com; ruf=mailto:dmarc-feedback@theartfarm.com; pct=100"', 'nodmarcrecord.blogspot.com. 600 A 142.251.37.1', '')); my $pp = Mail::DMARC::PurePerl->new; my $result = Mail::DMARC::Result->new; $pp->set_resolver($resolver); isa_ok( $result, 'Mail::DMARC::Result' ); my $test_dom = 'tnpi.net'; test_published(); test_no_policy(); test_disposition(); test_dkim(); test_dkim_align(); test_spf(); test_spf_align(); test_result(); test_reason(); test_dkim_meta(); test_published_errors(); done_testing(); exit; sub _test_pass_strict { $pp->init(); $pp->header_from($test_dom); $pp->dkim( [ { domain => $test_dom, result => 'pass', selector => 'apr2013' } ] ); $pp->spf( { domain => $test_dom, result => 'pass', scope => 'mfrom' } ); $pp->validate(); delete $pp->result->{published}; my $expected = { 'result' => 'pass', 'disposition' => 'none', 'dkim' => 'pass', 'spf' => 'pass', 'spf_align' => 'strict', 'dkim_meta' => { 'domain' => 'tnpi.net', 'identity' => '', 'selector' => 'apr2013', }, 'dkim_align' => 'strict', reason => [], }; is_deeply( $pp->result, $expected, "result, pass, strict, $test_dom") or diag Data::Dumper::Dumper( $pp->result ); } sub _test_pass_relaxed { $pp->init(); $pp->header_from("www.$test_dom"); $pp->dkim( [ { domain => $test_dom, result => 'pass', selector => 'apr2013' } ] ); $pp->spf( { scope => 'mfrom', domain => $test_dom, result => 'pass' } ); $pp->validate(); delete $pp->result->{published}; my $skip_reason; if ( !$pp->result->dkim ) { # typically a DNS failure, $skip_reason = "look like DNS is not working"; } SKIP: { skip $skip_reason, 1 if $skip_reason; my $expected = { 'result' => 'pass', 'dkim' => 'pass', 'spf' => 'pass', 'disposition' => 'none', 'dkim_align' => 'relaxed', 'dkim_meta' => { 'domain' => 'tnpi.net', 'identity' => '', 'selector' => 'apr2013', }, 'spf_align' => 'relaxed', reason => [], }; is_deeply( $pp->result, $expected, "pass, relaxed, $test_dom" ) or diag Data::Dumper::Dumper( $pp->result ); } } sub _test_fail_strict { my $pol = shift || 'reject'; $pp->init(); my $from_dom = "www.$test_dom"; $pp->header_from($from_dom); $pp->dkim( [ { domain => $test_dom, result => 'pass', selector => 'apr2013' } ] ); $pp->spf( { scope => 'mfrom', domain => $test_dom, result => 'pass' } ); my $policy = $pp->policy->parse("v=DMARC1; p=$pol; aspf=s; adkim=s"); $policy->{domain} = $from_dom; $pp->result->published($policy); $pp->{policy} = $policy; $pp->validate($policy); ok( !$pp->is_dkim_aligned, "is_dkim_aligned, neg" ); ok( !$pp->is_spf_aligned, "is_spf_aligned, neg" ); ok( !$pp->is_aligned(), "is_aligned, neg" ); delete $pp->result->{published}; my $expected = { 'disposition' => $pol, 'dkim' => 'fail', 'spf' => 'fail', 'result' => 'fail', reason => [], }; is_deeply( $pp->result, $expected, "result, fail, strict, $test_dom" ) or diag Data::Dumper::Dumper( $pp->result ); } sub _test_fail_sampled_out { my $pol = 'reject'; $pp->init(); my $from_dom = "www.$test_dom"; $pp->header_from($from_dom); $pp->dkim( [ { domain => $test_dom, result => 'pass', selector => 'apr2013' } ] ); $pp->spf( { scope => 'mfrom', domain => $test_dom, result => 'pass' } ); my $policy = $pp->policy->parse("v=DMARC1; p=$pol; aspf=s; adkim=s; pct=0"); $policy->{domain} = $from_dom; $pp->result->published($policy); $pp->{policy} = $policy; $pp->validate($policy); ok( !$pp->is_dkim_aligned, "is_dkim_aligned, neg" ); ok( !$pp->is_spf_aligned, "is_spf_aligned, neg" ); ok( !$pp->is_aligned(), "is_aligned, neg" ); delete $pp->result->{published}; my $expected = { 'disposition' => 'quarantine', 'dkim' => 'fail', 'spf' => 'fail', 'reason' => [{ 'type' => 'sampled_out' }], 'result' => 'fail', }; is_deeply( $pp->result, $expected, "result, fail, strict, sampled out, $test_dom" ) or diag Data::Dumper::Dumper( $pp->result ); } sub _test_fail_nonexist { $pp->init(); $pp->{header_from} = 'host.nonexistent-tld'; # the ->header_from method would validate $pp->validate(); # some test machines return 'interesting' results for queries of non-existent # domains. That's not worth raising a test error. my $skip_reason; if ( ! $pp->result->reason || $pp->result->reason->[0]->comment ne 'host.nonexistent-tld not in DNS' ) { $skip_reason = "DNS returned 'interesting' results for invalid domain"; }; SKIP: { skip $skip_reason, 1 if $skip_reason; is_deeply( $pp->result, { 'result' => 'none', 'disposition' => 'none', 'dkim' => '', 'spf' => '', 'reason' => [{ 'comment' => 'host.nonexistent-tld not in DNS', 'type' => 'other', }], }, "result, none, nonexist" ) or diag Data::Dumper::Dumper( $pp->result ); } } sub test_published { _test_pass_strict(); _test_pass_relaxed(); _test_fail_strict('reject'); _test_fail_strict('none'); _test_fail_strict('quarantine'); _test_fail_sampled_out(); _test_fail_nonexist(); } sub test_no_policy { $pp->init(); $pp->header_from( 'nodmarcrecord.blogspot.com' ); $pp->validate(); my $skip_reason; if ( !$pp->result->reason ) { # typically a DNS failure, $skip_reason = "look like DNS is not working"; }; SKIP: { skip $skip_reason, 1 if $skip_reason; is_deeply( $pp->result, { 'result' => 'none', 'disposition' => 'none', 'dkim' => '', 'spf' => '', 'reason' => [{ 'comment' => 'no policy', 'type' => 'other', }], }, "result, fail, nonexist" ) or diag Data::Dumper::Dumper( $pp->result ); }; } sub test_disposition { # positive tests foreach (qw/ none reject quarantine NONE REJECT QUARANTINE /) { ok( $result->disposition($_), "disposition, $_" ); } # negative tests foreach (qw/ non rejec quarantin NON REJEC QUARANTIN /) { eval { $result->disposition($_) }; chomp $@; ok( $@, "disposition, neg, $_, $@" ); } } sub test_dkim { test_pass_fail('dkim'); } sub test_dkim_align { strict_relaxed('dkim_align'); } sub test_dkim_meta { ok( $result->dkim_meta( { domain => 'test' } ), "dkim_meta" ); } sub test_published_errors { my $res = Mail::DMARC::Result->new; eval { $res->published() }; like( $@, qr/no policy discovered/i, 'published croaks when policy not set' ); eval { $res->published( {} ) }; like( $@, qr/tag the policy object with a domain/i, 'published croaks when policy has no domain' ); } sub test_spf { test_pass_fail('spf'); } sub test_spf_align { strict_relaxed('spf_align'); } sub test_reason { # positive tests foreach ( qw/ forwarded sampled_out trusted_forwarder mailing_list local_policy other / ) { ok( $result->reason( type => $_, comment => "test comment" ), "reason type: $_" ); } # negative tests foreach (qw/ any reason not in above list /) { eval { $result->reason( type => $_ ) }; chomp $@; ok( $@, "reason, $_, $@" ); } } sub test_result { test_pass_fail('result'); } sub test_pass_fail { my $sub = shift; # positive tests foreach (qw/ pass fail PASS FAIL /) { ok( $result->$sub($_), "$sub, $_" ); } # negative tests foreach (qw/ pas fai PAS FAI /) { eval { $result->$sub($_) }; chomp $@; ok( $@, "$sub, neg, $_, $@" ); } } sub strict_relaxed { my $sub = shift; # positive tests foreach (qw/ strict relaxed STRICT RELAXED /) { ok( $result->$sub($_), "$sub, $_" ); } # negative tests foreach (qw/ stric relaxe STRIC RELAXE /) { eval { $result->$sub($_) }; chomp $@; ok( $@, "$sub, neg, $_, $@" ); } } Mail-DMARC-1.20260306/t/09.HTTP.t000444000765000024 424615152630466 14665 0ustar00mattstaff000000000000use strict; use warnings; use Data::Dumper; use Net::DNS::Resolver::Mock; use Test::More; use Test::File::ShareDir -share => { -dist => { 'Mail-DMARC' => 'share' } }; use lib 'lib'; foreach my $req ( 'CGI', 'DBD::SQLite 1.31', 'JSON', 'Net::Server::HTTP' ) { eval "use $req"; if ($@) { plan( skip_all => "$req not available" ); exit; } }; my $resolver = new Net::DNS::Resolver::Mock(); $resolver->zonefile_parse(join("\n", 'tnpi.net. 600 A 66.128.51.170', '_dmarc.tnpi.net. 600 TXT "v=DMARC1; p=reject; rua=mailto:dmarc-feedback@theartfarm.com; ruf=mailto:dmarc-feedback@theartfarm.com; pct=100"', #'tnpi.net. 600 MX 10 mail.theartfarm.com.', '')); my $mod = 'Mail::DMARC::HTTP'; use_ok($mod); my $http = $mod->new; isa_ok( $http, $mod ); my $cgi = CGI->new(); my $r = Mail::DMARC::HTTP::serve_validator($cgi, $resolver); ok($r eq 'missing POST data', "serve_validator, missing POST data"); $cgi->param('POSTDATA', 'foo'); $r = Mail::DMARC::HTTP::serve_validator($cgi, $resolver); like($r, qr/expected/, "serve_validator, invalid JSON"); $cgi->param('POSTDATA', '{"foo":"bar"}'); $r = Mail::DMARC::HTTP::serve_validator($cgi, $resolver); like($r, qr/no header_from/, "serve_validator, missing header_from"); $cgi->param('POSTDATA', '{"header_from":"tnpi.net"}'); $r = Mail::DMARC::HTTP::serve_validator($cgi, $resolver); like($r, qr/"spf":""/, "serve_validator, missing SPF"); like($r, qr/"dkim":"fail"/, "serve_validator, missing DKIM"); $cgi->param('POSTDATA', '{"header_from":"tnpi.net","spf":[{"domain":"tnpi.net","scope":"mfrom","result":"pass"}]}'); $r = Mail::DMARC::HTTP::serve_validator($cgi, $resolver); like($r, qr/"spf":"pass"/, "serve_validator, pass SPF"); like($r, qr/"dkim":"fail"/, "serve_validator, missing DKIM"); $cgi->param('POSTDATA', '{"header_from":"tnpi.net","dkim":[{"domain":"tnpi.net","selector":"mar2013","result":"pass"}]}'); $r = Mail::DMARC::HTTP::serve_validator($cgi, $resolver); like($r, qr/"spf":""/, "serve_validator, missing SPF"); like($r, qr/"dkim":"pass"/, "serve_validator, pass DKIM"); # this starts up the httpd daemon #$http->dmarc_httpd(); done_testing(); Mail-DMARC-1.20260306/t/10.Report.t000444000765000024 443015152630466 15344 0ustar00mattstaff000000000000use strict; use warnings; use Data::Dumper; use Test::More; use IO::Compress::Gzip; use IO::Uncompress::Gunzip qw($GunzipError); #use IO::Compress::Zip; # legacy format #use IO::Uncompress::Unzip qw($UnzipError); use lib 'lib'; eval "use DBD::SQLite 1.31"; if ($@) { plan( skip_all => 'DBD::SQLite not available' ); exit; } my $mod = 'Mail::DMARC::PurePerl'; use_ok($mod); my $dmarc = $mod->new; isa_ok( $dmarc, $mod ); # this is equivalent to: # Mail::DMARC::Report( dmarc => $dmarc ); my $report = $dmarc->report; isa_ok( $report, 'Mail::DMARC::Report' ); isa_ok( $report->sendit, 'Mail::DMARC::Report::Send' ); isa_ok( $report->store, 'Mail::DMARC::Report::Store' ); isa_ok( $report->receive, 'Mail::DMARC::Report::Receive' ); my $test_dom = 'tnpi.net'; test_compress(); #setup_dmarc_result() or die "failed setup\n"; #$dmarc->report->store() or diag Dumper( $dmarc->report ); #unlink $test_db_file; done_testing(); exit; sub setup_dmarc_result { $dmarc->init(); $dmarc->header_from($test_dom); $dmarc->source_ip('192.2.1.1'); $dmarc->dkim( [ { domain => $test_dom, result => 'pass', selector => 'apr2013' } ] ); $dmarc->spf( { domain => $test_dom, scope => 'mfrom', result => 'pass' } ); $dmarc->validate() or diag Dumper($dmarc) and return; delete $dmarc->result->{published}; is_deeply( $dmarc->result, { 'result' => 'pass', 'disposition' => 'none', 'dkim_meta' => { 'domain' => 'tnpi.net', 'identity' => '', 'selector' => 'apr2013', }, 'dkim' => 'pass', 'spf' => 'pass', 'dkim_align' => 'strict', 'spf_align' => 'strict', }, "result, pass, strict, $test_dom" ) or diag Dumper( $dmarc->result ); } sub test_compress { # has to be moderately large to overcome zip format overhead my $xml = '' x 200; my $compressed = $report->compress( \$xml ); ok( length $xml > length $compressed, 'compress_report' ); my $decompressed; IO::Uncompress::Gunzip::gunzip( \$compressed => \$decompressed ) or die "unzip failed: $GunzipError\n"; cmp_ok( $decompressed, 'eq', $xml, "compress_report, extracts" ); } Mail-DMARC-1.20260306/t/11.Report.Store.t000444000765000024 545315152630466 16446 0ustar00mattstaff000000000000use strict; use warnings; use Data::Dumper; use Net::DNS::Resolver::Mock; use Test::More; use Test::File::ShareDir -share => { -dist => { 'Mail-DMARC' => 'share' } }; use lib 'lib'; eval "use DBD::SQLite 1.31"; if ($@) { plan( skip_all => 'DBD::SQLite not available' ); exit; } my $resolver = new Net::DNS::Resolver::Mock(); $resolver->zonefile_parse(join("\n", 'tnpi.net. 600 A 66.128.51.170', 'tnpi.net. 600 MX 10 mail.theartfarm.com.', '_dmarc.mail-dmarc.tnpi.net. 600 TXT "v=DMARC1; p=reject; rua=mailto:invalid@theartfarm.com; ruf=mailto:invalid@theartfarm.com; pct=90"', '_dmarc.tnpi.net. 600 TXT "v=DMARC1; p=reject; rua=mailto:dmarc-feedback@theartfarm.com; ruf=mailto:dmarc-feedback@theartfarm.com; pct=100"', 'mail-dmarc.tnpi.net. 600 TXT "test zone for Mail::DMARC perl module"', 'mail-dmarc.tnpi.net._report._dmarc.theartfarm.com. 600 TXT "v=DMARC1; rua=mailto:invalid-test@theartfarm.com;"', '')); use_ok('Mail::DMARC::PurePerl'); my $dmarc = Mail::DMARC::PurePerl->new(); $dmarc->set_resolver($resolver); isa_ok( $dmarc, 'Mail::DMARC::PurePerl' ); isa_ok( $dmarc->report, 'Mail::DMARC::Report' ); isa_ok( $dmarc->report->store, 'Mail::DMARC::Report::Store' ); ok( $dmarc->report->store->backend, "selected backend loaded" ); my $test_dom = 'tnpi.net'; # gotta have something to store. Populate a DMARC object setup_dmarc_result() or die "failed setup\n"; # tell storage backend to use test settings $dmarc->report->store->backend->config('t/mail-dmarc.ini'); test_reason(); done_testing(); exit; sub test_reason { ok( $dmarc->result->reason( type => 'other', comment => 'testing' ), "reason"); } sub setup_dmarc_result { $dmarc->init(); ok( $dmarc->header_from($test_dom), "header_from" ); ok( $dmarc->envelope_to('recipient.com'), 'envelope_to' ); ok( $dmarc->source_ip('192.2.1.1'), 'source_ip' ); $dmarc->dkim([ { domain => $test_dom, result => 'pass', selector => 'apr2013' } ]); $dmarc->spf({ domain => $test_dom, scope => 'mfrom', result => 'pass' } ); $dmarc->validate() or diag Dumper($dmarc) and return; my $pub = delete $dmarc->result->{published}; ok( $pub, "pub" ); is_deeply( $dmarc->result, { 'result' => 'pass', 'disposition' => 'none', 'dkim_meta' => { 'domain' => 'tnpi.net', 'identity' => '', 'selector' => 'apr2013', }, 'dkim' => 'pass', 'spf' => 'pass', 'dkim_align' => 'strict', 'spf_align' => 'strict', 'reason' => [], }, "result, pass, strict, $test_dom" ) or diag Dumper( $dmarc->result ); return $dmarc->result->published($pub); } Mail-DMARC-1.20260306/t/12.Report.Store.SQL.t000444000765000024 5006415152630466 17123 0ustar00mattstaff000000000000use strict; use warnings; use Data::Dumper; use Test::More; use Test::Output; $Data::Dumper::Sortkeys = 1; use lib 'lib'; require Mail::DMARC::Report; require Mail::DMARC::Policy; my ($report_id, $rr_id, $policy, $reasons); my $begin = time - 10000; my $end = time - 100; my $test_domain = 'example.com'; my $dkim = [ { domain => 'from.com', selector => 'blah1', result => 'pass', human_result => 'yay' }, { domain => 'example.com', selector => 'blah2', result => 'pass', human_result => undef, }, { domain => 'example.com', selector => 'blah3', result => 'pass', }, ]; my $spf = [ { 'domain' => 'from.com', 'result' => 'pass', 'scope' => 'helo' }, { 'domain' => 'from.com', 'result' => 'pass', 'scope' => 'mfrom' }, { 'domain' => 'example.com', 'result' => 'fail', 'scope' => 'mfrom' } ]; my $mod = 'Mail::DMARC::Report::Store::SQL'; use_ok($mod); my $sql = $mod->new; isa_ok( $sql, $mod ); my $backend_dir = './t/backends'; opendir( my $dir, $backend_dir ) || die "Unable to view backends in $backend_dir"; # The general gist of the tests is: # test query mechanisms # build and store an aggregate report, as it would happen In Real Life # retrieve an aggregate report, as if reporting it # validate the consistency of what was stored and retrieved # We need to run the tests for every back-end type. # This includes all Grammars for SQL, but it also could mean other backends # that aren't currently supported. while ( my $file = readdir( $dir ) ) { my ($provider) = $file =~ /mail-dmarc\.sql\.(\w+)\.ini/i; if ( ! $provider ) { next; } eval "use DBD::$provider"; if ($@) { ok( 1, "Skipping $provider, DBD::$provider not available" ); next; } $sql->config( "$backend_dir/$file" ); if ( $provider eq 'Pg' ) { $provider = 'PostgreSQL'; } if ( $provider eq 'mysql' ) { $provider = 'MySQL'; } test_db_connect( $provider ) or do { ok(1, "Skipping $provider, unable to connect"); next; }; test_grammar_loaded( $provider ); test_insert_error( $provider ); test_query_replace(); test_query_update(); test_query_delete(); test_query(); test_query_any(); test_get_report_id(); # creates a test report # we need to run get_report_id before ip_store_and_fetch #  so that ip_store_and_fetch has a report to work with. test_ip_store_and_fetch(); test_insert_policy_published(); test_get_report_policy_published(); test_insert_rr(); test_insert_rr_spf(); test_insert_rr_dkim(); test_insert_rr_reason(); test_retrieve(); test_retrieve_todo(); test_get_author_id(3); test_get_report(); test_get_row_reason(); test_get_row_spf(); test_get_row_dkim(); test_populate_agg_metadata(); test_populate_agg_records(); test_cleanup( $provider ); } closedir( $dir ); done_testing(); exit; sub test_insert_error { my ($provider) = @_; my $msg = "STDERR has expected warning ($provider)"; if ($provider eq 'PostgreSQL') { stderr_is { test_query_insert() } 'DBI error: ERROR: relation "reporting" does not exist LINE 1: INSERT INTO "reporting" ("domain", "begin", "end") VALUES ($... ^ DBI error: ERROR: column "domin" of relation "report" does not exist LINE 1: INSERT INTO "report" ("domin", "begin", "end") VALUES ($1, $... ^ ', $msg; } elsif ($provider eq 'SQLite') { stderr_is { test_query_insert() } 'DBI error: no such table: reporting DBI error: table report has no column named domin ', $msg; } elsif ($provider eq 'MySQL') { stderr_is { test_query_insert() } 'DBI error: Table \'dmarc_report.reporting\' doesn\'t exist DBI error: Unknown column \'domin\' in \'field list\' ', $msg; } } sub test_cleanup { my ($provider) = @_; if ( $provider eq 'PostgreSQL' ) { ok ( $sql->query( 'TRUNCATE author, domain, report, report_error, report_policy_published, report_record, report_record_dkim, report_record_reason, report_record_spf RESTART IDENTITY;' ), 'truncate_testing_pg_database' ); return; } my $reports = $sql->get_report()->{data}; foreach my $report (@$reports) { # print Dumper($report); $sql->delete_report($report->{rid}); } $reports = $sql->get_report()->{data}; if (scalar @$reports) { # print Dumper($reports); die "failed to delete reports!\n"; } if ($provider eq 'SQLite') { unlink "t/reports-test.sqlite"; } } sub test_populate_agg_records { my $agg = Mail::DMARC::Report::Aggregate->new(); my $r = $sql->populate_agg_records( \$agg, $report_id ); ok( $r, "populate_agg_records"); # human result is returned undef from SQL, but absent during insertion # delete $r->[0]{auth_results}{dkim}[2]{human_result}; my $expected = Mail::DMARC::Report::Aggregate::Record->new( auth_results => { 'dkim' => $dkim, 'spf' => $spf, }, identifiers => { header_from => 'from.com', envelope_to => 'to.com', envelope_from => 'from.com', }, row => { 'count' => 1, 'policy_evaluated' => { disposition => 'none', dkim => 'pass', spf => 'pass', reason => $reasons, }, 'source_ip' => '192.1.1.1' }, ); $expected->auth_results->dkim->[2]{human_result} = undef; is_deeply( $r, [$expected], "populate_agg_records, deeply") or diag Dumper($r, [$expected]); } sub test_populate_agg_metadata { my $query = $sql->grammar->select_from( [ 'id AS rid', 'begin', 'end' ], 'report' ); $query .= $sql->grammar->and_arg( 'id' ); my $report = $sql->query( $query, [ $report_id ] )->[0]; my $agg = Mail::DMARC::Report::Aggregate->new(); ok( $sql->populate_agg_metadata( \$agg, \$report ), "populate_agg_metadata"); is_deeply( $agg->metadata, { 'config_file' => 'mail-dmarc.ini', 'date_range' => { 'begin' => $report->{begin}, 'end' => $report->{end}, }, 'email' => 'noreply@example.com', 'extra_contact_info' => 'http://www.example.com/dmarc-policy/', 'org_name' => 'My Great Company', 'report_id' => 2, }, "populate_agg_metadata, deeply" ) or diag Dumper($agg); } sub test_get_report_policy_published { my $pp = $sql->get_report_policy_published( $report_id ); $pp->apply_defaults; $pp->domain('recip.example.com'); foreach ( qw/ sp pct / ) { delete $pp->{$_} if ! defined $pp->$_; }; delete $pp->{report_id}; delete $policy->{uri}; delete $pp->{id}; ok( $pp, "get_report_policy_published"); is_deeply( $pp, $policy, "get_report_policy_published, deeply" ) or diag Dumper( $pp, $policy ); } sub test_retrieve { my $r = $sql->retrieve; ok( scalar @$r, "retrieve, " . scalar @$r ); my %tests = ( rid => 2, author => 'Test Company', from_domain => 'recip.example.com', begin => $begin, end => $end, ); foreach ( keys %tests ) { my $r = $sql->retrieve( $_ => $tests{$_} ); ok( @$r, "retrieve, $_, " . scalar @$r ); }; # Test negation with '!' prefix my $r_neg_author = $sql->retrieve( author => '!NonExistentAuthor' ); ok( scalar @$r_neg_author >= scalar @$r, "retrieve, negate author excludes nothing when non-matching" ); my $r_neg_domain = $sql->retrieve( from_domain => '!nonexistent.example.com' ); ok( scalar @$r_neg_domain >= scalar @$r, "retrieve, negate from_domain excludes nothing when non-matching" ); my $r_excl_author = $sql->retrieve( author => '!Test Company' ); ok( scalar @$r_excl_author < scalar @$r || scalar @$r_excl_author == 0, "retrieve, negate author excludes matching records" ); my $r_sorted = $sql->retrieve( sort_by => 'author', sort_order => 'ASC', limit => 1 ); ok( ref($r_sorted) eq 'ARRAY' && scalar @$r_sorted <= 1, 'retrieve supports sort and limit' ); my $r_fallback = $sql->retrieve( sort_by => 'bogus', sort_order => 'invalid', limit => 1 ); ok( ref($r_fallback) eq 'ARRAY', 'retrieve falls back to default sort options for invalid values' ); eval { $sql->retrieve( limit => 0 ) }; like( $@, qr/limit must be a positive integer/i, 'retrieve croaks when limit is zero' ); eval { $sql->retrieve( limit => 'abc' ) }; like( $@, qr/limit must be a positive integer/i, 'retrieve croaks when limit is non-numeric' ); } sub test_retrieve_todo { my $r = $sql->retrieve_todo(); ok( $r, "retrieve_todo"); for ( 1 .. scalar @$r ) { ok( $sql->next_todo(), 'next_todo returns cached report' ); } ok( !defined $sql->next_todo(), 'next_todo returns undef when cached list is exhausted' ); ok( !exists $sql->{_todo_list}, 'next_todo clears exhausted cache' ); # warn Dumper($r); # die $r->as_xml; } sub test_get_row_reason { ok( $sql->get_row_reason( $rr_id ), 'get_row_reason'); } sub test_get_row_spf { ok( $sql->get_row_spf( $rr_id ), 'get_row_spf'); } sub test_get_row_dkim { ok( $sql->get_row_dkim( $rr_id ), 'get_row_dkim'); } sub test_get_report { my $reports = $sql->get_report( rid => $report_id )->{data}; ok( scalar @$reports, "get_report, no limits, " . scalar @$reports ); my $limit = 10; my $r = $sql->get_report( length => $limit )->{data}; if ( ! $r || ! scalar @$r || scalar @$r < $limit ) { ok( 1, "skipping author tests" ); return; }; cmp_ok( scalar @$reports, '==', $limit, "get_report, limit $limit" ); my @queries = ( author => 'The Art Farm', author => 'google.com', from_domain => 'theartfarm.com', recipient => 'google.com', recipient => 'yahoo.com', ); while ( my $key = shift @queries ) { my $val = shift @queries; $r = $sql->get_report( $key => $val ); $reports = $r->{data}; ok( scalar @$reports, "get_report, $key, $val, " . scalar @$reports ); }; $reports = $sql->get_report( length => 1, sort_dir => 'desc', sort_col => 'r.id' ); ok( $reports->{data}, "get_report, multisearch"); } sub test_get_author_id { my $times = shift or return; my %meta = ( org_name => "Test $times Company", email => 'dmarc-reporter@example.com', extra_contact_info => undef, report_id => undef, begin => time, end => time + 10, ); my $report = Mail::DMARC::Report->new(); foreach ( keys %meta ) { next if ! defined $_; next if ! defined $meta{$_}; ok( $report->aggregate->metadata->$_( $meta{$_} ), "meta, $_, set" ); } my $policy = Mail::DMARC::Policy->new("v=DMARC1; p=reject"); ok( $policy->rua( 'mailto:' . $sql->config->{organization}{email} ), "policy, rua, set"); ok( $policy->domain( 'recip.example.com'), "policy, domain, set"); ok( $report->aggregate->policy_published( $policy ), "policy published, set"); # find a matching report, or create a new one my $rid = $sql->get_report_id( $report->aggregate ); ok( $rid, "get_report_id, $rid" ); my $authors = $sql->get_author_id( $report->aggregate->metadata ); test_get_author_id($times - 1); } sub test_get_report_id { my %meta = ( org_name => 'Test Company', email => 'dmarc-reporter@example.com', begin => $begin, end => $end, ); my $report = Mail::DMARC::Report->new(); foreach ( keys %meta ) { ok( $report->aggregate->metadata->$_( $meta{$_} ), "meta, $_, set" ); } $policy = Mail::DMARC::Policy->new("v=DMARC1; p=reject"); $policy->apply_defaults; ok( $policy->rua( 'mailto:' . $sql->config->{organization}{email} ), "policy, rua, set"); ok( $policy->domain( 'recip.example.com'), "policy, domain, set"); ok( $report->aggregate->policy_published( $policy ), "policy published, set"); # find a matching report, or create a new one $report_id = $sql->get_report_id( $report->aggregate ); ok( $report_id, "get_report_id, $report_id" ); } sub test_insert_rr_reason { ok ( $rr_id, "at_test_insert_rr_reason with $rr_id"); my @reasons = qw/ forwarded local_policy mailing_list other sampled_out trusted_forwarder /; $reasons = undef; foreach my $r ( @reasons) { push @$reasons, bless { type => $r, comment => "test $r comment" }, 'Mail::DMARC'; my $rrid = $sql->insert_rr_reason( $rr_id, $r, "test $r comment" ); ok($rrid , "insert_rr_reason, $r" ) or diag Dumper($rrid); } } sub test_insert_rr_dkim { ok ( $rr_id, "at_test_insert_rr_dkim with $rr_id"); ok( $sql->insert_rr_dkim( $rr_id, $dkim->[0] ), 'insert_rr_dkim' ); ok( $sql->insert_rr_dkim( $rr_id, $dkim->[1] ), 'insert_rr_dkim' ); ok( $sql->insert_rr_dkim( $rr_id, $dkim->[2] ), 'insert_rr_dkim' ); } sub test_insert_rr_spf { ok ( $rr_id, "at_test_insert_rr_spf with $rr_id"); foreach ( @$spf ) { ok( $sql->insert_rr_spf( $rr_id, $_ ), 'insert_rr_spf' ); }; } sub test_insert_rr { my $record = Mail::DMARC::Report::Aggregate::Record->new; $record->identifiers( header_from => 'from.com', envelope_to => 'to.com', envelope_from => 'from.com', ); $record->row( source_ip => '192.1.1.1', policy_evaluated => { disposition => 'none', dkim => 'pass', spf => 'pass', } ); $rr_id = $sql->insert_rr( $report_id, $record ); ok( $rr_id, "insert_rr, $rr_id" ); } sub test_insert_policy_published { my $pol = Mail::DMARC::Policy->new('v=DMARC1; p=reject'); $pol->apply_defaults; $pol->rua( 'mailto:' . $sql->config->{organization}{email} ); # warn Dumper($policy); my $r = $sql->insert_policy_published( $report_id, $pol ); ok( $r, 'insert_policy_published' ); } sub test_ip_store_and_fetch { my @test_ips = ( '1.1.1.1', '10.0.1.1', '2002:4c79:6240::1610:9fff:fee5:fb5', '2607:f060:b008:feed::6', ); foreach my $ip (@test_ips) { my $ipbin = $ip; if ( $sql->grammar->language ne 'postgresql' ) { $ipbin = $sql->any_inet_pton($ip); ok( $ipbin, "any_inet_pton, $ip" ); my $pres = $sql->any_inet_ntop($ipbin); ok( $pres, "any_inet_ntop, $ip" ); compare_any_inet_round_trip( $ip, $pres ); } my $r_id = $sql->query( $sql->grammar->insert_into( 'report_record', [ 'report_id', 'source_ip', 'disposition', 'dkim', 'spf', 'header_from_did' ] ), [ $report_id, $ipbin, 'none', 'pass', 'pass', 1 ] ) or die "failed to insert?"; my $rr_ref = $sql->query( $sql->grammar->select_from( [ 'id', 'source_ip' ], 'report_record' ) . $sql->grammar->and_arg('id'), [ $r_id ] ); ok( scalar @$rr_ref, 'records_retrieved' ); if ( $sql->grammar->language eq 'postgresql' ) { compare_any_inet_round_trip( $ip, $rr_ref->[0]{source_ip} ); } else { compare_any_inet_round_trip( $ip, $sql->any_inet_ntop( $rr_ref->[0]{source_ip} ), ); } $sql->query( $sql->grammar->delete_from( 'report_record' ).$sql->grammar->and_arg( 'id' ), [ $r_id ] ); } } sub test_query { ok( $sql->query( $sql->grammar->select_from( [ 'id' ], 'report' ) ), "query" ); } sub test_query_insert { my $end = time + 86400; my $from_did = $sql->query( $sql->grammar->insert_domain, [ 'ignore.test.com' ] ); my $author_id = $sql->query( $sql->grammar->insert_into( 'author', [ 'org_name' ] ), [ 'test' ] ); my $rid = $sql->query( $sql->grammar->insert_into( 'report', [ 'from_domain_id', 'begin', 'end', 'author_id' ] ), [ $from_did, $begin, $end, $author_id ] ); ok( $rid, "query_insert, report, $rid" ); ok( $sql->delete_report($rid), "delete_report, report, $rid"); # negative tests eval { $rid = $sql->query( $sql->grammar->insert_into( 'reporting', [ 'domain', 'begin', 'end' ] ), [ $test_domain, $begin, $end ] ); }; chomp $@; ok( $@, "query_insert, report, neg: $@" ); eval { $rid = $sql->query( $sql->grammar->insert_into( 'report', [ 'domin', 'begin', 'end' ] ), [ 'a' x 257, 'yellow', $end ] ); }; chomp $@; ok( $@, "query_insert, report, neg: $@" ); } sub test_query_replace { my $end = time + 86400; my $snafus = $sql->query( $sql->grammar->select_from( [ 'id' ], 'report' ).$sql->grammar->and_arg('begin'), [ $begin ] ); foreach my $s (@$snafus) { ok( $sql->query( $sql->grammar->replace_into( 'report', [ 'id', 'domain', 'begin', 'end' ] ), [ $s->{id}, $test_domain, $begin, $end ] ), "query_replace" ); } # negative eval { $sql->query( $sql->grammar->replace_into( 'rep0rt', [ 'id', 'domain', 'begin', 'end' ] ), [ 1, 1, 1, 1 ] ); }; chomp $@; ok( $@, "replace, negative, $@" ); } sub test_query_update { my $victims = $sql->query($sql->grammar->select_from( [ 'id' ], 'report' ).$sql->grammar->limit); foreach my $v (@$victims) { my $r = $sql->query( $sql->grammar->update( 'report', [ 'end' ] ).$sql->grammar->and_arg( 'id' ), [ time, $v->{id} ] ); ok( $r, "query_update, $r" ); # negative test eval { $sql->query( $sql->grammar->update( 'report', [ 'ed' ] ).$sql->grammar->and_arg( 'id' ), [ time, $v->{id} ] ); }; ok( $@, "query_update, neg" ); } } sub test_query_delete { my $victims = $sql->query($sql->grammar->select_from( [ 'id' ], 'report' ).$sql->grammar->limit(1)); foreach my $v (@$victims) { # print "test_query_delete victim: $v->{id}\n"; eval { my $r = $sql->delete_report($v->{id}); ok( $r, "query_delete $v->{id}" ); }; warn $@ if ($@); } # neg eval { $sql->query( $sql->grammar->delete_from( 'repor' ).$sql->grammar->and_arg( 'id' ), [ 1 ] ); }; chomp $@; ok( $@, "delete, negative, $@" ); } sub test_query_any { foreach my $table (qw/ report author domain report_record /) { my $r = $sql->query("SELECT id FROM $table LIMIT 1"); ok( $r, "query, select, $table" ); } # negative eval { $sql->query("SELECT id FROM rep0rt LIMIT 1") }; chomp $@; ok( $@, "query, select, negative, $@" ); } sub test_db_connect { my ($grammar) = @_; my $dbh; eval { $dbh = $sql->db_connect(); }; if ($@) { warn $@; return 0; } ok( $dbh, "db_connect: $grammar" ); isa_ok( $dbh, "DBIx::Simple" ); return 1; } sub test_grammar_loaded { my ($grammarName) = @_; isa_ok( $sql->grammar(), "Mail::DMARC::Report::Store::SQL::Grammars::$grammarName" ); } sub compare_any_inet_round_trip { my ( $ip, $pres ) = @_; if ( $pres eq $ip ) { cmp_ok( $pres, 'eq', $ip, "any_inet_ntop, round_trip, $ip" ); } else { # on some systems, a :: pattern gets a zero inserted. Mimic that my $zero_filled = $ip; $zero_filled =~ s/::/:0:/g; cmp_ok( $pres, 'eq', $zero_filled, "any_inet_ntop, round_trip, zero-pad, $ip" ) or diag "presentation: $zero_filled\nresult: $pres"; } } Mail-DMARC-1.20260306/t/13.Report.Aggregate.t000444000765000024 425015152630466 17234 0ustar00mattstaff000000000000use strict; use warnings; use Data::Dumper; use Test::More; use lib 'lib'; use Mail::DMARC::Policy; use Mail::DMARC::Report::Aggregate::Record; eval "use DBD::SQLite 1.31"; if ($@) { plan( skip_all => 'DBD::SQLite not available' ); exit; } my $mod = 'Mail::DMARC::Report::Aggregate'; use_ok($mod); my $agg = $mod->new; isa_ok( $agg, $mod ); my $ip = '192.2.1.1'; my $test_r = Mail::DMARC::Report::Aggregate::Record->new( identifiers => { header_from => 'example.com', envelope_from => 'example.com', }, auth_results => { dkim => [ ], spf => [ ] }, row => { source_ip => $ip, count => 1, policy_evaluated => { disposition=>'none', dkim => 'pass', spf=>'pass' }, }, ); test_metadata_isa(); test_record(); test_policy_published(); test_as_xml(); done_testing(); exit; sub test_metadata_isa { isa_ok( $agg->metadata, "Mail::DMARC::Report::Aggregate::Metadata"); }; sub test_policy_published { ok( ! defined $agg->policy_published, "policy_published, empty" ); my $pol = Mail::DMARC::Policy->new(); $pol->apply_defaults; $pol->domain('test.com'); ok( $agg->policy_published($pol), "policy_published, default" ); } sub test_record { is_deeply( $agg->record, [],"Mail::DMARC::Report::Aggregate::Record, empty"); my $r; eval { $r = $agg->record( $test_r ) }; ok( $r, "record, test") or diag Dumper($r); #delete $agg->record->[0]{config_file}; is_deeply( $agg->record, [ $test_r ], "record, deeply"); ok( $agg->record( $test_r ), "record, empty, again"); #delete $agg->record->[1]{config_file}; is_deeply( $agg->record, [ $test_r,$test_r ], "record, deeply, multiple"); }; sub test_as_xml { $agg->metadata->report_id(1); foreach my $m ( qw/ org_name email extra_contact_info error uuid / ) { $agg->metadata->$m("test"); }; foreach my $m ( qw/ begin end / ) { $agg->metadata->$m(time); }; #$agg->record( $test_r ); ok( $agg->metadata->as_xml(), "metadata, as_xml"); ok( $agg->get_policy_published_as_xml(), "policy_published, as_xml"); ok( $agg->get_record_as_xml(), "record, as_xml"); ok( $agg->as_xml(), "as_xml"); }; Mail-DMARC-1.20260306/t/14.Report.Aggregate.Metadata.t000444000765000024 556315152630466 20764 0ustar00mattstaff000000000000use strict; use warnings; use Data::Dumper; use Test::More; use lib 'lib'; eval "use DBD::SQLite 1.31"; if ($@) { plan( skip_all => 'DBD::SQLite not available' ); exit; } my $mod = 'Mail::DMARC::Report::Aggregate'; use_ok($mod); my $agg = $mod->new; isa_ok( $agg, $mod ); my $meta = $agg->metadata; isa_ok( $meta, 'Mail::DMARC::Report::Aggregate::Metadata' ); my $start = time; my $end = time + 10; test_org_name(); test_email(); test_extra_contact_info(); test_report_id(); test_date_range(); test_begin(); test_end(); test_error(); test_uuid(); test_as_xml(); done_testing(); exit; sub test_org_name { my $name = 'Test Org'; ok( $meta->org_name($name), "org_name, set"); cmp_ok( $meta->org_name, 'eq', $name, "org_name, get"); }; sub test_email { my $email = 'test@example.com'; ok( $meta->email( $email ), "test_email, set"); cmp_ok( $meta->email, 'eq', $email, "test_email, get"); }; sub test_extra_contact_info { my $eci = 'http://www.example.com/path/to/dmarc.cgi'; ok( $meta->extra_contact_info( $eci ), 'extra_contact_info, set'); cmp_ok( $meta->extra_contact_info, 'eq', $eci, "extra_contact_info, get"); }; sub test_report_id { my $id = '12345566677888@sender.com'; ok( $meta->report_id($id), "report_id, set"); cmp_ok( $meta->report_id, 'eq', $id, "report_id, get"); }; sub test_date_range { my $range_ref = {begin=>$start,end=>$end}; ok( $meta->date_range($range_ref), "date_range, set"); is_deeply( $meta->date_range, $range_ref, "date_range, get"); cmp_ok( $meta->begin, '==', $start, "date_range, get start"); cmp_ok( $meta->end, '==', $end, "date_range, get end"); }; sub test_begin { ok( $meta->begin( $start ), "begin, set"); cmp_ok( $meta->begin, '==', $start, "date_range, get start"); }; sub test_end { ok( $meta->end( $end ), "end, set"); cmp_ok( $meta->end, '==', $end, "date_range, get end"); }; sub test_error { my $test_errors = [ 'error #1 for test', 'error #2 for testing', ]; foreach ( @$test_errors ) { ok( $meta->error( $_ ), "error, $_"); }; is_deeply($meta->error, $test_errors, "error, deeply"); }; sub test_uuid { my $uuid = '1234908748913u41u4-1203847308924-adskfjadslfj-13i41230984'; ok( $meta->uuid($uuid), "uuid, set"); cmp_ok( $meta->uuid, 'eq', $uuid, "uuid, get"); }; sub test_as_xml { my $expected = <<"EO_XML" \t \t\tTest Org \t\ttest\@example.com \t\thttp://www.example.com/path/to/dmarc.cgi \t\t12345566677888\@sender.com \t\t \t\t\t$start \t\t\t$end \t\t \t\terror #1 for test \t\terror #2 for testing \t EO_XML ; chomp $expected; cmp_ok( $meta->as_xml, 'eq', $expected, "as_xml"); }; Mail-DMARC-1.20260306/t/15.Report.Aggregate.Record.t000444000765000024 570515152630466 20461 0ustar00mattstaff000000000000use strict; use warnings; use Data::Dumper; use Test::More; use lib 'lib'; my $mod = 'Mail::DMARC::Report::Aggregate::Record'; use_ok($mod); my $rec = $mod->new; isa_ok( $rec, $mod ); my $ip = '192.2.1.1'; test_identifiers(); test_auth_results(); test_row(); done_testing(); exit; sub test_identifiers { my $id = $rec->identifiers; ok( $id->envelope_to( 'to.example.com' ), "envelope_to, set"); ok( $id->envelope_to eq 'to.example.com', "envelope_to, get"); ok( $id->header_from( 'from.example.com' ), "header_from, set"); ok( $id->header_from eq 'from.example.com', "header_from, get"); ok( $id->envelope_from( 'from.example.com' ), "envelope_from, set"); ok( $id->envelope_from eq 'from.example.com', "envelope_from, get"); # one shot $id = $rec->identifiers( envelope_to => 'to.example.com', header_from => 'from.example.com', envelope_from=> 'from.example.com', ); ok( $id->envelope_to eq 'to.example.com', "envelope_to, get"); ok( $id->header_from eq 'from.example.com', "header_from, get"); ok( $id->envelope_from eq 'from.example.com', "envelope_from, get"); }; sub test_auth_results { my $ar = $rec->auth_results; my $expected = bless { dkim => [], spf => [] }, 'Mail::DMARC::Report::Aggregate::Record::Auth_Results'; is_deeply( $ar, $expected, "auth_results, empty"); my $spf1 = { domain => 'first', result => 'none', scope => 'helo' }; $expected = { dkim => [], spf => [ $spf1 ]}; $ar->spf( { domain => 'first', result => 'none', scope => 'helo' } ); is_deeply( $ar, $expected, "auth_results, one SPF"); my $spf2 = { domain => 'second', scope => 'helo', result => 'temperror' }; $expected = { dkim => [], spf => [ $spf1, $spf2 ] }; $ar->spf( { domain => 'second', result => 'temperror', scope => 'helo' } ); is_deeply( $ar, $expected, "auth_results, two SPF"); my $dkim1 = { domain => 'first', result => 'none' }; $expected = { dkim => [ $dkim1 ], spf => [ $spf1, $spf2 ] }; $ar->dkim( $dkim1 ); is_deeply( $ar, $expected, "auth_results, two SPF, one DKIM"); my $dkim2 = { domain => 'second', result => 'none' }; $expected = { dkim => [ $dkim1, $dkim2 ], spf => [ $spf1, $spf2 ] }; $ar->dkim( $dkim2 ); is_deeply( $ar, $expected, "auth_results, two SPF, two DKIM"); }; sub test_row { my $ar = $rec->row; my $expected = bless {}, 'Mail::DMARC::Report::Aggregate::Record::Row'; is_deeply( $ar, $expected, "row, empty"); $ar->source_ip( $ip ); $expected = { source_ip => $ip }; is_deeply( $ar, $expected, "row, source_ip"); $ar->count( 1 ); $expected = { count => 1, source_ip => $ip }; is_deeply( $ar, $expected, "row, count"); my $pe = { disposition => 'none', spf => 'fail', dkim => 'fail' }; $ar->policy_evaluated( $pe ); $pe->{reason} = []; $expected = { policy_evaluated => $pe, count => 1, source_ip => $ip }; is_deeply( $ar, $expected, "row, policy_evaluated"); }; Mail-DMARC-1.20260306/t/16.Report.Aggregate.Record.Auth_Results.t000444000765000024 301115152630466 23067 0ustar00mattstaff000000000000use strict; use warnings; use Data::Dumper; use Test::More; use lib 'lib'; my $mod = 'Mail::DMARC::Report::Aggregate::Record::Auth_Results'; use_ok($mod); my $ar = $mod->new; _auth_results(); _spf(); _dkim(); done_testing(); exit; sub _auth_results { isa_ok( $ar, $mod ); }; sub _spf { is_deeply( $ar->spf, [], "spf, empty"); my %spf_res = ( domain => 'test.com', result => 'pass', scope => 'mfrom', ); $ar->spf( %spf_res ); is_deeply( $ar->spf, [ \%spf_res ], "spf, hash"); $ar->spf( %spf_res ); is_deeply( $ar->spf, [ \%spf_res, \%spf_res ], "spf, hashref"); $ar = $mod->new; $ar->spf([ \%spf_res, \%spf_res ]); is_deeply( $ar->spf, [ \%spf_res, \%spf_res ], "spf, arrayref of hashref"); #warn Dumper($ar->spf); } sub _dkim { is_deeply( $ar->dkim, [], "dkim"); my %dkim_res = ( domain => 'tnpi.net', selector => 'jan2015', result => 'fail', human_result=> 'fail (body has been altered)', ); $ar->dkim( %dkim_res ); is_deeply( $ar->dkim, [ \%dkim_res ], "dkim, as hash"); $ar->dkim( \%dkim_res ); is_deeply( $ar->dkim, [ \%dkim_res, \%dkim_res ], "dkim, as hashref"); $ar->dkim( \%dkim_res ); is_deeply( $ar->dkim, [ \%dkim_res, \%dkim_res, \%dkim_res ], "dkim, as hashref again"); $ar = $mod->new; $ar->dkim([ \%dkim_res, \%dkim_res ]); is_deeply( $ar->dkim, [ \%dkim_res, \%dkim_res ], "dkim, as arrayref of hashrefs"); #warn Dumper($ar->dkim); } Mail-DMARC-1.20260306/t/17.Report.Aggregate.Schema.t000444000765000024 604115152630466 20437 0ustar00mattstaff000000000000use strict; use warnings; use Data::Dumper; use Net::DNS::Resolver::Mock; use Test::Exception; use Test::More; use Test::File::ShareDir -share => { -dist => { 'Mail-DMARC' => 'share' } }; use lib 'lib'; use Mail::DMARC::PurePerl; use Mail::DMARC::Report; eval "use DBD::SQLite 1.31"; if ($@) { plan( skip_all => 'DBD::SQLite not available' ); exit; } eval "use XML::SAX::ParserFactory;"; if ($@) { plan( skip_all => 'XML::SAX::ParserFactory not available' ); exit; } eval "use XML::Validator::Schema;"; if ($@) { plan( skip_all => 'XML::Validator::Schema not available' ); exit; } my $resolver = new Net::DNS::Resolver::Mock(); $resolver->zonefile_parse(join("\n", 'tnpi.net. 600 A 66.128.51.170', 'tnpi.net. 600 MX 10 mail.theartfarm.com.', '_dmarc.mail-dmarc.tnpi.net. 600 TXT "v=DMARC1; p=reject; rua=mailto:invalid@theartfarm.com; ruf=mailto:invalid@theartfarm.com; pct=90"', '_dmarc.tnpi.net. 600 TXT "v=DMARC1; p=reject; rua=mailto:dmarc-feedback@theartfarm.com; ruf=mailto:dmarc-feedback@theartfarm.com; pct=100"', 'mail-dmarc.tnpi.net. 600 TXT "test zone for Mail::DMARC perl module"', 'mail-dmarc.tnpi.net._report._dmarc.theartfarm.com. 600 TXT "v=DMARC1; rua=mailto:invalid-test@theartfarm.com;"', '')); my $dmarc = Mail::DMARC::PurePerl->new(); $dmarc->set_resolver($resolver); my $store = $dmarc->report->store; $store->config('t/mail-dmarc.ini'); $store->backend->config('t/mail-dmarc.ini'); die 'Not using test store' if $store->backend->config->{'report_store'}->{'dsn'} ne 'dbi:SQLite:dbname=t/reports-test.sqlite'; $dmarc->source_ip('66.128.51.165'); $dmarc->envelope_to('recipient.example.com'); $dmarc->envelope_from('dmarc-nonexist.tnpi.net'); $dmarc->header_from('mail-dmarc.tnpi.net'); $dmarc->dkim([ { domain => 'tnpi.net', selector => 'jan2015', result => 'fail', human_result=> 'fail (body has been altered)', } ]); $dmarc->spf([ { domain => 'tnpi.net', scope => 'mfrom', result => 'pass', }, { scope => 'helo', domain => 'mail.tnpi.net', result => 'fail', }, ]); my $policy = $dmarc->discover_policy; my $result = $dmarc->validate($policy); my $report_id = $dmarc->save_aggregate(); ok( $report_id, "saved report $report_id"); my $a = $store->backend->query('UPDATE report SET begin=begin-86400, end=end-86400 WHERE id=1'); $a = $store->backend->query('INSERT INTO report_error(report_id,error,time) VALUES(1," Test error & encoding",100)'); my $agg = $store->retrieve_todo()->[0]; test_against_schema(); done_testing(); exit; sub test_against_schema { $agg->metadata->report_id(1); my $xml = $agg->as_xml(); lives_ok( sub{ my $validator = XML::Validator::Schema->new(file => 'share/rua-schema.xsd'); my $parser = XML::SAX::ParserFactory->parser(Handler => $validator); $parser->parse_string( $xml ); }, 'Check schema' ); # print $xml; } Mail-DMARC-1.20260306/t/20.Report.URI.t000444000765000024 277515152630466 16015 0ustar00mattstaff000000000000use strict; use warnings; use Data::Dumper; use Test::More; use lib 'lib'; my $mod = 'Mail::DMARC::Report::URI'; use_ok($mod); my $uri = $mod->new; isa_ok( $uri, $mod ); test_get_size_limit(); test_parse(); done_testing(); exit; sub test_get_size_limit { my %tests = ( '51m' => 53477376, '20k' => 20480, '5m' => 5242880, '10m' => 10485760, '1g' => 1073741824, '500' => 500, ); foreach my $t ( keys %tests ) { cmp_ok( $uri->get_size_limit($t), '==', $tests{$t}, "get_size_limit, $tests{$t}" ); } is( $uri->get_size_limit(undef), 0, 'get_size_limit undef means no limit' ); eval { $uri->get_size_limit('7x') }; like( $@, qr/unrecognized unit/i, 'get_size_limit croaks on invalid unit' ); } sub test_parse { my @good = ( 'http://www.example.com/dmarc-feedback', 'https://www.example.com/dmarc-feedback', 'mailto:dmarc@example.com', 'mailto:dmarc-feedback@example.com,mailto:tld-test@thirdparty.example.net!10m', ); foreach (@good) { my $uris = $uri->parse($_); ok( $uris, "parse, $_" ); ok( scalar @$uris, "parse, count " . scalar @$uris ); } my $mixed = $uri->parse( 'mailto:good@example.com,ftp://invalid.example,https://ok.example/path!20k' ); is( scalar @$mixed, 2, 'parse filters unsupported schemes (ftp)' ); eval { $uri->parse() }; like( $@, qr/URI string is required/i, 'parse croaks without URI string' ); } Mail-DMARC-1.20260306/t/21.Report.Send.t000444000765000024 213515152630466 16236 0ustar00mattstaff000000000000use strict; use warnings; use Data::Dumper; use Test::More; use Test::File::ShareDir -share => { -dist => { 'Mail-DMARC' => 'share' } }; use lib 'lib'; my $mod = 'Mail::DMARC::Report::Send'; use_ok($mod); my $send = $mod->new; isa_ok( $send, $mod ); isa_ok( $send->smtp, 'Mail::DMARC::Report::Send::SMTP' ); isa_ok( $send->http, 'Mail::DMARC::Report::Send::HTTP' ); my $body = $send->too_big_report( { uri => 'mailto:matt@example.com', report_bytes => 500000, report_id => 1, report_domain=> 'destination.com', } ); ok( $body, 'too_big_report'); #cmp_ok( $body, 'eq', sample_too_big(), 'too_big_report: content'); done_testing(); exit; sub sample_too_big { return <<'EO_TOO_BIG' This is a \'too big\' DMARC notice. The aggregate report was NOT delivered. Report-Date: Wed, 14 Aug 2013 22:15:04 -0700 Report-Domain: destination.com Report-ID: 1 Report-Size: 500000 Submitter: example.com Submitting-URI: mailto:matt@example.com Submitted by My Great Company Generated with Mail::DMARC EO_TOO_BIG ; }; Mail-DMARC-1.20260306/t/22.Report.Send.SMTP.t000444000765000024 703615152630466 17026 0ustar00mattstaff000000000000use strict; use warnings; use Data::Dumper; use Net::DNS::Resolver::Mock; use Test::More; use IO::Compress::Gzip; use lib 'lib'; use Mail::DMARC::Policy; use Mail::DMARC::Report::Aggregate; use Mail::DMARC::Report::Aggregate::Record; my $resolver = new Net::DNS::Resolver::Mock(); $resolver->zonefile_parse(join("\n", 'tnpi.net. 600 MX 10 mail.theartfarm.com.', '')); my $mod = 'Mail::DMARC::Report::Send::SMTP'; use_ok($mod); my $smtp = $mod->new; $smtp->set_resolver($resolver); isa_ok( $smtp, $mod ); $smtp->config('t/mail-dmarc.ini'); open my $REP, '<', 'share/rua-schema.xsd' or die "unable to open: $!"; my $report = join( '', <$REP> ); close $REP; my $zipped; IO::Compress::Gzip::gzip( \$report, \$zipped ) or die "unable to compress"; my $agg = Mail::DMARC::Report::Aggregate->new; my $pol = Mail::DMARC::Policy->new; $pol->domain('they.com'); $agg->policy_published( $pol ); $agg->metadata->begin( time - 10000 ); $agg->metadata->end( time - 100 ); $agg->metadata->report_id( '2013.06.01.6789' ); test_get_subject(); test_get_domain_mx(); test_get_smtp_hosts(); test_human_summary(); test_get_filename(); test_get_timestamp_rfc2822(); test_get_helo_hostname(); test_assemble_message(); done_testing(); exit; sub test_get_subject { my $subject = $smtp->get_subject( \$agg ); ok( $subject, "get_subject, $subject" ); }; sub test_get_helo_hostname { my $helo = $smtp->get_helo_hostname(); ok( $helo, "get_helo_hostname, $helo" ); }; sub test_get_timestamp_rfc2822 { my $r = $smtp->get_timestamp_rfc2822(); ok( $r, "get_timestamp_rfc2822, $r"); }; sub test_get_domain_mx { my %tests = ( 'tnpi.net' => [ { 'pref' => 10, 'addr' => 'mail.theartfarm.com' } ], ); foreach my $dom ( keys %tests ) { my $r = $smtp->get_domain_mx( $dom ); if (!$r || $r eq 'Does not exist') { print "it appears your DNS is not working.\n"; next; } ok( $r, "get_domain_mx, $dom"); is_deeply( $r, $tests{$dom}, "get_domain_mx, $dom, deeply"); # print Dumper($r); }; }; sub test_human_summary { my $record = Mail::DMARC::Report::Aggregate::Record->new( auth_results => { spf => [] }, identifiers => { header_from => 'they.com', }, row => { source_ip => '192.2.0.1', policy_evaluated => { disposition=>'none', dkim => 'pass', spf => 'fail' } } ); $agg->record( $record ); $record->row->policy_evaluated->dkim('fail'); $record->row->policy_evaluated->spf('pass'); $agg->record( $record ); $record->row->policy_evaluated->dkim('fail'); $record->row->policy_evaluated->spf('fail'); $agg->record( $record ); my $sum = $smtp->human_summary( \$agg ); ok( $sum, 'human_summary' ); # print $sum; } sub test_get_filename { my $name = $smtp->get_filename(\$agg); ok( $name, "get_filename, $name"); }; sub test_assemble_message { my $mess = $smtp->assemble_message_object( \$agg, 'matt@example.com', $zipped )->as_string; ok( $mess, "assemble_message_object" ); #warn print $mess; } sub test_get_smtp_hosts { my $initial_smarthost = $smtp->config->{smtp}{smarthost}; $smtp->config->{smtp}{smarthost} = undef; my $tnpi_expected = [ 'mail.theartfarm.com', 'tnpi.net' ]; my @hosts = $smtp->get_smtp_hosts('tnpi.net'); is_deeply( \@hosts, $tnpi_expected, "get_smtp_hosts, tnpi.net"); # print Dumper(\@hosts); $smtp->config->{smtp}{smarthost} = $initial_smarthost; } Mail-DMARC-1.20260306/t/23.Report.Send.HTTP.t000444000765000024 53515152630466 17000 0ustar00mattstaff000000000000use strict; use warnings; use Data::Dumper; use Test::More; use lib 'lib'; foreach my $req ( 'Net::HTTP' ) { eval "use $req"; if ($@) { plan( skip_all => "$req not available" ); exit; } }; my $mod = 'Mail::DMARC::Report::Send::HTTP'; use_ok($mod); my $http = $mod->new; isa_ok( $http, $mod ); done_testing(); exit; Mail-DMARC-1.20260306/t/25.Report.Receive.t000444000765000024 1174015152630466 16755 0ustar00mattstaff000000000000use strict; use warnings; use Data::Dumper; use Test::More; use IO::Compress::Gzip; use IO::Compress::Zip; use lib 'lib'; my $mod = 'Mail::DMARC::Report::Receive'; use_ok($mod); my $recv = $mod->new; isa_ok( $recv, $mod ); $recv->config('t/mail-dmarc.ini'); test_from_email_file(); test_from_file_xml(); test_from_file_gzip(); test_from_file_zip(); test_from_file_errors(); test_get_submitter_from_filename(); test_get_submitter_from_subject(); test_from_imap(); done_testing(); exit; sub test_from_imap { my $skip_reason = ''; eval "require Net::IMAP::Simple"; $skip_reason .= "Net::IMAP::Simple not installed" if $@; my $c = $recv->config->{imap}; if ( !$c->{server} || !$c->{user} || !$c->{pass} ) { $skip_reason .= " and \n" if $skip_reason; $skip_reason .= "imap not configured in mail-dmarc.ini"; } SKIP: { skip $skip_reason, 1 if $skip_reason; ok( $recv->from_imap(), "from_imap" ); } } sub test_get_submitter_from_subject { my %subjects = ( 'aol.com' => 'Subject: Report Domain:theartfarm.com Submitter:aol.com Report-ID:theartfarm.com_1366084800', 'ivenue.com' => 'Subject: Report Domain: tnpi.net Submitter: Ivenue.com Report-ID: tnpi.net-1366977854@Ivenue.com', 'hotmail.com' => 'Subject: =?utf-8?B?UmVwb3J0IERvbWFpbjogc2ltZXJzb24ubmV0IFN1Ym1pdHRlcjogaG90bWFpbC5jb20gUmVwb3J0LUlEOiA8YTY2YWVmZWIzZjI3NGNhYmJmZGM2MWMwMTVlNTg2N2VAaG90bWFpbC5jb20+?=', 'google.com' => 'Subject: Report domain: timbersmart.com Submitter: google.com Report-ID: 6022178961730607282', 'hotmail.com' => 'Subject: =?utf-8?B?UmVwb3J0IERvbWFpbjogbHluYm95ZXIuY29tIFN1Ym1pdHRlcjogaG90bWFpbC5jb20gUmVwb3J0LUlEOiA8MDJjNTM5YWY0ZjE2NGFlZGE3ZGQxZTdhYWJhOTc1MWJAaG90bWFpbC5jb20+?=', 'yahoo.com' => 'Subject: Report Domain: timbersmart.com Submitter: yahoo.com Report-ID: <1368868092.438744>', ); foreach my $dom ( keys %subjects ) { my $subject = $subjects{$dom}; cmp_ok( $recv->get_submitter_from_subject($subject), 'eq', $dom, "get_submitter_from_subject, $dom" ); } # Test UUID handling $recv->report->init(); my $meta = $recv->report->aggregate->metadata; $recv->get_submitter_from_subject( 'Subject: Report Domain: example.com Submitter: sender.example Report-ID: ' ); is( $meta->uuid, 'uuid-test', 'subject parser sets metadata uuid' ); } sub test_get_submitter_from_filename { $recv->{_envelope_to} = undef; $recv->{_header_from} = undef; my $result = $recv->get_submitter_from_filename('submit.example!report.example!1!2'); is( $result, 'submit.example', 'filename parser extracts envelope submitter' ); is( $recv->{_header_from}, 'report.example', 'filename parser sets header from domain' ); # Test early return when submitter already set $recv->{_envelope_to} = 'existing.submitter'; my $should_be_undef = $recv->get_submitter_from_filename('new.submitter!new.header!1!2'); ok( !defined($should_be_undef), 'filename parser returns early when submitter already set' ); is( $recv->{_envelope_to}, 'existing.submitter', 'existing submitter is preserved' ); } sub test_from_file_errors { eval { $recv->from_file() }; like( $@, qr/missing message/i, 'from_file croaks when file argument is missing' ); eval { $recv->from_file('t/fixtures/not-there.xml') }; like( $@, qr/no such file/i, 'from_file croaks for missing file path' ); } sub test_from_file_xml { my $file = 't/fixtures/test_dmarc.xml'; return if !-f $file; eval "require DBD::SQLite"; if ($@) { SKIP: { skip 'DBD::SQLite not available', 1 } return; } my $result = eval { $recv->from_file($file) }; if ($@) { diag "from_file XML failed: $@"; ok(0, "from_file with XML file"); } else { cmp_ok( $result, 'eq', 'aggregate', "from_file with XML file" ); } } sub test_from_file_gzip { my $file = 't/fixtures/test_dmarc.xml.gz'; return if !-f $file; eval "require DBD::SQLite"; if ($@) { SKIP: { skip 'DBD::SQLite not available', 1 } return; } my $result = eval { $recv->from_file($file) }; if ($@) { diag "from_file gzip failed: $@"; ok(0, "from_file with gzip file"); } else { cmp_ok( $result, 'eq', 'aggregate', "from_file with gzip file" ); } } sub test_from_file_zip { my $file = 't/fixtures/test_dmarc.xml.zip'; return if !-f $file; eval "require DBD::SQLite"; if ($@) { SKIP: { skip 'DBD::SQLite not available', 1 } return; } my $result = eval { $recv->from_file($file) }; if ($@) { diag "from_file zip failed: $@"; ok(0, "from_file with zip file"); } else { cmp_ok( $result, 'eq', 'aggregate', "from_file with zip file" ); } } sub test_from_email_file { if ( -f 'report.msg' ) { $recv->verbose(1); ok( $recv->from_file('report.msg'), 'from_file' ); } } Mail-DMARC-1.20260306/t/26.Report.Sender.t000555000765000024 1110115152630466 16606 0ustar00mattstaff000000000000use strict; use warnings; use Test::More; use Net::DNS::Resolver::Mock; $ENV{MAIL_DMARC_CONFIG_FILE} = 't/mail-dmarc.ini'; use lib 'lib'; use Mail::DMARC::PurePerl; use Test::File::ShareDir -share => { -dist => { 'Mail-DMARC' => 'share' } }; use Mail::DMARC::Test::Transport; use Email::Sender::Transport::Failable; use Email::Sender::Transport::Test; my $resolver = new Net::DNS::Resolver::Mock(); $resolver->zonefile_parse(join("\n", 'fastmaildmarc.com. 600 MX 10 in1-smtp.messagingengine.com.', '_dmarc.fastmaildmarc.com. 600 TXT "v=DMARC1; p=reject; rua=mailto:rua@fastmaildmarc.com"', '')); # We test both method and object type callbacks foreach my $callback_type ( qw{ method object fail fallback } ) { subtest $callback_type => sub{ unlink 't/reports-test.sqlite' if -e 't/reports-test.sqlite'; # Clear test database for each run my $dmarc = Mail::DMARC::PurePerl->new; $dmarc->set_resolver($resolver); $dmarc->set_fake_time( time-86400); $dmarc->init(); $dmarc->source_ip('66.128.51.165'); $dmarc->envelope_to('fastmaildmarc.com'); $dmarc->envelope_from('fastmaildmarc.com'); $dmarc->header_from('fastmaildmarc.com'); $dmarc->dkim([ { domain => 'tnpi.net', selector => 'jan2015', result => 'fail', human_result=> 'fail (body has been altered)', } ]); $dmarc->spf([ { domain => 'tnpi.net', scope => 'mfrom', result => 'pass', }, { scope => 'helo', domain => 'mail.tnpi.net', result => 'fail', }, ]); my $policy = $dmarc->discover_policy; my $result = $dmarc->validate($policy); $dmarc->save_aggregate; $dmarc->set_fake_time( time+86400); use Mail::DMARC::Report::Sender; my $sender = Mail::DMARC::Report::Sender->new; my @deliveries; if ( $callback_type eq 'method' ) { my $transport = Email::Sender::Transport::Test->new; $sender->set_transports_method( sub{ my @transports; push @transports, $transport; return @transports; }); $sender->run; @deliveries = $transport->deliveries; } elsif ( $callback_type eq 'object' ) { my $transports = Mail::DMARC::Test::Transport->new; $sender->set_transports_object( $transports ); $sender->run; @deliveries = $transports->get_test_transport->deliveries; } elsif ( $callback_type eq 'fail' ) { my $transport = Email::Sender::Transport::Test->new; my $transport_fail = Email::Sender::Transport::Failable->new( transport => $transport, failure_conditions => [ sub{ return 1 } ], ); $sender->set_transports_method( sub{ my @transports; push @transports, $transport_fail; return @transports; }); $sender->run; @deliveries = $transport_fail->transport->deliveries; } elsif ( $callback_type eq 'fallback' ) { my $transport = Email::Sender::Transport::Test->new; my $transport_fail = Email::Sender::Transport::Failable->new( transport => $transport, failure_conditions => [ sub{ return 1 } ], ); $sender->set_transports_method( sub{ my @transports; push @transports, $transport_fail; push @transports, $transport; return @transports; }); $sender->run; @deliveries = $transport->deliveries; } else { die 'Unknown callback type in test'; } if ( $callback_type eq 'fail' ) { is( scalar @deliveries, 0, 'Email send fails' ); } else { is( scalar @deliveries, 1, '1 Email sent' ); is( $deliveries[0]->{envelope}->{to}->[0], 'rua@fastmaildmarc.com', 'Sent to correct address' ); my $body = ${$deliveries[0]->{email}->[0]->{body}}; is( $body =~ /This is a DMARC aggregate report for fastmaildmarc.com/, 1, 'Human readable description' ); is( $body =~ /1 records.\n0 passed.\n1 failed./, 1, 'Human readable summary'); is( $body =~ /Content-Type: application\/gzip/, 1, 'Gzip attachment' ); } }; } done_testing; Mail-DMARC-1.20260306/t/mail-dmarc.ini000444000765000024 274215152630466 16200 0ustar00mattstaff000000000000; This is YOU. DMARC reports include information about the reports. Enter it here. [organization] domain = example-test.com org_name = My Great Company email = noreply@example.com extra_contact_info = http://www.example.com/dmarc-policy/ ; aggregate DMARC reports need to be stored somewhere. Any database ; with a DBI module (MySQL, SQLite, DBD, etc.) should work. ; SQLite and MySQL and Postgresql are supported. ; Default is sqlite. [report_store] backend = SQL dsn = dbi:SQLite:dbname=t/reports-test.sqlite ;dsn = dbi:mysql:database=dmarc_report;host=db;port=3306 ;dsn = dbi:Pg:database=dmarc_report;host=db;port=5432 user = pass = ; backend can be perl or libopendmarc [dmarc] backend = perl [dns] timeout = 5 public_suffix_list = share/public_suffix_list [smtp] ; hostname is the external FQDN of this MTA hostname = mail.example.com cc = set.this@for.a.while.example.com whitelist = t/whitelist transports = Mail::DMARC::Test::Transport ; By default, we attempt to email directly to the report recipient. ; Set these to relay via a SMTP smart host. smarthost = smartuser = smartpass = [imap] server = mail.example.com user = pass = ; the imap folder where new dmarc messages will be found folder = dmarc ; the folders to store processed reports (a=aggregate, f=forensic) f_done = dmarc.forensic a_done = dmarc.aggregate [http] port = 8080 [https] port = 8443 ssl_crt = ssl_key = Mail-DMARC-1.20260306/t/whitelist000444000765000024 45015152630466 15402 0ustar00mattstaff000000000000# Format: IP *whitespace* type *whitespace* comment # Reason types: forwarded sampled_out trusted_forwarder mailing_list local_policy other # any IP without a type specified will default to 'other' # Comment is a free form entry 127.0.0.3 trusted_forwarder Test Comment 127.0.0.1 local_policy Mail-DMARC-1.20260306/t/backends000755000765000024 015152630466 15101 5ustar00mattstaff000000000000Mail-DMARC-1.20260306/t/backends/mail-dmarc.sql.Pg.ini000444000765000024 251415152630466 21112 0ustar00mattstaff000000000000; This is YOU. DMARC reports include information about the reports. Enter it here. [organization] domain = example-test.com org_name = My Great Company email = noreply@example.com extra_contact_info = http://www.example.com/dmarc-policy/ ; aggregate DMARC reports need to be stored somewhere. Any database ; with a DBI module (MySQL, SQLite, DBD, etc.) should work. ; SQLite and MySQL and Postgresql are supported. ; Default is sqlite. [report_store] backend = SQL dsn = dbi:Pg:database=dmarc_report;port=5432 user = postgres pass = ; backend can be perl or libopendmarc [dmarc] backend = perl [dns] timeout = 5 public_suffix_list = share/public_suffix_list [smtp] ; hostname is the external FQDN of this MTA hostname = mail.example.com cc = set.this@for.a.while.example.com whitelist = t/whitelist ; By default, we attempt to email directly to the report recipient. ; Set these to relay via a SMTP smart host. smarthost = smartuser = smartpass = [imap] server = mail.example.com user = pass = ; the imap folder where new dmarc messages will be found folder = dmarc ; the folders to store processed reports (a=aggregate, f=forensic) f_done = dmarc.forensic a_done = dmarc.aggregate [http] port = 8080 [https] port = 8443 ssl_crt = ssl_key = Mail-DMARC-1.20260306/t/backends/mail-dmarc.sql.SQLite.ini000444000765000024 255315152630466 21710 0ustar00mattstaff000000000000; This is YOU. DMARC reports include information about the reports. Enter it here. [organization] domain = example-test.com org_name = My Great Company email = noreply@example.com extra_contact_info = http://www.example.com/dmarc-policy/ ; aggregate DMARC reports need to be stored somewhere. Any database ; with a DBI module (MySQL, SQLite, DBD, etc.) should work. ; SQLite and MySQL and Postgresql are supported. ; Default is sqlite. [report_store] backend = SQL dsn = dbi:SQLite:dbname=t/reports-test.sqlite ; dsn = dbi:SQLite:dbname=:memory: user = pass = ; backend can be perl or libopendmarc [dmarc] backend = perl [dns] timeout = 5 public_suffix_list = share/public_suffix_list [smtp] ; hostname is the external FQDN of this MTA hostname = mail.example.com cc = set.this@for.a.while.example.com whitelist = t/whitelist ; By default, we attempt to email directly to the report recipient. ; Set these to relay via a SMTP smart host. smarthost = smartuser = smartpass = [imap] server = mail.example.com user = pass = ; the imap folder where new dmarc messages will be found folder = dmarc ; the folders to store processed reports (a=aggregate, f=forensic) f_done = dmarc.forensic a_done = dmarc.aggregate [http] port = 8080 [https] port = 8443 ssl_crt = ssl_key = Mail-DMARC-1.20260306/t/backends/mail-dmarc.sql.mysql.ini000444000765000024 251215152630466 21707 0ustar00mattstaff000000000000; This is YOU. DMARC reports include information about the reports. Enter it here. [organization] domain = example-test.com org_name = My Great Company email = noreply@example.com extra_contact_info = http://www.example.com/dmarc-policy/ ; aggregate DMARC reports need to be stored somewhere. Any database ; with a DBI module (MySQL, SQLite, DBD, etc.) should work. ; SQLite and MySQL and Postgresql are supported. ; Default is sqlite. [report_store] backend = SQL dsn = dbi:mysql:database=dmarc_report;port=3306 user = root pass = ; backend can be perl or libopendmarc [dmarc] backend = perl [dns] timeout = 5 public_suffix_list = share/public_suffix_list [smtp] ; hostname is the external FQDN of this MTA hostname = mail.example.com cc = set.this@for.a.while.example.com whitelist = t/whitelist ; By default, we attempt to email directly to the report recipient. ; Set these to relay via a SMTP smart host. smarthost = smartuser = smartpass = [imap] server = mail.example.com user = pass = ; the imap folder where new dmarc messages will be found folder = dmarc ; the folders to store processed reports (a=aggregate, f=forensic) f_done = dmarc.forensic a_done = dmarc.aggregate [http] port = 8080 [https] port = 8443 ssl_crt = ssl_key = Mail-DMARC-1.20260306/xt000755000765000024 015152630466 13517 5ustar00mattstaff000000000000Mail-DMARC-1.20260306/xt/author-critic.t000444000765000024 67415152630466 16605 0ustar00mattstaff000000000000#!perl BEGIN { unless ($ENV{AUTHOR_TESTING}) { require Test::More; Test::More::plan(skip_all => 'these tests are for testing by the author'); } } use strict; use warnings; use Test::More; use English qw(-no_match_vars); eval "use Test::Perl::Critic"; plan skip_all => 'Test::Perl::Critic required to criticise code' if $@; Test::Perl::Critic->import( -profile => "xt/perlcritic.rc" ) if -e "xt/perlcritic.rc"; all_critic_ok(); Mail-DMARC-1.20260306/xt/perlcritic.rc000444000765000024 77715152630466 16335 0ustar00mattstaff000000000000severity = stern ; gentle stern harsh cruel brutal verbose = [%p] %m at line %l, column %c. %e. (Severity: %s)\n [-Documentation::RequirePodSections] [-TestingAndDebugging::RequireUseStrict] [-TestingAndDebugging::RequireUseWarnings] ; in general, I agree, but I disagree in mail::critic::result::evaluated [-Modules::ProhibitMultiplePackages] [Subroutines::RequireArgUnpacking] short_subroutine_statements = 5 [RegularExpressions::RequireExtendedFormatting] minimum_regex_length_to_complain_about = 8