pax_global_header00006660000000000000000000000064121763730560014524gustar00rootroot0000000000000052 comment=42f20630c3e67f083929492babf456a1d4bac770 pacemaker-master/000077500000000000000000000000001217637305600143115ustar00rootroot00000000000000pacemaker-master/.gitattributes000066400000000000000000000000321217637305600171770ustar00rootroot00000000000000configure.ac export-subst pacemaker-master/.gitignore000066400000000000000000000040671217637305600163100ustar00rootroot00000000000000# Common \#* .\#* GPATH GRTAGS GTAGS TAGS Makefile Makefile.in .deps .libs *.pc *.pyc *.bz2 *.rpm *.la *.lo *.o *~ *.gcda *.gcno # Autobuild aclocal.m4 autoconf autoheader autom4te.cache/ automake build.counter compile config.guess config.log config.status config.sub configure depcomp install-sh include/stamp-* libltdl.tar libtool libtool.m4 ltdl.m4 ltmain.sh missing py-compile m4/ltoptions.m4 m4/ltsugar.m4 m4/ltversion.m4 m4/lt~obsolete.m4 # Configure targets cts/CTSvars.py cts/LSBDummy cts/benchmark/clubench include/config.h include/config.h.in include/crm_config.h mcp/pacemaker mcp/pacemaker.service pengine/regression.core.sh publican.cfg shell/modules/help.py shell/modules/ra.py shell/modules/ui.py shell/modules/vars.py tools/coverage.sh tools/crm_report lrmd/regression.py fencing/regression.py # Build targets *.7 *.7.xml *.7.html *.8 *.8.xml *.8.html doc/*/en-US/images/*.png doc/*/tmp/** doc/*/publish cib/cib cib/cibmon cib/cibpipe crmd/atest crmd/crmd doc/Clusters_from_Scratch.txt doc/Pacemaker_Explained.txt doc/acls.html doc/crm_fencing.html fencing/stonith-test fencing/stonith_admin fencing/stonithd fencing/stonithd.xml lrmd/lrmd lrmd/lrmd_test mcp/pacemakerd pengine/pengine pengine/pengine.xml pengine/ptest shell/regression/testcases/confbasic-xml.filter scratch tools/attrd tools/attrd_updater tools/cibadmin tools/crm_attribute tools/crm_diff tools/crm_mon tools/crm_node tools/crm_resource tools/crm_shadow tools/crm_simulate tools/crm_uuid tools/crm_verify tools/crmadmin tools/iso8601 tools/crm_ticket tools/report.collector.1 xml/crm.dtd xml/pacemaker.rng extra/rgmanager/ccs2cib extra/rgmanager/ccs_flatten extra/rgmanager/disable_rgmanager doc/Clusters_from_Scratch/en-US/Ap-*.xml doc/Clusters_from_Scratch/en-US/Ch-*.xml doc/Pacemaker_Explained/en-US/Ch-*.xml doc/Pacemaker_Explained/en-US/Ap-*.xml lib/gnu/libgnu.a lib/gnu/stdalign.h *.coverity #Other mock HTML pacemaker.spec pengine/.regression.failed.diff ClusterLabs-pacemaker-*.tar.gz coverity-* compat_reports .ABI-build abi_dumps logs *.patch *.diff *.sed *.orig *.rej *.swp pengine/test10/shadow.* pacemaker-master/.travis.yml000066400000000000000000000016441217637305600164270ustar00rootroot00000000000000# Control file for the Travis autobuilder # http://about.travis-ci.org/docs/user/build-configuration/ language: c compiler: - gcc before_install: - lsb_release - sudo cat /etc/apt/sources.list - sudo bash -c 'echo "deb http://archive.ubuntu.com/ubuntu/ quantal universe" >> /etc/apt/sources.list' - sudo apt-get update -qq - sudo apt-get install -qq automake autoconf chrpath libsnmp-dev libglib2.0-dev perl net-tools python libtool libxml2-dev bison flex uuid-dev libbz2-dev zlib1g-dev libltdl3-dev libgnutls-dev python-central python-dev libpam0g-dev libncurses5-dev libcorosync-dev heartbeat-dev libheartbeat2-dev cluster-glue-dev libxslt1-dev libesmtp-dev libqb-dev/quantal before_script: - ./autogen.sh - ./configure script: make after_script: - ./BasicSanity.sh -V notifications: irc: "irc.freenode.org#pcmk" email: recipients: - andrew@beekhof.net # whitelist branches: only: - master pacemaker-master/AUTHORS000066400000000000000000000021161217637305600153610ustar00rootroot00000000000000NOTE: The work of everyone on this project is greatly appreciated. If you are not listed here but should be, please let us know! The following people have kindly helped with pacemaker development by providing code, documentation or testing, or fixes: Andrew Beekhof Main architect, Lead Developer David Vossel Lrmd, Stonith Maintainer, PE bug fixes and features Keisuke MORI Maintainer of the 1.0 branch Yan Gao Bug fixes, features and documentation Dan Frîncu Romanian document translations Raoul Scarazzini Italian document translations Charlie Chen Chinese document translations Contributors, ordered by last name: Lars Marowsky-Brée Project catalyst and advocate Dominik Klein Dejan Muhamedagic Alan Robertson Tanja Roth Thomas Schraitle pacemaker-master/BasicSanity.sh000077500000000000000000000037721217637305600170720ustar00rootroot00000000000000#!/bin/bash test_home=`dirname $0` valgrind="" verbose="" tests="" if [ "$test_home" = "." ]; then test_home="$PWD" fi function info() { printf "$*\n" } function error() { printf " * ERROR: $*\n" } info "Test home is:\t$test_home" while true ; do case "$1" in all) tests="pengine cli lrmd fencing"; shift;; pengine|lrmd|pacemaker_remote|fencing|cli) tests="$tests $1"; shift;; -V|--verbose) verbose="-V"; shift;; -v|--valgrind) valgrind="-v"; shift;; --) shift ; break ;; "") break;; *) echo "unknown option: $1"; exit 1;; esac done if [ -z "$tests" ]; then tests="pengine cli lrmd" fi failed="" for t in $tests; do info "Executing the $t regression tests" info "============================================================" if [ -e $test_home/$t/regression.py ]; then # Fencing, lrmd need root access chmod a+x $test_home/$t/regression.py echo "Enter the root password..." su root -c "$test_home/$t/regression.py $verbose" rc=$? elif [ $t == "pacemaker_remote" ] && [ -e $test_home/lrmd/regression.py ]; then # pacemaker_remote chmod a+x $test_home/lrmd/regression.py echo "Enter the root password..." su root -c "$test_home/lrmd/regression.py -R $verbose" rc=$? elif [ -e $test_home/$t ]; then # pengine, cli $test_home/$t/regression.sh $verbose $valgrind rc=$? elif [ $t = cli -a -e $test_home/tools ]; then # Running cli tests from the source tree $test_home/tools/regression.sh $verbose $valgrind rc=$? else error "Cannot find $t test in $test_home" rc=1 fi if [ $rc != 0 ]; then info "$t regression tests failed: $rc" failed="$failed $t" fi info "============================================================" info "" info "" done if [ -z "$failed" ]; then exit 0 fi error "regression tests for $failed failed" exit 1 pacemaker-master/COPYING000066400000000000000000000431761217637305600153570ustar00rootroot00000000000000 GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc., 51 Franklin Street, 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 licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU 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. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Lesser General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), 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 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 show them these terms so they know 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. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. 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 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 derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 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 License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. 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. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary 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 License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 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 Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing 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 for copying, distributing or modifying the Program or works based on it. 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. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. 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 this 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 this License, you may choose any version ever published by the Free Software Foundation. 10. 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 11. 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. 12. 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 >>>>>>> c88668a0e87ce5827262820dd0e307220b4189b8 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 the public, 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) 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 2 of the License, 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) year 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 is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. pacemaker-master/COPYING.LIB000066400000000000000000000635021217637305600157570ustar00rootroot00000000000000 GNU LESSER GENERAL PUBLIC LICENSE Version 2.1, February 1999 Copyright (C) 1991, 1999 Free Software Foundation, Inc. 51 Franklin Street, 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. [This is the first released version of the Lesser GPL. It also counts as the successor of the GNU Library Public License, version 2, hence the version number 2.1.] Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public Licenses are intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This license, the Lesser General Public License, applies to some specially designated software packages--typically libraries--of the Free Software Foundation and other authors who decide to use it. You can use it too, but we suggest you first think carefully about whether this license or the ordinary General Public License is the better strategy to use in any particular case, based on the explanations below. When we speak of free software, we are referring to freedom of use, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish); that you receive source code or can get it if you want it; that you can change the software and use pieces of it in new free programs; and that you are informed that you can do these things. To protect your rights, we need to make restrictions that forbid distributors to deny you these rights or to ask you to surrender these rights. These restrictions translate to certain responsibilities for you if you distribute copies of the library or if you modify it. For example, if you distribute copies of the library, whether gratis or for a fee, you must give the recipients all the rights that we gave you. You must make sure that they, too, receive or can get the source code. If you link other code with the library, you must provide complete object files to the recipients, so that they can relink them with the library after making changes to the library and recompiling it. And you must show them these terms so they know their rights. We protect your rights with a two-step method: (1) we copyright the library, and (2) we offer you this license, which gives you legal permission to copy, distribute and/or modify the library. To protect each distributor, we want to make it very clear that there is no warranty for the free library. Also, if the library is modified by someone else and passed on, the recipients should know that what they have is not the original version, so that the original author's reputation will not be affected by problems that might be introduced by others. Finally, software patents pose a constant threat to the existence of any free program. We wish to make sure that a company cannot effectively restrict the users of a free program by obtaining a restrictive license from a patent holder. Therefore, we insist that any patent license obtained for a version of the library must be consistent with the full freedom of use specified in this license. Most GNU software, including some libraries, is covered by the ordinary GNU General Public License. This license, the GNU Lesser General Public License, applies to certain designated libraries, and is quite different from the ordinary General Public License. We use this license for certain libraries in order to permit linking those libraries into non-free programs. When a program is linked with a library, whether statically or using a shared library, the combination of the two is legally speaking a combined work, a derivative of the original library. The ordinary General Public License therefore permits such linking only if the entire combination fits its criteria of freedom. The Lesser General Public License permits more lax criteria for linking other code with the library. We call this license the "Lesser" General Public License because it does Less to protect the user's freedom than the ordinary General Public License. It also provides other free software developers Less of an advantage over competing non-free programs. These disadvantages are the reason we use the ordinary General Public License for many libraries. However, the Lesser license provides advantages in certain special circumstances. For example, on rare occasions, there may be a special need to encourage the widest possible use of a certain library, so that it becomes a de-facto standard. To achieve this, non-free programs must be allowed to use the library. A more frequent case is that a free library does the same job as widely used non-free libraries. In this case, there is little to gain by limiting the free library to free software only, so we use the Lesser General Public License. In other cases, permission to use a particular library in non-free programs enables a greater number of people to use a large body of free software. For example, permission to use the GNU C Library in non-free programs enables many more people to use the whole GNU operating system, as well as its variant, the GNU/Linux operating system. Although the Lesser General Public License is Less protective of the users' freedom, it does ensure that the user of a program that is linked with the Library has the freedom and the wherewithal to run that program using a modified version of the Library. The precise terms and conditions for copying, distribution and modification follow. Pay close attention to the difference between a "work based on the library" and a "work that uses the library". The former contains code derived from the library, whereas the latter must be combined with the library in order to run. GNU LESSER GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License Agreement applies to any software library or other program which contains a notice placed by the copyright holder or other authorized party saying it may be distributed under the terms of this Lesser General Public License (also called "this License"). Each licensee is addressed as "you". A "library" means a collection of software functions and/or data prepared so as to be conveniently linked with application programs (which use some of those functions and data) to form executables. The "Library", below, refers to any such software library or work which has been distributed under these terms. A "work based on the Library" means either the Library or any derivative work under copyright law: that is to say, a work containing the Library or a portion of it, either verbatim or with modifications and/or translated straightforwardly into another language. (Hereinafter, translation is included without limitation in the term "modification".) "Source code" for a work means the preferred form of the work for making modifications to it. For a library, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the library. Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running a program using the Library is not restricted, and output from such a program is covered only if its contents constitute a work based on the Library (independent of the use of the Library in a tool for writing it). Whether that is true depends on what the Library does and what the program that uses the Library does. 1. You may copy and distribute verbatim copies of the Library's complete 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 License and to the absence of any warranty; and distribute a copy of this License along with the Library. 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. 2. You may modify your copy or copies of the Library or any portion of it, thus forming a work based on the Library, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) The modified work must itself be a software library. b) You must cause the files modified to carry prominent notices stating that you changed the files and the date of any change. c) You must cause the whole of the work to be licensed at no charge to all third parties under the terms of this License. d) If a facility in the modified Library refers to a function or a table of data to be supplied by an application program that uses the facility, other than as an argument passed when the facility is invoked, then you must make a good faith effort to ensure that, in the event an application does not supply such function or table, the facility still operates, and performs whatever part of its purpose remains meaningful. (For example, a function in a library to compute square roots has a purpose that is entirely well-defined independent of the application. Therefore, Subsection 2d requires that any application-supplied function or table used by this function must be optional: if the application does not supply it, the square root function must still compute square roots.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Library, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Library, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Library. In addition, mere aggregation of another work not based on the Library with the Library (or with a work based on the Library) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may opt to apply the terms of the ordinary GNU General Public License instead of this License to a given copy of the Library. To do this, you must alter all the notices that refer to this License, so that they refer to the ordinary GNU General Public License, version 2, instead of to this License. (If a newer version than version 2 of the ordinary GNU General Public License has appeared, then you can specify that version instead if you wish.) Do not make any other change in these notices. Once this change is made in a given copy, it is irreversible for that copy, so the ordinary GNU General Public License applies to all subsequent copies and derivative works made from that copy. This option is useful when you wish to copy part of the code of the Library into a program that is not a library. 4. You may copy and distribute the Library (or a portion or derivative of it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange. If distribution of object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place satisfies the requirement to distribute the source code, even though third parties are not compelled to copy the source along with the object code. 5. A program that contains no derivative of any portion of the Library, but is designed to work with the Library by being compiled or linked with it, is called a "work that uses the Library". Such a work, in isolation, is not a derivative work of the Library, and therefore falls outside the scope of this License. However, linking a "work that uses the Library" with the Library creates an executable that is a derivative of the Library (because it contains portions of the Library), rather than a "work that uses the library". The executable is therefore covered by this License. Section 6 states terms for distribution of such executables. When a "work that uses the Library" uses material from a header file that is part of the Library, the object code for the work may be a derivative work of the Library even though the source code is not. Whether this is true is especially significant if the work can be linked without the Library, or if the work is itself a library. The threshold for this to be true is not precisely defined by law. If such an object file uses only numerical parameters, data structure layouts and accessors, and small macros and small inline functions (ten lines or less in length), then the use of the object file is unrestricted, regardless of whether it is legally a derivative work. (Executables containing this object code plus portions of the Library will still fall under Section 6.) Otherwise, if the work is a derivative of the Library, you may distribute the object code for the work under the terms of Section 6. Any executables containing that work also fall under Section 6, whether or not they are linked directly with the Library itself. 6. As an exception to the Sections above, you may also combine or link a "work that uses the Library" with the Library to produce a work containing portions of the Library, and distribute that work under terms of your choice, provided that the terms permit modification of the work for the customer's own use and reverse engineering for debugging such modifications. You must give prominent notice with each copy of the work that the Library is used in it and that the Library and its use are covered by this License. You must supply a copy of this License. If the work during execution displays copyright notices, you must include the copyright notice for the Library among them, as well as a reference directing the user to the copy of this License. Also, you must do one of these things: a) Accompany the work with the complete corresponding machine-readable source code for the Library including whatever changes were used in the work (which must be distributed under Sections 1 and 2 above); and, if the work is an executable linked with the Library, with the complete machine-readable "work that uses the Library", as object code and/or source code, so that the user can modify the Library and then relink to produce a modified executable containing the modified Library. (It is understood that the user who changes the contents of definitions files in the Library will not necessarily be able to recompile the application to use the modified definitions.) b) Use a suitable shared library mechanism for linking with the Library. A suitable mechanism is one that (1) uses at run time a copy of the library already present on the user's computer system, rather than copying library functions into the executable, and (2) will operate properly with a modified version of the library, if the user installs one, as long as the modified version is interface-compatible with the version that the work was made with. c) Accompany the work with a written offer, valid for at least three years, to give the same user the materials specified in Subsection 6a, above, for a charge no more than the cost of performing this distribution. d) If distribution of the work is made by offering access to copy from a designated place, offer equivalent access to copy the above specified materials from the same place. e) Verify that the user has already received a copy of these materials or that you have already sent this user a copy. For an executable, the required form of the "work that uses the Library" must include any data and utility programs needed for reproducing the executable from it. However, as a special exception, the materials to be distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. It may happen that this requirement contradicts the license restrictions of other proprietary libraries that do not normally accompany the operating system. Such a contradiction means you cannot use both them and the Library together in an executable that you distribute. 7. You may place library facilities that are a work based on the Library side-by-side in a single library together with other library facilities not covered by this License, and distribute such a combined library, provided that the separate distribution of the work based on the Library and of the other library facilities is otherwise permitted, and provided that you do these two things: a) Accompany the combined library with a copy of the same work based on the Library, uncombined with any other library facilities. This must be distributed under the terms of the Sections above. b) Give prominent notice with the combined library of the fact that part of it is a work based on the Library, and explaining where to find the accompanying uncombined form of the same work. 8. You may not copy, modify, sublicense, link with, or distribute the Library except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense, link with, or distribute the Library is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 9. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Library or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Library (or any work based on the Library), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Library or works based on it. 10. Each time you redistribute the Library (or any work based on the Library), the recipient automatically receives a license from the original licensor to copy, distribute, link with or modify the Library subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties with this License. 11. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Library at all. For example, if a patent license would not permit royalty-free redistribution of the Library by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Library. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply, and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 12. If the distribution and/or use of the Library is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Library under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 13. The Free Software Foundation may publish revised and/or new versions of the Lesser 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 Library specifies a version number of this 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 Library does not specify a license version number, you may choose any version ever published by the Free Software Foundation. 14. If you wish to incorporate parts of the Library into other free programs whose distribution conditions are incompatible with these, 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 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE LIBRARY "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 LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 16. 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 LIBRARY 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 LIBRARY (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 LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Libraries If you develop a new library, and you want it to be of the greatest possible use to the public, we recommend making it free software that everyone can redistribute and change. You can do so by permitting redistribution under these terms (or, alternatively, under the terms of the ordinary General Public License). To apply these terms, attach the following notices to the library. 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) This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; 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. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the library, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the library `Frob' (a library for tweaking knobs) written by James Random Hacker. , 1 April 1990 Ty Coon, President of Vice That's all there is to it! pacemaker-master/ChangeLog000066400000000000000000003554201217637305600160740ustar00rootroot00000000000000 * Fri Jul 26 2013 Andrew Beekhof Pacemaker-1.1.10-1 - Update source tarball to revision: ab2e209 - Changesets: 602 - Diff: 143 files changed, 8162 insertions(+), 5159 deletions(-) - Features added since Pacemaker-1.1.9 + Core: Convert all exit codes to positive errno values + crm_error: Add the ability to list and print error symbols + crm_resource: Allow individual resources to be reprobed + crm_resource: Allow options to be set recursively + crm_resource: Implement --ban for moving resources away from nodes and --clear (replaces --unmove) + crm_resource: Support OCF tracing when using --force-(check|start|stop) + PE: Allow active nodes in our current membership to be fenced without quorum + PE: Suppress meaningless IDs when displaying anonymous clone status + Turn off auto-respawning of systemd services when the cluster starts them + Bug cl#5128 - pengine: Support maintenance mode for a single node - Changes since Pacemaker-1.1.9 + crmd: cib: stonithd: Memory leaks resolved and improved use of glib reference counting + attrd: Fixes deleted attributes during dc election + Bug cf#5153 - Correctly display clone failcounts in crm_mon + Bug cl#5133 - pengine: Correctly observe on-fail=block for failed demote operation + Bug cl#5148 - legacy: Correctly remove a node that used to have a different nodeid + Bug cl#5151 - Ensure node names are consistently compared without case + Bug cl#5152 - crmd: Correctly clean up fenced nodes during membership changes + Bug cl#5154 - Do not expire failures when on-fail=block is present + Bug cl#5155 - pengine: Block the stop of resources if any depending resource is unmanaged + Bug cl#5157 - Allow migration in the absence of some colocation constraints + Bug cl#5161 - crmd: Prevent memory leak in operation cache + Bug cl#5164 - crmd: Fixes crash when using pacemaker-remote + Bug cl#5164 - pengine: Fixes segfault when calculating transition with remote-nodes. + Bug cl#5167 - crm_mon: Only print "stopped" node list for incomplete clone sets + Bug cl#5168 - Prevent clones from being bounced around the cluster due to location constraints + Bug cl#5170 - Correctly support on-fail=block for clones + cib: Correctly read back archived configurations if the primary is corrupted + cib: The result is not valid when diffs fail to apply cleanly for CLI tools + cib: Restore the ability to embed comments in the configuration + cluster: Detect and warn about node names with capitals + cman: Do not pretend we know the state of nodes we've never seen + cman: Do not unconditionally start cman if it is already running + cman: Support non-blocking CPG calls + Core: Ensure the blackbox is saved on abnormal program termination + corosync: Detect the loss of members for which we only know the nodeid + corosync: Do not pretend we know the state of nodes we've never seen + corosync: Ensure removed peers are erased from all caches + corosync: Nodes that can persist in sending CPG messages must be alive afterall + crmd: Do not get stuck in S_POLICY_ENGINE if a node we couldn't fence returns + crmd: Do not update fail-count and last-failure for old failures + crmd: Ensure all membership operations can complete while trying to cancel a transition + crmd: Ensure operations for cleaned up resources don't block recovery + crmd: Ensure we return to a stable state if there have been too many fencing failures + crmd: Initiate node shutdown if another node claims to have successfully fenced us + crmd: Prevent messages for remote crmd clients from being relayed to wrong daemons + crmd: Properly handle recurring monitor operations for remote-node agent + crmd: Store last-run and last-rc-change for all operations + crm_mon: Ensure stale pid files are updated when a new process is started + crm_report: Correctly collect logs when 'uname -n' reports fully qualified names + fencing: Fail the operation once all peers have been exhausted + fencing: Restore the ability to manually confirm that fencing completed + ipc: Allow unpriviliged clients to clean up after server failures + ipc: Restore the ability for members of the haclient group to connect to the cluster + legacy: Support "crm_node --remove" with a node name for corosync plugin (bnc#805278) + lrmd: Default to the upstream location for resource agent scratch directory + lrmd: Pass errors from lsb metadata generation back to the caller + pengine: Correctly handle resources that recover before we operate on them + pengine: Delete the old resource state on every node whenever the resource type is changed + pengine: Detect constraints with inappropriate actions (ie. promote for a clone) + pengine: Ensure per-node resource parameters are used during probes + pengine: If fencing is unavailable or disabled, block further recovery for resources that fail to stop + pengine: Implement the rest of get_timet_now() and rename to get_effective_time + pengine: Re-initiate _active_ recurring monitors that previously failed but have timed out + remote: Workaround for inconsistent tls handshake behavior between gnutls versions + systemd: Ensure we get shut down correctly by systemd + systemd: Reload systemd after adding/removing override files for cluster services + xml: Check for and replace non-printing characters with their octal equivalent while exporting xml text + xml: Prevent lockups by setting a more reliable buffer allocation strategy * Fri Mar 08 2013 Andrew Beekhof Pacemaker-1.1.9-1 - Update source tarball to revision: 7e42d77 - Statistics: Changesets: 731 Diff: 1301 files changed, 92909 insertions(+), 57455 deletions(-) - Features added in Pacemaker-1.1.9 + corosync: Allow cman and corosync 2.0 nodes to use a name other than uname() + corosync: Use queues to avoid blocking when sending CPG messages + ipc: Compress messages that exceed the configured IPC message limit + ipc: Use queues to prevent slow clients from blocking the server + ipc: Use shared memory by default + lrmd: Support nagios remote monitoring + lrmd: Pacemaker Remote Daemon for extending pacemaker functionality outside corosync cluster. + pengine: Check for master/slave resources that are not OCF agents + pengine: Support a 'requires' resource meta-attribute for controlling whether it needs quorum, fencing or nothing + pengine: Support for resource container + pengine: Support resources that require unfencing before start - Changes since Pacemaker-1.1.8 + attrd: Correctly handle deletion of non-existant attributes + Bug cl#5135 - Improved detection of the active cluster type + Bug rhbz#913093 - Use crm_node instead of uname + cib: Avoid use-after-free by correctly support cib_no_children for non-xpath queries + cib: Correctly process XML diff's involving element removal + cib: Performance improvements for non-DC nodes + cib: Prevent error message by correctly handling peer replies + cib: Prevent ordering changes when applying xml diffs + cib: Remove text nodes from cib replace operations + cluster: Detect node name collisions in corosync + cluster: Preserve corosync membership state when matching node name/id entries + cman: Force fenced to terminate on shutdown + cman: Ignore qdisk 'nodes' + core: Drop per-user core directories + corosync: Avoid errors when closing failed connections + corosync: Ensure peer state is preserved when matching names to nodeids + corosync: Clean up CMAP connections after querying node name + corosync: Correctly detect corosync 2.0 clusters even if we don't have permission to access it + crmd: Bug cl#5144 - Do not updated the expected status of failed nodes + crmd: Correctly determin if cluster disconnection was abnormal + crmd: Correctly relay messages for remote clients (bnc#805626, bnc#804704) + crmd: Correctly stall the FSA when waiting for additional inputs + crmd: Detect and recover when we are evicted from CPG + crmd: Differentiate between a node that is up and coming up in peer_update_callback() + crmd: Have cib operation timeouts scale with node count + crmd: Improved continue/wait logic in do_dc_join_finalize() + crmd: Prevent election storms caused by getrusage() values being too close + crmd: Prevent timeouts when performing pacemaker level membership negotiation + crmd: Prevent use-after-free of fsa_message_queue during exit + crmd: Store all current actions when stalling the FSA + crm_mon: Do not try to render a blank cib and indicate the previous output is now stale + crm_mon: Fixes crm_mon crash when using snmp traps. + crm_mon: Look for the correct error codes when applying configuration updates + crm_report: Ensure policy engine logs are found + crm_report: Fix node list detection + crm_resource: Have crm_resource generate a valid transition key when sending resource commands to the crmd + date/time: Bug cl#5118 - Correctly convert seconds-since-epoch to the current time + fencing: Attempt to provide more information that just 'generic error' for failed actions + fencing: Correctly record completed but previously unknown fencing operations + fencing: Correctly terminate when all device options have been exhausted + fencing: cov#739453 - String not null terminated + fencing: Do not merge new fencing requests with stale ones from dead nodes + fencing: Do not start fencing until entire device topology is found or query results timeout. + fencing: Do not wait for the query timeout if all replies have arrived + fencing: Fix passing of parameters from CMAN containing '=' + fencing: Fix non-comparison when sorting devices by priority + fencing: On failure, only try a topology device once from the remote level. + fencing: Only try peers for non-topology based operations once + fencing: Retry stonith device for duration of action's timeout period. + heartbeat: Remove incorrect assert during cluster connect + ipc: Bug cl#5110 - Prevent 100% CPU usage when looking for synchronous replies + ipc: Use 50k as the default compression threshold + legacy: Prevent assertion failure on routing ais messages (bnc#805626) + legacy: Re-enable logging from the pacemaker plugin + legacy: Relax the 'active' check for plugin based clusters to avoid false negatives + legacy: Skip peer process check if the process list is empty in crm_is_corosync_peer_active() + mcp: Only define HA_DEBUGLOG to avoid agent calls to ocf_log printing everything twice + mcp: Re-attach to existing pacemaker components when mcp fails + pengine: Any location constraint for the slave role applies to all roles + pengine: Avoid leaking memory when cleaning up failcounts and using containers + pengine: Bug cl#5101 - Ensure stop order is preserved for partially active groups + pengine: Bug cl#5140 - Allow set members to be stopped when the subseqent set has require-all=false + pengine: Bug cl#5143 - Prevent shuffling of anonymous master/slave instances + pengine: Bug rhbz#880249 - Ensure orphan masters are demoted before being stopped + pengine: Bug rhbz#880249 - Teach the PE how to recover masters into primitives + pengine: cl#5025 - Automatically clear failcount for start/monitor failures after resource parameters change + pengine: cl#5099 - Probe operation uses the timeout value from the minimum interval monitor by default (#bnc776386) + pengine: cl#5111 - When clone/master child rsc has on-fail=stop, insure all children stop on failure. + pengine: cl#5142 - Do not delete orphaned children of an anonymous clone + pengine: Correctly unpack active anonymous clones + pengine: Ensure previous migrations are closed out before attempting another one + pengine: Introducing the whitebox container resources feature + pengine: Prevent double-free for cloned primitive from template + pengine: Process rsc_ticket dependencies earlier for correctly allocating resources (bnc#802307) + pengine: Remove special cases for fencing resources + pengine: rhbz#902459 - Remove rsc node status for orphan resources + systemd: Gracefully handle unexpected DBus return types + Replace the use of the insecure mktemp(3) with mkstemp(3) * Thu Sep 20 2012 Andrew Beekhof Pacemaker-1.1.8-1 - Update source tarball to revision: 1a5341f - Statistics: Changesets: 1019 Diff: 2107 files changed, 117258 insertions(+), 73606 deletions(-) - All APIs have been cleaned up and reduced to essentials - Pacemaker now includes a replacement lrmd that supports systemd and upstart agents - Config and state files (cib.xml, PE inputs and core files) have moved to new locations - The crm shell has become a separate project and no longer included with Pacemaker - All daemons/tools now have a unified set of error codes based on errno.h (see crm_error) - Changes since Pacemaker-1.1.7 + Core: Bug cl#5032 - Rewrite the iso8601 date handling code + Core: Correctly extract the version details from a diff + Core: Log blackbox contents, if enabled, when an error occurs + Core: Only LOG_NOTICE and higher are sent to syslog + Core: Replace use of IPC from clplumbing with IPC from libqb + Core: SIGUSR1 now enables blackbox logging, SIGTRAP to write out + Core: Support a blackbox for additional logging detail after crashes/errors + Promote support for advanced fencing logic to the stable schema + Promote support for node starting scores to the stable schema + Promote support for service and systemd to the stable schema + attrd: Differentiate between updating all our attributes and everybody updating all theirs too + attrd: Have single-shot clients wait for an ack before disconnecting + cib: cl#5026 - Synced cib updates should not return until the cpg broadcast is complete. + corosync: Detect when the first corosync has not yet formed and handle it gracefully + corosync: Obtain a full list of configured nodes, including their names, when we connect to the quorum API + corosync: Obtain a node name from DNS if one was not already known + corosync: Populate the cib nodelist from corosync if available + corosync: Use the CFG API and DNS to determine node names if not configured in corosync.conf + crmd: Block after 10 failed fencing attempts for a node + crmd: cl#5051 - Fixes file leak in pe ipc connection initialization. + crmd: cl#5053 - Fixes fail-count not being updated properly. + crmd: cl#5057 - Restart sub-systems correctly (bnc#755671) + crmd: cl#5068 - Fixes crm_node -R option so it works with corosync 2.0 + crmd: Correctly re-establish failed attrd connections + crmd: Detect when the quorum API isn't configured for corosync 2.0 + crmd: Do not overwrite any configured node type (eg. quorum node) + crmd: Enable use of new lrmd daemon and client library in crmd. + crmd: Overhaul the way node state is recorded and updated in the CIB + fencing: Bug rhbz#853537 - Prevent use-of-NULL when the cib libraries are not available + fencing: cl#5073 - Add 'off' as an valid value for stonith-action option. + fencing: cl#5092 - Always timeout stonith operations if timeout period expires. + fencing: cl#5093 - Stonith per device timeout option + fencing: Clean up if we detect a failed connection + fencing: Delegate complex self fencing requests - we wont be around to see it to completion + fencing: Ensure all peers are notified of complex fencing op completion + fencing: Fix passing of fence_legacy parameters containing '=' + fencing: Gracefully handle metadata requests for unknown agents + fencing: Return cached dynamic target list for busy devices. + fencing: rhbz#801355 - Abort transition on DC when external fencing operation is detected + fencing: rhbz#801355 - Merge fence requests for identical operations already in progress. + fencing: rhbz#801355 - Report fencing operations external of pacemaker to cib + fencing: Specify the action to perform using action= instead of the older option= + fencing: Stop building fake metadata for broken agents + fencing: Tolerate agents that report empty metadata in the admin tool + mcp: Correctly retry the connection to corosync on failure + mcp: Do not shut down IPC until the last client exits + mcp: Prevent use-after-free when running against corosync 1.x + pengine: Bug cl#5059 - Use the correct action's status when calculating required actions for interleaved clones + pengine: Bypass online/offline checking resource detection for ping/quorum nodes + pengine: cl#5044 - migrate_to no longer requires load_stopped for avoiding possible transition loop + pengine: cl#5069 - Honor 'on-fail=ignore' even when operation is disabled. + pengine: cl#5070 - Allow influence of promotion score when multistate rsc is left hand of colocation + pengine: cl#5072 - Fixes monitor op stopping after rsc promotion. + pengine: cl#5072 - Fixes pengine regression test failures + pengine: Correctly set the status for nodes not intended to run Pacemaker + pengine: Do not append instance numbers to anonymous clones + pengine: Fix failcount expiration + pengine: Fix memory leaks found by valgrind + pengine: Fix use-after-free and use-of-NULL errors detected by coverity + pengine: Fixes use of colocation scores other than +/- INFINITY + pengine: Improve detection of rejoining nodes + pengine: Prevent use-of-NULL when tracing is enabled + pengine: Stonith resources are allowed to start even if their probes haven't completed on partially active nodes + services: New class called 'service' which expands to the correct (LSB/systemd/upstart) standard + services: Support Asynchronous systemd/upstart actions + Tools: crm_shadow - Bug cl#5062 - Correctly set argv[0] when forking a shell process + Tools: crm_report: Always include system logs (if we can find them) * Wed Mar 28 2012 Andrew Beekhof Pacemaker-1.1.7-1 - Update source tarball to revision: bc7ff2c - Statistics: Changesets: 513 Diff: 1171 files changed, 90472 insertions(+), 19368 deletions(-) - Changes since Pacemaker-1.1.6.1 + ais: Prepare for corosync versions using IPC from libqb + cib: Correctly shutdown in the presence of peers without relying on timers + cib: Don't halt disk writes if the previous digest is missing + cib: Determine when there are no peers to respond to our shutdown request and exit + cib: Ensure no additional messages are processed after we begin terminating + Cluster: Hook up the callbacks to the corosync quorum notifications + Core: basename() may modify its input, do not pass in a constant + Core: Bug cl#5016 - Prevent failures in recurring ops from being lost + Core: Bug rhbz#800054 - Correctly retrieve heartbeat uuids + Core: Correctly determine when an XML file should be decompressed + Core: Correctly track the length of a string without reading from uninitialzied memory (valgrind) + Core: Ensure signals are handled eventually in the absense of timer sources or IPC messages + Core: Prevent use-of-NULL in crm_update_peer() + Core: Strip text nodes from on disk xml files + Core: Support libqb for logging + corosync: Consistently set the correct uuid with get_node_uuid() + Corosync: Correctly disconnect from corosync variants + Corosync: Correctly extract the node id from membership udpates + corosync: Correctly infer lost members from the quorum API + Corosync: Default to using the nodeid as the node's uuid (instead of uname) + corosync: Ensure we catch nodes that leave the membership, even if the ringid doesn't change + corosync: Hook up CPG membership + corosync: Relax a development assert and gracefully handle the error condition + corosync: Remove deprecated member of the CFG API + corosync: Treat CS_ERR_QUEUE_FULL the same as CS_ERR_TRY_AGAIN + corosync: Unset the process list when nodes dissappear on us + crmd: Also purge fencing results when we enter S_NOT_DC + crmd: Bug cl#5015 - Remove the failed operation as well as the resulting fail-count and last-failure attributes + crmd: Correctly determine when a node can suicide with fencing + crmd: Election - perform the age comparison only once + crmd: Fast-track shutdown if we couldn't request it via attrd + crmd: Leave it up to the PE to decide which ops can/cannot be reload + crmd: Prevent use-after-free when calling delete_resource due to CRM_OP_REPROBE + crmd: Supply format arguments in the correct order + fencing: Add missing format parameter + fencing: Add the fencing topology section to the 1.1 configuration schema + fencing: fence_legacy - Drop spurilous host argument from status query + fencing: fence_legacy - Ensure port is available as an environment variable when calling monitor + fencing: fence_pcmk - don't block if nothing is specified on stdin + fencing: Fix log format error + fencing: Fix segfault caused by passing garbage to dlsym() + fencing: Fix use-of-NULL in process_remote_stonith_query() + fencing: Fix use-of-NULL when listing installed devices + fencing: Implement support for advanced fencing topologies: eg. kdump || (network && disk) || power + fencing: More gracefully handle failed 'list' operations for devices that only support a single connection + fencing: Prevent duplicate free when listing devices + fencing: Prevent uninitialized pointers being passed to free + fencing: Prevent use-after-free, we may need the query result for subsequent operations + fencing: Provide enough data to construct an entry in the node's fencing history + fencing: Standardize on /one/ method for clients to request members be fenced + fencing: Supress errors when listing all registered devices + mcp: corosync_cfg_state_track was removed from the corosync API, luckily we didnt use it for anything + mcp: Do not specify a WorkingDirectory in the systemd unit file - startup fails if its not available + mcp: Set the HA_quorum_type env variable consistently with our corosync plugin + mcp: Shut down if one of our child processes can/should not be respawned + pengine: Bug cl#5000 - Ensure ordering is preserved when depending on partial sets + pengine: Bug cl#5028 - Unmanaged services should block shutdown unless in maintainence mode + pengine: Bug cl#5038 - Prevent restart of anonymous clones when clone-max decreases + pengine: Bug cl#5007 - Fixes use of colocation constraints with multi-state resources + pengine: Bug cl#5014 - Prevent asymmetrical order constraints from causing resource stops + pengine: Bug cl#5000 - Implements ability to create rsc_order constraint sets such that A can start after B or C has started. + pengine: Correctly migrate a resource that has just migrated + pengine: Correct return from error path + pengine: Detect reloads of previously migrated resources + pengine: Ensure post-migration stop actions occur before node shutdown + pengine: Log as loudly as possible when we cannot shut down a cluster node + pengine: Reload of a resource no longer causes a restart of dependant resources + pengine: Support limiting the number of concurrent live migrations + pengine: Support referencing templates in constraints + pengine: Support of referencing resource templates in resource sets + pengine: Support to make tickets standby for relinquishing tickets gracefully + stonith: A "start" operation of a stonith resource does a "monitor" on the device beyond registering it + stonith: Bug rhbz#745526 - Ensure stonith_admin actually gets called by fence_pcmk + Stonith: Ensure all nodes receive and deliver notifications of the manual override + stonith: Fix the stonith timeout issue (cl#5009, bnc#727498) + Stonith: Implement a manual override for when nodes are known to be safely off + Tools: Bug cl#5003 - Prevent use-after-free in crm_simlate + Tools: crm_mon - Support to display tickets (based on Yuusuke Iida's work) + Tools: crm_simulate - Support to grant/revoke/standby/activate tickets from the new ticket state section + Tools: Implement crm_node functionality for native corosync + Fix a number of potential problems reported by coverity * Wed Aug 31 2011 Andrew Beekhof 1.1.6-1 - Update source tarball to revision: 676e5f25aa46 tip - Statistics: Changesets: 376 Diff: 1761 files changed, 36259 insertions(+), 140578 deletions(-) - Changes since Pacemaker-1.1.5 + ais: check for retryable errors when dispatching AIS messages + ais: Correctly disconnect from Corosync and Cman based clusters + ais: Followup to previous patch - Ensure we drain the corosync queue of messages when Glib tells us there is input + ais: Handle IPC error before checking for NULL data (bnc#702907) + cib: Check the validation version before adding the originator details of a CIB change + cib: Remove disconnected remote connections from mainloop + cman: Correctly override existing fenced operations + cman: Dequeue all the cman emitted events and not only the first one leaving the others in the event's queue. + cman: Don't call fenced_join and fenced_leave when notifying cman of a fencing event. + cman: We need to run the crmd as root for CMAN so that we can ACK fencing operations + Core: Cancelled and pending operations do not count as failed + Core: Ensure there is sufficient space for EOS when building short-form option strings + Core: Fix variable expansion in pkg-config files + Core: Partial revert of accidental commit in previous patch + Core: Use dlopen to load heartbeat libraries on-demand + crmd: Bug lf#2509 - Watch for config option changes from the CIB even if we're not the DC + crmd: Bug lf#2528 - Introduce a slight delay when creating a transition to allow attrd time to perform its updates + crmd: Bug lf#2559 - Fail actions that were scheduled for a failed/fenced node + crmd: Bug lf#2584 - Allow nodes to fence themselves if they're the last one standing + crmd: Bug lf#2632 - Correctly handle nodes that return faster than stonith + crmd: Cancel timers for actions that were pending on dead nodes + crmd: Catch fence operations that claim to succeed but did not really + crmd: Do not wait for actions that were pending on dead nodes + crmd: Ensure we do not attempt to perform action on failed nodes + crmd: Prevent use-of-NULL by g_hash_table_iter_next() + crmd: Recurring actions shouldn't cause the last non-recurring action to be forgotten + crmd: Store only the last and last failed operation in the CIB + mcp: dirname() modifies the input path - pass in a copy of the logfile path + mcp: Enable stack detection logic instead of forcing 'corosync' + mcp: Fix spelling mistake in systemd service script that prevents shutdown + mcp: Shut down if corosync becomes unavailable + mcp: systemd control file is now functional + pengine: Before migrating an utilization-using resource to a node, take off the load which will no longer run there (lf#2599, bnc#695440) + pengine: Before migrating an utilization-using resource to a node, take off the load which will no longer run there (regression tests) (lf#2599, bnc#695440) + pengine: Bug lf#2574 - Prevent shuffling by choosing the correct clone instance to stop + pengine: Bug lf#2575 - Use uname for migration variables, id is a UUID on heartbeat + pengine: Bug lf#2581 - Avoid group restart when clone (re)starts on an unrelated node + pengine: Bug lf#2613, lf#2619 - Group migration after failures and non-default utilization policies + pengine: Bug suse#707150 - Prevent services being active if dependancies on clones are not satisfied + pengine: Correctly recognise which recurring operations are currently active + pengine: Demote from Master does not clear previous errors + pengine: Ensure restarts due to definition changes cause the start action to be re-issued not probes + pengine: Ensure role is preserved for unmanaged resources + pengine: Ensure unmanaged resources have the correct role set so the correct monitor operation is chosen + pengine: Fix memory leak for re-allocated resources reported by valgrind + pengine: Implement cluster ticket and deadman + pengine: Implement resource template + pengine: Correctly determine the state of multi-state resources with a partial operation history + pengine: Only allocate master/slave resources once + pengine: Partial revert of 'Minor code cleanup CS: cf6bca32376c On: 2011-08-15' + pengine: Resolve memory leak reported by valgrind + pengine: Restore the ability to save inputs to disk + Shell: implement -w,--wait option to wait for the transition to finish + Shell: repair template list command + Shell: set of commands to examine logs, reports, etc + Stonith: Consolidate pcmk_host_map into run_stonith_agent so that it is applied consistently + Stonith: Deprecate pcmk_arg_map for the saner pcmk_host_argument + Stonith: Fix use-of-NULL by g_hash_table_lookup + Stonith: Improved pcmk_host_map parsing + Stonith: Prevent use-of-NULL by g_hash_table_lookup + Stonith: Prevent use-of-NULL when no Linux-HA stonith agents are present + stonith: Add missing entries to stonith_error2string() + Stonith: Correctly finish sending agent options if the initial write is interrupted + stonith: Correctly handle synchronous calls + stonith: Coverity - Correctly construct result list for the query API call + stonith: Coverity - Remove badly constructed memory allocation from the query API call + stonith: Ensure completed operations are recorded as such in the history + Stonith: Ensure device parameters are passed to the daemon during registration + stonith: Fix use-of-NULL in stonith_api_device_list() + stonith: stonith_admin - Prevent use of uninitialized pointer by --history command + Tools: Bug lf#2528 - Make progress when attrd_updater is called repeatedly within the dampen interval but with the same value + Tools: crm_report - Correctly extract data from the local node + Tools: crm_report - Remove newlines when detecting the node list + Tools: crm_report - Repair the ability to extract data from the local machine + Tools: crm_report - Report on all detected backtraces * Fri Feb 11 2011 Andrew Beekhof 1.1.5-1 - Update source tarball to revision: baad6636a053 - Statistics: Changesets: 184 Diff: 605 files changed, 46103 insertions(+), 26417 deletions(-) - Changes since Pacemaker-1.1.4 + Add the ability to delegate sub-sections of the cluster to non-root users via ACLs Needs to be enabled at compile time, not enabled by default. + ais: Bug lf#2550 - Report failed processes immediately + Core: Prevent recently introduced use-after-free in replace_xml_child() + Core: Reinstate the logic that skips past non-XML_ELEMENT_NODE children + Core: Remove extra calls to xmlCleanupParser resulting in use-after-free + Core: Repair reference to child-of-child after removal of xml_child_iter_filter from get_message_xml() + crmd: Bug lf#2545 - Ensure notify variables are accurate for stop operations + crmd: Cancel recurring operations while we're still connected to the lrmd + crmd: Reschedule the PE_START action if its not already running when we try to use it + crmd: Update failcount for failed promote and demote operations + pengine: Bug lf#2445 - Avoid relying on stickness for stable clone placement + pengine: Bug lf#2445 - Do not override configured clone stickiness values + pengine: Bug lf#2493 - Don't imply colocation requirements when applying ordering constraints with clones + pengine: Bug lf#2495 - Prevent segfault by validating the contents of ordering sets + pengine: Bug lf#2508 - Correctly reconstruct the status of anonymous cloned groups + pengine: Bug lf#2518 - Avoid spamming the logs with errors for orphan resources + pengine: Bug lf#2544 - Prevent unstable clone placement by factoring in the current node's score before all others + pengine: Bug lf#2554 - target-role alone is not sufficient to promote resources + pengine: Correct target_rc for probes of inactive resources (fix regression introduced by cs:ac3f03006e95) + pengine: Ensure that fencing has completed for stop actions on stonith-dependent resources (lf#2551) + pengine: Only update the node's promotion score if the resource is active there + pengine: Only use the promotion score from the current clone instance + pengine: Prevent use-of-NULL resulting from variable shadowing spotted by Coverity + pengine: Prevent use-of-NULL when there is status for an undefined node + pengine: Prevet use-after-free resulting from unintended recursion when chosing a node to promote master/slave resources + Shell: don't create empty optional sections (bnc#665131) + Stonith: Teach stonith_admin to automagically obtain the current node attributes for the target from the CIB + tools: Bug lf#2527 - Prevent use-of-NULL in crm_simulate + Tools: Prevent crm_resource commands from being lost due to the use of cib_scope_local * Wed Oct 20 2010 Andrew Beekhof 1.1.4-1 - Update source tarball to revision: 75406c3eb2c1 tip - Statistics: Changesets: 169 Diff: 772 files changed, 56172 insertions(+), 39309 deletions(-) - Changes since Pacemaker-1.1.3 + Italian translation of Clusters from Scratch + Significant performance enhancements to the Policy Engine and CIB + cib: Bug lf#2506 - Don't remove client's when notifications fail, they might just be too big + cib: Drop invalid/failed connections from the client hashtable + cib: Ensure all diffs sent to peers have sufficient ordering information + cib: Ensure non-change diffs can preserve the ordering on the other side + cib: Fix the feature set check + cib: Include version information on our synthesised diffs when nothing changed + cib: Optimize the way we detect group/set ordering changes - 15% speedup + cib: Prevent false detection of config updates with the new diff format + cib: Reduce unnecessary copying when comparing xml objects + cib: Repair the processing of updates sent from peer nodes + cib: Revert part of a recent commit that purged still valid connections + cib: The feature set version check is only valid if the current value is non-NULL + Core: Actually removing diff markers is necessary + Core: Bug lf#2506 - Drop the compression limit because Heartbeat's IPC code sucks + Core: Cache Relax-NG schemas - profiling indicates many cycles are wasted needlessly re-parsing them + Core: Correctly compare against crm_log_level in the logging macros + Core: Correctly extract the version details from a diff + Core: Correctly hook up the RNG schema cache + Core: Correctly use lazy_xml_sort() for v2 digests + Core: Don't compress large payload elements unless we're approaching message limits + Core: Don't insert empty ID tags when applying diffs + Core: Enable the improve v2 digests + Core: Ensure ordering is preserved when applying diffs + Core: Fix the CRM_CHECK macro + Core: Modify the v2 digest algorithm so that some fields are sorted + Core: Prevent use-after-free when creating a CIB update for a timed out action + Core: Prevent use-of-NULL when cleaning up RelaxNG data structures + Core: Provide significant performance improvements by implementing versioned diffs and digests + crmd: All pending operations should be recorded, even recurring ones with high start delays + crmd: Don't abort transitions when probes are completed on a node + crmd: Don't hide stop events that time out - allowing faster recovery in the presence of overloaded hosts + crmd: Ensure the CIB is always writable on the DC by removing a timing hole + crmd: Include the correct transition details for timed out operations + crmd: Prevent use of NULL by making copies of the operation's hash table + crmd: There's no need to check the cib version from the 'added' part of diff updates + crmd: Use the supplied timeout for stop actions + mcp: Ensure valgrind is able to log its output somewhere + mcp: Use 99/01 for the start/stop sequence to avoid problems with services (such as libvirtd) started by init - Patch from Vladislav Bogdanov + pengine: Ensure fencing of the DC preceeds the STONITH_DONE operation + pengine: Fix memory leak introduced as part of the conversion to GHashTables + pengine: Fix memory leak when processing completed migration actions + pengine: Fix typo leading to use-of-NULL in the new ordering code + pengine: Free memory in recently introduced helper function + pengine: lf#2478 - Implement improved handling and recovery of atomic resource migrations + pengine: Obtain massive speedup by prepending to the list of ordering constraints (which can grow quite large) + pengine: Optimize the logic for deciding which non-grouped anonymous clone instances to probe for + pengine: Prevent clones from being stopped because resources colocated with them cannot be active + pengine: Try to ensure atomic migration ops occur within a single transition + pengine: Use hashtables instead of linked lists for performance sensitive datastructures + pengine: Use the original digest algorithm for parameter lists + stonith: cleanup children on timeout in fence_legacy + Stonith: Fix two memory leaks + Tools: crm_shadow - Avoid replacing the entire configuration (including status) * Tue Sep 21 2010 Andrew Beekhof 1.1.3-1 - Update source tarball to revision: e3bb31c56244 tip - Statistics: Changesets: 352 Diff: 481 files changed, 14130 insertions(+), 11156 deletions(-) - Changes since Pacemaker-1.1.2.1 + ais: Bug lf#2401 - Improved processing when the peer crmd processes join/leave + ais: Correct the logic for conecting to plugin based clusters + ais: Do not supply a process list in mcp-mode + ais: Drop support for whitetank in the 1.1 release series + ais: Get an initial dump of the node membership when connecting to quorum-based clusters + ais: Guard against saturated cpg connections + ais: Handle CS_ERR_TRY_AGAIN in more cases + ais: Move the code for finding uid before the fork so that the child does no logging + ais: Never allow quorum plugins to affect connection to the pacemaker plugin + ais: Sign everyone up for peer process updates, not just the crmd + ais: The cluster type needs to be set before initializing classic openais connections + cib: Also free query result for xpath operations that return more than one hit + cib: Attempt to resolve memory corruption when forking a child to write the cib to disk + cib: Correctly free memory when writing out the cib to disk + cib: Fix the application of unversioned diffs + cib: Remove old developmental error logging + cib: Restructure the 'valid peer' check for deciding which instructions to ignore + cman: Correctly process membership/quorum changes from the pcmk plugin. Allow other message types through untouched + cman: Filter directed messages not intended for us + cman: Grab the initial membership when we connect + cman: Keep the list of peer processes up-to-date + cman: Make sure our common hooks are called after a cman membership update + cman: Make sure we can compile without cman present + cman: Populate sender details for cpg messages + cman: Update the ringid for cman based clusters + Core: Correctly unpack HA_Messages containing multiple entries with the same name + Core: crm_count_member() should only track nodes that have the full stack up + Core: New developmental logging system inspired by the kernel and a PoC from Lars Ellenberg + crmd: All nodes should see status updates, not just he DC + crmd: Allow non-DC nodes to clear failcounts too + crmd: Base DC election on process relative uptime + crmd: Bug lf#2439 - cancel_op() can also return HA_RSCBUSY + crmd: Bug lf#2439 - Handle asynchronous notification of resource deletion events + crmd: Bug lf#2458 - Ensure stop actions always have the relevant resource attributes + crmd: Disable age as a criteria for cman based clusters, its not reliable enough + crmd: Ensure we activate the DC timer if we detect an alternate DC + crmd: Factor the nanosecond component of process uptime in elections + crmd: Fix assertion failure when performing async resource failures + crmd: Fix handling of async resource deletion results + crmd: Include the action for crm graph operations + crmd: Make sure the membership cache is accurate after a sucessful fencing operation + crmd: Make sure we always poke the FSA after a transition to clear any TE_HALT actions + crmd: Offer crm-level membership once the peer starts the crmd process + crmd: Only need to request quorum update for plugin based clusters + crmd: Prevent assertion failure for stop actions resulting from cs: 3c0bc17c6daf + crmd: Prevent everyone from loosing DC elections by correctly initializing all relevant variables + crmd: Prevent segmentation fault + crmd: several fixes for async resource delete (thanks to beekhof) + crmd: Use the correct define/size for lrm resource IDs + Introduce two new cluster types 'cman' and 'corosync', replaces 'quorum_provider' concept + mcp: Add missing headers when built without heartbeat support + mcp: Correctly initialize the string containing the list of active daemons + mcp: Fix macro expansion in init script + mcp: Fix the expansion of the pid file in the init script + mcp: Handle CS_ERR_TRY_AGAIN when connecting to libcfg + mcp: Make sure we can compile the mcp without cman present + mcp: New master control process for (re)spawning pacemaker daemons + mcp: Read config early so we can re-initialize logging asap if daemonizing + mcp: Rename the mcp binary to pacemakerd and create a 'pacemaker' init script + mcp: Resend our process list after every CPG change + mcp: Tell chkconfig we need to shut down early on + pengine: Avoid creating invalid ordering constraints for probes that are not needed + pengine: Bug lf#1959 - Fail unmanaged resources should not prevent other services from shutting down + pengine: Bug lf#2422 - Ordering dependencies on partially active groups not observed properly + pengine: Bug lf#2424 - Use notify oepration definition if it exists in the configuration + pengine: Bug lf#2433 - No services should be stopped until probes finish + pengine: Bug lf#2453 - Enforce clone ordering in the absense of colocation constraints + pengine: Bug lf#2476 - Repair on-fail=block for groups and primitive resources + pengine: Correctly detect when there is a real failcount that expired and needs to be cleared + pengine: Correctly handle pseudo action creation + pengine: Correctly order clone startup after group/clone start + pengine: Correct use-after-free introduced in the prior patch + pengine: Do not demote resources because something that requires it can not run + pengine: Fix colocation for interleaved clones + pengine: Fix colocation with partially active groups + pengine: Fix potential use-after-free defect from coverity + pengine: Fix previous merge + pengine: Fix use-after-free in order_actions() reported by valgrind + pengine: Make the current data set a global variable so it does not need to be passed around everywhere + pengine: Prevent endless loop when looking for operation definitions in the configuration + pengine: Prevent segfault by ensuring the arguments to do_calculations() are initialized + pengine: Rewrite the ordering constraint logic to be simplicity, clarity and maintainability + pengine: Wait until stonith is available, do not fall back to shutdown for nodes requesting termination + Resolve coverity RESOURCE_LEAK defects + Shell: Complete the transition to using crm_attribute instead of crm_failcount and crm_standby + stonith: Advertise stonith-ng options in the metadata + stonith: Bug lf#2461 - Prevent segfault by not looking up operations if the hashtable has not been initialized yet + stonith: Bug lf#2473 - Add the timeout at the top level where the daemon is looking for it + Stonith: Bug lf#2473 - Ensure stonith operations complete within the timeout and are terminated if they run too long + stonith: Bug lf#2473 - Ensure timeouts are included for fencing operations + stonith: Bug lf#2473 - Gracefully handle remote operations that arrive late (after we have done notifications) + stonith: Correctly parse pcmk_host_list parameters that appear on a single line + stonith: Map poweron/poweroff back to on/off expected by the stonith tool from cluster-glue + stonith: pass the configuration to the stonith program via environment variables (bnc#620781) + Stonith: Use the timeout specified by the user + Support starting plugin-based Pacemaker clusters with the MCP as well + Tools: Bug lf#2456 - Fix assertion failure in crm_resource + tools: crm_node - Repair the ability to connect to openais based clusters + tools: crm_node - Use the correct short option for --cman + tools: crm_report - corosync.conf wont necessarily contain the text 'pacemaker' anymore + Tools: crm_simulate - Fix use-after-free in when terminating + tools: crm_simulate - Resolve coverity USE_AFTER_FREE defect + Tools: Drop the 'pingd' daemon and resource agent in favor of ocf:pacemaker:ping + Tools: Fix recently introduced use-of-NULL + Tools: Fix use-after-free defects from coverity * Wed May 12 2010 Andrew Beekhof 1.1.2-1 - Update source tarball to revision: c25c972a25cc tip - Statistics: Changesets: 339 Diff: 708 files changed, 37918 insertions(+), 10584 deletions(-) - Changes since Pacemaker-1.1.1 + ais: Do not count votes from offline nodes and calculate current votes before sending quorum data + ais: Ensure the list of active processes sent to clients is always up-to-date + ais: Look for the correct conf variable for turning on file logging + ais: Need to find a better and thread-safe way to set core_uses_pid. Disable for now. + ais: Use the threadsafe version of getpwnam + Core: Bump the feature set due to the new failcount expiry feature + Core: fix memory leaks exposed by valgrind + Core: Bug lf#2414 - Prevent use-after-free reported by valgrind when doing xpath based deletions + crmd: Bug lf#2414 - Prevent use-after-free of the PE connection after it dies + crmd: Bug lf#2414 - Prevent use-after-free of the stonith-ng connection + crmd: Bug lf#2401 - Improved detection of partially active peers + crmd: Bug lf#2379 - Ensure the cluster terminates when the PE is not available + crmd: Do not allow the target_rc to be misused by resource agents + crmd: Do not ignore action timeouts based on FSA state + crmd: Ensure we dont get stuck in S_PENDING if we loose an election to someone that never talks to us again + crmd: Fix memory leaks exposed by valgrind + crmd: Remove race condition that could lead to multiple instances of a clone being active on a machine + crmd: Send erase_status_tag() calls to the local CIB when the DC is fenced, since there is no DC to accept them + crmd: Use global fencing notifications to prevent secondary fencing operations of the DC + pengine: Bug lf#2317 - Avoid needless restart of primitive depending on a clone + pengine: Bug lf#2361 - Ensure clones observe mandatory ordering constraints if the LHS is unrunnable + pengine: Bug lf#2383 - Combine failcounts for all instances of an anonymous clone on a host + pengine: Bug lf#2384 - Fix intra-set colocation and ordering + pengine: Bug lf#2403 - Enforce mandatory promotion (colocation) constraints + pengine: Bug lf#2412 - Correctly find clone instances by their prefix + pengine: Do not be so quick to pull the trigger on nodes that are coming up + pengine: Fix memory leaks exposed by valgrind + pengine: Rewrite native_merge_weights() to avoid Fix use-after-free + Shell: Bug bnc#590035 - always reload status if working with the cluster + Shell: Bug bnc#592762 - Default to using the status section from the live CIB + Shell: Bug lf#2315 - edit multiple meta_attributes sets in resource management + Shell: Bug lf#2221 - enable comments + Shell: Bug bnc#580492 - implement new cibstatus interface and commands + Shell: Bug bnc#585471 - new cibstatus import command + Shell: check timeouts also against the default-action-timeout property + Shell: new configure filter command + Tools: crm_mon - fix memory leaks exposed by valgrind * Tue Feb 16 2010 Andrew Beekhof - 1.1.1-1 - First public release of Pacemaker 1.1 - Package reference documentation in a doc subpackage - Move cts into a subpackage so that it can be easily consumed by others - Update source tarball to revision: 17d9cd4ee29f + New stonith daemon that supports global notifications + Service placement influenced by the physical resources + A new tool for simulating failures and the cluster’s reaction to them + Ability to serialize an otherwise unrelated a set of resource actions (eg. Xen migrations) * Wed Feb 10 2010 Andrew Beekhof - 1.0.7-4 - Rebuild for heartbeat 3.0.2-2 * Wed Feb 10 2010 Andrew Beekhof - 1.0.7-3 - Rebuild for cluster-glue 1.0.3 * Tue Jan 19 2010 Andrew Beekhof - 1.0.7-2 - Rebuild for corosync 1.2.0 * Mon Jan 18 2010 Andrew Beekhof - 1.0.7-1 - Update source tarball to revision: 2eed906f43e9 (stable-1.0) tip - Statistics: Changesets: 193 Diff: 220 files changed, 15933 insertions(+), 8782 deletions(-) - Changes since 1.0.5-4 + pengine: Bug 2213 - Ensure groups process location constraints so that clone-node-max works for cloned groups + pengine: Bug lf#2153 - non-clones should not restart when clones stop/start on other nodes + pengine: Bug lf#2209 - Clone ordering should be able to prevent startup of dependant clones + pengine: Bug lf#2216 - Correctly identify the state of anonymous clones when deciding when to probe + pengine: Bug lf#2225 - Operations that require fencing should wait for 'stonith_complete' not 'all_stopped'. + pengine: Bug lf#2225 - Prevent clone peers from stopping while another is instance is (potentially) being fenced + pengine: Correctly anti-colocate with a group + pengine: Correctly unpack ordering constraints for resource sets to avoid graph loops + Tools: crm: load help from crm_cli.txt + Tools: crm: resource sets (bnc#550923) + Tools: crm: support for comments (LF 2221) + Tools: crm: support for description attribute in resources/operations (bnc#548690) + Tools: hb2openais: add EVMS2 CSM processing (and other changes) (bnc#548093) + Tools: hb2openais: do not allow empty rules, clones, or groups (LF 2215) + Tools: hb2openais: refuse to convert pure EVMS volumes + cib: Ensure the loop for login message terminates + cib: Finally fix reliability of receiving large messages over remote plaintext connections + cib: Fix remote notifications + cib: For remote connections, default to CRM_DAEMON_USER since thats the only one that the cib can validate the password for using PAM + cib: Remote plaintext - Retry sending parts of the message that did not fit the first time + crmd: Ensure batch-limit is correctly enforced + crmd: Ensure we have the latest status after a transition abort + (bnc#547579,547582): Tools: crm: status section editing support + shell: Add allow-migrate as allowed meta-attribute (bnc#539968) + Medium: Build: Do not automatically add -L/lib, it could cause 64-bit arches to break + Medium: pengine: Bug lf#2206 - rsc_order constraints always use score at the top level + Medium: pengine: Only complain about target-role=master for non m/s resources + Medium: pengine: Prevent non-multistate resources from being promoted through target-role + Medium: pengine: Provide a default action for resource-set ordering + Medium: pengine: Silently fix requires=fencing for stonith resources so that it can be set in op_defaults + Medium: Tools: Bug lf#2286 - Allow the shell to accept template parameters on the command line + Medium: Tools: Bug lf#2307 - Provide a way to determin the nodeid of past cluster members + Medium: Tools: crm: add update method to template apply (LF 2289) + Medium: Tools: crm: direct RA interface for ocf class resource agents (LF 2270) + Medium: Tools: crm: direct RA interface for stonith class resource agents (LF 2270) + Medium: Tools: crm: do not add score which does not exist + Medium: Tools: crm: do not consider warnings as errors (LF 2274) + Medium: Tools: crm: do not remove sets which contain id-ref attribute (LF 2304) + Medium: Tools: crm: drop empty attributes elements + Medium: Tools: crm: exclude locations when testing for pathological constraints (LF 2300) + Medium: Tools: crm: fix exit code on single shot commands + Medium: Tools: crm: fix node delete (LF 2305) + Medium: Tools: crm: implement -F (--force) option + Medium: Tools: crm: rename status to cibstatus (LF 2236) + Medium: Tools: crm: revisit configure commit + Medium: Tools: crm: stay in crm if user specified level only (LF 2286) + Medium: Tools: crm: verify changes on exit from the configure level + Medium: ais: Some clients such as gfs_controld want a cluster name, allow one to be specified in corosync.conf + Medium: cib: Clean up logic for receiving remote messages + Medium: cib: Create valid notification control messages + Medium: cib: Indicate where the remote connection came from + Medium: cib: Send password prompt to stderr so that stdout can be redirected + Medium: cts: Fix rsh handling when stdout is not required + Medium: doc: Fill in the section on removing a node from an AIS-based cluster + Medium: doc: Update the docs to reflect the 0.6/1.0 rolling upgrade problem + Medium: doc: Use Publican for docbook based documentation + Medium: fencing: stonithd: add metadata for stonithd instance attributes (and support in the shell) + Medium: fencing: stonithd: ignore case when comparing host names (LF 2292) + Medium: tools: Make crm_mon functional with remote connections + Medium: xml: Add stopped as a supported role for operations + Medium: xml: Bug bnc#552713 - Treat node unames as text fields not IDs + Medium: xml: Bug lf#2215 - Create an always-true expression for empty rules when upgrading from 0.6 * Thu Oct 29 2009 Andrew Beekhof - 1.0.5-4 - Include the fixes from CoroSync integration testing - Move the resource templates - they are not documentation - Ensure documentation is placed in a standard location - Exclude documentation that is included elsewhere in the package - Update the tarball from upstream to version ee19d8e83c2a + cib: Correctly clean up when both plaintext and tls remote ports are requested + pengine: Bug bnc#515172 - Provide better defaults for lt(e) and gt(e) comparisions + pengine: Bug lf#2197 - Allow master instances placemaker to be influenced by colocation constraints + pengine: Make sure promote/demote pseudo actions are created correctly + pengine: Prevent target-role from promoting more than master-max instances + ais: Bug lf#2199 - Prevent expected-quorum-votes from being populated with garbage + ais: Prevent deadlock - dont try to release IPC message if the connection failed + cib: For validation errors, send back the full CIB so the client can display the errors + cib: Prevent use-after-free for remote plaintext connections + crmd: Bug lf#2201 - Prevent use-of-NULL when running heartbeat * Wed Oct 13 2009 Andrew Beekhof - 1.0.5-3 - Update the tarball from upstream to version 38cd629e5c3c + Core: Bug lf#2169 - Allow dtd/schema validation to be disabled + pengine: Bug lf#2106 - Not all anonymous clone children are restarted after configuration change + pengine: Bug lf#2170 - stop-all-resources option had no effect + pengine: Bug lf#2171 - Prevent groups from starting if they depend on a complex resource which can not + pengine: Disable resource management if stonith-enabled=true and no stonith resources are defined + pengine: do not include master score if it would prevent allocation + ais: Avoid excessive load by checking for dead children every 1s (instead of 100ms) + ais: Bug rh#525589 - Prevent shutdown deadlocks when running on CoroSync + ais: Gracefully handle changes to the AIS nodeid + crmd: Bug bnc#527530 - Wait for the transition to complete before leaving S_TRANSITION_ENGINE + crmd: Prevent use-after-free with LOG_DEBUG_3 + Medium: xml: Mask the "symmetrical" attribute on rsc_colocation constraints (bnc#540672) + Medium (bnc#520707): Tools: crm: new templates ocfs2 and clvm + Medium: Build: Invert the disable ais/heartbeat logic so that --without (ais|heartbeat) is available to rpmbuild + Medium: pengine: Bug lf#2178 - Indicate unmanaged clones + Medium: pengine: Bug lf#2180 - Include node information for all failed ops + Medium: pengine: Bug lf#2189 - Incorrect error message when unpacking simple ordering constraint + Medium: pengine: Correctly log resources that would like to start but can not + Medium: pengine: Stop ptest from logging to syslog + Medium: ais: Include version details in plugin name + Medium: crmd: Requery the resource metadata after every start operation * Fri Aug 21 2009 Tomas Mraz - 1.0.5-2.1 - rebuilt with new openssl * Wed Aug 19 2009 Andrew Beekhof - 1.0.5-2 - Add versioned perl dependency as specified by https://fedoraproject.org/wiki/Packaging/Perl#Packages_that_link_to_libperl - No longer remove RPATH data, it prevents us finding libperl.so and no other libraries were being hardcoded - Compile in support for heartbeat - Conditionally add heartbeat-devel and corosynclib-devel to the -devel requirements depending on which stacks are supported * Mon Aug 17 2009 Andrew Beekhof - 1.0.5-1 - Add dependency on resource-agents - Use the version of the configure macro that supplies --prefix, --libdir, etc - Update the tarball from upstream to version 462f1569a437 (Pacemaker 1.0.5 final) + Tools: crm_resource - Advertise --move instead of --migrate + Medium: Extra: New node connectivity RA that uses system ping and attrd_updater + Medium: crmd: Note that dc-deadtime can be used to mask the brokeness of some switches * Tue Aug 11 2009 Ville Skyttä - 1.0.5-0.7.c9120a53a6ae.hg - Use bzipped upstream tarball. * Wed Jul 29 2009 Andrew Beekhof - 1.0.5-0.6.c9120a53a6ae.hg - Add back missing build auto* dependancies - Minor cleanups to the install directive * Tue Jul 28 2009 Andrew Beekhof - 1.0.5-0.5.c9120a53a6ae.hg - Add a leading zero to the revision when alphatag is used * Tue Jul 28 2009 Andrew Beekhof - 1.0.5-0.4.c9120a53a6ae.hg - Incorporate the feedback from the cluster-glue review - Realistically, the version is a 1.0.5 pre-release - Use the global directive instead of define for variables - Use the haclient/hacluster group/user instead of daemon - Use the _configure macro - Fix install dependancies * Fri Jul 24 2009 Andrew Beekhof - 1.0.4-3 - Initial Fedora checkin - Include an AUTHORS and license file in each package - Change the library package name to pacemaker-libs to be more Fedora compliant - Remove execute permissions from xml related files - Reference the new cluster-glue devel package name - Update the tarball from upstream to version c9120a53a6ae + pengine: Only prevent migration if the clone dependency is stopping/starting on the target node + pengine: Bug 2160 - Dont shuffle clones due to colocation + pengine: New implementation of the resource migration (not stop/start) logic + Medium: Tools: crm_resource - Prevent use-of-NULL by requiring a resource name for the -A and -a options + Medium: pengine: Prevent use-of-NULL in find_first_action() * Tue Jul 14 2009 Andrew Beekhof - 1.0.4-2 - Reference authors from the project AUTHORS file instead of listing in description - Change Source0 to reference the Mercurial repo - Cleaned up the summaries and descriptions - Incorporate the results of Fedora package self-review * Thu Jun 04 2009 Andrew Beekhof - 1.0.4-1 - Update source tarball to revision: 1d87d3e0fc7f (stable-1.0) - Statistics: Changesets: 209 Diff: 266 files changed, 12010 insertions(+), 8276 deletions(-) - Changes since Pacemaker-1.0.3 + (bnc#488291): ais: do not rely on byte endianness on ptr cast + (bnc#507255): Tools: crm: delete rsc/op_defaults (these meta_attributes are killing me) + (bnc#507255): Tools: crm: import properly rsc/op_defaults + (LF 2114): Tools: crm: add support for operation instance attributes + ais: Bug lf#2126 - Messages replies cannot be routed to transient clients + ais: Fix compilation for the latest Corosync API (v1719) + attrd: Do not perform all updates as complete refreshes + cib: Fix huge memory leak affecting heartbeat-based clusters + Core: Allow xpath queries to match attributes + Core: Generate the help text directly from a tool options struct + Core: Handle differences in 0.6 messaging format + crmd: Bug lf#2120 - All transient node attribute updates need to go via attrd + crmd: Correctly calculate how long an FSA action took to avoid spamming the logs with errors + crmd: Fix another large memory leak affecting Heartbeat based clusters + lha: Restore compatability with older versions + pengine: Bug bnc#495687 - Filesystem is not notified of successful STONITH under some conditions + pengine: Make running a cluster with STONITH enabled but no STONITH resources an error and provide details on resolutions + pengine: Prevent use-ofNULL when using resource ordering sets + pengine: Provide inter-notification ordering guarantees + pengine: Rewrite the notification code to be understanable and extendable + Tools: attrd - Prevent race condition resulting in the cluster forgetting the node wishes to shut down + Tools: crm: regression tests + Tools: crm_mon - Fix smtp notifications + Tools: crm_resource - Repair the ability to query meta attributes + Low Build: Bug lf#2105 - Debian package should contain pacemaker doc and crm templates + Medium (bnc#507255): Tools: crm: handle empty rsc/op_defaults properly + Medium (bnc#507255): Tools: crm: use the right obj_type when creating objects from xml nodes + Medium (LF 2107): Tools: crm: revisit exit codes in configure + Medium: cib: Do not bother validating updates that only affect the status section + Medium: Core: Include supported stacks in version information + Medium: crmd: Record in the CIB, the cluster infrastructure being used + Medium: cts: Do not combine crm_standby arguments - the wrapper can not process them + Medium: cts: Fix the CIBAusdit class + Medium: Extra: Refresh showscores script from Dominik + Medium: pengine: Build a statically linked version of ptest + Medium: pengine: Correctly log the actions for resources that are being recovered + Medium: pengine: Correctly log the occurance of promotion events + Medium: pengine: Implememt node health based on a patch from Mark Hamzy + Medium: Tools: Add examples to help text outputs + Medium: Tools: crm: catch syntax errors for configure load + Medium: Tools: crm: implement erasing nodes in configure erase + Medium: Tools: crm: work with parents only when managing xml objects + Medium: Tools: crm_mon - Add option to run custom notification program on resource operations (Patch by Dominik Klein) + Medium: Tools: crm_resource - Allow --cleanup to function on complex resources and cluster-wide + Medium: Tools: haresource2cib.py - Patch from horms to fix conversion error + Medium: Tools: Include stack information in crm_mon output + Medium: Tools: Two new options (--stack,--constraints) to crm_resource for querying how a resource is configured * Wed Apr 08 2009 Andrew Beekhof - 1.0.3-1 - Update source tarball to revision: b133b3f19797 (stable-1.0) tip - Statistics: Changesets: 383 Diff: 329 files changed, 15471 insertions(+), 15119 deletions(-) - Changes since Pacemaker-1.0.2 + Added tag SLE11-HAE-GMC for changeset 9196be9830c2 + ais plugin: Fix quorum calculation (bnc#487003) + ais: Another memory fix leak in error path + ais: Bug bnc#482847, bnc#482905 - Force a clean exit of OpenAIS once Pacemaker has finished unloading + ais: Bug bnc#486858 - Fix update_member() to prevent spamming clients with membership events containing no changes + ais: Centralize all quorum calculations in the ais plugin and allow expected votes to be configured int he cib + ais: Correctly handle a return value of zero from openais_dispatch_recv() + ais: Disable logging to a file + ais: Fix memory leak in error path + ais: IPC messages are only in scope until a response is sent + All signal handlers used with CL_SIGNAL() need to be as minimal as possible + cib: Bug bnc#482885 - Simplify CIB disk-writes to prevent data loss. Required a change to the backup filename format + cib: crmd: Revert part of 9782ab035003. Complex shutdown routines need G_main_add_SignalHandler to avoid race coditions + crm: Avoid infinite loop during crm configure edit (bnc#480327) + crmd: Avoid a race condition by waiting for the attrd update to trigger a transition automatically + crmd: Bug bnc#480977 - Prevent extra, partial, shutdown when a node restarts too quickly + crmd: Bug bnc#480977 - Prevent extra, partial, shutdown when a node restarts too quickly (verified) + crmd: Bug bnc#489063 - Ensure the DC is always unset after we 'loose' an election + crmd: Bug BSC#479543 - Correctly find the migration source for timed out migrate_from actions + crmd: Call crm_peer_init() before we start the FSA - prevents a race condition when used with Heartbeat + crmd: Erasing the status section should not be forced to the local node + crmd: Fix memory leak in cib notication processing code + crmd: Fix memory leak in transition graph processing + crmd: Fix memory leaks found by valgrind + crmd: More memory leaks fixes found by valgrind + fencing: stonithd: is_heartbeat_cluster is a no-no if there is no heartbeat support + pengine: Bug bnc#466788 - Exclude nodes that can not run resources + pengine: Bug bnc#466788 - Make colocation based on node attributes work + pengine: Bug BNC#478687 - Do not crash when clone-max is 0 + pengine: Bug bnc#488721 - Fix id-ref expansion for clones, the doc-root for clone children is not the cib root + pengine: Bug bnc#490418 - Correctly determine node state for nodes wishing to be terminated + pengine: Bug LF#2087 - Correctly parse the state of anonymous clones that have multiple instances on a given node + pengine: Bug lf#2089 - Meta attributes are not inherited by clone children + pengine: Bug lf#2091 - Correctly restart modified resources that were found active by a probe + pengine: Bug lf#2094 - Fix probe ordering for cloned groups + pengine: Bug LF:2075 - Fix large pingd memory leaks + pengine: Correctly attach orphaned clone children to their parent + pengine: Correctly handle terminate node attributes that are set to the output from time() + pengine: Ensure orphaned clone members are hooked up to the parent when clone-max=0 + pengine: Fix memory leak in LogActions + pengine: Fix the determination of whether a group is active + pengine: Look up the correct promotion preference for anonymous masters + pengine: Simplify handling of start failures by changing the default migration-threshold to INFINITY + pengine: The ordered option for clones no longer causes extra start/stop operations + RA: Bug bnc#490641 - Shut down dlm_controld with -TERM instead of -KILL + RA: pingd: Set default ping interval to 1 instead of 0 seconds + Resources: pingd - Correctly tell the ping daemon to shut down + Tools: Bug bnc#483365 - Ensure the command from cluster_test includes a value for --log-facility + Tools: cli: fix and improve delete command + Tools: crm: add and implement templates + Tools: crm: add support for command aliases and some common commands (i.e. cd,exit) + Tools: crm: create top configuration nodes if they are missing + Tools: crm: fix parsing attributes for rules (broken by the previous changeset) + Tools: crm: new ra set of commands + Tools: crm: resource agents information management + Tools: crm: rsc/op_defaults + Tools: crm: support for no value attribute in nvpairs + Tools: crm: the new configure monitor command + Tools: crm: the new configure node command + Tools: crm_mon - Prevent use-of-NULL when summarizing an orphan + Tools: hb2openais: create clvmd clone for respawn evmsd in ha.cf + Tools: hb2openais: fix a serious recursion bug in xml node processing + Tools: hb2openais: fix ocfs2 processing + Tools: pingd - prevent double free of getaddrinfo() output in error path + Tools: The default re-ping interval for pingd should be 1s not 1ms + Medium (bnc#479049): Tools: crm: add validation of resource type for the configure primitive command + Medium (bnc#479050): Tools: crm: add help for RA parameters in tab completion + Medium (bnc#479050): Tools: crm: add tab completion for primitive params/meta/op + Medium (bnc#479050): Tools: crm: reimplement cluster properties completion + Medium (bnc#486968): Tools: crm: listnodes function requires no parameters (do not mix completion with other stuff) + Medium: ais: Remove the ugly hack for dampening AIS membership changes + Medium: cib: Fix memory leaks by using mainloop_add_signal + Medium: cib: Move more logging to the debug level (was info) + Medium: cib: Overhaul the processing of synchronous replies + Medium: Core: Add library functions for instructing the cluster to terminate nodes + Medium: crmd: Add new expected-quorum-votes option + Medium: crmd: Allow up to 5 retires when an attrd update fails + Medium: crmd: Automatically detect and use new values for crm_config options + Medium: crmd: Bug bnc#490426 - Escalated shutdowns stall when there are pending resource operations + Medium: crmd: Clean up and optimize the DC election algorithm + Medium: crmd: Fix memory leak in shutdown + Medium: crmd: Fix memory leaks spotted by Valgrind + Medium: crmd: Ingore join messages from hosts other than our DC + Medium: crmd: Limit the scope of resource updates to the status section + Medium: crmd: Prevent the crmd from being respawned if its told to shut down when it did not ask to be + Medium: crmd: Re-check the election status after membership events + Medium: crmd: Send resource updates via the local CIB during elections + Medium: pengine: Bug bnc#491441 - crm_mon does not display operations returning 'uninstalled' correctly + Medium: pengine: Bug lf#2101 - For location constraints, role=Slave is equivalent to role=Started + Medium: pengine: Clean up the API - removed ->children() and renamed ->find_child() to fine_rsc() + Medium: pengine: Compress the display of healthy anonymous clones + Medium: pengine: Correctly log the actions for resources that are being recovered + Medium: pengine: Determin a promotion score for complex resources + Medium: pengine: Ensure clones always have a value for globally-unique + Medium: pengine: Prevent orphan clones from being allocated + Medium: RA: controld: Return proper exit code for stop op. + Medium: Tools: Bug bnc#482558 - Fix logging test in cluster_test + Medium: Tools: Bug bnc#482828 - Fix quoting in cluster_test logging setup + Medium: Tools: Bug bnc#482840 - Include directory path to CTSlab.py + Medium: Tools: crm: add more user input checks + Medium: Tools: crm: do not check resource status of we are working with a shadow + Medium: Tools: crm: fix id-refs and allow reference to top objects (i.e. primitive) + Medium: Tools: crm: ignore comments in the CIB + Medium: Tools: crm: multiple column output would not work with small lists + Medium: Tools: crm: refuse to delete running resources + Medium: Tools: crm: rudimentary if-else for templates + Medium: Tools: crm: Start/stop clones via target-role. + Medium: Tools: crm_mon - Compress the node status for healthy and offline nodes + Medium: Tools: crm_shadow - Return 0/cib_ok when --create-empty succeeds + Medium: Tools: crm_shadow - Support -e, the short form of --create-empty + Medium: Tools: Make attrd quieter + Medium: Tools: pingd - Avoid using various clplumbing functions as they seem to leak + Medium: Tools: Reduce pingd logging * Mon Feb 16 2009 Andrew Beekhof - 1.0.2-1 - Update source tarball to revision: d232d19daeb9 (stable-1.0) tip - Statistics: Changesets: 441 Diff: 639 files changed, 20871 insertions(+), 21594 deletions(-) - Changes since Pacemaker-1.0.1 + (bnc#450815): Tools: crm cli: do not generate id for the operations tag + ais: Add support for the new AIS IPC layer + ais: Always set header.error to the correct default: SA_AIS_OK + ais: Bug BNC#456243 - Ensure the membership cache always contains an entry for the local node + ais: Bug BNC:456208 - Prevent deadlocks by not logging in the child process before exec() + ais: By default, disable supprt for the WIP openais IPC patch + ais: Detect and handle situations where ais and the crm disagree on the node name + ais: Ensure crm_peer_seq is updated after a membership update + ais: Make sure all IPC header fields are set to sane defaults + ais: Repair and streamline service load now that whitetank startup functions correctly + build: create and install doc files + cib: Allow clients without mainloop to connect to the cib + cib: CID:18 - Fix use-of-NULL in cib_perform_op + cib: CID:18 - Repair errors introduced in b5a18704477b - Fix use-of-NULL in cib_perform_op + cib: Ensure diffs contain the correct values of admin_epoch + cib: Fix four moderately sized memory leaks detected by Valgrind + Core: CID:10 - Prevent indexing into an array of schemas with a negative value + Core: CID:13 - Fix memory leak in log_data_element + Core: CID:15 - Fix memory leak in crm_get_peer + Core: CID:6 - Fix use-of-NULL in copy_ha_msg_input + Core: Fix crash in the membership code preventing node shutdown + Core: Fix more memory leaks foudn by valgrind + Core: Prevent unterminated strings after decompression + crmd: Bug BNC:467995 - Delay marking STONITH operations complete until STONITH tells us so + crmd: Bug LF:1962 - Do not NACK peers because they are not (yet) in our membership. Just ignore them. + crmd: Bug LF:2010 - Ensure fencing cib updates create the node_state entry if needed to preent re-fencing during cluster startup + crmd: Correctly handle reconnections to attrd + crmd: Ensure updates for lost migrate operations indicate which node it tried to migrating to + crmd: If there are no nodes to finalize, start an election. + crmd: If there are no nodes to welcome, start an election. + crmd: Prevent node attribute loss by detecting attrd disconnections immediately + crmd: Prevent node re-probe loops by ensuring manditory actions always complete + pengine: Bug 2005 - Fix startup ordering of cloned stonith groups + pengine: Bug 2006 - Correctly reprobe cloned groups + pengine: Bug BNC:465484 - Fix the no-quorum-policy=suicide option + pengine: Bug LF:1996 - Correctly process disabled monitor operations + pengine: CID:19 - Fix use-of-NULL in determine_online_status + pengine: Clones now default to globally-unique=false + pengine: Correctly calculate the number of available nodes for the clone to use + pengine: Only shoot online nodes with no-quorum-policy=suicide + pengine: Prevent on-fail settings being ignored after a resource is successfully stopped + pengine: Prevent use-of-NULL for failed migrate actions in process_rsc_state() + pengine: Remove an optimization for the terminate node attribute that caused the cluster to block indefinitly + pengine: Repar the ability to colocate based on node attributes other than uname + pengine: Start the correct monitor operation for unmanaged masters + stonith: CID:3 - Fix another case of exceptionally poor error handling by the original stonith developers + stonith: CID:5 - Checking for NULL and then dereferencing it anyway is an interesting approach to error handling + stonithd: Sending IPC to the cluster is a privileged operation + stonithd: wrong checks for shmid (0 is a valid id) + Tools: attrd - Correctly determine when an attribute has stopped changing and should be committed to the CIB + Tools: Bug 2003 - pingd does not correctly detect failures when the interface is down + Tools: Bug 2003 - pingd does not correctly handle node-down events on multi-NIC systems + Tools: Bug 2021 - pingd does not detect sequence wrapping correctly, incorrectly reports nodes offline + Tools: Bug BNC:468066 - Do not use the result of uname() when its no longer in scope + Tools: Bug BNC:473265 - crm_resource -L dumps core + Tools: Bug LF:2001 - Transient node attributes should be set via attrd + Tools: Bug LF:2036 - crm_resource cannot set/get parameters for cloned resources + Tools: Bug LF:2046 - Node attribute updates are lost because attrd can take too long to start + Tools: Cause the correct clone instance to be failed with crm_resource -F + Tools: cluster_test - Allow the user to select a stack and fix CTS invocation + Tools: crm cli: allow rename only if the resource is stopped + Tools: crm cli: catch system errors on file operations + Tools: crm cli: completion for ids in configure + Tools: crm cli: drop '-rsc' from attributes for order constraint + Tools: crm cli: exit with an appropriate exit code + Tools: crm cli: fix wrong order of action and resource in order constraint + Tools: crm cli: fox wrong exit code + Tools: crm cli: improve handling of cib attributes + Tools: crm cli: new command: configure rename + Tools: crm cli: new command: configure upgrade + Tools: crm cli: new command: node delete + Tools: crm cli: prevent key errors on missing cib attributes + Tools: crm cli: print long help for help topics + Tools: crm cli: return on syntax error when parsing score + Tools: crm cli: rsc_location can be without nvpairs + Tools: crm cli: short node preference location constraint + Tools: crm cli: sometimes, on errors, level would change on single shot use + Tools: crm cli: syntax: drop a bunch of commas (remains of help tables conversion) + Tools: crm cli: verify user input for sanity + Tools: crm: find expressions within rules (do not always skip xml nodes due to used id) + Tools: crm_master should not define a set id now that attrd is used. Defining one can break lookups + Tools: crm_mon Use the OID assigned to the project by IANA for SNMP traps + Medium (bnc#445622): Tools: crm cli: improve the node show command and drop node status + Medium (LF 2009): stonithd: improve timeouts for remote fencing + Medium: ais: Allow dead peers to be removed from membership calculations + Medium: ais: Pass node deletion events on to clients + Medium: ais: Sanitize ipc usage + Medium: ais: Supply the node uname in addtion to the id + Medium: Build: Clean up configure to ensure NON_FATAL_CFLAGS is consistent with CFLAGS (ie. includes -g) + Medium: Build: Install cluster_test + Medium: Build: Use more restrictive CFLAGS and fix the resulting errors + Medium: cib: CID:20 - Fix potential use-after-free in cib_native_signon + Medium: Core: Bug BNC:474727 - Set a maximum time to wait for IPC messages + Medium: Core: CID:12 - Fix memory leak in decode_transition_magic error path + Medium: Core: CID:14 - Fix memory leak in calculate_xml_digest error path + Medium: Core: CID:16 - Fix memory leak in date_to_string error path + Medium: Core: Try to track down the cause of XML parsing errors + Medium: crmd: Bug BNC:472473 - Do not wait excessive amounts of time for lost actions + Medium: crmd: Bug BNC:472473 - Reduce the transition timeout to action_timeout+network_delay + Medium: crmd: Do not fast-track the processing of LRM refreshes when there are pending actions. + Medium: crmd: do_dc_join_filter_offer - Check the 'join' message is for the current instance before deciding to NACK peers + Medium: crmd: Find option values without having to do a config upgrade + Medium: crmd: Implement shutdown using a transient node attribute + Medium: crmd: Update the crmd options to use dashes instead of underscores + Medium: cts: Add 'cluster reattach' to the suite of automated regression tests + Medium: cts: cluster_test - Make some usability enhancements + Medium: CTS: cluster_test - suggest a valid port number + Medium: CTS: Fix python import order + Medium: cts: Implement an automated SplitBrain test + Medium: CTS: Remove references to deleted classes + Medium: Extra: Resources - Use HA_VARRUN instead of HA_RSCTMP for state files as Heartbeat removes HA_RSCTMP at startup + Medium: HB: Bug 1933 - Fake crmd_client_status_callback() calls because HB does not provide them for already running processes + Medium: pengine: CID:17 - Fix memory leak in find_actions_by_task error path + Medium: pengine: CID:7,8 - Prevent hypothetical use-of-NULL in LogActions + Medium: pengine: Defer logging the actions performed on a resource until we have processed ordering constraints + Medium: pengine: Remove the symmetrical attribute of colocation constraints + Medium: Resources: pingd - fix the meta defaults + Medium: Resources: Stateful - Add missing meta defaults + Medium: stonithd: exit if we the pid file cannot be locked + Medium: Tools: Allow attrd clients to specify the ID the attribute should be created with + Medium: Tools: attrd - Allow attribute updates to be performed from a hosts peer + Medium: Tools: Bug LF:1994 - Clean up crm_verify return codes + Medium: Tools: Change the pingd defaults to ping hosts once every second (instead of 5 times every 10 seconds) + Medium: Tools: cibmin - Detect resource operations with a view to providing email/snmp/cim notification + Medium: Tools: crm cli: add back symmetrical for order constraints + Medium: Tools: crm cli: generate role in location when converting from xml + Medium: Tools: crm cli: handle shlex exceptions + Medium: Tools: crm cli: keep order of help topics + Medium: Tools: crm cli: refine completion for ids in configure + Medium: Tools: crm cli: replace inf with INFINITY + Medium: Tools: crm cli: streamline cib load and parsing + Medium: Tools: crm cli: supply provider only for ocf class primitives + Medium: Tools: crm_mon - Add support for sending mail notifications of resource events + Medium: Tools: crm_mon - Include the DC version in status summary + Medium: Tools: crm_mon - Sanitize startup and option processing + Medium: Tools: crm_mon - switch to event-driven updates and add support for sending snmp traps + Medium: Tools: crm_shadow - Replace the --locate option with the saner --edit + Medium: Tools: hb2openais: do not remove Evmsd resources, but replace them with clvmd + Medium: Tools: hb2openais: replace crmadmin with crm_mon + Medium: Tools: hb2openais: replace the lsb class with ocf for o2cb + Medium: Tools: hb2openais: reuse code + Medium: Tools: LF:2029 - Display an error if crm_resource is used to reset the operation history of non-primitive resources + Medium: Tools: Make pingd resilient to attrd failures + Medium: Tools: pingd - fix the command line switches + Medium: Tools: Rename ccm_tool to crm_node * Tue Nov 18 2008 Andrew Beekhof - 1.0.1-1 - Update source tarball to revision: 6fc5ce8302ab (stable-1.0) tip - Statistics: Changesets: 170 Diff: 816 files changed, 7633 insertions(+), 6286 deletions(-) - Changes since Pacemaker-1.0.1 + ais: Allow the crmd to get callbacks whenever a node state changes + ais: Create an option for starting the mgmtd daemon automatically + ais: Ensure HA_RSCTMP exists for use by resource agents + ais: Hook up the openais.conf config logging options + ais: Zero out the PID of disconnecting clients + cib: Ensure global updates cause a disk write when appropriate + Core: Add an extra snaity check to getXpathResults() to prevent segfaults + Core: Do not redefine __FUNCTION__ unnecessarily + Core: Repair the ability to have comments in the configuration + crmd: Bug:1975 - crmd should wait indefinitely for stonith operations to complete + crmd: Ensure PE processing does not occur for all error cases in do_pe_invoke_callback + crmd: Requests to the CIB should cause any prior PE calculations to be ignored + heartbeat: Wait for membership 'up' events before removing stale node status data + pengine: Bug LF:1988 - Ensure recurring operations always have the correct target-rc set + pengine: Bug LF:1988 - For unmanaged resources we need to skip the usual can_run_resources() checks + pengine: Ensure the terminate node attribute is handled correctly + pengine: Fix optional colocation + pengine: Improve up the detection of 'new' nodes joining the cluster + pengine: Prevent assert failures in master_color() by ensuring unmanaged masters are always reallocated to their current location + Tools: crm cli: parser: return False on syntax error and None for comments + Tools: crm cli: unify template and edit commands + Tools: crm_shadow - Show more line number information after validation failures + Tools: hb2openais: add option to upgrade the CIB to v3.0 + Tools: hb2openais: add U option to getopts and update usage + Tools: hb2openais: backup improved and multiple fixes + Tools: hb2openais: fix class/provider reversal + Tools: hb2openais: fix testing + Tools: hb2openais: move the CIB update to the end + Tools: hb2openais: update logging and set logfile appropriately + Tools: LF:1969 - Attrd never sets any properties in the cib + Tools: Make attrd functional on OpenAIS + Medium: ais: Hook up the options for specifying the expected number of nodes and total quorum votes + Medium: ais: Look for pacemaker options inside the service block with 'name: pacemaker' instead of creating an addtional configuration block + Medium: ais: Provide better feedback when nodes change nodeids (in openais.conf) + Medium: cib: Always store cib contents on disk with num_updates=0 + Medium: cib: Ensure remote access ports are cleaned up on shutdown + Medium: crmd: Detect deleted resource operations automatically + Medium: crmd: Erase a nodes resource operations and transient attributes after a successful STONITH + Medium: crmd: Find a more appropriate place to update quorum and refresh attrd attributes + Medium: crmd: Fix the handling of unexpected PE exits to ensure the current CIB is stored + Medium: crmd: Fix the recording of pending operations in the CIB + Medium: crmd: Initiate an attrd refresh _after_ the status section has been fully repopulated + Medium: crmd: Only the DC should update quorum in an openais cluster + Medium: Ensure meta attributes are used consistantly + Medium: pengine: Allow group and clone level resource attributes + Medium: pengine: Bug N:437719 - Ensure scores from colocated resources count when allocating groups + Medium: pengine: Prevent lsb scripts from being used in globally unique clones + Medium: pengine: Make a best-effort guess at a migration threshold for people with 0.6 configs + Medium: Resources: controld - ensure we are part of a clone with globally_unique=false + Medium: Tools: attrd - Automatically refresh all attributes after a CIB replace operation + Medium: Tools: Bug LF:1985 - crm_mon - Correctly process failed cib queries to allow reconnection after cluster restarts + Medium: Tools: Bug LF:1987 - crm_verify incorrectly warns of configuration upgrades for the most recent version + Medium: Tools: crm (bnc#441028): check for key error in attributes management + Medium: Tools: crm_mon - display the meaning of the operation rc code instead of the status + Medium: Tools: crm_mon - Fix the display of timing data + Medium: Tools: crm_verify - check that we are being asked to validate a complete config + Medium: xml: Relax the restriction on the contents of rsc_locaiton.node * Thu Oct 16 2008 Andrew Beekhof - 1.0.0-1 - Update source tarball to revision: 388654dfef8f tip - Statistics: Changesets: 261 Diff: 3021 files changed, 244985 insertions(+), 111596 deletions(-) - Changes since f805e1b30103 + add the crm cli program + ais: Move the service id definition to a common location and make sure it is always used + build: rename hb2openais.sh to .in and replace paths with vars + cib: Implement --create for crm_shadow + cib: Remove dead files + Core: Allow the expected number of quorum votes to be configrable + Core: cl_malloc and friends were removed from Heartbeat + Core: Only call xmlCleanupParser() if we parsed anything. Doing so unconditionally seems to cause a segfault + hb2openais.sh: improve pingd handling; several bugs fixed + hb2openais: fix clone creation; replace EVMS strings + new hb2openais.sh conversion script + pengine: Bug LF:1950 - Ensure the current values for all notification variables are always set (even if empty) + pengine: Bug LF:1955 - Ensure unmanaged masters are unconditionally repromoted to ensure they are monitored correctly. + pengine: Bug LF:1955 - Fix another case of filtering causing unmanaged master failures + pengine: Bug LF:1955 - Umanaged mode prevents master resources from being allocated correctly + pengine: Bug N:420538 - Anit-colocation caused a positive node preference + pengine: Correctly handle unmanaged resources to prevent them from being started elsewhere + pengine: crm_resource - Fix the --migrate command + pengine: MAke stonith-enabled default to true and warn if no STONITH resources are found + pengine: Make sure orphaned clone children are created correctly + pengine: Monitors for unmanaged resources do not need to wait for start/promote/demote actions to complete + stonithd (LF 1951): fix remote stonith operations + stonithd: fix handling of timeouts + stonithd: fix logic for stonith resource priorities + stonithd: implement the fence-timeout instance attribute + stonithd: initialize value before reading fence-timeout + stonithd: set timeouts for fencing ops to the timeout of the start op + stonithd: stonith rsc priorities (new feature) + Tools: Add hb2openais - a tool for upgrading a Heartbeat cluster to use OpenAIS instead + Tools: crm_verify - clean up the upgrade logic to prevent crash on invalid configurations + Tools: Make pingd functional on Linux + Update version numbers for 1.0 candidates + Medium: ais: Add support for a synchronous call to retrieve the nodes nodeid + Medium: ais: Use the agreed service number + Medium: Build: Reliably detect heartbeat libraries during configure + Medium: Build: Supply prototypes for libreplace functions when needed + Medium: Build: Teach configure how to find corosync + Medium: Core: Provide better feedback if Pacemaker is started by a stack it does not support + Medium: crmd: Avoid calling GHashTable functions with NULL + Medium: crmd: Delay raising I_ERROR when the PE exits until we have had a chance to save the current CIB + Medium: crmd: Hook up the stonith-timeout option to stonithd + Medium: crmd: Prevent potential use-of-NULL in global_timer_callback + Medium: crmd: Rationalize the logging of graph aborts + Medium: pengine: Add a stonith_timeout option and remove new options that are better set in rsc_defaults + Medium: pengine: Allow external entities to ask for a node to be shot by creating a terminate=true transient node attribute + Medium: pengine: Bug LF:1950 - Notifications do not contain all documented resource state fields + Medium: pengine: Bug N:417585 - Do not restart group children whos individual score drops below zero + Medium: pengine: Detect clients that disconnect before receiving their reply + Medium: pengine: Implement a true maintenance mode + Medium: pengine: Implement on-fail=standby for NTT. Derived from a patch by Satomi TANIGUCHI + Medium: pengine: Print the correct message when stonith is disabled + Medium: pengine: ptest - check the input is valid before proceeding + Medium: pengine: Revert group stickiness to the 'old way' + Medium: pengine: Use the correct attribute for action 'requires' (was prereq) + Medium: stonithd: Fix compilation without full heartbeat install + Medium: stonithd: exit with better code on empty host list + Medium: tools: Add a new regression test for CLI tools + Medium: tools: crm_resource - return with non-zero when a resource migration command is invalid + Medium: tools: crm_shadow - Allow the admin to start with an empty CIB (and no cluster connection) + Medium: xml: pacemaker-0.7 is now an alias for the 1.0 schema * Mon Sep 22 2008 Andrew Beekhof - 0.7.3-1 - Update source tarball to revision: 33e677ab7764+ tip - Statistics: Changesets: 133 Diff: 89 files changed, 7492 insertions(+), 1125 deletions(-) - Changes since f805e1b30103 + Tools: add the crm cli program + Core: cl_malloc and friends were removed from Heartbeat + Core: Only call xmlCleanupParser() if we parsed anything. Doing so unconditionally seems to cause a segfault + new hb2openais.sh conversion script + pengine: Bug LF:1950 - Ensure the current values for all notification variables are always set (even if empty) + pengine: Bug LF:1955 - Ensure unmanaged masters are unconditionally repromoted to ensure they are monitored correctly. + pengine: Bug LF:1955 - Fix another case of filtering causing unmanaged master failures + pengine: Bug LF:1955 - Umanaged mode prevents master resources from being allocated correctly + pengine: Bug N:420538 - Anit-colocation caused a positive node preference + pengine: Correctly handle unmanaged resources to prevent them from being started elsewhere + pengine: crm_resource - Fix the --migrate command + pengine: MAke stonith-enabled default to true and warn if no STONITH resources are found + pengine: Make sure orphaned clone children are created correctly + pengine: Monitors for unmanaged resources do not need to wait for start/promote/demote actions to complete + stonithd (LF 1951): fix remote stonith operations + Tools: crm_verify - clean up the upgrade logic to prevent crash on invalid configurations + Medium: ais: Add support for a synchronous call to retrieve the nodes nodeid + Medium: ais: Use the agreed service number + Medium: pengine: Allow external entities to ask for a node to be shot by creating a terminate=true transient node attribute + Medium: pengine: Bug LF:1950 - Notifications do not contain all documented resource state fields + Medium: pengine: Bug N:417585 - Do not restart group children whos individual score drops below zero + Medium: pengine: Implement a true maintenance mode + Medium: pengine: Print the correct message when stonith is disabled + Medium: stonithd: exit with better code on empty host list + Medium: xml: pacemaker-0.7 is now an alias for the 1.0 schema * Wed Aug 20 2008 Andrew Beekhof - 0.7.1-1 - Update source tarball to revision: f805e1b30103+ tip - Statistics: Changesets: 184 Diff: 513 files changed, 43408 insertions(+), 43783 deletions(-) - Changes since 0.7.0-19 + Fix compilation when GNUTLS isnt found + admin: Fix use-after-free in crm_mon + Build: Remove testing code that prevented heartbeat-only builds + cib: Use single quotes so that the xpath queries for nvpairs will succeed + crmd: Always connect to stonithd when the TE starts and ensure we notice if it dies + crmd: Correctly handle a dead PE process + crmd: Make sure async-failures cause the failcount to be incrimented + pengine: Bug LF:1941 - Handle failed clone instance probes when clone-max < #nodes + pengine: Parse resource ordering sets correctly + pengine: Prevent use-of-NULL - order->rsc_rh will not always be non-NULL + pengine: Unpack colocation sets correctly + Tools: crm_mon - Prevent use-of-NULL for orphaned resources + Medium: ais: Add support for a synchronous call to retrieve the nodes nodeid + Medium: ais: Allow transient clients to receive membership updates + Medium: ais: Avoid double-free in error path + Medium: ais: Include in the mebership nodes for which we have not determined their hostname + Medium: ais: Spawn the PE from the ais plugin instead of the crmd + Medium: cib: By default, new configurations use the latest schema + Medium: cib: Clean up the CIB if it was already disconnected + Medium: cib: Only incriment num_updates if something actually changed + Medium: cib: Prevent use-after-free in client after abnormal termination of the CIB + Medium: Core: Fix memory leak in xpath searches + Medium: Core: Get more details regarding parser errors + Medium: Core: Repair expand_plus_plus - do not call char2score on unexpanded values + Medium: Core: Switch to the libxml2 parser - its significantly faster + Medium: Core: Use a libxml2 library function for xml -> text conversion + Medium: crmd: Asynchronous failure actions have no parameters + Medium: crmd: Avoid calling glib functions with NULL + Medium: crmd: Do not allow an election to promote a node from S_STARTING + Medium: crmd: Do not vote if we have not completed the local startup + Medium: crmd: Fix te_update_diff() now that get_object_root() functions differently + Medium: crmd: Fix the lrmd xpath expressions to not contain quotes + Medium: crmd: If we get a join offer during an election, better restart the election + Medium: crmd: No further processing is needed when using the LRMs API call for failing resources + Medium: crmd: Only update have-quorum if the value changed + Medium: crmd: Repair the input validation logic in do_te_invoke + Medium: cts: CIBs can no longer contain comments + Medium: cts: Enable a bunch of tests that were incorrectly disabled + Medium: cts: The libxml2 parser wont allow v1 resources to use integers as parameter names + Medium: Do not use the cluster UID and GID directly. Look them up based on the configured value of HA_CCMUSER + Medium: Fix compilation when heartbeat is not supported + Medium: pengine: Allow groups to be involved in optional ordering constraints + Medium: pengine: Allow sets of operations to be reused by multiple resources + Medium: pengine: Bug LF:1941 - Mark extra clone instances as orphans and do not show inactive ones + Medium: pengine: Determin the correct migration-threshold during resource expansion + Medium: pengine: Implement no-quorum-policy=suicide (FATE #303619) + Medium: pengine: Clean up resources after stopping old copies of the PE + Medium: pengine: Teach the PE how to stop old copies of itself + Medium: Tools: Backport hb_report updates + Medium: Tools: cib_shadow - On create, spawn a new shell with CIB_shadow and PS1 set accordingly + Medium: Tools: Rename cib_shadow to crm_shadow * Fri Jul 18 2008 Andrew Beekhof - 0.7.0-19 - Update source tarball to revision: 007c3a1c50f5 (unstable) tip - Statistics: Changesets: 108 Diff: 216 files changed, 4632 insertions(+), 4173 deletions(-) - Changes added since unstable-0.7 + admin: Fix use-after-free in crm_mon + ais: Change the tag for the ais plugin to "pacemaker" (used in openais.conf) + ais: Log terminated processes as an error + cib: Performance - Reorganize things to avoid calculating the XML diff twice + pengine: Bug LF:1941 - Handle failed clone instance probes when clone-max < #nodes + pengine: Fix memory leak in action2xml + pengine: Make OCF_ERR_ARGS a node-level error rather than a cluster-level one + pengine: Properly handle clones that are not installed on all nodes + Medium: admin: cibadmin - Show any validation errors if the upgrade failed + Medium: admin: cib_shadow - Implement --locate to display the underlying filename + Medium: admin: cib_shadow - Implement a --diff option + Medium: admin: cib_shadow - Implement a --switch option + Medium: admin: crm_resource - create more compact constraints that do not use lifetime (which is deprecated) + Medium: ais: Approximate born_on for OpenAIS based clusters + Medium: cib: Remove do_id_check, it is a poor substitute for ID validation by a schema + Medium: cib: Skip construction of pre-notify messages if no-one wants one + Medium: Core: Attempt to streamline some key functions to increase performance + Medium: Core: Clean up XML parser after validation + Medium: crmd: Detect and optimize the CRMs behavior when processing diffs of an LRM refresh + Medium: Fix memory leaks when resetting the name of an XML object + Medium: pengine: Prefer the current location if it is one of a group of nodes with the same (highest) score * Wed Jun 25 2008 Andrew Beekhof - 0.7.0-1 - Update source tarball to revision: bde0c7db74fb tip - Statistics: Changesets: 439 Diff: 676 files changed, 41310 insertions(+), 52071 deletions(-) - Changes added since stable-0.6 + A new tool for setting up and invoking CTS + Admin: All tools now use --node (-N) for specifying node unames + Admin: All tools now use --xml-file (-x) and --xml-text (-X) for specifying where to find XML blobs + cib: Cleanup the API - remove redundant input fields + cib: Implement CIB_shadow - a facility for making and testing changes before uploading them to the cluster + cib: Make registering per-op callbacks an API call and renamed (for clarity) the API call for requesting notifications + Core: Add a facility for automatically upgrading old configurations + Core: Adopt libxml2 as the XML processing library - all external clients need to be recompiled + Core: Allow sending TLS messages larger than the MTU + Core: Fix parsing of time-only ISO dates + Core: Smarter handling of XML values containing quotes + Core: XML memory corruption - catch, and handle, cases where we are overwriting an attribute value with itself + Core: The xml ID type does not allow UUIDs that start with a number + Core: Implement XPath based versions of query/delete/replace/modify + Core: Remove some HA2.0.(3,4) compatability code + crmd: Overhaul the detection of nodes that are starting vs. failed + pengine: Bug LF:1459 - Allow failures to expire + pengine: Have the PE do non-persistent configuration upgrades before performing calculations + pengine: Replace failure-stickiness with a simple 'migration-threshold' + tengine: Simplify the design by folding the tengine process into the crmd + Medium: Admin: Bug LF:1438 - Allow the list of all/active resource operations to be queried by crm_resource + Medium: Admin: Bug LF:1708 - crm_resource should print a warning if an attribute is already set as a meta attribute + Medium: Admin: Bug LF:1883 - crm_mon should display fail-count and operation history + Medium: Admin: Bug LF:1883 - crm_mon should display operation timing data + Medium: Admin: Bug N:371785 - crm_resource -C does not also clean up fail-count attributes + Medium: Admin: crm_mon - include timing data for failed actions + Medium: ais: Read options from the environment since objdb is not completely usable yet + Medium: cib: Add sections for op_defaults and rsc_defaults + Medium: cib: Better matching notification callbacks (for detecting duplicates and removal) + Medium: cib: Bug LF:1348 - Allow rules and attribute sets to be referenced for use in other objects + Medium: cib: BUG LF:1918 - By default, all cib calls now timeout after 30s + Medium: cib: Detect updates that decrease the version tuple + Medium: cib: Implement a client-side operation timeout - Requires LHA update + Medium: cib: Implement callbacks and async notifications for remote connections + Medium: cib: Make cib->cmds->update() an alias for modify at the API level (also implemented in cibadmin) + Medium: cib: Mark the CIB as disconnected if the IPC connection is terminated + Medium: cib: New call option 'cib_can_create' which can be passed to modify actions - allows the object to be created if it does not exist yet + Medium: cib: Reimplement get|set|delete attributes using XPath + Medium: cib: Remove some useless parts of the API + Medium: cib: Remove the 'attributes' scaffolding from the new format + Medium: cib: Implement the ability for clients to connect to remote servers + Medium: Core: Add support for validating xml against RelaxNG schemas + Medium: Core: Allow more than one item to be modified/deleted in XPath based operations + Medium: Core: Fix the sort_pairs function for creating sorted xml objects + Medium: Core: iso8601 - Implement subtract_duration and fix subtract_time + Medium: Core: Reduce the amount of xml copying occuring + Medium: Core: Support value='value+=N' XML updates (in addtion to value='value++') + Medium: crmd: Add support for lrm_ops->fail_rsc if its available + Medium: crmd: HB - watch link status for node leaving events + Medium: crmd: Bug LF:1924 - Improved handling of lrmd disconnects and shutdowns + Medium: crmd: Do not wait for actions with a start_delay over 5 minutes. Confirm them immediately + Medium: pengine: Bug LF:1328 - Do not fencing nodes in clusters without managed resources + Medium: pengine: Bug LF:1461 - Give transient node attributes (in ) preference over persistent ones (in ) + Medium: pengine: Bug LF:1884, Bug LF:1885 - Implement N:M ordering and colocation constraints + Medium: pengine: Bug LF:1886 - Create a resource and operation 'defaults' config section + Medium: pengine: Bug LF:1892 - Allow recurring actions to be triggered at known times + Medium: pengine: Bug LF:1926 - Probes should complete before stop actions are invoked + Medium: pengine: Fix the standby when its set as a transient attribute + Medium: pengine: Implement a global 'stop-all-resources' option + Medium: pengine: Implement cibpipe, a tool for performing/simulating config changes "offline" + Medium: pengine: We do not allow colocation with specific clone instances + Medium: Tools: pingd - Implement a stack-independant version of pingd + Medium: xml: Ship an xslt for upgrading from 0.6 to 0.7 * Thu Jun 19 2008 Andrew Beekhof - 0.6.5-1 - Update source tarball to revision: b9fe723d1ac5 tip - Statistics: Changesets: 48 Diff: 37 files changed, 1204 insertions(+), 234 deletions(-) - Changes since Pacemaker-0.6.4 + Admin: Repair the ability to delete failcounts + ais: Audit IPC handling between the AIS plugin and CRM processes + ais: Have the plugin create needed /var/lib directories + ais: Make sure the sync and async connections are assigned correctly (not swapped) + cib: Correctly detect configuration changes - num_updates does not count + pengine: Apply stickiness values to the whole group, not the individual resources + pengine: Bug N:385265 - Ensure groups are migrated instead of remaining partially active on the current node + pengine: Bug N:396293 - Enforce manditory group restarts due to ordering constraints + pengine: Correctly recover master instances found active on more than one node + pengine: Fix memory leaks reported by Valgrind + Medium: Admin: crm_mon - Misc improvements from Satomi Taniguchi + Medium: Bug LF:1900 - Resource stickiness should not allow placement in asynchronous clusters + Medium: crmd: Ensure joins are completed promptly when a node taking part dies + Medium: pengine: Avoid clone instance shuffling in more cases + Medium: pengine: Bug LF:1906 - Remove an optimization in native_merge_weights() causing group scores to behave eratically + Medium: pengine: Make use of target_rc data to correctly process resource operations + Medium: pengine: Prevent a possible use of NULL in sort_clone_instance() + Medium: tengine: Include target rc in the transition key - used to correctly determin operation failure * Thu May 22 2008 Andrew Beekhof - 0.6.4-1 - Update source tarball to revision: 226d8e356924 tip - Statistics: Changesets: 55 Diff: 199 files changed, 7103 insertions(+), 12378 deletions(-) - Changes since Pacemaker-0.6.3 + crmd: Bug LF:1881 LF:1882 - Overhaul the logic for operation cancelation and deletion + crmd: Bug LF:1894 - Make sure cancelled recurring operations are cleaned out from the CIB + pengine: Bug N:387749 - Colocation with clones causes unnecessary clone instance shuffling + pengine: Ensure 'master' monitor actions are cancelled _before_ we demote the resource + pengine: Fix assert failure leading to core dump - make sure variable is properly initialized + pengine: Make sure 'slave' monitoring happens after the resource has been demoted + pengine: Prevent failure stickiness underflows (where too many failures become a _positive_ preference) + Medium: Admin: crm_mon - Only complain if the output file could not be opened + Medium: Common: filter_action_parameters - enable legacy handling only for older versions + Medium: pengine: Bug N:385265 - The failure stickiness of group children is ignored until it reaches -INFINITY + Medium: pengine: Implement master and clone colocation by exlcuding nodes rather than setting ones score to INFINITY (similar to cs: 756afc42dc51) + Medium: tengine: Bug LF:1875 - Correctly find actions to cancel when their node leaves the cluster * Wed Apr 23 2008 Andrew Beekhof - 0.6.3-1 - Update source tarball to revision: fd8904c9bc67 tip - Statistics: Changesets: 117 Diff: 354 files changed, 19094 insertions(+), 11338 deletions(-) - Changes since Pacemaker-0.6.2 + Admin: Bug LF:1848 - crm_resource - Pass set name and id to delete_resource_attr() in the correct order + Build: SNMP has been moved to the management/pygui project + crmd: Bug LF1837 - Unmanaged resources prevent crmd from shutting down + crmd: Prevent use-after-free in lrm interface code (Patch based on work by Keisuke MORI) + pengine: Allow the cluster to make progress by not retrying failed demote actions + pengine: Anti-colocation with slave should not prevent master colocation + pengine: Bug LF 1768 - Wait more often for STONITH ops to complete before starting resources + pengine: Bug LF1836 - Allow is-managed-default=false to be overridden by individual resources + pengine: Bug LF185 - Prevent pointless master/slave instance shuffling by ignoring the master-pref of stopped instances + pengine: Bug N-191176 - Implement interleaved ordering for clone-to-clone scenarios + pengine: Bug N-347004 - Ensure clone notifications are always sent when an instance is stopped/started + pengine: Bug N-347004 - Include notification ordering is correct for interleaved clones + pengine: Bug PM-11 - Directly link probe_complete to starting clone instances + pengine: Bug PM1 - Fix setting failcounts when applied to complex resources + pengine: Bug PM12, LF1648 - Extensive revision of group ordering + pengine: Bug PM7 - Ensure masters are always demoted before they are stopped + pengine: Create probes after allocation to allow smarter handling of anonymous clones + pengine: Do not prioritize clone instances that must be moved + pengine: Fix error in previous commit that allowed more than the required number of masters to be promoted + pengine: Group start ordering fixes + pengine: Implement promote/demote ordering for cloned groups + tengine: Repair failcount updates + tengine: Use the correct offset when updating failcount + Medium: Admin: Add a summary output that can be easily parsed by CTS for audit purposes + Medium: Build: Make configure fail if bz2 or libxml2 are not present + Medium: Build: Re-instate a better default for LCRSODIR + Medium: CIB: Bug LF-1861 - Filter irrelvant error status from synchronous CIB clients + Medium: Core: Bug 1849 - Invalid conversion of ordinal leap year to gregorian date + Medium: Core: Drop compataibility code for 2.0.4 and 2.0.5 clusters + Medium: crmd: Bug LF-1860 - Automatically cancel recurring ops before demote and promote operations (not only stops) + Medium: crmd: Save the current CIB contents if we detect the PE crashed + Medium: pengine: Bug LF:1866 - Fix version check when applying compatability handling for failed start operations + Medium: pengine: Bug LF:1866 - Restore the ability to have start failures not be fatal + Medium: pengine: Bug PM1 - Failcount applies to all instances of non-unique clone + Medium: pengine: Correctly set the state of partially active master/slave groups + Medium: pengine: Do not claim to be stopping an already stopped orphan + Medium: pengine: Ensure implies_left ordering constraints are always effective + Medium: pengine: Indicate each resources 'promotion' score + Medium: pengine: Prevent a possible use-of-NULL + Medium: pengine: Reprocess the current action if it changed (so that any prior dependancies are updated) + Medium: tengine: Bug LF-1859 - Wait for fail-count updates to complete before terminating the transition + Medium: tengine: Bug LF:1859 - Do not abort graphs due to our own failcount updates + Medium: tengine: Bug LF:1859 - Prevent the TE from interupting itself * Thu Feb 14 2008 Andrew Beekhof - 0.6.2-1 - Update source tarball to revision: 28b1a8c1868b tip - Statistics: Changesets: 11 Diff: 7 files changed, 58 insertions(+), 18 deletions(-) - Changes since Pacemaker-0.6.1 + haresources2cib.py: set default-action-timeout to the default (20s) + haresources2cib.py: update ra parameters lists + Medium: SNMP: Allow the snmp subagent to be built (patch from MATSUDA, Daiki) + Medium: Tools: Make sure the autoconf variables in haresources2cib are expanded * Tue Feb 12 2008 Andrew Beekhof - 0.6.1-1 - Update source tarball to revision: e7152d1be933 tip - Statistics: Changesets: 25 Diff: 37 files changed, 1323 insertions(+), 227 deletions(-) - Changes since Pacemaker-0.6.0 + CIB: Ensure changes to top-level attributes (like admin_epoch) cause a disk write + CIB: Ensure the archived file hits the disk before returning + CIB: Repair the ability to do 'atomic incriment' updates (value="value++") + crmd: Bug #7 - Connecting to the crmd immediately after startup causes use-of-NULL + Medium: CIB: Mask cib_diff_resync results from the caller - they do not need to know + Medium: crmd: Delay starting the IPC server until we are fully functional + Medium: CTS: Fix the startup patterns + Medium: pengine: Bug 1820 - Allow the first resource in a group to be migrated + Medium: pengine: Bug 1820 - Check the colocation dependancies of resources to be migrated * Mon Jan 14 2008 Andrew Beekhof - 0.6.0-2 - This is the first release of the Pacemaker Cluster Resource Manager formerly part of Heartbeat. - For those looking for the GUI, mgmtd, CIM or TSA components, they are now found in the new pacemaker-pygui project. Build dependancies prevent them from being included in Heartbeat (since the built-in CRM is no longer supported) and, being non-core components, are not included with Pacemaker. - Update source tarball to revision: c94b92d550cf - Statistics: Changesets: 347 Diff: 2272 files changed, 132508 insertions(+), 305991 deletions(-) - Test hardware: + 6-node vmware cluster (sles10-sp1/256Mb/vmware stonith) on a single host (opensuse10.3/2Gb/2.66Ghz Quad Core2) + 7-node EMC Centera cluster (sles10/512Mb/2Ghz Xeon/ssh stonith) - Notes: Heartbeat Stack + All testing was performed with STONITH enabled + The CRM was enabled using the "crm respawn" directive - Notes: OpenAIS Stack + This release contains a preview of support for the OpenAIS cluster stack + The current release of the OpenAIS project is missing two important patches that we require. OpenAIS packages containing these patches are available for most major distributions at: http://download.opensuse.org/repositories/server:/ha-clustering + The OpenAIS stack is not currently recommended for use in clusters that have shared data as STONITH support is not yet implimented + pingd is not yet available for use with the OpenAIS stack + 3 significant OpenAIS issues were found during testing of 4 and 6 node clusters. We are activly working together with the OpenAIS project to get these resolved. - Pending bugs encountered during testing: + OpenAIS #1736 - Openais membership took 20s to stabilize + Heartbeat #1750 - ipc_bufpool_update: magic number in head does not match + OpenAIS #1793 - Assertion failure in memb_state_gather_enter() + OpenAIS #1796 - Cluster message corruption - Changes since Heartbeat-2.1.2-24 + Add OpenAIS support + Admin: crm_uuid - Look in the right place for Heartbeat UUID files + admin: Exit and indicate a problem if the crmd exits while crmadmin is performing a query + cib: Fix CIB_OP_UPDATE calls that modify the whole CIB + cib: Fix compilation when supporting the heartbeat stack + cib: Fix memory leaks caused by the switch to get_message_xml() + cib: HA_VALGRIND_ENABLED needs to be set _and_ set to 1|yes|true + cib: Use get_message_xml() in preference to cl_get_struct() + cib: Use the return value from call to write() in cib_send_plaintext() + Core: ccm nodes can legitimately have a node id of 0 + Core: Fix peer-process tracking for the Heartbeat stack + Core: Heartbeat does not send status notifications for nodes that were already part of the cluster. Fake them instead + CRM: Add children to HA_Messages such that the field name matches F_XML_TAGNAME + crm: Adopt a more flexible appraoch to enabling Valgrind + crm: Fix compilation when bzip2 is not installed + CRM: Future-proof get_message_xml() + crmd: Filter election responses based on time not FSA state + crmd: Handle all possible peer states in crmd_ha_status_callback() + crmd: Make sure the current date/time is set - prevents use-of-NULL when evaluating rules + crmd: Relax an assertion regrading ccm membership instances + crmd: Use (node->processes&crm_proc_ais) to accurately update the CIB after replace operations + crmd: Heartbeat: Accurately record peer client status + pengine: Bug 1777 - Allow colocation with a resource in the Stopped state + pengine: Bug 1822 - Prevent use-of-NULL in PromoteRsc() + pengine: Implement three recovery policies based on op_status and op_rc + pengine: Parse fail-count correctly (it may be set to ININFITY) + pengine: Prevent graph-loop when stonith agents need to be moved around before a STONITH op + pengine: Prevent graph-loops when two operations have the same name+interval + tengine: Cancel active timers when destroying graphs + tengine: Ensure failcount is set correctly for failed stops/starts + tengine: Update failcount for oeprations that time out + Medium: admin: Prevent hang in crm_mon -1 when there is no cib connection - Patch from Junko IKEDA + Medium: cib: Require --force|-f when performing potentially dangerous commands with cibadmin + Medium: cib: Tweak the shutdown code + Medium: Common: Only count peer processes of active nodes + Medium: Core: Create generic cluster sign-in method + Medium: core: Fix compilation when Heartbeat support is disabled + Medium: Core: General cleanup for supporting two stacks + Medium: Core: iso6601 - Support parsing of time-only strings + Medium: core: Isolate more code that is only needed when SUPPORT_HEARTBEAT is enabled + Medium: crm: Improved logging of errors in the XML parser + Medium: crmd: Fix potential use-of-NULL in string comparison + Medium: crmd: Reimpliment syncronizing of CIB queries and updates when invoking the PE + Medium: crm_mon: Indicate when a node is both in standby mode and offline + Medium: pengine: Bug 1822 - Do not try an promote groups if not all of it is active + Medium: pengine: on_fail=nothing is an alias for 'ignore' not 'restart' + Medium: pengine: Prevent a potential use-of-NULL in cron_range_satisfied() + snmp subagent: fix a problem on displaying an unmanaged group + snmp subagent: use the syslog setting + snmp: v2 support (thanks to Keisuke MORI) + snmp_subagent - made it not complain about some things if shutting down * Mon Dec 10 2007 Andrew Beekhof - 0.6.0-1 - Initial opensuse package check-in pacemaker-master/Doxyfile.in000066400000000000000000002157061217637305600164370ustar00rootroot00000000000000# Doxyfile 1.7.4 # This file describes the settings to be used by the documentation system # doxygen (www.doxygen.org) for a project. # # All text after a hash (#) is considered a comment and will be ignored. # The format is: # TAG = value [value, ...] # For lists items can also be appended using: # TAG += value [value, ...] # Values that contain spaces should be placed between quotes (" "). #--------------------------------------------------------------------------- # Project related configuration options #--------------------------------------------------------------------------- # This tag specifies the encoding used for all characters in the config file # that follow. The default is UTF-8 which is also the encoding used for all # text before the first occurrence of this tag. Doxygen uses libiconv (or the # iconv built into libc) for the transcoding. See # http://www.gnu.org/software/libiconv for the list of possible encodings. DOXYFILE_ENCODING = UTF-8 # The PROJECT_NAME tag is a single word (or a sequence of words surrounded # by quotes) that should identify the project. PROJECT_NAME = @PACKAGE_NAME@ # The PROJECT_NUMBER tag can be used to enter a project or revision number. # This could be handy for archiving the generated documentation or # if some version control system is used. PROJECT_NUMBER = @PACKAGE_VERSION@-@BUILD_VERSION@ # Using the PROJECT_BRIEF tag one can provide an optional one line description # for a project that appears at the top of each page and should give viewer # a quick idea about the purpose of the project. Keep the description short. PROJECT_BRIEF = "Scalable High-Availability cluster resource manager" # With the PROJECT_LOGO tag one can specify an logo or icon that is # included in the documentation. The maximum height of the logo should not # exceed 55 pixels and the maximum width should not exceed 200 pixels. # Doxygen will copy the logo to the output directory. PROJECT_LOGO = doc/publican-clusterlabs/en-US/images/title_logo.png # The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) # base path where the generated documentation will be put. # If a relative path is entered, it will be relative to the location # where doxygen was started. If left blank the current directory will be used. OUTPUT_DIRECTORY = doc/api/ # If the CREATE_SUBDIRS tag is set to YES, then doxygen will create # 4096 sub-directories (in 2 levels) under the output directory of each output # format and will distribute the generated files over these directories. # Enabling this option can be useful when feeding doxygen a huge amount of # source files, where putting all generated files in the same directory would # otherwise cause performance problems for the file system. CREATE_SUBDIRS = NO # The OUTPUT_LANGUAGE tag is used to specify the language in which all # documentation generated by doxygen is written. Doxygen will use this # information to generate all constant output in the proper language. # The default language is English, other supported languages are: # Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional, # Croatian, Czech, Danish, Dutch, Esperanto, Farsi, Finnish, French, German, # Greek, Hungarian, Italian, Japanese, Japanese-en (Japanese with English # messages), Korean, Korean-en, Lithuanian, Norwegian, Macedonian, Persian, # Polish, Portuguese, Romanian, Russian, Serbian, Serbian-Cyrillic, Slovak, # Slovene, Spanish, Swedish, Ukrainian, and Vietnamese. OUTPUT_LANGUAGE = English # If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will # include brief member descriptions after the members that are listed in # the file and class documentation (similar to JavaDoc). # Set to NO to disable this. BRIEF_MEMBER_DESC = YES # If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend # the brief description of a member or function before the detailed description. # Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the # brief descriptions will be completely suppressed. REPEAT_BRIEF = YES # This tag implements a quasi-intelligent brief description abbreviator # that is used to form the text in various listings. Each string # in this list, if found as the leading text of the brief description, will be # stripped from the text and the result after processing the whole list, is # used as the annotated text. Otherwise, the brief description is used as-is. # If left blank, the following values are used ("$name" is automatically # replaced with the name of the entity): "The $name class" "The $name widget" # "The $name file" "is" "provides" "specifies" "contains" # "represents" "a" "an" "the" ABBREVIATE_BRIEF = # If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then # Doxygen will generate a detailed section even if there is only a brief # description. ALWAYS_DETAILED_SEC = NO # If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all # inherited members of a class in the documentation of that class as if those # members were ordinary class members. Constructors, destructors and assignment # operators of the base classes will not be shown. INLINE_INHERITED_MEMB = NO # If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full # path before files name in the file list and in the header files. If set # to NO the shortest path that makes the file name unique will be used. FULL_PATH_NAMES = YES # If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag # can be used to strip a user-defined part of the path. Stripping is # only done if one of the specified strings matches the left-hand part of # the path. The tag can be used to show relative paths in the file list. # If left blank the directory from which doxygen is run is used as the # path to strip. STRIP_FROM_PATH = # The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of # the path mentioned in the documentation of a class, which tells # the reader which header file to include in order to use a class. # If left blank only the name of the header file containing the class # definition is used. Otherwise one should specify the include paths that # are normally passed to the compiler using the -I flag. STRIP_FROM_INC_PATH = # If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter # (but less readable) file names. This can be useful if your file system # doesn't support long names like on DOS, Mac, or CD-ROM. SHORT_NAMES = NO # If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen # will interpret the first line (until the first dot) of a JavaDoc-style # comment as the brief description. If set to NO, the JavaDoc # comments will behave just like regular Qt-style comments # (thus requiring an explicit @brief command for a brief description.) JAVADOC_AUTOBRIEF = NO # If the QT_AUTOBRIEF tag is set to YES then Doxygen will # interpret the first line (until the first dot) of a Qt-style # comment as the brief description. If set to NO, the comments # will behave just like regular Qt-style comments (thus requiring # an explicit \brief command for a brief description.) QT_AUTOBRIEF = NO # The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen # treat a multi-line C++ special comment block (i.e. a block of //! or /// # comments) as a brief description. This used to be the default behaviour. # The new default is to treat a multi-line C++ comment block as a detailed # description. Set this tag to YES if you prefer the old behaviour instead. MULTILINE_CPP_IS_BRIEF = NO # If the INHERIT_DOCS tag is set to YES (the default) then an undocumented # member inherits the documentation from any documented member that it # re-implements. INHERIT_DOCS = YES # If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce # a new page for each member. If set to NO, the documentation of a member will # be part of the file/class/namespace that contains it. SEPARATE_MEMBER_PAGES = NO # The TAB_SIZE tag can be used to set the number of spaces in a tab. # Doxygen uses this value to replace tabs by spaces in code fragments. TAB_SIZE = 4 # This tag can be used to specify a number of aliases that acts # as commands in the documentation. An alias has the form "name=value". # For example adding "sideeffect=\par Side Effects:\n" will allow you to # put the command \sideeffect (or @sideeffect) in the documentation, which # will result in a user-defined paragraph with heading "Side Effects:". # You can put \n's in the value part of an alias to insert newlines. ALIASES = # Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C # sources only. Doxygen will then generate output that is more tailored for C. # For instance, some of the names that are used will be different. The list # of all members will be omitted, etc. OPTIMIZE_OUTPUT_FOR_C = YES # Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java # sources only. Doxygen will then generate output that is more tailored for # Java. For instance, namespaces will be presented as packages, qualified # scopes will look different, etc. OPTIMIZE_OUTPUT_JAVA = NO # Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran # sources only. Doxygen will then generate output that is more tailored for # Fortran. OPTIMIZE_FOR_FORTRAN = NO # Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL # sources. Doxygen will then generate output that is tailored for # VHDL. OPTIMIZE_OUTPUT_VHDL = NO # Doxygen selects the parser to use depending on the extension of the files it # parses. With this tag you can assign which parser to use for a given extension. # Doxygen has a built-in mapping, but you can override or extend it using this # tag. The format is ext=language, where ext is a file extension, and language # is one of the parsers supported by doxygen: IDL, Java, Javascript, CSharp, C, # C++, D, PHP, Objective-C, Python, Fortran, VHDL, C, C++. For instance to make # doxygen treat .inc files as Fortran files (default is PHP), and .f files as C # (default is Fortran), use: inc=Fortran f=C. Note that for custom extensions # you also need to set FILE_PATTERNS otherwise the files are not read by doxygen. EXTENSION_MAPPING = # If you use STL classes (i.e. std::string, std::vector, etc.) but do not want # to include (a tag file for) the STL sources as input, then you should # set this tag to YES in order to let doxygen match functions declarations and # definitions whose arguments contain STL classes (e.g. func(std::string); v.s. # func(std::string) {}). This also makes the inheritance and collaboration # diagrams that involve STL classes more complete and accurate. BUILTIN_STL_SUPPORT = NO # If you use Microsoft's C++/CLI language, you should set this option to YES to # enable parsing support. CPP_CLI_SUPPORT = NO # Set the SIP_SUPPORT tag to YES if your project consists of sip sources only. # Doxygen will parse them like normal C++ but will assume all classes use public # instead of private inheritance when no explicit protection keyword is present. SIP_SUPPORT = NO # For Microsoft's IDL there are propget and propput attributes to indicate getter # and setter methods for a property. Setting this option to YES (the default) # will make doxygen replace the get and set methods by a property in the # documentation. This will only work if the methods are indeed getting or # setting a simple type. If this is not the case, or you want to show the # methods anyway, you should set this option to NO. IDL_PROPERTY_SUPPORT = YES # If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC # tag is set to YES, then doxygen will reuse the documentation of the first # member in the group (if any) for the other members of the group. By default # all members of a group must be documented explicitly. DISTRIBUTE_GROUP_DOC = YES # Set the SUBGROUPING tag to YES (the default) to allow class member groups of # the same type (for instance a group of public functions) to be put as a # subgroup of that type (e.g. under the Public Functions section). Set it to # NO to prevent subgrouping. Alternatively, this can be done per class using # the \nosubgrouping command. SUBGROUPING = YES # When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and # unions are shown inside the group in which they are included (e.g. using # @ingroup) instead of on a separate page (for HTML and Man pages) or # section (for LaTeX and RTF). INLINE_GROUPED_CLASSES = NO # When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum # is documented as struct, union, or enum with the name of the typedef. So # typedef struct TypeS {} TypeT, will appear in the documentation as a struct # with name TypeT. When disabled the typedef will appear as a member of a file, # namespace, or class. And the struct will be named TypeS. This can typically # be useful for C code in case the coding convention dictates that all compound # types are typedef'ed and only the typedef is referenced, never the tag name. TYPEDEF_HIDES_STRUCT = NO # The SYMBOL_CACHE_SIZE determines the size of the internal cache use to # determine which symbols to keep in memory and which to flush to disk. # When the cache is full, less often used symbols will be written to disk. # For small to medium size projects (<1000 input files) the default value is # probably good enough. For larger projects a too small cache size can cause # doxygen to be busy swapping symbols to and from disk most of the time # causing a significant performance penalty. # If the system has enough physical memory increasing the cache will improve the # performance by keeping more symbols in memory. Note that the value works on # a logarithmic scale so increasing the size by one will roughly double the # memory usage. The cache size is given by this formula: # 2^(16+SYMBOL_CACHE_SIZE). The valid range is 0..9, the default is 0, # corresponding to a cache size of 2^16 = 65536 symbols SYMBOL_CACHE_SIZE = 0 #--------------------------------------------------------------------------- # Build related configuration options #--------------------------------------------------------------------------- # If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in # documentation are documented, even if no documentation was available. # Private class members and static file members will be hidden unless # the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES EXTRACT_ALL = YES # If the EXTRACT_PRIVATE tag is set to YES all private members of a class # will be included in the documentation. EXTRACT_PRIVATE = NO # If the EXTRACT_STATIC tag is set to YES all static members of a file # will be included in the documentation. EXTRACT_STATIC = NO # If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) # defined locally in source files will be included in the documentation. # If set to NO only classes defined in header files are included. EXTRACT_LOCAL_CLASSES = NO # This flag is only useful for Objective-C code. When set to YES local # methods, which are defined in the implementation section but not in # the interface are included in the documentation. # If set to NO (the default) only methods in the interface are included. EXTRACT_LOCAL_METHODS = NO # If this flag is set to YES, the members of anonymous namespaces will be # extracted and appear in the documentation as a namespace called # 'anonymous_namespace{file}', where file will be replaced with the base # name of the file that contains the anonymous namespace. By default # anonymous namespaces are hidden. EXTRACT_ANON_NSPACES = NO # If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all # undocumented members of documented classes, files or namespaces. # If set to NO (the default) these members will be included in the # various overviews, but no documentation section is generated. # This option has no effect if EXTRACT_ALL is enabled. HIDE_UNDOC_MEMBERS = NO # If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all # undocumented classes that are normally visible in the class hierarchy. # If set to NO (the default) these classes will be included in the various # overviews. This option has no effect if EXTRACT_ALL is enabled. HIDE_UNDOC_CLASSES = NO # If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all # friend (class|struct|union) declarations. # If set to NO (the default) these declarations will be included in the # documentation. HIDE_FRIEND_COMPOUNDS = NO # If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any # documentation blocks found inside the body of a function. # If set to NO (the default) these blocks will be appended to the # function's detailed documentation block. HIDE_IN_BODY_DOCS = NO # The INTERNAL_DOCS tag determines if documentation # that is typed after a \internal command is included. If the tag is set # to NO (the default) then the documentation will be excluded. # Set it to YES to include the internal documentation. INTERNAL_DOCS = NO # If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate # file names in lower-case letters. If set to YES upper-case letters are also # allowed. This is useful if you have classes or files whose names only differ # in case and if your file system supports case sensitive file names. Windows # and Mac users are advised to set this option to NO. CASE_SENSE_NAMES = YES # If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen # will show members with their full class and namespace scopes in the # documentation. If set to YES the scope will be hidden. HIDE_SCOPE_NAMES = NO # If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen # will put a list of the files that are included by a file in the documentation # of that file. SHOW_INCLUDE_FILES = YES # If the FORCE_LOCAL_INCLUDES tag is set to YES then Doxygen # will list include files with double quotes in the documentation # rather than with sharp brackets. FORCE_LOCAL_INCLUDES = NO # If the INLINE_INFO tag is set to YES (the default) then a tag [inline] # is inserted in the documentation for inline members. INLINE_INFO = YES # If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen # will sort the (detailed) documentation of file and class members # alphabetically by member name. If set to NO the members will appear in # declaration order. SORT_MEMBER_DOCS = YES # If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the # brief documentation of file, namespace and class members alphabetically # by member name. If set to NO (the default) the members will appear in # declaration order. SORT_BRIEF_DOCS = NO # If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen # will sort the (brief and detailed) documentation of class members so that # constructors and destructors are listed first. If set to NO (the default) # the constructors will appear in the respective orders defined by # SORT_MEMBER_DOCS and SORT_BRIEF_DOCS. # This tag will be ignored for brief docs if SORT_BRIEF_DOCS is set to NO # and ignored for detailed docs if SORT_MEMBER_DOCS is set to NO. SORT_MEMBERS_CTORS_1ST = YES # If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the # hierarchy of group names into alphabetical order. If set to NO (the default) # the group names will appear in their defined order. SORT_GROUP_NAMES = NO # If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be # sorted by fully-qualified names, including namespaces. If set to # NO (the default), the class list will be sorted only by class name, # not including the namespace part. # Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. # Note: This option applies only to the class list, not to the # alphabetical list. SORT_BY_SCOPE_NAME = NO # If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to # do proper type resolution of all parameters of a function it will reject a # match between the prototype and the implementation of a member function even # if there is only one candidate or it is obvious which candidate to choose # by doing a simple string match. By disabling STRICT_PROTO_MATCHING doxygen # will still accept a match between prototype and implementation in such cases. STRICT_PROTO_MATCHING = NO # The GENERATE_TODOLIST tag can be used to enable (YES) or # disable (NO) the todo list. This list is created by putting \todo # commands in the documentation. GENERATE_TODOLIST = YES # The GENERATE_TESTLIST tag can be used to enable (YES) or # disable (NO) the test list. This list is created by putting \test # commands in the documentation. GENERATE_TESTLIST = YES # The GENERATE_BUGLIST tag can be used to enable (YES) or # disable (NO) the bug list. This list is created by putting \bug # commands in the documentation. GENERATE_BUGLIST = YES # The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or # disable (NO) the deprecated list. This list is created by putting # \deprecated commands in the documentation. GENERATE_DEPRECATEDLIST= YES # The ENABLED_SECTIONS tag can be used to enable conditional # documentation sections, marked by \if sectionname ... \endif. ENABLED_SECTIONS = # The MAX_INITIALIZER_LINES tag determines the maximum number of lines # the initial value of a variable or macro consists of for it to appear in # the documentation. If the initializer consists of more lines than specified # here it will be hidden. Use a value of 0 to hide initializers completely. # The appearance of the initializer of individual variables and macros in the # documentation can be controlled using \showinitializer or \hideinitializer # command in the documentation regardless of this setting. MAX_INITIALIZER_LINES = 30 # Set the SHOW_USED_FILES tag to NO to disable the list of files generated # at the bottom of the documentation of classes and structs. If set to YES the # list will mention the files that were used to generate the documentation. SHOW_USED_FILES = YES # If the sources in your project are distributed over multiple directories # then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy # in the documentation. The default is NO. SHOW_DIRECTORIES = NO # Set the SHOW_FILES tag to NO to disable the generation of the Files page. # This will remove the Files entry from the Quick Index and from the # Folder Tree View (if specified). The default is YES. SHOW_FILES = YES # Set the SHOW_NAMESPACES tag to NO to disable the generation of the # Namespaces page. # This will remove the Namespaces entry from the Quick Index # and from the Folder Tree View (if specified). The default is YES. SHOW_NAMESPACES = YES # The FILE_VERSION_FILTER tag can be used to specify a program or script that # doxygen should invoke to get the current version for each file (typically from # the version control system). Doxygen will invoke the program by executing (via # popen()) the command , where is the value of # the FILE_VERSION_FILTER tag, and is the name of an input file # provided by doxygen. Whatever the program writes to standard output # is used as the file version. See the manual for examples. FILE_VERSION_FILTER = # The LAYOUT_FILE tag can be used to specify a layout file which will be parsed # by doxygen. The layout file controls the global structure of the generated # output files in an output format independent way. The create the layout file # that represents doxygen's defaults, run doxygen with the -l option. # You can optionally specify a file name after the option, if omitted # DoxygenLayout.xml will be used as the name of the layout file. LAYOUT_FILE = #--------------------------------------------------------------------------- # configuration options related to warning and progress messages #--------------------------------------------------------------------------- # The QUIET tag can be used to turn on/off the messages that are generated # by doxygen. Possible values are YES and NO. If left blank NO is used. QUIET = NO # The WARNINGS tag can be used to turn on/off the warning messages that are # generated by doxygen. Possible values are YES and NO. If left blank # NO is used. WARNINGS = YES # If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings # for undocumented members. If EXTRACT_ALL is set to YES then this flag will # automatically be disabled. WARN_IF_UNDOCUMENTED = YES # If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for # potential errors in the documentation, such as not documenting some # parameters in a documented function, or documenting parameters that # don't exist or using markup commands wrongly. WARN_IF_DOC_ERROR = YES # The WARN_NO_PARAMDOC option can be enabled to get warnings for # functions that are documented, but have no documentation for their parameters # or return value. If set to NO (the default) doxygen will only warn about # wrong or incomplete parameter documentation, but not about the absence of # documentation. WARN_NO_PARAMDOC = NO # The WARN_FORMAT tag determines the format of the warning messages that # doxygen can produce. The string should contain the $file, $line, and $text # tags, which will be replaced by the file and line number from which the # warning originated and the warning text. Optionally the format may contain # $version, which will be replaced by the version of the file (if it could # be obtained via FILE_VERSION_FILTER) WARN_FORMAT = "$file:$line: $text" # The WARN_LOGFILE tag can be used to specify a file to which warning # and error messages should be written. If left blank the output is written # to stderr. WARN_LOGFILE = #--------------------------------------------------------------------------- # configuration options related to the input files #--------------------------------------------------------------------------- # The INPUT tag can be used to specify the files and/or directories that contain # documented source files. You may enter file names like "myfile.cpp" or # directories like "/usr/src/myproject". Separate the files or directories # with spaces. INPUT = include/crm include/crm_config.h include/doxygen.h # This tag can be used to specify the character encoding of the source files # that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is # also the default input encoding. Doxygen uses libiconv (or the iconv built # into libc) for the transcoding. See http://www.gnu.org/software/libiconv for # the list of possible encodings. INPUT_ENCODING = UTF-8 # If the value of the INPUT tag contains directories, you can use the # FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp # and *.h) to filter out the source-files in the directories. If left # blank the following patterns are tested: # *.c *.cc *.cxx *.cpp *.c++ *.d *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh # *.hxx *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.dox *.py # *.f90 *.f *.for *.vhd *.vhdl FILE_PATTERNS = # The RECURSIVE tag can be used to turn specify whether or not subdirectories # should be searched for input files as well. Possible values are YES and NO. # If left blank NO is used. RECURSIVE = YES # The EXCLUDE tag can be used to specify files and/or directories that should # excluded from the INPUT source files. This way you can easily exclude a # subdirectory from a directory tree whose root is specified with the INPUT tag. EXCLUDE = # The EXCLUDE_SYMLINKS tag can be used select whether or not files or # directories that are symbolic links (a Unix file system feature) are excluded # from the input. EXCLUDE_SYMLINKS = NO # If the value of the INPUT tag contains directories, you can use the # EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude # certain files from those directories. Note that the wildcards are matched # against the file with absolute path, so to exclude all test directories # for example use the pattern */test/* EXCLUDE_PATTERNS = # The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names # (namespaces, classes, functions, etc.) that should be excluded from the # output. The symbol name can be a fully qualified name, a word, or if the # wildcard * is used, a substring. Examples: ANamespace, AClass, # AClass::ANamespace, ANamespace::*Test EXCLUDE_SYMBOLS = # The EXAMPLE_PATH tag can be used to specify one or more files or # directories that contain example code fragments that are included (see # the \include command). EXAMPLE_PATH = . # If the value of the EXAMPLE_PATH tag contains directories, you can use the # EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp # and *.h) to filter out the source-files in the directories. If left # blank all files are included. EXAMPLE_PATTERNS = # If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be # searched for input files to be used with the \include or \dontinclude # commands irrespective of the value of the RECURSIVE tag. # Possible values are YES and NO. If left blank NO is used. EXAMPLE_RECURSIVE = YES # The IMAGE_PATH tag can be used to specify one or more files or # directories that contain image that are included in the documentation (see # the \image command). IMAGE_PATH = # The INPUT_FILTER tag can be used to specify a program that doxygen should # invoke to filter for each input file. Doxygen will invoke the filter program # by executing (via popen()) the command , where # is the value of the INPUT_FILTER tag, and is the name of an # input file. Doxygen will then use the output that the filter program writes # to standard output. # If FILTER_PATTERNS is specified, this tag will be # ignored. INPUT_FILTER = # The FILTER_PATTERNS tag can be used to specify filters on a per file pattern # basis. # Doxygen will compare the file name with each pattern and apply the # filter if there is a match. # The filters are a list of the form: # pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further # info on how filters are used. If FILTER_PATTERNS is empty or if # non of the patterns match the file name, INPUT_FILTER is applied. FILTER_PATTERNS = # If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using # INPUT_FILTER) will be used to filter the input files when producing source # files to browse (i.e. when SOURCE_BROWSER is set to YES). FILTER_SOURCE_FILES = NO # The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file # pattern. A pattern will override the setting for FILTER_PATTERN (if any) # and it is also possible to disable source filtering for a specific pattern # using *.ext= (so without naming a filter). This option only has effect when # FILTER_SOURCE_FILES is enabled. FILTER_SOURCE_PATTERNS = #--------------------------------------------------------------------------- # configuration options related to source browsing #--------------------------------------------------------------------------- # If the SOURCE_BROWSER tag is set to YES then a list of source files will # be generated. Documented entities will be cross-referenced with these sources. # Note: To get rid of all source code in the generated output, make sure also # VERBATIM_HEADERS is set to NO. SOURCE_BROWSER = YES # Setting the INLINE_SOURCES tag to YES will include the body # of functions and classes directly in the documentation. INLINE_SOURCES = NO # Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct # doxygen to hide any special comment blocks from generated source code # fragments. Normal C and C++ comments will always remain visible. STRIP_CODE_COMMENTS = YES # If the REFERENCED_BY_RELATION tag is set to YES # then for each documented function all documented # functions referencing it will be listed. REFERENCED_BY_RELATION = NO # If the REFERENCES_RELATION tag is set to YES # then for each documented function all documented entities # called/used by that function will be listed. REFERENCES_RELATION = NO # If the REFERENCES_LINK_SOURCE tag is set to YES (the default) # and SOURCE_BROWSER tag is set to YES, then the hyperlinks from # functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will # link to the source code. # Otherwise they will link to the documentation. REFERENCES_LINK_SOURCE = YES # If the USE_HTAGS tag is set to YES then the references to source code # will point to the HTML generated by the htags(1) tool instead of doxygen # built-in source browser. The htags tool is part of GNU's global source # tagging system (see http://www.gnu.org/software/global/global.html). You # will need version 4.8.6 or higher. USE_HTAGS = NO # If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen # will generate a verbatim copy of the header file for each class for # which an include is specified. Set to NO to disable this. VERBATIM_HEADERS = YES #--------------------------------------------------------------------------- # configuration options related to the alphabetical class index #--------------------------------------------------------------------------- # If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index # of all compounds will be generated. Enable this if the project # contains a lot of classes, structs, unions or interfaces. ALPHABETICAL_INDEX = YES # If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then # the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns # in which this list will be split (can be a number in the range [1..20]) COLS_IN_ALPHA_INDEX = 5 # In case all classes in a project start with a common prefix, all # classes will be put under the same header in the alphabetical index. # The IGNORE_PREFIX tag can be used to specify one or more prefixes that # should be ignored while generating the index headers. IGNORE_PREFIX = #--------------------------------------------------------------------------- # configuration options related to the HTML output #--------------------------------------------------------------------------- # If the GENERATE_HTML tag is set to YES (the default) Doxygen will # generate HTML output. GENERATE_HTML = YES # The HTML_OUTPUT tag is used to specify where the HTML docs will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `html' will be used as the default path. HTML_OUTPUT = html # The HTML_FILE_EXTENSION tag can be used to specify the file extension for # each generated HTML page (for example: .htm,.php,.asp). If it is left blank # doxygen will generate files with .html extension. HTML_FILE_EXTENSION = .html # The HTML_HEADER tag can be used to specify a personal HTML header for # each generated HTML page. If it is left blank doxygen will generate a # standard header. Note that when using a custom header you are responsible # for the proper inclusion of any scripts and style sheets that doxygen # needs, which is dependent on the configuration options used. # It is adviced to generate a default header using "doxygen -w html # header.html footer.html stylesheet.css YourConfigFile" and then modify # that header. Note that the header is subject to change so you typically # have to redo this when upgrading to a newer version of doxygen or when changing the value of configuration settings such as GENERATE_TREEVIEW! HTML_HEADER = # The HTML_FOOTER tag can be used to specify a personal HTML footer for # each generated HTML page. If it is left blank doxygen will generate a # standard footer. HTML_FOOTER = # If the HTML_TIMESTAMP tag is set to YES then the generated HTML documentation will contain the timesstamp. HTML_TIMESTAMP = NO # The HTML_STYLESHEET tag can be used to specify a user-defined cascading # style sheet that is used by each HTML page. It can be used to # fine-tune the look of the HTML output. If the tag is left blank doxygen # will generate a default style sheet. Note that doxygen will try to copy # the style sheet file to the HTML output directory, so don't put your own # stylesheet in the HTML output directory as well, or it will be erased! HTML_STYLESHEET = # The HTML_EXTRA_FILES tag can be used to specify one or more extra images or # other source files which should be copied to the HTML output directory. Note # that these files will be copied to the base HTML output directory. Use the # $relpath$ marker in the HTML_HEADER and/or HTML_FOOTER files to load these # files. In the HTML_STYLESHEET file, use the file name only. Also note that # the files will be copied as-is; there are no commands or markers available. HTML_EXTRA_FILES = # The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. # Doxygen will adjust the colors in the stylesheet and background images # according to this color. Hue is specified as an angle on a colorwheel, # see http://en.wikipedia.org/wiki/Hue for more information. # For instance the value 0 represents red, 60 is yellow, 120 is green, # 180 is cyan, 240 is blue, 300 purple, and 360 is red again. # The allowed range is 0 to 359. HTML_COLORSTYLE_HUE = 220 # The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of # the colors in the HTML output. For a value of 0 the output will use # grayscales only. A value of 255 will produce the most vivid colors. HTML_COLORSTYLE_SAT = 100 # The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to # the luminance component of the colors in the HTML output. Values below # 100 gradually make the output lighter, whereas values above 100 make # the output darker. The value divided by 100 is the actual gamma applied, # so 80 represents a gamma of 0.8, The value 220 represents a gamma of 2.2, # and 100 does not change the gamma. HTML_COLORSTYLE_GAMMA = 80 # If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML # page will contain the date and time when the page was generated. Setting # this to NO can help when comparing the output of multiple runs. HTML_TIMESTAMP = YES # If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, # files or namespaces will be aligned in HTML using tables. If set to # NO a bullet list will be used. HTML_ALIGN_MEMBERS = YES # If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML # documentation will contain sections that can be hidden and shown after the # page has loaded. For this to work a browser that supports # JavaScript and DHTML is required (for instance Mozilla 1.0+, Firefox # Netscape 6.0+, Internet explorer 5.0+, Konqueror, or Safari). HTML_DYNAMIC_SECTIONS = NO # If the GENERATE_DOCSET tag is set to YES, additional index files # will be generated that can be used as input for Apple's Xcode 3 # integrated development environment, introduced with OSX 10.5 (Leopard). # To create a documentation set, doxygen will generate a Makefile in the # HTML output directory. Running make will produce the docset in that # directory and running "make install" will install the docset in # ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find # it at startup. # See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html # for more information. GENERATE_DOCSET = NO # When GENERATE_DOCSET tag is set to YES, this tag determines the name of the # feed. A documentation feed provides an umbrella under which multiple # documentation sets from a single provider (such as a company or product suite) # can be grouped. DOCSET_FEEDNAME = "Doxygen generated docs" # When GENERATE_DOCSET tag is set to YES, this tag specifies a string that # should uniquely identify the documentation set bundle. This should be a # reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen # will append .docset to the name. DOCSET_BUNDLE_ID = org.doxygen.Pacemaker # When GENERATE_PUBLISHER_ID tag specifies a string that should uniquely identify # the documentation publisher. This should be a reverse domain-name style # string, e.g. com.mycompany.MyDocSet.documentation. DOCSET_PUBLISHER_ID = org.doxygen.ClusterLabs # The GENERATE_PUBLISHER_NAME tag identifies the documentation publisher. DOCSET_PUBLISHER_NAME = ClusterLabs # If the GENERATE_HTMLHELP tag is set to YES, additional index files # will be generated that can be used as input for tools like the # Microsoft HTML help workshop to generate a compiled HTML help file (.chm) # of the generated HTML documentation. GENERATE_HTMLHELP = NO # If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can # be used to specify the file name of the resulting .chm file. You # can add a path in front of the file if the result should not be # written to the html output directory. CHM_FILE = # If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can # be used to specify the location (absolute path including file name) of # the HTML help compiler (hhc.exe). If non-empty doxygen will try to run # the HTML help compiler on the generated index.hhp. HHC_LOCATION = # If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag # controls if a separate .chi index file is generated (YES) or that # it should be included in the master .chm file (NO). GENERATE_CHI = NO # If the GENERATE_HTMLHELP tag is set to YES, the CHM_INDEX_ENCODING # is used to encode HtmlHelp index (hhk), content (hhc) and project file # content. CHM_INDEX_ENCODING = # If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag # controls whether a binary table of contents is generated (YES) or a # normal table of contents (NO) in the .chm file. BINARY_TOC = NO # The TOC_EXPAND flag can be set to YES to add extra items for group members # to the contents of the HTML help documentation and to the tree view. TOC_EXPAND = NO # If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and # QHP_VIRTUAL_FOLDER are set, an additional index file will be generated # that can be used as input for Qt's qhelpgenerator to generate a # Qt Compressed Help (.qch) of the generated HTML documentation. GENERATE_QHP = NO # If the QHG_LOCATION tag is specified, the QCH_FILE tag can # be used to specify the file name of the resulting .qch file. # The path specified is relative to the HTML output folder. QCH_FILE = # The QHP_NAMESPACE tag specifies the namespace to use when generating # Qt Help Project output. For more information please see # http://doc.trolltech.com/qthelpproject.html#namespace QHP_NAMESPACE = org.doxygen.Project # The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating # Qt Help Project output. For more information please see # http://doc.trolltech.com/qthelpproject.html#virtual-folders QHP_VIRTUAL_FOLDER = doc # If QHP_CUST_FILTER_NAME is set, it specifies the name of a custom filter to # add. For more information please see # http://doc.trolltech.com/qthelpproject.html#custom-filters QHP_CUST_FILTER_NAME = # The QHP_CUST_FILT_ATTRS tag specifies the list of the attributes of the # custom filter to add. For more information please see # # Qt Help Project / Custom Filters. QHP_CUST_FILTER_ATTRS = # The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this # project's # filter section matches. # # Qt Help Project / Filter Attributes. QHP_SECT_FILTER_ATTRS = # If the GENERATE_QHP tag is set to YES, the QHG_LOCATION tag can # be used to specify the location of Qt's qhelpgenerator. # If non-empty doxygen will try to run qhelpgenerator on the generated # .qhp file. QHG_LOCATION = # If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files # will be generated, which together with the HTML files, form an Eclipse help # plugin. To install this plugin and make it available under the help contents # menu in Eclipse, the contents of the directory containing the HTML and XML # files needs to be copied into the plugins directory of eclipse. The name of # the directory within the plugins directory should be the same as # the ECLIPSE_DOC_ID value. After copying Eclipse needs to be restarted before # the help appears. GENERATE_ECLIPSEHELP = NO # A unique identifier for the eclipse help plugin. When installing the plugin # the directory name containing the HTML and XML files should also have # this name. ECLIPSE_DOC_ID = org.doxygen.Project # The DISABLE_INDEX tag can be used to turn on/off the condensed index at # top of each HTML page. The value NO (the default) enables the index and # the value YES disables it. DISABLE_INDEX = NO # The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values # (range [0,1..20]) that doxygen will group on one line in the generated HTML # documentation. Note that a value of 0 will completely suppress the enum # values from appearing in the overview section. ENUM_VALUES_PER_LINE = 4 # The GENERATE_TREEVIEW tag is used to specify whether a tree-like index # structure should be generated to display hierarchical information. # If the tag value is set to YES, a side panel will be generated # containing a tree-like index structure (just like the one that # is generated for HTML Help). For this to work a browser that supports # JavaScript, DHTML, CSS and frames is required (i.e. any modern browser). # Windows users are probably better off using the HTML help feature. GENERATE_TREEVIEW = NO # By enabling USE_INLINE_TREES, doxygen will generate the Groups, Directories, # and Class Hierarchy pages using a tree view instead of an ordered list. USE_INLINE_TREES = NO # If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be # used to set the initial width (in pixels) of the frame in which the tree # is shown. TREEVIEW_WIDTH = 250 # When the EXT_LINKS_IN_WINDOW option is set to YES doxygen will open # links to external symbols imported via tag files in a separate window. EXT_LINKS_IN_WINDOW = NO # Use this tag to change the font size of Latex formulas included # as images in the HTML documentation. The default is 10. Note that # when you change the font size after a successful doxygen run you need # to manually remove any form_*.png images from the HTML output directory # to force them to be regenerated. FORMULA_FONTSIZE = 10 # Use the FORMULA_TRANPARENT tag to determine whether or not the images # generated for formulas are transparent PNGs. Transparent PNGs are # not supported properly for IE 6.0, but are supported on all modern browsers. # Note that when changing this option you need to delete any form_*.png files # in the HTML output before the changes have effect. FORMULA_TRANSPARENT = YES # Enable the USE_MATHJAX option to render LaTeX formulas using MathJax # (see http://www.mathjax.org) which uses client side Javascript for the # rendering instead of using prerendered bitmaps. Use this if you do not # have LaTeX installed or if you want to formulas look prettier in the HTML # output. When enabled you also need to install MathJax separately and # configure the path to it using the MATHJAX_RELPATH option. USE_MATHJAX = NO # When MathJax is enabled you need to specify the location relative to the # HTML output directory using the MATHJAX_RELPATH option. The destination # directory should contain the MathJax.js script. For instance, if the mathjax # directory is located at the same level as the HTML output directory, then # MATHJAX_RELPATH should be ../mathjax. The default value points to the # mathjax.org site, so you can quickly see the result without installing # MathJax, but it is strongly recommended to install a local copy of MathJax # before deployment. MATHJAX_RELPATH = http://www.mathjax.org/mathjax # When the SEARCHENGINE tag is enabled doxygen will generate a search box # for the HTML output. The underlying search engine uses javascript # and DHTML and should work on any modern browser. Note that when using # HTML help (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets # (GENERATE_DOCSET) there is already a search function so this one should # typically be disabled. For large projects the javascript based search engine # can be slow, then enabling SERVER_BASED_SEARCH may provide a better solution. SEARCHENGINE = YES # When the SERVER_BASED_SEARCH tag is enabled the search engine will be # implemented using a PHP enabled web server instead of at the web client # using Javascript. Doxygen will generate the search PHP script and index # file to put on the web server. The advantage of the server # based approach is that it scales better to large projects and allows # full text search. The disadvantages are that it is more difficult to setup # and does not have live searching capabilities. SERVER_BASED_SEARCH = NO #--------------------------------------------------------------------------- # configuration options related to the LaTeX output #--------------------------------------------------------------------------- # If the GENERATE_LATEX tag is set to YES (the default) Doxygen will # generate Latex output. GENERATE_LATEX = NO # The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `latex' will be used as the default path. LATEX_OUTPUT = latex # The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be # invoked. If left blank `latex' will be used as the default command name. # Note that when enabling USE_PDFLATEX this option is only used for # generating bitmaps for formulas in the HTML output, but not in the # Makefile that is written to the output directory. LATEX_CMD_NAME = latex # The MAKEINDEX_CMD_NAME tag can be used to specify the command name to # generate index for LaTeX. If left blank `makeindex' will be used as the # default command name. MAKEINDEX_CMD_NAME = makeindex # If the COMPACT_LATEX tag is set to YES Doxygen generates more compact # LaTeX documents. This may be useful for small projects and may help to # save some trees in general. COMPACT_LATEX = NO # The PAPER_TYPE tag can be used to set the paper type that is used # by the printer. Possible values are: a4, letter, legal and # executive. If left blank a4wide will be used. PAPER_TYPE = a4 # The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX # packages that should be included in the LaTeX output. EXTRA_PACKAGES = # The LATEX_HEADER tag can be used to specify a personal LaTeX header for # the generated latex document. The header should contain everything until # the first chapter. If it is left blank doxygen will generate a # standard header. Notice: only use this tag if you know what you are doing! LATEX_HEADER = # The LATEX_FOOTER tag can be used to specify a personal LaTeX footer for # the generated latex document. The footer should contain everything after # the last chapter. If it is left blank doxygen will generate a # standard footer. Notice: only use this tag if you know what you are doing! LATEX_FOOTER = # If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated # is prepared for conversion to pdf (using ps2pdf). The pdf file will # contain links (just like the HTML output) instead of page references # This makes the output suitable for online browsing using a pdf viewer. PDF_HYPERLINKS = YES # If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of # plain latex in the generated Makefile. Set this option to YES to get a # higher quality PDF documentation. USE_PDFLATEX = YES # If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. # command to the generated LaTeX files. This will instruct LaTeX to keep # running if errors occur, instead of asking the user for help. # This option is also used when generating formulas in HTML. LATEX_BATCHMODE = NO # If LATEX_HIDE_INDICES is set to YES then doxygen will not # include the index chapters (such as File Index, Compound Index, etc.) # in the output. LATEX_HIDE_INDICES = NO # If LATEX_SOURCE_CODE is set to YES then doxygen will include # source code with syntax highlighting in the LaTeX output. # Note that which sources are shown also depends on other settings # such as SOURCE_BROWSER. LATEX_SOURCE_CODE = NO #--------------------------------------------------------------------------- # configuration options related to the RTF output #--------------------------------------------------------------------------- # If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output # The RTF output is optimized for Word 97 and may not look very pretty with # other RTF readers or editors. GENERATE_RTF = NO # The RTF_OUTPUT tag is used to specify where the RTF docs will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `rtf' will be used as the default path. RTF_OUTPUT = rtf # If the COMPACT_RTF tag is set to YES Doxygen generates more compact # RTF documents. This may be useful for small projects and may help to # save some trees in general. COMPACT_RTF = NO # If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated # will contain hyperlink fields. The RTF file will # contain links (just like the HTML output) instead of page references. # This makes the output suitable for online browsing using WORD or other # programs which support those fields. # Note: wordpad (write) and others do not support links. RTF_HYPERLINKS = NO # Load stylesheet definitions from file. Syntax is similar to doxygen's # config file, i.e. a series of assignments. You only have to provide # replacements, missing definitions are set to their default value. RTF_STYLESHEET_FILE = # Set optional variables used in the generation of an rtf document. # Syntax is similar to doxygen's config file. RTF_EXTENSIONS_FILE = #--------------------------------------------------------------------------- # configuration options related to the man page output #--------------------------------------------------------------------------- # If the GENERATE_MAN tag is set to YES (the default) Doxygen will # generate man pages GENERATE_MAN = NO # The MAN_OUTPUT tag is used to specify where the man pages will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `man' will be used as the default path. MAN_OUTPUT = man # The MAN_EXTENSION tag determines the extension that is added to # the generated man pages (default is the subroutine's section .3) MAN_EXTENSION = .3 # If the MAN_LINKS tag is set to YES and Doxygen generates man output, # then it will generate one additional man file for each entity # documented in the real man page(s). These additional files # only source the real man page, but without them the man command # would be unable to find the correct page. The default is NO. MAN_LINKS = NO #--------------------------------------------------------------------------- # configuration options related to the XML output #--------------------------------------------------------------------------- # If the GENERATE_XML tag is set to YES Doxygen will # generate an XML file that captures the structure of # the code including all documentation. GENERATE_XML = NO # The XML_OUTPUT tag is used to specify where the XML pages will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `xml' will be used as the default path. XML_OUTPUT = xml # The XML_SCHEMA tag can be used to specify an XML schema, # which can be used by a validating XML parser to check the # syntax of the XML files. XML_SCHEMA = # The XML_DTD tag can be used to specify an XML DTD, # which can be used by a validating XML parser to check the # syntax of the XML files. XML_DTD = # If the XML_PROGRAMLISTING tag is set to YES Doxygen will # dump the program listings (including syntax highlighting # and cross-referencing information) to the XML output. Note that # enabling this will significantly increase the size of the XML output. XML_PROGRAMLISTING = YES #--------------------------------------------------------------------------- # configuration options for the AutoGen Definitions output #--------------------------------------------------------------------------- # If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will # generate an AutoGen Definitions (see autogen.sf.net) file # that captures the structure of the code including all # documentation. Note that this feature is still experimental # and incomplete at the moment. GENERATE_AUTOGEN_DEF = NO #--------------------------------------------------------------------------- # configuration options related to the Perl module output #--------------------------------------------------------------------------- # If the GENERATE_PERLMOD tag is set to YES Doxygen will # generate a Perl module file that captures the structure of # the code including all documentation. Note that this # feature is still experimental and incomplete at the # moment. GENERATE_PERLMOD = NO # If the PERLMOD_LATEX tag is set to YES Doxygen will generate # the necessary Makefile rules, Perl scripts and LaTeX code to be able # to generate PDF and DVI output from the Perl module output. PERLMOD_LATEX = NO # If the PERLMOD_PRETTY tag is set to YES the Perl module output will be # nicely formatted so it can be parsed by a human reader. # This is useful # if you want to understand what is going on. # On the other hand, if this # tag is set to NO the size of the Perl module output will be much smaller # and Perl will parse it just the same. PERLMOD_PRETTY = YES # The names of the make variables in the generated doxyrules.make file # are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. # This is useful so different doxyrules.make files included by the same # Makefile don't overwrite each other's variables. PERLMOD_MAKEVAR_PREFIX = #--------------------------------------------------------------------------- # Configuration options related to the preprocessor #--------------------------------------------------------------------------- # If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will # evaluate all C-preprocessor directives found in the sources and include # files. ENABLE_PREPROCESSING = YES # If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro # names in the source code. If set to NO (the default) only conditional # compilation will be performed. Macro expansion can be done in a controlled # way by setting EXPAND_ONLY_PREDEF to YES. MACRO_EXPANSION = NO # If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES # then the macro expansion is limited to the macros specified with the # PREDEFINED and EXPAND_AS_DEFINED tags. EXPAND_ONLY_PREDEF = NO # If the SEARCH_INCLUDES tag is set to YES (the default) the includes files # pointed to by INCLUDE_PATH will be searched when a #include is found. SEARCH_INCLUDES = YES # The INCLUDE_PATH tag can be used to specify one or more directories that # contain include files that are not input files but should be processed by # the preprocessor. INCLUDE_PATH = # You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard # patterns (like *.h and *.hpp) to filter out the header-files in the # directories. If left blank, the patterns specified with FILE_PATTERNS will # be used. INCLUDE_FILE_PATTERNS = # The PREDEFINED tag can be used to specify one or more macro names that # are defined before the preprocessor is started (similar to the -D option of # gcc). The argument of the tag is a list of macros of the form: name # or name=definition (no spaces). If the definition and the = are # omitted =1 is assumed. To prevent a macro definition from being # undefined via #undef or recursively expanded use the := operator # instead of the = operator. PREDEFINED = # If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then # this tag can be used to specify a list of macro names that should be expanded. # The macro definition that is found in the sources will be used. # Use the PREDEFINED tag if you want to use a different macro definition that # overrules the definition found in the source code. EXPAND_AS_DEFINED = # If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then # doxygen's preprocessor will remove all references to function-like macros # that are alone on a line, have an all uppercase name, and do not end with a # semicolon, because these will confuse the parser if not removed. SKIP_FUNCTION_MACROS = YES #--------------------------------------------------------------------------- # Configuration::additions related to external references #--------------------------------------------------------------------------- # The TAGFILES option can be used to specify one or more tagfiles. # Optionally an initial location of the external documentation # can be added for each tagfile. The format of a tag file without # this location is as follows: # # TAGFILES = file1 file2 ... # Adding location for the tag files is done as follows: # # TAGFILES = file1=loc1 "file2 = loc2" ... # where "loc1" and "loc2" can be relative or absolute paths or # URLs. If a location is present for each tag, the installdox tool # does not have to be run to correct the links. # Note that each tag file must have a unique name # (where the name does NOT include the path) # If a tag file is not located in the directory in which doxygen # is run, you must also specify the path to the tagfile here. TAGFILES = # When a file name is specified after GENERATE_TAGFILE, doxygen will create # a tag file that is based on the input files it reads. GENERATE_TAGFILE = # If the ALLEXTERNALS tag is set to YES all external classes will be listed # in the class index. If set to NO only the inherited external classes # will be listed. ALLEXTERNALS = NO # If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed # in the modules index. If set to NO, only the current project's groups will # be listed. EXTERNAL_GROUPS = YES # The PERL_PATH should be the absolute path and name of the perl script # interpreter (i.e. the result of `which perl'). PERL_PATH = /usr/bin/perl #--------------------------------------------------------------------------- # Configuration options related to the dot tool #--------------------------------------------------------------------------- # If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will # generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base # or super classes. Setting the tag to NO turns the diagrams off. Note that # this option also works with HAVE_DOT disabled, but it is recommended to # install and use dot, since it yields more powerful graphs. CLASS_DIAGRAMS = YES # You can define message sequence charts within doxygen comments using the \msc # command. Doxygen will then run the mscgen tool (see # http://www.mcternan.me.uk/mscgen/) to produce the chart and insert it in the # documentation. The MSCGEN_PATH tag allows you to specify the directory where # the mscgen tool resides. If left empty the tool is assumed to be found in the # default search path. MSCGEN_PATH = # If set to YES, the inheritance and collaboration graphs will hide # inheritance and usage relations if the target is undocumented # or is not a class. HIDE_UNDOC_RELATIONS = YES # If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is # available from the path. This tool is part of Graphviz, a graph visualization # toolkit from AT&T and Lucent Bell Labs. The other options in this section # have no effect if this option is set to NO (the default) HAVE_DOT = YES # The DOT_NUM_THREADS specifies the number of dot invocations doxygen is # allowed to run in parallel. When set to 0 (the default) doxygen will # base this on the number of processors available in the system. You can set it # explicitly to a value larger than 0 to get control over the balance # between CPU load and processing speed. DOT_NUM_THREADS = 0 # By default doxygen will write a font called Helvetica to the output # directory and reference it in all dot files that doxygen generates. # When you want a differently looking font you can specify the font name # using DOT_FONTNAME. You need to make sure dot is able to find the font, # which can be done by putting it in a standard location or by setting the # DOTFONTPATH environment variable or by setting DOT_FONTPATH to the directory # containing the font. DOT_FONTNAME = Helvetica # The DOT_FONTSIZE tag can be used to set the size of the font of dot graphs. # The default size is 10pt. DOT_FONTSIZE = 10 # By default doxygen will tell dot to use the output directory to look for the # FreeSans.ttf font (which doxygen will put there itself). If you specify a # different font using DOT_FONTNAME you can set the path where dot # can find it using this tag. DOT_FONTPATH = # If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen # will generate a graph for each documented class showing the direct and # indirect inheritance relations. Setting this tag to YES will force the # the CLASS_DIAGRAMS tag to NO. CLASS_GRAPH = YES # If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen # will generate a graph for each documented class showing the direct and # indirect implementation dependencies (inheritance, containment, and # class references variables) of the class with other documented classes. COLLABORATION_GRAPH = YES # If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen # will generate a graph for groups, showing the direct groups dependencies GROUP_GRAPHS = YES # If the UML_LOOK tag is set to YES doxygen will generate inheritance and # collaboration diagrams in a style similar to the OMG's Unified Modeling # Language. UML_LOOK = NO # If set to YES, the inheritance and collaboration graphs will show the # relations between templates and their instances. TEMPLATE_RELATIONS = NO # If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT # tags are set to YES then doxygen will generate a graph for each documented # file showing the direct and indirect include dependencies of the file with # other documented files. INCLUDE_GRAPH = YES # If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and # HAVE_DOT tags are set to YES then doxygen will generate a graph for each # documented header file showing the documented files that directly or # indirectly include this file. INCLUDED_BY_GRAPH = YES # If the CALL_GRAPH and HAVE_DOT options are set to YES then # doxygen will generate a call dependency graph for every global function # or class method. Note that enabling this option will significantly increase # the time of a run. So in most cases it will be better to enable call graphs # for selected functions only using the \callgraph command. CALL_GRAPH = YES # If the CALLER_GRAPH and HAVE_DOT tags are set to YES then # doxygen will generate a caller dependency graph for every global function # or class method. Note that enabling this option will significantly increase # the time of a run. So in most cases it will be better to enable caller # graphs for selected functions only using the \callergraph command. CALLER_GRAPH = YES # If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen # will generate a graphical hierarchy of all classes instead of a textual one. GRAPHICAL_HIERARCHY = YES # If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES # then doxygen will show the dependencies a directory has on other directories # in a graphical way. The dependency relations are determined by the #include # relations between the files in the directories. DIRECTORY_GRAPH = YES # The DOT_IMAGE_FORMAT tag can be used to set the image format of the images # generated by dot. Possible values are svg, png, jpg, or gif. # If left blank png will be used. DOT_IMAGE_FORMAT = png # The tag DOT_PATH can be used to specify the path where the dot tool can be # found. If left blank, it is assumed the dot tool can be found in the path. DOT_PATH = # The DOTFILE_DIRS tag can be used to specify one or more directories that # contain dot files that are included in the documentation (see the # \dotfile command). DOTFILE_DIRS = # The MSCFILE_DIRS tag can be used to specify one or more directories that # contain msc files that are included in the documentation (see the # \mscfile command). MSCFILE_DIRS = # The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of # nodes that will be shown in the graph. If the number of nodes in a graph # becomes larger than this value, doxygen will truncate the graph, which is # visualized by representing a node as a red box. Note that doxygen if the # number of direct children of the root node in a graph is already larger than # DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note # that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH. DOT_GRAPH_MAX_NODES = 50 # The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the # graphs generated by dot. A depth value of 3 means that only nodes reachable # from the root by following a path via at most 3 edges will be shown. Nodes # that lay further from the root node will be omitted. Note that setting this # option to 1 or 2 may greatly reduce the computation time needed for large # code bases. Also note that the size of a graph can be further restricted by # DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction. MAX_DOT_GRAPH_DEPTH = 0 # Set the DOT_TRANSPARENT tag to YES to generate images with a transparent # background. This is disabled by default, because dot on Windows does not # seem to support this out of the box. Warning: Depending on the platform used, # enabling this option may lead to badly anti-aliased labels on the edges of # a graph (i.e. they become hard to read). DOT_TRANSPARENT = NO # Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output # files in one run (i.e. multiple -o and -T options on the command line). This # makes dot run faster, but since only newer versions of dot (>1.8.10) # support this, this feature is disabled by default. DOT_MULTI_TARGETS = NO # If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will # generate a legend page explaining the meaning of the various boxes and # arrows in the dot generated graphs. GENERATE_LEGEND = YES # If the DOT_CLEANUP tag is set to YES (the default) Doxygen will # remove the intermediate dot files that are used to generate # the various graphs. DOT_CLEANUP = YES pacemaker-master/GNUmakefile000066400000000000000000000316261217637305600163730ustar00rootroot00000000000000# # Copyright (C) 2008 Andrew Beekhof # # 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 2 # of the License, 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. # default: $(shell test ! -e configure && echo init) $(shell test -e configure && echo core) -include Makefile PACKAGE ?= pacemaker # Force 'make dist' to be consistent with 'make export' distprefix = ClusterLabs-$(PACKAGE) distdir = $(distprefix)-$(TAG) TARFILE = $(distdir).tar.gz DIST_ARCHIVES = $(TARFILE) RPM_ROOT = $(shell pwd) RPM_OPTS = --define "_sourcedir $(RPM_ROOT)" \ --define "_specdir $(RPM_ROOT)" \ --define "_srcrpmdir $(RPM_ROOT)" \ MOCK_OPTIONS ?= --resultdir=$(RPM_ROOT)/mock --no-cleanup-after # Default to fedora compliant spec files # SLES: /etc/SuSE-release # openSUSE: /etc/SuSE-release # RHEL: /etc/redhat-release # Fedora: /etc/fedora-release, /etc/redhat-release, /etc/system-release F ?= $(shell test ! -e /etc/fedora-release && echo 0; test -e /etc/fedora-release && rpm --eval %{fedora}) ARCH ?= $(shell test -e /etc/fedora-release && rpm --eval %{_arch}) MOCK_CFG ?= $(shell test -e /etc/fedora-release && echo fedora-$(F)-$(ARCH)) DISTRO ?= $(shell test -e /etc/SuSE-release && echo suse; echo fedora) TAG ?= $(shell git log --pretty="format:%h" -n 1) WITH ?= --without doc #WITH ?= --without=doc --with=gcov LAST_RC ?= $(shell test -e /Volumes || git tag -l | grep Pacemaker | sort -Vr | grep rc | head -n 1) LAST_RELEASE ?= $(shell test -e /Volumes || git tag -l | grep Pacemaker | sort -Vr | grep -v rc | head -n 1) NEXT_RELEASE ?= $(shell echo $(LAST_RELEASE) | awk -F. '/[0-9]+\./{$$3+=1;OFS=".";print $$1,$$2,$$3}') beekhof: echo $(LAST_RELEASE) $(NEXT_RELEASE) BUILD_COUNTER ?= build.counter LAST_COUNT = $(shell test ! -e $(BUILD_COUNTER) && echo 0; test -e $(BUILD_COUNTER) && cat $(BUILD_COUNTER)) COUNT = $(shell expr 1 + $(LAST_COUNT)) init: ./autogen.sh export: rm -f $(PACKAGE)-dirty.tar.* $(PACKAGE)-tip.tar.* $(PACKAGE)-HEAD.tar.* if [ ! -f $(TARFILE) ]; then \ rm -f $(PACKAGE).tar.*; \ if [ $(TAG) = dirty ]; then \ git commit -m "DO-NOT-PUSH" -a; \ git archive --prefix=$(distdir)/ HEAD | gzip > $(TARFILE); \ git reset --mixed HEAD^; \ else \ git archive --prefix=$(distdir)/ $(TAG) | gzip > $(TARFILE); \ fi; \ echo `date`: Rebuilt $(TARFILE); \ else \ echo `date`: Using existing tarball: $(TARFILE); \ fi $(PACKAGE)-opensuse.spec: $(PACKAGE)-suse.spec cp $^ $@ @echo Rebuilt $@ $(PACKAGE)-suse.spec: $(PACKAGE).spec.in GNUmakefile rm -f $@ if [ x != x"`git ls-files -m | grep pacemaker.spec.in`" ]; then \ cp $(PACKAGE).spec.in $@; \ echo "Rebuilt $@ (local modifications)"; \ elif [ x = x"`git show $(TAG):pacemaker.spec.in 2>/dev/null`" ]; then \ cp $(PACKAGE).spec.in $@; \ echo "Rebuilt $@"; \ else \ git show $(TAG):$(PACKAGE).spec.in >> $@; \ echo "Rebuilt $@ from $(TAG)"; \ fi sed -i s:%{_docdir}/%{name}:%{_docdir}/%{name}-%{version}:g $@ sed -i s:corosynclib:libcorosync:g $@ sed -i s:libexecdir}/lcrso:libdir}/lcrso:g $@ sed -i 's:%{name}-libs:lib%{name}3:g' $@ sed -i s:heartbeat-libs:heartbeat:g $@ sed -i s:cluster-glue-libs:libglue:g $@ sed -i s:libselinux-devel:automake:g $@ sed -i s:lm_sensors-devel:automake:g $@ sed -i s:bzip2-devel:libbz2-devel:g $@ sed -i s:bcond_without\ publican:bcond_with\ publican:g $@ sed -i s:docbook-style-xsl:docbook-xsl-stylesheets:g $@ sed -i s:libtool-ltdl-devel::g $@ sed -i s:publican::g $@ sed -i s:byacc::g $@ sed -i s:global\ cs_major.*:global\ cs_major\ 1:g $@ sed -i s:global\ cs_minor.*:global\ cs_minor\ 4:g $@ sed -i s:gnutls-devel:libgnutls-devel:g $@ sed -i s:189:90:g $@ sed -i 's@python-devel@python-devel python-curses python-xml@' $@ sed -i 's@Requires: python@Requires: python python-curses python-xml@' $@ sed -i 's@%systemd_post pacemaker.service@if [ ZZZ -eq 1 ]; then systemctl preset pacemaker.service || : ; fi@' $@ sed -i 's@%systemd_postun_with_restart pacemaker.service@systemctl daemon-reload || : ; if [ ZZZ -ge 1 ]; then systemctl try-restart pacemaker.service || : ; fi@' $@ sed -i 's@%systemd_preun pacemaker.service@if [ ZZZ -eq 0 ]; then systemctl --no-reload disable pacemaker.service || : ; systemctl stop pacemaker.service || : ; fi@' $@ sed -i 's@%systemd_post pacemaker_remote.service@if [ ZZZ -eq 1 ]; then systemctl preset pacemaker_remote.service || : ; fi@' $@ sed -i 's@%systemd_postun_with_restart pacemaker_remote.service@systemctl daemon-reload || : ; if [ ZZZ -ge 1 ]; then systemctl try-restart pacemaker_remote.service || : ; fi@' $@ sed -i 's@%systemd_preun pacemaker_remote.service@if [ ZZZ -eq 0 ]; then systemctl --no-reload disable pacemaker_remote.service || : ; systemctl stop pacemaker_remote.service || : ; fi@' $@ sed -i "s@ZZZ@\o0441@g" $@ @echo "Applied SUSE-specific modifications" # Works for all fedora based distros $(PACKAGE)-%.spec: $(PACKAGE).spec.in rm -f $@ if [ x != x"`git ls-files -m | grep pacemaker.spec.in`" ]; then \ cp $(PACKAGE).spec.in $(PACKAGE)-$*.spec; \ echo "Rebuilt $@ (local modifications)"; \ elif [ x = x"`git show $(TAG):pacemaker.spec.in 2>/dev/null`" ]; then \ cp $(PACKAGE).spec.in $(PACKAGE)-$*.spec; \ echo "Rebuilt $@"; \ else \ git show $(TAG):$(PACKAGE).spec.in >> $(PACKAGE)-$*.spec; \ echo "Rebuilt $@ from $(TAG)"; \ fi srpm-%: export $(PACKAGE)-%.spec rm -f *.src.rpm cp $(PACKAGE)-$*.spec $(PACKAGE).spec if [ -e $(BUILD_COUNTER) ]; then \ echo $(COUNT) > $(BUILD_COUNTER); \ fi sed -i 's/Source0:.*/Source0:\ $(TARFILE)/' $(PACKAGE).spec sed -i 's/global\ specversion.*/global\ specversion\ $(COUNT)/' $(PACKAGE).spec sed -i 's/global\ upstream_version.*/global\ upstream_version\ $(TAG)/' $(PACKAGE).spec sed -i 's/global\ upstream_prefix.*/global\ upstream_prefix\ $(distprefix)/' $(PACKAGE).spec case $(TAG) in \ Pacemaker*) sed -i 's/Version:.*/Version:\ $(shell echo $(TAG) | sed -e s:Pacemaker-:: -e s:-.*::)/' $(PACKAGE).spec;; \ *) sed -i 's/Version:.*/Version:\ $(shell echo $(NEXT_RELEASE) | sed -e s:Pacemaker-:: -e s:-.*::)/' $(PACKAGE).spec;; \ esac rpmbuild -bs --define "dist .$*" $(RPM_OPTS) $(WITH) $(PACKAGE).spec chroot: mock-$(MOCK_CFG) mock-install-$(MOCK_CFG) mock-sh-$(MOCK_CFG) echo "Done" mock-next: make F=$(shell expr 1 + $(F)) mock mock-rawhide: make F=rawhide mock mock-install-%: echo "Installing packages" mock --root=$* $(MOCK_OPTIONS) --install $(RPM_ROOT)/mock/*.rpm vi sudo valgrind lcov gdb fence-agents mock-sh: mock-sh-$(MOCK_CFG) echo "Done" mock-sh-%: echo "Connecting" mock --root=$* $(MOCK_OPTIONS) --shell echo "Done" # eg. WITH="--with cman" make rpm mock-%: make srpm-$(firstword $(shell echo $(@:mock-%=%) | tr '-' ' ')) -rm -rf $(RPM_ROOT)/mock @echo "mock --root=$* --rebuild $(WITH) $(MOCK_OPTIONS) $(RPM_ROOT)/*.src.rpm" mock --root=$* --no-cleanup-after --rebuild $(WITH) $(MOCK_OPTIONS) $(RPM_ROOT)/*.src.rpm srpm: srpm-$(DISTRO) echo "Done" mock: mock-$(MOCK_CFG) echo "Done" rpm-dep: $(PACKAGE)-$(DISTRO).spec if [ x != x`which yum-builddep 2>/dev/null` ]; then \ echo "Installing with yum-builddep"; \ sudo yum-builddep $(PACKAGE)-$(DISTRO).spec; \ elif [ x != x`which yum 2>/dev/null` ]; then \ echo -e "Installing: $(shell grep BuildRequires pacemaker.spec.in | sed -e s/BuildRequires:// -e s:\>.*0:: | tr '\n' ' ')\n\n"; \ sudo yum install $(shell grep BuildRequires pacemaker.spec.in | sed -e s/BuildRequires:// -e s:\>.*0:: | tr '\n' ' '); \ elif [ x != x`which zypper` ]; then \ echo -e "Installing: $(shell grep BuildRequires pacemaker.spec.in | sed -e s/BuildRequires:// -e s:\>.*0:: | tr '\n' ' ')\n\n"; \ sudo zypper install $(shell grep BuildRequires pacemaker.spec.in | sed -e s/BuildRequires:// -e s:\>.*0:: | tr '\n' ' ');\ else \ echo "I don't know how to install $(shell grep BuildRequires pacemaker.spec.in | sed -e s/BuildRequires:// -e s:\>.*0:: | tr '\n' ' ')";\ fi rpm: srpm @echo To create custom builds, edit the flags and options in $(PACKAGE).spec first rpmbuild $(RPM_OPTS) $(WITH) --rebuild $(RPM_ROOT)/*.src.rpm release: make TAG=$(LAST_RELEASE) rpm rc: make TAG=$(LAST_RC) rpm dirty: make TAG=dirty mock COVERITY_DIR = $(shell pwd)/coverity-$(TAG) COVFILE = pacemaker-coverity-$(TAG).tgz COVHOST ?= scan5.coverity.com COVPASS ?= password # Public coverity coverity: test -e configure || ./autogen.sh test -e Makefile || ./configure make core-clean rm -rf $(COVERITY_DIR) cov-build --dir $(COVERITY_DIR) make core tar czf $(COVFILE) --transform=s@.*$(TAG)@cov-int@ $(COVERITY_DIR) @echo "Uploading to public Coverity instance..." curl --form file=@$(COVFILE) --form project=$(PACKAGE) --form password=$(COVPASS) --form email=andrew@beekhof.net http://$(COVHOST)/cgi-bin/upload.py coverity-corp: test -e configure || ./autogen.sh test -e Makefile || ./configure make core-clean rm -rf $(COVERITY_DIR) cov-build --dir $(COVERITY_DIR) make core @echo "Waiting for a corporate Coverity license..." cov-analyze --dir $(COVERITY_DIR) --wait-for-license cov-format-errors --dir $(COVERITY_DIR) --emacs-style > $(TAG).coverity cov-format-errors --dir $(COVERITY_DIR) rsync -avzxlSD --progress $(COVERITY_DIR)/c/output/errors/ root@www.clusterlabs.org:/var/www/html/coverity/$(PACKAGE)/$(TAG) make core-clean # cov-commit-defects --host $(COVHOST) --dir $(COVERITY_DIR) --stream $(PACKAGE) --user auto --password $(COVPASS) rm -rf $(COVERITY_DIR) global: clean-generic gtags -q %.8.html: %.8 echo groff -mandoc `man -w ./$<` -T html > $@ groff -mandoc `man -w ./$<` -T html > $@ rsync -azxlSD --progress $@ root@www.clusterlabs.org:/var/www/html/man/ %.7.html: %.7 echo groff -mandoc `man -w ./$<` -T html > $@ groff -mandoc `man -w ./$<` -T html > $@ rsync -azxlSD --progress $@ root@www.clusterlabs.org:/var/www/html/man/ doxygen: doxygen Doxyfile abi: abi-check pacemaker $(LAST_RELEASE) $(TAG) abi-www: abi-check -u pacemaker $(LAST_RELEASE) $(TAG) www: all global doxygen find . -name "[a-z]*.8" -exec make \{\}.html \; find . -name "[a-z]*.7" -exec make \{\}.html \; htags -sanhIT rsync -avzxlSD --progress HTML/ root@www.clusterlabs.org:/var/www/html/global/$(PACKAGE)/$(TAG) rsync -avzxlSD --progress doc/api/html/ root@www.clusterlabs.org:/var/www/html/doxygen/$(PACKAGE)/$(TAG) make -C doc www make coverity summary: @printf "\n* `date +"%a %b %d %Y"` `git config user.name` <`git config user.email`> $(NEXT_RELEASE)-1" @printf "\n- Update source tarball to revision: `git id`" @printf "\n- Changesets: `git log --pretty=format:'%h' $(LAST_RELEASE)..HEAD | wc -l`" @printf "\n- Diff: " @git diff -r $(LAST_RELEASE)..HEAD --stat include lib mcp pengine/*.c pengine/*.h cib crmd fencing lrmd tools xml | tail -n 1 rc-changes: @make NEXT_RELEASE=$(shell echo $(LAST_RC) | sed s:-rc.*::) LAST_RELEASE=$(LAST_RC) changes changes: summary @printf "\n- Features added since $(LAST_RELEASE)\n" @git log --pretty=format:' +%s' --abbrev-commit $(LAST_RELEASE)..HEAD | grep -e Feature: | sed -e 's@Feature:@@' | sort -uf @printf "\n- Changes since $(LAST_RELEASE)\n" @git log --pretty=format:' +%s' --abbrev-commit $(LAST_RELEASE)..HEAD | grep -e High: -e Fix: -e Bug | sed -e 's@Fix:@@' -e s@High:@@ -e s@Fencing:@fencing:@ -e 's@Bug@ Bug@' -e s@PE:@pengine:@ | sort -uf changelog: @make changes > ChangeLog @printf "\n">> ChangeLog git show $(LAST_RELEASE):ChangeLog >> ChangeLog @echo -e "\033[1;35m -- Don't forget to run the bumplibs.sh script! --\033[0m" indent: find . -name "*.h" -exec ./p-indent \{\} \; find . -name "*.c" -exec ./p-indent \{\} \; git co HEAD crmd/fsa_proto.h lib/gnu rel-tags: tags find . -name TAGS -exec sed -i 's:\(.*\)/\(.*\)/TAGS:\2/TAGS:g' \{\} \; ccc_analyzer=/usr/lib64/clang-analyzer/scan-build/ccc-analyzer clang: test -e $(ccc_analyzer) || echo "CLang Analyiser not available. Install the clang-analyzer package" test -e $(ccc_analyzer) || false make CC=$(ccc_analyzer) check # V3 = scandir unsetenv alphasort # V2 = setenv strerror strchrnul strndup # http://www.gnu.org/software/gnulib/manual/html_node/Initial-import.html#Initial-import GNU_MODS = crypto/md5 gnulib-update: -test ! -e gnulib && git clone git://git.savannah.gnu.org/gnulib.git cd gnulib && git pull gnulib/gnulib-tool --source-base=lib/gnu --lgpl=2 --no-vc-files --import $(GNU_MODS) pacemaker-master/Makefile.am000066400000000000000000000062551217637305600163550ustar00rootroot00000000000000# # Pacemaker code # # Copyright (C) 2004 Andrew Beekhof # # 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 2 # of the License, 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. # EXTRA_DIST = autogen.sh ConfigureMe README.in libltdl.tar m4/gnulib-cache.m4 MAINTAINERCLEANFILES = Makefile.in aclocal.m4 configure DRF/config-h.in \ DRF/stamp-h.in libtool.m4 ltdl.m4 libltdl.tar CORE = $(LIBLTDL_DIR) replace include lib mcp pengine cib crmd fencing lrmd tools xml SUBDIRS = $(CORE) cts extra doc doc_DATA = AUTHORS COPYING COPYING.LIB noinst_PROGRAMS = scratch AUTOMAKE_OPTIONS = foreign ACLOCAL_AMFLAGS = -I m4 testdir = $(datadir)/$(PACKAGE)/tests/ test_SCRIPTS = coverage.sh BasicSanity.sh test_DATA = valgrind-pcmk.suppressions # Scratch file for ad-hoc testing scratch_SOURCES = scratch.c scratch_LDADD = $(top_builddir)/lib/common/libcrmcommon.la core: @echo "Building only core components: $(CORE)" list='$(CORE)'; for subdir in $$list; do echo "Building $$subdir"; make -C $$subdir all || exit 1; done core-install: @echo "Installing only core components: $(CORE)" list='$(CORE)'; for subdir in $$list; do echo "Installing $$subdir"; make -C $$subdir install || exit 1; done core-clean: @echo "Cleaning only core components: $(CORE)" list='$(CORE)'; for subdir in $$list; do echo "Cleaning $$subdir"; make -C $$subdir clean || exit 1; done install-exec-local: $(INSTALL) -d $(DESTDIR)/$(LCRSODIR) $(INSTALL) -d -m 750 $(DESTDIR)/$(CRM_CONFIG_DIR) $(INSTALL) -d -m 750 $(DESTDIR)/$(CRM_STATE_DIR) $(INSTALL) -d -m 750 $(DESTDIR)/$(CRM_BLACKBOX_DIR) -chown $(CRM_DAEMON_USER):$(CRM_DAEMON_GROUP) $(DESTDIR)/$(CRM_CONFIG_DIR) -chown $(CRM_DAEMON_USER):$(CRM_DAEMON_GROUP) $(DESTDIR)/$(CRM_STATE_DIR) -chown $(CRM_DAEMON_USER):$(CRM_DAEMON_GROUP) $(DESTDIR)/$(CRM_BLACKBOX_DIR) if BUILD_CS_PLUGIN rm -f $(DESTDIR)$(LCRSODIR)/pacemaker.lcrso $(DESTDIR)$(LCRSODIR)/service_crm.so cp $(DESTDIR)$(libdir)/service_crm.so $(DESTDIR)$(LCRSODIR)/pacemaker.lcrso endif if BUILD_HEARTBEAT_SUPPORT $(INSTALL) -d $(DESTDIR)/$(HB_DAEMON_DIR) ln -sf $(CRM_DAEMON_DIR)/attrd $(DESTDIR)$(HB_DAEMON_DIR)/ ln -sf $(CRM_DAEMON_DIR)/cib $(DESTDIR)$(HB_DAEMON_DIR)/ ln -sf $(CRM_DAEMON_DIR)/crmd $(DESTDIR)$(HB_DAEMON_DIR)/ ln -sf $(CRM_DAEMON_DIR)/pengine $(DESTDIR)$(HB_DAEMON_DIR)/ ln -sf $(CRM_DAEMON_DIR)/stonithd $(DESTDIR)$(HB_DAEMON_DIR)/ endif # Use chown because the user/group may not exist clean-generic: rm -f $(TARFILE) *.tar.bz2 *.sed dist-clean-local: rm -f autoconf automake autoheader maintainer-clean-local: rm -f libltdl.tar .PHONY: rpm pkg handy handy-copy pacemaker-master/NEWS000066400000000000000000000000351217637305600150060ustar00rootroot00000000000000Nobody here but us chickens. pacemaker-master/README.markdown000066400000000000000000000045131217637305600170150ustar00rootroot00000000000000# Pacemaker ## What is Pacemaker? Pacemaker is an advanced, scalable High-Availability cluster resource manager for Linux-HA (Heartbeat) and/or Corosync. It supports "n-node" clusters with significant capabilities for managing resources and dependencies. It will run scripts at initialization, when machines go up or down, when related resources fail and can be configured to periodically check resource health. ## For more information look at: * [Website](http://www.clusterlabs.org) * [Issues/Bugs](http://bugs.clusterlabs.org) * [Mailing list](http://oss.clusterlabs.org/mailman/listinfo/pacemaker). * [Documentation](http://www.clusterlabs.org/doc) ## Important information about the _crm shell_ Since late-April, the _crm shell_ is no longer included in the Pacemaker source tree. This change was made at the author's request as it is now maintained as a separate project at https://savannah.nongnu.org/projects/crmsh/ ## Build Dependencies * automake * autoconf * libtool-ltdl-devel * pkgconfig * python * glib2-devel * libxml2-devel * libxslt-devel * python-devel * gcc-c++ * bzip2-devel * gnutls-devel * pam-devel * libqb-devel ## Cluster Stack Dependencies (Pick at least one) * clusterlib-devel (CMAN) * corosynclib-devel (Corosync) * heartbeat-devel (Heartbeat) ## Optional Build Dependencies * ncurses-devel * openssl-devel * libselinux-devel * cluster-glue-libs-devel (LHA style fencing agents) * libesmtp-devel (Email alerts) * lm_sensors-devel (SNMP alerts) * net-snmp-devel (SNMP alerts) * asciidoc (documentation) * help2man (documentation) * publican (documentation) * inkscape (documentation) * docbook-style-xsl (documentation) ## Source Control (GIT) git clone git://github.com/ClusterLabs/pacemaker.git [See Github](https://github.com/ClusterLabs/pacemaker) ## Installing from source $ ./autogen.sh $ ./configure $ make $ sudo make install ## How you can help If you find this project useful, you may want to consider supporting its future development. There are a number of ways to support the project. * Test and report issues. * Tick something off our [todo list](https://github.com/ClusterLabs/pacemaker/blob/master/TODO.markdown) * Help others on the [mailing list](http://oss.clusterlabs.org/mailman/listinfo/pacemaker). * Contribute documentation, examples and test cases. * Contribute patches. * Spread the word. pacemaker-master/TODO.markdown000066400000000000000000000053641217637305600166320ustar00rootroot00000000000000# Semi-random collection of tasks we'd like to get done ## Targeted for this year - Implement: - crm_node --standby - crm_resource --enable --recursive : set target role for anything we depend on - merge all the crmd global variables into a single struct - Only bump epoch if we have quorum when we are elected the DC - Bump epoch if we gain quorum and are the DC - Make sure crm_attribute/crmd writes direct to cib if attrd is not around - See if anywhere should be using clock_gettime() instead of time(NULL) - Make sure fail counts etc are removed on resource deletion - Test and merge ipc-dispatch.patch - Process election votes as soon as they happen notice: do_election_count_vote: Election 6 (current: 6, owner: 101): Processed no-vote from east-04 (Peer is not part of our cluster) - Support http://cgit.freedesktop.org/systemd/systemd/commit/?id=96342de68d0d6de71a062d984dafd2a0905ed9fe - Support 'yesterday' and 'thursday' and '24-04' as dates in crm_report - Allow the N in 'give up after N failed fencing attempts' to be configurable - Show an english version of the config with crm_resource --rules - Convert cts/CIB.py into a supported Python API for the CIB - Re-implement no-quorum filter for cib updates? ## Targeted for next year and beyond - Support A colocated with (B || C || D) - Implement a truely atomic version of attrd - Support rolling average values in attrd - Support heartbeat with the mcp - Freeze/Thaw - Create Pacemaker plugin for snmpd - http://www.net-snmp.org/ - Investigate using a DB as the back-end for the CIB - Decide whether to fully support or drop failover domains # Testing - Convert BandwidthTest CTS test into a Scenario wrapper - find_operations() is not covered by PE regression tests - no_quorum_policy==suicide is not covered by PE regression tests - parse_xml_duration() is not covered by PE regression tests - phase_of_the_moon() is not covered by PE regression tests - test_role_expression() is not covered by PE regression tests - native_parameter() is not covered by PE regression tests - clone_active() is not covered by PE regression tests - convert_non_atomic_task() in native.c is not covered by PE regression tests - group_rsc_colocation_lh() is not covered by PE regression tests - Test on-fail=standby # Documentation - Clusters from Scratch: Mail - Clusters from Scratch: MySQL - Document advanced fencing logic in Pacemaker Explained - Use ann:defaultValue="..." instead of in the schema more often - Document in CFS an Appendix detailing with re-enabling firewall - Document implicit operation creation in CFS once pcs supports it. - Document use of pcs resource move command in CFS once pcs supports it. - Make use of --clone option in pcs resource create dlm in CFS once pcs fully supports that option. pacemaker-master/abi-check000077500000000000000000000041611217637305600160470ustar00rootroot00000000000000#!/bin/bash UPLOAD=0 if [ $1 = "-u" ]; then UPLOAD=1; shift fi PACKAGE=$1; shift function tag() { if [[ $1 =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3} ]]; then echo Pacemaker-$1 else echo $1 fi } function version() { echo $1 | sed s:.*-:: } function extract() { DUMP=1 TAG=$1 VERSION=$2 if [ $VERSION = HEAD ]; then rm -rf abi_dumps/$PACKAGE/${PACKAGE}_$VERSION.abi.tar.gz elif [ -f abi_dumps/$PACKAGE/${PACKAGE}_$VERSION.abi.tar.gz ]; then return fi echo "Building ABI dump for $*" BUILD_ROOT=.ABI-build rm -rf $BUILD_ROOT git archive --prefix $BUILD_ROOT/ $TAG | tar xv BUILD_ROOT=`pwd`/$BUILD_ROOT DESC=$BUILD_ROOT/$VERSION.xml sed -i.sed 's: doc::' $BUILD_ROOT/Makefile.am sed -i.sed 's: debian::' $BUILD_ROOT/Makefile.am cat<$DESC $VERSION $BUILD_ROOT/root/usr/include/pacemaker/crm EOF ( cd $BUILD_ROOT && ./autogen.sh ) ( cd $BUILD_ROOT && ./configure --disable-fatal-warnings ) make -C $BUILD_ROOT V=0 DESTDIR=${BUILD_ROOT}/root install if [ $? != 0 ]; then echo "Build for $TAG failed. Repair, populate and re-run: " echo " abi-compliance-checker -l $PACKAGE -dump_abi $DESC" echo "" echo "To find libraries after building:" echo " find $BUILD_ROOT/root -name "*.so" -print" else find $BUILD_ROOT/root -name "*.so" -print >> $DESC fi cat<>$DESC EOF if [ $DUMP = 1 ]; then abi-compliance-checker -l $PACKAGE -dump_abi $DESC rm -rf $BUILD_ROOT else exit 1 fi } for arg in $*; do T=`tag $arg` V=`version $T` extract $T $V done if [ $# = 2 ]; then V1=`version $1` V2=`version $2` abi-compliance-checker -l ${PACKAGE} \ -d1 abi_dumps/${PACKAGE}/${PACKAGE}_${V1}.abi.tar.gz \ -d2 abi_dumps/${PACKAGE}/${PACKAGE}_${V2}.abi.tar.gz if [ $UPLOAD = 1 -a -d compat_reports/pacemaker/${V1}_to_${V2} ]; then rsync -azxlSD --progress compat_reports/pacemaker/${V1}_to_${V2} root@www.clusterlabs.org:/var/www/html/abi/pacemaker/ fi fi pacemaker-master/acinclude.m4000066400000000000000000000023011217637305600164760ustar00rootroot00000000000000dnl dnl local autoconf/automake macros needed for heartbeat dnl Started by David Lee February 2006 dnl dnl License: GNU General Public License (GPL) dnl AM_CHECK_PYTHON_HEADERS: Find location of python include files. dnl Taken from: dnl http://source.macgimp.org/ dnl which is GPL and is attributed to James Henstridge. dnl dnl AM_CHECK_PYTHON_HEADERS([ACTION-IF-POSSIBLE], [ACTION-IF-NOT-POSSIBLE]) dnl Imports: dnl $PYTHON dnl Exports: dnl PYTHON_INCLUDES AC_DEFUN([AM_CHECK_PYTHON_HEADERS], [AC_REQUIRE([AM_PATH_PYTHON]) AC_MSG_CHECKING(for headers required to compile python extensions) dnl deduce PYTHON_INCLUDES py_prefix=`$PYTHON -c "import sys; print sys.prefix"` py_exec_prefix=`$PYTHON -c "import sys; print sys.exec_prefix"` PYTHON_INCLUDES="-I${py_prefix}/include/python${PYTHON_VERSION}" if test "$py_prefix" != "$py_exec_prefix"; then PYTHON_INCLUDES="$PYTHON_INCLUDES -I${py_exec_prefix}/include/python${PYTHON_VERSION}" fi AC_SUBST(PYTHON_INCLUDES) dnl check if the headers exist: save_CPPFLAGS="$CPPFLAGS" CPPFLAGS="$CPPFLAGS $PYTHON_INCLUDES" AC_TRY_CPP([#include ],dnl [AC_MSG_RESULT(found) $1],dnl [AC_MSG_RESULT(not found) $2]) CPPFLAGS="$save_CPPFLAGS" ]) pacemaker-master/autogen.sh000077500000000000000000000026061217637305600163160ustar00rootroot00000000000000#!/bin/sh # # License: GNU General Public License (GPL) # Copyright 2001 horms # (heavily mangled by alanr) # # bootstrap: set up the project and get it ready to make # # Basically, we run autoconf, automake and libtool in the # right way to get things set up for this environment. # # We also look and see if those tools are installed, and # tell you where to get them if they're not. # # Our goal is to not require dragging along anything # more than we need. If this doesn't work on your system, # (i.e., your /bin/sh is broken) send us a patch. # # This code loosely based on the corresponding named script in # enlightenment, and also on the sort-of-standard autoconf # bootstrap script. # Run this to generate all the initial makefiles, etc. # Unset GREP_OPTIONS as any coloring can mess up the AC_CONFIG_AUX_DIR matching patterns GREP_OPTIONS= autoreconf -visf -Wno-portability if [ -f config.log ]; then echo Now re-running ./configure with the previous arguments last=`grep --color=never "$.*configure" config.log | tail -n 1 | sed s:.*configure:./configure: | sed s:--no-create::` echo " $last" eval $last else echo Now run ./configure echo "Now run configure with any arguments (eg. --prefix) specific to your system" if [ -e `which rpm` ]; then echo "Suggested invocation:" rpm --eval %{configure} | grep -v program-prefix fi fi trap '' 0 pacemaker-master/bumplibs.sh000077500000000000000000000062771217637305600165010ustar00rootroot00000000000000#!/bin/bash declare -A headers headers[crmcommon]="include/crm/common include/crm/crm.h" headers[crmcluster]="include/crm/cluster.h" headers[transitioner]="include/crm/transition.h" headers[cib]="include/crm/cib.h include/crm/cib/util.h" headers[pe_rules]="include/crm/pengine/rules.h" headers[pe_status]="include/crm/pengine/common.h include/crm/pengine/complex.h include/crm/pengine/rules.h include/crm/pengine/status.h" headers[pengine]="include/crm/pengine/common.h include/crm/pengine/complex.h include/crm/pengine/rules.h include/crm/pengine/status.h" headers[stonithd]="include/crm/stonith-ng.h" headers[lrmd]="include/crm/lrmd.h" LAST_RELEASE=`test -e /Volumes || git tag -l | grep Pacemaker | grep -v rc | sort -Vr | head -n 1` for lib in crmcommon crmcluster transitioner cib pe_rules pe_status stonithd pengine lrmd; do git diff -w $LAST_RELEASE..HEAD ${headers[$lib]} echo "" am=`find . -name Makefile.am -exec grep -lr "lib${lib}_la.*version-info" \{\} \;` am_dir=`dirname $am` if grep "lib${lib}_la_SOURCES.*\\\\" $am then echo -e "\033[1;35m -- Sources list for lib$lib is probably truncated! --\033[0m" echo "" fi sources=`grep "lib${lib}_la_SOURCES" $am | sed s/.*=// | sed 's:$(top_builddir)/::' | sed 's:$(top_srcdir)/::' | sed 's:\\\::' | sed 's:$(libpe_rules_la_SOURCES):rules.c\ common.c:'` full_sources="" for f in $sources; do if echo $f | grep -q "/" then full_sources="$full_sources $f" else full_sources="$full_sources $am_dir/$f" fi done lines=`git diff -w $LAST_RELEASE..HEAD ${headers[$lib]} $full_sources | wc -l` if [ $lines -gt 0 ]; then echo "- Headers: ${headers[$lib]}" echo "- Sources: $full_sources" echo "- Changed Sources since $LAST_RELEASE:" git diff -w $LAST_RELEASE..HEAD --stat $full_sources echo "" read -p "Are the changes to lib$lib: [a]dditions, [r]emovals or [f]ixes? [None]: " CHANGE git show $LAST_RELEASE:$am | grep version-info VER=`git show $LAST_RELEASE:$am | grep "lib.*${lib}_la.*version-info" | sed s/.*version-info// | awk '{print $1}'` VER_NOW=`grep "lib.*${lib}_la.*version-info" $am | sed s/.*version-info// | awk '{print $1}'` VER_1=`echo $VER | awk -F: '{print $1}'` VER_2=`echo $VER | awk -F: '{print $2}'` VER_3=`echo $VER | awk -F: '{print $3}'` VER_1_NOW=`echo $VER_NOW | awk -F: '{print $1}'` case $CHANGE in A|a) echo "New version with backwards compatible extensions: x+1:0:z+1" VER_1=`expr $VER_1 + 1` VER_2=0 VER_3=`expr $VER_3 + 1` ;; R|r) echo "New backwards incompatible version: x+1:0:0" VER_1=`expr $VER_1 + 1` VER_2=0 VER_3=0 for h in ${headers[$lib]}; do sed -i.sed "s/lib${lib}.so.${VER_1_NOW}/lib${lib}.so.${VER_1}/" $h done ;; F|f) echo "Bugfix: x:y+1:z" VER_2=`expr $VER_2 + 1` ;; esac VER_NEW=$VER_1:$VER_2:$VER_3 if [ ! -z $CHANGE ]; then if [ $VER_NEW != $VER_NOW ]; then echo "Updating $lib library version: $VER -> $VER_NEW" sed -i.sed "s/version-info\ $VER_NOW/version-info\ $VER_NEW/" $am else echo "No further version changes needed" fi else echo "Skipping $lib version" fi else echo "No changes to $lib interface" fi read -p "Continue?" echo "" done git diff -w pacemaker-master/cib/000077500000000000000000000000001217637305600150465ustar00rootroot00000000000000pacemaker-master/cib/Makefile.am000066400000000000000000000035621217637305600171100ustar00rootroot00000000000000# # Copyright (C) 2004 Andrew Beekhof # # 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 2 # of the License, 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. # MAINTAINERCLEANFILES = Makefile.in INCLUDES = -I$(top_builddir)/include -I$(top_srcdir)/include \ -I$(top_builddir)/libltdl -I$(top_srcdir)/libltdl EXTRA_DIST = cib.pam hadir = $(sysconfdir)/ha.d halibdir = $(CRM_DAEMON_DIR) commmoddir = $(halibdir)/modules/comm COMMONLIBS = $(top_builddir)/lib/common/libcrmcommon.la \ $(top_builddir)/lib/cib/libcib.la ## binary progs halib_PROGRAMS = cib cibmon if BUILD_HELP man8_MANS = %.8: % echo Creating $@ chmod a+x $(top_builddir)/cib/$< $(top_builddir)/cib/$< --help $(HELP2MAN) --output $@ --no-info --section 8 --name "Part of the Pacemaker cluster resource manager" $(top_builddir)/cib/$< endif ## SOURCES noinst_HEADERS = callbacks.h cibio.h cibmessages.h common.h notify.h cib_SOURCES = io.c messages.c notify.c \ callbacks.c main.c remote.c common.c cib_LDADD = $(top_builddir)/lib/cluster/libcrmcluster.la \ $(COMMONLIBS) $(CRYPTOLIB) $(CLUSTERLIBS) cibmon_SOURCES = cibmon.c cibmon_LDADD = $(COMMONLIBS) clean-generic: rm -f *.log *.debug *.xml *~ install-exec-local: # cp -f $(top_srcdir)/crm/cib/cib.pam $(DESTDIR)/etc/pam.d/cib uninstall-local: pacemaker-master/cib/callbacks.c000066400000000000000000001260661217637305600171440ustar00rootroot00000000000000/* * Copyright (C) 2004 Andrew Beekhof * * 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 2 of the License, or (at your option) any later version. * * This software 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 library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "common.h" extern GMainLoop *mainloop; extern gboolean cib_shutdown_flag; extern gboolean stand_alone; extern const char *cib_root; static unsigned long cib_local_bcast_num = 0; typedef struct cib_local_notify_s { xmlNode *notify_src; char *client_id; gboolean from_peer; gboolean sync_reply; } cib_local_notify_t; qb_ipcs_service_t *ipcs_ro = NULL; qb_ipcs_service_t *ipcs_rw = NULL; qb_ipcs_service_t *ipcs_shm = NULL; extern crm_cluster_t crm_cluster; extern int cib_update_counter(xmlNode * xml_obj, const char *field, gboolean reset); extern void GHFunc_count_peers(gpointer key, gpointer value, gpointer user_data); gint cib_GCompareFunc(gconstpointer a, gconstpointer b); gboolean can_write(int flags); void send_cib_replace(const xmlNode * sync_request, const char *host); void cib_process_request(xmlNode * request, gboolean privileged, gboolean force_synchronous, gboolean from_peer, crm_client_t * cib_client); extern GHashTable *local_notify_queue; int next_client_id = 0; extern const char *cib_our_uname; extern unsigned long cib_num_ops, cib_num_local, cib_num_updates, cib_num_fail; extern unsigned long cib_bad_connects, cib_num_timeouts; extern int cib_status; int cib_process_command(xmlNode * request, xmlNode ** reply, xmlNode ** cib_diff, gboolean privileged); gboolean cib_common_callback(qb_ipcs_connection_t * c, void *data, size_t size, gboolean privileged); static int32_t cib_ipc_accept(qb_ipcs_connection_t * c, uid_t uid, gid_t gid) { crm_trace("Connection %p", c); if (cib_shutdown_flag) { crm_info("Ignoring new client [%d] during shutdown", crm_ipcs_client_pid(c)); return -EPERM; } if (crm_client_new(c, uid, gid) == NULL) { return -EIO; } return 0; } static void cib_ipc_created(qb_ipcs_connection_t * c) { crm_trace("Connection %p", c); } static int32_t cib_ipc_dispatch_rw(qb_ipcs_connection_t * c, void *data, size_t size) { crm_client_t *client = crm_client_get(c); crm_trace("%p message from %s", c, client->id); return cib_common_callback(c, data, size, TRUE); } static int32_t cib_ipc_dispatch_ro(qb_ipcs_connection_t * c, void *data, size_t size) { crm_client_t *client = crm_client_get(c); crm_trace("%p message from %s", c, client->id); return cib_common_callback(c, data, size, FALSE); } /* Error code means? */ static int32_t cib_ipc_closed(qb_ipcs_connection_t * c) { crm_client_t *client = crm_client_get(c); crm_trace("Connection %p", c); crm_client_destroy(client); return 0; } static void cib_ipc_destroy(qb_ipcs_connection_t * c) { crm_trace("Connection %p", c); if (cib_shutdown_flag) { cib_shutdown(0); } } struct qb_ipcs_service_handlers ipc_ro_callbacks = { .connection_accept = cib_ipc_accept, .connection_created = cib_ipc_created, .msg_process = cib_ipc_dispatch_ro, .connection_closed = cib_ipc_closed, .connection_destroyed = cib_ipc_destroy }; struct qb_ipcs_service_handlers ipc_rw_callbacks = { .connection_accept = cib_ipc_accept, .connection_created = cib_ipc_created, .msg_process = cib_ipc_dispatch_rw, .connection_closed = cib_ipc_closed, .connection_destroyed = cib_ipc_destroy }; void cib_common_callback_worker(uint32_t id, uint32_t flags, xmlNode * op_request, crm_client_t * cib_client, gboolean privileged) { const char *op = crm_element_value(op_request, F_CIB_OPERATION); if (crm_str_eq(op, CRM_OP_REGISTER, TRUE)) { if (flags & crm_ipc_client_response) { xmlNode *ack = create_xml_node(NULL, __FUNCTION__); crm_xml_add(ack, F_CIB_OPERATION, CRM_OP_REGISTER); crm_xml_add(ack, F_CIB_CLIENTID, cib_client->id); crm_ipcs_send(cib_client, id, ack, FALSE); cib_client->request_id = 0; free_xml(ack); } return; } else if (crm_str_eq(op, T_CIB_NOTIFY, TRUE)) { /* Update the notify filters for this client */ int on_off = 0; long long bit = 0; const char *type = crm_element_value(op_request, F_CIB_NOTIFY_TYPE); crm_element_value_int(op_request, F_CIB_NOTIFY_ACTIVATE, &on_off); crm_debug("Setting %s callbacks for %s (%s): %s", type, cib_client->name, cib_client->id, on_off ? "on" : "off"); if (safe_str_eq(type, T_CIB_POST_NOTIFY)) { bit = cib_notify_post; } else if (safe_str_eq(type, T_CIB_PRE_NOTIFY)) { bit = cib_notify_pre; } else if (safe_str_eq(type, T_CIB_UPDATE_CONFIRM)) { bit = cib_notify_confirm; } else if (safe_str_eq(type, T_CIB_DIFF_NOTIFY)) { bit = cib_notify_diff; } else if (safe_str_eq(type, T_CIB_REPLACE_NOTIFY)) { bit = cib_notify_replace; } if (on_off) { set_bit(cib_client->options, bit); } else { clear_bit(cib_client->options, bit); } if (flags & crm_ipc_client_response) { /* TODO - include rc */ crm_ipcs_send_ack(cib_client, id, "ack", __FUNCTION__, __LINE__); cib_client->request_id = 0; } return; } cib_process_request(op_request, FALSE, privileged, FALSE, cib_client); } int32_t cib_common_callback(qb_ipcs_connection_t * c, void *data, size_t size, gboolean privileged) { uint32_t id = 0; uint32_t flags = 0; int call_options = 0; crm_client_t *cib_client = crm_client_get(c); xmlNode *op_request = crm_ipcs_recv(cib_client, data, size, &id, &flags); if (op_request) { crm_element_value_int(op_request, F_CIB_CALLOPTS, &call_options); } crm_trace("Inbound: %.200s", data); if (op_request == NULL) { crm_trace("Invalid message from %p", c); crm_ipcs_send_ack(cib_client, id, "nack", __FUNCTION__, __LINE__); return 0; } else if(cib_client == NULL) { crm_trace("Invalid client %p", c); return 0; } if (is_set(call_options, cib_sync_call)) { CRM_ASSERT(flags & crm_ipc_client_response); } if (flags & crm_ipc_client_response) { CRM_LOG_ASSERT(cib_client->request_id == 0); /* This means the client has two synchronous events in-flight */ cib_client->request_id = id; /* Reply only to the last one */ } if (cib_client->name == NULL) { const char *value = crm_element_value(op_request, F_CIB_CLIENTNAME); if (value == NULL) { cib_client->name = crm_itoa(cib_client->pid); } else { cib_client->name = strdup(value); } } crm_xml_add(op_request, F_CIB_CLIENTID, cib_client->id); crm_xml_add(op_request, F_CIB_CLIENTNAME, cib_client->name); #if ENABLE_ACL determine_request_user(cib_client->user, op_request, F_CIB_USER); #endif crm_log_xml_trace(op_request, "Client[inbound]"); cib_common_callback_worker(id, flags, op_request, cib_client, privileged); free_xml(op_request); return 0; } static void do_local_notify(xmlNode * notify_src, const char *client_id, gboolean sync_reply, gboolean from_peer) { /* send callback to originating child */ crm_client_t *client_obj = NULL; int local_rc = pcmk_ok; if (client_id != NULL) { client_obj = crm_client_get_by_id(client_id); } if (client_obj == NULL) { local_rc = -ECONNRESET; crm_trace("No client to sent the response to. F_CIB_CLIENTID not set."); } else { int rid = 0; if (sync_reply) { if (client_obj->ipcs) { CRM_LOG_ASSERT(client_obj->request_id); rid = client_obj->request_id; client_obj->request_id = 0; crm_trace("Sending response %d to %s %s", rid, client_obj->name, from_peer ? "(originator of delegated request)" : ""); } else { crm_trace("Sending response to %s %s", client_obj->name, from_peer ? "(originator of delegated request)" : ""); } } else { crm_trace("Sending an event to %s %s", client_obj->name, from_peer ? "(originator of delegated request)" : ""); } switch (client_obj->kind) { case CRM_CLIENT_IPC: if (crm_ipcs_send(client_obj, rid, notify_src, !sync_reply) < 0) { local_rc = -ENOMSG; } break; #ifdef HAVE_GNUTLS_GNUTLS_H case CRM_CLIENT_TLS: #endif case CRM_CLIENT_TCP: crm_remote_send(client_obj->remote, notify_src); break; default: crm_err("Unknown transport %d for %s", client_obj->kind, client_obj->name); } } if (local_rc != pcmk_ok && client_obj != NULL) { crm_warn("%sSync reply to %s failed: %s", sync_reply ? "" : "A-", client_obj ? client_obj->name : "", pcmk_strerror(local_rc)); } } static void local_notify_destroy_callback(gpointer data) { cib_local_notify_t *notify = data; free_xml(notify->notify_src); free(notify->client_id); free(notify); } static void check_local_notify(int bcast_id) { cib_local_notify_t *notify = NULL; if (!local_notify_queue) { return; } notify = g_hash_table_lookup(local_notify_queue, GINT_TO_POINTER(bcast_id)); if (notify) { do_local_notify(notify->notify_src, notify->client_id, notify->sync_reply, notify->from_peer); g_hash_table_remove(local_notify_queue, GINT_TO_POINTER(bcast_id)); } } static void queue_local_notify(xmlNode * notify_src, const char *client_id, gboolean sync_reply, gboolean from_peer) { cib_local_notify_t *notify = calloc(1, sizeof(cib_local_notify_t)); notify->notify_src = notify_src; notify->client_id = strdup(client_id); notify->sync_reply = sync_reply; notify->from_peer = from_peer; if (!local_notify_queue) { local_notify_queue = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, local_notify_destroy_callback); } g_hash_table_insert(local_notify_queue, GINT_TO_POINTER(cib_local_bcast_num), notify); } static void parse_local_options(crm_client_t * cib_client, int call_type, int call_options, const char *host, const char *op, gboolean * local_notify, gboolean * needs_reply, gboolean * process, gboolean * needs_forward) { if (cib_op_modifies(call_type) && !(call_options & cib_inhibit_bcast)) { /* we need to send an update anyway */ *needs_reply = TRUE; } else { *needs_reply = FALSE; } if (host == NULL && (call_options & cib_scope_local)) { crm_trace("Processing locally scoped %s op from %s", op, cib_client->name); *local_notify = TRUE; } else if (host == NULL && cib_is_master) { crm_trace("Processing master %s op locally from %s", op, cib_client->name); *local_notify = TRUE; } else if (safe_str_eq(host, cib_our_uname)) { crm_trace("Processing locally addressed %s op from %s", op, cib_client->name); *local_notify = TRUE; } else if (stand_alone) { *needs_forward = FALSE; *local_notify = TRUE; *process = TRUE; } else { crm_trace("%s op from %s needs to be forwarded to %s", op, cib_client->name, host ? host : "the master instance"); *needs_forward = TRUE; *process = FALSE; } } static gboolean parse_peer_options(int call_type, xmlNode * request, gboolean * local_notify, gboolean * needs_reply, gboolean * process, gboolean * needs_forward) { const char *op = NULL; const char *host = NULL; const char *delegated = NULL; const char *originator = crm_element_value(request, F_ORIG); const char *reply_to = crm_element_value(request, F_CIB_ISREPLY); const char *update = crm_element_value(request, F_CIB_GLOBAL_UPDATE); gboolean is_reply = safe_str_eq(reply_to, cib_our_uname); if (crm_is_true(update)) { *needs_reply = FALSE; if (is_reply) { *local_notify = TRUE; crm_trace("Processing global/peer update from %s" " that originated from us", originator); } else { crm_trace("Processing global/peer update from %s", originator); } return TRUE; } op = crm_element_value(request, F_CIB_OPERATION); if (safe_str_eq(op, "cib_shutdown_req")) { /* Always process these */ *local_notify = FALSE; if (reply_to == NULL || is_reply) { *process = TRUE; } if (is_reply) { *needs_reply = FALSE; } return *process; } if (is_reply) { crm_trace("Forward reply sent from %s to local clients", originator); *process = FALSE; *needs_reply = FALSE; *local_notify = TRUE; return TRUE; } host = crm_element_value(request, F_CIB_HOST); if (host != NULL && safe_str_eq(host, cib_our_uname)) { crm_trace("Processing request sent to us from %s", originator); return TRUE; } else if (host == NULL && cib_is_master == TRUE) { crm_trace("Processing request sent to master instance from %s", originator); return TRUE; } delegated = crm_element_value(request, F_CIB_DELEGATED); if (delegated != NULL) { crm_trace("Ignoring msg for master instance"); } else if (host != NULL) { /* this is for a specific instance and we're not it */ crm_trace("Ignoring msg for instance on %s", crm_str(host)); } else if (reply_to == NULL && cib_is_master == FALSE) { /* this is for the master instance and we're not it */ crm_trace("Ignoring reply to %s", crm_str(reply_to)); } else if (safe_str_eq(op, "cib_shutdown_req")) { if (reply_to != NULL) { crm_debug("Processing %s from %s", op, host); *needs_reply = FALSE; } else { crm_debug("Processing %s reply from %s", op, host); } return TRUE; } else { crm_err("Nothing for us to do?"); crm_log_xml_err(request, "Peer[inbound]"); } return FALSE; } static void forward_request(xmlNode * request, crm_client_t * cib_client, int call_options) { const char *op = crm_element_value(request, F_CIB_OPERATION); const char *host = crm_element_value(request, F_CIB_HOST); crm_xml_add(request, F_CIB_DELEGATED, cib_our_uname); if (host != NULL) { crm_trace("Forwarding %s op to %s", op, host); send_cluster_message(crm_get_peer(0, host), crm_msg_cib, request, FALSE); } else { crm_trace("Forwarding %s op to master instance", op); send_cluster_message(NULL, crm_msg_cib, request, FALSE); } /* Return the request to its original state */ xml_remove_prop(request, F_CIB_DELEGATED); if (call_options & cib_discard_reply) { crm_trace("Client not interested in reply"); } } static gboolean send_peer_reply(xmlNode * msg, xmlNode * result_diff, const char *originator, gboolean broadcast) { CRM_ASSERT(msg != NULL); if (broadcast) { /* this (successful) call modified the CIB _and_ the * change needs to be broadcast... * send via HA to other nodes */ int diff_add_updates = 0; int diff_add_epoch = 0; int diff_add_admin_epoch = 0; int diff_del_updates = 0; int diff_del_epoch = 0; int diff_del_admin_epoch = 0; const char *digest = NULL; CRM_LOG_ASSERT(result_diff != NULL); digest = crm_element_value(result_diff, XML_ATTR_DIGEST); cib_diff_version_details(result_diff, &diff_add_admin_epoch, &diff_add_epoch, &diff_add_updates, &diff_del_admin_epoch, &diff_del_epoch, &diff_del_updates); crm_trace("Sending update diff %d.%d.%d -> %d.%d.%d %s", diff_del_admin_epoch, diff_del_epoch, diff_del_updates, diff_add_admin_epoch, diff_add_epoch, diff_add_updates, digest); crm_xml_add(msg, F_CIB_ISREPLY, originator); crm_xml_add(msg, F_CIB_GLOBAL_UPDATE, XML_BOOLEAN_TRUE); crm_xml_add(msg, F_CIB_OPERATION, CIB_OP_APPLY_DIFF); CRM_ASSERT(digest != NULL); add_message_xml(msg, F_CIB_UPDATE_DIFF, result_diff); crm_log_xml_explicit(msg, "copy"); return send_cluster_message(NULL, crm_msg_cib, msg, TRUE); } else if (originator != NULL) { /* send reply via HA to originating node */ crm_trace("Sending request result to originator only"); crm_xml_add(msg, F_CIB_ISREPLY, originator); return send_cluster_message(crm_get_peer(0, originator), crm_msg_cib, msg, FALSE); } return FALSE; } void cib_process_request(xmlNode * request, gboolean force_synchronous, gboolean privileged, gboolean unused, crm_client_t * cib_client) { int call_type = 0; int call_options = 0; gboolean process = TRUE; gboolean is_update = TRUE; gboolean from_peer = TRUE; gboolean needs_reply = TRUE; gboolean local_notify = FALSE; gboolean needs_forward = FALSE; gboolean global_update = crm_is_true(crm_element_value(request, F_CIB_GLOBAL_UPDATE)); xmlNode *op_reply = NULL; xmlNode *result_diff = NULL; int rc = pcmk_ok; const char *op = crm_element_value(request, F_CIB_OPERATION); const char *originator = crm_element_value(request, F_ORIG); const char *host = crm_element_value(request, F_CIB_HOST); const char *target = NULL; const char *client_id = crm_element_value(request, F_CIB_CLIENTID); if (cib_client) { from_peer = FALSE; } cib_num_ops++; if (cib_num_ops == 0) { cib_num_fail = 0; cib_num_local = 0; cib_num_updates = 0; crm_info("Stats wrapped around"); } crm_element_value_int(request, F_CIB_CALLOPTS, &call_options); if (force_synchronous) { call_options |= cib_sync_call; } if (host != NULL && strlen(host) == 0) { host = NULL; } if (host) { target = host; } else if (call_options & cib_scope_local) { target = "local host"; } else { target = "master"; } if (from_peer) { crm_trace("Processing peer %s operation from %s on %s intended for %s", op, client_id, originator, target); } else { crm_xml_add(request, F_ORIG, cib_our_uname); crm_trace("Processing local %s operation from %s intended for %s", op, client_id, target); } rc = cib_get_operation_id(op, &call_type); if (rc != pcmk_ok) { /* TODO: construct error reply? */ crm_err("Pre-processing of command failed: %s", pcmk_strerror(rc)); return; } if (from_peer == FALSE) { parse_local_options(cib_client, call_type, call_options, host, op, &local_notify, &needs_reply, &process, &needs_forward); } else if (parse_peer_options(call_type, request, &local_notify, &needs_reply, &process, &needs_forward) == FALSE) { return; } is_update = cib_op_modifies(call_type); if (is_update) { cib_num_updates++; } if (call_options & cib_discard_reply) { needs_reply = is_update; local_notify = FALSE; } if (needs_forward) { const char *host = crm_element_value(request, F_CIB_HOST); const char *section = crm_element_value(request, F_CIB_SECTION); crm_info("Forwarding %s operation for section %s to %s (origin=%s/%s/%s)", op, section ? section : "'all'", host ? host : "master", originator ? originator : "local", crm_element_value(request, F_CIB_CLIENTNAME), crm_element_value(request, F_CIB_CALLID)); forward_request(request, cib_client, call_options); return; } if (cib_status != pcmk_ok) { const char *call = crm_element_value(request, F_CIB_CALLID); rc = cib_status; crm_err("Operation ignored, cluster configuration is invalid." " Please repair and restart: %s", pcmk_strerror(cib_status)); op_reply = create_xml_node(NULL, "cib-reply"); crm_xml_add(op_reply, F_TYPE, T_CIB); crm_xml_add(op_reply, F_CIB_OPERATION, op); crm_xml_add(op_reply, F_CIB_CALLID, call); crm_xml_add(op_reply, F_CIB_CLIENTID, client_id); crm_xml_add_int(op_reply, F_CIB_CALLOPTS, call_options); crm_xml_add_int(op_reply, F_CIB_RC, rc); crm_trace("Attaching reply output"); add_message_xml(op_reply, F_CIB_CALLDATA, the_cib); crm_log_xml_explicit(op_reply, "cib:reply"); } else if (process) { time_t finished = 0; int now = time(NULL); int level = LOG_INFO; const char *section = crm_element_value(request, F_CIB_SECTION); cib_num_local++; rc = cib_process_command(request, &op_reply, &result_diff, privileged); if (global_update) { switch (rc) { case pcmk_ok: level = LOG_INFO; break; case -pcmk_err_old_data: case -pcmk_err_diff_resync: case -pcmk_err_diff_failed: level = LOG_TRACE; break; default: level = LOG_ERR; } } else if (rc != pcmk_ok && is_update) { cib_num_fail++; level = LOG_WARNING; /* } else if (safe_str_eq(op, CIB_OP_QUERY)) { level = LOG_TRACE; } else if (safe_str_eq(op, CIB_OP_SLAVE)) { level = LOG_TRACE; } else if (safe_str_eq(section, XML_CIB_TAG_STATUS)) { level = LOG_TRACE; */ } do_crm_log(level, "Completed %s operation for section %s: %s (rc=%d, origin=%s/%s/%s, version=%s.%s.%s)", op, section ? section : "'all'", pcmk_strerror(rc), rc, originator ? originator : "local", crm_element_value(request, F_CIB_CLIENTNAME), crm_element_value(request, F_CIB_CALLID), the_cib ? crm_element_value(the_cib, XML_ATTR_GENERATION_ADMIN) : "0", the_cib ? crm_element_value(the_cib, XML_ATTR_GENERATION) : "0", the_cib ? crm_element_value(the_cib, XML_ATTR_NUMUPDATES) : "0"); finished = time(NULL); if (finished - now > 3) { crm_trace("%s operation took %ds to complete", op, finished - now); crm_write_blackbox(0, NULL); } if (op_reply == NULL && (needs_reply || local_notify)) { crm_err("Unexpected NULL reply to message"); crm_log_xml_err(request, "null reply"); needs_reply = FALSE; local_notify = FALSE; } } /* from now on we are the server */ if (needs_reply == FALSE || stand_alone) { /* nothing more to do... * this was a non-originating slave update */ crm_trace("Completed slave update"); } else if (rc == pcmk_ok && result_diff != NULL && !(call_options & cib_inhibit_bcast)) { gboolean broadcast = FALSE; cib_local_bcast_num++; crm_xml_add_int(request, F_CIB_LOCAL_NOTIFY_ID, cib_local_bcast_num); broadcast = send_peer_reply(request, result_diff, originator, TRUE); if (broadcast && client_id && local_notify && op_reply) { /* If we have been asked to sync the reply, * and a bcast msg has gone out, we queue the local notify * until we know the bcast message has been received */ local_notify = FALSE; crm_trace("Queuing local %ssync notification for %s", (call_options & cib_sync_call) ? "" : "a-", client_id); queue_local_notify(op_reply, client_id, (call_options & cib_sync_call), from_peer); op_reply = NULL; /* the reply is queued, so don't free here */ } } else if (call_options & cib_discard_reply) { crm_trace("Caller isn't interested in reply"); } else if (from_peer) { if (is_update == FALSE || result_diff == NULL) { crm_trace("Request not broadcast: R/O call"); } else if (call_options & cib_inhibit_bcast) { crm_trace("Request not broadcast: inhibited"); } else if (rc != pcmk_ok) { crm_trace("Request not broadcast: call failed: %s", pcmk_strerror(rc)); } else { crm_trace("Directing reply to %s", originator); } send_peer_reply(op_reply, result_diff, originator, FALSE); } if (local_notify && client_id) { crm_trace("Performing local %ssync notification for %s", (call_options & cib_sync_call) ? "" : "a-", client_id); if (process == FALSE) { do_local_notify(request, client_id, call_options & cib_sync_call, from_peer); } else { do_local_notify(op_reply, client_id, call_options & cib_sync_call, from_peer); } } free_xml(op_reply); free_xml(result_diff); return; } int cib_process_command(xmlNode * request, xmlNode ** reply, xmlNode ** cib_diff, gboolean privileged) { xmlNode *input = NULL; xmlNode *output = NULL; xmlNode *result_cib = NULL; xmlNode *current_cib = NULL; #if ENABLE_ACL xmlNode *filtered_current_cib = NULL; #endif int call_type = 0; int call_options = 0; int log_level = LOG_TRACE; const char *op = NULL; const char *section = NULL; const char *call_id = crm_element_value(request, F_CIB_CALLID); int rc = pcmk_ok; int rc2 = pcmk_ok; gboolean send_r_notify = FALSE; gboolean global_update = FALSE; gboolean config_changed = FALSE; gboolean manage_counters = TRUE; CRM_ASSERT(cib_status == pcmk_ok); *reply = NULL; *cib_diff = NULL; current_cib = the_cib; /* Start processing the request... */ op = crm_element_value(request, F_CIB_OPERATION); crm_element_value_int(request, F_CIB_CALLOPTS, &call_options); rc = cib_get_operation_id(op, &call_type); if (rc == pcmk_ok && privileged == FALSE) { rc = cib_op_can_run(call_type, call_options, privileged, global_update); } rc2 = cib_op_prepare(call_type, request, &input, §ion); if (rc == pcmk_ok) { rc = rc2; } if (rc != pcmk_ok) { crm_trace("Call setup failed: %s", pcmk_strerror(rc)); goto done; } else if (cib_op_modifies(call_type) == FALSE) { #if ENABLE_ACL if (acl_enabled(config_hash) == FALSE || acl_filter_cib(request, current_cib, current_cib, &filtered_current_cib) == FALSE) { rc = cib_perform_op(op, call_options, cib_op_func(call_type), TRUE, section, request, input, FALSE, &config_changed, current_cib, &result_cib, NULL, &output); } else if (filtered_current_cib == NULL) { crm_debug("Pre-filtered the entire cib"); rc = -EACCES; } else { crm_debug("Pre-filtered the queried cib according to the ACLs"); rc = cib_perform_op(op, call_options, cib_op_func(call_type), TRUE, section, request, input, FALSE, &config_changed, filtered_current_cib, &result_cib, NULL, &output); } #else rc = cib_perform_op(op, call_options, cib_op_func(call_type), TRUE, section, request, input, FALSE, &config_changed, current_cib, &result_cib, NULL, &output); #endif CRM_CHECK(result_cib == NULL, free_xml(result_cib)); goto done; } /* Handle a valid write action */ global_update = crm_is_true(crm_element_value(request, F_CIB_GLOBAL_UPDATE)); if (global_update) { manage_counters = FALSE; call_options |= cib_force_diff; CRM_CHECK(call_type == 3 || call_type == 4, crm_err("Call type: %d", call_type); crm_log_xml_err(request, "bad op")); } #ifdef SUPPORT_PRENOTIFY if ((call_options & cib_inhibit_notify) == 0) { cib_pre_notify(call_options, op, the_cib, input); } #endif if (rc == pcmk_ok) { if (call_options & cib_inhibit_bcast) { /* skip */ crm_trace("Skipping update: inhibit broadcast"); manage_counters = FALSE; } /* result_cib must not be modified after cib_perform_op() returns */ rc = cib_perform_op(op, call_options, cib_op_func(call_type), FALSE, section, request, input, manage_counters, &config_changed, current_cib, &result_cib, cib_diff, &output); #if ENABLE_ACL if (acl_enabled(config_hash) == TRUE && acl_check_diff(request, current_cib, result_cib, *cib_diff) == FALSE) { rc = -EACCES; } #endif if (manage_counters == FALSE) { /* If the diff is NULL at this point, its because nothing changed */ config_changed = cib_config_changed(NULL, NULL, cib_diff); } /* Always write to disk for replace ops, * this also negates the need to detect ordering changes */ if (crm_str_eq(CIB_OP_REPLACE, op, TRUE)) { config_changed = TRUE; } } if (rc == pcmk_ok && (call_options & cib_dryrun) == 0) { rc = activateCibXml(result_cib, config_changed, op); if (rc == pcmk_ok && cib_internal_config_changed(*cib_diff)) { cib_read_config(config_hash, result_cib); } if (crm_str_eq(CIB_OP_REPLACE, op, TRUE)) { if (section == NULL) { send_r_notify = TRUE; } else if (safe_str_eq(section, XML_TAG_CIB)) { send_r_notify = TRUE; } else if (safe_str_eq(section, XML_CIB_TAG_NODES)) { send_r_notify = TRUE; } else if (safe_str_eq(section, XML_CIB_TAG_STATUS)) { send_r_notify = TRUE; } } else if (crm_str_eq(CIB_OP_ERASE, op, TRUE)) { send_r_notify = TRUE; } } else if (rc == -pcmk_err_dtd_validation) { if (output != NULL) { crm_log_xml_info(output, "cib:output"); free_xml(output); } #if ENABLE_ACL { xmlNode *filtered_result_cib = NULL; if (acl_enabled(config_hash) == FALSE || acl_filter_cib(request, current_cib, result_cib, &filtered_result_cib) == FALSE) { output = result_cib; } else { crm_debug("Filtered the result cib for output according to the ACLs"); output = filtered_result_cib; if (result_cib != NULL) { free_xml(result_cib); } } } #else output = result_cib; #endif } else { free_xml(result_cib); } if ((call_options & cib_inhibit_notify) == 0) { const char *client = crm_element_value(request, F_CIB_CLIENTNAME); crm_trace("Sending notifications"); #ifdef SUPPORT_POSTNOTIFY cib_post_notify(call_options, op, input, rc, the_cib); #endif cib_diff_notify(call_options, client, call_id, op, input, rc, *cib_diff); } if (send_r_notify) { const char *origin = crm_element_value(request, F_ORIG); cib_replace_notify(origin, the_cib, rc, *cib_diff); } if (rc != pcmk_ok) { log_level = LOG_TRACE; if (rc == -pcmk_err_dtd_validation && global_update) { log_level = LOG_WARNING; crm_log_xml_info(input, "cib:global_update"); } } else if (config_changed) { log_level = LOG_TRACE; if (cib_is_master) { log_level = LOG_NOTICE; } } else if (cib_is_master) { log_level = LOG_TRACE; } log_cib_diff(log_level, *cib_diff, "cib:diff"); done: if ((call_options & cib_discard_reply) == 0) { const char *caller = crm_element_value(request, F_CIB_CLIENTID); *reply = create_xml_node(NULL, "cib-reply"); crm_xml_add(*reply, F_TYPE, T_CIB); crm_xml_add(*reply, F_CIB_OPERATION, op); crm_xml_add(*reply, F_CIB_CALLID, call_id); crm_xml_add(*reply, F_CIB_CLIENTID, caller); crm_xml_add_int(*reply, F_CIB_CALLOPTS, call_options); crm_xml_add_int(*reply, F_CIB_RC, rc); if (output != NULL) { crm_trace("Attaching reply output"); add_message_xml(*reply, F_CIB_CALLDATA, output); } crm_log_xml_explicit(*reply, "cib:reply"); } crm_trace("cleanup"); #if ENABLE_ACL if (filtered_current_cib != NULL) { free_xml(filtered_current_cib); } #endif if (call_type >= 0) { cib_op_cleanup(call_type, call_options, &input, &output); } crm_trace("done"); return rc; } gint cib_GCompareFunc(gconstpointer a, gconstpointer b) { const xmlNode *a_msg = a; const xmlNode *b_msg = b; int msg_a_id = 0; int msg_b_id = 0; const char *value = NULL; value = crm_element_value_const(a_msg, F_CIB_CALLID); msg_a_id = crm_parse_int(value, NULL); value = crm_element_value_const(b_msg, F_CIB_CALLID); msg_b_id = crm_parse_int(value, NULL); if (msg_a_id == msg_b_id) { return 0; } else if (msg_a_id < msg_b_id) { return -1; } return 1; } #if SUPPORT_HEARTBEAT void cib_ha_peer_callback(HA_Message * msg, void *private_data) { xmlNode *xml = convert_ha_message(NULL, msg, __FUNCTION__); cib_peer_callback(xml, private_data); free_xml(xml); } #endif void cib_peer_callback(xmlNode * msg, void *private_data) { const char *reason = NULL; const char *originator = crm_element_value(msg, F_ORIG); if (originator == NULL || crm_str_eq(originator, cib_our_uname, TRUE)) { /* message is from ourselves */ int bcast_id = 0; if (!(crm_element_value_int(msg, F_CIB_LOCAL_NOTIFY_ID, &bcast_id))) { check_local_notify(bcast_id); } return; } else if (crm_peer_cache == NULL) { reason = "membership not established"; goto bail; } if (crm_element_value(msg, F_CIB_CLIENTNAME) == NULL) { crm_xml_add(msg, F_CIB_CLIENTNAME, originator); } /* crm_log_xml_trace("Peer[inbound]", msg); */ cib_process_request(msg, FALSE, TRUE, TRUE, NULL); return; bail: if (reason) { const char *seq = crm_element_value(msg, F_SEQ); const char *op = crm_element_value(msg, F_CIB_OPERATION); crm_warn("Discarding %s message (%s) from %s: %s", op, seq, originator, reason); } } #if SUPPORT_HEARTBEAT extern oc_ev_t *cib_ev_token; static void *ccm_library = NULL; int (*ccm_api_callback_done) (void *cookie) = NULL; int (*ccm_api_handle_event) (const oc_ev_t * token) = NULL; void cib_client_status_callback(const char *node, const char *client, const char *status, void *private) { crm_node_t *peer = NULL; if (safe_str_eq(client, CRM_SYSTEM_CIB)) { crm_info("Status update: Client %s/%s now has status [%s]", node, client, status); if (safe_str_eq(status, JOINSTATUS)) { status = ONLINESTATUS; } else if (safe_str_eq(status, LEAVESTATUS)) { status = OFFLINESTATUS; } peer = crm_get_peer(0, node); crm_update_peer_proc(__FUNCTION__, peer, crm_proc_cib, status); } return; } int cib_ccm_dispatch(gpointer user_data) { int rc = 0; oc_ev_t *ccm_token = (oc_ev_t *) user_data; crm_trace("received callback"); if (ccm_api_handle_event == NULL) { ccm_api_handle_event = find_library_function(&ccm_library, CCM_LIBRARY, "oc_ev_handle_event", 1); } rc = (*ccm_api_handle_event) (ccm_token); if (0 == rc) { return 0; } crm_err("CCM connection appears to have failed: rc=%d.", rc); /* eventually it might be nice to recover and reconnect... but until then... */ crm_err("Exiting to recover from CCM connection failure"); return crm_exit(ENOTCONN); } int current_instance = 0; void cib_ccm_msg_callback(oc_ed_t event, void *cookie, size_t size, const void *data) { gboolean update_id = FALSE; const oc_ev_membership_t *membership = data; CRM_ASSERT(membership != NULL); crm_info("Processing CCM event=%s (id=%d)", ccm_event_name(event), membership->m_instance); if (current_instance > membership->m_instance) { crm_err("Membership instance ID went backwards! %d->%d", current_instance, membership->m_instance); CRM_ASSERT(current_instance <= membership->m_instance); } switch (event) { case OC_EV_MS_NEW_MEMBERSHIP: case OC_EV_MS_INVALID: update_id = TRUE; break; case OC_EV_MS_PRIMARY_RESTORED: update_id = TRUE; break; case OC_EV_MS_NOT_PRIMARY: crm_trace("Ignoring transitional CCM event: %s", ccm_event_name(event)); break; case OC_EV_MS_EVICTED: crm_err("Evicted from CCM: %s", ccm_event_name(event)); break; default: crm_err("Unknown CCM event: %d", event); } if (update_id) { unsigned int lpc = 0; CRM_CHECK(membership != NULL, return); current_instance = membership->m_instance; for (lpc = 0; lpc < membership->m_n_out; lpc++) { crm_update_ccm_node(membership, lpc + membership->m_out_idx, CRM_NODE_LOST, current_instance); } for (lpc = 0; lpc < membership->m_n_member; lpc++) { crm_update_ccm_node(membership, lpc + membership->m_memb_idx, CRM_NODE_ACTIVE, current_instance); } } if (ccm_api_callback_done == NULL) { ccm_api_callback_done = find_library_function(&ccm_library, CCM_LIBRARY, "oc_ev_callback_done", 1); } (*ccm_api_callback_done) (cookie); return; } #endif gboolean can_write(int flags) { return TRUE; } static gboolean cib_force_exit(gpointer data) { crm_notice("Forcing exit!"); terminate_cib(__FUNCTION__, TRUE); return FALSE; } static void disconnect_remote_client(gpointer key, gpointer value, gpointer user_data) { crm_client_t *a_client = value; crm_err("Disconnecting %s... Not implemented", crm_str(a_client->name)); } void cib_shutdown(int nsig) { struct qb_ipcs_stats srv_stats; if (cib_shutdown_flag == FALSE) { int disconnects = 0; qb_ipcs_connection_t *c = NULL; cib_shutdown_flag = TRUE; c = qb_ipcs_connection_first_get(ipcs_rw); while (c != NULL) { qb_ipcs_connection_t *last = c; c = qb_ipcs_connection_next_get(ipcs_rw, last); crm_debug("Disconnecting r/w client %p...", last); qb_ipcs_disconnect(last); qb_ipcs_connection_unref(last); disconnects++; } c = qb_ipcs_connection_first_get(ipcs_ro); while (c != NULL) { qb_ipcs_connection_t *last = c; c = qb_ipcs_connection_next_get(ipcs_ro, last); crm_debug("Disconnecting r/o client %p...", last); qb_ipcs_disconnect(last); qb_ipcs_connection_unref(last); disconnects++; } c = qb_ipcs_connection_first_get(ipcs_shm); while (c != NULL) { qb_ipcs_connection_t *last = c; c = qb_ipcs_connection_next_get(ipcs_shm, last); crm_debug("Disconnecting non-blocking r/w client %p...", last); qb_ipcs_disconnect(last); qb_ipcs_connection_unref(last); disconnects++; } disconnects += crm_hash_table_size(client_connections); crm_debug("Disconnecting %d remote clients", crm_hash_table_size(client_connections)); g_hash_table_foreach(client_connections, disconnect_remote_client, NULL); crm_info("Disconnected %d clients", disconnects); } qb_ipcs_stats_get(ipcs_rw, &srv_stats, QB_FALSE); if (crm_hash_table_size(client_connections) == 0) { crm_info("All clients disconnected (%d)", srv_stats.active_connections); initiate_exit(); } else { crm_info("Waiting on %d clients to disconnect (%d)", crm_hash_table_size(client_connections), srv_stats.active_connections); } } void initiate_exit(void) { int active = 0; xmlNode *leaving = NULL; active = crm_active_peers(); if (active < 2) { terminate_cib(__FUNCTION__, FALSE); return; } crm_info("Sending disconnect notification to %d peers...", active); leaving = create_xml_node(NULL, "exit-notification"); crm_xml_add(leaving, F_TYPE, "cib"); crm_xml_add(leaving, F_CIB_OPERATION, "cib_shutdown_req"); send_cluster_message(NULL, crm_msg_cib, leaving, TRUE); free_xml(leaving); g_timeout_add(crm_get_msec("5s"), cib_force_exit, NULL); } extern int remote_fd; extern int remote_tls_fd; void terminate_cib(const char *caller, gboolean fast) { if (remote_fd > 0) { close(remote_fd); remote_fd = 0; } if (remote_tls_fd > 0) { close(remote_tls_fd); remote_tls_fd = 0; } if (!fast) { crm_info("%s: Disconnecting from cluster infrastructure", caller); crm_cluster_disconnect(&crm_cluster); } uninitializeCib(); crm_info("%s: Exiting%s...", caller, fast ? " fast" : mainloop ? " from mainloop" : ""); if (fast == FALSE && mainloop != NULL && g_main_is_running(mainloop)) { g_main_quit(mainloop); } else { qb_ipcs_destroy(ipcs_ro); qb_ipcs_destroy(ipcs_rw); qb_ipcs_destroy(ipcs_shm); if (fast) { crm_exit(EINVAL); } else { crm_exit(pcmk_ok); } } } pacemaker-master/cib/callbacks.h000066400000000000000000000053331217637305600171420ustar00rootroot00000000000000/* * Copyright (C) 2004 Andrew Beekhof * * 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 2 of the License, or (at your option) any later version. * * This software 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 library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include #include #include #include #include #include #include #include #ifdef HAVE_GNUTLS_GNUTLS_H # undef KEYFILE # include #endif extern gboolean cib_is_master; extern GHashTable *peer_hash; extern GHashTable *config_hash; /* *INDENT-OFF* */ enum cib_notifications { cib_notify_pre = 0x0001, cib_notify_post = 0x0002, cib_notify_replace = 0x0004, cib_notify_confirm = 0x0008, cib_notify_diff = 0x0010, }; /* *INDENT-ON* */ typedef struct cib_operation_s { const char *operation; gboolean modifies_cib; gboolean needs_privileges; gboolean needs_quorum; int (*prepare) (xmlNode *, xmlNode **, const char **); int (*cleanup) (int, xmlNode **, xmlNode **); int (*fn) (const char *, int, const char *, xmlNode *, xmlNode *, xmlNode *, xmlNode **, xmlNode **); } cib_operation_t; extern struct qb_ipcs_service_handlers ipc_ro_callbacks; extern struct qb_ipcs_service_handlers ipc_rw_callbacks; extern qb_ipcs_service_t *ipcs_ro; extern qb_ipcs_service_t *ipcs_rw; extern qb_ipcs_service_t *ipcs_shm; extern void cib_peer_callback(xmlNode * msg, void *private_data); extern void cib_client_status_callback(const char *node, const char *client, const char *status, void *private); extern void cib_common_callback_worker(uint32_t id, uint32_t flags, xmlNode * op_request, crm_client_t * cib_client, gboolean privileged); void cib_shutdown(int nsig); void initiate_exit(void); void terminate_cib(const char *caller, gboolean fast); #if SUPPORT_HEARTBEAT extern void cib_ha_peer_callback(HA_Message * msg, void *private_data); extern int cib_ccm_dispatch(gpointer user_data); extern void cib_ccm_msg_callback(oc_ed_t event, void *cookie, size_t size, const void *data); #endif pacemaker-master/cib/cib.pam000066400000000000000000000003571217637305600163070ustar00rootroot00000000000000# login: auth account password session # may require permission to read /etc/shadow auth include common-auth account include common-account password include common-password session include common-session pacemaker-master/cib/cibio.h000066400000000000000000000034251217637305600163100ustar00rootroot00000000000000/* * Copyright (C) 2004 Andrew Beekhof * * 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 2 of the License, or (at your option) any later version. * * This software 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 library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef CIB_IO__H # define CIB_IO__H # include # include # include # include # include # include # include # include extern gboolean initialized; extern xmlNode *the_cib; extern xmlNode *node_search; extern xmlNode *resource_search; extern xmlNode *constraint_search; extern xmlNode *status_search; extern xmlNode *get_the_CIB(void); extern int initializeCib(xmlNode * cib); extern gboolean uninitializeCib(void); extern xmlNode *createEmptyCib(void); extern gboolean verifyCibXml(xmlNode * cib); extern xmlNode *readCibXml(char *buffer); extern xmlNode *readCibXmlFile(const char *dir, const char *file, gboolean discard_status); extern int activateCibBuffer(char *buffer, const char *filename); extern int activateCibXml(xmlNode * doc, gboolean to_disk, const char *op); extern crm_trigger_t *cib_writer; extern gboolean cib_writes_enabled; /* extern xmlNode *server_get_cib_copy(void); */ #endif pacemaker-master/cib/cibmessages.h000066400000000000000000000070601217637305600175070ustar00rootroot00000000000000/* * Copyright (C) 2004 Andrew Beekhof * * 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 2 of the License, or (at your option) any later version. * * This software 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 library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef CIB_MESSAGES__H # define CIB_MESSAGES__H extern xmlNode *createCibRequest(gboolean isLocal, const char *operation, const char *section, const char *verbose, xmlNode * data); extern int cib_process_shutdown_req(const char *op, int options, const char *section, xmlNode * req, xmlNode * input, xmlNode * existing_cib, xmlNode ** result_cib, xmlNode ** answer); extern int cib_process_default(const char *op, int options, const char *section, xmlNode * req, xmlNode * input, xmlNode * existing_cib, xmlNode ** result_cib, xmlNode ** answer); extern int cib_process_quit(const char *op, int options, const char *section, xmlNode * req, xmlNode * input, xmlNode * existing_cib, xmlNode ** result_cib, xmlNode ** answer); extern int cib_process_ping(const char *op, int options, const char *section, xmlNode * req, xmlNode * input, xmlNode * existing_cib, xmlNode ** result_cib, xmlNode ** answer); extern int cib_process_readwrite(const char *op, int options, const char *section, xmlNode * req, xmlNode * input, xmlNode * existing_cib, xmlNode ** result_cib, xmlNode ** answer); extern int cib_process_replace_svr(const char *op, int options, const char *section, xmlNode * req, xmlNode * input, xmlNode * existing_cib, xmlNode ** result_cib, xmlNode ** answer); extern int cib_server_process_diff(const char *op, int options, const char *section, xmlNode * req, xmlNode * input, xmlNode * existing_cib, xmlNode ** result_cib, xmlNode ** answer); extern int cib_process_sync(const char *op, int options, const char *section, xmlNode * req, xmlNode * input, xmlNode * existing_cib, xmlNode ** result_cib, xmlNode ** answer); extern int cib_process_sync_one(const char *op, int options, const char *section, xmlNode * req, xmlNode * input, xmlNode * existing_cib, xmlNode ** result_cib, xmlNode ** answer); extern int cib_process_delete_absolute(const char *op, int options, const char *section, xmlNode * req, xmlNode * input, xmlNode * existing_cib, xmlNode ** result_cib, xmlNode ** answer); #endif pacemaker-master/cib/cibmon.c000066400000000000000000000137511217637305600164700ustar00rootroot00000000000000 /* * Copyright (C) 2004 Andrew Beekhof * * 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 2 of the License, or (at your option) any later version. * * This software 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 library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include <../lib/pengine/unpack.h> #include #ifdef HAVE_GETOPT_H # include #endif int max_failures = 30; int exit_code = pcmk_ok; gboolean log_diffs = FALSE; gboolean log_updates = FALSE; GMainLoop *mainloop = NULL; void usage(const char *cmd, int exit_status); void cib_connection_destroy(gpointer user_data); void cibmon_shutdown(int nsig); void cibmon_diff(const char *event, xmlNode * msg); cib_t *cib = NULL; xmlNode *cib_copy = NULL; #define OPTARGS "V?m:du" int main(int argc, char **argv) { int argerr = 0; int flag; int attempts = 0; #ifdef HAVE_GETOPT_H int option_index = 0; static struct option long_options[] = { /* Top-level Options */ {"verbose", 0, 0, 'V'}, {"help", 0, 0, '?'}, {"log-diffs", 0, 0, 'd'}, {"log-updates", 0, 0, 'u'}, {"max-conn-fail", 1, 0, 'm'}, {0, 0, 0, 0} }; #endif crm_log_cli_init("cibmon"); crm_signal(SIGTERM, cibmon_shutdown); while (1) { #ifdef HAVE_GETOPT_H flag = getopt_long(argc, argv, OPTARGS, long_options, &option_index); #else flag = getopt(argc, argv, OPTARGS); #endif if (flag == -1) break; switch (flag) { case 'V': crm_bump_log_level(argc, argv); break; case '?': usage(crm_system_name, EX_OK); break; case 'd': log_diffs = TRUE; break; case 'u': log_updates = TRUE; break; case 'm': max_failures = crm_parse_int(optarg, "30"); break; default: printf("Argument code 0%o (%c)" " is not (?yet?) supported\n", flag, flag); ++argerr; break; } } if (optind < argc) { printf("non-option ARGV-elements: "); while (optind < argc) printf("%s ", argv[optind++]); printf("\n"); } if (optind > argc) { ++argerr; } if (argerr) { usage(crm_system_name, EX_USAGE); } cib = cib_new(); do { sleep(1); exit_code = cib->cmds->signon(cib, crm_system_name, cib_query); } while (exit_code == -ENOTCONN && attempts++ < max_failures); if (exit_code != pcmk_ok) { crm_err("Signon to CIB failed: %s", pcmk_strerror(exit_code)); } if (exit_code == pcmk_ok) { crm_debug("Setting dnotify"); exit_code = cib->cmds->set_connection_dnotify(cib, cib_connection_destroy); } crm_debug("Setting diff callback"); exit_code = cib->cmds->add_notify_callback(cib, T_CIB_DIFF_NOTIFY, cibmon_diff); if (exit_code != pcmk_ok) { crm_err("Failed to set %s callback: %s", T_CIB_DIFF_NOTIFY, pcmk_strerror(exit_code)); } if (exit_code != pcmk_ok) { crm_err("Setup failed, could not monitor CIB actions"); return -exit_code; } mainloop = g_main_new(FALSE); crm_info("Starting mainloop"); g_main_run(mainloop); crm_trace("%s exiting normally", crm_system_name); fflush(stderr); return -exit_code; } void usage(const char *cmd, int exit_status) { FILE *stream; stream = exit_status != 0 ? stderr : stdout; fflush(stream); crm_exit(exit_status); } void cib_connection_destroy(gpointer user_data) { cib_t *conn = user_data; crm_err("Connection to the CIB terminated... exiting"); conn->cmds->signoff(conn); /* Ensure IPC is cleaned up */ g_main_quit(mainloop); return; } void cibmon_diff(const char *event, xmlNode * msg) { int rc = -1; const char *op = NULL; unsigned int log_level = LOG_INFO; xmlNode *diff = NULL; xmlNode *cib_last = NULL; xmlNode *update = get_message_xml(msg, F_CIB_UPDATE); if (msg == NULL) { crm_err("NULL update"); return; } crm_element_value_int(msg, F_CIB_RC, &rc); op = crm_element_value(msg, F_CIB_OPERATION); diff = get_message_xml(msg, F_CIB_UPDATE_RESULT); if (rc < pcmk_ok) { log_level = LOG_WARNING; do_crm_log(log_level, "[%s] %s ABORTED: %s", event, op, pcmk_strerror(rc)); return; } if (log_diffs) { log_cib_diff(log_level, diff, op); } if (log_updates && update != NULL) { crm_log_xml_trace(update, "raw_update"); } if (cib_copy != NULL) { cib_last = cib_copy; cib_copy = NULL; rc = cib_process_diff(op, cib_force_diff, NULL, NULL, diff, cib_last, &cib_copy, NULL); if (rc != pcmk_ok) { crm_debug("Update didn't apply, requesting full copy: %s", pcmk_strerror(rc)); free_xml(cib_copy); cib_copy = NULL; } } if (cib_copy == NULL) { cib_copy = get_cib_copy(cib); } free_xml(cib_last); } void cibmon_shutdown(int nsig) { crm_exit(pcmk_ok); } pacemaker-master/cib/common.c000066400000000000000000000245011217637305600165040ustar00rootroot00000000000000/* * Copyright (C) 2008 Andrew Beekhof * * 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 2 of the License, or (at your option) any later version. * * This software 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 library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "common.h" extern gboolean cib_is_master; extern const char *cib_root; gboolean stand_alone = FALSE; extern int cib_status; extern gboolean can_write(int flags); extern int cib_perform_command(xmlNode * request, xmlNode ** reply, xmlNode ** cib_diff, gboolean privileged); static xmlNode * cib_prepare_common(xmlNode * root, const char *section) { xmlNode *data = NULL; /* extract the CIB from the fragment */ if (root == NULL) { return NULL; } else if (safe_str_eq(crm_element_name(root), XML_TAG_FRAGMENT) || safe_str_eq(crm_element_name(root), F_CRM_DATA) || safe_str_eq(crm_element_name(root), F_CIB_CALLDATA)) { data = first_named_child(root, XML_TAG_CIB); } else { data = root; } /* grab the section specified for the command */ if (section != NULL && data != NULL && crm_str_eq(crm_element_name(data), XML_TAG_CIB, TRUE)) { data = get_object_root(section, data); } /* crm_log_xml_trace(root, "cib:input"); */ return data; } static int cib_prepare_none(xmlNode * request, xmlNode ** data, const char **section) { *data = NULL; *section = crm_element_value(request, F_CIB_SECTION); return pcmk_ok; } static int cib_prepare_data(xmlNode * request, xmlNode ** data, const char **section) { xmlNode *input_fragment = get_message_xml(request, F_CIB_CALLDATA); *section = crm_element_value(request, F_CIB_SECTION); *data = cib_prepare_common(input_fragment, *section); /* crm_log_xml_debug(*data, "data"); */ return pcmk_ok; } static int cib_prepare_sync(xmlNode * request, xmlNode ** data, const char **section) { *data = NULL; *section = crm_element_value(request, F_CIB_SECTION); return pcmk_ok; } static int cib_prepare_diff(xmlNode * request, xmlNode ** data, const char **section) { xmlNode *input_fragment = NULL; const char *update = crm_element_value(request, F_CIB_GLOBAL_UPDATE); *data = NULL; *section = NULL; if (crm_is_true(update)) { input_fragment = get_message_xml(request, F_CIB_UPDATE_DIFF); } else { input_fragment = get_message_xml(request, F_CIB_CALLDATA); } CRM_CHECK(input_fragment != NULL, crm_log_xml_warn(request, "no input")); *data = cib_prepare_common(input_fragment, NULL); return pcmk_ok; } static int cib_cleanup_query(int options, xmlNode ** data, xmlNode ** output) { CRM_LOG_ASSERT(*data == NULL); if ((options & cib_no_children) || safe_str_eq(crm_element_name(*output), "xpath-query")) { free_xml(*output); } return pcmk_ok; } static int cib_cleanup_data(int options, xmlNode ** data, xmlNode ** output) { free_xml(*output); *data = NULL; return pcmk_ok; } static int cib_cleanup_output(int options, xmlNode ** data, xmlNode ** output) { free_xml(*output); return pcmk_ok; } static int cib_cleanup_none(int options, xmlNode ** data, xmlNode ** output) { CRM_LOG_ASSERT(*data == NULL); CRM_LOG_ASSERT(*output == NULL); return pcmk_ok; } static int cib_cleanup_sync(int options, xmlNode ** data, xmlNode ** output) { /* data is non-NULL but doesnt need to be free'd */ CRM_LOG_ASSERT(*data == NULL); CRM_LOG_ASSERT(*output == NULL); return pcmk_ok; } /* typedef struct cib_operation_s { const char* operation; gboolean modifies_cib; gboolean needs_privileges; gboolean needs_quorum; int (*prepare)(xmlNode *, xmlNode**, const char **); int (*cleanup)(xmlNode**, xmlNode**); int (*fn)( const char *, int, const char *, xmlNode*, xmlNode*, xmlNode**, xmlNode**); } cib_operation_t; */ /* technically bump does modify the cib... * but we want to split the "bump" from the "sync" */ /* *INDENT-OFF* */ static cib_operation_t cib_server_ops[] = { {NULL, FALSE, FALSE, FALSE, cib_prepare_none, cib_cleanup_none, cib_process_default}, {CIB_OP_QUERY, FALSE, FALSE, FALSE, cib_prepare_none, cib_cleanup_query, cib_process_query}, {CIB_OP_MODIFY, TRUE, TRUE, TRUE, cib_prepare_data, cib_cleanup_data, cib_process_modify}, {CIB_OP_APPLY_DIFF,TRUE, TRUE, TRUE, cib_prepare_diff, cib_cleanup_data, cib_server_process_diff}, {CIB_OP_REPLACE, TRUE, TRUE, TRUE, cib_prepare_data, cib_cleanup_data, cib_process_replace_svr}, {CIB_OP_CREATE, TRUE, TRUE, TRUE, cib_prepare_data, cib_cleanup_data, cib_process_create}, {CIB_OP_DELETE, TRUE, TRUE, TRUE, cib_prepare_data, cib_cleanup_data, cib_process_delete}, {CIB_OP_SYNC, FALSE, TRUE, FALSE, cib_prepare_sync, cib_cleanup_sync, cib_process_sync}, {CIB_OP_BUMP, TRUE, TRUE, TRUE, cib_prepare_none, cib_cleanup_output, cib_process_bump}, {CIB_OP_ERASE, TRUE, TRUE, TRUE, cib_prepare_none, cib_cleanup_output, cib_process_erase}, {CRM_OP_NOOP, FALSE, FALSE, FALSE, cib_prepare_none, cib_cleanup_none, cib_process_default}, {CIB_OP_DELETE_ALT,TRUE, TRUE, TRUE, cib_prepare_data, cib_cleanup_data, cib_process_delete_absolute}, {CIB_OP_UPGRADE, TRUE, TRUE, TRUE, cib_prepare_none, cib_cleanup_output, cib_process_upgrade}, {CIB_OP_SLAVE, FALSE, TRUE, FALSE, cib_prepare_none, cib_cleanup_none, cib_process_readwrite}, {CIB_OP_SLAVEALL, FALSE, TRUE, FALSE, cib_prepare_none, cib_cleanup_none, cib_process_readwrite}, {CIB_OP_SYNC_ONE, FALSE, TRUE, FALSE, cib_prepare_sync, cib_cleanup_sync, cib_process_sync_one}, {CIB_OP_MASTER, TRUE, TRUE, FALSE, cib_prepare_data, cib_cleanup_data, cib_process_readwrite}, {CIB_OP_ISMASTER, FALSE, TRUE, FALSE, cib_prepare_none, cib_cleanup_none, cib_process_readwrite}, {"cib_shutdown_req",FALSE, TRUE, FALSE, cib_prepare_sync, cib_cleanup_sync, cib_process_shutdown_req}, {CRM_OP_PING, FALSE, FALSE, FALSE, cib_prepare_none, cib_cleanup_output, cib_process_ping}, }; /* *INDENT-ON* */ int cib_get_operation_id(const char *op, int *operation) { static GHashTable *operation_hash = NULL; if (operation_hash == NULL) { int lpc = 0; int max_msg_types = DIMOF(cib_server_ops); operation_hash = g_hash_table_new_full(crm_str_hash, g_str_equal, NULL, g_hash_destroy_str); for (lpc = 1; lpc < max_msg_types; lpc++) { int *value = malloc(sizeof(int)); if(value) { *value = lpc; g_hash_table_insert(operation_hash, (gpointer) cib_server_ops[lpc].operation, value); } } } if (op != NULL) { int *value = g_hash_table_lookup(operation_hash, op); if (value) { *operation = *value; return pcmk_ok; } } crm_err("Operation %s is not valid", op); *operation = -1; return -EINVAL; } xmlNode * cib_msg_copy(xmlNode * msg, gboolean with_data) { int lpc = 0; const char *field = NULL; const char *value = NULL; xmlNode *value_struct = NULL; static const char *field_list[] = { F_XML_TAGNAME, F_TYPE, F_CIB_CLIENTID, F_CIB_CALLOPTS, F_CIB_CALLID, F_CIB_OPERATION, F_CIB_ISREPLY, F_CIB_SECTION, F_CIB_HOST, F_CIB_RC, F_CIB_DELEGATED, F_CIB_OBJID, F_CIB_OBJTYPE, F_CIB_EXISTING, F_CIB_SEENCOUNT, F_CIB_TIMEOUT, F_CIB_CALLBACK_TOKEN, F_CIB_GLOBAL_UPDATE, F_CIB_CLIENTNAME, #if ENABLE_ACL F_CIB_USER, #endif F_CIB_NOTIFY_TYPE, F_CIB_NOTIFY_ACTIVATE }; static const char *data_list[] = { F_CIB_CALLDATA, F_CIB_UPDATE, F_CIB_UPDATE_RESULT }; xmlNode *copy = create_xml_node(NULL, "copy"); CRM_ASSERT(copy != NULL); for (lpc = 0; lpc < DIMOF(field_list); lpc++) { field = field_list[lpc]; value = crm_element_value(msg, field); if (value != NULL) { crm_xml_add(copy, field, value); } } for (lpc = 0; with_data && lpc < DIMOF(data_list); lpc++) { field = data_list[lpc]; value_struct = get_message_xml(msg, field); if (value_struct != NULL) { add_message_xml(copy, field, value_struct); } } return copy; } cib_op_t * cib_op_func(int call_type) { return &(cib_server_ops[call_type].fn); } gboolean cib_op_modifies(int call_type) { return cib_server_ops[call_type].modifies_cib; } int cib_op_can_run(int call_type, int call_options, gboolean privileged, gboolean global_update) { if (privileged == FALSE && cib_server_ops[call_type].needs_privileges) { /* abort */ return -EACCES; } #if 0 if (rc == pcmk_ok && stand_alone == FALSE && global_update == FALSE && (call_options & cib_quorum_override) == 0 && cib_server_ops[call_type].needs_quorum) { return -pcmk_err_no_quorum; } #endif return pcmk_ok; } int cib_op_prepare(int call_type, xmlNode * request, xmlNode ** input, const char **section) { crm_trace("Prepare %d", call_type); return cib_server_ops[call_type].prepare(request, input, section); } int cib_op_cleanup(int call_type, int options, xmlNode ** input, xmlNode ** output) { crm_trace("Cleanup %d", call_type); return cib_server_ops[call_type].cleanup(options, input, output); } pacemaker-master/cib/common.h000066400000000000000000000026521217637305600165140ustar00rootroot00000000000000/* * Copyright (C) 2004 Andrew Beekhof * * 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 2 of the License, or (at your option) any later version. * * This software 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 library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include extern xmlNode *cib_msg_copy(xmlNode * msg, gboolean with_data); extern xmlNode *cib_construct_reply(xmlNode * request, xmlNode * output, int rc); extern int cib_get_operation_id(const char *op, int *operation); extern cib_op_t *cib_op_func(int call_type); extern gboolean cib_op_modifies(int call_type); extern int cib_op_prepare(int call_type, xmlNode * request, xmlNode ** input, const char **section); extern int cib_op_cleanup(int call_type, int options, xmlNode ** input, xmlNode ** output); extern int cib_op_can_run(int call_type, int call_options, gboolean privileged, gboolean global_update); pacemaker-master/cib/io.c000066400000000000000000000536631217637305600156360ustar00rootroot00000000000000/* * Copyright (C) 2004 Andrew Beekhof * * 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 2 of the License, or (at your option) any later version. * * This software 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 library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define CIB_SERIES "cib" #define CIB_SERIES_MAX 100 #define CIB_SERIES_BZIP FALSE /* Must be false due to the way archived * copies are created - ie. with calls to * link() */ extern const char *cib_root; #define CIB_WRITE_PARANOIA 0 const char *local_resource_path[] = { XML_CIB_TAG_STATUS, }; const char *resource_path[] = { XML_CIB_TAG_RESOURCES, }; const char *node_path[] = { XML_CIB_TAG_NODES, }; const char *constraint_path[] = { XML_CIB_TAG_CONSTRAINTS, }; crm_trigger_t *cib_writer = NULL; gboolean initialized = FALSE; xmlNode *node_search = NULL; xmlNode *resource_search = NULL; xmlNode *constraint_search = NULL; xmlNode *status_search = NULL; extern int cib_status; int set_connected_peers(xmlNode * xml_obj); void GHFunc_count_peers(gpointer key, gpointer value, gpointer user_data); int write_cib_contents(gpointer p); extern void cib_cleanup(void); static gboolean validate_cib_digest(xmlNode * local_cib, const char *sigfile) { char *digest = NULL; char *expected = NULL; gboolean passed = FALSE; FILE *expected_strm = NULL; int start = 0, length = 0, read_len = 0; CRM_ASSERT(sigfile != NULL); expected_strm = fopen(sigfile, "r"); if (expected_strm == NULL && errno == ENOENT) { crm_warn("No on-disk digest present"); return TRUE; } else if (expected_strm == NULL) { crm_perror(LOG_ERR, "Could not open signature file %s for reading", sigfile); goto bail; } if (local_cib != NULL) { digest = calculate_on_disk_digest(local_cib); } start = ftell(expected_strm); fseek(expected_strm, 0L, SEEK_END); length = ftell(expected_strm); fseek(expected_strm, 0L, start); CRM_ASSERT(length >= 0); CRM_ASSERT(start == ftell(expected_strm)); if (length > 0) { crm_trace("Reading %d bytes from file", length); expected = calloc(1, (length + 1)); read_len = fread(expected, 1, length, expected_strm); /* Coverity: False positive */ CRM_ASSERT(read_len == length); } fclose(expected_strm); bail: if (expected == NULL) { crm_err("On-disk digest is empty"); } else if (safe_str_eq(expected, digest)) { crm_trace("Digest comparision passed: %s", digest); passed = TRUE; } else { crm_err("Digest comparision failed: expected %s (%s), calculated %s", expected, sigfile, digest); } free(digest); free(expected); return passed; } static int write_cib_digest(xmlNode * local_cib, const char *digest_file, int fd, char *digest) { int rc = 0; char *local_digest = NULL; FILE *digest_strm = fdopen(fd, "w"); if (digest_strm == NULL) { crm_perror(LOG_ERR, "Cannot open signature file %s for writing", digest_file); return -1; } if (digest == NULL) { local_digest = calculate_on_disk_digest(local_cib); CRM_ASSERT(digest != NULL); digest = local_digest; } rc = fprintf(digest_strm, "%s", digest); if (rc < 0) { crm_perror(LOG_ERR, "Cannot write to signature file %s", digest_file); } CRM_ASSERT(digest_strm != NULL); if (fflush(digest_strm) != 0) { crm_perror(LOG_ERR, "Couldnt flush the contents of %s", digest_file); rc = -1; } if (fsync(fileno(digest_strm)) < 0) { crm_perror(LOG_ERR, "Couldnt sync the contents of %s", digest_file); rc = -1; } fclose(digest_strm); free(local_digest); return rc; } static gboolean validate_on_disk_cib(const char *filename, xmlNode ** on_disk_cib) { int s_res = -1; struct stat buf; gboolean passed = TRUE; xmlNode *root = NULL; CRM_ASSERT(filename != NULL); s_res = stat(filename, &buf); if (s_res == 0) { char *sigfile = NULL; size_t fnsize; crm_trace("Reading cluster configuration from: %s", filename); root = filename2xml(filename); fnsize = strlen(filename) + 5; sigfile = calloc(1, fnsize); snprintf(sigfile, fnsize, "%s.sig", filename); if (validate_cib_digest(root, sigfile) == FALSE) { passed = FALSE; } free(sigfile); } if (on_disk_cib != NULL) { *on_disk_cib = root; } else { free_xml(root); } return passed; } static int cib_rename(const char *old, const char *new) { int rc = 0; int automatic_fd = 0; char *automatic = NULL; if (new == NULL) { umask(S_IWGRP | S_IWOTH | S_IROTH); automatic = g_strdup_printf("%s/cib.auto.XXXXXX", cib_root); automatic_fd = mkstemp(automatic); new = automatic; crm_err("Archiving corrupt or unusable file %s as %s", old, automatic); } rc = rename(old, new); if (rc < 0) { crm_perror(LOG_ERR, "Couldn't rename %s as %s - Disabling disk writes and continuing", old, new); cib_writes_enabled = FALSE; } if (automatic_fd > 0) { close(automatic_fd); } free(automatic); return rc; } /* * It is the callers responsibility to free the output of this function */ static xmlNode * retrieveCib(const char *filename, const char *sigfile, gboolean archive_invalid) { struct stat buf; xmlNode *root = NULL; crm_info("Reading cluster configuration from: %s (digest: %s)", filename, sigfile); if (stat(filename, &buf) != 0) { crm_warn("Cluster configuration not found: %s", filename); return NULL; } root = filename2xml(filename); if (root == NULL) { crm_err("%s exists but does NOT contain valid XML. ", filename); crm_warn("Continuing but %s will NOT used.", filename); } else if (validate_cib_digest(root, sigfile) == FALSE) { crm_err("Checksum of %s failed! Configuration contents ignored!", filename); crm_err("Usually this is caused by manual changes, " "please refer to http://clusterlabs.org/wiki/FAQ#cib_changes_detected"); crm_warn("Continuing but %s will NOT used.", filename); free_xml(root); root = NULL; if (archive_invalid) { /* Archive the original files so the contents are not lost */ cib_rename(filename, NULL); cib_rename(sigfile, NULL); } } return root; } static int cib_archive_filter(const struct dirent * a) { /* Looking for regular files (d_type = 8) starting with 'cib-' and not ending in .sig */ if(a->d_type != 8) { return 0; } else if(strstr(a->d_name, "cib-") != a->d_name) { return 0; } else if(strstr(a->d_name, ".sig") != NULL) { return 0; } return 1; } static int cib_archive_sort(const struct dirent ** a, const struct dirent **b) { /* Order by creation date - most recently created file first */ int rc = 0; struct stat buf; time_t a_age = 0; time_t b_age = 0; char *a_path = g_strdup_printf("%s/%s", cib_root, a[0]->d_name); char *b_path = g_strdup_printf("%s/%s", cib_root, b[0]->d_name); if(stat(a_path, &buf) == 0) { a_age = buf.st_ctime; } if(stat(b_path, &buf) == 0) { b_age = buf.st_ctime; } free(a_path); free(b_path); if(a_age > b_age) { rc = 1; } else if(a_age < b_age) { rc = -1; } crm_trace("%s (%u) vs. %s (%u) : %d", a[0]->d_name, a_age, b[0]->d_name, b_age, rc); return rc; } xmlNode * readCibXmlFile(const char *dir, const char *file, gboolean discard_status) { struct dirent **namelist = NULL; int lpc = 0; char *sigfile = NULL; char *filename = NULL; const char *name = NULL; const char *value = NULL; const char *validation = NULL; const char *use_valgrind = getenv("PCMK_valgrind_enabled"); xmlNode *root = NULL; xmlNode *status = NULL; if (!crm_is_writable(dir, file, CRM_DAEMON_USER, NULL, FALSE)) { cib_status = -EACCES; return NULL; } filename = crm_concat(dir, file, '/'); sigfile = crm_concat(filename, "sig", '.'); cib_status = pcmk_ok; root = retrieveCib(filename, sigfile, TRUE); free(filename); free(sigfile); if (root == NULL) { crm_warn("Primary configuration corrupt or unusable, trying backups"); lpc = scandir(cib_root, &namelist, cib_archive_filter, cib_archive_sort); if (lpc < 0) { crm_perror(LOG_NOTICE, "scandir(%s) failed", cib_root); } } while (root == NULL && lpc > 1) { lpc--; filename = g_strdup_printf("%s/%s", cib_root, namelist[lpc]->d_name); sigfile = crm_concat(filename, "sig", '.'); root = retrieveCib(filename, sigfile, FALSE); if(root) { crm_notice("Continuing with last valid configuration archive: %s", filename); } free(namelist[lpc]); free(filename); free(sigfile); } free(namelist); if (root == NULL) { root = createEmptyCib(); crm_xml_add(root, XML_ATTR_GENERATION, "0"); crm_xml_add(root, XML_ATTR_NUMUPDATES, "0"); crm_xml_add(root, XML_ATTR_GENERATION_ADMIN, "0"); crm_xml_add(root, XML_ATTR_VALIDATION, LATEST_SCHEMA_VERSION); crm_warn("Continuing with an empty configuration."); } if (cib_writes_enabled && use_valgrind) { if (crm_is_true(use_valgrind) || strstr(use_valgrind, "cib")) { cib_writes_enabled = FALSE; crm_err("*********************************************************"); crm_err("*** Disabling disk writes to avoid confusing Valgrind ***"); crm_err("*********************************************************"); } } status = find_xml_node(root, XML_CIB_TAG_STATUS, FALSE); if (discard_status && status != NULL) { /* strip out the status section if there is one */ free_xml(status); status = NULL; } if (status == NULL) { create_xml_node(root, XML_CIB_TAG_STATUS); } /* Do this before DTD validation happens */ /* fill in some defaults */ name = XML_ATTR_GENERATION_ADMIN; value = crm_element_value(root, name); if (value == NULL) { crm_warn("No value for %s was specified in the configuration.", name); crm_warn("The reccomended course of action is to shutdown," " run crm_verify and fix any errors it reports."); crm_warn("We will default to zero and continue but may get" " confused about which configuration to use if" " multiple nodes are powered up at the same time."); crm_xml_add_int(root, name, 0); } name = XML_ATTR_GENERATION; value = crm_element_value(root, name); if (value == NULL) { crm_xml_add_int(root, name, 0); } name = XML_ATTR_NUMUPDATES; value = crm_element_value(root, name); if (value == NULL) { crm_xml_add_int(root, name, 0); } /* unset these and require the DC/CCM to update as needed */ xml_remove_prop(root, XML_ATTR_DC_UUID); if (discard_status) { crm_log_xml_trace(root, "[on-disk]"); } validation = crm_element_value(root, XML_ATTR_VALIDATION); if (validate_xml(root, NULL, TRUE) == FALSE) { crm_err("CIB does not validate with %s", crm_str(validation)); cib_status = -pcmk_err_dtd_validation; } else if (validation == NULL) { int version = 0; update_validation(&root, &version, FALSE, FALSE); if (version > 0) { crm_notice("Enabling %s validation on" " the existing (sane) configuration", get_schema_name(version)); } else { crm_err("CIB does not validate with any known DTD or schema"); cib_status = -pcmk_err_dtd_validation; } } return root; } /* * The caller should never free the return value */ xmlNode * get_the_CIB(void) { return the_cib; } gboolean uninitializeCib(void) { xmlNode *tmp_cib = the_cib; if (tmp_cib == NULL) { crm_debug("The CIB has already been deallocated."); return FALSE; } initialized = FALSE; the_cib = NULL; node_search = NULL; resource_search = NULL; constraint_search = NULL; status_search = NULL; crm_debug("Deallocating the CIB."); free_xml(tmp_cib); crm_debug("The CIB has been deallocated."); return TRUE; } /* * This method will not free the old CIB pointer or the new one. * We rely on the caller to have saved a pointer to the old CIB * and to free the old/bad one depending on what is appropriate. */ gboolean initializeCib(xmlNode * new_cib) { if (new_cib == NULL) { return FALSE; } the_cib = new_cib; initialized = TRUE; return TRUE; } static void sync_directory(const char *name) { int fd = 0; DIR *directory = NULL; directory = opendir(name); if (directory == NULL) { crm_perror(LOG_ERR, "Could not open %s for syncing", name); return; } fd = dirfd(directory); if (fd < 0) { crm_perror(LOG_ERR, "Could not obtain file descriptor for %s", name); } else if (fsync(fd) < 0) { crm_perror(LOG_ERR, "Could not sync %s", name); } if (closedir(directory) < 0) { crm_perror(LOG_ERR, "Could not close %s after fsync", name); } } /* * This method will free the old CIB pointer on success and the new one * on failure. */ int activateCibXml(xmlNode * new_cib, gboolean to_disk, const char *op) { xmlNode *saved_cib = the_cib; CRM_ASSERT(new_cib != saved_cib); if (initializeCib(new_cib) == FALSE) { free_xml(new_cib); crm_err("Ignoring invalid or NULL CIB"); if (saved_cib != NULL) { crm_warn("Reverting to last known CIB"); if (initializeCib(saved_cib) == FALSE) { /* oh we are so dead */ crm_crit("Couldn't re-initialize the old CIB!"); exit(1); } } else { crm_crit("Could not write out new CIB and no saved" " version to revert to"); } return -ENODATA; } free_xml(saved_cib); if (cib_writes_enabled && cib_status == pcmk_ok && to_disk) { crm_debug("Triggering CIB write for %s op", op); mainloop_set_trigger(cib_writer); } return pcmk_ok; } static void cib_diskwrite_complete(mainloop_child_t * p, pid_t pid, int core, int signo, int exitcode) { if (signo) { crm_notice("Disk write process terminated with signal %d (pid=%d, core=%d)", signo, pid, core); } else { do_crm_log(exitcode == 0 ? LOG_TRACE : LOG_ERR, "Disk write process exited (pid=%d, rc=%d)", pid, exitcode); } if (exitcode != 0 && cib_writes_enabled) { crm_err("Disabling disk writes after write failure"); cib_writes_enabled = FALSE; } mainloop_trigger_complete(cib_writer); } int write_cib_contents(gpointer p) { int fd = -1; int exit_rc = pcmk_ok; char *digest = NULL; xmlNode *cib_status_root = NULL; xmlNode *cib_local = NULL; xmlNode *cib_tmp = NULL; int tmp_cib_fd = 0; int tmp_digest_fd = 0; char *tmp_cib = NULL; char *tmp_digest = NULL; char *digest_file = NULL; char *primary_file = NULL; char *backup_file = NULL; char *backup_digest = NULL; const char *epoch = NULL; const char *admin_epoch = NULL; if (p) { /* Synchronous write out */ cib_local = copy_xml(p); } else { int pid = 0; int bb_state = qb_log_ctl(QB_LOG_BLACKBOX, QB_LOG_CONF_STATE_GET, 0); /* Turn it off before the fork() to avoid: * - 2 processes writing to the same shared mem * - the child needing to disable it * (which would close it from underneath the parent) * This way, the shared mem files are already closed */ qb_log_ctl(QB_LOG_BLACKBOX, QB_LOG_CONF_ENABLED, QB_FALSE); pid = fork(); if (pid < 0) { crm_perror(LOG_ERR, "Disabling disk writes after fork failure"); cib_writes_enabled = FALSE; return FALSE; } if (pid) { /* Parent */ mainloop_child_add(pid, 0, "disk-writer", NULL, cib_diskwrite_complete); if (bb_state == QB_LOG_STATE_ENABLED) { /* Re-enable now that it it safe */ qb_log_ctl(QB_LOG_BLACKBOX, QB_LOG_CONF_ENABLED, QB_TRUE); } return -1; /* -1 means 'still work to do' */ } /* A-synchronous write out after a fork() */ /* In theory we can scribble on "the_cib" here and not affect the parent * But lets be safe anyway */ cib_local = copy_xml(the_cib); } epoch = crm_element_value(cib_local, XML_ATTR_GENERATION); admin_epoch = crm_element_value(cib_local, XML_ATTR_GENERATION_ADMIN); primary_file = crm_concat(cib_root, "cib.xml", '/'); digest_file = crm_concat(primary_file, "sig", '.'); /* Always write out with num_updates=0 */ crm_xml_add(cib_local, XML_ATTR_NUMUPDATES, "0"); fd = open(primary_file, O_NOFOLLOW); if (fd >= 0) { int rc = 0; int seq = get_last_sequence(cib_root, CIB_SERIES); /* check the admin didnt modify it underneath us */ if (validate_on_disk_cib(primary_file, NULL) == FALSE) { crm_err("%s was manually modified while the cluster was active!", primary_file); exit_rc = pcmk_err_cib_modified; goto cleanup; } backup_file = generate_series_filename(cib_root, CIB_SERIES, seq, CIB_SERIES_BZIP); backup_digest = crm_concat(backup_file, "sig", '.'); unlink(backup_file); unlink(backup_digest); rc = link(primary_file, backup_file); if (rc < 0) { exit_rc = pcmk_err_cib_backup; crm_perror(LOG_ERR, "Cannot link %s to %s", primary_file, backup_file); goto cleanup; } rc = link(digest_file, backup_digest); if (rc < 0 && errno != ENOENT) { exit_rc = pcmk_err_cib_backup; crm_perror(LOG_ERR, "Cannot link %s to %s", digest_file, backup_digest); goto cleanup; } write_last_sequence(cib_root, CIB_SERIES, seq + 1, CIB_SERIES_MAX); sync_directory(cib_root); crm_info("Archived previous version as %s", backup_file); } /* Given that we discard the status section on startup * there is no point writing it out in the first place * since users just get confused by it * * So delete the status section before we write it out */ crm_debug("Writing CIB to disk"); if (p == NULL) { cib_status_root = find_xml_node(cib_local, XML_CIB_TAG_STATUS, TRUE); CRM_LOG_ASSERT(cib_status_root != NULL); if (cib_status_root != NULL) { free_xml(cib_status_root); } } tmp_cib = g_strdup_printf("%s/cib.XXXXXX", cib_root); tmp_digest = g_strdup_printf("%s/cib.XXXXXX", cib_root); umask(S_IWGRP | S_IWOTH | S_IROTH); tmp_cib_fd = mkstemp(tmp_cib); if (tmp_cib_fd < 0 || write_xml_fd(cib_local, tmp_cib, tmp_cib_fd, FALSE) <= 0) { crm_err("Changes couldn't be written to %s", tmp_cib); exit_rc = pcmk_err_cib_save; goto cleanup; } /* Must calculate the digest after writing as write_xml_file() updates the last-written field */ digest = calculate_on_disk_digest(cib_local); crm_info("Wrote version %s.%s.0 of the CIB to disk (digest: %s)", admin_epoch ? admin_epoch : "0", epoch ? epoch : "0", digest); tmp_digest_fd = mkstemp(tmp_digest); if (tmp_digest_fd < 0 || write_cib_digest(cib_local, tmp_digest, tmp_digest_fd, digest) <= 0) { crm_err("Digest couldn't be written to %s", tmp_digest); exit_rc = pcmk_err_cib_save; goto cleanup; } crm_debug("Wrote digest %s to disk", digest); cib_tmp = retrieveCib(tmp_cib, tmp_digest, FALSE); CRM_ASSERT(cib_tmp != NULL); sync_directory(cib_root); crm_debug("Activating %s", tmp_cib); cib_rename(tmp_cib, primary_file); cib_rename(tmp_digest, digest_file); sync_directory(cib_root); cleanup: free(backup_digest); free(primary_file); free(backup_file); free(digest_file); free(digest); free(tmp_digest); free(tmp_cib); free_xml(cib_tmp); free_xml(cib_local); if (fd >= 0) { close(fd); } if (p == NULL) { /* exit() could potentially affect the parent by closing things it shouldn't * Use _exit instead */ _exit(exit_rc); } return exit_rc; } void GHFunc_count_peers(gpointer key, gpointer value, gpointer user_data) { int *active = user_data; if (safe_str_eq(value, ONLINESTATUS)) { (*active)++; } else if (safe_str_eq(value, JOINSTATUS)) { (*active)++; } } pacemaker-master/cib/main.c000066400000000000000000000402251217637305600161410ustar00rootroot00000000000000/* * Copyright (C) 2004 Andrew Beekhof * * 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 2 of the License, or (at your option) any later version. * * This software 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 library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #if HAVE_LIBXML2 # include #endif #ifdef HAVE_GETOPT_H # include #endif #if HAVE_BZLIB_H # include #endif extern int init_remote_listener(int port, gboolean encrypted); extern gboolean stand_alone; gboolean cib_shutdown_flag = FALSE; int cib_status = pcmk_ok; crm_cluster_t crm_cluster; #if SUPPORT_HEARTBEAT oc_ev_t *cib_ev_token; ll_cluster_t *hb_conn = NULL; extern void oc_ev_special(const oc_ev_t *, oc_ev_class_t, int); gboolean cib_register_ha(ll_cluster_t * hb_cluster, const char *client_name); #else void *hb_conn = NULL; #endif extern void terminate_cib(const char *caller, gboolean fast); GMainLoop *mainloop = NULL; const char *cib_root = NULL; char *cib_our_uname = NULL; gboolean preserve_status = FALSE; gboolean cib_writes_enabled = TRUE; int remote_fd = 0; int remote_tls_fd = 0; int cib_init(void); void cib_shutdown(int nsig); gboolean startCib(const char *filename); extern int write_cib_contents(gpointer p); GHashTable *config_hash = NULL; GHashTable *local_notify_queue = NULL; char *channel1 = NULL; char *channel2 = NULL; char *channel3 = NULL; char *channel4 = NULL; char *channel5 = NULL; #define OPTARGS "maswr:V?" void cib_cleanup(void); static void cib_enable_writes(int nsig) { crm_info("(Re)enabling disk writes"); cib_writes_enabled = TRUE; } static void log_cib_client(gpointer key, gpointer value, gpointer user_data) { crm_info("Client %s", crm_client_name(value)); } /* *INDENT-OFF* */ static struct crm_option long_options[] = { /* Top-level Options */ {"help", 0, 0, '?', "\tThis text"}, {"verbose", 0, 0, 'V', "\tIncrease debug output"}, {"per-action-cib", 0, 0, 'a', "\tAdvanced use only"}, {"stand-alone", 0, 0, 's', "\tAdvanced use only"}, {"disk-writes", 0, 0, 'w', "\tAdvanced use only"}, {"cib-root", 1, 0, 'r', "\tAdvanced use only"}, {0, 0, 0, 0} }; /* *INDENT-ON* */ int main(int argc, char **argv) { int flag; int rc = 0; int index = 0; int argerr = 0; struct passwd *pwentry = NULL; crm_log_init(NULL, LOG_INFO, TRUE, FALSE, argc, argv, FALSE); crm_set_options(NULL, "[options]", long_options, "Daemon for storing and replicating the cluster configuration"); mainloop_add_signal(SIGTERM, cib_shutdown); mainloop_add_signal(SIGPIPE, cib_enable_writes); cib_writer = mainloop_add_trigger(G_PRIORITY_LOW, write_cib_contents, NULL); crm_peer_init(); while (1) { flag = crm_get_option(argc, argv, &index); if (flag == -1) break; switch (flag) { case 'V': crm_bump_log_level(argc, argv); break; case 's': stand_alone = TRUE; preserve_status = TRUE; cib_writes_enabled = FALSE; pwentry = getpwnam(CRM_DAEMON_USER); CRM_CHECK(pwentry != NULL, crm_perror(LOG_ERR, "Invalid uid (%s) specified", CRM_DAEMON_USER); return 100); rc = setgid(pwentry->pw_gid); if (rc < 0) { crm_perror(LOG_ERR, "Could not set group to %d", pwentry->pw_gid); return 100; } rc = initgroups(CRM_DAEMON_GROUP, pwentry->pw_gid); if (rc < 0) { crm_perror(LOG_ERR, "Could not setup groups for user %d", pwentry->pw_uid); return 100; } rc = setuid(pwentry->pw_uid); if (rc < 0) { crm_perror(LOG_ERR, "Could not set user to %d", pwentry->pw_uid); return 100; } break; case '?': /* Help message */ crm_help(flag, EX_OK); break; case 'w': cib_writes_enabled = TRUE; break; case 'r': cib_root = optarg; break; case 'm': cib_metadata(); return 0; default: ++argerr; break; } } if (argc - optind == 1 && safe_str_eq("metadata", argv[optind])) { cib_metadata(); return 0; } if (optind > argc) { ++argerr; } if (argerr) { crm_help('?', EX_USAGE); } if (cib_root == NULL) { char *path = g_strdup_printf("%s/cib.xml", CRM_CONFIG_DIR); char *legacy = g_strdup_printf("%s/cib.xml", CRM_LEGACY_CONFIG_DIR); if (g_file_test(path, G_FILE_TEST_EXISTS)) { cib_root = CRM_CONFIG_DIR; } else if (g_file_test(legacy, G_FILE_TEST_EXISTS)) { cib_root = CRM_LEGACY_CONFIG_DIR; crm_notice("Using legacy config location: %s", cib_root); } else { cib_root = CRM_CONFIG_DIR; crm_notice("Using new config location: %s", cib_root); } g_free(legacy); g_free(path); } else { crm_notice("Using custom config location: %s", cib_root); } if (crm_is_writable(cib_root, NULL, CRM_DAEMON_USER, CRM_DAEMON_GROUP, FALSE) == FALSE) { crm_err("Bad permissions on %s. Terminating", cib_root); fprintf(stderr, "ERROR: Bad permissions on %s. See logs for details\n", cib_root); fflush(stderr); return 100; } /* read local config file */ rc = cib_init(); CRM_CHECK(crm_hash_table_size(client_connections) == 0, crm_warn("Not all clients gone at exit")); g_hash_table_foreach(client_connections, log_cib_client, NULL); cib_cleanup(); #if SUPPORT_HEARTBEAT if (hb_conn) { hb_conn->llc_ops->delete(hb_conn); } #endif crm_info("Done"); return rc; } void cib_cleanup(void) { crm_peer_destroy(); if (local_notify_queue) { g_hash_table_destroy(local_notify_queue); } crm_client_cleanup(); g_hash_table_destroy(config_hash); free(cib_our_uname); free(channel1); free(channel2); free(channel3); free(channel4); free(channel5); } unsigned long cib_num_ops = 0; const char *cib_stat_interval = "10min"; unsigned long cib_num_local = 0, cib_num_updates = 0, cib_num_fail = 0; unsigned long cib_bad_connects = 0, cib_num_timeouts = 0; #if SUPPORT_HEARTBEAT gboolean ccm_connect(void); static void ccm_connection_destroy(gpointer user_data) { crm_err("CCM connection failed... blocking while we reconnect"); CRM_ASSERT(ccm_connect()); return; } static void *ccm_library = NULL; gboolean ccm_connect(void) { gboolean did_fail = TRUE; int num_ccm_fails = 0; int max_ccm_fails = 30; int ret; int cib_ev_fd; int (*ccm_api_register) (oc_ev_t ** token) = find_library_function(&ccm_library, CCM_LIBRARY, "oc_ev_register", 1); int (*ccm_api_set_callback) (const oc_ev_t * token, oc_ev_class_t class, oc_ev_callback_t * fn, oc_ev_callback_t ** prev_fn) = find_library_function(&ccm_library, CCM_LIBRARY, "oc_ev_set_callback", 1); void (*ccm_api_special) (const oc_ev_t *, oc_ev_class_t, int) = find_library_function(&ccm_library, CCM_LIBRARY, "oc_ev_special", 1); int (*ccm_api_activate) (const oc_ev_t * token, int *fd) = find_library_function(&ccm_library, CCM_LIBRARY, "oc_ev_activate", 1); int (*ccm_api_unregister) (oc_ev_t * token) = find_library_function(&ccm_library, CCM_LIBRARY, "oc_ev_unregister", 1); static struct mainloop_fd_callbacks ccm_fd_callbacks = { .dispatch = cib_ccm_dispatch, .destroy = ccm_connection_destroy, }; while (did_fail) { did_fail = FALSE; crm_info("Registering with CCM..."); ret = (*ccm_api_register) (&cib_ev_token); if (ret != 0) { did_fail = TRUE; } if (did_fail == FALSE) { crm_trace("Setting up CCM callbacks"); ret = (*ccm_api_set_callback) (cib_ev_token, OC_EV_MEMB_CLASS, cib_ccm_msg_callback, NULL); if (ret != 0) { crm_warn("CCM callback not set"); did_fail = TRUE; } } if (did_fail == FALSE) { (*ccm_api_special) (cib_ev_token, OC_EV_MEMB_CLASS, 0); crm_trace("Activating CCM token"); ret = (*ccm_api_activate) (cib_ev_token, &cib_ev_fd); if (ret != 0) { crm_warn("CCM Activation failed"); did_fail = TRUE; } } if (did_fail) { num_ccm_fails++; (*ccm_api_unregister) (cib_ev_token); if (num_ccm_fails < max_ccm_fails) { crm_warn("CCM Connection failed %d times (%d max)", num_ccm_fails, max_ccm_fails); sleep(3); } else { crm_err("CCM Activation failed %d (max) times", num_ccm_fails); return FALSE; } } } crm_debug("CCM Activation passed... all set to go!"); mainloop_add_fd("heartbeat-ccm", G_PRIORITY_MEDIUM, cib_ev_fd, cib_ev_token, &ccm_fd_callbacks); return TRUE; } #endif #if SUPPORT_COROSYNC static void cib_cs_dispatch(cpg_handle_t handle, const struct cpg_name *groupName, uint32_t nodeid, uint32_t pid, void *msg, size_t msg_len) { uint32_t kind = 0; xmlNode *xml = NULL; const char *from = NULL; char *data = pcmk_message_common_cs(handle, nodeid, pid, msg, &kind, &from); if(data == NULL) { return; } if (kind == crm_class_cluster) { xml = string2xml(data); if (xml == NULL) { crm_err("Invalid XML: '%.120s'", data); free(data); return; } crm_xml_add(xml, F_ORIG, from); /* crm_xml_add_int(xml, F_SEQ, wrapper->id); */ cib_peer_callback(xml, NULL); } free_xml(xml); free(data); } static void cib_cs_destroy(gpointer user_data) { if (cib_shutdown_flag) { crm_info("Corosync disconnection complete"); } else { crm_err("Corosync connection lost! Exiting."); terminate_cib(__FUNCTION__, TRUE); } } #endif static void cib_peer_update_callback(enum crm_status_type type, crm_node_t * node, const void *data) { #if 0 /* crm_active_peers(crm_proc_cib) appears to give the wrong answer * sometimes, this might help figure out why */ if (type == crm_status_nstate) { crm_info("status: %s is now %s (was %s)", node->uname, node->state, (const char *)data); if (safe_str_eq(CRMD_JOINSTATE_MEMBER, node->state)) { return; } } else if (type == crm_status_processes) { uint32_t old = 0; if (data) { old = *(const uint32_t *)data; } if ((node->processes ^ old) & crm_proc_cib) { crm_info("status: cib process on %s is now %sactive", node->uname, is_set(node->processes, crm_proc_cib) ? "" : "in"); } else { return; } } else { return; } #endif if (cib_shutdown_flag && crm_active_peers() < 2 && crm_hash_table_size(client_connections) == 0) { crm_info("No more peers"); terminate_cib(__FUNCTION__, FALSE); } } #if SUPPORT_HEARTBEAT static void cib_ha_connection_destroy(gpointer user_data) { if (cib_shutdown_flag) { crm_info("Heartbeat disconnection complete... exiting"); terminate_cib(__FUNCTION__, FALSE); } else { crm_err("Heartbeat connection lost! Exiting."); terminate_cib(__FUNCTION__, TRUE); } } #endif int cib_init(void) { if (is_openais_cluster()) { #if SUPPORT_COROSYNC crm_cluster.destroy = cib_cs_destroy; crm_cluster.cpg.cpg_deliver_fn = cib_cs_dispatch; crm_cluster.cpg.cpg_confchg_fn = pcmk_cpg_membership; #endif } else if (is_heartbeat_cluster()) { #if SUPPORT_HEARTBEAT crm_cluster.hb_dispatch = cib_ha_peer_callback; crm_cluster.destroy = cib_ha_connection_destroy; #endif } config_hash = g_hash_table_new_full(crm_str_hash, g_str_equal, g_hash_destroy_str, g_hash_destroy_str); if (startCib("cib.xml") == FALSE) { crm_crit("Cannot start CIB... terminating"); crm_exit(ENODATA); } if (stand_alone == FALSE) { if (crm_cluster_connect(&crm_cluster) == FALSE) { crm_crit("Cannot sign in to the cluster... terminating"); crm_exit(DAEMON_RESPAWN_STOP); } cib_our_uname = crm_cluster.uname; if (is_openais_cluster()) { crm_set_status_callback(&cib_peer_update_callback); } #if SUPPORT_HEARTBEAT if (is_heartbeat_cluster()) { gboolean was_error = FALSE; hb_conn = crm_cluster.hb_conn; if (was_error == FALSE) { if (HA_OK != hb_conn->llc_ops->set_cstatus_callback(hb_conn, cib_client_status_callback, hb_conn)) { crm_err("Cannot set cstatus callback: %s", hb_conn->llc_ops->errmsg(hb_conn)); was_error = TRUE; } } if (was_error == FALSE) { was_error = (ccm_connect() == FALSE); } if (was_error == FALSE) { /* Async get client status information in the cluster */ crm_info("Requesting the list of configured nodes"); hb_conn->llc_ops->client_status(hb_conn, NULL, CRM_SYSTEM_CIB, -1); } } #endif } else { cib_our_uname = strdup("localhost"); } cib_ipc_servers_init(&ipcs_ro, &ipcs_rw, &ipcs_shm, &ipc_ro_callbacks, &ipc_rw_callbacks); if (stand_alone) { cib_is_master = TRUE; } /* Create the mainloop and run it... */ mainloop = g_main_new(FALSE); crm_info("Starting %s mainloop", crm_system_name); g_main_run(mainloop); cib_ipc_servers_destroy(ipcs_ro, ipcs_rw, ipcs_shm); return crm_exit(pcmk_ok); } gboolean startCib(const char *filename) { gboolean active = FALSE; xmlNode *cib = readCibXmlFile(cib_root, filename, !preserve_status); CRM_ASSERT(cib != NULL); if (activateCibXml(cib, TRUE, "start") == 0) { int port = 0; const char *port_s = NULL; active = TRUE; cib_read_config(config_hash, cib); port_s = crm_element_value(cib, "remote-tls-port"); if (port_s) { port = crm_parse_int(port_s, "0"); remote_tls_fd = init_remote_listener(port, TRUE); } port_s = crm_element_value(cib, "remote-clear-port"); if (port_s) { port = crm_parse_int(port_s, "0"); remote_fd = init_remote_listener(port, FALSE); } crm_info("CIB Initialization completed successfully"); } return active; } pacemaker-master/cib/messages.c000066400000000000000000000321471217637305600170300ustar00rootroot00000000000000/* * Copyright (C) 2004 Andrew Beekhof * * 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 2 of the License, or (at your option) any later version. * * This software 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 library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define MAX_DIFF_RETRY 5 #ifdef CIBPIPE gboolean cib_is_master = TRUE; #else gboolean cib_is_master = FALSE; #endif xmlNode *the_cib = NULL; gboolean syncd_once = FALSE; extern const char *cib_our_uname; int revision_check(xmlNode * cib_update, xmlNode * cib_copy, int flags); int get_revision(xmlNode * xml_obj, int cur_revision); int updateList(xmlNode * local_cib, xmlNode * update_command, xmlNode * failed, int operation, const char *section); gboolean check_generation(xmlNode * newCib, xmlNode * oldCib); gboolean update_results(xmlNode * failed, xmlNode * target, const char *operation, int return_code); int cib_update_counter(xmlNode * xml_obj, const char *field, gboolean reset); int sync_our_cib(xmlNode * request, gboolean all); extern xmlNode *cib_msg_copy(const xmlNode * msg, gboolean with_data); extern gboolean cib_shutdown_flag; int cib_process_shutdown_req(const char *op, int options, const char *section, xmlNode * req, xmlNode * input, xmlNode * existing_cib, xmlNode ** result_cib, xmlNode ** answer) { #ifdef CIBPIPE return -EINVAL; #else int result = pcmk_ok; const char *host = crm_element_value(req, F_ORIG); *answer = NULL; if (crm_element_value(req, F_CIB_ISREPLY) == NULL) { crm_info("Shutdown REQ from %s", host); return pcmk_ok; } else if (cib_shutdown_flag) { crm_info("Shutdown ACK from %s", host); terminate_cib(__FUNCTION__, FALSE); return pcmk_ok; } else { crm_err("Shutdown ACK from %s - not shutting down", host); result = -EINVAL; } return result; #endif } int cib_process_default(const char *op, int options, const char *section, xmlNode * req, xmlNode * input, xmlNode * existing_cib, xmlNode ** result_cib, xmlNode ** answer) { int result = pcmk_ok; crm_trace("Processing \"%s\" event", op); *answer = NULL; if (op == NULL) { result = -EINVAL; crm_err("No operation specified"); } else if (strcasecmp(CRM_OP_NOOP, op) == 0) { ; } else { result = -EPROTONOSUPPORT; crm_err("Action [%s] is not supported by the CIB", op); } return result; } int cib_process_quit(const char *op, int options, const char *section, xmlNode * req, xmlNode * input, xmlNode * existing_cib, xmlNode ** result_cib, xmlNode ** answer) { int result = pcmk_ok; crm_trace("Processing \"%s\" event", op); crm_warn("The CRMd has asked us to exit... complying"); crm_exit(pcmk_ok); return result; } int cib_process_readwrite(const char *op, int options, const char *section, xmlNode * req, xmlNode * input, xmlNode * existing_cib, xmlNode ** result_cib, xmlNode ** answer) { #ifdef CIBPIPE return -EINVAL; #else int result = pcmk_ok; crm_trace("Processing \"%s\" event", op); if (safe_str_eq(op, CIB_OP_ISMASTER)) { if (cib_is_master == TRUE) { result = pcmk_ok; } else { result = -EPERM; } return result; } if (safe_str_eq(op, CIB_OP_MASTER)) { if (cib_is_master == FALSE) { crm_info("We are now in R/W mode"); cib_is_master = TRUE; syncd_once = TRUE; } else { crm_debug("We are still in R/W mode"); } } else if (cib_is_master) { crm_info("We are now in R/O mode"); cib_is_master = FALSE; } return result; #endif } int cib_process_ping(const char *op, int options, const char *section, xmlNode * req, xmlNode * input, xmlNode * existing_cib, xmlNode ** result_cib, xmlNode ** answer) { #ifdef CIBPIPE return -EINVAL; #else int result = pcmk_ok; crm_trace("Processing \"%s\" event", op); *answer = create_xml_node(NULL, XML_CRM_TAG_PING); crm_xml_add(*answer, XML_PING_ATTR_STATUS, "ok"); crm_xml_add(*answer, XML_PING_ATTR_SYSFROM, CRM_SYSTEM_CIB); return result; #endif } int cib_process_sync(const char *op, int options, const char *section, xmlNode * req, xmlNode * input, xmlNode * existing_cib, xmlNode ** result_cib, xmlNode ** answer) { #ifdef CIBPIPE return -EINVAL; #else return sync_our_cib(req, TRUE); #endif } int cib_process_sync_one(const char *op, int options, const char *section, xmlNode * req, xmlNode * input, xmlNode * existing_cib, xmlNode ** result_cib, xmlNode ** answer) { #ifdef CIBPIPE return -EINVAL; #else return sync_our_cib(req, FALSE); #endif } int sync_in_progress = 0; int cib_server_process_diff(const char *op, int options, const char *section, xmlNode * req, xmlNode * input, xmlNode * existing_cib, xmlNode ** result_cib, xmlNode ** answer) { int rc = pcmk_ok; if (cib_is_master) { /* the master is never waiting for a resync */ sync_in_progress = 0; } if (sync_in_progress > MAX_DIFF_RETRY) { /* request another full-sync, * the last request may have been lost */ sync_in_progress = 0; } if (sync_in_progress) { int diff_add_updates = 0; int diff_add_epoch = 0; int diff_add_admin_epoch = 0; int diff_del_updates = 0; int diff_del_epoch = 0; int diff_del_admin_epoch = 0; cib_diff_version_details(input, &diff_add_admin_epoch, &diff_add_epoch, &diff_add_updates, &diff_del_admin_epoch, &diff_del_epoch, &diff_del_updates); sync_in_progress++; crm_notice("Not applying diff %d.%d.%d -> %d.%d.%d (sync in progress)", diff_del_admin_epoch, diff_del_epoch, diff_del_updates, diff_add_admin_epoch, diff_add_epoch, diff_add_updates); return -pcmk_err_diff_resync; } rc = cib_process_diff(op, options, section, req, input, existing_cib, result_cib, answer); if (rc == -pcmk_err_diff_resync && cib_is_master == FALSE) { xmlNode *sync_me = create_xml_node(NULL, "sync-me"); free_xml(*result_cib); *result_cib = NULL; crm_info("Requesting re-sync from peer"); sync_in_progress++; crm_xml_add(sync_me, F_TYPE, "cib"); crm_xml_add(sync_me, F_CIB_OPERATION, CIB_OP_SYNC_ONE); crm_xml_add(sync_me, F_CIB_DELEGATED, cib_our_uname); if (send_cluster_message(NULL, crm_msg_cib, sync_me, FALSE) == FALSE) { rc = -ENOTCONN; } free_xml(sync_me); } else if (rc == -pcmk_err_diff_resync) { rc = -pcmk_err_diff_failed; if (options & cib_force_diff) { crm_warn("Not requesting full refresh in R/W mode"); } } return rc; } int cib_process_replace_svr(const char *op, int options, const char *section, xmlNode * req, xmlNode * input, xmlNode * existing_cib, xmlNode ** result_cib, xmlNode ** answer) { const char *tag = crm_element_name(input); int rc = cib_process_replace(op, options, section, req, input, existing_cib, result_cib, answer); if (rc == pcmk_ok && safe_str_eq(tag, XML_TAG_CIB)) { sync_in_progress = 0; } return rc; } static int delete_cib_object(xmlNode * parent, xmlNode * delete_spec) { const char *object_name = NULL; const char *object_id = NULL; xmlNode *equiv_node = NULL; int result = pcmk_ok; if (delete_spec != NULL) { object_name = crm_element_name(delete_spec); } object_id = crm_element_value(delete_spec, XML_ATTR_ID); crm_trace("Processing: <%s id=%s>", crm_str(object_name), crm_str(object_id)); if (delete_spec == NULL) { result = -EINVAL; } else if (parent == NULL) { result = -EINVAL; } else if (object_id == NULL) { /* placeholder object */ equiv_node = find_xml_node(parent, object_name, FALSE); } else { equiv_node = find_entity(parent, object_name, object_id); } if (result != pcmk_ok) { ; /* nothing */ } else if (equiv_node == NULL) { result = pcmk_ok; } else if (xml_has_children(delete_spec) == FALSE) { /* only leaves are deleted */ crm_debug("Removing leaf: <%s id=%s>", crm_str(object_name), crm_str(object_id)); free_xml(equiv_node); equiv_node = NULL; } else { xmlNode *child = NULL; for (child = __xml_first_child(delete_spec); child != NULL; child = __xml_next(child)) { int tmp_result = delete_cib_object(equiv_node, child); /* only the first error is likely to be interesting */ if (tmp_result != pcmk_ok && result == pcmk_ok) { result = tmp_result; } } } return result; } int cib_process_delete_absolute(const char *op, int options, const char *section, xmlNode * req, xmlNode * input, xmlNode * existing_cib, xmlNode ** result_cib, xmlNode ** answer) { xmlNode *failed = NULL; int result = pcmk_ok; xmlNode *update_section = NULL; crm_trace("Processing \"%s\" event for section=%s", op, crm_str(section)); if (safe_str_eq(XML_CIB_TAG_SECTION_ALL, section)) { section = NULL; } else if (safe_str_eq(XML_TAG_CIB, section)) { section = NULL; } else if (safe_str_eq(crm_element_name(input), XML_TAG_CIB)) { section = NULL; } CRM_CHECK(strcasecmp(CIB_OP_DELETE, op) == 0, return -EINVAL); if (input == NULL) { crm_err("Cannot perform modification with no data"); return -EINVAL; } failed = create_xml_node(NULL, XML_TAG_FAILED); update_section = get_object_root(section, *result_cib); result = delete_cib_object(update_section, input); update_results(failed, input, op, result); if (xml_has_children(failed)) { CRM_CHECK(result != pcmk_ok, result = -EINVAL); } if (result != pcmk_ok) { crm_log_xml_err(failed, "CIB Update failures"); *answer = failed; } else { free_xml(failed); } return result; } gboolean check_generation(xmlNode * newCib, xmlNode * oldCib) { if (cib_compare_generation(newCib, oldCib) >= 0) { return TRUE; } crm_warn("Generation from update is older than the existing one"); return FALSE; } #ifndef CIBPIPE int sync_our_cib(xmlNode * request, gboolean all) { int result = pcmk_ok; char *digest = NULL; const char *host = crm_element_value(request, F_ORIG); const char *op = crm_element_value(request, F_CIB_OPERATION); xmlNode *replace_request = cib_msg_copy(request, FALSE); CRM_CHECK(the_cib != NULL,;); CRM_CHECK(replace_request != NULL,;); crm_debug("Syncing CIB to %s", all ? "all peers" : host); if (all == FALSE && host == NULL) { crm_log_xml_err(request, "bad sync"); } /* remove the "all == FALSE" condition * * sync_from was failing, the local client wasnt being notified * because it didnt know it was a reply * setting this does not prevent the other nodes from applying it * if all == TRUE */ if (host != NULL) { crm_xml_add(replace_request, F_CIB_ISREPLY, host); } crm_xml_add(replace_request, F_CIB_OPERATION, CIB_OP_REPLACE); crm_xml_add(replace_request, "original_" F_CIB_OPERATION, op); crm_xml_add(replace_request, F_CIB_GLOBAL_UPDATE, XML_BOOLEAN_TRUE); crm_xml_add(replace_request, XML_ATTR_CRM_VERSION, CRM_FEATURE_SET); digest = calculate_xml_versioned_digest(the_cib, FALSE, TRUE, CRM_FEATURE_SET); crm_xml_add(replace_request, XML_ATTR_DIGEST, digest); add_message_xml(replace_request, F_CIB_CALLDATA, the_cib); if (send_cluster_message (all ? NULL : crm_get_peer(0, host), crm_msg_cib, replace_request, FALSE) == FALSE) { result = -ENOTCONN; } free_xml(replace_request); free(digest); return result; } #endif pacemaker-master/cib/notify.c000066400000000000000000000252231217637305600165260ustar00rootroot00000000000000/* * Copyright (C) 2004 Andrew Beekhof * * 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 2 of the License, or (at your option) any later version. * * This software 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 library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include int pending_updates = 0; struct cib_notification_s { xmlNode *msg; struct iovec *iov; }; void attach_cib_generation(xmlNode * msg, const char *field, xmlNode * a_cib); void do_cib_notify(int options, const char *op, xmlNode * update, int result, xmlNode * result_data, const char *msg_type); static void need_pre_notify(gpointer key, gpointer value, gpointer user_data) { crm_client_t *client = value; if (is_set(client->options, cib_notify_pre)) { gboolean *needed = user_data; *needed = TRUE; } } static void need_post_notify(gpointer key, gpointer value, gpointer user_data) { crm_client_t *client = value; if (is_set(client->options, cib_notify_post)) { gboolean *needed = user_data; *needed = TRUE; } } static gboolean cib_notify_send_one(gpointer key, gpointer value, gpointer user_data) { const char *type = NULL; gboolean do_send = FALSE; crm_client_t *client = value; struct cib_notification_s *update = user_data; CRM_CHECK(client != NULL, return TRUE); CRM_CHECK(update != NULL, return TRUE); if (client->ipcs == NULL && client->remote == NULL) { crm_warn("Skipping client with NULL channel"); return FALSE; } type = crm_element_value(update->msg, F_SUBTYPE); CRM_LOG_ASSERT(type != NULL); if (is_set(client->options, cib_notify_diff) && safe_str_eq(type, T_CIB_DIFF_NOTIFY)) { do_send = TRUE; } else if (is_set(client->options, cib_notify_replace) && safe_str_eq(type, T_CIB_REPLACE_NOTIFY)) { do_send = TRUE; } else if (is_set(client->options, cib_notify_confirm) && safe_str_eq(type, T_CIB_UPDATE_CONFIRM)) { do_send = TRUE; } else if (is_set(client->options, cib_notify_pre) && safe_str_eq(type, T_CIB_PRE_NOTIFY)) { do_send = TRUE; } else if (is_set(client->options, cib_notify_post) && safe_str_eq(type, T_CIB_POST_NOTIFY)) { do_send = TRUE; } if (do_send) { switch (client->kind) { case CRM_CLIENT_IPC: if (crm_ipcs_sendv(client, update->iov, crm_ipc_server_event) < 0) { crm_warn("Notification of client %s/%s failed", client->name, client->id); } break; #ifdef HAVE_GNUTLS_GNUTLS_H case CRM_CLIENT_TLS: #endif case CRM_CLIENT_TCP: crm_debug("Sent %s notification to client %s/%s", type, client->name, client->id); crm_remote_send(client->remote, update->msg); break; default: crm_err("Unknown transport %d for %s", client->kind, client->name); } } return FALSE; } static void cib_notify_send(xmlNode * xml) { struct iovec *iov; struct cib_notification_s update; ssize_t rc = crm_ipc_prepare(0, xml, &iov); crm_trace("Notifying clients"); if (rc > 0) { update.msg = xml; update.iov = iov; g_hash_table_foreach_remove(client_connections, cib_notify_send_one, &update); } else { crm_notice("Notification failed: %s (%d)", pcmk_strerror(rc), rc); } if (iov) { free(iov[0].iov_base); free(iov[1].iov_base); free(iov); } crm_trace("Notify complete"); } void cib_pre_notify(int options, const char *op, xmlNode * existing, xmlNode * update) { xmlNode *update_msg = NULL; const char *type = NULL; const char *id = NULL; gboolean needed = FALSE; g_hash_table_foreach(client_connections, need_pre_notify, &needed); if (needed == FALSE) { return; } /* TODO: consider pre-notification for removal */ update_msg = create_xml_node(NULL, "pre-notify"); if (update != NULL) { id = crm_element_value(update, XML_ATTR_ID); } crm_xml_add(update_msg, F_TYPE, T_CIB_NOTIFY); crm_xml_add(update_msg, F_SUBTYPE, T_CIB_PRE_NOTIFY); crm_xml_add(update_msg, F_CIB_OPERATION, op); if (id != NULL) { crm_xml_add(update_msg, F_CIB_OBJID, id); } if (update != NULL) { crm_xml_add(update_msg, F_CIB_OBJTYPE, crm_element_name(update)); } else if (existing != NULL) { crm_xml_add(update_msg, F_CIB_OBJTYPE, crm_element_name(existing)); } type = crm_element_value(update_msg, F_CIB_OBJTYPE); attach_cib_generation(update_msg, "cib_generation", the_cib); if (existing != NULL) { add_message_xml(update_msg, F_CIB_EXISTING, existing); } if (update != NULL) { add_message_xml(update_msg, F_CIB_UPDATE, update); } cib_notify_send(update_msg); if (update == NULL) { crm_trace("Performing operation %s (on section=%s)", op, type); } else { crm_trace("Performing %s on <%s%s%s>", op, type, id ? " id=" : "", id ? id : ""); } free_xml(update_msg); } void cib_post_notify(int options, const char *op, xmlNode * update, int result, xmlNode * new_obj) { gboolean needed = FALSE; g_hash_table_foreach(client_connections, need_post_notify, &needed); if (needed == FALSE) { return; } do_cib_notify(options, op, update, result, new_obj, T_CIB_UPDATE_CONFIRM); } void cib_diff_notify(int options, const char *client, const char *call_id, const char *op, xmlNode * update, int result, xmlNode * diff) { int add_updates = 0; int add_epoch = 0; int add_admin_epoch = 0; int del_updates = 0; int del_epoch = 0; int del_admin_epoch = 0; int log_level = LOG_DEBUG_2; if (diff == NULL) { return; } if (result != pcmk_ok) { log_level = LOG_WARNING; } cib_diff_version_details(diff, &add_admin_epoch, &add_epoch, &add_updates, &del_admin_epoch, &del_epoch, &del_updates); if (add_updates != del_updates) { do_crm_log(log_level, "Update (client: %s%s%s): %d.%d.%d -> %d.%d.%d (%s)", client, call_id ? ", call:" : "", call_id ? call_id : "", del_admin_epoch, del_epoch, del_updates, add_admin_epoch, add_epoch, add_updates, pcmk_strerror(result)); } else if (diff != NULL) { do_crm_log(log_level, "Local-only Change (client:%s%s%s): %d.%d.%d (%s)", client, call_id ? ", call: " : "", call_id ? call_id : "", add_admin_epoch, add_epoch, add_updates, pcmk_strerror(result)); } do_cib_notify(options, op, update, result, diff, T_CIB_DIFF_NOTIFY); } void do_cib_notify(int options, const char *op, xmlNode * update, int result, xmlNode * result_data, const char *msg_type) { xmlNode *update_msg = NULL; const char *id = NULL; update_msg = create_xml_node(NULL, "notify"); if (result_data != NULL) { id = crm_element_value(result_data, XML_ATTR_ID); } crm_xml_add(update_msg, F_TYPE, T_CIB_NOTIFY); crm_xml_add(update_msg, F_SUBTYPE, msg_type); crm_xml_add(update_msg, F_CIB_OPERATION, op); crm_xml_add_int(update_msg, F_CIB_RC, result); if (id != NULL) { crm_xml_add(update_msg, F_CIB_OBJID, id); } if (update != NULL) { crm_trace("Setting type to update->name: %s", crm_element_name(update)); crm_xml_add(update_msg, F_CIB_OBJTYPE, crm_element_name(update)); } else if (result_data != NULL) { crm_trace("Setting type to new_obj->name: %s", crm_element_name(result_data)); crm_xml_add(update_msg, F_CIB_OBJTYPE, crm_element_name(result_data)); } else { crm_trace("Not Setting type"); } attach_cib_generation(update_msg, "cib_generation", the_cib); if (update != NULL) { add_message_xml(update_msg, F_CIB_UPDATE, update); } if (result_data != NULL) { add_message_xml(update_msg, F_CIB_UPDATE_RESULT, result_data); } cib_notify_send(update_msg); free_xml(update_msg); } void attach_cib_generation(xmlNode * msg, const char *field, xmlNode * a_cib) { xmlNode *generation = create_xml_node(NULL, XML_CIB_TAG_GENERATION_TUPPLE); if (a_cib != NULL) { copy_in_properties(generation, a_cib); } add_message_xml(msg, field, generation); free_xml(generation); } void cib_replace_notify(const char *origin, xmlNode * update, int result, xmlNode * diff) { xmlNode *replace_msg = NULL; int add_updates = 0; int add_epoch = 0; int add_admin_epoch = 0; int del_updates = 0; int del_epoch = 0; int del_admin_epoch = 0; if (diff == NULL) { return; } cib_diff_version_details(diff, &add_admin_epoch, &add_epoch, &add_updates, &del_admin_epoch, &del_epoch, &del_updates); if (del_updates < 0) { crm_log_xml_debug(diff, "Bad replace diff"); } if (add_updates != del_updates) { crm_info("Replaced: %d.%d.%d -> %d.%d.%d from %s", del_admin_epoch, del_epoch, del_updates, add_admin_epoch, add_epoch, add_updates, crm_str(origin)); } else if (diff != NULL) { crm_info("Local-only Replace: %d.%d.%d from %s", add_admin_epoch, add_epoch, add_updates, crm_str(origin)); } replace_msg = create_xml_node(NULL, "notify-replace"); crm_xml_add(replace_msg, F_TYPE, T_CIB_NOTIFY); crm_xml_add(replace_msg, F_SUBTYPE, T_CIB_REPLACE_NOTIFY); crm_xml_add(replace_msg, F_CIB_OPERATION, CIB_OP_REPLACE); crm_xml_add_int(replace_msg, F_CIB_RC, result); attach_cib_generation(replace_msg, "cib-replace-generation", update); crm_log_xml_trace(replace_msg, "CIB Replaced"); cib_notify_send(replace_msg); free_xml(replace_msg); } pacemaker-master/cib/notify.h000066400000000000000000000026361217637305600165360ustar00rootroot00000000000000/* * Copyright (C) 2004 Andrew Beekhof * * 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 2 of the License, or (at your option) any later version. * * This software 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 library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include #include #include #include extern FILE *msg_cib_strm; extern void cib_pre_notify(int options, const char *op, xmlNode * existing, xmlNode * update); extern void cib_post_notify(int options, const char *op, xmlNode * update, int result, xmlNode * new_obj); extern void cib_diff_notify(int options, const char *client, const char *call_id, const char *op, xmlNode * update, int result, xmlNode * old_cib); extern void cib_replace_notify(const char *origin, xmlNode * update, int result, xmlNode * diff); pacemaker-master/cib/remote.c000066400000000000000000000453651217637305600165220ustar00rootroot00000000000000/* * Copyright (C) 2004 Andrew Beekhof * * 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 2 of the License, or (at your option) any later version. * * This software 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 library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "callbacks.h" /* #undef HAVE_PAM_PAM_APPL_H */ /* #undef HAVE_GNUTLS_GNUTLS_H */ #ifdef HAVE_GNUTLS_GNUTLS_H # undef KEYFILE # include #endif #include #include #if HAVE_SECURITY_PAM_APPL_H # include # define HAVE_PAM 1 #else # if HAVE_PAM_PAM_APPL_H # include # define HAVE_PAM 1 # endif #endif extern int remote_tls_fd; extern gboolean cib_shutdown_flag; int init_remote_listener(int port, gboolean encrypted); void cib_remote_connection_destroy(gpointer user_data); #ifdef HAVE_GNUTLS_GNUTLS_H # define DH_BITS 1024 gnutls_dh_params_t dh_params; gnutls_anon_server_credentials_t anon_cred_s; static void debug_log(int level, const char *str) { fputs(str, stderr); } #endif #define REMOTE_AUTH_TIMEOUT 10000 int num_clients; int authenticate_user(const char *user, const char *passwd); int cib_remote_listen(gpointer data); int cib_remote_msg(gpointer data); static void remote_connection_destroy(gpointer user_data) { return; } #define ERROR_SUFFIX " Shutting down remote listener" int init_remote_listener(int port, gboolean encrypted) { int rc; int *ssock = NULL; struct sockaddr_in saddr; int optval; static struct mainloop_fd_callbacks remote_listen_fd_callbacks = { .dispatch = cib_remote_listen, .destroy = remote_connection_destroy, }; if (port <= 0) { /* dont start it */ return 0; } if (encrypted) { #ifndef HAVE_GNUTLS_GNUTLS_H crm_warn("TLS support is not available"); return 0; #else crm_notice("Starting a tls listener on port %d.", port); gnutls_global_init(); /* gnutls_global_set_log_level (10); */ gnutls_global_set_log_function(debug_log); gnutls_dh_params_init(&dh_params); gnutls_dh_params_generate2(dh_params, DH_BITS); gnutls_anon_allocate_server_credentials(&anon_cred_s); gnutls_anon_set_server_dh_params(anon_cred_s, dh_params); #endif } else { crm_warn("Starting a plain_text listener on port %d.", port); } #ifndef HAVE_PAM crm_warn("PAM is _not_ enabled!"); #endif /* create server socket */ ssock = malloc(sizeof(int)); if(ssock == NULL) { crm_perror(LOG_ERR, "Can not create server socket." ERROR_SUFFIX); return -1; } *ssock = socket(AF_INET, SOCK_STREAM, 0); if (*ssock == -1) { crm_perror(LOG_ERR, "Can not create server socket." ERROR_SUFFIX); free(ssock); return -1; } /* reuse address */ optval = 1; rc = setsockopt(*ssock, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval)); if (rc < 0) { crm_perror(LOG_INFO, "Couldn't allow the reuse of local addresses by our remote listener"); } /* bind server socket */ memset(&saddr, '\0', sizeof(saddr)); saddr.sin_family = AF_INET; saddr.sin_addr.s_addr = INADDR_ANY; saddr.sin_port = htons(port); if (bind(*ssock, (struct sockaddr *)&saddr, sizeof(saddr)) == -1) { crm_perror(LOG_ERR, "Can not bind server socket." ERROR_SUFFIX); close(*ssock); free(ssock); return -2; } if (listen(*ssock, 10) == -1) { crm_perror(LOG_ERR, "Can not start listen." ERROR_SUFFIX); close(*ssock); free(ssock); return -3; } mainloop_add_fd("cib-remote", G_PRIORITY_DEFAULT, *ssock, ssock, &remote_listen_fd_callbacks); return *ssock; } static int check_group_membership(const char *usr, const char *grp) { int index = 0; struct passwd *pwd = NULL; struct group *group = NULL; CRM_CHECK(usr != NULL, return FALSE); CRM_CHECK(grp != NULL, return FALSE); pwd = getpwnam(usr); if (pwd == NULL) { crm_err("No user named '%s' exists!", usr); return FALSE; } group = getgrgid(pwd->pw_gid); if (group != NULL && crm_str_eq(grp, group->gr_name, TRUE)) { return TRUE; } group = getgrnam(grp); if (group == NULL) { crm_err("No group named '%s' exists!", grp); return FALSE; } while (TRUE) { char *member = group->gr_mem[index++]; if (member == NULL) { break; } else if (crm_str_eq(usr, member, TRUE)) { return TRUE; } }; return FALSE; } static gboolean cib_remote_auth(xmlNode * login) { const char *user = NULL; const char *pass = NULL; const char *tmp = NULL; crm_log_xml_info(login, "Login: "); if (login == NULL) { return FALSE; } tmp = crm_element_name(login); if (safe_str_neq(tmp, "cib_command")) { crm_err("Wrong tag: %s", tmp); return FALSE; } tmp = crm_element_value(login, "op"); if (safe_str_neq(tmp, "authenticate")) { crm_err("Wrong operation: %s", tmp); return FALSE; } user = crm_element_value(login, "user"); pass = crm_element_value(login, "password"); if (!user || !pass) { crm_err("missing auth credentials"); return FALSE; } /* Non-root daemons can only validate the password of the * user they're running as */ if (check_group_membership(user, CRM_DAEMON_GROUP) == FALSE) { crm_err("User is not a member of the required group"); return FALSE; } else if (authenticate_user(user, pass) == FALSE) { crm_err("PAM auth failed"); return FALSE; } return TRUE; } static gboolean remote_auth_timeout_cb(gpointer data) { crm_client_t *client = data; client->remote->auth_timeout = 0; if (client->remote->authenticated == TRUE) { return FALSE; } mainloop_del_fd(client->remote->source); crm_err("Remote client authentication timed out"); return FALSE; } int cib_remote_listen(gpointer data) { int csock = 0; unsigned laddr; struct sockaddr_in addr; int ssock = *(int *)data; int flag; crm_client_t *new_client = NULL; static struct mainloop_fd_callbacks remote_client_fd_callbacks = { .dispatch = cib_remote_msg, .destroy = cib_remote_connection_destroy, }; /* accept the connection */ laddr = sizeof(addr); csock = accept(ssock, (struct sockaddr *)&addr, &laddr); crm_debug("New %s connection from %s", ssock == remote_tls_fd ? "secure" : "clear-text", inet_ntoa(addr.sin_addr)); if (csock == -1) { crm_err("accept socket failed"); return TRUE; } if ((flag = fcntl(csock, F_GETFL)) >= 0) { if (fcntl(csock, F_SETFL, flag | O_NONBLOCK) < 0) { crm_err("fcntl() write failed"); close(csock); return TRUE; } } else { crm_err("fcntl() read failed"); close(csock); return TRUE; } num_clients++; crm_client_init(); new_client = calloc(1, sizeof(crm_client_t)); new_client->remote = calloc(1, sizeof(crm_remote_t)); new_client->id = crm_generate_uuid(); g_hash_table_insert(client_connections, new_client->id /* Should work */ , new_client); if (ssock == remote_tls_fd) { #ifdef HAVE_GNUTLS_GNUTLS_H new_client->kind = CRM_CLIENT_TLS; /* create gnutls session for the server socket */ new_client->remote->tls_session = crm_create_anon_tls_session(csock, GNUTLS_SERVER, anon_cred_s); if (new_client->remote->tls_session == NULL) { crm_err("TLS session creation failed"); close(csock); return TRUE; } #endif } else { new_client->kind = CRM_CLIENT_TCP; new_client->remote->tcp_socket = csock; } /* clients have a few seconds to perform handshake. */ new_client->remote->auth_timeout = g_timeout_add(REMOTE_AUTH_TIMEOUT, remote_auth_timeout_cb, new_client); new_client->remote->source = mainloop_add_fd("cib-remote-client", G_PRIORITY_DEFAULT, csock, new_client, &remote_client_fd_callbacks); return TRUE; } void cib_remote_connection_destroy(gpointer user_data) { crm_client_t *client = user_data; int csock = 0; if (client == NULL) { return; } crm_trace("Cleaning up after client disconnect: %s/%s", crm_str(client->name), client->id); num_clients--; crm_trace("Num unfree'd clients: %d", num_clients); switch (client->kind) { case CRM_CLIENT_TCP: csock = client->remote->tcp_socket; break; #ifdef HAVE_GNUTLS_GNUTLS_H case CRM_CLIENT_TLS: if (client->remote->tls_session) { void *sock_ptr = gnutls_transport_get_ptr(*client->remote->tls_session); csock = GPOINTER_TO_INT(sock_ptr); if (client->remote->tls_handshake_complete) { gnutls_bye(*client->remote->tls_session, GNUTLS_SHUT_WR); } gnutls_deinit(*client->remote->tls_session); gnutls_free(client->remote->tls_session); client->remote->tls_session = NULL; } break; #endif default: crm_warn("Unexpected client type %d", client->kind); } if (csock > 0) { close(csock); } crm_client_destroy(client); crm_trace("Freed the cib client"); if (cib_shutdown_flag) { cib_shutdown(0); } return; } static void cib_handle_remote_msg(crm_client_t * client, xmlNode * command) { const char *value = NULL; value = crm_element_name(command); if (safe_str_neq(value, "cib_command")) { crm_log_xml_trace(command, "Bad command: "); return; } if (client->name == NULL) { value = crm_element_value(command, F_CLIENTNAME); if (value == NULL) { client->name = strdup(client->id); } else { client->name = strdup(value); } } if (client->userdata == NULL) { value = crm_element_value(command, F_CIB_CALLBACK_TOKEN); if (value != NULL) { client->userdata = strdup(value); crm_trace("Callback channel for %s is %s", client->id, client->userdata); } else { client->userdata = strdup(client->id); } } /* unset dangerous options */ xml_remove_prop(command, F_ORIG); xml_remove_prop(command, F_CIB_HOST); xml_remove_prop(command, F_CIB_GLOBAL_UPDATE); crm_xml_add(command, F_TYPE, T_CIB); crm_xml_add(command, F_CIB_CLIENTID, client->id); crm_xml_add(command, F_CIB_CLIENTNAME, client->name); #if ENABLE_ACL crm_xml_add(command, F_CIB_USER, client->user); #endif if (crm_element_value(command, F_CIB_CALLID) == NULL) { char *call_uuid = crm_generate_uuid(); /* fix the command */ crm_xml_add(command, F_CIB_CALLID, call_uuid); free(call_uuid); } if (crm_element_value(command, F_CIB_CALLOPTS) == NULL) { crm_xml_add_int(command, F_CIB_CALLOPTS, 0); } crm_log_xml_trace(command, "Remote command: "); cib_common_callback_worker(0, 0, command, client, TRUE); } int cib_remote_msg(gpointer data) { xmlNode *command = NULL; crm_client_t *client = data; int disconnected = 0; int timeout = client->remote->authenticated ? -1 : 1000; crm_trace("%s callback", client->kind != CRM_CLIENT_TCP ? "secure" : "clear-text"); #ifdef HAVE_GNUTLS_GNUTLS_H if (client->kind == CRM_CLIENT_TLS && (client->remote->tls_handshake_complete == FALSE)) { int rc = 0; /* Muliple calls to handshake will be required, this callback * will be invoked once the client sends more handshake data. */ do { rc = gnutls_handshake(*client->remote->tls_session); if (rc < 0 && rc != GNUTLS_E_AGAIN) { crm_err("Remote cib tls handshake failed"); return -1; } } while (rc == GNUTLS_E_INTERRUPTED); if (rc == 0) { crm_debug("Remote cib tls handshake completed"); client->remote->tls_handshake_complete = TRUE; if (client->remote->auth_timeout) { g_source_remove(client->remote->auth_timeout); } /* after handshake, clients must send auth in a few seconds */ client->remote->auth_timeout = g_timeout_add(REMOTE_AUTH_TIMEOUT, remote_auth_timeout_cb, client); } return 0; } #endif crm_remote_recv(client->remote, timeout, &disconnected); /* must pass auth before we will process anything else */ if (client->remote->authenticated == FALSE) { xmlNode *reg; #if ENABLE_ACL const char *user = NULL; #endif command = crm_remote_parse_buffer(client->remote); if (cib_remote_auth(command) == FALSE) { free_xml(command); return -1; } crm_debug("remote connection authenticated successfully"); client->remote->authenticated = TRUE; g_source_remove(client->remote->auth_timeout); client->remote->auth_timeout = 0; client->name = crm_element_value_copy(command, "name"); #if ENABLE_ACL user = crm_element_value(command, "user"); if (user) { client->user = strdup(user); } #endif /* send ACK */ reg = create_xml_node(NULL, "cib_result"); crm_xml_add(reg, F_CIB_OPERATION, CRM_OP_REGISTER); crm_xml_add(reg, F_CIB_CLIENTID, client->id); crm_remote_send(client->remote, reg); free_xml(reg); free_xml(command); } command = crm_remote_parse_buffer(client->remote); while (command) { crm_trace("command received"); cib_handle_remote_msg(client, command); free_xml(command); command = crm_remote_parse_buffer(client->remote); } if (disconnected) { crm_trace("disconnected while receiving remote cib msg."); return -1; } return 0; } #ifdef HAVE_PAM /* * Useful Examples: * http://www.kernel.org/pub/linux/libs/pam/Linux-PAM-html * http://developer.apple.com/samplecode/CryptNoMore/index.html */ static int construct_pam_passwd(int num_msg, const struct pam_message **msg, struct pam_response **response, void *data) { int count = 0; struct pam_response *reply; char *string = (char *)data; CRM_CHECK(data, return PAM_CONV_ERR); CRM_CHECK(num_msg == 1, return PAM_CONV_ERR); /* We only want to handle one message */ reply = calloc(1, sizeof(struct pam_response)); CRM_ASSERT(reply != NULL); for (count = 0; count < num_msg; ++count) { switch (msg[count]->msg_style) { case PAM_TEXT_INFO: crm_info("PAM: %s\n", msg[count]->msg); break; case PAM_PROMPT_ECHO_OFF: case PAM_PROMPT_ECHO_ON: reply[count].resp_retcode = 0; reply[count].resp = string; /* We already made a copy */ case PAM_ERROR_MSG: /* In theory we'd want to print this, but then * we see the password prompt in the logs */ /* crm_err("PAM error: %s\n", msg[count]->msg); */ break; default: crm_err("Unhandled conversation type: %d", msg[count]->msg_style); goto bail; } } *response = reply; reply = NULL; return PAM_SUCCESS; bail: for (count = 0; count < num_msg; ++count) { if (reply[count].resp != NULL) { switch (msg[count]->msg_style) { case PAM_PROMPT_ECHO_ON: case PAM_PROMPT_ECHO_OFF: /* Erase the data - it contained a password */ while (*(reply[count].resp)) { *(reply[count].resp)++ = '\0'; } free(reply[count].resp); break; } reply[count].resp = NULL; } } free(reply); reply = NULL; return PAM_CONV_ERR; } #endif int authenticate_user(const char *user, const char *passwd) { #ifndef HAVE_PAM gboolean pass = TRUE; #else int rc = 0; gboolean pass = FALSE; const void *p_user = NULL; struct pam_conv p_conv; struct pam_handle *pam_h = NULL; static const char *pam_name = NULL; if (pam_name == NULL) { pam_name = getenv("CIB_pam_service"); } if (pam_name == NULL) { pam_name = "login"; } p_conv.conv = construct_pam_passwd; p_conv.appdata_ptr = strdup(passwd); rc = pam_start(pam_name, user, &p_conv, &pam_h); if (rc != PAM_SUCCESS) { crm_err("Could not initialize PAM: %s (%d)", pam_strerror(pam_h, rc), rc); goto bail; } rc = pam_authenticate(pam_h, 0); if (rc != PAM_SUCCESS) { crm_err("Authentication failed for %s: %s (%d)", user, pam_strerror(pam_h, rc), rc); goto bail; } /* Make sure we authenticated the user we wanted to authenticate. * Since we also run as non-root, it might be worth pre-checking * the user has the same EID as us, since that the only user we * can authenticate. */ rc = pam_get_item(pam_h, PAM_USER, &p_user); if (rc != PAM_SUCCESS) { crm_err("Internal PAM error: %s (%d)", pam_strerror(pam_h, rc), rc); goto bail; } else if (p_user == NULL) { crm_err("Unknown user authenticated."); goto bail; } else if (safe_str_neq(p_user, user)) { crm_err("User mismatch: %s vs. %s.", (const char *)p_user, (const char *)user); goto bail; } rc = pam_acct_mgmt(pam_h, 0); if (rc != PAM_SUCCESS) { crm_err("Access denied: %s (%d)", pam_strerror(pam_h, rc), rc); goto bail; } pass = TRUE; bail: rc = pam_end(pam_h, rc); #endif return pass; } pacemaker-master/configure.ac000066400000000000000000001605641217637305600166130ustar00rootroot00000000000000dnl dnl autoconf for Pacemaker dnl dnl License: GNU General Public License (GPL) dnl =============================================== dnl Bootstrap dnl =============================================== AC_PREREQ(2.59) dnl Suggested structure: dnl information on the package dnl checks for programs dnl checks for libraries dnl checks for header files dnl checks for types dnl checks for structures dnl checks for compiler characteristics dnl checks for library functions dnl checks for system services AC_INIT(pacemaker, 1.1.10, pacemaker@oss.clusterlabs.org,,http://clusterlabs.org) CRM_DTD_VERSION="1.2" PCMK_FEATURES="" HB_PKG=heartbeat AC_CONFIG_AUX_DIR(.) AC_CANONICAL_HOST dnl Where #defines go (e.g. `AC_CHECK_HEADERS' below) dnl dnl Internal header: include/config.h dnl - Contains ALL defines dnl - include/config.h.in is generated automatically by autoheader dnl - NOT to be included in any header files except lha_internal.h dnl (which is also not to be included in any other header files) dnl dnl External header: include/crm_config.h dnl - Contains a subset of defines checked here dnl - Manually edit include/crm_config.h.in to have configure include dnl new defines dnl - Should not include HAVE_* defines dnl - Safe to include anywhere AM_CONFIG_HEADER(include/config.h include/crm_config.h) ALL_LINGUAS="en fr" AC_ARG_WITH(version, [ --with-version=version Override package version (if you're a packager needing to pretend) ], [ PACKAGE_VERSION="$withval" ]) AC_ARG_WITH(pkg-name, [ --with-pkg-name=name Override package name (if you're a packager needing to pretend) ], [ PACKAGE_NAME="$withval" ]) AM_INIT_AUTOMAKE($PACKAGE_NAME, $PACKAGE_VERSION) AC_DEFINE_UNQUOTED(PACEMAKER_VERSION, "$PACKAGE_VERSION", Current pacemaker version) PACKAGE_SERIES=`echo $PACKAGE_VERSION | awk -F. '{ print $1"."$2 }'` AC_SUBST(PACKAGE_SERIES) AC_SUBST(PACKAGE_VERSION) dnl automake >= 1.11 offers --enable-silent-rules for suppressing the output from dnl normal compilation. When a failure occurs, it will then display the full dnl command line dnl Wrap in m4_ifdef to avoid breaking on older platforms m4_ifdef([AM_SILENT_RULES],[AM_SILENT_RULES([yes])]) dnl Example 2.4. Silent Custom Rule to Generate a File dnl %-bar.pc: %.pc dnl $(AM_V_GEN)$(LN_S) $(notdir $^) $@ CC_IN_CONFIGURE=yes export CC_IN_CONFIGURE LDD=ldd dnl ======================================================================== dnl Compiler characteristics dnl ======================================================================== AC_PROG_CC dnl Can force other with environment variable "CC". AM_PROG_CC_C_O AC_PROG_CC_STDC gl_EARLY gl_INIT AC_LIBTOOL_DLOPEN dnl Enable dlopen support... AC_LIBLTDL_CONVENIENCE dnl make libltdl a convenience lib AC_PROG_LIBTOOL AC_PROG_YACC AM_PROG_LEX AC_C_STRINGIZE AC_TYPE_SIZE_T AC_CHECK_SIZEOF(char) AC_CHECK_SIZEOF(short) AC_CHECK_SIZEOF(int) AC_CHECK_SIZEOF(long) AC_CHECK_SIZEOF(long long) AC_STRUCT_TIMEZONE dnl =============================================== dnl Helpers dnl =============================================== cc_supports_flag() { local CFLAGS="$@" AC_MSG_CHECKING(whether $CC supports "$@") AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ ]], [[ ]])], [RC=0; AC_MSG_RESULT(yes)],[RC=1; AC_MSG_RESULT(no)]) return $RC } try_extract_header_define() { AC_MSG_CHECKING(if $2 in $1 exists) Cfile=$srcdir/extract_define.$2.${$} printf "#include \n" > ${Cfile}.c printf "#include <%s>\n" $1 >> ${Cfile}.c printf "int main(int argc, char **argv) {\n" >> ${Cfile}.c printf "#ifdef %s\n" $2 >> ${Cfile}.c printf "printf(\"%%s\", %s);\n" $2 >> ${Cfile}.c printf "#endif \n return 0; }\n" >> ${Cfile}.c $CC $CFLAGS ${Cfile}.c -o ${Cfile} 2>/dev/null value= if test -x ${Cfile}; then value=`${Cfile} 2>/dev/null` fi if test x"${value}" == x""; then value=$3 AC_MSG_RESULT(default: $value) else AC_MSG_RESULT($value) fi printf $value rm -rf ${Cfile}.c ${Cfile} ${Cfile}.dSYM ${Cfile}.gcno } extract_header_define() { AC_MSG_CHECKING(for $2 in $1) Cfile=$srcdir/extract_define.$2.${$} printf "#include \n" > ${Cfile}.c printf "#include <%s>\n" $1 >> ${Cfile}.c printf "int main(int argc, char **argv) { printf(\"%%s\", %s); return 0; }\n" $2 >> ${Cfile}.c $CC $CFLAGS ${Cfile}.c -o ${Cfile} value=`${Cfile}` AC_MSG_RESULT($value) printf $value rm -rf ${Cfile}.c ${Cfile} ${Cfile}.dSYM ${Cfile}.gcno } dnl =============================================== dnl Configure Options dnl =============================================== dnl Some systems, like Solaris require a custom package name AC_ARG_WITH(pkgname, [ --with-pkgname=name name for pkg (typically for Solaris) ], [ PKGNAME="$withval" ], [ PKGNAME="LXHAhb" ], ) AC_SUBST(PKGNAME) AC_ARG_ENABLE([ansi], [ --enable-ansi force GCC to compile to ANSI/ANSI standard for older compilers. [default=no]]) AC_ARG_ENABLE([fatal-warnings], [ --enable-fatal-warnings very pedantic and fatal warnings for gcc [default=yes]]) AC_ARG_ENABLE([quiet], [ --enable-quiet Supress make output unless there is an error [default=no]]) AC_ARG_ENABLE([thread-safe], [ --enable-thread-safe Enable some client libraries to be thread safe. [default=no]]) AC_ARG_ENABLE([bundled-ltdl], [ --enable-bundled-ltdl Configure, build and install the standalone ltdl library bundled with ${PACKAGE} [default=no]]) LTDL_LIBS="" AC_ARG_ENABLE([no-stack], [ --enable-no-stack Only build the Policy Engine and pieces needed to support it [default=no]]) AC_ARG_ENABLE([upstart], [ --enable-upstart Do not build support for the Upstart init system [default=yes]]) AC_ARG_ENABLE([systemd], [ --enable-systemd Do not build support for the Systemd init system [default=yes]]) AC_ARG_WITH(ais, [ --with-ais Support the Corosync messaging and membership layer ], [ SUPPORT_CS=$withval ], [ SUPPORT_CS=try ], ) AC_ARG_WITH(corosync, [ --with-corosync Support the Corosync messaging and membership layer ], [ SUPPORT_CS=$withval ] dnl initialized in AC_ARG_WITH(ais...) already, dnl don't reset to try if it was given as --without-ais ) AC_ARG_WITH(heartbeat, [ --with-heartbeat Support the Heartbeat messaging and membership layer ], [ SUPPORT_HEARTBEAT=$withval ], [ SUPPORT_HEARTBEAT=try ], ) AC_ARG_WITH(cman, [ --with-cman Support the consumption of membership and quorum from cman ], [ SUPPORT_CMAN=$withval ], [ SUPPORT_CMAN=try ], ) AC_ARG_WITH(cpg, [ --with-cs-quorum Support the consumption of membership and quorum from corosync ], [ SUPPORT_CS_QUORUM=$withval ], [ SUPPORT_CS_QUORUM=try ], ) AC_ARG_WITH(nagios, [ --with-nagios Support nagios remote monitoring ], [ SUPPORT_NAGIOS=$withval ], [ SUPPORT_NAGIOS=try ], ) AC_ARG_WITH(nagios-plugin-dir, [ --with-nagios-plugin-dir=DIR Directory for nagios plugins [${NAGIOS_PLUGIN_DIR}]], [ NAGIOS_PLUGIN_DIR="$withval" ] ) AC_ARG_WITH(nagios-metadata-dir, [ --with-nagios-metadata-dir=DIR Directory for nagios plugins metadata [${NAGIOS_METADATA_DIR}]], [ NAGIOS_METADATA_DIR="$withval" ] ) AC_ARG_WITH(snmp, [ --with-snmp Support the SNMP protocol ], [ SUPPORT_SNMP=$withval ], [ SUPPORT_SNMP=try ], ) AC_ARG_WITH(esmtp, [ --with-esmtp Support the sending mail notifications with the esmtp library ], [ SUPPORT_ESMTP=$withval ], [ SUPPORT_ESMTP=try ], ) AC_ARG_WITH(acl, [ --with-acl Support CIB ACL ], [ SUPPORT_ACL=$withval ], [ SUPPORT_ACL=no ], ) AC_ARG_WITH(cibsecrets, [ --with-cibsecrets Support CIB secrets ], [ SUPPORT_CIBSECRETS=$withval ], [ SUPPORT_CIBSECRETS=no ], ) CSPREFIX="" AC_ARG_WITH(ais-prefix, [ --with-ais-prefix=DIR Prefix used when Corosync was installed [$prefix]], [ CSPREFIX=$withval ], [ CSPREFIX=$prefix ]) LCRSODIR="" AC_ARG_WITH(lcrso-dir, [ --with-lcrso-dir=DIR Corosync lcrso files. ], [ LCRSODIR="$withval" ]) INITDIR="" AC_ARG_WITH(initdir, [ --with-initdir=DIR directory for init (rc) scripts [${INITDIR}]], [ INITDIR="$withval" ]) SUPPORT_PROFILING=0 AC_ARG_WITH(profiling, [ --with-profiling Disable optimizations for effective profiling ], [ SUPPORT_PROFILING=$withval ]) AC_ARG_WITH(coverage, [ --with-coverage Disable optimizations for effective profiling ], [ SUPPORT_COVERAGE=$withval ]) PUBLICAN_BRAND="common" AC_ARG_WITH(brand, [ --with-brand=brand Brand to use for generated documentation [$PUBLICAN_BRAND]], [ PUBLICAN_BRAND="$withval" ]) AC_SUBST(PUBLICAN_BRAND) ASCIIDOC_CLI_TYPE="pcs" AC_ARG_WITH(doc-cli, [ --with-doc-cli=cli_type CLI type to use for generated documentation. [$ASCIIDOC_CLI_TYPE]], [ ASCIIDOC_CLI_TYPE="$withval" ]) AC_SUBST(ASCIIDOC_CLI_TYPE) dnl =============================================== dnl General Processing dnl =============================================== AC_SUBST(HB_PKG) INIT_EXT="" echo Our Host OS: $host_os/$host AC_MSG_NOTICE(Sanitizing prefix: ${prefix}) case $prefix in NONE) prefix=/usr dnl Fix default variables - "prefix" variable if not specified if test "$localstatedir" = "\${prefix}/var"; then localstatedir="/var" fi if test "$sysconfdir" = "\${prefix}/etc"; then sysconfdir="/etc" fi ;; esac AC_MSG_NOTICE(Sanitizing exec_prefix: ${exec_prefix}) case $exec_prefix in dnl For consistency with Heartbeat, map NONE->$prefix NONE) exec_prefix=$prefix;; prefix) exec_prefix=$prefix;; esac AC_MSG_NOTICE(Sanitizing ais_prefix: ${CSPREFIX}) case $CSPREFIX in dnl For consistency with Heartbeat, map NONE->$prefix NONE) CSPREFIX=$prefix;; prefix) CSPREFIX=$prefix;; esac AC_MSG_NOTICE(Sanitizing INITDIR: ${INITDIR}) case $INITDIR in prefix) INITDIR=$prefix;; "") AC_MSG_CHECKING(which init (rc) directory to use) for initdir in /etc/init.d /etc/rc.d/init.d /sbin/init.d \ /usr/local/etc/rc.d /etc/rc.d do if test -d $initdir then INITDIR=$initdir break fi done AC_MSG_RESULT($INITDIR);; esac AC_SUBST(INITDIR) AC_MSG_NOTICE(Sanitizing libdir: ${libdir}) case $libdir in dnl For consistency with Heartbeat, map NONE->$prefix *prefix*|NONE) AC_MSG_CHECKING(which lib directory to use) for aDir in lib64 lib do trydir="${exec_prefix}/${aDir}" if test -d ${trydir} then libdir=${trydir} break fi done AC_MSG_RESULT($libdir); ;; esac dnl Expand autoconf variables so that we dont end up with '${prefix}' dnl in #defines and python scripts dnl NOTE: Autoconf deliberately leaves them unexpanded to allow dnl make exec_prefix=/foo install dnl No longer being able to do this seems like no great loss to me... eval prefix="`eval echo ${prefix}`" eval exec_prefix="`eval echo ${exec_prefix}`" eval bindir="`eval echo ${bindir}`" eval sbindir="`eval echo ${sbindir}`" eval libexecdir="`eval echo ${libexecdir}`" eval datadir="`eval echo ${datadir}`" eval sysconfdir="`eval echo ${sysconfdir}`" eval sharedstatedir="`eval echo ${sharedstatedir}`" eval localstatedir="`eval echo ${localstatedir}`" eval libdir="`eval echo ${libdir}`" eval includedir="`eval echo ${includedir}`" eval oldincludedir="`eval echo ${oldincludedir}`" eval infodir="`eval echo ${infodir}`" eval mandir="`eval echo ${mandir}`" dnl Home-grown variables eval INITDIR="${INITDIR}" eval docdir="`eval echo ${docdir}`" if test x"${docdir}" = x""; then docdir=${datadir}/doc/${PACKAGE}-${VERSION} #docdir=${datadir}/doc/packages/${PACKAGE} fi AC_SUBST(docdir) for j in prefix exec_prefix bindir sbindir libexecdir datadir sysconfdir \ sharedstatedir localstatedir libdir includedir oldincludedir infodir \ mandir INITDIR docdir do dirname=`eval echo '${'${j}'}'` if test ! -d "$dirname" then AC_MSG_WARN([$j directory ($dirname) does not exist!]) fi done dnl This OS-based decision-making is poor autotools practice; dnl feature-based mechanisms are strongly preferred. dnl dnl So keep this section to a bare minimum; regard as a "necessary evil". case "$host_os" in *bsd*) LIBS="-L/usr/local/lib" CPPFLAGS="$CPPFLAGS -I/usr/local/include" INIT_EXT=".sh" ;; *solaris*) ;; *linux*) AC_DEFINE_UNQUOTED(ON_LINUX, 1, Compiling for Linux platform) CFLAGS="$CFLAGS -I${prefix}/include" ;; darwin*) AC_DEFINE_UNQUOTED(ON_DARWIN, 1, Compiling for Darwin platform) LIBS="$LIBS -L${prefix}/lib" CFLAGS="$CFLAGS -I${prefix}/include" ;; esac dnl Eventually remove this CFLAGS="$CFLAGS -I${prefix}/include/heartbeat" AC_SUBST(INIT_EXT) AC_MSG_NOTICE(Host CPU: $host_cpu) case "$host_cpu" in ppc64|powerpc64) case $CFLAGS in *powerpc64*) ;; *) if test "$GCC" = yes; then CFLAGS="$CFLAGS -m64" fi ;; esac esac AC_MSG_CHECKING(which format is needed to print uint64_t) ac_save_CFLAGS=$CFLAGS CFLAGS="-Wall -Werror" AC_COMPILE_IFELSE( [AC_LANG_PROGRAM( [ #include #include #include ], [ int max = 512; uint64_t bignum = 42; char *buffer = malloc(max); const char *random = "random"; snprintf(buffer, max-1, "", bignum, random); fprintf(stderr, "Result: %s\n", buffer); ] )], [U64T="%lu"], [U64T="%llu"] ) CFLAGS=$ac_save_CFLAGS AC_MSG_RESULT($U64T) AC_DEFINE_UNQUOTED(U64T, "$U64T", Correct printf format for logging uint64_t) dnl =============================================== dnl Program Paths dnl =============================================== PATH="$PATH:/sbin:/usr/sbin:/usr/local/sbin:/usr/local/bin" export PATH dnl Replacing AC_PROG_LIBTOOL with AC_CHECK_PROG because LIBTOOL dnl was NOT being expanded all the time thus causing things to fail. AC_CHECK_PROGS(LIBTOOL, glibtool libtool libtool15 libtool13) AM_PATH_PYTHON AC_CHECK_PROGS(MAKE, gmake make) AC_PATH_PROGS(HTML2TXT, lynx w3m) AC_PATH_PROGS(HELP2MAN, help2man) AC_PATH_PROGS(POD2MAN, pod2man, pod2man) AC_PATH_PROGS(ASCIIDOC, asciidoc) AC_PATH_PROGS(PUBLICAN, publican) AC_PATH_PROGS(INKSCAPE, inkscape) AC_PATH_PROGS(XSLTPROC, xsltproc) AC_PATH_PROGS(FOP, fop) AC_PATH_PROGS(SSH, ssh, /usr/bin/ssh) AC_PATH_PROGS(SCP, scp, /usr/bin/scp) AC_PATH_PROGS(TAR, tar) AC_PATH_PROGS(MD5, md5) AC_PATH_PROGS(TEST, test) AC_PATH_PROGS(PKGCONFIG, pkg-config) AC_PATH_PROGS(XML2CONFIG, xml2-config) AC_PATH_PROGS(VALGRIND_BIN, valgrind, /usr/bin/valgrind) AC_DEFINE_UNQUOTED(VALGRIND_BIN, "$VALGRIND_BIN", Valgrind command) dnl Disable these until we decide if the stonith config file should be supported dnl AC_PATH_PROGS(BISON, bison) dnl AC_PATH_PROGS(FLEX, flex) dnl AC_PATH_PROGS(HAVE_YACC, $YACC) if test x"${LIBTOOL}" = x""; then AC_MSG_ERROR(You need (g)libtool installed in order to build ${PACKAGE}) fi if test x"${MAKE}" = x""; then AC_MSG_ERROR(You need (g)make installed in order to build ${PACKAGE}) fi AM_CONDITIONAL(BUILD_HELP, test x"${HELP2MAN}" != x"") if test x"${HELP2MAN}" != x""; then PCMK_FEATURES="$PCMK_FEATURES generated-manpages" fi MANPAGE_XSLT="" if test x"${XSLTPROC}" != x""; then AC_MSG_CHECKING(docbook to manpage transform) XSLT=`find ${datadir} -name docbook.xsl` for xsl in $XSLT; do dname=`dirname $xsl` bname=`basename $dname` if test "$bname" = "manpages"; then MANPAGE_XSLT="$xsl" break fi done fi AC_MSG_RESULT($MANPAGE_XSLT) AC_SUBST(MANPAGE_XSLT) AM_CONDITIONAL(BUILD_XML_HELP, test x"${MANPAGE_XSLT}" != x"") if test x"${MANPAGE_XSLT}" != x""; then PCMK_FEATURES="$PCMK_FEATURES agent-manpages" fi AM_CONDITIONAL(BUILD_ASCIIDOC, test x"${ASCIIDOC}" != x"") if test x"${ASCIIDOC}" != x""; then PCMK_FEATURES="$PCMK_FEATURES ascii-docs" fi SUPPORT_STONITH_CONFIG=0 if test x"${HAVE_YACC}" != x"" -a x"${FLEX}" != x"" -a x"${BISON}" != x""; then SUPPORT_STONITH_CONFIG=1 PCMK_FEATURES="$PCMK_FEATURES st-conf" fi AM_CONDITIONAL(BUILD_STONITH_CONFIG, test $SUPPORT_STONITH_CONFIG = 1) AC_DEFINE_UNQUOTED(SUPPORT_STONITH_CONFIG, $SUPPORT_STONITH_CONFIG, Support a stand-alone stonith config file in addition to the CIB) AM_CONDITIONAL(BUILD_DOCBOOK, test x"${PUBLICAN}" != x"" -a x"${INKSCAPE}" != x"") if test x"${PUBLICAN}" != x"" -a x"${INKSCAPE}" != x""; then AC_MSG_NOTICE(Enabling publican) PCMK_FEATURES="$PCMK_FEATURES publican-docs" fi dnl ======================================================================== dnl checks for library functions to replace them dnl dnl NoSuchFunctionName: dnl is a dummy function which no system supplies. It is here to make dnl the system compile semi-correctly on OpenBSD which doesn't know dnl how to create an empty archive dnl dnl scandir: Only on BSD. dnl System-V systems may have it, but hidden and/or deprecated. dnl A replacement function is supplied for it. dnl dnl setenv: is some bsdish function that should also be avoided (use dnl putenv instead) dnl On the other hand, putenv doesn't provide the right API for the dnl code and has memory leaks designed in (sigh...) Fortunately this dnl A replacement function is supplied for it. dnl dnl strerror: returns a string that corresponds to an errno. dnl A replacement function is supplied for it. dnl dnl strnlen: is a gnu function similar to strlen, but safer. dnl We wrote a tolearably-fast replacement function for it. dnl dnl strndup: is a gnu function similar to strdup, but safer. dnl We wrote a tolearably-fast replacement function for it. AC_REPLACE_FUNCS(alphasort NoSuchFunctionName scandir setenv strerror strchrnul unsetenv strnlen strndup) dnl =============================================== dnl Libraries dnl =============================================== AC_CHECK_LIB(socket, socket) dnl -lsocket AC_CHECK_LIB(c, dlopen) dnl if dlopen is in libc... AC_CHECK_LIB(dl, dlopen) dnl -ldl (for Linux) AC_CHECK_LIB(rt, sched_getscheduler) dnl -lrt (for Tru64) AC_CHECK_LIB(gnugetopt, getopt_long) dnl -lgnugetopt ( if available ) AC_CHECK_LIB(pam, pam_start) dnl -lpam (if available) AC_CHECK_FUNCS([sched_getparam sched_setparam sched_get_priority_min]) AC_CHECK_LIB(uuid, uuid_parse) dnl load the library if necessary AC_CHECK_FUNCS(uuid_unparse) dnl OSX ships uuid_* as standard functions AC_CHECK_HEADERS(uuid/uuid.h) if test "x$ac_cv_func_uuid_unparse" != xyes; then AC_MSG_ERROR(You do not have the libuuid development package installed) fi if test x"${PKGCONFIG}" = x""; then AC_MSG_ERROR(You need pkgconfig installed in order to build ${PACKAGE}) fi if test "x${enable_thread_safe}" = "xyes"; then GPKGNAME="gthread-2.0" else GPKGNAME="glib-2.0" fi if $PKGCONFIG --exists $GPKGNAME then GLIBCONFIG="$PKGCONFIG $GPKGNAME" else set -x echo PKG_CONFIG_PATH=$PKG_CONFIG_PATH $PKGCONFIG --exists $GPKGNAME; echo $? $PKGCONFIG --cflags $GPKGNAME; echo $? $PKGCONFIG $GPKGNAME; echo $? set +x AC_MSG_ERROR(You need glib2-devel installed in order to build ${PACKAGE}) fi AC_MSG_RESULT(using $GLIBCONFIG) # # Where is dlopen? # if test "$ac_cv_lib_c_dlopen" = yes; then LIBADD_DL="" elif test "$ac_cv_lib_dl_dlopen" = yes; then LIBADD_DL=-ldl else LIBADD_DL=${lt_cv_dlopen_libs} fi dnl dnl Check for location of gettext dnl dnl On at least Solaris 2.x, where it is in libc, specifying lintl causes dnl grief. Ensure minimal result, not the sum of all possibilities. dnl And do libc first. dnl Known examples: dnl c: Linux, Solaris 2.6+ dnl intl: BSD, AIX AC_CHECK_LIB(c, gettext) if test x$ac_cv_lib_c_gettext != xyes; then AC_CHECK_LIB(intl, gettext) fi if test x$ac_cv_lib_c_gettext != xyes -a x$ac_cv_lib_intl_gettext != xyes; then AC_MSG_ERROR(You need gettext installed in order to build ${PACKAGE}) fi if test "X$GLIBCONFIG" != X; then AC_MSG_CHECKING(for special glib includes: ) GLIBHEAD=`$GLIBCONFIG --cflags` AC_MSG_RESULT($GLIBHEAD) CPPFLAGS="$CPPFLAGS $GLIBHEAD" AC_MSG_CHECKING(for glib library flags) GLIBLIB=`$GLIBCONFIG --libs` AC_MSG_RESULT($GLIBLIB) LIBS="$LIBS $GLIBLIB" fi dnl ======================================================================== dnl Headers dnl ======================================================================== AC_HEADER_STDC AC_CHECK_HEADERS(arpa/inet.h) AC_CHECK_HEADERS(asm/types.h) AC_CHECK_HEADERS(assert.h) AC_CHECK_HEADERS(auth-client.h) AC_CHECK_HEADERS(ctype.h) AC_CHECK_HEADERS(dirent.h) AC_CHECK_HEADERS(errno.h) AC_CHECK_HEADERS(fcntl.h) AC_CHECK_HEADERS(getopt.h) AC_CHECK_HEADERS(glib.h) AC_CHECK_HEADERS(grp.h) AC_CHECK_HEADERS(limits.h) AC_CHECK_HEADERS(linux/errqueue.h) AC_CHECK_HEADERS(malloc.h) AC_CHECK_HEADERS(netdb.h) AC_CHECK_HEADERS(netinet/in.h) AC_CHECK_HEADERS(netinet/ip.h) AC_CHECK_HEADERS(pam/pam_appl.h) AC_CHECK_HEADERS(pthread.h) AC_CHECK_HEADERS(pwd.h) AC_CHECK_HEADERS(security/pam_appl.h) AC_CHECK_HEADERS(sgtty.h) AC_CHECK_HEADERS(signal.h) AC_CHECK_HEADERS(stdarg.h) AC_CHECK_HEADERS(stddef.h) AC_CHECK_HEADERS(stdio.h) AC_CHECK_HEADERS(stdlib.h) AC_CHECK_HEADERS(string.h) AC_CHECK_HEADERS(strings.h) AC_CHECK_HEADERS(sys/dir.h) AC_CHECK_HEADERS(sys/ioctl.h) AC_CHECK_HEADERS(sys/param.h) AC_CHECK_HEADERS(sys/poll.h) AC_CHECK_HEADERS(sys/reboot.h) AC_CHECK_HEADERS(sys/resource.h) AC_CHECK_HEADERS(sys/select.h) AC_CHECK_HEADERS(sys/socket.h) AC_CHECK_HEADERS(sys/signalfd.h) AC_CHECK_HEADERS(sys/sockio.h) AC_CHECK_HEADERS(sys/stat.h) AC_CHECK_HEADERS(sys/time.h) AC_CHECK_HEADERS(sys/timeb.h) AC_CHECK_HEADERS(sys/types.h) AC_CHECK_HEADERS(sys/uio.h) AC_CHECK_HEADERS(sys/un.h) AC_CHECK_HEADERS(sys/utsname.h) AC_CHECK_HEADERS(sys/wait.h) AC_CHECK_HEADERS(time.h) AC_CHECK_HEADERS(unistd.h) AC_CHECK_HEADERS(winsock.h) dnl These headers need prerequisits before the tests will pass dnl AC_CHECK_HEADERS(net/if.h) dnl AC_CHECK_HEADERS(netinet/icmp6.h) dnl AC_CHECK_HEADERS(netinet/ip6.h) dnl AC_CHECK_HEADERS(netinet/ip_icmp.h) AC_MSG_CHECKING(for special libxml2 includes) if test "x$XML2CONFIG" = "x"; then AC_MSG_ERROR(libxml2 config not found) else XML2HEAD="`$XML2CONFIG --cflags`" AC_MSG_RESULT($XML2HEAD) AC_CHECK_LIB(xml2, xmlReadMemory) AC_CHECK_LIB(xslt, xsltApplyStylesheet) fi CPPFLAGS="$CPPFLAGS $XML2HEAD" AC_CHECK_HEADERS(libxml/xpath.h) AC_CHECK_HEADERS(libxslt/xslt.h) if test "$ac_cv_header_libxml_xpath_h" != "yes"; then AC_MSG_ERROR(The libxml developement headers were not found) fi if test "$ac_cv_header_libxslt_xslt_h" != "yes"; then AC_MSG_ERROR(The libxslt developement headers were not found) fi dnl ======================================================================== dnl Structures dnl ======================================================================== AC_CHECK_MEMBERS([struct tm.tm_gmtoff],,,[[#include ]]) AC_CHECK_MEMBERS([lrm_op_t.rsc_deleted],,,[[#include ]]) dnl ======================================================================== dnl Functions dnl ======================================================================== AC_CHECK_FUNCS(g_log_set_default_handler) AC_CHECK_FUNCS(getopt, AC_DEFINE(HAVE_DECL_GETOPT, 1, [Have getopt function])) AC_CHECK_FUNCS(nanosleep, AC_DEFINE(HAVE_DECL_NANOSLEEP, 1, [Have nanosleep function])) dnl ======================================================================== dnl ltdl dnl ======================================================================== AC_CHECK_LIB(ltdl, lt_dlopen, [LTDL_foo=1]) if test "x${enable_bundled_ltdl}" = "xyes"; then if test $ac_cv_lib_ltdl_lt_dlopen = yes; then AC_MSG_NOTICE([Disabling usage of installed ltdl]) fi ac_cv_lib_ltdl_lt_dlopen=no fi LIBLTDL_DIR="" if test $ac_cv_lib_ltdl_lt_dlopen != yes ; then AC_MSG_NOTICE([Installing local ltdl]) LIBLTDL_DIR=libltdl ( cd $srcdir ; $TAR -xvf libltdl.tar ) if test "$?" -ne 0; then AC_MSG_ERROR([$TAR of libltdl.tar in $srcdir failed]) fi AC_CONFIG_SUBDIRS(libltdl) else LIBS="$LIBS -lltdl" AC_MSG_NOTICE([Using installed ltdl]) INCLTDL="" LIBLTDL="" fi AC_SUBST(INCLTDL) AC_SUBST(LIBLTDL) AC_SUBST(LIBLTDL_DIR) dnl ======================================================================== dnl bzip2 dnl ======================================================================== AC_CHECK_HEADERS(bzlib.h) AC_CHECK_LIB(bz2, BZ2_bzBuffToBuffCompress) if test x$ac_cv_lib_bz2_BZ2_bzBuffToBuffCompress != xyes ; then AC_MSG_ERROR(BZ2 libraries not found) fi if test x$ac_cv_header_bzlib_h != xyes; then AC_MSG_ERROR(BZ2 Development headers not found) fi dnl ======================================================================== dnl sighandler_t is missing from Illumos, Solaris11 systems dnl ======================================================================== AC_MSG_CHECKING([for sighandler_t]) AC_TRY_COMPILE([#include ],[sighandler_t *f;], has_sighandler_t=yes,has_sighandler_t=no) AC_MSG_RESULT($has_sighandler_t) if test "$has_sighandler_t" = "yes" ; then AC_DEFINE( HAVE_SIGHANDLER_T, 1, [Define if sighandler_t available] ) fi dnl ======================================================================== dnl ncurses dnl ======================================================================== dnl dnl A few OSes (e.g. Linux) deliver a default "ncurses" alongside "curses". dnl Many non-Linux deliver "curses"; sites may add "ncurses". dnl dnl However, the source-code recommendation for both is to #include "curses.h" dnl (i.e. "ncurses" still wants the include to be simple, no-'n', "curses.h"). dnl dnl ncurse takes precedence. dnl AC_CHECK_HEADERS(curses.h) AC_CHECK_HEADERS(curses/curses.h) AC_CHECK_HEADERS(ncurses.h) AC_CHECK_HEADERS(ncurses/ncurses.h) dnl Although n-library is preferred, only look for it if the n-header was found. CURSESLIBS='' if test "$ac_cv_header_ncurses_h" = "yes"; then AC_CHECK_LIB(ncurses, printw, [CURSESLIBS='-lncurses'; AC_DEFINE(HAVE_LIBNCURSES,1, have ncurses library)] ) fi if test "$ac_cv_header_ncurses_ncurses_h" = "yes"; then AC_CHECK_LIB(ncurses, printw, [CURSESLIBS='-lncurses'; AC_DEFINE(HAVE_LIBNCURSES,1, have ncurses library)] ) fi dnl Only look for non-n-library if there was no n-library. if test X"$CURSESLIBS" = X"" -a "$ac_cv_header_curses_h" = "yes"; then AC_CHECK_LIB(curses, printw, [CURSESLIBS='-lcurses'; AC_DEFINE(HAVE_LIBCURSES,1, have curses library)] ) fi dnl Only look for non-n-library if there was no n-library. if test X"$CURSESLIBS" = X"" -a "$ac_cv_header_curses_curses_h" = "yes"; then AC_CHECK_LIB(curses, printw, [CURSESLIBS='-lcurses'; AC_DEFINE(HAVE_LIBCURSES,1, have curses library)] ) fi if test "x$CURSESLIBS" != "x"; then PCMK_FEATURES="$PCMK_FEATURES ncurses" fi dnl Check for printw() prototype compatibility if test X"$CURSESLIBS" != X"" && cc_supports_flag -Wcast-qual && cc_supports_flag -Werror; then AC_MSG_CHECKING(whether printw() requires argument of "const char *") ac_save_LIBS=$LIBS LIBS="$CURSESLIBS $LIBS" ac_save_CFLAGS=$CFLAGS CFLAGS="-Wcast-qual -Werror" AC_LINK_IFELSE( [AC_LANG_PROGRAM( [ #if defined(HAVE_NCURSES_H) # include #elif defined(HAVE_NCURSES_NCURSES_H) # include #elif defined(HAVE_CURSES_H) # include #endif ], [printw((const char *)"Test");] )], [ac_cv_compatible_printw=yes], [ac_cv_compatible_printw=no] ) LIBS=$ac_save_LIBS CFLAGS=$ac_save_CFLAGS AC_MSG_RESULT([$ac_cv_compatible_printw]) if test "$ac_cv_compatible_printw" = no; then AC_MSG_WARN([The printw() function of your ncurses or curses library is old, we will disable usage of the library. If you want to use this library anyway, please update to newer version of the library, ncurses 5.4 or later is recommended. You can get the library from http://www.gnu.org/software/ncurses/.]) AC_MSG_NOTICE([Disabling curses]) AC_DEFINE(HAVE_INCOMPATIBLE_PRINTW, 1, [Do we have incompatible printw() in curses library?]) fi fi AC_SUBST(CURSESLIBS) dnl ======================================================================== dnl Profiling and GProf dnl ======================================================================== AC_MSG_NOTICE(Old CFLAGS: $CFLAGS) case $SUPPORT_COVERAGE in 1|yes|true) SUPPORT_PROFILING=1 PCMK_FEATURES="$PCMK_FEATURES coverage" CFLAGS="$CFLAGS -fprofile-arcs -ftest-coverage" dnl During linking, make sure to specify -lgcov or -coverage dnl Enable gprof #LIBS="$LIBS -pg" #CFLAGS="$CFLAGS -pg" ;; esac case $SUPPORT_PROFILING in 1|yes|true) SUPPORT_PROFILING=1 dnl Disable various compiler optimizations CFLAGS="$CFLAGS -fno-omit-frame-pointer -fno-inline" dnl CFLAGS="$CFLAGS -fno-inline-functions -fno-default-inline -fno-inline-functions-called-once -fno-optimize-sibling-calls" dnl Turn off optimization so tools can get accurate line numbers CFLAGS=`echo $CFLAGS | sed -e 's/-O.\ //g' -e 's/-Wp,-D_FORTIFY_SOURCE=.\ //g' -e 's/-D_FORTIFY_SOURCE=.\ //g'` CFLAGS="$CFLAGS -O0" dnl Update features PCMK_FEATURES="$PCMK_FEATURES profile" ;; *) SUPPORT_PROFILING=0;; esac AC_MSG_NOTICE(New CFLAGS: $CFLAGS) AC_DEFINE_UNQUOTED(SUPPORT_PROFILING, $SUPPORT_PROFILING, Support for profiling) dnl ======================================================================== dnl Cluster infrastructure - Heartbeat / LibQB dnl ======================================================================== dnl Compatability checks AC_CHECK_MEMBERS([struct lrm_ops.fail_rsc],,,[[#include ]]) if test x${enable_no_stack} = xyes; then SUPPORT_HEARTBEAT=no SUPPORT_CS=no fi PKG_CHECK_MODULES(libqb, libqb, HAVE_libqb=1, HAVE_libqb=0) AC_CHECK_HEADERS(qb/qbipc_common.h) AC_CHECK_LIB(qb, qb_ipcs_connection_auth_set) LIBQB_LOG=1 PCMK_FEATURES="$PCMK_FEATURES libqb-logging libqb-ipc" if ! pkg-config --atleast-version 0.13 libqb then AC_MSG_FAILURE(Version of libqb is too old: v0.13 or greater requried) fi LIBS="$LIBS $libqb_LIBS" AC_CHECK_HEADERS(heartbeat/hb_config.h) AC_CHECK_HEADERS(heartbeat/glue_config.h) AC_CHECK_HEADERS(stonith/stonith.h) AC_CHECK_HEADERS(agent_config.h) GLUE_HEADER=none HAVE_GLUE=0 if test "$ac_cv_header_heartbeat_glue_config_h" = "yes"; then GLUE_HEADER=glue_config.h HAVE_GLUE=1 elif test "$ac_cv_header_heartbeat_hb_config_h" = "yes"; then GLUE_HEADER=hb_config.h HAVE_GLUE=1 else AC_MSG_WARN(cluster-glue development headers were not found) fi if test "$ac_cv_header_stonith_stonith_h" = "yes"; then PCMK_FEATURES="$PCMK_FEATURES lha-fencing" fi if test $HAVE_GLUE = 1; then dnl On Debian, AC_CHECK_LIBS fail if a library has any unresolved symbols dnl So check for all the depenancies (so they're added to LIBS) before checking for -lplumb AC_CHECK_LIB(pils, PILLoadPlugin) AC_CHECK_LIB(plumb, G_main_add_IPC_Channel) fi dnl =============================================== dnl Variables needed for substitution dnl =============================================== CRM_DTD_DIRECTORY="${datadir}/pacemaker" AC_DEFINE_UNQUOTED(CRM_DTD_DIRECTORY,"$CRM_DTD_DIRECTORY", Location for the Pacemaker Relax-NG Schema) AC_SUBST(CRM_DTD_DIRECTORY) AC_DEFINE_UNQUOTED(CRM_DTD_VERSION,"$CRM_DTD_VERSION", Current version of the Pacemaker Relax-NG Schema) AC_SUBST(CRM_DTD_VERSION) CRM_CORE_DIR=`try_extract_header_define $GLUE_HEADER HA_COREDIR ${localstatedir}/lib/pacemaker/cores` AC_DEFINE_UNQUOTED(CRM_CORE_DIR,"$CRM_CORE_DIR", Location to store core files produced by Pacemaker daemons) AC_SUBST(CRM_CORE_DIR) CRM_DAEMON_USER=`try_extract_header_define $GLUE_HEADER HA_CCMUSER hacluster` AC_DEFINE_UNQUOTED(CRM_DAEMON_USER,"$CRM_DAEMON_USER", User to run Pacemaker daemons as) AC_SUBST(CRM_DAEMON_USER) CRM_DAEMON_GROUP=`try_extract_header_define $GLUE_HEADER HA_APIGROUP haclient` AC_DEFINE_UNQUOTED(CRM_DAEMON_GROUP,"$CRM_DAEMON_GROUP", Group to run Pacemaker daemons as) AC_SUBST(CRM_DAEMON_GROUP) CRM_STATE_DIR=${localstatedir}/run/crm AC_DEFINE_UNQUOTED(CRM_STATE_DIR,"$CRM_STATE_DIR", Where to keep state files and sockets) AC_SUBST(CRM_STATE_DIR) CRM_BLACKBOX_DIR=${localstatedir}/lib/pacemaker/blackbox AC_DEFINE_UNQUOTED(CRM_BLACKBOX_DIR,"$CRM_BLACKBOX_DIR", Where to keep blackbox dumps) AC_SUBST(CRM_BLACKBOX_DIR) PE_STATE_DIR="${localstatedir}/lib/pacemaker/pengine" AC_DEFINE_UNQUOTED(PE_STATE_DIR,"$PE_STATE_DIR", Where to keep PEngine outputs) AC_SUBST(PE_STATE_DIR) CRM_CONFIG_DIR="${localstatedir}/lib/pacemaker/cib" AC_DEFINE_UNQUOTED(CRM_CONFIG_DIR,"$CRM_CONFIG_DIR", Where to keep configuration files) AC_SUBST(CRM_CONFIG_DIR) CRM_LEGACY_CONFIG_DIR="${localstatedir}/lib/heartbeat/crm" AC_DEFINE_UNQUOTED(CRM_LEGACY_CONFIG_DIR,"$CRM_LEGACY_CONFIG_DIR", Where Pacemaker used to keep configuration files) AC_SUBST(CRM_LEGACY_CONFIG_DIR) CRM_DAEMON_DIR="${libexecdir}/pacemaker" AC_DEFINE_UNQUOTED(CRM_DAEMON_DIR,"$CRM_DAEMON_DIR", Location for Pacemaker daemons) AC_SUBST(CRM_DAEMON_DIR) HB_DAEMON_DIR=`try_extract_header_define $GLUE_HEADER HA_LIBHBDIR $libdir/heartbeat` AC_DEFINE_UNQUOTED(HB_DAEMON_DIR,"$HB_DAEMON_DIR", Location Heartbeat expects Pacemaker daemons to be in) AC_SUBST(HB_DAEMON_DIR) dnl Needed so that the Corosync plugin can clear out the directory as Heartbeat does HA_STATE_DIR=`try_extract_header_define $GLUE_HEADER HA_VARRUNDIR ${localstatedir}/run` AC_DEFINE_UNQUOTED(HA_STATE_DIR,"$HA_STATE_DIR", Where Heartbeat keeps state files and sockets) AC_SUBST(HA_STATE_DIR) CRM_RSCTMP_DIR=`try_extract_header_define agent_config.h HA_RSCTMPDIR $HA_STATE_DIR/resource-agents` AC_MSG_CHECKING(Scratch dir for resource agents) AC_MSG_RESULT($CRM_RSCTMP_DIR) AC_DEFINE_UNQUOTED(CRM_RSCTMP_DIR,"$CRM_RSCTMP_DIR", Where resource agents should keep state files) AC_SUBST(CRM_RSCTMP_DIR) dnl Needed for the location of hostcache in CTS.py HA_VARLIBHBDIR=`try_extract_header_define $GLUE_HEADER HA_VARLIBHBDIR ${localstatedir}/lib/heartbeat` AC_SUBST(HA_VARLIBHBDIR) AC_DEFINE_UNQUOTED(UUID_FILE,"$localstatedir/lib/heartbeat/hb_uuid", Location of Heartbeat's UUID file) OCF_ROOT_DIR=`try_extract_header_define $GLUE_HEADER OCF_ROOT_DIR /usr/lib/ocf` if test "X$OCF_ROOT_DIR" = X; then AC_MSG_ERROR(Could not locate OCF directory) fi AC_SUBST(OCF_ROOT_DIR) OCF_RA_DIR=`try_extract_header_define $GLUE_HEADER OCF_RA_DIR $OCF_ROOT_DIR/resource.d` AC_DEFINE_UNQUOTED(OCF_RA_DIR,"$OCF_RA_DIR", Location for OCF RAs) AC_SUBST(OCF_RA_DIR) RH_STONITH_DIR="$sbindir" AC_DEFINE_UNQUOTED(RH_STONITH_DIR,"$RH_STONITH_DIR", Location for Red Hat Stonith agents) RH_STONITH_PREFIX="fence_" AC_DEFINE_UNQUOTED(RH_STONITH_PREFIX,"$RH_STONITH_PREFIX", Prefix for Red Hat Stonith agents) AC_PATH_PROGS(GIT, git false) AC_MSG_CHECKING(build version) BUILD_VERSION=42f2063 if test $BUILD_VERSION != ":%h$"; then AC_MSG_RESULT(archive hash: $BUILD_VERSION) elif test -x $GIT -a -d .git; then BUILD_VERSION=`$GIT log --pretty="format:%h" -n 1` AC_MSG_RESULT(git hash: $BUILD_VERSION) else # The current directory name make a reasonable default # Most generated archives will include the hash or tag BASE=`basename $PWD` BUILD_VERSION=`echo $BASE | sed s:.*[[Pp]]acemaker-::` AC_MSG_RESULT(directory based hash: $BUILD_VERSION) fi AC_DEFINE_UNQUOTED(BUILD_VERSION, "$BUILD_VERSION", Build version) AC_SUBST(BUILD_VERSION) HAVE_gio=1 HAVE_upstart=0 HAVE_systemd=0 PKG_CHECK_MODULES(GIO, gio-2.0, ,HAVE_gio=0) AC_CHECK_TYPE([GDBusProxy],,,[[#include ]]) if test x$ac_cv_type_GDBusProxy != xyes; then HAVE_gio=0 AC_MSG_WARN(Unable to support systemd/upstart. You need to use glib >= 2.26) fi if test $HAVE_gio = 1 -a "x${enable_upstart}" != xno; then HAVE_upstart=1 PCMK_FEATURES="$PCMK_FEATURES upstart" fi AC_DEFINE_UNQUOTED(SUPPORT_UPSTART, $HAVE_upstart, Support upstart based system services) AM_CONDITIONAL(BUILD_UPSTART, test $HAVE_upstart = 1) if $PKGCONFIG --exists systemd then systemdunitdir=`$PKGCONFIG --variable=systemdsystemunitdir systemd` AC_SUBST(systemdunitdir) else enable_systemd=no fi if test $HAVE_gio = 1 -a "x${enable_systemd}" != xno; then if test -n "$systemdunitdir" -a "x$systemdunitdir" != xno; then HAVE_systemd=1 PCMK_FEATURES="$PCMK_FEATURES systemd" fi fi AC_DEFINE_UNQUOTED(SUPPORT_SYSTEMD, $HAVE_systemd, Support systemd based system services) AM_CONDITIONAL(BUILD_SYSTEMD, test $HAVE_systemd = 1) case $SUPPORT_NAGIOS in 1|yes|true|try) SUPPORT_NAGIOS=1;; *) SUPPORT_NAGIOS=0;; esac if test $SUPPORT_NAGIOS = 1; then PCMK_FEATURES="$PCMK_FEATURES nagios" fi AC_DEFINE_UNQUOTED(SUPPORT_NAGIOS, $SUPPORT_NAGIOS, Support nagios plugins) AM_CONDITIONAL(BUILD_NAGIOS, test $SUPPORT_NAGIOS = 1) if test x"$NAGIOS_PLUGIN_DIR" = x""; then NAGIOS_PLUGIN_DIR="${libexecdir}/nagios/plugins" fi AC_DEFINE_UNQUOTED(NAGIOS_PLUGIN_DIR, "$NAGIOS_PLUGIN_DIR", Directory for nagios plugins) AC_SUBST(NAGIOS_PLUGIN_DIR) if test x"$NAGIOS_METADATA_DIR" = x""; then NAGIOS_METADATA_DIR="${datadir}/nagios/plugins-metadata" fi AC_DEFINE_UNQUOTED(NAGIOS_METADATA_DIR, "$NAGIOS_METADATA_DIR", Directory for nagios plugins metadata) AC_SUBST(NAGIOS_METADATA_DIR) STACKS="" CLUSTERLIBS="" dnl ======================================================================== dnl Cluster stack - Heartbeat dnl ======================================================================== case $SUPPORT_HEARTBEAT in 1|yes|true|try) AC_MSG_CHECKING(for heartbeat support) AC_CHECK_LIB(hbclient, ll_cluster_new, [SUPPORT_HEARTBEAT=1], [if test $SUPPORT_HEARTBEAT != try; then AC_MSG_FAILURE(Unable to support Heartbeat: client libraries not found) fi]) if test $SUPPORT_HEARTBEAT = 1 ; then STACKS="$STACKS heartbeat" dnl objdump -x ${libdir}/libccmclient.so | grep SONAME | awk '{print $2}' AC_DEFINE_UNQUOTED(CCM_LIBRARY, "libccmclient.so.1", Library to load for ccm support) AC_DEFINE_UNQUOTED(HEARTBEAT_LIBRARY, "libhbclient.so.1", Library to load for heartbeat support) else SUPPORT_HEARTBEAT=0 fi ;; *) SUPPORT_HEARTBEAT=0;; esac AM_CONDITIONAL(BUILD_HEARTBEAT_SUPPORT, test $SUPPORT_HEARTBEAT = 1) AC_DEFINE_UNQUOTED(SUPPORT_HEARTBEAT, $SUPPORT_HEARTBEAT, Support the Heartbeat messaging and membership layer) AC_SUBST(SUPPORT_HEARTBEAT) dnl ======================================================================== dnl Cluster stack - Corosync dnl ======================================================================== dnl Normalize the values case $SUPPORT_CS in 1|yes|true) SUPPORT_CS=yes missingisfatal=1;; try) missingisfatal=0;; *) SUPPORT_CS=no;; esac AC_MSG_CHECKING(for native corosync) COROSYNC_LIBS="" CS_USES_LIBQB=0 PCMK_SERVICE_ID=9 LCRSODIR="$libdir" if test $SUPPORT_CS = no; then AC_MSG_RESULT(no (disabled)) SUPPORT_CS=0 else AC_MSG_RESULT($SUPPORT_CS, with '$CSPREFIX') PKG_CHECK_MODULES(cpg, libcpg) dnl Fatal PKG_CHECK_MODULES(cfg, libcfg) dnl Fatal PKG_CHECK_MODULES(cmap, libcmap, HAVE_cmap=1, HAVE_cmap=0) PKG_CHECK_MODULES(cman, libcman, HAVE_cman=1, HAVE_cman=0) PKG_CHECK_MODULES(confdb, libconfdb, HAVE_confdb=1, HAVE_confdb=0) PKG_CHECK_MODULES(fenced, libfenced, HAVE_fenced=1, HAVE_fenced=0) PKG_CHECK_MODULES(quorum, libquorum, HAVE_quorum=1, HAVE_quorum=0) PKG_CHECK_MODULES(oldipc, libcoroipcc, HAVE_oldipc=1, HAVE_oldipc=0) if test $HAVE_oldipc = 1; then SUPPORT_CS=1 CFLAGS="$CFLAGS $oldipc_FLAGS $cpg_FLAGS $cfg_FLAGS" COROSYNC_LIBS="$COROSYNC_LIBS $oldipc_LIBS $cpg_LIBS $cfg_LIBS" elif test $HAVE_libqb = 1; then SUPPORT_CS=1 CS_USES_LIBQB=1 CFLAGS="$CFLAGS $libqb_FLAGS $cpg_FLAGS $cfg_FLAGS" COROSYNC_LIBS="$COROSYNC_LIBS $libqb_LIBS $cpg_LIBS $cfg_LIBS" AC_CHECK_LIB(corosync_common, cs_strerror) else aisreason="corosync/libqb IPC libraries not found by pkg_config" fi AC_DEFINE_UNQUOTED(HAVE_CONFDB, $HAVE_confdb, Have the old herarchial Corosync config API) AC_DEFINE_UNQUOTED(HAVE_CMAP, $HAVE_cmap, Have the new non-herarchial Corosync config API) fi if test $SUPPORT_CS = 1 -a x$HAVE_oldipc = x0 ; then dnl Support for plugins was removed about the time the IPC was dnl moved to libqb. dnl The only option now is the built-in quorum API CFLAGS="$CFLAGS $cmap_CFLAGS $quorum_CFLAGS" COROSYNC_LIBS="$COROSYNC_LIBS $cmap_LIBS $quorum_LIBS" STACKS="$STACKS corosync-native" AC_DEFINE_UNQUOTED(SUPPORT_CS_QUORUM, 1, Support the consumption of membership and quorum from corosync) fi SUPPORT_PLUGIN=0 if test $SUPPORT_CS = 1 -a x$HAVE_confdb = x1; then dnl Need confdb to support cman and the plugins SUPPORT_PLUGIN=1 LCRSODIR=`$PKGCONFIG corosync --variable=lcrsodir` STACKS="$STACKS corosync-plugin" COROSYNC_LIBS="$COROSYNC_LIBS $confdb_LIBS" if test $SUPPORT_CMAN != no; then if test $HAVE_cman = 1 -a $HAVE_fenced = 1; then SUPPORT_CMAN=1 STACKS="$STACKS cman" CFLAGS="$CFLAGS $cman_FLAGS $fenced_FLAGS" COROSYNC_LIBS="$COROSYNC_LIBS $cman_LIBS $fenced_LIBS" fi fi fi dnl Normalize SUPPORT_CS and SUPPORT_CMAN for use with #if directives if test $SUPPORT_CMAN != 1; then SUPPORT_CMAN=0 fi if test $SUPPORT_CS = 1; then CLUSTERLIBS="$CLUSTERLIBS $COROSYNC_LIBS" elif test $SUPPORT_CS != 0; then SUPPORT_CS=0 if test $missingisfatal = 0; then AC_MSG_WARN(Unable to support Corosync: $aisreason) else AC_MSG_FAILURE(Unable to support Corosync: $aisreason) fi fi AC_DEFINE_UNQUOTED(SUPPORT_COROSYNC, $SUPPORT_CS, Support the Corosync messaging and membership layer) AC_DEFINE_UNQUOTED(SUPPORT_CMAN, $SUPPORT_CMAN, Support the consumption of membership and quorum from cman) AC_DEFINE_UNQUOTED(CS_USES_LIBQB, $CS_USES_LIBQB, Does corosync use libqb for its ipc) AC_DEFINE_UNQUOTED(PCMK_SERVICE_ID, $PCMK_SERVICE_ID, Corosync service number) AC_DEFINE_UNQUOTED(SUPPORT_PLUGIN, $SUPPORT_PLUGIN, Support the Pacemaker plugin for Corosync) AM_CONDITIONAL(BUILD_CS_SUPPORT, test $SUPPORT_CS = 1) AM_CONDITIONAL(BUILD_CS_PLUGIN, test $SUPPORT_PLUGIN = 1) AM_CONDITIONAL(BUILD_CMAN, test $SUPPORT_CMAN = 1) AC_SUBST(SUPPORT_CMAN) AC_SUBST(SUPPORT_CS) dnl dnl Cluster stack - Sanity dnl if test x${enable_no_stack} = xyes; then AC_MSG_NOTICE(No cluster stack supported. Just building the Policy Engine) PCMK_FEATURES="$PCMK_FEATURES no-cluster-stack" else AC_MSG_CHECKING(for supported stacks) if test x"$STACKS" = x; then AC_MSG_FAILURE(You must support at least one cluster stack (heartbeat or corosync) ) fi AC_MSG_RESULT($STACKS) PCMK_FEATURES="$PCMK_FEATURES $STACKS" fi AC_SUBST(CLUSTERLIBS) AC_SUBST(LCRSODIR) dnl ======================================================================== dnl SNMP dnl ======================================================================== case $SUPPORT_SNMP in 1|yes|true) missingisfatal=1;; try) missingisfatal=0;; *) SUPPORT_SNMP=no;; esac SNMPLIBS="" AC_MSG_CHECKING(for snmp support) if test $SUPPORT_SNMP = no; then AC_MSG_RESULT(no (disabled)) SUPPORT_SNMP=0 else SNMPCONFIG="" AC_MSG_RESULT($SUPPORT_SNMP) AC_CHECK_HEADERS(net-snmp/net-snmp-config.h) if test "x${ac_cv_header_net_snmp_net_snmp_config_h}" != "xyes"; then SUPPORT_SNMP="no" fi if test $SUPPORT_SNMP != no; then AC_PATH_PROGS(SNMPCONFIG, net-snmp-config) if test "X${SNMPCONFIG}" = "X"; then AC_MSG_RESULT(You need the net_snmp development package to continue.) SUPPORT_SNMP=no fi fi if test $SUPPORT_SNMP != no; then AC_MSG_CHECKING(for special snmp libraries) SNMPLIBS=`$SNMPCONFIG --agent-libs` AC_MSG_RESULT($SNMPLIBS) fi if test $SUPPORT_SNMP != no; then savedLibs=$LIBS LIBS="$LIBS $SNMPLIBS" dnl On many systems libcrypto is needed when linking against libsnmp. dnl Check to see if it exists, and if so use it. dnl AC_CHECK_LIB(crypto, CRYPTO_free, CRYPTOLIB="-lcrypto",) dnl AC_SUBST(CRYPTOLIB) AC_CHECK_FUNCS(netsnmp_transport_open_client) if test $ac_cv_func_netsnmp_transport_open_client != yes; then AC_CHECK_FUNCS(netsnmp_tdomain_transport) if test $ac_cv_func_netsnmp_tdomain_transport != yes; then SUPPORT_SNMP=no else AC_DEFINE_UNQUOTED(NETSNMPV53, 1, [Use the older 5.3 version of the net-snmp API]) fi fi LIBS=$savedLibs fi if test $SUPPORT_SNMP = no; then SNMPLIBS="" SUPPORT_SNMP=0 if test $missingisfatal = 0; then AC_MSG_WARN(Unable to support SNMP) else AC_MSG_FAILURE(Unable to support SNMP) fi else SUPPORT_SNMP=1 fi fi if test $SUPPORT_SNMP = 1; then PCMK_FEATURES="$PCMK_FEATURES snmp" fi AC_SUBST(SNMPLIBS) AM_CONDITIONAL(ENABLE_SNMP, test "$SUPPORT_SNMP" = "1") AC_DEFINE_UNQUOTED(ENABLE_SNMP, $SUPPORT_SNMP, Build in support for sending SNMP traps) dnl ======================================================================== dnl ESMTP dnl ======================================================================== case $SUPPORT_ESMTP in 1|yes|true) missingisfatal=1;; try) missingisfatal=0;; *) SUPPORT_ESMTP=no;; esac ESMTPLIB="" AC_MSG_CHECKING(for esmtp support) if test $SUPPORT_ESMTP = no; then AC_MSG_RESULT(no (disabled)) SUPPORT_ESMTP=0 else ESMTPCONFIG="" AC_MSG_RESULT($SUPPORT_ESMTP) AC_CHECK_HEADERS(libesmtp.h) if test "x${ac_cv_header_libesmtp_h}" != "xyes"; then ENABLE_ESMTP="no" fi if test $SUPPORT_ESMTP != no; then AC_PATH_PROGS(ESMTPCONFIG, libesmtp-config) if test "X${ESMTPCONFIG}" = "X"; then AC_MSG_RESULT(You need the libesmtp development package to continue.) SUPPORT_ESMTP=no fi fi if test $SUPPORT_ESMTP != no; then AC_MSG_CHECKING(for special esmtp libraries) ESMTPLIBS=`$ESMTPCONFIG --libs | tr '\n' ' '` AC_MSG_RESULT($ESMTPLIBS) fi if test $SUPPORT_ESMTP = no; then SUPPORT_ESMTP=0 if test $missingisfatal = 0; then AC_MSG_WARN(Unable to support ESMTP) else AC_MSG_FAILURE(Unable to support ESMTP) fi else SUPPORT_ESMTP=1 PCMK_FEATURES="$PCMK_FEATURES libesmtp" fi fi AC_SUBST(ESMTPLIBS) AM_CONDITIONAL(ENABLE_ESMTP, test "$SUPPORT_ESMTP" = "1") AC_DEFINE_UNQUOTED(ENABLE_ESMTP, $SUPPORT_ESMTP, Build in support for sending mail notifications with ESMTP) dnl ======================================================================== dnl ACL dnl ======================================================================== case $SUPPORT_ACL in 1|yes|true) missingisfatal=1;; try) missingisfatal=0;; *) SUPPORT_ACL=no;; esac AC_MSG_CHECKING(for acl support) if test $SUPPORT_ACL = no; then AC_MSG_RESULT(no (disabled)) SUPPORT_ACL=0 else AC_MSG_RESULT($SUPPORT_ACL) SUPPORT_ACL=1 AC_CHECK_LIB(qb, qb_ipcs_connection_auth_set) if test $ac_cv_lib_qb_qb_ipcs_connection_auth_set != yes; then SUPPORT_ACL=0 fi if test $SUPPORT_ACL = 0; then if test $missingisfatal = 0; then AC_MSG_WARN(Unable to support ACL. You need to use libqb > 0.13.0) else AC_MSG_FAILURE(Unable to support ACL. You need to use libqb > 0.13.0) fi fi fi if test $SUPPORT_ACL = 1; then PCMK_FEATURES="$PCMK_FEATURES acls" fi AM_CONDITIONAL(ENABLE_ACL, test "$SUPPORT_ACL" = "1") AC_DEFINE_UNQUOTED(ENABLE_ACL, $SUPPORT_ACL, Build in support for CIB ACL) dnl ======================================================================== dnl CIB secrets dnl ======================================================================== case $SUPPORT_CIBSECRETS in 1|yes|true|try) SUPPORT_CIBSECRETS=1;; *) SUPPORT_CIBSECRETS=0;; esac AC_DEFINE_UNQUOTED(SUPPORT_CIBSECRETS, $SUPPORT_CIBSECRETS, Support CIB secrets) AM_CONDITIONAL(BUILD_CIBSECRETS, test $SUPPORT_CIBSECRETS = 1) if test $SUPPORT_CIBSECRETS = 1; then PCMK_FEATURES="$PCMK_FEATURES cibsecrets" LRM_CIBSECRETS_DIR="${localstatedir}/lib/pacemaker/lrm/secrets" AC_DEFINE_UNQUOTED(LRM_CIBSECRETS_DIR,"$LRM_CIBSECRETS_DIR", Location for CIB secrets) AC_SUBST(LRM_CIBSECRETS_DIR) LRM_LEGACY_CIBSECRETS_DIR="${localstatedir}/lib/heartbeat/lrm/secrets" AC_DEFINE_UNQUOTED(LRM_LEGACY_CIBSECRETS_DIR,"$LRM_LEGACY_CIBSECRETS_DIR", Legacy location for CIB secrets) AC_SUBST(LRM_LEGACY_CIBSECRETS_DIR) fi dnl ======================================================================== dnl GnuTLS dnl ======================================================================== AC_CHECK_HEADERS(gnutls/gnutls.h) AC_CHECK_HEADERS(security/pam_appl.h pam/pam_appl.h) dnl GNUTLS library: Attempt to determine by 'libgnutls-config' program. dnl If no 'libgnutls-config', try traditional autoconf means. AC_PATH_PROGS(LIBGNUTLS_CONFIG, libgnutls-config) if test -n "$LIBGNUTLS_CONFIG"; then AC_MSG_CHECKING(for gnutls header flags) GNUTLSHEAD="`$LIBGNUTLS_CONFIG --cflags`"; AC_MSG_RESULT($GNUTLSHEAD) AC_MSG_CHECKING(for gnutls library flags) GNUTLSLIBS="`$LIBGNUTLS_CONFIG --libs`"; AC_MSG_RESULT($GNUTLSLIBS) fi AC_CHECK_LIB(gnutls, gnutls_init) AC_CHECK_FUNCS(gnutls_priority_set_direct) AC_SUBST(GNUTLSHEAD) AC_SUBST(GNUTLSLIBS) dnl ======================================================================== dnl System Health dnl ======================================================================== dnl Check if servicelog development package is installed SERVICELOG=servicelog-1 SERVICELOG_EXISTS="no" AC_MSG_CHECKING(for $SERVICELOG packages) if $PKGCONFIG --exists $SERVICELOG then PKG_CHECK_MODULES([SERVICELOG], [servicelog-1]) SERVICELOG_EXISTS="yes" fi AC_MSG_RESULT($SERVICELOG_EXISTS) AM_CONDITIONAL(BUILD_SERVICELOG, test "$SERVICELOG_EXISTS" = "yes") dnl Check if OpenIMPI packages and servicelog are installed OPENIPMI="OpenIPMI OpenIPMIposix" OPENIPMI_SERVICELOG_EXISTS="no" AC_MSG_CHECKING(for $SERVICELOG $OPENIPMI packages) if $PKGCONFIG --exists $OPENIPMI $SERVICELOG then PKG_CHECK_MODULES([OPENIPMI_SERVICELOG],[OpenIPMI OpenIPMIposix]) OPENIPMI_SERVICELOG_EXISTS="yes" fi AC_MSG_RESULT($OPENIPMI_SERVICELOG_EXISTS) AM_CONDITIONAL(BUILD_OPENIPMI_SERVICELOG, test "$OPENIPMI_SERVICELOG_EXISTS" = "yes") dnl ======================================================================== dnl Compiler flags dnl ======================================================================== dnl Make sure that CFLAGS is not exported. If the user did dnl not have CFLAGS in their environment then this should have dnl no effect. However if CFLAGS was exported from the user's dnl environment, then the new CFLAGS will also be exported dnl to sub processes. CC_ERRORS="" CC_EXTRAS="" if export | fgrep " CFLAGS=" > /dev/null; then SAVED_CFLAGS="$CFLAGS" unset CFLAGS CFLAGS="$SAVED_CFLAGS" unset SAVED_CFLAGS fi if test "$GCC" != yes; then CFLAGS="$CFLAGS -g" enable_fatal_warnings=no else CFLAGS="$CFLAGS -ggdb" # We had to eliminate -Wnested-externs because of libtool changes EXTRA_FLAGS="-fgnu89-inline -fstack-protector-all -Wall -Waggregate-return -Wbad-function-cast -Wcast-align -Wdeclaration-after-statement -Wendif-labels -Wfloat-equal -Wformat=2 -Wformat-security -Wformat-nonliteral -Wmissing-prototypes -Wmissing-declarations -Wnested-externs -Wno-long-long -Wno-strict-aliasing -Wunused-but-set-variable -Wpointer-arith -Wstrict-prototypes -Wunsigned-char -Wwrite-strings" # Additional warnings it might be nice to enable one day # -Wshadow # -Wunreachable-code for j in $EXTRA_FLAGS do if cc_supports_flag $j then CC_EXTRAS="$CC_EXTRAS $j" fi done dnl In lib/ais/Makefile.am there's a gcc option available as of v4.x GCC_MAJOR=`gcc -v 2>&1 | awk 'END{print $3}' | sed 's/[.].*//'` AM_CONDITIONAL(GCC_4, test "${GCC_MAJOR}" = 4) dnl System specific options case "$host_os" in *linux*|*bsd*) if test "${enable_fatal_warnings}" = "unknown"; then enable_fatal_warnings=yes fi ;; esac if test "x${enable_fatal_warnings}" != xno && cc_supports_flag -Werror ; then enable_fatal_warnings=yes else enable_fatal_warnings=no fi if test "x${enable_ansi}" = xyes && cc_supports_flag -std=iso9899:199409 ; then AC_MSG_NOTICE(Enabling ANSI Compatibility) CC_EXTRAS="$CC_EXTRAS -ansi -D_GNU_SOURCE -DANSI_ONLY" fi AC_MSG_NOTICE(Activated additional gcc flags: ${CC_EXTRAS}) fi CFLAGS="$CFLAGS $CC_EXTRAS" NON_FATAL_CFLAGS="$CFLAGS" AC_SUBST(NON_FATAL_CFLAGS) dnl dnl We reset CFLAGS to include our warnings *after* all function dnl checking goes on, so that our warning flags don't keep the dnl AC_*FUNCS() calls above from working. In particular, -Werror will dnl *always* cause us troubles if we set it before here. dnl dnl if test "x${enable_fatal_warnings}" = xyes ; then AC_MSG_NOTICE(Enabling Fatal Warnings) CFLAGS="$CFLAGS -Werror" fi AC_SUBST(CFLAGS) dnl This is useful for use in Makefiles that need to remove one specific flag CFLAGS_COPY="$CFLAGS" AC_SUBST(CFLAGS_COPY) AC_SUBST(LIBADD_DL) dnl extra flags for dynamic linking libraries AC_SUBST(LIBADD_INTL) dnl extra flags for GNU gettext stuff... AC_SUBST(LOCALE) dnl Options for cleaning up the compiler output QUIET_LIBTOOL_OPTS="" QUIET_MAKE_OPTS="" if test "x${enable_quiet}" = "xyes"; then QUIET_LIBTOOL_OPTS="--quiet" QUIET_MAKE_OPTS="--quiet" fi AC_MSG_RESULT(Supress make details: ${enable_quiet}) dnl Put the above variables to use LIBTOOL="${LIBTOOL} --tag=CC \$(QUIET_LIBTOOL_OPTS)" MAKE="${MAKE} \$(QUIET_MAKE_OPTS)" AC_SUBST(CC) AC_SUBST(MAKE) AC_SUBST(LIBTOOL) AC_SUBST(QUIET_MAKE_OPTS) AC_SUBST(QUIET_LIBTOOL_OPTS) AC_DEFINE_UNQUOTED(CRM_FEATURES, "$PCMK_FEATURES", Set of enabled features) AC_SUBST(PCMK_FEATURES) dnl The Makefiles and shell scripts we output AC_CONFIG_FILES(Makefile \ Doxyfile \ coverage.sh \ cts/Makefile \ cts/CTSvars.py \ cts/LSBDummy \ cts/benchmark/Makefile \ cts/benchmark/clubench \ cib/Makefile \ crmd/Makefile \ pengine/Makefile \ pengine/regression.core.sh \ doc/Makefile \ doc/Pacemaker_Explained/publican.cfg \ doc/Clusters_from_Scratch/publican.cfg \ doc/Pacemaker_Remote/publican.cfg \ include/Makefile \ include/crm/Makefile \ include/crm/cib/Makefile \ include/crm/common/Makefile \ include/crm/cluster/Makefile \ include/crm/fencing/Makefile \ include/crm/pengine/Makefile \ replace/Makefile \ lib/Makefile \ lib/pacemaker.pc \ lib/pacemaker-cib.pc \ lib/pacemaker-lrmd.pc \ lib/pacemaker-service.pc \ lib/pacemaker-pengine.pc \ lib/pacemaker-fencing.pc \ lib/pacemaker-cluster.pc \ lib/ais/Makefile \ lib/common/Makefile \ lib/cluster/Makefile \ lib/cib/Makefile \ lib/pengine/Makefile \ lib/transition/Makefile \ lib/fencing/Makefile \ lib/lrmd/Makefile \ lib/services/Makefile \ mcp/Makefile \ mcp/pacemaker \ mcp/pacemaker.service \ mcp/pacemaker.upstart \ mcp/pacemaker.combined.upstart \ fencing/Makefile \ fencing/regression.py \ lrmd/Makefile \ lrmd/regression.py \ lrmd/pacemaker_remote.service \ lrmd/pacemaker_remote \ extra/Makefile \ extra/resources/Makefile \ extra/rgmanager/Makefile \ tools/Makefile \ tools/crm_report \ tools/report.common \ tools/cibsecret \ xml/Makefile \ lib/gnu/Makefile \ ) dnl Now process the entire list of files added by previous dnl calls to AC_CONFIG_FILES() AC_OUTPUT() dnl ***************** dnl Configure summary dnl ***************** AC_MSG_RESULT([]) AC_MSG_RESULT([$PACKAGE configuration:]) AC_MSG_RESULT([ Version = ${VERSION} (Build: $BUILD_VERSION)]) AC_MSG_RESULT([ Features =${PCMK_FEATURES}]) AC_MSG_RESULT([]) AC_MSG_RESULT([ Prefix = ${prefix}]) AC_MSG_RESULT([ Executables = ${sbindir}]) AC_MSG_RESULT([ Man pages = ${mandir}]) AC_MSG_RESULT([ Libraries = ${libdir}]) AC_MSG_RESULT([ Header files = ${includedir}]) AC_MSG_RESULT([ Arch-independent files = ${datadir}]) AC_MSG_RESULT([ State information = ${localstatedir}]) AC_MSG_RESULT([ System configuration = ${sysconfdir}]) AC_MSG_RESULT([ Corosync Plugins = ${LCRSODIR}]) AC_MSG_RESULT([]) AC_MSG_RESULT([ Use system LTDL = ${ac_cv_lib_ltdl_lt_dlopen}]) AC_MSG_RESULT([]) AC_MSG_RESULT([ HA group name = ${CRM_DAEMON_GROUP}]) AC_MSG_RESULT([ HA user name = ${CRM_DAEMON_USER}]) AC_MSG_RESULT([]) AC_MSG_RESULT([ CFLAGS = ${CFLAGS}]) AC_MSG_RESULT([ Libraries = ${LIBS}]) AC_MSG_RESULT([ Stack Libraries = ${CLUSTERLIBS}]) pacemaker-master/coverage.sh.in000066400000000000000000000031361217637305600170500ustar00rootroot00000000000000#!/bin/bash start=$PWD test_home=`dirname $0` sanitydir=@datadir@/@PACKAGE@/tests if [ $test_home != $sanitydir ]; then # Running against the source tree GCOV_BASE=@abs_top_srcdir@ sanitydir=@abs_top_srcdir@ cd @abs_top_srcdir@ grep with-gcov config.log if [ $? = 0 ]; then echo "Pacemaker was built with gcov support" else echo "Re-building with gcov support" last=`grep --color=never "$.*configure" config.log | tail -n 1 | sed s:.*configure:./configure: | sed s:--no-create:--with-gcov:` eval $last fi #sudo make core core-install else GCOV_BASE=@localstatedir@/lib/pacemaker/gcov/ mkdir -p $GCOV_BASE export GCOV_PREFIX_STRIP=4 export GCOV_PREFIX=$GCOV_BASE top=`find / -name crm_internal.h 2>/dev/null | grep debug | head -n 1` if [ "x$top" = x ]; then echo "Could not locate the pacemaker headers" exit 1 fi cd `dirname $top` cd .. echo "Creating the directory structure in $GCOV_BASE from $PWD" # The .gcno files will already be there for sources, # but we still need to create the include/ subtree find . -type d -exec mkdir -p $GCOV_BASE/\{\} \; echo "Now linking the source files into place" find . -type f -name "*.c" -exec ln -s $PWD/\{\} $GCOV_BASE\{\} \; find . -type f -name "*.h" -exec ln -s $PWD/\{\} $GCOV_BASE\{\} \; find . -type f -name "*.debug" -exec ln -s $PWD/\{\} $GCOV_BASE\{\} \; fi cd $start lcov -d $GCOV_BASE -z # Run all active regression tests $sanitydir/BasicSanity.sh lcov -d $GCOV_BASE -c -o pacemaker.info rm -rf html mkdir html genhtml -o html pacemaker.info pacemaker-master/crmd/000077500000000000000000000000001217637305600152365ustar00rootroot00000000000000pacemaker-master/crmd/Makefile.am000066400000000000000000000047131217637305600172770ustar00rootroot00000000000000# # Copyright (C) 2004 Andrew Beekhof # # 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 2 # of the License, 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. # MAINTAINERCLEANFILES = Makefile.in INCLUDES = -I$(top_builddir)/include -I$(top_srcdir)/include \ -I$(top_builddir)/libltdl -I$(top_srcdir)/libltdl halibdir = $(CRM_DAEMON_DIR) ## binary progs halib_PROGRAMS = crmd ## SOURCES noinst_HEADERS = crmd.h crmd_fsa.h crmd_messages.h fsa_defines.h \ fsa_matrix.h fsa_proto.h crmd_utils.h crmd_callbacks.h \ crmd_lrm.h te_callbacks.h tengine.h crmd_SOURCES = main.c crmd.c corosync.c \ fsa.c control.c messages.c membership.c callbacks.c \ election.c join_client.c join_dc.c subsystems.c \ cib.c pengine.c tengine.c lrm.c lrm_state.c remote_lrmd_ra.c \ utils.c misc.c te_events.c te_actions.c te_utils.c te_callbacks.c if BUILD_HEARTBEAT_SUPPORT crmd_SOURCES += heartbeat.c endif crmd_LDADD = $(top_builddir)/lib/fencing/libstonithd.la \ $(top_builddir)/lib/transition/libtransitioner.la \ $(top_builddir)/lib/pengine/libpe_rules.la \ $(top_builddir)/lib/cib/libcib.la \ $(top_builddir)/lib/cluster/libcrmcluster.la \ $(top_builddir)/lib/common/libcrmcommon.la \ $(top_builddir)/lib/services/libcrmservice.la \ $(top_builddir)/lib/lrmd/liblrmd.la \ $(CLUSTERLIBS) if BUILD_XML_HELP man7_MANS = crmd.7 %.xml: % $(top_builddir)/crmd/$< metadata | $(XSLTPROC) --nonet --novalid --stringparam man.name $< $(top_srcdir)/xml/ocf-meta2man.xsl - > $(top_builddir)/crmd/$@ %.7: %.xml $(XSLTPROC) $(MANPAGE_XSLT) $(top_builddir)/crmd/$< endif clean-generic: rm -f *.log *.debug *.xml *~ install-exec-local: uninstall-local: graphs: fsa_inputs.png fsa_inputs_by_action.png fsa_actions_by_state.png %.png: %.dot dot -Tpng $< > $@ %.dot : fsa_matrix.h make_dot.pl perl $(top_srcdir)/crmd/make_dot.pl $(top_srcdir)/crmd/fsa_matrix.h $(top_builddir)/crmd pacemaker-master/crmd/callbacks.c000066400000000000000000000214451217637305600173270ustar00rootroot00000000000000/* * Copyright (C) 2004 Andrew Beekhof * * 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 2 of the License, or (at your option) any later version. * * This software 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 library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include void crmd_ha_connection_destroy(gpointer user_data); /* From join_dc... */ extern gboolean check_join_state(enum crmd_fsa_state cur_state, const char *source); void crmd_ha_connection_destroy(gpointer user_data) { crm_trace("Invoked"); if (is_set(fsa_input_register, R_HA_DISCONNECTED)) { /* we signed out, so this is expected */ crm_info("Heartbeat disconnection complete"); return; } crm_crit("Lost connection to heartbeat service!"); register_fsa_input(C_HA_DISCONNECT, I_ERROR, NULL); trigger_fsa(fsa_source); } void crmd_ha_msg_filter(xmlNode * msg) { if (AM_I_DC) { const char *sys_from = crm_element_value(msg, F_CRM_SYS_FROM); if (safe_str_eq(sys_from, CRM_SYSTEM_DC)) { const char *from = crm_element_value(msg, F_ORIG); if (safe_str_neq(from, fsa_our_uname)) { int level = LOG_INFO; const char *op = crm_element_value(msg, F_CRM_TASK); /* make sure the election happens NOW */ if (fsa_state != S_ELECTION) { ha_msg_input_t new_input; level = LOG_WARNING; new_input.msg = msg; register_fsa_error_adv(C_FSA_INTERNAL, I_ELECTION, NULL, &new_input, __FUNCTION__); } do_crm_log(level, "Another DC detected: %s (op=%s)", from, op); goto done; } } } else { const char *sys_to = crm_element_value(msg, F_CRM_SYS_TO); if (safe_str_eq(sys_to, CRM_SYSTEM_DC)) { return; } } /* crm_log_xml_trace("HA[inbound]", msg); */ route_message(C_HA_MESSAGE, msg); done: trigger_fsa(fsa_source); } void peer_update_callback(enum crm_status_type type, crm_node_t * node, const void *data) { uint32_t old = 0; uint32_t changed = 0; bool appeared = FALSE; const char *status = NULL; set_bit(fsa_input_register, R_PEER_DATA); if (node->uname == NULL) { return; } switch (type) { case crm_status_uname: /* If we've never seen the node, then it also wont be in the status section */ crm_info("%s is now %s", node->uname, node->state); return; case crm_status_nstate: crm_info("%s is now %s (was %s)", node->uname, node->state, (const char *)data); if (safe_str_eq(data, node->state)) { /* State did not change */ return; } else if(safe_str_eq(CRM_NODE_MEMBER, node->state)) { appeared = TRUE; } break; case crm_status_processes: if (data) { old = *(const uint32_t *)data; changed = node->processes ^ old; } /* crmd_proc_update(node, proc_flags); */ status = (node->processes & proc_flags) ? ONLINESTATUS : OFFLINESTATUS; crm_info("Client %s/%s now has status [%s] (DC=%s)", node->uname, peer2text(proc_flags), status, AM_I_DC ? "true" : crm_str(fsa_our_dc)); if ((changed & proc_flags) == 0) { /* Peer process did not change */ crm_trace("No change %6x %6x %6x", old, node->processes, proc_flags); return; } else if (is_set(fsa_input_register, R_CIB_CONNECTED) == FALSE) { crm_trace("Not connected"); return; } else if (fsa_state == S_STOPPING) { crm_trace("Stopping"); return; } appeared = (node->processes & proc_flags) != 0; if (safe_str_eq(node->uname, fsa_our_uname) && (node->processes & proc_flags) == 0) { /* Did we get evicted? */ crm_notice("Our peer connection failed"); register_fsa_input(C_CRMD_STATUS_CALLBACK, I_ERROR, NULL); } else if (safe_str_eq(node->uname, fsa_our_dc) && crm_is_peer_active(node) == FALSE) { /* Did the DC leave us? */ crm_notice("Our peer on the DC is dead"); register_fsa_input(C_CRMD_STATUS_CALLBACK, I_ELECTION, NULL); } break; } if (AM_I_DC) { xmlNode *update = NULL; gboolean alive = crm_is_peer_active(node); crm_action_t *down = match_down_event(0, node->uuid, NULL, appeared); crm_trace("Alive=%d, appear=%d, down=%p", alive, appeared, down); if (alive && type == crm_status_processes) { register_fsa_input_before(C_FSA_INTERNAL, I_NODE_JOIN, NULL); } if (down) { const char *task = crm_element_value(down->xml, XML_LRM_ATTR_TASK); if (alive && safe_str_eq(task, CRM_OP_FENCE)) { crm_info("Node return implies stonith of %s (action %d) completed", node->uname, down->id); erase_status_tag(node->uname, XML_CIB_TAG_LRM, cib_scope_local); erase_status_tag(node->uname, XML_TAG_TRANSIENT_NODEATTRS, cib_scope_local); /* down->confirmed = TRUE; Only stonith-ng returning should imply completion */ down->sent_update = TRUE; /* Prevent tengine_stonith_callback() from calling send_stonith_update() */ } else if (safe_str_eq(task, CRM_OP_FENCE)) { crm_trace("Waiting for stonithd to report the fencing of %s is complete", node->uname); /* via tengine_stonith_callback() */ } else if (alive == FALSE) { crm_notice("%s of %s (op %d) is complete", task, node->uname, down->id); /* down->confirmed = TRUE; Only stonith-ng returning should imply completion */ stop_te_timer(down->timer); crm_update_peer_join(__FUNCTION__, node, crm_join_none); crm_update_peer_expected(__FUNCTION__, node, CRMD_JOINSTATE_DOWN); check_join_state(fsa_state, __FUNCTION__); update_graph(transition_graph, down); trigger_graph(); } else { crm_trace("Other %p", down); } } else if (appeared == FALSE) { crm_notice("Stonith/shutdown of %s not matched", node->uname); crm_update_peer_join(__FUNCTION__, node, crm_join_none); check_join_state(fsa_state, __FUNCTION__); abort_transition(INFINITY, tg_restart, "Node failure", NULL); fail_incompletable_actions(transition_graph, node->uuid); } else { crm_trace("Other %p", down); } update = do_update_node_cib(node, node_update_peer, NULL, __FUNCTION__); fsa_cib_anon_update(XML_CIB_TAG_STATUS, update, cib_scope_local | cib_quorum_override | cib_can_create); free_xml(update); } trigger_fsa(fsa_source); } void crmd_cib_connection_destroy(gpointer user_data) { CRM_CHECK(user_data == fsa_cib_conn,;); crm_trace("Invoked"); trigger_fsa(fsa_source); fsa_cib_conn->state = cib_disconnected; if (is_set(fsa_input_register, R_CIB_CONNECTED) == FALSE) { crm_info("Connection to the CIB terminated..."); return; } /* eventually this will trigger a reconnect, not a shutdown */ crm_err("Connection to the CIB terminated..."); register_fsa_input(C_FSA_INTERNAL, I_ERROR, NULL); clear_bit(fsa_input_register, R_CIB_CONNECTED); return; } gboolean crm_fsa_trigger(gpointer user_data) { crm_trace("Invoked (queue len: %d)", g_list_length(fsa_message_queue)); s_crmd_fsa(C_FSA_INTERNAL); crm_trace("Exited (queue len: %d)", g_list_length(fsa_message_queue)); return TRUE; } pacemaker-master/crmd/cib.c000066400000000000000000000164661217637305600161540ustar00rootroot00000000000000/* * Copyright (C) 2004 Andrew Beekhof * * 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 2 of the License, or (at your option) any later version. * * This software 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 library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include #include #include #include #include #include /* for access */ #include /* for calls to open */ #include /* for calls to open */ #include /* for calls to open */ #include /* for getpwuid */ #include /* for initgroups */ #include /* for getrlimit */ #include /* for getrlimit */ #include #include #include #include #include #include #include struct crm_subsystem_s *cib_subsystem = NULL; int cib_retries = 0; static void do_cib_updated(const char *event, xmlNode * msg) { int rc = -1; CRM_CHECK(msg != NULL, return); crm_element_value_int(msg, F_CIB_RC, &rc); if (rc < pcmk_ok) { crm_trace("Filter rc=%d (%s)", rc, pcmk_strerror(rc)); return; } if (get_xpath_object ("//" F_CIB_UPDATE_RESULT "//" XML_TAG_DIFF_ADDED "//" XML_CIB_TAG_CRMCONFIG, msg, LOG_TRACE) != NULL) { mainloop_set_trigger(config_read); } } static void revision_check_callback(xmlNode * msg, int call_id, int rc, xmlNode * output, void *user_data) { int cmp = -1; const char *revision = NULL; xmlNode *generation = NULL; if (rc != pcmk_ok) { fsa_data_t *msg_data = NULL; register_fsa_error(C_FSA_INTERNAL, I_ERROR, NULL); return; } generation = output; CRM_CHECK(safe_str_eq(crm_element_name(generation), XML_TAG_CIB), crm_log_xml_err(output, __FUNCTION__); return); crm_trace("Checking our feature revision is allowed: %s", CIB_FEATURE_SET); revision = crm_element_value(generation, XML_ATTR_CRM_VERSION); cmp = compare_version(revision, CRM_FEATURE_SET); if (cmp > 0) { crm_err("This build (%s) does not support the current" " resource configuration", VERSION); crm_err("We can only support up to CRM feature set %s (current=%s)", CRM_FEATURE_SET, revision); crm_err("Shutting down the CRM"); /* go into a stall state */ register_fsa_error_adv(C_FSA_INTERNAL, I_SHUTDOWN, NULL, NULL, __FUNCTION__); return; } } static void do_cib_replaced(const char *event, xmlNode * msg) { crm_debug("Updating the CIB after a replace: DC=%s", AM_I_DC ? "true" : "false"); if (AM_I_DC == FALSE) { return; } else if (fsa_state == S_FINALIZE_JOIN && is_set(fsa_input_register, R_CIB_ASKED)) { /* no need to restart the join - we asked for this replace op */ return; } /* start the join process again so we get everyone's LRM status */ populate_cib_nodes(node_update_quick | node_update_cluster | node_update_peer | node_update_join | node_update_expected, __FUNCTION__); register_fsa_input(C_FSA_INTERNAL, I_ELECTION, NULL); } /* A_CIB_STOP, A_CIB_START, A_CIB_RESTART, */ void do_cib_control(long long action, enum crmd_fsa_cause cause, enum crmd_fsa_state cur_state, enum crmd_fsa_input current_input, fsa_data_t * msg_data) { struct crm_subsystem_s *this_subsys = cib_subsystem; long long stop_actions = A_CIB_STOP; long long start_actions = A_CIB_START; if (action & stop_actions) { if (fsa_cib_conn->state != cib_disconnected && last_resource_update != 0) { crm_info("Waiting for resource update %d to complete", last_resource_update); crmd_fsa_stall(FALSE); return; } crm_info("Disconnecting CIB"); clear_bit(fsa_input_register, R_CIB_CONNECTED); CRM_ASSERT(fsa_cib_conn != NULL); fsa_cib_conn->cmds->del_notify_callback(fsa_cib_conn, T_CIB_DIFF_NOTIFY, do_cib_updated); if (fsa_cib_conn->state != cib_disconnected) { fsa_cib_conn->cmds->set_slave(fsa_cib_conn, cib_scope_local); fsa_cib_conn->cmds->signoff(fsa_cib_conn); } } if (action & start_actions) { int rc = pcmk_ok; CRM_ASSERT(fsa_cib_conn != NULL); if (cur_state == S_STOPPING) { crm_err("Ignoring request to start %s after shutdown", this_subsys->name); return; } rc = fsa_cib_conn->cmds->signon(fsa_cib_conn, CRM_SYSTEM_CRMD, cib_command_nonblocking); if (rc != pcmk_ok) { /* a short wait that usually avoids stalling the FSA */ sleep(1); rc = fsa_cib_conn->cmds->signon(fsa_cib_conn, CRM_SYSTEM_CRMD, cib_command_nonblocking); } if (rc != pcmk_ok) { crm_info("Could not connect to the CIB service: %s", pcmk_strerror(rc)); } else if (pcmk_ok != fsa_cib_conn->cmds->set_connection_dnotify(fsa_cib_conn, crmd_cib_connection_destroy)) { crm_err("Could not set dnotify callback"); } else if (pcmk_ok != fsa_cib_conn->cmds->add_notify_callback(fsa_cib_conn, T_CIB_REPLACE_NOTIFY, do_cib_replaced)) { crm_err("Could not set CIB notification callback (replace)"); } else if (pcmk_ok != fsa_cib_conn->cmds->add_notify_callback(fsa_cib_conn, T_CIB_DIFF_NOTIFY, do_cib_updated)) { crm_err("Could not set CIB notification callback (update)"); } else { set_bit(fsa_input_register, R_CIB_CONNECTED); } if (is_set(fsa_input_register, R_CIB_CONNECTED) == FALSE) { cib_retries++; crm_warn("Couldn't complete CIB registration %d" " times... pause and retry", cib_retries); if (cib_retries < 30) { crm_timer_start(wait_timer); crmd_fsa_stall(FALSE); } else { crm_err("Could not complete CIB" " registration %d times..." " hard error", cib_retries); register_fsa_error(C_FSA_INTERNAL, I_ERROR, NULL); } } else { int call_id = 0; crm_info("CIB connection established"); call_id = fsa_cib_conn->cmds->query(fsa_cib_conn, NULL, NULL, cib_scope_local); fsa_register_cib_callback(call_id, FALSE, NULL, revision_check_callback); cib_retries = 0; } } } pacemaker-master/crmd/control.c000066400000000000000000001004271217637305600170660ustar00rootroot00000000000000/* * Copyright (C) 2004 Andrew Beekhof * * 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 2 of the License, or (at your option) any later version. * * This software 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 library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include qb_ipcs_service_t *ipcs = NULL; extern gboolean crm_connect_corosync(crm_cluster_t * cluster); extern void crmd_ha_connection_destroy(gpointer user_data); void crm_shutdown(int nsig); gboolean crm_read_options(gpointer user_data); gboolean fsa_has_quorum = FALSE; crm_trigger_t *fsa_source = NULL; crm_trigger_t *config_read = NULL; /* A_HA_CONNECT */ void do_ha_control(long long action, enum crmd_fsa_cause cause, enum crmd_fsa_state cur_state, enum crmd_fsa_input current_input, fsa_data_t * msg_data) { gboolean registered = FALSE; static crm_cluster_t *cluster = NULL; if (cluster == NULL) { cluster = calloc(1, sizeof(crm_cluster_t)); } if (action & A_HA_DISCONNECT) { crm_cluster_disconnect(cluster); crm_info("Disconnected from the cluster"); set_bit(fsa_input_register, R_HA_DISCONNECTED); } if (action & A_HA_CONNECT) { crm_set_status_callback(&peer_update_callback); if (is_openais_cluster()) { #if SUPPORT_COROSYNC registered = crm_connect_corosync(cluster); #endif } else if (is_heartbeat_cluster()) { #if SUPPORT_HEARTBEAT cluster->destroy = crmd_ha_connection_destroy; cluster->hb_dispatch = crmd_ha_msg_callback; registered = crm_cluster_connect(cluster); fsa_cluster_conn = cluster->hb_conn; crm_trace("Be informed of Node Status changes"); if (registered && fsa_cluster_conn->llc_ops->set_nstatus_callback(fsa_cluster_conn, crmd_ha_status_callback, fsa_cluster_conn) != HA_OK) { crm_err("Cannot set nstatus callback: %s", fsa_cluster_conn->llc_ops->errmsg(fsa_cluster_conn)); registered = FALSE; } crm_trace("Be informed of CRM Client Status changes"); if (registered && fsa_cluster_conn->llc_ops->set_cstatus_callback(fsa_cluster_conn, crmd_client_status_callback, fsa_cluster_conn) != HA_OK) { crm_err("Cannot set cstatus callback: %s", fsa_cluster_conn->llc_ops->errmsg(fsa_cluster_conn)); registered = FALSE; } if (registered) { crm_trace("Requesting an initial dump of CRMD client_status"); fsa_cluster_conn->llc_ops->client_status(fsa_cluster_conn, NULL, CRM_SYSTEM_CRMD, -1); } #endif } fsa_our_uname = cluster->uname; fsa_our_uuid = cluster->uuid; if(cluster->uuid == NULL) { crm_err("Could not obtain local uuid"); registered = FALSE; } if (registered == FALSE) { set_bit(fsa_input_register, R_HA_DISCONNECTED); register_fsa_error(C_FSA_INTERNAL, I_ERROR, NULL); return; } populate_cib_nodes(node_update_none, __FUNCTION__); clear_bit(fsa_input_register, R_HA_DISCONNECTED); crm_info("Connected to the cluster"); } if (action & ~(A_HA_CONNECT | A_HA_DISCONNECT)) { crm_err("Unexpected action %s in %s", fsa_action2string(action), __FUNCTION__); } } /* A_SHUTDOWN */ void do_shutdown(long long action, enum crmd_fsa_cause cause, enum crmd_fsa_state cur_state, enum crmd_fsa_input current_input, fsa_data_t * msg_data) { /* just in case */ set_bit(fsa_input_register, R_SHUTDOWN); if (is_heartbeat_cluster()) { if (is_set(fsa_input_register, pe_subsystem->flag_connected)) { crm_info("Terminating the %s", pe_subsystem->name); if (stop_subsystem(pe_subsystem, TRUE) == FALSE) { /* its gone... */ crm_err("Faking %s exit", pe_subsystem->name); clear_bit(fsa_input_register, pe_subsystem->flag_connected); } else { crm_info("Waiting for subsystems to exit"); crmd_fsa_stall(FALSE); } } crm_info("All subsystems stopped, continuing"); } if (stonith_api) { /* Prevent it from comming up again */ clear_bit(fsa_input_register, R_ST_REQUIRED); crm_info("Disconnecting STONITH..."); stonith_api->cmds->disconnect(stonith_api); } } /* A_SHUTDOWN_REQ */ void do_shutdown_req(long long action, enum crmd_fsa_cause cause, enum crmd_fsa_state cur_state, enum crmd_fsa_input current_input, fsa_data_t * msg_data) { xmlNode *msg = NULL; crm_info("Sending shutdown request to %s", crm_str(fsa_our_dc)); msg = create_request(CRM_OP_SHUTDOWN_REQ, NULL, NULL, CRM_SYSTEM_DC, CRM_SYSTEM_CRMD, NULL); /* set_bit(fsa_input_register, R_STAYDOWN); */ if (send_cluster_message(NULL, crm_msg_crmd, msg, TRUE) == FALSE) { register_fsa_error(C_FSA_INTERNAL, I_ERROR, NULL); } free_xml(msg); } extern crm_ipc_t *attrd_ipc; extern char *max_generation_from; extern xmlNode *max_generation_xml; extern GHashTable *resource_history; extern GHashTable *voted; extern GHashTable *reload_hash; extern char *te_client_id; void log_connected_client(gpointer key, gpointer value, gpointer user_data); void log_connected_client(gpointer key, gpointer value, gpointer user_data) { crm_client_t *client = value; crm_err("%s is still connected at exit", crm_client_name(client)); } int crmd_fast_exit(int rc) { if (is_set(fsa_input_register, R_STAYDOWN)) { crm_warn("Inhibiting respawn: %d -> %d", rc, 100); rc = 100; } if (rc == pcmk_ok && is_set(fsa_input_register, R_IN_RECOVERY)) { crm_err("Could not recover from internal error"); rc = pcmk_err_generic; } return crm_exit(rc); } int crmd_exit(int rc) { GListPtr gIter = NULL; GMainLoop *mloop = crmd_mainloop; static bool in_progress = FALSE; if(in_progress && rc == 0) { crm_debug("Exit is already in progress"); return rc; } else if(in_progress) { crm_notice("Error during shutdown process, terminating now: %s (%d)", pcmk_strerror(rc), rc); crm_write_blackbox(SIGTRAP, NULL); crmd_fast_exit(rc); } in_progress = TRUE; crm_trace("Preparing to exit: %d", rc); /* Suppress secondary errors resulting from us disconnecting everything */ set_bit(fsa_input_register, R_HA_DISCONNECTED); /* Close all IPC servers and clients to ensure any and all shared memory files are cleaned up */ if(ipcs) { crm_trace("Closing IPC server"); mainloop_del_ipc_server(ipcs); ipcs = NULL; } if (attrd_ipc) { crm_trace("Closing attrd connection"); crm_ipc_close(attrd_ipc); crm_ipc_destroy(attrd_ipc); attrd_ipc = NULL; } if (pe_subsystem && pe_subsystem->client && pe_subsystem->client->ipcs) { crm_trace("Disconnecting Policy Engine"); qb_ipcs_disconnect(pe_subsystem->client->ipcs); } if(stonith_api) { crm_trace("Disconnecting fencing API"); clear_bit(fsa_input_register, R_ST_REQUIRED); stonith_api->cmds->free(stonith_api); stonith_api = NULL; } if (rc == pcmk_ok && crmd_mainloop == NULL) { crm_debug("No mainloop detected"); rc = EPROTO; } /* On an error, just get out. * * Otherwise, make the effort to have mainloop exit gracefully so * that it (mostly) cleans up after itself and valgrind has less * to report on - allowing real errors stand out */ if(rc != pcmk_ok) { crm_notice("Forcing immediate exit: %s (%d)", pcmk_strerror(rc), rc); crm_write_blackbox(SIGTRAP, NULL); return crmd_fast_exit(rc); } /* Clean up as much memory as possible for valgrind */ #if SUPPORT_HEARTBEAT if (fsa_cluster_conn) { crm_trace("Disconnecting heartbeat"); fsa_cluster_conn->llc_ops->delete(fsa_cluster_conn); fsa_cluster_conn = NULL; } #endif for (gIter = fsa_message_queue; gIter != NULL; gIter = gIter->next) { fsa_data_t *fsa_data = gIter->data; crm_info("Dropping %s: [ state=%s cause=%s origin=%s ]", fsa_input2string(fsa_data->fsa_input), fsa_state2string(fsa_state), fsa_cause2string(fsa_data->fsa_cause), fsa_data->origin); delete_fsa_input(fsa_data); } clear_bit(fsa_input_register, R_MEMBERSHIP); g_list_free(fsa_message_queue); fsa_message_queue = NULL; free(pe_subsystem); pe_subsystem = NULL; free(te_subsystem); te_subsystem = NULL; free(cib_subsystem); cib_subsystem = NULL; if (reload_hash) { crm_trace("Destroying reload cache with %d members", g_hash_table_size(reload_hash)); g_hash_table_destroy(reload_hash); reload_hash = NULL; } if (voted) { crm_trace("Destroying voted cache with %d members", g_hash_table_size(voted)); g_hash_table_destroy(voted); voted = NULL; } cib_delete(fsa_cib_conn); fsa_cib_conn = NULL; verify_stopped(fsa_state, LOG_WARNING); clear_bit(fsa_input_register, R_LRM_CONNECTED); lrm_state_destroy_all(); /* This basically will not work, since mainloop has a reference to it */ mainloop_destroy_trigger(fsa_source); fsa_source = NULL; mainloop_destroy_trigger(config_read); config_read = NULL; mainloop_destroy_trigger(stonith_reconnect); stonith_reconnect = NULL; mainloop_destroy_trigger(transition_trigger); transition_trigger = NULL; crm_client_cleanup(); crm_peer_destroy(); crm_timer_stop(transition_timer); crm_timer_stop(integration_timer); crm_timer_stop(finalization_timer); crm_timer_stop(election_trigger); crm_timer_stop(election_timeout); crm_timer_stop(shutdown_escalation_timer); crm_timer_stop(wait_timer); crm_timer_stop(recheck_timer); free(transition_timer); transition_timer = NULL; free(integration_timer); integration_timer = NULL; free(finalization_timer); finalization_timer = NULL; free(election_trigger); election_trigger = NULL; free(election_timeout); election_timeout = NULL; free(shutdown_escalation_timer); shutdown_escalation_timer = NULL; free(wait_timer); wait_timer = NULL; free(recheck_timer); recheck_timer = NULL; free(fsa_our_dc_version); fsa_our_dc_version = NULL; free(fsa_our_uname); fsa_our_uname = NULL; free(fsa_our_uuid); fsa_our_uuid = NULL; free(fsa_our_dc); fsa_our_dc = NULL; free(te_uuid); te_uuid = NULL; free(te_client_id); te_client_id = NULL; free(fsa_pe_ref); fsa_pe_ref = NULL; free(failed_stop_offset); failed_stop_offset = NULL; free(failed_start_offset); failed_start_offset = NULL; free(max_generation_from); max_generation_from = NULL; free_xml(max_generation_xml); max_generation_xml = NULL; mainloop_destroy_signal(SIGUSR1); mainloop_destroy_signal(SIGTERM); mainloop_destroy_signal(SIGTRAP); mainloop_destroy_signal(SIGCHLD); if (mloop) { int lpc = 0; GMainContext *ctx = g_main_loop_get_context(crmd_mainloop); /* Don't re-enter this block */ crmd_mainloop = NULL; crm_trace("Draining mainloop %d %d", g_main_loop_is_running(mloop), g_main_context_pending(ctx)); while(g_main_context_pending(ctx) && lpc < 10) { lpc++; crm_trace("Iteration %d", lpc); g_main_context_dispatch(ctx); } crm_trace("Closing mainloop %d %d", g_main_loop_is_running(mloop), g_main_context_pending(ctx)); g_main_loop_quit(mloop); /* Won't do anything yet, since we're inside it now */ g_main_loop_unref(mloop); crm_trace("Done %d", rc); } /* Graceful */ return rc; } /* A_EXIT_0, A_EXIT_1 */ void do_exit(long long action, enum crmd_fsa_cause cause, enum crmd_fsa_state cur_state, enum crmd_fsa_input current_input, fsa_data_t * msg_data) { int exit_code = pcmk_ok; int log_level = LOG_INFO; const char *exit_type = "gracefully"; if (action & A_EXIT_1) { /* exit_code = pcmk_err_generic; */ log_level = LOG_ERR; exit_type = "forcefully"; exit_code = pcmk_err_generic; } verify_stopped(cur_state, LOG_ERR); do_crm_log(log_level, "Performing %s - %s exiting the CRMd", fsa_action2string(action), exit_type); crm_info("[%s] stopped (%d)", crm_system_name, exit_code); crmd_exit(exit_code); } /* A_STARTUP */ void do_startup(long long action, enum crmd_fsa_cause cause, enum crmd_fsa_state cur_state, enum crmd_fsa_input current_input, fsa_data_t * msg_data) { int was_error = 0; int interval = 1; /* seconds between DC heartbeats */ crm_debug("Registering Signal Handlers"); mainloop_add_signal(SIGTERM, crm_shutdown); fsa_source = mainloop_add_trigger(G_PRIORITY_HIGH, crm_fsa_trigger, NULL); config_read = mainloop_add_trigger(G_PRIORITY_HIGH, crm_read_options, NULL); transition_trigger = mainloop_add_trigger(G_PRIORITY_LOW, te_graph_trigger, NULL); crm_debug("Creating CIB and LRM objects"); fsa_cib_conn = cib_new(); lrm_state_init_local(); /* set up the timers */ transition_timer = calloc(1, sizeof(fsa_timer_t)); integration_timer = calloc(1, sizeof(fsa_timer_t)); finalization_timer = calloc(1, sizeof(fsa_timer_t)); election_trigger = calloc(1, sizeof(fsa_timer_t)); election_timeout = calloc(1, sizeof(fsa_timer_t)); shutdown_escalation_timer = calloc(1, sizeof(fsa_timer_t)); wait_timer = calloc(1, sizeof(fsa_timer_t)); recheck_timer = calloc(1, sizeof(fsa_timer_t)); interval = interval * 1000; if (election_trigger != NULL) { election_trigger->source_id = 0; election_trigger->period_ms = -1; election_trigger->fsa_input = I_DC_TIMEOUT; election_trigger->callback = crm_timer_popped; election_trigger->repeat = FALSE; } else { was_error = TRUE; } if (election_timeout != NULL) { election_timeout->source_id = 0; election_timeout->period_ms = -1; election_timeout->fsa_input = I_ELECTION_DC; election_timeout->callback = crm_timer_popped; election_timeout->repeat = FALSE; } else { was_error = TRUE; } if (transition_timer != NULL) { transition_timer->source_id = 0; transition_timer->period_ms = -1; transition_timer->fsa_input = I_PE_CALC; transition_timer->callback = crm_timer_popped; transition_timer->repeat = FALSE; } else { was_error = TRUE; } if (integration_timer != NULL) { integration_timer->source_id = 0; integration_timer->period_ms = -1; integration_timer->fsa_input = I_INTEGRATED; integration_timer->callback = crm_timer_popped; integration_timer->repeat = FALSE; } else { was_error = TRUE; } if (finalization_timer != NULL) { finalization_timer->source_id = 0; finalization_timer->period_ms = -1; finalization_timer->fsa_input = I_FINALIZED; finalization_timer->callback = crm_timer_popped; finalization_timer->repeat = FALSE; /* for possible enabling... a bug in the join protocol left * a slave in S_PENDING while we think its in S_NOT_DC * * raising I_FINALIZED put us into a transition loop which is * never resolved. * in this loop we continually send probes which the node * NACK's because its in S_PENDING * * if we have nodes where heartbeat is active but the * CRM is not... then this will be handled in the * integration phase */ finalization_timer->fsa_input = I_ELECTION; } else { was_error = TRUE; } if (shutdown_escalation_timer != NULL) { shutdown_escalation_timer->source_id = 0; shutdown_escalation_timer->period_ms = -1; shutdown_escalation_timer->fsa_input = I_STOP; shutdown_escalation_timer->callback = crm_timer_popped; shutdown_escalation_timer->repeat = FALSE; } else { was_error = TRUE; } if (wait_timer != NULL) { wait_timer->source_id = 0; wait_timer->period_ms = 2000; wait_timer->fsa_input = I_NULL; wait_timer->callback = crm_timer_popped; wait_timer->repeat = FALSE; } else { was_error = TRUE; } if (recheck_timer != NULL) { recheck_timer->source_id = 0; recheck_timer->period_ms = -1; recheck_timer->fsa_input = I_PE_CALC; recheck_timer->callback = crm_timer_popped; recheck_timer->repeat = FALSE; } else { was_error = TRUE; } /* set up the sub systems */ cib_subsystem = calloc(1, sizeof(struct crm_subsystem_s)); te_subsystem = calloc(1, sizeof(struct crm_subsystem_s)); pe_subsystem = calloc(1, sizeof(struct crm_subsystem_s)); if (cib_subsystem != NULL) { cib_subsystem->pid = -1; cib_subsystem->name = CRM_SYSTEM_CIB; cib_subsystem->flag_connected = R_CIB_CONNECTED; cib_subsystem->flag_required = R_CIB_REQUIRED; } else { was_error = TRUE; } if (te_subsystem != NULL) { te_subsystem->pid = -1; te_subsystem->name = CRM_SYSTEM_TENGINE; te_subsystem->flag_connected = R_TE_CONNECTED; te_subsystem->flag_required = R_TE_REQUIRED; } else { was_error = TRUE; } if (pe_subsystem != NULL) { pe_subsystem->pid = -1; pe_subsystem->path = CRM_DAEMON_DIR; pe_subsystem->name = CRM_SYSTEM_PENGINE; pe_subsystem->command = CRM_DAEMON_DIR "/" CRM_SYSTEM_PENGINE; pe_subsystem->args = NULL; pe_subsystem->flag_connected = R_PE_CONNECTED; pe_subsystem->flag_required = R_PE_REQUIRED; } else { was_error = TRUE; } if (was_error == FALSE && is_heartbeat_cluster()) { if (start_subsystem(pe_subsystem) == FALSE) { was_error = TRUE; } } if (was_error) { register_fsa_error(C_FSA_INTERNAL, I_ERROR, NULL); } } static int32_t crmd_ipc_accept(qb_ipcs_connection_t * c, uid_t uid, gid_t gid) { crm_trace("Connection %p", c); if (crm_client_new(c, uid, gid) == NULL) { return -EIO; } return 0; } static void crmd_ipc_created(qb_ipcs_connection_t * c) { crm_trace("Connection %p", c); } static int32_t crmd_ipc_dispatch(qb_ipcs_connection_t * c, void *data, size_t size) { uint32_t id = 0; uint32_t flags = 0; crm_client_t *client = crm_client_get(c); xmlNode *msg = crm_ipcs_recv(client, data, size, &id, &flags); crm_trace("Invoked: %s", crm_client_name(client)); if (flags & crm_ipc_client_response) { crm_ipcs_send_ack(client, id, "ack", __FUNCTION__, __LINE__); } if (msg == NULL) { return 0; } #if ENABLE_ACL determine_request_user(client->user, msg, F_CRM_USER); #endif crm_trace("Processing msg from %s", crm_client_name(client)); crm_log_xml_trace(msg, "CRMd[inbound]"); crm_xml_add(msg, F_CRM_SYS_FROM, client->id); if (crmd_authorize_message(msg, client, NULL)) { route_message(C_IPC_MESSAGE, msg); } trigger_fsa(fsa_source); free_xml(msg); return 0; } static int32_t crmd_ipc_closed(qb_ipcs_connection_t * c) { crm_client_t *client = crm_client_get(c); struct crm_subsystem_s *the_subsystem = NULL; crm_trace("Connection %p", c); if (client->userdata == NULL) { crm_trace("Client hadn't registered with us yet"); } else if (strcasecmp(CRM_SYSTEM_PENGINE, client->userdata) == 0) { the_subsystem = pe_subsystem; } else if (strcasecmp(CRM_SYSTEM_TENGINE, client->userdata) == 0) { the_subsystem = te_subsystem; } else if (strcasecmp(CRM_SYSTEM_CIB, client->userdata) == 0) { the_subsystem = cib_subsystem; } if (the_subsystem != NULL) { the_subsystem->source = NULL; the_subsystem->client = NULL; crm_info("Received HUP from %s:[%d]", the_subsystem->name, the_subsystem->pid); } else { /* else that was a transient client */ crm_trace("Received HUP from transient client"); } crm_trace("Disconnecting client %s (%p)", crm_client_name(client), client); free(client->userdata); crm_client_destroy(client); trigger_fsa(fsa_source); return 0; } static void crmd_ipc_destroy(qb_ipcs_connection_t * c) { crm_trace("Connection %p", c); } /* A_STOP */ void do_stop(long long action, enum crmd_fsa_cause cause, enum crmd_fsa_state cur_state, enum crmd_fsa_input current_input, fsa_data_t * msg_data) { if (is_heartbeat_cluster()) { stop_subsystem(pe_subsystem, FALSE); } crm_trace("Closing IPC server"); mainloop_del_ipc_server(ipcs); ipcs = NULL; register_fsa_input(C_FSA_INTERNAL, I_TERMINATE, NULL); } /* A_STARTED */ void do_started(long long action, enum crmd_fsa_cause cause, enum crmd_fsa_state cur_state, enum crmd_fsa_input current_input, fsa_data_t * msg_data) { static struct qb_ipcs_service_handlers crmd_callbacks = { .connection_accept = crmd_ipc_accept, .connection_created = crmd_ipc_created, .msg_process = crmd_ipc_dispatch, .connection_closed = crmd_ipc_closed, .connection_destroyed = crmd_ipc_destroy }; if (cur_state != S_STARTING) { crm_err("Start cancelled... %s", fsa_state2string(cur_state)); return; } else if (is_set(fsa_input_register, R_MEMBERSHIP) == FALSE) { crm_info("Delaying start, no membership data (%.16llx)", R_MEMBERSHIP); crmd_fsa_stall(TRUE); return; } else if (is_set(fsa_input_register, R_LRM_CONNECTED) == FALSE) { crm_info("Delaying start, LRM not connected (%.16llx)", R_LRM_CONNECTED); crmd_fsa_stall(TRUE); return; } else if (is_set(fsa_input_register, R_CIB_CONNECTED) == FALSE) { crm_info("Delaying start, CIB not connected (%.16llx)", R_CIB_CONNECTED); crmd_fsa_stall(TRUE); return; } else if (is_set(fsa_input_register, R_READ_CONFIG) == FALSE) { crm_info("Delaying start, Config not read (%.16llx)", R_READ_CONFIG); crmd_fsa_stall(TRUE); return; } else if (is_set(fsa_input_register, R_PEER_DATA) == FALSE) { /* try reading from HA */ crm_info("Delaying start, No peer data (%.16llx)", R_PEER_DATA); #if SUPPORT_HEARTBEAT if (is_heartbeat_cluster()) { HA_Message *msg = NULL; crm_trace("Looking for a HA message"); msg = fsa_cluster_conn->llc_ops->readmsg(fsa_cluster_conn, 0); if (msg != NULL) { crm_trace("There was a HA message"); ha_msg_del(msg); } } #endif crmd_fsa_stall(TRUE); return; } crm_debug("Init server comms"); ipcs = crmd_ipc_server_init(&crmd_callbacks); if (ipcs == NULL) { crm_err("Failed to create IPC server: shutting down and inhibiting respawn"); register_fsa_error(C_FSA_INTERNAL, I_ERROR, NULL); } if (stonith_reconnect == NULL) { int dummy; stonith_reconnect = mainloop_add_trigger(G_PRIORITY_LOW, te_connect_stonith, &dummy); } set_bit(fsa_input_register, R_ST_REQUIRED); mainloop_set_trigger(stonith_reconnect); crm_notice("The local CRM is operational"); clear_bit(fsa_input_register, R_STARTING); register_fsa_input(msg_data->fsa_cause, I_PENDING, NULL); } /* A_RECOVER */ void do_recover(long long action, enum crmd_fsa_cause cause, enum crmd_fsa_state cur_state, enum crmd_fsa_input current_input, fsa_data_t * msg_data) { set_bit(fsa_input_register, R_IN_RECOVERY); crm_warn("Fast-tracking shutdown in response to errors"); register_fsa_input(C_FSA_INTERNAL, I_TERMINATE, NULL); } /* *INDENT-OFF* */ pe_cluster_option crmd_opts[] = { /* name, old-name, validate, default, description */ { "dc-version", NULL, "string", NULL, "none", NULL, "Version of Pacemaker on the cluster's DC.", "Includes the hash which identifies the exact Mercurial changeset it was built from. Used for diagnostic purposes." }, { "cluster-infrastructure", NULL, "string", NULL, "heartbeat", NULL, "The messaging stack on which Pacemaker is currently running.", "Used for informational and diagnostic purposes." }, { XML_CONFIG_ATTR_DC_DEADTIME, "dc_deadtime", "time", NULL, "20s", &check_time, "How long to wait for a response from other nodes during startup.", "The \"correct\" value will depend on the speed/load of your network and the type of switches used." }, { XML_CONFIG_ATTR_RECHECK, "cluster_recheck_interval", "time", "Zero disables polling. Positive values are an interval in seconds (unless other SI units are specified. eg. 5min)", "15min", &check_timer, "Polling interval for time based changes to options, resource parameters and constraints.", "The Cluster is primarily event driven, however the configuration can have elements that change based on time." " To ensure these changes take effect, we can optionally poll the cluster's status for changes." }, { XML_CONFIG_ATTR_ELECTION_FAIL, "election_timeout", "time", NULL, "2min", &check_timer, "*** Advanced Use Only ***.", "If need to adjust this value, it probably indicates the presence of a bug." }, { XML_CONFIG_ATTR_FORCE_QUIT, "shutdown_escalation", "time", NULL, "20min", &check_timer, "*** Advanced Use Only ***.", "If need to adjust this value, it probably indicates the presence of a bug." }, { "crmd-integration-timeout", NULL, "time", NULL, "3min", &check_timer, "*** Advanced Use Only ***.", "If need to adjust this value, it probably indicates the presence of a bug." }, { "crmd-finalization-timeout", NULL, "time", NULL, "30min", &check_timer, "*** Advanced Use Only ***.", "If you need to adjust this value, it probably indicates the presence of a bug." }, { "crmd-transition-delay", NULL, "time", NULL, "0s", &check_timer, "*** Advanced Use Only ***\nEnabling this option will slow down cluster recovery under all conditions", "Delay cluster recovery for the configured interval to allow for additional/related events to occur.\nUseful if your configuration is sensitive to the order in which ping updates arrive." }, { XML_ATTR_EXPECTED_VOTES, NULL, "integer", NULL, "2", &check_number, "The number of nodes expected to be in the cluster", "Used to calculate quorum in openais based clusters." }, }; /* *INDENT-ON* */ void crmd_metadata(void) { config_metadata("CRM Daemon", "1.0", "CRM Daemon Options", "This is a fake resource that details the options that can be configured for the CRM Daemon.", crmd_opts, DIMOF(crmd_opts)); } static void verify_crmd_options(GHashTable * options) { verify_all_options(options, crmd_opts, DIMOF(crmd_opts)); } static const char * crmd_pref(GHashTable * options, const char *name) { return get_cluster_pref(options, crmd_opts, DIMOF(crmd_opts), name); } static void config_query_callback(xmlNode * msg, int call_id, int rc, xmlNode * output, void *user_data) { const char *value = NULL; GHashTable *config_hash = NULL; crm_time_t *now = crm_time_new(NULL); if (rc != pcmk_ok) { fsa_data_t *msg_data = NULL; crm_err("Local CIB query resulted in an error: %s", pcmk_strerror(rc)); register_fsa_error(C_FSA_INTERNAL, I_ERROR, NULL); if (rc == -EACCES || rc == -pcmk_err_dtd_validation) { crm_err("The cluster is mis-configured - shutting down and staying down"); set_bit(fsa_input_register, R_STAYDOWN); } goto bail; } crm_debug("Call %d : Parsing CIB options", call_id); config_hash = g_hash_table_new_full(crm_str_hash, g_str_equal, g_hash_destroy_str, g_hash_destroy_str); unpack_instance_attributes(output, output, XML_CIB_TAG_PROPSET, NULL, config_hash, CIB_OPTIONS_FIRST, FALSE, now); verify_crmd_options(config_hash); value = crmd_pref(config_hash, XML_CONFIG_ATTR_DC_DEADTIME); election_trigger->period_ms = crm_get_msec(value); value = crmd_pref(config_hash, XML_CONFIG_ATTR_FORCE_QUIT); shutdown_escalation_timer->period_ms = crm_get_msec(value); crm_debug("Shutdown escalation occurs after: %dms", shutdown_escalation_timer->period_ms); value = crmd_pref(config_hash, XML_CONFIG_ATTR_ELECTION_FAIL); election_timeout->period_ms = crm_get_msec(value); value = crmd_pref(config_hash, XML_CONFIG_ATTR_RECHECK); recheck_timer->period_ms = crm_get_msec(value); crm_debug("Checking for expired actions every %dms", recheck_timer->period_ms); value = crmd_pref(config_hash, "crmd-transition-delay"); transition_timer->period_ms = crm_get_msec(value); value = crmd_pref(config_hash, "crmd-integration-timeout"); integration_timer->period_ms = crm_get_msec(value); value = crmd_pref(config_hash, "crmd-finalization-timeout"); finalization_timer->period_ms = crm_get_msec(value); #if SUPPORT_COROSYNC if (is_classic_ais_cluster()) { value = crmd_pref(config_hash, XML_ATTR_EXPECTED_VOTES); crm_debug("Sending expected-votes=%s to corosync", value); send_cluster_text(crm_class_quorum, value, TRUE, NULL, crm_msg_ais); } #endif set_bit(fsa_input_register, R_READ_CONFIG); crm_trace("Triggering FSA: %s", __FUNCTION__); mainloop_set_trigger(fsa_source); g_hash_table_destroy(config_hash); bail: crm_time_free(now); } gboolean crm_read_options(gpointer user_data) { int call_id = fsa_cib_conn->cmds->query(fsa_cib_conn, XML_CIB_TAG_CRMCONFIG, NULL, cib_scope_local); fsa_register_cib_callback(call_id, FALSE, NULL, config_query_callback); crm_trace("Querying the CIB... call %d", call_id); return TRUE; } /* A_READCONFIG */ void do_read_config(long long action, enum crmd_fsa_cause cause, enum crmd_fsa_state cur_state, enum crmd_fsa_input current_input, fsa_data_t * msg_data) { mainloop_set_trigger(config_read); } void crm_shutdown(int nsig) { if (crmd_mainloop != NULL && g_main_is_running(crmd_mainloop)) { if (is_set(fsa_input_register, R_SHUTDOWN)) { crm_err("Escalating the shutdown"); register_fsa_input_before(C_SHUTDOWN, I_ERROR, NULL); } else { set_bit(fsa_input_register, R_SHUTDOWN); register_fsa_input(C_SHUTDOWN, I_SHUTDOWN, NULL); if (shutdown_escalation_timer->period_ms < 1) { const char *value = crmd_pref(NULL, XML_CONFIG_ATTR_FORCE_QUIT); int msec = crm_get_msec(value); crm_debug("Using default shutdown escalation: %dms", msec); shutdown_escalation_timer->period_ms = msec; } /* cant rely on this... */ crm_notice("Requesting shutdown, upper limit is %dms", shutdown_escalation_timer->period_ms); crm_timer_start(shutdown_escalation_timer); } } else { crm_info("exit from shutdown"); crmd_exit(pcmk_ok); } } pacemaker-master/crmd/corosync.c000066400000000000000000000141051217637305600172420ustar00rootroot00000000000000/* * Copyright (C) 2004 Andrew Beekhof * * 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 2 of the License, or (at your option) any later version. * * This software 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 library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include extern void post_cache_update(int seq); extern void crmd_ha_connection_destroy(gpointer user_data); /* A_HA_CONNECT */ #if SUPPORT_COROSYNC static void crmd_cs_dispatch(cpg_handle_t handle, const struct cpg_name *groupName, uint32_t nodeid, uint32_t pid, void *msg, size_t msg_len) { int seq = 0; xmlNode *xml = NULL; const char *seq_s = NULL; crm_node_t *peer = NULL; enum crm_proc_flag flag = crm_proc_cpg; uint32_t kind = 0; const char *from = NULL; char *data = pcmk_message_common_cs(handle, nodeid, pid, msg, &kind, &from); if(data == NULL) { return; } xml = string2xml(data); if (xml == NULL) { crm_err("Could not parse message content (%d): %.100s", kind, data); free(data); return; } switch (kind) { case crm_class_members: seq_s = crm_element_value(xml, "id"); seq = crm_int_helper(seq_s, NULL); set_bit(fsa_input_register, R_PEER_DATA); post_cache_update(seq); /* fall through */ case crm_class_quorum: crm_update_quorum(crm_have_quorum, FALSE); if (AM_I_DC) { const char *votes = crm_element_value(xml, "expected"); if (votes == NULL || check_number(votes) == FALSE) { crm_log_xml_err(xml, "Invalid quorum/membership update"); } else { int rc = update_attr_delegate(fsa_cib_conn, cib_quorum_override | cib_scope_local | cib_inhibit_notify, XML_CIB_TAG_CRMCONFIG, NULL, NULL, NULL, NULL, XML_ATTR_EXPECTED_VOTES, votes, FALSE, NULL); crm_info("Setting expected votes to %s", votes); if (pcmk_ok > rc) { crm_err("Quorum update failed: %s", pcmk_strerror(rc)); } } } break; case crm_class_cluster: crm_xml_add(xml, F_ORIG, from); /* crm_xml_add_int(xml, F_SEQ, wrapper->id); Fake? */ if (is_heartbeat_cluster()) { flag = crm_proc_heartbeat; } else if (is_classic_ais_cluster()) { flag = crm_proc_plugin; } peer = crm_get_peer(0, from); if (is_not_set(peer->processes, flag)) { /* If we can still talk to our peer process on that node, * then its also part of the corosync membership */ crm_warn("Recieving messages from a node we think is dead: %s[%d]", peer->uname, peer->id); crm_update_peer_proc(__FUNCTION__, peer, flag, ONLINESTATUS); } crmd_ha_msg_filter(xml); break; case crm_class_rmpeer: /* Ignore */ break; case crm_class_notify: case crm_class_nodeid: crm_err("Unexpected message class (%d): %.100s", kind, data); break; default: crm_err("Invalid message class (%d): %.100s", kind, data); } free(data); free_xml(xml); } static gboolean crmd_cman_dispatch(unsigned long long seq, gboolean quorate) { crm_update_quorum(quorate, FALSE); post_cache_update(seq); return TRUE; } static void crmd_quorum_destroy(gpointer user_data) { if (is_not_set(fsa_input_register, R_HA_DISCONNECTED)) { crm_err("connection terminated"); crmd_exit(ENOLINK); } else { crm_info("connection closed"); } } static void crmd_cs_destroy(gpointer user_data) { if (is_not_set(fsa_input_register, R_HA_DISCONNECTED)) { crm_err("connection terminated"); crmd_exit(ENOLINK); } else { crm_info("connection closed"); } } # if SUPPORT_CMAN static void crmd_cman_destroy(gpointer user_data) { if (is_not_set(fsa_input_register, R_HA_DISCONNECTED)) { crm_err("connection terminated"); crmd_exit(ENOLINK); } else { crm_info("connection closed"); } } # endif extern gboolean crm_connect_corosync(crm_cluster_t * cluster); gboolean crm_connect_corosync(crm_cluster_t * cluster) { gboolean rc = FALSE; if (is_openais_cluster()) { crm_set_status_callback(&peer_update_callback); cluster->cpg.cpg_deliver_fn = crmd_cs_dispatch; cluster->cpg.cpg_confchg_fn = pcmk_cpg_membership; cluster->destroy = crmd_cs_destroy; rc = crm_cluster_connect(cluster); } if (rc && is_corosync_cluster()) { cluster_connect_quorum(crmd_cman_dispatch, crmd_quorum_destroy); } # if SUPPORT_CMAN if (rc && is_cman_cluster()) { init_cman_connection(crmd_cman_dispatch, crmd_cman_destroy); set_bit(fsa_input_register, R_MEMBERSHIP); } # endif return rc; } #endif pacemaker-master/crmd/crmd.c000066400000000000000000000014231217637305600163270ustar00rootroot00000000000000/* * Copyright (C) 2004 Andrew Beekhof * * 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 2 of the License, or (at your option) any later version. * * This software 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 library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ pacemaker-master/crmd/crmd.h000066400000000000000000000021441217637305600163350ustar00rootroot00000000000000/* * Copyright (C) 2004 Andrew Beekhof * * 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 2 of the License, or (at your option) any later version. * * This software 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 library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef CRMD__H # define CRMD__H # define SYS_NAME CRM_SYSTEM_CRMD # define PID_FILE WORKING_DIR "/"SYS_NAME".pid" # define DAEMON_LOG DEVEL_DIR"/"SYS_NAME".log" # define DAEMON_DEBUG DEVEL_DIR"/"SYS_NAME".debug" extern GMainLoop *crmd_mainloop; extern GHashTable *ipc_clients; extern void crmd_metadata(void); #endif pacemaker-master/crmd/crmd_callbacks.h000066400000000000000000000032301217637305600203310ustar00rootroot00000000000000/* * Copyright (C) 2004 Andrew Beekhof * * 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 2 of the License, or (at your option) any later version. * * This software 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 library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include extern void crmd_ha_msg_filter(xmlNode * msg); /* * Apparently returning TRUE means "stay connected, keep doing stuff". * Returning FALSE means "we're all done, close the connection" */ extern void crmd_ipc_connection_destroy(gpointer user_data); extern void crmd_ha_status_callback(const char *node, const char *status, void *private_data); extern void crmd_client_status_callback(const char *node, const char *client, const char *status, void *private); extern void msg_ccm_join(const xmlNode * msg, void *foo); extern void crmd_cib_connection_destroy(gpointer user_data); extern gboolean crm_fsa_trigger(gpointer user_data); extern void peer_update_callback(enum crm_status_type type, crm_node_t * node, const void *data); #if SUPPORT_HEARTBEAT void crmd_ha_msg_callback(HA_Message * hamsg, void *private_data); #endif pacemaker-master/crmd/crmd_dsa.dot000066400000000000000000000046001217637305600175220ustar00rootroot00000000000000digraph "g" { graph [ fontsize = "12" fontname = "Times-Roman" fontcolor = "black" bb = "0,0,398.922306,478.927856" color = "black" ] node [ fontsize = "12" fontname = "Times-Roman" fontcolor = "black" shape = "ellipse" color = "black" ] edge [ fontsize = "12" fontname = "Times-Roman" fontcolor = "black" color = "black" ] // special nodes "S_STARTING" [ color = "blue" fontcolor = "blue" ] "S_TERMINATE" [ color = "red" fontcolor = "red" ] // DC only nodes "S_RECOVERY_DC" [ fontcolor = "green" ] "S_INTEGRATION" [ fontcolor = "green" ] "S_POLICY_ENGINE" [ fontcolor = "green" ] "S_TRANSITION_ENGINE" [ fontcolor = "green" ] "S_RELEASE_DC" [ fontcolor = "green" ] "S_" [ fontcolor = "green" ] "S_IDLE" [ fontcolor = "green" ] // state transitions "S_" -> "S_ELECTION" [ label = "I_DC_TIMEOUT" ] "S_" -> "S_RECOVERY" [ label = "I_ERROR" ] "S_" -> "S_" [ label = "I_ROUTER,\nI_REQUEST" ] "S_" -> "S_RELEASE_DC" [ label = "I_SHUTDOWN" ] "S_" -> "S_INTEGRATION" [ label = "I_NODE_JOIN" ] "S_" -> "S_POLICY_ENGINE" [ label = "I_CIB_UPDATE,\nI_NODE_LEFT,\nI_NODE_LEAVING" ] "S_" -> "S_RECOVERY_DC" [ label = "I_ERROR" ] "S_" -> "S_" [ label = "I_ROUTER,\nI_REQUEST" ] "S_ELECTION" -> "S_INTEGRATION" [ label = "I_ELECTION_DC" ] "S_ELECTION" -> "S_NOT_DC" [ label = "I_NOT_DC" ] "S_ELECTION" -> "S_RELEASE_DC" [ label = "I_ELECTION_RELEASE_DC" ] "S_INTEGRATION" -> "S_POLICY_ENGINE" [ label = "I_SUCCESS" ] "S_NOT_DC" -> "S_STOPPING" [ label = "I_SHUTDOWN" ] "S_POLICY_ENGINE" -> "S_TRANSITION_ENGINE" [ label = "I_SUCCESS" ] "S_POLICY_ENGINE" -> "S_POLICY_ENGINE" [ label = "I_FAIL\nI_RESTART" ] "S_RECOVERY_DC" -> "S_INTEGRATION" [ label = "I_RECOVERED" ] "S_RECOVERY_DC" -> "S_RELEASE_DC" [ label = "I_NOT_DC,\nI_SHUTDOWN" ] "S_RECOVERY" -> "S_STOPPING" [ label = "I_SHUTDOWN" ] "S_RECOVERY" -> "S_NOT_DC" [ label = "I_RECOVERED" ] "S_RELEASE_DC" -> "S_NOT_DC" [ label = "I_RELEASE_SUCCESS" ] "S_RELEASE_DC" -> "S_STOPPING" [ label = "I_RELEASE_FAIL" ] "S_STARTING" -> "S_STOPPING" [ label = "I_FAIL" ] "S_STARTING" -> "S_NOT_DC" [ label = "I_SUCCESS" ] "S_STOPPING" -> "S_TERMINATE" [ label = "I_SUCCESS,\nI_FAIL" ] "S_TRANSITION_ENGINE" -> "S_POLICY_ENGINE" [ label = "I_FAIL" ] "S_TRANSITION_ENGINE" -> "S_IDLE" [ label = "I_SUCCESS" ] } pacemaker-master/crmd/crmd_fsa.h000066400000000000000000000075641217637305600172010ustar00rootroot00000000000000/* * Copyright (C) 2004 Andrew Beekhof * * 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 2 of the License, or (at your option) any later version. * * This software 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 library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef CRMD_FSA__H # define CRMD_FSA__H # include # include # include # include # include # include # include # if SUPPORT_HEARTBEAT extern ll_cluster_t *fsa_cluster_conn; # endif /* copy from struct client_child in heartbeat.h * * Plus a couple of other things */ struct crm_subsystem_s { pid_t pid; /* Process id of child process */ const char *name; /* executable name */ const char *path; /* Command location */ const char *command; /* Command with path */ const char *args; /* Command arguments */ crm_client_t *client; /* Client connection object */ gboolean sent_kill; mainloop_io_t *source; /* How can we communicate with it */ long long flag_connected; /* */ long long flag_required; /* */ }; typedef struct fsa_timer_s fsa_timer_t; struct fsa_timer_s { guint source_id; /* timer source id */ int period_ms; /* timer period */ enum crmd_fsa_input fsa_input; gboolean(*callback) (gpointer data); gboolean repeat; int counter; }; enum fsa_data_type { fsa_dt_none, fsa_dt_ha_msg, fsa_dt_xml, fsa_dt_lrm, }; typedef struct fsa_data_s fsa_data_t; struct fsa_data_s { int id; enum crmd_fsa_input fsa_input; enum crmd_fsa_cause fsa_cause; long long actions; const char *origin; void *data; enum fsa_data_type data_type; }; extern enum crmd_fsa_state s_crmd_fsa(enum crmd_fsa_cause cause); /* Global FSA stuff */ extern volatile gboolean do_fsa_stall; extern volatile enum crmd_fsa_state fsa_state; extern volatile long long fsa_input_register; extern volatile long long fsa_actions; extern cib_t *fsa_cib_conn; extern char *fsa_our_uname; extern char *fsa_our_uuid; extern char *fsa_pe_ref; /* the last invocation of the PE */ extern char *fsa_our_dc; extern char *fsa_our_dc_version; extern GListPtr fsa_message_queue; extern fsa_timer_t *election_trigger; /* */ extern fsa_timer_t *election_timeout; /* */ extern fsa_timer_t *shutdown_escalation_timer; /* */ extern fsa_timer_t *transition_timer; extern fsa_timer_t *integration_timer; extern fsa_timer_t *finalization_timer; extern fsa_timer_t *wait_timer; extern fsa_timer_t *recheck_timer; extern crm_trigger_t *fsa_source; extern crm_trigger_t *config_read; extern struct crm_subsystem_s *cib_subsystem; extern struct crm_subsystem_s *te_subsystem; extern struct crm_subsystem_s *pe_subsystem; /* these two should be moved elsewhere... */ extern void do_update_cib_nodes(gboolean overwrite, const char *caller); extern gboolean do_dc_heartbeat(gpointer data); # define AM_I_DC is_set(fsa_input_register, R_THE_DC) # define AM_I_OPERATIONAL (is_set(fsa_input_register, R_STARTING)==FALSE) extern unsigned long long saved_ccm_membership_id; extern gboolean ever_had_quorum; # include # include # define trigger_fsa(source) crm_trace("Triggering FSA: %s", __FUNCTION__); \ mainloop_set_trigger(source); #endif pacemaker-master/crmd/crmd_lrm.h000066400000000000000000000125311217637305600172100ustar00rootroot00000000000000/* * Copyright (C) 2004 Andrew Beekhof * * 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 2 of the License, or (at your option) any later version. * * This software 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 library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ extern gboolean verify_stopped(enum crmd_fsa_state cur_state, int log_level); extern void lrm_clear_last_failure(const char *rsc_id, const char *node_name); void lrm_op_callback(lrmd_event_data_t * op); typedef struct resource_history_s { char *id; uint32_t last_callid; lrmd_rsc_info_t rsc; lrmd_event_data_t *last; lrmd_event_data_t *failed; GList *recurring_op_list; /* Resources must be stopped using the same * parameters they were started with. This hashtable * holds the parameters that should be used for the next stop * cmd on this resource. */ GHashTable *stop_params; } rsc_history_t; struct recurring_op_s { char *rsc_id; char *op_type; char *op_key; int call_id; int interval; gboolean remove; gboolean cancelled; }; typedef struct lrm_state_s { const char *node_name; /* reserved for lrm_state.c usage only */ void *conn; /* reserved for remote_lrmd_ra.c usage only */ void *remote_ra_data; GHashTable *resource_history; GHashTable *pending_ops; GHashTable *deletion_ops; int num_lrm_register_fails; } lrm_state_t; struct pending_deletion_op_s { char *rsc; ha_msg_input_t *input; }; xmlNode *do_lrm_query_internal(lrm_state_t * lrm_state, gboolean is_replace); /*! * \brief Clear all state information from a single state entry. * \note This does not close the lrmd connection */ void lrm_state_reset_tables(lrm_state_t * lrm_state); GList *lrm_state_get_list(void); /*! * \brief Initiate internal state tables */ gboolean lrm_state_init_local(void); /*! * \brief Destroy all state entries and internal state tables */ void lrm_state_destroy_all(void); /*! * \brief Create lrmd connection entry. */ lrm_state_t *lrm_state_create(const char *node_name); /*! * \brief Destroy lrmd connection keyed of node name */ void lrm_state_destroy(const char *node_name); /*! * \brief Find lrm_state data by node name */ lrm_state_t *lrm_state_find(const char *node_name); /*! * \brief Either find or create a new entry */ lrm_state_t *lrm_state_find_or_create(const char *node_name); /*! * The functions below are wrappers for the lrmd api calls the crmd * uses. These wrapper functions allow us to treat the crmd's remote * lrmd connection resources the same as regular resources. Internally * Regular resources go to the lrmd, and remote connection resources are * handled locally in the crmd. */ void lrm_state_disconnect(lrm_state_t * lrm_state); int lrm_state_ipc_connect(lrm_state_t * lrm_state); int lrm_state_remote_connect_async(lrm_state_t * lrm_state, const char *server, int port, int timeout); int lrm_state_is_connected(lrm_state_t * lrm_state); int lrm_state_poke_connection(lrm_state_t * lrm_state); int lrm_state_get_metadata(lrm_state_t * lrm_state, const char *class, const char *provider, const char *agent, char **output, enum lrmd_call_options options); int lrm_state_cancel(lrm_state_t * lrm_state, const char *rsc_id, const char *action, int interval); int lrm_state_exec(lrm_state_t * lrm_state, const char *rsc_id, const char *action, const char *userdata, int interval, /* ms */ int timeout, /* ms */ int start_delay, /* ms */ lrmd_key_value_t * params); lrmd_rsc_info_t *lrm_state_get_rsc_info(lrm_state_t * lrm_state, const char *rsc_id, enum lrmd_call_options options); int lrm_state_register_rsc(lrm_state_t * lrm_state, const char *rsc_id, const char *class, const char *provider, const char *agent, enum lrmd_call_options options); int lrm_state_unregister_rsc(lrm_state_t * lrm_state, const char *rsc_id, enum lrmd_call_options options); /*! These functions are used to manage the remote lrmd connection resources */ void remote_lrm_op_callback(lrmd_event_data_t * op); gboolean is_remote_lrmd_ra(const char *agent, const char *provider, const char *id); lrmd_rsc_info_t *remote_ra_get_rsc_info(lrm_state_t * lrm_state, const char *rsc_id); int remote_ra_cancel(lrm_state_t * lrm_state, const char *rsc_id, const char *action, int interval); int remote_ra_exec(lrm_state_t * lrm_state, const char *rsc_id, const char *action, const char *userdata, int interval, /* ms */ int timeout, /* ms */ int start_delay, /* ms */ lrmd_key_value_t * params); void remote_ra_cleanup(lrm_state_t * lrm_state); pacemaker-master/crmd/crmd_messages.h000066400000000000000000000115251217637305600202270ustar00rootroot00000000000000/* * Copyright (C) 2004 Andrew Beekhof * * 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 2 of the License, or (at your option) any later version. * * This software 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 library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef XML_CRM_MESSAGES__H # define XML_CRM_MESSAGES__H # include # include # include # include # include typedef struct ha_msg_input_s { xmlNode *msg; xmlNode *xml; } ha_msg_input_t; extern ha_msg_input_t *new_ha_msg_input(xmlNode * orig); extern void delete_ha_msg_input(ha_msg_input_t * orig); extern void *fsa_typed_data_adv(fsa_data_t * fsa_data, enum fsa_data_type a_type, const char *caller); # define fsa_typed_data(x) fsa_typed_data_adv(msg_data, x, __FUNCTION__) extern void register_fsa_error_adv(enum crmd_fsa_cause cause, enum crmd_fsa_input input, fsa_data_t * cur_data, void *new_data, const char *raised_from); # define register_fsa_error(cause, input, new_data) register_fsa_error_adv(cause, input, msg_data, new_data, __FUNCTION__) extern int register_fsa_input_adv(enum crmd_fsa_cause cause, enum crmd_fsa_input input, void *data, long long with_actions, gboolean prepend, const char *raised_from); extern void fsa_dump_queue(int log_level); extern void route_message(enum crmd_fsa_cause cause, xmlNode * input); # define crmd_fsa_stall(suppress) do { \ if(suppress == FALSE && msg_data != NULL) { \ register_fsa_input_adv( \ ((fsa_data_t*)msg_data)->fsa_cause, I_WAIT_FOR_EVENT, \ ((fsa_data_t*)msg_data)->data, action, TRUE, __FUNCTION__); \ } else { \ register_fsa_input_adv( \ C_FSA_INTERNAL, I_WAIT_FOR_EVENT, \ NULL, action, TRUE, __FUNCTION__); \ } \ } while(0) # define register_fsa_input(cause, input, data) register_fsa_input_adv(cause, input, data, A_NOTHING, FALSE, __FUNCTION__) # define register_fsa_action(action) { \ fsa_actions |= action; \ if(fsa_source) { \ mainloop_set_trigger(fsa_source); \ } \ crm_debug("%s added action %s to the FSA", \ __FUNCTION__, fsa_action2string(action)); \ } # define register_fsa_input_before(cause, input, data) register_fsa_input_adv(cause, input, data, A_NOTHING, TRUE, __FUNCTION__) # define register_fsa_input_later(cause, input, data) register_fsa_input_adv(cause, input, data, A_NOTHING, FALSE, __FUNCTION__) void delete_fsa_input(fsa_data_t * fsa_data); GListPtr put_message(fsa_data_t * new_message); fsa_data_t *get_message(void); gboolean is_message(void); gboolean have_wait_message(void); extern gboolean relay_message(xmlNode * relay_message, gboolean originated_locally); extern void process_message(xmlNode * msg, gboolean originated_locally, const char *src_node_name); extern gboolean crm_dc_process_message(xmlNode * whole_message, xmlNode * action, const char *host_from, const char *sys_from, const char *sys_to, const char *op, gboolean dc_mode); extern gboolean send_msg_via_ipc(xmlNode * msg, const char *sys); extern gboolean add_pending_outgoing_reply(const char *originating_node_name, const char *crm_msg_reference, const char *sys_to, const char *sys_from); gboolean crmd_is_proxy_session(const char *session); void crmd_proxy_send(const char *session, xmlNode *msg); extern gboolean crmd_authorize_message(xmlNode * client_msg, crm_client_t * curr_client, const char *proxy_session); extern gboolean send_request(xmlNode * msg, char **msg_reference); extern enum crmd_fsa_input handle_message(xmlNode * stored_msg, enum crmd_fsa_cause cause); extern ha_msg_input_t *copy_ha_msg_input(ha_msg_input_t * orig); #endif pacemaker-master/crmd/crmd_utils.h000066400000000000000000000107671217637305600175670ustar00rootroot00000000000000/* * Copyright (C) 2004 Andrew Beekhof * * 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 2 of the License, or (at your option) any later version. * * This software 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 library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef CRMD_UTILS__H # define CRMD_UTILS__H # include # include # include /* For CIB_OP_MODIFY */ # define CLIENT_EXIT_WAIT 30 # define FAKE_TE_ID "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" # define fsa_cib_delete(section, data, options, call_id, user_name) \ if(fsa_cib_conn != NULL) { \ call_id = cib_internal_op( \ fsa_cib_conn, CIB_OP_DELETE, NULL, section, data, \ NULL, options, user_name); \ \ } else { \ crm_err("No CIB connection available"); \ } # define fsa_cib_update(section, data, options, call_id, user_name) \ if(fsa_cib_conn != NULL) { \ call_id = cib_internal_op( \ fsa_cib_conn, CIB_OP_MODIFY, NULL, section, data, \ NULL, options, user_name); \ \ } else { \ crm_err("No CIB connection available"); \ } # define fsa_cib_anon_update(section, data, options) \ if(fsa_cib_conn != NULL) { \ fsa_cib_conn->cmds->modify( \ fsa_cib_conn, section, data, options); \ \ } else { \ crm_err("No CIB connection available"); \ } extern gboolean fsa_has_quorum; extern int last_peer_update; extern int last_resource_update; enum node_update_flags { node_update_none = 0x0000, node_update_quick = 0x0001, node_update_cluster = 0x0010, node_update_peer = 0x0020, node_update_join = 0x0040, node_update_expected = 0x0100, }; gboolean crm_timer_stop(fsa_timer_t * timer); gboolean crm_timer_start(fsa_timer_t * timer); gboolean crm_timer_popped(gpointer data); gboolean is_timer_started(fsa_timer_t * timer); xmlNode *create_node_state(const char *uname, const char *in_cluster, const char *is_peer, const char *join_state, const char *exp_state, gboolean clear_shutdown, const char *src); int crmd_exit(int rc); int crmd_fast_exit(int rc); gboolean stop_subsystem(struct crm_subsystem_s *centry, gboolean force_quit); gboolean start_subsystem(struct crm_subsystem_s *centry); void fsa_dump_actions(long long action, const char *text); void fsa_dump_inputs(int log_level, const char *text, long long input_register); gboolean update_dc(xmlNode * msg); void crm_update_peer_join(const char *source, crm_node_t * node, enum crm_join_phase phase); xmlNode *do_update_node_cib(crm_node_t * node, int flags, xmlNode * parent, const char *source); void populate_cib_nodes(enum node_update_flags flags, const char *source); void crm_update_quorum(gboolean quorum, gboolean force_update); void erase_status_tag(const char *uname, const char *tag, int options); void update_attrd(const char *host, const char *name, const char *value, const char *user_name, gboolean is_remote_node); int crmd_join_phase_count(enum crm_join_phase phase); void crmd_join_phase_log(int level); const char *get_timer_desc(fsa_timer_t * timer); gboolean too_many_st_failures(void); void st_fail_count_reset(const char * target); # define fsa_register_cib_callback(id, flag, data, fn) do { \ fsa_cib_conn->cmds->register_callback( \ fsa_cib_conn, id, 10 * (1 + crm_active_peers()), \ flag, data, #fn, fn); \ } while(0) # define start_transition(state) do { \ switch(state) { \ case S_TRANSITION_ENGINE: \ register_fsa_action(A_TE_CANCEL); \ break; \ case S_POLICY_ENGINE: \ case S_IDLE: \ register_fsa_input(C_FSA_INTERNAL, I_PE_CALC, NULL); \ break; \ default: \ crm_debug("NOT starting a new transition in state %s", \ fsa_state2string(fsa_state)); \ break; \ } \ } while(0) #endif pacemaker-master/crmd/election.c000066400000000000000000000441111217637305600172050ustar00rootroot00000000000000/* * Copyright (C) 2004 Andrew Beekhof * * 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 2 of the License, or (at your option) any later version. * * This software 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 library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include #include #include #include #include #include #include #include #include #include #define STORM_INTERVAL 2 /* in seconds */ #define STORM_MULTIPLIER 5 /* multiplied by the number of nodes */ GHashTable *voted = NULL; uint highest_born_on = -1; static int current_election_id = 1; static int crm_uptime(struct timeval *output) { static time_t expires = 0; static struct rusage info; time_t tm_now = time(NULL); if (expires < tm_now) { int rc = getrusage(RUSAGE_SELF, &info); output->tv_sec = 0; output->tv_usec = 0; if (rc < 0) { crm_perror(LOG_ERR, "Could not calculate the current uptime"); expires = 0; return -1; } crm_debug("Current CPU usage is: %lds, %ldus", (long)info.ru_utime.tv_sec, (long)info.ru_utime.tv_usec); } expires = tm_now + STORM_INTERVAL; /* N seconds after the last _access_ */ output->tv_sec = info.ru_utime.tv_sec; output->tv_usec = info.ru_utime.tv_usec; return 1; } static int crm_compare_age(struct timeval your_age) { struct timeval our_age; if (crm_uptime(&our_age) < 0) { return -1; } /* We want these times to be "significantly" different */ if (our_age.tv_sec > your_age.tv_sec) { crm_debug("Win: %ld vs %ld (seconds)", (long)our_age.tv_sec, (long)your_age.tv_sec); return 1; } else if (our_age.tv_sec < your_age.tv_sec) { crm_debug("Loose: %ld vs %ld (seconds)", (long)our_age.tv_sec, (long)your_age.tv_sec); return -1; } else if (our_age.tv_usec > your_age.tv_usec) { crm_debug("Win: %ld.%ld vs %ld.%ld (usec)", (long)our_age.tv_sec, (long)our_age.tv_usec, (long)your_age.tv_sec, (long)your_age.tv_usec); return 1; } else if (our_age.tv_usec < your_age.tv_usec) { crm_debug("Loose: %ld.%ld vs %ld.%ld (usec)", (long)our_age.tv_sec, (long)our_age.tv_usec, (long)your_age.tv_sec, (long)your_age.tv_usec); return -1; } return 0; } /* A_ELECTION_VOTE */ void do_election_vote(long long action, enum crmd_fsa_cause cause, enum crmd_fsa_state cur_state, enum crmd_fsa_input current_input, fsa_data_t * msg_data) { struct timeval age; xmlNode *vote = NULL; gboolean not_voting = FALSE; /* don't vote if we're in one of these states or wanting to shut down */ switch (cur_state) { case S_STARTING: case S_RECOVERY: case S_STOPPING: case S_TERMINATE: crm_warn("Not voting in election, we're in state %s", fsa_state2string(cur_state)); not_voting = TRUE; break; default: break; } if (not_voting == FALSE) { if (is_set(fsa_input_register, R_STARTING)) { not_voting = TRUE; } } if (not_voting) { if (AM_I_DC) { register_fsa_input(C_FSA_INTERNAL, I_RELEASE_DC, NULL); } else { register_fsa_input(C_FSA_INTERNAL, I_PENDING, NULL); } return; } vote = create_request(CRM_OP_VOTE, NULL, NULL, CRM_SYSTEM_CRMD, CRM_SYSTEM_CRMD, NULL); current_election_id++; crm_xml_add(vote, F_CRM_ELECTION_OWNER, fsa_our_uuid); crm_xml_add_int(vote, F_CRM_ELECTION_ID, current_election_id); crm_uptime(&age); crm_xml_add_int(vote, F_CRM_ELECTION_AGE_S, age.tv_sec); crm_xml_add_int(vote, F_CRM_ELECTION_AGE_US, age.tv_usec); send_cluster_message(NULL, crm_msg_crmd, vote, TRUE); free_xml(vote); crm_debug("Started election %d", current_election_id); if (voted) { g_hash_table_destroy(voted); } voted = NULL; if (cur_state == S_ELECTION || cur_state == S_RELEASE_DC) { crm_timer_start(election_timeout); } else if (cur_state != S_INTEGRATION) { crm_err("Broken? Voting in state %s", fsa_state2string(cur_state)); } return; } char *dc_hb_msg = NULL; int beat_num = 0; gboolean do_dc_heartbeat(gpointer data) { return TRUE; } struct election_data_s { const char *winning_uname; unsigned int winning_bornon; }; void do_election_check(long long action, enum crmd_fsa_cause cause, enum crmd_fsa_state cur_state, enum crmd_fsa_input current_input, fsa_data_t * msg_data) { int voted_size = 0; int num_members = crm_active_peers(); if (voted) { voted_size = g_hash_table_size(voted); } /* in the case of #voted > #members, it is better to * wait for the timeout and give the cluster time to * stabilize */ if (fsa_state != S_ELECTION) { crm_debug("Ignore election check: we not in an election"); } else if (voted_size >= num_members) { /* we won and everyone has voted */ crm_timer_stop(election_timeout); register_fsa_input(C_FSA_INTERNAL, I_ELECTION_DC, NULL); if (voted_size > num_members) { GHashTableIter gIter; const crm_node_t *node; char *key = NULL; g_hash_table_iter_init(&gIter, crm_peer_cache); while (g_hash_table_iter_next(&gIter, NULL, (gpointer *) & node)) { if (crm_is_peer_active(node)) { crm_err("member: %s proc=%.32x", node->uname, node->processes); } } g_hash_table_iter_init(&gIter, voted); while (g_hash_table_iter_next(&gIter, (gpointer *) & key, NULL)) { crm_err("voted: %s", key); } } crm_debug("Destroying voted hash"); g_hash_table_destroy(voted); voted = NULL; } else { crm_debug("Still waiting on %d non-votes (%d total)", num_members - voted_size, num_members); } return; } #define loss_dampen 2 /* in seconds */ /* A_ELECTION_COUNT */ void do_election_count_vote(long long action, enum crmd_fsa_cause cause, enum crmd_fsa_state cur_state, enum crmd_fsa_input current_input, fsa_data_t * msg_data) { int age = 0; int election_id = -1; int log_level = LOG_INFO; gboolean use_born_on = FALSE; gboolean done = FALSE; gboolean we_loose = FALSE; const char *op = NULL; const char *vote_from = NULL; const char *election_owner = NULL; const char *reason = "unknown"; crm_node_t *our_node = NULL, *your_node = NULL; ha_msg_input_t *vote = fsa_typed_data(fsa_dt_ha_msg); static int election_wins = 0; time_t tm_now = time(NULL); static time_t expires = 0; static time_t last_election_loss = 0; /* if the membership copy is NULL we REALLY shouldnt be voting * the question is how we managed to get here. */ CRM_CHECK(msg_data != NULL, return); CRM_CHECK(vote != NULL, crm_err("Bogus data from %s", msg_data->origin); return); CRM_CHECK(vote->msg != NULL, crm_err("Bogus data from %s", msg_data->origin); return); if(crm_peer_cache == NULL) { if(is_not_set(fsa_input_register, R_SHUTDOWN)) { crm_err("Internal error, no peer cache"); } return; } op = crm_element_value(vote->msg, F_CRM_TASK); vote_from = crm_element_value(vote->msg, F_CRM_HOST_FROM); election_owner = crm_element_value(vote->msg, F_CRM_ELECTION_OWNER); crm_element_value_int(vote->msg, F_CRM_ELECTION_ID, &election_id); CRM_CHECK(vote_from != NULL, vote_from = fsa_our_uname); your_node = crm_get_peer(0, vote_from); our_node = crm_get_peer(0, fsa_our_uname); if (voted == NULL) { crm_debug("Created voted hash"); voted = g_hash_table_new_full(crm_str_hash, g_str_equal, g_hash_destroy_str, g_hash_destroy_str); } if (is_heartbeat_cluster()) { use_born_on = TRUE; } else if (is_classic_ais_cluster()) { use_born_on = TRUE; } if (cur_state == S_STARTING) { reason = "Still starting"; we_loose = TRUE; } else if (our_node == NULL || crm_is_peer_active(our_node) == FALSE) { reason = "We are not part of the cluster"; log_level = LOG_ERR; we_loose = TRUE; } else if (election_id != current_election_id && crm_str_eq(fsa_our_uuid, election_owner, TRUE)) { log_level = LOG_DEBUG_2; reason = "Superceeded"; done = TRUE; } else if (your_node == NULL || crm_is_peer_active(your_node) == FALSE) { /* Possibly we cached the message in the FSA queue at a point that it wasn't */ reason = "Peer is not part of our cluster"; log_level = LOG_WARNING; done = TRUE; } else if (crm_str_eq(op, CRM_OP_NOVOTE, TRUE)) { char *op_copy = strdup(op); char *uname_copy = strdup(vote_from); CRM_ASSERT(crm_str_eq(fsa_our_uuid, election_owner, TRUE)); /* update the list of nodes that have voted */ g_hash_table_replace(voted, uname_copy, op_copy); reason = "Recorded"; done = TRUE; } else { struct timeval your_age; const char *your_version = crm_element_value(vote->msg, F_CRM_VERSION); your_age.tv_sec = 0; your_age.tv_usec = 0; crm_element_value_int(vote->msg, F_CRM_ELECTION_AGE_S, (int *)&(your_age.tv_sec)); crm_element_value_int(vote->msg, F_CRM_ELECTION_AGE_US, (int *)&(your_age.tv_usec)); age = crm_compare_age(your_age); if(your_age.tv_sec == 0 && your_age.tv_usec == 0) { crm_log_xml_trace(vote->msg, "bad vote"); crm_write_blackbox(0, NULL); } if (crm_str_eq(vote_from, fsa_our_uname, TRUE)) { char *op_copy = strdup(op); char *uname_copy = strdup(vote_from); CRM_ASSERT(crm_str_eq(fsa_our_uuid, election_owner, TRUE)); /* update ourselves in the list of nodes that have voted */ g_hash_table_replace(voted, uname_copy, op_copy); reason = "Recorded"; done = TRUE; } else if (compare_version(your_version, CRM_FEATURE_SET) < 0) { reason = "Version"; we_loose = TRUE; } else if (compare_version(your_version, CRM_FEATURE_SET) > 0) { reason = "Version"; } else if (age < 0) { reason = "Uptime"; we_loose = TRUE; } else if (age > 0) { reason = "Uptime"; /* TODO: Check for y(our) born < 0 */ } else if (use_born_on && your_node->born < our_node->born) { reason = "Born"; we_loose = TRUE; } else if (use_born_on && your_node->born > our_node->born) { reason = "Born"; } else if (fsa_our_uname == NULL) { reason = "Unknown host name"; we_loose = TRUE; } else if (strcasecmp(fsa_our_uname, vote_from) > 0) { reason = "Host name"; we_loose = TRUE; } else { reason = "Host name"; CRM_ASSERT(strcasecmp(fsa_our_uname, vote_from) < 0); /* cant happen... * } else if(strcasecmp(fsa_our_uname, vote_from) == 0) { * */ } } if (expires < tm_now) { election_wins = 0; expires = tm_now + STORM_INTERVAL; } else if (done == FALSE && we_loose == FALSE) { int peers = 1 + g_hash_table_size(crm_peer_cache); /* If every node has to vote down every other node, thats N*(N-1) total elections * Allow some leway before _really_ complaining */ election_wins++; if (election_wins > (peers * peers)) { crm_warn("Election storm detected: %d elections in %d seconds", election_wins, STORM_INTERVAL); election_wins = 0; expires = tm_now + STORM_INTERVAL; crm_write_blackbox(0, NULL); } } if (done) { do_crm_log(log_level + 1, "Election %d (current: %d, owner: %s): Processed %s from %s (%s)", election_id, current_election_id, election_owner, op, vote_from, reason); } else if (we_loose) { xmlNode *novote = create_request(CRM_OP_NOVOTE, NULL, vote_from, CRM_SYSTEM_CRMD, CRM_SYSTEM_CRMD, NULL); do_crm_log(log_level, "Election %d (owner: %s) lost: %s from %s (%s)", election_id, election_owner, op, vote_from, reason); update_dc(NULL); crm_timer_stop(election_timeout); if (fsa_input_register & R_THE_DC) { crm_trace("Give up the DC to %s", vote_from); register_fsa_input(C_FSA_INTERNAL, I_RELEASE_DC, NULL); fsa_cib_conn->cmds->set_slave(fsa_cib_conn, cib_scope_local); } else if (cur_state != S_STARTING) { crm_trace("We werent the DC anyway"); register_fsa_input(C_FSA_INTERNAL, I_PENDING, NULL); } crm_xml_add(novote, F_CRM_ELECTION_OWNER, election_owner); crm_xml_add_int(novote, F_CRM_ELECTION_ID, election_id); send_cluster_message(crm_get_peer(0, vote_from), crm_msg_crmd, novote, TRUE); free_xml(novote); last_election_loss = tm_now; } else { do_crm_log(log_level, "Election %d (owner: %s) pass: %s from %s (%s)", election_id, election_owner, op, vote_from, reason); if (last_election_loss) { if (tm_now - last_election_loss < (time_t) loss_dampen) { crm_info("Election %d ignore: We already lost an election less than %ds ago (%s)", election_id, loss_dampen, ctime(&last_election_loss)); update_dc(NULL); return; } last_election_loss = 0; } register_fsa_input(C_FSA_INTERNAL, I_ELECTION, NULL); g_hash_table_destroy(voted); voted = NULL; } } /* A_ELECT_TIMER_START, A_ELECTION_TIMEOUT */ /* we won */ void do_election_timer_ctrl(long long action, enum crmd_fsa_cause cause, enum crmd_fsa_state cur_state, enum crmd_fsa_input current_input, fsa_data_t * msg_data) { } static void feature_update_callback(xmlNode * msg, int call_id, int rc, xmlNode * output, void *user_data) { if (rc != pcmk_ok) { fsa_data_t *msg_data = NULL; crm_notice("Update failed: %s (%d)", pcmk_strerror(rc), rc); register_fsa_error(C_FSA_INTERNAL, I_ERROR, NULL); } } /* A_DC_TAKEOVER */ void do_dc_takeover(long long action, enum crmd_fsa_cause cause, enum crmd_fsa_state cur_state, enum crmd_fsa_input current_input, fsa_data_t * msg_data) { int rc = pcmk_ok; xmlNode *cib = NULL; GListPtr gIter = NULL; const char *cluster_type = name_for_cluster_type(get_cluster_type()); crm_info("Taking over DC status for this partition"); set_bit(fsa_input_register, R_THE_DC); for (gIter = stonith_cleanup_list; gIter != NULL; gIter = gIter->next) { char *target = gIter->data; crm_node_t *target_node = crm_get_peer(0, target); const char *uuid = crm_peer_uuid(target_node); crm_notice("Marking %s, target of a previous stonith action, as clean", target); send_stonith_update(NULL, target, uuid); free(target); } g_list_free(stonith_cleanup_list); stonith_cleanup_list = NULL; #if SUPPORT_COROSYNC if (is_classic_ais_cluster()) { send_cluster_text(crm_class_quorum, NULL, TRUE, NULL, crm_msg_ais); } #endif if (voted != NULL) { crm_trace("Destroying voted hash"); g_hash_table_destroy(voted); voted = NULL; } set_bit(fsa_input_register, R_JOIN_OK); set_bit(fsa_input_register, R_INVOKE_PE); fsa_cib_conn->cmds->set_master(fsa_cib_conn, cib_scope_local); cib = create_xml_node(NULL, XML_TAG_CIB); crm_xml_add(cib, XML_ATTR_CRM_VERSION, CRM_FEATURE_SET); fsa_cib_update(XML_TAG_CIB, cib, cib_quorum_override, rc, NULL); fsa_register_cib_callback(rc, FALSE, NULL, feature_update_callback); update_attr_delegate(fsa_cib_conn, cib_none, XML_CIB_TAG_CRMCONFIG, NULL, NULL, NULL, NULL, "dc-version", VERSION "-" BUILD_VERSION, FALSE, NULL); update_attr_delegate(fsa_cib_conn, cib_none, XML_CIB_TAG_CRMCONFIG, NULL, NULL, NULL, NULL, "cluster-infrastructure", cluster_type, FALSE, NULL); mainloop_set_trigger(config_read); free_xml(cib); } /* A_DC_RELEASE */ void do_dc_release(long long action, enum crmd_fsa_cause cause, enum crmd_fsa_state cur_state, enum crmd_fsa_input current_input, fsa_data_t * msg_data) { if (action & A_DC_RELEASE) { crm_debug("Releasing the role of DC"); clear_bit(fsa_input_register, R_THE_DC); } else if (action & A_DC_RELEASED) { crm_info("DC role released"); #if 0 if (are there errors) { /* we cant stay up if not healthy */ /* or perhaps I_ERROR and go to S_RECOVER? */ result = I_SHUTDOWN; } #endif register_fsa_input(C_FSA_INTERNAL, I_RELEASE_SUCCESS, NULL); } else { crm_err("Unknown action %s", fsa_action2string(action)); } crm_trace("Am I still the DC? %s", AM_I_DC ? XML_BOOLEAN_YES : XML_BOOLEAN_NO); } pacemaker-master/crmd/fsa.c000066400000000000000000000647141217637305600161670ustar00rootroot00000000000000/* * Copyright (C) 2004 Andrew Beekhof * * 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 2 of the License, or (at your option) any later version. * * This software 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 library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include char *fsa_our_dc = NULL; cib_t *fsa_cib_conn = NULL; char *fsa_our_dc_version = NULL; char *fsa_our_uuid = NULL; char *fsa_our_uname = NULL; #if SUPPORT_HEARTBEAT ll_cluster_t *fsa_cluster_conn; #endif fsa_timer_t *wait_timer = NULL; /* How long to wait before retrying to connect to the cib/lrmd/ccm */ fsa_timer_t *recheck_timer = NULL; /* Periodically re-run the PE to account for time based rules/preferences */ fsa_timer_t *election_trigger = NULL; /* How long to wait at startup, or after an election, for the DC to make contact */ fsa_timer_t *election_timeout = NULL; /* How long to declare an election over - even if not everyone voted */ fsa_timer_t *transition_timer = NULL; /* How long to delay the start of a new transition with the expectation something else might happen too */ fsa_timer_t *integration_timer = NULL; fsa_timer_t *finalization_timer = NULL; fsa_timer_t *shutdown_escalation_timer = NULL; /* How long to wait for the DC to stop all resources and give us the all-clear to shut down */ volatile gboolean do_fsa_stall = FALSE; volatile long long fsa_input_register = 0; volatile long long fsa_actions = A_NOTHING; volatile enum crmd_fsa_state fsa_state = S_STARTING; extern uint highest_born_on; extern uint num_join_invites; extern void initialize_join(gboolean before); #define DOT_PREFIX "actions:trace: " #define do_dot_log(fmt, args...) crm_trace( fmt, ##args) long long do_state_transition(long long actions, enum crmd_fsa_state cur_state, enum crmd_fsa_state next_state, fsa_data_t * msg_data); void dump_rsc_info(void); void dump_rsc_info_callback(const xmlNode * msg, int call_id, int rc, xmlNode * output, void *user_data); void ghash_print_node(gpointer key, gpointer value, gpointer user_data); void s_crmd_fsa_actions(fsa_data_t * fsa_data); void log_fsa_input(fsa_data_t * stored_msg); void init_dotfile(void); void init_dotfile(void) { do_dot_log(DOT_PREFIX "digraph \"g\" {"); do_dot_log(DOT_PREFIX " size = \"30,30\""); do_dot_log(DOT_PREFIX " graph ["); do_dot_log(DOT_PREFIX " fontsize = \"12\""); do_dot_log(DOT_PREFIX " fontname = \"Times-Roman\""); do_dot_log(DOT_PREFIX " fontcolor = \"black\""); do_dot_log(DOT_PREFIX " bb = \"0,0,398.922306,478.927856\""); do_dot_log(DOT_PREFIX " color = \"black\""); do_dot_log(DOT_PREFIX " ]"); do_dot_log(DOT_PREFIX " node ["); do_dot_log(DOT_PREFIX " fontsize = \"12\""); do_dot_log(DOT_PREFIX " fontname = \"Times-Roman\""); do_dot_log(DOT_PREFIX " fontcolor = \"black\""); do_dot_log(DOT_PREFIX " shape = \"ellipse\""); do_dot_log(DOT_PREFIX " color = \"black\""); do_dot_log(DOT_PREFIX " ]"); do_dot_log(DOT_PREFIX " edge ["); do_dot_log(DOT_PREFIX " fontsize = \"12\""); do_dot_log(DOT_PREFIX " fontname = \"Times-Roman\""); do_dot_log(DOT_PREFIX " fontcolor = \"black\""); do_dot_log(DOT_PREFIX " color = \"black\""); do_dot_log(DOT_PREFIX " ]"); do_dot_log(DOT_PREFIX "// special nodes"); do_dot_log(DOT_PREFIX " \"S_PENDING\" "); do_dot_log(DOT_PREFIX " ["); do_dot_log(DOT_PREFIX " color = \"blue\""); do_dot_log(DOT_PREFIX " fontcolor = \"blue\""); do_dot_log(DOT_PREFIX " ]"); do_dot_log(DOT_PREFIX " \"S_TERMINATE\" "); do_dot_log(DOT_PREFIX " ["); do_dot_log(DOT_PREFIX " color = \"red\""); do_dot_log(DOT_PREFIX " fontcolor = \"red\""); do_dot_log(DOT_PREFIX " ]"); do_dot_log(DOT_PREFIX "// DC only nodes"); do_dot_log(DOT_PREFIX " \"S_INTEGRATION\" [ fontcolor = \"green\" ]"); do_dot_log(DOT_PREFIX " \"S_POLICY_ENGINE\" [ fontcolor = \"green\" ]"); do_dot_log(DOT_PREFIX " \"S_TRANSITION_ENGINE\" [ fontcolor = \"green\" ]"); do_dot_log(DOT_PREFIX " \"S_RELEASE_DC\" [ fontcolor = \"green\" ]"); do_dot_log(DOT_PREFIX " \"S_IDLE\" [ fontcolor = \"green\" ]"); } static void do_fsa_action(fsa_data_t * fsa_data, long long an_action, void (*function) (long long action, enum crmd_fsa_cause cause, enum crmd_fsa_state cur_state, enum crmd_fsa_input cur_input, fsa_data_t * msg_data)) { fsa_actions &= ~an_action; crm_trace(DOT_PREFIX "\t// %s", fsa_action2string(an_action)); function(an_action, fsa_data->fsa_cause, fsa_state, fsa_data->fsa_input, fsa_data); } static long long startup_actions = A_STARTUP | A_CIB_START | A_LRM_CONNECT | A_CCM_CONNECT | A_HA_CONNECT | A_READCONFIG | A_STARTED | A_CL_JOIN_QUERY; enum crmd_fsa_state s_crmd_fsa(enum crmd_fsa_cause cause) { fsa_data_t *fsa_data = NULL; long long register_copy = fsa_input_register; long long new_actions = A_NOTHING; enum crmd_fsa_state last_state = fsa_state; crm_trace("FSA invoked with Cause: %s\tState: %s", fsa_cause2string(cause), fsa_state2string(fsa_state)); fsa_dump_actions(fsa_actions, "Initial"); do_fsa_stall = FALSE; if (is_message() == FALSE && fsa_actions != A_NOTHING) { /* fake the first message so we can get into the loop */ fsa_data = calloc(1, sizeof(fsa_data_t)); fsa_data->fsa_input = I_NULL; fsa_data->fsa_cause = C_FSA_INTERNAL; fsa_data->origin = __FUNCTION__; fsa_data->data_type = fsa_dt_none; fsa_message_queue = g_list_append(fsa_message_queue, fsa_data); fsa_data = NULL; } while (is_message() && do_fsa_stall == FALSE) { crm_trace("Checking messages (%d remaining)", g_list_length(fsa_message_queue)); fsa_data = get_message(); CRM_CHECK(fsa_data != NULL, continue); log_fsa_input(fsa_data); /* add any actions back to the queue */ fsa_actions |= fsa_data->actions; fsa_dump_actions(fsa_data->actions, "Restored actions"); /* get the next batch of actions */ new_actions = crmd_fsa_actions[fsa_data->fsa_input][fsa_state]; fsa_actions |= new_actions; fsa_dump_actions(new_actions, "New actions"); if (fsa_data->fsa_input != I_NULL && fsa_data->fsa_input != I_ROUTER) { crm_debug("Processing %s: [ state=%s cause=%s origin=%s ]", fsa_input2string(fsa_data->fsa_input), fsa_state2string(fsa_state), fsa_cause2string(fsa_data->fsa_cause), fsa_data->origin); } /* logging : *before* the state is changed */ if (is_set(fsa_actions, A_ERROR)) { do_fsa_action(fsa_data, A_ERROR, do_log); } if (is_set(fsa_actions, A_WARN)) { do_fsa_action(fsa_data, A_WARN, do_log); } if (is_set(fsa_actions, A_LOG)) { do_fsa_action(fsa_data, A_LOG, do_log); } /* update state variables */ last_state = fsa_state; fsa_state = crmd_fsa_state[fsa_data->fsa_input][fsa_state]; /* * Remove certain actions during shutdown */ if (fsa_state == S_STOPPING || ((fsa_input_register & R_SHUTDOWN) == R_SHUTDOWN)) { clear_bit(fsa_actions, startup_actions); } /* * Hook for change of state. * Allows actions to be added or removed when entering a state */ if (last_state != fsa_state) { fsa_actions = do_state_transition(fsa_actions, last_state, fsa_state, fsa_data); } else { do_dot_log(DOT_PREFIX "\t// FSA input: State=%s \tCause=%s" " \tInput=%s \tOrigin=%s() \tid=%d", fsa_state2string(fsa_state), fsa_cause2string(fsa_data->fsa_cause), fsa_input2string(fsa_data->fsa_input), fsa_data->origin, fsa_data->id); } /* start doing things... */ s_crmd_fsa_actions(fsa_data); delete_fsa_input(fsa_data); fsa_data = NULL; } if (g_list_length(fsa_message_queue) > 0 || fsa_actions != A_NOTHING || do_fsa_stall) { crm_debug("Exiting the FSA: queue=%d, fsa_actions=0x%llx, stalled=%s", g_list_length(fsa_message_queue), fsa_actions, do_fsa_stall ? "true" : "false"); } else { crm_trace("Exiting the FSA"); } /* cleanup inputs? */ if (register_copy != fsa_input_register) { long long same = register_copy & fsa_input_register; fsa_dump_inputs(LOG_DEBUG, "Added", fsa_input_register ^ same); fsa_dump_inputs(LOG_DEBUG, "Removed", register_copy ^ same); } fsa_dump_actions(fsa_actions, "Remaining"); fsa_dump_queue(LOG_DEBUG); return fsa_state; } void s_crmd_fsa_actions(fsa_data_t * fsa_data) { /* * Process actions in order of priority but do only one * action at a time to avoid complicating the ordering. */ CRM_CHECK(fsa_data != NULL, return); while (fsa_actions != A_NOTHING && do_fsa_stall == FALSE) { /* regular action processing in order of action priority * * Make sure all actions that connect to required systems * are performed first */ if (fsa_actions & A_ERROR) { do_fsa_action(fsa_data, A_ERROR, do_log); } else if (fsa_actions & A_WARN) { do_fsa_action(fsa_data, A_WARN, do_log); } else if (fsa_actions & A_LOG) { do_fsa_action(fsa_data, A_LOG, do_log); /* get out of here NOW! before anything worse happens */ } else if (fsa_actions & A_EXIT_1) { do_fsa_action(fsa_data, A_EXIT_1, do_exit); /* sub-system restart */ } else if ((fsa_actions & O_LRM_RECONNECT) == O_LRM_RECONNECT) { do_fsa_action(fsa_data, O_LRM_RECONNECT, do_lrm_control); } else if ((fsa_actions & O_CIB_RESTART) == O_CIB_RESTART) { do_fsa_action(fsa_data, O_CIB_RESTART, do_cib_control); } else if ((fsa_actions & O_PE_RESTART) == O_PE_RESTART) { do_fsa_action(fsa_data, O_PE_RESTART, do_pe_control); } else if ((fsa_actions & O_TE_RESTART) == O_TE_RESTART) { do_fsa_action(fsa_data, O_TE_RESTART, do_te_control); /* essential start tasks */ } else if (fsa_actions & A_STARTUP) { do_fsa_action(fsa_data, A_STARTUP, do_startup); } else if (fsa_actions & A_CIB_START) { do_fsa_action(fsa_data, A_CIB_START, do_cib_control); } else if (fsa_actions & A_HA_CONNECT) { do_fsa_action(fsa_data, A_HA_CONNECT, do_ha_control); } else if (fsa_actions & A_READCONFIG) { do_fsa_action(fsa_data, A_READCONFIG, do_read_config); /* sub-system start/connect */ } else if (fsa_actions & A_LRM_CONNECT) { do_fsa_action(fsa_data, A_LRM_CONNECT, do_lrm_control); } else if (fsa_actions & A_CCM_CONNECT) { #if SUPPORT_HEARTBEAT if (is_heartbeat_cluster()) { do_fsa_action(fsa_data, A_CCM_CONNECT, do_ccm_control); } #endif fsa_actions &= ~A_CCM_CONNECT; } else if (fsa_actions & A_TE_START) { do_fsa_action(fsa_data, A_TE_START, do_te_control); } else if (fsa_actions & A_PE_START) { do_fsa_action(fsa_data, A_PE_START, do_pe_control); /* Timers */ /* else if(fsa_actions & O_DC_TIMER_RESTART) { do_fsa_action(fsa_data, O_DC_TIMER_RESTART, do_timer_control) */ ; } else if (fsa_actions & A_DC_TIMER_STOP) { do_fsa_action(fsa_data, A_DC_TIMER_STOP, do_timer_control); } else if (fsa_actions & A_INTEGRATE_TIMER_STOP) { do_fsa_action(fsa_data, A_INTEGRATE_TIMER_STOP, do_timer_control); } else if (fsa_actions & A_INTEGRATE_TIMER_START) { do_fsa_action(fsa_data, A_INTEGRATE_TIMER_START, do_timer_control); } else if (fsa_actions & A_FINALIZE_TIMER_STOP) { do_fsa_action(fsa_data, A_FINALIZE_TIMER_STOP, do_timer_control); } else if (fsa_actions & A_FINALIZE_TIMER_START) { do_fsa_action(fsa_data, A_FINALIZE_TIMER_START, do_timer_control); /* * Highest priority actions */ } else if (fsa_actions & A_MSG_ROUTE) { do_fsa_action(fsa_data, A_MSG_ROUTE, do_msg_route); } else if (fsa_actions & A_RECOVER) { do_fsa_action(fsa_data, A_RECOVER, do_recover); } else if (fsa_actions & A_CL_JOIN_RESULT) { do_fsa_action(fsa_data, A_CL_JOIN_RESULT, do_cl_join_finalize_respond); } else if (fsa_actions & A_CL_JOIN_REQUEST) { do_fsa_action(fsa_data, A_CL_JOIN_REQUEST, do_cl_join_offer_respond); } else if (fsa_actions & A_SHUTDOWN_REQ) { do_fsa_action(fsa_data, A_SHUTDOWN_REQ, do_shutdown_req); } else if (fsa_actions & A_ELECTION_VOTE) { do_fsa_action(fsa_data, A_ELECTION_VOTE, do_election_vote); } else if (fsa_actions & A_ELECTION_COUNT) { do_fsa_action(fsa_data, A_ELECTION_COUNT, do_election_count_vote); } else if (fsa_actions & A_LRM_EVENT) { do_fsa_action(fsa_data, A_LRM_EVENT, do_lrm_event); /* * High priority actions */ } else if (fsa_actions & A_STARTED) { do_fsa_action(fsa_data, A_STARTED, do_started); } else if (fsa_actions & A_CL_JOIN_QUERY) { do_fsa_action(fsa_data, A_CL_JOIN_QUERY, do_cl_join_query); } else if (fsa_actions & A_DC_TIMER_START) { do_fsa_action(fsa_data, A_DC_TIMER_START, do_timer_control); /* * Medium priority actions * - Membership */ } else if (fsa_actions & A_DC_TAKEOVER) { do_fsa_action(fsa_data, A_DC_TAKEOVER, do_dc_takeover); } else if (fsa_actions & A_DC_RELEASE) { do_fsa_action(fsa_data, A_DC_RELEASE, do_dc_release); } else if (fsa_actions & A_DC_JOIN_FINAL) { do_fsa_action(fsa_data, A_DC_JOIN_FINAL, do_dc_join_final); } else if (fsa_actions & A_ELECTION_CHECK) { do_fsa_action(fsa_data, A_ELECTION_CHECK, do_election_check); } else if (fsa_actions & A_ELECTION_START) { do_fsa_action(fsa_data, A_ELECTION_START, do_election_vote); } else if (fsa_actions & A_DC_JOIN_OFFER_ALL) { do_fsa_action(fsa_data, A_DC_JOIN_OFFER_ALL, do_dc_join_offer_all); } else if (fsa_actions & A_DC_JOIN_OFFER_ONE) { do_fsa_action(fsa_data, A_DC_JOIN_OFFER_ONE, do_dc_join_offer_one); } else if (fsa_actions & A_DC_JOIN_PROCESS_REQ) { do_fsa_action(fsa_data, A_DC_JOIN_PROCESS_REQ, do_dc_join_filter_offer); } else if (fsa_actions & A_DC_JOIN_PROCESS_ACK) { do_fsa_action(fsa_data, A_DC_JOIN_PROCESS_ACK, do_dc_join_ack); } else if (fsa_actions & A_DC_JOIN_FINALIZE) { do_fsa_action(fsa_data, A_DC_JOIN_FINALIZE, do_dc_join_finalize); } else if (fsa_actions & A_CL_JOIN_ANNOUNCE) { do_fsa_action(fsa_data, A_CL_JOIN_ANNOUNCE, do_cl_join_announce); /* * Low(er) priority actions * Make sure the CIB is always updated before invoking the * PE, and the PE before the TE */ } else if (fsa_actions & A_TE_HALT) { do_fsa_action(fsa_data, A_TE_HALT, do_te_invoke); } else if (fsa_actions & A_TE_CANCEL) { do_fsa_action(fsa_data, A_TE_CANCEL, do_te_invoke); } else if (fsa_actions & A_LRM_INVOKE) { do_fsa_action(fsa_data, A_LRM_INVOKE, do_lrm_invoke); } else if (fsa_actions & A_PE_INVOKE) { do_fsa_action(fsa_data, A_PE_INVOKE, do_pe_invoke); } else if (fsa_actions & A_TE_INVOKE) { do_fsa_action(fsa_data, A_TE_INVOKE, do_te_invoke); /* Shutdown actions */ } else if (fsa_actions & A_DC_RELEASED) { do_fsa_action(fsa_data, A_DC_RELEASED, do_dc_release); } else if (fsa_actions & A_PE_STOP) { do_fsa_action(fsa_data, A_PE_STOP, do_pe_control); } else if (fsa_actions & A_TE_STOP) { do_fsa_action(fsa_data, A_TE_STOP, do_te_control); } else if (fsa_actions & A_SHUTDOWN) { do_fsa_action(fsa_data, A_SHUTDOWN, do_shutdown); } else if (fsa_actions & A_LRM_DISCONNECT) { do_fsa_action(fsa_data, A_LRM_DISCONNECT, do_lrm_control); } else if (fsa_actions & A_CCM_DISCONNECT) { #if SUPPORT_HEARTBEAT if (is_heartbeat_cluster()) { do_fsa_action(fsa_data, A_CCM_DISCONNECT, do_ccm_control); } #endif fsa_actions &= ~A_CCM_DISCONNECT; } else if (fsa_actions & A_HA_DISCONNECT) { do_fsa_action(fsa_data, A_HA_DISCONNECT, do_ha_control); } else if (fsa_actions & A_CIB_STOP) { do_fsa_action(fsa_data, A_CIB_STOP, do_cib_control); } else if (fsa_actions & A_STOP) { do_fsa_action(fsa_data, A_STOP, do_stop); /* exit gracefully */ } else if (fsa_actions & A_EXIT_0) { do_fsa_action(fsa_data, A_EXIT_0, do_exit); /* Error checking and reporting */ } else { crm_err("Action %s (0x%llx) not supported ", fsa_action2string(fsa_actions), fsa_actions); register_fsa_error_adv(C_FSA_INTERNAL, I_ERROR, fsa_data, NULL, __FUNCTION__); } } } void log_fsa_input(fsa_data_t * stored_msg) { crm_trace("Processing queued input %d", stored_msg->id); if (stored_msg->fsa_cause == C_CCM_CALLBACK) { crm_trace("FSA processing CCM callback from %s", stored_msg->origin); } else if (stored_msg->fsa_cause == C_LRM_OP_CALLBACK) { crm_trace("FSA processing LRM callback from %s", stored_msg->origin); } else if (stored_msg->data == NULL) { crm_trace("FSA processing input from %s", stored_msg->origin); } else { ha_msg_input_t *ha_input = fsa_typed_data_adv(stored_msg, fsa_dt_ha_msg, __FUNCTION__); crm_trace("FSA processing XML message from %s", stored_msg->origin); crm_log_xml_trace(ha_input->xml, "FSA message data"); } } long long do_state_transition(long long actions, enum crmd_fsa_state cur_state, enum crmd_fsa_state next_state, fsa_data_t * msg_data) { int level = LOG_INFO; long long tmp = actions; gboolean clear_recovery_bit = TRUE; enum crmd_fsa_cause cause = msg_data->fsa_cause; enum crmd_fsa_input current_input = msg_data->fsa_input; const char *state_from = fsa_state2string(cur_state); const char *state_to = fsa_state2string(next_state); const char *input = fsa_input2string(current_input); CRM_LOG_ASSERT(cur_state != next_state); do_dot_log(DOT_PREFIX "\t%s -> %s [ label=%s cause=%s origin=%s ]", state_from, state_to, input, fsa_cause2string(cause), msg_data->origin); if (cur_state == S_IDLE || next_state == S_IDLE) { level = LOG_NOTICE; } else if (cur_state == S_NOT_DC || next_state == S_NOT_DC) { level = LOG_NOTICE; } else if (cur_state == S_ELECTION) { level = LOG_NOTICE; } else if (cur_state == S_STARTING) { level = LOG_NOTICE; } else if (next_state == S_RECOVERY) { level = LOG_WARNING; } do_crm_log(level, "State transition %s -> %s [ input=%s cause=%s origin=%s ]", state_from, state_to, input, fsa_cause2string(cause), msg_data->origin); /* the last two clauses might cause trouble later */ if (election_timeout != NULL && next_state != S_ELECTION && cur_state != S_RELEASE_DC) { crm_timer_stop(election_timeout); /* } else { */ /* crm_timer_start(election_timeout); */ } #if 0 if ((fsa_input_register & R_SHUTDOWN)) { set_bit(tmp, A_DC_TIMER_STOP); } #endif if (next_state == S_INTEGRATION) { set_bit(tmp, A_INTEGRATE_TIMER_START); } else { set_bit(tmp, A_INTEGRATE_TIMER_STOP); } if (next_state == S_FINALIZE_JOIN) { set_bit(tmp, A_FINALIZE_TIMER_START); } else { set_bit(tmp, A_FINALIZE_TIMER_STOP); } if (next_state != S_PENDING) { set_bit(tmp, A_DC_TIMER_STOP); } if (next_state != S_ELECTION) { highest_born_on = 0; } if (next_state != S_IDLE) { crm_timer_stop(recheck_timer); } if (cur_state == S_FINALIZE_JOIN && next_state == S_POLICY_ENGINE) { populate_cib_nodes(node_update_quick | node_update_cluster | node_update_peer | node_update_join | node_update_expected, __FUNCTION__); } switch (next_state) { case S_PENDING: fsa_cib_conn->cmds->set_slave(fsa_cib_conn, cib_scope_local); /* fall through */ case S_ELECTION: crm_trace("Resetting our DC to NULL on transition to %s", fsa_state2string(next_state)); update_dc(NULL); break; case S_NOT_DC: election_trigger->counter = 0; if (stonith_cleanup_list) { GListPtr gIter = NULL; for (gIter = stonith_cleanup_list; gIter != NULL; gIter = gIter->next) { char *target = gIter->data; crm_info("Purging %s from stonith cleanup list", target); free(target); } g_list_free(stonith_cleanup_list); stonith_cleanup_list = NULL; } if (is_set(fsa_input_register, R_SHUTDOWN)) { crm_info("(Re)Issuing shutdown request now" " that we have a new DC"); set_bit(tmp, A_SHUTDOWN_REQ); } CRM_LOG_ASSERT(fsa_our_dc != NULL); if (fsa_our_dc == NULL) { crm_err("Reached S_NOT_DC without a DC" " being recorded"); } break; case S_RECOVERY: clear_recovery_bit = FALSE; break; case S_FINALIZE_JOIN: CRM_LOG_ASSERT(AM_I_DC); if (cause == C_TIMER_POPPED) { crm_warn("Progressed to state %s after %s", fsa_state2string(next_state), fsa_cause2string(cause)); } if (crmd_join_phase_count(crm_join_welcomed) > 0) { crm_warn("%u cluster nodes failed to respond" " to the join offer.", crmd_join_phase_count(crm_join_welcomed)); crmd_join_phase_log(LOG_NOTICE); } else { crm_debug("All %d cluster nodes responded to the join offer.", crmd_join_phase_count(crm_join_integrated)); } break; case S_POLICY_ENGINE: election_trigger->counter = 0; CRM_LOG_ASSERT(AM_I_DC); if (cause == C_TIMER_POPPED) { crm_info("Progressed to state %s after %s", fsa_state2string(next_state), fsa_cause2string(cause)); } if (crmd_join_phase_count(crm_join_finalized) > 0) { crm_err("%u cluster nodes failed to confirm their join.", crmd_join_phase_count(crm_join_finalized)); crmd_join_phase_log(LOG_NOTICE); } else if (crmd_join_phase_count(crm_join_confirmed) == crm_active_peers()) { crm_debug("All %u cluster nodes are" " eligible to run resources.", crm_active_peers()); } else if (crmd_join_phase_count(crm_join_confirmed) > crm_active_peers()) { crm_err("We have more confirmed nodes than our membership does: %d vs. %d", crmd_join_phase_count(crm_join_confirmed), crm_active_peers()); register_fsa_input(C_FSA_INTERNAL, I_ELECTION, NULL); } else if (saved_ccm_membership_id != crm_peer_seq) { crm_info("Membership changed: %llu -> %llu - join restart", saved_ccm_membership_id, crm_peer_seq); register_fsa_input_before(C_FSA_INTERNAL, I_NODE_JOIN, NULL); } else { crm_warn("Only %u of %u cluster " "nodes are eligible to run resources - continue %d", crmd_join_phase_count(crm_join_confirmed), crm_active_peers(), crmd_join_phase_count(crm_join_welcomed)); } /* initialize_join(FALSE); */ break; case S_STOPPING: case S_TERMINATE: /* possibly redundant */ set_bit(fsa_input_register, R_SHUTDOWN); break; case S_IDLE: CRM_LOG_ASSERT(AM_I_DC); dump_rsc_info(); if (is_set(fsa_input_register, R_SHUTDOWN)) { crm_info("(Re)Issuing shutdown request now" " that we are the DC"); set_bit(tmp, A_SHUTDOWN_REQ); } if (recheck_timer->period_ms > 0) { crm_debug("Starting %s", get_timer_desc(recheck_timer)); crm_timer_start(recheck_timer); } break; default: break; } if (clear_recovery_bit && next_state != S_PENDING) { tmp &= ~A_RECOVER; } else if (clear_recovery_bit == FALSE) { tmp |= A_RECOVER; } if (tmp != actions) { /* fsa_dump_actions(actions ^ tmp, "New actions"); */ actions = tmp; } return actions; } void dump_rsc_info(void) { } void ghash_print_node(gpointer key, gpointer value, gpointer user_data) { const char *text = user_data; const char *uname = key; const char *value_s = value; crm_info("%s: %s %s", text, uname, value_s); } pacemaker-master/crmd/fsa_defines.h000066400000000000000000000525431217637305600176660ustar00rootroot00000000000000/* * Copyright (C) 2004 Andrew Beekhof * * 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 2 of the License, or (at your option) any later version. * * This software 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 library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef FSA_DEFINES__H # define FSA_DEFINES__H /*====================================== * States the DC/CRMd can be in *======================================*/ enum crmd_fsa_state { S_IDLE = 0, /* Nothing happening */ S_ELECTION, /* Take part in the election algorithm as * described below */ S_INTEGRATION, /* integrate that status of new nodes (which is * all of them if we have just been elected DC) * to form a complete and up-to-date picture of * the CIB */ S_FINALIZE_JOIN, /* integrate that status of new nodes (which is * all of them if we have just been elected DC) * to form a complete and up-to-date picture of * the CIB */ S_NOT_DC, /* we are in crmd/slave mode */ S_POLICY_ENGINE, /* Determin the next stable state of the cluster */ S_RECOVERY, /* Something bad happened, check everything is ok * before continuing and attempt to recover if * required */ S_RELEASE_DC, /* we were the DC, but now we arent anymore, * possibly by our own request, and we should * release all unnecessary sub-systems, finish * any pending actions, do general cleanup and * unset anything that makes us think we are * special :) */ S_STARTING, /* we are just starting out */ S_PENDING, /* we are not a full/active member yet */ S_STOPPING, /* We are in the final stages of shutting down */ S_TERMINATE, /* We are going to shutdown, this is the equiv of * "Sending TERM signal to all processes" in Linux * and in worst case scenarios could be considered * a self STONITH */ S_TRANSITION_ENGINE, /* Attempt to make the calculated next stable * state of the cluster a reality */ S_HALT, /* Freeze - dont do anything * Something ad happened that needs the admin to fix * Wait for I_ELECTION */ /* ----------- Last input found in table is above ---------- */ S_ILLEGAL /* This is an illegal FSA state */ /* (must be last) */ }; # define MAXSTATE S_ILLEGAL /* A state diagram can be constructed from the dc_fsa.dot with the following command: dot -Tpng crmd_fsa.dot > crmd_fsa.png Description: Once we start and do some basic sanity checks, we go into the S_NOT_DC state and await instructions from the DC or input from the CCM which indicates the election algorithm needs to run. If the election algorithm is triggered we enter the S_ELECTION state from where we can either go back to the S_NOT_DC state or progress to the S_INTEGRATION state (or S_RELEASE_DC if we used to be the DC but arent anymore). The election algorithm has been adapted from http://www.cs.indiana.edu/cgi-bin/techreports/TRNNN.cgi?trnum=TR521 Loosly known as the Bully Algorithm, its major points are: - Election is initiated by any node (N) notices that the coordinator is no longer responding - Concurrent multiple elections are possible - Algorithm + N sends ELECTION messages to all nodes that occur earlier in the CCM's membership list. + If no one responds, N wins and becomes coordinator + N sends out COORDINATOR messages to all other nodes in the partition + If one of higher-ups answers, it takes over. N is done. Once the election is complete, if we are the DC, we enter the S_INTEGRATION state which is a DC-in-waiting style state. We are the DC, but we shouldnt do anything yet because we may not have an up-to-date picture of the cluster. There may of course be times when this fails, so we should go back to the S_RECOVERY stage and check everything is ok. We may also end up here if a new node came online, since each node is authorative on itself and we would want to incorporate its information into the CIB. Once we have the latest CIB, we then enter the S_POLICY_ENGINE state where invoke the Policy Engine. It is possible that between invoking the Policy Engine and recieving an answer, that we recieve more input. In this case we would discard the orginal result and invoke it again. Once we are satisfied with the output from the Policy Engine we enter S_TRANSITION_ENGINE and feed the Policy Engine's output to the Transition Engine who attempts to make the Policy Engine's calculation a reality. If the transition completes successfully, we enter S_IDLE, otherwise we go back to S_POLICY_ENGINE with the current unstable state and try again. Of course we may be asked to shutdown at any time, however we must progress to S_NOT_DC before doing so. Once we have handed over DC duties to another node, we can then shut down like everyone else, that is by asking the DC for permission and waiting it to take all our resources away. The case where we are the DC and the only node in the cluster is a special case and handled as an escalation which takes us to S_SHUTDOWN. Similarly if any other point in the shutdown fails or stalls, this is escalated and we end up in S_TERMINATE. At any point, the CRMd/DC can relay messages for its sub-systems, but outbound messages (from sub-systems) should probably be blocked until S_INTEGRATION (for the DC case) or the join protocol has completed (for the CRMd case) */ /*====================================== * * Inputs/Events/Stimuli to be given to the finite state machine * * Some of these a true events, and others a synthesised based on * the "register" (see below) and the contents or source of messages. * * At this point, my plan is to have a loop of some sort that keeps * going until recieving I_NULL * *======================================*/ enum crmd_fsa_input { /* 0 */ I_NULL, /* Nothing happened */ /* 1 */ I_CIB_OP, /* An update to the CIB occurred */ I_CIB_UPDATE, /* An update to the CIB occurred */ I_DC_TIMEOUT, /* We have lost communication with the DC */ I_ELECTION, /* Someone started an election */ I_PE_CALC, /* The Policy Engine needs to be invoked */ I_RELEASE_DC, /* The election completed and we were not * elected, but we were the DC beforehand */ I_ELECTION_DC, /* The election completed and we were (re-)elected * DC */ I_ERROR, /* Something bad happened (more serious than * I_FAIL) and may not have been due to the action * being performed. For example, we may have lost * our connection to the CIB. */ /* 9 */ I_FAIL, /* The action failed to complete successfully */ I_INTEGRATED, I_FINALIZED, I_NODE_JOIN, /* A node has entered the cluster */ I_NOT_DC, /* We are not and were not the DC before or after * the current operation or state */ I_RECOVERED, /* The recovery process completed successfully */ I_RELEASE_FAIL, /* We could not give up DC status for some reason */ I_RELEASE_SUCCESS, /* We are no longer the DC */ I_RESTART, /* The current set of actions needs to be * restarted */ I_TE_SUCCESS, /* Some non-resource, non-ccm action is required * of us, eg. ping */ /* 20 */ I_ROUTER, /* Do our job as router and forward this to the * right place */ I_SHUTDOWN, /* We are asking to shutdown */ I_STOP, /* We have been told to shutdown */ I_TERMINATE, /* Actually exit */ I_STARTUP, I_PE_SUCCESS, /* The action completed successfully */ I_JOIN_OFFER, /* The DC is offering membership */ I_JOIN_REQUEST, /* The client is requesting membership */ I_JOIN_RESULT, /* If not the DC: The result of a join request * Else: A client is responding with its local state info */ I_WAIT_FOR_EVENT, /* we may be waiting for an async task to "happen" * and until it does, we cant do anything else */ I_DC_HEARTBEAT, /* The DC is telling us that it is alive and well */ I_LRM_EVENT, /* 30 */ I_PENDING, I_HALT, /* ------------ Last input found in table is above ----------- */ I_ILLEGAL /* This is an illegal value for an FSA input */ /* (must be last) */ }; # define MAXINPUT I_ILLEGAL # define I_MESSAGE I_ROUTER /*====================================== * * actions * * Some of the actions below will always occur together for now, but I can * forsee that this may not always be the case. So I've spilt them up so * that if they ever do need to be called independantly in the future, it * wont be a problem. * * For example, separating A_LRM_CONNECT from A_STARTUP might be useful * if we ever try to recover from a faulty or disconnected LRM. * *======================================*/ /* Dont do anything */ # define A_NOTHING 0x0000000000000000ULL /* -- Startup actions -- */ /* Hook to perform any actions (other than starting the CIB, * connecting to HA or the CCM) that might be needed as part * of the startup. */ # define A_STARTUP 0x0000000000000001ULL /* Hook to perform any actions that might be needed as part * after startup is successful. */ # define A_STARTED 0x0000000000000002ULL /* Connect to Heartbeat */ # define A_HA_CONNECT 0x0000000000000004ULL # define A_HA_DISCONNECT 0x0000000000000008ULL # define A_INTEGRATE_TIMER_START 0x0000000000000010ULL # define A_INTEGRATE_TIMER_STOP 0x0000000000000020ULL # define A_FINALIZE_TIMER_START 0x0000000000000040ULL # define A_FINALIZE_TIMER_STOP 0x0000000000000080ULL /* -- Election actions -- */ # define A_DC_TIMER_START 0x0000000000000100ULL # define A_DC_TIMER_STOP 0x0000000000000200ULL # define A_ELECTION_COUNT 0x0000000000000400ULL # define A_ELECTION_VOTE 0x0000000000000800ULL # define A_ELECTION_START 0x0000000000001000ULL /* -- Message processing -- */ /* Process the queue of requests */ # define A_MSG_PROCESS 0x0000000000002000ULL /* Send the message to the correct recipient */ # define A_MSG_ROUTE 0x0000000000004000ULL /* Send a welcome message to new node(s) */ # define A_DC_JOIN_OFFER_ONE 0x0000000000008000ULL /* -- Server Join protocol actions -- */ /* Send a welcome message to all nodes */ # define A_DC_JOIN_OFFER_ALL 0x0000000000010000ULL /* Process the remote node's ack of our join message */ # define A_DC_JOIN_PROCESS_REQ 0x0000000000020000ULL /* Send out the reults of the Join phase */ # define A_DC_JOIN_FINALIZE 0x0000000000040000ULL /* Send out the reults of the Join phase */ # define A_DC_JOIN_PROCESS_ACK 0x0000000000080000ULL /* -- Client Join protocol actions -- */ # define A_CL_JOIN_QUERY 0x0000000000100000ULL # define A_CL_JOIN_ANNOUNCE 0x0000000000200000ULL /* Request membership to the DC list */ # define A_CL_JOIN_REQUEST 0x0000000000400000ULL /* Did the DC accept or reject the request */ # define A_CL_JOIN_RESULT 0x0000000000800000ULL /* -- Recovery, DC start/stop -- */ /* Something bad happened, try to recover */ # define A_RECOVER 0x0000000001000000ULL /* Hook to perform any actions (apart from starting, the TE, PE * and gathering the latest CIB) that might be necessary before * giving up the responsibilities of being the DC. */ # define A_DC_RELEASE 0x0000000002000000ULL /* */ # define A_DC_RELEASED 0x0000000004000000ULL /* Hook to perform any actions (apart from starting, the TE, PE * and gathering the latest CIB) that might be necessary before * taking over the responsibilities of being the DC. */ # define A_DC_TAKEOVER 0x0000000008000000ULL /* -- Shutdown actions -- */ # define A_SHUTDOWN 0x0000000010000000ULL # define A_STOP 0x0000000020000000ULL # define A_EXIT_0 0x0000000040000000ULL # define A_EXIT_1 0x0000000080000000ULL # define A_SHUTDOWN_REQ 0x0000000100000000ULL # define A_ELECTION_CHECK 0x0000000200000000ULL # define A_DC_JOIN_FINAL 0x0000000400000000ULL /* -- CCM actions -- */ # define A_CCM_CONNECT 0x0000001000000000ULL # define A_CCM_DISCONNECT 0x0000002000000000ULL /* -- CIB actions -- */ # define A_CIB_START 0x0000020000000000ULL # define A_CIB_STOP 0x0000040000000000ULL /* -- Transition Engine actions -- */ /* Attempt to reach the newly calculated cluster state. This is * only called once per transition (except if it is asked to * stop the transition or start a new one). * Once given a cluster state to reach, the TE will determin * tasks that can be performed in parallel, execute them, wait * for replies and then determin the next set until the new * state is reached or no further tasks can be taken. */ # define A_TE_INVOKE 0x0000100000000000ULL # define A_TE_START 0x0000200000000000ULL # define A_TE_STOP 0x0000400000000000ULL # define A_TE_CANCEL 0x0000800000000000ULL # define A_TE_HALT 0x0001000000000000ULL /* -- Policy Engine actions -- */ /* Calculate the next state for the cluster. This is only * invoked once per needed calculation. */ # define A_PE_INVOKE 0x0002000000000000ULL # define A_PE_START 0x0004000000000000ULL # define A_PE_STOP 0x0008000000000000ULL /* -- Misc actions -- */ /* Add a system generate "block" so that resources arent moved * to or are activly moved away from the affected node. This * way we can return quickly even if busy with other things. */ # define A_NODE_BLOCK 0x0010000000000000ULL /* Update our information in the local CIB */ # define A_UPDATE_NODESTATUS 0x0020000000000000ULL # define A_CIB_BUMPGEN 0x0040000000000000ULL # define A_READCONFIG 0x0080000000000000ULL /* -- LRM Actions -- */ /* Connect to the Local Resource Manager */ # define A_LRM_CONNECT 0x0100000000000000ULL /* Disconnect from the Local Resource Manager */ # define A_LRM_DISCONNECT 0x0200000000000000ULL # define A_LRM_INVOKE 0x0400000000000000ULL # define A_LRM_EVENT 0x0800000000000000ULL /* -- Logging actions -- */ # define A_LOG 0x1000000000000000ULL # define A_ERROR 0x2000000000000000ULL # define A_WARN 0x4000000000000000ULL # define O_EXIT (A_SHUTDOWN|A_STOP|A_CCM_DISCONNECT|A_LRM_DISCONNECT|A_HA_DISCONNECT|A_EXIT_0|A_CIB_STOP) # define O_RELEASE (A_DC_TIMER_STOP|A_DC_RELEASE|A_PE_STOP|A_TE_STOP|A_DC_RELEASED) # define O_PE_RESTART (A_PE_START|A_PE_STOP) # define O_TE_RESTART (A_TE_START|A_TE_STOP) # define O_CIB_RESTART (A_CIB_START|A_CIB_STOP) # define O_LRM_RECONNECT (A_LRM_CONNECT|A_LRM_DISCONNECT) # define O_DC_TIMER_RESTART (A_DC_TIMER_STOP|A_DC_TIMER_START) /*====================================== * * "register" contents * * Things we may want to remember regardless of which state we are in. * * These also count as inputs for synthesizing I_* * *======================================*/ # define R_THE_DC 0x00000001ULL /* Are we the DC? */ # define R_STARTING 0x00000002ULL /* Are we starting up? */ # define R_SHUTDOWN 0x00000004ULL /* Are we trying to shut down? */ # define R_STAYDOWN 0x00000008ULL /* Should we restart? */ # define R_JOIN_OK 0x00000010ULL /* Have we completed the join process */ # define R_READ_CONFIG 0x00000040ULL # define R_INVOKE_PE 0x00000080ULL /* Does the PE needed to be invoked at the next appropriate point? */ # define R_CIB_CONNECTED 0x00000100ULL /* Is the CIB connected? */ # define R_PE_CONNECTED 0x00000200ULL /* Is the Policy Engine connected? */ # define R_TE_CONNECTED 0x00000400ULL /* Is the Transition Engine connected? */ # define R_LRM_CONNECTED 0x00000800ULL /* Is the Local Resource Manager connected? */ # define R_CIB_REQUIRED 0x00001000ULL /* Is the CIB required? */ # define R_PE_REQUIRED 0x00002000ULL /* Is the Policy Engine required? */ # define R_TE_REQUIRED 0x00004000ULL /* Is the Transition Engine required? */ # define R_ST_REQUIRED 0x00008000ULL /* Is the Stonith daemon required? */ # define R_CIB_DONE 0x00010000ULL /* Have we calculated the CIB? */ # define R_HAVE_CIB 0x00020000ULL /* Do we have an up-to-date CIB */ # define R_CIB_ASKED 0x00040000ULL /* Have we asked for an up-to-date CIB */ # define R_MEMBERSHIP 0x00100000ULL /* Have we got CCM data yet */ # define R_PEER_DATA 0x00200000ULL /* Have we got T_CL_STATUS data yet */ # define R_HA_DISCONNECTED 0x00400000ULL /* did we sign out of our own accord */ # define R_CCM_DISCONNECTED 0x00800000ULL /* did we sign out of our own accord */ # define R_REQ_PEND 0x01000000ULL /* Are there Requests waiting for processing? */ # define R_PE_PEND 0x02000000ULL /* Has the PE been invoked and we're awaiting a reply? */ # define R_TE_PEND 0x04000000ULL /* Has the TE been invoked and we're awaiting completion? */ # define R_RESP_PEND 0x08000000ULL /* Do we have clients waiting on a response? if so perhaps we shouldnt stop yet */ # define R_IN_TRANSITION 0x10000000ULL /* */ # define R_SENT_RSC_STOP 0x20000000ULL /* Have we sent a stop action to all * resources in preparation for * shutting down */ # define R_IN_RECOVERY 0x80000000ULL enum crmd_fsa_cause { C_UNKNOWN = 0, C_STARTUP, C_IPC_MESSAGE, C_HA_MESSAGE, C_CCM_CALLBACK, C_CRMD_STATUS_CALLBACK, C_LRM_OP_CALLBACK, C_LRM_MONITOR_CALLBACK, C_TIMER_POPPED, C_SHUTDOWN, C_HEARTBEAT_FAILED, C_SUBSYSTEM_CONNECT, C_HA_DISCONNECT, C_FSA_INTERNAL, C_ILLEGAL }; extern const char *fsa_input2string(enum crmd_fsa_input input); extern const char *fsa_state2string(enum crmd_fsa_state state); extern const char *fsa_cause2string(enum crmd_fsa_cause cause); extern const char *fsa_action2string(long long action); #endif pacemaker-master/crmd/fsa_matrix.h000066400000000000000000001414151217637305600175520ustar00rootroot00000000000000/* * Copyright (C) 2004 Andrew Beekhof * * 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 2 of the License, or (at your option) any later version. * * This software 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 library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef XML_FSA_MATRIX__H # define XML_FSA_MATRIX__H /* * The state transition table. The rows are inputs, and * the columns are states. */ const enum crmd_fsa_state crmd_fsa_state[MAXINPUT][MAXSTATE] = { /* Got an I_NULL */ { /* S_IDLE ==> */ S_IDLE, /* S_ELECTION ==> */ S_ELECTION, /* S_INTEGRATION ==> */ S_INTEGRATION, /* S_FINALIZE_JOIN ==> */ S_FINALIZE_JOIN, /* S_NOT_DC ==> */ S_NOT_DC, /* S_POLICY_ENGINE ==> */ S_POLICY_ENGINE, /* S_RECOVERY ==> */ S_RECOVERY, /* S_RELEASE_DC ==> */ S_RELEASE_DC, /* S_STARTING ==> */ S_STARTING, /* S_PENDING ==> */ S_PENDING, /* S_STOPPING ==> */ S_STOPPING, /* S_TERMINATE ==> */ S_TERMINATE, /* S_TRANSITION_ENGINE ==> */ S_TRANSITION_ENGINE, /* S_HALT ==> */ S_HALT, }, /* Got an I_CIB_OP */ { /* S_IDLE ==> */ S_IDLE, /* S_ELECTION ==> */ S_ELECTION, /* S_INTEGRATION ==> */ S_INTEGRATION, /* S_FINALIZE_JOIN ==> */ S_FINALIZE_JOIN, /* S_NOT_DC ==> */ S_NOT_DC, /* S_POLICY_ENGINE ==> */ S_POLICY_ENGINE, /* S_RECOVERY ==> */ S_RECOVERY, /* S_RELEASE_DC ==> */ S_RELEASE_DC, /* S_STARTING ==> */ S_STARTING, /* S_PENDING ==> */ S_PENDING, /* S_STOPPING ==> */ S_STOPPING, /* S_TERMINATE ==> */ S_TERMINATE, /* S_TRANSITION_ENGINE ==> */ S_TRANSITION_ENGINE, /* S_HALT ==> */ S_HALT, }, /* Got an I_CIB_UPDATE */ { /* S_IDLE ==> */ S_IDLE, /* S_ELECTION ==> */ S_ELECTION, /* S_INTEGRATION ==> */ S_INTEGRATION, /* S_FINALIZE_JOIN ==> */ S_FINALIZE_JOIN, /* S_NOT_DC ==> */ S_RECOVERY, /* S_POLICY_ENGINE ==> */ S_POLICY_ENGINE, /* S_RECOVERY ==> */ S_RECOVERY, /* S_RELEASE_DC ==> */ S_RELEASE_DC, /* S_STARTING ==> */ S_RECOVERY, /* S_PENDING ==> */ S_RECOVERY, /* S_STOPPING ==> */ S_STOPPING, /* S_TERMINATE ==> */ S_TERMINATE, /* S_TRANSITION_ENGINE ==> */ S_TRANSITION_ENGINE, /* S_HALT ==> */ S_HALT, }, /* Got an I_DC_TIMEOUT */ { /* S_IDLE ==> */ S_RECOVERY, /* S_ELECTION ==> */ S_ELECTION, /* S_INTEGRATION ==> */ S_RECOVERY, /* S_FINALIZE_JOIN ==> */ S_RECOVERY, /* S_NOT_DC ==> */ S_ELECTION, /* S_POLICY_ENGINE ==> */ S_RECOVERY, /* S_RECOVERY ==> */ S_RECOVERY, /* S_RELEASE_DC ==> */ S_RECOVERY, /* S_STARTING ==> */ S_STARTING, /* S_PENDING ==> */ S_ELECTION, /* S_STOPPING ==> */ S_STOPPING, /* S_TERMINATE ==> */ S_TERMINATE, /* S_TRANSITION_ENGINE ==> */ S_RECOVERY, /* S_HALT ==> */ S_ELECTION, }, /* Got an I_ELECTION */ { /* S_IDLE ==> */ S_ELECTION, /* S_ELECTION ==> */ S_ELECTION, /* S_INTEGRATION ==> */ S_ELECTION, /* S_FINALIZE_JOIN ==> */ S_ELECTION, /* S_NOT_DC ==> */ S_ELECTION, /* S_POLICY_ENGINE ==> */ S_ELECTION, /* S_RECOVERY ==> */ S_RECOVERY, /* S_RELEASE_DC ==> */ S_RELEASE_DC, /* S_STARTING ==> */ S_STARTING, /* S_PENDING ==> */ S_ELECTION, /* S_STOPPING ==> */ S_STOPPING, /* S_TERMINATE ==> */ S_TERMINATE, /* S_TRANSITION_ENGINE ==> */ S_ELECTION, /* S_HALT ==> */ S_HALT, }, /* Got an I_PE_CALC */ { /* S_IDLE ==> */ S_POLICY_ENGINE, /* S_ELECTION ==> */ S_ELECTION, /* S_INTEGRATION ==> */ S_INTEGRATION, /* S_FINALIZE_JOIN ==> */ S_FINALIZE_JOIN, /* S_NOT_DC ==> */ S_NOT_DC, /* S_POLICY_ENGINE ==> */ S_POLICY_ENGINE, /* S_RECOVERY ==> */ S_RECOVERY, /* S_RELEASE_DC ==> */ S_RELEASE_DC, /* S_STARTING ==> */ S_RECOVERY, /* S_PENDING ==> */ S_PENDING, /* S_STOPPING ==> */ S_STOPPING, /* S_TERMINATE ==> */ S_TERMINATE, /* S_TRANSITION_ENGINE ==> */ S_POLICY_ENGINE, /* S_HALT ==> */ S_HALT, }, /* Got an I_RELEASE_DC */ { /* S_IDLE ==> */ S_RELEASE_DC, /* S_ELECTION ==> */ S_RELEASE_DC, /* S_INTEGRATION ==> */ S_RELEASE_DC, /* S_FINALIZE_JOIN ==> */ S_RELEASE_DC, /* S_NOT_DC ==> */ S_NOT_DC, /* S_POLICY_ENGINE ==> */ S_RELEASE_DC, /* S_RECOVERY ==> */ S_RECOVERY, /* S_RELEASE_DC ==> */ S_RELEASE_DC, /* S_STARTING ==> */ S_RECOVERY, /* S_PENDING ==> */ S_PENDING, /* S_STOPPING ==> */ S_STOPPING, /* S_TERMINATE ==> */ S_TERMINATE, /* S_TRANSITION_ENGINE ==> */ S_RELEASE_DC, /* S_HALT ==> */ S_HALT, }, /* Got an I_ELECTION_DC */ { /* S_IDLE ==> */ S_INTEGRATION, /* S_ELECTION ==> */ S_INTEGRATION, /* S_INTEGRATION ==> */ S_INTEGRATION, /* S_FINALIZE_JOIN ==> */ S_INTEGRATION, /* S_NOT_DC ==> */ S_INTEGRATION, /* S_POLICY_ENGINE ==> */ S_INTEGRATION, /* S_RECOVERY ==> */ S_RECOVERY, /* S_RELEASE_DC ==> */ S_RELEASE_DC, /* S_STARTING ==> */ S_RECOVERY, /* S_PENDING ==> */ S_PENDING, /* S_STOPPING ==> */ S_STOPPING, /* S_TERMINATE ==> */ S_TERMINATE, /* S_TRANSITION_ENGINE ==> */ S_INTEGRATION, /* S_HALT ==> */ S_HALT, }, /* Got an I_ERROR */ { /* S_IDLE ==> */ S_RECOVERY, /* S_ELECTION ==> */ S_RECOVERY, /* S_INTEGRATION ==> */ S_RECOVERY, /* S_FINALIZE_JOIN ==> */ S_RECOVERY, /* S_NOT_DC ==> */ S_RECOVERY, /* S_POLICY_ENGINE ==> */ S_RECOVERY, /* S_RECOVERY ==> */ S_RECOVERY, /* S_RELEASE_DC ==> */ S_RECOVERY, /* S_STARTING ==> */ S_RECOVERY, /* S_PENDING ==> */ S_RECOVERY, /* S_STOPPING ==> */ S_TERMINATE, /* S_TERMINATE ==> */ S_TERMINATE, /* S_TRANSITION_ENGINE ==> */ S_RECOVERY, /* S_HALT ==> */ S_RECOVERY, }, /* Got an I_FAIL */ { /* S_IDLE ==> */ S_RECOVERY, /* S_ELECTION ==> */ S_RELEASE_DC, /* S_INTEGRATION ==> */ S_INTEGRATION, /* S_FINALIZE_JOIN ==> */ S_INTEGRATION, /* S_NOT_DC ==> */ S_RECOVERY, /* S_POLICY_ENGINE ==> */ S_INTEGRATION, /* S_RECOVERY ==> */ S_RECOVERY, /* S_RELEASE_DC ==> */ S_RELEASE_DC, /* S_STARTING ==> */ S_STOPPING, /* S_PENDING ==> */ S_STOPPING, /* S_STOPPING ==> */ S_STOPPING, /* S_TERMINATE ==> */ S_TERMINATE, /* S_TRANSITION_ENGINE ==> */ S_POLICY_ENGINE, /* S_HALT ==> */ S_RELEASE_DC, }, /* Got an I_INTEGRATED */ { /* S_IDLE ==> */ S_IDLE, /* S_ELECTION ==> */ S_ELECTION, /* S_INTEGRATION ==> */ S_FINALIZE_JOIN, /* S_FINALIZE_JOIN ==> */ S_FINALIZE_JOIN, /* S_NOT_DC ==> */ S_NOT_DC, /* S_POLICY_ENGINE ==> */ S_POLICY_ENGINE, /* S_RECOVERY ==> */ S_RECOVERY, /* S_RELEASE_DC ==> */ S_RELEASE_DC, /* S_STARTING ==> */ S_RECOVERY, /* S_PENDING ==> */ S_RECOVERY, /* S_STOPPING ==> */ S_STOPPING, /* S_TERMINATE ==> */ S_TERMINATE, /* S_TRANSITION_ENGINE ==> */ S_TRANSITION_ENGINE, /* S_HALT ==> */ S_HALT, }, /* Got an I_FINALIZED */ { /* S_IDLE ==> */ S_IDLE, /* S_ELECTION ==> */ S_ELECTION, /* S_INTEGRATION ==> */ S_INTEGRATION, /* S_FINALIZE_JOIN ==> */ S_POLICY_ENGINE, /* S_NOT_DC ==> */ S_NOT_DC, /* S_POLICY_ENGINE ==> */ S_POLICY_ENGINE, /* S_RECOVERY ==> */ S_RECOVERY, /* S_RELEASE_DC ==> */ S_RELEASE_DC, /* S_STARTING ==> */ S_RECOVERY, /* S_PENDING ==> */ S_RECOVERY, /* S_STOPPING ==> */ S_STOPPING, /* S_TERMINATE ==> */ S_TERMINATE, /* S_TRANSITION_ENGINE ==> */ S_TRANSITION_ENGINE, /* S_HALT ==> */ S_HALT, }, /* Got an I_NODE_JOIN */ { /* S_IDLE ==> */ S_INTEGRATION, /* S_ELECTION ==> */ S_ELECTION, /* S_INTEGRATION ==> */ S_INTEGRATION, /* S_FINALIZE_JOIN ==> */ S_INTEGRATION, /* S_NOT_DC ==> */ S_NOT_DC, /* S_POLICY_ENGINE ==> */ S_INTEGRATION, /* S_RECOVERY ==> */ S_RECOVERY, /* S_RELEASE_DC ==> */ S_RELEASE_DC, /* S_STARTING ==> */ S_RECOVERY, /* S_PENDING ==> */ S_PENDING, /* S_STOPPING ==> */ S_STOPPING, /* S_TERMINATE ==> */ S_TERMINATE, /* S_TRANSITION_ENGINE ==> */ S_INTEGRATION, /* S_HALT ==> */ S_HALT, }, /* Got an I_NOT_DC */ { /* S_IDLE ==> */ S_RECOVERY, /* S_ELECTION ==> */ S_ELECTION, /* S_INTEGRATION ==> */ S_RECOVERY, /* S_FINALIZE_JOIN ==> */ S_RECOVERY, /* S_NOT_DC ==> */ S_NOT_DC, /* S_POLICY_ENGINE ==> */ S_RECOVERY, /* S_RECOVERY ==> */ S_RECOVERY, /* S_RELEASE_DC ==> */ S_RELEASE_DC, /* S_STARTING ==> */ S_RECOVERY, /* S_PENDING ==> */ S_NOT_DC, /* S_STOPPING ==> */ S_STOPPING, /* S_TERMINATE ==> */ S_TERMINATE, /* S_TRANSITION_ENGINE ==> */ S_RECOVERY, /* S_HALT ==> */ S_HALT, }, /* Got an I_RECOVERED */ { /* S_IDLE ==> */ S_IDLE, /* S_ELECTION ==> */ S_ELECTION, /* S_INTEGRATION ==> */ S_INTEGRATION, /* S_FINALIZE_JOIN ==> */ S_INTEGRATION, /* S_NOT_DC ==> */ S_NOT_DC, /* S_POLICY_ENGINE ==> */ S_POLICY_ENGINE, /* S_RECOVERY ==> */ S_PENDING, /* S_RELEASE_DC ==> */ S_RELEASE_DC, /* S_STARTING ==> */ S_STARTING, /* S_PENDING ==> */ S_PENDING, /* S_STOPPING ==> */ S_STOPPING, /* S_TERMINATE ==> */ S_TERMINATE, /* S_TRANSITION_ENGINE ==> */ S_TRANSITION_ENGINE, /* S_HALT ==> */ S_HALT, }, /* Got an I_RELEASE_FAIL */ { /* S_IDLE ==> */ S_STOPPING, /* S_ELECTION ==> */ S_STOPPING, /* S_INTEGRATION ==> */ S_STOPPING, /* S_FINALIZE_JOIN ==> */ S_STOPPING, /* S_NOT_DC ==> */ S_NOT_DC, /* S_POLICY_ENGINE ==> */ S_STOPPING, /* S_RECOVERY ==> */ S_STOPPING, /* S_RELEASE_DC ==> */ S_STOPPING, /* S_STARTING ==> */ S_RECOVERY, /* S_PENDING ==> */ S_PENDING, /* S_STOPPING ==> */ S_STOPPING, /* S_TERMINATE ==> */ S_TERMINATE, /* S_TRANSITION_ENGINE ==> */ S_STOPPING, /* S_HALT ==> */ S_HALT, }, /* Got an I_RELEASE_SUCCESS */ { /* S_IDLE ==> */ S_RECOVERY, /* S_ELECTION ==> */ S_ELECTION, /* S_INTEGRATION ==> */ S_RECOVERY, /* S_FINALIZE_JOIN ==> */ S_RECOVERY, /* S_NOT_DC ==> */ S_NOT_DC, /* S_POLICY_ENGINE ==> */ S_RECOVERY, /* S_RECOVERY ==> */ S_RECOVERY, /* S_RELEASE_DC ==> */ S_PENDING, /* S_STARTING ==> */ S_RECOVERY, /* S_PENDING ==> */ S_PENDING, /* S_STOPPING ==> */ S_STOPPING, /* S_TERMINATE ==> */ S_TERMINATE, /* S_TRANSITION_ENGINE ==> */ S_RECOVERY, /* S_HALT ==> */ S_HALT, }, /* Got an I_RESTART */ { /* S_IDLE ==> */ S_IDLE, /* S_ELECTION ==> */ S_ELECTION, /* S_INTEGRATION ==> */ S_INTEGRATION, /* S_FINALIZE_JOIN ==> */ S_FINALIZE_JOIN, /* S_NOT_DC ==> */ S_NOT_DC, /* S_POLICY_ENGINE ==> */ S_POLICY_ENGINE, /* S_RECOVERY ==> */ S_RECOVERY, /* S_RELEASE_DC ==> */ S_RELEASE_DC, /* S_STARTING ==> */ S_STARTING, /* S_PENDING ==> */ S_PENDING, /* S_STOPPING ==> */ S_STOPPING, /* S_TERMINATE ==> */ S_TERMINATE, /* S_TRANSITION_ENGINE ==> */ S_TRANSITION_ENGINE, /* S_HALT ==> */ S_HALT, }, /* Got an I_TE_SUCCESS */ { /* S_IDLE ==> */ S_IDLE, /* S_ELECTION ==> */ S_ELECTION, /* S_INTEGRATION ==> */ S_INTEGRATION, /* S_FINALIZE_JOIN ==> */ S_FINALIZE_JOIN, /* S_NOT_DC ==> */ S_NOT_DC, /* S_POLICY_ENGINE ==> */ S_POLICY_ENGINE, /* S_RECOVERY ==> */ S_RECOVERY, /* S_RELEASE_DC ==> */ S_RELEASE_DC, /* S_STARTING ==> */ S_RECOVERY, /* S_PENDING ==> */ S_PENDING, /* S_STOPPING ==> */ S_STOPPING, /* S_TERMINATE ==> */ S_TERMINATE, /* S_TRANSITION_ENGINE ==> */ S_IDLE, /* S_HALT ==> */ S_HALT, }, /* Got an I_ROUTER */ { /* S_IDLE ==> */ S_IDLE, /* S_ELECTION ==> */ S_ELECTION, /* S_INTEGRATION ==> */ S_INTEGRATION, /* S_FINALIZE_JOIN ==> */ S_FINALIZE_JOIN, /* S_NOT_DC ==> */ S_NOT_DC, /* S_POLICY_ENGINE ==> */ S_POLICY_ENGINE, /* S_RECOVERY ==> */ S_RECOVERY, /* S_RELEASE_DC ==> */ S_RELEASE_DC, /* S_STARTING ==> */ S_STARTING, /* S_PENDING ==> */ S_PENDING, /* S_STOPPING ==> */ S_STOPPING, /* S_TERMINATE ==> */ S_TERMINATE, /* S_TRANSITION_ENGINE ==> */ S_TRANSITION_ENGINE, /* S_HALT ==> */ S_HALT, }, /* Got an I_SHUTDOWN */ { /* S_IDLE ==> */ S_POLICY_ENGINE, /* S_ELECTION ==> */ S_ELECTION, /* S_INTEGRATION ==> */ S_INTEGRATION, /* S_FINALIZE_JOIN ==> */ S_FINALIZE_JOIN, /* S_NOT_DC ==> */ S_NOT_DC, /* S_POLICY_ENGINE ==> */ S_POLICY_ENGINE, /* S_RECOVERY ==> */ S_STOPPING, /* S_RELEASE_DC ==> */ S_RELEASE_DC, /* S_STARTING ==> */ S_STOPPING, /* S_PENDING ==> */ S_PENDING, /* S_STOPPING ==> */ S_STOPPING, /* S_TERMINATE ==> */ S_TERMINATE, /* S_TRANSITION_ENGINE ==> */ S_POLICY_ENGINE, /* S_HALT ==> */ S_ELECTION, }, /* Got an I_STOP */ { /* S_IDLE ==> */ S_STOPPING, /* S_ELECTION ==> */ S_STOPPING, /* S_INTEGRATION ==> */ S_STOPPING, /* S_FINALIZE_JOIN ==> */ S_STOPPING, /* S_NOT_DC ==> */ S_STOPPING, /* S_POLICY_ENGINE ==> */ S_STOPPING, /* S_RECOVERY ==> */ S_STOPPING, /* S_RELEASE_DC ==> */ S_STOPPING, /* S_STARTING ==> */ S_STOPPING, /* S_PENDING ==> */ S_STOPPING, /* S_STOPPING ==> */ S_STOPPING, /* S_TERMINATE ==> */ S_TERMINATE, /* S_TRANSITION_ENGINE ==> */ S_STOPPING, /* S_HALT ==> */ S_STOPPING, }, /* Got an I_TERMINATE */ { /* S_IDLE ==> */ S_TERMINATE, /* S_ELECTION ==> */ S_TERMINATE, /* S_INTEGRATION ==> */ S_TERMINATE, /* S_FINALIZE_JOIN ==> */ S_TERMINATE, /* S_NOT_DC ==> */ S_TERMINATE, /* S_POLICY_ENGINE ==> */ S_TERMINATE, /* S_RECOVERY ==> */ S_TERMINATE, /* S_RELEASE_DC ==> */ S_TERMINATE, /* S_STARTING ==> */ S_TERMINATE, /* S_PENDING ==> */ S_TERMINATE, /* S_STOPPING ==> */ S_TERMINATE, /* S_TERMINATE ==> */ S_TERMINATE, /* S_TRANSITION_ENGINE ==> */ S_TERMINATE, /* S_HALT ==> */ S_TERMINATE, }, /* Got an I_STARTUP */ { /* S_IDLE ==> */ S_RECOVERY, /* S_ELECTION ==> */ S_RECOVERY, /* S_INTEGRATION ==> */ S_RECOVERY, /* S_FINALIZE_JOIN ==> */ S_RECOVERY, /* S_NOT_DC ==> */ S_RECOVERY, /* S_POLICY_ENGINE ==> */ S_RECOVERY, /* S_RECOVERY ==> */ S_RECOVERY, /* S_RELEASE_DC ==> */ S_RELEASE_DC, /* S_STARTING ==> */ S_STARTING, /* S_PENDING ==> */ S_PENDING, /* S_STOPPING ==> */ S_STOPPING, /* S_TERMINATE ==> */ S_TERMINATE, /* S_TRANSITION_ENGINE ==> */ S_RECOVERY, /* S_HALT ==> */ S_HALT, }, /* Got an I_PE_SUCCESS */ { /* S_IDLE ==> */ S_IDLE, /* S_ELECTION ==> */ S_ELECTION, /* S_INTEGRATION ==> */ S_INTEGRATION, /* S_FINALIZE_JOIN ==> */ S_FINALIZE_JOIN, /* S_NOT_DC ==> */ S_NOT_DC, /* S_POLICY_ENGINE ==> */ S_TRANSITION_ENGINE, /* S_RECOVERY ==> */ S_RECOVERY, /* S_RELEASE_DC ==> */ S_RELEASE_DC, /* S_STARTING ==> */ S_RECOVERY, /* S_PENDING ==> */ S_PENDING, /* S_STOPPING ==> */ S_STOPPING, /* S_TERMINATE ==> */ S_TERMINATE, /* S_TRANSITION_ENGINE ==> */ S_TRANSITION_ENGINE, /* S_HALT ==> */ S_HALT, }, /* Got an I_JOIN_OFFER */ { /* S_IDLE ==> */ S_IDLE, /* S_ELECTION ==> */ S_ELECTION, /* S_INTEGRATION ==> */ S_INTEGRATION, /* S_FINALIZE_JOIN ==> */ S_FINALIZE_JOIN, /* S_NOT_DC ==> */ S_PENDING, /* S_POLICY_ENGINE ==> */ S_POLICY_ENGINE, /* S_RECOVERY ==> */ S_RECOVERY, /* S_RELEASE_DC ==> */ S_RELEASE_DC, /* S_STARTING ==> */ S_STARTING, /* S_PENDING ==> */ S_PENDING, /* S_STOPPING ==> */ S_STOPPING, /* S_TERMINATE ==> */ S_TERMINATE, /* S_TRANSITION_ENGINE ==> */ S_TRANSITION_ENGINE, /* S_HALT ==> */ S_HALT, }, /* Got an I_JOIN_REQUEST */ { /* S_IDLE ==> */ S_INTEGRATION, /* S_ELECTION ==> */ S_ELECTION, /* S_INTEGRATION ==> */ S_INTEGRATION, /* S_FINALIZE_JOIN ==> */ S_INTEGRATION, /* S_NOT_DC ==> */ S_NOT_DC, /* S_POLICY_ENGINE ==> */ S_INTEGRATION, /* S_RECOVERY ==> */ S_RECOVERY, /* S_RELEASE_DC ==> */ S_RELEASE_DC, /* S_STARTING ==> */ S_STARTING, /* S_PENDING ==> */ S_PENDING, /* S_STOPPING ==> */ S_STOPPING, /* S_TERMINATE ==> */ S_TERMINATE, /* S_TRANSITION_ENGINE ==> */ S_INTEGRATION, /* S_HALT ==> */ S_HALT, }, /* Got an I_JOIN_RESULT */ { /* S_IDLE ==> */ S_INTEGRATION, /* S_ELECTION ==> */ S_ELECTION, /* S_INTEGRATION ==> */ S_INTEGRATION, /* S_FINALIZE_JOIN ==> */ S_FINALIZE_JOIN, /* S_NOT_DC ==> */ S_PENDING, /* S_POLICY_ENGINE ==> */ S_INTEGRATION, /* S_RECOVERY ==> */ S_RECOVERY, /* S_RELEASE_DC ==> */ S_RELEASE_DC, /* S_STARTING ==> */ S_RECOVERY, /* S_PENDING ==> */ S_PENDING, /* S_STOPPING ==> */ S_STOPPING, /* S_TERMINATE ==> */ S_TERMINATE, /* S_TRANSITION_ENGINE ==> */ S_INTEGRATION, /* S_HALT ==> */ S_HALT, }, /* Got an I_WAIT_FOR_EVENT */ { /* S_IDLE ==> */ S_IDLE, /* S_ELECTION ==> */ S_ELECTION, /* S_INTEGRATION ==> */ S_INTEGRATION, /* S_FINALIZE_JOIN ==> */ S_FINALIZE_JOIN, /* S_NOT_DC ==> */ S_NOT_DC, /* S_POLICY_ENGINE ==> */ S_POLICY_ENGINE, /* S_RECOVERY ==> */ S_RECOVERY, /* S_RELEASE_DC ==> */ S_RELEASE_DC, /* S_STARTING ==> */ S_STARTING, /* S_PENDING ==> */ S_PENDING, /* S_STOPPING ==> */ S_STOPPING, /* S_TERMINATE ==> */ S_TERMINATE, /* S_TRANSITION_ENGINE ==> */ S_TRANSITION_ENGINE, /* S_HALT ==> */ S_HALT, }, /* Got an I_DC_HEARTBEAT */ { /* S_IDLE ==> */ S_IDLE, /* S_ELECTION ==> */ S_ELECTION, /* S_INTEGRATION ==> */ S_INTEGRATION, /* S_FINALIZE_JOIN ==> */ S_FINALIZE_JOIN, /* S_NOT_DC ==> */ S_NOT_DC, /* S_POLICY_ENGINE ==> */ S_POLICY_ENGINE, /* S_RECOVERY ==> */ S_RECOVERY, /* S_RELEASE_DC ==> */ S_RELEASE_DC, /* S_STARTING ==> */ S_STARTING, /* S_PENDING ==> */ S_PENDING, /* S_STOPPING ==> */ S_STOPPING, /* S_TERMINATE ==> */ S_TERMINATE, /* S_TRANSITION_ENGINE ==> */ S_TRANSITION_ENGINE, /* S_HALT ==> */ S_HALT, }, /* Got an I_LRM_EVENT */ { /* S_IDLE ==> */ S_IDLE, /* S_ELECTION ==> */ S_ELECTION, /* S_INTEGRATION ==> */ S_INTEGRATION, /* S_FINALIZE_JOIN ==> */ S_FINALIZE_JOIN, /* S_NOT_DC ==> */ S_NOT_DC, /* S_POLICY_ENGINE ==> */ S_POLICY_ENGINE, /* S_RECOVERY ==> */ S_RECOVERY, /* S_RELEASE_DC ==> */ S_RELEASE_DC, /* S_STARTING ==> */ S_STARTING, /* S_PENDING ==> */ S_PENDING, /* S_STOPPING ==> */ S_STOPPING, /* S_TERMINATE ==> */ S_TERMINATE, /* S_TRANSITION_ENGINE ==> */ S_TRANSITION_ENGINE, /* S_HALT ==> */ S_HALT, }, /* Got an I_PENDING */ { /* S_IDLE ==> */ S_PENDING, /* S_ELECTION ==> */ S_PENDING, /* S_INTEGRATION ==> */ S_PENDING, /* S_FINALIZE_JOIN ==> */ S_PENDING, /* S_NOT_DC ==> */ S_PENDING, /* S_POLICY_ENGINE ==> */ S_PENDING, /* S_RECOVERY ==> */ S_RECOVERY, /* S_RELEASE_DC ==> */ S_RELEASE_DC, /* S_STARTING ==> */ S_PENDING, /* S_PENDING ==> */ S_PENDING, /* S_STOPPING ==> */ S_STOPPING, /* S_TERMINATE ==> */ S_TERMINATE, /* S_TRANSITION_ENGINE ==> */ S_PENDING, /* S_HALT ==> */ S_HALT, }, /* Got an I_HALT */ { /* S_IDLE ==> */ S_HALT, /* S_ELECTION ==> */ S_HALT, /* S_INTEGRATION ==> */ S_HALT, /* S_FINALIZE_JOIN ==> */ S_HALT, /* S_NOT_DC ==> */ S_HALT, /* S_POLICY_ENGINE ==> */ S_HALT, /* S_RECOVERY ==> */ S_RECOVERY, /* S_RELEASE_DC ==> */ S_RELEASE_DC, /* S_STARTING ==> */ S_STARTING, /* S_PENDING ==> */ S_HALT, /* S_STOPPING ==> */ S_STOPPING, /* S_TERMINATE ==> */ S_TERMINATE, /* S_TRANSITION_ENGINE ==> */ S_HALT, /* S_HALT ==> */ S_HALT, }, }; /* * The action table. Each entry is a set of actions to take or-ed * together. Like the state table, the rows are inputs, and * the columns are states. */ /* NOTE: In the fsa, the actions are extracted then state is updated. */ const long long crmd_fsa_actions[MAXINPUT][MAXSTATE] = { /* Got an I_NULL */ { /* S_IDLE ==> */ A_NOTHING, /* S_ELECTION ==> */ A_NOTHING, /* S_INTEGRATION ==> */ A_NOTHING, /* S_FINALIZE_JOIN ==> */ A_NOTHING, /* S_NOT_DC ==> */ A_NOTHING, /* S_POLICY_ENGINE ==> */ A_NOTHING, /* S_RECOVERY ==> */ A_NOTHING, /* S_RELEASE_DC ==> */ A_NOTHING, /* S_STARTING ==> */ A_NOTHING, /* S_PENDING ==> */ A_NOTHING, /* S_STOPPING ==> */ A_NOTHING, /* S_TERMINATE ==> */ A_NOTHING, /* S_TRANSITION_ENGINE ==> */ A_NOTHING, /* S_HALT ==> */ A_NOTHING, }, /* Got an I_CIB_OP */ { /* S_IDLE ==> */ A_ERROR, /* S_ELECTION ==> */ A_ERROR, /* S_INTEGRATION ==> */ A_ERROR, /* S_FINALIZE_JOIN ==> */ A_ERROR, /* S_NOT_DC ==> */ A_ERROR, /* S_POLICY_ENGINE ==> */ A_ERROR, /* S_RECOVERY ==> */ A_ERROR, /* S_RELEASE_DC ==> */ A_ERROR, /* S_STARTING ==> */ A_ERROR, /* S_PENDING ==> */ A_ERROR, /* S_STOPPING ==> */ A_ERROR, /* S_TERMINATE ==> */ A_ERROR, /* S_TRANSITION_ENGINE ==> */ A_ERROR, /* S_HALT ==> */ A_ERROR, }, /* Got an I_CIB_UPDATE */ { /* S_IDLE ==> */ A_LOG, /* S_ELECTION ==> */ A_LOG, /* S_INTEGRATION ==> */ A_WARN, /* S_FINALIZE_JOIN ==> */ A_WARN, /* S_NOT_DC ==> */ A_WARN, /* S_POLICY_ENGINE ==> */ A_LOG, /* S_RECOVERY ==> */ A_WARN, /* S_RELEASE_DC ==> */ A_WARN, /* S_STARTING ==> */ A_WARN, /* S_PENDING ==> */ A_WARN, /* S_STOPPING ==> */ A_WARN, /* S_TERMINATE ==> */ A_WARN, /* S_TRANSITION_ENGINE ==> */ A_LOG, /* S_HALT ==> */ A_WARN, }, /* Got an I_DC_TIMEOUT */ { /* S_IDLE ==> */ A_WARN, /* S_ELECTION ==> */ A_ELECTION_VOTE, /* S_INTEGRATION ==> */ A_WARN, /* S_FINALIZE_JOIN ==> */ A_WARN, /* S_NOT_DC ==> */ A_ELECTION_VOTE | A_WARN, /* S_POLICY_ENGINE ==> */ A_WARN, /* S_RECOVERY ==> */ A_NOTHING, /* S_RELEASE_DC ==> */ A_WARN, /* S_STARTING ==> */ A_WARN, /* S_PENDING ==> */ A_ELECTION_VOTE | A_WARN, /* S_STOPPING ==> */ A_NOTHING, /* S_TERMINATE ==> */ A_NOTHING, /* S_TRANSITION_ENGINE ==> */ A_TE_CANCEL | A_WARN, /* S_HALT ==> */ A_WARN, }, /* Got an I_ELECTION */ { /* S_IDLE ==> */ A_ELECTION_VOTE, /* S_ELECTION ==> */ A_ELECTION_VOTE, /* S_INTEGRATION ==> */ A_ELECTION_VOTE, /* S_FINALIZE_JOIN ==> */ A_ELECTION_VOTE, /* S_NOT_DC ==> */ A_ELECTION_VOTE, /* S_POLICY_ENGINE ==> */ A_ELECTION_VOTE, /* S_RECOVERY ==> */ A_LOG, /* S_RELEASE_DC ==> */ A_LOG, /* S_STARTING ==> */ A_WARN, /* S_PENDING ==> */ A_ELECTION_VOTE, /* S_STOPPING ==> */ A_LOG, /* S_TERMINATE ==> */ A_LOG, /* S_TRANSITION_ENGINE ==> */ A_ELECTION_VOTE, /* S_HALT ==> */ A_ELECTION_VOTE, }, /* Got an I_PE_CALC */ { /* S_IDLE ==> */ A_PE_INVOKE, /* S_ELECTION ==> */ A_NOTHING, /* S_INTEGRATION ==> */ A_NOTHING, /* S_FINALIZE_JOIN ==> */ A_NOTHING, /* S_NOT_DC ==> */ A_WARN, /* S_POLICY_ENGINE ==> */ A_PE_INVOKE, /* S_RECOVERY ==> */ A_NOTHING, /* S_RELEASE_DC ==> */ A_NOTHING, /* S_STARTING ==> */ A_ERROR, /* S_PENDING ==> */ A_WARN, /* S_STOPPING ==> */ A_WARN, /* S_TERMINATE ==> */ A_ERROR, /* S_TRANSITION_ENGINE ==> */ A_PE_INVOKE, /* S_HALT ==> */ A_ERROR, }, /* Got an I_RELEASE_DC */ { /* S_IDLE ==> */ O_RELEASE, /* S_ELECTION ==> */ O_RELEASE, /* S_INTEGRATION ==> */ O_RELEASE | A_WARN, /* S_FINALIZE_JOIN ==> */ O_RELEASE | A_WARN, /* S_NOT_DC ==> */ A_WARN, /* S_POLICY_ENGINE ==> */ O_RELEASE | A_WARN, /* S_RECOVERY ==> */ O_RELEASE, /* S_RELEASE_DC ==> */ O_RELEASE | A_WARN, /* S_STARTING ==> */ A_ERROR, /* S_PENDING ==> */ A_WARN, /* S_STOPPING ==> */ A_WARN, /* S_TERMINATE ==> */ A_WARN, /* S_TRANSITION_ENGINE ==> */ O_RELEASE | A_WARN, /* S_HALT ==> */ A_WARN, }, /* Got an I_ELECTION_DC */ { /* S_IDLE ==> */ A_WARN | A_ELECTION_VOTE, /* S_ELECTION ==> */ A_LOG | A_DC_TAKEOVER | A_PE_START | A_TE_START | A_DC_JOIN_OFFER_ALL | A_DC_TIMER_STOP, /* S_INTEGRATION ==> */ A_WARN | A_ELECTION_VOTE | A_DC_JOIN_OFFER_ALL, /* S_FINALIZE_JOIN ==> */ A_WARN | A_ELECTION_VOTE | A_DC_JOIN_OFFER_ALL, /* S_NOT_DC ==> */ A_LOG | A_ELECTION_VOTE, /* S_POLICY_ENGINE ==> */ A_WARN | A_ELECTION_VOTE, /* S_RECOVERY ==> */ A_WARN, /* S_RELEASE_DC ==> */ A_WARN | A_ELECTION_VOTE, /* S_STARTING ==> */ A_LOG | A_WARN, /* S_PENDING ==> */ A_LOG | A_WARN, /* S_STOPPING ==> */ A_WARN, /* S_TERMINATE ==> */ A_WARN, /* S_TRANSITION_ENGINE ==> */ A_WARN | A_ELECTION_VOTE, /* S_HALT ==> */ A_WARN, }, /* Got an I_ERROR */ { /* S_IDLE ==> */ A_ERROR | A_RECOVER | O_RELEASE | A_ELECTION_START, /* S_ELECTION ==> */ A_ERROR | A_RECOVER | O_RELEASE, /* S_INTEGRATION ==> */ A_ERROR | A_RECOVER | O_RELEASE | A_ELECTION_START, /* S_FINALIZE_JOIN ==> */ A_ERROR | A_RECOVER | O_RELEASE | A_ELECTION_START, /* S_NOT_DC ==> */ A_ERROR | A_RECOVER, /* S_POLICY_ENGINE ==> */ A_ERROR | A_RECOVER | O_RELEASE | A_ELECTION_START, /* S_RECOVERY ==> */ A_ERROR | O_RELEASE, /* S_RELEASE_DC ==> */ A_ERROR | A_RECOVER, /* S_STARTING ==> */ A_ERROR | A_RECOVER, /* S_PENDING ==> */ A_ERROR | A_RECOVER, /* S_STOPPING ==> */ A_ERROR | A_EXIT_1, /* S_TERMINATE ==> */ A_ERROR | A_EXIT_1, /* S_TRANSITION_ENGINE ==> */ A_ERROR | A_RECOVER | O_RELEASE | A_ELECTION_START, /* S_HALT ==> */ A_ERROR | A_RECOVER | O_RELEASE | A_ELECTION_START, }, /* Got an I_FAIL */ { /* S_IDLE ==> */ A_WARN, /* S_ELECTION ==> */ A_WARN, /* S_INTEGRATION ==> */ A_WARN | A_DC_JOIN_OFFER_ALL, /* S_FINALIZE_JOIN ==> */ A_WARN | A_DC_JOIN_OFFER_ALL, /* S_NOT_DC ==> */ A_WARN, /* S_POLICY_ENGINE ==> */ A_WARN | A_DC_JOIN_OFFER_ALL | A_TE_CANCEL, /* S_RECOVERY ==> */ A_WARN | O_RELEASE, /* S_RELEASE_DC ==> */ A_WARN, /* S_STARTING ==> */ A_WARN, /* S_PENDING ==> */ A_WARN, /* S_STOPPING ==> */ A_WARN, /* S_TERMINATE ==> */ A_WARN | A_EXIT_1, /* S_TRANSITION_ENGINE ==> */ A_WARN | O_LRM_RECONNECT | A_PE_INVOKE | A_TE_CANCEL, /* S_HALT ==> */ A_WARN, }, /* Got an I_INTEGRATED */ { /* S_IDLE ==> */ A_NOTHING, /* S_ELECTION ==> */ A_WARN, /* S_INTEGRATION ==> */ A_DC_JOIN_FINALIZE, /* S_FINALIZE_JOIN ==> */ A_WARN, /* S_NOT_DC ==> */ A_WARN, /* S_POLICY_ENGINE ==> */ A_NOTHING, /* S_RECOVERY ==> */ A_WARN, /* S_RELEASE_DC ==> */ A_WARN, /* S_STARTING ==> */ A_WARN, /* S_PENDING ==> */ A_WARN, /* S_STOPPING ==> */ A_WARN, /* S_TERMINATE ==> */ A_WARN, /* S_TRANSITION_ENGINE ==> */ A_NOTHING, /* S_HALT ==> */ A_WARN, }, /* Got an I_FINALIZED */ { /* S_IDLE ==> */ A_NOTHING, /* S_ELECTION ==> */ A_WARN, /* S_INTEGRATION ==> */ A_WARN, /* S_FINALIZE_JOIN ==> */ A_DC_JOIN_FINAL | A_TE_CANCEL, /* S_NOT_DC ==> */ A_WARN, /* S_POLICY_ENGINE ==> */ A_NOTHING, /* S_RECOVERY ==> */ A_WARN, /* S_RELEASE_DC ==> */ A_WARN, /* S_STARTING ==> */ A_WARN, /* S_PENDING ==> */ A_WARN, /* S_STOPPING ==> */ A_WARN, /* S_TERMINATE ==> */ A_WARN, /* S_TRANSITION_ENGINE ==> */ A_NOTHING, /* S_HALT ==> */ A_WARN, }, /* Got an I_NODE_JOIN */ { /* S_IDLE ==> */ A_TE_HALT | A_DC_JOIN_OFFER_ONE, /* S_ELECTION ==> */ A_WARN, /* S_INTEGRATION ==> */ A_DC_JOIN_OFFER_ONE, /* S_FINALIZE_JOIN ==> */ A_DC_JOIN_OFFER_ONE, /* S_NOT_DC ==> */ A_WARN, /* S_POLICY_ENGINE ==> */ A_DC_JOIN_OFFER_ONE, /* S_RECOVERY ==> */ A_WARN, /* S_RELEASE_DC ==> */ A_WARN, /* S_STARTING ==> */ A_WARN, /* S_PENDING ==> */ A_WARN, /* S_STOPPING ==> */ A_WARN, /* S_TERMINATE ==> */ A_WARN, /* S_TRANSITION_ENGINE ==> */ A_TE_HALT | A_DC_JOIN_OFFER_ONE, /* S_HALT ==> */ A_WARN, }, /* Got an I_NOT_DC */ { /* S_IDLE ==> */ A_WARN | O_RELEASE, /* S_ELECTION ==> */ A_ERROR | A_ELECTION_START | A_DC_TIMER_STOP, /* S_INTEGRATION ==> */ A_ERROR | O_RELEASE, /* S_FINALIZE_JOIN ==> */ A_ERROR | O_RELEASE, /* S_NOT_DC ==> */ A_LOG, /* S_POLICY_ENGINE ==> */ A_ERROR | O_RELEASE, /* S_RECOVERY ==> */ A_ERROR | O_RELEASE, /* S_RELEASE_DC ==> */ A_ERROR | O_RELEASE, /* S_STARTING ==> */ A_WARN, /* S_PENDING ==> */ A_LOG | A_DC_TIMER_STOP, /* S_STOPPING ==> */ A_WARN, /* S_TERMINATE ==> */ A_WARN, /* S_TRANSITION_ENGINE ==> */ A_ERROR | O_RELEASE, /* S_HALT ==> */ A_WARN, }, /* Got an I_RECOVERED */ { /* S_IDLE ==> */ A_WARN, /* S_ELECTION ==> */ A_ELECTION_VOTE, /* S_INTEGRATION ==> */ A_WARN, /* S_FINALIZE_JOIN ==> */ A_WARN, /* S_NOT_DC ==> */ A_WARN, /* S_POLICY_ENGINE ==> */ A_WARN, /* S_RECOVERY ==> */ A_LOG, /* S_RELEASE_DC ==> */ A_WARN, /* S_STARTING ==> */ A_WARN, /* S_PENDING ==> */ A_WARN, /* S_STOPPING ==> */ A_WARN, /* S_TERMINATE ==> */ A_WARN, /* S_TRANSITION_ENGINE ==> */ A_WARN, /* S_HALT ==> */ A_WARN, }, /* Got an I_RELEASE_FAIL */ { /* S_IDLE ==> */ A_WARN, /* S_ELECTION ==> */ A_WARN, /* S_INTEGRATION ==> */ A_WARN, /* S_FINALIZE_JOIN ==> */ A_WARN, /* S_NOT_DC ==> */ A_WARN, /* S_POLICY_ENGINE ==> */ A_NOTHING, /* S_RECOVERY ==> */ A_WARN | A_SHUTDOWN_REQ, /* S_RELEASE_DC ==> */ A_NOTHING, /* S_STARTING ==> */ A_WARN, /* S_PENDING ==> */ A_WARN, /* S_STOPPING ==> */ A_WARN, /* S_TERMINATE ==> */ A_WARN, /* S_TRANSITION_ENGINE ==> */ A_WARN, /* S_HALT ==> */ A_WARN, }, /* Got an I_RELEASE_SUCCESS */ { /* S_IDLE ==> */ A_WARN, /* S_ELECTION ==> */ A_WARN, /* S_INTEGRATION ==> */ A_WARN, /* S_FINALIZE_JOIN ==> */ A_WARN, /* S_NOT_DC ==> */ A_WARN, /* S_POLICY_ENGINE ==> */ A_WARN, /* S_RECOVERY ==> */ A_WARN, /* S_RELEASE_DC ==> */ A_LOG, /* S_STARTING ==> */ A_WARN, /* S_PENDING ==> */ A_LOG, /* S_STOPPING ==> */ A_WARN, /* S_TERMINATE ==> */ A_WARN, /* S_TRANSITION_ENGINE ==> */ A_WARN, /* S_HALT ==> */ A_WARN, }, /* Got an I_RESTART */ { /* S_IDLE ==> */ A_NOTHING, /* S_ELECTION ==> */ A_LOG | A_ELECTION_VOTE, /* S_INTEGRATION ==> */ A_LOG | A_DC_JOIN_OFFER_ALL, /* S_FINALIZE_JOIN ==> */ A_LOG | A_DC_JOIN_FINALIZE, /* S_NOT_DC ==> */ A_LOG | A_NOTHING, /* S_POLICY_ENGINE ==> */ A_LOG | A_PE_INVOKE, /* S_RECOVERY ==> */ A_LOG | A_RECOVER | O_RELEASE, /* S_RELEASE_DC ==> */ A_LOG | O_RELEASE, /* S_STARTING ==> */ A_LOG, /* S_PENDING ==> */ A_LOG, /* S_STOPPING ==> */ A_LOG, /* S_TERMINATE ==> */ A_LOG, /* S_TRANSITION_ENGINE ==> */ A_LOG | A_TE_INVOKE, /* S_HALT ==> */ A_WARN, }, /* Got an I_TE_SUCCESS */ { /* S_IDLE ==> */ A_LOG, /* S_ELECTION ==> */ A_WARN, /* S_INTEGRATION ==> */ A_WARN, /* S_FINALIZE_JOIN ==> */ A_WARN, /* S_NOT_DC ==> */ A_ERROR, /* S_POLICY_ENGINE ==> */ A_WARN, /* S_RECOVERY ==> */ A_RECOVER | A_WARN, /* S_RELEASE_DC ==> */ A_WARN, /* S_STARTING ==> */ A_ERROR, /* S_PENDING ==> */ A_ERROR, /* S_STOPPING ==> */ A_WARN, /* S_TERMINATE ==> */ A_WARN, /* S_TRANSITION_ENGINE ==> */ A_LOG, /* S_HALT ==> */ A_WARN, }, /* Got an I_ROUTER */ { /* S_IDLE ==> */ A_MSG_ROUTE, /* S_ELECTION ==> */ A_MSG_ROUTE, /* S_INTEGRATION ==> */ A_MSG_ROUTE, /* S_FINALIZE_JOIN ==> */ A_MSG_ROUTE, /* S_NOT_DC ==> */ A_MSG_ROUTE, /* S_POLICY_ENGINE ==> */ A_MSG_ROUTE, /* S_RECOVERY ==> */ A_MSG_ROUTE, /* S_RELEASE_DC ==> */ A_MSG_ROUTE, /* S_STARTING ==> */ A_MSG_ROUTE, /* S_PENDING ==> */ A_MSG_ROUTE, /* S_STOPPING ==> */ A_MSG_ROUTE, /* S_TERMINATE ==> */ A_MSG_ROUTE, /* S_TRANSITION_ENGINE ==> */ A_MSG_ROUTE, /* S_HALT ==> */ A_WARN | A_MSG_ROUTE, }, /* Got an I_SHUTDOWN */ { /* S_IDLE ==> */ A_LOG | A_SHUTDOWN_REQ, /* S_ELECTION ==> */ A_LOG | A_SHUTDOWN_REQ | A_ELECTION_VOTE, /* S_INTEGRATION ==> */ A_LOG | A_SHUTDOWN_REQ, /* S_FINALIZE_JOIN ==> */ A_LOG | A_SHUTDOWN_REQ, /* S_NOT_DC ==> */ A_SHUTDOWN_REQ, /* S_POLICY_ENGINE ==> */ A_LOG | A_SHUTDOWN_REQ, /* S_RECOVERY ==> */ A_WARN | O_EXIT | O_RELEASE, /* S_RELEASE_DC ==> */ A_WARN | A_SHUTDOWN_REQ, /* S_STARTING ==> */ A_WARN | O_EXIT, /* S_PENDING ==> */ A_SHUTDOWN_REQ, /* S_STOPPING ==> */ A_LOG, /* S_TERMINATE ==> */ A_LOG, /* S_TRANSITION_ENGINE ==> */ A_WARN | A_SHUTDOWN_REQ, /* S_HALT ==> */ A_WARN | A_ELECTION_START | A_SHUTDOWN_REQ, }, /* Got an I_STOP */ { /* S_IDLE ==> */ A_ERROR | O_RELEASE | O_EXIT, /* S_ELECTION ==> */ O_RELEASE | O_EXIT, /* S_INTEGRATION ==> */ A_WARN | O_RELEASE | O_EXIT, /* S_FINALIZE_JOIN ==> */ A_ERROR | O_RELEASE | O_EXIT, /* S_NOT_DC ==> */ O_EXIT, /* S_POLICY_ENGINE ==> */ A_WARN | O_RELEASE | O_EXIT, /* S_RECOVERY ==> */ A_ERROR | O_RELEASE | O_EXIT, /* S_RELEASE_DC ==> */ A_ERROR | O_RELEASE | O_EXIT, /* S_STARTING ==> */ O_EXIT, /* S_PENDING ==> */ O_EXIT, /* S_STOPPING ==> */ O_EXIT, /* S_TERMINATE ==> */ A_ERROR | A_EXIT_1, /* S_TRANSITION_ENGINE ==> */ A_LOG | O_RELEASE | O_EXIT, /* S_HALT ==> */ O_RELEASE | O_EXIT | A_WARN, }, /* Got an I_TERMINATE */ { /* S_IDLE ==> */ A_ERROR | O_EXIT, /* S_ELECTION ==> */ A_ERROR | O_EXIT, /* S_INTEGRATION ==> */ A_ERROR | O_EXIT, /* S_FINALIZE_JOIN ==> */ A_ERROR | O_EXIT, /* S_NOT_DC ==> */ A_ERROR | O_EXIT, /* S_POLICY_ENGINE ==> */ A_ERROR | O_EXIT, /* S_RECOVERY ==> */ A_ERROR | O_EXIT, /* S_RELEASE_DC ==> */ A_ERROR | O_EXIT, /* S_STARTING ==> */ O_EXIT, /* S_PENDING ==> */ A_ERROR | O_EXIT, /* S_STOPPING ==> */ O_EXIT, /* S_TERMINATE ==> */ O_EXIT, /* S_TRANSITION_ENGINE ==> */ A_ERROR | O_EXIT, /* S_HALT ==> */ A_ERROR | O_EXIT, }, /* Got an I_STARTUP */ { /* S_IDLE ==> */ A_WARN, /* S_ELECTION ==> */ A_WARN, /* S_INTEGRATION ==> */ A_WARN, /* S_FINALIZE_JOIN ==> */ A_WARN, /* S_NOT_DC ==> */ A_WARN, /* S_POLICY_ENGINE ==> */ A_WARN, /* S_RECOVERY ==> */ A_WARN, /* S_RELEASE_DC ==> */ A_WARN, /* S_STARTING ==> */ A_LOG | A_STARTUP | A_CIB_START | A_LRM_CONNECT | A_CCM_CONNECT | A_HA_CONNECT | A_READCONFIG | A_STARTED, /* S_PENDING ==> */ A_LOG, /* S_STOPPING ==> */ A_WARN, /* S_TERMINATE ==> */ A_WARN, /* S_TRANSITION_ENGINE ==> */ A_WARN, /* S_HALT ==> */ A_WARN, }, /* Got an I_PE_SUCCESS */ { /* S_IDLE ==> */ A_LOG, /* S_ELECTION ==> */ A_WARN, /* S_INTEGRATION ==> */ A_WARN, /* S_FINALIZE_JOIN ==> */ A_WARN, /* S_NOT_DC ==> */ A_NOTHING, /* S_POLICY_ENGINE ==> */ A_TE_INVOKE, /* S_RECOVERY ==> */ A_RECOVER | A_LOG, /* S_RELEASE_DC ==> */ A_LOG, /* S_STARTING ==> */ A_ERROR, /* S_PENDING ==> */ A_LOG, /* S_STOPPING ==> */ A_ERROR, /* S_TERMINATE ==> */ A_ERROR, /* S_TRANSITION_ENGINE ==> */ A_LOG, /* S_HALT ==> */ A_WARN, }, /* Got an I_JOIN_OFFER */ { /* S_IDLE ==> */ A_WARN | A_CL_JOIN_REQUEST, /* S_ELECTION ==> */ A_WARN | A_ELECTION_VOTE, /* S_INTEGRATION ==> */ A_CL_JOIN_REQUEST, /* S_FINALIZE_JOIN ==> */ A_CL_JOIN_REQUEST, /* S_NOT_DC ==> */ A_CL_JOIN_REQUEST | A_DC_TIMER_STOP, /* S_POLICY_ENGINE ==> */ A_WARN | A_CL_JOIN_REQUEST, /* S_RECOVERY ==> */ A_WARN | A_CL_JOIN_REQUEST | A_DC_TIMER_STOP, /* S_RELEASE_DC ==> */ A_WARN | A_CL_JOIN_REQUEST | A_DC_TIMER_STOP, /* S_STARTING ==> */ A_LOG, /* S_PENDING ==> */ A_CL_JOIN_REQUEST | A_DC_TIMER_STOP, /* S_STOPPING ==> */ A_LOG, /* S_TERMINATE ==> */ A_LOG, /* S_TRANSITION_ENGINE ==> */ A_WARN | A_CL_JOIN_REQUEST, /* S_HALT ==> */ A_WARN, }, /* Got an I_JOIN_REQUEST */ { /* S_IDLE ==> */ A_DC_JOIN_OFFER_ONE, /* S_ELECTION ==> */ A_WARN, /* S_INTEGRATION ==> */ A_DC_JOIN_PROCESS_REQ, /* S_FINALIZE_JOIN ==> */ A_DC_JOIN_OFFER_ONE, /* S_NOT_DC ==> */ A_WARN, /* S_POLICY_ENGINE ==> */ A_DC_JOIN_OFFER_ONE, /* S_RECOVERY ==> */ A_WARN, /* S_RELEASE_DC ==> */ A_WARN, /* S_STARTING ==> */ A_WARN, /* S_PENDING ==> */ A_WARN, /* S_STOPPING ==> */ A_WARN, /* S_TERMINATE ==> */ A_WARN, /* S_TRANSITION_ENGINE ==> */ A_DC_JOIN_OFFER_ONE, /* S_HALT ==> */ A_WARN, }, /* Got an I_JOIN_RESULT */ { /* S_IDLE ==> */ A_ERROR | A_TE_HALT | A_DC_JOIN_OFFER_ALL, /* S_ELECTION ==> */ A_LOG, /* S_INTEGRATION ==> */ A_LOG | A_CL_JOIN_RESULT | A_DC_JOIN_PROCESS_ACK, /* S_FINALIZE_JOIN ==> */ A_CL_JOIN_RESULT | A_DC_JOIN_PROCESS_ACK, /* S_NOT_DC ==> */ A_ERROR | A_CL_JOIN_ANNOUNCE, /* S_POLICY_ENGINE ==> */ A_ERROR | A_TE_HALT | A_DC_JOIN_OFFER_ALL, /* S_RECOVERY ==> */ A_LOG, /* S_RELEASE_DC ==> */ A_LOG, /* S_STARTING ==> */ A_ERROR, /* S_PENDING ==> */ A_CL_JOIN_RESULT, /* S_STOPPING ==> */ A_ERROR, /* S_TERMINATE ==> */ A_ERROR, /* S_TRANSITION_ENGINE ==> */ A_ERROR | A_TE_HALT | A_DC_JOIN_OFFER_ALL, /* S_HALT ==> */ A_WARN, }, /* Got an I_WAIT_FOR_EVENT */ { /* S_IDLE ==> */ A_LOG, /* S_ELECTION ==> */ A_LOG, /* S_INTEGRATION ==> */ A_LOG, /* S_FINALIZE_JOIN ==> */ A_LOG, /* S_NOT_DC ==> */ A_LOG, /* S_POLICY_ENGINE ==> */ A_LOG, /* S_RECOVERY ==> */ A_LOG, /* S_RELEASE_DC ==> */ A_LOG, /* S_STARTING ==> */ A_LOG, /* S_PENDING ==> */ A_LOG, /* S_STOPPING ==> */ A_LOG, /* S_TERMINATE ==> */ A_LOG, /* S_TRANSITION_ENGINE ==> */ A_LOG, /* S_HALT ==> */ A_WARN, }, /* Got an I_DC_HEARTBEAT */ { /* S_IDLE ==> */ A_ERROR, /* S_ELECTION ==> */ A_WARN | A_ELECTION_VOTE, /* S_INTEGRATION ==> */ A_ERROR, /* S_FINALIZE_JOIN ==> */ A_ERROR, /* S_NOT_DC ==> */ A_NOTHING, /* S_POLICY_ENGINE ==> */ A_ERROR, /* S_RECOVERY ==> */ A_NOTHING, /* S_RELEASE_DC ==> */ A_LOG, /* S_STARTING ==> */ A_LOG, /* S_PENDING ==> */ A_LOG | A_CL_JOIN_ANNOUNCE, /* S_STOPPING ==> */ A_NOTHING, /* S_TERMINATE ==> */ A_NOTHING, /* S_TRANSITION_ENGINE ==> */ A_ERROR, /* S_HALT ==> */ A_WARN, }, /* Got an I_LRM_EVENT */ { /* S_IDLE ==> */ A_LRM_EVENT, /* S_ELECTION ==> */ A_LRM_EVENT, /* S_INTEGRATION ==> */ A_LRM_EVENT, /* S_FINALIZE_JOIN ==> */ A_LRM_EVENT, /* S_NOT_DC ==> */ A_LRM_EVENT, /* S_POLICY_ENGINE ==> */ A_LRM_EVENT, /* S_RECOVERY ==> */ A_LRM_EVENT, /* S_RELEASE_DC ==> */ A_LRM_EVENT, /* S_STARTING ==> */ A_LRM_EVENT, /* S_PENDING ==> */ A_LRM_EVENT, /* S_STOPPING ==> */ A_LRM_EVENT, /* S_TERMINATE ==> */ A_LRM_EVENT, /* S_TRANSITION_ENGINE ==> */ A_LRM_EVENT, /* S_HALT ==> */ A_WARN, }, /* For everyone ending up in S_PENDING, (re)start the DC timer and wait for I_JOIN_OFFER or I_NOT_DC */ /* Got an I_PENDING */ { /* S_IDLE ==> */ O_RELEASE | O_DC_TIMER_RESTART, /* S_ELECTION ==> */ O_RELEASE | O_DC_TIMER_RESTART, /* S_INTEGRATION ==> */ O_RELEASE | O_DC_TIMER_RESTART, /* S_FINALIZE_JOIN ==> */ O_RELEASE | O_DC_TIMER_RESTART, /* S_NOT_DC ==> */ A_LOG | O_DC_TIMER_RESTART, /* S_POLICY_ENGINE ==> */ O_RELEASE | O_DC_TIMER_RESTART, /* S_RECOVERY ==> */ A_WARN, /* S_RELEASE_DC ==> */ A_WARN | O_DC_TIMER_RESTART, /* S_STARTING ==> */ A_LOG | A_DC_TIMER_START | A_CL_JOIN_QUERY, /* S_PENDING ==> */ A_LOG | O_DC_TIMER_RESTART, /* S_STOPPING ==> */ A_WARN, /* S_TERMINATE ==> */ A_WARN, /* S_TRANSITION_ENGINE ==> */ O_RELEASE | O_DC_TIMER_RESTART, /* S_HALT ==> */ A_WARN, }, /* Got an I_HALT */ { /* S_IDLE ==> */ A_WARN, /* S_ELECTION ==> */ A_WARN, /* S_INTEGRATION ==> */ A_WARN, /* S_FINALIZE_JOIN ==> */ A_WARN, /* S_NOT_DC ==> */ A_WARN, /* S_POLICY_ENGINE ==> */ A_WARN, /* S_RECOVERY ==> */ A_WARN, /* S_RELEASE_DC ==> */ A_WARN, /* S_STARTING ==> */ A_WARN, /* S_PENDING ==> */ A_WARN, /* S_STOPPING ==> */ A_WARN, /* S_TERMINATE ==> */ A_WARN, /* S_TRANSITION_ENGINE ==> */ A_WARN, /* S_HALT ==> */ A_WARN, }, }; #endif pacemaker-master/crmd/fsa_proto.h000066400000000000000000000237621217637305600174150ustar00rootroot00000000000000/* * Copyright (C) 2004 Andrew Beekhof * * 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 2 of the License, or (at your option) any later version. * * This software 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 library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef XML_FSA_PROTO__H # define XML_FSA_PROTO__H extern xmlNode *do_lrm_query(gboolean, const char *node_name); /* A_READCONFIG */ void do_read_config(long long action, enum crmd_fsa_cause cause, enum crmd_fsa_state cur_state, enum crmd_fsa_input current_input, fsa_data_t * msg_data); /* A_PE_INVOKE */ void do_pe_invoke(long long action, enum crmd_fsa_cause cause, enum crmd_fsa_state cur_state, enum crmd_fsa_input current_input, fsa_data_t * msg_data); /* A_ERROR */ void do_error(long long action, enum crmd_fsa_cause cause, enum crmd_fsa_state cur_state, enum crmd_fsa_input cur_input, fsa_data_t * msg_data); /* A_LOG */ void do_log(long long action, enum crmd_fsa_cause cause, enum crmd_fsa_state cur_state, enum crmd_fsa_input cur_input, fsa_data_t * msg_data); /* A_STARTUP */ void do_startup(long long action, enum crmd_fsa_cause cause, enum crmd_fsa_state cur_state, enum crmd_fsa_input cur_input, fsa_data_t * msg_data); /* A_CIB_START, STOP, RESTART */ void do_cib_control(long long action, enum crmd_fsa_cause cause, enum crmd_fsa_state cur_state, enum crmd_fsa_input cur_input, fsa_data_t * msg_data); /* A_HA_CONNECT */ void do_ha_control(long long action, enum crmd_fsa_cause cause, enum crmd_fsa_state cur_state, enum crmd_fsa_input cur_input, fsa_data_t * msg_data); /* A_CCM_CONNECT */ void do_ccm_control(long long action, enum crmd_fsa_cause cause, enum crmd_fsa_state cur_state, enum crmd_fsa_input cur_input, fsa_data_t * msg_data); /* A_LRM_CONNECT */ void do_lrm_control(long long action, enum crmd_fsa_cause cause, enum crmd_fsa_state cur_state, enum crmd_fsa_input cur_input, fsa_data_t * msg_data); /* A_PE_START, STOP, RESTART */ void do_pe_control(long long action, enum crmd_fsa_cause cause, enum crmd_fsa_state cur_state, enum crmd_fsa_input cur_input, fsa_data_t * msg_data); /* A_TE_START, STOP, RESTART */ void do_te_control(long long action, enum crmd_fsa_cause cause, enum crmd_fsa_state cur_state, enum crmd_fsa_input cur_input, fsa_data_t * msg_data); /* A_STARTED */ void do_started(long long action, enum crmd_fsa_cause cause, enum crmd_fsa_state cur_state, enum crmd_fsa_input cur_input, fsa_data_t * msg_data); /* A_MSG_ROUTE */ void do_msg_route(long long action, enum crmd_fsa_cause cause, enum crmd_fsa_state cur_state, enum crmd_fsa_input cur_input, fsa_data_t * msg_data); /* A_RECOVER */ void do_recover(long long action, enum crmd_fsa_cause cause, enum crmd_fsa_state cur_state, enum crmd_fsa_input cur_input, fsa_data_t * msg_data); /* A_ELECTION_VOTE */ void do_election_vote(long long action, enum crmd_fsa_cause cause, enum crmd_fsa_state cur_state, enum crmd_fsa_input cur_input, fsa_data_t * msg_data); /* A_ELECTION_COUNT */ void do_election_count_vote(long long action, enum crmd_fsa_cause cause, enum crmd_fsa_state cur_state, enum crmd_fsa_input cur_input, fsa_data_t * msg_data); /* A_ELECTION_CHECK */ void do_election_check(long long action, enum crmd_fsa_cause cause, enum crmd_fsa_state cur_state, enum crmd_fsa_input cur_input, fsa_data_t * msg_data); /* A_ELECT_TIMER_START, A_ELECTION_TIMEOUT */ void do_election_timer_ctrl(long long action, enum crmd_fsa_cause cause, enum crmd_fsa_state cur_state, enum crmd_fsa_input cur_input, fsa_data_t * msg_data); /* A_DC_TIMER_STOP */ void do_timer_control(long long action, enum crmd_fsa_cause cause, enum crmd_fsa_state cur_state, enum crmd_fsa_input cur_input, fsa_data_t * msg_data); # if SUPPORT_HEARTBEAT /* A_CCM_UPDATE_CACHE */ void do_ccm_update_cache(enum crmd_fsa_cause cause, enum crmd_fsa_state cur_state, oc_ed_t event, const oc_ev_membership_t * oc, xmlNode * xml); # endif /* A_CCM_EVENT */ void do_ccm_event(long long action, enum crmd_fsa_cause cause, enum crmd_fsa_state cur_state, enum crmd_fsa_input cur_input, fsa_data_t * msg_data); /* A_DC_TAKEOVER */ void do_dc_takeover(long long action, enum crmd_fsa_cause cause, enum crmd_fsa_state cur_state, enum crmd_fsa_input cur_input, fsa_data_t * msg_data); /* A_DC_RELEASE */ void do_dc_release(long long action, enum crmd_fsa_cause cause, enum crmd_fsa_state cur_state, enum crmd_fsa_input cur_input, fsa_data_t * msg_data); /* A_DC_JOIN_OFFER_ALL */ void do_dc_join_offer_all(long long action, enum crmd_fsa_cause cause, enum crmd_fsa_state cur_state, enum crmd_fsa_input cur_input, fsa_data_t * msg_data); /* A_DC_JOIN_OFFER_ONE */ void do_dc_join_offer_one(long long action, enum crmd_fsa_cause cause, enum crmd_fsa_state cur_state, enum crmd_fsa_input cur_input, fsa_data_t * msg_data); /* A_DC_JOIN_ACK */ void do_dc_join_ack(long long action, enum crmd_fsa_cause cause, enum crmd_fsa_state cur_state, enum crmd_fsa_input cur_input, fsa_data_t * msg_data); /* A_DC_JOIN_REQ */ void do_dc_join_filter_offer(long long action, enum crmd_fsa_cause cause, enum crmd_fsa_state cur_state, enum crmd_fsa_input cur_input, fsa_data_t * msg_data); /* A_DC_JOIN_FINALIZE */ void do_dc_join_finalize(long long action, enum crmd_fsa_cause cause, enum crmd_fsa_state cur_state, enum crmd_fsa_input cur_input, fsa_data_t * msg_data); /* A_CL_JOIN_QUERY */ /* is there a DC out there? */ void do_cl_join_query(long long action, enum crmd_fsa_cause cause, enum crmd_fsa_state cur_state, enum crmd_fsa_input current_input, fsa_data_t * msg_data); /* A_CL_JOIN_ANNOUNCE */ void do_cl_join_announce(long long action, enum crmd_fsa_cause cause, enum crmd_fsa_state cur_state, enum crmd_fsa_input current_input, fsa_data_t * msg_data); /* A_CL_JOIN_REQUEST */ void do_cl_join_offer_respond(long long action, enum crmd_fsa_cause cause, enum crmd_fsa_state cur_state, enum crmd_fsa_input current_input, fsa_data_t * msg_data); /* A_CL_JOIN_RESULT */ void do_cl_join_finalize_respond(long long action, enum crmd_fsa_cause cause, enum crmd_fsa_state cur_state, enum crmd_fsa_input current_input, fsa_data_t * msg_data); /* A_UPDATE_NODESTATUS */ void do_update_node_status(long long action, enum crmd_fsa_cause cause, enum crmd_fsa_state cur_state, enum crmd_fsa_input cur_input, fsa_data_t * msg_data); /* A_LRM_INVOKE */ void do_lrm_invoke(long long action, enum crmd_fsa_cause cause, enum crmd_fsa_state cur_state, enum crmd_fsa_input cur_input, fsa_data_t * msg_data); /* A_LRM_EVENT */ void do_lrm_event(long long action, enum crmd_fsa_cause cause, enum crmd_fsa_state cur_state, enum crmd_fsa_input cur_input, fsa_data_t * msg_data); /* A_PE_INVOKE */ void do_pe_invoke(long long action, enum crmd_fsa_cause cause, enum crmd_fsa_state cur_state, enum crmd_fsa_input cur_input, fsa_data_t * msg_data); /* A_TE_INVOKE, A_TE_CANCEL */ void do_te_invoke(long long action, enum crmd_fsa_cause cause, enum crmd_fsa_state cur_state, enum crmd_fsa_input cur_input, fsa_data_t * msg_data); /* A_TE_INVOKE */ void do_te_copyto(long long action, enum crmd_fsa_cause cause, enum crmd_fsa_state cur_state, enum crmd_fsa_input cur_input, fsa_data_t * msg_data); /* A_SHUTDOWN_REQ */ void do_shutdown_req(long long action, enum crmd_fsa_cause cause, enum crmd_fsa_state cur_state, enum crmd_fsa_input cur_input, fsa_data_t * msg_data); /* A_SHUTDOWN */ void do_shutdown(long long action, enum crmd_fsa_cause cause, enum crmd_fsa_state cur_state, enum crmd_fsa_input cur_input, fsa_data_t * msg_data); /* A_STOP */ void do_stop(long long action, enum crmd_fsa_cause cause, enum crmd_fsa_state cur_state, enum crmd_fsa_input cur_input, fsa_data_t * msg_data); /* A_EXIT_0, A_EXIT_1 */ void do_exit(long long action, enum crmd_fsa_cause cause, enum crmd_fsa_state cur_state, enum crmd_fsa_input cur_input, fsa_data_t * msg_data); void do_dc_join_final(long long action, enum crmd_fsa_cause cause, enum crmd_fsa_state cur_state, enum crmd_fsa_input current_input, fsa_data_t * msg_data); #endif pacemaker-master/crmd/heartbeat.c000066400000000000000000000413601217637305600173450ustar00rootroot00000000000000/* * Copyright (C) 2004 Andrew Beekhof * * 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 2 of the License, or (at your option) any later version. * * This software 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 library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ /* put these first so that uuid_t is defined without conflicts */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include void oc_ev_special(const oc_ev_t *, oc_ev_class_t, int); void ccm_event_detail(const oc_ev_membership_t * oc, oc_ed_t event); gboolean crmd_ha_msg_dispatch(ll_cluster_t * cluster_conn, gpointer user_data); void crmd_ccm_msg_callback(oc_ed_t event, void *cookie, size_t size, const void *data); int ccm_dispatch(gpointer user_data); #define CCM_EVENT_DETAIL 0 #define CCM_EVENT_DETAIL_PARTIAL 0 int (*ccm_api_callback_done) (void *cookie) = NULL; int (*ccm_api_handle_event) (const oc_ev_t * token) = NULL; static oc_ev_t *fsa_ev_token; static void *ccm_library = NULL; static int num_ccm_register_fails = 0; static int max_ccm_register_fails = 30; static void ccm_connection_destroy(void *userdata) { } /* A_CCM_CONNECT */ void do_ccm_control(long long action, enum crmd_fsa_cause cause, enum crmd_fsa_state cur_state, enum crmd_fsa_input current_input, fsa_data_t * msg_data) { static struct mainloop_fd_callbacks ccm_fd_callbacks = { .dispatch = ccm_dispatch, .destroy = ccm_connection_destroy, }; if (is_heartbeat_cluster()) { int (*ccm_api_register) (oc_ev_t ** token) = find_library_function(&ccm_library, CCM_LIBRARY, "oc_ev_register", 1); int (*ccm_api_set_callback) (const oc_ev_t * token, oc_ev_class_t class, oc_ev_callback_t * fn, oc_ev_callback_t ** prev_fn) = find_library_function(&ccm_library, CCM_LIBRARY, "oc_ev_set_callback", 1); void (*ccm_api_special) (const oc_ev_t *, oc_ev_class_t, int) = find_library_function(&ccm_library, CCM_LIBRARY, "oc_ev_special", 1); int (*ccm_api_activate) (const oc_ev_t * token, int *fd) = find_library_function(&ccm_library, CCM_LIBRARY, "oc_ev_activate", 1); int (*ccm_api_unregister) (oc_ev_t * token) = find_library_function(&ccm_library, CCM_LIBRARY, "oc_ev_unregister", 1); if (action & A_CCM_DISCONNECT) { set_bit(fsa_input_register, R_CCM_DISCONNECTED); (*ccm_api_unregister) (fsa_ev_token); } if (action & A_CCM_CONNECT) { int ret; int fsa_ev_fd; gboolean did_fail = FALSE; crm_trace("Registering with CCM"); clear_bit(fsa_input_register, R_CCM_DISCONNECTED); ret = (*ccm_api_register) (&fsa_ev_token); if (ret != 0) { crm_warn("CCM registration failed"); did_fail = TRUE; } if (did_fail == FALSE) { crm_trace("Setting up CCM callbacks"); ret = (*ccm_api_set_callback) (fsa_ev_token, OC_EV_MEMB_CLASS, crmd_ccm_msg_callback, NULL); if (ret != 0) { crm_warn("CCM callback not set"); did_fail = TRUE; } } if (did_fail == FALSE) { (*ccm_api_special) (fsa_ev_token, OC_EV_MEMB_CLASS, 0 /*don't care */ ); crm_trace("Activating CCM token"); ret = (*ccm_api_activate) (fsa_ev_token, &fsa_ev_fd); if (ret != 0) { crm_warn("CCM Activation failed"); did_fail = TRUE; } } if (did_fail) { num_ccm_register_fails++; (*ccm_api_unregister) (fsa_ev_token); if (num_ccm_register_fails < max_ccm_register_fails) { crm_warn("CCM Connection failed" " %d times (%d max)", num_ccm_register_fails, max_ccm_register_fails); crm_timer_start(wait_timer); crmd_fsa_stall(FALSE); return; } else { crm_err("CCM Activation failed %d (max) times", num_ccm_register_fails); register_fsa_error(C_FSA_INTERNAL, I_FAIL, NULL); return; } } crm_info("CCM connection established... waiting for first callback"); mainloop_add_fd("heartbeat-ccm", G_PRIORITY_HIGH, fsa_ev_fd, fsa_ev_token, &ccm_fd_callbacks); } } if (action & ~(A_CCM_CONNECT | A_CCM_DISCONNECT)) { crm_err("Unexpected action %s in %s", fsa_action2string(action), __FUNCTION__); } } void ccm_event_detail(const oc_ev_membership_t * oc, oc_ed_t event) { int lpc; gboolean member = FALSE; member = FALSE; crm_trace("-----------------------"); crm_info("%s: trans=%d, nodes=%d, new=%d, lost=%d n_idx=%d, " "new_idx=%d, old_idx=%d", ccm_event_name(event), oc->m_instance, oc->m_n_member, oc->m_n_in, oc->m_n_out, oc->m_memb_idx, oc->m_in_idx, oc->m_out_idx); #if !CCM_EVENT_DETAIL_PARTIAL for (lpc = 0; lpc < oc->m_n_member; lpc++) { crm_info("\tCURRENT: %s [nodeid=%d, born=%d]", oc->m_array[oc->m_memb_idx + lpc].node_uname, oc->m_array[oc->m_memb_idx + lpc].node_id, oc->m_array[oc->m_memb_idx + lpc].node_born_on); if (safe_str_eq(fsa_our_uname, oc->m_array[oc->m_memb_idx + lpc].node_uname)) { member = TRUE; } } if (member == FALSE) { crm_warn("MY NODE IS NOT IN CCM THE MEMBERSHIP LIST"); } #endif for (lpc = 0; lpc < (int)oc->m_n_in; lpc++) { crm_info("\tNEW: %s [nodeid=%d, born=%d]", oc->m_array[oc->m_in_idx + lpc].node_uname, oc->m_array[oc->m_in_idx + lpc].node_id, oc->m_array[oc->m_in_idx + lpc].node_born_on); } for (lpc = 0; lpc < (int)oc->m_n_out; lpc++) { crm_info("\tLOST: %s [nodeid=%d, born=%d]", oc->m_array[oc->m_out_idx + lpc].node_uname, oc->m_array[oc->m_out_idx + lpc].node_id, oc->m_array[oc->m_out_idx + lpc].node_born_on); } crm_trace("-----------------------"); } /* A_CCM_UPDATE_CACHE */ /* * Take the opportunity to update the node status in the CIB as well */ void do_ccm_update_cache(enum crmd_fsa_cause cause, enum crmd_fsa_state cur_state, oc_ed_t event, const oc_ev_membership_t * oc, xmlNode * xml) { unsigned long long instance = 0; unsigned int lpc = 0; if (is_heartbeat_cluster()) { CRM_ASSERT(oc != NULL); instance = oc->m_instance; } CRM_ASSERT(crm_peer_seq <= instance); switch (cur_state) { case S_STOPPING: case S_TERMINATE: case S_HALT: crm_debug("Ignoring %s CCM event %llu, we're in state %s", ccm_event_name(event), instance, fsa_state2string(cur_state)); return; case S_ELECTION: register_fsa_action(A_ELECTION_CHECK); break; default: break; } if (is_heartbeat_cluster()) { ccm_event_detail(oc, event); /*--*-- Recently Dead Member Nodes --*--*/ for (lpc = 0; lpc < oc->m_n_out; lpc++) { crm_update_ccm_node(oc, lpc + oc->m_out_idx, CRM_NODE_LOST, instance); } /*--*-- All Member Nodes --*--*/ for (lpc = 0; lpc < oc->m_n_member; lpc++) { crm_update_ccm_node(oc, lpc + oc->m_memb_idx, CRM_NODE_ACTIVE, instance); } } if (event == OC_EV_MS_EVICTED) { crm_node_t *peer = crm_get_peer(0, fsa_our_uname); crm_update_peer_state(__FUNCTION__, peer, CRM_NODE_EVICTED, 0); /* todo: drop back to S_PENDING instead */ /* get out... NOW! * * go via the error recovery process so that HA will * restart us if required */ register_fsa_error_adv(cause, I_ERROR, NULL, NULL, __FUNCTION__); } post_cache_update(instance); return; } int ccm_dispatch(gpointer user_data) { int rc = 0; oc_ev_t *ccm_token = (oc_ev_t *) user_data; gboolean was_error = FALSE; crm_trace("Invoked"); if (ccm_api_handle_event == NULL) { ccm_api_handle_event = find_library_function(&ccm_library, CCM_LIBRARY, "oc_ev_handle_event", 1); } rc = (*ccm_api_handle_event) (ccm_token); if (rc != 0) { if (is_set(fsa_input_register, R_CCM_DISCONNECTED) == FALSE) { /* we signed out, so this is expected */ register_fsa_input(C_CCM_CALLBACK, I_ERROR, NULL); crm_err("CCM connection appears to have failed: rc=%d.", rc); } was_error = TRUE; } trigger_fsa(fsa_source); if (was_error) { return -1; } return 0; } void crmd_ccm_msg_callback(oc_ed_t event, void *cookie, size_t size, const void *data) { gboolean update_cache = FALSE; const oc_ev_membership_t *membership = data; gboolean update_quorum = FALSE; crm_trace("Invoked"); CRM_ASSERT(data != NULL); crm_info("Quorum %s after event=%s (id=%d)", ccm_have_quorum(event) ? "(re)attained" : "lost", ccm_event_name(event), membership->m_instance); if (crm_peer_seq > membership->m_instance) { crm_err("Membership instance ID went backwards! %llu->%d", crm_peer_seq, membership->m_instance); CRM_ASSERT(crm_peer_seq <= membership->m_instance); return; } /* * OC_EV_MS_NEW_MEMBERSHIP: membership with quorum * OC_EV_MS_MS_INVALID: membership without quorum * OC_EV_MS_NOT_PRIMARY: previous membership no longer valid * OC_EV_MS_PRIMARY_RESTORED: previous membership restored * OC_EV_MS_EVICTED: the client is evicted from ccm. */ switch (event) { case OC_EV_MS_NEW_MEMBERSHIP: case OC_EV_MS_INVALID: update_cache = TRUE; update_quorum = TRUE; break; case OC_EV_MS_NOT_PRIMARY: break; case OC_EV_MS_PRIMARY_RESTORED: update_cache = TRUE; crm_peer_seq = membership->m_instance; break; case OC_EV_MS_EVICTED: update_quorum = TRUE; register_fsa_input(C_FSA_INTERNAL, I_STOP, NULL); crm_err("Shutting down after CCM event: %s", ccm_event_name(event)); break; default: crm_err("Unknown CCM event: %d", event); } if (update_quorum) { crm_have_quorum = ccm_have_quorum(event); if (crm_have_quorum == FALSE) { /* did we just loose quorum? */ if (fsa_has_quorum) { crm_info("Quorum lost: %s", ccm_event_name(event)); } } crm_update_quorum(crm_have_quorum, FALSE); } if (update_cache) { crm_trace("Updating cache after event %s", ccm_event_name(event)); do_ccm_update_cache(C_CCM_CALLBACK, fsa_state, event, data, NULL); } else if (event != OC_EV_MS_NOT_PRIMARY) { crm_peer_seq = membership->m_instance; register_fsa_action(A_TE_CANCEL); } if (ccm_api_callback_done == NULL) { ccm_api_callback_done = find_library_function(&ccm_library, CCM_LIBRARY, "oc_ev_callback_done", 1); } (*ccm_api_callback_done) (cookie); return; } void crmd_ha_status_callback(const char *node, const char *status, void *private) { xmlNode *update = NULL; crm_node_t *peer = NULL; crm_notice("Status update: Node %s now has status [%s]", node, status); peer = crm_get_peer(0, node); if (safe_str_eq(status, PINGSTATUS)) { return; } if (safe_str_eq(status, DEADSTATUS)) { /* this node is toast */ crm_update_peer_proc(__FUNCTION__, peer, crm_proc_heartbeat, OFFLINESTATUS); } else { crm_update_peer_proc(__FUNCTION__, peer, crm_proc_heartbeat, ONLINESTATUS); } trigger_fsa(fsa_source); if (AM_I_DC) { update = do_update_node_cib(peer, node_update_cluster, NULL, __FUNCTION__); fsa_cib_anon_update(XML_CIB_TAG_STATUS, update, cib_scope_local | cib_quorum_override | cib_can_create); free_xml(update); } } void crmd_client_status_callback(const char *node, const char *client, const char *status, void *private) { crm_node_t *peer = NULL; crm_trace("Invoked"); if (safe_str_neq(client, CRM_SYSTEM_CRMD)) { return; } set_bit(fsa_input_register, R_PEER_DATA); crm_notice("Status update: Client %s/%s now has status [%s] (DC=%s)", node, client, status, AM_I_DC ? "true" : "false"); peer = crm_get_peer(0, node); if (safe_str_eq(status, ONLINESTATUS)) { /* remove the cached value in case it changed */ crm_trace("Uncaching UUID for %s", node); free(peer->uuid); peer->uuid = NULL; } crm_update_peer_proc(__FUNCTION__, peer, crm_proc_crmd, status); if (AM_I_DC) { xmlNode *update = NULL; crm_trace("Got client status callback"); update = do_update_node_cib(peer, node_update_peer, NULL, __FUNCTION__); fsa_cib_anon_update(XML_CIB_TAG_STATUS, update, cib_scope_local | cib_quorum_override | cib_can_create); free_xml(update); } } void crmd_ha_msg_callback(HA_Message * hamsg, void *private_data) { int level = LOG_DEBUG; crm_node_t *from_node = NULL; xmlNode *msg = convert_ha_message(NULL, hamsg, __FUNCTION__); const char *from = crm_element_value(msg, F_ORIG); const char *op = crm_element_value(msg, F_CRM_TASK); const char *sys_from = crm_element_value(msg, F_CRM_SYS_FROM); CRM_CHECK(from != NULL, crm_log_xml_err(msg, "anon"); goto bail); crm_trace("HA[inbound]: %s from %s", op, from); if (crm_peer_cache == NULL || crm_active_peers() == 0) { crm_debug("Ignoring HA messages until we are" " connected to the CCM (%s op from %s)", op, from); crm_log_xml_trace(msg, "HA[inbound]: Ignore (No CCM)"); goto bail; } from_node = crm_get_peer(0, from); if (crm_is_peer_active(from_node) == FALSE) { if (safe_str_eq(op, CRM_OP_VOTE)) { level = LOG_WARNING; } else if (AM_I_DC && safe_str_eq(op, CRM_OP_JOIN_ANNOUNCE)) { level = LOG_WARNING; } else if (safe_str_eq(sys_from, CRM_SYSTEM_DC)) { level = LOG_WARNING; } do_crm_log(level, "Ignoring HA message (op=%s) from %s: not in our" " membership list (size=%d)", op, from, crm_active_peers()); crm_log_xml_trace(msg, "HA[inbound]: CCM Discard"); } else { crmd_ha_msg_filter(msg); } bail: free_xml(msg); return; } gboolean crmd_ha_msg_dispatch(ll_cluster_t * cluster_conn, gpointer user_data) { IPC_Channel *channel = NULL; gboolean stay_connected = TRUE; crm_trace("Invoked"); if (cluster_conn != NULL) { channel = cluster_conn->llc_ops->ipcchan(cluster_conn); } CRM_CHECK(cluster_conn != NULL,;); CRM_CHECK(channel != NULL,;); if (channel != NULL && IPC_ISRCONN(channel)) { if (cluster_conn->llc_ops->msgready(cluster_conn) == 0) { crm_trace("no message ready yet"); } /* invoke the callbacks but dont block */ cluster_conn->llc_ops->rcvmsg(cluster_conn, 0); } if (channel == NULL || channel->ch_status != IPC_CONNECT) { if (is_set(fsa_input_register, R_HA_DISCONNECTED) == FALSE) { crm_crit("Lost connection to heartbeat service."); } else { crm_info("Lost connection to heartbeat service."); } trigger_fsa(fsa_source); stay_connected = FALSE; } return stay_connected; } pacemaker-master/crmd/join_client.c000066400000000000000000000236151217637305600177060ustar00rootroot00000000000000/* * Copyright (C) 2004 Andrew Beekhof * * 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 2 of the License, or (at your option) any later version. * * This software 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 library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include #include #include #include #include #include int reannounce_count = 0; void join_query_callback(xmlNode * msg, int call_id, int rc, xmlNode * output, void *user_data); extern ha_msg_input_t *copy_ha_msg_input(ha_msg_input_t * orig); /* A_CL_JOIN_QUERY */ /* is there a DC out there? */ void do_cl_join_query(long long action, enum crmd_fsa_cause cause, enum crmd_fsa_state cur_state, enum crmd_fsa_input current_input, fsa_data_t * msg_data) { xmlNode *req = create_request(CRM_OP_JOIN_ANNOUNCE, NULL, NULL, CRM_SYSTEM_DC, CRM_SYSTEM_CRMD, NULL); sleep(1); /* give the CCM time to propogate to the DC */ update_dc(NULL); /* Unset any existing value so that the result is not discarded */ crm_debug("Querying for a DC"); send_cluster_message(NULL, crm_msg_crmd, req, FALSE); free_xml(req); } /* A_CL_JOIN_ANNOUNCE */ /* this is kind of a workaround for the fact that we may not be around * or are otherwise unable to reply when the DC sends out A_WELCOME_ALL */ void do_cl_join_announce(long long action, enum crmd_fsa_cause cause, enum crmd_fsa_state cur_state, enum crmd_fsa_input current_input, fsa_data_t * msg_data) { /* Once we hear from the DC, we can stop the timer * * This timer was started either on startup or when a node * left the CCM list */ /* dont announce if we're in one of these states */ if (cur_state != S_PENDING) { crm_warn("Do not announce ourselves in state %s", fsa_state2string(cur_state)); return; } if (AM_I_OPERATIONAL) { /* send as a broadcast */ xmlNode *req = create_request(CRM_OP_JOIN_ANNOUNCE, NULL, NULL, CRM_SYSTEM_DC, CRM_SYSTEM_CRMD, NULL); crm_debug("Announcing availability"); update_dc(NULL); send_cluster_message(NULL, crm_msg_crmd, req, FALSE); free_xml(req); } else { /* Delay announce until we have finished local startup */ crm_warn("Delaying announce until local startup is complete"); return; } } static int query_call_id = 0; /* A_CL_JOIN_REQUEST */ /* aka. accept the welcome offer */ void do_cl_join_offer_respond(long long action, enum crmd_fsa_cause cause, enum crmd_fsa_state cur_state, enum crmd_fsa_input current_input, fsa_data_t * msg_data) { ha_msg_input_t *input = fsa_typed_data(fsa_dt_ha_msg); const char *welcome_from = crm_element_value(input->msg, F_CRM_HOST_FROM); const char *join_id = crm_element_value(input->msg, F_CRM_JOIN_ID); #if 0 if (we are sick) { log error; /* save the request for later? */ return; } #endif crm_trace("Accepting join offer from %s: join-%s", welcome_from, crm_element_value(input->msg, F_CRM_JOIN_ID)); /* we only ever want the last one */ if (query_call_id > 0) { crm_trace("Cancelling previous join query: %d", query_call_id); remove_cib_op_callback(query_call_id, FALSE); query_call_id = 0; } if (update_dc(input->msg) == FALSE) { crm_warn("Discarding offer from %s (expected %s)", welcome_from, fsa_our_dc); return; } CRM_LOG_ASSERT(input != NULL); query_call_id = fsa_cib_conn->cmds->query(fsa_cib_conn, NULL, NULL, cib_scope_local | cib_no_children); fsa_register_cib_callback(query_call_id, FALSE, strdup(join_id), join_query_callback); crm_trace("Registered join query callback: %d", query_call_id); register_fsa_action(A_DC_TIMER_STOP); } void join_query_callback(xmlNode * msg, int call_id, int rc, xmlNode * output, void *user_data) { xmlNode *local_cib = NULL; char *join_id = user_data; xmlNode *generation = create_xml_node(NULL, XML_CIB_TAG_GENERATION_TUPPLE); CRM_LOG_ASSERT(join_id != NULL); query_call_id = 0; if (rc == pcmk_ok) { local_cib = output; CRM_LOG_ASSERT(safe_str_eq(crm_element_name(local_cib), XML_TAG_CIB)); } if (local_cib != NULL) { xmlNode *reply = NULL; crm_debug("Respond to join offer join-%s", join_id); crm_debug("Acknowledging %s as our DC", fsa_our_dc); copy_in_properties(generation, local_cib); reply = create_request(CRM_OP_JOIN_REQUEST, generation, fsa_our_dc, CRM_SYSTEM_DC, CRM_SYSTEM_CRMD, NULL); crm_xml_add(reply, F_CRM_JOIN_ID, join_id); if (fsa_our_dc) { send_cluster_message(crm_get_peer(0, fsa_our_dc), crm_msg_crmd, reply, TRUE); } else { crm_warn("No DC for join-%s", join_id); send_cluster_message(NULL, crm_msg_crmd, reply, TRUE); } free_xml(reply); } else { crm_err("Could not retrieve Generation to attach to our" " join acknowledgement: %s", pcmk_strerror(rc)); register_fsa_error_adv(C_FSA_INTERNAL, I_ERROR, NULL, NULL, __FUNCTION__); } free(join_id); free_xml(generation); } /* A_CL_JOIN_RESULT */ /* aka. this is notification that we have (or have not) been accepted */ void do_cl_join_finalize_respond(long long action, enum crmd_fsa_cause cause, enum crmd_fsa_state cur_state, enum crmd_fsa_input current_input, fsa_data_t * msg_data) { xmlNode *tmp1 = NULL; gboolean was_nack = TRUE; static gboolean first_join = TRUE; ha_msg_input_t *input = fsa_typed_data(fsa_dt_ha_msg); int join_id = -1; const char *op = crm_element_value(input->msg, F_CRM_TASK); const char *ack_nack = crm_element_value(input->msg, CRM_OP_JOIN_ACKNAK); const char *welcome_from = crm_element_value(input->msg, F_CRM_HOST_FROM); if (safe_str_neq(op, CRM_OP_JOIN_ACKNAK)) { crm_trace("Ignoring op=%s message", op); return; } /* calculate if it was an ack or a nack */ if (crm_is_true(ack_nack)) { was_nack = FALSE; } crm_element_value_int(input->msg, F_CRM_JOIN_ID, &join_id); if (was_nack) { crm_err("Join (join-%d) with leader %s failed (NACK'd): Shutting down", join_id, welcome_from); register_fsa_error(C_FSA_INTERNAL, I_ERROR, NULL); return; } if (AM_I_DC == FALSE && safe_str_eq(welcome_from, fsa_our_uname)) { crm_warn("Discarding our own welcome - we're no longer the DC"); return; } if (update_dc(input->msg) == FALSE) { crm_warn("Discarding %s from %s (expected %s)", op, welcome_from, fsa_our_dc); return; } /* send our status section to the DC */ crm_debug("Confirming join join-%d: %s", join_id, crm_element_value(input->msg, F_CRM_TASK)); tmp1 = do_lrm_query(TRUE, fsa_our_uname); if (tmp1 != NULL) { xmlNode *reply = create_request(CRM_OP_JOIN_CONFIRM, tmp1, fsa_our_dc, CRM_SYSTEM_DC, CRM_SYSTEM_CRMD, NULL); crm_xml_add_int(reply, F_CRM_JOIN_ID, join_id); crm_debug("join-%d: Join complete." " Sending local LRM status to %s", join_id, fsa_our_dc); if (first_join) { first_join = FALSE; /* * Clear any previous transient node attribute and lrm operations * * Corosync has a nasty habit of not being able to tell if a * node is returning or didn't leave in the first place. * This confuses Pacemaker because it never gets a "node up" * event which is normally used to clean up the status section. * * Do not remove the resources though, they'll be cleaned up in * do_dc_join_ack(). Removing them here creates a race * condition if the crmd is being recovered. * Instead of a list of active resources from the lrmd * we may end up with a blank status section. * If we are _NOT_ lucky, we will probe for the "wrong" instance * of anonymous clones and end up with multiple active * instances on the machine. */ erase_status_tag(fsa_our_uname, XML_TAG_TRANSIENT_NODEATTRS, 0); /* Just in case attrd was still around too */ if (is_not_set(fsa_input_register, R_SHUTDOWN)) { update_attrd(fsa_our_uname, "terminate", NULL, NULL, FALSE); update_attrd(fsa_our_uname, XML_CIB_ATTR_SHUTDOWN, NULL, NULL, FALSE); } } send_cluster_message(crm_get_peer(0, fsa_our_dc), crm_msg_crmd, reply, TRUE); free_xml(reply); if (AM_I_DC == FALSE) { register_fsa_input_adv(cause, I_NOT_DC, NULL, A_NOTHING, TRUE, __FUNCTION__); update_attrd(NULL, NULL, NULL, NULL, FALSE); } free_xml(tmp1); } else { crm_err("Could not send our LRM state to the DC"); register_fsa_error(C_FSA_INTERNAL, I_FAIL, NULL); } } pacemaker-master/crmd/join_dc.c000066400000000000000000000567271217637305600170300ustar00rootroot00000000000000/* * Copyright (C) 2004 Andrew Beekhof * * 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 2 of the License, or (at your option) any later version. * * This software 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 library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include #include #include #include #include #include #include "tengine.h" char *max_epoch = NULL; char *max_generation_from = NULL; xmlNode *max_generation_xml = NULL; void initialize_join(gboolean before); void finalize_join_for(gpointer key, gpointer value, gpointer user_data); void finalize_sync_callback(xmlNode * msg, int call_id, int rc, xmlNode * output, void *user_data); gboolean check_join_state(enum crmd_fsa_state cur_state, const char *source); static int current_join_id = 0; unsigned long long saved_ccm_membership_id = 0; void crm_update_peer_join(const char *source, crm_node_t * node, enum crm_join_phase phase) { enum crm_join_phase last = 0; if(node == NULL) { crm_err("%s: Could not set join-%u to %d for NULL", source, current_join_id, phase); return; } last = node->join; if(phase == last) { crm_trace("%s: Node %s[%u] - join-%u phase still %u", source, node->uname, node->id, current_join_id, last); } else if (phase <= crm_join_none) { node->join = phase; crm_info("%s: Node %s[%u] - join-%u phase %u -> %u", source, node->uname, node->id, current_join_id, last, phase); } else if(phase == last + 1) { node->join = phase; crm_info("%s: Node %s[%u] - join-%u phase %u -> %u", source, node->uname, node->id, current_join_id, last, phase); } else { crm_err("%s: Node %s[%u] - join-%u phase cannot transition from %u to %u", source, node->uname, node->id, current_join_id, last, phase); } } void initialize_join(gboolean before) { GHashTableIter iter; crm_node_t *peer = NULL; /* clear out/reset a bunch of stuff */ crm_debug("join-%d: Initializing join data (flag=%s)", current_join_id, before ? "true" : "false"); g_hash_table_iter_init(&iter, crm_peer_cache); while (g_hash_table_iter_next(&iter, NULL, (gpointer *) &peer)) { crm_update_peer_join(__FUNCTION__, peer, crm_join_none); } if (before) { if (max_generation_from != NULL) { free(max_generation_from); max_generation_from = NULL; } if (max_generation_xml != NULL) { free_xml(max_generation_xml); max_generation_xml = NULL; } clear_bit(fsa_input_register, R_HAVE_CIB); clear_bit(fsa_input_register, R_CIB_ASKED); } } static void join_make_offer(gpointer key, gpointer value, gpointer user_data) { const char *join_to = NULL; const crm_node_t *member = value; CRM_ASSERT(member != NULL); if (crm_is_peer_active(member) == FALSE) { crm_trace("Not making an offer to %s: not active", member->uname); return; } join_to = member->uname; if (join_to == NULL) { crm_err("No recipient for welcome message"); return; } if (saved_ccm_membership_id != crm_peer_seq) { saved_ccm_membership_id = crm_peer_seq; crm_info("Making join offers based on membership %llu", crm_peer_seq); } if(user_data && member->join > crm_join_none) { crm_info("Skipping %s: already known %d", member->uname, member->join); return; } crm_update_peer_join(__FUNCTION__, (crm_node_t*)member, crm_join_none); if (crm_is_peer_active(member)) { crm_node_t *peer = crm_get_peer(0, join_to); xmlNode *offer = create_request(CRM_OP_JOIN_OFFER, NULL, join_to, CRM_SYSTEM_CRMD, CRM_SYSTEM_DC, NULL); crm_xml_add_int(offer, F_CRM_JOIN_ID, current_join_id); /* send the welcome */ crm_info("join-%d: Sending offer to %s", current_join_id, join_to); send_cluster_message(peer, crm_msg_crmd, offer, TRUE); free_xml(offer); crm_update_peer_join(__FUNCTION__, peer, crm_join_welcomed); /* crm_update_peer_expected(__FUNCTION__, member, CRMD_JOINSTATE_PENDING); */ } else { crm_info("Peer process on %s is not active (yet?): %.8lx %d", join_to, (long)member->processes, g_hash_table_size(crm_peer_cache)); } } /* A_DC_JOIN_OFFER_ALL */ void do_dc_join_offer_all(long long action, enum crmd_fsa_cause cause, enum crmd_fsa_state cur_state, enum crmd_fsa_input current_input, fsa_data_t * msg_data) { /* reset everyones status back to down or in_ccm in the CIB * * any nodes that are active in the CIB but not in the CCM list * will be seen as offline by the PE anyway */ current_join_id++; initialize_join(TRUE); /* do_update_cib_nodes(TRUE, __FUNCTION__); */ update_dc(NULL); if (cause == C_HA_MESSAGE && current_input == I_NODE_JOIN) { crm_info("A new node joined the cluster"); } g_hash_table_foreach(crm_peer_cache, join_make_offer, NULL); /* dont waste time by invoking the PE yet; */ crm_info("join-%d: Waiting on %d outstanding join acks", current_join_id, crmd_join_phase_count(crm_join_welcomed)); } /* A_DC_JOIN_OFFER_ONE */ void do_dc_join_offer_one(long long action, enum crmd_fsa_cause cause, enum crmd_fsa_state cur_state, enum crmd_fsa_input current_input, fsa_data_t * msg_data) { crm_node_t *member; ha_msg_input_t *welcome = NULL; const char *op = NULL; const char *join_to = NULL; if (msg_data->data) { welcome = fsa_typed_data(fsa_dt_ha_msg); } else { crm_info("An unknown node joined - (re-)offer to any unconfirmed nodes"); g_hash_table_foreach(crm_peer_cache, join_make_offer, &member); check_join_state(cur_state, __FUNCTION__); return; } if (welcome == NULL) { crm_err("Attempt to send welcome message without a message to reply to!"); return; } join_to = crm_element_value(welcome->msg, F_CRM_HOST_FROM); if (join_to == NULL) { crm_err("Attempt to send welcome message without a host to reply to!"); return; } member = crm_get_peer(0, join_to); op = crm_element_value(welcome->msg, F_CRM_TASK); if (join_to != NULL && (cur_state == S_INTEGRATION || cur_state == S_FINALIZE_JOIN)) { /* note: it _is_ possible that a node will have been * sick or starting up when the original offer was made. * however, it will either re-announce itself in due course * _or_ we can re-store the original offer on the client. */ crm_trace("(Re-)offering membership to %s...", join_to); } crm_info("join-%d: Processing %s request from %s in state %s", current_join_id, op, join_to, fsa_state2string(cur_state)); crm_update_peer_join(__FUNCTION__, member, crm_join_none); join_make_offer(NULL, member, NULL); /* always offer to the DC (ourselves) * this ensures the correct value for max_generation_from */ member = crm_get_peer(0, fsa_our_uname); join_make_offer(NULL, member, NULL); /* this was a genuine join request, cancel any existing * transition and invoke the PE */ abort_transition(INFINITY, tg_restart, "Node join", NULL); /* dont waste time by invoking the pe yet; */ crm_debug("Waiting on %d outstanding join acks for join-%d", crmd_join_phase_count(crm_join_welcomed), current_join_id); } static int compare_int_fields(xmlNode * left, xmlNode * right, const char *field) { const char *elem_l = crm_element_value(left, field); const char *elem_r = crm_element_value(right, field); int int_elem_l = crm_int_helper(elem_l, NULL); int int_elem_r = crm_int_helper(elem_r, NULL); if (int_elem_l < int_elem_r) { return -1; } else if (int_elem_l > int_elem_r) { return 1; } return 0; } /* A_DC_JOIN_PROCESS_REQ */ void do_dc_join_filter_offer(long long action, enum crmd_fsa_cause cause, enum crmd_fsa_state cur_state, enum crmd_fsa_input current_input, fsa_data_t * msg_data) { xmlNode *generation = NULL; int cmp = 0; int join_id = -1; gboolean ack_nack_bool = TRUE; const char *ack_nack = CRMD_JOINSTATE_MEMBER; ha_msg_input_t *join_ack = fsa_typed_data(fsa_dt_ha_msg); const char *join_from = crm_element_value(join_ack->msg, F_CRM_HOST_FROM); const char *ref = crm_element_value(join_ack->msg, F_CRM_REFERENCE); crm_node_t *join_node = crm_get_peer(0, join_from); crm_debug("Processing req from %s", join_from); generation = join_ack->xml; crm_element_value_int(join_ack->msg, F_CRM_JOIN_ID, &join_id); if (max_generation_xml != NULL && generation != NULL) { int lpc = 0; const char *attributes[] = { XML_ATTR_GENERATION_ADMIN, XML_ATTR_GENERATION, XML_ATTR_NUMUPDATES, }; for (lpc = 0; cmp == 0 && lpc < DIMOF(attributes); lpc++) { cmp = compare_int_fields(max_generation_xml, generation, attributes[lpc]); } } if (join_id != current_join_id) { crm_debug("Invalid response from %s: join-%d vs. join-%d", join_from, join_id, current_join_id); check_join_state(cur_state, __FUNCTION__); return; } else if (join_node == NULL || crm_is_peer_active(join_node) == FALSE) { crm_err("Node %s is not a member", join_from); ack_nack_bool = FALSE; } else if (generation == NULL) { crm_err("Generation was NULL"); ack_nack_bool = FALSE; } else if (max_generation_xml == NULL) { max_generation_xml = copy_xml(generation); max_generation_from = strdup(join_from); } else if (cmp < 0 || (cmp == 0 && safe_str_eq(join_from, fsa_our_uname))) { crm_debug("%s has a better generation number than" " the current max %s", join_from, max_generation_from); if (max_generation_xml) { crm_log_xml_debug(max_generation_xml, "Max generation"); } crm_log_xml_debug(generation, "Their generation"); free(max_generation_from); free_xml(max_generation_xml); max_generation_from = strdup(join_from); max_generation_xml = copy_xml(join_ack->xml); } if (ack_nack_bool == FALSE) { /* NACK this client */ ack_nack = CRMD_JOINSTATE_NACK; crm_update_peer_join(__FUNCTION__, join_node, crm_join_nack); crm_err("join-%d: NACK'ing node %s (ref %s)", join_id, join_from, ref); } else { crm_debug("join-%d: Welcoming node %s (ref %s)", join_id, join_from, ref); crm_update_peer_join(__FUNCTION__, join_node, crm_join_integrated); } crm_update_peer_expected(__FUNCTION__, join_node, ack_nack); crm_debug("%u nodes have been integrated into join-%d", crmd_join_phase_count(crm_join_integrated), join_id); if (check_join_state(cur_state, __FUNCTION__) == FALSE) { /* dont waste time by invoking the PE yet; */ crm_debug("join-%d: Still waiting on %d outstanding offers", join_id, crmd_join_phase_count(crm_join_welcomed)); } } /* A_DC_JOIN_FINALIZE */ void do_dc_join_finalize(long long action, enum crmd_fsa_cause cause, enum crmd_fsa_state cur_state, enum crmd_fsa_input current_input, fsa_data_t * msg_data) { char *sync_from = NULL; int rc = pcmk_ok; /* This we can do straight away and avoid clients timing us out * while we compute the latest CIB */ crm_debug("Finializing join-%d for %d clients", current_join_id, crmd_join_phase_count(crm_join_integrated)); crmd_join_phase_log(LOG_INFO); if (crmd_join_phase_count(crm_join_welcomed) != 0) { crm_info("Waiting for %d more nodes", crmd_join_phase_count(crm_join_welcomed)); /* crmd_fsa_stall(FALSE); Needed? */ return; } else if (crmd_join_phase_count(crm_join_integrated) == 0) { /* Nothing to do */ check_join_state(fsa_state, __FUNCTION__); return; } clear_bit(fsa_input_register, R_HAVE_CIB); if (max_generation_from == NULL || safe_str_eq(max_generation_from, fsa_our_uname)) { set_bit(fsa_input_register, R_HAVE_CIB); } if (is_set(fsa_input_register, R_IN_TRANSITION)) { crm_warn("join-%d: We are still in a transition." " Delaying until the TE completes.", current_join_id); crmd_fsa_stall(FALSE); return; } if (is_set(fsa_input_register, R_HAVE_CIB) == FALSE) { /* ask for the agreed best CIB */ sync_from = strdup(max_generation_from); set_bit(fsa_input_register, R_CIB_ASKED); crm_notice("join-%d: Syncing the CIB from %s to the rest of the cluster", current_join_id, sync_from); crm_log_xml_notice(max_generation_xml, "Requested version"); } else { /* Send _our_ CIB out to everyone */ sync_from = strdup(fsa_our_uname); crm_info("join-%d: Syncing our CIB to the rest of the cluster", current_join_id); crm_log_xml_debug(max_generation_xml, "Requested version"); } rc = fsa_cib_conn->cmds->sync_from(fsa_cib_conn, sync_from, NULL, cib_quorum_override); fsa_register_cib_callback(rc, FALSE, sync_from, finalize_sync_callback); } void finalize_sync_callback(xmlNode * msg, int call_id, int rc, xmlNode * output, void *user_data) { CRM_LOG_ASSERT(-EPERM != rc); clear_bit(fsa_input_register, R_CIB_ASKED); if (rc != pcmk_ok) { do_crm_log((rc == -pcmk_err_old_data ? LOG_WARNING : LOG_ERR), "Sync from %s failed: %s", (char *)user_data, pcmk_strerror(rc)); /* restart the whole join process */ register_fsa_error_adv(C_FSA_INTERNAL, I_ELECTION_DC, NULL, NULL, __FUNCTION__); } else if (AM_I_DC && fsa_state == S_FINALIZE_JOIN) { set_bit(fsa_input_register, R_HAVE_CIB); clear_bit(fsa_input_register, R_CIB_ASKED); /* make sure dc_uuid is re-set to us */ if (check_join_state(fsa_state, __FUNCTION__) == FALSE) { crm_debug("Notifying %d clients of join-%d results", crmd_join_phase_count(crm_join_integrated), current_join_id); g_hash_table_foreach(crm_peer_cache, finalize_join_for, NULL); } } else { crm_debug("No longer the DC in S_FINALIZE_JOIN: %s/%s", AM_I_DC ? "DC" : "CRMd", fsa_state2string(fsa_state)); } free(user_data); } static void join_update_complete_callback(xmlNode * msg, int call_id, int rc, xmlNode * output, void *user_data) { fsa_data_t *msg_data = NULL; if (rc == pcmk_ok) { crm_debug("Join update %d complete", call_id); check_join_state(fsa_state, __FUNCTION__); } else { crm_err("Join update %d failed", call_id); crm_log_xml_debug(msg, "failed"); register_fsa_error(C_FSA_INTERNAL, I_ERROR, NULL); } } /* A_DC_JOIN_PROCESS_ACK */ void do_dc_join_ack(long long action, enum crmd_fsa_cause cause, enum crmd_fsa_state cur_state, enum crmd_fsa_input current_input, fsa_data_t * msg_data) { int join_id = -1; int call_id = 0; ha_msg_input_t *join_ack = fsa_typed_data(fsa_dt_ha_msg); const char *op = crm_element_value(join_ack->msg, F_CRM_TASK); const char *join_from = crm_element_value(join_ack->msg, F_CRM_HOST_FROM); crm_node_t *peer = crm_get_peer(0, join_from); if (safe_str_neq(op, CRM_OP_JOIN_CONFIRM) || peer == NULL) { crm_debug("Ignoring op=%s message from %s", op, join_from); return; } crm_trace("Processing ack from %s", join_from); crm_element_value_int(join_ack->msg, F_CRM_JOIN_ID, &join_id); if (peer->join != crm_join_finalized) { crm_info("Join not in progress: ignoring join-%d from %s (phase = %d)", join_id, join_from, peer->join); return; } else if (join_id != current_join_id) { crm_err("Invalid response from %s: join-%d vs. join-%d", join_from, join_id, current_join_id); crm_update_peer_join(__FUNCTION__, peer, crm_join_nack); return; } crm_update_peer_join(__FUNCTION__, peer, crm_join_confirmed); crm_info("join-%d: Updating node state to %s for %s", join_id, CRMD_JOINSTATE_MEMBER, join_from); /* update CIB with the current LRM status from the node * We dont need to notify the TE of these updates, a transition will * be started in due time */ erase_status_tag(join_from, XML_CIB_TAG_LRM, cib_scope_local); fsa_cib_update(XML_CIB_TAG_STATUS, join_ack->xml, cib_scope_local | cib_quorum_override | cib_can_create, call_id, NULL); fsa_register_cib_callback(call_id, FALSE, NULL, join_update_complete_callback); crm_debug("join-%d: Registered callback for LRM update %d", join_id, call_id); } void finalize_join_for(gpointer key, gpointer value, gpointer user_data) { xmlNode *acknak = NULL; xmlNode *tmp1 = NULL; crm_node_t *join_node = value; const char *join_to = join_node->uname; if(join_node->join != crm_join_integrated) { crm_trace("Skipping %s in state %d", join_to, join_node->join); return; } /* make sure a node entry exists for the new node */ crm_trace("Creating node entry for %s", join_to); tmp1 = create_xml_node(NULL, XML_CIB_TAG_NODE); set_uuid(tmp1, XML_ATTR_UUID, join_node); crm_xml_add(tmp1, XML_ATTR_UNAME, join_to); fsa_cib_anon_update(XML_CIB_TAG_NODES, tmp1, cib_scope_local | cib_quorum_override | cib_can_create); free_xml(tmp1); join_node = crm_get_peer(0, join_to); if (crm_is_peer_active(join_node) == FALSE) { /* * NACK'ing nodes that the membership layer doesn't know about yet * simply creates more churn * * Better to leave them waiting and let the join restart when * the new membership event comes in * * All other NACKs (due to versions etc) should still be processed */ crm_update_peer_expected(__FUNCTION__, join_node, CRMD_JOINSTATE_PENDING); return; } /* send the ack/nack to the node */ acknak = create_request(CRM_OP_JOIN_ACKNAK, NULL, join_to, CRM_SYSTEM_CRMD, CRM_SYSTEM_DC, NULL); crm_xml_add_int(acknak, F_CRM_JOIN_ID, current_join_id); crm_debug("join-%d: ACK'ing join request from %s", current_join_id, join_to); crm_xml_add(acknak, CRM_OP_JOIN_ACKNAK, XML_BOOLEAN_TRUE); crm_update_peer_join(__FUNCTION__, join_node, crm_join_finalized); crm_update_peer_expected(__FUNCTION__, join_node, CRMD_JOINSTATE_MEMBER); send_cluster_message(crm_get_peer(0, join_to), crm_msg_crmd, acknak, TRUE); free_xml(acknak); return; } void ghash_print_node(gpointer key, gpointer value, gpointer user_data); gboolean check_join_state(enum crmd_fsa_state cur_state, const char *source) { static unsigned long long highest_seq = 0; crm_debug("Invoked by %s in state: %s", source, fsa_state2string(cur_state)); if (saved_ccm_membership_id != crm_peer_seq) { crm_debug("%s: Membership changed since join started: %llu -> %llu (%llu)", source, saved_ccm_membership_id, crm_peer_seq, highest_seq); if(highest_seq < crm_peer_seq) { /* Don't spam the FSA with duplicates */ highest_seq = crm_peer_seq; register_fsa_input_before(C_FSA_INTERNAL, I_NODE_JOIN, NULL); } } else if (cur_state == S_INTEGRATION) { if (crmd_join_phase_count(crm_join_welcomed) == 0) { crm_debug("join-%d: Integration of %d peers complete: %s", current_join_id, crmd_join_phase_count(crm_join_integrated), source); register_fsa_input_before(C_FSA_INTERNAL, I_INTEGRATED, NULL); return TRUE; } } else if (cur_state == S_FINALIZE_JOIN) { if (is_set(fsa_input_register, R_HAVE_CIB) == FALSE) { crm_debug("join-%d: Delaying I_FINALIZED until we have the CIB", current_join_id); return TRUE; } else if (crmd_join_phase_count(crm_join_welcomed) != 0) { crm_debug("join-%d: Still waiting on %d welcomed nodes", current_join_id, crmd_join_phase_count(crm_join_welcomed)); crmd_join_phase_log(LOG_DEBUG); } else if (crmd_join_phase_count(crm_join_integrated) != 0) { crm_debug("join-%d: Still waiting on %d integrated nodes", current_join_id, crmd_join_phase_count(crm_join_integrated)); crmd_join_phase_log(LOG_DEBUG); } else if (crmd_join_phase_count(crm_join_finalized) != 0) { crm_debug("join-%d: Still waiting on %d finalized nodes", current_join_id, crmd_join_phase_count(crm_join_finalized)); crmd_join_phase_log(LOG_DEBUG); } else { crm_debug("join-%d complete: %s", current_join_id, source); register_fsa_input_later(C_FSA_INTERNAL, I_FINALIZED, NULL); return TRUE; } } return FALSE; } void do_dc_join_final(long long action, enum crmd_fsa_cause cause, enum crmd_fsa_state cur_state, enum crmd_fsa_input current_input, fsa_data_t * msg_data) { crm_debug("Ensuring DC, quorum and node attributes are up-to-date"); update_attrd(NULL, NULL, NULL, NULL, FALSE); crm_update_quorum(crm_have_quorum, TRUE); } int crmd_join_phase_count(enum crm_join_phase phase) { int count = 0; crm_node_t *peer; GHashTableIter iter; g_hash_table_iter_init(&iter, crm_peer_cache); while (g_hash_table_iter_next(&iter, NULL, (gpointer *) &peer)) { if(peer->join == phase) { count++; } } return count; } void crmd_join_phase_log(int level) { crm_node_t *peer; GHashTableIter iter; g_hash_table_iter_init(&iter, crm_peer_cache); while (g_hash_table_iter_next(&iter, NULL, (gpointer *) &peer)) { const char *state = "unknown"; switch(peer->join) { case crm_join_nack: state = "nack"; break; case crm_join_none: state = "none"; break; case crm_join_welcomed: state = "welcomed"; break; case crm_join_integrated: state = "integrated"; break; case crm_join_finalized: state = "finalized"; break; case crm_join_confirmed: state = "confirmed"; break; } do_crm_log(level, "join-%d: %s=%s", current_join_id, peer->uname, state); } } pacemaker-master/crmd/lrm.c000066400000000000000000002105741217637305600162050ustar00rootroot00000000000000/* * Copyright (C) 2004 Andrew Beekhof * * 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 2 of the License, or (at your option) any later version. * * This software 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 library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include #include #include #include #include #include #include #include #include #include #include #include #define START_DELAY_THRESHOLD 5 * 60 * 1000 #define MAX_LRM_REG_FAILS 30 struct delete_event_s { int rc; const char *rsc; lrm_state_t *lrm_state; }; gboolean process_lrm_event(lrm_state_t * lrm_state, lrmd_event_data_t * op); static gboolean is_rsc_active(lrm_state_t * lrm_state, const char *rsc_id); static gboolean build_active_RAs(lrm_state_t * lrm_state, xmlNode * rsc_list); static gboolean stop_recurring_actions(gpointer key, gpointer value, gpointer user_data); static int delete_rsc_status(lrm_state_t * lrm_state, const char *rsc_id, int call_options, const char *user_name); static lrmd_event_data_t *construct_op(lrm_state_t * lrm_state, xmlNode * rsc_op, const char *rsc_id, const char *operation); static void do_lrm_rsc_op(lrm_state_t * lrm_state, lrmd_rsc_info_t * rsc, const char *operation, xmlNode * msg, xmlNode * request); void send_direct_ack(const char *to_host, const char *to_sys, lrmd_rsc_info_t * rsc, lrmd_event_data_t * op, const char *rsc_id); static gboolean lrm_state_verify_stopped(lrm_state_t * lrm_state, enum crmd_fsa_state cur_state, int log_level); static void lrm_connection_destroy(void) { if (is_set(fsa_input_register, R_LRM_CONNECTED)) { crm_crit("LRM Connection failed"); register_fsa_input(C_FSA_INTERNAL, I_ERROR, NULL); clear_bit(fsa_input_register, R_LRM_CONNECTED); } else { crm_info("LRM Connection disconnected"); } } static char * make_stop_id(const char *rsc, int call_id) { char *op_id = NULL; op_id = calloc(1, strlen(rsc) + 34); if (op_id != NULL) { snprintf(op_id, strlen(rsc) + 34, "%s:%d", rsc, call_id); } return op_id; } static void copy_instance_keys(gpointer key, gpointer value, gpointer user_data) { if (strstr(key, CRM_META "_") == NULL) { g_hash_table_replace(user_data, strdup((const char *)key), strdup((const char *)value)); } } static void copy_meta_keys(gpointer key, gpointer value, gpointer user_data) { if (strstr(key, CRM_META "_") != NULL) { g_hash_table_replace(user_data, strdup((const char *)key), strdup((const char *)value)); } } static void update_history_cache(lrm_state_t * lrm_state, lrmd_rsc_info_t * rsc, lrmd_event_data_t * op) { int target_rc = 0; rsc_history_t *entry = NULL; if (op->rsc_deleted) { crm_debug("Purged history for '%s' after %s", op->rsc_id, op->op_type); delete_rsc_status(lrm_state, op->rsc_id, cib_quorum_override, NULL); return; } if (safe_str_eq(op->op_type, RSC_NOTIFY)) { return; } crm_debug("Updating history for '%s' with %s op", op->rsc_id, op->op_type); entry = g_hash_table_lookup(lrm_state->resource_history, op->rsc_id); if (entry == NULL && rsc) { entry = calloc(1, sizeof(rsc_history_t)); entry->id = strdup(op->rsc_id); g_hash_table_insert(lrm_state->resource_history, entry->id, entry); entry->rsc.id = entry->id; entry->rsc.type = strdup(rsc->type); entry->rsc.class = strdup(rsc->class); if (rsc->provider) { entry->rsc.provider = strdup(rsc->provider); } else { entry->rsc.provider = NULL; } } else if (entry == NULL) { crm_info("Resource %s no longer exists, not updating cache", op->rsc_id); return; } entry->last_callid = op->call_id; target_rc = rsc_op_expected_rc(op); if (op->op_status == PCMK_LRM_OP_CANCELLED) { if (op->interval > 0) { GList *gIter, *gIterNext; crm_trace("Removing cancelled recurring op: %s_%s_%d", op->rsc_id, op->op_type, op->interval); for (gIter = entry->recurring_op_list; gIter != NULL; gIter = gIterNext) { lrmd_event_data_t *existing = gIter->data; gIterNext = gIter->next; if (safe_str_eq(op->rsc_id, existing->rsc_id) && safe_str_eq(op->op_type, existing->op_type) && op->interval == existing->interval) { lrmd_free_event(existing); entry->recurring_op_list = g_list_delete_link(entry->recurring_op_list, gIter); } } return; } else { crm_trace("Skipping %s_%s_%d rc=%d, status=%d", op->rsc_id, op->op_type, op->interval, op->rc, op->op_status); } } else if (did_rsc_op_fail(op, target_rc)) { /* We must store failed monitors here * - otherwise the block below will cause them to be forgetten them when a stop happens */ if (entry->failed) { lrmd_free_event(entry->failed); } entry->failed = lrmd_copy_event(op); } else if (op->interval == 0) { if (entry->last) { lrmd_free_event(entry->last); } entry->last = lrmd_copy_event(op); if (op->params && (safe_str_eq(CRMD_ACTION_START, op->op_type) || safe_str_eq(CRMD_ACTION_STATUS, op->op_type))) { if (entry->stop_params) { g_hash_table_destroy(entry->stop_params); } entry->stop_params = g_hash_table_new_full(crm_str_hash, g_str_equal, g_hash_destroy_str, g_hash_destroy_str); g_hash_table_foreach(op->params, copy_instance_keys, entry->stop_params); } } if (op->interval > 0) { crm_trace("Adding recurring op: %s_%s_%d", op->rsc_id, op->op_type, op->interval); entry->recurring_op_list = g_list_prepend(entry->recurring_op_list, lrmd_copy_event(op)); } else if (entry->recurring_op_list && safe_str_eq(op->op_type, RSC_STATUS) == FALSE) { GList *gIter = entry->recurring_op_list; crm_trace("Dropping %d recurring ops because of: %s_%s_%d", g_list_length(gIter), op->rsc_id, op->op_type, op->interval); for (; gIter != NULL; gIter = gIter->next) { lrmd_free_event(gIter->data); } g_list_free(entry->recurring_op_list); entry->recurring_op_list = NULL; } } void lrm_op_callback(lrmd_event_data_t * op) { const char *nodename = NULL; lrm_state_t *lrm_state = NULL; CRM_CHECK(op != NULL, return); /* determine the node name for this connection. */ nodename = op->remote_nodename ? op->remote_nodename : fsa_our_uname; if (op->type == lrmd_event_disconnect && (safe_str_eq(nodename, fsa_our_uname))) { /* if this is the local lrmd ipc connection, set the right bits in the * crmd when the connection goes down */ lrm_connection_destroy(); return; } else if (op->type != lrmd_event_exec_complete) { /* we only need to process execution results */ return; } lrm_state = lrm_state_find(nodename); CRM_ASSERT(lrm_state != NULL); process_lrm_event(lrm_state, op); } /* A_LRM_CONNECT */ void do_lrm_control(long long action, enum crmd_fsa_cause cause, enum crmd_fsa_state cur_state, enum crmd_fsa_input current_input, fsa_data_t * msg_data) { /* This only pertains to local lrmd connections. Remote connections are handled as * resources within the pengine. Connecting and disconnecting from remote lrmd instances * handled differently than the local. */ lrm_state_t *lrm_state = NULL; if(fsa_our_uname == NULL) { return; /* Nothing to do */ } lrm_state = lrm_state_find_or_create(fsa_our_uname); if (lrm_state == NULL) { register_fsa_error(C_FSA_INTERNAL, I_ERROR, NULL); return; } if (action & A_LRM_DISCONNECT) { if (lrm_state_verify_stopped(lrm_state, cur_state, LOG_INFO) == FALSE) { if (action == A_LRM_DISCONNECT) { crmd_fsa_stall(FALSE); return; } } clear_bit(fsa_input_register, R_LRM_CONNECTED); crm_info("Disconnecting from the LRM"); lrm_state_disconnect(lrm_state); lrm_state_reset_tables(lrm_state); crm_notice("Disconnected from the LRM"); } if (action & A_LRM_CONNECT) { int ret = pcmk_ok; crm_debug("Connecting to the LRM"); ret = lrm_state_ipc_connect(lrm_state); if (ret != pcmk_ok) { if (lrm_state->num_lrm_register_fails < MAX_LRM_REG_FAILS) { crm_warn("Failed to sign on to the LRM %d" " (%d max) times", lrm_state->num_lrm_register_fails, MAX_LRM_REG_FAILS); crm_timer_start(wait_timer); crmd_fsa_stall(FALSE); return; } } if (ret != pcmk_ok) { crm_err("Failed to sign on to the LRM %d" " (max) times", lrm_state->num_lrm_register_fails); register_fsa_error(C_FSA_INTERNAL, I_ERROR, NULL); return; } set_bit(fsa_input_register, R_LRM_CONNECTED); crm_info("LRM connection established"); } if (action & ~(A_LRM_CONNECT | A_LRM_DISCONNECT)) { crm_err("Unexpected action %s in %s", fsa_action2string(action), __FUNCTION__); } } static gboolean lrm_state_verify_stopped(lrm_state_t * lrm_state, enum crmd_fsa_state cur_state, int log_level) { int counter = 0; gboolean rc = TRUE; const char *when = "lrm disconnect"; GHashTableIter gIter; const char *key = NULL; rsc_history_t *entry = NULL; struct recurring_op_s *pending = NULL; crm_debug("Checking for active resources before exit"); if (cur_state == S_TERMINATE) { log_level = LOG_ERR; when = "shutdown"; } else if (is_set(fsa_input_register, R_SHUTDOWN)) { when = "shutdown... waiting"; } if (lrm_state->pending_ops && lrm_state_is_connected(lrm_state) == TRUE) { guint removed = g_hash_table_foreach_remove( lrm_state->pending_ops, stop_recurring_actions, lrm_state); crm_notice("Stopped %u recurring operations at %s (%u ops remaining)", g_hash_table_size(lrm_state->pending_ops), removed, when); } if (lrm_state->pending_ops) { g_hash_table_iter_init(&gIter, lrm_state->pending_ops); while (g_hash_table_iter_next(&gIter, NULL, (void **)&pending)) { /* Ignore recurring actions in the shutdown calculations */ if (pending->interval == 0) { counter++; } } } if (counter > 0) { do_crm_log(log_level, "%d pending LRM operations at %s%s", counter, when); if (cur_state == S_TERMINATE || !is_set(fsa_input_register, R_SENT_RSC_STOP)) { g_hash_table_iter_init(&gIter, lrm_state->pending_ops); while (g_hash_table_iter_next(&gIter, (gpointer*)&key, (gpointer*)&pending)) { do_crm_log(log_level, "Pending action: %s (%s)", key, pending->op_key); } } else { rc = FALSE; } return rc; } if (lrm_state->resource_history == NULL) { return rc; } if (cur_state == S_TERMINATE || is_set(fsa_input_register, R_SHUTDOWN)) { /* At this point we're not waiting, we're just shutting down */ when = "shutdown"; } counter = 0; g_hash_table_iter_init(&gIter, lrm_state->resource_history); while (g_hash_table_iter_next(&gIter, NULL, (gpointer*)&entry)) { if (is_rsc_active(lrm_state, entry->id) == FALSE) { continue; } counter++; crm_trace("Found %s active", entry->id); if (lrm_state->pending_ops) { GHashTableIter hIter; g_hash_table_iter_init(&hIter, lrm_state->pending_ops); while (g_hash_table_iter_next(&hIter, (gpointer*)&key, (gpointer*)&pending)) { if (safe_str_eq(entry->id, pending->rsc_id)) { crm_notice("%sction %s (%s) incomplete at %s", pending->interval == 0 ? "A" : "Recurring a", key, pending->op_key, when); } } } } if (counter) { crm_err("%d resources were active at %s.", counter, when); } return rc; } static char * get_rsc_metadata(const char *type, const char *class, const char *provider) { int rc = 0; char *metadata = NULL; /* Always use a local connection for this operation */ lrm_state_t *lrm_state = lrm_state_find(fsa_our_uname); CRM_CHECK(type != NULL, return NULL); CRM_CHECK(class != NULL, return NULL); CRM_CHECK(lrm_state != NULL, return NULL); if (provider == NULL) { provider = "heartbeat"; } crm_trace("Retreiving metadata for %s::%s:%s", type, class, provider); rc = lrm_state_get_metadata(lrm_state, class, provider, type, &metadata, 0); if (metadata) { /* copy the metadata because the LRM likes using * g_alloc instead of cl_malloc */ char *m_copy = strdup(metadata); g_free(metadata); metadata = m_copy; } else { crm_warn("No metadata found for %s::%s:%s: %s (%d)", type, class, provider, pcmk_strerror(rc), rc); } return metadata; } typedef struct reload_data_s { char *key; char *metadata; time_t last_query; gboolean can_reload; GListPtr restart_list; } reload_data_t; static void g_hash_destroy_reload(gpointer data) { reload_data_t *reload = data; free(reload->key); free(reload->metadata); g_list_free_full(reload->restart_list, free); free(reload); } GHashTable *reload_hash = NULL; static GListPtr get_rsc_restart_list(lrmd_rsc_info_t * rsc, lrmd_event_data_t * op) { int len = 0; char *key = NULL; char *copy = NULL; const char *value = NULL; const char *provider = NULL; xmlNode *param = NULL; xmlNode *params = NULL; xmlNode *actions = NULL; xmlNode *metadata = NULL; time_t now = time(NULL); reload_data_t *reload = NULL; if (reload_hash == NULL) { reload_hash = g_hash_table_new_full(crm_str_hash, g_str_equal, NULL, g_hash_destroy_reload); } provider = rsc->provider; if (provider == NULL) { provider = "heartbeat"; } len = strlen(rsc->type) + strlen(rsc->class) + strlen(provider) + 4; key = malloc(len); if(key) { snprintf(key, len, "%s::%s:%s", rsc->type, rsc->class, provider); reload = g_hash_table_lookup(reload_hash, key); } if (reload && ((now - 9) > reload->last_query) && safe_str_eq(op->op_type, RSC_START)) { reload = NULL; /* re-query */ } if (reload == NULL) { xmlNode *action = NULL; reload = calloc(1, sizeof(reload_data_t)); g_hash_table_replace(reload_hash, key, reload); reload->last_query = now; reload->key = key; key = NULL; reload->metadata = get_rsc_metadata(rsc->type, rsc->class, provider); if(reload->metadata == NULL) { goto cleanup; } metadata = string2xml(reload->metadata); if (metadata == NULL) { crm_err("Metadata for %s::%s:%s is not valid XML", rsc->provider, rsc->class, rsc->type); goto cleanup; } actions = find_xml_node(metadata, "actions", TRUE); for (action = __xml_first_child(actions); action != NULL; action = __xml_next(action)) { if (crm_str_eq((const char *)action->name, "action", TRUE)) { value = crm_element_value(action, "name"); if (safe_str_eq("reload", value)) { reload->can_reload = TRUE; break; } } } if (reload->can_reload == FALSE) { goto cleanup; } params = find_xml_node(metadata, "parameters", TRUE); for (param = __xml_first_child(params); param != NULL; param = __xml_next(param)) { if (crm_str_eq((const char *)param->name, "parameter", TRUE)) { value = crm_element_value(param, "unique"); if (crm_is_true(value)) { value = crm_element_value(param, "name"); if (value == NULL) { crm_err("%s: NULL param", key); continue; } crm_debug("Attr %s is not reloadable", value); copy = strdup(value); CRM_CHECK(copy != NULL, continue); reload->restart_list = g_list_append(reload->restart_list, copy); } } } } cleanup: free(key); free_xml(metadata); return reload->restart_list; } static void append_restart_list(lrmd_rsc_info_t * rsc, lrmd_event_data_t * op, xmlNode * update, const char *version) { int len = 0; char *list = NULL; char *digest = NULL; const char *value = NULL; xmlNode *restart = NULL; GListPtr restart_list = NULL; GListPtr lpc = NULL; if (op->interval > 0) { /* monitors are not reloadable */ return; } else if (op->params == NULL) { crm_debug("%s has no parameters", ID(update)); return; } else if (rsc == NULL) { return; } else if (crm_str_eq(CRMD_ACTION_STOP, op->op_type, TRUE)) { /* Stopped resources don't need to be reloaded */ return; } else if (compare_version("1.0.8", version) > 0) { /* Caller version does not support reloads */ return; } restart_list = get_rsc_restart_list(rsc, op); if (restart_list == NULL) { /* Resource does not support reloads */ return; } restart = create_xml_node(NULL, XML_TAG_PARAMS); for (lpc = restart_list; lpc != NULL; lpc = lpc->next) { const char *param = (const char *)lpc->data; int start = len; CRM_CHECK(param != NULL, continue); value = g_hash_table_lookup(op->params, param); if (value != NULL) { crm_xml_add(restart, param, value); } len += strlen(param) + 2; list = realloc(list, len + 1); sprintf(list + start, " %s ", param); } digest = calculate_operation_digest(restart, version); crm_xml_add(update, XML_LRM_ATTR_OP_RESTART, list); crm_xml_add(update, XML_LRM_ATTR_RESTART_DIGEST, digest); crm_trace("%s: %s, %s", rsc->id, digest, list); crm_log_xml_trace(restart, "restart digest source"); free_xml(restart); free(digest); free(list); } static gboolean build_operation_update(xmlNode * parent, lrmd_rsc_info_t * rsc, lrmd_event_data_t * op, const char *src) { int target_rc = 0; xmlNode *xml_op = NULL; const char *caller_version = CRM_FEATURE_SET; if (op == NULL) { return FALSE; } else if (AM_I_DC) { } else if (fsa_our_dc_version != NULL) { caller_version = fsa_our_dc_version; } else if (op->params == NULL) { caller_version = fsa_our_dc_version; } else { /* there is a small risk in formerly mixed clusters that * it will be sub-optimal. * however with our upgrade policy, the update we send * should still be completely supported anyway */ caller_version = g_hash_table_lookup(op->params, XML_ATTR_CRM_VERSION); crm_debug("Falling back to operation originator version: %s", caller_version); } target_rc = rsc_op_expected_rc(op); xml_op = create_operation_update(parent, op, caller_version, target_rc, src, LOG_DEBUG); if (xml_op) { append_restart_list(rsc, op, xml_op, caller_version); } return TRUE; } static gboolean is_rsc_active(lrm_state_t * lrm_state, const char *rsc_id) { rsc_history_t *entry = NULL; entry = g_hash_table_lookup(lrm_state->resource_history, rsc_id); if (entry == NULL || entry->last == NULL) { return FALSE; } crm_trace("Processing %s: %s.%d=%d", rsc_id, entry->last->op_type, entry->last->interval, entry->last->rc); if (entry->last->rc == PCMK_EXECRA_OK && safe_str_eq(entry->last->op_type, CRMD_ACTION_STOP)) { return FALSE; } else if (entry->last->rc == PCMK_EXECRA_OK && safe_str_eq(entry->last->op_type, CRMD_ACTION_MIGRATE)) { /* a stricter check is too complex... * leave that to the PE */ return FALSE; } else if (entry->last->rc == PCMK_EXECRA_NOT_RUNNING) { return FALSE; } else if (entry->last->interval == 0 && entry->last->rc == PCMK_EXECRA_NOT_CONFIGURED) { /* Badly configured resources can't be reliably stopped */ return FALSE; } return TRUE; } static gboolean build_active_RAs(lrm_state_t * lrm_state, xmlNode * rsc_list) { GHashTableIter iter; rsc_history_t *entry = NULL; g_hash_table_iter_init(&iter, lrm_state->resource_history); while (g_hash_table_iter_next(&iter, NULL, (void **)&entry)) { GList *gIter = NULL; xmlNode *xml_rsc = create_xml_node(rsc_list, XML_LRM_TAG_RESOURCE); crm_xml_add(xml_rsc, XML_ATTR_ID, entry->id); crm_xml_add(xml_rsc, XML_ATTR_TYPE, entry->rsc.type); crm_xml_add(xml_rsc, XML_AGENT_ATTR_CLASS, entry->rsc.class); crm_xml_add(xml_rsc, XML_AGENT_ATTR_PROVIDER, entry->rsc.provider); build_operation_update(xml_rsc, &(entry->rsc), entry->last, __FUNCTION__); build_operation_update(xml_rsc, &(entry->rsc), entry->failed, __FUNCTION__); for (gIter = entry->recurring_op_list; gIter != NULL; gIter = gIter->next) { build_operation_update(xml_rsc, &(entry->rsc), gIter->data, __FUNCTION__); } } return FALSE; } xmlNode * do_lrm_query_internal(lrm_state_t * lrm_state, gboolean is_replace) { xmlNode *xml_result = NULL; xmlNode *xml_state = NULL; xmlNode *xml_data = NULL; xmlNode *rsc_list = NULL; const char *uuid = NULL; if (safe_str_eq(lrm_state->node_name, fsa_our_uname)) { crm_node_t *peer = crm_get_peer(0, lrm_state->node_name); xml_state = do_update_node_cib(peer, node_update_cluster|node_update_peer, NULL, __FUNCTION__); /* The next two lines shouldn't be necessary for newer DCs */ crm_xml_add(xml_state, XML_NODE_JOIN_STATE, CRMD_JOINSTATE_MEMBER); crm_xml_add(xml_state, XML_NODE_EXPECTED, CRMD_JOINSTATE_MEMBER); uuid = fsa_our_uuid; } else { xml_state = create_xml_node(NULL, XML_CIB_TAG_STATE); crm_xml_add(xml_state, XML_NODE_IS_REMOTE, "true"); crm_xml_add(xml_state, XML_ATTR_ID, lrm_state->node_name); crm_xml_add(xml_state, XML_ATTR_UNAME, lrm_state->node_name); uuid = lrm_state->node_name; } xml_data = create_xml_node(xml_state, XML_CIB_TAG_LRM); crm_xml_add(xml_data, XML_ATTR_ID, uuid); rsc_list = create_xml_node(xml_data, XML_LRM_TAG_RESOURCES); /* Build a list of active (not always running) resources */ build_active_RAs(lrm_state, rsc_list); xml_result = create_cib_fragment(xml_state, XML_CIB_TAG_STATUS); crm_log_xml_trace(xml_state, "Current state of the LRM"); free_xml(xml_state); return xml_result; } xmlNode * do_lrm_query(gboolean is_replace, const char *node_name) { lrm_state_t *lrm_state = lrm_state_find(node_name); if (!lrm_state) { crm_err("Could not query lrm state for lrmd node %s", node_name); return NULL; } return do_lrm_query_internal(lrm_state, is_replace); } static void notify_deleted(lrm_state_t * lrm_state, ha_msg_input_t * input, const char *rsc_id, int rc) { lrmd_event_data_t *op = NULL; const char *from_sys = crm_element_value(input->msg, F_CRM_SYS_FROM); const char *from_host = crm_element_value(input->msg, F_CRM_HOST_FROM); crm_info("Notifying %s on %s that %s was%s deleted", from_sys, from_host, rsc_id, rc == pcmk_ok ? "" : " not"); op = construct_op(lrm_state, input->xml, rsc_id, CRMD_ACTION_DELETE); CRM_ASSERT(op != NULL); if (rc == pcmk_ok) { op->op_status = PCMK_LRM_OP_DONE; op->rc = PCMK_EXECRA_OK; } else { op->op_status = PCMK_LRM_OP_ERROR; op->rc = PCMK_EXECRA_UNKNOWN_ERROR; } send_direct_ack(from_host, from_sys, NULL, op, rsc_id); lrmd_free_event(op); if (safe_str_neq(from_sys, CRM_SYSTEM_TENGINE)) { /* this isn't expected - trigger a new transition */ time_t now = time(NULL); char *now_s = crm_itoa(now); crm_debug("Triggering a refresh after %s deleted %s from the LRM", from_sys, rsc_id); update_attr_delegate(fsa_cib_conn, cib_none, XML_CIB_TAG_CRMCONFIG, NULL, NULL, NULL, NULL, "last-lrm-refresh", now_s, FALSE, NULL); free(now_s); } } static gboolean lrm_remove_deleted_rsc(gpointer key, gpointer value, gpointer user_data) { struct delete_event_s *event = user_data; struct pending_deletion_op_s *op = value; if (safe_str_eq(event->rsc, op->rsc)) { notify_deleted(event->lrm_state, op->input, event->rsc, event->rc); return TRUE; } return FALSE; } static gboolean lrm_remove_deleted_op(gpointer key, gpointer value, gpointer user_data) { const char *rsc = user_data; struct recurring_op_s *pending = value; if (safe_str_eq(rsc, pending->rsc_id)) { crm_info("Removing op %s:%d for deleted resource %s", pending->op_key, pending->call_id, rsc); return TRUE; } return FALSE; } /* * Remove the rsc from the CIB * * Avoids refreshing the entire LRM section of this host */ #define rsc_template "//"XML_CIB_TAG_STATE"[@uname='%s']//"XML_LRM_TAG_RESOURCE"[@id='%s']" static int delete_rsc_status(lrm_state_t * lrm_state, const char *rsc_id, int call_options, const char *user_name) { char *rsc_xpath = NULL; int max = 0; int rc = pcmk_ok; CRM_CHECK(rsc_id != NULL, return -ENXIO); max = strlen(rsc_template) + strlen(rsc_id) + strlen(lrm_state->node_name) + 1; rsc_xpath = calloc(1, max); snprintf(rsc_xpath, max, rsc_template, lrm_state->node_name, rsc_id); rc = cib_internal_op(fsa_cib_conn, CIB_OP_DELETE, NULL, rsc_xpath, NULL, NULL, call_options | cib_xpath, user_name); free(rsc_xpath); return rc; } static void delete_rsc_entry(lrm_state_t * lrm_state, ha_msg_input_t * input, const char *rsc_id, GHashTableIter * rsc_gIter, int rc, const char *user_name) { struct delete_event_s event; CRM_CHECK(rsc_id != NULL, return); if (rc == pcmk_ok) { char *rsc_id_copy = strdup(rsc_id); if (rsc_gIter) g_hash_table_iter_remove(rsc_gIter); else g_hash_table_remove(lrm_state->resource_history, rsc_id_copy); crm_debug("sync: Sending delete op for %s", rsc_id_copy); delete_rsc_status(lrm_state, rsc_id_copy, cib_quorum_override, user_name); g_hash_table_foreach_remove(lrm_state->pending_ops, lrm_remove_deleted_op, rsc_id_copy); free(rsc_id_copy); } if (input) { notify_deleted(lrm_state, input, rsc_id, rc); } event.rc = rc; event.rsc = rsc_id; event.lrm_state = lrm_state; g_hash_table_foreach_remove(lrm_state->deletion_ops, lrm_remove_deleted_rsc, &event); } /* * Remove the op from the CIB * * Avoids refreshing the entire LRM section of this host */ #define op_template "//"XML_CIB_TAG_STATE"[@uname='%s']//"XML_LRM_TAG_RESOURCE"[@id='%s']/"XML_LRM_TAG_RSC_OP"[@id='%s']" #define op_call_template "//"XML_CIB_TAG_STATE"[@uname='%s']//"XML_LRM_TAG_RESOURCE"[@id='%s']/"XML_LRM_TAG_RSC_OP"[@id='%s' and @"XML_LRM_ATTR_CALLID"='%d']" static void delete_op_entry(lrm_state_t * lrm_state, lrmd_event_data_t * op, const char *rsc_id, const char *key, int call_id) { xmlNode *xml_top = NULL; if (op != NULL) { xml_top = create_xml_node(NULL, XML_LRM_TAG_RSC_OP); crm_xml_add_int(xml_top, XML_LRM_ATTR_CALLID, op->call_id); crm_xml_add(xml_top, XML_ATTR_TRANSITION_KEY, op->user_data); if (op->interval > 0) { char *op_id = generate_op_key(op->rsc_id, op->op_type, op->interval); /* Avoid deleting last_failure too (if it was a result of this recurring op failing) */ crm_xml_add(xml_top, XML_ATTR_ID, op_id); free(op_id); } crm_debug("async: Sending delete op for %s_%s_%d (call=%d)", op->rsc_id, op->op_type, op->interval, op->call_id); fsa_cib_conn->cmds->delete(fsa_cib_conn, XML_CIB_TAG_STATUS, xml_top, cib_quorum_override); } else if (rsc_id != NULL && key != NULL) { int max = 0; char *op_xpath = NULL; if (call_id > 0) { max = strlen(op_call_template) + strlen(rsc_id) + strlen(lrm_state->node_name) + strlen(key) + 10; op_xpath = calloc(1, max); snprintf(op_xpath, max, op_call_template, lrm_state->node_name, rsc_id, key, call_id); } else { max = strlen(op_template) + strlen(rsc_id) + strlen(lrm_state->node_name) + strlen(key) + 1; op_xpath = calloc(1, max); snprintf(op_xpath, max, op_template, lrm_state->node_name, rsc_id, key); } crm_debug("sync: Sending delete op for %s (call=%d)", rsc_id, call_id); fsa_cib_conn->cmds->delete(fsa_cib_conn, op_xpath, NULL, cib_quorum_override | cib_xpath); free(op_xpath); } else { crm_err("Not enough information to delete op entry: rsc=%p key=%p", rsc_id, key); return; } crm_log_xml_trace(xml_top, "op:cancel"); free_xml(xml_top); } void lrm_clear_last_failure(const char *rsc_id, const char *node_name) { char *attr = NULL; GHashTableIter iter; GList *lrm_state_list = lrm_state_get_list(); GList *state_entry; rsc_history_t *entry = NULL; attr = generate_op_key(rsc_id, "last_failure", 0); /* This clears last failure for every lrm state that has this rsc.*/ for (state_entry = lrm_state_list; state_entry != NULL; state_entry = state_entry->next) { lrm_state_t *lrm_state = state_entry->data; if (node_name != NULL) { if (strcmp(node_name, lrm_state->node_name) != 0) { /* filter by node_name if node_name is present */ continue; } } delete_op_entry(lrm_state, NULL, rsc_id, attr, 0); if (!lrm_state->resource_history) { continue; } g_hash_table_iter_init(&iter, lrm_state->resource_history); while (g_hash_table_iter_next(&iter, NULL, (void **)&entry)) { if (safe_str_eq(rsc_id, entry->id)) { lrmd_free_event(entry->failed); entry->failed = NULL; } } } free(attr); g_list_free(lrm_state_list); } /* Returns: gboolean - cancellation is in progress */ static gboolean cancel_op(lrm_state_t * lrm_state, const char *rsc_id, const char *key, int op, gboolean remove) { int rc = pcmk_ok; struct recurring_op_s *pending = NULL; CRM_CHECK(op != 0, return FALSE); CRM_CHECK(rsc_id != NULL, return FALSE); if (key == NULL) { key = make_stop_id(rsc_id, op); } pending = g_hash_table_lookup(lrm_state->pending_ops, key); if (pending) { if (remove && pending->remove == FALSE) { pending->remove = TRUE; crm_debug("Scheduling %s for removal", key); } if (pending->cancelled) { crm_debug("Operation %s already cancelled", key); return FALSE; } pending->cancelled = TRUE; } else { crm_info("No pending op found for %s", key); return FALSE; } crm_debug("Cancelling op %d for %s (%s)", op, rsc_id, key); rc = lrm_state_cancel(lrm_state, pending->rsc_id, pending->op_type, pending->interval); if (rc == pcmk_ok) { crm_debug("Op %d for %s (%s): cancelled", op, rsc_id, key); } else { crm_debug("Op %d for %s (%s): Nothing to cancel", op, rsc_id, key); /* The caller needs to make sure the entry is * removed from the pending_ops list * * Usually by returning TRUE inside the worker function * supplied to g_hash_table_foreach_remove() * * Not removing the entry from pending_ops will block * the node from shutting down */ return FALSE; } return TRUE; } struct cancel_data { gboolean done; gboolean remove; const char *key; lrmd_rsc_info_t *rsc; lrm_state_t *lrm_state; }; static gboolean cancel_action_by_key(gpointer key, gpointer value, gpointer user_data) { gboolean remove = FALSE; struct cancel_data *data = user_data; struct recurring_op_s *op = (struct recurring_op_s *)value; if (safe_str_eq(op->op_key, data->key)) { data->done = TRUE; remove = !cancel_op(data->lrm_state, data->rsc->id, key, op->call_id, data->remove); } return remove; } static gboolean cancel_op_key(lrm_state_t * lrm_state, lrmd_rsc_info_t * rsc, const char *key, gboolean remove) { guint removed = 0; struct cancel_data data; CRM_CHECK(rsc != NULL, return FALSE); CRM_CHECK(key != NULL, return FALSE); data.key = key; data.rsc = rsc; data.done = FALSE; data.remove = remove; data.lrm_state = lrm_state; removed = g_hash_table_foreach_remove(lrm_state->pending_ops, cancel_action_by_key, &data); crm_trace("Removed %u op cache entries, new size: %u", removed, g_hash_table_size(lrm_state->pending_ops)); return data.done; } static lrmd_rsc_info_t * get_lrm_resource(lrm_state_t * lrm_state, xmlNode * resource, xmlNode * op_msg, gboolean do_create) { lrmd_rsc_info_t *rsc = NULL; const char *id = ID(resource); const char *type = crm_element_value(resource, XML_ATTR_TYPE); const char *class = crm_element_value(resource, XML_AGENT_ATTR_CLASS); const char *provider = crm_element_value(resource, XML_AGENT_ATTR_PROVIDER); const char *long_id = crm_element_value(resource, XML_ATTR_ID_LONG); crm_trace("Retrieving %s from the LRM.", id); CRM_CHECK(id != NULL, return NULL); rsc = lrm_state_get_rsc_info(lrm_state, id, 0); if (!rsc && long_id) { rsc = lrm_state_get_rsc_info(lrm_state, long_id, 0); } if (!rsc && do_create) { CRM_CHECK(class != NULL, return NULL); CRM_CHECK(type != NULL, return NULL); crm_trace("Adding rsc %s before operation", id); lrm_state_register_rsc(lrm_state, id, class, provider, type, lrmd_opt_drop_recurring); rsc = lrm_state_get_rsc_info(lrm_state, id, 0); if (!rsc) { fsa_data_t *msg_data = NULL; crm_err("Could not add resource %s to LRM", id); register_fsa_error(C_FSA_INTERNAL, I_FAIL, NULL); } } return rsc; } static void delete_resource(lrm_state_t * lrm_state, const char *id, lrmd_rsc_info_t * rsc, GHashTableIter * gIter, const char *sys, const char *host, const char *user, ha_msg_input_t * request) { int rc = pcmk_ok; crm_info("Removing resource %s for %s (%s) on %s", id, sys, user ? user : "internal", host); if (rsc) { rc = lrm_state_unregister_rsc(lrm_state, id, 0); } if (rc == pcmk_ok) { crm_trace("Resource '%s' deleted", id); } else if (rc == -EINPROGRESS) { crm_info("Deletion of resource '%s' pending", id); if (request) { struct pending_deletion_op_s *op = NULL; char *ref = crm_element_value_copy(request->msg, XML_ATTR_REFERENCE); op = calloc(1, sizeof(struct pending_deletion_op_s)); op->rsc = strdup(rsc->id); op->input = copy_ha_msg_input(request); g_hash_table_insert(lrm_state->deletion_ops, ref, op); } return; } else { crm_warn("Deletion of resource '%s' for %s (%s) on %s failed: %d", id, sys, user ? user : "internal", host, rc); } delete_rsc_entry(lrm_state, request, id, gIter, rc, user); } /* A_LRM_INVOKE */ void do_lrm_invoke(long long action, enum crmd_fsa_cause cause, enum crmd_fsa_state cur_state, enum crmd_fsa_input current_input, fsa_data_t * msg_data) { gboolean create_rsc = TRUE; lrm_state_t *lrm_state = NULL; const char *crm_op = NULL; const char *from_sys = NULL; const char *from_host = NULL; const char *operation = NULL; ha_msg_input_t *input = fsa_typed_data(fsa_dt_ha_msg); const char *user_name = NULL; const char *target_node = NULL; gboolean is_remote_node = FALSE; if (input->xml != NULL) { /* Remote node operations are routed here to their remote connections */ target_node = crm_element_value(input->xml, XML_LRM_ATTR_TARGET); } if (target_node == NULL) { target_node = fsa_our_uname; } else if (safe_str_neq(target_node, fsa_our_uname)) { is_remote_node = TRUE; } lrm_state = lrm_state_find(target_node); if (lrm_state == NULL && is_remote_node) { crm_err("no lrmd connection for remote node %s found on cluster node %s. Can not process request.", target_node, fsa_our_uname); return; } CRM_ASSERT(lrm_state != NULL); #if ENABLE_ACL user_name = crm_element_value(input->msg, F_CRM_USER); crm_trace("LRM command from user '%s'", user_name); #endif crm_op = crm_element_value(input->msg, F_CRM_TASK); from_sys = crm_element_value(input->msg, F_CRM_SYS_FROM); if (safe_str_neq(from_sys, CRM_SYSTEM_TENGINE)) { from_host = crm_element_value(input->msg, F_CRM_HOST_FROM); } crm_trace("LRM command from: %s", from_sys); if (safe_str_eq(crm_op, CRM_OP_LRM_DELETE)) { operation = CRMD_ACTION_DELETE; } else if (safe_str_eq(crm_op, CRM_OP_LRM_REFRESH)) { operation = CRM_OP_LRM_REFRESH; } else if (safe_str_eq(crm_op, CRM_OP_LRM_FAIL)) { rsc_history_t *entry = NULL; lrmd_event_data_t *op = NULL; lrmd_rsc_info_t *rsc = NULL; xmlNode *xml_rsc = find_xml_node(input->xml, XML_CIB_TAG_RESOURCE, TRUE); CRM_CHECK(xml_rsc != NULL, return); /* The lrmd can not fail a resource, it does not understand the * concept of success or failure in relation to a resource, it simply * executes operations and reports the results. We determine what a failure is. * Becaues of this, if we want to fail a resource we have to fake what we * understand a failure to look like. * * To do this we create a fake lrmd operation event for the resource * we want to fail. We then pass that event to the lrmd client callback * so it will be processed as if it actually came from the lrmd. */ op = construct_op(lrm_state, input->xml, ID(xml_rsc), "asyncmon"); CRM_ASSERT(op != NULL); free((char *)op->user_data); op->user_data = NULL; entry = g_hash_table_lookup(lrm_state->resource_history, op->rsc_id); /* Make sure the call id is greater than the last successful operation, * otherwise the failure will not result in a possible recovery of the resource * as it could appear the failure occurred before the successful start */ if (entry) { op->call_id = entry->last_callid + 1; if (op->call_id < 0) { op->call_id = 1; } } op->interval = 0; op->op_status = PCMK_LRM_OP_DONE; op->rc = PCMK_EXECRA_UNKNOWN_ERROR; op->t_run = time(NULL); op->t_rcchange = op->t_run; #if ENABLE_ACL if (user_name && is_privileged(user_name) == FALSE) { crm_err("%s does not have permission to fail %s", user_name, ID(xml_rsc)); send_direct_ack(from_host, from_sys, NULL, op, ID(xml_rsc)); lrmd_free_event(op); return; } #endif rsc = get_lrm_resource(lrm_state, xml_rsc, input->xml, create_rsc); if (rsc) { crm_info("Failing resource %s...", rsc->id); process_lrm_event(lrm_state, op); op->op_status = PCMK_LRM_OP_DONE; op->rc = PCMK_EXECRA_OK; lrmd_free_rsc_info(rsc); } else { crm_info("Cannot find/create resource in order to fail it..."); crm_log_xml_warn(input->msg, "bad input"); } send_direct_ack(from_host, from_sys, NULL, op, ID(xml_rsc)); lrmd_free_event(op); return; } else if (input->xml != NULL) { operation = crm_element_value(input->xml, XML_LRM_ATTR_TASK); } if (safe_str_eq(crm_op, CRM_OP_LRM_REFRESH)) { int rc = pcmk_ok; xmlNode *fragment = do_lrm_query_internal(lrm_state, TRUE); fsa_cib_update(XML_CIB_TAG_STATUS, fragment, cib_quorum_override, rc, user_name); crm_info("Forced a local LRM refresh: call=%d", rc); if(strcmp(CRM_SYSTEM_CRMD, from_sys) != 0) { xmlNode *reply = create_request( CRM_OP_INVOKE_LRM, fragment, from_host, from_sys, CRM_SYSTEM_LRMD, fsa_our_uuid); crm_debug("ACK'ing refresh from %s (%s)", from_sys, from_host); if (relay_message(reply, TRUE) == FALSE) { crm_log_xml_err(reply, "Unable to route reply"); } free_xml(reply); } free_xml(fragment); } else if (safe_str_eq(crm_op, CRM_OP_LRM_QUERY)) { xmlNode *data = do_lrm_query_internal(lrm_state, FALSE); xmlNode *reply = create_reply(input->msg, data); if (relay_message(reply, TRUE) == FALSE) { crm_err("Unable to route reply"); crm_log_xml_err(reply, "reply"); } free_xml(reply); free_xml(data); } else if (safe_str_eq(operation, CRM_OP_PROBED)) { update_attrd(lrm_state->node_name, CRM_OP_PROBED, XML_BOOLEAN_TRUE, user_name, is_remote_node); } else if (safe_str_eq(crm_op, CRM_OP_REPROBE)) { GHashTableIter gIter; rsc_history_t *entry = NULL; crm_notice("Forcing the status of all resources to be redetected"); g_hash_table_iter_init(&gIter, lrm_state->resource_history); while (g_hash_table_iter_next(&gIter, NULL, (void **)&entry)) { delete_resource(lrm_state, entry->id, &entry->rsc, &gIter, from_sys, from_host, user_name, NULL); } /* Now delete the copy in the CIB */ erase_status_tag(lrm_state->node_name, XML_CIB_TAG_LRM, cib_scope_local); /* And finally, _delete_ the value in attrd * Setting it to FALSE results in the PE sending us back here again */ update_attrd(lrm_state->node_name, CRM_OP_PROBED, NULL, user_name, is_remote_node); if(strcmp(CRM_SYSTEM_CRMD, from_sys) != 0) { xmlNode *reply = create_request( CRM_OP_INVOKE_LRM, NULL, from_host, from_sys, CRM_SYSTEM_LRMD, fsa_our_uuid); crm_debug("ACK'ing re-probe from %s (%s)", from_sys, from_host); if (relay_message(reply, TRUE) == FALSE) { crm_log_xml_err(reply, "Unable to route reply"); } free_xml(reply); } } else if (operation != NULL) { lrmd_rsc_info_t *rsc = NULL; xmlNode *params = NULL; xmlNode *xml_rsc = find_xml_node(input->xml, XML_CIB_TAG_RESOURCE, TRUE); CRM_CHECK(xml_rsc != NULL, return); /* only the first 16 chars are used by the LRM */ params = find_xml_node(input->xml, XML_TAG_ATTRS, TRUE); if (safe_str_eq(operation, CRMD_ACTION_DELETE)) { create_rsc = FALSE; } rsc = get_lrm_resource(lrm_state, xml_rsc, input->xml, create_rsc); if (rsc == NULL && create_rsc) { crm_err("Invalid resource definition"); crm_log_xml_warn(input->msg, "bad input"); } else if (rsc == NULL) { lrmd_event_data_t *op = NULL; crm_notice("Not creating resource for a %s event: %s", operation, ID(input->xml)); delete_rsc_entry(lrm_state, input, ID(xml_rsc), NULL, pcmk_ok, user_name); op = construct_op(lrm_state, input->xml, ID(xml_rsc), operation); op->op_status = PCMK_LRM_OP_DONE; op->rc = PCMK_EXECRA_OK; CRM_ASSERT(op != NULL); send_direct_ack(from_host, from_sys, NULL, op, ID(xml_rsc)); lrmd_free_event(op); } else if (safe_str_eq(operation, CRMD_ACTION_CANCEL)) { lrmd_event_data_t *op = NULL; char *op_key = NULL; char *meta_key = NULL; int call = 0; const char *call_id = NULL; const char *op_task = NULL; const char *op_interval = NULL; gboolean in_progress = FALSE; CRM_CHECK(params != NULL, crm_log_xml_warn(input->xml, "Bad command"); return); meta_key = crm_meta_name(XML_LRM_ATTR_INTERVAL); op_interval = crm_element_value(params, meta_key); free(meta_key); meta_key = crm_meta_name(XML_LRM_ATTR_TASK); op_task = crm_element_value(params, meta_key); free(meta_key); meta_key = crm_meta_name(XML_LRM_ATTR_CALLID); call_id = crm_element_value(params, meta_key); free(meta_key); CRM_CHECK(op_task != NULL, crm_log_xml_warn(input->xml, "Bad command"); return); CRM_CHECK(op_interval != NULL, crm_log_xml_warn(input->xml, "Bad command"); return); op = construct_op(lrm_state, input->xml, rsc->id, op_task); CRM_ASSERT(op != NULL); op_key = generate_op_key(rsc->id, op_task, crm_parse_int(op_interval, "0")); crm_debug("PE requested op %s (call=%s) be cancelled", op_key, call_id ? call_id : "NA"); call = crm_parse_int(call_id, "0"); if (call == 0) { /* the normal case when the PE cancels a recurring op */ in_progress = cancel_op_key(lrm_state, rsc, op_key, TRUE); } else { /* the normal case when the PE cancels an orphan op */ in_progress = cancel_op(lrm_state, rsc->id, NULL, call, TRUE); } if (in_progress == FALSE) { crm_debug("Nothing known about operation %d for %s", call, op_key); delete_op_entry(lrm_state, NULL, rsc->id, op_key, call); /* needed?? surely not otherwise the cancel_op_(_key) wouldn't * have failed in the first place */ g_hash_table_remove(lrm_state->pending_ops, op_key); } op->rc = PCMK_EXECRA_OK; op->op_status = PCMK_LRM_OP_DONE; send_direct_ack(from_host, from_sys, rsc, op, rsc->id); free(op_key); lrmd_free_event(op); } else if (rsc != NULL && safe_str_eq(operation, CRMD_ACTION_DELETE)) { #if ENABLE_ACL int cib_rc = delete_rsc_status(lrm_state, rsc->id, cib_dryrun | cib_sync_call, user_name); if (cib_rc != pcmk_ok) { lrmd_event_data_t *op = NULL; crm_err ("Attempted deletion of resource status '%s' from CIB for %s (user=%s) on %s failed: (rc=%d) %s", rsc->id, from_sys, user_name ? user_name : "unknown", from_host, cib_rc, pcmk_strerror(cib_rc)); op = construct_op(lrm_state, input->xml, rsc->id, operation); op->op_status = PCMK_LRM_OP_ERROR; if (cib_rc == -EACCES) { op->rc = PCMK_EXECRA_INSUFFICIENT_PRIV; } else { op->rc = PCMK_EXECRA_UNKNOWN_ERROR; } send_direct_ack(from_host, from_sys, NULL, op, rsc->id); lrmd_free_event(op); return; } #endif delete_resource(lrm_state, rsc->id, rsc, NULL, from_sys, from_host, user_name, input); } else if (rsc != NULL) { do_lrm_rsc_op(lrm_state, rsc, operation, input->xml, input->msg); } lrmd_free_rsc_info(rsc); } else { crm_err("Operation was neither a lrm_query, nor a rsc op. %s", crm_str(crm_op)); register_fsa_error(C_FSA_INTERNAL, I_ERROR, NULL); } } static lrmd_event_data_t * construct_op(lrm_state_t * lrm_state, xmlNode * rsc_op, const char *rsc_id, const char *operation) { lrmd_event_data_t *op = NULL; const char *op_delay = NULL; const char *op_timeout = NULL; const char *op_interval = NULL; GHashTable *params = NULL; const char *transition = NULL; CRM_LOG_ASSERT(rsc_id != NULL); op = calloc(1, sizeof(lrmd_event_data_t)); op->type = lrmd_event_exec_complete; op->op_type = strdup(operation); op->op_status = PCMK_LRM_OP_PENDING; op->rc = -1; op->rsc_id = strdup(rsc_id); op->interval = 0; op->timeout = 0; op->start_delay = 0; if (rsc_op == NULL) { CRM_LOG_ASSERT(safe_str_eq(CRMD_ACTION_STOP, operation)); op->user_data = NULL; /* the stop_all_resources() case * by definition there is no DC (or they'd be shutting * us down). * So we should put our version here. */ op->params = g_hash_table_new_full(crm_str_hash, g_str_equal, g_hash_destroy_str, g_hash_destroy_str); g_hash_table_insert(op->params, strdup(XML_ATTR_CRM_VERSION), strdup(CRM_FEATURE_SET)); crm_trace("Constructed %s op for %s", operation, rsc_id); return op; } params = xml2list(rsc_op); g_hash_table_remove(params, CRM_META "_op_target_rc"); op_delay = crm_meta_value(params, XML_OP_ATTR_START_DELAY); op_timeout = crm_meta_value(params, XML_ATTR_TIMEOUT); op_interval = crm_meta_value(params, XML_LRM_ATTR_INTERVAL); op->interval = crm_parse_int(op_interval, "0"); op->timeout = crm_parse_int(op_timeout, "0"); op->start_delay = crm_parse_int(op_delay, "0"); if (safe_str_neq(operation, RSC_STOP)) { op->params = params; } else { rsc_history_t *entry = g_hash_table_lookup(lrm_state->resource_history, rsc_id); /* If we do not have stop parameters cached, use * whatever we are given */ if (!entry || !entry->stop_params) { op->params = params; } else { /* Copy the cached parameter list so that we stop the resource * with the old attributes, not the new ones */ op->params = g_hash_table_new_full(crm_str_hash, g_str_equal, g_hash_destroy_str, g_hash_destroy_str); g_hash_table_foreach(params, copy_meta_keys, op->params); g_hash_table_foreach(entry->stop_params, copy_instance_keys, op->params); g_hash_table_destroy(params); params = NULL; } } /* sanity */ if (op->interval < 0) { op->interval = 0; } if (op->timeout <= 0) { op->timeout = op->interval; } if (op->start_delay < 0) { op->start_delay = 0; } transition = crm_element_value(rsc_op, XML_ATTR_TRANSITION_KEY); CRM_CHECK(transition != NULL, return op); op->user_data = strdup(transition); if (op->interval != 0) { if (safe_str_eq(operation, CRMD_ACTION_START) || safe_str_eq(operation, CRMD_ACTION_STOP)) { crm_err("Start and Stop actions cannot have an interval: %d", op->interval); op->interval = 0; } } crm_trace("Constructed %s op for %s: interval=%d", operation, rsc_id, op->interval); return op; } void send_direct_ack(const char *to_host, const char *to_sys, lrmd_rsc_info_t * rsc, lrmd_event_data_t * op, const char *rsc_id) { xmlNode *reply = NULL; xmlNode *update, *iter; xmlNode *fragment; crm_node_t *peer = NULL; CRM_CHECK(op != NULL, return); if (op->rsc_id == NULL) { CRM_LOG_ASSERT(rsc_id != NULL); op->rsc_id = strdup(rsc_id); } if (to_sys == NULL) { to_sys = CRM_SYSTEM_TENGINE; } peer = crm_get_peer(0, fsa_our_uname); update = do_update_node_cib(peer, node_update_none, NULL, __FUNCTION__); iter = create_xml_node(update, XML_CIB_TAG_LRM); crm_xml_add(iter, XML_ATTR_ID, fsa_our_uuid); iter = create_xml_node(iter, XML_LRM_TAG_RESOURCES); iter = create_xml_node(iter, XML_LRM_TAG_RESOURCE); crm_xml_add(iter, XML_ATTR_ID, op->rsc_id); build_operation_update(iter, rsc, op, __FUNCTION__); fragment = create_cib_fragment(update, XML_CIB_TAG_STATUS); reply = create_request(CRM_OP_INVOKE_LRM, fragment, to_host, to_sys, CRM_SYSTEM_LRMD, NULL); crm_log_xml_trace(update, "ACK Update"); crm_debug("ACK'ing resource op %s_%s_%d from %s: %s", op->rsc_id, op->op_type, op->interval, op->user_data, crm_element_value(reply, XML_ATTR_REFERENCE)); if (relay_message(reply, TRUE) == FALSE) { crm_log_xml_err(reply, "Unable to route reply"); } free_xml(fragment); free_xml(update); free_xml(reply); } gboolean verify_stopped(enum crmd_fsa_state cur_state, int log_level) { gboolean res = TRUE; GList *lrm_state_list = lrm_state_get_list(); GList *state_entry; for (state_entry = lrm_state_list; state_entry != NULL; state_entry = state_entry->next) { lrm_state_t *lrm_state = state_entry->data; if (!lrm_state_verify_stopped(lrm_state, cur_state, log_level)) { /* keep iterating through all even when false is returned */ res = FALSE; } } set_bit(fsa_input_register, R_SENT_RSC_STOP); g_list_free(lrm_state_list); lrm_state_list = NULL; return res; } struct stop_recurring_action_s { lrmd_rsc_info_t *rsc; lrm_state_t *lrm_state; }; static gboolean stop_recurring_action_by_rsc(gpointer key, gpointer value, gpointer user_data) { gboolean remove = FALSE; struct stop_recurring_action_s *event = user_data; struct recurring_op_s *op = (struct recurring_op_s *)value; if (op->interval != 0 && safe_str_eq(op->rsc_id, event->rsc->id)) { crm_debug("Cancelling op %d for %s (%s)", op->call_id, op->rsc_id, key); remove = !cancel_op(event->lrm_state, event->rsc->id, key, op->call_id, FALSE); } return remove; } static gboolean stop_recurring_actions(gpointer key, gpointer value, gpointer user_data) { gboolean remove = FALSE; lrm_state_t *lrm_state = user_data; struct recurring_op_s *op = (struct recurring_op_s *)value; if (op->interval != 0) { crm_info("Cancelling op %d for %s (%s)", op->call_id, op->rsc_id, key); remove = !cancel_op(lrm_state, op->rsc_id, key, op->call_id, FALSE); } return remove; } static void do_lrm_rsc_op(lrm_state_t * lrm_state, lrmd_rsc_info_t * rsc, const char *operation, xmlNode * msg, xmlNode * request) { int call_id = 0; char *op_id = NULL; lrmd_event_data_t *op = NULL; lrmd_key_value_t *params = NULL; fsa_data_t *msg_data = NULL; const char *transition = NULL; CRM_CHECK(rsc != NULL, return); CRM_CHECK(operation != NULL, return); if (msg != NULL) { transition = crm_element_value(msg, XML_ATTR_TRANSITION_KEY); if (transition == NULL) { crm_log_xml_err(msg, "Missing transition number"); } } op = construct_op(lrm_state, msg, rsc->id, operation); CRM_CHECK(op != NULL, return); /* stop any previous monitor operations before changing the resource state */ if (op->interval == 0 && strcmp(operation, CRMD_ACTION_STATUS) != 0 && strcmp(operation, CRMD_ACTION_NOTIFY) != 0) { guint removed = 0; struct stop_recurring_action_s data; data.rsc = rsc; data.lrm_state = lrm_state; removed = g_hash_table_foreach_remove( lrm_state->pending_ops, stop_recurring_action_by_rsc, &data); crm_debug("Stopped %u recurring operations in preparation for %s_%s_%d", removed, rsc->id, operation, op->interval); } /* now do the op */ crm_info("Performing key=%s op=%s_%s_%d", transition, rsc->id, operation, op->interval); if (fsa_state != S_NOT_DC && fsa_state != S_POLICY_ENGINE && fsa_state != S_TRANSITION_ENGINE) { if (safe_str_neq(operation, "fail") && safe_str_neq(operation, CRMD_ACTION_STOP)) { crm_info("Discarding attempt to perform action %s on %s in state %s", operation, rsc->id, fsa_state2string(fsa_state)); op->rc = 99; op->op_status = PCMK_LRM_OP_ERROR; send_direct_ack(NULL, NULL, rsc, op, rsc->id); lrmd_free_event(op); free(op_id); return; } } op_id = generate_op_key(rsc->id, op->op_type, op->interval); if (op->interval > 0) { /* cancel it so we can then restart it without conflict */ cancel_op_key(lrm_state, rsc, op_id, FALSE); } if (op->params) { char *key = NULL; char *value = NULL; GHashTableIter iter; g_hash_table_iter_init(&iter, op->params); while (g_hash_table_iter_next(&iter, (gpointer *) & key, (gpointer *) & value)) { params = lrmd_key_value_add(params, key, value); } } call_id = lrm_state_exec(lrm_state, rsc->id, op->op_type, op->user_data, op->interval, op->timeout, op->start_delay, params); if (call_id <= 0) { crm_err("Operation %s on %s failed: %d", operation, rsc->id, call_id); register_fsa_error(C_FSA_INTERNAL, I_FAIL, NULL); } else { /* record all operations so we can wait * for them to complete during shutdown */ char *call_id_s = make_stop_id(rsc->id, call_id); struct recurring_op_s *pending = NULL; pending = calloc(1, sizeof(struct recurring_op_s)); crm_trace("Recording pending op: %d - %s %s", call_id, op_id, call_id_s); pending->call_id = call_id; pending->interval = op->interval; pending->op_type = strdup(operation); pending->op_key = strdup(op_id); pending->rsc_id = strdup(rsc->id); g_hash_table_replace(lrm_state->pending_ops, call_id_s, pending); if (op->interval > 0 && op->start_delay > START_DELAY_THRESHOLD) { char *uuid = NULL; int dummy = 0, target_rc = 0; crm_info("Faking confirmation of %s: execution postponed for over 5 minutes", op_id); decode_transition_key(op->user_data, &uuid, &dummy, &dummy, &target_rc); free(uuid); op->rc = target_rc; op->op_status = PCMK_LRM_OP_DONE; send_direct_ack(NULL, NULL, rsc, op, rsc->id); } } free(op_id); lrmd_free_event(op); return; } int last_resource_update = 0; static void cib_rsc_callback(xmlNode * msg, int call_id, int rc, xmlNode * output, void *user_data) { switch (rc) { case pcmk_ok: case -pcmk_err_diff_failed: case -pcmk_err_diff_resync: crm_trace("Resource update %d complete: rc=%d", call_id, rc); break; default: crm_warn("Resource update %d failed: (rc=%d) %s", call_id, rc, pcmk_strerror(rc)); } if (call_id == last_resource_update) { last_resource_update = 0; trigger_fsa(fsa_source); } } static int do_update_resource(lrm_state_t * lrm_state, lrmd_rsc_info_t * rsc, lrmd_event_data_t * op) { /* */ int rc = pcmk_ok; xmlNode *update, *iter = NULL; int call_opt = cib_quorum_override; const char *uuid = NULL; CRM_CHECK(op != NULL, return 0); if (fsa_state == S_ELECTION || fsa_state == S_PENDING) { crm_info("Sending update to local CIB in state: %s", fsa_state2string(fsa_state)); call_opt |= cib_scope_local; } iter = create_xml_node(iter, XML_CIB_TAG_STATUS); update = iter; iter = create_xml_node(iter, XML_CIB_TAG_STATE); if (safe_str_eq(lrm_state->node_name, fsa_our_uname)) { uuid = fsa_our_uuid; } else { /* remote nodes uuid and uname are equal */ uuid = lrm_state->node_name; crm_xml_add(iter, XML_NODE_IS_REMOTE, "true"); } CRM_LOG_ASSERT(uuid != NULL); if(uuid == NULL) { rc = -EINVAL; goto done; } crm_xml_add(iter, XML_ATTR_UUID, uuid); crm_xml_add(iter, XML_ATTR_UNAME, lrm_state->node_name); crm_xml_add(iter, XML_ATTR_ORIGIN, __FUNCTION__); iter = create_xml_node(iter, XML_CIB_TAG_LRM); crm_xml_add(iter, XML_ATTR_ID, uuid); iter = create_xml_node(iter, XML_LRM_TAG_RESOURCES); iter = create_xml_node(iter, XML_LRM_TAG_RESOURCE); crm_xml_add(iter, XML_ATTR_ID, op->rsc_id); build_operation_update(iter, rsc, op, __FUNCTION__); if (rsc) { crm_xml_add(iter, XML_ATTR_TYPE, rsc->type); crm_xml_add(iter, XML_AGENT_ATTR_CLASS, rsc->class); crm_xml_add(iter, XML_AGENT_ATTR_PROVIDER, rsc->provider); CRM_CHECK(rsc->type != NULL, crm_err("Resource %s has no value for type", op->rsc_id)); CRM_CHECK(rsc->class != NULL, crm_err("Resource %s has no value for class", op->rsc_id)); } else { crm_warn("Resource %s no longer exists in the lrmd", op->rsc_id); send_direct_ack(NULL, NULL, rsc, op, op->rsc_id); goto cleanup; } crm_log_xml_trace(update, __FUNCTION__); /* make it an asyncronous call and be done with it * * Best case: * the resource state will be discovered during * the next signup or election. * * Bad case: * we are shutting down and there is no DC at the time, * but then why were we shutting down then anyway? * (probably because of an internal error) * * Worst case: * we get shot for having resources "running" when the really weren't * * the alternative however means blocking here for too long, which * isnt acceptable */ fsa_cib_update(XML_CIB_TAG_STATUS, update, call_opt, rc, NULL); if (rc > 0) { last_resource_update = rc; } done: /* the return code is a call number, not an error code */ crm_trace("Sent resource state update message: %d for %s=%d on %s", rc, op->op_type, op->interval, op->rsc_id); fsa_register_cib_callback(rc, FALSE, NULL, cib_rsc_callback); cleanup: free_xml(update); return rc; } void do_lrm_event(long long action, enum crmd_fsa_cause cause, enum crmd_fsa_state cur_state, enum crmd_fsa_input cur_input, fsa_data_t * msg_data) { CRM_CHECK(FALSE, return); } gboolean process_lrm_event(lrm_state_t * lrm_state, lrmd_event_data_t * op) { char *op_id = NULL; char *op_key = NULL; int update_id = 0; int log_level = LOG_ERR; gboolean removed = FALSE; lrmd_rsc_info_t *rsc = NULL; struct recurring_op_s *pending = NULL; CRM_CHECK(op != NULL, return FALSE); CRM_CHECK(op->rsc_id != NULL, return FALSE); op_id = make_stop_id(op->rsc_id, op->call_id); pending = g_hash_table_lookup(lrm_state->pending_ops, op_id); op_key = generate_op_key(op->rsc_id, op->op_type, op->interval); rsc = lrm_state_get_rsc_info(lrm_state, op->rsc_id, 0); switch (op->op_status) { case PCMK_LRM_OP_ERROR: case PCMK_LRM_OP_PENDING: case PCMK_LRM_OP_NOTSUPPORTED: break; case PCMK_LRM_OP_CANCELLED: log_level = LOG_INFO; break; case PCMK_LRM_OP_DONE: log_level = LOG_NOTICE; break; case PCMK_LRM_OP_TIMEOUT: log_level = LOG_DEBUG_3; crm_err("LRM operation %s (%d) %s (timeout=%dms)", op_key, op->call_id, services_lrm_status_str(op->op_status), op->timeout); break; default: crm_err("Mapping unknown status (%d) to ERROR", op->op_status); op->op_status = PCMK_LRM_OP_ERROR; } if (op->op_status == PCMK_LRM_OP_ERROR && (op->rc == PCMK_EXECRA_RUNNING_MASTER || op->rc == PCMK_EXECRA_NOT_RUNNING)) { /* Leave it up to the TE/PE to decide if this is an error */ op->op_status = PCMK_LRM_OP_DONE; log_level = LOG_INFO; } if (op->op_status != PCMK_LRM_OP_CANCELLED) { if (safe_str_eq(op->op_type, RSC_NOTIFY)) { /* Keep notify ops out of the CIB */ send_direct_ack(NULL, NULL, NULL, op, op->rsc_id); } else { update_id = do_update_resource(lrm_state, rsc, op); } } else if (op->interval == 0) { /* This will occur when "crm resource cleanup" is called while actions are in-flight */ crm_err("Op %s (call=%d): Cancelled", op_key, op->call_id); send_direct_ack(NULL, NULL, NULL, op, op->rsc_id); } else if (pending == NULL) { /* Operations that are cancelled may safely be removed * from the pending op list before the lrmd completion event * is received. Only report non-cancelled ops here. */ if (op->op_status != PCMK_LRM_OP_CANCELLED) { crm_err("Op %s (call=%d): No 'pending' entry", op_key, op->call_id); } } else if (op->user_data == NULL) { crm_err("Op %s (call=%d): No user data", op_key, op->call_id); } else if (pending->remove) { delete_op_entry(lrm_state, op, op->rsc_id, op_key, op->call_id); } else { /* Before a stop is called, no need to direct ack */ crm_trace("Op %s (call=%d): no delete event required", op_key, op->call_id); } if ((op->interval == 0) && g_hash_table_remove(lrm_state->pending_ops, op_id)) { removed = TRUE; crm_trace("Op %s (call=%d, stop-id=%s, remaining=%u): Confirmed", op_key, op->call_id, op_id, g_hash_table_size(lrm_state->pending_ops)); } else if(op->interval != 0 && op->op_status == PCMK_LRM_OP_CANCELLED) { removed = TRUE; g_hash_table_remove(lrm_state->pending_ops, op_id); } if (op->op_status == PCMK_LRM_OP_DONE) { do_crm_log(log_level, "LRM operation %s (call=%d, rc=%d, cib-update=%d, confirmed=%s) %s", op_key, op->call_id, op->rc, update_id, removed ? "true" : "false", lrmd_event_rc2str(op->rc)); } else { do_crm_log(log_level, "LRM operation %s (call=%d, status=%d, cib-update=%d, confirmed=%s) %s", op_key, op->call_id, op->op_status, update_id, removed ? "true" : "false", services_lrm_status_str(op->op_status)); } if (op->output) { char *prefix = g_strdup_printf("%s-%s_%s_%d:%d", lrm_state->node_name, op->rsc_id, op->op_type, op->interval, op->call_id); if (op->rc) { crm_log_output(LOG_NOTICE, prefix, op->output); } else { crm_log_output(LOG_DEBUG, prefix, op->output); } g_free(prefix); } if (op->rsc_deleted) { crm_info("Deletion of resource '%s' complete after %s", op->rsc_id, op_key); delete_rsc_entry(lrm_state, NULL, op->rsc_id, NULL, pcmk_ok, NULL); } /* If a shutdown was escalated while operations were pending, * then the FSA will be stalled right now... allow it to continue */ mainloop_set_trigger(fsa_source); update_history_cache(lrm_state, rsc, op); lrmd_free_rsc_info(rsc); free(op_key); free(op_id); return TRUE; } pacemaker-master/crmd/lrm_state.c000066400000000000000000000472111217637305600174010ustar00rootroot00000000000000/* * Copyright (C) 2012 David Vossel * * 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 2 of the License, or (at your option) any later version. * * This software 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 library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include #include #include #include #include #include #include GHashTable *lrm_state_table = NULL; GHashTable *proxy_table = NULL; int lrmd_internal_proxy_send(lrmd_t * lrmd, xmlNode *msg); void lrmd_internal_set_proxy_callback(lrmd_t * lrmd, void *userdata, void (*callback)(lrmd_t *lrmd, void *userdata, xmlNode *msg)); typedef struct remote_proxy_s { char *node_name; char *session_id; gboolean is_local; crm_ipc_t *ipc; mainloop_io_t *source; } remote_proxy_t; static void history_cache_destroy(gpointer data) { rsc_history_t *entry = data; if (entry->stop_params) { g_hash_table_destroy(entry->stop_params); } free(entry->rsc.type); free(entry->rsc.class); free(entry->rsc.provider); lrmd_free_event(entry->failed); lrmd_free_event(entry->last); free(entry->id); free(entry); } static void free_deletion_op(gpointer value) { struct pending_deletion_op_s *op = value; free(op->rsc); delete_ha_msg_input(op->input); free(op); } static void free_recurring_op(gpointer value) { struct recurring_op_s *op = (struct recurring_op_s *)value; free(op->rsc_id); free(op->op_type); free(op->op_key); free(op); } lrm_state_t * lrm_state_create(const char *node_name) { lrm_state_t *state = NULL; if (!node_name) { crm_err("No node name given for lrm state object"); return NULL; } state = calloc(1, sizeof(lrm_state_t)); if (!state) { return NULL; } state->node_name = strdup(node_name); state->deletion_ops = g_hash_table_new_full(crm_str_hash, g_str_equal, g_hash_destroy_str, free_deletion_op); state->pending_ops = g_hash_table_new_full(crm_str_hash, g_str_equal, g_hash_destroy_str, free_recurring_op); state->resource_history = g_hash_table_new_full(crm_str_hash, g_str_equal, NULL, history_cache_destroy); g_hash_table_insert(lrm_state_table, (char *)state->node_name, state); return state; } void lrm_state_destroy(const char *node_name) { g_hash_table_remove(lrm_state_table, node_name); } static gboolean remote_proxy_remove_by_node(gpointer key, gpointer value, gpointer user_data) { remote_proxy_t *proxy = value; const char *node_name = user_data; if (safe_str_eq(node_name, proxy->node_name)) { return TRUE; } return FALSE; } static void internal_lrm_state_destroy(gpointer data) { lrm_state_t *lrm_state = data; if (!lrm_state) { return; } crm_trace("Destroying proxy table with %d members", g_hash_table_size(proxy_table)); g_hash_table_foreach_remove(proxy_table, remote_proxy_remove_by_node, (char *) lrm_state->node_name); remote_ra_cleanup(lrm_state); lrmd_api_delete(lrm_state->conn); if (lrm_state->resource_history) { crm_trace("Destroying history op cache with %d members", g_hash_table_size(lrm_state->resource_history)); g_hash_table_destroy(lrm_state->resource_history); } if (lrm_state->deletion_ops) { crm_trace("Destroying deletion op cache with %d members", g_hash_table_size(lrm_state->deletion_ops)); g_hash_table_destroy(lrm_state->deletion_ops); } if (lrm_state->pending_ops) { crm_trace("Destroying pending op cache with %d members", g_hash_table_size(lrm_state->pending_ops)); g_hash_table_destroy(lrm_state->pending_ops); } free((char *)lrm_state->node_name); free(lrm_state); } void lrm_state_reset_tables(lrm_state_t * lrm_state) { if (lrm_state->resource_history) { crm_trace("Re-setting history op cache with %d members", g_hash_table_size(lrm_state->resource_history)); g_hash_table_remove_all(lrm_state->resource_history); } if (lrm_state->deletion_ops) { crm_trace("Re-setting deletion op cache with %d members", g_hash_table_size(lrm_state->deletion_ops)); g_hash_table_remove_all(lrm_state->deletion_ops); } if (lrm_state->pending_ops) { crm_trace("Re-setting pending op cache with %d members", g_hash_table_size(lrm_state->pending_ops)); g_hash_table_remove_all(lrm_state->pending_ops); } } static void remote_proxy_free(gpointer data) { remote_proxy_t *proxy = data; crm_debug("Signing out of the IPC Service"); if (proxy->source != NULL) { mainloop_del_ipc_client(proxy->source); } free(proxy->node_name); free(proxy->session_id); } gboolean lrm_state_init_local(void) { if (lrm_state_table) { return TRUE; } lrm_state_table = g_hash_table_new_full(crm_str_hash, g_str_equal, NULL, internal_lrm_state_destroy); if (!lrm_state_table) { return FALSE; } proxy_table = g_hash_table_new_full(crm_str_hash, g_str_equal, NULL, remote_proxy_free); if (!proxy_table) { g_hash_table_destroy(lrm_state_table); return FALSE; } return TRUE; } void lrm_state_destroy_all(void) { if (lrm_state_table) { crm_trace("Destroying state table with %d members", g_hash_table_size(lrm_state_table)); g_hash_table_destroy(lrm_state_table); lrm_state_table = NULL; } if(proxy_table) { crm_trace("Destroying proxy table with %d members", g_hash_table_size(proxy_table)); g_hash_table_destroy(proxy_table); proxy_table = NULL; } } lrm_state_t * lrm_state_find(const char *node_name) { if (!node_name) { return NULL; } return g_hash_table_lookup(lrm_state_table, node_name); } lrm_state_t * lrm_state_find_or_create(const char *node_name) { lrm_state_t *lrm_state; lrm_state = g_hash_table_lookup(lrm_state_table, node_name); if (!lrm_state) { lrm_state = lrm_state_create(node_name); } return lrm_state; } GList * lrm_state_get_list(void) { return g_hash_table_get_values(lrm_state_table); } void lrm_state_disconnect(lrm_state_t * lrm_state) { if (!lrm_state->conn) { return; } ((lrmd_t *) lrm_state->conn)->cmds->disconnect(lrm_state->conn); lrmd_api_delete(lrm_state->conn); lrm_state->conn = NULL; } int lrm_state_is_connected(lrm_state_t * lrm_state) { if (!lrm_state->conn) { return FALSE; } return ((lrmd_t *) lrm_state->conn)->cmds->is_connected(lrm_state->conn); } int lrm_state_poke_connection(lrm_state_t * lrm_state) { if (!lrm_state->conn) { return -1; } return ((lrmd_t *) lrm_state->conn)->cmds->poke_connection(lrm_state->conn); } int lrm_state_ipc_connect(lrm_state_t * lrm_state) { int ret; if (!lrm_state->conn) { lrm_state->conn = lrmd_api_new(); ((lrmd_t *) lrm_state->conn)->cmds->set_callback(lrm_state->conn, lrm_op_callback); } ret = ((lrmd_t *) lrm_state->conn)->cmds->connect(lrm_state->conn, CRM_SYSTEM_CRMD, NULL); if (ret != pcmk_ok) { lrm_state->num_lrm_register_fails++; } else { lrm_state->num_lrm_register_fails = 0; } return ret; } static void remote_proxy_notify_destroy(lrmd_t *lrmd, const char *session_id) { /* sending to the remote node that an ipc connection has been destroyed */ xmlNode *msg = create_xml_node(NULL, T_LRMD_IPC_PROXY); crm_xml_add(msg, F_LRMD_IPC_OP, "destroy"); crm_xml_add(msg, F_LRMD_IPC_SESSION, session_id); lrmd_internal_proxy_send(lrmd, msg); free_xml(msg); } static void remote_proxy_relay_event(lrmd_t *lrmd, const char *session_id, xmlNode *msg) { /* sending to the remote node an event msg. */ xmlNode *event = create_xml_node(NULL, T_LRMD_IPC_PROXY); crm_xml_add(event, F_LRMD_IPC_OP, "event"); crm_xml_add(event, F_LRMD_IPC_SESSION, session_id); add_message_xml(event, F_LRMD_IPC_MSG, msg); lrmd_internal_proxy_send(lrmd, event); free_xml(event); } static void remote_proxy_relay_response(lrmd_t *lrmd, const char *session_id, xmlNode *msg, int msg_id) { /* sending to the remote node a response msg. */ xmlNode *response = create_xml_node(NULL, T_LRMD_IPC_PROXY); crm_xml_add(response, F_LRMD_IPC_OP, "response"); crm_xml_add(response, F_LRMD_IPC_SESSION, session_id); crm_xml_add_int(response, F_LRMD_IPC_MSG_ID, msg_id); add_message_xml(response, F_LRMD_IPC_MSG, msg); lrmd_internal_proxy_send(lrmd, response); free_xml(response); } static int remote_proxy_dispatch_internal(const char *buffer, ssize_t length, gpointer userdata) { xmlNode *xml = NULL; remote_proxy_t *proxy = userdata; lrm_state_t *lrm_state = lrm_state_find(proxy->node_name); if (lrm_state == NULL) { return 0; } xml = string2xml(buffer); if (xml == NULL) { crm_warn("Received a NULL msg from IPC service."); return 1; } remote_proxy_relay_event(lrm_state->conn, proxy->session_id, xml); free_xml(xml); return 1; } static void remote_proxy_disconnected(void *userdata) { remote_proxy_t *proxy = userdata; lrm_state_t *lrm_state = lrm_state_find(proxy->node_name); crm_trace("destroying %p", userdata); proxy->source = NULL; proxy->ipc = NULL; if (lrm_state && lrm_state->conn) { remote_proxy_notify_destroy(lrm_state->conn, proxy->session_id); } g_hash_table_remove(proxy_table, proxy->session_id); } static remote_proxy_t * remote_proxy_new(const char *node_name, const char *session_id, const char *channel) { static struct ipc_client_callbacks proxy_callbacks = { .dispatch = remote_proxy_dispatch_internal, .destroy = remote_proxy_disconnected }; remote_proxy_t *proxy = calloc(1, sizeof(remote_proxy_t)); proxy->node_name = strdup(node_name); proxy->session_id = strdup(session_id); if (safe_str_eq(channel, CRM_SYSTEM_CRMD)) { proxy->is_local = TRUE; } else { proxy->source = mainloop_add_ipc_client(channel, G_PRIORITY_LOW, 512 * 1024 /* 512k */ , proxy, &proxy_callbacks); proxy->ipc = mainloop_get_ipc_client(proxy->source); if (proxy->source == NULL) { remote_proxy_free(proxy); return NULL; } } g_hash_table_insert(proxy_table, proxy->session_id, proxy); return proxy; } gboolean crmd_is_proxy_session(const char *session) { return g_hash_table_lookup(proxy_table, session) ? TRUE : FALSE; } void crmd_proxy_send(const char *session, xmlNode *msg) { remote_proxy_t *proxy = g_hash_table_lookup(proxy_table, session); lrm_state_t *lrm_state = NULL; if (!proxy) { return; } lrm_state = lrm_state_find(proxy->node_name); if (lrm_state) { remote_proxy_relay_event(lrm_state->conn, session, msg); } } static void crmd_proxy_dispatch(const char *user, const char *session, xmlNode *msg) { #if ENABLE_ACL determine_request_user(user, msg, F_CRM_USER); #endif crm_log_xml_trace(msg, "CRMd-PROXY[inbound]"); crm_xml_add(msg, F_CRM_SYS_FROM, session); if (crmd_authorize_message(msg, NULL, session)) { route_message(C_IPC_MESSAGE, msg); } trigger_fsa(fsa_source); } static void remote_proxy_cb(lrmd_t *lrmd, void *userdata, xmlNode *msg) { lrm_state_t *lrm_state = userdata; xmlNode *op_reply = NULL; const char *op = crm_element_value(msg, F_LRMD_IPC_OP); const char *session = crm_element_value(msg, F_LRMD_IPC_SESSION); const char *user = crm_element_value(msg, F_LRMD_IPC_USER); int msg_id = 0; /* sessions are raw ipc connections to IPC, * all we do is proxy requests/responses exactly * like they are given to us at the ipc level. */ CRM_CHECK(op != NULL, return); CRM_CHECK(session != NULL, return); crm_element_value_int(msg, F_LRMD_IPC_MSG_ID, &msg_id); /* This is msg from remote ipc client going to real ipc server */ if (safe_str_eq(op, "new")) { const char *channel = crm_element_value(msg, F_LRMD_IPC_IPC_SERVER); CRM_CHECK(channel != NULL, return); if (remote_proxy_new(lrm_state->node_name, session, channel) == NULL) { remote_proxy_notify_destroy(lrmd, session); } crm_info("new remote proxy client established, session id %s", session); } else if (safe_str_eq(op, "destroy")) { g_hash_table_remove(proxy_table, session); } else if (safe_str_eq(op, "request")) { int flags = 0; xmlNode *request = get_message_xml(msg, F_LRMD_IPC_MSG); remote_proxy_t *proxy = g_hash_table_lookup(proxy_table, session); CRM_CHECK(request != NULL, return); if (proxy == NULL) { /* proxy connection no longer exists */ remote_proxy_notify_destroy(lrmd, session); return; } else if ((proxy->is_local == FALSE) && (crm_ipc_connected(proxy->ipc) == FALSE)) { g_hash_table_remove(proxy_table, session); return; } crm_element_value_int(msg, F_LRMD_IPC_MSG_FLAGS, &flags); if (proxy->is_local) { /* this is for the crmd, which we are, so don't try * and connect/send to ourselves over ipc. instead * do it directly. */ if (flags & crm_ipc_client_response) { op_reply = create_xml_node(NULL, "ack"); crm_xml_add(op_reply, "function", __FUNCTION__); crm_xml_add_int(op_reply, "line", __LINE__); } crmd_proxy_dispatch(user, session, request); } else { /* TODO make this async. */ crm_ipc_send(proxy->ipc, request, flags, 10000, &op_reply); } } if (op_reply) { remote_proxy_relay_response(lrmd, session, op_reply, msg_id); free_xml(op_reply); } } int lrm_state_remote_connect_async(lrm_state_t * lrm_state, const char *server, int port, int timeout_ms) { int ret; if (!lrm_state->conn) { lrm_state->conn = lrmd_remote_api_new(lrm_state->node_name, server, port); if (!lrm_state->conn) { return -1; } ((lrmd_t *) lrm_state->conn)->cmds->set_callback(lrm_state->conn, remote_lrm_op_callback); lrmd_internal_set_proxy_callback(lrm_state->conn, lrm_state, remote_proxy_cb); } crm_trace("initiating remote connection to %s at %d with timeout %d", server, port, timeout_ms); ret = ((lrmd_t *) lrm_state->conn)->cmds->connect_async(lrm_state->conn, lrm_state->node_name, timeout_ms); if (ret != pcmk_ok) { lrm_state->num_lrm_register_fails++; } else { lrm_state->num_lrm_register_fails = 0; } return ret; } int lrm_state_get_metadata(lrm_state_t * lrm_state, const char *class, const char *provider, const char *agent, char **output, enum lrmd_call_options options) { if (!lrm_state->conn) { return -ENOTCONN; } /* Optimize this... only retrieve metadata from local lrmd connection. Perhaps consider * caching result. */ return ((lrmd_t *) lrm_state->conn)->cmds->get_metadata(lrm_state->conn, class, provider, agent, output, options); } int lrm_state_cancel(lrm_state_t * lrm_state, const char *rsc_id, const char *action, int interval) { if (!lrm_state->conn) { return -ENOTCONN; } /* Optimize this, cancel requires a synced request/response to the server. * Figure out a way to make this async. */ if (is_remote_lrmd_ra(NULL, NULL, rsc_id)) { return remote_ra_cancel(lrm_state, rsc_id, action, interval); } return ((lrmd_t *) lrm_state->conn)->cmds->cancel(lrm_state->conn, rsc_id, action, interval); } lrmd_rsc_info_t * lrm_state_get_rsc_info(lrm_state_t * lrm_state, const char *rsc_id, enum lrmd_call_options options) { if (!lrm_state->conn) { return NULL; } /* optimize this... this function is a synced round trip from client to daemon. * It should be possible to cache the resource info in the lrmd client to prevent this. */ if (is_remote_lrmd_ra(NULL, NULL, rsc_id)) { return remote_ra_get_rsc_info(lrm_state, rsc_id); } return ((lrmd_t *) lrm_state->conn)->cmds->get_rsc_info(lrm_state->conn, rsc_id, options); } int lrm_state_exec(lrm_state_t * lrm_state, const char *rsc_id, const char *action, const char *userdata, int interval, /* ms */ int timeout, /* ms */ int start_delay, /* ms */ lrmd_key_value_t * params) { if (!lrm_state->conn) { lrmd_key_value_freeall(params); return -ENOTCONN; } if (is_remote_lrmd_ra(NULL, NULL, rsc_id)) { return remote_ra_exec(lrm_state, rsc_id, action, userdata, interval, timeout, start_delay, params); } return ((lrmd_t *) lrm_state->conn)->cmds->exec(lrm_state->conn, rsc_id, action, userdata, interval, timeout, start_delay, lrmd_opt_notify_changes_only, params); } int lrm_state_register_rsc(lrm_state_t * lrm_state, const char *rsc_id, const char *class, const char *provider, const char *agent, enum lrmd_call_options options) { if (!lrm_state->conn) { return -ENOTCONN; } /* optimize this... this function is a synced round trip from client to daemon. * The crmd/lrm.c code path should be re-factored to allow the register of resources * to be performed async. The lrmd client api needs to make an async version * of register available. */ if (is_remote_lrmd_ra(agent, provider, NULL)) { return lrm_state_find_or_create(rsc_id) ? pcmk_ok : -1; } return ((lrmd_t *) lrm_state->conn)->cmds->register_rsc(lrm_state->conn, rsc_id, class, provider, agent, options); } int lrm_state_unregister_rsc(lrm_state_t * lrm_state, const char *rsc_id, enum lrmd_call_options options) { if (!lrm_state->conn) { return -ENOTCONN; } /* optimize this... this function is a synced round trip from client to daemon. * The crmd/lrm.c code path that uses this function should always treat it as an * async operation. The lrmd client api needs to make an async version unreg available. */ if (is_remote_lrmd_ra(NULL, NULL, rsc_id)) { lrm_state_destroy(rsc_id); return pcmk_ok; } return ((lrmd_t *) lrm_state->conn)->cmds->unregister_rsc(lrm_state->conn, rsc_id, options); } pacemaker-master/crmd/main.c000066400000000000000000000112541217637305600163310ustar00rootroot00000000000000/* * Copyright (C) 2004 Andrew Beekhof * * 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 2 of the License, or (at your option) any later version. * * This software 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 library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define OPTARGS "hV" void usage(const char *cmd, int exit_status); int crmd_init(void); void crmd_hamsg_callback(const xmlNode * msg, void *private_data); extern void init_dotfile(void); GMainLoop *crmd_mainloop = NULL; /* *INDENT-OFF* */ static struct crm_option long_options[] = { /* Top-level Options */ {"help", 0, 0, '?', "\tThis text"}, {"verbose", 0, 0, 'V', "\tIncrease debug output"}, {0, 0, 0, 0} }; /* *INDENT-ON* */ int main(int argc, char **argv) { int flag; int index = 0; int argerr = 0; crmd_mainloop = g_main_new(FALSE); crm_log_init(NULL, LOG_INFO, TRUE, FALSE, argc, argv, FALSE); crm_set_options(NULL, "[options]", long_options, "Daemon for aggregating resource and node failures as well as co-ordinating the cluster's response"); while (1) { flag = crm_get_option(argc, argv, &index); if (flag == -1) break; switch (flag) { case 'V': crm_bump_log_level(argc, argv); break; case 'h': /* Help message */ crm_help(flag, EX_OK); break; default: ++argerr; break; } } if (argc - optind == 1 && safe_str_eq("metadata", argv[optind])) { crmd_metadata(); return 0; } else if (argc - optind == 1 && safe_str_eq("version", argv[optind])) { fprintf(stdout, "CRM Version: "); fprintf(stdout, "%s (%s)\n", VERSION, BUILD_VERSION); return 0; } crm_notice("CRM Git Version: %s\n", BUILD_VERSION); if (optind > argc) { ++argerr; } if (argerr) { crm_help('?', EX_USAGE); } if (crm_is_writable(PE_STATE_DIR, NULL, CRM_DAEMON_USER, CRM_DAEMON_GROUP, FALSE) == FALSE) { crm_err("Bad permissions on " PE_STATE_DIR ". Terminating"); fprintf(stderr, "ERROR: Bad permissions on " PE_STATE_DIR ". See logs for details\n"); fflush(stderr); return 100; } else if (crm_is_writable(CRM_CONFIG_DIR, NULL, CRM_DAEMON_USER, CRM_DAEMON_GROUP, FALSE) == FALSE) { crm_err("Bad permissions on " CRM_CONFIG_DIR ". Terminating"); fprintf(stderr, "ERROR: Bad permissions on " CRM_CONFIG_DIR ". See logs for details\n"); fflush(stderr); return 100; } return crmd_init(); } int crmd_init(void) { int exit_code = 0; enum crmd_fsa_state state; fsa_state = S_STARTING; fsa_input_register = 0; /* zero out the regester */ init_dotfile(); crm_debug("Starting %s", crm_system_name); register_fsa_input(C_STARTUP, I_STARTUP, NULL); crm_peer_init(); state = s_crmd_fsa(C_STARTUP); if (state == S_PENDING || state == S_STARTING) { /* Create the mainloop and run it... */ crm_trace("Starting %s's mainloop", crm_system_name); #ifdef REALTIME_SUPPORT static int crm_realtime = 1; if (crm_realtime == 1) { cl_enable_realtime(); } else if (crm_realtime == 0) { cl_disable_realtime(); } cl_make_realtime(SCHED_RR, 5, 64, 64); #endif g_main_run(crmd_mainloop); if (is_set(fsa_input_register, R_STAYDOWN)) { crm_info("Inhibiting automated respawn"); exit_code = 100; } } else { crm_err("Startup of %s failed. Current state: %s", crm_system_name, fsa_state2string(state)); exit_code = 1; } crm_info("%u stopped: %s (%d)", getpid(), pcmk_strerror(exit_code), exit_code); return crmd_fast_exit(exit_code); } pacemaker-master/crmd/make_dot.pl000066400000000000000000000265501217637305600173660ustar00rootroot00000000000000#!/bin/perl # Copyright (C) 2004 Andrew Beekhof # # 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 2 of the License, or (at your option) any later version. # # This software 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 library; if not, write to the Free Software # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA # # generates a transition graph based on the crmd_fsa_state array in # fsa_matrix.h and an actions graph of sorts based on the crmd_fsa_actions # array also in fsa_matrix.h. $do_links2self=1; $input_file = $ARGV[0]; $output_dir = $ARGV[1]; make_inputs_dot($input_file, $output_dir."/fsa_inputs.dot", "const enum crmd_fsa_state crmd_fsa_state", "const long long crmd_fsa_actions"); make_actions_dot($input_file, $output_dir."/fsa_actions_by_state.dot", $output_dir."/fsa_inputs_by_action.dot", "const long long crmd_fsa_actions", "ELSEIF_INVOKE_FSA_ACTION"); sub make_inputs_dot { my ($input, $output, $start, $stop) = @_; my $duplicate_edges; my $self_links; my $illegal_links; my $nothing_links; my $warn_links; my $filename=$input; my $filedesc=INPUT_FD; unless (open($filedesc, $filename)) { print STDERR "Can't open $filename: $!\n"; } my $seen_start = 0; my $input = ""; my @lines = ; my %HoH = {}; my $intro = 'digraph "g" { size = "30,30" graph [ fontsize = "12" fontcolor = "black" bb = "0,0,398.922306,478.927856" color = "black" ] node [ fontsize = "12" fontcolor = "black" shape = "ellipse" color = "black" ] edge [ fontsize = "12" fontcolor = "black" color = "black" ] // special nodes "Any State" [ fontcolor="white" fillcolor="black" style="filled" ] "S_PENDING" [ color = "blue" fontcolor = "blue" ] "S_TERMINATE" [ color = "red" fillcolor = "red" style="filled" ] "S_STOPPING" [ color = "red" fillcolor = "red" style="filled" ] "S_RECOVERY" [ color = "orange" fillcolor = "orange" style="filled" ] "S_HALT" [ color = "#eeee55" fillcolor = "#eeee55" style="filled" ] "S_ELECTION" [ color = "purple" fillcolor = "purple" style="filled" ] "S_RELEASE_DC" [ color = "grey" fillcolor = "grey" style="filled" ] // DC only nodes "S_INTEGRATION" [ fillcolor = "#33dd33" style="filled" ] "S_FINALIZE_JOIN" [ fillcolor = "#33dd33" style="filled" ] "S_POLICY_ENGINE" [ color = "royalblue" fillcolor = "royalblue" style="filled" ] "S_TRANSITION_ENGINE" [ fillcolor = "#33dd33" style="filled" ] "S_IDLE" [ fillcolor = "#33dd33" style="filled" ] '; $outro = '} '; $filename=$output; $filedesc=DOT_FD; unless (open($filedesc, '>',$filename)) { print STDERR "Can't open $filename: $!\n"; } print DOT_FD $intro; foreach $line (@lines) { $seen_start=1 if($line =~ /$start/); $seen_start=0 if($line =~ /$stop/); if($seen_start == 1) { my $is_input = 0; my $is_transition = 0; $is_input = 1 if($line =~ / Got an I_/); $is_transition = 1 if($line =~ /==\>/); if($is_input == 1) { $input = $line; $input =~ s/.*Got an //; $input =~ s/\ \*\///; chop($input); } if($is_transition == 1) { @bits = split(/\s/, $line); $state1 = @bits[3]; $state2 = @bits[7]; if("$state2" eq "") { # for some reason it ends up in @bits[6] sometimes $state2 = @bits[6]; } chop($state2); if($do_links2self && $state1 eq $state2) { $self_links = $self_links+1; } else { if( $state1 eq $state2 ) { $self_links = $self_links+1; } if( $input eq "I_TERMINATE" ) { } elsif( $input eq "I_STOP" ) { } elsif( $input eq "I_RELEASE_FAIL" ) { } elsif( exists($HoH{$state1}) ) { $rec = $HoH{$state1}; if( $HoH{$state1}{$state2} ne "" ) { $oldval = $HoH{$state1}{$state2}; $rec->{$state2} = $oldval.",\\n".$input; $duplicate_edges = $duplicate_edges + 1; } else { $rec->{$state2} = $input; } } else { $rec = {}; $HoH{$state1} = $rec; $rec->{$state2} = $input; } } } } } # print the whole thing somewhat sorted foreach $state_from ( sort keys %HoH ) { # print "$state_from: { "; for $state_to ( sort keys %{ $HoH{$state_from} } ) { $color="black"; $color="red" if $state_to =~ /STOPPING/; $color="red" if $state_to =~ /TERMINATE/; $color="orange" if $state_to =~ /RECOVERY/; $color="#eeee55" if $state_to =~ /HALT/; $color="blue" if $state_to =~ /PENDING/; $color="purple" if $state_to =~ /ELECTION/; $color="royalblue" if $state_to =~ /POLICY/; $color="gray" if $state_to =~ /RELEASE/; print DOT_FD "\"".$state_from."\" -> \"".$state_to."\" [ color=\"$color\" fontcolor=\"$color\" label = \"$HoH{$state_from}{$state_to}\" ]\n"; # print DOT_FD "\"".$state_from."\" -> \"".$state_to."\" [ label = \"$HoH{$state_from}{$state_to}\" ]\n"; # print "$state_to=$HoH{$state_from}{$state_to} "; } # print "}\n"; } $color="red"; print DOT_FD "\"Any State\" -> \"S_STOPPING\" [ color=\"$color\" fontcolor=\"$color\" label = \"I_STOP\" ]\n"; print DOT_FD "\"Any State\" -> \"S_STOPPING\" [ color=\"$color\" fontcolor=\"$color\" label = \"I_RELEASE_FAIL\" ]\n"; print DOT_FD "\"Any State\" -> \"S_TERMINATE\" [ color=\"$color\" fontcolor=\"$color\" label = \"I_TERMINATE\" ]\n"; print DOT_FD $outro; close(DOT_FD); close(INPUT_FD); print "\n$output Done...\n"; print "Saved $duplicate_edges duplicate edges\n"; print "Saved $self_links links to self\n"; } sub make_actions_dot { my ($input, $output1, $output2, $start, $stop) = @_; my $duplicate_edges; my $self_links; my $illegal_links; my $nothing_links; my $warn_links; my $filename=$input; my $filedesc=INPUT_FD; unless (open($filedesc, $filename)) { print STDERR "Can't open $filename: $!\n"; } my $seen_start = 0; my $input = ""; my @lines = ; my %HoH = {}; my %HoH2 = {}; my $intro = 'digraph "g" { rankdir = LR // size = "30,30" graph [ fontsize = "12" fontname = "Times-Roman" fontcolor = "black" bb = "0,0,398.922306,478.927856" color = "black" ] node [ fontsize = "12" fontname = "Times-Roman" fontcolor = "black" shape = "ellipse" color = "black" ] edge [ fontsize = "12" fontname = "Times-Roman" fontcolor = "black" color = "black" ] '; $outro = '} '; foreach $line (@lines) { $seen_start=1 if($line =~ /$start/); $seen_start=0 if($line =~ /$stop/); if($seen_start == 1) { my $is_input = 0; my $is_transition = 0; $is_input = 1 if($line =~ / Got an I_/); $is_transition = 1 if($line =~ /==\>/); if($is_input == 1) { $input = $line; $input =~ s/.*Got an //; $input =~ s/\ \*\///; chop($input); } if($is_transition == 1) { @bits = split(/\s/, $line); $state1 = @bits[3]; $state2 = @bits[7]; if("$state2" eq "") { # for some reason it ends up in @bits[6] sometimes $state2 = @bits[6]; } chop($state2); @actions = split(/\|/, $state2); foreach $action ( sort @actions ) { $key1 = $state1; $key2 = $input." {".$state1."}"; $value = $action; if( exists($HoH{$key1}) ) { $rec = $HoH{$key1}; } else { $rec = {}; $HoH{$key1} = $rec; } if($action =~ /A_NOTHING/) { $nothing_links = $nothing_links + 1; } elsif($action =~ /A_WARN/) { $warn_links = $warn_links + 1; } elsif($action =~ /A_LOG/) { $log_links = $log_links + 1; } elsif( $HoH{$key1}{$key2} ne "" ) { $oldval = $HoH{$key1}{$key2}; $rec->{$key2} = $oldval.",\\n".$value; $duplicate_edges = $duplicate_edges + 1; } else { $rec->{$key2} = $value; } $key1 = $action; $key2 = $state1." {".$action."}"; $value = $input; if( exists($HoH2{$key1}) ) { $rec = $HoH2{$key1}; } else { $rec = {}; $HoH2{$key1} = $rec; } if($action =~ /A_NOTHING/) { $nothing_links = $nothing_links + 1; } elsif($action =~ /A_WARN/) { $warn_links = $warn_links + 1; } elsif($action =~ /A_LOG/) { $log_links = $log_links + 1; } elsif( $HoH2{$key1}{$key2} ne "" ) { $oldval = $HoH2{$key1}{$key2}; $rec->{$key2} = $oldval.",\\n".$value; $duplicate_edges = $duplicate_edges + 1; } else { $rec->{$key2} = $value; } } } } } $filename=$output1; $filedesc=DOT_FD; unless (open($filedesc, '>',$filename)) { print STDERR "Can't open $filename: $!\n"; } print DOT_FD $intro; # print the whole thing somewhat sorted foreach $family ( sort keys %HoH ) { # print "$family: { "; for $role ( sort keys %{ $HoH{$family} } ) { # aid readability $color="black"; $color="red" if $role =~ /TERMINATE/; $color="red" if $role =~ /STOP/; $color="orange" if $role =~ /ERROR/; $color="orange" if $role =~ /FAIL/; $color="#33dd33" if $role =~ /ELECTION/; $color="blue" if $role =~ /RESTART/; $color="cyan" if $role =~ /TIMEOUT/; $color="gray" if $role =~ /UPDATE/; print DOT_FD "\"".$family."\" -> \"".$role."\" [ color=\"$color\" fontcolor=\"$color\" label = \"$HoH{$family}{$role}\" ]\n"; # print "$role=$HoH{$family}{$role} "; } # print "}\n"; } print DOT_FD $outro; close(DOT_FD); $filename=$output2; $filedesc=DOT_FD; unless (open($filedesc, '>',$filename)) { print STDERR "Can't open $filename: $!\n"; } print DOT_FD $intro; # print the whole thing somewhat sorted foreach $family ( sort keys %HoH2 ) { # print "$family: { "; for $role ( sort keys %{ $HoH2{$family} } ) { # aid readability $color="black"; $color="red" if $role =~ /TERMINATE/; $color="red" if $role =~ /STOP/; $color="orange" if $role =~ /ERROR/; $color="orange" if $role =~ /FAIL/; $color="#33dd33" if $role =~ /ELECTION/; $color="blue" if $role =~ /RESTART/; $color="cyan" if $role =~ /TIMEOUT/; $color="gray" if $role =~ /UPDATE/; print DOT_FD "\"".$family."\" -> \"".$role."\" [ color=\"$color\" fontcolor=\"$color\" label = \"$HoH2{$family}{$role}\" ]\n"; # print "$role=$HoH{$family}{$role} "; } # print "}\n"; } print DOT_FD $outro; close(DOT_FD); close(INPUT_FD); print "\n$output Done...\n"; print "Saved $duplicate_edges duplicate edges\n"; print "Saved $self_links links to self\n"; print "Saved $nothing_links links to the A_NOTHING action\n"; print "Saved $warn_links links to the A_WARN action\n"; print "Saved $log_links links to the A_LOG action\n"; } pacemaker-master/crmd/membership.c000066400000000000000000000230741217637305600175430ustar00rootroot00000000000000/* * Copyright (C) 2004 Andrew Beekhof * * 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 2 of the License, or (at your option) any later version. * * This software 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 library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ /* put these first so that uuid_t is defined without conflicts */ #include #include #include #include #include #include #include #include #include #include #include #include gboolean membership_flux_hack = FALSE; void post_cache_update(int instance); int last_peer_update = 0; extern GHashTable *voted; extern gboolean check_join_state(enum crmd_fsa_state cur_state, const char *source); static void reap_dead_nodes(gpointer key, gpointer value, gpointer user_data) { crm_node_t *node = value; if (crm_is_peer_active(node) == FALSE) { crm_update_peer_join(__FUNCTION__, node, crm_join_none); if(node->uname) { if (voted != NULL) { g_hash_table_remove(voted, node->uname); } if (safe_str_eq(fsa_our_uname, node->uname)) { crm_err("We're not part of the cluster anymore"); register_fsa_input(C_FSA_INTERNAL, I_ERROR, NULL); } else if (AM_I_DC == FALSE && safe_str_eq(node->uname, fsa_our_dc)) { crm_warn("Our DC node (%s) left the cluster", node->uname); register_fsa_input(C_FSA_INTERNAL, I_ELECTION, NULL); } } if (fsa_state == S_INTEGRATION || fsa_state == S_FINALIZE_JOIN) { check_join_state(fsa_state, __FUNCTION__); } fail_incompletable_actions(transition_graph, node->uuid); } } gboolean ever_had_quorum = FALSE; void post_cache_update(int instance) { xmlNode *no_op = NULL; crm_peer_seq = instance; crm_debug("Updated cache after membership event %d.", instance); g_hash_table_foreach(crm_peer_cache, reap_dead_nodes, NULL); set_bit(fsa_input_register, R_MEMBERSHIP); if (AM_I_DC) { populate_cib_nodes(node_update_quick | node_update_cluster | node_update_peer | node_update_expected, __FUNCTION__); } /* * If we lost nodes, we should re-check the election status * Safe to call outside of an election */ register_fsa_action(A_ELECTION_CHECK); /* Membership changed, remind everyone we're here. * This will aid detection of duplicate DCs */ no_op = create_request(CRM_OP_NOOP, NULL, NULL, CRM_SYSTEM_CRMD, AM_I_DC ? CRM_SYSTEM_DC : CRM_SYSTEM_CRMD, NULL); send_cluster_message(NULL, crm_msg_crmd, no_op, FALSE); free_xml(no_op); } static void crmd_node_update_complete(xmlNode * msg, int call_id, int rc, xmlNode * output, void *user_data) { fsa_data_t *msg_data = NULL; last_peer_update = 0; if (rc == pcmk_ok) { crm_trace("Node update %d complete", call_id); } else if(call_id < pcmk_ok) { crm_err("Node update failed: %s (%d)", pcmk_strerror(call_id), call_id); crm_log_xml_debug(msg, "failed"); register_fsa_error(C_FSA_INTERNAL, I_ERROR, NULL); } else { crm_err("Node update %d failed: %s (%d)", call_id, pcmk_strerror(rc), rc); crm_log_xml_debug(msg, "failed"); register_fsa_error(C_FSA_INTERNAL, I_ERROR, NULL); } } xmlNode * do_update_node_cib(crm_node_t * node, int flags, xmlNode * parent, const char *source) { const char *value = NULL; xmlNode *node_state = create_xml_node(parent, XML_CIB_TAG_STATE); set_uuid(node_state, XML_ATTR_UUID, node); if (crm_element_value(node_state, XML_ATTR_UUID) == NULL) { crm_info("Node update for %s cancelled: no id", node->uname); free_xml(node_state); return NULL; } crm_xml_add(node_state, XML_ATTR_UNAME, node->uname); if (flags & node_update_cluster) { if (safe_str_eq(node->state, CRM_NODE_ACTIVE)) { value = XML_BOOLEAN_YES; } else if (node->state) { value = XML_BOOLEAN_NO; } else { value = NULL; } crm_xml_add(node_state, XML_NODE_IN_CLUSTER, value); } if (flags & node_update_peer) { value = OFFLINESTATUS; if (node->processes & proc_flags) { value = ONLINESTATUS; } crm_xml_add(node_state, XML_NODE_IS_PEER, value); } if (flags & node_update_join) { if(node->join <= crm_join_none) { value = CRMD_JOINSTATE_DOWN; } else { value = CRMD_JOINSTATE_MEMBER; } crm_xml_add(node_state, XML_NODE_JOIN_STATE, value); } if (flags & node_update_expected) { crm_xml_add(node_state, XML_NODE_EXPECTED, node->expected); } crm_xml_add(node_state, XML_ATTR_ORIGIN, source); return node_state; } static void node_list_update_callback(xmlNode * msg, int call_id, int rc, xmlNode * output, void *user_data) { fsa_data_t *msg_data = NULL; if(call_id < pcmk_ok) { crm_err("Node list update failed: %s (%d)", pcmk_strerror(call_id), call_id); crm_log_xml_debug(msg, "update:failed"); register_fsa_error(C_FSA_INTERNAL, I_ERROR, NULL); } else if(rc < pcmk_ok) { crm_err("Node update %d failed: %s (%d)", call_id, pcmk_strerror(rc), rc); crm_log_xml_debug(msg, "update:failed"); register_fsa_error(C_FSA_INTERNAL, I_ERROR, NULL); } } void populate_cib_nodes(enum node_update_flags flags, const char *source) { int call_id = 0; gboolean from_hashtable = TRUE; int call_options = cib_scope_local | cib_quorum_override; xmlNode *node_list = create_xml_node(NULL, XML_CIB_TAG_NODES); #if SUPPORT_HEARTBEAT if (is_not_set(flags, node_update_quick) && is_heartbeat_cluster()) { from_hashtable = heartbeat_initialize_nodelist(fsa_cluster_conn, FALSE, node_list); } #endif #if SUPPORT_COROSYNC # if !SUPPORT_PLUGIN if (is_not_set(flags, node_update_quick) && is_corosync_cluster()) { from_hashtable = corosync_initialize_nodelist(NULL, FALSE, node_list); } # endif #endif if (from_hashtable) { GHashTableIter iter; crm_node_t *node = NULL; g_hash_table_iter_init(&iter, crm_peer_cache); while (g_hash_table_iter_next(&iter, NULL, (gpointer *) &node)) { xmlNode *new_node = NULL; crm_trace("Creating node entry for %s/%s", node->uname, node->uuid); if(node->uuid && node->uname) { /* We need both to be valid */ new_node = create_xml_node(node_list, XML_CIB_TAG_NODE); crm_xml_add(new_node, XML_ATTR_ID, node->uuid); crm_xml_add(new_node, XML_ATTR_UNAME, node->uname); } } } crm_trace("Populating section from %s", from_hashtable ? "hashtable" : "cluster"); fsa_cib_update(XML_CIB_TAG_NODES, node_list, call_options, call_id, NULL); fsa_register_cib_callback(call_id, FALSE, NULL, node_list_update_callback); free_xml(node_list); if (call_id >= pcmk_ok && crm_peer_cache != NULL && AM_I_DC) { /* * There is no need to update the local CIB with our values if * we've not seen valid membership data */ GHashTableIter iter; crm_node_t *node = NULL; node_list = create_xml_node(NULL, XML_CIB_TAG_STATUS); g_hash_table_iter_init(&iter, crm_peer_cache); while (g_hash_table_iter_next(&iter, NULL, (gpointer *) &node)) { do_update_node_cib(node, flags, node_list, source); } fsa_cib_update(XML_CIB_TAG_STATUS, node_list, call_options, call_id, NULL); fsa_register_cib_callback(call_id, FALSE, NULL, crmd_node_update_complete); last_peer_update = call_id; free_xml(node_list); } } static void cib_quorum_update_complete(xmlNode * msg, int call_id, int rc, xmlNode * output, void *user_data) { fsa_data_t *msg_data = NULL; if (rc == pcmk_ok) { crm_trace("Quorum update %d complete", call_id); } else { crm_err("Quorum update %d failed: %s (%d)", call_id, pcmk_strerror(rc), rc); crm_log_xml_debug(msg, "failed"); register_fsa_error(C_FSA_INTERNAL, I_ERROR, NULL); } } void crm_update_quorum(gboolean quorum, gboolean force_update) { ever_had_quorum |= quorum; if (AM_I_DC && (force_update || fsa_has_quorum != quorum)) { int call_id = 0; xmlNode *update = NULL; int call_options = cib_scope_local | cib_quorum_override; update = create_xml_node(NULL, XML_TAG_CIB); crm_xml_add_int(update, XML_ATTR_HAVE_QUORUM, quorum); crm_xml_add(update, XML_ATTR_DC_UUID, fsa_our_uuid); fsa_cib_update(XML_TAG_CIB, update, call_options, call_id, NULL); crm_debug("Updating quorum status to %s (call=%d)", quorum ? "true" : "false", call_id); fsa_register_cib_callback(call_id, FALSE, NULL, cib_quorum_update_complete); free_xml(update); } fsa_has_quorum = quorum; } pacemaker-master/crmd/membership.h000066400000000000000000000003741217637305600175460ustar00rootroot00000000000000 void reap_dead_ccm_nodes(gpointer key, gpointer value, gpointer user_data); void post_cache_update(int instance); extern gboolean check_join_state(enum crmd_fsa_state cur_state, const char *source); #define proc_flags (crm_proc_crmd | crm_proc_cpg) pacemaker-master/crmd/messages.c000066400000000000000000000722441217637305600172220ustar00rootroot00000000000000/* * Copyright (C) 2004 Andrew Beekhof * * 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 2 of the License, or (at your option) any later version. * * This software 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 library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include GListPtr fsa_message_queue = NULL; extern void crm_shutdown(int nsig); void handle_response(xmlNode * stored_msg); enum crmd_fsa_input handle_request(xmlNode * stored_msg, enum crmd_fsa_cause cause); enum crmd_fsa_input handle_shutdown_request(xmlNode * stored_msg); #ifdef MSG_LOG # define ROUTER_RESULT(x) crm_trace("Router result: %s", x); \ crm_log_xml_trace(msg, "router.log"); #else # define ROUTER_RESULT(x) crm_trace("Router result: %s", x) #endif /* debug only, can wrap all it likes */ int last_data_id = 0; void register_fsa_error_adv(enum crmd_fsa_cause cause, enum crmd_fsa_input input, fsa_data_t * cur_data, void *new_data, const char *raised_from) { /* save the current actions if any */ if (fsa_actions != A_NOTHING) { register_fsa_input_adv(cur_data ? cur_data->fsa_cause : C_FSA_INTERNAL, I_NULL, cur_data ? cur_data->data : NULL, fsa_actions, TRUE, __FUNCTION__); } /* reset the action list */ crm_info("Resetting the current action list"); fsa_dump_actions(fsa_actions, "Drop"); fsa_actions = A_NOTHING; /* register the error */ register_fsa_input_adv(cause, input, new_data, A_NOTHING, TRUE, raised_from); } int register_fsa_input_adv(enum crmd_fsa_cause cause, enum crmd_fsa_input input, void *data, long long with_actions, gboolean prepend, const char *raised_from) { unsigned old_len = g_list_length(fsa_message_queue); fsa_data_t *fsa_data = NULL; CRM_CHECK(raised_from != NULL, raised_from = ""); if (input == I_NULL && with_actions == A_NOTHING /* && data == NULL */ ) { /* no point doing anything */ crm_err("Cannot add entry to queue: no input and no action"); return 0; } if (input == I_WAIT_FOR_EVENT) { do_fsa_stall = TRUE; crm_debug("Stalling the FSA pending further input: source=%s cause=%s data=%p queue=%d", raised_from, fsa_cause2string(cause), data, old_len); if (old_len > 0) { fsa_dump_queue(LOG_TRACE); prepend = FALSE; } if (data == NULL) { fsa_actions |= with_actions; fsa_dump_actions(with_actions, "Restored"); return 0; } /* Store everything in the new event and reset fsa_actions */ with_actions |= fsa_actions; fsa_actions = A_NOTHING; } last_data_id++; crm_trace("%s %s FSA input %d (%s) (cause=%s) %s data", raised_from, prepend ? "prepended" : "appended", last_data_id, fsa_input2string(input), fsa_cause2string(cause), data ? "with" : "without"); fsa_data = calloc(1, sizeof(fsa_data_t)); fsa_data->id = last_data_id; fsa_data->fsa_input = input; fsa_data->fsa_cause = cause; fsa_data->origin = raised_from; fsa_data->data = NULL; fsa_data->data_type = fsa_dt_none; fsa_data->actions = with_actions; if (with_actions != A_NOTHING) { crm_trace("Adding actions %.16llx to input", with_actions); } if (data != NULL) { switch (cause) { case C_FSA_INTERNAL: case C_CRMD_STATUS_CALLBACK: case C_IPC_MESSAGE: case C_HA_MESSAGE: crm_trace("Copying %s data from %s as a HA msg", fsa_cause2string(cause), raised_from); CRM_CHECK(((ha_msg_input_t *) data)->msg != NULL, crm_err("Bogus data from %s", raised_from)); fsa_data->data = copy_ha_msg_input(data); fsa_data->data_type = fsa_dt_ha_msg; break; case C_LRM_OP_CALLBACK: crm_trace("Copying %s data from %s as lrmd_event_data_t", fsa_cause2string(cause), raised_from); fsa_data->data = lrmd_copy_event((lrmd_event_data_t *) data); fsa_data->data_type = fsa_dt_lrm; break; case C_CCM_CALLBACK: case C_SUBSYSTEM_CONNECT: case C_LRM_MONITOR_CALLBACK: case C_TIMER_POPPED: case C_SHUTDOWN: case C_HEARTBEAT_FAILED: case C_HA_DISCONNECT: case C_ILLEGAL: case C_UNKNOWN: case C_STARTUP: crm_err("Copying %s data (from %s)" " not yet implemented", fsa_cause2string(cause), raised_from); crmd_exit(pcmk_err_generic); break; } crm_trace("%s data copied", fsa_cause2string(fsa_data->fsa_cause)); } /* make sure to free it properly later */ if (prepend) { crm_trace("Prepending input"); fsa_message_queue = g_list_prepend(fsa_message_queue, fsa_data); } else { fsa_message_queue = g_list_append(fsa_message_queue, fsa_data); } crm_trace("Queue len: %d", g_list_length(fsa_message_queue)); /* fsa_dump_queue(LOG_DEBUG_2); */ if (old_len == g_list_length(fsa_message_queue)) { crm_err("Couldnt add message to the queue"); } if (fsa_source && input != I_WAIT_FOR_EVENT) { crm_trace("Triggering FSA: %s", __FUNCTION__); mainloop_set_trigger(fsa_source); } return last_data_id; } void fsa_dump_queue(int log_level) { int offset = 0; GListPtr lpc = NULL; for (lpc = fsa_message_queue; lpc != NULL; lpc = lpc->next) { fsa_data_t *data = (fsa_data_t *) lpc->data; do_crm_log_unlikely(log_level, "queue[%d.%d]: input %s raised by %s(%p.%d)\t(cause=%s)", offset++, data->id, fsa_input2string(data->fsa_input), data->origin, data->data, data->data_type, fsa_cause2string(data->fsa_cause)); } } ha_msg_input_t * copy_ha_msg_input(ha_msg_input_t * orig) { ha_msg_input_t *copy = NULL; xmlNodePtr data = NULL; if (orig != NULL) { crm_trace("Copy msg"); data = copy_xml(orig->msg); } else { crm_trace("No message to copy"); } copy = new_ha_msg_input(data); if (orig && orig->msg != NULL) { CRM_CHECK(copy->msg != NULL, crm_err("copy failed")); } return copy; } void delete_fsa_input(fsa_data_t * fsa_data) { lrmd_event_data_t *op = NULL; xmlNode *foo = NULL; if (fsa_data == NULL) { return; } crm_trace("About to free %s data", fsa_cause2string(fsa_data->fsa_cause)); if (fsa_data->data != NULL) { switch (fsa_data->data_type) { case fsa_dt_ha_msg: delete_ha_msg_input(fsa_data->data); break; case fsa_dt_xml: foo = fsa_data->data; free_xml(foo); break; case fsa_dt_lrm: op = (lrmd_event_data_t *) fsa_data->data; lrmd_free_event(op); break; case fsa_dt_none: if (fsa_data->data != NULL) { crm_err("Dont know how to free %s data from %s", fsa_cause2string(fsa_data->fsa_cause), fsa_data->origin); crmd_exit(pcmk_err_generic); } break; } crm_trace("%s data freed", fsa_cause2string(fsa_data->fsa_cause)); } free(fsa_data); } /* returns the next message */ fsa_data_t * get_message(void) { fsa_data_t *message = g_list_nth_data(fsa_message_queue, 0); fsa_message_queue = g_list_remove(fsa_message_queue, message); crm_trace("Processing input %d", message->id); return message; } /* returns the current head of the FIFO queue */ gboolean is_message(void) { return (g_list_length(fsa_message_queue) > 0); } void * fsa_typed_data_adv(fsa_data_t * fsa_data, enum fsa_data_type a_type, const char *caller) { void *ret_val = NULL; if (fsa_data == NULL) { crm_err("%s: No FSA data available", caller); } else if (fsa_data->data == NULL) { crm_err("%s: No message data available. Origin: %s", caller, fsa_data->origin); } else if (fsa_data->data_type != a_type) { crm_crit("%s: Message data was the wrong type! %d vs. requested=%d. Origin: %s", caller, fsa_data->data_type, a_type, fsa_data->origin); CRM_ASSERT(fsa_data->data_type == a_type); } else { ret_val = fsa_data->data; } return ret_val; } /* A_MSG_ROUTE */ void do_msg_route(long long action, enum crmd_fsa_cause cause, enum crmd_fsa_state cur_state, enum crmd_fsa_input current_input, fsa_data_t * msg_data) { ha_msg_input_t *input = fsa_typed_data(fsa_dt_ha_msg); route_message(msg_data->fsa_cause, input->msg); } void route_message(enum crmd_fsa_cause cause, xmlNode * input) { ha_msg_input_t fsa_input; enum crmd_fsa_input result = I_NULL; fsa_input.msg = input; CRM_CHECK(cause == C_IPC_MESSAGE || cause == C_HA_MESSAGE, return); /* try passing the buck first */ if (relay_message(input, cause == C_IPC_MESSAGE)) { return; } /* handle locally */ result = handle_message(input, cause); /* done or process later? */ switch (result) { case I_NULL: case I_CIB_OP: case I_ROUTER: case I_NODE_JOIN: case I_JOIN_REQUEST: case I_JOIN_RESULT: break; default: /* Defering local processing of message */ register_fsa_input_later(cause, result, &fsa_input); return; } if (result != I_NULL) { /* add to the front of the queue */ register_fsa_input(cause, result, &fsa_input); } } gboolean relay_message(xmlNode * msg, gboolean originated_locally) { int dest = 1; int is_for_dc = 0; int is_for_dcib = 0; int is_for_te = 0; int is_for_crm = 0; int is_for_cib = 0; int is_local = 0; gboolean processing_complete = FALSE; const char *host_to = crm_element_value(msg, F_CRM_HOST_TO); const char *sys_to = crm_element_value(msg, F_CRM_SYS_TO); const char *sys_from = crm_element_value(msg, F_CRM_SYS_FROM); const char *type = crm_element_value(msg, F_TYPE); const char *msg_error = NULL; crm_trace("Routing message %s", crm_element_value(msg, XML_ATTR_REFERENCE)); if (msg == NULL) { msg_error = "Cannot route empty message"; } else if (safe_str_eq(CRM_OP_HELLO, crm_element_value(msg, F_CRM_TASK))) { /* quietly ignore */ processing_complete = TRUE; } else if (safe_str_neq(type, T_CRM)) { msg_error = "Bad message type"; } else if (sys_to == NULL) { msg_error = "Bad message destination: no subsystem"; } if (msg_error != NULL) { processing_complete = TRUE; crm_err("%s", msg_error); crm_log_xml_warn(msg, "bad msg"); } if (processing_complete) { return TRUE; } processing_complete = TRUE; is_for_dc = (strcasecmp(CRM_SYSTEM_DC, sys_to) == 0); is_for_dcib = (strcasecmp(CRM_SYSTEM_DCIB, sys_to) == 0); is_for_te = (strcasecmp(CRM_SYSTEM_TENGINE, sys_to) == 0); is_for_cib = (strcasecmp(CRM_SYSTEM_CIB, sys_to) == 0); is_for_crm = (strcasecmp(CRM_SYSTEM_CRMD, sys_to) == 0); is_local = 0; if (host_to == NULL || strlen(host_to) == 0) { if (is_for_dc || is_for_te) { is_local = 0; } else if (is_for_crm && originated_locally) { is_local = 0; } else { is_local = 1; } } else if (safe_str_eq(fsa_our_uname, host_to)) { is_local = 1; } if (is_for_dc || is_for_dcib || is_for_te) { if (AM_I_DC && is_for_te) { ROUTER_RESULT("Message result: Local relay"); send_msg_via_ipc(msg, sys_to); } else if (AM_I_DC) { ROUTER_RESULT("Message result: DC/CRMd process"); processing_complete = FALSE; /* more to be done by caller */ } else if (originated_locally && safe_str_neq(sys_from, CRM_SYSTEM_PENGINE) && safe_str_neq(sys_from, CRM_SYSTEM_TENGINE)) { /* Neither the TE or PE should be sending messages * to DC's on other nodes * * By definition, if we are no longer the DC, then * the PE or TE's data should be discarded */ #if SUPPORT_COROSYNC if (is_openais_cluster()) { dest = text2msg_type(sys_to); } #endif ROUTER_RESULT("Message result: External relay to DC"); send_cluster_message(host_to ? crm_get_peer(0, host_to) : NULL, dest, msg, TRUE); } else { /* discard */ ROUTER_RESULT("Message result: Discard, not DC"); } } else if (is_local && (is_for_crm || is_for_cib)) { ROUTER_RESULT("Message result: CRMd process"); processing_complete = FALSE; /* more to be done by caller */ } else if (is_local) { ROUTER_RESULT("Message result: Local relay"); send_msg_via_ipc(msg, sys_to); } else { #if SUPPORT_COROSYNC if (is_openais_cluster()) { dest = text2msg_type(sys_to); if (dest == crm_msg_none || dest > crm_msg_stonith_ng) { dest = crm_msg_crmd; } } #endif ROUTER_RESULT("Message result: External relay"); send_cluster_message(host_to ? crm_get_peer(0, host_to) : NULL, dest, msg, TRUE); } return processing_complete; } static gboolean process_hello_message(xmlNode * hello, char **client_name, char **major_version, char **minor_version) { const char *local_client_name; const char *local_major_version; const char *local_minor_version; *client_name = NULL; *major_version = NULL; *minor_version = NULL; if (hello == NULL) { return FALSE; } local_client_name = crm_element_value(hello, "client_name"); local_major_version = crm_element_value(hello, "major_version"); local_minor_version = crm_element_value(hello, "minor_version"); if (local_client_name == NULL || strlen(local_client_name) == 0) { crm_err("Hello message was not valid (field %s not found)", "client name"); return FALSE; } else if (local_major_version == NULL || strlen(local_major_version) == 0) { crm_err("Hello message was not valid (field %s not found)", "major version"); return FALSE; } else if (local_minor_version == NULL || strlen(local_minor_version) == 0) { crm_err("Hello message was not valid (field %s not found)", "minor version"); return FALSE; } *client_name = strdup(local_client_name); *major_version = strdup(local_major_version); *minor_version = strdup(local_minor_version); crm_trace("Hello message ok"); return TRUE; } gboolean crmd_authorize_message(xmlNode * client_msg, crm_client_t * curr_client, const char *proxy_session) { char *client_name = NULL; char *major_version = NULL; char *minor_version = NULL; gboolean auth_result = FALSE; xmlNode *xml = NULL; const char *op = crm_element_value(client_msg, F_CRM_TASK); const char *uuid = curr_client ? curr_client->id : proxy_session; if (uuid == NULL) { crm_warn("Message [%s] not authorized", crm_element_value(client_msg, XML_ATTR_REFERENCE)); return FALSE; } else if (safe_str_neq(CRM_OP_HELLO, op)) { return TRUE; } xml = get_message_xml(client_msg, F_CRM_DATA); auth_result = process_hello_message(xml, &client_name, &major_version, &minor_version); if (auth_result == TRUE) { if (client_name == NULL) { crm_err("Bad client details (client_name=%s, uuid=%s)", crm_str(client_name), uuid); auth_result = FALSE; } } if (auth_result == TRUE) { /* check version */ int mav = atoi(major_version); int miv = atoi(minor_version); crm_trace("Checking client version number"); if (mav < 0 || miv < 0) { crm_err("Client version (%d:%d) is not acceptable", mav, miv); auth_result = FALSE; } } if (auth_result == TRUE) { crm_trace("Accepted client %s", client_name); if (curr_client) { curr_client->userdata = strdup(client_name); } crm_trace("Triggering FSA: %s", __FUNCTION__); mainloop_set_trigger(fsa_source); } else { crm_warn("Rejected client logon request"); if (curr_client) { qb_ipcs_disconnect(curr_client->ipcs); } } free(minor_version); free(major_version); free(client_name); /* hello messages should never be processed further */ return FALSE; } enum crmd_fsa_input handle_message(xmlNode * msg, enum crmd_fsa_cause cause) { const char *type = NULL; CRM_CHECK(msg != NULL, return I_NULL); type = crm_element_value(msg, F_CRM_MSG_TYPE); if (crm_str_eq(type, XML_ATTR_REQUEST, TRUE)) { return handle_request(msg, cause); } else if (crm_str_eq(type, XML_ATTR_RESPONSE, TRUE)) { handle_response(msg); return I_NULL; } crm_err("Unknown message type: %s", type); return I_NULL; } static enum crmd_fsa_input handle_failcount_op(xmlNode * stored_msg) { const char *rsc = NULL; const char *uname = NULL; gboolean is_remote_node = FALSE; xmlNode *xml_rsc = get_xpath_object("//" XML_CIB_TAG_RESOURCE, stored_msg, LOG_ERR); if (xml_rsc) { rsc = ID(xml_rsc); } uname = crm_element_value(stored_msg, XML_LRM_ATTR_TARGET); if (crm_element_value(stored_msg, XML_LRM_ATTR_ROUTER_NODE)) { is_remote_node = TRUE; } if (rsc) { char *attr = NULL; crm_info("Removing failcount for %s", rsc); attr = crm_concat("fail-count", rsc, '-'); update_attrd(uname, attr, NULL, NULL, is_remote_node); free(attr); attr = crm_concat("last-failure", rsc, '-'); update_attrd(uname, attr, NULL, NULL, is_remote_node); free(attr); lrm_clear_last_failure(rsc, uname); } else { crm_log_xml_warn(stored_msg, "invalid failcount op"); } return I_NULL; } enum crmd_fsa_input handle_request(xmlNode * stored_msg, enum crmd_fsa_cause cause) { xmlNode *msg = NULL; const char *op = crm_element_value(stored_msg, F_CRM_TASK); /* Optimize this for the DC - it has the most to do */ if (op == NULL) { crm_log_xml_err(stored_msg, "Bad message"); return I_NULL; } /*========== DC-Only Actions ==========*/ if (AM_I_DC) { if (strcmp(op, CRM_OP_JOIN_ANNOUNCE) == 0) { return I_NODE_JOIN; } else if (strcmp(op, CRM_OP_JOIN_REQUEST) == 0) { return I_JOIN_REQUEST; } else if (strcmp(op, CRM_OP_JOIN_CONFIRM) == 0) { return I_JOIN_RESULT; } else if (strcmp(op, CRM_OP_SHUTDOWN) == 0) { const char *host_from = crm_element_value(stored_msg, F_CRM_HOST_FROM); gboolean dc_match = safe_str_eq(host_from, fsa_our_dc); if (is_set(fsa_input_register, R_SHUTDOWN)) { crm_info("Shutting ourselves down (DC)"); return I_STOP; } else if (dc_match) { crm_err("We didnt ask to be shut down, yet our" " TE is telling us too." " Better get out now!"); return I_TERMINATE; } else if (fsa_state != S_STOPPING) { crm_err("Another node is asking us to shutdown" " but we think we're ok."); return I_ELECTION; } } else if (strcmp(op, CRM_OP_SHUTDOWN_REQ) == 0) { /* a slave wants to shut down */ /* create cib fragment and add to message */ return handle_shutdown_request(stored_msg); } } /*========== common actions ==========*/ if (strcmp(op, CRM_OP_NOVOTE) == 0) { ha_msg_input_t fsa_input; fsa_input.msg = stored_msg; register_fsa_input_adv(C_HA_MESSAGE, I_NULL, &fsa_input, A_ELECTION_COUNT | A_ELECTION_CHECK, FALSE, __FUNCTION__); } else if (strcmp(op, CRM_OP_CLEAR_FAILCOUNT) == 0) { return handle_failcount_op(stored_msg); } else if (strcmp(op, CRM_OP_VOTE) == 0) { /* count the vote and decide what to do after that */ ha_msg_input_t fsa_input; fsa_input.msg = stored_msg; register_fsa_input_adv(C_HA_MESSAGE, I_NULL, &fsa_input, A_ELECTION_COUNT | A_ELECTION_CHECK, FALSE, __FUNCTION__); /* Sometimes we _must_ go into S_ELECTION */ if (fsa_state == S_HALT) { crm_debug("Forcing an election from S_HALT"); return I_ELECTION; #if 0 } else if (AM_I_DC) { /* This is the old way of doing things but what is gained? */ return I_ELECTION; #endif } } else if (strcmp(op, CRM_OP_JOIN_OFFER) == 0) { crm_debug("Raising I_JOIN_OFFER: join-%s", crm_element_value(stored_msg, F_CRM_JOIN_ID)); return I_JOIN_OFFER; } else if (strcmp(op, CRM_OP_JOIN_ACKNAK) == 0) { crm_debug("Raising I_JOIN_RESULT: join-%s", crm_element_value(stored_msg, F_CRM_JOIN_ID)); return I_JOIN_RESULT; } else if (strcmp(op, CRM_OP_LRM_DELETE) == 0 || strcmp(op, CRM_OP_LRM_FAIL) == 0 || strcmp(op, CRM_OP_LRM_REFRESH) == 0 || strcmp(op, CRM_OP_REPROBE) == 0) { crm_xml_add(stored_msg, F_CRM_SYS_TO, CRM_SYSTEM_LRMD); return I_ROUTER; } else if (strcmp(op, CRM_OP_NOOP) == 0) { return I_NULL; } else if (strcmp(op, CRM_OP_LOCAL_SHUTDOWN) == 0) { crm_shutdown(SIGTERM); /*return I_SHUTDOWN; */ return I_NULL; /*========== (NOT_DC)-Only Actions ==========*/ } else if (AM_I_DC == FALSE && strcmp(op, CRM_OP_SHUTDOWN) == 0) { const char *host_from = crm_element_value(stored_msg, F_CRM_HOST_FROM); gboolean dc_match = safe_str_eq(host_from, fsa_our_dc); if (dc_match || fsa_our_dc == NULL) { if (is_set(fsa_input_register, R_SHUTDOWN) == FALSE) { crm_err("We didn't ask to be shut down, yet our" " DC is telling us too."); set_bit(fsa_input_register, R_STAYDOWN); return I_STOP; } crm_info("Shutting down"); return I_STOP; } else { crm_warn("Discarding %s op from %s", op, host_from); } } else if (strcmp(op, CRM_OP_PING) == 0) { /* eventually do some stuff to figure out * if we /are/ ok */ const char *sys_to = crm_element_value(stored_msg, F_CRM_SYS_TO); xmlNode *ping = create_xml_node(NULL, XML_CRM_TAG_PING); crm_xml_add(ping, XML_PING_ATTR_STATUS, "ok"); crm_xml_add(ping, XML_PING_ATTR_SYSFROM, sys_to); crm_xml_add(ping, "crmd_state", fsa_state2string(fsa_state)); /* Ok, so technically not so interesting, but CTS needs to see this */ crm_notice("Current ping state: %s", fsa_state2string(fsa_state)); msg = create_reply(stored_msg, ping); if(msg) { relay_message(msg, TRUE); } free_xml(ping); free_xml(msg); } else if (strcmp(op, CRM_OP_RM_NODE_CACHE) == 0) { int id = 0; const char *name = NULL; crm_element_value_int(stored_msg, XML_ATTR_ID, &id); name = crm_element_value(stored_msg, XML_ATTR_UNAME); if(cause == C_IPC_MESSAGE) { msg = create_request(CRM_OP_RM_NODE_CACHE, NULL, NULL, CRM_SYSTEM_CRMD, CRM_SYSTEM_CRMD, NULL); if (send_cluster_message(NULL, crm_msg_crmd, msg, TRUE) == FALSE) { crm_err("Could not instruct peers to remove references to node %s/%u", name, id); } else { crm_notice("Instructing peers to remove references to node %s/%u", name, id); } free_xml(msg); } else { reap_crm_member(id, name); } } else { crm_err("Unexpected request (%s) sent to %s", op, AM_I_DC ? "the DC" : "non-DC node"); crm_log_xml_err(stored_msg, "Unexpected"); } return I_NULL; } void handle_response(xmlNode * stored_msg) { const char *op = crm_element_value(stored_msg, F_CRM_TASK); if (op == NULL) { crm_log_xml_err(stored_msg, "Bad message"); } else if (AM_I_DC && strcmp(op, CRM_OP_PECALC) == 0) { /* Check if the PE answer been superceeded by a subsequent request? */ const char *msg_ref = crm_element_value(stored_msg, XML_ATTR_REFERENCE); if (msg_ref == NULL) { crm_err("%s - Ignoring calculation with no reference", op); } else if (safe_str_eq(msg_ref, fsa_pe_ref)) { ha_msg_input_t fsa_input; fsa_input.msg = stored_msg; register_fsa_input_later(C_IPC_MESSAGE, I_PE_SUCCESS, &fsa_input); crm_trace("Completed: %s...", fsa_pe_ref); } else { crm_info("%s calculation %s is obsolete", op, msg_ref); } } else if (strcmp(op, CRM_OP_VOTE) == 0 || strcmp(op, CRM_OP_SHUTDOWN_REQ) == 0 || strcmp(op, CRM_OP_SHUTDOWN) == 0) { } else { const char *host_from = crm_element_value(stored_msg, F_CRM_HOST_FROM); crm_err("Unexpected response (op=%s, src=%s) sent to the %s", op, host_from, AM_I_DC ? "DC" : "CRMd"); } } enum crmd_fsa_input handle_shutdown_request(xmlNode * stored_msg) { /* handle here to avoid potential version issues * where the shutdown message/proceedure may have * been changed in later versions. * * This way the DC is always in control of the shutdown */ char *now_s = NULL; time_t now = time(NULL); const char *host_from = crm_element_value(stored_msg, F_CRM_HOST_FROM); if (host_from == NULL) { /* we're shutting down and the DC */ host_from = fsa_our_uname; } crm_info("Creating shutdown request for %s (state=%s)", host_from, fsa_state2string(fsa_state)); crm_log_xml_trace(stored_msg, "message"); now_s = crm_itoa(now); update_attrd(host_from, XML_CIB_ATTR_SHUTDOWN, now_s, NULL, FALSE); free(now_s); /* will be picked up by the TE as long as its running */ return I_NULL; } /* msg is deleted by the time this returns */ extern gboolean process_te_message(xmlNode * msg, xmlNode * xml_data); gboolean send_msg_via_ipc(xmlNode * msg, const char *sys) { gboolean send_ok = TRUE; crm_client_t *client_channel = crm_client_get_by_id(sys); if (crm_element_value(msg, F_CRM_HOST_FROM) == NULL) { crm_xml_add(msg, F_CRM_HOST_FROM, fsa_our_uname); } if (client_channel != NULL) { /* Transient clients such as crmadmin */ send_ok = crm_ipcs_send(client_channel, 0, msg, TRUE); } else if (sys != NULL && strcmp(sys, CRM_SYSTEM_TENGINE) == 0) { xmlNode *data = get_message_xml(msg, F_CRM_DATA); process_te_message(msg, data); } else if (sys != NULL && strcmp(sys, CRM_SYSTEM_LRMD) == 0) { fsa_data_t fsa_data; ha_msg_input_t fsa_input; fsa_input.msg = msg; fsa_input.xml = get_message_xml(msg, F_CRM_DATA); fsa_data.id = 0; fsa_data.actions = 0; fsa_data.data = &fsa_input; fsa_data.fsa_input = I_MESSAGE; fsa_data.fsa_cause = C_IPC_MESSAGE; fsa_data.origin = __FUNCTION__; fsa_data.data_type = fsa_dt_ha_msg; #ifdef FSA_TRACE crm_trace("Invoking action A_LRM_INVOKE (%.16llx)", A_LRM_INVOKE); #endif do_lrm_invoke(A_LRM_INVOKE, C_IPC_MESSAGE, fsa_state, I_MESSAGE, &fsa_data); } else if (sys != NULL && crmd_is_proxy_session(sys)) { crmd_proxy_send(sys, msg); } else { crm_err("Unknown Sub-system (%s)... discarding message.", crm_str(sys)); send_ok = FALSE; } return send_ok; } ha_msg_input_t * new_ha_msg_input(xmlNode * orig) { ha_msg_input_t *input_copy = NULL; input_copy = calloc(1, sizeof(ha_msg_input_t)); input_copy->msg = orig; input_copy->xml = get_message_xml(input_copy->msg, F_CRM_DATA); return input_copy; } void delete_ha_msg_input(ha_msg_input_t * orig) { if (orig == NULL) { return; } free_xml(orig->msg); free(orig); } pacemaker-master/crmd/misc.c000066400000000000000000000044111217637305600163350ustar00rootroot00000000000000/* * Copyright (C) 2004 Andrew Beekhof * * 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 2 of the License, or (at your option) any later version. * * This software 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 library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include #include #include #include #include #include /* A_LOG, A_WARN, A_ERROR */ void do_log(long long action, enum crmd_fsa_cause cause, enum crmd_fsa_state cur_state, enum crmd_fsa_input current_input, fsa_data_t * msg_data) { unsigned log_type = LOG_TRACE; if (action & A_LOG) { log_type = LOG_INFO; } else if (action & A_WARN) { log_type = LOG_WARNING; } else if (action & A_ERROR) { log_type = LOG_ERR; } do_crm_log(log_type, "FSA: Input %s from %s() received in state %s", fsa_input2string(msg_data->fsa_input), msg_data->origin, fsa_state2string(cur_state)); if (msg_data->data_type == fsa_dt_ha_msg) { ha_msg_input_t *input = fsa_typed_data(msg_data->data_type); crm_log_xml_debug(input->msg, __FUNCTION__); } else if (msg_data->data_type == fsa_dt_xml) { xmlNode *input = fsa_typed_data(msg_data->data_type); crm_log_xml_debug(input, __FUNCTION__); } else if (msg_data->data_type == fsa_dt_lrm) { lrmd_event_data_t *input = fsa_typed_data(msg_data->data_type); do_crm_log(log_type, "Resource %s: Call ID %d returned %d (%d)." " New status if rc=0: %s", input->rsc_id, input->call_id, input->rc, input->op_status, (char *)input->user_data); } } pacemaker-master/crmd/pengine.c000066400000000000000000000221641217637305600170340ustar00rootroot00000000000000/* * Copyright (C) 2004 Andrew Beekhof * * 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 2 of the License, or (at your option) any later version. * * This software 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 library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include #include #include #include #include #include /* for access */ #include /* for calls to open */ #include /* for calls to open */ #include /* for calls to open */ #include /* for getpwuid */ #include /* for initgroups */ #include /* for getrlimit */ #include /* for getrlimit */ #include #include #include #include #include #include #include #include struct crm_subsystem_s *pe_subsystem = NULL; void do_pe_invoke_callback(xmlNode * msg, int call_id, int rc, xmlNode * output, void *user_data); static void save_cib_contents(xmlNode * msg, int call_id, int rc, xmlNode * output, void *user_data) { char *id = user_data; register_fsa_error_adv(C_FSA_INTERNAL, I_ERROR, NULL, NULL, __FUNCTION__); CRM_CHECK(id != NULL, return); if (rc == pcmk_ok) { int len = 15; char *filename = NULL; len += strlen(id); len += strlen(PE_STATE_DIR); filename = calloc(1, len); CRM_CHECK(filename != NULL, return); sprintf(filename, PE_STATE_DIR "/pe-core-%s.bz2", id); if (write_xml_file(output, filename, TRUE) < 0) { crm_err("Could not save CIB contents after PE crash to %s", filename); } else { crm_notice("Saved CIB contents after PE crash to %s", filename); } free(filename); } free(id); } static void pe_ipc_destroy(gpointer user_data) { clear_bit(fsa_input_register, pe_subsystem->flag_connected); if (is_set(fsa_input_register, pe_subsystem->flag_required)) { int rc = pcmk_ok; char *uuid_str = crm_generate_uuid(); crm_crit("Connection to the Policy Engine failed (pid=%d, uuid=%s)", pe_subsystem->pid, uuid_str); /* *The PE died... * * Save the current CIB so that we have a chance of * figuring out what killed it. * * Delay raising the I_ERROR until the query below completes or * 5s is up, whichever comes first. * */ rc = fsa_cib_conn->cmds->query(fsa_cib_conn, NULL, NULL, cib_scope_local); fsa_register_cib_callback(rc, FALSE, uuid_str, save_cib_contents); } else { crm_info("Connection to the Policy Engine released"); } pe_subsystem->pid = -1; pe_subsystem->source = NULL; pe_subsystem->client = NULL; mainloop_set_trigger(fsa_source); return; } static int pe_ipc_dispatch(const char *buffer, ssize_t length, gpointer userdata) { xmlNode *msg = string2xml(buffer); if (msg) { route_message(C_IPC_MESSAGE, msg); } free_xml(msg); return 0; } /* A_PE_START, A_PE_STOP, A_TE_RESTART */ void do_pe_control(long long action, enum crmd_fsa_cause cause, enum crmd_fsa_state cur_state, enum crmd_fsa_input current_input, fsa_data_t * msg_data) { struct crm_subsystem_s *this_subsys = pe_subsystem; long long stop_actions = A_PE_STOP; long long start_actions = A_PE_START; static struct ipc_client_callbacks pe_callbacks = { .dispatch = pe_ipc_dispatch, .destroy = pe_ipc_destroy }; if (action & stop_actions) { clear_bit(fsa_input_register, pe_subsystem->flag_required); mainloop_del_ipc_client(pe_subsystem->source); pe_subsystem->source = NULL; clear_bit(fsa_input_register, pe_subsystem->flag_connected); } if ((action & start_actions) && (is_set(fsa_input_register, R_PE_CONNECTED) == FALSE)) { if (cur_state != S_STOPPING) { set_bit(fsa_input_register, pe_subsystem->flag_required); pe_subsystem->source = mainloop_add_ipc_client(CRM_SYSTEM_PENGINE, G_PRIORITY_DEFAULT, 5 * 1024 * 1024 /* 5Mb */ , NULL, &pe_callbacks); if (pe_subsystem->source == NULL) { crm_warn("Setup of client connection failed, not adding channel to mainloop"); register_fsa_error(C_FSA_INTERNAL, I_FAIL, NULL); return; } /* if (is_openais_cluster()) { */ /* pe_subsystem->pid = pe_subsystem->ipc->farside_pid; */ /* } */ set_bit(fsa_input_register, pe_subsystem->flag_connected); } else { crm_info("Ignoring request to start %s while shutting down", this_subsys->name); } } } int fsa_pe_query = 0; char *fsa_pe_ref = NULL; /* A_PE_INVOKE */ void do_pe_invoke(long long action, enum crmd_fsa_cause cause, enum crmd_fsa_state cur_state, enum crmd_fsa_input current_input, fsa_data_t * msg_data) { if (AM_I_DC == FALSE) { crm_err("Not DC: No need to invoke the PE (anymore): %s", fsa_action2string(action)); return; } if (is_set(fsa_input_register, R_PE_CONNECTED) == FALSE) { if (is_set(fsa_input_register, R_SHUTDOWN)) { crm_err("Cannot shut down gracefully without the PE"); register_fsa_input_before(C_FSA_INTERNAL, I_TERMINATE, NULL); } else { crm_info("Waiting for the PE to connect"); crmd_fsa_stall(FALSE); register_fsa_action(A_PE_START); } return; } if (cur_state != S_POLICY_ENGINE) { crm_notice("No need to invoke the PE in state %s", fsa_state2string(cur_state)); return; } if (is_set(fsa_input_register, R_HAVE_CIB) == FALSE) { crm_err("Attempted to invoke the PE without a consistent copy of the CIB!"); /* start the join from scratch */ register_fsa_input_before(C_FSA_INTERNAL, I_ELECTION, NULL); return; } fsa_pe_query = fsa_cib_conn->cmds->query(fsa_cib_conn, NULL, NULL, cib_scope_local); crm_debug("Query %d: Requesting the current CIB: %s", fsa_pe_query, fsa_state2string(fsa_state)); /* Make sure any queued calculations are discarded */ free(fsa_pe_ref); fsa_pe_ref = NULL; fsa_register_cib_callback(fsa_pe_query, FALSE, NULL, do_pe_invoke_callback); } void do_pe_invoke_callback(xmlNode * msg, int call_id, int rc, xmlNode * output, void *user_data) { int sent; xmlNode *cmd = NULL; if (rc != pcmk_ok) { crm_err("Cant retrieve the CIB: %s (call %d)", pcmk_strerror(rc), call_id); register_fsa_error_adv(C_FSA_INTERNAL, I_ERROR, NULL, NULL, __FUNCTION__); return; } else if (call_id != fsa_pe_query) { crm_trace("Skipping superceeded CIB query: %d (current=%d)", call_id, fsa_pe_query); return; } else if (AM_I_DC == FALSE || is_set(fsa_input_register, R_PE_CONNECTED) == FALSE) { crm_debug("No need to invoke the PE anymore"); return; } else if (fsa_state != S_POLICY_ENGINE) { crm_debug("Discarding PE request in state: %s", fsa_state2string(fsa_state)); return; } else if (last_peer_update != 0) { crm_debug("Re-asking for the CIB: peer update %d still pending", last_peer_update); sleep(1); register_fsa_action(A_PE_INVOKE); return; } else if (fsa_state != S_POLICY_ENGINE) { crm_err("Invoking PE in state: %s", fsa_state2string(fsa_state)); return; } CRM_LOG_ASSERT(output != NULL); crm_xml_add(output, XML_ATTR_DC_UUID, fsa_our_uuid); crm_xml_add_int(output, XML_ATTR_HAVE_QUORUM, fsa_has_quorum); if (ever_had_quorum && crm_have_quorum == FALSE) { crm_xml_add_int(output, XML_ATTR_QUORUM_PANIC, 1); } cmd = create_request(CRM_OP_PECALC, output, NULL, CRM_SYSTEM_PENGINE, CRM_SYSTEM_DC, NULL); free(fsa_pe_ref); fsa_pe_ref = crm_element_value_copy(cmd, XML_ATTR_REFERENCE); sent = crm_ipc_send(mainloop_get_ipc_client(pe_subsystem->source), cmd, 0, 0, NULL); if (sent <= 0) { crm_err("Could not contact the pengine: %d", sent); register_fsa_error_adv(C_FSA_INTERNAL, I_ERROR, NULL, NULL, __FUNCTION__); } crm_debug("Invoking the PE: query=%d, ref=%s, seq=%llu, quorate=%d", fsa_pe_query, fsa_pe_ref, crm_peer_seq, fsa_has_quorum); free_xml(cmd); } pacemaker-master/crmd/remote_lrmd_ra.c000066400000000000000000000464661217637305600204150ustar00rootroot00000000000000/* * Copyright (C) 2013 David Vossel * * 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 2 of the License, or (at your option) any later version. * * This software 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 library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include #include #include #include #include #include #include #include #include #define REMOTE_LRMD_RA "remote" /* The max start timeout before cmd retry */ #define MAX_START_TIMEOUT_MS 10000 typedef struct remote_ra_cmd_s { /*! the local node the cmd is issued from */ char *owner; /*! the remote node the cmd is executed on */ char *rsc_id; /*! the action to execute */ char *action; /*! some string the client wants us to give it back */ char *userdata; /*! start delay in ms */ int start_delay; /*! timer id used for start delay. */ int delay_id; /*! timeout in ms for cmd */ int timeout; int remaining_timeout; /*! recurring interval in ms */ int interval; /*! interval timer id */ int interval_id; int reported_success; int monitor_timeout_id; /*! action parameters */ lrmd_key_value_t *params; /*! executed rc */ int rc; int op_status; int call_id; time_t start_time; gboolean cancel; } remote_ra_cmd_t; typedef struct remote_ra_data_s { crm_trigger_t *work; remote_ra_cmd_t *cur_cmd; GList *cmds; GList *recurring_cmds; } remote_ra_data_t; static int handle_remote_ra_start(lrm_state_t * lrm_state, remote_ra_cmd_t * cmd, int timeout_ms); static void free_cmd(gpointer user_data) { remote_ra_cmd_t *cmd = user_data; if (!cmd) { return; } if (cmd->delay_id) { g_source_remove(cmd->delay_id); } if (cmd->interval_id) { g_source_remove(cmd->interval_id); } if (cmd->monitor_timeout_id) { g_source_remove(cmd->monitor_timeout_id); } free(cmd->owner); free(cmd->rsc_id); free(cmd->action); free(cmd->userdata); lrmd_key_value_freeall(cmd->params); free(cmd); } static int generate_callid(void) { static int remote_ra_callid = 0; remote_ra_callid++; if (remote_ra_callid <= 0) { remote_ra_callid = 1; } return remote_ra_callid; } static gboolean recurring_helper(gpointer data) { remote_ra_cmd_t *cmd = data; lrm_state_t *connection_rsc = NULL; cmd->interval_id = 0; connection_rsc = lrm_state_find(cmd->rsc_id); if (connection_rsc && connection_rsc->remote_ra_data) { remote_ra_data_t *ra_data = connection_rsc->remote_ra_data; ra_data->recurring_cmds = g_list_remove(ra_data->recurring_cmds, cmd); cmd->call_id = generate_callid(); ra_data->cmds = g_list_append(ra_data->cmds, cmd); mainloop_set_trigger(ra_data->work); } return FALSE; } static gboolean start_delay_helper(gpointer data) { remote_ra_cmd_t *cmd = data; lrm_state_t *connection_rsc = NULL; cmd->delay_id = 0; connection_rsc = lrm_state_find(cmd->rsc_id); if (connection_rsc && connection_rsc->remote_ra_data) { remote_ra_data_t *ra_data = connection_rsc->remote_ra_data; mainloop_set_trigger(ra_data->work); } return FALSE; } static void report_remote_ra_result(remote_ra_cmd_t * cmd) { lrmd_event_data_t op = { 0, }; op.type = lrmd_event_exec_complete; op.rsc_id = cmd->rsc_id; op.op_type = cmd->action; op.user_data = cmd->userdata; op.timeout = cmd->timeout; op.interval = cmd->interval; op.rc = cmd->rc; op.op_status = cmd->op_status; if (cmd->params) { lrmd_key_value_t *tmp; op.params = g_hash_table_new_full(crm_str_hash, g_str_equal, g_hash_destroy_str, g_hash_destroy_str); for (tmp = cmd->params; tmp; tmp = tmp->next) { g_hash_table_insert(op.params, strdup(tmp->key), strdup(tmp->value)); } } op.call_id = cmd->call_id; op.remote_nodename = cmd->owner; lrm_op_callback(&op); if (op.params) { g_hash_table_destroy(op.params); } } static void update_remaining_timeout(remote_ra_cmd_t * cmd) { cmd->remaining_timeout = ((cmd->timeout / 1000) - (time(NULL) - cmd->start_time)) * 1000; } static gboolean retry_start_cmd_cb(gpointer data) { lrm_state_t *lrm_state = data; remote_ra_data_t *ra_data = lrm_state->remote_ra_data; remote_ra_cmd_t *cmd = NULL; int rc = -1; if (!ra_data || !ra_data->cur_cmd) { return FALSE; } cmd = ra_data->cur_cmd; if (safe_str_neq(cmd->action, "start")) { return FALSE; } update_remaining_timeout(cmd); if (cmd->remaining_timeout > 0) { rc = handle_remote_ra_start(lrm_state, cmd, cmd->remaining_timeout); } if (rc != 0) { cmd->rc = PCMK_EXECRA_UNKNOWN_ERROR; cmd->op_status = PCMK_LRM_OP_ERROR; report_remote_ra_result(cmd); if (ra_data->cmds) { mainloop_set_trigger(ra_data->work); } ra_data->cur_cmd = NULL; free_cmd(cmd); } else { /* wait for connection event */ } return FALSE; } static gboolean monitor_timeout_cb(gpointer data) { lrm_state_t *lrm_state = NULL; remote_ra_cmd_t *cmd = data; crm_debug("Poke async response timed out for node %s", cmd->rsc_id); cmd->monitor_timeout_id = 0; cmd->op_status = PCMK_LRM_OP_TIMEOUT; cmd->rc = PCMK_EXECRA_UNKNOWN_ERROR; lrm_state = lrm_state_find(cmd->rsc_id); if (lrm_state && lrm_state->remote_ra_data) { remote_ra_data_t *ra_data = lrm_state->remote_ra_data; if (ra_data->cur_cmd == cmd) { ra_data->cur_cmd = NULL; } if (ra_data->cmds) { mainloop_set_trigger(ra_data->work); } } report_remote_ra_result(cmd); free_cmd(cmd); return FALSE; } static void remote_init_cib_status(lrm_state_t *lrm_state) { xmlNode *update = create_xml_node(NULL, XML_CIB_TAG_STATUS); xmlNode *state = NULL; int call_id = 0; int call_opt = cib_quorum_override; if (fsa_state == S_ELECTION || fsa_state == S_PENDING) { call_opt |= cib_scope_local; } state = create_xml_node(update, XML_CIB_TAG_STATE); crm_xml_add(state, XML_NODE_IS_REMOTE, "true"); crm_xml_add(state, XML_ATTR_UUID, lrm_state->node_name); crm_xml_add(state, XML_ATTR_UNAME, lrm_state->node_name); crm_xml_add(state, XML_ATTR_ORIGIN, __FUNCTION__); fsa_cib_update(XML_CIB_TAG_STATUS, update, call_opt, call_id, NULL); if (call_id != pcmk_ok) { crm_debug("Failed to init status section for remote-node %s", lrm_state->node_name); } free_xml(update); } void remote_lrm_op_callback(lrmd_event_data_t * op) { lrm_state_t *lrm_state = NULL; remote_ra_data_t *ra_data = NULL; remote_ra_cmd_t *cmd = NULL; crm_debug("remote connection event - event_type:%s node:%s action:%s rc:%s op_status:%s", lrmd_event_type2str(op->type), op->remote_nodename, op->op_type ? op->op_type : "none", lrmd_event_rc2str(op->rc), services_lrm_status_str(op->op_status)); /* filter all EXEC events up */ if (op->type == lrmd_event_exec_complete) { lrm_op_callback(op); return; } lrm_state = lrm_state_find(op->remote_nodename); if (!lrm_state || !lrm_state->remote_ra_data) { crm_debug("lrm_state info not found for remote lrmd connection event"); return; } ra_data = lrm_state->remote_ra_data; if (!ra_data->cur_cmd) { crm_debug("no event to match"); return; } cmd = ra_data->cur_cmd; /* Start actions and migrate from actions complete after connection * comes back to us. */ if (op->type == lrmd_event_connect && (safe_str_eq(cmd->action, "start") || safe_str_eq(cmd->action, "migrate_from"))) { if (op->connection_rc < 0) { update_remaining_timeout(cmd); /* There isn't much of a reason to reschedule if the timeout is too small */ if (cmd->remaining_timeout > 3000) { crm_trace("rescheduling start, remaining timeout %d", cmd->remaining_timeout); g_timeout_add(1000, retry_start_cmd_cb, lrm_state); return; } else { crm_trace("can't reschedule start, remaining timeout too small %d", cmd->remaining_timeout); } cmd->op_status = PCMK_LRM_OP_TIMEOUT; cmd->rc = PCMK_EXECRA_UNKNOWN_ERROR; } else { /* make sure we have a clean status section to start with */ remote_init_cib_status(lrm_state); cmd->rc = PCMK_EXECRA_OK; cmd->op_status = PCMK_LRM_OP_DONE; } crm_debug("remote lrmd connect event matched %s action. ", cmd->action); report_remote_ra_result(cmd); if (ra_data->cmds) { mainloop_set_trigger(ra_data->work); } ra_data->cur_cmd = NULL; free_cmd(cmd); return; } else if (op->type == lrmd_event_poke && safe_str_eq(cmd->action, "monitor")) { if (cmd->monitor_timeout_id) { g_source_remove(cmd->monitor_timeout_id); cmd->monitor_timeout_id = 0; } /* Only report success the first time, after that only worry about failures. * For this function, if we get the poke pack, it is always a success. Pokes * only fail if the send fails, or the response times out. */ if (!cmd->reported_success) { cmd->rc = PCMK_EXECRA_OK; cmd->op_status = PCMK_LRM_OP_DONE; report_remote_ra_result(cmd); cmd->reported_success = 1; } crm_debug("remote lrmd poke event matched %s action. ", cmd->action); /* success, keep rescheduling if interval is present. */ if (cmd->interval && (cmd->cancel == FALSE)) { ra_data->recurring_cmds = g_list_append(ra_data->recurring_cmds, cmd); cmd->interval_id = g_timeout_add(cmd->interval, recurring_helper, cmd); cmd = NULL; /* prevent free */ } if (ra_data->cmds) { mainloop_set_trigger(ra_data->work); } ra_data->cur_cmd = NULL; free_cmd(cmd); return; } crm_debug("Event did not match %s action", ra_data->cur_cmd->action); } static int handle_remote_ra_start(lrm_state_t * lrm_state, remote_ra_cmd_t * cmd, int timeout_ms) { const char *server = NULL; lrmd_key_value_t *tmp = NULL; int port = 0; int timeout_used = timeout_ms > MAX_START_TIMEOUT_MS ? MAX_START_TIMEOUT_MS : timeout_ms; for (tmp = cmd->params; tmp; tmp = tmp->next) { if (safe_str_eq(tmp->key, "addr") || safe_str_eq(tmp->key, "server")) { server = tmp->value; } if (safe_str_eq(tmp->key, "port")) { port = atoi(tmp->value); } } return lrm_state_remote_connect_async(lrm_state, server, port, timeout_used); } static gboolean handle_remote_ra_exec(gpointer user_data) { int rc = 0; lrm_state_t *lrm_state = user_data; remote_ra_data_t *ra_data = lrm_state->remote_ra_data; remote_ra_cmd_t *cmd; GList *first = NULL; if (ra_data->cur_cmd) { /* still waiting on previous cmd */ return TRUE; } while (ra_data->cmds) { first = ra_data->cmds; cmd = first->data; if (cmd->delay_id) { /* still waiting for start delay timer to trip */ return TRUE; } ra_data->cmds = g_list_remove_link(ra_data->cmds, first); g_list_free_1(first); if (!strcmp(cmd->action, "start") || !strcmp(cmd->action, "migrate_from")) { xmlNode *status = create_xml_node(NULL, XML_CIB_TAG_STATE); /* clear node status in cib */ crm_xml_add(status, XML_ATTR_ID, lrm_state->node_name); lrm_state_reset_tables(lrm_state); fsa_cib_delete(XML_CIB_TAG_STATUS, status, cib_quorum_override, rc, NULL); crm_info("Forced a remote LRM refresh before connection start: call=%d", rc); crm_log_xml_trace(status, "CLEAR LRM"); free_xml(status); rc = handle_remote_ra_start(lrm_state, cmd, cmd->timeout); if (rc == 0) { /* take care of this later when we get async connection result */ crm_debug("began remote lrmd connect, waiting for connect event."); ra_data->cur_cmd = cmd; return TRUE; } else { crm_debug("connect failed, not expecting to match any connection event later"); cmd->rc = PCMK_EXECRA_UNKNOWN_ERROR; cmd->op_status = PCMK_LRM_OP_ERROR; } report_remote_ra_result(cmd); } else if (!strcmp(cmd->action, "monitor")) { if (lrm_state_is_connected(lrm_state) == TRUE) { rc = lrm_state_poke_connection(lrm_state); if (rc < 0) { cmd->rc = PCMK_EXECRA_UNKNOWN_ERROR; cmd->op_status = PCMK_LRM_OP_ERROR; } } else { rc = -1; cmd->op_status = PCMK_LRM_OP_DONE; cmd->rc = PCMK_EXECRA_NOT_RUNNING; } if (rc == 0) { crm_debug("poked remote lrmd at node %s, waiting for async response.", cmd->rsc_id); ra_data->cur_cmd = cmd; cmd->monitor_timeout_id = g_timeout_add(cmd->timeout, monitor_timeout_cb, cmd); return TRUE; } report_remote_ra_result(cmd); } else if (!strcmp(cmd->action, "stop")) { lrm_state_disconnect(lrm_state); cmd->rc = PCMK_EXECRA_OK; cmd->op_status = PCMK_LRM_OP_DONE; if (ra_data->cmds) { g_list_free_full(ra_data->cmds, free_cmd); } if (ra_data->recurring_cmds) { g_list_free_full(ra_data->recurring_cmds, free_cmd); } ra_data->cmds = NULL; ra_data->recurring_cmds = NULL; report_remote_ra_result(cmd); } else if (!strcmp(cmd->action, "migrate_to")) { /* no-op. */ cmd->rc = PCMK_EXECRA_OK; cmd->op_status = PCMK_LRM_OP_DONE; report_remote_ra_result(cmd); } free_cmd(cmd); } return TRUE; } static void remote_ra_data_init(lrm_state_t * lrm_state) { remote_ra_data_t *ra_data = NULL; if (lrm_state->remote_ra_data) { return; } ra_data = calloc(1, sizeof(remote_ra_data_t)); ra_data->work = mainloop_add_trigger(G_PRIORITY_HIGH, handle_remote_ra_exec, lrm_state); lrm_state->remote_ra_data = ra_data; } void remote_ra_cleanup(lrm_state_t * lrm_state) { remote_ra_data_t *ra_data = lrm_state->remote_ra_data; if (!ra_data) { return; } if (ra_data->cmds) { g_list_free_full(ra_data->cmds, free_cmd); } if (ra_data->recurring_cmds) { g_list_free_full(ra_data->recurring_cmds, free_cmd); } mainloop_destroy_trigger(ra_data->work); free(ra_data); lrm_state->remote_ra_data = NULL; } gboolean is_remote_lrmd_ra(const char *agent, const char *provider, const char *id) { if (agent && provider && !strcmp(agent, REMOTE_LRMD_RA) && !strcmp(provider, "pacemaker")) { return TRUE; } if (id && lrm_state_find(id)) { return TRUE; } return FALSE; } lrmd_rsc_info_t * remote_ra_get_rsc_info(lrm_state_t * lrm_state, const char *rsc_id) { lrmd_rsc_info_t *info = NULL; if ((lrm_state_find(rsc_id))) { info = calloc(1, sizeof(lrmd_rsc_info_t)); info->id = strdup(rsc_id); info->type = strdup(REMOTE_LRMD_RA); info->class = strdup("ocf"); info->provider = strdup("pacemaker"); } return info; } static gboolean is_remote_ra_supported_action(const char *action) { if (!action) { return FALSE; } else if (strcmp(action, "start") && strcmp(action, "stop") && strcmp(action, "migrate_to") && strcmp(action, "migrate_from") && strcmp(action, "monitor")) { return FALSE; } return TRUE; } static GList * remove_cmd(GList * list, const char *action, int interval) { remote_ra_cmd_t *cmd = NULL; GListPtr gIter = NULL; for (gIter = list; gIter != NULL; gIter = gIter->next) { cmd = gIter->data; if (cmd->interval == interval && safe_str_eq(cmd->action, action)) { break; } cmd = NULL; } if (cmd) { list = g_list_remove(list, cmd); free_cmd(cmd); } return list; } int remote_ra_cancel(lrm_state_t * lrm_state, const char *rsc_id, const char *action, int interval) { lrm_state_t *connection_rsc = NULL; remote_ra_data_t *ra_data = NULL; connection_rsc = lrm_state_find(rsc_id); if (!connection_rsc || !connection_rsc->remote_ra_data) { return -EINVAL; } ra_data = connection_rsc->remote_ra_data; ra_data->cmds = remove_cmd(ra_data->cmds, action, interval); ra_data->recurring_cmds = remove_cmd(ra_data->recurring_cmds, action, interval); if (ra_data->cur_cmd && (ra_data->cur_cmd->interval == interval) && (safe_str_eq(ra_data->cur_cmd->action, action))) { ra_data->cur_cmd->cancel = TRUE; } return 0; } int remote_ra_exec(lrm_state_t * lrm_state, const char *rsc_id, const char *action, const char *userdata, int interval, /* ms */ int timeout, /* ms */ int start_delay, /* ms */ lrmd_key_value_t * params) { int rc = 0; lrm_state_t *connection_rsc = NULL; remote_ra_cmd_t *cmd = NULL; remote_ra_data_t *ra_data = NULL; if (is_remote_ra_supported_action(action) == FALSE) { rc = -EINVAL; goto exec_done; } connection_rsc = lrm_state_find(rsc_id); if (!connection_rsc) { rc = -EINVAL; goto exec_done; } remote_ra_data_init(connection_rsc); cmd = calloc(1, sizeof(remote_ra_cmd_t)); cmd->owner = strdup(lrm_state->node_name); cmd->rsc_id = strdup(rsc_id); cmd->action = strdup(action); cmd->userdata = strdup(userdata); cmd->interval = interval; cmd->timeout = timeout; cmd->start_delay = start_delay; cmd->params = params; cmd->start_time = time(NULL); cmd->call_id = generate_callid(); if (cmd->start_delay) { cmd->delay_id = g_timeout_add(cmd->start_delay, start_delay_helper, cmd); } ra_data = connection_rsc->remote_ra_data; ra_data->cmds = g_list_append(ra_data->cmds, cmd); mainloop_set_trigger(ra_data->work); return cmd->call_id; exec_done: lrmd_key_value_freeall(params); return rc; } pacemaker-master/crmd/subsystems.c000066400000000000000000000130501217637305600176220ustar00rootroot00000000000000/* * Copyright (C) 2004 Andrew Beekhof * * 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 2 of the License, or (at your option) any later version. * * This software 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 library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include /* for access */ #include /* for calls to open */ #include /* for calls to open */ #include /* for calls to open */ #include /* for getpwuid */ #include /* for initgroups */ #include #include #include /* for getrlimit */ #include #include #include /* for getrlimit */ #include #include #include #include #include #include #include #include #include static void crmd_child_exit(mainloop_child_t * p, pid_t pid, int core, int signo, int exitcode) { /* struct crm_subsystem_s *the_subsystem = mainloop_child_userdata(p); */ const char *name = mainloop_child_name(p); if (signo) { crm_notice("Child process %s terminated with signal %d (pid=%d, core=%d)", name, signo, pid, core); } else { do_crm_log(exitcode == 0 ? LOG_INFO : LOG_ERR, "Child process %s exited (pid=%d, rc=%d)", name, pid, exitcode); } } gboolean stop_subsystem(struct crm_subsystem_s *the_subsystem, gboolean force_quit) { int quit_signal = SIGTERM; crm_trace("Stopping sub-system \"%s\"", the_subsystem->name); clear_bit(fsa_input_register, the_subsystem->flag_required); if (the_subsystem->pid <= 0) { crm_trace("Client %s not running", the_subsystem->name); return FALSE; } if (is_set(fsa_input_register, the_subsystem->flag_connected) == FALSE) { /* running but not yet connected */ crm_debug("Stopping %s before it had connected", the_subsystem->name); } /* if(force_quit && the_subsystem->sent_kill == FALSE) { quit_signal = SIGKILL; } else if(force_quit) { crm_debug("Already sent -KILL to %s: [%d]", the_subsystem->name, the_subsystem->pid); } */ errno = 0; if (kill(the_subsystem->pid, quit_signal) == 0) { crm_info("Sent -TERM to %s: [%d]", the_subsystem->name, the_subsystem->pid); the_subsystem->sent_kill = TRUE; } else { crm_perror(LOG_ERR, "Sent -TERM to %s: [%d]", the_subsystem->name, the_subsystem->pid); } return TRUE; } gboolean start_subsystem(struct crm_subsystem_s * the_subsystem) { pid_t pid; struct stat buf; int s_res; unsigned int j; struct rlimit oflimits; const char *devnull = "/dev/null"; crm_info("Starting sub-system \"%s\"", the_subsystem->name); if (the_subsystem->pid > 0) { crm_warn("Client %s already running as pid %d", the_subsystem->name, (int)the_subsystem->pid); /* starting a started X is not an error */ return TRUE; } /* * We want to ensure that the exec will succeed before * we bother forking. */ if (access(the_subsystem->path, F_OK | X_OK) != 0) { crm_perror(LOG_ERR, "Cannot (access) exec %s", the_subsystem->path); return FALSE; } s_res = stat(the_subsystem->command, &buf); if (s_res != 0) { crm_perror(LOG_ERR, "Cannot (stat) exec %s", the_subsystem->command); return FALSE; } /* We need to fork so we can make child procs not real time */ switch (pid = fork()) { case -1: crm_err("Cannot fork."); return FALSE; default: /* Parent */ mainloop_child_add(pid, 0, the_subsystem->name, the_subsystem, crmd_child_exit); crm_trace("Client %s is has pid: %d", the_subsystem->name, pid); the_subsystem->pid = pid; return TRUE; case 0: /* Child */ /* create a new process group to avoid * being interupted by heartbeat */ setpgid(0, 0); break; } crm_debug("Executing \"%s (%s)\" (pid %d)", the_subsystem->command, the_subsystem->name, (int)getpid()); /* A precautionary measure */ getrlimit(RLIMIT_NOFILE, &oflimits); for (j = 0; j < oflimits.rlim_cur; ++j) { close(j); } (void)open(devnull, O_RDONLY); /* Stdin: fd 0 */ (void)open(devnull, O_WRONLY); /* Stdout: fd 1 */ (void)open(devnull, O_WRONLY); /* Stderr: fd 2 */ { char *opts[] = { strdup(the_subsystem->command), NULL }; /* coverity[toctou] The call to stat() is a fail-fast, not a race */ (void)execvp(the_subsystem->command, opts); } /* Should not happen */ crm_perror(LOG_ERR, "FATAL: Cannot exec %s", the_subsystem->command); return crm_exit(DAEMON_RESPAWN_STOP); /* Suppress respawning */ } pacemaker-master/crmd/te_actions.c000066400000000000000000000421641217637305600175410ustar00rootroot00000000000000/* * Copyright (C) 2004 Andrew Beekhof * * 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 2 of the License, or (at your option) any later version. * * This software 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 library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include #include #include #include #include #include #include #include #include char *te_uuid = NULL; void send_rsc_command(crm_action_t * action); static void te_start_action_timer(crm_graph_t * graph, crm_action_t * action) { action->timer = calloc(1, sizeof(crm_action_timer_t)); action->timer->timeout = action->timeout; action->timer->reason = timeout_action; action->timer->action = action; action->timer->source_id = g_timeout_add(action->timer->timeout + graph->network_delay, action_timer_callback, (void *)action->timer); CRM_ASSERT(action->timer->source_id != 0); } static gboolean te_pseudo_action(crm_graph_t * graph, crm_action_t * pseudo) { crm_debug("Pseudo action %d fired and confirmed", pseudo->id); pseudo->confirmed = TRUE; update_graph(graph, pseudo); trigger_graph(); return TRUE; } void send_stonith_update(crm_action_t * action, const char *target, const char *uuid) { int rc = pcmk_ok; crm_node_t *peer = NULL; /* zero out the node-status & remove all LRM status info */ xmlNode *node_state = NULL; CRM_CHECK(target != NULL, return); CRM_CHECK(uuid != NULL, return); /* Make sure the membership and join caches are accurate */ peer = crm_get_peer(0, target); if (peer->uuid == NULL) { crm_info("Recording uuid '%s' for node '%s'", uuid, target); peer->uuid = strdup(uuid); } crm_update_peer_proc(__FUNCTION__, peer, crm_proc_none, NULL); crm_update_peer_state(__FUNCTION__, peer, CRM_NODE_LOST, 0); crm_update_peer_expected(__FUNCTION__, peer, CRMD_JOINSTATE_DOWN); crm_update_peer_join(__FUNCTION__, peer, crm_join_none); node_state = do_update_node_cib(peer, node_update_cluster | node_update_peer | node_update_join | node_update_expected, NULL, __FUNCTION__); /* Force our known ID */ crm_xml_add(node_state, XML_ATTR_UUID, uuid); rc = fsa_cib_conn->cmds->update(fsa_cib_conn, XML_CIB_TAG_STATUS, node_state, cib_quorum_override | cib_scope_local | cib_can_create); /* Delay processing the trigger until the update completes */ crm_debug("Sending fencing update %d for %s", rc, target); fsa_register_cib_callback(rc, FALSE, strdup(target), cib_fencing_updated); /* Make sure it sticks */ /* fsa_cib_conn->cmds->bump_epoch(fsa_cib_conn, cib_quorum_override|cib_scope_local); */ erase_status_tag(target, XML_CIB_TAG_LRM, cib_scope_local); erase_status_tag(target, XML_TAG_TRANSIENT_NODEATTRS, cib_scope_local); free_xml(node_state); return; } static gboolean te_fence_node(crm_graph_t * graph, crm_action_t * action) { int rc = 0; const char *id = NULL; const char *uuid = NULL; const char *target = NULL; const char *type = NULL; gboolean invalid_action = FALSE; enum stonith_call_options options = st_opt_none; id = ID(action->xml); target = crm_element_value(action->xml, XML_LRM_ATTR_TARGET); uuid = crm_element_value(action->xml, XML_LRM_ATTR_TARGET_UUID); type = crm_meta_value(action->params, "stonith_action"); CRM_CHECK(id != NULL, invalid_action = TRUE); CRM_CHECK(uuid != NULL, invalid_action = TRUE); CRM_CHECK(type != NULL, invalid_action = TRUE); CRM_CHECK(target != NULL, invalid_action = TRUE); if (invalid_action) { crm_log_xml_warn(action->xml, "BadAction"); return FALSE; } crm_notice("Executing %s fencing operation (%s) on %s (timeout=%d)", type, id, target, transition_graph->stonith_timeout); /* Passing NULL means block until we can connect... */ te_connect_stonith(NULL); if (crmd_join_phase_count(crm_join_confirmed) == 1) { options |= st_opt_allow_suicide; } rc = stonith_api->cmds->fence(stonith_api, options, target, type, transition_graph->stonith_timeout / 1000, 0); stonith_api->cmds->register_callback(stonith_api, rc, transition_graph->stonith_timeout / 1000, st_opt_timeout_updates, generate_transition_key(transition_graph->id, action->id, 0, te_uuid), "tengine_stonith_callback", tengine_stonith_callback); return TRUE; } static int get_target_rc(crm_action_t * action) { const char *target_rc_s = crm_meta_value(action->params, XML_ATTR_TE_TARGET_RC); if (target_rc_s != NULL) { return crm_parse_int(target_rc_s, "0"); } return 0; } static gboolean te_crm_command(crm_graph_t * graph, crm_action_t * action) { char *counter = NULL; xmlNode *cmd = NULL; gboolean is_local = FALSE; const char *id = NULL; const char *task = NULL; const char *value = NULL; const char *on_node = NULL; const char *router_node = NULL; gboolean rc = TRUE; gboolean no_wait = FALSE; id = ID(action->xml); task = crm_element_value(action->xml, XML_LRM_ATTR_TASK); on_node = crm_element_value(action->xml, XML_LRM_ATTR_TARGET); router_node = crm_element_value(action->xml, XML_LRM_ATTR_ROUTER_NODE); if (!router_node) { router_node = on_node; } CRM_CHECK(on_node != NULL && strlen(on_node) != 0, crm_err("Corrupted command (id=%s) %s: no node", crm_str(id), crm_str(task)); return FALSE); crm_info("Executing crm-event (%s): %s on %s%s%s", crm_str(id), crm_str(task), on_node, is_local ? " (local)" : "", no_wait ? " - no waiting" : ""); if (safe_str_eq(router_node, fsa_our_uname)) { is_local = TRUE; } value = crm_meta_value(action->params, XML_ATTR_TE_NOWAIT); if (crm_is_true(value)) { no_wait = TRUE; } if (is_local && safe_str_eq(task, CRM_OP_SHUTDOWN)) { /* defer until everything else completes */ crm_info("crm-event (%s) is a local shutdown", crm_str(id)); graph->completion_action = tg_shutdown; graph->abort_reason = "local shutdown"; action->confirmed = TRUE; update_graph(graph, action); trigger_graph(); return TRUE; } else if (safe_str_eq(task, CRM_OP_SHUTDOWN)) { crm_node_t *peer = crm_get_peer(0, router_node); crm_update_peer_expected(__FUNCTION__, peer, CRMD_JOINSTATE_DOWN); } cmd = create_request(task, action->xml, router_node, CRM_SYSTEM_CRMD, CRM_SYSTEM_TENGINE, NULL); counter = generate_transition_key(transition_graph->id, action->id, get_target_rc(action), te_uuid); crm_xml_add(cmd, XML_ATTR_TRANSITION_KEY, counter); rc = send_cluster_message(crm_get_peer(0, router_node), crm_msg_crmd, cmd, TRUE); free(counter); free_xml(cmd); if (rc == FALSE) { crm_err("Action %d failed: send", action->id); return FALSE; } else if (no_wait) { action->confirmed = TRUE; update_graph(graph, action); trigger_graph(); } else { if (action->timeout <= 0) { crm_err("Action %d: %s on %s had an invalid timeout (%dms). Using %dms instead", action->id, task, on_node, action->timeout, graph->network_delay); action->timeout = graph->network_delay; } te_start_action_timer(graph, action); } return TRUE; } gboolean cib_action_update(crm_action_t * action, int status, int op_rc) { lrmd_event_data_t *op = NULL; xmlNode *state = NULL; xmlNode *rsc = NULL; xmlNode *xml_op = NULL; xmlNode *action_rsc = NULL; int rc = pcmk_ok; const char *name = NULL; const char *value = NULL; const char *rsc_id = NULL; const char *task = crm_element_value(action->xml, XML_LRM_ATTR_TASK); const char *target = crm_element_value(action->xml, XML_LRM_ATTR_TARGET); const char *task_uuid = crm_element_value(action->xml, XML_LRM_ATTR_TASK_KEY); const char *target_uuid = crm_element_value(action->xml, XML_LRM_ATTR_TARGET_UUID); int call_options = cib_quorum_override | cib_scope_local; int target_rc = get_target_rc(action); if (status == PCMK_LRM_OP_PENDING) { crm_debug("%s %d: Recording pending operation %s on %s", crm_element_name(action->xml), action->id, task_uuid, target); } else { crm_warn("%s %d: %s on %s timed out", crm_element_name(action->xml), action->id, task_uuid, target); } action_rsc = find_xml_node(action->xml, XML_CIB_TAG_RESOURCE, TRUE); if (action_rsc == NULL) { return FALSE; } rsc_id = ID(action_rsc); CRM_CHECK(rsc_id != NULL, crm_log_xml_err(action->xml, "Bad:action"); return FALSE); /* update the CIB */ state = create_xml_node(NULL, XML_CIB_TAG_STATE); crm_xml_add(state, XML_ATTR_UUID, target_uuid); crm_xml_add(state, XML_ATTR_UNAME, target); rsc = create_xml_node(state, XML_CIB_TAG_LRM); crm_xml_add(rsc, XML_ATTR_ID, target_uuid); rsc = create_xml_node(rsc, XML_LRM_TAG_RESOURCES); rsc = create_xml_node(rsc, XML_LRM_TAG_RESOURCE); crm_xml_add(rsc, XML_ATTR_ID, rsc_id); name = XML_ATTR_TYPE; value = crm_element_value(action_rsc, name); crm_xml_add(rsc, name, value); name = XML_AGENT_ATTR_CLASS; value = crm_element_value(action_rsc, name); crm_xml_add(rsc, name, value); name = XML_AGENT_ATTR_PROVIDER; value = crm_element_value(action_rsc, name); crm_xml_add(rsc, name, value); op = convert_graph_action(NULL, action, status, op_rc); op->call_id = -1; op->user_data = generate_transition_key(transition_graph->id, action->id, target_rc, te_uuid); xml_op = create_operation_update(rsc, op, CRM_FEATURE_SET, target_rc, __FUNCTION__, LOG_INFO); lrmd_free_event(op); crm_trace("Updating CIB with \"%s\" (%s): %s %s on %s", status < 0 ? "new action" : XML_ATTR_TIMEOUT, crm_element_name(action->xml), crm_str(task), rsc_id, target); crm_log_xml_trace(xml_op, "Op"); rc = fsa_cib_conn->cmds->update(fsa_cib_conn, XML_CIB_TAG_STATUS, state, call_options); crm_trace("Updating CIB with %s action %d: %s on %s (call_id=%d)", services_lrm_status_str(status), action->id, task_uuid, target, rc); fsa_register_cib_callback(rc, FALSE, NULL, cib_action_updated); free_xml(state); action->sent_update = TRUE; if (rc < pcmk_ok) { return FALSE; } return TRUE; } static gboolean te_rsc_command(crm_graph_t * graph, crm_action_t * action) { /* never overwrite stop actions in the CIB with * anything other than completed results * * Writing pending stops makes it look like the * resource is running again */ xmlNode *cmd = NULL; xmlNode *rsc_op = NULL; gboolean rc = TRUE; gboolean no_wait = FALSE; gboolean is_local = FALSE; char *counter = NULL; const char *task = NULL; const char *value = NULL; const char *on_node = NULL; const char *router_node = NULL; const char *task_uuid = NULL; CRM_ASSERT(action != NULL); CRM_ASSERT(action->xml != NULL); action->executed = FALSE; on_node = crm_element_value(action->xml, XML_LRM_ATTR_TARGET); CRM_CHECK(on_node != NULL && strlen(on_node) != 0, crm_err("Corrupted command(id=%s) %s: no node", ID(action->xml), crm_str(task)); return FALSE); rsc_op = action->xml; task = crm_element_value(rsc_op, XML_LRM_ATTR_TASK); task_uuid = crm_element_value(action->xml, XML_LRM_ATTR_TASK_KEY); router_node = crm_element_value(rsc_op, XML_LRM_ATTR_ROUTER_NODE); if (!router_node) { router_node = on_node; } counter = generate_transition_key(transition_graph->id, action->id, get_target_rc(action), te_uuid); crm_xml_add(rsc_op, XML_ATTR_TRANSITION_KEY, counter); if (safe_str_eq(router_node, fsa_our_uname)) { is_local = TRUE; } value = crm_meta_value(action->params, XML_ATTR_TE_NOWAIT); if (crm_is_true(value)) { no_wait = TRUE; } crm_notice("Initiating action %d: %s %s on %s%s%s", action->id, task, task_uuid, on_node, is_local ? " (local)" : "", no_wait ? " - no waiting" : ""); cmd = create_request(CRM_OP_INVOKE_LRM, rsc_op, router_node, CRM_SYSTEM_LRMD, CRM_SYSTEM_TENGINE, NULL); if (is_local) { /* shortcut local resource commands */ ha_msg_input_t data = { .msg = cmd, .xml = rsc_op, }; fsa_data_t msg = { .id = 0, .data = &data, .data_type = fsa_dt_ha_msg, .fsa_input = I_NULL, .fsa_cause = C_FSA_INTERNAL, .actions = A_LRM_INVOKE, .origin = __FUNCTION__, }; do_lrm_invoke(A_LRM_INVOKE, C_FSA_INTERNAL, fsa_state, I_NULL, &msg); } else { rc = send_cluster_message(crm_get_peer(0, router_node), crm_msg_lrmd, cmd, TRUE); } free(counter); free_xml(cmd); action->executed = TRUE; if (rc == FALSE) { crm_err("Action %d failed: send", action->id); return FALSE; } else if (no_wait) { crm_info("Action %d confirmed - no wait", action->id); action->confirmed = TRUE; update_graph(transition_graph, action); trigger_graph(); } else { if (action->timeout <= 0) { crm_err("Action %d: %s %s on %s had an invalid timeout (%dms). Using %dms instead", action->id, task, task_uuid, on_node, action->timeout, graph->network_delay); action->timeout = graph->network_delay; } te_start_action_timer(graph, action); } value = crm_meta_value(action->params, XML_OP_ATTR_PENDING); if (crm_is_true(value) && safe_str_neq(task, CRMD_ACTION_CANCEL) && safe_str_neq(task, CRMD_ACTION_DELETE)) { /* write a "pending" entry to the CIB, inhibit notification */ crm_debug("Recording pending op %s in the CIB", task_uuid); cib_action_update(action, PCMK_LRM_OP_PENDING, PCMK_EXECRA_STATUS_UNKNOWN); } return TRUE; } crm_graph_functions_t te_graph_fns = { te_pseudo_action, te_rsc_command, te_crm_command, te_fence_node }; void notify_crmd(crm_graph_t * graph) { const char *type = "unknown"; enum crmd_fsa_input event = I_NULL; crm_debug("Processing transition completion in state %s", fsa_state2string(fsa_state)); CRM_CHECK(graph->complete, graph->complete = TRUE); switch (graph->completion_action) { case tg_stop: type = "stop"; /* fall through */ case tg_done: type = "done"; if (fsa_state == S_TRANSITION_ENGINE) { event = I_TE_SUCCESS; } break; case tg_restart: type = "restart"; if (fsa_state == S_TRANSITION_ENGINE) { if (too_many_st_failures() == FALSE) { if (transition_timer->period_ms > 0) { crm_timer_stop(transition_timer); crm_timer_start(transition_timer); } else { event = I_PE_CALC; } } else { event = I_TE_SUCCESS; } } else if (fsa_state == S_POLICY_ENGINE) { register_fsa_action(A_PE_INVOKE); } break; case tg_shutdown: type = "shutdown"; if (is_set(fsa_input_register, R_SHUTDOWN)) { event = I_STOP; } else { crm_err("We didn't ask to be shut down, yet our" " PE is telling us too."); event = I_TERMINATE; } } crm_debug("Transition %d status: %s - %s", graph->id, type, crm_str(graph->abort_reason)); graph->abort_reason = NULL; graph->completion_action = tg_done; clear_bit(fsa_input_register, R_IN_TRANSITION); if (event != I_NULL) { register_fsa_input(C_FSA_INTERNAL, event, NULL); } else if (fsa_source) { mainloop_set_trigger(fsa_source); } } pacemaker-master/crmd/te_callbacks.c000066400000000000000000000422241217637305600200150ustar00rootroot00000000000000/* * Copyright (C) 2004 Andrew Beekhof * * 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 2 of the License, or (at your option) any later version. * * This software 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 library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include #include #include #include #include #include #include #include /* For ONLINESTATUS etc */ void te_update_confirm(const char *event, xmlNode * msg); extern char *te_uuid; gboolean shuttingdown = FALSE; crm_graph_t *transition_graph; crm_trigger_t *transition_trigger = NULL; /* #define rsc_op_template "//"XML_TAG_DIFF_ADDED"//"XML_TAG_CIB"//"XML_CIB_TAG_STATE"[@uname='%s']"//"XML_LRM_TAG_RSC_OP"[@id='%s]" */ #define rsc_op_template "//"XML_TAG_DIFF_ADDED"//"XML_TAG_CIB"//"XML_LRM_TAG_RSC_OP"[@id='%s']" static const char * get_node_id(xmlNode * rsc_op) { xmlNode *node = rsc_op; while (node != NULL && safe_str_neq(XML_CIB_TAG_STATE, TYPE(node))) { node = node->parent; } CRM_CHECK(node != NULL, return NULL); return ID(node); } static void process_resource_updates(xmlXPathObject * xpathObj) { /* */ int lpc = 0, max = numXpathResults(xpathObj); for (lpc = 0; lpc < max; lpc++) { xmlNode *rsc_op = getXpathResult(xpathObj, lpc); const char *node = get_node_id(rsc_op); process_graph_event(rsc_op, node); } } void te_update_diff(const char *event, xmlNode * msg) { int lpc, max; int rc = -1; const char *op = NULL; xmlNode *diff = NULL; xmlXPathObject *xpathObj = NULL; int diff_add_updates = 0; int diff_add_epoch = 0; int diff_add_admin_epoch = 0; int diff_del_updates = 0; int diff_del_epoch = 0; int diff_del_admin_epoch = 0; CRM_CHECK(msg != NULL, return); crm_element_value_int(msg, F_CIB_RC, &rc); if (transition_graph == NULL) { crm_trace("No graph"); return; } else if (rc < pcmk_ok) { crm_trace("Filter rc=%d (%s)", rc, pcmk_strerror(rc)); return; } else if (transition_graph->complete == TRUE && fsa_state != S_IDLE && fsa_state != S_TRANSITION_ENGINE && fsa_state != S_POLICY_ENGINE) { crm_trace("Filter state=%s, complete=%d", fsa_state2string(fsa_state), transition_graph->complete); return; } op = crm_element_value(msg, F_CIB_OPERATION); diff = get_message_xml(msg, F_CIB_UPDATE_RESULT); cib_diff_version_details(diff, &diff_add_admin_epoch, &diff_add_epoch, &diff_add_updates, &diff_del_admin_epoch, &diff_del_epoch, &diff_del_updates); crm_debug("Processing diff (%s): %d.%d.%d -> %d.%d.%d (%s)", op, diff_del_admin_epoch, diff_del_epoch, diff_del_updates, diff_add_admin_epoch, diff_add_epoch, diff_add_updates, fsa_state2string(fsa_state)); log_cib_diff(LOG_DEBUG_2, diff, __FUNCTION__); if (cib_config_changed(NULL, NULL, &diff)) { abort_transition(INFINITY, tg_restart, "Non-status change", diff); goto bail; /* configuration changed */ } /* Tickets Attributes - Added/Updated */ xpathObj = xpath_search(diff, "//" F_CIB_UPDATE_RESULT "//" XML_TAG_DIFF_ADDED "//" XML_CIB_TAG_TICKETS); if (numXpathResults(xpathObj) > 0) { xmlNode *aborted = getXpathResult(xpathObj, 0); abort_transition(INFINITY, tg_restart, "Ticket attribute: update", aborted); goto bail; } freeXpathObject(xpathObj); /* Tickets Attributes - Removed */ xpathObj = xpath_search(diff, "//" F_CIB_UPDATE_RESULT "//" XML_TAG_DIFF_REMOVED "//" XML_CIB_TAG_TICKETS); if (numXpathResults(xpathObj) > 0) { xmlNode *aborted = getXpathResult(xpathObj, 0); abort_transition(INFINITY, tg_restart, "Ticket attribute: removal", aborted); goto bail; } freeXpathObject(xpathObj); /* Transient Attributes - Added/Updated */ xpathObj = xpath_search(diff, "//" F_CIB_UPDATE_RESULT "//" XML_TAG_DIFF_ADDED "//" XML_TAG_TRANSIENT_NODEATTRS "//" XML_CIB_TAG_NVPAIR); max = numXpathResults(xpathObj); for (lpc = 0; lpc < max; lpc++) { xmlNode *attr = getXpathResult(xpathObj, lpc); const char *name = crm_element_value(attr, XML_NVPAIR_ATTR_NAME); const char *value = NULL; if (safe_str_eq(CRM_OP_PROBED, name)) { value = crm_element_value(attr, XML_NVPAIR_ATTR_VALUE); } if (crm_is_true(value) == FALSE) { abort_transition(INFINITY, tg_restart, "Transient attribute: update", attr); crm_log_xml_trace(attr, "Abort"); goto bail; } } freeXpathObject(xpathObj); /* Transient Attributes - Removed */ xpathObj = xpath_search(diff, "//" F_CIB_UPDATE_RESULT "//" XML_TAG_DIFF_REMOVED "//" XML_TAG_TRANSIENT_NODEATTRS); if (numXpathResults(xpathObj) > 0) { xmlNode *aborted = getXpathResult(xpathObj, 0); abort_transition(INFINITY, tg_restart, "Transient attribute: removal", aborted); goto bail; } freeXpathObject(xpathObj); /* * Check for and fast-track the processing of LRM refreshes * In large clusters this can result in _huge_ speedups * * Unfortunately we can only do so when there are no pending actions * Otherwise we could miss updates we're waiting for and stall * */ xpathObj = NULL; if (transition_graph->pending == 0) { xpathObj = xpath_search(diff, "//" F_CIB_UPDATE_RESULT "//" XML_TAG_DIFF_ADDED "//" XML_LRM_TAG_RESOURCE); } max = numXpathResults(xpathObj); if (max > 1) { /* Updates by, or in response to, TE actions will never contain updates * for more than one resource at a time */ crm_debug("Detected LRM refresh - %d resources updated: Skipping all resource events", max); crm_log_xml_trace(diff, "lrm-refresh"); abort_transition(INFINITY, tg_restart, "LRM Refresh", NULL); goto bail; } freeXpathObject(xpathObj); /* Process operation updates */ xpathObj = xpath_search(diff, "//" F_CIB_UPDATE_RESULT "//" XML_TAG_DIFF_ADDED "//" XML_LRM_TAG_RSC_OP); if (numXpathResults(xpathObj)) { process_resource_updates(xpathObj); } freeXpathObject(xpathObj); /* Detect deleted (as opposed to replaced or added) actions - eg. crm_resource -C */ xpathObj = xpath_search(diff, "//" XML_TAG_DIFF_REMOVED "//" XML_LRM_TAG_RSC_OP); max = numXpathResults(xpathObj); for (lpc = 0; lpc < max; lpc++) { int path_max = 0; const char *op_id = NULL; char *rsc_op_xpath = NULL; xmlXPathObject *op_match = NULL; xmlNode *match = getXpathResult(xpathObj, lpc); CRM_CHECK(match != NULL, continue); op_id = ID(match); path_max = strlen(rsc_op_template) + strlen(op_id) + 1; rsc_op_xpath = calloc(1, path_max); snprintf(rsc_op_xpath, path_max, rsc_op_template, op_id); op_match = xpath_search(diff, rsc_op_xpath); if (numXpathResults(op_match) == 0) { /* Prevent false positives by matching cancelations too */ const char *node = get_node_id(match); crm_action_t *cancelled = get_cancel_action(op_id, node); if (cancelled == NULL) { crm_debug("No match for deleted action %s (%s on %s)", rsc_op_xpath, op_id, node); abort_transition(INFINITY, tg_restart, "Resource op removal", match); freeXpathObject(op_match); free(rsc_op_xpath); goto bail; } else { crm_debug("Deleted lrm_rsc_op %s on %s was for graph event %d", op_id, node, cancelled->id); } } freeXpathObject(op_match); free(rsc_op_xpath); } bail: freeXpathObject(xpathObj); } gboolean process_te_message(xmlNode * msg, xmlNode * xml_data) { const char *from = crm_element_value(msg, F_ORIG); const char *sys_to = crm_element_value(msg, F_CRM_SYS_TO); const char *sys_from = crm_element_value(msg, F_CRM_SYS_FROM); const char *ref = crm_element_value(msg, F_CRM_REFERENCE); const char *op = crm_element_value(msg, F_CRM_TASK); const char *type = crm_element_value(msg, F_CRM_MSG_TYPE); crm_trace("Processing %s (%s) message", op, ref); crm_log_xml_trace(msg, "ipc"); if (op == NULL) { /* error */ } else if (sys_to == NULL || strcasecmp(sys_to, CRM_SYSTEM_TENGINE) != 0) { crm_trace("Bad sys-to %s", crm_str(sys_to)); return FALSE; } else if (safe_str_eq(op, CRM_OP_INVOKE_LRM) && safe_str_eq(sys_from, CRM_SYSTEM_LRMD) /* && safe_str_eq(type, XML_ATTR_RESPONSE) */ ) { xmlXPathObject *xpathObj = NULL; crm_log_xml_trace(msg, "Processing (N)ACK"); crm_debug("Processing (N)ACK %s from %s", crm_element_value(msg, F_CRM_REFERENCE), from); xpathObj = xpath_search(xml_data, "//" XML_LRM_TAG_RSC_OP); if (numXpathResults(xpathObj)) { process_resource_updates(xpathObj); freeXpathObject(xpathObj); } else { crm_log_xml_err(msg, "Invalid (N)ACK"); freeXpathObject(xpathObj); return FALSE; } } else { crm_err("Unknown command: %s::%s from %s", type, op, sys_from); } crm_trace("finished processing message"); return TRUE; } GHashTable *stonith_failures = NULL; struct st_fail_rec { int count; int last_rc; }; gboolean too_many_st_failures(void) { GHashTableIter iter; const char *key = NULL; struct st_fail_rec *value = NULL; if (stonith_failures == NULL) { return FALSE; } g_hash_table_iter_init(&iter, stonith_failures); while (g_hash_table_iter_next(&iter, (gpointer *) & key, (gpointer *) & value)) { if (value->count > 10) { crm_notice("Too many failures to fence %s (%d), giving up", key, value->count); return TRUE; } else if (value->last_rc == -ENODEV) { crm_notice("No devices found in cluster to fence %s, giving up", key); return TRUE; } } return FALSE; } void st_fail_count_reset(const char *target) { struct st_fail_rec *rec = NULL; if (stonith_failures) { rec = g_hash_table_lookup(stonith_failures, target); } if (rec) { rec->count = 0; rec->last_rc = 0; } } static void st_fail_count_increment(const char *target, int rc) { struct st_fail_rec *rec = NULL; if (stonith_failures == NULL) { stonith_failures = g_hash_table_new_full(crm_str_hash, g_str_equal, g_hash_destroy_str, free); } rec = g_hash_table_lookup(stonith_failures, target); if (rec) { rec->count++; } else { rec = malloc(sizeof(struct st_fail_rec)); if(rec == NULL) { return; } rec->count = 1; g_hash_table_insert(stonith_failures, strdup(target), rec); } rec->last_rc = rc; } void tengine_stonith_callback(stonith_t * stonith, stonith_callback_data_t * data) { char *uuid = NULL; int target_rc = -1; int stonith_id = -1; int transition_id = -1; crm_action_t *action = NULL; int call_id = data->call_id; int rc = data->rc; char *userdata = data->userdata; CRM_CHECK(userdata != NULL, return); crm_notice("Stonith operation %d/%s: %s (%d)", call_id, (char *)userdata, pcmk_strerror(rc), rc); if (AM_I_DC == FALSE) { return; } /* crm_info("call=%d, optype=%d, node_name=%s, result=%d, node_list=%s, action=%s", */ /* op->call_id, op->optype, op->node_name, op->op_result, */ /* (char *)op->node_list, op->private_data); */ /* filter out old STONITH actions */ CRM_CHECK(decode_transition_key(userdata, &uuid, &transition_id, &stonith_id, &target_rc), crm_err("Invalid event detected"); goto bail; ); if (transition_graph->complete || stonith_id < 0 || safe_str_neq(uuid, te_uuid) || transition_graph->id != transition_id) { crm_info("Ignoring STONITH action initiated outside of the current transition"); goto bail; } /* this will mark the event complete if a match is found */ action = get_action(stonith_id, FALSE); if (action == NULL) { crm_err("Stonith action not matched"); goto bail; } stop_te_timer(action->timer); if (rc == pcmk_ok) { const char *target = crm_element_value(action->xml, XML_LRM_ATTR_TARGET); const char *uuid = crm_element_value(action->xml, XML_LRM_ATTR_TARGET_UUID); crm_debug("Stonith operation %d for %s passed", call_id, target); if (action->confirmed == FALSE) { action->confirmed = TRUE; if (action->sent_update == FALSE) { send_stonith_update(action, target, uuid); } } st_fail_count_reset(target); } else { const char *target = crm_element_value_const(action->xml, XML_LRM_ATTR_TARGET); const char *allow_fail = crm_meta_value(action->params, XML_ATTR_TE_ALLOWFAIL); action->failed = TRUE; if (crm_is_true(allow_fail) == FALSE) { crm_notice("Stonith operation %d for %s failed (%s): aborting transition.", call_id, target, pcmk_strerror(rc)); abort_transition(INFINITY, tg_restart, "Stonith failed", NULL); } st_fail_count_increment(target, rc); } update_graph(transition_graph, action); trigger_graph(); bail: free(userdata); free(uuid); return; } void cib_fencing_updated(xmlNode * msg, int call_id, int rc, xmlNode * output, void *user_data) { if (rc < pcmk_ok) { crm_err("Fencing update %d for %s: failed - %s (%d)", call_id, (char *)user_data, pcmk_strerror(rc), rc); crm_log_xml_warn(msg, "Failed update"); abort_transition(INFINITY, tg_shutdown, "CIB update failed", NULL); } else { crm_info("Fencing update %d for %s: complete", call_id, (char *)user_data); } free(user_data); } void cib_action_updated(xmlNode * msg, int call_id, int rc, xmlNode * output, void *user_data) { if (rc < pcmk_ok) { crm_err("Update %d FAILED: %s", call_id, pcmk_strerror(rc)); } } gboolean action_timer_callback(gpointer data) { crm_action_timer_t *timer = NULL; CRM_CHECK(data != NULL, return FALSE); timer = (crm_action_timer_t *) data; stop_te_timer(timer); crm_warn("Timer popped (timeout=%d, abort_level=%d, complete=%s)", timer->timeout, transition_graph->abort_priority, transition_graph->complete ? "true" : "false"); CRM_CHECK(timer->action != NULL, return FALSE); if (transition_graph->complete) { crm_warn("Ignoring timeout while not in transition"); } else if (timer->reason == timeout_action_warn) { print_action(LOG_WARNING, "Action missed its timeout: ", timer->action); /* Don't check the FSA state * * We might also be in S_INTEGRATION or some other state waiting for this * action so we can close the transition and continue */ } else { /* fail the action */ gboolean send_update = TRUE; const char *task = crm_element_value(timer->action->xml, XML_LRM_ATTR_TASK); print_action(LOG_ERR, "Aborting transition, action lost: ", timer->action); timer->action->failed = TRUE; timer->action->confirmed = TRUE; abort_transition(INFINITY, tg_restart, "Action lost", NULL); update_graph(transition_graph, timer->action); trigger_graph(); if (timer->action->type != action_type_rsc) { send_update = FALSE; } else if (safe_str_eq(task, RSC_CANCEL)) { /* we dont need to update the CIB with these */ send_update = FALSE; } if (send_update) { /* cib_action_update(timer->action, PCMK_LRM_OP_PENDING, PCMK_EXECRA_STATUS_UNKNOWN); */ cib_action_update(timer->action, PCMK_LRM_OP_TIMEOUT, PCMK_EXECRA_UNKNOWN_ERROR); } } return FALSE; } pacemaker-master/crmd/te_callbacks.h000066400000000000000000000026341217637305600200230ustar00rootroot00000000000000/* * Copyright (C) 2004 Andrew Beekhof * * 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 2 of the License, or (at your option) any later version. * * This software 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 library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef TE_CALLBACKS__H # define TE_CALLBACKS__H extern void cib_fencing_updated(xmlNode * msg, int call_id, int rc, xmlNode * output, void *user_data); extern void cib_action_updated(xmlNode * msg, int call_id, int rc, xmlNode * output, void *user_data); extern gboolean global_timer_callback(gpointer data); extern gboolean action_timer_callback(gpointer data); extern gboolean te_graph_trigger(gpointer user_data); extern void te_update_diff(const char *event, xmlNode * msg); extern void tengine_stonith_callback(stonith_t * stonith, stonith_callback_data_t * data); #endif pacemaker-master/crmd/te_events.c000066400000000000000000000404021217637305600173760ustar00rootroot00000000000000/* * Copyright (C) 2004 Andrew Beekhof * * 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 2 of the License, or (at your option) any later version. * * This software 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 library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include #include #include #include #include #include #include char *failed_stop_offset = NULL; char *failed_start_offset = NULL; int match_graph_event(int action_id, xmlNode * event, const char *event_node, int op_status, int op_rc, int target_rc); gboolean fail_incompletable_actions(crm_graph_t * graph, const char *down_node) { const char *target = NULL; xmlNode *last_action = NULL; GListPtr gIter = NULL; GListPtr gIter2 = NULL; if (graph == NULL || graph->complete) { return FALSE; } gIter = graph->synapses; for (; gIter != NULL; gIter = gIter->next) { synapse_t *synapse = (synapse_t *) gIter->data; if (synapse->confirmed) { continue; } gIter2 = synapse->actions; for (; gIter2 != NULL; gIter2 = gIter2->next) { crm_action_t *action = (crm_action_t *) gIter2->data; if (action->type == action_type_pseudo || action->confirmed) { continue; } else if (action->type == action_type_crm) { const char *task = crm_element_value(action->xml, XML_LRM_ATTR_TASK); if (safe_str_eq(task, CRM_OP_FENCE)) { continue; } } target = crm_element_value(action->xml, XML_LRM_ATTR_TARGET_UUID); if (safe_str_eq(target, down_node)) { action->failed = TRUE; synapse->failed = TRUE; last_action = action->xml; stop_te_timer(action->timer); update_graph(graph, action); if (synapse->executed) { crm_notice("Action %d (%s) was pending on %s (offline)", action->id, ID(action->xml), down_node); } else { crm_notice("Action %d (%s) is scheduled for %s (offline)", action->id, ID(action->xml), down_node); } } } } if (last_action != NULL) { crm_warn("Node %s shutdown resulted in un-runnable actions", down_node); abort_transition(INFINITY, tg_restart, "Node failure", last_action); return TRUE; } return FALSE; } static const char * get_uname_from_event(xmlNode * event) { xmlNode *node = event; while (node != NULL && safe_str_neq(XML_CIB_TAG_STATE, TYPE(node))) { node = node->parent; } CRM_CHECK(node != NULL, return NULL); return crm_element_value(node, XML_ATTR_UNAME); } static gboolean get_is_remote_from_event(xmlNode * event) { xmlNode *node = event; while (node != NULL && safe_str_neq(XML_CIB_TAG_STATE, TYPE(node))) { node = node->parent; } CRM_CHECK(node != NULL, return FALSE); return crm_element_value(node, XML_NODE_IS_REMOTE) ? TRUE : FALSE; } static gboolean update_failcount(xmlNode * event, const char *event_node_uuid, int rc, int target_rc, gboolean do_update) { int interval = 0; char *task = NULL; char *rsc_id = NULL; char *attr_name = NULL; const char *value = NULL; const char *id = crm_element_value(event, XML_LRM_ATTR_TASK_KEY); const char *on_uname = get_uname_from_event(event); const char *origin = crm_element_value(event, XML_ATTR_ORIGIN); if (rc == 99) { /* this is an internal code for "we're busy, try again" */ return FALSE; } else if (rc == target_rc) { return FALSE; } if (safe_str_eq(origin, "build_active_RAs")) { crm_debug("No update for %s (rc=%d) on %s: Old failure from lrm status refresh", id, rc, on_uname); return FALSE; } CRM_LOG_ASSERT(on_uname != NULL); if (on_uname == NULL) { return TRUE; } if (failed_stop_offset == NULL) { failed_stop_offset = strdup(INFINITY_S); } if (failed_start_offset == NULL) { failed_start_offset = strdup(INFINITY_S); } CRM_CHECK(parse_op_key(id, &rsc_id, &task, &interval), crm_err("Couldn't parse: %s", ID(event)); goto bail); CRM_CHECK(task != NULL, goto bail); CRM_CHECK(rsc_id != NULL, goto bail); if (do_update || interval > 0) { do_update = TRUE; } else if (safe_str_eq(task, CRMD_ACTION_START)) { do_update = TRUE; value = failed_start_offset; } else if (safe_str_eq(task, CRMD_ACTION_STOP)) { do_update = TRUE; value = failed_stop_offset; } else if (safe_str_eq(task, CRMD_ACTION_STOP)) { do_update = TRUE; value = failed_stop_offset; } else if (safe_str_eq(task, CRMD_ACTION_PROMOTE)) { do_update = TRUE; } else if (safe_str_eq(task, CRMD_ACTION_DEMOTE)) { do_update = TRUE; } if (value == NULL || safe_str_neq(value, INFINITY_S)) { value = XML_NVPAIR_ATTR_VALUE "++"; } if (do_update) { char *now = crm_itoa(time(NULL)); gboolean is_remote_node = get_is_remote_from_event(event); crm_warn("Updating failcount for %s on %s after failed %s:" " rc=%d (update=%s, time=%s)", rsc_id, on_uname, task, rc, value, now); attr_name = crm_concat("fail-count", rsc_id, '-'); update_attrd(on_uname, attr_name, value, NULL, is_remote_node); free(attr_name); attr_name = crm_concat("last-failure", rsc_id, '-'); update_attrd(on_uname, attr_name, now, NULL, is_remote_node); free(attr_name); free(now); } bail: free(rsc_id); free(task); return TRUE; } static int status_from_rc(crm_action_t * action, int orig_status, int rc, int target_rc) { int status = orig_status; if (target_rc == rc) { crm_trace("Target rc: == %d", rc); if (status != PCMK_LRM_OP_DONE) { crm_trace("Re-mapping op status to" " PCMK_LRM_OP_DONE for rc=%d", rc); status = PCMK_LRM_OP_DONE; } } else { status = PCMK_LRM_OP_ERROR; } /* 99 is the code we use for direct nack's */ if (rc != 99 && status != PCMK_LRM_OP_DONE) { const char *task, *uname; task = crm_element_value(action->xml, XML_LRM_ATTR_TASK_KEY); uname = crm_element_value(action->xml, XML_LRM_ATTR_TARGET); crm_warn("Action %d (%s) on %s failed (target: %d vs. rc: %d): %s", action->id, task, uname, target_rc, rc, services_lrm_status_str(status)); } return status; } /* * returns the ID of the action if a match is found * returns -1 if a match was not found * returns -2 if a match was found but the action failed (and was * not allowed to) */ int match_graph_event(int action_id, xmlNode * event, const char *event_node, int op_status, int op_rc, int target_rc) { const char *target = NULL; const char *allow_fail = NULL; const char *this_event = NULL; crm_action_t *action = NULL; action = get_action(action_id, FALSE); if (action == NULL) { return -1; } op_status = status_from_rc(action, op_status, op_rc, target_rc); if (op_status != PCMK_LRM_OP_DONE) { update_failcount(event, event_node, op_rc, target_rc, FALSE); } /* Process OP status */ switch (op_status) { case PCMK_LRM_OP_PENDING: crm_debug("Ignoring pending operation"); return action->id; break; case PCMK_LRM_OP_DONE: break; case PCMK_LRM_OP_ERROR: case PCMK_LRM_OP_TIMEOUT: case PCMK_LRM_OP_NOTSUPPORTED: action->failed = TRUE; break; case PCMK_LRM_OP_CANCELLED: /* do nothing?? */ crm_err("Dont know what to do for cancelled ops yet"); break; default: action->failed = TRUE; crm_err("Unsupported action result: %d", op_status); } /* stop this event's timer if it had one */ stop_te_timer(action->timer); action->confirmed = TRUE; update_graph(transition_graph, action); trigger_graph(); if (action->failed) { allow_fail = crm_meta_value(action->params, XML_ATTR_TE_ALLOWFAIL); if (crm_is_true(allow_fail)) { action->failed = FALSE; } } if (action->failed) { abort_transition(action->synapse->priority + 1, tg_restart, "Event failed", event); } this_event = crm_element_value(event, XML_LRM_ATTR_TASK_KEY); target = crm_element_value(action->xml, XML_LRM_ATTR_TARGET); crm_info("Action %s (%d) confirmed on %s (rc=%d)", crm_str(this_event), action->id, crm_str(target), op_status); return action->id; } crm_action_t * get_action(int id, gboolean confirmed) { GListPtr gIter = NULL; GListPtr gIter2 = NULL; gIter = transition_graph->synapses; for (; gIter != NULL; gIter = gIter->next) { synapse_t *synapse = (synapse_t *) gIter->data; gIter2 = synapse->actions; for (; gIter2 != NULL; gIter2 = gIter2->next) { crm_action_t *action = (crm_action_t *) gIter2->data; if (action->id == id) { if (confirmed) { stop_te_timer(action->timer); action->confirmed = TRUE; } return action; } } } return NULL; } crm_action_t * get_cancel_action(const char *id, const char *node) { const char *task = NULL; const char *target = NULL; GListPtr gIter = NULL; GListPtr gIter2 = NULL; gIter = transition_graph->synapses; for (; gIter != NULL; gIter = gIter->next) { synapse_t *synapse = (synapse_t *) gIter->data; gIter2 = synapse->actions; for (; gIter2 != NULL; gIter2 = gIter2->next) { crm_action_t *action = (crm_action_t *) gIter2->data; task = crm_element_value(action->xml, XML_LRM_ATTR_TASK); if (safe_str_neq(CRMD_ACTION_CANCEL, task)) { continue; } task = crm_element_value(action->xml, XML_LRM_ATTR_TASK_KEY); if (safe_str_neq(task, id)) { continue; } target = crm_element_value(action->xml, XML_LRM_ATTR_TARGET_UUID); if (safe_str_neq(target, node)) { continue; } return action; } } return NULL; } crm_action_t * match_down_event(int id, const char *target, const char *filter, bool quiet) { const char *this_action = NULL; const char *this_node = NULL; crm_action_t *match = NULL; GListPtr gIter = NULL; GListPtr gIter2 = NULL; gIter = transition_graph->synapses; for (; gIter != NULL; gIter = gIter->next) { synapse_t *synapse = (synapse_t *) gIter->data; /* lookup event */ gIter2 = synapse->actions; for (; gIter2 != NULL; gIter2 = gIter2->next) { crm_action_t *action = (crm_action_t *) gIter2->data; if (id > 0 && action->id == id) { match = action; break; } this_action = crm_element_value(action->xml, XML_LRM_ATTR_TASK); if (action->type != action_type_crm) { continue; } else if (safe_str_eq(this_action, CRM_OP_LRM_REFRESH)) { continue; } else if (filter != NULL && safe_str_neq(this_action, filter)) { continue; } this_node = crm_element_value(action->xml, XML_LRM_ATTR_TARGET_UUID); if (this_node == NULL) { crm_log_xml_err(action->xml, "No node uuid"); } if (safe_str_neq(this_node, target)) { crm_debug("Action %d : Node mismatch: %s", action->id, this_node); continue; } match = action; id = action->id; break; } if (match != NULL) { /* stop this event's timer if it had one */ break; } } if (match != NULL) { /* stop this event's timer if it had one */ crm_debug("Match found for action %d: %s on %s", id, crm_element_value(match->xml, XML_LRM_ATTR_TASK_KEY), target); } else if (id > 0) { crm_err("No match for action %d", id); } else if(quiet == FALSE) { crm_warn("No match for shutdown action on %s", target); } return match; } gboolean process_graph_event(xmlNode * event, const char *event_node) { int rc = -1; int status = -1; int callid = -1; int action = -1; int target_rc = -1; int transition_num = -1; char *update_te_uuid = NULL; gboolean stop_early = FALSE; gboolean passed = FALSE; const char *id = NULL; const char *desc = NULL; const char *magic = NULL; CRM_ASSERT(event != NULL); /* */ id = crm_element_value(event, XML_LRM_ATTR_TASK_KEY); crm_element_value_int(event, XML_LRM_ATTR_RC, &rc); crm_element_value_int(event, XML_LRM_ATTR_OPSTATUS, &status); crm_element_value_int(event, XML_LRM_ATTR_CALLID, &callid); magic = crm_element_value(event, XML_ATTR_TRANSITION_KEY); if (magic == NULL) { /* non-change */ return FALSE; } if (decode_transition_key(magic, &update_te_uuid, &transition_num, &action, &target_rc) == FALSE) { crm_err("Invalid event %s.%d detected: %s", id, callid, magic); abort_transition(INFINITY, tg_restart, "Bad event", event); return FALSE; } if (status == PCMK_LRM_OP_PENDING) { goto bail; } if (transition_num == -1) { desc = "initiated outside of the cluster"; abort_transition(INFINITY, tg_restart, "Unexpected event", event); } else if (action < 0 || crm_str_eq(update_te_uuid, te_uuid, TRUE) == FALSE) { desc = "initiated by a different node"; abort_transition(INFINITY, tg_restart, "Foreign event", event); stop_early = TRUE; /* This could be an lrm status refresh */ } else if (transition_graph->id != transition_num) { desc = "arrived really late"; abort_transition(INFINITY, tg_restart, "Old event", event); stop_early = TRUE; /* This could be an lrm status refresh */ } else if (transition_graph->complete) { desc = "arrived late"; abort_transition(INFINITY, tg_restart, "Inactive graph", event); } else if (match_graph_event(action, event, event_node, status, rc, target_rc) < 0) { desc = "unknown"; abort_transition(INFINITY, tg_restart, "Unknown event", event); } else if (rc == target_rc) { passed = TRUE; crm_trace("Processed update to %s: %s", id, magic); } if (passed == FALSE) { if (update_failcount(event, event_node, rc, target_rc, transition_num == -1)) { /* Turns out this wasn't an lrm status refresh update aferall */ stop_early = FALSE; desc = "failed"; } crm_info("Detected action (%d.%d) %s.%d=%s: %s", transition_num, action, id, callid, lrmd_event_rc2str(rc), desc); } bail: free(update_te_uuid); return stop_early; } pacemaker-master/crmd/te_utils.c000066400000000000000000000362351217637305600172430ustar00rootroot00000000000000/* * Copyright (C) 2004 Andrew Beekhof * * 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 2 of the License, or (at your option) any later version. * * This software 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 library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include #include #include #include #include #include #include #include crm_trigger_t *stonith_reconnect = NULL; GListPtr stonith_cleanup_list = NULL; static gboolean fail_incompletable_stonith(crm_graph_t * graph) { GListPtr lpc = NULL; const char *task = NULL; xmlNode *last_action = NULL; if (graph == NULL) { return FALSE; } for (lpc = graph->synapses; lpc != NULL; lpc = lpc->next) { GListPtr lpc2 = NULL; synapse_t *synapse = (synapse_t *) lpc->data; if (synapse->confirmed) { continue; } for (lpc2 = synapse->actions; lpc2 != NULL; lpc2 = lpc2->next) { crm_action_t *action = (crm_action_t *) lpc2->data; if (action->type != action_type_crm || action->confirmed) { continue; } task = crm_element_value(action->xml, XML_LRM_ATTR_TASK); if (task && safe_str_eq(task, CRM_OP_FENCE)) { action->failed = TRUE; last_action = action->xml; update_graph(graph, action); crm_notice("Failing action %d (%s): STONITHd terminated", action->id, ID(action->xml)); } } } if (last_action != NULL) { crm_warn("STONITHd failure resulted in un-runnable actions"); abort_transition(INFINITY, tg_restart, "Stonith failure", last_action); return TRUE; } return FALSE; } static void tengine_stonith_connection_destroy(stonith_t * st, stonith_event_t * e) { if (is_set(fsa_input_register, R_ST_REQUIRED)) { crm_crit("Fencing daemon connection failed"); mainloop_set_trigger(stonith_reconnect); } else { crm_info("Fencing daemon disconnected"); } /* cbchan will be garbage at this point, arrange for it to be reset */ if(stonith_api) { stonith_api->state = stonith_disconnected; } if (AM_I_DC) { fail_incompletable_stonith(transition_graph); trigger_graph(); } } #if SUPPORT_CMAN # include #endif char *te_client_id = NULL; #ifdef HAVE_SYS_REBOOT_H # include # include #endif static void tengine_stonith_notify(stonith_t * st, stonith_event_t * st_event) { if(te_client_id == NULL) { te_client_id = g_strdup_printf("%s.%d", crm_system_name, getpid()); } if (st_event == NULL) { crm_err("Notify data not found"); return; } if (st_event->result == pcmk_ok && crm_str_eq(st_event->target, fsa_our_uname, TRUE)) { crm_crit("We were alegedly just fenced by %s for %s with %s!", st_event->executioner, st_event->origin, st_event->device); /* Dumps blackbox if enabled */ qb_log_fini(); /* Try to get the above log message to disk - somehow */ /* Get out ASAP and do not come back up. * * Triggering a reboot is also not the worst idea either since * the rest of the cluster thinks we're safely down */ #ifdef RB_HALT_SYSTEM reboot(RB_HALT_SYSTEM); #endif /* * If reboot() fails or is not supported, coming back up will * probably lead to a situation where the other nodes set our * status to 'lost' because of the fencing callback and will * discard subsequent election votes with: * * Election 87 (current: 5171, owner: 103): Processed vote from east-03 (Peer is not part of our cluster) * * So just stay dead, something is seriously messed up anyway. * */ exit(100); /* None of our wrappers since we already called qb_log_fini() */ return; } if (st_event->result == pcmk_ok && safe_str_eq(st_event->operation, T_STONITH_NOTIFY_FENCE)) { st_fail_count_reset(st_event->target); } crm_notice("Peer %s was%s terminated (%s) by %s for %s: %s (ref=%s) by client %s", st_event->target, st_event->result == pcmk_ok ? "" : " not", st_event->action, st_event->executioner ? st_event->executioner : "", st_event->origin, pcmk_strerror(st_event->result), st_event->id, st_event->client_origin ? st_event->client_origin : ""); #if SUPPORT_CMAN if (st_event->result == pcmk_ok && is_cman_cluster()) { int local_rc = 0; char *target_copy = strdup(st_event->target); /* In case fenced hasn't noticed yet * * Any fencing that has been inititated will be completed by way of the fence_pcmk redirect */ local_rc = fenced_external(target_copy); if (local_rc != 0) { crm_err("Could not notify CMAN that '%s' is now fenced: %d", st_event->target, local_rc); } else { crm_notice("Notified CMAN that '%s' is now fenced", st_event->target); } free(target_copy); } #endif if (st_event->result == pcmk_ok) { crm_node_t *peer = crm_get_peer(0, st_event->target); const char *uuid = crm_peer_uuid(peer); gboolean we_are_executioner = safe_str_eq(st_event->executioner, fsa_our_uname); crm_trace("target=%s dc=%s", st_event->target, fsa_our_dc); if(AM_I_DC) { /* The DC always sends updates */ send_stonith_update(NULL, st_event->target, uuid); if (st_event->client_origin && safe_str_neq(st_event->client_origin, te_client_id)) { /* Abort the current transition graph if it wasn't us * that invoked stonith to fence someone */ crm_info("External fencing operation from %s fenced %s", st_event->client_origin, st_event->target); abort_transition(INFINITY, tg_restart, "External Fencing Operation", NULL); } /* Assume it was our leader if we dont currently have one */ } else if (fsa_our_dc == NULL || safe_str_eq(fsa_our_dc, st_event->target)) { crm_notice("Target %s our leader %s (recorded: %s)", fsa_our_dc ? "was" : "may have been", st_event->target, fsa_our_dc ? fsa_our_dc : ""); /* Given the CIB resyncing that occurs around elections, * have one node update the CIB now and, if the new DC is different, * have them do so too after the election */ if (we_are_executioner) { send_stonith_update(NULL, st_event->target, uuid); } stonith_cleanup_list = g_list_append(stonith_cleanup_list, strdup(st_event->target)); } /* Everyone records them as safely down */ crm_update_peer_proc(__FUNCTION__, peer, crm_proc_none, NULL); crm_update_peer_state(__FUNCTION__, peer, CRM_NODE_LOST, 0); crm_update_peer_expected(__FUNCTION__, peer, CRMD_JOINSTATE_DOWN); crm_update_peer_join(__FUNCTION__, peer, crm_join_none); } } gboolean te_connect_stonith(gpointer user_data) { int lpc = 0; int rc = pcmk_ok; if (stonith_api == NULL) { stonith_api = stonith_api_new(); } if (stonith_api->state != stonith_disconnected) { crm_trace("Still connected"); return TRUE; } for (lpc = 0; lpc < 30; lpc++) { crm_debug("Attempting connection to fencing daemon..."); sleep(1); rc = stonith_api->cmds->connect(stonith_api, crm_system_name, NULL); if (rc == pcmk_ok) { break; } if (user_data != NULL) { crm_err("Sign-in failed: triggered a retry"); mainloop_set_trigger(stonith_reconnect); return TRUE; } crm_err("Sign-in failed: pausing and trying again in 2s..."); sleep(1); } CRM_CHECK(rc == pcmk_ok, return TRUE); /* If not, we failed 30 times... just get out */ stonith_api->cmds->register_notification(stonith_api, T_STONITH_NOTIFY_DISCONNECT, tengine_stonith_connection_destroy); stonith_api->cmds->register_notification(stonith_api, T_STONITH_NOTIFY_FENCE, tengine_stonith_notify); crm_trace("Connected"); return TRUE; } gboolean stop_te_timer(crm_action_timer_t * timer) { const char *timer_desc = "action timer"; if (timer == NULL) { return FALSE; } if (timer->reason == timeout_abort) { timer_desc = "global timer"; crm_trace("Stopping %s", timer_desc); } if (timer->source_id != 0) { crm_trace("Stopping %s", timer_desc); g_source_remove(timer->source_id); timer->source_id = 0; } else { crm_trace("%s was already stopped", timer_desc); return FALSE; } return TRUE; } gboolean te_graph_trigger(gpointer user_data) { enum transition_status graph_rc = -1; if (transition_graph == NULL) { crm_debug("Nothing to do"); return TRUE; } crm_trace("Invoking graph %d in state %s", transition_graph->id, fsa_state2string(fsa_state)); switch (fsa_state) { case S_STARTING: case S_PENDING: case S_NOT_DC: case S_HALT: case S_ILLEGAL: case S_STOPPING: case S_TERMINATE: return TRUE; break; default: break; } if (transition_graph->complete == FALSE) { graph_rc = run_graph(transition_graph); print_graph(LOG_DEBUG_3, transition_graph); if (graph_rc == transition_active) { crm_trace("Transition not yet complete"); return TRUE; } else if (graph_rc == transition_pending) { crm_trace("Transition not yet complete - no actions fired"); return TRUE; } if (graph_rc != transition_complete) { crm_warn("Transition failed: %s", transition_status(graph_rc)); print_graph(LOG_NOTICE, transition_graph); } } crm_debug("Transition %d is now complete", transition_graph->id); transition_graph->complete = TRUE; notify_crmd(transition_graph); return TRUE; } void trigger_graph_processing(const char *fn, int line) { crm_trace("%s:%d - Triggered graph processing", fn, line); mainloop_set_trigger(transition_trigger); } void abort_transition_graph(int abort_priority, enum transition_action abort_action, const char *abort_text, xmlNode * reason, const char *fn, int line) { const char *magic = NULL; CRM_CHECK(transition_graph != NULL, return); if (reason) { int diff_add_updates = 0; int diff_add_epoch = 0; int diff_add_admin_epoch = 0; int diff_del_updates = 0; int diff_del_epoch = 0; int diff_del_admin_epoch = 0; const char *uname = ""; xmlNode *search = reason; xmlNode *diff = get_xpath_object("//" F_CIB_UPDATE_RESULT "//diff", reason, LOG_DEBUG_2); magic = crm_element_value(reason, XML_ATTR_TRANSITION_MAGIC); while(search) { const char *kind = TYPE(search); if (safe_str_eq(XML_CIB_TAG_STATE, kind) || safe_str_eq(XML_CIB_TAG_NODE, kind)) { if (crm_is_true(crm_element_value(search, XML_NODE_IS_REMOTE))) { /* Remote node uname and uuids are the same. * We also don't want them to be present in the * peer cache, so we shouldn't look them up with * crm_peer_uname() */ uname = ID(search); } else { uname = crm_peer_uname(ID(search)); } break; } search = search->parent; } if (diff) { cib_diff_version_details(diff, &diff_add_admin_epoch, &diff_add_epoch, &diff_add_updates, &diff_del_admin_epoch, &diff_del_epoch, &diff_del_updates); if (crm_str_eq(TYPE(reason), XML_CIB_TAG_NVPAIR, TRUE)) { crm_info ("%s:%d - Triggered transition abort (complete=%d, node=%s, tag=%s, id=%s, name=%s, value=%s, magic=%s, cib=%d.%d.%d) : %s", fn, line, transition_graph->complete, uname, TYPE(reason), ID(reason), NAME(reason), VALUE(reason), magic ? magic : "NA", diff_add_admin_epoch, diff_add_epoch, diff_add_updates, abort_text); } else { crm_info ("%s:%d - Triggered transition abort (complete=%d, node=%s, tag=%s, id=%s, magic=%s, cib=%d.%d.%d) : %s", fn, line, transition_graph->complete, uname, TYPE(reason), ID(reason), magic ? magic : "NA", diff_add_admin_epoch, diff_add_epoch, diff_add_updates, abort_text); } } else { crm_info ("%s:%d - Triggered transition abort (complete=%d, node=%s, tag=%s, id=%s, magic=%s) : %s", fn, line, transition_graph->complete, uname, TYPE(reason), ID(reason), magic ? magic : "NA", abort_text); } } else { crm_info("%s:%d - Triggered transition abort (complete=%d) : %s", fn, line, transition_graph->complete, abort_text); } switch (fsa_state) { case S_STARTING: case S_PENDING: case S_NOT_DC: case S_HALT: case S_ILLEGAL: case S_STOPPING: case S_TERMINATE: crm_info("Abort suppressed: state=%s (complete=%d)", fsa_state2string(fsa_state), transition_graph->complete); return; default: break; } if (magic == NULL && reason != NULL) { crm_log_xml_debug(reason, "Cause"); } /* Make sure any queued calculations are discarded ASAP */ free(fsa_pe_ref); fsa_pe_ref = NULL; if (transition_graph->complete) { if (transition_timer->period_ms > 0) { crm_timer_stop(transition_timer); crm_timer_start(transition_timer); } else { register_fsa_input(C_FSA_INTERNAL, I_PE_CALC, NULL); } return; } update_abort_priority(transition_graph, abort_priority, abort_action, abort_text); mainloop_set_trigger(transition_trigger); } pacemaker-master/crmd/tengine.c000066400000000000000000000166021217637305600170400ustar00rootroot00000000000000/* * Copyright (C) 2004 Andrew Beekhof * * 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 2 of the License, or (at your option) any later version. * * This software 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 library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include #include #include #include #include #include /* for access */ #include /* for calls to open */ #include /* for calls to open */ #include /* for calls to open */ #include /* for getpwuid */ #include /* for initgroups */ #include /* for getrlimit */ #include /* for getrlimit */ #include #include #include #include #include #include #include #include extern crm_graph_functions_t te_graph_fns; struct crm_subsystem_s *te_subsystem = NULL; stonith_t *stonith_api = NULL; static void global_cib_callback(const xmlNode * msg, int callid, int rc, xmlNode * output) { } static crm_graph_t * create_blank_graph(void) { crm_graph_t *a_graph = unpack_graph(NULL, NULL); a_graph->complete = TRUE; a_graph->abort_reason = "DC Takeover"; a_graph->completion_action = tg_restart; return a_graph; } /* A_TE_START, A_TE_STOP, A_TE_RESTART */ void do_te_control(long long action, enum crmd_fsa_cause cause, enum crmd_fsa_state cur_state, enum crmd_fsa_input current_input, fsa_data_t * msg_data) { gboolean init_ok = TRUE; if (action & A_TE_STOP) { if (transition_graph) { destroy_graph(transition_graph); transition_graph = NULL; } if (fsa_cib_conn) { fsa_cib_conn->cmds->del_notify_callback(fsa_cib_conn, T_CIB_DIFF_NOTIFY, te_update_diff); } clear_bit(fsa_input_register, te_subsystem->flag_connected); crm_info("Transitioner is now inactive"); } if ((action & A_TE_START) == 0) { return; } else if (is_set(fsa_input_register, te_subsystem->flag_connected)) { crm_debug("The transitioner is already active"); return; } else if ((action & A_TE_START) && cur_state == S_STOPPING) { crm_info("Ignoring request to start %s while shutting down", te_subsystem->name); return; } te_uuid = crm_generate_uuid(); crm_info("Registering TE UUID: %s", te_uuid); if (pcmk_ok != fsa_cib_conn->cmds->add_notify_callback(fsa_cib_conn, T_CIB_DIFF_NOTIFY, te_update_diff)) { crm_err("Could not set CIB notification callback"); init_ok = FALSE; } if (pcmk_ok != fsa_cib_conn->cmds->set_op_callback(fsa_cib_conn, global_cib_callback)) { crm_err("Could not set CIB global callback"); init_ok = FALSE; } if (init_ok) { set_graph_functions(&te_graph_fns); if (transition_graph) { destroy_graph(transition_graph); } /* create a blank one */ crm_debug("Transitioner is now active"); transition_graph = create_blank_graph(); set_bit(fsa_input_register, te_subsystem->flag_connected); } } /* A_TE_INVOKE, A_TE_CANCEL */ void do_te_invoke(long long action, enum crmd_fsa_cause cause, enum crmd_fsa_state cur_state, enum crmd_fsa_input current_input, fsa_data_t * msg_data) { if (AM_I_DC == FALSE || (fsa_state != S_TRANSITION_ENGINE && (action & A_TE_INVOKE))) { crm_notice("No need to invoke the TE (%s) in state %s", fsa_action2string(action), fsa_state2string(fsa_state)); return; } if (action & A_TE_CANCEL) { crm_debug("Cancelling the transition: %s", transition_graph->complete ? "inactive" : "active"); abort_transition(INFINITY, tg_restart, "Peer Cancelled", NULL); if (transition_graph->complete == FALSE) { crmd_fsa_stall(FALSE); } } else if (action & A_TE_HALT) { crm_debug("Halting the transition: %s", transition_graph->complete ? "inactive" : "active"); abort_transition(INFINITY, tg_stop, "Peer Halt", NULL); if (transition_graph->complete == FALSE) { crmd_fsa_stall(FALSE); } } else if (action & A_TE_INVOKE) { const char *value = NULL; xmlNode *graph_data = NULL; ha_msg_input_t *input = fsa_typed_data(fsa_dt_ha_msg); const char *ref = crm_element_value(input->msg, XML_ATTR_REFERENCE); const char *graph_file = crm_element_value(input->msg, F_CRM_TGRAPH); const char *graph_input = crm_element_value(input->msg, F_CRM_TGRAPH_INPUT); if (graph_file == NULL && input->xml == NULL) { crm_log_xml_err(input->msg, "Bad command"); register_fsa_error(C_FSA_INTERNAL, I_FAIL, NULL); return; } if (transition_graph->complete == FALSE) { crm_info("Another transition is already active"); abort_transition(INFINITY, tg_restart, "Transition Active", NULL); return; } if (fsa_pe_ref == NULL || safe_str_neq(fsa_pe_ref, ref)) { crm_info("Transition is redundant: %s vs. %s", crm_str(fsa_pe_ref), crm_str(ref)); abort_transition(INFINITY, tg_restart, "Transition Redundant", NULL); } graph_data = input->xml; if (graph_data == NULL && graph_file != NULL) { graph_data = filename2xml(graph_file); } if (is_timer_started(transition_timer)) { crm_debug("The transitioner wait for a transition timer"); return; } CRM_CHECK(graph_data != NULL, crm_err("Input raised by %s is invalid", msg_data->origin); crm_log_xml_err(input->msg, "Bad command"); return); destroy_graph(transition_graph); transition_graph = unpack_graph(graph_data, graph_input); CRM_CHECK(transition_graph != NULL, transition_graph = create_blank_graph(); return); crm_info("Processing graph %d (ref=%s) derived from %s", transition_graph->id, ref, graph_input); value = crm_element_value(graph_data, "failed-stop-offset"); if (value) { free(failed_stop_offset); failed_stop_offset = strdup(value); } value = crm_element_value(graph_data, "failed-start-offset"); if (value) { free(failed_start_offset); failed_start_offset = strdup(value); } trigger_graph(); print_graph(LOG_DEBUG_2, transition_graph); if (graph_data != input->xml) { free_xml(graph_data); } } } pacemaker-master/crmd/tengine.h000066400000000000000000000055411217637305600170450ustar00rootroot00000000000000/* * Copyright (C) 2004 Andrew Beekhof * * 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 2 of the License, or (at your option) any later version. * * This software 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 library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef TENGINE__H # define TENGINE__H # include # include # include # include extern stonith_t *stonith_api; extern GListPtr stonith_cleanup_list; extern void send_stonith_update(crm_action_t * stonith_action, const char *target, const char *uuid); /* tengine */ extern crm_action_t *match_down_event(int rc, const char *target, const char *filter, bool quiet); extern crm_action_t *get_cancel_action(const char *id, const char *node); extern gboolean cib_action_update(crm_action_t * action, int status, int op_rc); extern gboolean fail_incompletable_actions(crm_graph_t * graph, const char *down_node); extern gboolean process_graph_event(xmlNode * event, const char *event_node); /* utils */ extern crm_action_t *get_action(int id, gboolean confirmed); extern gboolean start_global_timer(crm_action_timer_t * timer, int timeout); extern gboolean stop_te_timer(crm_action_timer_t * timer); extern const char *get_rsc_state(const char *task, enum op_status status); /* unpack */ extern gboolean process_te_message(xmlNode * msg, xmlNode * xml_data); extern crm_graph_t *transition_graph; extern crm_trigger_t *transition_trigger; extern char *te_uuid; extern void notify_crmd(crm_graph_t * graph); # include extern void trigger_graph_processing(const char *fn, int line); extern void abort_transition_graph(int abort_priority, enum transition_action abort_action, const char *abort_text, xmlNode * reason, const char *fn, int line); # define trigger_graph() trigger_graph_processing(__FUNCTION__, __LINE__) # define abort_transition(pri, action, text, reason) \ abort_transition_graph(pri, action, text, reason,__FUNCTION__,__LINE__); extern gboolean te_connect_stonith(gpointer user_data); extern crm_trigger_t *transition_trigger; extern crm_trigger_t *stonith_reconnect; extern char *failed_stop_offset; extern char *failed_start_offset; extern int active_timeout; extern int stonith_op_active; #endif pacemaker-master/crmd/utils.c000066400000000000000000001036471217637305600165550ustar00rootroot00000000000000/* * Copyright (C) 2004 Andrew Beekhof * * 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 2 of the License, or (at your option) any later version. * * This software 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 library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include /* A_DC_TIMER_STOP, A_DC_TIMER_START, * A_FINALIZE_TIMER_STOP, A_FINALIZE_TIMER_START * A_INTEGRATE_TIMER_STOP, A_INTEGRATE_TIMER_START */ void do_timer_control(long long action, enum crmd_fsa_cause cause, enum crmd_fsa_state cur_state, enum crmd_fsa_input current_input, fsa_data_t * msg_data) { gboolean timer_op_ok = TRUE; if (action & A_DC_TIMER_STOP) { timer_op_ok = crm_timer_stop(election_trigger); } else if (action & A_FINALIZE_TIMER_STOP) { timer_op_ok = crm_timer_stop(finalization_timer); } else if (action & A_INTEGRATE_TIMER_STOP) { timer_op_ok = crm_timer_stop(integration_timer); /* } else if(action & A_ELECTION_TIMEOUT_STOP) { */ /* timer_op_ok = crm_timer_stop(election_timeout); */ } /* dont start a timer that wasnt already running */ if (action & A_DC_TIMER_START && timer_op_ok) { crm_timer_start(election_trigger); if (AM_I_DC) { /* there can be only one */ register_fsa_input(cause, I_ELECTION, NULL); } } else if (action & A_FINALIZE_TIMER_START) { crm_timer_start(finalization_timer); } else if (action & A_INTEGRATE_TIMER_START) { crm_timer_start(integration_timer); /* } else if(action & A_ELECTION_TIMEOUT_START) { */ /* crm_timer_start(election_timeout); */ } } const char * get_timer_desc(fsa_timer_t * timer) { if (timer == election_trigger) { return "Election Trigger"; } else if (timer == election_timeout) { return "Election Timeout"; } else if (timer == shutdown_escalation_timer) { return "Shutdown Escalation"; } else if (timer == integration_timer) { return "Integration Timer"; } else if (timer == finalization_timer) { return "Finalization Timer"; } else if (timer == transition_timer) { return "New Transition Timer"; } else if (timer == wait_timer) { return "Wait Timer"; } else if (timer == recheck_timer) { return "PEngine Recheck Timer"; } return "Unknown Timer"; } gboolean crm_timer_popped(gpointer data) { fsa_timer_t *timer = (fsa_timer_t *) data; if (timer == wait_timer || timer == recheck_timer || timer == transition_timer || timer == finalization_timer || timer == election_trigger) { crm_info("%s (%s) just popped (%dms)", get_timer_desc(timer), fsa_input2string(timer->fsa_input), timer->period_ms); timer->counter++; } else { crm_err("%s (%s) just popped in state %s! (%dms)", get_timer_desc(timer), fsa_input2string(timer->fsa_input), fsa_state2string(fsa_state), timer->period_ms); } if (timer == election_trigger && election_trigger->counter > 5) { crm_notice("We appear to be in an election loop, something may be wrong"); crm_write_blackbox(0, NULL); election_trigger->counter = 0; } if (timer->repeat == FALSE) { crm_timer_stop(timer); /* make it _not_ go off again */ } if (timer->fsa_input == I_INTEGRATED) { crm_info("Welcomed: %d, Integrated: %d", crmd_join_phase_count(crm_join_welcomed), crmd_join_phase_count(crm_join_integrated)); if (crmd_join_phase_count(crm_join_welcomed) == 0) { /* If we don't even have ourself, start again */ register_fsa_error_adv(C_FSA_INTERNAL, I_ELECTION, NULL, NULL, __FUNCTION__); } else { register_fsa_input_before(C_TIMER_POPPED, timer->fsa_input, NULL); } } else if (timer == recheck_timer && fsa_state != S_IDLE) { crm_debug("Discarding %s event in state: %s", fsa_input2string(timer->fsa_input), fsa_state2string(fsa_state)); } else if (timer == finalization_timer && fsa_state != S_FINALIZE_JOIN) { crm_debug("Discarding %s event in state: %s", fsa_input2string(timer->fsa_input), fsa_state2string(fsa_state)); } else if (timer->fsa_input != I_NULL) { register_fsa_input(C_TIMER_POPPED, timer->fsa_input, NULL); } crm_trace("Triggering FSA: %s", __FUNCTION__); mainloop_set_trigger(fsa_source); return TRUE; } gboolean is_timer_started(fsa_timer_t * timer) { if (timer->period_ms > 0) { if (transition_timer->source_id == 0) { return FALSE; } else { return TRUE; } } return FALSE; } gboolean crm_timer_start(fsa_timer_t * timer) { const char *timer_desc = get_timer_desc(timer); if (timer->source_id == 0 && timer->period_ms > 0) { timer->source_id = g_timeout_add(timer->period_ms, timer->callback, (void *)timer); CRM_ASSERT(timer->source_id != 0); crm_debug("Started %s (%s:%dms), src=%d", timer_desc, fsa_input2string(timer->fsa_input), timer->period_ms, timer->source_id); } else if (timer->period_ms < 0) { crm_err("Tried to start %s (%s:%dms) with a -ve period", timer_desc, fsa_input2string(timer->fsa_input), timer->period_ms); } else { crm_debug("%s (%s:%dms) already running: src=%d", timer_desc, fsa_input2string(timer->fsa_input), timer->period_ms, timer->source_id); return FALSE; } return TRUE; } gboolean crm_timer_stop(fsa_timer_t * timer) { const char *timer_desc = get_timer_desc(timer); if (timer == NULL) { crm_err("Attempted to stop NULL timer"); return FALSE; } else if (timer->source_id != 0) { crm_trace("Stopping %s (%s:%dms), src=%d", timer_desc, fsa_input2string(timer->fsa_input), timer->period_ms, timer->source_id); g_source_remove(timer->source_id); timer->source_id = 0; } else { crm_trace("%s (%s:%dms) already stopped", timer_desc, fsa_input2string(timer->fsa_input), timer->period_ms); return FALSE; } return TRUE; } const char * fsa_input2string(enum crmd_fsa_input input) { const char *inputAsText = NULL; switch (input) { case I_NULL: inputAsText = "I_NULL"; break; case I_CIB_OP: inputAsText = "I_CIB_OP (unused)"; break; case I_CIB_UPDATE: inputAsText = "I_CIB_UPDATE"; break; case I_DC_TIMEOUT: inputAsText = "I_DC_TIMEOUT"; break; case I_ELECTION: inputAsText = "I_ELECTION"; break; case I_PE_CALC: inputAsText = "I_PE_CALC"; break; case I_RELEASE_DC: inputAsText = "I_RELEASE_DC"; break; case I_ELECTION_DC: inputAsText = "I_ELECTION_DC"; break; case I_ERROR: inputAsText = "I_ERROR"; break; case I_FAIL: inputAsText = "I_FAIL"; break; case I_INTEGRATED: inputAsText = "I_INTEGRATED"; break; case I_FINALIZED: inputAsText = "I_FINALIZED"; break; case I_NODE_JOIN: inputAsText = "I_NODE_JOIN"; break; case I_JOIN_OFFER: inputAsText = "I_JOIN_OFFER"; break; case I_JOIN_REQUEST: inputAsText = "I_JOIN_REQUEST"; break; case I_JOIN_RESULT: inputAsText = "I_JOIN_RESULT"; break; case I_NOT_DC: inputAsText = "I_NOT_DC"; break; case I_RECOVERED: inputAsText = "I_RECOVERED"; break; case I_RELEASE_FAIL: inputAsText = "I_RELEASE_FAIL"; break; case I_RELEASE_SUCCESS: inputAsText = "I_RELEASE_SUCCESS"; break; case I_RESTART: inputAsText = "I_RESTART"; break; case I_PE_SUCCESS: inputAsText = "I_PE_SUCCESS"; break; case I_ROUTER: inputAsText = "I_ROUTER"; break; case I_SHUTDOWN: inputAsText = "I_SHUTDOWN"; break; case I_STARTUP: inputAsText = "I_STARTUP"; break; case I_TE_SUCCESS: inputAsText = "I_TE_SUCCESS"; break; case I_STOP: inputAsText = "I_STOP"; break; case I_DC_HEARTBEAT: inputAsText = "I_DC_HEARTBEAT"; break; case I_WAIT_FOR_EVENT: inputAsText = "I_WAIT_FOR_EVENT"; break; case I_LRM_EVENT: inputAsText = "I_LRM_EVENT"; break; case I_PENDING: inputAsText = "I_PENDING"; break; case I_HALT: inputAsText = "I_HALT"; break; case I_TERMINATE: inputAsText = "I_TERMINATE"; break; case I_ILLEGAL: inputAsText = "I_ILLEGAL"; break; } if (inputAsText == NULL) { crm_err("Input %d is unknown", input); inputAsText = ""; } return inputAsText; } const char * fsa_state2string(enum crmd_fsa_state state) { const char *stateAsText = NULL; switch (state) { case S_IDLE: stateAsText = "S_IDLE"; break; case S_ELECTION: stateAsText = "S_ELECTION"; break; case S_INTEGRATION: stateAsText = "S_INTEGRATION"; break; case S_FINALIZE_JOIN: stateAsText = "S_FINALIZE_JOIN"; break; case S_NOT_DC: stateAsText = "S_NOT_DC"; break; case S_POLICY_ENGINE: stateAsText = "S_POLICY_ENGINE"; break; case S_RECOVERY: stateAsText = "S_RECOVERY"; break; case S_RELEASE_DC: stateAsText = "S_RELEASE_DC"; break; case S_PENDING: stateAsText = "S_PENDING"; break; case S_STOPPING: stateAsText = "S_STOPPING"; break; case S_TERMINATE: stateAsText = "S_TERMINATE"; break; case S_TRANSITION_ENGINE: stateAsText = "S_TRANSITION_ENGINE"; break; case S_STARTING: stateAsText = "S_STARTING"; break; case S_HALT: stateAsText = "S_HALT"; break; case S_ILLEGAL: stateAsText = "S_ILLEGAL"; break; } if (stateAsText == NULL) { crm_err("State %d is unknown", state); stateAsText = ""; } return stateAsText; } const char * fsa_cause2string(enum crmd_fsa_cause cause) { const char *causeAsText = NULL; switch (cause) { case C_UNKNOWN: causeAsText = "C_UNKNOWN"; break; case C_STARTUP: causeAsText = "C_STARTUP"; break; case C_IPC_MESSAGE: causeAsText = "C_IPC_MESSAGE"; break; case C_HA_MESSAGE: causeAsText = "C_HA_MESSAGE"; break; case C_CCM_CALLBACK: causeAsText = "C_CCM_CALLBACK"; break; case C_TIMER_POPPED: causeAsText = "C_TIMER_POPPED"; break; case C_SHUTDOWN: causeAsText = "C_SHUTDOWN"; break; case C_HEARTBEAT_FAILED: causeAsText = "C_HEARTBEAT_FAILED"; break; case C_SUBSYSTEM_CONNECT: causeAsText = "C_SUBSYSTEM_CONNECT"; break; case C_LRM_OP_CALLBACK: causeAsText = "C_LRM_OP_CALLBACK"; break; case C_LRM_MONITOR_CALLBACK: causeAsText = "C_LRM_MONITOR_CALLBACK"; break; case C_CRMD_STATUS_CALLBACK: causeAsText = "C_CRMD_STATUS_CALLBACK"; break; case C_HA_DISCONNECT: causeAsText = "C_HA_DISCONNECT"; break; case C_FSA_INTERNAL: causeAsText = "C_FSA_INTERNAL"; break; case C_ILLEGAL: causeAsText = "C_ILLEGAL"; break; } if (causeAsText == NULL) { crm_err("Cause %d is unknown", cause); causeAsText = ""; } return causeAsText; } const char * fsa_action2string(long long action) { const char *actionAsText = NULL; switch (action) { case A_NOTHING: actionAsText = "A_NOTHING"; break; case A_ELECTION_START: actionAsText = "A_ELECTION_START"; break; case A_DC_JOIN_FINAL: actionAsText = "A_DC_JOIN_FINAL"; break; case A_READCONFIG: actionAsText = "A_READCONFIG"; break; case O_RELEASE: actionAsText = "O_RELEASE"; break; case A_STARTUP: actionAsText = "A_STARTUP"; break; case A_STARTED: actionAsText = "A_STARTED"; break; case A_HA_CONNECT: actionAsText = "A_HA_CONNECT"; break; case A_HA_DISCONNECT: actionAsText = "A_HA_DISCONNECT"; break; case A_LRM_CONNECT: actionAsText = "A_LRM_CONNECT"; break; case A_LRM_EVENT: actionAsText = "A_LRM_EVENT"; break; case A_LRM_INVOKE: actionAsText = "A_LRM_INVOKE"; break; case A_LRM_DISCONNECT: actionAsText = "A_LRM_DISCONNECT"; break; case O_LRM_RECONNECT: actionAsText = "O_LRM_RECONNECT"; break; case A_CL_JOIN_QUERY: actionAsText = "A_CL_JOIN_QUERY"; break; case A_DC_TIMER_STOP: actionAsText = "A_DC_TIMER_STOP"; break; case A_DC_TIMER_START: actionAsText = "A_DC_TIMER_START"; break; case A_INTEGRATE_TIMER_START: actionAsText = "A_INTEGRATE_TIMER_START"; break; case A_INTEGRATE_TIMER_STOP: actionAsText = "A_INTEGRATE_TIMER_STOP"; break; case A_FINALIZE_TIMER_START: actionAsText = "A_FINALIZE_TIMER_START"; break; case A_FINALIZE_TIMER_STOP: actionAsText = "A_FINALIZE_TIMER_STOP"; break; case A_ELECTION_COUNT: actionAsText = "A_ELECTION_COUNT"; break; case A_ELECTION_VOTE: actionAsText = "A_ELECTION_VOTE"; break; case A_ELECTION_CHECK: actionAsText = "A_ELECTION_CHECK"; break; case A_CL_JOIN_ANNOUNCE: actionAsText = "A_CL_JOIN_ANNOUNCE"; break; case A_CL_JOIN_REQUEST: actionAsText = "A_CL_JOIN_REQUEST"; break; case A_CL_JOIN_RESULT: actionAsText = "A_CL_JOIN_RESULT"; break; case A_DC_JOIN_OFFER_ALL: actionAsText = "A_DC_JOIN_OFFER_ALL"; break; case A_DC_JOIN_OFFER_ONE: actionAsText = "A_DC_JOIN_OFFER_ONE"; break; case A_DC_JOIN_PROCESS_REQ: actionAsText = "A_DC_JOIN_PROCESS_REQ"; break; case A_DC_JOIN_PROCESS_ACK: actionAsText = "A_DC_JOIN_PROCESS_ACK"; break; case A_DC_JOIN_FINALIZE: actionAsText = "A_DC_JOIN_FINALIZE"; break; case A_MSG_PROCESS: actionAsText = "A_MSG_PROCESS"; break; case A_MSG_ROUTE: actionAsText = "A_MSG_ROUTE"; break; case A_RECOVER: actionAsText = "A_RECOVER"; break; case A_DC_RELEASE: actionAsText = "A_DC_RELEASE"; break; case A_DC_RELEASED: actionAsText = "A_DC_RELEASED"; break; case A_DC_TAKEOVER: actionAsText = "A_DC_TAKEOVER"; break; case A_SHUTDOWN: actionAsText = "A_SHUTDOWN"; break; case A_SHUTDOWN_REQ: actionAsText = "A_SHUTDOWN_REQ"; break; case A_STOP: actionAsText = "A_STOP "; break; case A_EXIT_0: actionAsText = "A_EXIT_0"; break; case A_EXIT_1: actionAsText = "A_EXIT_1"; break; case A_CCM_CONNECT: actionAsText = "A_CCM_CONNECT"; break; case A_CCM_DISCONNECT: actionAsText = "A_CCM_DISCONNECT"; break; case O_CIB_RESTART: actionAsText = "O_CIB_RESTART"; break; case A_CIB_START: actionAsText = "A_CIB_START"; break; case A_CIB_STOP: actionAsText = "A_CIB_STOP"; break; case A_TE_INVOKE: actionAsText = "A_TE_INVOKE"; break; case O_TE_RESTART: actionAsText = "O_TE_RESTART"; break; case A_TE_START: actionAsText = "A_TE_START"; break; case A_TE_STOP: actionAsText = "A_TE_STOP"; break; case A_TE_HALT: actionAsText = "A_TE_HALT"; break; case A_TE_CANCEL: actionAsText = "A_TE_CANCEL"; break; case A_PE_INVOKE: actionAsText = "A_PE_INVOKE"; break; case O_PE_RESTART: actionAsText = "O_PE_RESTART"; break; case A_PE_START: actionAsText = "A_PE_START"; break; case A_PE_STOP: actionAsText = "A_PE_STOP"; break; case A_NODE_BLOCK: actionAsText = "A_NODE_BLOCK"; break; case A_UPDATE_NODESTATUS: actionAsText = "A_UPDATE_NODESTATUS"; break; case A_LOG: actionAsText = "A_LOG "; break; case A_ERROR: actionAsText = "A_ERROR "; break; case A_WARN: actionAsText = "A_WARN "; break; /* Composite actions */ case A_DC_TIMER_START | A_CL_JOIN_QUERY: actionAsText = "A_DC_TIMER_START|A_CL_JOIN_QUERY"; break; } if (actionAsText == NULL) { crm_err("Action %.16llx is unknown", action); actionAsText = ""; } return actionAsText; } void fsa_dump_inputs(int log_level, const char *text, long long input_register) { if (input_register == A_NOTHING) { return; } if (text == NULL) { text = "Input register contents:"; } if (is_set(input_register, R_THE_DC)) { crm_trace("%s %.16llx (R_THE_DC)", text, R_THE_DC); } if (is_set(input_register, R_STARTING)) { crm_trace("%s %.16llx (R_STARTING)", text, R_STARTING); } if (is_set(input_register, R_SHUTDOWN)) { crm_trace("%s %.16llx (R_SHUTDOWN)", text, R_SHUTDOWN); } if (is_set(input_register, R_STAYDOWN)) { crm_trace("%s %.16llx (R_STAYDOWN)", text, R_STAYDOWN); } if (is_set(input_register, R_JOIN_OK)) { crm_trace("%s %.16llx (R_JOIN_OK)", text, R_JOIN_OK); } if (is_set(input_register, R_READ_CONFIG)) { crm_trace("%s %.16llx (R_READ_CONFIG)", text, R_READ_CONFIG); } if (is_set(input_register, R_INVOKE_PE)) { crm_trace("%s %.16llx (R_INVOKE_PE)", text, R_INVOKE_PE); } if (is_set(input_register, R_CIB_CONNECTED)) { crm_trace("%s %.16llx (R_CIB_CONNECTED)", text, R_CIB_CONNECTED); } if (is_set(input_register, R_PE_CONNECTED)) { crm_trace("%s %.16llx (R_PE_CONNECTED)", text, R_PE_CONNECTED); } if (is_set(input_register, R_TE_CONNECTED)) { crm_trace("%s %.16llx (R_TE_CONNECTED)", text, R_TE_CONNECTED); } if (is_set(input_register, R_LRM_CONNECTED)) { crm_trace("%s %.16llx (R_LRM_CONNECTED)", text, R_LRM_CONNECTED); } if (is_set(input_register, R_CIB_REQUIRED)) { crm_trace("%s %.16llx (R_CIB_REQUIRED)", text, R_CIB_REQUIRED); } if (is_set(input_register, R_PE_REQUIRED)) { crm_trace("%s %.16llx (R_PE_REQUIRED)", text, R_PE_REQUIRED); } if (is_set(input_register, R_TE_REQUIRED)) { crm_trace("%s %.16llx (R_TE_REQUIRED)", text, R_TE_REQUIRED); } if (is_set(input_register, R_REQ_PEND)) { crm_trace("%s %.16llx (R_REQ_PEND)", text, R_REQ_PEND); } if (is_set(input_register, R_PE_PEND)) { crm_trace("%s %.16llx (R_PE_PEND)", text, R_PE_PEND); } if (is_set(input_register, R_TE_PEND)) { crm_trace("%s %.16llx (R_TE_PEND)", text, R_TE_PEND); } if (is_set(input_register, R_RESP_PEND)) { crm_trace("%s %.16llx (R_RESP_PEND)", text, R_RESP_PEND); } if (is_set(input_register, R_CIB_DONE)) { crm_trace("%s %.16llx (R_CIB_DONE)", text, R_CIB_DONE); } if (is_set(input_register, R_HAVE_CIB)) { crm_trace("%s %.16llx (R_HAVE_CIB)", text, R_HAVE_CIB); } if (is_set(input_register, R_CIB_ASKED)) { crm_trace("%s %.16llx (R_CIB_ASKED)", text, R_CIB_ASKED); } if (is_set(input_register, R_MEMBERSHIP)) { crm_trace("%s %.16llx (R_MEMBERSHIP)", text, R_MEMBERSHIP); } if (is_set(input_register, R_PEER_DATA)) { crm_trace("%s %.16llx (R_PEER_DATA)", text, R_PEER_DATA); } if (is_set(input_register, R_IN_RECOVERY)) { crm_trace("%s %.16llx (R_IN_RECOVERY)", text, R_IN_RECOVERY); } } void fsa_dump_actions(long long action, const char *text) { if (is_set(action, A_READCONFIG)) { crm_trace("Action %.16llx (A_READCONFIG) %s", A_READCONFIG, text); } if (is_set(action, A_STARTUP)) { crm_trace("Action %.16llx (A_STARTUP) %s", A_STARTUP, text); } if (is_set(action, A_STARTED)) { crm_trace("Action %.16llx (A_STARTED) %s", A_STARTED, text); } if (is_set(action, A_HA_CONNECT)) { crm_trace("Action %.16llx (A_CONNECT) %s", A_HA_CONNECT, text); } if (is_set(action, A_HA_DISCONNECT)) { crm_trace("Action %.16llx (A_DISCONNECT) %s", A_HA_DISCONNECT, text); } if (is_set(action, A_LRM_CONNECT)) { crm_trace("Action %.16llx (A_LRM_CONNECT) %s", A_LRM_CONNECT, text); } if (is_set(action, A_LRM_EVENT)) { crm_trace("Action %.16llx (A_LRM_EVENT) %s", A_LRM_EVENT, text); } if (is_set(action, A_LRM_INVOKE)) { crm_trace("Action %.16llx (A_LRM_INVOKE) %s", A_LRM_INVOKE, text); } if (is_set(action, A_LRM_DISCONNECT)) { crm_trace("Action %.16llx (A_LRM_DISCONNECT) %s", A_LRM_DISCONNECT, text); } if (is_set(action, A_DC_TIMER_STOP)) { crm_trace("Action %.16llx (A_DC_TIMER_STOP) %s", A_DC_TIMER_STOP, text); } if (is_set(action, A_DC_TIMER_START)) { crm_trace("Action %.16llx (A_DC_TIMER_START) %s", A_DC_TIMER_START, text); } if (is_set(action, A_INTEGRATE_TIMER_START)) { crm_trace("Action %.16llx (A_INTEGRATE_TIMER_START) %s", A_INTEGRATE_TIMER_START, text); } if (is_set(action, A_INTEGRATE_TIMER_STOP)) { crm_trace("Action %.16llx (A_INTEGRATE_TIMER_STOP) %s", A_INTEGRATE_TIMER_STOP, text); } if (is_set(action, A_FINALIZE_TIMER_START)) { crm_trace("Action %.16llx (A_FINALIZE_TIMER_START) %s", A_FINALIZE_TIMER_START, text); } if (is_set(action, A_FINALIZE_TIMER_STOP)) { crm_trace("Action %.16llx (A_FINALIZE_TIMER_STOP) %s", A_FINALIZE_TIMER_STOP, text); } if (is_set(action, A_ELECTION_COUNT)) { crm_trace("Action %.16llx (A_ELECTION_COUNT) %s", A_ELECTION_COUNT, text); } if (is_set(action, A_ELECTION_VOTE)) { crm_trace("Action %.16llx (A_ELECTION_VOTE) %s", A_ELECTION_VOTE, text); } if (is_set(action, A_ELECTION_CHECK)) { crm_trace("Action %.16llx (A_ELECTION_CHECK) %s", A_ELECTION_CHECK, text); } if (is_set(action, A_CL_JOIN_ANNOUNCE)) { crm_trace("Action %.16llx (A_CL_JOIN_ANNOUNCE) %s", A_CL_JOIN_ANNOUNCE, text); } if (is_set(action, A_CL_JOIN_REQUEST)) { crm_trace("Action %.16llx (A_CL_JOIN_REQUEST) %s", A_CL_JOIN_REQUEST, text); } if (is_set(action, A_CL_JOIN_RESULT)) { crm_trace("Action %.16llx (A_CL_JOIN_RESULT) %s", A_CL_JOIN_RESULT, text); } if (is_set(action, A_DC_JOIN_OFFER_ALL)) { crm_trace("Action %.16llx (A_DC_JOIN_OFFER_ALL) %s", A_DC_JOIN_OFFER_ALL, text); } if (is_set(action, A_DC_JOIN_OFFER_ONE)) { crm_trace("Action %.16llx (A_DC_JOIN_OFFER_ONE) %s", A_DC_JOIN_OFFER_ONE, text); } if (is_set(action, A_DC_JOIN_PROCESS_REQ)) { crm_trace("Action %.16llx (A_DC_JOIN_PROCESS_REQ) %s", A_DC_JOIN_PROCESS_REQ, text); } if (is_set(action, A_DC_JOIN_PROCESS_ACK)) { crm_trace("Action %.16llx (A_DC_JOIN_PROCESS_ACK) %s", A_DC_JOIN_PROCESS_ACK, text); } if (is_set(action, A_DC_JOIN_FINALIZE)) { crm_trace("Action %.16llx (A_DC_JOIN_FINALIZE) %s", A_DC_JOIN_FINALIZE, text); } if (is_set(action, A_MSG_PROCESS)) { crm_trace("Action %.16llx (A_MSG_PROCESS) %s", A_MSG_PROCESS, text); } if (is_set(action, A_MSG_ROUTE)) { crm_trace("Action %.16llx (A_MSG_ROUTE) %s", A_MSG_ROUTE, text); } if (is_set(action, A_RECOVER)) { crm_trace("Action %.16llx (A_RECOVER) %s", A_RECOVER, text); } if (is_set(action, A_DC_RELEASE)) { crm_trace("Action %.16llx (A_DC_RELEASE) %s", A_DC_RELEASE, text); } if (is_set(action, A_DC_RELEASED)) { crm_trace("Action %.16llx (A_DC_RELEASED) %s", A_DC_RELEASED, text); } if (is_set(action, A_DC_TAKEOVER)) { crm_trace("Action %.16llx (A_DC_TAKEOVER) %s", A_DC_TAKEOVER, text); } if (is_set(action, A_SHUTDOWN)) { crm_trace("Action %.16llx (A_SHUTDOWN) %s", A_SHUTDOWN, text); } if (is_set(action, A_SHUTDOWN_REQ)) { crm_trace("Action %.16llx (A_SHUTDOWN_REQ) %s", A_SHUTDOWN_REQ, text); } if (is_set(action, A_STOP)) { crm_trace("Action %.16llx (A_STOP ) %s", A_STOP, text); } if (is_set(action, A_EXIT_0)) { crm_trace("Action %.16llx (A_EXIT_0) %s", A_EXIT_0, text); } if (is_set(action, A_EXIT_1)) { crm_trace("Action %.16llx (A_EXIT_1) %s", A_EXIT_1, text); } if (is_set(action, A_CCM_CONNECT)) { crm_trace("Action %.16llx (A_CCM_CONNECT) %s", A_CCM_CONNECT, text); } if (is_set(action, A_CCM_DISCONNECT)) { crm_trace("Action %.16llx (A_CCM_DISCONNECT) %s", A_CCM_DISCONNECT, text); } if (is_set(action, A_CIB_START)) { crm_trace("Action %.16llx (A_CIB_START) %s", A_CIB_START, text); } if (is_set(action, A_CIB_STOP)) { crm_trace("Action %.16llx (A_CIB_STOP) %s", A_CIB_STOP, text); } if (is_set(action, A_TE_INVOKE)) { crm_trace("Action %.16llx (A_TE_INVOKE) %s", A_TE_INVOKE, text); } if (is_set(action, A_TE_START)) { crm_trace("Action %.16llx (A_TE_START) %s", A_TE_START, text); } if (is_set(action, A_TE_STOP)) { crm_trace("Action %.16llx (A_TE_STOP) %s", A_TE_STOP, text); } if (is_set(action, A_TE_CANCEL)) { crm_trace("Action %.16llx (A_TE_CANCEL) %s", A_TE_CANCEL, text); } if (is_set(action, A_PE_INVOKE)) { crm_trace("Action %.16llx (A_PE_INVOKE) %s", A_PE_INVOKE, text); } if (is_set(action, A_PE_START)) { crm_trace("Action %.16llx (A_PE_START) %s", A_PE_START, text); } if (is_set(action, A_PE_STOP)) { crm_trace("Action %.16llx (A_PE_STOP) %s", A_PE_STOP, text); } if (is_set(action, A_NODE_BLOCK)) { crm_trace("Action %.16llx (A_NODE_BLOCK) %s", A_NODE_BLOCK, text); } if (is_set(action, A_UPDATE_NODESTATUS)) { crm_trace("Action %.16llx (A_UPDATE_NODESTATUS) %s", A_UPDATE_NODESTATUS, text); } if (is_set(action, A_LOG)) { crm_trace("Action %.16llx (A_LOG ) %s", A_LOG, text); } if (is_set(action, A_ERROR)) { crm_trace("Action %.16llx (A_ERROR ) %s", A_ERROR, text); } if (is_set(action, A_WARN)) { crm_trace("Action %.16llx (A_WARN ) %s", A_WARN, text); } } gboolean update_dc(xmlNode * msg) { char *last_dc = fsa_our_dc; const char *dc_version = NULL; const char *welcome_from = NULL; if (msg != NULL) { gboolean invalid = FALSE; dc_version = crm_element_value(msg, F_CRM_VERSION); welcome_from = crm_element_value(msg, F_CRM_HOST_FROM); CRM_CHECK(dc_version != NULL, return FALSE); CRM_CHECK(welcome_from != NULL, return FALSE); if (AM_I_DC && safe_str_neq(welcome_from, fsa_our_uname)) { invalid = TRUE; } else if (fsa_our_dc && safe_str_neq(welcome_from, fsa_our_dc)) { invalid = TRUE; } if (invalid) { CRM_CHECK(fsa_our_dc != NULL, crm_err("We have no DC")); if (AM_I_DC) { crm_err("Not updating DC to %s (%s): we are also a DC", welcome_from, dc_version); } else { crm_warn("New DC %s is not %s", welcome_from, fsa_our_dc); } register_fsa_action(A_CL_JOIN_QUERY | A_DC_TIMER_START); return FALSE; } } free(fsa_our_dc_version); fsa_our_dc_version = NULL; fsa_our_dc = NULL; /* Free'd as last_dc */ if (welcome_from != NULL) { fsa_our_dc = strdup(welcome_from); } if (dc_version != NULL) { fsa_our_dc_version = strdup(dc_version); } if (safe_str_eq(fsa_our_dc, last_dc)) { /* do nothing */ } else if (fsa_our_dc != NULL) { crm_info("Set DC to %s (%s)", crm_str(fsa_our_dc), crm_str(fsa_our_dc_version)); } else if (last_dc != NULL) { crm_info("Unset DC. Was %s", crm_str(last_dc)); } free(last_dc); return TRUE; } #define STATUS_PATH_MAX 512 static void erase_xpath_callback(xmlNode * msg, int call_id, int rc, xmlNode * output, void *user_data) { char *xpath = user_data; do_crm_log_unlikely(rc == 0 ? LOG_DEBUG : LOG_NOTICE, "Deletion of \"%s\": %s (rc=%d)", xpath, pcmk_strerror(rc), rc); free(xpath); } void erase_status_tag(const char *uname, const char *tag, int options) { int rc = pcmk_ok; char xpath[STATUS_PATH_MAX]; int cib_opts = cib_quorum_override | cib_xpath | options; if (fsa_cib_conn && uname) { snprintf(xpath, STATUS_PATH_MAX, "//node_state[@uname='%s']/%s", uname, tag); crm_info("Deleting xpath: %s", xpath); rc = fsa_cib_conn->cmds->delete(fsa_cib_conn, xpath, NULL, cib_opts); fsa_register_cib_callback(rc, FALSE, strdup(xpath), erase_xpath_callback); } } crm_ipc_t *attrd_ipc = NULL; static int update_without_attrd(const char *host_uuid, const char *name, const char *value, const char *user_name) { if (fsa_cib_conn == NULL) { return -1; } crm_trace("updating status for host_uuid %s, %s=%s", host_uuid, name ? name : "", value ? value : ""); return update_attr_delegate(fsa_cib_conn, cib_none, XML_CIB_TAG_STATUS, host_uuid, NULL, NULL, NULL, name, value, FALSE, user_name); } void update_attrd(const char *host, const char *name, const char *value, const char *user_name, gboolean is_remote_node) { gboolean rc; int max = 5; /* TODO eventually we will want to update/replace the attrd with * something that can handle remote nodes as well as cluster nodes */ if (is_remote_node) { /* host is required for updating a remote node */ CRM_CHECK(host != NULL, return;); /* remote node uname and uuid are equal */ if (update_without_attrd(host, name, value, user_name) < pcmk_ok) { crm_err("Could not update attribute %s for remote-node %s", name, host); } return; } if (attrd_ipc == NULL) { attrd_ipc = crm_ipc_new(T_ATTRD, 0); } do { if (crm_ipc_connected(attrd_ipc) == FALSE) { crm_ipc_close(attrd_ipc); crm_info("Connecting to attrd... %d retries remaining", max); crm_ipc_connect(attrd_ipc); } rc = attrd_update_delegate(attrd_ipc, 'U', host, name, value, XML_CIB_TAG_STATUS, NULL, NULL, user_name); if (rc == pcmk_ok) { break; } else if (rc != -EAGAIN && rc != -EALREADY) { crm_info("Disconnecting from attrd: %s (%d)", pcmk_strerror(rc), rc); crm_ipc_close(attrd_ipc); } sleep(5 - max); } while (max--); if (rc != pcmk_ok) { if (name) { crm_err("Could not send attrd %s update%s: %s (%d)", name, is_set(fsa_input_register, R_SHUTDOWN) ? " at shutdown" : "", pcmk_strerror(rc), rc); } else { crm_err("Could not send attrd refresh%s: %s (%d)", is_set(fsa_input_register, R_SHUTDOWN) ? " at shutdown" : "", pcmk_strerror(rc), rc); } if (is_set(fsa_input_register, R_SHUTDOWN)) { register_fsa_input(C_FSA_INTERNAL, I_FAIL, NULL); } } } pacemaker-master/cts/000077500000000000000000000000001217637305600151025ustar00rootroot00000000000000pacemaker-master/cts/CIB.py000066400000000000000000000511301217637305600160510ustar00rootroot00000000000000'''CTS: Cluster Testing System: CIB generator ''' __copyright__=''' Author: Andrew Beekhof Copyright (C) 2008 Andrew Beekhof ''' from UserDict import UserDict import sys, time, types, syslog, os, struct, string, signal, traceback, warnings, socket from cts.CTSvars import * from cts.CTS import ClusterManager class CibBase: cts_cib = None version = "unknown" feature_set = "unknown" Factory = None def __init__(self, CM, factory, tmpfile=None): self.CM = CM self.Factory = factory if not tmpfile: warnings.filterwarnings("ignore") tmpfile=os.tmpnam() warnings.resetwarnings() self.Factory.tmpfile = tmpfile def version(self): return self.version def NextIP(self): fields = string.split(self.CM.Env["IPBase"], '.') fields[3] = str(int(fields[3])+1) ip = string.join(fields, '.') self.CM.Env["IPBase"] = ip return ip class CibXml: def __init__(self, Factory, tag, _id, **kwargs): self.tag = tag self.name = _id self.kwargs = kwargs self.children = [] self.Factory = Factory def add_child(self, child): self.children.append(child) def __setitem__(self, key, value): self.kwargs[key] = value def show(self): text = '''<%s''' % self.tag if self.name: text += ''' id="%s"''' % (self.name) for k in self.kwargs.keys(): text += ''' %s="%s"''' % (k, self.kwargs[k]) if not self.children: text += '''/>''' return text text += '''>''' for c in self.children: text += c.show() text += '''''' % self.tag return text def _run(self, operation, xml, section="all", options=""): self.Factory.debug("Writing out %s" % self.name) fixed = "HOME=/root CIB_file="+self.Factory.tmpfile fixed += " cibadmin --%s --scope %s %s --xml-text '%s'" % (operation, section, options, xml) rc = self.Factory.rsh(self.Factory.target, fixed) if rc != 0: self.Factory.log("Configure call failed: "+fixed) sys.exit(1) class FencingTopology(CibXml): def __init__(self, Factory): CibXml.__init__(self, Factory, "fencing-topology", None) def level(self, index, node, devices): self.add_child(CibXml(self.Factory, "fencing-level", "cts-%s.%d" % (node, index), target=node, index=index, devices=devices)) def commit(self): self._run("create", self.show(), "configuration", "--allow-create") class Option(CibXml): def __init__(self, Factory, name=None, value=None, section="cib-bootstrap-options"): CibXml.__init__(self, Factory, "cluster_property_set", section) if name and value: self.add_child(CibXml(Factory, "nvpair", "cts-%s" % name, name=name, value=value)) def __setitem__(self, key, value): self.add_child(CibXml(self.Factory, "nvpair", "cts-%s" % key, name=key, value=value)) def commit(self): self._run("modify", self.show(), "crm_config", "--allow-create") class Expression(CibXml): def __init__(self, Factory, name, attr, op, value=None): CibXml.__init__(self, Factory, "expression", name, attribute=attr, operation=op) if value: self["value"] = value class Rule(CibXml): def __init__(self, Factory, name, score, op="and", expr=None): CibXml.__init__(self, Factory, "rule", "%s" % name) self["boolean-op"] = op self["score"] = score if expr: self.add_child(expr) class Resource(CibXml): def __init__(self, Factory, name, rtype, standard, provider=None): CibXml.__init__(self, Factory, "native", name) self.rtype = rtype self.standard = standard self.provider = provider self.op=[] self.meta={} self.param={} self.scores={} self.needs={} self.coloc={} if self.standard == "ocf" and not provider: self.provider = "heartbeat" elif self.standard == "lsb": self.provider = None def __setitem__(self, key, value): self.add_param(key, value) def add_op(self, name, interval, **kwargs): self.op.append( CibXml(self.Factory, "op", "%s-%s" % (name, interval), name=name, interval=interval, **kwargs)) def add_param(self, name, value): self.param[name] = value def add_meta(self, name, value): self.meta[name] = value def prefer(self, node, score="INFINITY", rule=None): if not rule: rule = Rule(self.Factory, "prefer-%s-r" % node, score, expr=Expression(self.Factory, "prefer-%s-e" % node, "#uname", "eq", node)) self.scores[node] = rule def after(self, resource, kind="Mandatory", first="start", then="start", **kwargs): kargs = kwargs.copy() kargs["kind"] = kind if then: kargs["first-action"] = "start" kargs["then-action"] = then if first: kargs["first-action"] = first self.needs[resource] = kargs def colocate(self, resource, score="INFINITY", role=None, withrole=None, **kwargs): kargs = kwargs.copy() kargs["score"] = score if role: kargs["rsc-role"] = role if withrole: kargs["with-rsc-role"] = withrole self.coloc[resource] = kargs def constraints(self): text = "" for k in self.scores.keys(): text += '''''' % (k, self.name) text += self.scores[k].show() text += '''''' for k in self.needs.keys(): text += '''''' for k in self.coloc.keys(): text += '''''' text += "" return text def show(self): text = '''''' if len(self.meta) > 0: text += '''''' % self.name for p in self.meta.keys(): text += '''''' % (self.name, p, p, self.meta[p]) text += '''''' if len(self.param) > 0: text += '''''' % self.name for p in self.param.keys(): text += '''''' % (self.name, p, p, self.param[p]) text += '''''' if len(self.op) > 0: text += '''''' for o in self.op: key = o.name o.name = "%s-%s" % (self.name, key) text += o.show() o.name = key text += '''''' text += '''''' return text def commit(self): self._run("create", self.show(), "resources") self._run("modify", self.constraints()) class Group(Resource): def __init__(self, Factory, name): Resource.__init__(self, Factory, name, None, None) self.tag = "group" def __setitem__(self, key, value): self.add_meta(key, value) def show(self): text = '''<%s id="%s">''' % (self.tag, self.name) if len(self.meta) > 0: text += '''''' % self.name for p in self.meta.keys(): text += '''''' % (self.name, p, p, self.meta[p]) text += '''''' for c in self.children: text += c.show() text += '''''' % self.tag return text class Clone(Group): def __init__(self, Factory, name, child=None): Group.__init__(self, Factory, name) self.tag = "clone" if child: self.add_child(child) def add_child(self, resource): if not self.children: self.children.append(resource) else: self.Factory.log("Clones can only have a single child. Ignoring %s" % resource.name) class Master(Clone): def __init__(self, Factory, name, child=None): Clone.__init__(self, Factory, name, child) self.tag = "master" class CIB11(CibBase): feature_set = "3.0" version = "pacemaker-1.1" def _show(self, command=""): output = "" (rc, result) = self.Factory.rsh(self.Factory.target, "HOME=/root CIB_file="+self.Factory.tmpfile+" cibadmin -Ql "+command, None, ) for line in result: output += line self.Factory.debug("Generated Config: "+line) return output def NewIP(self, name=None, standard="ocf"): ip = self.NextIP() if not name: name = "r"+ip r = Resource(self.Factory, name, "IPaddr2", standard) r["ip"] = ip r["cidr_netmask"] = "32" r.add_op("monitor", "5s") return r def install(self, target): old = self.Factory.tmpfile # Force a rebuild self.cts_cib = None self.Factory.tmpfile = CTSvars.CRM_CONFIG_DIR+"/cib.xml" self.contents(target) self.Factory.rsh(self.Factory.target, "chown "+CTSvars.CRM_DAEMON_USER+" "+self.Factory.tmpfile) self.Factory.tmpfile = old def contents(self, target=None): # fencing resource if self.cts_cib: return self.cts_cib if target: self.Factory.target = target self.Factory.rsh(self.Factory.target, "HOME=/root cibadmin --empty %s > %s" % (self.version, self.Factory.tmpfile)) #cib_base = self.cib_template % (self.feature_set, self.version, ''' remote-tls-port='9898' remote-clear-port='9999' ''') nodelist = "" self.num_nodes = 0 for node in self.CM.Env["nodes"]: nodelist += node + " " self.num_nodes = self.num_nodes + 1 no_quorum = "stop" if self.num_nodes < 3: no_quorum = "ignore" self.Factory.log("Cluster only has %d nodes, configuring: no-quroum-policy=ignore" % self.num_nodes) # Fencing resource # Define first so that the shell doesn't reject every update if self.CM.Env["DoFencing"]: st = Resource(self.Factory, "Fencing", self.CM.Env["stonith-type"], "stonith") # Set a threshold for unreliable stonith devices such as the vmware one st.add_meta("migration-threshold", "5") st.add_op("monitor", "120s", timeout="120s") st.add_op("stop", "0", timeout="60s") st.add_op("start", "0", timeout="60s") entries = string.split(self.CM.Env["stonith-params"], ',') for entry in entries: (name, value) = string.split(entry, '=') if name == "hostlist" and value == "all": value = string.join(self.CM.Env["nodes"], " ") elif name == "pcmk_host_list" and value == "all": value = string.join(self.CM.Env["nodes"], " ") st[name] = value st.commit() # Test advanced fencing logic if True: stf_nodes = [] stt_nodes = [] # Create the levels stl = FencingTopology(self.Factory) for node in self.CM.Env["nodes"]: ftype = self.CM.Env.RandomGen.choice(["levels-and", "levels-or ", "broadcast "]) self.CM.log(" - Using %s fencing for node: %s" % (ftype, node)) if ftype == "levels-and": stl.level(1, node, "FencingPass,Fencing") stt_nodes.append(node) elif ftype == "levels-or ": stl.level(1, node, "FencingFail") stl.level(2, node, "Fencing") stf_nodes.append(node) # Create a Dummy agent that always passes for levels-and if len(stt_nodes): self.CM.install_helper("fence_dummy", destdir="/usr/sbin", sourcedir=CTSvars.Fencing_home) stt = Resource(self.Factory, "FencingPass", "fence_dummy", "stonith") stt["pcmk_host_list"] = string.join(stt_nodes, " ") # Wait this many seconds before doing anything, handy for letting disks get flushed too stt["delay"] = "20" stt["random_sleep_range"] = "10" stt["mode"] = "pass" stt.commit() # Create a Dummy agent that always fails for levels-or if len(stf_nodes): self.CM.install_helper("fence_dummy", destdir="/usr/sbin", sourcedir=CTSvars.Fencing_home) stf = Resource(self.Factory, "FencingFail", "fence_dummy", "stonith") stf["pcmk_host_list"] = string.join(stf_nodes, " ") # Wait this many seconds before doing anything, handy for letting disks get flushed too stf["delay"] = "20" stf["random_sleep_range"] = "30" stf["mode"] = "fail" stf.commit() # Now commit the levels themselves stl.commit() o = Option(self.Factory, "stonith-enabled", self.CM.Env["DoFencing"]) o["start-failure-is-fatal"] = "false" o["pe-input-series-max"] = "5000" o["default-action-timeout"] = "90s" o["shutdown-escalation"] = "5min" o["batch-limit"] = "10" o["dc-deadtime"] = "5s" o["no-quorum-policy"] = no_quorum o["expected-quorum-votes"] = self.num_nodes if self.CM.Env["DoBSC"] == 1: o["ident-string"] = "Linux-HA TEST configuration file - REMOVEME!!" o.commit() # Add resources? if self.CM.Env["CIBResource"] == 1: self.add_resources() if self.CM.cluster_monitor == 1: mon = Resource(self.Factory, "cluster_mon", "ocf", "ClusterMon", "pacemaker") mon.add_op("start", "0", requires="nothing") mon.add_op("monitor", "5s", requires="nothing") mon["update"] = "10" mon["extra_options"] = "-r -n" mon["user"] = "abeekhof" mon["htmlfile"] = "/suse/abeekhof/Export/cluster.html" mon.commit() #self._create('''location prefer-dc cluster_mon rule -INFINITY: \#is_dc eq false''') # generate cib self.cts_cib = self._show() if self.Factory.tmpfile != CTSvars.CRM_CONFIG_DIR+"/cib.xml": self.Factory.rsh(self.Factory.target, "rm -f "+self.Factory.tmpfile) return self.cts_cib def add_resources(self): # Per-node resources for node in self.CM.Env["nodes"]: name = "rsc_"+node r = self.NewIP(name) r.prefer(node, "100") r.commit() # Migrator # Make this slightly sticky (since we have no other location constraints) to avoid relocation during Reattach m = Resource(self.Factory, "migrator","Dummy", "ocf", "pacemaker") m.add_meta("resource-stickiness","1") m.add_meta("allow-migrate", "1") m.add_op("monitor", "P10S") m.commit() # Ping the test master p = Resource(self.Factory, "ping-1","ping", "ocf", "pacemaker") p.add_op("monitor", "60s") p["host_list"] = self.CM.Env["cts-master"] p["name"] = "connected" p["debug"] = "true" c = Clone(self.Factory, "Connectivity", p) c["globally-unique"] = "false" c.commit() #master slave resource s = Resource(self.Factory, "stateful-1", "Stateful", "ocf", "pacemaker") s.add_op("monitor", "15s", timeout="60s") s.add_op("monitor", "16s", timeout="60s", role="Master") ms = Master(self.Factory, "master-1", s) ms["clone-max"] = self.num_nodes ms["master-max"] = 1 ms["clone-node-max"] = 1 ms["master-node-max"] = 1 # Require conectivity to run the master r = Rule(self.Factory, "connected", "-INFINITY", op="or") r.add_child(Expression(self.Factory, "m1-connected-1", "connected", "lt", "1")) r.add_child(Expression(self.Factory, "m1-connected-2", "connected", "not_defined", None)) ms.prefer("connected", rule=r) ms.commit() # Group Resource g = Group(self.Factory, "group-1") g.add_child(self.NewIP()) g.add_child(self.NewIP()) g.add_child(self.NewIP()) # Group with the master g.after("master-1", first="promote", then="start") g.colocate("master-1", "INFINITY", withrole="Master") g.commit() # LSB resource lsb_agent = self.CM.install_helper("LSBDummy") lsb = Resource(self.Factory, "lsb-dummy",lsb_agent, "lsb") lsb.add_op("monitor", "5s") # LSB with group lsb.after("group-1") lsb.colocate("group-1") lsb.commit() class CIB12(CIB11): feature_set = "3.0" version = "pacemaker-1.2" #class HASI(CIB10): # def add_resources(self): # # DLM resource # self._create('''primitive dlm ocf:pacemaker:controld op monitor interval=120s''') # self._create('''clone dlm-clone dlm meta globally-unique=false interleave=true''') # O2CB resource # self._create('''primitive o2cb ocf:ocfs2:o2cb op monitor interval=120s''') # self._create('''clone o2cb-clone o2cb meta globally-unique=false interleave=true''') # self._create('''colocation o2cb-with-dlm INFINITY: o2cb-clone dlm-clone''') # self._create('''order start-o2cb-after-dlm mandatory: dlm-clone o2cb-clone''') class ConfigFactory: def __init__(self, CM): self.CM = CM self.rsh = self.CM.rsh self.register("pacemaker11", CIB11, CM, self) self.register("pacemaker12", CIB12, CM, self) # self.register("hae", HASI, CM, self) self.target = self.CM.Env["nodes"][0] self.tmpfile = None def log(self, args): self.CM.log("cib: %s" % args) def debug(self, args): self.CM.debug("cib: %s" % args) def register(self, methodName, constructor, *args, **kargs): """register a constructor""" _args = [constructor] _args.extend(args) setattr(self, methodName, apply(ConfigFactoryItem,_args, kargs)) def unregister(self, methodName): """unregister a constructor""" delattr(self, methodName) def createConfig(self, name="pacemaker-1.0"): if name == "pacemaker-1.0": name = "pacemaker10"; elif name == "pacemaker-1.1": name = "pacemaker11"; elif name == "pacemaker-1.2": name = "pacemaker12"; elif name == "hasi": name = "hae"; if hasattr(self, name): return getattr(self, name)() else: self.CM.log("Configuration variant '%s' is unknown. Defaulting to latest config" % name) return self.pacemaker12() class ConfigFactoryItem: def __init__(self, function, *args, **kargs): assert callable(function), "function should be a callable obj" self._function = function self._args = args self._kargs = kargs def __call__(self, *args, **kargs): """call function""" _args = list(self._args) _args.extend(args) _kargs = self._kargs.copy() _kargs.update(kargs) return apply(self._function,_args,_kargs) # Basic Sanity Testing if __name__ == '__main__': import CTSlab env = CTSlab.LabEnvironment() env["nodes"] = [] env["nodes"].append("pcmk-1") env["nodes"].append("pcmk-2") env["nodes"].append("pcmk-3") env["nodes"].append("pcmk-4") env["CIBResource"] = 1 env["IPBase"] = "10.0.0.10" env["DoStonith"]=1 env["stonith-type"] = "fence_xvm" env["stonith-params"] = "pcmk_arg_map=domain:uname" manager = ClusterManager(env) manager.cluster_monitor = False CibFactory = ConfigFactory(manager) cib = CibFactory.createConfig("pacemaker-1.1") print cib.contents() pacemaker-master/cts/CM_ais.py000066400000000000000000000505331217637305600166150ustar00rootroot00000000000000'''CTS: Cluster Testing System: AIS dependent modules... ''' __copyright__=''' Copyright (C) 2007 Andrew Beekhof ''' # # 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 2 # of the License, 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 St, Fifth Floor, Boston, MA 02110-1301 USA. import os, sys, warnings from cts.CTSvars import * from cts.CM_lha import crm_lha from cts.CTS import Process ####################################################################### # # LinuxHA v2 dependent modules # ####################################################################### class crm_ais(crm_lha): ''' The crm version 3 cluster manager class. It implements the things we need to talk to and manipulate crm clusters running on top of openais ''' def __init__(self, Environment, randseed=None): crm_lha.__init__(self, Environment, randseed=randseed) self.update({ "Name" : "crm-ais", "EpocheCmd" : "crm_node -e --openais", "QuorumCmd" : "crm_node -q --openais", "ParitionCmd" : "crm_node -p --openais", "Pat:They_stopped" : "%s crmd.*Node %s\[.*state is now lost", "Pat:ChildExit" : "Child process .* exited", # Bad news Regexes. Should never occur. "BadRegexes" : ( r" trace:", r"error:", r"crit:", r"ERROR:", r"CRIT:", r"Shutting down...NOW", r"Timer I_TERMINATE just popped", r"input=I_ERROR", r"input=I_FAIL", r"input=I_INTEGRATED cause=C_TIMER_POPPED", r"input=I_FINALIZED cause=C_TIMER_POPPED", r"input=I_ERROR", r", exiting\.", r"(WARN|warn).*Ignoring HA message.*vote.*not in our membership list", r"pengine.*Attempting recovery of resource", r"is taking more than 2x its timeout", r"Confirm not received from", r"Welcome reply not received from", r"Attempting to schedule .* after a stop", r"Resource .* was active at shutdown", r"duplicate entries for call_id", r"Search terminated:", r":global_timer_callback", r"Faking parameter digest creation", r"Parameters to .* action changed:", r"Parameters to .* changed", r"Child process .* terminated with signal", r"LogActions: Recover", r"rsyslogd.* imuxsock lost .* messages from pid .* due to rate-limiting", r"Peer is not part of our cluster", r"We appear to be in an election loop", r"Unknown node -> we will not deliver message", r"crm_write_blackbox", r"pacemakerd.*Could not connect to Cluster Configuration Database API", r"Recieving messages from a node we think is dead", r"share the same cluster nodeid", r"share the same name", #r"crm_ipc_send:.*Request .* failed", #r"crm_ipc_send:.*Sending to .* is disabled until pending reply is recieved", # Not inherently bad, but worth tracking #r"No need to invoke the TE", #r"ping.*: DEBUG: Updated connected = 0", #r"Digest mis-match:", r"te_graph_trigger: Transition failed: terminated", #r"Executing .* fencing operation", #r"fence_pcmk.* Call to fence", #r"fence_pcmk", r"cman killed by node", r"Election storm", r"stalled the FSA with pending inputs", ), }) def errorstoignore(self): # At some point implement a more elegant solution that # also produces a report at the end '''Return list of errors which are known and very noisey should be ignored''' if 1: return [ r"crm_mon:", r"crmadmin:", r"update_trace_data", r"async_notify: strange, client not found", r"Parse error: Ignoring unknown option .*nodename", r"error: log_operation: Operation 'reboot' .* with device 'FencingFail' returned:", r"Child process .* terminated with signal 9", ] return [] def NodeUUID(self, node): return node def ais_components(self): fullcomplist = {} self.complist = [] self.common_ignore = [ "Pending action:", "error: crm_log_message_adv:", "error: MSG: No message to dump", "resources were active at shutdown", "pending LRM operations at shutdown", "Lost connection to the CIB service", "Connection to the CIB terminated...", "Sending message to CIB service FAILED", "apply_xml_diff: Diff application failed!", "crmd.*Action A_RECOVER .* not supported", "unconfirmed_actions: Waiting on .* unconfirmed actions", "cib_native_msgready: Message pending on command channel", "crmd.*do_exit: Performing A_EXIT_1 - forcefully exiting the CRMd", "verify_stopped: Resource .* was active at shutdown. You may ignore this error if it is unmanaged.", "error: attrd_connection_destroy: Lost connection to attrd", "info: te_fence_node: Executing .* fencing operation", "crm_write_blackbox:", # "error: native_create_actions: Resource .*stonith::.* is active on 2 nodes attempting recovery", # "error: process_pe_message: Transition .* ERRORs found during PE processing", ] cib_ignore = [ "lrmd.*error: crm_ipc_read: Connection to stonith-ng failed", "lrmd.*error: mainloop_gio_callback: Connection to stonith-ng.* closed", "lrmd.*error: stonith_connection_destroy_cb: LRMD lost STONITH connection", "lrmd.*error: stonith_connection_failed: STONITH connection failed, finalizing .* pending operations", ] fullcomplist["cib"] = Process(self, "cib", pats = [ "State transition .* S_RECOVERY", "Respawning .* crmd", "Respawning .* attrd", "error: crm_ipc_read: Connection to cib_.* failed", "error: mainloop_gio_callback: Connection to cib_.* closed", "Connection to the CIB terminated...", "Child process crmd .* exited: Generic Pacemaker error", "Child process attrd .* exited: Transport endpoint is not connected", "crmd.*Input I_TERMINATE from do_recover", "crmd.*I_ERROR.*crmd_cib_connection_destroy", "crmd.*Could not recover from internal error", ], badnews_ignore = cib_ignore, common_ignore = self.common_ignore) fullcomplist["lrmd"] = Process(self, "lrmd", pats = [ "State transition .* S_RECOVERY", "LRM Connection failed", "Respawning .* crmd", "error: crm_ipc_read: Connection to lrmd failed", "error: mainloop_gio_callback: Connection to lrmd.* closed", "crmd.*I_ERROR.*lrm_connection_destroy", "Child process crmd .* exited: Generic Pacemaker error", "crmd.*Input I_TERMINATE from do_recover", "crmd.* Could not recover from internal error", ], badnews_ignore = self.common_ignore) fullcomplist["crmd"] = Process(self, "crmd", pats = [ # "WARN: determine_online_status: Node .* is unclean", # "Scheduling Node .* for STONITH", # "Executing .* fencing operation", # Only if the node wasn't the DC: "State transition S_IDLE", "State transition .* -> S_IDLE", ], badnews_ignore = self.common_ignore) fullcomplist["attrd"] = Process(self, "attrd", pats = [ ], badnews_ignore = self.common_ignore) fullcomplist["pengine"] = Process(self, "pengine", dc_pats = [ "State transition .* S_RECOVERY", "Respawning .* crmd", "Child process crmd .* exited: Generic Pacemaker error", "crm_ipc_read: Connection to pengine failed", "error: mainloop_gio_callback: Connection to pengine.* closed", "crit: pe_ipc_destroy: Connection to the Policy Engine failed", "crmd.*I_ERROR.*save_cib_contents", "crmd.*Input I_TERMINATE from do_recover", "crmd.* Could not recover from internal error", ], badnews_ignore = self.common_ignore) stonith_ignore = [ "LogActions: Recover Fencing", "update_failcount: Updating failcount for Fencing", "error: te_connect_stonith: Sign-in failed: triggered a retry", "stonith_connection_failed: STONITH connection failed, finalizing .* pending operations.", "process_lrm_event: LRM operation Fencing.* Error" ] stonith_ignore.extend(self.common_ignore) fullcomplist["stonith-ng"] = Process(self, "stonith-ng", process="stonithd", pats = [ "crm_ipc_read: Connection to stonith-ng failed", "stonith_connection_destroy_cb: LRMD lost STONITH connection", "mainloop_gio_callback: Connection to stonith-ng.* closed", "tengine_stonith_connection_destroy: Fencing daemon connection failed", "crmd.*stonith_api_add_notification: Callback already present", ], badnews_ignore = stonith_ignore) vgrind = self.Env["valgrind-procs"].split() for key in fullcomplist.keys(): if self.Env["valgrind-tests"]: if key in vgrind: # Processes running under valgrind can't be shot with "killall -9 processname" self.log("Filtering %s from the component list as it is being profiled by valgrind" % key) continue if key == "stonith-ng" and not self.Env["DoFencing"]: continue self.complist.append(fullcomplist[key]) #self.complist = [ fullcomplist["pengine"] ] return self.complist class crm_whitetank(crm_ais): ''' The crm version 3 cluster manager class. It implements the things we need to talk to and manipulate crm clusters running on top of openais ''' def __init__(self, Environment, randseed=None): crm_ais.__init__(self, Environment, randseed=randseed) self.update({ "Name" : "crm-whitetank", "StartCmd" : "service openais start", "StopCmd" : "service openais stop", "Pat:We_stopped" : "%s.*openais.*pcmk_shutdown: Shutdown complete", "Pat:They_stopped" : "%s crmd.*Node %s\[.*state is now lost", "Pat:They_dead" : "openais:.*Node %s is now: lost", "Pat:ChildKilled" : "%s openais.*Child process %s terminated with signal 9", "Pat:ChildRespawn" : "%s openais.*Respawning failed child process: %s", "Pat:ChildExit" : "Child process .* exited", }) def Components(self): self.ais_components() aisexec_ignore = [ "error: ais_dispatch: Receiving message .* failed", "crmd.*I_ERROR.*crmd_cib_connection_destroy", "cib.*error: cib_cs_destroy: AIS connection terminated", #"crmd.*error: crm_ais_destroy: AIS connection terminated", "crmd.* Could not recover from internal error", "crmd.*I_TERMINATE.*do_recover", "attrd.*attrd_cs_destroy: Lost connection to Corosync service!", "stonithd.*error: Corosync connection terminated", ] aisexec_ignore.extend(self.common_ignore) self.complist.append(Process(self, "aisexec", pats = [ "error: ais_dispatch: AIS connection failed", "crmd.*error: do_exit: Could not recover from internal error", "pengine.*Scheduling Node .* for STONITH", "stonithd.*requests a STONITH operation RESET on node", "stonithd.*Succeeded to STONITH the node", ], badnews_ignore = aisexec_ignore)) class crm_cs_v0(crm_ais): ''' The crm version 3 cluster manager class. It implements the things we need to talk to and manipulate crm clusters running against version 0 of our plugin ''' def __init__(self, Environment, randseed=None): crm_ais.__init__(self, Environment, randseed=randseed) self.update({ "Name" : "crm-plugin-v0", "StartCmd" : "service corosync start", "StopCmd" : "service corosync stop", # The next pattern is too early # "Pat:We_stopped" : "%s.*Service engine unloaded: Pacemaker Cluster Manager", # The next pattern would be preferred, but it doesn't always come out # "Pat:We_stopped" : "%s.*Corosync Cluster Engine exiting with status", "Pat:We_stopped" : "%s.*Service engine unloaded: corosync cluster quorum service", "Pat:They_stopped" : "%s crmd.*Node %s\[.*state is now lost", "Pat:They_dead" : "corosync:.*Node %s is now: lost", "Pat:ChildKilled" : "%s corosync.*Child process %s terminated with signal 9", "Pat:ChildRespawn" : "%s corosync.*Respawning failed child process: %s", }) def Components(self): self.ais_components() corosync_ignore = [ r"error: pcmk_cpg_dispatch: Connection to the CPG API failed: Library error", r"pacemakerd.*error: pcmk_child_exit: Child process .* exited", r"cib.*error: cib_cs_destroy: Corosync connection lost", r"attrd.*error: attrd_cib_connection_destroy: Connection to the CIB terminated", r"stonith-ng.*error: stonith_peer_cs_destroy: Corosync connection terminated", r"error: pcmk_child_exit: Child process cib .* exited: Invalid argument", r"error: pcmk_child_exit: Child process attrd .* exited: Transport endpoint is not connected", r"error: pcmk_child_exit: Child process crmd .* exited: Link has been severed", r"lrmd.*error: crm_ipc_read: Connection to stonith-ng failed", r"lrmd.*error: mainloop_gio_callback: Connection to stonith-ng.* closed", r"lrmd.*error: stonith_connection_destroy_cb: LRMD lost STONITH connection", r"crmd.*do_state_transition: State transition .* S_RECOVERY", r"crmd.*error: do_log: FSA: Input I_ERROR", r"crmd.*error: do_log: FSA: Input I_TERMINATE", r"crmd.*error: pcmk_cman_dispatch: Connection to cman failed", r"crmd.*error: crmd_fast_exit: Could not recover from internal error", r"error: crm_ipc_read: Connection to cib_shm failed", r"error: mainloop_gio_callback: Connection to cib_shm.* closed", ] self.complist.append(Process(self, "corosync", pats = [ r"pacemakerd.*error: cfg_connection_destroy: Connection destroyed", r"pacemakerd.*error: mcp_cpg_destroy: Connection destroyed", r"attrd_cs_destroy: Lost connection to Corosync service!", r"stonith_peer_cs_destroy: Corosync connection terminated", r"cib_cs_destroy: Corosync connection lost! Exiting.", r"crmd_(cs|quorum)_destroy: connection terminated", r"pengine.*Scheduling Node .* for STONITH", r"tengine_stonith_notify: Peer .* was terminated .*: OK", ], badnews_ignore = corosync_ignore, common_ignore = self.common_ignore)) return self.complist class crm_cs_v1(crm_cs_v0): ''' The crm version 3 cluster manager class. It implements the things we need to talk to and manipulate crm clusters running on top of version 1 of our plugin ''' def __init__(self, Environment, randseed=None): crm_cs_v0.__init__(self, Environment, randseed=randseed) self.update({ "Name" : "crm-plugin-v1", "StartCmd" : "service corosync start && service pacemaker start", "StopCmd" : "service pacemaker stop; service corosync stop", "EpocheCmd" : "crm_node -e", "QuorumCmd" : "crm_node -q", "ParitionCmd" : "crm_node -p", "Pat:We_stopped" : "%s.*Service engine unloaded: corosync cluster quorum service", "Pat:They_stopped" : "%s crmd.*Node %s\[.*state is now lost", "Pat:They_dead" : "crmd.*Node %s\[.*state is now lost", "Pat:ChildKilled" : "%s pacemakerd.*Child process %s terminated with signal 9", "Pat:ChildRespawn" : "%s pacemakerd.*Respawning failed child process: %s", }) class crm_mcp(crm_cs_v0): ''' The crm version 4 cluster manager class. It implements the things we need to talk to and manipulate crm clusters running on top of native corosync (no plugins) ''' def __init__(self, Environment, randseed=None): crm_cs_v0.__init__(self, Environment, randseed=randseed) self.update({ "Name" : "crm-mcp", "StartCmd" : "service corosync start && service pacemaker start", "StopCmd" : "service pacemaker stop; service corosync stop", "EpocheCmd" : "crm_node -e", "QuorumCmd" : "crm_node -q", "ParitionCmd" : "crm_node -p", # Close enough... "Corosync Cluster Engine exiting normally" isn't printed # reliably and there's little interest in doing anything it "Pat:We_stopped" : "%s.*Unloading all Corosync service engines", "Pat:They_stopped" : "%s crmd.*Node %s\[.*state is now lost", "Pat:They_dead" : "crmd.*Node %s\[.*state is now lost", "Pat:ChildKilled" : "%s pacemakerd.*Child process %s terminated with signal 9", "Pat:ChildRespawn" : "%s pacemakerd.*Respawning failed child process: %s", "Pat:InfraUp" : "%s corosync.*Initializing transport", "Pat:PacemakerUp" : "%s pacemakerd.*Starting Pacemaker", }) class crm_cman(crm_cs_v0): ''' The crm version 3 cluster manager class. It implements the things we need to talk to and manipulate crm clusters running on top of openais ''' def __init__(self, Environment, randseed=None): crm_cs_v0.__init__(self, Environment, randseed=randseed) self.update({ "Name" : "crm-cman", "StartCmd" : "service pacemaker start", "StopCmd" : "service pacemaker stop", "EpocheCmd" : "crm_node -e --cman", "QuorumCmd" : "crm_node -q --cman", "ParitionCmd" : "crm_node -p --cman", "Pat:We_stopped" : "%s.*Unloading all Corosync service engines", "Pat:They_stopped" : "%s crmd.*Node %s\[.*state is now lost", "Pat:They_dead" : "crmd.*Node %s\[.*state is now lost", "Pat:ChildKilled" : "%s pacemakerd.*Child process %s terminated with signal 9", "Pat:ChildRespawn" : "%s pacemakerd.*Respawning failed child process: %s", }) pacemaker-master/cts/CM_lha.py000077500000000000000000000624241217637305600166120ustar00rootroot00000000000000'''CTS: Cluster Testing System: LinuxHA v2 dependent modules... ''' __copyright__=''' Author: Huang Zhen Copyright (C) 2004 International Business Machines Additional Audits, Revised Start action, Default Configuration: Copyright (C) 2004 Andrew Beekhof ''' # # 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 2 # of the License, 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 St, Fifth Floor, Boston, MA 02110-1301 USA. import os, sys, warnings from cts import CTS from cts.CTSvars import * from cts.CTS import * from cts.CIB import * from cts.CTStests import AuditResource try: from xml.dom.minidom import * except ImportError: sys.__stdout__.write("Python module xml.dom.minidom not found\n") sys.__stdout__.write("Please install python-xml or similar before continuing\n") sys.__stdout__.flush() sys.exit(1) ####################################################################### # # LinuxHA v2 dependent modules # ####################################################################### class crm_lha(ClusterManager): ''' The linux-ha version 2 cluster manager class. It implements the things we need to talk to and manipulate linux-ha version 2 clusters ''' def __init__(self, Environment, randseed=None): ClusterManager.__init__(self, Environment, randseed=randseed) #HeartbeatCM.__init__(self, Environment, randseed=randseed) self.fastfail = 0 self.clear_cache = 0 self.cib_installed = 0 self.config = None self.cluster_monitor = 0 self.use_short_names = 1 self.update({ "Name" : "crm-lha", "DeadTime" : 300, "StartTime" : 300, # Max time to start up "StableTime" : 30, "StartCmd" : "service heartbeat start > /dev/null 2>&1", "StopCmd" : "service heartbeat stop > /dev/null 2>&1", "StatusCmd" : "crmadmin -t 60000 -S %s 2>/dev/null", "EpocheCmd" : "crm_node -H -e", "QuorumCmd" : "crm_node -H -q", "ParitionCmd" : "crm_node -H -p", "CibQuery" : "cibadmin -Ql", "CibAddXml" : "cibadmin --modify -c --xml-text %s", "CibDelXpath" : "cibadmin --delete --xpath %s", # 300,000 == 5 minutes "RscRunning" : CTSvars.CRM_DAEMON_DIR + "/lrmd_test -R -r %s", "CIBfile" : "%s:"+CTSvars.CRM_CONFIG_DIR+"/cib.xml", "TmpDir" : "/tmp", "BreakCommCmd" : "iptables -A INPUT -s %s -j DROP >/dev/null 2>&1", "FixCommCmd" : "iptables -D INPUT -s %s -j DROP >/dev/null 2>&1", # tc qdisc add dev lo root handle 1: cbq avpkt 1000 bandwidth 1000mbit # tc class add dev lo parent 1: classid 1:1 cbq rate "$RATE"kbps allot 17000 prio 5 bounded isolated # tc filter add dev lo parent 1: protocol ip prio 16 u32 match ip dst 127.0.0.1 match ip sport $PORT 0xFFFF flowid 1:1 # tc qdisc add dev lo parent 1: netem delay "$LATENCY"msec "$(($LATENCY/4))"msec 10% 2> /dev/null > /dev/null "ReduceCommCmd" : "", "RestoreCommCmd" : "tc qdisc del dev lo root", "LogFileName" : Environment["LogFileName"], "UUIDQueryCmd" : "crmadmin -N", "MaintenanceModeOn" : "cibadmin --modify -c --xml-text ''", "MaintenanceModeOff" : "cibadmin --delete --xpath \"//nvpair[@name='maintenance-mode']\"", "StandbyCmd" : "crm_attribute -VQ -U %s -n standby -l forever -v %s 2>/dev/null", "StandbyQueryCmd" : "crm_attribute -QG -U %s -n standby -l forever -d off 2>/dev/null", # Patterns to look for in the log files for various occasions... "Pat:DC_IDLE" : "crmd.*State transition.*-> S_IDLE", # This wont work if we have multiple partitions "Pat:Local_started" : "%s .*The local CRM is operational", "Pat:Slave_started" : "%s .*State transition.*-> S_NOT_DC", "Pat:Master_started" : "%s .* State transition.*-> S_IDLE", "Pat:We_stopped" : "heartbeat.*%s.*Heartbeat shutdown complete", "Pat:Logd_stopped" : "%s logd:.*Exiting write process", "Pat:They_stopped" : "%s .*LOST:.* %s ", "Pat:They_dead" : "node %s.*: is dead", "Pat:TransitionComplete" : "Transition status: Complete: complete", "Pat:ChildKilled" : "%s heartbeat.*%s.*killed by signal 9", "Pat:ChildRespawn" : "%s heartbeat.*Respawning client.*%s", "Pat:ChildExit" : "(ERROR|error): Client .* exited with return code", "Pat:Fencing_start" : "Initiating remote operation .* for %s", "Pat:Fencing_ok" : "stonith.* remote_op_done: Operation .* of %s by .*: OK", # Bad news Regexes. Should never occur. "BadRegexes" : ( r" trace:", r"error:", r"crit:", r"ERROR:", r"CRIT:", r"Shutting down...NOW", r"Timer I_TERMINATE just popped", r"input=I_ERROR", r"input=I_FAIL", r"input=I_INTEGRATED cause=C_TIMER_POPPED", r"input=I_FINALIZED cause=C_TIMER_POPPED", r"input=I_ERROR", r", exiting\.", r"WARN.*Ignoring HA message.*vote.*not in our membership list", r"pengine.*Attempting recovery of resource", r"is taking more than 2x its timeout", r"Confirm not received from", r"Welcome reply not received from", r"Attempting to schedule .* after a stop", r"Resource .* was active at shutdown", r"duplicate entries for call_id", r"Search terminated:", r"No need to invoke the TE", r"global_timer_callback:", r"Faking parameter digest creation", r"Parameters to .* action changed:", r"Parameters to .* changed", ), }) if self.Env["DoBSC"]: del self["Pat:They_stopped"] del self["Pat:Logd_stopped"] self.Env["use_logd"] = 0 self._finalConditions() self.check_transitions = 0 self.check_elections = 0 self.CIBsync = {} self.CibFactory = ConfigFactory(self) self.cib = self.CibFactory.createConfig(self.Env["Schema"]) def errorstoignore(self): # At some point implement a more elegant solution that # also produces a report at the end '''Return list of errors which are known and very noisey should be ignored''' if 1: return [ "(ERROR|error): crm_abort: crm_glib_handler: ", "(ERROR|error): Message hist queue is filling up", "stonithd.*CRIT: external_hostlist: 'vmware gethosts' returned an empty hostlist", "stonithd.*(ERROR|error): Could not list nodes for stonith RA external/vmware.", "pengine.*Preventing .* from re-starting", ] return [] def install_config(self, node): if not self.ns.WaitForNodeToComeUp(node): self.log("Node %s is not up." % node) return None if not self.CIBsync.has_key(node) and self.Env["ClobberCIB"] == 1: self.CIBsync[node] = 1 self.rsh(node, "rm -f "+CTSvars.CRM_CONFIG_DIR+"/cib*") # Only install the CIB on the first node, all the other ones will pick it up from there if self.cib_installed == 1: return None self.cib_installed = 1 if self.Env["CIBfilename"] == None: self.log("Installing Generated CIB on node %s" %(node)) self.cib.install(node) else: self.log("Installing CIB (%s) on node %s" %(self.Env["CIBfilename"], node)) if 0 != self.rsh.cp(self.Env["CIBfilename"], "root@" + (self["CIBfile"]%node)): raise ValueError("Can not scp file to %s %d"%(node)) self.rsh(node, "chown "+CTSvars.CRM_DAEMON_USER+" "+CTSvars.CRM_CONFIG_DIR+"/cib.xml") def prepare(self): '''Finish the Initialization process. Prepare to test...''' self.partitions_expected = 1 for node in self.Env["nodes"]: self.ShouldBeStatus[node] = "" self.unisolate_node(node) self.StataCM(node) def test_node_CM(self, node): '''Report the status of the cluster manager on a given node''' watchpats = [ ] watchpats.append("Current ping state: (S_IDLE|S_NOT_DC)") watchpats.append(self["Pat:Slave_started"]%node) watchpats.append(self["Pat:Master_started"]%node) idle_watch = CTS.LogWatcher(self.Env, self["LogFileName"], watchpats, "ClusterIdle", hosts=[node]) idle_watch.setwatch() out = self.rsh(node, self["StatusCmd"]%node, 1) self.debug("Node %s status: '%s'" %(node, out)) if not out or string.find(out, 'ok') < 0: if self.ShouldBeStatus[node] == "up": self.log( "Node status for %s is %s but we think it should be %s" %(node, "down", self.ShouldBeStatus[node])) self.ShouldBeStatus[node]="down" return 0 if self.ShouldBeStatus[node] == "down": self.log( "Node status for %s is %s but we think it should be %s: %s" %(node, "up", self.ShouldBeStatus[node], out)) self.ShouldBeStatus[node]="up" # check the output first - because syslog-ng looses messages if string.find(out, 'S_NOT_DC') != -1: # Up and stable return 2 if string.find(out, 'S_IDLE') != -1: # Up and stable return 2 # fall back to syslog-ng and wait if not idle_watch.look(): # just up self.debug("Warn: Node %s is unstable: %s" %(node, out)) return 1 # Up and stable return 2 # Is the node up or is the node down def StataCM(self, node): '''Report the status of the cluster manager on a given node''' if self.test_node_CM(node) > 0: return 1 return None # Being up and being stable is not the same question... def node_stable(self, node): '''Report the status of the cluster manager on a given node''' if self.test_node_CM(node) == 2: return 1 self.log("Warn: Node %s not stable" %(node)) return None def partition_stable(self, nodes, timeout=None): watchpats = [ ] watchpats.append("Current ping state: S_IDLE") watchpats.append(self["Pat:DC_IDLE"]) self.debug("Waiting for cluster stability...") if timeout == None: timeout = self["DeadTime"] if len(nodes) < 3: self.debug("Cluster is inactive") return 1 idle_watch = CTS.LogWatcher(self.Env, self["LogFileName"], watchpats, "ClusterStable", timeout, hosts=nodes.split()) idle_watch.setwatch() for node in nodes.split(): # have each node dump its current state self.rsh(node, self["StatusCmd"] %node, 1) ret = idle_watch.look() while ret: self.debug(ret) for node in nodes.split(): if re.search(node, ret): return 1 ret = idle_watch.look() self.debug("Warn: Partition %s not IDLE after %ds" % (repr(nodes), timeout)) return None def cluster_stable(self, timeout=None, double_check=False): partitions = self.find_partitions() for partition in partitions: if not self.partition_stable(partition, timeout): return None if double_check: # Make sure we are really stable and that all resources, # including those that depend on transient node attributes, # are started if they were going to be time.sleep(5) for partition in partitions: if not self.partition_stable(partition, timeout): return None return 1 def is_node_dc(self, node, status_line=None): rc = 0 if not status_line: status_line = self.rsh(node, self["StatusCmd"]%node, 1) if not status_line: rc = 0 elif string.find(status_line, 'S_IDLE') != -1: rc = 1 elif string.find(status_line, 'S_INTEGRATION') != -1: rc = 1 elif string.find(status_line, 'S_FINALIZE_JOIN') != -1: rc = 1 elif string.find(status_line, 'S_POLICY_ENGINE') != -1: rc = 1 elif string.find(status_line, 'S_TRANSITION_ENGINE') != -1: rc = 1 return rc def active_resources(self, node): # [SM].* {node} matches Started, Slave, Master # Stopped wont be matched as it wont include {node} (rc, output) = self.rsh(node, """crm_resource -c""", None) resources = [] for line in output: if re.search("^Resource", line): tmp = AuditResource(self, line) if tmp.type == "primitive" and tmp.host == node: resources.append(tmp.id) return resources def ResourceLocation(self, rid): ResourceNodes = [] for node in self.Env["nodes"]: if self.ShouldBeStatus[node] == "up": cmd = self["RscRunning"] % (rid) (rc, lines) = self.rsh(node, cmd, None) if rc == 127: self.log("Command '%s' failed. Binary or pacemaker-cts package not installed?" % cmd) for line in lines: self.log("Output: "+line) elif rc == 0: ResourceNodes.append(node) return ResourceNodes def find_partitions(self): ccm_partitions = [] for node in self.Env["nodes"]: if self.ShouldBeStatus[node] == "up": partition = self.rsh(node, self["ParitionCmd"], 1) if not partition: self.log("no partition details for %s" %node) elif len(partition) > 2: partition = partition[:-1] found=0 for a_partition in ccm_partitions: if partition == a_partition: found = 1 if found == 0: self.debug("Adding partition from %s: %s" %(node, partition)) ccm_partitions.append(partition) else: self.debug("Partition '%s' from %s is consistent with existing entries" %(partition, node)) else: self.log("bad partition details for %s" %node) else: self.debug("Node %s is down... skipping" %node) return ccm_partitions def HasQuorum(self, node_list): # If we are auditing a partition, then one side will # have quorum and the other not. # So the caller needs to tell us which we are checking # If no value for node_list is specified... assume all nodes if not node_list: node_list = self.Env["nodes"] for node in node_list: if self.ShouldBeStatus[node] == "up": quorum = self.rsh(node, self["QuorumCmd"], 1) if string.find(quorum, "1") != -1: return 1 elif string.find(quorum, "0") != -1: return 0 else: self.debug("WARN: Unexpected quorum test result from "+ node +":"+ quorum) return 0 def Components(self): complist = [] common_ignore = [ "Pending action:", "(ERROR|error): crm_log_message_adv:", "(ERROR|error): MSG: No message to dump", "pending LRM operations at shutdown", "Lost connection to the CIB service", "Connection to the CIB terminated...", "Sending message to CIB service FAILED", "Action A_RECOVER .* not supported", "(ERROR|error): stonithd_op_result_ready: not signed on", "pingd.*(ERROR|error): send_update: Could not send update", "send_ipc_message: IPC Channel to .* is not connected", "unconfirmed_actions: Waiting on .* unconfirmed actions", "cib_native_msgready: Message pending on command channel", "do_exit: Performing A_EXIT_1 - forcefully exiting the CRMd", "verify_stopped: Resource .* was active at shutdown. You may ignore this error if it is unmanaged.", ] stonith_ignore = [ "(ERROR|error): stonithd_signon: ", "update_failcount: Updating failcount for child_DoFencing", "(ERROR|error): te_connect_stonith: Sign-in failed: triggered a retry", "lrmd.*(ERROR|error): cl_get_value: wrong argument (reply)", "lrmd.*(ERROR|error): is_expected_msg:.* null message", "lrmd.*(ERROR|error): stonithd_receive_ops_result failed.", ] stonith_ignore.extend(common_ignore) ccm_ignore = [ "(ERROR|error): get_channel_token: No reply message - disconnected" ] ccm_ignore.extend(common_ignore) ccm = Process(self, "ccm", triggersreboot=self.fastfail, pats = [ "State transition .* S_RECOVERY", "CCM connection appears to have failed", "crmd.*Action A_RECOVER .* not supported", "crmd.*Input I_TERMINATE from do_recover", "Exiting to recover from CCM connection failure", "crmd.*do_exit: Could not recover from internal error", "crmd.*I_ERROR.*(ccm_dispatch|crmd_cib_connection_destroy)", "crmd.*exited with return code 2.", "attrd.*exited with return code 1.", "cib.*exited with return code 2.", # Not if it was fenced # "A new node joined the cluster", # "WARN: determine_online_status: Node .* is unclean", # "Scheduling Node .* for STONITH", # "Executing .* fencing operation", # "tengine_stonith_callback: .*result=0", # "Processing I_NODE_JOIN:.* cause=C_HA_MESSAGE", # "State transition S_.* -> S_INTEGRATION.*input=I_NODE_JOIN", "State transition S_STARTING -> S_PENDING", ], badnews_ignore = ccm_ignore) cib = Process(self, "cib", triggersreboot=self.fastfail, pats = [ "State transition .* S_RECOVERY", "Lost connection to the CIB service", "Connection to the CIB terminated...", "crmd.*Input I_TERMINATE from do_recover", "crmd.*I_ERROR.*crmd_cib_connection_destroy", "crmd.*do_exit: Could not recover from internal error", "crmd.*exited with return code 2.", "attrd.*exited with return code 1.", ], badnews_ignore = common_ignore) lrmd = Process(self, "lrmd", triggersreboot=self.fastfail, pats = [ "State transition .* S_RECOVERY", "LRM Connection failed", "crmd.*I_ERROR.*lrm_connection_destroy", "State transition S_STARTING -> S_PENDING", "crmd.*Input I_TERMINATE from do_recover", "crmd.*do_exit: Could not recover from internal error", "crmd.*exited with return code 2.", ], badnews_ignore = common_ignore) crmd = Process(self, "crmd", triggersreboot=self.fastfail, pats = [ # "WARN: determine_online_status: Node .* is unclean", # "Scheduling Node .* for STONITH", # "Executing .* fencing operation", # "tengine_stonith_callback: .*result=0", "State transition .* S_IDLE", "State transition S_STARTING -> S_PENDING", ], badnews_ignore = common_ignore) pengine = Process(self, "pengine", triggersreboot=self.fastfail, pats = [ "State transition .* S_RECOVERY", "crmd.*exited with return code 2.", "crmd.*Input I_TERMINATE from do_recover", "crmd.*do_exit: Could not recover from internal error", "crmd.*CRIT: pe_connection_destroy: Connection to the Policy Engine failed", "crmd.*I_ERROR.*save_cib_contents", "crmd.*exited with return code 2.", ], badnews_ignore = common_ignore, dc_only=1) if self.Env["DoFencing"] == 1 : complist.append(Process(self, "stoniths", triggersreboot=self.fastfail, dc_pats = [ "crmd.*CRIT: tengine_stonith_connection_destroy: Fencing daemon connection failed", "Attempting connection to fencing daemon", "te_connect_stonith: Connected", ], badnews_ignore = stonith_ignore)) if self.fastfail == 0: ccm.pats.extend([ "attrd .* exited with return code 1", "(ERROR|error): Respawning client .*attrd", "cib.* exited with return code 2", "(ERROR|error): Respawning client .*cib", "crmd.* exited with return code 2", "(ERROR|error): Respawning client .*crmd" ]) cib.pats.extend([ "attrd.* exited with return code 1", "(ERROR|error): Respawning client .*attrd", "crmd.* exited with return code 2", "(ERROR|error): Respawning client .*crmd" ]) lrmd.pats.extend([ "crmd.* exited with return code 2", "(ERROR|error): Respawning client .*crmd" ]) pengine.pats.extend([ "(ERROR|error): Respawning client .*crmd" ]) complist.append(ccm) complist.append(cib) complist.append(lrmd) complist.append(crmd) complist.append(pengine) return complist def NodeUUID(self, node): lines = self.rsh(node, self["UUIDQueryCmd"], 1) for line in lines: self.debug("UUIDLine:"+ line) m = re.search(r'%s.+\((.+)\)' % node, line) if m: return m.group(1) return "" def StandbyStatus(self, node): out=self.rsh(node, self["StandbyQueryCmd"]%node, 1) if not out: return "off" out = out[:-1] self.debug("Standby result: "+out) return out # status == "on" : Enter Standby mode # status == "off": Enter Active mode def SetStandbyMode(self, node, status): current_status = self.StandbyStatus(node) cmd = self["StandbyCmd"] % (node, status) ret = self.rsh(node, cmd) return True def AddDummyRsc(self, node, rid): rsc_xml = """ ' '""" % (rid, rid) constraint_xml = """ ' ' """ % (rid, node, node, rid) self.rsh(node, self['CibAddXml'] % (rsc_xml)) self.rsh(node, self['CibAddXml'] % (constraint_xml)) def RemoveDummyRsc(self, node, rid): constraint = "\"//rsc_location[@rsc='%s']\"" % (rid) rsc = "\"//primitive[@id='%s']\"" % (rid) self.rsh(node, self['CibDelXpath'] % constraint) self.rsh(node, self['CibDelXpath'] % rsc) ####################################################################### # # A little test code... # # Which you are advised to completely ignore... # ####################################################################### if __name__ == '__main__': pass pacemaker-master/cts/CTS.py000066400000000000000000001612731217637305600161170ustar00rootroot00000000000000'''CTS: Cluster Testing System: Main module Classes related to testing high-availability clusters... ''' __copyright__=''' Copyright (C) 2000, 2001 Alan Robertson Licensed under the GNU GPL. ''' # # 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 2 # of the License, 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 St, Fifth Floor, Boston, MA 02110-1301 USA. import types, string, select, sys, time, re, os, struct, signal import time, syslog, random, traceback, base64, pickle, binascii, fcntl from socket import gethostbyname_ex from UserDict import UserDict from subprocess import Popen,PIPE from cts.CTSvars import * from threading import Thread trace_rsh=None trace_lw=None has_log_stats = {} log_stats_bin = CTSvars.CRM_DAEMON_DIR + "/cts_log_stats.sh" log_stats = """ #!/bin/bash # Tool for generating system load reports while CTS runs f=$1; shift action=$1; shift base=`basename $0` if [ ! -e $f ]; then echo "Time, Load 1, Load 5, Load 15, Test Marker" > $f fi function killpid() { if [ -e $f.pid ]; then kill -9 `cat $f.pid` rm -f $f.pid fi } function status() { if [ -e $f.pid ]; then kill -0 `cat $f.pid` return $? else return 1 fi } function start() { # Is it already running? if status then return fi echo Active as $$ echo $$ > $f.pid while [ 1 = 1 ]; do uptime | sed s/up.*:/,/ | tr '\\n' ',' >> $f #top -b -c -n1 | grep -e usr/libexec/pacemaker | grep -v -e grep -e python | head -n 1 | sed s@/usr/libexec/pacemaker/@@ | awk '{print " 0, "$9", "$10", "$12}' | tr '\\n' ',' >> $f echo 0 >> $f sleep 5 done } case $action in start) start ;; stop) killpid ;; delete) killpid rm -f $f ;; mark) uptime | sed s/up.*:/,/ | tr '\\n' ',' >> $f echo " $*" >> $f start ;; *) echo "Unknown action: $action." ;; esac """ class CtsLab(UserDict): '''This class defines the Lab Environment for the Cluster Test System. It defines those things which are expected to change from test environment to test environment for the same cluster manager. It is where you define the set of nodes that are in your test lab what kind of reset mechanism you use, etc. This class is derived from a UserDict because we hold many different parameters of different kinds, and this provides provide a uniform and extensible interface useful for any kind of communication between the user/administrator/tester and CTS. At this point in time, it is the intent of this class to model static configuration and/or environmental data about the environment which doesn't change as the tests proceed. Well-known names (keys) are an important concept in this class. The HasMinimalKeys member function knows the minimal set of well-known names for the class. The following names are standard (well-known) at this time: nodes An array of the nodes in the cluster reset A ResetMechanism object logger An array of objects that log strings... CMclass The type of ClusterManager we are running (This is a class object, not a class instance) RandSeed Random seed. It is a triple of bytes. (optional) The CTS code ignores names it doesn't know about/need. The individual tests have access to this information, and it is perfectly acceptable to provide hints, tweaks, fine-tuning directions or other information to the tests through this mechanism. ''' def __init__(self): self.data = {} self.rsh = RemoteExec(self) self.RandomGen = random.Random() self.Scenario = None # Get a random seed for the random number generator. self["LogWatcher"] = "any" self["LogFileName"] = "/var/log/messages" self["OutputFile"] = None self["SyslogFacility"] = "daemon" self["CMclass"] = None self["logger"] = ([StdErrLog(self)]) self.SeedRandom() def SeedRandom(self, seed=None): if not seed: seed = int(time.time()) if self.has_key("RandSeed"): self.log("New random seed is: " + str(seed)) else: self.log("Random seed is: " + str(seed)) self["RandSeed"] = seed self.RandomGen.seed(str(seed)) def HasMinimalKeys(self): 'Return TRUE if our object has the minimal set of keys/values in it' result = 1 for key in self.MinimalKeys: if not self.has_key(key): result = None return result def log(self, args): "Log using each of the supplied logging methods" for logfcn in self._logfunctions: logfcn(string.strip(args)) def debug(self, args): "Log using each of the supplied logging methods" for logfcn in self._logfunctions: if logfcn.name() != "StdErrLog": logfcn("debug: %s" % string.strip(args)) def dump(self): keys = [] for key in self.keys(): keys.append(key) keys.sort() for key in keys: self.debug("Environment["+key+"]:\t"+str(self[key])) def run(self, Scenario, Iterations): if not Scenario: self.log("No scenario was defined") return 1 self.log("Cluster nodes: ") for node in self["nodes"]: self.log(" * %s" % (node)) self.StatsMark(0) if not Scenario.SetUp(): return 1 try : Scenario.run(Iterations) except : self.log("Exception by %s" % sys.exc_info()[0]) for logmethod in self["logger"]: traceback.print_exc(50, logmethod) Scenario.summarize() Scenario.TearDown() self.StatsExtract() return 1 #ClusterManager.oprofileSave(Iterations) Scenario.TearDown() self.StatsExtract() Scenario.summarize() if Scenario.Stats["failure"] > 0: return Scenario.Stats["failure"] elif Scenario.Stats["success"] != Iterations: self.log("No failure count but success != requested iterations") return 1 return 0 def __setitem__(self, key, value): '''Since this function gets called whenever we modify the dictionary (object), we can (and do) validate those keys that we know how to validate. For the most part, we know how to validate the "MinimalKeys" elements. ''' # # List of nodes in the system # if key == "nodes": self.Nodes = {} for node in value: # I don't think I need the IP address, etc. but this validates # the node name against /etc/hosts and/or DNS, so it's a # GoodThing(tm). try: self.Nodes[node] = gethostbyname_ex(node) except: print node+" not found in DNS... aborting" raise # # List of Logging Mechanism(s) # elif key == "logger": if len(value) < 1: raise ValueError("Must have at least one logging mechanism") for logger in value: if not callable(logger): raise ValueError("'logger' elements must be callable") self._logfunctions = value # # Cluster Manager Class # elif key == "CMclass": if value and not issubclass(value, ClusterManager): raise ValueError("'CMclass' must be a subclass of" " ClusterManager") # # Initial Random seed... # #elif key == "RandSeed": # if len(value) != 3: # raise ValueError("'Randseed' must be a 3-element list/tuple") # for elem in value: # if not isinstance(elem, types.IntType): # raise ValueError("'Randseed' list must all be ints") self.data[key] = value def IsValidNode(self, node): 'Return TRUE if the given node is valid' return self.Nodes.has_key(node) def __CheckNode(self, node): "Raise a ValueError if the given node isn't valid" if not self.IsValidNode(node): raise ValueError("Invalid node [%s] in CheckNode" % node) def RandomNode(self): '''Choose a random node from the cluster''' return self.RandomGen.choice(self["nodes"]) def StatsExtract(self): if not self["stats"]: return for host in self["nodes"]: log_stats_file = "%s/cts-stats.csv" % CTSvars.CRM_DAEMON_DIR if has_log_stats.has_key(host): self.rsh(host, '''bash %s %s stop''' % (log_stats_bin, log_stats_file)) (rc, lines) = self.rsh(host, '''cat %s''' % log_stats_file, stdout=2) self.rsh(host, '''bash %s %s delete''' % (log_stats_bin, log_stats_file)) fname = "cts-stats-%d-nodes-%s.csv" % (len(self["nodes"]), host) print "Extracted stats: %s" % fname fd = open(fname, "a") fd.writelines(lines) fd.close() def StatsMark(self, testnum): '''Mark the test number in the stats log''' global has_log_stats if not self["stats"]: return for host in self["nodes"]: log_stats_file = "%s/cts-stats.csv" % CTSvars.CRM_DAEMON_DIR if not has_log_stats.has_key(host): global log_stats global log_stats_bin script=log_stats #script = re.sub("\\\\", "\\\\", script) script = re.sub('\"', '\\\"', script) script = re.sub("'", "\'", script) script = re.sub("`", "\`", script) script = re.sub("\$", "\\\$", script) self.debug("Installing %s on %s" % (log_stats_bin, host)) self.rsh(host, '''echo "%s" > %s''' % (script, log_stats_bin), silent=True) self.rsh(host, '''bash %s %s delete''' % (log_stats_bin, log_stats_file)) has_log_stats[host] = 1 # Now mark it self.rsh(host, '''bash %s %s mark %s''' % (log_stats_bin, log_stats_file, testnum), synchronous=0) class Logger: TimeFormat = "%b %d %H:%M:%S\t" def __call__(self, lines): raise ValueError("Abstract class member (__call__)") def write(self, line): return self(line.rstrip()) def writelines(self, lines): for s in lines: self.write(s) return 1 def flush(self): return 1 def isatty(self): return None class SysLog(Logger): # http://docs.python.org/lib/module-syslog.html defaultsource="CTS" map = { "kernel": syslog.LOG_KERN, "user": syslog.LOG_USER, "mail": syslog.LOG_MAIL, "daemon": syslog.LOG_DAEMON, "auth": syslog.LOG_AUTH, "lpr": syslog.LOG_LPR, "news": syslog.LOG_NEWS, "uucp": syslog.LOG_UUCP, "cron": syslog.LOG_CRON, "local0": syslog.LOG_LOCAL0, "local1": syslog.LOG_LOCAL1, "local2": syslog.LOG_LOCAL2, "local3": syslog.LOG_LOCAL3, "local4": syslog.LOG_LOCAL4, "local5": syslog.LOG_LOCAL5, "local6": syslog.LOG_LOCAL6, "local7": syslog.LOG_LOCAL7, } def __init__(self, labinfo): if labinfo.has_key("syslogsource"): self.source=labinfo["syslogsource"] else: self.source=SysLog.defaultsource self.facility="daemon" if labinfo.has_key("SyslogFacility") and labinfo["SyslogFacility"]: if SysLog.map.has_key(labinfo["SyslogFacility"]): self.facility=labinfo["SyslogFacility"] else: raise ValueError("%s: bad syslog facility"%labinfo["SyslogFacility"]) self.facility=SysLog.map[self.facility] syslog.openlog(self.source, 0, self.facility) def setfacility(self, facility): self.facility = facility if SysLog.map.has_key(self.facility): self.facility=SysLog.map[self.facility] syslog.closelog() syslog.openlog(self.source, 0, self.facility) def __call__(self, lines): if isinstance(lines, types.StringType): syslog.syslog(lines) else: for line in lines: syslog.syslog(line) def name(self): return "Syslog" class StdErrLog(Logger): def __init__(self, labinfo): pass def __call__(self, lines): t = time.strftime(Logger.TimeFormat, time.localtime(time.time())) if isinstance(lines, types.StringType): sys.__stderr__.writelines([t, lines, "\n"]) else: for line in lines: sys.__stderr__.writelines([t, line, "\n"]) sys.__stderr__.flush() def name(self): return "StdErrLog" class FileLog(Logger): def __init__(self, labinfo, filename=None): if filename == None: filename=labinfo["LogFileName"] self.logfile=filename import os self.hostname = os.uname()[1]+" " self.source = "CTS: " def __call__(self, lines): fd = open(self.logfile, "a") t = time.strftime(Logger.TimeFormat, time.localtime(time.time())) if isinstance(lines, types.StringType): fd.writelines([t, self.hostname, self.source, lines, "\n"]) else: for line in lines: fd.writelines([t, self.hostname, self.source, line, "\n"]) fd.close() def name(self): return "FileLog" class AsyncWaitProc(Thread): def __init__(self, proc, node, command, Env): self.Env = Env self.proc = proc self.node = node self.command = command Thread.__init__(self) def log(self, args): if not self.Env: print (args) else: self.Env.log(args) def debug(self, args): if not self.Env: print (args) else: self.Env.debug(args) def run(self): self.debug("cmd: async: target=%s, pid=%d: %s" % (self.node, self.proc.pid, self.command)) self.proc.wait() self.debug("cmd: pid %d returned %d" % (self.proc.pid, self.proc.returncode)) if self.proc.stderr: lines = self.proc.stderr.readlines() self.proc.stderr.close() for line in lines: self.debug("cmd: stderr[%d]: %s" % (self.proc.pid, line)) if self.proc.stdout: lines = self.proc.stdout.readlines() self.proc.stdout.close() for line in lines: self.debug("cmd: stdout[%d]: %s" % (self.proc.pid, line)) class RemoteExec: '''This is an abstract remote execution class. It runs a command on another machine - somehow. The somehow is up to us. This particular class uses ssh. Most of the work is done by fork/exec of ssh or scp. ''' def __init__(self, Env=None, silent=False): self.Env = Env self.async = [] self.silent = silent if trace_rsh: self.silent = False # -n: no stdin, -x: no X11, # -o ServerAliveInterval=5 disconnect after 3*5s if the server stops responding self.Command = "ssh -l root -n -x -o ServerAliveInterval=5 -o ConnectTimeout=10 -o TCPKeepAlive=yes -o ServerAliveCountMax=3 " # -B: batch mode, -q: no stats (quiet) self.CpCommand = "scp -B -q" self.OurNode=string.lower(os.uname()[1]) def enable_qarsh(self): # http://nstraz.wordpress.com/2008/12/03/introducing-qarsh/ self.log("Using QARSH for connections to cluster nodes") self.Command = "qarsh -t 300 -l root" self.CpCommand = "qacp -q" def _fixcmd(self, cmd): return re.sub("\'", "'\\''", cmd) def _cmd(self, *args): '''Compute the string that will run the given command on the given remote system''' args= args[0] sysname = args[0] command = args[1] #print "sysname: %s, us: %s" % (sysname, self.OurNode) if sysname == None or string.lower(sysname) == self.OurNode or sysname == "localhost": ret = command else: ret = self.Command + " " + sysname + " '" + self._fixcmd(command) + "'" #print ("About to run %s\n" % ret) return ret def log(self, args): if not self.silent: if not self.Env: print (args) else: self.Env.log(args) def debug(self, args): if not self.silent: if not self.Env: print (args) else: self.Env.debug(args) def __call__(self, node, command, stdout=0, synchronous=1, silent=False, blocking=True): '''Run the given command on the given remote system If you call this class like a function, this is the function that gets called. It just runs it roughly as though it were a system() call on the remote machine. The first argument is name of the machine to run it on. ''' if trace_rsh: silent = False rc = 0 result = None proc = Popen(self._cmd([node, command]), stdout = PIPE, stderr = PIPE, close_fds = True, shell = True) if not synchronous and proc.pid > 0 and not self.silent: aproc = AsyncWaitProc(proc, node, command, self.Env) aproc.start() return 0 #if not blocking: # fcntl.fcntl(proc.stdout.fileno(), fcntl.F_SETFL, os.O_NONBLOCK) if proc.stdout: if stdout == 1: result = proc.stdout.readline() else: result = proc.stdout.readlines() proc.stdout.close() else: self.log("No stdout stream") rc = proc.wait() if not silent: self.debug("cmd: target=%s, rc=%d: %s" % (node, rc, command)) if stdout == 1: return result if proc.stderr: errors = proc.stderr.readlines() proc.stderr.close() if not silent: for err in errors: self.debug("cmd: stderr: %s" % err) if stdout == 0: if not silent and result: for line in result: self.debug("cmd: stdout: %s" % line) return rc return (rc, result) def cp(self, source, target, silent=False): '''Perform a remote copy''' cpstring = self.CpCommand + " \'" + source + "\'" + " \'" + target + "\'" rc = os.system(cpstring) if trace_rsh: silent = False if not silent: self.debug("cmd: rc=%d: %s" % (rc, cpstring)) return rc has_log_watcher = {} log_watcher_bin = CTSvars.CRM_DAEMON_DIR + "/cts_log_watcher.py" log_watcher = """ import sys, os, fcntl ''' Remote logfile reader for CTS Reads a specified number of lines from the supplied offset Returns the current offset Contains logic for handling truncation ''' limit = 0 offset = 0 prefix = '' filename = '/var/log/messages' skipthis=None args=sys.argv[1:] for i in range(0, len(args)): if skipthis: skipthis=None continue elif args[i] == '-l' or args[i] == '--limit': skipthis=1 limit = int(args[i+1]) elif args[i] == '-f' or args[i] == '--filename': skipthis=1 filename = args[i+1] elif args[i] == '-o' or args[i] == '--offset': skipthis=1 offset = args[i+1] elif args[i] == '-p' or args[i] == '--prefix': skipthis=1 prefix = args[i+1] elif args[i] == '-t' or args[i] == '--tag': skipthis=1 if not os.access(filename, os.R_OK): print prefix + 'Last read: %d, limit=%d, count=%d - unreadable' % (0, limit, 0) sys.exit(1) logfile=open(filename, 'r') logfile.seek(0, os.SEEK_END) newsize=logfile.tell() if offset != 'EOF': offset = int(offset) if newsize >= offset: logfile.seek(offset) else: print prefix + ('File truncated from %d to %d' % (offset, newsize)) if (newsize*1.05) < offset: logfile.seek(0) # else: we probably just lost a few logs after a fencing op # continue from the new end # TODO: accept a timestamp and discard all messages older than it # Don't block when we reach EOF fcntl.fcntl(logfile.fileno(), fcntl.F_SETFL, os.O_NONBLOCK) count = 0 while True: if logfile.tell() >= newsize: break elif limit and count >= limit: break line = logfile.readline() if not line: break print line.strip() count += 1 print prefix + 'Last read: %d, limit=%d, count=%d' % (logfile.tell(), limit, count) logfile.close() """ class SearchObj: def __init__(self, Env, filename, host=None, name=None): self.Env = Env self.host = host self.name = name self.filename = filename self.cache = [] self.offset = "EOF" if host == None: host = "localhost" global has_log_watcher if not has_log_watcher.has_key(host): global log_watcher global log_watcher_bin self.debug("Installing %s on %s" % (log_watcher_bin, host)) self.Env.rsh(host, '''echo "%s" > %s''' % (log_watcher, log_watcher_bin), silent=True) has_log_watcher[host] = 1 self.next() def __str__(self): if self.host: return "%s:%s" % (self.host, self.filename) return self.filename def log(self, args): message = "lw: %s: %s" % (self, args) if not self.Env: print (message) else: self.Env.log(message) def debug(self, args): message = "lw: %s: %s" % (self, args) if not self.Env: print (message) else: self.Env.debug(message) def next(self): cache = [] if not len(self.cache): global log_watcher_bin (rc, lines) = self.Env.rsh( self.host, "python %s -t %s -p CTSwatcher: -f %s -o %s" % (log_watcher_bin, self.name, self.filename, self.offset), stdout=None, silent=True, blocking=False) for line in lines: match = re.search("^CTSwatcher:Last read: (\d+)", line) if match: last_offset = self.offset self.offset = match.group(1) #if last_offset == "EOF": self.debug("Got %d lines, new offset: %s" % (len(lines), self.offset)) elif re.search("^CTSwatcher:.*truncated", line): self.log(line) elif re.search("^CTSwatcher:", line): self.debug("Got control line: "+ line) else: cache.append(line) return cache class LogWatcher(RemoteExec): '''This class watches logs for messages that fit certain regular expressions. Watching logs for events isn't the ideal way to do business, but it's better than nothing :-) On the other hand, this class is really pretty cool ;-) The way you use this class is as follows: Construct a LogWatcher object Call setwatch() when you want to start watching the log Call look() to scan the log looking for the patterns ''' def __init__(self, Env, log, regexes, name="Anon", timeout=10, debug_level=None, silent=False, hosts=None): '''This is the constructor for the LogWatcher class. It takes a log name to watch, and a list of regular expressions to watch for." ''' RemoteExec.__init__(self, Env) # Validate our arguments. Better sooner than later ;-) for regex in regexes: assert re.compile(regex) self.name = name self.regexes = regexes self.filename = log self.debug_level = debug_level self.whichmatch = -1 self.unmatched = None self.file_list = [] self.line_cache = [] if hosts: self.hosts = hosts else: self.hosts = self.Env["nodes"] if trace_lw: self.debug_level = 3 silent = False if not silent: for regex in self.regexes: self.debug("Looking for regex: "+regex) self.Timeout = int(timeout) self.returnonlymatch = None def debug(self, args): message = "lw: %s: %s" % (self.name, args) if not self.Env: print (message) else: self.Env.debug(message) def setwatch(self): '''Mark the place to start watching the log from. ''' if self.Env["LogWatcher"] == "remote": for node in self.hosts: self.file_list.append(SearchObj(self.Env, self.filename, node, self.name)) else: self.file_list.append(SearchObj(self.Env, self.filename)) def __del__(self): if self.debug_level > 1: self.debug("Destroy") def ReturnOnlyMatch(self, onlymatch=1): '''Specify one or more subgroups of the match to return rather than the whole string http://www.python.org/doc/2.5.2/lib/match-objects.html ''' self.returnonlymatch = onlymatch def __get_lines(self): if not len(self.file_list): raise ValueError("No sources to read from") for f in self.file_list: lines = f.next() if len(lines): self.line_cache.extend(lines) def look(self, timeout=None, silent=False): '''Examine the log looking for the given patterns. It starts looking from the place marked by setwatch(). This function looks in the file in the fashion of tail -f. It properly recovers from log file truncation, but not from removing and recreating the log. It would be nice if it recovered from this as well :-) We return the first line which matches any of our patterns. ''' if timeout == None: timeout = self.Timeout if trace_lw: silent = False lines=0 needlines=True begin=time.time() end=begin+timeout+1 if self.debug_level > 2: self.debug("starting single search: timeout=%d, begin=%d, end=%d" % (timeout, begin, end)) if not self.regexes: self.debug("Nothing to look for") return None while True: if len(self.line_cache): lines += 1 line = self.line_cache[0] self.line_cache.remove(line) which=-1 if re.search("CTS:", line): continue if self.debug_level > 2: self.debug("Processing: "+ line) for regex in self.regexes: which=which+1 if self.debug_level > 3: self.debug("Comparing line to: "+ regex) #matchobj = re.search(string.lower(regex), string.lower(line)) matchobj = re.search(regex, line) if matchobj: self.whichmatch=which if self.returnonlymatch: return matchobj.group(self.returnonlymatch) else: self.debug("Matched: "+line) if self.debug_level > 1: self.debug("With: "+ regex) return line elif timeout > 0 and end > time.time(): if self.debug_level > 1: self.debug("lines during timeout") time.sleep(1) self.__get_lines() elif needlines: # Grab any relevant messages that might have arrived since # the last time the buffer was populated if self.debug_level > 1: self.debug("lines without timeout") self.__get_lines() # Don't come back here again needlines = False else: self.debug("Single search terminated: start=%d, end=%d, now=%d, lines=%d" % (begin, end, time.time(), lines)) return None self.debug("How did we get here") return None def lookforall(self, timeout=None, allow_multiple_matches=None, silent=False): '''Examine the log looking for ALL of the given patterns. It starts looking from the place marked by setwatch(). We return when the timeout is reached, or when we have found ALL of the regexes that were part of the watch ''' if timeout == None: timeout = self.Timeout save_regexes = self.regexes returnresult = [] if trace_lw: silent = False if not silent: self.debug("starting search: timeout=%d" % timeout) for regex in self.regexes: if self.debug_level > 2: self.debug("Looking for regex: "+regex) while (len(self.regexes) > 0): oneresult = self.look(timeout) if not oneresult: self.unmatched = self.regexes self.matched = returnresult self.regexes = save_regexes return None returnresult.append(oneresult) if not allow_multiple_matches: del self.regexes[self.whichmatch] else: # Allow multiple regexes to match a single line tmp_regexes = self.regexes self.regexes = [] which = 0 for regex in tmp_regexes: matchobj = re.search(regex, oneresult) if not matchobj: self.regexes.append(regex) self.unmatched = None self.matched = returnresult self.regexes = save_regexes return returnresult class NodeStatus: def __init__(self, Env): self.Env = Env def IsNodeBooted(self, node): '''Return TRUE if the given node is booted (responds to pings)''' return self.Env.rsh("localhost", "ping -nq -c1 -w1 %s" % node, silent=True) == 0 def IsSshdUp(self, node): rc = self.Env.rsh(node, "true", silent=True) return rc == 0 def WaitForNodeToComeUp(self, node, Timeout=300): '''Return TRUE when given node comes up, or None/FALSE if timeout''' timeout=Timeout anytimeouts=0 while timeout > 0: if self.IsNodeBooted(node) and self.IsSshdUp(node): if anytimeouts: # Fudge to wait for the system to finish coming up time.sleep(30) self.Env.debug("Node %s now up" % node) return 1 time.sleep(30) if (not anytimeouts): self.Env.debug("Waiting for node %s to come up" % node) anytimeouts=1 timeout = timeout - 1 self.Env.log("%s did not come up within %d tries" % (node, Timeout)) answer = raw_input('Continue? [nY]') if answer and answer == "n": raise ValueError("%s did not come up within %d tries" % (node, Timeout)) def WaitForAllNodesToComeUp(self, nodes, timeout=300): '''Return TRUE when all nodes come up, or FALSE if timeout''' for node in nodes: if not self.WaitForNodeToComeUp(node, timeout): return None return 1 class ClusterManager(UserDict): '''The Cluster Manager class. This is an subclass of the Python dictionary class. (this is because it contains lots of {name,value} pairs, not because it's behavior is that terribly similar to a dictionary in other ways.) This is an abstract class which class implements high-level operations on the cluster and/or its cluster managers. Actual cluster managers classes are subclassed from this type. One of the things we do is track the state we think every node should be in. ''' def __InitialConditions(self): #if os.geteuid() != 0: # raise ValueError("Must Be Root!") None def _finalConditions(self): for key in self.keys(): if self[key] == None: raise ValueError("Improper derivation: self[" + key + "] must be overridden by subclass.") def __init__(self, Environment, randseed=None): self.Env = Environment self.__InitialConditions() self.clear_cache = 0 self.TestLoggingLevel=0 self.data = { "up" : "up", # Status meaning up "down" : "down", # Status meaning down "StonithCmd" : "stonith -t baytech -p '10.10.10.100 admin admin' %s", "DeadTime" : 30, # Max time to detect dead node... "StartTime" : 90, # Max time to start up # # These next values need to be overridden in the derived class. # "Name" : None, "StartCmd" : None, "StopCmd" : None, "StatusCmd" : None, #"RereadCmd" : None, "BreakCommCmd" : None, "FixCommCmd" : None, #"TestConfigDir" : None, "LogFileName" : None, #"Pat:Master_started" : None, #"Pat:Slave_started" : None, "Pat:We_stopped" : None, "Pat:They_stopped" : None, "Pat:InfraUp" : "%s", "Pat:PacemakerUp" : "%s", "BadRegexes" : None, # A set of "bad news" regexes # to apply to the log } self.rsh = self.Env.rsh self.ShouldBeStatus={} self.ns = NodeStatus(self.Env) self.OurNode=string.lower(os.uname()[1]) self.__instance_errorstoignore = [] def key_for_node(self, node): return node def instance_errorstoignore_clear(self): '''Allows the test scenario to reset instance errors to ignore on each iteration.''' self.__instance_errorstoignore = [] def instance_errorstoignore(self): '''Return list of errors which are 'normal' for a specific test instance''' return self.__instance_errorstoignore def errorstoignore(self): '''Return list of errors which are 'normal' and should be ignored''' return [] def log(self, args): self.Env.log(args) def debug(self, args): self.Env.debug(args) def prepare(self): '''Finish the Initialization process. Prepare to test...''' for node in self.Env["nodes"]: if self.StataCM(node): self.ShouldBeStatus[node]="up" else: self.ShouldBeStatus[node]="down" self.unisolate_node(node) def upcount(self): '''How many nodes are up?''' count=0 for node in self.Env["nodes"]: if self.ShouldBeStatus[node]=="up": count=count+1 return count def install_helper(self, filename, destdir=None, nodes=None, sourcedir=None): if sourcedir == None: sourcedir = CTSvars.CTS_home file_with_path="%s/%s" % (sourcedir, filename) if not nodes: nodes = self.Env["nodes"] if not destdir: destdir=CTSvars.CTS_home self.debug("Installing %s to %s on %s" % (filename, destdir, repr(self.Env["nodes"]))) for node in nodes: self.rsh(node, "mkdir -p %s" % destdir) self.rsh.cp(file_with_path, "root@%s:%s/%s" % (node, destdir, filename)) return file_with_path def install_config(self, node): return None def clear_all_caches(self): if self.clear_cache: for node in self.Env["nodes"]: if self.ShouldBeStatus[node] == "down": self.debug("Removing cache file on: "+node) self.rsh(node, "rm -f "+CTSvars.HA_VARLIBHBDIR+"/hostcache") else: self.debug("NOT Removing cache file on: "+node) def prepare_fencing_watcher(self, node): # If we don't have quorum now but get it as a result of starting this node, # then a bunch of nodes might get fenced upnode=None if self.HasQuorum(None): return None if not self.has_key("Pat:Fencing_start"): return None if not self.has_key("Pat:Fencing_ok"): return None stonith = None stonithPats = [] for peer in self.Env["nodes"]: if peer != node and self.ShouldBeStatus[peer] != "up": stonithPats.append(self["Pat:Fencing_ok"] % peer) stonithPats.append(self["Pat:Fencing_start"] % peer) elif self.Env["Stack"] == "corosync (cman)": # There is a delay between gaining quorum and CMAN starting fencing # This can mean that even nodes that are fully up get fenced # There is no use fighting it, just look for everyone so that CTS doesn't get confused stonithPats.append(self["Pat:Fencing_ok"] % peer) stonithPats.append(self["Pat:Fencing_start"] % peer) if peer != node and not upnode and self.ShouldBeStatus[peer] == "up": upnode = peer # Look for STONITH ops, depending on Env["at-boot"] we might need to change the nodes status if not upnode: return None stonith = LogWatcher(self.Env, self["LogFileName"], stonithPats, "StartupFencing", 0, hosts=[upnode]) stonith.setwatch() return stonith def fencing_cleanup(self, node, stonith): peer_list = [] peer_state = {} self.debug("Looking for nodes that were fenced as a result of %s starting" % node) # If we just started a node, we may now have quorum (and permission to fence) if not stonith: self.debug("Nothing to do") return peer_list q = self.HasQuorum(None) if not q and len(self.Env["nodes"]) > 2: # We didn't gain quorum - we shouldn't have shot anyone self.debug("Quorum: %d Len: %d" % (q, len(self.Env["nodes"]))) return peer_list # Now see if any states need to be updated self.debug("looking for: " + repr(stonith.regexes)) shot = stonith.look(0) while shot: line = repr(shot) self.debug("Found: "+ line) del stonith.regexes[stonith.whichmatch] # Extract node name for n in self.Env["nodes"]: if re.search(self["Pat:Fencing_ok"] % n, shot): peer = n peer_state[peer] = "complete" self.__instance_errorstoignore.append(self["Pat:Fencing_ok"] % peer) elif re.search(self["Pat:Fencing_start"] % n, shot): peer = n peer_state[peer] = "in-progress" self.__instance_errorstoignore.append(self["Pat:Fencing_start"] % peer) if not peer: self.log("ERROR: Unknown stonith match: %s" % line) elif not peer in peer_list: self.debug("Found peer: "+ peer) peer_list.append(peer) # Get the next one shot = stonith.look(60) for peer in peer_list: self.debug(" Peer %s was fenced as a result of %s starting: %s" % (peer, node, peer_state[peer])) if self.Env["at-boot"]: self.ShouldBeStatus[peer] = "up" else: self.ShouldBeStatus[peer] = "down" if peer_state[peer] == "in-progress": # Wait for any in-progress operations to complete shot = stonith.look(60) while len(stonith.regexes) and shot: line = repr(shot) self.debug("Found: "+ line) del stonith.regexes[stonith.whichmatch] shot = stonith.look(60) # Now make sure the node is alive too self.ns.WaitForNodeToComeUp(peer, self["DeadTime"]) # Poll until it comes up if self.Env["at-boot"]: if not self.StataCM(peer): time.sleep(self["StartTime"]) if not self.StataCM(peer): self.log("ERROR: Peer %s failed to restart after being fenced" % peer) return None return peer_list def StartaCM(self, node, verbose=False): '''Start up the cluster manager on a given node''' if verbose: self.log("Starting %s on node %s" %(self["Name"], node)) else: self.debug("Starting %s on node %s" %(self["Name"], node)) ret = 1 if not self.ShouldBeStatus.has_key(node): self.ShouldBeStatus[node] = "down" if self.ShouldBeStatus[node] != "down": return 1 patterns = [] # Technically we should always be able to notice ourselves starting patterns.append(self["Pat:Local_started"] % node) if self.upcount() == 0: patterns.append(self["Pat:Master_started"] % node) else: patterns.append(self["Pat:Slave_started"] % node) watch = LogWatcher( self.Env, self["LogFileName"], patterns, "StartaCM", self["StartTime"]+10) self.install_config(node) self.ShouldBeStatus[node] = "any" if self.StataCM(node) and self.cluster_stable(self["DeadTime"]): self.log ("%s was already started" %(node)) return 1 # Clear out the host cache so autojoin can be exercised if self.clear_cache: self.debug("Removing cache file on: "+node) self.rsh(node, "rm -f "+CTSvars.HA_VARLIBHBDIR+"/hostcache") if not(self.Env["valgrind-tests"]): startCmd = self["StartCmd"] else: if self.Env["valgrind-prefix"]: prefix = self.Env["valgrind-prefix"] else: prefix = "cts" startCmd = """G_SLICE=always-malloc HA_VALGRIND_ENABLED='%s' VALGRIND_OPTS='%s --log-file=/tmp/%s-%s.valgrind' %s""" % ( self.Env["valgrind-procs"], self.Env["valgrind-opts"], prefix, """%p""", self["StartCmd"]) stonith = self.prepare_fencing_watcher(node) watch.setwatch() if self.rsh(node, startCmd) != 0: self.log ("Warn: Start command failed on node %s" %(node)) self.fencing_cleanup(node, stonith) return None self.ShouldBeStatus[node]="up" watch_result = watch.lookforall() if watch.unmatched: for regex in watch.unmatched: self.log ("Warn: Startup pattern not found: %s" %(regex)) if watch_result and self.cluster_stable(self["DeadTime"]): #self.debug("Found match: "+ repr(watch_result)) self.fencing_cleanup(node, stonith) return 1 elif self.StataCM(node) and self.cluster_stable(self["DeadTime"]): self.fencing_cleanup(node, stonith) return 1 self.log ("Warn: Start failed for node %s" %(node)) return None def StartaCMnoBlock(self, node, verbose=False): '''Start up the cluster manager on a given node with none-block mode''' if verbose: self.log("Starting %s on node %s" %(self["Name"], node)) else: self.debug("Starting %s on node %s" %(self["Name"], node)) # Clear out the host cache so autojoin can be exercised if self.clear_cache: self.debug("Removing cache file on: "+node) self.rsh(node, "rm -f "+CTSvars.HA_VARLIBHBDIR+"/hostcache") if not(self.Env["valgrind-tests"]): startCmd = self["StartCmd"] else: if self.Env["valgrind-prefix"]: prefix = self.Env["valgrind-prefix"] else: prefix = "cts" startCmd = """G_SLICE=always-malloc HA_VALGRIND_ENABLED='%s' VALGRIND_OPTS='%s --log-file=/tmp/%s-%s.valgrind' %s""" % ( self.Env["valgrind-procs"], self.Env["valgrind-opts"], prefix, """%p""", self["StartCmd"]) self.rsh(node, startCmd, synchronous=0) self.ShouldBeStatus[node]="up" return 1 def StopaCM(self, node, verbose=False): '''Stop the cluster manager on a given node''' if verbose: self.log("Stopping %s on node %s" %(self["Name"], node)) else: self.debug("Stopping %s on node %s" %(self["Name"], node)) if self.ShouldBeStatus[node] != "up": return 1 if self.rsh(node, self["StopCmd"]) == 0: # Make sure we can continue even if corosync leaks # fdata-* is the old name #self.rsh(node, "rm -f /dev/shm/qb-* /dev/shm/fdata-*") self.ShouldBeStatus[node]="down" self.cluster_stable(self["DeadTime"]) return 1 else: self.log ("ERROR: Could not stop %s on node %s" %(self["Name"], node)) return None def StopaCMnoBlock(self, node): '''Stop the cluster manager on a given node with none-block mode''' self.debug("Stopping %s on node %s" %(self["Name"], node)) self.rsh(node, self["StopCmd"], synchronous=0) self.ShouldBeStatus[node]="down" return 1 def cluster_stable(self, timeout = None): time.sleep(self["StableTime"]) return 1 def node_stable(self, node): return 1 def RereadCM(self, node): '''Force the cluster manager on a given node to reread its config This may be a no-op on certain cluster managers. ''' rc=self.rsh(node, self["RereadCmd"]) if rc == 0: return 1 else: self.log ("Could not force %s on node %s to reread its config" % (self["Name"], node)) return None def StataCM(self, node): '''Report the status of the cluster manager on a given node''' out=self.rsh(node, self["StatusCmd"] % node, 1) ret= (string.find(out, 'stopped') == -1) try: if ret: if self.ShouldBeStatus[node] == "down": self.log( "Node status for %s is %s but we think it should be %s" % (node, "up", self.ShouldBeStatus[node])) else: if self.ShouldBeStatus[node] == "up": self.log( "Node status for %s is %s but we think it should be %s" % (node, "down", self.ShouldBeStatus[node])) except KeyError: pass if ret: self.ShouldBeStatus[node]="up" else: self.ShouldBeStatus[node]="down" return ret def startall(self, nodelist=None, verbose=False, quick=False): '''Start the cluster manager on every node in the cluster. We can do it on a subset of the cluster if nodelist is not None. ''' map = {} if not nodelist: nodelist=self.Env["nodes"] for node in nodelist: if self.ShouldBeStatus[node] == "down": self.ns.WaitForAllNodesToComeUp(nodelist, 300) if not quick: if not self.StartaCM(node, verbose=verbose): return 0 return 1 # Approximation of SimulStartList for --boot watchpats = [ ] watchpats.append(self["Pat:DC_IDLE"]) for node in nodelist: watchpats.append(self["Pat:Local_started"] % node) watchpats.append(self["Pat:InfraUp"] % node) watchpats.append(self["Pat:PacemakerUp"] % node) # Start all the nodes - at about the same time... watch = LogWatcher(self.Env, self["LogFileName"], watchpats, "fast-start", self["DeadTime"]+10) watch.setwatch() if not self.StartaCM(nodelist[0], verbose=verbose): return 0 for node in nodelist: self.StartaCMnoBlock(node, verbose=verbose) watch.lookforall() if watch.unmatched: for regex in watch.unmatched: self.log ("Warn: Startup pattern not found: %s" %(regex)) if not self.cluster_stable(): self.log("Cluster did not stabilize") return 0 return 1 def stopall(self, nodelist=None, verbose=False): '''Stop the cluster managers on every node in the cluster. We can do it on a subset of the cluster if nodelist is not None. ''' ret = 1 map = {} if not nodelist: nodelist=self.Env["nodes"] for node in self.Env["nodes"]: if self.ShouldBeStatus[node] == "up": if not self.StopaCM(node, verbose=verbose): ret = 0 return ret def rereadall(self, nodelist=None): '''Force the cluster managers on every node in the cluster to reread their config files. We can do it on a subset of the cluster if nodelist is not None. ''' map = {} if not nodelist: nodelist=self.Env["nodes"] for node in self.Env["nodes"]: if self.ShouldBeStatus[node] == "up": self.RereadCM(node) def statall(self, nodelist=None): '''Return the status of the cluster managers in the cluster. We can do it on a subset of the cluster if nodelist is not None. ''' result={} if not nodelist: nodelist=self.Env["nodes"] for node in nodelist: if self.StataCM(node): result[node] = "up" else: result[node] = "down" return result def isolate_node(self, target, nodes=None): '''isolate the communication between the nodes''' if not nodes: nodes = self.Env["nodes"] for node in nodes: if node != target: rc = self.rsh(target, self["BreakCommCmd"] % self.key_for_node(node)) if rc != 0: self.log("Could not break the communication between %s and %s: %d" % (target, node, rc)) return None else: self.debug("Communication cut between %s and %s" % (target, node)) return 1 def unisolate_node(self, target, nodes=None): '''fix the communication between the nodes''' if not nodes: nodes = self.Env["nodes"] for node in nodes: if node != target: restored = 0 # Limit the amount of time we have asynchronous connectivity for # Restore both sides as simultaneously as possible self.rsh(target, self["FixCommCmd"] % self.key_for_node(node), synchronous=0) self.rsh(node, self["FixCommCmd"] % self.key_for_node(target), synchronous=0) self.debug("Communication restored between %s and %s" % (target, node)) def reducecomm_node(self,node): '''reduce the communication between the nodes''' rc = self.rsh(node, self["ReduceCommCmd"]%(self.Env["XmitLoss"],self.Env["RecvLoss"])) if rc == 0: return 1 else: self.log("Could not reduce the communication between the nodes from node: %s" % node) return None def restorecomm_node(self,node): '''restore the saved communication between the nodes''' rc = 0 if float(self.Env["XmitLoss"])!=0 or float(self.Env["RecvLoss"])!=0 : rc = self.rsh(node, self["RestoreCommCmd"]); if rc == 0: return 1 else: self.log("Could not restore the communication between the nodes from node: %s" % node) return None def HasQuorum(self, node_list): "Return TRUE if the cluster currently has quorum" # If we are auditing a partition, then one side will # have quorum and the other not. # So the caller needs to tell us which we are checking # If no value for node_list is specified... assume all nodes raise ValueError("Abstract Class member (HasQuorum)") def Components(self): raise ValueError("Abstract Class member (Components)") def oprofileStart(self, node=None): if not node: for n in self.Env["oprofile"]: self.oprofileStart(n) elif node in self.Env["oprofile"]: self.debug("Enabling oprofile on %s" % node) self.rsh(node, "opcontrol --init") self.rsh(node, "opcontrol --setup --no-vmlinux --separate=lib --callgraph=20 --image=all") self.rsh(node, "opcontrol --start") self.rsh(node, "opcontrol --reset") def oprofileSave(self, test, node=None): if not node: for n in self.Env["oprofile"]: self.oprofileSave(test, n) elif node in self.Env["oprofile"]: self.rsh(node, "opcontrol --dump") self.rsh(node, "opcontrol --save=cts.%d" % test) # Read back with: opreport -l session:cts.0 image:/usr/lib/heartbeat/c* if None: self.rsh(node, "opcontrol --reset") else: self.oprofileStop(node) self.oprofileStart(node) def oprofileStop(self, node=None): if not node: for n in self.Env["oprofile"]: self.oprofileStop(n) elif node in self.Env["oprofile"]: self.debug("Stopping oprofile on %s" % node) self.rsh(node, "opcontrol --reset") self.rsh(node, "opcontrol --shutdown 2>&1 > /dev/null") class Resource: ''' This is an HA resource (not a resource group). A resource group is just an ordered list of Resource objects. ''' def __init__(self, cm, rsctype=None, instance=None): self.CM = cm self.ResourceType = rsctype self.Instance = instance self.needs_quorum = 1 def Type(self): return self.ResourceType def Instance(self, nodename): return self.Instance def IsRunningOn(self, nodename): ''' This member function returns true if our resource is running on the given node in the cluster. It is analagous to the "status" operation on SystemV init scripts and heartbeat scripts. FailSafe calls it the "exclusive" operation. ''' raise ValueError("Abstract Class member (IsRunningOn)") return None def IsWorkingCorrectly(self, nodename): ''' This member function returns true if our resource is operating correctly on the given node in the cluster. Heartbeat does not require this operation, but it might be called the Monitor operation, which is what FailSafe calls it. For remotely monitorable resources (like IP addresses), they *should* be monitored remotely for testing. ''' raise ValueError("Abstract Class member (IsWorkingCorrectly)") return None def Start(self, nodename): ''' This member function starts or activates the resource. ''' raise ValueError("Abstract Class member (Start)") return None def Stop(self, nodename): ''' This member function stops or deactivates the resource. ''' raise ValueError("Abstract Class member (Stop)") return None def __repr__(self): if (self.Instance and len(self.Instance) > 1): return "{" + self.ResourceType + "::" + self.Instance + "}" else: return "{" + self.ResourceType + "}" class Component: def kill(self, node): None class Process(Component): def __init__(self, cm, name, process=None, dc_only=0, pats=[], dc_pats=[], badnews_ignore=[], common_ignore=[], triggersreboot=0): self.name = str(name) self.dc_only = dc_only self.pats = pats self.dc_pats = dc_pats self.CM = cm self.badnews_ignore = badnews_ignore self.badnews_ignore.extend(common_ignore) self.triggersreboot = triggersreboot if process: self.proc = str(process) else: self.proc = str(name) self.KillCmd = "killall -9 " + self.proc def kill(self, node): if self.CM.rsh(node, self.KillCmd) != 0: self.CM.log ("ERROR: Kill %s failed on node %s" %(self.name,node)) return None return 1 pacemaker-master/cts/CTSaudits.py000077500000000000000000000703651217637305600173350ustar00rootroot00000000000000'''CTS: Cluster Testing System: Audit module ''' __copyright__=''' Copyright (C) 2000, 2001,2005 Alan Robertson Licensed under the GNU GPL. ''' # # 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 2 # of the License, 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 St, Fifth Floor, Boston, MA 02110-1301 USA. import time, os, string, re import CTS class ClusterAudit: def __init__(self, cm): self.CM = cm def __call__(self): raise ValueError("Abstract Class member (__call__)") def is_applicable(self): '''Return TRUE if we are applicable in the current test configuration''' raise ValueError("Abstract Class member (is_applicable)") return 1 def log(self, args): self.CM.log("audit: %s" % args) def debug(self, args): self.CM.debug("audit: %s" % args) def name(self): raise ValueError("Abstract Class member (name)") AllAuditClasses = [ ] class LogAudit(ClusterAudit): def name(self): return "LogAudit" def __init__(self, cm): self.CM = cm def RestartClusterLogging(self, nodes=None): if not nodes: nodes = self.CM.Env["nodes"] self.CM.debug("Restarting logging on: %s" % repr(nodes)) for node in nodes: cmd="service %s restart 2>&1 > /dev/null" % self.CM.Env["syslogd"] if self.CM.rsh(node, cmd, synchronous=0) != 0: self.CM.log ("ERROR: Cannot restart logging on %s [%s failed]" % (node, cmd)) def TestLogging(self): patterns = [] prefix = "Test message from" watch_syslog = None watch_remote = None for node in self.CM.Env["nodes"]: # Look for the node name in two places to make sure # that syslog is logging with the correct hostname m = re.search("^([^.]+).*", node) if m: simple = m.group(1) else: simple = node patterns.append("%s.*%s %s" % (simple, prefix, node)) watch_pref = self.CM.Env["LogWatcher"] if watch_pref == "any" or watch_pref == "syslog": self.CM.Env["LogWatcher"] = "syslog" if watch_pref == "any": self.CM.log("Testing for %s logs" % self.CM.Env["LogWatcher"]) watch_syslog = CTS.LogWatcher(self.CM.Env, self.CM.Env["LogFileName"], patterns, "LogAudit", 5, silent=True) watch_syslog.setwatch() if watch_pref == "any" or watch_pref == "remote": self.CM.Env["LogWatcher"] = "remote" if watch_pref == "any": self.CM.log("Testing for %s logs" % self.CM.Env["LogWatcher"]) watch_remote = CTS.LogWatcher(self.CM.Env, self.CM.Env["LogFileName"], patterns, "LogAudit", 5, silent=True) watch_remote.setwatch() for node in self.CM.Env["nodes"]: cmd="logger -p %s.info %s %s" % (self.CM.Env["SyslogFacility"], prefix, node) if self.CM.rsh(node, cmd, synchronous=0, silent=True) != 0: self.CM.log ("ERROR: Cannot execute remote command [%s] on %s" % (cmd, node)) if watch_syslog: watch = watch_syslog self.CM.Env["LogWatcher"] = "syslog" watch_result = watch.lookforall(silent=True) if not watch.unmatched: if watch_pref == "any": self.CM.log ("Continuing with %s-based log reader" % (self.CM.Env["LogWatcher"])) return 1 if watch_remote: watch = watch_remote self.CM.Env["LogWatcher"] = "remote" watch_result = watch.lookforall(silent=True) if not watch.unmatched: if watch_pref == "any": self.CM.log ("Continuing with %s-based log reader" % (self.CM.Env["LogWatcher"])) return 1 if watch_syslog and watch_syslog.unmatched: for regex in watch_syslog.unmatched: self.CM.log ("Test message [%s] not found in syslog logs." % regex) if watch_remote and watch_remote.unmatched: for regex in watch_remote.unmatched: self.CM.log ("Test message [%s] not found in remote logs." % regex) return 0 def __call__(self): max=3 attempt=0 self.CM.ns.WaitForAllNodesToComeUp(self.CM.Env["nodes"]) while attempt <= max and self.TestLogging() == 0: attempt = attempt + 1 self.RestartClusterLogging() time.sleep(60*attempt) if attempt > max: self.CM.log("ERROR: Cluster logging unrecoverable.") return 0 return 1 def is_applicable(self): if self.CM.Env["DoBSC"]: return 0 return 1 class DiskAudit(ClusterAudit): def name(self): return "DiskspaceAudit" def __init__(self, cm): self.CM = cm def __call__(self): result=1 dfcmd="df -k /var/log | tail -1 | tr -s ' ' | cut -d' ' -f2" self.CM.ns.WaitForAllNodesToComeUp(self.CM.Env["nodes"]) for node in self.CM.Env["nodes"]: dfout=self.CM.rsh(node, dfcmd, 1) if not dfout: self.CM.log ("ERROR: Cannot execute remote df command [%s] on %s" % (dfcmd, node)) else: try: idfout = int(dfout) except (ValueError, TypeError): self.CM.log("Warning: df output from %s was invalid [%s]" % (node, dfout)) else: if idfout == 0: self.CM.log("CRIT: Completely out of log disk space on %s" % node) result=None elif idfout <= 1000: self.CM.log("WARN: Low on log disk space (%d Mbytes) on %s" % (idfout, node)) return result def is_applicable(self): if self.CM.Env["DoBSC"]: return 0 return 1 class FileAudit(ClusterAudit): def name(self): return "FileAudit" def __init__(self, cm): self.CM = cm self.known = [] def __call__(self): result=1 self.CM.ns.WaitForAllNodesToComeUp(self.CM.Env["nodes"]) for node in self.CM.Env["nodes"]: (rc, lsout)=self.CM.rsh(node, "ls -al /var/lib/heartbeat/cores/* | grep core.[0-9]", None) for line in lsout: line = line.strip() if line not in self.known: result=0 self.known.append(line) self.CM.log("Warning: Pacemaker core file on %s: %s" % (node, line)) (rc, lsout)=self.CM.rsh(node, "ls -al /var/lib/corosync | grep core.[0-9]", None) for line in lsout: line = line.strip() if line not in self.known: result=0 self.known.append(line) self.CM.log("Warning: Corosync core file on %s: %s" % (node, line)) if self.CM.ShouldBeStatus.has_key(node) and self.CM.ShouldBeStatus[node] == "down": clean=0 (rc, lsout)=self.CM.rsh(node, "ls -al /dev/shm | grep qb-", None) for line in lsout: result=0 clean=1 self.CM.log("Warning: Stale IPC file on %s: %s" % (node, line)) if clean: (rc, lsout)=self.CM.rsh(node, "ps axf | grep -e pacemaker -e corosync", None) for line in lsout: self.CM.debug("ps[%s]: %s" % (node, line)) self.CM.rsh(node, "rm -f /dev/shm/qb-*") else: self.CM.debug("Skipping %s" % node) return result def is_applicable(self): return 1 class AuditResource: def __init__(self, cm, line): fields = line.split() self.CM = cm self.line = line self.type = fields[1] self.id = fields[2] self.clone_id = fields[3] self.parent = fields[4] self.rprovider = fields[5] self.rclass = fields[6] self.rtype = fields[7] self.host = fields[8] self.needs_quorum = fields[9] self.flags = int(fields[10]) self.flags_s = fields[11] if self.parent == "NA": self.parent = None def unique(self): if self.flags & int("0x00000020", 16): return 1 return 0 def orphan(self): if self.flags & int("0x00000001", 16): return 1 return 0 def managed(self): if self.flags & int("0x00000002", 16): return 1 return 0 class AuditConstraint: def __init__(self, cm, line): fields = line.split() self.CM = cm self.line = line self.type = fields[1] self.id = fields[2] self.rsc = fields[3] self.target = fields[4] self.score = fields[5] self.rsc_role = fields[6] self.target_role = fields[7] if self.rsc_role == "NA": self.rsc_role = None if self.target_role == "NA": self.target_role = None class PrimitiveAudit(ClusterAudit): def name(self): return "PrimitiveAudit" def __init__(self, cm): self.CM = cm def doResourceAudit(self, resource, quorum): rc=1 active = self.CM.ResourceLocation(resource.id) if len(active) == 1: if quorum: self.debug("Resource %s active on %s" % (resource.id, repr(active))) elif resource.needs_quorum == 1: self.CM.log("Resource %s active without quorum: %s" % (resource.id, repr(active))) rc=0 elif not resource.managed(): self.CM.log("Resource %s not managed. Active on %s" % (resource.id, repr(active))) elif not resource.unique(): # TODO: Figure out a clever way to actually audit these resource types if len(active) > 1: self.debug("Non-unique resource %s is active on: %s" % (resource.id, repr(active))) else: self.debug("Non-unique resource %s is not active" % resource.id) elif len(active) > 1: self.CM.log("Resource %s is active multiple times: %s" % (resource.id, repr(active))) rc=0 elif resource.orphan(): self.debug("Resource %s is an inactive orphan" % resource.id) elif len(self.inactive_nodes) == 0: self.CM.log("WARN: Resource %s not served anywhere" % resource.id) rc=0 elif self.CM.Env["warn-inactive"] == 1: if quorum or not resource.needs_quorum: self.CM.log("WARN: Resource %s not served anywhere (Inactive nodes: %s)" % (resource.id, repr(self.inactive_nodes))) else: self.debug("Resource %s not served anywhere (Inactive nodes: %s)" % (resource.id, repr(self.inactive_nodes))) elif quorum or not resource.needs_quorum: self.debug("Resource %s not served anywhere (Inactive nodes: %s)" % (resource.id, repr(self.inactive_nodes))) return rc def setup(self): self.target = None self.resources = [] self.constraints = [] self.active_nodes = [] self.inactive_nodes = [] for node in self.CM.Env["nodes"]: if self.CM.ShouldBeStatus[node] == "up": self.active_nodes.append(node) else: self.inactive_nodes.append(node) for node in self.CM.Env["nodes"]: if self.target == None and self.CM.ShouldBeStatus[node] == "up": self.target = node if not self.target: # TODO: In Pacemaker 1.0 clusters we'll be able to run crm_resource # with CIB_file=/path/to/cib.xml even when the cluster isn't running self.debug("No nodes active - skipping %s" % self.name()) return 0 (rc, lines) = self.CM.rsh(self.target, "crm_resource -c", None) for line in lines: if re.search("^Resource", line): self.resources.append(AuditResource(self.CM, line)) elif re.search("^Constraint", line): self.constraints.append(AuditConstraint(self.CM, line)) else: self.CM.log("Unknown entry: %s" % line); return 1 def __call__(self): rc = 1 if not self.setup(): return 1 quorum = self.CM.HasQuorum(None) for resource in self.resources: if resource.type == "primitive": if self.doResourceAudit(resource, quorum) == 0: rc = 0 return rc def is_applicable(self): if self.CM["Name"] == "crm-lha": return 1 if self.CM["Name"] == "crm-ais": return 1 return 0 class GroupAudit(PrimitiveAudit): def name(self): return "GroupAudit" def __call__(self): rc = 1 if not self.setup(): return 1 for group in self.resources: if group.type == "group": first_match = 1 group_location = None for child in self.resources: if child.parent == group.id: nodes = self.CM.ResourceLocation(child.id) if first_match and len(nodes) > 0: group_location = nodes[0] first_match = 0 if len(nodes) > 1: rc = 0 self.CM.log("Child %s of %s is active more than once: %s" % (child.id, group.id, repr(nodes))) elif len(nodes) == 0: # Groups are allowed to be partially active # However we do need to make sure later children aren't running group_location = None self.debug("Child %s of %s is stopped" % (child.id, group.id)) elif nodes[0] != group_location: rc = 0 self.CM.log("Child %s of %s is active on the wrong node (%s) expected %s" % (child.id, group.id, nodes[0], group_location)) else: self.debug("Child %s of %s is active on %s" % (child.id, group.id, nodes[0])) return rc class CloneAudit(PrimitiveAudit): def name(self): return "CloneAudit" def __call__(self): rc = 1 if not self.setup(): return 1 for clone in self.resources: if clone.type == "clone": for child in self.resources: if child.parent == clone.id and child.type == "primitive": self.debug("Checking child %s of %s..." % (child.id, clone.id)) # Check max and node_max # Obtain with: # crm_resource -g clone_max --meta -r child.id # crm_resource -g clone_node_max --meta -r child.id return rc class ColocationAudit(PrimitiveAudit): def name(self): return "ColocationAudit" def crm_location(self, resource): (rc, lines) = self.CM.rsh(self.target, "crm_resource -W -r %s -Q"%resource, None) hosts = [] if rc == 0: for line in lines: fields = line.split() hosts.append(fields[0]) return hosts def __call__(self): rc = 1 if not self.setup(): return 1 for coloc in self.constraints: if coloc.type == "rsc_colocation": source = self.crm_location(coloc.rsc) target = self.crm_location(coloc.target) if len(source) == 0: self.debug("Colocation audit (%s): %s not running" % (coloc.id, coloc.rsc)) else: for node in source: if not node in target: rc = 0 self.CM.log("Colocation audit (%s): %s running on %s (not in %s)" % (coloc.id, coloc.rsc, node, repr(target))) else: self.debug("Colocation audit (%s): %s running on %s (in %s)" % (coloc.id, coloc.rsc, node, repr(target))) return rc class CrmdStateAudit(ClusterAudit): def __init__(self, cm): self.CM = cm self.Stats = {"calls":0 , "success":0 , "failure":0 , "skipped":0 , "auditfail":0} def has_key(self, key): return self.Stats.has_key(key) def __setitem__(self, key, value): self.Stats[key] = value def __getitem__(self, key): return self.Stats[key] def incr(self, name): '''Increment (or initialize) the value associated with the given name''' if not self.Stats.has_key(name): self.Stats[name]=0 self.Stats[name] = self.Stats[name]+1 def __call__(self): passed = 1 up_are_down = 0 down_are_up = 0 unstable_list = [] for node in self.CM.Env["nodes"]: should_be = self.CM.ShouldBeStatus[node] rc = self.CM.test_node_CM(node) if rc > 0: if should_be == "down": down_are_up = down_are_up + 1 if rc == 1: unstable_list.append(node) elif should_be == "up": up_are_down = up_are_down + 1 if len(unstable_list) > 0: passed = 0 self.CM.log("Cluster is not stable: %d (of %d): %s" %(len(unstable_list), self.CM.upcount(), repr(unstable_list))) if up_are_down > 0: passed = 0 self.CM.log("%d (of %d) nodes expected to be up were down." %(up_are_down, len(self.CM.Env["nodes"]))) if down_are_up > 0: passed = 0 self.CM.log("%d (of %d) nodes expected to be down were up." %(down_are_up, len(self.CM.Env["nodes"]))) return passed def name(self): return "CrmdStateAudit" def is_applicable(self): if self.CM["Name"] == "crm-lha": return 1 if self.CM["Name"] == "crm-ais": return 1 return 0 class CIBAudit(ClusterAudit): def __init__(self, cm): self.CM = cm self.Stats = {"calls":0 , "success":0 , "failure":0 , "skipped":0 , "auditfail":0} def has_key(self, key): return self.Stats.has_key(key) def __setitem__(self, key, value): self.Stats[key] = value def __getitem__(self, key): return self.Stats[key] def incr(self, name): '''Increment (or initialize) the value associated with the given name''' if not self.Stats.has_key(name): self.Stats[name]=0 self.Stats[name] = self.Stats[name]+1 def __call__(self): passed = 1 ccm_partitions = self.CM.find_partitions() if len(ccm_partitions) == 0: self.debug("\tNo partitions to audit") return 1 for partition in ccm_partitions: self.debug("\tAuditing CIB consistency for: %s" %partition) partition_passed = 0 if self.audit_cib_contents(partition) == 0: passed = 0 return passed def audit_cib_contents(self, hostlist): passed = 1 node0 = None node0_xml = None partition_hosts = hostlist.split() for node in partition_hosts: node_xml = self.store_remote_cib(node, node0) if node_xml == None: self.CM.log("Could not perform audit: No configuration from %s" % node) passed = 0 elif node0 == None: node0 = node node0_xml = node_xml elif node0_xml == None: self.CM.log("Could not perform audit: No configuration from %s" % node0) passed = 0 else: (rc, result) = self.CM.rsh( node0, "crm_diff -VV -cf --new %s --original %s" % (node_xml, node0_xml), None) if rc != 0: self.CM.log("Diff between %s and %s failed: %d" % (node0_xml, node_xml, rc)) passed = 0 for line in result: if not re.search("", line): passed = 0 self.debug("CibDiff[%s-%s]: %s" % (node0, node, line)) else: self.debug("CibDiff[%s-%s] Ignoring: %s" % (node0, node, line)) # self.CM.rsh(node0, "rm -f %s" % node_xml) # self.CM.rsh(node0, "rm -f %s" % node0_xml) return passed def store_remote_cib(self, node, target): combined = "" filename="/tmp/ctsaudit.%s.xml" % node if not target: target = node (rc, lines) = self.CM.rsh(node, self.CM["CibQuery"], None) if rc != 0: self.CM.log("Could not retrieve configuration") return None self.CM.rsh("localhost", "rm -f %s" % filename) for line in lines: self.CM.rsh("localhost", "echo \'%s\' >> %s" % (line[:-1], filename), silent=True) if self.CM.rsh.cp(filename, "root@%s:%s" % (target, filename), silent=True) != 0: self.CM.log("Could not store configuration") return None return filename def name(self): return "CibAudit" def is_applicable(self): if self.CM["Name"] == "crm-lha": return 1 if self.CM["Name"] == "crm-ais": return 1 return 0 class PartitionAudit(ClusterAudit): def __init__(self, cm): self.CM = cm self.Stats = {"calls":0 , "success":0 , "failure":0 , "skipped":0 , "auditfail":0} self.NodeEpoche={} self.NodeState={} self.NodeQuorum={} def has_key(self, key): return self.Stats.has_key(key) def __setitem__(self, key, value): self.Stats[key] = value def __getitem__(self, key): return self.Stats[key] def incr(self, name): '''Increment (or initialize) the value associated with the given name''' if not self.Stats.has_key(name): self.Stats[name]=0 self.Stats[name] = self.Stats[name]+1 def __call__(self): passed = 1 ccm_partitions = self.CM.find_partitions() if ccm_partitions == None or len(ccm_partitions) == 0: return 1 self.CM.cluster_stable(double_check=True) if len(ccm_partitions) != self.CM.partitions_expected: self.CM.log("ERROR: %d cluster partitions detected:" %len(ccm_partitions)) passed = 0 for partition in ccm_partitions: self.CM.log("\t %s" %partition) for partition in ccm_partitions: partition_passed = 0 if self.audit_partition(partition) == 0: passed = 0 return passed def trim_string(self, avalue): if not avalue: return None if len(avalue) > 1: return avalue[:-1] def trim2int(self, avalue): if not avalue: return None if len(avalue) > 1: return int(avalue[:-1]) def audit_partition(self, partition): passed = 1 dc_found = [] dc_allowed_list = [] lowest_epoche = None node_list = partition.split() self.debug("Auditing partition: %s" %(partition)) for node in node_list: if self.CM.ShouldBeStatus[node] != "up": self.CM.log("Warn: Node %s appeared out of nowhere" %(node)) self.CM.ShouldBeStatus[node] = "up" # not in itself a reason to fail the audit (not what we're # checking for in this audit) self.NodeState[node] = self.CM.rsh(node, self.CM["StatusCmd"]%node, 1) self.NodeEpoche[node] = self.CM.rsh(node, self.CM["EpocheCmd"], 1) self.NodeQuorum[node] = self.CM.rsh(node, self.CM["QuorumCmd"], 1) self.debug("Node %s: %s - %s - %s." %(node, self.NodeState[node], self.NodeEpoche[node], self.NodeQuorum[node])) self.NodeState[node] = self.trim_string(self.NodeState[node]) self.NodeEpoche[node] = self.trim2int(self.NodeEpoche[node]) self.NodeQuorum[node] = self.trim_string(self.NodeQuorum[node]) if not self.NodeEpoche[node]: self.CM.log("Warn: Node %s dissappeared: cant determin epoche" %(node)) self.CM.ShouldBeStatus[node] = "down" # not in itself a reason to fail the audit (not what we're # checking for in this audit) elif lowest_epoche == None or self.NodeEpoche[node] < lowest_epoche: lowest_epoche = self.NodeEpoche[node] if not lowest_epoche: self.CM.log("Lowest epoche not determined in %s" % (partition)) passed = 0 for node in node_list: if self.CM.ShouldBeStatus[node] == "up": if self.CM.is_node_dc(node, self.NodeState[node]): dc_found.append(node) if self.NodeEpoche[node] == lowest_epoche: self.debug("%s: OK" % node) elif not self.NodeEpoche[node]: self.debug("Check on %s ignored: no node epoche" % node) elif not lowest_epoche: self.debug("Check on %s ignored: no lowest epoche" % node) else: self.CM.log("DC %s is not the oldest node (%d vs. %d)" %(node, self.NodeEpoche[node], lowest_epoche)) passed = 0 if len(dc_found) == 0: self.CM.log("DC not found on any of the %d allowed nodes: %s (of %s)" %(len(dc_allowed_list), str(dc_allowed_list), str(node_list))) elif len(dc_found) > 1: self.CM.log("%d DCs (%s) found in cluster partition: %s" %(len(dc_found), str(dc_found), str(node_list))) passed = 0 if passed == 0: for node in node_list: if self.CM.ShouldBeStatus[node] == "up": self.CM.log("epoche %s : %s" %(self.NodeEpoche[node], self.NodeState[node])) return passed def name(self): return "PartitionAudit" def is_applicable(self): if self.CM["Name"] == "crm-lha": return 1 if self.CM["Name"] == "crm-ais": return 1 return 0 AllAuditClasses.append(DiskAudit) AllAuditClasses.append(FileAudit) AllAuditClasses.append(LogAudit) AllAuditClasses.append(CrmdStateAudit) AllAuditClasses.append(PartitionAudit) AllAuditClasses.append(PrimitiveAudit) AllAuditClasses.append(GroupAudit) AllAuditClasses.append(CloneAudit) AllAuditClasses.append(ColocationAudit) AllAuditClasses.append(CIBAudit) def AuditList(cm): result = [] for auditclass in AllAuditClasses: a = auditclass(cm) if a.is_applicable(): result.append(a) return result pacemaker-master/cts/CTSlab.py000077500000000000000000000567641217637305600166110ustar00rootroot00000000000000#!/usr/bin/python '''CTS: Cluster Testing System: Lab environment module ''' __copyright__=''' Copyright (C) 2001,2005 Alan Robertson Licensed under the GNU GPL. ''' # # 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 2 # of the License, 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 St, Fifth Floor, Boston, MA 02110-1301 USA. from UserDict import UserDict import sys, types, string, string, signal, os, socket pdir=os.path.dirname(sys.path[0]) sys.path.insert(0, pdir) # So that things work from the source directory try: from cts.CTSvars import * from cts.CM_ais import * from cts.CM_lha import crm_lha from cts.CTSaudits import AuditList from cts.CTStests import TestList from cts.CTSscenarios import * except ImportError: sys.stderr.write("abort: couldn't find cts libraries in [%s]\n" % ' '.join(sys.path)) sys.stderr.write("(check your install and PYTHONPATH)\n") # Now do it again to get more details from cts.CTSvars import * from cts.CM_ais import * from cts.CM_lha import crm_lha from cts.CTSaudits import AuditList from cts.CTStests import TestList from cts.CTSscenarios import * sys.exit(-1) cm = None Tests = [] Chosen = [] scenario = None # Not really used, the handler in def sig_handler(signum, frame) : if cm: cm.log("Interrupted by signal %d"%signum) if scenario: scenario.summarize() if signum == 15 : if scenario: scenario.TearDown() sys.exit(1) class LabEnvironment(CtsLab): def __init__(self): CtsLab.__init__(self) # Get a random seed for the random number generator. self["DoStandby"] = 1 self["DoFencing"] = 1 self["XmitLoss"] = "0.0" self["RecvLoss"] = "0.0" self["ClobberCIB"] = 0 self["CIBfilename"] = None self["CIBResource"] = 0 self["DoBSC"] = 0 self["use_logd"] = 0 self["oprofile"] = [] self["warn-inactive"] = 0 self["ListTests"] = 0 self["benchmark"] = 0 self["Schema"] = "pacemaker-1.0" self["Stack"] = "openais" self["stonith-type"] = "external/ssh" self["stonith-params"] = "hostlist=all,livedangerously=yes" self["logger"] = ([StdErrLog(self)]) self["loop-minutes"] = 60 self["valgrind-prefix"] = None self["valgrind-procs"] = "cib crmd attrd pengine stonith-ng" self["valgrind-opts"] = """--leak-check=full --show-reachable=yes --trace-children=no --num-callers=25 --gen-suppressions=all --suppressions="""+CTSvars.CTS_home+"""/cts.supp""" #self["valgrind-opts"] = """--trace-children=no --num-callers=25 --gen-suppressions=all --suppressions="""+CTSvars.CTS_home+"""/cts.supp""" self["experimental-tests"] = 0 self["valgrind-tests"] = 0 self["unsafe-tests"] = 1 self["loop-tests"] = 1 self["scenario"] = "random" self["stats"] = 0 master = socket.gethostname() # Use the IP where possible to avoid name lookup failures for ip in socket.gethostbyname_ex(master)[2]: if ip != "127.0.0.1": master = ip break; self["cts-master"] = master def usage(arg, status=1): print "Illegal argument " + arg print "usage: " + sys.argv[0] +" [options] number-of-iterations" print "\nCommon options: " print "\t [--nodes 'node list'] list of cluster nodes separated by whitespace" print "\t [--group | -g 'name'] use the nodes listed in the named DSH group (~/.dsh/groups/$name)" print "\t [--limit-nodes max] only use the first 'max' cluster nodes supplied with --nodes" print "\t [--stack (v0|v1|cman|corosync|heartbeat|openais)] which cluster stack is installed" print "\t [--list-tests] list the valid tests" print "\t [--benchmark] add the timing information" print "\t " print "Options that CTS will usually auto-detect correctly: " print "\t [--logfile path] where should the test software look for logs from cluster nodes" print "\t [--syslog-facility name] which syslog facility should the test software log to" print "\t [--at-boot (1|0)] does the cluster software start at boot time" print "\t [--test-ip-base ip] offset for generated IP address resources" print "\t " print "Options for release testing: " print "\t [--populate-resources | -r] generate a sample configuration" print "\t [--choose name] run only the named test" print "\t [--stonith (1 | 0 | yes | no | rhcs | ssh)]" print "\t [--once] run all valid tests once" print "\t " print "Additional (less common) options: " print "\t [--clobber-cib | -c ] erase any existing configuration" print "\t [--outputfile path] optional location for the test software to write logs to" print "\t [--trunc] truncate logfile before starting" print "\t [--xmit-loss lost-rate(0.0-1.0)]" print "\t [--recv-loss lost-rate(0.0-1.0)]" print "\t [--standby (1 | 0 | yes | no)]" print "\t [--fencing (1 | 0 | yes | no | rhcs | lha | openstack )]" print "\t [--stonith-type type]" print "\t [--stonith-args name=value]" print "\t [--bsc]" print "\t [--no-loop-tests] dont run looping/time-based tests" print "\t [--no-unsafe-tests] dont run tests that are unsafe for use with ocfs2/drbd" print "\t [--valgrind-tests] include tests using valgrind" print "\t [--experimental-tests] include experimental tests" print "\t [--oprofile 'node list'] list of cluster nodes to run oprofile on]" print "\t [--qarsh] use the QARSH backdoor to access nodes instead of SSH" print "\t [--seed random_seed]" print "\t [--set option=value]" print "\t " print "\t Example: " print "\t python ./CTSlab.py -g virt1 --stack cs -r --stonith ssh --schema pacemaker-1.0 500" sys.exit(status) # # A little test code... # if __name__ == '__main__': Environment = LabEnvironment() rsh = RemoteExec(None, silent=True) NumIter = 0 Version = 1 LimitNodes = 0 TruncateLog = 0 ListTests = 0 HaveSeed = 0 node_list = '' # Set the signal handler signal.signal(15, sig_handler) signal.signal(10, sig_handler) # Process arguments... skipthis=None args=sys.argv[1:] for i in range(0, len(args)): if skipthis: skipthis=None continue elif args[i] == "-l" or args[i] == "--limit-nodes": skipthis=1 LimitNodes = int(args[i+1]) elif args[i] == "-r" or args[i] == "--populate-resources": Environment["CIBResource"] = 1 Environment["ClobberCIB"] = 1 elif args[i] == "-L" or args[i] == "--logfile": skipthis=1 Environment["LogFileName"] = args[i+1] elif args[i] == "--outputfile": skipthis=1 Environment["OutputFile"] = args[i+1] elif args[i] == "--ip" or args[i] == "--test-ip-base": skipthis=1 Environment["IPBase"] = args[i+1] Environment["CIBResource"] = 1 Environment["ClobberCIB"] = 1 elif args[i] == "--oprofile": skipthis=1 Environment["oprofile"] = args[i+1].split(' ') elif args[i] == "--trunc": Environment["TruncateLog"]=1 elif args[i] == "--list-tests" or args[i] == "--list" : Environment["ListTests"]=1 elif args[i] == "--benchmark": Environment["benchmark"]=1 elif args[i] == "--bsc": Environment["DoBSC"] = 1 Environment["scenario"] = "basic-sanity" elif args[i] == "--qarsh": Environment.rsh.enable_qarsh() rsh.enable_qarsh() elif args[i] == "--stonith" or args[i] == "--fencing": skipthis=1 if args[i+1] == "1" or args[i+1] == "yes": Environment["DoFencing"]=1 elif args[i+1] == "0" or args[i+1] == "no": Environment["DoFencing"]=0 elif args[i+1] == "rhcs" or args[i+1] == "xvm" or args[i+1] == "virt": Environment["DoStonith"]=1 Environment["stonith-type"] = "fence_xvm" Environment["stonith-params"] = "pcmk_arg_map=domain:uname,delay=0" elif args[i+1] == "ssh" or args[i+1] == "lha": Environment["DoStonith"]=1 Environment["stonith-type"] = "external/ssh" Environment["stonith-params"] = "hostlist=all,livedangerously=yes" elif args[i+1] == "north": Environment["DoStonith"]=1 Environment["stonith-type"] = "fence_apc" Environment["stonith-params"] = "ipaddr=north-apc,login=apc,passwd=apc,pcmk_host_map=north-01:2;north-02:3;north-03:4;north-04:5;north-05:6;north-06:7;north-07:9;north-08:10;north-09:11;north-10:12;north-11:13;north-12:14;north-13:15;north-14:18;north-15:17;north-16:19;" elif args[i+1] == "south": Environment["DoStonith"]=1 Environment["stonith-type"] = "fence_apc" Environment["stonith-params"] = "ipaddr=south-apc,login=apc,passwd=apc,pcmk_host_map=south-01:2;south-02:3;south-03:4;south-04:5;south-05:6;south-06:7;south-07:9;south-08:10;south-09:11;south-10:12;south-11:13;south-12:14;south-13:15;south-14:18;south-15:17;south-16:19;" elif args[i+1] == "east": Environment["DoStonith"]=1 Environment["stonith-type"] = "fence_apc" Environment["stonith-params"] = "ipaddr=east-apc,login=apc,passwd=apc,pcmk_host_map=east-01:2;east-02:3;east-03:4;east-04:5;east-05:6;east-06:7;east-07:9;east-08:10;east-09:11;east-10:12;east-11:13;east-12:14;east-13:15;east-14:18;east-15:17;east-16:19;" elif args[i+1] == "west": Environment["DoStonith"]=1 Environment["stonith-type"] = "fence_apc" Environment["stonith-params"] = "ipaddr=west-apc,login=apc,passwd=apc,pcmk_host_map=west-01:2;west-02:3;west-03:4;west-04:5;west-05:6;west-06:7;west-07:9;west-08:10;west-09:11;west-10:12;west-11:13;west-12:14;west-13:15;west-14:18;west-15:17;west-16:19;" elif args[i+1] == "openstack": Environment["DoStonith"]=1 Environment["stonith-type"] = "fence_openstack" print "Obtaining OpenStack credentials from the current environment" Environment["stonith-params"] = "region=%s,tenant=%s,auth=%s,user=%s,password=%s" % ( os.environ['OS_REGION_NAME'], os.environ['OS_TENANT_NAME'], os.environ['OS_AUTH_URL'], os.environ['OS_USERNAME'], os.environ['OS_PASSWORD'] ) elif args[i+1] == "rhevm": Environment["DoStonith"]=1 Environment["stonith-type"] = "fence_rhevm" print "Obtaining RHEV-M credentials from the current environment" Environment["stonith-params"] = "login=%s,passwd=%s,ipaddr=%s,ipport=%s,ssl=1,shell_timeout=10" % ( os.environ['RHEVM_USERNAME'], os.environ['RHEVM_PASSWORD'], os.environ['RHEVM_SERVER'], os.environ['RHEVM_PORT'], ) else: usage(args[i+1]) elif args[i] == "--stonith-type": Environment["stonith-type"] = args[i+1] skipthis=1 elif args[i] == "--stonith-args": Environment["stonith-params"] = args[i+1] skipthis=1 elif args[i] == "--standby": skipthis=1 if args[i+1] == "1" or args[i+1] == "yes": Environment["DoStandby"] = 1 elif args[i+1] == "0" or args[i+1] == "no": Environment["DoStandby"] = 0 else: usage(args[i+1]) elif args[i] == "--clobber-cib" or args[i] == "-c": Environment["ClobberCIB"] = 1 elif args[i] == "--cib-filename": skipthis=1 Environment["CIBfilename"] = args[i+1] elif args[i] == "--xmit-loss": try: float(args[i+1]) except ValueError: print ("--xmit-loss parameter should be float") usage(args[i+1]) skipthis=1 Environment["XmitLoss"] = args[i+1] elif args[i] == "--recv-loss": try: float(args[i+1]) except ValueError: print ("--recv-loss parameter should be float") usage(args[i+1]) skipthis=1 Environment["RecvLoss"] = args[i+1] elif args[i] == "--choose": skipthis=1 Chosen.append(args[i+1]) Environment["scenario"] = "sequence" elif args[i] == "--nodes": skipthis=1 node_list = args[i+1].split(' ') elif args[i] == "-g" or args[i] == "--group" or args[i] == "--dsh-group": skipthis=1 Environment["OutputFile"] = "%s/cluster-%s.log" % (os.environ['HOME'], args[i+1]) dsh_file = "%s/.dsh/group/%s" % (os.environ['HOME'], args[i+1]) if os.path.isfile(dsh_file): node_list = [] f = open(dsh_file, 'r') for line in f: l = line.strip().rstrip() if not l.startswith('#'): node_list.append(l) f.close() else: print("Unknown DSH group: %s" % args[i+1]) elif args[i] == "--syslog-facility" or args[i] == "--facility": skipthis=1 Environment["SyslogFacility"] = args[i+1] elif args[i] == "--seed": skipthis=1 Environment.SeedRandom(args[i+1]) elif args[i] == "--warn-inactive": Environment["warn-inactive"] = 1 elif args[i] == "--schema": skipthis=1 Environment["Schema"] = args[i+1] elif args[i] == "--ais": Environment["Stack"] = "openais" elif args[i] == "--at-boot" or args[i] == "--cluster-starts-at-boot": skipthis=1 if args[i+1] == "1" or args[i+1] == "yes": Environment["at-boot"] = 1 elif args[i+1] == "0" or args[i+1] == "no": Environment["at-boot"] = 0 else: usage(args[i+1]) elif args[i] == "--heartbeat" or args[i] == "--lha": Environment["Stack"] = "heartbeat" elif args[i] == "--hae": Environment["Stack"] = "openais" Environment["Schema"] = "hae" elif args[i] == "--stack": if args[i+1] == "fedora" or args[i+1] == "fedora-17" or args[i+1] == "fedora-18": Environment["Stack"] = "corosync" elif args[i+1] == "rhel-6": Environment["Stack"] = "cman" elif args[i+1] == "rhel-7": Environment["Stack"] = "corosync" else: Environment["Stack"] = args[i+1] skipthis=1 elif args[i] == "--once": Environment["scenario"] = "all-once" elif args[i] == "--boot": Environment["scenario"] = "boot" elif args[i] == "--valgrind-tests": Environment["valgrind-tests"] = 1 elif args[i] == "--no-loop-tests": Environment["loop-tests"] = 0 elif args[i] == "--loop-minutes": skipthis=1 try: Environment["loop-minutes"]=int(args[i+1]) except ValueError: usage(args[i]) elif args[i] == "--no-unsafe-tests": Environment["unsafe-tests"] = 0 elif args[i] == "--experimental-tests": Environment["experimental-tests"] = 1 elif args[i] == "--set": skipthis=1 (name, value) = args[i+1].split('=') Environment[name] = value print "Setting %s = %s" % (name, value) elif args[i] == "--": break else: try: NumIter=int(args[i]) except ValueError: usage(args[i]) if Environment["DoBSC"]: NumIter = 2 LimitNodes = 1 Chosen.append("AddResource") Environment["ClobberCIB"] = 1 Environment["CIBResource"] = 0 Environment["logger"].append(FileLog(Environment, Environment["LogFileName"])) elif Environment["OutputFile"]: Environment["logger"].append(FileLog(Environment, Environment["OutputFile"])) elif Environment["SyslogFacility"]: Environment["logger"].append(SysLog(Environment)) if Environment["Stack"] == "heartbeat" or Environment["Stack"] == "lha": Environment["Stack"] = "heartbeat" Environment['CMclass'] = crm_lha elif Environment["Stack"] == "openais" or Environment["Stack"] == "ais" or Environment["Stack"] == "whitetank": Environment["Stack"] = "openais (whitetank)" Environment['CMclass'] = crm_whitetank Environment["use_logd"] = 0 elif Environment["Stack"] == "corosync" or Environment["Stack"] == "cs" or Environment["Stack"] == "mcp": Environment["Stack"] = "corosync 2.x" Environment['CMclass'] = crm_mcp Environment["use_logd"] = 0 elif Environment["Stack"] == "cman": Environment["Stack"] = "corosync (cman)" Environment['CMclass'] = crm_cman Environment["use_logd"] = 0 elif Environment["Stack"] == "v1": Environment["Stack"] = "corosync (plugin v1)" Environment['CMclass'] = crm_cs_v1 Environment["use_logd"] = 0 elif Environment["Stack"] == "v0": Environment["Stack"] = "corosync (plugin v0)" Environment['CMclass'] = crm_cs_v0 Environment["use_logd"] = 0 else: print "Unknown stack: "+Environment["Stack"] sys.exit(1) if len(node_list) < 1: print "No nodes specified!" sys.exit(1) if LimitNodes > 0: if len(node_list) > LimitNodes: print("Limiting the number of nodes configured=%d (max=%d)" %(len(node_list), LimitNodes)) while len(node_list) > LimitNodes: node_list.pop(len(node_list)-1) Environment["nodes"] = [] for n in node_list: if len(n.strip()): Environment["nodes"].append(n.strip()) discover = random.Random().choice(Environment["nodes"]) Environment["have_systemd"] = not rsh(discover, "systemctl list-units") # Detect syslog variant if not Environment.has_key("syslogd") or not Environment["syslogd"]: if Environment["have_systemd"]: # Systemd Environment["syslogd"] = rsh(discover, "systemctl list-units | grep syslog.*\.service.*active.*running | sed 's:.service.*::'", stdout=1) else: # SYS-V Environment["syslogd"] = rsh(discover, "chkconfig | grep syslog.*on | awk '{print $1}' | head -n 1", stdout=1) if not Environment.has_key("syslogd") or not Environment["syslogd"]: # default Environment["syslogd"] = "rsyslog" # Detect if the cluster starts at boot if not Environment.has_key("at-boot"): atboot = 0 if Environment["have_systemd"]: # Systemd atboot = atboot or not rsh(discover, "systemctl is-enabled heartbeat.service") atboot = atboot or not rsh(discover, "systemctl is-enabled corosync.service") atboot = atboot or not rsh(discover, "systemctl is-enabled pacemaker.service") else: # SYS-V atboot = atboot or not rsh(discover, "chkconfig | grep -e corosync.*on -e heartbeat.*on -e pacemaker.*on") Environment["at-boot"] = atboot # Try to determinw an offset for IPaddr resources if Environment["CIBResource"] and not Environment.has_key("IPBase"): network=rsh(discover, "ip addr | grep inet | grep -v -e link -e inet6 -e '/32' -e ' lo' | awk '{print $2}'", stdout=1).strip() Environment["IPBase"] = rsh(discover, "nmap -sn -n %s | grep 'scan report' | tail -n 1 | awk '{print $NF}' | sed 's:(::' | sed 's:)::'" % network, stdout=1).strip() if not Environment["IPBase"]: Environment["IPBase"] = "127.0.0.10" Environment.log("Could not determine an offset for IPaddr resources. Perhaps nmap is not installed on the nodes.") Environment.log("Defaulting to '%s', use --test-ip-base to override" % Environment["IPBase"]) # Create the Cluster Manager object cm = Environment['CMclass'](Environment) if TruncateLog: Environment.log("Truncating %s" % LogFile) lf = open(LogFile, "w"); if lf != None: lf.truncate(0) lf.close() Audits = AuditList(cm) if Environment["ListTests"] == 1 : Tests = TestList(cm, Audits) Environment.log("Total %d tests"%len(Tests)) for test in Tests : Environment.log(str(test.name)); sys.exit(0) if len(Chosen) == 0: Tests = TestList(cm, Audits) else: for TestCase in Chosen: match = None for test in TestList(cm, Audits): if test.name == TestCase: match = test if not match: usage("--choose: No applicable/valid tests chosen") else: Tests.append(match) # Scenario selection if Environment["scenario"] == "basic-sanity": scenario = RandomTests(cm, [ BasicSanityCheck(Environment) ], Audits, Tests) elif Environment["scenario"] == "all-once": NumIter = len(Tests) scenario = AllOnce( cm, [ BootCluster(Environment), PacketLoss(Environment) ], Audits, Tests) elif Environment["scenario"] == "sequence": scenario = Sequence( cm, [ BootCluster(Environment), PacketLoss(Environment) ], Audits, Tests) elif Environment["scenario"] == "boot": scenario = Boot(cm, [ LeaveBooted(Environment)], Audits, []) else: scenario = RandomTests( cm, [ BootCluster(Environment), PacketLoss(Environment) ], Audits, Tests) Environment.log(">>>>>>>>>>>>>>>> BEGINNING " + repr(NumIter) + " TESTS ") Environment.log("Stack: %s" % Environment["Stack"]) Environment.log("Schema: %s" % Environment["Schema"]) Environment.log("Scenario: %s" % scenario.__doc__) Environment.log("CTS Master: %s" % Environment["cts-master"]) Environment.log("CTS Logfile: %s" % Environment["OutputFile"]) Environment.log("Random Seed: %s" % Environment["RandSeed"]) Environment.log("Syslog variant: %s" % Environment["syslogd"].strip()) Environment.log("System log files: %s" % Environment["LogFileName"]) # Environment.log(" ") if Environment.has_key("IPBase"): Environment.log("Base IP for resources: %s" % Environment["IPBase"]) Environment.log("Cluster starts at boot: %d" % Environment["at-boot"]) Environment.dump() rc = Environment.run(scenario, NumIter) sys.exit(rc) pacemaker-master/cts/CTSscenarios.py000066400000000000000000000411641217637305600200220ustar00rootroot00000000000000from CTS import * from CTStests import CTSTest from CTSaudits import ClusterAudit class ScenarioComponent: def __init__(self, Env): self.Env = Env def IsApplicable(self): '''Return TRUE if the current ScenarioComponent is applicable in the given LabEnvironment given to the constructor. ''' raise ValueError("Abstract Class member (IsApplicable)") def SetUp(self, CM): '''Set up the given ScenarioComponent''' raise ValueError("Abstract Class member (Setup)") def TearDown(self, CM): '''Tear down (undo) the given ScenarioComponent''' raise ValueError("Abstract Class member (Setup)") class Scenario: ( '''The basic idea of a scenario is that of an ordered list of ScenarioComponent objects. Each ScenarioComponent is SetUp() in turn, and then after the tests have been run, they are torn down using TearDown() (in reverse order). A Scenario is applicable to a particular cluster manager iff each ScenarioComponent is applicable. A partially set up scenario is torn down if it fails during setup. ''') def __init__(self, ClusterManager, Components, Audits, Tests): "Initialize the Scenario from the list of ScenarioComponents" self.ClusterManager = ClusterManager self.Components = Components self.Audits = Audits self.Tests = Tests self.BadNews = None self.TestSets = [] self.Stats = {"success":0, "failure":0, "BadNews":0, "skipped":0} self.Sets = [] #self.ns=CTS.NodeStatus(self.Env) for comp in Components: if not issubclass(comp.__class__, ScenarioComponent): raise ValueError("Init value must be subclass of ScenarioComponent") for audit in Audits: if not issubclass(audit.__class__, ClusterAudit): raise ValueError("Init value must be subclass of ClusterAudit") for test in Tests: if not issubclass(test.__class__, CTSTest): raise ValueError("Init value must be a subclass of CTSTest") def IsApplicable(self): ( '''A Scenario IsApplicable() iff each of its ScenarioComponents IsApplicable() ''' ) for comp in self.Components: if not comp.IsApplicable(): return None return 1 def SetUp(self): '''Set up the Scenario. Return TRUE on success.''' self.audit() # Also detects remote/local log config self.ClusterManager.prepare() self.ClusterManager.ns.WaitForAllNodesToComeUp(self.ClusterManager.Env["nodes"]) self.audit() if self.ClusterManager.Env["valgrind-tests"]: self.ClusterManager.install_helper("cts.supp") self.BadNews = LogWatcher(self.ClusterManager.Env, self.ClusterManager["LogFileName"], self.ClusterManager["BadRegexes"], "BadNews", 0) self.BadNews.setwatch() # Call after we've figured out what type of log watching to do in LogAudit j=0 while j < len(self.Components): if not self.Components[j].SetUp(self.ClusterManager): # OOPS! We failed. Tear partial setups down. self.audit() self.ClusterManager.log("Tearing down partial setup") self.TearDown(j) return None j=j+1 self.audit() return 1 def TearDown(self, max=None): '''Tear Down the Scenario - in reverse order.''' if max == None: max = len(self.Components)-1 j=max while j >= 0: self.Components[j].TearDown(self.ClusterManager) j=j-1 self.audit() def incr(self, name): '''Increment (or initialize) the value associated with the given name''' if not self.Stats.has_key(name): self.Stats[name]=0 self.Stats[name] = self.Stats[name]+1 def run(self, Iterations): self.ClusterManager.oprofileStart() try: self.run_loop(Iterations) self.ClusterManager.oprofileStop() except: self.ClusterManager.oprofileStop() raise def run_loop(self, Iterations): raise ValueError("Abstract Class member (run_loop)") def run_test(self, test, testcount): nodechoice = self.ClusterManager.Env.RandomNode() ret = 1 where = "" did_run = 0 self.ClusterManager.Env.StatsMark(testcount) self.ClusterManager.instance_errorstoignore_clear() self.ClusterManager.log(("Running test %s" % test.name).ljust(35) + (" (%s) " % nodechoice).ljust(15) +"["+ ("%d" % testcount).rjust(3) +"]") starttime = test.set_timer() if not test.setup(nodechoice): self.ClusterManager.log("Setup failed") ret = 0 elif not test.canrunnow(nodechoice): self.ClusterManager.log("Skipped") test.skipped() else: did_run = 1 ret = test(nodechoice) if not test.teardown(nodechoice): self.ClusterManager.log("Teardown failed") answer = raw_input('Continue? [nY] ') if answer and answer == "n": raise ValueError("Teardown of %s on %s failed" % (test.name, nodechoice)) ret = 0 stoptime=time.time() self.ClusterManager.oprofileSave(testcount) elapsed_time = stoptime - starttime test_time = stoptime - test.get_timer() if not test.has_key("min_time"): test["elapsed_time"] = elapsed_time test["min_time"] = test_time test["max_time"] = test_time else: test["elapsed_time"] = test["elapsed_time"] + elapsed_time if test_time < test["min_time"]: test["min_time"] = test_time if test_time > test["max_time"]: test["max_time"] = test_time if ret: self.incr("success") test.log_timer() else: self.incr("failure") self.ClusterManager.statall() did_run = 1 # Force the test count to be incrimented anyway so test extraction works self.audit(test.errorstoignore()) return did_run def summarize(self): self.ClusterManager.log("****************") self.ClusterManager.log("Overall Results:" + repr(self.Stats)) self.ClusterManager.log("****************") stat_filter = { "calls":0, "failure":0, "skipped":0, "auditfail":0, } self.ClusterManager.log("Test Summary") for test in self.Tests: for key in stat_filter.keys(): stat_filter[key] = test.Stats[key] self.ClusterManager.log(("Test %s: "%test.name).ljust(25) + " %s"%repr(stat_filter)) self.ClusterManager.debug("Detailed Results") for test in self.Tests: self.ClusterManager.debug(("Test %s: "%test.name).ljust(25) + " %s"%repr(test.Stats)) self.ClusterManager.log("<<<<<<<<<<<<<<<< TESTS COMPLETED") def audit(self, LocalIgnore=[]): errcount=0 ignorelist = [] ignorelist.append("CTS:") ignorelist.extend(LocalIgnore) ignorelist.extend(self.ClusterManager.errorstoignore()) ignorelist.extend(self.ClusterManager.instance_errorstoignore()) # This makes sure everything is stabilized before starting... failed = 0 for audit in self.Audits: if not audit(): self.ClusterManager.log("Audit " + audit.name() + " FAILED.") failed += 1 else: self.ClusterManager.debug("Audit " + audit.name() + " passed.") while errcount < 1000: match = None if self.BadNews: match=self.BadNews.look(0) if match: add_err = 1 for ignore in ignorelist: if add_err == 1 and re.search(ignore, match): add_err = 0 if add_err == 1: self.ClusterManager.log("BadNews: " + match) self.incr("BadNews") errcount=errcount+1 else: break else: answer = raw_input('Big problems. Continue? [nY]') if answer and answer == "n": self.ClusterManager.log("Shutting down.") self.summarize() self.TearDown() raise ValueError("Looks like we hit a BadNews jackpot!") return failed class AllOnce(Scenario): '''Every Test Once''' # Accessable as __doc__ def run_loop(self, Iterations): testcount=1 for test in self.Tests: self.run_test(test, testcount) testcount += 1 class RandomTests(Scenario): '''Random Test Execution''' def run_loop(self, Iterations): testcount=1 while testcount <= Iterations: test = self.ClusterManager.Env.RandomGen.choice(self.Tests) self.run_test(test, testcount) testcount += 1 class BasicSanity(Scenario): '''Basic Cluster Sanity''' def run_loop(self, Iterations): testcount=1 while testcount <= Iterations: test = self.Environment.RandomGen.choice(self.Tests) self.run_test(test, testcount) testcount += 1 class Sequence(Scenario): '''Named Tests in Sequence''' def run_loop(self, Iterations): testcount=1 while testcount <= Iterations: for test in self.Tests: self.run_test(test, testcount) testcount += 1 class Boot(Scenario): '''Start the Cluster''' def run_loop(self, Iterations): testcount=0 class BootCluster(ScenarioComponent): ( '''BootCluster is the most basic of ScenarioComponents. This ScenarioComponent simply starts the cluster manager on all the nodes. It is fairly robust as it waits for all nodes to come up before starting as they might have been rebooted or crashed for some reason beforehand. ''') def __init__(self, Env): pass def IsApplicable(self): '''BootCluster is so generic it is always Applicable''' return 1 def SetUp(self, CM): '''Basic Cluster Manager startup. Start everything''' CM.prepare() # Clear out the cobwebs ;-) self.TearDown(CM) # Now start the Cluster Manager on all the nodes. CM.log("Starting Cluster Manager on all nodes.") return CM.startall(verbose=True, quick=True) def TearDown(self, CM): '''Set up the given ScenarioComponent''' # Stop the cluster manager everywhere CM.log("Stopping Cluster Manager on all nodes") return CM.stopall(verbose=True) class LeaveBooted(BootCluster): def TearDown(self, CM): '''Set up the given ScenarioComponent''' # Stop the cluster manager everywhere CM.log("Leaving Cluster running on all nodes") return 1 class PingFest(ScenarioComponent): ( '''PingFest does a flood ping to each node in the cluster from the test machine. If the LabEnvironment Parameter PingSize is set, it will be used as the size of ping packet requested (via the -s option). If it is not set, it defaults to 1024 bytes. According to the manual page for ping: Outputs packets as fast as they come back or one hundred times per second, whichever is more. For every ECHO_REQUEST sent a period ``.'' is printed, while for every ECHO_REPLY received a backspace is printed. This provides a rapid display of how many packets are being dropped. Only the super-user may use this option. This can be very hard on a net- work and should be used with caution. ''' ) def __init__(self, Env): self.Env = Env def IsApplicable(self): '''PingFests are always applicable ;-) ''' return 1 def SetUp(self, CM): '''Start the PingFest!''' self.PingSize=1024 if CM.Env.has_key("PingSize"): self.PingSize=CM.Env["PingSize"] CM.log("Starting %d byte flood pings" % self.PingSize) self.PingPids=[] for node in CM.Env["nodes"]: self.PingPids.append(self._pingchild(node)) CM.log("Ping PIDs: " + repr(self.PingPids)) return 1 def TearDown(self, CM): '''Stop it right now! My ears are pinging!!''' for pid in self.PingPids: if pid != None: CM.log("Stopping ping process %d" % pid) os.kill(pid, signal.SIGKILL) def _pingchild(self, node): Args = ["ping", "-qfn", "-s", str(self.PingSize), node] sys.stdin.flush() sys.stdout.flush() sys.stderr.flush() pid = os.fork() if pid < 0: self.Env.log("Cannot fork ping child") return None if pid > 0: return pid # Otherwise, we're the child process. os.execvp("ping", Args) self.Env.log("Cannot execvp ping: " + repr(Args)) sys.exit(1) class PacketLoss(ScenarioComponent): ( ''' It would be useful to do some testing of CTS with a modest amount of packet loss enabled - so we could see that everything runs like it should with a certain amount of packet loss present. ''') def IsApplicable(self): '''always Applicable''' return 1 def SetUp(self, CM): '''Reduce the reliability of communications''' if float(CM.Env["XmitLoss"]) == 0 and float(CM.Env["RecvLoss"]) == 0 : return 1 for node in CM.Env["nodes"]: CM.reducecomm_node(node) CM.log("Reduce the reliability of communications") return 1 def TearDown(self, CM): '''Fix the reliability of communications''' if float(CM.Env["XmitLoss"]) == 0 and float(CM.Env["RecvLoss"]) == 0 : return 1 for node in CM.Env["nodes"]: CM.unisolate_node(node) CM.log("Fix the reliability of communications") class BasicSanityCheck(ScenarioComponent): ( ''' ''') def IsApplicable(self): return self.Env["DoBSC"] def SetUp(self, CM): CM.prepare() # Clear out the cobwebs self.TearDown(CM) # Now start the Cluster Manager on all the nodes. CM.log("Starting Cluster Manager on BSC node(s).") return CM.startall() def TearDown(self, CM): CM.log("Stopping Cluster Manager on BSC node(s).") return CM.stopall() class Benchmark(ScenarioComponent): ( ''' ''') def IsApplicable(self): return self.Env["benchmark"] def SetUp(self, CM): CM.prepare() # Clear out the cobwebs self.TearDown(CM) # Now start the Cluster Manager on all the nodes. CM.log("Starting Cluster Manager on all node(s).") return CM.startall() def TearDown(self, CM): CM.log("Stopping Cluster Manager on all node(s).") return CM.stopall() class RollingUpgrade(ScenarioComponent): ( ''' Test a rolling upgrade between two versions of the stack ''') def __init__(self, Env): self.Env = Env def IsApplicable(self): if not self.Env["rpm-dir"]: return None if not self.Env["current-version"]: return None if not self.Env["previous-version"]: return None return 1 def install(self, node, version): target_dir = "/tmp/rpm-%s" % version src_dir = "%s/%s" % (self.CM.Env["rpm-dir"], version) rc = self.CM.rsh(node, "mkdir -p %s" % target_dir) rc = self.CM.cp("%s/*.rpm %s:%s" % (src_dir, node, target_dir)) rc = self.CM.rsh(node, "rpm -Uvh --force %s/*.rpm" % (target_dir)) return self.success() def upgrade(self, node): return self.install(node, self.CM.Env["current-version"]) def downgrade(self, node): return self.install(node, self.CM.Env["previous-version"]) def SetUp(self, CM): CM.prepare() # Clear out the cobwebs CM.stopall() CM.log("Downgrading all nodes to %s." % self.Env["previous-version"]) for node in self.Env["nodes"]: if not self.downgrade(node): CM.log("Couldn't downgrade %s" % node) return None return 1 def TearDown(self, CM): # Stop everything CM.log("Stopping Cluster Manager on Upgrade nodes.") CM.stopall() CM.log("Upgrading all nodes to %s." % self.Env["current-version"]) for node in self.Env["nodes"]: if not self.upgrade(node): CM.log("Couldn't upgrade %s" % node) return None return 1 pacemaker-master/cts/CTStests.py000066400000000000000000002507231217637305600172010ustar00rootroot00000000000000'''CTS: Cluster Testing System: Tests module There are a few things we want to do here: ''' __copyright__=''' Copyright (C) 2000, 2001 Alan Robertson Licensed under the GNU GPL. Add RecourceRecover testcase Zhao Kai ''' # # 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 2 # of the License, 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 St, Fifth Floor, Boston, MA 02110-1301 USA. # # SPECIAL NOTE: # # Tests may NOT implement any cluster-manager-specific code in them. # EXTEND the ClusterManager object to provide the base capabilities # the test needs if you need to do something that the current CM classes # do not. Otherwise you screw up the whole point of the object structure # in CTS. # # Thank you. # import time, os, re, types, string, tempfile, sys from stat import * from cts import CTS from cts.CTSaudits import * AllTestClasses = [ ] class CTSTest: ''' A Cluster test. We implement the basic set of properties and behaviors for a generic cluster test. Cluster tests track their own statistics. We keep each of the kinds of counts we track as separate {name,value} pairs. ''' def __init__(self, cm): #self.name="the unnamed test" self.Stats = {"calls":0 , "success":0 , "failure":0 , "skipped":0 , "auditfail":0} # if not issubclass(cm.__class__, ClusterManager): # raise ValueError("Must be a ClusterManager object") self.CM = cm self.Audits = [] self.timeout=120 self.passed = 1 self.is_loop = 0 self.is_unsafe = 0 self.is_experimental = 0 self.is_valgrind = 0 self.benchmark = 0 # which tests to benchmark self.timer = {} # timers def has_key(self, key): return self.Stats.has_key(key) def __setitem__(self, key, value): self.Stats[key] = value def __getitem__(self, key): return self.Stats[key] def log_mark(self, msg): self.CM.debug("MARK: test %s %s %d" % (self.name,msg,time.time())) return def get_timer(self,key = "test"): try: return self.timer[key] except: return 0 def set_timer(self,key = "test"): self.timer[key] = time.time() return self.timer[key] def log_timer(self,key = "test"): elapsed = 0 if key in self.timer: elapsed = time.time() - self.timer[key] s = key == "test" and self.name or "%s:%s" %(self.name,key) self.CM.debug("%s runtime: %.2f" % (s, elapsed)) del self.timer[key] return elapsed def incr(self, name): '''Increment (or initialize) the value associated with the given name''' if not self.Stats.has_key(name): self.Stats[name]=0 self.Stats[name] = self.Stats[name]+1 # Reset the test passed boolean if name == "calls": self.passed = 1 def failure(self, reason="none"): '''Increment the failure count''' self.passed = 0 self.incr("failure") self.CM.log(("Test %s" % self.name).ljust(35) +" FAILED: %s" % reason) return None def success(self): '''Increment the success count''' self.incr("success") return 1 def skipped(self): '''Increment the skipped count''' self.incr("skipped") return 1 def __call__(self, node): '''Perform the given test''' raise ValueError("Abstract Class member (__call__)") self.incr("calls") return self.failure() def audit(self): passed = 1 if len(self.Audits) > 0: for audit in self.Audits: if not audit(): self.CM.log("Internal %s Audit %s FAILED." % (self.name, audit.name())) self.incr("auditfail") passed = 0 return passed def setup(self, node): '''Setup the given test''' return self.success() def teardown(self, node): '''Tear down the given test''' return self.success() def create_watch(self, patterns, timeout, name=None): if not name: name = self.name return CTS.LogWatcher(self.CM.Env, self.CM["LogFileName"], patterns, name, timeout) def local_badnews(self, prefix, watch, local_ignore=[]): errcount = 0 if not prefix: prefix = "LocalBadNews:" ignorelist = [] ignorelist.append(" CTS: ") ignorelist.append(prefix) ignorelist.extend(local_ignore) while errcount < 100: match=watch.look(0) if match: add_err = 1 for ignore in ignorelist: if add_err == 1 and re.search(ignore, match): add_err = 0 if add_err == 1: self.CM.log(prefix + " " + match) errcount=errcount+1 else: break else: self.CM.log("Too many errors!") return errcount def is_applicable(self): return self.is_applicable_common() def is_applicable_common(self): '''Return TRUE if we are applicable in the current test configuration''' #raise ValueError("Abstract Class member (is_applicable)") if self.is_loop and not self.CM.Env["loop-tests"]: return 0 elif self.is_unsafe and not self.CM.Env["unsafe-tests"]: return 0 elif self.is_valgrind and not self.CM.Env["valgrind-tests"]: return 0 elif self.is_experimental and not self.CM.Env["experimental-tests"]: return 0 elif self.CM.Env["benchmark"] and self.benchmark == 0: return 0 return 1 def find_ocfs2_resources(self, node): self.r_o2cb = None self.r_ocfs2 = [] (rc, lines) = self.CM.rsh(node, "crm_resource -c", None) for line in lines: if re.search("^Resource", line): r = AuditResource(self.CM, line) if r.rtype == "o2cb" and r.parent != "NA": self.CM.debug("Found o2cb: %s" % self.r_o2cb) self.r_o2cb = r.parent if re.search("^Constraint", line): c = AuditConstraint(self.CM, line) if c.type == "rsc_colocation" and c.target == self.r_o2cb: self.r_ocfs2.append(c.rsc) self.CM.debug("Found ocfs2 filesystems: %s" % repr(self.r_ocfs2)) return len(self.r_ocfs2) def canrunnow(self, node): '''Return TRUE if we can meaningfully run right now''' return 1 def errorstoignore(self): '''Return list of errors which are 'normal' and should be ignored''' return [] ################################################################### class StopTest(CTSTest): ################################################################### '''Stop (deactivate) the cluster manager on a node''' def __init__(self, cm): CTSTest.__init__(self, cm) self.name="Stop" def __call__(self, node): '''Perform the 'stop' test. ''' self.incr("calls") if self.CM.ShouldBeStatus[node] != "up": return self.skipped() patterns = [] # Technically we should always be able to notice ourselves stopping patterns.append(self.CM["Pat:We_stopped"] % node) #if self.CM.Env["use_logd"]: # patterns.append(self.CM["Pat:Logd_stopped"] % node) # Any active node needs to notice this one left # NOTE: This wont work if we have multiple partitions for other in self.CM.Env["nodes"]: if self.CM.ShouldBeStatus[other] == "up" and other != node: patterns.append(self.CM["Pat:They_stopped"] %(other, self.CM.key_for_node(node))) #self.debug("Checking %s will notice %s left"%(other, node)) watch = self.create_watch(patterns, self.CM["DeadTime"]) watch.setwatch() if node == self.CM.OurNode: self.incr("us") else: if self.CM.upcount() <= 1: self.incr("all") else: self.incr("them") self.CM.StopaCM(node) watch_result = watch.lookforall() failreason=None UnmatchedList = "||" if watch.unmatched: (rc, output) = self.CM.rsh(node, "/bin/ps axf", None) for line in output: self.CM.debug(line) (rc, output) = self.CM.rsh(node, "/usr/sbin/dlm_tool dump", None) for line in output: self.CM.debug(line) for regex in watch.unmatched: self.CM.log ("ERROR: Shutdown pattern not found: %s" % (regex)) UnmatchedList += regex + "||"; failreason="Missing shutdown pattern" self.CM.cluster_stable(self.CM["DeadTime"]) if not watch.unmatched or self.CM.upcount() == 0: return self.success() if len(watch.unmatched) >= self.CM.upcount(): return self.failure("no match against (%s)" % UnmatchedList) if failreason == None: return self.success() else: return self.failure(failreason) # # We don't register StopTest because it's better when called by # another test... # ################################################################### class StartTest(CTSTest): ################################################################### '''Start (activate) the cluster manager on a node''' def __init__(self, cm, debug=None): CTSTest.__init__(self,cm) self.name="start" self.debug = debug def __call__(self, node): '''Perform the 'start' test. ''' self.incr("calls") if self.CM.upcount() == 0: self.incr("us") else: self.incr("them") if self.CM.ShouldBeStatus[node] != "down": return self.skipped() elif self.CM.StartaCM(node): return self.success() else: return self.failure("Startup %s on node %s failed" %(self.CM["Name"], node)) # # We don't register StartTest because it's better when called by # another test... # ################################################################### class FlipTest(CTSTest): ################################################################### '''If it's running, stop it. If it's stopped start it. Overthrow the status quo... ''' def __init__(self, cm): CTSTest.__init__(self,cm) self.name="Flip" self.start = StartTest(cm) self.stop = StopTest(cm) def __call__(self, node): '''Perform the 'Flip' test. ''' self.incr("calls") if self.CM.ShouldBeStatus[node] == "up": self.incr("stopped") ret = self.stop(node) type="up->down" # Give the cluster time to recognize it's gone... time.sleep(self.CM["StableTime"]) elif self.CM.ShouldBeStatus[node] == "down": self.incr("started") ret = self.start(node) type="down->up" else: return self.skipped() self.incr(type) if ret: return self.success() else: return self.failure("%s failure" % type) # Register FlipTest as a good test to run AllTestClasses.append(FlipTest) ################################################################### class RestartTest(CTSTest): ################################################################### '''Stop and restart a node''' def __init__(self, cm): CTSTest.__init__(self,cm) self.name="Restart" self.start = StartTest(cm) self.stop = StopTest(cm) self.benchmark = 1 def __call__(self, node): '''Perform the 'restart' test. ''' self.incr("calls") self.incr("node:" + node) ret1 = 1 if self.CM.StataCM(node): self.incr("WasStopped") if not self.start(node): return self.failure("start (setup) failure: "+node) self.set_timer() if not self.stop(node): return self.failure("stop failure: "+node) if not self.start(node): return self.failure("start failure: "+node) return self.success() # Register RestartTest as a good test to run AllTestClasses.append(RestartTest) ################################################################### class StonithdTest(CTSTest): ################################################################### def __init__(self, cm): CTSTest.__init__(self, cm) self.name="Stonithd" self.startall = SimulStartLite(cm) self.benchmark = 1 def __call__(self, node): self.incr("calls") if len(self.CM.Env["nodes"]) < 2: return self.skipped() ret = self.startall(None) if not ret: return self.failure("Setup failed") is_dc = self.CM.is_node_dc(node) watchpats = [] watchpats.append("log_operation: Operation .* for host '%s' with device .* returned: 0" % node) watchpats.append("tengine_stonith_notify: Peer %s was terminated .*: OK" % node) if self.CM.Env["at-boot"] == 0: self.CM.debug("Expecting %s to stay down" % node) self.CM.ShouldBeStatus[node]="down" else: self.CM.debug("Expecting %s to come up again %d" % (node, self.CM.Env["at-boot"])) watchpats.append("%s .*do_state_transition: .* S_STARTING -> S_PENDING" % node) watchpats.append("%s .*do_state_transition: .* S_PENDING -> S_NOT_DC" % node) watch = self.create_watch(watchpats, 30 + self.CM["DeadTime"] + self.CM["StableTime"] + self.CM["StartTime"]) watch.setwatch() origin = self.CM.Env.RandomGen.choice(self.CM.Env["nodes"]) rc = self.CM.rsh(origin, "stonith_admin --reboot %s -VVVVVV" % node) if rc == 194: # 194 - 256 = -62 = Timer expired # # Look for the patterns, usually this means the required # device was running on the node to be fenced - or that # the required devices were in the process of being loaded # and/or moved # # Effectively the node committed suicide so there will be # no confirmation, but pacemaker should be watching and # fence the node again self.CM.log("Fencing command on %s to fence %s timed out" % (origin, node)) elif origin != node and rc != 0: self.CM.debug("Waiting for the cluster to recover") self.CM.cluster_stable() self.CM.debug("Waiting STONITHd node to come back up") self.CM.ns.WaitForAllNodesToComeUp(self.CM.Env["nodes"], 600) self.CM.log("Fencing command on %s failed to fence %s (rc=%d)" % (origin, node, rc)) elif origin == node and rc != 255: # 255 == broken pipe, ie. the node was fenced as epxected self.CM.log("Logcally originated fencing returned %d" % rc) self.set_timer("fence") matched = watch.lookforall() self.log_timer("fence") self.set_timer("reform") if watch.unmatched: self.CM.log("Patterns not found: " + repr(watch.unmatched)) self.CM.debug("Waiting for the cluster to recover") self.CM.cluster_stable() self.CM.debug("Waiting STONITHd node to come back up") self.CM.ns.WaitForAllNodesToComeUp(self.CM.Env["nodes"], 600) self.CM.debug("Waiting for the cluster to re-stabilize with all nodes") is_stable = self.CM.cluster_stable(self.CM["StartTime"]) if not matched: return self.failure("Didn't find all expected patterns") elif not is_stable: return self.failure("Cluster did not become stable") self.log_timer("reform") return self.success() def errorstoignore(self): return [ self.CM["Pat:Fencing_start"] % ".*", self.CM["Pat:Fencing_ok"] % ".*", "error: native_create_actions: Resource .*stonith::.* is active on 2 nodes attempting recovery", "error: remote_op_done: Operation reboot of .*by .* for stonith_admin.*: Timer expired", ] def is_applicable(self): if not self.is_applicable_common(): return 0 if self.CM.Env.has_key("DoFencing"): return self.CM.Env["DoFencing"] return 1 AllTestClasses.append(StonithdTest) ################################################################### class StartOnebyOne(CTSTest): ################################################################### '''Start all the nodes ~ one by one''' def __init__(self, cm): CTSTest.__init__(self,cm) self.name="StartOnebyOne" self.stopall = SimulStopLite(cm) self.start = StartTest(cm) self.ns=CTS.NodeStatus(cm.Env) def __call__(self, dummy): '''Perform the 'StartOnebyOne' test. ''' self.incr("calls") # We ignore the "node" parameter... # Shut down all the nodes... ret = self.stopall(None) if not ret: return self.failure("Test setup failed") failed=[] self.set_timer() for node in self.CM.Env["nodes"]: if not self.start(node): failed.append(node) if len(failed) > 0: return self.failure("Some node failed to start: " + repr(failed)) return self.success() # Register StartOnebyOne as a good test to run AllTestClasses.append(StartOnebyOne) ################################################################### class SimulStart(CTSTest): ################################################################### '''Start all the nodes ~ simultaneously''' def __init__(self, cm): CTSTest.__init__(self,cm) self.name="SimulStart" self.stopall = SimulStopLite(cm) self.startall = SimulStartLite(cm) def __call__(self, dummy): '''Perform the 'SimulStart' test. ''' self.incr("calls") # We ignore the "node" parameter... # Shut down all the nodes... ret = self.stopall(None) if not ret: return self.failure("Setup failed") self.CM.clear_all_caches() if not self.startall(None): return self.failure("Startall failed") return self.success() # Register SimulStart as a good test to run AllTestClasses.append(SimulStart) ################################################################### class SimulStop(CTSTest): ################################################################### '''Stop all the nodes ~ simultaneously''' def __init__(self, cm): CTSTest.__init__(self,cm) self.name="SimulStop" self.startall = SimulStartLite(cm) self.stopall = SimulStopLite(cm) def __call__(self, dummy): '''Perform the 'SimulStop' test. ''' self.incr("calls") # We ignore the "node" parameter... # Start up all the nodes... ret = self.startall(None) if not ret: return self.failure("Setup failed") if not self.stopall(None): return self.failure("Stopall failed") return self.success() # Register SimulStop as a good test to run AllTestClasses.append(SimulStop) ################################################################### class StopOnebyOne(CTSTest): ################################################################### '''Stop all the nodes in order''' def __init__(self, cm): CTSTest.__init__(self,cm) self.name="StopOnebyOne" self.startall = SimulStartLite(cm) self.stop = StopTest(cm) def __call__(self, dummy): '''Perform the 'StopOnebyOne' test. ''' self.incr("calls") # We ignore the "node" parameter... # Start up all the nodes... ret = self.startall(None) if not ret: return self.failure("Setup failed") failed=[] self.set_timer() for node in self.CM.Env["nodes"]: if not self.stop(node): failed.append(node) if len(failed) > 0: return self.failure("Some node failed to stop: " + repr(failed)) self.CM.clear_all_caches() return self.success() # Register StopOnebyOne as a good test to run AllTestClasses.append(StopOnebyOne) ################################################################### class RestartOnebyOne(CTSTest): ################################################################### '''Restart all the nodes in order''' def __init__(self, cm): CTSTest.__init__(self,cm) self.name="RestartOnebyOne" self.startall = SimulStartLite(cm) def __call__(self, dummy): '''Perform the 'RestartOnebyOne' test. ''' self.incr("calls") # We ignore the "node" parameter... # Start up all the nodes... ret = self.startall(None) if not ret: return self.failure("Setup failed") did_fail=[] self.set_timer() self.restart = RestartTest(self.CM) for node in self.CM.Env["nodes"]: if not self.restart(node): did_fail.append(node) if did_fail: return self.failure("Could not restart %d nodes: %s" %(len(did_fail), repr(did_fail))) return self.success() # Register StopOnebyOne as a good test to run AllTestClasses.append(RestartOnebyOne) ################################################################### class PartialStart(CTSTest): ################################################################### '''Start a node - but tell it to stop before it finishes starting up''' def __init__(self, cm): CTSTest.__init__(self,cm) self.name="PartialStart" self.startall = SimulStartLite(cm) self.stopall = SimulStopLite(cm) self.stop = StopTest(cm) #self.is_unsafe = 1 def __call__(self, node): '''Perform the 'PartialStart' test. ''' self.incr("calls") ret = self.stopall(None) if not ret: return self.failure("Setup failed") # FIXME! This should use the CM class to get the pattern # then it would be applicable in general watchpats = [] watchpats.append("crmd.*Connecting to cluster infrastructure") watch = self.create_watch(watchpats, self.CM["DeadTime"]+10) watch.setwatch() self.CM.StartaCMnoBlock(node) ret = watch.lookforall() if not ret: self.CM.log("Patterns not found: " + repr(watch.unmatched)) return self.failure("Setup of %s failed" % node) ret = self.stop(node) if not ret: return self.failure("%s did not stop in time" % node) return self.success() def errorstoignore(self): '''Return list of errors which should be ignored''' # We might do some fencing in the 2-node case if we make it up far enough return [ """Executing reboot fencing operation""" ] # Register StopOnebyOne as a good test to run AllTestClasses.append(PartialStart) ####################################################################### class StandbyTest(CTSTest): ####################################################################### def __init__(self, cm): CTSTest.__init__(self,cm) self.name="Standby" self.benchmark = 1 self.start = StartTest(cm) self.startall = SimulStartLite(cm) # make sure the node is active # set the node to standby mode # check resources, none resource should be running on the node # set the node to active mode # check resouces, resources should have been migrated back (SHOULD THEY?) def __call__(self, node): self.incr("calls") ret=self.startall(None) if not ret: return self.failure("Start all nodes failed") self.CM.debug("Make sure node %s is active" % node) if self.CM.StandbyStatus(node) != "off": if not self.CM.SetStandbyMode(node, "off"): return self.failure("can't set node %s to active mode" % node) self.CM.cluster_stable() status = self.CM.StandbyStatus(node) if status != "off": return self.failure("standby status of %s is [%s] but we expect [off]" % (node, status)) self.CM.debug("Getting resources running on node %s" % node) rsc_on_node = self.CM.active_resources(node) watchpats = [] watchpats.append("do_state_transition:.*-> S_POLICY_ENGINE") watch = self.create_watch(watchpats, self.CM["DeadTime"]+10) watch.setwatch() self.CM.debug("Setting node %s to standby mode" % node) if not self.CM.SetStandbyMode(node, "on"): return self.failure("can't set node %s to standby mode" % node) self.set_timer("on") ret = watch.lookforall() if not ret: self.CM.log("Patterns not found: " + repr(watch.unmatched)) self.CM.SetStandbyMode(node, "off") return self.failure("cluster didn't react to standby change on %s" % node) self.CM.cluster_stable() status = self.CM.StandbyStatus(node) if status != "on": return self.failure("standby status of %s is [%s] but we expect [on]" % (node, status)) self.log_timer("on") self.CM.debug("Checking resources") bad_run = self.CM.active_resources(node) if len(bad_run) > 0: rc = self.failure("%s set to standby, %s is still running on it" % (node, repr(bad_run))) self.CM.debug("Setting node %s to active mode" % node) self.CM.SetStandbyMode(node, "off") return rc self.CM.debug("Setting node %s to active mode" % node) if not self.CM.SetStandbyMode(node, "off"): return self.failure("can't set node %s to active mode" % node) self.set_timer("off") self.CM.cluster_stable() status = self.CM.StandbyStatus(node) if status != "off": return self.failure("standby status of %s is [%s] but we expect [off]" % (node, status)) self.log_timer("off") return self.success() AllTestClasses.append(StandbyTest) ####################################################################### class ValgrindTest(CTSTest): ####################################################################### '''Check for memory leaks''' def __init__(self, cm): CTSTest.__init__(self,cm) self.name="Valgrind" self.stopall = SimulStopLite(cm) self.startall = SimulStartLite(cm) self.is_valgrind = 1 self.is_loop = 1 def setup(self, node): self.incr("calls") ret=self.stopall(None) if not ret: return self.failure("Stop all nodes failed") # Enable valgrind self.logPat = "/tmp/%s-*.valgrind" % self.name self.CM.Env["valgrind-prefix"] = self.name self.CM.rsh(node, "rm -f %s" % self.logPat, None) ret=self.startall(None) if not ret: return self.failure("Start all nodes failed") for node in self.CM.Env["nodes"]: (rc, output) = self.CM.rsh(node, "ps u --ppid `pidofproc aisexec`", None) for line in output: self.CM.debug(line) return self.success() def teardown(self, node): # Disable valgrind self.CM.Env["valgrind-prefix"] = None # Return all nodes to normal ret=self.stopall(None) if not ret: return self.failure("Stop all nodes failed") return self.success() def find_leaks(self): # Check for leaks leaked = [] self.stop = StopTest(self.CM) for node in self.CM.Env["nodes"]: (rc, ps_out) = self.CM.rsh(node, "ps u --ppid `pidofproc aisexec`", None) rc = self.stop(node) if not rc: self.failure("Couldn't shut down %s" % node) rc = self.CM.rsh(node, "grep -e indirectly.*lost:.*[1-9] -e definitely.*lost:.*[1-9] -e (ERROR|error).*SUMMARY:.*[1-9].*errors %s" % self.logPat, 0) if rc != 1: leaked.append(node) self.failure("Valgrind errors detected on %s" % node) for line in ps_out: self.CM.log(line) (rc, output) = self.CM.rsh(node, "grep -e lost: -e SUMMARY: %s" % self.logPat, None) for line in output: self.CM.log(line) (rc, output) = self.CM.rsh(node, "cat %s" % self.logPat, None) for line in output: self.CM.debug(line) self.CM.rsh(node, "rm -f %s" % self.logPat, None) return leaked def __call__(self, node): leaked = self.find_leaks() if len(leaked) > 0: return self.failure("Nodes %s leaked" % repr(leaked)) return self.success() def errorstoignore(self): '''Return list of errors which should be ignored''' return [ """cib:.*readCibXmlFile:""", """HA_VALGRIND_ENABLED""" ] ####################################################################### class StandbyLoopTest(ValgrindTest): ####################################################################### '''Check for memory leaks by putting a node in and out of standby for an hour''' def __init__(self, cm): ValgrindTest.__init__(self,cm) self.name="StandbyLoop" def __call__(self, node): lpc = 0 delay = 2 failed = 0 done=time.time() + self.CM.Env["loop-minutes"]*60 while time.time() <= done and not failed: lpc = lpc + 1 time.sleep(delay) if not self.CM.SetStandbyMode(node, "on"): self.failure("can't set node %s to standby mode" % node) failed = lpc time.sleep(delay) if not self.CM.SetStandbyMode(node, "off"): self.failure("can't set node %s to active mode" % node) failed = lpc leaked = self.find_leaks() if failed: return self.failure("Iteration %d failed" % failed) elif len(leaked) > 0: return self.failure("Nodes %s leaked" % repr(leaked)) return self.success() AllTestClasses.append(StandbyLoopTest) ############################################################################## class BandwidthTest(CTSTest): ############################################################################## # Tests should not be cluster-manager-specific # If you need to find out cluster manager configuration to do this, then # it should be added to the generic cluster manager API. '''Test the bandwidth which heartbeat uses''' def __init__(self, cm): CTSTest.__init__(self, cm) self.name = "Bandwidth" self.start = StartTest(cm) self.__setitem__("min",0) self.__setitem__("max",0) self.__setitem__("totalbandwidth",0) self.tempfile = tempfile.mktemp(".cts") self.startall = SimulStartLite(cm) def __call__(self, node): '''Perform the Bandwidth test''' self.incr("calls") if self.CM.upcount()<1: return self.skipped() Path = self.CM.InternalCommConfig() if "ip" not in Path["mediatype"]: return self.skipped() port = Path["port"][0] port = int(port) ret = self.startall(None) if not ret: return self.failure("Test setup failed") time.sleep(5) # We get extra messages right after startup. fstmpfile = "/var/run/band_estimate" dumpcmd = "tcpdump -p -n -c 102 -i any udp port %d > %s 2>&1" \ % (port, fstmpfile) rc = self.CM.rsh(node, dumpcmd) if rc == 0: farfile = "root@%s:%s" % (node, fstmpfile) self.CM.rsh.cp(farfile, self.tempfile) Bandwidth = self.countbandwidth(self.tempfile) if not Bandwidth: self.CM.log("Could not compute bandwidth.") return self.success() intband = int(Bandwidth + 0.5) self.CM.log("...bandwidth: %d bits/sec" % intband) self.Stats["totalbandwidth"] = self.Stats["totalbandwidth"] + Bandwidth if self.Stats["min"] == 0: self.Stats["min"] = Bandwidth if Bandwidth > self.Stats["max"]: self.Stats["max"] = Bandwidth if Bandwidth < self.Stats["min"]: self.Stats["min"] = Bandwidth self.CM.rsh(node, "rm -f %s" % fstmpfile) os.unlink(self.tempfile) return self.success() else: return self.failure("no response from tcpdump command [%d]!" % rc) def countbandwidth(self, file): fp = open(file, "r") fp.seek(0) count = 0 sum = 0 while 1: line = fp.readline() if not line: return None if re.search("udp",line) or re.search("UDP,", line): count=count+1 linesplit = string.split(line," ") for j in range(len(linesplit)-1): if linesplit[j]=="udp": break if linesplit[j]=="length:": break try: sum = sum + int(linesplit[j+1]) except ValueError: self.CM.log("Invalid tcpdump line: %s" % line) return None T1 = linesplit[0] timesplit = string.split(T1,":") time2split = string.split(timesplit[2],".") time1 = (long(timesplit[0])*60+long(timesplit[1]))*60+long(time2split[0])+long(time2split[1])*0.000001 break while count < 100: line = fp.readline() if not line: return None if re.search("udp",line) or re.search("UDP,", line): count = count+1 linessplit = string.split(line," ") for j in range(len(linessplit)-1): if linessplit[j] =="udp": break if linesplit[j]=="length:": break try: sum=int(linessplit[j+1])+sum except ValueError: self.CM.log("Invalid tcpdump line: %s" % line) return None T2 = linessplit[0] timesplit = string.split(T2,":") time2split = string.split(timesplit[2],".") time2 = (long(timesplit[0])*60+long(timesplit[1]))*60+long(time2split[0])+long(time2split[1])*0.000001 time = time2-time1 if (time <= 0): return 0 return (sum*8)/time def is_applicable(self): '''BandwidthTest never applicable''' return 0 AllTestClasses.append(BandwidthTest) ################################################################### class MaintenanceMode(CTSTest): ################################################################### def __init__(self, cm): CTSTest.__init__(self,cm) self.name="MaintenanceMode" self.start = StartTest(cm) self.startall = SimulStartLite(cm) self.max=30 #self.is_unsafe = 1 self.benchmark = 1 self.action = "asyncmon" self.interval = 0 self.rid="maintenanceDummy" def toggleMaintenanceMode(self, node, action): pats = [] pats.append(self.CM["Pat:DC_IDLE"]) # fail the resource right after turning Maintenance mode on # verify it is not recovered until maintenance mode is turned off if action == "On": pats.append("Updating failcount for %s on .* after .* %s" % (self.rid, self.action)) else: pats.append("process_lrm_event: LRM operation %s_stop_0.*confirmed.*ok" % self.rid) pats.append("process_lrm_event: LRM operation %s_start_0.*confirmed.*ok" % self.rid) watch = self.create_watch(pats, 60) watch.setwatch() self.CM.debug("Turning maintenance mode %s" % action) self.CM.rsh(node, self.CM["MaintenanceMode%s" % (action)]) if (action == "On"): self.CM.rsh(node, "crm_resource -V -F -r %s -H %s &>/dev/null" % (self.rid, node)) self.set_timer("recover%s" % (action)) watch.lookforall() self.log_timer("recover%s" % (action)) if watch.unmatched: self.CM.debug("Failed to find patterns when turning maintenance mode %s" % action) return repr(watch.unmatched) return "" def insertMaintenanceDummy(self, node): pats = [] pats.append(".*%s.*process_lrm_event: LRM operation %s_start_0.*confirmed.*ok" % (node, self.rid)) watch = self.create_watch(pats, 60) watch.setwatch() self.CM.AddDummyRsc(node, self.rid) self.set_timer("addDummy") watch.lookforall() self.log_timer("addDummy") if watch.unmatched: self.CM.debug("Failed to find patterns when adding maintenance dummy resource") return repr(watch.unmatched) return "" def removeMaintenanceDummy(self, node): pats = [] pats.append("process_lrm_event: LRM operation %s_stop_0.*confirmed.*ok" % self.rid) watch = self.create_watch(pats, 60) watch.setwatch() self.CM.RemoveDummyRsc(node, self.rid) self.set_timer("removeDummy") watch.lookforall() self.log_timer("removeDummy") if watch.unmatched: self.CM.debug("Failed to find patterns when removing maintenance dummy resource") return repr(watch.unmatched) return "" def managedRscList(self, node): rscList = [] (rc, lines) = self.CM.rsh(node, "crm_resource -c", None) for line in lines: if re.search("^Resource", line): tmp = AuditResource(self.CM, line) if tmp.managed(): rscList.append(tmp.id) return rscList def verifyResources(self, node, rscList, managed): managedList = list(rscList) managed_str = "managed" if not managed: managed_str = "unmanaged" (rc, lines) = self.CM.rsh(node, "crm_resource -c", None) for line in lines: if re.search("^Resource", line): tmp = AuditResource(self.CM, line) if managed and not tmp.managed(): continue elif not managed and tmp.managed(): continue elif managedList.count(tmp.id): managedList.remove(tmp.id) if len(managedList) == 0: self.CM.debug("Found all %s resources on %s" % (managed_str, node)) return True self.CM.log("Could not find all %s resources on %s. %s" % (managed_str, node, managedList)) return False def __call__(self, node): '''Perform the 'MaintenanceMode' test. ''' self.incr("calls") verify_managed = False verify_unmanaged = False failPat = "" ret = self.startall(None) if not ret: return self.failure("Setup failed") # get a list of all the managed resources. We use this list # after enabling maintenance mode to verify all managed resources # become un-managed. After maintenance mode is turned off, we use # this list to verify all the resources become managed again. managedResources = self.managedRscList(node) if len(managedResources) == 0: self.CM.log("No managed resources on %s" % node) return self.skipped() # insert a fake resource we can fail during maintenance mode # so we can verify recovery does not take place until after maintenance # mode is disabled. failPat = failPat + self.insertMaintenanceDummy(node) # toggle maintenance mode ON, then fail dummy resource. failPat = failPat + self.toggleMaintenanceMode(node, "On") # verify all the resources are now unmanaged if self.verifyResources(node, managedResources, False): verify_unmanaged = True # Toggle maintenance mode OFF, verify dummy is recovered. failPat = failPat + self.toggleMaintenanceMode(node, "Off") # verify all the resources are now managed again if self.verifyResources(node, managedResources, True): verify_managed = True # Remove our maintenance dummy resource. failPat = failPat + self.removeMaintenanceDummy(node) self.CM.cluster_stable() if failPat != "": return self.failure("Unmatched patterns: %s" % (failPat)) elif verify_unmanaged is False: return self.failure("Failed to verify resources became unmanaged during maintenance mode") elif verify_managed is False: return self.failure("Failed to verify resources switched back to managed after disabling maintenance mode") return self.success() def errorstoignore(self): '''Return list of errors which should be ignored''' return [ """Updating failcount for %s""" % self.rid, """LogActions: Recover %s""" % self.rid, """Unknown operation: fail""", """(ERROR|error): sending stonithRA op to stonithd failed.""", """(ERROR|error): process_lrm_event: LRM operation %s_%s_%d""" % (self.rid, self.action, self.interval), """(ERROR|error): process_graph_event: Action %s_%s_%d .* initiated outside of a transition""" % (self.rid, self.action, self.interval), ] AllTestClasses.append(MaintenanceMode) ################################################################### class ResourceRecover(CTSTest): ################################################################### def __init__(self, cm): CTSTest.__init__(self,cm) self.name="ResourceRecover" self.start = StartTest(cm) self.startall = SimulStartLite(cm) self.max=30 self.rid=None self.rid_alt=None #self.is_unsafe = 1 self.benchmark = 1 # these are the values used for the new LRM API call self.action = "asyncmon" self.interval = 0 def __call__(self, node): '''Perform the 'ResourceRecover' test. ''' self.incr("calls") ret = self.startall(None) if not ret: return self.failure("Setup failed") resourcelist = self.CM.active_resources(node) # if there are no resourcelist, return directly if len(resourcelist)==0: self.CM.log("No active resources on %s" % node) return self.skipped() self.rid = self.CM.Env.RandomGen.choice(resourcelist) self.rid_alt = self.rid rsc = None (rc, lines) = self.CM.rsh(node, "crm_resource -c", None) for line in lines: if re.search("^Resource", line): tmp = AuditResource(self.CM, line) if tmp.id == self.rid: rsc = tmp # Handle anonymous clones that get renamed self.rid = rsc.clone_id break if not rsc: return self.failure("Could not find %s in the resource list" % self.rid) self.CM.debug("Shooting %s aka. %s" % (rsc.clone_id, rsc.id)) pats = [] pats.append("Updating failcount for %s on .* after .* %s" % (self.rid, self.action)) if rsc.managed(): pats.append("process_lrm_event: LRM operation %s_stop_0.*confirmed.*ok" % self.rid) if rsc.unique(): pats.append("process_lrm_event: LRM operation %s_start_0.*confirmed.*ok" % self.rid) else: # Anonymous clones may get restarted with a different clone number pats.append("process_lrm_event: LRM operation .*_start_0.*confirmed.*ok") watch = self.create_watch(pats, 60) watch.setwatch() self.CM.rsh(node, "crm_resource -V -F -r %s -H %s &>/dev/null" % (self.rid, node)) self.set_timer("recover") watch.lookforall() self.log_timer("recover") self.CM.cluster_stable() recovered=self.CM.ResourceLocation(self.rid) if watch.unmatched: return self.failure("Patterns not found: %s" % repr(watch.unmatched)) elif rsc.unique() and len(recovered) > 1: return self.failure("%s is now active on more than one node: %s"%(self.rid, repr(recovered))) elif len(recovered) > 0: self.CM.debug("%s is running on: %s" %(self.rid, repr(recovered))) elif rsc.managed(): return self.failure("%s was not recovered and is inactive" % self.rid) return self.success() def errorstoignore(self): '''Return list of errors which should be ignored''' return [ """Updating failcount for %s""" % self.rid, """LogActions: Recover %s""" % self.rid, """LogActions: Recover %s""" % self.rid_alt, """Unknown operation: fail""", """(ERROR|error): sending stonithRA op to stonithd failed.""", """(ERROR|error): process_lrm_event: LRM operation %s_%s_%d""" % (self.rid, self.action, self.interval), """(ERROR|error): process_graph_event: Action %s_%s_%d .* initiated outside of a transition""" % (self.rid, self.action, self.interval), ] AllTestClasses.append(ResourceRecover) ################################################################### class ComponentFail(CTSTest): ################################################################### def __init__(self, cm): CTSTest.__init__(self,cm) self.name="ComponentFail" self.startall = SimulStartLite(cm) self.complist = cm.Components() self.patterns = [] self.okerrpatterns = [] self.is_unsafe = 1 def __call__(self, node): '''Perform the 'ComponentFail' test. ''' self.incr("calls") self.patterns = [] self.okerrpatterns = [] # start all nodes ret = self.startall(None) if not ret: return self.failure("Setup failed") if not self.CM.cluster_stable(self.CM["StableTime"]): return self.failure("Setup failed - unstable") node_is_dc = self.CM.is_node_dc(node, None) # select a component to kill chosen = self.CM.Env.RandomGen.choice(self.complist) while chosen.dc_only == 1 and node_is_dc == 0: chosen = self.CM.Env.RandomGen.choice(self.complist) self.CM.debug("...component %s (dc=%d,boot=%d)" % (chosen.name, node_is_dc,chosen.triggersreboot)) self.incr(chosen.name) if chosen.name != "aisexec" and chosen.name != "corosync": if self.CM["Name"] != "crm-lha" or chosen.name != "pengine": self.patterns.append(self.CM["Pat:ChildKilled"] %(node, chosen.name)) self.patterns.append(self.CM["Pat:ChildRespawn"] %(node, chosen.name)) self.patterns.extend(chosen.pats) if node_is_dc: self.patterns.extend(chosen.dc_pats) # In an ideal world, this next stuff should be in the "chosen" object as a member function if self.CM["Name"] == "crm-lha" and chosen.triggersreboot: # Make sure the node goes down and then comes back up if it should reboot... for other in self.CM.Env["nodes"]: if other != node: self.patterns.append(self.CM["Pat:They_stopped"] %(other, self.CM.key_for_node(node))) self.patterns.append(self.CM["Pat:Slave_started"] % node) self.patterns.append(self.CM["Pat:Local_started"] % node) if chosen.dc_only: # Sometimes these will be in the log, and sometimes they won't... self.okerrpatterns.append("%s .*Process %s:.* exited" %(node, chosen.name)) self.okerrpatterns.append("%s .*I_ERROR.*crmdManagedChildDied" %node) self.okerrpatterns.append("%s .*The %s subsystem terminated unexpectedly" %(node, chosen.name)) self.okerrpatterns.append("(ERROR|error): Client .* exited with return code") else: # Sometimes this won't be in the log... self.okerrpatterns.append(self.CM["Pat:ChildKilled"] %(node, chosen.name)) self.okerrpatterns.append(self.CM["Pat:ChildRespawn"] %(node, chosen.name)) self.okerrpatterns.append(self.CM["Pat:ChildExit"]) # supply a copy so self.patterns doesnt end up empty tmpPats = [] tmpPats.extend(self.patterns) self.patterns.extend(chosen.badnews_ignore) # Look for STONITH ops, depending on Env["at-boot"] we might need to change the nodes status stonithPats = [] stonithPats.append(self.CM["Pat:Fencing_ok"] % node) stonith = self.create_watch(stonithPats, 0) stonith.setwatch() # set the watch for stable watch = self.create_watch( tmpPats, self.CM["DeadTime"] + self.CM["StableTime"] + self.CM["StartTime"]) watch.setwatch() # kill the component chosen.kill(node) self.CM.debug("Waiting for the cluster to recover") self.CM.cluster_stable() self.CM.debug("Waiting for any STONITHd node to come back up") self.CM.ns.WaitForAllNodesToComeUp(self.CM.Env["nodes"], 600) self.CM.debug("Waiting for the cluster to re-stabilize with all nodes") self.CM.cluster_stable(self.CM["StartTime"]) self.CM.debug("Checking if %s was shot" % node) shot = stonith.look(60) if shot: self.CM.debug("Found: "+ repr(shot)) self.okerrpatterns.append(self.CM["Pat:Fencing_start"] % node) if self.CM.Env["at-boot"] == 0: self.CM.ShouldBeStatus[node]="down" # If fencing occurred, chances are many (if not all) the expected logs # will not be sent - or will be lost when the node reboots return self.success() # check for logs indicating a graceful recovery matched = watch.lookforall(allow_multiple_matches=1) if watch.unmatched: self.CM.log("Patterns not found: " + repr(watch.unmatched)) self.CM.debug("Waiting for the cluster to re-stabilize with all nodes") is_stable = self.CM.cluster_stable(self.CM["StartTime"]) if not matched: return self.failure("Didn't find all expected patterns") elif not is_stable: return self.failure("Cluster did not become stable") return self.success() def errorstoignore(self): '''Return list of errors which should be ignored''' # Note that okerrpatterns refers to the last time we ran this test # The good news is that this works fine for us... self.okerrpatterns.extend(self.patterns) return self.okerrpatterns AllTestClasses.append(ComponentFail) #################################################################### class SplitBrainTest(CTSTest): #################################################################### '''It is used to test split-brain. when the path between the two nodes break check the two nodes both take over the resource''' def __init__(self,cm): CTSTest.__init__(self,cm) self.name = "SplitBrain" self.start = StartTest(cm) self.startall = SimulStartLite(cm) self.is_experimental = 1 def isolate_partition(self, partition): other_nodes = [] other_nodes.extend(self.CM.Env["nodes"]) for node in partition: try: other_nodes.remove(node) except ValueError: self.CM.log("Node "+node+" not in " + repr(self.CM.Env["nodes"]) + " from " +repr(partition)) if len(other_nodes) == 0: return 1 self.CM.debug("Creating partition: " + repr(partition)) self.CM.debug("Everyone else: " + repr(other_nodes)) for node in partition: if not self.CM.isolate_node(node, other_nodes): self.CM.log("Could not isolate %s" % node) return 0 return 1 def heal_partition(self, partition): other_nodes = [] other_nodes.extend(self.CM.Env["nodes"]) for node in partition: try: other_nodes.remove(node) except ValueError: self.CM.log("Node "+node+" not in " + repr(self.CM.Env["nodes"])) if len(other_nodes) == 0: return 1 self.CM.debug("Healing partition: " + repr(partition)) self.CM.debug("Everyone else: " + repr(other_nodes)) for node in partition: self.CM.unisolate_node(node, other_nodes) def __call__(self, node): '''Perform split-brain test''' self.incr("calls") self.passed = 1 partitions = {} ret = self.startall(None) if not ret: return self.failure("Setup failed") while 1: # Retry until we get multiple partitions partitions = {} p_max = len(self.CM.Env["nodes"]) for node in self.CM.Env["nodes"]: p = self.CM.Env.RandomGen.randint(1, p_max) if not partitions.has_key(p): partitions[p]= [] partitions[p].append(node) p_max = len(partitions.keys()) if p_max > 1: break # else, try again self.CM.debug("Created %d partitions" % p_max) for key in partitions.keys(): self.CM.debug("Partition["+str(key)+"]:\t"+repr(partitions[key])) # Disabling STONITH to reduce test complexity for now self.CM.rsh(node, "crm_attribute -V -n stonith-enabled -v false") for key in partitions.keys(): self.isolate_partition(partitions[key]) count = 30 while count > 0: if len(self.CM.find_partitions()) != p_max: time.sleep(10) else: break else: self.failure("Expected partitions were not created") # Target number of partitions formed - wait for stability if not self.CM.cluster_stable(): self.failure("Partitioned cluster not stable") # Now audit the cluster state self.CM.partitions_expected = p_max if not self.audit(): self.failure("Audits failed") self.CM.partitions_expected = 1 # And heal them again for key in partitions.keys(): self.heal_partition(partitions[key]) # Wait for a single partition to form count = 30 while count > 0: if len(self.CM.find_partitions()) != 1: time.sleep(10) count -= 1 else: break else: self.failure("Cluster did not reform") # Wait for it to have the right number of members count = 30 while count > 0: members = [] partitions = self.CM.find_partitions() if len(partitions) > 0: members = partitions[0].split() if len(members) != len(self.CM.Env["nodes"]): time.sleep(10) count -= 1 else: break else: self.failure("Cluster did not completely reform") # Wait up to 20 minutes - the delay is more preferable than # trying to continue with in a messed up state if not self.CM.cluster_stable(1200): self.failure("Reformed cluster not stable") answer = raw_input('Continue? [nY]') if answer and answer == "n": raise ValueError("Reformed cluster not stable") # Turn fencing back on if self.CM.Env["DoFencing"]: self.CM.rsh(node, "crm_attribute -V -D -n stonith-enabled") self.CM.cluster_stable() if self.passed: return self.success() return self.failure("See previous errors") def errorstoignore(self): '''Return list of errors which are 'normal' and should be ignored''' return [ "Another DC detected:", "(ERROR|error): attrd_cib_callback: .*Application of an update diff failed", "crmd_ha_msg_callback:.*not in our membership list", "CRIT:.*node.*returning after partition", ] def is_applicable(self): if not self.is_applicable_common(): return 0 return len(self.CM.Env["nodes"]) > 2 AllTestClasses.append(SplitBrainTest) #################################################################### class Reattach(CTSTest): #################################################################### def __init__(self, cm): CTSTest.__init__(self,cm) self.name="Reattach" self.startall = SimulStartLite(cm) self.restart1 = RestartTest(cm) self.stopall = SimulStopLite(cm) self.is_unsafe = 0 # Handled by canrunnow() def setup(self, node): attempt=0 if not self.startall(None): return None # Make sure we are really _really_ stable and that all # resources, including those that depend on transient node # attributes, are started while not self.CM.cluster_stable(double_check=True): if attempt < 5: attempt += 1 self.CM.debug("Not stable yet, re-testing") else: self.CM.log("Cluster is not stable") return None return 1 def teardown(self, node): # Make sure 'node' is up start = StartTest(self.CM) start(node) is_managed = self.CM.rsh(node, "crm_attribute -Q -G -t crm_config -n is-managed-default -d true", 1) is_managed = is_managed[:-1] # Strip off the newline if is_managed != "true": self.CM.log("Attempting to re-enable resource management on %s (%s)" % (node, is_managed)) managed = self.create_watch(["is-managed-default"], 60) managed.setwatch() self.CM.rsh(node, "crm_attribute -V -D -n is-managed-default") if not managed.lookforall(): self.CM.log("Patterns not found: " + repr(managed.unmatched)) self.CM.log("Could not re-enable resource management") return 0 return 1 def canrunnow(self, node): '''Return TRUE if we can meaningfully run right now''' if self.find_ocfs2_resources(node): self.CM.log("Detach/Reattach scenarios are not possible with OCFS2 services present") return 0 return 1 def __call__(self, node): self.incr("calls") pats = [] managed = self.create_watch(["is-managed-default"], 60) managed.setwatch() self.CM.debug("Disable resource management") self.CM.rsh(node, "crm_attribute -V -n is-managed-default -v false") if not managed.lookforall(): self.CM.log("Patterns not found: " + repr(managed.unmatched)) return self.failure("Resource management not disabled") pats = [] pats.append("process_lrm_event: .*_stop") pats.append("process_lrm_event: .*_start") pats.append("process_lrm_event: .*_promote") pats.append("process_lrm_event: .*_demote") pats.append("process_lrm_event: .*_migrate") watch = self.create_watch(pats, 60, "ShutdownActivity") watch.setwatch() self.CM.debug("Shutting down the cluster") ret = self.stopall(None) if not ret: self.CM.debug("Re-enable resource management") self.CM.rsh(node, "crm_attribute -V -D -n is-managed-default") return self.failure("Couldn't shut down the cluster") self.CM.debug("Bringing the cluster back up") ret = self.startall(None) time.sleep(5) # allow ping to update the CIB if not ret: self.CM.debug("Re-enable resource management") self.CM.rsh(node, "crm_attribute -V -D -n is-managed-default") return self.failure("Couldn't restart the cluster") if self.local_badnews("ResourceActivity:", watch): self.CM.debug("Re-enable resource management") self.CM.rsh(node, "crm_attribute -V -D -n is-managed-default") return self.failure("Resources stopped or started during cluster restart") watch = self.create_watch(pats, 60, "StartupActivity") watch.setwatch() managed = self.create_watch(["is-managed-default"], 60) managed.setwatch() self.CM.debug("Re-enable resource management") self.CM.rsh(node, "crm_attribute -V -D -n is-managed-default") if not managed.lookforall(): self.CM.log("Patterns not found: " + repr(managed.unmatched)) return self.failure("Resource management not enabled") self.CM.cluster_stable() # Ignore actions for STONITH resources ignore = [] (rc, lines) = self.CM.rsh(node, "crm_resource -c", None) for line in lines: if re.search("^Resource", line): r = AuditResource(self.CM, line) if r.rclass == "stonith": self.CM.debug("Ignoring start actions for %s" % r.id) ignore.append("process_lrm_event: LRM operation %s_start_0.*confirmed.*ok" % r.id) if self.local_badnews("ResourceActivity:", watch, ignore): return self.failure("Resources stopped or started after resource management was re-enabled") return ret def errorstoignore(self): '''Return list of errors which should be ignored''' return [ "resources were active at shutdown", "pingd: .*(ERROR|error): send_ipc_message:", "pingd: .*(ERROR|error): send_update:", "lrmd: .*(ERROR|error): notify_client:", ] def is_applicable(self): if self.CM["Name"] == "crm-lha": return None return 1 AllTestClasses.append(Reattach) #################################################################### class SpecialTest1(CTSTest): #################################################################### '''Set up a custom test to cause quorum failure issues for Andrew''' def __init__(self, cm): CTSTest.__init__(self,cm) self.name="SpecialTest1" self.startall = SimulStartLite(cm) self.restart1 = RestartTest(cm) self.stopall = SimulStopLite(cm) def __call__(self, node): '''Perform the 'SpecialTest1' test for Andrew. ''' self.incr("calls") # Shut down all the nodes... ret = self.stopall(None) if not ret: return self.failure("Could not stop all nodes") # Start the selected node ret = self.restart1(node) if not ret: return self.failure("Could not start "+node) # Start all remaining nodes ret = self.startall(None) if not ret: return self.failure("Could not start the remaining nodes") return self.success() AllTestClasses.append(SpecialTest1) #################################################################### class HAETest(CTSTest): #################################################################### '''Set up a custom test to cause quorum failure issues for Andrew''' def __init__(self, cm): CTSTest.__init__(self,cm) self.name="HAETest" self.stopall = SimulStopLite(cm) self.startall = SimulStartLite(cm) self.is_loop = 1 def setup(self, node): # Start all remaining nodes ret = self.startall(None) if not ret: return self.failure("Couldn't start all nodes") return self.success() def teardown(self, node): # Stop everything ret = self.stopall(None) if not ret: return self.failure("Couldn't stop all nodes") return self.success() def wait_on_state(self, node, resource, expected_clones, attempts=240): while attempts > 0: active=0 (rc, lines) = self.CM.rsh(node, "crm_resource -r %s -W -Q" % resource, stdout=None) # Hack until crm_resource does the right thing if rc == 0 and lines: active = len(lines) if len(lines) == expected_clones: return 1 elif rc == 1: self.CM.debug("Resource %s is still inactive" % resource) elif rc == 234: self.CM.log("Unknown resource %s" % resource) return 0 elif rc == 246: self.CM.log("Cluster is inactive") return 0 elif rc != 0: self.CM.log("Call to crm_resource failed, rc=%d" % rc) return 0 else: self.CM.debug("Resource %s is active on %d times instead of %d" % (resource, active, expected_clones)) attempts -= 1 time.sleep(1) return 0 def find_dlm(self, node): self.r_dlm = None (rc, lines) = self.CM.rsh(node, "crm_resource -c", None) for line in lines: if re.search("^Resource", line): r = AuditResource(self.CM, line) if r.rtype == "controld" and r.parent != "NA": self.CM.debug("Found dlm: %s" % self.r_dlm) self.r_dlm = r.parent return 1 return 0 def find_hae_resources(self, node): self.r_dlm = None self.r_o2cb = None self.r_ocfs2 = [] if self.find_dlm(node): self.find_ocfs2_resources(node) def is_applicable(self): if not self.is_applicable_common(): return 0 if self.CM.Env["Schema"] == "hae": return 1 return None #################################################################### class HAERoleTest(HAETest): #################################################################### def __init__(self, cm): '''Lars' mount/unmount test for the HA extension. ''' HAETest.__init__(self,cm) self.name="HAERoleTest" def change_state(self, node, resource, target): rc = self.CM.rsh(node, "crm_resource -V -r %s -p target-role -v %s --meta" % (resource, target)) return rc def __call__(self, node): self.incr("calls") lpc = 0 failed = 0 delay = 2 done=time.time() + self.CM.Env["loop-minutes"]*60 self.find_hae_resources(node) clone_max = len(self.CM.Env["nodes"]) while time.time() <= done and not failed: lpc = lpc + 1 self.change_state(node, self.r_dlm, "Stopped") if not self.wait_on_state(node, self.r_dlm, 0): self.failure("%s did not go down correctly" % self.r_dlm) failed = lpc self.change_state(node, self.r_dlm, "Started") if not self.wait_on_state(node, self.r_dlm, clone_max): self.failure("%s did not come up correctly" % self.r_dlm) failed = lpc if not self.wait_on_state(node, self.r_o2cb, clone_max): self.failure("%s did not come up correctly" % self.r_o2cb) failed = lpc for fs in self.r_ocfs2: if not self.wait_on_state(node, fs, clone_max): self.failure("%s did not come up correctly" % fs) failed = lpc if failed: return self.failure("iteration %d failed" % failed) return self.success() AllTestClasses.append(HAERoleTest) #################################################################### class HAEStandbyTest(HAETest): #################################################################### '''Set up a custom test to cause quorum failure issues for Andrew''' def __init__(self, cm): HAETest.__init__(self,cm) self.name="HAEStandbyTest" def change_state(self, node, resource, target): rc = self.CM.rsh(node, "crm_standby -V -l reboot -v %s" % (target)) return rc def __call__(self, node): self.incr("calls") lpc = 0 failed = 0 done=time.time() + self.CM.Env["loop-minutes"]*60 self.find_hae_resources(node) clone_max = len(self.CM.Env["nodes"]) while time.time() <= done and not failed: lpc = lpc + 1 self.change_state(node, self.r_dlm, "true") if not self.wait_on_state(node, self.r_dlm, clone_max-1): self.failure("%s did not go down correctly" % self.r_dlm) failed = lpc self.change_state(node, self.r_dlm, "false") if not self.wait_on_state(node, self.r_dlm, clone_max): self.failure("%s did not come up correctly" % self.r_dlm) failed = lpc if not self.wait_on_state(node, self.r_o2cb, clone_max): self.failure("%s did not come up correctly" % self.r_o2cb) failed = lpc for fs in self.r_ocfs2: if not self.wait_on_state(node, fs, clone_max): self.failure("%s did not come up correctly" % fs) failed = lpc if failed: return self.failure("iteration %d failed" % failed) return self.success() AllTestClasses.append(HAEStandbyTest) ################################################################### class NearQuorumPointTest(CTSTest): ################################################################### ''' This test brings larger clusters near the quorum point (50%). In addition, it will test doing starts and stops at the same time. Here is how I think it should work: - loop over the nodes and decide randomly which will be up and which will be down Use a 50% probability for each of up/down. - figure out what to do to get into that state from the current state - in parallel, bring up those going up and bring those going down. ''' def __init__(self, cm): CTSTest.__init__(self,cm) self.name="NearQuorumPoint" def __call__(self, dummy): '''Perform the 'NearQuorumPoint' test. ''' self.incr("calls") startset = [] stopset = [] stonith = self.CM.prepare_fencing_watcher("NearQuorumPoint") #decide what to do with each node for node in self.CM.Env["nodes"]: action = self.CM.Env.RandomGen.choice(["start","stop"]) #action = self.CM.Env.RandomGen.choice(["start","stop","no change"]) if action == "start" : startset.append(node) elif action == "stop" : stopset.append(node) self.CM.debug("start nodes:" + repr(startset)) self.CM.debug("stop nodes:" + repr(stopset)) #add search patterns watchpats = [ ] for node in stopset: if self.CM.ShouldBeStatus[node] == "up": watchpats.append(self.CM["Pat:We_stopped"] % node) for node in startset: if self.CM.ShouldBeStatus[node] == "down": #watchpats.append(self.CM["Pat:Slave_started"] % node) watchpats.append(self.CM["Pat:Local_started"] % node) else: for stopping in stopset: if self.CM.ShouldBeStatus[stopping] == "up": watchpats.append(self.CM["Pat:They_stopped"] % (node, self.CM.key_for_node(stopping))) if len(watchpats) == 0: return self.skipped() if len(startset) != 0: watchpats.append(self.CM["Pat:DC_IDLE"]) watch = self.create_watch(watchpats, self.CM["DeadTime"]+10) watch.setwatch() #begin actions for node in stopset: if self.CM.ShouldBeStatus[node] == "up": self.CM.StopaCMnoBlock(node) for node in startset: if self.CM.ShouldBeStatus[node] == "down": self.CM.StartaCMnoBlock(node) #get the result if watch.lookforall(): self.CM.cluster_stable() self.CM.fencing_cleanup("NearQuorumPoint", stonith) return self.success() self.CM.log("Warn: Patterns not found: " + repr(watch.unmatched)) #get the "bad" nodes upnodes = [] for node in stopset: if self.CM.StataCM(node) == 1: upnodes.append(node) downnodes = [] for node in startset: if self.CM.StataCM(node) == 0: downnodes.append(node) self.CM.fencing_cleanup,("NearQuorumPoint", stonith) if upnodes == [] and downnodes == []: self.CM.cluster_stable() # Make sure they're completely down with no residule for node in stopset: self.CM.rsh(node, self.CM["StopCmd"]) return self.success() if len(upnodes) > 0: self.CM.log("Warn: Unstoppable nodes: " + repr(upnodes)) if len(downnodes) > 0: self.CM.log("Warn: Unstartable nodes: " + repr(downnodes)) return self.failure() def is_applicable(self): if self.CM["Name"] == "crm-cman": return None return 1 AllTestClasses.append(NearQuorumPointTest) ################################################################### class RollingUpgradeTest(CTSTest): ################################################################### '''Perform a rolling upgrade of the cluster''' def __init__(self, cm): CTSTest.__init__(self,cm) self.name="RollingUpgrade" self.start = StartTest(cm) self.stop = StopTest(cm) self.stopall = SimulStopLite(cm) self.startall = SimulStartLite(cm) def setup(self, node): # Start all remaining nodes ret = self.stopall(None) if not ret: return self.failure("Couldn't stop all nodes") for node in self.CM.Env["nodes"]: if not self.downgrade(node, None): return self.failure("Couldn't downgrade %s" % node) ret = self.startall(None) if not ret: return self.failure("Couldn't start all nodes") return self.success() def teardown(self, node): # Stop everything ret = self.stopall(None) if not ret: return self.failure("Couldn't stop all nodes") for node in self.CM.Env["nodes"]: if not self.upgrade(node, None): return self.failure("Couldn't upgrade %s" % node) return self.success() def install(self, node, version, start=1, flags="--force"): target_dir = "/tmp/rpm-%s" % version src_dir = "%s/%s" % (self.CM.Env["rpm-dir"], version) self.CM.log("Installing %s on %s with %s" % (version, node, flags)) if not self.stop(node): return self.failure("stop failure: "+node) rc = self.CM.rsh(node, "mkdir -p %s" % target_dir) rc = self.CM.rsh(node, "rm -f %s/*.rpm" % target_dir) (rc, lines) = self.CM.rsh(node, "ls -1 %s/*.rpm" % src_dir, None) for line in lines: line = line[:-1] rc = self.CM.rsh.cp("%s" % (line), "%s:%s/" % (node, target_dir)) rc = self.CM.rsh(node, "rpm -Uvh %s %s/*.rpm" % (flags, target_dir)) if start and not self.start(node): return self.failure("start failure: "+node) return self.success() def upgrade(self, node, start=1): return self.install(node, self.CM.Env["current-version"], start) def downgrade(self, node, start=1): return self.install(node, self.CM.Env["previous-version"], start, "--force --nodeps") def __call__(self, node): '''Perform the 'Rolling Upgrade' test. ''' self.incr("calls") for node in self.CM.Env["nodes"]: if self.upgrade(node): return self.failure("Couldn't upgrade %s" % node) self.CM.cluster_stable() return self.success() def is_applicable(self): if not self.is_applicable_common(): return None if not self.CM.Env.has_key("rpm-dir"): return None if not self.CM.Env.has_key("current-version"): return None if not self.CM.Env.has_key("previous-version"): return None return 1 # Register RestartTest as a good test to run AllTestClasses.append(RollingUpgradeTest) ################################################################### class BSC_AddResource(CTSTest): ################################################################### '''Add a resource to the cluster''' def __init__(self, cm): CTSTest.__init__(self, cm) self.name="AddResource" self.resource_offset = 0 self.cib_cmd="""cibadmin -C -o %s -X '%s' """ def __call__(self, node): self.incr("calls") self.resource_offset = self.resource_offset + 1 r_id = "bsc-rsc-%s-%d" % (node, self.resource_offset) start_pat = "crmd.*%s_start_0.*confirmed.*ok" patterns = [] patterns.append(start_pat % r_id) watch = self.create_watch(patterns, self.CM["DeadTime"]) watch.setwatch() fields = string.split(self.CM.Env["IPBase"], '.') fields[3] = str(int(fields[3])+1) ip = string.join(fields, '.') self.CM.Env["IPBase"] = ip if not self.make_ip_resource(node, r_id, "ocf", "IPaddr", ip): return self.failure("Make resource %s failed" % r_id) failed = 0 watch_result = watch.lookforall() if watch.unmatched: for regex in watch.unmatched: self.CM.log ("Warn: Pattern not found: %s" % (regex)) failed = 1 if failed: return self.failure("Resource pattern(s) not found") if not self.CM.cluster_stable(self.CM["DeadTime"]): return self.failure("Unstable cluster") return self.success() def make_ip_resource(self, node, id, rclass, type, ip): self.CM.log("Creating %s::%s:%s (%s) on %s" % (rclass,type,id,ip,node)) rsc_xml=""" """ % (id, rclass, type, id, id, ip) node_constraint=""" """ % (id, id, id, id, node) rc = 0 (rc, lines) = self.CM.rsh(node, self.cib_cmd % ("constraints", node_constraint), None) if rc != 0: self.CM.log("Constraint creation failed: %d" % rc) return None (rc, lines) = self.CM.rsh(node, self.cib_cmd % ("resources", rsc_xml), None) if rc != 0: self.CM.log("Resource creation failed: %d" % rc) return None return 1 def is_applicable(self): if self.CM.Env["DoBSC"]: return 1 return None AllTestClasses.append(BSC_AddResource) class SimulStopLite(CTSTest): ################################################################### '''Stop any active nodes ~ simultaneously''' def __init__(self, cm): CTSTest.__init__(self,cm) self.name="SimulStopLite" def __call__(self, dummy): '''Perform the 'SimulStopLite' setup work. ''' self.incr("calls") self.CM.debug("Setup: " + self.name) # We ignore the "node" parameter... watchpats = [ ] for node in self.CM.Env["nodes"]: if self.CM.ShouldBeStatus[node] == "up": self.incr("WasStarted") watchpats.append(self.CM["Pat:We_stopped"] % node) #if self.CM.Env["use_logd"]: # watchpats.append(self.CM["Pat:Logd_stopped"] % node) if len(watchpats) == 0: self.CM.clear_all_caches() return self.success() # Stop all the nodes - at about the same time... watch = self.create_watch(watchpats, self.CM["DeadTime"]+10) watch.setwatch() self.set_timer() for node in self.CM.Env["nodes"]: if self.CM.ShouldBeStatus[node] == "up": self.CM.StopaCMnoBlock(node) if watch.lookforall(): self.CM.clear_all_caches() # Make sure they're completely down with no residule for node in self.CM.Env["nodes"]: self.CM.rsh(node, self.CM["StopCmd"]) return self.success() did_fail=0 up_nodes = [] for node in self.CM.Env["nodes"]: if self.CM.StataCM(node) == 1: did_fail=1 up_nodes.append(node) if did_fail: return self.failure("Active nodes exist: " + repr(up_nodes)) self.CM.log("Warn: All nodes stopped but CTS didnt detect: " + repr(watch.unmatched)) self.CM.clear_all_caches() return self.failure("Missing log message: "+repr(watch.unmatched)) def is_applicable(self): '''SimulStopLite is a setup test and never applicable''' return 0 ################################################################### class SimulStartLite(CTSTest): ################################################################### '''Start any stopped nodes ~ simultaneously''' def __init__(self, cm): CTSTest.__init__(self,cm) self.name="SimulStartLite" def __call__(self, dummy): '''Perform the 'SimulStartList' setup work. ''' self.incr("calls") self.CM.debug("Setup: " + self.name) # We ignore the "node" parameter... node_list = [] for node in self.CM.Env["nodes"]: if self.CM.ShouldBeStatus[node] == "down": self.incr("WasStopped") node_list.append(node) self.set_timer() while len(node_list) > 0: watchpats = [ ] uppat = self.CM["Pat:Slave_started"] if self.CM.upcount() == 0: uppat = self.CM["Pat:Local_started"] watchpats.append(self.CM["Pat:DC_IDLE"]) for node in node_list: watchpats.append(uppat % node) watchpats.append(self.CM["Pat:InfraUp"] % node) watchpats.append(self.CM["Pat:PacemakerUp"] % node) # Start all the nodes - at about the same time... watch = self.create_watch(watchpats, self.CM["DeadTime"]+10) watch.setwatch() stonith = self.CM.prepare_fencing_watcher(self.name) for node in node_list: self.CM.StartaCMnoBlock(node) watch.lookforall() node_list = self.CM.fencing_cleanup(self.name, stonith) # Remove node_list messages from watch.unmatched for node in node_list: if watch.unmatched: watch.unmatched.remove(uppat % node) if watch.unmatched: for regex in watch.unmatched: self.CM.log ("Warn: Startup pattern not found: %s" %(regex)) if not self.CM.cluster_stable(): return self.failure("Cluster did not stabilize") did_fail=0 unstable = [] for node in self.CM.Env["nodes"]: if self.CM.StataCM(node) == 0: did_fail=1 unstable.append(node) if did_fail: return self.failure("Unstarted nodes exist: " + repr(unstable)) unstable = [] for node in self.CM.Env["nodes"]: if not self.CM.node_stable(node): did_fail=1 unstable.append(node) if did_fail: return self.failure("Unstable cluster nodes exist: " + repr(unstable)) return self.success() def is_applicable(self): '''SimulStartLite is a setup test and never applicable''' return 0 def TestList(cm, audits): result = [] for testclass in AllTestClasses: bound_test = testclass(cm) if bound_test.is_applicable(): bound_test.Audits = audits result.append(bound_test) return result # vim:ts=4:sw=4:et: pacemaker-master/cts/CTSvars.py.in000077500000000000000000000004511217637305600174110ustar00rootroot00000000000000class CTSvars: CTS_home="@datadir@/@PACKAGE@/tests/cts" Fencing_home="@datadir@/@PACKAGE@/tests/cts" CRM_CONFIG_DIR="@CRM_CONFIG_DIR@" CRM_DAEMON_USER="@CRM_DAEMON_USER@" CRM_DAEMON_DIR="@CRM_DAEMON_DIR@" HA_VARLIBHBDIR="@HA_VARLIBHBDIR@" OCF_ROOT_DIR="@OCF_ROOT_DIR@" pacemaker-master/cts/LSBDummy.in000077500000000000000000000052461217637305600171000ustar00rootroot00000000000000#!/bin/sh # # # Dummy LSB RA. Does nothing but touch and remove a state file # # Copyright (c) 2010 Andrew Beekhof # All Rights Reserved. # # This program is free software; you can redistribute it and/or modify # it under the terms of version 2 of the GNU General Public License as # published by the Free Software Foundation. # # This program is distributed in the hope that it would be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # # Further, this software is distributed without any warranty that it is # free of the rightful claim of any third person regarding infringement # or the like. Any license provided herein, whether implied or # otherwise, applies only to this software file. Patent licenses, if # any, provided herein do not apply to combinations of this program with # other software, or any other product whatsoever. # # You should have received a copy of the GNU General Public License # along with this program; if not, write the Free Software Foundation, # Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. # ####################################################################### # Initialization: desc="Dummy LSB service" . @OCF_ROOT_DIR@/resource.d/heartbeat/.ocf-directories : ${HA_VARRUN=/tmp} # Backup in case .ocf-directories doesn't exist ####################################################################### success() { echo -ne "[ OK ]\r" } failure() { echo -ne "[FAILED]\r" } # rpm based distros if [ -d @sysconfdir@/sysconfig ]; then [ -f @INITDIR@/functions ] && . @INITDIR@/functions [ -f @sysconfdir@/sysconfig/pacemaker ] && . @sysconfdir@/sysconfig/pacemaker [ -z "$LOCK_FILE" ] && LOCK_FILE="@localstatedir@/lock/subsys/pacemaker" fi # deb based distros if [ -d @sysconfdir@/default ]; then [ -f @sysconfdir@/default/pacemaker ] && . @sysconfdir@/default/pacemaker [ -z "$LOCK_FILE" ] && LOCK_FILE="@localstatedir@/lock/pacemaker" fi dummy_usage() { cat < Copyright (C) 2004 International Business Machines Licensed under the GNU GPL. ''' # # 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 2 # of the License, 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 St, Fifth Floor, Boston, MA 02110-1301 USA. import string,sys,struct,os,random,time,syslog from cts.CTSvars import * def usage(): print "usage: " + sys.argv[0] \ + " [-2]"\ + " [--ipbase|-i first-test-ip]"\ + " [--ipnum|-n test-ip-num]"\ + " [--help|-h]"\ + " [--perform|-p op]"\ + " [number-of-iterations]" sys.exit(1) def perform_op(ra, ip, op): os.environ["OCF_RA_VERSION_MAJOR"] = "1" os.environ["OCF_RA_VERSION_MINOR"] = "0" os.environ["OCF_ROOT"] = CTSvars.OCF_ROOT_DIR os.environ["OCF_RESOURCE_INSTANCE"] = ip os.environ["OCF_RESOURCE_TYPE"] = ra os.environ["OCF_RESKEY_ip"] = ip os.environ["HA_LOGFILE"] = "/dev/null" os.environ["HA_LOGFACILITY"] = "local7" path = CTSvars.OCF_ROOT_DIR +"/resource.d/heartbeat/" + ra return os.spawnvpe(os.P_WAIT, path, [ra, op], os.environ) def audit(ra, iplist, ipstatus, summary): passed = 1 for ip in iplist: ret = perform_op(ra, ip, "monitor") if ret != ipstatus[ip]: passed = 0 log("audit: status of %s should be %d but it is %d\t [failure]"% (ip,ipstatus[ip],ret)) ipstatus[ip] = ret summary["audit"]["called"] += 1; if passed : summary["audit"]["success"] += 1 else : summary["audit"]["failure"] += 1 def log(towrite): t = time.strftime("%Y/%m/%d_%H:%M:%S\t", time.localtime(time.time())) logstr = t + " "+str(towrite) syslog.syslog(logstr) print logstr if __name__ == '__main__': ra = "IPaddr" ipbase = "127.0.0.10" ipnum = 1 itnum = 50 perform = None summary = { "start":{"called":0,"success":0,"failure":0}, "stop" :{"called":0,"success":0,"failure":0}, "audit":{"called":0,"success":0,"failure":0} } syslog.openlog(sys.argv[0], 0, syslog.LOG_LOCAL7) # Process arguments... skipthis = None args = sys.argv[1:] for i in range(0, len(args)) : if skipthis : skipthis = None continue elif args[i] == "-2" : ra = "IPaddr2" elif args[i] == "--ip" or args[i] == "-i" : skipthis = 1 ipbase = args[i+1] elif args[i] == "--ipnum" or args[i] == "-n" : skipthis = 1 ipnum = int(args[i+1]) elif args[i] == "--perform" or args[i] == "-p" : skipthis = 1 perform = args[i+1] elif args[i] == "--help" or args[i] == "-h" : usage() else: itnum = int(args[i]) log("Begin OCF IPaddr/IPaddr2 Test") # Generate the test ips iplist = [] ipstatus = {} fields = string.split(ipbase, '.') for i in range(0, ipnum) : ip = string.join(fields, '.') iplist.append(ip) ipstatus[ip]=perform_op(ra,ip,"monitor") fields[3] = str(int(fields[3])+1) log("Test ip:" + str(iplist)) # If use ask perform an operation if perform != None: log("Perform opeartion %s"%perform) for ip in iplist: perform_op(ra, ip, perform) log("Done") sys.exit() log("RA Type:" + ra) log("Test Count:" + str(itnum)) # Prepare Random f = open("/dev/urandom", "r") seed=struct.unpack("BBB", f.read(3)) f.close() #seed=(123,321,231) rand = random.Random() rand.seed(seed[0]) log("Test Random Seed:" + str(seed)) # # Begin Tests log(">>>>>>>>>>>>>>>>>>>>>>>>") for i in range(0, itnum): ip = rand.choice(iplist) if ipstatus[ip] == 0: op = "stop" elif ipstatus[ip] == 7: op = "start" else : op = rand.choice(["start","stop"]) ret = perform_op(ra, ip, op) # update status if op == "start" and ret == 0: ipstatus[ip] = 0 elif op == "stop" and ret == 0: ipstatus[ip] = 7 else : ipstatus[ip] = 1 result = "" if ret == 0: result = "success" else : result = "failure" summary[op]["called"] += 1 summary[op][result] += 1 log( "%d:%s %s \t[%s]"%(i, op, ip, result)) audit(ra, iplist, ipstatus, summary) log("<<<<<<<<<<<<<<<<<<<<<<<<") log("start:\t" + str(summary["start"])) log("stop: \t" + str(summary["stop"])) log("audit:\t" + str(summary["audit"])) pacemaker-master/cts/README000066400000000000000000000146561217637305600157760ustar00rootroot00000000000000BASIC REQUIREMENTS BEFORE STARTING: Three or more machines: one test exerciser and two or more test cluster machines. The two test cluster machines need to be on the same subnet and they should have journalling filesystems for all of their filesystems other than /boot You also need a number of free IP addresses on that subnet to test mutual IP address takeover The test exerciser machine doesn't need to be on the same subnet as the test cluster machines. Minimal demands are made on the exerciser machine - it just has to stay up during the tests. However, it does need to have a current copy of the cts test scripts. It is worth noting that these scripts are coordinated with particular versions of Pacemaker, so that in general you have to have the same version of test scripts as the rest of Pacemaker. Install Pacemaker on all machines. Configure cluster communications (Corosync, CMAN or Heartbeat) on the cluster machines and verify everything works. NOTE: Do not run the cluster on the test exerciser machine. NOTE: Wherever machine names are mentioned in these configuration files, they must match the machines' `uname -n` name. This may or may not match the machines' FQDN (fully qualified domain name) - it depends on how you (and your OS) have named the machines. It helps a lot in tracking problems if the three machines' clocks are closely synchronized. xntpd does this, but you can do it by hand if you want. Make sure all your filesystems are journalling filesystems (/boot can be ext2 if you want). This means filesystems like ext3. Here's what you need to do to run CTS: The exerciser needs to be able to ssh over to the cluster nodes as root without a password challenge. Configure ssh accordingly. (see the Mini-HOWTOs at the end for more details) The exerciser needs to be able to resolve the machine names of the test cluster - either by DNS or by /etc/hosts. Now assuming you did all this, what you need to do is run CTSlab.py python ./CTSlab.py [options] number-of-tests-to-run You must specify which nodes are part of the cluster: --nodes, eg. --node "pcmk-1 pcmk-2 pcmk-3" Most people will want to save the output: --outputfile, eg. --outputfile ~/cts.log Unless you want to test your own cluster configuration, you will also want: --clobber-cib --populate-resources --test-ip-base, eg. --test-ip-base 192.168.9.100 and configure some sort of fencing: --stonith, eg. --stonith rhcs to use fence_xvm or --stonith lha to use external/ssh A complete command line might look like: python ./CTSlab.py --nodes "pcmk-1 pcmk-2 pcmk-3" --outputfile ~/cts.log \ --clobber-cib --populate-resources --test-ip-base 192.168.9.100 \ --stonith rhcs 50 For other options, use the --help option and see the Mini-HOWTOs at the end for more details on setting up external/ssh. HINT: To extract the result of a particular test, run: crm_report -T $test ============== Mini-HOWTOs: ============== -------------------------------------------------------------------------------- How to make OpenSSH allow you to login as root across the network without a password. -------------------------------------------------------------------------------- All our scripts run ssh -l root, so you don't have to do any of your testing logged in as root on the test machine 1) Grab your key from the exerciser machine: take the single line out of ~/.ssh/identity.pub and put it into root's authorized_keys file. [This has changed to: copying the line from ~/.ssh/id_dsa.pub into root's authorized_keys file ] NOTE: If you don't have an id_dsa.pub file, create it by running: ssh-keygen -t dsa 2) Run this command on each of the cluster machines as root: ssh -v -l myid ererciser-machine cat /home/myid/.ssh/identity.pub \ >> ~root/.ssh/authorized_keys [For most people, this has changed to: ssh -v -l myid exerciser-machine cat /home/myid/.ssh/id_dsa.pub \ >> ~root/.ssh/authorized_keys ] You will probably have to provide your password, and possibly say "yes" to some questions about accepting the identity of the test machines 3) You must also do the corresponding update for the exerciser machine itself as root: cat /home/myid/.ssh/identity.pub >> ~root/.ssh/authorized_keys To test this, try this command from the exerciser machine for each of your cluster machines, and for the exerciser machine itself. ssh -l root cluster-machine If this works without prompting for a password, you're in business... If not, you need to look at the ssh/openssh documentation and the output from the -v options above... -------------------------------------------------------------------------------- How to configure OpenSSH for StonithdTest -------------------------------------------------------------------------------- This configure enables cluster machines to ssh over to each other without a password challenge. 1) On each of the cluster machines, grab your key: take the single line out of ~/.ssh/identity.pub and put it into root's authorized_keys file. [This has changed to: copying the line from ~/.ssh/id_dsa.pub into root's authorized_keys file ] NOTE: If you don't have an id_dsa.pub file, create it by running: ssh-keygen -t dsa 2) Run this command on each of the cluster machines as root: ssh -v -l myid cluster_machine_1 cat /home/myid/.ssh/identity.pub \ >> ~root/.ssh/authorized_keys ssh -v -l myid cluster_machine_2 cat /home/myid/.ssh/identity.pub \ >> ~root/.ssh/authorized_keys ...... ssh -v -l myid cluster_machine_n cat /home/myid/.ssh/identity.pub \ >> ~root/.ssh/authorized_keys [For most people, this has changed to: ssh -v -l myid cluster_machine cat /home/myid/.ssh/id_dsa.pub \ >> ~root/.ssh/authorized_keys ] You will probably have to provide your password, and possibly say "yes" to some questions about accepting the identity of the test machines To test this, try this command from any machine for each of other cluster machines, and for the machine itself. ssh -l root cluster-machine This should work without prompting for a password, If not, you need to look at the ssh/openssh documentation and the output from the -v options above... 3) Make sure the 'at' daemon is enabled on the test cluster machines This is normally the 'atd' service started by /etc/init.d/atd). This doesn't mean just start it, it means enable it to start on every boot into your default init state (probably either 3 or 5). Usually this can be achieved with: chkconfig --add atd chkconfig atd on pacemaker-master/cts/__init__.py000066400000000000000000000001121217637305600172050ustar00rootroot00000000000000# This file is required for python packages. # It is intentionally empty. pacemaker-master/cts/benchmark/000077500000000000000000000000001217637305600170345ustar00rootroot00000000000000pacemaker-master/cts/benchmark/Makefile.am000066400000000000000000000017401217637305600210720ustar00rootroot00000000000000# # heartbeat: Linux-HA heartbeat code # # Copyright (C) 2001 Michael Moerz # # 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 2 # of the License, 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. # MAINTAINERCLEANFILES = Makefile.in EXTRA_DIST = $(bench_SCRIPTS) $(bench_DATA) benchdir = $(datadir)/$(PACKAGE)/tests/cts/benchmark bench_DATA = README.benchmark control bench_SCRIPTS = clubench pacemaker-master/cts/benchmark/README.benchmark000066400000000000000000000050761217637305600216550ustar00rootroot00000000000000Cluster benchmarking tools ========================== This is a set of simple scripts to run and time Pacemaker CTS tests. The purpose is to investigate how the cluster stack behaves for different cluster sizes. Supported cluster stacks are openais (legacy), corosync, and heartbeat. Quick start ----------- - Create a directory to contain the output - Copy the example control file and edit it (optional) - Run the benchmark tests: # /usr/share/pacemaker/tests/cts/clubench (on the first run, it will create ~/.cts file to keep your CTS settings) - Create graphs from bench.csv Description ----------- The clubench shell script runs the benchmark. It depends on the working ssh, syslog configuration (loghost), and cluster configuration (stack dependent). The auxiliary cluster_test script from the CTS may be used to do the CTS configuration. It is stored in ~/.cts. The stack configuration has to be done by other means. Typically, it consists of creating and distributing the basic configuration files (openais.conf, corosync.conf, or ha.cf) and the authentication keys. The benchmark tests configuration is held in the control file: SERIES: a list of cluster sizes to be tested (optional, defaults to the fibonacci series including the node list length) RUNS: how many times to run CTS (optional, defaults to 3) CTSTESTS: CTS options to choose tests (optional, defaults to --benchmark) By default, all benchmark tests are run. Those are Restart Stonithd Standby ResourceRecover The CTS is run several times (RUNS) and then median is calculated. TODO: Stonithd should be updated to exclude time which takes the node to come up. Prerequisites ------------- The benchmark is run on the control host (loghost). The loghost must have the following packages installed: syslog-ng pacemaker The nodes must have the following packages installed: syslog-ng pacemaker cluster stack packages The usual prerequisite for CTS applies: ssh must work for root without password from loghost to all nodes and between nodes. Running the benchmark --------------------- usage: ./clubench dir: working directory (with the control file) # clubench output Output ------ The output is stored in the directory given as argument to clubench. hb_report generated reports are in subdirectories named after the number of nodes of test clusters, e.g. the set from the SERIES variable. The end product is stored in bench.csv. It can be imported in a spreadsheet application to generate graphs. bench.csv contains only medians and timings for all runs are stored in bench.stats. pacemaker-master/cts/benchmark/clubench.in000077500000000000000000000075531217637305600211640ustar00rootroot00000000000000#!/bin/sh # PROG=`basename $0` DIR=`dirname $0` SSHOPTS="-l root -o PasswordAuthentication=no -o ConnectTimeout=5" msg() { echo $@ >&2 } usage() { echo "usage: $0 " echo " dir: working directory (with the control file)" exit 0 } [ $# -eq 0 ] && usage WORKDIR=$1 test -d "$WORKDIR" || usage CTSCTRL=~/.cts CTRL=$WORKDIR/control CSV=$WORKDIR/bench.csv STATS=$WORKDIR/bench.stats test -f $CTRL && . $CTRL @datadir@/@PACKAGE@/tests/cts/cluster_test 500 || { msg "cluster_test failed" exit 1 } test -f $CTSCTRL || { msg no CTS control file $CTSCTRL exit 1 } . $CTSCTRL : ${CTS_logfacility:=local7} : ${CTS_stack:=corosync} : ${CTS_logfile:="/var/log/ha-log-bench"} : ${CTS_adv:="--schema pacemaker-1.2 --clobber-cib -r"} : ${RUNS:=3} : ${CTSTESTS:="--benchmark"} : ${CTSDIR:="@datadir@/@PACKAGE@/tests/cts"} [ "$CTS_node_list" ] || { msg no node list specified exit 1 } case "$CTS_stack" in openais|corosync) HB_REPORT_OPTS="-A";; heartbeat) HB_REPORT_OPTS="";; *) msg "$CTS_stack: cluster stack not recognized"; exit 1;; esac CTSOPTS="--stack $CTS_stack --at-boot $CTS_boot $CTS_adv" CTSOPTS="$CTSOPTS --facility $CTS_logfacility --logfile $CTS_logfile" if [ "x$CTS_stonith" != "x" ]; then CTSOPTS="$CTSOPTS --stonith-type $CTS_stonith" [ "x$CTS_stonith_args" != "x" ] && CTSOPTS="$CTSOPTS --stonitha-params \"$CTS_stonith_args\"" else CTSOPTS="$CTSOPTS --stonith 0" fi CTSOPTS="$CTSOPTS $CTSTESTS" fibonacci() { local limit=$1 local n=2 prev=1 tmp_n while [ $n -le $limit ]; do echo $n tmp_n=$n n=$((n+prev)) prev=$tmp_n done [ $prev -ne $limit ] && echo $limit } [ "$SERIES" ] || SERIES=$(fibonacci `echo $CTS_node_list | wc -w`) get_nodes() { local c_nodes c_nodes=`echo $CTS_node_list | awk -v n=$1 ' { for( i=1; i<=NF; i++ ) node[cnt++]=$i } END{for( i=0; i $odir/ctsrun.out 2>&1 & ctspid=$! tail -f $odir/ctsrun.out & tailpid=$! wait $ctspid kill $tailpid >/dev/null 2>&1 } bench_re='CTS:.*runtime:' diginfo() { local d v local ctsdir=$1 local s="$2" filter=$3 ( cd $ctsdir for r in [0-9]*.tar.bz2; do tar xjf $r d=`basename $r .tar.bz2` for v in `grep $bench_re $d/ha-log.txt | eval $filter`; do s="$s,$v" done rm -r $d done echo $s ) } printheader() { diginfo $1 "" "awk '{print \$(NF-2)}'" } printstats() { diginfo $1 "$clusize" "awk '{print \$(NF)}'" } printmedians() { local f=$1 local s="$clusize" local middle=$((RUNS/2 + 1)) set `head -1 $f | sed 's/,/ /g'` local cols=$# local i v for i in `seq 2 $cols`; do v=`awk -v i=$i -F, '{print $i}' < $f | sort -n | head -$middle | tail -1` s="$s,$v" done echo $s } rm -f $CSV tmpf=`mktemp` test -f "$tmpf" || { msg "can't create temporary file" exit 1 } trap "rm -f $tmpf" 0 for clusize in $SERIES; do nodes=`get_nodes $clusize` outdir=$WORKDIR/$clusize rm -rf $outdir mkdir -p $outdir rm -f $tmpf node_cleanup for i in `seq $RUNS`; do > $CTS_logfile mkdir -p $outdir/$i runcts $outdir/$i mkreports $outdir/$i printstats $outdir/$i >> $tmpf done [ -f "$CSV" ] || printheader $outdir/1 > $CSV printmedians $tmpf >> $CSV cat $tmpf >> $STATS msg "Statistics for $clusize-node cluster saved" done msg "Tests done for series $SERIES, output in $CSV and $STATS" pacemaker-master/cts/benchmark/control000066400000000000000000000002071217637305600204360ustar00rootroot00000000000000# SERIES="2 3 5 8" # test clusters of these sizes # RUNS=3 # how many times to run tests # CTSTESTS="--benchmark" # which tests to run pacemaker-master/cts/cluster_test000077500000000000000000000123431217637305600175530ustar00rootroot00000000000000#!/bin/bash anyAsked=0 if [ -e ~/.cts ]; then . ~/.cts fi CTS_master=`uname -n` CTS_numtests=$1 if [ "x$CTS_master" = "x" ]; then anyAsked=1 printf "This script should only be executed on the test master.\n" printf "The test master will remotely execute the actions required by the tests and should not be part of the cluster itself.\n" read -p "Is this host intended to be the test master? (yN)" CTS_master if [ "x$CTS_master" != "xy" ]; then printf "This script must be executed on the test master\n" exit 1 fi fi if [ "x$CTS_node_list" = "x" ]; then anyAsked=1 read -p "Please list your cluster nodes (eg. node1 node2 node3): " CTS_node_list else printf "Beginning test of cluster: $CTS_node_list\n" fi if [ "x$CTS_stack" = "x" ]; then anyAsked=1 read -p "Which cluster stack are you using? ([corosync], openais, or heartbeat): " CTS_stack if [ -z $CTS_stack ]; then CTS_stack=corosync fi else printf "Using the $CTS_stack cluster stack\n" fi tmp=`echo ${CTS_node_list} | sed s/$HOSTNAME//` if [ "x${CTS_node_list}" != "x${tmp}" ]; then printf "This script must be executed on the test master and the test master cannot be part of the cluster\n" exit 1 fi printf "+ Bootstraping ssh... " if [ -z $SSH_AUTH_SOCK ]; then printf "\n + Initializing SSH " agent_tmp=/tmp/.$$.ssh ssh-agent > $agent_tmp . $agent_tmp rm $agent_tmp printf " + Adding identities...\n" ssh-add rc=$? if [ $rc != 0 ]; then printf " -- No identities added\n" printf "\nThe ability to open key-based 'ssh' connections (as the user 'root') is required to use CTS.\n" read -p " - Do you want this program to help you create one? (yN)" auto_fix if [ "x$auto_fix" = "xy" ]; then ssh-keygen -t dsa ssh-add else printf "Please run 'ssh-keygen -t dsa' to create a new key\n" exit 1 fi fi else printf "OK\n" fi test_ok=1 printf "+ Testing ssh configuration... " for n in $CTS_node_list; do ssh -l root -o PasswordAuthentication=no -o ConnectTimeout=5 $n /bin/true rc=$? if [ $rc != 0 ]; then printf "\n - connection to $n failed" test_ok=0 fi done if [ $test_ok = 0 ]; then printf "\n\nThe ability to open key-based 'ssh' connections (as the user 'root') is required to use CTS.\n" printf " Please install one of your SSH public keys to root's account on all cluster nodes\n" # todo - look for identities and guide the installation of one exit 1 fi printf "OK\n" if [ -z $CTS_logfile ]; then anyAsked=1 read -p " + Where does/should syslog store logs from remote hosts? (/var/log/messages) " CTS_logfile if [ "x$CTS_logfile" = "x" ]; then CTS_logfile=/var/log/messages fi fi if [ ! -e $CTS_logfile ]; then printf "$CTS_logfile doesn't exist\n" exit 1 fi if [ -z $CTS_logfacility ]; then anyAsked=1 read -p " + Which log facility does the cluster use? (daemon) " CTS_logfacility if [ "x$CTS_logfacility" = "x" ]; then CTS_logfacility=daemon fi fi if [ -z $CTS_boot ]; then read -p "+ Is the cluster software started automatically when a node boots? [yN] " CTS_boot if [ -z $CTS_boot ]; then CTS_boot=0 else case $CTS_boot in 1|y|Y) CTS_boot=1;; *) CTS_boot=0;; esac fi fi if [ -z $CTS_numtests ]; then read -p "+ How many test iterations should be performed? (500) " CTS_numtests if [ -z $CTS_numtests ]; then CTS_numtests=500 fi fi if [ -z $CTS_asked_once ]; then anyAsked=1 read -p "+ What type of STONITH agent do you use? (none) " CTS_stonith if [ "x$CTS_stonith" != "x" ]; then read -p "+ List any STONITH agent parameters (eq. device_host=switch.power.com): " CTS_stonith_args fi if [ -z $CTS_adv ]; then read -p "+ (Advanced) Any extra CTS parameters? (none) " CTS_adv fi fi if [ $anyAsked = 1 ]; then read -p "+ Save values to ~/.cts for next time? (yN) " doSave fi if [ "x$doSave" = "xy" ]; then echo "# CTS Test data" > ~/.cts echo CTS_master=\"$CTS_master\" >> ~/.cts echo CTS_stack=\"$CTS_stack\" >> ~/.cts echo CTS_node_list=\"$CTS_node_list\" >> ~/.cts echo CTS_logfile=\"$CTS_logfile\" >> ~/.cts echo CTS_logport=$CTS_logport >> ~/.cts echo CTS_logfacility=$CTS_logfacility >> ~/.cts echo CTS_asked_once=1 >> ~/.cts echo CTS_adv=\"$CTS_adv\" >> ~/.cts echo CTS_stonith=$CTS_stonith >> ~/.cts echo CTS_stonith_args=\"$CTS_stonith_args\" >> ~/.cts echo CTS_boot=\"$CTS_boot\" >> ~/.cts fi cts_extra="" if [ "x$CTS_stonith" != "x" ]; then cts_extra="$cts_extra --stonith-type $CTS_stonith" if [ "x$CTS_stonith_args" != "x" ]; then cts_extra="$cts_extra --stonitha-params \"$CTS_stonith_args\"" fi else cts_extra="$cts_extra --stonith 0" printf " - Testing a cluster without STONITH is like a blunt pencil... pointless\n" fi printf "\nAll set to go for $CTS_numtests iterations!\n" if [ $anyAsked = 0 ]; then printf "+ To use a different configuration, remove ~/.cts and re-run cts (or edit it manually).\n" fi echo Now paste the following command into this shell: echo python "`dirname "$0"`"/CTSlab.py -L $CTS_logfile --syslog-facility $CTS_logfacility --no-unsafe-tests --stack $CTS_stack $CTS_adv --at-boot $CTS_boot $cts_extra $CTS_numtests --nodes \"$CTS_node_list\" pacemaker-master/cts/cts000077500000000000000000000137531217637305600156320ustar00rootroot00000000000000#!/bin/bash cts_root=`dirname $0` stonith=rhcs schema=1.1 stack=mcp logfile=0 summary=0 verbose=0 pengine=0 watch=0 saved=0 tests="" install=0 clean=0 build=0 kill=0 run=0 boot=0 custom_log="" patterns="-e CTS:" # Note the quotes around `$TEMP': they are essential! #TEMP=`getopt -o t:ac:sSvpe:lwf:d --long run,clean -n 'cts' -- "$@"` #eval set -- "$TEMP" while true; do case $1 in -x) set -x; shift;; -a) screen -ls | grep cts exit 0;; -c|-g) cluster_name=$2; shift; shift;; -S) summary=1; saved=1; shift;; -s) summary=1; shift;; -v) verbose=`expr $verbose + 1`; shift;; -p) pengine=1; shift;; -e) patterns="$patterns -e `echo $2 | sed 's/ /\\\W/g'`"; shift; shift;; -l) logfile=1; shift;; -w) watch=1; shift;; -f) summary=1; custom_log=$2; shift; shift;; -t) tests="$tests $2"; shift; shift;; [0-9]*) tests="$tests $1"; shift;; --build|build) build=1; shift;; --kill|kill) kill=1; shift; break;; --run|run) run=1; shift; break;; --boot|boot|start) boot=1; clean=1; shift; break;; --clean|clean) clean=1; shift;; --inst|--install|install) install=1; clean=1; shift;; local-init) local_root= case $cts_root in /*) local_root=`dirname $cts_root`;; *) local_root=`dirname $PWD/$cts_root`;; esac cat << EOF > $cts_root/CTSvars.py class CTSvars: CTS_home="$local_root/cts" Fencing_home="$local_root/fencing" CRM_CONFIG_DIR="/var/lib/pacemaker/cib" CRM_DAEMON_USER="hacluster" CRM_DAEMON_DIR="/usr/libexec/pacemaker" OCF_ROOT_DIR="/usr/lib/ocf" EOF files="extra/cluster-init extra/cluster-helper extra/cluster-clean tools/crm_report.in" for f in $files; do cp $local_root/$f $cts_root/ done cp $local_root/tools/report.common.in $local_root/tools/report.common sed -i.sed s:@localstatedir@:/var: $local_root/tools/report.common cp $cts_root/crm_report.in $cts_root/crm_report sed -i.sed s:@datadir@/@PACKAGE@:$local_root/tools: $cts_root/crm_report chmod +x $cts_root/crm_report cp $cts_root/LSBDummy.in $cts_root/LSBDummy chmod +x $local_root/fencing/fence_* sed -i.sed s:@OCF_ROOT_DIR@:/usr/lib/ocf: $cts_root/LSBDummy exit 0 ;; --wget) files="cluster-helper cluster-clean" for f in $files; do rm -f $cts_root/$f echo "Downloading helper script $f from GitHub" wget -O $cts_root/$f https://raw.github.com/ClusterLabs/pacemaker/master/extra/$f chmod +x $cts_root/$f done shift ;; --) shift; tests="$tests $*"; break;; "") break;; *) echo "Unknown argument: $1"; exit 1;; esac done # Add the location of this script export PATH="$PATH:$cts_root" which cluster-helper &>/dev/null if [ $? != 0 ]; then echo $0 needs the cluster-helper script to be in your path echo You can obtain it from: https://raw.github.com/ClusterLabs/pacemaker/master/extra/cluster-helper exit 1 fi which cluster-clean &>/dev/null if [ $? != 0 ]; then echo $0 needs the cluster-clean script to be in your path echo You can obtain it from: https://raw.github.com/ClusterLabs/pacemaker/master/extra/cluster-clean exit 1 fi if [ "x$cluster_name" = x -o "x$cluster_name" = xpick ]; then clusters=`ls -1 ~/.dsh/group/[a-z]+[0-9] | sed s/.*group.// | tr '\n' ' ' ` echo "custom) interactively define a cluster" for i in $clusters; do echo "$i) `cluster-helper --list short -g $i`" done read -p "Choose a cluster [custom]: " cluster_name echo fi if [ -z $cluster_name ]; then cluster_name=custom fi case $cluster_name in *) cluster_hosts=`cluster-helper --list short -g $cluster_name` cluster_log=~/cluster-$cluster_name.log; ;; custom) read -p "Cluster name: " cluster_name read -p "Cluster hosts: " cluster_hosts read -p "Cluster log file: " cluster_log ;; esac if [ $build = 1 -a $run = 1 ]; then install=1 clean=1 fi if [ $build = 1 ]; then which build-pcmk if [ $? != 0 ]; then echo "You'll need to write/obtain build-pcmk in order to build pacemaker from here. Skipping" else build-pcmk -18 rc=$? if [ $rc != 0 ]; then echo "Build failed: $rc" exit $rc fi fi fi if [ $clean = 1 ]; then rm -f $cluster_log; cluster-clean -g $cluster_name --kill elif [ $kill = 1 ]; then cluster-clean -g $cluster_name --kill-only fi if [ $install = 1 ]; then cluster-helper -g $cluster_name -- yum install -y pacemaker pacemaker-debuginfo pacemaker-cts libqb libqb-debuginfo fi if [ $boot = 1 ]; then $cts_root/CTSlab.py -g $cluster_name -r --stonith $stonith -c --schema pacemaker-$schema --stack $stack --boot rc=$? if [ $rc = 0 ]; then echo "The cluster is ready..." fi exit $rc elif [ $run = 1 ]; then $cts_root/CTSlab.py -g $cluster_name -r --stonith $stonith -c --schema pacemaker-$schema --stack $stack 500 $* exit $? elif [ $clean = 1 ]; then exit 0 fi screen -ls | grep cts-$cluster_name &>/dev/null active=$? if [ ! -z $custom_log ]; then cluster_log=$custom_log fi if [ "x$tests" != x -a "x$tests" != "x " ]; then for t in $tests; do echo "crm_report --cts-log $cluster_log -d -T $t" crm_report --cts-log $cluster_log -d -T $t done elif [ $logfile = 1 ]; then echo $cluster_log elif [ $summary = 1 ]; then files=$cluster_log if [ $saved = 1 ]; then files=`ls -1tr ~/CTS-*/cluster-log.txt` fi for f in $files; do echo $f case $verbose in 0) cat -n $f | grep $patterns | grep -v "CTS: debug:" ;; 1) cat -n $f | grep $patterns | grep -v "CTS:.* cmd:" ;; *) cat -n $f | grep $patterns ;; esac echo "" done elif [ $watch = 1 ]; then case $verbose in 0) tail -F $cluster_log | grep $patterns | grep -v "CTS: debug:" ;; 1) tail -F $cluster_log | grep $patterns | grep -v "CTS:.* cmd:" ;; *) tail -F $cluster_log | grep $patterns ;; esac elif [ $active = 0 ]; then screen -x cts-$cluster_name else touch $cluster_log # . ~/.bashrc # . $BASH_FILES/.heartbeat export cluster_name cluster_hosts cluster_log screen -S cts-$cluster_name bash fi pacemaker-master/cts/cts.supp000066400000000000000000000033661217637305600166140ustar00rootroot00000000000000# # Suppress (verified) bogus or unrelated errors reported by Valgrind # # Don't care # Non-recurring { libqb-dynamic-callsite Memcheck:Leak fun:calloc fun:qb_log_callsites_register } { libqb-init-1 Memcheck:Leak fun:malloc fun:strdup fun:qb_log_filter_ctl2 fun:crm_log_init } { libqb-init-2 Memcheck:Leak fun:calloc fun:qb_log_filter_ctl2 fun:crm_log_init } { pacemaker-init-1 Memcheck:Leak fun:malloc fun:strdup fun:crm_log_init } { glib-1 Memcheck:Leak fun:malloc fun:g_malloc fun:g_slice_alloc fun:g_slist_append fun:g_main_context_new fun:g_main_context_default fun:g_source_attach obj:/usr/lib64/libcrmcommon.so.2.0.0 fun:mainloop_add_signal } { glib-2 Memcheck:Leak fun:malloc fun:g_malloc fun:g_slice_alloc fun:g_slist_prepend fun:g_source_add_poll fun:G_main_add_fd fun:init_ais_connection fun:crm_cluster_connect } { glib-3 Memcheck:Leak fun:calloc fun:g_malloc0 fun:g_main_loop_new } { glib-4 Memcheck:Leak fun:malloc fun:g_malloc fun:g_slice_alloc fun:g_slice_alloc0 obj:/lib64/libglib-2.0.so.0.2200.2 fun:g_main_context_dispatch obj:/lib64/libglib-2.0.so.0.2200.2 fun:g_main_loop_run } # Not verified as bogus { Heartbeat-01 Memcheck:Param unlink(pathname) fun:unlink obj:/usr/lib64/libplumb.so.2.1.0 fun:G_CH_destroy_int obj:/lib64/libglib-2.0.so.0.2200.2 fun:g_main_context_dispatch obj:/lib64/libglib-2.0.so.0.2200.2 fun:g_main_loop_run } { OpenAIS-01 Memcheck:Param socketcall.sendmsg(msg.msg_iov[i]) fun:__sendmsg_nocancel obj:/usr/lib64/libcoroipcc.so.4.0.0 fun:coroipcc_service_connect fun:init_ais_connection fun:crm_cluster_connect } pacemaker-master/doc/000077500000000000000000000000001217637305600150565ustar00rootroot00000000000000pacemaker-master/doc/Clusters_from_Scratch/000077500000000000000000000000001217637305600213545ustar00rootroot00000000000000pacemaker-master/doc/Clusters_from_Scratch/en-US/000077500000000000000000000000001217637305600223035ustar00rootroot00000000000000pacemaker-master/doc/Clusters_from_Scratch/en-US/Ap-Configuration.txt000066400000000000000000000416131217637305600262160ustar00rootroot00000000000000[appendix] == Configuration Recap == === Final Cluster Configuration === ifdef::pcs[] [source,C] ---- # pcs resource Master/Slave Set: WebDataClone [WebData] Masters: [ pcmk-2 pcmk-1 ] Clone Set: dlm-clone [dlm] Started: [ pcmk-2 pcmk-1 ] Clone Set: ClusterIP-clone [ClusterIP] (unique) ClusterIP:0 (ocf::heartbeat:IPaddr2) Started ClusterIP:1 (ocf::heartbeat:IPaddr2) Started Clone Set: WebFS-clone [WebFS] Started: [ pcmk-1 pcmk-2 ] Clone Set: WebSite-clone [WebSite] Started: [ pcmk-1 pcmk-2 ] # pcs resource rsc defaults resource-stickiness: 100 # pcs resource op defaults timeout: 240s # pcs stonith impi-fencing (stonith:fence_ipmilan) Started # pcs property dc-version: 1.1.8-1.el7-60a19ed12fdb4d5c6a6b6767f52e5391e447fec0 cluster-infrastructure: corosync no-quorum-policy: ignore stonith-enabled: true # pcs constraint Location Constraints: Ordering Constraints: ClusterIP-clone then WebSite-clone WebDataClone then WebSite-clone WebFS-clone then WebSite-clone Colocation Constraints: WebSite-clone with ClusterIP-clone WebFS-clone with WebDataClone (with-rsc-role:Master) WebSite-clone with WebFS-clone # # pcs status Last updated: Fri Sep 14 13:45:34 2012 Last change: Fri Sep 14 13:43:13 2012 via cibadmin on pcmk-1 Stack: corosync Current DC: pcmk-1 (1) - partition with quorum Version: 1.1.8-1.el7-60a19ed12fdb4d5c6a6b6767f52e5391e447fec0 2 Nodes configured, unknown expected votes 11 Resources configured. Online: [ pcmk-1 pcmk-2 ] Full list of resources: Master/Slave Set: WebDataClone [WebData] Masters: [ pcmk-2 pcmk-1 ] Clone Set: dlm-clone [dlm] Started: [ pcmk-1 pcmk-2 ] Clone Set: ClusterIP-clone [ClusterIP] (unique) ClusterIP:0 (ocf::heartbeat:IPaddr2): Started pcmk-1 ClusterIP:1 (ocf::heartbeat:IPaddr2): Started pcmk-2 Clone Set: WebFS-clone [WebFS] Started: [ pcmk-1 pcmk-2 ] Clone Set: WebSite-clone [WebSite] Started: [ pcmk-1 pcmk-2 ] impi-fencing (stonith:fence_ipmilan): Started ---- In xml it should look similar to this. [source,XML] ---- ---- endif::[] ifdef::crmsh[] ..... # crm configure show node pcmk-1 node pcmk-2 primitive WebData ocf:linbit:drbd \ params drbd_resource="wwwdata" \ op monitor interval="60s" primitive WebFS ocf:heartbeat:Filesystem \ params device="/dev/drbd/by-res/wwwdata" directory="/var/www/html" fstype="gfs2" primitive WebSite ocf:heartbeat:apache \ params configfile="/etc/httpd/conf/httpd.conf" \ op monitor interval="1min" primitive ClusterIP ocf:heartbeat:IPaddr2 \ params ip="192.168.122.101" cidr_netmask="32" clusterip_hash="sourceip" \ op monitor interval="30s" primitive ipmi-fencing stonith::fence_ipmilan \ params pcmk_host_list="pcmk-1 pcmk-2" ipaddr=10.0.0.1 login=testuser passwd=abc123 \ op monitor interval="60s" ms WebDataClone WebData \ meta master-max="2" master-node-max="1" clone-max="2" clone-node-max="1" notify="true" clone WebFSClone WebFS clone WebIP ClusterIP \ meta globally-unique="true" clone-max="2" clone-node-max="2" clone WebSiteClone WebSite colocation WebSite-with-WebFS inf: WebSiteClone WebFSClone colocation fs_on_drbd inf: WebFSClone WebDataClone:Master colocation website-with-ip inf: WebSiteClone WebIP order WebFS-after-WebData inf: WebDataClone:promote WebFSClone:start order WebSite-after-WebFS inf: WebFSClone WebSiteClone order apache-after-ip inf: WebIP WebSiteClone property $id="cib-bootstrap-options" \ dc-version="1.1.5-bdd89e69ba545404d02445be1f3d72e6a203ba2f" \ cluster-infrastructure="openais" \ expected-quorum-votes="2" \ stonith-enabled="true" \ no-quorum-policy="ignore" rsc_defaults $id="rsc-options" \ resource-stickiness="100" ..... endif::[] === Node List === The list of cluster nodes is automatically populated by the cluster. ifdef::pcs[] ..... Pacemaker Nodes: Online: [ pcmk-1 pcmk-2 ] ..... endif::[] ifdef::crmsh[] ..... node pcmk-1 node pcmk-2 ..... endif::[] === Cluster Options === This is where the cluster automatically stores some information about the cluster * dc-version - the version (including upstream source-code hash) of Pacemaker used on the DC * cluster-infrastructure - the cluster infrastructure being used (heartbeat or openais) * expected-quorum-votes - the maximum number of nodes expected to be part of the cluster and where the admin can set options that control the way the cluster operates * stonith-enabled=true - Make use of STONITH * no-quorum-policy=ignore - Ignore loss of quorum and continue to host resources. ifdef::pcs[] [source,C] ---- # pcs property dc-version: 1.1.8-1.el7-60a19ed12fdb4d5c6a6b6767f52e5391e447fec0 cluster-infrastructure: corosync no-quorum-policy: ignore stonith-enabled: true ---- endif::[] ifdef::crmsh[] ..... property $id="cib-bootstrap-options" \ dc-version="1.1.5-bdd89e69ba545404d02445be1f3d72e6a203ba2f" \ cluster-infrastructure="openais" \ expected-quorum-votes="2" \ stonith-enabled="true" \ no-quorum-policy="ignore" ..... endif::[] === Resources === ==== Default Options ==== Here we configure cluster options that apply to every resource. ifdef::pcs[] * resource-stickiness - Specify the aversion to moving resources to other machines [source,C] ---- # pcs resource rsc defaults resource-stickiness: 100 ---- endif::[] ifdef::crmsh[] * resource-stickiness - Specify the aversion to moving resources to other machines ..... rsc_defaults $id="rsc-options" \ resource-stickiness="100" ..... endif::[] ==== Fencing ==== ifdef::pcs[] [source,C] ---- # pcs stonith show impi-fencing (stonith:fence_ipmilan) Started # pcs stonith show impi-fencing Resource: impi-fencing pcmk_host_list: pcmk-1 pcmk-2 ipaddr: 10.0.0.1 login: testuser passwd: acd123 ---- endif::[] ifdef::crmsh[] ..... primitive ipmi-fencing stonith::fence_ipmilan \ params pcmk_host_list="pcmk-1 pcmk-2" ipaddr=10.0.0.1 login=testuser passwd=abc123 \ op monitor interval="60s" clone Fencing rsa-fencing ..... endif::[] ==== Service Address ==== Users of the services provided by the cluster require an unchanging address with which to access it. Additionally, we cloned the address so it will be active on both nodes. An iptables rule (created as part of the resource agent) is used to ensure that each request only gets processed by one of the two clone instances. The additional meta options tell the cluster that we want two instances of the clone (one "request bucket" for each node) and that if one node fails, then the remaining node should hold both. ifdef::pcs[] [source,C] ---- # pcs resource show ClusterIP-clone Resource: ClusterIP-clone ip: 192.168.0.120 cidr_netmask: 32 clusterip_hash: sourceip globally-unique: true clone-max: 2 clone-node-max: 2 op monitor interval=30s ---- endif::[] ifdef::crmsh[] ..... primitive ClusterIP ocf:heartbeat:IPaddr2 \ params ip="192.168.122.101" cidr_netmask="32" clusterip_hash="sourceip" \ op monitor interval="30s" clone WebIP ClusterIP meta globally-unique="true" clone-max="2" clone-node-max="2" ..... endif::[] [NOTE] ======= TODO: The RA should check for globally-unique=true when cloned ======= ==== DRBD - Shared Storage ==== Here we define the DRBD service and specify which DRBD resource (from drbd.conf) it should manage. We make it a master/slave resource and, in order to have an active/active setup, allow both instances to be promoted by specifying master-max=2. We also set the notify option so that the cluster will tell DRBD agent when it's peer changes state. ifdef::pcs[] [source,C] ---- # pcs resource show WebDataClone Resource: WebDataClone drbd_resource: wwwdata master-node-max: 1 clone-max: 2 clone-node-max: 1 notify: true master-max: 2 op monitor interval=60s # pcs constraint ref WebDataClone Resource: WebDataClone colocation-WebFS-WebDataClone-INFINITY order-WebDataClone-WebFS-mandatory ---- endif::[] ifdef::crmsh[] ..... primitive WebData ocf:linbit:drbd \ params drbd_resource="wwwdata" \ op monitor interval="60s" ms WebDataClone WebData \ meta master-max="2" master-node-max="1" clone-max="2" clone-node-max="1" notify="true" ..... endif::[] ==== Cluster Filesystem ==== The cluster filesystem ensures that files are read and written correctly. We need to specify the block device (provided by DRBD), where we want it mounted and that we are using GFS2. Again it is a clone because it is intended to be active on both nodes. The additional constraints ensure that it can only be started on nodes with active gfs-control and drbd instances. ifdef::pcs[] [source,C] ---- # pcs resource show WebFS-clone Resource: WebFS-clone device: /dev/drbd/by-res/wwwdata directory: /var/www/html fstype: gfs2 # pcs constraint ref WebFS-clone Resource: WebFS-clone colocation-WebFS-WebDataClone-INFINITY colocation-WebSite-WebFS-INFINITY order-WebFS-WebSite-mandatory order-WebDataClone-WebFS-mandatory ---- endif::[] ifdef::crmsh[] ..... primitive WebFS ocf:heartbeat:Filesystem \ params device="/dev/drbd/by-res/wwwdata" directory="/var/www/html" fstype="gfs2" clone WebFSClone WebFS colocation WebFS-with-gfs-control inf: WebFSClone gfs-clone colocation fs_on_drbd inf: WebFSClone WebDataClone:Master order WebFS-after-WebData inf: WebDataClone:promote WebFSClone:start order start-WebFS-after-gfs-control inf: gfs-clone WebFSClone ..... endif::[] ==== Apache ==== Lastly we have the actual service, Apache. We need only tell the cluster where to find it's main configuration file and restrict it to running on nodes that have the required filesystem mounted and the IP address active. ifdef::pcs[] [source,C] ---- # pcs resource show WebSite-clone Resource: WebSite-clone configfile: /etc/httpd/conf/httpd.conf statusurl: http://localhost/server-status master-max: 2 op monitor interval=1min # pcs constraint ref WebSite-clone Resource: WebSite-clone colocation-WebSite-ClusterIP-INFINITY colocation-WebSite-WebFS-INFINITY order-ClusterIP-WebSite-mandatory order-WebFS-WebSite-mandatory ---- endif::[] ifdef::crmsh[] ..... primitive WebSite ocf:heartbeat:apache \ params configfile="/etc/httpd/conf/httpd.conf" \ op monitor interval="1min" clone WebSiteClone WebSite colocation WebSite-with-WebFS inf: WebSiteClone WebFSClone colocation website-with-ip inf: WebSiteClone WebIP order apache-after-ip inf: WebIP WebSiteClone order WebSite-after-WebFS inf: WebFSClone WebSiteClone ..... endif::[] pacemaker-master/doc/Clusters_from_Scratch/en-US/Ap-Corosync-Conf.txt000066400000000000000000000063671217637305600261000ustar00rootroot00000000000000[appendix] == Sample Corosync Configuration == ifdef::pcs[] .Sample corosync.conf for two-node cluster using a node list. ..... # Please read the corosync.conf.5 manual page totem { version: 2 secauth: off cluster_name: mycluster transport: udpu } nodelist { node { ring0_addr: pcmk-1 nodeid: 1 } node { ring0_addr: pcmk-2 nodeid: 2 } } quorum { provider: corosync_votequorum } logging { to_syslog: yes } ..... endif::[] ifdef::crmsh[] .Sample Corosync.conf for a two-node cluster using multicast. ..... # Please read the corosync.conf.5 manual page totem { version: 2 # cypto_cipher and crypto_hash: Used for mutual node authentication. # If you choose to enable this, then do remember to create a shared # secret with "corosync-keygen". crypto_cipher: none crypto_hash: none # interface: define at least one interface to communicate # over. If you define more than one interface stanza, you must # also set rrp_mode. interface { # Rings must be consecutively numbered, starting at 0. ringnumber: 0 # This is normally the *network* address of the # interface to bind to. This ensures that you can use # identical instances of this configuration file # across all your cluster nodes, without having to # modify this option. bindnetaddr: 192.168.122.0 # However, if you have multiple physical network # interfaces configured for the same subnet, then the # network address alone is not sufficient to identify # the interface Corosync should bind to. In that case, # configure the *host* address of the interface # instead: # bindnetaddr: 192.168.1.1 # When selecting a multicast address, consider RFC # 2365 (which, among other things, specifies that # 239.255.x.x addresses are left to the discretion of # the network administrator). Do not reuse multicast # addresses across multiple Corosync clusters sharing # the same network. mcastaddr: 239.255.1.1 # Corosync uses the port you specify here for UDP # messaging, and also the immediately preceding # port. Thus if you set this to 5405, Corosync sends # messages over UDP ports 5405 and 5404. mcastport: 4000 # Time-to-live for cluster communication packets. The # number of hops (routers) that this ring will allow # itself to pass. Note that multicast routing must be # specifically enabled on most network routers. ttl: 1 } } logging { # Log the source file and line where messages are being # generated. When in doubt, leave off. Potentially useful for # debugging. fileline: off # Log to standard error. When in doubt, set to no. Useful when # running in the foreground (when invoking "corosync -f") to_stderr: no # Log to a log file. When set to "no", the "logfile" option # must not be set. to_logfile: yes logfile: /var/log/cluster/corosync.log # Log to the system log daemon. When in doubt, set to yes. to_syslog: yes # Log debug messages (very verbose). When in doubt, leave off. debug: off # Log messages with time stamps. When in doubt, set to on # (unless you are only logging to syslog, where double # timestamps can be annoying). timestamp: on logger_subsys { subsys: QUORUM debug: off } } quorum { provider: corosync_votequorum expected_votes: 2 } ..... endif::[] pacemaker-master/doc/Clusters_from_Scratch/en-US/Ap-Reading.txt000066400000000000000000000005221217637305600247520ustar00rootroot00000000000000[appendix] == Further Reading == - Project Website http://www.clusterlabs.org - Cluster Commands A comprehensive guide to cluster commands has been written by SuSE and can be found at: http://www.suse.com/documentation/sle_ha/book_sleha/?page=/documentation/sle_ha/book_sleha/data/book_sleha.html - Corosync http://www.corosync.org pacemaker-master/doc/Clusters_from_Scratch/en-US/Author_Group.xml000066400000000000000000000014521217637305600254450ustar00rootroot00000000000000 AndrewBeekhof Red Hat Primary author andrew@beekhof.net RaoulScarazzini Italian translation rasca@miamammausalinux.org DanFrîncu Romanian translation df.cluster@gmail.com pacemaker-master/doc/Clusters_from_Scratch/en-US/Book_Info.xml000066400000000000000000000040101217637305600246650ustar00rootroot00000000000000 %BOOK_ENTITIES; ]> Clusters from Scratch Creating Active/Passive and Active/Active Clusters on Fedora Pacemaker 1.1 5 0 The purpose of this document is to provide a start-to-finish guide to building an example active/passive cluster with Pacemaker and show how it can be converted to an active/active one. The example cluster will use: &DISTRO; &DISTRO_VERSION; as the host operating system Corosync to provide messaging and membership services, Pacemaker to perform resource management, DRBD as a cost-effective alternative to shared storage, GFS2 as the cluster filesystem (in active/active mode) Given the graphical nature of the Fedora install process, a number of screenshots are included. However the guide is primarily composed of commands, the reasons for executing them and their expected outputs. pacemaker-master/doc/Clusters_from_Scratch/en-US/Ch-Active-Active.txt000066400000000000000000000544001217637305600260230ustar00rootroot00000000000000= Conversion to Active/Active = == Requirements == The primary requirement for an Active/Active cluster is that the data required for your services is available, simultaneously, on both machines. Pacemaker makes no requirement on how this is achieved, you could use a SAN if you had one available, however since DRBD supports multiple Primaries, we can also use that. The only hitch is that we need to use a cluster-aware filesystem. The one we used earlier with DRBD, ext4, is not one of those. Both OCFS2 and GFS2 are supported, however here we will use GFS2 which comes with Fedora 17. === Installing the required Software === [source,C] # yum install -y gfs2-utils dlm kernel-modules-extra ..... Loaded plugins: langpacks, presto, refresh-packagekit Resolving Dependencies --> Running transaction check ---> Package dlm.x86_64 0:3.99.4-1.fc17 will be installed ---> Package gfs2-utils.x86_64 0:3.1.4-3.fc17 will be installed ---> Package kernel-modules-extra.x86_64 0:3.4.4-3.fc17 will be installed --> Finished Dependency Resolution Dependencies Resolved ================================================================================ Package Arch Version Repository Size ================================================================================ Installing: dlm x86_64 3.99.4-1.fc17 updates 83 k gfs2-utils x86_64 3.1.4-3.fc17 fedora 214 k kernel-modules-extra x86_64 3.4.4-3.fc17 updates 1.7 M Transaction Summary ================================================================================ Install 3 Packages Total download size: 1.9 M Installed size: 7.7 M Downloading Packages: (1/3): dlm-3.99.4-1.fc17.x86_64.rpm | 83 kB 00:00 (2/3): gfs2-utils-3.1.4-3.fc17.x86_64.rpm | 214 kB 00:00 (3/3): kernel-modules-extra-3.4.4-3.fc17.x86_64.rpm | 1.7 MB 00:01 -------------------------------------------------------------------------------- Total 615 kB/s | 1.9 MB 00:03 Running Transaction Check Running Transaction Test Transaction Test Succeeded Running Transaction Installing : kernel-modules-extra-3.4.4-3.fc17.x86_64 1/3 Installing : gfs2-utils-3.1.4-3.fc17.x86_64 2/3 Installing : dlm-3.99.4-1.fc17.x86_64 3/3 Verifying : dlm-3.99.4-1.fc17.x86_64 1/3 Verifying : gfs2-utils-3.1.4-3.fc17.x86_64 2/3 Verifying : kernel-modules-extra-3.4.4-3.fc17.x86_64 3/3 Installed: dlm.x86_64 0:3.99.4-1.fc17 gfs2-utils.x86_64 0:3.1.4-3.fc17 kernel-modules-extra.x86_64 0:3.4.4-3.fc17 Complete! ..... == Create a GFS2 Filesystem == [[GFS2_prep]] === Preparation === Before we do anything to the existing partition, we need to make sure it is unmounted. We do this by telling the cluster to stop the WebFS resource. This will ensure that other resources (in our case, Apache) using WebFS are not only stopped, but stopped in the correct order. ifdef::pcs[] [source,C] ---- # pcs resource stop WebFS # pcs resource ClusterIP (ocf::heartbeat:IPaddr2) Started WebSite (ocf::heartbeat:apache) Stopped Master/Slave Set: WebDataClone [WebData] Masters: [ pcmk-2 ] Slaves: [ pcmk-1 ] WebFS (ocf::heartbeat:Filesystem) Stopped ---- endif::[] ifdef::crmsh[] [source,C] ----- # crm resource stop WebFS # crm_mon -1 ============ Last updated: Tue Apr 3 14:07:36 2012 Last change: Tue Apr 3 14:07:15 2012 via cibadmin on pcmk-1 Stack: corosync Current DC: pcmk-1 (1702537408) - partition with quorum Version: 1.1.7-2.fc17-ee0730e13d124c3d58f00016c3376a1de5323cff 2 Nodes configured, unknown expected votes 5 Resources configured. ============ Online: [ pcmk-1 pcmk-2 ] ClusterIP (ocf::heartbeat:IPaddr2): Started pcmk-2 Master/Slave Set: WebDataClone [WebData] Masters: [ pcmk-2 ] Slaves: [ pcmk-1 ] ----- endif::[] [NOTE] ======= Note that both Apache and WebFS have been stopped. ======= === Create and Populate an GFS2 Partition === Now that the cluster stack and integration pieces are running smoothly, we can create an GFS2 partition. [WARNING] ========= This will erase all previous content stored on the DRBD device. Ensure you have a copy of any important data. ========= We need to specify a number of additional parameters when creating a GFS2 partition. First we must use the -p option to specify that we want to use the the Kernel's DLM. Next we use -j to indicate that it should reserve enough space for two journals (one per node accessing the filesystem). ifdef::pcs[] Lastly, we use -t to specify the lock table name. The format for this field is +clustername:fsname+. For the +fsname+, we need to use the same value as specified in 'corosync.conf' for +cluster_name+. If you setup corosync with the same cluster name we used in this tutorial, cluster name will be 'mycluster'. If you are unsure what your cluster name is, open up /etc/corosync/corosync.conf, or execute the command 'pcs cluster corosync pcmk-1' to view the corosync config. The cluster name will be in the +totem+ block. endif::[] ifdef::crmsh[] Lastly, we use -t to specify the lock table name. The format for this field is +clustername:fsname+. For the +fsname+, we need to use the same value as specified in 'corosync.conf' for +cluster_name+. Just pick something unique and descriptive and add somewhere inside the +totem+ block. For example: ..... totem { version: 2 # cypto_cipher and crypto_hash: Used for mutual node authentication. # If you choose to enable this, then do remember to create a shared # secret with "corosync-keygen". crypto_cipher: none crypto_hash: none cluster_name: mycluster ... ..... [IMPORTANT] =========== Do this on each node in the cluster and be sure to restart them before continuing. =========== endif::[] [IMPORTANT] =========== We must run the next command on whichever node last had '/dev/drbd' mounted. Otherwise you will receive the message: ----- /dev/drbd1: Read-only file system ----- =========== [source,C] ----- # ssh pcmk-2 -- mkfs.gfs2 -p lock_dlm -j 2 -t mycluster:web /dev/drbd1 This will destroy any data on /dev/drbd1. It appears to contain: Linux rev 1.0 ext4 filesystem data, UUID=dc45fff3-c47a-4db2-96f7-a8049a323fe4 (extents) (large files) (huge files) Are you sure you want to proceed? [y/n]y Device: /dev/drbd1 Blocksize: 4096 Device Size 0.97 GB (253935 blocks) Filesystem Size: 0.97 GB (253932 blocks) Journals: 2 Resource Groups: 4 Locking Protocol: "lock_dlm" Lock Table: "mycluster" UUID: ed293a02-9eee-3fa3-ed1c-435ef1fd0116 ----- ifdef::pcs[] [source,C] ---- # pcs cluster cib dlm_cfg # pcs -f dlm_cfg resource create dlm ocf:pacemaker:controld op monitor interval=60s # pcs -f dlm_cfg resource clone dlm clone-max=2 clone-node-max=1 # pcs -f dlm_cfg resource show ClusterIP (ocf::heartbeat:IPaddr2) Started WebSite (ocf::heartbeat:apache) Stopped Master/Slave Set: WebDataClone [WebData] Masters: [ pcmk-2 ] Slaves: [ pcmk-1 ] WebFS (ocf::heartbeat:Filesystem) Stopped Clone Set: dlm-clone [dlm] Stopped: [ dlm:0 dlm:1 ] # pcs cluster push cib dlm_cfg CIB updated # pcs status Last updated: Fri Sep 14 12:54:50 2012 Last change: Fri Sep 14 12:54:43 2012 via cibadmin on pcmk-1 Stack: corosync Current DC: pcmk-1 (1) - partition with quorum Version: 1.1.8-1.el7-60a19ed12fdb4d5c6a6b6767f52e5391e447fec0 2 Nodes configured, unknown expected votes 7 Resources configured. Online: [ pcmk-1 pcmk-2 ] Full list of resources: ClusterIP (ocf::heartbeat:IPaddr2): Started pcmk-2 WebSite (ocf::heartbeat:apache): Stopped Master/Slave Set: WebDataClone [WebData] Masters: [ pcmk-2 ] Slaves: [ pcmk-1 ] WebFS (ocf::heartbeat:Filesystem): Stopped Clone Set: dlm-clone [dlm] Started: [ pcmk-1 pcmk-2 ] ---- endif::[] ifdef::crmsh[] [source,C] ----- # crm crm(live)# cib new dlm INFO: dlm shadow CIB created crm(dlm)# configure primitive dlm ocf:pacemaker:controld \ op monitor interval=60s crm(dlm)# configure clone dlm_clone dlm meta clone-max=2 clone-node-max=1 crm(dlm)# configure show node $id="1702537408" pcmk-1 \ attributes standby="off" node $id="1719314624" pcmk-2 primitive ClusterIP ocf:heartbeat:IPaddr2 \ params ip="192.168.122.120" cidr_netmask="32" \ op monitor interval="30s" primitive WebData ocf:linbit:drbd \ params drbd_resource="wwwdata" \ op monitor interval="60s" primitive WebFS ocf:heartbeat:Filesystem \ params device="/dev/drbd/by-res/wwwdata" directory="/var/www/html" fstype="ext4" \ meta target-role="Stopped" primitive WebSite ocf:heartbeat:apache \ params configfile="/etc/httpd/conf/httpd.conf" \ op monitor interval="1min" primitive dlm ocf:pacemaker:controld \ op monitor interval="60s" ms WebDataClone WebData \ meta master-max="1" master-node-max="1" clone-max="2" clone-node-max="1" notify="true" clone dlm_clone dlm \ meta clone-max="2" clone-node-max="1" location prefer-pcmk-1 WebSite 50: pcmk-1 colocation WebSite-with-WebFS inf: WebSite WebFS colocation fs_on_drbd inf: WebFS WebDataClone:Master colocation website-with-ip inf: WebSite ClusterIP order WebFS-after-WebData inf: WebDataClone:promote WebFS:start order WebSite-after-WebFS inf: WebFS WebSite order apache-after-ip inf: ClusterIP WebSite property $id="cib-bootstrap-options" \ dc-version="1.1.7-2.fc17-ee0730e13d124c3d58f00016c3376a1de5323cff" \ cluster-infrastructure="corosync" \ stonith-enabled="false" \ no-quorum-policy="ignore" \ last-lrm-refresh="1333446866" rsc_defaults $id="rsc-options" \ resource-stickiness="100" op_defaults $id="op-options" \ timeout="240s" crm(dlm)# cib commit dlm INFO: commited 'dlm' shadow CIB to the cluster crm(dlm)# quit bye # crm_mon -1 ============ Last updated: Wed Apr 4 01:15:11 2012 Last change: Wed Apr 4 00:50:11 2012 via crmd on pcmk-1 Stack: corosync Current DC: pcmk-1 (1702537408) - partition with quorum Version: 1.1.7-2.fc17-ee0730e13d124c3d58f00016c3376a1de5323cff 2 Nodes configured, unknown expected votes 7 Resources configured. ============ Online: [ pcmk-1 pcmk-2 ] ClusterIP (ocf::heartbeat:IPaddr2): Started pcmk-1 Master/Slave Set: WebDataClone [WebData] Masters: [ pcmk-1 ] Slaves: [ pcmk-2 ] Clone Set: dlm_clone [dlm] Started: [ pcmk-1 pcmk-2 ] ----- endif::[] Then (re)populate the new filesystem with data (web pages). For now we'll create another variation on our home page. [source,C] ----- # mount /dev/drbd1 /mnt/ # cat <<-END >/mnt/index.html My Test Site - GFS2 END # umount /dev/drbd1 # drbdadm verify wwwdata ----- == Reconfigure the Cluster for GFS2 == ifdef::pcs[] With the WebFS resource stopped, lets update the configuration. [source,C] ---- # pcs resource show WebFS Resource: WebFS device: /dev/drbd/by-res/wwwdata directory: /var/www/html fstype: ext4 target-role: Stopped ---- The fstype option needs to be updated to gfs2 instead of ext4. [source,C] ---- # pcs resource update WebFS fstype=gfs2 # pcs resource show WebFS Resource: WebFS device: /dev/drbd/by-res/wwwdata directory: /var/www/html fstype: gfs2 target-role: Stopped CIB updated ---- endif::[] ifdef::crmsh[] [source,C] ----- # crm crm(live) # cib new GFS2 INFO: GFS2 shadow CIB created crm(GFS2) # configure delete WebFS crm(GFS2) # configure primitive WebFS ocf:heartbeat:Filesystem params device="/dev/drbd/by-res/wwwdata" directory="/var/www/html" fstype="gfs2" ----- Now that we've recreated the resource, we also need to recreate all the constraints that used it. This is because the shell will automatically remove any constraints that referenced WebFS. [source,C] ----- crm(GFS2) # configure colocation WebSite-with-WebFS inf: WebSite WebFS crm(GFS2) # configure colocation fs_on_drbd inf: WebFS WebDataClone:Master crm(GFS2) # configure order WebFS-after-WebData inf: WebDataClone:promote WebFS:start crm(GFS2) # configure order WebSite-after-WebFS inf: WebFS WebSite crm(GFS2) # configure show node pcmk-1 node pcmk-2 primitive WebData ocf:linbit:drbd \ params drbd_resource="wwwdata" \ op monitor interval="60s" primitive WebFS ocf:heartbeat:Filesystem \ params device="/dev/drbd/by-res/wwwdata" directory="/var/www/html" fstype="gfs2" primitive WebSite ocf:heartbeat:apache \ params configfile="/etc/httpd/conf/httpd.conf" \ op monitor interval="1min" primitive ClusterIP ocf:heartbeat:IPaddr2 \ params ip="192.168.122.101" cidr_netmask="32" \ op monitor interval="30s" ms WebDataClone WebData \ meta master-max="1" master-node-max="1" clone-max="2" clone-node-max="1" notify="true" colocation WebSite-with-WebFS inf: WebSite WebFS colocation fs_on_drbd inf: WebFS WebDataClone:Master colocation website-with-ip inf: WebSite ClusterIP order WebFS-after-WebData inf: WebDataClone:promote WebFS:start order WebSite-after-WebFS inf: WebFS WebSite order apache-after-ip inf: ClusterIP WebSite property $id="cib-bootstrap-options" \ dc-version="1.1.5-bdd89e69ba545404d02445be1f3d72e6a203ba2f" \ cluster-infrastructure="openais" \ expected-quorum-votes="2" \ stonith-enabled="false" \ no-quorum-policy="ignore" rsc_defaults $id="rsc-options" \ resource-stickiness="100" ----- Review the configuration before uploading it to the cluster, quitting the shell and watching the cluster's response [source,C] ----- crm(GFS2) # cib commit GFS2 INFO: commited 'GFS2' shadow CIB to the cluster crm(GFS2) # quit bye # crm_mon ============ Last updated: Thu Sep 3 20:49:54 2009 Stack: openais Current DC: pcmk-2 - partition with quorum Version: 1.1.5-bdd89e69ba545404d02445be1f3d72e6a203ba2f 2 Nodes configured, 2 expected votes 6 Resources configured. ============ Online: [ pcmk-1 pcmk-2 ] WebSite (ocf::heartbeat:apache): Started pcmk-2 Master/Slave Set: WebDataClone Masters: [ pcmk-1 ] Slaves: [ pcmk-2 ] ClusterIP (ocf::heartbeat:IPaddr): Started pcmk-2WebFS (ocf::heartbeat:Filesystem): Started pcmk-1 ----- endif::[] == Reconfigure Pacemaker for Active/Active == Almost everything is in place. Recent versions of DRBD are capable of operating in Primary/Primary mode and the filesystem we're using is cluster aware. All we need to do now is reconfigure the cluster to take advantage of this. ifdef::pcs[] This will involve a number of changes, so we'll want work with a local cib file. [source,C] ---- # pcs cluster cib active_cfg ---- endif::[] ifdef::crmsh[] This will involve a number of changes, so we'll again use interactive mode. [source,C] ----- # crm # cib new active ----- endif::[] There's no point making the services active on both locations if we can't reach them, so lets first clone the IP address. Cloned IPaddr2 resources use an iptables rule to ensure that each request only gets processed by one of the two clone instances. The additional meta options tell the cluster how many instances of the clone we want (one "request bucket" for each node) and that if all other nodes fail, then the remaining node should hold all of them. Otherwise the requests would be simply discarded. ifdef::pcs[] ---- # pcs -f active_cfg resource clone ClusterIP \ globally-unique=true clone-max=2 clone-node-max=2 ---- Notice when the ClusterIP becomes a clone, the constraints referencing ClusterIP now reference the clone. This is done automatically by pcs. endif::[] ifdef::pcs[] [source,C] ---- # pcs -f active_cfg constraint Location Constraints: Ordering Constraints: start ClusterIP-clone then start WebSite WebFS then WebSite promote WebDataClone then start WebFS Colocation Constraints: WebSite with ClusterIP-clone WebFS with WebDataClone (with-rsc-role:Master) WebSite with WebFS ---- endif::[] ifdef::crmsh[] [source,C] ----- # configure clone WebIP ClusterIP \ meta globally-unique="true" clone-max="2" clone-node-max="2" ----- endif::[] Now we must tell the ClusterIP how to decide which requests are processed by which hosts. To do this we must specify the clusterip_hash parameter. ifdef::pcs[] [source,C] ---- # pcs -f active_cfg resource update ClusterIP clusterip_hash=sourceip ---- endif::[] ifdef::crmsh[] Open the ClusterIP resource [source,C] ----- # configure edit ClusterIP ----- And add the following to the params line ..... clusterip_hash="sourceip" ..... So that the complete definition looks like: ..... primitive ClusterIP ocf:heartbeat:IPaddr2 \ params ip="192.168.122.101" cidr_netmask="32" clusterip_hash="sourceip" \ op monitor interval="30s" ..... Here is the full transcript [source,C] ----- # crm crm(live) # cib new active INFO: active shadow CIB created crm(active) # configure clone WebIP ClusterIP \ meta globally-unique="true" clone-max="2" clone-node-max="2" crm(active) # configure shownode pcmk-1 node pcmk-2 primitive WebData ocf:linbit:drbd \ params drbd_resource="wwwdata" \ op monitor interval="60s" primitive WebFS ocf:heartbeat:Filesystem \ params device="/dev/drbd/by-res/wwwdata" directory="/var/www/html" fstype="gfs2" primitive WebSite ocf:heartbeat:apache \ params configfile="/etc/httpd/conf/httpd.conf" \ op monitor interval="1min" primitive ClusterIP ocf:heartbeat:IPaddr2 \ params ip="192.168.122.101" cidr_netmask="32" clusterip_hash="sourceip" \ op monitor interval="30s" ms WebDataClone WebData \ meta master-max="1" master-node-max="1" clone-max="2" clone-node-max="1" notify="true" clone WebIP ClusterIP \ meta globally-unique="true" clone-max="2" clone-node-max="2" colocation WebSite-with-WebFS inf: WebSite WebFS colocation fs_on_drbd inf: WebFS WebDataClone:Master colocation website-with-ip inf: WebSite WebIPorder WebFS-after-WebData inf: WebDataClone:promote WebFS:start order WebSite-after-WebFS inf: WebFS WebSiteorder apache-after-ip inf: WebIP WebSite property $id="cib-bootstrap-options" \ dc-version="1.1.5-bdd89e69ba545404d02445be1f3d72e6a203ba2f" \ cluster-infrastructure="openais" \ expected-quorum-votes="2" \ stonith-enabled="false" \ no-quorum-policy="ignore" rsc_defaults $id="rsc-options" \ resource-stickiness="100" ----- Notice how any constraints that referenced ClusterIP have been updated to use WebIP instead. This is an additional benefit of using the crm shell. endif::[] Next we need to convert the filesystem and Apache resources into clones. ifdef::pcs[] Notice how pcs automatically updates the relevant constraints again. [source,C] ---- # pcs -f active_cfg resource clone WebFS # pcs -f active_cfg resource clone WebSite # pcs -f active_cfg constraint Location Constraints: Ordering Constraints: start ClusterIP-clone then start WebSite-clone WebFS-clone then WebSite-clone promote WebDataClone then start WebFS-clone Colocation Constraints: WebSite-clone with ClusterIP-clone WebFS-clone with WebDataClone (with-rsc-role:Master) WebSite-clone with WebFS-clone ---- endif::[] ifdef::crmsh[] Again, the shell will automatically update any relevant constraints. [source,C] ----- crm(active) # configure clone WebFSClone WebFS crm(active) # configure clone WebSiteClone WebSite ----- endif::[] The last step is to tell the cluster that it is now allowed to promote both instances to be Primary (aka. Master). ifdef::pcs[] [source,C] ----- # pcs -f active_cfg resource update WebDataClone master-max=2 ----- endif::[] ifdef::crmsh[] [source,C] ----- crm(active) # configure edit WebDataClone ----- Change master-max to 2 [source,C] ----- crm(active) # configure show node pcmk-1 node pcmk-2 primitive WebData ocf:linbit:drbd \ params drbd_resource="wwwdata" \ op monitor interval="60s" primitive WebFS ocf:heartbeat:Filesystem \ params device="/dev/drbd/by-res/wwwdata" directory="/var/www/html" fstype="gfs2" primitive WebSite ocf:heartbeat:apache \ params configfile="/etc/httpd/conf/httpd.conf" \ op monitor interval="1min" primitive ClusterIP ocf:heartbeat:IPaddr2 \ params ip="192.168.122.101" cidr_netmask="32" clusterip_hash="sourceip" \ op monitor interval="30s" ms WebDataClone WebData \ meta master-max="2" master-node-max="1" clone-max="2" clone-node-max="1" notify="true" clone WebFSClone WebFSclone WebIP ClusterIP \ meta globally-unique="true" clone-max="2" clone-node-max="2" clone WebSiteClone WebSitecolocation WebSite-with-WebFS inf: WebSiteClone WebFSClone colocation fs_on_drbd inf: WebFSClone WebDataClone:Master colocation website-with-ip inf: WebSiteClone WebIP order WebFS-after-WebData inf: WebDataClone:promote WebFSClone:start order WebSite-after-WebFS inf: WebFSClone WebSiteClone order apache-after-ip inf: WebIP WebSiteClone property $id="cib-bootstrap-options" \ dc-version="1.1.5-bdd89e69ba545404d02445be1f3d72e6a203ba2f" \ cluster-infrastructure="openais" \ expected-quorum-votes="2" \ stonith-enabled="false" \ no-quorum-policy="ignore" rsc_defaults $id="rsc-options" \ resource-stickiness="100" ----- endif::[] Review the configuration before uploading it to the cluster, quitting the shell and watching the cluster's response ifdef::pcs[] [source,C] ----- # pcs cluster push cib active_cfg # pcs resource start WebFS ----- After all the processes are started the status should look similar to this. [source,C] ----- # pcs resource Master/Slave Set: WebDataClone [WebData] Masters: [ pcmk-2 pcmk-1 ] Clone Set: dlm-clone [dlm] Started: [ pcmk-2 pcmk-1 ] Clone Set: ClusterIP-clone [ClusterIP] (unique) ClusterIP:0 (ocf::heartbeat:IPaddr2) Started ClusterIP:1 (ocf::heartbeat:IPaddr2) Started Clone Set: WebFS-clone [WebFS] Started: [ pcmk-1 pcmk-2 ] Clone Set: WebSite-clone [WebSite] Started: [ pcmk-1 pcmk-2 ] ----- endif::[] ifdef::crmsh[] [source,C] ----- crm(active) # cib commit active INFO: commited 'active' shadow CIB to the cluster crm(active) # quit bye # crm_mon ============ Last updated: Thu Sep 3 21:37:27 2009 Stack: openais Current DC: pcmk-2 - partition with quorum Version: 1.1.5-bdd89e69ba545404d02445be1f3d72e6a203ba2f 2 Nodes configured, 2 expected votes 6 Resources configured. ============ Online: [ pcmk-1 pcmk-2 ] Master/Slave Set: WebDataClone Masters: [ pcmk-1 pcmk-2 ] Clone Set: WebIP Started: [ pcmk-1 pcmk-2 ] Clone Set: WebFSClone Started: [ pcmk-1 pcmk-2 ] Clone Set: WebSiteClone Started: [ pcmk-1 pcmk-2 ] Clone Set: dlm_clone Started: [ pcmk-1 pcmk-2 ] ----- endif::[] === Testing Recovery === [NOTE] ======= TODO: Put one node into standby to demonstrate failover ======= pacemaker-master/doc/Clusters_from_Scratch/en-US/Ch-Active-Passive.txt000066400000000000000000000463751217637305600262360ustar00rootroot00000000000000= Creating an Active/Passive Cluster = == Exploring the Existing Configuration == When Pacemaker starts up, it automatically records the number and details of the nodes in the cluster as well as which stack is being used and the version of Pacemaker being used. This is what the base configuration should look like. ifdef::pcs[] [source,C] ---- # pcs status Last updated: Fri Sep 14 10:12:01 2012 Last change: Fri Sep 14 09:51:55 2012 via crmd on pcmk-2 Stack: corosync Current DC: pcmk-1 (1) - partition with quorum Version: 1.1.8-1.el7-60a19ed12fdb4d5c6a6b6767f52e5391e447fec0 2 Nodes configured, unknown expected votes 0 Resources configured. Online: [ pcmk-1 pcmk-2 ] Full list of resources: ---- endif::[] ifdef::crmsh[] [source,C] ---- # crm configure show node $id="1702537408" pcmk-1 node $id="1719314624" pcmk-2 property $id="cib-bootstrap-options" \ dc-version="1.1.7-2.fc17-ee0730e13d124c3d58f00016c3376a1de5323cff" \ cluster-infrastructure="corosync" ---- endif::[] ifdef::pcs[] For those that are not of afraid of XML, you can see the raw cluster configuration and status by using the +pcs cluster cib+ command. .The last XML you'll see in this document ====== [source,C] ---- # pcs cluster cib ---- [source,XML] ---- ---- ====== endif::[] ifdef::crmsh[] For those that are not of afraid of XML, you can see the raw configuration by appending "xml" to the previous command. .The last XML you'll see in this document ====== [source,C] ---- # crm configure show xml ---- [source,XML] ---- ---- ====== endif::[] Before we make any changes, its a good idea to check the validity of the configuration. [source,C] ---- # crm_verify -L -V error: unpack_resources: Resource start-up disabled since no STONITH resources have been defined error: unpack_resources: Either configure some or disable STONITH with the stonith-enabled option error: unpack_resources: NOTE: Clusters with shared data need STONITH to ensure data integrity Errors found during check: config not valid -V may provide more details ---- As you can see, the tool has found some errors. In order to guarantee the safety of your data footnote:[If the data is corrupt, there is little point in continuing to make it available] , the default for STONITH footnote:[A common node fencing mechanism. Used to ensure data integrity by powering off "bad" nodes] in Pacemaker is +enabled+. However it also knows when no STONITH configuration has been supplied and reports this as a problem (since the cluster would not be able to make progress if a situation requiring node fencing arose). For now, we will disable this feature and configure it later in the Configuring STONITH section. It is important to note that the use of STONITH is highly encouraged, turning it off tells the cluster to simply pretend that failed nodes are safely powered off. Some vendors will even refuse to support clusters that have it disabled. To disable STONITH, we set the _stonith-enabled_ cluster option to false. ifdef::pcs[] [source,C] ---- # pcs property set stonith-enabled=false # crm_verify -L ---- endif::[] ifdef::crmsh[] [source,C] ---- # crm configure property stonith-enabled=false # crm_verify -L ---- endif::[] With the new cluster option set, the configuration is now valid. [WARNING] ========= The use of stonith-enabled=false is completely inappropriate for a production cluster. We use it here to defer the discussion of its configuration which can differ widely from one installation to the next. See <<_what_is_stonith>> for information on why STONITH is important and details on how to configure it. ========= == Adding a Resource == The first thing we should do is configure an IP address. Regardless of where the cluster service(s) are running, we need a consistent address to contact them on. Here I will choose and add 192.168.122.120 as the floating address, give it the imaginative name ClusterIP and tell the cluster to check that its running every 30 seconds. [IMPORTANT] =========== The chosen address must not be one already associated with a physical node =========== //// No syntax highlighting here to avoid line munging with source,C //// ifdef::pcs[] ---- # pcs resource create ClusterIP ocf:heartbeat:IPaddr2 \ ip=192.168.0.120 cidr_netmask=32 op monitor interval=30s ---- endif::[] ifdef::crmsh[] ---- # crm configure primitive ClusterIP ocf:heartbeat:IPaddr2 \ params ip=192.168.122.120 cidr_netmask=32 \ op monitor interval=30s ---- endif::[] The other important piece of information here is ocf:heartbeat:IPaddr2. This tells Pacemaker three things about the resource you want to add. The first field, ocf, is the standard to which the resource script conforms to and where to find it. The second field is specific to OCF resources and tells the cluster which namespace to find the resource script in, in this case heartbeat. The last field indicates the name of the resource script. ifdef::pcs[] To obtain a list of the available resource standards (the ocf part of ocf:heartbeat:IPaddr2), run [source,C] ---- # pcs resource standards ocf lsb service systemd stonith ---- To obtain a list of the available ocf resource providers (the heartbeat part of ocf:heartbeat:IPaddr2), run [source,C] ---- # pcs resource providers heartbeat linbit pacemaker redhat ---- Finally, if you want to see all the resource agents available for a specific ocf provider (the IPaddr2 part of ocf:heartbeat:IPaddr2), run [source,C] ---- # pcs resource agents ocf:heartbeat AoEtarget AudibleAlarm CTDB ClusterMon Delay Dummy . . (skipping lots of resources to save space) . IPaddr2 . . . symlink syslog-ng tomcat vmware ---- endif::[] ifdef::crmsh[] To obtain a list of the available resource classes, run [source,C] ---- # crm ra classes heartbeat lsb ocf / heartbeat pacemaker stonith ---- To then find all the OCF resource agents provided by Pacemaker and Heartbeat, run [source,C] ---- # crm ra list ocf pacemaker ClusterMon Dummy HealthCPU HealthSMART Stateful SysInfo SystemHealth controld o2cb ping pingd # crm ra list ocf heartbeat AoEtarget AudibleAlarm CTDB ClusterMon Delay Dummy EvmsSCC Evmsd Filesystem ICP IPaddr IPaddr2 IPsrcaddr IPv6addr LVM LinuxSCSI MailTo ManageRAID ManageVE Pure-FTPd Raid1 Route SAPDatabase SAPInstance SendArp ServeRAID SphinxSearchDaemon Squid Stateful SysInfo VIPArip VirtualDomain WAS WAS6 WinPopup Xen Xinetd anything apache conntrackd db2 drbd eDir88 ethmonitor exportfs fio iSCSILogicalUnit iSCSITarget ids iscsi jboss ldirectord lxc mysql mysql-proxy nfsserver nginx oracle oralsnr pgsql pingd portblock postfix proftpd rsyncd scsi2reservation sfex symlink syslog-ng tomcat vmware ---- endif::[] Now verify that the IP resource has been added and display the cluster's status to see that it is now active. ifdef::pcs[] [source,C] ---- # pcs status Last updated: Fri Sep 14 10:17:00 2012 Last change: Fri Sep 14 10:15:48 2012 via cibadmin on pcmk-1 Stack: corosync Current DC: pcmk-1 (1) - partition with quorum Version: 1.1.8-1.el7-60a19ed12fdb4d5c6a6b6767f52e5391e447fec0 2 Nodes configured, unknown expected votes 1 Resources configured. Online: [ pcmk-1 pcmk-2 ] Full list of resources: ClusterIP (ocf::heartbeat:IPaddr2): Started pcmk-1 ---- endif::[] ifdef::crmsh[] [source,C] ---- # crm configure show node $id="1702537408" pcmk-1 node $id="1719314624" pcmk-2 primitive ClusterIP ocf:heartbeat:IPaddr2 \ params ip="192.168.122.120" cidr_netmask="32" \ op monitor interval="30s" property $id="cib-bootstrap-options" \ dc-version="1.1.7-2.fc17-ee0730e13d124c3d58f00016c3376a1de5323cff" \ cluster-infrastructure="corosync" \ stonith-enabled="false" # crm_mon -1 ============ Last updated: Tue Apr 3 09:56:50 2012 Last change: Tue Apr 3 09:54:37 2012 via cibadmin on pcmk-1 Stack: corosync Current DC: pcmk-1 (1702537408) - partition with quorum Version: 1.1.7-2.fc17-ee0730e13d124c3d58f00016c3376a1de5323cff 2 Nodes configured, unknown expected votes 1 Resources configured. ============ Online: [ pcmk-1 pcmk-2 ] ClusterIP (ocf::heartbeat:IPaddr2): Started pcmk-1 ---- endif::[] == Perform a Failover == Being a high-availability cluster, we should test failover of our new resource before moving on. First, find the node on which the IP address is running. ifdef::pcs[] [source,C] ---- # pcs status Last updated: Fri Sep 14 10:17:00 2012 Last change: Fri Sep 14 10:15:48 2012 via cibadmin on pcmk-1 Stack: corosync Current DC: pcmk-1 (1) - partition with quorum Version: 1.1.8-1.el7-60a19ed12fdb4d5c6a6b6767f52e5391e447fec0 2 Nodes configured, unknown expected votes 1 Resources configured. Online: [ pcmk-1 pcmk-2 ] Full list of resources: ClusterIP (ocf::heartbeat:IPaddr2): Started pcmk-1 ---- endif::[] ifdef::crmsh[] [source,C] ---- # crm resource status ClusterIP resource ClusterIP is running on: pcmk-1 ---- endif::[] Shut down Pacemaker and Corosync on that machine. ifdef::pcs[] [source,C] ---- #pcs cluster stop pcmk-1 Stopping Cluster... ---- Once Corosync is no longer running, go to the other node and check the cluster status. [source,C] ---- # pcs status Last updated: Fri Sep 14 10:31:01 2012 Last change: Fri Sep 14 10:15:48 2012 via cibadmin on pcmk-1 Stack: corosync Current DC: pcmk-2 (2) - partition WITHOUT quorum Version: 1.1.8-1.el7-60a19ed12fdb4d5c6a6b6767f52e5391e447fec0 2 Nodes configured, unknown expected votes 1 Resources configured. Online: [ pcmk-2 ] OFFLINE: [ pcmk-1 ] Full list of resources: ClusterIP (ocf::heartbeat:IPaddr2): Stopped ---- endif::[] ifdef::crmsh[] [source,C] ---- # ssh pcmk-1 -- service pacemaker stop # ssh pcmk-1 -- service corosync stop ---- Once Corosync is no longer running, go to the other node and check the cluster status with crm_mon. [source,C] ---- # crm_mon -1 ============ Last updated: Tue Apr 3 10:01:28 2012 Last change: Tue Apr 3 09:54:39 2012 via cibadmin on pcmk-1 Stack: corosync Current DC: pcmk-2 (1719314624) - partition WITHOUT quorum Version: 1.1.7-2.fc17-ee0730e13d124c3d58f00016c3376a1de5323cff 2 Nodes configured, unknown expected votes 1 Resources configured. ============ Online: [ pcmk-2 ] OFFLINE: [ pcmk-1 ] ---- endif::[] There are three things to notice about the cluster's current state. The first is that, as expected, +pcmk-1+ is now offline. However we can also see that +ClusterIP+ isn't running anywhere! === Quorum and Two-Node Clusters === This is because the cluster no longer has quorum, as can be seen by the text "partition WITHOUT quorum" in the status output. In order to reduce the possibility of data corruption, Pacemaker's default behavior is to stop all resources if the cluster does not have quorum. A cluster is said to have quorum when more than half the known or expected nodes are online, or for the mathematically inclined, whenever the following equation is true: .... total_nodes < 2 * active_nodes .... Therefore a two-node cluster only has quorum when both nodes are running, which is no longer the case for our cluster. This would normally make the creation of a two-node cluster pointless footnote:[Actually some would argue that two-node clusters are always pointless, but that is an argument for another time] , however it is possible to control how Pacemaker behaves when quorum is lost. In particular, we can tell the cluster to simply ignore quorum altogether. ifdef::pcs[] [source,C] ---- # pcs property set no-quorum-policy=ignore # pcs property dc-version: 1.1.8-1.el7-60a19ed12fdb4d5c6a6b6767f52e5391e447fec0 cluster-infrastructure: corosync stonith-enabled: false no-quorum-policy: ignore ---- endif::[] ifdef::crmsh[] [source,C] ---- # crm configure property no-quorum-policy=ignore # crm configure show node $id="1702537408" pcmk-1 node $id="1719314624" pcmk-2 primitive ClusterIP ocf:heartbeat:IPaddr2 \ params ip="192.168.122.120" cidr_netmask="32" \ op monitor interval="30s" property $id="cib-bootstrap-options" \ dc-version="1.1.7-2.fc17-ee0730e13d124c3d58f00016c3376a1de5323cff" \ cluster-infrastructure="corosync" \ stonith-enabled="false" \ no-quorum-policy="ignore" ---- endif::[] After a few moments, the cluster will start the IP address on the remaining node. Note that the cluster still does not have quorum. ifdef::pcs[] [source,C] ---- # pcs status Last updated: Fri Sep 14 10:38:11 2012 Last change: Fri Sep 14 10:37:53 2012 via cibadmin on pcmk-2 Stack: corosync Current DC: pcmk-2 (2) - partition WITHOUT quorum Version: 1.1.8-1.el7-60a19ed12fdb4d5c6a6b6767f52e5391e447fec0 2 Nodes configured, unknown expected votes 1 Resources configured. Online: [ pcmk-2 ] OFFLINE: [ pcmk-1 ] Full list of resources: ClusterIP (ocf::heartbeat:IPaddr2): Started pcmk-2 ---- endif::[] ifdef::crmsh[] [source,C] ---- # crm_mon -1 ============ Last updated: Tue Apr 3 10:02:46 2012 Last change: Tue Apr 3 10:02:08 2012 via cibadmin on pcmk-2 Stack: corosync Current DC: pcmk-2 (1719314624) - partition WITHOUT quorum Version: 1.1.7-2.fc17-ee0730e13d124c3d58f00016c3376a1de5323cff 2 Nodes configured, unknown expected votes 1 Resources configured. ============ Online: [ pcmk-2 ] OFFLINE: [ pcmk-1 ] ClusterIP (ocf::heartbeat:IPaddr2): Started pcmk-2 ---- endif::[] Now simulate node recovery by restarting the cluster stack on +pcmk-1+ and check the cluster's status. Note, if you get an authentication error with the 'pcs cluster start pcmk-1' command, you must authenticate on the node using the 'pcs cluster auth pcmk pcmk-1 pcmk-2' command discussed earlier. ifdef::pcs[] [source,C] ---- # pcs cluster start pcmk-1 Starting Cluster... # pcs status Last updated: Fri Sep 14 10:42:56 2012 Last change: Fri Sep 14 10:37:53 2012 via cibadmin on pcmk-2 Stack: corosync Current DC: pcmk-2 (2) - partition with quorum Version: 1.1.8-1.el7-60a19ed12fdb4d5c6a6b6767f52e5391e447fec0 2 Nodes configured, unknown expected votes 1 Resources configured. Online: [ pcmk-1 pcmk-2 ] Full list of resources: ClusterIP (ocf::heartbeat:IPaddr2): Started pcmk-2 ---- endif::[] ifdef::crmsh[] [source,C] ---- # service corosync start Starting Corosync Cluster Engine (corosync): [ OK ] # service pacemaker start Starting Pacemaker Cluster Manager: [ OK ] # crm_mon ============ Last updated: Fri Aug 28 15:32:13 2009 Stack: openais Current DC: pcmk-2 - partition with quorum Version: 1.1.5-bdd89e69ba545404d02445be1f3d72e6a203ba2f 2 Nodes configured, 2 expected votes 1 Resources configured. ============ Online: [ pcmk-1 pcmk-2 ] ClusterIP (ocf::heartbeat:IPaddr): Started pcmk-2 ---- endif::[] [NOTE] ====== In the dark days, the cluster may have moved the IP back to its original location (+pcmk-1+). Usually this is no longer the case. ====== === Prevent Resources from Moving after Recovery === In most circumstances, it is highly desirable to prevent healthy resources from being moved around the cluster. Moving resources almost always requires a period of downtime. For complex services like Oracle databases, this period can be quite long. To address this, Pacemaker has the concept of resource stickiness which controls how much a service prefers to stay running where it is. You may like to think of it as the "cost" of any downtime. By default, Pacemaker assumes there is zero cost associated with moving resources and will do so to achieve "optimal" footnote:[It should be noted that Pacemaker's definition of optimal may not always agree with that of a human's. The order in which Pacemaker processes lists of resources and nodes creates implicit preferences in situations where the administrator has not explicitly specified them] resource placement. We can specify a different stickiness for every resource, but it is often sufficient to change the default. ifdef::pcs[] [source,C] ---- # pcs resource rsc defaults resource-stickiness=100 # pcs resource rsc defaults resource-stickiness: 100 ---- endif::[] ifdef::crmsh[] [source,C] ---- # crm configure rsc_defaults resource-stickiness=100 # crm configure show node $id="1702537408" pcmk-1 node $id="1719314624" pcmk-2 primitive ClusterIP ocf:heartbeat:IPaddr2 \ params ip="192.168.122.120" cidr_netmask="32" \ op monitor interval="30s" property $id="cib-bootstrap-options" \ dc-version="1.1.7-2.fc17-ee0730e13d124c3d58f00016c3376a1de5323cff" \ cluster-infrastructure="corosync" \ stonith-enabled="false" \ no-quorum-policy="ignore" rsc_defaults $id="rsc-options" \ resource-stickiness="100" ---- endif::[] pacemaker-master/doc/Clusters_from_Scratch/en-US/Ch-Apache.txt000066400000000000000000000622261217637305600245650ustar00rootroot00000000000000= Apache - Adding More Services = == Forward == Now that we have a basic but functional active/passive two-node cluster, we're ready to add some real services. We're going to start with Apache because its a feature of many clusters and relatively simple to configure. == Installation == Before continuing, we need to make sure Apache is installed on both hosts. We also need the wget tool in order for the cluster to be able to check the status of the Apache server. [source,C] # yum install -y httpd wget ..... Loaded plugins: langpacks, presto, refresh-packagekit fedora/metalink | 2.6 kB 00:00 updates/metalink | 3.2 kB 00:00 updates-testing/metalink | 41 kB 00:00 Resolving Dependencies --> Running transaction check ---> Package httpd.x86_64 0:2.2.22-3.fc17 will be installed --> Processing Dependency: httpd-tools = 2.2.22-3.fc17 for package: httpd-2.2.22-3.fc17.x86_64 --> Processing Dependency: apr-util-ldap for package: httpd-2.2.22-3.fc17.x86_64 --> Processing Dependency: libaprutil-1.so.0()(64bit) for package: httpd-2.2.22-3.fc17.x86_64 --> Processing Dependency: libapr-1.so.0()(64bit) for package: httpd-2.2.22-3.fc17.x86_64 --> Running transaction check ---> Package apr.x86_64 0:1.4.6-1.fc17 will be installed ---> Package apr-util.x86_64 0:1.4.1-2.fc17 will be installed ---> Package apr-util-ldap.x86_64 0:1.4.1-2.fc17 will be installed ---> Package httpd-tools.x86_64 0:2.2.22-3.fc17 will be installed --> Finished Dependency Resolution Dependencies Resolved ===================================================================================== Package Arch Version Repository Size ===================================================================================== Installing: httpd x86_64 2.2.22-3.fc17 updates-testing 823 k wget x86_64 1.13.4-2.fc17 fedora 495 k Installing for dependencies: apr x86_64 1.4.6-1.fc17 fedora 99 k apr-util x86_64 1.4.1-2.fc17 fedora 78 k apr-util-ldap x86_64 1.4.1-2.fc17 fedora 17 k httpd-tools x86_64 2.2.22-3.fc17 updates-testing 74 k Transaction Summary ===================================================================================== Install 1 Package (+4 Dependent packages) Total download size: 1.1 M Installed size: 3.5 M Downloading Packages: (1/6): apr-1.4.6-1.fc17.x86_64.rpm | 99 kB 00:00 (2/6): apr-util-1.4.1-2.fc17.x86_64.rpm | 78 kB 00:00 (3/6): apr-util-ldap-1.4.1-2.fc17.x86_64.rpm | 17 kB 00:00 (4/6): httpd-2.2.22-3.fc17.x86_64.rpm | 823 kB 00:01 (5/6): httpd-tools-2.2.22-3.fc17.x86_64.rpm | 74 kB 00:00 (6/6): wget-1.13.4-2.fc17.x86_64.rpm | 495 kB 00:01 ------------------------------------------------------------------------------------- Total 238 kB/s | 1.1 MB 00:04 Running Transaction Check Running Transaction Test Transaction Test Succeeded Running Transaction Installing : apr-1.4.6-1.fc17.x86_64 1/6 Installing : apr-util-1.4.1-2.fc17.x86_64 2/6 Installing : apr-util-ldap-1.4.1-2.fc17.x86_64 3/6 Installing : httpd-tools-2.2.22-3.fc17.x86_64 4/6 Installing : httpd-2.2.22-3.fc17.x86_64 5/6 Installing : wget-1.13.4-2.fc17.x86_64 6/6 Verifying : apr-util-ldap-1.4.1-2.fc17.x86_64 1/6 Verifying : httpd-tools-2.2.22-3.fc17.x86_64 2/6 Verifying : apr-util-1.4.1-2.fc17.x86_64 3/6 Verifying : apr-1.4.6-1.fc17.x86_64 4/6 Verifying : httpd-2.2.22-3.fc17.x86_64 5/6 Verifying : wget-1.13.4-2.fc17.x86_64 6/6 Installed: httpd.x86_64 0:2.2.22-3.fc17 wget.x86_64 0:1.13.4-2.fc17 Dependency Installed: apr.x86_64 0:1.4.6-1.fc17 apr-util.x86_64 0:1.4.1-2.fc17 apr-util-ldap.x86_64 0:1.4.1-2.fc17 httpd-tools.x86_64 0:2.2.22-3.fc17 Complete! ..... == Preparation == First we need to create a page for Apache to serve up. On Fedora the default Apache docroot is /var/www/html, so we'll create an index file there. [source,C] ----- # cat <<-END >/var/www/html/index.html My Test Site - pcmk-1 END ----- For the moment, we will simplify things by serving up only a static site and manually sync the data between the two nodes. So run the command again on pcmk-2. [source,C] ----- [root@pcmk-2 ~]# cat <<-END >/var/www/html/index.html My Test Site - pcmk-2 END ----- == Enable the Apache status URL == In order to monitor the health of your Apache instance, and recover it if it fails, the resource agent used by Pacemaker assumes the server-status URL is available. Look for the following in '/etc/httpd/conf/httpd.conf' and make sure it is not disabled or commented out: [source,Apache Configuration] ----- SetHandler server-status Order deny,allow Deny from all Allow from 127.0.0.1 ----- == Update the Configuration == At this point, Apache is ready to go, all that needs to be done is to add it to the cluster. Lets call the resource WebSite. We need to use an OCF script called apache in the heartbeat namespace footnote:[Compare the key used here ocf:heartbeat:apache with the one we used earlier for the IP address: ocf:heartbeat:IPaddr2] , the only required parameter is the path to the main Apache configuration file and we'll tell the cluster to check once a minute that apache is still running. ifdef::pcs[] //// source,C doesn't deal well with \'s //// ----- pcs resource create WebSite ocf:heartbeat:apache \ configfile=/etc/httpd/conf/httpd.conf \ statusurl="http://localhost/server-status" op monitor interval=1min ----- By default, the operation timeout for all resource's start, stop, and monitor operations is 20 seconds. In many cases this timeout period is less than the advised timeout period. For the purposes of this tutorial, we will adjust the global operation timeout default to 240 seconds. [source,C] ----- # pcs resource op defaults timeout=240s # pcs resource op defaults timeout: 240s ----- endif::[] ifdef::crmsh[] [source,Bash] ----- # crm configure primitive WebSite ocf:heartbeat:apache \ params configfile=/etc/httpd/conf/httpd.conf \ statusurl="http://localhost/server-status" \ op monitor interval=1min WARNING: WebSite: default timeout 20s for start is smaller than the advised 40s WARNING: WebSite: default timeout 20s for stop is smaller than the advised 60s ----- The easiest way resolve this, is to change the default: [source,Bash] ----- # crm configure op_defaults timeout=240s # crm configure show node $id="1702537408" pcmk-1 node $id="1719314624" pcmk-2 primitive ClusterIP ocf:heartbeat:IPaddr2 \ params ip="192.168.122.120" cidr_netmask="32" \ op monitor interval="30s" primitive WebSite ocf:heartbeat:apache \ params configfile="/etc/httpd/conf/httpd.conf" \ op monitor interval="1min" property $id="cib-bootstrap-options" \ dc-version="1.1.7-2.fc17-ee0730e13d124c3d58f00016c3376a1de5323cff" \ cluster-infrastructure="corosync" \ stonith-enabled="false" \ no-quorum-policy="ignore" rsc_defaults $id="rsc-options" \ resource-stickiness="100" op_defaults $id="op-options" \ timeout="240s" ----- endif::[] After a short delay, we should see the cluster start apache ifdef::pcs[] [source,C] ----- # pcs status Last updated: Fri Sep 14 10:51:27 2012 Last change: Fri Sep 14 10:50:46 2012 via crm_attribute on pcmk-1 Stack: corosync Current DC: pcmk-2 (2) - partition with quorum Version: 1.1.8-1.el7-60a19ed12fdb4d5c6a6b6767f52e5391e447fec0 2 Nodes configured, unknown expected votes 2 Resources configured. Online: [ pcmk-1 pcmk-2 ] Full list of resources: ClusterIP (ocf::heartbeat:IPaddr2): Started pcmk-2 WebSite (ocf::heartbeat:apache): Started pcmk-1 ----- endif::[] ifdef::crmsh[] [source,C] ----- # crm_mon -1 ============ Last updated: Tue Apr 3 11:54:29 2012 Last change: Tue Apr 3 11:54:26 2012 via crmd on pcmk-1 Stack: corosync Current DC: pcmk-1 (1702537408) - partition with quorum Version: 1.1.7-2.fc17-ee0730e13d124c3d58f00016c3376a1de5323cff 2 Nodes configured, unknown expected votes 2 Resources configured. ============ Online: [ pcmk-1 pcmk-2 ] ClusterIP (ocf:heartbeat:IPaddr2): Started pcmk-2 WebSite (ocf:heartbeat:apache): Started pcmk-1 ----- endif::[] Wait a moment, the WebSite resource isn't running on the same host as our IP address! ifdef::pcs[] [NOTE] ====== If, in the `pcs status` output, you see the WebSite resource has failed to start, then you've likely not enabled the status URL correctly. You can check if this is the problem by running: .... wget http://127.0.0.1/server-status .... If you see +Connection refused+ in the output, then this is indeed the problem. Check to ensure that +Allow from 127.0.0.1+ is present for the ++ block. ====== endif::[] ifdef::crmsh[] [NOTE] ====== If, in the `crm_mon` output, you see: .... Failed actions: WebSite_start_0 (node=pcmk-2, call=301, rc=1, status=complete): unknown error .... Then you've likely not enabled the status URL correctly. You can check if this is the problem by running: .... wget http://127.0.0.1/server-status .... If you see +Connection refused+ in the output, then this is indeed the problem. Check to ensure that +Allow from 127.0.0.1+ is present for the ++ block. ====== endif::[] == Ensuring Resources Run on the Same Host == To reduce the load on any one machine, Pacemaker will generally try to spread the configured resources across the cluster nodes. However we can tell the cluster that two resources are related and need to run on the same host (or not at all). Here we instruct the cluster that WebSite can only run on the host that ClusterIP is active on. ifdef::pcs[] To achieve this we use a colocation constraint that indicates it is mandatory for WebSite to run on the same node as ClusterIP. The "mandatory" part of the colocation constraint is indicated by using a score of INFINITY. The INFINITY score also means that if ClusterIP is not active anywhere, WebSite will not be permitted to run. endif::[] ifdef::crmsh[] For the constraint, we need a name (choose something descriptive like website-with-ip), indicate that its mandatory (so that if ClusterIP is not active anywhere, WebSite will not be permitted to run anywhere either) by specifying a score of INFINITY and finally list the two resources. endif::[] [NOTE] ======= If ClusterIP is not active anywhere, WebSite will not be permitted to run anywhere. ======= [IMPORTANT] =========== Colocation constraints are "directional", in that they imply certain things about the order in which the two resources will have a location chosen. In this case we're saying +WebSite+ needs to be placed on the same machine as +ClusterIP+, this implies that we must know the location of +ClusterIP+ before choosing a location for +WebSite+. =========== ifdef::pcs[] [source,C] ----- # pcs constraint colocation add WebSite ClusterIP INFINITY # pcs constraint Location Constraints: Ordering Constraints: Colocation Constraints: WebSite with ClusterIP # pcs status Last updated: Fri Sep 14 11:00:44 2012 Last change: Fri Sep 14 11:00:25 2012 via cibadmin on pcmk-1 Stack: corosync Current DC: pcmk-2 (2) - partition with quorum Version: 1.1.8-1.el7-60a19ed12fdb4d5c6a6b6767f52e5391e447fec0 2 Nodes configured, unknown expected votes 2 Resources configured. Online: [ pcmk-1 pcmk-2 ] Full list of resources: ClusterIP (ocf::heartbeat:IPaddr2): Started pcmk-2 WebSite (ocf::heartbeat:apache): Started pcmk-2 ----- endif::[] ifdef::crmsh[] [source,C] ----- # crm configure colocation website-with-ip INFINITY: WebSite ClusterIP # crm configure show node $id="1702537408" pcmk-1 node $id="1719314624" pcmk-2 primitive ClusterIP ocf:heartbeat:IPaddr2 \ params ip="192.168.122.120" cidr_netmask="32" \ op monitor interval="30s" primitive WebSite ocf:heartbeat:apache \ params configfile="/etc/httpd/conf/httpd.conf" \ op monitor interval="1min" colocation website-with-ip inf: WebSite ClusterIP property $id="cib-bootstrap-options" \ dc-version="1.1.7-2.fc17-ee0730e13d124c3d58f00016c3376a1de5323cff" \ cluster-infrastructure="corosync" \ stonith-enabled="false" \ no-quorum-policy="ignore" \ last-lrm-refresh="1333446866" rsc_defaults $id="rsc-options" \ resource-stickiness="100" op_defaults $id="op-options" \ timeout="240s" # crm_mon -1 ============ Last updated: Tue Apr 3 11:57:13 2012 Last change: Tue Apr 3 11:56:10 2012 via cibadmin on pcmk-1 Stack: corosync Current DC: pcmk-2 (1719314624) - partition with quorum Version: 1.1.7-2.fc17-ee0730e13d124c3d58f00016c3376a1de5323cff 2 Nodes configured, unknown expected votes 2 Resources configured. ============ Online: [ pcmk-1 pcmk-2 ] ClusterIP (ocf:heartbeat:IPaddr2): Started pcmk-2 WebSite (ocf:heartbeat:apache): Started pcmk-2 ----- endif::[] == Controlling Resource Start/Stop Ordering == When Apache starts, it binds to the available IP addresses. It doesn't know about any addresses we add afterwards, so not only do they need to run on the same node, but we need to make sure ClusterIP is already active before we start WebSite. We do this by adding an ordering constraint. ifdef::pcs[] By default all order constraints are mandatory constraints unless otherwise configured. This means that the recovery of ClusterIP will also trigger the recovery of WebSite. [source,C] ----- # pcs constraint order ClusterIP then WebSite Adding ClusterIP WebSite (kind: Mandatory) (Options: first-action=start then-action=start) # pcs constraint Location Constraints: Ordering Constraints: start ClusterIP then start WebSite Colocation Constraints: WebSite with ClusterIP ----- endif::[] ifdef::crmsh[] We need to give it a name (choose something descriptive like apache-after-ip), indicate that its mandatory (so that any recovery for ClusterIP will also trigger recovery of WebSite) and list the two resources in the order we need them to start. [source,C] ----- # crm configure order apache-after-ip mandatory: ClusterIP WebSite # crm configure show node $id="1702537408" pcmk-1 node $id="1719314624" pcmk-2 primitive ClusterIP ocf:heartbeat:IPaddr2 \ params ip="192.168.122.120" cidr_netmask="32" \ op monitor interval="30s" primitive WebSite ocf:heartbeat:apache \ params configfile="/etc/httpd/conf/httpd.conf" \ op monitor interval="1min" colocation website-with-ip inf: WebSite ClusterIP order apache-after-ip inf: ClusterIP WebSite property $id="cib-bootstrap-options" \ dc-version="1.1.7-2.fc17-ee0730e13d124c3d58f00016c3376a1de5323cff" \ cluster-infrastructure="corosync" \ stonith-enabled="false" \ no-quorum-policy="ignore" \ last-lrm-refresh="1333446866" rsc_defaults $id="rsc-options" \ resource-stickiness="100" op_defaults $id="op-options" \ timeout="240s" ----- endif::[] == Specifying a Preferred Location == Pacemaker does not rely on any sort of hardware symmetry between nodes, so it may well be that one machine is more powerful than the other. In such cases it makes sense to host the resources there if it is available. To do this we create a location constraint. ifdef::pcs[] In the location constraint below, we are saying the WebSite resource prefers the node pcmk-1 with a score of 50. The score here indicates how badly we'd like the resource to run somewhere. [source,C] ----- # pcs constraint location WebSite prefers pcmk-1=50 # pcs constraint Location Constraints: Resource: WebSite Enabled on: pcmk-1 (score:50) Ordering Constraints: start ClusterIP then start WebSite Colocation Constraints: WebSite with ClusterIP # pcs status Last updated: Fri Sep 14 11:06:37 2012 Last change: Fri Sep 14 11:06:26 2012 via cibadmin on pcmk-1 Stack: corosync Current DC: pcmk-2 (2) - partition with quorum Version: 1.1.8-1.el7-60a19ed12fdb4d5c6a6b6767f52e5391e447fec0 2 Nodes configured, unknown expected votes 2 Resources configured. Online: [ pcmk-1 pcmk-2 ] Full list of resources: ClusterIP (ocf::heartbeat:IPaddr2): Started pcmk-2 WebSite (ocf::heartbeat:apache): Started pcmk-2 ----- endif::[] ifdef::crmsh[] Again we give it a descriptive name (prefer-pcmk-1), specify the resource we want to run there (WebSite), how badly we'd like it to run there (we'll use 50 for now, but in a two-node situation almost any value above 0 will do) and the host's name. [source,C] ----- # crm configure location prefer-pcmk-1 WebSite 50: pcmk-1 WARNING: prefer-pcmk-1: referenced node pcmk-1 does not exist ----- This warning should be ignored. [source,C] ----- # crm configure show node $id="1702537408" pcmk-1 node $id="1719314624" pcmk-2 primitive ClusterIP ocf:heartbeat:IPaddr2 \ params ip="192.168.122.120" cidr_netmask="32" \ op monitor interval="30s" primitive WebSite ocf:heartbeat:apache \ params configfile="/etc/httpd/conf/httpd.conf" \ op monitor interval="1min" location prefer-pcmk-1 WebSite 50: pcmk-1 colocation website-with-ip inf: WebSite ClusterIP order apache-after-ip inf: ClusterIP WebSite property $id="cib-bootstrap-options" \ dc-version="1.1.7-2.fc17-ee0730e13d124c3d58f00016c3376a1de5323cff" \ cluster-infrastructure="corosync" \ stonith-enabled="false" \ no-quorum-policy="ignore" \ last-lrm-refresh="1333446866" rsc_defaults $id="rsc-options" \ resource-stickiness="100" op_defaults $id="op-options" \ timeout="240s" # crm_mon -1 ============ Last updated: Tue Apr 3 12:02:14 2012 Last change: Tue Apr 3 11:59:42 2012 via cibadmin on pcmk-1 Stack: corosync Current DC: pcmk-2 (1719314624) - partition with quorum Version: 1.1.7-2.fc17-ee0730e13d124c3d58f00016c3376a1de5323cff 2 Nodes configured, unknown expected votes 2 Resources configured. ============ Online: [ pcmk-1 pcmk-2 ] ClusterIP (ocf:heartbeat:IPaddr2): Started pcmk-2 WebSite (ocf:heartbeat:apache): Started pcmk-2 ----- endif::[] Wait a minute, the resources are still on pcmk-2! Even though we now prefer pcmk-1 over pcmk-2, that preference is (intentionally) less than the resource stickiness (how much we preferred not to have unnecessary downtime). To see the current placement scores, you can use a tool called crm_simulate [source,C] ---- # crm_simulate -sL Current cluster status: Online: [ pcmk-1 pcmk-2 ] ClusterIP (ocf:heartbeat:IPaddr2): Started pcmk-2 WebSite (ocf:heartbeat:apache): Started pcmk-2 Allocation scores: native_color: ClusterIP allocation score on pcmk-1: 50 native_color: ClusterIP allocation score on pcmk-2: 200 native_color: WebSite allocation score on pcmk-1: -INFINITY native_color: WebSite allocation score on pcmk-2: 100 Transition Summary: ---- == Manually Moving Resources Around the Cluster == ifdef::pcs[] There are always times when an administrator needs to override the cluster and force resources to move to a specific location. By updating our previous location constraint with a score of INFINITY, WebSite will be forced to move to pcmk-1. [source,C] ----- # pcs constraint location WebSite prefers pcmk-1=INFINITY # pcs constraint all Location Constraints: Resource: WebSite Enabled on: pcmk-1 (score:INFINITY) (id:location-WebSite-pcmk-1-INFINITY) Ordering Constraints: start ClusterIP then start WebSite (Mandatory) (id:order-ClusterIP-WebSite-mandatory) Colocation Constraints: WebSite with ClusterIP (INFINITY) (id:colocation-WebSite-ClusterIP-INFINITY) # pcs status Last updated: Fri Sep 14 11:16:26 2012 Last change: Fri Sep 14 11:16:18 2012 via cibadmin on pcmk-1 Stack: corosync Current DC: pcmk-2 (2) - partition with quorum Version: 1.1.8-1.el7-60a19ed12fdb4d5c6a6b6767f52e5391e447fec0 2 Nodes configured, unknown expected votes 2 Resources configured. Online: [ pcmk-1 pcmk-2 ] Full list of resources: ClusterIP (ocf::heartbeat:IPaddr2): Started pcmk-1 WebSite (ocf::heartbeat:apache): Started pcmk-1 ----- endif::[] ifdef::crmsh[] There are always times when an administrator needs to override the cluster and force resources to move to a specific location. Underneath we use location constraints like the one we created above, happily you don't need to care. Just provide the name of the resource and the intended location, we'll do the rest. [source,C] ----- # crm resource move WebSite pcmk-1 # crm_mon -1 ============ Last updated: Tue Apr 3 12:03:41 2012 Last change: Tue Apr 3 12:03:37 2012 via crm_resource on pcmk-1 Stack: corosync Current DC: pcmk-2 (1719314624) - partition with quorum Version: 1.1.7-2.fc17-ee0730e13d124c3d58f00016c3376a1de5323cff 2 Nodes configured, unknown expected votes 2 Resources configured. ============ Online: [ pcmk-1 pcmk-2 ] ClusterIP (ocf:heartbeat:IPaddr2): Started pcmk-1 WebSite (ocf:heartbeat:apache): Started pcmk-1 ----- Notice how the colocation rule we created has ensured that ClusterIP was also moved to pcmk-1. For the curious, we can see the effect of this command by examining the configuration [source,C] ----- # crm configure show node $id="1702537408" pcmk-1 node $id="1719314624" pcmk-2 primitive ClusterIP ocf:heartbeat:IPaddr2 \ params ip="192.168.122.120" cidr_netmask="32" \ op monitor interval="30s" primitive WebSite ocf:heartbeat:apache \ params configfile="/etc/httpd/conf/httpd.conf" \ op monitor interval="1min" location cli-prefer-WebSite WebSite \ rule $id="cli-prefer-rule-WebSite" inf: #uname eq pcmk-1 location prefer-pcmk-1 WebSite 50: pcmk-1 colocation website-with-ip inf: WebSite ClusterIP order apache-after-ip inf: ClusterIP WebSite property $id="cib-bootstrap-options" \ dc-version="1.1.7-2.fc17-ee0730e13d124c3d58f00016c3376a1de5323cff" \ cluster-infrastructure="corosync" \ stonith-enabled="false" \ no-quorum-policy="ignore" \ last-lrm-refresh="1333446866" rsc_defaults $id="rsc-options" \ resource-stickiness="100" op_defaults $id="op-options" \ timeout="240s" ----- The automated constraint used to move the resources to +pcmk-1+ is the line beginning with +location cli-prefer-WebSite+. endif::[] === Giving Control Back to the Cluster === Once we've finished whatever activity that required us to move the resources to pcmk-1, in our case nothing, we can then allow the cluster to resume normal operation with the unmove command. Since we previously configured a default stickiness, the resources will remain on pcmk-1. ifdef::pcs[] [source,C] ----- # pcs constraint all Location Constraints: Resource: WebSite Enabled on: pcmk-1 (score:INFINITY) (id:location-WebSite-pcmk-1-INFINITY) Ordering Constraints: start ClusterIP then start WebSite (Mandatory) (id:order-ClusterIP-WebSite-mandatory) Colocation Constraints: WebSite with ClusterIP (INFINITY) (id:colocation-WebSite-ClusterIP-INFINITY) # pcs constraint rm location-WebSite-pcmk-1-INFINITY # pcs constraint Location Constraints: Ordering Constraints: start ClusterIP then start WebSite Colocation Constraints: WebSite with ClusterIP ----- endif::[] ifdef::crmsh[] [source,C] ----- # crm resource unmove WebSite # crm configure show node $id="1702537408" pcmk-1 node $id="1719314624" pcmk-2 primitive ClusterIP ocf:heartbeat:IPaddr2 \ params ip="192.168.122.120" cidr_netmask="32" \ op monitor interval="30s" primitive WebSite ocf:heartbeat:apache \ params configfile="/etc/httpd/conf/httpd.conf" \ op monitor interval="1min" location prefer-pcmk-1 WebSite 50: pcmk-1 colocation website-with-ip inf: WebSite ClusterIP order apache-after-ip inf: ClusterIP WebSite property $id="cib-bootstrap-options" \ dc-version="1.1.7-2.fc17-ee0730e13d124c3d58f00016c3376a1de5323cff" \ cluster-infrastructure="corosync" \ stonith-enabled="false" \ no-quorum-policy="ignore" \ last-lrm-refresh="1333446866" rsc_defaults $id="rsc-options" \ resource-stickiness="100" op_defaults $id="op-options" \ timeout="240s" ----- endif::[] Note that the constraint is now gone. If we check the cluster status, we can also see that as expected the resources are still active on pcmk-1. ifdef::pcs[] [source,C] ----- # pcs status Last updated: Fri Sep 14 11:57:12 2012 Last change: Fri Sep 14 11:57:03 2012 via cibadmin on pcmk-1 Stack: corosync Current DC: pcmk-2 (2) - partition with quorum Version: 1.1.8-1.el7-60a19ed12fdb4d5c6a6b6767f52e5391e447fec0 2 Nodes configured, unknown expected votes 2 Resources configured. Online: [ pcmk-1 pcmk-2 ] Full list of resources: ClusterIP (ocf::heartbeat:IPaddr2): Started pcmk-1 WebSite (ocf::heartbeat:apache): Started pcmk-1 ----- endif::[] ifdef::crmsh[] [source,C] ----- # crm_mon ============ Last updated: Tue Apr 3 12:05:08 2012 Last change: Tue Apr 3 12:03:37 2012 via crm_resource on pcmk-1 Stack: corosync Current DC: pcmk-2 (1719314624) - partition with quorum Version: 1.1.7-2.fc17-ee0730e13d124c3d58f00016c3376a1de5323cff 2 Nodes configured, unknown expected votes 2 Resources configured. ============ Online: [ pcmk-1 pcmk-2 ] ClusterIP (ocf:heartbeat:IPaddr2): Started pcmk-1 WebSite (ocf:heartbeat:apache): Started pcmk-1 ----- endif::[] pacemaker-master/doc/Clusters_from_Scratch/en-US/Ch-Installation.txt000066400000000000000000001540361217637305600260460ustar00rootroot00000000000000= Installation = == OS Installation == Detailed instructions for installing Fedora are available at http://docs.fedoraproject.org/en-US/Fedora/17/html/Installation_Guide/ in a number of languages. The abbreviated version is as follows... Point your browser to http://fedoraproject.org/en/get-fedora-all, locate the +Install Media+ section and download the install DVD that matches your hardware. Burn the disk image to a DVD footnote:[http://docs.fedoraproject.org/en-US/Fedora/16/html/Burning_ISO_images_to_disc/index.html] and boot from it, or use the image to boot a virtual machine. After clicking through the welcome screen, select your language, keyboard layout footnote:[http://docs.fedoraproject.org/en-US/Fedora/16/html/Installation_Guide/sn-keyboard-x86.html] and storage type footnote:[http://docs.fedoraproject.org/en-US/Fedora/16/html/Installation_Guide/Storage_Devices-x86.html] Assign your machine a host name. footnote:[http://docs.fedoraproject.org/en-US/Fedora/16/html/Installation_Guide/sn-Netconfig-x86.html] I happen to control the clusterlabs.org domain name, so I will use that here. [IMPORTANT] =========== Do not accept the default network settings. Cluster machines should never obtain an IP address via DHCP. When you are presented with the +Configure Network+ advanced option, select that option before continuing with the installation process to specify a fixed IPv4 address for +System eth0+. Be sure to also enter the +Routes+ section and add an entry for your default gateway. image::images/Network.png["Custom network settings",align="center"] If you miss this step, this can easily be configured after installation. You will have to navigate to +system settings+ and select +network+. From there you can select what device to configure. =========== You will then be prompted to indicate the machine's physical location footnote:[http://docs.fedoraproject.org/en-US/Fedora/16/html/Installation_Guide/s1-timezone-x86.html] and to supply a root password. footnote:[http://docs.fedoraproject.org/en-US/Fedora/16/html/Installation_Guide/sn-account_configuration-x86.html] Now select where you want Fedora installed. footnote:[http://docs.fedoraproject.org/en-US/Fedora/16/html/Installation_Guide/s1-diskpartsetup-x86.html] As I don’t care about any existing data, I will accept the default and allow Fedora to use the complete drive. [IMPORTANT] =========== By default Fedora uses LVM for partitioning which allows us to dynamically change the amount of space allocated to a given partition. However, by default it also allocates all free space to the +/+ (aka. +root+) partition which cannot be dynamically _reduced_ in size (dynamic increases are fine by-the-way). So if you plan on following the DRBD or GFS2 portions of this guide, you should reserve at least 1Gb of space on each machine from which to create a shared volume. To do so select the +Review and modify partitioning layout+ checkbox before clicking +Next+. You will then be given an opportunity to reduce the size of the +root+ partition. =========== Next choose which software should be installed. footnote:[http://docs.fedoraproject.org/en-US/Fedora/16/html/Installation_Guide/s1-pkgselection-x86.html] Change the selection to Minimal so that we see everything that gets installed. Don't enable updates yet, we'll do that (and install any extra software we need) later. After you click next, Fedora will begin installing. Go grab something to drink, this may take a while. Once the node reboots, you'll see a (possibly mangled) login prompt on the console. Login using +root+ and the password you created earlier. image::images/Console.png["Initial Console",align="center"] [NOTE] ====== From here on in we're going to be working exclusively from the terminal. ====== == Post Installation Tasks == === Networking === Bring up the network and ensure it starts at boot [source,C] ----- # service network start # chkconfig network on ----- Check the machine has the static IP address you configured earlier [source,C] ----- # ip addr 1: lo: mtu 16436 qdisc noqueue state UNKNOWN link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo inet6 ::1/128 scope host valid_lft forever preferred_lft forever 2: eth0: mtu 1500 qdisc pfifo_fast state UP qlen 1000 link/ether 52:54:00:d7:d6:08 brd ff:ff:ff:ff:ff:ff inet 192.168.122.101/24 brd 192.168.122.255 scope global eth0 inet6 fe80::5054:ff:fed7:d608/64 scope link valid_lft forever preferred_lft forever ----- Now check the default route setting: [source,C] ----- [root@pcmk-1 ~]# ip route default via 192.168.122.1 dev eth0 192.168.122.0/24 dev eth0 proto kernel scope link src 192.168.122.101 ----- If there is no line beginning with +default via+, then you may need to add a line such as [source,Bash] GATEWAY=192.168.122.1 to '/etc/sysconfig/network' and restart the network. Now check for connectivity to the outside world. Start small by testing if we can read the gateway we configured. [source,C] ----- # ping -c 1 192.168.122.1 PING 192.168.122.1 (192.168.122.1) 56(84) bytes of data. 64 bytes from 192.168.122.1: icmp_req=1 ttl=64 time=0.249 ms --- 192.168.122.1 ping statistics --- 1 packets transmitted, 1 received, 0% packet loss, time 0ms rtt min/avg/max/mdev = 0.249/0.249/0.249/0.000 ms ----- Now try something external, choose a location you know will be available. [source,C] ----- # ping -c 1 www.google.com PING www.l.google.com (173.194.72.106) 56(84) bytes of data. 64 bytes from tf-in-f106.1e100.net (173.194.72.106): icmp_req=1 ttl=41 time=167 ms --- www.l.google.com ping statistics --- 1 packets transmitted, 1 received, 0% packet loss, time 0ms rtt min/avg/max/mdev = 167.618/167.618/167.618/0.000 ms ----- === Leaving the Console === The console isn't a very friendly place to work from, we will now switch to accessing the machine remotely via SSH where we can use copy&paste etc. First we check we can see the newly installed at all: [source,C] ----- beekhof@f16 ~ # ping -c 1 192.168.122.101 PING 192.168.122.101 (192.168.122.101) 56(84) bytes of data. 64 bytes from 192.168.122.101: icmp_req=1 ttl=64 time=1.01 ms --- 192.168.122.101 ping statistics --- 1 packets transmitted, 1 received, 0% packet loss, time 0ms rtt min/avg/max/mdev = 1.012/1.012/1.012/0.000 ms ----- Next we login via SSH [source,C] ----- beekhof@f16 ~ # ssh -l root 192.168.122.11 root@192.168.122.11's password: Last login: Fri Mar 30 19:41:19 2012 from 192.168.122.1 [root@pcmk-1 ~]# ----- === Security Shortcuts === To simplify this guide and focus on the aspects directly connected to clustering, we will now disable the machine's firewall and SELinux installation. [WARNING] =========== Both of these actions create significant security issues and should not be performed on machines that will be exposed to the outside world. =========== [IMPORTANT] =========== TODO: Create an Appendix that deals with (at least) re-enabling the firewall. =========== [source,C] ---- # setenforce 0 # sed -i.bak "s/SELINUX=enforcing/SELINUX=permissive/g" /etc/selinux/config # systemctl disable iptables.service # rm '/etc/systemd/system/basic.target.wants/iptables.service' # systemctl stop iptables.service ---- === Short Node Names === During installation, we filled in the machine's fully qualified domain name (FQDN) which can be rather long when it appears in cluster logs and status output. See for yourself how the machine identifies itself: (((Nodes, short name))) [source,C] ---- # uname -n pcmk-1.clusterlabs.org # dnsdomainname clusterlabs.org ---- (((Nodes, Domain name (Query)))) The output from the second command is fine, but we really don't need the domain name included in the basic host details. To address this, we need to update /etc/sysconfig/network. This is what it should look like before we start. [source,C] ---- # cat /etc/sysconfig/network NETWORKING=yes HOSTNAME=pcmk-1.clusterlabs.org GATEWAY=192.168.122.1 ---- All we need to do now is strip off the domain name portion, which is stored elsewhere anyway. [source,C] ---- # sed -i.sed 's/\.[a-z].*//g' /etc/sysconfig/network ---- Now confirm the change was successful. The revised file contents should look something like this. [source,C] ---- # cat /etc/sysconfig/network NETWORKING=yes HOSTNAME=pcmk-1 GATEWAY=192.168.122.1 ---- However we're not finished. The machine wont normally see the shortened host name until about it reboots, but we can force it to update. [source,C] ---- # source /etc/sysconfig/network # hostname $HOSTNAME ---- (((Nodes, Domain name (Remove from host name)))) Now check the machine is using the correct names [source,C] ---- # uname -n pcmk-1 # dnsdomainname clusterlabs.org ---- === NTP === It is highly recommended to enable NTP on your cluster nodes. Doing so ensures all nodes agree on the current time and makes reading log files significantly easier. footnote:[http://docs.fedoraproject.org/en-US/Fedora/17/html-single/System_Administrators_Guide/index.html#ch-Configuring_the_Date_and_Time] == Before You Continue == Repeat the Installation steps so far, so that you have two Fedora nodes ready to have the cluster software installed. For the purposes of this document, the additional node is called pcmk-2 with address 192.168.122.102. === Finalize Networking === Confirm that you can communicate between the two new nodes: [source,C] ---- # ping -c 3 192.168.122.102 PING 192.168.122.102 (192.168.122.102) 56(84) bytes of data. 64 bytes from 192.168.122.102: icmp_seq=1 ttl=64 time=0.343 ms 64 bytes from 192.168.122.102: icmp_seq=2 ttl=64 time=0.402 ms 64 bytes from 192.168.122.102: icmp_seq=3 ttl=64 time=0.558 ms --- 192.168.122.102 ping statistics --- 3 packets transmitted, 3 received, 0% packet loss, time 2000ms rtt min/avg/max/mdev = 0.343/0.434/0.558/0.092 ms ---- Now we need to make sure we can communicate with the machines by their name. If you have a DNS server, add additional entries for the two machines. Otherwise, you'll need to add the machines to '/etc/hosts' . Below are the entries for my cluster nodes: [source,C] ---- # grep pcmk /etc/hosts 192.168.122.101 pcmk-1.clusterlabs.org pcmk-1 192.168.122.102 pcmk-2.clusterlabs.org pcmk-2 ---- We can now verify the setup by again using ping: [source,C] ---- # ping -c 3 pcmk-2 PING pcmk-2.clusterlabs.org (192.168.122.101) 56(84) bytes of data. 64 bytes from pcmk-1.clusterlabs.org (192.168.122.101): icmp_seq=1 ttl=64 time=0.164 ms 64 bytes from pcmk-1.clusterlabs.org (192.168.122.101): icmp_seq=2 ttl=64 time=0.475 ms 64 bytes from pcmk-1.clusterlabs.org (192.168.122.101): icmp_seq=3 ttl=64 time=0.186 ms --- pcmk-2.clusterlabs.org ping statistics --- 3 packets transmitted, 3 received, 0% packet loss, time 2001ms rtt min/avg/max/mdev = 0.164/0.275/0.475/0.141 ms ---- === Configure SSH === SSH is a convenient and secure way to copy files and perform commands remotely. For the purposes of this guide, we will create a key without a password (using the -N option) so that we can perform remote actions without being prompted. (((SSH))) [WARNING] ========= Unprotected SSH keys, those without a password, are not recommended for servers exposed to the outside world. We use them here only to simplify the demo. ========= Create a new key and allow anyone with that key to log in: .Creating and Activating a new SSH Key [source,C] ---- # ssh-keygen -t dsa -f ~/.ssh/id_dsa -N "" Generating public/private dsa key pair. Your identification has been saved in /root/.ssh/id_dsa. Your public key has been saved in /root/.ssh/id_dsa.pub. The key fingerprint is: 91:09:5c:82:5a:6a:50:08:4e:b2:0c:62:de:cc:74:44 root@pcmk-1.clusterlabs.org The key's randomart image is: +--[ DSA 1024]----+ |==.ooEo.. | |X O + .o o | | * A + | | + . | | . S | | | | | | | | | +-----------------+ # cp .ssh/id_dsa.pub .ssh/authorized_keys ---- (((Creating and Activating a new SSH Key))) Install the key on the other nodes and test that you can now run commands remotely, without being prompted .Installing the SSH Key on Another Host [source,C] ---- # scp -r .ssh pcmk-2: The authenticity of host 'pcmk-2 (192.168.122.102)' can't be established. RSA key fingerprint is b1:2b:55:93:f1:d9:52:2b:0f:f2:8a:4e:ae:c6:7c:9a. Are you sure you want to continue connecting (yes/no)? yes Warning: Permanently added 'pcmk-2,192.168.122.102' (RSA) to the list of known hosts.root@pcmk-2's password: id_dsa.pub 100% 616 0.6KB/s 00:00 id_dsa 100% 672 0.7KB/s 00:00 known_hosts 100% 400 0.4KB/s 00:00 authorized_keys 100% 616 0.6KB/s 00:00 # ssh pcmk-2 -- uname -n pcmk-2 # ---- == Cluster Software Installation == === Install the Cluster Software === Since version 12, Fedora comes with recent versions of everything you need, so simply fire up a shell on all your nodes and run: [source,C] ---- [ALL] # yum install -y pacemaker corosync ---- ..... fedora/metalink | 38 kB 00:00 fedora | 4.2 kB 00:00 fedora/primary_db | 14 MB 00:21 updates/metalink | 2.7 kB 00:00 updates | 2.6 kB 00:00 updates/primary_db | 1.2 kB 00:00 updates-testing/metalink | 28 kB 00:00 updates-testing | 4.5 kB 00:00 updates-testing/primary_db | 4.5 MB 00:12 Setting up Install Process Resolving Dependencies --> Running transaction check ---> Package corosync.x86_64 0:1.99.9-1.fc17 will be installed --> Processing Dependency: corosynclib = 1.99.9-1.fc17 for package: corosync-1.99.9-1.fc17.x86_64 --> Processing Dependency: libxslt for package: corosync-1.99.9-1.fc17.x86_64 --> Processing Dependency: libvotequorum.so.5(COROSYNC_VOTEQUORUM_1.0)(64bit) for package: corosync-1.99.9-1.fc17.x86_64 --> Processing Dependency: libquorum.so.5(COROSYNC_QUORUM_1.0)(64bit) for package: corosync-1.99.9-1.fc17.x86_64 --> Processing Dependency: libcpg.so.4(COROSYNC_CPG_1.0)(64bit) for package: corosync-1.99.9-1.fc17.x86_64 --> Processing Dependency: libcmap.so.4(COROSYNC_CMAP_1.0)(64bit) for package: corosync-1.99.9-1.fc17.x86_64 --> Processing Dependency: libcfg.so.6(COROSYNC_CFG_0.82)(64bit) for package: corosync-1.99.9-1.fc17.x86_64 --> Processing Dependency: libvotequorum.so.5()(64bit) for package: corosync-1.99.9-1.fc17.x86_64 --> Processing Dependency: libtotem_pg.so.5()(64bit) for package: corosync-1.99.9-1.fc17.x86_64 --> Processing Dependency: libquorum.so.5()(64bit) for package: corosync-1.99.9-1.fc17.x86_64 --> Processing Dependency: libqb.so.0()(64bit) for package: corosync-1.99.9-1.fc17.x86_64 --> Processing Dependency: libnetsnmp.so.30()(64bit) for package: corosync-1.99.9-1.fc17.x86_64 --> Processing Dependency: libcpg.so.4()(64bit) for package: corosync-1.99.9-1.fc17.x86_64 --> Processing Dependency: libcorosync_common.so.4()(64bit) for package: corosync-1.99.9-1.fc17.x86_64 --> Processing Dependency: libcmap.so.4()(64bit) for package: corosync-1.99.9-1.fc17.x86_64 --> Processing Dependency: libcfg.so.6()(64bit) for package: corosync-1.99.9-1.fc17.x86_64 ---> Package pacemaker.x86_64 0:1.1.7-2.fc17 will be installed --> Processing Dependency: pacemaker-libs = 1.1.7-2.fc17 for package: pacemaker-1.1.7-2.fc17.x86_64 --> Processing Dependency: pacemaker-cluster-libs = 1.1.7-2.fc17 for package: pacemaker-1.1.7-2.fc17.x86_64 --> Processing Dependency: pacemaker-cli = 1.1.7-2.fc17 for package: pacemaker-1.1.7-2.fc17.x86_64 --> Processing Dependency: resource-agents for package: pacemaker-1.1.7-2.fc17.x86_64 --> Processing Dependency: perl(Getopt::Long) for package: pacemaker-1.1.7-2.fc17.x86_64 --> Processing Dependency: libgnutls.so.26(GNUTLS_1_4)(64bit) for package: pacemaker-1.1.7-2.fc17.x86_64 --> Processing Dependency: cluster-glue for package: pacemaker-1.1.7-2.fc17.x86_64 --> Processing Dependency: /usr/bin/perl for package: pacemaker-1.1.7-2.fc17.x86_64 --> Processing Dependency: libtransitioner.so.1()(64bit) for package: pacemaker-1.1.7-2.fc17.x86_64 --> Processing Dependency: libstonithd.so.1()(64bit) for package: pacemaker-1.1.7-2.fc17.x86_64 --> Processing Dependency: libstonith.so.1()(64bit) for package: pacemaker-1.1.7-2.fc17.x86_64 --> Processing Dependency: libplumb.so.2()(64bit) for package: pacemaker-1.1.7-2.fc17.x86_64 --> Processing Dependency: libpils.so.2()(64bit) for package: pacemaker-1.1.7-2.fc17.x86_64 --> Processing Dependency: libpengine.so.3()(64bit) for package: pacemaker-1.1.7-2.fc17.x86_64 --> Processing Dependency: libpe_status.so.3()(64bit) for package: pacemaker-1.1.7-2.fc17.x86_64 --> Processing Dependency: libpe_rules.so.2()(64bit) for package: pacemaker-1.1.7-2.fc17.x86_64 --> Processing Dependency: libltdl.so.7()(64bit) for package: pacemaker-1.1.7-2.fc17.x86_64 --> Processing Dependency: liblrm.so.2()(64bit) for package: pacemaker-1.1.7-2.fc17.x86_64 --> Processing Dependency: libgnutls.so.26()(64bit) for package: pacemaker-1.1.7-2.fc17.x86_64 --> Processing Dependency: libcrmcommon.so.2()(64bit) for package: pacemaker-1.1.7-2.fc17.x86_64 --> Processing Dependency: libcrmcluster.so.1()(64bit) for package: pacemaker-1.1.7-2.fc17.x86_64 --> Processing Dependency: libcib.so.1()(64bit) for package: pacemaker-1.1.7-2.fc17.x86_64 --> Running transaction check ---> Package cluster-glue.x86_64 0:1.0.6-9.fc17.1 will be installed --> Processing Dependency: perl-TimeDate for package: cluster-glue-1.0.6-9.fc17.1.x86_64 --> Processing Dependency: libOpenIPMIutils.so.0()(64bit) for package: cluster-glue-1.0.6-9.fc17.1.x86_64 --> Processing Dependency: libOpenIPMIposix.so.0()(64bit) for package: cluster-glue-1.0.6-9.fc17.1.x86_64 --> Processing Dependency: libOpenIPMI.so.0()(64bit) for package: cluster-glue-1.0.6-9.fc17.1.x86_64 ---> Package cluster-glue-libs.x86_64 0:1.0.6-9.fc17.1 will be installed ---> Package corosynclib.x86_64 0:1.99.9-1.fc17 will be installed --> Processing Dependency: librdmacm.so.1(RDMACM_1.0)(64bit) for package: corosynclib-1.99.9-1.fc17.x86_64 --> Processing Dependency: libibverbs.so.1(IBVERBS_1.1)(64bit) for package: corosynclib-1.99.9-1.fc17.x86_64 --> Processing Dependency: libibverbs.so.1(IBVERBS_1.0)(64bit) for package: corosynclib-1.99.9-1.fc17.x86_64 --> Processing Dependency: librdmacm.so.1()(64bit) for package: corosynclib-1.99.9-1.fc17.x86_64 --> Processing Dependency: libibverbs.so.1()(64bit) for package: corosynclib-1.99.9-1.fc17.x86_64 ---> Package gnutls.x86_64 0:2.12.17-1.fc17 will be installed --> Processing Dependency: libtasn1.so.3(LIBTASN1_0_3)(64bit) for package: gnutls-2.12.17-1.fc17.x86_64 --> Processing Dependency: libtasn1.so.3()(64bit) for package: gnutls-2.12.17-1.fc17.x86_64 --> Processing Dependency: libp11-kit.so.0()(64bit) for package: gnutls-2.12.17-1.fc17.x86_64 ---> Package libqb.x86_64 0:0.11.1-1.fc17 will be installed ---> Package libtool-ltdl.x86_64 0:2.4.2-3.fc17 will be installed ---> Package libxslt.x86_64 0:1.1.26-9.fc17 will be installed ---> Package net-snmp-libs.x86_64 1:5.7.1-4.fc17 will be installed ---> Package pacemaker-cli.x86_64 0:1.1.7-2.fc17 will be installed ---> Package pacemaker-cluster-libs.x86_64 0:1.1.7-2.fc17 will be installed ---> Package pacemaker-libs.x86_64 0:1.1.7-2.fc17 will be installed ---> Package perl.x86_64 4:5.14.2-211.fc17 will be installed --> Processing Dependency: perl-libs = 4:5.14.2-211.fc17 for package: 4:perl-5.14.2-211.fc17.x86_64 --> Processing Dependency: perl(threads::shared) >= 1.21 for package: 4:perl-5.14.2-211.fc17.x86_64 --> Processing Dependency: perl(Socket) >= 1.3 for package: 4:perl-5.14.2-211.fc17.x86_64 --> Processing Dependency: perl(Scalar::Util) >= 1.10 for package: 4:perl-5.14.2-211.fc17.x86_64 --> Processing Dependency: perl(File::Spec) >= 0.8 for package: 4:perl-5.14.2-211.fc17.x86_64 --> Processing Dependency: perl-macros for package: 4:perl-5.14.2-211.fc17.x86_64 --> Processing Dependency: perl-libs for package: 4:perl-5.14.2-211.fc17.x86_64 --> Processing Dependency: perl(threads::shared) for package: 4:perl-5.14.2-211.fc17.x86_64 --> Processing Dependency: perl(threads) for package: 4:perl-5.14.2-211.fc17.x86_64 --> Processing Dependency: perl(Socket) for package: 4:perl-5.14.2-211.fc17.x86_64 --> Processing Dependency: perl(Scalar::Util) for package: 4:perl-5.14.2-211.fc17.x86_64 --> Processing Dependency: perl(Pod::Simple) for package: 4:perl-5.14.2-211.fc17.x86_64 --> Processing Dependency: perl(Module::Pluggable) for package: 4:perl-5.14.2-211.fc17.x86_64 --> Processing Dependency: perl(List::Util) for package: 4:perl-5.14.2-211.fc17.x86_64 --> Processing Dependency: perl(File::Spec::Unix) for package: 4:perl-5.14.2-211.fc17.x86_64 --> Processing Dependency: perl(File::Spec::Functions) for package: 4:perl-5.14.2-211.fc17.x86_64 --> Processing Dependency: perl(File::Spec) for package: 4:perl-5.14.2-211.fc17.x86_64 --> Processing Dependency: perl(Cwd) for package: 4:perl-5.14.2-211.fc17.x86_64 --> Processing Dependency: perl(Carp) for package: 4:perl-5.14.2-211.fc17.x86_64 --> Processing Dependency: libperl.so()(64bit) for package: 4:perl-5.14.2-211.fc17.x86_64 ---> Package resource-agents.x86_64 0:3.9.2-2.fc17.1 will be installed --> Processing Dependency: /usr/sbin/rpc.nfsd for package: resource-agents-3.9.2-2.fc17.1.x86_64 --> Processing Dependency: /usr/sbin/rpc.mountd for package: resource-agents-3.9.2-2.fc17.1.x86_64 --> Processing Dependency: /usr/sbin/ethtool for package: resource-agents-3.9.2-2.fc17.1.x86_64 --> Processing Dependency: /sbin/rpc.statd for package: resource-agents-3.9.2-2.fc17.1.x86_64 --> Processing Dependency: /sbin/quotaon for package: resource-agents-3.9.2-2.fc17.1.x86_64 --> Processing Dependency: /sbin/quotacheck for package: resource-agents-3.9.2-2.fc17.1.x86_64 --> Processing Dependency: /sbin/mount.nfs4 for package: resource-agents-3.9.2-2.fc17.1.x86_64 --> Processing Dependency: /sbin/mount.nfs for package: resource-agents-3.9.2-2.fc17.1.x86_64 --> Processing Dependency: /sbin/mount.cifs for package: resource-agents-3.9.2-2.fc17.1.x86_64 --> Processing Dependency: /sbin/fsck.xfs for package: resource-agents-3.9.2-2.fc17.1.x86_64 --> Processing Dependency: libnet.so.1()(64bit) for package: resource-agents-3.9.2-2.fc17.1.x86_64 --> Running transaction check ---> Package OpenIPMI-libs.x86_64 0:2.0.18-13.fc17 will be installed ---> Package cifs-utils.x86_64 0:5.3-2.fc17 will be installed --> Processing Dependency: libtalloc.so.2(TALLOC_2.0.2)(64bit) for package: cifs-utils-5.3-2.fc17.x86_64 --> Processing Dependency: keyutils for package: cifs-utils-5.3-2.fc17.x86_64 --> Processing Dependency: libwbclient.so.0()(64bit) for package: cifs-utils-5.3-2.fc17.x86_64 --> Processing Dependency: libtalloc.so.2()(64bit) for package: cifs-utils-5.3-2.fc17.x86_64 ---> Package ethtool.x86_64 2:3.2-2.fc17 will be installed ---> Package libibverbs.x86_64 0:1.1.6-2.fc17 will be installed ---> Package libnet.x86_64 0:1.1.5-3.fc17 will be installed ---> Package librdmacm.x86_64 0:1.0.15-1.fc17 will be installed ---> Package libtasn1.x86_64 0:2.12-1.fc17 will be installed ---> Package nfs-utils.x86_64 1:1.2.5-12.fc17 will be installed --> Processing Dependency: rpcbind for package: 1:nfs-utils-1.2.5-12.fc17.x86_64 --> Processing Dependency: libtirpc for package: 1:nfs-utils-1.2.5-12.fc17.x86_64 --> Processing Dependency: libnfsidmap for package: 1:nfs-utils-1.2.5-12.fc17.x86_64 --> Processing Dependency: libgssglue.so.1(libgssapi_CITI_2)(64bit) for package: 1:nfs-utils-1.2.5-12.fc17.x86_64 --> Processing Dependency: libgssglue for package: 1:nfs-utils-1.2.5-12.fc17.x86_64 --> Processing Dependency: libevent for package: 1:nfs-utils-1.2.5-12.fc17.x86_64 --> Processing Dependency: libtirpc.so.1()(64bit) for package: 1:nfs-utils-1.2.5-12.fc17.x86_64 --> Processing Dependency: libnfsidmap.so.0()(64bit) for package: 1:nfs-utils-1.2.5-12.fc17.x86_64 --> Processing Dependency: libgssglue.so.1()(64bit) for package: 1:nfs-utils-1.2.5-12.fc17.x86_64 --> Processing Dependency: libevent-2.0.so.5()(64bit) for package: 1:nfs-utils-1.2.5-12.fc17.x86_64 ---> Package p11-kit.x86_64 0:0.12-1.fc17 will be installed ---> Package perl-Carp.noarch 0:1.22-2.fc17 will be installed ---> Package perl-Module-Pluggable.noarch 1:3.90-211.fc17 will be installed ---> Package perl-PathTools.x86_64 0:3.33-211.fc17 will be installed ---> Package perl-Pod-Simple.noarch 1:3.16-211.fc17 will be installed --> Processing Dependency: perl(Pod::Escapes) >= 1.04 for package: 1:perl-Pod-Simple-3.16-211.fc17.noarch ---> Package perl-Scalar-List-Utils.x86_64 0:1.25-1.fc17 will be installed ---> Package perl-Socket.x86_64 0:2.001-1.fc17 will be installed ---> Package perl-TimeDate.noarch 1:1.20-6.fc17 will be installed ---> Package perl-libs.x86_64 4:5.14.2-211.fc17 will be installed ---> Package perl-macros.x86_64 4:5.14.2-211.fc17 will be installed ---> Package perl-threads.x86_64 0:1.86-2.fc17 will be installed ---> Package perl-threads-shared.x86_64 0:1.40-2.fc17 will be installed ---> Package quota.x86_64 1:4.00-3.fc17 will be installed --> Processing Dependency: quota-nls = 1:4.00-3.fc17 for package: 1:quota-4.00-3.fc17.x86_64 --> Processing Dependency: tcp_wrappers for package: 1:quota-4.00-3.fc17.x86_64 ---> Package xfsprogs.x86_64 0:3.1.8-1.fc17 will be installed --> Running transaction check ---> Package keyutils.x86_64 0:1.5.5-2.fc17 will be installed ---> Package libevent.x86_64 0:2.0.14-2.fc17 will be installed ---> Package libgssglue.x86_64 0:0.3-1.fc17 will be installed ---> Package libnfsidmap.x86_64 0:0.25-1.fc17 will be installed ---> Package libtalloc.x86_64 0:2.0.7-4.fc17 will be installed ---> Package libtirpc.x86_64 0:0.2.2-2.1.fc17 will be installed ---> Package libwbclient.x86_64 1:3.6.3-81.fc17.1 will be installed ---> Package perl-Pod-Escapes.noarch 1:1.04-211.fc17 will be installed ---> Package quota-nls.noarch 1:4.00-3.fc17 will be installed ---> Package rpcbind.x86_64 0:0.2.0-16.fc17 will be installed ---> Package tcp_wrappers.x86_64 0:7.6-69.fc17 will be installed --> Finished Dependency Resolution Dependencies Resolved ===================================================================================== Package Arch Version Repository Size ===================================================================================== Installing: corosync x86_64 1.99.9-1.fc17 updates-testing 159 k pacemaker x86_64 1.1.7-2.fc17 updates-testing 362 k Installing for dependencies: OpenIPMI-libs x86_64 2.0.18-13.fc17 fedora 466 k cifs-utils x86_64 5.3-2.fc17 updates-testing 66 k cluster-glue x86_64 1.0.6-9.fc17.1 fedora 229 k cluster-glue-libs x86_64 1.0.6-9.fc17.1 fedora 121 k corosynclib x86_64 1.99.9-1.fc17 updates-testing 96 k ethtool x86_64 2:3.2-2.fc17 fedora 94 k gnutls x86_64 2.12.17-1.fc17 fedora 385 k keyutils x86_64 1.5.5-2.fc17 fedora 49 k libevent x86_64 2.0.14-2.fc17 fedora 160 k libgssglue x86_64 0.3-1.fc17 fedora 24 k libibverbs x86_64 1.1.6-2.fc17 fedora 44 k libnet x86_64 1.1.5-3.fc17 fedora 54 k libnfsidmap x86_64 0.25-1.fc17 fedora 34 k libqb x86_64 0.11.1-1.fc17 updates-testing 68 k librdmacm x86_64 1.0.15-1.fc17 fedora 27 k libtalloc x86_64 2.0.7-4.fc17 fedora 22 k libtasn1 x86_64 2.12-1.fc17 updates-testing 319 k libtirpc x86_64 0.2.2-2.1.fc17 fedora 78 k libtool-ltdl x86_64 2.4.2-3.fc17 fedora 45 k libwbclient x86_64 1:3.6.3-81.fc17.1 updates-testing 68 k libxslt x86_64 1.1.26-9.fc17 fedora 416 k net-snmp-libs x86_64 1:5.7.1-4.fc17 fedora 713 k nfs-utils x86_64 1:1.2.5-12.fc17 fedora 311 k p11-kit x86_64 0.12-1.fc17 updates-testing 36 k pacemaker-cli x86_64 1.1.7-2.fc17 updates-testing 368 k pacemaker-cluster-libs x86_64 1.1.7-2.fc17 updates-testing 77 k pacemaker-libs x86_64 1.1.7-2.fc17 updates-testing 322 k perl x86_64 4:5.14.2-211.fc17 fedora 10 M perl-Carp noarch 1.22-2.fc17 fedora 17 k perl-Module-Pluggable noarch 1:3.90-211.fc17 fedora 47 k perl-PathTools x86_64 3.33-211.fc17 fedora 105 k perl-Pod-Escapes noarch 1:1.04-211.fc17 fedora 40 k perl-Pod-Simple noarch 1:3.16-211.fc17 fedora 223 k perl-Scalar-List-Utils x86_64 1.25-1.fc17 updates-testing 33 k perl-Socket x86_64 2.001-1.fc17 updates-testing 44 k perl-TimeDate noarch 1:1.20-6.fc17 fedora 43 k perl-libs x86_64 4:5.14.2-211.fc17 fedora 628 k perl-macros x86_64 4:5.14.2-211.fc17 fedora 32 k perl-threads x86_64 1.86-2.fc17 fedora 47 k perl-threads-shared x86_64 1.40-2.fc17 fedora 36 k quota x86_64 1:4.00-3.fc17 fedora 160 k quota-nls noarch 1:4.00-3.fc17 fedora 74 k resource-agents x86_64 3.9.2-2.fc17.1 fedora 466 k rpcbind x86_64 0.2.0-16.fc17 fedora 52 k tcp_wrappers x86_64 7.6-69.fc17 fedora 72 k xfsprogs x86_64 3.1.8-1.fc17 updates-testing 715 k Transaction Summary ===================================================================================== Install 2 Packages (+46 Dependent packages) Total download size: 18 M Installed size: 59 M Downloading Packages: (1/48): OpenIPMI-libs-2.0.18-13.fc17.x86_64.rpm | 466 kB 00:00 warning: rpmts_HdrFromFdno: Header V3 RSA/SHA256 Signature, key ID 1aca3465: NOKEY Public key for OpenIPMI-libs-2.0.18-13.fc17.x86_64.rpm is not installed (2/48): cifs-utils-5.3-2.fc17.x86_64.rpm | 66 kB 00:01 Public key for cifs-utils-5.3-2.fc17.x86_64.rpm is not installed (3/48): cluster-glue-1.0.6-9.fc17.1.x86_64.rpm | 229 kB 00:00 (4/48): cluster-glue-libs-1.0.6-9.fc17.1.x86_64.rpm | 121 kB 00:00 (5/48): corosync-1.99.9-1.fc17.x86_64.rpm | 159 kB 00:01 (6/48): corosynclib-1.99.9-1.fc17.x86_64.rpm | 96 kB 00:00 (7/48): ethtool-3.2-2.fc17.x86_64.rpm | 94 kB 00:00 (8/48): gnutls-2.12.17-1.fc17.x86_64.rpm | 385 kB 00:00 (9/48): keyutils-1.5.5-2.fc17.x86_64.rpm | 49 kB 00:00 (10/48): libevent-2.0.14-2.fc17.x86_64.rpm | 160 kB 00:00 (11/48): libgssglue-0.3-1.fc17.x86_64.rpm | 24 kB 00:00 (12/48): libibverbs-1.1.6-2.fc17.x86_64.rpm | 44 kB 00:00 (13/48): libnet-1.1.5-3.fc17.x86_64.rpm | 54 kB 00:00 (14/48): libnfsidmap-0.25-1.fc17.x86_64.rpm | 34 kB 00:00 (15/48): libqb-0.11.1-1.fc17.x86_64.rpm | 68 kB 00:01 (16/48): librdmacm-1.0.15-1.fc17.x86_64.rpm | 27 kB 00:00 (17/48): libtalloc-2.0.7-4.fc17.x86_64.rpm | 22 kB 00:00 (18/48): libtasn1-2.12-1.fc17.x86_64.rpm | 319 kB 00:02 (19/48): libtirpc-0.2.2-2.1.fc17.x86_64.rpm | 78 kB 00:00 (20/48): libtool-ltdl-2.4.2-3.fc17.x86_64.rpm | 45 kB 00:00 (21/48): libwbclient-3.6.3-81.fc17.1.x86_64.rpm | 68 kB 00:00 (22/48): libxslt-1.1.26-9.fc17.x86_64.rpm | 416 kB 00:00 (23/48): net-snmp-libs-5.7.1-4.fc17.x86_64.rpm | 713 kB 00:01 (24/48): nfs-utils-1.2.5-12.fc17.x86_64.rpm | 311 kB 00:00 (25/48): p11-kit-0.12-1.fc17.x86_64.rpm | 36 kB 00:01 (26/48): pacemaker-1.1.7-2.fc17.x86_64.rpm | 362 kB 00:02 (27/48): pacemaker-cli-1.1.7-2.fc17.x86_64.rpm | 368 kB 00:02 (28/48): pacemaker-cluster-libs-1.1.7-2.fc17.x86_64.rpm | 77 kB 00:00 (29/48): pacemaker-libs-1.1.7-2.fc17.x86_64.rpm | 322 kB 00:01 (30/48): perl-5.14.2-211.fc17.x86_64.rpm | 10 MB 00:15 (31/48): perl-Carp-1.22-2.fc17.noarch.rpm | 17 kB 00:00 (32/48): perl-Module-Pluggable-3.90-211.fc17.noarch.rpm | 47 kB 00:00 (33/48): perl-PathTools-3.33-211.fc17.x86_64.rpm | 105 kB 00:00 (34/48): perl-Pod-Escapes-1.04-211.fc17.noarch.rpm | 40 kB 00:00 (35/48): perl-Pod-Simple-3.16-211.fc17.noarch.rpm | 223 kB 00:00 (36/48): perl-Scalar-List-Utils-1.25-1.fc17.x86_64.rpm | 33 kB 00:01 (37/48): perl-Socket-2.001-1.fc17.x86_64.rpm | 44 kB 00:00 (38/48): perl-TimeDate-1.20-6.fc17.noarch.rpm | 43 kB 00:00 (39/48): perl-libs-5.14.2-211.fc17.x86_64.rpm | 628 kB 00:00 (40/48): perl-macros-5.14.2-211.fc17.x86_64.rpm | 32 kB 00:00 (41/48): perl-threads-1.86-2.fc17.x86_64.rpm | 47 kB 00:00 (42/48): perl-threads-shared-1.40-2.fc17.x86_64.rpm | 36 kB 00:00 (43/48): quota-4.00-3.fc17.x86_64.rpm | 160 kB 00:00 (44/48): quota-nls-4.00-3.fc17.noarch.rpm | 74 kB 00:00 (45/48): resource-agents-3.9.2-2.fc17.1.x86_64.rpm | 466 kB 00:00 (46/48): rpcbind-0.2.0-16.fc17.x86_64.rpm | 52 kB 00:00 (47/48): tcp_wrappers-7.6-69.fc17.x86_64.rpm | 72 kB 00:00 (48/48): xfsprogs-3.1.8-1.fc17.x86_64.rpm | 715 kB 00:03 ---------------------------------------------------------------------------------------- Total 333 kB/s | 18 MB 00:55 Retrieving key from file:///etc/pki/rpm-gpg/RPM-GPG-KEY-fedora-x86_64 Importing GPG key 0x1ACA3465: Userid : "Fedora (17) " Fingerprint: cac4 3fb7 74a4 a673 d81c 5de7 50e9 4c99 1aca 3465 Package : fedora-release-17-0.8.noarch (@anaconda-0) From : /etc/pki/rpm-gpg/RPM-GPG-KEY-fedora-x86_64 Running Transaction Check Running Transaction Test Transaction Test Succeeded Running Transaction Installing : libqb-0.11.1-1.fc17.x86_64 1/48 Installing : libtool-ltdl-2.4.2-3.fc17.x86_64 2/48 Installing : cluster-glue-libs-1.0.6-9.fc17.1.x86_64 3/48 Installing : libxslt-1.1.26-9.fc17.x86_64 4/48 Installing : 1:perl-Pod-Escapes-1.04-211.fc17.noarch 5/48 Installing : perl-threads-1.86-2.fc17.x86_64 6/48 Installing : 4:perl-macros-5.14.2-211.fc17.x86_64 7/48 Installing : 1:perl-Pod-Simple-3.16-211.fc17.noarch 8/48 Installing : perl-Socket-2.001-1.fc17.x86_64 9/48 Installing : perl-Carp-1.22-2.fc17.noarch 10/48 Installing : 4:perl-libs-5.14.2-211.fc17.x86_64 11/48 Installing : perl-threads-shared-1.40-2.fc17.x86_64 12/48 Installing : perl-Scalar-List-Utils-1.25-1.fc17.x86_64 13/48 Installing : 1:perl-Module-Pluggable-3.90-211.fc17.noarch 14/48 Installing : perl-PathTools-3.33-211.fc17.x86_64 15/48 Installing : 4:perl-5.14.2-211.fc17.x86_64 16/48 Installing : libibverbs-1.1.6-2.fc17.x86_64 17/48 Installing : keyutils-1.5.5-2.fc17.x86_64 18/48 Installing : libgssglue-0.3-1.fc17.x86_64 19/48 Installing : libtirpc-0.2.2-2.1.fc17.x86_64 20/48 Installing : 1:net-snmp-libs-5.7.1-4.fc17.x86_64 21/48 Installing : rpcbind-0.2.0-16.fc17.x86_64 22/48 Installing : librdmacm-1.0.15-1.fc17.x86_64 23/48 Installing : corosynclib-1.99.9-1.fc17.x86_64 24/48 Installing : corosync-1.99.9-1.fc17.x86_64 25/48 error reading information on service corosync: No such file or directory Installing : 1:perl-TimeDate-1.20-6.fc17.noarch 26/48 Installing : 1:quota-nls-4.00-3.fc17.noarch 27/48 Installing : tcp_wrappers-7.6-69.fc17.x86_64 28/48 Installing : 1:quota-4.00-3.fc17.x86_64 29/48 Installing : libnfsidmap-0.25-1.fc17.x86_64 30/48 Installing : 1:libwbclient-3.6.3-81.fc17.1.x86_64 31/48 Installing : libnet-1.1.5-3.fc17.x86_64 32/48 Installing : 2:ethtool-3.2-2.fc17.x86_64 33/48 Installing : libevent-2.0.14-2.fc17.x86_64 34/48 Installing : 1:nfs-utils-1.2.5-12.fc17.x86_64 35/48 Installing : libtalloc-2.0.7-4.fc17.x86_64 36/48 Installing : cifs-utils-5.3-2.fc17.x86_64 37/48 Installing : libtasn1-2.12-1.fc17.x86_64 38/48 Installing : OpenIPMI-libs-2.0.18-13.fc17.x86_64 39/48 Installing : cluster-glue-1.0.6-9.fc17.1.x86_64 40/48 Installing : p11-kit-0.12-1.fc17.x86_64 41/48 Installing : gnutls-2.12.17-1.fc17.x86_64 42/48 Installing : pacemaker-libs-1.1.7-2.fc17.x86_64 43/48 Installing : pacemaker-cluster-libs-1.1.7-2.fc17.x86_64 44/48 Installing : pacemaker-cli-1.1.7-2.fc17.x86_64 45/48 Installing : xfsprogs-3.1.8-1.fc17.x86_64 46/48 Installing : resource-agents-3.9.2-2.fc17.1.x86_64 47/48 Installing : pacemaker-1.1.7-2.fc17.x86_64 48/48 Verifying : xfsprogs-3.1.8-1.fc17.x86_64 1/48 Verifying : 1:net-snmp-libs-5.7.1-4.fc17.x86_64 2/48 Verifying : corosync-1.99.9-1.fc17.x86_64 3/48 Verifying : cluster-glue-1.0.6-9.fc17.1.x86_64 4/48 Verifying : perl-PathTools-3.33-211.fc17.x86_64 5/48 Verifying : p11-kit-0.12-1.fc17.x86_64 6/48 Verifying : 1:perl-Pod-Simple-3.16-211.fc17.noarch 7/48 Verifying : OpenIPMI-libs-2.0.18-13.fc17.x86_64 8/48 Verifying : libtasn1-2.12-1.fc17.x86_64 9/48 Verifying : perl-threads-1.86-2.fc17.x86_64 10/48 Verifying : 1:perl-Pod-Escapes-1.04-211.fc17.noarch 11/48 Verifying : pacemaker-1.1.7-2.fc17.x86_64 12/48 Verifying : 4:perl-5.14.2-211.fc17.x86_64 13/48 Verifying : gnutls-2.12.17-1.fc17.x86_64 14/48 Verifying : perl-threads-shared-1.40-2.fc17.x86_64 15/48 Verifying : 4:perl-macros-5.14.2-211.fc17.x86_64 16/48 Verifying : 1:perl-Module-Pluggable-3.90-211.fc17.noarch 17/48 Verifying : 1:nfs-utils-1.2.5-12.fc17.x86_64 18/48 Verifying : cluster-glue-libs-1.0.6-9.fc17.1.x86_64 19/48 Verifying : pacemaker-libs-1.1.7-2.fc17.x86_64 20/48 Verifying : libtalloc-2.0.7-4.fc17.x86_64 21/48 Verifying : libevent-2.0.14-2.fc17.x86_64 22/48 Verifying : perl-Socket-2.001-1.fc17.x86_64 23/48 Verifying : libgssglue-0.3-1.fc17.x86_64 24/48 Verifying : perl-Carp-1.22-2.fc17.noarch 25/48 Verifying : libtirpc-0.2.2-2.1.fc17.x86_64 26/48 Verifying : 2:ethtool-3.2-2.fc17.x86_64 27/48 Verifying : 4:perl-libs-5.14.2-211.fc17.x86_64 28/48 Verifying : libxslt-1.1.26-9.fc17.x86_64 29/48 Verifying : rpcbind-0.2.0-16.fc17.x86_64 30/48 Verifying : librdmacm-1.0.15-1.fc17.x86_64 31/48 Verifying : resource-agents-3.9.2-2.fc17.1.x86_64 32/48 Verifying : 1:quota-4.00-3.fc17.x86_64 33/48 Verifying : 1:perl-TimeDate-1.20-6.fc17.noarch 34/48 Verifying : perl-Scalar-List-Utils-1.25-1.fc17.x86_64 35/48 Verifying : libtool-ltdl-2.4.2-3.fc17.x86_64 36/48 Verifying : pacemaker-cluster-libs-1.1.7-2.fc17.x86_64 37/48 Verifying : cifs-utils-5.3-2.fc17.x86_64 38/48 Verifying : libnet-1.1.5-3.fc17.x86_64 39/48 Verifying : corosynclib-1.99.9-1.fc17.x86_64 40/48 Verifying : libqb-0.11.1-1.fc17.x86_64 41/48 Verifying : 1:libwbclient-3.6.3-81.fc17.1.x86_64 42/48 Verifying : libnfsidmap-0.25-1.fc17.x86_64 43/48 Verifying : tcp_wrappers-7.6-69.fc17.x86_64 44/48 Verifying : keyutils-1.5.5-2.fc17.x86_64 45/48 Verifying : libibverbs-1.1.6-2.fc17.x86_64 46/48 Verifying : 1:quota-nls-4.00-3.fc17.noarch 47/48 Verifying : pacemaker-cli-1.1.7-2.fc17.x86_64 48/48 Installed: corosync.x86_64 0:1.99.9-1.fc17 pacemaker.x86_64 0:1.1.7-2.fc17 Dependency Installed: OpenIPMI-libs.x86_64 0:2.0.18-13.fc17 cifs-utils.x86_64 0:5.3-2.fc17 cluster-glue.x86_64 0:1.0.6-9.fc17.1 cluster-glue-libs.x86_64 0:1.0.6-9.fc17.1 corosynclib.x86_64 0:1.99.9-1.fc17 ethtool.x86_64 2:3.2-2.fc17 gnutls.x86_64 0:2.12.17-1.fc17 keyutils.x86_64 0:1.5.5-2.fc17 libevent.x86_64 0:2.0.14-2.fc17 libgssglue.x86_64 0:0.3-1.fc17 libibverbs.x86_64 0:1.1.6-2.fc17 libnet.x86_64 0:1.1.5-3.fc17 libnfsidmap.x86_64 0:0.25-1.fc17 libqb.x86_64 0:0.11.1-1.fc17 librdmacm.x86_64 0:1.0.15-1.fc17 libtalloc.x86_64 0:2.0.7-4.fc17 libtasn1.x86_64 0:2.12-1.fc17 libtirpc.x86_64 0:0.2.2-2.1.fc17 libtool-ltdl.x86_64 0:2.4.2-3.fc17 libwbclient.x86_64 1:3.6.3-81.fc17.1 libxslt.x86_64 0:1.1.26-9.fc17 net-snmp-libs.x86_64 1:5.7.1-4.fc17 nfs-utils.x86_64 1:1.2.5-12.fc17 p11-kit.x86_64 0:0.12-1.fc17 pacemaker-cli.x86_64 0:1.1.7-2.fc17 pacemaker-cluster-libs.x86_64 0:1.1.7-2.fc17 pacemaker-libs.x86_64 0:1.1.7-2.fc17 perl.x86_64 4:5.14.2-211.fc17 perl-Carp.noarch 0:1.22-2.fc17 perl-Module-Pluggable.noarch 1:3.90-211.fc17 perl-PathTools.x86_64 0:3.33-211.fc17 perl-Pod-Escapes.noarch 1:1.04-211.fc17 perl-Pod-Simple.noarch 1:3.16-211.fc17 perl-Scalar-List-Utils.x86_64 0:1.25-1.fc17 perl-Socket.x86_64 0:2.001-1.fc17 perl-TimeDate.noarch 1:1.20-6.fc17 perl-libs.x86_64 4:5.14.2-211.fc17 perl-macros.x86_64 4:5.14.2-211.fc17 perl-threads.x86_64 0:1.86-2.fc17 perl-threads-shared.x86_64 0:1.40-2.fc17 quota.x86_64 1:4.00-3.fc17 quota-nls.noarch 1:4.00-3.fc17 resource-agents.x86_64 0:3.9.2-2.fc17.1 rpcbind.x86_64 0:0.2.0-16.fc17 tcp_wrappers.x86_64 0:7.6-69.fc17 xfsprogs.x86_64 0:3.1.8-1.fc17 Complete! [root@pcmk-1 ~]# ..... Now install the cluster software on the second node. ifdef::pcs[] === Install the Cluster Management Software === The pcs cli command coupled with the pcs daemon creates a cluster management system capable of managing all aspects of the cluster stack across all nodes from a single location. [source,C] ---- [ALL] # yum install -y pcs ---- Make sure to install the pcs packages on both nodes. endif::[] == Setup == ifdef::pcs[] === Enable pcs Daemon === Before the cluster can be configured, the pcs daemon must be started and enabled to boot on startup on each node. This daemon works with the pcs cli command to manage syncing the corosync configuration across all the nodes in the cluster. Start and enable the daemon by issuing the following commands on each node. [source,C] ---- # systemctl start pcsd.service # systemctl enable pcsd.service ---- Now we need a way for `pcs` to talk to itself on other nodes in the cluster. This is necessary in order to perform tasks such as syncing the corosync config, or starting/stopping the cluster on remote nodes While `pcs` can be used locally without setting up these user accounts, this tutorial will make use of these remote access commands, so we will set a password for the 'hacluster' user. Its probably best if password is consistent across all the nodes. As 'root', run: [source,C] ---- # passwd hacluster password: ---- Alternatively, to script this process or set the password on a different machine to the one you're logged into, you can use the `--stdin` option for `passwd`: [source,C] ---- # ssh pcmk-2 -- 'echo redhat1 | passwd --stdin hacluster' ---- endif::[] ifdef::crmsh[] === Preparation - Multicast === Choose a port number and http://en.wikipedia.org/wiki/Multicast[multi-cast] address. http://en.wikipedia.org/wiki/Multicast_address[] Be sure that the values you chose do not conflict with any existing clusters you might have. For this document, I have chosen port '4000' and used '239.255.1.1' as the multi-cast address. endif::[] === Notes on Multicast Address Assignment === There are several subtle points that often deserve consideration when choosing/assigning multicast addresses for corosync. footnote:[This information is borrowed from, the now defunct, http://web.archive.org/web/20101211210054/http://29west.com/docs/THPM/multicast-address-assignment.html] . Avoid '224.0.0.x' + Traffic to addresses of the form '224.0.0.x' is often flooded to all switch ports. This address range is reserved for link-local uses. Many routing protocols assume that all traffic within this range will be received by all routers on the network. Hence (at least all Cisco) switches flood traffic within this range. The flooding behavior overrides the normal selective forwarding behavior of a multicast-aware switch (e.g. IGMP snooping, CGMP, etc.). . Watch for '32:1' overlap + 32 non-contiguous IP multicast addresses are mapped onto each Ethernet multicast address. A receiver that joins a single IP multicast group implicitly joins 31 others due to this overlap. Of course, filtering in the operating system discards undesired multicast traffic from applications, but NIC bandwidth and CPU resources are nonetheless consumed discarding it. The overlap occurs in the 5 high-order bits, so it's best to use the 23 low-order bits to make distinct multicast streams unique. For example, IP multicast addresses in the range '239.0.0.0' to '239.127.255.255' all map to unique Ethernet multicast addresses. However, IP multicast address '239.128.0.0' maps to the same Ethernet multicast address as '239.0.0.0', '239.128.0.1' maps to the same Ethernet multicast address as '239.0.0.1', etc. . Avoid 'x.0.0.y' and 'x.128.0.y' + Combining the above two considerations, it's best to avoid using IP multicast addresses of the form 'x.0.0.y' and 'x.128.0.y' since they all map onto the range of Ethernet multicast addresses that are flooded to all switch ports. . Watch for address assignment conflicts + http://www.iana.org/[IANA] administers http://www.iana.org/assignments/multicast-addresses[Internet multicast addresses]. Potential conflicts with Internet multicast address assignments can be avoided by using http://www.ietf.org/rfc/rfc3180.txt[GLOP addressing] (http://en.wikipedia.org/wiki/Autonomous_system_%28Internet%29[AS] required) or http://www.ietf.org/rfc/rfc2365.txt[administratively scoped] addresses. Such addresses can be safely used on a network connected to the Internet without fear of conflict with multicast sources originating on the Internet. Administratively scoped addresses are roughly analogous to the unicast address space for http://www.ietf.org/rfc/rfc1918.txt[private internets]. Site-local multicast addresses are of the form '239.255.x.y', but can grow down to '239.252.x.y' if needed. Organization-local multicast addresses are of the form '239.192-251.x.y', but can grow down to '239.x.y.z' if needed. For a more detailed treatment (57 pages!), see http://www.cisco.com/en/US/tech/tk828/technologies_white_paper09186a00802d4643.shtml[Cisco's Guidelines for Enterprise IP Multicast Address Allocation] paper. === Configuring Corosync === ifdef::pcs[] In the past, at this point in the tutorial an explanation of how to configure and propagate corosync's /etc/corosync.conf file would be necessary. Using pcs with the pcs daemon greatly simplifies this process by generating 'corosync.conf' across all the nodes in the cluster with a single command. The only thing required to achieve this is to authenticate as the pcs user 'hacluster' on one of the nodes in the cluster, and then issue the 'pcs cluster setup' command with a list of all the node names in the cluster. [source,C] ---- # pcs cluster auth pcmk-1 pcmk-2 Username: hacluster Password: pcmk-1: Authorized pcmk-2: Authorized # pcs cluster setup mycluster pcmk-1 pcmk-2 pcmk-1: Succeeded pcmk-2: Succeeded ---- That's it. Corosync is configured across the cluster. If you received an authorization error for either of those commands, make sure you setup the 'hacluster' user account and password on every node in the cluster with the same password. endif::[] ifdef::crmsh[] [IMPORTANT] =========== The instructions below only apply for a machine with a single NIC. If you have a more complicated setup, you should edit the configuration manually. =========== [source,C] ---- # export ais_port=4000 # export ais_mcast=239.255.1.1 ---- Next we automatically determine the hosts address. By not using the full address, we make the configuration suitable to be copied to other nodes. [source,Bash] ---- export ais_addr=`ip addr | grep "inet " | tail -n 1 | awk '{print $4}' | sed s/255/0/g` ---- Display and verify the configuration options [source,Bash] ---- # env | grep ais_ ais_mcast=239.255.1.1 ais_port=4000 ais_addr=192.168.122.0 ---- Once you're happy with the chosen values, update the Corosync configuration [source,C] ---- # cp /etc/corosync/corosync.conf.example /etc/corosync/corosync.conf # sed -i.bak "s/.*mcastaddr:.*/mcastaddr:\ $ais_mcast/g" /etc/corosync/corosync.conf # sed -i.bak "s/.*mcastport:.*/mcastport:\ $ais_port/g" /etc/corosync/corosync.conf # sed -i.bak "s/.*\tbindnetaddr:.*/bindnetaddr:\ $ais_addr/g" /etc/corosync/corosync.conf ---- Lastly, you'll need to enable quorum [source,Bash] ----- cat << END >> /etc/corosync/corosync.conf quorum { provider: corosync_votequorum expected_votes: 2 } END ----- endif::[] The final /etc/corosync.conf configuration on each node should look something like the sample in Appendix B, Sample Corosync Configuration. [IMPORTANT] =========== Pacemaker used to obtain membership and quorum from a custom Corosync plugin. This plugin also had the capability to start Pacemaker automatically when Corosync was started. Neither behavior is possible with Corosync 2.0 and beyond as support for plugins was removed. Instead, Pacemaker must be started as a separate service. Also, since Pacemaker made use of the plugin for message routing, a node using the plugin (Corosync prior to 2.0) cannot talk to one that isn't (Corosync 2.0+). Rolling upgrades between these versions are therefor not possible and an alternate strategy footnote:[http://www.clusterlabs.org/doc/en-US/Pacemaker/1.1/html/Pacemaker_Explained/ap-upgrade.html] must be used. =========== ifdef::crmsh[] === Propagate the Configuration === Now we need to copy the changes so far to the other node: [source,C] ---- # for f in /etc/corosync/corosync.conf /etc/hosts; do scp $f pcmk-2:$f ; done corosync.conf 100% 1528 1.5KB/s 00:00 hosts 100% 281 0.3KB/s 00:00 # ---- endif::[] pacemaker-master/doc/Clusters_from_Scratch/en-US/Ch-Intro.txt000066400000000000000000000160601217637305600244720ustar00rootroot00000000000000= Read-Me-First = == The Scope of this Document == Computer clusters can be used to provide highly available services or resources. The redundancy of multiple machines is used to guard against failures of many types. This document will walk through the installation and setup of simple clusters using the Fedora distribution, version 17. The clusters described here will use Pacemaker and Corosync to provide resource management and messaging. Required packages and modifications to their configuration files are described along with the use of the Pacemaker command line tool for generating the XML used for cluster control. Pacemaker is a central component and provides the resource management required in these systems. This management includes detecting and recovering from the failure of various nodes, resources and services under its control. When more in depth information is required and for real world usage, please refer to the http://www.clusterlabs.org/doc/[Pacemaker Explained] manual. == What Is Pacemaker? == Pacemaker is a cluster resource manager. It achieves maximum availability for your cluster services (aka. resources) by detecting and recovering from node and resource-level failures by making use of the messaging and membership capabilities provided by your preferred cluster infrastructure (either Corosync or Heartbeat). Pacemaker's key features include: * Detection and recovery of node and service-level failures * Storage agnostic, no requirement for shared storage * Resource agnostic, anything that can be scripted can be clustered * Supports STONITH for ensuring data integrity * Supports large and small clusters * Supports both quorate and resource driven clusters * Supports practically any redundancy configuration * Automatically replicated configuration that can be updated from any node * Ability to specify cluster-wide service ordering, colocation and anti-colocation * Support for advanced service types ** Clones: for services which need to be active on multiple nodes ** Multi-state: for services with multiple modes (eg. master/slave, primary/secondary) * Unified, scriptable, cluster management tools. == Pacemaker Architecture == At the highest level, the cluster is made up of three pieces: * Non-cluster aware components (illustrated in green). These pieces include the resources themselves, scripts that start, stop and monitor them, and also a local daemon that masks the differences between the different standards these scripts implement. * Resource management Pacemaker provides the brain (illustrated in blue) that processes and reacts to events regarding the cluster. These events include nodes joining or leaving the cluster; resource events caused by failures, maintenance, scheduled activities; and other administrative actions. Pacemaker will compute the ideal state of the cluster and plot a path to achieve it after any of these events. This may include moving resources, stopping nodes and even forcing them offline with remote power switches. * Low level infrastructure Corosync provides reliable messaging, membership and quorum information about the cluster (illustrated in red). .Conceptual Stack Overview image::images/pcmk-overview.png["Conceptual overview of the cluster stack",align="center"] When combined with Corosync, Pacemaker also supports popular open source cluster filesystems. footnote:[Even though Pacemaker also supports Heartbeat, the filesystems need to use the stack for messaging and membership and Corosync seems to be what they're standardizing on. Technically it would be possible for them to support Heartbeat as well, however there seems little interest in this.] Due to recent standardization within the cluster filesystem community, they make use of a common distributed lock manager which makes use of Corosync for its messaging capabilities and Pacemaker for its membership (which nodes are up/down) and fencing services. .The Pacemaker Stack image::images/pcmk-stack.png["The Pacemaker StackThe Pacemaker stack when running on Corosync",align="center"] === Internal Components === Pacemaker itself is composed of four key components (illustrated below in the same color scheme as the previous diagram): * CIB (aka. Cluster Information Base) * CRMd (aka. Cluster Resource Management daemon) * PEngine (aka. PE or Policy Engine) * STONITHd .Internal Components image::images/pcmk-internals.png["Subsystems of a Pacemaker cluster running on Corosync",align="center"] The CIB uses XML to represent both the cluster's configuration and current state of all resources in the cluster. The contents of the CIB are automatically kept in sync across the entire cluster and are used by the PEngine to compute the ideal state of the cluster and how it should be achieved. This list of instructions is then fed to the DC (Designated Co-ordinator). Pacemaker centralizes all cluster decision making by electing one of the CRMd instances to act as a master. Should the elected CRMd process, or the node it is on, fail... a new one is quickly established. The DC carries out the PEngine's instructions in the required order by passing them to either the LRMd (Local Resource Management daemon) or CRMd peers on other nodes via the cluster messaging infrastructure (which in turn passes them on to their LRMd process). The peer nodes all report the results of their operations back to the DC and based on the expected and actual results, will either execute any actions that needed to wait for the previous one to complete, or abort processing and ask the PEngine to recalculate the ideal cluster state based on the unexpected results. In some cases, it may be necessary to power off nodes in order to protect shared data or complete resource recovery. For this Pacemaker comes with STONITHd. STONITH is an acronym for Shoot-The-Other-Node-In-The-Head and is usually implemented with a remote power switch. In Pacemaker, STONITH devices are modeled as resources (and configured in the CIB) to enable them to be easily monitored for failure, however STONITHd takes care of understanding the STONITH topology such that its clients simply request a node be fenced and it does the rest. == Types of Pacemaker Clusters == Pacemaker makes no assumptions about your environment, this allows it to support practically any http://en.wikipedia.org/wiki/High-availability_cluster#Node_configurations[redundancy configuration] including Active/Active, Active/Passive, N+1, N+M, N-to-1 and N-to-N. In this document we will focus on the setup of a highly available Apache web server with an Active/Passive cluster using DRBD and Ext4 to store data. Then, we will upgrade this cluster to Active/Active using GFS2. .Active/Passive Redundancy image::images/pcmk-active-passive.png["Two-node Active/Passive clusters using Pacemaker and DRBD are a cost-effective solution for many High Availability situations",align="center"] .N to N Redundancy image::images/pcmk-active-active.png["When shared storage is available, every node can potentially be used for failover. Pacemaker can even run multiple copies of services to spread out the workload",align="center"] pacemaker-master/doc/Clusters_from_Scratch/en-US/Ch-Shared-Storage.txt000066400000000000000000000552571217637305600262220ustar00rootroot00000000000000= Replicated Storage with DRBD = == Background == Even if you're serving up static websites, having to manually synchronize the contents of that website to all the machines in the cluster is not ideal. For dynamic websites, such as a wiki, it's not even an option. Not everyone care afford network-attached storage but somehow the data needs to be kept in sync. Enter DRBD which can be thought of as network based RAID-1. See http://www.drbd.org/ for more details. == Install the DRBD Packages == Since its inclusion in the upstream 2.6.33 kernel, everything needed to use DRBD has shiped with Fedora since version 13. All you need to do is install it: [source,C] # yum install -y drbd-pacemaker drbd-udev ..... Loaded plugins: langpacks, presto, refresh-packagekit Resolving Dependencies --> Running transaction check ---> Package drbd-pacemaker.x86_64 0:8.3.11-5.fc17 will be installed --> Processing Dependency: drbd-utils = 8.3.11-5.fc17 for package: drbd-pacemaker-8.3.11-5.fc17.x86_64 ---> Package drbd-udev.x86_64 0:8.3.11-5.fc17 will be installed --> Running transaction check ---> Package drbd-utils.x86_64 0:8.3.11-5.fc17 will be installed --> Finished Dependency Resolution Dependencies Resolved ====================================================================================== Package Arch Version Repository Size ====================================================================================== Installing: drbd-pacemaker x86_64 8.3.11-5.fc17 updates-testing 22 k drbd-udev x86_64 8.3.11-5.fc17 updates-testing 6.4 k Installing for dependencies: drbd-utils x86_64 8.3.11-5.fc17 updates-testing 183 k Transaction Summary ====================================================================================== Install 2 Packages (+1 Dependent package) Total download size: 212 k Installed size: 473 k Downloading Packages: (1/3): drbd-pacemaker-8.3.11-5.fc17.x86_64.rpm | 22 kB 00:00 (2/3): drbd-udev-8.3.11-5.fc17.x86_64.rpm | 6.4 kB 00:00 (3/3): drbd-utils-8.3.11-5.fc17.x86_64.rpm | 183 kB 00:00 -------------------------------------------------------------------------------------- Total 293 kB/s | 212 kB 00:00 Running Transaction Check Running Transaction Test Transaction Test Succeeded Running Transaction Installing : drbd-utils-8.3.11-5.fc17.x86_64 1/3 Installing : drbd-pacemaker-8.3.11-5.fc17.x86_64 2/3 Installing : drbd-udev-8.3.11-5.fc17.x86_64 3/3 Verifying : drbd-pacemaker-8.3.11-5.fc17.x86_64 1/3 Verifying : drbd-udev-8.3.11-5.fc17.x86_64 2/3 Verifying : drbd-utils-8.3.11-5.fc17.x86_64 3/3 Installed: drbd-pacemaker.x86_64 0:8.3.11-5.fc17 drbd-udev.x86_64 0:8.3.11-5.fc17 Dependency Installed: drbd-utils.x86_64 0:8.3.11-5.fc17 Complete! ..... == Configure DRBD == Before we configure DRBD, we need to set aside some disk for it to use. === Create A Partition for DRBD === If you have more than 1Gb free, feel free to use it. For this guide however, 1Gb is plenty of space for a single html file and sufficient for later holding the GFS2 metadata. [source,C] ---- # vgdisplay | grep -e Name -e Free VG Name vg_pcmk1 Free PE / Size 31 / 992.00 MiB # lvs LV VG Attr LSize Pool Origin Data% Move Log Copy% Convert lv_root vg_pcmk1 -wi-ao-- 8.56g lv_swap vg_pcmk1 -wi-ao-- 960.00m # lvcreate -n drbd-demo -L 1G vg_pcmk1 Logical volume "drbd-demo" created # lvs LV VG Attr LSize Pool Origin Data% Move Log Copy% Convert drbd-demo vg_pcmk1 -wi-a--- 1.00G lv_root vg_pcmk1 -wi-ao-- 8.56g lv_swap vg_pcmk1 -wi-ao-- 960.00m ---- Repeat this on the second node, be sure to use the same size partition. [source,C] ---- # ssh pcmk-2 -- lvs LV VG Attr LSize Origin Snap% Move Log Copy% Convert lv_root vg_pcmk1 -wi-ao-- 8.56g lv_swap vg_pcmk1 -wi-ao-- 960.00m # ssh pcmk-2 -- lvcreate -n drbd-demo -L 1G vg_pcmk1 Logical volume "drbd-demo" created # ssh pcmk-2 -- lvs LV VG Attr LSize Origin Snap% Move Log Copy% Convert drbd-demo vg_pcmk1 -wi-a--- 1.00G lv_root vg_pcmk1 -wi-ao-- 8.56g lv_swap vg_pcmk1 -wi-ao-- 960.00m ---- === Write the DRBD Config === There is no series of commands for building a DRBD configuration, so simply copy the configuration below to /etc/drbd.conf Detailed information on the directives used in this configuration (and other alternatives) is available from http://www.drbd.org/users-guide/ch-configure.html [WARNING] ========= Be sure to use the names and addresses of your nodes if they differ from the ones used in this guide. ========= .... global { usage-count yes; } common { protocol C; } resource wwwdata { meta-disk internal; device /dev/drbd1; syncer { verify-alg sha1; } net { allow-two-primaries; } on pcmk-1 { disk /dev/vg_pcmk1/drbd-demo; address 192.168.122.101:7789; } on pcmk-2 { disk /dev/vg_pcmk1/drbd-demo; address 192.168.122.102:7789; } } .... [NOTE] ======= TODO: Explain the reason for the allow-two-primaries option ======= === Initialize and Load DRBD === With the configuration in place, we can now perform the DRBD initialization [source,C] ---- # drbdadm create-md wwwdata Writing meta data... initializing activity log NOT initialized bitmap New drbd meta data block successfully created. success ---- Now load the DRBD kernel module and confirm that everything is sane [source,C] ---- # modprobe drbd # drbdadm up wwwdata # cat /proc/drbd version: 8.3.11 (api:88/proto:86-96) srcversion: 0D2B62DEDB020A425130935 1: cs:Connected ro:Secondary/Secondary ds:Inconsistent/Inconsistent C r----- ns:0 nr:0 dw:0 dr:0 al:0 bm:0 lo:0 pe:0 ua:0 ap:0 ep:1 wo:f oos:1015740 ---- Repeat on the second node [source,C] ---- # ssh pcmk-2 -- drbdadm --force create-md wwwdata Writing meta data... initializing activity log NOT initialized bitmap New drbd meta data block successfully created. success # ssh pcmk-2 -- modprobe drbd WARNING: Deprecated config file /etc/modprobe.conf, all config files belong into /etc/modprobe.d/. # ssh pcmk-2 -- drbdadm up wwwdata # ssh pcmk-2 -- cat /proc/drbd version: 8.3.11 (api:88/proto:86-96) srcversion: 0D2B62DEDB020A425130935 1: cs:Connected ro:Secondary/Secondary ds:Inconsistent/Inconsistent C r----- ns:0 nr:0 dw:0 dr:0 al:0 bm:0 lo:0 pe:0 ua:0 ap:0 ep:1 wo:f oos:1015740 ---- Now we need to tell DRBD which set of data to use. Since both sides contain garbage, we can run the following on pcmk-1: [source,C] ---- # drbdadm -- --overwrite-data-of-peer primary wwwdata # cat /proc/drbd version: 8.3.11 (api:88/proto:86-96) srcversion: 0D2B62DEDB020A425130935 1: cs:SyncSource ro:Primary/Secondary ds:UpToDate/Inconsistent C r----- ns:8064 nr:0 dw:0 dr:8728 al:0 bm:0 lo:0 pe:1 ua:0 ap:0 ep:1 wo:f oos:1007804 [>....................] sync'ed: 0.9% (1007804/1015740)K finish: 0:12:35 speed: 1,320 (1,320) K/sec ---- After a while, the sync should finish and you'll see: [source,C] ---- # cat /proc/drbd version: 8.3.11 (api:88/proto:86-96) srcversion: 0D2B62DEDB020A425130935 1: cs:Connected ro:Primary/Secondary ds:UpToDate/UpToDate C r----- ns:1015740 nr:0 dw:0 dr:1016404 al:0 bm:62 lo:0 pe:0 ua:0 ap:0 ep:1 wo:f oos:0 ---- pcmk-1 is now in the Primary state which allows it to be written to. Which means it's a good point at which to create a filesystem and populate it with some data to serve up via our WebSite resource. === Populate DRBD with Data === [source,C] ---- # mkfs.ext4 /dev/drbd1 mke2fs 1.42 (29-Nov-2011) Filesystem label= OS type: Linux Block size=4096 (log=2) Fragment size=4096 (log=2) Stride=0 blocks, Stripe width=0 blocks 63488 inodes, 253935 blocks 12696 blocks (5.00%) reserved for the super user First data block=0 Maximum filesystem blocks=260046848 8 block groups 32768 blocks per group, 32768 fragments per group 7936 inodes per group Superblock backups stored on blocks: 32768, 98304, 163840, 229376 Allocating group tables: done Writing inode tables: done Creating journal (4096 blocks): done Writing superblocks and filesystem accounting information: done ---- Now mount the newly created filesystem so we can create our index file [source,C] ---- # mount /dev/drbd1 /mnt/ # cat <<-END >/mnt/index.html My Test Site - drbd END # umount /dev/drbd1 ---- == Configure the Cluster for DRBD == ifdef::pcs[] One handy feature pcs has is the ability to queue up several changes into a file and commit those changes atomically. To do this, start by populating the file with the current raw xml config from the cib. This can be done using the following command. [source,C] ---- # pcs cluster cib drbd_cfg ---- Now using the pcs -f option, make changes to the configuration saved in the drbd_cfg file. These changes will not be seen by the cluster until the drbd_cfg file is pushed into the live cluster's cib later on. //// source,C doesn't do well with \'s //// ---- # pcs -f drbd_cfg resource create WebData ocf:linbit:drbd \ drbd_resource=wwwdata op monitor interval=60s # pcs -f drbd_cfg resource master WebDataClone WebData \ master-max=1 master-node-max=1 clone-max=2 clone-node-max=1 \ notify=true ---- [source,C] ---- # pcs -f drbd_cfg resource show ClusterIP (ocf::heartbeat:IPaddr2) Started WebSite (ocf::heartbeat:apache) Started Master/Slave Set: WebDataClone [WebData] Stopped: [ WebData:0 WebData:1 ] ---- After you are satisfied with all the changes, you can commit all the changes at once by pushing the drbd_cfg file into the live cib. [source,C] ---- # pcs cluster push cib drbd_cfg CIB updated # pcs status Last updated: Fri Sep 14 12:19:49 2012 Last change: Fri Sep 14 12:19:13 2012 via cibadmin on pcmk-1 Stack: corosync Current DC: pcmk-2 (2) - partition with quorum Version: 1.1.8-1.el7-60a19ed12fdb4d5c6a6b6767f52e5391e447fec0 2 Nodes configured, unknown expected votes 4 Resources configured. Online: [ pcmk-1 pcmk-2 ] Full list of resources: ClusterIP (ocf::heartbeat:IPaddr2): Started pcmk-1 WebSite (ocf::heartbeat:apache): Started pcmk-1 Master/Slave Set: WebDataClone [WebData] Masters: [ pcmk-1 ] Slaves: [ pcmk-2 ] ---- endif::[] ifdef::crmsh[] One handy feature of the crm shell is that you can use it in interactive mode to make several changes atomically. First we launch the shell. The prompt will change to indicate you're in interactive mode. [source,C] ---- # crm crm(live) # ---- Next we must create a working copy of the current configuration. This is where all our changes will go. The cluster will not see any of them until we say it's ok. Notice again how the prompt changes, this time to indicate that we're no longer looking at the live cluster. [source,C] ---- cib crm(live) # cib new drbd INFO: drbd shadow CIB created crm(drbd) # ---- Now we can create our DRBD clone and display the revised configuration. [source,C] ---- crm(drbd) # configure primitive WebData ocf:linbit:drbd params drbd_resource=wwwdata \ op monitor interval=60s crm(drbd) # configure ms WebDataClone WebData meta master-max=1 master-node-max=1 \ clone-max=2 clone-node-max=1 notify=true crm(drbd) # configure show node $id="1702537408" pcmk-1 node $id="1719314624" pcmk-2 primitive ClusterIP ocf:heartbeat:IPaddr2 \ params ip="192.168.122.120" cidr_netmask="32" \ op monitor interval="30s" primitive WebData ocf:linbit:drbd \ params drbd_resource="wwwdata" \ op monitor interval="60s" primitive WebSite ocf:heartbeat:apache \ params configfile="/etc/httpd/conf/httpd.conf" \ op monitor interval="1min" ms WebDataClone WebData \ meta master-max="1" master-node-max="1" clone-max="2" clone-node-max="1" notify="true" location prefer-pcmk-1 WebSite 50: pcmk-1 colocation website-with-ip inf: WebSite ClusterIP order apache-after-ip inf: ClusterIP WebSite property $id="cib-bootstrap-options" \ dc-version="1.1.7-2.fc17-ee0730e13d124c3d58f00016c3376a1de5323cff" \ cluster-infrastructure="corosync" \ stonith-enabled="false" \ no-quorum-policy="ignore" \ last-lrm-refresh="1333446866" rsc_defaults $id="rsc-options" \ resource-stickiness="100" op_defaults $id="op-options" \ timeout="240s" ---- Once we're happy with the changes, we can tell the cluster to start using them and use crm_mon to check everything is functioning. [source,C] ---- crm(drbd) # cib commit drbd INFO: commited 'drbd' shadow CIB to the cluster crm(drbd) # quit bye # crm_mon -1 ============ Last updated: Tue Apr 3 13:50:01 2012 Last change: Tue Apr 3 13:49:46 2012 via crm_shadow on pcmk-1 Stack: corosync Current DC: pcmk-1 (1702537408) - partition with quorum Version: 1.1.7-2.fc17-ee0730e13d124c3d58f00016c3376a1de5323cff 2 Nodes configured, unknown expected votes 4 Resources configured. ============ Online: [ pcmk-1 pcmk-2 ] ClusterIP (ocf::heartbeat:IPaddr2): Started pcmk-1 WebSite (ocf::heartbeat:apache): Started pcmk-1 Master/Slave Set: WebDataClone [WebData] Masters: [ pcmk-1 ] Slaves: [ pcmk-2 ] ---- endif::[] [NOTE] ======= TODO: Include details on adding a second DRBD resource ======= Now that DRBD is functioning we can configure a Filesystem resource to use it. In addition to the filesystem's definition, we also need to tell the cluster where it can be located (only on the DRBD Primary) and when it is allowed to start (after the Primary was promoted). ifdef::pcs[] We are going to take a shortcut when creating the resource this time though. Instead of explicitly saying we want the 'ocf:heartbeat:Filesystem' script, we are only going to ask for 'Filesystem'. We can do this because we know there is only one resource script named 'Filesystem' available to pacemaker, and that pcs is smart enough to fill in the 'ocf:heartbeat' portion for us correctly in the configuration. If there were multiple 'Filesystem' scripts from different ocf providers, we would need to specify the exact one we wanted to use. Once again we will queue up our changes to a file and then push the new configuration to the cluster as the final step. ---- # pcs cluster cib fs_cfg # pcs -f fs_cfg resource create WebFS Filesystem \ device="/dev/drbd/by-res/wwwdata" directory="/var/www/html" \ fstype="ext4" ---- [source,C] ---- # pcs -f fs_cfg constraint colocation add WebFS WebDataClone INFINITY with-rsc-role=Master # pcs -f fs_cfg constraint order promote WebDataClone then start WebFS Adding WebDataClone WebFS (kind: Mandatory) (Options: first-action=promote then-action=start) ---- We also need to tell the cluster that Apache needs to run on the same machine as the filesystem and that it must be active before Apache can start. [source,C] ---- # pcs -f fs_cfg constraint colocation add WebSite WebFS INFINITY # pcs -f fs_cfg constraint order WebFS then WebSite ---- Now review the updated configuration. [source,C] ---- # pcs -f fs_cfg constraint Location Constraints: Ordering Constraints: start ClusterIP then start WebSite WebFS then WebSite promote WebDataClone then start WebFS Colocation Constraints: WebSite with ClusterIP WebFS with WebDataClone (with-rsc-role:Master) WebSite with WebFS # pcs -f fs_cfg resource show ClusterIP (ocf::heartbeat:IPaddr2) Started WebSite (ocf::heartbeat:apache) Started Master/Slave Set: WebDataClone [WebData] Masters: [ pcmk-1 ] Slaves: [ pcmk-2 ] WebFS (ocf::heartbeat:Filesystem) Stopped ---- endif::[] ifdef::crmsh[] Once again we'll use the shell's interactive mode [source,C] ---- # crm crm(live) # cib new fs INFO: fs shadow CIB created crm(fs) # configure primitive WebFS ocf:heartbeat:Filesystem \ params device="/dev/drbd/by-res/wwwdata" directory="/var/www/html" fstype="ext4" crm(fs) # configure colocation fs_on_drbd inf: WebFS WebDataClone:Master crm(fs) # configure order WebFS-after-WebData inf: WebDataClone:promote WebFS:start ---- We also need to tell the cluster that Apache needs to run on the same machine as the filesystem and that it must be active before Apache can start. [source,C] ---- crm(fs) # configure colocation WebSite-with-WebFS inf: WebSite WebFS crm(fs) # configure order WebSite-after-WebFS inf: WebFS WebSite ---- Time to review the updated configuration: [source,C] ---- crm(fs) # configure show node $id="1702537408" pcmk-1 node $id="1719314624" pcmk-2 primitive ClusterIP ocf:heartbeat:IPaddr2 \ params ip="192.168.122.120" cidr_netmask="32" \ op monitor interval="30s" primitive WebData ocf:linbit:drbd \ params drbd_resource="wwwdata" \ op monitor interval="60s" primitive WebFS ocf:heartbeat:Filesystem \ params device="/dev/drbd/by-res/wwwdata" directory="/var/www/html" fstype="ext4" primitive WebSite ocf:heartbeat:apache \ params configfile="/etc/httpd/conf/httpd.conf" \ op monitor interval="1min" ms WebDataClone WebData \ meta master-max="1" master-node-max="1" clone-max="2" clone-node-max="1" notify="true" location prefer-pcmk-1 WebSite 50: pcmk-1 colocation WebSite-with-WebFS inf: WebSite WebFS colocation fs_on_drbd inf: WebFS WebDataClone:Master colocation website-with-ip inf: WebSite ClusterIP order WebFS-after-WebData inf: WebDataClone:promote WebFS:start order WebSite-after-WebFS inf: WebFS WebSite order apache-after-ip inf: ClusterIP WebSite property $id="cib-bootstrap-options" \ dc-version="1.1.7-2.fc17-ee0730e13d124c3d58f00016c3376a1de5323cff" \ cluster-infrastructure="corosync" \ stonith-enabled="false" \ no-quorum-policy="ignore" \ last-lrm-refresh="1333446866" rsc_defaults $id="rsc-options" \ resource-stickiness="100" op_defaults $id="op-options" \ timeout="240s" ---- endif::[] After reviewing the new configuration, we again upload it and watch the cluster put it into effect. ifdef::pcs[] [source,C] ---- # pcs cluster push cib fs_cfg CIB updated # pcs status Last updated: Fri Aug 10 12:47:01 2012 Last change: Fri Aug 10 12:46:55 2012 via cibadmin on pcmk-1 Stack: corosync Current DC: pcmk-1 (1) - partition with quorum Version: 1.1.8-1.el7-60a19ed12fdb4d5c6a6b6767f52e5391e447fec0 2 Nodes configured, unknown expected votes 5 Resources configured. Online: [ pcmk-1 pcmk-2 ] Full list of resources: ClusterIP (ocf::heartbeat:IPaddr2): Started pcmk-1 WebSite (ocf::heartbeat:apache): Started pcmk-1 Master/Slave Set: WebDataClone [WebData] Masters: [ pcmk-1 ] Slaves: [ pcmk-2 ] WebFS (ocf::heartbeat:Filesystem): Started pcmk-1 ---- endif::[] ifdef::crmsh[] [source,C] ---- crm(fs) # cib commit fs INFO: commited 'fs' shadow CIB to the cluster crm(fs) # quit bye # crm_mon -1 ============ Last updated: Tue Apr 3 13:52:21 2012 Last change: Tue Apr 3 13:52:06 2012 via crm_shadow on pcmk-1 Stack: corosync Current DC: pcmk-1 (1702537408) - partition with quorum Version: 1.1.7-2.fc17-ee0730e13d124c3d58f00016c3376a1de5323cff 2 Nodes configured, unknown expected votes 5 Resources configured. ============ Online: [ pcmk-1 pcmk-2 ] ClusterIP (ocf::heartbeat:IPaddr2): Started pcmk-1 WebSite (ocf::heartbeat:apache): Started pcmk-1 Master/Slave Set: WebDataClone [WebData] Masters: [ pcmk-1 ] Slaves: [ pcmk-2 ] WebFS (ocf::heartbeat:Filesystem): Started pcmk-1 ---- endif::[] === Testing Migration === We could shut down the active node again, but another way to safely simulate recovery is to put the node into what is called "standby mode". Nodes in this state tell the cluster that they are not allowed to run resources. Any resources found active there will be moved elsewhere. This feature can be particularly useful when updating the resources' packages. Put the local node into standby mode and observe the cluster move all the resources to the other node. Note also that the node's status will change to indicate that it can no longer host resources. ifdef::pcs[] [source,C] ---- # pcs cluster standby pcmk-1 # pcs status Last updated: Fri Sep 14 12:41:12 2012 Last change: Fri Sep 14 12:41:08 2012 via crm_attribute on pcmk-1 Stack: corosync Current DC: pcmk-1 (1) - partition with quorum Version: 1.1.8-1.el7-60a19ed12fdb4d5c6a6b6767f52e5391e447fec0 2 Nodes configured, unknown expected votes 5 Resources configured. Node pcmk-1 (1): standby Online: [ pcmk-2 ] Full list of resources: ClusterIP (ocf::heartbeat:IPaddr2): Started pcmk-2 WebSite (ocf::heartbeat:apache): Started pcmk-2 Master/Slave Set: WebDataClone [WebData] Masters: [ pcmk-2 ] Stopped: [ WebData:1 ] WebFS (ocf::heartbeat:Filesystem): Started pcmk-2 ---- endif::[] ifdef::crmsh[] [source,C] ---- # crm node standby # crm_mon -1 ============ Last updated: Tue Apr 3 13:59:14 2012 Last change: Tue Apr 3 13:52:36 2012 via crm_attribute on pcmk-1 Stack: corosync Current DC: pcmk-1 (1702537408) - partition with quorum Version: 1.1.7-2.fc17-ee0730e13d124c3d58f00016c3376a1de5323cff 2 Nodes configured, unknown expected votes 5 Resources configured. ============ Node pcmk-1 (1702537408): standby Online: [ pcmk-2 ] ClusterIP (ocf::heartbeat:IPaddr2): Started pcmk-2 WebSite (ocf::heartbeat:apache): Started pcmk-2 Master/Slave Set: WebDataClone [WebData] Masters: [ pcmk-2 ] Stopped: [ WebData:1 ] WebFS (ocf::heartbeat:Filesystem): Started pcmk-2 ---- endif::[] Once we've done everything we needed to on pcmk-1 (in this case nothing, we just wanted to see the resources move), we can allow the node to be a full cluster member again. ifdef::pcs[] [source,C] ---- # pcs cluster unstandby pcmk-1 # pcs status Last updated: Fri Sep 14 12:43:02 2012 Last change: Fri Sep 14 12:42:57 2012 via crm_attribute on pcmk-1 Stack: corosync Current DC: pcmk-1 (1) - partition with quorum Version: 1.1.8-1.el7-60a19ed12fdb4d5c6a6b6767f52e5391e447fec0 2 Nodes configured, unknown expected votes 5 Resources configured. Online: [ pcmk-1 pcmk-2 ] Full list of resources: ClusterIP (ocf::heartbeat:IPaddr2): Started pcmk-2 WebSite (ocf::heartbeat:apache): Started pcmk-2 Master/Slave Set: WebDataClone [WebData] Masters: [ pcmk-2 ] Slaves: [ pcmk-1 ] WebFS (ocf::heartbeat:Filesystem): Started pcmk-2 ---- endif::[] ifdef::crmsh[] [source,C] ---- # crm node online # crm_mon -1 ============ Last updated: Tue Apr 3 14:00:06 2012 Last change: Tue Apr 3 14:00:00 2012 via crm_attribute on pcmk-1 Stack: corosync Current DC: pcmk-1 (1702537408) - partition with quorum Version: 1.1.7-2.fc17-ee0730e13d124c3d58f00016c3376a1de5323cff 2 Nodes configured, unknown expected votes 5 Resources configured. ============ Online: [ pcmk-1 pcmk-2 ] ClusterIP (ocf::heartbeat:IPaddr2): Started pcmk-2 WebSite (ocf::heartbeat:apache): Started pcmk-2 Master/Slave Set: WebDataClone [WebData] Masters: [ pcmk-2 ] Slaves: [ pcmk-1 ] WebFS (ocf::heartbeat:Filesystem): Started pcmk-2 ---- endif::[] Notice that our resource stickiness settings prevent the services from migrating back to pcmk-1. pacemaker-master/doc/Clusters_from_Scratch/en-US/Ch-Stonith.txt000066400000000000000000000264521217637305600250350ustar00rootroot00000000000000= Configure STONITH = == What Is STONITH == STONITH is an acronym for Shoot-The-Other-Node-In-The-Head and it protects your data from being corrupted by rogue nodes or concurrent access. Just because a node is unresponsive, this doesn't mean it isn't accessing your data. The only way to be 100% sure that your data is safe, is to use STONITH so we can be certain that the node is truly offline, before allowing the data to be accessed from another node. STONITH also has a role to play in the event that a clustered service cannot be stopped. In this case, the cluster uses STONITH to force the whole node offline, thereby making it safe to start the service elsewhere. == What STONITH Device Should You Use == It is crucial that the STONITH device can allow the cluster to differentiate between a node failure and a network one. The biggest mistake people make in choosing a STONITH device is to use remote power switch (such as many on-board IMPI controllers) that shares power with the node it controls. In such cases, the cluster cannot be sure if the node is really offline, or active and suffering from a network fault. Likewise, any device that relies on the machine being active (such as SSH-based "devices" used during testing) are inappropriate. == Configuring STONITH == ifdef::pcs[] . Find the correct driver: +pcs stonith list+ . Find the parameters associated with the device: +pcs stonith describe + . Create a local config to make changes to +pcs cluster cib stonith_cfg+ . Create the fencing resource using +pcs -f stonith_cfg stonith create [stonith device options]+ . Set stonith-enable to true. +pcs -f stonith_cfg property set stonith-enabled=true+ endif::[] ifdef::crmsh[] . Find the correct driver: +stonith_admin --list-installed+ . Since every device is different, the parameters needed to configure it will vary. To find out the parameters associated with the device, run: +stonith_admin --metadata --agent type+ The output should be XML formatted text containing additional parameter descriptions. We will endevor to make the output more friendly in a later version. . Enter the shell crm Create an editable copy of the existing configuration +cib new stonith+ Create a fencing resource containing a primitive resource with a class of stonith, a type of type and a parameter for each of the values returned in step 2: +configure primitive ...+ endif::[] . If the device does not know how to fence nodes based on their uname, you may also need to set the special +pcmk_host_map+ parameter. See +man stonithd+ for details. . If the device does not support the list command, you may also need to set the special +pcmk_host_list+ and/or +pcmk_host_check+ parameters. See +man stonithd+ for details. . If the device does not expect the victim to be specified with the port parameter, you may also need to set the special +pcmk_host_argument+ parameter. See +man stonithd+ for details. ifdef::crmsh[] . Upload it into the CIB from the shell: +cib commit stonith+ endif::[] ifdef::pcs[] . Commit the new configuration. +pcs cluster push cib stonith_cfg+ endif::[] . Once the stonith resource is running, you can test it by executing: +stonith_admin --reboot nodename+. Although you might want to stop the cluster on that machine first. == Example == Assuming we have an chassis containing four nodes and an IPMI device active on 10.0.0.1, then we would chose the fence_ipmilan driver in step 2 and obtain the following list of parameters .Obtaining a list of STONITH Parameters ifdef::pcs[] [source,C] ---- # pcs stonith describe fence_ipmilan Stonith options for: fence_ipmilan auth: IPMI Lan Auth type (md5, password, or none) ipaddr: IPMI Lan IP to talk to passwd: Password (if required) to control power on IPMI device passwd_script: Script to retrieve password (if required) lanplus: Use Lanplus login: Username/Login (if required) to control power on IPMI device action: Operation to perform. Valid operations: on, off, reboot, status, list, diag, monitor or metadata timeout: Timeout (sec) for IPMI operation cipher: Ciphersuite to use (same as ipmitool -C parameter) method: Method to fence (onoff or cycle) power_wait: Wait X seconds after on/off operation delay: Wait X seconds before fencing is started privlvl: Privilege level on IPMI device verbose: Verbose mode ---- endif::[] ifdef::crmsh[] [source,C] ---- # stonith_admin --metadata -a fence_ipmilan ---- [source,XML] ---- fence_ipmilan is an I/O Fencing agent which can be used with machines controlled by IPMI. This agent calls support software using ipmitool (http://ipmitool.sf.net/). To use fence_ipmilan with HP iLO 3 you have to enable lanplus option (lanplus / -P) and increase wait after operation to 4 seconds (power_wait=4 / -T 4) IPMI Lan Auth type (md5, password, or none) IPMI Lan IP to talk to Password (if required) to control power on IPMI device Script to retrieve password (if required) Use Lanplus Username/Login (if required) to control power on IPMI device Operation to perform. Valid operations: on, off, reboot, status, list, diag, monitor or metadata Timeout (sec) for IPMI operation Ciphersuite to use (same as ipmitool -C parameter) Method to fence (onoff or cycle) Wait X seconds after on/off operation Wait X seconds before fencing is started Verbose mode ---- endif::[] from which we would create a STONITH resource fragment that might look like this .Sample STONITH Resource ifdef::pcs[] ---- # pcs cluster cib stonith_cfg # pcs -f stonith_cfg stonith create impi-fencing fence_ipmilan \ pcmk_host_list="pcmk-1 pcmk-2" ipaddr=10.0.0.1 login=testuser \ passwd=acd123 op monitor interval=60s ---- [source,C] ---- # pcs -f stonith_cfg stonith impi-fencing (stonith:fence_ipmilan) Stopped ---- endif::[] ifdef::crmsh[] [source,C] ---- # crm crm(live)# cib new stonith INFO: stonith shadow CIB created crm(stonith)# configure primitive impi-fencing stonith::fence_ipmilan \ params pcmk_host_list="pcmk-1 pcmk-2" ipaddr=10.0.0.1 login=testuser passwd=abc123 \ op monitor interval="60s" ---- endif::[] And finally, since we disabled it earlier, we need to re-enable STONITH. At this point we should have the following configuration. ifdef::pcs[] [source,C] ---- # pcs -f stonith_cfg property set stonith-enabled=true # pcs -f stonith_cfg property dc-version: 1.1.8-1.el7-60a19ed12fdb4d5c6a6b6767f52e5391e447fec0 cluster-infrastructure: corosync no-quorum-policy: ignore stonith-enabled: true ---- endif::[] Now push the configuration into the cluster. ifdef::pcs[] [source,C] ---- # pcs cluster push cib stonith_cfg ---- endif::[] ifdef::crmsh[] [source,C] ---- crm(stonith)# configure property stonith-enabled="true" crm(stonith)# configure shownode pcmk-1 node pcmk-2 primitive WebData ocf:linbit:drbd \ params drbd_resource="wwwdata" \ op monitor interval="60s" primitive WebFS ocf:heartbeat:Filesystem \ params device="/dev/drbd/by-res/wwwdata" directory="/var/www/html" fstype="gfs2" primitive WebSite ocf:heartbeat:apache \ params configfile="/etc/httpd/conf/httpd.conf" \ op monitor interval="1min" primitive ClusterIP ocf:heartbeat:IPaddr2 \ params ip="192.168.122.101" cidr_netmask="32" clusterip_hash="sourceip" \ op monitor interval="30s"primitive ipmi-fencing stonith::fence_ipmilan \ params pcmk_host_list="pcmk-1 pcmk-2" ipaddr=10.0.0.1 login=testuser passwd=abc123 \ op monitor interval="60s"ms WebDataClone WebData \ meta master-max="2" master-node-max="1" clone-max="2" clone-node-max="1" notify="true" clone WebFSClone WebFS clone WebIP ClusterIP \ meta globally-unique="true" clone-max="2" clone-node-max="2" clone WebSiteClone WebSite colocation WebSite-with-WebFS inf: WebSiteClone WebFSClone colocation fs_on_drbd inf: WebFSClone WebDataClone:Master colocation website-with-ip inf: WebSiteClone WebIP order WebFS-after-WebData inf: WebDataClone:promote WebFSClone:start order WebSite-after-WebFS inf: WebFSClone WebSiteClone order apache-after-ip inf: WebIP WebSiteClone property $id="cib-bootstrap-options" \ dc-version="1.1.5-bdd89e69ba545404d02445be1f3d72e6a203ba2f" \ cluster-infrastructure="openais" \ expected-quorum-votes="2" \ stonith-enabled="true" \ no-quorum-policy="ignore" rsc_defaults $id="rsc-options" \ resource-stickiness="100" crm(stonith)# cib commit stonithINFO: commited 'stonith' shadow CIB to the cluster crm(stonith)# quit bye ---- endif::[] pacemaker-master/doc/Clusters_from_Scratch/en-US/Ch-Tools.txt000066400000000000000000000111471217637305600245000ustar00rootroot00000000000000= Pacemaker Tools = == Using Pacemaker Tools == In the dark past, configuring Pacemaker required the administrator to read and write XML. In true UNIX style, there were also a number of different commands that specialized in different aspects of querying and updating the cluster. All of that has been greatly simplified with the creation of unified command-line shells (and GUIs) that hide all the messy XML scaffolding. These shells take all the individual aspects required for managing and configuring a cluster, and packs them into one simple to use command line tool. They even allow you to queue up several changes at once and commit them atomically. There are currently two command-line shells that people use, `pcs` and `crmsh`. This edition of Clusters from Scratch is based on +{cli_name}+. Start by taking some time to familiarize yourself with what it can do. [NOTE] =========== The two shells share many concepts but the scope, layout and syntax does differ, so make sure you read the version of this guide that corresponds to the software installed on your system. =========== ifdef::pcs[] [IMPORTANT] =========== Since `pcs` has the ability to manage all aspects of the cluster (both corosync and pacemaker), it requires a specific cluster stack to be in use, (corosync 2.0 with votequorum + Pacemaker version >= 1.1.8). =========== [source,C] # pcs ..... Control and configure pacemaker and corosync. Options: -h Display usage and exit -f file Perform actions on file instead of active CIB Commands: resource Manage cluster resources cluster Configure cluster options and nodes stonith Configure fence devices property Set pacemaker properties constraint Set resource constraints status View cluster status ..... As you can see, the different aspects of cluster management are broken up into categories: resource, cluster, stonith, property, constraint, and status. To discover the functionality available in each of these categories, one can issue the command 'pcs help'. Below is an example of all the options available under the status category. [source,C] # pcs status help ..... Usage: pcs status [commands]... View current cluster and resource status Commands: status View all information about the cluster and resources status resources View current status of cluster resources status groups View currently configured groups and their resources status cluster View current cluster status status corosync View current corosync status status nodes [corosync] View current status of nodes from pacemaker, or if corosync is specified, print nodes currently configured in corosync status actions View failed actions status pcsd ... Show the current status of pcsd on the specified nodes status xml View xml version of status (output from crm_mon -r -1 -X) ..... Additionally, if you are interested in the Pacemaker version and supported cluster stack(s) available with your current Pacemaker installation, the pacemakerd --features option is available to you. [source,C] # pacemakerd --features ------------------ sys::[pacemakerd --features] ------------------ [NOTE] ====== If the SNMP and/or email options are not listed, then Pacemaker was not built to support them. This may be by the choice of your distribution or the required libraries may not have been available. Please contact whoever supplied you with the packages for more details. ====== endif::[] ifdef::crmsh[] pass:[# crm --help] The primary tool for monitoring the status of the cluster is crm_mon (also available as crm status). It can be run in a variety of modes and has a number of output options. To find out about any of the tools that come with Pacemaker, simply invoke them with the --help option or consult the included man pages. Both sets of output are created from the tool, and so will always be in sync with each other and the tool itself. Additionally, the Pacemaker version and supported cluster stack(s) are available via the --feature option to pacemakerd. [source,C] # pacemakerd --features ------------------ sys::[pacemakerd --features] ------------------ [source,C] # crm_mon --help ------------------ sys::[crm_mon --help] ------------------ [NOTE] ====== If the SNMP and/or email options are not listed, then Pacemaker was not built to support them. This may be by the choice of your distribution or the required libraries may not have been available. Please contact whoever supplied you with the packages for more details. ====== endif::[] pacemaker-master/doc/Clusters_from_Scratch/en-US/Ch-Verification.txt000066400000000000000000000173241217637305600260250ustar00rootroot00000000000000= Verify Cluster Installation = ifdef::pcs[] == Start the Cluster == Now that corosync is configured, it is time to start the cluster. The command below will start corosync and pacemaker on both nodes in the cluster. If you are issuing the start command from a different node than the one you ran the 'pcs cluster auth' command on earlier, you must authenticate on current node you are logged into before you will be allowed to start the cluster. [source,C] ---- # pcs cluster start --all pcmk-1: Starting Cluster... pcmk-2: Starting Cluster... ---- An alternative to using the 'pcs cluster startall' command is to issue either of the below commands on each node in the cluster by hand. [source,C] ---- # pcs cluster start Starting Cluster... ---- or [source,C] ---- # systemctl start corosync.service # systemctl start pacemaker.service ---- endif::[] == Verify Corosync Installation == ifdef::crmsh[] Start Corosync on the first node [source,C] ---- # systemctl start corosync.service ---- endif::[] The first thing to check is if cluster communication is happy, for that we use `corosync-cfgtool`. ifdef::crmsh[] [source,C] ---- # corosync-cfgtool -s Printing ring status. Local node ID 1702537408 RING ID 0 id = 192.168.122.101 status = ring 0 active with no faults ---- endif::[] ifdef::pcs[] [source,C] ---- # corosync-cfgtool -s Printing ring status. Local node ID 1 RING ID 0 id = 192.168.122.101 status = ring 0 active with no faults ---- endif::[] We can see here that everything appears normal with our fixed IP address, not a 127.0.0.x loopback address, listed as the +id+ and +no faults+ for the status. If you see something different, you might want to start by checking the node's network, firewall and selinux configurations. Next we check the membership and quorum APIs: ifdef::pcs[] [source,C] ---- # corosync-cmapctl | grep members runtime.totem.pg.mrp.srp.members.1.ip (str) = r(0) ip(192.168.122.101) runtime.totem.pg.mrp.srp.members.1.join_count (u32) = 1 runtime.totem.pg.mrp.srp.members.1.status (str) = joined runtime.totem.pg.mrp.srp.members.2.ip (str) = r(0) ip(192.168.122.102) runtime.totem.pg.mrp.srp.members.2.join_count (u32) = 1 runtime.totem.pg.mrp.srp.members.2.status (str) = joined # pcs status corosync Membership information -------------------------- Nodeid Votes Name 1 1 pcmk-1 2 1 pcmk-2 ---- You should see both nodes have joined the cluster. endif::[] ifdef::crmsh[] [source,C] ---- # corosync-cmapctl | grep members runtime.totem.pg.mrp.srp.members.1702537408.ip (str) = r(0) ip(192.168.122.101) runtime.totem.pg.mrp.srp.members.1702537408.join_count (u32) = 1 runtime.totem.pg.mrp.srp.members.1702537408.status (str) = joined # corosync-quorumtool -l Membership information -------------------------- Nodeid Votes Name 1702537408 1 pcmk-1 ---- The node see's itself in both locations which is a good sign. If the node list is empty when you call `corosync-quorumtool`, then you've not correctly quorum in 'corosync.conf'. With everything looking healthy, we start Corosync on the second node and run the same communications check. [source,C] ---- # ssh pcmk-2 -- systemctl start corosync.service # ssh pcmk-2 -- corosync-cfgtool -s Printing ring status. Local node ID 1719314624 RING ID 0 id = 192.168.122.102 status = ring 0 active with no faults ---- Everything appears to look ok from +pcmk-2+, time to re-run the membership and quorum checks to see if it shows up there too. Again, if you see something different to the above, check for the usual suspects: network, firewall and selinux. [source,C] ---- # corosync-cmapctl | grep members runtime.totem.pg.mrp.srp.members.1702537408.ip (str) = r(0) ip(192.168.122.101) runtime.totem.pg.mrp.srp.members.1702537408.join_count (u32) = 1 runtime.totem.pg.mrp.srp.members.1702537408.status (str) = joined runtime.totem.pg.mrp.srp.members.1719314624.ip (str) = r(0) ip(192.168.122.102) runtime.totem.pg.mrp.srp.members.1719314624.join_count (u32) = 1 runtime.totem.pg.mrp.srp.members.1719314624.status (str) = joined # corosync-quorumtool -l Membership information -------------------------- Nodeid Votes Name 1702537408 1 pcmk-1 1719314624 1 pcmk-2 ---- endif::[] All good! == Verify Pacemaker Installation == ifdef::pcs[] Now that we have confirmed that Corosync is functional we can check the rest of the stack. Pacemaker has already been started, so verify the necessary processes are running. [source,C] ---- # ps axf PID TTY STAT TIME COMMAND 2 ? S 0:00 [kthreadd] ...lots of processes... 28019 ? Ssl 0:03 /usr/sbin/corosync 28047 ? Ss 0:00 /usr/sbin/pacemakerd -f 28048 ? Ss 0:00 \_ /usr/libexec/pacemaker/cib 28049 ? Ss 0:00 \_ /usr/libexec/pacemaker/stonithd 28050 ? Ss 0:00 \_ /usr/lib64/heartbeat/lrmd 28051 ? Ss 0:00 \_ /usr/libexec/pacemaker/attrd 28052 ? Ss 0:00 \_ /usr/libexec/pacemaker/pengine 28053 ? Ss 0:00 \_ /usr/libexec/pacemaker/crmd ---- If that looks ok, check the pcs status output. [source,C] ---- # pcs status Last updated: Fri Sep 14 09:52:25 2012 Last change: Fri Sep 14 09:51:55 2012 via crmd on pcmk-2 Stack: corosync Current DC: pcmk-2 (2) - partition with quorum Version: 1.1.8-1.el7-60a19ed12fdb4d5c6a6b6767f52e5391e447fec0 2 Nodes configured, unknown expected votes 0 Resources configured. Online: [ pcmk-1 pcmk-2 ] Full list of resources: ---- Next, check for any ERRORs during startup - there shouldn't be any. [source,C] ---- # grep -i error /var/log/messages ---- Repeat these checks on the other node. The results should be the same. endif::[] ifdef::crmsh[] Now that we have confirmed that Corosync is functional we can check the rest of the stack. Start Pacemaker and check the necessary processes have been started. [source,C] ---- # systemctl start pacemaker.service # ps axf PID TTY STAT TIME COMMAND 2 ? S 0:00 [kthreadd] ...lots of processes... 28019 ? Ssl 0:03 /usr/sbin/corosync 28047 ? Ss 0:00 /usr/sbin/pacemakerd -f 28048 ? Ss 0:00 \_ /usr/libexec/pacemaker/cib 28049 ? Ss 0:00 \_ /usr/libexec/pacemaker/stonithd 28050 ? Ss 0:00 \_ /usr/lib64/heartbeat/lrmd 28051 ? Ss 0:00 \_ /usr/libexec/pacemaker/attrd 28052 ? Ss 0:00 \_ /usr/libexec/pacemaker/pengine 28053 ? Ss 0:00 \_ /usr/libexec/pacemaker/crmd ---- If that looks ok, check the logs and crm_mon. [source,C] ---- # grep pacemakerd /var/log/messages | grep -e get_cluster_type -e read_config Apr 3 09:19:32 pcmk-1 pacemakerd[28047]: info: get_cluster_type: Detected an active 'corosync' cluster Apr 3 09:19:32 pcmk-1 pacemakerd[28047]: info: read_config: Reading configure for stack: corosync # crm_mon -1 ============ Last updated: Tue Apr 3 09:21:37 2012 Last change: Tue Apr 3 09:19:54 2012 via crmd on pcmk-1 Stack: corosync Current DC: pcmk-1 (1702537408) - partition with quorum Version: 1.1.7-2.fc17-ee0730e13d124c3d58f00016c3376a1de5323cff 1 Nodes configured, unknown expected votes 0 Resources configured. ============ Online: [ pcmk-1 ] ---- Next, check for any ERRORs during startup - there shouldn't be any. [source,C] ---- # grep -i error /var/log/messages ---- Repeat on the other node and display the cluster's status. [source,C] ---- # ssh pcmk-2 -- systemctl start pacemaker.service # crm_mon -1 ============ Last updated: Tue Apr 3 09:26:23 2012 Last change: Tue Apr 3 09:26:21 2012 via crmd on pcmk-1 Stack: corosync Current DC: pcmk-1 (1702537408) - partition with quorum Version: 1.1.7-2.fc17-ee0730e13d124c3d58f00016c3376a1de5323cff 2 Nodes configured, unknown expected votes 0 Resources configured. ============ Online: [ pcmk-1 pcmk-2 ] ---- endif::[] pacemaker-master/doc/Clusters_from_Scratch/en-US/Clusters_from_Scratch.ent000066400000000000000000000002671217637305600273160ustar00rootroot00000000000000 pacemaker-master/doc/Clusters_from_Scratch/en-US/Clusters_from_Scratch.xml000066400000000000000000000027571217637305600273360ustar00rootroot00000000000000 %BOOK_ENTITIES; ]> pacemaker-master/doc/Clusters_from_Scratch/en-US/Preface.xml000066400000000000000000000012501217637305600243700ustar00rootroot00000000000000 %BOOK_ENTITIES; ]> Preface pacemaker-master/doc/Clusters_from_Scratch/en-US/Revision_History.xml000066400000000000000000000050451217637305600263500ustar00rootroot00000000000000 %BOOK_ENTITIES; ]> Revision History 1-0 Mon May 17 2010 AndrewBeekhofandrew@beekhof.net Import from Pages.app 2-0 Wed Sep 22 2010 RaoulScarazzinirasca@miamammausalinux.org Italian translation 3-0 Wed Feb 9 2011 AndrewBeekhofandrew@beekhof.net Updated for Fedora 13 4-0 Wed Oct 5 2011 AndrewBeekhofandrew@beekhof.net Update the GFS2 section to use CMAN 5-0 Fri Feb 10 2012 AndrewBeekhofandrew@beekhof.net Generate docbook content from asciidoc sources 6-0 Tues July 3 2012 AndrewBeekhofandrew@beekhof.net Updated for Fedora 17 7-0 Fri Sept 14 2012 DavidVosseldvossel@redhat.com Updated for pcs pacemaker-master/doc/Clusters_from_Scratch/en-US/images/000077500000000000000000000000001217637305600235505ustar00rootroot00000000000000pacemaker-master/doc/Clusters_from_Scratch/en-US/images/Console.png000066400000000000000000000235111217637305600256620ustar00rootroot00000000000000PNG  IHDRz' iCCPICC ProfileHPSǿ{-! kATBB(! \ ""`CW@\ĂmPĂ.Ȣ*ޛ杙37g}3 %2 Ea8n phYB@.fMfᅥ, E8NG4l(5R^-i"d@g֡8l'":dKhF l.Y6NOϘa!7D&œ^fV#=M<3e9 gaG<_h*6A;Бh6:]C/oG Fcq011f%S9i\ `0X,ac)-ؽ&l';p8#3.ep{ppq1'< |ߏ"tpAE#LezDgb1XAl$^&ߑH$Mi O'UNFHrdC'9,&o%ג;(.ōGɦlS.RS>IQLRRUR-RR :˥˥OIߒ~%CѕaɬiZȆȦn=*{MNNW[#W(wH(EբzRԍ1GcRh%ڄ|||Ya:Kg'w_.r_]yQE M  _ފ;[) (TڧtY2MI\|R bZMIU5U_UՋjnj)jejթ.|2/ wFq1!8ѣ1Y٤HeUե5FAA^'YgNG]=hMzyz zC}WL;X{Taa-#ֈoרc`,014!4MM L[M_iř06nncf~EE[KCKe+z67F\}l6A6llيlmi[:`<;qhx/'TN-.>xYә|y؅reUÕZMˍv홻{1"fk=;P^^^=rޑޕޏ}4}x> >6};0~~;L69oR9 <2Ia(#4,n !̐!BB3C]]j05aG?DxDlx)슒]=c6FR,?-w$nr]Km.[riϮ^Zq*p4++UÚLd&V'N=ٻ/9n28י[}TOvM.O~WߤOZ:֔OOHo R22r3F"pc QH,-b}O+Vʕ\ejgy>y?FfZfÚk%ZpXo~ P0pDE6#ǞVl^)^b^R^u {,~izk֞mmnluG]li^Π-eVVn]7qxpE`E=|LjV\q/go>}UrA߃-55凰r==ug()9VP;\Vwޮm paX^M6ћJN/~Iɀ]O59]Lm.nZVL&Ŷwu8u4jk3Ugn;Gac'Ou?wljW׊o:|NDY+BNJm-X;@Ys>x6lu 2@ģCRa2kn?#+rN89̧w:&;=02}:3L`?3)Yh pHYs  _IDATxm.PF1=D(x}HJ]60O"i~&Hn#L&L&L&L&L&L&L&L&L&L&L&L&L&L&L&L&L&L&L&L&L&L&L&L&L&L&L&L&L&L&L&L&L&L&L&L&L&L&L&L&L&L&L&L&L&L&L&L&L&L&L&L&L&L&L&L&L&L&L&L&L&L&L&L&L&L&L&L&L&L&L&L&L&L&L&L&L&L&L&L&L&L&L&L&L&L&L&L&L&L&L&L Y}x.)cmݟiҫ4?Z{R+ޖ2-S =ӑup}LfEx<||އ #Þm韞F{egW9zmW9gc֌E|1˅m.. ]}MFB6,):Lq\mX^me[早kmȐH9zjmnLMᘽRYY^|=B;)X>qem]#ZG\E_kL=UWͥ5ZOzmӌyvٳD+~tgmx7zcc#!{ X/(1m^!{먺/jwxd֫G_M#wf\ fr33^m<:g^'Ln]aށ8k˶ڳ]ޱMgGcGbK<^#]W{ x)?8oFa/a&>9 Z30Rhtpmi@9>sf,&X[62V9-iuϔhu'Wf&9:MvZˬN:3B#<޳F0 @a yw(;4?oD0>arpGR({b<҈/~34a L&H/$i$a\%L"P$Ls&zϛ|=Cryqɳy$kw7k14a4a4a4a4G<j;Y{$Ȟ>(WȾMK|>Ow"uLQYu{ڲu,sk޽OycߥƙLpgrPwB`֫-G+:z2ޞx,_y?a2ͭ}/j<"dGJ}Tݬ(ۺm.ql-;r=(vwZ+2+qެ_xF2O9y>0y-D/jrA~EZdG33ںr=ZϽgjKq::N܅ xel9e"ֆږ5|)kmٳ̴ֶ)-JE'ש-ݟ#dڵ֭Dy&˥vl- LFjst뼺w>SZ~LTo4( 0(uO`?`t€\DfHxܙyg:a4\H&H&H&H&H&H&H&H&H&H&H&H&H&H&H&H&H&H|>iwxeguO̓G+ʹz|>7<0כ[V:*Y~ir)8;6YĖwjw^w6k?ܖ^sgz%\0/[3 k @0!"-dz&}iyw#ȩk3Ffi].7uZy[uf$=I s M M M M ϻop_1)cOY)rz?:y>Ge}ԾSr6kyϞvdʹʹp4Mʩ[jW`b)rz?=E_Fk˲]L;?/,9M̶ Ѓ00z](*trЫ^$G;ھQ*>Us֝Ҳt|u(0upoe柫 9,s[=g]κ6ӵaK]k}OߦzJ,|i~~\D^{ֿkEދ7 tt9jedWYg[=Huhwdz=rV]ـp~vԺ}6w2#pg¢9 /mR^Y#/2eז= \Kg#֥6.KƙiKw&6H(}fx|Q|$)էmjwk~ ߜ#٦ x7Џ {Mxa&ÜXW)=CeyH{|~m٣go{m]1xq:M-L3^zLlku͗RY{'hmOk˞-m?bbo\ߵ-֖ۻщ`m>xo/^&y}vOߦZ-[D2@.O|L4q1EAئ?LzSQ!w$Lf6W҄I҄I҄I҄I҄I҄I҄I҄I҄I҄I҄I҄I҄I҄I҄I҄I҄IG2wD"QWs6=۫5?/n퇽o=Ymy1;鲿KE3χu K˞ٮz!?=/ЫrF&X!rg.>]Y>י͕Sx\3ҹko;|ar0/D[1.}6vZYwjuϼ/+-zx1#zUZ\F"lӵ6GȰZy2R-{zz=N[rl|MFKqkԬ]G]-ms"6DCt"bk-mn-ߞ0Lm6Gˉ[e8Qz:߳{-m/w&oEZp\yڪv ]]0r{4ko[ WtzEvs3Gd/btC=;emt6D8Jui}; '3+4]q 3? #y<ΛQn!LDO83CVBhږӈ̖}gSp> ec&w`7u. xm^.\gk[jmOT힙 d6 Tjm.&;m#^}VgsxKkiTm9Xw2;]_8s0WnP'8;5,G{$$i&L >?[|r=F#T)~|O?o1pić s M HI80 @0ɭ-gs&=&HI{=kM!˸|<_O5Mϻ @0 @0 @0 @0 @G c6!8韭eJ/9&ww;rqj_stjG^6_֝ܙ"Ҳg='HdvN㱏\ڥy(|7َ\g$ LxLP!!k[C柫 YlLmHDۭm{jmp={ɶm^ãi=',g?!\4M?n\e~ 뭺a`LY 6Eֽ%,(mzLmiQ"{,f 9\Z k$}\;_N| {b{N,3ocѻ׷wkξ|Eev̳eǙ ֹ39y8x7LҞ H}ܙ+:U[&k?ꐿh]e[*232=e嬭Gt{9*zlmmUNuET1$._E/;*Zo)g:eVykuda+ԫזϼ5De=:Ec$;۹(6,ڶW ֦VgԕH5w]+]Gd}٦۽ ז˖Mgյ&s8^Of6/6}v?cحk.a& #xuu_ݝֻwͽx12π"3mN2ZW$/vmu=ٻ^Y=^ٞku5RWrZ'lIzceKz-|6aa}1b0 pg8B=pW$i&L _G{^um=b$=2c?ؿΚ~-z|eq]Lf ^_/-{fzH!Ҟ | pUk{g;r90 @ay<=o![C柫 lLm"UkKmi,Sa[~ի},2&kCC\6T2H_n^k=`K]\nmv:J,+*jZ}_3`YAw39e7'֩7ɡם,ڶ]hGcѶD[F>09R8Ijѻ͑պM[wml{tV]k2g{6̕" f_d{c1k̵f|a& ,:De/_];]G3π"qNղDe̞;#D'kٞku5RWrZ'lIzc_5;ww%zֺӟ0- c @0&24w&H&H&H&H&H&H&H&H&H&H&H&H&H\x:w&HݍZܙ M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M E{RIENDB`pacemaker-master/doc/Clusters_from_Scratch/en-US/images/Network.png000066400000000000000000001575211217637305600257220ustar00rootroot00000000000000PNG  IHDR5؂ZsBITOtEXtGenerator Version0.9.1*g0tEXtDomain UUID3090075f-7f78-9e48-658a-29766804a121%tEXtHypervisor URIqemu:///systemDvtEXtGenerator Appvirt-managertEXtDomain Namef17-demoD IDATxw|gvr:E(4+ * ("" ]DPltPBIH!.׶Gm^nwvKN!ׯ\󜜜O?sީSKv,pq®ʢ v8p6q:>sڎι(IIIv/1&1ƉĩEQs @ '"I :|*??//1v4J68IA9眕9t-[®29jtpcws$1߷nC1ƜN?H1qk9.ǿu6UUsrr$ OIL"w>|bHa1ɤk$g)1XUՠ 0'q3<nvg>|800Pe]M&Srr,ˆ\1n6f늢#np!@P䝈عl6+bFVRSSE10 8 *gtѩ8IL$IeƘ^A]e *>v{QP!$uˉXq# @4۴i뺮0nߔqtS^lb'dL*9[8Xbb!\(O7oC^uT<`]s @"1kʲ( %%%r9 __"mQJ\EScĈs.d9$I$ιtC/180?_r^ю/iRK:/1"b%AP'cL򨪯Oddfg J c]}118w_L$zjɿ%:DD#CvL%+H I7C# _=7c0I"QqÛpKP=.`%]Y,Kd2)9gĈ1w뽍pos]$bLbRaAL)IL~nq-Kdd;y<}|j#F$m۶*" ءf1&%- bvcvAAP``TttMIX_D/)).r"ڻw_zZZͦiھ Itoq)?444>>m6۽8T :ADl6~ EG N?L&X```DDl6˲i$ILw1޽{wlo"g9;w*"֕TPXbaa fs믿>|JNij```ppppp߻ve("juaÆZ&%Ik׮۷L&,rdYp\߯]{*$I$1PExP')nn80##s^\\|1>NHH4-11uM׈;u] "z%av4M{$%%fdNӹY oӦjU%777---++ff:=΀q!7o 8m۶R%///--ѣe_Exd6&I,j97L񡡡.ۓwA͚5kԨju:;wt:o֭ۮGm`2HjFI{zJJ effE.5st|=yEscqEUtk ɤ{y%9D^"wJD91b1`u00_:NiZhhhjjs$Ɖ|87#_~]nhڽ{O?T4EQs֯1***<`bPQp9]X% 0(KN0tb  ]==S'cE .76˥zܡabPuNr9-b2 + 5 ߐ,$5?&DT4Y,fvyn*i4%1Tb eYeYuMtMuգ`{"$+"+躮i(;A,Ur$Y6̲Ȳ,IL MTգ/PFg@@lv\rJu= &I&IQLbOi"2LK.SiXo/ڱQD?%oJNP!8eI~kU~>-֌b;cG%T~ _7K-oKG#H$z @=AP G#H$z @=AP G#H$8QѵB87Sh@Rj;ѽzܳҹgbU)SwT[gٍp^y9y9r9'N|ÁKk87@M֯/0^⋛6kClOOO6|x-R72tX^)}Æ W]իaBb޲+g^:^0!SQ,^|qN z~/E~*ZնFE.7_rџi/̘ѾC&M`x4UZIO.=WZjݬyǟ;)uQ}֨__.}TtL r?p_6n\٪-T3w={vsM{Nl}C~盷lR֭[i{񕟈_ʕ+r̓n˯i_۷qxjٕGS5?_mժ϶n| qΜ9{[u?sέօя?u?o)--m޼ +J>6}ܜJ*G~bU@BS?;3zgee=3Dooڭ6k֌rrrm[KUbٺDھãF/!!W*X;&&Ng-;ZɉQѻ+'&%{xOӯ(_r%v~o֭[o_޲eK"ڳgC6ob޴q޽{kRW9XoۚTTXU>|a z}΍3 ZGIԣGSI}QQQW]yEYKHLr\>ID۷o2ٿdY>ED;w5~-""]I%")![щ**_9u8jC@5 2Cfa ƍMdQΘ1_'OObb+V$'C|#xazJJJZZszM"*v8BCC;6e_#?~\ƍH+NgܿUM-F+/6@]].gurͦ.]vXݻDP bOg IDAT,3)IY21Ɖ'9'.og;#GH4d谌#G6kĉb/?w3"66vC}ŗb{ vі-Z,ZzTEE'3f̵VXZhjq9ljھc0]}iVj(-ڹ,_yuᄉkMhhӉYΖ.BPGq׭!j+ C40 ] Cu]TMS;]yӦ_֭w>G26eIӯ%nSTSK p-$uԟ[HLNriWƘ,+\O7o-tK}LbLb@%Y<.,vuC9+CPG{?ĉck0+{e";<.9Y,&]7t4sWԜLCPGً&Ŕ}ӥ*`ssNb5<:׉;Ts$)"t] t"@)g|ss @( c,L&)1%NQ* [E͝7/-= ?qx!J*)s& ꫯ9tu~([Y75^;Nι꿷Fl߾wرɓII8tY8l@u?"Ͷh~mVVVRRҠA2-!={0 X?uƌYnUz,3)IER$1]s^M賯V/͞CDF=4O>7lؐf0}!"P%+++7''11yU熟~]Sty7yI~~%Qf{-{oiFDSo% +>^|Y||ec%\^GGG;eI$v70СCi=ov1󄄄;Z\\g2Uڋ(Tasw޽;::SN״iӶl2MpAP)I?ĉe2]SKuY'N]L$&Iy32hQ``3RRR&MtfΚ}z۷o2ٿdYQÏ=ڥk7!.s"3?~J*)AzbѢEvzi9߶uKpH:q!v[x]vK ڴi C3<?s ޽o߾-X,9wof͚{(VچNS)R oFO>QUIdIE4k.S`IXX$IRdIbLy["0jUw-[Nj-]9~ڇG޳o[U1bc_aaaEEE͚VHXT }wV%T Pt:KmWofZZs^;'j޼Eƍ׬K;D7..&MzrذaDԼy={߻s??-22RTwk.\o>1(III7o1cƈ#ڷOϨg͚o>Ӄ&]mvŊ?㏜5C/7yOv{q'O~q"=ڴisu}ݷ{cumʔ)B-rO* ~;v0L]v}gCBB諯&3f(bƍ7|/y i&5jдeR_&0F3dgg]}d47ԙkJw]`%$ɣz#>Zݐ>|#߿޽gȑ'=tfffff擓wPŗ=׼y k ƯG=u*Ȑ!v[C$I E;xرcǎڵl%嗌;w ]v+*޿QFegg4k)uSOM馛֯_?hР=zΛ7///Oz7mtw ^5kkko:a„N:Qh>LD_#8qB.anA„DT\\,˲UUG$>!t%99y߾} D]MD7-pAP)ҨQ? KOOMblb>esK8cD9tNnpĉ$IX$ຮkNrp'ʎOMJLUC 4(5ݥ\zUw>S лW;7n >vQe̘1ÆyxYf_ԺujjND٠m۶4M zOMFѽGwyر'TVTU>aC~ڵk^}5͚5߱cGQQѭڧOGq L p^@P)Z^cIƢxr{e-ÃIIq݌bR,&y[xjkDWnԨѴiӜNM&Ӳe?J=cS>}#G^իWE%̷ LSo3Y[rС۷o?zXbbbjjرc[jU\l%{铘xر6 Cu" |j^{'Oߚ?M6}fMDDDF,._iUTU?"VVŋYd՟'N.r4U o~oݶmϞ=rKxXXQIBDNJmP~sQ> ,UTUQٷs ^APܤܤ3Ifo fY DѡzTmvӧX$I=zts>ް?Ξ ^?~|ƍfyĈWWnٲeDt]wyT_u]0Zˈ1XWee !ޅl8cs"#FK{tWoVhhl6}L}߈sYG,9׮].gϞ&LhݺZrǏ+tRl€.4-8(XU=I!W\yND1U((4|sN&J(=zmQVkn^^tttNNNRrE=e[nǎ@֨ٳgv͛;uDdܹ-_VTd߿ߋ3fn|{^n%\l{Z"?o'{u͛t{x O\1rI qHfM8Ql3f̵OMo"ozgz%J7n)z!o0G+9]\\pM?^s:}%K:-Y!Cj; PS0 (@=AP G0 a2sUMXzL)6&6)!qd˰cHys_ODv,uYk;yPPH/MӬVk`` cX#<9X,@HN B|C*Ÿ ihOcdPQ 0@CUuU~8.Åz]/ [2}k;w:]&))w zV0Z~J5M۷eM\|q~eM?0k쌜xs_2F7p#A绲P:c?~xxxu?DD{6DtU~<<+O7kt1SR*n?=uЃD~m1oPɽ㯢2ǎwtƏ.ʏGKh<srr5kĸG*.NϥcOl6իO^Dtãoƫ{ŲNW,[{W,srs&w%-n޼SHiTzvr*{F"ZK/?߼y'ID?rDBÆDt.pU *9w:㷜]k;%!9-[ 2>EBDgZGn2ö+?3W̮dVm߱s!!=xH"`;_ [|9"喙2Q?UU}%o.~w1o9筑+WڧΜ>-AVϝY/Vr]q3 IDAT:L9{-[haX|ۇ;̛=3A>Y9 +^U=#9"$p`z_ÄDL\ʊWXdEEE[u?;%:*F?SpdD4薛rͷӦ<GD;cDC5kU_ez}xa6G 6l;&22nƷ;nq-7ݸt_UgB'OÏf}HFFTTԕ_v!!!!]tx+p}sر~1Y-(,5^ӧz̨{Q]O=j%;nuoM|1kdxx{eomVRUO'ۗ._u:!!!uhhS8w*٢?~;wV۱7BCsssǗݕ_=!!!''ǷKbx<ʷg<9ӷ}YNNnBBB+̾vZzfD_uUWCHH#=C<7mC^}}5}z!wOtw,ykaaaƎ޵kj3nsI|{}韨-jue[6TUpU:ժ888' -VM D?nn++***33Qr2?~<::ߝ"6&fiqGGG?~T5r>5)$8^\JTt]51֤qGG?|ͷ-護^[h_yrتeӟoUTc?gxXUTUMRR޳Gd)-;`.HgS-ߵUYNnٻo禉] srssrs_y}a+wp͞򑌣?9薛7FJF '+_5r[֞}5q$=dY-{@ ukw֪(DĽQ=ʼn"u?V >s{w}Ihii;:8j$үO۪Ut|ڔ3p81woBx3o~1#3üٳr(+5{)gBG=r4+٧܏7 ­[6-]CE} js}Wҕ|X2^F,o޼[nZZl~w%oP#(ꩍ7&$uZ/^/[,9ݹgbbcȗ>~tZӧ&8`+3f|'k~[#i%Ǔ&x{0ǎM|3k߹3;Ny$󿧬T͛7/_uV:};vW^ {ѣNzC=|РA}tW^2eڵk[pEN8G\jHOO {nxx{2zBg@mP5%X|yg:u|͛B^z5u_L#BH~aCIVVV.ۤi4'9r8={={O⹵5qwM4!|q`'l`ٛ5kFy޽Kٳ={Z?/&M?i&))noٲe޽:tPΗd􂒏2dw޽nnn~>|n|Ƀf:DZmZ&7+}^?ɬ̬,//quurN7oӣK׫WL(Bx<=ɓcƺ5i5;;[xjjjnF-Z}NNN􄳳sVVֿx+eEٵkѿOL^ݻΝ;ի׵km֧O::dddTu-Pg^'H@]p܄ V6@7S66)))wvJQԕW.Z R{f\"dcc&MU)%c;VqSW޿ovvv-;>>>&&&ͣ#(Nb\.]Hm۶ݳgEQ׮][|ǏICkߠnfdf|UUkiiikc+ U @}=~ܶu !~=Ϛ5{ŊjKvy>VH 5-mUMiK.o&m { T9W޸q#=1vO?mذ400ڞ8qbܸqBp…UZV2\Gqڵ۹s9srssWZ%ϟ?ɒ%CronnشiSʕ+׬Y윔y;vT)I3BÈEQBGP1ԊW^9` !dQ˗-C 󟖚ڼYG.^xa·lO?Ϙ`mmgϞRJf0L?i޿wkWcz%Fh":8|.]RRtjtkmm+,YRd8=Qϕ+Wnݺrt+ --iӦ۶m_ȑ# ̘1d|oB8 g /(&`!K70&`MAHKKK$i r(0 ++Tm.]EE]IxOe'P-,mFFϝDΨ~o@Z$5kѦM[ךdmݺU)&BWZSu/ (4 k[}!#E,}nιe}auƆ*IR}P˫7Ob{nZZZ2D"Qzn }842`NRAWRSCB>xݫ6sWDus,.@@ikIΧ̶;Y4dyvj!WrW[.! -]WOzFƒL`l3SӤwaǎz<}֣KJ.DNՕ zUO| ~Gx[h?|>מ׮ x;{ zu.]y4q[dX,>v¥%Žw_`>&DC#\-.):q7=Si<*;tXd )sX+G#~dogľ>~ؤ۷˗5vtk$Svl+V>ܳ__cvNK200PP. PSO=sw\tutXl--5gq]NG` =' 1nHA?q%2My!蟭AlMJN>vT2Ql즿םq6'O=qݟBB"cO=|%_/_,w ~3rh;d*ە͹~&"|g~;v:"Gn_ܵ+HU~L!XLQ8:lmX,զbXz66cFo]Wd.;_*'LvlgB¢YQעΟkiaaiahYK-f}$&*xi66FFfܼ}_\`Ⴙs*;ok``0}G1.RYd3]d-eBB^UΝl=bEzFƣXѣ5!@5ߩsg%v*q"ޝұyP˗٢ҫ7,bѻmٖ277KǏYffY~3gIHnZ1޾:11(xۤ$HJR9撴mEU^U&7dԔrtuY,VV jBIO2E%%,ٸ2trxrgYXXdff閖K}8.㖖2 ~֬sȠACF]<:"\2BFWGY^W5ykp['zt몣{oȋ@P/::::::ZuHyVRZRt?ArwL:SN^^7zg[17w뎝nШn~!U KNut|lpDMLLH-.f7l,7khq%骆#o.wuR2qBر&* bS2집>v|)m],>ŮL?vvoå..}ѳNsw !2ibR3r߯kf>\.wɊox&I^m+-627}:l7m>t$lqw?(nKܭIL-{;;A'Ƚ()cōѳg5ܾ}ϜO::vڄ'I9D(fd 3#EzUx;?U'BC: F sI/("h_<0 C}#K3+P4:bK\@s_D"]ٛP)D2`W6֫O:P" EQG@S{BhAAPhAAPhAAPhVu}'/%'+Vu.sHk=t@G{#ݕgYXMƾ{yz5Ru.j C脂68/U'o ʼn333s!:vvήI)I$%ukN\@չg:>Oű/_s>[Wk&'@.jnls!<鋧cY,V=IIxsw72g00]&VO·lTE}lo<,]0JKKY,sz @MYZYZ 8FF:12¢Bc#c)Q.[=UgQ5{&_< 8V,+U'nPzdhEEEJ+ڛ3ԟG޵׹~^_I S{)X[=YPP0g{uttȯk|`ꌀ]۶\:sgL.^T\dea%̬{xIiӺ܀66t?{C_`aCL:`Bb"Nz򕡑G' 3dhzҙSOIWWm֣F Ю]{2rt, b}]y :s6=AGwe颅&&;ϟMn{tĩޣG=x`@--63tO[zN!;vxώ9^Nj[n!Bcގ{྽7U>(x1~U[6yC lުd[S܆l۴ص[AU6г{6.ɓm+$ah`X)TuPP|>_$l<==FG/_/^%#zzR5dh:2dL>s1EDGfLq.K7v4eߴc'NBdV8%ޥ=]J uo$k++k++ɓ"YݝfϜsy=M%[|5J[i66ZZZƽ{5,y{@(:7sO=nU:N2r4q?\yKlvNDŒ'ϡQe 7˖𰠰pᅅ((,<|INyI'_wtp133VzX,7b琡~} s^ DE<5|w~gIzN >2!I11sXSgKء'OC2anf6o֬ظDž?HҸÙ8|d}[ZX||Yٞ|x/`HqKV~7oپ ?~Bq|%Fz urdT)b"{|(`}WΉo !/;vx!S^^J9=yN >{kHPP$&XDzFƎl\(6J+JJJ#NNߧ6oڔn֤.Y&n :6oVըk!ܼ}gɴi߶m_zUH8v/}r?}0 Jx$zbGb1=#wkgn`;!DfBd@~'ϜO>3d cy۶,̂Ϟ|Ya?ٵ}cDŽ"= #BH;(wltgk׭{Cgee=xо Fo3_r9xg/^vva/\}?}9?ҴߴU e>ʈ}x=ߣS;G[r IDATc?ܺe['OJ۸i8#^{›7АS|(@aaA(b2}zy^M0pZt=L̙93g/F^?gi~wݣ׮ߘ0̬Y")Q5'`h}&M~}n@x䌻ۤ]{.?OAhii}r{M5nҔ쓜zDE͟=@֌eK߫yh;v`7nݦ(*=##6ȯI)٘U>soԵ!dx߈'E"!D$E}mmmvR\Rlff {1c'Nnؼ_VBlvqq1!HO=6ovv :afjٯLM6ן:qԉ(JMK8yꯍ= Gz3aO}zpp/_%,],_UMsrnߡ +qjZ#0}ik#ׂbޭkQqшz-7qJ#ݿ[vzZ"(#3s뎝ڷgf)Baһ^EMMMSKz(/Uǡ^7nޚ)7ӆ[$*9%E$1 Sް13,(:vh_\RrE=;9x}A{vTvj|d~2+Էwмyyww S^ ܺfJyBḱ+C?mSY~{ ߦukڶi UiC_99vS&NkoKƎ8>^zʤtA{͞Kiբ҅ C^l!dAx!!s7ءzzl'܉v 6u˖Eu9#3k{Ю_/Nf︳.n/囙ytr_dݧ==zǟy ;V{ά;vG7157f̃G1O3zw;A geۘ)zP}%M0m XfϜv,֕J-,,z/Y0a9t|)gp8t]!B3O[1p㽽{y>}V|CffW+̨TNty?Qÿ'h/?(i0гvNμKbGNӧ]_!~//q>[XKKkСOn]纜+440qL TPOUԩ:Vc}*}{RԒzu}{ۻL{[M+죆$mҲo=尸^$&gfi\;I/)=;WmFFFNN ,YXV* W;N~lOqIqJőQr>ѽ+425VIbafS|MSKNn_}cF }ݻvIP.]aaeu棸ֺ OBȨq,-駔/-15R 5bkk;uLPЯwsfWuqS##~iRwVVV˾N t2eK.noUCPn[\^De@ fR2ODm&O?Yˉ+ͤ|WF :bPǪJ%bO& 5NG_OQg,֪nI}KIqy\c#F\^9 F@9p^+**240Wڋ[JoF*166rF5tJ LF4 "ZYY9n o=LIyR({{S޿Su"ZVN֋΢N ;*L&~e@FXDSP@ (4 @ (4 @ (4"$KU .yL&Z( S o ƀ~o9TH$zu[:ԩ}BT &٬I[()@`0D" Y,Wu"  kE?Tb( Ps*(4W{ (X\֞݊,@EQ CY4(!@61M_LB~{tuuq9qEQcOx| O+0}y95nKzfzIEQ +J@-7oۻ71M=jSHV7+/&rE<jiԽ$C'(w;tu %J;~bQ]z:cۤ$:m5k %OkπA^C8(t2qIHx ɗQCii61?&??z ~^G.X]r$.ݿ䣼~$+Zzķodo:?5-"@Pԅk2հÁ<}J/пd#a1q;?yR B@zq5Wkٗ.ȁ#B߼}{CD#Bo߽[Bz螟K?-,M/=dxة0k+}cx̩]nG~xաdr7ܸr̲T!@ud鏁k:%$t NdW?uzuvvKM6}ŒwZ4jD2yϾP:x⥭!߭Xd7&xiVt{$I?`($& ??4~e>dW@ L&s4ْ~-^ddh(ǍsI\fEuʺwϾܸy:EQnnM޺sһg_++벿D(ȯص7o7[zVFf(_G@}Oa٥ǏiGGǜz:''G:^ϣ(j`~{^~]rWQ_NB>mRRQQ1]~ #&%qUN4 WW7n߽y΍윬7 !z2 \(ԕ?Zҳlmlvllgk+H%OYZZBRSS踕$VqcF0}$B_OܳGw#CâF#stuy<"}\~pPg\]!|&`;'P6jl4}}m+;:ا{oȺBLMM%8+vouτ6l5uτuFN0^ 8}4OI OӴic'N52 (xO5ZBQϟkE_ P" DqLc7ߦgd85v\0w.73(>X5sFB0cm 0Q[[ʔV/=X ϗ޷Sz,t6ggWggW9rVOUԩ:V,Zdٛ)n E^ؾ#+;аHA\KKb,,(d2Y,=_}%zf?}hxZz} ![I|+;v4Gn WRXx8!dxI} !a$N:_<}rm^^P\ګW ?yxr_yfW/~oW݊2k ̺yN&n;wrov̬,z#aK[XXXXXXXzYsi344BMD9vU)ѱd0:vQq]ҡP?Ǐ lj}bq B-De,,,$ic{t9!5xmmI~Ӻ;oG1 >BȚY$~ytuu޽tvr"dffJ/xnYW.3v_%&%ݽwێ?ZuyjtJ+jRn]?z [.?|*!d6ߴYzqs˚#)nU6st$4tӐA4; 5!@AAPhAAPh z/KKKUTjբUeb8MBZzZ)_~Y,GM38k (W_1FY4}}U~SN-$0hԡH$zu[:@+:E[*&xr~SS  )Td6k,V4 e_g @zߔN 0 HDX,fX|>_Չ4 PV[-ѨP8@QJ"jzs mUuj^a0T=г*ŕ`z48=b]B8`p'ΪNSp&>vjE27G1?u]fYs ~~!>AIl\L~g##N%7}#=:wuqqUW W7[NƑ>MOvݢ"y}d=xVV }u*oԳ@]]]R}3N⁞kTn߹u#.?r7F;?OammՋN>UYY'o]EE{ttt[DXXώ%%342oU9 ¨@,>{n ŽEzU𶁺/CƉ}Cޙ.b%@'._psmBhtҲfLb!E^Ժu>|tL&CO욙} U^\*, 'd&M"3RYNv򆲤M!ÉǏm.`Դ']pvYtRMML_zqy--AH%_<;j̘Zݽ [7Z(X ,wɮnqq1im޼yMyu>B\]ifo޼~y䒒b7&:j#cc#G\QL.t\ l}u---_o@_^\p@p0f),,HJzkiiظۤBznL#BgH/x.O~?!$6.ҳ{oţ+!$6=iii1 GƒUa```0khZZA, v<}zc.ݗb6!~ʕ4٣E# mmmB&%qsΘL_ŕ!@IGY6eyXL_RHMM %' ԴTBTPuAy$nsBG a0tܹ1F #>{V?x$,-==t=A;BknP"\,Q%rObO)('sMU=j챈%ikk;5vR.[ƍ>|xfiiʿw 3++M/~}ecmMǚ_!K^0A^\p@PhH4r9ȋgz211XPonވRXX eϟ>֡}Ƕm}ΟY0ojUy<}H}Y頂PgΞ,((* 7!)އ>c}#N;Fմi3%T֬YGϞӕgY 6,y;YGGѱqJJw]]?[RR"IOuO\]GgU'RϜ;5|td֌鄐\ XL"_ŕP.  ^rK\]?g'W / !;yBEG]^\ܲQ\n ~=99ٖV::U@WWwW v>!$??)ч\,K(޼u]z}ظq OWcՕ`7nF'>,@o v2=?3+M6֭? W 5 bmeUCÖ-ZUc?(W- ᕖFF];v୨+\+-tTIA;A 8Ҷm;`۶R'Ŵiݶ}b86Ѯ;<:uMzVRܲ:w׏yk!ã=]oDgdkii5vtvyqժmwymIDNݫ;7vo'UᣮFE600KT;{wısܮ]UiՕ`X쩓_2-/\x r_gdUys:YbXq0r_gdUM$/Su"uM(:TՃVpj6Qu P}S 3<@PUZZJΥ0 PbT@Á@=0LURw(/ȷSu"  B*]`ŶqvrVu"  d2\\T7 )/nFOH? ȀŜתEsOD;9xw2kiWŤ}*'!ł5e+[v _|ާ9}ZB^dpnd*٧|jxWҡL'i,1uYA*ݎa< MAscŘ{ 2ՠVW^BƸlK16ϤWO{3U#Cu!SO1%}6>dLBO'^?TOy$O )Xc ԥ!mM::,<Wv /R|TC4ZWW9%9ZNŤsў:U]EE'>r.eqKֱؼRqqXLe'/Y^us`Kr مr4y%\twnTP{*6:n~TW>t%bzT+%m׍sY9 E̓υoB[m^H̯|γ*\/EA9Of옔bBHSkOJ8$0hԡH$zu[:B@Y+l, X>͌u6?/q7ief*|՗-MLz\L},dnb>͓zOy$Ϛo:5bik1uQS]zUXXǯW܉R=ԦnMBa&͚4KM`-(h Ɂ=A~ ؀2lzڗ - !A~Β} d{g+#SL0x͆Ȭ,CB^er7FfU>Oy$O [E+8 o=@V^\Dw$'BgUy(LU" HTK0Xb:аw}jSܛAoߡc"EN  ?Mqj ;@%Ǖpҹx!6}CW2,"l`Hh>?ZK H# KUР ڠ(@7VP C%@/ρ]J(Q=P-(EQbZU*Y( Q+}yB mWξcMMM+^޸rYpPU((aнфԴs/͘;M6֊pzNQ-P S>j[XD\CL 7+!bP .}тl6[^y { %<}~W /P C\3ɴH$ü=~LG"NlkEbjO~mp':r':Nt~j7( ALL ./]μܑY\.r\~j9( <TfOLLL`Vv3%Lq%4vθD(ԆdLNMzxrdgtz_H\RR"$IPA?JjCԃ @M<mRҎ]/EFOLGu_%.((x叫~YJ^R%k׬&p@p@mbfi`0lGN۷>G d0gVv `xߥ|[\\|IT{k8@Q!@#/I H$ 6tL&S, PH/U\\y%(nVmbP"jC2&z7|>_R6(,Y@6j>HarP:( +Ps(ԃR^PBX,Vii)]:`0B!Ru"  `gkgbldj{<)/ȷSu"  b:6bgBHvv6W ŶqvrVu"  eΞ?;,qT@ME-bo E {#PaMXQl "E pm&#pwqpp<<>{3 㾷{zuK }rWfZ5k~HK蠺֭]WQ@YG AG$zOPMQcY"Cպן($jz'kKkh;0Ǥuk;@M?88T\@۱,a*T@SI*QXt0"ջW@w P_ pP(; @}8rWDQҁ!PNJA: PUB{6Zz\JnoV-7}ЩE]a\MJNM74гVRQD.WnEx>ď-sCϞ=dlܺeFOBo7m+6{."<%4 ٧x'@)|zpΊ;WΝY<nX<'!1kjb~†3fe[׮:zkg;wV _7uZ]7nd> ly#^ϞmﮝKVߡ>?͜5kgGؼAD[xيڵj8tġjXlETOqt gddTn]iSq6|Gcb7yh ժVUTqwuݵmKjwۼM={$[H]ݮKN-8ޭGC<~G_3 lۨyKe%^(MOVryԉ̦MxY|C-[VX̬ʄc=,|BB{fylo{llllll, )aHE^=޻ǽ46679d<56]lHX2lkWl3p#vn| LivÈ!{"ur ]=֧{d[lq зo233jRͼHYu3w͵k.L4}qhJ)t}Zr<njG#sVXqܨ{ k?:o~֮@=y6[ثgC ZxtIJJX5kլɞ_rQßlml VqEřJS'M$oH5*qYs-ZPZ5g?_M8̬Y'y6[xيnnWΝrLg7E˖O'Fhc }q䩖>G ,[pBoBQT5gNѽg \an/X[-lmm ڲ}93BUx2dy'5v]r%0x㺕+Z5m0\yӧ/X!ǻK>EVYd25w-t-].:F*~v jղEo`T^ݺEjl`ҔKW?bnٰмm{}-(x#(`m۰ukw`ffffffu)|)NRop+:S ;n}ffU4sQ#<|dɊE6/YsSf'&&֨Qct9GQSg'$TVudF*$ ZB2U."f07: M ZD޿[G)Iix,NA?ZB233w]r5)9Y$6mx@NNڎjڎt4c[kMmml233?|}nJJG^(V0hM#M4ZժJ*maw4}.={`l}l4_wrke tSwѨyKB\.ߴm{ںȱ{jަa߼}?$T|՚\<ǕK$\ݣo11m(}|i׹g㿝) yV*4cOHO/n=:̥Fι+s/DDͣ@ϜewBZup0 'lo߁ܻXjuNNI{X2lmz=?]{s]zL,=k&&3N﨨!9wT+KKk+_OϞ;?}[~n9:8 5o,{{ [ul|O?,;\!ONΔO.ly70HMMMfLO>3cd6ik7npզMdiiNIIEl唉_".\4u4m .+ ¥˓'.| IDAT2a|PSޕP*V8nqF2 .::d_@IHLߓA ׯ !66vRRrժUܜ044فloon!%%%wyr \"lձ]}׮;vOڶu $99jժOV<ؗkV,sOɴ[lrǏރ<kcc&*6W+wppHIIQ'555w\<ٱ/_+N$:Z5kΜ:ţ{OfKz;[<5g5bڕ++Ul-w'ܶUXYY׬QǕ[ZZr>|*R*V~kV3 s^9HU*..V͚ œ6I+Wם%W;wlcm!`Mna[ZZ&$$pt$ŕ'$$XZZ!7 a\\0O ի+.,MGxrڧO2,>!!hƍ<[tTۙ+V424LHL\l{bڸ_3>.=V&$^]s޽ʇ G3|+fϜt媐U̪ -c3f񣣣 !>Gxp&!d`~<9{NBbbcFyx[k/4ރ\͚ &]]?afa#!\ SC <{aNݠWYxGiXZja!22aVxW%~~CTׁ2nZմi;5k쿥voNԱ#vDUo;/Y7Q5Ï*bhho²JPh> ԿuJ@ J;//e4 RK|ʤ۵7zTy(WYHt_ĝܿ%灞?,h +Lh;]@MF9R2v :K&g3d@۱$jjVƓ 12ĩ @Iɑ;;3m;K[S?j;Ui-3F ԃ@M<[SnMm@$z AG$zPMQcY"Cպx@3)U׌NM Bm$IW/__cH!CZD :j@t5IRH(tH"h; ݁@ #H4 vGQCxh(U: #x (nγAlmթݱ~4ܫW&\׌O=INIdM+ׯ[CX4nX$,][)kR=j>(%xhŞďϻvtXb 323޸ZN& ~N2Mn#"#"GjުDGQTj@O q|>J*UUO?mټeMxVVzu/۴jQM]890^<~-ʾ=aQ/żJvM5lfMw8i͚Q,J(5xhj05U;%5ťK.ݳU{UrJK{34SnǏ]:ߓ~^E=}/ CCߤf\XldhGOY[[vUTҸace=~ۮu;vqN]zOTn֤!!^z/^PjyF >(Exh}]7"(;'RJ a 4lBvҶ}veٳB\./+苷o~`u}poW0-Ĵj*tl۱o-qrsȈw1|ߠ0M~Wo^|2+;OiU#poQ#ej׬}Ὧ_4%۪D_~-d Fo!R bOv|~lml=\= Eih\إ˓Ox.=?n:d2WerPVw Enu3[I HNk%RKj@O ְm*22a#r.^500o:P]|M5_X-hX\PJ-,N =@MX Pjv $z $@ @I$Œ@H$1x (@),{[ñ@ v,:K*`gk@tҐtmTñFtL􋿣r9ڎ@g mll;j;݁@M<VZjv E{=@ #H=@ #H=@ #HЩEˈȧO{ `A5_@I^71hZggc_Iej:լ :W+.42]Lұ&"RJ~:0謇4 .\8d?:T6d6}:~+6h̩SU sŝqnrɕMMUMOO1)|i$WߴmZ<-._34 g=~PKtV\{G;;{[[ݣo6ڞwr[zT7W8QW e %DBC?}~7>_!Wjџ/{W nڼua:kH}G0È[79qB*oڶsOأ yv~?d{wT_H&&n\8;~1!$`F >Y^\:{SV7mV=:.̠f_˰7]ٳ}ۓgTvΝ۶޸|mKVb wޓXC޽?+v9{cOw͛{BFH8dwhXģG;l:ۉ<0eSXlTFtJ ֭mrkgq&_v}K/vhniܽwhޣb sP?b1@H$|"a°vv/Ez8nCE%3_w=վs3b?lSkV,#lvv&&&O|*[̹ӧZYZZ[Y:}Z6҂Vֿj))֭k٢9!kr9!D.9~>ᮢ#;5k**U4a[R=:.̠)))>Y8wogkkddwT[xS&YZZXZZ̜:;{VVlg_Pj #8SOϚ1cV),W6 ,{R{BΙ]g׷yg9۳/>UcD,-gNr<-;N7&5 @g BPMsnEvy[I,?NlҸZaayG|igkث'Wӄd{{{vje+.Q03ҪyS'Bj8:֪Yիnn\m'[BȺ9Eoz]2TT0 Zf][w411>CWaan송X,fSRRm.$RRRrGy"WMa$OEE`\ٜ+<2jFW"O[w\QߘP6!YP$k\ʱH]r_qL"ξpi+,2E66[fee_F BH\\W. srrԴ4eඕ ڲ}93oe$WGCNg5bڕ++UlM蔕rP \an/X diiPё_F++++Qa8kk>|WV!+esʆV`YJhB+< erw%P`o+,qVw@P>mml7jx-].:F*~vl.=V&$^5_~ K(@/V-[d~v Fխ e 3+&$&.^+W6:ee2!Q* }mԔ5Ajm@RrrRruWF*W.:B W+֬5cM@ځ)lTЊL> U MDvȳWD_#oL:\Y"!Є5,dU˿>XػA KT"m޽ot 4GQSg'$TVu_Yks[>oew 137{?Ue %+Vn^_pn ]4clK ?WFra 5jXXEa~>lu}|P` B\G Z!Q8!}=rpSHٜ+<'<}NN}d#ɳWD_SoLЮ]Ʌh;(U 5Vahhߐ%^陵!ĽQ<;k>Oy67n?԰1d Iq4C;:÷iѫo&Oq䉂ӟwbpw\ V<)A rsa!|B9U,PU٤e7B& pT"]ұ2 m vvv?ʤ;(AzL5PQ@قw"䆧$z AG$z AG$z k;(^Elj%bmRzDBQUuk%f (^EQթc':/_|e @P>|ЩC'L0c)=<wuy (R)EQr\ہ*E"D"v  @yW@I@Pn0 D!(((mG; 4(J<% @Qn솩I&`o_ԣtpq邚!$|Hu!$˗CG-_f@5Uιh}@ycdh8swyX,f+wt-{gBHG^\`Z.;;-/cǻw1p 8=: @1:?EDQ]B9=}5kԠizvm۲kۖw11穜kW!]u [~'O޷ON3Bex_8}jQQV @"##|ީK7vl \v}Ŧ&&͞Ǜ0Oل_֙/^hV !d'L=b8!D''''~hme?mT*8 W4 @4lP6@17^f&!1q٪/u˖iiigVVV\'|^xf'5:^j5WEVaEݹ{oպa!? 2 (+oe7hljS]ɹ;SRSSRSɹ#[N:GNqæ\[SS>{vbڿ^~s,b˗\댌 TJG^nh4M3-br-cϞؽg”i{y`L0nM`С#G+W_w=۹'!=vQԒ+?&%9 covժU;lijeOkXZjC!4,oHW/zR8P\|I&999*TX]200 BBd2D"axD"X̦ڎP%o+@P>}Ĕӣd&KHʇ5!III9bU_c E666@P>xZ5kժYKہ@G AG$z AG$z54Mg)ZڎE1 CR(aHcHȑE {A v|ɔ\$O* Kkd42!F+'bmGPhEK>oj|C5|B_vI h v(F,׶7 <$C*<-k/hE>#GPHL(yHaah7@@M4Є C@@U ahR ?5kfRRRģ%|I9ph0 )+_ԪUka5Aē=\UV,{] C Qv).Zh: jyufMDfM~0n4JaB Y @ 614Cӄ1F(%^ Djeeh0 CؾsP WZktqwvD,f[4k|^=kbP߷o^s?\'V,ssuohWmy٢YڹS0\{=tXhAvVQ2֑Cbs {-a~{{Sƻozr1ŋ]<ܯpµWPjhL&eRT"Qs]gN wڹ7;w];w儐۷oo9sbV,_&Hu筻!sнv wWmyIyyG"߷7:|\"nټ)p deePaHN[>_"ů]*=D"^-UCP#^vmSwY@BM CӴi務]/0iS.^<ϖBNnec% =^ʹM`f^̼ʸܕs$L4̼ ԩ&Ofmc]R]~5lۆ6ndmy:TC;=zA3  ˗/ЌѣUCP !ǎ^zŪ5k[mpJj:hÐV4%9.T[;}jJ IfH(\y۩66춭]:yB^ZZZqI?+y<Æ2n-Z5'PEFM04s…_gٷ7[/?u6C3*!w=:w[H=F&M^rgw[XWwt$|`aa=2. ժU'sB0;;[dhHS V֫֬f[8۹Be=Pu%24zP$j޲UHȞ?^( brJ ܰq꤉*XM~ uy =~)IR8氻:urݸ!(%9)%9i NiE:^.wS'RR7oשSPĄw={^zhD%+E&իWѳgPYcN͛oFuCP@͋:A7=s0O+]@!4ϗ_.Id~ݺt^\Z#G9±`tŽ]m{{6G>ϖO2;{v:yS 04ӧOV,7[˖.vvyS'PYyO7ƥc{ef?Ա C3.>}jIy033\ⅰ?Di;]Rj_yӧǣ(xysnr%&dѠ_BαVhh2v:hy!y떍J[7olݦ{@ &fhB"vXYY;J&jo0:x(ghMNI<|uU<^ޥmP !"2x էڥ P:`'6.V(:h;#ˣ^E}Pj<0!ڎ@4C1)lDDOˎ4H` ʙd׎r\&i;֮{ƕ绘mP 'hOb)eM+!gPjCĦѽe,@@d2riD O1!P $QУ͏F>x}""{z gXa&T@E*{4y~ ^c"3$rq~0zxbȘP P8K,v$@|+@DQT9=mze3 ;d 9gQ 14w/gPα~;ne~1ujJ'*g..SB Kw\marℭ @9Ü@mHʜ_=iI'S'Eu"o׵h08{x~cw윜Z5j ٱ};MBq.%@߾}~?o&D† ݫiYz2'9-Aݦkto LPB")#Gw˰^L)#߀HqWO6灞'373{;;k )f@)ZX YtM6֙= wIFjYjM10V y?}M_s?I_~ηi>uѣͳ__|G&b&!{dz?iSeJRBH\|{G>M5>y)!٣˔ >ᆱ5}\Kee ٿ!Ξ-[V&khhE^QإvO>[2\.PBm;tP6;vkF߈_vXQ\(< 9B@$440,w}qxyh^Mj*Uӫfd*|3+##3.>~{voޢ%_|a+8{tӧի3h{ !=X. '''OX]J$[8AlH\P yŽxx {z9w^u]?=إsWemQEOģKR\NӴL&쮅K[[Y–BDDl sظ¥y,-w Q֧#ؼi׶-:=|z={drzw<?.V ?>vۦmFG?Tx԰lA^?~QQFɖ 믞?-x|ZreBvlo xCܻp}꤉U*WfƳ_W_/_2a@?f4[x)ǛU" ƌ[\'Ō$&dYoܫ[wdw uL0L&}4l%9,(sP(ɦ9}[U<ϭ$yfw'thm$$&FzhswRy (=ϗ蘘/_vDlpt֭qV0Ra.!&CPBHԲqE*Dz"u9*˹~ 28µ{2^SϤ{tdԈիqs7[[YB^~m7or+VEM[;;< ?&%anHHMMg"/ oJ&IuVVB)`ݼis`~w-_ǻMVƕ*e~֭w_@r˖[ZZ:V{U+lܭԣm1'͸Q#)}z kצ'L6W1R!,(s@  Ms>{喱z%ʼpy=[  D"^|`XڅsBtY"؉cٯ/[}ܙGTEDn2OCk+\9w&y>g"M(O?s嵿dǏz]`Xa[(ijSdJjD"zrɊ쮜CCC0W^Cr_g }Ӷ [wd {vbڿ^~s,R؉T_PόYsnϟRi|B–;jЀݥl6 +;3*8V*50=z\($$eHd04!A =\[O,ݴ5"QӸzzzusfkcSvko4k[V։S;vovvv  EII֫YE͍[mܺs< {6pR]t+wnjj>ҥc[SRSSRSluءHPNCG$~Ւ+d2Bţ P h.Ye_=j>mڶ3k洩;v5`y6$%zj3f2r [أk[-YA:(줨T_P!}ny뗱B]fC& g뎝^rP٨\ٶp_*X_hX>g ;k>Oy67n?԰1d IqRq=~PyVܾs'lϜ;!x%͚6awݹw? o-yFPQsa.; $S!M'??&%9 kӪe;v`ff&D"nݱ?!;ˈW? yn11kֿyYAmֹzF}IIIիW;F Ry AFM?THxrw244xѬI<Ŝ@+ 2L*gfE" +&m5(?__2B`P C" >I`3GQT ULe2¶Aă 3( E>R`BrChn(sr.zVar-vŋ(m.*`,(<$e0W)+L o;.LʱX9Ŕ_&CP(Yc)=EI$A[y`B@HNMKRJ1|i:Ku]((lmlINIHXBƖ{>X$Pd2{z.OƄ@@&Hp&Tӣ@ #tD,.#R3,ar_頙I,.;|(4GQiWwd #I?gXifҠАhCk;7a$Pz(vlɫW<==–K ԬY" O?>^ 4dYM6EEE.d7rejժeii9|LaƎU޳gرcُ+0 J(hUؒ3&&&ݻwvvvsa׬YsK.z*z3gt}Æ &L(ʕ+o޼O*ٵaÆ7n\|˗2l…#GB>ĶJ;K2FI pە+WrT*!ܽ{-ϟߴiS<44СU!+W` !7^c\ͲC&JZnվ} /Z+$ܹСve˖oaeE 9"ѣǮ_F/ksEJM34Mk v#55uSN;s4!$""b޼񎎎cذaύ7lxIc{7o^NZ cc?4jԈr AVX|2 .28]PxX@+Źmss)Sܻw}7~$2=sl{\Ζۿ}6?Ν;~DPP&9i`mO ?%-IXoܸ@4RJÔM äˬ,cJFFF~{ڻ(8l)` M]{FbzPԤ4[bjK1֏r IaP51\zidSt7nxh!z6_ewfiisss{{ʕO=x;w^ f&7gf׫TrX}k_NNNV*8{{{_>Iܐ-@@(nꦑdz?zzzn}7_le|>q~޽_+wFFޫT*˗a(*?ݿ?6>&q0ۻ(=}ݍ-bh$JtGѣ_G~5 \.7xBp14ᅲ|WUۋRp5 G |<zv145)@(" )@(" )-7 s=R IENDB`pacemaker-master/doc/Clusters_from_Scratch/en-US/images/Policy-Engine-big.dot000066400000000000000000000145311217637305600274650ustar00rootroot00000000000000digraph "g" { "Cancel drbd0:0_monitor_10000 frigg" -> "drbd0:0_demote_0 frigg" [ style = bold] "Cancel drbd0:0_monitor_10000 frigg" [ style=bold color="green" fontcolor="black" ] "Cancel drbd0:1_monitor_12000 odin" -> "drbd0:1_promote_0 odin" [ style = bold] "Cancel drbd0:1_monitor_12000 odin" [ style=bold color="green" fontcolor="black" ] "IPaddr0_monitor_5000 odin" [ style=bold color="green" fontcolor="black" ] "IPaddr0_start_0 odin" -> "IPaddr0_monitor_5000 odin" [ style = bold] "IPaddr0_start_0 odin" -> "MailTo_start_0 odin" [ style = bold] "IPaddr0_start_0 odin" -> "group_running_0" [ style = bold] "IPaddr0_start_0 odin" [ style=bold color="green" fontcolor="black" ] "MailTo_start_0 odin" -> "group_running_0" [ style = bold] "MailTo_start_0 odin" [ style=bold color="green" fontcolor="black" ] "drbd0:0_demote_0 frigg" -> "drbd0:0_monitor_12000 frigg" [ style = bold] "drbd0:0_demote_0 frigg" -> "ms_drbd_demoted_0" [ style = bold] "drbd0:0_demote_0 frigg" [ style=bold color="green" fontcolor="black" ] "drbd0:0_monitor_12000 frigg" [ style=bold color="green" fontcolor="black" ] "drbd0:0_post_notify_demote_0 frigg" -> "ms_drbd_confirmed-post_notify_demoted_0" [ style = bold] "drbd0:0_post_notify_demote_0 frigg" [ style=bold color="green" fontcolor="black" ] "drbd0:0_post_notify_promote_0 frigg" -> "ms_drbd_confirmed-post_notify_promoted_0" [ style = bold] "drbd0:0_post_notify_promote_0 frigg" [ style=bold color="green" fontcolor="black" ] "drbd0:0_pre_notify_demote_0 frigg" -> "ms_drbd_confirmed-pre_notify_demote_0" [ style = bold] "drbd0:0_pre_notify_demote_0 frigg" [ style=bold color="green" fontcolor="black" ] "drbd0:0_pre_notify_promote_0 frigg" -> "ms_drbd_confirmed-pre_notify_promote_0" [ style = bold] "drbd0:0_pre_notify_promote_0 frigg" [ style=bold color="green" fontcolor="black" ] "drbd0:1_monitor_10000 odin" [ style=bold color="green" fontcolor="black" ] "drbd0:1_post_notify_demote_0 odin" -> "ms_drbd_confirmed-post_notify_demoted_0" [ style = bold] "drbd0:1_post_notify_demote_0 odin" [ style=bold color="green" fontcolor="black" ] "drbd0:1_post_notify_promote_0 odin" -> "ms_drbd_confirmed-post_notify_promoted_0" [ style = bold] "drbd0:1_post_notify_promote_0 odin" [ style=bold color="green" fontcolor="black" ] "drbd0:1_pre_notify_demote_0 odin" -> "ms_drbd_confirmed-pre_notify_demote_0" [ style = bold] "drbd0:1_pre_notify_demote_0 odin" [ style=bold color="green" fontcolor="black" ] "drbd0:1_pre_notify_promote_0 odin" -> "ms_drbd_confirmed-pre_notify_promote_0" [ style = bold] "drbd0:1_pre_notify_promote_0 odin" [ style=bold color="green" fontcolor="black" ] "drbd0:1_promote_0 odin" -> "drbd0:1_monitor_10000 odin" [ style = bold] "drbd0:1_promote_0 odin" -> "ms_drbd_promoted_0" [ style = bold] "drbd0:1_promote_0 odin" [ style=bold color="green" fontcolor="black" ] "group_running_0" [ style=bold color="green" fontcolor="orange" ] "group_start_0" -> "IPaddr0_start_0 odin" [ style = bold] "group_start_0" -> "MailTo_start_0 odin" [ style = bold] "group_start_0" -> "group_running_0" [ style = bold] "group_start_0" [ style=bold color="green" fontcolor="orange" ] "ms_drbd_confirmed-post_notify_demoted_0" -> "drbd0:0_monitor_12000 frigg" [ style = bold] "ms_drbd_confirmed-post_notify_demoted_0" -> "drbd0:1_monitor_10000 odin" [ style = bold] "ms_drbd_confirmed-post_notify_demoted_0" -> "ms_drbd_pre_notify_promote_0" [ style = bold] "ms_drbd_confirmed-post_notify_demoted_0" [ style=bold color="green" fontcolor="orange" ] "ms_drbd_confirmed-post_notify_promoted_0" -> "drbd0:0_monitor_12000 frigg" [ style = bold] "ms_drbd_confirmed-post_notify_promoted_0" -> "drbd0:1_monitor_10000 odin" [ style = bold] "ms_drbd_confirmed-post_notify_promoted_0" -> "group_start_0" [ style = bold] "ms_drbd_confirmed-post_notify_promoted_0" [ style=bold color="green" fontcolor="orange" ] "ms_drbd_confirmed-pre_notify_demote_0" -> "ms_drbd_demote_0" [ style = bold] "ms_drbd_confirmed-pre_notify_demote_0" -> "ms_drbd_post_notify_demoted_0" [ style = bold] "ms_drbd_confirmed-pre_notify_demote_0" [ style=bold color="green" fontcolor="orange" ] "ms_drbd_confirmed-pre_notify_promote_0" -> "ms_drbd_post_notify_promoted_0" [ style = bold] "ms_drbd_confirmed-pre_notify_promote_0" -> "ms_drbd_promote_0" [ style = bold] "ms_drbd_confirmed-pre_notify_promote_0" [ style=bold color="green" fontcolor="orange" ] "ms_drbd_demote_0" -> "drbd0:0_demote_0 frigg" [ style = bold] "ms_drbd_demote_0" -> "ms_drbd_demoted_0" [ style = bold] "ms_drbd_demote_0" [ style=bold color="green" fontcolor="orange" ] "ms_drbd_demoted_0" -> "ms_drbd_post_notify_demoted_0" [ style = bold] "ms_drbd_demoted_0" -> "ms_drbd_promote_0" [ style = bold] "ms_drbd_demoted_0" [ style=bold color="green" fontcolor="orange" ] "ms_drbd_post_notify_demoted_0" -> "drbd0:0_post_notify_demote_0 frigg" [ style = bold] "ms_drbd_post_notify_demoted_0" -> "drbd0:1_post_notify_demote_0 odin" [ style = bold] "ms_drbd_post_notify_demoted_0" -> "ms_drbd_confirmed-post_notify_demoted_0" [ style = bold] "ms_drbd_post_notify_demoted_0" [ style=bold color="green" fontcolor="orange" ] "ms_drbd_post_notify_promoted_0" -> "drbd0:0_post_notify_promote_0 frigg" [ style = bold] "ms_drbd_post_notify_promoted_0" -> "drbd0:1_post_notify_promote_0 odin" [ style = bold] "ms_drbd_post_notify_promoted_0" -> "ms_drbd_confirmed-post_notify_promoted_0" [ style = bold] "ms_drbd_post_notify_promoted_0" [ style=bold color="green" fontcolor="orange" ] "ms_drbd_pre_notify_demote_0" -> "drbd0:0_pre_notify_demote_0 frigg" [ style = bold] "ms_drbd_pre_notify_demote_0" -> "drbd0:1_pre_notify_demote_0 odin" [ style = bold] "ms_drbd_pre_notify_demote_0" -> "ms_drbd_confirmed-pre_notify_demote_0" [ style = bold] "ms_drbd_pre_notify_demote_0" [ style=bold color="green" fontcolor="orange" ] "ms_drbd_pre_notify_promote_0" -> "drbd0:0_pre_notify_promote_0 frigg" [ style = bold] "ms_drbd_pre_notify_promote_0" -> "drbd0:1_pre_notify_promote_0 odin" [ style = bold] "ms_drbd_pre_notify_promote_0" -> "ms_drbd_confirmed-pre_notify_promote_0" [ style = bold] "ms_drbd_pre_notify_promote_0" [ style=bold color="green" fontcolor="orange" ] "ms_drbd_promote_0" -> "drbd0:1_promote_0 odin" [ style = bold] "ms_drbd_promote_0" [ style=bold color="green" fontcolor="orange" ] "ms_drbd_promoted_0" -> "group_start_0" [ style = bold] "ms_drbd_promoted_0" -> "ms_drbd_post_notify_promoted_0" [ style = bold] "ms_drbd_promoted_0" [ style=bold color="green" fontcolor="orange" ] } pacemaker-master/doc/Clusters_from_Scratch/en-US/images/Policy-Engine-big.svg000066400000000000000000001011371217637305600274750ustar00rootroot00000000000000 g Cancel drbd0:0_monitor_10000 frigg Cancel drbd0:0_monitor_10000 frigg drbd0:0_demote_0 frigg drbd0:0_demote_0 frigg Cancel drbd0:0_monitor_10000 frigg->drbd0:0_demote_0 frigg drbd0:0_monitor_12000 frigg drbd0:0_monitor_12000 frigg drbd0:0_demote_0 frigg->drbd0:0_monitor_12000 frigg ms_drbd_demoted_0 ms_drbd_demoted_0 drbd0:0_demote_0 frigg->ms_drbd_demoted_0 Cancel drbd0:1_monitor_12000 odin Cancel drbd0:1_monitor_12000 odin drbd0:1_promote_0 odin drbd0:1_promote_0 odin Cancel drbd0:1_monitor_12000 odin->drbd0:1_promote_0 odin drbd0:1_monitor_10000 odin drbd0:1_monitor_10000 odin drbd0:1_promote_0 odin->drbd0:1_monitor_10000 odin ms_drbd_promoted_0 ms_drbd_promoted_0 drbd0:1_promote_0 odin->ms_drbd_promoted_0 IPaddr0_monitor_5000 odin IPaddr0_monitor_5000 odin IPaddr0_start_0 odin IPaddr0_start_0 odin IPaddr0_start_0 odin->IPaddr0_monitor_5000 odin MailTo_start_0 odin MailTo_start_0 odin IPaddr0_start_0 odin->MailTo_start_0 odin group_running_0 group_running_0 IPaddr0_start_0 odin->group_running_0 MailTo_start_0 odin->group_running_0 ms_drbd_post_notify_demoted_0 ms_drbd_post_notify_demoted_0 ms_drbd_demoted_0->ms_drbd_post_notify_demoted_0 ms_drbd_promote_0 ms_drbd_promote_0 ms_drbd_demoted_0->ms_drbd_promote_0 drbd0:0_post_notify_demote_0 frigg drbd0:0_post_notify_demote_0 frigg ms_drbd_confirmed-post_notify_demoted_0 ms_drbd_confirmed-post_notify_demoted_0 drbd0:0_post_notify_demote_0 frigg->ms_drbd_confirmed-post_notify_demoted_0 ms_drbd_confirmed-post_notify_demoted_0->drbd0:0_monitor_12000 frigg ms_drbd_confirmed-post_notify_demoted_0->drbd0:1_monitor_10000 odin ms_drbd_pre_notify_promote_0 ms_drbd_pre_notify_promote_0 ms_drbd_confirmed-post_notify_demoted_0->ms_drbd_pre_notify_promote_0 drbd0:0_post_notify_promote_0 frigg drbd0:0_post_notify_promote_0 frigg ms_drbd_confirmed-post_notify_promoted_0 ms_drbd_confirmed-post_notify_promoted_0 drbd0:0_post_notify_promote_0 frigg->ms_drbd_confirmed-post_notify_promoted_0 ms_drbd_confirmed-post_notify_promoted_0->drbd0:0_monitor_12000 frigg ms_drbd_confirmed-post_notify_promoted_0->drbd0:1_monitor_10000 odin group_start_0 group_start_0 ms_drbd_confirmed-post_notify_promoted_0->group_start_0 drbd0:0_pre_notify_demote_0 frigg drbd0:0_pre_notify_demote_0 frigg ms_drbd_confirmed-pre_notify_demote_0 ms_drbd_confirmed-pre_notify_demote_0 drbd0:0_pre_notify_demote_0 frigg->ms_drbd_confirmed-pre_notify_demote_0 ms_drbd_demote_0 ms_drbd_demote_0 ms_drbd_confirmed-pre_notify_demote_0->ms_drbd_demote_0 ms_drbd_confirmed-pre_notify_demote_0->ms_drbd_post_notify_demoted_0 drbd0:0_pre_notify_promote_0 frigg drbd0:0_pre_notify_promote_0 frigg ms_drbd_confirmed-pre_notify_promote_0 ms_drbd_confirmed-pre_notify_promote_0 drbd0:0_pre_notify_promote_0 frigg->ms_drbd_confirmed-pre_notify_promote_0 ms_drbd_post_notify_promoted_0 ms_drbd_post_notify_promoted_0 ms_drbd_confirmed-pre_notify_promote_0->ms_drbd_post_notify_promoted_0 ms_drbd_confirmed-pre_notify_promote_0->ms_drbd_promote_0 drbd0:1_post_notify_demote_0 odin drbd0:1_post_notify_demote_0 odin drbd0:1_post_notify_demote_0 odin->ms_drbd_confirmed-post_notify_demoted_0 drbd0:1_post_notify_promote_0 odin drbd0:1_post_notify_promote_0 odin drbd0:1_post_notify_promote_0 odin->ms_drbd_confirmed-post_notify_promoted_0 drbd0:1_pre_notify_demote_0 odin drbd0:1_pre_notify_demote_0 odin drbd0:1_pre_notify_demote_0 odin->ms_drbd_confirmed-pre_notify_demote_0 drbd0:1_pre_notify_promote_0 odin drbd0:1_pre_notify_promote_0 odin drbd0:1_pre_notify_promote_0 odin->ms_drbd_confirmed-pre_notify_promote_0 ms_drbd_promoted_0->group_start_0 ms_drbd_promoted_0->ms_drbd_post_notify_promoted_0 group_start_0->IPaddr0_start_0 odin group_start_0->MailTo_start_0 odin group_start_0->group_running_0 ms_drbd_pre_notify_promote_0->drbd0:0_pre_notify_promote_0 frigg ms_drbd_pre_notify_promote_0->ms_drbd_confirmed-pre_notify_promote_0 ms_drbd_pre_notify_promote_0->drbd0:1_pre_notify_promote_0 odin ms_drbd_demote_0->drbd0:0_demote_0 frigg ms_drbd_demote_0->ms_drbd_demoted_0 ms_drbd_post_notify_demoted_0->drbd0:0_post_notify_demote_0 frigg ms_drbd_post_notify_demoted_0->ms_drbd_confirmed-post_notify_demoted_0 ms_drbd_post_notify_demoted_0->drbd0:1_post_notify_demote_0 odin ms_drbd_post_notify_promoted_0->drbd0:0_post_notify_promote_0 frigg ms_drbd_post_notify_promoted_0->ms_drbd_confirmed-post_notify_promoted_0 ms_drbd_post_notify_promoted_0->drbd0:1_post_notify_promote_0 odin ms_drbd_promote_0->drbd0:1_promote_0 odin ms_drbd_pre_notify_demote_0 ms_drbd_pre_notify_demote_0 ms_drbd_pre_notify_demote_0->drbd0:0_pre_notify_demote_0 frigg ms_drbd_pre_notify_demote_0->ms_drbd_confirmed-pre_notify_demote_0 ms_drbd_pre_notify_demote_0->drbd0:1_pre_notify_demote_0 odin pacemaker-master/doc/Clusters_from_Scratch/en-US/images/Policy-Engine-small.dot000066400000000000000000000030701217637305600300300ustar00rootroot00000000000000 digraph "g" { "rsc1_monitor_0 pcmk-2" -> "probe_complete pcmk-2" [ style = bold] "rsc1_monitor_0 pcmk-2" [ style=bold color="green" fontcolor="black" ] "rsc1_stop_0 pcmk-1" [ style=dashed color="red" fontcolor="black" ] "rsc1_start_0 pcmk-2" [ style=dashed color="red" fontcolor="black" ] "rsc1_stop_0 pcmk-1" -> "rsc1_start_0 pcmk-2" [ style = dashed ] "rsc1_stop_0 pcmk-1" -> "all_stopped" [ style = dashed ] "probe_complete" -> "rsc1_start_0 pcmk-2" [ style = dashed ] "rsc2_monitor_0 pcmk-2" -> "probe_complete pcmk-2" [ style = bold] "rsc2_monitor_0 pcmk-2" [ style=bold color="green" fontcolor="black" ] "rsc2_stop_0 pcmk-1" [ style=dashed color="red" fontcolor="black" ] "rsc2_start_0 pcmk-2" [ style=dashed color="red" fontcolor="black" ] "rsc2_stop_0 pcmk-1" -> "rsc2_start_0 pcmk-2" [ style = dashed ] "rsc2_stop_0 pcmk-1" -> "all_stopped" [ style = dashed ] "probe_complete" -> "rsc2_start_0 pcmk-2" [ style = dashed ] "rsc3_monitor_0 pcmk-2" -> "probe_complete pcmk-2" [ style = bold] "rsc3_monitor_0 pcmk-2" [ style=bold color="green" fontcolor="black" ] "rsc3_stop_0 pcmk-1" [ style=dashed color="blue" fontcolor="orange" ] "rsc3_start_0 pcmk-2" [ style=dashed color="blue" fontcolor="black" ] "rsc3_stop_0 pcmk-1" -> "all_stopped" [ style = dashed ] "probe_complete" -> "rsc3_start_0 pcmk-2" [ style = dashed ] "probe_complete pcmk-2" -> "probe_complete" [ style = bold] "probe_complete pcmk-2" [ style=bold color="green" fontcolor="black" ] "probe_complete" [ style=bold color="green" fontcolor="orange" ] "all_stopped" [ style=dashed color="red" fontcolor="orange" ] } pacemaker-master/doc/Clusters_from_Scratch/en-US/images/Policy-Engine-small.svg000066400000000000000000000220421217637305600300410ustar00rootroot00000000000000 g rsc1_monitor_0 pcmk-2 rsc1_monitor_0 pcmk-2 probe_complete pcmk-2 probe_complete pcmk-2 rsc1_monitor_0 pcmk-2->probe_complete pcmk-2 probe_complete probe_complete probe_complete pcmk-2->probe_complete rsc1_stop_0 pcmk-1 rsc1_stop_0 pcmk-1 rsc1_start_0 pcmk-2 rsc1_start_0 pcmk-2 rsc1_stop_0 pcmk-1->rsc1_start_0 pcmk-2 all_stopped all_stopped rsc1_stop_0 pcmk-1->all_stopped probe_complete->rsc1_start_0 pcmk-2 rsc2_start_0 pcmk-2 rsc2_start_0 pcmk-2 probe_complete->rsc2_start_0 pcmk-2 rsc3_start_0 pcmk-2 rsc3_start_0 pcmk-2 probe_complete->rsc3_start_0 pcmk-2 rsc2_monitor_0 pcmk-2 rsc2_monitor_0 pcmk-2 rsc2_monitor_0 pcmk-2->probe_complete pcmk-2 rsc2_stop_0 pcmk-1 rsc2_stop_0 pcmk-1 rsc2_stop_0 pcmk-1->all_stopped rsc2_stop_0 pcmk-1->rsc2_start_0 pcmk-2 rsc3_monitor_0 pcmk-2 rsc3_monitor_0 pcmk-2 rsc3_monitor_0 pcmk-2->probe_complete pcmk-2 rsc3_stop_0 pcmk-1 rsc3_stop_0 pcmk-1 rsc3_stop_0 pcmk-1->all_stopped pacemaker-master/doc/Clusters_from_Scratch/en-US/images/f-13.1-welcome.png000066400000000000000000005235741217637305600265340ustar00rootroot00000000000000PNG  IHDR i1 iCCPICC ProfilexXgPMX`w9%眓sFrPQHV""HT  |﫺nW3==sByOtt8n{o& |~hw^ydOEƲ~ѱ`ƣagƃ8<}89Dc K}`(!`{6F:""j_1? =}|~QH\tO߇[DxliH?YiEyXڮc!ngX -Ͱ0{L _|l?v;4 ~8a4 *zX[>AD2AT4K= QLY@* 6!B$ qB($)Bd YA; AP<eAPTBU&tAF  /B !PG#,N/D"FD!{aK,b D$R)TG"m{Xd2YC!Y2 P2(-凊Ae*PMsjMBКhs:A/o/tO ÆǨa0PL*8sӋyǬaXNVk`˱wcX:vGq&Ha\)׃-6xQ&OƟ7Ot&L'hLBO"|'BD =1xXFB$1P$ <N2422L0|'Hb$=^IR3>iHee4ggڵڳ:::tfuu}tt ][ԗտ@ aa(hĘbl\a=HkcNlΫZGC 96['?Q|~iqN((;s2)S5ȂB¦"rQJiy?J *=C8f̪\|"eA*ܪjg>ruimGX]i=>~a \/l7F6694=hVknni9Պhop%K]m2m._W|}u嵾E۫nPou@]]nZqKVmەwX!dMݻ|/|n_<0o?ڃ4n>R9:X'*Ontw,+!vw'VNn` )Ei2%R3\e r%sZv_PXDy M -J*.i3l~5!7";b:cbntG |ǧU=> %Ň ?|"8my9 Wү&hMONθ72 7Kbb>Y&~Ҽ v|8ٲm? r qtEQ ht3F3݇N $hf-2*JZ{ZktJtO08aX`tƸʤٴŲf5gpӠ+uWپYo!o BVPdpUpF8-5XTGb,ρD$䒔}ά<ܙ5rSű/8~ĭN-"aP+v( ->S]v^HD\5~vtx.nnm^jt Uk%ڥnvwv޴v!NaOݾ{=Pwx3P8xihc ƺ}:kfZqm썹y ߖt?nYs j7u~15g@ ! (MQxF!QZ ]!b0o.8g#Db!y"S(6sY|bCyOMaN%3_BrUr+s? EO%)#T+l$ +*#L,^]-")E%!#$J@J'?pTLAiTX]_uAM=^CCQsUk|O]'=i}Aa1;63SsVyk\ulmv+o`\RZV^G~oyр `carVtvL]쭸 'RRoO?w0Pdfa,l#9zG5)K?!~RJ~]Q%JY)gЪʯ^VΥ>yz#oKܗn\A^uvxÿAͬ=^˾'=&?5;O}b9k1 @)\py S%Cv$xL@ _+@dC"HGd9r%:E3mq4bNK8<.ׇ kD^b.q!ɘ(XDecS˔`"5%;k2`gfoPtĕMny B5BZBEEzD}b-4@k('% d؛˦ʽTpVdVQ*TvRTyڢ1٢BS{BL]OoI1ɢٸ )E_6,vŎ.ܮnWNYhY◈O_YXH5ud{l@ː h!鎬AQD}4탾g{1Wx.[TBaEc`#n13v1i2Y0ّ% `вp(BC,D\P|V*+V򐔀Ԁt 9[rEK*e_ߪj!ښ̚Z={JuTuzmG Md9LP&V̿XYnYclm-<]nθ#JxX{yU{1 ಐa#Q)+qf ]IeLiYF?Wc'NvΟN*VwUU:\Xl( lbb׶k;:oR=ۓK7|?G O`610B« 7w?M;^޻ht/.+W}qwۺІݯg7_f#퓡eD\I@C9w0ژ{XK. Wt KǘdLb 7SҨ, p'^psvp>s7/[QBHWX]DETYLI\f(-)!&(ɑU+ijkQOD ^ÏT S_\V'Q6vfnNG\\Ϲ;1}n?o_0|ʫ'1E F)D7݈7Mx䑼(;$ٝe=v5bœO. <<Quxt-|E#wSmPk%Ͷ+.WG\va\?7x>(2T4xd l3/S_|4mlJmZt2+Ec ŧKe>}TlՕV_'=ڏkkQks?>\W]`Hݠ2wMͩ-խ[sǶ'ߵ\n\~.ͺz8ـJo?fRvQnbޥ|^ pHYs   IDATx ]E7~^$} .j@YqQgdt ~.ç7:fe#NTdW!J}#$;Nz_wgUVֽV{KJEO-JCb92@F #d2p PCCkѣ-aqZ\booGFF #d2@F #`"MMMF \ӓd2@F #dNt`B=^WڱcDzcl+#dtzC~aܹs@F #NnjQ<Cɖ-[z 3fq'&Lf Z>lJ ԩSog',Tjg??3WBps5׸$8ns#X8+Vwܡ1;we˖i4 8(6N9zSN4A]sͻKmr@4eojl@gzF #8XfuQ:o"1^criɘ1czL8`N-#df4 UnyGuӧ,,` l޼YgE8#QF h6WZ3˴iM&&NP;P{7oQh?>N Yem%?@fd2~%TDt5LRgΜ%K4x&K r"-ݻdIO(Gk)GVmIrɅ=ɩ@F #q2*pXzɇ} mmmK{[[[f`MD v-6k,wwɓ'RY@69pڴi*(X"P_'N}ڥ f,ˮ _$'MѣFi(?*+3utʶe,7Hh:G9Ms @awɽrm3JƎjv鐻?% VrY5TTJR)ʜɗ.?A9b{X9@F #__}ɶm䤓N>2W91_/pVK|9q?.z!g@֯_r(< bƋ u @aڵ:hMV:}xV[U&-IlnذA&MyOΚNcR@gzF #x* оG߾K.~2_=(w]Z&Oh1d f 1t+k&{.>Yb/w 6Lof+_FYc[:d2#ooڴI9]}s9`vB"7:,t2φ;!Apv,z1`trRSɖ mr`aϞ='}G|0 L!Ciyd'vHS+ҷn%].MuhƗa VJOp쾅?V;;;;q s%2{hu(CF # 3\m4g#w✭}h}t4M5$5BC#(,,_K|W>bB'n*~zCtF #x!+[lo5r؂cg6,:gP2@F``+^^;R>mMگ=l*vwIK/0ej,.|kYߐQSQ^}Ld2aG&[Q$pcol q s>Pν;=; ]&z6sPCY fsر*J > CTd2O1\s2ͣqoډ:4e筇uxk › !Mϯa֣l2Lȗ)Ie5,9µ\Cީgu`w s6|i,6 `} Kkǁ߃s:#<hK?UZ͕'0+Lֵѱq";wI 2א2^zL>d6#w,1sCF #`i.g ,M.c˖-jXӳggyq~,.㢟\۶~Vd2 *G~Vu }xm:m`>ޞCF #<p7 5uu77yɝq㵅2]-b^]3-#pd_3 j)g2@F`pj& u<~tsd2@F #?C.JMF3Tbszd~F #d2@F #04?1~d2@F #d2{kKY0#d2@F # @d2@F #d<>,@F #d2@F`%XGN/s_O7A}QYlcc6fʉ'7|f3Ø{.,3d2@F``}Fߜ M~{$7ϭu_HwF̊p;&.@v@~<Ox`+ghpg@F #3kNo{ vM>Z{{ U}3&)=utTCPF)um-֛.7X~`rʛ0a?OAF{κ1 "vz'>$T%n\rv<#md2@F #C7m^,ԑ֎2wޡҍA_; C ]|BƍEy(9y\`A]K[w=g'h0O4 rg{E֮*K=o#_ ɩG>t'M$۶o7?Rm>@+-W]т@ &Ph>XwuE/_G{08| ORK(CF #d2OOM nҷGF6 IiEy)ЉKeH{{qqc\ =,{( :8Rʵrh=LI=Ҙ^Zm/s0JL0/X@^L1"֜%"8MZe9٧@F #dt<**hXx46i_LӁ(Œm,*J*y7k ;x>2x:˦n[>w6ˣҕ}#W^K:\@ 37v84aG4R)@6xٍi{?.(-O mGtc.%y_m۷U8Ƹč1% ͕ KF #d2&ɮsiIz: oE`:D?3!}wI9ga2a℺ z^n[ eV-{ڔ}I,8U>ݟ4c6waaǍ].ir-[ BFРw0Na`|B|=#lO^+޼0w6r$ވ6g.-֌O4Yxt!qgG`$2O<9uϦo9ӵ2@F #x#˼/ )A뵇bک9iVKJGG'_uDxn ;e⎮<yIX%}h9jWwkh_|}"fQ*2sJY>f 6`WN;oxp?Laʨ߲}|up"ߋn4-A֑obcg9% ,&My6ɆeQ{ڤytz&ڷ^z'Ikى;vi8pG0)g@71R+>cz,Ȭ\ [._L02뮓 /p9ĝ;ȎZ96wG͗-1QZ5#BGdҷ˶ PeG)Hb2\Zř%Ė-[bɁ[N1">G+{d2p#U0a߉g?*xIڥҗ#M3\āH#^NGkc[g~8i3]].͓6af@qȰ˰ET[ ۮR+h#rXڮq@\pn@|bxWeg86^QnRY+=rͿN&b)ViixO5CGOl/3φ6>c֟3 cz27!<RR笛d2XRž(L6aT閦N @U)>^+olZ~BޏN#Xo?1e04'RF6;;˫jXOBnLQБ#g?Xy~.b#buCi^ocҴ oTL`ҊNuc#.<< :){ bj~V|?;D<8 9s㉂XXB )eZl CZ@F #<G {"@hi fG;WyQ译U:r+~\#[^Xr6oޕ掝?bҔC ?8t[k~ъri)Ϗub;pq 7ȫ_;OoX|FǤo)/ XbM;p`&6@D0"˻K_^pT%2a1apcmm|6I1AVie۰x"`'@ڕrd2ģ·Ai@TLWp#vLO@ y>|q]oⴑ"?OyCǒ|C=6twd -\8Tc(ti6Gb`|~ks8H%ArԑRei(fz)k0,2m+əCo"ݸ/}PlF t4$ q4 s`@挈'ΞCF #d2O?Ы >}O$Zwߪc?˯x1ʱ);'+4Wȧ,vwZSd庲LY ^Evu4AWϟ7·!7=$wf@Xaf?n<ģ# s \x025 c<82k,Y%WzH&<2ai!jG|#uWEuqPq34Xvc>%WB_^àЧPnR]%~$$IN#s8Hx^G'6fϔUJkf@pYv<;ct_z9|VIƀ{;\LEN?`% ;-QôUz0Y;p3l}skեX|(z @ IDAT o,}l#=X4Z0C"yQ y}Bl绻9`ˮynu~]d2@F``|ޱeĻH5 ]  }=X-DWO?eY,waL>+o>d6}(߻Me0:z(^j~eʔ)qըQ'@o(@{"=4Ap޼y#Vi ҙg)~g;8S͙"fy{dTa:J'=FWCukN+4:2{lޔ:~$E:uB#OPv8{©.x&@o6[SN9E^vYsоwF2|  )/:L?6|;Хl3gΌ3 Hp39Yc Q^(Nb{2BwO~l8kcn1=b'z姏ڍhx#2ȐnlܸQ;|qcQ9{lC17xכN4u07e@&N?t}0oZPukʾY4Xhd%yiJ`im۶I #ѣF7qՍ;B5?GY.}Ny:/Ǐu쮻իW\gjI5CfζnwRlYpst?k#|*b_9)Mi(t?x9d3@F #g ؇Ӷ\Ě鬒 0v8RrY L{w.4צwɫ}j&N/qsC9@,_8lGa!khm#&ϒygǻ6}@կ"> fLG ē/@F #d2Crc3r~Ǚͦ:U'ry axƬD9bǎrm ݱ#jLr@F #d) \gF #d2@F # d2@F #<اwlq}>Nr.zi-Z4(wl7sYĺ _;./$au@F #dF'V/^Y>Y>@_ }&C/Xbg@:ˢo|Unh8= tˮF[{˿,KT|T3˾ϑ6"W~Q>s?7M˒Eߒ#·>kDH>B'ʕo@?{ݷ˷:EՉC?d2@F #Gw|ŗAfc]rnC_{?|SɅ f`k| {\_D>rzo%VV(4N{Juf Wr6}w@{nɎj ws&ܵ[ayxgi-oM,]no\ʨ2^%dmhzz>_$_ޱZ~t\?"ӛ%mҰ61_E_mê 9/+|y:R?5|Ku7dϗ[e~L}T}[N:_oA۲oIYXZ;I_gsY'#d2MRiǰA ߳*xh`W} M͏_- >as or\rD|>4⭨=9\9MićDk[|\nVI/|t ]MZ/VڰI6n);mQxիHEX5lLco.\( ^m"ޢ嚯}ևIETم߼U"_|,v+H: *_چ/4OfOWz\|]-ҋtgw'?{rL6#bY;fv& wrX*x{UC Yq;^ujum[,w ]]n-\=Yb ߓ_(6\͆5vh[Xmo_~ ؋>a{]"[*m2} z/Qtr4~_4ɕrїʽ(_q./wʯb.ȴˍ -_ɻƻkK+7#>፺$n!#d2"yoBfVƞ^Y?kX(X.[xMg% <*Sik/R FV^P.0`藢$Xoh>]{O/R30޵L|B_x7oByۍW_(_6p?ptnsT4S_.goIo+HQ.|_6ݲ :i\sgP~qa9/>%G_TdoXt՗=R~xϺB!].-?xHϝ.}\/kPPu/X `}Ee鯓*/k~ FrTv|{E2__.6[+oWO7ROȢW42]*5C.O]Wˆ.\n%_B:xo|r$o~(?Qk=+cղiw*r+CC_3N{\!|Hߑ_x.y⾟/V#}軮S5 eK̎w/gߖ6]/]ܵn,(_tMWM7|U8 HOe\[ϟ(szW9x*˔fz_ܾRzˆ%.z7AZ9Y^(ʍ(wR6-ȿ[m)5&̙l|^9%'HKni>W='dy_ͿOJǎخZx^!s2X#Q/[1(7j9zܳ;r5&]H^4J*fb4Na~n;+ɱhwL{~-O}.JsքgT޾j4=-{'Y+ln|qHKSWmzϮ["$-ʥ?\"(|N<#c"=V&rwEƎ$'y2 a}K VE.[/r*t99SһYx_uT#O?GA(!9ߍmHAVgm@F #CQ]eʱϓ"ٴ˟W=}sj}կc0xc7lw%u9Klkm7zDF7B@Z uس+/{w?xpxf@^t+׼]-9'Js9D cڀC]>ipe ÉL c,dF^pdenu~3@F #x gu5eb>QZ+vY`dF;MfZ"nѯ[mAk&yݛ&=д(M~ԁ =ɷN/7M!qn>]Ί;;kEy׼},2؀*s/Fk{Bn?ʍA;o]=پK:{qy9~yd#^c +e"Tm7ʄg?x:Шl wwGQS&ȑg$+&cϔӦɘfo C%>g̔_!0d%@).н{k>_yC!X-G\~;}E/У9(zdCdڴ)СBtܾ]ϘDK37Q*ji~k&' (=J: seV4omYLwȭA.y䎕2sh)7)k?2r<1MtpLX(0[K?2x{uI}&Yf\+q q7-v~܁d2@FIB=ʕj=dѻk J.h}pr8$zKe٫'7&}=;HpF,IxptU>dRLnG,]xNynZkiX9sE\$ʽ.joN;NN:9qRi=V_urqv t0 70vZ$_n=,#2K./_g*'Oŀ@o2#7}N>-@o[LRab \ڰj[A7bxgk&uzW˳g4Pr!e2r? )zvє,`k~@$F9cE rͽsO;_ |K_YLNdǿ$ג3v|:Z?^۾S*2f(bO<}عxbO ʥ7 ;ƌ+z|Da[__un=Oz|KSYvlw_cAuȣ-x^}ʨxoj@S#ٻس-^i8Q1r߃ɘQ2$}ha;cǷHniĒ7ŧ|DxN`^14˨^{3WƷT䡫Z^o\FC+ 2@bnR@F #(MmcdLCt`IBJK~^ꮴx:wD_j_KDj}Wx|E3|n >],i= 7-{Џ>Mҕ68=xtR޳mC۱@dVtrGg&EoۍnlѾkl6 =;a!-[x]MXsd@$-uz |"E'M v͌ZzِŃ@0·RNFniMܸn'|b<m} x}ڽM%Iw}~C:"T_L%`Zlv)/FŪ6AH |#O!*$dd.d%4T缴Z)k̒,b*^-b#\/†*YcQ)P+|XPhᨃ)@idex"|W-ITBu&/kT,!|n[~DQ*Kʫk>AikMh,ƅԆo^|\(Cb|UHXAW3XCL]>0:.A5ne 2?Z@UH X5Dz슊u ?0Ynjc$:f+K}%ߖxM|oy$QΏ4*h7fkB@?PA!S c w&IwAx7CEM(D\8Gyix/R8)Pu Ffa(TǠ(q&YYNw6Zl@^Y;"͊RITiǒ:B:ndV1uT2Q?1hqSƌ" 'zޖI6wlU|*ڱm)Q(Z4m4~Z3 8ިbfF5T o_f[Q ]jT+Lx$%ZM B?aF#biڠ< IWQ]嬘s3A.3&dŤث#Hu{:羃Hܝ SU& ZYKUIz,bA< Kƭ]F! H7m9l=$xW~EYP܎hZ8~ЋkT$WpI*jtoQ?r A4b֭UkKrum t٘O@$_NJt dK!Qe@FUDQ~Ruu У7hTilK! <:YLPH02Jٔ4SdDbV"ZT6mDD]!+JF̘,IG6m6Y)Hi{%Ap2(4R+@]"i`[i>" DU;T]|u.-O"2SuB=NBʹC%9vG3@KiνI^QGA*JpA؅&t/mwdžJ݄ 3N:eaK'y z TiC6hL h<˹^2JWE&Bm$zz%LBG)siYI:3z xJQb,7q]!C Z\~UCCg@ȏ]EPѢLSz.Pm_7ٙ jN7j)r]ANY]Y\>mQX)GT :!R5FgY73)D5IbY!qD1UQm3,qU2HM!JB t>MH\:5 Z 6J2)Z54s&<&zl&x `ƃ]9aPa5A6gTEj~+.QRJSY3tyR!MMD UX`;֪I6ft -gm%,rj.$3S:Ɠt0x olPZ/K'P"(B:%U#ÙVKRU@"H|fJ.!$aA.7M\aϜR@!:^?1rgfd.#0y-rC3҃L^+ P[ 5T!`64Ta $b]?fbQr0t5"_LYk(e)BVh$ ڜ6tds/\1M*im1&=r̾k-ҺS4 9OYehA8!E$jBRAu} v&TO7Q?v)vnHMg܏ =_)tYu't;{t*i0* }K<StNM>D[S6i ["Mr)j"ŏ8Kڋ2Ev"b'HV1uG P29ľUWh"IPe>u6Y i'<G*_Lَu^2{<Ӷ+C*Ѹ".u?>Sҭ7sUT{2 s 'kZˢ %9PP%PFhmk9=6=֍IūNLMOLW ZF)D"fH0Fʥ ni>a$H0[M3H0]'SdmP{̳ܸy`e>FT2E̤QHL/*c"ëS7=QN1;uTD9"@ipY}nj; hv1Rs)Ɣë4T6+sT$g)#0L۩$v4L;Jiw>whQEnT fA&zE2-SZ!EueU \g`yZ@2oWb3 6B$mDnNˏ;Dw2BkcBbVQaL (f T=+Uu"f#LJT, 3;&E:"QG+1\LPyup 6'VFPjRb̈́MCY*Դ,5]%`Cs9("5MuhG;Gw(׀zs th4isDp濄65<2 }Êʁb ,VVn6P0׎T1!*m>l7Z2+MrS7p~h4hՃymcEMYmHbE0fPOIm2Q4`ЙTc ?jɲ͞<Kr}*Q̫BP+qgq/_1ۡvHJ1mltt :R( r9خ !J ҧNIP,$Mt}'x8uFT@!c'P- 2S5惛f!TdYi!L\tӌJeص@.}}/T&%A11C&Zb< J僘E`$2..P n<-NnT! LՉ YۚRQ^ZtIHΠzE DŽSڪ|%)f Q-&+tʫs 1pL V{(j lXrfAFrJd,h !0+y*YMS OUޡ|6]iD/SyGRTc.:BJǔaZ1SLX!C^mHi_s%3YI$zB$]U7j/t]RB=ِK \y;gOw -pvJjQ^d&BAႈc-_OC;Tt,왕͝)UUHBW :1t504 /҂BCBwaDqU |'&0 VqzqI# [m5UM$4+زNd1 'аAIt@Aܵ<EmJv~E1/CʨrdyPʑb>h nȱDȘ $O)o "* ( "f.:q 81SI~F9Sui竬T"O!^0 Kh6^!kۇ%!W,`݃D؝vzNjUU:3c<ֽZƋbi Ro~]QkHs@/Jw(_j߂=tr&9 ߯45ψ_) ` yD '@A-A=} pTcJ' ABg@ۗ [ =hN\'@\9Bt&S(Ҫ2$ P #u:*m[XaԎ!8nL&\c` (fCp5f&!v`, tX֜6gU?vQ). t@U|ǫ*}h=ƱL Xp6Yy.f=~?Z0&%\ڳ#O U$S;^˫ x%$n29y,)m\\9I%o Ɉ]IOA[RR.mPiCDJIAPb~,=RۮF4RJgݥ d&$seSX =_$[̀VE P $Vq=V-PkSEJĉAa\7?P3񪂯g'r;tV * v+<X+Tyr7.g@K@rQtC%]Lc˘ ;A=% 3Ap^hœf˶VoyzC] 4S[<ۯwbf3L;_K¨u ';M& 3S"E(^Wz}Ge%'- IDAT+u6B #q\a-jhq4Hlr#{I~U"P0.y++`BC۵2lʥLcCxʮv|Kp=8&x.c@+<LF2~6JQ,IpUŠf{i>Qȭ :| Q,t5Ȩ?-TFrjBp#5y<]c)4ruq1$1c3c΃D<IOtA7?D:*&/p3fQˡY;lf t EiFn֘^ 2&j8uZ ES.7s) XR9&fDbV- \Q yT 6$EE?M9 = -#F]@`* sL;Rp0s'Q>CuPA 1#' vJV€w| ji&eY4C)E)Jw&bWMHlD! 'rVRBdzćX;S:f= ciݭr*#P`ݍ- 0fܘklW[i׋[޾i|cf3C":bbŶ1PVƤ"8IJTJ.*O0 ʒh6 :8KzW(lB̈́r!Ì`-EIBM&c>LbTp^S i~dPXR5w}M)lu<(6&jLj(lQKoLR0 m*Vs_o17|0UJJUbO 5#< FJŽ}f I XRDP{*iNl _NwqƵΧҾkܬƩ3\!Ҙ7uUPq:n9#dlXKI>H*SE^%>z2LG:6i:̘]m ⒡E%c͆X c) Q vMϺkwYk>:vi Hi#2B@wlh;$ `4@tM A)mSӯYfZ]8:?8y[6130ض\/ʮaI/ᒟq9xO"B>]q,dvG}t_s,URgܱ*dq9H)aG4~ZXtacm!' G!D断qOPvb~47>3bvCl6ң^Ğ/!8g=.գC<>KN~kvJӿsνvqX { ^f?T?po}Sp+zw*㮪 ɹdCJX^,ZkAUq%!ob3@Rͭt_|&QTH }e8vq\k N90&Пn L|AsIkI.nW4hΕ` Y38W3⮫P'k^MZrq54KӪylp| ]>ό+气r"NmIq)el@0`:u#Q\Hwq(s<&/;O_^P`D'3q&[ =uda T)"R<`Ƒ8v"$jVt ctp9MLTsaciLl4EHPCId|Պ*\b0Wlޕ™yj#.H=ޔC{KcWύVka+ÛĉpRs`0%~)p;up}b|{ ޴!8Ľԥ7bbC%Aڳ@S1Hj6Bl/ac [c[8 0W ˸hQv8 nPiP~(mY6'[Dz$6WLRL@%*+ꀱ eC#Y($' 4FMRCߝx!;k͆۾Ofj)zbu* (RYN/1 pu$;mÁ?r7pyegJqeI S>`Xm8:!^:~pMWu3b[`c*WĄʛg>5hD_\AX5Uw,%NKp\>0gL7~1>\0;uxR@ɺ趍@b: U#}kЏ^YǝC&/dr~^'K͎^wBWnL j؆J`"ZެG+B8ĕȶ] y(@q3M-56֝ @ɞl8ǽTS2&2s#^x]\T p}!ξ)X:191ӎqQq-D~7Zr&l4n U,l0 ?V{=I{ } цpI5 iZ|ű+~x8]KAQ%«s^\Qk'%g=Js tT;վ^Et>iG)@01DŽX+ڀy͇_͐sWYץυƋhCEޠ WE]xZV[]|E.^Oo 8̗Y垫e%Uן~M}O^|WtC'@4y,g=3D XسybԧzNTEF~%j^t ɋ(Xǹjb&d2CGgؼ{ݣ ʤEs;1#C6| 7KҩvxJ)A_ уαsqk[J&pԐl筽ga;DGՐ} vlh?옮Wv${up):gO*9:78d_V!r<=%HoY&PGkwGY1uBO{g8WcG\9*o̭hP۶qk+WÙw!]1&O3GBnL 29ƒɛ%7GVLZ"0u6*~4n%Ad hMu%d ށ'zn p{3Gd2{B{e0rsY|tHKJ-Ӏx,ewa!(h`^P(+{X ∕H,a9e3-\Ds-~v%sn 00x@-zmoJ\9=X5Soœ @Sl=&W7?$Waa8f9ӆQYm pET蜌G'rZc̸quI8~Y .40dsS8l0;,tڠg;³&B:汙x_3&&k $v);cp8cTl)TWA`CSɆE 8W`<}A/>&7|և Cl))hWKS{l v߸{T + `:і|nZ f^F٘jk\'FqΐhI#1mM '!Ǜ#=Oym―{ !Orqa Q^tv$1!F:;gdRei-.f9eI6! 3䕤e9%cVr[89;UښH }[}O9A"_HAɼ]`rrvWm6tA=O@EB-t1J sR|-uf%D.tµ[}60o IP0#swnT 55W5l!녈`ãW;[9P&zH.5;·KS/ĻMKs `Csj!JxYO]靚qć^dh@ dޢܓ׵dom+ςIXr1!#MlX ,3'L0dZ'=xYmN臇b |2 X9 wāio5:;sp%:cvo&q^dEj .Gs|j'9g{SLVy&~70>k$H>2 %m] :S]3_X d!cZ&o ޳WX _*'vgCwDoߖ\IݪQ𳆌1_zex~/@L8il|1jb<7^x(. dV9%&9h#xË0/Jc+Ћn3!8a *uRsm!B u#Q8obagSwW͚c^'cg[ydv:}|c馷l^嶽4GZ/ZtR>WD;"U|JgnAEep4ls5vJpS;ڙq2KXd $ZU@k{=HۤPso2!6C}(;΁wl Z$'ގۀ=FBA c[%Nם:°-LAX?2 jZG9ДY&$?ئ p>y%k].k' 5xq,% v|^_3y*Tpzd*ӋRј6yK?>?l6Iψ.G_'ml];'>Cuavn.odZ1{||v?wİͺ024ol Ne toFW^6bYBjPӏ5\Yڽ#c8k@۸`۬& qy%d x:T8NID< DfSCdcXat]Țs"lN sA1\W"vO\K_9570inFJaŋ=ռ>?P~5owNFe'"]Q+T%zmG`%!'\muڈ9x̴P݆_Lvu=d,n\vkve{~o.xJbvv9K1yaQ  Mq,Si'r=5q0|W7hkę!c_C9HSE7YL'TOA.Q8L#nt:ܡqq v>j t;u 2[’T(ޖs3m.K<{*R mS!!!4(9 hj[).73jǜ?Hʕ l·7O v hHOnCKc} vLۣ+ۚk1Fe/7մښ?sS/>:WI\b\+.I<)(څZ`o$& uYWd/W7w:]TKHAjaß$PiE b֧a)#a0eÙdd*8qW4J܄ߨy{[7L"ne 07e};ء/u Ix30COה(Yt°gr$1't<~@3!O+=S\[2fG]F9AfauP^0aKgɄ`<Lfĕ|'[C8ںyVŖ;5N&?ˇ&gck3hGVeπ0{ & X}7cc睅˾byb$ݸtbi->[>ŬwNTh+,3 _xQ+f"> Yu|12UN$u P"};mfэ|$/ %k:qnl`=ȐW_Qr$^4Y0I^w䟅.eTf,eؽGxђPt'QK͸eBe0W4\#ރ M;,` .^ Hv5&xf1cB" +FXJ cH1s_<' IDATK&QLWܼfn ME+tbI̩[v_=\V-]AGK [}F;}OqoD߃ rW\}gy#6N64*b޳:@Y3!nZńY!?1֘>yȊmhSJq^VXG8|#y .R17^_o~{{{?p{˚vadOzs2OyȁSZ 3gSؠw;;evg鉠 Xֻc.4Vs5Bny#z&?71y!#2h`rhxud^s x$ o^ָǓzkM bM<"H^ٿA:unh%;0P6$O !J(Y4oܲc5{?;v ߔ y~k'mActi^LڪǹKyTZ-CiC}faЉޱ/%ar5Sl bA>/J1V?nYgt,ݟZF E7|*,u>P{ 6ϣRC46QҚlTM%Ѿ2vNv ۟+6?aS֧Qܦ4|H;5-پZHs<}\t)zjŇ0c9ˢ}# J'Vpf3<6CrXsI carWTF ff#0r ҃ގ+.2,<ϰgх_ڵ$V5.ٷ ~3`FՑ[G stݲ58:Ρi7_pCrg71&.vP[\<6сqYrLh:KikWQy z;Koe L~#Ĩ1*4x<^wBuٳstUˆfj͵wWGYo5D昊nH3!"ˮ$HP'y6l,\* 5Xj.\[!:Q2UG\}gjɆs?5iί֕0 T8'1;#Ys*2~3+!XlU֚\vtx(òbP0Of` f4]IƩqjy9R:R:%^FF8hqS]|C:6XmnjHqv mJ@8l]ih,Gcߎ^BۤeȮ,e+z%=uShGqa?uL2uGY:g柉9T )隴ngѠ2LaQzk3ܩK?ܾ_ʛ|/ß|SC=coZP0>3O u:Jx*`Rvt 5i+z'cYFp}wh}8x֬0^lS9raKCu b KS{{9&h.@G; {5|f BTs{9{3Ek 1L'N>Z{[iض 00Gy )3| \"m~Cgk 0rB [Wo&Dyf-l$169V#!%{f "wFRy<%n|al&8? M|UPn(x3uFkz<(J8ɕsɦ~ ANo,rٽ1ڳk5O،pܒFAM5pxO{Kyd3ul:l3x:O{Jbo&g|+_o=u9g6EExuɗ{C6^t\`9w}>QsyѸ~G_^m+"Iy/? ^[`80{H|[!CI'ڐ_WuGW.t?nw~÷/~/﷿WW^9C$XkN`ș-%UuL;  %>֐Wц hy “t]:a On;LȣZƹQ[LJ,GtnW?5ūATna,)xHˉH KI/%.~eHZ[S6Ǻ '1bX aq'=^2,.!RI.Mf0!c8SE`vO2fG޾9/mIel|ȚS|JEϧa!Ͽ[!t^#zmfXFqc7tu?5\rLs+qȵ7}g:6S 㜼38IBS9dO!́JаN#.b346 ҟ :|E3^(a%C|΋k5Y5Q8o꓏S?۟C#?KWo}wdЁ)G5g؜O%rZ^bwteRa_FԘlw26W'~YGbLÐAk\Dk8(33,]`UgH Kkd8AO kB*7Ch6Hb ?`|p,&Uϯs@m7M*.O6S1y᫉f8O'یI_'vv7O>}~T4|L!fyeȧ,yYRP-7ssD9oH?cJ3 ފ}"t{+6-*>VPyR1R'WMF$N$gs/puQ^\o?hjm%xqYGmfJȬ {.8=/ `gT/pvD 59rs.8+݄(s>S|0k.gM{Qq+$cS);[/r<ꏭ n}^x+_{Mgpz~&=1tDK.|*b| 1Qp f!G\ :w3"edD.~RMҸƖwܸGWUFŲEAw44o^9aϐ\Z jl{ ++)Z)Xɞ}X%Ajܢ k'Jh>w濻g>{{o|o|_|ʷy?z{)ԡc˝#`ٕޤs[=.cvliљb(/@R@0};Iw,/4FO~A#UI $h.wGe3s5"}as”(' *:`c U=ӿhg+,M/u9Ƿ"fiv^"ʻ\6ਸ/CGeRU9ָV0T*, +uEIp`;bq=9Ń($t HLX%O7Bbʎ5 ,~I8<ְ'8R}׾tү|1e%8?s{Ӌ'^O'Ft^rRs1U *hTj,1LjO@pNp5)&biUr}e1u:J[lg,øpK:/+ r>4́^K:h=E6Y#1Gj(r L'IY9q5w_P&"ٳC3d­zEO"~zS*i\/F (Dž\!Zmak uX=1f;un_ s;Qg,d؋'pABaK/'6)g6xQhh^>'=O'5rxZƼMtZm.@6F/q,FFX!lMsDn',W^>(FPs˅,3sZRa<EF쫠N ~!c6$}Pg]U,jӛQkSf0=ڡ9ř@9.YOp 9Ԋ>̖y¹&m ag]U(|dIZfX91wa=-=|$Yu lWձeىy Bh!+rKQ&# OvZg&.wMN'屩ޕ"e4+3F-W X3 rr;cUK9nMNya?㬥Wn<*}_\g Sag>{?uf_K!}xkrժޫ?׸eryXC. 5]Ϟ▰e@֣]zspEXEzdrͫ-K~mfI:R΁$~bL/< m%NMe1RBIFH: k"E ۳z9ʃwLzN#C +z[ؑ'-a+yq[PXSAzRb G27ȐY=H8i[.. `tn#qo|y}iu`χsZ1ų;}APLơ;"#ʜEi( <<6Ӳ\>'dGl'Sڣld 1r:GHSՀO uLw 9+ƹ&Jŵ1ҷexݍL{<σ[Y͆f=4*0yA<[Kfr{z6,w{I>ww~o|ۺ^~k_n} KnT-s;'QdSOOmið=XY`ݎPQZOڪMoS0n[r60I]rh|lbSƖ(?!,8p1yVj|h CSck$nJ=1prЖUzrO%˘Х]%8_R8/1gp#&Cg٫+]'x67gy|tw67v:Lqhf22ZͮgQ|ZَFl4r&N;{u&F"3+ybbؤ) 9/=q&^gYLKҸ-Zd|OBtSaXz=dTPSYـѝ`G R\U~ˎG^El@lٕrPQ˃V v56)/,a30s ka·l25dMBTh\wXvn%# e O1WHT^:I6ӵD~—y ?6.$6og{o(%y/!3>b i-|#c]b>πl1upZ⺀ DZvԙ`63# @=qq,`΅u&J@A"Q#6؋ڦ;JģQ;n8oA]w]h2I`r657^%pgC"GE7NdλZI׸Z5c`ّTq刷B1uO߼{>p{W_~ C?[C?_ODzḱ-yt&gן2 4SKPg@#$ړ:AUB~Q1Ǚ R퇊nLQG@bG3w]%͋bClLlwNe PM' ΣǡX)kxc^^>PA[N){P7r2)'k\$ =mS!0?z@X^ji"ւ<+n%ͧ<3Byރ8-fW[2C_ZyNdU .\>LFB0YvÊ2CƁf`ԤbM/B fF@(D2>9Aϗ+y+|Bi SK<#c,x1O-3@O? >iVwgy#xד2$wʈxZ׬ =ĄA^IFT6sかΧn5;Lb\|b'Mc3gT ldd"F']؝ʻWOz 2{nxh1YN`yM\+<A6:_Rzn zQǘA`o?>^ޙI4soWh+,q${55SaVt&5?Yx Ε F Ȳ:Jw67J`/rv>/'w2GYK_~r{AK_}Cs3FRHV[eQ}/y(Ӳ+YΩ5- ty߻_}5_qʗr)})6cq{Pe7CƨabS[Ÿ虭9\IoMaK~^o}#;=2G䗼V?3~|{w@[OGThU]OHK|r\L %$L DEaYҶ 똢0 M‹䯄Lf<X3h\= c/BYgxӭv׉Y0ZVClkrܛV+hj2Źj;`؟SE ;v򤀅_Ʋ*vsTStѾ$SdĄ.nWfa@vfd(Kl{τ2'ѩ9!WG cY]t|KHƠ5/5 WEB(` ~EQ%sH͝@ a["l{g6*뎰:an6b{V_ɢ0A_c'bkZ֝-?_F?x1 +s 7Z/==H'۟c?tr? ?g% DN3&5rV/N\믯؃ط3ُP׃[zN[>`/|_?{Q;ͷnWbOSϐ|C}}ut+2CAe _/Jɼ~ V.@]7\a#'cBcC 1|D8hyBⲞd=ú>ژx7KeX&%( fg[Z3^DSLN8LUP52"9(ڈmmsW +\ 0X4.PYgi9D4biϞ Wn<~Wp<٤D{U^^|^埽Yޏ~^K$ʷɝ,=^s)% O@ϮXj%Ee* G${H͌\ ~DǞ* Z'+̄J-$rat K=Q(m`nGM'&,|z˥Xޡ%CYWgX&1K' 3iE:C;Ps4E<60]9 ދ2/Ob9p DOşn>RY  ={u|ӌ?ᑨ\} REzxva xA()yR9I]g yp3t k OP%+wsH1y|[: +jrNxjݪџ8ZX5!麯Ak)dC ?<-8cQ!?' bt[pq]P"> ݘHm{oX{qTi@0.?*߱Q{X5k/B>aon8*NBw3*U޸$= g1#P_! ԊߡRȍc_7,uIPMu̻uS<Ϯ8 k"'Ïn_mfxO>|bSyA L~ccFvzL9-aaRP2Fkq>sml5B[|A޾[('!z|2~#yQwJ9^$2Cࡲg&VN/k530㙤V' <}~ }2u7\#;_x /KWf&R˸6hz}qmPYߩ/Z1,S?VI)Yt;v{a ч<)iΏ&szƬꁽ; \aPDlz(18׺+EɅ Po$}{^]gX#ۙ,xXޔ+B^~_Wh92q}DDZYQpV~z&xa{|m_pgGӻQ8?jxh:l-}rԿe!z {ut49oK)Z>o{;$9WG5A -slNOk)ܯbw#/KZ Hu>y_}4v_0zV/|5-CR5I>H^{G&E>tIEn;cLwF"G\2xfp ` oHmW05_ss*wr0{7b 2, =`nr@q];"u3 1 ǃi;`}I^?]2&׳%lq?FL٨50J].ິ/ PgìZNkkqmv3yu%eԦ҃gbB}^X*}G8<[\㺱OȒk΅'"cc[-'PchDul=.\]e*LGlzp6p @;],[+~[ 9?Ӂ̈́O"mMJnryAޗkv4dLe#!}mOPk}tyƨ osAfDyIS|]?;?T>!_K/>ߧܪԐ7$U/g]򈪨?0mv\3+4Am8cԫDBCsk'zT*=73a\0B{M<|y>hc>0eX֤b ]<c$ D=dʳITg=#ɹ$ӄρ !LmP6dt %>QŸ&'m4o49R*bDj9r9`.R\L?PB&mpy=<䚸egG]@<ιu_.I|+́x*:V6$ M*H\uPK7QB>رYQ8xcSd1ScLeURf+ᨣ!1}zCV빲ӬdHmnY{:e"A)xhWapHS>~o'_;9T|A+~@M;<ٟ95FǦ0 cSf_#7$"f$]}Y. ]T^N?8j7@|#L681*A[ xkvWؓڲ RŴWƦT@Ƀ:Z`:+pω y~~I~勯?7~9ymPQqqb : -sBNc-}Lc˳f´a.6ģggX:^7SWbG])sbo~ޞ|~֕륗nMI?_7>#/D`}Sh|dݿ+Le־%< a=4pq-@ܖdc:}l_B@N-zf!2%#ުyh" Ǧw>y>R[搭'CRbܬ)=W=~<ޮ2gMc.n {nȣd:[^HP.'w}xɹrT^\;. SeN};2&obQ?ބ!Eی["e&znjܬp^UJXBLe6<ͅү}y=ڙd-sjJ&ie=%f&n=Gxr}ƴ4LxO},^$$}pLRifcc,CP ĸ[b&w+ׁ?,ly2BJ9nو1#㊳A027V"4dɅ-ӛj**Eh3{)lD#A)߮ln jmfѤfolYd~ބ=;h6wzCM'N}$] {.f] 6zr)8E`( ?Ծ9֜wb ҝ"9T[( r`r%XY\F7eYiGаvexR1a/ʷd=(jwʗktG揝=9 IDATx'FYiP̉%fv;A{7̒s#One$p !0uu9Ɂ@S ak;0j~nDB &ofI쵊Ksh\ؐc22K#獃`{N#V32?hGVs1|w'9~W^JР% %eƸ"]65cC!v3Au_;ѐ F#/t'aua%#@Ķ{Ju]93Znd']'O|{?GCu~(}[/س5] !g:YЙ0!a o)Ԍ3¨$g?`8%P'q|Gĕ~0 |y>n&Z*gRN=Ex2lͰp=gfu[51gDD:B:43KH 0l1P9ӤɎkbe0't3h8itpO~㛇?1nk*.!r;:QLN,"3߉%~c ʳ);!z̳kHPp>`ܖoO^xWoo۫ow_}s__?_t']G>o/?_wys ^)yKX}~d't>~rBzL]T,_L>D\Odط>-5 erRCW[C՚ka*lWanh%l0v~]8sRzhAA.C'|;ӠS_ksJmzh0ujx w+ t]$4&Z1VT~>ܸ ?Vkѯ|Pէ^ CC n&JN?9T(A m0b@]'j$vό;hE [F6kVA8fߡ#忠}-_ {&k k!LT&w2ȯbFpGV tj]?iLAm#> Az1dc8e Ğ2jI:u;:&st7ew9Rc A\.`G݈pG}H g#(J`6\sx  >Os x]tEO iXB 1pnM(Jrw:tQ%'lH.6r~/]f u8p!d&)Yh%C ' r!) 8ossP3d= aSruqPs ݚʻO{G?ڛGe}sN&229B JE8`QպtY媫NX ]U]F[VDEƄBB朜sz}뾞N]}w~~{G>gA™TY/xㅏ~sz[1ks沏~ Q_G^^\~'uy{>?|[x'}}zG&]pm_hҤ[T3dO|#|޹H~ң/}:c'MoՅ=_ *j GOz#;&ZO.ȽB4pV˻c~}?f[vwk~ {/?Ɵ<|.D<<jVL9IiNHtɄ~KN}TX#`n:r9G|>>'ޖW)ř,'Rɺ"7m֓΍h'%4h; :cSءC}o$RVl cia0A :wM^CtJ7`cl 9m";X8z-xuc.q5`S7ଠ}Y(e :|}B,ŬͫÙsK<̑GQmc8ƆIwxfāvnשԟ/VL!|[]2Gƭ7kNw#n>_oDXbCugn+! a,"c2t#YҳKF#=$DWT2)9ր8Tf\1_azQ\ fCJК#mBX2ξWA_.~j,y ܩHw*Q/ XM쏴C؎ OR;NJx @J#'Fz֊Iw`!dUO>Ό)Ꝋ_ LEǮYqԸ{Hr+DsEap: *xfgg=Qm1ZL  ]B!?%Ұ`(A ?nRڡYDxh O)vqҿn  }H{s|s w<2CI;N:Hv[g=mRkΩ 0@1jQwLg^ÙXG%sH{k"Rh@ClV QgGs.=1Dw1x'94Kqn [q6U4&r]T~SF܈7$[n]tôˆhɘ꯱mub (mc:}|`j ֟jftg0ܱ$V| /ZW>K&ϟnk l{j]y \\ǟ=MH7(@}*]~W~,{_Ͽ{N\U|'+O- `|'>~Kױ@F~Sw'zE@/_"gO~?z%)orsG@uktyk֒i{ӏ [z/Aoh?pȽ|ޫƫ!)z+r6c7{6<*=ttQᤌRvNz$; )غrĽ4夺"\Qnڑ{m~G^!g$[p1ܛ}hmqj&鈲b۫W#B)Q͍~|9HwiX퇏ac֋S9J? hK4SR"7 l?F"-?4';al |b0pQ=)Жop\Y1M1 $NЍ1RD:wi\_=I7 ׺p7z=Wy/[7!ꑓ{l''5a6sփ<#"Sy ?&Be`(a4g:m]pٓ[Z B:[-kӹMʃ9`+ /oQSy?u fmy,9472n7yֵ}ڦ ~,zD3K*/ xt<2"NDǒcVǩt\Lpz G햭mݖI&2怋wx8rrhV>:m 9B ujLK:@\Wێ6'F1NvޯD'r^AX&P,RړTFR0 Ǣ"ۼ))G^tcGO|^gJo7]~z+>_M_S?>߰|ޑngW;gzCMPBˍG= En@NVo_|LT\,-|nnkޮbmPs>Q7UЏ[?[nަ}'._^q/}>P~G߼iE>!_m)K,¦r\7#y=Bmi֩@h?I=&ejhp+uZ> )r7#f(.i=ִ&9?q0lF擔A[Lڨģ[VV `훻|&t+zHlḴ Rr58Ģ= ;- UNNֵn3}nk4"kBclLj>N'rCբkߣrDz`eŮ ˹UO>15E*a,kϧQ(+rMނE֍G01}9Tvwq^o|ߏ> ~ͯx+/!z}%O_ŪSnoK?tKzD7_aE_K>UC>|~;^ӗyӻܫ>+_tJ>=u򳗟=뉗eϽş(9W~ׯ}iz%a/߭zy~ݯσ<˯u\xk^vSU>ǝoAߪW;>pYE_g+쮗?q{TUOL|Əϧx_пxʅt&fIKdͼ8OSr3Hj z䫿94X/HI@ڜ9MَG jOڽ)تLV^PEpb!7S[5d#+n<̟5q?.U]:u2#q!4e$kCi}jg+}AGT4K?[}iM>8d^z]P Qp .Lɣ'K'ɲ=D\[nӊjiRnll!տ7xsTZ(##5]XfK{g!Gjo<q|'Q'<WQ؞FG{&3YӠraz[*V8$`;rxo BRS1;7 SPä4ؤl7vr ޚqЛ \69zuΈwd_mǓ 9"<:8*pd8d4i ؂vƀ, q=TD&TNfkLѪWeW6? s.Gs0. DdEc <'h?\\1$6'P#ob8;s"rmϳjgl6sgS7Atu^[zޯoMzK>i#'/_#?ߑ>gk _˗mGߠ3K#}qx?4@>]f=sV9sy'R.^_>u+Ыoܫ|!3;ޟ9s^_9kA*o[?py?|゛^70^{.Wx'= P^Ի.[~=}? Rx} Sv?ψyy/ Q}{~g./\xuOwi zDhc,Yg2&۽Z) `>.x NPpsdZ{˱Aj VmCuNyH/} bxGD pvƪUgs4j.0ʭlLK݋mAvxRRa!*nhHѳ9 fL%]m&2Hd㱤vWڵt:P&16i#EՆ=TC) O(3$37+&6yg5^4&SONd֟C/9Ʃ>kf^aa Eҵ01=d Wb>1~Z{kd88Au ]ȬQH=,@K2z32ޖŇvMK:D;n^oՒKㅴ1pmbNAI: fUukO Ɖ+W#;rp^{:}$&~RBg&`wu e9VCYp~`T'1簓ւߧ4ٝ^ouƽgCsпw߅-c4RekxD0|FNsBotl!؅junq#ޯm6畡jNŨ6.r5;1> j܄4vlR_ʠ6NMŚt&| ø\˜=Nj\&xI%?!oкI)gN+ZZ\`.[\>>M'=Ưh,w_wsXG䕑||.ew,;|_cۺ蕏c&7H:oOOuI݀}+!I y1 _%;۲ҷc D6Fozv-e9fsqRGLi1vzAFX %.~Ĝ㋋ޞ/f 밣Var)&c9*XSOJv3u]w!\h?3oŇjZ u 8@4wc+J g;}]MT7h}*+ Iekjyĩ;.$8fLj:xh IDAT[qdip6X[\奋G_/oJDŎ{lÖ5)aBf=Y\t5'nH)kx{>&Zn1cxKKxz?Ƅ2Т7Z.f˹[ i][2gy25YoσGp<{z[k`nFK@量[xホ~f1youqn{){|! - R)h1ZݸM@} bd\1qH|d9d^L:_.9Y'flʱR`ktR_ږYZ),KϢ&z̥̞o|m d5 !QTQGu˞BFߌu]Qaa1/eZt6Wz6rnyA>^Kiq )[z@o\Z[& Nۻcֿ .Q3b.;0er6XjYTycR̎83o|^ylݼNO{/.2Z}-\r,|ǫV ]@Ozm^M.AxCuܶÏc>_W~w6'Lxʼ]yVz Շ<@Y#Ez^{偏e7vW]̮+~ScQSZնOٺG2Wou7>>Ode{׺prmC7\Yj)LIizx:r)C+C2 <a-s@;/0uB V* cBXĽA+DBDN41-9\c+_QR#6񨵰|@o_kNzUn"DTGndMY=Nr8EfrkvVb'"].Ub% >Hv'kyQ&4KrފcN?IE'fh 66B{qK >QL=l Z+xO`ϗ9re㐸| i,mB\ӗwXMz&;=*v)й0fnEÊ5ƥslcݞ|1Y-a7;0=}$a1OMA{ࡋ mMUǎE95@ 7і-Ys[9JxUPr]OImZgpF޶b}+(_ K $c>6~Ap֣,@XMwd\}Bv-`Z\ku!ad:4]Z(:8e/\sދ.{7'_pL#8)|Dl.6o֙V?zbR&3.>{F] 7*?]zo7Sd^_iǣOՇ[|##c7{?GDU-~*@1Q?Z&wٲnQjomn5h1*ۇУX{J=<0PKzXQup^[bsRb)Bx!ޣ <:|v)]/>^~ϩx'|R>~[ᕏw A/QgUc*#7 J.EVaa}sPn?=c:Mx)C)#7$'ƛ>hpXv}JNqS(m&!KbbK֍$ThM֯>Y!өJǓdo ӟL "ӍTSȶ0hbgރ3`9R9e,^QTiz<`b5YfY̱4y ޜG]kz DMqF5PPK'"n,R5B3}D; c^؃iVrA]hmS+V:)i}1":֪u֩AF #\xs]1&oz0M?mQkHIV"9=dtg>ԓrH}o:s|nivKB=UUUd5.&!RCelrbHFA۹kKn]0XN_:.#W1j[Tiƭc7xG8tU6 0j_I<}ɺ ^:7+x iu3K{C'@NAǶͩ h;n*98<&uvۻlnvנ9 i/7BuYxZ J<f8QnjzH&ʼ"zV|#([Tҏ}uE>1 >Y1OA iiYw }#ysǨ9;"'44,ªfr̒Pil~e@<)eA'M'%e"^2:<-a]kǏt|XL%O,W!D<@L|0ڵTy,O2%r9T^MbzMSk"Cimy' +Jt'+G>ɬ)[kGUAlE=밁2EL]7gRhB4{Hfsu g%:c5Fp<-Y-.Sphw0Rɢ^{k~i^>y>9NRWw/m-k0z/d*bRY[1Yk6H%WV_ҁ#bĆpk6Y}wݵm߲7^ƓAZ!};.}0u"ҾONW?Bh?|Ts & v2(гC{y[;滱$YOۻgh~9ޯ:A9:GL~ru;ty`l@G<715Ccv}0~HqT` fĢQāAIg`*Ii;2Aoϑ`{@!p̹etIԨi2F{j}d:ՕY'?~pNYr Cu'pg;t 99BY*T}̯'@`p4 #VP…(9F6sc!/Fρq3ҵ-8)pP<"/q[ƌ(;sߏ&yxv&I&f@~LC@(~Bq)M=_8֢׾|Mi{ Ƅz¯Xlä~,Xe"`*FA0eTqMX1Usм-Ъ4Ѵ-.vm\ mHidã13Q#YUM52cӵIAo8ml~bAm;m^[ln`N ¼R= &Y,A-%݁U9|LI1@Mxd=_>ń.3>{@ O? ~c~ƃ5<-=۲a5=Y^uSN){/|H_ax~0Oˋ粲'|zg K?闿=oN:92.m[_>e"$봪knmɈ@V.UD+LQcȎ"*I!XU;lUs=U&Xc܏N=ia;{<߹Y;{rH&__`pY6j$㆗sj h/[(gB?t\2$񵰖<vD3xs.|W|7*Q 0"f=D 1BH`jI]vƆ/8wHI Hrƅ[~H³_uQjK/g\~WY+ ش? 8Z$_imN=>K?B5/MiѷH)W-$r~H zr|W>BoZCoW ?#Sk q1J΅i75>"|ΓaL]Qu dZ=^$Z,7Ta!Vޛ,څ:3蛐M)IS;K{x!φ^䦓>C7Mi.7 mKN^VNp&ml B~DO[4t5._@d?ׯ'GHʈqbG5w1yx缲aѮ/S-8gp8scf?ZV8>8VF~-J]]D9\m H35Q[;M%ha1 _أ_>3>E p:O|#/?~^8! HźQ/V'<ǟ}5y{e ˟V>}~xq/MHx/|v++fw|ϿDW0hxR5H?wy_D5\spAv꯵} +%~ YIc}YghWNY(YT57EY~IIPatI٨]jH _ݙN$w1ρ@*{?o7O/tF1<GjF dqؽg 2 lu[8\۠~rMvf\XOkDHW+ܘ0.GaMj7ςiW7UUE$mc"(3hRڎF^#Q0u t!AJgjLʂI1 `ÕNEYe 5w98 Zc&JȔ cw%cDVlƞ*Ζ5kЎͭ@4Wg^Փ󓎩=(e=qi=x! |@_ nm. m{t^WWp[~}uyRjz zǯҷ|/s_DZ5_mVw\ޤ`|~o> ͕e˻ noEU]>%O/RƷ{1FYr]?~Z8|Q[\>/7g/so#_t~/| |~] (ٽz+>rݭ}y?x<Ífߣ1hNNk#x-M8<1J~*zYPlETtwFI2i?эvJfe^Oc,ʭp ^KPH< ܢS`](N5K{ڐv|{шQɞy]% BWiz.k=+ ̃JxυЎ3$4J`wÊ0- Sb]n\8GR5YvR 'n\̻9~@F#᪠['x@kR뎨=$ޱH{Kjøɻ3)v Fsm|n!`a(=Kw?Gj*M )VьNCk7I_O^ 7Jpv#?דXغ  cw[`!ߑd7NrgA0ȷ94v0T`{$` !JXnJz^S  u}FZ.ъHT%1V}UW\7 &musfK0t^8d5<c7 *d%nyB촎p( IDAT%ʷT x6VX:2D?YAɣ[|H巂^W C/ΝX!(QvL"7 Yj._KbLF'*JR /~|NgϾe^~-x~7"?~L~R}W| Ǟt?;^ç@o/}緌x7_=ї]+;?+gc%Z7-t;OIo0z&1Vyw-}IY}.= y`$߷-,cdޕz7Ɔө[Yjy3x3?Hś]ر InY%^bU.=8- IF.jj$ȎjfYiߚVrR[?݄u`P􁍢"4KnπjoeOuL t]W?VenuBELԬ)t#a{lTe?3_GvO%?lZ^h0kf:7v+ю +*橩|N"$˹ӵ@$4s`6%M;FN}5@}r{Nt5Y⺄9! VC;Ip v"3=cJz=:9Mͺo) v(yC@v7 jf尷}sW's8ˆ740ot5.W8cx|, k?s*7N=x }. {Ko>3w/_W/|яo:Ǥ')X_yu]o.3>T֫$^Wos+8/~μjr\AussN!m56º$.`{aZv*쉗_o@RiRIJv1Ă)ڣ~Cq0nqi35@ocF}?k`?l3ʳ(}4UٟŦڷ@[z~Cv;- 9kg &1}|vא$yC|l3uaxK/_jFZkzۚ 벶AVvH7p2Cb|L |\4 aWb]mƇ]ocGT;f)gi;fFR[= kG Cxc(j$[>t d:&N&o\x`\3 8'!TxWU`:6Hʓ:Xt֎B۶mw 3Ix68v7;`Ǧ$wQUVXC6w;~,7rn*_ۘn}w)&Ex4^/*{@\Loy|۫~/~g CN/y~‡)Yz>;k^_WY_:d92CAzcz3v;o|_{t?oѫo;?D6m=zj)Bë׾^[>蛲nVr3.oy.ߡǫ> 95ˏż>xɺi?+@y?j/zS.o׏2M~*:0Ik03#ӽI dF5jj]~@:GyҟQY!dr[3)زaχd3oi_Xˠ&Cf.NM.ĢqlgY-|;|1/ϵ$Z+N`HήV\:XL\!9/\ịrW0E, ?Y%)Igp&#J\` BL>ju*qs$]TX x;@ ͇$|T?3i,ɑA (o݁H`z/prebw=lo2S訚kTO=kⰕW cя)s) Vx+W<&l :4m7/T!/85ҹ:ѯ=[s!&/I\M]5q;"tU`?)>w~՜^qR oŮJp/X zbJ9G%|h`sun-I4fBzN.,MYQWh2{m0 )G #"LJ[iGĞCCq֊}|ꠁѷ_ tgsgLn1t(Z/:+g,: +¬4.;&s; gT(z:GǺ`o߯ ]-(CZ]|vywȽo{|DyXe?JP0{4| 'qA; Z8+x/q*7#lwD_6|e[>znFU emn17~m J}nROv4I]W ?k1y,ւ?>[54cj5Dm㮰ceo1s sY m^8l0|ڝ%nFЃ.R·*FG*Bi~oU,Ne^kLf9zHII@,MΣ2hijn@1~D1o!n+ͫ=֙yO"K`'|W ?0;Cƛv0WG"aU躼c~}h4u7Xw2fF-`h*v?ܼRp327"0) HE!\ɦ5&zwS[gQrq6GupNL07Yo!9wŲ%tskMcODc1j\HzDsqx6dձ䑃3yFY2CMWҹ _ m ^]n02,=ls|,غ ]ǯAs?&藟ui}Z`E ϙ#?D0tȩTM\rbUT*E5/쭼bF9~tJ'5 6)1=慳0Zik!Ru \ʸ͞鰀WCx E&ƩpݒY%Fdk M]mk%hA5cշ~0F*Xf[JV(R{aǂQ-Xyo泽c6$i1=#O9 >H!ggzV,ul9F4VC>relO} 'H\]3kҭ L րŮC{>>%'e+kW p"g0< pC(d!';#؃6fG'4.`w|l7|Ʉ-^p#9b9fNwiaeqvP506g޶5XYwg|J((wvxZ#7:')nR 7N&-6Ԍ"$ȃ+>Whts Pۜ1FCl#ZsA/ >#5|t's?PXܚ>!3nۉ<0 #;e>qG ne2M9{ZU5@mG~Y0Bt'bѐ;Tϭ',rtby F<9w0M<`2 0WM^iIrf"ڍm2|.g܁÷qMRgޖBn* хv7 ߪh!ՍcYvV]hev$h+Nkh}ԉy Z3TΙ 0`6g?Ce0HHkڝ" ltg=8nޢ!ym&X(XmR{*͟,CsJ(3 Qo:ôg.JK)\|4 !e4K܆U]@6F掠<,<$tc&wh(7208YU`6aS€(5Ww:FVgTF /2=kͿ`vp9pYQٮIJ1OkH±jc"sYμZW2 qLL,)1MC[ 6D |xb⣽hQ_z͌+(SdNaș\6- ϡCnl鰏BDL_׌^MrbsNfd1!jz7x~ݖ\!ըrt\qKvylrݞFuNÇNINɞY:oImᕽm<#~x'&?8 (k: 4lD]eyEraNWd;&qq$$;hߖM8di }s56ý}5cdtp]jm|7R|,R˫8!3(Σn{su]Mfd11(Tn.<Q=jXG:b;pNY/9Lduy@ ihNL60 F+4P2rI¥wi i0 yX7%/US 6՘pјc4q]ˁ@N7 yqoZp <#Mj1.bam0< AD&g{0.ǴsxVq=C q~#J^EaL7Q46֑s)2(GX/b@ f5:p876Q+ՍX*Uhi'^rx xqSrV1D^^Q m %(#1GJ.(I87'Xv _XX t^> K pD7i ec[XdqW6<0Hc4gdákT yz}[Ӽ{hWs櫞OK'y۠m&NNSӨ8meu"CIF_ؕ[_GZ=RQ_^k|ܙ.T>+օmW&C^; I(gkH`ajwe)|EVvkᬢFo|U{6\}j+ RYy-. !PWVLDqp 9sv# ݢ_z 7˘0kXdo,Wv5וP_iomHn۝z:BۭŁ\Κ}l;FLjqp#A͘Z"R/OE08Q"ч=ju3\n@HIcM$rvv:M_Id6 H,򰌞 7_ȑGa>|`bB0#$SfL`ᴼqT6]$_IIMf' K쉃RiZ.F>@;Ʋ1|{jzsw썧(S #zY} :䱒؁Ǭ3$GIܶD&EZnZDz'L{8|t{ Lj"f̓<9d-me:ի-T[zT?yQQP;LSвDlmOP,0Bbz3|ߞE3q&ȒҀ#RT[5 |0RJ<9H߄7I!o/4إ1{N@05ߝvf8)&a j>RUN *ѢI\bGj`Q 5`mHxf b7|aR83#9[H yъ+:uw9JtVMŖa9qGi%|҂koO& IDATV뺃nj[iz<biGT8) 3GkT.t+͑O!I.51hL3UEEs:0j6<޷҃|ǦȋV Ҵn-16C[uRأ;!o-Ix@h+uS, ڥ6gmI GXB O]Y<})Fpy?kj .wO jnM: K2ioK2o+k,66Ɩr>}-XZ_פph"H.h|EPsMBܓd(`Z1lVT0l{1+3TJ^>D;N" v$s:hpYBsuV:axţ<7(|kS ^T6v993{3@Tx-s юY랾6!}rǐvѩR'/aUmFd C7cTd< 9uweDV)hX+5u0 k'kr_^]adN:9rffv}n׮ʴ)N2ۖ\.~zu-( _gߔ7lK5SH +n,ug=ɣ&=Y8(&Қm#'m-?*|cY'.${r o[C(܀݈}Er8=y¨棷#r[5Σ.uƆTD;h~mOj:cx\ ilm늺A`Oз,'%eu4Z] I۔y#sf{fͷQvԃcVkDrDRmɂ rԎ'2b3V;(R*QQzҢاz;^9mH5F; 6iH$Z>hIÛ~W&+h9M!SF~RLfa`Hs ?z) b ˃|4(372Wپ TO  `°ŁajRa.jD9xd (`Q]jθ"ZG_XiW|CTbJqFm/Lk cb.%o%)yN!11fW)~ܥqZ~xL3 I?2ExψHZpLox rDH? 7ܴ&nZkM't bDߐI3t{$eBQKA1X: һ?"3:܄DGZ~Xxn} H /&d#S5P'Ki53c]<8-p5b|NLMk.VOW&fpOd}T>h^~[s/SX*_DN軡Sӎ]3s'yx~sV;c چ Fɩ5R5%'ȽT|>:R(t>J_5MSt؁PSVTۺ>!*ahHT9Q5X8X(2D}2}Rj  OIk9Jh[ 'S2SoT]1@>{nזRz(GE!pZG1 ҁA݊c[ MQ94RHK.߉bp2)>TVf+;݂ ԶÇӒcU¯'o=Vr/G* ]SebFv~ؗ]pwSe =`"jl`>mjdow +5.iagM=jvp!u:YWK;qu4!KSm8Σyp_gt#f5.ޥُp{c¨Dc`j֟nGw,2(Cm/IX߰n6tkЉ?A'LR0R*M4}`ȳjq 5bդ9HOFqRNĺkeR[7==s5&姄kgm+tye `~&=0Tb?L9[#l>Q.Ewڛ ڵ52hWY$=Zk(2l)u-%Ex1bfn.kZ4F+EE.YH9{%'z)o5( أnm6 o{brFۃ*m/{$I.w8IDA3!ed& F&!7w#wYY=]s3xY9297 j8V ^{lgCms*A'Gh4M5tC>B3=P9ha/*Ta?IMS!n bܾ)|\ }ŻT,]ޚ""xoyX:m;x~E^_].:kOTq*hx_Bz2ɑ~*jwj"!]8=Y٩HU"~F~>?4[hcc4??ȕ6bƯ Ysq42lS->;*d"͊gFk VR~T\UovqSpOk?kVU4Mפe I.K¡ՀEJ'a#~,E 'e}8M =XpV կcHUa!:byVi߄ljm:?`A83ީWB?6zUMb |qMZ35D/<_2c>2.g(꣚JTT%'1NV+֙ytⰻ{yMX\etݢE[I*QmX=jQ,g E\&N.UdXW2got˃nYkȡ_:Gƨ)o&j\G~Gz^{ lb,bf,2_=SJfFvoņs=Fwmm`Ry4Do;`է.}Ts0/bb4 *nhب`g  i.Vn6:lzN g/ оЉئ&]Љgn#eU XsgZ/vbf]+$xTY_Q oa Ǭ ~Fͳq}T?!;NCϛ7z;:ok ś!3T*bC"Zb2h\;]N @,,r1E!RLJ:Ҷ:_q}>}a-EèD~ߺШ\d8Y7Ǧ%D9/y|O%`1u&\(/+3m'kiH"v45ƞ⑐[uN͜*Ы" JZk7q:~86 ny iRϩ(O>9T,9a]5c^{-1obuFL y\1W~4QEKQ4{k20 ~}hl .ben(]s,*6>3; [֣zRv j"mqnuw 407ܖG 0vS:3=!NA}cGʅQ%ZF6m޳-LO QougWF'౱]Zlp\Ej|e5ppαs ʓc@ U͠uX;ƲFi"0nbnگ'0[|LxwxDs}р,7RW~t(9_aN:ͽ`ں:lkLz不Ֆj7+36b-=kQli.H&FIyYZ(:^=~i^8"_vjen+E2mD8lx|:wJYcvEw=FM,.'!]ЁzbWqs~Q7 k\y2Ϲ8 TXv\^2M;W-lW!H!.6b]&𘪁.<;|mkzVѯ'JcQQW] kXНq6bdpTd}`j)MO&iZFLd,as e EK|y+6vXsVfWf#lױaUPɅ֝* 0[(o $'! ֎ޖyu(5yAשV{zj;ӫzW:xi#c[ttAH]Ձ È~c|Ry 67C[թd_)6vpm80XAWo]uQ_ɪa窌F>| #Ot!@i)=e#8@E^~bL\t֠YRo%፣59xF#Le˳|+O]yfgT;9p3!Loqڡ?^"fuӎ'?KHB?'\[3ɨ]oS`#6%^m5K7bv쐠>țh<; r' ;ˀD=SY:U P.<ƕ_ O\:He&}Sk3}aĀYMD9;rWhJbKC?/H@› l1刯KC9)kHa߰Dh5~HͳsoYkψÅw<܉Q0]۾LBjfPyDK>o?T^pi58V5[L.x P[cX]cL˿:^YOdf S /CG墏UyqB[Tf bg4NndI8tKT`IJy4籴s`iUgu֬o4t# $}9 0e~qYVb/82]9%ᤐAA"`g2\W.<0:zB´\#ت3Z'h"!wUUQUM} & IDAT3p^cCA2-Gu"8N>PJR̝PP&DX~=wW L@r~Jnkr4A#i;T m`+[5W5^ʃ0r]F>yaR" 6ۻ/̄]6#?mF}c`|c̉44mNk#[V!45๦ϫ‹ P5!s?g^Ѽ'Ä?_G`)D;i^6rUaq B ۩4CX M|"Eߣzs(uM1Hq""¨je.:y,O[!}*ohe9=Yeؿ l q&Pٰc-;9φU2>:lgc1AqSsD@56{v@" ;s1+Z2Z,+?!dàmF& ϭ1PM=v/0sʻD`9 {SQT(S6.τvLyf~ a;@:V6 ]x@G{V!GGªŮ'q= usv^i648TiTl*SO@׌V8w[yZy=b{iD:h>w m{2 J˵DТv*ŮCxu&oC1X˭XU[Q۸GroA}W`W -#w첒:̼յ _[LcY.-d;2rN @=uf.ݧZ Q6ue/j}&/V={1꙯j˄*-ٖ_+˦ I h"ܵ(g29(W׾z:)c;ZuwQK?/wVԙBZ +^a )Oէp ܈ح :5.UqY^jO(?y4=_/ ➴5I|Gw N{BEblo&9r>p@gݤ(=vQMOdջ;U[z/ң5]~ִ̰TVq mj}bgO*5ywihaL$sQ8qi|ҋ&siчgy鰍rr>]Kp_鷟i! Tׅwi58/b`.;(Xuz\x ]3^\ 3; ᬸí!^O l2.>`׾յ/P 8dP^RDBL[(9ǜ^v Ut_a<+|[Ù2jg^[sAӔMr4Lr^Sb l>x\=4AZW>w~4T] Qz3*B{V=%X^{Q펈y5"xM}h!9ExI{9&TqSD\iB^ƍ*kSwaC 'љ[Vl[U0dƾ"ʡfQXXdo=N??ti&1׮jPSW'G.:;>O[ P+.΃Cvn&?nmN(*/mȲN{XN>T> S<]/تoNj+MSJ-MLcUMOwзfcS!t'T hIxG'}qC>^0)#\g!iB&cÈa{'ۦcyѫ"[%~ rEo?mq2ZW?Y0kNzyO;SUѓU}9n-K&.|6\eKαo Kφ~k W=p(pl1Ȣ/y5U}? ^ 52W9JʞBS kh Nۇ%-*hv9+Ѭ]=z q1JrEXO\@4 Pw많i7uΣo+ts`PpL,6{F3TGD!ywp5%ی1ux}D`@;h-9g3Y*4U7_1pW|͏)1cSv܊#٫s=à4nr'wͻbϺ9Ss`HcUK&*F\am3m-bz?Ug1Ikz@Æ2 \l$3TT~~3'd:;Nإ~nho٪?fnVwM~S5L[nPzܭU?ƨPe1;a ]6whc;62en}l c2`=im5qV9i;ƃfn9a=|W: 6K;nQ][+\*^aq{-^J2a%Z:;R~h1Uul8nM'^?wr1s} \8e #Mm$`sm]2v pm=M>ܲw:n ",7|ש+&?ǿjLV16kVGӃ΢k.v|xJ/3dwQ4c[E]2nh6猫2=sl*.+F^+. }e=X-vB3|ehXbK\ڨAǘTȰ^dްŤ1wbLeD]sXuLYZ.v*]{NҒή[?iІJYz%zMr6~Js&%/.oL}{Hu&9564ךñƳ:;[8sX. Nlp[<չ\C3+ 1Frԗ\R'㢥'V_G \uPńa[pE_I^ ieՌԢ cW^( ^2H/a5&hU&tN-3:}"q@_%W&.q:+t9#moys~g;J^$w6}pwoS~VwU([ei;OuM{ZScqU܃h׭+?).詬z8`W+ 1?0%mBjb3;E:l]ʱ2U6;D߰#^N4KhgY{YYVdЃߘ}Tǡe,w }1c9Ft>[F@:03o覨`vnghETC}nͽb`Pcme͎p5S*HЎθh:yF RNet,Яa5Wh5ou峿lݜU\M }TxD+vhqnS+K*ghShi-NВ. Bd?8PLm}ZC2&Gɯp+{Z#H VHO&6J&vTi{\:JN(dzj ]D7J/vAz"*S2 [ٕ[HPQj*v^s8+9ck,poY%oٴW|Dm#:&vdurOsQ֐-cjk+l[*T" hE(i!Bh[1Z,?[7hyJXAYnTr-_뼭}z-S}'%qˏXuG"4auUg<=|Oi[>&Oߔ 6TO.OWOo?',:~_ w7.߻~793s[蹽e:j1zX;?bNoO_~k>=/~ٯ~o~7-(.xןKeqD|o/߽Eu_:o;\nuFjBva7؅c6X7/ qڹw6sXmoS3Mh}vGXfbxIsN6[G_ԟ-y K ?#61araXWwvw{/1o`5W!q6gTbv!'?7_O_a!1u>[_Q H,@r"D+?}߿|O}a^M7D>WPW㯗֗m͘ZEN%xSeB#zF˱d4s3F*yzs`׍j_0 NKo[s-c8?ѹ㟳ms{us5zrc 蜟w,cclJmZu=u3$ʹ;ս9W0pNp7?ቛ- D*C yxz_}ݜ̋X۾wn?OB机w;&'1؛{I}f#M:y/ڤT (@o9|cn//ZsFdODWu\owsL܄;9Y[l2tŅ7&>~+~էc|Co||p8YM3m"Of<7Ï-CuxL"CN@c<E]4zxö7ζnJ1}sr_Fb[y4>Oͻ1t€Oy\8ԎƒͳA |<\.vflQ | d Q`)0/i[@RFakx^%^Pu}n7G9wܘ[)st-N[?ib]*~}K_Sl^Ë/Y1g&s5McoIκv\N9_Dq$v^'! sⴐ@Kj()x\WГ|?oq[ܮ$} 濦ov5_lc̛/?ucC~w uCn<*ρZtJXSp WL" qo;VA1PϝvUz=V36dz"E(k@>8L)[;2s>A\/ tߥءL|B:ݤoR 6ܚ'25ՁO=}zI,ktϻ'Ya|N3ŭG 3cj3s$vƝsw۽xc.k{5kIw/B(D|uuL?|S:9~X8%ɬyl3c>=~o[7cl{i0l3!Y v O $mxM䕱0\hQOŎ9Q=}ݷI@.0[M_;n;V 4bЂ_) ( d]<'o<߉-˺q3`[~ qvaJKkr,\h")ȅ[6\-ugo) pS})B ?9n_KcgxV-OA2#k9Fik=rO/N( d]<ӧTF^Ifsx|㘾kb38ۧ>|&V *ڵ^;ùG O׭_A9xw\<7Z;aʎy&S3]n 78` &(_ d:ޙ'kɼ19˱m؞iZwK\3qhxnύugq.<O ;v5ڇw1Y d<կ&F~Z#}qmgp&lz۹n:vУlRgp&{9ܶ gqmU[u #m.Yun?5`w&|ib2ǴwG;K)6p4n+0|E {9LW Kwtq"¼}vN_!sBGn2lYEY^N_҂{}Jn|%4d=?Sp :OQR-X}ap1Vaqpt/rG/Lbu.cmJ9J8xع= Fbn8gr{bߓ#(^@ -AQеf]ز ێT8fvM gZދ]NP1?rI ԡel]9_Þ=[7~sU&sOck9?yPm*ͭ(iF\OOQ4>͹sbc:Ht,I?[)qc (~1T~Ƹ?!G&nggCqx\ۡ[UZ6C&1`/t@xYo[1^XxhiHfq#o0 iNhUjab][W9.Eזr{#X*i8֐;-cnTWm_iyCw;+ -+ygȁ;OaA.wlF4q ]3GXQ )ȯJ %y}UTWk+=Ӹ߭nзJ}p45X59]|\xۏ8sͭ>nё?|蛍`ٿw;8'~[8-DY4.+|b8?|3*PdTNݍlحu&玡;+Vk+e6nܹZomlx]xtT !nWn9. $ DW)ȫdKP_uCNjT7v<tsŰG}wŘܺ;0;&\ j0tv@;`7] i<"F[Hu^1!ބ"n%*Z~͍ fݫA׹} S0҈ Uki]{-Fq;'#6+Gm-âBDg{Z}P(Fchs Zޗn>G6VbF-8n^,@zd\uky}vu6nw_кdcFD:6c@6%sx5vnIp?+MUF] Ex.Tf߷̥ׄ_Uu-IE빽0809m֍x{1C~o= s)61 D-kb@|cWO5W#-Һlc^5n 3s vJ팦LË:̀*(pMõ3%_ z IDATf?b{w#nRO6f[~c͋v<^k弯&*8n􄖓7=)ـF_xc>jCGkj;8kZr;jyqNwYMAE+7Y2Լ " ^~a}s`H[wgw c DY|fi*efYo2Ns8o@ cߪ=E,C7O4ȸ)(1w'Xبa OVطں#X> EqcH~.&1Xk%F7!#ČNw^(<$@. e*K4 P ˭)Vuvv'>WzJkKK3Zȡr9؁d֠k:iQSF^ /z[>[ܞmݜnHQL{ľuW Urp.|8gs$h?Ezؑ{ciÃiF}FkHzsso>P0)ns& 7F^$8raXO-ףRd@𵸒)o͋G,x̶_A1[)nXvK:{̫CmLKѠf1vֲy=_h; 8V/ݔ~@G(pyI}W`S57{4ngȹס:F{7tCϛlZf&cc1|pu3qtmU07щ}BFNr: 5w } uW C߫aac.-d[/ tEOO9_u4du4/?ç:Ϋ|2W&6uXJl5[U|I`Ώ>L"ɵMys%33Y@zc$;p.;p2QV oZ)g KN]ؼ0t37~4-#? Dʅ'$Q緛vop=)p Ls]^AkS/5F=\~ Z\jZ@ԍ^"mQ˛ųn+Þ2* q7++ȋ=]9jD>-DyY';j;:['Ǹi}-\ 5i?ϺG՝5xljG^uZ*yIs$\QU d*~r}L]);.>N9oH;Y ;} ;vw:pioøҿhqSCb%)?A*ԵC.ތꓐgna>}GJAcXmG?[BJnj p'}:,4k󀅡^#e)f揘^;~P sˌ9g~UZP)2_pZ*ܣ%y&u"7c$@4Ǯ3yz'|-T[ZsMWM@x y n(wmo@^zȭ*|7 /Yѹu þ73yY_0 &ȹoNh+׍)cw] ~CIbBP"EbVR} Y&_\8c06 ?O-\jGߠ@[UymwjlYf@0֧ %cY7KPu:>0Q5ú\!] =+y84-10!8ntᝇ i/^,@zd+6W>Gci]N?lZPL܌1N=o75Q0{GAsI`1#ve 1aac[sW2n8HjLϤŅlFՕ>>Ik;܊g6|.EfaEZgȣ9F} v51)ϫm6KY|'}G㔎>^LiuQ~ݒ}nr_Ʊ1|5ăsXy_oH4ko=r34Vn|ujPPO=kXzn 7Z<wvf[~rAWD7ifZ8 C0EO$~ Zœ:' ❳#0pC}53>~ƹa{Nj̬.E^+V X'bT&C*}eүgu]g'$<̈́};bN((pwXcq |Vo\M51㾟˹pE~)o/c\i\M<~cUkϛeY o+Z |uEO!XĢ_p0? /B>~J*=Hɣu" +MM8F gp| ^h 9ہkMʉ1$v`~" Q_w_4\saK\fR\F;N64@I)(x ,xu}qos9ᾆ!ߑg[Ofu΂mM%mVBόf>x<DZqگΏZ j~-Kk'֥~OZwD)xnot '^i3 !Sv 5H{,ޤcWu3|E((7"s|;׼(bq|ȘݻvP;α";2ccQLήnx|OEw#v H;9/N##֝74F+3c7U1MX7cO⵱W7\g+n B >@a#6,%*X &mM)F=lQD(?Z:Q D8W'1T+puih!B?<*^tPZ@KHI 3r5~C8|HԬhX?aN0bet⼳E(k@ 0,xEq4Lom ,㎛yl?i?8qg-0ރA3ý5 X vߢ&-=qDNîFx-"@UD\2ælŜ́=-\L7߽aIq+XOX]=[|A"P ɠ:U?'=' ?\k@w#b2NbSIf`|0O/Pl8oJAMol#я4vr? ٛ̽'<_õ飍cAw&8 D7W 74Qࠀ/|ڋ5c.}u{9|>5f9r_%u^V0|gQPWw?Ǡk$xs)76OGp^ [vmZ,@çZp#&N(֧$(lZ[e__//~ෞ~?zw}+fX%|߮}cw^;,Fh'0{U/5!ĒsWt,̝톧EǒI'~Ҿd{Iܛ|hGvs~\l E&>#?Ꮮ~ǿ?ݧ?B1_<}Z3Ź/U*M &sc{L\)/)8 H5brB -B0c0*(] ,Ss渝㽬iV5 &0q}y-= D(Cd i ]lw[6\ֱmhϸ|{[cgϛ=7ǭ; 8-R( \3=8/o#ow030ؘ_C7ԼAocTo&y Z.BW>d☯EBߦ&yXp ??[u}#:T&k9yn_W k(pEx- [ c'w :f;=2K8F.7q~' }i֦E4 ~aЗX=ׁq3'ciyO-.|c^~z _OgO˯~z/(nQ'[O(=\?}Oӏ/~?ħ$ |*,T?->ױJZ>Q\>h!XsЌ[j ݊Z))@6$"7hNkNڏ{7I<63֘c;1g^Mǟ~_p1\?0f\$A, 8d "v4f1"SHp&3MPC6{gatS/# ]+,#}q7L&<lbi Pjj<9WZt)7=˾h3NFчhi޻^#'CXR[(;H7w?jGqtҚٳEbjtɸ–Iqai@;ȫVLu) {ސN&*3!fxޫ_k@|4E hOs8rV>߼}%}?^9|zoLg='{RTnV\T`Y^zA(> Ys[As%k$tۂF{1̇{m2ڣ& mD=^0\0]n}FkAk< {UG@D ֪F~ƈr&(q6niND#$bQLW5Q&׫-1pq1UD5\/D|ʚr~XIJi? _ %I%~U~oB3THS\cm!{]_] /,n$_M'3_Y^ r8=%83r, t;scO} l Oaɀe}1Bbk.UFs#_qݙ3j1Wк8LrCZe`3f3J`_ҕ̂ޘKsH>0X|P/< Ji8{<6Ko㏃Nzo%/Z^\Iӛ_M7_KyG8Kɬ@,a8E"8c&&R5J0w*Di*\#P#Z"kNc{DK}{%utHtⰨ$u㼑EpvȔ~F\~ GoA$ Ջ'ÒmKnFY.|]VoL_{3鵗BZ\<9>-ܙ-|"}IO=x*?7Hқ7o^OsLTD! ͷgPtb^S `be8YpI~{k?ۣD)fuz>v:uAVg8ܼ#F\55Ӊ@-@ǪF`xڜO(w1ddQ2 r2 =lN%69f_%{ ~ބN-ȜnJ_鍊WǙӏЇӓ?ä>|s~_Jo^L+۷zPw̥cKx,/׾*Gޣ'd)θ o Ň"\=}yPuXo'(mLUq ;FitaЈ0qJ Sӈ RgP\#4 WR#p#P *է+Lƴf :}XGIAWug1hhx̹Ș  g!ꀜuHD(qZkxNZݜgt=JrK(D:Ť:V /|&]N:}!%rٓ7+1g0vSS)1FdE *X#P#Ʒj`c/8s#̛:wE~EoE|ài>'A͞@E*eZ.r纼svQ|yHX7=L|z%6ry y2D0H[xǥKSb@ټbA[o$]8$vN MgOiy{Րf#8汢1_A$8 gRϊPX[-QC![x~~?)YO!x`'H?c?}Ӽ aq?b 2ǒ3'OXs`X9v>]|1G?̇2daO847#dªŽ!~ 4ȥE&x4=}B FYԎ?iۀNWi V |FF`OȞWkv Agc~Vr0;ĔiGD1%] fs<%=J;:≛QBGkсtW #R]X" SgLh}}-}KNqcӧ9u"_x mċE+NCD* Y=!Wp)Q8^?~^tblzg>(9z72  Ӗ#8[eЈ;G]}q5vbPRi%3›+7ty<^H@$眉Džj_#P#Ⱦ*@)Dc؎7 ^nDZ G=}<.UH|dH=[#v QI!t^G+8KeC (dMO@ exy/c]fC:C [Ex&S顳NJ5/:b9` MׯwnS /7^~/_+EN73foS1{"ܸZx .G 'VO[>c;@RHl$2(d8ZU4 S;nZ)*g@%Ln)(QJ#΃} 1ey}SfZ=s"P ;gwjb2;nAwP2̖~u97 ~"DIv?{2~Re wA5Ta^@p:3%T WP}^m}s=2b>yϻI{E=& o_|#8c`6qb=-5dCiCs$5 Y[=!dյk՗OO>A+EYOֱh22ɞFOF07,C.d 3cɄ̭Hkv}@-8B8҆^-g񓗊K3LA55@-@v*W#0f|S{L 莣>ZN>s8yL]f5PTأ4ÔtVOt[S\s3| mWl;tRdPi5:8btyZ,sl7W?Ai׃'jO$-teer6K& bw60od"jjZL1UU@_6@w' >):OEO6#Iw%#  E^'315;&vo]c0)e|J^y╔v+w=$j=r`ȈQlw}v^8{,Ӊp`ψoлҷ=^x㏡x2 3 q+-l pfgC1*B $~Q6pCRZ  ?3$_ӻޒ3G,4XmI]}x'ЈF[X0>7+´04bw# 8CF"2?8V: Bลt9ȝVӻ);suNc& d黺Ƒtߒ~+rc:<|4;{ Ǥ* G:2 TX/l'o_Lkxiрo;c{乯^J/_]''W/Kq^d@٬<}a3x%F| /(|/k|3$>}(P/:!5 Qf]hhf۔GY.~W_4:wTS z<biV#P#Ⱦ#V|#o!8o\.wB5J_IK:0:yI5^ $$#Ho.GID6Iǘg?&toL/YP<pn~.=ZG f[*>DceJt;DYG26pɿQvnnXN_7NK8Sb Zp͕b ,lX,'\,bЊ3.k00F֓!2Cz0|/s?-k[9GȆS9kOj؄v"P Ukvjetu9~G& dQY 2C|q4EJ4݀zK|-̎$>uɔqփ?ɣ$?Y&9zo</!Ǜqo%Y?`{HOijm/D8b??^z={3!ׯgmac8Mu˷Z ĥœ7^KW;08^چ[%eP2D ;# a`>j]mq+9m)TC{;qxztԷ]l@,|6~Ʃ_3Ѷ.Oz0#a k#4|e,,^F`(c\%|GK.&r B AC9zDÁ]7%. @dY$˞΁_xWɘR eyv|ǭKϧ关9t۝9;]2 hc+W/U"}t{7y8+fD4>7.h,K_.úO PH^TvIW>3_q1I #MD5Pvao> [oF;黄a8dh`!-Z55F L%+YHMr9.DLwwZzw5ÖB?2I+$owp3klB&&3.I4T) fsd ^б1#f[HzK,7`OD/ٓ3d]Q(0ww<Vd13\~fK"YKz)L /tYƒI%3|"-+J#tg/ݵ1[Wİ8&[ ڃo, l*. I1TkxvHÈTHWa!^׏ѓ;]Ydž˯nms}@f>.uPOS za+~qa~9s"^3*x Ye!UVk1V=ia {vmGMl(|&Xy0R!̨;T}Tk]ωZH;o>0vVG秷9S$:+E0/T  W[hEYxP6O|mh@05O DGgsH<~޾ $Q|ḢP4/6po͍.iJc_I~ 9MOiaw+ 8/6 7DEcÏ^{7w׾"`yܛ}WNhvre'3;iS!v c+$q]x,=-?@i( %{λf{46x1~u6қ_JB}A,FY;n9i l@8]|hҥWәs*7Oɂ=,_go/{l!LC0ᅐJ3a,PLoF‚A!yID_yYAYS&tTj[:os9Nk/d1#O5v;q`pG=v L47# q$wdIED,3%i,!frV'cOnB v|Lrl/׋ Ko(BGL#_6Ǽ,f6Y} (^IO?a];UD d;Z2liy5!n#٬ytb ;޸~ں4> H2*- {@W[@@XXaL56iߩs9NnY!8{w!]\p0T#4.j R[+oFFF ;P#pdf}oCvOʜ Izq$?Ѡ9ꎍkEj^'0Uڅ%D#VpbG/4Z ?l}坷,~7~;B١5OcᰟјS^OY&kNJ^=M.Lցv>xZNM rtyrug.~G gC~L}e]h1q-'~2fS>T#K.w8YU֭/DHvVוEZ8<-:#P yuxrDkϳP<q:^y{nKI/Łɀ|>y8fZzLA[MCrZ̨3˕\T䝃uK휘{>πLd΀p;ݧiȓƷd_t3ƛZ۬&4P.Dyqe%IP<~Fa̲KObɹ>fDOo.laT^jW"kjn[:e>V I%{9Q{E'npV]tuu>ǫ'%܊sypoo`\-ZJ$gɆ3i:D|PLg8u$dz3+a>^hГsÓ='m/m]],0|aq7 ŮaqUtpT!:IU_5wWjrwgQ9=u6M'"LbfLJ6k?bZqr~x9m~as ĔE'5gwYĈrֹO#pZ\gy -n]?wڀ `aeDIX(^ÄH2rD1YDqaO3@"s5tkhI+ˤ((AoǮ1g^i&SЍKV  L6^={/8w>.|ܝy~}Dw7cr7v}x1měʸ(DP+ziinZ-5M w6l Dvt u).ES*Vd'םKcun%б[55wejrW.kQ7 yGFcpq:2d0'y߰ɝl֔l c!&&яPw~9_&ekagwΓɍOz9ޢr[_΄X8<ņ_Osis}w/#YUKQI?nBac5_~  ƵPbʁU%gZ;3>QΝ#y7F?v%=]ey\wbIaN4'Æ7,Y#0lo"d7J88q=,7ػ>|,pϦ9/1 ~Ĉ/F%qhGSqW-I/,mQ0Z86r8S=VZSΎ73&=߿o(@T FKt4$;SOA6WD1G&ۆdQzFU-? Ub蝅ɖ qU{ N# f!BwTR7r&SkЕOpŘc_~{-I& 8X܈g DE/3){NyҞB]hT"& 1# (@V0W<$}=.᭹˚XU':/}s'p b˸珛k긟K2[Z.@H5g_|zJ|zj8Jof իzag'X&D q=lQ3llw4Y2VO"T0W<.c@}O*i\ "rC 9o3Ρ Qjj%ٗV5!e3T~f͛7wȼKf9SvSbyNsbلfz 7p a8=T8BQ=ڽ0[*#t&/aYAKp!*D \[xɴ*UM8>J`1I%U]^5'Ϧ_h޿tZ^K\KK.y1hV \/xCֿeN%9< ]Q CQ~Z-T>!7z[v0WAL&c-&Bh{2|pJd?[u0鰡TVP#n-=H̓uslvgTJ4IM]Zt#R$ G %]C79љښxi},qfq_҉-Ds u8:{, U0ΡO~kV 7 (&4@B36-uQ+a'FUdDl/;AE倎5j3$|m8;s|򐝾q6g^C!uTp55wt&ߍVk#M׿ipDca$;H>'譨-SrnOp"H|\W~w{Nx={@HrUoގՓE%}}.w|1Al%PXLb;}\&ƽ]g>^C'1xY|a5h qh̰ఋ2Cװʈ1p#맙>VWG2T ϊToM1uJjj09`WSfcӾͱw;q7'0' { L|{X݅©k:]B߸g%_r~ǻN%K}Hpή:"P k=l`h6ݼ/.OkJ=[ht#fvI/LD_-it==cd:3(}aQݏz2L`5%Sug%(p9x<|8;#%]"շw~cK 鏾v"J%tKx'qmI#-/.cmfӬ-Lxy(ސ-(@4>F5`19=59)KF! ĴGá @iQI\(zCBa. /Nunwɼ Wmev !|s:#OP7F;֐˞ [;*ci`Mٱ9A>b~WQff-3 +1bw^̢OR_%o6__y ) A4?Ɨӏ<~v'>*vSpzx)seR7Qx|I<<0ƕ?O{hypf rē֌Up}ռkkG@˝ bJ(I5A*{qN c }ӬfM2 )+  ytzU#pGFVwa0{yV3vt.9'{ U\g_"}: ,RƎo-[&A^=oNwP|i6\@p[9FD$'=v!z`<#0D=lZP=g@;`÷ę=\Lf cw|e|:]F9冴H8"2>:*\.=fٔ9&ˉ#8Y 2RI7`!#nWᢌ>8[ 5ύN[]d: Y__/42=v:P,u.#se?lx}+9̹ `3l }c0[x GR*>mҧF_l~fM3in: )sH}2bdIMƐfldX9ZA B4dcpZ9v}Wv16W2;k븁kb(;Jr\@vbNwej_#P#pȁ'#_D!5=AKi =;ro豽#*$S;[Wn?-G/5E&9<. bcxq*oYbqA$>MJ\\9=w:ƂtPǚTϰc3-\lW|@E ڪF"_2WiwAq(֡{t!e@SspOۉ#;2ޅ]ҭ"M4KKG䇬7 +42NŢC/RSػWq18~> s"L F%xgh"kkY ]vvQG(@RPa^VNMZ%P/rқНL|pG",{|[|,{MW qnXbb2iմp4V4[#8F X8rھ^jgBK5`$$ߥU,'+JRc>2ی$+ *n~k$ A<'i5{V.eJӹ4@(j?4жQ!$lV2s[+DvJͱli{ps5pAS!LZ!"ZIP w>Ĺq:Eq8:Yɽ2 M|o.I:I)Fd8?pm U6!t8;>d{ݭXv0.G=AH -xղ.uLv8l̥I7+A$I2ʀ n}v 3doΟ1*gPĕL~J*Ѐy9M5lf9D15ϧ:R$++DüsIP}ƣ C,*OΪag1N%#kj/ٿV59q}Pv\y,WIh(# 2Ydi bEvU<|yo/h  *np}cv2tnKgFdʌP8 B ,Ʊ欣]i_ ak%O!NհM>:o>-=e $?o =LN1a.q75v?ʦX`T\ -$/~˯C~x"D#ڼ,KQ5 bmLy?DS JkʿFryfScv8'(5UJ@Ȥ55qc,f!WA4p{O"6&ݥ8Gv&:"p\@֤IٓSr`x_1/X,e;LN'K5TYhH %r`>#~z۟y[E(ťM ,XߋIxer[裀^ƠV8.1r"1CrPHHϤtyQWLĴr5XN* O93.*VӛIX@*MzS<)V `;"d}RSkxsȅ]]pcFxvv-]Ѵr.lXc5@fx&ׅ%c*,\a@1]Nt]F~KOn6A/AZ=!/x| H\ÍTR55ZKX&|ׇ;RM=`eAE;OāSa.âWHj %vKY-b._C%y/ۇ +`^bs.CYY$ђɺ8PL1ҍw+7⫫2ИH>ts~yq?chGtڌfgjf-zn$M=~_$p>5* 3{X _$58s"P ;gwj (n恾g> uԧhSCO(Yb1=2 +)UT Gfi-'Y'5c @SAZ,.`GBaJ&n ?N9 *o4H:` |L;nHfܙ2v%SXH!,(<$L8"ύRPJzǧ_,w|,m_hE!P})Hm5j윔ئSGm55wjDm55G0e#&?_Xup^r(H[8UKvCY1k:&9)Ps®D&+-Z3Rau:Ͼd1]ߔ^4ϼVz7lӂ{= ޓ\߹N3|9/F@θh"j<F i1%X|*/CbM<h:Xhƛ.B$)3l;Xc,O8o<"jjj2կ{.{2P&Tdqvr\DXΕ{;z_z&] IG`ܗ7Pd N`jWgyBAfPhhWTeKY-&7pȗr=t|k.gϞJAIZ2hJxEP]m|,=Қ 3<%>#/$},;kiu#:>@Jÿ^_{a!Յ004E_ց3QεL-Z(!hmCx&нs=jw3R?cɞ>#Qס#q 8{hÀze~H}d/!W">&[n37ě̥S_ұ)*.]#Ǩ "P /Ϡ`3ʼT 3g[$Q|ɡtPmѯs` =f DA{YHY<@{YC;"#:y'G7QsG[(]]o ( 3@r u09H>m1%D%崼Yo%$)P]@&oٕx"+Hvͱ8) j~J?CS=dO,H~7>՗=0zZ9}<=e)W  %5Ubizq}P`H D׼73Y0.+OQ4Kht6{oɘjNW֓W@ejj59WF|GF`qmPOq.7_T\ʹ6S'g=Lh|Af *1:UVسH27Y<7Ǹ$|'̭+iֵn;&}O}ҳydz,>[w_-6Ņgrj5ʷ;cg-Rg88=2ړc빲,BFb{ܘN6"ھ @:N{Lj17s,{U1Ɏˬ<Y@-@3Uw#hlԽu\q?w-<( F_?9B n,8a5;n 3))gC,V*8%lvC P38[ oͲ_.x<./Y 4A>-ͥoHKfӘgIC#7H!eBiX"eY!@58& = b$ϳ,QTTAoxLK͹KN F_O&Ëf{JSZ{DѵorP2}ޟQ=#+ ~X ?œZ!U5q@@?4 Z -o}Heȏ&(a#` ځ@nB(8|B]IFFHF GrYSwW;dw!DLA h@}Ztm}~' cJM xw>-k9䳜!L7Wf8 "}0K U8I.0M?qSŅޓ [ղ*Rw”X RjrHf Sf8%`MEJlE$WZ*9d8Sr (rQgF~Qpi "e̳l'AvC3Z`,!F0$ЎY;ߖj%'cy{ϋߡ7[)DTFF`#P } nU]#ئ]n;wT-b@L֘9x'5#qcp8uDG8gLUK[(#d41"WqfNnKt42AcE0Ǘۿ~9<{*7K]~$=K8{3~06<#xHދ '&soi?z٘D?SC l0""wxdtw>uǑvO.X$Gy]~UW0j~PnjcrX[@@-@Tloo &kй18~}-?ws7*]$nT| &iqA_Pit:LRkRg7M!іZJZ9>a#%AGǂ&I(ycid]x(:NbϿ~Z|iB-`G Ywvv`2f~^rG\WO%gvK2~1ѳi$GrUP%q e՘r>[՞-/7"O0ܸn^M_;͟ߛ"=ud{(<{Op7ӹ}OZ9u6-IW<κM̿#8OD*\s0ǠgPO.HP2!D9k 'q*tzgOТh?8SfL:+b|>9fd2rɢq{)taQ,T,^byTkjFE Si5S%#sw˛#PM|!{u&6ՄPC(0z~7!ȄP CK:|9N.KqMAc 0 ļ.ŒtF{`I"ř"FLf⼇~wq$t?hyp^J.}w~(}w?='nP~{=]|f o_ϧ(]vc@#,"|L:u|z380o={`E1/p%○?o~u.#3–kqWg6ߦvEqiM$Z`Hlf$\e`5^[VT3va zz>& `;ִG}&Eq8Q3pėGK?BՕR@-@+UoG g%q۴ݺ$I7W]N]n{'1z SddJ:.{rz i}c#;(vn;z%HŕǞUPv@x#Ģm&tjϧ޸{I~`z*M+'_EQ0\o\^z׊,|. 83)KCq8JqGxH$43t*zptF8>z룏G=]x._&C(yȣ?~}[#P#0dj"`oM6=/6!d$nk}Y4O8Q1}'{牺E\-5V 6n^/qe ]fBUA`Kx=Q@ƒXK쪷D6 7B4`bf٢}eX߇#".(F ђϝV"Cp#<}/d0&S#g?4.{ 0;es 2-A` .߄}Q9{܁qrc1aEf0hErC1W:gn8=d'C;C d2issGQ{7>zʹz &\o1db8LvZZ8 񓸑|ż(kuJAdA]yN(K7< \Iܫދ"?XZba}X#"gRhD ˴hCЩi,-[.})8]iF;:G"_?ܕn<F`[ovkj# h9&QxEcﵟ֟?Us , 3҆75ɭt IDAT1GZC7fHDg%;z!%Xy옗0smkk;2^}̥Εloa`fpyTTY0㲪N9ΜwsiM'+2@ʊ Œ QN G,ʌ11 &H1}BdFZ r?`U镖h<6ky#5cpDLae8>nWEt al<tD֣@gU.>`t y 7;^tQPG4Gӕu[N5@^= [V#r|6sF]x(vmlL;vDnZ;6@:<8I3!cjĸ\@,:#AHb̆qc_،eKoC)-t!HBRi=sٻw/9s_w a o .ɇ{](5#hbfcCz%Gˉ̼Lt4+ŃR~-5cD`(sw &u=+!p*cE P ! L;hn jW焾0t$?Rwŀ=_Egn#|^>d sElC":G:X>RJ$` @ H K qT1xi4{=ُނF|ţ:8R /cĻMAyxHrѦfckw*o7bc\0e`=8Ju7ׂp [BYYq`XTJK/C[ ix"![Ԏ6-PxCXP y}Yע D ځ *LuI{5b› =t/ԓ>sr͆mrЄg l3X=Y^ǘ5,C{LQ6U5[x1n75&'h-|$Rw8Nvf[XI)vnDE : 0@7uܭ\T:*)um~< UYoxyp'9Q45 nE睙-Z^k;aFl"ɾ7gJpсmgU7IFY^L:p`(#H^QbeӎY611 =`"h-U*on*RW",ZA00+TM-Z`6?tDگ6ܰ!ĒT0 ða a|JP;;IԳ)F9}ȫڎ:/W DNI,0&\i{uƚ'st!V伞G f`LM `C|KtVh>kI:ֳ?~ul^RQ\ G9q0U$)--K IFJuKͤH=3z/\NMGV Bfs-  @Q'NpWUjX{XPi:0l@b*uj51&T%l^y>TJ%4)E'AT3(Ud/ia;뢡}$q@DՐl,g;a|u!Ѣ$12Ki#Qrm*F㶉~4 b(/: 7ăH*H41; u[^1|8;S?+W <s$Z_wClo#kN cX~DMWR}\Ύ,wr!+ ƕ l?M +akQ0T&35}EQXB >PY:=$ fHz ᾍĀTx TlC6_-BxzȚ+aWkh㜄cBIDЍv8 `9}8m2evRx*􋋤 w(⼏ ,;< 43E48(KyyzE}EFXN?KYG4*# $iTm; `L#M*kuQH+-[ S'ZݫMu`1 O[j:f<8P+[;URlDHzWΫXM2'6:"u}iӱ!8Vxk@mdAw~t ˚U[Z8t]`.Ć`ҋ4=lEڴ|&zUm xѶeNs/?  `xHtZ|Wi_cIT|H(VCKWܸѠ>:͹GshpfX`>MRA,겲6/W^bh%6t.׆i/cd*#Jl$&{`uc=|1Ǔ &=PH Zгù*tl!vu_[V" KLby 5cㆍ`'XM6!XHs̭ȭ8kShΒqS m'gtI衉$<*QdiXT_T(t%L]v-4aI>9}= lGi uʎ&(]A @s0iWZ%@Ҩ8[cqƔ0z1p+I[+:Ȼʺk)6P{p An^xCc yhU] OR;~mcِПB2i`30ŪD_ȒZMZmľGI]L? z>kmgCF: 1؜eAZD>7AyKu4XY^S[!8[ cNl00s5 ]握;Q[Jx=A%)XCvZi)AI>mJA-㽇LRJL%"g3`mF7sL&f1۪s-STd'TWQlT϶)2`侂yQ@\.O2 z0ې@MV.S.b9g`2:(:v7A9MZ-*N{0sU~E]oL0ggޗ}>u9ĴeA M'uM/ԚצkA+MSr{2Ĭ4-m6f|ѰhrT.(֌TSYvUˎeMQ,]?H=#ۃUL" #3lT<0 :Nˏa6a!h MJ$PDs[j_SŮѬÉopL4I~rZхL*MaHd/ ]x6ς{l%wOg]ۣY_i&/o硔 JE鋠(|\5oj'X)$ :0j^SsUY lU8)1,l]b*f]bdx|<[ɺpufTRe2؄:>޸ږk,WJjb7W Pq4T'`Q!kŕhzLd\:?!JG9OKu2} HBHW- TE#]R]2ZecA-ەmW\x9Z6QUiJ+K9̪[WǨHѲ !ap[p8wy`[:C)Л.ZED'&B5 W<@a,(cWzP zKtmG&Fhd 9.|;Ռs̠@Dfɧ 9YIxsU6 ,+FUDls4/J oMQ.32L7, t.ds@Ktl]-dOM7$}1ݨ˳GP_^mj=v(; ~Np&`WG~@v4-RpCKhVkTgIbLR-mt}Qo M=ɦ%:-W9dDs - b1懲+Q}2~_$K(;v@iKmSB$``Ej?q^?ɚgz_j?rJ|[lٮоleTO4޻$KƑJU(B bq oJSX #2k|P3gx$ic襧 ]$?FyG UM `8ldhLhق (i> K=m!G^ !So ^FNeFTLA^+eC>ӡoC'j 0mvmf-,on>=괍#wK#B8VCA{B0.C_֩ }0I>G1~zBx]7a}yzmScr6C?Oc(颤ڻ)_+klE'}N DWBnˏtj `xHS93΍\ц'xJq":QGM-4X42u6 cn挙0g% .3,fT͌ 4e-»6OLP% 8 L}<b=m``78 ju'B4 yC؊ٵKQuamXBF͋ k懦0Aa#h>NͰ ˉZJpKR톍HJ0)AB 4?j2S-sL9p*PVKt窙SS/S]ԑ׆Q>U !Hnrm#^I]b!r>0GTfٌ Kf8$#N|A5 "\ͺҷĞ V {7ȷZ5쑺ELfS' T\D0_U,f `ItN566^OJf}vL93K! t_ 5 [l]}o;8PF=OP[>Wm^<5N8dfJm&U }oE&t>x(+_mWCOmd:(1[L/GS~Lk;$U5JBھ0{TF-6$HD, :A)Y#[ IDAT7æ/v*%-o}{(mr;ϙb\id)OWVcV#3gFC'U`7Gɶ-GB47#KA\a p>>VGeGiI\X^\lP$Mk^ i9mjTkG>ZU6IiW }a+F>ժ AH؄6,ͳːg{-!yW+؛J̓|X 8mR ըهRNlTTLطPL/u#ReSȾ~FvЩ Ǩd`RATguAIJ~q *@TC?=*Ha>C19 %Ś`ul4CaEŤ7HXߌ& / {9VjҀO&uE>NGh++MbQoږDo>NlcX6LI+؃zs="e0\GL[l"BCee,vG0YwWj%'*JiRKT;tj a?&SGI.L$@#|0ly{<۱-׋e ;ywl8TlGPcU'cCZ4Ji&Eԍ3fdu<<_Oz?fuQT3դ 9a5_E׽dyrmtjU?ՌbVPWhQL$\i GZ!":є81.Iַa(9f6Ô#Je'؟ɄSB200~maBW3B؉SHMD9[m;ehY^I9['F ;G#8YsM?tNiP%* 9nCW0RE>bUHqGAwnXE$59]3$@):6Ί?]S^֦#zIƲ=A{y?י7]ɇ7eלP [ӠAG8'(,HuZ!=ܻ=nُ5?›AS^U2UA$\7i UI50;Kx~hsL: ƝFblƯd.wBksH`Oyiy2n'{d7Wuʵ6MYw($~O d# ŲPeF1f Ǽa4t bg w%jŦV$ &JkgTN9{9hg:C/QLYp:\WI|Oc&&sy5:y ̑ 4p@ !l uuZv;UAwl0QJ~͂܇ MF㍔.v6l{b=+g\烢xzݠ7 bҲ cYA3ʕ*xZPrVwAob}­y 5\Vlb=7 @ `؎UJ>ˍpb.4u=얃i`(I`S!dS9SK*>>@d$Q?~zSgW7lV7< 0 ·(?oA'Qe޻RUizw-X+㙹̬koB_D('My2,7X Rcnbzl9>ok?m%*Y^i~60Me' /_/ΜL lI#W!bd4S75X1}SUp W#~Tz' jAsLLvxhDϋ]>Xl6y0W$G[T h S{AK)xWq[2u~Kj\l+rYV7Sv5kZTHQb۞cۨ=!%sdbV7wS w/i**.2f @'#p'`47Fz0.7OrsrA)pB9đV0$B_z\A?.&ou=v:i#LFCU -=!0[E[ TR^CB/jt*uQNdigGeS&1d5uMqiR1ZHҌk6X4#_CN&ΟI0iͩn,mNWL??!Oύ5V7Wb8h a[Pr rՂm!>z~-̣u!* :5ȧD}WV^7j+!ޠYhR;r)I@BA<[d[$4hv6-8Zc ߟ[`ĢdGT'&L-C_S @W 0*A'$Ƈoޱ NF o#m)tf;G,?BAE/d1;`PL7%A`y4nVSB.˝UQ T˵]F P@$L̃o q\ӭv:HP[϶ɖZetCܖ-XYM˅a<(A Aﰉ@$CPWDP(9j֭\ ^A7'm~ ʈSVzk߂%3$@"Ydi#Wۇ>AH-B!vxLnpe܃#ߪ *-!6Pֶ&eN ^SR>X+jQE Ka!ԗJR[?m]C{HbR@$h 57 cN,syR lK;'팹q}l?D}IT|*.c* H5h~4@C߈0gG-4sUֱSe>eHq4%-@.].nu˩.\8ɊHR~k?&s L pQqAlLѵ}۷1tEes`/li0hRc!LX0=ZGjz_pLLѵ1eZXê&Ў Xl D`Ap~pL5ɛqXۀ0 @:/ - 3/jɹM$3sJ :zgD\gUGaEvy})Τy{r8my6F2Ũ&?öZ/DFlWM%&d^E@9)H$  @A6I "ncGJZ]g}¹~wQW⌕|ؗ:S?^ P}^Լll'__-A q4X ,M)yKi[Pʝ[`=g q-%T1 T \PhvoMKmVF` unǏE?C׻GbuNNt<=A MՉ!V 4FP @`FȑN[9[֮?|xA0L08wrTYmV!uoR6hP yX$쌊8! +Rz:P(Duk=*2lmr|t$Brnˏi lt|yMAbu;.Ft.KxRbD +k0R$,U:)@™iZS{pom(94qy e43e(̥ NA9?BOV\/ɺR5 @ xm/=hS G+ӟ[$SfӌvѻQ (ɽc?`*iF;I鹪r9˩X*1I&^c24eIEg6~VwQ\i/;ťNNQBGvZE(cu"LvP5=qMu`UemNUNȄjiQ_ O&n7T&>Q̐ 4u     @ %     f`,K$@$@$@$@$PBH  HHHHHEH. @  %H(     h "K$@$@$@$@$@%zy}DJ @X_.ZdAc2%o+n=q\{L~|Q݃O>'ڢH#O?/Ne>%z7˅AR{LA~`7]?ϒ#Cz [?B>8`3a;_-3gϕ731ǝ| /+ޫ?Cv~+~m29oCn9@vf翶DE%#m|WϽ,{m-Y._W&[.[,e 5kɍw>,lW ~vctyNl䊛)?9ʞ;o+>"y9{wv?O5sxQ9M~6GO4@Aﱙ>%2lˁr_n19\{oFzwNnUzq~J~Ϋ _7j 1o4C]&{ryw/FX%O=\Ͼr:O/t9eevr~I۵ xi殽2 yXR=Ӟ6tyR_O>|a_&נ7-x=1suѱVhS^PB{̛.;zޔҟoǦ4\Hz76M ts9'e#4|ٷX%ݻ|ɖ ?EW||漟փ:9XW f͞'7:˧ʟnGK7yUk ;{vŒ1XWv>{W^}M.Y`_O{|g"k֬ m&{rǃOZΐSuF >6ȿ( sؠC-IdYn_9xoHl۷ 7)+w+VSear[>@r/|~eZKCoJko9x߉y<+r뽏YܹߺTW]:&S;V Nfk0N[~zI{|[_vj*]'O5۟L;\շ^V w/Zz%'sU?yiB/b>aʞ+dkyIպzۡ'sL۴|C3~P{k"2/[$Wjs9A.׿^WȀ-;mcbO"6w&U*e^~o%?l;n,LU_lv3N9oN }}s6d@쇏啲$CDž7d-?a;X@/8λ 'Vҁ1C$֧owؚr~+ئ2X\u!%Ȫիm;ՇyǴVF,^\.6>"y j 2p>'gf۷sD b.Ϛy[O<* >p 8׿V?U4?h4^ҡ6c-Fiӟ]G6ms2)6mM 5WuF۞\V0.u#6Ex>|;b6IxNWf^mƍLpr618zէ&Ku{ t=p t~)]^k7X#{pק<'ZwS)Uq:4 |^/Pk + 6%bx9PuRk׭+*oX+mʿMW _;t+z`ul _CN:JN*\ο~X*Yܱv.V.OE_?S|+5Pz~pw/k/E%֮{}'|G7^W&h{ɵoi %AպҶv[u?]xh̓ 1 m|9u+ J@~5{$p(֬[o߀n5f'w?]vv>:[y# ;1 Vd?PW_?opo6,<ˮ>Zdy 6>CSjJVp zណ 4ʸ5^Y`vba IDATڼ︃ 4m#ޤjXϼ8G|Iddއc# 2'mNV^9;Ϯ (sݏX3B`QղOLM+?r[s1m@=l5u+cubl2VyŊR^=}'Yg誃'ww.}yguBg\vT#obU(w Fz|IN{K5C[l9 ^$#&#KJ~sqGGG*XV n :nm˂B?\z V'^\zգ?G캽\49Dl yJ_CRs ߺcE7[ pߴL C$(eo!ׯB6X:-嶭6p'xyB  sV#OS6J:yRN3V[O۾Kj}Cmzq ȱr ƜMvu7>Dw֯~[e\yb+qcڦ^U}ėnMc6e;(`Xq= _PJ! fHڒ@dm&$w*wy|pWo>Jm'p}G><[0ps-\8o磲Kg/[ujIxbVZϾ~ґ?M=%,nn_A-'om$MaT OŠ=ejcoy*1Mت'|Kܓqߨ=T{XL}ٞ}J+`ui~C?h[-yVު/!{6[.Wpcz~cIWRC ]  +N̦}~ wUECuO }%&{MU7䬗SX:-gj xCcn~sm< s.ѱβՀ,ݓ?M7GUuzʁ~ˌ>҅Gvt'ٷh`W}ѯjHmBt3ϵ'fᑫxJn=D9^7g=+ӭ xz? !|!l=[m [Mpɷ/RnU(7x˶%Xa߶5 SUǫG;avq>_=SyTN{`\WqГR1F9~w}1v> ^zbuo-3 /-\PX#m_9 @'rq:/&'l=y~n \<[}OOFa8gL9]Mkw.p=b//^&}G͑ @_;3 ${ rM r8\O x$',M|OkOu5fUrA{0h"k&xسg    h;śn0 @+ 0i%mE$@$@$@$@mNH_> Vf_$@$@$@$@$ @+ 0i%mE$@$@$@$@mNH_> Vf_$@$@$@$@$ @+ 0i%mE$@$@$@$@mNH_> Vf_$@$@$@$@$ @+ 0i%mE$@$@$@$@mNH_> Vf_$@$@$@$@$ @+ 0i%mE$@$@$@$@mNH_> Vf_$@$@$@$@$ @+ 0i%mE$@$@$@$@mNH_> Vf_$@$@$@$@$ @+ 0i%mE$@$@$@$@mNH_> Vf_$@$@$@$@$ @+ 0i%mE$@$@$@$@mNH_> Vf_$@$@$@$@$ @+ 0i%mE$@$@$@$@mNH_> Vf_$@$@$@$@$ @+ 0i%mE$@$@$@$@mNH_> Vf_$@$@$@$@$ @+ 0i%mE$@$@$@$@mNH_> Vf_$@$@$@$@$ @+ 0i%mE$@$@$@$@mNH_> Vf_$@$@$@$@$ @+ 0i%mE$@$@$@$@mNH_> Vf_$@$@$@$@$ @+ 0i%mE$@$@$@$@mNH_> Vf_$@$@$@$@$ @+ 0i%mE$@$@$@$@mNH_> Vf_$@$@$@$@$ @+ 0i%mE$@$@$@$@mNH_> Vf_$@$@$@$@$ @+ 0i%mE$@$@$@$@mNH_> Vf_$@$@$@$@$ @+ 0i%mE$@$@$@$@mNH_> Vf_$@$@$@$@$ @+ 0i%mE$@$@$@$@mNH_> Vf_$@$@$@$@$ @+ 0i%mE$@$@$@$@mNH_> Vf_$@$@$@$@$ @+ 0i%mE$@$@$@$@mNH_> Vf_$@$@$@$@$ @+ 0i%mE$@$@$@$@mNH_> Vf_$@$@$@$@$ @+ 0i%mE$@$@$@$@mNH_> Vf_$@$@$@$@$ @+ 0i%mE$@$@$@$@mNH_> Vf_$@$@$@$@$ @+ 0i%mE$@$@$@$@mNH_> Vf_$@$@$@$@$ @+ 0i%mE$@$@$@$@mNH_> Vf_$@$@$@$@$ @+ 0i%mE$@$@$@$@mNH_> Vf_$@$@$@$@$ @+ 0i%mE$@$@$@$@mNH_> Vf_$@$@$@$@$ @+ 0i%mE$@$@$@$@mNH_> Vf_$@$@$@$@$ @+ 0i%mE$@$@$@$@mNH_> Vf_$@$@$@$@$ @+ 0i%mE$@$@$@$@mNH_> Vf_$@$@$@$@$ @+ 0i%mE$@$@$@$@mNH_> Vf_$@$@$@$@$ @+ 0i%mE$@$@$@$@mNH_> Vf_$@$@$@$@$ @+ 0i%mE$@$@$@$@mNH_> Vf_$@$@$@$@$ @+ 0i%mE$@$@$@$@mNH_> @VvƾHHHHml kcMlXmݨS#kN ҕkeTLzԿ8i91 @V\)K^_,sΕeo,5R=ի8pl5a[׸sV˒+ QH L=dr䉲r6 @:j    :ސ^zQso>rիV3mzjYp<ԓ2d02d&u4Nj okvtr䝥__]z3rݭ /,)ۍSms#pQHHH:'Z9${5Z֯_'k׮!5Qc^2ÎhXxZ&B5߯wҷw/#'vFT'   =˖-aGukexa-YJckK=whɶ}v˧>u H؂HHH:%^=Mڵk:եB>F'W]ΏӕzaR?w$   NՏNmj=/\8lHHHM4[v< j7d>޷o߾2h Oqۓ4eWY3˜9e̘ Nꓼ5M(M r$@$@$@ݗ[Nc}G}%:p 5x;n<2;5 ߌ o:@^t-7ʡgH{Z|h1rH}>vWZ%}~b _+{WtƸzq| :R^~y\l"#,׶VylG^H؎HHH PsX=xM+x-V>GYաhX~-G w$:=rnyiC;tM%jN^ #&wu̝[B > SB/~MQf?&7Dz>r7ʦ۩6^&   T-FV>^{MFiKkJBYJcE,VT4&l#˗![l?K;.SoM~(Gc}Yr,诖1ETCWlyGRU=2ЬW r9ֿ&yEz+Uie|5WI>N?.7Rn_g}nw~[nnwS̑&~T??vڷ¨[:P9Toz8{>zɱ 4n8M]5FXz5V>4(5VB듖VXAC?R&K^]VXi~I27o+2dPs]{>LVO{@f>3Cv}7X_,nj c~ ?dA[oTU+Yen=Vvew@YrLye qǽKLR:(?~,\V>S\"'! /^?᝶^?wwn2kLsϱ/ʘqC}N;HY||o~wzr='ɣOΐ~}|ڏ&y   % …!٫n_Qכ>VV>Ft%K,cLzl7;㱯  8Pn[8hd]uLqܢ̑=4XNopW;xj+9Jyiӿ?e` yge}&;:=O>*Q vWX.+9h_\=3g>)[o5AN>=[O=jCCʩrG}@rԿMٺ[{u>kKLm谡r~*Z:2^a!_;[r%JU߫[?H9ӟ>uc{{Z?lpˏ5Z{-p TCu]0pDࣇ:XX`~c> ;+V`^ 1B}eáĪF~eya$}mB\SGKwqƛח=i~z V}:+W5k:[8?`Y+)+j}Eځ-bw]|̞}&=7| QC=ZJ]1|WW IDATI&MXG?3?믻VWU@o Cfvt(cH}@t\uݔ$$4_+к @ΐHHHH Z]Q&V:n~+[{Aů[է/-\Po*/F}'i! Uo,]b߲OviyG,mgcA{m9EqE0ԣgY A`'c3ΛVXgcijp ?3Rxq۰ƌ'>mhFqAp~7g~FhTW@ tzayO7=mĭ8PW>uo}Cʚ5\U^o[漭7_6ùxG50]as?os)Kms-X&HHHH lJb}~dm[y 2Go8VCïm2ĜΗfdߊ<VJҗ:Xɀb9V5~ﯶjN(55P'pTw)^sdz/2Pkv̕n"k.im'M[Y"-md=UqG^xV _|^u}3}>LyU^sUVNv~k/yaEs|9V>ٳen>insY=G3RW@&$@$@$@$P Ԓ<mW ^_W;pCK/$cFzC$#GW,<>A|z+sΔG[`OW_z:s3v:9yR3z[yeޔ[J7ސJJWVv֧c=%>4nXER^sԿk~-f/?? ]$>7So9X^o}vzIe9^ 3߱ õp~A kbxЛuţCӕ+!}mݜugu 97˥]$;V?^o9#o @ZA} @ zmۭ7o=ak`;6_TuuW$Qk~oma׮.Ϛ%3>Cd⮓>6︣?@f>,mF[ `Gw]&:{SC qamagFq5343g=#C#xQWNnh1B$Z;_Im?s=Q?|sOo{@Gv?Qn H{j:L9OGv`}E-{ l +V#ktk lmHHHH- 7n?Ѓr[G5[:`> ('{^ d+]ARkB1\ez#`b-fxsz:/]v,"Xـ Fi#Ŷ#KRK=w;}RQPSKVo].I6l}W_?eۮfzJK/ 7(}f¿i')mEMqPdnǪ6qߪR=cL[ӪyeܰW6Y7ǩ#nӄWC'~4v5Pz 6tTMҕTmU̞QݨvlTHHH`& ^1cFuGiA2kؑG LUMm ~Qi_k1Dr>~czȊ}Va4 ,͒ @W v+cs,70mX}~xW4 Hդ=t'oʝwݡ1/}Vn&9DO¯I'ճ]\Ȧ|8v   ͚?"N.n^E  78C/]hDb[& [m'w}ԭqI['KWx\r#lv"  .+N.n o `Za]駻j8>b?8r({0mn: 8kxt.E~7x0(PaR` 4@eoh.>$$NplF$@$@$@`b>2kѩnzcxbnX5k 8֓CmHHHH4c+HS}𣆃U#o)Ϛ''o`leF AH0Ό-HHHH"} [ˬ3dw9T4JY}ٙիFdv/׬&ו:膍h2f6c,9eÉ-\и_`ٴq$@$@$@$OZtzf-~SݍbVve3[O!KxJ濶Tf>]aw[Wu[Wd$x$   #X#XqC!`萎~$jj.Z-gp^H\ն*1)`HHHHHY<"'    l 0lO-'F$@$@$@$@ݏwN8"    l 0lO-'F$@$@$@$@ݏwN8"    l 0lO-'F$@$@$@$@ݏwN8"    l 0lO-'F$@$@$@$@ݏwN8"    l 0lO-'F$@$@$@$@ݏwN8"    l K7qb$@$@$@$@$@݋@zjCGC$@$@$@$@$r^$@$@$@$@$ cHHHHi͛'gϖsŋeذa2n8fmdرU ^ԳgO0a˲~lnrA!h܎$萾}6z}fy9Sj|GQn+-[& jeM+ MK$@$@$@݉>+ӦM3gO;Mps9My"9c-ɳ5}<ɚalg @^^}.['?y򶷽^CZ&ܩ^,攸9M΅HHH,| /V9S!-Xs&ɤ.?>O&~,xj4iթErvy2}y,o}~N1b%'K0ɗ#]tŵDl@?hP ҐG CxԦ6?wdk >JiSmIx DiiJ" HI5O 5T#Qw|;~&Qsvo3s|ν3[`F)եSt.4 S܏KUt x6xuNzS3~|N9C?m3AQT>XQIY[Q]]Zx68 G-=d!`x h\5WՁe{|LHL i(ə!XdL[Z%Ј( vXϡ Tn;2VWA8}$khFDFВIL3;-7">z6ʊ!/OE~UQ!kyB_p%oWŴ@^_XLJfukB(KX!׋EWjKJ[˅⥗^ _i/O=%s *#2۩kH#7<13 8-[ q,0Nɟ| "/>V~ju.Fr޶zxũϠIs_zMʳflY/4t(aoףbZZ*cCkUQJۗPrVVi8E˜Xѳ8EhB%TZB *+[Ph>\|J/~e)z:l"nŨj oBCv_=q- Ĝi}nAClMVHHKra1)1c&߬d=h)m3 6M*BZļh( mI h TW~GډGIE5! zW9 s~: 1Qr87RƇ'#_f?O`D#'WlI~)(oF7n8,4u=j|v=E܏֢ryQxvz۪h ld3Xd D L!u~K]wk#E`TW]1IX-zDNT s6bY*L$و JQ!w̝+j(< p"zʉʬFƗ*'@;d2_[5|\+bM WO 3+dEYT"a簣(`gҟ{(ۉDw9+Pb. Kvk&lCu}5v=V=ݝdلu.g%J˺h` Sevcp/'I9ύ4\@''PUkJT~erwe5\<Sj=Ť$TWade!^A-FP6ypxt6>{Ņx ذ kI5! E3QR-$GH0!_Nw*>@f —`CSNg 3 4\)Prs}T=/U zd,]5d=@ X$tX,(|#4x55Ǫ]xӷ_ H$bI7CdV&¡2ZVWcZR54(^źEsRDz.ZUyEztnZ/a,Q鿑FO%>`^~j4Kpa5Y<:!8:J;u|BW? 9@p JlBnp`9w6p2=U+g0: =vem)\o]fxN*" ? >,Gvu. Np;@Z;gV>>}Z$aau\X1pL.%Z!-+a2^*OElq+%D*Y>1b%t>ԩS=$ш{K k.r-=K0\#9!V&cqR7QL*]ӾAm J9}! %`GdP(*$1V[iɴb0]JY/ W9~b>f&ɗj7auHT?iC~{IpoH]m$,Ep`O&+Jb%8%#ZqC\1 3YTFG=5RfV+N?TܝEl^4 Zҙqn"A5K#)ɔ񘕒Dh]PVV9iX]`f2HȬ;V12rD-)t8[1jL2;>-9V9vP_x~qvy#A^*!GSQ;oEt"m1J Y!>N}I8J82O< Z$MJ|m :[j%;NJL"FM%o@;x$ٯ] ֊IQ^LJ [m͘q~̛HJ" [|K-;EgvIKc"}ɣF3 / 5]`–xhBqtqep.-V- @DQ$iFH8"'ZbҠ# zZ^iJ~0/J谂1\;C5MfB]$}T9V~:ff&iV)XaC!>9o^'d;U2#ڵ 7#+,1]-Ƿ*#Fj)G<\4@NɂUpxBEk&RKjp9~0+Z.S!30mX:ՌA )`!D(IDATtu!m(HdN*Q}OMՈ(;N1>Ke {wȪ߈lҀj# 45QȹQh GCg-x J&Xs4Sƞy;<^)WSQO~x՜Ww_99Ӆr'P7܎RRR#GR>38íU>V)e?cPxٳgʼne+FعB(ip2 ٥ɓE[:\E|mXQꪫ2 8믿.1wȝ O#7tV /ǡI$xQ΅m랉8= .NAE\8kE@V'{nd ~ f~G!'WDZ1+x8/o^EEXE=$N "?qĥGo<c,ZŌD 8=XCtЋ\efzWӥe;ݴ!ӝQvqytmep&[Rv=;y+sE#{&̃ȲH}Խ[=҂30#f9C Huq&zsG Pu"{=e?,3^5)AU ^_Bۄ@&7*J c}Yqx!~*u{@Bp;s?UN iƇv+?SO%V6dѾp2y9[A[S9- /.yj4`o>e+8q8?9F!Cĕ x:z0y*k׮J+Ng#zc5-YtSz̖~oo=!)u HKʪ:OfFn|dn)kOBt7HY9$83is shPPa`qxZ:F^ Fb-?I9Wp&$ggdBqanyGUUH_xG(D.Qɢ?gǂyxb=fǛS^WOzh7|O<Ǽ4dl*\oà[ Z7`OIB!CԸy(+FדI$S2r i#MH}6W"[" X,^Dަ,X'EgCv6v>[H?Oj({xÚ1k1afsRl>PT N+3xJ~W0N ݻpٞ ,OW_8Uh"$is}yiɣniupe7Q_ ʪk#$Ay w+Osj--TM.fgUTPGD7 [_*V=N#R jqu'^=M}iuJS_o[RX7'xsPY_V(R*0n. |+f:5s#&=s.ыDoy/su^ mmmB``EXyILABV*,!ʁM7K2 &ʅPpdRkGD9dh)r0Y9 +"_FoS!Ϛ1] #e?{x/CҢև(38 5^W+V,Wó-૯Ǧׅw-_[))' H3K' -G}T(ͅempZ\~KeH"P B"Pmzm\8>!'v6<8e'V>tDz|ȲG_=KG.AK+]-#weٶ =eJ^̰r}R>9H` ڣ|ti 2.hpG D(@ D(`Dv ZZ/賋UJy3 Nr+2XiEya<|MEN{FFj^P;g/47_NXfen|@ ܽC'>Z*wj܏?@ D(@o)* z08g.nC1|P0.)NM/@W?4X|{)ZkN{1P5P B"P B"`a@3ܺo .pOh .k _|HHH8B"P B"P B *Ο7MIENDB`pacemaker-master/doc/Clusters_from_Scratch/en-US/images/f-13.10-install-complete.png000066400000000000000000004654231217637305600304330ustar00rootroot00000000000000PNG  IHDR i1 iCCPICC ProfilexXgPMX`w9%眓sFrPQHV""HT  |﫺nW3==sByOtt8n{o& |~hw^ydOEƲ~ѱ`ƣagƃ8<}89Dc K}`(!`{6F:""j_1? =}|~QH\tO߇[DxliH?YiEyXڮc!ngX -Ͱ0{L _|l?v;4 ~8a4 *zX[>AD2AT4K= QLY@* 6!B$ qB($)Bd YA; AP<eAPTBU&tAF  /B !PG#,N/D"FD!{aK,b D$R)TG"m{Xd2YC!Y2 P2(-凊Ae*PMsjMBКhs:A/o/tO ÆǨa0PL*8sӋyǬaXNVk`˱wcX:vGq&Ha\)׃-6xQ&OƟ7Ot&L'hLBO"|'BD =1xXFB$1P$ <N2422L0|'Hb$=^IR3>iHee4ggڵڳ:::tfuu}tt ][ԗտ@ aa(hĘbl\a=HkcNlΫZGC 96['?Q|~iqN((;s2)S5ȂB¦"rQJiy?J *=C8f̪\|"eA*ܪjg>ruimGX]i=>~a \/l7F6694=hVknni9Պhop%K]m2m._W|}u嵾E۫nPou@]]nZqKVmەwX!dMݻ|/|n_<0o?ڃ4n>R9:X'*Ontw,+!vw'VNn` )Ei2%R3\e r%sZv_PXDy M -J*.i3l~5!7";b:cbntG |ǧU=> %Ň ?|"8my9 Wү&hMONθ72 7Kbb>Y&~Ҽ v|8ٲm? r qtEQ ht3F3݇N $hf-2*JZ{ZktJtO08aX`tƸʤٴŲf5gpӠ+uWپYo!o BVPdpUpF8-5XTGb,ρD$䒔}ά<ܙ5rSű/8~ĭN-"aP+v( ->S]v^HD\5~vtx.nnm^jt Uk%ڥnvwv޴v!NaOݾ{=Pwx3P8xihc ƺ}:kfZqm썹y ߖt?nYs j7u~15g@ ! (MQxF!QZ ]!b0o.8g#Db!y"S(6sY|bCyOMaN%3_BrUr+s? EO%)#T+l$ +*#L,^]-")E%!#$J@J'?pTLAiTX]_uAM=^CCQsUk|O]'=i}Aa1;63SsVyk\ulmv+o`\RZV^G~oyр `carVtvL]쭸 'RRoO?w0Pdfa,l#9zG5)K?!~RJ~]Q%JY)gЪʯ^VΥ>yz#oKܗn\A^uvxÿAͬ=^˾'=&?5;O}b9k1 @)\py S%Cv$xL@ _+@dC"HGd9r%:E3mq4bNK8<.ׇ kD^b.q!ɘ(XDecS˔`"5%;k2`gfoPtĕMny B5BZBEEzD}b-4@k('% d؛˦ʽTpVdVQ*TvRTyڢ1٢BS{BL]OoI1ɢٸ )E_6,vŎ.ܮnWNYhY◈O_YXH5ud{l@ː h!鎬AQD}4탾g{1Wx.[TBaEc`#n13v1i2Y0ّ% `вp(BC,D\P|V*+V򐔀Ԁt 9[rEK*e_ߪj!ښ̚Z={JuTuzmG Md9LP&V̿XYnYclm-<]nθ#JxX{yU{1 ಐa#Q)+qf ]IeLiYF?Wc'NvΟN*VwUU:\Xl( lbb׶k;:oR=ۓK7|?G O`610B« 7w?M;^޻ht/.+W}qwۺІݯg7_f#퓡eD\I@C9w0ژ{XK. Wt KǘdLb 7SҨ, p'^psvp>s7/[QBHWX]DETYLI\f(-)!&(ɑU+ijkQOD ^ÏT S_\V'Q6vfnNG\\Ϲ;1}n?o_0|ʫ'1E F)D7݈7Mx䑼(;$ٝe=v5bœO. <<Quxt-|E#wSmPk%Ͷ+.WG\va\?7x>(2T4xd l3/S_|4mlJmZt2+Ec ŧKe>}TlՕV_'=ڏkkQks?>\W]`Hݠ2wMͩ-խ[sǶ'ߵ\n\~.ͺz8ـJo?fRvQnbޥ|^ pHYs   IDATx ]E7~^$} .j@YqQgdt ~.ç7:fe#NTdW!J}#$;Nz_wgUVֽV{KJEO-JCb92@F #d2p PCCkѣ-aqZ\booGFF #d2@F #`"MMMF \ӓd2@F #dNt`B=^WڱcDzcl+#dtzC~aܹs@F #NnjQ<Cɖ-[z 3fq'&Lf Z>lJ ԩSog',Tjg??3WBps5׸$8ns#X8+Vwܡ1;we˖i4 8(6N9zSN4A]sͻKmr@4eojl@gzF #8XfuQ:o"1^criɘ1czL8`N-#df4 UnyGuӧ,,` l޼YgE8#QF h6WZ3˴iM&&NP;P{7oQh?>N Yem%?@fd2~%TDt5LRgΜ%K4x&K r"-ݻdIO(Gk)GVmIrɅ=ɩ@F #q2*pXzɇ} mmmK{[[[f`MD v-6k,wwɓ'RY@69pڴi*(X"P_'N}ڥ f,ˮ _$'MѣFi(?*+3utʶe,7Hh:G9Ms @awɽrm3JƎjv鐻?% VrY5TTJR)ʜɗ.?A9b{X9@F #__}ɶm䤓N>2W91_/pVK|9q?.z!g@֯_r(< bƋ u @aڵ:hMV:}xV[U&-IlnذA&MyOΚNcR@gzF #x* оG߾K.~2_=(w]Z&Oh1d f 1t+k&{.>Yb/w 6Lof+_FYc[:d2#ooڴI9]}s9`vB"7:,t2φ;!Apv,z1`trRSɖ mr`aϞ='}G|0 L!Ciyd'vHS+ҷn%].MuhƗa VJOp쾅?V;;;;q s%2{hu(CF # 3\m4g#w✭}h}t4M5$5BC#(,,_K|W>bB'n*~zCtF #x!+[lo5r؂cg6,:gP2@F``+^^;R>mMگ=l*vwIK/0ej,.|kYߐQSQ^}Ld2aG&[Q$pcol q s>Pν;=; ]&z6sPCY fsر*J > CTd2O1\s2ͣqoډ:4e筇uxk › !Mϯa֣l2Lȗ)Ie5,9µ\Cީgu`w s6|i,6 `} Kkǁ߃s:#<hK?UZ͕'0+Lֵѱq";wI 2א2^zL>d6#w,1sCF #`i.g ,M.c˖-jXӳggyq~,.㢟\۶~Vd2 *G~Vu }xm:m`>ޞCF #<p7 5uu77yɝq㵅2]-b^]3-#pd_3 j)g2@F`pj& u<~tsd2@F #?C.JMF3Tbszd~F #d2@F #04?1~d2@F #d2{kKY0#d2@F # @d2@F #d<>,@F #d2@F`%XGN/s_O7A}QYlcc6fʉ'7|f3Ø{.,3d2@F``}Fߜ M~{$7ϭu_HwF̊p;&.@v@~<Ox`+ghpg@F #3kNo{ vM>Z{{ U}3&)=utTCPF)um-֛.7X~`rʛ0a?OAF{κ1 "vz'>$T%n\rv<#md2@F #C7m^,ԑ֎2wޡҍA_; C ]|BƍEy(9y\`A]K[w=g'h0O4 rg{E֮*K=o#_ ɩG>t'M$۶o7?Rm>@+-W]т@ &Ph>XwuE/_G{08| ORK(CF #d2OOM nҷGF6 IiEy)ЉKeH{{qqc\ =,{( :8Rʵrh=LI=Ҙ^Zm/s0JL0/X@^L1"֜%"8MZe9٧@F #dt<**hXx46i_LӁ(Œm,*J*y7k ;x>2x:˦n[>w6ˣҕ}#W^K:\@ 37v84aG4R)@6xٍi{?.(-O mGtc.%y_m۷U8Ƹč1% ͕ KF #d2&ɮsiIz: oE`:D?3!}wI9ga2a℺ z^n[ eV-{ڔ}I,8U>ݟ4c6waaǍ].ir-[ BFРw0Na`|B|=#lO^+޼0w6r$ވ6g.-֌O4Yxt!qgG`$2O<9uϦo9ӵ2@F #x#˼/ )A뵇bک9iVKJGG'_uDxn ;e⎮<yIX%}h9jWwkh_|}"fQ*2sJY>f 6`WN;oxp?Laʨ߲}|up"ߋn4-A֑obcg9% ,&My6ɆeQ{ڤytz&ڷ^z'Ikى;vi8pG0)g@71R+>cz,Ȭ\ [._L02뮓 /p9ĝ;ȎZ96wG͗-1QZ5#BGdҷ˶ PeG)Hb2\Zř%Ė-[bɁ[N1">G+{d2p#U0a߉g?*xIڥҗ#M3\āH#^NGkc[g~8i3]].͓6af@qȰ˰ET[ ۮR+h#rXڮq@\pn@|bxWeg86^QnRY+=rͿN&b)ViixO5CGOl/3φ6>c֟3 cz27!<RR笛d2XRž(L6aT閦N @U)>^+olZ~BޏN#Xo?1e04'RF6;;˫jXOBnLQБ#g?Xy~.b#buCi^ocҴ oTL`ҊNuc#.<< :){ bj~V|?;D<8 9s㉂XXB )eZl CZ@F #<G {"@hi fG;WyQ译U:r+~\#[^Xr6oޕ掝?bҔC ?8t[k~ъri)Ϗub;pq 7ȫ_;OoX|FǤo)/ XbM;p`&6@D0"˻K_^pT%2a1apcmm|6I1AVie۰x"`'@ڕrd2ģ·Ai@TLWp#vLO@ y>|q]oⴑ"?OyCǒ|C=6twd -\8Tc(ti6Gb`|~ks8H%ArԑRei(fz)k0,2m+əCo"ݸ/}PlF t4$ q4 s`@挈'ΞCF #d2O?Ы >}O$Zwߪc?˯x1ʱ);'+4Wȧ,vwZSd庲LY ^Evu4AWϟ7·!7=$wf@Xaf?n<ģ# s \x025 c<82k,Y%WzH&<2ai!jG|#uWEuqPq34Xvc>%WB_^àЧPnR]%~$$IN#s8Hx^G'6fϔUJkf@pYv<;ct_z9|VIƀ{;\LEN?`% ;-QôUz0Y;p3l}skեX|(z @ IDAT o,}l#=X4Z0C"yQ y}Bl绻9`ˮynu~]d2@F``|ޱeĻH5 ]  }=X-DWO?eY,waL>+o>d6}(߻Me0:z(^j~eʔ)qըQ'@o(@{"=4Ap޼y#Vi ҙg)~g;8S͙"fy{dTa:J'=FWCukN+4:2{lޔ:~$E:uB#OPv8{©.x&@o6[SN9E^vYsоwF2|  )/:L?6|;Хl3gΌ3 Hp39Yc Q^(Nb{2BwO~l8kcn1=b'z姏ڍhx#2ȐnlܸQ;|qcQ9{lC17xכN4u07e@&N?t}0oZPukʾY4Xhd%yiJ`im۶I #ѣF7qՍ;B5?GY.}Ny:/Ǐu쮻իW\gjI5CfζnwRlYpst?k#|*b_9)Mi(t?x9d3@F #g ؇Ӷ\Ě鬒 0v8RrY L{w.4צwɫ}j&N/qsC9@,_8lGa!khm#&ϒygǻ6}@կ"> fLG ē/@F #d2Crc3r~Ǚͦ:U'ry axƬD9bǎrm ݱ#jLr@F #d) \gF #d2@F # d2@F #<اwlq}>Nr.zi-Z4(wl7sYĺ _;./$au@F #dF'V/^Y>Y>@_ }&C/Xbg@:ˢo|Unh8= tˮF[{˿,KT|T3˾ϑ6"W~Q>s?7M˒Eߒ#·>kDH>B'ʕo@?{ݷ˷:EՉC?d2@F #Gw|ŗAfc]rnC_{?|SɅ f`k| {\_D>rzo%VV(4N{Juf Wr6}w@{nɎj ws&ܵ[ayxgi-oM,]no\ʨ2^%dmhzz>_$_ޱZ~t\?"ӛ%mҰ61_E_mê 9/+|y:R?5|Ku7dϗ[e~L}T}[N:_oA۲oIYXZ;I_gsY'#d2MRiǰA ߳*xh`W} M͏_- >as or\rD|>4⭨=9\9MićDk[|\nVI/|t ]MZ/VڰI6n);mQxիHEX5lLco.\( ^m"ޢ嚯}ևIETم߼U"_|,v+H: *_چ/4OfOWz\|]-ҋtgw'?{rL6#bY;fv& wrX*x{UC Yq;^ujum[,w ]]n-\=Yb ߓ_(6\͆5vh[Xmo_~ ؋>a{]"[*m2} z/Qtr4~_4ɕrїʽ(_q./wʯb.ȴˍ -_ɻƻkK+7#>፺$n!#d2"yoBfVƞ^Y?kX(X.[xMg% <*Sik/R FV^P.0`藢$Xoh>]{O/R30޵L|B_x7oByۍW_(_6p?ptnsT4S_.goIo+HQ.|_6ݲ :i\sgP~qa9/>%G_TdoXt՗=R~xϺB!].-?xHϝ.}\/kPPu/X `}Ee鯓*/k~ FrTv|{E2__.6[+oWO7ROȢW42]*5C.O]Wˆ.\n%_B:xo|r$o~(?Qk=+cղiw*r+CC_3N{\!|Hߑ_x.y⾟/V#}軮S5 eK̎w/gߖ6]/]ܵn,(_tMWM7|U8 HOe\[ϟ(szW9x*˔fz_ܾRzˆ%.z7AZ9Y^(ʍ(wR6-ȿ[m)5&̙l|^9%'HKni>W='dy_ͿOJǎخZx^!s2X#Q/[1(7j9zܳ;r5&]H^4J*fb4Na~n;+ɱhwL{~-O}.JsքgT޾j4=-{'Y+ln|qHKSWmzϮ["$-ʥ?\"(|N<#c"=V&rwEƎ$'y2 a}K VE.[/r*t99SһYx_uT#O?GA(!9ߍmHAVgm@F #CQ]eʱϓ"ٴ˟W=}sj}կc0xc7lw%u9Klkm7zDF7B@Z uس+/{w?xpxf@^t+׼]-9'Js9D cڀC]>ipe ÉL c,dF^pdenu~3@F #x gu5eb>QZ+vY`dF;MfZ"nѯ[mAk&yݛ&=д(M~ԁ =ɷN/7M!qn>]Ί;;kEy׼},2؀*s/Fk{Bn?ʍA;o]=پK:{qy9~yd#^c +e"Tm7ʄg?x:Шl wwGQS&ȑg$+&cϔӦɘfo C%>g̔_!0d%@).н{k>_yC!X-G\~;}E/У9(zdCdڴ)СBtܾ]ϘDK37Q*ji~k&' (=J: seV4omYLwȭA.y䎕2sh)7)k?2r<1MtpLX(0[K?2x{uI}&Yf\+q q7-v~܁d2@FIB=ʕj=dѻk J.h}pr8$zKe٫'7&}=;HpF,IxptU>dRLnG,]xNynZkiX9sE\$ʽ.joN;NN:9qRi=V_urqv t0 70vZ$_n=,#2K./_g*'Oŀ@o2#7}N>-@o[LRab \ڰj[A7bxgk&uzW˳g4Pr!e2r? )zvє,`k~@$F9cE rͽsO;_ |K_YLNdǿ$ג3v|:Z?^۾S*2f(bO<}عxbO ʥ7 ;ƌ+z|Da[__un=Oz|KSYvlw_cAuȣ-x^}ʨxoj@S#ٻس-^i8Q1r߃ɘQ2$}ha;cǷHniĒ7ŧ|DxN`^14˨^{3WƷT䡫Z^o\FC+ 2@bnR@F #(MmcdLCt`IBJK~^ꮴx:wD_j_KDj}Wx|E3|n >],i= 7-{Џ>Mҕ68=xtR޳mC۱@dVtrGg&EoۍnlѾkl6 =;a!-[x]MXsd@$-uz |"E'M v͌ZzِŃ@0·RNFniMܸn'|b<m} x}ڽM%Iw}~C:"T_L%`Zlv)/FŪ6AH |#O!*$dd.d%4T缴Z)k̒,b*^-b#\/†*YcQ)P+|XPhᨃ)@idex"|W-ITBu&/kT,!|n[~DQ*Kʫk>AikMh,ƅԆo^|\(Cb|UHXAW3XCL]>0:.A5ne 2?Z@UH X5Dz슊u ?0Ynjc$:f+K}%ߖxM|oy$QΏ4*h7fkB@?PA!S c w&IwAx7CEM(D\8Gyix/R8)Pu Ffa(TǠ(q&YYNw6Zl@^Y;"͊RITiǒ:B:ndV1uT2Q?1hqSƌ" 'zޖI6wlU|*ڱm)Q(Z4m4~Z3 8ިbfF5T o_f[Q ]jT+Lx$%ZM B?aF#biڠ< IWQ]嬘s3A.3&dŤث#Hu{:羃Hܝ SU& ZYKUIz,bA< Kƭ]F! H7m9l=$xW~EYP܎hZ8~ЋkT$WpI*jtoQ?r A4b֭UkKrum t٘O@$_NJt dK!Qe@FUDQ~Ruu У7hTilK! <:YLPH02Jٔ4SdDbV"ZT6mDD]!+JF̘,IG6m6Y)Hi{%Ap2(4R+@]"i`[i>" DU;T]|u.-O"2SuB=NBʹC%9vG3@KiνI^QGA*JpA؅&t/mwdžJ݄ 3N:eaK'y z TiC6hL h<˹^2JWE&Bm$zz%LBG)siYI:3z xJQb,7q]!C Z\~UCCg@ȏ]EPѢLSz.Pm_7ٙ jN7j)r]ANY]Y\>mQX)GT :!R5FgY73)D5IbY!qD1UQm3,qU2HM!JB t>MH\:5 Z 6J2)Z54s&<&zl&x `ƃ]9aPa5A6gTEj~+.QRJSY3tyR!MMD UX`;֪I6ft -gm%,rj.$3S:Ɠt0x olPZ/K'P"(B:%U#ÙVKRU@"H|fJ.!$aA.7M\aϜR@!:^?1rgfd.#0y-rC3҃L^+ P[ 5T!`64Ta $b]?fbQr0t5"_LYk(e)BVh$ ڜ6tds/\1M*im1&=r̾k-ҺS4 9OYehA8!E$jBRAu} v&TO7Q?v)vnHMg܏ =_)tYu't;{t*i0* }K<StNM>D[S6i ["Mr)j"ŏ8Kڋ2Ev"b'HV1uG P29ľUWh"IPe>u6Y i'<G*_Lَu^2{<Ӷ+C*Ѹ".u?>Sҭ7sUT{2 s 'kZˢ %9PP%PFhmk9=6=֍IūNLMOLW ZF)D"fH0Fʥ ni>a$H0[M3H0]'SdmP{̳ܸy`e>FT2E̤QHL/*c"ëS7=QN1;uTD9"@ipY}nj; hv1Rs)Ɣë4T6+sT$g)#0L۩$v4L;Jiw>whQEnT fA&zE2-SZ!EueU \g`yZ@2oWb3 6B$mDnNˏ;Dw2BkcBbVQaL (f T=+Uu"f#LJT, 3;&E:"QG+1\LPyup 6'VFPjRb̈́MCY*Դ,5]%`Cs9("5MuhG;Gw(׀zs th4isDp濄65<2 }Êʁb ,VVn6P0׎T1!*m>l7Z2+MrS7p~h4hՃymcEMYmHbE0fPOIm2Q4`ЙTc ?jɲ͞<Kr}*Q̫BP+qgq/_1ۡvHJ1mltt :R( r9خ !J ҧNIP,$Mt}'x8uFT@!c'P- 2S5惛f!TdYi!L\tӌJeص@.}}/T&%A11C&Zb< J僘E`$2..P n<-NnT! LՉ YۚRQ^ZtIHΠzE DŽSڪ|%)f Q-&+tʫs 1pL V{(j lXrfAFrJd,h !0+y*YMS OUޡ|6]iD/SyGRTc.:BJǔaZ1SLX!C^mHi_s%3YI$zB$]U7j/t]RB=ِK \y;gOw -pvJjQ^d&BAႈc-_OC;Tt,왕͝)UUHBW :1t504 /҂BCBwaDqU |'&0 VqzqI# [m5UM$4+زNd1 'аAIt@Aܵ<EmJv~E1/CʨrdyPʑb>h nȱDȘ $O)o "* ( "f.:q 81SI~F9Sui竬T"O!^0 Kh6^!kۇ%!W,`݃D؝vzNjUU:3c<ֽZƋbi Ro~]QkHs@/Jw(_j߂=tr&9 ߯45ψ_) ` yD '@A-A=} pTcJ' ABg@ۗ [ =hN\'@\9Bt&S(Ҫ2$ P #u:*m[XaԎ!8nL&\c` (fCp5f&!v`, tX֜6gU?vQ). t@U|ǫ*}h=ƱL Xp6Yy.f=~?Z0&%\ڳ#O U$S;^˫ x%$n29y,)m\\9I%o Ɉ]IOA[RR.mPiCDJIAPb~,=RۮF4RJgݥ d&$seSX =_$[̀VE P $Vq=V-PkSEJĉAa\7?P3񪂯g'r;tV * v+<X+Tyr7.g@K@rQtC%]Lc˘ ;A=% 3Ap^hœf˶VoyzC] 4S[<ۯwbf3L;_K¨u ';M& 3S"E(^Wz}Ge%'- IDAT+u6B #q\a-jhq4Hlr#{I~U"P0.y++`BC۵2lʥLcCxʮv|Kp=8&x.c@+<LF2~6JQ,IpUŠf{i>Qȭ :| Q,t5Ȩ?-TFrjBp#5y<]c)4ruq1$1c3c΃D<IOtA7?D:*&/p3fQˡY;lf t EiFn֘^ 2&j8uZ ES.7s) XR9&fDbV- \Q yT 6$EE?M9 = -#F]@`* sL;Rp0s'Q>CuPA 1#' vJV€w| ji&eY4C)E)Jw&bWMHlD! 'rVRBdzćX;S:f= ciݭr*#P`ݍ- 0fܘklW[i׋[޾i|cf3C":bbŶ1PVƤ"8IJTJ.*O0 ʒh6 :8KzW(lB̈́r!Ì`-EIBM&c>LbTp^S i~dPXR5w}M)lu<(6&jLj(lQKoLR0 m*Vs_o17|0UJJUbO 5#< FJŽ}f I XRDP{*iNl _NwqƵΧҾkܬƩ3\!Ҙ7uUPq:n9#dlXKI>H*SE^%>z2LG:6i:̘]m ⒡E%c͆X c) Q vMϺkwYk>:vi Hi#2B@wlh;$ `4@tM A)mSӯYfZ]8:?8y[6130ض\/ʮaI/ᒟq9xO"B>]q,dvG}t_s,URgܱ*dq9H)aG4~ZXtacm!' G!D断qOPvb~47>3bvCl6ң^Ğ/!8g=.գC<>KN~kvJӿsνvqX { ^f?T?po}Sp+zw*㮪 ɹdCJX^,ZkAUq%!ob3@Rͭt_|&QTH }e8vq\k N90&Пn L|AsIkI.nW4hΕ` Y38W3⮫P'k^MZrq54KӪylp| ]>ό+气r"NmIq)el@0`:u#Q\Hwq(s<&/;O_^P`D'3q&[ =uda T)"R<`Ƒ8v"$jVt ctp9MLTsaciLl4EHPCId|Պ*\b0Wlޕ™yj#.H=ޔC{KcWύVka+ÛĉpRs`0%~)p;up}b|{ ޴!8Ľԥ7bbC%Aڳ@S1Hj6Bl/ac [c[8 0W ˸hQv8 nPiP~(mY6'[Dz$6WLRL@%*+ꀱ eC#Y($' 4FMRCߝx!;k͆۾Ofj)zbu* (RYN/1 pu$;mÁ?r7pyegJqeI S>`Xm8:!^:~pMWu3b[`c*WĄʛg>5hD_\AX5Uw,%NKp\>0gL7~1>\0;uxR@ɺ趍@b: U#}kЏ^YǝC&/dr~^'K͎^wBWnL j؆J`"ZެG+B8ĕȶ] y(@q3M-56֝ @ɞl8ǽTS2&2s#^x]\T p}!ξ)X:191ӎqQq-D~7Zr&l4n U,l0 ?V{=I{ } цpI5 iZ|ű+~x8]KAQ%«s^\Qk'%g=Js tT;վ^Et>iG)@01DŽX+ڀy͇_͐sWYץυƋhCEޠ WE]xZV[]|E.^Oo 8̗Y垫e%Uן~M}O^|WtC'@4y,g=3D XسybԧzNTEF~%j^t ɋ(Xǹjb&d2CGgؼ{ݣ ʤEs;1#C6| 7KҩvxJ)A_ уαsqk[J&pԐl筽ga;DGՐ} vlh?옮Wv${up):gO*9:78d_V!r<=%HoY&PGkwGY1uBO{g8WcG\9*o̭hP۶qk+WÙw!]1&O3GBnL 29ƒɛ%7GVLZ"0u6*~4n%Ad hMu%d ށ'zn p{3Gd2{B{e0rsY|tHKJ-Ӏx,ewa!(h`^P(+{X ∕H,a9e3-\Ds-~v%sn 00x@-zmoJ\9=X5Soœ @Sl=&W7?$Waa8f9ӆQYm pET蜌G'rZc̸quI8~Y .40dsS8l0;,tڠg;³&B:汙x_3&&k $v);cp8cTl)TWA`CSɆE 8W`<}A/>&7|և Cl))hWKS{l v߸{T + `:і|nZ f^F٘jk\'FqΐhI#1mM '!Ǜ#=Oym―{ !Orqa Q^tv$1!F:;gdRei-.f9eI6! 3䕤e9%cVr[89;UښH }[}O9A"_HAɼ]`rrvWm6tA=O@EB-t1J sR|-uf%D.tµ[}60o IP0#swnT 55W5l!녈`ãW;[9P&zH.5;·KS/ĻMKs `Csj!JxYO]靚qć^dh@ dޢܓ׵dom+ςIXr1!#MlX ,3'L0dZ'=xYmN臇b |2 X9 wāio5:;sp%:cvo&q^dEj .Gs|j'9g{SLVy&~70>k$H>2 %m] :S]3_X d!cZ&o ޳WX _*'vgCwDoߖ\IݪQ𳆌1_zex~/@L8il|1jb<7^x(. dV9%&9h#xË0/Jc+Ћn3!8a *uRsm!B u#Q8obagSwW͚c^'cg[ydv:}|c馷l^嶽4GZ/ZtR>WD;"U|JgnAEep4ls5vJpS;ڙq2KXd $ZU@k{=HۤPso2!6C}(;΁wl Z$'ގۀ=FBA c[%Nם:°-LAX?2 jZG9ДY&$?ئ p>y%k].k' 5xq,% v|^_3y*Tpzd*ӋRј6yK?>?l6Iψ.G_'ml];'>Cuavn.odZ1{||v?wİͺ024ol Ne toFW^6bYBjPӏ5\Yڽ#c8k@۸`۬& qy%d x:T8NID< DfSCdcXat]Țs"lN sA1\W"vO\K_9570inFJaŋ=ռ>?P~5owNFe'"]Q+T%zmG`%!'\muڈ9x̴P݆_Lvu=d,n\vkve{~o.xJbvv9K1yaQ  Mq,Si'r=5q0|W7hkę!c_C9HSE7YL'TOA.Q8L#nt:ܡqq v>j t;u 2[’T(ޖs3m.K<{*R mS!!!4(9 hj[).73jǜ?Hʕ l·7O v hHOnCKc} vLۣ+ۚk1Fe/7մښ?sS/>:WI\b\+.I<)(څZ`o$& uYWd/W7w:]TKHAjaß$PiE b֧a)#a0eÙdd*8qW4J܄ߨy{[7L"ne 07e};ء/u Ix30COה(Yt°gr$1't<~@3!O+=S\[2fG]F9AfauP^0aKgɄ`<Lfĕ|'[C8ںyVŖ;5N&?ˇ&gck3hGVeπ0{ & X}7cc睅˾byb$ݸtbi->[>ŬwNTh+,3 _xQ+f"> Yu|12UN$u P"};mfэ|$/ %k:qnl`=ȐW_Qr$^4Y0I^w䟅.eTf,eؽGxђPt'QK͸eBe0W4\#ރ M;,` .^ Hv5&xf1cB" +FXJ cH1s_<' IDATK&QLWܼfn ME+tbI̩[v_=\V-]AGK [}F;}OqoD߃ rW\}gy#6N64*b޳:@Y3!nZńY!?1֘>yȊmhSJq^VXG8|#y .R17^_o~{{{?p{˚vadOzs2OyȁSZ 3gSؠw;;evg鉠 Xֻc.4Vs5Bny#z&?71y!#2h`rhxud^s x$ o^ָǓzkM bM<"H^ٿA:unh%;0P6$O !J(Y4oܲc5{?;v ߔ y~k'mActi^LڪǹKyTZ-CiC}faЉޱ/%ar5Sl bA>/J1V?nYgt,ݟZF E7|*,u>P{ 6ϣRC46QҚlTM%Ѿ2vNv ۟+6?aS֧Qܦ4|H;5-پZHs<}\t)zjŇ0c9ˢ}# J'Vpf3<6CrXsI carWTF ff#0r ҃ގ+.2,<ϰgх_ڵ$V5.ٷ ~3`FՑ[G stݲ58:Ρi7_pCrg71&.vP[\<6сqYrLh:KikWQy z;Koe L~#Ĩ1*4x<^wBuٳstUˆfj͵wWGYo5D昊nH3!"ˮ$HP'y6l,\* 5Xj.\[!:Q2UG\}gjɆs?5iί֕0 T8'1;#Ys*2~3+!XlU֚\vtx(òbP0Of` f4]IƩqjy9R:R:%^FF8hqS]|C:6XmnjHqv mJ@8l]ih,Gcߎ^BۤeȮ,e+z%=uShGqa?uL2uGY:g柉9T )隴ngѠ2LaQzk3ܩK?ܾ_ʛ|/ß|SC=coZP0>3O u:Jx*`Rvt 5i+z'cYFp}wh}8x֬0^lS9raKCu b KS{{9&h.@G; {5|f BTs{9{3Ek 1L'N>Z{[iض 00Gy )3| \"m~Cgk 0rB [Wo&Dyf-l$169V#!%{f "wFRy<%n|al&8? M|UPn(x3uFkz<(J8ɕsɦ~ ANo,rٽ1ڳk5O،pܒFAM5pxO{Kyd3ul:l3x:O{Jbo&g|+_o=u9g6EExuɗ{C6^t\`9w}>QsyѸ~G_^m+"Iy/? ^[`80{H|[!CI'ڐ_WuGW.t?nw~÷/~/﷿WW^9C$XkN`ș-%UuL;  %>֐Wц hy “t]:a On;LȣZƹQ[LJ,GtnW?5ūATna,)xHˉH KI/%.~eHZ[S6Ǻ '1bX aq'=^2,.!RI.Mf0!c8SE`vO2fG޾9/mIel|ȚS|JEϧa!Ͽ[!t^#zmfXFqc7tu?5\rLs+qȵ7}g:6S 㜼38IBS9dO!́JаN#.b346 ҟ :|E3^(a%C|΋k5Y5Q8o꓏S?۟C#?KWo}wdЁ)G5g؜O%rZ^bwteRa_FԘlw26W'~YGbLÐAk\Dk8(33,]`UgH Kkd8AO kB*7Ch6Hb ?`|p,&Uϯs@m7M*.O6S1y᫉f8O'یI_'vv7O>}~T4|L!fyeȧ,yYRP-7ssD9oH?cJ3 ފ}"t{+6-*>VPyR1R'WMF$N$gs/puQ^\o?hjm%xqYGmfJȬ {.8=/ `gT/pvD 59rs.8+݄(s>S|0k.gM{Qq+$cS);[/r<ꏭ n}^x+_{Mgpz~&=1tDK.|*b| 1Qp f!G\ :w3"edD.~RMҸƖwܸGWUFŲEAw44o^9aϐ\Z jl{ ++)Z)Xɞ}X%Ajܢ k'Jh>w濻g>{{o|o|_|ʷy?z{)ԡc˝#`ٕޤs[=.cvliљb(/@R@0};Iw,/4FO~A#UI $h.wGe3s5"}as”(' *:`c U=ӿhg+,M/u9Ƿ"fiv^"ʻ\6ਸ/CGeRU9ָV0T*, +uEIp`;bq=9Ń($t HLX%O7Bbʎ5 ,~I8<ְ'8R}׾tү|1e%8?s{Ӌ'^O'Ft^rRs1U *hTj,1LjO@pNp5)&biUr}e1u:J[lg,øpK:/+ r>4́^K:h=E6Y#1Gj(r L'IY9q5w_P&"ٳC3d­zEO"~zS*i\/F (Dž\!Zmak uX=1f;un_ s;Qg,d؋'pABaK/'6)g6xQhh^>'=O'5rxZƼMtZm.@6F/q,FFX!lMsDn',W^>(FPs˅,3sZRa<EF쫠N ~!c6$}Pg]U,jӛQkSf0=ڡ9ř@9.YOp 9Ԋ>̖y¹&m ag]U(|dIZfX91wa=-=|$Yu lWձeىy Bh!+rKQ&# OvZg&.wMN'屩ޕ"e4+3F-W X3 rr;cUK9nMNya?㬥Wn<*}_\g Sag>{?uf_K!}xkrժޫ?׸eryXC. 5]Ϟ▰e@֣]zspEXEzdrͫ-K~mfI:R΁$~bL/< m%NMe1RBIFH: k"E ۳z9ʃwLzN#C +z[ؑ'-a+yq[PXSAzRb G27ȐY=H8i[.. `tn#qo|y}iu`χsZ1ų;}APLơ;"#ʜEi( <<6Ӳ\>'dGl'Sڣld 1r:GHSՀO uLw 9+ƹ&Jŵ1ҷexݍL{<σ[Y͆f=4*0yA<[Kfr{z6,w{I>ww~o|ۺ^~k_n} KnT-s;'QdSOOmið=XY`ݎPQZOڪMoS0n[r60I]rh|lbSƖ(?!,8p1yVj|h CSck$nJ=1prЖUzrO%˘Х]%8_R8/1gp#&Cg٫+]'x67gy|tw67v:Lqhf22ZͮgQ|ZَFl4r&N;{u&F"3+ybbؤ) 9/=q&^gYLKҸ-Zd|OBtSaXz=dTPSYـѝ`G R\U~ˎG^El@lٕrPQ˃V v56)/,a30s ka·l25dMBTh\wXvn%# e O1WHT^:I6ӵD~—y ?6.$6og{o(%y/!3>b i-|#c]b>πl1upZ⺀ DZvԙ`63# @=qq,`΅u&J@A"Q#6؋ڦ;JģQ;n8oA]w]h2I`r657^%pgC"GE7NdλZI׸Z5c`ّTq刷B1uO߼{>p{W_~ C?[C?_ODzḱ-yt&gן2 4SKPg@#$ړ:AUB~Q1Ǚ R퇊nLQG@bG3w]%͋bClLlwNe PM' ΣǡX)kxc^^>PA[N){P7r2)'k\$ =mS!0?z@X^ji"ւ<+n%ͧ<3Byރ8-fW[2C_ZyNdU .\>LFB0YvÊ2CƁf`ԤbM/B fF@(D2>9Aϗ+y+|Bi SK<#c,x1O-3@O? >iVwgy#xד2$wʈxZ׬ =ĄA^IFT6sかΧn5;Lb\|b'Mc3gT ldd"F']؝ʻWOz 2{nxh1YN`yM\+<A6:_Rzn zQǘA`o?>^ޙI4soWh+,q${55SaVt&5?Yx Ε F Ȳ:Jw67J`/rv>/'w2GYK_~r{AK_}Cs3FRHV[eQ}/y(Ӳ+YΩ5- ty߻_}5_qʗr)})6cq{Pe7CƨabS[Ÿ虭9\IoMaK~^o}#;=2G䗼V?3~|{w@[OGThU]OHK|r\L %$L DEaYҶ 똢0 M‹䯄Lf<X3h\= c/BYgxӭv׉Y0ZVClkrܛV+hj2Źj;`؟SE ;v򤀅_Ʋ*vsTStѾ$SdĄ.nWfa@vfd(Kl{τ2'ѩ9!WG cY]t|KHƠ5/5 WEB(` ~EQ%sH͝@ a["l{g6*뎰:an6b{V_ɢ0A_c'bkZ֝-?_F?x1 +s 7Z/==H'۟c?tr? ?g% DN3&5rV/N\믯؃ط3ُP׃[zN[>`/|_?{Q;ͷnWbOSϐ|C}}ut+2CAe _/Jɼ~ V.@]7\a#'cBcC 1|D8hyBⲞd=ú>ژx7KeX&%( fg[Z3^DSLN8LUP52"9(ڈmmsW +\ 0X4.PYgi9D4biϞ Wn<~Wp<٤D{U^^|^埽Yޏ~^K$ʷɝ,=^s)% O@ϮXj%Ee* G${H͌\ ~DǞ* Z'+̄J-$rat K=Q(m`nGM'&,|z˥Xޡ%CYWgX&1K' 3iE:C;Ps4E<60]9 ދ2/Ob9p DOşn>RY  ={u|ӌ?ᑨ\} REzxva xA()yR9I]g yp3t k OP%+wsH1y|[: +jrNxjݪџ8ZX5!麯Ak)dC ?<-8cQ!?' bt[pq]P"> ݘHm{oX{qTi@0.?*߱Q{X5k/B>aon8*NBw3*U޸$= g1#P_! ԊߡRȍc_7,uIPMu̻uS<Ϯ8 k"'Ïn_mfxO>|bSyA L~ccFvzL9-aaRP2Fkq>sml5B[|A޾[('!z|2~#yQwJ9^$2Cࡲg&VN/k530㙤V' <}~ }2u7\#;_x /KWf&R˸6hz}qmPYߩ/Z1,S?VI)Yt;v{a ч<)iΏ&szƬꁽ; \aPDlz(18׺+EɅ Po$}{^]gX#ۙ,xXޔ+B^~_Wh92q}DDZYQpV~z&xa{|m_pgGӻQ8?jxh:l-}rԿe!z {ut49oK)Z>o{;$9WG5A -slNOk)ܯbw#/KZ Hu>y_}4v_0zV/|5-CR5I>H^{G&E>tIEn;cLwF"G\2xfp ` oHmW05_ss*wr0{7b 2, =`nr@q];"u3 1 ǃi;`}I^?]2&׳%lq?FL٨50J].ິ/ PgìZNkkqmv3yu%eԦ҃gbB}^X*}G8<[\㺱OȒk΅'"cc[-'PchDul=.\]e*LGlzp6p @;],[+~[ 9?Ӂ̈́O"mMJnryAޗkv4dLe#!}mOPk}tyƨ osAfDyIS|]?;?T>!_K/>ߧܪԐ7$U/g]򈪨?0mv\3+4Am8cԫDBCsk'zT*=73a\0B{M<|y>hc>0eX֤b ]<c$ D=dʳITg=#ɹ$ӄρ !LmP6dt %>QŸ&'m4o49R*bDj9r9`.R\L?PB&mpy=<䚸egG]@<ιu_.I|+́x*:V6$ M*H\uPK7QB>رYQ8xcSd1ScLeURf+ᨣ!1}zCV빲ӬdHmnY{:e"A)xhWapHS>~o'_;9T|A+~@M;<ٟ95FǦ0 cSf_#7$"f$]}Y. ]T^N?8j7@|#L681*A[ xkvWؓڲ RŴWƦT@Ƀ:Z`:+pω y~~I~勯?7~9ymPQqqb : -sBNc-}Lc˳f´a.6ģggX:^7SWbG])sbo~ޞ|~֕륗nMI?_7>#/D`}Sh|dݿ+Le־%< a=4pq-@ܖdc:}l_B@N-zf!2%#ުyh" Ǧw>y>R[搭'CRbܬ)=W=~<ޮ2gMc.n {nȣd:[^HP.'w}xɹrT^\;. SeN};2&obQ?ބ!Eی["e&znjܬp^UJXBLe6<ͅү}y=ڙd-sjJ&ie=%f&n=Gxr}ƴ4LxO},^$$}pLRifcc,CP ĸ[b&w+ׁ?,ly2BJ9nو1#㊳A027V"4dɅ-ӛj**Eh3{)lD#A)߮ln jmfѤfolYd~ބ=;h6wzCM'N}$] {.f] 6zr)8E`( ?Ծ9֜wb ҝ"9T[( r`r%XY\F7eYiGаvexR1a/ʷd=(jwʗktG揝=9 IDATx'FYiP̉%fv;A{7̒s#One$p !0uu9Ɂ@S ak;0j~nDB &ofI쵊Ksh\ؐc22K#獃`{N#V32?hGVs1|w'9~W^JР% %eƸ"]65cC!v3Au_;ѐ F#/t'aua%#@Ķ{Ju]93Znd']'O|{?GCu~(}[/س5] !g:YЙ0!a o)Ԍ3¨$g?`8%P'q|Gĕ~0 |y>n&Z*gRN=Ex2lͰp=gfu[51gDD:B:43KH 0l1P9ӤɎkbe0't3h8itpO~㛇?1nk*.!r;:QLN,"3߉%~c ʳ);!z̳kHPp>`ܖoO^xWoo۫ow_}s__?_t']G>o/?_wys ^)yKX}~d't>~rBzL]T,_L>D\Odط>-5 erRCW[C՚ka*lWanh%l0v~]8sRzhAA.C'|;ӠS_ksJmzh0ujx w+ t]$4&Z1VT~>ܸ ?Vkѯ|Pէ^ CC n&JN?9T(A m0b@]'j$vό;hE [F6kVA8fߡ#忠}-_ {&k k!LT&w2ȯbFpGV tj]?iLAm#> Az1dc8e Ğ2jI:u;:&st7ew9Rc A\.`G݈pG}H g#(J`6\sx  >Os x]tEO iXB 1pnM(Jrw:tQ%'lH.6r~/]f u8p!d&)Yh%C ' r!) 8ossP3d= aSruqPs ݚʻO{G?ڛGe}sN&229B JE8`QպtY媫NX ]U]F[VDEƄBB朜sz}뾞N]}w~~{G>gA™TY/xㅏ~sz[1ks沏~ Q_G^^\~'uy{>?|[x'}}zG&]pm_hҤ[T3dO|#|޹H~ң/}:c'MoՅ=_ *j GOz#;&ZO.ȽB4pV˻c~}?f[vwk~ {/?Ɵ<|.D<<jVL9IiNHtɄ~KN}TX#`n:r9G|>>'ޖW)ř,'Rɺ"7m֓΍h'%4h; :cSءC}o$RVl cia0A :wM^CtJ7`cl 9m";X8z-xuc.q5`S7ଠ}Y(e :|}B,ŬͫÙsK<̑GQmc8ƆIwxfāvnשԟ/VL!|[]2Gƭ7kNw#n>_oDXbCugn+! a,"c2t#YҳKF#=$DWT2)9ր8Tf\1_azQ\ fCJК#mBX2ξWA_.~j,y ܩHw*Q/ XM쏴C؎ OR;NJx @J#'Fz֊Iw`!dUO>Ό)Ꝋ_ LEǮYqԸ{Hr+DsEap: *xfgg=Qm1ZL  ]B!?%Ұ`(A ?nRڡYDxh O)vqҿn  }H{s|s w<2CI;N:Hv[g=mRkΩ 0@1jQwLg^ÙXG%sH{k"Rh@ClV QgGs.=1Dw1x'94Kqn [q6U4&r]T~SF܈7$[n]tôˆhɘ꯱mub (mc:}|`j ֟jftg0ܱ$V| /ZW>K&ϟnk l{j]y \\ǟ=MH7(@}*]~W~,{_Ͽ{N\U|'+O- `|'>~Kױ@F~Sw'zE@/_"gO~?z%)orsG@uktyk֒i{ӏ [z/Aoh?pȽ|ޫƫ!)z+r6c7{6<*=ttQᤌRvNz$; )غrĽ4夺"\Qnڑ{m~G^!g$[p1ܛ}hmqj&鈲b۫W#B)Q͍~|9HwiX퇏ac֋S9J? hK4SR"7 l?F"-?4';al |b0pQ=)Жop\Y1M1 $NЍ1RD:wi\_=I7 ׺p7z=Wy/[7!ꑓ{l''5a6sփ<#"Sy ?&Be`(a4g:m]pٓ[Z B:[-kӹMʃ9`+ /oQSy?u fmy,9472n7yֵ}ڦ ~,zD3K*/ xt<2"NDǒcVǩt\Lpz G햭mݖI&2怋wx8rrhV>:m 9B ujLK:@\Wێ6'F1NvޯD'r^AX&P,RړTFR0 Ǣ"ۼ))G^tcGO|^gJo7]~z+>_M_S?>߰|ޑngW;gzCMPBˍG= En@NVo_|LT\,-|nnkޮbmPs>Q7UЏ[?[nަ}'._^q/}>P~G߼iE>!_m)K,¦r\7#y=Bmi֩@h?I=&ejhp+uZ> )r7#f(.i=ִ&9?q0lF擔A[Lڨģ[VV `훻|&t+zHlḴ Rr58Ģ= ;- UNNֵn3}nk4"kBclLj>N'rCբkߣrDz`eŮ ˹UO>15E*a,kϧQ(+rMނE֍G01}9Tvwq^o|ߏ> ~ͯx+/!z}%O_ŪSnoK?tKzD7_aE_K>UC>|~;^ӗyӻܫ>+_tJ>=u򳗟=뉗eϽş(9W~ׯ}iz%a/߭zy~ݯσ<˯u\xk^vSU>ǝoAߪW;>pYE_g+쮗?q{TUOL|Əϧx_пxʅt&fIKdͼ8OSr3Hj z䫿94X/HI@ڜ9MَG jOڽ)تLV^PEpb!7S[5d#+n<̟5q?.U]:u2#q!4e$kCi}jg+}AGT4K?[}iM>8d^z]P Qp .Lɣ'K'ɲ=D\[nӊjiRnll!տ7xsTZ(##5]XfK{g!Gjo<q|'Q'<WQ؞FG{&3YӠraz[*V8$`;rxo BRS1;7 SPä4ؤl7vr ޚqЛ \69zuΈwd_mǓ 9"<:8*pd8d4i ؂vƀ, q=TD&TNfkLѪWeW6? s.Gs0. DdEc <'h?\\1$6'P#ob8;s"rmϳjgl6sgS7Atu^[zޯoMzK>i#'/_#?ߑ>gk _˗mGߠ3K#}qx?4@>]f=sV9sy'R.^_>u+Ыoܫ|!3;ޟ9s^_9kA*o[?py?|゛^70^{.Wx'= P^Ի.[~=}? Rx} Sv?ψyy/ Q}{~g./\xuOwi zDhc,Yg2&۽Z) `>.x NPpsdZ{˱Aj VmCuNyH/} bxGD pvƪUgs4j.0ʭlLK݋mAvxRRa!*nhHѳ9 fL%]m&2Hd㱤vWڵt:P&16i#EՆ=TC) O(3$37+&6yg5^4&SONd֟C/9Ʃ>kf^aa Eҵ01=d Wb>1~Z{kd88Au ]ȬQH=,@K2z32ޖŇvMK:D;n^oՒKㅴ1pmbNAI: fUukO Ɖ+W#;rp^{:}$&~RBg&`wu e9VCYp~`T'1簓ւߧ4ٝ^ouƽgCsпw߅-c4RekxD0|FNsBotl!؅junq#ޯm6畡jNŨ6.r5;1> j܄4vlR_ʠ6NMŚt&| ø\˜=Nj\&xI%?!oкI)gN+ZZ\`.[\>>M'=Ưh,w_wsXG䕑||.ew,;|_cۺ蕏c&7H:oOOuI݀}+!I y1 _%;۲ҷc D6Fozv-e9fsqRGLi1vzAFX %.~Ĝ㋋ޞ/f 밣Var)&c9*XSOJv3u]w!\h?3oŇjZ u 8@4wc+J g;}]MT7h}*+ Iekjyĩ;.$8fLj:xh IDAT[qdip6X[\奋G_/oJDŎ{lÖ5)aBf=Y\t5'nH)kx{>&Zn1cxKKxz?Ƅ2Т7Z.f˹[ i][2gy25YoσGp<{z[k`nFK@量[xホ~f1youqn{){|! - R)h1ZݸM@} bd\1qH|d9d^L:_.9Y'flʱR`ktR_ږYZ),KϢ&z̥̞o|m d5 !QTQGu˞BFߌu]Qaa1/eZt6Wz6rnyA>^Kiq )[z@o\Z[& Nۻcֿ .Q3b.;0er6XjYTycR̎83o|^ylݼNO{/.2Z}-\r,|ǫV ]@Ozm^M.AxCuܶÏc>_W~w6'Lxʼ]yVz Շ<@Y#Ez^{偏e7vW]̮+~ScQSZնOٺG2Wou7>>Ode{׺prmC7\Yj)LIizx:r)C+C2 <a-s@;/0uB V* cBXĽA+DBDN41-9\c+_QR#6񨵰|@o_kNzUn"DTGndMY=Nr8EfrkvVb'"].Ub% >Hv'kyQ&4KrފcN?IE'fh 66B{qK >QL=l Z+xO`ϗ9re㐸| i,mB\ӗwXMz&;=*v)й0fnEÊ5ƥslcݞ|1Y-a7;0=}$a1OMA{ࡋ mMUǎE95@ 7і-Ys[9JxUPr]OImZgpF޶b}+(_ K $c>6~Ap֣,@XMwd\}Bv-`Z\ku!ad:4]Z(:8e/\sދ.{7'_pL#8)|Dl.6o֙V?zbR&3.>{F] 7*?]zo7Sd^_iǣOՇ[|##c7{?GDU-~*@1Q?Z&wٲnQjomn5h1*ۇУX{J=<0PKzXQup^[bsRb)Bx!ޣ <:|v)]/>^~ϩx'|R>~[ᕏw A/QgUc*#7 J.EVaa}sPn?=c:Mx)C)#7$'ƛ>hpXv}JNqS(m&!KbbK֍$ThM֯>Y!өJǓdo ӟL "ӍTSȶ0hbgރ3`9R9e,^QTiz<`b5YfY̱4y ޜG]kz DMqF5PPK'"n,R5B3}D; c^؃iVrA]hmS+V:)i}1":֪u֩AF #\xs]1&oz0M?mQkHIV"9=dtg>ԓrH}o:s|nivKB=UUUd5.&!RCelrbHFA۹kKn]0XN_:.#W1j[Tiƭc7xG8tU6 0j_I<}ɺ ^:7+x iu3K{C'@NAǶͩ h;n*98<&uvۻlnvנ9 i/7BuYxZ J<f8QnjzH&ʼ"zV|#([Tҏ}uE>1 >Y1OA iiYw }#ysǨ9;"'44,ªfr̒Pil~e@<)eA'M'%e"^2:<-a]kǏt|XL%O,W!D<@L|0ڵTy,O2%r9T^MbzMSk"Cimy' +Jt'+G>ɬ)[kGUAlE=밁2EL]7gRhB4{Hfsu g%:c5Fp<-Y-.Sphw0Rɢ^{k~i^>y>9NRWw/m-k0z/d*bRY[1Yk6H%WV_ҁ#bĆpk6Y}wݵm߲7^ƓAZ!};.}0u"ҾONW?Bh?|Ts & v2(гC{y[;滱$YOۻgh~9ޯ:A9:GL~ru;ty`l@G<715Ccv}0~HqT` fĢQāAIg`*Ii;2Aoϑ`{@!p̹etIԨi2F{j}d:ՕY'?~pNYr Cu'pg;t 99BY*T}̯'@`p4 #VP…(9F6sc!/Fρq3ҵ-8)pP<"/q[ƌ(;sߏ&yxv&I&f@~LC@(~Bq)M=_8֢׾|Mi{ Ƅz¯Xlä~,Xe"`*FA0eTqMX1Usм-Ъ4Ѵ-.vm\ mHidã13Q#YUM52cӵIAo8ml~bAm;m^[ln`N ¼R= &Y,A-%݁U9|LI1@Mxd=_>ń.3>{@ O? ~c~ƃ5<-=۲a5=Y^uSN){/|H_ax~0Oˋ粲'|zg K?闿=oN:92.m[_>e"$봪knmɈ@V.UD+LQcȎ"*I!XU;lUs=U&Xc܏N=ia;{<߹Y;{rH&__`pY6j$㆗sj h/[(gB?t\2$񵰖<vD3xs.|W|7*Q 0"f=D 1BH`jI]vƆ/8wHI Hrƅ[~H³_uQjK/g\~WY+ ش? 8Z$_imN=>K?B5/MiѷH)W-$r~H zr|W>BoZCoW ?#Sk q1J΅i75>"|ΓaL]Qu dZ=^$Z,7Ta!Vޛ,څ:3蛐M)IS;K{x!φ^䦓>C7Mi.7 mKN^VNp&ml B~DO[4t5._@d?ׯ'GHʈqbG5w1yx缲aѮ/S-8gp8scf?ZV8>8VF~-J]]D9\m H35Q[;M%ha1 _أ_>3>E p:O|#/?~^8! HźQ/V'<ǟ}5y{e ˟V>}~xq/MHx/|v++fw|ϿDW0hxR5H?wy_D5\spAv꯵} +%~ YIc}YghWNY(YT57EY~IIPatI٨]jH _ݙN$w1ρ@*{?o7O/tF1<GjF dqؽg 2 lu[8\۠~rMvf\XOkDHW+ܘ0.GaMj7ςiW7UUE$mc"(3hRڎF^#Q0u t!AJgjLʂI1 `ÕNEYe 5w98 Zc&JȔ cw%cDVlƞ*Ζ5kЎͭ@4Wg^Փ󓎩=(e=qi=x! |@_ nm. m{t^WWp[~}uyRjz zǯҷ|/s_DZ5_mVw\ޤ`|~o> ͕e˻ noEU]>%O/RƷ{1FYr]?~Z8|Q[\>/7g/so#_t~/| |~] (ٽz+>rݭ}y?x<Ífߣ1hNNk#x-M8<1J~*zYPlETtwFI2i?эvJfe^Oc,ʭp ^KPH< ܢS`](N5K{ڐv|{шQɞy]% BWiz.k=+ ̃JxυЎ3$4J`wÊ0- Sb]n\8GR5YvR 'n\̻9~@F#᪠['x@kR뎨=$ޱH{Kjøɻ3)v Fsm|n!`a(=Kw?Gj*M )VьNCk7I_O^ 7Jpv#?דXغ  cw[`!ߑd7NrgA0ȷ94v0T`{$` !JXnJz^S  u}FZ.ъHT%1V}UW\7 &musfK0t^8d5<c7 *d%nyB촎p( IDAT%ʷT x6VX:2D?YAɣ[|H巂^W C/ΝX!(QvL"7 Yj._KbLF'*JR /~|NgϾe^~-x~7"?~L~R}W| Ǟt?;^ç@o/}緌x7_=ї]+;?+gc%Z7-t;OIo0z&1Vyw-}IY}.= y`$߷-,cdޕz7Ɔө[Yjy3x3?Hś]ر InY%^bU.=8- IF.jj$ȎjfYiߚVrR[?݄u`P􁍢"4KnπjoeOuL t]W?VenuBELԬ)t#a{lTe?3_GvO%?lZ^h0kf:7v+ю +*橩|N"$˹ӵ@$4s`6%M;FN}5@}r{Nt5Y⺄9! VC;Ip v"3=cJz=:9Mͺo) v(yC@v7 jf尷}sW's8ˆ740ot5.W8cx|, k?s*7N=x }. {Ko>3w/_W/|яo:Ǥ')X_yu]o.3>T֫$^Wos+8/~μjr\AussN!m56º$.`{aZv*쉗_o@RiRIJv1Ă)ڣ~Cq0nqi35@ocF}?k`?l3ʳ(}4UٟŦڷ@[z~Cv;- 9kg &1}|vא$yC|l3uaxK/_jFZkzۚ 벶AVvH7p2Cb|L |\4 aWb]mƇ]ocGT;f)gi;fFR[= kG Cxc(j$[>t d:&N&o\x`\3 8'!TxWU`:6Hʓ:Xt֎B۶mw 3Ix68v7;`Ǧ$wQUVXC6w;~,7rn*_ۘn}w)&Ex4^/*{@\Loy|۫~/~g CN/y~‡)Yz>;k^_WY_:d92CAzcz3v;o|_{t?oѫo;?D6m=zj)Bë׾^[>蛲nVr3.oy.ߡǫ> 95ˏż>xɺi?+@y?j/zS.o׏2M~*:0Ik03#ӽI dF5jj]~@:GyҟQY!dr[3)زaχd3oi_Xˠ&Cf.NM.ĢqlgY-|;|1/ϵ$Z+N`HήV\:XL\!9/\ịrW0E, ?Y%)Igp&#J\` BL>ju*qs$]TX x;@ ͇$|T?3i,ɑA (o݁H`z/prebw=lo2S訚kTO=kⰕW cя)s) Vx+W<&l :4m7/T!/85ҹ:ѯ=[s!&/I\M]5q;"tU`?)>w~՜^qR oŮJp/X zbJ9G%|h`sun-I4fBzN.,MYQWh2{m0 )G #"LJ[iGĞCCq֊}|ꠁѷ_ tgsgLn1t(Z/:+g,: +¬4.;&s; gT(z:GǺ`o߯ ]-(CZ]|vywȽo{|DyXe?JP0{4| 'qA; Z8+x/q*7#lwD_6|e[>znFU emn17~m J}nROv4I]W ?k1y,ւ?>[54cj5Dm㮰ceo1s sY m^8l0|ڝ%nFЃ.R·*FG*Bi~oU,Ne^kLf9zHII@,MΣ2hijn@1~D1o!n+ͫ=֙yO"K`'|W ?0;Cƛv0WG"aU躼c~}h4u7Xw2fF-`h*v?ܼRp327"0) HE!\ɦ5&zwS[gQrq6GupNL07Yo!9wŲ%tskMcODc1j\HzDsqx6dձ䑃3yFY2CMWҹ _ m ^]n02,=ls|,غ ]ǯAs?&藟ui}Z`E ϙ#?D0tȩTM\rbUT*E5/쭼bF9~tJ'5 6)1=慳0Zik!Ru \ʸ͞鰀WCx E&ƩpݒY%Fdk M]mk%hA5cշ~0F*Xf[JV(R{aǂQ-Xyo泽c6$i1=#O9 >H!ggzV,ul9F4VC>relO} 'H\]3kҭ L րŮC{>>%'e+kW p"g0< pC(d!';#؃6fG'4.`w|l7|Ʉ-^p#9b9fNwiaeqvP506g޶5XYwg|J((wvxZ#7:')nR 7N&-6Ԍ"$ȃ+>Whts Pۜ1FCl#ZsA/ >#5|t's?PXܚ>!3nۉ<0 #;e>qG ne2M9{ZU5@mG~Y0Bt'bѐ;Tϭ',rtby F<9w0M<`2 0WM^iIrf"ڍm2|.g܁÷qMRgޖBn* хv7 ߪh!ՍcYvV]hev$h+Nkh}ԉy Z3TΙ 0`6g?Ce0HHkڝ" ltg=8nޢ!ym&X(XmR{*͟,CsJ(3 Qo:ôg.JK)\|4 !e4K܆U]@6F掠<,<$tc&wh(7208YU`6aS€(5Ww:FVgTF /2=kͿ`vp9pYQٮIJ1OkH±jc"sYμZW2 qLL,)1MC[ 6D |xb⣽hQ_z͌+(SdNaș\6- ϡCnl鰏BDL_׌^MrbsNfd1!jz7x~ݖ\!ըrt\qKvylrݞFuNÇNINɞY:oImᕽm<#~x'&?8 (k: 4lD]eyEraNWd;&qq$$;hߖM8di }s56ý}5cdtp]jm|7R|,R˫8!3(Σn{su]Mfd11(Tn.<Q=jXG:b;pNY/9Lduy@ ihNL60 F+4P2rI¥wi i0 yX7%/US 6՘pјc4q]ˁ@N7 yqoZp <#Mj1.bam0< AD&g{0.ǴsxVq=C q~#J^EaL7Q46֑s)2(GX/b@ f5:p876Q+ՍX*Uhi'^rx xqSrV1D^^Q m %(#1GJ.(I87'Xv _XX t^> K pD7i ec[XdqW6<0Hc4gdákT yz}[Ӽ{hWs櫞OK'y۠m&NNSӨ8meu"CIF_ؕ[_GZ=RQ_^k|ܙ.T>+օmW&C^; I(gkH`ajwe)|EVvkᬢFo|U{6\}j+ RYy-. !PWVLDqp 9sv# ݢ_z 7˘0kXdo,Wv5וP_iomHn۝z:BۭŁ\Κ}l;FLjqp#A͘Z"R/OE08Q"ч=ju3\n@HIcM$rvv:M_Id6 H,򰌞 7_ȑGa>|`bB0#$SfL`ᴼqT6]$_IIMf' K쉃RiZ.F>@;Ʋ1|{jzsw썧(S #zY} :䱒؁Ǭ3$GIܶD&EZnZDz'L{8|t{ Lj"f̓<9d-me:ի-T[zT?yQQP;LSвDlmOP,0Bbz3|ߞE3q&ȒҀ#RT[5 |0RJ<9H߄7I!o/4إ1{N@05ߝvf8)&a j>RUN *ѢI\bGj`Q 5`mHxf b7|aR83#9[H yъ+:uw9JtVMŖa9qGi%|҂koO& IDATV뺃nj[iz<biGT8) 3GkT.t+͑O!I.51hL3UEEs:0j6<޷҃|ǦȋV Ҵn-16C[uRأ;!o-Ix@h+uS, ڥ6gmI GXB O]Y<})Fpy?kj .wO jnM: K2ioK2o+k,66Ɩr>}-XZ_פph"H.h|EPsMBܓd(`Z1lVT0l{1+3TJ^>D;N" v$s:hpYBsuV:axţ<7(|kS ^T6v993{3@Tx-s юY랾6!}rǐvѩR'/aUmFd C7cTd< 9uweDV)hX+5u0 k'kr_^]adN:9rffv}n׮ʴ)N2ۖ\.~zu-( _gߔ7lK5SH +n,ug=ɣ&=Y8(&Қm#'m-?*|cY'.${r o[C(܀݈}Er8=y¨棷#r[5Σ.uƆTD;h~mOj:cx\ ilm늺A`Oз,'%eu4Z] I۔y#sf{fͷQvԃcVkDrDRmɂ rԎ'2b3V;(R*QQzҢاz;^9mH5F; 6iH$Z>hIÛ~W&+h9M!SF~RLfa`Hs ?z) b ˃|4(372Wپ TO  `°ŁajRa.jD9xd (`Q]jθ"ZG_XiW|CTbJqFm/Lk cb.%o%)yN!11fW)~ܥqZ~xL3 I?2ExψHZpLox rDH? 7ܴ&nZkM't bDߐI3t{$eBQKA1X: һ?"3:܄DGZ~Xxn} H /&d#S5P'Ki53c]<8-p5b|NLMk.VOW&fpOd}T>h^~[s/SX*_DN軡Sӎ]3s'yx~sV;c چ Fɩ5R5%'ȽT|>:R(t>J_5MSt؁PSVTۺ>!*ahHT9Q5X8X(2D}2}Rj  OIk9Jh[ 'S2SoT]1@>{nזRz(GE!pZG1 ҁA݊c[ MQ94RHK.߉bp2)>TVf+;݂ ԶÇӒcU¯'o=Vr/G* ]SebFv~ؗ]pwSe =`"jl`>mjdow +5.iagM=jvp!u:YWK;qu4!KSm8Σyp_gt#f5.ޥُp{c¨Dc`j֟nGw,2(Cm/IX߰n6tkЉ?A'LR0R*M4}`ȳjq 5bդ9HOFqRNĺkeR[7==s5&姄kgm+tye `~&=0Tb?L9[#l>Q.Ewڛ ڵ52hWY$=Zk(2l)u-%Ex1bfn.kZ4F+EE.YH9{%'z)o5( أnm6 o{brFۃ*m/{m[V~TQE,*)D"DфNMV FCI:ڑڃJ4y5T&;h!H֨> +ONڕ~mv)kd0yIK>cq+67)*cRsaKrMd]QàKDIƠ?Si$4pW`_/e ю9$}3L7ciPvdգ6Ejp]*ae>zAjq֟K8/$NH.1F&LB>1`z!H*9lK@ Ae,(bxaFCz-Da<(Y-vfd2SQxc1EExrPzYRD'Z eY Iڈ&pSѤMʔjHk+]؃[SV-t24(۵E+kN ziwµnǪ0E,b|510㦽r;RDŐhq9סkB8%FAAhY?∡*5~E&fYdLITa/C3M , ̵JXn/ީ%S["YyENIkJŊ/9GR+eTJF㩼Ƒb)Kީ V.]v/b:i54ZGb84Ϻ%SqtfgF,p6 ϼ}Ҳ:ᛝoӦ4Y`~[|BD!9!/VdjvB&^o| LRO_AK_XX+\%csm*&j@5bR}Ji},|o:|`:0 eYȵZFr)PkD@g%$bEPWڧZz d :kyǑ Kڱ&b3t&dBble-?EK'q(ԑ0h|9;Qs*rS'iLPG\LI-4ب6ㄌ9n6¯EݐbO<d : YFEK Tj1%ő:3l*,D4IQܥo,K) Fͯ=LW`ҷ?\'HJH)| >:7ZDVh*9^!BxD.&oYmoT瘤">xec$mVt 8 G#vDCv%5P*$61_DJ̗\e7́ġoX˜P',cHj|PqOHK f\T:RK8y,Q8U-j4P}v2 12P򩢪lIHR8:].LcnԨIhb6mScF+8ຣU`ڃGriΒj-Bv IԁDSF[3T^WHF nm͔t$ҍ6>GcdK4j^irEHvԟ-aJT{TRe3Rկz.zZ[P|A_:O!3;q5)cʪ A*'A&.'0#QѬa*>`8h);T5oa5tEc+!8Ԋh7SxI7A +Pű"R$^ +a&=z]ʌǞpJڤKfZ 5&OmK)V[3@b5$,,``!<+tRy008"TI Se/H>\`qrC!ZB;/X3W e?4]C~bfcWX[6F| qpMut>n'1f  cb9 :M) Y_uPW:ȐT-ؖvKiP(R̈́=e`ط9HŚC+b9RSd|EJnTo Z% LrI^瑱ΥZ_!RNwЗxi  zt˱x-ޢVC%a\% ?q7T2y$626Y|؄6ۧI :4Б֧((k|rnPQjI@ W:4֌ɖBtT$ F.Y44۲UX~ґLh'H:x;` |(/ 6%yG 0Hd84I,7=?MDj4/eeq8t&U"Od~ vI4G\khsC Ax2s p PG[i6#*_."rh)$c!̌6e K$.YeP$JIg K+Z2C)DXM79HёlbΫ݂L# rR J 6pj9TX +ԍ6lo!&(j>%L+ ^lv e iAbYΓ?ʐnE]BWpSfI.W,U KE%FEPD͡[iK6Hnc9;HSRP&_T5r^~+qg Ql7>ʠ#2?Fh=lE)Mo4NC2DKQ?bbPFWfI*ujE,G-2䒬۳+.1 RĂb ꌑ~(kz w> [fAȭFXPɽ)Xjq{[PIOzQ/tuv h XÖM0SF 'iPb;[} ZN@<zZ fSU d#戦"TpFo^(74(E϶ VPYtbb'Rd@%nk'^&_4m,Y*RI=!r] klx0A {:Ś QAB6A3+tj98y kУ&j#u*E Z+ .$aW3[7)s*R[4 j:Zf&P^B$R<#!mNIJ&<UMfGcWkcgfVK AᐋS|0fAMf5۹r*u`;5؋9E>RSsNIIezc"v˛E)A~ZQm)1|rRyVRIn*[P^Nh"+! ڂ.NH_ЫOu-`Eg*49*enJiPԐ 9lvD Y]d4 \FwlѡtA)P'Sa_P8rF|RɸKAlK|d,%_]ٯCżHǘ(r싊O̶͔p}[|ddI伐R0R]q8Ή"+bQrL"hA.1ɎCiK;H"UKF>muaƘDʥI=:ck)$<7v !1 GҖ`.L3Qcfb]NQXL@` A~gU h~Z(} ca(ye4\ eƵ>JX:Vbb ]䃆>{QbzMf%&bԅIuBi)'2kUq|Q62.H-/Ɩ~#Th&[ZT 9(YևTO5ĵtJ$~ƛQ[<'!ԭuO29Zt#TJf 49^ga( %F|71$-!65{ZUɑFXӹhi$-%M0:dAq CPT)R~[v[] ћ0N{Enџ /5Զe,$u`c(W2UIҧFњ6c+ӦlP40|C\uۡk%X D6l[䠄5 ([aS{ ~> $/|Pa"doԛ1S㝔 H {MȮ`C.F*> >O/R(j \m6 ;T;DU>*D!+1DP+P?IŒgW1Cb}0@**OX-0xsPt<҉z!JT"9q [kǨ#Ej`HF(81-7B)n)ZsSj\-Gҷ贑Hk!cTJU@SW4Rn\$.E`X Uf$28i`Qh||d[J!?HrD:c)X)ISO*E~7eCHp#X4G ߟ=lQQ&+*ed6P4F c*XB!$dbm~ѡKst6.(Ů抝Rj!edqSJ+IzN6YBeQERU4mLiR4؃dqI$?Sg %T0)&DL+fu -H߆%(.ޥl @mxdth9jqEo E/fQHZt)ſ`3x2b7Ey4(> G#VAuh.\z<,lG #[Dd$1ꭅ%6B7,-el=|*"lGfPq|R{f1 K ~Z`ߣF!)F8")U^R(V-͢Qi:@AћF+ 0[Cƣ)< WXySSSQap SƐ G(} M@&C 221T~ *P\ɔ)YjE`ɑ*,Yn &lJ;#&WF s0ٚŋhWXƠ" unHKcֈ>\A):-u1|'Jլ@ymX 674EŴӚl `ʼnvCX"ar1r H`^K,T*< }5ux.{2CVބgSa*?ɥi٦S7!K]Y-\6C*ɶԸ*r524^XbiMrT,YD;'ɴRex9SvJFvlڅ5wIڝU$q='I[ܞUO#Me7muVkh+νvf~PV3"=;{g)`>W Bm,I ǡKGz#"[4g=ɩ555:GIʪkFYY% EF$2 ݛGraΆ7>I珰dymLcshz,CZTj|OQ(z.SLXGWx_p*`vln_!r" 1etbl>WÖ@.E+^8(i)QP'F1C C%ivFz%)Zi˞60ŇF 5ZOe: x/8nҤ*)prmF؍OYbBkB/AYavdLHc? 3PqX%C `$.r[&4XQ#\3l%u͑]sъREQpyGf,|QNeY $muN+L:aIk%3RDЛ'D#{a+Vփi15_"l:𷁲Ca>zkوxYo}uĊwXU5LBMѩu jXR m (PG%YlR6C&'V$+ T h4 ͆V6psɂ ơf-6qP]c`dT)IYtT义)[2u_(CFEv-M:ES8#Y Ac?ʶUQv#g%DJ3Fй:w_TYz5jaSs-݄$[2mDֿɥ0|AC@>,y [SOv^p٬>6ڇ- R5LVtG йEW{秡yUF8jI]mfdxdB8g`gC<@{R@N5IJ9+]^>]2l}|.ksU0!e}3Fk%iu\@i e'VhM-IlsH9ŠbJf!xc$p[HJ!Mi^jv_S"G: , J2b,EDu_G)qrTxfEh eha/xU=ut24,'i5%C$]PFr!EM~c 3i,eabM%6Im ĎqTԯU3a5Og@1:kx8x$UA7bsd%|`(E2zV3ۋvhӢUuQ2 m!7HIg+I -Vx~L?B =Ml$>k.K'|p77=\j5 jp: АNrx;Q# AĚKѪA*-2EeqhWDTM5 M:V*9`*Uآ9OoGc38 mȖ ĊF6 M ?NoCxQ08 ȤC@;Vg4RRZuS0oiNvvG[ԅH{muC8^_F~HIG(@57Qɠ c=H 鰋iُ*;i|`2?‰0G V؞M|j[,ʢ$-+kFK?Esq؅oJ ]A&E1YR46G`Ax qc+vP |_i9 zkL^ҥl Oòdbѧ|5 -,SYRxQ' "cjNݎd$A-K^#UK^5jJ9Tc y QGyq/%]rR[rK,fࠥ֋Wy{IFY*O͂bɸ@l-g{:(T33hDA2&ULM'MKDϻ$FI`i`cJ> ʨcW4$S 7yb<@vKs:%fĦ:o,÷!"xP3%%;xEHn~,eW#N|FEڃ/~郒t.,5J6E.:LPh ɚB57s:PUjjsؐ ?`[)f͘*%3v#_6pbg3GR9XڬYq_69"{33w&uG_j]:Uq5Hyrɦ U_&nXL. 2GzPA9`?E<*\z(Z[>[1iC2jhP"6D|f UWz z. QzlITC7uLOr~KtR!r]Xpգ:)١nFچ&9?|/l2We*9,Z򽵠5t+.[jQ6Q|ĥ5%W22 YSz%;#3ja5 ftGdsobP8P_1tzo/NhchͲ>)1PKGC[ %s`%hō6J@w`DԄt!ܣ/g"ӉGTYI*I YvK4*UѰTSlǾР1.H0=c\[H'1nv5nR3#ژb^".[9 K0RPO8tt/ J%ʙ@4 NxMP?']և3qM)5Pkv6Қ:PudFP 7%L lL>+ې4[+kiI. i!>2R.D!* /vO ~ZSJ uQ 20J5qvAFRp$|WJ+blQGsQwl/kmQU#ScO 풾2m|ڧVWk shtC;? %ש( m&|ù}i=H6.е cmQ7J~Idj8m-N[dRnx .c%7Pv$$+htEv-G2JJ~$PscF-pJ DzZug7KaE(ǺPmr_SܿEI0(5zojz O_.G/phdѡL0^'!Qi QV1>THP-H'VI)j`_ܠ'7zeSS5lvj e\AHk$HoMv&eŮ_9k|fjj){EP㚩J@\:Qſlb܀jk5JD&8PGhQ$ҒI2?zO%qiEɐn+Ci uV} fMJibO凼2@Zv5[ ;AS61ah\2ڠh|`xj$7zuljkHGbbFk 5j 萸XRnFBEVu`[ruBH.Y.r^GkҠx%΍h-lwMOx+nm曧[nu~EF<$#`0F#6|Rx/NO驟T\ynڅ۾m/O}hmAِ0F#`0'[>~ȑ#СCr>)}s\$"7L8򨌀0F#`6[& /~ _UHwЧ2|~|(S0F#`0D`[t^~8(d\#`0F#[& )݉G!#`0FX[2b0F#`0F`e0F#`X N@#`0F# N@VA2F#`0F' kF0F#`X' d#`0F#`ւh#F#`0FUP0F#`0kA Z`#`0F#`VA *(Y#`0F d-0ڈ0F#`0 d,c0F#`Zpm#`0FUp J1F#`0F`-8Y 6b0F#`*8Y%#`0F#F1F#`0F`e0F#`X N@#`0F# N@VA2F#`0F' kF0F#`X' d#`0F#`ւh#F#`0FUP0F#`0kA Z`#`0F#`VA *(Y#`0F d-0ڈ0F#`0 d,c0F#`Zpm#`0FUp J1F#`0F`-8Y 6b0F#`*8Y%#`0F#F1F#`0F`e0F#`X N@#`0F# N@VA2F#`0F' kF0F#`X' d#`0F#`ւh#F#`0FUP0F#`0kA Z`#`0F#`VA *(Y#`0F d-0ڈ0F#`0 d,c0F#`Zpm#`0FUp J1F#`0F`-8Y 6b0F#`*8Y%#`0F#F1F#`0F`e0F#`X N@#`0F# N@VA2F#`0F' kF0F#`X' d#`0F#`ւh#F#`0FUP0F#`0kA Z`#`0F#`VA *(Y#`0F d-0ڈ0F#`0 d,c0F#`Zpm#`0FUp J1F#`0F`-8Y 6b0F#`*8Y%#`0F#F1F#`0F`e0F#`X N@#`0F# N@VA2F#`0F' kF0F#`X' d#`0F#`ւh#F#`0FUP0F#`0kA Z`#`0F#`VA *(Y#`0F d-0ڈ0F#`0 d,c0F#`Zpm#`0FUp J1F#`0F`-8Y 6b0F#`*]E2&g {) vu[F#`0F %zΘDr32@q3eۡ1 k;qZ#`0:N@.pzƍ@nTWBL6˞E 0IH2vȳ#`0F+N@E GLx5e GfbkR"5T.{3aU0F#`. N@. 5WИ\lT79o ۵{c`XZ0IdϥԽZ;] #`0FD %ta"7-]J%I"=kis?Pp-u}>_f(H.dY0VjNF7d0FpNvgN]٨b1mTutRƄ,@h|'##xn#`0F s´ lJ$țbYzB;)8=ca2 IzF1ㅕ?s#`0F` 8YW{>B),Н+(,N!n%8$]8y2Rk=q"X#`0+"dE.;u~p֜8p^ќcP;9SyY7o %WGRFs#`0F`[8|SV8{vg5o2}F,yJFm)MNx&k=$vQҫ#+#`" 0tb0FK ' tkkCOs-HB=eض%7qw<"`B1^`Pxb[:2,u*9+k#`0F d=8mqVyt 0;)݈T[IƮݼ۫̊"phr3&$]cBp06-3Lck#`0F\8-6= j% ۢLBb} _'ؖ`8ҢȎ|$o(`J8P;VmYOȦWF39|4F#`N!djÎxŃD6͕xH|a;ryI^YP4a>溯 y$C| ~ H+#&>/a4|d#`0Fl' Ao ]nLCJ:HscLYּRSlpR''x.L0aF]`D!pqXH1nڿw)S#`0F`D ȈƚVqQs#>vh/L.#izgt׽|x e3 $ya29:v"CcPt Y$#G0F#` dj+\lr|G|OxNWvyEWW`5Ooϟ||F%bSCl +΢ +f&bCFL1F#`p56:V(U@H̊h#o:::>#`0F!dXkMons F;u[U%Շ bC>ޔ >A={ L@3vyC(\vdoŕLIAb0jJD#m@+H0H>*o.Z80F#@ vA[g{CycMp+ K١>qrޏˍ;7ГY2oc:"^ns,LLf.屙j0F m il$#CkI-᠜Lؾ0F#PD fWtoUfm't(^\9߯oaɯAeEֱǿI> wq(Чb!>)g |0uU:Q2!|_8J#`DpX_g>fem[tRSFJQzA0_Qi3W}ujM\7l"p#JeX#ޓwTÏk:]Ԓv y2ʦL{ב\hs>xe*Px@$Dq* ICx^0F#`..y>p_ֿUIk`i2 tUjKa~5uz}H"ьȜt>Իc7 p!QnC{',#`2&L4bJIH!#`0D`=;Wc9Cz)2'PEhL-băi}&;6GMQᛱQ%J_럙+ 3:}*y$NDALH'KyxZoQKÕ· Ǖ.Fq8&0FRWØN] aKWF#`EZnLl׏ n#>VЪmt߱Ӹk7~P[m?tXih| ynV?Jody 0F:+uK.t1a~mDd!EB?Nt]0F' ;<{p_xIlwM37KxphR;m.lܯoy5&ML : CϷ&S ߘĸ)r>y5R+礬ְqYsAj Wd7 { g0FVFye*޶=6ؽr>KvۼjWNxNtQo~z4U8#^ }5+\>9Lj̣OW"4b問u=1}sQD>ss?1pv" $-`'n)˛8H4/Mb0F _[7݋{ |lJ6ܗiƦdܔǧ!6;qjb+)<}NF[bll|Ja-|B$ȮLc=Tye8䁗98X?I%yd1&] !ˮh9@C;9LC}#`0F\<8s;73<\r8R--Icʚ uW0+uϳGy%le3.|YGlaD8?nU7pju9OI$ b(`h nǪ$D 0 OD#`0wp?\ nʼnlM+[]r^dn`%wMwBϛ ;WXgFPq|[}*Z5&ݎM}!%f=ƫ&N$EL@Eu& + 0⩙RUXX+ypFe70F#0E`)V\>ljfܨ{ؘ|b3̇ݧNNbo@s)WRGFhWs-cGO)`L%E\s~ x8n c _tn1cjJH =V+ {gKf>Y)|0F#`_y'd= C˹k(kl^I'Gi.@ ű{Ux#sF IDAT!> 2wbڣ-&_ 輽ϛW]QacX'G_]hm!X'cPaLiu%d)R$x2Կn'GZOa&r/;>#`0m} N*c',lW<6JB^c75* km *iU 7m]IL"ۤ^$|v+nC(:es"E2 h0%+)\h$ am \A$b0FK*O>nt6<䮣'V1s^H= MX[ևp},i,W8= ᯈ~n*HXnjwOCd αۭ[a$%GlxZb o$d:d~m19-n0Fo=b]>{I}ڝ\~ ~n 7]´ .۫+" qn 1bP)n ^NaDr>0nq83zӧ{,nw 7 }p.4&n:+l;Y|W;nt7=>Qɞ a`Vrd/WFe%BfJ Iq0CN>WF#`%%s$dM`m*5Ngƪ A-YJؠށ[83flOfd}x#'.;[x3wYmȹ\9z~%Мi5p` O|q~4>wĀnִI vQqrTj3^LTL,#``_i}4F#`%p_ɭf&]QD[ϝ+4V?M|J+# 3cGJD@,|vZx7B%VMU˭P3/٥42&#(AhW~q LW6&!{LB` a @#Rּjs1,/0F#`R\ )-s|ps'H q m¹ĸ)P>}vu۬"ƈD@L"Jrgz`|dL^2՛ȗV*GY*1xq@صH>7muߣuN)l+c~#, a=a {`-c ~ŲȠ#`0Fu ?&{GnIÁm] 2K>)_9X80hARc=|ӵ>[WzVc.]t*7ޫ[6kj #v]Hw̙|_Y7XJBxL*%! WFļE.\sxo v1F#`6{rS1S!Rl3i+ p6@"p ?s Hܒ 5)*3V\L<"r;_J_3#aA%ޮe*|^(t>x^?n/,n:-nIH ,Z;8V$ߥpY5j&0F#`%ESd<{?n§wU r_\sj|S`jͯqB qj{ zE۠X|^+(C\ryc+^_"##@lBKiXIHSCey+uҌX\?8=LG9 벳 B}."ob;1u܎eq MrU #7>rߩ'kn@կ映]J$d)6J_`7Y<΍ \l?Wⶔem*l-*Dr,I4݅[njx[>|_PNc꭮V})Ơ$C؉drCmXn_B91{a 5qd^= 5~qW˹\ n鵯}iy|r NoP7g?{~t:|C [n|a;9Nq\FlE_f?cuLFK{Pf2&m2j8}wY΋ c4V]v6[E TVja]lcv!ueL,m ԝL||ރ">ri\m!3REpy2_/vWd; Ahc4Ghˑh\a5Iq '?/_f-o'?y;w]_ ɓZ{Ӡ{!^H _[χ>C-+־Pb\:;9lL3F8^pMn"Mzv۔X.y]1HbRoݻv|Hd%h2Wnt ~#T}E,mp_ '6cHDqD@c)| TW2uQ/[Rd] I>{W]gcp1'qwM~ֳ_M|'=iz]5-{woߧk|OMo>b ק}{kٟyӿ;wk4oԧ~k?_2*x@>)7LMG&N,Y_[iu.Fo/*cx&lY~'r/k3ozҵOJlU-yW+1crׁ}[:}_5ݳ=ȏh[C;*n]a .Ƹ܎jġg[g&KLc|[mR gӢa2Ϳ\_/֕/x3obouh?C1\GB6+w]sEz|fbYjnyJ\ j; v}`ɍ,7|>*`g6|sf!bVC6H|T}֩+Z"pENLݢb_GspWYxk\YC+qٟ_X8/~kղBOގ{ .k@DrߪY&K'+, tOT0$$kO34Np"s,&77`i>xl)1y5~G7_5w;N/7O?c?x'~ǧMӣh7i~>_GjG>[x;P:l[neoӇ>_@Bp?Clsu5/ARɲJlMyl"?9_%㵯>OM5}}*cXq9XlMo5_g[Vzg9m7hg&o~'bz\oW??]Ml8o~ެsW<`z>7}w~g[[{MK7N?3?3Wg5{6W/_@ࢹ~m6~h "7Xd,p)[J>KfMKFzaT&Ꮜ0ͯvֿ& 67ϼr^G=]qh6&{xq93̚0&pw\Ie%=M?7C݁ cy'in;IݬP63Ư3?!щG|XU 14*P`A?vt |I}_?iO{=OIxыPd/{˦wz{?=tMӏUc LWg@;ɟ7%/Tx _'{FVb۝vl1ZMoê8n6n!4u e_̔nZ\9\,OzO81??߀)VYg|k#Nξ[Wi}nwo|Oeh:Y^H>TZ6`[ISn^)>7ђn~/i_{xNadϵ0'>q1<7qR`sToz5䑸UWP*Nhqd 8a(D?1;c߂.dx)PV)Yԁx(.X]l|(~j9dM9^QC`^,3^b(ps>?*nTeYtLV,GN~t骫y|¢e/)ĜTїűFwۿ==5wNos+ۋK^bfg>x;?Ifb߲85B믛.F/[kvo+{1_:vu1ވ =XlY4^6\FI=6.O*kv/i.羛ݮ ϓo}A|jύܖpozɢO3nnCa}t#e>ȣdr39&)|h܊SwFq.?L5lNNIƢo~>G`ig?\,'p"d @"_OFf>\e'LPQ@57,:F3lr&Ӟphd]w  ݃ߍu+jIr+rDJz#1}W|Ŧ;u]\M7܆}mpoRѸ!S7A5'2w}bLro3u%~E=M) _T>5 \:&AޱcH7ګtk3ߖ߱$,<)ap-6htG7?0Hֱr/š nJ'Y`s5za[ִLZT~tGAæIiFG`Y #X^.$ %X1qX:4EuvJC!n9ck)Hz7plŷw},[\Ǵs椵yu6wbAy_|%=; jN;Vb{wtɼyNb/Nߖ'OY)stFl-\b:G_|p#ǟxB/_._~OʭNEQO#o{~3q} $6@S2~E=M) _T5 t&A^>w\~{Vw>CRԓ ;gYڷi:3K(̓sthpFS: aҀ "%#6޸xV|fȧo`zi{QSjNk h^ڧa,.+|ѪJi40jpBǩWFO6E~ӑc"(c*+; qj8v a_V!)Wԅ}1N#q#zNVjVs֪zu48Ml- CYu=v73#ڇ(ؙiU+5jyo+s=Ob{o~(pA rӏ=V̙3AoW#+.]jBII]Ïȁ(wa-oЙBԉXVS ;k]yAV?ݜv|!^9#uQGA[}~v Q_HpQm:Muʦ[.x)ž\< C 2ės3F\qruLdCIroݯg:%j3?$_;\{=uee>Yky.yLlp߳$|$l6̓Wc G2Gq}\!ЂtP>Ԃ-u0Q6iܵëz0L1OX\o?2[GdP`,1(aZdQA]Wn_~I0.c=uXC!BNcK2x+;6|{փ *#0w?3P1Zb<1g0h2~9 l|aHBθatw+DpU{Ix2x`ܦ٣\C!ptNx; _u45aӸfg2f8)*;4i5=}t9 t8֥΁7ʠ$u^TSs@ C!ptFvxW,_"7ߩҧO_y8Ź FuEj׻F=h3p:EP+ ÒOޑ4ɍsٴR!4nEdǦrZ{cUu;C!PM7Ï޽Q^i>a2# Xxjj}[ ٴa0,aq6o'%@3+(*Gp8CuHnvt=zñx@*++r  0?u޼(7)^ɰ騘\uu9n8ٺi}ig= k9 a2C!p8:2igwtC.6Q-ui@ǣr%O&|Xt^[\bsPfxp<):$Dg(Q9C!h)X6ؼe.uu5 /l͖CJASG=q ݈)6'NN &_~RQ04#W%H A6n AҔ@mp4C!p8-@r@Z ՐnNST#lSet:C!ة@H!CS8ޥM b ҹ4fq8C!h!:bViTaeƻC 7# Π=p C!p8v4ikpViX%`DMW"7;AU|rC!p8v<I V4d k*q`Wtt킕wKUdYi.R8p8C!th7L 0ۈu,G?!I p8h A'0~ VnI9 r|A~K>`BAW܋zڼtC!p8@K!СId(y2:14h°Fns޺7-F²u1 ]0ʖ)^.ߞ7SItӷj0Ke r$q!$&]9C!p$E8 (`,f>}@. :C#V݄w$*#vR)[,N9 <88$x~eԏq|ZuzGH8]Ύb!sME p8C!?g#0hu6_Txi;JIBַHF/ r3'^`s!zsm^ yer~ Kle7_`Js^~3XEgk'(&`ğmgӝlڴCy 풥KY$۾6+Dlz=V8?]1;2 ߟ;\>ab>~"Q^^믿QgW_?BwXd{rđGiXt2kV+퍑2#kXq=qVlQu[?wqqbsu ٞOOƶ/>oO `f&VΎ;P?]at d)#Ҝ]E:B` |5i< cc`>T{m Gmq RY#_$hZu4ha%FdnW>]vZ3$5|Y %%^*+W4_|D>|dÁg9/>`KlO77ݨX:lկMn 0r嗓Y?,^Xw1,}GZv#]3ɺg+N6e<5{>MOX,ˆg\dUyE-w)F&mM;C^E\/VlifN;26-@01 _]EY3yk!4Y2iL&38x)DxW֪QRkWyAH`0lCC´)g̑<2)- #XDΎ_SLܰa̺r4. }i^qks3cdȑzYڤ-}0>Eȹ c?x@.}Oˣ<,{1IYyP~bЯo_!:uB-hg#̰?Jw\ߛ3?Ҫ\GWɦwg8L%?켴3ϔ&Tl> :#??q2S߸.Ykl,Iak ^~Lſ?OmywsϑoIOO_;} %D={d6QqIŦlG--qߟ(L(mUa㔩-p7U(:qvm@Dӈ4eaj2kkmeIV6)KciD^AS^B##ۤtsX.e ܼhih 2V3i}@T2РWH#)d/`4L rR[$324)  ʤbM^{alW'ţ ]UU%{キsuϿPNLj׿A,X G~ f'X:;I5eCl9VdL!aʔTN O.vV\}KivZ aXs}5 $}ngXyq@aWF'W`? jkZ3Lkkl5vid( vQ_ A%-Jd&SzY)2銚:YBo1F 0B"t5 /cWd#6e& NGtv/ D bs>48+a)7c#U^BY, hj~ ؠ08ͨ{ҷOׯ_hGm7N3O?%|#󥲲RyiO+.L/~8_~tY:?}F^zey墋/s°/gi\BB`qvӉөKNNhV~X7$&זEW=a<,˥?%q}80xpO:Uƌ"xͥa؇ߒ[~|yrM7mҗ}2ϥaQeQ4 k' b˂qT}stM+- LV-پ?v(9(gG;#˥MܢW-YѰD1F5}Iӵ8/5A|(:&̫m MeӾ-QӄT\FJfS&l~sv<% u8FlF4H] X^6"«u\rzrL3ZO`Zm*RJRQii N烷&2rLks]GI=vpرJ| % #eX b)Pߥz \!QI PZ\ -6ҹܧ0$eQ}ouIᰶ'~SS`mV^6ި'釕9-ny0 ~WI}+Hl%N5aqqg9&}=&.N'(<9Lf[92mvJ; (I:k X)䃊tt%L İni<ۦMLPG4UL)/>$ǣRju:/::t:7iC#3nj~(w7"UXW: 0A/7@U֓ג(- (O&k랦)4t$/"K~Z:@v/kpшa$1 Y#=g0~sn޼y-g($$iٹXtAl1k3g]Ϟ=NNo={lٺEu\!II3bs]绤g~D)6-X?³g.Qgꖙ>e&g{w3v~x \͙3X{7J3f|[8-!:#6F?I?l-\(gb /(ݰw'?ngMiFH$yʎ[e{kg(75N?eG}ڍ3IdUs@ZiVgTp{Uv 9KR lƨn @c<9ZڣHs5Hxf]0?i^@hzu63@ywTV-qq| :&ᥡe2땩"l׻*uaFGjR7 -yq 8\*v Ķ`tGG Hk!uQyb(T6?ĝmj( ?:J0aRh`ϚuC}ރӹ-ot-n}ZǏ8>aL"s3frک w۱[n-ӏ=Vw8wPHW?p@]|5_^GB6lq)gq_,̿+tw"ҵtNzxw3$!>ƍ /\*6d F~S#xOIA\C5ք)N2*%lLk]ai#-lNaqg+m?o\g=Cqϧտq);n6<%ʻPӬٹv4i!uK kM-hT2s d쨡IdD3ۄ%KC bi IDATѫlz^|ZZ$ <|syltO'!aa0PG-UgkVɭ.{mڏAʒ%_3>-3galGcp?j T- jS+_H}Keȱu.v8nǞ{.s;DG}NmLeK1ۦ坫q# |6iᨮ.\\5 R$՘DeXjk<'DM@N̮HǡjW [fyik0yȷe m3^r&uײظNGtrSW4#d{`Vi]ʎr tQِEܪ{aW`rO-֌Eq zvC{faP֊N 漘i@Dt3Χ),,!>l49*,&q4"i343V4ÝU+ePԓôq1.2lzѐV~N{B%n$c F߷ ZQSEckq2Tk-:$iȞy.X&M?^ըE?sO,Z߾:!\ް hbS/*P{iGK*@{E` 2x`t:d{hts@rx isj نi(Û:!&X;!jy;!ƫQ q,H'Fck`;]Uְ5. ?"0"X=#ɣXQt`0Ҹf0΅4ZCgtPb(^nF0H9!YC$iY5@P*6$ִi_k:҃80hyf5!poovmtGv;><HcgET0`()F4Qh<CB%hZ9!1  P,e8#hԛ(c^G_?(c`"~;z0d:WǂIw@24my#l^l?~񂧰Ͷpܵ+hyۛr `)^[l mӷ-%9::ю:rݴH$jk0h@lFl 'ۘtB ʠү{:"VDضFt΃:pkbhC Gx*eG.pDt ^cZ)SȢJ[^x3%?a)zew$u֭:mϏI.%7ʨӒ߳[ )zO=nvܖ|vvQmdZu)X:稀q9`]Lq)`ޣQc,G#yHJ=ś'?BӠ!\8F>3AE#ɑ =#VQ<=JdMȃz!wEj$^UFrHԤTv:N%j7)y-{m,lǁ`t+0t>WvܗU5>hРURz-!e)~Eb ~nO8AܑX%e5+Mi~k2%_W;U]W<ˡi3֦=F8aް{Ĉg3 398ꄀ{&p>ȥ{@OQƃ,NX̛4Ұ=f}.vN,lHn|yhFptio< 0]@ iXt2®N~}@O-C4o :6yGv!A7v#<*L&C Fʴ?n9௦CƎ]{9-o g K8v_1r袋uG{MSoU1y@ð#t q뮻>,ek+ȴilҥIy衇eWAȤ=981e鿾|C?k׮Ul:)AG6LHʶg}.Y}6~e7'J&udȦٮL}u1>b>?/>e{}!CI{hl; FQzet-۰a|#G}TY̦eʲ`;IyyFZ ۧwIQv8ɳꫯac%KޟagҥˬFqf_gbӦM2cw-ޫO?g6lad7l}q|Q>gIlӭ)e70 Ǐ* rcfX㚦Q:T#$Bd0$F5L? e3:=5alôc CG O#;%<8٨)Z}Ç:suʔπ)W]txE)ah+^>=L-gk'|-IfL1+ipGj`]g뮓wy[~!Yh⪫N|Nj|^ͷGyeBI5GxyGeϞ"In{_~{ ޻ȜٿG{L~BY裏hCq \r,dqn:*=˓.LEYF~~Erg?g=ftTstn6y71aQ.) {ٯ$&̤zfԙ'>* C#j|??ɮvEe|f}"$`M,^r%nz_8]orkeG÷N;M~1Ob: >X$l8Rqg7(7tYg-տɍA^}\ _~yd6g&.V x&]d[aQ]>Ǘ~%y&tߡ1XvMX4yyXOݵPPi$NQӭ#Nt.W_}}92 o*p6g{&}v^g)W_sMF+(MŎ-%SFq|Q+(+3;bMcXjbnV[70(# F>:Bp$H=`62 #+iRoM]v 1ڈ6ּْ-tDZ>V\ J橧7N˗K~~d I4I-.pF5<Է)!ض~W#~?;y_.XΝ+sd6i!02dGߜ8역ݛ`aaeeOQ %bt#L.dn^\{3&-0,SJ%Ǜ։@&g7~hɤqg4T)Seʱ &aaT-KMk- ci@sDh`5Qo-UsXPL'D߿㖆2(Σ9PHMЄCk+5Cf*lZ dP<6)3q&j01 EWӑ R* *~ P=T"3 )G ܙ Sf)8h)bra1V Udy퐈;6oތ5ߔo/·e_䩧fr 2Iϟ/zr͟@FhT`رңGY|썑+vuWumjhj6tM {V Of>%[hNQdkuMmA1ޛ(hٔ6v֭kr't#_h3XFҍS&S8o2'PGlQ5]'I]rK6cƷ.wO6ĵv}_QF|vΌ6yi'9{ 49Tڧ$|Q+ɸg2H ĭcƙ di'I'FZ^#֨I>ݺJVu>K( O8z?iIF11a?0=5maF@Hq(*|$ 4NS©i{k55\WҚׇ~D~vzp k@~5-oRLyIV3Ϙqysl,V=L2dȐ̦uX9q$}x[nOGa u~,CSڷБG-tn[y}) ߰q*<6tuWCM)& ٓcT{MfSGMOAy\gE\{=uee>I#_h3bȑs3RXh)ݸ(}э^fk%Ss~qqk=VgI<񲄿|& 3Io*vMSl+ld]6Z6ć^oΞNkTcc)5J"ST55kB fF3S [h; LWfh5A$:~?vA#-CZ38^{`ZGfݧC!p;f5αvٜxͷiڪzn؀"}ު5Ax{ׯ ]r,N^рNq&A'E芳=Z77Ƹm4I3`G!A `9Yi%Ϩ72F)PFKϦ#"<JxLIkLK+}7c<ܘyDs;e:dD{YE! \b}8C!p$F9 DƣuBtv%GBh^ڑ 7|c1gU6U4A=h٭0}cgVfg֛^7. Do3t82^++]Fn $tZC Vi8ԃPwpC!p8#ፂBmJ|\zVvSp ^)ZehF{&|2et*NkS:/7ޔ \18!Cp ECZw3mˤMN*6†V 2~D)0PϣH6w%"OEEER>aEOޜ޳h5pʤ IDATi`{ҥ5v2qtZuBhl#`-B-.XhP__ΆtKqyjVDVZvS-NK~$kӶd㼼|8u iAqBTC[GDG<@P>ږ][NcTӟQ3{sFB;pA[5eYB=@ [[fM:qN9+xտ>bjAMsWe- .ҫWoٴq=zHCxAFgJ +3ReD63cq֭;NʪJR]|࿺FgNtm9dٙqqD }&G b uO<)..n6]#-O4hP <ͅ@k_ujOӮ"ЩG@7&54JlJ˟: 2L,["[˶JUU-7ӯ^ȇ_zNw}A]էOi|EYeW߾ql?*Aկ_ dSC\.YgZG߂x8FxZt8>rQ2nru׫a8c49|HNe˃1c6|pJ0ia%K`&O[p2´ᡇ)_[I{)se47)!#86=w>ʈE]#zVΦMdƌ0{a嶎#<*Lm9 q!a۱}}͕/ _?k׮UqϾ/CkY}_}U9#ݣ.[“8(ŜeK.SMd닕+D>q qV9ϛ!Y:1krl+NqxS΋/ݎ=!v5~C0k<ԓ'X;o5-1M.R(hDgp -t`>GY}"$B HkS0no.48l 8jZZ?d8xyfF[K.T}H06~xȏ|裏ȷ=CO6.** 榛oVuϿSYv<n _|!?p%r.kFxB3IO9w͑|@l"?&E. \z\R^yf9g5خ:3f,[\JUW$̆W\HS$i oMDnlƛnOnfw}/5{Ho.:[w&7- /W\y􅲳=qA6dٸ)Vs7n`m d1 N`SR9Y1qoA]!t)[P!w3F lR^^&3`6ZؔP~5A ҟme)ާvT өr~&UZ9R.x邝{H_Lr<( yreȳ%ZvQ P^^.cƎGyoFfyMoV\)uH-dSy_gHgɓ'7o\zdѢE"o[jDH$3muZt,c,X'1xՁo@ǎ= 3_}5o/#_|cu4Iuٲe8X{KC8i֬;_N9Eqϛ9_Y?#>S?[}LYj OXQns߯g;NF-ig)ϛ > meaˣpLr/l62:%cqg\=md`uwC`G"F@v[2\C  Z-@KaL4kBB!o(ڤQg d3q,<8:D#Bz[WVVu=eEkǨHo\!C˧_.>(= +ݎrՋ&?te Z8{ie.e] Q q`Zy JyfjF:vq99=bYjC0Oa*dF>}F^ze~Q.b;wsx63/l+ &27O=M]qeҿJ[&3Ia2m4fۊ#bv?ž2fVVf~?7Q2l2ƹ%#(<[E&+, \tl#S.rև=qzC 64`h0?bގqlP=I4{3W, ÏF=LtR=`]0=a.jl+E{0.7(]n>6aFWx  0GU>^Q%Faה筑 %NdX_A6dda[̲622Ip "'v _zT-s@Z,3K6^P25QRg;Ñr28J| ##Ege,[L^uc$D: c`TSf3eјU])>m`=%ze˒5'[=Ȱj ?*)jl[뤴N+ Q=W**INo't򗿒ٳɖ[Ywb$2H3b}Bv:|:JJDzs_EݗHuMt:?_.ֺ;Xqc:ׇ 6TKŸCb+Fs2ttw;f͒s=Giى'͙3X1{} ofn9cg``+Il#3T>+'n9s+PClԽb*G2s麳`K껝L{ .3^TG=/!Z8͐˩@t.ԘFfc:X]yN)Q\?yHFAolʷmHܘ46.D>5eүgpNKcX79xl\U'OQOƣ,%( xoWGc :kI= Ez5Hϼz˺ʿ/-ֳJN/W^;-i3Ϙiv[QqɅ^(bEؿտi0­gmȆW\mdM ʉӍzr v-[rpZy'Kly'#Cg+Hoyެ8[qIpr}ϸl8Tc}_x:R! VICvS6>LauN@Ϙq`!8l=G?:6Woonai#fφumU`?bQƍ1]dc~J;l`Nael(Wb/CaDkId y~aFFЉ8;WQX^aTc!gQ ꥛TK2)ۦSgz!=C߀`q_jya:wC 1v.YC!p8)no5习tDh욵5J:&0:ϊ :"U~nE4ab-8l}uRo99W9Bݻ{13,[D}m9|@ᆠU^t#NꔏQ]d@|8p"@/p@,P+oNǿu$E66]Q] V^8I^1utѣ@\BmRYHA/ڷlTGFF C!p88 @C+-9ՠqfDX#/LW~}-[%,8R@MwR10_cY~ wv}m6ynQ/K-F;VF,6Ve\ UJꝯk06UmX_џAנz65)UE]!p0c~lߊ omjnp`I)sAkJ~ p8C`AMj[>|GmZ܏aa3:SӫP ; *{4Yz,]T?koH8{SeMsli ]a&Va#vUfq48X!u$,U>0‚ٍ˔Y>c[`cy1qT3fԇKGL^طt6ď5k?AXH޷o_U,)}zH|[/.-8n<{2jQ~_cs8C!!p# ;mݴuZ#f]c as܉#5bA7"US]#]qEa1ǢZ=K:bAw-tWj]x^^T`*գ{u&**ʵ-~ ?HwMq8Egq@O,oXHb\4Γ{!_VQ&k^"8 d;uuƋ /:Fاj<ل< )đzm޺A^g,ߚ'_*} ɬ~UkxЗ:=YWO)zIsqC!p8:hH}pǰ'M+aP̐΂pE9]{ИQ\wBz:'yuwvZUw'd/YXpF6h/CR c=O[nukRZ.Wаόk(1;A|YZ'}5@':E~ ~J7ɋU5r{. N.y-\P| ~txC!ptHO^JJKKw޲]`nXΫQ=z[284F1釵 t06o٤tclիVp4ztuUO۴i'/]ͥŋe͚qceak$]F>ZPL &ȐC1ʌTUUj 9qaXvC{={Qv]F6#?*:['Gzh:lkR3jw5☣#fcn`Fmơ}F1Ǩp8C#v``=Z  8'swQxpS:a3 vҐG]QG;hqĂ#4uqqQ7VDg-:!=r`l3fftb;N0_ 8?} 7HXqV\!|ҮDs@q0pWuUNktx\{p$x9餓eS*ĈfJxmӡ3݀{@~Nz晧;ߚ! S;C![A 0k䘣!CɢOJ^>@pA78txj8^xuq7NhS үoٌQNP2Pz5c(WH#vQ{% (?nk0@c`m݀w:uƩe t7 ^\BL Lo4N)'ɴC瞕|C!p8Ns@Euk;} 2\ }N>t4iӰ۫g/ضNGt/.Vg\ 7[6L#[X#.L/C *$k a FuXǃ7mڨmp:G`8}|,[8w$ӬjpCV,E0#IZw͛7OF ) ՃN̗otKG[.y:w!*\+ՙ+p=c?_,Y hP=\C!p8΂s@tw{G?p ƛ2YK)G.8>tёzH! _Jő|LڲQ 8)X321ot:];k> eRg7Fln[}PP rnh8ZB:\h]Ԁ(K=vb{ ::tB1Z[P6,tp:Xt eT>(R IDATk*/tw}Gv: =1r8ZDyԽ΄.U6g{?DDkNy1 pNԩ{o)!.8C!ЙH;3oP3f VCxЮ:֖p5FYDoY<oݲEӔef]T:pq:zEFf?mNMb~3q:'ݱP7lX IKÜSիaW+#4t9Yr( )C_pHQ[] 0MX>Fw}`|+_T:KU)Uph@m|`9@:!FtĈGf82CN!7}N[.8C!8UWb75t"NZuaQ6sxoxmras/1Sv2K_CDNLb`]s C:jq8&QgXrɟzPm:ZֻoNन΅?0þ .("?D IpƄKb 71AkA$ATTmyNutTwRNU}}dwuTvoF2cVQӂHPAr FvĂKAcܼEs٭d@2:$F@3HLn6I-W=-6ÚJÚXYbp֎1܂K,pb50^%D#z:4kHc^[=pޭ8G @@ &ʸ\W*96zվF:t waRܱSisnn aA} =[ëXak>g`Y257ΰ  pP&ngW[ɷ(Pv:\w=ojf؈X5kr0={&UV;aAX"Ǒ Bb&WC^#b@{゘Z3 nN P6@$Jl~K.Š[G,s uՕ;K P o(bF_$v[ DZkne2Æ#.-!y-КWKSl2-L  &@R͎_Xvxj ~jtsS֗vv2ZȲ놻eVcbi5 ~r*H&xX.#h-"^?::퀮\,  p6 ƽl`S X`ѺU+w½cx]ՀxAՄmf[y4nZw6kBZ>)u][nu7?˄  gQ? WOʽߝ1r~CGk@ZHVՄp\kܰ2j}iڤ,R~^7Køp  p eMƆ|wɱKtRCu8 $Bg>l$,oݸaw-q#j+תU[Z4o)k֬qC^vJ|B@t{s~ٿ6VQQ,iظu!*6q_@\G]+4iTʺwޑ-[M7;7u#qUL{@@l 9[4Pr@;~k[2/Iђ#nĪrH+)_j@Wpڭym}tySr׏. @@l 9:'`5:$[om>ziGҬY3iܸ[kvuj?Ͱ-),'{?D5l(jVP_3n;o@@, 9K<}wD /iH .5MjU~+s&  p 'neȑ#Gܝ̽Pp=<#e Ba7N, @@ ^Q=x *,MܻѠ7ԮegB@H-@ڇ;۽*Wuv^VZIy$#.# `}>:$M5eڍ~Uqܛ4mjYOMz %,>9~T<;' )y g BiIi񳕠|͹'˓&sՄXߝ?[@Кj?b'6x^#n?P>,Gum';6Ĩo>rwDBKo' yx@B8  >-[p}}`7H!v?A{m#YT"Iob,j   @Wd^[a7ku>]+ѫurHU6vګ2l:UYt}@֭+ꕏdvOF Jfq:5JoeUd~D2"Y/ Tb,Pk>ƆzTX8}\pby2'rߣEҰQ^D 4h(GN[S5pX͇jCo,Em[W.oEy3,k^wWʯ~+֭o5'z9U0# i-ׂ}-,Ԛњ>1+x>iܫf=<[["CQ֫/k׬zlK tT|]7m$rɅ1޼y|gꫯ4~{Ҵg (  ]G^Y/ܻ7Rћic)9~ޢysZ^Iڶk/Ňj"mn./?HΚ1եK\$.1|جxu_6c~3D϶.?-8pp ҺukW;oSّ#~UNrˤN&^Sd϶|˖-{%wte~H=\;ʿͷ<^z%9\{GG:];bw&.#ZkQ"ּɚҬY .Љ:ï?#ݻ 2D[ߛ(mvKc-}z-+=(.. /0:ִiggϞwO~h6 U :u$&Mr^Y~,_\j@k5,v^}4瞓n=_ IDATI>!x@N_r TW-س 2jjߌvWuKpT VPV-҂n=m6vR~2:JS$A-9i}n='ynܾ].`4zmEKmNݺҭcg.@-ʅNj"'nבu9\,+Bk35'M@_[޽{(:]?;W^']n%w{5(}_Mi{<Nv_N ښk&ӟ\:Ck!ygRTY9K}`h`k%9\|H2i۶Nv=o:u_v^J:x!6,綾^*k׮kFySk_Gj4)tI"Yu~_R7$LTM>L|LÞ;tZkeH>!yu嘚6>_v'}[2znWTh毥ĉӾ+"]vug֭Z#餇-maӚ5ky[L.]d}A&-vի]voMZ;w*6K۲$s3@@E )f~]i*8oM6gJVL;k]l-?>%Z 'N|l}i\}B6N㏶DvzCzht9kmںBK:w=OG(^:z4+"sv@j:-[*ϙ#u: FJT xxz>?k~{ՆL}=B,h`šVy̽FZӧZ~oi}OXh6ڽn#UDRU D u8wAֈX@`}-n9V瞍.ZNԾ#}^AI|>MY=Ț2z=m2{iK> mu,şڵ[wg&^uԬ8YSmpX#Mk6jC7ސ]4 zYŻf?6eԨѮTeG}D ߸me9te„ >}x؎;FƏN6b֔)S ^6竪=Z" A-dy-thhmͭvi!'ĚEY?!mF .͚[: [AڦL4lPp[nlނ];UkeWui:b6iL7ۀo^_\nyK\pфl=%3$L~k7eȎ;ulfcmIJYV-@;?{PvyBG&_L3'{7) ԀQ"   P Vo͢vܥWs`h=z_+o tЗq=b;[u{T\cGl^bCZjv>}HҠa fwh/ZbߤVI СqTWyMR6tUL UJ  pfĴݯVe[4kcaspgTjL;wlI X_Zc5+Fr#Ni-_)t@b#xj@*J@"+Ys+{4asw.QfXVf?V`AM2mE/6FW?WQ:6Ú=Z^CdIE8LY dB  @)wk9hԨւldEgi:10۷Ge𐁮ýuBJɎ?{p$HVU|DF  /I3%vu ~?{nbàjҰ|c|^w<,:cFkDqc^${;D@f`ij)3^Ykȩ#^x ٵs*vG뜟yCCGoQ2jݳA33#5 V8%Ezχ6oQ`^?5ݺK~͎֕]R-y&):p nL[usQcR`@csTE?-;v+ao`*ӻhޥeZ°I\S]ժS[֭'5  T}@@@@ V$V   P UK   +@k@@R*%s@@ 5  TH9   j@@TJy@@b@b5x  U*@Rd  ~b@@27nr'c@@@ F&X1D@@Uٓ;  Pv)[n;vȾ}iӦr9Huց7v͚5bS͚5]vgɉ'*Ζ={JO><>H@ ?:PSСCҠAS*]5 UK  P>CYz+ 4HƎ#l;3ÆuAH6lؐcYUte<Âsʮ]Bm6y7d…2gdcʕi4<@t:]wݩ^m*%s@.V{UJFդIǹZk咗QMH4#}#_~ȞI2~]yfk>/^,ÇVZX*>͛7{nǦM[n&aÆ$y/RԧO5P+5x?M,-ǎCɎKN*~|dA^z`,|#w0iEg"n%o~f^ZC{K%KXJվVn4,Bzߤ[^u?0j]YuݳsTngYYz^E-;kO+k{N| sV࣠d?Сt]|KIS}-++{Nnzyއ"ϰ۔j[f͚%7pCF|X-Ԗ-[Rew}W9"}Aߛ0Aow?c.IS<>yfb< >.>h\^{fU `˳ӖJů̖g'IdgGr/럧ةP$c??7Ѷs(&l[%̐V <ݖ^n3RzCV*|q4 2 ^l'c{\, ws.$ȑW9j6um`wy3R֝#'%A$*|a7?^&e)4'l-x3&[Q1B. LR=RfZI3 yoٳemY0yR_oz>&MɖëlJڼ2!Yd,[LfN'},XBgKf,Q:W5-++uLx.%YV"Hz<4yW/gq^o²+dqh?xF,ӿ!elpnMl?U{ltҥ|+_..{l3mI9V!/kÇӗ _&mg=l4%b'[&h/Lw<j3<{dټL'[~ڴiIy:&J0#Ua? $?] j,Jͣ^'@DI*ynzK]n>TH?+ۮ!7˜ugd7+ %[L j^y_F$s=u~b'Ui%,`6ʗ6mH~|iV\7|M~6V[*OxWYeҌE75T&^ݞ],ϓ {z-N^ce4w"Yhzd;'[ 1[WirwٺXkݯ7˼'_޻%y-`gʼ=Γ"m _Mʤ~XSv'ds&+(q-E$`(_.髲q3EFB΁,/GrrsY~g?43Ci!r5ddgedj=cv95Aձ- 1)}I}ˊ?y3^]ȳO1+ *QvlY߁ifִmd۷,ωh X_ 7ߢ)o O*fp*xߍ"Ge~Z<]Vn.Fwu\@._L L|%: o_6oeE#ӝGLgYc/C,sx4vLVyT\ڻ 3m&7k&ڶq֪mFߏ|џ ZU;7'qN~{Pˆ"Q?O 6 Ȃ=X俷~;?k =ǖL7"W~fw^$H]pa=^ի^RɾKܹv̺D> @>u-(Θ+3!'?$(ѹttϧ"LzP̞[ydJwB rDV\(عZ0soO,x-`%ҳW[Isknt׃$;7 &qi7ǽܧf(=޷iq3dĪRK#5FAم۽ o=?_Ӧ7\ʞM6e:}n[m(R-j6jQQe3ѕ 5k;N|k >l=M֬&+`jvg!C^g6/v,ؑuI|?NXtAxغuctL~ɪU E,]ToٸZ)qŵ>çlzXa% .2\ WXn&}*(^,>Yu6Д\+N %Sfr{a&iWSFW ZI\ʻ8ӬL/6zV>75uN]ۢ TWf_+i-8?wJ7sZyl2).٤pQL=@׹Z0}z?tۂ]nQ9f7,;5J~O,^cػ\7R7r. d"?E׫L \nSJwOiHNޕUe+OQUh!s;m͓{w%HKzhɓw)m=+N*g>Ie`6ҹ-)_1Hy>^ժ%>f.l+ͽ2׼.9_K1-x^xynV6Ѐ>Lr9;dU.m&=?ʧ\߂n79X/5]J6SKJ׿Pm+Ӹ}ie;P˓˂IDAT~lgn] o4K߷/g|Ty;rdl>}~dLL}-&رǁE˖w}n_,]ӛo)}?z-hV)˫̕]  {[&Bl#h} h^g6/vl¶FBM 2Ya{p$z!.zkom#,}n:ڗ?mͳ4bMIHmh%~&)ܴTk.hr:&;_Ҽb,}1!ʵ5@_̖wlkU}?ՆH3/T~nH .cZwI/C-%MH{)F7Iɵ=oSʑC `-tdmܽ*gΘ dȥȤ9A2ʵ?WfôI@$*'Ut$"CWꬡr@AWOf=dwL\qHz.{aK z\ }LٮIj֟z{{,ou,-*4TS?ii KI㟛伨eGHۆhA2wmo9n۔+/r |5:.gi1i]1{s -ԫy8$sMesN熝Z^*/ֆSMzmO]:T{\2&UZ Gs͗w@fݧ%#7.RbtbUZ{s3i .XK=WeΣtǯyrF@Iֿ>_h#wl_>_dܵzEYl1h߳7 .信qܛ}׷W}okG/$àC'&9woQ[6l/Kg)i;]NۗwɢUHm֧C4G6KIֶl]'sH;Tts$"K?-rn;~9OKqfv'#m7'N ~n߼Aב~oLwU{vNUu<tcя;'A_6^mo7+ZKykO:mlds?}9YkdŲ~CrcFG6ĽKrι4qwU]v{VΙj,Q2ckS ?G/UM%HTmsF߳7 .信q2yw>>WmP-/O,Mi΂ g{og|]I^+j7&/ay*M~-rɭdފ`^ɚ͎3wVMXf kffD-M|ӏ^CE'N}m?pg璝ߖl7baK}ͫY8F92e2U&Vx) ޒ*F͑19-'~[OJ.ZݯM˴!L ~{k}RMm۶uW&ܵK:bg~*ôMk[6TYw:?? I4 >l9Bs M#G=K\G5vڹ`b>>zzW<U4rKbڂEVj?L &V2ϤX:cSGH<:iNeZQKI4FW(jՕ<[yɶT$E]avv,>41TW\W!R'gS+::rC'5|mW|TkJk'츺KtLGf*‚R6;g"]NOu^9.eqs6yNOq!ΉKۦ_Z=ύnoҬqSo\s⹤?ť߬*Ix~nB~CSf.s/5ΩpOv>/W\: wQvj$шbsLWkbo[wk?͈]%?QYڹa䮻Ғu5rOTrruD "p4s%xFNR 2u ™x ?Mܸ?6d]B>I4J;eqiל6T)9oRU!&*$|✫x.oQ&1yꍨoss27 ~+e.sl23?}-e}mjr"S񥒩,9V&-g.:ڍ 7jk9ٕ͋ݷ:Td}0&Syž&6}UN|_ |d3@eS:5!j2v<@@d&TPh9`M2k'dW"L/LXSC}hWV߽PoέC)h{L=LCx @SĚc]$M3ewdY|C, v>2 O4UESU+#d~|[TMe[i,I+ۼ+kDFޏa;2A@+l% $Ū3mfL]ZGF,^xO}~5 @@\ K{IENDB`pacemaker-master/doc/Clusters_from_Scratch/en-US/images/f-13.11-post-welcome.png000066400000000000000000005710331217637305600275710ustar00rootroot00000000000000PNG  IHDR i1 iCCPICC ProfilexXgPMX`w9%眓sFrPQHV""HT  |﫺nW3==sByOtt8n{o& |~hw^ydOEƲ~ѱ`ƣagƃ8<}89Dc K}`(!`{6F:""j_1? =}|~QH\tO߇[DxliH?YiEyXڮc!ngX -Ͱ0{L _|l?v;4 ~8a4 *zX[>AD2AT4K= QLY@* 6!B$ qB($)Bd YA; AP<eAPTBU&tAF  /B !PG#,N/D"FD!{aK,b D$R)TG"m{Xd2YC!Y2 P2(-凊Ae*PMsjMBКhs:A/o/tO ÆǨa0PL*8sӋyǬaXNVk`˱wcX:vGq&Ha\)׃-6xQ&OƟ7Ot&L'hLBO"|'BD =1xXFB$1P$ <N2422L0|'Hb$=^IR3>iHee4ggڵڳ:::tfuu}tt ][ԗտ@ aa(hĘbl\a=HkcNlΫZGC 96['?Q|~iqN((;s2)S5ȂB¦"rQJiy?J *=C8f̪\|"eA*ܪjg>ruimGX]i=>~a \/l7F6694=hVknni9Պhop%K]m2m._W|}u嵾E۫nPou@]]nZqKVmەwX!dMݻ|/|n_<0o?ڃ4n>R9:X'*Ontw,+!vw'VNn` )Ei2%R3\e r%sZv_PXDy M -J*.i3l~5!7";b:cbntG |ǧU=> %Ň ?|"8my9 Wү&hMONθ72 7Kbb>Y&~Ҽ v|8ٲm? r qtEQ ht3F3݇N $hf-2*JZ{ZktJtO08aX`tƸʤٴŲf5gpӠ+uWپYo!o BVPdpUpF8-5XTGb,ρD$䒔}ά<ܙ5rSű/8~ĭN-"aP+v( ->S]v^HD\5~vtx.nnm^jt Uk%ڥnvwv޴v!NaOݾ{=Pwx3P8xihc ƺ}:kfZqm썹y ߖt?nYs j7u~15g@ ! (MQxF!QZ ]!b0o.8g#Db!y"S(6sY|bCyOMaN%3_BrUr+s? EO%)#T+l$ +*#L,^]-")E%!#$J@J'?pTLAiTX]_uAM=^CCQsUk|O]'=i}Aa1;63SsVyk\ulmv+o`\RZV^G~oyр `carVtvL]쭸 'RRoO?w0Pdfa,l#9zG5)K?!~RJ~]Q%JY)gЪʯ^VΥ>yz#oKܗn\A^uvxÿAͬ=^˾'=&?5;O}b9k1 @)\py S%Cv$xL@ _+@dC"HGd9r%:E3mq4bNK8<.ׇ kD^b.q!ɘ(XDecS˔`"5%;k2`gfoPtĕMny B5BZBEEzD}b-4@k('% d؛˦ʽTpVdVQ*TvRTyڢ1٢BS{BL]OoI1ɢٸ )E_6,vŎ.ܮnWNYhY◈O_YXH5ud{l@ː h!鎬AQD}4탾g{1Wx.[TBaEc`#n13v1i2Y0ّ% `вp(BC,D\P|V*+V򐔀Ԁt 9[rEK*e_ߪj!ښ̚Z={JuTuzmG Md9LP&V̿XYnYclm-<]nθ#JxX{yU{1 ಐa#Q)+qf ]IeLiYF?Wc'NvΟN*VwUU:\Xl( lbb׶k;:oR=ۓK7|?G O`610B« 7w?M;^޻ht/.+W}qwۺІݯg7_f#퓡eD\I@C9w0ژ{XK. Wt KǘdLb 7SҨ, p'^psvp>s7/[QBHWX]DETYLI\f(-)!&(ɑU+ijkQOD ^ÏT S_\V'Q6vfnNG\\Ϲ;1}n?o_0|ʫ'1E F)D7݈7Mx䑼(;$ٝe=v5bœO. <<Quxt-|E#wSmPk%Ͷ+.WG\va\?7x>(2T4xd l3/S_|4mlJmZt2+Ec ŧKe>}TlՕV_'=ڏkkQks?>\W]`Hݠ2wMͩ-խ[sǶ'ߵ\n\~.ͺz8ـJo?fRvQnbޥ|^ pHYs   IDATx}Ewd{#!$R @45>>Eѧ؟<y* Q !$@{93~ْ !9̜9sf7Kr9J.F|9#8#8#)5ԩS)8Geן=p#8#8#"L_'rQ]];yx<8#8#8':sũ͛7khh՞ -Gp7'x: :thz8#'EEE3m9R$x,eyWez~a&ݺub -6_yٰ6m :&{?|m~f Rnp}yk}Hݴ[޺uU6cf76d>ܕ~8/pG`_G;dkHt4={-τȜ'1n>cϒw7HZoX!K& f=-#? }pA9AlXܳ儑 :rGppN8,]T2K{KKKak3t"Z ۷o>M8pzб ycgϞX-եhN GuER%)K#ݽ{.u^k6 X'粫ZýS:w%S[l-;#/#Te*,5Z_tB2S&4\*ʋvZ'R%|y+r,ҍRk eHtMexϰZnKGpYfƍeرʑʉ\Yu.d/,?^WC5W'ڜYjNsˡ%ȰpVXN mrpӀ5Ziʒ6Y5W=z>&6c1eIӚ͖rGp T7mO)JdJyWdKg2EzaƺC>Cs͚P?zr29k=;˳?h-/ 3}H{YJHS<8@G!k׮N:I*7f:M.q'O>NFpoxkM o'ga l4s7hڌ6`3Lʖ mrWkaǎON>26g&OWGpޚl-$S\4\)GkF2ՕCl2F.ݽR[]-wq'ʷJdPN@5#8W 2D9r5~g+F(>eq"2kڠ6jpրFaC]֏첌zq"K:qԍh.$I;nR73V?u=8[ zٰ~r.&Cw$$k|6tO{WeTʿ6"EeXZ!O7b0!}_Iv'rǿ)g469Gpv@+ۑ7 v$icWuӜM g",&v:M˓LGhqtXϘmdythM/i7j~qG`?D[Et-aY*ږa$ybRfh3doÿM ^sOҪejNҹO?+ vҹseRG۰xR-{pG`/())~&Dޖ6v=: ɘe7muˤh3zPA&橻6DD-sfŃ#8+&ɼ elS!\HMqshz#/|CRU/?$?;UqvmG!WsK&v)-9{ֵq8#;ܚwE1ޛُ])X]t>(Dr;HBO@]։y|s6BԧSC]ifEEqб1-: m ~qG-dnHu8k+Ɛeq/N-~\i5zdEI(M4ŞZ^ԫvp#> e 7I?O9#б Ob?=1~Rmp}LL=Ni.Dݤ~c=jkqBor?rrS`Vfzۏda,Iak^ V<8#w'6Lu/nw5 :.̷7,por|'q_t3'p^GDI?=yM&_vYh3$ڤ@v&=0 eIϮ-;GpNKv>|-3Z VMrVHJ8]'u.Ex'NjSҘGp: 4ؖ%Ns"ʢNӸ͹.bpoǦM 3 lmr׫X1=hРݶIϋF'b2.kvG80=U{86l4tn.uKv#8o0tȽtӖѴ{JԚ5k|;7mX Ul67V9#/# -π%wGpZG`h9awh+o;#8#8#]Hi+V8pGpGpFmw GpGpGpv6eK8#8#8@ Hy#8#8#npGpGp@ Yŗ]| y|INgCc6^{M͛'|dmmyL:w_3fߤq+Ӟ/ܕ۳M8#89VG;:~&_Ȑ|ȞvoH{F0s t0$^PUc7 $s"f͒s[E`/Q$N^GpG`G_*jG==6kkBBN؞c ;*t Ȇ [Iq|s:b@C,իk׮z&O,\pAG6Ƕk`Ĉ đ_ $թNVX:J>=n#W.&~v#8#kvçuꞂ](p6jUVVS&LmԜM3ɁuTحj'|C9Dg3p+޳_״#"I  oɒ%TG:!ejwl޼Y+FRNgHAuڨG`ygCGd_ =_Cmn\E6bcLݸqtྊpGpk㧐!Q,ۥ̳Rtp6ܖښF;(}{̝󢔕re vȫwT)6rR-TSYU`NdV㯪ʤ,g@j֭2l0PI%@N|AK9#2dZr,z(|y[3ŊS$̔b)[~ti8̙#=;ω:k1uٌd@ %EY+=K^=`I ҇QW^[23Yfș.Ғ]5:1u"'S"Mk]g@H8 6T:i}LJ =c"=%see Z7Hv*׷l_oo{e綾^ur".իԷJ- 27sڌO򹟆Nܾ:{κ1 :L2ETpG7.X1xl΢캼l7$'YU3(o f$ h '9(aښ5Aa=e-#gwBxbi`Æ M$t&|lښNY\~;ȤsH&Hcn_tHО_}V3\EE~֎F$o e9R?D(cg ^J׿U;doj{7

5A&T*7~b&rwu {^n3 $nxnrEa'G :|OAZaFR%ڗYqzi:y1LbMԊ{b= 1N8#8[.3fHz.U/*5>?#ϣ?Tҕ;a}TxpF\㨯ɐ~Y8F#>tmX#w1n,<|~Gf@HHbƛӀEw̲Yn/{}L:&FipʹVqͦBqSS6ju 1N/xFF .ҌXZ9d(ꈬظIcQɛH9[1GK8DGl޼yxK:\ڷrJcD3zo>ZGpGhoxQN#~##)&kkpأ%NtDpD/I Lwo-,r)6s9mM8>>xI_^ ,*R'>uRz\R*pN5CU]m73/Z{cG{ď{88~΀0e'!eByϘ!i{ouGpG`AKEə!Lj%SV "*&/>V>$? _ۉ';iV$T4'tmDon`=W D +Bl`6&QPϑ`W4s\soX4[wIQ>T?@ 6O*l"uY ]Jw%:t!y1gEA.\xE2-~/h2#8#!?uꀀ{"d$ '/&du(*]:/ X1ߑ;dv ڵI77o ^Q;`m$n&.+-z3yot ,MOQs3hOIi޵hW',p>hriK]JgPgE)>4i\i컡"YPJpzu[^ү[/-.}nBǁ8CVewa ]` S|s7zQ4mfG̀K.;CKd!*ߤŁ ccsV9xXFJ3d2 5 e)p8KU_/x/ݴxtIǃi:$;d`9[a3"g =8#8X^prt$J:'pPU9MI\'mQ!^[(!SҷWFJϮ|u=6E+Kd[UuuȤ6*nvaK|ŲeˤkxE|9™˜}wHUu O/Ymג3rOIXJ)jvK\e6WU7<0%! #X yi.杖ͨv~O`(߇`8#8@{!@>?|bˈOAe8ދaIq IDAT2+pX->D>!9#Ϯ{YʌJZ{۶7NJ(Mx5mr-SGvu@(d}IK^p8ōQ'z Ovyy h:aÆu%#3H&LzJ{9݃pazG` FCz6J5d$̯gɸZ~GsžA_#mz/=8$g2 3K ,'t(QLiܙxspGpOR(q2RK.5u@ז|a3 g',* %͖2? -V܏"2oys)/5SUB.rx) Io7baG WǛ%)@,v?q % h@ t@'=!Gy7w34ӾOw?@ u=DN=A҅ϧOK #Ag3 1zTTT ~GPp9=>VGp >ǡAȧ2;Q|,TU>̈i1.-GZ/[or]OkD'|bϛ˃كvNtBϐ{7֬YGvRѲpc 2gxx3>fĿǛ7ˀ2qG+ڵklL'. љ8k&O^ r{ك>8q%@gӦ]r9 ec~[wGp4YT4/Xn%$>1itZޘG{b'LC%S8yZ a amƍgթSD"Yxb7T%q咭Y8xWďcS6c Ytz:KFɀAni=*ı'}/[sn(ѡ2N~'iQ!c|ѣߊxGpG` g r.r(}ݛfJvu@Hq) cC.kY`HR>fOylj<~eMPMIcbH94΂ǁ)87k]H(?7OvjD'1O~<8#8#Ec }"lCBO GęeM?4^C3l/sb'4#~ɆGH#M8#8@;  p>NGpGpG}E߼pGpGp :ckkr}'嫤r4uFj,_9m {b_YY)o&;&wGpGزtYcweYXBiGwM jL6yj~gc' lx+Ԭn\k堎|^Zftg-' s$k<.7V$߼$ٹ44])Z΃}L:{צ}9r%ȯ_5O"Ș=hR~;H|rL=UGpG-@*ՏʩW_"umL}2‹dHK|f{IoYgO#9G!Sf\Ҙ{9z,z#s9 |סEotKK6-xZqGHqvoP\.G*x7Ӂ ||XfrU7.YZ_#|dӐ^@MMZg7/<3T}7o1DRһip(m΋˳?FϿR>7'eZ~=vYlYi՚yg#oȂOa)~Z2=~3lO:uGpG-@Frx6^9XRDӭAoFlZ;wwp`fEAF&r5Os$]v^T"Ex`#NTL~ /Y&,zڴ7߫mRMZςV5V[G L5=ϮLId>/L?L}Tɧ*,OޡxB6"՟6]a*U^r|dtՕRon/zkWcO,4ň6:M&1]8alR.CWS[d՚M8vo./լ&C[wB$&M,lw|BKiIߙ$yW51{/6׿8Mn*G~q=؅na{5"sʤowsz6͹_>{#r׳+ O]w|w*;ϭL8Aع#75'N o=汶z\ھEnUnYﭟZF֍/|J>_H`3Ͽ36Wˀ/3Wڻ+bK_$52_,ƝJɊOɊuW}RV}ɕ~E.T܊,& ={䘣Ζ_Ë; dˬe=]]߳g>|zBȫe/OEk-(foәWP~Ù+e`67z-;߁7;Ev~z.#Gu ˾}x!2x\5/>, GηT<)5Es<NYs?,BU)_aϔq?N/zaՇ^j8[W[yJQsJwC~jT._\y,~rذQX"h6"Yd_(q8?m/|A&n"+U۶KCOtϝ*k R7}V K%W~nL Qh>: ork,7_{ %MmD:ux;PvN u:;ncߎ y-)Gq:7QN9rԩ?E 3T ؗCh7 . 5[O"a2PWljL >*sSyyWʢ0=vGpܫ![)kU',̉4{4(d0ynrpt.ȇ\{dS;I[Um_|^(C/mxpK&N8X*i\VYz>!'2m\L;Bd:; *仒$7xjPsWiz}~L8dP4wTo\%5݆}YnT&Yx`6%C!=$WC~xϧ#ú3oHtyڭrѻjrdSr7%̛eԻ[ɨYߓMu9e 0ׅ~ fK_LW|A8c\yՅ"ԨЏiO`GpGୄ@_2^Dߒ~xhoJwY_9&ə$oW*:]O.G (2=xBوc<^~(/Xrp*,*pRf5ϖRЍť^~@%'yc{,TI vΌ&fC`R1&=86NL7lN7Z-` 7mkzv T}{ҖwAy%|ݩy&~Mzx%)ɾ㻋]ӞuGp}p-=fgGΕnGG~S2tf?Zy=HIU-U')MybkܵE[-B]ftNtYR B0_GpG#lAҀ.Up7_MapGpGpǼ 'GpGpG27)vLnpGpGpπD$ YC+BjAW^LFF l:rS vGpGȤRx<f^>R d3B C_R: pX4:ZZ@f̺5CQN_G~XR^cPS1Z%v%H&XI}MZ>DXML+i6}q11"0_ ǭjJH*\֖:z߂{-2 i,cW``'#bYB(Ҏ Àn lhD% {pGpG8͕r|BInѮ8]Q!D9^E3KF-3m ypNw(^.<5O)6˦bU&EB~TT ^A/e͚4yc Sw#gӬ4AAc #S!Q0#w(-QC FtheވVzOb+ bȴC#GpGp1@2@g48쒥C҄C'$UVcHjqFJoAǬH)e[?J ̩F"d$VnC" LDc-jGD ݚ !!@|My`uB.ئH~!*tHĜ5.2ԅ<)6:=G!˩U2e*R%Lf"^{45=8#8#8`d@(9Du2E WbI 4h))a9#_o ml IDATHqVؒJ!W"iS0LIdZS :fXMtt6ّPObgA3~jΰPMQQMAFm.Ҙ3J.V6 6˷"6NPHh-*2X^#EBpGpG@3 x"o:"e3TĕOQQrFU$$ZO*i)7[;#IK *c*R[MBŸh^,, &*,umɗ fP7ڊ6"N:mxI!FE'!"[Ϡ^Pg/nmh/q5`9=+lMa2tXՠr&tp᠘J1P˃#8#81,bx* #.32c@dHS2:"FRQU,ԹahC˙d^Z…=(WY$ZmdtykEq-3 RnhH :E2 +@9Iԡ7H%TAVƕKms:bќ Sc"BkJhme~&ińqO:#8#dR'Ԥ$Rt#jerlHG\Sm PDq)Vpl@'2j.ڈ I|,Gy}$'YFٚQB6 "cd/Gu9:by|:NXKPBMuiPb2뗪`+@&ͨ)M@y=KD+TdEڂEsց@E:h6yGpGp[t>'T|Z+t$F4UŴiB5[>Uu͆&`qe )f2ׂpzڷBAcÔɢfAD7*$|4XU>űR)~ؒVҘ\sDXŐ$NgD Β"VAی ژ޽89GֵQ59!K!VҬGpGpo욌$NB>j RcB><N!A^e<\cʴ7suDpz> g0 D y)7f *W^cD.CcEc^ E[<],X$AD^Y֧M{ACMQ%N ]/*'q\Zd U[#8#8@aT+"b}A!e@<Suq`^&8tܳld5:FXja@D,.R:v!UˬGCS3:GU)xƃF̛@SL3/V+y&%?``XB][E!TҌXy4 L_A#:6b |h3(ԧ@ Xy~˰TU)pGpG`G3 F}IJ-Y %$p$XDGD$= $21i; v, e]~4 ńIj(,$fVdPnmCAG&KUF9PNmU2[Z eOf&) ճ>ђZ2@8 XGϧ 5`>'BP˰U~oi&*ypGpG`E@PwvSŰi8+b*;ʽ)g v/I-\NxdV'Fn!CQ{Vx4Mдݠ؀ǎ#8#8c``$F$5NB*1%ZTSANH@ج iDDY DZ6NlD"Bflb7Uc9;fj0X֨F~'MڡAZsGse#FúahgDXBKϣ-؃XƐYSwe a ZMWGpGpт*GD:I͓$B!YeJdI]/ҊĜ4*CΜ mڰzltpJ Җ.2-(:}d]7qPLecjy˘^_b(-RZ,ȴZIFCdȄrsLw@Jl:%kn&=:j7=SݵPGò;ǴTdvidJ8#8#p `3 J I4 G:ZbaoŶU/JdAuZh1;g˫`Tq $:Fzn4+h-&4(6 /F"% 1r#I)biC9*Ȥg #GXS#z15 -D2)˷kLjB ɪ̼iߧP)O=CQ5M (8<8#8#H)XdU 'ɣj#d$!yDM>YurlS@Fm/HУC q퐪Z;"kJR\ݍZ솒xi5M%Je:ZD{*D&qF쭍cG n- :#b2},M-餄z@`^p:ƌְJ~DuUHE7cđumZ }=vGpGFL$ (TRbO#ªV^:j@[b 0`x*oDfW/ZOkᢍecY+ (bM~Pg&(jԅ 잩B9;=G]} cty:N:NZҎGpGp ̀`!s$XqQh6Okd^,' +_%$)6dO۵CN E lՔ]ڲ>+mFN"MC֣BZ֍GI^ U1fCá9 iYU-1D g2 Y+>X#c0~?!H?=[avT/#8#8x8NpB*'>:>ki#8#8@FIb%4B*/BLd3<Ĵ$& Gg;PKhd&+:m^ց@LkHtAEUM-春X0g4[Qo*2#nP-*b `=GqC317cLԊQ6!SK+4 9us̴peWxrС=+s 4*Mxs<ك#8#8΀İe^y1ZFH\e, Q] DF&Y. !cP$ mH3Q/#@{'B;VP;VTc'ثXAY!o#|A{sM'ayUˮ2kl˰q}!H@.H. R`/5CτI g2_u5A9c 1AmH(zoPgtFFhcGpGpBI|dS10N$/ĊU)# I?qoΈIr(Ϧh5 ʴ> b-WmQPt\D*<")C r3u$x#~h&!85M[ zlYgFc:k)6")&ӶAEahYM3Ŷh2"~W(ǗC =vÃ#8#8: FFI2~t=وWC}%ںj:=1h, ebrA=f(h5\]jÑ0œH!qCKDb'pbͽ (H/N]::ndX YX0-ťTGOpx0MSNH 3cK:`H#f:v ;Y7~9bYYҵK6O`1:nC?ӴtL43!B>F"])W@#~ Rp]KA}~u#y{#ў}(S"]8#8#p@  1PȴkrLe$XgPȳ`ZI0V}(!4ŻslyZ3Bn_*?n$G 5|il۾0mq`QfubgU|(g6B9uBZD@IIU˰Q_g`DӾCY> =Dv&cr-1SgdOǐ6x/w,t<8#8#XGB Yʓ+% ɥIH+C#;/ߝOD]ZS1z8L1k#F!MuO':1SK 0=ksu6 q:W$:+˜?~Fi_B;&y pZ:Quq)\Ph8Fm3|>ƚf=y#OT/x=8#8#XZh$Rdx NH2qk,\)'ͳc5Ϊl՜{,֋M.|m^Q >b!qVcω΀=|y|d5dɩa1g߭etNi:]촟 3=Ufz1;oe$S=yiǢW&O}FV̾K;NśЇyN<-۰i\밹:#Kl E}"y;oEgm_~7:Vz>@+* ,uB c ˠ,D̋ j7/S'GaCNZ~ k D+ĶLv=Sm{̙ʣpMlx/q5M̞eߝNk/M<8#8[cu!$')-ө0,?%,O@()"!cV.DHɭfx B"O(9H~=eŲxj^Y _ʐA}11H>AlVt 틖(%,}V32h@oU{WL0 -]*%ekd1zb9P1% 'ö IDATiUIx?ԩ{vhevLFE2D ,3uBVQ%j;x)#Rh#jq޽#ܩVu$>Ywv@I#8#/"{m"-$ OĈ@<Ĥ1o ICŪO#6 yPb d7nʹa3/Ɂ񿈘KMN=ezB̆TUUI65Uš2D8[rĘ'i3d rȃtg@8'+VG{AXPc5!)jҦ,qʴTC*@lAgt,@Ҿ*駟Y0 2=i: /쀬YF֯I8Գ#8#?TĖN%H G cu&(庞?扦Y@IDjq$[c"9뛷1بS[ +SCr7|^>7?( -ԇֳGϲnTWdTG{űeY!GRKHHHHHHX`#!dW&.Q9 iJp}HY<3VS,Id#0@6 l\pvlz0SϽn3YCaŁۀƼo-Y:Sϻޮ EC,@A7DvyQ;~;^7Ix}yZscɎp-oCmc })VEVF*0Ԗ+Cu];ҴbBt > : xG|3 +Vػ6HNJ.0.к~ϗXJEՑJ>(AW^v{nU """""""EAMO@MwO*,dՓV1}],b(*hF(` e7s$6)&t14=r[ȩ N9Bwd\۲6\cN'TjX#S-BclE$S1V#` OA0 :9a+oC׶,3DFoob+*P8"wS/go&ϹYs}#|s֭m{eL7t;G`=z(շl^~il;ELO*mӧUVʓ)))))))T2lQ˕ 昉N&ƁF1{RVpM1''Roqz/U8b2^$X-(kА}b 蔊 0&sSseѦ1evgO84zrxyEͺݬ'50q޼pPH:WN2|6פH˺1rƢ0_aT9:K]1^z٫J']}kݺU+#:u[ n@G+T>w٘1/¯p_ZYil65Vǖ9f|GlȻ7O2E^b%]۶ֹsge]Я_|J]0aqSOc_~t,2ֱCxtʥeX <؞~i裩oVv!5> n1b h߾:Fku/E E E E E׎@||5JTC ﱕUž'R}{™҆鐦)Ek dS >;fj1مN4#x$(#䋅jХo a9Hmzy"|.XM# -&4]?yv7ct韮DF~A *cL_ɹ`e\ G_zyb"a6y}&RB ;"giѱ!\c;}?6hР {X;ߎ>:mf6|lLO>V_CoWƍ#<^~刪o6vyZfJ%d^}5;#u$5]ڥ 2>s;ST|A`>}lթZMS; bk[Qp(8پg&M*fʍVXamZkÖu,o)aSRRRRg>oGIcHC˲\R8í'ƅ;I$2Ueq{'')#S e yD9s'&lb%I3_aʠ -ǕC~GPiSYH q$jU>x#|-Td,|o܊T6m4T|+<+|,2ǚpW߾uԥ]}յb6}_׊+[\3"o}Kd1YI'L>Eza] <쵪Q2"'Bɡ@(ȫ";qj/cۂ婨 $XY.OuQڐ /V2kV1;9coeI?[q:pXxٯ߯eHbǕ#n/g|kiCN7oGA|81Ycs+L&v\9YdEl?hR-=;ξ<~{z z=vUWY9N:Hvv_6gtqlYg nE*m]eY.ШQ#nmSۀjۢ.ZEWO}v|m0~Feh뭷^zRK-U}cu,W¥4h\/vCoǕ.DC\HFcRo=ėJ1W[Ш=;]+^R]5h] *P(سy0 $jB?",>)äuMP–GWO }qug&sfAB ^3@ьƱ>ޔCO?I'f+?S ؞v\6/nrn_egF[6t0;d.sC>駟am} /G6^c͵lԩ٘ݧ;6b"4?,\o0|Ͷ[oU"^O駟x۵mkrsy:9M8믽Ztxd(7?_tms{K.ޤ"s:V1)))))8 p@2$PrYla%>w<-eE9 WgTDexfE.Gk8q.M .a^ :m[l1T)>('_F|cS#m̊Ҹr92o;vmYhwOJW">\KSRRRRuCBUH.1pQƟ (d$M8_Qbu0U]A$>_d|, '=R|^2[ ?"=x_ <2}cWQK,AF8.(ې~DO>Z齮1! G,l7gcG;?3P,|VL8* `ѿzzbMiRZ+ JoD\r7s%߲kF=YeɊHMOZ/]{幔\'W)pyΧsX ҝ'ӭ1I%}nL؜!B<Ü%,4P|PC sZ`aP xK!ǼUa> ZjLX,~96 Hm|ށ;ي;/+]۰݀޽[wҸ]+{: Dޖi|imT1UV+bܸ"V_/CMHHHH5#r&S$!uVG1 < ߷Ǭw8r7m3'@79>+4>Gۄ "&t1z/ԇcCԸ>3P΃Ƀ1C|gr(ބXT>A)UpF&e%F)abi 8dL:g*1ޖzzQA;ڗnzUy@4|cRH۶|S$+]K[9FU T}^:֫$gRRRR Tgn#%:Y9iIBBhޅQ-wJ҅s؋*@BDE~؈jth5x]i?J.E[Jq|/W!>,Gx d uZQV uG J7qӕp}2v@@@@@>|*3B#̄VBYJy<ᰟDQ%=Wx_Ի(I`OꮈʨIѯA0kNل"cBH&b G:)0PVD1A;ƀGDZGe~& FC' utpǧ & @xQ"<]3@-d4k˶F}K/}^V|[g~UӋFSЃw޽ ."/|{Ǻt٠7'-%{6ydtSUgYx/GMs{cܸ"6] u/H~0 aH&4Dp!48%bSe~)<ìq_ +L'}/ 4+}s$4H&e U*YP9p\A>81cSx=D 0 1B8ia%HLv|F(B矷7x#*zo$p*\{mј+ lq.?MQrC@6Uyx}ﭶ7ٴx"U:LJȻﹻ`ȑUЫRU\y4d6E E E E EJ,$l̓d ۱8F'`s OB&ScvDf'xM~Zc$9c lw>IY*:!-HБ˭ (s2iv>a@qC>f܄uI9NNCy׭p%8 DԘST!*(/PsP:+*TAQm4;mE |;5>-F\?[/l9W&MX3z} sO*wsζKEiSwU&;Cވx'l̘»Go֬}ywޠ==zt }G+DE z!+-6Ӻu"V>~Au]o ڵkGg0ߪ~ 7ft5ױ^&9""""PF(C8|54D戢` :+9”耦 O؉^/jB/ iyX{qoO^w~Nrxp#8~OzD ` =Fij` CY86x_H*!i̦F] \+%~V4fazQQ^tK~7z{=3]J1\!y=ewک [n*hgzcʇS-b2}w~HO?O9jt5gv]f,4Jx!`'\Iyq*p|1yh&XHc@#aJ+"G\$b\Ԩ)D:c 9oA38&CcF.Iaw",AA@{r9r% {r ~I Q4Wp1dޠ"JW=x T `F\Ђ{N|Cls/sb@ i81?b"D H]bԡCk@LR>(}o${Q2r-}E 9K]m޽{[&mڴٵ^gL :km6gn{l7L; IDATO}$b!C'Mdlmֺıc}o|Ki;&z5ױ^$9""""PGAMD$qD%R6x>񒋹K.'uĖ= {͖)M^s 9β6֦e2uƇ춻I]n}=;e Ͼιٞ~-auheg\ia>vr];|Mǟە7>l7E3,xKEc_Ósq cu[)@~ CbN$W(%_\BU>uiWpƯe*jz͹7Nj/p yK$WO1v 7uo=1YnnwDFǏB/sӎ;4[n*,߸j>}gUxq3*,^F\kįMzzԔ8{ck;|NO}@@@@)&LqwPИI'L@+ֈ^I,*=Ζ" SGq.YtO!x3k l-:dgꦇ?uY :4;7?sN˶컞VUڷPѪv{yYѧ^zc6X]4`_ιaAmzqyeU@ds!@d(\ȻBO% /ZL]! 1#F$"A@] ,:,T~Ȃ7 ^mr^=~WtZ䝮{VR#(˧q b]r*~^5xp⣒\9ꫯfW\q||Rֵ8W;Jo'/KĵkXV*>"_}u/H~,+ cOZ=W1 /XpoRWHz*.mcx y*kd76U@@v]' v`;vd!6i㥭6}fNx6>[{%v`+i_i͖񔟯zrLQ[M3cǍmN-5fqq?!`q#Y,HblGqޔ:U,E37F/r,bI\ WJ\]a2· dEH(Z(KmUUڶe]Z+m޽[rĽӆ ڴi]J*;ã>ReAr4j2n_ƍgr|ݵOr*8xp~^XE u'Hn,h e |V1ՙF+_cvG›}]|XuX wWkۦMu5>\z\@@@FbwN0}30;%THĭDE Qf %2j]3gR;gۓ(phxPlJ l`nE{{G֪ml>]{:–Xhj?ț[<.0ӿ;Z(3w혿lcG^7Tm="_ ? o{X5~b}*ԇ*'_^\#|@rCrn>(Ad>zϻckX| d(GeGo6xo>QSׄ)>Gd̉'P\g|]7~>E E E E E`~I>s{&LC ԋ2@9u@-[L=!'&jMn3l\~A t#ІmnG05L\wǓyۭ.'un/ˮR'-bi}-z?e {`};=mC/چ`6Zξt P#`nZqy8-IF64)*W27Ji ^ ^(3dBCyS1xÈb<D'h_-HyN)))))))) G`VDlaTѓK8@ f+m}DhizOY4 rˍ() ),9²-ZnOOyyM [f%mݺAeOfGz{RͿ ю>h+lަ~ d8QQei3ѧlSOeO<;μ.tFێ;t; vmM NɼX8"(e좉YLBtmW;gN65`I>0- NzhVݮtWxN$+~&90,$hЩH @")W Ɖ߳p` acV0P |&M.StЁ9ܠ.WD?ؒ.%Wn,۳nPgn,:`cy${伄P| #KAGP9rH^ z4Pʀu:75dPBDCse_P^8E#VpQUمUꠅГ.AquiX4:_b* X*-Ev!)}d"299E E E E E E E E`!ބTZ*DI[ncERkz ,ɌN7\s(&qz%J#[bBN-]崀&  ,Д5rHFHhe0 EJGN' {:9Mbx i8eEDsr9iQ3)))))))) z&t$Z`Yt# fORؑ BN,⇤iuPȇZ 'pL˔Q!9~~ ;TPhn!B.+p n`J_M>Ss I$R@$},Z\Er/GɉczŦN^J/(I:xY:G$i 7&fCB)€e>PQ-LC#({RH7`!~瓜I[#FY)fq"RB&w 3]Dݤ1@O\8^͓RRRRRRRR gz? uB~6#>qt#ɛ++ Aą4(G)`gt&ɩԛ'f^yl{{hؐ|R%K(p QK9'!}^QYv%ggلo/$m+/!%9[Owk$$Yu Ջ:CA4@!_\5LFJ/Gp llģhNN?x&oƽE&%Jc9`l[(giܱx`dłA3 #99 ]^~آv?V. -  ¡3BODQ)eWLl"?kP @XBh,(։b0$+Qq1;^@1ouZiEzCvŹ&;dvVh{;˯W@[,gZ5bfEŰk P;dɟzV{|f{7놫i.ۜ,_&uy@Hؤ6m-Omß+!6\ a@kֱzUkݲ{_g[࢓8iKU 룃xX#HpF2g """"""""`G'L[=+d[ EL6p깫X\< &,x^~Z"J6.=_qlï3f٨'i_W${va'߈w(j<]bb>ٓϿ-omdsVVb<szX돟k" α&-61|7mYmźּ'ܯIeL6 +*=\fO>>>nqv[O,_|c;}W Z`<;$G!1ddHbԕG_(<2A"{YE)xtNHHHHHHHXh"-XETBEı4&!dD9/ue㐉b,)#,1S  ĉ*( _}d,ѓ5Hh2]/4Q͖E2}Hd3 cʲC=elR۫\Wr"?7-7{nxZ6oE/h!;T 0bM5:%]#׆L# VP6蔨>dvWatIa:,@֨Se &+W`0Ie dC!#uyǘ"A%br Q(Ykl`[1ha3#hE8OlzF(";IWg[ o$()[q:YeU4h Dž In3S µ"BŊZE(0Y~e@6=tCs#Ȯԥ,$h+1?¨8"+\ Q&L;ń߄WѯزUJEtԘxҺ~u?o6qu1YvT/$N*J_ ͘2e[lmR7m63d aZ6#@{J]DrW|?@|1ΙSïμ"Ig)'"> .n <1޺T<]ЪGyLbs SRRRRRRRh j%!э,m̶0,-$2ʘ_*-):՘jSP#MY,'NOɛs.}w=qٮ&Lڞz~<$|?DxFA@FV1|<ξtMxcc}m໱-9WlG'Fbq5acWo395t\( x$qĞpU qL{$FE@¡ .} f{FžB[RRRRRRRR4XsgDB1S/NT przLHEᩐ*c$z/uY =ؙDsJؽL 7}Ϛ3 NGO/ ~ݧ Ω^8x'mYXPR)'%H>Ie@$$=6 s*6FN?N;/rY> Ԍ@Y8'IhlJL0(>O9E E E E E E E E`@#%SP[ff2)"qD](༱]l~z|(\T!'mΤx Oh"GWB d*iENN*Q# 8YJ[aVmN*B - *0N]@@@@@@@FX\cN<&{42Ju%Vu#&YRJ K%OJ)D?4*GS̩~/p yohujՆrŞԨ? 29,`h’<A5%h2^ B\-r;8:yLDC25C`Dy,hDu{ 8%ƞdz'"b@t idAQ1O %)ŹiQ8JıV)RAt\}fK-<5WA9 K;m]F ey =㒵H4 ŮXb/JP~78V*>LO^EJ(H^xJVKx7U= S6oaÇT<^{u&M4o9>ysr277"3?ͮ3{=7>4'Ks7|cwdƚk)?>N:_X"ӓ,4:;3!?J{#61 8BdD*Љ-n-zj9WVߥzA[mU5_;cϽj'H{49|3opr>$!Ƥd>61J_ae=FxI6C7t5?*Oz82;\A< ?f_=EJs|#ʉ`Zaglҽ! co1&8Ou1;@L"JCVd@H n%W&|ulI4DWyb/N#V[} kӶw__};Gⶁ|VZ=sV7SA mͬ#Va97gZ[VʪeJo{+/MV@3@3fh=p'pЕW5ZZlegy]3du괊ධZKzȻXӏnQ6x]nvʪ|UF6Yi޵9J^]^pUy@Ƅ_Yz8X@_zOǡmP#޿bE(8MD'yȟBxn>:Xk>d_}=ܳ-\cƼhg<;M7l7|֚Vob׿b[m JO")C> "eFs=gK.=XuC$|M6/sv۠K.vC>So}ߘ1csNLx_l8] uAtbذC,W(r6kw%|i7|0+^F<=#v}رc̳ٙ\g>ﷶmښkqmc+Sޟ<]?ɕWF_j*STAص]gUsg%#۫]r%:)&~v.A:thUrkUUW8,Ǘp n n%Lp\ 4u>7s, y$azc&^H$?Q!_ՈgbRiΙ_ݿKy7믽jw=RӹvmelJB<qPas2bȃ&w}(]DP鞆XGIn3oA/!< pLf<`-]|G:h7r};Y :NTnD))24h$".ބI"V=7}ׄ)7EY!oΠDh\ijLI ֚4i,U`mʡY֭3RM7+HmN#)@k ^zF~?\{QJz)|h+_܋195B6m2Bw\+}Gn;Sf'TAi׮]U~Jb#S6|ƾmvŃ_^Zvf-\hT*W 52D>U/I{Vb#q1i% Ne X2/Cvi3p3[Jz$4(ʎr8 HRd>HTWtm3ЋhrN̮x 'OLu3d3A|.ÄAjc!\ZxD^zim͊ߘEIqL_o- zto>1޼R c{˄ l-z<'l4y=3:k; ^ɓ'J+$7iRxĄ\KaCuCcrUA}:ĉ4F嗏e̻ zGa]mwMVYjt͛7Kmfs};lmvU!X66wO?-ykޕN.?µmk_?>T%o _ۙb1TjsKE]bRiΥ]5Vї9ɯu^bm_# I:'c8tQ|+` <'ǕOpJV)c͋V)**cobbXAIOGY?ܶ˜->zDWӌ)梄gG4d<݋*Ɩߴ GKeqK pc#x#{~e`y)SSlcǟp>@+M/j;Xt,}lRsJo]lks<΂iEEBnllժ6zτYa}w.1ᖊ]GyT[ȸ]gQ^^jK9`ugX]v؈cmuޔqk W}QcMQ<ɓo'rJѼwۭȵSyV/-L.[_lU9TOMr-Āum:s>?K> 觟~8Le %@Wu׺DD ]bRiw7:?YXlݶ*BSTe5Ǚ.-d~Y=dXs3aOI,Gf猇v^${+| E EHb 6sT$P2_2,(l\\?$˛KnhKkё)H`ALI* =*TXh+_H:Pw37faq,Pr#DBCfB|o-G۟q?G"b3.7:?;7淿`;XN-@·-5Vnݺ*yx${-6~UƼ1tޠ| "O:IJ" 1kmۭd'| c]YO1&=n8z2lN<d#}9wl]“V/5 r>p]<.zpVUXr+~o:*~r}(WɟJ-%kΟ_u#߈_3u^nE !ۑB4BuʿOZ a L<O-9#AWHUeCF8hs|)ҢPHJJ]bD`RBR!ʸMD@GPUPIr+ 5,xqK/!n`BL9Ɔ =|zwӪnՙ n`x?.z^ϩ3Q)vuVMG֟k1=S|(f>2CX A&0 3k# $%]C<`țuAR/Ӿxvo p)Ѣlj>{ ;D8T0Y񑓑(Tʋ1g$^?h#^BQa y*>$KEAt) ,pSRRL5Jn?n#uZ5n_@;;ʄ7n$+ kjSXGmJŘGk0BD>!M,mE3ۃ`ڥ[ˇbCv cvӖP@㨎<3ζ_t`ʸ_%EB.&S,Pp{K3hbs*^_ /,BPVu&=]̺:#D$~{RIp>`}'zk{$deY c$>"*0JBhĩ&5B7.;z1bemm5ٙ'e-W\t6P]>XdvG[z)܄~X,i殃N>nnGLHa듸=6SΘː|DFQ$G'^<*2V5(k"nh^ B H(%7 /ǂ2f|'O7oԛ‘Z#řˮM螈29dvyPrq􌰟 $p.AXҐD0Fx%"; $Z]?TqcC/-w`~y-l٥ST4&myTMqߛкU3ui@|L"z1Qn;G|*~t߉uD&ap;WEqREQL&&9GpI|Ԏ8J;&y`'|l=7~Fw_hr~Rkpd&^ {핧)h7 >ڵYڶn&gmABvv3{+;ܞyJxzK/EK "|&|Цz=1";`0ECLI"@Ax.Û!XBJN<"⢰2""b8_yr4gN,43?DB-51e/cRɄY h` [4/v,,вG,q&lyA\,FHI=﹘i[4|a9EGG3y9ִɲ{اӾ.bw=vغkuO}w]l6ƌ[x6VpѾ66a҇ ;aX{1vmغkwu|k#+Ua~Sp54{LZljW^wVPP[?e ~8Ⱦ{E<T6T6Zi$2bE!F&RS A.B![8U'.+\,T3s@@@@@@@߂ŌogcN>V[&Dc~WhL;M04zpoF$ό3%~Fcm-"|Z޻5Wk}zБO]bu  G#`%,@p$R$Sz pR?ZE`Ap %.̲)M= _w[wSN뷗5oW2uMz7xkբ_̭ IDATyE'~aik;j 6G4ئ\a.kMʀqxʵx7 iv1{/3N</,]orۂ-7Tp}1~񾏰![.T:o.ĎQ(n|j?$_>5T_95""ag$ԛL8s(rl81-jRٹ XᥞʀW={Qoog]fYs<딣b%`QC(3, ԏ k~6Io{"llmdl{Y3{iN>xPݷ=ƽ-pkrKlh'ӭtiMFIՓ%0N+;?<Ӷpv!K+^go5½(,` EzʕΓbH-*dPDgJpf\4gF̀˸,4qomCvޥM0oծ9W>_o>XO}T0׺,>էO?'[gunפÉOI⛴ٚ6mj.:}r9B*Zanc}/"Y QGq $͢S1` 1 mp7ϾDivݥ<˖Ċk~O⁇nkC.gжfl'}/;ؽm ggikT;ۇ=*=w;d{m]Ue6jdOv`Tr㽒a?ӭ`-4}1IC}\}=+v&OQ@^:Ş"ᐣ8r-rZ @.` GKKKFbUxqDٸFY׮]C6< .:ִيk-ΡCO;ڴmg+`'tYl\lۼض[VYu5-{oeW\om/qPh  l[im*Qݸ_aam!-[cg?֧RůtA~9ϿV_cM]]c=dLN8D;2w}g-ZW_{MJsBq@k;y/T}V~\]#9G6財дvÍ7fJ!?SW^9X2ge b:pZ+ PW [ncv8^$vb\I4|Xu}ϦM/[Slj@޷i*ũeggNQ?\EUuJsJ ҪIzl5}"_>5M^ mU]9E=O@FɠLY|Uxy3EQqRo]nK~ГI%Mx"% xخo?"ƶiéEW WvXKQ,mN{YZvuv w&LZnܢX -?3ѓN}}:9?tq_?]WO:0|} "T.T3YE϶eI&LL9ɩϡ* UᡪK:ow~Q;2/519NdGTrdaCA/e`DT4}KKs?p> ҕD 67+lTk=.W2ShHs, ,$.-*D 玗A)_9A H)KRP,LFph2æ0KshǏl?^l}mn70V^ye[guc5&.2Ğ{ړOYdA̭Z(ZN-B<vwA7>;Mwh?c8s9ϿL[p쮩3E}5~>;ۚk/}Xq\O wq}&xfO6vsЎ=gg~"63mwMi pEC &!"9N̒Go9b‰N$,d9 *PԊ|X*9q˞߈w] S|%ؕVdćN5^nZ!CM#G /l&e7|zvc[nQŖ0loNwqq۟r-W ǘ*nL}Wa]6!Ə>kUpVYe2|gm]z*el=)wsܰaRqo3^܉ַK W\qEoϫOl /Ls~{R~Ĉ9T!$.bq {˿Q a0m41|x!qܞFom󘟩pJĚ,Ns[秷fg3ѹsp ؕ;nvԛʫ FC9dIHVvvA8H?h,>G:qZr$#9jYVpTҊP9B݆Fwr!z1#I*BXR 9,uqHyL8E<џN_+9_5;hV3^n゚SowRD5=aT|O;v{6?紷c~zésXSٝm}GO6;cs)\ x:]l\>[]+Ue+Ld퉰L[d9%9e6MX;e^4J,O1AQAOYQHEKiS$I CP֖HbNٖXhCG8\|L2%5ױnPQ/ddI#M=cZ-o'cN9sJ0/SxX-]rоBwNhze>7vYϠ#p]8g}nv\~B mÏkģ# rZެޝMk?م^h.Z1 Fz~kǧ;NLGl]{%>n_:(kx2ѣGWr6`x1qcvnrm}YW_cqvj[_v;|QX:\4ݺBym2ޟrQGm2M&vN_7WwW|{gkm}}&z|oNٜG;q< Auwӭ *ZI(\0 ;ӕ`2FԒ~1Upp߮suB u܉'#T#|w*G&p0`r?cpJN8e :tJq]4J[i2||{F a! ER|bV6nmI ~JB:jI1o*G@wF 9/vko=j4n>u_uFn&ir $ݶ9}<ͪ馛B\l뭷b'Fo^_뮻y2;1q8䐃u?xg{챻;:N#b]! %&~L܄~TW9x' ?l>.7;s"~cN8z!<6u |ڜa=sU*WU&gڪcL8eB oCL6R3~D("U“"A(\S q,fi6|1)(uBKKO9xBc`]*(XhsN R)ݵ)X8q8bKőU)?&dzxcgAV49qL_ Ǵ쳏֥; m?($x#<' |9 IΓ."0#0ȓXg&ً̬:&ܽ*򥤝7)=yGWd<]$-< 3`2)<+K|HT`!%xAʡŁ,IQD3rC%<'!dn%1>`{lEsy :/o$v㰋.mw9 ds|XVx,#_T%` Z\6^Z3dSiTs@/q"S@Q3)>1tNyYupyS("9LvUX@b— /C5h)Iܛxᴽk@' ТZQ.A1ULj|h"I3'V)=yω\NX6de,:NǯPl謧/ hbP8cA/H#)U[E"PT*< e{ʨGrʄQӘA<ńߡTɽD<b@_}ȿ|(_U2v2T Ajʲ譐0L9ˎ-Lԥ?%K1}ډK,ր79-w)[ΣQ,$Ja^rh4z`ZsNŘ"@}/kZ=T*@E"P,O2KIF4'MwB|ʃ(:HFsNkL7*+SUZv]Z!Q6RC(/VQ%,p$ObNE `I7H#_0q!z.CbU6_)\c)$S.zu=?,>"~Л˴~Enh9{^ ?t[Ui@E"PT*w4_-:SAֻH" f6c/<yWLB5 B"u Im cL~_o\uIw:}* Spꃧ!eYHdN.C|af&14H58)dF7t-]$,>l1f,\Pn='RO/ 1tNYv2k_T*@E"0W#L9Ȅ1 1d]W;pN4# Dr>wgb2Z79CTcTڏ)#9{^$/ZbZ.@Ӱ9P9-H1)i !co Mˉ5ɍD@ZtbQ'55Pb(pOcq򥾀`P-sp s`(Jdcﵖy-9W^x^M龒^ ,zG-UnE"Px#٠J[c3,=J6:X|$RpLȓ7HA+m9ʩ̷Y$g )ư=FFs Z'ͮL140i\GX7C!ɗsRiaI[L=/srcΌu*" xlJTN@=g&YdJ=ƙd+t,̜6udZ7y{J(&;*oy"v~pT<4KŪ9-x^s>_u\T^ Rr^Hd& eFY<2Me$Q '.MIy.r-0y[ hD0?5u(bP$5Nft[i@E@ LgMLU0HIS>\.ٮIeיdYLC*Uc_v7׍i>eom7^Uip`AwL[slՕGRl3G֖.KλE6/A@VN1)別vյ&H m7vZKY{* bܔS~U)H~)6:2Bh¹xdF>qc_xƙgٷsHȟ{.^zI"|@?az7Wٸq줓N.]phرvm7nF{lX|[mesQcbkU"3ΰ?';3!S ફkڮr;1c:E̹N6d뜓.7b;\;ÎGxhw;?0}k~ۭƍ_+ָŨQ֟sM}j6l=<[g}S!~.N9ŋ4=:_Zוw գ>&}5ӹ]LsT][wk.Nut§S+g,<<3sȼ%!l<%{tBg}ЯO۾}>s7|~qMRomqP# Pf%?pزCr җX*%^E MJC5\4tY% 1#O{yߑ֣_ . ^ &1v\xFq&E}fUWMUVY˼?ژ?ٺ&漷'!CD^ٛ6ovhcTχNեnm?Akwb?gܬۻ .BiӦو G*tӹ|Ĕvm=%G^_+/#ؔ5̑ńgpITsݎTNK -ؤ٦yҪݐ c0޽'덴zMy;>n!Ap-3c]?Mzaƹ?we'lrK+-g7G[v!v"b-6]NҞ엗lg _6nhm Y!FSP$"A`16y[h펻' F 뭾}كӞSϾi6mM[xd`* ; uɐsG!}N wM^72} _6&{rMZ&W^i'NV[MzEȖ[xKsկ~nFw|',m{ˠOOv񥿷%U=ݏ=>w=Kņ. ؇F̧1Oh/qwk:ac'ϝi8,)h713zl+j~}[Kim% /AE91ޥРU]}Dh(ANz9rpoZ7,,?vinŨ-7|zodⲖe]Vo*rU;!3.[GkVtM6zN>C9ˣUQ~o?{5:[9t}O_f;/ !{~r/ַMO}?皶gwO1%}O|޽,lyimݎzNHv}O}heEx >^-&+?^{^WfE"P?B` /*17@^gc6HN2mUej+X;/ Ҍ%l ?=vzb7OY{%@=du%x'ong#QL4lKRYoK?.K{/g0G/j/4_zEmIJqǷEE/p^r?_Iİ|Ek4:mIEpzϛ^smAOsO7]e*ޱ5*A ak%digDӭ(ՄzEL{ 8HX9Xr3ڤɏv:7iv?mluw?.9x[gwF[k'O%,fwn{䯗ISmev6ٶ?e o>[qey7T>qtWlݵVӈa-9t=}6f?{O4dD5[aR6lGg{Tvs{ y[+NAEO9GN(YMdKB[δISCΓG'7a<8ݶCwvϯ_a{$^<%t 需F%KbgL7Z9Ε^ʹ;.kz"PxuH@|1kr3^+@E" 0ȓHX@<8IUc<9g&Qzڒ,)+aI:LcjiEsIr V;# +,E\@#M~pmŻ9-%Сۮ;.}^}C޻6}ٱ'm~?bp+i=hw3,v&qYo?1M#s ,`]w%\>яQKjT*6"RZ1RZHF?oAԑGi!rh m(EJ9&.O7/ 3p'~&|+ǎE#ғ`KA!1&ˤ+yRA#{|l'heT*ɹ@3&+.m,Xh."tB ďoc]1F|>I$Wˈ:qu?Ob<җ-0BmS>SQ_@E"PT*B*ȳX9E4>1WODI HIf$ňlQɧ]}OJ¤O_)Ib"$c\'& vVBaU5eHTLF *>:$gQ>QГRa) !HWsei y ٹD4bVzT*@E"Pd $R&<2 %Ոɤ[C@=U w8zZ{J~RѮZ֒b"[Dn ֪~)^pʐb*xYv=X깔s=GhGI<5t4wV $zk l)M)ޤ/sa]~վ"PT*@E`@`V5&T4Y&. Y*(Ǽ$zTp>}PӏNQlxs[`FurhT2il8\qZ⤨̖i a(žƻϝ1jaItZ"%i "ْy;)>C YlЍ^pݙD XATE'c,4.43RzɥCjVT*@E"0o!0II&H1 D 2%CzHwbۃ(4.LޔN58 Y }=fBП E(J8s6HcgA"PT*@E"0!&L9`^O&7BP@FTW灼lT =)|qzKiq8s| ^4;:ChOKB`(}QRȶu"PT*@E`nG`MH6Ȁs$#z=,|g(IP LƑ‘lAqO#,"„ҧC/{a@.칬=8jz$+ c7 >w=Ior`%tWkX[t{Ū_Pp6 z`܁,[ؕA@쐨ӢIS@E"PT*y ]Ejlk^PɩH3%/I-UzP}(vƐ$ #1RYt翾C#VRM]RQcb@B$"R^|D Ja8?tr>Å t|Wך/ oxpK"i?f *xtiK9(V(H1O2EO$L .|,6lmucE"PT*\.b$`e3QDdȞI*[!+b /I{ 6xK )ܚ++y%ɇOrS&10) ɖ4C!GjQ8#Td@E"PT*" o> QT!$R%z%, Zf&FI[gB}@:d6@Z4(G>fC!-Zpy}[?EeD!`yOo8ׯsLU RHOX(7W- ;>k:F>s#iŧ}ՕC81Q8["+ ? 9}E"PT*@z$PWcON'ȀU5SJAR! R@$=Ř󙯠&)"HiUdB6=2E,bҜtv^ޣ*;1cr,uH"G=sDEh/B_:.(<3#9ӑ2Nr2:7d;"K:w{w-'eX·xm@E"PT* D/8rY&lJ\1ԑGpHT≫!Ą|WVB+z1 f^*r4f2KK, (NA46i#rfs4tC.`Nc1'l6m[a2*ۇ,RU6:dSʇHe3v?hvasZ=(y׿_o}R{g2^st$3}{}VmC۶L{ͩfnjh|j,$+p.ckP$"PT*@E`F`yr_0V\0qbzvos~r+]P/z W'B#>kόS1V[E"PT* &lLv愢c7$-Fvt"1J(l;mч,p'lO)⋽Ŏ:dkb.byw}vڤ).ZS^naw[mÏٮ;nf|#El]r7WsEUV7Ӟy߸;jٽ7~Ϧ=/ۑm򞑶[b|w_mڔO1c} ;޿[Xܦ=}WVO2>=sHcl'gamlՇۧ>/.k>[fEm _mϿ.z`}}Gy3όAJ铀9v=Wy}\.[jBiCE"PT*v@x\$ 2lH&ݿ\+3_8Ts(4J2).ƫf_|wؘ>m۾=v?م-Pqhc1R:dq;нlOۖo'9{gˮCᲖ [f3Rﴇ=5GhOgLf?>8$;%,Nn\,@nζﴡcg_5FIߥ{ knn9r K-(V 6eSvKbeq\^~wS q6/%Q/sW5_`l}ζQ|~3u_w}vIv|4nbc . e' G9w:/@̗D;?#kT*@E"P1;loQ$dS[_SG\ P)I %3Aݝ% Iw8:8C3fw_HAxlS?vAr~ȣ Or&<ɟ:mM(0]GpIղKlj .Z{m&Cag_~n[qe{mo=S-ojOrQ }hK/dg{$PE!CR\U<,(wyAl}h=:dĦ+@E"PTn; ^dx"-K&~~2)-Q'| 2@^b]fR!=s(Chv'V#y=K Yn<d *7VZq 쎻bC/jK]<˸jd-,f&{oa_Ǟ?qwnۨNGxx;} 8e;Y~%P@H<ŢpBӾEq2z,yt3rCppNvԘDD]s,CE"PT*<v@2l%FhJfqĒOa̛Y`MM'^e$ބ&4%: My1{5TgbK ymG)¤ywjw~|O[x7ݟ7 N6mMtOpg0.8e v˯_chwW][e|Er bRP|sSzԇҫqvVW!t/oV(t -:dԎb{SRtJ9㹜b*@E"PTz*9d2rLv "$9 _:K38]<#%Je)'S}PC9iǜcöfe_;gsRezQGwuvaSm4\&%k@p?5]N~U{MvDH[\'pݔl%bGō]z=B[xqV!vWOX|OOb e`O~a`79?v?vX>ǜoFGqArٷRI&8;g#^x(`iKT*@E"P (_C=ބb 3 BV=ЕU=#ozӶ4s@v&eI]Sm{@1 .J:R{._- hLqNW͢GrsV~:EAy1D )֦HZj2Jz(9Є;ǐ1w 86# i_$ ]ps9 Bv~:4zOpkT*@E"PW>VD )`dG/E/5P$(D[:b8`W >;O$3dB6̸^!(&c&-usWs uaA>YSA6VZ~9T Ut5TDTErHR4Z rnڨ}E"PT*Ëe*&s21V4r(..6hv?@4Ht #8zHY4  =8AאB;H~9·H.d7 z飄GzTtBYK=&9%6Vtx68\'%IЊYY0͋!VT*@E"0O!L$c4DfHyiϊ"LoJ[&|U%`C_{"yUr]Ə/yr{nJ&ǔk LgZ %rzzjU&6#dG Fc9 %|-B "*I>iы9'-F8eNBXb5>%KC\!= *@E"PT=d> O5\&%,]iHD{≤I(d))'nKr(>/3E5KCjAcFzX|x<&u}X ,QİW BCjnוu-H]jͦqN4+ *2./H`JMbcHUP}4GFOOX̳KEHe|JbP[E"PT*<$lL62ݙ:L6Z|"],hBL0c/oTȨ"PT*@E`@@`ͺNO3Gu>LHDb#[ G73O%i dp٩1Dޘw5C]GO~1"+@K#iJ ΑsDfR^RɈ5(ݳw8 9JDsS(A\;SP|ɹN8# At>r vHJSshס* +qʊ#yDq <@l }4lnMK.]]Ҟ֍cZd" |=&D|}MQNImn~)f$qer8ϗ[_[C3<'P48t(O&w}jT*@E"P, '*ODd՛HrDq:RaF#7N>QR8ʤiGx͹&+`N`i5|:T*@E"PWZ(/LKZ1̔I^DW('*ydmSL y:%L940ʳ"B/o]z%K7|艣7N).]4]@u$YD/ˑvl :No'NeE}Al^8r ΁ UUZj<C2ܶ|n/)h asyr^'vX0>&")CE"PT*< <o4etM=y ECjL<6sO\ )IRLe7yEIG Ӟp1wǴ76BAIqá$614is-2)AjJ$A*dgU'. ߌd &lcEĤI$Eps$Ӥp!8 ASXc7R@E"PT*s9|Ci?u$̊ku$}I7G^M=j1Tt[HӊB3Ozi5x=k$ޓO!s L}eo dʳ9WGRH.\a'QA [POvY28,@BSR:vx? NA#]E5,մo{/u|*@E"PTj=m- 23M}ȑh$iwv>ҏX|&2fuE,Kw+YIɣcXV2beAfyay×@ѹ!7Gy1#/Y]T ɂ3 2dHչIO)h9 b"@4;r@/Y&r$Ҽl,JT*@E"P{z:ɔsH [I,JLH/"ٓV^:f!wtOJO:ڳe)$Ɯ26/i1fLC5ץ{[ 3'YYl1*J ;H~=p˷ \,fx!cRݰGcuxo^UIYHKI/uPT*@E"0#ēL3u,*qVTf›z %i,鄜 4ÔdAD!ZNkRS!ۀU '4Z#%%:7TGIJK<쪌).'lF Lɘv|i?d#.Km *B"PT*@E`G1TAEK)iuBB8R8Y8pO1gΪ!mIAtC=u3 aF6]0r9&M*Β^QaPD"g#~WLy^#crɞ44ꡱ 4%j&E ܅uR=V*@E"PK2/U&cI  OV2qeҙ.OTwXVIh:ҎdYN\UPdR@K>RlE1`(B(-A%rQ HQ15tH2ଡA*9qB;)]4 C rQ,YU D׉1:^rxлGvysH]E"PT*<,7wL-+D)9m/w=̔h~X5l(;_N"&"fދa']b2qFbe75|<wZxrĘ4_FiCQ(F&j4-z[ls&z>XZ4֜Teq} m24FjC.]9Y)nNΣTm@E"PT*;Feyhޤm@V:-+V[R+!ep ZsČ#fDO8H х骴H$es ]9X3x3:Uq/}02qВ@(sH2PQma#Z“<7&z%sf]wwh'7>9am[THzIHz*@E"PT 1Qe2iHIlzҒŁi{uEͩm9YoZqirgLQZo }G'3O9D**8|Ssw#AB=MFIL1. ca,:8Nie1&<)G%¢>˳- ij7ɧVsjRm:T*@E"P[cx=-t0Ky;P1uFJ&B.>xHq.[v EҌsA8Z5uK.-l(XAY |eBv =#$7XF>)!׈?%n1WĘv ,xmvPR|T93奈UUH+@E"PTb:3VILKꈉ omU޷[vLLíI*%A%Ӧ5RRknȧDP U|U% | J !q\ pƲN{1{{cw9cαχg^҆7FZxo`;S, I.Xw|U\>-#:2.͞W[o سY ;>޿bCɜ&d`20 LnL\4ܵ&'Lk,3DlN Ŧ9`Hj[cg! \/[vn'漒VD1$\!&kxȌ^bZၫ#mX{f !r)&|AqQI\TWs4dvlogH(ڦgKV[>1'%@h20 L&d̀ QO1aSb"%[: l2&10-[۔SQ|Ը֔-Ȭw,l u_6q ċ_G=W)QԥɶN#c-;5X()]klܹ8ͪ{1{p! [o^͹,?>=V{]Ӓ'd`20 LnBgxEwM:u'ΈYF2XAe-zliǀjlBc]mP0Kӵ (L-w;H3^vB*(Bѱfpd`20 L&7 ~aАVm2l;VflI.2?Jgj$9G?q!:L} ##X6)b"r`?kU ,8l^Xt5?˜+m?~93r!%HҎ q=b[Kç>ѨxXN.-d7T]S0p3Vü8#L%-imW,?>ew>< L&d`2g@joC)}NPRpGB8#- *2j@#]Kcv DstzpXbKR[>,`\kE*{iL<3֡--c< $\j,B" W8.(yVWJ4Z6: 6 Næj^ݶ0 !l{d`20 L&@~VE uy\W*$ٸ]Χ3Cǟz}opq$8z)~|*Y r[,ܾZƥմ^+WCMh[|`ºK /PGTpzQ'zb uhՀbPF_s#k[Ii ҲC2 K5G_y>d`20 L&="Ri Ը.)! 5b#|+.4i(:\,-X ɷff+@a046c.>zH 6GEp[~)kn}q .JO+Vy^FV KzB^i5 ]X*͉C@}M&d`20 <HrOɆ釆F-Ĕp|߭!!LfI pa9G}E,#;N4( j}XQ]]/CTc {s .bx VrY {c|XDiy_zl-_ɁDߌiPz_^&؜'d`20 L s4Ȟ:h !$r,)=.}=& 2Yj,<н9:\bkmc-/!-=0Mq]Fc0nc0:( oL×:Z2)AO)2V6+׵5ņ&,#1ehR0Ju1HStt co,t5m20 L&d&d,qiXefz 8dTi/ϐH+i^BьtdHGS”W,3d(@;` 7>~~1FY]_ ־<B*id`20 L&MBM, ^h.JȢMBEB<#ƻ0 hV:慌qws IDAT>Ǧ+C/Փĸ\zo:C$͒L2kYaVʰ5+ |=v.Ԙ"7uCGOћZ#jg+Dk -W87)%#P_ A >fzpd`20 L&ˀ- %cQ$"CB31,_!we{7_zN5/Ld,%^J@3}kJĶ@cR/ ވ`F4\ypvjAkkLѳäik^2Eca2׃W x C(|*?k x߻/y20 L&dd W@S44h 'D[ k|;@}8C|8(?򍿭GΠP+ ZVޗYz/ip$ hm+cS F? .Z`!-~{#fVEp(\ [$\)[rΘ`cd`20 L&MɰvNun`xqC XnBi>jZ 舫L5[VU'eCԾi@O=K_AXZ&/7qɸb+k_.ګ3$C9Uۆ:=cXG:tΖOs!alEs՞%RI]8d`20 L&M@44Q}K4WVӂ mK4>@Cl}BMDXE٥[dg^!+3M%n3q1f-3i_m UKB#Sކ> ξyX6GhϘܳ$-}%@ a'1O&d`20 ܔ Qj8|Мy>+_Q`hTU2 v=;6~]Bcigq;ި5Հq=Cj }VgVi'Lm4^ =.id`20 L&7%yDTGF}E&|"gr{;L1$VuQkEmC0WN:l!3i^Ș)z6IZL^x|ī.,08k?#j%Gf@oE`61~F?mq&9kűͯ5/8ElUYF|mVi20 L&d!mJ N UAHLXh104PR XH b#ڼ E?֫hV : /! ˾"{LBe2%J}pu-@՗<3׊%"m{Vs-X)a;vvM)%Vزed`20 L& ɀP6"B_=@RЙg@ͷIYSIܤ` D ~#)f.-In9tYHM)S0Fˌޛ8d}gg@qвw^+7Ć $w`œuq uFwYG!i6%^I969ER=n!?A hqT(eR୩T/-fA8=[5NօkTG݂$!#޾(~r.ϩjjrHHV*Hۨ-=JZmwdrmRx2N72G&jd<r؟*J4v7Hci-td`20 L&7 *@Kr@kE݉p1頶 u)-O \}k-Q)#9sk,ÛKמNaLī;v;#6B9^cf)P3j&Nd~]}X'=CvoN Z 63RcJՎ񶻥d`20 L&ȀB)H76w4K Uܨk8 QK& MRiE1YSQyB3 Vr߳[NX+9.cj-^p-mm'AG5B/N_,(i(a1 ֕** F=rϴd`20 L&WLMkʢgy`Y;O.crv=@Pr%~:c$9~"Ҷr!ct3E'W* c ES5bJKc9WDΎ{;ζLI}a Y;m ^iGȭ a.pShP()#;m20 L&d&d@`M~MAMC7ч<7hVt Q[+$OT8 # 5(]#) }HZl',(>ј؊V} -3 zMYn'=j]0]p&)'+ūM{!&d`20 L 46s& 4*#f tr+$L4m. (*jIs[4ّG$Y2_kPkuqw(\ez֒1eO&d`20 <p) melT-zn E~-k꣜,U*Zw=|;,V2ַ3\!-g˗p>ёMWߓ٥NgmCtj dU-Fg tЕ2Gv #ig8CC벍ᥬ L&d`20x3PkA>/poAJ&GCYO"썑eH$w|- ƶyn"ʿ46s6e/9֕R 8{]ihzt.H04P4p%"69R`hͷj狙d`20 L&C /2lpq"~U{?,=,ˬ)j*m)x;?m;hQ..);mQRے E sggvg ngiZns4k5IZX>OZhkT4k%Y]g7.ׇewdM&d`20 ܔ ־}]M7t7v0=:y2c/R5"';>aΞ,B|9V(56泑,vas|[ثpH=8[V}\&d`20 L c !!mt Ƽe)3Zg8Ipny -I mBl 0!8-ͬǭÆc?$N ֘)ztSWUA~ein*gu {Yj2=Z35MΤf6 L&d`2Pf@`|B6#96RF6l/REN=O1v4E\=ր>˚jJW\ :r\Guzc*N_hC[z;񈆒V6@x~$XFsݫŻN|[4ͳL$bӈߢ-CiܬO&d`20 ܔ !tEA!Νa8*; o ٮRT+r[qzmǬqugkYW^,^"Z#-: :yK+ٔ G;''~G5p=jֲ_|.뽍*d/R8V혱apAeqqΓd`20 L&7!y:uc ̸7DRnD P3%VM2a5^c%urXN_Y (-k!g4ʐY[p=+i[lZEy\=Ga?o5"׈ g,?2pm(ͤ,0K L&d`20x3ļp'M3is,E!ې:6Cփ!UiVo]oz"dgˏ'X[MC0O]]Ir%B(ǓiZB|/E1{[b%x4?h- *^VS{tETqgΖBZl_s L&d`20x3( L(M~dJGkZ BiZk AdJ*YMPd?>iL^eNŨ2[X@vz, Ve'5P(YlR9Qu "YW'ȥ}B>$R`:Ō\AʲѩE#) "'(9O&d`20 ܐ <ylҸz̷p%Dҩ9ܷ,V@`" YaS  =#\:X5_HhD5Wg 凗7XB'iծ0ˉu0C}8 z{ vc?zˑl󌮌, !Ӱ'ڶxkDz*td`20 L&7!C2w_H/ 5\T&d`20 LnZ+X޴!,/oo8[967FԭdVH u vSt4@äe,aX(YQz?jϏ5=Ԥݶa?49;=2Y2k ,'n!ff\HۮbPvJf4r3$u0\أXW/g: L&d{#ۿ{whӊ/ל>q?y/xggM{2[Ω E(M5{\ #bc]n&a%-܁ݳ0WN#@G_Ags0.&lj[6=z?-5P!K<82TrY{ÛӵG )PBD֞0v6vkM\)/*<3\`20 L&2_ӏzz=*>ok[moy+y/:}g]58{>M/ZC3F3)I„x@ڼ v8' @1'I!:SKuFdgaJԮ+xr)<e9CPhm=܅v* W[Cϻ)ߍqLln]9Y, v8bmS<ſM@3c^|?^ L&d`2pwN?szNjո"7L1rȿS{CrZJsK8TRkE@<8@ĵp#0~Vʍ3_dj-LaKJWm6,2-VۢlB;8[f,"[$=ds2iO]2t.+[>%o*pmkO?V!"͏L7 L&dB]떪{NoW1-[^ bg2TQ$QW(>wZe&] omLWbu|nwb=Djswl)VGIqd։C{p֤־|^DOk2R5\q$bX2й,c3K|iFCs L&dff+<}z㹲~߉l} IDATۿOM!\ ܶɢC5w Ka\(;7-U1Fa,:?;\TZ"Yx1=ׅҋD (s<(Z0*] MKz%#NkJs;ʠg*^1`vǬ[bJm~f8 L&rN_ϊs"wJ5BL"IՃJjb -u.o(ix;&:}\y97v\ N:<{As0K'l[=_fz6LR]e e-K2θ ȀsUͮjm^G_͢'O ַ\MZ'q8m20 L&3_I0;"R^Kum$o22za-y%md0"&}Xkb]nbp%6a1n+<:ľ:3-o-Fl"vk.RD->Zۺγ<8%e=l_IzI,2vEZAva=lK*ǟ_5_ V*nF? WWYN;Z+5aqӓn|vz~=gwՌ &aM`6H{ġEo &g:~Ǜb`\%fT(΢AT=3FV[E$k8@Ǧ1 \Ap 2FÞe Yy^>j6xd+U4ԫf㎜k3 L&dCw׼/}Bݞ'O_:~G/Aj7WMGTNl[s4oք79E1Rx;srE`w%GAu"l)Gx%cn-[?du!]Ԗ)."Ǜ-=åO >jnCy%R ]dhhص*(tp"33'>$yS:Ʋ90[FC qnd`20 L p~>l/ӿo>?O9?es:鋿ts!/o[K\ \ߖF7k+DyV$p/7èc[ZƦ{},Cָ qs":*c#G/ohaG<֭qX5GVJ*E_9>$aj!Xq5`:j| r˱n?CZ:~p}-f>5y9y20 L&1ܚtw]|PP;ߊ6'x:6zE"ٳ >ZvLx#ָ rAx%E4}Ȭ = /m O<(m 2KA>z O؞H-+s7c=Fg '{{^"4S]3 _0Y ɔMxkXxeD5ШٕQ,,:7E+ L&d!,>x 7}+}~׿"b_܂BEpLx%.hjoQ*|58Ǹwpgnn{SgB+BVqܢIT#FEU@E ΄Uo(=>)aY*#BB C KNَ5CCH]d`20 L&G(<'{ў^"~bOh{`9X^256-S7=R,)6xؼV'yƿ4H`\}:r |Xﵰ-"EQk g c X kq< Ykq ]/p^ab5y9%f J_c`0m20 L&&~}$C_yE~sF7S꯿!U+\YxqI}j:ZO8>U8OG/~h>zy~mZoBUy-2mfCy~26ѳ4dnklTC+4Mu؇X0rieqIGCvF+-llhs L&da^o/gW>S|M ^8-xta4ۘ5/:i\a@í6jMC5㊅=݅KgNh)~rtzڢ~K_}{iyˈh D_ ]{;vm9M1|NŕM}ZWn/is p!/GxP?m20 L&&nxtBs{NO~gB.~+/+gAZ?4܄Qդ:rxr[C}CYU}GC7ײ2ZXq5CHRs.jŵG5k]BX/ryndٵD-.-k~JVUQAχh\`<EI#]Vqϴd`20 L |O}i`NO'g>O~wO?޻(e_g/,-܎Mo7Ϧ?aEE kDŽ/z~HpiCD ]Bؑa=VK꓅ўşT\K%}?ŻG3`f8#E$xS4Nx!;{yb#t68[|\ =Ŵ*X1'9V>k>vYmVE'mpܙx&d`20 7}QDU?ukmJ c=uػOKGL4_`.'zQ{ ALܼc jlDz\cDvuP#X*&BNӭU~djI(z-Y&d`20x3}o87?=zWP4GK ј\ME~oGtUl]l'4֤%{o&ָ&kЙ2Ͼ)j#jhe&XK9zR,8<%r۩waMKirUp`c2o4wCŇY׶N&d`2fO\;so6~?5}ų pM _A=pORm %'W:7Ea+tٙ62/{΅Zuqa,w w}Dxx%LWg9OQxE(8f]0uG5mJa dޘvHkb|AhqȫPEp\ ѕ֯r#y RcE6 L&wv_W׎?yO\~EB 9ޖ Ypѐ2 ΖiSLdojMk2 Xĕ3LKd;F m5*fk!^}sxm}὎x{!Dȝju;\)<ĹzU2ܫwmVVEq~UY(!O̲xs L&du~9||ڍ+!sүB~*nS)tR@4vɰn)4o7Ç\jHWৎRq=w]}7bbBjx@"~b*B (J0Hي㼰'ydZwLr q:zLC'Y[~P u -ij) *>,C.)XdK*#(YZ+n20 L&<We'~~:'OOuGm b]M!З),,j D\ UC6-eJ䑣 ݁R@BT5cUMQ!aZ爌E&\|CĘ/ Qcr9xf·y"J4}3@kx-zq&l;}:OJ[0צY"f Z+} 1OKaDc9Ɲ_] XwL>u;ʹd`20 L ݟy߃zoU30`}6RP:Q\b^i!e38Inؗ4o V-6D$1F[_d\0peND"8xuvxw_@khKw}KZ,p[yXcc5%d J~Uq<2r}X.MRid`20 ԰b|ȉꂬV0Ԛ%C6c C:ű'u9M&d`2dwp ֍olYnײ7$SD 8˜H#;ĵIm)Y􂛨b]9t_8DۇG'uWPjL-D~[,fZKVYfKK+|Л/3!800ʞл%.֫_k]: @9sBֿO&M;qid`20 G j8] noޗmYW=Z17ʭ'eo Ib ^HS\8FR5T몀0J5LXƌ&d`20x2poc|m+VOI+c榐b^J)9GG nnl 3p|DTWBf5]Bbʟ!;n'cL({[HF Y$3]bqVf 2YYeuadC)R$hً.w9LcT\p92&?:xWU݄+"gIA&}82m20 L&+yjއՏ GaWeoILbSW]h & Odsc#?!aa] )ml{=x:0Ѳ+rW6F9 >AʑW@: CK%a%+Ӗ5.VEiҟ^Ciw/xZGg@gӀ5{e^(i I,od`20 L&D{ӟ\/>kOݬgj.Tjb*H%\!aE0MvijS;# 46,AVG\iK1bJ*6xb_BH+\rSխ%hFByIR+,=;T#A9Q{juq W3_19X)ؠ)pZےUúT9:%\zk 9d`20 L^7}޼Ͽ?vci~`'mcQ"0CmZDն ʩaպ1~lCqљx~?NI˟]H]Bv>ʪNҚ3X@+Q,p<zl잁Z\UyŎžd`20 L ث2s|tvU =5a _?d>Yߎ%K,SH!$ztag4sШ&pd`20 L&DT+^}z{z嫾gշ/ӓGW.h<硵q?1xe4 2V6_T*iϲж=N㧧 *Vcnar)oҮp`XcAoA)PxL<.DUӀXӤwfЁz-qw "! ئ =ٓ.L:p|q _ϒ}(Fɭ꓃vY%6 L&}zVbhJ$e/:dtWe|[~{NO`>KϪʣ+xȍ\4DkzO 2/rY >@&12D`z/XiQX щoiڇzPsϜ3/nvT5<;ąs}I&ہJw"*'G ' Wy[8&qWlW]2ފ٤O,jh ƛ+v]̳M/.6u2@VdxZƒt+ 6ɡ DݖֳΆj˔y5e䙻$V,qtmۣ*XRP[r`ҡƟ{#y-<Ń 0Hc7W&Y D2}`7;NK'd`20x2'x:MW[us ط~]UrG>гH3y,Z SUVF;lP(nQg|IO-^I_6hK.Iyvvҡtr4+];:2KWĬ;3ķYR0z= Fֻ=i;NUhR`r&r ̡rEJ39 9M L&dqܱu;K}?VC:I{찾lF~4M:D2gL#;Y)"yӣUldTsuU#1?K`µJ *JYȅ  e_ue?sJ,/frW:QdHX1li<.YQ՗ }5?b K6 'd`20x2/Orm\֫iʀބNdeQzSmjCC8ۼ]FV+v-(.aˋ؆'Y.!ʘp(G!rn]cG?*F {юl \-^eٕ[Rvz&DJS|0suqjxCVDأOąUl NzA' Nou>{~)dgӗ]j6w'Nןި ^Aq9 |Z8O}/[O~z\} Ϟ`b+U=V]bA wD-E~QYq4,YbfnY:Xq֝P..2j$:{pۦt/:YS ϤFO#@p`ؽl_ӻN~OsEqW|+No?R?d;O4ڷkڕd>d.V{m3\^882L惗˹- FɸHl K. "h֠l[}AM~5oQj}zt2ćX~dmN}%帄Rׅ ^uŁ \?W+ `6;2)<ǚ!@tx RtNlZY)^==_ }PO0~ӟ|?z dZ'OީQ 9ak_wz?y# L^w7o /7vƷ|Ή_úߍϩQxp|/D2y.W{.CxPA='->FӃtnӐuzA!| @Y`2_\#ǓFX9BԼu"e^sϳKNҦ5:c/Pdк1&*,&8ǞHH}*n;;~|V}?.&~lnnS|ySYdE?K<x_{YΕ+ q7ЛnvF yH>L8~Z(>ՑyP|ͮ[B=&H9Z<ݬF8׸*^"]ڹ=cҎˣWQKyB@/Z-,ˬ/;BIR:)t4dq3~7@`Oߜ_:x[\>ݕr^O_>땏RZܒ5υ\Mq>_OO}㧯_yǫ_~^ ~5p΂~:?k{꣟8=OD"7 HrH{jDk1\69RZ0ή9zkIj8ڣ>MWL;V 6 )bkqJ9$lҲgx!bw1x,7 ֌]ʢ*Z叜?T,H X)V(+ Ŷqfm@>eGwN#kwOל^էM+\֪ms6q |9 niړ>Y)B(>Y_՗|]]]`XB MxҐR_ y+-e EB%.oQ Xf綍>C KĻ P1:H(V _МY!9Zn/YET M?Bر .%y m\m%{ 95}v|DLnzDˤP JqcV+{k!G-HYˡ{즻/y=`,O|loPwi:.}W=^վBqC/5ŜOYȥ>kZ&ŕ> |7+'V>n)]O>#[bM)=4á:kHYtJ7WsZBto8ҾJzᡮpS+|,:-{+]vA$L{3p+!id`2eUwqeM|n/` RD{eD]*Pn1QmtLM)?.0mإC Ӆ8[04\.5bQX)o5{fLdxBjDxkNҭX3mDYQn9ӡת(H8jvQ;_Aҝ54 "g~/V'd`20 g^у'n2𶷼~o@cg$1iAWXuʟzlT3%(,7iؔTsDHf@lo O=o%: &az)MSE}tYi_ފį!+'"2]piH:p!ᑙ0=W[q"^VH :9\#%P'- 9:+]{ ;=l}DWuo n6s4wb1zsw#rAʱQjbZ옵p%ķ 0e43@v'k/B`.|v;!&dEu %~2p~ rW#}b;Qb4wbP2]^>7+ ɒc}hBk-]lɬ%x >o?cx{CJswv@wqG3KK!sUra-S.B[IyUIb^1sgs}~{Db6û?k_w''dAuG̕AZV)+EΞ 9WHVsEMs^heU+@֡p; ˩j  IR`f%WiJ6<oTjke@^8~p^@lId`20x3ŧ p#o"?+AjE Jh@Iaj }0si863͹WY1rEjW1WJq],ƚQu-ӊIGlA,T}`h5-w|08lZ܂ T.ɯlru#[;Ķ|l+Pg߻ |?=y+o|[o _?pzymU'&dgSp?|ӹͶt|0a4g ц.jǑ \NW#}v(ua0ݶu PK/-"U|, <ѲE ٹ)qA`2 &ID!> ޟ!xt8agsg=6o׺퟾R:d`20Y*zԇ?>W?nE ).y$Di1Lw5bSZIU ,YC$Zꖠ2+hLE$s j+5?Qϐ0J(W#@FuA 򎨒؍֠`ο/V+~1rcbu̶ӿx?*pPL L&]ge/|/دў e5B>+|ßzVî|og2-bi+< &*;%V-0E6yPИ|9 3 h/0Hk^ qg[)'î@W&a¶Pt|U޺@6Մv˅?Qj͙E/D .4a Ji^?{cufI))˦(mbRbt?RKH[i#p`7H:)Z -LI$pa!uĨ +,%EHɖHɕH~k}νofޝ{ܹfsk;]g}NScC p6$<0OO'qu{z߶X7׾{ۿ\~`̀ 0Ua6c eTPFJ=(i -A@2u~*h Y.y5hROD*!k`1 Ƅ^MJ61DxDklIf1/Mbl 3 JxC#7dQ8za|?ECo~Ez,JnR&m<1k Gom濞oEڝȓ?y@"1a 4X)4lD!R2͗h.-! )~t*9^>KI>% X6~-64FA[ʊaъ%&Cҭ zd҇8 'q#84έ1F!'#hA_(dvl+Gn \{{{/\'|u8oސwWcՍ ]6:fL iM zKž1щЋ^9ry쇁6J%2V6%;r KsՊ7| g-ҟϬ{R,bp0paB*umMԝf3FY[~ pqʪ6WU$7dF1;w#P)h @!U>8p58\}d[X㺌Ci dPv\A 3Td'͇ZmP6Ҍx?'^ZS@@@@:8NR, 63mXd]xևwWL|=Z.exbkHRSRA;.N`&%KlI-}{qw jC{5wo˧`ည1Bp@#:OR1E>fҞ#H0d2A O]ȫ Ζ<Ų1f@b4$Cy0d`Y<_=o$v`5덼d.z۟xG~U~/vjb AA87 kbd@p5"Vy*樍Q'3!Gbi^"b(%gͥ[둆*l27izͷ|5 JZ-G KcD'gL-d0eK0g虏dU.َ멦>z'E-tw*l63%KܡHO9|1*h)Ψ#oE\@ 2pY IDAT%743,*<.Wl@{{{{{X`K "x_U_+oZeNov#m'>v,@rj4,n6ADaT7W,& V tV6%bB xPݹ'0XBjc\Q-mj 9retvedקITKt*pRbfCqQQ" 踨(ģ\"p*Cm]0y{ڞ6 &W,~'?uNuG>X)#o6"QoDGu4d SL9cSܻz :J@Gɍ:*I&8h rɐKt;jCj]$vje,zJ|n S[BgBjo밎E* m=$S&V41(vw/]nQ@@_9M$/Şȣ`Dז`Ϯm`mIuBQmL?݌쁯k39AW[H|𴫾| >u.XQ \3LaK9kKoSa̩,xgE7]Y׳*hf ee UR?bP-ݭh-q{LIٍfJ oBŋK$@Y4Ng/tKbCG|\̈́xY ZP.Ԙ}DaXK7B>,oiOW~y|u P<(hi4v4P$Mel 2A捷HI 񫲕:4C~WjU"PXaIx&ZRD[H 6J@)ZD[eQVG11kLLBV!Q_*x˧|1c)^t=fE"c yB9y$$=nTk==2ol.>C/"?D_2x|; X9 a򜥮jٔA:OP@ C1E;{/]PQ\Qv6Rdj5Y#rj%k,J ;F}v#t84%,]Z!z5 KO[-k,A|C F?yOgwLXtPomoYٜYO%W\uH^s&@t`3! Pcb0< D\I0^r6SujT3KT]$HAh ͜cPnJ@G+xAXa>@)jyl' '{ pEx6 x~xe.ةt&i`!xz8+x,Ʀ<οZ||g~ ?x0t6߃ <@*̺@"ֵxtf˜ƈ;FдZGG:UZ?t?V=lq:<R >ZhBai 1 zhVKTyÁ˫cC˪ji<ڬRX؝0f/d b෴ ˎ̖utttttU׽勧M?.~߶xۛ_xۛu'k%,>َ=ꑿgi%FB 2."9 :U(4ftN -!bGP;(~rf5D%OQYˉFL5Z~d])M0*AyH k%o8ق.Qξf/|)Ce_dWaGq%B>qQCahKi{$=ijX<+vжxN{R~<,s-׽a͝~KPmџRw{np??G4> u]k7*o|2[fd=?=]ej4Bӓxdu #JI(AAPxGI$7N1L'~ {mއ':>MW޾~V|s-~qӈ |͆M7|6,Ń}qo/6Ꙑa@?=s&>CF^pQ pհ0+vgTHdkrKUvE(&Rιu)d f-JMC~0MA=OE(Wדqein Uj>.k^Tuijw T<r,jyzr-t} .J\܏.-\\3f~;R2,GTɨ:UjrAe5P1k|ҧ늸.o~]4ߌI*?ߺNܺ6W棟:}os7Luƶ0 qU=u@{j͗}/6[յn벞8|_|1"(@~#ʡ|6枙|_X?o UqyySþ) `v\D/vI29LqeҴ) C\m6T;PYqe@!k20" N+#(ZwS._SO_5hm$y8GجUHeK @̋69ȬѣXc .a}EoG${ե[{ D.is~h]<"Yzً&|d=#^}F"C.v`p^Fjéd} G>Hn4a?kf8[O}i:r&Huo/->ėȭ+ `=o{"7C¬(ཉ{߹a}ވ &יA_7gC<|?`#ͳX_? Y5v u6G}o| ~.bDгP$w3ãA@!V *""qFht`S4w=>a&pQJ8hWtDA tݦ3}dAg?"DFt,h*\u|2 “U ʈ.2eD% =P׌V|rbb_n`@~`:)qB '5-Y Ń6`B:.p:&F* >g$ۺῇk޷, ?g 0W}7ƶ:O7䳳$pC|7QX׌gל2#Ԫ9= @# ѨC02F^L 4gn]"oMfQ ׆j~~BFUK(,h-ĔE9*.۠93fPvi$5l@ ;3foH` W pdX9 U .\{zr-{K r A \8jb[X mJD) kԈ;ї`0_3w/w~ OT~?=;>(Xs.3J6 \WrKמޙ'>!# 7YuPgס= Fou1տ]ΞrhY '+٘`9 H5Pu1NlΏ K.E|7=A-!ӝ=տ%E/%}i.e=kVbd YI}\̀ ҐNՌw1'hT^u% ⁣RsyÒAsl{Wl4Y[|*?1~YW313C$4+~l3@#?-"]XQ#?m 7;`O"Y~n'~>N̯w w^ʷ綶nms|F7>SOL747qX~I"p93>/,ڤߒyBH}oA㙣Mu`Y۵8nzXٗp:t2fcVzzQ -V<CJbv!W` a?7RD|h-BHYigˢD0B@B d̥5bX,eXRB# Y=iK 9`L/K.Tvf>nYܢi>x%@E>`& St9vV_m0dpRhVe}~ZUj: v5y,Tml$:b?gw1~VI?S)m?bb/8[v=-P(1 R"^*&T]M'o!M`]: Ţ-i3P&p@@ Zˉ .V^z@#7m̎xQ5ػt  DM^de0eJ99LSq;'ʀJr+RhEe~ "dgpd;㸴1zUf6%X)Xh-=H?Ep2gL%K2A|tNT/,{`[ayjs?qÃؙ]E MY]A׺hMڥk6=}1_hl|.6Yl2˸߇)OP\=POZHrI"/2UćDYET7Rse$ػEA3 jU6Eβ:]\.Ups7_iS",bcOK.h6: .?ЫEՒ9LxvMkB=!e|Mpxٕǎ/ ?d/Lj?IyI>:sX6lT1CL tx`.0?óO_v=gX`Y{>{gޑB:yfZ ]c3wRFYwK%rV @4Ym`dp"tZNk="%U֣R#91P:cV$ym̈xDf( Pg`G0ak5n:Kc,SMNظԑ\"j?c:Wڿ%eYksCc 1Xr'b*snjQYy,z/F./ѕ: tM񬁡/zV>u{? $mYG7u7|\3Axz8)[0Tp#JWA4ADU2Ak YY1+#z8swOokm/+*RBgE~ B]gB4##nwTT}6j:Tl墕mB ZejbV_aOi͋ESl-;/nǴP<5|%=D-]}ز,惼qAyA>6<̖7瓱XI%va7KQS=uցPaI^(?002#Htɽcʫ)|ҕ7 {Bpx<;} =Ӂ,ːkv#W\H,l\KUE =%-Ӫ%YOkoXPkxf4>`XMGc>Bv(l(do >kH9><^=Y#t 4R),&2hitifl.X=88Jb) /m  HH .nƝ`J,S څ[,/NGJCݨSk@=yOK538R4 D+}7{) (F<+=k<#fZHXAFX*x"xKEXgDz@3/"x/{m1I=} w(m$|{.^hē|v^/]wOE>]fo}8yi&/jdha7KxIx_wn،O/߼{XQ ʫ([ƍ&貉eG^>x1~G&;^vD?Rf\ҥ5@XʜO2]ډoJt&% )hedp~8" Ȩ|U7t+{EK׮.^xQ /.|+/@ڢN%RzTS13h)PY~|wiq+K`_"w;!xݯh>i6v9iS`\xu 2 <4>jD>G!D ;e~?S`/u(?'=?u:FX4> #?ڵ܍F IDATη<w:vÝX^3w?t7/Xi~7f0M]|@ˇxޥΎQ9g\]>ދpg6c%|Ju3oyF1؁=!>oDSf{a<tN< )ᑍ": `], \QIZ6< ojHO CS3E9vRcX wTgo_7CKH L)̉_a-0WT,P*i(j[G{_h$oSS8cDl=!sf>݀=cN\L8Ȗ Dc׊s$]A\3k}R|N˾ۯeWs}טߗ[VzVש:czwFmUD. ClW):䪱dņ"^>D2"6g,8w8Zl)ydTJU4yY޷X䢢1eR:v\_[k6F(gxR] Fk{`,Y'ۯR|لH1yL?mpY}f~:`:?$p;W,n(MR|o];W=F\AȜAT?OzǸ*b;m$>s!sƘ{D0$@2aʐ*^jhWiɰ,tzC=}5(_rnAJ,Jѫ-6JJP ZA2* @>B!,#SJ\/-H;kBDS2/ , edZ!l w(Iud Nʫzud^B&X{uR=;.ԻQq3!m>ėg['`)M_2Ѩm>"@ dJ:NX ZJ}#8Ny s::へM&}pr iS>un0On=_e6ӼLS.Րuc8<'Uj U.D*E=t)@Y {2_ytX/S2(]a݈a͎!T dX &C?J9ASSZxd `̨C 5SGMW'r~>wЧ8i,-x&"L3e3&LMcIDywL/ܳ7dP&c.͂c : gsۚX3 x ɐҍ8X,3Ǔ|'@M' rDu/a7=v5W1R#FeW̢X5Շ0~z:`Խ;uզ.uaA ~wu*94X"4tS& Sg*6M)=W}OM̀bXx@Xd䆄*PCglD'p(Y`uQJ s'?6x偝܀W-FAIXˆ7.뇼(}*Uc b㒰jŸzLN%IGg#Ch^ee<ݑ,TU=2qQJƟٝ]C.K .ēlWjܡ'9A΅>iwϘy20#;e A⼐njE}*`c S} ە`j9~MԦ}#7MJ}=wj=?;'Ȧ`h p*Qa(X$زIL A@<ꃥFTG60#BB#~/?LT˖neN6 u(4iGc6ۢIME2v4 ~+itj r~v$28]) a"iju_e%y-xjRCLKv%2)i/&K$O3Ҹ'@qw6۳I6d4A˟v%Α{vݎYQhsNۣm D?'LoPVس}Q$PgӜik13K7uMǩO8};5o.229%gꞘ)wٳd R'BQ{8n jj_0-KZ%^*5&~QQA6D <:AF֜LȾT9+싥_5& a77B>$Um tj%-%7#| WF$|@GzCu~DGfʾ$sl!G#a!9cdo4M ">6r]{I" 0M0٩A2za݈}ÁlRLcfA'M<;B R2ejqqL 3+ g"UpԌH7.li}P@}78JQ MeȌTlmY [k5qIb.>B0$'( `i|B8LWR&qNyTY3 Z< % L0ҋ~;{v0qqӻS}IAk4)!~|Y8q~9v)0%ߴUcgF4gVSuS7Aʖ?h^@1As[w8"hK[`9BKb&Lԛ,8R1 yV>Q_G&~8ŜО>!!v JYȋOdSMKhLWSJGN0)@u|'tPϊQ 3]n=?Lc Wȧ,x+/\ɕ]we8;ƤdN ,Į |ӱM=cwa =oԛ 7 YPW%)vGQ=A5lbL ѷ iMbk`^n xf>Boj.)lAkXn )tS+ΩE\])RMGhJ,K}ö^rثE6.ٍO8*HJmR9$,ծ^]:+]x})ц C c@*韂hDy7uG{'p6SlFMSMǹt@-Ƕgvag {q.VyЙ`{g;a3aC )%D,RZu`)eb$̠hhdmL6Ƞ1D&0◘?̭bRiC AD*c)C;H e5uT02)0I9ӣڵ!"1DjpP),' BZFhS %Q\y`V~ٛgO>suԛ.*+[eO6u9Ƀ]wyf/VQ6m]PbߦO)y "7dI hR9&Fķ בC`L6 IT?uZ#>0/j[ ʳlk%(MO&d, vFj{8ZJP N}CDTf 1TKA+a2~>~B֕5 Ьs&ďV[Vtƪ|śS$ެdVyݍ{mSO\4XUu1' ijmَsOs|`۟㎯x01z ݞdkqo|u5^bb_BȨɁt(B "^lhdI$H!"Y?4*#PE]^Te5GYرbq˟ BgmD XD+``6ڮL6N+\A9*ߘ3#Az:xiV6$O$AẀdhqF bu_t*!YEcW =p= aȔt]_t\{w}Fa ~ԢuQmt+qXM|x=|xi;B{{-蟁~@+&$4Uee&<>Zѧ*?ЬJ,>3VAY y531~Ä? (w0mI+GeKjѹ=uwE\9 <+M­A(B9| #@6R2 lD jԠ2#`![ :#Đ{У!|\qdutN< ݇ySz\}ZT@=opZfPHA a_@s΅1U hkH9i0Nr;d̖A*Y 3"82y5OK c^Z0U|hαe 3w#X^8l&ͩ3}5@ Rݣ . &v+lJa=ʱ H_EAb_d\v,L<Doi1źzbhDᯞvttttt 4H0j 0WA&f-+J'z ~E3W6MRVst.l2GxfuKhnu- 2(fmNzToXR橓ćtV7%͇FՊ#M.FSLbA~93&qujv8BN O&uј@lo|БC~$1eu,˗dNѪggaYcd=c|{zR%E5MI1&t=z6q+g')Sq'B]aR\O4ڙ}'n/#"[d[*1mMKFD W@-\RJe$c"eR29{9D0{ҐB X,fHhU2:MW5^}Q|j/b y8=S*=/q`#?1i+e=tu.:Xs>ȝ@_7 $i`.&0z5iħb~.,@V$>(PNЬ]uteq1AvLɨ,fcqaxAX>B?4VfpF{@ۇYvOP&*~mx eM2>g)v0Z3@,@)qfM,{CЇ3#%Ap+:^^.rY[OxFM&NuhT _tH9Qɓq*|î56d8_W`M+-p)#΁^wǭF `.I$8勇4_ͮ99G);ɻۧ2)tS\Ӗ<,.<7Nͽs?6R<Pr0g1HM_E3^dNu ;;j:̈bEX66 (1GZ4ȃruo˜aGY5'݌*`:Z9mC-Eq.`':GTG@fgD3)̮g-|y`*8 |/2کؓ_m䳻mAIeg sѦ;f62M0綧m{ 6 W"+ 6!*0}P-ny@#\?@+=+J=ֿJhrjQԕ8Uo|a@ܾTw̐9)x\Lv=7[]G)ט_yy\@d~g Qˤbø?\ʘ4+*k` +:eD'xl5-b7lAF,G/iK/i /-.K/.x`m]ͩ`8mO}m,1uYۮ͏K=ne q炿|Ηz ng`>nJ(:"~}@9 ̲@ecݦvdOіtiDF\Xw0@E)C  +\dUWHlW.fG 3ɜ?gaCA[%u8 -)E7AlqXe I; PQK A AEA seV/"x\y/.idlĝ)y5&ug:I$Ml 4st){@ޞM}zcM=IvGy"x`Aehb[-Or% IDAT~= @X`5aZޑk#@@s"gvS'$rgfmx(=ShY|! &j[jL eJ%QԠWp17SU aBG7ƣf"@C/XO3fb;S㕦ȧe:lNޮcw&ˁ.6]x=0, `;* B`\R-6M.+=f={~+ł~ՙ.+ 3]V%U䮲a"m[Bq'4гZwr791䤯:QEr$tZ@"w3PRkm]\(9m "f)0<g̐bad:ė:bA(9f (`ڞۿI{>>xu9>guhS}]'|.A&_C#G؃ s/~($QKP9aM Gn:wP4όj R cŠ[gIL-r6A&[1l` QylqǕbhT}35gR1$5:;öDQG5G?ՠ-}j,EM)P`3Q= {B:Ԋ7{Y]YF' 0k0(EI}/Lߖ0`A;'ݖKǶ}wL[&'= jdL N99|05w Siyk *HCBFET PI{yҕf>tԌhĪ^{|}SQ_*:y}X3FB.J.`i%Ƙ% ́6ofYqL5hlwNCzTJO &7cUUmv #KpD)b Arah2G}{?<[B#vP&'(~_;bA5k=?oxiw>[ss|f_>x?܉d˩ F>Y@4g?Ƈ*n=\̟ߝnu;Y˰-;:&&t!BjIJ4* \7 T/ a 1LΏ6WD@Xއz:` 3bf7SLX\,,$ ~3?PA|d9L)[G 5naw;ܫPZcڏKK>е*Z.O닐FڒEGR𴡩o:D> ]d O, 1`ת㱝tyWdViOi&הy}{[_J:vLޏsNG|;Si{h WLpFHEr#0ʬ6 Q|WycL'} >THDc,K R42L,\m>ހlZ9fMerՄ 0qhKXU#@ d.Ғ4IzӇ{Wܑd}"̔;xj2hn*v{5,Ϙӹ#;\{ީَm# d3Ji T]?*֝f>cs@dGtz(`w|5r%IP0S$iM}(C@5ь˥LtSxƁ$@ԣ CgbBҨ1u+o, POSr Osc(FF!Unjq"@@D Ӻv 쥵)z󫝱aт6CͰAxD{wяlp]&x\#?^lm4{>@3ǒd6jQc] BkqO9fAŔ Ѓ)'&;2ˉ `U eQU @1'aeg*JL'(Y`TIs,rHVչs+1Cdw'siw{{bC[~ (Nm1 2PQCO6 ͐LmyA9^hiչTi( >15)h儴ٜ#і&:^N u8.z♯Y20rmg>\3g>|H}fÖ]ALq˜f|fo:zP?=p\0'vd6$fDJE?8XlHje`[ Knu.{!L+w:nmuGs{?Z \=xrTrNGuXsfV6>DpzsN>9LJ4Mc) ss%t޳=k]VQabJ࣎./+xCW,I !Dbk\*Cưb٣@g3+schdFiY;X<|P=o,TSqn^|췞uKݡ9_vOʧ,ݛ傇!Ǟ߃G~[7^yvrp#|.eXs_wSg{vO:>xmԧ R H#U!N')ݺ 2([ʤ(y@b0*s.rr,eDR @H1Pˣ5t&DI$ǣ!T~ JG}5* "^Z Ef*ӫLތJP GG$-hsA( b+^>2md.5M֠ԟ*"KlᒙΩvPѮ.yP/%ڪݟ%I/NF'^!M*Ni*F𢵟y73"'uǓQz!8OI>6.c?Hm.u~=c  ({VT@<)7_b&~/CT"4"C,1KPyWks1cfcv"qG6&|zLn# Qfv'חTVR! >Az0X$0m\kXW:%TK@@Hudɦ#N` @a{<ȻY^*?\u9f B*{ffm.=pcQ/t* Q'GdLd o1V2rs Uֱ/>t=p:YN5U_dO/gxD}.k>#Sg%?v\΋\icN7rQ-3+m|v;?(ag6a!l#`+q^P coqAl}F̀q{ݗ{ɬ%`%}`!_ zi+>(/X=f2PH fU d czҶ!I1SՁiUm99)e^,nA3Ш)f2  WkXJA3 !vDB*@/M46ӍܶqGVqul/w 6N|Ix7@xY~-`wm%mPiO2'훓ҿ >|Vw\Im{ݟL u[DZ2 ށ̩= 4iP:]vda-Q,8+hn X8y m2gv&^dH\f<%Ix&Ue~j_澖K @^3 1 8MOm&p^ 63Á .QEقT7QE,1= ?e{{myu=߶sq7+œ_^0{s ?ŏ;i.|Y^}_8USÿGuMo7=ŐIm:0fmnt/{Q3y|vKpcG)j.-S.O)p]wtbχ2 3jgCǞ0)tE FJ#P5'dpC  F, 8.p. ,$лſN-YIa+{^<6ȟ:NyT|// 4caO~7j ֬o;5_/\]k_mG~.V ˋ'Vo2vx>>?} Qߵus ?3>.X$va8 6bY^CiHaA5XЭ0Z|`ن.rN%L#u^:l*{Sh\]\zeqE+W˗//ꤝeG*o)LViZ/`P*aK2^7{=Z8I6z&;?FjYq+l۰Ofb? +Zpb$G RO'NPP;_ȧX ~SظyR4޼O}qgNN(?떀Zv㭔 IDAT_2OygsuQ6n%=@5v>/->S_9^X'3)>&lv*Z6n?{$qj@ݜxPx/@W/$LJ:Gt9d1ePȮ,ҞUܲDw>! )„(US @P0ǣi,=JN IY&%fI/=|.(!lCϺNԗ~D~𮭯 ?='~r'8:@B#hԧ&ߎ b\}[c(s7xDZǟM-eI% g=o{&_:uty;l>$];J6&.v3 - +JrԔ$ Gn3p* t+ܿDT` *.si]ɁCb<LT @R3Naj *`E[ @8OJ-ERd$d ca\ xO)e( vexB5! bN0V$er{< )&&DƦkv, gi8^)S8Cy#5GJnEOz߃г`O}u2kgPc~ZK5y~uwܺ5m|9w[I>$w N8.'eIM` TC6''Mj?G hբb__\6} W) z ƒm4 k,[֜d^&`= ܑX~U˫)X,4+/rE鏧ˊUBrЬ# beQF`:)GS+Z*0M*7 PqEDrEljȏIh}!erc\#wH'0ɟs}I+0,F%tYJ<{#),Sfbc5r ;(w׭%GgrPa[` Lg}.kT3!ڐ,/u.Г-i UhnjGjY"ʖO#`< PgOHE38-ۇUjTGS}:pMPFK0s@@@@@@@y>0`e+;A0puy  o&|T':<,wSB^ KÀ Su!b6PsRE;<lCMrCr<&Qx3xsH*#3&%[㩶 ts8˧kPP%Y>L2X#ymVdfO :=uttttttt7C V.p`]^ @$] 0q?IOBNef9eLL4hPL!!h'0 %*&'n?<*=^$>eehH[O %bEX^_6ReGd?젇S:$*HT *Tz5%[!@a{.(1 >D}!========pp .q2`ӷi@^a""KlEAӦ tMQP \l'մ81,TLMj˰͂a >O;胪7UeN.*'Y[n)`/uU[@kI6l_3ZU5Eo>gY갂 9W~/1!========puRQy={99~K5=ڻdW'T|?,dfS!KaZfgg!תń|/< 0~A,DSyI3K` n_՞`: d34fYZut4XVIf'.pр(7@HOWU{/d(ӈ$HvK,,","A3 ጐHͫ",R k|`9"_^UHρ:H=a]z.\xod&FƬ|lz{‡J > υ)Ŕ739d/j(i숴!WI0^pi]|o*zaщsq!"zyyNFW?^0$Bjʗ+'_2mXE`XEC"o*4#b F |? 5taΌ].I$?;'DWsmEq;sZy=ɃKD5h÷NBI=~yF#t!+?<8Ʋ{?BbL=k AXك[,} 6^wdKV,OosY$VzoSNg/eE`XE`XxN2h|~N,^cqtb{{ZMW|;xYh ^46rfļ^trWser|z)@ _(z(܎T5g֣Dž2~^ɚjAGsg|dW)Etһpž< Cy Gg\DE`XE`X[69,l2"Lh!C'M8y*ۙUeSqT?_3Lxz҆̋$'yGL Zv5CVb?x({1l[ `x~^a蓩1r+XrT wt8n=3tP%.EmYfyN>:Tqғ۷҃Akl,R~R~XE`XEGF]n*)rN<0g)bCq$ke蜯MB[,ݸB%מ M[|@eo.)TN!@}(Ds>)Su8_O%~#26. z( O?U %l^rѭU+@EY7_'7=BN,šx5Ť?=u{objr<' Pk)W1u`KiU%Ƥ.buKjϧgnK_\˩W_`=87`2>TL8>,2_z",",6/ ~}&*]梾V49 biO5sK( j'.N|ڂEHzEҌqDRx1k`M<kuJw5R 2v& ,G /OAx*6r36Iz 5ha &> qW.ş0xu(?}0ݶ,","q H6d(v J6MD r `:.$/ork?r "t$o)3–nsJS+ ~9䋇-KQ+| ڥsD *nMƲCǃٟ,M#l]z,X4F)t4:H"CtK>䋄|Y̓ٶE`XE`Xo2)O޽?O1q4)XR!U&steA ]9)TS,|V%as`+>Δ=JlㅹNv[9!tYd$bNAaϥxU'=?_ƍ׉QJm){*a&ҳ fV3̶DhZ\ݬ)Yxȳ/W9vnpVAƺy3+Zk7P#޶,","!P"r W]NcȣYcl87s"< 6w@'!R;|NG )5ki/d{;k'<=  K'j֥1M^",",7~!#(<@H7B!G,rntC=YQD:ay+TN2T&4w\Pk-Nobmsk?_]~;dFZ2ƒ8(6N~!-}RWXLS8M~#s\Φv"ɏE[9z?Hẵ&낅^m-f",",@8{#4QDı 0 VJyXVY{pzO??ʛHQ~k"zslX.VrIAjbHWt܇V'd"BwGr=ư"EQOE+|ŗtZ Nxyzy6>6LXèS9xSQȗ$D&SC>_3aU<",",zM #,B˟I, .Rxd"TU~qJ۰|J$w~.')Yiu{pk FއN=܇ d9 8܊R OG-?w"!>Y#3vh;(I5B#ن'3{&o?)}H-pyOs2EĚ>ai4\m,","Qx󆂛檭C 8| 25,O=V!yDd^\!r€7QZ/?U“˟֎ Z3k56|Yv1u%P2&x~]ns,|2I?R "De%93^&UJ$+nMI yEJ!'VcͤBE^4-","|$Cbn%Ɍ!|QE#hO fo 36 (@'>u B^) ,'ͱ))@L"]OrW'Kճ ZZVns% M3cqfy6&.61a]8 _W`9/CO_׭qNO8)!$"I4\H hض,","x QBѦk fY9ԍ@cDD Z{v<t%\gˇDupBi&La?7[hQf|rOƷs$L'}r*_u#sk5ih5m͉AU9ȮJ?K'[4f-z_uėM0[&Y1! qd[{]E`XE` +Tj36@>1Ueh9 ȥ&&h,1(@ IDATijX Y ,"sNB5E :Q̷hTmY)(,4spdV&|Y% S3խgs 졫*58 !̖&5Db.0XF1Z;ɛEsaAbittMQEH&#rA۞N/m",", ܂U2X:llz"^eU\Վp|^KU)]0ս|? Rbo`)G-#y]v1z=XXO< lN[#7%yM'(īRbb;c o9ko-RH=Bbx;_ Ia Q!{.~AtH@}n",",A@c37q~BG}|^3&c[z -U&]ٷ.Uʿ ߾3L;КP;Ƭ cqRN[)]%ۉXLX[ |ga|~E@Nh$.V6blӰIkd[[Rd☕0KT)md|K1mX)EJ9{|MRknB(_Ÿ$-","|^ 4Qr L%s̏}/ s"FubM 69x6EOP$+i7=m?(s(`9s_kn),CDnr4I u)G({O JBg^gǗOϺ3[6y͸Zl[E`XE`kxpjۦC'<* 9 Pc8xl2[^cb'yFS$/Oz ] ; ]Hy{3(=Zܭw,",""g@TPcGz.=/Pveu 'c%b7ĺ˧pOMs=KPE0QS Tu/Ӈ_|G",v#GM>& &4ozhNBS Hd'KSS8zU8ܖI ;Ma_+%kVRMp{ \O7Wn[=&LE`XE`X@ a&7RL&<2kJhmFPCszO/g==ψ!xD lGS`iҠ'Cɀ[=ganϚc<ΔMFm2]ƍu n嚯&fr j CYn)NxܭgT?ŊπZnKnyoUl,c@{YE`XE`xm([61}̮qh#!5oxG5Tbe p~_|*F剥"q?qɩpy^W%2ѭC3U!&M/mP<)6 ̉W̦^ ?ħE`XE`XYz 7">J1fS@Hb*Nz?vY'.ycra_SJ,! X׵m!a.rrž@h<{_)nsO8xܱxhD9^ ^Y9gvy5HkJiS62@pɝr|*7}3ߌ7@"ϾqZk",",B >DffZ#avUI|-!ƔؤVcWG09ΐhe(D 4[Po {YIhg>GT;%Lx7@6oZƸ $Gz~([NF*@UГ.l<1~G",",>gሇoW% Іvo8jUcqy]2Y&P~ζ+p\LyqyZ';G =F8R% Ud"3%c!vվ2u *x)vG$7DIkQ?kK?T!u j{]E`XE`w@L/bxkgf59RC^v'dceui))~HycsBS a3ItJsNoɽ;8t_4B~#]w8.k-N(Dkh?JĹʠd'_v'ρh:rGqG Bo)hyzY{x'e"VQGȐI7e"ay_mXE`XEC!g@Ff~QJ}׍zd7E&ZXt_]f0&ӓ 465G@K_RJ-^zxN)K1tqoS\Vn#nZ!F7544X_vyˤ#KkRGuLpJhr%`.)D >[m","|@Ty'<%9 .覾ɛ,3=}grHXz҂"ꖔZ= QOo FjٟvȠ=yAh-a׸mbqČR>'?jgeR3} Dkbۣ` #S~q޵.̮Y15>ؽ7v",",7!(VB{d1F7Zބi]/"*cJ|bk0Yo}{=êmUfXmk=>KimA #m\&#=X+d#.y&*Jf=ǣK+)@2y1c2Mk-0Z7E`XE`X> /ca3(Sj=K#/|[>&Ѳj:RMeoUM=~<3Bd[!65tu#MH3Sdi\&:|ޟw*d6:Z~h6?]RW ǃx2'ȵnl\YK ^E`XE`X>.@E J-鄤BVՅvrOD0Jl,ԄO Lk,n!@q*aYr\zq =o\ɉ75 TzwCea-Cǯn>tDY ػ51Y_k~Dh) sہK=X#?XF6;j:y`n[E`XE`RH36'e5d$X#=1Q'jKco e }o*Y0MSdmh y݇l:uԢl2o!m)$u#(xb3&I`&󣚸gmkpTRh4$E谉=椲j]0| Lʖ=hh/m jdBaCHMmgR'RL Rif!(KF.93vON}#:ªe|CSMJDF$WJRa3T_x~PFɒl2dg?qh8r'Ҹobu'>HL-{GI_ɋض,","#GHI#L~*ءb _95)RBi+xH6$:rbfFO.@Rppk:),Zj(ϓȘfdxʅE`XE`Xcwk~OU\C5c<4Y9Ym-IEn>o$C$P7ĖجIMĊe x^x(<_s& 64̈́~bjl14Zx\,46~]b&;QH+Y;L/Ճ rcKIx]jS% *PrE`XE`Xo ]LX.s43fZ 2@&ARHܙ'q08SZ9~ 93kJhR"g.ވɾl`1dKعp0煽>$d~ebZx ݔǧ)5(=+њn>=?S\2ϻV`MY?J[]E`XE`X?UsaS2M(mB2(9v"&nÑ}jPb|o?|.f0:f!*&8ubg]8pl1'.}  rTjjMzL̮MQbLRv_vAP[+ :J˞]xSB1F%cHXkQpl ;n伂EE`XE`Xo| a!C*!3ΐ!%mszҤ3s#|o]K=D#fKnt^+Τ$TGvN+Tl͖8%J% JR~9؛{'®^ $ c\#.6웢C3kϸnO1fWqr",",GA@' !!|F =5S,CUFlqP1Ǜ|Ű& :5}߲HC¬ߛc? pa""YDRtYcPH/:~ӑg_,Gol(6ɻDZf֘;%#ԧպ'n뙓Ebo~c,ЛwF0cP4ٓ~E`XE`XoVPD~=,ԓyd*B  )NW>JM@s'/&ir ,>ҏѓcTBZUx0-G*D??Y?cObI:%vj cr˛n.};9d󖂎(h41"pκPx\\.jY;Ş[|]fi 3ؖ9=Jiggȷ-","|^ WcC]UEX1~paFi?c#7[dLL) HR!KS 2,lؕs E)D-͸(K:RK^cFhTڡ[9`Kg<(xg!xs sٹ)F41tq",",@@' -̰d2)RYƐȘT2 GB2|mZy"/o|vQuX Y$Y5c&CS||ⴃgYvk`+Y/" &OtS0֩NӐ/'6EPd51`Ӝzl\zyZױ`Q̇_:_!߇  EmO;Q+2|Qv",",3b`r9QR7d;(Es1pQ,6 Pȧ6I.4yo47[\|+^t"Bt]_&z}!.A tScqF1ҵ\:WݳũPI95:7,c_ZE%ʼnȸsHzק֣qzCĻ`4A ч[lYDŽȮ!n :2 y7\/a"inEN#8q ;ti+3S; F5K)M@7XZ-",",G@&=*cu '.]Q;EjU"[y ${ol:Q9wߝޅ|j ""yt=œuyqÂ{r~Bσq%T8dUb+^O/dk' S&M !˘%{1E$Cad fǨ"?,i",",kD>)-&&*i0Y:r~C>H:7cؼq:w $-1^?gT|| q+vՋnm 99Or|r;9EIo(A78N,)`$#/4ck{%^OG M˯NrkO9\B|ggZcqZ2\(No,","#[C$S^˓=X' Yl3k5rP`2>{<*&\!e[T|g/"a1 sG;7'CKMqfzL8'Kv`T)D1A~Y@]>.ԻP.NNˁ6yk/_lBRy6*{3_E`XE`/yI'"9;Ƣ0̒LQ=hhPq˜ [r#@`eg!D{ >q'>mCOCFBuGDBDc}^"3E/&|b`NCNpBg)Ƃ;VZk$תb.+ v zZOGt'{2mO!D\hſ4"d",",Bz}]cx~g;/㗔ވ*DRA* 5V}syHJ$9/e $*>Y}CgB@Da@ۥTzWF B pf|e_>iD%Ҹ4;W&cV5>B)xR91i^Sɽ "bä;=k:t"a",",B `=ɄB#]|:Y)j?!BYɩS~+z_1wpjG/!>)aff[}:x$2)q, ^˘t}EN-҉ IDAT4@A1\@L—nOK\瓃lј$?GՌCIP&;.","| S8#B.paPU DZ5Bpsa)սן>9sW,#|?=d[}WΩ{X5]|YM˶T"{JG\G{qdM^v\]?ٳi2G42+d31tlL{:7qN+ c;ƃwlbӷnxE`XE`X1a4,SpKWsp>ef:3}/ҐĊ2W);{] Տp+~tħV(fZHN^aO~÷aq /9ےVMc/1蹺~`e=_+\SHUSzt\Y&tN*(0^nArBd"8YK^vOLHx."zMm0=n)DP{YE`XE`@kxEEC-2a!f MC@Ut,D6]PčdH7'-&8$NOv֦xjSld+UKUznRmao0e5Fz3BNyI̎> 61䒵'y^;2sϹKS1F$QsDFh*izqok.cձ{r .>~ x׳,","|t | CK p _eMVducy4SD{V@wPq,ogc9I&c&b #kbZ,r%@o){8sΓ\Z᭍r{ Q?tndcz|stNyvw:}BZYDvAj+e2Ã!#śqKۉ2~PnXETĻ|gӎfqtWܤW"㶃E`XE`XoءZl)&@uH%Ēi覨&Q$ E{YarJMlxܤ%z'|&2-Bb?'k,E&N:K<g6f-1c)U^-hriGv`W{[:&z(7~ZϞ!VΩﹳc/",", p8cᑞ E)PL8mqckuo) &&q,JNJ$Q /=  Ь=Z>Gu 7Jo3co7mh BGf rftknub6줸)^.4 a*I|I3]dtŒĭӾnj",",@%T )FX%BE)LCN.ꭇ#UXƞ=$]LrE>Y"-]ax%ɔ}yT76]|__~u.=Rbq[ӗggYټ.0.Η{Uӯ> c<؄JR?dBMm,S&}PIvX}e,A+}~{-Q91̳^Ä?hD!D9GJMיDP[|ON#Is#&_^oZ(wG/Y( X1g7Jo3wH]P4c?",",@?Dh2|zTb̒aL ɻϽ -","CC 3Yo2֎LdAļ.V r V2;\E`XE`-X9QLQjbJM*3B''|mҌ(+Ix!v`nyk8^ 檇b1aë]#;11qճiyցrRrɣ$=K `eyթtA8{ܦh׵6>3w߽Cu",",I!dHb5̩ Tvѻ,W*T] 2zmHji2Ub%iLe=f_shY%%^tjAE"˕}t7G`}+,A<1V,#K\outܒD;cd}vd#)2N-1Ek'^F Ik1",",7Khx>7}C!" uXB^<ӗ1LrL=7IUb(M8pX!3SߵUM Uee] ؝^( %531}IQb%ɑ9|點vgUD%}[u큀~E 8r8ń3'$2ix=k7Ye",",GBۓBB՛Qaűn τVcF@L'C,YEMX]|S==|p؛|R;-0u d}&Z1#Op]jJg[f("Yr&NZ:I5-*۷Z&?m",",80xy!V$ҟn#5kzscYE=-9\) @/Z.˹ knx}?j>ܯOp鳚x-S fn:\_L>Y0d=o/9=6k gM1 t~'Oq!A\OϪ߄!R~ ܊"l%^+]#E6~I6xws/",",6K{4g~$Q !DR}6Ti}:bpBTÎ09Iqn7NÃ̛>!{i<-έGu ](OĄ0O_^rG +Vm]S (p1?XsJq,cJ4d4[^ _Y+W~~L5jvt3d",",A*h(iyXDC*/:kc?¤X!CT\ ?6Mbuœ01̘f'5qy?O>)Ofu+ya$a‘YjiEQ!,9a4k  1qď>.] |増93qh ~/",", &9F r&#~ѥ>dI0$a$|Ry|\IOFOgt k*'|֥B- 4)\{/؀fgiG^׭Wכ2 8Mp՚  #Q\rj{Od!fw[K4vr{;Da~Ij",",4%<=M>΍7mbP9M ~֔3N3 6Y倻MY3TPrx7 ޵5:]\j5]4q!y X> hQ@] 4teT۩Kj|R9s2")Blub}Ul0x~NŚ]jQvrjc1fS4ӮHsr",",7 D2$2u54ܬ ȧ}%t/oIVw EA%M `OFb ĭ>$]5^~!>$2] & oCɅ}l7~@ _Kz#s;Zɞe͐tLC.@O*>>m4=xi|z7y)W1j",",?! #2Hxh&FE뮗/~%MTW Q9kuE%_\|/WHѣ4V̐@*PP\ SZJ? S_; g&-*Cy %ڻ:/ 'r!3cxxg=m PYAam^;FStO `9{j5$ܶ,","!/N9Pic,=bζ3ϯ?!|jÀ<.JJp8v閤5% >-<R8Ē ԦǬ5?%$+6)Ju&6jԪ5O!>.)}<[%PtPzs∴›MVȇm%\'sK;ܙ$#L5Kb KVk6cYr[ !MnA`TkfAE .:8ЭW~H>2)g3KU50gO,&MJct#Иy,#Mc]5}c-E`XE`X>zb\%vSBESsxr8;cG){ ߆:.3 QM :Q![K A:?8Y3%SHW\Brfd{A&V"/< zr?]= Oŷ\=yb鎬M:]aއ˗g~ SO\#k],q .= |~kdusgQc3$rpKU,.EF{auG5,Ōݻ"DB.t֫O9K/)%1E{iψȚy$*],P!3 gA`L>tNA57kҋo[E`XE`Xw@L>q} |ؚ!6&b/=\M&-NE!#rr D/GH*k\$ȳ@:Y<<օQ9AJ `ꇉO3k&n#CZ۳N=S"t!=yՌg]e$y fG2p& Z`o|R '"ɇ ь[x.$)&Y!cbuXE`XEc t, 7Y=sw [HsKOn#17.v4Hyy,g Fƪ#$B8T9i-kxl5bEY >ѷ'DCWL{[ZdCJ}g>xC'<9us"wN"P{5=%Ktޘ7g#iu  ?M(>OnC 5r]-","|4; jt_CΐbM5*ɷQ׌*?L 8~aŠ+1w:A I|Eg?|C^Uw0m`;ʔݱ{)d=L*`8Dj}\m ;IKy95pLc^g=zi ԇLH\- w!8MXr|G>XN:~9˩Rdo$",",@ 6 CjI"e:_U42 nPWfqtp 9u fj҄]bqbmA}cQ龫S?t}6B§ZkqY>͡wc7lC"|2%L> 8ı 7s5Q *ƹEd 8ÎVB@6oJ"Dvܲſ^d=8m[E`XE`(o Q047ys4ӌjYc?KGluuC"e_lMn'6!Qz0ciίKdM\p#|rm֘p#`/I}ՕbK(6@ :g.nۮ|oO67a2uHa<:4 >={eϳRP ̠#Y DCl,","Q3 -5eCHHy@g.+ ]2q#pr|Ó\ y6,1 ^ִ@>-cTW5Ѱfa4B+HԎ+Y,6r`H"'~_983~r4] ћEDNhFJOO|ծ| X,{PHRpE XũHZ$3~XE`XEG ߂} &PǮ(4|쥹4btWhH,DKixxr{~̉kMRdHJD >> L]$^ ڡU*"&  N@\|FFߊO_%5/! ɬ0'Q+WcC~v(1<_˫u$@%Zo,h&/","|T^ņw}#cbrO z1Q6dzg)6N# Bq<ʤI,ηkC-0HF-6c3B",v 4=f)\`P=q!>wȎXg $ {d*љc)^'@Pϡ DcȆ)hF>pCCi{Bx/",",BB=~uE MᘼnmDCo3WB^I G2Ԓti,\x2 6zհfW/>Sq.?D $z}ŗhۂ80i4$ H.4>v :N>BN6kh6M1zg3RXOn8^}E&Ȑ͖!]ImXE`XE "פ9d2^NCRx,d<f%44Js|1"n31Ĩ!Lҋ1^S`ӌ _rl(= ~ 9;{>X)G> Tݪ&`jx5"7xu78i=Ar'Hi*.!]M_Qa; -","|(nπCDB| PLz$&nehDsm2 ##x\{@+ f3˓6.]\$8Z|˙ (iFй 900"EɉD1 '!qw1)nv+ȯ7׮|lBrb=!E`XE`XːݰEm{"q썆3vӂ0qClj E5>ߤֆ =%ɳC{0v|ś<ěec\#tEZ[&92fj(VU>Ǐx2:XQCJQ \ kKɧI\{HwDH!`mpT9l-","|i :K߫V+uTVsuO;+!yt7 ?&;z7~ž\ImR!H6|[9'j@!L L4l*9DÛ/a%n\u=uf-£coƾj|1]=Źl+.U59 Bc1CW"›?c T:[2v{]E`XE`0,K'sG1zv)3Q\d3GXGS}n:[A9ke]Şs)O!˜Yn_614ai4lB3>r "@yI^3%=z{[bpbwDlv8YI%mEf+6޽^LBT^=\g","'??OSn՟ ɔpG?{ІOynhP_)_~GG'm^bpn9JHߵKh 2tq n/3/f<"i>_vĪnp|.o6To 5F:ɉiLXn8StE`XE~S;?տ=?Os/d d'OO++:eϵ~Oo?y}/}sOǿOwן~O>(BhCb6ό\dKM20ӵ2)XH' ̭jM+;'({$U\ًë kAF}.r;ɻ_U%I&C뺘W%ZoJoZE ,F^4Pq:,,օSPl-[/3qfܶ,"Hӏ?_7^_Xo5EܯS_/s [˿g~KOמS1OObiF\v>:(-k9`&: 1?IYCC&+O8R)\+Nx89Fte[24|ə.{, L}QG=(8(h2ωmX[⥡>ߩjYxyFTMPPp{{{L1/! ,"BOg_HW|-Y?on~W~^c ?~ CM(ƑdC(Aig;:Y"I,蝃ra.)s J|u_B8qOo2()&jl S7FcۯTz{70T$J 2 j3z})R<sYHvМǺ{y}'s~6K|\l8_E`X~1Og( [UUkC9rЃ| (~fHFW+.uIVǽ][]n?ner{23@%B ))((g9Z{Ds9k5h>qqG*mZ̄пMxn[, R!1$OnbSx#B'g#]))Xpe.Y/GThf8j}BZRVP@apB[*g= m=h|@ :=]FEvTɇpϮ5LaJ@Rz`fΦ<^Ic(Wf%$v2?`aw f4j&]rT'$$$$eZ/+Ih|CoD^z07FQ$O‡UjBW5~Xc6! gXW" $F]1h;@K?wh1닾m2^@ܧ [o^- 4䆳m gBB=iDžvHC$dJ`=lsԻ_pmGdyh06T<<<<<<-)P6#[KǎqӓSٖ$>L֬Y-zC;O-U&-.0Ӄn@EA/Fcd`Y8KN2֬ʦ _]DIǂrdiG&,~7= zAp0&LF0%]>sB&\Q & ը..t36J6@H}c1sz3"OggmCEek(b ntP?h<<<<<==?jz644:<0>ySNml'Yҧ~r'[8Ownޖ@>4)XLG|"Gj%!W+[N YtZSr:h1 NWDз&Kĵ;Ho0&\TKyigN<;.2915y>z]>Q? Z,aΘAK1&*rG+(v<[F,fFPh pp7 G} ˿m$m?omMTVJuC^ziG,oذK:s/v6<LR5ܗH1č!T = %2 B(TH\ 6xȤ=`زI16 Ib D!c\ ½cKTwJ=n`"h@>rU+ 8 bQg(GJu>MA?,ڃ AM"mV%GLZ0ˡcClB mzr8S<<<<<==|C>36e3"-7|R c>"O=3x3-"֯5Coc^ecrC:bSϐ̐'";&!]r]:bڵ|2g|{A.2Wζ6lM^m(ʖ`1H7hbYz(TPZ7 /;kwTQ-NJ[|VH yLhE:B=)7WX@ g=7Ny$j>#,1E"D)?NcysF"D.v(FA&NKȋ r8Iu@@@@vFTg|-Ŗ]ouSg>jn~=hڠ֠Ï8BOg=w7:YjXIi{j1w2|rȩNHB~X~E>{e괩2r%HBTԽ{w%\ť-l+ھukm/32—H hhQjJ.0-!D% 87zV̻ZkpK[lÑq;#=9sNAQ vS>g4Fgʥ]7'?Pvp *>Pѿ90 p:PQ.|T!d<—HI R@4Ŭ 0{$$$$$|/{uWa&yKvS g{ܪa_P{ɿ'iZ>>xQ;b'"t3tT*PEl>e-xh Y>/%d߀DphL!9F NL+ Ai9 '~7y8!-zRb+\lCKA6yI9`>rKKUϲ'"+W~~4ꃐ<"㬳.9ΑHB<koʫWbCGf qWT ^TC#eELSWq_cJ/$95~Wal/JիWApHz~;{~+k˫#fBO~wts)Y8`} >"߀{gpO&|k;3F9' .،җ"˖=)o!!]DHL.\Dy¿Q@ ۘ[^2}Pv:kW9Sʷ};Hߕcd!p8!'LQ+bzZKĐ)XKօtj0` K^Ńm7Ix52"*3I,x٠~G82܁ 2Hg#IvF30&>$FsArǶY$5z$[# i=dfzINNqpU,*Gd䇕S[76lmՒ#&`Сx޾Kּ΀;5H8Qۡf=>:Cx tz=ڗs`z3 ОrُQy˴zDzΝ; 9S'hE!!ڂvZ=`ЇYLC9;aiSOHg'&={ch?Y}ecKd?̛̒{|+HccJK?;Z~/rA~qj݋ӻwgub[{wydÚ|(\].fFN1B -yQcm_u*)}p7}a;dD7T p4<<<<<Wu :} z,!7R΄0r΂yy&EMvRv|C^_"] E{g4##uep{JC(/a?ͽgK#Vaxǯ93W K: /<:y~2k,+u(ಳ<]{U^VH6Iӟ9 {B=+G1 ?%Y[皱_?=,?_#}v<Q7<%y,ncZvË&A2f5+d$"b;@jURC5Ved8(Z^bWsp"mgc2Uz HT2i*a8=Pi(Ə=iDAQ `3AMFPVTk\vHi]@l}@+HPs i)RKetLHHHH*jE$FݰV6!%ˠz셥Bx?P/y{讟<^3a`D+/R.vaa;<]-}\6h~M=(r~!_?`ƣ#6?#UGRp\rUH {Gy ˈϔoM^~p-;rG<}UfO~r|qҧvr أi?{K/+F˿$S8y Koh#pVcC ŦˉBc@jۙ< %CYm:FQe42LpD6it(FZ쥒<<<<<xn8$wklg}.jI;=gLJ(/<<؟=w{b?'MHz\>^d}W^,͋/1&%$|3g0[q/\KNBF-ѻ[!C?qnj?{=_?@2S:+v'> H&`퓁hO\|9FW/>y̯^5,,br8}??E%v;)gnFSL ` `Ek cG)R'ÐYG ! Q;'`T?VqCV,e2챸JHCI\ƎfQh?@E9S/aЁv2&C1QM@)\8>y{т0JjUǍTYS!? |0([%;&l#$$$$$lk~<=>tyKڪpkkJw(B?fD4poCqiͭ~̧7q&FNHTD/wn`ҡ^}Eqc_Ur jd-y=yo^TWf=:o[_eW<.xrɥȻX3eԅZ_@ fC8Q0٤\zf:l,و=|6|Ůiҡ ɠ6RJEFf#ygKj$$$$$|=^={ʫ@fB6btf@{Arj?<$OFiK ?ŅI'oy[$zw4/Y,W^> ˮ䩧],,$f>QåJe+O*ߕp5Tl 63%IC\dE<* $447J3 ؖI1bt\٭1IBtqNH {}ikQq 3\Шt9Nӌtv(c''KAgevn<8ؚÏa;'Ǔ# {,kիB/r اnoSN.׻Iò?M7z?||KeΝ:#ǽ~{q#Xo,5;#c|2Ha:2t`:vT*PZx\{_Y-eNNH4z C7 ' Y8H}#lx$Jf!U8pCee@L]"E D bxmV+0oLB>S&І POiA/\͐pD X*U. Ծ9CT*y y y y y`q?ҹ__uz,SLIJvPvH ˈei=W[߿9^vAJWHQGvnaҢcD[{s` B?,$:hY`=am20&3Aju""RIHHHH{O⇁0 ]LDH\x).s4ehxy__;VCI_cz ew݄ 3#|ĂH \Ch#@  5l$>}}/r 1 p37-(5 .4gAS6PFb+N؂gKyuփ@mi#| }&v:Z`HNCl'/H8B"mzg7PSTM#ܴi SIHHHH0#f/>/nڠ 4ύLy>mD ^ A!A.-B[F7Z{H9M4Ճue WNAM QZzP6g ^L\EqFB +y@7*%@#Xuy̥3R'e󔬔l~ #9a(h C!lP 3Ug#՟hJ@@@@|3k{Eĭ5 ?|`qћ#Sz1K2Zhۤ?ƒ¾ѥBD'V8wj]GZLcfdF7o.q(53 A`[a򕈚CAOz֨r%Wex':9?pilm`[aN4hAQB8IbC^bBj|Xyc#cK Lw· ;K=4ys@ R5P4 RKB2`thO&}PMrK%X0%qLk&J=f%OFbVeѣR`zJ׶٠3(@2)Ǣ2{?@y8DbOIPlƆ#6-##lЊ6PaDZ6JQs~@@@@@zGն$mNaU|E/JlD[[-gڶАxia ,ǰџ`h(*kL:Ea`<$61WfO-(Ao;2iG<P^~_v I*)2|Sq&h3$ 7Ou1SPȅⶡ$Deȳ,C=\ m5:7bcsу&޽c;#׳,$@̄XWD[/[Z|d\|^iLᇁ!U |-7;P*BX(&$$Fhm%(HiK S _gza?Ä(=&<FGEOdT1YT1ar 'kE mC48|]Q'$57G9D^.5> o+{Ⱦzq? ;vF͛|퐼۷a79dKǡ;ߘ`U=$<%$(,PC@am,j鍀`Ӊ?ڑ5 PCXhYM偗p]iĬ*ĦT>fN9Dkeuv8qA<7l'Q,Jl6<&ψt}iK-(DŻ#  4NL.j2b.P﮵N؅1'^t \;b,%&*ZXė;M:4pe!84jT"J DCd>!&Ri *&A!ˮ؏*C EXMPH6*! Xrd"P2mTQ #eE&6`5P)u;FY@0s!v|t W%ЦqhbȀsX]{PmR"VifO0V#06'AMZ@?.(;GNH#;WO}_ěɴLVj%$$$$$$$f@4`Rط< 3J} T[z`@hd i<'R>A -G6@`g򱍜$, IBP&sfΨʇF^W9 \^yr¾O OkPBT  5@2SP|c$eYE 8NQĒ;tH>ЂL="1@;0d 8Ng#,ҡ퐠9mD'  x}aÄ"@ K,j  4Ҿ K(JU݁Lpٚbs  IDATbm"uGuQ\Hxh )2]Z, ŨE[Bm:glYu8GcY <<<<<<<3:Eq$Z%< T Wc%[(L vQ*ߘo09O(w&B%H qڈd,Ɔѷ3IpY*]53j !ZPZ$iw D v&%;ZZL P">, DTFӀ`0qjhhba1m@ U)O3 i5 9M䁝51&8CGcD;!uF$Y0uByC/E EEAg5h(塃y1WJ=$Ԥx'bj' ˪. CtX$5ZrLJp{Ma Z 695u9D %8 =vY7iYTbቛsg\L)F{@40dTŘ$L4K(rMG` SLڍ9BZoA'Bjˋvd{k$LpX (0!?(d<ʙ}FU_A  r`(YibB\T"g>~Q!'M(|A>]?U.LJJK,kJ@@@@@@@}z65\6`Aqh⢱>i=E]&p4-R]y~MB@DjqVneb pv!qݻB=8t'<C!FSUE*%t|5(#J_xb ZBZO 9f}߇PȂNLHHHHHHHة=R KM R%A>/! xMX}|Osh*J !P' pˤzX%LL(7sM'#9<XRLA zQ~9HĩNHHHHHHH=h Vˢ8 _30b5r'Ή-9=%D!a 5vY^+uGPeZĮ2@٬PSOh4 kgGǛ@ 6RBla- fQ9#h6$2hgP9jC`N9sR3y y y y y y y y`@a1Bo{]%iTry,XŽu2 LtPkDkH(Β8 HG!T%!܍!(+k; fe(K:eƓHOh2Mb!-&@4q &1A )O&=PjZ#qFeS;y y y y y y y y`@AdZGY< ;/g DY5|VDok ٜ]Њ\3m="mL&X`@]z \(C&@j, ͈5-2u0q #yC(ǩG0Qc_*n{2=4F 3 9Ey*@ɲn$ nR('5Ϡ9XM8XLt"ґ6塚\PB梕,y{ Mi]4L @a@YӺ#ńjy xfΈ|6} d<<<<<<<o3(Xpڈ3 S:4 PMT(Q[\#ի;1HJrzAG)]*='D5$}55vnL@|01=k魭 10֩E/:hŪ $fZgpQ ;z" 6k:Uo+$H|;谶4# S@Gj ^g)3RGP0<‚@pGZiUXS3y y y y y y y y`& vԐ2 YYO=%#М?+ <P@*ÎQ|ȉe)H T^i)# AB8v 'j&"^ pABUZQEG81á/q%L R 4]TpFHcfL֤K%y y y y y y y y`@ErZ *'Z |ǶPe H)2bqDM>E3Z7qGg<<<<<<<OUE=6l ;Q;GI3 ;yLHHHHHH=,YDaÆQ5;‰J>d#4 )%kٲe 2*kciӦkj/3f߮ #9Ed!ͷ&738c{ݦ 6uo<<<<<1k,9쳥W^Up;mŊ ?˗/~ g{BezCŒqɡ@-B1{_"NSFćf}ٺ9P\x^>bv. q2ӥwm ,~Ǟ%{6ωkΑyG 9eNuYz\zBߖ~u;g4g; i˶ڥe傡@d˿meGWNݎx1bvZ dWZ%}KϞ=O,ʏA~Yg)ڲ-d֦JW]uvmrYg5ˏL>8 rJ51y'ޓW05H^|i9瞫ǷުIHEoQyLRT@VW_]&K6W7ӗ嵬{ =]^_q 0@οa<:h/6ۿj#l9vY _^,&NV]6eҷքn)[ש*V?Můlj0d8E^y1kL!','3c5uk\V{w |6>+5VLFpa^E#_!7w,-®^OoMe_oGQw2`5a<_rӦ5rSCo-hN9ߵFl'~)h0j2B5ē53{Τ\r%_|S[#RUVT/pfr> (<#D<ՖN;M;|aH\AșSuA֯`VͷA :{W5Kakƻ5;(qzn[?7uݡ#o c iL5c\ؿ%} k= \j™_Q&,ēC/Xx]/)ַ7Wo -2XÓ9XMDžױ㘬½4C?Iem< 9ǩO 2<~X#7xcY6\GYJɿo_WW*lJm.><.VG+/x`I&5lru۸Ln<|֯_ղ`m;>Sq<g0^nz̛>\s9?ܥqҒvmһwo٭Neݤ'`{ZѰvLpl42v3('Z4Ȳ9=ƗSY/O;]i -y\}LY4`x2 bV/7ʢ5vz#fNAڌqrԀeƷ|jQer 7L5!(ioJ'3d>#V/nvˊ@:y6e=s"+jX-3E*IZ9[o!cp9q5"RuQf };g珿]VHʝgK#u24jSM}6gkz58wLq3p֯;t~L|n̸m7J[ ~] bbqb!8fD߽B+]d3lfoE+b0*kBPz\ .X2Goo`kԵ԰nȍU=F6ueL٬7/cyG  8gl.F9{WLj;߄ݺI{zSaOU߉J)Kh}|/[NLezcT;rJ}-aNbr[o$%oģ+cΝ;kPpIDAT˽ 'G-d'?|\OB2,8sTa7.Dc|qFlMX> !O HU•y'/R 0HSMI$W0q(^v Ե?baR'-96|d"u1"wN~!@KrcqZ!f<߂5o],Nuz.I=O?,S1yywɦ)wdse`c˛3dҘ1goiI{c̽뇲heeUFf}ger\r-'@2y G n"cozSn (Lu NeiRLwt,{vyv ymmŸ;{N ]*=rViuN^q\3dHX/Nj1inRߩrրt $I2nEַ&2^_iSΉrm{ 'u2#0v޵>LnC0eMۂ&R.n^22g}$Yl|cyk.D%S?_{<F*^#*u_.O;9w$9=_PʝR2nʡru7GL4޺c/U^N +M/~B9wqfn݈lOǥl\ڶxh5Aݼg6Z\cs'ʟv s-nHEh_7ጾ~f컦᮶e}`˛/ά>EMke2q4|2ud^J]KxQq2 wbğӔќ Ȫuٯ,2CVZ_%MAYMseK%v{nqsP~Jh7 'ohunS;ɴ;%8a?Y]w+Z#Tׯo~V2K V|7=3`q4U6?y0>\?lF\8oVR<`|\piJB<.%n mFr;dY̛7O/msqۻN@wD70Ar[ tU3.$Ycˌ#dGaB%!2eXOϾ ϓqSK^rX,JOK}j˜˼yeCGt`)[ˬ'N3Fȥ!ihꋉ L G Z-' (;%Y%r4sd e"5ߖNt08HciʩSBNK_t.ZzIw9˝W#vrz!'^ 6]#VM$uSee`Zne5Ҕ[P|]L' Ht 1 v9eQfOX?_Zي:_2ZrM'Ã?=_Ƞk|*RЬ qO5ρrr@**^4/Av/^zKCDɲhZ\Q՗w-/:XN'+RuΑT, #K9!K_n@޾- !pꤲͅh }{ZP(oh!߷ߍNc3~$yW 9 ?+6`\ydT 3: }o-=GL_qZO8GޏG}T8Z.IX[xdNx^iN$A< aUS|}1|3ڞS3P4)GO8GLi_^J#(~I@pߩIn<8W>sT7e澅doo_.t]>d4ʓ+WrmkiПp!,#:Db7(UfCk-HΉP^\V|ؼac>?V&tikE+WE\48&gza5҄k\5Sјɟr芯%]΄%Gs\9GVT8Tu5u:.!z則ѽ-E]"cNm㲱6w2w6{Vq (\7L;ໆG}G9v4X}mߙ |X}?Oa\4*$(ԼJx(=kew0BZ;Hu#A|v8Nwd297Mf3B+TF8 kJ[t)(}-)\×ryӟ?wMd6|1µLw˯ZSB&47/9/[98 B 8ߨ_??)L6>OHKnI-Ξp9gA|gSʵIxuin6ܧTD29܈|10- *G eg@hDax627ŭQg. ? %"İ Ի"XK{NƟZ9s̙lVLdׂL Kn+eu9>ri d=صw"S0sʏ[V+znC)kdenk~QU[ +m!'hU)dr̅O{ݖ7?ra=^+w$VqY :ʟ߅tw',ϭK˰n]'4my'"SoFW70~)=R,w*Wz/-+܎C|<&n%O<9YG 2ל\KvW]C,}*~ ߞ&*_ߏ)טS?g;ygrOjUs~ - kNB񥿯XP-sn+T(#cr~~6Ϛ}[|< IP@.yimijzT~9ss 41`سpɑ/;"8߬N|1/a &)hp =(& i+%`]Nzh_9ZM^ۺ'WWKį[q\6,=PRG5D]7R쎺fn/Gj0W}Q^F(> g{'文I\Nc7.#Cn2ܹN#)_܀92)2F^K,a4cEC"~ƲUV7F&5qvpheU $P|X6-2A!e"6\qɗcUrѰre[2kkӞ'嚈kdUMC&ʣ?>!e ij%rrӭW/O^,I7[ey'xFNs~y~"֍_ 稝z|$eHoV&ة8kJys9㬓ŏ߸2d_ʠC W]eX'&I^Rރ&e=JSF!8ŜڔkԔ723U Uw{U#]qvS^^r;*|_/ƣ,7і7#~X9 +2#y6H)mBm'].Tϙ#;P9 ҋ/Rlf̍,{챇Vo:$q&T& yG9RY,+_/b>}h2VL}r٥x&ucV$\gk6E3 ~0MX luRw:`lP0OkGoCQA꨼Ж\ޜ]]lܸ t6VYp7qsz]NM)O0 :j[Z]O){7>g?֯*u|ۈ;Br*rUxj&ZReڷe+6w77㕯KcW./R[ˆZpmuՔuܼTSgBV\*6|j="{e*\s~6n Y |Sf`ms߳&Mho@`(ZHټ^ˮJ(S38;-q$bV|!4<-ڴٟx6ǖuV$,noz}& )LL k &-]p  G7TV6̧L&L ӟ??m!"ϫ-TbijTYfBkͲG|+\|uXپ|iy[/N>ꡇ3!;L&j<(/ƵdF2O`.?imd5|A99xXБ/.| }9qeW|o 7TW{s{0|T^V] M~[%!gJ>Z S}&:v%Xm1$#y y y y y y yRT^.jn9ݹ2k_k˱Z*g70m|gS|C=7sCo<ѩ=?V~'6UQF!ַ~$\uKtгY{|>߳֜ě<<<<<vVw6ʲ$'y y y y y y y`'2DK-dԖ5wU%M4ɢ=x/gwtM>|f$̀Mu@@@@@@@@@6mUIENDB`pacemaker-master/doc/Clusters_from_Scratch/en-US/images/f-13.12-new-user.png000066400000000000000000005763101217637305600267240ustar00rootroot00000000000000PNG  IHDR i1 iCCPICC ProfilexXgPMX`w9%眓sFrPQHV""HT  |﫺nW3==sByOtt8n{o& |~hw^ydOEƲ~ѱ`ƣagƃ8<}89Dc K}`(!`{6F:""j_1? =}|~QH\tO߇[DxliH?YiEyXڮc!ngX -Ͱ0{L _|l?v;4 ~8a4 *zX[>AD2AT4K= QLY@* 6!B$ qB($)Bd YA; AP<eAPTBU&tAF  /B !PG#,N/D"FD!{aK,b D$R)TG"m{Xd2YC!Y2 P2(-凊Ae*PMsjMBКhs:A/o/tO ÆǨa0PL*8sӋyǬaXNVk`˱wcX:vGq&Ha\)׃-6xQ&OƟ7Ot&L'hLBO"|'BD =1xXFB$1P$ <N2422L0|'Hb$=^IR3>iHee4ggڵڳ:::tfuu}tt ][ԗտ@ aa(hĘbl\a=HkcNlΫZGC 96['?Q|~iqN((;s2)S5ȂB¦"rQJiy?J *=C8f̪\|"eA*ܪjg>ruimGX]i=>~a \/l7F6694=hVknni9Պhop%K]m2m._W|}u嵾E۫nPou@]]nZqKVmەwX!dMݻ|/|n_<0o?ڃ4n>R9:X'*Ontw,+!vw'VNn` )Ei2%R3\e r%sZv_PXDy M -J*.i3l~5!7";b:cbntG |ǧU=> %Ň ?|"8my9 Wү&hMONθ72 7Kbb>Y&~Ҽ v|8ٲm? r qtEQ ht3F3݇N $hf-2*JZ{ZktJtO08aX`tƸʤٴŲf5gpӠ+uWپYo!o BVPdpUpF8-5XTGb,ρD$䒔}ά<ܙ5rSű/8~ĭN-"aP+v( ->S]v^HD\5~vtx.nnm^jt Uk%ڥnvwv޴v!NaOݾ{=Pwx3P8xihc ƺ}:kfZqm썹y ߖt?nYs j7u~15g@ ! (MQxF!QZ ]!b0o.8g#Db!y"S(6sY|bCyOMaN%3_BrUr+s? EO%)#T+l$ +*#L,^]-")E%!#$J@J'?pTLAiTX]_uAM=^CCQsUk|O]'=i}Aa1;63SsVyk\ulmv+o`\RZV^G~oyр `carVtvL]쭸 'RRoO?w0Pdfa,l#9zG5)K?!~RJ~]Q%JY)gЪʯ^VΥ>yz#oKܗn\A^uvxÿAͬ=^˾'=&?5;O}b9k1 @)\py S%Cv$xL@ _+@dC"HGd9r%:E3mq4bNK8<.ׇ kD^b.q!ɘ(XDecS˔`"5%;k2`gfoPtĕMny B5BZBEEzD}b-4@k('% d؛˦ʽTpVdVQ*TvRTyڢ1٢BS{BL]OoI1ɢٸ )E_6,vŎ.ܮnWNYhY◈O_YXH5ud{l@ː h!鎬AQD}4탾g{1Wx.[TBaEc`#n13v1i2Y0ّ% `вp(BC,D\P|V*+V򐔀Ԁt 9[rEK*e_ߪj!ښ̚Z={JuTuzmG Md9LP&V̿XYnYclm-<]nθ#JxX{yU{1 ಐa#Q)+qf ]IeLiYF?Wc'NvΟN*VwUU:\Xl( lbb׶k;:oR=ۓK7|?G O`610B« 7w?M;^޻ht/.+W}qwۺІݯg7_f#퓡eD\I@C9w0ژ{XK. Wt KǘdLb 7SҨ, p'^psvp>s7/[QBHWX]DETYLI\f(-)!&(ɑU+ijkQOD ^ÏT S_\V'Q6vfnNG\\Ϲ;1}n?o_0|ʫ'1E F)D7݈7Mx䑼(;$ٝe=v5bœO. <<Quxt-|E#wSmPk%Ͷ+.WG\va\?7x>(2T4xd l3/S_|4mlJmZt2+Ec ŧKe>}TlՕV_'=ڏkkQks?>\W]`Hݠ2wMͩ-խ[sǶ'ߵ\n\~.ͺz8ـJo?fRvQnbޥ|^ pHYs   IDATx}Ewd{BHI D j^}]T. y"ԇ" / B$@{93~ْ!9̜9sf7Kr9J.B<9 #8#8#5ԩSSp>f??q{46GpGpG#D2?- Oº:w>xpGpGpNt8E͛7khhٞ -GpO=T|2dȐ6\pGhOgr>HXd˖-k/;"?\u&)[ Mmꫲam0tLz-FclT*l.wG`_G`'ŧO k7ŋ p EַnmXt>jjjd…2}tcֵkWuغư7OӔсRHڜ1czzpb2u6?>׊ڜ9sڤCԫw/)ʨ`]R]8edwq|x2s;޽<#8~@믿g:pɺutVN 6L[4MK,?~>}Gztu6oޢ֭[:th9]6f$7lx#8:Q]'_ߦDԤ{h ٳ5ny&FE$v{ȾAr} YuY0kT\ ,B +s?wAS#8 K ?|؝PVV&qioii>o~NDka§iY:$cLStؑmҩ>}nQHjD iwyڥnk&d\vU yW:=zJNcj-rGpe{zٸy^4@ZkNp>S^ pՕKEyQNKDo"r8<ݸN.%ɯ\ +O_l].Z~rs^8#GϚ5K6n(cǎUUN Ϊ3p/'#^yy7d:Q ȪUtz\@/)Gub uZhcը*LS:\zCy5!0մ )Kdl;#V@rGiwT?$VSO*3]*=IM. 3m>yilքlɱ\+Y7dfStoxEn,=|} ;=pypB׮]+'x.Unt>ȧ:!Ň],Cc=V~iBNFh3~ nVo-&:md&f.R-!RŽ;}dL烁mϔMiVӯ#5^U'[ISZiXRHHQed+%Y eX2WW+\>{!%]+ZjOoœ7̕Ƞ>7[jGp6H6bImBbrYmDʰBol8 aoCv:bX?O~7r꧿#g469Gpv@+ۑ7 v$icWuӜM g",&v:M˓LGhqtXϘmdythM/i7j~qG`?D[Et-aY*ږ,~bfZKf`KߪFsZ #]~V!k7Vt}]qOP/CΝ+7L"<<چuěG]hٓ#8{@II7!rl逰#$iH4Ά(c̽!m\&EXDу :51O]%'ڈmQƘ3+G_8dP7N̫GoHQ6b˅'=Q1oʗN'lzQџ^ة_Nk{83?t^}XY;w1vZN]8#pkxog?vF`uE0} = >uY'N2L: QN uY5AŘp0D eS+p"COOxqj >HS߯a#k/2LB1OODR,BH^ʹӀa(;xL@l؆I ypEࠃwy' $$-c[bۜZ%xgC3f` fx]YwÜlb]$0ӻ/آcd=:"\C&,#8iQvŒQ1"nj=h4L6kjRP#*E*n7Iqy7(ߐ,y_Yz#$q37Gp<z%۶mӣx@}\U+EVhsKxT-Ob3 Ib4ԥ^t"v0izMg@LPӚMɓӵhqLԡn[l.sG`_G+/xS'| Q7Xښ%i\ùA_UNrrScVfzOda,IaIQ3/mB+rG;ȓ:ŋ7;Қurv[bR879Okq_8H #\"E烤Ğּh/;I_xmQMzRjY2ڤgז͝p#8o'N%XGyDN:TSR™lTbn[&PcyD+U$%E鮓:tw"ei w)iӎ#8{vlˉO'9QeQi FCtcӦMxD\6Z6lf4hnۤE#m1pɵme#=jusp6pl:~7a:ZxyGp7: t:iˁhڽXvnj͚5m>hƛ6|,Ն*6Gؗ g@vג;#8#KH4ќӰG㷊_GpGpG`hs Vn$봕~lk^8#8#8m#f뻆#8#8#8@%WtGpGpG | pGpGpw@K8#8#8m ,<$g|'31|믿. V<&n;w3FoҸ恕{^icY٦rGpG|#Byyysa?i/udHumdO;7=#J9:zSJKa/OE|Yfܹs-|"_ȗ('_\SSe|r1Ǩ#wa_"CCĖ/ؤcܽ{ N#8##+O`#}Gݞf|r!_!'l1o:ldÆ J{891RJHzrdҵkWa ۦG׿U֮]_Ç+2G~18TWW;q[b~:(97b{cO#8bO\9Dt; ^w 8#8n#@ ֩{ vMۨVYYNAs$0anUSs6)#$QaA=P͠áKxR|;_n &0`%KhSM2E6o,}#GF'3C$@P:m#N]`w>|Q&%Vg啅Y^i1ate- S$];gOmi6u{x@;6W^~e]7 .'^zII}K2΀,sC:$ik#ɓkGNw.q+:tk8#p5 uj zԂ44ۨb 7+d5n.lu'.OsMg]ٵr*߶#'A7)MhޣGO86CrkeNV,JYqmr1$ # gGqF=#bk}pCxpgxU \,AE/s 't.ǚ9sr)#= :a/7زbQǃ#8#UH:@?װCK@zJbY ]Do%K “C|.\ #.NJ<nӉuYgъzyfv]V}e LBǓ*w3]DI4Kyϓd0m͚꠰GϞđ;!\x4C&|c:t>6mHҬt. d9\Y$ x17/]Tm$h/Ͼh+|Й`8q=љbD9Kr̓De}"8O#8#xrUN,3EE 4UXRXeZbM ed[NƲǟUi'9|Hz{7gQ\]o+ǞzT{Sn{@d }?Mkp#2J Al"ukv{/%_"{nk{7

iS 2R˝䞇u5޹-yìKLr[&7<)?i}IaPkh_r>8 fŽtaǧ,+ Czmg_'DIu}'B6mI˨RR thkHGbt@!ēl,i]*ًĜ[=8#8[o`r zCm x8LrZ|YW5#b{%WdmR\I)]Iv7`1Ջ^"@m$M7稯ѱ9"L]xo^+&*~iA'~NLg.jehzCwԻ\\w񇮕 uG CJd'8D-t@K0)g@71R+138i[ 8#8oyH!Tg(sN;[ssĉ7 rM-BN.eXm2l8Y9dJ32sj9!#b&i؎e[ghdG%KGb29:\Zř%:bSǃXҾ+W#G=pGpF;10G?2R)blh%ANLELj.NpRݏNJGf@&cyUa@ԙKI oc" i{\~/I35H8KӺuQI)HuQ`40†)"\, bj uq~WAg."svi_z…7_TH.v(8#8s_'9*@JpBhH+_|2!ߥ򊏅κMvo ]ktsVG@|ո#f@i2}7FreI981)SYgkwMϟ5OX|FѲлdvΠR5|t \i컡"YPJpzu[^ү[/-.}nBǁ8CVewa ]~<5{B?pVMQM-' Xpp>88 ܍^3M[3 Aps ;P ~7izq Ř\Ux 6Ca"CEYJ&B]|JO>x0M~8] ,c} LsF$_8=aGpG QܓDi6/U|.ʢ*Ǹ)7+dp+sr]Dy$%}{edʬYn^DUeP^7o:FMYn3 lXltOAԣo:ǡW8sS\ d rؗ Mh 8py&v֭d2@EGW 8uWUC񟊳MFg 96:tF,:=z0•\ruLJ5GpGx#DJ!0-Mpz:t8vɩP _0

ץX=n8}E2"v4lo!uX4J2E}?"RgeP%|0brMy.z,§lGpGh/G'Ol)9T'{1ұVT IDAT\f%чǕ9;c$a/ˢYVy\5]koIɢe)ﻦMeЮ;z6J/YD_ҫW/8Nnqc5F/өhG^ZpС6} ҄ g^ ~dR  u2r-_G9bߌ~_#mz/=8$g2 3K ,'t(QLiܙxspGpOR(q2RK.5u@ז|a3 g',* %͖2? -缻Edb9y)/5SUB.rx) Io7baG WǛ%)@,v?q % h@ t@'=!Gy7w3gԱi_@ u=TN=A҅ϧOK #Ag3 1zTTT ~GPp9=>VGp >ǡAȧ2;Q|,TU>̈i1.-GV/~{e9ʵv=y̮9wrB7oG^y!nYF 4ҥe>d f|ͺ;7o#e裏W_kʡؘN\3pcM/;[#'|:q!1(KM1s~/// ұ8#Hg%SјKW6!'I^|̲Mi?r駷vhsdC#v$M˦eopGpvw@|#8#8#wy8#8#8u$NWItiԩ:l&Yjs}#i;(eprkfI垏ك*7Ï/gtۃ^pGpԯ]en鿛"]p nO,^3K- 05s1g|d_{?r^s.gU/ 0\‘9͜)7_;T9i^fǻkӂO-9BkFx[ordaw~?؛ -7GXjV?)W:S<^kl28 )iY+C{|GM+%6Z1|zPyzygHyW;?Dɻw!e7Ȓ-|L=CWmo>*g~[|K;cdztGfٞt8#8[ 2l;sv^[㓥 نrbp`fEAFMCNEkHUT("H'_&wK?FɆ%K}n6MnTֳ kkeͦV)Q"5k&}ϭL]&$|~d5U~7qg&Ҫ L#4ttYI=(69^NmUk6]TWnLm݅ Uv<04w`"ޕOݿ ^"LL$Fֿa7}i2uS6>/_fo4Kn8잁I齓|iσ#8# F*dZ[u?N5u2śk&s &'n[ wG˒ Grr7Ȭ`d?+ 6c^ $.7+-_]7s`fQp}=Na%JEٓal-BG[N:?ǿW[;م@N ^ݎ7o[ cd}crm7o婢r'z<|GNk<.[C?>_W>{qck /\X}m _=C)exlenGg|w*U$+>#++]YYdu -q[g,{. k^}L,teu7]_?/]}ߖ7dSe"?ɇN[8r~S>6Fy؏~ݾus.T܆"ɗ&zM1G%/oeΏ. ܒ-&뱏$/-_=[~ɥB^-r̼~Yv2o6zmڏלYR1mo9>;/d--]v9d]Qʘ97yop(p]"]iye}^\; RǮ|C!ݤ?w7/opץSKoȔ@wl#` p s~#Ns^/3W&~!ٮx' 2OlG_ZQM4R!}eooS:F#GBLi2Y$u6s/ûrfHVm&̗WɌ'S03.o["e$UT.̙yERR]JN靖ΔTW)&.^3O<.3f21v»Jz /?>QD&Y #EЎmErJQ4|8?m/Y&n"+U۶KNNDN~zQ >%+o0Ce$qxx\}ťs͟kuĶTH4޾/|RNggBWv9mQ!>'Sz>C{/L_2 rar|/եf6IC8L]P8ib'd/}Iyĕ(LrGpGୃjVEՉ;s" ^`d: =J.-zYy~rHt.G墏~Z}Aɦ4w,&e##w|A"Sї7Kw<8[U+tV$ZؾZ{*79_οdL}l l OyEl|<*m#. (VmZ/kꤺrT rsWdyi"ee5mg@cP͆VozLo^exnr1ceᬍҹקt.߆BR9cc| $\PGݾZV!'"4.,F=rUgL[#_YN/}, d+7dk5U%X*ŧ//4#8].WIM!2#_k6m#1tS'e,HtegUkw6.[-U۱?슁DyT^#Ǝ#|=QG6{>ߖC.c1_>*˖͖יmBir|S]llݽ/wKGpGMB FHM˳4CA\?}>T_xyxrک#us{[ؼCv XLuԬzJG-$SކʚTȄa,+eӖS@9K}e2ɕ&^7VF)]p5@G5SP}Tكl/BQ\Hg.:gqrcCzYr[&01陿 ֆW?m[qyewuzPO7@shP˙d׸܄ ?-z&F #[{W<$NxVN^( A*|_\y2WYVVփd)9q W-A7}^x *I vOn+ 8VV?3y❕>8GrX5OH kv̅k'ާd;?";䪲2wʏI0tdX79&Y#LM.|1r&xn*ǎ|Y-2_9B9?'D:sB%erd_N,W^u}5Dyc6s-XmǯGpGx+!'g|}r@&ËH~2wp-^=.+:nIr&ʠN7XO(1x~ɏQBnԃ^EN:fYgM\/SzSnXx)_.', 9[6WsPw;ܱW.iGJÐZ-~a-^L'JفiN1RZ,EYkx_ޥj$.Lnl/^&gΔO'5X/Vjŭ,X.5Q+l5.Dm!LTt.:ȔzlЩچ'I hwd_IKu,Kzjs[&W,+ʅ/Lóؑl\Q#TtZ[{c:|}DĭZV<{Oxw{ u|I&+۷cQ kqWi lT>^*۸U+ '5 WZ]](iD_륬{w)ɋJʥs9 )$uߊ%RVM)81O(gm)NGO\SUʎ oHCkIN^r%s~tNIfW w2@b_]ȵGpGCȔu’$Ƥ''&۩iuq3?^]ƒV6mMNT#մ/z[C\s.2o;?$o ˨N]욘#8#+k4?w+ Dr'gNj: ?Om[-j`X0{h=Gu*jxvI8#8@f vtߵhMs@P|}؎#8#8#@ >M<8#8#8@ )Icp#8#8#D|$"#8#8#t8ވ78#8#8,_wq]mߎzURA2FyBΞ-Hb*>$LjC)4+VAOI# tB7,(4#LJyMipjV`BM*䵕FFƶb{  <8#8#_#k]_"1UQI:6^Vgx7 i0mA;X:2MN;uB!ca~dyZ@UZvUak)xO1%ꄴ.+%IX[>#@ڤFD,O)23)U xG}Z:T BXf5^5a IV#8#8~@&{A0$$e `8z7`âqЪ(2c֍r>Z/Xz-0T<.+ fE-0IPBMZk&BXj"gZI;EUKib@އ8nUSW@RᲶԉ ka@Ocg; MDvuS`F#Jv/YTdރ#8#8@F_oM$rNtv $*z%]2* h9-l+Pfȃs @ryJY6#z6Ŭ/5ڦR * z(kͦgsdJVd b;tVtj*Lt(j2js9ƴ eQ@pyTд]p"F>G:,0d@lmQa//U/#8#8]y)cԧ$|jn\7"%zJTIKA)I:=X^(MUSj2"-E+b`Y-0Vay,mkK̮n7VM5IwҁmkKL 4.< Xj}d:{pshC{ygXgny%30 |P/ZGpGp,tQ@`A@WIAuq4r'Dj%"1z$eA׍0 ;@Z$*.$!EyXg"h ($sl_+ZkVuc6GC*_L(/:P`XʉOŸA*Q2 ]lөtpO@ t!ZVGGk(S4I,&{pGpG`E >&]$1T+3=[f#D:_䜊Hn-'Kcg̈́>iu`,PvFРU5Oc9#?2V7֌*ȷQo#C@|k64+(fH7ѸKӾ ;H8|( 6"Q'ɴ壉ƺ)m8oJÖƬb~#*$Q5Mu 8&Np5x ¬ag_ Ѵf=8#8##`gd vS$3R!< v ,'.S1@hOk'6i>$_D>qhg JHǎ7OQ!־2gk$rM-b#J/b_З :t&&ꄰ>m $ 2h*1tRXH].b)ȇP9!Һ'[ըbނ'GpGp_ 3 $\A )K⩎ ,5e#0JVo'bqQ^f-O?5ѱ֧>4M144be}\!͋4,̞#4c,A֠fzIf` Wo1g7i7e+@EsA>`}UGlXꬒHi/#8#8=1KRj!R(i%#":"'ID-V TVqO  #`a'l.벜d/&LWEa!4+"25umx>2YBh7ц uU'tmR\(c~D0664Oeuu>( ELBqJy:x>OoW9Xe{H3Qɓ#8#8+ꀐ*%Ø*OAXAS),QmN>#|Ijr+ C%er>7r ѷ:P2ۏ2!qvO Zi4U}S!3+&Bj(RP&PX3eGh+6h/Dp˘-~( 2\i1X5m%f !'ȫE=$bK !.b5XK*㥑R6-8Iż|,KP u6lBzitXZ`ƫB`[tX}lr\hըҚ l?մ'(315C;K'4^~m*?6TP͚",cc:4mR:#8#@,T9"ґHj$ *cT"KhJ~9V&洤Q!ri#ֆcp˭ UYtِiA1)#몸bB(SCltTӽ([bB+4EiZfgFUMN5B"<@&cTbk,Yv0U-ydUVG U8_t?*&skMF'S:иGpGpUjHIf<ґ {+-|U"8B^޹P=[^ %!P4Ucv3XAk1FI|1A-h!k,QLJ-0KcL6ʙOVA&>S ?Ě"|ףUu(Xh!YMi]\;gW;>hXOVeM+>:L}q1o`0DpGpG@B@Otp J8IV$$#j:p3c2j{A mKhT!XkV2X?n d7ӵOam*AWR-+Eњ$ V!*76*eom=J0Ntkl!&scQ/ m|%(na,N'%Ә[txX5fP; 8pD:/#mJs#8#8~΀6`G$)DFbCGVJQ#ĕ&H)Sy#6ܔ}zZ m$/Z%4m@MkR:31DW.bAnɼR zTsB|^28#*bb φ4VHb:Y#U9/dPfLi/9Ki'|WC%˳ qqv<8#8#X`V#$B/#B }_# էJdI>a_*q%L!{ڮMruj(b0fԖItXo3rui- B%n$?JblBGM(1:ɏO;zj6''XpD>SqL,ZAGyPt#/dc y-Ea?~qGpG8 {@w*UO +2b6@ˍHT,.JY8OT2k,,:TTlĚ1lp]Ձ0tB"eh"ZM+K!p3c:6Jd~}Џs,ؒ*a"k {q^ HԉuhZ:P9O-Ue5Fc{TǾ!:^tvјGpGp,j>'$3Q#JAL5ca[{B?$KVtV@VWEaUSJ,aI&H,51CгDQbF}Y9-XL1yE3h3eVW:&ʁ:t,&Niu@p:%vYSa0D Wv ]}{hسwfIGѢb4±K!Vyx?Q_LNGpGp2J .٦QdR|d\%<$'I4I(?:ہz\EC$ 4^ FiGjeZ4@3/jE m1,ze98!4ߊ$|S vcjQ1seVsGp>REt0  '11c`VP* `X\aiȩ#d+#\Ŭk!~PAm"{QGpGp$t%(т6BB*CL8F`IZ]8 Ro66A8tIm W&LhCzQ;ڱɼհ25Ϧc>^7 y Ý@m:,˫E\vAXc[eNg? AtAЦnNG:vup_,{z&Lj>+X̔z KPQ jÜFڶ@лE]̄4m}:3H7MEc;#8#HrE$ `tG~('DU|7]%VJnNd{CtF$HZ-F!X}67@iUQlj̐`|' e0T9'qIhX#A#8qC$0ITyƱlRc83 ـXSMM1* Csp"mZ)EfO񻂭 \G9_GpGp(12 HIIS/*22FH"m_꛵UN sh9@6+ lKX %OF$j+UW顈A eQhE, 1CABGP9|pGG 3]\w>P'b;wGl?FA }p*С]q#J-(l).=B}ģi2uBR!KGpGp(&t#M$* r@B@I\I*\*[%)kPmTd- ah!)|lu"9tC`]E,`6*h [Pr׈9vV3:N¬:u)VpPto:*#BEӮhGB溱 VlSް̇=V(>ݐ\8Wa;C*|Ŕgo|WI}=b:!lۃ#8#8J%C'd#~00O MzZĬȁ6FcY jڈ}N[IrV&<-tVKb1|ui[`/dF:B+WNLf\a\ I.IXEGpGpF*WǃdG ,j-6 rIQ1#^CIJVd)3SXQD!upHl!э:,i*fFɒ|)1$e,dy쏊X&8Hh설uu|^ c&ű٨L T4o) tp#60Z=2"(} o hf## ǂY GpGpH«O,.>JBy!A 1KM#44ńFN A5Joq7E;dd!G__znCcFkKʊeիeI.]̖d?I~}y3\Ӹ4 cB& 6,Ob~p^a˲v>hM$Z3HCaJ zZ b {S΋oE qU$EIGpGpu@HuF_c*E'JFz2n!PO+.k'Kg"},[Nsr'Β+KL̚T䫗)C#+l_qi9Lt20*vǣw- $T2 y=jUh?>i} ڱZ2sTNtG4];rԂpGpGBJlsa)D1_pLyi-S.%_E/Z!;m|cgJ~=OS{͘]yZ9yOp0.䉧my؆M[O]Yoefh.Fg+Fq5bh2.:蓰2 ]I}IV)+!,D̋I(]5 .Q8Lv= WxJK8 4Apv6Coذ ;d IDATOtį cuHB-I2؍09 P66 ShvR|qɜM rfA4hu 3|XRpTmskڒ]͛o?{wauwŇ}>>GpGh8 H IdAaDe+ Պւ%Z|"u*ic!d2wR962KᩙAФa]~M^LOِj#ʦꜽ8L gK^[\3L>}i3e rug@&+VO=37fTb57c?KJHe;%X+Ĝs TjcUgv7*1k} `kր#q|Y77h`a!6蜛l浃~7;[u]xU=>RTE3#X{mclm˷mj]]?xXF I6HNJ.0.з~kGկ/_찾}Gk}:^Um++3yd;S2E E E E E E EEAEMQ=oיzHE=ϭ nSʼnߜߪ!%B+ Y=mmL_冸s( ?a e ($x8oNCs#7 :Պ "d!"$n~Mƕ;@װ/)*/C`3`T`9>LNc>#'wmo+# ~l2ӥcz`f\u PwpYg]ŝ5\nzk޼y_r)ewy_^TlemVU:^@@@@ E1E$!)<4=z0Lvv21Xxzi{m̘죏>N?",b.m{޶JWF|C=d/}=soq־}{[gm7ƨ\;>v]w# c'}٧+#>Ċۣz'|b?ߤI<ࠃmF;Xfje~y㱨p^>))))41 Ә*E VJ:WAЋH gzTSKheFs c`HP ;[Lv'& P(#䋅jХo a9H|9ZCn8O# Vm` !owX[PR9|P!gKMH̀ҼTiX!D`< - gH}5g:u9ҶݮWOI|Bo[u;V>٩R$Q)yᇶNm .([Ì mVvYg֘Q+;, /pD sbnmJש6~}q _M+lxwܱ5>yvDzf3\=E E E EOb2C!N*)S'`2oˁeRPpLnI&1C8Q(r$_ :rAA8:DȪfL;0$G1}T@@S̢ੁBZXAT1Ux0'ʠ"PNY0蟋 ,jEsaa2Q h?qop28((Ӟ>3z s%`o'E˴mjJQI`8uݵQ'/ .[q ǎ;4/T {gosJWᎪpR9\W^}o~ʱ܊|:))))kx4d )Rʼn38"qH\̄h xdyH2+}P s]TOX0E@6NjH\ r*"D}NYZtpJ1zb)B}c뢅$,ZAdd.xU(~JK)P4 M,|X{ \inmKQ5<y*1J|cϽj]|D=ՕmTϞ>;Go}7fs%om{LY1bVζN"?7cYp'"E E E E^D 1TTQFH~$:y&?Nr<uEhG/LYrH5Iì8!9&Q(!vJ4$ G%D<;+D rL%TNq͝~0Z:*0&d./ 8`3N/We|+XC%\JʃF{F&cⷣ.̪! ҿw7~U\ܹsܜD\{uRT{f߾֭kW[lP|hv=<}ֿvWo&cRxǖ={ZeQ ڏ?h:yO;,*@rViN`N1N|%EʷZzﴓZ⋡@&~4{1{yV+r܌em?EA@@@@@6Op7ԣ DKtP'_ n/)/D}qu yJU3  \HeGr\i0x8dA$>1 sk(8A~,ׇ?^D+&ҌQl_le l 9:2$o5mtW.!V[m5h q_7"ͻoYqko\.OnԳ֡C %=lLt>v O?Zd .7xr95R;ψ͈n<ߞ|qVƿs=<"-7d=zps2 WiAl<># z0"d;RsC<;Td' 藑s #ݼ.c̥y#(d0!+A<-CG=4BQAy.'OdYx~trԍ'G6$ƛ/=H2=Uj뭷*[|P>}n3ހo|ֱ| g)W|kGSfGSsIn: Tnp˿]D_X3\pԫcx9*9DR$ R4&L=at0|Ό |r(,ZT+ȧSS.Nb!$FEʓ,7`o`'pf/:=҂>*-Og,Kd\C(ܔX sڋA.QBk" ©`4EBD }v87L;!0v@m F= X݈V{5;opӎ;V" ?|*-JVD qs=gqW4!V5k'<իg֟%Ǘ]^|d.=uf]|AȧU|8))))& [0LTO#4*}dHdL327JPcf΀paQ *VbK,1AVYϹ;jvߐu?E7rWyj{.ZlmmK-ecǾSSx>^޳7¯ZXEEUo9޹=w~y>X^X*(7x#B-uΜMM&B@@@@߄eR#0fĒ=tE)|OBܛ2ZKY± LdMOvB3͐q$W|“(Cq p=Az*z ;G6CE-&Dz[Cu-t BI *E+ ނ7Ԧ&Q6tț⺵-d#?N2YZlu?cHNBH/fKA}S|#nȐ!vCp3gƯ!xg*w꥗^1x`];c-ٖ\r"7X.r0 RRRR]!TVx-NG$%CEPI&ܓ]f]/ݴ߸SiLy_L]^rZ1 mS7ُzL`f_z!6uz  ht;1ĉX2Ύ&?WxIPq%GU 2#AW_W] m Ňo$dV2Uqܣy0 O_}U/D$?\(wJ9IZ| FoboWoZmNqN'!QZ= 2R&)r4 a*eFZY`LJ $ ŇL]D>刁ow1dA; AdE/W?m! n#>jK3IT}Y/Nuϐ䰈y϶5Mv)STlѢaVhVZZhYwVsr[/riyZ%xV;bI&߈l8QS12xAƕ4?B,+!SRRR3UfcfʓBj$|A8rI?ʈ= c@ ?WvjL@1Ly@:J|(Ր,t1-Y}1aYQGS`2/!iWrO4\ }?`iODh*o7+tυ@'LY?,R&uATgHu1"oE2qG֦M"|رcm첕Df6ʵx]wrZ.ce3\P$|N99ǙwOTdmWX<~AGc;ܰaOٓÞ@ο +@Z,~&8E E E E~Fd"Y'ʐ::YŞuJ {r *f$؏P`q |A_ Z hma4aKQKF;HcNK$5/FbIty(ӄ#dO+8^b#7ʓ&~*+ O,T+-<Ǵ=yt`:[|Q;_J6~~b&nY,>{IrYm,JۿueW-99Ǚq@i{*\L[nUZOh#7"HDG$WSRRRotBR3pt'L5ʢlcDx"@` dŕH6l܇f;G I0\m&|j]/tLoa N`%NR橛 (>nnjC#)I"x|`"(q B"jL)v}G(2Ѹ* - :E]5I&bw֧Eq>uqH,10d(}i\P֭e+;ʽT'm,>o IDATFzG7 qK~/mSTPͳ=y[|3zo`n6nj`{̭^[#94kB賂|8{x 7mN1ꟑEY6vεշ|PΕ_~vroس/˝om'VY n F~Mvv=m˥O+oznzC87o Ypkh>`ԐPcQl,\ ~T* R#RS$ ^HE$>P>Gߜ H0{2z;^V~ )Oh^v,y~}J+u*gVgG–^7% nʣ^K.ɳ<)^L01W_>>91Dzk|뭷[]ѨXXb {G]veEXtۼV"1 tmgDofźvݬX>Ta!XĜ~i9Lp„ u-7sjyNV!w߅jr%hv*rkQJAjH)))) ؍I1s|! ɿ Oߋ/HB+ *.md_t r^6|R#g70r;m9*;}`M^vj=іkvBkwv}o~}.}]iMV+%*e%7|Kw?U~>Zr\[6]V72q~\fU% 8) K0H>Λ2Z'RVR37x&/9#ȹb  oEWfbmb V=(^F"6~=:>[mqmO?e|ÜlIq۶mjef;%x:umZ&My?t(9q@7oSql "#O7msr||ȑ#l=v7nwMC ?"G>ms{#<`v*}]e"E E E EDyeB2dD1JPQon3˰}J9szkLIq֯ppE9[B>RkuMYdiȆ^F({Dba!*q&+ 9ѣ~ǏN[6_bإK}7 K`6h{}x?dTvk*>N7Zkeύz֮_{ァO]Zk{igv=UH_׻C&O>8{=N4Y7sUa +O|:DFpޓ/ZS'tm[Ľ5!]j'xA<9;]ÛڧV͛8^źo9ٶV˚))))4*ѝD'oFL4q HfdĩNx Xx߆DdŠdp)I.&~f~xp;d\O[silڞ;nb>mJZr3mIHZM_~lܨ `sr[e468B]&}5i֣jv[}b5z^g^$˶mb?+3[FPҐ0XH @,tju:(yڒYxqpQHOn ?κS#( oB)E E E E E E E E~D{B0u?(J>:VF@"U Y`q(oo,-# X_#o3l\vAlzH.=Vrř#Oat6L\܈ }EiktA7=OK;_Z7U iCc;ou6l5GN7(@GH1~!p<'Ӫ$ WǸJE2`XzGQ5HBi!!O9*W=#"}?Os:=RSKHHHHHHHG[11 !߰X`:(|٣Lo63Eq =>NյW2^ؓY̡'?Um颌eCYf<Jdyr,P?B7뺁+4+Ɂ]OR00By\j))))))))" :v9)!S!Dw0w%aߪ( p` acV0P |&M.StЁ9ܠ.WD?ؒ.^BLn,:`c,9Up r=msRY8WH~ ٶ) (=%KΫ Qg+ r+r/M8S͕oVww1 nSc$n[xn@s~ځ">>k)E E E E E E E EFz4&/S4xd+#ld"\)"%dB 4K~cԿrػ7ء )X(Xe&qn$B#M=I.Yq|<:$A1/a\uTH*6hUe9X)7"8˨Ij(@ԝF\(|ۋ&lND0))))))))"5 Մiz+QFNyʩވѡpB :(8"M0P_rRRK96HNa8‚ Z8KD'ɹ*s#.U,&8!2tAh @^',m找k+$h#5$B2.ċQ P?i4'-Oyas@ĉ=Q$\a< -6,T? 4&<G{4Kf1G:ԃ)XxRE_mW `LD=ՍNc֩9V!Ie ``BTQ=qh1YhIl !%xb ollf"_F&5MzHLe@'H6`]>lp u @1%Ѡ-@Cd1LvJcd x ud#4ȩdٓMRRRRRRRRKfJb*1Dɤ"iJEr;:Lýi2FRNAVsTА# =M/+ }*#-SGNX/E+| x>0y竸 ԁ/.AquQS"xe3e 9y_)EΓ pt46^K|/0 dMH"Aě0cEN4#}͡N i]Px"IqI@H65iD&$Ύ0Px HNwz0V()L)8BN$D)*F?EFov7}g16/7ҢFy"cXBX#C5/78z95/>I#gOF9FCSKHHHHHHHhdS@: R$I;RYRɘ,*de^hA &bqI.( /SA"6)e}r\TP5P |d\Y48#4W :O#VL MdfOǢUhieK3.*lU2~H hQfMAޯ3ԅɇl^PT>SyR""""""""g^D)r&O2DCO@pHǑՙuikK=Rt3ɖxE E E E E E E E7X"Qq̅Cb/5iLH)⁉pVXA{&/2q;5P7rv ;lW[pyW. Mw0VTG;gRFŒ$C֩-k=+oODURSݻ Ր(:A:d̏5jJ&h%7\ۇBS3bԯRd}˙scSuOA>\`/pZ|"VU`hU<1u@}L/$s-em׵Z@@LWb?v [8X  +8brKu [yQOly“hzfDҹ'4^7v-Bx"(@ ίJGa럡""""""""fHz>X0V(ˊ"0JMh]Oo1BbL\B29@6 ̙ %!m6)6?W)ڀsب1ZKZFve֮Mc%칙uZo7ɮ);j` ?Oby;bNW8&~lom>2>z |iǜvGb omі\|a_ƃmXЧ6-V YםN ¡3BODQ)eWLl"?kP @XBh,(։b0$K[mKtd/Q\_^~clZUgmmnw?4zE[]S̽lõ4Yz;OO滟T$PAKZ֍?T1s5Ų(nJz\> 'gߴM[ ۦ۟X46\{ECmZCGm˶ka*h׶uƆ?itb !\t'mStxt=x}t!x)WVR W=aRRRRRRRRh )V CBS. |z*)I,쬧Wȣ;RK@W$;Gm6vh^;n o {'Fiסsm 7߼l=/JǗ_`{v^Sg}11 kXșj= /c-2E%O_`m:VTʿF<>5}Ѷg_8~7{驫Q5/'O4N'vH u%x8Q LoP)^֩}`Q&tDG:=SRRRRRRRMK(АPȲȘ8$$씨BX=l2Q%E|e4f28Q$<۟n? z "`q^|e\| \fKwI}0پgmTkwq<˜,0?63Oۣ*pkȣ_f_~[V-7ۯ4 ?P*Zz1xu箑tkCRP&+WH(tJT2^ut0E0RRRRRRRRA5*#Tsu #(LRlPaHEs^1HP \"H)JV_}|8,,ڲ[{v'} ZZ bC&޻pD/<骍t۴׉vi$()[qxҧ_w5:;m+) @Qq1 09f2k#E z3Q`d۳:lzG]'MKHHHHHHH'h+1?¨8"+\ Q&L;ń߄WѯزUJEtԘa~KO}7um׳3:ݮ}z!qRqP h(f mT_9}բJ޴<Ѹ%?n]6Xծ:/h#Ea %w-өt#9~09* Btr"Os↮㭋JpG$69E E E E E E E ED@kP+ngicaql!!/QRhIѡƤU(ib1Xxt`%|_kU͛-nyJQzfԫq߷D;M==džz=?#h1E%+aCd\,1^xIQ~pKߖXlz %9xB:b|\RIT JNc1wbs8`Dq!5#Q~ ~)ADsoʘAf;))))))))"2OEBWnqɤ8G8%2kHit 2qHq/ju Ip;;5peãrAeU%ƃviUXpQz4#9% wʪO?92Yv]w E.F֢e^ƏoK-ݸ ~fp3+>Gff-9p6|lG{ORpqz%Fgg&G1qoF0"}GuH:ŭmynXdň ɣb#s,( p^ ŃCCJeN({RMٕ .+>9L@VS0%b Hռ'P,ͱZ+7Yꫯj;;/f[j)i} ꫯ7|cʟfڼq>囕Rڬƍr-g>Pul=^-p \=MfrD:&ɱmLlD8$YAxϡ>_\=ˋ/F}%"chA<\~#4W<,d6U],lO8&*yF#VJn, dRBfj1HIC[W敃hyٜ`T 1E+YgtIV\qE&ҪuvQ_~oKǙpɕW^elN9T׵Zǎ+h|≃Ytyuw%쥗]f5mܺmn7ꉺKϾ52|wiݻoNPkT)&N5Ε:u*8VZycM6aÆeyGJU~>\>TIǞZɈ~ UsCݻE|qy:Q_+}Jcqa?^]JzKG8M24$WnůR8E <)&LCBpX)cA1&Z#me2FdTڥbOT("|EQD'K8cQ /Ξ+G _uv(uۮP wC^v`Q&Qg) B/uuĘ{0V=`vt~E#~?g=38"^y{v 7 /"}ŮZK?Vշ~kxoH?y*olVY\0X{~A{i̋eE7|rͶꪫ0y{0N:]+x}ge}0-m]T2.^dɷ|ruy]y_Ju1Xc"tkDbRI.:P q!VW󭶟 |s^A1[gʲ˛ )[ .m֥>7$6jԨLV8U7OWgT}CxEm~l C?l,b7WkyWOurYSfKw grBPX$dy`5$QZ8yBU9;s&S|gŃp>V50XsɭtHh(:l:+Uc!"\W'v I[M¸CPn@>oL߽BcB y Ȉb1!9/0!φ"Ila@@c,$FA0/۷Grr8k4,"SvG3N?ZlqCd<3z衶 X.Jo߾wUcګ[V_}zʍ`}$[o5͚5sPx|cҴ޺B -dw~ 3iӦ۠/v1G%?7GDzgT.E+5ū&_ټ[7Q^?/gt^LWꫯSO96`}iy_JukUr}kT+W7xtvՖXb xATsP$AM9/q+D-'ߣɤwkԨƕ>7$jʾ;b婦yVg3o6<^g5{Nz '6^^W) ͷ]?G7O}Ë8ldIjHv'qLCH8x)D/Eu9Q ܈#b@' J0(?cøXVA +]|GA`FB[[ X̨0 %*}=/fOd^7?~% ٩i!ϟg[~{wCBT&yzmb%/Kx)\CބoQmbRNzYtVO7*رFY+̿ 1)oO![ymV$ i`k'K/ܩgy9ک!vl=H_B^{-7h#^8}MOurQw"0h[SO88; x[S%>(lFK:aS.RTT()ysG(PBB}䳭VΏIz"@8eui -^zDW㼜;p^iҕ(v#T-A1@%7sʿ ){8]6Tęgekd>7dbҭFU٩i٤f.s9v;s]ɟx6~ل+7tU 't=@^%h$$CIpi3&ЗkT6 E B~X"A$19ORO\(\Y/ zeB }>.iud;#gSD1/ _XГ+ B{B[|@Sug9scpLY]|$'bCO65l^N=p'|c5ִ6Ě7o}o 6lk?m&ͶەR-͏g6^Q[JTdz%mF[%8⟶nپ=IƎH$i#&{a}mxGrQ|PsFt *uy8sDF2GPAUAAbPT$ 5,Q=F~^"Y~#ʈ-s(myW`T@M:)) mڴ>}|+sʄM6"{|Cju?xS\k,i_ᩧfMVE5쓵?J,_EJ=Ǚ2] ?҃|Qr1ק^iZ}EC/!P'NOU-Uqo|6}8,ԟO[~Bf®#Ӂ@a=9ED-W^|9#8S$:iD X0,"5l)g`>E Eӧ;ڎ<av͙{ֹ;]*9#F`Uu?l-K'Onvy95j8q`݁?Lg0| Kȅh+,$Ǒ_B1+ɾAWOr#U" s٣h)5>ؠ1h=iC?Chv]qzXB$0|\/tdȇ.EwA'؜y$=*D`"$/eUHe( OLKh -?|-d^|mKϹ5~X$u? ]PfbL1/ǎG"V-)q&7 dLq@x[ k{ FO+$K, hkt ߮;} *o"Bc(@۟47ۨ!N FWq&* {|<~oyye }:.ӹ 4EN b}@T*Buj-NȟGQԅ_dMvjoOL}@@@@@@@@=ބĝCO*uWI<KɁ3aԭr7:6~~N'?lݖXl!qMd;m&invt;-h"e'j^TO; qPJO0Q^"lR! x!l` cH~ $/;/t)pJRRRRRRRRO| IzYLfhL@ OEVIGB֓!w9 1/'.$m*KoSq3:V;> <&_v+7e{yjמ ֤'o Ңyy~m0tȋ B^(HׄH6Rypv Pnf4y~ ϕWc B kV?s| 3^I: IDAT=5'x< 9%3K R `!zb{»Vx`܎$W=7sPQ"IhV@GpfumXWmi{VN]wjw}}p96^Ur}W _J5ޭwgR_h>XP @ٴj+:S~u_nqiMIw+ 1vegۺ=-WH5*[|ǼdwD< 8͵eO^j |u [jxx\H?~漥aD, uJ/s}-[͊*[[g?J񪄯i3+WDO { =5d(gO"xO2HP)= '!0E/:{b7%ݗ/u"Y0|Nٮx ֠~YfK}'O&Ktu־]lk>}K{y5vl-7Em*i =M, $\&'7Zq 0;IS#9N>nHnAnbLG:1ች. BN/ucߵI.O,4"*^2|Hh~Mo6;V[]1_J_M4b3逯8Y~p2TCOP PLX\`f!r#0@aDXP$*پvN=vNx" GνL`}%6Sg^w'Z#ˡ駟s5i-qNfgc'lҧSֻڼ ڷ_f(&ƖD lzҴ/ǪǯM{gg'G?FO?qHO}]Zfޓb׈-*N .|0CGx13|'9>ǍDT6,3|;l]m\%ꫯ{5|wyG}im2;Ωxm}_5 ^4wv-֟#Ik>'HeH ,tb$#`8Q6БF^eE7]G~7(B6od_O{Sma\v݃?`yypഃ퀽k/gO=϶趶M#~َo?vF5m1I>{oo_1~rzk8y5432PA0 lm7FX?:>`-gOurnx˞t] *BB!☸"UrG*??Yw]_ny; ظ5lu׳&MYœuw[VXzӓ1R>?aUWoIlwv 7_܌έ+W^y6rʩkWe>-ZXk JR\]uZie]s=/x-0#sO~ @ +3HTG>G3RiW}="_ڣڞg}*ִYsdS6lXVuȘ>F[&zR筜J:qc@fiEZEy+r /V]mu]ۍ6xيzq%9/?y+sGL6mCŗ?RJߢGO+_ҍ3"w^{@]PP(Ql Ɗ5D"Fb1{4!Q" XcW7;wD%(7s3{r?{`n=Q$eRȗg )I*>E wI"}3_ӜNB6eJGϷ@}EۼZ[Գw;`>𺁍o;ː,mN{X{mλ^ym"Fغu.fַ+Y .~n6.%\Nuo9k]s0twC꺿 ^J矬e;nFlxdX ڑ=bdy.[3νFU;eixм=9›7?yu-RL *"'ER}ELDbd+(q">/I8~v|Q2=({sCFasL_r@2dw=6rpp|onY]2p}6칡_#FԷH;ܶv[{۠Vp4ydO]/PY魍]z;c_{."%^~}5>kժuX{mͧ.9enl=z mॗ=ƌm]w]~6e鬞8fW#e>z-I{ꩧlav5sϵSڜ|NX=s:߰_z=u|7iY]ﶛu>bܲP^R̙!hm 5f'kQ6jowޑĜMkTj|ʪ~$mN>}geCzvj^Ujj{]ꪫE]guֻLJjY|VK>waG~3Fj]cQw%|){B&m~>e|4h*df $Y=k׸*$B3!_zd(*O0||3OHVAtJjwVMՖ-1$HN\z .n$)=  [K99Nj+r?%l}HكBmA!Q}]0O<\WC]@rTJ`5)jAHCƐ-LUᓠ9TS>;?hgw6Ɇ6mw[ncC}ڶm+[xzb5VCpqmӽgcF]vYw[{֭Z؃cO?0{~Hg=Zha, V[+`m?}EB;dumݺuT.WY."$;K/l7mO_Ǟy7tOZk?R3׶:״گVu<גރ;o$!mk޼y>9eO\v̟W_]{N>TowԸ>uWsesSOkaN 7=V8N:bli>;{뮅n;A]!ma?޺>o47Voz);>׵mkIg=k^Cg|8ٞzک+KCs>7>wenOyźlfocg{W_xvW/h7x=Sv뭷9=g@P"BT:5'$ D8vȒg/bNQ(Ȣ2*.xMh%“_( jZ & +^h>E]JA{PܙP~BsJW!%'c 3 >.,M9i4Hh@Xy."֥˳˴i*m%J+QL4ZjUٮhjĉ^U`Ƥc1vA}2S.=swVJ͕WN[ڵkgG}TN;hw}ZV}B2;6%X\" KsqҪkVT٤o,oH]sݏΞIݺuDyF]9>v}veMp-;Oq}BϬ9gNKkXW}`.SZ376ߺ9Cu {3kO<1Ğ}Y%ݷkU}=xQJ!TXCF)P .W šd":zՎkj|1Rґ4P+"JSލm e@,?D*5U;?E)wʚT+dajP<:D: nayߵQP{pfI)w׸Α`S4E #pŃlq~Bhu ^7xڴi#[ǣJlV'm"ꫯxb4 [m\]`p{GmY믿~q_YS:7z?S[feަWlv޹VkmFXꓫmsjdqʔru>[9V%vv͍ϫrjΞYE9&,cǎE49}Sֶ>;mTamqu,~~_x_־} H](iAo.USfbÏUٵ ';'ɼbur]wR׬} .})Wԥg{|Uo"k|}/wmkmXp? .r;{W3dA#cJň)%%F$*x`>F7RqK*`F \Q{[B`urt]q*m[&O,jG <Csoyc?Y lBo36ʎ;`'|q? sa:VhaYf>(^eNÏo+ aYsz .gaol/c=h5 P8|5Hsj 7ܨdp?1{f?gvkmtN]xvsϳei߯~z#qD#"q2(hDRC2|2U,pHy.R983`OT* NZ9p0d?0Dh&vY [@}N}v !HLhM60#TkSo a7ϯ 9H,=Ȝ)V#Q;H;I) :ѧ:W4#P)+*z]"* S +64WS|HʅlQ{l; {}g&N3/eT>b+q$^cG SkNWـo/K0TQ Uu@@@@@@@R S@$BԎWAOٖ`HRlxˣhE4EPv}%C@ꨴK$L^ah60꣹䢚 "*$2H]T5!s; fRC N6,O,R&}I4 |/,4!0 IDATReKp4o᎔"R "rhۜ\3<}~~`sb'9)Iۥ<&@E5(r#{ { { { { { { {F ΋dQ;I !xdʠI σ "aq>5XTvQ٫bO GN* T8cMJGD&bBNK$Up!N KTb;&Be_cPQ41c*W.*\|3((Q*IdcZ$䒥S:K@@@@@@@ Vu p,2gyg>yGH/b ftJ9  RʱANN?̆xμ&7nFum›Scq㖾0<2 ._G:0Y-Ťʟi`~iZw(tag=Ϛ\Һ7ء7X=83#Pkч($mb?ژDA˒ W8MJH* ^s{b?mmZl[whkkave|IlN￲Ӻmeਕ%)f;"4?uIܙh%6%k ݓ b# 3R%OÖ[f)Aݲ}6d7Pϰm~}s(Zlh)=@ U}Ltb3Al${e;I93Qaw e========Bgo5Ģ(hLE^ɾ-S)Tl2Lؠq\1\ty"AgG\+V dﴩS-k_q8qұڪM^: |≦]SQZy&hAKZlOTzn^;+)'> z.~K$\ l+77$eB>[ԑZӵ BP!9m ~˞lH޵=5Ϻb-ΧBiS1<8jɉwdll-XkCko9՞oml[Ӭ٦qZ5^+X;u[ώ6Zo}r0}shh|:͋n 8z "QчVb\ hsըQ#T :#Zce`IK(Sv{Vmvݱ5:c![w}mҿ^hmsm:vŽ'۟n_GvcÏ>;>*>c/֢=PAgʆ'öڼ [8޺w]:m{{-6`^bՅ=Wγl Y z,LL~yOeGfǠ^;;l mk[^[fjiOP7WIoOV'>ARl¢Q0^ԓOڔ)}5d|GXhIӦfFj_(LB0ΣH<4Fp6qJBxS'# mp9DM5-0CGِGr-i^BU0`ҹzմҐaJ@LEoك.U:zW^Q|}#Wcel#Ê VY`>{t/EB 0_"k K E0G^ՕҐ[ÅKO\d+5^Zݶtk+ m4=vϖC<Fz_l˄әm$bH%MWMդ'uS|'x{mmU<9 z`:V?c"-oZ.nsF 4djGmW(HA]2LeUOnV+az QIG;wP֧iv̡%gmޞpfbcԪ͛Vb& v{٥YCWǟZӕG5_c,Xxz]^84mR_@X"|ѧږ7s?}/A l!(͛JYgnt0j]_ ,.iz>&ѽE<D E&hWy}Զߡoޖ\j!>vםw~?#{ { {`(lX2~&&jsq˘|xI֤I|CZic====` f#Րdo6p==K,^뜂P<;á wF4(M,gWLjӺ7;@cޘduߘݢ|偦M۞t}k{;:wn[nhgu Iaex{&᫂`Ƈ]|=Ht5Q*Ʉ)(Vgʫ5Oo'W6{ll睺ֹS[ۢ+?~Rxkk/( /O|JH (%IC)KS75F, y==P@C n˰a11A-FRѩ=T̩)\-+eOXrlnض8e{k?~^g6Q [.&mjrplEFSt#N,!K#B>k}躴.fs8{@?;^ּEy8j*{qS{ɮX=FP˸TR<$'y/T?%@Ub8IyPZX0:xrXpJӒ7XJ(!X/+ D EyD%҇QUfB'l aiR%DCmD'TSi}b/2dr%ɨADѩO}rB========x}]'h .=AWtg zd *OR jlfJ >>P/Bu*$A⍘(JMb ߅3XD:2&3T L0|%Vd` !J,AFCɖ|v*zqU*ί&`l4Q?٭=Cxŕ_ɔ33{qYͿUg37;z͹ddddd|_=`E`7'; 5I(+`&,AЃˠbWHqd k8J@FuOd$ہ+B;Q/J J~h)Cu4ůNIJYS/P7kh}%x'00]SYk W.䃰@Wr^-$ʱ_Ir*~-B*4no˭{`ҤIvw?g"=====0y@_D@I |VdHU IN򀟚$x(o0pLDlH(l,VDT,N:tZ鶪Q4Nq%*/l[D$-/ _5B-O9!}g+PF{d& _LAOmH=xLQ|ΗSVI tW;1\gd̑KVXa9gP@@@@݂gpč*@)9 #MAtT'R$*{q!qJ#ؖSBLuDd̀(v%Q2L )g!"x*kV U$'#Tt1Cv H2LDT7:㑧lA}*)Sn)Q%f (k% rwF7&MYuֵ?pC1/Nu_xE~{1F5ְ?QW[j?\{Ə`v} l]6ܰ믿^{m[}c>Wr)kZ>}e'N{ׯu} =c:uދ.*{ァVڵv'n;d;vXȍPl"XyTFl%HN|׀((LF &TP3(UA)SPϥǃN:$S⣚eJZ3q12[اV ܒV.m}lT5 q[8tUd'PI(/BUdp tq%D#'A>C>^/z9恗^p3f]wݵvWؔ)SϞƍK.)tك>hwqFkreه~hO>y6rH;f#ǀzV]xgw R{i 2D[Fe\pIrzѮǂ* TDO& LV3QCoPRИ`܂ʆ[5!"UNKR7IiĔe ~!TU+N.XIW5Ph݂x7+| ] þT6こ4D,L0z7 ѩQɟ<[C8~OZ"1~1ᄃ[c_^Z3v9 /.z3_n]lΝm%V{nGn%駞Nvq7:[l1rˮ;է=, ^Yge}G|ry晶ꪫZkUKp oPD޽vR#϶J/ORQ@9o.&B\1YeUm۶,̍:"Ӵ*Ī#,1y 88V#آ^ Cr)^J10(UʠHuiZܐiUi"F*(GPhҗDG\`bdi9C|( T q'%VbYfl;+lǪVU>SI@gzKR0d+TAqĬ J(+2Ǘ Ơ/A\7jxBK+L)a-ऑDsI$8փ]Ptg RP#RE OX݊A*CP$ɹ<)М|<&[[I5q N6`*@d5yQ(@^:KǔrQ'&oVW?^~v%O?ԖYzީK."0.9Xᶝ֩Zc~5`qđµ+]IӚ9Ξ9TzsŁȬjs[b+Uq]Qϕs \{m&Ӭ??O0Zn-,ۑ¹======@CKg," EK<c@ x+ qC!dS?,]i.Os!uc|-#`KP5$~֥/&ai`c2Bb&Lq1DN-UL>`hNpTs! 'bFF`.U~/ T%$nԨ-cEvN>E{429jܔXUT}ܨ>{pÍs,зo_Ƌ/hgukͲk CA͖G19nnfm;cj[.RXedddd|o %/l}%z$*H0\ gP#~}!=4B$Yh>Y8J7xvez|ꢀϱ'r]sEbFAjd&B؇c::#lS:%}Qj&]|*u7Pѧ-) ?ڬksG6OA1VR.n C\֩YwkI6_:'،S`-kXiVrXYCZ)J4kH\ x`Kޮ<,)vx)L IDATu``sqp2뮽+!4)`&I`3kk_I+I$"w0_ -9|%Pc&xrZ5teLh (Id]vD-%JW=@s9fC*R R4`.,wBVN,σgddddd,@X12`Q<5j%! DHB Hwa* :}lJz`36v[.'&8^d]w< RtKQc8_5!^mm[kHXZʅtN>M\ z$xxX'S[<%N=5U{]އ%ʳ{2qã} ۺ1qޱX^x|[s+;aW@tQ:5+========`yp{#PN$FX@+%) xJ2VPe'Y$HDSj:Шҥ[J&dxB=C+%Hhʹ%V$ChΎNf`BA~P۱|upJ\'~aό|W7N!t] x@TD4)>Rc7oF?>?|, %ej ;nhw<8ڮ1|W *N^X'FEo#7Xe"DAPFZ. -^s<-+%{ { { {Qz*Z1!Fi +F/K3TSE\OŠTD*"5E7k2ֻ~uNǟ|j#Fhg=Ǝ&x7kMoN:WΦ؞le-6GgZ5ں]?䒋On|Ե6iۯϴSmI[aeO?c^~b'N׆qvmC{XzOv#I@c4='/R3ri}lVZFXqٟnG﷕m lu[b?nL[Ͻh-V^5 [X؂uaOhxAӕҍA\Il {?9/J9$){`xʫ8%yk====?;OW%_~޷9]{%m6IųP$:_ώYV+oqcnq, l@Clij"ybme};PE&?mFvG",l1$.YR?mWUABl5Z 7f;y?}ox=:}Ӝ̚|n؆oMʛ[#;t^ThBxp}#$4]xB?!+5^ڎ?;Om[7;zn`m~ ڦn;Ҽ6>IDd&d;^[gWgUcZC}dCtj+/C@p僟5~%{ { { {+ =*nG(F׶.#^ 5Q9Ek(m⵩\P~.4 +]ä@|&ф\ZҺw.<#/pUӦͬ6?5~r`hWh =$l%Jknpf!4 I=$傥#3ֳ |!)Acm]BB &Oy~U>z,gAISlV*r<%&L}rlM(`}Vwlo+6^Ξ+شxX/#_vmZQ doM~^79 {؎6^~iњ7[^u}W_O_#Od1\ة֔l¤`ykdYaGstƋ2)* v[=~(i*.*8OIL_gp=0/3>I W?x`$Jr=|L,y m><̈́do@u:%:~9js,|^aJZt& ,0~J`!xT_s#lӍ:f3_<3v辑\x[btt#QK#voct¾"&#t;Y{mulkoynP SH|"Cj`9\oɺU en*gd<ɟ>G'(>KhFm 2"Lyc:{&Spѡ!08ϪCPatgܱ~m-}u`cF :_$chM aa =Abbj{!@ۈ|[RA@}zsaEfPJS[9rǃ~(zh ֩ƒaʾAqWNse>PГ)C~Ѥ @J/&A8 `r$A~hykhCnM9Fneddddddd=saz ~Is^<"WQ= #.t=1A[BQ7.H*Ɏ Dr$,N'8t@ӨK)QsCE^C#9fX*>G qzEc2bl+HU%zVT&vJ0"AQmLF%@@Zhu@@@@@@@UYs)$TE4%)GT:DJipg4;iP.@5WCh,ܸSY+ ^K`s]WgQ_ }J6I.Y,lS(ŪL*!BPBPCBr[!*A0J v/\{uD\.')S& 6i6lfdFE0V,0#BGm1~A`a0~(ItD| X1#4#YAjȻ@>g;c=Ѓ6*[odލGZ<0[?c"- dAfd&PZ)ԬH۰P(#ՃfW)B%%[DJV&x_-._&p2ʼnzdr Sgۅ SBKɥ!QLHH}VDpf2Ws0rR3ahŘܦ42\vW΁\VVRO?mCk߾-RyZ =/ hMFu&"NcEBamp(tVS">dNYx3飀`91jd竝=)yXv =&1pO, ?ACHk&ҁu6k$hUv!Zǡ*5k%):VQ!ؠKg]uqrUUGyၷߚdM4Ǽpv@6m\#"G%0]i˕K c: GYFJ%/N1}aBdUqT'Ogd4_$4An '%lS*)$8pP&H|e'&  Qx){Ш@Oa$G9#A%a߲A-hS\$ФqߊJ[{'F"JP#"b)m*]-\5]F~S_b%Y(x'AZ3@=L=Iv5@_F %\4ِ{CW( ,{)!NXurǸ`vmݥ _T.O%|%@\gddddddd=!iLF@7#dX1g3 e`IK%GB0pX,t-tPA::mDV& <8fs%~€XA iB<'Ic˽VCa{$t2xǕ!҂N-6.JV)xۓP殐4IJ C:"m#)痪+Y]G}6#ڞ WN͛_F7n|#%s!LG֭Wd\h:ypLbp%C6x0;hs/kPăIH2 l`l).'@ /ڬaUH[@bb|ph8)N'*9NhTISGu7dY;FH2_qSTTDAS/̦ijVBjK )sDCMIR Ib(k/녙o;noSe-y7wy緤uީ?{?k0#M4n1bJdX@@@z Gh\ѷ d̨{W=:v&@:h q%N#pD[@ WޕVز}9('$ž1łыiu[[(Jr4Ail&7xc ipY2]7%,&GIYMM}LE}PHYGCñqyjzEwiϯAI٦~c}!~饗W^[nk/;v.}ƍ_5|in6]/R6 m٠)dpqcq᨟3=uMu)R8NP%;uW(\ˡtX=QmUMDAdR(FE'Wp"YfB³ZrpK$4>%6 9:?\=͛j$r:kyb4Jq$0WH?0[}vvqϴ+m[ͬky,mAauyUk5gѷ~v≽eֶvʩ砱|9\ܹm֮]; F7pu ^ø]Wmֳ-[Z/0=C؆ f O9Xs5O>kN;5\#ZhaScPGQNN\| h]P/pp~n{)|rE{O[K~'n;0;v,====x6D q"Ft1>~ | d?ay$"HU%'jTZJ: #w;=Q"1kh.'58i>[  ~\腑ijx鐾P6c\ꫯU}Wǟxn3fvavnkotvɓ ѣmO_o/6fhk+(_>a 5n/1b}û/й7b."Wl3% d<:J lԩz^Ʌ^08 סZ?^{m?'|Rc9;h!ea2σs IDATαMbeu{Fm2ؾv>y0gva /lܖU-p-V[nF۷h-mfvWŔlF נ.Ձ޽{XΡC^￿JVlm{ÕJeqɯGgmW]u_r~rIЃ>UVYڶmIvG~[nddd,hTNQ#B< yu!B^O 0L?PHqC#xh| }GhncE]ǺP+8 (28/e^u睄 >;'؜V |mJ*ke2|9 )9*SdMsTαeOF$:%<_ÇY֭gەwi9uWc;P"hE?蠃KkѾEc%|[ _R 'j WYLۦsZ G?QAZiMDRUKUUW]`OuСCgׅc3s=gguqI W^uVCvVZ-]bk߄ ~ȧMoVJb,|vnњ>}j7}+W,7hJ@$Ǝ!5ØA < SNZ*TZ\%^ii2`L ԣUGBJ0Hv% M8mI.ͮ5))FfS?xDUpv4* IrTjek'!Km6%tEcH.]"P)nJ ZusV]L<ٚ2ŷ|[ppT#8R[_}q+5iZ禱ڨ#l饗Tr͍2Wb,-UL@N<ߔߖe+kLQ0{T?>q#G}BV[me<g&!LH5 WPkq>c[o$ۺ[fܑέ`[ #Y!HSNGl"RQR*^r~($,0K:N \rTx.Z5 zG|)=zS'q # B'ިQ#% |p\aoZ_i\aR߸(˕n?nomL\F1&PM}====#ӚAc%T,WAUzt\RuY@ ;=68\xAo#%H<`B'Ljj&-dj}קF 8S$4c~SJ4D%}둑`k |{H,jhd H= "y#6Kdq%99V LKN 1uN6V(s4[ǎl[< mw-(5n4cgmYdEﱳ?]K$1;gwh3'IwhC\Wjߝ jUmX=rG>c_[_C)>mU͚5SN]tQpN,lސdvGJ\puwS"CƭW ˜|Q#W aC%/{4`Q#d/"wY\y:oLZwA! %,Iu@^1'8ڥ)3Pf!L v>FPy)6-+ !԰Mu 9%i*IL5a|c{ V<Դp`^cڗI$ UA Ei3S)IW`Uq'+_M7Q$<7vj> Ҕ\fCAc[e- @KnxDl+`/T- ă k"G)@g[4MsLYjLxR]S$hrx(Z (Plxg`+L JFaA2Sta2%cD,KN))X MZ\YW젞w#J>%>U P-D\"=eMwm]1NR z.߅r]x5@SH yx܈U`rz!F`x2-D!6 Q# } ½\O:|>lX.#4U8t&{WImu:`G#A*SC,tUNxڽ#H9N!(_=.IG:g:֧E >IqI!*qҌ\<4m:B/PѪZ:8~a+ySA '+D[g!ƨatKB#׍y&PUՙ(EqQ .Q `ؙ0('@8QL]Q#倊2q-(8lEP >oU1꣪}s~{a}U { }F#f:f]괥B{N,$ :PDN|X*t(@hS K0j2ՕFƻ˒Kt0P)8]!u"~ plA#\Weettu2,QRnT QNb!W]ye^@U*PE(arCВmr<C;wQmIb~,oWCeO{)8~s071A:LV&q6hf5a:cmsd9a  :p(=bJ ï>("W @ ڔ*Q0 5Bk*dEF}%G| ;m1f\sba1"4Ux亥I8ɔ!h U@U*P T6 ( A$NEt&}=y4|_ӯI{9RЍ/3+{:x xsN]%F5x)訥 R@{9!:L( g ƔyFF9B>9Kk*Ge,{K\ TU@U**6׼Q+RJ91b %qbB`"Ɇ8BpSAR+:cL3 -XcU|B~Ȧy*owZ/d>0R Ɇ" _;7@ĺ`a!$NgXON&^ Nޤ AS7,Zb =*CF%O,dz=9ieqTh"ÁKq4i?5FU*P TU@U`qU1YX#O$6hHheb s.s`J Ȧ3f:i\18ɖ хr($VJ@qPqi #7=}IG[^awc==yS4C*qZ+t̕#N^ݡHv19Ae)1 FVMUU@U*P lXJJ2-.ODQrSO-,Ni,mb. no:6Ŭ(Q@H9@`j}hq&NEǠ!g1}UR^ӢsqLGNTp A-|0()xҕlqJŰGɥ4C z^tWDQ$!c  >n,N3 s9a܇HS7!Glht)EժU@U*P TIVqL@pW'*7769260q5`10XnmXczM7%:(x }`' }B/cn%&2̹+Pns#?l zgt؈AArjSK {cm\-9v$1UL*mͶm<~v3K+ק4]\uUZۿ˸U@U*P ܋X DK ,F kNGh6"L:x9~sM :0& t,N fc 6)qA ! _P.QpVMh\&ǚ xQ X\>践b]ĵ$-13:>r4sxC? f(apYi_v7ۃvGzPʡ*P TUݬ0i$ ,-4}gf}>GXtOgj F NF%Oy@bmkP9[eϨ]3!ia,/x#Sk37_aZ; J8֋%au@oo^}g2Bx3D,jѵ :hHO49tW 6R =b6lhe&ŧ-mG=G?>ʠ*P TU[ RI8w9L hƐS(6a?KZm2 /E=}^99}JpLW9xKt[9C/z3/mSh'̤|'ZH.8?7x89|QSFa'%}ӄnфS7|)c-Tf%~M r8mY0N۔D臡8I4@}?bDj.>\خw?z}rvхo/{K{Ô/iՊ8oI!OyJ+ V8mݦ=]~ڴp#r}{]qގ;3Fc'<}#imЇ>TV[g=}^־կjZբUU@U*+`&*69,ĕ$s$$yR, :(T{5Q2 Ann:tGm>`ǫ& x`fޤqf_3#rǫ #!t4WJC4̈́8ᕠJ[$y'7*ϖW2ŎፈKLLÚk$/_l7Gy 3׾z8n:[q!7# o}zSi{NH><_JKtuK.] ۊCW( 7ܨͮ!1՗l?c;3V`o;=WB6EͪU@U*8*D1k$"bI+ۿ~7,=%W䃅 CAQB!k@l\Ц:I+H`qJ)k-4/≮ 1.F -c|h})!Wt-ZNSHޜ`N.!RrQ62b%Ab p(Pz|ؐ0/Ye= rA.FR4ނg?)뱏}6.[_Umzk;?g-Xnū guV+ھ]MțgLaknWcqSζ;o|㲾q[6jko}kgjb BtJ\ TUf,DURU)"5 PH>~ ӊd~@s^ACWhJz;^b q;/~D629CՐs!35cݐ{tK {$g 35eCu6"MFcRHQ̞I ,lL!zÎKW>f|i<*I\ [mVJ-dr۔4mV>u;ҥKf8|;CV{lͰi9}l;Sbxx~h׼39~v;x.tIv}^W>s5YYƪ*P TKEhI = n,?D#ImI>i HJm|8Q:O>E›hN0igN‰SD <8qL@CAEm^3M֬#/vNT e2;h8Mdx=dNα0ĦM$;uы ɴ`OfH 8FtiU )vdM_n}*+O8=GvGO:=g|[͸Zcalwrt|y'>QKo9tozиQ^Ѯڄ?[oc7p ESρT&U@U*P ,T6yu@v&z2ڴB0RKnYI1"b$PrcW9hJpV "4SN[[N=+"Lǫ%(ek:xLaL[K» "VEJgiaS夅[X0)V8Dʁq'jIa# rO񡧭 96MCF֥DLR- >^*P TU@UU0Gi<09߁GL^ԔzC@6O)Nz  ݼk &GJ KV,?)~kAe'P6m' S{tf&LL p8ރdPD;ǘQ A@N78u[,Ʌo*nC2ܧ\ܧU@U*P , \084XbPuq3GC#tˍ%AZ9F4HG,r qM CPO$s&Rdc &L•ЍN\H+g;pTL bܓ`@p i414Y.'/(eWe zoryXMF_5A;4i/ժU@U*P TEz uvaS (I%gr,D3B:G\3/#AO"L/Н0ӉrYnAwdٞ o$iLZpp,A YtP$z58*Y3uJ&:0Ris@;{ceyFh1kLAOZU*P TUb6 IE A@DT=L&M-F fRN kHPbl:(c$ 2ӴQcgYΐ_ M' 6ȍWA52s7d\e/*qj5b¹*!@)hßli3yQVц? !G_x8i ,P6tS}0UUͿjU@U*RBK^m/K8I(dPINUᵥ^mK&c=A$›I&2 e~z-;Kx&){ ]o%dlӤo!ݢ$81x\TӔrA_9ISׁf$QPF@+^SڻzSB_2ˢZU>v=BWE\oZU*P mx]M]{ "l q3iH|<VMxӘ܄=mȉ`%FSo F:LU留x 2iH#JyFt3"gPմ龨CH $~8r#kc4 7hDG@@Gz2ݺ8:;0aZ]U`!*p񃧷o^~$r!bV[^W*P T ёtv> D=""I5y n' @ȍk @ka?ffӑ2T*aYw)X"w N_ʺS4McL8D]D1$\_ 8Pʩu)IN4gZI0O!UF$dAEʺO"å0#;+\5P8:"VWo*=lR׀b?=>~By(VSSoOPdĤ\:UU@U*P , {@HDqxB^KM0"!C2Kf*ʚ~qAKC_L+'p}^a3C:~<'ALVD4 s9H-Cm,hH= e(D)cNSe86Hqsbx>1&JGlS[)RP7oe@!gO1JR3?{Y=}2fY۫q*7LR*P TU@U`TπP&S?|Bxf бv"(c GA4)ل%#~ C):pJ"PЅ?gRL6c2|ć{-bE4+#R6+p4!΅+19L#8؄`2 MO_'Lx_E5 ,Xk?vnZhqV`Kܞq,B*P U?\p"@;j3!m޽҃ -syPLkbـ@B 2@k%Ȉ@W )!BO]+.}䦻x5^V0Q9' $XK0k;跤Hn1iɭ{Z41~I@W9 :Uu_o^v9_k8d[Mժ+&߀/oY{Ԯ۬H*P l8 lB3f 0߄034.xs6tjظp(AdB" 4%2A[dEÆsͶ* 48 v ':q&w`A"%쁜W@LK!v^M2Z^1WQ>t7>uc!{,(Z]Rv˶fv-UPD1v R=Hѓ\ GB Aۃ SJ<4(Ck39=ۡof B;ӃB4$;IX5ów52qO5,T2`\&5P>9gn#_|+j1ec%脕2#J1gŌzPǪ*J:bRթ*@7>!Xz/0O^9U TU~:٠3頩Zơ1wGjk[s0ʨ ΩzL.&_nώn(~u7.Wv:=7!}pcR`4&?8CL*}Zc@2Iy(r߈xY('G@U*P TUT}H@mH0KJf$u$2}a3yT |KoK'̈́sqHjp:ܒ'$8x$RM 2n XhN:(= ޘ` Uẗ[!19 rLJ" b]1)_cs=ժU@U*P TSOa}PKnyg7ӂuLQO P0J1{Ƴk%1;MzNi=xLRLW* a*8'µ k@,%mP:9Ιe\Ip唅`nvBN͐C@q0m&z ժU@U*P TCp#4S_opG̓prDi┐ps{ȧɋ$ xA߹L%1:x=/ql9DFt XE>ĔC9|3mňx j`H9ıMy;i h̜Sn7B?+(34m^B8OwYRryk|;?Yح-nlqVՑGvq'ꪫl{vЎxiW^yl]m*D%[ TU |̈́RC @e ahs@mHJy  gi}d6m@QEs"CK6?;UK5!bft# 8㘤1jIqw+y`guZctj \h178T9lYSBݟ)z֌$Qﵧ秵]vٹO/|yv{ыiQ'>qfׯ}M~G}|ޑg}]~7ez ozЃڑGJW TU@U`]W`D"%ԩϔlJIo>n`- 4o6#ƹ% ;?)+kVxk(́{B |0U\nx[a1Õ S$e(mSCA TӜ1zs،'d==;a= r勗92 ign$2ŗg׽uO=}>^ooO{R|nM6[oޟx+: IDATj6۴e˖ |v[|ԣۏ~. W TU@Uެ1_3t]J[؆,q!rN_0~˥@$ڱ/w8AM|޼݊$bCzKp*%=D.FlHr%Ƒೕi:#PT_)AL 3(0Wh̵TcևGHI]>B9pDp(1@} W9ۤۋwoFNλ~kv/ir{_kǴ]7vG=z/D9>s _TPz>vqk^yOsGiWZ~i}gk\'X{o˖osƓO<]?;vS;wtMmmO|~uyiᢋ/n'cptp z.{8`^_җzn!d02 TUWM{#88fL5eGpDlzn'׵Ęv"&ɉJ`]Q܌LCzVdӮͣ^ҙ=zq!Ø QʆcN7xt=b]{ ,4Aߜ=m C&(~t;B8R ]9eM?aկ~j<h;g7|!n/~.-ZsH_nw/ۻ7?o^~YN?8>R}+_iK)o{Ҿկ="sϻv7^=أm?~x|SEӟ= Wg[W`Q~G>)^ϣl_ۯv/ph3SNQ^o䃧WvdZx#@m/W !'9mU*P T6 Œ4k;.MtSۑo`&EKΆCƦ9Ip'³ |Lj27Ѣ ) ^Z @cΒu)ps)$g}nqގ;3ki㦅?yр{''~ژG^eY=ɹlU@U*V@B>V$D.٦Hkk-Opܞヮ= u\]HH&O=k~Z뷝ˇ<~B;dšq{\;Wt>UWp|{ӏmG~jO?z͸Zcm2?W֦> ]A'>Q%3!WYZ~A{=_/}tncTU@U*aT`Cu*acB$Kp((liTh&$ 拹LLFpD:M3̝t8>&Γ6,[~0s 16,O؊{[`ܓ79aA{ Ϟ|undM%gΉf~XK"ŽYI{4(e\b%Yhk|!T*6HPu ,T}G|B8Uvw~^j?qùZZ/[U*PXW k;!fK*Nf0"`2PCr)&3w|hɀ3"K/I[bxOAeM`62hNֳ6M9 .DjODXxܚ歕|>r3){&Q!3j֫GK1B1e2#%rW4V TU@U`C$i;aaIb\eprvܳЀ~r1MzWMHnc޿sNB%t6ˮ s1"^f$ 68/uT\D"ZH!ЉgaF%$7*Gr4DS!6no+Ti@Zv 5*P5 TU@U`R2|SԔsd'qEQgGL8[,WT51A'{eD_ҁ,̕2& +FaScP"^5ǴQҖ9m Ih 9 cZDs/ry$ʙ zYJAa#ΤNRͿ:},9zQ[ʉbwzjBq>@`gl dMsl Ð]JFWf:upѐEhI Щ"GqlC漏*w~ukGYS})mf t21W|,I':R\}U`*I'[y)/P *\_o{ժU@U$$8yL@_!z*gNL%P9?y «HrD3^ۓpkO~D褏*tjM0c+2;{o^`kniR-1Cyp>2 h;~Q~p%,ȍ"ft C,9U HEؚQ SV}U`*GOٻKڭז/ۺ-&ZU`UW>~۪@U*aU`)I8N "0ESPB2IdoMԺo/ރင4U % /O:grSrDt%b:V tq5Jrc;U*^Yu:ʘ M3ܣB "[ܸ D_!>?,.&I0s9P UxԮ۴goڮOonpah}x.=Ds۫V TK1$KW\C ]'"ζAb/Ǣq$iOt74"Г5E$Lń85ƀ6,9:HC Pe~8#n8LΑ'cN &qBMЌ6+@wPk!(20QT&mͪG@U*P Tk:9h*RT3Ǒ0 |RΤǚq}K\{=-9} bk0&uv$X)6Z  9tfNɮ+%JoLWrGUנ*P TU@U`B7yOAdő4>X|9 &yPUO"Dz<3>ONa BzOS&dSn'}Zn@yD!0TG8r‘:M\}a&M#?\::fh#N!9aʅRw̧rjԦ(rc#(UU@U*P l3 Az10%wn"rˮ\Ol'ڲ I2q8mdJ{ڱg 'kNsnZtb05 $Se"O" fټ sg,ٳ::1یIhX"&r+jVe2X#CkP TU@U*U`*vۀFQr$wjDeR[Yw}{rkHnLD o78{i:PqNY%OBac@/453r"?8W2(a8gWcbԣ؆`3gP4n"VU#nbU(:vMvS0չg৆U@U*P T}pLsS[~D%1fOvJDʁXkPK\A|6OJk8uG1'\\0y9=g苰\nw\a׮!;ڇ5l.::""SWMB\[bBȖ3>5=>pic/a+%g:V TU@U*WW@&d?j` Oٗ'49IJ&)dBt梂t'Lĺ htz#!H0B "N\0Hm"ġ(j@@Ne֑idI)rMĘ0pxR/;g[qQ׌KoժU@U*P TO)XAu6Sb "A45vQ8U.7M@1+LJ |vCU6KJUO:B/FAĩWuЇDMʱ9R/&qT2}枾ʀ27kƓb2iGYLޮ-k輒a@5Ρ6+){TYKe_&di Q8 &\X!ǯsU*P TUbU_DQm2XI"SAH&qS*d$Eͅ) )Dl#%0L1)'[,bG7ʐ#,&! jȓ=W}!MIIјNJ19p6MFFHpR 埒 [yU@U*P T!t^d' DT<;QS.ۥ@w##$lI֗uOIS}]ExN M$9LXJ8҃ȨHۑFDziҜyAJ!цX|"a0ʍXXu;T TU@U**[&* ?6a143g[NiR7+qn;h$ FOST6qqK& )"&\ DG\+bPS HGXQA`d(|c1S 15/o"ZŏY60vI@X3 Q!ɀL-p{U@U*P Tc0!GLhJ9NzluIPMU)sF|g5[N#;LM+.sOt۹k[\t]\(> AدdM(6PG) ۴Y-tKo eDH9w,ļDr !8AݪU@U*P Ty1`b VTb\3I&rN: ʑIF< yJ &{sn&XV$D+wAx9rtw 1l4RbL?줏MK#g]:`F&)\-b2Ya 1Mk}NeW@U*P TURXn-Bj(Hi NK*Ihpem& ɖIW'^n0YPg24d9 8r7ڇ$W@. s)g@U·Ψ.  M G%Я|/ftf^(~ӀXCN4K:UU@U*P , ,KSŠfPrtfhi)bp|e@pIv\rlgNѵ1"c?5y16YOBD.H8v 8)p`džEM5  *t^6!86\3Ȫ:L3i+[3VngwS@U*P TUKcdj\E&O Zi&rk~ʹ>JJ ,Y IDAT@UT${j5n|WKdn=]'w$xR-ubDj}#{0Bq :ht@NL:CZo6W G9ַS +[<XpXtu TU@U*P+[LI6$b\<}"BI9pיr5Q+fšIHV{)')gOPo*ĚadX&r a rudq2LR}xj(bBxr*lhnaV`DI^0x墯±N UDcD.8' *P TU@U`p5Jj VsS(B׽P9 k"*NtRQ cKsX\E8Yg'8wv+|fbH!{bL6NƖ1y\jA5Ȩ h=vxV8z:wE@E晅VYXUG ow\#nஅjU@U*P Tz=(ɢ *&gƂ(&1Ab\p.6Q-ɹ,`gAzuDsډkb NMï F"p8\\L0F#Wao9e,']e:s,Oط^ mp, "~ \b s*ܴ !}!~ڙu TU@U*P+?K J)~ 4֠9MsHq bkk-˞DToZ;  vL 9g 0o0 2- '^-U!/)6|b,S*뽏`L}T+t5^E&C@_tˇ{MS~͈kR TU@U*V`zd2,-$DzO]@\6*$c1(bPI˩wey` $ReG:$Ny"i#B|s`LP%)L81:t]Rt+r#rR0VkR(llBg'sx€9)c5=םXQ@U*P TUbV0,"$#_Y'M>!j(e͡1% 6uyfHICȓOȧ!z^zTVD@" N9Ā憍6ylN—y61r7~-Xլq˘je>4b ZD2 ~zUU@U*P , <zEa;7·Ldx"4H,$ϾȌ5bcS8J ))2>";b#rv/Έ)ո'l#}l,ϵx-L]bF^ذ)s)Ü$J=]X-{7MgOJljlT̃UxCnw7SU*P TUb6 &X6IcDU6m+=v &Id^ Fd3@Hv  F$ ƹFh _ b]sKŃ$]#h U`ِ<9HIG?xO?Y (! (AyK_WG &CmyDϐO(UU@U*P , !tCd$yKyg4]+API+%Ntsw֞:AƔ`ޛA'I,uς%445ΐ+?e .ϱ4"?Hf`D<^EJqXxfT 8G|)?3933S02O$2e3 OX U`n5te:ʘJ&w#SU*P TU_ɟMTT|T3)#*lLCc`0|-a߯vp$b3D̋K䬕|&!=‰&oχ4 K)9((dcǘV2ic P@yd!P*̋s 1,Rdt>9(OVK<&%=GBl~R.1yyc$D;A,D~R&!\`25b&ll$_L+o~c clm&mS]U*P TUb6 $$l,E8PjLh4sC*-cקӄn53Ԇ $ )]g$^pb=Z dtfRaL8ȯ :E%"04}#Yh9  }jmX,9DT+PaJ'V)WώPV TU@U*h*/"4YAIE1 /Κ ,MU\5ޠ* ?$(ٱGM ?õ6۶Jioȣj;}:5s W5Lźօ)u;Z^Skyojcved kZk'Gn~5^җGwv}m'W՚-|e1q|G)U|̿kÕ|㬀"߫jA"4H#p0 7OPI9vdI7<&,%^zpƭd qx)=mteDč@n.(}% -]mTIEU*_NWNPZfD>f3u$K0g S.6p'zo8;2>3ۿ~kYf wZf".Le] [m£G/ԺyoowHkGoૹy'>EӮя|}j}߷K.B{K_zl,{|-k*g@r&fM J qnN2:ycRWo4!0ɴHP;/m T!8 X3'UwT4f~n  SCMƓ3+ H$N;hE@C (7Sl)Y Ms$vƔ {Cƙo yb0sq bH=~@C|@[h:vmg^嵐ɬZx rAbm,Zu࿇O|=zօ{lyO{ǾK]xn[l]r|Ygs=oǵ7.ol{|Mk*c$i8Ab;LX@*ED1hU#$S X& º\{ RV7r @#< [Wj@=lT\8sڋ҆ai=K4 mO]3csiY(r.u|o)<{7%:ޒsC;\={1×nN;JF[vyoގ=%[n-^.acڮFz%/y俵#+;t~{{?f|A.t9ӯk[׌!&뚟]?alvm}ӺSuvS;wzM7m]*Y/~wk[s{ݮ)c$!hBD%x[5\j9%n"sRMP *!g?y{~jru~{y=}{.]н㬳|t[ɟX얱|~%wzRv-Ey1OκC%^ZaEkZ&ʋr oQMׄ|KkD~QMۢ| (-oyK{sOioyoϺ6{J!Ͼ= '?m>mY";bY&}co~`;_8/47ֵެ#_a:[wn=ilJ?{b J19MN98*r7`sDq(c-+m)UF p:ˆ4`98 l t K&?+VDL-)IVIoaαB놕rYX<3҃3&mEB,$qZxEMN51\*b#=S5#ysOَK_%;cW֯_o{vӛ޴|xo??aST{_-9O~5n %\be?aog=vi/{^em{)%CX*u>ٺ /hghi˭k@5?:#G>>կ~Q nw[Z7QEU\?<繶YhKQ<1m:v~ZP$~{߳Euܧ?Ov.bץ_җy]}m' ZgrkZ&[Rq2--R]n(ŧ_.W$w}:7goKg>g>Ӟw6vnE۶oZ_Ŏϥښ5kګ^-o]Jd3_wmm2 O~r;|[|Et߹E5;Nj@:LOEȘ< dY3h FL )cJb2aKYr8<.k2X?[jP.315z aH5akkRV?.I?* ??Dn- Yx؉4IƢC25s.Oz cC9]V 炫hOo7ہN~xZv]i<0I{[ߦ7y{γ߾,7NmGyvk_vayutE]=Wra5l":#=WG/~.(D[\)|;=yN9y3}_\gcs>ڞ'7%WWn{\mݴr)i_GxKc~ o^?iq{Zik~Ƕ5NR냶KgQO\>Hlw.po鳞==ھ (|ζ.-ۚϿbEgyWkRNˎ!-[R4h̷Ewdy[|Et߹y5_gkTvze`!O@! ӑ6  H[XXF|Wʑ<̴gB)Ԙ Ёy\ȲfEGcc1, 3Q yHOJzP i ]81bVSi1c ܘ7|A?OF4/>fF#50W~nz}÷ntӸ~ 빩K]&[j׿~ܲ[o|u&"6ns[OUgKLe]u%8?3@>Oh(y5")]u<`泟\;ڟs>zN;GY|kֿ߾NM|. K4.sO*|.׎-nqЌd)}:ky-/(,toӛ$5ߖ5 4ؚok4i[c,wǶV6_[{-=˴/f\m>mYrv*؋>s!~wf;QO}p'tb˿l^>AZ}>w7Y"ηlͿsvk֮~PVqL];Ja1ЬRm4h襐@ϲ 80)>c> rf%|Y@pLʹo!a-eZgyFf|1(ui)gEƧee%ODAU8͢!h_ˋBC7m`9 -l(Aʏb9aԼ)D5Plv#,lx<>V0zF7m_zJ4k@2]Xh 5yMjS;?я"gα _vA#R7mͺ敖Z'{v?~?»1׻uۢmt)yn mo{[z>Wi[*ӛM;r[/6:+8OW4c~"7\:z.餭ZV&'+Kx5ijg\l}X훅nwG?zR;i{ŷwhk_wPUm>mYrv*}GxEv0_gsn}ԣf.Rm.|z~QN+#l>_wnn5xD9@?lZtFK_2Myja)R+ԟed<;e.Y;më#s \Ns Fרt=lf\CY^5? ty9/#s˄8!zMfqf;Z˓%hNڪ?aly( =y5up>q7 xvhx𐇴?ď}cMe]׃˭k-x>F IDATAĭltYpڒZ&:ƃ֭Sp7?>4ڶ :ϓ{R;ē"Uq.PXb9.ҟhK[R:E[=+pE]Ԟg Җ[tZq{(—j-ָE\lM't ڶ~!\xl?lk,mSkۖ~տom:̅j{|;s\yv%_qƴl]w4,|M*Wn;9Y}Kk9w9ԭCS{[wu5Xn\>m9U+bUτ$mg}{ݫq_opNf;>m]"; x-o=Hr׻Gj'=/%^qڠw,*_W硇Ҟk}6ߑE69"ۢܿs[2']Rcd`aA 8Q;G@NZ.`iNLpt|su+ZݚiiY<24Pm. m)~ԣACAHSė"c  SU<Ǡԃ9F0/2~BLf~.I ElW+kǮFmBя |\;VİY%ڦĈo_4L"a?o|/w{=;cxE?}&7θ8~}_mwCڥlګx}vcNGcP(2;膓`sM5C-[_fU<gٞ98#y aeh]-ؼVp?k*B)`2U=9fVU䝘T@dJ)5 )@(8.+LN{(4ҟQɠӆ0&pov62[c1ѣ؉2N$k; z;MI-`ՙ@̂՛DHӨʨAh. [b6ST̗:a8M qWY= J#%DT `_(^*U @29xxݳb;Vfs3=n}`Z"sIHǰ;$EDD15ϱFmMT('>[~#Go==Wm> (5~"ngg`36p!gPʛIl5^nMVY g]XWC^-.+B0#ɡF4zP 0cI)r18`QQxelޙQ%}xX2 M]L̢:2y saeu0DĚquI\0 2;:٧Zy3EN+Iul{{gggg]z%/y/`32  rJy+ K@XHP=~f, H 7  P ~ VGʬ H%Y EȾk0[{6|i S%)eIWeY![ Q6>3Us$Eρb2+s@@@@@@@ @ ХV/xm5.5J~|lΓY%"X|P(b汚6/_Rr.P$Qkl J!Q˦%St`9>0"?7HMo6+[3=;33333333r2{lP8  Ќ" $geK' kd5i&jӖ %|BfEcƙ8ibbB>li6!Wad =#n37 DbmeVLcP`"̌fP~X6>EM`Y&: ?D0#EVcⓏi5Nq-m{ÕLr xCX~ѹV+WˀjC@Enj',*d:`* ,EY#c:vļsCCpY6 ⩷,(b`'+ . ,;>RtslFnj5)o)1L$V2nCea'2h aMc5d^46?&<\jQz;кon~-lOҗ&^Ym>++ggggg`g@BPs(>X󐛌Z&iKTkiIIB;lc,$#S0ėp~Ǣ@JInEFWf#ڜa_=4XrHUR!9DK| :xtBo^̌:‡ĵI #z9o]vYo??aST{_`7MMoz M9yu;;|_8|+^?YhSD{k^ݞK.dg>|3yP|N,Z<ڶ3333320> h @Yh.4Y@MؙJm$tH:P-³tds՗;Z#&GcGW.l|.mo} nplܼ=vywKom&6:sm_~G>_ " vl~zo׼絻.#~ŷ]=ꑏjWS\\pNkO;6i|;jr(#_ggggg`%e7Ai kj"t$g=B.BAJ?AC,#Zfma (o '@hXx C'L93^KB*Q$ p}nCHq (MwB 'OR- A*R5~U23O醇L!6ms7;[8oWߍo|[·p;1V=Apۃy[k`?ϵs=;sQy u{]ӟ=g;oo^o~c% lyk}+K.ȹ۠f M(`^W4nzf6.{v}"GES(k|oT߾k-FE~9}_1u̧=,k__Wڍnta^E]<ж4Xn-N{zzzzVR5ZrF@k,4]glz16`<Ȑ,nBQ/eR)>3Ȏf2 jFZ"id*I(q`ҧsc4*"MgX~ hLaDAh(  i ɵ!+m|*':g&O{NЇڷv?{=Ӂr |з:]ӱۮ>]|3l~SNyȞ*l!<pnݺvawko~>{G;Z#< :)VN}ީ̘nzqOj'xXLx&zM|>mx\$q;Bj6xŇO39| ܞSڱ׏5 WY6)/y7G?<{zzzzV\TJ$VML(| FE7{&p'lpF'πO*F] znlxM#ۓvDA$l#:5x"&wsk&ˢ5l_Ba= lu6S뇱amEKnl= Ob2TFTNQQQ=h1 vrG<z!O_!4~xIОg8|#Dqz; P`` ^{H-y_ϙLov8˯Ir (ay9;SN>i^'IN慏o[32|q9߼9=ԧ,:]>)@'Kv$ w0+3<^{[rH 敿?܁======;Gi?e& V*S鍺34)OH0~^'ƃ>}_h[q<*R Ĩ$ E\ ^B[&FDL0:LbE/AY3s>]I>K_R[~}v)^]|o%ggggg`d`%aV[X՗̀U-$:V؏h4]߼/aǜGO(@h4 [CB8dljk&e ]11vO=VXm*8ՑLuim$&~S:!zGPy4 8~p, 7O<]}w{g55//5!7Grˍx߽O7-9lheXp&Wnr0A?*³If6EA{h{Аդ8A8$DO7+[2fߋ݊=)Z*uZ.nTY snt͔ԕLhG}UƘOYlíYh4߂e_"VAso========+%k  ;Y4M'f!yKA(z (NIXLs.#3i Eiw^j)X|^:GzXPAh:D,9I5+NM!'0\x$3$u&sFѶS ꖪ)ZfT)%qի1`sL  \9@aeCd RS'+3dh34@ǜ'3|@bZ/WK~r`-W  :DL J5$w@f;)8(00gda8̬&BˋrEBư#|NaĺnIzzzzzzzzVVʰ@"thL`5@Bqh#-Ezo4Z\֪2K -0^4J8ƑC|Fdaq@k>fC\r:..4k UH`oւ!J[h,S}ig4&TqJzXYP2 ʷh30d^JiCXαGU\/F5e}A2B-Q"-[qb(y3M0$$Ah0G========;{ty{qČ5ea%鑅%;&S)xTj!0˔ ?"N-1Ch~Ћ \Ji;C b,f k`P2:CmwG\eؾVt,؊j ORt$g^*>ߴs㶚(aL385f6|JLgggggggg`dHbqh)eDgF,n4 ^j&'(1dӀm'+pHTc !?LjP*)^CF@ 'q8Qs%*fa3*7kǚn鈱H18H1Q2*%Dš $ b gtSjqxnǰ؅@? CFD,^(n17=%!G 06D5wӏ)cid $G\KS 024e5,5le1O& Np2`-+k ;7V l腜-J5Q6"8a7iFTlP 9m EaO(=bQ2U DzzzzzzzzVN2bD-p̥PH2+qRW)(j k`OL(3~ I( 1n*@[ơٓ2BQ~l2@Ӕ'BtG,;b݊#/F"LB*.VVyc5= U  h5 }@@@@@@@ ʀ (,̘}LIkуL0L@TNوj%.OēoXPKzf\+h RmĞ,J7UɄ= .tLuCWQOy1q|z x#d]P zLxÅ"&I%ӵCVRqm,I\}33333333f`:@,T>>8r >C>o49 I`( fM;1cCЇ&[^e!8N)vPx L$- V7&%T2fn#/ʔ.Y>R$ŊY^p]P;%_;!%8Bl1.ۑD~/pT2R}@@@@@@@N YJqLidg1Ndt.Ft6S\T~WiMPiv6o1OZ^JCo¬Oh,s×j `{4tJ+2ٮo 0K5ǽ*B뱆5m>cqjcWvA||H?J(ߐ1A,?+3gggggggg`dHJaͱaTSRSD-/ϳy@kshZ fC31 xFWY ~$6+YJ\TvlA#S=MA0)Oôϼ͒RCD.?z9).1Ec~b========+'^w1@O+S>g> y;&9.20t-sK4/4W1QV/,)ǜsi,A:̢Z ި3OH蛎~.ECvy iZ)0A@OfjYx[#Cގ%,aKA[AQ exܖSk^b~)rYB-gIxj#Udl,k4(p LBeh`c!7Ԥ 3|g HvXn][du[·Z VZt ;k gQPyǡ `T{33333333g(AeQ? Lh^| 9)K-X aSĸn  y;S}] sQ:D\È*ɤ j&'c0Jh+&#?oܦ# g=(>֨Y;g:"EXح5RHGVᢱ*AR1 XzzzzzzzzVVZ$fI m1H$ąJMY,x/dJV76t)>#H,ȋ쯢i#㍺_HMy|=pXPD/Lt୊ น8VL͉a;#= Grc.ֶ*$ꃩb ?r9†ؙ^IJAADecYa)Awl~R[@@@@@@@@~!`qE#`s'1Ąm&tg\24̇lL@Gtʾn%_Jr {CUĸQ`xMw5oT~aBilyAJμH2:L ›i,ZAh#rXg7Ybd&7lFV[dDXziDŽl3"Kq̀BA9=V۵u:֨D eF8Q1ɕsd%CF|hX_*>rU/~ԫ{>3; 32'/S9gM)3']/[⵱/ ( NAhN6Fʤ &W yu~ ٰZ@oҝY$[`q[Q?F_"yedAX~p8+nb/Z8š} 6^ǮuzCm?FTp(G֕zҒ E#+? LqU:[z_,9+d-ѦHA] nNjId QGHi۬X.tYu4^ڣg)\;|ej|lOuz}k_hgوg>5vЊU;?M%\LCk'!!;%ZN}`烼lK.{C| 2A رB5K&C5TDsB(t@EVgb'~X-XSWkl ֤sfό?A04jRC̤(SZmAmDionRoMr@bDR l zڴ^;"(mՆQ{PLh !9'ɵǣ7a*(V풷]X#@!`⃞L\)KK5GIsHfpd?SƦgF>3o*H, N,2ҍ~@IJF2 "pWESLɐ!%.[8k̐1@YG3^D!7ւ]vJ6]y< @KCecN($y7bQSǚr&yg t7nZvw}ha˹ YH*, (@GsdR_B!s]\*"O7F33333333R2o*lq 2=,"⪸'jR`,MkB*giƹkcBÎdYb} 5 Fl&P:y^|4+8շ~#u[VsJql^a42-8gJh1;A_Ƣuەh+/Dmյ!b3ICefE$<ہ./aDV5F,fs@@@@@@@ ȰĎ7Y -b9p6dMɁ5IBo)o _-W|gv>Wn 1 LL[$CO}jߴi ttݎ+*d"H)–6s/dJ`mk 3\r.'eKE+:yuT!י!Ǽdb6P}.z^8^=cj2_r7[ggggggu.WcaǐqSjj "Ѱ -bQH@p zxbҳ ЬAFd4N=wa4ᶆ~x;vbJ}Xi/\I>z9?ixNLt9O?c(>mW~%K$nͷq~1{_ZDc8t{|E"g[lJob`᷵vMu;oXN3T1n3;*`͟mB "!Ŵă8 Rh^ A7IcṵmDUC,hؔtmHHJ)綫sk~m 9K*>ֵ97h_m򞁞_pT2'@c ш2aHG# p 4XebD·_n!ҸPahGx!,7Ct|*=eBD$&;)y&ѹ~o[-:Pmܠg%뙁: \,`K#w űgTcGTF'(GkUrqaCͅ0dkttTCv㓤yXS8vF6aŽ{?vG]d&?Woo zzzzzv ,&pl:0s)*zٵ,V]LC~P4$W4lWpdHUPkxި2'$F[Wl@;mPA .BT6,Gxp"yL{O1F&`}JYƬ'IIyk2YkWF%J;x"ϘWⶌhg͉ oTmWSZ]`ؐ(瞁/k#i&8&6E[ x1gbz+uFq}5~6:1;Xp^vSrҳ\U.ec\_naJwiD_R[5V7I-YTGs ؉ !Au۳Fٰ"!T}XkԄp(\\!#lNL._ȟ|׾9 ".Yx 0bBJ(\0`y`h]y^#ͱz"$P̽DJ(q\q x}Ť!;fMVFF04d뵡koߒ.-EQ8TblLBɈRϑR͜ 7qL+c$NcQ:oOoc΁ya)0)2AB%Sw========+&``P$BE&E Hl0((4f:Vk78{.s(ZľF#di`NEٷc1F _ {b1Sk MF6nmXdlj13}d Tn~Ȗ|-Ӓ6~MCX(Nlqt  /66a W:]˘*L@@@@@@N?*3,XAXcdzTE_^D-@CnƿzGAY).Qy+KÈlی6}kϯVkD &ٔo(> }3E=SSf![aɗ qS_CE+9w^ѱ>3[/پO< pl"fHDmm[cEj[o91 D2ƀI*5B2`QsR4X᪥& }v= s. PCnش0=O<MƇ#3)mblF,eۻVY 1F.Q2+"?9nbaGQHhR1q-B.Pa4Kе0ckdyLa6g2mom+__;ܵu'?yG 333333SgA%y)1Κ=MjVGyUG:zpςYdJTlvVSɄ?oHlLD=.j'gYNp*l,},>0uGƖWOs¦ ϞD}_ Ҩm~Y ۓa0d`3 ;6\h0LMwP,[P &d IDATi&=QjO|anx-xץ^_-2v[k~^viWg{zzzzz~1ƃѥEo|8"vZSfA^Rf;0(#[x[}#_CF_VXd6g;)oԍqP~%kgk)l+|'C=l#!"IZ,A~i>Ceexlwu QS7QNΐ:hM8*ij5v-n}[vۭ} OxBuӮ?g?;h}c/y7Mwm/=vea`qjy{̧pyܮyk?]ve /l|A߻n?Y?Fwh\r@"}K_nvw߽wno~GS>կ~e_⤷3 `B)i,*sN2j  XZP\ǃ}| HBBQ\. G̼ޖ?*d#mKEF60 sPG%h& D,Oc1ǒ"h46#8v*a4Fy z#Gȅl)w.>Ro(Bl M.$ҙ4˚0kHmw@Gn'i~~/ngyfC/h?я~Yz}${?7aIE687i{^7d9yyuYvi|O}Sm7n`W򕍃<|{k/zы),k7:.hlg \u;`Se 4K +od˔YL {gu:YqYvc,vI H1)9 +qK`Fi;5tBcdPQ&Y2KP?jJmqVԕUj1AN*!p" E#uH,G݀=Ks5ex.h-7ڤG>o8GjWZw9}٧tAo}[|3Emk['?Fq^To======_EVJ@ap&8q88 `-졧e- u{бoCIVhōMzcљhؖth׮ PĭI8B)ː2o8cx=-a># Y `BTL(rMt3t$_@N74VAEL(PAq-| 蠋jWSUAɢ4@Rɹ][._}=4WRWn~q==׿uݻ)>o3!g"J%w %{Z3rѿao.ntݛ;׉ͽyD/YjMS| z7V/F׾fdg~J3X8RƎ ('ѡ2ƵS0Thr>'J @8 ş|Da7a`6"] rN6zn+Y=c M;Fx)?p"gܞXK1+@/D52c+G(GbЬmOC( ROC_MOҗ䝘aS}\{zzzzz s ?:Li/!8{bQ+F00TcvyY#†i.vNF0<$ſ} $f-gYGآ4fAK )m4(^HZ@2JS;zx>t;(@(X؈$1  BW5)yaBei5f{]co~Fn K}+ч 蜠?:P [iz1O tPsM LAgu"BtɆౌV22{@b霷v83*VxGyoM:y'ɕ^׶>vk]p} {jFCzH?u5o vhlB)[E6`J!"gSZ<#E1 Uԡq2وS޾t6x85F8M;$QNE*Aa x UIC>n.'zÎw“`hWmJa櫠dD 37:FtR nĂ<Sc9vMH;| ׾c.\ߧ?i^m^/❤w)P3zzzzzz Z$'pK. %3 Е0v$ CTjjCF0Z H -Աt($ ފ0Asn! I³'sW1=5sSP;v,߿t.O8ϔsƼA뷌-cgG33333g@; E(Eb'+xL:glrK[I,ݠkmdn~<A 5?^AWW&qdwD44\ /)y<(XRtXn" \-X~bA|1G"!dA37ȀY: Ppc0ט9-Em23t9pYE$#z-)?P) n_ ^[!\eذA e b3v|XsPxLZ@s΅15Xs0'B<g.۱0֋̋@C z)'! ׍`X[!dX:\`"O1i#5b9dLr1Ƕo#X|UӠY }R8WkE|/S%DMLW)/&##c=u %4w@-x*f#@o#sQM`kJ`׻adn{?ϴm p5voӮwvm/ggggg3*@@Fi@ypjVf Nj  'ge xE\`g8t1:mYL:)=V@qY%OqsX!hAȉBϥ//#-3*A<3 CM `^cԸokJ!T[Ϙ,C5%BN:ჼPhM6(-AJb-E+2m]܉@F~AI $Y )ױAkhUoul/Kpmvg%Ǖ߇vJ۝ xd֠E`lL@:"]"nK^+8CԦ.A5ĭΰhaY^ #iu/H\o`8@:!0.;)Ô=;WyL2ʅJp/9S5SNx9Ǽ iQyC4۔W:9f飊60[|FL`N#8~Js< pTଧ3(>TFw========+"k409Cpx U!6r ZV(@֨W[5yofLqt׀S&[R053ak"c\b$b=S~ `@UT˒*wb 9#'ce`J -Φj"DFW~wԱsiŕ:)ǂ3Fs27nR%I9gggggggg`ee`kXw݁}"s*DVU|[>~>`oA X!K {鼄eBA+0lm_>/ 0v?6NxlYFB!JҬby \xBrN>7q[U “/U}#ZbQmzߞ-W<й|ߋ'zzzzzzzV\& T`'G̏ϐ0q2g֕~{eWŴ%΄s$[f=ߑ[t9ءC{׹I|Ï!2ZeʪZgQw|AVb?.if#esS}M*RQk +>8Od"Í/sj?~߃pX'hŘN,ΊSN=j<5S \ENms|XE`XEFÄ{t30:!#dϪVe~ *\b0Yy\MO?Y't|bN]"8?#oN4-LxV+L ӠNWʇg'w=j)!Հ{ʮ[+IĚ$3-`$0*퉡@1Rkr$M' (ʭD؆ AFš i~s6,",".M11.0,[rdCc~{ m+|땿hɟ;)sBdBE34̓,!9WIB6H TC%17[W:+sԂx湏}\vlaxB2 ?D"^ێ4M.@qsvcT(\w8-|OoILYl~:ЀXB3GH3}gE`XE`X7@@ ̀vʁ?YyN=6O]K<܇&:YlNkgCO%>Yo)HH= $z~R6Ŀ2842-'7"<\p{o$Q:3+C'E:NX ^Ǘ3~ٸƒa<"Ss}XَS"g{$g{XE`XE`x4ٱyß_c!CRi|Co lTnfĎCQER_zH+!r:2L~"q Ōx5ثvU|W@*Y>\"gMD)_52>̼$'eb,fO#ADމFy5 }#䙔[t2$?xbKo;&FE`XE`X7@oBr18Y8uz4t:b.yWecERyKRP?k/SoRs_E͘VCin䊎4=M~G~"}\WaMU 8jdc 0GX>(E7Wp8iECM1g۶tٛPd",", + j(x&!P*mäg&BG孠\n&aH6|DƢgل|+?RD%|u}ȺG<g*uLk8^Gy8D%f||r+pUBW"H31S/pplh>ǧx▫+h/~76)žsY|bv(őIF$uNXDfA f}T_O3کtXOc{>>;E`XE`X CKMczqCwD囶oAo"v2 2!_4$JPzl<$'u"]pӌG^n1 -ꬳku74my ?~֍#@cXE`XEM3 Ü,&Y4`&#!pMw;MB]GSАxٷ6b9j4掩Cʅ8?s#vGҸ5ܖ`D:D y}]="7:Աx&Z"q> 95T{c'g",",[ _BB^X!')DKɇPF?>W7#4*<LkԢ 6q$Dȸ5p7F k>m5a'? ,|E0jISfH}߅RwH~nI)u_#sdc_m Ƌ}B -oW"=SCLtK5.;]E`XE`nMu.? tg !)g{ze"E6cFpHLj">0u8CٹAX?B.7SW^W!@ OɮŅjkIhzхXo|b"Xɘ:zt;E`XE`X sM1 0v^Tm4:"UYJOkk**?%vu:ܬ?ªm gg} _ TcO=1HlfQψW\dR4iʦV;V3NN R SyI ?I< aXE`XE} YbxᙘG'JH 9{zag$rxŖ|e8_k;'`$EQ~7Yr󻤟 eh6v"8q$)>?Nd {V6k⸞I 08b::u.6M׼Gl1<ُAg8i-cXE`XE-Xf[lr+I< f1&XTRsrq%0'.B5!9/;o;9v#Ydc[!QciԖ̱5{D;1 ku1f(3NW\o|qtDžK_ZS_:͗K_1Q EaXE`XE-ȷ`BBuGٹe5Au#i"juԛF|s(֊)uJc4R@;KgE^r#=D+j5Qz``p6ДFb5xG|O ?e=,","SDvU )p!&'X6)3WI:IImD̵b$Yj[5y(#d?䤠t9or_` u">>s1\A}C$eq sd#fG#4Isj:x{=t5Ud=@ GL:|=8h",",o3oWHWMb')ޘu]sHy*wSBlO\)$?[!1+\hx$mJr^P>Q5 d.7kTqX[kV9v۬$s'}J25'd=.+$Ć-Q1 ",",oK2xF~ԹQx74vv f?M?N1MPۄs|p I-q'Eb6P{c+):-].w*#Z̲ىҧlyd54:gá_׫tm 89μƩghO͊:P-nE`XE`X@3 ' a@[X1t&SH~OuҝPDLty}liN0Kb?̈{}喝}L\eanٿ߾ 4'PH9k䶶Ϛ` QCY> bQ PS1 F5Tdyq8j:xs+eOэ]",",[ aJ C {_E*KpQ¼~\̧u$?H\Op!=?g)ۘnڇE7:kLqK WmuZ渓/a} $,:`t1hOCVO:8تLjd\{F]8HSM|+l줃%K"zB G4&ΗKXE`XE`x/>` ~^I#glt(PCbk=w\D/?h>Nx,Zz'&AsN2eDJ*vy ȭrE89zA4:juKc<_t*#Mz^\ݠ6*nɒ4:m^5.4j;l=~&d ,","#Їе͒rG`ˆB#S4ExH֏M}y *H6mz„Odž& th EZp:ئ3ѪÎ-m98匫{Y#$8KJoh e-tB|ADtRr Ň s*5)\P\zr..~%l~zO",",B{&v^#07&N8HN}}bm,w~ qkn =< õCҜ80L0!'h)1\xV2svhl,˜:c뺎NL{lF7K̙<}J1 ^#<‹+Ot?jФ[5>]Kq wek",",!ЇЇY2AEC"2sOe" ox%m^"DN.fɳOƪ0Z-j kr& ŇrĦA۵;j>%qnH,Iky}T0Aj;ʿhxk:2̊ B.c3N,dUda0tVy)lO_ vRrŃ+#^3(8#䵌ÎE`XE`XwB@߂efN9ıRFpoTd3 YCpDIπ#pnVDT|q0 кEϜvs"_A1a^Ә\DSs;^$D+@Y@c[񕂈#VijĘ)+<&$8è$^?t Q+nJ8[9)fdsޥ*]l,","\π$mϕeJk!(}XhHu vŗCMOٵ)ܲQH̗(&#L@ϳr3цb<"Q~|ώ(y*) n|%>g/ CFċ/lbJ<)VOJ׍(7@ș[~,3Z yc8hu/SƞE`XE`X=2<64Ի6Ժ:sLKeNj fqܿ'!V[ Vtzš6~% 5)w.!=?ϩwƏz죳?͕4n$/]2f&q`p)clNs\{et 9l;Nf<7n9>vu4s܃(E4f8 {/5=rڀ+\i`ɛ'j ,",!o*4#75pHh<'# JCW>% "\9 )_GVO٠3&Ci6r=ɃK֣D35*"{ƥbBY~}5 $q@6Zy{s#!u%0YM %ݞe8j_b0m\w'k,Ob{;9 o3Ѯfj"Z,n( t䟯+oJK͔ ON&ȽPkVt wt<fI+aE(Zema污 >r_+$I1C6YWRXyXE`XEGFs"x 0ǜ :dSL?͆H'mVZ$TUnҍ[nTBjAۄsȱ-!{~rBWe^_n~r`Ė4"a8Q |'TVμgp!}E竺 gc ~u#HHi Ho"F@pds5]N6q",",_wv  1E9sI>7DQ^y_<-B]3^?' l#XߛK*bٞ>,em 7T=AHC3<oW9ϻ^F?܄|RFvgHElM8֖_Rc?cxʈ95&!VՄM6\1sɡ}~ 1Pџd:+`˜8؉f>ՎE`XE`X?..1! 50BuH1rM! o,*N:祓?ULDn2E'>üp ('x}t4oY_5 ⼦cs C'?vC\lY4;#c{^E`XE`x Ka͢Ēp&+l>. a?2.X^gWz4[=*4#|n,+Am"(Vk 0oDI)T _ɐLŜ[HΥIvIu_ !2sN2S5g1uIJ *ؤؠq #b IDATT=t=qi>v妢 #(SjG.'GF%Aci|e/C?|;kk(& @_N鋥Ip\3C\GpxŔ9obQ`m8.q^6ՊSCz-Y)V\?qs-܄LC|@9iFCsNmir\ tg?z-\t!契y4mcmD(\_.L*'Tl[8,46AA50s_~-O-L^W' ;E`XE`X]fCYY .AɦhAnt&C0دV[Ï)I[!y`aK7sV~9䃧-KQ-WC nj%4.*! _cf]7 z۽K`FG)#RE0gGh:!B/_EB^Ou6UlŇۙVCටAͧ0Ɏc+>85HF"4fm~\j?k ]r'.?\.&qdU?xnddnc;nI\enHL[XǬ>/-E?j\&@Lc#k9Xo={U/YwlrG#}.'CDsJJ1:%ߞE`XE`X>+ZzK7lhxi<"'nxDjꧮBͳ"ZsvPXB==YE&c4G&:|ҀmWZ9#[mhϺ┅Lq/l.~f9",4Ƨf:.MltbVp^sCMX)& K'jҜf;B7iXE`XE/F@GېaPcq笐fH9puCgnЙg@zK܆!I8ef!k->q@iCנc-[*NEmUȵP/vWW?8;df:Zc\NA+ƕG*f.hyEoBY`:2%ljWXd>єuާ2[K`b1{Xi{^E`XE`x>xky&(8{@>J) "ˊJoDE$@n(ti^zT@MZ90Ҷd.+9!~L3|yCUI>!Pj-⸓<l>n +D.F,Zlp3+/s|="`QW=4ǧBDWBd2=SĞ \v",",?_<)4 F"mY9M?X(8HyltIP]?P.E x$ WBDrr%9519'-\/)K j`}Gz,G[(}%.$'59s2T 8m8yB8G#h6ycցEDX7NS? ϕ)$jJ4i4I1,",".|yC]s!L?trݚʧ+PjEYXDv€7 .?UMOmkGji@l×u.;4SE*sOj5!Zcd@1 OgA&4n[,4;\6M3IW܊ק4F&NTcͤV!z_"",",~PУ$9= U<ľnlMT>pF8;qZu"LL@ w8i}NIb2҈6.Kճ D-NOOU4s$ C+cqVy5&.6ѱvֈ\[+AI'('34 U{)0*DZd-R4/xXE`XE`x>BBfYV+МE5W""؄Sy;p]]ܒZ.3yD:¨i,a?7[hQf|rO .̯k$L'}r*u#sk96jݚm͉I *rdB-Ick)|+Ԣy>`/ VIVLHE0l'flk",",oIiiH?s#EdcdFֱq=h_&a|wY1?:76aW@3S _xc,DId"5w,","bnsHDK-LLZ!XbPf,=;:"D$.XD4\} 49n@넞CF#0ߢEPש۲ %Y2h쭳~J| S3ѣWmЪ l~Mi&N8y\1݃fxe4)2 5Fo =jB61'B8(=sҋӎE`XE`XB ` $ȄWGU!jG8^KU)0 9{MX]|o6MRNGfc؟u=\xH'n lj$ ^Ҵ?:jNxp%۰|y=O ~:$$^гOXE`XE`xԀya:Sa1cn2Q ȾtЭRp54aWCkBS# :I9mttn'P[ |O0}A gl2?I9, UF-]p lGVT(8f%=L *Z o)< +X #=qI8`ͭZKs ",",oda/jX]b6qaNĨEEunrLȘpS_vɽ98<ɱǫi*|E25}w(9I쀲 NP^vA Y{ȉfvvت&1qrm<=6( ҜR] ~8||;ڸe#ٚތ<5*̎E`XE`X@_k8S65B>9_qP9"RO@@Ax`6m4,[E6`i2qsM4oA]5qRCP7ZjC`ԁE KO@0;"'A Wl-&C;as5Z[hH$7}Kk`'{5i؞,; Dv4>?Má_Uj$&yvZþVJEkVR-_Mt]O׫=3Z,E`XE`X@ ȰH‹6SdGzM ߱x1\vًgO3bȷ$9B58ۑ44X{4i<ŔD2!^CEj0gZF ʩs<ΒMF_c2z`rW Ac9aD5¡,4'<\+bπFnKnyoUl,c@{XE`XE`m([61=dG$Bj>j F1gRu &*Y~5E'{EMlQ.'As4zM\ӔʐGf!Q!OeK9!OK0=W4c&,GniSt݆`SWBc o?z hC~r! TE`XE`Xނ kwR3G ^6L$T.${!W5 *챒?PO\zl YB:@Q׽m!arr^|K$w,^F}hQkC+pV$FFSJCҀ%K4?7χ7⛱p*ȳyڱ,","VЇ 5Lk3}"B/0Lێʐ 919_iK1e56%;y.gH?4s2~"-l'b!eSIg=GTOJ0nmzoP-1nmHH#%+BaG+m點V*~+#j@~LΟ:$ܗQ;[E`XE` > G<|0),n6f"UgPXsg@]Ͷ+p\Luqy*ٌ:sQSgو#Yڱd9]E2s^B07b/_+S;"y'J ݟ"*Ùj kr.ryO4&ܲ))~Ց~cs=8 a3ItJkttq1ihdtq8\8$w:B!Z]G5V"Q%(u`"/Yy7y㦡9{9k͞G{DǫH+GɐI7e#ay_cXE`XE3 YzxT%RߺQ!⦟WdjEgg6k1O9r&R>r*pZ;gn#ty'nM"IcO#[iIqxji\ ~yvyۤ#KH)#n;.B4\ X c=k6 d",",o0b$Wcv.C|wm8Ld\ z#ڵІ"ꖔZg Q+^d,jٟ_ߕȠgd!Z,ˮqŢ/Z>}-N?j2YCtvMYZl{0rͽD]u!g7o9߰'E`XE`XRЯQ4J0c\ni1%>sd15sķg7=êmUfX㢃8Xg#z9DWI}-9ƛul`E- JPDio2GZ$癨TJFр%sە5LrXP_?>u",", q;;+92E/ 4b§g'\L_-DvG-~i4"E`e L#%!EeĘ&#qI¶u?#TZ#b/,~p|OyحX+|?",",; LPp> ْNH*dUNF Z|bIoㅥ~0(C,:(ǣGƕ|SِMuӐnYXoې͇@r0հOFv<8&q<5GMo x98ӏh>ed#6XW딺cXE`XE=(4fnNkȤIF#z4b(%N<0Qzco W}o*ャ8eڂԆ\uOIpԥeÑ7|at9EQ=su$gFQMS[!h >4 3I:lbO9$Z2̵<enc 7)",", _Ƞf&Z<Ԥ1*XkvF yp}B:-M y"4d{葑 qrΊ3tS_dZA$j4&^B%G" 9WJRaT_x~gTFII6G8 N9GDv'z!O0ȞFvEu#;E`XE`Xvt$pH!!Cp1vzAB@WL"s[JHMob:bgK6>fphْ=4 AM1<ң4qQ3s% }drלu{dIK]^:+?܀4tn:RXj(ϓȘadxʁɎE`XE`XwA䱻5?姪g)dqZh,\Ym-IEn>/%GL7ĖԤCb2DŽx=V/B4|Ј9m< fB?!@ݐ͗C WϏZџC̤&J |ŋx\'+#y'Ye3 H~5^K)nFCq Eâ? jCiXE`XEG@ Hn)ֆ͌VB$0Hy_ IDATN W_ː>k̶RJy:k"6'i:ǐmks=^a {# |H8 ʆŴ~p{(DԬ8Sj9sM|C8p/x\fٛy ;{>.","1':Ȕi2FiAɱ@4t*O}(xGηК˨auL!/*&84bO݀8plg&} rTjiMzL̞MSbLQv_vAPPZ+j/'J˞xSB3F%cH(Z40.3@p`Î9`qXE`XEG _{%qXaJH6̬32{jev4)o775u ?(Y1=ʥ3)o3U;UijfK\%J% JR~9؛ϚO:]] $ j9DGi\llL7M_6j+Ɏ8u{1s)^yqu_(w,"," gS3b`Z9Qm&ML 1<--7n #u^O5 n~Zgh&TKO!DD8)(YJ\^^uKB?t(&M |*#έ֜7%#tΨun/|({u_#`3ʀN3xI?,","#+ UG0Qme4 "`~CVEaC_!G"ء\ھ:I+/L]%n%j~藚>Dñ'u1I:%vj c5rSZ ͗9d󙆎(h z0I8TL.D;>x6` =o9cduSψm9sF}l E`XE`XwA 0DUHXc+/.2 u &^?~B绒d2?dH6h> +r$퇭i:~~'͇~=_Z6T2tY  LuMEiD-͸%orD%1#4A*kϭ& /^gu}$;B /hbZv=͈9f:Ջ.{\E`XE`xttLrLTFj֨9$2f&̭8е&!|V՗O>nb;H:D lCV, g:Ftd{w\ KvkVS/" &O&04!&ėPd51`9zl\鸺|?ou6O:L6 7G'0:HktuWҜHB S'ysͳ9^DL)"Ѐ؁7u PE"yOש _cV$;K",",9b%fI g7?1M7Dw[!ŠnNhͥC[~ێ$I2sw3g&'c E=yQ}kDm8pP*ZpRgEb;yXE`XE`x7z K,hk9-H&5M)i",",k/D^G5] b9Q܄@~m_H:7cؼqN2^I&[b@]?g|Տn?V,dëMf\m 99W- سfFS4% 懿ix>5BwbO#1|i[#}8zŧymhE_~u_>DruμZcڸZ2EXL4@'s,","#[C$S͇^˓̽X' Y0kj]Ρd||KyEW Ml=y>3C%2<^C||mĀ8YYhz< L-7ř)'NW;3! Ĺo *2&hNyp;(Mvcr`LDhQa4F.ӆ"W`&ܞE`XE`XC#5BB$c\Y2?| 5*^|Ys;"XY!'֧\o||v'MѤ@]R8{Pq-zG6qsp҂+4zf,ceKzV^L0-ULtZIܐ1Ւ>yyҝɌNמBN#beҼ",", 2@ y:|_RzU(ܼ* 5ݹ)* syHN$ 9/j&v5|ݬ^ Wb "br0v)*CňDS4'ֿщ4.;Ӯd~FgU!4u>g1- 6ՕI'rH* =,cw \9vwE DI1Z@L—nOK<瓃lXf$?GՊCIP3U8#Bpa9"kqs#G'&ºZVhR\" XcQm=_9ji+:jWiFCV:j9Vl./g5 :|st&StjgRg0Y:Ȭ{Ȳ192 cy7Ӱ Oߺ4?E`XE`X?bhb Y̧f<4Ç}N 61䑵+y^;3sKK1F$pD }9kF3ۚXu^<+|>|y>j",",n6Bab^"Vc`j9z)!4k*뚌Tp,1& \"UzWbWޮq(!zη^Z~1u/y,{IŤCzhĚxX q)cdrڣ[̪@1?U6g)/|8qy]W2r*E4>睬)`}%?yәz{yXE`XE=ClԢT4Z60\e(V$+%rl1^\  u&p3;!m\/!yF'ɈsX9l}ou ='sku]aHv\3CLaNRgE &?6OLlG(v:哝ߺ8i4.4zXE`XE`x;t!pIWjanPRg0]{|uj BY\`L4+yyY e* hp:$,!*%98W?l]|7*s(9,وE%5v&^659buz`gBr&89L=.","a&pî!πWb_Mn!2-yp cV=Y䔽8sΓ\Z5F9KE26P!GCl,K/GmvK9'uj' RS Oo换S^W0Qcrtǂ(b'ލ`{4?v &=GٷʏNE`XE`X~; b!eD`q:q!"KF0TcuIU~lgDD$ږ蕟]jːgH.n9Yc9-^WM6u;C<g6f-1c)U'J_vzmUڑUxKB/7eOG˳ryl=rz;=,","FцCN\Yń;V晦"lbj'ϢJ$䥇#aPOͪ3}TGNpc8@9v,_F})g- w>C6C8[ub6줸:Kg-4Ɔݛ9T7OHgrvъ%[a}]jE`XE`X7@#T )FX%BE),CN.Gb=g8tͫ2ɕt3zE[JlytC3'Ld3B8QSv`IL^ 1 "6Jsr4gʳvQ86:O-xhNj=CgOdX?*7 cӲH'׹/q,","C|;DOCi| W5kXE=늽|=$'&_71CΒ5,=Z3fi3k9k1b܋fqm L+§ڳ$81\"ޠ&{̄s<7qm/{,BiDcXE`XErBVpC7<RrUMk%F "Z ȞZ2zDT{r;Y1'U?bzlJx*?ћA}{:1돑S1Ͼ`2mDMGKǏ SrFJ,n/4>OY\Y5(B=R7YN?2D",", + !a7aX)GXV躉 bxcoT iR',~2KJn9&hvKDN l4τ Z8Q_z!sSET9q R ꦐɧյ|t"Sma ֳN~UױdUpPҬ6w;Iyj3LgJHN=mbE(Ĕ%Øw{8XE`XECC 3&ln^:P<'I N>H5Gآq^!=Hn46"=Sb3g>0Y/FPq",", pB7)LB!IjUF]n$ jG*ea ;UaeAU ^=M:5C]"DYc+[UB=rPI#j)GwS[p9 _f 9bYzYO^O6{h |r'KSNx;е9utܒD;cd}v+_GR9&gd1!@_ڬbp132Ng3I^5LdXE`XEF#L4{<>^,nȤB!Wu0a $=/pO.D{Mh.|: 9ctnqUdmE@&Ԉ]֑h yFRQؗ%.Izyžn IDATJ:K$.(*9p|y !fMIdg{j7Ya",",;!I!:Q0Dq좇3՘l:CĶSD88%Yĺ߄:+/_Yd[:g?j>8WJI>P*sr SSd@8f4n>\8ޥt6G鬒3'u:؍̕\&S $dhK,njCf;4XE`XE`x>ðBd呇0wZ9vHԬjS9&f5RpCW',L4j,`_G4G'Anq>sN5!-S f]' _=){n~ µ 㧹 L՟B !ns63ÿ|/^H_ [8",",ߍ@n9ws~$Q !D}6Ti}N2ᄨJC?ar:5R1Lo|폩Ó>!{i<-έGu (OĄuq4|ˍV,=SOSBc;22X00&>wAn%{%$|V!H%LXk7b",", 4E4<,qh! ٵ1aҬ!YqFCnyŸHgMcuœZfLaDbdI0$a$zRy| .֤'FH~yO\1d=up5%\ :p0#ڑsA{rd2HtF?ZʙbvۺAt0]k퍳L֏v,","W#p~]áC`!܌ax!F Ξ Ϛtq:>~_3s>8.aj&(wH5Ѭ&x]snK_EYjhc#.&"&Rqmr`:gKqopB2~pk΍ )Kf !'s*/"/ H&5*]x"栳hot.=^uiO,gϖ$@"$@"0DjB0sV6ݑ@3TC/>14 M4Gc*CYnhQ4:7"2mBփ){^q%Lt S&Ad vS+:̊Y|k;6BȽ0+JMQDXzzayz0}f|vg\k媡:af bU:GSryHD HD X{@<T%3?,szGI(ԁSS4gj:61BJJ> _E@ԑP05 y';xdKmq[@!,-9'hJd͓t ǚ*ݎX셞v>]ɡ|r/X<`DXXaE'YҀXP(v33.A!hͿZw5宍ȌᇎQZg4bփ9L2\-D HD H5~&vD䃜55Tmte`)]C f:HAKl`($|#1 R{'fo U`SJ0b g\6`˦L(=jxa>q{$t0/DZ$@"$@"0yML-FFs`ٸ%v4h,v!GCzvYUţjvüLsBfb1HsZZ֋]etR'S0zP&a2hKfG ?1WXentA=v TM0},@8Ǝ>|Lݳ`a")0No Y~|U-B|MD@t GH_F8F fKD HD #d:倧|фgbCʒgn"2s^:gk̀fyt))mv5\dZLK*[mxDH QL36?b/Y#iɳXMIAc"qEKID s!3ρLRQ(j/c¢ŋv:a}T\c?w1Žq=_9~4&}X/C"$@"$Ao`3!Gi&3D|sZ{2M$Ja0YL\3 ;HZ7+Y:,X"LDAvl8gVpyD! `r9xwqy-,K qDlhgR783ߢrJ |j^<i-rnW2EUQ\z`S;'بt*P sMz'^Eƹ>ܑ瞕%C"o8bX%@"$@"L.pzZ>#h6iРЫPAZry&n)nRȧheFӴG bN-_t ėzv,fL'@G%{Bp3i+ Y`Kb8GAz.۩P8JQhKuU ~(R,\|GЎZăz] Fbw~]."đ7#.l_ F ^ݥp!}"$@"$@?L5eL :Z(YT2jK%)r7gd32Iv]D4Ƽz=HXuO甐ʺƒJ1QM# %bDbE<ʸ/u$#yXHI.: jcd"QM=j\VEqWi7~"8Ǽ| H|cj4=laTp0Y2YeOU6@c"T˖$@"$@"0i`"Qd|K1WKk8TN2"PXT ¶@(`s[DX.i3Ȧ~gS~ oԉdwts&ťzyE2Ag$V亐u!Q>ZCTq*DQ哮Pxmںj-`t )ldiM$z."= tLv9sߌ /kƟ-HD HD`r!` g>؎1aɄkQ2LACɾnD;3=  SioCoCI*c Hw7^Rm>j %C*360.vDU'b.nƯ/a[v=F"d>!SG\qɤqVhyIQHK1L,a-ܕᎈ4{C0%w/dd`ZtGD HD HɁ O7ozc2iz?vҴa갥%=vS?M Q LE!nh'nflҠLjƨH fGiSZ'z jd2Br}MuNhMm8R/KHyv?h|@.@6-I$P TĴ,´8 ]<$_ÄŇc̑ >cKnpȖ$@"$@"0瀠}t*ﴤXs%y/!D:ژo4/NcӳLvAFV$9Q/vң%n E/ɐMyĔ241X4%&˩!AM0HhLQ2bs994宁0uy>~"COht4 \@pp?B/CY}08th9A s,J,uyӛ<&@"$@"LB@Mj6%0Ni 8 ՘T[ʙ)pD%L M`!/iٶG w[.NZeK]NQt]ovc׈sǃ${ _"2 ]@ yG?Д"[lFKVq9Yp"ҕďqR)&/-8R8"rd_^xQRD HD Hɂ>pbC2QdofJ<"sTi,!Q(Dr)a8ڡY7Dԥ۰ Ls25V<1KAsWfGw)—,_Ib4sbtY %Q\׸8zdH;2,Fxv{>PzѺdƦ2Id7nR|R5sH@lAd A`' 4ttfY]"$@"$dA@x5{y$C@Rrye2]!jBadȦ>4qN< o c2/W fLVG1Y](~#N CARri܂{9(@v>x}9fKQNy*"lO$,"LS( =K!],Rx"c|-X3J̲OD HD X`iH=TC-L"O 5: ,XYA5rh\&%D HD HI@v!2!xҙFc|5-Hp7:G2y%`؝vlP|hSPQ4'sK;P/>mRU4=MԤSpz2]Z27/ឆ*dpG~@MzW9+AY~4/iڑ fH|~nuf#bv҉  3[ HD HD H&aWI#M̙LZcO-Av:Cǀ3 8L?oJκ_p.-3(};Cm6\2^r9fWXnFS$ˌٰwA f;A||.mY@so|i(>XYV^Da"R6Y FD^2{ 9vkЍnH6|Ab@&HoĄ䓾ԓEٰM"ml@"$@"$ 䐑2dP(n`S"!^i'$aNFc VY/Y"0C=ݭv]ŏtMe#!YKFG"7>[+8@cMh <6'^eab Xdѹ|p$1aNvB8l@3+h߸8J=bm'@XFci  Ӏ>)cu}#c BD HD H& ZeGȌ1& K6G&06E'j$+5f+G"qMJd,f S=Me66i&1aoؖs*+x`ҢNphGCVhѷ:t9hmOB+#7 @Bg QRci·k[l=:0N80 OZe%@"$@"Lw/|Ṫj.IuגĤ&ĖUOz-;ce{gDKVRd4jb4Ŧ$_Rϰ@]jLp160"F$&(9l[L²x]Sű!0(ƲxtcLmuĸ88j|Ir4i/] ZpԈTEA>li?Q})u$%Ic"$@"$A@`)4=TQ#.!WILà B'x]3; 7ʡaL< IdyG|,XbժXi;)046tf|ߙmˠe*x4Lry<~|#h$E.Œ#a[ QGn;2r=R1mX$N!+bUtaRF߁Р`7`bOD HDA`@Y3yE.(̫s2f.d'ٯ\+hc&,z7 [2ڥey%&]&G^GNJ7f[1zHɎwCi١ۯsS}@HbbKK!DA5; $A1FbRqC9$"NdBT,E1YJ6M jk"ˉK]~Q5Jg#@"$D" /r/ʓO>9X_|JFnT1NeZ 1 9= =9f@rc϶Zt.#lLHJ?lEзUU$Hl@"$!tҼjwpŃߏIc5^='3yGK:ġaXЉ9F)-Y5cȆ aJ8!^kLeDmvT#Ksc|5FgUh$OflRIv0t!r˟SQY4o-| pi'4f1Q, 1M%O}CHQ"pUlEdP  =;L?*,yHD xI$95Б"d© HKi8Zy$d2KӗɴTI[6Q71$XyX\'DMeT -j.L=aC rk",`|D׾*S#x]VXB4]Uz!Ih' iD5w \\!/EEIf Qb~ MUN`X Xbx9 'fKD HYL_G{lUzmYc(i Aasϕne+{9l0m$=]٩a)*c$sEvY1H8~͸LkU{}(-0W#(ˤOg̗h颙;O~46>0@M%ԧ>x)c^[D"9{W%,Uk1(|TԼWl. +N8MŔE/čiĥ%ʖ$@"Y䐃[.xvyvѐУlD&L$㱷L2tdK^Ɉץ3u(Y떪L77JmXwG:O~+ ژ}Lj7c07'^TvG&lNvf[2|v_STia6\(\#ƵD@3U @Ӯry0cAv5aU /p4.HD @G\yNY|po?g~<~|no4W9|́ӅiryC&B&)1Ddbl`xbi<##xL6 UIV`ZkJP1fWdMZnf0>@ұ_sdlޛwjuDS=E߻|SG"$r]4IΌJ&u /["$@"& po˥mÏ<\~zOʫ^q/L:uj9?'ͨKm<U%b\%RK$]!GJ:|&v_`q5Ww^]<˼ _exWcjRlwRC]2mr䇎,97 ̉{N",%8/.#Q̱&Lf#F"mS鄂dudsCJA÷%m$'Ma=aϾh ,չTw;#{9ejYks\+[䣙u"x1 sowѠ i='pօKӊ7q4wB>aeF]* Z_gˍg$@"L+(^v5ҹwR'eW?PWF|e*_ׂ16VxeĴ~!~4moሤ[#>R6tao1oVFl9^cn5gRھ:a!SPe+z$WUeU=6Q5Or( ~ mhu΁'ꠠx EzVْn^yMEΧ:T >Xb7F0GLuVc$ 9~~8)j,JCq(Z5>eK{ʍ/Kf~%@"$/SX|Gxw:U|˯緾Y~tO?Rw܋Oj o2Ƨhr%ڬYWWe뭷.ze 7,Їc=jgn@޻<㕾~E]WΟrOEǼVtᇽ{@<㏕ 6ؠG>^"ߌ=G>bf#gE˿K\ .@t~WUOuYG8000 .H`W\qEPvqGcܹsev?|ZJ艡vyfuL'ۗd<_0/ 4s1$1KJݨ %k [s{cJb@)Vff]F K$CMnkX]a,%@9ډp" H%?zob. P_е&vm5jsk%@"$/+~^R~{P|L;a+/;+oIו߱?+;sk?Ue]v-e]w/W\qٰ_h.Ww_9餓?q2=ꨣʡZyrYg)A}衇)R~o/Bm,>ArLdnfU۔em-7|ח۾|3P鵺D(BQ<ȃnrg3uưcw,Y"?"o.W_}ukuN38wy峟p%r,|.2tM*Z8ܓ290asΜ9O/oVx/}I{9=>MF8|x$`]M8$dIRX&j6Wר3 WqlyTA{lem&ܮ0vڱ!$Y{xw (: q:P4@UeWaSjb>CD5C"$@"2C.+;+.Z)Ok..~elsWuʳLǓqe=}뭶.vܙdMm_ M60'7.)~WغަB3^N}%oO; r"8e#T voݜDs)hN@;04I7zݴ ϦOFXh_@1U,DeIE/"D HE`ɒy7AËFn\ƽJqOe9UN"d+?z܇uO+;Syev.^7Q뮻>8"ŋ˿IXL]wru &3f%^7Ovm[oٮ;&Ky9tk77ۼ|/6(޸mQdq7d-*oW_rQ˿tYA-ȴHo(GIɵn1o܁Zt)>gdf07Ly+gkT|+R~K/vFXD0>a>`#XK չK2?TZ艢:Дp=cc"xL=GBWՉLCG*ȏ1{w*HS^he#x=s%&eU2TpnH ӓ$pd1ۨbA`[ϝ mwY%P A |gJv @B!&ƴD\D9zT1?+rvD H Ło-k W*W^}Eu#w>?+_OzaAywO'W=,,9qPxͫ_5e~y+K_&\^x)3:Z;Dݸwbj{E^˰Ϧ#%n]%b_{eXSA\p_^ʼy?*|y%X#6v_mݦVߢDvG'5Ik0JO=4Ab8-Ì1Zg.4-TIBלNb(`NL4x!(C=4R>8&Yut kZFB<Γp XD9!o#u)!lH6c"$@"0Պ3G\p?|n~_cc|3lwK_CޫWKqq׃ __˺o|3Ǖknf/7+4b v>fn?i{~Yxr%gygH@߼wk|I},wϛTحhaCCYS w`y3?~ ߸.M^}N6SO RGԘd"ZH$$/fxMŅ])%ICуao`l4ΝDŽWn9&=s(F:|Ab2^s`[} o <| 9B|>./Mɼ/fCPj0I lgqA'xLձX!!\V%@"$6ܨp܏ˢ+Zp>;>]jy(vk=*g=x><@}sHRXo׼Vkm8 A[^Ɩ㰲 n]|=Oq)ܴ˻TK.bluZv;<7'PoB)7Xy𲹷>tAhpͿ*,Bx?N;\o˿|y1 &,Fe-$*dA3Seʒ'˖G!!=hү}lKYEũ:3K8HY_j>ڰA㥨~x] >ug17]HD HUHϙuv9}^2|>olnzbcʴ2|6^'o7/+ޕyNx}rv~~ymOx|4xɪ^JJ#wS&$zlj (V+F=Dj5-ֻ]Y1dMLw1ȗ$<=\1 H.<`ܳ.A΂K\7W$5UAl\/:\$ y jR!>)8]Dz4؆Ze‡[1QR@STxH }SZ2?<!u'%@"$@i򑻇rιLJXcG{jO=D^VqN_wM;Sm߬^\G!o;,4`h#zvsm{\yuzrNWbbi#*ύt3HK2XmYQ^ k4kc1x@E)0b)%:;$κ1=T&(Ǡ1ֈ$>|1ՆYy^hߊͤX4ْRkct6mddmH, _j4qc.ӈ#%@"$N++|7>W9pȱʲx-_[o)Vcdv-x>4lŖ e6\9 wq=͋]U{J?y2ePdPICRb\Y'2E|GQEGճ>“EU1@ZRjt%L1Z}-c7eIEb|"FZ430ԒJ EZ\~]>T;Fٷ&UpV^ȠשP0^Eq;yOBxGQS)H7EAzD HD@@+>] sGoZb_|JsY`ثw]sW_xnN IDATZf{>@.B$o"+a$Q dƄ#%Ujv0{RFxW&_-ANiEiTklNiPTD(a| 4/y"$oZ;'vi2IiOZ"IHI0W]8k΂b*dL88,|[`ؘ>>Y\c(-HD phU,2 #zW9I_g_9!EϺ9䘿$u :T撑.,h4B&-ހ6gHaԅs~SFa& Y{yD9]c@~;uHګ#\p}ڠ%}{ԣ(Ϟ5s1$Բmܫ$:}jS=R$bX84Ϟ&AxNncQ\U:%@"$e10HGcr'bEkmJR($ߍ[: %S2mτ<N46-O]$ceod>6Pa-p0}R;+"3q陎xQH(A=.O[ Қ:Ԩf" 5tEBǡ׫.,7u`uuB<}Zбj G_[[dI y"$@"r,zk}r[z:<'k<{Nc^DiaM,9˸Qu,f" 9+ɠ4T!nŷևlW.|]x0(= ?Fˬ(M>c- /JKCZlIlqݔDD5'վk+7ENzH| tXYuIҡXGr-DV#G^帽踶l@"$D"=|o[lDzoɦHE-1-:ɘ`Z^:'lz}{Nbؓ#Eh"0_nq{MGuAES@XDϳ%)q"%@ХU'Id#ꥤ,>M=»&e]^h-~v$'.,{&ف~Y37G»~DJeXɡcHC52qFNf^eA \;rjD HUzkYo*_w{rկ}- [], 9Y.cWMLS6g墾k&i#hjG%I"_I-:>=z!hX#}u%O6!1g<6>3YűڈF<^Z/ dSn:bM&N YS } -Y“_E"6:X,X`y:G rhSh329s$@"tMoS^הoYY1+$3ˮ6ҫ_fW1#dPKpEɸ-nBgyNc*Ĭ.=Eic$RZ DepG6cQ&N4 RY&a6vv3E;_RCИ)8;;v5@zͣ=z׷}hpFDC]BH~"MApu`?!^@14"9LD H&o_gm|@.m˒%ڽ;agXo\+s2.%d\NC{c8\fVv6uRMrVSq}ʄwJrȞGӹr59\[bT^44Y,Ret>ū&1NM:nXa@WO Nl8Kc`cz&''TC4d!;ЩR '~`"(TD H C>^V>bUGQR!B ^(h%BF&XsQI᠞G<k(Ahxrd19oDЃ|Zpf@f/"fBdj@)?e0c0UzfeITJ#= E{cR^W;9,$w%u?qC,UÐ₲%@"$@"L*jcH<2$*d g]FDԓq&Сg%vS20U 53XD]])ߐZ,+`:ƈ /Wbzj15X2/Y@1"+14޸C$ 8;1$"ƀ`GB؂atcf}'ka3Cu'^&I;yGQ"$@"$d@.,l -鵌U;b&I+T,*Q%u;Jb-0pB2u9pyJFˉ$b3)ƑTܰB* `T52d->L50l7T4 |xXd#4L4Jjr]$&&-;uܯ"/Lk# @H! 7bNǚqMv\:nDM"İ=#~uB6D HD HɁiH-UF$0L)af lE<&!g͑x뼕cJ1v4lxbL&ފj wdȠ 4GM:12@s,AcIsAfT ctq.21D HD H5|y疑L2--O5E%"`476q%B&.\vAc7u҈C067!1 `\P/.QN#P]WZ47>0D8XĆ;ă5 ʉk(VEΏѧƳXDl!R '@"$@"[T3C8DE!QeD8=[|t=S@ waˍdwt3 f]+@k*>\5"kSʼnh4L/GD-I/09$rcI=\Fɤ @=syFeCh QPU7r{5iWKmh/ vD HD HP}K/2Nr&Rd(eC0EID]E b"5$_T*ևF,Bn-P: VPͼR8L Ks>쪨0]Zd1^.iˆ;\n#AfQ|x_IvvT9W3cǎG75gKD HD 43mm2٥R_PZkzYQ׻W$1ɉiDII>FbBLe|f2ov< u:w_b mQ@j#=Wzdz m>`A-Y zuА(MD HD HIrr[[艦w1HRʘWU }v }c3IӱԓdE܌0b̟hLOvĤTCOb!6ibrVc3o)1^8|y q DgefAI`u^*]]Z]AI]+D HD HɈ@G 2+sElS)$i&J:ɨT04#MCgT91\ ^]Ҭ밓ZsŐ(0HDKOΝ.BLh(r0rk2 T-1ALo= +@T2.PSV48CFIrA}I:n(&SHWOвitbI"Q/Ebnֺϩp-;-JGfx`c"$@"$d@~Cf]YJ'Ige*a4`&٢I3rnCӚ#1E!D2[^kZ.ɎdDX9XpX * QN4zo( FoǃuLV4Zf' Ҧ b.1G0=Q`b[.O1D%D@ ecp4 :ҳ%@"$@"LIC:4cT"\ y+0HaKzD|٩:Ǡk%a&t6P\"C~D-LΔ2u+9WGOZĤQ#l;McA 1w1$*- *ۄ ilZ8re2@caP(w8[ 3 }W*Xb$(["$@"$dBxkgzJ1WH*8$Lrsd*1%G]hBq(# &}$$ Si/^Zpfٓeb85d\ih@s2D1^CWѶ:Wxl$`J,pHAcC:=]5}9p_ W {&M9LD HD Xp K`pzp: "pU(|DbLVU sm 5:Ӈ 3Ih/(=tdRJRPDCbc=rNd(ǁZ!8Z],JLT`]jMA 9V3&CIfD HD H|T -u4THjiXunFz -m6ϻkotjYUz^(jtR&0SWt"D4TDTتKsZO1q } /GJ0m74?hKˡ%e;?LgjD+*m a h8h'@"$@"L& pO̒ظL8;,D*rDs0z,aitX$:l3q>oĺN}-CW6QuRK6\ܔ4!YbGDdvb (>Q]cKϤʉ@6ܐ7,+ Sy쨣&!@fi: bND HD HtzoBGw˹60$R%7hșFnoisjA$'КtKΒ>* al6L892FŜf\Tc U w>dX$v4ʣc-] OgYAܡus815ː "' jC%'@"$@"LҤZ3rJ{4 2IG;hŎF-wU$A@2`eBTۺp367[r`aʸΟRK4z=i1,)P²^Ȇ/|u[1Ń \KI8=_|,wDYJjMDu!/;/AܞOB!}"$@"$Ko5wkgגT VQ"+l)iD$̑[D;lE/q,ER˴TȀT?]241jIa``|:*\D IAv:C )y4=MUTC Qp8*Έg5z/ΪsC4}&&@"$@"Lz M cpX~J &d$j霳:ppCL$*`$<)VF5µHzn5gEH],@#rɡ^GmD'삮zvehKCi"w ojՐ5ÆQ@)$0 Y !k,N'|d*8HD HD`FQ>9r-lYϷtfi'N J4Kpg1L;V\zLColNC ؠB(f[#cS2;[$@ڗI3F"Hz \֙MCbz"SQ{HQؚ *|X::caD~ zD HD H&mUw=JdtaC,utWu*ک3( kJ`0om^]|&5Yh)fxya"*G.yh^3 ـ7sy>^$'ݐqM ^=˒A#Ц#͌j:^JЦك;"/M(|D HD Hlz Adrhr$&qפ*G>sBX3V#-zDa֫}ԴWƙCA3:`',dڃB`z)K6hndɤn*L~m1 t휹}(p6vD HD H& =Ȑ5wH6Ic.4HH{*ވRBS?H էp^2Bi{[b(R.-Hd&b̤q*_oA<\D HD HI@erJ -5 ݣ IDAT@"$@"Xn˷W2i.HD HD HG炪E$@"$@"$AI+@"$@"<x˂ C=T|ɲ&޺e"n6On_.Obb|+˛:ofkU:j7O|cP81N3'*; 4$@"$ ~[6ؐOǮW^YN:þMo=wY^xVdUasAA!v>.lcy ;sn=X;({GNlk`>7Aa@G1g&^2|3]ewLy Yf_ro6.IҋrӜʒR>>in-2ve`߿ԲT\`n9.{L]O 0 ^7~VוLLdk+ GoS^{yx^v1cGU"{}wܱeSnTryǗ3g<̘1~\{j3;r뢖>[Ϛg+-'tZyۢrb9ߎYcU zʌOW&TⶤN(>ܸO+'A?{#yYeו}y)wʳ#F`v1_~Y} w{|i/睨Yft,O V=dzOS~p̥R{쟣E in=kYpFnBMw#ٻKݐOi XorG?'B4V6RY^)֧ךɯ Zq}QMݲBq.co-☴Qg>}b_\i䍷QSNQ10ъMa!|g XUa Rya?Tﹺ^,yJ+dn{oA^κ -r{0?\@yTPNűA*xǗp=橇;\rKuʬMpzfmM-7ʶ7-AfTN;pl& r7]V܂Piֹxf?;m*2E ,'jy N)ǞzAe=]`>wfR?ho[/.AE6Yw};7)i$v2y'&3OUbx)?dv9[\v,wv_G>Q.8X[˙Noǜ^ʡ_*_eө}ou˦w)o>eӚ+߇7 \cgFJ ʑ~.?x=~~Ye0Ho.v]ÞR(sǖ#EY);grV9<3O.Y{0?Q1m3?ܣ-D̀~ȹWpѝoQooϏvD?N)e/nR+vO-񿋽e .-+[giʩoߌrʬcQ sU0?f/2ϧ\:{Nw>\s3\̎(>agrW?)]S>ߔ]O/Ǖ??rq_/{|nz#_m=G.<qL9gegY6oViɢ'crg>|z3B`q'N;y3o{%Swܧ|,y N.er>\ۧRsN*NlGo򁓏r?]N>r/ZV@0Ƴ\uOuµt^'峧_N }e#{eyvkowq Lgu(s'cCO9;堚|uK͟/=9[qZu=}RDҙ.^̯P*=r /g|~݃rIsl%KRl;n/OL73;36rP9&IX# s8{G)JMe}+"`\ @ H bn0";Q˦@LLf3NdLgZƈ,0I"ҰKZ#ؤwyܿ/ U9ss;wfjkګ5-< 4UY()ER7Iey44KúTIEft7̮XoD~U~E^=\noq|F^|&4~.Qy2\"bDk܍3Fo{a0Chis~U(i(e0<DA5ʶݻ~4*ŅNm36\W Lg>pU/BPQ}}#T{z*Ål%=4w;tg* S`N@"ll(R?yiF'a17+cvOW>6nhCqRBtŃu1l|me(`P EʚGѨ0v\vǒH{ 7 SSVJX#w QG95rOx  YX2%42+L"s`.-N엁*)ϭ(x9v2ʽ5C2e|yӃX%X <&Cߺ_z#EovQϛ!h^}iΟK7N‚lF7s9ےWX ~.{OlB<~9h'l(|Rf'wCbXT0YL ɃkeKk+9C( fDzZ1:ő Oh Y1Rꐟ5A)YSX!:kր&@Wf1Î.p{l5 nb`sfs?>yr,(W'>N !n~ӻ}6 wLe79 GTF os_Z+G6B.)"|^cWch_~f2\]}0W8||~9rDx-Ͱ&"< =UɕD_8x] aGWy CcfIJ4cCW 47@ߋѕM=Vy.\(JI`X}FT/W>1ϕ/EMٲ][X* gQ_e;uz }/$(z-[VnMϧ;}wnŪՆQ~ HJ2IBi]\nR]4TbdkN4ˋ=m$PE%P L-t|7U؄'䙆҆М57 >癭XjE0ɀrLNTU%9S䖨GIbh!J&}Ҡ# zV^HP'*@?X~~XpX3%URp %oׯSB$hߞn26j=n#YE:{_C|$>ڽ*Mӟ&>%e>J#08 y3}e %z]0E@nj3,s'ii5> Ixtb@ ے㲩]^*Bn>ٗ)ū M:9ln9P$ɬi܊Ώ xyI3tf~<\xEKß+>rQI4CˉC;%1GN{u0YG=3z˦"gXC4Xӧf{#wO9qZi W}3_2@+LD.fGyyyCR > ɶũQiqC}6zW/]onY}Ū[ 'i|M4[:L>]=qz%wM(__ϟ?/ijlLYRTLN,yJv;2dʢլ,I5G!3WR Q"Uҋ_.Aa^vT9dV8pOdd*]$,Ƕ n4## P_>9 wtE__@+ovUrD9VWtLM#VߗY(ϝ:!Gʪ7PZ0p lb+moI&Ckt6#lJ/"ϕP\sT"=_v_@MM'b/$;Hz)Ǫџ~Q0\vs9s_yU2DكFVV!To' {CL3<EgVJ#L@Z&c4~,̅n||8$Pݻ vټ?_˥zCf'EOG|b<񒶪.ߺV|Zf6Oa8t'_S&3{ކ\ITi<8sh\6/$|OZx$ p~8'|\I AoT~<&/Ctamg/r o7-l܌{Mt#cIJgT| tEffT,ו 00KQfG%| *SO>nKoЯ8HC׼!߃ c%~ B!!mռUn@$*cM -,.n)o_fbmC`|dVѣ{*5ksDJN wK af?ēц(/TY봴eCv}4?["EZbRvB߫)GCeiwe2Ec`f Y~\tY;RS پ$J%$F\X%!Qwr$ ()moۤ*/qbVfhMcGڴ\aHx" ȋ!23<Ϝ岮2$ue[Q1tӬlYb|JB싥ROS<@bag?J5 ?ݵ:iУ6iwqĊ/}xEhGXt6QE4>JKlR owh6(i%rg&* 6em7XhMe0䓚 =ghˢ͇G 攊eW7I>8matq9dw<}4^mq8LSh:kus] q' PIDAT(,G|ۻv9>c*KM0A)c7|SVXh|J]9|P',[XlXTV};Aۄ#pX$ҋշ eWaKL~|x EzYy-}x%_NHF<{ 6~Sn3/5'݌f:|C7ҋ5|ݏ>Ce+0؂U}d "]_J3|7K^(n#:]ߎ/]`#9"3@Q.gieyB' #ܐӼw=H|Pq Vju5b~#9B5]Ar$:A=w\.gOaCжMRt>zۆy8a.7bR=َ'439 ">Xr7\ګ?:K|ώ2#Ӯ>iǠ Qpx\o~zY  *fʧu?W UUzIJ\};!_$LKQ ERHQ EP㑘?1-Os0O|Jܨ|nE`9.Spͱf]-tvD dʈvǘVJȟ<+#̔:;!kc5‘@) (@) XQ0n!Q6+G_XyB8[܏NJ~9VxAA~훧]q7Ez=POs=dD'>/;JJJ駟ve9\` OwvR Pz'U6ERHQ ER+W `$p3RtoE[݄mC367do7C%+YULHT>zcZ“@) (@) \%oH$#3ٶ$SΫٕ]^ +\uޭڮ߭v@M]SHQ ERHQ ERHQ`)ES+IENDB`pacemaker-master/doc/Clusters_from_Scratch/en-US/images/f-13.13-date-time.png000066400000000000000000006211441217637305600270250ustar00rootroot00000000000000PNG  IHDR i1 iCCPICC ProfilexXgPMX`w9%眓sFrPQHV""HT  |﫺nW3==sByOtt8n{o& |~hw^ydOEƲ~ѱ`ƣagƃ8<}89Dc K}`(!`{6F:""j_1? =}|~QH\tO߇[DxliH?YiEyXڮc!ngX -Ͱ0{L _|l?v;4 ~8a4 *zX[>AD2AT4K= QLY@* 6!B$ qB($)Bd YA; AP<eAPTBU&tAF  /B !PG#,N/D"FD!{aK,b D$R)TG"m{Xd2YC!Y2 P2(-凊Ae*PMsjMBКhs:A/o/tO ÆǨa0PL*8sӋyǬaXNVk`˱wcX:vGq&Ha\)׃-6xQ&OƟ7Ot&L'hLBO"|'BD =1xXFB$1P$ <N2422L0|'Hb$=^IR3>iHee4ggڵڳ:::tfuu}tt ][ԗտ@ aa(hĘbl\a=HkcNlΫZGC 96['?Q|~iqN((;s2)S5ȂB¦"rQJiy?J *=C8f̪\|"eA*ܪjg>ruimGX]i=>~a \/l7F6694=hVknni9Պhop%K]m2m._W|}u嵾E۫nPou@]]nZqKVmەwX!dMݻ|/|n_<0o?ڃ4n>R9:X'*Ontw,+!vw'VNn` )Ei2%R3\e r%sZv_PXDy M -J*.i3l~5!7";b:cbntG |ǧU=> %Ň ?|"8my9 Wү&hMONθ72 7Kbb>Y&~Ҽ v|8ٲm? r qtEQ ht3F3݇N $hf-2*JZ{ZktJtO08aX`tƸʤٴŲf5gpӠ+uWپYo!o BVPdpUpF8-5XTGb,ρD$䒔}ά<ܙ5rSű/8~ĭN-"aP+v( ->S]v^HD\5~vtx.nnm^jt Uk%ڥnvwv޴v!NaOݾ{=Pwx3P8xihc ƺ}:kfZqm썹y ߖt?nYs j7u~15g@ ! (MQxF!QZ ]!b0o.8g#Db!y"S(6sY|bCyOMaN%3_BrUr+s? EO%)#T+l$ +*#L,^]-")E%!#$J@J'?pTLAiTX]_uAM=^CCQsUk|O]'=i}Aa1;63SsVyk\ulmv+o`\RZV^G~oyр `carVtvL]쭸 'RRoO?w0Pdfa,l#9zG5)K?!~RJ~]Q%JY)gЪʯ^VΥ>yz#oKܗn\A^uvxÿAͬ=^˾'=&?5;O}b9k1 @)\py S%Cv$xL@ _+@dC"HGd9r%:E3mq4bNK8<.ׇ kD^b.q!ɘ(XDecS˔`"5%;k2`gfoPtĕMny B5BZBEEzD}b-4@k('% d؛˦ʽTpVdVQ*TvRTyڢ1٢BS{BL]OoI1ɢٸ )E_6,vŎ.ܮnWNYhY◈O_YXH5ud{l@ː h!鎬AQD}4탾g{1Wx.[TBaEc`#n13v1i2Y0ّ% `вp(BC,D\P|V*+V򐔀Ԁt 9[rEK*e_ߪj!ښ̚Z={JuTuzmG Md9LP&V̿XYnYclm-<]nθ#JxX{yU{1 ಐa#Q)+qf ]IeLiYF?Wc'NvΟN*VwUU:\Xl( lbb׶k;:oR=ۓK7|?G O`610B« 7w?M;^޻ht/.+W}qwۺІݯg7_f#퓡eD\I@C9w0ژ{XK. Wt KǘdLb 7SҨ, p'^psvp>s7/[QBHWX]DETYLI\f(-)!&(ɑU+ijkQOD ^ÏT S_\V'Q6vfnNG\\Ϲ;1}n?o_0|ʫ'1E F)D7݈7Mx䑼(;$ٝe=v5bœO. <<Quxt-|E#wSmPk%Ͷ+.WG\va\?7x>(2T4xd l3/S_|4mlJmZt2+Ec ŧKe>}TlՕV_'=ڏkkQks?>\W]`Hݠ2wMͩ-խ[sǶ'ߵ\n\~.ͺz8ـJo?fRvQnbޥ|^ pHYs   IDATx}Uյw4zD@iV5g)nz1EI4y_Ljob# JA{[k{ S(36s{;oR\N*++JR ~GpGpGp:WTҥ)8Ggٟ444{GT6GpGpG#D2ø% Ozw>xpGpGp:tx;|KR[l8#+p[#8o>h|2lذv\pGHds>HXd֭+Ȇ -X;" ?\z!![ m˲q#m04L+cƌclT*l.wG`_G`һ-ŧok7%Kh ןp E7n[t>jkkeѢE2sLcֽ{wuxñm6?)A'On(קoo'&۶m pYfM:D}򙢌:P .e厀#,_\FǗH\B:hڵe?z/w8#!i?uuuꫯ8)\~z?v#FVMҥK߀_?|^={h-[7C9dm6md;7ˆdC+l8F?jeΫHt/mA>g>R+s9Mfo) }.Ɵ%:~۱q,[,Tz\փ ٍ*v;GNշ1GpNGQòe˄>N(++8T_U>C'c۴ 0{R]:lHk6`~T(]$u"¿4={\R7ev~N+H^Ky>r#82OumlڲCvTcd9-<?Βe(s8˥(or"n{1#r8<ݴL.%A/]$C+{_mhVy#8!@^?{lٴi?^92g918)x饗^:JgCT&Yzsӡ%ׂȰ pV\N ms,ӈuuZqʒ6Y-k֬^z:&6c1eI,ӖrGp TVk.Cz<2eһGv&}0b^ǜ.>FM6H}i|ɻv5\1W&]~ F% g=g_&3^]Vl.O;#YuO)ts'y|?\Vh9!$l?4\mڤ@6l6E*i0DVvr'w: mur}H{~uG͉zٺ^2JIUrDV*k%SS):d&Nj: )^!u55R~7-Ϳx|޼aD{pGlC*GlШ#rtVe,DPF~Mծ4BC=(?<~4u9Җ]Q/TD{ɎQ'vb-d;i'MvkgGx!P[ 7W^*ܲrɊCddU]<=S[(^l9w-9<+ 5yO9#t䜙ߎj#O¯ߞlN<I=e?0ie<Ԯ]'p) ,[^_=EJ_ujK:aI~P﮸'(eɖ3/cѽb'j#8^ PRR"Mܽ=: l{twgEε!m&EXDу :51M]%'ڈmQ;GV<8#"pȐ*_ɏe_-*Ē -NzcE_/}hPjZ찵yvr][Ñq0rޒeOo>%猳ݺv2GpGKxV{8+6[n\HcII21uw?ߒͤPeڲYQQztl_|lj8#&C@Ww2~7wKz쀵 }H史у/v-zZ\q5zd $CN씏$EbI?/TB=GDyhMRc#t.tn 8P';iq'nr-ř4ER;hee ~71QڈӦX.6wKmzW-:YmM#5tl>|;#!Ʀe^*9lCawܸܣ{#ƂmTo{MjkesH嶭ڶ2).!6˶H4Cg>(Oʻ0rpGCO>}v݊㬢] ,ܞGsV{N}V1q4$}DRѩKD:2l`&ЙuY-;kQk1vRp}LL.nRm7JҴD!}xLYU\f99ߓSbVʢ0X˨S.1ȶo9#Çח)Rt>HI)ok6y GMxIIG6IMz`l'GAZj'h]{6w# x=&]i}'rJ+))HuNj|-zdhö*"tK=Ft4΄]maJ#8^#@!\s"bI}TDYi~owlS :\۱yf9383qDMNa˱>Ƈ 6yd] vrnۮ>x#89Q]mlF#M2\0U {pGx@M͋eXnWʦ֮]ؘhyLǼ]bp}nh}dw-#8#6D-9 xD[fwGpGpGsڝ42,6;#8#8@X8#8#8.#6lGpGpGhi vGpGpC-9#8#8@;.Sx).9y&ꫯAĭk׮zʸq|%y#ܕ;N8#89Vgsa?ivwF9}R8ns@Ց% ;vlGm֊+|#@;+tƍWIq<91RJHzrd͚5ҽ{wa SL /3cȺu 0rHŃ_/G{'n+WG-szhO?#ĕKIu݀#8#6=i`4 hAr'f]>d2Lr :hv]m衇hzg<AL9h %|K.ժ: WNS6mlٲE/GVNGHAuڨGpByCGd_ =_;knE6bCH݄ tྊpGpEɫ㧐!R,;/̳RitpvܖںڦF;)cG̛rf zȫ[ 9ϖHQQҩ*LrJ+WtfRK:J# vm6>|pph(ΤMnCBCo>#):t ti:ߟw>DNC@q>|t,E,_ekzıEҷgJ-R,;~\tU8ŷ$. :^{u G48#97|8B6|Ğn ĂN;SN~Hѩ?)nrEg=}x{GpcVa:Ft[uZC 9b\_[[]sS\oi+hS3sN:ZW?!]`3C: ܥ { GÆvZnʥYi4h>Q*yyq%Su@]~or;l UTtqmDPƇC)!Mnvv-S矟 ső TtkOLփF'. g6-,"}{hM[ѩٗBGc鈣ӹ \O|@KtH6oެgncF]~B'CCgҵ=>Zl;lqGe+;6BdžF";O0>FLgrXqcZ10J[;6䈛ZȈe `S2zDOɔfd5rPFdҸӶĎJKgb29:Ző%:bWǃXԾUV#G{8#8@G# rpBȝxG?2R)b,?4# |cAr}sLm<#L(ygHޛ>{YGpGwĔ*rQr&sDH?S:ɔJa /6v Nr:|Q1u0?:LA!6?:)هч؀UyQg ,}&X|@s$=pD$; +Wb7LMSR8b R"i`VSD>, bh Ϻ8P+с3c=VN?/ bh"śRӴd<8#8׫@Jr4M"8y떃QY:t^@^c3{l"ֳ~m۽|hj&ܲ 3_G1.L-pLAahG@Q,)n'f`vG1m49svZ<{]sg-_!}H{wa (\?)[?4 \3u7t@D0" VKcv/W~G¥ ~W8G|l\PF]~g/t,wGpG/ whRcnPO1UX^DRWw? i.>Ń͏$:γ?-ɲ"o=QnV,3_L/^oFݑ pZ>{]8!'AS5!{&ÆHܸ)95 H`mvȾ||γ@mC L JIӋA.ƨǖmr;gd s*R2q KU, ux/=4{tIǃq:$;d`>[a#"qg =8#8X^prt$J:'p_PY9MI\'m^!^]R,=]RҿOFJ<ȺpU%: /v maMa>p099p簐ƞ"lliڌ=#g}vY{32tI2eE&L+◙ad{Kuc,+?~:{ۇBg`(I[sn:Ls?c`(߇`8#8@G!@>?|cߒHK8WHs8BfK;2 IDAT/33s)vfogyHkZ+2m8BV(+tQ~ λMeСzJ/]Tiӧ= DTW@փ>/9A8q<3?\?1{lظIj #a~-^&TE/,A5ҪwYiCr$ 8pB}3A2n8]7gَk,_:GpG`D d-s#%BZ[-xN VۡBe2pPZ{g9^Fs=t8Lum eIGaKaPM: bᕻV~O;2d=_!noJRCR4Y 옋JuƁK#7,|pdʴ^PWckw2_wZ!'>N|ew94 Ƈ:KR@N8?$0c<c͚5K-[$52hy;o!2ivKf6r?:Sޓdyex3f;pGprVΘ "j۞X۳f6{`ڋ$PD^Nbi-/>\Niۦw| D(I/qN )Qn8?GC4a!KɈރex!7PԑD3;"_GpGpC xalM$-}HI83fe:{yeCD<_";e7:/bFc;#8#p ȁpGpGpv=p#8#8#p ![{lq}-'wB[Z*IӧOnd7ˊ[o]WiC۶nJ|0>#8#8ese*n ΖUpZp&Vr;O-Z5 իeͿ'֚g~V>vvwBJܙg5;iCg~r`;#]E,;&5+e[<ש'Ry[[ʵ+bO(R&YlP+5RDm!oFpxq;dw>~l2e}rBOD6aWiN1Ee{{)AM8QrǍ-*KJ mڛUv&gARkdV)V"ܝeEտṩr4Q9edls;o2VI[Tw-0V3fʌ[LW6[ER L%)k/}ݗLa{\M_SS)zr{4 ^SWt2#}tal,m+3d-3fJ& B4{U:UV݌mwqZwyv0 efy0`4ydU+W Y*OLdF6a9sֹ2}s7{9g]QW/#g]uɨ+y+KCR+Q/D6ϖk2g~{IB>3pGpތ$߈D|~<A.YYY~w@-೻pXryT~}R\qFO,Wi~Mʝ R&YhPֿy[߿B9yx|B? D}=$/L>s#oBC[:?z~womz28'o[cd}rɥ TQ,zz_Xײ*'럛&w5Cn!ȟ^U2۟/YS6gKeEYyk ڗc4 ׾h0yY3=MlozN~U򅫯.xMM6-%RVCREW+%;0vHiYCೳ%uXډP;'7!}VC"8Qԩ3Q8٢—riwuՏ/OOMit\FK1t~ŸxAyrvJ+/o'ϰ${gɖFˢ5Mlo^H2ǝ,KdGC9R_CdNW3t/:D~j^rՇO+h8Wo[)iG*߿Z*QT~}e ÇAӴdU|) k rԄK_L| EV>"3r)7]m7}V K+pahT7OKw%mEq:FFKz Mnc_U[?}J] v}X&ɩgGNr>2rar|m/եv5MC8 ]P9ibGdC/|Avĕ8 |;#8Րuk/wD^EPHt~ ^:G{)yfԅrHt.~\?dU;I[WoQgȭ/4-/UIrFvlʍ+EN~= /.:WHS%9r[!"F۹67o-RS]j9PtKd-ڲP2mtQiZ1l\sA)fEk6o,j2O9h& OoCAH{ı^/bw.Q(ZӀ:"X#ϒI ,5j^OSw$3 #EnJ~}0B)Ͳa <`1V57y&זIiCJWe˥fj1L&]ZN61^NjMO&G *4=xCلc}5 ?w, 9Q/zv+pRfw'#yt5oIGB??e9`hع2yrƱMpdms=]~iؒy{M-X tu.`d,UJJ`Hie1/Z|ynlT2*Q]/L͜-_=eb\&[#;jP[Wc[`FNx vپJrRZ")-XSowr'BɶhhsE2! bZeT ۏ-|+ImXV LóJ4)ࡏ/j% *nPt4`mL7lVVH#56ʧno.,/deL1jvv*ZGK^r;Hyacj9] = %hk)Eܫ\cȐ.R^";Ssgݱ6`.tĥ<^eTm|M&Kr2wI4btpWL$v5\pGp:LYWnjLI[H)V64y U+^5۶k`-r]LE4{b)SnBj@SʱSIoJ;ɏc"IPyR n/Oˤg"īt|BU;2p:LoKA"F]qhȀo.*QZ 2POYL?~rT pظ΀٩4%tOmf@k}eK{.m1 ~{7OYɝڟWoYxo#\&Sž㻋]3ӞtGp}p-ݗfgӆGΕnS}S2tF?ͧZy"=HNU'.yb[ܵU[dJ]ft.tYR6B0_GpG#hA҈. r7_nwpGpGp׼ GGpGpG2;8#8#8@DG@"~wGpGpNG wz%^#8#8#8D b6ܸb߶뢰nի䕢! -Sk'daق$=ن]+;*|$iEaR!O&]iX. <1VZ, VH`"Bb$$VlT~bF MrGpGدH <8ڨ"zCH?&x^%D1qXl q0nAFt L hg` 9}WA'A[a+eW"s2MW(aP&U/4zY(O`WXyrM-AfD҄2ᑁq}NABy;n}hAP-j< eciО<{=k =,qGpGpL*sA0փGr8|@$(Iwy^ 0=ލt2=\lhQj1`Y9= =Ơb"A5%v%,H&QktP>HVҎujV7zqwFb"0sV5u%$.KH}nˇZD9X6?izֶP&!H0Mm(ٳdfRi#8#8=\! H7 $FI(z%]VL3bwkwh Tu htdt,6uD QAFBtVĆ݉j|5EEK kA}Q~qGpG8 "ۺH'q[ssT܆P=@. SJZVOaHĔ,BiVpl\/ kܦ6q3Z(mŻ:"N:n?&C:<{_,o%>Jx2Cbx843gFTQZ6aѼa} V b>(@-#8#8Ĩb v$ :ȸggy"LIE9W iAׅ0 @(*.$!EyŘgh" ((O_ B> , 4m0 T0B mwSg@C)b'>2D "¸6t-NZÝm4{T@Ø!Ӫ=:8ZD^|IZmb1aܣ#8#8+ 5"a$ ބZ2y&*$TĨDr-l:Q|9&I#cVb5 yQw^ yQmjTPAmcB* Qb`4> h]sLNuiPb<k`ʞ+@"!ը)@iݙKD+T9$4F#,nɋxlq>=8#8#"t}?N~RSWIVh:9(>*qӄj |  , Rh4m)5Ek:o[ݨd`dDS]:=oJÚY 0GE IjpAM$Z( K"6c,l$VO/5vfpk>4qGpGp0+&I/ݨD H%9ǘ)/) Ohei9q2mŅ\B{j]ցO9LF CQB'FM?6<|$ 鼶)+T#;,1r\-.E} m Cg\"NӦ iyiESŢ|.|/-y ^M -xpGpG`E0Bbw=t @©:R80\:Y6 #dz*vXӯ@H2ii:0ѐH`Ԍ4+zrs^Хvޛ~sGpGدE!)" '~mF ?Ik3)2jP Әő UzAѺ\a]my"xa]Kn}`N!}E>C, +C6Ie4Q y' ՘7E\b .~P X+4S됲Yy"]سR˾16gVx4Mд=XGpGp204IHjRP4Ub.c)ZTSANH@ب iDDQ DZVNlD$Bfl`H7+5ū*uR3rcvͲv13IfC^4vjTqMb ˚af,u= c bG+C,-S͚"c}24mR:#8#@`,T9"Hj$ *cT"KhJ~:"洤Q 9rgʱR~8V*F,K[:mȴeUA1!)!VX QcBK؁|!|󺪊 {"hM12Z76~wGpGFL$ H(TRlO#¢^2j@kb 0`x+oDFW-ZNKᢕebY+#u(ԩbI|Pg")j/+:i~>c H;qgCR+$1V,C+Hȳg 4ePA ޡYh?8i~hK;GpGp,0+ ̑ BrNb#BK }_# շJdI>a_*q%쌱"{ۮMruj(b0fԖI4Xo rup8[:Aj-*)BjH~Ļ 5<ޙxб@Cp'GDoHpcQk[g{3FY*>X#Ha X{BZsg{x?>>omQu8#8#pĝxJ@p$6$d$d S1pD F$j%,Er'Yy*5A*@c wJY2xac ܴ"&j%-Z,J™̴]QT$4l~L}ǦT pڰG峀D˱Q'L!% sײPoQUf ؝1PV#>o1 siCu1҈uVJg7ި7pGpG@@@׀G+*$)$uT 8C9 %^ClnꀅNbQHvuu D\#"A@Ҫu!% ʳZMC2-LfKU+lf;do|igNzR{!u:t<G?4MH=6M[ zGFc:k)#{(&ӺAE{`YMK3ƺh4"~W(ǗC =6Ã#8#8: FFI2~t=وWCy%Zj:=1h, -yVcpA-f(h5RYJÑ0œH!qCSDb#bӸ{AO!QB[ t(bH.ž4Gaf (d Zz9$Q1Ne:X,rh:EİnE״ qU$EIlGpGpu@HuFƍ_c*=Ox< ՑcѷЍi$ԨoQ<$ (Q"96aHK}d@*;j(7%cF 5=پ*t*VF؇H0/TL,І^я00xH34,8%aG7$4ďX *ZC!dtsi.ey1y*1<ImNFl+1_u_EE5x8\GpGp,2JxgNMGD,Du]r[娌࣡@ZS4s"( Uu%ޢU30䈱##%\'G1kG(YNZUk7PZ2, !E(C,)Ӷs:$:Arq',ܩeX4 2m>"cB}&LmSޡSq2 q}nh;%˸0^:_jPӰ<8#8#Xs@#$\M^ݲ>ȌzV(RސOyQqf.U6X%X*YnLG?T6m&|y)GC8'|:ۜ^"(+Wo~{~ mՀ+:ig}$GΕ!ʊU'SzCvۏ/"0W^}k)KWg$vYr|7g?rrxY||iodeZ8I|2~jf摞äI̷'R,^!egYtt(_RYU#ދ9Un7V||>t[Yz~29rW'z9q_.Μ+3.:FAΉUhbiB1t 1$w갇Zf7FÒ2M"KꄂZ!oo[RZR"}#FqMs=W&]Fڦ~swޣmzr2jԨ&*&=8#p@ QgV>Gprʴɉǎw0F~{wS05L5F, [l0 NF ᮥhi1=*6?{hEq X&*jQ"FM{c{]4boW{}"oݙ9mΜw즤*+H~3?܆ը 6:`ש6bgZO{Zdp֖1tmeL:#####P@C;'EQ '_`/& Y`8ыZ @P DlJeʳ[s Jd;"( T?0^BށϽny#;hM񴩑vqڹ"iHYôGnilXOz߶ݳ`tlmֵ[I_lu=n {Q8)MMNB٬3/fMg5tOlhb_j+P̑ hfHwvPxh>0`3܀Kp JpVEfK6 BFOr`]M_}M˨Q_ /.mm 3sfwmoFA!WLDfw}W3 7Ni539|cx~kSǕ2ﮞ99999[j*qBdj=Dr-`+.e\BW4OR41iȉUtPɊDZM/U˜m8aOB!JP<`|Cō1dBPi4qذ&1D%RSdt}HĔS?isq_)^^?exPp>I%k+|!#7':,0ڞ<:>x)^z=v뭷3%3~;vhs9-z\sUU/m]}5E( EwvÀlwolꩧ#Yzia_[pU(D*ɝ4gv5*/}ƕ-|E 5\?Jߙ^~S&tRڵ* 1s6xVmrxg#< GYnl^lxT[l%\O?Ԧb w@jZ4\g}yK QpQ+ r-K>WAPK=+$^]ؑ=H`UGqн4@DYtB RDHڨ (y*hT1} D]H>=SmDZvsZ\ A$|.XMC+sT4ܴ\J (-^ "50ZsL΅~# !]  By69ʖ.g/[kvUZMcr^z%sժM n۳;e F ܱ6TSH)I-% /.g5֐3Ȕp\ʚ-.HyD%e GZy W7tDD':)VNu͝~0:MSۤSSw\_q1v}<|3:j BJC{A8y$Exkk1zIV{[:W5<4АnBS ݺOa_} أp[+ڶręgaԨT>q;W O~+^wOo믷%`Djo7=jWmO~>gϞqdoښtI'Y~D Cr)/6%[@>~7jB~7t,srrhkN, (, $4M](EY5%O8VxWdW,ݹ#&G`q= ա 9AQыMղiTk5w l< hʆ ڈnlD06LJ& dtUHxMu+TtG>|cm"_&w%9999f^XZ+J(/gpՒl8"BozĻM>W "倀ҫٔ`E53>\-GhM$>^Or|A e.=&n[vx- ;XޓE^AO"מ`Hq*G8H"kĹaR }|͚4Ad~rDR *xJf_kܗq8~_jbzU?)' Ucl4>{׀zVkԲFo{UO>RK6'KI2W]uU"F5kאޭ[F ȯLh@1 dHE /B`\a>@ `%be!=~g; /9ײU-aKOѧH8^Cįh# T*MI3Hӿ94hBxR= 6d4W%=QjI=v2܀v=8bc?%K\qRki* ܃}d[~^;}>IѾvxMyG< v駟USݠOZ=si lV Kg^FQRHnB~7-rrrj|CFC d2QXtT_կ:q_86{F~Lо?f.Y7G G G`b@@P@3,8 :({gVb%X Q))HN}hiPK(Dz ilFp\Rv( E(Za: K{=(9{CoX죔튜8:5`sGp]#U*KFܔ{w.$ur!Ħ%,?`B-gqQxa ;hOLjBnN-PB}TO|ŗɍK1~7zcxa!Sry_G b' xd0@%k<$\\(za?%Əq b!{+0#eӇ@8L8H^3bDOTB(Sa+8ўɄV"4=d@A$ftcd'01mS2rtIDO^ЧmI -lףO|OP/ -`=I{F6xBVΝF?D,WvAryt I;0gOIHATR+|>;h8hwOX§,%!TCYRxT uKhhvYï>-&ܯt=6|T:c5lػM̷C7W.X39,+z`~桇޽)Z< t ug;jhk- 6`52W^ymf?:2 $'i%G G GrzY!DD$S 6Q&E}CAJ5y*pZ7_6A-Lu۽؈?]((/ CGbA&IRĘIzk;qBC̩=l)f2'RqETҵ='SXR F m-F :Ms퓘AJ0dpwu^ܗ^~." ν,%}_-\pmݶUl^rɥvǥ"޺6I@.ŋe]^ܸY[lm{W~xַ\c w}-rn8t[/Q{l;￯˖srr~}@$D܄'|$ R%tQh]-!kЩ)["6r٪A6% vsy7Bs+Jl~r_#LnY~ɀtJycpAl۵D0UU6\'2bBXJ6&ZDmbLRĢhi# 0F6EW,PGd~z,cԨ ,}ݺuk?b H;_ًc췉16['o.J:f<O?~zJ>sŽv/ZCז\tn;$;{GXe1x9@_ȝpX_"z2,Kɡ@C8~ߵ*GuTCٷ iH_eUқ#.]iN}2tQx4͈M^py6S$6_4###0G=2A^:w%\a2FJBF}%.OElW{[4\ᓧrԩSs"7|vӍ7ڶn[0&BcSxu^c]*{{0ז6wdAS)'\F6ݻ*Ĺ6c 7YtGok֞ymR3?66e6΃gVE~,###"nwj%I 0t!JM4F ȕ"@IWD/  C7j  0:5tᒑ9)cf{7{O~+.b{lƻCmuzؚvɾ;3>srs$m0(gۓJ.HɘpM\GJEA4h$xWE$#p ҸI:^:*RGO.ʃgz>1 ^^pBNUo ZՐ$(E#3V6N?zC6(۞Pr07L\pC؈$턃jmE$%GzmztorrlZfW= Ȯ}mRvۍw>m=vyW0-F8阓G( Mt Ò3iq>J)r10MB GB?F_-zLTxRZ|->Q E$#6݊+B~_ '=A "X`0m!eBI d-&T)z鑁xn4sݭO蓮 _W!F._`/>LcvŶֽp 6Gr=ɨ9r:1v?R;h޶_Wۣ_#N>s#oz;eG. ]pn ?K5X vQ(>D[l?'Hk\nwQy%.O>.ԟM}>bA|_XIOt~OHCcezZ.99999999m"]q@BHB` q"UR aʰ5/TЋm4657\;l"f@_c,bv, J_14S8W ç&g#e=P'?^*Z!E6)55PKOxhEo];xδCse<G͕IktDI8F۵SC7}7h QxĜ#>h7rrrrrrrrF:iT?gx.ʕ!MAұsĖHZP}H ;(!KqTRhd>J0sGuM]OO/NE2s&R /b"E.y0}Svd^ :KIi$qE=T2 / 'isk0B#uOh^Ш]/nb+u@@@@@@@D  لdD3"7H } EKZDb6*iWd j p7l#>AI .`Bq7.CVPRcP1 ,I[)R쌂 ?YrBth),-OL 3DAԗݲ nR6B_bĄ< CFq/"jD󣢺8O&BR%J<|Pw0BB!r<^|䗆}}ߪcX>LS.BAE㶫Jp!J(My$K(7'! <;''H3*ɤǘ"TD/+95M-S Y|$JV\ե=tu={l'E#h4)@?W"V%h?ͱ} KcГXb08K- *`!S1]P!/6$mzNrrrrrrrrD|#ऀ!'A/"A<ƈ="8$mȳj@>UHӇB  UyW%1Ȟ\h PTSGɧL*Uۀ,ER'llRJׁf}Հmڢj 4R88( sOBWt5! ~C.C$vJf8|H rrrrrrrrb&t@iUDI[qg-JsS#Wp]ii5R 2NcK3 jI㪄86MHձhTua/A|LVss">0W)Cհʊ.R6 =tr Rg>x.B) /Y' YH'[$q %Al?"99w]УOl'=4%G G G G G G G G-DS$'u:CLId˶R%BSv\I w)`- T .Ads%y$.A)\l+%Ѣi POj%GnK. ~!LKB1!X6epq&^ZEl%Г*RrU ~x>R9V1OL CTnL ֘4?}D"AtHak=0Z\Q!k-V!Cݦ(B]ԜiөI@qv@OCE@k=`_KutTd 491.vjBI8o\^WcAKU96EO9OZjy########Ц"`[ Sx0PbеK{7IwYC6ySpt$)lzӴ PC!Iqv%{OmrLN]/,[[h{$l8?I$Q4RIkF5gfy(A \&X56+>3٠ 8dD+Y|JHJ]&Zo ҸEZW(|q%](m͂CzhfI099999999{L{6‹pK CVՇyTD@ \$aS`ł2A|BQ h %v 'bI$|.}cb{QLqHV/Hcmզj 4ik~߳OeODS2S]fM:xA$[Mء%IW'1?^ԪU2_uB6 .Iuw|h+`:d7F9ZpV#j,hZو>L*HAU2> m@>bKKo=aKeqM5#n"mA-P/=I1ǽ]%2[Svh;[k:Q B9Gz2KP'eшzԩN yn~ [C%yQ vuUvRR)7rrrrrrrr&= 4+ x1'.Z 06臺)=BOZG"Aڇ?iKڔꢖ ᇸ y#Wޱ駝aMʾ[{κQЧٻ̨78ÏYvɿ^jF;چ= 2}e6|GgWQ0Hm4"\1;4|erKG0%Uם4H4Rp-wfr;G G G G G G G G`yItTҁ1Oꊉ@sF @(W+eؠ(_ygD HALYgy} %TWH&>T{ebgwwY[57?esw8vs[vq:8}/$]ug^x[y'me֮H.@rkH{ۺhoyv#/=~oǖZ֐l.{;欄lU7>lW\3G;\tn>>Lv*Ί1Z,_I ]Au t0DCfM:3CUs6Tdl5W99999999m+GfT+QAېKd$_x$ezz7wOr| aϾw:Fm^nI W6 mg;p1VHސ~G2Y'_7v56;Y++>!>6,=O^84Xen͇|զz [tn֪[癦?_*XQYYmi/q}3-7^xY> h|bHH513aG3WMJ/HFQ*"#T6݂%\I*AIH>&)J6VmjkЄT Tcڌ?kqGW_+ kh$g[uy:ԮވO||=FY;珅Q}2-`/vp{ԧ5mg^CMy'yEY;ϘTO80_}MAF Vj_Vũ% /iB _ %j r ŢSx⌚U:e+}_:^kYk  n[y=+4'C~ Mo?ڎ>:ceg߄gq{,3ο7]U$o;d f^^ǫo v:|.{^<~zp*H$PtOR2hDl4 V:X۵ IDATw{∸) TW/ a߳"٫ \t09ywXX7 :OmA(9&jfIڠ$Xd-Ð z$=)?tcjIbe-^P-ʰ*XjćЪ 6ZV>cB,&0mDӑO ;J-/O (BRhrM(hQ٤rF)E}h2P+ ;<0FK#P$ :HYP#y;k@fYQV'1@O %f TIU J4'ͦYN']"*h+QB8l>H>v~Q[:&` Cɣ'ARq(7!R)aC>?lQFTUU#_@rT,A$ F^JXc=J~(TzKCQ4I]?'izr 0$2Yݎl!D@AdYY@pKL_j| &iCB~U^[Z! %(6mhjWNN ? {ܵRNEsP7rrrrrrrrD H(5 V /*IRd 1ICH<;YE%A?ۓE -8a_|r>/T-SKT@\+5 hP$$n}b"QtZQ% :} +` S]M'5x: %yMIsٍ'JrU^wU =#M\&t@Ā>ȑbHHaT~=$Qa&ʝp2kSԾ}Ѩ"9BV@Glm\qpb$CN2qn -Ř8ilƂ2.YP22)iA7-dَzxURI `'x\~X(H |rASRܬ^D 2(xhSW45iD$Ftdjĺw)&H6|pF '&#S4̈́YD)iMl\W W܎e+A|仈Pr_JpJ\~zتO0%XPM{F6UBR>DlZlvd8VOdl########І#+ \6)B|k4Xڞ ,NbxU`;~/ɾ˃@VDH[! }O03ѽ>ޖipIsARR+C?Zыv$6xh`~˄g *8}$zBFtjb2<- |t]NX˕x.%\LS9WFgW@B$_$Z s Xw@=w,l(:z !)?kX)Q ÅQ1sţrCHhtAdwDhn9 `T(jI+ѬfM{R?]B'\Td3,u)#rO\rrrrrrrrVp V +&@ _| &p+X@bP #@׹W5fAʃ5.ZuKހ.᳒DZ$dۦcԩPxQYC!z b78.$ɇ!]lJ+ Ie<8K QB,'~!IJfE{XCCWEVa Hdd Mb:I2}#) {[Ye 4b$E|ŵa4&%r՞:xN^# C&YiB ?Td,R$hlǛ#W99999999qp gG`]bF>uC&HIC梀bI `[^8co乞`WvH# Pi4VtjY@ 1Ơsjڔ 6*bv׸b>mЪZ4E?ɇ;( j"˓4.Ѕqar`'-hO|0IʹhC8 bՀ ZI%te).QU)ᘞt{U$B5乺As<(GuBCfC?%ޥ}|8WSRaLj ^@TM2IUM*^.]tP!}NZ%~:\#1R-pS5֨Qq|X 7IB,N)KFnLE]"h. {^%Dܔ)Զ]g+MIV}&8f8ڶ2 TSNno_u]|n+tdv _9ԑtoއ1$ᐞ 14][Ihoϫ\7t<: OR;(pɃòT5F&ۥ< +Q{*hC(:P%;Eо #d\ě¯= EUE! tNaמ2t6ݑ+Cmхnb2j3 pmu:v8#B$$;-2M;okmT*\QCTSHɉ* $ -A|R*#( V5Z* J9jzJm@չ) s(ٯ-%J'9d5&ʙ6!/;yڀf^.99999999m'ZnQCC?灷:EC"(J KuĒ*;li/8郞ڬ16{R_WVqJd$[mC˯6]զvJHn|lG?s)[厌#lwl;b ύ˃4NJP<~B{ӟD ʹb ĹVSdtQZWCFtb:6߉ՈHBj@#k]`e6.S!- _}i)(jR,z&#,Ǟv}?{~lϲ8^)1چ>{qWW?&^=pӉsأjl~j;Gεa/_c .9@u6ruXW$!tj58cw;Nom:geI-0owpJ{K{ZS{[N!]fvm/g۰/d[l^{s҈__@/=DѮ&)L"tPT3QPi8^$G{,$% Oi;ZyζNuޒz{Øp?u5ųVĒb-sYfunvhshOL,8 FȂBU&DN` Z#!S2ۤ|iޞˌ6|''I^ y9F~9z^f8~g_RN;nGv䉗/eիuVַ h+-}6қqXyk!C߷#?ߞM;ڽ bpUPS BFGyȂsYdwj;-ǟӎن: ~ Zkc >~l$dx/!SʅId+YN b-Ɨِёl6o^y%{{ﱩڶbKnN@~+obs3oc78?Ӭoi]w٥^'6`hhl:G G G`ë4@_ Gy_l̓C)Ln $f\ҒsIoSZdְ^V¶˅tkڠLҺ!÷\stgdL}>+.){wüZ٬;֙m=l#n Mo}F-=v9:/#Y?D(;6b1 +jLR38L̩O> {v]ןhﷅM5sn]:X<~X`[`<-VqY+Ft鉃O)C#8Ѵz.K9LAU~?&Hz̾&ֵ[wsmoAcmɥzXfy׎;Bo*x -]t%P4Ϊ|ޜo&5\Z($-B6̳˯`{oCsjOkǤ[οb^$ۘ|Pcue#w;|rȡΫ~L`R۲fmvcιl=oVчCFH[6~ˮRD嫯R,^7򵥘MÕ\LP7Yj-8 d2 &;͡#P.S,1e=~yumx"ցMd,{Gl*e]к.V^{d#Eۖ#qXi[}I$G;Lnηo YP2 N?2h<-"jǟֻ`Ŏ=r$R3o}zĺ/g_l'PTΔ{ո" "Gy#]}y^e% El6/[#l4/N0W_mD'xxOGm|m֫gO{1bv[;5M;i9iTS~\y2+/'S5us~ƞyz]xKZj" bƱ8p;Tﭥx5cd7MO=iss6rHkפF%^}Y{' /SsgHj4殻펕/3hslr.RKl*hl4E-}?^{mۋnnݺB .|SZ{9/J@4h6@d"%9%]xS em j T꣣[μv᧶ۮ8.8u7#m*~-m5vevm6_;m/mU/Dfc;`Mڋ(֭Q3u]u=sq]pAv-gXpO]39`v`/£K*ŷH0rZo|>rz9zG /E[ޖ ɅSX* JD(5ڪOkˊ$2p5QfB-e~talo tߵ^_uUyo՚{Ck~#?d쳷O|䆿۠>Q+i 7gvdSo;`O>9V..Kk쨣UVY٦n:[nC%SklݭڦrJ*h/ZΕVuwi'nW;>= ]K•ov;裭K.6\so^w]!ńRKiƏ-}ϗ\b 7>ck}7CZkb7i9999/xA |K,4 &gKO-fzriU 丠Q1h|aly\lؠۅWc^s8khO?ש}q&.n[: o~$A \f'u#-27ٖioNx! nv>:νv0g[ְ|g_f{xF2!qv[؎[V{Y; ml}OvFd2;ﲻ1E yst}O'g_L>RLwK}-S b5MUT@d6Q&w޽U3ln 7sV֭y睧a2_O? ݲE;z+lS٩\cG>k-5vԩVՒm)H7VOWOG}dk׮d[*]g=5[U=Zki7|?j%I1Ŭ>z{####D ~&F t$hUql)"p'"0j5D $(/>9|2[(+qu]UNGmmqx{/ۯBA`r;suv$'P1̷ˮ=Nb".+,*U{Ow< |%[n-d8NAz}pyIkl=JЅ46$@-4iV%IY,@oau[/.pرLol믻xwiS"0 3Xs6\9Tv*&[lVzUv^zeΖ_{u5[W֭5vͫ%_~Ϋ~\nF<js1Cѓ+RS\Q\(Z\gq vJΗ\rIcYZғ@ݩԩn@@@/G0M6 [!$.:'+& uɇ.HOn$[<`BՂN~iH)Vd)E Ӑ&ySjCI_|Zqp:zMicWn_eYs5l}_W6GMnJk>}1>͈V'L2r*?N,_1Y? 78@{GG?\fZWOkldZkUڮWM[zb{٠AHlv_E8Rv8چ}~IU_[O1@3/D? 48zuF IDAT~NXWA$莖˚gI ( zAu%$EcQt=Dx&mɦ@dwqg2HnGBgdONb]&(+S;ztu2{%G GEȣwf####H5$1DʃZp3tT@'`' 8 lкdB@ R'wUd!_eNrL%!r%r*E1ci:>Pm~ì:$%vUGO.dJi|š ˚|θgM&VHPmXW|#!>l ,\(k^0qݺ9\rrXx Xm+T<8:##CHDxKQ hF0m]W6T t}DQj ?(WXHJI:h?C,h"|*kR#{GM <DΓ D}KSIz+2PB9iډj!WШ[usaCr8t,Ϛ<lXj26]L99m#O=n[cӣ,srrrR|D`<hhw빃©4ƄB5Y zp/$LVd+dڢV$,TJvUzy-+x<\$ Z"S`A;x*RXSOU&+>@WOB yK ES54(JAѤ.Cz.99m-.xx[vo@@@@%z o(M2 !C-%Τ81'O~{T |>ѐ,Y 9.5ύ$eIe `LEUF]Kx0 $qߎdtFh%]Qkpv>td Tl 2 Tb™>u@)?tɔDCM?Ma/hxYph׃ρ01ȔXȺxWRW uxE4SZUhFrA),ssҢ8حI`n:`<唏.Z quU]tuώ˿%G G G G G G G G E n"yRC֒ &$zZqjeuI^+@c %Y U&y&8z^҉v$:ӞM=PGaPNBMHB&E@ ӑ"Et6,RT,TwK93sw%HI̻oܙ3sξ qd 8ܮ& { ; d%OH >g\ǝM( ޖE'6cv_i^iιr-胧~Z gHtNCv55555555=#˓Lڕ52y'LI*3%+ă)>HFsL4k쪼J)i3q r2[PKH?EL9Y )R!VQ%ǸSM0b"&,\0q&Q#/G2|':1>Oi>'XaYyYC .%(܊ x"~yE`0p/\[@@@@@@@@O@r%ifLCeQE)9L,3mh/<\Z"f!Pj@U4Z`%4 h| ˚d#-q+ wAU|H R^p&#ÁBIdO膗>cI 9>llji v|~}i0sgO&L}I՝r] gq$9/wL"l'ZL\9ir:Xe5~ `C&4-νk ɞvUI7}d&;Kd!ydYLSRO0MIt<u%Z_x-Kz罏ems/>S{ e5$rm,X**(>|ܢ@@cEHaI?G,Gڤ60 SN;#=щGXH%6H2Loamwp}`B g_:I+Rf;m+`_]w%y9`QvѹGȜs >6b_+T|0R:iW|1C0.bftv.1rd{ꙗlS .逇_*D掤Qn,>ﷰi =PnӭI)!<`sC4P[@@@@@@@@ O3Ժ|/i?w1 y5i(By Y~'i0pK?L*+,b?=2?t=i~oڍ?t{Y>y>6@ ]v6d֬N~yeClϯdc{magÏ]Y̋}܂1nx٣OpeہG_`|su[a6lCewv]} y5mf'~oYy=d߭T<4|_VE0m7Vʖ[fa;ؽGG!Giwu}讶+ ZFٰw6Xz iq[†-aй9f` v}؅V^~a{ױ56l(F9w<~oTSLn7;ގ_x-vڣO`Gz}ߓvZ,S{Rp(|0ŋRX`2?_?4"fJ/"dR[%7b£2OUNTjIW;rۀ {,qTLٜ?\el駱%j6ᣣh4oȜ͇ѾZKjbo ^˲bYf/mag즿;.e[~uuavX4/1Cyq6{sxx{16sia>k/-C6Y_Z ϖ-=Γӄ4AK:ClO&FFFFFFFFDO);tz v.f6a(J(}+tV~kCT|*f O2I8^B"q<׬>ijG֧momk ٞ|9nG445l~Yhv +S3nA0LکX+!}s#¶iZb]] u<i;&qK؛#ASBT&qM/D: x^-W/0i]NjjjjjjjjzN^,V l97h*Hfe'Ѯ`+gbɞ{# * pb8`z;ȝy)_p?`=lj}^c9K{_.&_~?eN]9@aw3#OfL* _0>$ڱڟq̧OZdATXo ^S.s.Z&yNotmY,^ym!Ѓ8qu/u;l ̟ަ;W[ikgA?T; 4Jo<4}̾ *K'vgݖǨ0F%`GxuWzP?b<a+`!s[~ľs=E<>?_P>(Ngx(C$f၏~tXXxq C]Emhm55555555=)7RHRA15F2 &K]ORH1$4 ϱ<#1u䞤4󞮜>rg ;}a||r!u$SShx% ;m`XZ\c@@@@@@@@O@&L 2aTi,dWc*Ĉ#Mr.lzOcC4c}2O9ΦY0]H8_qە) kN=q' Sϩ-bŢPuCLs Pzs '<"eX}{&HuU^/i$9Iv$k'PO4*y&. gђÆqW 0!DQ۬r01d!A2&y"OSTEH]0nN4L  χ빢qv@Sʝ%S'C->Iʠ졖 (dm55555555=*x BH&5n̐9±J"u|2=$u='?9e!q1S\SM} TЀ#) i lYtE2;OP$WQv# (2+rcb۝й+< L>Dq[z2A8A^ *0>[[4 DDi,9L2GG ӈ# 2NFDNunxh Mvˤы!͟L:Tg뇾eA'%6꒮RmSHeI}A`7t =l`j=JSd!+$X0ȣdpJO`MTGI IDAT.ݖ[33Y&*/']gGFW{(թe>f G הX/:0.q M1s!|]"m?j"X2enTQ`hMĜv~.UP'9&9zFc2сkyHKuКFؙ-5ܲyJEV'~24q9Cx{kjjjjzFzw> QT!$R%z%, Zf&FGgB Z2F5Qj,ZiтQFQ@+& g%֑}8m pc!PϒsGsG~@҈0Iy'X˦2zR<ZGilucrjg _dB'l1zZۄEm555555n#Ydʬ=Y@{rAPqlZ$l%A6uH'ِg#L 4Wy_2ְyیFJϘ)c Ff5zj쑤s_QKHE{|7nzh/p/۠{kѹ>Sjv"tEK%Qi;H#ߋ5Z.MDT.i"pP |kjjjzD H&Xo䲞GB˜SNlȼ !}9!AW# 9zK+L=tO#l=:߆&mS?d4ylā&zUgv^Tkb PsYTV?cvj615@[okxW^ ˜#WIﳑ}[~sfڔSLnmc:[+v}zսTC545KI؞5iA(- E,o@s.>555555@p ~7o:+}Q☵\ |ߍ3LarFY KBOy87ɽ{J!d&ʔ1|K%%  =>{~gh#!{y8}o 8(Tiƛo?o~@s.8߬ ;g{~A̭IZ뎑¡m*>Q LuQ}V񱛀.?뿙,c >yLQʶC!hs7!Ѐ7)Cl=6UV\fƛv-f==q. FjnMoZࢿdqmOkHڳliW^~uɧ 87l#ﷃ>y9{WwwX>U7_E@{ \z'?P~Q/quױGmW)c2YXwq?>a?CvY#P#P#P#P#P#0#;2\1yd O=~J^1I*%deSh hHyt ~t=U<,mpLvn6lm/D{6Kiߞ[3Ͻhk~N‹. %l Ǹ\qm*@\t{U|PC_'v7/x9f[{}l]yggyC{WlŇQ~Ӯ^%ۢ i/܃0\0 x0d>1_r9mց')f3vf {l%]tJ ]}1ߴdzwQ5mO< >;BL"e7d+!U3 'o,R0A{՝ ߱26`8>}@@@@g!=dGJ~ID .)kdz_ٖ%3y4Lڏe>R4¾$7' wUOw?.}|YfV}'U-VXMmv9ܾwmw/5Trm/Ģag-h싫..9F,k 7_]{)Ydqgo^}#6??b}'̾é'׾09|;m)yrEG 藴;l"sqUq}Xm9^ug v *#o-?Evآ.jvZ}9C;%ls=w[ˮڀlYg9.1SM=~65ewߵC;;M;t̲_.?ڶD-Γ<'t o>h'?9S޻`?:iC@@@@$|_)ǭ >8.lʤXj"1f{gl#O6[&q[昍W{mw>hV%j3n~{lE;v!goou66Ok.~=ԋ(^E-0x A}[B]Ȼoog^;#y{EO[zm-w?",3 )@ R\UpBBmB cӞnBM8w:C·[n⋶[.;l^vM7ٺg[o]y"k/f/mvvAٰaQ\Zwv֯+vmï|նguqSlK/vomv;Q& Ƅixr߯&olvWʇ]w8̩sLJxdM2Z:#ۤr,oR,*.rC`C5A^Ȩɱ6`}K%l! ;xﭱ;1E| 0V(@/NC̉bxp 6>|\}]KgƵK^^^|5{0{~]h}l#3NO?dnw=3zd\ͷލg(F~ dž;(׬o9cg^!s Zsu<(Dx76:i8(&2Ec#Pivɿk &\?kyG\:qiYg?4SM7`>M16^`P8s_a0p@l[n6Ђ'ѝݴ ֔. :~#l5oUV;6|q iMy}gWr)mV쾛9߫fu~.rTI-Ʉ8f¯!GH7$A0曍z 7mK6!>]XZ|c.| l{u{䱧 -LE1rE맟}n]k]l-3s헿N6]j]v ŏ] ^vn[wc_qں/BS5i G X?C):ZZ{ B!| 16'n;}-7j[ ,ZkǠ;wt6&k8's1B/:&Aہo)qKc]A>9}@@@@@$J3$G%bBkwoVghKW{%_gG}ypnB̮םs㶻wŻ;e=gS#5)3lbGōJ{=;Ϧj <4 s}ڟ\a1ǵ+^<#Ē z!_a KsطJH]#N<dI~2zv)Á)k.r 70cгN(dvx vى'`7X?[q(ׯ[^{}|q1.9=l]w﷙^" 61m^*:s\X#P#P#P#P#P#0iE@_Dc1N&5*Pr#cI< 2+_;IeZRDKBMyͻԖL+,by?m vO]*,9޸Գ`?ǟgl<6x -.BoG /@v_o_qg|.Nh#AB ZX!cޮq! Akn|>,`_'pq8/ͩb5#[o:D4~#CWn^i`7Ozkut}Y mjwĈSNnN){$;[#$##GiSNo"g}yu߲oّ(yQkKRK-bnoi3H|x|י3$#QI3~ Z7A& S_X.m60l)Ym FgG(륐9-F1>[FRßQ: iMiȧ5{ H趨+Z<#,9)>PG AD1;siY4c+} YrL4 l^Ҋk$(>EDկ]ljkؼC|CWUjAқqƙl Z߾S?y$СCm9*sv0P[3ز]feV<7XuН|C_9nQÎ;[mas ţͮ6:Ӈ^FI71[j~|yx(!b=Pg.GϛDs:18]E]b#Uf'[AKDZdShMDk<1fEvAh3Af@KKٳTd p'E$lK{Ne HEpTq1FJ1"Z2+ҤhZͯv'_b$<@c8wN9]d;mؓ:?5555555hxLPI#W7y"3ISIVv)]O.SJd`B۳4ْ!RrFq}LbeHz\e.sRIpJKD7v ¶֡"rNOxq4kJ%Nsn6iBr2k(PHcؠŋ!X31kciA؇u&CN7}3 ߜ4Of:K@@@@@ނ1A]VFlAj+.W" h4[GJ(i1ΈRsP5ACjcF~X` p}$b!?Pò[vv]٧b<"nGeA>cĄ;P%w8+<.yFTPs4yv\24DžY%,ʰo"hz[&>Q^yn?n>ŲZ#=匌&TfdSQL*#+LkF(2 Þ&IITzEsNJv"C$T< \J~2 Lh.'%qHI1ιƖ% HO5-H>#*OZ˒ۀ4ρ8&_Wo|nML>ML 3 (uO(!&Hf=A7/G`r|]EfBgD[0x4\RL/bbJc^cR^tMm Jiv?r,<0rpY|&=#$1 3\w{JUCK.qދK 2:ưbt3Ƀ^r0{^ug.ӣ; =<#V$130%,*:2!݋PK=d~:J>!mCa*$9⓻0JahvL ғ>izŠ 4Cm'?nortؐyx?E"6q-;% *4)nYnb {\⫌wlb3S]be8ET8(fS9e2q4&&zgFFFFD+ng`J ffk R" IDAT@.&r7A.tfW-'<6'Q0zd2ɓOEqĠ^ӂNIt/iU ,0:jZ\ 3VOݢ J*1r,G8. \PȄWr4)X<rHS'.n ғfD,4Q@:Q4aM (} wLwI+E\'LٔF2(d1*I%\e)_ElBZ<4ߊ̔4La$}G:h{ ^el)ΡgBL qA|A(^]ҡI%OTSrq^dbi_5\|G#JwWnuRl%΢Z/+*WvJaPNsюFkjjjj&]n'\'sHdO3D4pӀ VS r{(gC_^ vM{^`(:ŀ4NQL@ho!xWf`Z~p It0G]E~\\zJH9mԣW'E@^WMJ}$м$ :f/Mͧݨf=L-X/Q]$l~$"(閂k"(yUқ NǞ('iN3_yu] 68 4&2ﵮ9)bsY c)'k@G*ͳ12h$hm %}3rE5VHMr@#' L\ "XP]K i&FNr 59?a K* anI?9|4K$ NNQQ eb)ENӱub~AQ^Fzd : y 2h.uĨ )04zOz@-;Q55555H4-{.:ghɣrF B.$2*U]i#)e8S;>S`ni텓29;bz@“i,ak$F0Jوp5c!PZ'R@&|%C%#Z|, |7";+p;g [% ~p BRd݌ L5fEn$tR c@@@@@@@@߾}SNk/v@fȞ瘉7OsIj-s+yN8PGB66ct۶# S!Lm48_ B"j:&ᇼ|FJSŁ8H#Լ5jr~dX}:XRp6_$CP)15vf侢ƹZc\}Gr"F7*pbK`ѬD@@@@@@@￟yD܂ 2RIq:]HȑY" N6i<.y$c 2IOq]~yN"LpZwuu +l'抑.ZNX fKY*, VnNjaK6_,M1,tavPf>JAyТl܂@>>iG..Fjŵ-XL"#)GR!i09x2$J)`VKDt%甒'6L/&eEShJ >1 BIsBȔ4,<>9F"1NgiG-]/hTz4jː~ (CO@~0d=Xk9`+) hF= \~PrcR55555555`D癑a2Yƣ"`"-%SN;,*uh/<@ZEBC+L)d0Ǿx av٨F0C2:Lk.Wt\k&p–obic Jikwr^ݬ@z\Y.f r;P~s *1} -\I:t>IU(O #H2|)k)ףC5_T%d޼݊-nOj_]Y1AsG/(ɥ 퍎rd]lP񳎱FGy4אu|%3!!hv@b d1丌8CM<9UQ7[EJlȚis{f!{s]2`Ծ(A-Ȓ>{Fl *YY$ydcNK7Qiu~ m%#B!m+T}NGc &g2XA,@ AIˑCK!R֙膨3QΓ3xT@UH<D4fˉ/%AOt2`ds ,e>g9bM;Aީq:nV^LZ'_ y97yTP9/y| Ɠ: jjjjjjjjzR5R%zO3)B+. I4gjt7H&x<>{2 ޳hOGe2x1A#.ͫ?x!iAv&}-dr:8V" "xMSgE]1¯?< sY@|W_ PNJM<%-%q?)h>l7M5ՔvλjSO=:d!ÇU> tGdWgmo睿-;?IٿKx뭷l}W>:Ȧb#Gڎ;do7bjkvao${'p":LW11xꩧ&mԴK/ف`6_y;3wޱ#<^x7ǥ`|#S1X3k|S9W|ھ{)xCo?H{g];f2h;3 ;3Y)tMg~=¶?!}ˉz@e|ld 87Rƒ;oTRWUx 伏dG|]')Ad؝{#O|2֝?j$Xx@ QeHQ<4Y :8ls(nubC.h$b'6&&@"cݞ0Rk>A3s4eSxx4!n%3|iD'/DMvoncucm}'SN>sA5^Oj+-8g|tӶqcclˏj JIgAm78bJgdv;m׷E]ۖZ=䐒DxTǦQ[~y` l=kVx\g,|Mc:2.qc|4||ߞq/uRcC.#W\̓+!uiٝwe'p_y-BM}vyK,ubɟ{זYHtR<芿^gu=L63Yov@k"m ]ux")f`*R۩x~x T:$Lۨ:oT۳zf^p[g۰1u5V}ަ[|oz+XPt,Y  ʂ}|FкK=E;Dfh|\ _:WrB,B,eN3q*GnmGst=q՗I1'=Nds9 :%]umι涽}N6=l H#VW?dxe#X@Š׿yF,f/6Ìm!cˤdluwlvZk{e|9~Sm?m Rr+ރ5W[WWi\?h~rwrݷoeR~`{ﳏt7>ѱ0~m6-M7ʘ<`>sww,${1]'`-4S޾xQG%KW?^wo~u] ӟ^W]Z߾}U|.ĸG~X48qks~f\imf]/nۜ?*;'m]w8ߘc=&6O? 0??}@%jj掦<116D){R`8]hAbC=Z&ĸt3qłzaR :>nױ^x!?W_Gl}/\K66¸Ƅ@)8"$J* mѪ, [&Q-w@zZb=EN[PK=f %>}I}21yΏkzu@W?_ W$Njb|1K/l|؍7ވSW_uv-*x;l=w\`{ Ms챸-l;G? /ȋ/hbg_\Xzdw\M̘ҝKYz/ ݎq7ݸ*TO?-hw-?­}_MeM6.Z_;;d.:uٶ+6Ç Czވ琷d#=bS9T1Âvm)J|s++VZi4v9`;X~f/x}(臽@A2QTGF` &a؅  yQd>" ty銦FĄ}k^⻀hn>[>!/-C_~9 [YȜ#hp~Сvٯ2㷾-_p! ^{2_Y[xly:@4|>~׿\߶#oC~@;DbwX/6mV#P##ԾiN:yNvȾ %1|2q"|L׏z ,r`3!X~8,г"plHd8ΆvFrWv|gD6ib+pRfuR5+D\{ZLkqjÅ!#I!}cjZyX|Lbqzs]ilpLd4^"ԟ􅿻P f͖3s7e-ym:K,-R$;,w;NSJ|_$> 4>t&_cqbuO{ǵqq~9J?n[xsX=* ߱:osƦAc; .fqV1.س1gn}3wq Pj_#P##H"WUv0Xe]yb iZΉ4S`]gO z)N9h q2c2aFlr8Oc PoSo<$r5Mc4J"XSQ93b-viT+@:Bx¯Bk[ŷF':ZO\d8燜qdr[+2WZy\ͶŶ]vev<޲r'wzY-o[w]oȼ۸/z9 ' ]_J-{FKCl3?c''")e9-L!mw|ήНcQcZcw. /n_bW^u[yn2Վ .۶ f;3mv*=x 3e}'WFwaw`zcCMs;W{4Pql|.6^Jܴ/!C؛#T"x7w/X_:)ƗgY~~\Ym, IDATO ;} t_4_Oɘ{e˘g-LOJz^Ȣ[9Ֆ[%]Oycގg2 |gcӄwjjF@e|R"QYF 4z/7hdJU[T0iX3ŻUOh#g%dG,IGFdi?>! ?@%"QGz\iBx<  R8K{#Ř膟aRqQIr"bIf/9}`\I8#WwSܿ'!7ϜI׵^cx7^^=|oݷtoi.y K.[o]<r$SW^6޻1oXyo#z0瀷?Ti5dۄy"C J?pCx:1Teq䷶.&!_kVq^˛B5(CT[@@wEx~5M~kjjj&XX&5*!vZ ex$z5/P̘\ȧc#VDn&*#5Ѥ.`rZAE Q_oƒÐ̄k(cHJs >z{BLq=K zHv:fdiKcXuh8m[`ycJ0r:稣I; -i7iFFFF`lDt3DLWɦ<=U@s:a@q3t%,eܵ$r S@FG~bQqk<%֛b _eԜqH݈rpEK65I>b Z&teQ$N/98bv< ^jGz7DeӄV붶55555555=$}.6lXs@>/J ,`)J.CdA&dLw3 OS|d4#> n;mi'~h?k#qaܥ vtfe)/DCRd-FZ{tZt!IxaSMϝoEaԾFFFFFFFF'D ^Ët3mPL?vA"TxߔN$2Q 4w\!ɨ/ "C#'(炏5Ɲ- mAJ.\Fh"LSjO6.R^xē=GeV&eZI):emOF1=1q~Gk3h'Rq(TJ&LjjjjjjjjzF3 L/+q9B%q\+L+u基Oz~kv} eb%Cx@lK>SRuXEL҄iۧ7V6BQ#x=o=) V )rQ6\R}xk\(#Txh`9\Ӱ͢%oA.T`;Rp,C^zxͷ?`#{O D]v@d,3Mk/3>5u$VN4΄3Ǟ;1RʴR9t!>h*aw^/\VPG~d8bJ`aZpO3(F}J\7OA@%%ܴ{AK9Og+N0ź=(oEjDVHa#׭QGLAbpN.̉DOl7VRT'=jҝg;-7FѻA5D)"$A(E'A)DDI 4=JkoϾ23o.|kuYs-$ vݏf>R{ŢnF` F_nhhbkjp HҒb1ccr mOfQJ`K&- 1k`\Dc\[@@?h[H"BGeBNЀIQ,="RUeńt<;RxA$dtB+&֮u)PIr ~# vDŒ.i-ԻJky +DB7y 6X54ܑ.x,Ai?avt-1?~ɐݢ'V33l[[>XyEupY!8J,5aP[IނY_ 551"BB-iEYmIK0#@-+,T+٥K8O sr˄%)L0}D#0'IdXc<#/R\tŐ N&BAl6e퍷{ _P}+EH):0 )֚L2FJ4s̈́e:3nfMƈ zO9ji8|‰(v`2Ѷnj t)#{7[oյ|]N?LR֮ FFFFFFF`b@q DK) m\#ZiHJ!9 zI+;aעY&+1ɣnR2]h&JMn !p-mE!26o"@1,DxO YҜ3~H1ټ?_F.5qfM3sy]ُ$ Shš3'S4 mńlQ!ِiQNU>d隋m6E˛=cZ:r!/M/S͖6d>SOCo\}tXp\A<أiUWH|^|\vƅڭܸQHjFF`‰@KL1E ,}IC=Biɶ \S5 d /Gkؼ/ ^95rML0kY N09uaux?&Rبiqȴm'BVL2쀀f}.%@ؑ\d8I\rmZ$<8z(๔ XfțKi=~W^~3/Ab=vMr:sΙ~ta앎=Rtry>xKŸv'bn5.t7Ş*F@@A9[ o="2J=&ɓl^qe7J12tSȇ]{kelFY $8QK=/@̦%@ٱl7.g w9 pX;Q6FGDd$'kE*e4pI(3*MO R8 gbTTqHe߈Oxlw*>S鐽vLl'd2!G~t)ד z#<at\Rطnpd>K=t`2ܠɳ0"[QĀ4!֔!ck.OٸYxH>wÑ;fEFKZK:OZߒF/dBA7^{5 ;_O?LK.R8M? 矗^ $LSr+|Hs^ kg]`?Q9ӊY<->xtqLj;>0}famtWؠs_62Q{1iELwyGzv>-ܢӧ {3űQ_~)wӺotO~=~;vȮ[}XoЋ7?]~N=t=w~ g5v_t^7.7pGZsЮl)xi^c< ݟn&3M;t[o/Ei?u؉.`);心G6\wif: 0KmeH_uÌislH0NúQ zBc$j@"'BUv(YzffCx|Ps?1pp)8$]0%!Sp#!SMc gLD|xf1L9g` d9RBM.PM(:ōQMjkaJLʑMnY;]}مiٕH]mÐn?/4z7x5VJ7:˭rMv/E[|ISO3Hy:~iƃCQzNiʩJv-~?ԋ6jo|2yn_?"+o~g#^;^cA78ק_2MF- qtzA_ ATZy)'~t:7W?9HJ<9ަX`wbriYVYV`@1 1桊Cr\fI[Пh> V1ҤODF$f@-ZK9W`) EBbY L M0fBUx@&C6 0)OlZ @~!_[_ 6̣ywM⋧7 /k1mX"ʬi9 і5y2kz'B /,w}tߧ]vSNzUęiOXP0'~Л [ÏN8%6YrI}R{ ֩s̙"fzi].eG8& w$xq nmθ'z>vC&f_J_ZIK-s@?ڡ-Ѹŏ1N+v?{(]}-W|=r0D>M ]+mW*~] (`_$W$?bsߊR$4qQ ] p9 ,4TlȪ|7T2^/c4J`^A[~h2&IJCx M+M}:s>lH6HӤ0+/=Iq6/IUpqٮ[mVZyyꬿi SO>v[鬟%W&6||/>qoKs5O]{ zi .ӮCȫFFF`E'9gr_D_+e)($ǒ%$9J@B9gYEooR%L{)_CSNC0|lLbs~. ff$R=M yp®a8 A,W]Ņ.R>|&+u )%^C!c`4lƜ.1AԚ`࠴2+CNѭ,BXimmFxM6nzv|~2{훖/nnZ{q T7/N#~tB^wUҗ6Z/-c~w ƾ'a YuwydvI_6i=VZf1|Z>xv(͈+5{jM+.-q|e-7K)\ _Ү;p{8XӴ7e]wKu^'|ƭvlIQ*>?&pzg5'jYn|_WZ;a;?<]555"S  $1!U"#|0,טcԁw_)ީF q3GSo"Odn ͮhu#D4mU3)(/W4:ɴb {C /c $ Fל72}}kxش /t]ۛ)<¿ӌ3ϒלI˱gLMoB?巷-_EqG³ǝtj_#P#0D+M;y f@Wp5z g|4ROP9U[Њ<|.!q>m1PWBd6lǓQ~E !d$-+D>I1 d"DB%OI=8Be/s E P+ț HGh>3RQ%@LnSG1ϋOea^z|"zǺ*S#P#P#P#P#P#P#0F@H$J3@(G&0do(zxDuƱb.#={kQ+isWn/;n)VĨ%+WHƶ!דϖDUIJ %&+pr]|C~y#Vdg 5FV`"֮FFFFFFFF`E@π39H:='fQȊHkΓSi!aj¶2'8Z/XؒmE|ERuK.,y˩yA4.ä, 0g iIX2/S{$ȵ"0}͙vKNE'Aa_QA9%_h:f?t> Xf{vL8%Y, #0f Ɯn"E|$HGS\iזGL6LIrh1ClYB ԛ2{&vcaSih7"&,( % boȔ!@4@#)BFdkVRA 5i)pic9c  &ŦmAEoy>a! LfDX<,&Y`bIXSK!''TP8/d˙=ðbs;rC7K)<[5h}Xo;3~- G\!y4H/ófg 4Ydc B^2c?Nb@Y())_%2Z ' C4+)Ge; McI:~3'f73U8JͲЋM-]q -!o 8f`H )D\.sjTqiTxGAߗu>x9S[@@@@@@@@@)XJ>ZBieK\ ;=fhQEC+ Q^Iyl=a[Kb[6fI$%3K_t wCט8D[&8ܣQ҆^;O!i4A*HM*JzM(d;)8hjkZ!E։"S' 1lMeL-XܣYJ-$z#tr &XX0%}nA|1eVp7 t\Nz)|9?8w6BT5H \jh8$hCdHDM ]j&a)-.J%͒Z<*W#YNjjjjjjjj&,&4FhW8"9D$2W 5Z6sIplQ UQ"%-˒PLȓl-JlO6HblXwtS(80jň/x%qM\?LԼYO1FHɹ6bBX֗Pa:3(m6y  㴫X+ S+ӂW6`J(Uey[J6gx7P X2.SOK|nZeO ~x+#tߓr%\IMd z~t6D0"s:ф ?h(P9 0*{܊٣ˆ= 7M:#}Uq0.-Cƙ|Qvcu]#P#P#P#P#P#P#P#0F@&IFv_c ԱD)D_Y6bL-&[brSӣEs[,!B^uҔIm{`My: BEФ%Mt}Y&nl$l(]ND9GCY$m0cy2QW5Z#?b4 厕@6::(P!i%.EjSLRN11ADM(lE=9nޅ?7J\P@ HT UsaİjX{nI<>pDCуhA| ﺴ`ŊeɴCAV\ 'Db "$jnkXP6PtIa$ #*.IU1bUٴVM+Z<Ly$m^h*9J]JG͇ µt61و̨OArC&;,`:[͜Ny#G.ͦJsM{CbF^S|-5Cc'1Cpfx{/haƙbtw[oϐ}яinqn}Vn\T1&z'`j#&1ӜRDN%HN^cD2N魗M+y`F0OrY*jF$֐`@9Z7Y~HDE`B]'kˢ.n%O\;>ϧΣcZʢƾٝP1Ftmݺҋ`(@^֡7a_qEkK,JW&<{3fLz _zsݿ)v[i#~.;K;Nz_w;H555Gcua^C)^F}T/"RL5QKbL qN(S՚4L7 -$OV!#MbDrnz˝CGH AV345P,&VNl:qDA\09c:)TˆQ>8d&2~X ƐCؘf30C:sow+j {p;gf}(o8g?K,XsQG-ロ6LS[ogN.92qđW\4ϼoC~vm~mw8B7fL3r{;3~=͟~>?OOGydZt1V_}t͵f]_a4L3\(Ş9,{['Zo+qKsv $6V^2 hA ),^4iŇFdqԃpA@unEmޓC>mpL $7{%itTW3Qt92rqHmМ xLA:1(9#8BQ'Q;E]Ba;N:(m.OH]vYK-"nN7*҈>snLW_u%xy3=ܓt9Rb?z~G2Kw%{IjwߝF~x~f%{6m[oE=+Q꫄ae~L=N9O wC6HO|#R6 ߗ#cVGw_5j9OwyWz-{|mU6 IDATy۴~v<;cfi`9眛8`X]Æ]peeꩧJC u1B|W:2=\##Zo>'z*yu }TWjYdt! . cu]78iZkC;Ti6yi}M4L曡2vkߗ-tu\ :T֌[\Av_絯g76|.^|mv76%m>4?E^Tռsi[nIs˭w!/IXg!cꩧʇzֱFFFiq_$݂iʙ: ڕ2EbTY%Y Yp'Z(@/ tq/v ?Kcb>PM8E f%EjhH,7?D3mUo-%Ջ 3aqm/noهEӪs`i, `0)~ WxEJ]|qgC.b6DR'H -GMB_8fsvZs9?>>Ohꫯ&:ľYĔ.1>Î-\,X4c;nmvOyϝ^࿕~}َU?<ȣi>= a9Oye_~aLZ W=z!fiyovn^:u]#P#P#qDoIZޒJ{H9)YFt`oD3lZyiK塮Gg]a2qPW5xHEӥ`?LTw H\Z!q}4"!,Cb TM㭸&sY !%. QH%5ɦku¶ =UdĉcdM6Qr3nxp~rV]π:h~}Lr4C4=odjlos|0i\Ua"t0pآL~lXc|&dϽB::o@S~Cnwt5\젃Kq% nf/lf72kh^eXN׸:t/]wuΛPvzme[R{&YxARW%(ӗvc*8L]存k YKZ1y'zZW555,m*Xay3Sq2Ac~_,LV%5YR1`cC}ffjTAHhx><n `ʼnH߹w6R(d A/+T8`M-UI@ՅҌnXqϋ!/O9b@ IW=Pv8&vjZk4n'.(|S^MnIYWvZN[:i5>>O.؜vC^[u YE~?kJdO*HH-Ulnr-dw%(q%=i{>!d<=uLzT#䋄5OI&[ͩ,"bkf0+ 1kd]9,Tg+n=m:eYuo?s >6g9?:f5T#m&磏>>rW^6UFFF`EUA77ب7G?l1{S 牞ZN2IEU2!Qas$&Y|@s[mǠpyb(L (A 1u3E˹D`TΊ^ .@^d36 ٶ EHTG(dJ4\Dz1 9JU3c")g51GQ'\ys?9Ar\6g0FH}+ \(h-=ЌE=tfyeEF0ٯ9Y/^M Qo 4Ϧ_h;[{ Ǐ  R2D+"=gS|@BX9M d| ; $3`BɴVd5l_@"H~diO=[jfBK cڲ) jqd30 ܞ0T Co5[T&(]NOd$*^8*TCޤ[uFFFFFFFF`bؠޝnK-lMRCKȎb“, ^)X),UTtLR 0(:}}P =r2(QYV Fr&m;fWWȰ82GCZ0g@=y:oԡͽ\H,@ٝl@d*>JaP澴7z"V&\?,bI*sG%9:(̄f $Mgi`iEocDQW+ոoN `fM7S9dA ) :rVL)"<*h Pkn X2bޛG%AAg(Q9ס5c`m3ʖ?B:ʛ#h WK :ΰ4lQ~$L>h9(ruCx$fUBA,Su4v~b|éqQ~+vmK7tS'?[do1a| `k3DӘH)`P6!Q66PvꩧoǞ>,̒m>OL -<8=:`?~ܭ#e.%\2S˓O˿=d_e5iv(uh%5OnaXM~?ʼn1rȚS1ik^b6j;pscħ&1GakV!y~̤+a3-x,⬈hK,ߥck-E[/Iq;W!3|HNHs5ww'xƩ>lHT?8qiz(໨>wNCdHf¤]7[;˯bqac·-~Y1e̯J:ӎsT}v9,-b:G} o'_b4̳!kM\pA钑#3G䎱mv^ZdEwUvܺ?t^z4 3 o97^8a܈k<_>iBk;qIcxǘd}]Ň[o;~rFFF`\FOxÌɻ&%L4A=InhWЀ9seg;u=W+#է.J'|lz(lDfU )14> =\ŮY !?wdP29KV$pE)y*"膬nՂiGʼn f,aٸs>kهD&e:7I,t:˯F{Ow}w:~Gw_5jT:sq~NN=dwe믧{sݵgkNGf ^׭Wo}ӓ|"x lDl=t%#s|ץi::csmvo9ߨtJ#FtiSO;-~iK/{ߏ̯Gw֩_Jl'ltک?I7pCkgk ݷ[7pa0tӥ?O*\sM;Dxi?7,>8t 7K/xi\qxM]ᕘ'|2Ӣ.c{S՛O:\5554($~,l$VX k$>#ǔH]9nsdBMzcspsa:퐚|0`tۋց]0 MW6$IkLx-7 k$QED/(wf@,v8l9x$<8iƬ0qs#!SF :&*iy(D~tQbC9XxǦwudС"ۮZZ3qW:2=\i /0`Zl?Btkǭ%ϧg7Uwbn}(.´׶J'pxmގ;5zkN?=q{dU\z 2Dr0eojZh!?{Oq\{[߉[Ҏ;򗿨d!cꩧfZ?7Xe1󟟝fi>~X¸~mJ3ǜsXbɥң=7ZU};p90;6}\_zO'quXֱFFF#pQ{(0@Y .F>IxJ*]LԢZhZ .:b<H->R”)وf,wbYl}IT3Ra+%d5 -ya3S|A-gl^}FWpcoA>5Ŕf ^N LWc ]U\v]'{B$S2Tco .ל-O-hkx 矟K5Ο#A?!O:0ߜN9ǸmoSL|sAe2v[,]~[wuw FSU2|'bx7l0of+qoϔba䥗w%{̏ZD\zӴNyzpǕoVuZsw 6ک_0m BW\pX:G' hۣ0ҞƒeKDvWTAW ģ.|5q]&2S A3gdӞ{N7li|g _@<I[lEI[nI6yӦ}1]}պ]gdOj*YCM/rq[)k IDAT.8 kDk~Ӿ+%;HyZҗ0KxgVXaӵ=4yGݼK69ZwO>|]\v7%[7Gscz ~; /~Nq LuU`ň%0GTknX 1ulh1t"^d)y4/mHl*LX Ni$C?+q(/Y >ׁJו͛/Z`9† Ə9zR3/E%P`q!h:2{wREeUWKs9G:cSN>Yk-䤕VZ) C6'lEfo1c6pvE"9}Wd-eb66۔'+a˜M,{5ӧ7`؞簹=|2dH,5vͷkXcu7L۳Nw D>z+c[;" է2yNzY']vr]LWC퉣'Fd6[GN4)$[df22y.;Fe->$lmn T \qغj"qې+=tˆ_F zoRa!Av '*`(ƞ\8^3 .Dxηub虠&'Qxnc>3MvչtWmOjxXg56|WXb ̏鞻ʴ:#* lGjګ $&!I߱$PLuhdFTi<9"q0w)vPh #ۧ=q`lN1 z6 \)~`LW PQ4 B%55PgvM+DvhSXQt1w@06]Y*h6'{)񭎈-R4r]LhBWNj akZhɫPKEɫ岘n&X@ۨ(7ڶXT U5G<\4>E Es+`QUFV iȻBN`UlTY~!`YBhb3\9U2s|?BOA%L2Ɗ SZ@΂k<8W#+ FJ,"J\Ԝ`<%qx]L(R~Lq !x{#&AqF2j4MdDn)Ml&+VH P$.P.d`N9M5,ʰ{h㖫EJxv^Mu(X }qjjjjjjjjFZedJasvov[N 7kqJԓX0;.6tyYT@NJ mxXkvӸBVX&$[kBj>aRb!{TmB&i| WITKU6}>aMR&K`I6%9U,\Q΋?JŧzX#P#P#P#P#P#P#P#0@"ObrmvK&fWyhNZ-WHԩfgA5$7Ioo[NRSD]P kˠѾ}B:5NU٨s8Shgf]m GO\#B*C햭 "A ( |ky$g'PI* xr,NYq0TFFFFFFFF`@E@%7FO5WTVxllր1enx6eJ~A*ܢUIj@J 'Iv[ 0c QX,RddZ6xgPbC҇˜& @d GS:ld/uiT&*8䆐X|bf'Y!1 s]@@@@@@@@BiadL`ޘ]lOPVkzJ7 =5 cI9HülJOĒ, `¤٠у.(U qibRPNK/±D}\jm܉>nOj (4N'N"0ɈOĕH%]ʕV o oras /D _BEU(PBbm55555555(zK˦AZ~ĚIk$ \1Tr #L#ѻHj(QKeǻ4ؙ’,IyfX8Ək؆$v/v'7((uD77FO)F!0dSjmwH%;K+fna}=P"6FFFFFFFF`@D`3DKdW;g3O pJkްJTq ~!%埒mU.%go@H-t066>4U.lIb鈃Ö^GOy囹: -8ؘ!AH)4C>NKaQ{+ B \N 2`oBK  RVDےB=@ZZqR>Y%bIZXa T6dsnS˳r .w]걹P a0LP@/!V"B{i(As![G0y` 1~ڧMZN(zoD8A} |@8La9hM蘒>ia90mL\55555555%(@p2dR ?T,^ ԲLQБm<,R *FLFF?5 |XaAAR {^w.3Dsګ3w>ǖ3pɇB(:s(L2/B7}=BmX.L4zF{!"~-N|V{G yn{h"FȜ(:y԰Y70)2Ṣ vF Oٞ$zSh׏I Bc,!#d5\}Ȫ2m>4c0 ?+@0IN#52~Tަ4)V\Еp3@Ltwa4ʔy(BT롱<ڐ>bnXz~x"` ӍɩsI%,#utY uB H4 A+`-_ki(w-QmӉcD}Q>![F ꫲf 92^F &[ic U0*f cDA|.|0`iܕ{j݇JaC\zxuR'7!9s########qD+ d)$=Tob$5M5O'`,p(NQГ܇qV 5nT}+/^iz lT Wm7y *aP~ wHYbŨK\ƢO ĂkHC#Ǽj@H[ ХqHV.p|Ysz########D{@r9f<7+o$ul8HF$c)"gi'UM ptsHoGCV|N kΣEKbA#H5hku52[Y؃ٚсvfS,!Bo@/\HVS }7,{(AsŒ@5F{Em^k7Mye)XCfI [@@@@@@@N3ILu#aDf 6-F&꓎~o#Q [a hJC˕$:鎄[@VEMLjY00^ϽKjp ds #e-ӀxȪ>gmjHॣa0{j8{CR lsb ylla4v(-Jfpz5PCn<&)C|&66[S 8"tP }xUiEP^Cb/As"RE\: WH'?%LBH<1Y0lzeF?+3 -Z3[܈2-QH_nos|Cc#>m6SN>Iqg?j=(  q<*1Ӆ@\<|BAl\% k G$!aP Se p!΃CUT5TNas@4 ?A}m/+H>XU^(z5֑eHH ?HّN *GbU'٥3Ẍ́jP9tl8[ԣʫS#~[PBR~PBR43&:.p PiDϟ)qu[čn㵯}ݜLKxj+sNŭqvlٲr[ܢG?>OVߡ]ˇ>$0n{{Sve'?ŸU\pt{z.rX>;Tv70#0WќfR($;F&2N: #^ԄDؘd;'jFd1UdP499iĵF\b<-O Icp| Mc*"vy'c Ƥ D\ dD11Sj fmVr1.+~kwDVZUs9kg=˅'֭^on˲dɒ׽utw+|em-yc/_җye]u!ԧ>z察Ї>|K_7O======n[Jq$FheK-:tW5+ƴ#I͑8փYc"mv#sQva+M]#ïټA0G$ r<>*t6 I9d!SZdauà'" (,]sVgr `|ҡ7'` Wu1ד:~7VC}֪<38+ct}!~o}|;)?ʇ>/cU?/guVYrGqaVN˞{Y/_^~WyPy[uo~91GG~xr-zzzzzz6,d0H!U t Ӑ, șH 鶁H3EWSyx1* .fYi6xBcV/VoT"t3m'o}1N*GiCE%KXtŋ8A[.>c_rw߽.(ǾUGc]w-oy[ ######G`XqWa^rW90dԹSN`ՆQK9&Ӳ&:GGGGGGA rTB7'@ 08bNBTH6(@[L$fNLɟJWг BWz-Um>p8#!Q\2 i~G' ▎ W+C!F[ίt$!1Ztn6l['39p5H 4}ĒpZ;֣ZW3 uMD o] Ek1{W\Vk>rgicFKSL|y g?YyTxl&.Ps{;^]˒%KV}#s6######aG`}2JFZ\_3+z;Tri9gmI(P5Um&g#  &ޓGbFH1j YIޔQRl^ @|.rnJJDlܪ@OIq_il?t :Ísc W*og*#c##1z솃lئAElMm}FO=ͦW8Qq >DgвЃ{y4:BV'c!{h# $nSש9ƕ<}nIXI|bRR9+X.yiLZr9ucje8#2ÆR#L#̘>BۘOdy@VΘR#/g_.c$ىA査h5f2fL[@@@@@@@y2H^ri \CN :yi27'At&nuRS@%#4KO3njk$B[̆Qfd;`_X3r BZGe8sH`qunɯA5JRA5Ǧ*?F(xD"+rh6sH*ݻ ÛЙ(Q';$Y$ədM'̀6$2d[ 5 8# H{M'p-Do jIs<^6-e$m(MOsM4dD,ix4pz9֍LJz" 1ŐE=Ubo{1'§2 Zȅ6(XUs=########D`M3ԲE o[@nǙ` 8|L(PK\5M464F*0 8o%9Z٭z/Nۛ؃ߌs$Vcpª*I]Аî)YN9Qp%mFXBiłBXjG_ŌhV<S=I{`qϯN+*hȊÉi3&ҨBu1 elj }lr2M&b-2l)tO6DH S Adb]( lАs!eH'=40S%6r~Rh4!gq=8Xg,Oq,3iSp"W)&Zirq|$l6_٠ A<Gzzzzzzzz6f K-H@7O BiS'-8tnK\zct ¯ęXʣJ\GaD2o Nh\H+$Q7IX#$Z<T؋Z8H<Q#Hj &ħ٤+5gpX(u0HW3fZHI(C YT[M֮MjH )z0#;M ࢁ LR'%gLL,}Җ`+1jSFaH#тiE"ٛ'ωÀ-Yc mNf ٘C4xF|H#0z, |[y3ffA,4ಌOR]Ԯ己!#um}D#b‡; \o*d}a)|3ZՖ`Q*8>#)X8\ ƲF 4eBOP6c?͈ }f#zzzzz?A8g~ϟO,XParXvciz/_V/_mWhe…eM)ބ !&T.H}EY Fp|-J e mF%zC!*֊PE(w0N)qm<0T Hx.d@l~IX#clʈ Q`:lvi.甚Mb[5=====yWʃ>v"=.+(G۪?oMoRvu ]:kʹ[~%_5|[ou{}˒%Kʦmc)X5yԫ"ܜtfYg |8ЀeBb'jVY"P@ ? D ;3{ ;d#CTk3$Ŝ-E!0[, jQTe1] ݼZvca3Z`c1[C(K~XP:vCYreYbEYcҥmwܱdIAu7X%V,_ wJ>f.~[F&brgNrYqk%dFoֈ^=I~M~Ǚr F! [pSW6#76Īxl7ᴕQ.)/B7-Bl_c9+*tp'qfΏ:PCxW,sײkhlbɫ' ronɤvƖ؂6)'urw;Zpٹ{;O[}<}/>1 .*{h|Ѓ)?ɏW_6|BwDα%į`'Ȣ*2I=Xrl ofno}:WrڗqZjO5`na.9ZӠsr59nxb`r. ' 8uRl0r#`#9 8Cim!Rw\S[z13b5%P[@@@@@/^ՏU`B'k?y]|ַl[nK/>k)qa lj(&j^9dę;ׇ2I%:537h}t -y|ޣPUNPJx :a2' ؃N?h(<ԜZ~><  ta{tMq \沎_3shثAMEi@######pF7o *6/`%[WAJj$^-E$; $щ-*1ײbdF4gBZoOJ5 =*.MB>8CVlI_C̢=Fj7b iLU[h'8ZS[Ra& uXo StIЀ\KCQy{&G,*^=}ymⴃFm/|M i!Rz######p=#@O+sf'^y=5-&,$ kM )BjBYI .`NUK1YɶLV= Y/: Ad:?nYNN͗x+*c IvfL&u h's! }HG~u!q#__gJwnWs ],9S7\<,{z)=묳R}===3"T=ꢲ>/_E3#zxwϞ(/HtJ2:5a[rkk7&W%5t4g ķkbO^1"fYCiyƳIm(v Rέg85%*5h2L 0n-^tc⣫* ծ2a Տnw"_iߥwkk%/)>S7zor'SN9eo\g}vӝGOGGO^ʃ3?ڠ~eKLf݂Uˉ2 'O@X d!doĺ5@#V(zp9Uy Ȥ8)Q@jՂc ~%H}yF ͒h`S14M`njRyԘ \$Xsx7CVjR+g<wAġU1~ fkZG-oyKOZ/EAń GJ(<ƃNFb ͒jtQYv -K]Z 3z\{F^ ÊV"|?Oۿ-K,)wԣ7-~a7E+^^{}򣣏>p嶷m9W&Gr\ϖ[(XwS?r߿6)w˱􌁔?]o?>ꨣ +<5ټ.p[G]zWx9cu]M_'o-x|衇;nmz}##pӉTRyKFqL[bc7/zqrğ]?~pڻ123PqwLm 1CH~ʓ&jfzPf>:dQ/(eB8J6 辔UE"vb Դ1Jz)YNr`7WwpUQihN7Z*&>Z$: !<|! Zx txiiƽu.?.wK!?38nvi*z׻_~p {^9cʻn'o{~W?C/V[կo}k/Ї=r!?uP؜w`WzIsٜ6zo|p?m]xᅶ8Vq.2> ;N9G.TwGGG`c T  e+ .߾/K7m6ʚPW3JPN"dKclzEO q jB׿N^qx+_+Gk^>l6oyի^eM^.=ܳe/+g% :oҗT^7߼lKַj++$sٜxӞfߘ++\#lM3?O|.u{>7bƊTo====k*_srKW-Ճ@Wy 'BO7 :y<|el&<)d5~2sbƘ3GܸԸ`0[MdOXMAjN)~FtxJwY` r'ɮU'\KH!/dDLhYC* ).c>=VCEGŅ с@$$4`i{og-Y{{ȋx;TejP@-ZTN?g?[v(]mɒ%[?xgM6Ɵp`w4u|Y2>3p;LXMA@@M,.7fKˮZ/nO]BM2OD嗹 TŇW7Mgt1ϖR(i jڮ޶` uD`/l*O~O'kRV[O>/W\q'>Oy m];A[5;Px ^> hdݘ@Ū 3*\6Muؾ߳R'6Qym|Xy"8WV===cu)3pM-7+W]\+ (uZ]6_]_=n9GcΩۿ(>A>@VA_a/ظ(g<:is9#`EtPg,V xϐ+`tFcFY Ub%P,<8%Jլ>Cg$s4lL%su}cTE$=UTfnC*1^|.) A')F!sj.<4 }ƩX X[K\+}la{ =yO">?ӺnX͈/}K] Pp*\4 zE+ )\ծ)'ND*&SsLAދy.S"cdm1H&ZI7l%r\Q;8%>[ʏ56r6Am*+M?2fUM61_|̕n>nYt :DxQ˧#~m#馛<]jwy dɒ2C`?81n)\n g=+@˿Kk yMi=NJ֯ɷi=k _f_uަ֘;###p˽r-eۭ7o2 %+*2Woj˴p-[sq~rmxJG}gB{eֹhsSCH[~Ll$)0ҩ̳'2%gb:id>+k Ģd2NT͆aN[PX T}b eúO/f"`5ëb`&e&},x/Z,V<|P8qтN~cp29">s!V7Gfڧ##D9N-GSOo/嗿͝]=ww٭l&e6/>rک?)}G^~zO_=k􁇢|ӟъƛcEŭü'My4m.ژ}2=Od:&LUI$GqYLJ-GxQJ8+ V8̹75<{ѕfib;VD4 ZPLL0=O4Q UކԸ$ O>-h1ӄ 䡴&QGļʅ nbC{[_ + [|T.6mp4U|l2G1Ih٘ dnc-nqvMm7o|q{\#\{cSBX(ǘLRnv˖oR`񦋴ryr5x{(Oԧ\w lU~]MzѶ1mM6'Y#P h[8$ä&$cYnb&q lht!< jGsu TXtD#rtXWf;# cS5)&A&zͣi-Žz   TxpD!؟keo?q%J>͕y1aYv*Pz8"SSl7oac;Go===7PI8+X3fEڋX+ uWX\c''~zcgRv};<9SkrofG.67mB'N#_`" = o"!DF:0}En˘61xc7fc-Pͫ/Tc82MrVnKTAĬ=,PÀѦuA5Fm)oV=dCu;uQ"8yQMT8ļpcN+E`rE{#0 y} ,HVŃ MX.VpP|.#oliڸy Ǹ]v٥6α|x59o5I lm%5$e1]MLsSd=jSl$!7M((Hʌ PEI@fA7rS'|4 brWcdW ̣ٚwlBq#zB #lgw+C^}b W?@!K@l;G7Tر+4{ؠ"@>uC%ᩋ~V=(G7l*AV-RXp3*3 tutn#⍩*< ^AjpӭtB )b}i%5F萖717F*Xj⎨?S@@@@@wNs'@EQ.VAH=;#ķdqoQԃL6WB_ͩn _l@}:5DBAi1o b$pҫK08b#4tes+񣪘~K*mJAU<% W}WFlXczJdhsB汁\$Az3t^s9!H0֬5Wsm^TU8p&BɦeH1D˅śAzEtTϳ(X<_ _@B######ENvn8׳@#ObucŊmlc{\#Ɖ@D )bљd@@$cQ+ikMl5XkQYSUW]A &nɲ,iN,ǙU_JsӜtP[VbC$+5^`yZR92_jߢ%ڛ*xp]|6x{;0x3~Ņ+T,mJGVD*ڜ\9 =GGS {kY9` ]G6l( ,6(46@7u?#2Aցqj0F's`tCSb8$jFgi!K&쇅У32E3|qXr %+kպ3DxS*D\3rsGC'X`eOUQě`4@amhccb#ŏ ?U|(FrR]xeʓD#f\OqGGGGGG`ÌEQ^8X /hyMbt-t6`8N-ī)BE0eC؃X$C{zzzzz6p厔/;׆ԍ^qxt,4tai4!n1Ε+qh~dIҡn7l/Z'HD)J.<7^'~929MT3H.Ug󜸥j=Eb!ˠt/1їbNi=אM2+b- I{CFb|fc=KYgUvuc m>b\[m6墋/Kccpv;>dž(.A.5p)[ޮ%ijd4x6%Z+>6/]|GA`(N `ϡJQh'RikAQp:\-z<({wO"Z!$ȷg/|VlE?"x-T\3*>El,[O \s`(=h~" y'٦{vfɩCCoQ%<}[or'SN9e<8˝t"Aw]z9iY"v7Qgɦeo>lmHrHH^Gd"d59Ymޔ (R$\-W$|nRaz_'$?U`iQ{`d[TjIY+u{*>Դ%]OXяw(O|z_o{#Q^זw>OЇ>T{책ۡz/~qӕtd׿~o|cTWdsk5R7o/W_}uy]^X]ot|>?xg.w޴>F|7= |Ss[mb೨ go:Uu2!"D0l٩m6 X[h{||Dj/0}jLR+h4 PǰjI}0{BY3qz&*2gh9m5q< :6/, MӅs~fԳ<^L[^HEqUgqB:oT,[-K,)sL!I>(W$Y|w\~k_ֵV[|#(?яʋ^%/yIYtiWZ'o}[˓$|wn*>SevjsWzsSW&ӚhX4 -ws|O~0[[o:˟Ϸmy]dlZT#r#P:Lڀ VɆk.XẂ?cQv $l ~4h^}oM?az^uCGnR>fo^m b %nnapzeP-Fl.(U6w \fӹk贴BxbvW?;8'ůyk@o*}"x?׽.e=,/{g?_rAwܱ|K_rRk2Ն55do}[;^e!\5ͺ̕vWlM0h6d|>O{^e-t^WL}ΠD0CĄF~ F_3Nqq=h` 7`PCJ(%YU ^Ȟ {^L Ҟ䗼Sň$*7QG]yI!衯)!G SpsS{UN'$OUIIjܻMI"HAk@P Gyм Z$D!π"V5^|T Xzω:'b| a( }Oz?n~9\vy$ IDATӟt38c6%y;P;C*^zoz[by{Ϛ@3*\6碥).3'L0ּ1@QM߸QIx|Tt2'qqvH*8W MHi̖Wy-3b5U<56N咏gWfzEcX)Ykj{|\PX a>o8 G o-آr!޼Φ_MozSy#9 `%dٲe~yZǦx|GQ9mڡMbA"җ=]$<uaLxBQGGr[@n~ߔfX iYlDys[a{<] ښlEg6{V>u,n6_򗍺&ߦijߢvyC={"Ϯ&R?w?>2/M7Le|B*LV'EFJ}0'zY,rPb`V.x&z"p,Њ.G"?yF˧4;j 3%P~ (i* *H9uxEAcz 4Zs,fyYy5eez7Ȋ'ZҠY?e4f"oQDsU=8^V-؉urДLBe5y\< xh=( =4i 5 ('SȊ `rO(O|_vO83&̍D>76&VmN:FrW##psGzz!yyhexzr9gN/#m"lrq?'K TNi$U Rp/&!Ք׉eCi$+Z\}0H "fLГG|WNg:Í0nzUa4V4L~ bZA@l3s yXm0.3!Zo16M*p'Vw~0+En{:L&Z@4>5f)쒥QoSxkuS/=d?8v[ݪ<1Koj1nykvҲrKu(vЃI.z ̏}.~^i Dj(\@lFYH}՛= ɩPxɺ6s/^ʌA57AdZm9n;઼U1H =3"- YJNE?6ߓAb;?2j:zbQDhhJz1)(@C"cXhZLM"hS"SSl7olܰ 9'ltߐG}mk GFL#+D@y(ˍ#в~E")4QNFE W^*N $:_5NVᓘBJט@|`3}, (+z4-F'tFaB19N?X/8Q_sF&#ǹS+!*@<3Po======Po…+o@^ߴ\%~qclzŨ))nc:. o u'kHva0Pg}8H45!yC Ak3^ t|քϤz8L#I¯Ob@B&a7uKBz<g&Z2 ׫H Ƈuxm8v #~6Q`M$?-xkb#####F_U+\4>F$FZmy"OpmÍhSǚwFIg,4Uw":iEB&  o=T|H:ne cLSu{V3hvS;}@G# !Bēm_1膱$=j@2DWS6[H$D/(*LbS8E UھM ~ʍӵnb5JЁVhHn?j~#0'p6۴lݶM"HY[.]Vοr[l 8m(CNWWU ZE9f:uH1* >E5`ҕFBNxzmW}iQDAVjF4@7KXwoS Bt"-Jr, 7`;LVCU+3P[m_xm'jFxtԴ?jbbg>"48֋IU`X1T uWA3UT6f######E? \oחU4(΀(Ӝ+DT{nʫ,NE D \[=#KAck<2 U!5I_"~l$zv! c; U2urk8N3,h1|>ˈO MpLBrGw6TF,6cHb:&GWM X.nu3t.LX9~-a9)F.ߩq^[-O======s|R#SC ~y.z"ݒu%y i^gθ3EZ )c &QrVO(S2zЛGNX,X1*/d"+ypR }9pF]Sc)0TA֥0#^nxĬZmA kc$أӘxfSB)N݊[ԑӞKHQd5JJ3Fm" 5).r=wΐR1leqmSo:`EryLJLo^ö30(dChh&^$fF,E,>cBE+L͐ >IP`P^AO[w@ahxደ<غ5+Xzzzzzz6eJveתf!$jqA3`'5j-E_T-]Zxt܉'LxMoI_b?}55EXxt{F2Fz~!6Xa/usOR[ j/yBȡ/ezZćbUș`P'?hhd*iƘSzmV2Zxh4#sS0I0l9sP)31qOaub4,¶&t2GGGGGG` *8#!I8);ݲ,^s֯ǝnkr&bCRKpۦnV.it3vۗ=nw{ۺ+W z~{@PĴ&O:!Msק7~b#v~SF䪫aRWxQU$I׏ =4h •AEcHۖ#:$Z43" J#ƇD`izV@KZ\Ppcvm_@TNPJaY19{m.h@<V X?\>1Cɟ#fnoW,~ߗW_QnNz/ɪr+[jUd/TG2/_6k}䭥}eҽ^ 8h(lFD=@:g򙧦-{XJf.˩p&#Z4i=G HѬd<(Z/ <>X4vVe,L/mSsA dIT dq2 ngYCou\=xi*k>:x*z0{K0ӶLk+UN A<< ZC'to.op#|zֳ_zMuY>:XgC7 8GGGxc?v +#AoFxˮ,p D639ߜV|\7qobo8{Ye [xok+[rqqܧt>\]WM~ҵCUv¼69։^ urZCW +5{I2$WLfHu#P)M',p@R F] *+¯M䄣փhC qh1F ?_ԧve=,x3ʅ^8Cor'SN9e#&#pg;N>wܹvP~}s'`es)wrܶ\}~!S5_Ļ~ ֬]K$7uShtu,Bkn^PO$<~W;E* <'xb !J۹N< a^kļ*3kL($HRίZ%\0OԚ-ϨjENnpk@"\cxP} 4 vGp&rW9gtBm}V]ze̱aò;n5)0LbL òpok9o~(jyzv+/{\Lk9Ì_f(Av*o92-5fٷ(m\򕯤g>^uG!/;N9'~r;߹{MHOen )H u,~#)w]w朎u6~MϷxZ;8pZgo둏~\y]9QA=b}U]o% q 4ny[q[E,ł VF\E||yjT.RT6.ɮ~ԧbE8nLsp̘ԉ¦E7r;ܡ ze=hvi%]ғ>./_ 'Pc9vbw{{ń ڪ h :ԞުG \k8R8 ZՊz[ rKH=W$vs=은\{?Zk\}Zy~g}OOMoxޏȏLw??=OOʯLozӛBg?{?h$67|] aWj)`//z,m+6m/OŇ__>8,A[?F;%~ l(g>4}ڏ 3mqL o\v-gnӡ۽E4jv%x:xw@D!_×ft+B _&Z9 ޯYr Zx9P|*$P Нbs"~Y--BTXKaB @zo`DJ*HJQٰ8ZB)B&<B @dCVp<|-'HIJV 8>\ԚztFm$7L I8{ߣϗ_9zv1]pVCݿwz7񐌼mo3f[Yg5/^O}^6]~?}ɟoWYGϪ w~wO /<^uwo|#geqY lڔWl:=3xcw0BbOi?O~.Mv#<n1p1ӟԦƶ{':0tV9^/s=oz{t铞<:Krυ,hmvT{L-z (kYF iD[ UAsO3[Tt_VĖ+Ӓ[-ò g4@7E !MΎy)i9)J"ѴUN"@pJLv䘏WbPNh5=[VO"$*fq}zv)E}[bqR>}%JԧVVu(1Z?f;"p>&% Gs,1}+J>}Q*gQU_Q͕g}G]0G}utޮ=/VdY)9񤓧_u6oE;D/" P>j8'QmoUaeA:~A ijKOM`;n.vrLH+#X4pIN-}M)x~1K/+4N.q!>aJIۈMiDn҆*)!;%9/H4:V"k۴3%=PWËۨ0,=L/e?ltVQ1}^WqVK<^xi8c>GC>7wq΂ļ6*E>6 l̃60PRȷU}(T|Xu"ˤk-S]w:#.Fy~y1WH_+?]N't`ܑ?_w7׾Ӯ]Wӷ|˷7ϓϔ/e`Fas($C<oC^fgU7xKw}wM/˝`=O5yM uG#~䆱 я{ԅ~"dl|dž%rs- jpϭ|f)8"_4Wg Puq#oL_(Kd}_,P_"SlƐ K- k[KFy`2+_"iGyM&MFF78%&y_2>d\cRv}ZO\~VnrH`7dKB=m j' ys|N ^p(_I 9gKcQ9}Na\hxКo7s3l-_ex% p[.r|rݦ}v;+)WkoEmڴc: th$( "&`a߅@"2 ۭ܆8y`$qU#ٲV튋G F!i;Z/T&; 9#C{ <&BMMRSiDc -<(6w3!{=sPW1qn60WZK hYj^zn[N㻿GOxh<7mʗntQP}7s~+bz+^ᣔto7N/Ћu}wG>V MEyqӟٟL留îoӏ(ھ=A#cnM b/Fz>|``ޮMӮ<ӿۅ~wL|I!} #`O&G"#-|*|?wdH9XmYrTBI#V;OۗլWrDs5)qm@<_6V|vI&g:o[UGhDf䪫J[~O@G##PwIf֎vc1:{ |{~V~'2!Ex ՀHO}M9c+!ئ_u^P `<`?Cd*'rXG}8Q1L_K_ybեV\pwv-,b2mZC:hffjyG> B˵!5tqdv)XPT;|F}2!$0wr8T_VE?Bt:CqX8Ǯ[twO6+mKDQ|MD[iU]g@*p`/_:ӐDʀ>P٦/v%be5ݨ޺C,7d1(BhYr]'7Wx؎r$59؇Dū4M}2rƙEZIbtXsC."^_<;.+#鮕iIG̔bZ޽z" zr,[d7~Иjm+EhC||;۹t:V7灮^[]SLw[ jY߆,AJmPT]g|(T=9 daC:23L0( . +e)\ҪOb4D2TU@G#tF`/Ey f@;0 LōE7-ۮtm܇H,P兄U PJ}Cb.^VD%.ɥɂMTJ(|4E|0u1(}a 5RTl~IS "RdNTbܪlcC*QI|' $|ZW=HʼŸ'*(r uG#t:GLXmx>bQ~%[j(D$K` % dEՏ-~1) =YVe rMwRDq8? `C%W1 @͈j%@V'y)C]A* y#tY~lXx ݜXw楋ëZOR~R(7[G#t:GJ);j]wMQ]_{t^88R&8) !<P-@ЇOޠm,+;+?˿{!^Cl "eHe}qqjd1 (h|i ZX%'LV:}}pۼ cT}DcAKeJ <b*H&\s_!;q6A`6e>a`.;BNn a=5j#a8\ǜЇG5dc.j.i14"S.hM:IH .h9pb!IUYF楛K?, }Co5Vѥ#t:@G`D@+ 1YŽK (w'Am|VjGp_=6h&ۜ;V,^0@.)vطz8'˖+Kb]fSJ$\QWm =)%UcaqH;AI2>,#XP4 QVƋ5#AdRņVo(1m$TvH)#t:@G`kD`~ `0@["fR:)ۺXD}פ(.Eu8q pD>bRfUGB]flc+WY}^PA-WmWю ZX0ņ֬mfl˾Gp$ ?$X lbAFQ)U7ppE{X =nI֜ .@G#t:[$~ du awGoZ[" T!g5$,}F c*IBtU^gimYTua}ymSOj-}X2vC/j7sXgu$vu-.M)MDV>j3rv#t:# gWezË/s<"ǂɇgȖ^[ٚc [fږS t$nS{E W>2 gZni70D)ޞU)z}1BHDBD&pfۣ?) "bcA;(!aT)oڐ$bɥL,elTuXȑC F dG3,f@G#C>7pu~xq9sϝ{#Ck+B |Xx|p4ln$S,f^X;AU Zc#Yb3/؊D 0mdɴ˫ a(_$$jJ5&g:(qK#o WZZWՂ Rj+ ~H6UMJKDu$03h.@G#!W+wqO~|'?ey:u9w߽m:}CN=uti | J!„Ue$s c"$fI9]z{iwI^C%qe5/uA (>yg\i'0E 6H"K)wuT4b=D-އ?RWn,V/)c.\fR)zߜ=Kq;r|H?jL]:@G#8"֫{n9@>13:kzҎ/ӿ-x:P`iy245lQKR1p%Q,BG(}Dm_zEѐv!S=m]dkh˪6,o}GU+*{X#~}D) :y#ZObb9敟MSYj"y0-J>j,%aU.jQ)t:@Gg>؂ui;}i+G)'~޾6prKW@3lTS_*B+7,E{zeИqE2C 5ա_B8AqU^c~P ;1 ]zLoƼ0ƙYXН}QОEn ` _X` slh3P,uyH("VQʏ_% s]:@G#8"+ x=&?˚&  .f^8H1@i@. >"T/Q zI?|4F HvgtS?Y?>Nx5)5}ľu:@G#pDF@C?{s;; {t'O'qwDFX34Yf CSct2''#xYً)i  J^$ԃX,i%D^`8SʎI{B%@#4{a`4bؤ`2!uʰˡM-FBb*O|b fg #J®yYtAgZvcǞC˃^bL#!eX9,bay4mۍ@G#tMf~'aI c;4=N3~#.GO)Xc>&,]|Aȳk%cН41@EyMQT9'i؆j%¹G"T(k?d?zuDc}“]d(vxa;ؕ0 Lc7YFd ɣkl "]|_J eJ. NJ)<ʇ jRD{# :1Dd@x@^Akh ϛ,3,lͫa$vlhEͱT'6Ƶb G|ZQ)rx2SWI%UD mY2VJlj-GcՌﬤ*6D>FUă>bTtKvȸ%, 햃T͎Xo@G#Y/>iS{D>EēNs}#%+!~#O,l< `-񐏀: ^_*DBN~ʢ~V~Po dj;r &vMS# IDAT.;a;(eA5!B#4CbٞB\wRx>[!2=Vm8[y8ZpA B$@Ԯ'k %YV7#edgEG۬Ő0DYжloh!qPǂI%WH ,+saH\@G#t;oaJ>SRAb{;!Y'pt>4X$$$,$*ेR_\v;=< Ӊ'ۨù?WLlnڗ z zhjr_`ScR=Ӭ%\6""â MJa.6.k#܂nņ)ËY gAKQa2lQG^ S%I6xUppwqBe2frzQu:@G#pF aɦꚫ*Y{>{m^dx:U$1Ozl֓k;NL$k+??K;X)Nyço{wX]X֝l@v!s12*l [%/8“h h ՇQRL[<#SJopM?ƫ0زì&$a[6IJ]oqEb牑+ B…2FL}JjGRTp(~$0&!G[HAcLO`GIGN=XҺ;3o@G#iH;x]zNUBq'<>~\Kqs&;>yc {w3X{yq$q/VZvMǧ^8Yg VԢc^'r:n5Cl@aK 9@Q~TA#f H*iu_Um+g? !hԵ5ErAUqm/xqjX ,8`t+ثhx؉ЁmX*I.!saC~A&v%: ӥ#t:7wIVF8?uilb|N%K_ML:H\LK4vD=D9^5/ɐ.=lCGKϯ+c?"!VKx4O֪D:R&Wae9X̀W;ȕ k'PdbW5v%$d;T&=ڜ'%ZKgx̾u:@G#pE; p^===+vPv{%u޸~C 6W vzaX'$5 GqS-+Îq&!JB<=4c̓`7W$D2ɾD21Mw#t:#*{A9͡sjoSp΀Q8\Ns%j+7|NRNSqG.8;!̆PESt|&D(kϚvrT99t65F:A(Z!\`]uE"sZTm7%"ooiϛcXL|OcX:|˥ 8x,":}h !W^!@D}Hּ7RL;! U !>sDaKvL?MKr~v}=vVt:@G#p"pk~~ :w/? .)JT<ִSۣt[oy$_x`<&w;ɇ0 fw0?jU <_H b]0TMW=:޻a)Y$%d{GC73=d^D67@6mYᤄ:d=>hcbJ6]quMܓ|B@G#VIzx0/'-Bv˭pFo_wtj+!eq.4G gn)A7_DoC;O?c.N:[o11xصLd[_9ݭ,fr?񤓧_m⹙w_]6 HDD v2n0S8ʁB_Ue듗{٘dOP \C` ilH7Snz,yAԄY2$Aw|~XU]pt)e!Dl1sД0ļՎKڳꚢXʇ#Id%ř+<<"Dze;-y~v#t:?HF[/KڒwYf1&ZXO>唉"`6xqǽꟶs|BO=9 @_w7L_v9Q!Ɗm:oRbr.+j!J˟/Df#]J*oqS٥+uXPS 3` R*ɃĖe?ltiP^&Zv~7<խ&uBnZ1DwK_TKBuǗ2vEK/Ty'>2_P˙3 w7;wIRah`?5``Hզ˅H+&H1-)G44 1g;cvË1;@G#pF@)0pg=R65NbD}V(<=|FL{+:o8r̯gNg~ۍ7\D=+aA/Ta+P)2vw@Zb3vtdK461}d#V@`VS>"s75>r in#) 21Ͻ<KX씏2aszL4Yb]`iI"hDqj!?ڊw~h$Hto6u`t@G#tA/۩Gn*{6u&,^tt-'p{:%~xؐ>1cځM\ ЉņayHuY%[JA(DuǞp%iZt 6 a.&aa<}]$MfYIfFQ+NBL?!HvނU ?=F!cNôYK,FmMKمoԐ~:eta1K9a4x9ɇ'_1t Q!s=sZ}t:@GD3:pWMjcf~gL<\ *x0}kt;|r6|E dS6 Pj?^!_wd(ª @ې$Ӎf+Y Yp_W:,;eWq 'xƷzs8@11n-1i*HdPgDRa*3}ŀ1͏ąb0t-Eh  y9 )kb{ɘdM$d@G#<)sww9{ 7Lg~ӥ_{7fϼV p^:xqmpC 9[ݧҙSIнkM~G @ F8X+߯D=z| l G!;~8  ǍM! {Ztn)~k ݫ M Ѯv ؗ]hN>2)?XKKSWܯ$āȊRϑ`uLPD&(#t:_M'Mgqut@C,dN,C'>;`lVU?W_|Um:?t$S~,*JR@%=G>Ÿ7AC0Q7߄nN@g!t铝Qf0\"K'3]pyVQ!YDBџS3StIVl'Mz"vt:%/X=]Mq+x! \A\ !@*Hj{:_a` ~M7Pt-y"Xh? ` R+ E-Tlh%Ϯ fHUa`HZQ9i#JdjlL$20ʦel,(JQVgJ"|PvE08ڟ*3?F>0jp B ut:8ss8]@ gBOswuthE90g┸O<ԟ;mHDP%o]B{޹-RsZQ&|Ag4ɣO ^@O5glCl-G'ON;_jUP>! Jb/CcvM!GYH JȑśHLҚxğ.@G#<rw}~a)>^o?Wۻ>'n<|fK'ûI8> e5*0k`XluKG Qހ>3̔Ͽҏ*^=(lqcmeUdi'$dǩ$5G|{dC:x^?PߢP |[вyvģɂjD#RIK'2؁83G䰅^xg@%@G#t){ +{~:ؽOLu<}{ V'xtGrˡEmW'k鉗>iyz׽xI :7.g.*uSSSzuޥ$0vt(-Y!)H *a='!݋ ~&(n÷EN#i"2C~nݠG*{vj;p8n$YpBV_{4Kx䚧x[&47=7[O4nvoF?қt:"pNxM~7wmlBg|Yo3CgynDA~+&D@+ E:J[ h€{tߡYK;?x.cCH %=i!ĊylVB %fKۯ_$+)UoiP'ąnA rheff:Jb"T,1t$:a 88TqRg$[]Ab؄e[m3V;@G#0"p/G[t7ނe,EWo Jc8& ѥ bGgAR ٷ+)B(kl?eFQK0deXK DK8FIDu)^zpPK=Y"NXDG11_y#F4M-ȖKfXW"jCpJi(1/?Ko;'AD~{lYWe£%ڴ? U3ut:@G#*P"p V]VqmdfBFR_YYP{@d+!b^~tB 4܄Kp(.V/Sۚ%^A;}V=x1:޽C43[ij؍ArUPKVWiŃ`p#.itV|Frs F4UMBUL4s8RE,T H`KG#t:@B,\p _|Sh$mAO(mC IDAT (۶vڡllzsqd{kaؗP)? Cp6PEkY @ Zp@߉zA++q+@;% st,zՆR>SH<}CKG#t: *Vq;QG!nn~$&,[u`՜q_۪,Lx_2 &i*Y:W`ZPND׶*#hh#qc6-M(%܇K+&fH p]ۍ';"#e1BHBvMÃRXWrR.H0yH)g98).JxVH%'hR$2TVCc,+\]:@G#tR"B*e@XANPmBH5YT<5bfn{n:qLkZQ2mڣkMQ ٮU:29JN[aQ"A[cKG#t:VW@ u+mi(p)\3Hd9w<§NdK,A. 9VBEl2[8E=E SI۲"zcڪUɞXo*u5t>*ums:Kc,IJD{5"A˻M2C^^|C_NW$$>A$2|q D )t:@G#U"[ &NLD@E.%KސpMѴUC|1j95\guUH6UɄ%10..zBՑcX" fqn %=14' Wdf.T/V٘DsQp<L_z!٬ZN}J4A?$a) 摀F\9$C<1ץ#t:@G`D@ j17-$n3DC6(7)V> `bi bv ׀6G:Uƴ˷G$onX ˇBٜF c#'D/RBM\ġQ1uD*%eJ" 5Tp-62R(`V"J1Ҿ"ꡃl *;ĚZ\@G#t:-5 _0w Er`ug,kWg%l^MHt"cZв5pI4&YWIWPDs)qćz m H@s l{}/h%"})0JԽƎ!^(]= DR$g~_f k[+Un'n1۞ƑM%sXt:@G#"! AOx RYŧ >rxfe]/4J.$EPӖ4?J_=)(Hxop=T]+9»JWŎAVX9,cacNTh:v|`bVhlC6jJF$$ e:%DIeX˶*vG#t:<L ]j`<B^Pm 0ݑ ;h] k;W' }i@AYT YC~u2w}Dݰӳ8isbh=έ?K0P T :ĤA0-e F<Ƕ}Τ{^)OJv޶$,4t:@G#E" HH(o"!K'#(edklbk7T"/(`.c:ҬxNi?a?Ƣ@`+Kl`E TFctiYh47 QÌ^t*q(lt3Ҍ[hይhqaH=[g3oUx4t:@G#la 'P6`c!54-q{=X%PJ#Y+.ę s@bQ}]E Pme)sqv$%2*М :nl왭IdW;䥕a<\؛M0 JL;@nAfliSG۰xִ]+!zY$Xדl" ΊfQI~W@G#t:Gmr $h.&T#G%l.d։eT A+ua*kťR&,bٶɍyg.Rha ~YOkX`cX?L[NqB,kD[݅b㡆JIR+ZfxN 7kǘ؈C΁@ ]"\R'ݮr>DBIb;x2 h|0*c;:r*DlOR ESZEl-xlV=P"B͘u k1Mt:@G#8j# N00۫^B<x $F)a<\m/`\N& ~ תˡr([ᇆGI#-K4p jx02X15̰ZXP.~EIQmh,H*1XIAB*ăCB'65VV߷@G#t:-x g\8soC.f 78J&hY!.*_S^GYc.?X΂֓` :sf8Dsa蹲 Y/)9EB!qz-b¥쨳B~,XUb3cZdĊ\Y~J@G#t:>"B`|Hj,ٚZPj( "tB!Xm0^eqt"apsV܉%Ɂ;g@fH#Eຨ2k3xmـ #[߫!$-=L%}K7~؄cI刎 $]mw1招.JO,T2r{ɇ w:@G#XB_҈`%QĔ D oZakwz Z43/C6.TmĺꡓYc@y"kZJQU# fQe01!EJsHg0/Ó򧴃Uc̼JRUx`:b .S"nKa@G#t:GyV ,jiԫ.M΅N֦tbDgUr,E p]{8GeEOvΦ|L:B'.l|33zCJ߄☎$#05K@>Dd=IeF4T+M(^GDb1r3bJv䋘/S{G#t:V$`fwxG梯ڻMv=Ȉpb>C 'uW٨!ȩo30IZ@5-0wE>;ESMa*]n iȏUP8 ax V(G&7iCP2D05KJ';>tG_+euPLNp:~wRB\8owv:@G#8#n Cei`_R P%lC^Y~(1\^_$3 N`>% hN}aT f̌;\ 6@Npe[s\WX DsPE#6P\'9jθW!%B6VGhč5녾ic}$c]mmUZS{mtho: 9?[G#t:Pt˄Ig~Xh1[0U+%K0o}M2dV^Zm\Zr-3xO= }I4F]1: ٨̄ZRQfVNtD5uMd]x!E}GjH=&P;t9V\<ӎ5=X1kU$#ەRbBm};)@ݝlϹt:#lAF'8>#zG:) ` K5{+X8EV@tK6J Cf4J:|{1~N]vNOIO˦=BcVt:@G"}?L@ %.0OjZWR}P0j3JVjqrh}RK>94acc%.֍Z̋7N0ڱ}'Q*VT;^\Irfp!&+:l jR]G Þ+q%;T}vK.lzI ky7Pn/뮛7Mx_M?ڶk= ? =dO??8t:@G7^ƹېڒ 'X q=T @v]"`(:ȱ~chQj~N~ldJp Irn9l{+7I21n䮮zdDל-&t[.3}搉+|T|lJ T#aS(EtH&!Їjz^??]s5G}^WL_|W=N.g?h 7vmCO^~7:@G#덀&(0A'day_ڿ_g**)6d ]K>2ap$|NL̖lRZlW+7gBɇY mH^هmk׶$Ĉ$Fu]I1ӫ_!v_~wsϛFٽ{/}tV쳧n喡w}Muӏ{b܃9gϞ~קK '?}Kozն-c{9g^b\oc/uɖ-:Ą^*1b?azӛ\&t:@G _ & }E#x Fg#b/奒2{sߝ8_ftbRoBB9UmR@\'hi1yڴdu;D&#䝰(1/+q"vD34SxSUbZwb§h?KDv`q3ϑĊ䃶>/I H;&,>ƼbIȋ_򒉧cڵfwD/z/8No|^ot5WO|+ _7~7pN<|~: IDATvG{>9'>鍿8|{_^WM׽nc=Otu?;}{z}z=9xSE#j[|iwճPP%}w9D?_W ysz^6}ꓟ~~މ .@G#<B ^u@.ʄԦ UfV6ÇU}|FT v@ꌹM^ޖ қ)KhO/cqP,H"|z]±C|M<1j@U[1U?V ę/vDWf&3k}0!NFt u|N|h1Xv̬uF"fw Bf oM'p!//tă<>&\jzֳ5vie_uҼ>9ކ}V N:i?&;ww?X ˉӳl?4Ot袋s9{}w7_jO_Ogku՚WӯNs(kߛu4{*z忚?˟C_Los\[CmS[?SNzt:@G`M4A*  f<^Dӡd==OwY,XA1,4߂fCbhz `Ɂ {C`gLp;3JJĘ+g'7*8\.q{XpGׅF8Bf!FLwŜ3МPhSVO}5~l-y 壼I"H}?g[.+:< ?1ݠՂ']z Ox$9{mmG{__N|ϴ[/yVl93MR믟.꺽Sε,ކ)MB^pc}y7=NMG?z_o[ou"q 6oi7;IgR^7hk?w? ۆ^7:@G#8 \Z7A)}y+$rAyDɍYaP? :r,"xq?X _۫!Y?+y\}ٸ7 ]9Mgc+4^N~klȟ}Ā.o ΁Dq,~P3{L#" |8;L~}^(ce+ǭ1qv[xi{#!*7wBZ[nq%/{pϮ{d aJB a(DdDQEvVGG}QSgA&B@Q1!$IB%T{ZksoTk{{{Իs w8ܐwj=__{k`}<ͷַ?y2{0'}_9mSO__UӀ?nsa~z8ӧ\0q1G<.f\Eݭ8W ?0O}mxfAg3 t:2 |ɧuL??"M .t/d$Lǎd NӞmbMfmv,In}'Ksl繎R?H;KS0[KB+^NyO:'ypt3Q>,|iGdsEKP94l(mY3L灺~i_n,ÃLQGŭPEq w[OmpOO_{ίV=otv̟q778:ev7xOR7/?SǓ0<'k.t>U%o>``Qˏ5 {*t*sThFA ]Txa(S=xJ Sa_|DKcCցwMlCE"]+^㻟=3^;o1u?E DBƟC7F~.;:DDzϫ[ 0 #c4B.bC *:f%ʙ8ɡ|%Cl洼( p=^R =ɑ Ab'ђew^k@W:'*DB4=egc}Sn@g3 tkt L8 zn24 n &Ʀ7S'͓d}P8@,]ng boqcbpV@ea!(r^q`hjN :Q8==X<|7"kJQE c4+t&~P;.SuΉⴰ9E&./ 3r_ôs>w`\@g3 t:[#FNj HGiz/6 nx[l{wxMAy{VOr P .[#vuĭWiw_^E ߌnJ>ֺPհ'S@SJo('A$t2K'YщG:Rfą`Q`H.d܅盷@g3 t:!Zq"73 JHjO-Q . #H{d#4 앝īGW"QgMݧ#jvJo bnzLl0(ff*xjCp@ik2KO}h*[`K[X-*E܂,S ;:V2Dr3#!<߭3 t:@g`ke nkQ 9]|L8T~CҲ@8wg<+c#xF:U -`*6ƭ>$IermѢ3v4XƆΔ[<#R)Il(VsOjI՛nO 'IAhLa$&s}CN`K:zS'R]=DW ʆ(˛{ t:@g3pg`ذ3B,TKoIA3?7]B-] Kvm6ũE8keH?F7>(p!Ь>x. ɻLy\de#IɩX]GVXЫ a4 .QYh Rеń^ڴ4\iZv,ǸQr [,^0V:֚= t:@g383g@ ,)ѥ+Pg|JK$}/RV5$Ů* zw7@Pc$B?:bBaۥ-kip8Ɂ ? 'BY8v0-xY*ShZ'ffLt^0ɋ 4;sHh-+Ph6(ӲՅTfe9R©HFx.'d#4|M̳[^w^ztЃ@g3 t:-| bLHj@3\u~C|gU:}Kd.(B`@7;-د(1vu7~}"Ul,Üo{+ p9 )KS)gpy䉳SI>Z͠`#\!z"WtTfv-nҔq#Kb^*ʤ&٤5Ʊ2~Q(o 9kWZ26כ:@g3 tFt tE,D VbF7lee VHM6*Sб}H(6;'gU`a(vB]nWv`hla,]X33gAU%)xAHrk$8>I(U@klzCty)%173sXF*|/ܠ2EۊxLK?}QЛ2Ä>u:@g3 l ̷`7f+ |Y,:y7r"^:g3t薢x,[I1ZK^`W9(Wm@.[Uhs(eyQ@FA',zҏۜ`bX  :6 ^B߾Jʑ3[a}xvŻbG(x ;!싰!+).MU8"Od51O@g3 t:[&,@#k Q'5mS!k.@x X7E8fr~Un*9zʘ;:זcw%lrKLъVszUʓ|`(gSCZ W~T8C!\Ӊ|'b=d x)(rHcu~Ħ=Iѷݩ0s!}g3 t:ȀBg \dԧ %rH @$K)i1\,̀C& ~)")ENvlBi<$E <\X>Bs9K? #\,@buB4wfad4X0Ά+9?IӪdpL!?ԕ1C+(.u:@g3 l hdi.6@4:&Ʀ'4?gaҜGA8ElX!Q\DC_@k& |#wU(KEle qzTi2UyFӘy$1/T0l rj@ j),!ەNPF ֢w<"AI~Cy-Mrţ'Rsu:@g3 l Df Xpp`ucɐ!Gひ=gvtз =n~Ϋh7nhEQ -=xz`ʳ}#qODQcYKҍ%0fdas0SɤHCS8F"(Sp܊ +䎂oF,0RJ˵ Ea8p2Wj!hVR@g3 t:-O K@*:eF2xU,!O$]dJ(Ep֣ @.۰Fhmi: Cg- $SXSZY `'ljُO"WKh歅"$1>$0 zN-ܪZ`ǣc [&t+݂EXkdO7ҶBhs)ij1Qzk >T~V&7¾c܋/x餞qlCV.Y첛d1NjЪ5Їf0^GX2[g3 t:VȀv@%&d6伆1HxS zUZa~mk?DB7G7"bki%mbJrkC<|1&;YWbwV\0gS7`"Ѕ|en1Ͼ$4mmWTt+k=+TzaVK[}\xP DPʒJƒ}Y< ?b4|@g3 t:[" 0`2! ~4}G2K KS?d\{`7]^ؠL*VCŃ<3'0>pCКZ[tr5:0$ 22 !b/YYaȡsM6CtaL_ 9'&`$Q.JזɃh 0PBB拪qm2f٩۱! t:@g3%2/"耑,̍G]6h(Kj=Q/&_ jqYHM'` mÆ Ǧ/*~kyEJd/HI.pʿGta8_ z_mlS@g3 t:!‡ =7XP glxAH*CA::ŭ:ea^. 5IHm̓Xʴn2`_3web$B>fNso]s%!@)a߹F\tH6-&eb HO,c[\Q_<#zm[DCԤQBf~ ׎LAg3 t:`C' 7QCiV0@Sh34U'>NX C~ 6ez L}l-0&s٧@g3 t:;q hH~9 #nZGJ NÖ'@UG%b1T8a[eX;\B:czQAky99 /($aP/'EN62>5Dl-HdETrR0_(Ճ@g3 t::Y%8]M+<o ! nv3'A:hűT\h%G_GSiE]ų(.}abƞ  ūa8+J.51ѥ&.<$T}`6!gy C]74gweXT~.Zf1}hZ9Q,la12Hϝ@g3 tR@5ԛ/i ss:\vt.XZ]NHd* #x=sǕwJu)pظl3%ܡfQtۋREGjw lˆ'ؽ+!dQHnBχ۞xփsDa9|veb%keNj}aA\X\:@g3 t 3 diY-a\PѴ>hS#WL|€!(D!eaHmsV6{(˱2sx`gZ cSo۱3w=v+{+;OF@x.s%G!v![QP8v):o3U.Q!hÿ`Lmkc2q~.KنK($K.պ t:@g383  $ 2獺qݨ1O^z1_LTQ]0|/D,C 'ƥhO= ζfYso\| Z 9Xla Ɓ-T|;1uRL,̱t‘&z Zcvl0<㛹mVLc-EDUz>-4=*sM!I|48X} t:@g3:CBC4@4Α)Z^UW8^CpXwf(Cge%C1O"U`ǯ3Ary O+k .BĞ9(hΆ)@kCEv|lSpPXF#i*"k4ę!ۏr'2oEH Zi2ZM"F8Ag\#u:@g3 l pH$/V +[l|y|KF:O͵s $Hlp閤5@3"K.[ylxu`^E =tPoS9ez y|dŚ];Z$|wÇ`M"*}͒tM(:(^GzlϝUH-siTvKz, ]߹U=8:Q/vsf3 t:@g`d``  fݵo@ײ)0 j,;fUҡ`q`41Ĝ`iۓh3]*@Cs/qe-B`e\)l1 Hm*S$ 5$Ѽn+*(nڵLzq@E .:ЭW~]6y.5 XLҽ*EИT":ku#n@g3 t:}yXOr-&ѝz*ІV.NR=ohm_!at=9] A=.;c:3YPFHg (f\ NЍ*EN$ȫ8ȷZ-WUb鎬UBHj .)*tsPr!<`x~jIZ(Vzr/| =w:@g33|K0ѵv0݌@@a!gSY!ϖ4y6Vﺘ1@ZcnAQ?!g*#a#ȦnM\XÀ7t]Y ]7NFڱ@ I)[:,iqh>I޾˩)ɵOYLڈ x淸Ÿэn^:@g3 \ܹs|__Ǒ74 P@l܇nah2& UBjĜOK~ڠDN/Ŧ+~oܙ(z̙qe08P!p:7mdPt%ﵡ0 v01VB]tc[d}6^5&^t7 ŷ%gA`TivA|dDĀ("t]wqNGyֽaux3 t:}3wc|}sYk9chǬBFȂN߲iCYSռ91\$H325_R4Do zJj%MX'z ZF>k*vόҿV0I~ 6h{Bݏk` *B>X;2G͸-T>V%bO*c`TebǃTd;"· ь[x."ks;lud}?}{ƥDT^u@g3 t )8fBe$&pY`25v?L(&ڎO1r|S?? Zۿɛv!9ӈ=hDĕZXfLVull.!ó M)"ഗ?I27XKؑxCgmiU֗ ;z>3$TlFᒽߊe{L=Hd"/\Rc;pH%0^|ڶz-"UD–ZG3 t:@g`Kd`~: sPSr.fXۀ!d a#-!1fL×\bNZpg~oײlGl%iBcVXUA 3a Z 㢂84#)4(Nԫһ`Az#<*V3WʘĤ0Ed8Stpe4'gTpѐ)h +n.Sg3 t::Ǜ-!0R)]ܓī[S,33WF ,;hju לO|!j|kH"^<$z2,FC В'MpɐO]p S y?tlQ}ڱ 2#Eպk$>L]jwB''"HˎΖ(C2ps@g3 t:MEid\ b\fŠ8R}n+E<ևCL;l H 1*ay,Dʊd3XW1[L'1qo:y Ct\$hH>reCz:v(@|KVʦh!^TK8S6rAR2};:3{P*D!b*I:@g3 tDVπzF jW&M,R 2SʅtxtfRaN<L^ز3 Dܗtn..W&|d\.p4ohU)T!F`ӧؖX݊`D1Dmf(Dۆ!<{ƘKD0Xsſvv]#<'Ӱ3ύW9"v t:@g32PM\8"l!l҂M4;qdCcl{~'7`aISC ڦi+dKܜlG9B]ѰK+_М7P< EWߪU1۰,߄r ua< \ DWMY9R+L*:n?5—8E9/.u t:@g3%2ώF@HW-4Aliv)͟k7iCxdҵGW쑓}3 ƍ jEH;$jt/mn jLXc_~o+CXȢla a$P 'V J*<6$C#b^):;׌V~|8(HH4:~ iMt v@ơ-ҧ{jG'~]z\:6Lm5"膅MXI˅v t:>exqr)v>[K /87;NlOdO2W콷@@ Vm+#83pOdi:' ]*1_\gJ')ǔ5&1 ѝ2DNVL]e 2kA &Rg,́)R[ns \/ȫY uǝa)N2E [8׵S#W23t4:GZ-[A"L9Z9G[g3 tCo8!W;wT| z,ږD[+RRLN2 s,L2KB4v0 n J+07 xsCOK38e+|WB@Z[0l#=%P KoZSy_ ?`9z2ƛߔ:Um(>,ZYA9L!9/ۨ"ŷ>rļ t{ 2 f[JXhw*B1:UyVx iSg3 \'\'n3di9z]Ps 04+/P '#зLaj`fp5Z&aB˚አ07L 'm]$Ln ŹACۛeAY6?Zox4)e X ^ t>ćNAbVByu=fk.<*B%i۴:^tDt t: g;_ƿcc'tqM /w/{q׻}^7ׯ'i|pC!EУcsghhhӯA,8֣Ђ 9~pZМ/d-+=@4z\ɳ/,9y6*AWv0yDD/;g_t ۴}H5Z 5*oE6BȽ44US,O<ăeeSAu t:|q^;n'o9~%yj{;Q:z|ۣ}Nw|虔Knݰ@́mR1HrCc]/'27X%L7xMzd)l -Xʣ}gb҅=، Yg,2ָ+ZR\"{?^=y߹qmYx%E69~|_G{IGK^OmG}^7 EhƆ'B[@&gP.è׭X u)MKSfaC["uOzq$,cY@8KlN"WR3['٩<i3L95,ɧ@|OҤr[tk88Ni`5u Ge3Jyp]O4mXgE8Y!mv t:P^sN)>o~8Cg?{ء^/=<6?ߕe&ŭQG~1zxx~۸oqe!4o?e`NO$}<$ ^Y(>7G!vӾc響d\yR9'cK$p?-2n2 hA9N,BO;ii[4i3$kz~e/~%X9ڜ> ؛ި$$Fg::K˵-j YLPPiC&: 0kbt]4V1 >ePV]j ^b+w t:k(nz_=-꛿붫~#o>{<7;frͻխno')dzqꩧur5kz|MtG>f_xN۰֗#Bӿk`|O-w:kk"kr|}mwHP>q<0e';gUԩ';GZ m$xw'C\z6ٖn@3yMGG=%+p+ڍ/3rY`U!#v%YNlQC\pVs@+D#%-1t t: 4y+U|qӛt|Oޯݓ'>*fs&G_vt77'?qysN˼/7+]6> v1:կ~mNQ華@i@뱖>͆C9Ƅ~}X&8XFCU~$,Rx>'{*+3MZ8"~UQϛLrk.!.,ؽ 4"܇Ϝl5}^p %e@w"5/b`<;,ҍ?&q kaC3 t:T>ό}+ÿ[U|>w>>x>q|?;N8v{}o?y뛽7MwNw8v}s[.g=kq>O~>G//׽u{x=Cn?S?e9,_;u n3'qw=E x8ǝ>^ڿ١nxOvu;Ǘewַפ=o_xӟBG笳β??h9LW֩lU{7~ww|CnHG Ia V5 1/O5\Ɩ`kL!A<>T85ZZ@@0sȮ=Xqync!vĆ\8]hcƐSc,iVcⱬ!#?E2,W'FR1f29I۵uՀV dZD[⬖OI\W`/BЋ>w:@gtָۮ.}o}x7>h\߸4Ϗfݦ{=z~쭏wo~swӝf wz|[-Ex7.wq# g~fx _8Jwpr U`[VGkO<鷸-tC|;֍otqo<.Epw _WX:{?K_'v0Q<Ox\E?K.q!r)x'ʮf\<9uBnH Ya`fiL= pd"Ҕ~E{rTjZE<MME H㒙HB7x re+\ %n!Y>_$^4"d/ bZP4'h!9^$Zbl˞B~O/DxFL9J:} t:|T{_|ka5Gqq0 3e%4;0!m±q '/}?Oxo>^iw2}s,x;Ļ9~w~o`7Vнf/}K~x6o{ |ç{|_E}]=&Gsƭnyq;e5FE!>o |?`uv@?즖8Oz뜯@ڵK3r9ah9=竾.09 6^׌׿u >Wl~-=w]-[ r^ ـEdUIz.2GPZb:z&$b69S~Y;ML V/aQgӠgcV2 US(L`3.dǨYԣHlw|zDcI O%@=cUQb_K\,)ÀFDAV ; t:qӛ^=tb?s}D|=t~?3ϽNp%/;^wo7.p;AW#s?>O ~Է<7G}ѲѴg/=OOOO/y؝ξ^=&w=tG+^K xM_/tڹkU?Oy!׳ .`o^۰-fXKowb\|`\p\WNK=te/}{WW?A㵯}-[t 7ۼmn3_eF]zC]kZ.z툨9@4?f%,HqVz9NS]ԅ]eOpK2f161ư᥈9g,kҼZ2YZ ݬ.9hfsAЇ&)r!r&u%B&sF aOeZ&/1u`W'yy;lVK8$b]ךV3 t:7{u1W>bo^:|nmw} y}7ȷÿ׸zyx/xz\zDw qX6@\2~?<9~| zqXaz.ov>^98|ׅ^0^W3=~ewXmldcQF%Rl$*TwI"z(a&8G f^Iģ(Bza0+j2eɃeco NG9D֫tq^Cu t:AF`qbo:|W\D?_6xP?v|Bf7WפO~_WY] IoB\aDu St ø6Gƅ Җ-!Sg3 tc5A_R7h_zge;xqΛߢ7.js1>;vGy~\ ո&;~=Iw=ɯ?l۶_p2! |bǩcFKҪaJ.( y8Nښ˶8<|`!ݾ4Yޒ@62x HI֠nv#VU| 7—b4`Ґ$W&o}u:@g`gޭAZݛ۵N/~~_ y*o#\ z~u:wvE(:׫`/3OXqD!Ҁ@SZ$5.%eYc8_A*rA _9.Eb"&tFMM^ |\x!+]O\ޱ(>4ڽm ˴穫5Yg+c`qU2!`iUe,L{jrU)Qx:@g3pd@]EWj׆ϯGIqwg0 h$sPaw]-%ȒgJ;H)bzi gUaFP$B9r=axU+[tV!+DM0yzhK[ͰКJi+T3"cӪq=74 ڸ[|, ˤ̘tO9Xz t:}b`dz}5\%w\'jEŽ6TŐ(BS"gՋel;!~³lJhb!p# adJ@ģX(hHЇD!^[/tkIJ3)u#ybyMcZf* "aP1}rj/Vhƀ?h[b5,@g3 \Y~c{~zZw[o>k}M._{#do|l #N`TGp`JF9C"D8No~]E-]MU~Y(BWgO=)yB~=.ZPIh%gj>eE+<3 t:joѡ2}[\rȡ7KN?6}[=u/K>8_zUkrU'պ&qϕ:0s6v]ࡎhQ47˫w)|oTҲ)NTu^P4kɚCgຼ oH9j#0 HoVhrPޓljjdTQ4ca-+َ">D7ߧͦck@%`_lJfj:@g3pd`m=yz۸ӟkZg[(]{V!75Tչ&{h:9qA460f 44Уt"O72bXB!g(us|$"8}?#!;4a*{؉!w>t4h3.BZ h>DP#(>ͣiL0dgD$wU:"(uND_1֮;)+v:@g`f[w`}Aeu_N|_9g&79dVdҵWzM>ko,¢P&̜'`P5 1m 8Q'a '?JqG@(z.(_U/ښWE :<ʟ YDI{]d)I)Y'm3uG~2lU,1F$JsiEږ6,1}O9r}˷$`4ΒF#FM]zi(DGs 9%&y J(n:GXI.B C_kUtYݚEȆt,uX'+m$y_|VJ:@g3 tBBB5 qU)On*<┅(TJ I?䮁A%aAfqљ-J !f^biaa=PZWW! ("!ATd48E$Ͳ6 %Ns&!94ȁE@ dg aY(Q AU`$Dd"3޺|@|U_UޮnϮxjH9J2[ֵYzǗ !Lł5Q0> "1]?'tm\@ Y@<94Feu 1fH.'d 4myDy(yaɻqXlD`F|6"viK.HPJ@:sxgEV`% 7_xx65]]BA lG%UHfMDR! -"N.sPG)2@y ¸IKb@@ 3 Gn2&E7ƃlyϚfsR$ O #Uťe&oP} nH[,n/hQ9ԁq K3ET&KK]AcrQ@:K#-H$@tet%gJtY9FB1 @@F ~-͙ck]7'u#'쉊Tity5ȝphx#ygud1ոI S'F3-ϱxDI;}700$̨꨾(*(CkP؄XƉ&R0وcf[H4hjgFG4eO(f x2p! IsbE#Q=@ XşZ[Dr%u1iPP5`y֊^F첂¢$bHrA^kSfE(aLD|&j"c_鏶f,G.elBKA/35d/AӴ5i\a,pJ`itϨQm[őDb NU h'';l%{(Æډ`J7UX!@@ O=CdeIU\Z9ց]Say1Cfm՞8۱,&EV6ڜfFDԎ0!8miTlJ$M ^۔1q&M.cj,okUed%ef2s '@@19QMEʊ.AV{FБ)vs.?8W%\E'l@@ N-wɁ8coS\HgT}8gTT ) [$L81_2.f9~XsߕY  KBG}Ƞ8&%BH$5H%"`M*e -*ZLxD~1Oiz%c}W:JhtAtYG[#y؃ۄYŌn͢.g @@ 3p}0q!*:ijK5Xh$ Wύz=Z, 1`FTt ["(h7i>AsIBսۢDV>j6Ei Q"qĿ1QpMн~fYMBx瓭w~2:HQ')KP @@ 8+`Ls|ZiN"" 8QeV*FjE2#|y{tɞpN)_UqVܰFs{i=g%yJ"gt!&rVpm2ie,'SR. zffj-. ,n|Xfڱ֊$*@@ gw@1WQVIH#^0lfl )F9gxdUoZmή l8X] Lvl@ @d\JPd(gɔE_P"G`a Ĺ0kP:93ֱ0@#ai" k`xVQ/St#D&+R)I tXܬ:M HhwB/2CFA9GmHmVâ]򒈫)1 52.:u4B4N@@ HGTyfC]I縛S Ms͡W:Hz. V;IW]X,#n0IX\ڈ8o$Pq$ r':jيq},2?W y&*Ib AK#JlZu]YC(tMA\ {gV-4ހ 3L#c4 K~ha@@ p6!̀H?Aų%|24CgL  ot XhjNنn| ߰~stC69+6AeK>]xq{aÉ\,a[u#1Y]) ҬԱKOuUsV* j )n 4%%]:]1,jфQ b(@@ $BgQ׾DGF$gD- 3c*Yt#qy5"D<hu@h#i-rdq(Tyc 1ΫM#X;SJ28QÐw|XլǑY@[[xX:;g~ˊ:iQfAۡuZfIFclي4eG1~@@   2J٧ԻO)htNlqlF#i$;$0K YLթ tZ _tB !*S]q TC\~{Ь%{\Е!U"+?ЭE +`gt;BbVBu|=ЊkRl  8@J ]qdI.QP':u'); pNvr9I2ޛHDbhyqyqZ Clasط:ā6%B(j[#v $sԥ,( fIbc 2In cz;:+'DɚYJ-ŌFYbxd:gy+G8z!@@ =n^=;eөf&IP qw bq1Սi\%T D-[K[ IDATN|8͑uAևm #\df<,y{p5粶o'&4Q\ǿɺ%A@VfukGRR22=+Z=0#{"x>ʇm@ @"3Υ8 |hfy|߮q}U* OIpUs%'SK75FP[BJНeG7B'ewhFU%TS\6v=h<ʞ]jOjĒJGE!IӏۀzڜAV=kذ3gJpVv@@ %$v}}I: ƜAk_U,穆l@ م Cy݊KidI4ӗ5Xh\"uP082 -!0bvR6{ႊ8gZ)*![`/y'`oҚQs Ë;0/Gac /Jim( I$8k" l)qL#xRZ!R@ Y@wE%TTpc ȉuЍ748oQ˘+CG`W]̈tMUe^!$@{5wei+{(Dz'MYN@G2H-Z)"E38pŦlTwHl me%hV®R2 *A҈`#NZrcvNȩ5x@@ p!нw ;;.-ڊL(%ᄀ$Oe=J֠Et쮻s.KUf(3,Ԩk{Ek"vJ@DxΉwFq 5 Ȑ(8-i2R6gC:k5J?L ZBJm@ @Τ(L2t#F(ֹ RQ2 8ڼIw9Vx-9-HmWy&54霭 ̀@@ 3Z8ûw:#ûN慶@@ t2Pp'~i/3o߿?+;ћX"J9rdT3]aӷ'OR=W o~ S)tq:<8Ha8@@ /H{gn̘14kLE03nX Bڿ6кfje@zjz:l7 g?M6ѪUyih:wބ_OwfBݺunAHcEw͢Q|lٲ&L@}-@+)ovw#8@&$I)*7tuIph3P9غm?'I1BF/~1㐙p\.L)/[hM?UMGJ0p$qk[H~FT⑽hk}iaTf ;L}rU-Ѵq辧NOØmc̆ڳ8<,J]IM~vV{|Ncg#G#/iȐ!TQQ!|k[[=cPh mS.ٳgӊ+蓟dQ8",s䗿%[4bĈ_?Ŗ}jD9,_.AHΊO1ӂ׮]+rx>.<@VZa޼yiNgYL KGZnXDCg5mC{'?gE٧UhgUtMjM#--85*nK7 j&л6Щ:TIZٿ_L(j<1޳f NUF(U]?<'^2~q,yѦ${ FrLdw8a6+ڒ/4l9d]i\:ԝ8NzJ;O.=~`*мUߌU%/4' : FX`7t8/#|u$a&}̤L:?Oy1)Ut5(2> ?<C47 >|*)4}+2 >@4N|e_"gld&r$/Nbf @ʩjL+#q&W7T`i'r?ii#XnfФvA󫈆̧;v5Oxⵄ: =Eј5KOmCI[] i;d̷hWF1`fq 3qLTVRqAf\F3jbq=zj{ڵc >j8{y.!>eYj# yw7ߢKSZhۢhs;Ti-H3DŽlmu&z|as,^ny1Sp.'q+X%C0Xʐb >iqT܁}I7aǮ]n[-;~;tz48v3}O)>>4Ѽ ?$+6Aɒ%jYBY_&d`AWoY~FH>rpm䀈F2~10φLU{*y?-<}D-T~~Ku&;`ߡ:FֻAYTYRVg袴;-So>";}%4ofڽyk"v0vb}ݬ%޶nYqwi]3t2mj;ңOc={iýɬ{aXdmoAƸMh͈U1n=LMqsҏQڼl"ZBzC9DMߺs4)FʨO4'Q}8^ZM[͐#Diʴqrx}=fCY=BcDtNCѶm/ں ̢Mkji&>wO2rp3KȆ͚JJCF%S5E M $ύBq':AT,2}]Q!Aˡ4qݹg-k}eKmGҲ7]528#Yt}hfڜ9F1{WyFeoBE>4~ҵT5?*/:~"2NRz MHɮ7,kG:.Q9ov}fiDBp?QzGOV߂/B.qjxiQ3l>ԑ_!mlAXfn%o6vC1lnnm*?A].^#d B>~H2] 7 u ;IZ 20[cb y!ZWcvi4=q1;rk໷E Zʆm7Ficu̅<jg]LUsMrsڧ]Cng+m]jk%'_O;7gvъ-4{¨GJ3c [Mu 'ٯE҉ ʚQLwmrz75o1V[^x് Ty%͙c/)<;|j'߉<L54!ַ?we/ZKGT:XO4N}oG5K nL>7ކ^u]Ko\ {\饗^gGme縌ǎtlw vC>G~!?ƺC4d>-[l:h|s=9;XO >-x$UUUXSs6 YL^2׌ga.SeQo]o|iwҴѕ|Ǡ/]1K ?ɦkק3r?ؓz^<ư=l1w:vӝ4vU6{4WM1YftJtȫЉ <9M/ѫϣa#GPs'컇FINF}6+XЗng}x/rehX%R?aX%@gMzg,`]p5=2S4bTNg-]ƚiȵmxwI#.B|8w]֚c"L;||,FGVHl'#׽;U|~=T٫.2Y^sßBmMq77  ^)/1[]snѽx݀*߲,%iǃ]ɯW`VNRƄ" /~<.8]MJJ& 祠qJ޵[@*GJ9ǻ.͋1ܹe}h{gxih D#< O5s7c.۵|Ko]@WVco_|ǯ&M퍜CDOsӛh&r-{ 3+}ӱk@nkhRFJ"҈a7p\'Sҍ|h:=,;:1L]z7x.~3feбrŦ'|~xꩧ2] @w;&g> b!Bmd.{} / / yS6A#^! c6Ñ-oAtLzdnwaM`֟4yб ! o$U<Ȝ )%ᛤo&vt5}DI6'ow.WS_YWbř˃Mv_Zj\^| ~=} J1rͪkAvӎ4=j$Y1X}'SN֞nT9GO奼ڥ/\|6F%}n>5 IТU,e(O|m٪xI; RdeAXͬ〇ܝ\ Isκգ@tcYy>lK|8hZF?֯ #8ǎ\.rKn@<ɃYʸ#cJ5??`z{wxgߦcD7̠1lz+a==Yq#\ġVy8bŒ!_)c-9^ ?k膁&4;v cXMW_"N<pr"*rYKb!{ id5J T4 m̱\XL鮹ᱢR)h;~)=zul/w' l,͸Nzc,gw;r HN&Ĥ5.Vڝz٥9؃l;ט<_$ rut~'wwQ|ȕ o&Sד 6'$)tfmɧ-x]nGһNٞ@+>leM-+iug +^|>5AO뫯Jy'RMNMH𹲺4B}HƂY#=XkR;~ ߍ7Ԗ6&b'[hpj|W},~\fD*5Daz >ˊe\u"UhaNK9?z+B!\\bעzkөzvC9o{ka\q+A>S͇>;r1O Wx=nN8^Ćۤ^C}|`QA5C,b>:Mg} b+Gg#3lbS):k?ҫb_Ëc/W/hv1xy!9~l|I\r) ˶0{1 b˸0,om֥g?$ ߴs0Uǃp{<ԕ /y*f͒Sg@Јc|oΜv!cnUzL*z5#g)O9eMiMk n4⎅_CuR)ÑQMyrFoN:QS:vn-__j:Bm:Z 5.[Νhk9]y56}']4;kбfj>}jb;mOҺp~#;(qMΝH_p˝Ғ4n^ w8xjWl}G**H!QJs"KzWyg|%l_K7KHyQoGǔkSU\F>S(yUqm.<]vӯ b %IW^PMۖ◟l~]J,! H^?G{A/5A䥣6 y#Ls7oq:,23([P- >~=ǁ*:[;11FW/I 7l|\GgG4*+m"up3m\Z_.ޘ]1ƏB?r#7є2fVт'ɚݙА0CO=2VV 5s`J&ꚍoyZFb9TTyӢOos 4iT2{58RҦ9Sd)O)=}iϡs4 Ik&8@)eDoXbGΥ5ӫiPP ?2A1h ^6YI4aVʬ0ٿd,W hiU =xvxJ TQ4h*{;u0M7TXL<^c)i;=I7&֢(ۊsik94iSm̨^H =I)gĿ%m\ {r?͡qj:9Eط?~rnt;Ip4l|ʌ3'9fn̩f9}d._̥*Z#4lhjyi/ŋgRm+"oDcµ|Me 4øka7s]Cn{џ&iX*vYGzq:ޭtbp?FOnj)ižӖp;?"d\4 |#g4oT\H|R͔/҇X ^}n>uxHa[x,~5uߨ1f?Gk?F ?`{,IGl3.5Tj7|W>{v8_Q^4)moğuvYy1_]ʫ8afMYTj=8L5X+]r%rG3GH,_1hz~׿4f<[H/[b0-|@,AIv7#; e 6i7OgZN~Z,6 <sO&Nx#-|'ϑ~{,|6hKK5`~ߡޓQyFB[ZOrrv,6SߍܓPV{f{6'nQ֡:PՓ-|~;Jw{u/8߁14Z} Н󲨽Jb*s7.ǘK|inu׬6"lrnm.<ۄRIvv MJW*m:_Yα%ܱ/6/R- ` 3FwM~Wf{&,Yț}eC}$7<}s!?2<flblg!X2 ҥξf^__/& ߊ&+%nH`@؞뮻س>MR;-TM9L8&女P*?;[٥T[檧,ёA RpJ;i =Tgst\r ~_SyS ǯ1T>u`L$H/來p:DHi©=zG12ǒעbb܍:nm5&if׀d׊\^gaSlk|| "&S!˅LWU_<<Gܒ|x^ee%x-A2Zp5tRg೐ k~+G/| Xܹd}~d2uK-gx?i4r v0@@ (#S>WʌlecIGvl9V1pZ#>\?`m˱]-xЛKxÖL|!2|Wӂg >Jy@g)[m&u6K:F@ 4ДTgóXbUlݹ Ŷ#rRÊ7vz=PC?~S<|9]ƎK_W liH?YiEyXڮc!ngX -Ͱ0{L _|l?v;4 ~8a4 *zX[>AD2AT4K= QLY@* 6!B$ qB($)Bd YA; AP<eAPTBU&tAF  /B !PG#,N/D"FD!{aK,b D$R)TG"m{Xd2YC!Y2 P2(-凊Ae*PMsjMBКhs:A/o/tO ÆǨa0PL*8sӋyǬaXNVk`˱wcX:vGq&Ha\)׃-6xQ&OƟ7Ot&L'hLBO"|'BD =1xXFB$1P$ <N2422L0|'Hb$=^IR3>iHee4ggڵڳ:::tfuu}tt ][ԗտ@ aa(hĘbl\a=HkcNlΫZGC 96['?Q|~iqN((;s2)S5ȂB¦"rQJiy?J *=C8f̪\|"eA*ܪjg>ruimGX]i=>~a \/l7F6694=hVknni9Պhop%K]m2m._W|}u嵾E۫nPou@]]nZqKVmەwX!dMݻ|/|n_<0o?ڃ4n>R9:X'*Ontw,+!vw'VNn` )Ei2%R3\e r%sZv_PXDy M -J*.i3l~5!7";b:cbntG |ǧU=> %Ň ?|"8my9 Wү&hMONθ72 7Kbb>Y&~Ҽ v|8ٲm? r qtEQ ht3F3݇N $hf-2*JZ{ZktJtO08aX`tƸʤٴŲf5gpӠ+uWپYo!o BVPdpUpF8-5XTGb,ρD$䒔}ά<ܙ5rSű/8~ĭN-"aP+v( ->S]v^HD\5~vtx.nnm^jt Uk%ڥnvwv޴v!NaOݾ{=Pwx3P8xihc ƺ}:kfZqm썹y ߖt?nYs j7u~15g@ ! (MQxF!QZ ]!b0o.8g#Db!y"S(6sY|bCyOMaN%3_BrUr+s? EO%)#T+l$ +*#L,^]-")E%!#$J@J'?pTLAiTX]_uAM=^CCQsUk|O]'=i}Aa1;63SsVyk\ulmv+o`\RZV^G~oyр `carVtvL]쭸 'RRoO?w0Pdfa,l#9zG5)K?!~RJ~]Q%JY)gЪʯ^VΥ>yz#oKܗn\A^uvxÿAͬ=^˾'=&?5;O}b9k1 @)\py S%Cv$xL@ _+@dC"HGd9r%:E3mq4bNK8<.ׇ kD^b.q!ɘ(XDecS˔`"5%;k2`gfoPtĕMny B5BZBEEzD}b-4@k('% d؛˦ʽTpVdVQ*TvRTyڢ1٢BS{BL]OoI1ɢٸ )E_6,vŎ.ܮnWNYhY◈O_YXH5ud{l@ː h!鎬AQD}4탾g{1Wx.[TBaEc`#n13v1i2Y0ّ% `вp(BC,D\P|V*+V򐔀Ԁt 9[rEK*e_ߪj!ښ̚Z={JuTuzmG Md9LP&V̿XYnYclm-<]nθ#JxX{yU{1 ಐa#Q)+qf ]IeLiYF?Wc'NvΟN*VwUU:\Xl( lbb׶k;:oR=ۓK7|?G O`610B« 7w?M;^޻ht/.+W}qwۺІݯg7_f#퓡eD\I@C9w0ژ{XK. Wt KǘdLb 7SҨ, p'^psvp>s7/[QBHWX]DETYLI\f(-)!&(ɑU+ijkQOD ^ÏT S_\V'Q6vfnNG\\Ϲ;1}n?o_0|ʫ'1E F)D7݈7Mx䑼(;$ٝe=v5bœO. <<Quxt-|E#wSmPk%Ͷ+.WG\va\?7x>(2T4xd l3/S_|4mlJmZt2+Ec ŧKe>}TlՕV_'=ڏkkQks?>\W]`Hݠ2wMͩ-խ[sǶ'ߵ\n\~.ͺz8ـJo?fRvQnbޥ|^ pHYs   IDATx`TEǿ[{';XQ@A@;zSPgg"EEDUz!RHl~6&$xy͛7o~3s:(//鮡+tEB@! B@!&W/ ehhe6K ! B@! dhӓ%j*߃G6B@! B@4]OKB@!&r/]vh߾}$B@! 4a!OV-(..޽{ʧʡݻ#** `jgs.T1ǣGM.SaO7/B@! ZK.pZ%=L&Vtuz1]B@^Xyi]ٌ4]VDFF*k%%%طo8l\n*3"F_RRs_4׫2  Fe8pe ! h)ܹ2ofu֑#?`o$!::" ! cCcXp!%?11Q--ԅǏW^l;"$$g\fFFzyIJJDB- RyUyǏ4lPСejuL2LY>/@! hI_QiŶC'?f}:krrZo۶M}{뇅Z k"x\/{UÙp`:wkSؑ> lNs%Փ..UidK!  Ư> ^1!88Z ]_~#BYY5"%%EgUccc8iTZ\_d$$$rq?=mGGP|*j+iۿz1 U.|M ׹$^! @Ke^Lf PQf"8=WfTܭZRl~_zl`\%<W-n}}q'BpJB$> :n}:9"B $z֭(((@޽Fe/{ ȁrcΝ;q _yוGk ;;[r?s`+Xp$p+dee)yWb,qer\!^>>X_2Y22wr3\nT] Ց,99+B@!(3YQ\fJN G CrH/ Z7jZt oiK|:!ufdB@/޶m[Q+7WiX:idNi㴆xc}epY  j0p9 \[8-~P_|i-Zyi洚QW'NS;C+B@! ~Kf yDZwg3n8%BZ݁~_yq> m0SpTX˅ a(;YۇOClSxB@!p`M̞u]Ms[ݡ2U~\1MTswqﴼ&v*k<2~ji B@S@Tx"V SwqDs # ɓGR*O<A-Y">D<@8{7@RX5~f:l ! 8c  vn \Ϛh^s|"5 iLPe򢕡,5{HB@!p*: wM㞽/ha0.0x+wW`#媇 ںaw.K_n=ï u#1)L}}rVPpB@! &IuQv;e5 ""ܿkB]Z,Y`sജGxyZz6*pZS_*_V?me砉P*B@!PuJd %t~deF4Nmsz߿VU\x_F7soRsBVAEpn9T%B@$ЦM5 M <p~'pܠ%Pq4Qkznxx?mCn24}ΧU|1\&/4GQ/8Bw>6 lXQ>.B@! N%z47xd8i-G|^nv",Trv3 ˁb( F@HA.BlZsAB@!8YGGG{fkִkXpY =y[ڽRϢDtlH zjzp+=ᴜ2<Zyֶ6TϺ.qB@! ZySRJK]AK띾z:.!/9h^fbnycNoF.",~Utd?ʿ`t(8b,%BL&:555Uyggg#=={@}l8/753~'p9j>l`Pr;|+H>,9 Z4e{ hep砕BdKe^uՓqlYiL_x! -E`ժU;f9;{>Ȟv *-4_+v M ]tS +yF Xoi< -B@$ݻ:'lHkN ZڷJwd|p_XXr-Y6s:>q}A+Y2||>nݺud ||.܍}+g} DŽB@TX:Ii]m & ]4|M! G;k_4$kp>rrr4k yR׎{?Ju] ! h)%Iz! Bt&@Pho2Z! B@! @]/}< mQl:B@! B@S@OK݄B@! B@ 48 %IB! B@! B% 쭑 ! B@! h>bh>RB@! B@Soyyy< FBB"""d2СCطoN8Ţ\dnaaaHNNF^ЪU3n/h^klsJYB@! Bt&z5NKDѵ,..QQQQ2tNGO@EErrr` anJPl `,XȆO[nݻQRRшp@3'>l6c߮]; 4HRN*Kce9Yl0E$B@! عs'RRR7a#{{g~Yqҥz洱*x6# ԊroƎ㔏 0914AYܞ켯ff[65͓d5+\Aknv's{_}~l1d+!1m/w*B! B@!d$ȥ k!i1 h> 8aY/zOw+׊B99mfls𶿁ӒP׌-y n@{;]tu@ u0 Wx.tVvBOh4L Qߊ' }4x13рLC1v2(\gJgElLƎ` ¨Q<_:--MW̹?'A! B@#Ve G5";x%51<^Z%c/q֛l< H+h\tkv>BtG;3˽oMz@-)f \68(t3%NF] 4O. x:s 㲛… qe1S"$(W- G`#2NH,˒}Pd*Ipp]`@8`Ɇ=FoCTRSOsמ ~VXyS(&%j=qZ~fyZ@"acypǐeB@! 'Eh7h*жNgtv qVE(24\ykݥ6Zb@ӻӝ8ώ`z\z 0w_imrs=OP5p싋@*-S@uN6e$N߾}ة%;AB}`踞($PտTFuHaP: Ay)S }86σZZm6 y>Ά%#@np{KB@! BQjbsPdd( %}~Ogn3]ڐ[#OkG|Cb:iQ Յ;x4&#嵩шZjl\E>33MI)zJG4?Hk[N*2hжJeh׮(r~ %%Yo^Du`d7]^"'_}lYT3DUl̝;WuA飦f>Z{EAV8B4d `; B%[f`|eq cl$`k"şBؤ*B@! BO rs%L*<n^A޺<dʢՃ8X^+VPcO q=*4l4ˡV/- BIHsNs?k׮U])=,Y?gϭ,q/1IO\B@! oAI񫠶i_g\r`o3_OMPf2cl R[+KsYNlgf2O~$! B@! N6brZYkYP-F4Z+py ~q5WqRƣ暯_}"NX y?LB@! B@&/B@! B@4[%! B@! 7F1}Ͷ#x=&Ti-ZuG.}.6)N=gSٗ7bkB@! B@®< wmrZLt; ]ZZZ.l,~-qշ{p߽0gəg]P Vǖ^Ƕ:N11<%s |ˀfGk%(Ƕų0{":-yyMW[rxfNY{]'6u>WX:yf+ %B@! M&`ƧӖi13c 檫֗1OǤ)2ƒ&b'(,_ DT~g\V9iv)*nƽk] gbrF}⳼j;~u(<߆s qJtA?C7Ҽ-ړ7nDV`ڿxqTs63*iZNT-,UE1oC{s}a@%@Y}7}aV3U$L"ڪS`gdFunQڄoPqKc),A3~G̮s6檝#⃩S1Oqy.Ƨc۳ؾv+QP问\-t&J+a'֫ޫ{m'MWiAee9 +-oޥ~{ 171],pi,?)^{/ÌfOۑJOSƂ_ԏs7a̺XN$܇ÕGg#Q?A=X<#mÔa4쿵5_32> *U{aePIB@! 83AEq5Jfn7+fBy.t! 3l#&$}GF`5t..s>{wk\+u?o:ʪB#;\tXt?W2=?`/ E U^κϻؼ|g}^g^1]- '';I0w؋%1}h?3Wn{Z}Tl7lAn)b{o5au[tv3R.z z KQ=X`֭! B~@G $wΡ-|QOUM~?F$Xy+t© 7m6^~m6z7aw1d ,X+I; UgsZu x˱q̜nK=ƺqYCYfk@Y-$qۄ< _|EvNVvaFCAJe( 67j#$ Yx:5݆7C_lX:R?|Ͼ5mQ Cx8m#08'B.CtrxrOyZ9=ɥرxpB8-4`eж8(܆G^J\B@! &CQS3 {=BKՀScLz/Ŗ0_߫V';Ͱxw*VLU>!k5!l+.Ǻ 7 !ʛ^G5>K1dQ կVA$tIob]QkwXQZG o?_݋Ph=< 3]%U$m7PyBΝ{>xUJOF j]6sk:pRg(!*DYal쪡R7ϒ%KxpIڕCp}ap|>J\kؽ ~3~RѕNMƗaП^1e56@6IπΛDwZ?oR& j4{~*1Y]Xru8i FQWގŋ$/ׇh\D6U_sûzQ\ N]9Gܮ;:%X }nƮ?GOH;.k! B@! &c(GJښĻ4MN; nـM]D5Nq͍!mOUnXVS)Ƭq?bɎ"DSn(\J*a#Qs.;W޾0bC8g; ;qMGr)PQGSIk*CيRT ԂANEƒU(AT$`風l>ѱ4m3:EӠHZd$%$ ,@{*vV%ߎ*-vCo`);1fpӠ}8.AWZL{l olޝV$&BBB+yEd1J*uc.xT08WbpV0+܂n!,Ȇ9=7 ȅöZj'&7rHP:Me]'3ӑ]F-G"P9&,!S]AcO#n3?-]j;K όI:4+ g.Bq/W@ ! B@ӞAdd:Jbꐀu ڇ)M125\c+*`Euk&Az )9{%xj5bj*V08qhTKD8\td[9 Z"pҦ{DVpu%нOoJTGT$ϣeWg>0vo<~pyI+c K^ htGJ;rIƍ<3<-ÒePHvOfe@\09AצQo'x?dْSgO R{'߇cOGza=aXrD6Sx}>d~0C0˅yݗq[xG7Ǿ{[K]pRGތVt[gBeƌtuh{ o &L>/IrצeVMǸ'z fpAxV[B.Ю;\[-oQDĨYֹA.S 2xKq0jT[a67 xK%MSy9FuW0Aa3aۋH~a3PvVKǸ4W~%NIv 'm %j)G]RwrFP a7C""@Ɋ-aq<7 fatTҭ B@0T|NjVP(-@X#!( Rjnc7ƶD3!ﺨSR#A٥Pu.:4`y 4\Xxlf3E}W0f:NR 3t^ @DDShlJ(;u+:yFнJ4:PVF.>ʶЌAa4= k KM_M@H84R&Ut eBjCpt4 d9 ! !S鳺uc382(!:Ftg.!:z-?_].F( w٢¨ kc I%B@! NS00K4BHQa0# ]A]YQQFL7rddIMyChyba35!PiGi ۭ]Suֈ۷ϫ5zt$ɯS$yMQ Co q4se.ēj_X. AHFԈ̉daC'>ot<"~t,5A/|m5Z4Uz:T.KjzYPϥx>CI^c17`gOGo,EˮB@! uԸ$`jj h(g#4+@PZ}̗*u-$ji-v1s@UNזR;o}ڱf mhVբmZn:af&T5+F ! B@!p Qkydim׸y wof]RN.B@! B '5sB@! B@}ruB@! B@! xp?@! B@! _~LNF! B@! g4]A~ xF?o s~ދ#9'N60%1 W]vRՆewb#-7j@@F$ 銡:,1B@! B@l(.7ctRVJl8v%D<$Bo{y0?$&$@& ;)px^~ݺ ^17?m؃7?_ k8g\#}cErs@ zHrr*y$/]R%Ǡ]v5IUa빿wUB@! ݒp!;>ԩƎX ! &$s9>I;$|gtqѧ߃w뺊vlV1=;\` a;#@J%V DŽaB6}`$5! <5n{݉ y<4X~چؘXBo8:aa\Q>#ݪ=Z/XȾ4fm: ;6BiªW+ETta鲥x@aaJp8 8q|srw=Y"7,qƑ_>=yd4B@!pPXT0y=-jL/ڇ}oo DB@64$֖M?:T|$} IDATt1T'#{~'ߐvp}|V:WBXqOp;1f{ qGsml2ƥ!u|{zyDw髥 Sׄ ж3339WA-1!u:'71ZV(=WZ! @KXr\2v<**]9 7Y_? {<ޘǎIcϨ1A4-խڦ'MѻuaCUeK!~kf(}Gɕ&!o}*t8^YSAⲸ@A ߓӝ0p&2 s$8%8&>ChD8|G+-8pYpޫF_?hь2ش3e1͋\=CB@Ӟ-xokq5ךL䧭@Ei1%q)_ H@^G >.pIh#bnCjjVW-o]~՚ L%! J//zrf/_ķ@ÀԠX_qrLT#\̙<~m9؝ALR9,{ #7v]##'0qmc7m /c1469C/߾ IaJ?~Nmݻw7@,B ؖo͋QD ! @s-xokqkMVm#0 D AҰ{^T'c`ռ #{>l6Z]&o7泸4OTdq$IBlgi )r35 U@w/}w]?W_{<%dfdfQXn@\esƦ1zyILj /+WTEyil-=|->W ?n0מDmW>>; Q>OacȜ u`%*ATnzحN&'58[~{a_ZV#(5^ȎFdZOTm۟C/Ed[imVرCx.AW>ZZuK $w>=p]ϓ A! ZRz5k*UAo D ^QZZ4L>r9研L~]UH1ĶЬoR;tģ=wSmDX 6}[8[قȣ+Gpe"ԯλrڶk aAhݦ]ֽ˨/POeNb#8$QQQji۶-zAg j׮ݘ02rSo,~uu's]Zѕ+`Dg+5 Xfo`x(G #=7_2p"1d:5&9q 2`T8tH V9ϸAA*]g0'.ܳ^ ZZ_~\GpV 1̀Є'F#,Yxk_{DJ.6ݕcnQ3P:@^eDpʑSEG9=?ƍ9g,7PE+BNiSofP?^i`?奕8,ڟJjV?'4B@!$ܢ{oUرڻ .pT={-lGW#?Úr[X/C!p>\srܯ~ńW`8q#>~ݛ݌>}@0lCb;wƯ[6:Mxϳiΰow##w)y  F@ѳI"R;p{*;wz./; sfϡЪ1'wZ_%N7l'v5O^5v7zԡC­lD;{&тr8o DlϞ=pmѲ6z޽ؼy3F| |G 5+܋mе[7D ׬QZuI#?AϞS|>ԑ[oGo/++KcuVaHHL^>MiOEAZfOcvW/:7'I5hT"Aӆu$3dN۶mS/`~~#zCc Q5w pbS;Wsɧ&#>.ƏgIaFt[,SS/`_n&O~ v|ÍxWȰ0]nnU_nCc ==ZtI;g6  j!77,oԓS1yd*k;u)d;Xx1V ~Ʉ1cK~ ڴi|) U5(?sr@28,lu)))>Y̕W]?u']طo=\|] _Wڜ.4S? dw'(3ّ[dPeI1at8[ۑX.)Ԋ: 7W]xs>ӎB`R;_C/rMT>[q 1v`z+g\B ‚p}غOW-#UK?s?{<ޟzS^\$dh<t)Zɲ#M{;.ϰ۞]T]DF~|Pi fy=hP߇,dL û uIWoU2Fusj3O~-Ѳ}j;_Wg5J|˭œx)aT;e]nl0XL:uD^;«/:Ue䕠=f˖-ҥs4>k |3ڵmY~e˖S|nDs%n'<8.t'{;}Φx#=aW;k׭&24۷oǍ3:vgoV1z(%oؠ4C෥ ;Q-{SPP%KǺkUr~UgUV,d:s3j?&&a+/ч,\y|ӇJ7 ڵkV#55U}//(n#k~n&כ/ ,O\Z%Ůc#^Jsҹ\©sٙ*W#Nk" 2Zc֮hOT0`̝7Oz]+,ޜNBIta`GJlI/EQNTuUtLig{Z jg{O(!Fp' xgKK)'6<*Ԋa+ʯt3 #}4Lۡ=$!">hd[E edSڠ.N⿘`9d0}%' A1(Z\L*R*ؙ^=,e= F3 ́ߓk"sD6uJt ϣkߵv"C,ɇ ȅ+y@7N_۝T?B@!Ьk]KOONPIzۮXM:_':vw~ym茵__q $ө>5)e!C/ v& u.0đf-J\Pb's ll]\]51UUi:,J(/9tBg!9UO,ۋ[y.ߏn& 6Xa)%H1 x%**p0 ?IXn5 JHƟ//7a qF 8.X;JP)R|߫w)BcXԱ+/%BEZng|I#a@MҴH7R]_@T}4ܒX! E@sLu 'NŇ8*L?­ݰƣiGzt ;k8>knX;eڿwlByELu>idZjiSω'=hA/2B]~6蝓g c/~Xnwz[k kG+XL^K^{| &` P+nV9_WbmͷK$79$hK.i#F6I=k->nF"BVqDh\~[=F`~գexkMZ{W]}5eYnf_K =kהSN9gɡ|8Z)${߷TOLn}o*:gC#נlje_YVL eOqer;r-Kp8io(o5e~ DB5dmFPPs1@&3 mo`}CR^Sm]:GXmP8ϑN9KߞȬrrrRقrJY~v"|ÑX򚟺%[Boo-h2`}-w;#+KT9IZyQe ,+VO-n+|_;OQ,7GzY3޳x12;?2=P`@8/_ /}+e6GI?ĥ=徥.&W3mN8a`|s>IMoo~fݹ~]9<'wD[fM!K_{9y9̇i{.wN8ᖉa7t3rճwg3%A~S1?Re{V߅@~]l\φrHfCI`Obz_ySgFn>ÒqΟ0s)ogKAbC_k_Uni\I3y&gMl <h=-o~ue=ǒ*{ pw}ԗey \}>{Rn!sN ^*p~g?;@zfNL:/yKˮ]ʥ]V.5D,}WYd9́̒BfT 7\ϱ4'lg̕}.2 IDATן_^V9}B[y+K)O0d_hGY}G­(~FʹG?Rf+grYLJwUyϫ ҘguӭW}qI?z#eו*?"eߺ`v|+gvrA3hP`@CP`VƧ*=sŋ˧7]{oc{ֺd%Ѥ<}8g8g;,"3/hڟ h\C^]rm?q{'\C?\>ghӖ6я~43aÛgCi> //փ׶lZ<]rg>6z W_8;?O<iYc B-oOz-|>ES,}<-Gq4  q7m<MzӞ/? ?ж.^xa~^_^?rm恜9q&g]< ___)Oǜ_}gm3yrN JPO+=?WzaKj#Y :z=jP%$%"˓K9\.w+wA]):"@+/v,8T6|嫼Nݗl-:{Cy6[#֝bdN~c˗=e pzW橕L|w9^(ݭ\1|J7y 1[w˽ C7˾(+bg_|1coRnJlşr7?/FVs.ߋo`xml?txP<2~~F1_w~{3 "~Lcc@PX#,eպ[e{5̸btXl>mq|sc|&a|~ A?Gp/lə,ck>qq^xI'gK]<%m2odž&VV9^*Y<ֻ[f.PeĿ7/VzW.9sm/_ycwB׬lL0뵯983+DnZ_]ڿ,_:b AϾ {7y N)WB.X 6YeٯnP`@XCUcPW%w/?fK7g{Mߵ|sxҵsM'9k^.QK_T^af'~X>P7|,5989)=]X&8S*e3 '\]̮o^+g/'Nc'8?5[Psk}J87buWaNc+fҙ]mː'ej)(OJ)^m~\ tmuv(ݽ®kˎu~ʆ3붙wP`@eXCU{ت lmytKzg?7;S:|eمr`ܿ~a\#8nW*/W5gW4 {BsGM/?QWw;rߏ>nm&!3Ȧ( rPՈ۶m-oe8֜yb .쑹|Qڥ͏=,WͿx?㡛˥m(;USe/| _}0)W+c 28󺉲e|=}ʲ-?R^Eyuz,{s\祉+򪿻Z}m_?biz_+WNۘGg Lo2M=L~My7Yՠ (=M>Q|+S孯|\_n8'ozr9g˾w~Xq- {5-q:c|䛦~+s1RVmFxk{;wfWzwzN&y[o <ܽݾIQzpE|U (pgl@PQ`o}3~奔lff&<ɼmOޜ|m]֯C-Ocss.8ή?66^{=>^=kXߙ[)\3A1vcXh ^ĵo:rP:;rzp=@vV{s_2})Ke3W\>Sv<_N< 2bQfDP:v8z\re/'S}fٿ=.@yC+g,^RXL4,^[>-{sHa.{^?Q_ܠYI .м%4ׁ&2>-k04i@P?˗/}] ڤM`i׮[zխ8O^\~I?+>j_nr7+3  (P<\ 6dg7{P ?ӳ68J xȣݛ}UnGMILRLɽϽ{?OPpWvٝW1|g㪂ˬ i3>[~:U$y<|3Ɯi@P;G6 Gcŷz|ϸ8;=Gv|W,Z;O9z@8$8dM0=TwO]wxwA (0 (0 (DW5RKmsrV' e).{;9z+p:7>ײuȗVn\u{+eԕ~kɚüD_ƦVLz2=6- وsۘ'ڷWrr>0Q'揸mx4,_ ,)-ݣ r2/X(P̴\z L!{`ҝmy>26MqF@,l0Cũkq0eJцP5GBҘ~gHzyK;+ǵ/_׾ &EhEF݅rVyӟNAPA^E' )Ȅ]eDY[肞z yR~&xc唓F5d]z}&<)oț ;S7wefªkMt:yG1D]:1س[$'mRǪ|ćgֳW1TxRz*[ݠxFs(=w`AI^WGYTŗ91Rl Ò ?v2hױ)A:CYoH[ :pt>=hBqJ^ גH?𘺀o{h 0нhp#3o'n%U[cgmCd]qf4M}?0-mYG7K64jzGB3q^QDy7wEOm}")˜tDI؉m?S0؈SFJ_FMDeb/8 6˛>qi'ژ~Q &W/:tGuZy`W>PyP]H0j<t/'GxtzebZxt%!R6 -]7u:gyCX>&cހo۷&r|"'7v/m)wx.~ϣ.UWᴵ~ϣ{KK#h.)p+`eW?[:|cyx,֥.c,xm:,XWOю~SN~f3dRΡWoni,τa/-㋼˝3R=ҧW,c78!׹N,>Cw[&r񛬥ҽóFbcl]-(C{zȗ`ioM] O@'U'inQs,E}X~>3jchsÊC4>y-SʶzR56DO7=Xpnjށ |2Z  Hi waLX1glUuh,8'[Ǯ/,8p`)6x,{ה]SV<sH䆁cX = 1!52ʫ ,=ajTMp$bvoRk(s odt j%2mWQщ jy;ֻo狧HJ@;;>g@U ({ g1e6>-!9 ޣ\4>|C*8GQFvD;25w$N,gZ`Bn 3QN* _#:^TW^pMyn?u`jۨ&EUh 2 -uNw0#0u5ثoa!赿Ae. " |u@iG {hmq\g%N1V?^;8{xr"cZ40TNM:$&8kbyT_Q ]ԔpXcx<|30d;h2?C"74$ҷODxfO𓏢{5j{^Plpcs|a,̗LK[xMu1 #K@@1$tÓ*"L_'( 4T6uz3{M۹󵯥Xmhw{ W~N8Cw*%@#iV_e7Jwst}7Qx};zyC>^_'Rԇ5C8]u18ִǶ OVNcS&ms R20Xv);p/С'tСeS;.<3FEÿݠ_|9&QDspOG*|`*,_q?ADч'@!2kfzB3!lWcghlӀ]YKսvD8+.[`#O!6_ t kOMehB?|8WVㄉO1p; %p998—i{C ]q8qUa&{s5qE'ӀYm|q+n# IDATaj`ͧ^> 5F櫠(qF혊 p"F}6àq//7 Ad C7``*@ 41Z\%_kYbIU:Y#.I1C4h@xpWĈy)*>v=q;gTH '$_ۧ^G(8ZKCYR`Y"*z&[?er+IHCYq d׀w* F`Q-Uk@Gn0̬2zlFFzBȋbf+X] 3{mL2F,.遣8kc#+7T ,dőuk(S}Nu>Dp8:aϚ?S4j N*~QJS~&3>6w hK9 PkU·jЗ1rSv2 ͐W89u50GЩ)9\GFWg>,$"2_!.W>571pgqEMc CкMI~%` )f&|E}M|>6K%fؕkLPfuh>9m](Ak;K@g8yC =@b-u7dC]mm<Ǖ5ǣh*+8:ĉ ?'U9d8LvtF?rٝīꆴض?z  gbw+WkwЋЎ/X]fՁԑiL:'-ܜ!$(%qE N\'y.}c ٤,w49Ϣ ol(Uu7z&ѿN08?0kg %d 3VZ#|8fuYuҺ2O\'+} u U" ٶ?Pl^n܎G\ |lpH;:ΐ7cE:gc[K#xgiג[UBGgwȷ+FgtTb "\(zC[}AT哶ԏ: ѦІe~ o?Kga8s uhX%FjV*fCr:A1\hxr{ՖM?^'d'߇'֣ )LLF+Ko.aHFk.{pŢ"i>8 &| ew~(Ih[c04F칹i_DA,jd@M>3Z3 H$h! tjae܊hx6.Ns%=~6.o6r!UvX΅47aS;/<6x< cvYU@?nSuM_tgPQ'-0[\YW ^~'{[)PCW +u0O9믾 ,PrO۵\aGziu8.gU2 `9+xu_5£4(iWIweUaGwmgG#nMK?6I@qq2,+O= Ʀ.cPϙ"!3N: c#(SeǑ4 !ca.M̗YjCpj1Jߞ[DW,%T3k[R^Olx<\ X >fiNa J[l`Uȅ aZ:hH2밮:cVhGfg7Āa HhL .~~ɘ6N"e1a߁Ok#ixSQȁt23f?w ݹs_o2%t7͚ulШjiHlwh`!p^ܳ ڦ0AIxKY~U)c6&}dI) =;h+vYh`;]zo?33]^<|Ы*Rz/\ S+KAhSz{-4qŢOy."g/o8KkquF`c\:u̪Ny[n8+7X=yRҗwZ v[=|W:>2 z2:Av2DH9 ݲ,'Kf|OOTT9E0/Vǭy4z}7v'e'Ytuے:L6z9ϊ-ꄌW:U!sfK\i&"/'2sg|C':D~SSdKJ`ӷѵgDP [O譮SF '}: CZ灏;Iݹʿ֢+<־^'&VC\}@=Hv8k 7ѶjW<dP򞫮OҶrܦehIDY?|dvn4FIN_2^2[/Bsiϭ ӠC/y:G%B֡lTgyekeb@ŭW;$&+H2*SDeʾ|t-Vܨ*eADOs>u@rG_ ډ&d1g{uf1xq%F 4nšMMۮ\"#g *3Qi;de8Z`_ hpxC{JpC4B'^$+8Y )cAF#Y|Ip&uQchSяr`60K gs. 6@`u3Fq0c`]K ~py1pݿh08bk z3r$Xۘv4dvݴ-p\^[<˴u60*Wt"c29/7݌ѧ+0 Wqfޯ^Y֬/ۮ۞=/]eMYVNx_--֣^!|<=y߲`\:2V$ 7&cXJp@gt@\`ajwX<e[cӾ@tR5u Y K!gy'HߢA!i;e݉k Zˮ01.7EeNDVGpLTMD)v 3y%S6A_@"+^ c{qOp(4$+q Yj}4H yG}~0 C2aV`9S4a@ My#> g`42ɏ6+[As݄._uIeS<>C Bڞ V`N7a [Nq.a6m2E[mC:`U8ЫZE;`I#Iz|Eێ_vkM^T7t~ e-~J98[tu<d {baeBgAjeP)ߛ7Np ;ckׅ2.!u*6J468vXI;qe:N.k`O |GF.aQ=%ZbC9XPA'oK'FHG)ɔ/l~+g&aզg#j0žGG{HN*^ N>Md>Ϣ_4~U֢눡2RL w}\R{-Z"#Qٌ[U<0 ] ZY4lfeGCL>fyÖ 0a@чp%Y +=G~TWAcLZZC\Hczd @CyQھ޸L]Pq{ PRoJEq;~ڗlS Qc^YS8.aOy3D T*-tځ>IP ЀG+8CCFQcO=/!H~{ieq@:ct=n[r+y+qTtc@SZhHQ!` ^k[x4GArv\gɲFd6[i @?%/E_:m S6w+ˣ7RI űA J~G7IS.ft:::Z&>*#͔_8<5UVreR=USo-liy*tV `R/ y"SScQԫH>'W{ uwm'r~`F\҇غG'&l y%n! M}J#dw>nc;HuETuB#Sv8SV*PmX+;n[a'p+jSUu.ۻbo?զ0#YWYY-ڠ@yl9P?R&vY944% "`Ao? 6B >#3*)OG@rHvYAwXF%a0 Q6H:C 0T ,ұI ̲V\Xy 0|QΖ j_! wڤ-.^x[]BuvK:\z.CޫJYO[/[(|-\*3W}^]qz1_A2t'ː3OϹ~V(WU80sP*'<=Ht;5Y ,[;=Za]&XgA:2I8h+,1D 4p +80PEH[; Ouʾ{[8d x´rA tYmgnz0H 8w߁tCg)|zeJ0 scJnP!([B/)QJy/]8yVCA8~n'ctIv{*2u얐3n\=gK,`rUglBqVf9U1di6M}<֕1HNM *{?˪{{o.Wm &_-Z:}s˯ fVZh. ',jftyʇ00\%gNW=>N%_+[—iA3 ϓGD&3|˛PMҹuW) 4⣭gĞґ`;m$8$`2f[8v}Sh ͚ 'E O | ,k3Պy~[0bt`a벲4wj0e%Hܳuӆy3iJkl\ɵ8觏+ TJn'!_BWr8wO'p˒`(G=:ΰByRoWgSic!OhO@&rk]ɚ('?) QTgWt Ќ^QVLT[QOdmfːrEA6<<#Նoe6&FTO!Ї./W_ēY%% ~]!=[k{,'|x"} 8EDdFO2x3)$*_c4Ơ|"oY\9*C= 3>Ԙ@PPX)O9VTxK0)+!_4_]FkVwHCa8c#cd"=h3m4 @)FLRy4^ViG v B)} PsFZgD)eT>2tH2F.QBi=\ IDATK.%P&, F];{iƒg VkYj[YaFHt~ ƨvyXgЭN&#+tt@ 4yFY)$ W̃ZAЭ)@;H@#z m P-"HfH8]G`k::I\i@@ ?y+~OO}MueQਠ 97Gm 7cZPaQYbL9F'q_}Vr(ʌpSjUM;u8!-:~ ? xz2[|}i}|2aHF=C1:Lݖ 28YmG5,wkD (,Lg&gS{tHR94rwt3K i3qli7̡SC/97F] >5hWi@A;:\ 8[= ΆJ64@J55t??}$4^IP6<.Bxe1wc脞-@F/<̑Ci3LJ#F@3S3PxEuQc`Pzn4uC#HW^&YǡC#g Βa!?g8Nq,pV2l64tGU4np%9mQPqge9 rCY GS,'1:^cj g請W}7:$f넳if cMpldl7B:8| *«1J6du/tlo #O?4)_#<nG>mw%f ꑏ j7uc 5ڼݏC' :\Hڐ6$>:`cޙz@h%ol 2*EN i?/yAT-L4F Iithp0 *{3r#V3 & Ijh.q_: 謱e͟U!l%yk5vp2K$0o Du~9CT"Đ쭶䑸iMz:ʾRœ Y@vZҡ֛LJuYx-<)ԥ8u\!]GlC!4y)bIu'w}ޯ҆62iNR(,JDdRKCIAw:35\҅TJ ۦgZ0x9+?YLo0ԃ3uK5G}#%\af5Z Sd+L<1|{v:F~~\K3o)y~Y*˩5ȠqzWmc -H`>&YCV8Xmx7 ҏJ&k4fؑ&Ԉ{+Oq_;RTK\\v/ Ѓ2X/M}O2LI1R{j!܏ǔmx`t8[bfyHjh\UpeTX4ƁLm,߾ꤻbY 38dG4xRцaLxa 7H9rH`s4fz8Ruǟ "09@_R%^]EZ#-xk6-F}0|o~fE5p|^) c IRdpI@[s'9}Ӕ^ ޷6rfO K@[U*|ZQ.)e9qtl>!%ы8bPu|D 8ah-|5K}: 2嶞.xH]JPO.YwYrj#__-J.I   q6}f۽>(1o棓9>m95{ӯ 'fԙ[KqR(џiw79H%w6B8J:y.!jt`tpȢn3<ꖞg)` 1̱iB`ҏGY5 o8-q>Nqod,(C'TF{ 5NUmp:DV){DQSg+h?##P|&OX[֜Ʋih :L#О~&X~uL7;CvHغk-Ml/{nr1:&/I`1;MH'?YWm0!T=(8𻧳fPFG'Xe9?ݏގ,ۙ{y 3"/R7<76ٺFGksvm` \]S>:|O yeEwհ#8xoA>hڦe/1Ʒw?~?n60#? +^9Or6'`tßуV((*tSH}伞)xYP}l]Љ-SHt+sB+xIZI -{3;ƒWcbYpsyl(2ijWxV=yj-+ʢri}Zr 'hc| \.yr2S÷ŜQ( tRQC5׺&W.w!/qaq gQ1T\Z5T N%m\2!040a.]{5/W[Avq B;ufgP FLQ\B[ *֌/~E xQdM!$4+ve} #A|sQZ_ޓ5)xKM&"Z_ŷLF)Cwʴ?'~iW2+,w^ySZy1=c,9c .GA)+_$~3eԵ.O*cSu gyϷw頠>`u>~ "PWf>U!WsِϪwʫh{[Lti9xo5b5}7'pVE׋Q u<$*+]B~k\E'ȅlIh\5>DO5xIbhn"3}GHxdK_Gn&0;nm{mQcasP6c\Rjq+&lLwwuAXY-S7&:pqƸ=x]f8`wqF4\eq7 dkl_1 Y΍+4jWp#M8?P086e ShTWz'i#NKnc@!Tฯ!8=Vll³.8ٛmBgxO4󺢃z=kG%MȪA[ʣL2X!y>̗<_xgȃzNPq [ 88>1(D,38;vKdu '+NЈp#he<;≳}5v2mt݆25Aq9> ' չ350g@AC5?tm53Cix2eyGQF~ ,vn'r]yU^ؽ:qO`XajҞkWmhUU٢I~WeF)3@ӊUh+&,?9g_%_϶2NY4 dl)ҒNlK;~³ 7HGΆ|+C>=EqIW/2>kay^4tKIy$/A0Nz#ea)P|:m ,X_S AluV,W -^Pr߻&rU6ŀIGYƼ~v6KDx_'8t"_dF}1Odai]JlqjAgIuwƬiP:Tv $l6?z.G\lȨ y2 TH^J lt &)_7_Y]M2B/e+#=#Sʰydo߳ WZ7x؀ ^# Y<\ʙi%7T֟YV!a:3Đ'MY`W䳇M!v t{= 4(CQ. MaPUC<(X :##n^`dFIH:6xۻ&N#Q[JYޒ0o\ٴ)2Gm \Z2BN&a?Ęb,p䱷-0jf(i3ݦз>HSA; )><I!^T܃@C5Xdn[팽3~N=򲗽ٳ\~妛ne-<._#2m޼5I X=ozӛ=v*+pwg8eIOzRٍQmG>Ru{a3<}^K^iӦ{P/-^l@ "ʑZY yOV6"3 qTZ/ճ@ & ̅84:P;`y&fݖ_8UV{sUƑ5G#m܁QfNW!=  h,Zg90xx61q#CYYqת 336u7]Rpfs:{ Z&֗W'.Wՠ]od@_4AE3 p|pĆx31k`eO6; MH鏑HOl9'-nʑ$nuGO'7Hx#kN%@#  Zcznq Ϫ [[t>=)d߀}\ﶉ&04) 4C#KmuJKO͆ؖ  )S%]>+O IDATSZygp\ rOgY1v.i< rsCiC9畍1UDjPSZU28 ~fYDf;8%FWak%L9{o{|_) c,qIg 5bLFD0h'd SЧ.װЊb{l_ IK3\ɩjm1#tq`Kn+,`$hW@>Uk$)┗A*-h?erhPǙҿ!͵^V@Of|-/IFs~ě8LXv7/g}vyc[Ǘ;vgO-o)~〻}nٻw=a.\qmo{[ꪫS(+~w~<,7xa?X7}c v>)/x {6p5 T| s*icƑf%2ܪ _Bdt2:R4 N5)絬oe`{^{?0 }Pq%c2VZ)lcs F M"D:E|ūz-c2q i5ŤH?{m[>³ΌA:Q63jdāS +|!jCg*NkhCZΝOŹGgM7! Y=K A!r$㓙Pg '!hX:;ջŽ8Pҙ~rN04ӵC @1+ǘ/ 388/XgM}4ړM~MJ8C2^ApqѨhCQ N ~:s\^{}RkD:j$`DI"tP^4 !BMl I2D;vUazy>{jUVJHuW>=9c1齛ݼN&أC6\ 72䡳iwܦUDX!k4[O=*ӷo\̓ 09*v,@ &^s6  Fh "{nTC`!Zs~:ud>Sk]Yt,3Aݎ9+;:$w jFnR&=ss~ܧ:`.4/$^~,4 Ư`]3:(Tg8?{>GZ/Ɠ`<<.L7@9|.6f+m_~Sh{^,]ue nyxԺ`껲:̘ݱ&djCk~unS;2lu:qrxQ˾ dN|]t_8{7oW޷#_f9.o ;P{7ci Zk/.<pK_nnwS@sUxtld'*#*Ctn„=v- P19Ul~3꥘WJ؃Eea[:I=QEWQ>{Yoj_Mw:0G.^]ެh{o\,yR1 pkd9 Z\Nm`\iwX*rS;;.IRƿٺK| =K'r"ehh@39_-;%9/NFe3_:[IN;+8ٗe`? puTT_Av)|xtt'Ae}ьoW][uô6k9GRnOM_2{q{`DXy@8F1x118KeRy? nn__I;g_P Za_czF gjư9305 @&a#aJB l>stPFǹ~h`FK>ʛ_즃J:ڃ. c  &qhvãּИh6`b,ϑ1`(_jL= .ްН修ۿxioru տWo~7 /H{~Ϳ7: 7ſW&~}r3{~W:N7/ߵo39~~Wdd #9f\[yէ䘎Iҫa#Vk[#]z3=I"ݦG;NzVBig 3oVaNҳ;=kNsikG :\!˯sn50@)fWD)+GVvsjf)*P Z@l:|k*>Mj׬3~xMa={%h $x$imzI]eφ;_|NhyFvttkW/3rQ~(OAp1Bec !p]V `D|/v<DZT'mztɡfz9"i$ ŰhsvAX%4DCm~&n>Bkdtp9<Tٝu,,ʇx$i@W~N8N5'=FޯSj#N2Fo)"Uf2ֈ+>64s& iy#w9/9:nAþnU5<@qN*^WO?~ѥ6) T7 6;AF}VZfjvt v3^ 4ԃ!iMrxHQ~:wLx? ȦvsV3D]^*li7H_˕C_:e;ՋtO66:{C rLt(oP:ޝzjwO٠%4 Ewm#P՝ٻ8gGؚ a+/uu:TԴm?dka{|@d|Ϟ~n44 v!$mփB`}a8ﵣ=}-y7,X::S$#d)CvϦ ctv3x6g#$Og?bu@ſ-' yP:Xߏ 9=ͬ·TO n8<N1bH$J}#QSgOTf ZgžA.lR:+Mށ;`GmOƯ6I€FGG< #]ģՃNZ_"P_ TD#?бE:<u»oގL~K.;A^v]6=@NMM32?#uVOd~/~f^O{+7Of_ n'ɓȀR[%jlD|Z\67)J0}S޿xUFRz9Fo^+0Y!6]yHz'K׾ַ6~a]ǯ%ί%-UoԟSK4AG_ggo~_w?݂oBgbOqCt]K@u|sd4:0줣T`ڱXmtE/,0-^Clws6cBy}ڴا: Phm$ܳiW@0;[ϝ/$6Qvn6Z8]o2W4eS{yzކh֡tT!mugc2Fv6LEc4~O~ԮDVB6O/rN'h\-M OF'%Ss'tbj0zxTq{ܽf2#H'Y SI<'@TvYy-(Vou2)yfmm `dru?Z'•Ǜ[q_Yh$/ v[cpttݼo ZfcML(^rR` 8P0vu!~atn|KjútԹ1K|m6 u,tm*|~E=[$9d:bK:mmvJ4n (<ď*2v^,}xި;+셥:y'NgYx2.>×QRHHvJ7'VCGM),uhԠfyטl :^oB|ţWƽ:>7?~\jk&[yd۔ =~~hs2/Ai'1,"]|l$>jipFMd<˓I:Tv/@\ߛEQP'ͱbzm"L!e6 M#^5:}:%}$Tvju^>62\:M1"w.to2 ә=p`6 9>{ϏxtM&Dy1}l:k÷,Syl O2ztŷF1 Wnu0LJKNm0nF/uXԡQbkj)@8GLZvtȗ7fq@U,k$_bGn/qܦֳQ3@ukiD߼y<Õ03\"׽(-84[i3zo˒6+|َK26ҧuf;O05 dHaXDz~= 07LaN!,3Ap60aCgx_;Z6l?rv hj51=nenܣt_wy{ &a!6sV< ?}83:I}~W;-l=T)#ݭ[66sWٖ[3 IgL~Gu  4O'Gyݫw }9@p`l,haZ@_}Wybԥ5p;/G rn .v@BC%@`©HrLF(Ko}%`}:,f>A OF;^Wr&ɊX o÷4bGf;^[kݭak'_ &5X6x~ Cܮ= >n#Sŏ1㫳:?3UVT0[gޭ zwd5M9:B*r8~nB@\P(лFm<v:ެ45xQ^GPuڣ:jJ9sqmf< fiҷ?`5)^Mu=p=-6)~ ^*Yt8ϯ)xǁWh>yXg @])3\Ψ3)px<ѭL!8=;>ݍ<@n 3_Z_<& Gff4{Q˲ݬJ]<^_:..toF߷}m߲Qi;ȝ%[VB7{u!Ji~<O߫:B#|r:=TBľVG~؊VV0N)Tߎ}dxB\},-eV];,`l_+2j]XC\dd0l{uG_1K:b|D y 9ۓw %}pF?j]axGum&PzWH۝ YLcc\/]?HO#u e|>/xON{|wd|Gy9nNPgC2Lu"Ld%x𝁨Osc{qxе2NP~ ?Xl׌ :2t7iʯl|k;?*To_j SǟTn? #QWqrU~+8tNS3`4JA\mJb;'R:Fvݧ* $/~٨b قzf.~h`n{c G$*KGFk{ N a{4[#),s6B9 Ƹ~rJudWsQؿ_I( u 8GkS|ԡbUf-uwL5ܞWMI7\~6qRuZ__]_hϿU*E@Vbej>1VĤ\lCRa*uSxAS#lFӖ}~XJ6_N<'8+OAl2Xb: &vF,8{mfg+f\Ln[YGgFlgl~ÙdRߧ|+j9rB7Wve9_ P_KoGol6Cztrr{^VknY.{f6km{z>lJL=yf }9UD &[ 7su+hVқǏꀣ[1" 5u/Nyr6\s/YCr>ҍn!͌W B^/<IJq8=! Zn*WMO,Fz{79DA #guOE5gMAKz>;?]ۻ8[aTUZq/}O5Zh8C/ Egu݃%A('gCF2pLj\㜞OHƟQĩ V0fGX}5]xW`ƛKyb yk;x]A`nw\ϗ׿Nf Gr_J|;6ooïV?pc;_A0k@'/ v\_[+& t6\z|RIEx![J;-qWedd Y'JRkd6Ҧs n{t6[yfM;L1_0Vf3=/6X<v @N'd:sZr:KËrA88v-*=hqOoA޲~)Gy{g%K-˘phml"+cNzCv0 gC+^{ SW_>mgeaϱIN+ă,3`+XS^[&1iK퍳͏kDΧRG7j\ɵ׏AΑu0{|1tx6NzRNo %Ë`͗G/ku$lC#7aw!aKׅ*)[/^P 7/ 㰨Óxk>;nx=G gt`Ǩu:d/,ߨ3|,ky%(:o6c'AԢeGEub6q^āUox+H0회zسnٚwnmzL[ :*LWw_sL^>PGu޼+SWɾλ]roբBw7:ηo0'7ܢ ?n-:޴mB,F/Ёz<ެu>yXSEf&M/“|fV}N06haˮfTOZՉr{`so,~$0x84 LeL:,pnrNo?y?zF ;8^s=)WDZHo!BFr8!c e>U8!] gV+ Il jN'S{M[I> zKN.'Ƚ =_lf{Ul\ U3"g^y` ZQ\4GF=k'BuͅD:!q~Ky9^wKC2 #Mnntc3zp_t:J'Aƨ:?Wc{޼`Z{@v竎qFCCz0SӫO7s+w޵~Nms8|1HJ`3|/[BU{a.3 (h}dwgM.9i3؃p'N~/gk7 +]ztywsbo;sNLp5e-+ClhV)D Ǜ]iκWTL6vo᥽쑇dp9a]ƀ)j\rk戕O8@מ=oҗ'3 uoV9><Ʋ?K >g:jx6ZMwνΉ]mO>,0|N4Q_'6[7/M^Ӝѽ,r8gm On^ꗋﴯ'7W0Y"9FA8fݾo`i:^rR;:ģv=5 /ňFU松aD^`+:-:\u0Y{Wi'W)~MXs(_?nS$6ِGu&nJx+HhĬ+^jx길]pt{9{*Η]t'Cqu oϱW` 2(A"^ x']^XSѻ& S쑫,O;Tǂ,]O&)#Oysz߿GC=:KVNdxvh|>B $*:Vnz~Q9bдC]!X{vs?z٪n:qn4 uV7!x=ϙs>}z _F2ZY2u=xaJ"E # S|2UDGDO LH#t ovRS҇Ƽ5~0 xQO/c]TҀG=Hۑu߳n Ϛِ.jFYmG49:Í6=7|/ҵQ3| W82C9FC4~?8SeR((\ش:?}2tl V |!I+gg?n~_V6=I7Ց.s8 cNmjzt8ԁ{"Sy/j2;¦5[=?c¹3b=k@8ʫ=۾/mJ5;]pCSSϲ ~6TZ˱Tskoـѻ!Whڞ Ȃ ׹9}]<Ҁ Ѳh ך{ml6 vo#Z׫6xpZEb/{悡=9GK/O쮜^[lck9ڟo~jmOiucq`R^z9vFI-Whmv^m ׶{mXY9ua\ I96ŵȚӇQ#L4 N%`32g,O}0pL(U3rn7śu$ṇ, <['ιBѵUx}UeguH_? _fM7{dNᇥnLO+^^"--|$A_e?k?"{M/<>kx|1g 2g]7hrkiy-0 u'x{՛Oީk0o򠿙| z'/'2^' {/;񍬓D(Nc;N~ t T-j@PZ6bW9t98OmThI?;rL'{jxH}VW'SO R'gTzy|94៞mH[z31ɩ{#58_jS3wW^y F}>ᯍO^.թ1S`=~r/؏-˨V6 o{4O&=64zF=&[x=O6kO0yA!̖`u`x'::zzt%o6H$%[ncQ_T=OyZYʋOFu3x ]d=6K&dbx][Ӳ}D5;d*DNNf PtWLrAFs^y– &>4/:)|Ԋz/'#_NǷTˣ1!aÎSAnf+Z*o1 .>KdةVy+7O>đ2:٧$^SuH_Dt>{BvuriÓ[mڧ񇼭+r.<#}][wڕhFt֟:#@OѶY3*EX'F9uw~Ibz W44Mj  }Zeʶ-Dn@o7?wu 20"b@#]E=.^yyZ#[CO4k bx ~^K^SRZ hmtsTJz<& 9%{Gh,e; fG\7‭g.Rbu Osx9)'xhՓy<x]w^6p&V5p?/^M䣔` ώ8WL?ґ؂6;Bhm7G4gC:sZә0DZ5iJi Ɲ;) ̂\tbtvlU Lss\Ow )G}X2<ӎI0qϕM\NgA$>dM,;v#y7p @ڏ/tBxY+Ɇ?j /ڻc{HM)};afd1FW/48axE/gүOAaixy +w}bܧq6wEfQH>~c%+>v~2ƙ\yxIo 0>A” 7>; |{ Wb*x172/@Vt`3tkoT H_z?M^GS[3~?{4SCyhLq3LCppKAM+3IG'?~~tiTϿ6Ռ/3ڷ( NKY]^(42w T.Xpq+׮GSaSxr)DZu T2~,=U09u/v^hAQu_Qj&M<7>: ʟ]fܮM|Ъix&t f͵u~ ꙝ ۗN3^( +ɗJ//DӂžuFu8V!Ni4kl/О(MYgKWNH~]/*'c|e:>.)p?yt7} |Zx@]:8?gS:<GS^̶lOvÏl :/iscuq+Ὗu*-xj?vYŞy%Uցyu̟Q3v'=~A=z~\yH,B >mV:z]۟mq _S]xc=v3RE>;%s@,5N'7u==as) :binݼa~jw"\%N)%?4A{эPKnQ~'܃wJ3i OL ='K{8ℓ |mi#Es68iu*46'qٿ|N`UKoYx)}z>9/ۼ—Z뵣$4_8mK.[s4Z= JQtzɊ_kl#sM5ߦd]<opIOj~_n)CG<'8 M['=ge9tk8PDPr) }搳8P <+:F e %,twقBN'G~Pg֧N?Sa87;u<_Bo#Zž IDAT;ӳf@?*ۛbƗYr4}tfjD˽7[zѭ&?5<|.M?Y54XȖ~ _JH$ F9xoDi㋸!GG0[ sɸ]_ v\euesζ\"`kAF~}ynJ^tpuґh.YۗXG##dz1g9GյNɈڢ+>^yWB}IyQikC8Dk_5ӂo;+O9fXFb];Im[#lW`H=mFii% ΢iu(XcV|?u엲t`S9,` +폇89Xx⭽Gt.խ:]h|C>u_h O$޽/l<\jNףN ^S0MlӾ69LOegV !a#ِ_^ JC4>KNmW~[N 'Wf}8t'sKsr <ϯϲ?~.Jl6 I#+] Kc4jo6 `2gրT6/׾+ul+ KȜ*gm^O>hJHtkd999~j'̒z-xmpg$p(R2͘L)>훟#A|JU435B]ʁ=-kwS]=_nsƸ]Iw h=#gWSkpN{]Ve &P{Uܳ9`lKTNSt,$ߡ4 ^pUpbz8WKwn>`U!za|ztN=H(Qp(yXRcc0/]bTB{s^#T3t#ñu/ChS Kl|ϝOpalp'Go\Eӿ GϮ:p.~{yJ+ {g_RO{7?Oa|zW aڋ8^\ߙ:t~[y)`S>B4/au.kK.FA1>ul/>~#qnm3fe];iy;fgGD>0]:<ڲ ]հ\ٔ'`A?,/z1Enħ>8+N>uݟtuhE寓 |ٌ=s.ZFшY^iN\pc`kDӖPe3gG1Il :ᗃ糌Vh ttVa>&jR{s tp}G8߮mS8_r0\,8V)AZG N'^Mwo~h@Q:n4 |0fN>y4B: `F:jV=]*-"it-XYV}>8`ޫ&0UuxT-_<s^& gfL$ M`4vӸ%M~VveY41[m7_y>69#nVӇx)߲'O޷Se;/񱓍=+|0?7uX#؏MGjiYP`E;S6<īPB6._x ̣xO>v7lw]ݼu|_>ӛwZڕMaRfGASrA*%oy3z/Dx(6D ]rvL+:W'r#P= vOjVlNu> j0L{*p88qYiluʣ7Zn'إrdiO~i5 X0<.g f{y㻩۸ٟLc" ]tUo`ql<\px̃U.&sxmm[4mi}clNqX>Ć_5i0yKs>11L[ fݧ?+dԈ/{_ߩe7[P}'yuFh]9hOlG'5'>y:D[6gdu슦"OWVX>c;~#{ rjiH֡+G'P(˦QGeA_4^ssԦanaJ '<Ճ>f 4BX煂co<σ,6[l@>. M+0_=`˪T,8t!瓏G͹%XnAuоGPi=TU"t5ި[:ؠ7BxhTZ@Rr!34gaNcJg_͜^R?K=>U9꽩tR|GwiFn_.>aijOgLwA؂oyt|{KKx>vs>+'?;ӆf~|=nͯ}?߬JrQ4~'7|u?!_{Q )hLYzw2/>8{.OW.;U6ldf.duƃp|֞ Z0NꦴD牎 V bzA !<.EFw7[f)ףCWݭ#r:{oU`SO?ٓu-uf3`:|5i/(n&b6F\}x|-Sۡc0ҟͺOdkwucـeIĄ-{z;Ez0<[@xmfy# Cw;3GT>ŷ~WY!#n29~bL8G1{@a|-=N|} 鼢>1--TCt .F!UY6bJ=SsM!̐9ʍ73>5Icq"OIW3(A}n>|ޥLS'cVeU0ܟ3,k bR ׿_gzѴіQ?4"Ѱ@]鵿}y翦^9?y^mZhLQKb;T^TӜڪ9܍tOyōCNks~KgM)) ^=&OSW=Xidz":~qM:џMO/ݼ%mzkku`Y3^CLe`#sB>M1+o3uN`]Covۛntx̆_ >A}Mg[^jTFa Yq6)M:N>C3 7}z8HAf5jb]{Q̶\wOY6*G!?WgR@: 26 \${㽠ݴc2:y FyfZ _l#☲/YyW/Ft/r$L'$A6KC(h.W//:)? ^}v߈qϝ gѓY2'y5٧M6: 4aSoSaZJ4M_];Mn'Zp]=ӥgmhtg,W^&g3+vSǨ?Bnعʒ3ڋ:߲RF0-M^\omr/Bu2; |z.-Z M,6Bޒ鵧O7Q;9H*.d?}eE* C#t]QĤ\=~6}T'ig=[ta89(ww[-`L|1ExTG~ (<27f)V/;=#YgmU:˗{?%;*[:g4pmcЪa[<{s|{t$v5x<=B cLKGGliDu#wY"[)a`OG,^}U6_ 62xS&{ {kz]7/XP1,*,eKGKCA/׹FuRgK0rgPNyG<oMu8]g>o$hl~f} ɜL{rѳ{}f d&ۙ>7'LA@B3'h?/AW Y:`W~侃^zV%pLrv`M9lle6Sޯ#`#3bg FwiO?D}=] ݙ;t'8éI;geR})CpF t-(Ql ,bDjWs:gӺ9E*e{i99.p*/촻Փ Rp\rpQ񁝼[@s9d㖣 hM87^yGJ880uVf_h$O9Q{`;Yt@&VV:$i 'vpE^97 ˻oDokj [Z\yf2\3+?X'KزѸ>䷹?T{㌮o>z'G7xz>xe t,7|u8eYG+^G:ݧ8Ig@"{ߪ2Oyu/̓x1n+ g7 Ϩ]N4kF;#l=.s7gjn| 6z*˦d G9 zJl7 IDAT\^l ~2EEW7z/T%qt먣}:چXdh,6 N:4:W.@{Lj ?:$znzߨ+,WK,\Gmaunj?U9fcJ1f<u"s~2ʀ^rF(hƠwK@:ѽgnd.ַ8=/ 3=vJFw>Xa _3]˲~P_[v)O}UaxK#D<{b]0(_2SҮ#Fdo>{^Yw^\3ľ?Q_pHOU p3{?[oULv~kKz7\ƔNkWk*~~o}7U^e.If_訤1E ]W98L_P@ώ3^Cxπv ߁}7<3SǭIIp]wqή`pqnrnL5vy3E4gs&5ֻxulYd:R4M\/[kц_S5bl>{p?w'=tSt5jFu"5B"9:7:Vj9gԸ/Iڄvi6-gޑfzWY 4?@k|9Â6ŃuW_RF^FY)?͆2}\`4`8p"Z*&(Os }QCr Z\M OEv1^pZr4Z2] DOOF,V]O]" NDQ yA;ܝdC𱵚hc;K:gӷ/qN т񉣊d*=lazqAHzRn%{^ǜJ7ЀR_I6'. A"8uM&_In #VWtⷿY]9ke%;F&9*x6s_`ߍ/w:oD~YNty"EК[3^ʗn>n~蕺T@JVw8`+F>鈎qrFgq\L' Lx,.@HNɩ`t^# ~Nr=YN0< >cfE_h%IyE7nǟ}7jf< ._(ϬG?Տ{?Nk)bzY#Chto#nVedt2ŁW~ *`\ׁrsT"ΜE腎2SVx =N'O!x36])]u&XdndnTᨃnK}3JmeGO*9!ޕ )\;i7ҳe^AlǂCSkto8\h< u9o\GKwɇu>kҳ'į+d `=Lroãλ/7ۧeJ e֛ CN2㡐xrzcQwkd[7~n]/P`wx kˣpO|!W3L) h5|7Cn4p= qP?0bG]Ar4yJw0'K_RmQT﮿#l sxrE$GL<ݾMKYj91^ "'?[sy &{6N/S,Jagq7&s0(m:z|:tZ3d,bAv=2: m;_;8uH /۵w9``r383F8`p h4D9{GA_?qRq}tVSPVԴ[a>w鵵6N`Xѹ(g?ك=[~7o4i 8t*H3*~b;?jv6)R\eu^ mqqoA4ǩ(`׌ AКJrd?:(Np^xX^sYP9cmʒO[8I݋iT[KfF[uNkKTt8y҈fj-|սk_%Ü|=JnF ~g7iQP;wr/\v߇ Y|jv ~`x[o)\~Gճ`?m[֦Z|ۈ]ΘTzZ#:x=NG;t=''? v聎GS.{wh{r!So:.7ɗ`8z7y+C] `o/=>=r7any6ʉJ0`e>i{VH"t2|65vgV&`C# %ta`S{=+79ӳ |^Vڏ9=ą9T ܡQ;}I2aOTgLi>`V\ 6RQG=guSkZN0=)O8BYi\(' ?Iؽ'6[ &ѳB*=~nڍk/[ϵ+gW/}~k7>8\vp~|ދ?4?ό\o|p7ދ$ea{lEF#+jcJM,fFɕ}Sq=쑀pPxP,x$[[gY p#f3ǥ8hD 5xW,_=c"fg\|+nEDRJV` +Oѹ5foOEoy=!-(fOOk3]|%"Wko|%[˳Gc W,6k..Ȅz{Fh3ơPgxuVX&'Xl}cI7w4u^V./}xnn3Th7ϱNy`f7*wuIgv> :PE'dΛ_(rAMNsBdbXcm(_z{߭qƴH sJƥz0=*aI. f\Qi;fvDXv獘 N5M♂~ҳ|;{Pd> Lܳ&^w|xnC.o>wt0 7LݔUlǢڃy2rҗCZ󫍛չi/H F[^~aBԦj~ hΛ_k3 Bj։ʏԞ1\\z[F 9H/-X{ˑu%w#L~y20Nt9?6>(x2AYZ+NLJg1O 0s0ѽ vř5[9 [sїj1q|~O}%J%Ÿ_#GBs`I-lw;!O>iA5`dž]Vgك ~}q8T&hS{QKYm$Y }=|!~£p}6Rg XB]?\+h]#X03󹺮o ̓^ߴ걌wwܞ%9@{߯0u)D~ =?Tk=hwsu h";okKjtoH=/4}=I:( ѿ:NouCtfv|4p'G^쳒BrK'p2{0ˎ7oꪮW`&6/j0,+cc1g 6 6f KoA]w{~uȈ̈<7ED>WK#x;(şoq<ռ:%!"~c[|Y"7ʨG^z4 OG}V]z4?eNsUL h]8{ՐBK&'/WM:8PL!ʍ<뮮6kP&WSݰ"P1 [xO 4GKKvY@M{'9*ljt:;Qgf8<F 9R3p_q8޹0~tӴƿgع;mә}:\̊q#F2g\G0W=-WMa`=L^6pH r]Z߼K'sVx+{z 6Kixϼ ? Wϗ ._8`G>ucʏ~4g4h&J tfۣ1hA1"DPG-/t( g7$ǬWA6e1jְq0 q ;f1ggY7*]IDG%w琦8tUqIQgU7 * \sڮqsƯM&겹Xs>s(} QF3&q!;˶,eb ^3s5*£gOx"l=R otu< =SiA̤~0p.ُBݐ_  G'J6L~xMqr#⫡1 ];k'Qp[͈'حÙcp^&k5 3 .S WgʊEF䓸ʿ:e te9nǺDZװߢQf6'%+!i\;UvƏ.{ĉ(C{iHQn׶{m ~>M#,uYyn_@qXHеJU2[# ] ,QOT4M,n:26%+̙re( "c_P6z?O;bѩ(؎6Lor&E0_JOʱM˷DuO"QSOz4"`j;TkPv9/k(3@So^#s(7gY|wp}d?1:%pH`eځr"xo3`"Ls hp0gS&Dc2}&sLq\ N׹,-δno=a_ҥKc|7[>7ȅԋ<zdVmX07´aT^tReڸL:`QDz;Df.#9fF"3Ex_qšŅ 8ΦAygߢL5B\FE4j Od$"P-:uU=Tb142;(=* 0 FCRb`[?'FKx9kرe)F 8_"'JYn #ΚLxj@$I\>ٻBzst\(3F}"?([EHq(XFP ]h|H՘ ]c/Yzl #zgdbK'); g Sɏq}f)Sɺu|e~!Lk#Bi45#gk5¤9 O= ; muCf{m"+`m2o$-C3'eGY1smN G/m Z0tNyfݙOb&([G'e|ɣl431tQl:Yӧ#<'n>72'!t"><20ִ}ʊA̔g^N:߸iI7? 6%t]AmO%#XkD3()<-xpi=đ63+ߺD89,K\8{ҶnkLHOr';;32#o81C/E亖pq@Wڼ<0\PH |0,uL/Y^!2ـz/yO\fDBjP)W^kN#{z@k>B}u1k|yc^ֿ2^ bݤ.(ڎ(Wh|B5|.d( IDATebhѱZ,;W 8U{Ǧ}e{uWf,n3E8> N,tvA)Xw0}~"~#Lg[.4eVd<bW$Vy.lۛ6,y3tV ކ^O.kݻ5ruOxc2kI'9ggpLW %~"YH1i Rݟb cה)&PWl^1gd28j{WKl%)֙3Uh_?)qʻۣ|ti"S(+rϺv_F 8#\[~ #- qy3\krImy )C<8B>><M>~sNr6Nc$6 saEC uax Q(6.|~&G| ОI?4*o1{h]q@O?;EPj3I`e$NX+.I^y)6ؒ>g\-#ݛBzp<j+u<9K-p8gআ0Ř BIwb6")>AA{Grqv'V*`n(+ J:AO[(7 I%C 9eMpF U'3hQ BTKI ۅ<$8_/,//[rU*S(ǟrc_X~+.Q + 5@T~N"ʚb΂9V$j|ieF<0C]N=e$c] ָcOx` t.?WM^2шQ)Ȍ(kzp$D놙F45F| sDy _fA24U5b%^rMԡ\[-?WÑ_fvn#D|126b@>Fwn A>(ѐ%s~#|$ƒ3x9(}=O)-O8ȑo o|hb4Gwo޳~ড"A"\RZH'#z.V=!FqFJԁT<rKG Rbg6CDNiu$hJz l%.nN }eR,w G,_0V١bMT=w>]ik hgNi;ʄmʱeqe*?җr;v/9-o{FҷS|J(I@G6xG.}8eD~w sCKחޞl8\puvp2u<tX^R }Y[MbXw?oG>7 snٳkWoNM8EȊef?7}&p{fEelr`⡕ou6QK#g0 mbZNĉLZϹY?7̶0`4sa|bpFfQH$؟y%DɄtDrD vHQÇ|;dEGL/Frv^B2'eǠa4AJ*Tav F)]Lۋ}0m0d*0A?qB;rrn0Bg]?a0RwzbhAiVWŪ<2ÿx93'n$ F~ɳgSe¨ʌ|>ik\ZjH63D]gY%Nh!>6Gf#5JSpw '?:kp, BUFXa33 /Fq?=q",.#|IDjg  A( ]Nas^X"ѓ/\mD FٟJ@:ΌoS֋?T' ua,-=Oa:OeCNؼTmGɋ3d!IfM4)~N:}ByƑ =isC~ܰߴʙQB "S$6瑎/DYJ Iӄs|b\[>'?F.ofQ/m8_H[,V#ހ1>KX !I8u= F=r-mb`$t_XE=($fK%fW`VH(pr"kNGT~>As1ve:lwq_} zz,q4; W{&F80jfz@9&ZX4.Ki i{O`.OdW@vnZZ\3&=tgF;Kd_A_ H%*+Y;͗2; Ng bIGi9 8}]ɓZ^.`3@t_~[9'0^;28Bbu9nb5Z_ށ.Za):.g{3c  xzȄYF_Ow$7ݝlƩ̤c4b݃ȸأ~*3`j2sߡf?P @ >xhr3Q2qw݁0q1,th'$=!9Ѐm(:WKte,k37Ow٠oJ%Rkp:UC1,,4z!1V4r55D#j' ! pIphPW`PyU9,Nwq&F>hX 8j =֨nm\˿nR3Fխ-QHAǪdb.5x/gE]mgYAe%6"(@΢oLLR Q-'Po=dd!&~n{=8L/wi= 78m;yǵq2|q>mʖ,ұ6DZ6*eAK{My׼k2mLxFă f"m廂uRsD'B9LY!L M>k!{ːW~(e{I>FjYmZ?*-: f%2 -[*|'ťO,FEK_,<=?;xֵ4$O>{uoa7;p5:Fd=#Kѝ MaӁ q1@e7F 6{s9Z3q͛ƙ_:NHAE glq vJ2kYꕡ~0X<\ 1YSV" Bf,$@## s*>G\VN'IJ.#ĞJx|G(UPѾ0pBLzi iI@!s 6,$5^(WӴf&&0@;oWɣrb!X{;, t1Tбg:Ghy?' , >r`5'Y\N8?essQ?\x/_Z=TV=s/. xq`E63svLhTs|gL90X7 ǝTnB %]Xynlplcwv;e1Q;eb:>Ύ1TޝD+٤Cؖ ,̸<35h+bTOe߬:IC-@„LD@sM3CT)'g_XI,ޔ{K\Ɔe27֝xaC~K S^h9dA ? ixN.)wMq ™Fa w),4vܱ0ij8s$}~@m IDAT3Bd"k A~v".Lm? K&raqX" tl2dZ; f(^E -5AS+.S8C'Ӑ塞ǒIgӁK'w'/"v3?){Eu#pˍ_.|oǽ? Kgyտ/ys鏟Xzo&mSwk(ox6n׿>i'yʕ嵯}m9xوqeexr '__ȯ1i?S#ĸ~{>^}p0p|B[L14\&x(׍EXpG(w(†K;n`h,ƨPv:Na1 }w|qQ2}pTjT eu[w{Sׂc|TI'ʪ<&>.XR9[]$ Q#o817|OWsz,3'z"I^ 'gգ 'R"Uo:zqRaYM*m8dS{0gjk pKPމ|zƫƶznrxKFTI@RnzaP_|M[\Ņwi7wy K@7zs/N嚥'yS4) %py):΀adtqO *xְuN8a>W.5]?K1̬ hF x# 9Zr+s?+ʜt.\J9Lz$i\%.O  faݨȲXz+]pFLN2] }f#xo߇iC5%ACԭ4LzZ7c5 \8-Rn^=0ELf7k7JYeuìܷvk-Vm>m[|u_Qsӹs|gﰭL O am;mRk<ǎ\K.g=+緾 g(woo+^񊹗:4=\uuו夓N*[5pay_8/}_\qo./WU^kڅ 2o* >(EY:Xcd*\GWe0"q(ƉsV1,J22z* (<{ŔmY(ZmZJ(I~mױ X3,O: b `d}FTPeB^|c*/ )qs,zZPN&sHeEUi6}E:|`00QY$Ux⬬<oy6uX?6/25rB`cggTB!媄3MEc& 4ޣÂ7uC4#\:bXSeoY7ݓ7Wב-s95<7g~uyj8wGȠ`F,9%AL A. bh0WkD aG$DSW.mE{ˌ%!N\ީ`v?{3E޲I8ƸlF&C CLYӈWMhNMj[x!8[%u9/RynFy)ѩCu|Sw: dEkZDŽry&<_{(km!x78}|9uKgAq ?Hya`}f 饉]2"QzLA}إA 8xi}q~@9!&0õi="2j&~b֔742Ƒ%ܦ,f 6W={h,Nv"ƛ ҳ44gf S1':`؆ cl` #け٩X:#S#1o)/#N3{ 3g[4k{fQN 4s/u2AFuTd=;C3䩳FY 㒀p0ys4~&3ӻ澏8ngӆ^?<_+~IC]. 6N6Y H_TMNsK}BSU*LzɈgx̥gYL-%rYH "6{ ǭ\6y7(x.G)W뗔>y}y/}ܚ2Nظ"tǗsN(|\{(ǟRfZ?9/ߩˀ"~1o~:y3}q}Byז 0~e|[UE8kǭ?:cD-' /ʆNzo?;͔OC pT M<#!٣~f#Mc L^zxNvYVTDr{g?Y__[o\}wO??8zgO}j>>^/w\WW[0+,{n>__K7`bŊre=?8ү}kW~WʩǤa=qas?s//ʏ>?\'pv \r-c%k)>oq6gnݫV-(;wGBu}_KA?3f c&RhDT^2:Æ-QE&Cf_/qk1~֡RdiP T5EX?u?vGߑD#'F!cT&i8i|07e?|k:̊ !yBhJbtO!(S#$hxYx*4z-;8>x`FȎ*7 6._Ű\[<*ș߾)'LΡazu;WG32y\I7QQ|SM%7uf9RW> f-@R1r%NX<pqXljΐGǛ1vs5eGI:<V[8 ƞ3+/]W7N&pF'ZgƶuL^Y2\^>#q.rܛ?Ϻ#g&b {jL_ ҺB7He Wqgh#cDAա4vJ l9 N|0FU"3 uȣc|0l7;mlpʤeǼsv~G "30h^?5͑=Ⱥ^li99fpeYf2 fZaY hP9mQdָT rcKKsL5KuqR67c%#pL ;6O8h`)'Z?do*}l6}˖w3m ZZ1""~[wAʺ'5؅#Nnsh 'Pʍ#~ tX ۟vF&i{S,cm^&zr#Hx4j#'Gvl-ڰWRQDyhx瘳hetݩ'j@9 NYBw5(;mG{F;}.`rz/L" H*;|_)LPq FɀT:4F+`L50W. uQl|H:zs7& maVشZ&Elaፇ[ VZTK zz? I(YO#qpΒuy/<"\41)ƒ'8!>&V`_ĉv@yBK$BF9R&t@kEvfUIC.jRHz<|Cf@. 9YO1)_.۩?+Qi2俖S )㗔u&fE\[EG(ܰ\zŦrp 38O47O}gqy%aKf]R06EƠ5x'+jk.[2L9tc?Ci[yN'P '`;ˍ[h*.7}G,_/mOxڥ#wWꌸ~T.XxF܀|*NI>7-{ˉo>.%K';?~/Op.}Mj3ҥ/R{*}{f͚.3\sM袋5`  44G=v[ꪫOO$~ɟɔ K/4]*p7Qя~ov-R>Ouֲ??//wzF# Yº;/3|?>y},<>h7u{]?]N<%9yNpY$ağr|%ٟr%_>9G!fO|呏|1?T0m`h[xX'ƹN.kޫ߱*qT-UƚшPѭ> csiT@W뺳5MwV Z-g*tۭkU}.|*֬ebReZ4(P@voo.c^]웼SC%r]6؞ \c[(.Z/ԽO2+ =}VIXVq%v ,Iʲ9Hc>ļ4qhyIu[ ?ljtFmv7ᜈ2K4 :pƂ1U1y.g^rC31sq>i 2|mPw1%HytM3 ᑛz :`e=u&԰ѯ5sGv /p#e/21-}cA{|I'?3`7ӌ,̴36gCR] gN&~=7%z3q;gVYG}?Cr)|]+ OuV. I {۹2r凾o~g5L] v<ڟX:thWXV&Bynn{蠱,=GB/2l5refY?xe8OMg"_뵆֓^yF&;+xF Zr{_:#S݇ȶJx(Q.+Pv=hʴQ6 e-0F]B"G@GJR4\ N8Imfϔ LP>g4:I`#t`C Z xP! 5u*4nרSQtf!H``247WӁX*.*KEGM ]2()xxr'U8̋9 ``W."=y 0_>׼S=_"F8s4xnx̿!Fg =~NlrQp|hO@i3xMyZ;3xQ08pEzO)/| w̕:gᵎZo$as\Cu*rx5t?:nr7S-ۛW+_i;5者,)p@n`f a7kѣ#Y( Vɇ1JU0C+yгO=@>L_;8ӘLjh]Yo'_,|tkӦsiSGH+uQ vv]#E1x/8u3~gǴah~1f|R~-Y\)kz~T} IiQ)*!KW!hFGQsF:. =3:IHDU-4y#?FCrR IDAT%"a}K"O9+sdgɣ{IG{yokO%}clzdAp?#ڟI7xefFQ"vg4f?c}Olc 7Ⰶg!ClX#$?}azl}.vgM}mzBLtH;0v!"Ƀ+C8Uvx:aauʰ4rԄV5)C+9}!r7>AX\ 2@ D* Y&Jg͗ 絣#RL%FVee! B+U@AyoǏz }MZ'#b5jOnsUtA1p`9W.jRz&.30W  =s#Jh N^!6<98Z7C(0*v4^-f79aof NZc_B `=tsRƋN9zգz~tc8|Pw'i)!v=c/p|C|ٟi-(Ssdy6;Yn$-j6mNc>B)KTLf,?Ѧ=cy{܅п-wy IFo,;#eW"vw= Z1:#+\"ե30pSCC{:>lOxDΐ_xe3ϼKv׼;|wqM~|ֿgWUM7mڔSO=uL'vish?3 `~yW&N #98@㾔ѰNqqw3F& d8AY|&.ۿ,p;w u_O+ =;Wo`&!cq'kEz G\XOm1ޟv Z)HY(qS|R>؞uF.EٟF_8OJM2̩7n맧śLDu7>GW V܇ʁM%MoתY '[>Ow '+cz7ʢ|Y_KѕnUZu Ъr-A胙vC:j,;#h8x4DiQ0#<5 9-h$ t]C]pùUĩ!?= b,Yі-ك*פU{[ҖeR/<05,,u@/;(}$21Hp p#e)WɡxǑ}rφn/)C|dyq2;Z֜@-0 g?mը (ǛSl=Uv ȡ8,CLiDAzI0?4P}1uT)=$iIrOIg~%]F,f6dT6_FC氘,ȝBؙus[ ?wOCGiPSGF)>iv 0;쑣A]pt|Үo6橯koNAOC[t'=3d]rS'/Żm5EpptZX/\pWGq1| 6}eEI#}ڜ.}L  $K/:6 20ߤW65S'<.L,w*q2!R4H[ZDu儨e b#ʋ +c['3ҥNYyd}s#.S果zq{\97oNh{{_֭˒i]:s#tF<яNqqwo|cB= t·g|GqLԢ_EW ܴ obhd'JMLB9XH;xG. 㐑U e&BuD#?:tZrsJ^Eї8.{pZ،QG?*ga(ekqo#]Bi1pp$1cȑwLCܬ6peF/׷z꛴:i ?o%mxkR*O?me)ʘ'^.=Q>x >c7O=L`1Ʃ Du38( y4٬6#L'@'b"Jg!0!jcL&²]Z~+ZFZ5X=8׮,[c4Ysa/|S췠mCI@iQalD}ۆO~A6~jd%i~]uվ77uS[N(SolHuڄEvɀ/u4t_ztI<'?#?8 ԑGu pEbxd6ɏ8Oy1} :)&K?4NkqY=ߔሻ@^3N@Y7_TG Y@Ci,# Fe5daF 7wL43 kD(50HMIZ'Kbä62Y`vN!ѤκaZGq% 'Ń̮Ñp|u 8d\~V(?MciKTR)\p~T=r=3.)˲谜Bdfmbhs}k8_kbᡲdæ%^/}_ xt$? eGT 5moHDz9Ν/,y֯0Dte)e}~نoJ/<<8!9j?:?7 `yFV!S6s=Z||'w}[7tve;XCnU_"3W&z>/g],K~>X^RK U`Mݕ̲]tQ CC~\CUCY\יּazg-BIݷٯW4n0`(3a'18ïgg\+>F_ ip5=߷YcAGc,8sϻ??ɾI^\zE< wgx߈p>J_휱9cT=P!f]FC93>p\1fY9&1fذ;M"ZCZu1plx!|d _"C.,َ ."eǫt؆hhagE/p0/3ҙ+L^CH2Wċ:I@:;+*e*@KGq@)O1H5F^"dOYIxOySpK=e8 vIN fT4(͵a2Cʲ3;Ԅkc8:Gz 7l~1n:= B[1AOx4,#|g&5//1@$~ ([\? gqw̢Ijqy+ ?;>pZtH[2{w Y+{j:(>(r3[3~G;a_AWyTӅMņ ? G'mDXNm/RGʴ18A^'2Hj;}Ԏǎldn0i:islϷgqfp_wд= tu!߁_u-1,K<dHBk{!Fój@8|xΎP$ H7k)$#%$<Ĉ22B&{ O v* [乙(\;K:'N顱gGܧgCY3{ߛ͛GNZgB]貶A y"<`tֵM6DZF46foc 3oe^F6`?ujyçh9{DZ}RtbzG+z|ysm=}y5۲op6 ~t=alYY5;8.u:'Ũ0[p<>XZS4rwvQel5N X0T>u[qv ɝm{XO_;ˎoUS(lj˗ˑWm_gM8{?~>_[&5eڵky]/ek=靡7tS9묳nk/|Ldܲ{qs ~cx>=_p٤o'Ogxwy}ߝmۖ*q4=/0~v>p>p:'}p??t=n=rbzV>QqIEA)uS 1 6,SNvCTq,oҢxi]F!Ɠc 3(wu|a` kU 0˨XCRC5CE `IpY?z!GTa?̆XG8; RNHcc UpQIh:YĪs2rP?W~"πivjVRvVs$*  HEs3C 8dbbi ϡ֧G m 0%,#zM_^'qu5O:xmxv<AQTޣq㉵$r6IH0 lJjOp7W(YNAOo3:A |O82ze_̈́M/ur&ظR0KM$h-~C[ʁ=l.pv0kvw ?m!W9+yu=8%bˆ ی|d4/=:C#J|KV \M!(H' 1kp+vjyQ>Wiy:Eke#Ahбi"Mkd_I} R϶1ۖg+τٛψec;.1uBfzn;|{ Z*z) R@Kz4ARH\='zոEug_YfT<(/a%2g`j\抻 3ށeʩ0eJڙy'؏= _\GW%1j}5ix)BǸNjL[]gGmg.!?|6z0 tI^|2xԉZ͔T'y)6%.##7J<71szwgO=! gc'N%I?<\o.)6ѯW\Q^o~Yu /Y]>_-kOL[0} yc97Dx0>e9e(*^]?#H&:c 1it2~|Yة(@QT~4 bq pzE!Dq ʙ>E(2<kȠdBvw5( "Th[guuUL0OLj:f>$ <`b<^" 8yݪGf n5F ,B`Sfhx<]@2oޛH}4<5P4Cd"Y89x22#Is/W$%]~Q^i?r  g#Gojt#]׏SI']!hʎȍ3: 8N9\ l "_ ⢋{U "5F]daq᠆7{siv;W׮ꫯ`[0dN&%0HiPH"0#iDrF ?FL00M x0쾺^]9ygSN%` uުkB` IDAT{{c7<ΤSD|̨ᒃr{vKֳF>KE#iZajd[~Gڝ7i6{,(&BfŹ۩]6=hLŶ (Ke^J/DѽĽ6 ߴUߊP/帾;vKF"uw^\Aj) : lꀷީ- ]u#%O F ɲChkpq$}'T ɹcOȜ& kn>38px~_jbw 2No9v&|qjǨ!uȌJqb<ہ'``\  3f瞛éTa^w50/\aZU`9s54hHys&p(| >O7"*,ѕ$%{%#pBĔi٦gǣOY(c<А]r0LMCRTC?A]%Qn z5k(ԙtԍՑv  : wc ;Pӟv8k)<eICkdܸq@zL!ۯ!^]yH23Mr73QֱxO !qd}*':us)yleƔ<#8"k4ͺ=b{?=.aqf.,lo(]BQF\a?.}PmpxFrվxII;m{⮓A]:Q~zS^Ci?.pyrh]s8\ 1ED ni c3,+t>{gv-;Lh/mdYBRԩm^BJAb[S?CրyxwfYUY CiC0]tv&>YoDD0$|F>m֧Yi[_`u-)ƣN }wtJ>C9yZT/Dz{}geԎ{(D%-]WCBIu t?9lk҄{ǧ#ζ/\^tjĝzLj|.Uylqbkyo#t&_S)owЯ|p<g¸’g;ݬ0OXvF ^vn  . $*] @ăMNPdOd8} :cDBv2ޤp[3gD2g ]܂ĕ #onXn2 O}73'/ӗ˧|=]} NXMfgf`Qppx + tLFF(N =|Cg6x-hMnEOp\?0pRy_?[|r|'N7?So/Oןn?/>) W]ēo`,kixrο}~3* @^1|A*v\v7rlYϢe<~3V8qTIwv&P cW?q3spKM% !e ;gl3"g.$ʋpӬ5Wn  4BUKVcK^ws꿺.xtt猡R܊O O ZQ''L$,B=HӉWB6aw҈3:+cA&h%mybX#LÕsþ㞲8(Gp|ab~܉97pK[Q͛׮܁NP#]D˶aa{N2(hk0ydԣiH Yʣ,k IF.|ȥ:2Q':ތ4P4.rc+4qD7Cl`w:]hW1)k'm~g@G\R{6wɧ y-8fFj`Ga:V80 6WI?\_u`qʙv`JU OW!}a`uk׉-WMߓ[,U~8x#': mҲXrj^{PL#o-&uxPHF~X > +!'ȹ'rwTN;;}QHxy=4~~[sm+Вy?+?v2j;e|^B^!qL~0, :ٳ^O6fͫ,uOo0I|%O@֏r3goMmм^z-e|N*|%hhԫ4"\ȏC#ҵHYYoNgsƐ33 p){4'Q@CO.Q?܂3x fHhj$OZFJ28 FaljYLY];p.q"Y<~Ԩ݄Rmw#4ۤNڒr d+#WcW'N4H<{\xիI'iʴez)mh6ys-Wi#u6 M\>e3w5 =q\W%b4xbQ}3mf}<v=BrK=2r~Զk?aZ YaѻSsT!,uJAvQOZQ\ZeOM|"TK|=#Fu`e}Iu./??ڧr SfJ:lk} ƠX!NҒKWVg#NCMK[,-y\m&LX& ~'_G3ex "36 yJiO4.&GN1:䛦[ ޱ9 "aY 8,Y!(j0Eyod89YxyI "a8[ӻ "}F-OVoo4LoBcʄxXfϣA\.izOhz?ʐfoSDgܨX#*w0o$bLKx}HSx4TzT] e5#:jUsQtsV؛2f-ABgJ 1pԅ2"֣e4k!&4N8G3 [\~m9ȁڵUGyTq 0|X9?%,`gm~LdpSYft:fJ-SR3YMR ^DO:_ 8=`3}7oGT>,Ue'ô*A';=Lr7 (k9BH2/i?q}c[v#r%;c2{2~1`ʉ!y[ҋlyt2>P69uKics251K'SS쵋asY)9y9(OU|"|hr1}NfΒ;ԭm6-{$"Ab;> ux%x',tt2bZ4/e)cyD^᷼_޾QTGnԻ` I6#q{2gYUiu,;[ q РRxpw) <8@b&(hf.[ꬿKh @虜g_nc`[7daǓበ35:d^~QQ# ,<Z5Yf d۱H`;_WzP?~e,d8)4|nwk!;A/6Ύ$AJO7oF ]*o:QY-^+Kop"•ʽKy[p ەm_x$>\>SrZᐜj_/d>$LDZ>:4l,tfZKxp#K\m_:]}Ye?nO?4nvr5 A,!@q%ǎ}@LÔhfwp,mt9h 1oF>"#-O-?r5t0DΆhl: Ҹ ϣs1]kˁ l:ַߢǙtel1O.;<ٍWos!Nhξ9B22?Ƴ# ל58+E/ pl8Xlp&nYT#Jxv;F9CŵMC24Jק4cz,U+),dKpGQ8NiERtIvf;n NS%Tv=HԬQ;**ra m ߩgL\u h$|ߩCl&GI\qL/oP3rQ4"}e~i  >oZK04zR!|~r={.ORIR^:844$ ox$\d1ʬ;k-u}oY.K-%Onvd d̳}B$1)fgۀ?'^w%sY/?XslBCഉ6XXɷaү|/kU+k֣Qc0|:M^g'zh'"(K+tK苢GĨ;F"Ŵ 5e\X)uBF?-GQmmcV %'֡{#*W[Lvz}37 G2#dRdSǁ vOMt Jv6!\mxG4ڗ#߳l `(0D6`Ժqm$.? .CZA*^6y{ wO/G#L8%оwka&bľ_΀#Sm._fMd0|{+̉4Z kSN1~,p.t\ԗ[>t:tYOK1'o=@3uЦ ?Ku9/_98.~b%>v( k;?CVMm]fm2߫h=j ;7w¤ѡY{|t ǩԐ< lT1zsUb$5Č2 wPb'q<\ZKʳifP(K5SPy+gvݘ!Nဣ 23}ٟ{t3Gî=ۦkb$U :px? O+TG爍C01_$[#75K*<ur Y@C&Cj|Cy#c>?rʊ,Av=U t?[.ϖ[l9k*0 F8ۙ”XXzT`pFgoo"1>9iH]Ufǘ>0:6MZpXf{y9̪-N5>p<*>!~Y\*y//w(܀i 1M2Na^rt]:\\Tzx2ѥ13AuY}ӣdUܘKC u*^Eu(ՙw0(W;dpJ} ax:Cw: 6M=SgrPԏS>Pq%8@exz+?r .Rd+)[sw9`/rmV=VYmP ~b='lsN-=Pc85Z+-A֫CG5r :Q4:{Sbǀy6'Cڣ P<9gqhL ֳS:ք{ozW}zݓ+(F~ko~ui:|OOwZ:ةpP A|c*,Ry']^_Fi~đ؈e5sm nEYz _'*(`Oξ2ր U IBQȰY%3&Akc2:Ti0^r;^k8cP9s"׀r᭗;k/T؍\v8QtV~7 4CkD쌜=eW=83 t&<ȣ;9f7K\.ޫ#/ɨFHCBIc|Y-NN,ԈҤ|^244kikާ/P;FsCE$0n_A/^""s8!bܟ5=)oH_ljFZagFnݯHUh3$;9搄hz91ߠ],Ctܺz:e6;p34]ݸl{H14Gp'mPp" bQF-/y'+enbC>Jf|91UwKC4ѹh3v0,3yn]O6mjPKv_' ?}I,fU4Fp 0Q;{ rO{gԫ7I ^} O+C@t)/צrt޺?`뷗۴:sxe99;,;>6ɆzxD2JM_03y#IG6s휓E0}coy`~%0,O9U&LζoqZo r#i `i$#sؽ;ypozQ&s($Cޏ*Af |Sؒe2>&Mc c3 &"`\KQ'e;0-Kf_}m >'E?1:OsD:: ;:'Lv2g 7uSD9NeRwv% vGyF[!en #S `O`Y7u홲s eG@{8.x~(e-~W4$9ϱ0:D}J/QE /i0>,Bsce%lHGNS{VWԫ^җZ7?|o`lABa4m1g~{"(mܒR'd@+7Or-GNieYU5S<muRv=FIŨ_s'v" |;[)$vx>+%E ʹ7BuȚf$Q)kXiO>ߡ^(3wCUaq5#8/ClsWXr(աQmʃ;R - eRF<>օG tEpAglІhV ooϖxg¶-^HaLRaB߹ ϟDi92٩8jg HXC[cʒ;!JIrle̮=ϐj\62@)6D4e8̘c&&kPǺS3>gKwa<5Rc} た lt/L1CBҊ|xp 9aKZ <*hM(Nu{C\gJf8C %,zT&U-dqKE\Ty!3(q gws IFHGP,Mz "E@<6nB>;q)`q̌Py> cVˣܖͩ BykXH?v4xХrR@Uڿ .C]b`z1rN{xZ:^L7)eYc2 ntdF;"'sD (z[ 4ϢktL'S ͕AG=*>^ 3π"!l%TL 93 δèwz8X^EdhVm:p\6m!#5Qd^86锡C|3ӽ/q,e 'Hu1Ҝ,QGu<'bBWNziSm̑ O?HXQohבno;| d| u%=(OjbM>)-Y2 ~4*A?E'!l3quۼ_lXy74=ggb3t{aPkBX2fϽ7̓YLrоY`+Z'(xoi%ܱ#{ZguK82z7'ʃc|UwAIM|HwOHC_ay>979@&lD+ꟊ- f]痈m0 Kc2FT0bOwG846mhh5X4w{ JK[px =*IH?~${!>`Ư/ox>}F7l`:я?G>9$M6h˙#Y6R./?KNn%汑Jzm@^Wg)`kZn /8a;) sTBXll9[|pfw OTYu2C1v4Nc&>c:1U,/Y׳y Z2㒆gl::.y;!`Y,6"[ Y/><{YI y $B9l޾ L9N;5^*0*Yn3<&2;Z gjTw:zh8jڔC`RTGH U ad]}x#x2fa8z;oj*^:4@(>4.;unmu rc,m;= uf ׺Cf2qO\oGE̖hB7nީ)$Ba{Bpun9$E '.R<~ j׬OtN,-288%}up;ر!< U벡U}92Dt|9r'`7L7`^n7ޚ(mi# ߅uD96x"Q]YEL#zೲb˄q Uq\ f!q ':QGhFY9/jywe{Om{Q{fō\U[ 0I3ڬ(+6PyeOxgwr$\~HMH~wU0 rusȳt,G*nx?4_%YvnaU^`uGX~!@!,t_Q"8;@:3mSoutvʺQw7:G|lewGy :Z35u*u[a`7sgQQu4aa;aIT Ϗ 7kF=–]"^;ߺV/=rPODLYP6̕{;O\q!n5V#c,7T60NrQB=p87 wlG>T ƝmPmai$ʋfZ)zG6lܒ|stOպk7engxN0KLSd^m4&KA 3GepO>|n~y#b{db8+Ov:WFkXܐF>i͠m;-H7"bHg ɇbL'uS=[;ż9jRi%eT6\ ]⭧4i]h$Iv#r:+!8Lˋ }iTuԩt#NRViR/p{LHГWx~9 rf״֕[GV.n 3"R=ʩ<2dOBL1"-|Ic=W7kϐL>[>Hy܈v.'"\Ua_Q+{;.ձf}x #LY2+\ȯuvDFX14TE,\1DfKDSAvv\$")\AU@LlT1PK#iM^4 x(4NlOL'EddrSo HH7ʠ/7-fR _0eyYK^ˠz,a8q6/.3,q)xx k9~|'*7^<pU¢l7ke ZAw|2}f 5ڻ_m-r`ˁ<ӝ 5 *^Bqq@yj3vfN^kr 1ױ ŧ! XPF8|z.F3x+.֍<#Tߙ#u avœ- pgU2WC)\ED?z:Bg[l5=Ȁ|;o}~_ڷût tizO`6p{maGoɮ/|g'9?e˰KiXsHWām]Xi5IdCRpPndz S-f)gka!aVȬX"29Dɷx-p~臦~:Cdvn;k"^ӧOO__;}}k-[9@_qc! *r_3w4+8N=וJMwe k%c댟 LbQGF 5T*Ha gz9P;~2߸ZUO0"xϽF7Xm^alࣞwDhx n֋3W熅w߈Uꂾ|r\yVYg@R7I tbd?Cdq]g_=~zsx84& V|u( d`';v#F $o_Ǐ;Q%֚By)% D qtǍi'2-P;tԻFm# -,\k|J>\+ȥ3HxZudԇu.i΀fڑ ۋ6WrfYqx5k(>K` .3e=n*HӹǓ#gՕ}6c2hi>@>ȴ%R> ,n_oeq6ݵoH8Z͘`>l?ZK!(#Cy%/EUFF/vG2yv#:?sTY횞v3oֹV?@5BPHo"ʑv3:1QOڔٓΚيpq.ݨ'Ce@ۺbtA;&--zp^|}'ھS" >[XdY_˻z`ib$"<'h.<.H+=c;S~/h9\#~eh:'l"0{*9@r_egzC$: 69I %xncFz;_Aw:rHLϧ(aC_ϟ^7M/]M/pyz[>SL?? p/ xW}s?ӥG.V#8,'$wݚ~3<!. +TV}~ <p|͙EZu@iZϯ[ y-jLMm'úQ'#_%N83}7| E2%ҵl#xr#hMLuۖb7$x#E7cՎ ?T? =qsq|Bkq%#^sm~8rXx42ǷwefcҀك tLWIX0ʪZiHMS0=ƒy'>*"=1!Nwp/o'uYԑ 1h;41Mtt6\3DF +nw:5| D$a"*Z S3nΆЎ)XZ)!T|x5yϖ1@xaga8J=N,H& oh)[#!HyΘ!8S\ܗK9茜uEv*?Yst7f{-]l)sypO%i3ۈF8W4 W5|tsN@`Raz]`:\2ŋ2TMDl=(4\r™o6d9h 7KPzGiw[L)i_K:p<ڑ#sR&F Vp*z6uf߫o1_sF -};Dyith OaE6"at޴>JtRؖJûG>yKǩ:߼u|a9Ǧ/2 eRI pa0zaP51Ȯ;2$p_˯'B <|#k0903$Ơx0QCO CSKJ2Jl o8R}[.q8N'{x0o_[XvlzYc2&Oy^~yzۿxzÓKv~0ʈ->ᎍRYP@7xnn> frQ?<'lO! G֥̫LYfj<_׹P[nW->9p=ޝvSǾ\7?7o;_o?{?o1rOҌV%cF  PTL eFns3bX<"3cG%Oc TUy  rV:5XeHjjejPh9OkvXG*/烆I|אqpL p4F8rb7x&W{9S?Ø"5){]+5^)̜S._`3C2 Q= q'Bcu7_%uC|a!0WݸOcw#<ݞ)@ҝk$.Έ ʑ}Q Z%׏kY|0@)F[s{)P{9,#6xj%FIwWBg512 p0?g!i&kQl_ē4A!g$=xC~PA[r,)wyXxN%GV.}J[mYǾvmC~smT'.M)g2zCw0i&9衬<4#[t _] i3㳩7m-^9!8ߙ<=xrzYaziseӏ/Nϛ@oxq`֬6㜻/<\:CV->;X: D'i(Lc2EƵzU40Ė(ןya QscpPgZdQ(v =np#W|'9#l^->uv+:\5cy$/)sIߤi9O,H1ӯdKh:9m7"Bd _kk=aX[.H yFVmL:lfxӁ1<7wʇSeͺh/2{¥^m(Lli<{ b_- g{Wk :y'Û n'/n":W$$uy[! Z9^d'OzXto-;OA@4qgLǴF]7u!Ykbx1:f&m7LKxm xQaCCt/zl&ƶCq4=sd\?[AD]|WNǟ9YN?qଦy"_iW8MׯߜO?#?Zgy駟eLݝei__7.O:7gbG녲MO1YI÷7Zix7s2/F8X(4ͺyIC"YTnغC cwˁO]zmmb.\09K?~q_=~[˿1.\NpIcOLӏ?ul3"] 3*E6Ϙ[$cyzJ-Xkn699F7s qo{4egppt_RbFE;9:D 1钅c p9H!Rث3ң*,C?68rS.Y2V0SVUŸZ81%l( ,yΟnp,L+UcK@CZT}2<a# dzkSL Ӻ.pº[fl10,?A5SL>^+6H_j|*TT"j"#&z훀n~^9 IDATl.I1mR#V Qݩe йԥ9rT'Dj6kZM3O*\h5FCwNYn} rPԑ |e8:'@eQf[-KA^W@_+Q\azuKyptE0YHf 5sDh$inxs#LȢ}\|mF;!z6[~y/ #=&ָ[8 rcԅQ"qJuajpgnWV Twtbܩ ΩSih4@ECDFBܐ}4^.mQrB9 ׻KNrSv)6a`#˪Ec =Kׁդv6\G-t8Cl@s5q?vF8A之OLׯ< /sݛzR=;0cOۣ]Dwwwgs|}Wׯz.~_q |yA@G}b}(V6O񓿭g%0&>pw o*p(7" ʶX`zJ^!hsWމצޤW2or#?#{iǜqhCoLOc?9ߠؖcٷ?=OO_xv1}<;ln9YfFl?h9&/Qr,Q Ũjc(Rv883xS4QQnbR2TYCgQaWLe'iTTр( wW)e;eoԨPs6ogo_BK R՝P5 1xPv|/410 WgY`lp:v iwGXtX G:¨⫲hQD"z/gb%`D.NO]AK)+7#FY35}#]wG8Ps}:١X_R9p8#MT[#OlЖ㱆HBo݅WkG?:%eJ e:Oa4 q:Na! zjlvɤNݝ?Ǿ9"DdxZoϝ8.l٘8 z8'By{C5'1 ~mo^Q=J$'C/Rf;4:# yqGM*gF"5_Bo;2?2:POU|kTG~ӕ>v=y+cMeA? 0OU5KWGV'8 o)$"dc4w0ml ٳلŋ5Cm:o[VwXnzVy8iH|jsbak9 ?.hi{tDpq SF=4~/Gtm~IþXÝ~~ecԏ[Q@kr/#:L\(^SS'e !KwqpD'OԉϭO]O.Z@[l>~M[ ddS}x g^8 ,#Sxx7DM!-ݔH,w4`g婃f^4o`A9 y%:1`4uF#$k!"@w8V浂oőְ͗ƵX+y禿stIP7i?_> d*x K]dQ!v$KHLn# R'\W'@wxթ~<⣁wm5 AY ^ԭM p?KK}hhy{>?^7L_ozӛ?*k5_5ӷGʟ }O﫮C/41AQ"s_cӇiǼ{gc暦Wk8<]jO2>U2)"w @J'R5ڴ (n;8s%e25n>WupIe,Rpt*f98JfqGea rT*Cxs?y:T= giXѦS1Drov1uX0||":a*ol~?Lx)N[4l` ,wli*2r ,i X7 fdx1IgrFsMLpSv~0r%vDexfug&$d-vȒ fxZ~fHW ?F(9˔ J/ q<1N 9^Q q:e7!z |!D[/h[LfǙ8M/Lh[Z̀'3o 2rWjҊA/;fY8e}]|o+4+F {*)}}V>I}lRr:vN/>/#K҆"6mrË{ ܣl`WqGe\jyAE CҚ޼vHt@.:6f5ÏdӜg@(,t P.FdBgNއ5[E_NPd*|<_8ձ~ C\J`ٌ\9rjl4Q>'-_3HtieNNeotUD|ֿeW Ux56Hlt>*D&}KN}ّWKғ,JYN@+{Z_c9z=ѺnE UXdk9J1q EZDJ~_aM5=:zv޳ba (""P $#G`#QȾ%, 0QP" @$NwݷnWs'8>}SN:ԩg<d9,\sM/~夓N#oy[~1Q:3n5#:tB6/ޮnjB,]~yl0Lnfo|Cܟ|vw ||/x{Hr@@D1`q^ 4Xqr8SwWuq+TQTCl c`z5TWT40a?-zl=㪬Gư|򈊡pP v B `ac\4D'H;ww*YK/3*9qU%2)K5BHc[㌫rOo`K|N1pXl9yGl$ ٭ FG+`4-$gu1q2|g#c uQ fU $Iшb68 v#@ĸ$n$M;kLmA4*< vXl5 t?Da,vlajn`3z7Yul0%ΰME$f30a "Mjඁp 1Op?yn=yD7#ʟ \EBU棯m(үj2|0e\"J4Rn2GD~]] gcI/a-[dwkyPx;ek~-*)RQN?tr;߹Mo|1G=(θα<8K^r'}Z#3fN&^8]vYq6۲xAf|ЇO93꽼Gm߾<@r}򓟼͕h%!xh։͒u=&04Mh7#dco.-s?[ݓ%?}νQ~\-\rIꪫʧ>GwHoSO=5|G<"͵Sp]@)g'k 5a@@6A_rvmAݳݤTM1"m\ ШVQW`G09úX.DW Sԫ?RL]Z x5D四eo$-rqugHE -x#LZK>g~R~Sz9AdlټKئLAIwWSA&Á3DH6qfe MU=~W4^rD&qO^R6t߼7@BU)gIÀ3)AI[H,cHa?QϼS0e,pYiӎi˄R4zЎv /it*z<8 2`nCS%u]c[QƵ|ĥgr ]MhA<"Ia#RKT"N]%|Z-LY$,<&r2v>hglIKNXhemT@C͓"T3mv蚇K4l.x  MyЕѐE`+S:q0 ..~^R0HS7OnT5o/yx.a 74.5ma"*ökPT9>BV I`UJ_Œ33 :2| ~fÐxȹ^[[zmdzR^1P_EHY,CLޜ/u)J 3[<ݪ&6F9EsR{(ur;f&ߺXg|ڹJ6AQs }a OE1?h -[7p|5  儆}WŔ5Z{dl=e>M)$q W JΨ_JQq?nh xLȏ!!XNiGz {1%)0ґ]sr[xp#̈́e^-g4j\ƗiνwKW S~oiȬ1ƥvi=> WDQbzU2  F&Tv53K>a'S F<%d.ckXi▴j\wtDp!L{J|5BCu IDATUTd I Q76 ?24iSdXlOoω_,R1V`^qH=H 8C VvQ쁓G:*߁ARn”HcB6~#e29V< d>3[QLϦ&Q4ơ.*m/gW~W~{;;"? OxB;#Xx?l; oo1M~kTG>w[guVysSP̂"'>*Q7P;RGy:Zo޲7ie<zo`LftގM;wݻ`s^1 TCpkvrߠWZe۷}+_W ?h5Lgy~fOSzWGAsc'X15x=t4 Y{3́碫*)+0vETFQ؉LnZw2N@y1 C K}Dp+c!0Wߝ1WH-x* ٴ1F0BP]oU"PFLZ~q) 0x3ODR]SX"z2S8sW֫fh-3dHψ"`U0Td];1@3acZ@UICۘ߈S]+NUlQ!R^RV !kT.bqHYz_]O0pN~ K~.FD'="儘;ϻs?xJrRR70{.pyщSSFc|3J,R3 L_(嶮4XH(^  4TLhEjn@qlp0t߇T>TNs2G1ZF͸@}` {ִ"T'~,ߙiN[S~͂kzRvBIfTbХ-*^Kؼ%>1hf)~4C}Hde`xI&i9=}MvlW4ATc3L2SgD0F4L|S) 5^ͧL<Ͱ( 1TH#`[VyɃo.\wOxiD\F̸WqT5}ϼ7J,±ﲼWqGI긑~n~~#`KyW聯AƼP>/Ìgzc(p/cwahJI8 ̌|\{Y; {~w|k\Ϳ^(j /4Fi®rWk)52NX֤[ =8x^!<:Z$&dГ>'])&g>5߰: 7":iL`foLNBf3;º>;qKEwܘyX >]OcY!}qq[e\E埙ze6Hd/Q _QUT!뢐9 }F<͸̨0)(RK* µHPvg>Xŕ1ѱ]4 ¼rJB4  D=c^Σ!I֬Y|[,C3C%Un2P!φe-w4DiEg嬣uT9*q\eU482Hw FD (8.l/)GTQ@r2P! UTB*RB)m/%Z!C k C:zkg:g)iUJǨi;P8h(YРؾHL *D# 8QZ)_tY{?ʱrژõeSLCByWoIHAFfn{wu1NDa}%IMC:YoC b|V.a&z,q {(.gw iGm  vi fUYпe=aۦ;zOS>zq[7$H,/,f6a"'vm`< ?8Gw6Zb*{KYC])*a*qNy0|G|JL=˲b<bbr5Gi),MW]j{ھe󣝊&<p䮻x5&6%]e^xУߵL,}6,qJ:ZRCe;QɕYgPm+b6c3TM,wbK'\?p.1A`̸3;>t9<6J OXξ[x 864ƀ(х% ~gH jh"4=Ve׻ 9  d6A^%}mxB]d)ÉČ-G4$ O%FVG*HUĂ,ixz}M%2JTXZ&5l++3 nU1 3UY@ 8JNyAKEbсCpi&^$Obti( keBKyPМ_'jg̟BNBz!N\:=,}BcIm(pT;X|qS l[4l(^8ZY< ч)=k >>Yt\޴hFiL6>72=¥G@|Xf]suq%="ַO?~ײ໽?c[Kf7W:Fѻ]rSQED%7qPIp׼wy5 x-'e?焯9oYrڙdwo/a-BrSSb|ovO/zыS\pA4Fno-[C/}K|X`aYwRgtV1y@W\6c'39OOndp؄L]zb&$j3(;N9V2s?p'a "M\^4c(]ui8C23[ĈcmN&dy6gI|Q0;Z tGm T:a< )DC!8E茬F.#Ǖ8zX2C\#K"]`% 2[f(%\FBYҰmz(S2Ea`@p/g P,j#l? #eѰ0Wǀ~?wUqΔG/Y:.ۼhˆs2Ja"=;>Hp1cIcs CQYV)WQiq( k`]u8ɐGEQT;J,Ǹ._H}`5V]A2{; "5E6Я% ԩe=6//5,`f)"H%:Z`Ϩo %vjPF*I,}mضduGu0+UES*2'y^zٟP_KPC a ĝ0O M"m'#j  ˏ1x1QF1H{{F򌲄O|Ѳ3q0Qg<:5l%:u}Qt˗gmc$mXJh"-̀wiqA,$j410 s$Pyp?"8nD)it2\ĵT#&t~2 -cQNRire 䣚x /gŎK#}E7ݠqW׿^~7~#_䢋.*ˬ'>Q^WecK/4*ٿ;M{̜4G=^*Azw%ni,.Ž /Yj6ޏV~U= Z+Diw({eqrB|:ιgYܧdx?Op~s=%ǯ9,@uKFY[=Z:ƞ\הI6 w9?@hršfp~gV1Dgcf:D(1 BOC]'Ǥ(@˚agufZkPA2?]FJ$ Y ]-38*mf¶AUa\*On3d OFv|BCeu4u !(/6C? șf"Tֲ[DR}sOHaA z+ʽℲK|EX='=&+c&c>NpD ʿ$J4eNTpT!߻ T=NQ.C=dU] NfBW`UgISįS_T tFԨ 5 }:' }b(А2>Î~v؞?1B@"ƱN%m GEG~hڟ1m#'nm+r5y(G6ˆ6aO$t)18WfU33읈wO:ۮ\2S=9ˬ({'!3QB[vފyW"W<TGRʪp?: ~k<-̳ `Wo:i!Jf>,xFm8-"Hp6`Ϙig-;l@MlY۰J5tO^W}Ӊc:,xѧYx@`&>ݾֵegP -g@*jlq<|gq`2;y54I>T`XҚn1͒@ʈ,/%64;3kd_9gFɠ L!X`l#EM^U׎Lxi,$`@|lH*;Dz İ_33̣%7 Nnxݭ|N˦nvln|(Oo\uvXI[k?^RN땧EG)~ˮ] .ץ!ozӛ2~4^.I7n6t=g(*( ǎy(9J1Deq=VIG_?3< \@)<2U3/4dso3*#X"1E>cG?w8q;1Vfg6g49Ρc$(`lP&/W1ZgATUi+tf<M' P*hs|UСJ\yroQ(t*?x\Y'uGR*E!jdmE(r"SdĐgaQW&$,ʹJ:@>HyLAL2~{Z7FbSE6^ cGq }3{pxdfM# 9AI>*[L{ ߍI~FX@ˉNۄ xvqEU!lQQB sB֓6+Ckt~A~&?A6 c8î[Qo |['g|>-'H5i0; {,n0m[v]_Сp_X ^Won5XI4`]gtԡFϑNiZ[#uo x&opܓDڪ;ڐA8euwvK`% -k|@qoa#i1'EĪ)#?Y?\'O/|gJazi N{z^= .GvIhF5y=n UU_$ % q׀?rݼjt7T:MQD$ xq+'q7(j]3ُ7 Z@'LEr泟\bs{x9Utۖ^7#ܦOWgsUY\.ǣ(Ζ7]{/rU~O./υTCN(a Z嵯|a>W{33翴|m˝oW^U~;~MWeOKʅ*k)rtwq.EpfOG%| IDAT OM3;Lne8`Y f\WQ`UP˒ou=qr7[1zK!YYmtGeaV> ېsY>q oqJҒJ+N6ܳ]r7W:go) x"+Ft*],#(g1` X%rG2|,5 ۼyxb㤝&u׳Ayf@hޠ #~"l κ(O/q5hq3ģpMR e4_:JO}IG Hf@]y|c5e2xNa#>yRuY'=l҇ǘ0HP^}'J3!ۑ3q])> [cND=W\Nћ?+ХH|I ,^yfR'kսBLS\Dޣr(l QH Bt :H%vD|28e~䂆񆠭 M ʰ6vZDQ0. n7F?QVMϴ֝g0_.y=D.pi 7u-u|ZЈ,n#*Q:G;?A8d}[b >&Eu' QLkP28ެ;.lW?4ꎠMX0 X |8-Xc1*;D\&3}/ƋqiAփQ #|F`Jt UV<9O9>I[˙z J/?qe~Y hsZf9/OY* A1 t-]_6e\|wk'1/<>|wpdSqvXցV=M̷v2\0j0HidZ<` 'ʿiGucERR<4yat#aۉ;uA[zj?ӝ=߾,`_5Bg*sw2rr[/~[6(oNZmf?duY߫Rx5|gd"Tsg4* AXqH1+cNa0YeDS$ si4v+x5ڦ9<}']EXZq%˱Lx=S0Sxlg?4k#k&_|QГ&(.tf*GQ, nY쩀"5CqvY}wX6mwf'X>^Έec7fZ"3*3oj J 8L"  k᭾m$!4rFB[yh{'|qr3[^sƁwzV$LF8lrHyʪ vAz,)6(h| dq̹8ZdeZ7r Z]K[S#$P/zPC7At yD߸ /Z$"Kk GfÏT8ͬu|~zD(t)=>$Ow&8-RnCEB%jR`h}Uh9$Khs42e *^.}Uheqsj#ꜵ3Hq1sĕa/lMdYz7H,},WŝIg G@E֑|c΁{ p=i)40C"}P̔-1p3^(CT:苹mU<ˈX2SrB=WQyݼ>pyP y KV2O9BfWӎZʄeClv|v`!-Yw$< |3:V~=+E/X(o}{c~哟T/̬^b9R7YvdGwc]LYNY]~aX/qei9С/[կGG>\΀ ?p"_U+?('n2a#hȄ|ҋ:(= o."4^1WxN6Ef AcZ{Q5>-?e|nn_~mJk]l\8(8M_ϙ>MF0xDn|c Y%?\~@ȕxn吳rCO"Ā]Y9C\s2_,deg X-e܌uOv5((xfv'^!j8+B~~Y,:C7ICX͆aΦ"prd,N 򎭼(\K/q͈Fh)sB ΤI ~Ɋ{Wl;ϱs-M{x+O3xD'},[(Q,GfQUh.=  0pGqI#/ <&0~l4. |-?yx&@yloc1|!lhmg{eߓ ʲe$}ɀ4 17j@2+O2k8װ@K#5񝡏W`)|r4T "c@6<3X΄;q pp:g7*K]CĊFQD;lPCwn9͢M=a028f-&cߝ<5!ij(.U:0sgATBj82a@kGL2ARɈDI/|r;4O~aK~b7r]pѴ8 ל/ N0x~ڸ)we:ʃp򆷼ܵ\yspW9IJZijӷN+nn`513xQ`{979h7 牟|q 9~+>W]u%m@Bt QNX͇Y@(N21:*#%-|Q1WA*󞆓OO,:x+$GLMw N=7O_xrYسZrnlCex( G*LB t1g wfN8\n>F3n`6lHB%f*(_}wY!*wP~gc.n=g?=e1]Y29K#w,W0En߾)4~c$ uzl> + Y''p= W4Iq 7CѤ<㺲L5d3MYôθ ]s=2xJlnYs蒋1=ef#⨁ET\S'cK@W\ **8R( qsߌ焳/rc昿qһwέe߁$xH=(M%4w@~ l.E k.zAqnDH\qdKB%b2Kxe'wLI[ig|%ic W3٤G?\6o={H^x ڮiYdVoLw @lLN𩸂O6$4C |ɇ 8s? - ZupѶKGࢂ-Ϧh!m~omĥA.+lRC=ۗh" guUl\Hf~njDڲxH"u2 85jZof3Yŗ!35o B:/|Nܝykʿf3\' WIJ,Ya"ˊ"LB H; *GЁI 0P*OǷ%_ |H \pﻧ<A$vݻw q]{# ,N?~ga4VN=rp< U=/}y~vRx6b_6vIX-4?덿Mgbj#̖x9#Q?nrƓ@p 0.HX6>&qj [8S+g>2vf)ϥv\1{c٠@nsȯl80fMAJaqݦ{<mfqŻ@%xLG <W9ᣅb= a| le$D:d gn؍~qdׁ^hlBQ U@h۲0 o:q$ c$Qegws)9xT$4VnSfP_<'|W0e=q]wqAJ:ӏl$PFy<}4pNx`>OuTh,-wS{z~~_~摿$ir]:'I[6BP5u[7sLieRZ&4iSP`; u.Sany+G++MmN:fWu\Ǫ.(ҮU8rcm6Rk(U\W!H֑;4@Y#f\B 4x܅7ݶuwxrjbVʔ~ˌTpAOC!D }۹ޝ(Q;;[[߹ BOOilz9q7Ĉ{pt4tXf]vd4i|n}ZDl#gV[Y`᭨sCG$;T*8kh;ogoADFGqr|e1"$IgqqUFɆ}ޥ1qր,>v͖9hS_H[b*+D<o=Q1w̍-ГHہ6y$4P=<5/mSenlyZăBa4d+ 8dv'E(4t2L+?8SFx҃ﲾ^ ="Z*~'UZhPpii O/{'7"ɷUNl3<ߥ{WaELkflL<63O]`p)=rp6pUERxXu&yC&ʶ\C"SV &O0e\+1MbTט ]M%T;F^q{w'ie3Tv_8\9bq±Y/5c|6jǼ =m(U~QUاOz&T]ċ11da`%L ܋wZٸ5d5rqgRZx*QWWl:qL Ik!Wel*q>QZ$PAnQ# -3R({Eh]\$p=TsN;T*_>QsM{|2O! 39BYB C򀷢3!"ʉ{PJ7r*?" `&( ?7;u*@*qʘ*.*4%#>xb l"ጲe3ֻv͔3Pf? ]h]Y_?,ΒF/W!̫f[ʦ$^f  'I1@\ ?)AIBЌ?HGt#e{LYΐ't1X.=Pa^ߎ #G;IYoQOkpك,.ai>zm&_hǶzyۺ4z_!rshNRZu6ffXE_x-mhl8Tä Y@{<-_*FTM?z }*)W‰\g#:}lx@KF1,_0H}Ⱦ<HGۊ#ZH;㶗(?,t(l鯱f8पt3ږ@(y:Rɠ֕ƺg>.XB&bX.gjٟ}ua5iF(q'ҷPz>oԇ'NK5ǃ?_K>nDsLjadRZz Sn$8`cmX<҉JLzQ^/kBŕdNo ׸o3H5 tUjDZ@fh۰av=͔6`,gW0 $ [L(pU%?uR_$5B>>tV ^;ۙ#c@kٔ,/qexLs 4Q$^zM, X .$of{5&KVċ\=ri ȚqB :x0A=sl Q|sƽ(MQ ReV*7I M`p}|4Vɝ0@UPFr`[OEЙ_oUr)u 5VɶNqGu'Ÿo# ^FnקH#(CYZC[F7M6'STywFGix>&L)<ʑ6ꝺq9K?I% 鹤Fڀ7nYBro<'64 7, ' {hg`ԇnC@m#JiE6",c eYڵD!=NId[M b QLihW$}BTXm*gP&Ńe ICWM W6`B@h1`KnD]#9>dzݜ~oe^Cekk^}Se^n}OAkL]շNAM/C/\]kkȌ8_A- Y sQ>|56iARǝ'7bוCPZFxMݽ4V`0^{P@c.^!bx>Si XviL eoo8I%vIc?aW0bc8qK;GA嬀%^!h `a(Ald&@!7+.TUsnIaFFAL:)V(B p_=Gwݯc Ve\Vwm\D*+[^ം,d+[~ə]( Ԕb`H@;(Jdj>ٸ7 `(sEŦXIiZݳ)dGOO`rb3&a.kaF=JJ6goòq1A42ڮWFusEJQ<|4R 3|vĺVI*̦He#@$i| 7ʿϰw3nΪ:kIfBG.0þ9<Ǔ]$ǸK}TdrdD1 CN1жrW~\%e½PdWyʭ]3nlSJ2'px J%AgL7މAyo_W l3fO& U/VZ&47ǙsI-ʡuk2bin?slkŘ}W7ԕ_%7~ґvg&|DxQWbގ1Q`wWla&hR d_'m\~Ұk.[Hp .?n 8} sMRX:I4K2Ր2eF7TWznͣt>t)}VHTƁi{tی5- :^cJţr>l?@\pc.Fp6d|Q)săTv@CGkqfN Sj$&:ʈglygKsYQ)m%;`[e\o^(xlj[3ap5 |t: K:XJZ_IMKg8ۤ>@(Ɨ)0Up8\+ĭŝB+ifEvcseZjLby@}nhң*SW &t3YiM3Ls;kCJv## Kaǁ2eaGO1lfN6Gm88q4 n)I?ӉwϰrԺH&He,>cZ)e[a:Xb|1ߍkؠ 8c=p>?1Fd.B`F&,tE!8ua q1ѕa\K\Ug[T"*8@ `@[] s'XkzA '"ac=y "0沶Ŭ?Ч{ypdtGGgv28qF^VA2n*H(A\\Bv^d aht'^ሇ8߾y7or ᐙYS&@ֳ8"]ܷGtrr. B~yCd5d1ȪUРʠeʛUT Єz#O͛Me*p5vcx*}) ^)I4;;{%=,3i:NEb'l`f w Mzh8,+Q1g>*D[Vʸ2j< D%&f~QF=Qe1yN`@Zu_Wa%!D:H. iBeB-2q*֥&⻬w cf[C414L#W׃.P1#饁yM _ Ѥ#tbd\P?n.dAº~ `tYQp1*SK>Y y]"ʧN[?i d%>A"g\ôE'\ q1gRNYrkАwlʻء[~ L;/^f|{Ӭ,OPibV]Ë3پ ϾT8$)q(²n6O=mhΎ`s ] 7jᵑe M'Maζ6e~l}O $]wmGW^O= |5XJ#wƟ49kS&4-7)tL3~I:H?M,WZ2_ -gW`mԋ&ɃOm#r5~5) ȟvd@#yns*^ZI@$הdKqfݽ8 *𼭣ёT騌 jtp("=4J< ~ 2Vhns[ofw`²,!e+af`n\ؠ6(MQFnьmg$R1RXX[F@㸃%RAQ!0"W81ШNEQxBfP`XBq @3DЏE!b+(PV1 !VoZ|_\2|g5n8CЬFO*WQEVI%2T[̚Gʿ\p/IFQ%3`QexM06 ʿ̆2C6K~pDXevW_蠲H \figR$O[/p# qf>(PFRDp6SfSwUeG?xXj<./$ζMB0r(Q@;fAyK ˾Dej,ép]wvh_ =0,ovC%b_OPomD*^X7ǡF)l;S _=L$f(Iε)*QN)}Ky>Ɔ9+Yi\o Svk6Yf ?{wrtw=y@$@ 8!MlihD.a 6иm@CtEHD@A@f&L1!L'%^j禿{yvkW޻vUM_/kGI$v&Lᚶmt{ˤ%>Շ:#r8fŌrtH.1WiAfO7")q&K:QCd( yz0PdyF^yןi *r#e&L]>Qs&=K#R}:Lc_<9I{>p?/m  3?z@=P N BI0><"+fq1 &nqc){\,^8vcB edAih18h/aEg4WGUcZPNY7= ~L}/vwE\f#¤H`T7&=Gs۬| E}~Pʛ=IwJ.^N>p~"Xk2cdxTD߂M>̈Qg<% 8aG 6)GTϰ6zP:L5GQz씺;,fs10sKNS,=1b" h yf?io~V3(.d_H*>3632Bz!*f֮)'P匔ȵޛ)Ƽm}?lg#:6}(E;݅BF/]Y'c$To>x_ ¨h2/~sPrތfl(%OZ G .hK4񀿲Xsj`ŵ~7 IDAT "ڏ9q%ނ.RJ|g(EG,~e}HN}x:rHO|ID3:GُG h1.:s.ŏQaI"w8:K9+.YZs^YSHeEDW~%6$ks!N,HT=\Ϊˋn:^%]#<""erLB?v ةmz#IJXKcG6eS?m"l9UqSA}{%(*4sD}U6H?vlG<~̹n:’ }\޹rLJ7푝Q䌌f\D+'98m *a;r^4_mNBK_6=1,=> : p)2 {ӟ]y+;Ձg| ,kCg~%O`٘+O-|Q."峟+qxnvˢ3r9Gf"JC+M~o`百kdV]ם19R1 EU74 -|B4+#+n\SUa`Y_7tK@W(> \ynn'kN\J9D8U.FcHԎȦC).l2f(>:H Kc%f6rRx0smw\lv5t5Tz?R{50gww:4 О'"XF\O+k‹^1o ҫFuY9 bNY&:x6ǃc~zs(~GB8ά6JU)EEUXi0>p?c 0M 'f'3=QG ?뤅l\#;ZX>ȑ:%$UUc`022`ˡL_=]1r?9+8z$9,͆!c9.-i&lѾ {┡ypKCYDT_?y{Ƞ!X6\ײ'}z^fvF8=?r:Ա/f_ Ff<cD= Wݟ6z$Rq>,ݽq'+T7?ѓ?Bxv̵S39:Y2h*p8T"TOwi}plţ1 ^|"mf+kh}4sDZ|Ke'[KƩpRI;Js9?4I /Yf~00pRʨ:p:' L%^]#+iP<#> ֍yf9Z^3A/YϞĐWŋHg'av׽CfYV' @ G3iaAS@n? `T6.'ڴ]|${41?gcNjvw0< 8gp ua *x #uUPZt ;JVylr u$ySj#Ar(K)+:bR]jJ>(-Qg8pƁ3<9`of\@uzvP xQ@pXʗcw f<6 ¶ wܑ߬!1j c0Pyu() %6;ggU)+,Kфt&4apZ辽Qe:R(w>ΧسQn'@x~1BkЗ}7s _F]u>ʏ$Ι=KGzR{"+X;>&{t (gfvŴs m<s: [=^uu;Sg&AG? O 8 <8+g}9/J3w~Zu>?·GzU7~*)c_m+ܒ qQ,1fy,{c3ASN&c.L:>ɐ;A;@Qrrj䨟A恏/RCݷzf \@F^?﨓ޏ<t ܆ -&IN92dӖ\}2U/xwlY}0%u?|Qf뼟cuΉCwC X} =&MbNtZM8/fϠQ|6z@͙ }Թ=@GdNPryA{k%辻*|gRj4(FA6ЃυQ=5ܥ952E8u*:m4$sF$ͬIBaG3vpU< ^-#{ϛ:F%B)EKb|nOZc8No ,)k  ̍*Tp28R:`a)Ѥg}#H,wNض:x}Q|+꯾jû6qx :)NG'(0̘Q̆m^7!&k<6wS(iOuq04gjyU%>F(T#JJ`7kk3O2~l%;߱Gu`6G7PR)֣+,| 7c3NsԌVA;JB#ERgeҽ 9CQ_$;.m3z6Z$bp<$>NT5G8%<(pc({6S.BOŞѫR焂@ĕR̜GrS!#Rds$=6nwFs e>>7;ocJ7I01(tOoW/kCO>^Cv7Ip5^?_>kSb=\O"tzyhqq%AOģXsԞ |ۂ-fx.ZoIcN)qzpl(a l?M1/sꄀ2 =GBm׽ yr1H;I>n~=57'2Ȏ+4uPp FS",4ߚ .\Ў8q' ?xCM 5FSWd#x,}#+ ? M|<)ing X*7{9a\/sLF#t]T6/gM4k?^o.z{K~j(44$=sƁ' [7Xh|w=9imPX/|_s' gq́ƒYڸ3^fE͔L_2 iJM ev5vǺ1 }<`CF)XπٓҔJ373؛1Jў}4mq {e۸Mt _ f|L4=͸sʠόb@WN)fg [0=gOy_Ư1=|T),ff4~W Χ2ֹ>wsS׆DyHB.阭{4|$O(y1'-x{ޡ}>uγ7Ḿڒ dyc忂J[Ι_Gf5.㘁#C81Uל"0m)G:l-BwэLjY2u._kރC{5=fy_ȡ1Q#-(!F K,W#U9]?{\S1LEFq QÖdI\r@$o9Nq*aQ E`5 eWĵ"ffq~&T[}`WٔL=iP`P}Qm,|wb /_;ǙʫTNP>A9X487jY+gtڔ0ƣ1T!?Ŗ z͆ZaѧgB*ߦC~,yΆjt*<-!?l8*f˨!}9G+9`Mmrs)%&]>#˘ޠʰOfm6!4 2THQ1t YP]mƼbin̨w0LT): C ЇWhm$}y ?-TI#ūh&TULi/>"%[zDkO i.F:ܞï7. U*sX mJʋirA,g4 >/^li~_ ~^mx3OO3D8تP ͨYƺ F;aT 2Csѧ6~\{Ȁ)Eϸ23V?f̖2'T3) 3::AɜYf Ͱ5o-w5%p6Uc$Qʶ=gnRMi}:Me3=&@EU Ibˋ9:yqcl+cwH tQ%Cnvn? 0e!{~3Gn2;LQ]P9>\wFz/ǣ=C}fϸrj1J_7b̤ ބ(!&し"F6i=k'=e4~BbfntEr {(qϥ{}{{G 䳂C\M̦zUYSky O?;h=,J'_pz舼ESy u[f?ГE>tUEH7cIչit/@kd# 5ޅؼ?I<+irpTNy_pljPLmos+e"2Aj;Wt52KJwv<9-h1^^[efo]~oTkߵY.! I۳x QfG IDAT.\{@YnjVX^EӢ٣V8TLNh O(ֱ!y*sak4Aһ{Y<nC^)jQadW+:pRdݮNhKp+Giaf`rv[):{Xxڄ'Ժ <)tqA8 ZOK$a)0Nl`_偧!{ Q+])(g{ D}夨򬭽Є ؗw*]JwvqIO=kGA#"GߟyEoxV^龎Ϯ3s9Jq8kaqp{Kf2֌"&A9ߥh{Q)M@9 bK'@A)޹L6\b2gD=2sIʆr`sl2Zio`oƕ/}[:^f|4&쵯e U)cK .j"KwH,XCqG3많fcʱfN_DOԧ:"$B Α~OM["&'ml7w|Sg}{[wMx̝^?Yθ^#Me[Opy [pd1vJ7֧. <1slF>Y~wmLԏm!xz=, u/Levyڏm "_֩'* >I9q}H֗p:1 5}1/ں6J 51"gݯADZ;vʝW6&rN 8ǫb*`  'srwϥWSdOT>#r_w,MgWwHѕPOnDKcp c0rM<$+V]9vPS 6|xJݫ[G)>\=1H6~ 3oγfut {?^u~,4yxcHsDs0bC7یG` =-]f H0hy$$]ǯ\)_pZ3F6-1b+]%+`NИJ'sɹ^%D#>bflG`~F7Q!_Q?ȷךnȢю݌.F+T8hs@y9x'b">ˑ}6sO6x |f_& ܥOХXZvͳ8O|C ٳ~ Z*<Wu;4G;2Z~abeU#$97P4 nCBJFE O2 AgxǮ <Ͼ e(ƋNPO>}19rG䋨0F8_x2OD}56)lP©l3>{x;X޵̞\C{"C"#+[]Mz5/jks9oWכῳjV$c4W# ?z1H!]Ev Yn/x +ä1׾:Aot HUHa]h  ߽ѽH`}0{3ᰃ?tkc=ESojB }OYSn/dxvU^O8&QʑWs.*?gnN]%pS~igpZ {,|)RgYpU*>.2=-Ov:X~oY/p::(?=m~^Ͽt7}wcg?K}>({wLa~nx+^?#3Kqboi7tѦ1Z qAKɢgljFN0=|6/f|F@Scg B9v3;Z}8s(!ka)( S.Iw{0"g0ˑcsx g}"* 4t6˥\c-F}OGOϹK@зH3#"Ѵ33j0.f(6 xr^֌-n+Z:䤘RzM:њ!mfN nu]p yu=^ e2stedqz]C3!~NݔxxCo9<*`O8dM1*}e ྦྷL?>ڔ3ί~ )zDD>Ge"QӞ2g0ͦrџ #O?+3qJ-WaE|= 9*z,*E4w1+xs(sKY2rm л'q.n>~J4C~oϦ:ϡ8Ldb\k<9`Q&^`g`\N7g۹TcrM7mjh(6!M JacHe$_D1}~f͈3Ѡv#tbZjg@oWy3{^y6B;P]egR OR9$DM] -W=oᎼyomߘuv_ʣ+9m@^뛾零|p{uOWj7Y31`6KL;nPri䔿6NaJBsk\5fyh/c@ow<?5Co 0 RX7G9npp e4fL] cxQ @1)+@cDB/eWK ч8D7e?332P?M.4^CN W: )C?4yJcsȔiVYJw:&GHDB*ܔA5a?5lz3.x ?Y`~̀όL@墮̚@X3n5z2F$=[2T8T>ڤ婰Tu`7"@= G6XS t{vi*m U$2_7z' v0` Sg4r(q:Q$ݓ2yDwvj#SdE쏭7"Q=Am%9ȑwGP%m?ja'BU7NG;LGƹptȑ3^xgͶv@%&%eJxqh)}1~ aR?ed ]3b/z.a`?G+tDz&~lL{GBnm8q$:b NZdVyKVO1_A9!g/VA0r͌q<xO`/=zՕ[$K瑺 Zw Ҏɥנ-o'w×Ã9R~s$+'0u}nDSL>7K<Kњ0Ũ 728VB:ނ]nB"VeT2l%u7caHH0z†VGM=2z]Ł3'C ^\ί$ 6"0 \_un)gEüp3</Zv:7`dV2w_h HRr b!p";o? 9M 3ͬSlK7&yAţ^~rN>(?m> O|K総>?u{Jkբjٻ{{wxLggo?: [_7ۇ~n7[>{tsg}gphOy\{$ٛ--C}}? 9Pnf0o\u5Rv!VfgͬYYģnj=e3ﺳ"1ئޏf)%c|L 2J>?x3dSwdϏ8 D"0_ ff\,ԑ}:7k9cĤ;Y@IC)4cgae2_i8sf,?!$xN;'_Й5Q8aR7v( Ѫ.xʥ WbIr1:5L;[i8>J|Nd6oqk}SNPiuMRܱ|"Y\O9a&Ҡ~QsX [vv>*T^["7!X+ࠨ1l0z{&ˌ'|f<:JpOK5=dl,[k s@oKHE ̱~FJ\+amן 1U#8,qT!ѻhѸ4cc.td8qT\ͮd@> :WޕV_T' Xʛ9z=`=f6 sldb:(y0pԡR V pc?vow~臶~Gt8OoͿ9 Bq`Û˿|{7hkk O2'yלƼq vq܄63K?ƓfRn";cOdk.Yoʴ͐ƽ Iu0f > :3 alM=>Za pJccVxdn3jceȊ4Λ^W0JQ6u]}D20҂kRv`/vE|'3~ty@M 2N)]7&$AzFlۿYT5!yݤ\'G/3z/vk ~( J Nu^WR ]zigXYOGܱs(&FnGyF nOF@]*+.[YL-'`Y;ϤN-g8ƻrTO$N>4"mYЄ~۠;0 9Y&o38 4`'͸%7nw<#^$?9+,z5AxpϒN=ޏ'FC'M_eoK#|5>}cH9F||ȇ|11xŰyyMܺ?',op]o/I:1j7"fP8NƦ!p(Dc{kƇu|9K;ctYG]e\kG͟i!i&-+{nߩv?HP(̘J, R2cށˑs:Ş20c3WGMb9N R-<twG xNW@7;fPH٘ һc_ěv_B]zr?V{xG u3N 5$SxKәъGcm|~Ƿ=>_Zų"{]Oh3k| Z㡫oٍ-MZ\g1Ư.͍xM\&tkg9*02JpfETpU.#@OߎuDCńh|JLLɟo~CS }H^x3sLç|oʇk.t?ӷ?wnlŝXk*/Z}M ^S>Sw}wy[o/oum~Ǐוw~we[Mo ڳ[[ۋ_ꭶg>{mfwgדC3D8pn k{cQH35H6l=ڬMX\T8I(;gydw} # z{Dz=Haxpw] }N*ch iDs8؏@T1|M z~sY{[ Z8OwQꈹNCf3gv&kt򍎆D/:LRߥ)k-89XcIQcROI s/|33Nߕ׷yU ^Kхd˩3CZvҎ2aԪbEi 'FAd\;~0f)N+{֗g$^ ΩJ59 d#}t s8RoxI08*:|->2RO N,pUe&exC^q/G tj[T # /{F P:ά?8>lHzGJnER\q͖\=ً DWdW m 0|AC\/i۵ ?TyQ%9}10K<}L%JO0޷]1чȜ2391'D;R @'#Ow_vQ=Ҍ{_>g}~.D~Ô; C7G.ZJpgih䘘kmr!\73X[mx'ex?O8q~|iӊ>ìYL{mymoe Ѐ"y楩S:o:Q~|N(?+^M;l]Ν)OC2;~я^n_% ϖHXfMDq==. +W(J@701ԗ ?"|/ aD %И:fr"\PCsʽP80 ҋ's]aӟIY( r 3 ˀA=.ܢ= Ajx :1fw#`{iķ9 gg U ;u0肏"(Ό YRVY ZȒţʃ ^x4=Be:hWPZzQ 3W2 d!Q:sʇZXtrs']gx~'lWl_>mi-~,/6C1Eۣ/wcۗÿK8}yI;Rof;Yu=OߞgHE_E;g6_q㝛Eo;~|m߶=ϝg<Ӿ.~m^nOyS7y7Yܿ^2 8~r6߸gG A&EaOjKϘjecbDѡ@vj j,s_9pzqtҕH?)` >jmk)_Z9 G{u;_*=E;d>Q uM(crR^={gxƁt0(p`#f6~ӓ9'3|k 㼻1Z\)3vZ\]jN3S<_: 3l+B0LR˧"8v@-aB|z6Jqf~ aCͻh׌Dq6DYK[1_Z%V@Դ}9}6: =WmfeȘ?_~g]{Gsn]_YZT2xwe\M- d6y! mctEZֳ`\1$G2O^5xJ  |I?7?|g|&I@eyd!_&,}'?Nz< CKy]7<=3oHpf3踒a:u\Yד-{uz%^_ vOӏ9J2:Xv ȼ ]u+Mo\TUۮIu%* TTW 5{=j !̦Я֌/1Ӗ?L>3G+ֆ3˫ qĨ ͙!CY!wڴhe"z88|$h.8y.qN-kqhat'@孱Ӿl lJeGׁ8}=8B%z}0(W 8'O>8(\~Ͽ-lǞ?o'#Dk8mE xܒ3JwQ!<4wx^iosday8^wOm]uf|.|^Eku&r{Q) 1gW$x2~R2C;'}K4hhUw{a<ygP3V{fnL:4)lR@8qohV{_s^Qf"!eҥ6TxeL NO+͹`֜Ā7_{$Z݊H>1kEW8S:d3qf.f(.8LV=M>i cٻ@B¯pdlz* p9}`yg_'rҨp޵xޒ XK!zKS6ƻ3vN[OTp晩.-Qқ8hA67{^=}OO,Ye A/ֆKexE} eֵ֖Ǎ=8F4p Uȭl:\[]F'y+,A FիzԾ.h$fRW@GME F2O)}??uUq\mB^ tpdˈ%ޏs 0M 6[U &u[9UwUNeZjgR_N/9< Dռ_z]׷u#ѥg|94ޚѬ|p'*E2@Iֿs}"l8n>NX˕x컠Ƅ-Ͼ>r~jE3A]ToX VQ)#D #9y#l/|$xcտ1%D09;8鷶A.u 180ЈqĠ{7+kKUVsnzF,O{/u5tTcLMcrIF!F}vqIJ6cqW?0{7_=Yx~^Uxi˅K|vgs78g?ٳ>?{//5N<9~nߗ໾6N5kܟsۧ~nq7m__}~αs/o-%8ΥkeΑ~F(~{>gh'[9Xa `e=nwZ6ˬ]f MSGFN k̀eCʲpXFvҵSY ED\ixՌsi{eazʅ9g>rW#9sCp<zN&F$1ɐ1/M09wJv6lrzkG-fwKN!O*KU1?۟BqʙWnCtiz--eÌ?ΏPKXog;Ơ҅,cz~"i|; PTU)iu(\|D6D,YxJ2mK千F4^Fw5wlX !{ӦEi3_M~k+m" 9ai'5x8sh#,O4~_},c.N9쌙zfF}f1~iOImvl{#0ql~N ̵N P*QGL¨X6PN*vvWod@|ƸG> mD6 _igfsk/Fig52jr],*rZT-78niOO2n&ʌ^}}mV;Q"bǹ0u40nvK{N-=q.MpXsذ!gɁ% U"͎ He3P_itIzx0ȃ -\'W^d?\wK@;0Tw1}Yk7P;Γ>D􅛛IЄ_(($䇭3#|WCg(Uhq' ŭEC=qg&Xx}zHܻvߕ{`۟3~?خ?ʠ!E 8w:ș 4^!y&hh e1G{G.eຝ!~b̾ t2Dz/^ɔ;<:^$I! Nxgf‹1?18PrW571evaˌk_KKw{wYWt}'|f= ή7N W~aǸ`v^ؼ_wy VӴ1)//im??}~drOOGw @Q.ΊONkk]7JNdcO퀱0k )ifZ3vPG>N}$"/g6gou2hWc >Lte8Ch~=H? wɌ}s4NJެ̫mj[cnY 72]pIy9At59;SShFu R]֌^Wh82dΦhoPFK6d{謁f$);Sv7r*3y}ݚPegCu"]3f' |xyoϡzX!G ^SzdRz("%=K)Ue=_@^]_;l؁mOv9r, ^]rX0`.BTPQìf9n1\8q`./}89$!(Avk]3SYx|# IDATݸf3Au:SC1!`sldC| }ocɹŹp=DX8EDvU=%9Oˣn{OTcooۃq :s/lfәշ4a" zǁv>]<7oƳ/|y"sA*7f*z(ퟶҲa `jc 9l9LriW~s̳qH.E^"2'Ef83cc,?,D]vU*V2sۿCǔ1OO}SoGG~GfK^9K{ݾxU}7|ìٷ,Z3٤?}T7loGWce79x`v췙M䟾gg ߒBLq{BDVQe =0PN(CN 2=G4z"khKkQRD|ifSѷ8[H`Ne YI\&T!CG>3;'@!ʼn6ƴ݅a)6tZvЙsk0>T )+yr3]]Yb0"&%f2L2o=n cr"&ͅ3(J:Ï~@TaZK0DS}D 'Ǝs'b)#:^JWKHw.Ri&Z"^8z:@ qS){H k:fgtO`f'ǧ 0lAA[iN =_ͽ F'Mh1d9Q/K2 wMr;z%NFk"A8A'䖱[ޏW j3t{`u1('$] QQ^S Pg8XUNwq}XYw׬{nL(*|lޟK>탶7y'rv$64a 8)!B!(:N5pp0 4hzA(Gh{]~,I Xek>_P g2 K]%pp[΂,刞}9~qpm{zW`>>iR뮻n|_1et']]oNrvFBʹ mޑxc?iO.wǽ~gp?nG?u?;}gol+>8Կ>yF1fh\XF\c(Rj0RD)j',fG4wJo1Q@[ |\nu)KYǜ"K'g-EހL Ħ,ڰe:LQ e=˵C b[?e%7<`(GkJ*g Z325cN&j5DuK!3oE.jv}3o1Ff$# p㩙vٿ%Féfw }=Ra b8Nt>70^^)bzD]eA=x:Yڂ(3KHrیuQoabm>kg}ĎcVH č҄WMF*T RATTQB}.9ʉY{s1ǜs1ǜS iV&6I,w:cᆔ#[hRWogcoҐ(_ٜB/|ϞWAeez^m[]IH#!\^Lᷝ-D,_]JУ޺ ;.&_(6b'G/|: 샎@1OO=!䃘jt}FrFL<3FYjh; _7sr`%]ʴ#nX7|g;' خ=B\,_xˆÓ:][$!8[\& '>F Xr1r!}-vp] p>"2ilu_ \3F-XNpk._ vxi/uAܵ!GU۠PIZp K^_j)`7!t!a(^% 弋= Li=\.|<)(C`@9YN<-N~$r#!:Yg ʰB o ;5|2N1l# S[Q ]>Bc<^"e9-{[W?SW+esW?+Po_id5 ]/bã/tTj.R‘(C\᚝oG `cW V>M뜰g֤49ЛH ϢW>n Hi2} W;Hk׫^t׾02ݣT0@{~oll{HmaV~~]9|λ8ٟ3AsǠa(JӌFp8ѿIhqY_ϻC09X,} +Bo+|JMi2%_]lF(a_?>c4jE7 /:* o[)ϰ^ ?Wrh~gcA8ƞP+ \̥r VQOǎ:T|&y:(ه -GqN>?XYFk ;+V#?߉jxHa.1 :б0nK>pOQ/ĉ\/Mȏ:~.G&YQKϰ 43J#)crg}9?ɡ/^E/Q/C(&r4y@N*, an6KPLNK2=hdff4O"rzq@5W$(QC,IuXCΫ4uiؔlzpMx:!^޸"STrΝgW;vVJx~ij3)WlC RiUCN.HP7]_G;?߇WOwBwtx^(P:? wu EQ13X[OYP"GegXDяFѹ%yKO^FSУFT:A Ƴ>piC=6L((U0PNɣ_'$[/ 8?TqStXDq꯯WK89Ī8y䔊ñN 2S3rceQQReQ cخ)^tujgU< i3Si "ᥛ 1ue6B!F8r'XN$ȋ xA*b=8$F-ǹr.xSɶtΠ#?:x|PxxsF4rI;U/.#Ï+k-/K(CvgpMd4be,yƄJHC܆/~k*qʷg>-:߶ $ڝoG*CBnSAǁ[GCZ6 mLԂ;3%@a/d:N{cfUi8C(0}3:]"n*+t@X<llG'8mD Tp}"뎤#ΰeb.LJ$-l 4#n^ **D29/H1mp)_1~J63ONؓh(!7wƂ֐Z,~³>uࡇJ8qQ$n"kw};aH+7?oϿxr c?Lẗe&Î"QJU&H ;qgWo-OPg(gchT8S2=ׄgWWaʽczNn Q2{VUQfsIqLPE[0ZqDák:c@"(m.~oWx^V]IsP>× eD"+1H%73ڶZN"Ahh1捲 t`f*2āѝØ|͆*Һ_` t ΅f5^bT.׈;uUt& DZ,DԄܣY:Yp. Ɔ7<+ Fjy!0u@o$%p@1W3Һ7Y~ S?Qw?)Z$ EV'D,B.arB4bD~,J卐 hv\?TvMpJ\R<:(:{P/Kn։μO8jSy ^mwPs5mSFN.0ݙ>4u}oSn4cS6!}b$Tgvy3 _^c}&#M[ZҦ _xjh f.sv.( pU*C?#,&B\5 nzl -c 5v `=6mLRw)p4;OI-p84.C3GIiq@ vu DoMYh֩Q;xUԍ8}Y 2u7 ݬ͆`.00[iE+PrgpMڑ&H(2)@|K{՝hvفxXZ&7, CX$#|UGoycۻأOsW~㿜\8SmAt1<ғ" nxn'^1A|$Lu7^I;߂r֞-\S*)u0pӸ#Gv,浼VS1e~,۝wSҖU@XR?i,SZZJ}>F̌G#Ïn u\p,(fkKeԱr#g%Lg xUfo"g\/9*/1Cg2q6XFgtJEa|mil^$O~ ޫJ_N6A0K1 }\ݛK-0"j ^fÛ9 rIԡ \q,08w"0tdoΉ0? IDAT>]o10lXXǖWkDBpiDyXuB1Ł|.RҪ̽ճ9,x1N3DFH:&aȬX^6Y2qjT@n9vR\Ju䛼5=Ojw͵l>r_,I@Om:j I"HYs.e;W~5'vpU#֗#~d?8&w_I2F2sm`lOIFgwhC/t}&യ@5mnN}qNOȗH[g ُw>@V@* OK6GJBm à1-cAoz;}0ЅΘT<VS_1칎{'Y4r W|sJCr;]eBpgi@ob636BS9q]_^ֱD,=W/>3ij'ҺI"H]7+%/{{ C< X1LiE]yim4,  JO/ I StO.Q"8  w4"NFgGRPV.0>B!!ܗ)oM4%}~8wؑ q{g8Fؔa)2[&p" SiC.YOݐ +l˷r':5+0$dل\S5|c4432员TRJgsΈy:9Tq DFo@8#@l )vK|bF:6k:# c, -Ґ;y+t͈vE>61cy3.Ѵ.ڿVmviCx#ZB40<~0D6k KqHtdo\:![Oh92|f Pc@ nށC>ZgUW8tk፴o5밠mj垄> Q6 Azմrؔ8"ki;W7-I+/ 2j^7+/µ,c70ivc2 # ).2>63UdX\tjY anG^+>:DdexMh2F\Wcv}eiC3ϸ2F(0أJB㲅oq 8WZT"&1PH8>̮/e}2)~k΁8 ӟ+i =FŹرhŒHN*Հ`|x2D=U@:>3u9|zH1֎g}6s\l ' jqi^RAV06g@DAɲFn-]gu'Q22v[o%Nr1{bc:[.(׷00b sRGk}+[zƝsF4x'5mt S.5Fie/ {eZ5,W:A.gs82N`Ȩ{"O2 1B$fsw0NruO044}.@\$3%x͗֙FGdINGM$Qs ?:z?Gs ]g8O"bLV^!dL[LȻ*S֙ _r^,wf- X$Qfە;u6weGUkZ8ug֙CZPuh""ۢmZ1M[7Tgry;Z1RƔCӒ'Q%6ƷLpe/_s ZB">[98; [WE7C0㈽OfI岓V1PMg/ZÜgYcLcζZ-nstCUl47S}WBKڪfu˰+]kn06K3aziix֠a|SF%w1qb_t[&>v'd$鼹y挽u4hg^w3Kf:hH>w Qz,[xj hxd4e?D]'I聤;H.2##GWL<{M`*d'g Q"X;*M/L-2wmY>p\g @-G~t29WŭVPHeCe``Mϸed W_mńq^O@ɟxJd 'd84u@֙zz|&dt= t, /i5Ro 1}MT&Y֥ جzQ̮E|&nWWǎi/7V(3~\V S?:LHCuvlo.Yq q1\Y/{~شΦœ+ahdrpy"o !_,Vˮ 3{ .k4.KAa~*C٣![Ǎjk_-0;n-Xc>#hwN8] _ eHK"n ,@=E[l^ikL s3r%pBfQ3#)fЉF^([-b(;TH)|PlTIu6uf[qP$x! {ԡ]TT~P/dİ`ơ,qpVg .Vy Gz.,quZ}]JZyB-j&<9xFeyYͱg/3;?1^* C'ND#D/‘J7-}}`4NwW##ISV'nc%e¢T6fX uv`@o/gű5?#Ozj GxPh|XNÏW!v fԍ#,Ӿކo<[f;0^t@nB{/e'J jr6pJGqxĵKdKt?4 ?mw&q@;{:NF;*?d$ш]QΆqM>~AS2r= 3K#׽jcL@`Rv M94kLs)TGʶҔ^M ~>08,ٟ5;uϠk*-Y|C?9)P84C&A!uC! Ɔ3x55G}A@BS#$ 4iQdx_r }Εi8s_s90/ XVsbl#aOSaK>C(»!p)g݀dšjpBAw1Ƽ311tC)qg*o`d罅;V!xm E*iU8}LØU6nXPC5 GUT(9۩NsUKFⷆ|a'Я+] +5 ou"iɖ"K CYNJ%\zY 5_K*I.  x}pY0 !^kJ:<n:'.`Yw_"'\\$`6ݠ>:jߤw9է"!}oB4XQlq]%ndK}ibj\^!hk12KP`\B챆Wk@48H\0wtNvqЉH j+]"<1v 8n;بDry`EXo$rsyBߤ䖙{H2O~ hï1+L^eBdE '0C+sCw rg[G^}gy|?kWO_ecFʉ¨ pi/.ob'kQMgF#`qoocE3ar-U6/h= B+ wiUhp`JZd =72< s,K*@qUjV P,tw:Fd&9xpI,_4JLg{y|/=O~b?|]=r4NOB|pi,C!$hBZIv륾,4Ο(y&2I4l IDATύ,|+g-Ϗes90/g<,I-!Ǖ+"O0(˞zˏ̤7I /xZQcc鬫EM9J* @/ WGCt$+t#B; y3u̩3EʼnAM+O"_[sk.ቖ3~vhڇhc=WGLW_aSTR"+U,SHEyHRiȏFv 7]\bqcO# ҶUg'5kd<̆{Q:d2%+떙:strjt~S~<HiK5΄#7e9Lq wnEXMŸ8!A| 36O/?=hq:os*W6DqV62 ~]Ǡ6ڌ|pqɾi/>-AD)uCQ^T6M`#УoZ8ygr2:*.C3fV8E<zSxgfa8[` >Cw^sy<3TrPe5JU ] pf턃 3=BM|.yZ4ށvB[\ǵyu|ⓟ+_xB9sf#S+{>WұXU)qbdЅ=yseZq Bo}BTwהb4t7J o5pҲzV96P!/6_=t~9//-5ALq*qgS#"fq!]Pf`GѸBئ˘w*M1B؇7g\8c iEqN#xqMeQ-qS\Ǯ[a**_hft\.lt^Cg3Q@?]W5r+~:{植,9qjBeFY~ r!3#w{(G7|5*ҩqo:W:Iac8ֽ1ffR142 d?qKY_GqvOF@+/'Caġ47LƉqA'BAiz -3ұT Bc:c w_xwmDLh~1QǼ7uv" t:l`d ܥZs%pi$ZE= zApL 9-.U/?0=8Ϫ4DqaxRvc"-91S%yAb$r'3jqmdOnʨI\GwvpORF&ӤHxhhϥ|`]K?;$cȆZ2|_7OuORޓnjQm$t~+9ǟ)4U}+(eΔG|3O37}q\>N7s*M'f-}:yƸ9Z#0Yn)yn,I'+gr&*}.;s i<%`RwMGhū%dQrUMל/<K.7y}s?/$99qqq׍4Kk\+JXjyƁ6i1̓7Z M͸y 8g(@(3gru ?vBvtQL{&.7bQFpluI<`<Qx6CorvߍԡƌeBUa"hfg+TAKUFea::Dd$Ie؍T=F<2I8|=p5u0ңoJvV1GH~ RDP9K2H 0wuGz+ƵNVT+y <;p (Y䇴$?)/:?urӧ ,nJa(3wg`@6|E a(v)D7Vj^N+ԡ'!>#l^OT֠U;u"gk{AG&ʯE+t;c >7Ftdk`bTe۪BėptPrxR QnTJ Vy[PWN ?S.dlK<&ؽVQn- !C,"̰\{T(2<'Kh nCڮu*oJl>|4<\fDYc.DyH})ᦚgq:;r,i 3nE>eceDFbxzy~/Ö́ߐlqsȐ9bMg?{h 0cD=@>F^$hWAsx yi:!EDѱ2eIM sG )6(¦ny:A0LDM}mg(M}o`T2㐎j?\QI sV8a?ɸBykk Ff&pv<>J#<0W֮7ef5#fɬ0EQ\i143 jh .Q{t:;6n*,;?ӥ7ɧ._V{嶳'X.\ o;S{^Y.^^!;oM iɪu\9N'֔:K};iiǸ^w¥G:gB^ևe߸R,}gZbCSțօzN ˰J'AjZ4U_r~9哟d?s__y-Y\`9s|KpPqGwYAAlv|GWpU#$B~;fH:JbB%̓͌-W(v^wY#񋒉H2> o/.ʢ(y'Sm.9gRް 2sKjpc!s&o%R Y-~"q`W?o<;V[Kc,Qh E/ ex\8bpFٽN9PԤ[i.KSF Rԫs`oVnbR9bW }C|ggw,S黔 8@L\5VDž yn!E&`d4γ=C%g 3   Y&(BȏPA 8%m25:w20F;YNBL]+`& 81[O](s9m* naki<95a:AM;vO69&Pc]T3Ɛ1&&',}!}-XndG>ynx1z!e\8Q g5G >څ> 8l=q]SJ"% #1=Z# w2TVu1X2##(v. bKXq${lm @@aV{g R?+Ό̣!L(O">79܁.S:(P2}Ea{031yu'&>z;U,ͫ7=w^tkx=.˕:7-?| ᎂyfÀ; n0Q pR.,"ؙOZi30z:[G; I\c;:NRB2L{5pyGʽ[N;_+zf|rbe\M̯9&p1O53W7Ph:_gUT`mflʌo)F]ݫ )'ZJ~1Rɡ%yH2;u6ȱJ2,B!83PbW ;xBk21Xϭo '<.F&dEf9VEEq2zfS-0,@Z-٠#f"hȌ̮uP)*((/3+zwL>A#/8^,"`z!k}uҙ |yaF'ۇ1`'lfur2Q(lrLDmI6ڿEYzȘ­EOY)LBM##Gr*-+8qu_m7`׶7C7|3QF'HIi[\ W?!=3Vb l? Q {=b8u)WWqC'7s8ǣ8 }gӱ~WEΜ*3r $mZ#O(93uq  FR2+O|H,oc@g2 hwc~'9 N,sQITC])~Qw$goS7۬V4<- c[Єάx9tchT4 _ljƼ׉x&bapB9pPQ\Nܐo|#aѫȊڕ˭IpBIȒo҅(+>uUU)|QW֏a鸁U2vGa?@a=hL EdY 5Z/wbg*c {iylD|=1p?> =p<4ĖYO!uЈ^isRƤч=f΍@^>q*ɺN9M.ѩcY|)ʝ82k3hhW9 g)<.ItBǒZjf=E`26GrF]!Q 91pJ;gsB^9cyFt F:lwgW \˴?~5up+'5lu ^C6 5 K?^=rpSL,8N.~Ɖ-NkvqbQ{֚N $^n%_N4q?B<2zY58(GFᴈ;{ٔ Pԗ_ cGC3c <`qUòk/?ڹڼ|Gr."";gCXG9w_ 3XyvWA)?Tn(Apݔ Ah_$-'g:d@AW3NwN1x3aٸdLV-2?b+ c.^vVXlu@- )hM K5bӛ_;-g7XI#:>-. rVygq[TQn P%#t; ,wv4|0[…*&Ty3=фʅFRuM&)$$ulg q#R @=̯9^g>S>'Od6oVZĖ߹cV|ەrke< oЧۭC4 N}Ǘ m%KFN4t_Yl~ҢdVSG cmӠ<9۷@D?΄(sj0\sw8A+eL 5,Q& UA&|(:,q;C+#ef4=B=_PI `FՇ}ja)Τg,o~O\)W/2*:Ld* IDAT3%4OyF BUFG6<\$) +2-DodfBe{0Gč[EOpʱ}=)צ:}nr=_.0ð~gmP! އ/7X":\4R:c*WeBC#?Iʱ8&8fiEþ0\33:njn"hAb >mP}4g5+Q%-zxJ VL +LӦl?*Fd4%tB4D;y` >g28 l7`pi^5qN~x/u0J<8[u%*t$!,S&O ] }C lۖ}M `3*a _bylKi8t l3۞esM6d1:0w ^MOB{6ݸ̌Xѐ{`eur;Ɓ~sy$H5fPټOJ +|P0ފ41urY]?nB:s}a(5\3$ 2*~ J(82\nSz9^g1-Wg?gF[NrayӉ+eeae_ί~WYvL9L1 ቁ'm$IrY1TJ_cGp22n(\؅R> sCxhe1!.$YzB&/vBʄt1\11[qc% q1TzgjeW7n,W ^ՑϜEsv=q L 8X.@CfKFe0 P'5rs5_Zt %!]fKfŏt|e_~l𴡌PnTϼ #oeeTbƾ #IY(j=dHWʖ^^-;W_~ifYrOY@s)iIDAS^pXp?H]GdxaHR\򉪀~)VݞxQ/˅O(lBA+6Gnu8{ᖇiHgڏݴړQKcbbe7W92- nfuBH"_TkL b*}hl&˵4~Sv@m4⧱\SqRN&Р>ƸZ# Luve.`HIcpudbkw^8S)ץP^Gk,3cߴi? 6]޳iغD9^V|q^G:\s-ҾEvo8W g7Owpbg%= . u|;^U,3s,m-dxF3N?1" %Lʰ5ހN#HBD4 *90v"> n6|wOJshtp`{e~ #_$}o/#kIɢoc^a%^f᳏42oq6)LۏP+o~ӑ o9v !F!卛B*|FA =wzo6/)̬9a U1Ya  dڶP03 W3ggtGn/S)=3è@!/Mf)^~| O.0= JOL:tjUTk!|McKgp̸$|5>Nvk[f E Yv;y'c?-oyKB//Hyj?p; o;?^mykʏȏ{>Sz_E_pn×ml`(r̺XЪf3d61FǾc!yy m8ᦀL12ЁxԙcY}CdR3c2$DCPSpHX!@3ơ2y8P#\6z(# Ù,"[b\8n;;ReAbcܔQ/~;;!ֱFx}HN~ʼnN nfƾV]XkHh%è4r;LS4A5NޓBCph~+C<(g>jxP^bwSD/\dcA`Ur(B;wdD^O:!$NKB:.0C드s> 'h5t |[EZ**߀mRI4*5}F@6Oh"OI=uԣtn ϭGǗ(Ptq=f~kA}쮹B #{ !DA<8;YAZY͕܋G>FL9OąuH椪* ٢]>Q9| UNLel!SG( cb*ʭUЙ]!s K^4/MɧN[O!G;3OkLi /Q:,kWcRta`<7d=fu8Ÿcb;Q`>of4,+xjDpIFF#xV*y\Ϝ 3mo9UD <>8_S󋟶PpᵍױŶe}g} ZQ;#RMqhal~[N֑뎸ێ'P3/ET^,y76),,uBAHL:x%.N5h^a۹Ά}x5|:,3sOPFQ⤁a[| TIz|g4*t!o5L]~~*rwK6v^}{݁^kixo]F(eo`޸q؏Xh@WS%mDP~󬇓"4a1g^cDKt|jWxGꄟG7FpxNd Z#ZzWiLIÛ|~}v=0y2DIߦ 0Lx.?=:А ޮr&|~΀cS9PRK1;Đ=ely憀ҫ$a",Ouϲ RvgboN!LXOXD0F tȦK]; h?e^F&'kLNB9%Bcv3T8119lW#Hbiu?/=ߋF;kNY8̾yV[[Qid'-8(VetnX1ڧDRd i۶lPhptXPDaX̥Ȉ !0+q|: "de)w鯱WBQE3{`͒P\}NόF#2=Hx+ xPA !'. V F.xx'drc{}uΝV3Vh@?u2\fVVHp$œ9(Ƭ m[ %88x瀽H㵜{q>Nr曧Ia_履G>Ӧnx&hЍO~ww__E+п/(sӟٟh__>S?u0Q@Wo}_~=yw ȏ>>lzs;=۴oIWUk^I ^WL~?7>`\u8¸\`/eVH1 9߉yhQb?up'|e +#w&fg~͕ M27!MV8wD |UH=o_#x"o4DyW[(3x;(*o#|CNg{b/O(6>lpy,IISs8L([k2~UkR;$h" 6c Y:ǖq;>Uƀ5K0_N?pl'~Lo(mNUP.hOk A|q%cJ1;p;T\ks3B!y}= =ꆶ+#^+ zqm3Sgy5-zc۠mm.U>mV3NY4 <&= ߱K t /jg0>5xŀmQNh & GGcjt 4h;\]8|ƴ 9)H`meA8< 9o7OJJʬ+*-Ҋ _̙ IDAT31yii// -T zhtxӞ*/9-W̓يt|zYz?W/}K??L~wyO|z_|ߒȯ/Qگ[:(o yJ?2+=85x8(|!"qaQ|']ǥ%@኏3+:<+h0ϰҭR5+ # | W**8gWT-KQ;:!4O:vQTZLYGQE]`*VekZ-'<߸ |9Ϝo7ve+"$`DG[Ehds_CY).w,#ō2|/ğ;{!9pۈ"EYA%Ǻ#o}Q_Ft%,N2P/BseCJx|c/{?ֺpt:R앂wq l{0R'ȅk}@ūTr׾M~LTvAI [#\@3x\{$t_<:Syʜu秬dl^YfL^8d$U](n"ٓA+]HmF;8[O.(9{6ަ}"]^syHV)¼6J eW ^/yH;` ֋|'3v)Jv KW_VӋLz ^j[82 p ʽ;{WեYo1a;SԼ2yu?{~h0,c|e;`8+B~{KTi /y19l#zX{ʒJBX^mN,|<֕8CW36qO󗂞s< lvd6)L (7@QuD*0 *  :8 cUTTdoKSDdcVSo8S*c)}4pu&S~wUCMm zf-ҶWIC^*~=T6qoM4H[5$iM&lFh0uot,ː1D z4J *uLieیmò*O~.C%; JF˄Uu 2g+l:tۍ2ץv1-6[/Ү$ _5Dŷ-y[g["LrJݹv)G JxJ3S:( 2hj6SrU QX/= γ/4>GOLgoa5q_cϽtZknC9VPk(Ep@V oi|ox!bۥ =}@B0lSm+Ʒ'nl 4XAN|a 2"8o x&D̦Dyj+XL`GY8YF0`T9("cP 3K0MlW5LXiHO؇/+VሣƟaCpDYx@_u AM7}_o\ܢp{T npUG$^e[p*c($AȨLr¶DB\J^:yOE|u]$=pΘl߻['k|-pRRLžN9?)*#)4TP+N\̷NZdkd/ޣ8[}_~Tc|;[-2(*7»wKe>Π"A!5@pN. ';m5IV*к`_i5rHE&EmQԔD–ܞz+LOʰ{=ٖ &Q"wx^?NlWfZp\Á &y*-ʒyݞնI~)l,4l/Wyf8|OCvʴ$[^cx>*6C_! vee؎-`r<ÅO':[%ͼ|x~mixFg逧m!ea5"t^}s(>v[tvނ.t\UfGiֳJC(,e}vc[s_<e$Y5o\doSmK%YF$ Ul;F jܻ 7aį"f~ybxtJm`̨%gʮ1 6L)r#o)A掠- )u{^ O>"Ȋ_&E%=7bXm u4g]Fs;G!R/3O+zA$Ac*A[m;;߬=" {ܽ_v{Ds wwoiPq Gs~yRxF+y`km'@P*8 ΝNmQ߯={Z3gK ؽi1oD4;v>4(g>3[ _<\AҮ>?:?c?V[ӝ)OyJ헴˷ƌWx^vtaI`~?L<`7Tacs +5cܽ}kw$)Ӟ=6x̅)y%2,:7zEN^$ig#eEKV|2#׳BAׂj2yb޶LezV#,3&CrhغmϻFEQ\P8W@{_ı*A?$>~2;$\7qC2҂eWK8@(*)+WY+\4XP&;+/iҔqjS'/7(#8 ;˨,x'}Ϯ (^yJ^l+paO㔛)_pT4Xu=#È,CA}`ƾNj{ F*r "9T㬸 o~ ֈ=YEYKC);ƗUWeA42:е)Tm  ɒF$PX6)EP=֘xL*';h*/S!)(7}~\nKi}?A?S.c0ɳW]Q^*c`Q7dajO- yI@x6L2:yrފVO E"|XF":fouyciL<]?V<@jKM^ӧ?C؏l =`گ]-_E_op[}囿ϙ*^ƄoBx_@> 0u*8!Ϋ] \$AGڡm٤w"sJSv)qeMz"ITH/%PURpNWkfל|܆ &%W@=.xeXd>w w>;0X +iTPTՁ5e`+9C[rBj#p]-% فAeV}'!xϼ{]MXtJ)JWPs~[wʃ*$+bq)*v(Hc]G_c2z`EAis9|"j5STgq/j G'9ΓWi۳@,yp*h6Gy ½z>>2(P^F HpngaM8 y.{""mN~bC{ܽ&N RcK۪=8G,F7ϵh91+;9x.*ל\o̹ek 9moۂ8m7ٖoOX/#E⡁t=8aWg4][\5BەQgP7cnV˪}yW礹ų xBٱ PQyi:GPޥ_ԠӋ ]$).~RAO?qaC(dzHD ;K򖱍T5Vq2~;.ܤ2ZgSvY&prm߂i,C/ 6"\\[G^yU-,\$ cQJS)íp|񰲥坽O9!t]q|\e>Iox'Cʨ@hӍ49 9PZ-l-5wTmovx;'3C_GNK\Yu`E׾o )R@Ln0+_] _ga:0O:O,pjإ@,nL2I\3B0υb']-@-~*o$A$:_Χ[',Z>ms,'@w~BCfd\h1Ok4۟}݌Ы.E?Al::K_lg_U_*ז4//x &W=\Z+'~'v]ve{z=qJW7~7Nx#GM]W^~-M?C?=t__BKh| WI _ʷ[ok<@Oez T>{GkȤƍ79ˇG>>}8ɝ'NMO/xҗ7=϶|\@hx x/9!Ic$[;O%i+P㊈J4fv2ᓀP;yF<[e؞hȗP󀼒B l\rjdU]%)ɁˇYxr8 H {ٳz a]yNLgҷb8ލChm̷Qx2mvCse ?>SV4k{)($H1N<‚|BrVu%CnټӗglQ|ĿTx{<-O_b4BO-JQi,3kbooy]} R4kK|k \?k=IYV^^b͠3B>g}%euv*>-_%>(=cٽe;W6HVYIZsݢz\ % QW? !z>4َ(lڃӜ;!| J<ұJנS{=߳@:+#_ xxsTd]A3KjDQ`#TM X)6F.T Dy<ˆan83H%v1mfžv =ںt@A*ƹqmUøjm[Yi桎[ŗI=*Φ-0>?&w@E<|wQ~ME1]|xS,Ge+VAD|UepU^%9C~ِmqrtʗ7#\y>6 $_AeBed o[ְ] 1e,Gg9Oژ9 \^1?no`2&ד)(7$(_"e/ Us.#4)+?0G(09W(x$S{i@Gw+&{FlpDe(!-N0oyJUsUHh>@l !>*tn2r ɺ?lZHS+zL;}o8ļ -txmW'3_J"HX^]e;4A \ )|"Iλ%a8l:Xus?X'{a^ktv?W!Tf :xx&+r //^1O|J0?7<;5%%Ceڶ2N/*%<`OI1m @/Z)!sS֍[Q:eRI\y|x?XŝmɖoېO< *znCxP*Wi naAVRN08w`Nhūx݅ Vyr,{4eUv9 {rz훐njLu8\x̺`?wp75V\J !x#xC/bj藞Ya0ERvV'.-uH7MP4Olʺc™"FBɯhL$@@  r"U0a{ˋ2 .ƥhp5LYR~q\K۽mM^-(*l~o'w,iGn:}iPy.ymD:xX۩x jkTt`ϸ@ h+w|,"~@GpƢh\˗Ƹ w ka1@6&Tp4Ѿpw^ 峧GqS_rE߽,)NcH&H_ǡ-0F|WW$s^IшAsu+& 3˂N2" BTjnǂEoz0n" tRCt7F9_ya402o D~[,h\P-Y +йߍ:YRe+7lz_<ձ ?;c':DP`3gY37R<8TTDuu6<ϜtW\W{{Oj|ɗ~/sXtW]W28YfHtOs\f}}xqB>~}]&?YTPt253}dC̟Ov+SO'˻by/zt˿ p!(>µfK4LwRr{KH37(+&ALzE޸x@S!VVlgL P.Gg,4*5.K+W1w>kxWSY'%2u ?:N5 hWX撍>mJ,OWvAHwT#2BF~erKEi0**R0{Ct׵-C* 6\Jls+ծ˫.<=3GAJͧ cm"|6\`{b: 1t@ղ4[CM@KX%=Vcn$#X+شq p;7 QYSYU7/.L4V "] *>z9TRa 99+=)k|QmII-q}O9~ -.%zX˃"LlYGaVaɵG7y3D@i7 U)KW"]M3 *r5boW: A2^' "(H?cN])8P>i8̡k<,K~S!ߪ.'; T֯uQn_<}mC@  `[zTg}=q\@(]ƒI*"rlC*vry#Lۈ)6'\oAh+;|ֈcA]ffʦ >i{9X: 38G5yaP@Aˈ'\ScQl/[!ܽhC\ExTyF#&eg!;4xgKᷜ?Be{b[/p2eêjhe&Kf_KLF(g'zmƀX^RF'(o>G"*/A+]m5:B_|~ww'n9ݴ2u}nnn˿*xW$%ph\f[pZQzT W]'^]y|݁|Pt 䏧ŋOO雾iz3ֈWù84u@;zx1vj@#zB.{JNsf!91#:~aP`>99- h[%s>^ʺs۫s\¤('t弩> v zlkX7];^،tW!ݲGe@;'tw?CS9e]*SviVqKaL .80J+4t*=8i}X|t{A40{s^"3wF!ez2Hi7}/*F]7AiE*_6ݒ՝WʵԛD=Ik>\BPJg p4Jۍ ! \q[=eOr ҙRoRB5d=G[d0 \~Cr+ޖ"9Ш j]^ Py4JrӂW^W% @}"PAP~Kz3l3i *(N'1_;NexnWG"m}9 4P4hX%'oF@d; i'!9\+.3'R/:pza -ݏ?}<9m4J[#לiP~󟿟zի2{0 w{NW2C3{O}2B.=z+|~n2r =W3u뾆9XƁ'> WҐQ]]{BIx{r`Lw*W;ޫx3sp2]j^cQHE Q c_vqg4 2B'&'S0%'{VGAÑ|i&FOWCPˍy!#ٗսzYxM:|vs- HH)ZV|]BWv)ܮ )p/mj%sU!cJ,˴r2FoyE3sAmKjr bȊ(+~>w)Lt ?[eV-M{H'd4?*H[V⽏Yh uJSVeF8w*&|LP><6q [v+; k}~yq`mt<\PJ- P.-te>˔E*2bVt*XdFߡ *igԁtRu Qqi~T>l灵zH˦ɫA&R*`R3`|OP)}/mQlF:3@ 2m\Cq o풴*XdxgJEz]#ӭ>1æTjؓ_@}o 0Clpv{=vhGP65IٮtL0U*wF𶆬[~;g}d[n@"#0d"Cǂ5&2#CM)6^ >oRY 菉|tZy6 -NU@kG/*3?X#|޶%~{K@} y y:' O>{;].dn i۸F^Aܡcj ,YiGf @Vij#61xW=ȭ~)>rW7oYzj:uOkkR!<Xs +^UiW y=@=PSE遲=}ٗ}>0LYƫa׳z=y³N ʷʯhW/N/^'I}檂<8ҳ ؀L6PL8z N]G<>LcGv!L>?> 0&GFINao e5LG]cgyVɒ; ?;,tM &a1xVk7'Cy]LG-vEx1ʾH{;i^nzf2ʃ"3 h鶁|Z^!/78 NVpJ@-]C9rn^u0YUa<3|gCӹ~ϵߴ 3]heGC:%+qp|n¨ .2(Ӭ%{xFbɟO})}{B ݓdƴ\]5w\ x~=io%W|a.xX_yqW+.JRl*W_ ?;m{0O$ƫ ~w~q@ooH}^Wtw8ƨAA^#F A'ےF,. xXRpScun;vtLmHϞCRhc.`XI#ӯEלX]aM&ۮV GQ* BA১2N =VJ/!Z+]g~#Uyp2pеʙQP!/W( aȈ#!J i.IɖӲwa4]X u GVQab4~ ȴ]_K;s $>h`X!* M4TY F8;m >P>Y!xgy*q#Qwſg *P>wE@B wXTa={ 8`+GjPVdDt Q*=Q) /ӄbxڱn9Vjl_[,zqpCk@l7&+H`-j_,Ue" dL|h^_'Jy=~a1V 4\41A^a ;tҩRGb}goc vrUtnYܪil'3hO m]bdaE2og5b9R㢩 h/`O_rTڃ?o7W_ TT~vAw'TsL  _g&0=)> Dy+\SbE5ƩcGN@gyCx%kn3V(;R"4낮!cUM/X W"ŵUEiƀzmO5S:+: \sM)ⷲu`|BO8fdGy ##jh_!E2XFrZMbT .gxD\{!W<Oou(˰X*ćl#Ӈ?\(j1" ιZŶ 烌LI[IW#O,Foyo@'*K:3Nl28K-h>q| N6PRw ԭxz,8ᐺô ;. m?/OVUMb]텨ڗ#;?#Lz1ʊw|_;ڎD,GۮAukV⡲٣ yp~^VƠuմ~ t\yR-(fǦۡ{^U1 #M0N|#mx]7u(ێp<|]#8~>h\'S܉Zu|C8QmIJɱHϣ dUȭ6czpK|vK\l.ϺGR_zP!m9א!:g: o_YV! VEclK]3}~E܀y.QYÇf|.\KZ]P#8j\S!5xqC\gM]?pU-N;wOArq HW-krHXtob"I`:o(g0mBA6}I =mcv^89~}[Dizqʈ )OpC|J̅J3-oy M&Br*a}3=e 3AF/]]GPGT a\71;yt7M5&yF\bk«xHcw[:uoxn@)@ i^VToO롸!akyuBxԾ A8CCFh?1fL8̩U o) "Rrܝ7f($nSI Y+Wnm3?)(: "xʏel d*0am 8`ەs퀌 `BBIIJiP",y¿'Z*poG(p^x2t B^*52 %y&}S)QBXy./é/Au_gQoca{8)3 CF YsWws*y-bYV4ɳ=}+qxKSP<pMHRnT!K됟o0໊=<H Irkez@m st"{x8MYûA:1oꋣ0l njLZ +¶3H>$U$Cpqapg0qL{O -u\cw̐A=0u^dqj^ />={ :iaȞz:ub,~R+DUH$^z5G3(z8fTM 3BsJ ;,aFZ`?Ì6i`='p“zvɐn΅O ȟnG]4h@ѠKlT"$ w6' !r6(' {nh n9_y{K6Ʋ |G s$A3iTpkj xk= eTeoJq7*LW#ϥxxj@f=ō {Uk]2X "l~ͣJMC{uxx@7SV/l/m_ׄjmCQjp/͗lH߇o4?SӳvlԄ? $udNl(Uę"q6Q`O5s;E߶>*jP2?8(==oh~l+xtnm߶M/2boJ<&oW+ZIu`= #F?zPͼ.<Iճ⟐ (p\F,փIzy~l(q4M?H:,o*HÂcY*F8tS q ySPaPP<8 Ac8W&8G#gwSӊ<2pP™Qgӹ߾|hQ7iw 1(g@=_J >/Q˴78³n`κUGcXe[))a<zT88ڸ)tmpLR'((O*4¶p!6e9Ld}Ry>qH_e[̢r5ER;Z)2? \lhn#,qx/P2fon<[$hTVвX& H|t\OCd4 ;>&Z) R4hsNpL\G?/A|y~I0`/>!¶V-&.6~x7=k?|4dJ.>qQvv^p?SA%C7B}0yj+PCu(RL32% F*x,v^N!k8w;* ;yLf纞ߙfA(sn>̼[뎷s򔢌 ABys./SbW"nWuuU6" H2|0nhpW{b^{(=WI<\ *cpyx ?%9ĕ:/gQBX 軚صeᏠd0}r«sAw6@8:yǥzr~tB|{H O@uGM\Ly)b/N 6wI3шd.OW1Wq]P׎DGxWʮŝE[a ʠAZ[ S߷G< qnԓG/ ˓Cq>#Sm`=w$Wը@.A2e>SWU $rUӚgr[1GN'֗cVމ1;$ʕq1(aݘôɧRm!\TNhiul0oƳ2@;djgt~P$k+z|cI8j̖^YѓBÀ}c gϭ| d9m/z8[Dub_ژq86yA0 K!065 h ؙ!^Dh< }?\͌$X(Ww%'Rio;P^)V[CyGˀ+|qkRӷ )V?7b$P}e4W ׷U> }Y+ Ғ!_0 ~ylxI~u*rZִb#2И}IȀΈI$t&S}oy t50f_(Uzg?3txN97^ IQ M;Co0Y!4v p8?_smo 1YY;]wu 5 )9q|"',13~ÛpG\s,$AjGWS東w^Aڕ 6v0h `nC}`^Xy O, dž$O7s>lx̗LEvݥ=4*T!F(`V+SI)[i-ych-5 C᥮sS|,nHkGHNĠ<+@c\'gyk&(gEy3VMfoӵ\ӫڨD GZ*;%SmvUI'!vVO$E~!< 7UUP/VQ#r#J $Cnz_>|YwzBaˍxK̐b/vXXu}gx3\NۧQ߳G/+lx`;zbw7e, RlC-Fu0q!\E1l3gc\X笄 |kȻ6˖o,p񛮧5:gkx⤤_ŅeN@OpJ=w/ v0kv 8yuHO8cJ,;-[oxA'9t)Oykéa,[' Fb-%=ˡ~w.lCfXc+S)o$T@ or8JEJy4\ $m&B`V74O)y QjreHv| g'`D`F 4|Yh`@Ç5Ebe-;܌m@e~/K "޹7<1c e]I̶7^R 6T?3"OjHS<1\=a/MBH9xN :nإa:Ewj|5h4SfrZYEA88p23킌* e|7ܜʼssM<ܼ#.l#l#s"xLk8{ʌ9{BbU:' -={<MV\mj|ΤP* (`62Sٗ IDATHJo&,QNs O_}%"0LR;+@Jɺ_ :@o@Hcy1 ˅Ao0@)-eȻ2~֎J;U[m{)oj#ɀ?_:Nx4*=8.HemJ僛x&Ӑ*3W%/yXcmbM[_RoضΪcgw /dc'[}!nxSmi"  AOk!Hg cG؟"`^7rikZz2]mRez %$>:U<c.*C*lh5A9U1?pe^Ɯꜭ/!<3.+"lh3QBR>dAh]9e&/JA&U.XzPg陃w(Wqj ( fåʙ7<.> -dF:a'd#8'Q'f\YF!BU04/,]'Nc_g~;;g%D!xϕzZ|O|G),-DJAY~Z ̃ғvG@=P2,u|:!>m,{ e!EqR 7cAA8i"ǪvIoʪJ!gDBD׈w  >9L+xAm$-_cC88%̬]$sXyFǨ Qw~ʹ+cNHTof0# vc2-v[dT@s Xefsx-G䵒uxgj8TY &3ޭp(|F iH zNGnOj4[CZ۴F:*v56xs<=@0IYԝӀ]TL[\<'d4,AztB 2.q=&+5: I V 0Af5o6JmaB[Pj|}%Z|ĝo;! 'Wv4YP2wj@Vx^6=IO}8Hps89ڟ iVhv699ɹΓyx3(/󼂡A!8ك1yA|:egtWcN;xˋ޻Ȯ(nQvQƉGh▸11&Qc\qM@c"ƍE$AZw߻5fg[˩SNUsT 7tʤD\T'|œS$]}pWgYAVZyX{JJ(p7deaSh4Z\ nbV -c؈od-s*75{kܐ+˃W'Nc,@95/9h 96[LW%kCdk &U |UҎ^?k\Z1aztiزi޲aSm]x ^g(s'23no45 qGahP;::.z~ Zodo;64g]f$mxCc=|X<%{l4j${+c20+4ֈDpxWJ cCnxq ]pvAW2Y?cx&ukܮq¶ϱ ܈:艃l@i`4l{MB5F߇1 g^;;L&D &"m|5 âqw0XD ; d)s Hw0(au,[`N1,߂|ia}GޗAr?3 ҹ˥4i8HQ4^ >l`a]Ր*73`^='bYiO]qꕈHmxHIK/;tiѩH5[j!\k,Q`?|cYu/\UֲlqeȓSS~;O6N~)ฏsΉ5򻮼)8Fi憶By7nqwԫYO'+8Xwn31z(H,˫e}zG}ez.rQv4قt@dPg[eh Lwv8앗᷸lc]#OtrFݎB$ +:.j9X?ª>@ZLH4>5$*٢: M9]徛a1!"fTR&@; ]tޔM87Wƒ}&$SU<4Tf{k>a8ѓ'?""󺰪Az0C#hGYoρ\]VIF'J5 P"^ӊ1n] ?UyeOʫ zJ`2=$[<\TE1]"ζ5\..Hl/O)3TUݥmE^ܳ/}AOv+F[@;,91؞ad@(^UcgQتAHӹ$pZTe3Ơ RlL|SPM!]YI"2 O_b9-1\3t0%d5tE M/[N"Dɐp^ө\SL !h}RYԯ$$ ܂Zpd85oF?~x Τ6yB6^/Q ;2 aTց&L+74ЈD8ZldSwF?pv*XhIY EJm% tU+d䥃+1K[ w2d`pT_ٰj[ow>]nk!+cG_V2k p~[%Ė(˦@UߙTzB"eS5%ά0Gųzu~F#$ޭi{ K:[e^y^x4ym/$~Que@<)Mc4 ¨?mfғzDI=玘c})F_2]^8g@ "1P:w-{f%C IW۴^ 7md5n(E?+eI"35IpS8f ]|ѐAp˽Lib]ȴЬr j7aH+x.wzR[G8li/q z}q2H zՆxpg݅[0xzqͥweKnE (̟10`CP𷋭v5^㇌+~#~wbln~/9')|1CzE);1B;p˛whlmc,]XԵ1CՂ9H(qz= 3dt27(Ʃ{-v:ɛ1&'Y 1 Hr@툧r\ʥ LH8wSJEq9.i({˕Gjè;S6˱*Dě2eTg~Xr@|K^~xGJyoZGK^ˁ֞.5x-}ԉeч}xU9/y@4xz}cCe< B>0)K-훛 `:]31zdaog ]4@ԭ 66t8_0F"PD?U?CHI{RAV9v6o 08U!=N=|zU,_YQԩii1bʶ\a!BX_Ѻhƿ:ߴcA壽o> Pw B 7 R“wg|'G<4=A-"SGӻeKKWqUس:-<AZ'Kpф7y2x=bMi+ @/pU?4'T>5n߇p _ ӄpU#[ :O# ۩C7_%l}63[իR߻dư ^AmJ  Sųv,ӊ㍷3{h۔m_Gqv B\Ѿ x y [ )f.^ωk_*D(~FЍMFWP/@[1.Gj-h3r%%k7mu7WIE(Z<$uď2NF$۲0H +2|AcЎs\#N\V۬ev{ A$fTvFoyB I . <`*L2u&' N[y,> 2U}́[$ 7F,*)3=J`ay_'?{' RS 5a78*2yrz絔n9P3!RԶ+R~Je:arobвdȇ呧W^Wej|+|>U&F@4`0U5 +#IcQ,gvJk-'S[ͼ20*XSg~7alKm(̠K 3AM ]ȓ #|iG%:3 azyahma6'ppMҟ% e[`nW޹PnKߡ1>n)[9Zv^vQ2Ƈ[eoUvK(-QGD 0#41!TEi/9\ݘ%X1/r N z`}2g_TeaǼNŁ_Cwy;pۜ7 a;u[wKy Y9-ڼ<E{(rTa^Ra댬T⪢ɇ+YV?; Ȃ7(BvpB UށN(*9W&>JNy9SK=tU ( Z_V(˓*U'ϵIA@Cԭȑ3i@^*Q(tEB6I+Dy%88C 4M2R!EV 5XqW:i,65y!q` 蚮| \Gf|l4C0A|VduEH}R 5 Un<}L^\AdT0)2id5mQl G|LG9y q؇Z'Zq[Cm VM#]GogF!-0X,I~;<銻c:^NGx5@3z$2z[@ IDATxkg]ѷss]e;ZpcTEg<\"Jg;@vi= =0($$Y*L"v6~lHQ )4TLп{Jsq7u J#īRKtFA%ScV" ș %, B~ZtV i"a0 ogr㵟-z½GZo*|򝯝_>{uHyo.7]嚯~= DThT? =O-W|y9Ct (W9g~?,?)\nu|Q?ogkr\T>? nSWb:0Ԃ<?|k/׏})SIa^3xx'_󵏗]?|OWMʢ\Eg E蛥V08ZL@uanR1(^%SKc'y$´}(zI$xA~^;FnHy<]( #(EP¤|aP@{wKC@^~RA'>5!tBufhιTg r UILyu)ѱY<^iA9ci>u$P{'Lad:{ʹnXdzCr^k~<n|c+/}c_傏]> ˓ra?lݲ|++Y܏~?)o|G?r̽/|˟y[yk|˟i'X9='No/}|9gkv"Jt;m۲nzuy[-9嘣OMPv{ʆ ~t9)^.*87X.ϔw2׳|/~ӡm tC+(a[Zt7{FVx%x_8v4NG8+& 碋.ҟ% FПW`af?flټ|36SƷ*\l ϖ*{L|,[˦-e׵,Gz;^>,M<1]zW9C[ ٲeKٰastٽ{A)[zSg R9ǪI(tĘ/ɽpE;{IӅtH-Ü'ʺ@KaU!N%JA>QXWBFNM&Bb7#4P%e@ 0rA^Ӹ@0\^B ir8z(Tz,yO}KQCʬJzDt7e1`Xp)˅rɓy6+M$QP4l Q/h^CQΌ'qADTU *ʒP|ʚJ q]WQ% =+ `9NFiDD 3i6ʲR^q>>uJspݭB٤oo~i=[n OYQu^kUY"jALshV Q-WFh3Aje(X\_E7b.O'z %^ܩ\ƻt \zmQ@h>$aQ &]~ m ymO f"h@^Q`'U? W,k2.*yL׳@{4{nbWo%ȏz/1|Fa}tHrC)0e 1a@ uޡy&lP51"O?jT'=+@[/hQη %_2H% ~Ήz@$tn rΊeIOt&/j,P=un c19g]Hcg TwFXl B dܺ4; dYQu0z1D'{:1"Lcj疶n<˦7ob^)mGs ǔ~I]\fl)k2 #.6޻6#;4HC0G?~S{C-7w\-߻w剧?|w&;,}+c/D=g˵7rO'@D9GXה ?//%lrPg{GhSEhf1 @t&c?c@|$e΀($\.Q2~1J^H˭SePo9]ml(Gϔ41ߚ)=L4mϔF8L Ze1@e *7/4}>Lҏ% ߦ@+Ys@kuTOtDXhqaUڔ'4(#XfPpܣVq<z_;XpVa1ZJxbWeB> W!J$\F'ϊ-s ͼ. te|A#W"t)Wh #oh B- .4Bw KZgyob&m Ѭ sMpottxP^(J4m s 18tp-򧊰Ϡd{LRV[Ig]LBwI=.? U5g>A["#R^*0:Q˛l|o Sijr_巶ebЈQZ* l,`Z8Qm#9>ڥCa  mnݙSKqY>Ǻj;*5|UQg5>nr#iYW-8F<$'6OP }D%Ť<*ݪ++ ¥/q*#w)d)uZHֈ9m; }5q1S# eTS&p]*4_=L]e-r{]P%޾^3%t53B#%ZʽAt,Nχ1 0BB!Su)1+$p:7=(,4PI/ȇާ2gpu 1Y7D?h6VC=pͦXh*<Ixgg|v 70F"ytg BݞC]qgV`e%]pl92rFK'Yp5v^1073:88~g/Y1Z0$XCsWF.<<&exmS Tz}gRvBԍeEy*oi"`:܎ pJa֕n^0/$=씙L}c\}h|ċ2wƪ7k@eڵerʵv/ᒏ󞆡fy9`m'r?WyWa~lX6%vۦ\~FuGK0X`:+)Odz~o ~ 6_S:p4|[_(G ۡSkf8R /q`T8 `W-Gv -^ # ~Ǖ ҳD 7`c ),ˉ7-2eX r{k|!+=21'!&\[ӟѬq}kXɄOO+r @ٸqcy[B_l9d}J@VywՎ΂I9&^V'>B`.]T4QHߧ`|\%V^1f 8)a|*.F eƥY(!V-- +0F!,;i[*yUJ' aHY@XdUbOMIyGe &լ+N$Lc h{X| 8ܬ#&^'?e.uiy4yx2o?IA>4{}a,n~|(=o">ƾ 84Ƃ)m4CI16{ ֭ ^)^,tzhăOh~قChXճԯlIB/9c@e쀕', I:݊tsh v>^VO{'T DGEfHr!7v;@. T;Y'@%Vr3q s 8a#.ƴ]JF]50M1jt=pdVγVb<3Out UѨ[n⬃ J|y$x9FegmS U|Q~1\G8 Gz7Ss?=^Z[Y`t1srU{=G}DQژPד&.9e=܊CW[^Zˠ9 fns!\`x穏5³t6-2lJbEM'(G9x;1C+1PcZ EςaW6lXWip|W9n[Q/+~#ׯ?^(>!}Kv~e^9G ?qnQn P~C~&m۶v t0:XX'jLlZn+p[߽/Gz`\>7*vw-;īxʹą;&O=䩂Ao9rm.%B |:8ɰym ;4 -l$-oXr8wC誌|:!X}&zk)~tՀCCDǠZB:l:SM:]慖i*Kد(~ugiilӎ2qO|OEn< 4XbFĬ|cכ`bpYC]UbFD > v<-]-T1h_F'*eA_dA.YG1v%G&sseg`#PJ 5H}|O#$F@z ւެIz3;/&=8S{:j͗ SMIedˢ+Urt.(HPqpbE)Ն< ҧIsNȂ9( DaF'ͭ2 UzVSw-"jY(SKٞ 4ya F7?Ubd%q`J_ہoΣ}ת/ym*t] %*+*S4FA\WY2hf2.֡/ (ph[KTk aqw ڈ>RqZX<dDoVݓW=Ly &tK4=^-lu+$|s1*`=͇\ZPw@/k1)4<o ؞gpeqI#LŃp-9`[tGфM:XgƧ^A;QZ!ޫ6`jhK!`t'Ef)T2 f!$ZaX';h"4YB߼&Ĺϋ~sq6 ?-g8o.-7c=YWI~.}v9Z o=\~uL[kLĿܹuG?]j[`> oXx<o.b=7OL4ˍ?M͠CtrI'prilYm3U|6w~|⏗5}4O&foA3BNnQ|˟򖿨4E{O<`:h5!a4 4@CqBb 0.0,zغ&閞% صsWݴt[ˇZSծ#jk۰o`8)pڑpc}TY߸G>3sIg?r! -R: 0C=gl*W_}uW/]O?񁡻\2&wVGhI?Kp.G.FPsP@`QTXDS$ɬ*)ׅahL::gs0- GO|we=r#8sZ=LjWǘCAM*-QVXeIzܣـ?wEz=Xw+ 6e+eRۓ;򂊼O>Y <^xC@o}YaE )S( g:J jyVʇHb5"T*qf>W e\*]чU8+nӆ9zrVA2/ CH:etEV-=Pٸ!g;@.<3:FUS~,ֲ]֘bE@p?eC|9|~ CIg[z}^s/QFRTN$}nY*}k7Y.}c̣>sHWq0Zغ/o;)l#0 n}d{U>Jw~viՃ!K|Ds 2OO+qQK=2J]*F0t&n("2oakD.qDzv7S0y24^% `?~1?yhd6˜)c❕{9OmuU>md]wms5ŒE\˖#s 㤃/> &R_ي0 ItV"V "dA7Ԏ;Ȁ cM&FĒb >= JW ZAw+_NequϦ׼>C%o:qX州r 3`Lı/;qT=Rۍ([@{a6EӼ甹=?C'S'ocaa9,ԧʹ[o>% B (:oz;"h#KPayIpμP IlJ眥%%SLgАM㊵%+D#4Ea ->]4n*{0x]|s8D`')eZbT,9EC%pSn CYC%κ(y8 qD(@j@QCPm=ˮ;VBg5keG4(΢P2eǵz Y~qrs![RN*դ6kz|Fn-9 T}wt[;8aㆺ53"i>#n$ DKSi7u\8H)]m/jQ;>J1n})2lhۯ"vs%:e0vYVixTnW" \;^#ag\" F\y9^CÎa !-" 㻸^ |@. ]Aq̫f{0 yK 3Q0YүNzP67AyПeB;[ALz W@{:P v5 mjPXjieX9}Bs(Ġ`:,Zvȗ{5&a`) Br(ck,{wWf]s+þ4xF|wSxkcaS=资c,@ O"Ƈ9dp@C2lUٳ24fK 9F82G فVܳt҈4"C=;Ğ'5ܤo0x iLehNfՉ'1hN$նx*q#ex_5e,^ǁ)QBI+s~u6Yw @d 䦣=\[\{9rYN=SÌ,]刍YX>qr>m |窡rTٶ\],u5?*/{ˢ{P-xx~{{i'=I+tPL]6pDo L% {)kQADZ{ԍ!< ę rN999e03f392W*hU4>UtA7Ӱ,N7+u5s XPE֣aM㙞1(<¦uqo@50x=Xح {|֬ٔ1$1 JuTnvb Tbx\gq)eP?)g2 5SA8{&@h`}ܘʪme< ;ҠblO14-H/F.c4 X?鳆kwTa,` `y7v:3W!nbSyE#+ufD$渖 yJpfT'cBqU.0Sy:mdQO(M\?\㈊䝇َSx˨rx(P׸S)(Nb]1 Th]wBH84*5i'B :$=#oZn#3=޶dF9ɯu.>&ݢKE@h0D:Mex,,8ע[2J)O":js䝿Wm^5rX`Xd>3 {[D%>P'nEN:me>yÇ'p&VY }饗FҮ@]>fI[m6 [T8[v;H@j7wE"Znνjuo[ ͢!O Y, <( Bvej& *9¹=<$p׺@W5mErbم/aYpr6x`z-(ȫ!/_MzF i2VX?f=R#v2'O-_q${Z*}rAP y%T+hTD~SlԂڅkl pD&l3zw)=Xugk(h`e>0J5|YQ/a^nx_8zH iD[M(/,bR/Wz0Pz[3f=!h X`nb;v[ %R %9IFN%RIVVf0<i$(D9m`I{_r$_m r Hxa3kWwrc6PÌl, /93bpmH?yܧ=q[Ě5;;o}g/_Μ|Wmb p?y{)O? y[9ssSns?541~IfIF!.1 6q:-+-;'8.Mvp̍sZ&We2-qЭEuNnT_Ab(  d, ip΋!$I@s HW2ܣcC ",9˼-'ĻUB%ղŅrtUV켠*@W_ & VzRi:ibHxWR?H+28C;yL "DIxM\\za )!99"A@=k’Aޘ<*9a=aݴSn|'~Fu&UXBQKU1ʴioPO vcQl$+n)HlZs 0^vKAQ #u.4`04܏9[a(>I:u "5oәN7ݲz!FM,Q^-PQC IDATxFjtc'uҴrg=3ZVF4EcB<Dz1Mogh,;b{.!!u ,ŃIAj ɸÌ?j0|$vLhM+^j,sHZHXyxܸt&ڵxxLn̋WTY 0ŀPklJeϱ=G8_zN.G!_ԇ, aLh#nGaϵN^[GͶ ˆ! ?\Df6mn vâQv LL~ɣqҕ~ 0,1-4qI#L#˄Ě¥`Ya>GCy]Q,XdH Sy!>qv/5j0#[ R' |G[D ʗZc>v 5,QWWxqKܢޙWŹD*̱0:W2M8WAnN`y)jt9/#üqW)W:`rsfCNQB`fEZ$L|`MYN8v6sW*V +͊5B~k[s'(fe~tY04L< s#_$9(v**0+L$e5mcrM Ǻ%|XR]DWqBfqL Y.u{9RV]F|s8xe[ŧKJ+へO X+qxq }oG hۑ!_P<ς⹲4YI>~d;Z)nbAn~,N^RٽV0<DZ=`@ϏO0 +.C(5JD\!]y ;ʽ(kl؋{ֳ}QWXUjB`c8遗,Q/rEV eߑW#Fɖccdlq{#@N?4ikq@^7~k6}50BC>?4YioO^Lj:/}߹M/9uUTpW픡窗z\#^!]KԽwd^%tKs겳VYm`9Gʷ;)$(0Wf(b?@!@kmJOV3'Y_\X43 û{|{M`pp&Jؙ׺z1f.BhVr~'_HKICR2F5胻pIEI; 8&L@D|~Yn]E5Y4Jv/O\1.ij7ɠ< |hA;WWe[ziMKYN/-T|zg;M+L$s(DR9̱B@tdiu@{ `] kyJ]1"F&a``*Df[($v vDŽoֶ-')XnHuT2OQC9ڷ<ʵ BGkw;D@2 mI@cz `#g1d46qG7#1lL1=VB$mEN#z@N@:D_b,5_#@*`!gttDa#[>D.ગBA}r FҠmgWUBV6*)K؋q AYړF&y#qA]Z'& _Cɍ R oBU 5ɇVv4iża R\;>(q78[H *$TMM;Lʉ"^P͗pIGZ!+JqttXɮ,g>|9u4GSYXѩwCJ~aYMy}M7> exQ} Wios {L ur$Fn\l2&gPܠ0NQu _cԝ]n8b95yZmQ;aHNGLMs88/eY˲2|OY=\ (._pGF(a(.x{)Q>]7X^*U"2/#x;wVb3MFNΟ,p`]si)hڞFkYQi'Sr(fB7o$m5QQ(7?KD9&f2 єOx Ĉ;pUu|^n~v ^·]jZK(ϱZ'Jj=2Hcü"4ͷ!K} hYK<.S;0qhDAHBN1%3qѾ2&JX{W# 헺/4il/5~UZqVʝz+fKDbcXi7Zg߼g.?H?# a3Ҏprv8ѧׁW UkBF۩cVࡁzM4:E(dC(. Њ5,p goz mA?J60E~;apIG8t.X2.Ҿ^KyؓkijpڕzS9h}C:ٚ0=Qm$o~{}̛+%mN}۸{A3'VmͼCmjD6Z8jsK@KH   ]1 ه׃@t

Oﺵs9sabC婰غk@ xWEsP9vHL~G~$ԇ?ntV`F7Bk+]PA| )A-Ϥ%9YKn;eR1"V5Ҿ9<@"FjF/È@Jp\+ĉ ը$7/8Zpyau@>(Sl"_`P?uT [ȻC-AgaZ 'j$_e [2Pi&la-#ZցNUaFrN>JDiY~NǂgO931>JY}۹m\8ܲReZN~χksn9䓗ȴP;;sR O~)3ry#/r1w@wrF,WMPWIs6B!Wl*0"8ee.bnSR~pbۧH "DFI3ꔈ1A13Y#r_'vb([jg.P^U}z}섄hGEʰ@!()Rx8:2A ϗС0g{y֚kιZkιZ˰Pʝ :DYQvSBQ QQrr *E%a <~JYfװigGa!ALqQ O)31gz >^ 21@63r'4rf`,YY 3w9FF${4a6˲XFaYnBLuhϓ"(e8ќ|K4 >8,9O=Q ڃ/DH zrr#2~bf#:K= #|\'{HY<"pstô!ozǎ jȲ ;1Z B,U=~~LT pC7mBr( +JYy]iʂFS:J/B/Q< {eZiG5(B7 >15IRyQl )Үb=Yi$ʰƑ+g潗Z94Y~笸=uj̼mB'hOg[9B5B1|>M^< ex?M c^f)T Qr Ni-"3D[1|m@G`x gk+_ .aoQ]ʤK-t(8)xFY>d {yxmc%}2&2qN*D iS+AEǯ`Fc2w :F-j>Aes@&\579} AGcv[VM}Xټr\V!r\HC]zŕ!DҊd *o\"*EǛr犩<_>uxD84Ǩ;X*<9u@J'iCox{*>^6BСpdT!:ɑ\ /`?&"k} zZ' Jp$lєb|-..}k?++ww>٨M^$+2LUW 6%`ؚ"QD|y.>- wg>v>vѓҞcܠ^C|q F'\-_s,b(Aϓ-=KgbFi9匵Y0BUJ7 R)c\˦a(^:rԗ@,ìFC]11 x*㬟v2B+Uj;GQH꩎D $B*P XeŁk¸q{~a,e1\vR<ܰ$6<4^A#>+@CoF(\$ʑQ:D!Y"'0M] Ż\LD9Q!/v V-kոw rU`^ѫM_A~֗ѡIW ϩ =p޴ָ? p'<ɪls˅gM'GҁH+^ݨ+|weםD\'92&C;ļgxˊ-E'pu~Is*΄KP ;U,~>~ >)!z16\ H^. 8y.A!\Y?EWfcI.K*>!tpu!>"q(t8JԶ_ l}_7qM$t== Pv'ϲ!soHg9i|k3pi/CҧЮ.ǡ ojTkDs-)^3& @|zB ޹&߈mށ/Rñ=y ?cz`ͻ>WDpF<x?qthsFJa 6]QbC0 t"3>@lIuhWB%$ p@Dp͕?< 1/H{-~ еN;sϽ&.?'22)RP(z#""Ho&VaVv&S$_ Ƽ2)ۋ4>(.QI[X~ߵ?Ӷ u#o;̌m($x[LTceqH?눆){ehkM=O31ҷ:Sͥ7Y}3ئR0#1;*f*i֨p|g#9Asazea^%4ZUCzQNP=_>8c*5#zT<87_B[cbp 3&zurOt84',X ٢:#th3ɧ>W*,\!OF: (o}\e;$kd&`iI?'3ͭua4ŒSI;^"c7$ v6MEB\:҈B;lk"4\LՆg?T yS!xCϩgr4/PTPwO&dox,+1mq\Y ΔFH0H{Ow5T iHbZ  mice%_`XVmAm-Q-J~@DƐޝmc3Q w2 o;9PNIk藔ںPfA"XlHgMPG޴g.?OaP^Lbn,..Q@q Q9ϋ5oVb#T8[^p@)GT')*0 IDATP"F1i7:y)24ߨ-w":+ͬMR2W'x8m*߷(F!~~|S7/'@"ďK N;F:8+9f:^^N;0reUdƸ}62bT rKӰ-]. S^Sh32 J]$;8Uq6[eH8 dclr|!񘹇@KFGjFiT&xhXTńWă9Ny5F辡 # l `lzo/xzIyH1{Z.(G6x;H^ʰqpⰯ>"pozΞ2jm77Jvg,X0#c!^␽ TH`ʺু/nhI(f iOt<;F:x]w_㼶ړάv{fru(K|g6*lG?oIQ"}·52G=w?ߠTN2I&|(8 ^:/iMfr;5}`ԩ'7%s~.aͿD't )44S |P?#{qU{.PkH4yU.S(/|[e< 8nag_ -UG<9 U6d[hfLͱΛPF ʰ큲;.f췑&A- T%2Iuo_d3Ji9!9&Pl){#p4l%l;E*'Fd9 <(c,]ں9PN \ɟؗ2#(qpYZe_R鸘_D`g8i}m҃>L7")^:l51..XFCT]0X^c{*4yJ9,,Ga),;u"h#*;m,/NnFKCu{e([ࡐo6ڀc0;G\s89~H.T,Ҏ(5 v)G}{+I`]A>AuPjbEFW/$A1k=WIb'O e#c.Ztg#P'cf/ ].^eSagUp*PU8RWcL`X;(EF6lVx mNV)<ROGԇB~ =oVp\ɡK& %mhgeG Ic?.uO%2Œ!_9b=kSһ$e%kq@02ywi?C?C~_n=h?3?Ykys=ܳ4kLyT]\sM7~IZ[[k볌᛿S8Μ9r_״7MmyyK1ְǧ?Woȁs1|:Gz].#T22;Fe`PIEAtWfPAthqbޫpދ4n焂V$;^1dŧ@il>xNEf*y ƍ[D;[9m6U/ՎwZ{*EY@AL5ʨU"S(ӑ//X >g2Ե,aI3`9PS{q/oycBc[F"Yu*PAS3@1VN(8iBrAw um:Y˅}N)˲E?"Vv+/:ƭ^S+H=q(؇e P4M o',|5mK9VKX{@6~GY1؁#`퓘#ƹ |J=tN>`':Q^QNi=2F;1粠%NXMwG{.L!;H@f |[tKW1Q> AvCqrѢon8bCL'|C"ȓ\xt=ћ 5a?T{PoߒeE&oUx!9?O3j@!`Y%?ysVӪ(ѸzLv}:6ׁGb;x@*˶⦓+eN`guob(?Ʋ`>76,6g puV :r8ߛAH<ޢll;e*1Of, #>a X0|&q̰/f}X5-[6OH4cGط#ӈfֽ843=NH:٧4.=VӁMà 'W*cޏ%w fu0 thŸOАczZ CA <>2Yc" GWv9&o[!x H!tG@U 7W9`J:zxd9)ofxyP̔W?%H\gA"Mv3,{%!Eչ0ooI̮ X;!p:i-9A̵)Wx#zک)+/ ~Vtj\7}S?E/jo}[ۧ>==y;M~ ^ZG_e'!~7xcyfhO~OO'o,ֱnW푏|dDW=1i/}K\]wu4ͲF4r`ȁt|9g@r,g`9RufC9Գ?ccÍ3nƸǸ;>3 x;f xRuq=?)tQf. yBj Bz YmgɌc 8g6 L>7o74~ms\yU'P9v9N9NŹ15p#YpnP;m~.8HE Z?O>>5Fq/*h[M`|:#.\ kky.= ]OVdY?hޮ xYh)9rQnq q -^]c&|Юa eD+P8|Koͺa~["Y|̣ax)z,*kk 'ҕ}(pOgJtD*P涞)q5B:DAU!`x+!/ _NN7BxB X΢lyi:G8Di.,SruT#{U:p_vYw9u-.8-::*~W=m7|>?uLKf\r%m}fȁ![ƺ~ Y1!o(;*c/gpQc?㪆KTlwFsGXr r:ƌZ.Mc-W9Οmӆ24plļנ@U4qMwa[tC !D'xxoLgnr'#"<.-eN&0vҘ tŰf@ 34xzȴY& 9p0×^ P qT8و 8E/|^&8wӧ >K¤ K~LWw;iɕ[,poC5{[<,CSO06i#{gL\zo'˨CDi ?WI)G`:v#MkMD#JMQ0hjS N HW,+(Wx ZI'Ibd*V@Tl*Y\Dnil,CWxƭlrLX&c& ^"u&t4餝4J82@ꔾpmvady3Z8 w 0@dS Y<^fms,_}KJX,!Q(0Z J{/UH*s#4T|%" ó0Rs߂Cf !=U/>|c#<\ճc9r YP'XܦveW@ϠR0 ak爬BT0p hpqb,~|7uv 2$ƒ]55CP_?=na^'^$݀ύl/$O|b/lǛ]{8Q˕uO}Sxu<%Kbs/i*4tV$^SuLtڨ.MJ݅.x %y^d}GŔ*>P4d(+S:.94f_#onR:҄q>G IgTsD' ,GE5~1Ğ΢ ܛg./U&L6̧ͱJ;a]F PLMo%)˖"L־lѽ ;1r-f!bvH '%7়hs$&ym> !/# C L:v5K vy;2򎵙ˎc,N~,cpc8ڹ'$FH#.&D{!w]λ+f CT1*@ Qd`>'Y ;i2ƣ >DӰ]k=;+HJtxi_^=4DNh'tH˵1넁|0\$ﲞ^r;-~V`HesjZxK4X@)gz#>O Dx;q0y3't(|gSPDc?+<lkr)?y 7Wиu:uh{$^:Bo}ߗ̻;/qev׸w/| 5\Ϊf7xc{WZ֡C718? Ohzֳڏ菶zx 90XyߏЎY!ǪQY"#!?Hu'`õH$c(+3Z!\ǺRw~@+5z@75.EM OwE`1f7jOfr5j!,iE$OBB=-?A-0|`L,JGA1!])c,:\.Qx].=Np{ DPw4Rc*^9 L%mK=ZַgZ;0WQ38"e@X1{n!d0xe5Y,u!SYrb(hz\f['2,'`9ޝY@L1畝<:wR a*9>Dn#ݓ^\NGP KkH;lOgeH՞~y'4ko?} 0Áx AN<,>H@q*;f~`[0\n$M%kGh$ǦIfرX0*Xcۀk?-$=/wW`0{ \3 ̨%{DP`\{/ z|+*KCZ`*y)KxSv3|+M>;vն½Αz_c/&!ձe S1p4,IQ^Ol1~ח 8`ɰ2rmW2^ /wIWaug Ү<)42|ϼWR>kVä<8cc;r9]% eyaCs6Г'0 v S;,tE}'W_S_JyN'x%ƿ鸼 2܄d:pٜ&>IL}-ID:3aa '`o'2 ?C|9Fe !q#o Cc2#c`!(8+4Y{营 !*[\f *mzi9&2FjuD8oxY(W#nwFJ~q$5+/)zо!389v'O`l!̖[u2q|D~Xw\ BGGj`^)^s{{ƑMb)Q٧r}8J:(v_Pm)q CvWYo3<ڛn#O#N-Sr"2icG8!8h^YT\YB`&d.^Oa6mif\Вc3F7t;_ƖNT&\EHqSK ?L@Az%2N*!oing:^Vҋ'?s:*NqDp*/}+*ckiۿ@4bt)d̺} Ƌsj'x!I&g =eVC^rS s(\lll>N6z+4aP:G.K:c'yk>s3;J IFW̡K/qD+HX7iOX` x _:EC@-!/juj:>%I##$Jdߩ\)P 9;qE0[o\KzʨGdS.iipSI8B"ȍeiOp!r`ȁ5cX0]v O2N(;{EYw QqsPaeq x#g,b!te*=㿊1TTt"hM03[RJ 1 dL u6bҦj>|GЉ}f/c1FX pޝ;CIHfRF2!\б |,J Pɱ[ "x(OUL)'!3Y~ϱ,QG. 07nC=Ə_Xo,_>#bK46:)?n"7ѝ`kLE1TczΔڹ|^]gE@Y^(?:Vg!җaYh5iplB#n-e82xAfY1F yl[&|-DzWXYB=iy7z7u*mUC,Զ4]!e[f6$;bDp? ӠQ=N|>͋DT_Nߛ8J\kzvL[8~>Q \>#IM+K q_ܳn9g;ˆZ_^K"=f(a,G""8(D&ic-_3>6kL33*R8դ34pJsFq\ _~xf`7>Ti; ,Ǩ-CA+<ɻQXy1fyf2Ǣ&}a!=΁L8f=G&4mG; ٛLC9GI'v |GfLk2 _ToE|}H7*6{ 츄Aztt=šΔ*А (F8E $SyJ 3!JN38nk>eŗ_іί)@ݡT4w8M!2. *"Sʁ\>%R{Jw$\;ܡ ?y!*]p4e;!{y0= 3` v\ibQkqKvxaI H:W?mW> 5g_/x0q?7J}*|!05Fs26ŀ(CTpH38ߖWVxX1Bnoc Li %o;derfclNҀT>D|R;o{'YC;F=1Œwcx9,hTc B^' 2TЈ3piVk߰KxCG a ZyYR@)0J}k$oXHǨ->{M|}އo[醐_FgGbo}Yv(K)[IߞYəlС<uLk9V SNy?Y9o೎">sٍ6 +'!7,:j\pl'.Ĝ4/ţ@Iur51Y@.g%R^[Y3f* lK̺gd)`yzDn)K>SHB\5_H_)Wx5zcȓvYNa QStRօ A''Ȥ8còƻ le{~ڔlIי(~ Σ)L4 F8I1y+t}֫${ӆB|".և}G' ۽)q&v˔LqZ@+u#%r9Ijpl ;u%p@NHD[p_ڮFҋ?v~<>nl7N8#k-wrY&]a>/e¿*^'S;C= <ۄȘ~8ht{&e5P2$G1Pg,ުX-܁H1OQaxqڎ̴΢oyAXɧ1v}aΈdp`og\wϦs2O#95ol{?u 3p(@$y9z~J㏽J$ouh :@7]TtѶqʯʻԁΈ6!7y21~[8o@3zw4* Ml.q^F^yH,>9dkȁa|Ѿ!j 3G?vq'ζ?qҋ|q˽/n;n4]/zڐ=l{dcNcqN @f;#hq@3^ ʦcPmDh f aOxi2 ?j|f-MS#Ԣt{yGM3ށaB(˝ь2-mw(4aXb\IreټQkt.54v-yB( de"f.:,TRC|5x]κWi` WR aP L ?M!<?Zy }Zo-uqPVA`NfHv.@]xr燎*rr⥊2j1$BL9‰\I XX49HNjeQ"'m.<cMCxnY$Vz{}~>L;?W O"wLn#D,B H@ƦYƱӱ&-0۽)}Vx,^t&C$6WNG:C'6wo|9mzҞ͙$gf?BsLlvJh6y/$*i$֛QGk1u#-:0,?0j@8;F2 i0z壑๫"  `3c9yxn;+-Mn] `wwe҅k.iq`揍702h8l%jkDmw[ s7Es8@pr}l螛g]

1F-_ؖDF_ SyĻ]ptĕ'1rc ^κSvUw|u5A2(Q5,屟?ˍÁrQ1&/tL[v 8/ԓeg?ݧ-Sp bH1Od+ oId@TwY}>g!>1F`6H4o |f?7xP.md|[ fݩ`̾_a`=8Xu6e6Jdö; '!X).k^ Y/{8 pT,$2AK-\`ETja6%̓ҏ`&5Ơ a'2BC#v$+}%|Vm*:DS6FpQY xNiRunʥ":rb7/0Ȋ2풣;H{?~6Fw/w4Yc01<3c9VY ~_2)s|!L.ʤS8̮,ʺq_7#JczH;"IscдMJx=Vzj2ڞ=+߹!MYO$5~vN`1ydYqN+hV{Jűi>fY>Q>俕D@h(H_16xGyu}-Ga$j_\t&Я{cM;K䉢@yvQ.cZguZg#ț2.߆0Lȏ7<;`4mili|!Pg4 v[s3G!6ƲMNCa\@7$~V"X~ S! u6;cϽ7lgOm'SbͻLuTI:m~r3OA0XQYfiU4cu$5*h8J.pIz\n\$^d@c̊3kk*u-p}|ômf~"65 rR.މ8@׉4#h-HU B@@dWHSlH,7 wQ Uw0bf*4.^Xjǎg/h'!nwwڧ?13frvko dk' Qc\a]mId8v=Ѿirc{v]+3T1EVQ7.Tmuu}FFJ8\/GH>:ێTަCs@p*9PJ$Z_wxm}S2$\ϖ o=I:,ï!$䢹vrRNҰ9+ۇ?y7J"}RS[άCa^_N?=Z@w?>>GIƕ;`<;dFej'Qi3 vt\zH:;V9q1L1F=*leO3㬁vZ_S҈ǻlu}O[mf'ibJÄK(>*gqBeC}O'* > =Y\o(ٷHCpi֐_ t3 -;~ک$ 3nHxψNbளsx,P5/(ۖ=W)'SxĈ[ZΤW<<~ X:>~E ndC3τ[6JK=M8 Y! a_,)CW$ #Uw[uk[aS 6fiy}U@Yj[fJ۵Kۭ'0֎,hw9og''𓶅;!.9ƸuF)d@cXt egl ː4I`fpV_fZe)Lmo {29KgqYM8>1Vj (h#ΐۆ)W$((ξ\K qt2j jU\Qrd#*c\)o/F9HfuVrUN):8UX JxbCek3F0QM_;S.b3(dYzVdY~V!j(\൶18DO*?*4K-Whrgқ6 -C`z^XDIhCNVyl&jZi{CJ95|(+XE#3g4dN \SUR^ cȊ2 ] 膼 噼VZȇvH62YVH1ŁmT'D G9oz3I8)`Z&K4m> hQqajg_) bhx Nj<=aC- S']gU9wt)Cxi]@CڅR8IAM T ;IVPue?aK2A%\,󔟊SH}'P"݋ RlHD)Oljkq `e\HYa-`%"(0m. 5۝7E#zNa &wZlr= 8g)cToʥɌK|lÖ_H.i)t_aZXg{Ӯo~/+J{GAvjBܜ;zH{K׵_]]sY.N ]>' ]Sl$=ujΓ,,.JH{[Yʘ4==a܏ptE!1, ;nCw~݀rAGm6 `;ڢM]jPL_MXv$ƃ"xXoN;?,= vNv 7Ͱ4iO{Gzqjk{W_G?c?~g|Dzv|f_p]WUg P~]ycr_5 Ƈ.BҺˬ= 3w0uG\ׅYJ9 0RԯL bZKYW*n'PfD} J w،Cvl˞[SV|YNw1 ɯ(u? ywSm#QxI>% ̈| Nt]7NPvJf;YTMe>LNyHX0.LGz 1g071dgE L nWX-~Axlj.](ph@Y V.4*-} !@VG2k}q ghlV Tg4TɞЦ"$#MnyTG!.?wx衃r%Jm`I`mX8;#H2tq0/RAcފm. q x|drw3 aD% !10Ϭ i/wԓgJ<+AP=iƧK_*TR _̕q@ng]LhgNdF0 }r~y#So^>'~O'm?׵_| U?K_/^?G?}3=]O~T{Pϧ.9_y ᙜc*qUiC FK;M~C`3:0}/a< Nx/8 Q5] 2y0 1yޥRK7 Fw-5ϵeB\p\;{ G~ͅG~=}TJS9L{1?/ `{[>}coo[ys+^ Bdڳ:_zt|)]<]{r&85iozӛ\bRCSvQJ /M(-kffx<.IE|i#Ǖ9*:<ȴ\uwd`8M:6gv %ʱenZV!)RkGg1Ȃ "q\Q.zTh97Zșũ7)_C7h o]~%&֝yVA@ǒ>iVbz)wïp^ VrbDeah?uS|ZpP]`hlFc.q5yvYC`dhdyFhd ?#P"< x$"& 9Y6ҡ$<Vԭe^<#F>e+=Ԉ\ʲ+-ϦpW駜رe'z4|/`8|Xd˜l0iYȌ}m n9=3cX RAc֓1xX6IQ_=W8;aǘ֨=JvKuFۻ IDAT!ΠZX(?K\Ӣ={M7 BfDQDѠ118 7IOnz IOn5jDzƠhQ *2)cC 4C <@{D~}VZjUZVWpi,|_Lȥ}`9oXʋ$xQm µN^S?]x@E5  kj^ v2q+~uOkiɗ{^\1md?x(?E\UpWw>]p*Wloi:#(?=%E6Ĺ ?OlgvVxZ[% vQz"X_?”&XWTtKO@#qd&e/IdlVpb1!v̅G$Ȥ)<5 v*Cİ"ٵ5mAL7oIyYQ!\9N:*;{Ik'ZiϞ5Potb]z衇ο!o1er35w*gzH+_vJׯPW>/4鯕zeO-Pyj6`a'l'X-\O`o'"vQdݳHC.Wڀi/څ2MȻ ҈ƂXrQ) KUy4_!CKQoc Zř6kO ;awŻDkXnKٴmOY Vڕ11̊ˆݏqzW1-J{+Yxq93wy5yMV738]+o0 O@wN+x;yf'FAxO+"{G2gGb6-UU0sO5 P\eݺu*Ӹ(nMoCus,,}(omRIvpjvQIΖ'FNx@Q}7 q[@@P:p\yeA)Hf!\:|(PϜ ȓ=og eL|D:Sjx7AE%.'i8a](DɆ e5[B^׶|:i(gZleVڬ 9robԕҲj=04@x~N@QʔWy*jFf^> :{{ɗ =ۢ@]cJ[";[Z'#O[lh'G*X|Ya?ĵ$Xňt óvrdL$0Hij~8U86i06 [L;6D#ӌFZ5RP gpbay#.ʘb"pu,ߔVQ#+ym;CK{}c^\n]l c:l2v ˭붳-C?9:+hkGO~2.1< LG=)EoUV=_/_g^?pnW`.Wiz\EazRiK9"ssU)09@8'(99-Fq  (#!d uQW@P[̈́2+7kT0;p  9c9=ջ&SN$y[wnWUD]Ln[^(Fҫd.USS:G頑H֪qVN!gG6 rp@Γ"mTaVhSy5!0W< -z6iJZ~kO388t$j֘kCl:qTIHbB' S<{]n5O k(VGυcLEw@IpNBCVQ``_6\x ]ATL~4F9/DH(%{gSnc3qTx{np5&ʛJh`F2jH:pa_ٴ= Gm>HSۿƩedЕv Q{Y_ 9>W)^y44I+h nHk>\ 0 w޲iXټ Cꋻ"F/|`o qŠDL@<='P"2 @ f ժ\m}[YSez@$0`wwaKiORUʐ)ױ wه/?[0PEwFmƓX.޾S;$ld (Xg<@ kHܑ'l$j[lP4\1@RYhoЌ=*.Frg;XVcH(kd~V۫NZ#|-Gȏrs.*I0!m=/x?Aܹ?Sw l@L@J8 l먑@u}q1= ,{ \J)E0{A MIZ' R%.JPeqȀ"#TE]:t駖Y(Dn:&KIED,d0 aa`q4###;K˧?{>r ϣ[ _GGYn[sUVN\ǥ+˫^zb[7\^^r7/=rʵw\QK/wY9|/|Y]vHw,k+ȵS1!ضZHP/nԁ6և1mgCj=/$PcxlGhd{B$;,5Ȑ;`XB{pӣqS aC:[C˘f(T˂y ghqGpd˝m* %7o໮Vb\oߏtͤ}.50r7ri܀k6Y%\.*+W;5}VO|9vs=|3pWp "Fp܆0 v:^#}V,u6Žcޚ+Ǔiv`;{tD8B!su"Q8SgrLDFV~뽸d>e>.F׳@YW}VCXG̅Q2 T\D({YI{:1of~4?`jz`pM1AiAb.ጪprt* q"iS_W QUHCƋA.2 cld] Oڊie&i"cB N ;@n\i.Aʤ@`b*=)(jZڳɤzA E $8 Mt ̣7N`+/6 ,ʥ.r$(E'}=b3=Z複حgE[Wmkt rJFԃrx B _oZm\OH6ne>'~Хl!R?**j]uw<h]gغ°m4QQjա>)̡wCg˳MlCJ S~5պTd˰` $ do5 .ȧ5xns5#m<}St %bOO@$ riP1V՛jVr9Fc=xRDA6-$O ,͙|IQ&Oz\٥ @r!BZFY Bsd59 рxUa:&A{W!RƉa''ğ1> Fʗ - jd")u%SxPIUʿpKb i |#[׮ABOTW}yTgm~b1䏴xH/NIyQsT7ZGQ8{[4"ש[vDc_$x̫ Ih&/éA˖Ltj=,Qc8 3񝋄/ycQn+O9$$s t !A}dqlK=8(*87<8Wr~β}r܊c `۶}{k˽5o/G /<'nOʺ{wteYo9ḗK=}ˇoԻv=UX~pePwXH:^"XBk("f,##m <*0C]Q (z`dr~<)2y' _q g٢# yͲYqɬGL3sP)Bw? 铸(d-x,ѡ \VWԑYD;lr^{lٲ_t w\oO>a/"sG'',IP׾R.Ͼ+o͚5Osַ5 x/oy[gO y֙Byw}T%"du$<_,wb/Ӌ^#,2051W67.;s'Xqv)+z0GYE{Q9n*[”S߼CsQSEBhu2Jwhmy*&nyb%*pH%~ָlhH`ym5g7 B;p)H@L\FQ@W3"9'BvܕuhЇ3‘mu*PEdIdSl R$Ͻ\B7X *?FJx#ЕV)ȃCJtW*r{l Oj5dT& k:]% ˄VaNDyʲ©7jب+4rpuf|fuFwi]vsa,2E}k3Ƀ*{Fr#uJƇ]a1+E\~@](OJhCZ3'OpޝN$WXi,W.p N[J)׈WC =aqkLh M|/=w*~3m7Fx Ӑ(5N9Ζ|v7Ql B +l[hal4$x*53, 8lP϶ nUԍcT}i-.l)}WGܨ{@1rRh Xc)J!\ wYs|K-괻;5-܍A+zH;xv/ʗu6呚LoE=:P `{dgU_~V5Ԡ 7sTdk,gۦPxSH2UF2FtZxB{jl󌺵aɖvЄ qר nP'Һ">v&-5[=Y |*.:uɬh鼦ѢlR,`!Z^*my`i_cڽ'ulmy+ q"l$XygZ~Z:ڌOz hz~WC)t1럷%vwx@1ށV 25OBbZW3QrӪ gBebk IDATc la ,]Yr̉vc9(f [dHs{o&38}Lw"7;spWYueq$B/e:r۔{a v^:j|~#d}/3mMB?w'路a^I]Bٵy' ۱rl@U}k g <(p[9}egֲep,}=zxY`S90x q a۞WmWrc~yOy~wXu?/zы~w>~D0~  sG W3l@ +Yvj㝊NeŜAUn*( rU;QfAApG5 $dt>leEdJd"VWYp~ u)zʿer||L{t[-&Bˇ>nV*Vp&58'~8 $QuRGmOں˲j mca@ aЪ4 R R2mM J (;fZ: 7xql\c &^XoA$h[kO]FfVk>OC!eھW-saͮn]?oWa,]w>)W hXmsk3W~ t֔ ,+ԇwŃ(|̊邱Xs]⽬Tx Qs>j4M]pxaE; q.S#N候i '+.gy5{=|V aŋHK,=e]U6l@Vf`}/;J^,O[m> 6Jl%yPMFoYS`4#7lփςuv~VNG:uɾ9:TXt)cQ.uYWG,Qvnzy?E#ά 3œ QZxRxe^$ϳ$xm@v =ySn ~)94]_vA ʂYsV[{j:z.n;,]˖# JѮ v*/^2ol@82EU.FQr\ʼ7gYr);Ff1\9!F# U*fҿWGQ2*x*6rYsQWѽY)n:Y#|2F 9T9QyGM 8%IJGYr6t%ABE*FO#/ߺ(2&fA/dme2cu؅SF)DvRW{/"r2` 7M{5N2A_=A^xid ۍҪb[44hi.F4hVΗO ;d\eGzhYvhoc b ByR8VRҎI ȮN[8kP M8a4KH(Dҋ*oW%|[Ej DŽ z߇w.c,QI`R(J.* Ʊn ^cDy&^|x "F!8Q8Ͼc~7W|1R&mTyҷEl7<.1k/c xPL1?^4kދFOLJM'mhl!"k1\/>9cj,X!i(+^M>G-"Xn}u Pm_CXa#vrJ_#D\%"}íIzoDp9ChrhOڌ'i5GZA7J8 I)6Oi oTZJlXڽP4d5>`1iK@]<; 4=AU~fç#ԓ4_ <+)M~*Qx֘sD}e.yf`*k:5m;GM{KxZ0~@n[nW&-X[2ZШ\]wߺᆱyZNX2&{:LI:{ӽNFޅ> S/b{ c.#i/i S4@W ҺUdh03 (+*yNs?6t7<;gH)a暡4{IG\8riWW*KbD\4,[_|ց^q{YٵeE#8C3=}'{lW`{}STy3cc#3g-!œEuVs@8e6 2?6oC7nE* Ιy4<cGtZ\yp%:]G%GX*& UYDž7G9)* f•"0OT']x/n (YKwH ;fE1ka( =˅dw)?OX$7/h&,*Ofب>ʜD([?xxg9>̓NqGr$xQnY󈀐<XDqsJ%7 t@UY:w\Gް5n2O1w6Jz{%8w|zNF^I:YG׭@9{CX T`nO>HD_tͩ,H>)&,Ŝ6*Qg6krAߩs5𷇾!'eЧ5]͕oHzgH#qv#^8v`Rj b8 NQ{!^<܃/p--'-#,eoJM=l58!|JsQS_m?eu0 (ģ(=1"-O?.v6t-?RF7'h`5' o{OfTuu]z"KW<1Qcgk]N14^]x)'2 `Lv.)pObyg7.F'QPޒVS0ru` JY f^:w~=[0lS{Yg?[Ifn\/HS W$U?F:"L_m:^^ơqNxXѕcuQ? `am^\:Ҥkh~ă1pzŊ~fKHP{ghK o_g՟XB3{9P hǀ-a6̰zt1A#WiXIjXe{8 # !Zu نc!ƒ/?y]]NU8/,G>Hq+fx­; 6opSް,]:V߶?ZS/_[_+5LCF! (3c=IҐ |-H*(l˒6ҷ>Bx^?mlLЦ+tvs_A,L| +foۡW%Ź|u%-4Et Nou(;MnǠ;̺H~Lٵ^je p u5@o:W]N][Ŋy(xcT]V?srϘY1"u6 m&8Ϥx)W9 WKKLU>&聭/m: q׳0 Ziф\_)!".i*,t"61gA $j+ ٰ1H4^U:wP\JDWMg|xQA{ӊ]]G8xVό]ۡ|cK=п4pt,-vT e4-9vg/c+8xe\jd?ö|dL兮;Ȉ6io!z 1MyX#굎o,2pDnEq~x@[,u撸CX4:.l\0Q\{gmaEbkxHC  u%_;e4{irxn<2x\=:* {2o4.rH9Z6 mt4T-P%0 hLMj7d5 o2j#jA6KWH[aʷQ\Gn7+0Q B(18u z]#kvڵ9εws^pߟM{~n.Qn/++߽ejJp5%˾٧?XYN: ڦ ']O,wyG9wA Ll}[Go;R 2ҡi'z׎eM< xA}.QJYx *8i`|;{\3"#g`BIӿ035CU ˯ݑ1c`SϤSMUnlL[ <™B;eڸpl7cGYwE\GgrppMz:sb1ǁOBO2qcxYP9/icZ+H0Хg|v^wkpT/Dn"H CA̞˖s0sxQeNz,V4\睭%|G fGe5OJu4l~Nl= ex>m*F^zu9yxw]H0^k,:_}ػ?_6l({"j\>ʳV]nҗ' [9rmwSO=r1+(l߈կB3(YкEo-9.Al1 m24LHZKDYM7E"U/i c/x-z*\cPpxԪo;o޼}'f/| nHnyֳU<"4>˕W^I FYt "t>xSoWPo^9<&MyYqd+.F*i1r4ЁkϬ{כ7 L0h͍aҕx3h]񐯋Zk,PӃ2zhQ@^"MK(G6[7֟ g1^7@O(0?T)[YMm,R|Nys99xa;;ng>9[Wc 8|rW/-ʿ}۸ ^RKP_\qMy뮿rInb{ƛnem+)=k|2'I*.2"LL)6`n`a:pmO›Fat9Ad:mCI<%.a9WhN`Gx\P^rSY~}>P_%Fv>ӀU7bi?7!W X)\3@C)VSrQt7SZsw" ̞3;Ni9yO!az.mXD= 宇ya,Lit^HIy}*Wu%|_1vXK:*]hE.-mVTEw;-+;pl@o|({I6 /<_H D WDέU U9F#Q __zl{Xuﴮs%_wz f1m+]7z`6{H#/8k%ҥE=<뇠A=x~8=),m(kFslIOR~`~rj ^]Q-Hw'~ͥΗI|Lk 2Ԥ\<s*"$/ 1@2n+}nlfE"27idnN8|# ^GuTۏ|w|3)GT<f+]w݅UzUxxǭÉ8tvѫA|[nspz\j{`+~T?g}$n)A~'?ɤ}9-R%vtL=f(N(L qnYi|@Y#bs|3V w*pQ2dtꯠhu[3(A) (N*4٫/i~6/svcs=chSn%[3l2%D@өSpֵS|'. oGUH^< XZ<CVwRPw/H`)5:f6iBWs^4WU(̠;m9A@l/+?Pc9$Gt)rΏdj54epX/gam^5<Ž+c!=ҮRZ5h Wih|-41 . Ch5Be5R3YIO}BV;S!߲mx^|{ q\5vHx/P^wPot5^$6}l,G2dQnlcR'jѴ" EQF?&l'4̊{7\>nO ׷;n{0}dT1+ԃY>ngsQgb;Nf |**u ~xx#LNG苗(stP6OsW,򬟴 Z$< qĀ]ճ>iV[Hi Sܧ-@84~hl#4C*;&[w3/84Y/DZ #sEY.u3aaZFmFQq)c^ <%Cx* slu:L%9>dbL%A~Wϧ=ɿcpӿs̳[nF9_7|3FS5?}se_U3%|S˥]Y^S:n}ʕe7Wpz @7/WjE8u205 ]'x#BL+2s\9z;$rr,ޑC;q]4 D@ϕ /˿__*(y쥢kk/~G[*rHҽ}Իf %U5(|.n9?3bUA|ӟ_ۿy5R\~u%VE]TG757?ĐW.'Й)w?j][ fp1~h{WBܯ@*,&πHuoGQ"YV_Kx<^ΣU̢UVJrUt|+ 8 q? ~SoDp5hi O ,R>d**)d)ک9 ]Ke^OEerf2lѰx,tE7Hy!5ucP;c/q/yƁq0[ pb|\yY٨H=,HB%w !Z%J"$ t#XXva )nRd+6y*tY*Nd~= H׆|vła3(]' #Q\o/9JzO_4xW.zz<0AO NE[8"? T]Ur' ˳~(0_`,'7ug/²Mxޯ^`NB>˷, "G>i@˖xflo=rm[dV' S}hUYRBOK`:Y.w)ߛfPNZ0-Lʧ Dζ)]_WOw~wg}nV?ϖ+yko,gqbI8Nx?~9M^?/|! /|;sixW7D־ʿe_駟Cfk3ߗ 縎0LAϽs{圠PUyW,ey*lryFɘrTG8N3<9e*wt!x:i& 9_3bּ\ dUQyY q<2;-wg^NJ`a{~)xx,(uk!Swib}Tf. zݬEU2.-?+^40"o@eW45eԭT(B7ϡV[&o#7Np 8+RcDxڀ*l(b#WҩQ㭣G8,i*G|U=PQx;#YncwG `1naH*<3-qxnɰ.$K7Cdm^yҶu*غGԾ&v[k 6+:I7~9oҽUxز}a(M;< YŖ\12- UlCRiw%_~ @=?ꣀлE}=6QQټ'lde2G by?ƂyĚX wsY;^HnCXA/Ā2tXu& Ű|KRKv,GQYrp cOؒK©[o#PUVu-l X_Q뗕O;\CSNSN9')J;J,sf~xxSrg3(kZDY+&}#aŝO])$4d"Sp#4U ۔r[42]mg 0oRy `T D9@[ƀeH^[mSTU׽}e*~%K/z4}k W.]$w=Ͳe\̱\QD,X^0> /0͟( zw% *g^*E6F4Nrm$)chGRaIl$cGG)?BȮVI=Je"SqL`ɜ4lsᕍTU$TN1zQ2Q9@$]*({0k`2]8r%p|b,.dM5U.Fm[$b6ʫ { 5h1r18Yb刃Ϥ?TP, Ÿ׀s(+"(sT볼WNi٠gU.]cNBn . (]w :1a5^ WmP(R+,!qgFIK-:.F<ePV7*mhXgP3Fƛ\܅ cuw 4Օ_ʖf6hO tM_"s*DeA 8RQt9eد5N:-U*zbm>/y5L.CߖK+ k w$'ܻ~Vl_*n0*cY&NZPhJo=8ݷYnȳj\}dĴ=\ G]}k$|vm'UA-!& >)/ ˩sR8l#FO`6BcV/x#gl,:.[kvy$xRaphl]c0O^fܧoIÜ3)3*kB|ӓKmVρv7(Y SMB'Wޥʻc ks]5,d$,i]wkȘQID3~$d6SV_f6p6}VNo.;Of` `eڦn PѷA)/k=ePjG! !LJ[2!RX1pʽG Г%/z>W XzUYAk2}s]e)\S :[gu x?+R0 Qbvdm KtM&„O]Z|Ogaxc;^6b~%o?s+) 3iS@eߎʎF?ufX`<<.he\4B~  M-Xykμ~a V8˹ c}R _#M!.,tTp ʩ*/qFЮ NYEX>a)FAexZ@0~ ,+dM% z;cg IDAT2I< Ni&q!D^Lñs)?J 4nG@?*p|N},';9lہcMGV>%>9% ^2G>!c.?/9{a`{FN u4O`+m<O3`'I7j44/1ap.N[~C-DGU6mtn 8ʱۏ /zH8yfQ뽕v[JC#.z e42EQD7eܱwr}:+"G*_Yѷh(P/Y-HiP>,ZcT8Uoj*m\ x@8Ғ']ujG'3Lf}hxHNzogJª;3V h) xNX̧{z!Ȏ֟\ A0</󨵛W3*r%+ǖ˾su9}[5^_N Dk$?+<3j 8YpC9c }?Zu*߻L FBzIԛLNFX9}m5 X5=;n!lC\RE'tGge3ݱt5Y6 >Dާdg ޽{w[+^cXyӛTu'=~10ߵ^@{Ji&j̡C^wu]zW=_r%^`́x{5A}޳gO\/"o~sm۽`p-N$(AvGw|B=^>c$tAbvx0g{+"gʛSW|2r10o>-Oe3 5.@ӦE3UThD٫TX)V#F4cUr' DgU,B(m!-UQƆ0w!goۅ ~pQҴ*SyeRj+h6#W/۱Y폌`~lW3yErL ehl L2߲W=\ <<j>wlkCye}ۭnPTՁ"m9pŜrrѲ~u<(Xԟ0E:=n~tIr4O!g5U"NKIW^R<ƪs.O#{C8ɨ{zb<4&K F͹6eg WNj;k.O `r71,CUYC1;՚[؅3?*Y~{ ؤskfO0MӴ*K_p#ie3?6XU'^h45x$rEoR3OR]ԅ08zIhqv@Ժb<ӊ$$kDca&G9xȘ̙S7|n9>eU~J9 { {))lUp_h2XҐW ^q,*Z`P yn R=͢G 6!>J%oB#=9ʭGGc@O[VO,ޗ^+~pѽr_E!]G?>7c!|8STN4:0<"y?L*\}$y$|ă#>G/T$[_ -z ̭x簟Hxo9h2z έFـq@ww`{ߋ"䳭1!Kg;:?]^U|l\BzanRmBhKS%ɐ*5J:[t{O;>;fa/hl1=MWY(Gl,_U>|rSWzªq-؈RXKtw nhCSU:&Ȣ@ƃ?QM[iSڗ?+YY7yBy+`IkȀnpWQė]l>I2]߱yIA%;EGv.^eH5f7ƌt`;:+ #W5Xȫh0ipnA[.eWfSAO Ix1Zo/DW:(fn>b PίĽ%]6|WXK,Ɓ=0̞ şMC8@Ye[Kx ૾#uo^> n}Rl;|{} N'+=pwٸa}yu/WN:S~2r\sDTw`#./[pVVǎ.x2| /N/|cy}rW`G?Z+yb}2%Vb.b#<z0ԕv hcӹͷ8ׂfu3?0]=!*NKhGv:BviK[)4F\Vøvm9]nlϡCҞ7דO>}/>~oUC=[}/{Htq淀ŏPnuO`/L?,~#'jXPyG0F[rU% f^L=0.*qQL鷠n z]e|dq1P[HoFz(\vܚV"-bqOK @6{Νb^n0m*"|'*YI#5Hj`74]+ ]5Ix8Zh[VuUL=)B+W[|HfŅ'iw{gQwUYM7c0[m)V6 +v+,m%yL||sfM1WaC7<Г'djSi /Cm>(m|ȲÇN{bϛUA~|HO]]7 YlzLg ~{e^c$0!KxW2]Eoӥo{!qXߦ1p|w0c~|vz4e1IBg#ҟm` 7i:7m#Oۥ}XL c!L/YH}Sq} D5m /ޏy-|țO~ڎ1zˉťGTVPWWP:/k- | LˡCoP۟={N l#z<3R<;":kyfa g22q"قv I QJx./V @;K3ʍN] ׊A2X7F(h[ Il{ \~j-k T!*('6"[<4̳ok fg֊_:=xvQncxGa"A:\@\FH4Љj󎊯󸲑,n΅ZUstWWhťCwJK/Ҭ^^u uŦ-3t *:jJJn;Y] h쑯Hh* GVUyATt{))N[^xJ08t 9r .E,?+}5>QGyѴxfU}{<_Fo;,$"jn7EQQ)S*sFR>,CcH#q1K%; r,+LҊJ4I`=a:O・<X-Ր($,@$O&apTHC!m(6ŀC*0ж#:`Ù)~;o}WiU̶A˲IQ\Rs#!h5f3]%y 9olV;eˀH(^@s/ydI&GYOVz)>+-KcTčyѶWqܹCْd>HO50Q ] ymxlmesͬx<^vC|yQR?44Tؿ*!WL%a~|-ߩ3+}`(A\^ߟn*#wOt /|Ol?%eN#h+oãge5S34ﺁJ% i GG_MG5"DZE ԋC\7'XkFM70i;$QlV!vK.Yˬ֧'Nfqu}ҹLć ȃ #*cW<΍W'P,5;ЁAEuA'-nQ~W $h2:*>\KT`@8bIAC,xI ԭU8UEr3 Ne} d9k.wdù*yq[ #2;x5חs'NW7(TFwp_8>j̔ s\* jZ0Q X˯}zq4hڵ+Ҵ < {)asO8H5yDsfuUHR4 naѿo=FHp1N#UW~N~($;`\)>qhLmg.X[0[t/ClPaO7"$MD_#@Y0GcCcdGz?`vv]BJ{ Ui4ʱR~%*]ɝ eoګFlb|4~7y sV:YQRl䜩@F0FW"7ə{\HQG0|jy4WrjsֳFxA .WSm_nhyD)![-D|/>*((h+B"[%Ow. [ v DRo)s*6%)ylr7NƮމcـ ,+ 򱌴K*2Q$JC/Fw /i\L& ynCi%<ǿ@#"_(/R+i; PgeoW|/%~Sv<Q]~jg_mX! ~J0ŕ4ݾѸ'$Ɓi/ٞЛ$* ?SH?)˷+TQnO*~SvPLf*NCkyMz^]b}^yocgw75ӬZv]5#RMW7+#|Ƙ7 %!ߦv|aoGnEY=8H`}^gEi kXaGAl  8:wt$*y֤g'Z09Wz#AAS\zik\ˊ^2 I0@J]@P^ߢc%Ve _\"e.yY2:LD׫,5jh `NeU%ԭRW5e|ғyZMeN/Z\; imaSD͊|6']M;8VnAl~E=s5PBE8+D5ƾԅ"uew@.tAoafWwb-iw7˃>H@WJ~GU^ (q(wF7C`Ϟ=x {pe߫.bTKCgs}܋qa߾ː֤ӕuO.|PzFwpn"FW O>1h | frTp[M0h bz>2k`H )57'gyH_jYQcwVf¤sr]+?RJ~P eV  iFDZcjbQgC(\&nNT%2PfWSW]!bح:Ҿ*^"{H5= fœ^Uod9Zbs񽢢,"b,_5QACo@YbRJ\*Pv'<>lv02"WI]&'(W|OCy.}u%B'JeG ЇJ{mc,TxZunIm( `}-(X4 8@y-@Ulh}O-PW#ixNw1 4S&?AzO 7yq:G#ygUaE@l>4cwSgMDthĢJ%E#(#d@QIoVUme#=52 ,V'uxH/2X7 8:cL>"}"CO(Wb/h5TO|cN-UoS.('U>^ olV{=hl7`|9=*DZLY HC3OJ@iAI4Ac^Jdc ;|MF$v&t`NJZ0, W<0UEQz |%O13h`V%WbUbâG^OmuW?eB@Z{i9%"1eeQQ[則?pq%[` 9J it\Y[]A UseYsFw D_(l  *`Hx>. Atg|Hd23r+ǹH9gOGahwS'a Ye"2pM9tp,x3_lR ($aKrQB)-u7}=ek;Yw[ǑvﺽG^@@wm#*,TNŀɪahHƕxJu4H>z?P6mQ)Zݶһzng. Dզӈ%IWqӁ<6=DM;_(k(pyP…9E8raLcA?39UNOLt1ckJ_? r~L)sQhZcJ{GܧR׿Sp7Z4W|椸dOZp&ޔ~A9[g{)yn~$KJ^B1BJÕ⊌2er*BNzv_Bn;mH%5{3M&Ry/ ]LNI}ͣ;ph6(ü "FqqwyPЇ7m@7RAѺqt/uE ps,yުFD@,Ͼ7a: rLx:.*GQ9GD*mrkU0&G)V%C92|%0By'`l e($u)EMR9ac.DcF҇B.H\=y\=n=uF15//6vSRa E8}U Qnx)|-XZ*,̂8E*I?׉b&!ƻJ RÖ4xigqqP u&6VV~ M8||kwyxlOU_vdվw7hr{5; nxn6S=lRa#>@佫uRU%-(i@9z ]!J/F/ ~Kzl. 5A4h%e}, = 6k![-٢e:،>bH}zLއg$mQukhI Uq~km\M+^VW޹I論߲<H4%J^Њ'3Pkd2 +ʿhΜ?ȩ4K&VO\a vvis\ik9kLMc! qȈ k 8,.p`໼K.+[,z[KW ~<Aᘡ>aG)wsJ>%!<pwFQuk ݛ/rwA" /O `A Գzmґ6i}'ڑQqxW;(4c>H+Ype>֩L0tQ@Ш2} ƭtc@)懀52[:O#Z?K0mɜ׎ 7|5?nеE _b2&W}L!d+|>k%Q wx׍{rƂ"++D8sX( 8⢧sMSnc;" 6h*BRYxtţ~>+؋0Na`2I 3iAWm3m9 DJ<'&NE6]׮/B*eU{趮< Q` gUȏRA[YW;v'Hל# yB>ibqp)4v_ M]qR)NLBPzȿleD Z|iWG )`[pcș6]ߌ\ ͢v Gĵ,cptZ%p9-VQ-S4qzMeORDR}n'^7hh!_x U=; :ߘ,ɟ)74uE j`%:)CzvFS̀Y=%ON|W[S1\LÁ5`Ch"jy?lCg"YA#TǨVޏ7 0JCsÐ1Qc49RVkǐ ESN^(hGG0"Ez;0lW /^޳}FnP ^{qYR~@P9GIDp@43Fn $춁7䧊ӑ8@Gbud~$!b3OV%z'#ߴpw(d|^uQUB(VݜNIԕ_e`p6jDhkp6*) ?cY`72vmdd*QڐoQT+n+{MǺiTq2T<,+{졵'=Cctګ䍒lGQޛq@6">ti)hIZ቏<{*F|6w g{fzh<9A)d>҈OahyDQ6W|sVw%9shMYEFެM bKrc&PwAoVe8]'p%Pc<89O70oc!e}Oʧ'1$RV11jSRɺWk@6޷(^6$W @1Ő4!1d/Ɠ7wl*7omiσ+"v512hrDq^R~r 7A#pL˜ IDATڝM,1X37,^zAEpdof ~vMGhD/0ÓrVJJB_:,;NUqco1ntI gfä*4[`xw|+qI-wh=Ȗ%n>[FVS`gspT a¥@08nV;(w^J/yE$*7<# @Nwsj DoSXsҙV40t2ʸ'F7jgkYPΪw/SVQWA7F/z#UÃ4boi+`>\\eFIt"!/YQ>{/*og##MTੈy.JzR2 QsK@ǣ-[6b qc؆=-Zpm$29&_S^7 ʅ.9o*ZV:5.&>+={ Zy(<@N]z஻ǀ0yƂ; *h2Ga8]e |(Vwq kFq6"fgl Y $;#2 &24'3eڋ˶Uh[r ==);WA mnJv3p;چtڐfZEĕçmH[G@#lƉm6.ۿ]z܈ͅ?/O^$K&C7o('GD+S9<7FVS嵣l)O޽|rC33{dcw3t|+ӯ_{CxlbU(զ3›^Ͼ1Z>kcyqq8k!©/׮ (UBE~H{E9H ̤@g]ߴXR}= 62AnM֜㲓(MY ު5J7 96JP»ttMLi*Ųp1Ovb!bP_3W=g tc56_JyTt@Э@[~9`7WePc0Wx7N{fd:h<»ӳypi~[ve(E%S?IZ*x|9PoqvQP}|HW g]Aq%Y("f<@ |U#.* @QIf&WS>Jc X nwMH6 4dʖ()x˪tQi'`b=PçCŘNY Qn )Sg#sx ,wjvyňvp/{^#:L!ޝhu kGi $_Z'"m`YoΡ}[ڍ$J k|a_."SbaPQxM{zSu0yB "uWH—;.FI')Dk\m+ҨL[}_љr-dvoy͠}x>ūn0[ d |cØ@7ۛ.Ez_4vv3ETCCQ?Da3P#1hsg;WR6BwK-ӷy{SPPjrtzM=k(|G }n}ʧz91L8&חz9QTNeտx*1}v;E\ uB*hgN&LsP\F%ͫ@euxEq@O9mdY=r"2[,ã G*`U豤5'X! S}F~ Q4D *(*BG%rKBcVPKHg9\Sǻja{G#',v,6pUa8t2^ y XRHޜz@rW\-=9>=rәoxL1/{v__~ܻ:\^yO}ܹ3'}}Q䯔?wó_|Px U?sTO{ϗ~-X_rGwow |YxG߁*ټNWRN^~jϖ;cm<=(' `v@yjpVpnI\y}^諴vQ ;ζO`+ [̰%4.Y[3kDq܍XA|Ұa<{c<1B@[ysmP&,o0r50g;+XUXGL-d0[%HV M~.^W&LVr-&ax[fq#.19i7m'AX\zdvѶQyc͸jK6DnceE%6*;`;K4ؗcL% A`I8/yTCAX\:,`l̾| Å?^C3J+L\%R9żI1 Kb4 I/cLD? "WC1ϖraB9rB'P?dZxr1O xgzƸA>`5z. ^-o_/1FI#@+}K_*{p'2.u+I>iPb ȅ^OO\ZڇGv;ʾ_}9G{'9Wouۀ1s높w'+w_?=6ހWQ\Q}Ɖr΁r{+#A>m}9ɸ'+Xeduy9I1?|eM#7nY(uBPV*>VSBYIW IvNstKbZ%(;?go= ߫b '! \H0A^ykj*?@Tyx@ t5yT-4bOr VtYU& ЭQ4)7dJ5e)YYgs Q@sn(.Y5N+jPɌb>W`}?she4i:<`Z7mBYwIh? Dc%3>Gpkq&8zwY)>Ɗ0&C6|QXȺ(sﭯj~xOo:g#)'p20X:h[*] M-23l1 OK~pϫ@7FYN>٤q<ٚ _S0^֭:Ky7*UJ74mQvpE~ 6+IVEH *6&)E4xm`l3*'b@CI IC_yePpc{,5F=@hOv⤧ڹ(QTqXJ~99 = THZ1QmU~;|Ϭ"f0(e2mQ@3'!@pgȕ$@ADhey|8psRWv ?.{\~e) DxsF*dP*{.| $!&_[vpGiRr_[^U[m|ӈ&h"mc>2QS$OƬn2O 7fVg9cKOٺuoS>rG?V0ƀw}G# +pPV`׭q 垻MO|쉸;0 aH93wx%+%3Qޡenrt?퓺R_h)CBvaV0cDvƮJ8pqny63v&:DqoЍ搦?CgM|m<\cwi׮5 \Fpukjb\>#'NXfBZOq94ۇ2(ӧO' #3G[GǬ\ZޥN3:~s<>㖃ڇij|/~ll *C\?5R^ [q3pt0ۏ]_L; "5~Ҹf.YpMuxvsNY|feg0BwQPer9 g\p\}ZƸ 9A+IOI#Cu"*"Yeg*1g2+qv8Y(8s_s cRgu#^ TA.Ɔɸ[De8tAuYqw.R^fp@'k >%>(1T]l.( ]j}/hzwgﰊKWO4=tl 9ҷq\9+I qzj2u" i+i!Nju1+xK4+aC(O֨E;JbgYMRyUxqarbY_,Ugxf[Y:9^oQ`OVb,/l9*N9^8<.pq<'A!n;{/eAyy fkC;ۖyA/$NE?c(JNX\<QX[04_ /3#1(3Ņ&c52߀5^#o*_^e|svr]9Eu14җo xzʋMtܶAkPs9S0fqH)CK^d0C,_Iu}tзђ}{ÓReoϪN1v~2@|cE A`" U+7e̢KSl+ ANxoQ/l yS-H0 CQ \@!gL噄  y|T{]&u\@3!q$::hX&Ark G![5^ BXc+rԙc+8;oCYN%)]EF(Lv-0+9 f ߊ{KZ6~~﫲qOESV\P ;<4n0upkdI/@n5AeO!]k\(`wox1w}ȏ(q{=w_I?S)3~~}WٱҾw~N`=[Y{=wbFfo~=7Sn>U"df\Ƌ_7 ײoX_h+S k?9P9W87]`aU_ީt-zEpNF !9vi89S3# x׹`MjMSXC5qixhbEvUA%%E)kAj@5g>F\c(#ϲIRY%d {լ 2}te(X 4{cl ʦG%5iROQ.oW@ 0G2`f5BkzU׭ Fv|pa? PDjAɺ\i!)^@.o9}HݤmE855 EׁbC I?(<DܶͩGGϝ/ D*O1#ax@?003ǣ+b*܈֠j*Y"e>/pT 8}wVQ^{Ms{R%yawH |KW+zʃ{<;_;XĠJES7үLE5~'&u-^?x&4@mcx#puB*}V`8b(`x-pX(xr:NYi>ٮ·goS.ük|_a\Lbȶ ;m p#VÜ0s~4WR7@e{=|w +L6e~F(.?{"íƐmv2v4X^@q,B+ۀs+\&I_!3J7|tp-q IDAT~zE(ȧ*R1 P?*ƿt27njCX)ISѝu-[P9?|ɑ/~{W_?^NzE 'CADG-ʤH5LWg4ds|Q8FuՃA$Y k䓑H* oۋo/9'avGIsyrr/~cɋ?k,((WzGj>WfϞ+'WOFaPo 7{iA2Q H/W݌CPV9(ȝϤRH~g@rBEhFA 3*lX|4ϔ5# P&n*4ck%uv^.bŻ!LLqVʰ`#=z\DcS9#^%Ũ+O;0Be{'B.} )=o_Co#jLN;(@ܥFH`{P8уi,vTؖ./n ` NC3)H;m6?7;=QM=](UEnCC%n*҉JoUzzi|jkOytgO,zD^g:[ƃ6ErHk5EEh4mxbz m"^鲮`F:1U-a#ٳsDyDcaQ>:H}RIO,I9VH%MEELhhblXWOcnSYV(51&xrW¢54\@OXRGۙoőucNygZ#?zSۏ"7uW $mhH8'KcfIJP ~ķcX//9PLl`&x;C-Pށ%->,Oz do=ҎKFUSZ.ﲭкc%0P,f£}iy%k9/a2M? ϫ*Ү,j;f) [+qVe~ (mhn q 2\w1hٶ~}/>Ck* su0@ڌIUԪ;ĥuXCgw7)˹<,+h'+wU7/YiK ؉.mT \^oȊC- Sk5"@$lҿ~s&vC忝o]ң 7nTs[OBȋGY9G0Wkhr} 4sԙw'K/(gϞlj>,8 M0ƀy,5gN.gp{,'ʱϗ3@hO=jM=`,:K&_ɤ1jArڟ|28M0mJ1Q.e~of7+o,Wܸ"E7.}*S+_|1UϰKQ"vV + ({P}}01||قLΩɛ|7~H?qUuP9`ɢ@;YP֥\%\7Qڙ#(7(|Gnn*#10#x9b@UzmHiv(]Az#Ss ǭ6j2FFqbe2sor_%B]Zp4ʾih*=(DJP 5 :1LkoQ˶Ѭ4+-;9ϣ1l߀\xBc h|P8j9^@qd 69(*j2_{T:RO)ҷeβ[c+~#nPyVmyTZ{I$$ "X)7⼂vc3Npr#O ` _YÄm_U=y‡$iȧòl36ukш4G{x ˂Tv8PC1:늶Wqn6 a3>wU_aVQ]2=&qo2 Mٶ[lTce|FQ(+" @xh3%FގB}S;z8p P0z̥ ^3mf I^1¥$"4b6g}#$cU {S[|#]&uRJ2x[d´Y%a#Ny V9U,8O ^0TPU,XW/OŸC"V9~ktLP"G^cj2|[.lrA`8Uey޶**k;A^f6uUxV~s ds|)30_,NqNo(W1tVRˊO%_BKdBjpB?1^2M%V5@H`yǃ))+=[@ZF˃/AEuѸw^9 o_q\?'FHaXH&o8|7'Y+~k݃y&3߬g~+Ο]Lk7?a`>tJ@5;%c+J<I|fkGh7E$3DQQ&Os]AE]-yލL>SaQx(\:־NJUa\oc:gԷt~P.8 .جp"se*V9ᦋ1qN6ПcFZ n>o9u4gVEO1@ ӰehАB* 蒓sT"ǥnTx%|zbPի@:96#(yEVִuVQ#v(w,혴*;bQC~(rFա! ͪJ) AC{lmA<̵(c}}B6+4RF;']c(f" x>'KEȏG$q Rf;|/PξcUZlX҄i5l>gPII,K'^lXC4yЈMZ2!I__ً)pdE1Ge)x <϶oQ~v{4g$U~禬u 0˺iG 0 s<,44 Z^rp +O3~~}A-mWU3y웲Zi28oV]pX2>4{b2f 7\l ) \U6V xh5 էFQti(un[QĉE{yn/^ |Qjtzrh`sa_l.;ѳ3^Xj99 >1.4}Y0׵K%.*dqR^K#ujU _YlxPV7 AaD5I,bmb Pwb 7f؉Fӯ-9UX5NKV0t5a+$ԁ]Q)lj]w>2DTA+>.oq!Z"y&nw$p{GoF7ʊ ЖoӾ0^xV`/᪃2gW''㻍F$,e;9[rTVmqxUp{G p InU82 =`h揃x/G$BwEҳn28*)+J Cx?Ϥ||6K3'j\i]`ٮ;u7בML S'WMYC_wzw Zy;k8{$ƀ'GG0^T2͇a5?,Mv{?.[5&ۘ= >Qmw<aĻ! > ,Gނ; 1XEWB _.LEUIo9sEH+L\,->5B#u22 Ձ`} < ߸ M7 =hlrx+8GѲ;21r>vxX]\1(֎C12Ly V $+[NۏhŌ(?N MWQ.'hq}qW^9B@# hBk9L*X@iX_Y}5E.`RV)]t$jq@m3D 2ֱ&+SGMc:bƻ׮/]f; -kDz-$(܏|Rj<(ͩzP$2Fmn %zP~a}V硥6@Y,m6G;H J%6N8*bpaWߎc_jףo3r2Cb0DhFElA@UYݹi\84B#pAE3Ld:y߿!A {}]v{׮]wpl+:F#lJxŞrXGuȴxǷ]0X<=$.¶k6C6(*"xv>s5_]{x+L;x^P] ܍mY&fOS9(P$|e"VO4V< 68ƀ҃x KfJPx:T 90 Y>p{ 0Фf'j`F&j7_# [j2Ϛ և*9Љ 4P#esh?a0-pƶ]%u̒5t K9/v(PNjJԵv\cg1k~A~~}.+_]k Xij ]]b%J1v*<=zm?qF~9lNuw'+f#VeZ+u..MHy"W]@_yL}a*x Q^,!\W7O-ٺf/*2PW˾et'(^ֽ5PΕ,(L§42J=j[Cz]Nq[zy-CQnzh<񽠫Qĸ *(޴ϲ-o7<{xBC4pJ3_'>|HIi*PTpW 3e3i- GwVM<[X5^˳҈\sf[W*3D9Q閱VnhM\Ug>o;"t PT}| El'ۿ-@#iUU-C7~#p(`ªwiC|~)}0sTtV/eq5m4i@I4HH`˷7]PnNpή#[!,Ӌ+440-n F(!`{Z&EGD,q=Ьu .m)_5OTvj=ܓ` IDXj€oҗT>-zwMv%βcCs |Rգ\ !l"]AFp[e ,N^6n5(D$4WP-M~k?Vywsr $okv-<s3oB`m!/N xD>u_Z%/ JXFyN9Y[4h zd],zpnT Fʿ"ڍ۾!Mtac~~&!87AYT#1DE|Yhk ??G;SD.rm7ݝ+d:^3THj-]Qtf hlCХ8V]4 "ZϕW|h}?Y85@ HI#<0.RyYkr(PeA^|Z $ oWMc"ydLTp 0e| ˺޿@ҴC*`49h;`l,LsaW„# e&ACs5٧0^H+gFs\ڑ'B35$Qq]u+!R$X1ˬz#QpWsWB TqϩR!`QqBa~e0c_؀xf'+^h`#SEwd7ɴBJWapcZzHz:o Ur^*5D]:(S]]*PvUqfT&v5ѻN?2E{gP&=椑UeEE LQC5!q |FiVU@O$* c.J7,m'qVQ2qxkFCHB:0QA^j4W>T\kM_eۇ9uN`6]1O$|n=}8:I+'*>7@nqҽ^|l4ZVHciʆƓhʠG@LS@#dbn)y|#&0HOG'3,)[QW%|z+ʻ9^^L~o{i4r‹ŁA˝2DY56A},|ھج_/یAzaȯY1 =tk>8v>H~ #:PO Cm)QwgB1\ {z ľ;cZk=5jP:R HUm1:ߴIʽH<`Y񢋕~xCE݊8d0qxӜn2IP(H9w m=~C#{}:*2`ǭ `ԭFdvPӋ'խ]3ŕ+G#^0+Q((D~ mA)&!?js=f j ĺ6'LK04.O@-A+?}7uMT{` ]%نDiJ"$m%2J~gS]Ih&Q|KWW! GLagrVSQ]& rDM<@k D*.H#<~Gy O0%1:W|qzf-zF< em '!&ovm4 00o/Flǐ =<`//)iz難PpHMEyu+'9qz_^F8Rcrrlc݃Zݾk߾}|gySMs=Q*_W7Y_\~<|޹ޢK ,yn%Ie*_1cp=汏-1~.l'_fh/+@:u(}J6AajQA߀E uM^L.H.z T-ܸ}kb;C;GPzY%9(FmB? ~SœUGet* *+v+ V4EP *Gʍ^Z Gx-ݷyd>[KnVxJ[\**x̱ !IijQD0^u7nҢ{4,FXwr@3~fڈ pF2clal**zN ޘ#mKŇ9c%6NCOU WHLA 3|seBq\ů͓xσ<%lhnm. 1 $tCؤs} ِ{i!1\x lAUyɕg/7*~dU4SXt1>4ڙ<֐Qu%BYXt Xa=C4-#8Oczögox%%(ƒdc%~Y샴{ &$n+/xb Sč(JAh55W QYTs߁!̻ܚ[1qN mL/Ή  o'N<&I}m+yΑF23MSxk NP@3Sh]̈djݻ'@"+67s= z0M*Ԧ3ZJwۇ}V= a%< VM(`nO ꖍNQl/ex@6#Ӫx 8+3|XI 6zK6-wl$e߱ GBU'Mj(m|W1mXxRa@I CC (t{۪YNGyc).ܱ%/qr0K/_s1vcYt2ԑ, ,z9E=X]{V e;Fyoݎ*G4$ *.h us0;驔q`#3@oMKP&o:.`V^DWe2Riq'`Bu,C"* d`غީx{E&a89Xa D $ ζǿK"UE??aluaܕi8Y'W,E?W+爻hT=~0 N4`5_^ K4QbP4F *n f&80Gh& xG둰x/\sYUl?r]:Lz#O0 s Son&W;0i\r1馺q?<nX|]cpl+ OHxz..!Uk-gy&t\tE{˕}au}sqU.z??)zֳ/x __oux\p1:0fO}Sя~tV8'>O̽ O`Rl]TJ 6},+ӣ}{_9묳R<9YN2V8^4>-o)Їo}k?|[8XW^CyNփ@LN"W7+56s_Q3¸Bn Sqi}oj92-gjoq?2F2c4v1go/p5A6"0#F'˕7eSa1` {*N>_WoE(߲>t!oW@osE1~PWAjZ*p^Ա0i*sD)Hg(U1иPC=*n/cAe7xv䱜QmE 8;E[~ Jj`0iHF^S78lHJ[ C|`K*}CC2Ҡ.TAqS|ĹO; -r> Ɯ[xB\5W:qo"}&E[:B'ېMٞc 8bP&A/=Ly־0hRkB!: tԍDE HͳtC#suoƸ;36Kqt1uKW+1 i?*A_XnWpH >9U\qfkO{N/^BV -OpVFbcx+~ҴxExor"C0//p-(|E|G)uҡA~qH:ʪD`uWHzUG*R0+' \Oc4%noy4|.w–Obp:2QWD#C# GG$~%+Z}/[l{K/Ίʯ^ OxB+Կ+7pCqw<4'?^-.' vRڽH^PHt _;vo+Ǐ!1 *JWh&h#g)稄w#T( 2Fhw(*SjòNUa>(g@W Q\iL˗󾫴b\e]D1PD.̖^f&mGqd't K/H8.X'C4hz(?|)n儃qfZBLhm(z#ljIT$}Vc^#EH/2`X BxA) EX0`V:hb<0c ֐;/r~C#1N6GDzQR5x_XFo jc ?Hw5ihC Ū}{+R@guR3P}e;0i:0g1{aq}îeϘ@8+Wm2c IDATs@^^#͖Qpx^/qO0 ǚke>I2SɣB$!ee2EIWrBJ%y<rMQ\kxֽ⦑ 0*pN^UF=k Wa\4SyXp!y ,̳,O}N^Q=ʾ}ʛ|&~U~MS?=XB:>*ˮxd *Q*?tjy"@cZU])x2F}mS zY?s/O+gC3hhO\28:"#y᝚6uhyk^STg뗼% prٗ_~yVwޝ(~]veE_xK/{;puӟt-?#? k | f,|/M gw:P;}7Ly03Of/Dv7ĞЛ291Ed qz9׹Da֕ER`COAZ϶/WTd#\g2;%Ι쉟#@\r{]`HlwD5K++.9~v@!M\LhHeK=xf1X%^e!*s^}&@gen 2/LOy>*PbGtATvʼ,/+uީhAML$w 0lǿЪ,˺e"VE8Je!#V\Z `ܚ*A3ڊH]ntic(@u-_hI\V7t^đ+[*pܦD>sW ]񢜆K6|>j||GL8YAI 6 ,`!1`GBCkm/{D1HT9cO *mtF ;p6eg'Lg`ч(hyDxo-:dU~C;vX;qǷ 1Q W5ڗ(tPLK-&ԁ tt%V0v@hg1 oi k|t^ 5W.ߢb]I1.|BV\{g1S/]Wi~.Hm>eZUQ(43 x^mVZؘwؑm ŚKN#?rxz ̎nȫCrޱrR~ ?_^v9d~{)X?7"P^+/~'7(o+eY^_ h| וW?!J/A:Y~n;%PpH:Zn 0iߡaS>%^*dَB#7GY3w{ hVC8: +g9eooqjzs+=xDz9Yl>tw??{.ٛs.{O|˽gu7 ܶeir'> 'wZtH+?>*˶v.`29k,3dW 6 =SpqV+ BL1֘`qJEid6hI'fլJ=@0stq,Ztd&k#iU^\Isv"Л_˙>[\y[:мzPEGz̛(IS'1 e\zNmD86Fed,QI6b|G볎h9vx책ABFf18 eroj )!]dDU䕇R)<-~/om[?n Y)r}oP2GMʭ+,;}>^|Ex%L7u WUt7z*!hSWsoOEZ$y}k>81-JpOQO4Ֆ'WQPwlh*RQ _@']*W[A*w mӏ@[VTyS1/hȚ"7IW6'h{2/]ҚxEgE`X Q;Aݸ c8ލk;E<IsۂS)sJ@ppO>N=q5ƒd 0-Gxggm8d ~m?-q<|n0]s l8D GoP #ʢ|ԀJLM>÷-4Ma~~hWYcHc1DȓZ'@-(At H4\kKW|g G4u%{<βQ}݃3 ]4=2(O9H8h`0NmU ʬe˞sO3^Ҳ/kyW/0p=O-O}OBx|#,\|zY("H::b/֥ 2@)H! N1ڞT ~ˬ^"@%Kb3 ŭ'd;<"!,*^B!J "ZcOD(Tw7 VyhXs.}pSky6]o xӟ#[lЙ\, S唈NR}o{9Z)scҊ]=f :N yE \Q甑<0rn)*@dhG#qH?}wA++'⼲ 5h,z';pէ^hlpUd%Wt:h$.J9QVxș؎+ӭ23Z Ԫ*fHթ.ªIHwWzMLۭ"XVkӅҲTm4浊gUUV%~}(ʠF D%-'(p6Ɵ`E\]xW+HVoUܗYwyQznTW}FY爮H9X5i@T7YLCV~S}-Q0TD]'Ak{ eA'7dyg,yo8myK[%{hKïёuR]'DPD^ ^dX;i#2 dн_0n-kǀc[Y۴3LB(!ӨdzLUyt0|cݗ*o:h"WrhӉNQ缕]^e^~fGh'8W<2Y09_uoѦAU+垣]Iw"[=tX _NO HrWo&v7vn:PCYm\Üf!*ѫ *#ˊ4GeNVXCv,v42yK q,vY=+yʖۂ왏_ 418޶_$ U&5䐃㥫u{*L*\1QVY.i*|7CR-i-]ay]'yl#ޫ/#vn'+Ch*[5@-: 8u"q8/L|$^@ I% /p[]x Snvynn1O>t]N@ N3-2a3;P>sp=VfYk=;UAbrCRzp#;6 - F;F)cqƸXٍWBv H14[d m')pKs1:7_f>WWgz\aX a 2]̅m)`8Vش|}[0;Z8>ITrީQIj $ ,+ŪIYI!@¼EՆUy館 rXf:AGM'305x)S\|O9k3Lx)+U,> >xX]o."(]"1=ZS$fH$uo2&rsZ>U?Oe>[e\{]?GK\}#8Սe@M&hG $Wb c/Ɣ̜g,rt|A?b3پ͠()rcs=y$Qz~'EčRܡ491Q6 ^*tNp|1OD",?3?|go~W5'l߾<3ug?yiV>??K oxCy _P"0`Y^!oe]Enu;PCB Jo)QV^=*K@IEȯrɄJu9Iϕ|QV<"ds gJc tkVXA=箂j1W 2m9n~f(!+*UX(f+V>M+(q$zYGq4Xp/uqR0j(ԫ`;W 0CC 6GۥDpy7 %Q!lGvTOX[W=Zc͊{DYd?4swl1hm=&Tl]mSC9AJA^Y9MsiЋ&jdoێ ˔x.j>Ƈha`g"cEZq o +U0⩚`l>/ yJy,F۝ݜ DғGzUYڊcwͮax+;Ki lICq #|Iӈe6wA"^*:@0xKXʪ|;|eog#|58D?[|98yw{0TUFx/ ^G-đPqyٺtIZ+f;h̀FaA~eۨ(6Z~iwqixы* Sx4$9Qip44v:1,X(GP ZSkJX6^sws~<]܆~rٍR7 1lRtGM&g@s1h1^q-rŃH}483XgsD:aK;_C P7e<@Lht=he{a `? G9.{hJT ʫHW xN$VWf(*;iÌ̈́L3zAOw,#'Hz__|o{O]A\z*Br-[e{Kɿ}ꠗ@{xmoHѡ@ |PWRܮLPU!*9)T!#(^Yγ|Yy=/Aq)a QH!WW؎Cxչ:)LˋLҨƥ̲*󞸀nU +T C-b 58 ~2"xW*!*5SHblk|~5+\˞uܹ:,<^>gp4d @Ģ9Jӿr/,K73ﹷ ]i@ZS_>\-gaG~{Jg\dX1b WQW.a+(X/w$pvm+u 1!xWu4 }y֣ jq`$ek,+ۊv>3I1Y IDAT?[TrA}x'nkZ)8\{`cX<,}=R= |Pqn 2u5~ ~SҰ)aHḻtd\\%2 @pra&lM R%4(?ED_a}0݆1*4lIp_EVF?{PAC~V6g3mxOB^)&Yj'|@r`b'^#Hs2_gkJ?(6Fb:.&qzp#|D<5F玲('1[` !_k'>N 7yJE1͗B, €M`?ia8J%Vۣw ! 8y-ck,==9N*Hp3j0Ko.W/I pC5WI#熱(ͧ7ExB;9GoJ:x Y89J ]t3lbX߶NRѦlYL/7C.'jXxSkG`zxKB@yx-X*!4ˊ~RHXcv2 ǜ20b)zj*y H[w T ENca-H'r߻[ԯ°j$ʼnu0Ah#]iqHyڿ^=PzN:eh-G[z@.\!1T֤f?3f ~5duݓ825q i[/&W+j0E7tPZB\׷ s&e `8E2|k@I7&B`WV*-G.(mU*XG7qXSrz| $+_ M>sͬPh1Hlyk?` Ћ [-ic0583  oCc ^7:2()YT}*eBpgpa%5>!-CAFEeAߤD?CkdzbGKAv!m6h{Քu= B~r#ͅ.`Gdwa~`f/w}^۲q^Ouxc)ԣ8Cl;H& AB]ĺC41Z97PA遹?c||# OG_!</X|W8#x=͵35I#XPeA( +2c%Xlpo,$zpnCiCz)|+?r׮*S3C|y{>\X\tA=C.?^2_ *}To`G?uRu.Se=OVezRf{CgIЇGXl0 3&i^V\^Gwq4ZF4{Vr.i')VmS҅+S#mڹ:fxソ裲+lvu(С: 8}]xO}cT} ^*pVwT[UgF;gRAg*܁튯X:Jm#DRVug c9SɱL%B=*CJ)V˘1y X*:*>Nq*;=*$a#Te򘻩 Q)ڔ)s?s'99e=TʥHy ]o5kHBED?. 'aUHBTT."elDD['| ^{8j|&/{)G^iP}+fIirE"|3ZV)4<̫W=DW["⎹GcwjÄ R7W!dzQV;^D"b=j\ŵJo5 6UBEQSဌ }r,8G-O-mdGyOC5EU1Ϙ70lU&PsmqY?0;zߦœi<~i{{.-8Z6v\7|g{Y듶f|(sИr~a>ZiPdW*:oǝ]Lp6ڼ ?e[9XhsKPqb } nq "OtM͛GL‹=c{YSqy6DUTlipD'o [<,/Ю<|#viQdEp W-r^ &@>$=JC "zirCAz  Sat],[TF׫Pу']Gԙ)K6 JPUit2<e,X[Ӈ@R<3q8r]Ҧ`Fj̶v Z/¥:`p8fqWSz/ !SGv,͔o~-{AnUm컩bq p',/ퟖʼn^zo`y#Gh7B ᇜg8vW_0FXUsuFn80Z-3<{<_2 G"kaX#!&CC# amm,TSm9S/[^upyopա7#9O>盽xP^xgnlG.g0V0^uJ1j06(/PxBTtiF33o3̧< n'wL 'OL4CLZ})GEd8$E}>6p@kX{Y*67F[;eLEŪA&YVxd6fb\ɟ{K_۾mSiN-HG .wCJ7?<t(С@ߊ-̉x7SP7\S#;07>(CD^T!εQnn"U|qR!mW]mK$v%w@JTܣm1 ƻRbk^+īY. <Y[X`:O+." uH,Yڊ/L.+={mzZ`n'B}D8AWŤ1 #"9xBR)3\F=TFWyW=n/22(% ݔC4;@YU9H2B;μTɶ [ru4z+x^g C:U`LLZO@f'3J7rM0-bKZ+ua-g(n&;^AEomyg1`hJ -e!*.aB(&bMz_0'"`Egϼo<"TJ]7't2}k2md,\bi-"<%:d4yVC= qL]VgiՖV#9~hXRqP0˴qZoejQ䵡+։*Fx7`;>= 2!t  S{_Ic:f־J$|3'8%O{%2Fp+mK'7ކ1Bɧ-+-Ei(r/=y\3TwRap8$9 meQu!Y) Y>6Fρ̵V>-?HKϟϨe{>ڴ׮L;9~y l a t~l4QBmȒ|)ɉ& 3=E14Dݏ ė]ڲlsZʮN (5Iމ 1X# 1aO@~Nq+ k:ddH3h2"Oz?2Sr^b @yŀ ;/*^k^WCJѭg֡G t((R;!IՐFPmJD$HBGn`6B&ضk !'<*A!)M(`} k̩QF(½Y1`\YU8ࢠdqF8E{^vt]&g#Z/<Qb|@ig+, Y{ݥ*_@:*^eW! 6p֑-킳+bIkY^5I~T8MoS?vwDW\Cޖ"T[/ $jr,*O(|(ՋCjDWO2_9I! n 6U@P+o"IީcNmcH3ϥ@0[h7`#Gq0xhζgi.EI6=^|fŠg<'|zV KBx췊 J*υ]=Ljޟ5_XLzFδ%s//Md'A^1]I_`8/uߩ} >;t\߭¨졁<1rٞnQ̅Tٷ}g8GcCO}lW7Ie|`~dmS/9sqXކk9iVy,td*] o)q\4752hH wE=mA;Ht=eˎ2^3ܙ睏Ànv.\VQ[OnEY;.̑(-#ӇA#(2nl6-x{@o?+D4`y+ho l*ңwp>&aC`)?KLÀ:Z=)}#X!rpౌGB Ga:A3KbBkà~!ݼYjKݷ*jE^8Bq'4k׀&ek;#,/M/p"ASzp)AHJ}C,>|w(С@ccF;Mc1`lV#enU]ku, 򍰺?C,]x?:6UE\FC@U=}8 |8(ʂ@m? +>7`y7y 1@REtKTP}p `neAp&Bl/͢0ySؗp|_F? bqAA[+#DLIs˲P "'UW{{d/ܺp36 =!""+[CN5@F] LYʽe^KHE\U܄>SSiTm#B$]BrѲLj,1P^UI;' @+>/ aT ;tM< ͽog6=a'϶vQxR +Iӂ'0C?۠O{҃V|FvWom9آjd]x&7ԇCV=v3FDH\!b5B\=P ` .jk ~5iYxׁ$n3 jj;ۖ&}(0sq@pCX'^ 'ls }5c9J/K 6N> R#S#nK:h1eG"U}9$)uwPݣ$|%MYd uбXDŽS],{ H"Kו|TǭN-šآ<<F\!z80Mԥgc(OmWI .S F7)*zYv*g]U҇G}Հ'oGfdXx88Р`'tKA-|zHeHX0.oc-Mn# j %+Z͡ɯd IDAT1Y[B*Gѥ"e_%_V4-rW[$eT6%!BH#K|< y,'Rj9~-G8@@4@)҈;FaXSaY7h# vs&{>P(e顗M Forg䶝,; ޤmחӚw;Vkdn.މ7Ѧ/.pnZxס@ t(Сg D%w#Ӫ 9!"%FYEl"Wa*Rg sniK(EYykOr(*ؙT4ɌY<^8*aر!QL*2锚 )Pų5 LHy?..X3iR&&UBxqX lb8e+*FFXwe?W?W:sʵܤKd_(=c@o`[WF"_%HQ qE~A#SրԬ {.I7P?c(@g\<@:Żz)yaƑ׺dቲHJ@1K\TZ9> /nTW1DnH-U\|"\mP;ϔFz÷m4XR9^ 4۶4*zP/ \Y7/7BEh0آ!Ѧja8y7}:1a^mH Lxn'yaZ+ @G@X"A_(|l[\4^-Pɫ*F6OQ|l O@v|TMzXyj:ch\7pdVI!^1kM^7UVS5X/g CFqm%PE|;f2ʺ $GKcy勵o(f I24˂v _7|wgwY);3nِ$ I"EJ FQ*^"\TT.x%t5 Ez$}sd7;!_{vsoyo9SBw?irVs T1Q P:Q6Gq\DhJ:6W)SI .Nu߃ u__A -O:- VS oi2G1k^A؄/j lH>Yrx"J*W‡Ϟ~nI\6e U0O#<]zylpp|a9[H^(^)8a<9?\l4#8 z;LL C8āC8āCp Э'9DqhAg dLgAD~N?˗lg7Vco ti8;,iuIe8v ;gX1Fg(n m:1җJ 0i43q)+_rq2e YCr41#3Ԍu4pq|~CegI34:n܁3Az9M|`nfm (rO<3azVeb4|EJ82O`x=3j]wy>!^f$0Ty1*>ift)a]d _uOjYeo E2G,u_ 9h8 \0=|yY\hGos:j`##iwn UO{. F9+C{?6.C4I&Y)I߃$u,\0w`7?Fi(<; @M`24ƛgbʰ](V$nxYWU,ks};G(yX,iDp>m:r,3҄SPܭ2,;P^NsLghÒ36t6{Y?" b$xq LLxdVxi!dK sE'ܗhYVRNz9[O:DZ`)Uy0sa@I:~BXlsـy(/@$8q sO=͡S^WI|ܔǡn&>G=햛׶c7iak??Lh?}]r ۳|O9}募?-^77jGiL1')15u3r_E:MHpCnj-Xm Wge]ѱ ̹]Y]jw2u- 0]&@%1{cxp|wA{Yk}m-ak; 8cgޠ$e/q_2Ϊ \mw9skuu@ D^ yg}6[1Fo~B<@%!BZY]"i45tG;r9;<&3K5W W#waw?Fd _~Otwߦ/'X-8L:~@ŨΚڕ;Z^w.u t9g"YmF~ qr<*0 EVlO`#<^m!S$AQ|b3Ypl?w CWfìPoG$n-lgγ-EfC l忴X{ KYU:tq#  ."'!|>h`_u^rGAD0MO-, lX|)5&mE1<5J1F$ӓ{Ubހ0~Nc†^8 K0eM`vN Laa I ,q^p8/񝌒WK `: uƼof/Ҩ?G"o䑾n'HY]Ggt@80peĻ?}y{͛߁-O|Y6>>(\xylz[VJ~(āo:$,- Kŀ>G#߯ rD~>~;>48䟃t1m,GW=n|,]aF# tD8p&}_1 X;1Їs;6]Xl >֡Չ,f.\'A~ۡCPN|~3`?O2X@ Fd1˫!2$ h\hϠ)f_2"7&hkd hhOf/_HRk:LB÷}5fx1)SVc(a8![4fpՇ|3$4L l"kV,g};pq$4u6 c,η%#3iqcHJKU)qn v-#s`D%=حfy'cN㍴$#tg^q 'ONk@3%&4}Q~X;0=d?W' XPms0:Ed]cS6p;h{-۾as1J,eqy}ݝLj? py]h҉i8e:HG_óf pNBid+iʲ2 ";uCw pIcu`y?w%#(N?kj#q+M;NuN2ؔE) W_4Ȃ+[&S`&qED[SIGY@=J[Wԥv A$4@DQ ;0lG.z6'k+($p2\ pnP'<7E|R*(kQ֒}(_=S}@ab" HTs5}̱maۓ{ܱ]t-:Ƕycv;Ug3knN+Ӿ/1dn߇kuݺ<]~%'?+^|ߴzE7>|~կm;w?}a _xrmjrϊrZXf%^LW!u`vî_w置'λ"'sCڣ 6u;K+`RmlmttPɧU #9x qe 1H$%ܝu(x/{;55D q?#Xӥ˼o 9aW\Q?G W;6 Y1㬙 9}`%Ɲ^i+^WXT8ءIķę4m$>#2pR6=;x2)fR בB7v4/6^'ƀĸSyvW (c{,,36k{Yec.z`Եm({d;8 ۰Adƒxp'iˆ+4RY4MkC(pG;8Rgŷʧ{"LWeO8X/=ss6j|pL(ZdlPn9WWĮq&N!/+W [XqѨbo<ک_p:6TaU9m*C&':WSq)FfiGe܏ "`V#+#02 @~|l?8gm"_l\ң{U'ѵJ5Ke+Xi`:q*?SR-@Ab7 @bѯ1O^ނ!$_q. *{Bʦg"#plpGbl,/^z(Gz|L)(J^cY\owtf-ΏtM\m{\ GWEkWlQeÃg e/OɓW.MI1ze ^:"uUy\q)s\\Co3+Jى#N#_]eX%Ndb::"8#]Dݽ ^!.idցpc1:-/t?_ʗR51{e_u'>ιlGo8埽95~}S_Vw/h{n;omo|{ۭNmV?o}#{~?wǽ_Yv;<}Ogɿyۇ蝉?8VK.Ӟݞ/*\ӧ?v֛^OGNqx ^.fci׿Ť;Vz7&o[7+r~Ob紝L۝fFz"c1zxw6[|XgFCXZ〒g5#9!YoaoL{Ӝ8D+$Xݾ||dF:!dJ܂2{A.'gC_",(K5b0"@V'НqVlwEYaQ x%nI!㬞Gm֙8^: HX:3y[:1dG%i%速TE2gӸ&]`,-/S-C>/oj9TTBp#t gr+n%rQcݐ,rOB &k G2 H,ws &CxBزLx,4teGJOC;W dk )c[]hysu@ 0?# ^]g6a8+h4e5b6f.%_c~˱O:xޖCkC(~e$N}4X0s_Y"yEK~aeELBYR~Che>_v;ޚ,?nc8ߴg~g~1 +z^)r3 gIwݳ:}gc9_>΃ksijo7W8[+]clXzfŇq8+C3^h{ϟ_dx;ίDCmǶmM#K=)O xWC,_3Jkp.o߽4ʧ}>dkYuв&kQ:nL6+_[7[b|Lf{2a `5Lr mtcSH{ȃm퟿+v`FdٶYc>=e{>h{_"&Vcl4F5p;?P̺ߴyv 842VY LoJM'3{.wŒAǃ3_4 m- 84wXL?ga)>٧/׻sq_'DlÈ#is@j#AN:czzW NI02Y]`Xi荻4Ibb-^|;i-=\vqiMe< ҙZ.[}|2UOF,+U#Wϵ ;2#&S]?Eh]%Gcs^H)~nON2A~Ʊ.c}yJR_` )3w>BkxG%ʳ߄&u:#XiE &^-۟)q9|94T:gihۏQБ#NW=䕃:) b 6Cppg@qF#R.wfU/l:ll-o=V}٦^$1Gx7_$,N}G2GOQmBTx̓o,PM.DJ`s,Pl.W []^M+tQmLsa!= "C~.B\\u'f-チ5UeP 1o/d'P{xuʙ K} ?&R+zDw탟@`{*9s#`[w!%NiS:QN!@\Ҩi5]Zy©pH@$QbC8"*_<-JӓxA82,P&g) LK0 *Z >3Uil՘L9{ <, O\xk1T|2 ^1 ^%oc`󗘄d "KmaX,}Ǥ7@X!bnE2rxmEgh:faSJX6Y!aV0$$ ^ObҀ# &~.]΃I"]+-(i>td FzψPgsf„'?iټQ[Sj 2EF)?|<ڸЀtn-!/ήsP58B-Run~:,{Tu:l=}ٞ|icQ=&,=[37:)\.m۵tp~3至_Gq<~Ʋbn /yqce;hj_>/L=nr{|!\o 7־mWlyg?~QM? z:p<1ǵ3_U7t]{[tOUsV}%:Fp<}}i'c/}zp|'?5V=_ھoYc^ޏQ6@wKԚuCrZq%:~P}7oV¥yCMŁS~ی&%$tyjfӧqA;{6ݣ633X 561v혬6+mi% }MG7{m/I64j w,,. 䵍Wh9OoCߜw˞CŜMjHqILȥaaWG lpF z& PrRf]:LI aӦ\fyQDmgi(4ZY],w*BsLicB=teyFStm'RdB-rnhfG80GQl1\Hgkߙ5wϰ:?߃MIIa.ϜytDQgDXtY[pgaDWIJۅTમn51y+{/o^6ӎ8ԎkpdGûcVolRCWWk3˓3:,GMqU ˾;=Cʭ #)iAʒX:dԳ9> M 3n(` "ANI x;E12eekc;S2Il* O;, W)>o1c)p(:"\x?6m5ՒvVSQytl.߾#3Ǵ60=s^ zqB[i4:OV}Ig*/00[[(f6؃TA7<_^K:?/6ۘRh@4pX+X@M h.BDm%Wp'~Z}, w)?Bv+zn׵΃iӎI+GPC=mCe[a"? Y!J,ͥ:! d*?\(ΊW'7o{xH!#}t@1 2IVs {tfsBqG.f=H! {<&m_0;C?²388c*11 U0pC+%e.d=e +]RM7wm b[BgT 02etC[ic']*rSaWMY=BtVhL ߗyYn0&*! oeɯL^YZ/2Ue~1fAqF+>)EYxYS:Q ={x|:"ݡV_gdM;gi̧}GO~#׃rGV\~W xץ\!x|zWr@uđ[ڝr,;㯼,7e #~;pg?/+_|f-G[Og |=yn8:g{ /8yx܍6?~SxvܭϴF)|rsl5ڜpyF}Vm[fO$C 1г/]cwfuaêV>/yu\`,Wld5C*ۜw%/afd'v6 ;gx75ӻraCXFrYn 3)q<54u(34rFA{DMC'[2}%Jc=J#atwyֻExЛ.sy,HgBK([Tg :€4ԩ]͹~Rz'n, l{8Tήj G4:yy<"sVpdň8u=٤q!=][M?ș꫾C58`I6lhX۔0Y<R/$mccfS#Gt3&]-A,U+"k}f%vۦ2F/yYy) >[>ixh<`q+.y:;zx\Ag\4+} xVnwl͑ucl9RX\!ZPpAoO:l\ ˌ1VKFm am5檀)XČ % K$Дa2ְ>/`0 rv9lr Pfz S%fT<؃*!g~MKBdfmEZJ@Gn^Q*]dW䝑@^2q 2 Ύe(1ѥ6N~~x#&x [(k~i )$P/nNߣ#<3+G% t,azL J+YG'p*(zcI\. _^?Gfo|ߛN9juo~?}.+?>OotF9O~:ߙQs6>7wl<zϵ7w.wvl{YonMs~ (7tGX|3',6nr.tɧL 3kH^gŰK7ﷻ ,w3jq:̀tmY} _"54pm:Ұ1Fl FC@ƹ׬ .CuI1>E>@(/Cᬩt7qdj;=1 fپg6>sz>R`6mle9>:! 8Q=D<5>v >kLcIu&gƦ+#C"tp8Lgvh&ER!FCZ6-2jۅ#"v#9#!!A f򐂸*Qh~2yM謘rVq CF#(ebAI2 c;4Ȭ7endƦw@~([NQ_ E9z$(LVl޸/}_D 1dj&XG7_0:wqkipl` z>[dO@cS7)<{p]> h՗ibm4JRǀ>6±32eU~F,ى&Ҧ;1Ka$ ,pf6TK3iBc>ZAGz5 ɹĀw Laٻ!UF^<ig0=njKS VD`R NWpp\fqe\"6Y~ ~e,3Qh+ ϳ8VzT6vijS2%ToS[E.>!.D1> ͉#wOz¨yK,%H/` _0Wޕ!*+f<^*8f#P塢v3⬃G#o[IfѦzJ+3ni >:V[kD5ɠA:Xϣ7#FOd>?l _F᥺*HcGB4&o| AyS̀Sv 5 IDAT3r6Dx_4h!A3:F>RT$"ɓ veF/ȧ<@qig&t (8psMd5Frt /gZ{k{6ͥޞxSo(p{o>9WiO ?XP_z>*>uOc#|gĻwKۿc{ًo ^~y1:k1r| Ug]9#'ڟwf~%==sܭymsknQcC׿ԭSpvm?}[ ۳~zˮxh/YW?"WJ@a\BjTg(X$. &!2r  Z-ѷˡ{*u#K u` 2A]gd&_ͳw",dmӆi~S\``Æuͯ?s7^As煹 l)KDJnX'h@}r8 RLoRtjR R#ﮘl|?… K|aj0(>q^f*#̫jE0Q# oA:LjBr_i 0RW1K/.T-:U Uy^|WyG7ìH@*_\{x.#'?J^N&|q|e8[:P~tAbMJCi0)dN‡اi5iS䏼rXᡷ_.*g2$: ͱAgxex?~'q,x.|>+ aYפ㑺ZF/Lɳ>m;\hi|%>V:V&| ] l:yf'w.6RI*#)/xJlR/w-3̀3PzK^xLwdo0?m?ǵjwCOʁ7~eFkcM-ihK5`Lg"f6jlTcjt5ۭAfYls(]%7aQ_@8P1H{#K ,]8Cds5S'v[lvޡAo8@T/M| V3aۘUss.`xYi($iߠ 0,gn $N#"}=,d(DZ4% x![5;\ʕgp9Y>ow^ecĸ؄-s 엹☱l@[&#_gK`·`ra |7cy Ъ $wNhD:wUe;>cj'[7%]ܷ4QbF#$the:>ia؋܅6xۑ(h3 \glgr31;8PV;K<073c Ф^˟8@%sp:JQ\8,:?G3Cז0: 5K&\2t.lftd CSUYsS3I^j/]k=SuCWs :.lMD:>j_C 'g&c`%ژ+r/˸]X6qIGW>P\ `-`z\t`K,fn:!6Zw+VtgU'N I @:pAAB\ B2&8r}73 t#"&*Ip9Dsi%KcSeP!7s2۪fw'3ae Ґ|[[Q$~u u).(zBǐęVT$!WZo2R4rʿV0OoeA>GYSL{剡I2"I,2ȹ :>8)97Z,1(Ӥ<0S:~G/e"[ ,+a35.gtE܊Gd Z!epo"<(YY!;넝䌭 Gi,xj(;"Ne!,KEzdݮ`W:0r:.y"KK*?ĆMD¿ФI, t?/e`|ak3(<-{1ux 7MOq{{eiX7W#}Iw,2[Z-𥜮ȩN@,ӎ% 0chd_xͱwk0(v%Ъ!%Lտc3g/w rg=^Y~ţgM^ 7\1'C&$LzWdh Fvfk". )ܿ/74𬠀G` mN3@`MxҢWACNq(% , j ?u),K:lzNDb/ndPԅԯxo9'ŲSTYXM8xBf(JWhe7.At AՑyVXa*πIqVkєDWHnZq&F"Ȱ}*۬<32֖>G❂] zm=y #i{q3|ϵ?H[%ҟN'\mmB^rct`4 d/{;$**s"jZӓhŇ9QrR\f-O s|^.=09AD Y96Qp@FìͳVg [# H:AV$ Va%C2m\Ls"$ps}Jf -7 哴BceF HLO5—f&ʤ;e G ZNeچ-[y,;ו$N'z+rW /ʊb Ll&Dg-qi;ɛJBy1Cpt',+@4Gfg7,"<(R>ao+*:*i5>tpiveROhWVZIO9~/iE麤2RpDtBq:his|3lOP'rI7tD:xn2 =pUf ]qE ;Wdɷo/h©oiOox''CX#XQia;快2P>Abl_˃ "ab3.F[0Gkf`>24 ]`${5V1fwA1swUc'ip23ZNLJwf3|OF@`-`/:ٻbbJ&V~;Hz.iw.03@܁7΀w qllꈯ$Znwej?d=Rw<)^6211Kpi}$#g]*q8ee9}:_Yi~/H"CJЇ8, 4<@N99g6 * >K*gxg ē7~Ft})O/f _M%ogYIqoc!8vCuHSD\Lk|.iHfWSi~{#Mxއ7%3[^Ac*xJb,D@l~ e2 Q`KU(~GQT#>Β_e><щ);d'=/mGV0R!w(O +EQ:'7owڔ.` 0}g'i>zLi;HOгl}BB.6,/ Klw?m`2MX b9"S׸M $MG~B<&!Sܰ.cb\!I# 58gv^Ǹl :P#8RQp1⪁C7F_9% g#R0- CGNiғK0 +eP^V8ip8qX*C`w~%jw+U!l0D(xtU^hOQ<{F<7pIT,iZ .Oyť#o+t(_\_~A0$ %Hë=H>#|U4!x$m?)on@04tU/:7:b(VYs(?&vQ7JH\4m^'eE e:#\ߝS=5{WwozI3x)w74 d54shy!yT'wjX:R> Wm)~!8CF?:AA?g ˑ,\=e }fzy}  #jL+|H` Dlh聕 KQIs.uMMqc-!s+ D!gʄa{cZlEkۂ'Ng ýI>]`Xz,A=W@㬘 *:Ǚ"b @ zO’KXO)S":SJx9$L[zϐ9tYH :v19  0m:gO$fY,f8Oj9R9gۈKmpjxڿ_T `&?؆Ln򳣶30n G2y,>)EΫB%^),i\94Ў2֎ CS=2wu%hØDVs`,a8 4/>mMib944|ֆGϭ{K`]҂SPU;/qe#"Ft H$1Ȭ*B! "rڬ^ {Y)#|[oy|?hR` G-p(`h u)2"K XDK|wL!_jBmQ;9{xk?3A)xt]eh7gpҌ#EA ]qdRd'{Gt*寍=F;2 l,^C+|"ۄ!>61^\|0EHLg̷S~vnjl" dXj\)H%Vz[NW@Ŋao43@uFTN㷦!Tiz%,GbIm! +4 54xlt=}2cZ'QF%sܥ>: .C\Zf++oC:I=E)z %N6qNJ+xP;V I^S~$R3 = t%YZxdi#}v26C|?0Sob-cdb}>wO8M]8p8>۟|\-;(6C\8MHc@<ŷwd&Ŷ6+M2ΌK)aep2-9b@nAW4x.G +t*E0{ڕeW,5bP12Κ7i֟*¦40mKC:Mx x;Y?'j\*#%^Q|>t߃ddz˞_z~1iHӤc_QA{ȓ=KcX]pN* e|2tp'Ψ ' Ã3H\Cci±H0J cV' 1|~,2~Q#|O>S E1I)l*3@*5F㴐?ЙqWwrj;# OeA_*G\F52;֌Y/>#M^@x#:\Kq_s+³1uC+Ny]A겸C xo| y8it$ӳ$L3A=衽cC@\,̠M [{7z+{څ#oဂq["Ď"B^Q:aW.+[MUZŲ2YÕ30!qq͟ӣVڃOY nOdtrc} r E0WGixm%pϕM~3|*IW%*Yhdbp GyWv eG/ost 'B&ikn^N=zb|d>}zr dJ'F 1!I8 |rF*"Lò#1k7)@Ó5:(;Mv N ;9iޚqt\ >vld$\Tz$.s9Sad*ę#SIqiblqN fI->cqQlUk5qߣ",'*TR =!I"|O 1hO;#m|vBP./qW";kʮp/30×P.?| ܬ0zTNÅrcڥ4%OF璆[,y>M w/(! I8ۥQIA*W<::}zvR<2HZ8Zj9zP՗_}n<fԣ!^, ;;*etNXR G+up!:zMaA' 5,X%*u gIdm{,^ac?Ke=/gpgC}e٨̿~oe{XEi~5a |i9 b6 ہ2iz\cXYB62 WN:q]Ggx$=\W7h$L )}/p p}w IHH#;Rrȫ ^j`h3|ƹ1=lȈ t>hC嬬{.AzInSVf?8p }P6)MS.+&'<0ͻ%HFF78E,hƤ$0 qV\PP4'/]we|VߺmBt&{֓KzNDk,AzQIt#hGybٽ!P&Y!c*3i +@Rb/Y1"^3s6']_>EVlIW9(A3GƁݢBvV46 9 ġXr]!Ut﬚/cKeݰacrF\3To9X3qO9N ac!,|mSD,-`" 6P#Yx%~G[>yO呰]V 0͑iG26U8+peLAgr"8H Dϵ #ưVkTT&Oj3GP[ 14fY3,8g3ha%j4cmmm9ɔ5nN&8TJ^ qu\jQa޽,sr2Voaf,|F|+x[e0ilq''6= |ttrV P.Ű٤!sv}`Í/+ B@4B-p0[ݒ marGÄTRyg|=dTvy8k v{{QqrƄ?Xڮ@;pHc<.n`s̊ lgnk2$!2;2NoqQ])iU؀:2d+IW,jj|qI7-#٨tҫ(Y:Z.+%N5xϴ23O:Ŀ bé8ßYިD^V8*TSgP@zD)?H; ehZ3е8QHXNb;bKq&~%zsO_Y׾}mdvr/h!?ۆ9W~rnژ.xS8df˿>ιL۶el;:|x=_",uv˳}EQ~>DҳnQ؋ulܚ8}pwȟʁ<0l5(&ϱڡr5.4x03_y#Y@[kwpi7ix-,5iYQv='3Y3ӹ·Ԙ6}.߿j}R0/ `_Be 7\Q~oǁc`N"555|wc )ZYlY.ms_?e+ZB~?%IPrTPB~.-WZr U6!Fd&__=(Yeы:<}ޱ-:>Ȗ9yp/ζk?4lvթ3ԩSmMԈtD#:Ė-"E)HB3IGADH1HLZHq4DHj@b^֭[9u!w]mGٿ]i}~z>5p.9Ufި+s#sR[)M/+] HGW9E]pWv8<9ǿD9]*qH}+C.}f~<<{z#p6}Rpqلt:/>lr{r{v%آY, t}[ZD}=G~WCy<;؟A_O_jғثJ8=7LaW/vvy26xљx XɪreSF J~ݲǓpٍ* 7K3GMr]mيOyt%,{LG_2|Յ8a>#9 K7VjcYL]y6 5(0`g{fo8|6 |܋=]WlE%lBn\Q!#]~Ĉ{}-o-rGwsXq'Ȅ}wcsf>UF6Cc,Ug9IbFs[_p *`1pR+aa#7{Ve 1yb=R΅E+wRNe ld=wru,ړ[ `ZN+nSJ@/t]`2fl³S?ǛCMJ$o⥆Q#. .=|Z.:y%.cO^{ v{:GqG&YHs< WWWF*W 3鍼/}zӇӼ=Y>`ORߏ`Wz}f"(zn30G=2*-7JgHkݢR-v"l I(8&@]n5Ull韥~xo^:\dgKMUހ ^~; >{/0k/B0Q?ۮ0_E *oʧ1^){K[FTG'!Lr8u$>_Ժ)^хp'd /TRB?/̃/~.iN@̩RtkBQS79֧?ytg68(mRa>9lxT˳hTVm+ D=?* 0G9GW4Bm*<= AfhυOp]ˣle x-8,<+!uFX.u'䑀1Fe f %z*5AǏ919p'G]}$'[U{Z|q#GG89WR梎眳 Шz&H1nT߇c832{ cy؉9o>eئڤ͐N;dnmo*g&hv6I?st:'@֛up4pp_A7b~=v'~Cw\`8-9)WpG&+4n4>Dz? f~bv`%kS{dCLP:pᛌl=oz@qՎD?x%>!G8FK'MUi7''8D8JJ.X ڭcYE|ߑ|l| GL:8BAorl_}#sWŽ8pbUw)-ViתKKCy`Gh}+O %:damH-voǣpҍ#X=1 ^4O?mƀ a0^pڇGe-@~NHOꥭXw$duidno:D1CS(=NR f> ]*V{pn3xy~`%O Q*u}62䌾+9$>ldmlsʻz| 9lrWW/ qSZ%{9z:M/l;"'ߪ)=aq^ZV{{=Ib#Xl%f0FKAdcٕ[?Wt%5+A֫2(@@:)~Ϳ|L;rzp;}ֳ+5l~zrrK'D' MG#?k'o;zwOxl:ϼ?\Yu+/gX߹MxxS'{1 `fg"f75|>1F\9&: Ձ IDATl: )\)e ](R/Ը1Mp&i.w7zt6>ԺϪH>rjLϟS_-:Ktg4=YץQF!Gq{i.+g˕1%+2 }黾J1>??z{tz8N2A*!۩2'{ (bFJy=" W_СgMeA_ͮL'V6Cf/(lDH^o`?[Nh2haЮ_..`-GZvɹ֙lF7f'o;?y6jbvцqgk!mWqX&Z^` -dfRdY: zܭ 9`h.Gd{ar: p4ջN?Zo>%1av=K ~xqT]8^, 2fY|qnw#z#WyMP {yFmr<œ!r7~^3 'F@DN\xn [yH~ ~$.8tS1(iA`p7B^B%4q{-p:Jò w?su?#wͰ!UI Qԭ| \1}G*l*;HX9{A\)IM>>]K'SSg6F׵o3 6OTI_p>1 v_pxC7ZC ,7Ft}-Fl LfL~|^p'g+A_ c#>d=噽 3Af/]pKՖkkC򇼞v7D‰bYa7C޽% ϟnnGp&T 戒vnv͹G`TO!Ay(:s%00|d{ׂ(=82+]gf2`ɡLǾNLO3'5n _@A}(#H?(ƪHx.HʙM{>l9k q&;(LLOL(ٛN\oW:5N) ,yu'8ڴogTg:pZ5OYGe/f':pr6p8Ky\~qᰕ \ OÎ)3Fcznjnu'x\ /c_F,I .!@}2 b1>'|I\ ޺oigh/7Afi=i{4g,8賙߽h[BN}NuCA dC+TVFfzgGt8@KGX`(,؊6&êHkn*긒ǐ۞XZͩ}=.Ё̞b>]v2Ow1q;m/:to牾uKkt_ .ay 3.#Kt3mv8CO@C^6 ]9.ͺ-$8sNmb,^%fDw̛ҜxA6y쇿+Oۚ/\d 륜۲o?y-0ѻ$#7}d\&n.ҕWg:zP\Zv=$͊gW&#<1g_ya _-z'%?x3xblUe<}̈PHzHzOc|VQ|OwJD@65;%3]6Ղ_Ox> F]ֿ~EK RoߙV,^>B~:R?v| n|G=Dҁ*#,ccuw\jvO}%EθFsg)kE̦sqrPצ/?XZþke,xay/IN~|ik"0Dr8z6t8iax-cdAU[pMa9m ,gy^h/~=ש&Sy:ڋcu/&ʠX2yk|@8uuVK;~ 5V1iBO4~?94C$xxA`Y&'k7 x vG b~vsut~ zo3-{LGpC-Ω2ٝy adLGs[7*orrŧELGY⥿#-BzASR܅l{ErFh(hSMPI3j<-_ɨIF)f@`g:>28;k{#sANyvˈޝPb(\cXKw/r̙c|́KTds8Fs_Lՙut߇thY|!;RTQxّ?[ǜk9#ֲd7*iSÉHpCm@z#t~F[Ym-&UF7:3Nq,.l FB2pч9 Ws1>YP/OZK8"L pkUocb4/6"_ 9>pNmJg?/w@x$E)P=sá-@Gѧ4tz+Ļ\ӣ9h=Patru+fFP ar}86/'D'_C>,*}@MO8Fd ,MjoV'xbepG= 4dxz '/Zx ߍCT&bzVhTӢ4= U%y:?쨻z&N d [w IqXo\)!B@.sDuliK A*Wyf-?b@ז8ͬѣ81t4"\[gZ%kKyU>VIB=.tw}qwW7cgʻz-%Ū$@9iG aSpcm{H9x7k_ӻ2ixc7y.<湶[S޾ƋO,8n;( 'gg8fGv7- {oqrlS7컩؁#neƣ5=IF&358 N`ޜӝW>4|NMUDʙ/mǑ!ea1+~=L/2-Y &pXB }ЀqegpX#mڜg[[< =w^{{hFR9zT(4 *Wޓ &D9=OƏR}B&K eψg~WO;N?VPt ~D4tI9tt|#, gݎ=8tO^@g>Ӂ`S2IR1ᝌ>_hٔxt֑5X(uG%3`!ER{ܕ?\duzkGok;Ot}Wntgy].܈5Vܮf L~@Jn]kȂWsrK{'~l\p2_ LHetG[G=o5" ȹt8Y__(u $<NIU=Vx(n]``Miݵ:Z-iB"1j$mo7Mǭ=_i}Bsh6f[/8],tsh;>%Heϗe]{ѯ6<.J.|fS푦I3m;({zn]7dtl.yƫu+wvIQx(+A0g6!KGNurG q- 2}JU'"<}1g pMǫ-R| =.5Zhd-a,Er7Tt2R9<T I; ];R8#kAO 0c(\1;ԎJšciҎI #!mn7,g%:|Y9?@1m )Q97/`Laj mјpwMLsAB>9;ZO Kp#WVvZHH!> $h0> [u qH|8AeXcG ~Ѣ//ݞ;zgG^Jf-\c_VnTO§|:A[o)lR?9o2}佲\׆tm鐿CW?e|}́9߂*I76 0#)U/Ahb8Ъ9zn쎻MtF-6迬&dN=IГpȞe-iK&Sy-g AC̿LudלԚǍpwgI4jqљA׉je5[V6 Wu_5z\3*z1kPx` km_h7OH1~1;޳du|(ݾ/wΣǯ@~i| IDAT5}-4x.Mwߗ ݣ_c~w2lv\h2N #ozcc4_n;znHxw={rjDUPT} - L^dHmN۽>o^ ##wP9S焟?ˑn@i6.i2I\eNGGO4Y_ ѹ"z?VZg:=6[.KSB1=l8ۮp;Q.3ExgɠAk&W#6HEl췔z gT|l B8qD ,EBoz] '.AtSC0 "KFz;XRpbkn Hv ?ZIN]Lh>E8MҸ'vEcԗ7Xr2< C _= Q'XdOfA9FBO?Xs=?ZEPeչV^Q:xt&*dxҕ9aԁ|4_-`qeIPz*[hZ4#2{//^=_s6uqvQ]5:Ƹf>PMzaЂi4yMC}iAtkw27yn?N|iM|3~§4w ЋOo3 &fflG6F:_礇ٴQy-/PRMFF)m5#N#P T]wF3#fq7޺H>t\N4oXͳ#~i7ypL>xg;+=GL9G@әE6^|:{9p^/0䚄o2 GzYk9wKs??>{w 'Q7 1Wq>11[N˖`e=d[@@/ܸLʠKff? L3t*2z8YcOCd+VU1E L L$4kxXPޓǗe .eC鯼~ot#$cL|J]\8B]yzKGN=H CL<ܾv:=̭aYOKKO%&Y~{|n$iW*UI @PJ/Ƹv|aVXH)$b#wpW |J;N_njyGռIOOE;}h[_q~8VI:xZKr5攠cBJnZm1TצtP4%T5rD`S#^Z||B܅4CRYtC4%G=gp$hep\+b7 ^cZsGr[Y=S>9W>wZcNr9  d$`_f~p #3K U-~՜gMJ*zZ#?k>R`?u:OI>=INH<4\\/O,2~ oM7 BB{N O[}i*;9Y#2s?):]Xi<\ÆP ؒ`W.Q* t/jl|Oo?86٬*P}T1 iuV3+ko>K5RzQ{:Su7UUO5,:͵iΤ=tٴusb6.x:y\W蔳_u w @FAS?owoYdW"_|pS?fec`=1݈&QeѧANup}Y(1e̚ʣ|@mǦi:2蘴_smf.~Cds4:oyoovx+ hoģfSķo}L]F4.NF&֨hrgB9t^4|5,tWN{&HMc^S&a^T&';qk_0"*Ƣ/$5ꛓΜo&CA7<^ ǻ{ymRQP0%g i\`vKcAP- ',$*眞;=cgqHij{WӤpzW VadTnUdQO"Gix :!?ʞ{FlܵV<ԧ#`KmD68s#4ǚ~?b]FN D`+@_F;@\:_h-Gith;q+MG,x Du+xt}ayp)ʩ8<=w*Ã#Gp4 X%^t"*/~fw?^5gnR=RBMa>YrU]J#SEby,Sh4'g~^N.s Wޜ䌋#1(ϲY$7֠޸f9E}WO^}_||dC!\˟c̉!<3_6HQz'$Opr{[=</'yKo>Pt dvx=]83%sd3bAA]|d CX͌j'} B~jIJ+>_qee_?hS @Js >2$4lL ARe3 l _a~\׽L6AxbFǔJs I?tw_g! F~!9SF% d?;ţܟY/G2DZ#1 yȸk:O༑sx{<73#A%FO=rczЫ>eמ z;N堉,3ڽ{(.O/@O6HxC[|@5sիM?Ⱥ~_p2ĮW>jo4[pkoWݜu^y_O҂~ѓ{~ρ'\,N?C?R}~꧖O~}sZ?~1f*/{W8ۅTب:9Fڴ2*gꏎFռ1W6 ?N8+,NK1)MvߚvbC((MOko6;g^B%ToC*}5v;umwCmN#G`Mߕ-`Igۙ9m4i <~7}" ߁/ltyܙxW 宣Ü wNwГe߈}@8<@VQH\RvƄf<g0pC˝vw$}ȶY}Z!G8=YX_1oN ־sԵo;!x[h2 q9ǩgFwI~xT_I.!Fm/緇fI Y8|`㭯=҃nBlg@̛.z[? V+7y܌ޣg'gcݡt&3 u^rntۧ᥾iMKocHq* W@{9-^߱4 ߩM}\'lО xf"ĞɣL /Sg{O<ѕYACoko̾f{HF} hœM |ڟ_ 5f7ѻ |*2cB{;v6+_*|#s4v*Ma' gjb`FY7=%UJ]27g**|4r1Po~k^My gƻr7!{`?k ċ")aʄ2_pb;~@@Kx*\MQ'إm$uYTx?G_O|7Wm?NUVsPl#WȚHC´p"g2 G}Uو:] H,/ @6(cUQyic', UpbKe̩g36o\z::X7tgA @]ѻRރZf7cl@a#LgrogmrN=cٔz^)-; 658HAe7NN*OX!wHu8-z|9p{W|$\:Ư~ʖt 7240._`*}.x8ɓ\!a<{, 0,HDtO6UIف[-;'O6t蒩t[@]2+ Wy -U꧁59NHW˳ >~n;X+;1ëOWO?\c*ۑDuMS_ȑY:}?3={6 [Ab3~g}nKz6_ H_FjB*gO]OU]uoVƨñK)T0;@oû]ml%XgTA8CQ> &, q6O?5g-Ҝ_F8.h^C#c]bΣ{FԵMz]~yJT#J h.m*}V+,R|#OsqnL}.xTcG8pcr QkV0uQJ>rzt>!a:l`NZ׿Yp=bkE4/+cw0d_$Dt?qB]P &.£3$Gݐ(PY< ݓ&ӷ}۷u&|ԟS?g7Z괚;d 2͈::LIѻ3Ro-w6wf ŌaCԋ/!:;ؖEWם#O#9>b'pPt*c#S!s} KQ}=gZڔerj?uk+6 ((=yA 6_ֽou߱d3gI pkgiǗoo93O&nnC$)Ǵx0Ѳ`RCnҟ/z|91V9SNK.Q/ 0+i8'o8ۋûͨjLQWnTG+k7]>we;6KffVС򘹂 c;s>NH[nNx=Ut<ߥN()#v}GQU/  4}4YdÖ5-6i".U3hWCn 0ڷ%:dchl[_͟ě}kv2O}^Jյީs `@DSgPӟ\ ^ m^|)iy2ە?Ø 1ajB%lUlZ:R3b&Mie--x\FnܼQX$(Dٛ~9!+L>v/M5(皦p(9 Gm+ ;㣴Gf, p໎9tA8 XP>Ȟc?i% O['8HV#;Co7 n{W58G#o Y:Esӆ/;:#i:x _ ~=|M.U,,S̍yJ7:,;e?~C4(}ߨ_yS=<8˦ts;i/*XB9ͣ+Wf1.[8l>Hɩs/W 7 x!Xu^쐣KsǏϱ zNd#=|}=[Dk c/Q3S7>s x^k,[]  ؋abAO{fEL#S.Qc@N.e:"zݭNRJٔ9`9l%A#_45ݿYynέ&ף_kwWOw_+s̍޽{t?8}s;Nl9L|??z;ğ?~9y tM>`VqU5[=b?ש~1ITݦj#^li.`; w8:s\GPtByV7uĴQײ}yw#shgV;[YPK'ڮh?ỷ9Ž+7w MS鎙!-Hc'p1-.t#!Y3=F .նHu`%sGY~,A>P2_.">,lNk[QI=m$ VCXߦX?:/52KkY63"FgՋC/1 ByV H7J~Umـ.Z(N٦Ǘe8ZP.ГmpdK0v3'Q'6 ܾ﶑\j P{u;8?ުlGK^mSś~fkN};M&8w泜uk%|hht~޽TLԃ'ʳ&68s< gЖN LJ>n*>KaS{ vg]îQʟ %8 <&<_Rf*Gxg=tgN_}31]ly&0,{oرMjBwV1~F>y_&>?,@9a?iiT}[[l X7_IwCKE˗RT]NUsr'xQo=Ǹ`GL@K0^hpu4==r[uZ( `illIWG# 28<6"w|a6^-׳p?l6~Bj V 9P.f325ޣN_4O3?) 2J^s_O~ (_>}w}/qu\^zi3~W>?N;~5xUH8G7an)-~{ٞC^X.P陏DN`lFg[^lc .ffm<gr<ͶL%{ied>۵݃nd2hǭDq@I6Ggӎ6'D 'u%h,f!}γӛtė&f2~/ണE5rĹy\yNs? ʐu.oҚp@M'?֎:gL+]s7>oHoepͦ~ k-=cY)@h3;Y:d[JPб~I}-1 xoCC?4n q61&r6C[ukDPh lB#|7zmxG>DޫT~fD F_<7@etE4{YSi}Y [}zTQɈ! ~eSeхN8xۂ5.0WO*@T%x̎4S~>߅Gf5Ww7^aFvV)8*o9/`xd+Xo.U^?lݷƕ`9~[o}VH_ {^5,f@-a/2`;$ -A ~.fH;cT0Rf;c6l*룴yקK%xkDg*5:VZ@H #G@(r'p0Ԭ_{ֻwH1{iK%0ο 11ŋctq)ʦB5>yG7;{zW5,_i'ҭDxDNӜb/v|[1K4j2s(Ye2Ӳg<2Ҁgp#׌m r8Lo*s|ݧ֩Kl >vt'׽w|4\c_rӻK`J;tL9\^U<׹UdfE{d &X%Pk#óuV{=##Ϧ8e5 JW 4(3@;f3I\~79Ѕ3'n&@4+.xfG/zp4w9i^lW9ԳюWqSƏ͒3 ~U$tՐR][=??|Nx)؏}OO%L׷|˷ҽk4_~*߿\>3ղ>*>~:zXMP'MO]S/c 3uOsb G誯L˹ZNk/6+wwkQv=n+~w߃^uDT7_cߞ25wCR H}q s Cx3a>΅)=V~W sκo_iC3VԔXgZo{vAzLA #`fg%xıv/< |6?Ԟ #/%tFn*VeV+`92Cv^~Aɩ,ұtʑ6+a^P&Ğ~G^[|P/x:ope";ff/Ŷce"={()7 %~[]oFSBtb 5Jѿȫ}$ Z6zs 7oZ~b?L~BrRW*Dw'%v D0nLPZ@֯77O|pΜmg99ber5{@ݨ?$ܿRȸ_z#͊[w9ɊS6ʃ~_I \_9v?\z>8 씠Xz. t*p;Ynكr-QKׇ^JkGf\-P;x.|=૏xUlcGoKC.A3dr9ـ:1`pܷԤl))GՖUCNK^{kǠXhgF3n}*X},a?5f]u- OyG4WB_ou/43cg̗wڏފ7WK}3xL|hP` gwˬŌD̀1ϚZaP3L >f?FH+~ w2@1b]A2aLFX%p&Ϲȥ)Yp$sa~6{p% :~aiDÀ4X9]vQ؋B G=笲-s;ҪpsJ\φ\{鵞 anB')x>/xUhlGe:?yڈiy.r9h`[ o{*,=tLhOCShd2:mC ?kȮ*f0zӸb&{S:9@'Kh~}tTsp0~}-HC= d-Tu˫>1҇UnueeVcvCd]~[u@{gӹGg2j?ݽF輿qz™K?X:].vgs]X28'^ Iy>go[~{kU.jm cr"ªX #Gpd_"YA\ n#@[I #Nunf{mޯ|~NNqw|w1G7ǜcntޞz;^n74f)wt՟]ǖ,qlOr}YN|v!}n_1G\FM?_1~#|w_zM5X뭎 b5K?gʯ\q??v#?ٷω~o7rdtssu>zY[p6TƓ\{B׎ -{#x96ީ3oZ}>[ǒ]done p^+֭بqBL-nx-ƗrfL` !w9s ~kV IDATxBF{m@9 &h|4?珽E:vIHv?ūu?XhXo4@۟D]q/} ۝Y|{U2usTdSĵOJ+qsQ1v`0q|H`^h\15}A8N[qIT)>NkK}-9Zf@ČG@ M-ޥ U}v6ܹcoo4o|i=mtg5Pz =6Wpy,|I"UJ׬9C/u[}"@r) Y p^r1Z[m4t[f#ړCniJ/?^q_.+|>2' D癦xΤ#VR˻\Ѷ>RفPwg=7Hgm[jk؃w} tGy #aOYU~Ͻ {+OJ?T4(.%`0Zp{<+/0vMϓ$ޑՋvKq˪ۢV;VYFyB<l?9}y^(fk=nߣpC !>Fo3?QFJ۾Ӌky} N]k80aA+,'E\f*)\YLѠ:4_֗_*㙲7+ K^c.<G D-Tpp,#S1'KnʕO۰qKki&k)7fAV^p޽fxC0IٱQ07MS%MmT .N.ʁ<;NaJg>%3 ~Gӌkr 1,Y쨮RɿM - B&~Q+ѿoϯO\<xkn_}+-= Ys~Gd<YqY_k]?gl h9ß?/:Mc`!#< >gז(8gݦ:k:<Ǟͱ4\9շ r՝=8F9ʜ6eA/;:ofZlV𞳱2٠ggM7~(7vt(pfa]ڣWws#Q:``._nd:Dv'DYǍ~m):\t.Py˙$ku1!~2A9'hm;PЍW8M0<[0 7fNkr^g9GFA@n~ ͹E/=H8qo1m/h)ěmږmF?s>术3$F ׺'~p4#?OIds5ɼKm߈}k@NݫΣǂ$n,KP֟S(=ر#|aMS`{9uf ZU!u__CTw%~`=7;f?slO`P}=jA @/+`\?ćXB6eK 50V}n}N-qT.; ~<1@Uk`X4,tǖ z8yWTJPE98u͋LV#.qo8 NK|l{2ᬣ-MS9$‹*,N'&iu\bыѿʆG8 tsF D@{#MTᎇ.D&rЃ˵#}߃)̾Nnv,+{}JVOEH/S^a\2h7R9aԄWw.g ;{v@N!,݂E>1w1]ޜ畃Gw$"gs0 C}& cv~Q\p|W_JSBO_?crGw^Xr3IF귧O.6SO #6 /$&BHP?gǍrW:̐St/ERoR^pP#,ϚV͌z32Iǎ=j={}nsL)`glvj*N{5ùzp_@z^H`#?6#[+aY|kAc只eK<}>m<< i>+6͖o$: ٷM78e%֓IxX[рFqS{kzh.[1˾MZBĀjrNƊw(_mVDBֹ֞ $OtpzߺYxD~tul+~y9O(F6s =IK)Ə_żm08~k8%Ǻ-fҾ{ 69Atz_o>ʓ_!^6 ͫ6u֣9hF[='3DoT^9V`B*='G:}UW.:ՅPnbn_Ml>pfc<o1{\aL{uI.uxBgf8ӯtM=;{\X?{~*!WA^|7oJ^tFF t>w' ·!m:m*Ol&xwz*pfi|.MnFfˣx~A,+pي.'Ș4q{/Wzd%T3ҍ8RâO#~Oջnlp6JP̆o{vfLV7K^2d?'Ƽ{WwP̤a.~fտ]ђ",c4m1o7Z>KaO46g4/Lv01f6B$s{搽3s4ŋcpFU8,)Ns{/77N`B-7Nj@=~La J7'4'P 9|3sΈVcɞ"q)bz7EeBy:Ѹ u#e1ld>Qi⍙/ @t{ѿᓾ{`f πIkOmB8}p?W_{--zT,rE4c1|_KWo_1.(?S?oG;p_\_iIo~ٮ̟3W_>9`Mfdذymct^,gߟ6w>ױlP% 7*}ힳ+=ܨZy7r30' XO!ʫ>lbeL^46Mj$L|μ0F6㠌yZx ˹7lO^^}+Wg6u6x(%ï,Ǜwo}j/.@0 Wf!؁ȫ=hgWkkIĆF7J]O*lOh@v`=~rkքa3"^J"p IJqYmfߗt/NDO;cA\o|G(^. i_}.]IqnW 9amF?DO1ݎy(޵c6TӜ+Gᾑp ҡ +q鄑p{`cV9-o%O 4~^m%zȉHsJn38.g\ *|t=}frm 't67N_6 Ac!hK皞x6..Z'=|2M){r{ =w;Ԓ4ÁW >[>jÂ.=S 0<Ǖl^>G^ݎ6t%3[/Jmo<@k( ڱ53a'RY~^@{_ lC}_/lϥ%: :ly@شWIH_E%]^EG(s 1 ))guu,>8o7nw88)%"K1B9C9yxpGi$;X<oz]պJ]Q}]7 `/pA/H`-} pZۧX.I0wh K]Yj>+o4TJN$nܟBaCh+ݙ%peOgOhE{`0-`)[A3@b}t6㡬o$Rqӹ.RR4n#U_<֡8CuFv/GtU'Z6XZa#e#6GY>_2yշa/*}~]}g߼yoY]0R8ybnĸ'P ( X>FgsMÍCuEk9>Em^J<OlYaH݃+@@JOowM3Ț`y7peL/U>:17F|G8z} $`߬d y 8Fu r1ņrOOpVot]yӴ.h$##뮭<~[a?oh#޷{A|dȗ`{zL0gzz\Z&s}ہLˑ6 Q|S}QSJނ<6?JK7mMc6O#\pK[& z^Se%:s|K"Ee<&c7<.4Go:' A}}$8w" }L@~nҰ%>Kl| yX[Hԗ< }kv2,w9#ޯލ I{W$`hfswG^0t3F,G7^`K jy~7_ HVlU~:cN  ӹU0R>$']iu1۱n #SYrKpxBlsZ,#_X}'a[ozsk?p?k:\uǕ{",zބ|YkD㘄z7 /3[`ˉk-rḷ|͵ӾG*zXtTvmpNE['SIP{ϟ~  7/oٻ%#y27~cgWS%L\_C58= V{z?_ū7ݫ?Zs᫿W՟sʑo$_q@4wYrԶ>Y5޳]{#aw8 FuѿZXU~?k[۳[9j?V6i z*?QjNhV){,UP =^Mt;؃Fٵ:ءIZgz+v2Gu̖| IDAT:-tΡ,HYYڷ::0 K3F_./G?饫p^lj8}ȯk jTN[YSC}Z=WKNz8Q6Ԕf\v fݰzZR arBzM3_TrgJo@^Wi!ײMcNnB1?6[D@] v{ `,Mۥe::ﲤw' iW~"q'9\rNg3'?.[Nb+{LdGFrj+ S֧WW$PWo=-z{NMW]ܷ@? >Ϲ" $>)a'M73%UvK>)z`˧eb; b*yYQrc:cd@@q^}W_Wtce>&s]\9sV6d6 Jk#+sFs舅7%\K|hW19Ju#4xvvH=qdt2ꤒs.3Fφ\vWҧowS:ORwsrՔ94Z,q8pV$XȟBOORS@T+ Uqht,8'X`3U6ttKܵ2N:rnZ`Ŭjg<]o$L .tyKz&'y-UoMw hςꐗ2/rċϵN;nfۣ9:l )%5|g̓L/ij)DdY#o>"s u 2d?]<3!W}s驟4T-f&z,dw5PC'd #>\0=1Yů7իwTiһ[FKt:_eHW0WkvWvv}շW{W?xY/ſx~6žizCdǤ6hݜ@s-`As//qj֨N¥MhTQ9}]Go`p„l.gֱj_9_kC )eNZhBii 4ՃQ*brr3BZZOG0{MteI;S(fG|iϷ^`.|0TbپկY9$z %(Wo\}>_9ՎuT,L7uy݌Or9kjbrltzܵ6]OE8hR>ƿ?4r(/8&_)(`j6FzcV9O81p>Ŝs1&q K<^gğJ[f|0--bI2 p#s DzMqAk8 ,(n3v6-ݝjN$?[Wom 6{| R6 nX#% qdK9i W3 :]7Tƣeyk@1E>Z|sYH/2G9f9q\}"\ (x) ,!/,__IS-RW௮ʻNgLPz*G6@wF{P L'eT+qtT8{_kW"yPJ |gΣ]YkaED9;q#kH:^L>drf?4N$ɚ )[Ҙچk Xس+PغB̸7YI(aY;pɥ)Pxl|UTzdݞtu{>Am;lZk8[i7߻* fZcz%z{t>g߯tɣ \|] @'y ?&8f`nXnp υGzyu:~؟u =^D;Vy!J-Pp_5Of/y=.7mZR=9}Tdo{ۃA s#!2i_jr&¦)*9g7zz{6ֱ 74wm4ikFl!2}qw<ɸ;|5*HO(̆pZ@SA{0r$nM]ǵggpӞٲRenufl>hLaAӦО~Hy49~=PӨkK\Oѩ 33/_7?x4g7w_iGůȿ*O@|;AW7ud~ _2{=u63 ̡d˿p-h%k6vm,9ӕ+bi"?f㥑ӵVF`]MLLv(It,G;T{HMX$&Ӏ;N=1^J9JGIӛp3SA>/w}=t͋Fޥ~j9ᱍʻm9FL_Jm'sz3&Aҗ8'۳~+=(lJL f'D7xM>m{,Ǩ}z]? ~ޓC:d(`sNvӱ96u+\$Cu̬"eϨ8U7qO%F3Q9+<ć`z_݊GU'>ԂA&G߇~Y.HmtU^y-_fʖpG/ ,ؗtqQ?t0 0hC~]=s[mX~|0{R{WɕqL~N.و؆{tD{/K5y3pP؋,: xmFq=J O?ڽ8ґDe9 |^oxILZæ7}9w_Jk:.qYڿ>qcʬ?c!+c?bUZg3aPb;91 HdB3Ic#l;Dҏمc~6(g/e2(& :Ub< ESw2G40oVyǩ% וdzLӁJ*)(!xhEG{`qАi3BKQY:S\#,dj6Ỳ`Mm} 16/>n;D%q{1 `x0g; uORɳd ڢu^=H!O'u*xnjr# k=ʹtۃaD_L?X'ɫ~gGkz0_MiMoqa;F9ڪ Ƽ8'#JK >|:&cG7an_'p5Neaz3!V5,zSKyxm3d.h\4lr^]Nr~׽Fh0Td~ףG\go7]9I?3pj8l/Ng:[ryob2^:FK(ǘmч-uZq:6l6(.v]H^9G!}NF4dQ\T74)9s86aiu!zo7&bG[<1a5V}8-쉟O->iOPr>mgk[*q?5Qa F(܊O66bþT'FQk?3>|xrrˏ=R¿W{與m~ 6@+yWD9x_YNA6iiuw QZ_>!߶!qlŹ[4sn=d61  :fm{lY_{mTAs7{#Qc's G:Ob_g.Z?t.' %6}h$7DQq𻝾9W[W??{v+tA׎6p,Ǒ/!r>)V'ƿ I ZKgOޜwK;9-yBi7OG4|Mܣu2>y}kzFnGb9cT@(!xt.#-C1d6|-,A.S6|(G2"N96=P/|@#C7C _QrGFKOJ|,*2T *γAf{v}Qf2]H~nG)Zk_}r++Co/ rofϗ۹_q<G ]H.A9u4.XҘ1Ebڮ1Nk^цBqp^mE__'ݕvySF)k4K(aR6rKŧ>!Hc*f X)GbB#1SdF: :xQn($V*KnġpqdËZZ>#ӣwgz+Pp>01K4 ^=-7~2pe! q$ům)`vRMXa^jNiK>c6ծM ~Й|w'ek?KOgֹtYG5~+ۥmf(K1m/ⰋKFM>:xrr[u³R/g6cNmysQv}hrR뫶z y;=p[n eБr TE;#Ni~T_ɹt4~W5N8ϛGe]C^߸//83g#UDL'|uu Z)6q>jdс>0wl&G9pޱ]ڐsoLib`lq|b9ZekgtL{Աien.y^]qNeK{咗MQb7շI!%qh8"ۼ-Zc}e)tA#K紼_ghu>,Jr9K{į\at.akzG:4$\?jq(4gdWiܭc%=A)?:[&&JkFt1Yj;r09EQ__/¡D7ݘܢ7~P:<`{~56CH~ ]6b业Z miJ\fz z>b}$ vh_agυxr(yY8"G>F4õ6K~R|0 sad1ggտs޻A|چf;=M9|cfR/;Cv~o6W²: $G *ҏ;kRBR{-ٲ';ow zgi_j ^Xlv=&tWx7Pl܌vP\*p\MS^ymSrI CQ5>=6V"Qq U U9>[z+!q!-ô;!K[᫼>ckڽuej=Xk8VnJCR:sB +cҗ?pFdr_szTSMg u<zsp)/3x4΋p~3цÑKT4','p0g4!Kw׬O6mTxe(җ>q"z^0*EFwχ{><v9uwʐ4S'0+ Q۳:Y t(#=}]2*L'om7*c|wؤ'p%Y%g[Chփ|.:ϗәݒ\鏾AۭҊn&`y {Tp>LgpΰĘp;Fo{yxSrui0;ĞT&vot^f5Jdu9hBoۈ+f2///:~[?0Qz?o8k9#M2uuL.p̩w{3V`-SQC"1aӲ`11U'vi~]G-yFbgぼLsZBNkrO/vZy(g_zpvhz::lQ(+v?NkeA'=+Z'u|quGG-Hmҙ]:4Z:|nMwߑ]:5*ޞ*G#ܒk*(MvoDxkr:m IDAT:Ց_Lg?<:͒1pwVӽz_mS>|k9s?L(|"9:Egg/m$of'ɶ|F=KwI(. t5N -UI4=ϴ{aNZ¡'Oi6!!1}w4nڳ;ə "F7S1> ןտpn=\ DtzUfVu(a|q^x<ϥtRxK @ŀ7lޓޓij,n4I2m$ҧ{/'9It|S]ӿs/9mMi9 H9V_Mc%2r 6BǔN: +M<ǣ{߃v`;=5< 5kḿ(Yxmfj)W^}MfXoI"ךvvC.6I>V+׿mZUHfiyz|+8_Z{/p7E?rzup}0;jyvI^Yyg^1]HIoյt<'&r,SY Rlأl{ff[yl%WzK"Sq*ێ t&P+oܿzֆlؖ8_oIp6ӎf_u脀e[81oAv)]s@FT@[+ y' SXFx·HtD*fSb].ُך:ݽ1-eۭw8hP~^"stܻڦ}+?_"AWw\ ~/v1=˷[3 })sAs} [cKs7s@CIH!lR~v h!9ےY9:d6fROgJ?,#O40yЬ*# BwWX@t oEx,X-*kNd4}'4TE̖\dORWr|,} gp>v^Ou)3xIlYp];=3#_KLCgp[D3 mKtg\t<[fadGv ? sѣsq}o< -hB1aS;c3Y.<}`!F'-3?sdFi_孃_&ǔTG[brtfTV -7`eS37.1n6Fk*AOl87ύ1ހi)Go#ǜ9_Retz%^?Zz .bBb#Hic96E(Զ݊>lflL(Rs7BpD3&4q\=_o߹C<[x~,SBe֨?[fg׿+r" F ?To wx/kmjFLX|}Nl)AN:+Ts43|xges ?Nս㬻~!.9ӓmȅ~̎=п~dЈ~un}4_`}O?Gvz7͎VgRٗQ.kWOvA&,t7:EyG`"7]sSSw S|[@w]2-{ulލ^=a) oBouZʑ:\}c!|[^r/6o4eRCiż_e-oX ЖH N1#zzpxܬނl ov/\O8EY E8U0j}]sK4!\8Y&Uf^9arK7 i~Th:H\KE-zwf ]{.pJU/7w `k{ڞ&r;9#I l7Ԅ(4B@TnFT>XB4+C9UFeȽ|zA:Fgt;:Zx#HpoW!(qT>cy qv:Esu,F* C$> 핡* o'Ѧj6{FF_`}~8QMWé4焯Ӵh2NYغ}[8p?5ʚu†L4%F=Fƭ z$a參2$'OGtaӕϲ3;^"V` a?Msb93EfZq]GhRxmc=O/г2XFo(alA?ID~hO^}si$="i|Hz3"k"ИrCj!>xAˈYƥ'; ٌѳn Nq3ef.y;Yci @>~yqthm/@ѳǟ Q B=k4-Bͷ旚V {+rg;+> x:omaxnnhvc$G8ySʃ7Dz[lgpuE7 m @%ԾJL-5)#os~3}}n2WYoo@G;!=U'lĕӧh3 f@c ,=*Hx>y㑲{ٓ`zY-z&L,afnhf>4jPɳiy9Ǻ.ƾ EI>R62NʰqI񥺧=%!wLOlP&}A]}l 6ΖqWT@7ڴ#NPRަ&]b׹{Xc}NsMu}p訟Zn{қVԃ RV@Ҵ>i3R>u1`h9  ;|zv}nΑc4w=9]ZO)d-=e6K6:cWy6_x2onM|ݟML&@h8!RǍz+#܍K9+Qjr|^.W䓿 `sl罟 &E-YxtwX׽ay%Va5ҽcA ^5dkK:`l`I._r6x/7| B3^WkFʍ;6`3Ogkpp@'f/H&O3>mt//!-we 6oR>ݼ{δcXp0^&N}rtZr 2- +pQz|th{MHE7ǍMǣcDB'w[LW/Q RT axЫgU.I7Sf;EgзVOwnfjLvɓZ,:A._\_p Ss7[iT4K:k9`mi^.5l>x5[mZkY>Wֶ[bʶfI`:.ufƨ:{~nf_d?md]۠ө%8{2u~?jD "ĞQfx=Fma4#Wvw,g뙺zOstosFk9@vj߾q~F WƷ>N5wh6?|[~WovoVvi;gÍFNwЯlӃǜ4#/ߋϫy\Wz#tH{~~.O<}nHNtY0 ZDmL? Nkj#o/!K؏_;.-QubP+StX-:#F_G趫oҞ6j{-)iǚ\I^Ϸݿwd,:_o6uүtrFn_O;HySű]w &!1j†k]}gz]UgLצSq.}<t-2җW΂+<ΣE4ÆV:ni<0gSd#)K&+GFr\_I3lʫ hG]_<+,b W\S w*vC<+{)\^ T-'}Hf{}mT1 J'ې5~>YF z?Y6 =A"^|M݌\z 2'P- h镀l=M]U^%62i(Y=M$٨vCs~ xj$Klߵt7RCx^%[Ձk^)k<:0c.JƑ14ۡJz*}IxK$U0+oIwz@K4b<"^w+S_plq%X.wm^阬'FhXEVKcNEչz#X?vQ4PK{g'2ݯ.l%uumdK4ujr$Js;_;{86s{! Q{n-F!ppi'3`!o} v(5XeشޭD` s^u{,;gn}Vuܚ:ebq~n\˯Qz6ABmA3n~ZZd{3ȏ#q\Gs<#chքMˊRr0Wyp\nz}6nwfj)W}D6vWٲAf(S`?#@._Ë6|3J6+*]=}ޑ1mr&h`'f^yk}7=;HpƳw/R('!95ιhsĔ|xUeC/"mqbÕ%ݥuy}W6bܳm*S2OE *= 3*G0|9F1Ev>57n;a(zS02)5pC\UZʎX4'+Hs~ޅ葪t <|gXjǢO60AF&duFѨ,զDл91UtNf2 VcƲYʠbҵ_-M3Ow=R*FKdMu2·l]tsh.`9xGOu|D'J ^{<'غXq6=.izw`!,;=omz'p]N{Z|.<_|>PW3V61bǰT?w83ENI~7VmL>P~w.t8]vh!ga7f+7[s<@u`iS'dvm_pz75<_p;3~||eοč[֥ ys[Av1sIY:s2Gzʴc]=a#xuY|اZ~>8Wy  cGl0^}l}9SۿL+WAKyٌ2~~&=D3ky),#"VJӶ̘Fctgq)cnYCV5F=s ;.M~7%A[&Fq}8ktk/VftglhR .'ػȦ{MnKkDeY˘Fy`UF&Ԃ:I8b+ Vo4|y(0|Т7%զInv#%_0x)A6\3u] 獎R9k[g 3{}ynW_dFOǧ9R: |:eS7Bݧ#H64jNsUЩ6=oDZ3ltaAhvGѣ/8׃ 稢] oׂ/EOOg6!|tjAw{6Җw_ѥzOn }&/'z]\_ttE`z]̄=^lvG>4wc~9#8 IDAT<ُ&An>K>+mHGM=KyJ#Dj 39fe/\ͨXne׶QO+뼮$0mxG6L.i6;wWgtI] RO۾ɡJ?{f oMs՝eO[{韶Tdpuuv~FRJYn:Bx`LzPs)ԹzNɎ[ .Q>:ʗ~G^23Ry]乚|#G~1;: M8Ą~sS.G,ӻ 2Z2/&b6@X 4H|@eG6 L3wfu 0e}c <# `NhDq~ƲqԴ<<͑bHy)v>4T9^G1UU~{ 餍ܢlP =ʝ}[z}~95\#m*<~[Lќ}1{RaSə\ }ux%=*7:_<,M eZX]CRG6]:H̩i83eLn0'J8gI; 먭uH3 a3zlSM/:l[Y }g 9x~G.-ٚi[³3L3Gp$ѯp䎳ņѐ!ȚUNmE|J/|>s/x]AՎ_m~18ZIX2i=wFtﯾR?|1;.~;FN.㴂\p8DŽF ?HgfΖlQ`KJth{F%Ҿ EgӤ/hkvK>w?;,TGwp -_Hi}ks s8zg#N46[a4,'M~_NLЍ%~?z|YD]&hĿ  MHRӧqpoѧ7+qꡩCOOTΠG{l:UK0~3Wo]7}Сw~ogKmK8י @ U, ߮||QOf8{F+H'EfZ,=)p#thpR钏:XZJE |3-Z{D mzd>hGI#6L2|ݒ[N8&SM7K,+YlM}z@Rxh-(9)',% #Ed=ܘ?Mt |+&:.`1+f<Ť GlmznlO+}O- (8 Nyn FA-#lyN>@2""VƠ ň MYFQ)\@;RK2fR~H"SR9ɓ*aWQ>Z;^VuW&Qa[u4!W"yʯ=mPLV̕BCK X 6lg1G; [;rKqxqv*hq,gtgbp]8=_65d{ R(`|w~]5KjLo[Ag?ѿaqmOeӣ'#M񧑅;tzAϗ=>(?+jz6m}pDѼehL4>ӷ襏z{^y+tvsy^5\ҔpAb"<.זv} ߈w -C_%t{ͣѧ FӍcF]蘢 u6LlM6㥛Ճ h|N@S5RɁM#:osCe#:;|ΚKt9c? 6mp}>܈:KXRglh{s.}/ybgϲ:ϥ)۠,rӍM7jLikvan}~v}Џ&鴯:d7yzsJgf6Eo sŻ`>zsr9^>{ӫ73#(Ѥ/>hoܼGy 8ۜzo|~ra#OeIl"N oSQ[iv7zGRNJ]g/r9ߟEM&n`Đw3M?cr݆;B2Q~//#6R]]OT7'^xCo/y̡,WORVg 9 Q Mcf 'H(|GXQt+59{/Z;NMۙ9B{ vwbכfqɇ컎cHP<O#.(ӯR&4Zs',h` / \,qtHߢ8^*~1GϾ!"M=c wdyn%HYg5)j@[?[S>O-m+}M |kŗ9j޻vkW3uQQ4|' _lk91kk/j{nllO0!0'K L\|w G'QQ1(o|N91bU4B>?*%Z;'BO%B5( 7)yn].CTuk#>qX4'p>qH羳^s?:u^/H?i|L {XQj{1޸ +Ćz);+v(G'P5sWZ6| `{[{׽.'N+]}W~W_O~|ff&¸^g7wΜ}ƸvKˤLO'7-ٜ $pЊH.ݸ`2;t3FZGM[gOG;ݩNQ,Νְ@h9^!ҁv$/CUAtGVYV!A&}Ň|w/)v(AY'.slCuFMHƄ8Q h?-ہ!98V3܀IhaplD Nlwmc &|de-b]r:8᝼k&]a(.-GIQpgw.~,βt$R:], c?ևpMo|qѳ[dcfݡfƓ$3:Fyy7ZYWP-s}˳ w3nx!]8Mԃt8 onFH0BMɥ3qt0.I\ hT[^\eTQIyLVȓ .sJJc0F(" րp1#)zgi(6ID{d JA9 `x1HJac< פ܎~iRRS?h]ڴT*ҌXey"L[QgR`#к4LG֟<1+FȨ|Qt9y9xe|F^Ft*NI߀agp  l~˸;1[]R43AAv(W&_kt Il^1UΊCpsIq{hCǹ\) F\DlC N6PgWJut r y#)kOBN otYƊ$ʌY+g,o5x uB):F+'(:0~\$,[m&dBr7 PcA>7e#n#Q@o^ prd q(_'raUs7]mK۠q$(a&oqFqXtE5s- jat)(|R)o|>ka- y1< nwSK:e q^"Ș{2wJaTfΚ^b+VbM$ks֛M٢"hńkJg)}ֺRF m)rLuFe.ޙvgSvmq 5X M%[wiNi AÇԸ]5b$R('ӦAhwɈq'\|`Ӹ*TC讌wqU[٠z!qtvF((fr wt6I/ef;t#5b̧z>_ZtRc(_)O*1FNOZ2L:RR/ ExI×Nh*Mʎr"FPA>#t)ZۡA;uU|#:V99{Է<:'4.Wq~@_^3y)]s;! yX<5y:DQ' _Y܍Npxmδ3PL!ю^ xhgoj}=Ml핯|e{.g?;<8-^{m?~۷/N!gϞv{9p3Lsb v͌Ȣ CЎ0̦rYˎn8ڎNCgl$t qe ,ׁf4Aڸ .3fwsR;Ό<7:Z=9B|# &vM7< ,wQwy1qH6fS1:Ü'NZj ɣ%ha~N1g<~&m+2 $LHÄ_S7f;rnE:Z.9gV 2tN[Jqۂ^Wk8lܸW8fxFz ˘<<|4tc^aOm FFE F]-lk8qن= g {O!gpޗxeXJt,)aۧ+QBga"o4\PFr^)yh6lۑ3̇}pK£r[M~"G5 xM5}zЍuZPKxNx/ݒq+>mF YZ^{_^uqõsRC Zt)Cy"->KL ^wv3S9`p_hsOW's43HAלZ\bϾ=Dct<2 (6nwS˞CGWڿrt!w)Y;l&{(&{ιz0}1m.;l8Tsy%)"j󼽬6l'<dz[c-`,=JĘm4tdt3G-ZHot}$ނSe?Fc hci&NDv4(M ~C F#ϳ.7/a*7ֹ,hܼtڭέ{w#cTV@COI%?.9\dmvޯk\:~ibf ϸ\Fuk̃B{f:VʹgN[Fu~lGjW*u}xɔi4G ^c:hbtCU\E~OO幧xy(/0M^#߈0b}m:Ndek68h+3Йb!ГI)X1B}elr]xqٗWxqP ulܒ|+,YFN@9Nri` uJ贰6I 2YS_h| ADJhqtt%?U:u@3Jw̫k>Xih/6g4r$;XmD9A,5VS`|O88kL1$ՀxQӞ;/Dގ $4T gsU k8J IaQe<%e3}sBlD*0<9Pc/#mt3Ļ42*͋ჯ#3MM c~X2C+7[N E&4$&3J]skqCa-@Z4]nAYIIV>t:Մl:_\zP'  y3 ý+8=T%0l2-e;vFcƤv}Jo;@R8z[}#nU\TiI`٧` Qc(F ʄhW/]3*>Y Ajuw7.~Bcc?Oxi0 ݗgg4L0dv@$+c@8F{-ŀvƗ$9;}|1;Vg"+$$/9aye~G Zjw0p`7c5x+20vՅkE26oyg,!~%ᶳ:5|xq4? m lhYBi53nEbz]#9\n9f}`o7[k05.C};v" $\e>Cqq4}p%ۈ}(I54 N'ҬsHki p֡'wg5`,ֺe6M|uM)G+ j`clʫCG|K"ip'xqhgo8~ GC$)ݲz[>HH0VخE!5nDNh:.KCSu;0}.͹ӊ7i6dzE+ At\`Yr `qN#K Ƚɹ :kD[tN[1Q3{ǐxSO+KM`l;Vv=Kt$3r߉lo .I=spX+@!HmFǽ&7^g|6?o r|u6 It(KF]/l2FY׋: ny^тce y.ALAPKMm]3 9}ItJfP=8ڷKl@!Ǩ E_*>}v,+܊gE%)/~]1S( BùO林$``Y0pb`6N \X_X2P۫A(<6߼:ڰcTo:+u7!hI~T"(K7̳R/7 BE礒v|r,Y <*zr w5Ṱ!yyH i M+BA#ʦB'K|Y!>>:ERX1ȍc)fPi=rTcs,N+;Odv>]x$|W-_ȟI&62 Hȁ7I^豐城NEhukhxYVkG1~i@eW[]udq iiw/Sg%W2GnuFt,+׹C8 3.߄Mz`cOa4;C&|xzІY +Bj7$wo3Sq ]ɗt@ۜxW/)7hl`y68qqnm܇wDJx?~=z1`Mt~SC`I{9\6or/&Dv.DurQ ,iFXn93 vĩq$?g#fo D=:ČsO pERd qYaὑ10I0D*ͳ hBi a.yl`stmhp+|Y,^4wkVQƐ9ʑ},;tr3 exeAjS; |tf#?AAÍ"qKtf6Kn% i}f^I4ǀv:ZВogc;n凜<`]|;Xޤ$ztڭhSp,̐S#k&` űryc\kp(wL#|qb#=aZaNY|+$ Zid"FH!n\0`b(NL.x@g¢pEC5 0Ca+aiB+o,E\#iG!e*2vS KvqcNF,wҝ(De2x.#b|O(e8\:W]24ss8) p2މ:&^䪖!| xl(@%:^%Z2X9^@Ȧ!-cUgV?nUؾGci{ gz(46ϫKQc޸`891);Ȭjip  IMX¬yh(A<7vB3.?/a!9(F~>tn4#A#q0k5no3>a J[¹ :&ZyO=Tk>|,pQԖq2pWu5C,[Y]:8pAgCUR'8iKS!!_hyhYi~Q,-gqtSPvSD+T4rCEB`p~ \)@9C.6`[ymdvD|. aG, 3/ u嗷lx3L%3e/{Y{ݮ8=}c;wlG ~w7L]vY/vmtI}7}S6Qܻwo۽{woisipIՋC 7ˆV3&zvK?>G-_`WV1&.Y~cUWNΡ^FNS:w@{ҷ|1ewӮoϾ(tCD7y/yÞ3ۨ@'cҘ$ men0)KF ?~_V/ J]UdL3C/H 'y 9qBgn'N.¸l:|d4[b(!+qf"Y>>::t9cPңuh 1Hcl@ls!cGis F(p%AIx !%eKʈ2i,8[^ʬ]a6@hDq%#(r~w¸mU2@i'=OָЮخƽYʹ9RK"d@[-j{ہ8[,!_DYxǍ|(SuO7s3܈o&cqvq2]GЩSU}F]8f|C,o{-C6 4+a\I׸ <~d1xh^-K'Y^iG~:&3vM3% b+.*ay O[R6κ]Pq"PeVsr}%.ʹ}zન;xstn߉Gsr:pMLV@I\o[ d,'|lJ>MĺNed cѲyF+Lyxq_G+sB ztf'O&|Ljđdݧٯ; ڱwfa 4b?55 `)}cc$H??o/yK62rh g>/n;#~l#_Ko;wK_?q/|IOzfI7|s6q3ԵY: cM=t -Ut*wc9̗۬~AK&j6VaҞvѾs֙SՍ)=ȍû wa!#~$Lݎt;&QwCƒG0dbo4tT19qD̻lL<>R/ĩG䝑 Gz IDAT7]Z5G0qH^SYk{ l[u\P 9vL:35r d|&nw'Qfy#JeLi+t)a9κ2GNj4N(Ou^*Ta^[Mpϴʜ{b+,ŀ#e\0KxxgBaQ 򟦁In  IA"r鸞 B*r-v$LjcFsU5;$RBsĠ>D [j&-~ (@,Vx" PPVx&w* D;Q/N~(Gp!Ƈtlrt:&Z< _C` bh`F7. 8>(uJ}c𠿃Hr=AXk>϶nyCڏȏsWɟl1??={E.䁟i]vY(׿)̌5,mN׉'s$΋??jԧ>5~sˠh]r%w{&O{g=Yo=~;پ뻾닞]j͝؍h 8΅Ζwt¸A^ʲ Ohp45AO6y#>wǫ^`4Fj;x<%D< ={wf`@ 3rsk 1б|?י!_?ZW:X9_dn7t!-=Ae[z$ :,>p3 Xp^d^a?uAj%}h.9Cʀ{ _tJcPIҏxFIG6E.m9+^}Nv[ jZNԨLmfj(Վ@Ԩ_Gc`::O#g;0wp?vbP ?ޮp=v;<{E|ww=$>DG*?c`˧FCf wa olDܨCpY-{Qs,o'r{oYl|b 1C}j}tigz]_w;>-޻ZC޺2StmS v'*ẕA\ n KDf"ϼ%,?!=Vxb0|\0zgmu:r.,&;ઽBx,#07^y6wA%c6R@=!xA` lC8z+ a۹F(JgaKʬ~nO)]G 'Ɩ! `GK$O"MGi _oga y0(Țl'NEy]Ӡz^C4h'574+t1Sƈ? J9Sm1*2#[Sdq ǩm ":8C(h?92%a/O[%oi^;/?ND5٣Z$Zf[F^ctgwAي7N'Kqa`9}T# Qz3K6?u3O?$i٘/GQe2Gzn8qekbc4*8iɆs-y:P8 FZB > -_>㽑A^HAJa!4幞XS]l!dAƇ uh)p䅂G#+疝@Y~Gd X+l%8eH-;NFgW,,fl?TZ3$ ~nyP[]ps5`|/1fn$ʐҙ+43l`(|6偓À7p/Ո$< h V;I'o4X1GE!ueaxɊohd0d)T8kTރ2q&':ԧ)&mCPWW SZyg^˱.K7{&xQB $#JzdctWBdNZM*Bi23yV)Ó$.B tc 75K"tȷ\M_)/ݴ%bG!t՞A'..TN3oFEMwwl'=uoluAbv=9i7tS{Ol7:h??:.!سgOf[o5(=򑏌}w}t:=)#㮆]0J~ƮQ|ٟ۟Ss#ok.fɄ Gl+mFLr7́7Iڎ;>uko}[ޥ{M=hկns__ _ۿv޷iyOH{t@dàqc;\:nX799ƄmԾ$]Yb=ftc]`2=yvMWFw;mۏQMm:e#ߑv %$$3X7iQ<a蠎°.>4FUxE.L{g\<[f=U{nǠ;fqeَ']a#Y-?bkh4! =Kma3؟#${KbpS\w}h , 8A#q1x9sު${sې-XdAy é xjYr7+oxawzHˍF `0Fn<>vx};3/e07K.yA$pq3͈ !JE4y? f[^Sv,'ˁmaxOiKn4_7`P[D;.[j`l_X|&~598^~\#|O9FLj#0k6vxlͬNH`x9h)`/:=:NGJKbmKq1:*Zw^Rgڃ@kzqR |w3N0$#-ԇui'AG:^&L_.>c4`#IU3>FD^gcD ѡ?L^'ԭ혴wO]!iN;8t`ȨUd2[YXԁ~`'ꃌ'Bދ'\鳋!U)D58B:Ȁu+Q梬DH`P6WHu%uЈyMQ{j4H]Ufɘu]䕼lؗ)-V,ONzrv“N\T銎b9E6zQ<,6?)z(BC1C(mzYFep#W|L~+*lhE`f ^Ȧ~SrʃJC[R(Rn+W \$C=M/pxeB壡a-mYK:D^[5}b TfJ92h杛PKu˺M>mǴcb9j_6n+=zd{s~=On剆'>1e)Ifl+^hڵ&_]w׾[%3x#ΙŽ G??I:8(gr7CP {p=WߏbP #<~BDq~gxhs_=. フ{fگl瘹y 3LOy/_ܹ[FȠ `AR^q@nYPھ@;}r>4d:03 %w**,v>R.,'ILC9,S T*z\lzHr,y4|yt: &m5V&d@B),[dȨXMhE8(7/b; w2aq;k̥M>8HwӼԱ{Y[GC淃`P*b^VgC= C|[i_p#>[`<@99)89>`^a/RVpWSa̔jsi #6yu&r yN78.ro=/18&83bc#dw&Eg{i1l HDh4[^bJdmnx‘E6+GQA0IE]/핕!۠HDHx[Oʒ4fX@h<3l\g8rL#XyƋB*4RJHCE'^0.%eHwiyږO9C qքc',#0NC\t2d$'i"Yxt |q ,uKDfu~ M*}ў#E_y8nUxs( Oz . ʌ} ]2WxǑ@;oʝjGtiFAQOU=B;yuxYF"Hq\{P6~@0]rH΁kaYR`jMOm~ VyIjbhtדOpZSF5! qY8&Qeq`.2j=3*\+"gP|9`x$ago#pkR`V/@ߝ3ܢF ࡆ!ltJ ?=iI~H:p0ĭ)o/i: @#:8E&2Y퐙t3'H;ʑ88r 6*ޝF)Ɔ8N'4JW`ء_ZGM)uQbjO%A>*"ȋ(zo{*t9EzSN'”4PQ|8Xid:\6,3*fG|gi'ͳTezSi!WE”qXP.e,>j5!DW Gr~Dؘm)bA֌5 ɞzb[@at<]`/"ZKŗF2zmm IDAT3ʗuBg$mxQVS3s`zX/GOg>9$]S{8Y]rcУ3-.sCJ^n|ahg싣X/܆%SP8@`lWd@0+%\H; k;=a'&:%u{$r{u[:ƢOICq>ugze͟c_%C1 i*{]xo_ĦT, ]l-6s קQuܧjsӟtskǎmwwwE렻O|3kl,g^ۃJo0_y_p=W>Ѡ_vedY~e~Y~+f_G$ɚqN334h^٬5 lm/;2O2Qk6p]G2_g%# >Pl'#ª'zOtyyNqW= ՗NfuOMBjDMcvCX<sNXy呥K4\]g:|Tg+ϳ^[xt<џCpʳ1V]-#FhĄG=8PZ14Bt@(x|C=$|{iOx<0֍:,8 HiTISUYpMuj#e|Gʆ8g:e%)|Q3`)#1ۤGVLBY)9GY`mMG iLtp /^_>%}C]A[[ 1ÔM>chuy<9{,VILn9Vr9h]?]FaWU}# \NJ~Hh zو!DMFR zi, j(`xb,h4hrg`re f#?$2Yloc9O #F(E؂UBedg^&ғD/TBRR4d,7-\/.y ##ƕ,mA\ TUP ^MO˷x;뻁Zdޠ.d?uU"PjѐxuSr30B)& bgxt: o A:LkxM{`Syȇv"ҁHϊ`#;MၘM(w5{0'tI|C캼 C!m Ze#2 !6=Sϔ;ʤ Dv/ }yOƾN؛B)ş3i( Ac4&IX?$&];umdg=̗{U[Sݙ>*\ڻ.o/4*,!g:ȏ:R#Lrapso;Ohwl?>i_ko)XN<S[VkKj O(KwM ^p7܍0Jfx]gFqLOO3ZIuNf?O&0~8x.o'|=tgY7lpsAws]:{Oio,90:cO\o8bU]}p,|ea7 Z GblbU fRK t}[{ݮ&p}* ,=@Հ3r;7t<3yrQ8Xՙ% B33+)|f!-;9&7WJ P= &W;in:|=n~Xy`qg^5gyBhx$4R:ס~W$w7\B+<\epluTIxHf>c* lJ^6g'.ŶIKg%`q6;w;ͷ} _/w,,Ow6,2;uзp0>7pfYBg>Ү#'y/|_ \"|}ru7f`c|&`xo6CN?[=̳|'\u+cp(01#Ya#|㷲o ~`֡|]xT93KvH3N Ы"in7/g~7+gsc9!%[uFZx)GaՆ6۳E)'St`{o{qOP#/QXw/_ǽ<Ȍmΰ(e谝MfyupMN4ıt]?C~ u($CَOC1lP=#_̦֍ 0r½2fZYe9j7%9TAѨz!c r,Ks;ϟHΦ,2:2>u ͱ-TA <3:4h>,q: JWg⟉XqYӜ`dJ"N.APU*472ƹ:_HGXF"XnHFнިR"݀kro<=v MU28˲$4,#7B22JAM\m%10t\ iE0I'1"BBHrQ8iņz,~$Af>.9Mrs9*zћt]-%WrGZc d[FmX FXiaÏmxP<r*K'C#5knࢁ{I8+c*g2\i` "&\:X ǂ__ǖ|J"(ͪ eNzw: 2 K]#p ! -ac0> [} ~n{gA=FtDcdwxOwxæ>+C| _ K?0 7٥}>ryYU8x E-"VL;$/uo2ǟ vX.u]&q uёa ǘFDHgnV7ƥ!ʁm@A*eC}J+=!Z2b"~SP>EגE"K]Ӭa.q{ʀcpށ[3%mWxwbv,#K`6FYtK }B7MFMHTSF%~74R;V$tJ;FGtrI/hh.^E?2 !|M<࿴m%wv^.KK%jc[s${t8v}mol{[ԃ.Ư|͙x7e?5~ɁwUjƙ6Iv7A:NΙvM/ ;hG2ܩڥ1`6^k۬-|sC?^>m~KčT#ӳ#> ]flȧ I_!~ l%{.M_p OZkX`>'0Dd1뎓ꤏq.fA8RbyGta>D4x⒁׸k2lxBF 1;൬erU>Nc*{DŽ.7 Xf!F&\ggI #@\h8lsTxm:Rw5 kɗ[MYeVG9Y‘:x929)+8ʴv<Ε6,N+i7)뷡è7h րK=4ʐ1cjoZ[~ g:w7 GKBBg^ހ NXOB; ۷(ߡ<NFZŁfDCa S:"F-<ɓV8V8tt8\ozeMX$~NT`ƠHriOuN=b&ANGչU0oo :wos=Rlց#7!gD {2͡pF?ftĈkyk3A  k [Zi;1OApbfRx_ Jy2 b; 渪BI3zm`r/ VO0R][iX/fBw:鐛Cpo'ݮr tkrZ::/,Y3U{E ;L;]g&J:]oC05谟}GvkcO`T`I` 9WM|}l 5$/}6=,i] r w(7hY@8Kq_ؓ/[lۿ+&EkPGCs;v}t2W=߲9zb{ihU?;tZ3֍15}oWیQ~V-g Kgpo3oT,;tV gg L^mLj쒭:2vqתZd<]u'XYQHߟPڗ2M`}'AD`@fɱ <{ޢ/$ذج+@n>6q{~99_fpގ N{W/'x?n ^7'`_"!lW=AZW&Ox-&ܝ|o0^tmΤ09Xc{̻ l@r tH.=쨝=5ifGCjAZ5OP5Jɯ۾@&) IDAT9˯X&K؎|lW[؈!9իQFj5Bo Yۊ壝pmo6,>%\ w`LpW(Ϟq'.(= 0Nx'0l@O=̉~a p}{sRj2'mW0yksju= 6 `|=V` Ix.7YܢkDIYŠW0pe!pvA/Hmr g50!m2cpdYe-S4f;+OGF .ԙs`9dwwYg V͎<'OTp9Ӑg) +C-02.0xćoݎ G kr^^aA;Ixؘj=!< w"_}/mR|G77_v/}wVͿ9ion~=%7??w*=KWG훯ԗo~~xf?~_e7t',x-"jXuvUWu[}sW:ܚ<{،~im&[Gf'uzbsCo}\K-:YNz7tpMx f̹nmOr#ÀoLOp]ksJҔM&5]uB?C!:t,^ Įk[Cia>PrvAU+@}Tãòew FV3~W._7_z!^AHמ3 _Gm2z-\[׌*!̻6o7Nd}9{0?kh{ҳ>D: U`y6(Sd ~vfԟ>^z[`z kY'78Kaf^.vJO`~vQ}1KoGx?+<} U鄭OUD3Q7bQL]`%v]sl@NVz _tl UV]_qryI?i|JPE+"KPoLh'A6Gv20cRjo>!SkQI̮%adzַصWvy##ϟ+wб u·mt">r?ëﯯM 7l\\r˒ :B8:{Q9nMJ]$zڥ]*߮Ͱe bMs'$ߑc<ҭΟ0fwڞkcGkV,~'rk!MQ%%wm4R굡]@u v߄-S czq%x̱iqUtZXZy2CB'BŅ0__7C; aK , ?ڟ3d dCǔ%*ǫ dYIFgp1 SAEF9r+pzbWv@E;_СEJlFg.hФlxWJ9r˻`vtW~yW<$Ï>˂~Od)Lg`[ϟh]62pNGE'roɈ;J_$XU'nK*d䚭 L@#?@FSN|cs@yzB˅w.o;6ۏ7ͱ ѸhrVg0GQB9rmmȂ\_~'|_5v|mgUՕ?ڌo{MWJU W s>Vs3Pwf˽6סS:U9Wt =>߰.w 5 3ҷ6~_q4JKE։Mnfך2Vt}`.&13Yk}:,:)H$Pdo@M:k>MY9=}Ggf?m4ƃ(V́Y,  UX^rͶFңȿ̴ZbNh0P\Y>4#Fod7Hp9M' "e}>m2XV.^OJQZ 2ʈ#;?k7eaħO[^zN?~u,VϝS-8]ye}]|{yO`çWzmg]h3ܷ.`#[:pcsOq󣭸Q7PUoigE'܂e+RH~M^GYJt0׏q߫ۥ)>GױI̊d4fvt 6XߖʒM<q='աMupa3}³ Ѯk|e~@Uo z>$zV3 ;<@Izd?.8u݅&m KY< }T,=B[z&0:H }A>Aq` e~.w E=Ds4 g&rJ(tb~n00wY'y׌O>oZ,\w:`G[jwDV{̈dw ¾Q{咽k')E72nKġR|8э:%ÂMٶVdՔ('?7u%>W_O/РXt"H-U@0{?QzůzB zWc/]{a$tYz%z'~9x5I[@=}r|!oh Ե:Me܏CBF Gɛ]% _ӝn?}ujɯRMUcy\m)!0F{ѯ>s6=$=ċU(߀K Xowni W;?onn;WzܟL?o/_/{Ûӛ?~xsC_^/%o]U:#) tLZӥ V9W%|OuR @?bQoמ9_0|>:=Xg)zőUa"-ym:Cu=1sm 6w'_=XGux{ | M8aO^6/n~ww|Rw:{h/9dě P7oA|i*|ŁlӲ%8:z&ٗ 2s㲂J񡚜Q͏BGgcxd'*`srYiȞO2ޞԾ~lH\RCN5_tڌNovu/e_ykm[,f7_|-GuMV.ykH(=ߠ@4-Ms٫ z xLle=Fl,ns/څ7?Rm+n^="W ܁x2y ՋRy>fGf+#8W na@a˕\_dtx6 @?:(p+z)e~L8U`{aoPCy7XR}O+voc`jxʥ'GS6gifKJo_)NA"ZÝ̶9[u'?dDd1H̀Y>{#V >o+f12>vhh^'^lM;Z U|TϙNcổgKmmqygz \)AtP~|KmXYwet Z Vawkg;l28u8ll]0_T:!]oyƁoVdCX NMjhRcf춧f #٧g7ܑ܌ >ºW;)_ |lgh9~WAlj+Gp-iK?G=DN@8]V992:ت,FEAeQzC{5!e9jdJ.guf\_ ~K^ O?y^>-s 8e͟]-#پ,|YeM }H ,4Jw^}1 Ʈ}:n3K[P.W1xoxƶ~C?Z/?43z/UJ<E:^t5z D>X/2>AvS>SyÞ;(Eɑm][ʨǩ|yɬ Öu]W88 xA2pN~<*'\{ Q^8_yrzSZ u ̑O*\{bkug&V=:@f'ʮʕn[…9`?Y }/ط??~ɯ|k_oNp*Û~7}{ 7`O{WoO ,^J T7+a:~@SKīn/@3+ߠ#]O#$2P0_RκON|N~Vv>n8@ (٫3- å\$ (mc0{7ߊ׏V~O׿+ Ax.t+Ъ'zs_[f -Y Cg8`+(}q:-M>7<*g.ov| n>{A.(]E3F΀K2l^Ig KSά}Akdf:Q?H/3<~>Hc1|A6*c4n)?y+Q0`Ly} 4X686'*m#.6]=~$BWonw impF~ą7(S@ do^I^ݐ-Q/I`Ñ|֖Hz^|3g/OzvXʐ@Y}|A#e`@bO v0N'1X*v`+آEmkxcu{-:e @B``2-_Ad E`, UG~g~r}T0&jVn6 4ќwǺ+8emi/ίׅ_^P~Koyһ:RL| p]ǵgZCA,YLl4_bdb4QU LGzf/;SSV$8/7Y_// C4tۯU g{A)qiߩ<2zߡ 7|fk^:mYMh!$tm]H hBWܲ| v?N$>瓵4첃t\t/X ȿ*`{?Avn>"ϼ5}7_zևz=f 03'^NY:pn7ޟ7ztr{u+k%葎s :֑|q~R>k^6ۭu?}}m:׏jC-|s`o 曺KG[ȏ&-fdᰜm np,4=K |rW |E#=%o=H/8]Ga2<5hA m;kn|~ w^@@@Ϲ/]A]=oIͦw/l&=O0"#:-%X2,zYtA%ldW tTNgZ@w}wNX,5땊\DA7\lCJ':)ΛwnhET{A}Ƿ0; ͮct.E. @qeqn>Om-5ýSibA^AQMޫW]Gf ގZ>9b)~?JUnzuesAy@@W^I蹼tAČV`OP'&d؈a猰+ ?;}dϲ ț[.F+~۫DNk'旟Jgg{5ku.z|2i0]_R?ZqE!V1$[y#=}9?=:ӜrM1AۧѻY:=\zǝs\S?^p_ HL (Au»;)d 3[ |O͛'w~gh˟#wZ[-LU] ÷ G(OHg+CBvc|L%!y`hʢk]2H0xNWL-Y IDAT2xou#}ݑLf{zx'C`kc$xh J.8AMg=j0*"n}dvR>o_ir]d)kF~Cd(ϡؗ{ww/C{7:IFGyQM,Сc RomNf{ʳ{ht4:,jo^ :|g.ppEgu49of[@S.0s|MŝiNS)Z׹ n]xk!`Pi,.xtNodJ{dcz`[N$?}ll b(ۋ.D̲bB++{A@U<_epd֡?lreN8}m w ڄv=؅,6P8{UaڏjvD wC!SRnUwmבהԶHC dZ}9HvTd.EĻAǻYm3kMpU|U}ч/ٮD|\ǞJ{ 7>.яE2y7U_pجo6 q0[3W=>ɬoʼ[goo۠'cetxdMEțVHX Rf/ D_ao98a` !V @3 aXoH$(<  Yp̻3cnTko/m_ ҖUo0Z4̻{"Ceq킴nKZ ތcUnǠJW޽ξ\* =x!#eV`gKDJ_u0aZב#\.H+rp(%Yl52j +3H^*(`*6@`CD*Xt^z_S!u)lL`ݥ\mOˑ~lmrږh"{z^`WaNGwO?+lQ⵴B| 4}{WN^{_.0༎Z>x&:= #W.Bl l|[GkoЀݫ10J>t?_JY [7:LKw tA3y`Gt^˾7U"_t#3 ףqʷDomFv_HGlR/%K@Z@o3髻VZ'< :7:îm>yt6 8ndgJn+Kà\폧muhawzF5= jES3b~nڏCS3&W"bIpzۈ3Kk6OA쬬?}|d|Ps רϲ0ȇwیF@ yStaƧ?8s Veeg/<^tü t!Fn>~SU9ݗO@v;A&_Ռko9ɨW\ikp5}Ny\@F1OhʠO}6zX\1yUsOpOg^y@2xrHx#ZK#h8\ frOs4Xفή1h1h#gx΃o{ri].`^lնl x·@|,579 HV&J_#=yv)Gn{5aw vßkەM[?$hY2;>9s?w25ö9pX޿@WVr3\}g; JGV+ ]4C0\'Nz|o0x&&#  r&M^o=Y+wNp<牟Q^^/%R?5Y`f0~-n"=k4:^e_@u_muߌj:>:nm;dVXno]|5NwP]:e͋r]3" ^dw7/ 1 7t":'頖n\MWlڦJ\xl]]R$lv[%ŝ8o?:}]t}s*ٮxw@^"w[2f3oly=TWgw2 f>å}qD}CZG?'߼zpZ TXs'!p7c,D4Dǽf$K?d)Lw8v*P{Pޭ<ֶNQ> :8 ,`@w7ZE,٨m_0%fU713Nl(7X'.:!۷^Y}Ʉtο}5ᙍG[쯠 oo}&'ؕXt]kKc~_`kl3kޠVuܨ(pn|AÂ˭(V@Kc`e|8⑙Hy:{J/ b,p8``G~ z#>T#JK[6ڻ)[V <~]Ye/23n;/*f%ARÖ/~.|m龜z0\(X5G[~:?oB恈>"C=b4M,/^~%eWȍӻ?[a\QJd21hP AXQQ}4#c pes8[QFi`k:lo5sb@`ye3tTz8qW=JSrpKk19 6Qkх t uIt ʀrxݝ_8Ow{]00vl)9z1G;2''R`Am(A;_Cn|+8o =GiX,O}ܲokx`j7~-R/%CI`vn!Y';޿~͊!:ꯎ_nSzAĞo+Ay'XS؇l CH(:ް}:eښJRg_iWߚI_ʌBVS'>~A ӪŕUb4yƓY \U'*@)/ l(iѴg7oaK+w@:ޖ 2h?M~KT7|2r2!^/h)7|!n%E%ډ}_>7N:wKɥf>QzRKa]#4X0gd8?v}WCSO$f :xN^<=73\o&ڳd89VMw:I٨?lF9inAW[.u=ΜX!=4$h7_БPaDCp A<9Bj tEY]>ͦ{يk]‡S\&ekǑ:g|dA~[ػBd6}V 9Q&,xZ;nEo拾ϖ(Dg3ī4#Ѵ&>9o]7p<U t>uulV>^_,vy:b}>{/? [aM63Q:~ʳAg:*>h'+'A̋}DeL6'3Y>uAXD|1n` , y^YP7H}d߂Ј>C_}VJi UyK7;ns•^I |=/}AW|"g!R{$e Wagn!ތ@L2 s!-Kp"}páiz« V\^̊;L;=hm.c@`_X_=aUCX?7y b/:{ٿz h\r`4W^>xn᏿Eg pp3u #]ڿʴ-`W}\G_yOGAA0fcԓ2UjX Ay=:ѻF1N&lzvqJ.N(-z#.0e [f'xz)% [/,7wXڷY{ñ5w}&:wl>XyZ%tt4+sԑ}?:[fwms%- {H-a߮\|şp5z{۠yi=,?߾MRJG>Izk$AUfFn3ֽl%u?>;`Ş9=*7Q27o? BC`t;-G}=_h*2ngF4yQ fˉnK ^ѻQD9Uϕj+Zvb7 F\'b,3h@HutXeXn'\jK*]і`ՋUVC8KFFِd<EGWpdkV֭t3,Lg7@+d:;J~`?pp<.8챌]PxN_I|ѱ *iL0 OւzN+|}A=Lq ?#wZ4J.؀+'{,  Y%,'j*>gL5|1ٹNο6N_#EPxj/f?Z*@_ճWW ZmE75H8E`wGp:(3NG`ۊ'> {&'[[] {w|=(6^Җd Ҽ5`<{lh|6,>!z,p T咅*蕧GMLdAop%[SzǗ;Zߗ`?"0qڜK \1ѵ%7>fNhM+β#DHb?leXG=mL{+R_yo6:S%+rI \zp# ",Hp͆+i?j :4l ϭ8pqY?[y4[w *-3.dz^*V3'(Y0>q ~S=kK @ Yo{_:Oy_gxPΠ@2`8Ab`Z.^p0ՠ91ϫLWOe c4>ςɳ+lӊnn6x:Be廇=Mzx8@={r+^gHSxgb>fp;p{6= .]igH2]yvT7޽>dV9?,;|]głAlS,LE6w5hrhO]&3'Z or'fS֯}i+o'Le@|c|=xeAkT~67:Vj׭+e~^J:yR]ngzϝO[nxqo{k<to.b8~|YΏ^a2:{xubDA+`f{P#~CR@o f!}m<ّ:k+t(]Y tI=~-6^r!'i0$Lۂnݶx\u$ڂ"J IDAT) 6^L#3xO{#`2gdj~#]m>NN̋)y lsXdl;NF٬`38=ôߞb0p* P{ߵs#xA; zlJ@jpeT>HZm(TS{oW`׺/7b]D ;~t^d .qϫ$kG͗T',ym+^JʖiNl's9Ԋ;jK=VK܎`}Y}|2g9<'bh Ь1:c S{Bm439*/.ewJ2Hسo;$a+9NH\?h|@pJ !dx"тR%:*7@FVtMf``Cwi /L۝{e%3',2wCDz/W{.J/uXP[LD\}:.rwD 9B5qd7y?{T'06~b[ >&^mCs>{+@ϟmO̐{,ɋA_{$^ ;X}~#`$`l,rL gx Au j2G7PYy4|(l:Gľ:/`z)WĪjUuXcbUf廙k *c@vov-[uf,E/=t[ۥ;2P϶EnNVhuT{I< ņ ݲ:6''AcLw8_pU,|Nm4,]:xW((^@oK>O[9E䰀|[,7u~ٳC6d?#ϖDfp1Њ } )n\hƧtȦ#K`k&mz:VP5h,oNފOhs-1G2̯dY2ss+^lK8?goIw#›ԽFr5~8r# wojCKSjnl 'eTdff]8)vS`"ؙ];yYTqI"CEO4SW~{b<}U{Ku׷ͣW}i{]Wױ> V]>&Cg%Ϛ[^o/b`>F_Њ&6@]F[m8} bE̳l}iΏXޟ@\ ; 9M\IfL<7ѳ/VKc?DgGbPO]!lU/QV)sM=^_ici OgeNǗ~>.Ah :3\ћ91g&^ѷq68kTE~'h菻s@^>$7`u>oPVܵ B9SQw{ukΊ vث1 )`۫q` 49u(1cB'pεyҹ +0W9KWyBpew~(e|̯{+vqWw@򅯑?_p|F:8%{K}䞼} xՍl@<Qi BtFH,|;`ON#[] .:2 <|S-^JN*gjV>̎ ~څ|h:._+{5ߊhW Kgj.P6fQu3p5 2Иu֩,61?WhlnF綴dē뭖j oO 鮯} V 3֟r=V1Yxz" > yg+_`<\  ʉ[;!y?\\U&ȣSKE,e<p@X2W<fo~`*ZOHV%HjtVk &/}^a`׋yl^k7o0$"\hgیniC^WG4@qKtNi yOgeL.z:y^o~W*\7V9#ڳiӊ<-W3W8tҬ*a'/#M,躼'YYA:B2һh>lzU^u]m< p%g[ûzUvXƏ34T`&d}%>rE [#D9׃KHdYƭ!#u_'e6upe"&s,.BxiO]ߦ<߇s6 w|pHd8_ XAC6:?|ۿd XΛȆY烶N x;~}OeOZmOPa/uC铞o֟竬Hy VDz:}O}~7g2'l\@Kf%߮g9 O+\:{yANok3qwx }*(TP(Ʊ<%,(˲W/ D˓<,A^e)l't5Fel=(M`~%tVQ3Y m;ę 7ܷ@BPk#CNF^^1zi , |Dryˊvp#"[Jl r g066^ ,u_daٌ!*w3K>$d&zZ3"B3a{m2$z.2A$dչoy?9fG9!;_W n3ХBuUsB;J'2Сbhe`16p$\nZYpll ȡ Xmh<2B[Au>ߺp'2b?:~tR(;z)%YlyӆEkX")H1_zvm &3[5Y`sJ+Df+6xŁjfK&YWȨCy|v>dl[߼nosI7~~|lbi<ެGMZALw>z`^@OŷJw1`]l}о v8gUƥΑo<~չ@|2uuOV q-"H6oJ18"\_兪)y<&1@DsK1+b3#SzFWf2D"=b'p /D7F-`Gγ1=(hàoו/W WUQH >MƑB%ak g/rl9sQ$FBz)1JFd;fO5T=?9yJ6c;Ny=*\XIp 8,.z+=Dg&ߣ~ߡ}6cˏ* Dp72q>m#r;ڛPc cKOwtQ3a+3Fԍg <9 11]vG×M32Y(~4׺ї|nƞ{9>iIG/`W~29/.{~6w泶jA!n  Gų.+~שwY1ӯ2ܸݒ2ov26\#㳥I$O˾# O -x$hyAy1 w:}[%H0p传9sq9;<Es<ڿlʃsqkܞjC6g~m%._d[fDt폂=Vt^>eGYu?k[U逭nCaO ԟ|pz1kA.6sh_WZ|%[BL@X~VqBH:<bN}G'8Vgi}yΟ:r۔ȍ\7V 9GB7}%7 5‹q?nÇћϾPr%x'Ӿ<}G3»W]pbe%JByʟ/=DfsFW(V0\rXC|Y^x- ٹa@ߕgAeNy`~3=mG{w[-wȦ403_rYa|v> oߡiGNÉqh>U*$|{tCEZENPO[,B۱1y8'4SoTa,L Ww2SlԵяC/W&0虃I?ƃ(3{ 18cUʮsy2܃i0܏JzAoxGp^ާ9F<'K" p>kήt{v7koԥ`tYq3YLjk?/u IËm=#Jtݞݱ1$^8^3@}^{cl[u_[oP_{)$07?:U\_* [bM=V |e)N5߬lUGs5YBf~'UctT#'`sgXЕgY`o +/h ^7eΧ:- x9/߀B8m!Ca`[G=qo8?_5zmYKc|5[S{r٧?;m ֗ Lm}N3ǷڟO ʿ, y\^Hp3^kF-EF !jqm C=. * P3 ˀ 0s!!l$9[˾aﳛ゚'5D`{E?A_@i?{ z ~+pk$/ H@0ӗZw<_Lt{k IMfx} J;O >Utעbs2k<}W=n;a&2šl \2d0[ϳ.)'!)WPLmUl\YT> ofY+ \~h|V@ %e[B'O'_h= 7@ll~qZ g5puS`#cLw߻<"ْA I>~D]iltt{+cWY`Js.DeCvN~{pe3I=}~dE߮@#CR6k[M6fj+cBWRh]_Fck r>n+\QS$i.\]1ܺӻs><~Ks;Gp4/y_p$ r'A㏿ae b,?3g'/+sdY iRuZPܩx~r0<{y*Ls@2Eȸ&/t]A?FRPlLt3` 1^{:*dKhqoǶ]`6B+__Oܼ ?K/?gn7WJl_5/s.O۫*#u.u~ALOPߠg:Ӗ'x /ݭ3l gGa)APsk $jq>?esV{;Q=f3LpF9O}aƩh] [\Ge߂P4ZN (ėgMo?W$Z[}VO?/΢3 -R=|2>7Ҁ XΧ<yazLy߈&l>(+Q8)>>+CT?3O;#Sol$<_ -p_p] Vl !x6\sO?l,X*^|N.ό.XΎrCX'ELs\'4>)hrrj˂=:mzÍB̹`p=z9{- _Y=Qf܇ݐ>ݠVC /,?*u`Y0\i+4McW2+G"ZxqMmf͸CcYEB#\WoWŝ͌ h%5!^q tv1P_5FT.d_PQcx72X`o+ I^rdx :TN !¯tp6Wc hˊ͖NjdwnNO YFvM0-xG*慷2S+tdQ4{a| זHwU:<24pr]pc|Z& >\u4< \s(z Ǯ}^w&9`̬%/ȑR`TkdVlb@.լK F _wy%7R᭮y:~ Ӌ¦z(o}=cB''iE@CU _vѽ2/]WK3&V~}xvuƇrݟLt;x?hfӕ)KFX89dW 7.l88Ppp!zy+`lG*RoM/ ,/oNo>|2{7??_ѣG7o͟Sտ^|)$ UTSߎ<+҂u@TxVA@.=g}ޟu篪kzPTPb4ƨQc$vHb: l扆(j4D#ig?p:U]C_u;"}_Z;Z5]^W>ݛlܲ e#נ]QO~b.NPxc+x^@u"R` Pj&_uo{L+b$7<׹o |{8+PgI0`Xo',_:|t 8<[j={W$ f-@)m|Y:;X0} Z ԑv塇hs3e`om'ٗ^yp&;h)5|k61+(j@+guF[ w=s:4ox spn}6Z@}8:#J'Kڹ\;oDt7^V8i&W8]li5Lw7r$U2A:Ǻ7f< z fK >%vl͇dU*{tx˶^Pg _GntWf/ p[A>E|gWGZ{Yf۷& ~0_UڷW7 sQ&ءA*\iĬ$6Gpgyu}Iw; ?<UF@W}+7g?z#p}3'_˻4|l /5 {|X\FFwy-3Y ߩ_6e\>hӿ)yj 6FVI;vPd okQ77PI=kV WߕK}:Ɨr|zskWvfMDlPhix6ӏh 2Kp w3n3r10pvգ`HQp;_: .X-8gE{z0f0`yVLqmKAq~7~ҍd<]f27H@ VyjXQ޾c{_$ M0 tϒg 뢫+Rl4눦 |~ﵗ.{ p{yl_893L- hS؁y$d}<ά /sYbt1R:Bvi'^B"%3~rҗz:0xM; /9n{@Ob%v| DћBK1'SVkOՓ,xI+c|XNE/wdށ/nVxS>,MyxЇ/8u\s.-C3rAWl_񗌂{=ahu%GZ>r YM<5Nf+ ?T_J/#I`59$p#\e1FHD0]_)?|W|Eoo_g,4?'f^~7?g7{ޓ`f毪L[7{׽eWUۓ1\إκWwtjVf$CU|+U}yzO|d):4[uA!BGu-5sHp𿕏x-xzMu9ׁ,Y|`?o*0LYg"?2[MTo#xѬrW[frH~Ane !Q^+Ǯ|/ޛsAP nAg$'˄A~=W8buhm{ؽh p#y}&uC+g41ڬ(_hf,/ξyyn0Uy=)}@Lps + 5# sA5k/ < L}='OP)k/x`Y?jZ὇Ξ (nͯ1bNd!y>SjǛOE@_Zr#"`hQO uzI?:8z92N.zJ dM1ʷGoؠqoݔgf޷L3ggvBGqbG_?^^./>9uj׷6`s3NYMsK<O]o0+W4ta:-π߁l.=V^WrIn`a^+w[-YQcs"=>,c;;'Aꇨi{ڤ>@i:fbuu>Ny7OLNl: OԹ\2wiq+<_3kzwyK4Ro~3+fVo,%DAkuU1Z+p:qU`ӱw /3ЌF‚t{.С^P: MX~2 >=&*ܬpYG'1XNu`y:D^ny>z(.ܹz]AOV*gf⯧ujk>+DڹG g~*`[K,F[ 뵔k`E(&!: Cؐf}.开{ `珽zN姳*2;=p_8G#O7rY\XDB_!x|7%Gk#~.lp8iQf#H45t_OYt-2X͂_Ixu-83=;Ox#WpTp[=`ЌAF\кe*߿Ηz[Bmip?2[kťο.=dC{̎iJ`8a ߍoVgPw肀`$8'cp#Yݮ|U5ۛ^ >ҕ N| `=rWU+!5ioc8{Xv§.\Q[V3f~Uɨ>_wv$Tzrs:_7[./z~諾3hf#p 7*%qTp)l0a¦4t\mYKVaG`H ۿc#-Ăe,Gu@sӣtNlc">7۞y4'5Joˈ+۟/ؾr]П"VLM@AYj+!/?$bM^Ð#ģ:)t^wP.҃PUxe;O}0y/<8[y`r5; S@zs|{}^V(9?$;^7ȆeJf}տ4@1}Hxϒ+pd >x'n Q |y1FF:'fwQ0>͓O>_ ~ANB;p8|7_E_thm˿r+ {7-rd0`@= +As\:U]N:UNР.[שNk D: }N&w>ޕaw+:%gN6FcŬLx3a ,x>yi'wNd0Ja]˙ju?5e:gj~6[qf6l(->ځ χgefSg=KZ~wm!ٟ_POWQ ݨ[p3cA[.$T$ɤ:ͶKy&>-'omxҶ^|f44}yA>o8;uxx'nQ(O 3{(=ओm>it /jЭJiVvgXᲭf]QKӪղ b> ӹXZBPp9E6ߩ^NdQ}{+ VAGƌ#;Ęz2~xXYMvk5XLFʂ@ BEFyҀpIˈ)+hGKs{7;x k>ZV:+`^~J !5hrKxcEOӵGO&MU?08LRlfwe2Gh|W L-x ʑl>cEK"px=ЈWGԏPWn+EVO6 /=oOvyӪ6w*~f |'߸yW=|bxW9Lvy3Ղ}Xޏv{[,b.lO~^+\3G&uB9Y+/KL#muSAU jIu-9܍Fo!mKD+R>TOlӛ:X0GJvWFU Jٞ! {ahs?@7Qy6^'7n;g!y 9dVՠ3\4yc:>l-:1Ym:} mJʂנ;z׿G>l`w @3>;, ▮ A;>#V!#V`_ovTJwn{m]%D>&w jN s$`` _GW;U2ЙOq9ON`BzA@a}F=G#BTHS^z1y/ \ͩbrK)G'!c`X#.xf9Ks@2+dPfx/99σ!+"`[f]}ct0}o R}8Ù,=2)}7kLh>m0pMUЂ3zk|(xVڧ>:{ECdnjJ^_ xD}#@Ko,qXנbx'{.2{3 A9%5;9oQt+`[{ ܿ@{3c+6rkctְ[b?l|Io *we{q[;Ȕ݌w X1P˾n$_!|ɗ|_u W_1rܡ[rY_K~^k~ͯnՁ 7ƛ}cg ?͝6O?uW}А.\ͻ=SXKoˡWk^01FbTXP%X 7ܭ3)𼗿1[Ё`K+h{qpG'FmLk>UP$t,ВʯTGG[3:D?UGvSo9ncK| B:uuo{_lkdg_0+D0=g>{Zgiei 2Nɫ#m֭$K=٬%șXחxG6ޒLņzB'[^.Y!A|!x&LjG-锗2yF^-ToP ߌVf.γQEtY>̝I K[l3 bg)INw=:Z^!\ z7Tz:7c}[-:rrHpܲf^o%sA4 ޼yp8C N["\o+VU y5 8/`_J|EV=ǬY Qt^+zG|ћz BY%HnVM? ^G>A둺/!k`] 7/'Ov|ܧckQ~ [4T)do s xNz0H9 DKmI \&i<_rՀ>S~go4S:;ʆ4ϛ:;׳@OSs>~-H/D-9TR*0ȝ,N=„`/mqv.wxgJ4[v-Kv7##"\\  &9WZnmfaِ`12e܇ # I"8 H_KI?D]i-O:w% 0S)18@w\YmA֣E,r; 0B7\:-8'Z7&Kl:4=#xno g`23,0A>xC>F|s,lOM.WZpCstthŸAkDzUV>a?XPO fN͸_dOߧfS:#cwtqi=[կɒ㠿pōglT]##?'ܗ˲.{1MFՍt+/A<9SU{ e⍗ aWl~Yy5udVY2CZ2e$Mշ@9uBlKɥ.`ߪLKQbYB~(.aj f.Bw*l} ګJ3ۏ'%!!+5 n;CB1Wd3<8_{Vt @Vn;cFHUcĻ3t0-#_wOx?vE}CMx}da'D Dl:9r;KZ-|x)tu| {Ay/0{7#(gFqXMJe4V|yA ӥI,[޹`ѷ%c?R?79B|0tK{:'T2k$9[M w ޥK+?I7f+<] lӣX% NgYTɬy-j=!߂۫>pFzX(> QU"Q< Au#~VT1Ҳpth{rx+-lSvBz݂_Cu %gf '^&*'w0X .?+CaBi_3_O i*|ɧ; nZ ^Jo4=M~cyҍft(>kֳdTKehOm;2IN^Ҋ䋆8=Vʘ>#/"ݝtu\ mx X@wˣ)iÎD2ե.2q˭d+)†д׬`9G} a^h[^4곷 l_gOW^y2|٫_k Ҿ{w+_:roqys[|#R7p}fE}o!v oÁϾ{ @WW#W~6~T~/uW'Q23VC'h-~r uR:'y>xl{ujA5@UށI-+mИy|;dN9eZŮoAGGTWp/0Z[:йhwٞ`{HQ!޻ `B :w[yZvSyJBmˀuPuo!{AnA|x ֹ~3}?ZXˀj?xxƂ T:EʻjF⧛f['zÄ`M mRzt ,d:vVy;3XH[GOl_k)|KgxՁJl>x+, 1CoRfvQG{t>Y0F| k@X6 9Ԓ-f^O TwmSERw  ~ ucA㹯o뼢| H-fܵ_~Փ&b6 N䅾կ|ã{=W^uV϶nmʼn~ ~'z3s;x2L6^_壼)ëQ_0_!-Y{ 1Tx<\a~,.7xOsAq`Kd09Jwҝ-v? B8XzƸiE$L5a\i (xfnJ[\Nc_A\x-4\Ȳ-G84XII mڒ3unB+?L-WS(f*%VdkW=?AD53Ut!]siu\h'<Җ]lAy?_w'9N E ]Ε>p l#>/3㺙>>!n O|4eo]#4X1lx|͒i'>iKUNgcu3娃aUnrB21|HAqܾ?[ t۽f?[4O~ag^zŤgiw\dR?A=ڊ uwF ЦWpmعMD&ڊjϊԩ7!?{l>@x ̲w4jv]8gy߹i^IGZwZv<ou;6ʒ|㝷hv+yNjM)Ź.B*m> ZQ7+BpBYZْK=;)sEik/]?l !JןcRx Jj~tgkO2obírD89@#DlWC zɡ>{d>|f)5AפX^26ἫٙmɄ`蛭:!FX =d`+vQsld7T2(h~랁MON.pl+t͎̎n[ƛ{f4GᝀK{#Rq%$x L`N *!؏.Jwѳ`_]އi?DgnƆk tʖƀؤ {t w` 4EU P]iUSt8.RɈmW^OqeHF&y޵ kAc9 ,0Ff )}Zsy TH ޕE6,KK5 IDAT/y0Vs;_Kfq7pl%cLVwa+l]߂]]m)l &]mH7PY{ෝ!T>F9\98"<4/h `T.O']10l(q-#>Gf*']Y^:p `,Ao쿛$FL^D 2eKFO3Y#q-k['>O&쪧T`s[r׺Ɠm,vŋz+wx:;je@ku,]@ɀ[R}wvj<.n'y7uv>.y7X~/E_7 : ]"}8_|cu7G]~oo'o_V&ЗA ^/[K_Q-uO^mկnIoP`/jS}rȊ%sq|ww$s P'!k4e*`>cH_) Ket\veq`N~Yh <~:_$ҡ?!O }/ f}=pA/E?W7r\^<@6^#I& eTߣ{-eO.y!f߁G1^+V.KwU5gBQ';m3o^l+uhrg] z?f7O.gNGz~h970N[ ^ `p'?>ٲ-Km::;p <]}EC'6SgԧWZQCҧCl.rcb;[zvElӡ_sZ~K!10`7O;0*4v63)W`Yp;m3 /|Nt>Rr\ &We/^yo6&R0?/r\5c(ˬNe`(keł~@wNs4UѵMy<$5Ax́dǀ8)sOV>l8- s iZ`9{?Z& hM6T!J! GFAKW4]C^hc;3q_3cÕ>z'm–dFFd1e/r_BN*g2v=Y9S&abpۈeHl $}'nV7_d|nuܯzi^c|wrKot =l'[]r}"<3{ƎЙ jl>yB(X5KWV ذ0ڻۏ֐snggG罙#~?;;nտW -1^_Kfg}{^(P\fͿy ˾l-7nkvw7Q0o B97(Aqo_1C=jȧL~Ilrր [gM=p~Vh[ *)l !I-؊1_/Gx&CڃWj<ت~PV0?E')}-(!dԭ&͇k[H\sGXNZ[D;̠0KkVo X{QnZq G <T/Y~ĺ"ZΙc(4{u;X33 M Fq  > +.`ReV..tqvO#IdtxFe(PVDO9͢^ ag9SɘW |%FxfIoxԴRзcFѣE3Y1JS>>"b_3tx!*Xw٨rȗ_F}7{*2AU",`*L%\lg/99= W9[=>@lhUOh 3 jl0Mtϲ'v %MEo*IfOn{hDpK9E:׈ψ*X#+2N}d`sm(|>ǎz:4چhTG܏ɒ`so $/G_;(ϲc~}k|,13z~@𥳐7T:#F~nMGJ;|u:9.nK͆,GevU),Y`vP)Q>:_J/Hi:FDG o =w _it*5WO͔=VgҌ6,x!3 *;`.f5Bt8ݲSrY^0wo/73VrעL]ls@]_M@c8`W?l3.كpg{ʔ2yC|Y:D/3\.0pEK^xK0OtѭY`ckN{\fXFҺt\d.oF^ M "bOНuF2+וNAyߝUyoߑOW6.TЗ (/]lrg:Tل.v|ոʁ@p±%~h@ǩoy.'?h# ߒI XrS&?ҿs<2m=+c>KwDLܥ.>jky6?CnͰ/uĚI(&m$:5f݋MUֈO؀Q|Fl)'?z}LV,?2{_xK* %-_&W-"T+oaݛ=h98V+Nh.!9 ^K%+ȏU' 6"wzYh%M^ " 0?xgZeMVV3I%SRNmWfy"4KMWE@~G_He5ajRR3eWcd?UIC@OU8oVwA'_^>qUZ3F|ySAR 􏡝{\f|,xPVN#P9r&++ fѕJ dN䤵w;)Ͱ3'"k#S*oQd"ldÄor}zvAx˨Z6MΫ4ZSiCjcK£uV:/2kt_ːp˩&JF #?Ɉ ''̕ NT^<Ձ"+\mqr*`V~_ͱcO꾒'{Ndvj~7(?.Vj{b2n&TB~ A QX6zXv#m h C>??uOP &FM#TbOMIi=lF4%?|_~y3H`I}m [W:?UÞY_n_O8ܫ:@ s/'3hPua zߵhYpR4of?C8(IF#/@ځh>4]^סTdD_9>+`ea٬/ex~γny ^N~{"}K,y- /]χwp-m) C~Ҳ YdNߌn2U,{/SmY|0(ep] l{8:*g;'ኊɕnk'nbQS[Z+7۫fܒ+B' \oFWXr|׽'o:s!3ٸo-՟ (\p`}LfVHr:8ԓ0c#G#q:U9 W# vX #MK|fsշRD&;ڏ!L|LiF~FN[օ~$83̲Aeot5 \omh{E( -'F t ܣ+w1G /8GZ{YO܃g򨼂3O.>MG-o]3Pُl=v:tD .i.5oPނ,Hɥ)ds{.~!*S:Nwz'3ó9v @7(VMd޷'tٷmC͸.\+p(St }FlP3Q^ . `ʣtMFEwii mWƜ7D?[z65t@g$(v4wQJC%S?_~qq}ɗ|ɖotւooz{쯃o `"W|l`FbZ "" gEQoÙٰ^O9ܧ֐'kѾ[FvAb[;]Ho:m;XOU Ouڻwd/T~&@ӣ nWw:ziZ k'N/_j{@=lh ڂР6͎,ql^Lu N~cKl6 ,Pn%Iy{`ӟ !o/;/޸uեɩdo^gd}` ss zՁc ? klfY,A3}kJR|'AWYrsɾ˶T .d0t[U?^_P/Q?.ܑta6oK{kXBc3 d kuc#NgN|̭B[ձ]&#gO=79?!nlW۬H2^|Gz$|OOߐ%{m xf˳KtOɛz3bʿh[}ވAdNxQ4f=7G 7VMx`>sha gεmy٫KӻK<Я5t(m3Z% Bps0Q-og }YSY9\9~0}_3kPb c/81b2Y1tlj he5{сKe.EEk_Y,%HJMWaR1SoY{^+,u;;ӹУIp­Ŏi+}p*T>:gԲzЃgz I6WYy-thF׹$Lhkd8ǣoer? ?T+t{6u8fWg_A+V1 zlLrmIVCY'10:DlA}?8$k˾ƒ~j7,HHN¿;mx苾$OkUʉ~WGՑo>UQ.auuKfDT*לld$HTm%,u IDATB-lPoK'鴋:f(/`ٍgLJX$bb&&ts|~UEmn^^32ghsWA5Sd~R۾(K/Dym[zmɃWсGP{9կDʐ8k Z'~vboD<*o9h? ׳8Ǒ )ZL_`A]#`rd/+|~yXd$/ G/\{Fg@MY@9}t19ZYKCÛV"++ Wvģ L7E٣[$cѻ*ة 6˹&uJzwAg;o>Ėd [; ]WNl`ݰX;W4 QWlgk 嬠:z Df>[,zaRZ# W g@`.,}[|VPCli.eGh69) !ov69\Ǎ/x"{K֫w퇲]:*ʮQtEB*ږS}]uŒ)P Tr5]K'b86oy}߻V˒nS $-mc +Mg[n+;dڷ5ckJe?W#8Z&[zKw(e=#eV5,_ ǘ}ϕQp za3`o\B償rXQZ^cph5aFVh@SR-/x߸3/rH,((MfI>s?tB`Wlץ,*xm/̎L l0&^;xzpg!6|k[nUOH+?=`+-g99f.[Z*9iGVUr'_^fs&3lz_P~O_u]gG9 hW@^e_{ɳ{3QQxR9]LV `nVF2Z'li`&wV -`6=\̎Er:C~lu*I;p}aYS6=Fw}zuC"JxWmstxսG3+4ߏ{;xxZ~[O,}WO7E >l}r*!{۫z m!R?]1Cx-elйAت~BT_܍ӭ:/ܫ簿hLWm ԩc=r%\Q޳&L=Y>u,o4f{{3NG;ɯp:{E`ЛmwU8X vJ;B|Ww )|V3[/_?4We,`tzb+oy5<.maCvwj!7oqwddɇ] :O (}0(kVU[o Så8*\\JP\!d<9@^^p!S5Of.x;'6=b.~|@K卞Ѥ$007;8f_N["nyZR~yxդ4*Ǥ( wyT F3Œ]~Ҋ(?Y2Yb%u_0YCd=^8~'89\3 [3hhpvB(%( gm"+z6Xs'KrmB.# TX+.67|?z83f鞶T}.< ` JQvgxcs+O0}7uʾMe<$m=$#.d_;pxBc vud\9}zyQQ_ 0@>.>ouo@G=۫m[P+3sW{tcQra PkgT?'+Ynk=m D;. WW|Wko~7_U_W:mյYXSU\.uc\Ͷ:]O:ĊV+<1`qa9^W[a&Eݷ43[^Wvm ӑ[фǗ_EK0^*8Y_}h?k%h{zA:wf \<BNPm[>B3u\6S/ u:H 귚"Yϵ7%Z×T6y H_r_/IcBu' MѦݺ3` S87 }ӚX# [ 6:E^]v7 61}/ v1L0xAY_@qoD[=㡲fZ>e#n[e.n,iN\}ثAUyC{EeNBDt,G hf.8J ?<< DҏT`@ :>^R6{|{U~3>{RZiȿ64(\ȠC^i n="m]`zU ys`| OvHa LF.jpGpRŧMx^ G ֧N_xxSlwP8@.K@3!ՄT#9{;j~~6ٟw߸n= [7@l |x : iQiV< .v{WF@7lT~trŒm3e;x/1ƐPonR`ΑX'e_*i5|PDG|S`*? `cl8=;nh=4:~ςzbkҖ 葧>{#}ׅf@z>!5d?Yӽ2CGLgV~zZM'Zu8|J'W5%]YRR*Wav:Akrxzp[1</ jJ-<\@3E+U@ҩH fMS>i@_=fEvG}'w]dy3=i4;<&~=2C8ɜNRޣKd#7" gv+d3zJ?:؅O+U6P7d8XG>ǤRop&#Νs#+߽+ayK3;CKx'~Kzcd:7yV& <:t նs-|~{Wz hrB3Fo|CYl3o$׵}usY2aDXlvLitڒe/a~CCk6WKp*+K vz"tk/"`w= WgI;4t`KGLz6'sMzn V<9cK7/Y- Ƣa~;r}6jgy߲Z%٣ϧYW\kwFw d_v|js*vo)~C#VG|=G :%lv;Ԭ͌vٓ=__ \'|3T%YR:kCa/zdHMbMeK{<֟ =Up*0xsDfu7];n'Z_OT|[}3ZV'lbWhi&ϫ//Ϣ-fc}gljL<~u./`w ~e>+@;V#/ v ww$BBN=V-,=V`ҠuU!rݟ>Lc:=Y 8xUpj6xHn/ڪ?dp};bp:gAo; tU˶dtt,/0VE `b; lS_;)58.ʁ].Ttw{N>=lP3Y)7zK˻>> X_LW1>M3OL>V^`Z!fj>Oǀ n -c;7=2j`aa=\Ƈj!ÕO||:O?۪`B&!0,#Fd˜DA`XˣOiޫ&lp˪|[ W8{U03. E5d/^^4T !i8T>K$;5IfOlk~'F8ԣ?(OlAqS~k\5xHK>*uz&/\Hzޡ}5ݯ\U&dJ*CN+*3W9(nVQ'Dv3;G~lJt۷4uss 4Un&Kd3(E AD !!d`@"H@1A Q MNWpoU4mar]Yϴg ߜn *w"a.]xK?V!q;~ky0lf3РC:}DFGxHF ġ 4t?w`:LUV:N3zsmm%yIٔGrOРE͸E([yh5Z 2~*;\:iPӍo5Jq[1od$[".vۿm>GcthP϶/dkA>3_.rF2ǾJoU'to4ol؀N> o*?#K9ꯚ)NvrU{N O4[g99lEp `΀Kwϟs*p`A5-[]tV:dr ݌Wky’oD `L'|^2nY(]9U3Qh1x&_|Kۻ-vϦj8㓯k:}~/L2̺欪d8v>4_ fȱේa3{y8ZdG9^g)/>k挄sH_oy,9<=.G6ީ?}uoɹ$oyqH̍Ugdfg`VZ^[ rmb2jUP:gxk>|[ CqDŎ.r?NwTVxy6P-C?J6ÀjfٜDSL&txl}~[.ٟn,\pxBP'{2x \]^|E;8GwѧKvLZ׍27jcq#^ީ$]ʒɩ 0!?*ؔ*9uzd6A&(r9ӅzGeWʥ.|8v^μs: \b- |jKV1}^{à7Fƛh٠|ƯlMswn6 ^1v^_cȷO7R&P o𖖽"=JXک3)#t_k;B\t¡nal=z:1wG! {o+'̘3hS.boyQHC[W| `Q;/ <]Q骠Cd9aUǩ])8vwg#i\qLn<Ł4G9UÑ*5 IzX%:!U"ߞˎk4 cc2^t/]^􏝡eٌ9`Ur}ۻ}O*MQV\fxZ(3˙QzޛneP^M&QhXWrLŵtNx]uW>L^[ \n4xKÞko_?L^|~Bf3| :%xT"2D)ڢ${O.ߜ>C g^8qrQ&z?Qc68h83';gHwݜvyѓBP>'}K^=ECݭx $\}/_  Zӳ5P\$WbYNV)C\F> ig7%{0f`(Xֽgh# Nz.g_Z}* U\2V `S8,_9Of t9O1q?|хo!OɯA<@Rç9 Gy`:=l+/\d6x .(RitvS˭h?{(gz=tFzk%yR*~W #廭 7>rMG㕟{Wh+MrGץ3tLxf|^3YvO6WC1uw"QTJp1>um8R'SS#W^/5:77K=Sixk28lf[9`#8l-.r:$ٍLYD0ΒccE_pZ  p>aoiR*)NnK~Ӊɺ4(쵖OŽV88-! >/^ X('k\9:͎; WT9lT8Rv*g 0n5,z8tݰwV}هzC;/}]|;Vg _^o[:I\7W֖VXEv=j`ƗW |xA7YWhh+NC邃J/R8w~vvCLϵmO!J*Ǝ~V&kfۇ`VazP1H r3l G/vނ \6$8&-]j+՞}L\Uƭǎ\F[>[}CIHH3?j:S}_բYY9ʋ`Zv6]Rרᠾ͒a yK *'h» =ۥbzsLRoHURsS9G+9tȕ_x+EvSLJ KkxALQ¤!f-w,v2kCyu/ %{]IPkQУ '|)|}́9 -9MlX[^clfk ρjzYfy|j?q8%^/w8Qkf76Oٚpc_&[ݮ '[f 8qeg|+?3'L+uMrzl6ͭNI6'X̷m+xfy ^r^}sگl&UAau}qD5T,>9q3*3_ 0ple@{+>*`^m¨&A9|!;NL6_Acu:r9V mWУpz89~́;\#ots9#/[|$&Ctc^;n/Gkqڜڒ_ }O~=w^蚭05 `Iw.khўf'OCden1C%;ˑwYǿz翽oq9g4t}p#)ݯ=8ngt{yDbBI_ ?_|{K fe@+g8: ,6 jG[Vڻ22>Vxצ6_"S!Wȉ(>{dzg;<-ϰ)U'cn+Xy{ܳ髺<3$Õ{֞ ^YXNGq'W׽;[y=M6V3g>ї-ZC fmwhۦl j}o@ ӶJ#ZjrgBϤUvAG"[;ϴ.<_1ܒZY XG(}A4ul2+s GG*1C=C'9?L}*G'?+Gx ~nd,9:9V>0K!O=>_]+txF'9/wΐdOh芃#mptiVTO^#[Z.*jUg =g4&=p Gw`mn>y`W_w7y,Q$W%WG+* g}&#ӡޭݔBȄ3t,xc%8y02d& |jf9Mq9, oP+ӌ8;du?3:wV-30SNN:ހmim}ϒgIp;{Sf颣4nezͶ˥3IfBO:ёvuceoNf߀@9obg?jYљkC2×Գǧr O+W/O"ڇ1Y36!'A߻l&*1Rti\Iyp-O;7Vv,Gff'?T7/_W /]{L?X\qxOI?~=?ACt"^ hlq?/_>F[2C@&aIEd/%^G͖/ߙKX{9vWڪ3{]ݽ¯\# pm"w>lݣnyI?١>C'VYyC7۪,\* vŶ_h^ ^N/i{?.S-!6&VFW,z7V̈ 6\Um{SBx "AO׿)镊]9{w[+qR,X`^ty'K/Hg*Ēn7y4NPKPs2ˮ_K"쩜ςa!lU11_iCha]J|7ǩ7-ϵ\$D)2.Yy0^Qe{|5rIA/=ٖ:}>!:o8 =zaWvC8_h*igshGϫgFuD BYECqx_Q8~3K`f4N'e.zhW ɽMf4Mla{B<V^Y!ɰ22,J}2PwGٯhzdCtT/M$o<ᰕS ]E׼?۽xsst,`8N'<tp]&m7駱~!mfxsH8IA#[nDk 9txf~tVn]J93hvg3ͬg`&,,4,.@2^%/Ku< Cl(|-[3T|]]w^^sK_n[iHlDbpzlC<>;>| ֖d{<~jSxan| <^{MR]$Ɣڗ_jkO2:yTlv=9Pr,kig-t}8 J^o!'BWvxd1>7{XvNr\hg3 $N]&u*>=؏g[Cumm ]P8NoV<W)xk@탞Yl5aWmQAO}KO i3]0pdF할5f E~rK>}7e-PG?)7e,;!2}erM76֝YYʩ>11I<Py-/<|{]Uf&>e7Sɒv=ڲes*m;ةx8 v?035e04Gx2 8%@OnhӋ>- P^:c=tե iktWLb[IMmQ* .9͉!SF})?If7|5: wf<}x ÂGt )'s7qUq3Tak:'4+/5[j5=o(fjsB2|ac NfA=[_o3R~/>fG8o4`h&` 00`sHKrxf³tu/tAÃ/|y`d3\leX!C$*r /SiKvGxOVGlW 1xzuonɾ_©>*6{hZ}wmpQR~2.{o;@66ϗzo8t,`9lo ?L=q_I[_~'?yer˿f|;WB@q*3#^mfEe&fP" 5rڔ07KG_pF:$4V~o9DcN[C 0U%Gf{uʐ%PQ]iy~ lų׳cSk}'DlٳUrK_C;*}6gqo>G3ڃ,%8Af~ 3MXW o픋wTp фAs^^S]+}t1,?^fppF&+X݋_Mf[M1uf 93=;ꗧlDũ 8eFoHC˳wjpV~=qU\;^yMM5Y 越 Yi!^[華91~tXf5pNwTG;lq dj7r nKiI5י؝Ƽ~; 263%'9iwS9dXis IDAT7]e7k3.lGu7F3[`ll,zK9*[ۇ}G78^!56{tO8{ \Ͱ/׾~}L\*pwR5APmeF_#8 ~~!gsN\~ހ4G}H'l{o-t =~p;Ǵ>0?/7ܶ䐆ʝ1i;{āfE/_݇7j<0:nCҽNvqrCh,;@=G+xlWZY8G={'wgڜ/6e^+̲)~᳥Eҩ:6#rL\`1L{ӏΙ3 |< fhw7\dwy.tʓJ %|of3W,ڊXm'0砆E7rZΕU|6 ޳/X)Y}kInN*3)`'G *<-oOov4{v4hz_ :>L+몪^ A&UY1xUkT5Z^앣}`a`4΀ڒ@{ .HP]ȏ}(SWtǝ2 瀨r#2ǩOqqSk䰹G|hkfg~[oԨ{׀@? =hl -ܩ_f4)VHB4(hhwOnj2#7-I~nAug8OkWxWfNւZrS 6>a,zMsI{,c9|̓^@^r ׬*%T\^]7َG=28[92V $ccVŒ`W,Uǃ?3s/~7(^m?$ ^m Q|:!mߐVt7гXg T/GԲ1[0:2^pֶ~'bu`ژ~ӛzet@3dz:z~x>TӦ^׼g|Gƽz[%`lu0$mEsmb2`پ`f3-<&+;0x0}oO^|ކO\VH6J$Td_ ݜx5-_ 3,At'| L9} ǑQ C>'s s(ா~ r&fhs,P1o^uW|GtJ3\Ap2:(e % BYڒ n9(''Wq]i)_Mx\hD 49G: 0oapWMۗރrOpA:YV Vd'+;6gSw7KNvѸ}=a`:gtf`'M:S.?gw/˗/^_?˿?4ǿ>9/m͑8oR`ιq>-A7iqmج;fkWz?7bf ޻ ً'9oۏ6]{N_ptQL>'B'uׇ͌`g+]Я;u }sՐ9;-.20>;0[!h֚^pGf*gyz5+s`R6uS9x)ΕsOz!ϻ_4)hu؏BA(Kݥ +GI fВM%օҏ^e,߻K@0so{rL:\AqV! >΍' MϞs8`N'_mAH{h4bzf: 2/c;ƥP/PkNH?1g۫Έ$'pP#avf Lrܡ*ZDWmKY;TDKA$xh{9mJ{ЃN}3F{cF#sdgm_(Yp?ͯ]wbDHmCgE{}b+J+p {zD#l{,wc?CϏd|GB_4' ̹CtOv}͙ Pɋԏ! CO_K%Km;5Ǻ/zTͱ#u i~DB?* @yl?+ Mhw3*>-U!_cV=c f-ocܘV9fYS0!sϹ^ioOahG%6(S~ {ᖷzi;\@ YUZ,Պ-/ɫ.O~~]~L44W 讃aHۏmH ŏ(Ȁҿz9uwQh^K,1>\qnL>ilъ׭9?= EiXd&u0; y=j.笄34W=ۯt7{8n'Sk-(tvoCǬ2m6,0ڋIo=~-xk2)483B_zGi`b鵊'@p5e8v/mtҧ~ -Qx?,VMГ4k=~|]i 7"=9W~3-b' &x׵7[u.3N/:т^ow+6(`@O?}@ #G٤t| '%_zՖΧgQ\_^u ?׾Yto/'??Exfk]Q];@j?ϥ'`MϬN~0V3WfFaRmN XQ 9)sQږ ':fc#^9` G)+\L  ZZ% @, f2x }yfClɱXw9BQ vufs4+o@l5X~U=Qcfhثo|u<(9WhX)Y+ Y]d:><(Z_0Z^ UMϞԹ| FFno7Ge6I3/u S x&g#g/D?,v0 fݒx}[~>uHە'0t^ӳ/3"oy9>W @C gqhuGOzmv;j_ai^_(Em%2bb^)䶫~~_}^R8l+K$_G6ƩN 1SA>)N^ކ{27~1W!u51Nv"NlЭnOg^g6[jO~x-~lK@0'廟ï[s8$n)AM#٫||9ے>󗷜sQZ ҽ _Z4?|5D`oE*=njeyƯggMmGN|'Ȕ#~ЋqIUh\켁>Jmei\s ZRt*gNy^UϷysF\d4[5I6~g'Qכ*n6, aJ`^q|ƭ]ļD@':NQCguא+ 9.Rh1CZ&!g+8X:؍uyqO3>aDKe>_B>9jH+f]c.6x1DL2'91SN)>/y0px$fvcUr[ԫ=/MC" e P43=8eխ 0'*SEJ a2݂0@-PY, ڕ&:xh{u0[i'x7:TnrgOλ RvhP[ӓȱ2:+3fOdL`^8gZqF28?:Pi9˯`p?뵧jk,TsF;<iϏo7[n;<_ }5uxz[ũZ )WFOjN &\M{GtIzgh UGf^zӀ=d &_6:Gc=>Kg't4h+_x tݡ͸'bbTƺF$OwWҗ:LCƛo s>3@?|b98uG6v0~xntՓFs%o9)o}Ȧro+ӷO0댎ZNv/ո>غO+ ^m%[[hc쯆?}e2zW5'o؛ }.15ϚQo{U Cpst@k҃3;h-Ac9!`7A-G}5b|կM6נּy T-ݧhfm'ogxh׆_t8;'( A3sKjg z^) ^l͙Dl@:0!*+X/'~[~>~y~7~lil|˽ bsFˆ71l]a3yio?e:Gh}&XYzӹmgWޮނgh+ wHbѫٽ`ʶw:ȶ ąR\Q[-7lq]0Ur9Pis%{>G'j%SkG)wy|2q~4h`L>h*MQAp} 9rP!6Mu{[,PxmExf&ʂB~FѬ9PGa:)@$TqA2Q#1˂aEf3Zp>UFvKk7ꙚTrfWO?EPVG[k VyEƃp8" |𾙂؊7 xv×^~H; :s b+Ȑ&<$csϖc%r`x9Bgu1kGJ] ҈F0O瑡"T,~|k_t2S'OT ~zrK_/ߗϏ9OWj]EĤoTxA9XLL t;g_լX}FcffvzxrA,efW[:}m<u,lP:*_?K&KNCv`2S忖 so \=H9Vʆl ;8/bY59#L_fBjY>#ޞQL[y)gF[@- T^7f2y~rOe8XmfХg:QOWI0)gg3CPtf{_0ÕCfϻ Cyht,)FpAKx|3{ E뽞mk /L/#'׽{N6\ \ IDAT܋w zU2;,J r%/>)6C 1֢Kgv5{5ﶥd+'X,J?g?KG6 9utѻ:X%G>GQ*O/9:!}5\|ҭDz.~n|nY:QӖM`yɧ"{k \}? #*'E7+cT|ސ^5n|hA,{^m)+VV#Ez9XM {6!ycUn1lts?ZE5o*TP c9D `kD{vS*vq" .b垕hձ~)>뙋. *9f4=y <j[Wx6~g' )0ǣ`:5- 8+ܖ!9xIBk| S^ڜj@%4p@gxt.8TǴXDxlٳѦ.tmvp5tfj`+!Qt ?BA9`(nmt2P9+x}1AKa{`]"g,o x:Ziu:gm1/^㴊#ʆK6T`=h=K/э yeҹ{en\I^:4yRAT/w^Y{Y%~?> eH=v/>_?iٙ-`6rgxAw=,nUAѻ}ͱΉl6sٻw[liNWmڳs\vs2 ÿ2`Uy}mv\+)ZAAiG>gsI8D@k ià.]SmCt&:n1X\IJmK gA3R6q04n GP/pȌ)[A}=Z9ht a}3+4s9Ջ-ƒȟx{eq&W+C8/Z8eVC%:; U6'm;Zg13zt8v|P8:bVů|._.ъcB;ݭ=zAOl8m&W#Ѡ=OW ~"@i م{QKMoB8nHGh|aOZIbvpjG{%ٌ{e+ϰ-;8?<8Q+~Wy=;225V5]?cy8I; Z' ;vlmWѕ9,#9 _CPJVpyC-OV- :y^4b/ {|! "`z>[>m%R<:߯;*keOÂ~F !:k|ڿίDf+s /, s٬WL>UxLݦ5G!G[J }N2+/yϮ7YHXQZ)і. q{Y Fcо䏞B'ebx\V>?Gse[y)!:4n4=TYp˱qh _=0aWt#XQNWa`/ w<#/:2(otGt?w-C?_~XO_H_3:oo_ZZz;7ߘ#r~Z~廿a>>4_+I$eIŏ*9}4`(ۻk HnMiP0~Iכc 㯜/@P,{n-8˴lÍh{-;9Y-/({,?upo3@ϱup+ޝAkmx(lƸH8r+ʅqW07T^~ٽlUƚOX'?>O;ʨZrl= X)oY^}W22n3kn`JN3 |+@rX]}K ;^_.9N><o9^vZCd2+w$3֩Qԩg_ez,c_xked` zfFfzmw3ӥ2Zp- |k;tl*Y\)CLAu] Jz``]w(PGEBU7f^@@:& 3H= =aeIL;ե ,^ݪ 9HjlG+N//$*2OeVǕ>NS aȁNWt?R+% ǿpE?| +=|'\z~o vѧ_ ~A_{?/ſxտWÊc_~D?1r@X7Kb8f6ójjZߣsoH2iĦfQP;9{0`U[WkXe+n 6X4ҶuP>RX*.`Ҡ^] bj F 6P<-pz mLXYԯ^BhuSs?wJ| Th6}u{&WFӍ~zWS4}uqs>2جvόD>}q^(H h/4zv_fpӽӫ.g=I١ -]`e D3Ѓ9CRvzQW_>r6!X=ԛ}XG!jr#0q[O ߷$%8S`pd) NGGM7ӷCm\訙MG $ÛO"X6-nuo8 tNIb1•OVir#>} YȹTjWTY`g# !mQ4D, WhN'Gy+LiN 9fwv6G聱`De~݌;]>8DI218=@pl{c:VY7~>2^h+qRV:OopNn2[]][{¶T[Ƒ#8Xl ֦?,*ԓ\z2y\ rn+FPzڄ>վ>өJ5z7߽AQi%DZ>+ yV]f{FJz.Υ>$$߭DKn j{obCg\u\Sj@ko4(Cdn88~>yܬ.ˉ&5I (W.?<ѣ2 4w&dH­~cs=0u( |5L?c @"tk,^ A/^tN'7:x?ewFXȣ`JTn7:'6EMuFC=s/hpf{FGgj+˵́$L|:rb[ɟyu3#3 4HtBi+(myO{"~IF_k,Շu?.?'/ ۅ"~^Mjh;̌lݱ-64k3 s 7C0n* 6HSin37> NI0l^ \5h6Q_s]^-L2di!䄙Rƌw|: 읯fWox֠]l l Kh.ZN!wC- Ρ[]fr_{K/q^JؕgXu^@~j?lY3 -g~&O=Y4# ?->mk~G$yKnb]xN>g ӯwe-}taA:_9m`E_`| ǝKqC[`,J_99oYm_g?.ʤK1t'*sx rsC4CPJk/V향˭83;.I$Sc仡FS[Y\[A޽I?ܑ?L{+ccC 2)YܐfZ)@ۉ_PN#ކ%bN3+Ɛ{sxCc_} HE5‚X6$2y2-lijȶ"}"|mfh`,qh,$VV2D,''O|:i,& K͑&?=˓\xu@ NG_ |^-{!AVXE /}9o~^}C66!&,mKz[YDFvoX-lYdm.}`Ʀ]UF@35y:>ɻru$'`]Ca,4J$ׁjG]C>W+8`P*̙EJZݐOTlV+Am&Q}؃dܝW*Q9]=NcFm_qcUMa{聪{c}wPpjX&Q pZJGFjqupX*)qp:pX@)UpZ9tqq3qMhpkE y?wqS=܏`Wj|DxGRr)&xca|>Q (uOwsuLhAo󽊳O,]*k}{u`hrýlpSk{x\y H\[[0!?`^]_͗կ/o}Ϳђ.??=3&{_؏~s/~Kzj_/g쟽{o~Osz?~/XaM7]?GZ/|w~۾ۖ~/.&\]뻾k_8_K.:.=={޽ݿ'ğԟShmTp X?z+\~/?8??/}#$lc9mkx9]m&̮6߫9s `; [A( HANcJ] wksmp۬ 9)/g[rU`uise7}P1꣢'G/_,6s0qz35[CRjo~ B2{ 9jry.O ]y IDAT`guC f2>*~эފ| #GˍiYSfqj߫ ͒M9߷l_da4[іrY{V _}:qag_Nq=Uj߯M?:X;kLN.]rߗpx;S~om|ׯtO42,~+n n/O(T}Ӷw~xڎg 6-&\m_+Of bs˯$DKQ\XOͰǜp1z>}r_Z5Efn EKw_<8\A?3@ppg@'\=mfabdhDKu߷:P,Kʣ3ςf`@ QtOZd9tgNmy}ꢬ:yd7puيQTq5Cfe+?t?8k-o /V=ހ8p#}卺yݠzޟޞw}:sUw{b4q`$'n:4 MDZ A,Z$醦BHBb$݉qfsuk<5N]q-%wg=zz5+_^i0 2`gJp^g{%7e,L+ &G||`NK= Yv9VI/+e<[9CWg̘Fm{Q9f/:F7ǃp+wlctPz]OG/|=`ǥr.DQcǴĕ.ԅ:czw% = [^JFJ,jRfsį+-m=ց:wju79=󿠈+z=9}ck'_xa>GOoah7W_ݚ:_+۷}F/˿;~ گ݈?T[V}}5UmO7u40oI~z?)F}?}|w} 2c{U_U?}_~7ܦO~oMoo -P _e/N'G()[qlM9鯒~sbh6}ՑTΞ#W9(xmz0#)i̙~_:OAZc^?;W}Juܲd<) |AJ/`it=D xtSHu:#u%: Ԯ؛1`x~yNdz=hw=gwdg4v/84:3={Q!q.$d+O r> Ko2^S].sklJq{C Z7x>աF7AzfIn@d-oJkj]} ohS0ϑK6=^xoUV7b&U7i2,Y޸>ifX*G$shҮ(Qqwx=:>Gォue#O}ã= g;}!sȥ KBEv#&z- ʺд1>kNzG) 7ƫ!,᤮,1䪃?Pm]@s3h?̧xf6-wn./p$ vວJ֝aZ~$˥v2|WN4U]g:陑kua7?جQz};^h6k)tDdӣ Ž˦GM)f!6[ˢ{dU&| 3_ |-fUDz<`I \Waެ3_ӏeo?^_;:W8_98[>???xԧ>u?rrEoğ~s-pxw~~\~~l{L8z>-qe_e+3KK/%_%-σ%_7Q _;Xgo>қP]9njv-H9#jj$V# q\#:׳5Fo[+yN^0Lg9XMS|N#wٝ:/栾Y 5{6Dw:pDF~eNVAx-sS7 r1wo+xQ}zBާl ǢqZɵtG遏.psL9OؼpeU>'7sݛf'x eyvo/&u)ctqLP㑎Ho<=R/w^QҮ(쥷9Y DMji7Q'_|VµŽoW'% Z2w#͘KWɦҋw0!Ye!Kq+鲢,:@i.!?X9o~ۓP#X]b ?9ʚ/v F>sI9R~paȵKzM*CҁjsPV?{]Jќʫʉ. `8jso3QmgK)躖L=<϶wRpVYc 'tzBzsIFd,Mv (/ݳD cjYaz&[ZhbSK8ȯv_Zu'dg!Wl yW6_~v!l{w\ɖmF}&C~S+a9͎WeF{F6ӕ/GT>Nū+:*. bK@v+\-!k3ʦTTLзcuRm >x?=rOicۛn \BȩB HqHcM.XH 6s|tM69oD_9P=Bn#HB̮1%UmẓLq9ܕCwSϴ\QtŮ`ډhсBZYECoMwr&cߑn aRŤQ`qNd*$^Ύ]pՂhd" {~If4 =- ,pGg~˔58#Fk-=^+`\t@w8uwU: Nɏ̣gy2.=%zWN􂻬]w$pe3|~Ow}Mí% Yi|Ë~U{ ?逇h=-=3`ףsv,2$?8CAL_or{wtF>fȈgV<-h=ѸZph`fXƴyD'?gO fVT>C&?w{.]=y5'~}Nlw}1iJS_u¯O}yN3g oF?GȦN?IϽ>O>~k0M}aAKۿ}_C~{_?䥱G>QB,.f_.erI v݅_0Lle͎؏iaVuiҭLsly;CKHD'p^ !8F={r+FfML4lA:XQ;ʻ5kBf{VYI +{ %eO0\7;:M/N M{9 1Kj3-ӏmKiXK)ݎKPI=59P\S&d(s%WdgGijcY46k7;}Āl4]9JP`{ATtd3>Ң x77#yNؤOX5}33':GPm9Of狲]pû:x7ė2,)-t0Zp6A^1γQCAHXp. wJ.YrIA Agf qӃGkmh4$/tG8ބeLk[aߕG1+uZwiqȤRjX0[ps &4ʧ*לxAm ~5bZmFo=^p=TtѿWrN⹑5h},GnAsfHCG*N,yIƠ]0a.JgwxF(\;GGiG@h2~2|L4<\UD83ѧɣcuBfx΃Y]p A:?LÞ`Xڟf }|uFk <`@f#@xo4n+x}&&@+$}-EؾqmRw<1+G= Oj.ٻEnGnWx^g_[թgԵͣM_gCh\?|WN{~o-oo]NF /l/y~>x_zr@' d8Uc$hOT~O>ȉu WNQu|`/Jh݈[.DI/tM7B; |g:;6 D o4e8zNq2thDS.l9i̟&M~zh0M|? ue v֡ܚE@;LaLu96 x0g_#iAب8|KL'6pȀp9[ݖC؇nCw)coxT~uw?w{zK?уğ ٧jrČkoG>]nnivSnj'ȅmvaJחWci^L=64VoJ0l6FtI/zVy'4D+q=MsrwFt-OX]kiWN˜ߜ#Pe$4;~G_O_͎4}VÎKtntUhslF~$EH^;6?sþ͚3Nӳh $w=VznH ZI [0"~.|V{eK+O>vЈV|`7M ڈm9[lqvbHZQ?43,Zd*p'4lg]}?ԭi~{[Ir%9tVuN rႧfw ,##[lN<_K} }}Յ$.?l&:9GoiZƘ]{i 1%$rg>՚9< UjQ\58*# #+6mSѽ=pU#)Js(ŗcC<;*cU莮-ŋsј"^xd+;rR%N&@9sΡC`B.<׌cxMDFp]9Eso\4wS~Fyt f컠L;># NqqFg)ǯxN;:,3U#}ia2BEO}D Mλ2>(ǧ?Z\xT IDATᇆN5Kzg 5G ܃9z|_o/V<7g8湼|O:?:ˋrN8$]muE??ݧO}ߟI}Oo??OO|ɿٴpq+_OzYcojs9Ĝc˦~ӟ~s=w}}雾i0++Oomm{YW_9?g7ƟNĀ_hs.rG_;~8?{}'$8-s}SչIQ_SX њM%#Q(.sgZʖYc"4H.~i'6WsfbF_vW?ϵ8=DOEi{ P݂'<LNt;+|"rwkәp]W\0~੶9gkcrx{S5oz F+aj a1>ҌTsg,|ALʗ?֮;[]xqTN>+GzI.?; !>g#H9̉omlvR.V~Vp3|lvD;@e\XO=|$*-9` ,h8~<|,s)) N+5g !@q3>,/#t-ܝ~l,~!HGeWNw]D]&]KS$: $,:QPQhrLzՂ=םq~ZωwaVG}:첋{%ɳlѕu -㡷k^Y (~mh'%\:kv/ysB] 3 JlI+X=gwpe /-!ϛALm?ZdwӇ@?xF/ sR%h~oT8s%oFU `݃Fhki4y+ߜxٌowe`yF6ЫԜg߹p8 !UF4~MpuwNIdq# l~0HGZ)Qy04&.UYFrTRuz8o7 ~,`9ZG qG(98  8NN()#RYw1[3iY(缯ӦA(X1G~>`픀+ax~t \zozx>4t>hRBG_MW/2XݝF՛(ϩ&h7/rYbiȌS#x<J\{es<={eƏhb`y//$2I`qF'[69 tESłil]U +G<+-(ai&K]z9/?}˷|?2_|wzN׿N~}/|铟zaN_Kl?wtӛ|޿ p ]뽍o'AV{Zdrɡ7rΖ[g3y\T]W/)ly`ƃ=Ld$[~e9cv7Y%DyvOifu1 VTtJ-F ı@x>G:uf&dNoEpA-N*ˌ7҄ ϥ96֡(z#9ˎ-@Brk_Oy<6ž :Ц43i3 8n޺ϓ/d(* +o/7̎y[Ǒs.M|pf2~K$t:N]DDFC3Zo T /~AcTffeɌwQnv}v+nVpQ3&Hxa}as44~U~aV_n>ެz_t?~KU߳Y=6&|OʎvtoۢLͨXP%܎Пk|(3˔+a(. .'vGXz}U(z7OoقB|?~X3aFz *e~miA=\agR"SXU0DiE`07&{:+Oi+p5HҖ0x":#SsPS^js8 혼P<ٺ`q<6Iܳ_ Tއ8Xs,ѮDOf|Aؚ6Sʞ.(b?i>5#lwgt>Op>03 PJQ)29WX pJN>y_tz1a46AǬ|dø32i؟V?}:0L1CCD}wtt9~;tA=uNyxpE55^'[#5^&k<q(od¥CFaK0~yOhћ#h7P3_ݽ|';}<{_OwikOFFӿrgOG-ZueMO9?Sdv^G=hSI55S=կRicgzPӶ!f֙5 y$6 l`W]mNjwI. x) GE6:a:wo7f7ݷt6 sN}6jlMˣ-:>();1r=ᨼOλ(fG[0 `#dѤc̦ "ĨgَN!M;5:4Mg"P̉q6{#Zެ.M['J Cws@3rnΘC(B{ppE6`y=mH<3M NF7L;cWZ}P>NصhQz іfs'?s *n{yB/%W[n۱j#тXgnc*v7q{)CG>^G2V4yxr?~<ؒVzKK={T}ΜC/GG+K-1Qaul߭>G^@]U#dG-8؛ sO^{#ߣzk^nov=p|oZDwa)^>҅W f =h&#WȖZr  t Mo+IPQ}du/eA'-gc[>Q`\0'WndwoܦpYRP)QnR}NЮsY?7~ XG>oe?FiJnؿmݼ5gsDʜbn܈y9SM፺10ꥥw^S4G@)FHit 6XK4 ,[zψxƆWT ƻM^SS͙ ?yC5yg{ g2" -rn.v.xJtepqgSt,{ޥ3Ջʹggh \fbӁ8d 9{Z(`H֡Ң^{% }{|FnQ %$wvnQx~Ԓ3[Vxױp^cHl֘mse3R l5eX`Kukmr7[̓P[ MSGsx/x43&ҕLn])8[։@h$ǻ|d՟3On}ꫧNoy*"9/tgqu8Yj:я{7r~vm:يl6Tm܈-ãd&\;C[] i ;gٝ[m4Z\?}^oĥ-n@cBUp-pnQW6k06:8μQ*w/~/=9Q=p:GJu/ v%t{嵜߸pJtM^gv+X77*{p*>%oh?8)AvB]! w֩.Sq9nd:HUC!u҆fdL!М{Oࣔc43gNksצ Wϕؑ[}&!'ҿۯ-YZA#4IFltS{AM ƽS%:u,F[r?h6ٚU٥ãA#MUؗ]_@/e_D0$l>!xV邽ݦ>tLsW[[TK3؂Wtn=yTFV>A.8 o_[ "ꂑ PFtZ?OAv|x}7⿥<~AgѺY D>ӱMs_%WOQOݺɥ>h`lHz p\!Υk[U]qj BV'X# _AeJ̟SH^N:d>̗0XVJ0U+7_ʗܿ4 u_Λ'u bŇoTv4Doێ8thmG6[ Jă{9N!w( k'T>7ҏw ~YD?^nйx2^T@օ q_[ttSU2NxfQE% QzɃ|vlew`T~ lL=g#SrEFy_ƭΗiw}/7NӭwoǞz9wF Y8OY?WsOMǭ3wt̲;*mػUe0 >Pn@1E~fɯSxS_4 8LɯבbUhTf*EksŎgh2}rs0?Եӧ۩9tuz\N6~jNg}qxfqͮ*:r։g49Ѐuߜvv2>_sWэ ,S=R84[_y^Z$|铯qN.8E@h+ 'Ü 8 /uBkG3;$Ι3֡ :<ᛍg|ɞcDp8sy*g},F׾q, ꣀ764ƭfpԏ輓Z.<+ Qi f|Y&b9O6`vq,]nk} 6zKji3",M3oMyTOj/jʜJ42k݂tΣrp3\Y  ʙ, g/w_AzġͲcU'|u(=+YyTfnlZyrq=͂g'tѸ% A5:7iaeg"W_pQzj:}ԽӦB X'ouI+CNIfM~l0uuR,}׾g?"GDP3&&h!%[~Ng+^}-=W̬& N Q?ȘVg#% RZm`Y,C>(n'bylG(+sDVC~  Mt7 6YkGݜ]Ӡv6gpx$ !D䔫1kΌOrR!`fiގ0l #?.‚_T:=%SpӁ($m7g}OAyh % {=@;\=LqݜWSX0/z6\ Ne%,sS4Gy;~ xw<d0`jP st(2|UiNv߬1yS=]d=ܱuG|./Fjl`#+O֤6N:4fjdX]7%ҥ-=] Dhk h `uCEFt8`眼sm䰬,  ?f=mMTa yhNt}ʌ&xq(IO1쉣bZ|ӾmzwyPҮޖD#mNd%}x n\j XlTLA=ф/fƿG] h@8fj7f>'N?I!Q[~O?s>p7LW废Na@Yq%(SL h(/;kO=y+Z3$Rbu7Ц#]m d\7]t8fʮ\ԱCshy$Ѩg%XN+`wVDzQ_c#B8GT֩:oX+=>*W6t_#^|Bcإޢ.<~s}e }xpl6xT׎6^e2 (|"8V=LF #F>nF6?:!]yʉr`/S2ہɽz ZBm[y~ = IH`{\]gAZu'};-ڱ +w;z!@\uHr}brV*rqּe w$5Qvm$nl%9#Dnl2J+:TA ~}ʟʞI^$syrJ!phS\87<0wNjD+c!J.pk}=ee/P:{`L19L䃾BKGB;0BCQjiX6;TLºȥϽ7qQiPX f'-g£~Q$ИTnCJ/ۦjp;;@S9]ܾ =4e?>mc7̛VZ=PFMֳSp/p9Uءs l=^븲4nzzxk$;F5o:)) 2 '2Lpj" ؃ꥋ1PY.3}~PSƟxE7a8x38t32\Wfi–em߲?+Z |A+gt*:%YQa;stqՉS S:akl%4c25z#4RrJ(ϻu8jcLnHOFn3?ggS;pN4n7%[id8>-6rN$c]~ قm̧c6:/N|yLF'Pn(O^?}Mu?#^gp3g:#.Yt?lWrS4_zd66liH+-Cejpƣulmr:tv#ȳfZ9»9etfMr_yvi#3Jl 6o΄L>iGbk?͡ᔞ)ɥOց3<%ǵ (\~l9"]S_Mw R\ mپ{z@lZ|yחM(cucuL'[1?,0k^!{n}C7;f qP%Dv|[PK='8x(hH>{.yE<<< \v:'z12' m:|V#6ȴ͓m 6m?e $`4yԓ9dh*tp7pL[|d 松:ᶲӂL;N-@JY#{_xlٕWMN{A4>or6(șM{2Ӕ;~L=vOO%s=uX7~y TG[YbV J dztG^q`&8H]w}B]G^bV֞?<Ӯ`hntTQ4<`tW흲U4=gF΀ VNwKh2W. PLbo U֕npZQYZЂ ~ l}g#6SD}$ǞpS|Z^Z;sdk 5c|wet4a):%>*U{5=?}[KEz>Skڌr69Z*#Z)??$JY|#wnWnz(txN9=ANxNCNGZyz:TE:zY~Mܻؖt<2F+mʧ7hEΖl\0^<ߏ/utvUDWs]p޿fG(^]4z-C^v)/瑄M7>tKC^U~ .)VJcf_y}z&ΓO|6i}ϞZD}j6f/W}ڥ3}ǴCGV}]Y\:aΒѸLR*pnB4ߗ9Vk֬;v,/7Bu1Zg(k`ljtdke>:UFԲ1|FU_Gukgtm.5fsZt9AWzHY*P 5#3yy?8S19z i/AIճ+W(;d轩{yFtT0@[Qh1 ^f$QI|zg:ׂ;?*}#<]Ya5o8U:$hڼckÕ)WDɡۤR*+r8bB}}~;ѩig^mNa3go''ܨ睞 '>bmY{U.>;W}W]νe1jj3m2\KokZʣ{Wy4OeC1`#1o*fxz=9`o?D .;R/HW4~_ԇɪ}:f9ɣme[@Zn8o@ʅua7PHbuuUrb[p* is|q%84#DGZy@DqeL/ei *!f+/$mz7u8V =.gR3M Gy=fA킯 \h'[^Y~ϩZ}3xO~V [pզLҏӔ2c7@at ǂ~JrP ԽkT 1H٤FrRffcu9aX͓ le({KٟO%t>\ xoP56a >a(6rA\@UhGsҟ캲$lpٙyWk֙OcAiM o3>g hމxs+ >F w;yި 1y9cj\:XϮرp4xB@=DN ~Ȏ i{9ңK<֦f4·vX`7ؕڻ &t1;ǻ(=6c3/sj$#|c>O7XS#(ny w^Ch[{^;6ǠF9Y^8H]l',C#f$\po2kO>4{|h?)9m֫o;#q!-9ulѨٕj{SХ*fDg˚ބWe?ӇqGhyeܩ'+ْp[0}z* RF~lOxopug:o:![9`4PޮdDW#"J  >{!Pj _dgj+U64n@yRjv=MWB=z}Ej@ɽfzyr;C?ψ=Ŧtv&BV hZu=C@3 A}?1>QoӣH$ӿtf+L7qwu.& Fu=s>lv*l@(D)'B4-wK ,W^rGɞxvA˭ވOpQ u^ʽVDwCWk'[QqCȸ4m6B=ri,' .GG֕w /$\ȇP<'qFK_"82ިx(aiFcWϹ}7{ R8g#rVa?aLuF)Xi3C0}sl;.|@Ôᇋ*, @.X=(\'bplN6?C\=^Ⱥwr+*oz9-mm~`\ϱ~W8_^ݬO_kSo,C?ЗÈ LFwJz8簖u7UWy"v,B]dyIYd6,Qz1X:;ݮ9t6Z~ BgJwhGNH?HTjG^2D:OSW_gbzш=?kT8:'}.{jNFEv_a ]t-9t:ate鎼ɦ}=?Z5}GCEaFp]̥#gU%+r~Y#^lo/ρ9zcX^#Nڪզ_kCmKoL;7uqe;uSdѰ&83#&F^s5\.o>83/7-ˋMw1I+ggF>fk&@YYk=\ ,M[NjKxt }9D:{(;[Q!(x`Q2Q@0 ݗV l 6Vǒi׻=c&vhiywuӄoN1 (}1־뀗V;[}ǜQ #&  ݂JEk8pF8]*W{XGY{ngx=LyѷįZjW_؄@.#zns)zB7j%k#+g,TK'%,m[iWQm89#$6+7C>b2ڎN2 D aXK}M;U{10mm=CM7 >PtL[%~#* >wsR?\@@'po+B SvI^N[^7 Mp1 q+<~\|TB $ 􈍘L۬OAX߸Ҧg27Rw8}p_Apt_Zkܯǧwc{"Tדc O- ύ*S[C !Ь[4}ZLF>*Z91;z~s*/Z~x><ˏyؒ%@ N زS B`o`X2)G ɐu=Fa 1K.9˥*נݳN3H.J:-ND0m4w? \)`yqGKǥ!TS8%4]Y.)mxMl(䡉릟sʒ|A!)L|+._1ulpN~_xw)@Gϕ}TK?)%KO ~fG me n<|z߿c/L7b}3Gv> vNO5&h$7U*0t60yáV桭pGx&{AorkJHT 8InT%ӳ\6Ip R|(l IDATWI>92OS1ʖ'Nx՗E> gYzQ,u1{m[t j|Ogs;=_`WãUGͧ6.96T/{/T#jr$ [On7 1S`fԠi?! &P#z.(>|xwGyvКN?V ;HQ,Xҋ9>q@ڥsR'7#pOijNTN\}j6ZZ]+}GrNU{[<<{y4+TݩuQMcmd/x@͐V6fSC_<ߨk3*9 09~:D5:#FUd#{t5f5k5sUI\# 4DƛM : ~ЈhXz3&U.)-<^h1}r8=Qe<:Q'למk乯ko5ӌKorf ߁xDwmkWGvujx17m )譝玊kO1w’!~G8|:JΕѿdJz˻ۮˑ}&0zvD飲s8xz9*L=KW9G1ȓss-<~/yi/Z$8;!gqx#x]5XNUgl}D7bzr$qw[pF< /EϜ~絟U$h<>8;M3-gHI}f<|-݁ z\>+_Į1\wr{?og_o1=.ޱ?sa Ҫӈ@SW{~7-Sҧ兆LTկR)Oonyt,49]}"IM&%v/x%CzKzѭ}Lǯ9uocd2 V:}->ҋmܧ,D|,'8 ?To}#V7tiəh ˗|[hw_r5%o7Ճ A>8@گ/E9>~>)UΡvjVu٨z9']v6uE0u1yzemvg|sujgZ1}1VuNaT^:@# ?2KpBbds:fgmh_]gR.\lƔ*ӎ 4t]8u=i؛mRTnOx؏hX@?) 8{\) n { qL#x#M_?p XFIMEbd/}bI‹ó:+^#M->ǩW'YBD0sA`9tk8v|Cwe[)߮^ Nߣ<.ů[f,tM&C143S,0g1a(.FO lC#ӛsumAt%"2/mslvmF9(0`Os8@*l3OB%2n͒CN8nS$k:1[Nθ"V3>Hcv%~ (96)ҙtfJC@>8== x ?/.ч` ەBjw7|w{ XZxf(X.!>(AK=+#f)d9>,Ai.gL=2w:$me x9#vf|󳟌i+eIU :ݳ{/1{e/g0 (_bS<6⛃GvEv̩_E /XhJ[ݒY0@:/jeJ{Q+Z=\L] l&Ak9LV+X9cjp<ρ^|^1,8i|<_~`Jxw"[i/R e4r\}yQ2z5/:[6pߕ\r%)As|ѻ9~g$FqqݒdX#No&; ' \7p줆Jrh1tLqkDx g 𨧻dCE_Bcn>,=` zoLwv#;܇ P.=t^յgZz7\֚!!=;A9Jغp7%YA74Wbn7_XzWi |IMTB= WFkVQ}#r8g|:,1J:u폎2y^+cFst<8̸ppl (dUz.ǧmIYb`ڔp%N'GKyG2ЁL_JCH2:t\8sڍmQPtIhB|?dqFCӣ[Pu%xL׆܏<]Px]=ҍmNn^(;ۧ/7guwq+cZ{v(֠8jD'JXۊF79W'͈1 AAyvV:D'v3<~fZ`SdwzrlB\a{xOx:İ{yK ڳm@{3`m"`AÞoX͎E|-xᨾWv@$sF=mա_cw{{4S[N2{'3NAn+04M[G|p*kyn5]9Q<ߘaD&8ggj ~x xy怡7f?l]``G$ W.>N+Ne@f< รP='~]BR9+[ *x Ϳ4)p{X/%KsUYpȶ3n} ʲaַ WxoJf<^e1eNӣL:xFx ' hpř7K?ѳd_ —(Ib]i6Ļf()vm#NvGY=^gr9延I A57*otV9ց::].6dvU/Άlg˯|#d_ F$fYc> i/&$a_:hx) H28%:LzҠD˴7٦$[=o$"@m_)VMGU󠃢sdu>;~NlĆisfKbΚBzA{9Z=\=\k9xܩFIs7%bo8Y=Obds"+KK n%Qu'?0]#`0>W.ay̹KOqaJgxK,˻eCJH:E(f=;@[ lL#C<4Fy/̶b}7[ /*l70>k| ds|͡w]\}=Y`p%n3Y]IfuU ~b׳JoVp/+qD(e,q\+*uW/L3HD+ Crt#mӗgK!;')!Mw҆:}_}9 &?Ź{w}j~kl%,O9&ozߛvr`y M=n ;g7[Fzq4xa̱twð elM[2̗9K=1ب0v]}'6V~ jF"_tT7lW^_z1LMz9ǵ <.|(͕.ԑ *x17ݴ %c!xxPȾ%Ï\@gg4{N?Z. `zP869#HG%_7] ġu';p94?|xnLh& 6`too-_f,@tuo0xǥkFw!r\sp+KSuqǰh G7˧p+r3hAz &D7\o Xg.KN*з!AJ=}m2S(_2} MD^~4m9E IDAT/j] sI)z۷6a{}'&c7ʩTps~)kųԗlr{#S9JY@r KJ+pki^PL.:^F):})Gy?هo]lÜ*W(Zh͙fՙdSu㣺e}Q)0=_mOu;Q9dz }d9y~ tnB? Ǔnx%9aʜS{k7o$sO_L e=d갺{L,VL$+>:V'>Ln=ڬ)]":L2rn`@/Mڭc l[lYB<]DE^8ҡYsFtE=!~r̊k-@.ߩ҂c]3Yc/bAfsE_uPpKs \Tp= @-$\6]Q՛^u]FailW9 E{{2\{~}‡<(#]osozrx)3ǟqG# w^Պ资x*/4g?0>*`kq:^xG@S:?ur֊_ϥ_i)mʔ>z!ֆҔ&9t[o?Et'MUN^*gcx_+Hn pBk|[E=ٙ^Fi?p,dH9 Gzh \s4B Kqƫ{.X3=۰ogyV IjA?tK_Z'gpC` 3"}8GhQģ蚎rŴarLن S]wY2UBwrYH~zYV.;I/;O%-wM}WތV/T <ƷJ.}6o4Ӹӯ>}}id+[:T5l;­:ۥ1)_wwω~Ay::k[Jof#ڢ_uzyok9xoyw`f"r̓cdH퓮(y ̞1; Ϲ;ҍឍfޕxx7[bP',-*te*w;=:pN8 N1MV(p<`l`ӏZ=GGyxeSA6J $#]55ѷ ¹y|Lm䴴tGoO Ho?)Z@4&K̭T(l95 Ѧ[=֘z >Y9~}V\+i{C0&}rOoTP.} Ͷ|䱦(Î'= r8_,8vel31+Ϧ3w;LJ33U&>7K0KDZb*?tv.߳#剬 ʺ[{||u\ .RU_` vk:S72},8 .Q{p-;` @~9Q:*W[J[`zN `Yv vWj]ՍGѪTiǛqf`VMuӃ𳜂V:m<ߒS~^_3ս#^#.A#e:}w<Jn*Z+VCW >P֕uHfgW 5fmƉJ{@{+-Mqz2ľ!]&|A=Y~+.QhFC/IP7~UwU6BkQ`NپLWʹwnF]u˃E+7p!۲AWɎ]aN]ˇVk88DN|hoQ|CX*i\8$7sQ'$X'0n9wWye/C$Y]ts)nPyW~hߣc'> (ӯ譔oq0'j9c 3-:jIb.8Ql,Q͚YzZW'~WܟoTkG#:T=w,(zP,l ^ }t {[cay϶(n5ls9+u0=2=_^x͇=<.id11kxQxroCrtu6ܞs#g ~a3ʋJ!7){zpnwJ›wwcNL}7~NT#wM~O*mF{ׄf\7^.H>C:Pכo+&3.hk ?uB; H̾3w9>[ZH N3 \Ծ+LiՃS@l S'7* < #^pS­Fk_,=~hgrgײ ]ʹ-p|%es>_]뙣ʞj3n7w <7NöB/3[OW_.x$Kg;?䑮 &VȕAߣ aES~Gjنd6^[>w lr7^XK;´^ޭ_1Mb!76;A:];A;F㻎A<{qxzn."+5r3g1#0]짳 pzK{q-/ h7L=Fk$rz&|KAH!K9Q ޱ(kΖri2(>b)ZkO"`ɏ7p2y]Q|(T!t[t;F1]w_11 oCo뽣x rT_˩{OCcvŧp7n? |~(t+zEE080ԕ;9%pGm lB9`WA?#ګǾHqc.zʒ\ѣ8^(Gwln5*n3^xIz<靣'-8ztA?ӎ]M&ګk0@\H =@ #?pz;^ߜ*dV8cfTx 7e.dckja`ܜ7ϡ)M9Z$ )I-64j)`tuphQAw^чWV/,k+!((p Mź#OFJ 4=]LupVY6_J4Џ`9ej:Qiҗʰc6 /-ݞ{p׆]Nx{HoǞKNW1oVa3z5e(͇?=Z8p7 zy8d!uG}ϦDv_&}|Ik Y3ѬQh.Oe͙*9Rx?5ӝC.,erhfp?s<ӓ^¿x_}>//\|쵺 W&Yri{Zf+6[DrƏ<9d? o/W/)78!Ӳ63[譺 ,vaN.OBۜ~e7vtQo&ҏ#}A%+,R[e{>Ӹ4r/bCwݧC]zW5%;|>OŁq8 ̮S:@5blSJCs\6bְlIv!v#>GُqNu 5: sHY,Y4;C4=>^Wgpp.V ԉ6޵6:~LݣIQo$*yadqbRu+'~[GKP}w֠g#)ѽ FG7sA6rs($\:)O^[?wvׯA LJP#nTK<~s/nWp]C' }d;=$Ga٘mֱ7w/!z` kw-e8S!z-gKHR1j,?32}8Ub@g|w,ky?St*#mӘ;JR`m9b}U>l?F(rn6X\ӯ)78~C#CPNFe<-cJ/9xϧGFCA`s OIK<ڱs|dM` |%A6< }˨^:QGt~2@'l NhJ>hy䉷H="2Ɨ[E j^}{XZEX:EG3iY+GO᠏X"Ry|/\эy:`twZUexϣx>륗^Z|R}s__]fS^/0@tx+[E0͖VVgγ#o is8=wV%g W[ wD6]dfատ,+>otFxu~M{sn #|S?cZ/3uΑ`gMv8r6T(~B?z#٫hgߌk#|k;NǮ.ruM~a΃oue]l,a<ַ0$WBvA-b\y9g>߱@2͔qYnnwhl[a2%ЃWc@@3mhɁ#Ȑo)֟&>Gqh8(y8ud6=}ի/?_ډ 6MSw*tuzF+K?>QYZ}#Kxg?.C7O5xDp NӜc}׽) ʡ{Ƀ^z0_ϙn}|Ս .4wgFLlzPtϖufO胰;6%6lY1p {g<:t@[j ɧx(59Nh64,0?nFod=XY5s 5\Mޘ 9lII!5D0OWgl+^:~Gv|o#fEdŁ|. =& s^^s{/OՓg |nzr7;2 K gfڶ;=)$ aD.+~0;+fҏ W78s~%(zoG=~ݫH/]0'MRȥД0FN(&t{\(:L?Z i` %k~l@ #p裂s2 {5f{n1WQceY%6Crؽ;D.I^];o ҭ&~ŗhuxJ>o p*.PC Ecq8a#A/eY խsl"F[uwBds³RSW$h ~ţ)<,d.<= {Q!;opZOui~~_}?Ǟ~!)Ȗ|KKN 0le}r.苾r{g?xz:kL<=_`ϐ~?lj#rLߤFS)ֳ'g3t$w %u\?Agv g9߮m,4,{#')r`HZbk :RS9ooyW)|akKӳƛ{죍͜=YGW~OWRu5keG⍤++ ~8G@̯yoM3&+ɆLv̕T1D;D{pȍfxp >]+w:xV_zpr1ۚ49+g#1z$ 8xV[j= Md#91xlPNoֵI#s0 2C]TohWn /t)}r2x4 g.d̳XtOlP P~/{Ҙ()x2K~oVڠqzNE8!A+£j|BWxPW{4'.zD&ΕAMպͦ9׽}%5~6Kg2/BR8o<,t=n9tu/^I(″t].ȘjBmvQ:#H[J4(/^܏ G)%nZ'[:~F ۓPixy`6j*DWωctoY }68NAey8q6kSm^Jm|ܞ3.k1»9Rހ8xgǃ .pH&LLa-\ɤQΛ)~Ӭ9ƀuF\pW¨9A82pn=XRezpR } LMU={ӱz%F )?ϼaW.Y?yŜit ~یs xЉOgtl/:\: H{ӱ,^.q~<;n~ӌE `Kih7`tyu!GBR5hxzN\DFs0 )<_3;Yũ3>ChZ?G'8C9F L)qCTrK{Ȗ*7Ƿr9OS~O9ԟSO{2<|XZY!C/Bz|ӏ??o$(:WS bTiyۜ yYpO_L諸 &fLK[4=XGq婖p3NljPߚ.# ޯ=d!3syFH8kk8;k:G6!&2{c6[`_޽iGr6XSo^ʿ{q#ko3-c5X+#1'Hz(˷fs8@=2[ቜv[#:n.Wvc 6<+~~"9P{?ͣŋ6ރ~W[ cO@3zOG<芎GGn}.Oe߱g¾A8>3Kփ9u7g Gsc힧h̑mӃ.%pqVw(94g#gdN4-wUuKӚI;8y)UY 2'ADPfARkW~Kxv9%l*Zi>\+ī){/g J,S<2')Բ"[8@lx2eJdٻ)(P?K٦g\J6}P}rrd;]3zV>;>qt*Bg,|~ׯcX`{F߃Yc>G?Y%ذTfyCn d;2G^`/,jI#}[1=x)ē~pH?B@Ŝʼ\tw  G%+^Qz7e4Lu.Ȉx- '}]Րߕnh/P~0z)h: hN{ mPd 39EOw'kYW ;]9dV^{K[ke}}T\ceDچ~.2?~O:Ny{bq^b-NoM}wF =YiO?}J8O;E~/w,±Ս֛~܏I NyW$GM?{+:)?rnyw/tON0۟ãYzG4~E^w7_k;:`O~/ǟk^o*~rn>޾*ձޭTT\JhQ߫ӑ/Fi >X{V6z9hWuY,ڎ].vnujg '+t|-^νA]K$fdp>lٖF&o Оq^+P[TýkMv>X^N"XYRYݒ6ҫA6fGI$uϷtSx9z1}çG K*G<!Yv_ޟt)@+!]+G%zه;:#xWGGmNJd5M ujW3w&z7cA; N%?rt,'(=Sc 뇄hG 6?ZjO2}TELwW6^mV.QN῾28X_FJꈩZn:ur06WsH-噂O Nl1joHg62Ŋ'h\b],Y/fFe? wt>p3}/o}R `l<-d_-ذc ߾Y` eOtWz+=^rb=l@ rfekY.iM| }gHhR)GZ$ߕ&M֩-M5{Չ'[Ni&5M,]bع9T2s_J%s?r)~ߍoئw-gV/[ |N-~йҔn(~ =8zCx~*í>%4oąA]*oj?qI•G?^9G]ckr `FUj 0{7 cJ?3&3czUvsFط,5Y$KgxNOi/]b էx,`-aJ@?dMyV/K2c3k3ŧ̕3öMЅ5$b"a'SvO~ϧL7Hsu?Վ{Usn9O9:M(_s:տW}86"t C//O? 8OFձe)Ws^8fܗgimkau D:)0}IT yd<`A gRGg?Z`D᧲sZGM/&6>k֜I -^ Г`t}A-|(O>8#t{#&=׹Aۨp0U V IDAT-YV.[bNgIn[g>8mS=yPeN~G^JqyTj" n<'?Q Ydt3?}Ջ4\&Öߴa'sΐg>c? XmFƜ:¥r՗ }TLx%#REԲm3NɁ4^[0<;U<QlBG]<6[Ң >=[a{FaQ|PRӡul0@6̣瞛aG9R'^FK-yz228hJ\_k/dp rl}PY{vL=+> :b̞/QH{2dX:šn3}̠ W2̘b' HY,HfGc~Ks͖}e/lJx^zkj$4Q:]iF!dzԝ䇝Mݶ^ yVͯA~78+aQ7ﵹsB6RZhg=\-b3[ (<G(>^%fTJ > |s?9AYN9?< G9RFa6[ 3/vMGv]SN>j)6u!.ieD>Y > ?}35pN3S]l/gy~o;}~mͧ;C Y; aӹ(Vo4R% LL]8%b:vsrgayV`\0:h?BAُ׆ew^W69\aӱ]} jճO]\w±KrWWaѿθn6ri HmG::[ 49 +g;=#7S_:}=7_3)i=]=2jywfh "BLJ?-=<[=vvH' q>?8|:_َ:~[CQxKvLw guNl+,D>[_d H%sH~벩`SE}%ޣOPk+y=SMCs{O;Wenc~lT FNr8^ajdtTy-ĴgM1D`qs:휵GpvF4a+pܧ\=nv;l#r s83Wg4֥Cm(&t rCgAk5oë uNʁ7JzxXP .i7e$UΗS@W=M"(esf({y왎djxsTyOJ]9B|`O77G{惇C+SY co?}sw4pywR_9`ӉcSY`=C@U^ >qus\r{:^=_GdN>w5|Y]/ϑ wbJRF-'9t[f{z?ۜT?JOs].IXQatYFwh o14O~5>>~is,e菥p˜V8Rm8я~w{?!昛q`m}1Erq\ >kmY)Dp |5~KU_U|ל}o-Wt> }c~̏B=>o-8a魙;o.ީJ:?GAu[(ǔK{>.Cq969cו\S>3i5v4ʂYk:C6DǜgК@4˯v@hXf;i|s9F?9'34O6g<''&ohrF^+MBQWU K3N1xLce |p#HpѢc [&H-pd#FT'&+ gL/@ol/>f%q#yOJ48#ze5Ҭ%DHOی~gǡ9j42\~E~I4+N\6xq#sEh׭hކy]67<\͉u'Zx?LQ\`>睏>bnw D2Ϻ, 3IVX4}%Ps86̻覣_``c/s*!C ޜ m6̿:KqceqP Ak%8(&>v]' ͦ#sc6(aF&z֑*a73[>w|̃R1|]pχi )~<ӡU#ţmme8Dtm--%8|| [8$5=*+5įA|,;@΂QAY&ѷ::mƻFr-YE$?u=%:.y{Vc_ho3N^o# >(nn 69/?t .싞=T_Aod@~RLŕG |K#6_|NWN__>ٲϟ|-]hݾFǿmp>Osd[}k9pk(};T}k5?o _YA Zgo'B?mho-SQe / p >y3 .+d)K۞աLpF~ů[|~9Ǘo}XҖUWfN`h/Q5;;Fˣm&@3,6c#g3y-ø3f[lp}D6Ż~m~i9u9Qn1=(ڿWgtޔeDݼڛWZG;Np" @sCn0hsh(ձ͞wvxw2bF( I@&Gx4f_hON8P4_#wwMΦě~8xTlAGOv-=ޠ ZM~g; !Yp7G,؄ΑyFVNWYB^A_GJt|,?pt"]$Pn%ntWu0< ?ԅk3FV*>dv#[rz#g×S臏:et '<^JXe  ^mo#֯?z(L/7#`K`GA>#WjTNx0F}M~81X҈6[(ka;^=~ΣTҨf`X*X|8FW+#-:Z{e]-rrŜ~a:_Oi??D]!SQC^KEgr")@lz#3xX^ZO*$;93 `?\yNPQ|>xnyz}Ɵ K/|-ujAJ(ڎ(!UaB54-譛okY5CL /]ZVzۧ; wZW0yf){Zڴ}yW5,mf` D58Fg/4~.K`^TpذfkuT!1Z?]4˻ =ÿ<$a,{V^fHU=W>һH{NéHlH 35s>/oNИCcOC{ _@q1!αi^: VeVK!y4'kMa}ǓSL*@ڴpF*"Ʒ^:}9PRQ9#VLE2E ppz6\UʊGgd!Kgx[' ?KOndᦨ*kx+m 6'u>%?xny2W:D{tGqy#0``q\ύ`4]:pǻʾg[Gaehe`aP0V;f>79Ms3 EW 㭩烫/UBTg r~oz^|*hnUEt V[aM:Z1hDo֘,ar qq%>@~옾 `˳iyPgz12[ڀ΃?zVvDkw, `Nwz'N8襨go싋gnϠxӳ IDAT%,.cz`\?n߹IFyN__?GZco[~o|u޿y9O Aԟ\ h_?gv6Sm ?_ܼ|+~2~Wf3ymI[%Я:G4_`czώV6/ZϋfǏm%*5COz7mr:u/Om oP5zq ۧ3*oZٖ;.BḣӍ0hVf EvO}fє|x2>!M ji͔npbyr<\f7W3'Z]׮^EYC&J,h , :aQ@{zʝc1J-_@o6_JGO=%4VC| jw/1-ǎ= <*#C5(a:BM`MHnhwO/Q?1;8!맯O?[\Ek/n|ܬO<S@ 駛dwz(=|ԅ+*Ά΅0/zhYVVoJ:o7I`>hvy\~ @ֺí̱X߁̭!46,:of]܋W b!k[zɲ>-ʋd 2Ckr|Yzx/gY= VJA^|׾(.(`\A8uENj”pG52e疍}h6,y (ѽ筪P7mo'T0a^}?Y藱.*Kՠ)4cu:ǼzJ/yGl!o~doZs,̔*l[ [uU>VxZNK R.۰cxv H7t ( 3!}Odj_ 7Pw='! 0)`BJi̊rKxWf?;r>'' F`_iEyANA}pޮy}ޏ<] r_h} -؝. o[r\i~e m̯U7-L׊7eaz K{voz=kp6Ae ^>`%0G0_ _h챋]ιI.$g x( r>"WWBstl aow=}璾3!ˣ{ӯ=$5/孒׃ӟ?աR.uUW+Wz ==0k=u 4OO  F˯ٳpfw<XQУpO^ࠟ=<٭fC"gF=- =g:#;n >+~\:bTWZ@,{ DlFguuoƓ`ե[@,G>/E P=#=* FҠf󃃟wC"[نkxcK t\-26@>20ape$kIįUDjҏt[hpx`-=# g܏'>/;Wea;9|%\iKnh4o+4/lٕg[ ,xfgM o6gv)F> `uqu$ZJIvu5B|;Zy8խ1zrƧW+ o϶n{A| {!g/n?zx a} F:wg%vڠF& ţelgΖlb;|y]'$C }}gq;87(|;g76` W RU p - μ`[ oUACev[|[^9\N`D3?nF~/lI #,3ho'C+_|p;͞~.  сts_[&AHOݤ7{ (]:A~{_MIJGel2[v.k[QVu01fzFL>OXGC̆q33޺wt6W>0]LV*3)d f : Egpl@"y/dQlȳ>vثbʯƟw~B|ڪYŞ/}/oUKX_9Ӄc-uϑo +EGa-iҠ;o?j{Yn|(lr|[4nW ɘ06w̝{'trȏY&Gϊ"[P_C_$k[# }Lt$U=wkňOugm$u?9zeerDH䁝ϢY5mpV] 9W\t{YSD-N#0R.Asߪك6-(Ʋ2R^fA 1U֡ރ5Yy!(瑲e{ӷ-#D73\>ŵ;$QZjNrnI ^ybNjieU9H6 WLBroC RħU"fPj "@#11thHZ8=K~/۫xkp,OޛOI>; f<E}_^ %zOe'F6㥻Ʉ0|Haﻖ VUݞi3{;@Ϫ=9Xl0,\ҵN8uԽnGEF|5m;8E|-ϋoͼV0Mݭ?P_ Wv[[R^g7_SuC!eEK]ef>&3>q[tmMtl0&Ԕeo~ +& [T,Zp:fr' x^)kQ7扁# xEKK 2}2 WL{ieWyIxNfuo}}gf 밳 m f? Iv#>/?6?+8mӠXpN+[ݯ]ol2/S8V2fhL6Q ,/df}!d$ti;=| VVpxM-fu_0N짪h.ѾsR .ODze@JO;-3O?!)KOV&{ݣ7h!7ofdJ~!AWBlUVk~* ^~V)$.y_#u ^YxIձhV7,`S+,6PFvJݯA=Ip۱\Ku"p΋bi}[4#dK&4IK)q[m ֓Os:/Q:\_mv'jV,}?h4~%IiÀ 6ɺǸ&lګ _[QkA|bem2IWlzy%:pf7}#dtdN t~fT DD^TVV=tEZ 2IaDm1g'e➬mK L%9!([}.6e9?.P2nH;m A:Y/ֽϒܿzE^zS`W_Z `V~?Q-/K3]f6G i:aoxj0{7lohƏMtgm)c`&0€? >=nC4Z~էxk*uTa[ |E_J}9QF#FVh8 ' K|w{0?iZId:d8'܋'Qa{}R^5O%&^ρ+YnG ~:T3Ff[<TҬ߀œ} &3/.Ҡ; WU]ge+ %]l>vJ.~@[?<̻^6ǬY@߽ALbw&`0klNmӱ׷J.ccj W|u?f6@ŗِ\I--*+ bB:PjWXg,"^z|%Zg){&p(* |_U, .],gR0 =m9uNebgqOy Oe8$w})A`g̡` ~sV #nOoRQR2> ;?蓶+_W.h5ڂL| YLOL$Ț=E{R}<ә6R:& eWdpQ>użr򜡐3ZAx̹lČ-([!3\ h;994ԗ1lU ckgou1 ^9T UY]k]P^ u &ZOQx3Z!6XdDOxtΧؾ^4m^mA2X ]OGN^g ^+7}ߦWI_I ATVWf uj+w]^13ܞN/:}]+SJ.ft,^'S~?3g_Y}?6t|E^+C`\2{fJ n0G| mx=f׺کIo}ln V~U 3-k?P5mɞͳ/1{-y;YIw?}nC:,繗" Uc20 |q~^O6,<1`T* -0pﰲff}MBq-][Z:O>tiBIWO8j@Z{-}*[`C[ѭJO40Kyl2yO,0-gpI@Kn'}j(x>o@ukcMWY}l ѹdeCw2@+WYaqSiVv53%?*{ C%+#;c] *?ܠN2A*Rч={#w]߹|.1EBΦ?<ӥi:l[_UhK' 6iN}oyOVT? l(c)JdJo gĻ}9$x ZC|Ɇ-ۙ0#ϊuNɯ[|Lk=ۊ=mtn}:]a$W:sLz=/ʲ2KY-60tKJʀ Βs cf ~A\Έ{͔RxKw-ʜ3`4]AgV27Ú9FJP6u*>E72@zX!ÑQ0&'[ުH^w2>F֨3~pr&ش 1<*0/ whXv?2F uOU,˪4E/F- JV_3d96ZZpdM BN8sy\)%f $$Fs,{ٖoiV'aPkffsQh*}ʈ1ZJ u:7>@VPtwyV԰l=OP nm0W ߯tqʙ:lPnNp%׷훿{~)_ON{|u}%% zwrN Ǘ=@{uMǷ4Wy|F-9N1>Q-TRޡN8uzz{+%'?o{aຢG~L-VFWWXˇ*.j)aFVe3h\DIө7pV%ݺZD^+ޣEN:3ۼ44F'ئPd<‡NN@qAϻՖ}+/@&>-i:/ZMj1 @@l{SB9a_Y9_ yz4XaV{VQwc}>xn-irri.</f׽/|}=_p`z40Rzlcv^EvKB:C?l+eW=1|'P?:k]0|'';3yWLCU=u@!bF_A4c}1˫<f[or3(Wd0ж%يՁPJg7ۺS>rtdYS9=6f8Oٗۡm@W G&=ߒ ܭ܈SVV.qFf{f>x`6ϝ1ou!"dϏlс*z4wBP]L0L<\kxIN=uJe7|G7φZ ߊނe0Oy1WAR"hVG߀ gu4_ -Ϟ)[d]*#n`lilX}8$^^{fg> TR <-?cj@6FvGvbf e;|}keBB?_?],|_Kwd/ 4bp<9t#`{P#}jF5s')3=RV .Y ]G8 Aq;L0Sg(!ut [0:e;("ڱ3|P^dTTem6<=C(@ow"'/~ ]nԷLyu~=L + Lty+u:f)Z,du $n,a76Bz5*d`&#uREFu YF>zsP`oٻ S-Ag/d1yj\ $ixVqGxًG:~wc=1uꍙ#9 hk [Z @TV99`M*؞LWsYnTM;O ۡsB:AW7[[U,؈'9[^81AE&BO`@h>4: gy8[.\;hBz{|-O?.){//?n~ggo~g~%ogɏru??i7|VU7t*+w h/ Ɩhfy^JIו6wN ? /: JԎixѤ3vKhR^gx> ~ϺFJ_`m`Z]-a|']>D;_'xh3h= [zs 6 >|! ^_G7NV[/W)teBӳ'c6adiB- LPmESFXўh`L*uO|ܗ 8oo=@{G |`|,;<6z_#7[L( <Ͼď(c~R3-kF 5ms ARb&T Ni_4bB[!Sp㴂JqK?Ӄ,_$ S{|u_*E@m @T"saKC_Fc9Rtsx8 @` ,qdv +_3(qғ|7 OyÛ lk4xO 3"|ɟ> tܾOoFf9`:WB0itŷrT==AsO,ᅾIl-,ih0v^i,^2d/7ѳWm>(GtHg|4&ѰLFao>n?|F>Z:nz9 :03:а)~xh\;TpR2MnFOJdggazzhzp#چfKiK3U=Y|3SwL12:Sg?`*=yTU?G^>(ڢ_~z/,̾KigS;S2,_$DUy?'q}vH`nW]TvE'}BJ3AC\zߜ=eYLcҁt/#x~ESҹa>][(,λN燢6CƷuSI;F@P?b1oq 0NNN!]+ lg0NZ',(em3{-wt 6PKq{?v:Zmeу ?,K-]Gv:7@tHo?}^sF .@cj w K4/`#VşglEoU9zZ:tf#=Y^ ?姺w߾+M{}x߿Q˖c&QfdUF)pBEwn^zdW[ a@z>bG.2 WF+y&wuwE:Oܻ~)mVNWΉ72gG3B_K\72Lgi螝f[&^-NfvY5Kge ũ>;[1u]A2JEO`x2ൗϭx'H74i865 T"퉫Z} &2 d{+p lO eW7nu1>XZ,XU쿲p7u|s^2GG[Mn0$,KC {Nφђ11/ȷVƒRf'$Fͥ|qW+C/ORAȻ(hWT1*8F'joZQ `<$/Znk6edw RgB$uZI$Smw^mZLK?^,R??2X^C`D1w FMvM#(2NȚt>+g}AӓtP wu9QGRY GɁrTn;g+}K'PIqyK%c;|X0'h`[Yt:Rf7YDo68 Xh+7=[a#Al>&(D3yr/B? oP@iP8 3~'jljA`ieߑΑYj xtA26 `Eo;"|WWg{-8=-3{KoB}ߠ}cu+ U[vJpC#fUzo~3ye{uA= ?0Нd~R l$!dӿ%M3SpHA3FeP)ɷWx1V2ڲ}ݫfBVQmaOM R/o%R]Gwl>.z63|NgcNۀ- +>/;!~/ȣ+e'ϟu(&O=ءReOhPTe s#0,MTu[w߬+=lTvmfeߟq8/2 wmPW("g/`&{&eoa $u~1,>3aЙ3=Z"-Q>BTf)a{u4H%>13k _Ɯ@,4R+8c9fg N;5,sK)5mn ty!oh>-@y}?!>i-ٳ~Rɔ.2"ʧq>HJ=msZy5`!t 2Tp/|WכōBk.{4N>Z?A,ͼѶe̱[fAo7Ɔ-'WkZƿ6\ WRcI~t,ABYntrZdϗxHt~ŋަ+¦̞֚V:R;>w?i`lAh.ӗ{eMJK1=bl]9z= s7=>rx1 Rڪu6ŶvWsg?(oWWVN+} Գ|elӁB`sH Uo5b9[.ڃ`Tfm|zڝ/6yil:6N|蔎O ŗQe+ ^]d[ge *η~tEu"hQ֛fȼʊg6{6\ZM(6 AgA307뼨1<[2IpQ1M0_VVG٪ H}jn'c3⾙$7T6o ){(NҕS]hゃ:2R!Vb{c Tde`&c`Lrgd~3m?7)o5г 3MUƬ>yдʺmt| DgifgD8>1 RoVD#&hƖZTpDw]ŃyPп :]| 4CZ5+fģa*[)íV|oPc(f_y,'zvZat%Rr%VzE =ثɨg [=!07B9転/+e] >xN.DF{`ehW)(3(9x VTo & 4H֡ϛY&_%8Ν,'~:t~jt 5TK=_L/(+םfUg= .(8u[В"ِ>j㝷|#7te0^\gp%"UB90'ȻoV''ohEx,K4m2Z\CQ{zV}řMÚoaG xF*Mރ&=ZQ^xeN&ێV2iu0XՋnPEƉϱ]:?O{F:+!a>v?CeqZg;s2傠KyB@R^X@-]@%ur XVy+m?ؚSV~9IkFy7zr⠞ݼ߾oCmt  0 {N?#Fs?'9dbdL^L9sr }3.OKΰW:;p䑢 $=#`W!GeF 톓xt2]٢ >{U GOIm FZAF`]argyg=8hT'<5V8ɨ_ U {'*ǎMRxEM_}{xv]/}h?ޣYo.ڱxա2;-o?Uzs;Wu^hVK{%`u":=<#/o<6ܒDC0y!4+=Kz 3=zWyYþl;0:8CHiɊ`Փ;3_uTO+;ߝz<9Au{;wo~}Vp6׽e G(؉eu~d"|"`wr Ry|2O2SN[_^uڃ+>~Ѵ']nBUnijYjz Hb"LL@ebi&!OחM:hP+cvBv< 60mH'KX'3Zt_џ &  o xikܽ.nmtoeP0NA0 BehhlG,gq{_p]PcF!C&6 2RN#*=<h=me`$L@l~r@Y+p0O;@$7N'ܖA6w,̟xYF5 FBo ga}9`!1r'i>NֆWN:=t(އhQ%ǀr{KPOϫ# |:OQH]Dv! -0Z $EW&+l K} |'_}#k%Ad,'u!3HÝyF~ݿHFVT}pGf f<ڡh?p#g#rosU#G>_ҧ8mgF [)M׽t&BX/oV-j3z#yy9ܛX ߽iغNI/4[p?~x97[aֳ?Oa$1tNytt~=9m{SS5=ۦ*W8N`xCAVz|;8[0%A<Q;4"r O*ZT?ڷjh:'Y K{yBXN:B69Q麗>ps}K DOU9h*:+;mFc'n{y =>RAmu[I[޸W=7NF:)IZ&pr;~:쏼87Myn4!kcl|?ePEg~v&)p;u;zۀ\M۽~O(-:aAXgHGWDǩ{ҿ`-"pdlY#/y^X/ťQz@^ʂePkUD/'-m&s}N]m c8/p+̿Q(oBfx?YCy@xMy2.DŽ *9ձo P]'e>dUv[Š5=:_k>־\Ut>'3xBFN7p0!ٽ#4:7c t,bөYޙm0_Ԟ4k ;=ڎ!bgDiJgwsz)&kpV͈{zBX uꇺ\m_Kʾ݉f+{<IGmC!k(A-5-@II^Y}/_AQF4ōvg\7$op;T{DOs3+h- }|TNl4mW[J$6ُف^G ެ>t/ܣnxU,^Y@.V_`agfJ&wnL4N]sXiW, tU_L;@9H}>~|iC:6EU3t͖k#8Wijv|u 7#\OW=~'?;G {*ٵBɆ< n,V8>SD|yז*+h&"({ y /LѰsgڶL6 A8nY1YzKꛘlيhxAa%qCn.}zmWs+E6:5T)׎(F&|c rx8yܩxв`RA#`A\hcj#,ʽ٠2Q*_u-=Bcn?:X)N~.r& (GFzF 8k#sa(,҅| z'w[۸Ȅ a/AA_J3Eh TnZr- h rQ+WiFݓ]|D+ Ɛ:#oVImPÜ~\lM|2<@%:э|5X[XP4ҳ-?}пEyܽo d(fC00EvT[3w Nf񷄾ӻ preiH C?SNr+ hFs jR 0=FYŬNl7S牀v!9/08?V%|GervU#, &L&7KꆿSn{ _`$#g y#rT &ޫ%:\M v`|nN$BkVKT"%D~<ʿ@^1* Va| DG>Bn?u}8J /= N5LPw[Z)!oSp@Ap3V6*n%.z_rǟ&JP\aIǟ;w 4E+?ꊷ`nKڽ!x!4+7{?7@޶N FȺ`1}1O tCdl+NLz/ ;ă]l\pWœCF4sp)->Lv{3KG~}*ܱUrG}+>Rw |qo=X;y3Fda! ћOn5>ozS9,dVtm:ٹ_d$c<oS3@穓 eY)Qi3˥sA`{7GmnQv}~YdS3Z(,gʒ7L+~.p|ꘙF= SN7z}؋'ƶSѓu|{]>K w9s.pBq :79;dTőh1r*xSmmV4L o݋_tetdtL%~R:~ȻVB9fi@="!T"z2@j IDATy.\z$ց[zwfP`q?(]˷3@nlrUyʺJ̨ÉT}խ,bK=#{fG8$Dl{-->O gcқ]Ȱ7W>|oT< FD?A_6 B >:ÿW(YN..>t^9̉tix"/6 KyhlˑYvrqMaLr0px3X3i&R^<ca?+Jo0@Gl=x8=ڶ;5Wr\aWd|9#>8?:uF#䟼A}}J=0w|t~eO 7 lhBv{˧Y(@ᒟ//$Ht\ϭ ȳi{mvt^n"L:z_AhYF>}~Z/\GX'N:[SٟN'ZQ^p(+<ÛGnK@_2nqɒL:LsI,!.KC糂GƓKԉ^e[n*gV,4Vm)y^o'Wn!:lh-^Dfe ttx?q.Tc>3f+||g@?s)~\݉;sxSQtd$F~ 1h<~x=7pM-;._Qܫt{@Z]WtKwGҁU?upW5c\P~f-y6#-c;ϕ $MuRP J+վ=3'X[q@WЎFڮNb?գ hN:/m}[ֶlg뗄 G~Ytʾ^(q 2}_4:v]!Q eӠ{܌ 07~HH/l{s[6QcKCzu< `{ GIO D㲬C)r#?'޳-]8-. ;SCCʘmspd~mnH)÷]S>x|?{o>~р7VțG^v!;%lθO+x;9U 4p1GEuU|1b&@ɧ?~ -rz~^VǴ\d]W4g/v`O>@O]l5`Bf5zfW1mqo}0/& |F|L5`*{h#'c|ǽP!mF4O~J'7?Ms<fOe@:{>W T)56N^%rd%E{dֳ3tpEfEt#=r=|p%r$"W@20tz ? 4XwV\d4Bȱz^-ݡX#îG~&|-'l"S*=zWò5ްʾ'F  IAQ:;“EYK[V<&_0u=m$utgAsd?VI>;ZE|h@=,CR+<7f3^ lʧCx Z/\Og$ǁgsj-J*䆋24Ӗ~Y⟌7tae֞=[ۧ _g\TeHvxeY0BW9?._k@!mf-F-.QRK ۳yѝOFl3; ]6{#߃Z?"<|[OV"AS.@kW|6Ӎ{ q>w؃;Ta?IGf9j%X6wi]WXfuJpm;peE#<6 pH]>@ .~+a G.% T =uW@ڒx/>X'1^in*n>hOUd/k?odL{dU с7$fN߮7ѽlPv >t'{zI=;ǖdfQ83&cr&̓iEg?+M4᰾.S&| ZC' (Zݩn/p!]:q;7o?n6>Gbd4ή~Y3Ae߸[I#tOPSW@c_O{d\٣|9EN:-d_ ]:oY:,7os":ouDr^w:#7z(̬WŪvuN봃5ɁܣyOg*xk,䥏\`3L@+90Z^m;PzȪ_㍭,@d'tL88%M q"준獂MGdT=O<~85<:0t;9U84ŹC CGLc96x We*s'/<}? k|WiO{Bo4KЮcp-VWOZHG!]޼u==ce/9b<_IKW>]m2w;a^߈Sيů˗J^ =D7Ku|Y9w:UǼˁUfܻmvt "$|cv*RrR*N#ز'Q-Nup?حӋO>ݗ~tڎ^𘼾,0 lfqNv~$oѓ:g:6pLI;[|s[0_:y(w ݼCmߕ`@ \e+r:٩< NP@$Ȑ}t3,3+~ Ĥ"[[ hGAlGr̞Vh ڃK7 R S#;ɛ&/AyO O'|Ngr)CBm&GJI/ /N/u^ɩYc؟2Ђ{}k/Ϋ,GGIn95sbme+dyzbg}iTMsʿ}u_<;noeKB'0XG{SloN>oµU?ef={l,K̗/tV̹6iVH :uUP78YnSRIL[WJF.}9{ńtDߔGEc|i+jP?+ݸ6'LGoxt_ܓ-},z3Y3~m:яtD :;vfxJw[9+}{v礁#C(g //[1%@f2HKy_VM}jIwptAGGjToy:kY"T,sj{8nLxS0r"\q8o/]4(`ס=jFaBxTj%}\W>)HOAt غoE|n+p)SGk3#ߥHn4N~< [֙LFAܛRV%Gv]c 67}΃FsN'Z^ZO$gr{ȥήB6rmڹA:H':m$<ꗲx\ǩ#7;2s޵!h%T8$VFƬ\|L~ )g{:nTstNLY#ojsvmel0>{m`+z_t76ymvr/CwkOz2K7 - MYOK`=ޕAlɟ=ʳm`+>SI6awꩺP:f  =ٍwV5i|z'u9Mjq65ɏ*g5>Z*d$<<,;y]{?cEYqCٰYA!}y'me~?8;`^?yEzO$*y 4Ո`ߑw͜9$L՗oxuJ8uwBS͡PgS(W>/ yz7e0}48}*G* 3hm/AC:i*<6NmCWz#,nܸLdP |D5lO: _.=rL/[^ `Yʃ2L"9z t O 8u˜,~fx4˭*wx8B`ic{iϔ-Ot,r^Mx=&a4f<e]BM.7_[M96TwCl,}sbC߂U7`Nt3X|`~T>U>`h'f1NFNY֙u\PNQ&+y]k'; ~0邎 v:Cpdz}`{(, _~O&@~H@\=>=ϳ vsY9ֲYm5eѧv?VHT"^}uC^,ȸK;+RNCxioJ>%jd2'adQ>S쿎pCOf#وET"KI1Nl&{٧u'tU'翜}Rɨ^uÇ%6%,`tM85kUuM^plo[[wu>h?Ǐ.UG=xL76,> :ikcf0|R,:–ݗ/=L}M9S^GhN^ 9qޟ F]VsW tu ɠGOh ?Noll3p igvK~uGÏe}ϺY=|$@;nuuM~+pY@a  |'±`pg9|RK}9ǧϒeNE&X>~xQ+@\]]E ΏCP{VdY ^ش-ۡڡsh}L6g2$50ȃc5p {aEe\t2&5^!,_p˂\h9 vK_ xiƀ zfkى9gK`oC-fy+>J ؈҈gJEWq ѡ刺:F?ov?yg@hm5] xŁ-|q;KC`>U|+1T V;Arx `z0Oek[x UL W~/^7yn9Ly8A2?aq3x [Ymrx& nϛTi@ IDATѱtlTsQ.G!]z) pÀ軏ww9vxor$zso+\OZy#<3︝E}Vcs郹2K#b]NWZ \e:w -}:_ur)<>h}Qs}9xhOzHFKvy8e;G9w}7rARϬeOǣK9_W _ч,`LGkީb$%H:}2F;@>T4wHG+?_r]hks8a+y6hɻ+ ua aђ6u^~u|9`Y_gH UO_;_X:%[-UFO_:MnYVOnIPgkϪ{Z+ ;_;uTk'Z:(f']÷3CEľfYux'=/G'6 [:](ewXzurhwnsdvVW |Y'qD7i>u@әL= i@ecue'F,}/ΑW 6\ L2F)}o d\z.Πopx\G2O'M"]NX=-Wx_QLI'UGA RA004٢XY>N4Ebڅ}1|`L蜠197w .)K䍇د>{=fjϞ察MA1Z꠾Uϭr:Y; u򻗯/Ѥv']8I&+[؈/gg`Ō5lA^?<Cܟ$?ԓkec `ig`v&vi[U/%sHY6]'&]>ifyR+^S,Ř0Mt$z;3u+| =sT9N\mp0 C'FU9͹"%ArYRlʎ݃\㨽$T~?(E<^ˮ0c q]q9"+_X VJU\҅#|t/aQks@(OCk đ(ХmOF˛8T[(,cpoM|>sʓ|2p^'nk>2,=֡Yrki-kz60ZXg`D &/@ oؔf4JF;-:GcDuAlyo۳F iry_CY6ohmbum|2׸ &[K?xOg;иpߺO8^AWߡ!>%9]X]Ug t~v;;'6? h75Ul3#^0췺ECz k{ܰ1m CsGy?ڠd0{;<`lnW~_>ௗ?ttBC(KnG(ڏvcxñ4 8<_du#=/xb맟{@/E[BdX{:]#S{A`wgfN'2yéw-x 0T/40!WT$^0:l=#6C>a fu #NՓGlX\Xmx3urEco1sY=Gi7㳖’_~~ʂv봆CT[8j5ugNweptO]QJ^_2f]X̾'BewRL<()բ _6G-lzw}/ .{aR>0gVT]M;:OG)my{ܳd4ʥ_< Fy"m˝_իM_M·ɣ RkٖVi}S+:RA| HA 6j6] d SA0l#^ZWl w;X='_xlaե{|>o>t9!\^+dVl#/}c1OӉg|8{mA<(@`g68+ 6c<x?r/ԖE|VR.`ߣGf ƗR:oL >5 &B=Gs՗h-oCߏe$0#V`>lzԗ5C+ÔW߻^~|?v9btjAiY'CZJ!ޣ[*8_'~A*e7y>rnr=S[T_^eg>!7gO~S>ߎI+VT_&ЛaLG%ϲ#_]g e(5En%e@舅#3׵gt$ނߦzl4~&ʧm6túOɤ?x'V!>8h]G{Ҧ~_ӷ\5 Q;J:NY,vkLh/H: th=hX>r ѽz^ R|~-\}Ukt;W(?  t{ףx .G{-#e#@`EO URe uOZ|`?{AJ]jX@.X8w^V:4@է}PE ?d v؛Kle$d ecy:< ӳOYjvRR%F7ydfy_~WV hMm]1)1A7ڴ@|k}m~yjc+ƶ!ȿ>N_:2ftkg~~z6UY?M[sUv˻cN"Iwf6W^n@'?p cK7^7?_m[ՙW'^4nվ~1D y펬^!+abv[gm@hb߷SDDrk Ja4v^mWJט\ZJ.ߜ꒥^~E0%J*]Iv~զ\Թpv^@~鞝Sϝ4ٮ t*?~8`Vw<HI : Cjј@C.>'BGusNiƟ<'!f3F{x }v$+Zh{?X(4Q!I΢3W%)*"tE8J_etLHv<{cIf79Ă _)¥×&r7C~c> O+P&\lo8rXA]~rY] ?KAg:PuP~^=sS)rG3@ODMnle|㨦;ѕ\N\eNRN2}v MI'1?_  xnTam4SOW4g| `a>w==g:,9zP."bo18t)рNEى#KI0`o#dHI5^(,gdfB=fKNہ?NukA@wcɭ?EOA1~tǞt졕l]{Gxn1dVβf?؄ }JE϶Q UEO(D0g'bE;guF:KdП}ʾjsVC[lO,,>Q j?1A75WB̜H4u-3GW )+B]HNPOVEQ$(MUu;ˮ>r.t~L9T:ӇӲnxċ}+d I߷^sѡ1κZGr6׹OƕK\N2`zOG}vaNO*zK^C2{ Q~tHߔfd.7\@bI|* Lʓ݀uBɤs8`GਥStoûU*9*/>+MOhdK#uCLSYC߬t_+ (>n9O`unkD<@3z+`Z'*3gU0ttWBzAa; w.N0F@W{[=P@tWԝ՟##۝Y;TX3l^`³xxo3տmꄴe Cڥա|wؘX :[錝}BMσ  vF-B[ƀOz{%hfkWSI1WWw9o>ڳ/ZPÑWSgm<Id Yyڏ |Ӄ?ʭ~T{^,WMG j9k{Oav6;O(9['te~}?n9VXLo@ld<]ͫu\(Hm e7+mzgңƶu0{?AfKsV>Q0FZ:f_@G^C@8(OM>&(:D3}hR i78munא~>-0N`Wԍ: kOgqRX-Y:%r-nCFwă7N4Q^6g3XזKb#A_#1 ~yd]cz kSߒ-OV7_#`;mN23lZm: wLWzˋy6x-K}-" P(4xvD2>}uvg`iXp4gϑ_V;#8|׷7Niڒ3UV>.}`6*{5c`\=WjaC3gC J^2bȷ/tlYSĵ :wk?B^6ӭk=o~'xࢵ|:~Fm>Go%=2ƈ]A >Ie|\x[;P0נcl7 pXXUu%g~'.k$R([yu(?~aRû=_ɪOg6>#w>i$Fwt0 /t:&w?ͬ G7=_Hw'P|-$t҂No]zx}#v W_ äɻusA+vF#Qӏ`r~xdTv/GFe9xfSKˢm|;( 78 ;..OHvy '˧}2l-9.dHV>ky{=\uѵx9#(zo؀^;N^w`FNU`[&~t ?fdq6c,A](N\O'#C|gY* OuK?8XTՍ A Pfh/3х[?}[Pщ`=lIBeiKCBw0dƈ>an|.r7$(اƱ>Y6P!8Xo|'  J[ܽ H~0u 5<~策/H&w " |;zWm,9<}R̞ Ɨ]\\Ut!;C>Kkkwis>9Dw(2̦wk bcf  /˴4ԷvmdQ@6OB 2%6ҴE ~lscwY~ -`>xxA 8낁_e?_g $cxN8x oo>,):Jϳ&͎eX4xEgϫ?~xx ^_~>KKހEzVlH@~D}uc_%L`[(<'-1•--L^L|(<+*AKCcbxM95CƤ@r)wMcá/,NH59t1U_wIts5YcʛQi,)7\I}?;'r 5M#uvsEt0=9k,6`"y9jy%cG ikxf9o:JBt|Ouz:t+@ y@GIhʹJ3`ێMI?=G*p;^cJmfv74ԨN;6: \;)Ù3C{kļ  hlyv3;owyߧ xl;Q 80t gņ =5^GoF,_Ȁ.~n;o?|7:kƒ>:i|=pe٭N']g{A_;p5#>6Tmʲ=ի=ldӓ?woctH_ݙGxU: KfT0<>_P_/ʤt Ww`u-[v>i4!lb6<6#񡙏zfxW9|?8A+f\ | )Bۡ`Y'9W;/9X<6|iVM [y qxa;<}^Y2]z2/ *::J8^3V/ɥ# VRXIӞ^*ٺ6uP^?z۫AN\̞NpOW{ni̪EOzV1}+e3uK[m|kB|^WwU_:ճ_Z:]_}|?lj7o&]4(1AYm͎8;{ܓj VY}c G}dL'C̞ c+_8>7n  L5b*eTmKPP8}ҹvPG/9t'Xm_5P-Efg*pǹd>06?+bz:8[gk$ـc÷J^C69|qd*^LtNK[?w@$ {xyD-PU{Fjk\zlņn[MHc;cvhx}շ=Pڻ&d7ԫ(}l'rfnlCE]uv4NnvWJj:[r*  sHet7ݰg؆/Ox;l("zh-x7gu u RZwk#5fU=m7\ڤ`>+^ܫG}򴡥&r?]=L 6ӹvÞ.` L/NAd:Ht^, uԙp SDh >h fD_|<mZa"HUhUnsw_=ixz6I28y4z=:{y^PG_;q92Sy\&◿fזn6\!'!3ߛWGt~2hyx:RgȾmlJ=?"u 쩘Ap}u.m1&oN:uhi8،Oh*c*&ZNnx84՝>Ś|V\ȭ[ɐ}w:AY"NYFkLΑ)(#u׮W<f[Gu[M!#>" G_縲H[GݠOYT%sV!խlLKff_ۚ6xGx;ϟx F]>l6sIͶ?8Ho~b%?Efd|,F'h-ն fTOivNf$`+E %<ډv3C8? d'}&0P&fڥƁy~0j5: 4#ʾe)>ǾTO8j7yϗWum7yd$xV Um:/-Z8V|qJ,Cw`lkŃ44^D+(!Td]<2|@77䯵Ckm϶ӮRŔ@heu>yiv} ~L8[ w4ջ;9" }+6?ӗQeoB@_ `^gZV]M'/ղy$hcV?cȯgD>Ø gTKtʤC7*kw?\[wzۯ<_1{!_n5}@[g[m_9/g*2XH.+K $ ɯ\'B°뤧XH/ -]0,{c0ἅ1r-pdɂ{@M2'8k ǡ5x8vuN&Ot#oqx:sl[&%Y3^2LzcF85[c.h D>2ǔv~o#ʑ8ʅ6K쓻| S`ˤ N)O'yvG Mc[tP,d/KuF;ɻc886trn; C۱UP:SfO Wf`wک ] Uw듗_# 8B:P?x^"|rmGF q>!_JD5|Ⓗ./G@Ǘ) WA.a?|uKv6%e^i4II9[Y|o {ՀICJ `%oķkA%AFv^ٲ$W`nŽ66|zs̸; ,06.\&OZ/5lfIڂkSNj6ݡ|܎_@.;w}5b-pt/a/i/J>g ŸL::ώJ>cIz/[h`׆)vO~^:8xNԓ, uj8HhSړk/>鑒ݰOTOh̀s|LP Bj [edd&նP=f`x{Gu<7wm~Tm A߭ h*'W2_\Yw!_Xwjc~$t7}UNG8dO.0}ɣ(Z->t6on:NpQfŷ`dX0YnyN[G\?K_%WooCt,O8^=/?=MmHx mgO:'Y1v-aok#̒:n;֛= kEe~4 suK{}Lfx v]ȑ;Bqˣ^ėz}rntl{'GdA?92]SתUw]Yxs,!ucȟl l\B|# g@~b4  HL~tCgty!\A#ծ9ݝgyW6:Q.DfmVtfU@{p>o`W}+/~t*o ~i6m?mAˇ{*S/әP)-SO &lųA_s0Ui;mF\F\BTF￞- @|xIv]] 2FyǹLRz2ډ{݂>g#GEA5Ѫd:d _uR#e fռ\.xGv*Fo)]4HN.% nRrOY&hyt>G&8SFC4= R^iO^5~v9GlN:|offӑԆ Uz:.hr7z!Ku6K4|tÆnqAیg;ޕ a``.G1|3zſBx?:2+:闎V4|=?= |rN0>Ar7+066 ݯDAI7%NS`̋6p^3_qFlGx;6uw{pwNnKd+ۿ?s8C4;* 0Vp}Z?VU(c&N3]/;?ۖz遽Mԟ̸zc~f ;mX IDATFey騛} &gfct%VbZn>t£PL|>'a%?f/1ΠuYi_LC{_1SrTFڝ:'P@%r8][G _Ɠm0F9U.g.S+ѩ5~  Y*s":H?E:O%Yc@C6Y^8 KgESZ%ИE oosC7^&{uyrn["QQ_w=D ~l/ %Fclz| ~1s?Xŗf+/zre( xo~UC $ǖU6?S|]Gj` ^' P9ewE!|-׺#3nV]rl>u}Fs ;gM~l#:An9|ʾi ] ||NjzAMxy-AP૏q| /Wg,X!0[&^;U=_꠶l3᙮T_Rk d3PYsڙ< Z| +x_{A+~fky|7(st'#|a?^F?ѧثqɟz&O]ŊD?)ODm(U9%7 &]lf4WnэM=Oa6 >\h'miw?'7d+r=_u;6aTL7w_d?jGu pVk?$fgC?50ʉS6p,g`ZP/.yD=>w?a: y,NؖnS8@McÎ" %Cg΃bLhi9*h;:ӐN*^g'0z#_,o#A|wW@5~MƹBF#bJǀ]a8iARUӱ;T4o;xyف%:O}9 ]Uɉ4ɣW)owInޑukl\/lrVs%rJf+m zu d>gv}aipfޒHt}3s/)8R.dYEG~rv>thnеXex褰ݑiC$ٽ3/ lj8oF_zt4_W:ٯkwmSK|_<ۇ oOL+6!w2yh}bOc~W+O]"mڡ5d}&'vPdh;#N}9-%_#oU; db0̏odmhIp ;gώp坥.t6y-v bVA}׭Jկ/g5B~DOunz{slW gЏ-' g-= @|Zە(t#Mm&zN4̺m\pl<0{Nڼ iRwpnV>ҫ]?2E8ڤҦ7 :CM'{ğsK 6ֹKϞϮ%w*>N͉gΈݜh3xc{ŲL3k%ef<0]ѧvבru6>]]#|m? TWi1#wht7?W0`tkFzr>x(M]ǟ`䙒㡶!l9HoL4K?AL2Vf ܠfho{_DB<O ^@_nI0=(&#vňχ ߼RxܮH.=[xM~~!܂Nj GЪz9[`J3;|-[ƇNlx|AWN&W_hI<97ž^`#]X?VUbˌΞړȾs2pMd0>{@J9~'Pozsg (k 6iLwҵ{xM4opx{-3GP>Zx{{5O=Kt*MJxK6p%?~fa/,yt"/S]7|痜L^}|SH?Y B6||'4O9~Z9x1]5hd/Ցx ZtrXy3>7I@=nuv_BPopV%>]mȳ^g#Ǟds; Wug3ϫk[OΞۿv}KU|<اi;pnbzW8 fϪG7&a^}6X$JmU*yk Nl`cA|ttBԦw{HKTTf] ;"F蓰ȭAc\Z*ɫvI~+$SbڬXi`;su ]iG٫sޔ`',1чt&k ]_V3$U :ylJ0{࢝3OOwXx8n)#@䠛dm5Ó !>ٝOGih t8L_1gƂ/RNKy:M;&={c^J>$wzO>_x |v-(\T:Èp=Ǘo^l{A͠sih?>Ϯa:JB'эV'@ʭ|P;ԣ#) ^]yL>|m>N'<f"] ~ ;VpR 7uĞib|j8vimMGoBBe) ߑo\c O HwtEKl0 Th³TG!z]Xa,.6_:Sh P :ʅߩ{_06s,`-tɷ>=A#r/2`i'` h 8'rO0s%:OG>0VU7awHRUN{ese*zxGe|=m'6ʾlrʤ7|56|ekA{mAһBdr{|p7dw#^4/i_,YtUf7!%D[ ꍠw'![r[ˢ8/{fWp!>JѴ @+П Xv/~[Pd=cos+=|$?[ɧӯ":Gq`:3!ޱeh۸o`:S\ o-OaԘK^in9٩=F3 Cvʰi<^1hF Y&}Dh t 3(KfE$NOã )G ._ o{~rvPu`>>`#5p H,FG`+/񱧭8uU]:.*C&o_N2i~QcsA~:缂PY^4kv# |LjdVSQvynD>uXoѽo;L13_^}N{NPYmN{O-{HJG챯#1s/z(B0}">zanskDà?>{S󿮽4es=E\c4[MR=O}g9pVѠ v!gJa#lmJAp m6n\󫞹fO9@U[`8= 1\qr#OߟlnֿCڥP?w "#ʥp 31\>C9,cV̑=1z6YSj7K׺ v33Z}3}6S^9{] ,:Gpѡ O<~*@ Yp6]9M1mV m1۔=;Iy8.%xGO": ϧ2]v +btȎ#|8m>!P]e^CoBR8t:UwI9+ʱn4Da5MfHv2#p6I݁$D45PyWq>wzә9#5y~:oLp h386#coV|lbp:j>;Oǫ/hvM8K' 5=c7 lA.xڒ;;92 k!K&ctt.O񫕷YSV_,o[0w ͞~=,Y FrkvOtߕ|Чْd[p V/:@BF١L&LWl Z(m~th,75yH#>،6+×^LtBw|,(_sӭq ,E~WW6IS=_+Q؉IK?iuۨoZUf&TYzkk6n q^P:>u[8KL7 ~CwAi]Y S'o:"+n?o#2봞wcKФ#cSy7ʒ3q+}fPIg\n6 p6k&0t@wu~ʧެ( vd{+o~'3'T RlOd9~x7ü~˲OJh2{܌ϖl%M@ 岁S._mQڲ2VU'̦,ǯc,ɷVG_bW- ꇜdE09Z"|uhAzf͊SO&[x.uٟ39 [˂">w`аCѐ.F(a#9)=lw'@:ulрٷl_Oe/S^@@@đ'h: -7Wݓo6Y}r co 3<, ˠ: %p/as~Ha.nȮhf =HO͂8z ̢6[ـ¿ bo2>LOGWo- CH+>6W{;JG˫̨Uv[䞷 ~xf_Ӂ!t)Cw~SÀSo"~S yn Npto?zV n@3ESǖJvKޏ )v7td=+Ny|W҃<=t>u,l^v'fϬ6;'Ot`m~Pl3;؛'F<$ M(y_]`VwVlj?RƋL`-O2&*w~DG~Ձg,cXoŵONyN?i[0U!!x<B޻ܨ{ֆWtDhw/،n[g[:c`Nե_A#UJޏ}yDCp`)_\uGZ_ IDATOOݯpd pM/^SAG J?oy٥g#| 9Fcort\s6wN}ܪs/pg[|弫ױtn~NfY KYxDPe{V%_1{~8al;})PwhGWKh2=6یm>g77^%(Ob~?3C-nd$ɾÏF.xݧ0śo@gvG_ɮUY WD<~d {6QFli!V6S*qz+oM1YV^u!|e> :8<铂ٙlm+=(ώfWo@ +"[UL萃b1t=]8]I{F e/ O Zd*?ehg; TX~ґ*A7iBxdO u6в*) ffm:ܞxʭSpuL-W6NtZ^>b d| OGimF~;BGf9cyzt~hF/[zW||ƏXK6-aIž^+:tfo^*8=ڛb#YPќN#7d. \eOxtу^voltث hwx^8+/|6*l<pEg݌`Ӏv,R|-ϻm7 A2;Ik%+0@AoSH[?}Ѡxw˩(bt>AxVv=+ njJӑ]_P!#mRX&`s[<{t.:'OO:ڟڢuQybVÿA4Z{5k_}v^~N6 .ue" j Kogn?'gN7o_<Ͼ<a=kJ__iY`<<9s@ҀG@?-Ô-jFG]4قW30jB-]+RV?u3#$XV^rYAN { xd'u[?3W{bM0oi~2)7L0ꍕaTʇaWO_B~4^+C[ӐXZ_ n qH,{h ĤgCA0P1e 7%OÌ^Hrڗp_0 AZ 48CuT/rm%9Y pmk|GjXR~ ! VS^rNRsɌ>8ypdЊw*w  yw1z=y+@goLu~(@3wuJ[W]G;y?8Cd<DtN+<\(]urlIr4* 0xhw EW:?Y|N:2 ~c8Bo5YC:DɜM?.8_f;s W_πeN-K{=ylJN+3 56o~F{ѩuW&I.:`6W0Z3~CjnHh m:^P<}&GY>,*d| z/J?aUgbz|u<븚^^=A>oƿ?EgK1/'vw>@p|q;?Î2t xH&(%m@3jk.k4v5)ollOupޡ,ߤ+fD~V_?|p::u"]mVGS]h2oЊ߽zc2!JpT,gA|xsj~u#絘pQk~Z郝C !9ɎN-\d Z/nlu6KBt= Gp=3)O FN4?P:a>O=^}2O`AtlR6A~Q{3ػ%[ HR?;w(NG y@R^tZ\GY聯 Jzf @l| g>W~vvH+{^; x`YxX0pyk MgwiUF) dc=۫o_ ՝ud7Jf3K6V|1ߵ AƏ逭efAU 8h&[ Cx`7p3C1oo>L~>;g݅߳.8Eԛ =ǠkD,-Os>HQytozkbA>u:tI w^::V :+ñPnԓI7R6G0pЉU3fNqlxYF_E2&>ګ g0~mC=)3W ❭w8I#dMMYęE.5W(z>R|XZPr|/pdH}/u*O)KqzhNЕd>- ]c{Zp(JW~ nFtv5u+Å.pZEk$`-؋I/fu_(O6r|ǖ'WMy xG최w_?z}?[YAa eOin9|B=96]`˱tvF)K݋u/bQ<]$#tʰ!j? Cs|v Z@6a=~(<Ȥ ̚)$r1X+<f*2<١+i]+;A=5B.?_K;>d5Rɗl$gfÞNQro<\pki8 (2) ;C:-_=~Bl4L`<+uգ|*>}wSF9ckee%W𿆉<Ҋוοqǂ"핽UV5v+^\:pU'x3lk!<8Q?owj)ݭ@Y\QOq2gi16O{3^A-[c[! O pL.x,"o)\@G™Co:jqmN>Nn&o#[q3t%U0]&~iԝ]]c_'Naұ\Gl%a'ڙp3hjV^Xma :ژӥv:6rȂ@fS =~Ҍ!cw ʇ?z|==nN{?$vw`C7o>`؂` h^-;ƃmuTgkb4?Vo T@ iXS>?@=v?8*$Y= ((S|56vm]M}MB4`[Š-gf_&ǂ!lYi8yR} v} q@=KwV"}sNV|x2Iq ,xt}*V̇M? Qڏ m#}*0]Z"ݫL˿`]͟$ Oo@Cդɍl$9pgn+:x:HƤ̣=cې\Bߌv?vHs|izw9e{%.xRwn8н>ˋYs|Ct9X'π򔗣Ȃ#]'z|$ ^fK儫th+}ӿ>) />ܯxVU|ymTM޵/^'4WH%wuBǏz1F=d_ZXR_Q!zaqaA8x'/;TytXzNaiHUvɵ<+puW!yU{>|UfG'VNb2b^~"N3!O:y,z0Yu,6[+N#;<2*8MǗ75 _= q:b4S4M_g|' ';FGyڊ &{?]wꈸ+#y&T·+o-5uW76ySV ]]m]ktu6{?`'6̦_79S،N _~7^|1*N"3ɸgl3ti3\=rh;Z944KlPg)zBp;kGui DGmӖKzjȋ'?"lGvs7kBAD{}Mⓞ ~!!EU2^nЇt>z H?ڟS);??NGv2ӹ.{}U#'3(feA ц\PoHq| <ɾ2oSjGzzˠP/~hK/V& x[z|{Ar`Xy\NyȲ*˭-mNtM_YKv+mvq|һ`pLn?v6X%, _Z66tk׶Quџv/y?kr+*9^/:9^# *0|CQ 2>~^([e_[M W_p:.N9ikIŽ` e|uGwc>>?| Q@lsmYgM.pMN*l /gvv1o1v?ua|k'wȧ#ïSz s*=GشujHGgFLuuJi{x.NOaW+n⋗?\^O> ~Fq0<2a7v?=)«"c_|̿peg |2)!t%` \.cO ;bDI:|4̪ocʯ&h_2*kS@ opq r~3oG ]Ʃ$N}rU;ߑ-.;^%0 lcuڌ({QCͿOf< ҳk}:p=}o9n!W- 2ȅy@Ox?U'̏wFb@GbtW1/C6|. \WkKV+']{˿̾KG-OC GÓn7-]xH]_9 a/6ucz\[ <&>Yלߌf "ߖ^+32\MNĀJ:\;8N&^yM>av녿s:RkGZVK%g5ݾل@IY 3йoYvҤgXѱi $Tеc .gt=?e_;XKƝ)-+68@fϖx-{';[[J<9uo%i<+{wz3tof?{i+xf/L}tګՆA(zsr L^{vu=x k/.M+cGY\ H/ RRGs^Uh aƁj$>}QNnA?zO}-x.}|oЪ;|]MVZl?z5,g׎fe7`ZXA~HPݽĺ QtfP^Ϧlpe>29*וî}^n僮!=)/zxa}+ά8OqrmANFslxӯs8A}] IDATfWkh \談g/Wn`,_ D3>/{nʾ4.3Eh)͊5yNn3 Um=)8<8g íN1:N^|ު)_[_ff6o9%`'%b¬TB}S)l9'ǿq )bTTNV3:E2jôm6\g.N928#/]Ǔ_~X9\gCE_ wԃQzv`ѕwp.Z99.qߥwtfrX V𤂻蹞#Bmf􉙳-]'|'wp/n8 B6իHuGۭ ճo'Y =AS#ܙr٩/9g0e[|`K{1]u,:_ANNG&wJl }}{=>^:3n u>MVU ~##rGOG7X-*@brח_׫/%Cs:ZKԓ؃Ⱦt [ui\.?e<=\ec:;_:ڠ9%]V\> ~RE_.yl6?$>71:Xߟ\ڪ1 >3ϯt|e:\ۜZ|ӾsNf\? O^IRra0O =Ro9=fԕCI(?lK\'ꫮ; ?S'xdmx³-^[? Ѯo^oJ/ M`z^~{yb7$#~6+GH㛟\ "XP0;uA*zSfz?; >h>Q$:j9xatUvBO8P.Ɵ+~r3΂Q>) 3+kc WG)ٞvg=⟎+{Gz.o 켾aYwwWyȈM/ L?tkoUDt> }Rգt钀B5􇵇W9gMϘjESe"zrrGe@E2<1P̮$j(hrNY'+8>k[)ה~;y5z<=zw{/W2u:!G9['HG ~dW()p1E -S>_ . 3`K? }x9:^:IQXDuKS\'?+cY̊ݝFxTvfDAQn[HwA~RxtRG&BǑ!|9 |:CWidjD8H{}Ϳy52t]2&9o;rB.-mY29H6 /;v?\7%?8 ix:Lϫ;ݩO'KϺ} i"Fp7~#dvDx|g+F+W0Y64&JktLoW7~+UM/l}O:rFl;"Ũg^v}z=^G@'}O|NH'펻'&ۥz Z9z.CAvCGnzuKwnJKr^4>69)?l{PH3<$o<ب2l#5NjVEu6ż.a!sg[ac(iɡi㖞#Jbi(sy}A>|fv{F?1@(%x +8lMkg GLGۻ)H vq|_^6.Z縴_$t[T*O:mKrMyݵzgg\:s%u'N_hu~+[t6A=iłvA =Nl&S;o{n@ H V;ONt oq?fo(}tubv-N@џ:~vi!t~mw[ NP˳cҏ F")6{ C~Ophf֖GO0nO =lFvJɠOS bO>kߌY%ۀAz¤93|Vlp">ɰ7kkjHO:]__{v lA?kQ><>& {0+[ýtbaW¾է~2lWwՍפT  8}ىKϤ'~ !0;qs:O=7lVe;C LWK8F^R̀ĝpo;Cߩkx]Glx;SIi&*9|wug@Y]cFGp!WӅ39ˌ9}z\z;gzPEgN^}xux ~c[%~ɇ~Zg6-X>r+ s2!  ЖgLyJ[GгgKN# \[7L߀jwr{OFpL n3&utQ067t=B:0-4{wuo 15rӗ~K74J0=kp,`iIEW^f3:)!#i4q`l|AcklRGdtx` 0`gv_t[ȏ6= 7rKaƒ-lꋇq? σG6HG#qרl {);qb [&᥺]EAj{<+'ǽ2g̪M=?oQNGaKNY ]'O5t 1<vЦ׶.x}Rac7Z>WzU݁cKlL?Y=|Jqe{9<Zy_4{l^*h߃8WG4Ň#Y{*ݬ|+S!Lu\6Cl:Ǯ%:~yס\Y @ yco[g[:-Sgvh?J5;p$= ju\G.=Sݩ'ph),U&pgnMlS.,dpO2;uB&ċ=Tf=ۧcYT-JYe Lv& B/r.?Zl&eP_̏{Vj^sl if k:5oƯ|,_i/L xD{% q;gc+}>!gM6 g/{৖ѫ}ڏ>x_Q-G72_ڥ1J[Χ7@7SE>~x {Aάt~k}৖/gm;6Gw6-?8)'[p=MOeO~*Z_m^{x}ڵꏨ[dg|)iVzC쨞3xtV d٘[?OivW>OʔN؏2fՀCL3C-wX!R`,1UK ϐ9{~pM˨OШ ʯ`1l? бkRdZYr@#qO_ϞgIGV(җ.: 4XzQ:uзQ>Aw:gtͨ~O=:p4TGʣT78M_ dؒ[t$Թaɴw23Eww͖ r6Y|q06CLp}QiLP;|Vxwgsɶ =T_I>BnOeTb BYiY=W`F0i r|bGuxw&[KO'TY.vrccm>5|{g4:0;^c|/~6\=|:A.{{+dZ ?m$\'R:G>[RN_;xw-hJ?JUʌwrMјT#ڗ 4w|؜m|4> Z>hH'D]B|!;Csvǧe{%pKkX/es(Ihذ#o鯯WY ץRk;6@uGo_0cN~ӱXR?H;<#Qw8:bp7գ?N+j?䑠ĹlSF^Yxv2!3Yjw:/  d|/ :+xVwm ڠi˵ByVF|j]!Z=B`Y;8udKo'Z_'#i9dʏERqIݺNso/\e]ݔ:Ho¹` ?(><>/s_RKW$ ࠑ$?rK:g:Uv>E, _{ Qz0]vM w(DۏgCZz,K x;?୕qXٌl^ t>?,}roeŔX)Dy]#e U%Vǔr #6%r.age%z`Sf`|"'~<ѣ~_1}峲 }e>N-s|/Cèߵ ȆקLk_GH"/Yj3edtI*vĞhMK9;WǏ6ol~,qqV{#Ju0xvu>TV{FSGK_y'8 oqa`9ᾮوYy49:[SA3 : Fa:;rYKFbN[ͽ0jsYŖ_9Zu"c:4yIɧ%8ZO?6yB3&C/^]%߷z4p\8O=UJrG0qd};'˵c-] a6<E?=.!/OSD5yUx jt/ЛB7L:=T~e?yhLht|q#i7{_Gq3 㬌3'n}:_~ND#z3^g~W9y3 Fly/=/'а[ +xYsݣ*@χ D:H{Oí!RN6\*B6W.Xv碿j“^f'̡:0u_vV1Wp56xA ݡzo $y<ΔZ3ȓ.W pV|SĶE8xùх*YGk@?r>{bzD ]dCgZŷDF ^?_Y N1߷\zW?5xÛ/|6O^rUײx^I䤌K1y <^V^ծKiooZٸS#OկY3[!2D3+++yE1x_N]7`V{>' c3"rwNiR#)C1?e_NO@OEV]Gj5V[揹|rygI%fա+Rwչ1 iY:%/, /dc^XJA>+2]D@e=:x{23ߖg DtHrb$iNG=b-ٝuJA IDATWv]ςǽs4cApݯ`p}b5)ɹgoЬ *L'*c<髌=GK󎼙☜+CRWdk\D>_+Xzac谟yP|WFͬ.Ia{> 8n0c`~\w9=Al %b+8󞒛ZI#fEL,5_Woѣ纨1z@}&H,[E81\=m^2 wSWjeշ"8T5A&} 6iK/ti o# ؀(6PSd.KO.'%ϗ9e#cɈƗJ^to}lą&E=$AWȻl.+m;8_\y4YGБG]kB8`lCG4wQQdOs=+V.mt?d4Ez{gCq>U*6T6KFןŶYqZ*mWQ_ٟ?$4G*x+ђ*47_@;^5<a+IyT~xDώӯjbpIK.u҈%զ'+uA>Ȗ?{@_ QxGϋ$ Sԏ:{>ɜV&xDjU+,Hg.>@O#-g'@>4o\hAïC҃x{^&-#r<xE|F8$?c>\1T=w@.2' {5 -~֌fR]d(s`!~T kL.v`,QR' }OGvA$J}#Nwf䝏ʨt-7peK ?hI0+Z5d=a=Z"Φ6|<]O2~U=[ ?W6^rIf"^FcƫFouI4Qh%H(g6{lg^nf[G+`jOGKn$6G4ϳg6/85RW?W:G\t:* =-rvbאzg+uE3.Aq񥃶KѾsUG6]7(Ç逖W+ r-E+'%߻'u71wୃDOWzL}ALnJ:Ok:qK3`,yt^߼mkKu:D"m䶜Йdh9?y/N~z93!R3=[86;^Pb.sK}lChlk麠];2]YZc!Pp(;M~@/t<= Qf3Ah5H#}Nc'm3Iƥ ,EǾprՈ{x|VTõzEaK._eP\~(oOJ (!Yµ<(ORgq}jT~m#޷f2g` }uܔ5j&/^W'+S[^zHO]J87]:[ɯ Ĩ/f2`0']NU+jL舾-ݟ]z~/_k: xmvS`hOͤk(VldeztBt#9WXYSn-HUdJ.vi3FUӑ ʵ_`Fk%T+'KWN»ٕx mW]f3UmՏٌoQ :;)OH 4W{hɦl[pu5]3%pԡVQ_?ҿjFmC3:"+)o|Kw_֑z]>_׹?~h.ߋ7}$:}ixg@[6x;e~3<_2 ڎlЛzVS88u,gr#u˷ TFT~LaVvlH8-}RRy5|x{r"J-m.ܧ?2ԙ Zj נmoY,G @B*gAgvAxB[U߱of)H=-8w3;Al޳H IfShtȪDsrO s)i}m ʛ!_f^>NoE/`yWyXn g.;'3kX ?f7oÀ@./ }GgWWg+^;:=Gg}nWu&[iҗ8 8+>=*ǟMz&BP5lf56_EoקVx}C2٭W*z/0Lֿ<^ҶB1PO\>J_V WOV)>WZ)lcg CU}ҕx; 䏏Cr96cxx di2Q]}S6JʝD V|J˗ У ph&[ x\>5E2? ^z~6|^ш%_ RBWr=Gl [\> ݖL|2up_98O#]y6wtAڣL2y[dhJJ9W`J-~6|;wVvױ:Bx[I&:Sfert)X>\בq a^0K^~۲4Kn%e¬4}KpIx[ Wy , F_Pzf죠H^!3{ޞ׸>w沍Su ~!e/#^ kfM>|ת|;lH`\-まUW]p$˾k';[ ~7 ~^]34ݳo>拖~ƕk~y_3g0(mGG%{ g6?3?ft r#>W.T ͆0]F t/A\xi7:?/=\gX'kP:ZBҡĿt*<:ޝYX38و,#Blvzs?}o+ -~G ڵ GUo:ms閩UD_7񸁝Θ$xFOSQώ`  w\p7ex?'uEjvtY 4>mimې.f[RmG\rn> XȏE "uՇam6O枘Wg+Ovpcux28Wc x?fϫ#G@t:YLiw%YgŁoq'|G?6x@ ͂Lj~`Pt_d ŸAײWF&GDZ2Ms?}LL)W?z5@/a'/ZS.78r:%XBhWWu;Y J _|e=w`i`p0I/:vGsv%wݐ'fgfD\[ۗ/nYb&31aG?q>{i2{@vǏϯM!V]?_eu>޳RS'Lw01)T0zsp f99M`Ut]: pÖ"&t='I+Пc8\o6,Lt$_sPQ?i%똡Wd "ƃ~ u7ut R6?p* :+h9N?}I *]G^b9$ZUgGGbn [.?y/X~R9oFԶd}!~p<}4Ɓ^ O3j1ȏ*4U4crxK6,ew%h0`?s (#結͐۲nzb6Ɨr6΂DN[g`mpdX9`A(o@p [=iu'c+WFOio6]ӗ.Gs=?#.:}vR b+KKnu #i`*ֹܠT: ia8/ r܂Agf1e'czZQςS$fZur?lW'}H==:=,+`LuCqfwy`B`&"C0p; /t[Yx;E"9; jrІlo ñ?Ng0L~l|}GeP |N@0[:w$d Q`[T'8蛁AAAUVT˵c?lhEwX~ >ճsl+~Ct]wTy&W^{N'x>c3fYW;ŧ`H^TVev7l,> F]'<rupcҨ+`w6_J4P'rl2LsA^/@+艞mdؒw< <}5>"7ՑiuA7|/^7U^- v6;6|^!m=4PiCwߊ~ubo>]@z<=\Gg8kd` 2&hC:LuS7k99hu:>|mzL~ף#xoFfd߳tm_uNO/7uQ~Q묨Q /s _]9S h׎'K|j WkmM Po%emW_XGK |gՃK(pPZ?x KUzq _(3]3 VwiIY{1xRJ/}<:?utR(c = Gg蹀u%Ieyxx?AI ӿW@gT&g>{^PdN IDAT·dPsT^-k"Pym::PWcyQM/:ҳ-};Lw~弲>oEY|K>5H+j:e%ݵݢ3>:OhpjKG KiNsG-txQ6i^n[qm V7^ϗue~CcKBdSν> ?7{KMnJAGdg]G'L:/s"8݊;-| P/j|C8)O^٪|:폓6hE+9 PemZ8iV/D2!z17AlZS$]Kg+] :fo@44:&ڽ_Pz<뼅a"JSDgUх+E {ܖ'_tbp:`BcϬ(seV4SԟcCg>U|ֲ7z_x<[]6Tϕn9~Q<:{76bSý|xoa <<,O>3^>Ii*Nn>'>|ݗI}m-|'x|tlίmE_̏5nc?}o6Y"@ǘc]phye?i}p;+/#*+vPyo^<6=c7 $Kl-:נy]҈ ?5xPy&5c+;}vm9_ʶD6sp fR'{^<[F9M7S3`U}J!ؒ\`o:{v[-3ϭ,HVtmHhg[t? w-WG/(MFsߚ Z4Mcm=M>YG`o.x~+5(]:4sW&s8MbSQ۶؞+|a镓'lk<+L&p혯$3q,&&_ H FF{qKow;LcJEp1_Hdeߞt5T(WoDz}vTWOo_( J BLV5ڧv68Z@2o۟Hgg_Ų{} 5gr[i wO>X"f,n=W@%!yYCpY8 T1CPxa8Yx4Qnx@ O1..7ޡ0VШ@sZ:Չ< go%3(˳\zq*!]u^3d&YȌ9"ʮn!p->0{#3t2r1S߳ݿ,Ga Z{^2#Ʌפ#!}yҽ4%(?T\R,qpMv1e'KGr*W_},wi:GnL#v0mgDBF0XT0[V!'G.051x.Y,Ѿlo5#OX-S'y6x`7뼯Eq4y2`Fsث0TݳipatE܁ֶǓ\{aN YmׂN~:~lQe <1c3+.4X{tfjgV [&*y!>s|p50M|mukB#$)s,A/^d?9GVI#_@&]ۈ&’|p_w|goS /ZVf9)V4V/YEֱozow@ss$'9glil<ưɯ:H!:Wk!x?>)PC#D[a{馲plDy,_VLux"dQXÈKG募$T7٪|JݩlQ?d2IWYfe>20`+IG~r>yU_P0T4l'1>? k>V"8g E@Oj<Яo(m' dX!ݫ>suR|8:B`@KS˜`[i8!Z.ʷNzr $wO ٲ8migmw:B7$wt ""Og–'Dk в x5pg[l J4_rW& < 60d#s WmU& rb6;>?  ꑹvJA̖n(ǰmJgeaa+p;"foB#wཋ5|j1d.ĭ`idsrovGT~:.Żw?U[{qW|(͠r/}aS;B+|'|y;Dq6}h>ϳzS=5 ?G7la^|;y2O?ȱ I+V+>{ٵ*'on2MԋB ۄ\|ax@#Ft(TF74viE}y˩jw#QKG)0E7p =n9cMөt{`/u~HRFwB(o9k3!_Mn>kh ;t'6\>+#i.:2+?7>5.0JpZ?-MhŧZZH\u&+[a <׽$i*u"d9kz U|d}Z_Y2- ޽k_~4yN_AYK6+mwGiȾ_&ɯS[2nEתXWaeuzx2 Nna/j_S=bBy t^65y޳h>x׹n 39Jh&t|f#e%"70{{ "7ؘE<ÖQW7t68H}ha÷d(..sX>oy9` 8Y}8n({=`wx';\ vZngؿ93xm׻"晀F$׾~ll^Ȓ7QB$a_^"db/vu&?\y~t3`Oy4gcr~rke7=e;kxFolDƖ|&S,_e}\f =*2Q%]&9v$"7_MeۯRE25Y+o~Mձ>Ҁ'h\}WMF &1b/`lKM" ?-/(y5qV֔m7(=*Qy'm{CD%sW_PЙ(i"]bĉsB:C<>ޥCc/Y=bС >[撙}꿾{S㮏kKH&ϑoa*#C^p{x vH̄b'w# mkNB&@NR!|Kf?! >@"R<#Xz:L=Kx4?I&فvoA_iJKx :|cf;KΙ| Tdі:Y.Z jps^=|Ic6j5۩OׁG^kΏVuLآǽ+r|`7Fn+D:hW϶>H}%Wz8 r*8n)HxY}6Ɵ{|~K!([Te[O|_5DFVd+ &ѐ㏑\LJ'MzxSYkrMD۟\S M̃O~}VL{!/߃n~%)+:\2mp G.E؃OWPV'2u퇗 =5$J"N#G7/*.R?y g~TwlɃRχxgIMrhd엟-5Ce/. &UOT^0ȹ "^G~Eеll.(gx|ڨZ8Gg[x&ʳ+7_/_qvXz^ez idVgn'YϏ<})ZG3UC@1N,4 뢳Nq7ūQـ6PTV!h1Wy0c%^։W9 YdX#`(c μ-:UPR G;cX7sNa/^r8g _9ty`[t܀kh$?։g9Rj=tKl5NW`sg9nrs,jߜ\˻]32:?NnaWȕs``܋%`cKdZE:vc=>6%OG|~q鹠Gq:򐱰K45iqK[iЬ &LW)hcWѪN(ޤFXUٲK:l'Ait(lCPY+:Vjۜz@Y^v~qT籱cY&(FCNJ铁h?/e%]V6@?EcO#5VW䳊c<cT/A|cd\ɤN%>Xx){0;gC@at[gq"d*nqcoFZ{F4He墰F38zmog$:}L }Lftړt!1?X4 JK6`{zot`mKcoɊ~h͕^YP\=Evd=zXX7beU>+d=NO?|Gq< ^<"ndF&$M'l*]v~K "jzl›<;JH|} zv4:rХ՘ggl߄ }=>ﵝ:ڱ$8_No7yD6aKMMbcM\(Y:’|Vן7_;M`4'Fv(}+Î}'zY`ӿtڀ43]% w)/E/G)mE,0Dgֽ#Hۮ[:da].}RaTK>a/?/VL/;LX(7mN9G ޓJJ|8C+)tf:ƣOջM7aYsΎ IDATr`IJƽC{/t atr%~`C4%`U:N]*SJh07?o2N]kK~+ clpYUBG]3yAox#pU$k!x$'g x0}:nt #m ק=[&|=96Ap0"I6tEB7[[zvƷ.;ھ}*/gau7o&$;Z,C4n!D7;:@E*NvSe95[: I40!㵆39O^~tqG~uWY4Vcr. })(DMBlNʦU{y^aLXoׁ8^xEIT0z&ې=_Bw x56[uW)Q+Қ0b$pm.bYrPZ̀>CHp}a%jb"9>1[/ W.#7 D@D#O crI)-+6| FuaJKYRH&-ȊG!<.sxg~*^Im9ll&6WW*a<;0Ǐ:]ӷ8Hgl0sN)-xf0_N9';mpo<~rg/jŏ'|f(tU}S~+oϷu?d'sje+ #T:%vYϾ葢7 >@fd eY JAMDϊSMh?Jg#gA=uDõ^!bmEӑ>x`fo;5y8 D=VI^FH&٤鼗 ?˾+\]ܵWwaa{Α &@h ,N^ϗwI;>=]H{BI:4ݿmC1hAޏ/6ph04ɵ* iT;lhsOg_2(`>~t @aͶݑavVMeѰ vO(+>K{:|~fۖ/`SUǠN}\{5ZfCSg'?E/[ nv̄%,<Ə$=~$#>_ |7Ʌ2$X~+@ɜ`}B|^v(7k%nF9ǯ}囏v9%Zd㻫No+rG "nϻGΚwMݟW~q4# :/ ﱓ~nOӧYOk?aʅE4*?=v] ]|# HӈsޭP+L>qRJ{aΩp`w~h zO@(fWcvLq: :(+,GKNoƥOt,G񜗠[+jt}NnoTMZxS%H(G3OyUz Mr3DbaJv 8L KCK|tduXO!S0&|-ӏLDse9+:=lEc:h`_*ŝЮ1'`` رI].SG4Ӷg+L$yeۤV6U*t9xЏI }Jc(^& ξyIO>ǯֱ`3+n~ؿ9geDz70N( q=<79ϞF8O8ㅉ_x;ݴ˧\4Ro6ʞJrpg{!ϽJ@Қݟ"/8(ގxL'/{_AU[?@N|N1pd/>,|1Б.I0|?YJcr%,?* Wvۯӹh4GXvk+l~aPL|uVo4?hģccufwн;+{!^ J'+(ƻ8~E0k\5}ϳqr(4O}MM(O8,r<|.%WqOyEru "N 0{7җE:ϫЏ5.ޕS'Kj0PRNGuܴirSv~EDdX4>iȊ26#yխGnRu?wf545AGǵtf6OWzzU}x`oXBѻpe z7өޠ:pP}_ CnϬƏrY\18F|jIxho ʒuG yd;֤K?+ &Y~^aOL.ڀd@cNv%.lpmVU 6~ %HgITJ~u D!`r):&xHƵO>dӕCK-xf( .Qc>m`J4Y9zHLh5#]/=lQ9U%p/ ;2f_:!|^Oa1&=|`~ ,-ޫt;*Ǘh䕵g_؜?\T~}iڙlYZ<&vZQD_\F.]9lv Ti|ߟ>NraF_S^c{?gJ Q?yZ8Σf̞̋ɸ:tQu@{,5Ζ. 8h v\<` #az^U6ܣUr53gӕ~r]:cEo5&G{i*12G.,&p ">hHI&d4Qtu+& *{nWZ9J?VәdH牠#R+8XA*al:Y۠j%)5bu8=ȮwGj&݃V)wƆ\@.Y~U[IJ76zt /46XH!iu& ,ޣ:LOyszha9 Sf9v#sζG fawx)y@FU67 sD:7Q\Ƨ'If 8vOOݩJ{4!#7ӕlw h9|lWG 3#fLW @q\.`\2 ҲH3=fc6)g8Ѡq V/OA@#^ &?g+K&lUyqrT6lyP"3'&*r۝MxI!?0HF~Y/DSE` na%qL,M4_DKUFC섿UEvy霾;ȕ6\^~gp.nRɒ=:CFwt:o__&V kҕtҎ$O?wS9P-|,M(|ٿrORN1H R]u<xJE!cdx0P9$!ʌR"bWz)пlBcUqcժ:X|*Nvu`N-}` ˀ#LΛ}īd/БKGJ['QQ'u1d. FdwʧI`?:o~h-̖&7H |`Kѕwb#OY~?{<7{(+: 5.[#є7V?v=Zc2Pa:;& LBGln&M MfTMoYשC~2Z=w{| q<[m~䞌壟!(ua$u0Wtluף, ɕ?̢ks>0aym {v*\N[azb04)I3P7Gb,gpL[7PVجx)[3p8;~t:@i'G膲gbD}xtxyoh#U);% u8VdL⏮VB nu=91{5>EsGVu:P=Y}>] ".ޗnĒ:(=s 3P 1ݏߕ|vlG52h23p;0pت_d8ױu~MOΩwvXgk& /ҝ&DZquo1Ux-܋X|1]e=|p5ۊOgrCPViNpA䟔UwnT0h  "H8eY&&b_zQK!AbѰvS?]>!Cm"ӽsGǕ_lr+')NcN d 8qc.ruC:vnՙJɨ-F.G[SVWSfj|k8\lʳ<~},.z$+j8e㼷C}}ũ 'SI٠@C }/:wp^S~@7pՠN~oW4$6QҽT{|Ƅ6s2L%6= C @|}VזxvLB{*@iz3ٺZrG{E |+c"5WwS ZSI:jh,#ēH2tJ0T\j2]qn]nEqh#YѺJ,@s7}JGX@8E6}t}t! џ'gOsη]NBokBӡq7aW[҉XEǻ9"g';O!y=;$VD:& Y/ 珕KR k@3͌na<˧=JS}|(¼0 ,Y* j>0mzC k=+d^̫ VW_+5wcQM"آ}ʻ  KX_qO^xT7ӊt5` > mDZj뚊W9 ^H)eKF,%հ "ø:$i[*[tPL`H6KF+uĖh ֳ}.c|&Ʃ`[H ra W`fwߍ5Y9ϻc;1SyCyvw0㣷"'^psZ"|x[(Mc~'0˳ T ?ٰ)ml~C:&t=E}{I`㏧U s+K+ ;zgs|v+AW}2xr, Uo?s`\jT u/=̆3鞜^R:>ߝ_mc/&Ld{hw>h|Wؔ'[-=uh7{>OZ=_v&J$c1\RO_&>\y misxa-j^\f#m5`d8[/xX8^:C^zó%W sқДG8@t[7 lT GY>?~y|=# YŇ5ա/hƟl6+1Ȼ-=x֠bD0ӁL7ˋҲa@lWz݄Im•ӱ;|[WWp!]Ǝ o[.~W7(Ŋ>#2Puv'3e8IÂ_ |55f~_ߒ>5]w7KM"UFf,>C>9_œ_Ri}v YY"'Js|פTH&L::8bl?=<M>买?m"3([\嶆fta6$bw<ש1ey.Ÿ!6$+Q*˥ayveF*Zݍ%ګsu)c<~q-;bdHx~yVaɹ&(~:A= *9N>xSNjŎѕ u}i}lE.0=x M`Ip|&@Fd|'{'z%*9Ц_$s*L& 4$_?;U pvkt ^5mvMm_쨠10o~t|iAw6KwJF:юCr{2~6yw,0A4[яZI?>-_ge^lGRC']]~}:'J#\ޝE_tKʿ{ vnAjpM﫳mzc>ZMN|d=Vg ɴɂ!}g~RJϖmnUvi]owΧÚmz|՟?Itm~y;y6?|R~+$c_ g+oa̛}}|Yv\ͣO}>`|+p]^9g.ȸ e #y߁WMJ\zR^݊ ZWǸH-ձMV>GgM%}uO)vp*&ƳZ GU )c|ĊkL y d>WxoiWB{쇞^IuʱċVImOw(]O^=~ҭ9~w?]m2 ~/sf|,ONŠUl+p⭦Ek VGsZ.>%q^PQߛFd@I_|rlPURV al3.$?3|[ .um~:vUC#lmeYoud=w= :/?7V)82F󋞝, :oe}w^q; 9_G N9+?'v{\L|z 6v^d7xs҇d*yv\Fk6` f6AoiAn/E'k"^fia5vD|8,MM&]2aN:w-ߋ&=a+ i4̯er)}Xa_Sh+0%\I3Ѣ#>)&Sm;mp%^.\IFR* t+쬈X<9نmyNx9m}7?< בHph0( hL7CG!_N=h}#L!no\eP$lG4^+bN $L8!ëgfO)5V^'u  dV+J`|8ۢ~cOLL7G_ TM VC$:g윰M4ql>*/X+ǧVuKb<ߝSuҋ'Rh>8F/:0"ʛ]>%*h"|x{:݌ӞSg( 1}*G<řvE๝X;Nf/s/қSٶxOSNɅ xt̜g0XEkN}iI~x`0EȇEb>G+]4c+/~]!-SڧB25%R@H':{F;RL•=أNds~^<\m=xot>uz&piMtkxΏ1>7ty^3eZɻd|@J,L{qu餾3 xo&1bé٫(uovxNuN2Nr뢽KW4k/I2"筇t1M*qikNg+l7'3z]m%8/?G6>|2 ƫ >2Xzk'Fؕt ~qh8i/ lx? 컕~3ڹT Z=;wrɇFIŎ匛8aϓV߳=?2٤R9Jy"o vP|ۊ;ejzɃw5h\u|Ա/517ޕx]}]vٖAXdy8N<817l`b\䫺nS6ÌiѰ:pr^INt8aw`Kt_O%ƓMzt/| z&>4~Y%g|[? {㏣}ea>ê𤘯 ڻMD^NZe0";; &c?}t/drs?^v/o6EC9;I`>E~z=Gk2wo.v\OcF Ki?C*v./rR{ %Nf|e^,5˳%-݅ܝV3`ٜz'\!THسSo>F+Htm@Sn{ƋU><BKWz֩A67[K__AU]qު5(=8²sAoso_o|s-Ogi8grSh_ Mi#c>Wn.%kiH?/9Ҏp8\Z+&t*&2Dc Kђ ӈn0&?Y26KWm g׋GZ;E7I2q;Lϖkuc?((/ͥSpKӉVǙsW.ïxDߎMSqe݉07,]ؓ5 D j񕓀+/eСx5\ёkDї/tV`Lٺv=p|X){xN6N)oqM^ج"ȴ8t)&;3L!~Vthw5|Kܓ٤6dSxP{d@*^ ;]ƠU=&,FQxi7IiX7tLW|rL>t:kHwc=t:񛠔҃ɉzٶ4@=lf?yԯM6՗u"=(N>f֗Nt~VMQ[-dk_t&_yEd: /@6;w:2ațX-;[/1y,K|1Y^ru॔&QVWVDYn6Q. W'tުY^{^(/i{ iO|T#u=Nҝns}l}Vr9 2贅z+iK7G+hΥ8E$!sߛ& 켤[=b<x;dcYHU7ar2dWs@& v t,TZu+7y]uI$ WNYAa'_<6= HIZQzy{u/ ?,m(ױ&+DSq)Kd%Og|(Od>ãka)eK? ]L셇џ횤1S CNm07ݳ&Qz<1NOӌn$#ߓv|d\+od+<}2l|ѳok]gSGxIr&2 _||䛽E?S&4룯JNy G4{3f|ĞXq>gb̀>UƓO.qdDOs4lzE`?_XG_ Ӌp613hʥBd=s0I6}礝@2lmZqD.ҝzYOϏUTG)k{&'. [|G dY{ww_U3LhdBnu9ԆuIֻ[ Z Ot6ӷ3 6m+|ϊ վlwߔ/9= |#[_찙/%pAMó0l+v HL0@n vv|w?fVèc2vGy^& m[n,^MqV>].|t$ JK+<Oz`o{j&t߿yhK-MINW܅G,Ǟd>:{@;bnͳ}c3ku__a!w=F`|ש ,ueWd0mۊ^~+WSʖo6Ow,(/|q)qѡNyjKo7ޔHKѧ--pX` {+eEden*`)t7>|ok(Z}u&0B(_|/aܱձ>v(}ن}_:\u~ϯ C{C`Nh'?a>pGgb[픕 Mp1LTqjZ?;aX=(0Wq8soQ|BVO_ D?[='/-NE (M73q7]6zGff+4D&?_4g`yvmp~d8`oV36Ek&OktKsㇾ``^ ^NxŭB׮`D/QZeCz;A[%}R:d04>΃^B?{teЧx6Ȗ\[,{;FGꐿB>XOLۯ{^ήpfm.\).WŦN2Y]z2X_<0Pj~4+\Z=~:E#xCߑKOpDR<+SB@?|~g!tlu3ey_A֗ L˻;`7_ F7]߫q/?aQ8{NesZ9FAqMљfNVzOGVYC>Gά; إ+mu*,y#]?\)J˸KrY68J9*˭ H;5<@dxlVG7 ]W W49IS9IoSFa%YEw9C#tl1d vVI aqCQj0'3?=IyNeu #+|ţޣ[?}M|ꀧ,=Ľ:+Â} u/W~(n~T̯ &7ęD%V_{0GLaD4(*@ݕ<}. _ߋ fnط7_И+7qAە `3%"\R~&^򲻺ޙ= ɰI0{"svP^˶VaF'4)OkAy b_cۗgE/W'dW=Pl㣟C`_Mhjc?p->l64P;PY.Y|QiaG1g@gc4τΙ`=E8>TMvX}}V*EUHGiKEbD&Ã%ۼVOs=>MU{Bc/vx UJO((<ůS@6bZnh F#CNqQ)}3 {xQtLPCo:XKFzy9z~ w]4K.O4rdq*kTyߵNehU ƹ ++kM뺸*/{6Nts2np\G][ >өLpnEwU ؿFvѶZ~&&ǸAvgW4 bMI#!,&5 3?7<tR2O":[4@<'V0x]" v 5|Uv+L\~ NaWg. 96.lL}hla?&&Q"E{.[ #Б}ó.~|oS\_xIѾ늘`< t댍sXlq=ijLwrxde͂|*Yl]ڹgm+2ϯtҮ [ 4_uv#0;+y\aCل HJBYp8Oy;ۅcc7Yhr{K1#\3}ॾu:omwdmg;g ]pϧN0f;bt:`@q{~O­WgtG,۞bT#]*1^vVi@q/0+K!鷅NVǛDv7~q#_Q4l=޷guHo>ᖅ& z]*:~|@n'Q*bѽ|EV/d??ހ* cd# ) ^m't~dKsV V5Zl+lPWN˛OݞiEF+9{"w>8$ct.>iAgz[G[]mP"MMhDtX)pT(St(pB鬎TnˋV~嶴q}^j?/BX$&ؠ}.>6.M(ߨ<0L6ƪ'Ѡ>)Km+Aal,Lxng)Oh٩VѲ"698C|Wx &쟜L`|dn%yċp [k4*V)@?m}nwV|rA qW;~YL ΂JGTw+3xbwM@Yy;ܮɣh GJz..xkW8g )7g ŗӰ~{Xo'G޳gLT Naw~9W&#g,a徉蛸fǓ<l*v!tFcuAQNƫO%Ln! aݼʈcr]mr4RfL )]G9,L,-GUY)җltӡAض?JW|KbyW]b^emRܩHLa8V49]_M(h͡8:GN0/~d"ulP-,'Sѱ-dieXi/}EQ]̱``BNcvxS ɃG?I##pkP?W0.;xI 4?>&5Vyi [nց"l648?*Y(Զ@+*4>}/5öwV&ggͲ&SURD1Aq(&H's(kh$ʊ;NS8&{6Q xS#,i-<TKwL]%.:l>3h..t}؟,tRk ü 4+)'҉6yV:+T/hdֻC:P] ;Q/Dް{{3>x8N߇ס ~W~g=iKlɝ؄z>Y=]&襌C_]a|@A꓅柅`==g-]-I'ru|Gܛ>5clDW,^׷g9BrN7YWlл&iÔ~ߓ0R$ kp, S~ZM^Wah%Ahyu`?W>0?h 5TFOQۢrΆ,|},?~EL&*Ed)bQ}°r2,r|V'kޘ60 K<N вχVA##![ApLSGLЊUagGh:|?0Z{[$악?ѣc0?*$NIw q#;`Y7Y_~_]6*'g`rY@.; Ofԓk@yV~NCLAN^3pWM@lz] 9QD7|vy7?vg+t` 8={l=p%E/(_|VgI;a)[dv|<׮%&gho4=$_Ul bb4(<0G߯ gHL& H+/a>*OO@5)oĢry3|p+?,ƣ+0لJOPm fQ}/'OxE}iߩRĄv$W''VW&??EH}mp1I`v< J΍NC$<Iؼ&Z&QhdяV:ȒgL`k /'2h<-^IVj$sX/wtB7/: .~U־P ցq2t,ᝎ=q?p 7)rʢ-I;fi*qIxKw04DgxdgXYzwŃ,sr+K u(.0-˖N{]WԲJ\8?<GROC|!_40A1m CĮ㕽p+ْt_y*+s_o6~rc]>:~3_JYtllp?:xװ1U򎬕7\|%\=*76 3?{Ѯ uGOG|ҵD#R`vYQzJ[i0Zj}>>*~ |Lv|͊볔Uצuxcl= wc_'$ϛԓ\]ŕ/GSg/jLP(҇ۖ߱|rV*uПx &߫(ZڿӶh`@ `:WzI| ڸ{R6}lS}NYzk&LO7l*)٧NK*;Q Ux̶1`c' ^ZZn>/,'S.%'$t4Kg>"Gǂ'݅Ӏ2Tq{yҟ|@њ/8Mpv ų!<'PPV,8DI Cz&=Q 0o`=y|]a+^SOέH:v4۞#ޢ,LqtG+khµO|m)kyOrDTw=*g3Cp<چkF7buF2At6k-,{~mձʕk6N7)6i-} cӹƱڟL~fGoV(\Vnc@4'8$3mwplvoi[ #Pɼ-q#P9cz5e;;>'9m:?:~hTѾ_cz>dp_=+܂7Y?Ԃ<en1p8mt$W,U )4?y +s&v#gygҀ-X./K?XqS=xuSwҬr,`'pfM[Bf ;B>?*ME4yp D(]HJ[ {Pٍo顼⁎rIg:Mt0$$P"aE{.i[&LPjAebZ_6 >?O1Fzxգ7SMsZc~+ ފ$t>eNMù~7l`5&xs Ny2Ѵ&Ɗ^'O44m DP4[lLph~S>1+w8 @U˼sH&ʒo`(pS~匮Q1 ],A~ ~ - hy3RIO[@ A9clEjVls=iˤayxNHXAdeQtXG{NJt&ZQ :+9" J-ޜV&Ku܁6C'\dWŜc!8rUǡ8\wOc]fFChwOo @Ə@F]hTd=4Qu5 4t'<bߊS>^_ݫGx ڒ8QI*rб%| :]h~i[ :ei:(fʭNAN4RbWi+aw\Gd^ ;_{H+ʬ|gsB[3l6:u}GoiO5ܼUde7yR}lc[,yMk+ȟd ]ǧ\iA˖b/ 0<~]wl<كהK'+L8ڭM]F: /5`z'n7l`K+<-+ <ݪ+h!՟3p '@~.h66Ƚ|-ؖv6\ŞHs`7 _7=Ik4c(BV _mʼnƗ99,T@Dp|Jptth j-?5Xn ,S:yG?Zkd>}{l$ {@6L3R@8[tPM:B]ghK۩t4[^:^rg %Sffγs)ǟԋxj-:Xȿ ͂Y3Ӥ5(yN'x&D,+Kt}JΫ'ܹ~ty~d#'.Y9y8b˃{-,gdMX I0Odd/z4xT{AA>_H)H~x7I',9|RK OEC2_Ɇye?=$`>%ê _f?MF6CcO񳀺Gx=2akc2êMVM0O~‘8T07֕|G;tغ&.j5ݪ68)|4lvhtqA>QPoD_t%_z«ڠV^pB+|)^G?o ؐ:L+ iBݤ=ellTGOndXg|Ovg3g& bLxZޕ&Xo?7l@EAaDKs~]p3CI~7̔ y!%8q3fni!`?Nq~?;@\38xCgU2t\^X oO~m7mI\^G1\0QK^P?`!ttL"[?Sсbe텰: tɲſ &S:&(k)/d8l:ԅtOLу6^ـr식5,\AR~=v_ٻD7L_&_~[?|*Nz~%TWT`n)h8W gzvLV jB711g_+FWk`OO`PRs- +?yt&w5X#sd_(?Β|H+ rb4`;|2|Ue nP&ULZAI0(ۨ)̬0huH?}T,<=NgPH *5cc#~bߎwyH;[OQ3{%.nO`i bَH9t g0X;7˷tU?_b.8/ؙSR_(8}u@OљXLބ8 w7Qiλ1xC:iewfOٌ/LٞM= 07v38 (V-)'ߦ|$v7LN?~ҫO/,`&Rȱ2o{vwNvTU>Ea293SH$t(m}'NcGʎ]KWZBrѻzaq],^4|Uǎ`:5g`q.A>Oԑ_qmJ=_$6^/}ߗj'[d'6; 5{\=9F/Mzv7_6\[Kw ""S7n{. `z"vlO29k6(7691>ML8u+pk.dt_'6c+SŋW)SPz4GLxϫolr&\m.;ݧ*o%DSw ($!Vn4.;+~x#6*}wOldq}zM[xʎhwW߫$O6-i>&ˑ/YhqP?&m: L Xs<Z'pbueEi4e`qqyA˛r.gOiOY2~.6JYWÃg4;~1sx Snp ʖz?_5e2Wຊ{IyC@ۛ[w{ZqPU& jIo)_iG[,@8-T#UN|by|!7DۗT6Ku:::0|>:SOhA=o8.)}l ݄ᘜ >ڃ.#˷K}η˽O=?<ll&_&{ .2=Ͽ&^٠vYxe I)_9ZT6zW ,5{<VoaZ7>rz:[D& `@7lΦ7C`蘎fۣ7u>+K?g4?{w@z: wWCEO}t:&VgMƸ5?jFmcĢ(J{*nͷ{QaM}x' *&DMl5%ͽ39eYF_C;d?D%пxJo,<ɭ/\wD,۠2? sV4x.@;hAOv /Flpٖk'‘2|ߓPmm1mѽ̎Mkruoi:p%@  نg#^FNP~An2ͪ&t9F  ꇧd}w6njUމ(ћ;I{ʆr-(R~{ͷ㋯WmM;xaiW(`ts{M޵`?ebf[P_ `X=-R{3-:|_%hʭo γA7% /~W_n}f_ӂIGc[OM@_-(cn(d>XƝwˣ#{h϶[^߯6UOj94~gO@`eSqY82C+[$O~Czȷov.Oy~~KvjCL8)OqM*)J.oe/^_?`Z^;d5{6s{ĭWQ6oO҄7?tM~z!*dDz/̮K/k]M(+Y m= *ǨhMnD{A|-7RPA>t_$d>O)bfM/ʵ,738TXB[1=koxx~"I?c8Y3z+~|:fk}C0?W#}&D?m^p՛MҼ8o1+'5w9kcQu91v>׸`6y1C2~Z3(b! a|{BIKA^pL\whD̀E\Stœt2/a3_P>>OEq|p5]%'x8̙\nE݀ Ȏ1ˠ[pn3^ +YBگ !85`HJ3뤰f&~'g:xYg_2=)1ob' _ xw w8H_Ҩѥu@i4QO lPH7٠ K˖dս1[o_4=M N|r6'm+no# $`ov~L>: tթȧ@'L|>E6es=eڅ߳{|nCƑ?:ՈMp:6C"݆n!K짾@.^}2|:LTmCp}m*Gn2oގHhOUn2z2.&Cz)}05AWi|2t;kS7>:>k[y;6 vOeK&?GBA֎M_PW&'H{n=Y[L(09LGaBBnrc">|o6tΧhtŦp$eӉz#+yFCb׳Kd|:Z׿[aAj@/[$M_2?41[ʃ}+N|%meaC.x;냒w>I rLdMT[Wt@gtnEKst]P[.MVSGp'Ur0[ѯ]x1dzvwOMy~EPyfÊMpP#sEpd*ٮ&x~k {Z頕ddwzgbӻMDV&|\`ܒnuƚeWU4?mkN64t)oyk2Z-ЌGh{ySqgAw*I{z$&w?4[/þ@6I/pׂHa?Q*6+ ~?VoLt,C .,]I _f3tYY\k6p[g-ixhN]LWycu!x*4Zv?zXayzYP>-([ 0>x7k&O&:o9^~Vy/=U߼b~$y&b6|0QK_$Q-.o8eyhWd1)^ljzeMb{ m)(ض9GﴗR;Ի$t8&] EĜrc^ubgW >\}6V*&S h~F4Exoj+5fūW^ɤ5LV}@cg3@ҭdqt^[:9N;L 9٨IvF /|o ,> G?OC`qO;|ƤtX6ڊNjcM&c__,'if7h H< "C~c,;08F9, bH4tAt EqwIJ NB'ǜHS> x!Kfx\Б?Z{SRM˵;'J:: k~8d{uEpb0ށ[ `:OҬFPi!a+OZdʭL_taɒڀ@F3#p|/6m `>0r} <#m$囘Lγ* 3P ڇȤiؑu^[:յ .}ڤ7ς{`69ZT΁ 9b^A?iO8 2 4r_P_dg7v+_pG"}%.AR nOs\vAi2kK\ĿI=qd,hg=ݣkɍ͎g&#Y<~,%T9R?ѵp'~fM$3 `^}QdKeoAR?4cM.iqP/_iGLEx8v6Aǣ9]BCLKD(]Nt.چeɅӆKJz@&ȵ;[I[Lc-<|cosnA.{(|gO(_HG{7d|>ǧSDӧR^X7a"Lro"Y8eXf+&Jp誉yg'!'Ip4wLꘘń̯qҗ=486wmRx7i>;/.яuFzE㡝ZcCc^6a| #}Lv5Nz̟Nܶ`Η1yBd?m64o FV*6ߏѶǕJV?M|>_8x>3t:ាozDr+OgI$~LcF[l.~~y/@2J )ձ$Hm͓3?}?1]f'Za(:_ hId_v /xawkdʎap y1aw k3 4'w'B(Vc6@p1 SG 4}gR vL_Iqx9=c|ys5p1ЂܵTNr9 dw^2x<J@.|{po`"X)\ʍxF[mtNcϓJt?5" [?$'?MG)-^yɹ Uhv_87up鏎7B՗[1!'21}%{[dk΃UٝjtT&;Nu:dsNLFsO:0ۑ{xA'F>yxe[i *>c#7Qzׄ]8݄gԟ?O8 L -?Oo`>u7?de :Վ%Jי/*lo:S b r+\,F\CNMͫh>[}6_D ,\LFeިPO6LDs}tOg*v`k4X[rP??XOHiD=Cq&Je=w>@,畓>&V0ܟog.Մ̝Y`ɢ Ao~{g~s OVTeeS*Fj_V3'R2oЭ=zJhM-9Z=L~Wjx$jGק?v &9ƝwYy鎽wG"?&5=b9'Wvlsہ=aYz>&%<5'ІX]9YV8ҽz3[oOܰA B0IdriM߷R2Cmk%~O]ut{| 3Ov3F{snuWmjӾ!ڧMÄ+MOߟK鳶 f+#oZM&n9o8^\}>0^B~vKVtnšl;*g""Ɵ=J\Oq0^{Opa|٬GV#$d 4z5|&.2f+S77&Z^jUfGW0a/;ݎj5e&!_e^h (cl.G}[cIW z/C i {B6"G}A/iK\|*>ֱNM0'MèM=;89*5=ބ̆1]R4?Klhrr[{nr Ex;i:7qLDZspTtup|mc B)o,?jhFGL60V~<=멃ɸQD-~)I|{)+'_o&=|fHOEѤW~6$(å.6\6, Xѣ/y]9ڂCR5_6Ѽ./h+DS>'G EWsCY^ %؏S T{*cpORwOٟNXX7V/~mЖG Q?7OꂤR&QfI*"fQ$ꇉ_g1f%G'(˂H*K .=g|v;~_~{kTʐ!&ܤu*OQ{e?Aj2yn9z~/$:~~1IWlM&G3=5ocڴ>OX+}僿jS鿢5[S8ANE#p8\x0([U&R rr5r caΏ.y9e9dI< Fe t0pMvc2I3ZWk8,V \Ek7D_^h{pl"֊s{OK~>jiҎi={[y/xWgvti/'3SL{/Y>ӽfWtޫtg^Fl:]'߰w5% Rx][lTziU &g:K7\ޯ_즺'9i=I׮8ݝ'gjoYCZӇ_< ~mɇͿ&?6cLq4w {$bdx,=ҷT9s N >8+ytҗd81uN^2{ʨD8ұ`/x|huʡ2RQ|li@?}[5e>~61wgʮ`a,-z`Ks+9oOP.W/AcYwtK|؋`B7\1OΞ8>I&i6iP9?/&aSe &Rp1=g`瞮٘ CX9`K=P:/{Ԡ=ef?fc<3̏.C"rǷθ-v=zr~2<{~w0N/7n`O<TgO |!ک'f~5oÏGcM0Nsꏭ<no5Etϊ\6ܞ ٽC6M_|X-s=ibauꔙ|->kUkDqGwS᪽Olk"u{uTGJƄk(]\>qwlϹ/Aj>zٯV瑬*p X@vߏSx:3D FVJ_?C>J= ]kPxnlBu=d=3/ 8*@*x=2kux\g{ZP*AH=x/;.oF K^M=䝆nz@x rg :TƎ {^$tL\5:F)^q{N i#=O,y~a/CS_6c NfF@kK.EbrA~5r Ń@v& +`'óYSX|zgD7raAY[g:>t 1aRE z7|~?%#-OWPϗ 彳ut׍ ZиC3o"`v'/alc™~wNv nRL:1mHCldX44&6Yz4G+AK_|u:oZN6<3whN'k9MN׆Y*&R619ȩH\ <9G)>+ŃWoUC#_3`ae:Xxkuu#~͖Ƨ PѺpz^U߲i_U?NàVݩe ?lHۀ\V;u ڤNw_>t WK׀ 8]ٻ-5(,P|kAQ6{G= Rc0/\OZitr`{m^G8,O^2ȻނAcDK/{ޱQ!p&k>S X`Vl$"{JYC`˭~|Ij#}zҷ[Z-7_^6, ew…gGoEW.>>?? -l(XʄǞ l āRį$ө/ Kݘ :t4{ގf\A> 9 gΛrN0'9gҶA v7 GXyLD:i\ !y̤O}4ks~, $ne{;){K_Lhȳ{C& K%۵!Nkuo4 iK'Ѥn6*<ڌk5ٛ._ D[ XVϏZF_9í =nlML8Erz}vGYWWyWg.OFI^ Yp yeɸie^ՖE?6WZ?bZ}aʁQf~t@kk80ݫk3G?gxWb6L޼p DwtƬ[hwb3Σmxf >O >H-}- ;H .J77+- W8 cFc|[N!`YoGh*o1|hLEq!iN5pC\AƜrJ.ϖ Dp-+O?Ue'ǣoGi;]. 0!+s0RQ9_:b5V2Sewqȭpe+q=-YEGB_ww{(_Jy+s͘My9qpCʍG<.y] ~%l:^OJD ?8 8*es>Y9rK,uqW ,sǃzI"Ps}&L𤾁=?Ksdh_St}u&Ǯg_'ʄ IyH?J_S {lz|O=OWypOxw.n;h~s3W:VlpD 2}?m"+=*ٛ6ϯK9z}J#֙şX%fI(w&˫@8Mz:Rȕ6+F瞚6bGgE d$xVW򆻳zh᳞N0|oqh @[?uU>yCKk %LG|a~';_Oy^VlY~Ew(Ae?#O74zF'oHִնwjѸʲ׫|lAEx%ѷS8sH\t@G\trM4%Ώfp|\PT+5!.GʍeOӗz1jU$l7{zNHqfvʹU|<#,K)<X[ s>yeLJ6I}zߥRnL1`ݪSZ߀31R:L<~u7PΧduJp$Q:<9 'ud"B}^~^I2lp&_~ :ojo\j9?& @tMWsLw=~ɾW=nG{"Jgͻ|𗣨+ĶF IY @ 8t#&x"8]> W.E㘠GI˃9}㶁5cMgtwys>|w[yp t:u*hN@[V9p- kx >N2hGsR7G&|I˥$/ZA,Y`'&Ǎ ?7 șls@|3g@n|>JgbGZΘtcK|m§l_=Kk}%@>W+2G/`7 .Vmt]<{ܓ?֠~OOڇ vl(88G)цq;roQp&/ &d.ҵxAݣ/L]O7Oy]{D  z*c.ÔluʫYGNh"'_Ʒ?F#WxT?sXNDz"{:}%׏hMIX4' \Zf{.Ov.4_FZ:l_z 6[=n` /ͅk]_zB咞S|Lّۤ&T0٣o˷ghNt]=]H䌐c|N;,_:cy-} gɶOZVq:"΂ .A(BtV H#et4+o/)48g?D론hK_9XTҿ L3yG}<)IJ^56@ v `m8!|4z *'ԣ2/;'ݣ@54ڂNW"7Z >@>9| BoBڍG&\8ϠO7ɖt`ccW8v IDATT剸tu "sGkj9>VljO~6/W"eqyJ#:5~/n>C[rUOfP;v|фC{U(B?seA~_vϤ&l>,}&]C692g"3oBv$o6??0~m/-֯O)ƾ{|r44n?S"6:ˢWCݞ_! 5fX*ڌqD1?@aWt$@F+T"^ wzńai/|n">+lHO伃k3>iWgQ[gnï:|%F.ȧ;NvC@Mgw bzvVܗ9Q0'?N7~GKz|:"e#ߥ O(A|`'#[ei^muPfu\޶&1>=kg.| .:` :읷~dǔ>hɞ0v?𤯕7y/[CPm??Y /+pXߙtnL e 44/ӵEHhĔ.!X> ^s: r *2>^ l䘎Nnrt^3̐\y%/&]Г: >#XbpO {6ƚ?tN?xWp 0  ڃ ׽36|`a2f_+ylx9/e~#ytdqM/ί;UUSW ֩uLxTds Ti2Ƨ͸otꓔܽA?~~{VЁ-LgeR++])!ɇOɭ,ڧD=sV+5`=mM<7)UI}}#9C1`OEoztX+S!< f W+J a#y<yh?FoOtMh[.ѤfO\zkK( ?:Q[za8yڙp~ ,}PFykڂ^.)mHvLH/}p Փ-XȢHdGG rMo>To[7Mvls >eWF-@ 4XVH|hn(뒻tpU_'ߴbwVt.GG0GVC?C&V6=]ēd &M<$6|R/Y"ɋ6>qxcG`Kc/*h\$W|B?|hIe#3[905iMe˶84zo|`=v端u>g7ҭ/Z׏`ɖ?_o=Im't'9m"iN͘:V-U8"ş^ ZWܗ/~P?4Q>k5]7Q3e}O~Kʻ:]i5vۊtS9xu}9aIݤ#D63y#k u }ߪ^J]#9 PlvNoO<"^aHogR.\ s&gK6]8Bh9l5@&O{} |wɲ:(08ݟZzw/+xr1)e# K` t3bOy{)u\|nwM'ii,@( %7GG_x@^K@5.D|A<,q;K`$N<=UA|v팴.v1il@(u zqU4Fg(Sxڮ! ?#D])t ڧޱs32ei[V d%0xf$rO誁?X*k._Dd+AIW(3nN86٧=TAz괶 ODOydxK %znHÔm Dɼ6tmatn9F#zL` L":M1-OU9UK{ʟ};u4g&){~n3=0 R`ĐH!'\x?t+zek[[ o'6}U{E}~a/4RȳO~gCmxH!YD1~WtN`^!Q6ut6о` _ -m!c{ҿy  R&33ɦ6wki8Qzq{:.vCOu l:UgP~762=A׻^ W'Ο)y6\?_x7X`? FG?*;70o3_ .%?^2yf`l?s¯sX%2׿}{Lwm'|Dͻ-0smI^_PƧ66#$nU~|1LJ?m@qr2h>fiwv#%~cJZIt^b~ $óIL?>3psor ʜ&=]tO4p01bߟw[]o}V^SDu}ՆvjA"X;Mf<յ~&=^6)tL8mQAwɀRgb}r?22ñ2۟id|wze^淾@`#/9~`ܧ?; }rpJ:uDJ2zV'6VTW_?յKJJ-pU# kiSS-eJF^$_ :<%P )bKl^sp_5Pkj#qը#,PK7P3pMnLy93ro]6Jt462r% zLiqlNR *ϖ^=k57 14r N3{ݸJy9?M/ݲ*tI! (|:O38&f6X o~)2Cnȡ&Kx_2/nٗN45gp]EBF< }Sa _ 5fZS%*/|4fPT#~@ƛ6𒌆/?쒒h}hIgHrvU>8.}>D6 lL8?qIƳ"NGcf{~,ul0oz/ėz΂2F^D/ RP&&_^䟥3t:JlFVӃzN) DQo֙Lr:-{hz݌t:{<?D MSM.w1H&nAw/dO׳6D|fVn>&َՓ%o /l2=i]ud`C66}*Yۨ}@s.?|q|CS&Kt#6懎. DگٚOpw7/ JOϫp`voz xlɫEg`/ Drڍw5qt6l8_}xGۓx|zI&u0b6XO@W+G(2/P'A$$3L=O7)AA˗ ^ x;oS&|a [jM'`黋?lk߃"#(m9]pa mOG1&7"&g^0 :gvv7Uޒ Cq}IϏ֦/Gn8xmf!Wikiu2 ;N0Z&1QmA l j 6239^|k'x0s w3Ԕ ߺi V'b~ MEB%ܥ n5YtSQZ|%\d\sxo_zkP>WG+'oFh:t|҃3Gw|~ ȷM Kj(x訡3]_?-<(姕e;gSJf-Zlf޳?nu=lr9/\e_S|E;㻜-:qd,ŧq^Qfe6j *}~ʄ:3Dߧ#x&6GDڵ#Oҫo^lo=(5 9}B|ݐFV~miJ6>>O췉_tAWgwJ-dKy{-#=AvO ~jӿMF:uk;=H7fޜcwENub [[J9|rq=$*ڨ;k&;6]0\hO>EKS nP|j>!/Ƴ҇{ P1H@ygIYB]':韼(6qݏow&g  Dܕ>|2u~攵Be[4fGKro:ڧ7>oYL'l} q~x6#c@vMd$Ll?% B N8đӕK$yM,Cw <>8yҏ TcA`LlEx\`:[ӷ|#=u486\KC6>O߽~`/'%?UWǕ'u Q9 fҥ{Eta-`f.M09Okj^ ʇߎَ^% jbntχA|*ƱI؇gLH^~ !³/&(_]8E|0WN 9v:t5<0!l6%ބ:7-Osz?t]Pӂx"^ wGU׽`x2k|3Ds>>/ߧB6<7 ͮm1a4V2b^vG>/zZ@JiVT{~ZM'h6N7nP!12 xg< *x*rOʴP/}Rt3O |,JÓIԖBukGᠶO=QSR OJqEOmր2yH &X9 g1'qS 1Hv n69Lhy >ɸ`rt_0&? G2U#G&W>zɑxN_^zW\l%)?ޗ.bxNf~ `$Ni&6A\]Byʲv4+c/N Wpx)OOη ϲkc_>nُi_8< {UXJd@Y7JiDYd'#MLG_VS4'd=7oJi{:b[`wjlbNjltǤVGA>&ec+kJm_>d'-a⅟d9̯O/ƕwV=1z$l,QQՆ2=(!+&;XtlM}kR=ř&Q_Kup`7ʷk?L`Yd<ͫx tGϮ#ǧٕ=<۲.,<ޗ|pdH6yd:ZlCϒjJJzHtlήRʡ3yUVgqd4l_(G-sz<;4`pL2 =`.l ^RؤO*O=]Se0L7g`78q|F+_E-hCup~|oYm[ MX[yfqoѩQ3 ɥݥT'GH~[$O? We`{CigX  ߠ(Ħ*ǘ-3LQ_RC[<:J~>>h7Ch~sp99Ft peUPi ~z,`|*S>|jtxtQhwc ^95&B .1Kߝn2av *Ҫ{# >T'Vu5hxul]8urۿ:2ς,Vܳ'Eh GGyb Mv*WQݦ/‘54qW $l`@Gձ'JX2bQ|}#󚅠}.w%Lmm:x2x|Jv^0b߂7].27&[O7n*# IDAT:r9xC|h"{דO?7T4*Mlg+~o5-xl-6ld\j;6 Ah)s{кY=V> D}%] ~c9wϘQ~Wx^v쥃ꄟ#Y vĒ GG =p>+M: >yiRJt}E OJpॿ۪_a?2T)/f:T<\ :3k) _}m+1Iu~9}߃/MFx"㟁N^ާz)~O{5!+ 6 cwd־A$xzdޙ Our>N_z{x/O",m.A@9G0$XNjt3tat_1r)>Ico}շMĔ#{ V_(:(v|7ݍ0p~[AޛQXP2Nu`ur}njΦ|7~4J]ٽ`ȃ & L$Æ&)N|n3l[]qCMqD_x{b;m;`3ћUcGف Fڜ4$Io 74_i^=6hi[7. |B:=fˆMե=a#tX{pvt >yd&?+M`2E.:kci}&4MVtG]vxC}o߮-@4+SL"q Wq(//^z#GQsG…L+6W()etj(rRҲ``Cʜ ֜TxqBT$ yHß0xWٳujAWЃSȂN [Ma@.*5`X "#/3\9hδoa=6m)>2>rFϠ>+>[ɾGYY2'=r myD#]4:k| n>xu f> ]bOx ^9+r>?W5y%tKG` &>w^2&めxX?OX=bpӋ/zO L} 79M9j-Z§ ܏&&C~1_7]6?3i_0|2pjFs\L!OF|ׅ|,ְˑN!uN OGwթ<>"x='ȱml 2Gn ~:qQl6u;3|{9+FV(fktvOT7cM c*鏽*tt w>GI] YVt΀<%&z6~z4ǂoR+{mK/ &>u O})Uhnauyu\^9'7}k[@9-=`no?mVZn0wǣ*LE$ Xܫc]H_{2wvUlE;L?뢾H7<\;0vFkL VnmdFgQ ڗ3l/[3`^v};14.~݋EMj3 gp|6ytu$976|z lyvs䟝@Mﳫ]锏gA?oҝ7_,1\Gmӱy'@.9GMgנW9O8_; 9pƽYGyRHbjރ 3(b Ɣ?LpHt%?ww:UwRhh j1DGX K\RJxF{r+vwIo$íLW U 2dT*ld@ md/f,UUv.CÔ6!"a7ǿۉ|[ lG96gSbitVl00[PĦh\+}~~hNgegGrÝg;fS۷;Q[h5VgMSu4ܤF^Sâ&7d,O>YG++pi.me"f,[@|j`9$??j>k?tF>^~S [)觌?`=#8 n'!*SYz0LDwKN!& ̭ٯI!&[W;:dD^ӟFO'\m2:G5 ֎G ^\9׏vYy3|~7 S th/a#;|^ϊkoK} jƅ~?m{qu&} ^2G=;w6LY={M`k ԳYm,dX=2*>JJ _)EEW2\wnk;Rh2kko~{&*+lSm=6j~~K9evZ{.YU 7M{MsnGXʷrk~x'م"wO'9Ľ|rk']~A|o[[t‚R(ɗ> YUoWWK/}G I'-o{@΢%Sr 4сlD{כ^޳KS>|1lʍ ~O%A'>hggM4ڌڽJ3*Ǎy<.|a^H 7JOO i~xҡ/sLK}z?sRzU3#Z4>[MC?43c|& Kj5}dQhSvDKn3in:d3Wߏ̶1njq|M u>+vkGO~u [{!7KQ5s ϞşVچ*O&E_heڠUu=y \u=?eűbQcg|c=UL^iNBi9?ob ܯ _){O M91WX&zo7Rɝ׆o/{,ma}o6cKA'qΕ]m{to[G| ٮH3ZgGWgke' ~[ b"{/_iBNS|g ٝ{s ݥg:|cKKcS7={[;#4 O붭ǜA2=VqR>l~ߑ( 0okw8Uq=Jj`jĆ@ vaF{.qhݷo ,yv|ڧY$mVLA3.G(ȇP,=]0l~ΪhyWVx^^IQG1w_~lhğ 'z&&hvvTO?s 7GU-c;?/A>7M4_D 㧟}׏zt->:L{3݄w&M;uI9go>'X03NWO^GslB?}}=zz>x&,|pL5KWx{{@xAfK4;ҁˤ7mݦgm l=MzMi6|v :χӊUs;MvLQ2G)ޞE@d?WLnwQ07dAqT_H=4(|]`N쀿 1?>w7+UǨtNǷiX9B%yvz !2`Vv@ >'c$Fv߁/u j+,mjN cO5޷yD:Xc%wVLG FMx$;t魱%[3/yQd>caKՑ/J]KSu8:<ʃ?{m~qopN"e.}:س21EˠhC0qu:mî: jf &i[Y1÷N;W.>*-EeP+yH.OJlPL3d,]1.oΆ|nهHfg: }v4{gCBm1 #[YamA=kv mOGo h2]=;kwAi|h tV`Vv6-ly^А|/>=6SB jko `P|ԭNO r[ѓB䇧}hTGjLf bW Vk4Mr:ڧĶz$g줐Ul݅MTڙG3ᾷ_b66dk?9 LFIw[S;oږSуkA7 -wOj J|W4Yؗ !xp ~:|gV|r&w2Ykyd篾iE5./?鯶cM"K*~zQ&f'M>϶o ]Sk$_ CN%=رyxQ.Wf7YogXV~_|٧ _;O7` _[_?ՓlV:]g$[zX~{F:m|& ~}'H.; s"N݈'2?+`Qcxw`6\M^{; 0~$Cq>(+ )Wĭ`jty('Cu3U+鴺4Iw;-JZ᡻{>lRO6tpd+6twٍ>>?, pnIW}?e} /OGѯ^ ۵mz_GS<m3wGI֙/6P/[}IF VT#)#ט)8 W&t8= GB:_9viEO "K.ӗok· psdrwm1}*z1Qg{d VnK @me@9 ;Syx痞*rtஶe:at ;_Wp6qgo8+]VeB{S0G 6`w\})̏;tvM%/ӟ[RyYG+ v4O3h|RΝY ]Ɉc=u8̽%R@Xձ]M% ;L0T`luS^* vS0C Klr4,H ~13<[!G'zP Ȕ)7|?vAD*mv"NatKn÷L$XLHplͺ^C%pmeQGg&VN G!τ6O_sWt8UǧG@{Ѯ ?+DбjEyp? ݄&TXqmj V'?тgx][=̶p~֣{ S x/kC|k8O=7;@fP^ϘN](~vSgVc< Y?VS0ki ć#CuNkFDǘmm!Wn>-6ŜgzNkqbI̞g?DtAݪu~j(:|%}T7텈||Dp/;/ԇ)={~8,"&A` ^Үn }ް<emݔ됻4y#m}o~jlɞ6~0 W]EU3e o1`PU)2q)^Z2nHK1^ c7Jc A!1x+6MQ1O wL2w妐p\Ɠ] )_טşu±mPg|Lt >w3X.]Tȸe/3 ٲpTtMHTC?ZQ{o.̡OBLO$_ʡ` *{+ܰ;+o`\GHbl-[^}N|i fG{zM5& 1~{I (Jӝ:&z.iQ?:-Jʖh6޶=;[czOGo||{;yZtCpC)4grsIZeu:=`5:Bh>z_ʟuFDzVu%L ŷ _d'^vLg|TЧ[cB{e>akaf fʹ(]oGY%>3m|b 6WZvۃt| Ort_{޳rTaU/^¹6O~+ɛ>W` W ~- ';Yñ

[-?{#X:pGxeQ)]̗KdVN|jE+ Boot<ٱ~[ڟt!Dt<~/6$_ :iW@52bwqԭXU2V¸`ᠠ.|k[- *@i0y 3\Kwƪax6n;ܖx?:Bg۳=iţ3X֮$/wc}2ZiSWf.I[I0&3)6 _h2l#෴n->x>x ŻV @A;a\]d+Dc#=.2>HMpW~So`{tkGiIpvr:ePٛVp]bWƏbZW~~لD=v I1Y$.OyLnq`&n79|y|bjʛ??ᑏ *uїyln·XSMG>r}FxWDO(v^Gէb˿M>;W櫥i^x]>6-pOmwCȕOFm9PƄςd|m|'OڌyۈU+3n,gwv:ߘx*z{Y// ]`tn6aޮO \X:oz瑨.³0%ɷr0W]@gGb$A`7L;g0՟O3lC.]gʈ}t#^z?lX1ӧӇAWztC8uh9jcJX^LLR, lI.b[ʌ0oۄ#$OKg" |<>Y̭y[5_7*B{ќjxj݊vm{>7II !TƽG 6خtdBNpYrqp-#AܡC]Kn-o{)Z3fgr K Vp᝷7lۺ< >kB4pH,뚗J# vV[ 򎝕 ?4_쮭>wdvL0\؀  |/ëDg[>8,g]յ*{s7G (+۶u52Z:Vfc4;dq8Z: %gS#b]>h~Rit LJ |<_[WNnQl2^eO _9Гo_]"YxD5g9!;;t|Em5vښRԏF;% ?X,I{7KOwDM;m3t uS#p%gYѿJhkWoSx,@PLW_ݩO@+<ѧ3?V:ْN'?:~bm) liOCӧArӟ7&γ͕.  Hl{'v7IJh+p 24u0yD<<#]`C*Ǖ jRk3B]V.m|ޫ ~c jW]^N ;Si:y,f6NWA9|F1dߘ(X׶z39 ط,׭FgLMf,V*ߋ^V~lwuߣ _̵Aq_TMidMnt/H^߻u X?Acxgl~OO=ګʵIĐEό%S]9Ϡl+ƚ⊯z6v.S߿R'_ȧ.:|\rR%x﫣w_`;:?p깺dW_?P7ɩJHlҍOИ&Ne1?_buA[\ߜl짿qrpu3z{ b?'4!ɬLپ/i#hY<ރ7bk|뾼 .SGOmO,MD3SZL?w$hˆں9sX3P|L1dxÁ68 .d"ݳSeh +9X^UW%8a ʸ$3]< awzܧ+nWr>8@f倷ES `z{:R hOoxoXGϼy;/^츹+`9n[ѬI;}K:ZxQY+e3?*}|zM,/ gQlu;=W2\:<=~҅ [)Ooˏb6{pon?{Wv *ipO5THfiw^kk0_~W>LShxNM\<Ց:t1#W>}Az?{fp^9Ifa"M8 ֱ]#?u"Y2h:w;Mv?aVnu>/u7u./}? 8_p~Ǐ 3= _sʪCO,٣ӔȒ}xOOǓHNcX+-~t4Q*cgH7D &O &m+Bp  4|dNOGK.pT3MjշA4~17Ygؖe|:L`nd 'ٵ~`PClcƻso&K&HJ@:|s\-}?og %'TLbߏv4Q !=mQ? .Wg8ϐ ,Џm)YKo52TW?ߠ<;5ggGeg.Zt郌m h>䱥A1ZշfbK5@u?Z- ytђ_"kϪɗ]#:^@LlGwAVݓA0SqvzmN>r^u淂D=镝6/8x cOaG=JA/y&PyVgTB>qNVvDWblJU'}+pؠs^G'SB}ͱMnG d~H: |S]3?LࠔyV_G鐕f Qr5.qg`mNvd|>Qƒ~n@v(ac^h;l bG_qHLμl>wOO]|HAba7)pӫ=Hes?e '=MzMG3& } kl4- 1[ O[Qqc L@#eñ jcBèϞ}tt7?KVhz̸5Ho&DG7~4cຟ=ocdިl{frpL!tW㩁x$lʀcegbUz(F*:=pu-訑b[_^K*[;O&å_tAҝVAtpWH8A^6zљufCjL [ڟ`Co@G>Kt?tҘ/?NO_<{i4 b` Ez@iQ,`{=?Ha[Y|%Qr)mg'Bرd4^ϏN= YcE]^~G grlb~V@giJflZx4+|gK 0^0Zo#vqq)9J~Uk't}2!=+3Y':E'M =t{%N`#L:X5MF#_ myUq><I_cl}6ז]ӗ6 n'v٧@AtI=;/.'(&Z* &ַLcVǭz۱?/4ц{r x J$|}+E<Ϭ/<2bE= Fnó`f&I{h7];F b6X`I^~ /ө] i2 |I!O V H)dc̤⡻cǭ`&my .Օ9ڠ㗎 @} VրV*2++#XB0_/P'@-cX0O41w <:u/&$(,"F{OJl+ɰOz{Ǯx uG7lndZRxx˙Ȋ /] 1!Е. `2yߏ[z&d+́GV8)4pvw7_7vYƗɀNx 2 d6_=lu/_|2o_u?[VD= <~h[VѸYQ8;-Ucºv qχ_PXh IDATg+;d{m"L>q`J[GGOnYu966ՁY0/7\^^m/;mhĖ1R>EƟߴ!7QP[z2?wMتR:kԷU,H>wuի?iN/W}FMq! {򑀍J(kȠIGfBe"ʳj`0JG`|0LֶdlR"|}GU#$8i7̧tPkri}[YN3܍q2AwhM)kQf~lޱx@@Ar&L^%{U㗽 ( &wdq+{Jji/(8/pAu rVҟj{6C3r!x |v˅~'O8x׭hʣZtht/=l"5]twxPu\N*fD۲<y:Ts9"V 2c A'ٕ.oNw˶3,BLYCw?P+X^BBW`k>j4 .?Fk5o Ozk!z}.o`el(\dΎZu0 G{0h-k] I~rfs|86];W/|E=B:5u-ɷVO? 1:gV΄1(e\wG>ŒGk>'kXwhX8| ͼ#Y}ǙL.D&|| ddʖ%9(})¶C S.S"#f۟!|mX03z B`o8 ct.Z{;lfȝ;&'dIf <}ۦm[.I{"T&o'gkJ[qՏўJ_ޝOSª0> Яɢ/bStm&|?\cu&YV>\|O)-\;}O& *16.=AVĤs][82IaC`n_/&*x~$ dȦtR-cjѮy%tް7z; }t U+1 DhK ʚ)^v<^N: F_uԞ@v/ e|p?W:BE_v4$p g)ʢQ?&KksWqG0sڳhIǀɩ@,v3})&DtʾH=L.sҦrVo/? pڿ_=73yx,x7)@"Mfz3||/W?:9L&uxE]d?lk_|}o&V RKV>lwgMMޤ=Rus{xv߅MXP{3jޏ,;bF㒿2룋Roh-tVJ'V=S=v}r*O&3('|~ۥG5Q6=?S}K]G6֏{>ٹ3k]HVJuvZ;1tm?_Iϛg:=i d}D>ks }gF%dy6PHo|71}Afg6e#&%^m&OGO\:`ix/}.mǏ GZ__1 få_6uqɰ-06!=;O|bmnM6J߮W>~m"⻹+_N|Q}꓆'K=zW}a˿~w]/ Ȕss*[s$XL Xȵ~8[J.q'HBg3D.fӏ l˔[ɋ&#9l8_+w .塡\^߂V|s ݁op12^7.ۜñN:ɳ =[:fi l6Sc ;\t?P7 t4^%VPT ;Q4CƊ.:z e|wڟ|*L|9AdplNoi$J=[{a | Iw+H%uKzŝɤat+5 x8u2IjB/#sK_d g#Xӕɕtty_@㼴0іEH峏_ _(\l kyLhuNk'[t5+Ӭ;i0gGJ~CO()o2uK;{7|7_v[ϣ0SY;| %To&WÏG.yN?nէDv=\AU9'aй葌ea\GJ}&]{˷}r Lbw&*}1jCƓڄ j4YMZ`mO &L$d`MxWcd\be3v͔F?7AGGd~ӯ*@rto''rqVP |O{ggǞI vܻku|xC}N<$|zN)^dWgOyýpŤ7=@ ١~`ds;V֞~O{Aj%>U8qZAjx~-Ż[HWv ?eUVG)? x LrzN 4pɤDV] ~u8r @8 ܘovk߂H~HN~AɈo"S~a)X rCSbQuN˵M7s?Y~x[*<"+o3gOyҬ)ɢv]_O>E{H({t2Mҿ}}?|4'x}3ޫs&>W>XElgwK~R!^:_¾_&K:wlyVXd贇xŧG#_ (xCe$1 ] :'X]9>OzAw0cK ΡvoW=+V"Dژ;K&" %_0fɍMv,M{v}A?ۅ7Уz _$G@>|#`yJ/>uշ_y΃+avywE{xkm# ;?}$ˏ_sMձ7% #P iy$a8Su<_~r/|}&I=ԳtQA\tLJos_W_wi vTa|NnqV>{*ݮAq W'=}U,Gb |N/<OE$eM`4n(A KsJYAnNpU>r.#3Yc@;ps7XNd:4mw ޶5rxW hTƷ?Pp@WC07ɇ?_ͨѼpG `J!ZBLjm?r|t%!|%]=ґFMW '=2a"hy郓MtԱ`v/K1g~5z.䍼tLZ%vMx,rlhˢ=;} l &pU>z϶\n\kXCoxn.TvEZV*eJ#vZ)X@@%7!?h _`S?o/;ڥ0¥^oGGxMz)$$g[Jt'z G*9J̓5zTкʛ><EY|<!}R܃OOQt'/0!C#3`t-*mEf/ty>8+VS#ȷIIg $x< kp,Fpn"E͂h]HU-)qxr'O0-2|#M1`ez)|E-FVUI8=+ak!htA`p{Gű ~㴮 }".8^;|3^h,gOك_27+շɢ- &n2\Ӹ`)7_ ^ml+^}AmN pvE.}vtxD I&{ ҏvyҴV'R Ouף#A7ӝvfBS?2L1 vԋ63ucx nvIOo=x&;J דv>m{/Ez7Wm__"]>.z'x~D>M&,^YNUėݧߊX;PbhvI]ov.gl#1> Ll4]Š'{M]:<&LB}׌Σkl̮h}鞯SJwmw;76  '_v{ŭĺxG#HO\ӯW~j) v8JOeS}QeH> J>p~?=(k0raRNDt|p$й.M{a\{ +cx!Qf* ˁʛ)|jx;@|Q׽nܔ ?zي#s;oH\H)]V\{z'\X NJt^UΎVMgV2V p'tGO,8$Ш/m6{ȖN:hh^8p^uw4~SVG[zCvpL!(t6}b[ՀsDr:H:p+0Sv婸\֧g:f D~V~E翏O=| h [1ךR8 RnNG4PAҗOMo&ceGmDKĭt]` )qd,㔡ZEc9r H#vچ="k-\]7k~:n=ꭳ>oip#"{ Nm]'ak mgG)jCHhFcK5+]P_/:(lɱ@U0%)m%M|gkE 9-y ngA7Mxqt-ܺڣD"H.׷Co&D!g*^Eӽ0W6:* lKvٞXcV3W~RJ8}ܕe)(_bWdǣ0 pG fHGs:<leݿWVmJ`OZw(tN+֗5t3{TAv{ x`[kWC_ 䐞ӂpҹJȡ\4k<_Z/{vm`<>cC@ݤcp\$cl|L]_#&e_ؤ`WL=6tM'0'h:l7>k Dh@sv F[/Z0Q.{Oo YV\}V?|qz# ϥ?MxD}u3w.Vw;_#D7 we%sfr?GΓ;N9tvL2*|XU8VN, اl#rPט= {ySFIp햢2m.|8bN:#GYR"O<ҩ >{;5^4FcKF`eJ?! F>8qm02ܟ8w9M0=Ts( 5ltyk ʒg%lмІV%=Sa8 أ#t28˟} kVī͓e105S{90Oq#5vKd0qgބʒvƌ(XTqt 77VcհAd]G:([ kr:u? mnkn =񿺡;%(]|x~K(NC (:3n?;&Χ Yo^sgz:z qmm'c/slMpud=slAi0_L_!k\>@)DMn|J2~F?SI#tcH`m`.e#M\}>ZW:qSb\0\|luws1G>x =t.mw4Mo衽:tT[8HlA{s&O<>?|`/dzfnGSx}N;O1R^5>/q"`=ӱgq?k.еQҋ n+q] ϵUeټ옹 hIo+>B`6'3wŪrGeN11=d mY@%yv&>>jJ蕫Yux:( ڃcG IDAToY;Р?=?yp-A/#"Cro?"_CYlZЊoA۶K;|4>1+{aam& >QRQp^2^~58Tio,~~cVϧb]r*V܄k?xVu0q`oHyĨrdW&=1cGr{_g7N4F7tZ>Y\0H.=R>9iHy|%MrG|x9:^T9b Zװ4Rz:ypM7ٳ MGWpΊTV85%8)aPF%.n<;Z9:u|/*炶*t;šB\ÊW.% rgA,->CݙCQ*MR\<A49piEV? i3 zҕ x nurP9>Izr1u: sgp=}w>ƫ;|M9.Goba| >*UGCupLM?. Н%/dk`-:hyTv^m:N=>hr>]c-6ڰ7A\<]cUShv;Z&ہ_a@q\ۮɭNґ͗?]=7~ɽ2e)٥>wv,?8~쥎+[j ߹%luw<_\Ѓ7o8k`34vCPץ }`6-ɜ|ژȽDqxf2hQPjPߛL /ḏ&I/5<lYݗF]̄` t}@YrlHmqMn'a[,eexDĄքp /> Wf6Ƌ0g]ܳk%+у L8?@{0x7 [ &A{+qNB1: N FI9tC]OzC}!>o~_=>_Hю^VHULR9wJI]xׇ>l`-qfdm^\_GٚO'OgN%{GSv/ 39$# L ˂z/E7?BP;k^g, VMԀsJ&tPѦ(t?^ӓ2 L?v0. dzKY:/^&f>E@{bD{2aD y '%hjvgc9So'/WU'r];^*ѮvN=*'LDnQ0/ëe 2'jhW7 :7(L2?·Օ t͟.ѣ~ c>4!C/8Ё3FJ1_ 7?zA/}9=6a~#Q 6O%?%tcWk [y-ubT pROP;Y$ҴMxi9Հ f;Q7B9@eF>s.].mLwG^J`ltP+ҙ8Ǘ DžsV`qLaew\e8FxnħterǶ(7 L "(򁗋-XO"MG &Y go ßCPy|KǗs6/>/U?K8Apks&Q/!k:h~ olE|L  ߂vD7*g >uIUԓNw%&; LVrNl {<{nR~:d5lź҈o8jÖFo9"k)O٭X1-aAn]c4x0ᥗdn]>:F3{ԤCP7 !8cͥsVܲ_|Ş{QuO; RF/i7pSw@=u[>AϾv;EږK ҕcA<. ÷8oTkŒ~6_~K\_ ~ioxclj&q8ʤ=|䴁!g )tc>vLNF>&ǏT"xyziɓM_A"ߟB|Eo5ZϪޙwN|0y&0;yĝ<'G,;&ze/Or?Ew~ O>o ]݃ͭx _yA!mq*e@Im+ț$˞&nW$%H\6Q-;3٣Qtc [ x~~,6P^sx|m㏎ztX 6 ٚ pED\>Ng{9{dȠǵ'F<>z<;ض4T~O_MľZUdrr%ާ|lW-Kޭ!2x^7Gԣd" o;z zೆ)<(+m;Pz_v׏-&T^Χp [lm/Wmf  $/=Wcv+?\8Sb$кuĿ[3=I9u1pF4w{u\U*ǰʺF\- KvMsN2~{TNI.+V)OG=sP#)ty[i5?]1GxY-\Sq)ࠉ<:g<=X9=}s#_G^۵A2+UeyB0. <8ݔ!dr;s޶Hν9}o2 P }Ueo`xh@?%O;G0* @|4tlPNR@Aobz"~@ƀoln/Kǫ_lxa']+g1ԱFgtˣ?Dwr\U+6ɩ:clAbtaARlAҵ:̯і`;.̿.}J\ie3tPg/[O=e+'\~u&7@4p-dž_wg{@C:G)CZN2A.LGJC {\.a얮խxwuQ?jNʦ'H#3t{fގ 2[u=> 8&Ǔ۠yw/KiZGgC]@=n`;>"Wţ8{|C`҃NGz: ^5-C>MG '8:{ӾJG䗣;HȆA}94A<d/=^:)y\?r|bb1ǭ06$t4]u-L[^VOȩtn6ȣ yr6 ^:<ӟ:=fpOF\Χ#]HjRiFdo.i۳ͽ XӊMZ^1wiHe+헬kuX;d3Pr>hu*À^m\JpxLa+UF1H@wa*2ЎҶ5{tMۆ>21Qf84[dn0Rh79VL Џ/)x AndL_֎ ᣼M6$c>Dgcs,ۆwҍ5_ ^=x|3po5G?(w5'bpY;L6-~K EW"g{1i~;/RtN#=\< |Eg䘼]ǮzKDcGMׂ޽^@yVׄ%ɹg| mn"{V2UL'Y7p\ûB:@i:"_ \:dWczz6TEtXDL0?XAt ಛ>墷Xsew hP.+\Gwl|5;/|!MbBŦbޟQ:kD&<޺gյ-3s?uAO VxWCf{%\p [hzCSg5&Vh;VGtm>$!yA=O?s:u,5fg{)|E鞞6y|a>oGBNk{H 'mM\mTe5e/{m+~7o'6ЅVn׭Fw HHhZw,E7'f {uj㣟w![>ğ(Xn&ZhAWl7q' R zazW'_8=>}X9t^=`: :Ntdal_7l #}g@>cUy .ϭM!?Sn]:8@`>˖m< Tѧ&Ca6z|OJfyЇ2ԃEk6<&G_U/*ד*]^&]Wto£ksw&V/ZCu~ Zc"u!f&}~R7v8r603⁽ 8uvB,_͙(#/&D5%t>{4`Ĥ|N0-7 RLҐcqL5 [Z{W҄7HP]*3)鞜pmf`bFtnmun0V_20& wGw ?6Vf3P&)+NީNEG޲LgFy m޵hڣt=|៌`~ cmɵ;Zc`_*zsrbѯ?ۑPkNȟnp F:/\ %(p?z\[{/8)^R8r|oIg"}C/~Zgṫӗ_w2?֘2*]8|^tt! *+59@/?\+e.>OGcqѢW⮳Tt+`%ҡ'b^:ãE~ʡѥcQ:M惫|@kA]ɠc?vt*È.UD'[8:q n+_r,~:?eJn |Ss|d-h&T(4@/vV+7 'x||#&Mg=qX~Q2~*i~["<zt(p7Q|xZd6dX@=Ve8kۊ՝x32}Yo@76E&=i3;npm5جn'ө%k<>ͼ7(9D٫Gz;k2d Zltj>o 88ӶoN\䪵AB:FS+?y?ԗ-OlM ^bMT~In7^< #t]E?qv]A|藽rƓarq;&_u`v Wѕ? V:Rs4aq V׆<=}9}z \ IDAT9>;5+LlV~ʼnMޝU=^}ux}<Ag 2#&J4Sw/.$O{ASc~[aON6l g=W3>s]I=!f/K9v6ݎ=<Ȱ%s\JùnG{i(cbzב6ɣ\v%uH=H\e];K633q3見Mxng.~r^?4^Vr£V} ؄h5pu _FqEqVMY88{+W؄׮}2t|jK~111(կ %:GOH=] (X6:> |r/ʋ?LG; lI5Bw34˸>6!N}v||r<?96v>/7KOSSC`;A1~Io,E8ȷY8~t;! ^yn Q,z[]*Nˉ{; ڋ?SvyM; WcKBx6Hɕ.}M|lw>$V0 :*Cy4ku#bDr:S>e]+?Ӎ8švPrD\O޳{x:z1PrG zV7.kp^}M v$j4/h-W.T3e15S'S(Ԇpͯ˿O}ﭯ(.Vѵ6qē6c={1OOOl9}xWɼ'mu?򂙸)1?)o7{\E{W%E&zSx0@>Џ)X`f쨲;~Fxt@-t|rtq~^O`o#g@m_&C] .Z&3ߣk<:JƆgH77t'W | 9~E];0Sv;"?{\>1:>Zh][8Yqof $Pσ̛y} CX,A un͠G}5( 9;/>}O]+~tѤgo'+._z}n ; jOB`UVёX\6A%m 3YWK7p4ڱvKzx6:|ā] &^<=VcCa{䟗},ɗ-~d[Ϗ|1`n ďЯc++WY}sـ% RD% ||տC}͏ ,k ;zل/kX_>G@!rJv>7d&ɷ6 (87;<"yb6KP~V+{z->xyg *tݠv4[8~ٚ^%CzH4^zU[ ?OжaC|F/Q` ?)h| ;>~C89 kyڠ<zYHLK: HηgL0?:p, WGf/?/a1DK_ٓ'J;Z[(6(/k87hFm_8n hpz&~pBאTq,H)rsWa`랂l[UT=2 |;V3 kK9N~#!8 nFsNx\ W̳U_g:hVg`FǙ ?Y%8(]hs|_k dίoF xoE8:6}VOy-(UaHw:R[ß#7wј:\>\+_%cñ@rmg8]|KG9t*T]e7 u0cx*S0~?!F?l$먮:dX@^j4_} _N5)pꚣLg™ sC?A7w]٪g2ʄO]hnUy>/`65as:727\Y:,9.'??ӑw•zQr9ëN=nЀL|eφO ΋v[aB+$&rg/?/Xg4 &9YÅ_fB.e?3a?]0] tOon]Fg+ř5@ꖏ^΄2pkKg?]*IMV+Dmt>8 6`txT/hHW >.:C[xw;>CEӚ,O^Yq ?bIf=l-1co_C61 UO>Yk#b: {a.{⥬SOm<<-_:~x2h_|Vx;1}v|)drlG_Ol6;?J\rfbʾyo&6ݪe0irxϿj 0EB0Do6Z !L:|B`*w 9&[O~vT$"^6]u+G{;}7_^}޷ڭ"AdŮ` @m~E٧//|cs~|4 @ۋęӟsE`,2ٻgz$0+80lXvoRc'q\(lzAJ(1K ֻ;([S_{Cm+,Q=Cd~[sd۽2{ݗDOtoė3sx.g>-|g}sY?u:M탯S>6=N_kgdt)qM&Oљ'*&* M^4^MK7|>g&W?<=`z &|#xDZJ;z ˾OMc+a8 uTvt0,^n:'G5cu'6 .A$8duvpαAv|zs:~WI@J#~e8 ǃ 4ZC! V:wo< '=ٲώ fi-"p$sRթ0£3*[ʍ/x GOvb-{SR~Uᛪѵ"H[w&gXeec+Ȗ~&oi fpn>oo=喞.R=S߿ipg`ԝ)o~Xe_e!X\٤֡է$u*Q i(BZɮtx"Wg J9 nbVJM:wf˕R٬_JML4\1QGm+-ev}rG>U[9|(\\ ƶXY5K?(<:& hP} pxu&^J8G<a}Q :Ream[|hL╆-cf_ܠֹ^M8v=}U:w_|OƷ0?-H?8}qTc{/{ohEkmFly$vShk ~KƋNC;$>IGL]/Ƿw I-?;d±lm\4+I&="3l+>*;TT82nJWnCsŎ _lD3^x:nE-nM& yM,t,CxUxٳ{.;db"C\|lW>@L,=h9K#Lli[Ou6ƩV=t{ܥxN3=]hyw'X1=^"xZ9o"Si z^:i+U? yLzuq}Vm^g[gwÀ F/VHFOm23{eeÁ?A#+3N6.G=a8 Ң_;= <`/>K4ٽdWh;{VͲϟS7%.NʶpSfDW#V:U==Q?/_ hӫo^*Vdsџ Z3~&_6y̸^ϒyvEL;V'  joZ1L8r]!sM"MgNLg<p|݊섏/| bMy9|g=Ģ|/s5_i+oA/;&`~9'^PnB,TMo=&q!.:%L7~9we~uhpdW;NA1b;:6/}I_~݄|(gܱm⳵ScyA?IWG,vf*YڮnL8R;f"g[~B)Z4? oC[S<.N*vl?>m'vguc4iݨoᗂtroUmY79J MJN!f=&<_=^wg'_7G\ 4#@''NJG);(!V)Π1\?8P]/HL~B` r]>nuo 9ʭ~IWF޲Ÿ#MO $?:`SIF*{NNުՎ`R; x d5Z ? O{%`h}s9{p 5Aa@?^w 6菟x|'\<'QF_' 51T|s:H~f]c{ 0/\M3{YGgळ>Kq"cɬxOeVI @΄ [`N3=bV0ڬZt~d*q]#S^G8u)7ۓO=a&bF7ctʤ -ls'7d}RLJ\t6&I_=@X8k28,Ol=49Gs7^騲|Aҋ/: /mk[]0~lN| Voc~ jX:CU".>ѵFO\9k+n7MJ!.Pd ^i˛ly`ÿ{`d A4'[u=G16e;7CvYi'uEڣ2 /84A_񧣹m:# hOgaWy9QWhelcgQ@w>^rz}e;։HNv7H>誁tDLG.`"bD͘/U<Ú1I7aNT'dž5?BCl֮:ɷ xt`JGٯǠf2{ίf ʚ+=+@SS+d,c,KNhժ#Dڟ[,d@>zt/np q?܅f;OU}AH<*rJ[=``8=Puo=q~y/xD*ʣM8k7d RdEͶ>:z6G[LfsYoɐ+;g=?(8ծ|3L)i evʎʆGY:53IFD-NVExzgOGfK> l [eΟTy#_~?XzԼB|>ѿ ߗO#}7m|dGg6='~dLaq~JtMj3 ];VMxn9y %?hr#/^V?ux)DcKnbsPއwXow}-dr:zwvۘݽ>HwL\e7y8=$}3ʓQphڳL6&#Z??^?m/C.N|R8D?p/?k'>T23nҤO_p%9>m]Ϳ o&K@\]<ۣ1}> .m ]?7ۊ0G<ɢ,5r@:k-V4]n/Go _y;+j^7?dzo@zC/R?l(кe=oy,.ںpxй(v'Y񟿔Y%˩WѼh\7/xj7ﮣNIWuuFP/:*nzT[{n@WLuNrp'Od+V$o~ۡqK8|&Y-{~vł/…vfָa݀*4 ~Հ>95*04:6VcxEhI]JIqf{PWf]IJݝih@mWt@wN&4wVʣ7<)]}sVgʈ59Ae+E!0sRrV=/>> G|XMC_aV)tG]eqv'7P Pwvea`w2gq&O?_s/Ɨ$矮۠.xsa{Avqf+ŝgm^z_yTl͏۱5xC G\3ݻ|~)#]ҝ'ngCܐ7N6%-M.EU)b\"ޔ4!1<rN0yYiyb,_x }1)zi:-b>ʃt@8]tp> ұUJ:0Ûi_g`2yko3/S0 ]m(9tqbu: bVE@9<ԤĞI$`'|Lx69+dI+;yM46\M>" @_5^ldxt~c\p#:~;;+a$s y=< x!8dnwyW&g KL:jPDtɅ`&LL:cnSlWx|3P(ܗȶ0OLWu2dtk>!xKg=Pl'XpAsP5ʮ7\P]@יA^NxHb{+qj>CgP0Vw/'g(8m =mgAZ'=]tZ=LF9gCvbNp)+K:3O?~l!{O6u|m_XۚG&zLf|Iڻ"lex ]Otmw篫gX<:lď<Ȍ1й>PW~ۇ$~NzGGv8]݉~etx|k(Svy;?'o89vK{՟v5h&$W9[cκW&_v ]MH&.ٷfH[>[eL'tWPo'x?l"0?4e{igh~RG׳Oѿ̏b 9;v&&2 _|Ԁ]78,o7:yu[)^6Id^.B:o{up0aJ\ڦ|6wbyߙ8/2l=[1GL/[t 3>ç|m16uh_|Rr8ؾqVmq7M|-;^boϫŁx&/dq=丈k_Y_\jo:z[do:jұځw6!åti/(Olr{qZ i?.R <~6@cl9Vf0Te|ѿMf'!_g&{ MdptxDAC:cMtx7],īIk7Qw)rǿ=^3s3oή1_yrB>\Zlwk'l>vW~v2b3L'=|S51u.ۄyM/g+Zdl~G)y\n5mw+VCxdyZ'\rP ޻' Wz/FA=_ޭC> o|N]%XrJwv#)Xgm߂=ua>_9zI[I:`5nu/9 } 6Xܳ=?{oozJuvvb[vA]~?g| Lȸ1bL<& 0 ћ^㇏Mo Y'7ĎnF`&O 욭[Q[$:dV TLk?+\0[M3M|>ʕ#ʼn,1yvHNm4ĀLw`Uo&i6ӳϵ=m&xgy/lN阬d ~g>,=TG+Kq1a=Vo">GƌW:K=һ|r:ͩ/nFg6;ՑH];?B\/ޏSvv蜇Gcmd303X;?z=-'g(K:.}aǫz8wE|FK4Cy&2J׵#ԉ{yʛѡI? 1ow_q^5051{r>͚|]=F_Q182[M|v<ZY6nAz<=ѯ _-ND+_f̮՗3'c0xdߘnqͶ! n Jup-@<ho>(Eteg?GjS58iո \m[嫗M(տt Az[vQT>ÏXp";J<7SI<ı@Vԓbvo/]NsPI#|>xx@;< qZ'|j LMu ,Quʥ};7ߖ Wm:$cw-K4H|Ek|&1  Z'u*5ɉ>y ?]:t$duЕ>iI_ WJNx nt+kL#mn#|ќʨc/SnvJ\ #+86#A^>2hp_8 ?u߁{/ЯRo"O9|1Wg~P;3V3<`Կz:uח$g&)/Z[xc[IG\AR_T?v/tΑm\ҥWcn=nt TYYXۧ0z|-Qg@ZĎ{:ZʄA4K,_g6ac0ʖƮwI/%\}J-^x^N?fOHi])7opSq\ǼpSC 90o)z&3`LpҦ'VX9c-%‘F_9X:Z|B ,g8oX>8GYGum:muwJo v+@Wn}N>𛤹+ S?ْտ,:$J|o`g[́h@6zhý:48묝`C[3D-~џFq=}N 4`O9~F~$;R H9ΌٲcjΧAR[3<#_cdž+<WCN'tN|u3}R>(3;}wMGom؍.]Np78oH%12(?RlxAa<7Yrc>w\^g#k/zpPGG0'?Jуk.uJCtӖ&#GPX+oOd`Ϳk/coϮhGL"!8[xΔ[U)F/6.ѳuلG,7 ln&l+Rm37;BwJ4oyb=л;fH,>Vdv|k|M|<{9!Ascb/|cz|:6 TL(1o6et@6vHT.r{? j }vC؉p'j/%b]/ê7}ˉ}5X(&g7Ocϛ@ *tQFbO970WH4.Qru = oU78(_\_ÉY?L&hO  ҬrCb~Ϫ&]$`}P޵[cR1Pv  >p%>LWgONuⴼ;lraYCO IDATW&{ #X3ގtQmc8y>כUzP'U_1q˷N݈dpkߧ 8cfL؞ǾtK);Եl`}  mOy'Fw'}\>x*#[}8"(?E!0ЅG>|)/;3,o3pqnr3`3>ƣu~Hǔ 3H7`xPST.p|%oK˫6da\2w=;XA5+87y ,4vT7uO'n٪{fzTV-x?(6/v/o|;B/?*ߎM^Gg~aqNzԱ; }rt,nt \+pjGKη"22uPMeO:+lOg݋ ԡtwF[+p:KbiWe;u6.}_Xo |lc[ј_s ti{`pWŘpWRɪj^W]^V؋򷎒}g# ڗзy:vX>[ݿ7:Dgr nxd/tLZëϟקvVt7jsh1I'KL G\Wz0z>_Xz :C:K+Skz Y:Zܥ# Ň#hj=7ᏏKN "n mhV @i_W>X: [g> rn"mNxWL|~Pς=l! t߭ b#xU;֑ίU;NYDDcAsIGZ[^[84C:As.g_$48lu~ ^Yi[Oؠ.D Km'5Q+ʓPv\Ru8nHmΣg8 P& BD. AV}gďH%vS /a ^u\G ؅]ɌmԵ/~3ͧvlI{lPjf70lүh4a QHy}NV]f/] pcxgBSFi[ !t>?}odAqɶń }v,FC|/5 ~ >=(ޚL|kR--zm `9Y٪ r%^m!r(:/n!UP8_ҷ jq䶷~yCbbv |`m~ڂ/r+?Æ۱ GAl`w۳񵉥Gw]G{ĖxnzA}o1GaFM>w%&T!*k7}ʿE{KxPyhʙ_ w.gsKnR~Oo~0i`$^gs襣rmWGBQv?!K{`/ W0u'v MYF,`g86H(kB6 Q3CQyu/eQp]N_VBsi2LGPtuF=ʠM=dvP&Pz)KPӥzptJՁÛH ȶ8dk"=zaT&I2^>29󎕟ҭ:n\Cxz?v0+Wׁ ؘrJ[J^?N du4k0V= xkSƖ4gsq<`x9+Q }r!'C^G5óGx--O96/r;u}@k679Ox}e>c7%':ybWOtv(#VZv`C ^V%ֹlAc_}\'&riۇ?-VvX'ػwvd,ݓLp%ۻkӼn# .؉ll]jgApZ]w:l4צ>]$)ŅGu=Y:¥|!^}ȋW%"XX<%өq~T⭕Y\)/[t%>}غ >A+߰Eǚt&Ezɡ4HV|Q|Xx&CΛz&>`ۖ ³mWhϥ^^.[>W&[+)fS>>f;,}#V8Y .!dSeE8'vS_rTf6գ?50 SOَO][i Ҁ=_=Σ IuMO{"]4zWk <7%U} /DϹx?V$M+ʸ?M41ʣtN[@j$łY5C^K69W?s'vF*Y,+'ƫbO_Z@g*SSe=>w_SdljvptVPMŞM%xϓ&3 <{閵`\ V@DGGDKM6 K9CNlt&;M~},>TɉMHhjaSG.ܧ=Jf H`U}v ;^^>oB`tt;Uv9AeDR_ʽo1j ǵfevP]@S:~ؔBT An*).`g9.X+73t&.\%ZX̕d\Nb4u2$o#\ .0GCYc.}*:jÉV3 'KxmëCt|Ϝ~`,, oo9N'UN?I$f+3\].<<v=ܔvv5^7<Ѐ".~ VB.}, zxVFÛ b3?`vq25=s\ D`4|#f=/{_~xOR70X,zеD/KG`?%kod>m^ 6/{8:`g\Y(nrWY>YGCcFϑkuљ! GՅ5|gB:OLH٬ܰ_~0i O R+_<: #d6$k~͗Sv{38zGBN 'rNGo^ȧk!_$O`x˻t㢓h^aW]Tg6Gm0&]y}43`;GtBշ/`uw14q/X't:$OZ[:g+Fa7! ɭCׄ2:.2o% >7U{yz۶\<Ón $ymޠv0:GL {yϵ{R:R|+vx~$8݋F(71aB31N|Mutrne҅5YL6I6ilNLm{_s{+mDq쳞 ~ӗX"y?]q}Ѡ똸x{g>X9e@|}z1<6UqMZ ?? &5{T >oă|Ņo*>JۡGL0zhwWe<N6*Z>kϷ0^|Wm\< N ç^/zgۉ!oN_?g5ٿ_EO{cȟtMvQS?7VקnyF)pwA;YfsԦ}/#En@ӏ=1[M\Gݚhсg2|\+Ca^qm(LВu|H1ܗ͗]o>u8,Nt=);ʓɰ*7Ϋ7:D?t=颼HLGt+`wu'4鱆$''Zt.t)xft2a1iHuPj=fU'0D;L*k};5S1=DSmhuO1U"C|2nUFRW.?h5[âj l4;vSl>>W=L7 k 5h{<}KFgoB$ݩ>O}6 , H剛SG\{Pg ;^pV:"O@C4k欌[krIH~ S7WdTfNvFK8>c d,ϯ%]:f:̵DYg-y`[&ZûxdGmKt_12~Mn0?YJcЯ(f$^_ gzatN^9} `Î8;gUOzyEu1yI۝n&<@} ]7Wŋ>A'_=dwx}oU m@%i if, \ޝu/_~Z`׽"zB0}t{VZ߽NaK>Q~hGAl`2C`OV0萕-t 0 ~#ôU6ΫȅBeiV/Z%LwG:@Sl+1ĝ3 g=ozz~僁oadp"fJ<1ƃ _׌I#Sg~28۴tO__MC[ LIq#C8Fh0cKӨ, NF5(2li_إ@'jgK4Q\GŒ`÷Uh.[~5XYB8D|O%3 a֜F#dν0Fϗ*swl"l2)7L.9 BsnI7Tq20i)Yόg:,S *-\sg) ?wqϗ=ec?ˣOr˖*Ҝ0FӽJ>w;?oXOe77K秽k8>-Χ6rq4?a d*~o2-J[xݗzv0O2kYVrt&~ɓ﨑e8^\ P W/oO6>>l˟VBC`:^w^lX\7p#/|z7PQi6RM'.X}PD`g0P7)]ً'۾UJ +:,?#,^|6950!&jX)!.Wz;/_.ѱ2 _~+Rd"[YMϰf0:~ }w}zq.Ng;Z1d4ٰAS6}%V€(+wA,e"<{f#·ؖa̞Ԑ T/فmg|`P^9"8xUKy&,6W3n4e|lls O%t'hD ѳ+wz@ئ|MaeSK˳=[:[ڥbzK(nl"+&ПKUw2#Dᒿ|63o#6J|ge4uefy0r6⬓R=~|yM%?I( .6w6:)R)O#s9 ASJlF7ԹL_}Ý d <Ѧb- N/{x(>u~mj>=ۀAGGavr4"Cǀ ېmlŻlV̅:l_ IDATѵwOq`>#8]$W_>c߳ǎ~8xUx^G/iiOa=EVʘ@q?ޯF, >x𔀏xiAfXuǬ?VXAHfo$XZǷpe:VoK1 WS*F>@k_ZL|^QnUqa[UZ L7ΰ<>7̊ 0q:ᇩ5y` 2cEڳ2g0#fGtmSAI n&$zK1P1&GRWF|%>݀2<K{Tw嗯7 r0] mD1J~1;X:3[‡xa߄\]l!g};; /IS~''<^xl2myb19]!RGUiCi ;2\zA-#͠OK5n^oq;ٱK2K{y +YTcVLc3>ɵ8abB<`3x>GwOg.Ryƿ&5c 9{K\ɻ }tVz!ް:~&-L.o[yXrrG~W舏x?2<|ǽq00(,:[N^aV9_֏ǦG&J2^}Js !ʷ]bl`$9ykLYsA vev|wv,< {ev 0Vƍ}*+t2T(;|հ*;ĥ#$ } %x ? eg׋ : IfjPE`:Z|̝6ۮ3#@p;f~QF߷ܴ짡 vN}V~2!#fst?K%hVfvG;aIi%|:~k,gӕ-`t)]t8aC@ƻ56M<1Xx_azpd$?ع>;m5{ϮՐ_6q8+u4`M_dGt9{PdyHKD W M3߷Y>EV?}-UxCFqYփmVܗuB~߯.:7#c316˸NdD|}P+[x!:4LJ<0:&{yU4t.Ipޱs_'|ޫ>H:pVl]C_8:tc7HY:jP/nx6!+cw"ٌq?&[ 78kAGMa *Yrul<ұC”1º\9nL;lD FyC43ɋªwaZ}SN,_ʲ.+OwoD*7ÁkJ4Cz A kP ]3?^%kճI LO_cӁT6=} W| #iT QGPE]&F` @΀&akFI8H7#Wlw{Ҋ32xh~WvEw+bi,Faވ* l KG`2yu/D%htf\a,[1zLe#S bZ>D1]h.})4Z rSOpF4̷VLVO؉'L7mt t3]U Ki ;Wg*Bݺ~xwv,9" 2a>}=;A5+F&-[K8ש)|OwVa(db{:OgO,kT|ط)gvC?UYlyFt:wxH ΆU`|=X>#| nwAp0ZYVt޲٨_B&s_[ 4<]T*\3fd ?Ӌ>](7^ugN^'^xbt_y}|q~F~t ,@)x?YgXΗC2h/{𕀟:£GT7 !Dv<#勲h%H| O_/[]fv(:nR!Bs]6ړ;1 0%yjFwYQѾ ౯7x^=2]x8u7Q4#һ[Sx /݄!]x?fҎ|[:+^/P;%w Z_`6G5V_H;gvy. e I *4xEIgL4ʿg+j.mBװ]]WGBt< ɘ@{.4|wf"{Zˑߟxٶq)٬kWdй y m}`y<d lJiK8u'Lua@.>HKh>^: '4>a>umuiʥMeW/P[tN oU ??:?gOsMK͔o p- 9׹U xmƗit芏cOg Vc՛d@_0 ֈMagY¿ ]2{ lυugڒG>;=/;d/o߾yGc3Y~Unmɶv`v=։nV$8̞d0UNo:/0o afk;u.! '3 Gu'|oh>[d>훃)Y9 2e5ʉx w>7[^"^t6H$I_븆 7h䇱<&V`;-OU&=Tḩtuo5t8 {YuvAtGr:$A|˯lva>=ɦ0y%o kAjr=;':|Ovڌ#YE4/]nKD+ NJv9j(m'3pP4cg6[9Hi'QQPُ霋ϡX Ǻu%kr0 L:Bs/M:o vn MsHt%/]f ul$M@ =ְvWo KkH|~rfuNw΅}4?MX ;I<'|9+CCl萭d_ֽuogit~RR|їYIVhmn\==L0/0z ]-Í.4wKS+̧_Oũ0uf~}0_8?6,@ƒMB^z^J^M dWKAΛ/FG˶7~g 6(c>tM4G⻲M J6ݡpIE_2e+%dd0#^p#Y3 7sId@|b[I'~ [&lkg6+9 )f͙ĊAwa'f3 u 񈯤򠍲ZξN=Kul&t$\Vz /͜;KiD@tkW'[ H#TN~>y:Lщ( 6 /+]; ifUwU<)>4=8Qt3k5!=df2ف^̮<{:b//Xg,y}S7f;xvSZGt9:u~?5iSʞb2iq__vx{:;әG֕50`ӴiF zN@|tF=1 CΦ+WJM֚{+\wu6ټfgp5ƈU gCAYCp*a:_͑]ε:1"M awuἙB.+ }*?z'w|YΚmT?B(A X$O}ЛLzhlG?elbeLʎ/v|{iKNDH:kP9W4JE,?K:=y~ ex2>/ϝNoMiơ{E3WeȻGz9mwَaRج~-!w~wej \$hdCoccMі>zW?iAA.'I '*ct~ѹd*?j; %xсP ~_'(!/caބ9'ዳ~лQY\ VL6)x?亸s4.T!]w38Q2p;8iwƻp~hh@'vkdMh&fV:Y`af('ff)h 5#>l wo!{"QnOt=Tb?(ُ@lUЁPc8]v7 r]~F׭ßF::M6<-ov C?7$\&>,0CymקA_Zhvruk/?)8wXIC+)`ңaE4bDr:p ]}J ȎIձu /n薿KҒwo{2FSZ45*^iƴmDwa ypG؈;EnS/Ir,N43',e1*l&c* ʌ͢OC!e@cB/{^@2ٕS|O^k8/n'֙E3rt//lB'l!F笢(hKw;W9av;_ #/P9W[[atRum#H=x?ͯ%:yn@ԗ1rK9wE 8ÛYuY%;mG'|%dSkͧEpXh=XN^))Ϻ /uvHRpKW"is"al9x85V褬A9e~Nמll ftN ,fd~yfjMQ khuE}j&Z5ke_zNH)MQt(l泖)̴ߛ_~~>ϝYbBYhy^ÿ8:u> ұ0dL<)-X9PZ9]x f~W)'2LQV ֻ۞qV̷)m/Z!/}W>yneD lފ0Wt}]g3d~Rb~lntNOto+:>VG˪ۿuaIv`H@^-ha r];v9F`ݿUVW4:o:}ٮYuȇ$}HE|+՚ex[]ʣ:((O>I6t_埞FK+_);>ܛM&4#$/UО3]= }T/Ka}W9\vS~s@]i/:ls Of, eH琡ޟ($ zHv}ɗ' j8QZ0vϤIγQtW8@2t=Kf$sSyuuɾBS<2fޖ6#^Zt7T?ɀgsQswg3a}i +~ph{6"8>J2S8)N5Og>쫿Hkɷ,^˖<qa BNkpd@]U(SrhЊ6$}nOVIL*^Dfح@}289σqTYWG_<. baqѻO^.]olXÑ+' J[3"/_yWeɓW}Av_%LëC#bpq^~g<'y )|yW:*{鹼8[[,5;\D3 Srt283?YNV *+?FVga C*l]ҕ͖W:GK쌦3Whӵ ~R',d;vV,O'gQbkcYy# ~#:[ͰU6*06KG]2XفQ IDATy^UѸ1G)CU1PgW-U6|ъv}di* ӝ:#;8{xPYf˳i)?`5ѷF^3l_gN%GؖoFʵ.zBf2H)Y wq5(Ks%IwͰ:B^lPo+ͨ  Gڍ^cUׯ?%WJVg`2ř\PE-o}*g@u[암0}XGMc'I 6ݤiެr2kk:33Q=8XOF3[l{u;*c%Ꮶ' pu>U:A v:<.tNqoqKo\]v#:t颗N/~]:DGzaO eI;9Zz?G߶Ȱ'l]fjBkY˿N> |jC"~P i]ףeD>UVjtJiY?r?ѵ#6dgke?JAQIί^}fpd~V`S~ϒ&[lᵃG@¶J"#|q&vVέ V0JT蜮\9 ۫@V%O3]O^y |~*K{#l Tސe rfy/aCeOIed+p[u$OҵMP7=ex=o^B5qR3w4mbz>,A,j+Q P{pG )]A#3^=yQGe[I&Oup;w ؘjp*BL*kP‹U%Z<Akj49=is_<\)wIc8ΜDKb?/ #bJNkH!,&Dž-;dJ8.{(A~;O~FBs352arGe9hk@ۢ18d/~7*ӫYdf /g2X͎q155 j]]xM, u x Pwwؑlуa;lFΎ1B+ '>ɹʎ(^^^% ;~4!op/uUY24( 0= qwr!*O?aM?Ё~X3lO [F"^p0+0f[lHsfOXj¤|4|y'ţc|,+jfG|ә?NdU6?O=CgyϹ^J` wܢ/G|:>zϋH7@ s59!$L/k;[ 0"RGE?}L|4 axĊ`Ou 2?E;7‡:oM^O`wW-R47?VCvh9S@q5=faE4&< ?k;@Rv3|. :9/~%ް_wח[:uj#<JD-y: }2A=t'yG-/A[]B͈ܰ x¡afIxa9mh0Oi/J > W_Jc,+FO]\:W0Y=ks^6wV80zaiR!V,+ݽLlh@g(OaR^ D|8|=t/DܟC+#%_lOg{P.\~[ /)j2ܤ?6+ Β'^iVt?M 쭔=s,NHxw?Dwh03J˸Ŧ2pr3Kli5\̄ڭV]Nmr`;(B_)~+XP9A1Qsx2 ,,ȁ3y}z&r";iNF90{vcA Шԓ'qOY:TpEy3O7lc;1fȇ0Y*v3lOo$gعt [y{F̦c{2j0yaJ}l򼄋Kdw-wyYaI9y`0_i ̝2r6EpRy6lrQϫ5xjp~igpe˛E _lIl E'_ڥΗGgo~tF쎦tGc3uVƆ~f]KҗDjX06vAup/_bB:vt~hУOҎW=}.XOG}d~,4 VM GVVtx]BKV8_] ?-ENrNptx _K3謣ѵϲRdѰ zNʟ9'NAnNG{쎍~; ~'L;sMa? Y6>{͘Z!/fBgjF)a)CH,叴NxWc'نd׊%n^^gFU @e`֙Hˏ;tVK7[Β8kvוI,O =R⊦b4vVJ</.U?oM{lgTYGxv!۱="CrA/Rk%t%?[9sXm*@az3[1(+??ωrB"M:M['FZLq=\R */7x~:l$,`?hov"~ZI ЦHtRfwdPiy峯<Ba##hשChw|2pVix^) #  {IQ{'_k@XGžu1N N1.}!i2 ՒFn%=jL=yޒr٣xeJFXɵΙŭHLx~ %bKiŤ?YV1o&F?<(0~@N<(l,/GD}ݗ'._$Ÿnɲ%~itp^<)-?W~a!;/ <+4uOa#UPf'W2yC˽@p6C>h?g>_O3={̆=H:ZGWie)#?L&t'F0&Ny Ws~z˶s|.;>ca }:WS3~+ty]Fb0-mF>Sc6Ð_Cq'V~x&<8aKҒ9u-_ [oʼnkulQB !?dIFqxKk䋈t[aw赋}N!.5^tO}`r# M#7_|?eyoʭ䂫뫖HSnX !tc03᳏Aeǭ[DKhu[̀/J+ ' |Ĭ`jҳ4K yh,K#[eA֡c\!ft6 :y >Cwhxa)t0)$w +b.,Ȱx^Ngp~5eVlh,0z?< e+dWoڴMd׿a %cå9Yt^3_߃]2?%r~{HuKN5+l::\|aBu͓LVtifoO D zRz`OëYuWtsul:eY_\'(',;SiU>Lfn7*mX\xN]³aì悧`HA ;4E@snN赟ny?!306ZׅHW8)J)?|쯓A{W"uLa[> )|CNş|8wv_xLJĝ~.=\* +o`ϊ3@|5JsVD">զz]{T/<Duؓ\]K8~qԝ5tӝ}tJe>:Wc+]W]N(`5f߀BCtfS0 eU#=Zh>|@V†ʃҬoj3zy{]WDsSmg?#_X_ 'zyx6f]Ona.o!|=\tpС#yTj/UŹ:Gf2?Jc^ϙ/,+g:Ùf*mLmfeEw<ɹJ@Acl_{ȰeMqfeӞ6Cu|W.&>8C:a~|+EFޭ+?oSK[opm֨[{O a&9>Wiukr]Ǘp[1ٮ <⩪rNwAaa>.|Է V )Vv3Nf ۭ̻CzfJ# >Ӂ~:^i|߻d9 ~E`䚯Eá6{ I9LG8;Y$5K7vz}Ln`?Z{dz'%f ~qr. [Y{*Xѻhڐn擭4g@o&kg]71}8f-eo`^ ![0~figpH3۟lݯylԥQu̼NMtz~ܲ޴/%KvKc1pdX~ꒌp|:'x |@ǂo SgCc2`~}G\4f vƟO'{QV"<3G>Ydy#teϧaȟ;[_xOayζ8]Wagϵa}\'-d: vct;m\5J<""߫@@ Kd=%t!Q >D3k=ê |ܣNao4 <Ă!٪^鐹FxUs9;]-4\~V:|W!pfDŁln[T0 ;>#mɑP^:9w0NWCKaYdn4/^x֠'oLBa|p7>~~9a]ͮ$mjR<ޝG&S=<О K{Lf:wZ^!sk2>*0=l8D~뼎n<*yUdVr o HT*`xɾU%i}W IDAT&G1h׿곇:Wapv|*:-8rgQnm|*< ,~k3ߪ¨@9ڈ(v? "nK I ϋVmJB~~hQuLz^8-ׅޢؽ\曓4C~5Pn>aʋf^2 u\ql[|`*bov\L56g}CtTprspDbơͳI|͵A`mDS3b/ja6?yM9y<̬r/hd GoamQT#aF׳|t+gufL0MK ٺͦοLk+:elsSG8c'rlǏz[h4*;}FU :3u4)VonGM|4w?VNl~vH:PWCv;S~>:oe]jh\|X*7@^v `ytj:`d1 op=贙Vtar c3aӭLϡ֧l w^^:iF:Hf 7/ޫ *=(y5 Flty4Cxd'>觸Z`ZuFYCtTN8hO*R?ܕ$ 4|hcb+g \:8_։$ffcV^$yeKJ@]c￷_km!v?mCfS~VNZr*Օ3Bn%U0*f ze}n &Ǟ으Ӿ=}7$P__8k@3@Tݯ!' {=8-*cv ;$xdC *"}zrYqP3ɀvO|49hdq_޹katd`2BO!Bt/W&1sf?ρtdoiꓣ$t2 .yiY&-t,3ktI^N^|1_  k ?^O€,.O-WВ''ld_Df[RA>D#MHN=i8L5 LæM7Xx۵z>I}4n|֑|<.T9Kx6ӓ,Y>J?\oi?hώWm|@BӥN@3U&7Y#=ygZt_BW!ե?]"vTp%/2hi@,"%'GXʛ GaJӹ.O(f/ eWs-QU=O:^vI4#왃ߩ@lt?uVZ_~s𼱸1; w36;C)_nTG˳Y:2NhN?K"$d nϳщ0 5 ÉT=iEiX"_9S ;;f7?T NEp (>{~f]`LUyb~5~ D}_cFK{#h$iHRS=( &*r40,gǶ<\^ /f85-~\'_6;op9Axy?/Fd- glyAV(Ieflh5䉮r$_y/֞ ӰY~+'"ɫ=0<511˼+𥳐hvO,$ fht%>#?;):t&t~Qާ5V˖|uuK5/?h&Nhu -)]yHaTo} EIa2l/M5E)JtC똝{^HhrxCeVgF 0Dk+-UJ^G)O/t¹]D+֥YV;r߳@Vho6NlF(_t/28N4t"j% K~Z8nuϕ%tr\ʳ'|:a^{E(I6rtl:~ӕ/???m0fa+8L^+ɠ|f•?gad0F|W~t =m%Rc~i+ 6:#Z:2XI-~,S ,t1?c.7;eXas،{`/?Ya|oOh/"pt3U TzKVt{Cћ _Za#BOAV~OoIx,?^7t"akB1yg3ԡ]QiOcϼtݯR>hƧ}Y:e{=e՜@_ht>y-?0GpG;'N׌? <.~@e51YG)DP vu]sV %h|u'[xJbD˳NF 2O?^dC/ޓMLfUY}BNvK$ _nU:gJG$r]u /[/.=-X>É/IBAYN7FZ }5b2N {w*~6PX*$w;F`)_da><)_Ƣao`gs3:}+C&,;|91:+o[.cUF0:l-Ɍ~q'3hq>eqva奢7P1}C$/W)=5WZ^9$ӟ-൴ɓi} r?uxik _v_݀!w5|[}w<"^31x\5~VnOxaԙol24"`ۥ#Ү&|vNȫ?\/ZyᨁF$d4uwF$y-gvٌSÏ/SS+| :Չ|rj`[:pғfoa|wS[o\fnc IP:8z.:/ =e}I@=]cM *J3߽r|sN[eK:Ӽ $oAU | ξA ,JL/T;{Y\mp} /~I|83q-_6_5>0Ng_vnu'$W&AxfO'a+NtVmRt|Ĺ}>|5Fu=ytmo޴Ց/K"f, "񤻮#x!4a+6cOvwt;vt^( whB@kqiw+ zswP|>gǓ{.6*+hTkik TOQ~!5¸]_)׿\yڇڀk+Ew(켂W(A6W'O{^ Ǔ翱 e#PhKq-@KLҢzT'OX#+#*J{v*,ɕ%p*!2O+0yOۣqW{2u=q$mNUqc WUdXSzi8+}4pg.GO/ܓe|Y٣t{W_d_}/ꌵ RF /CLϔXh=*a٣@0tgD) η^c9'N31`U٥AA]gQi'WA 5~;aOfҬ3K0^m^;N oblC0r m>V| MXNS%֠lXIг6Ga*e #R:GK,Sh!H$uVu_ؖ(%`M?)k寞>~We{ 8.̎%]+0+L7IuFC/+l\4y4*+rlOлYa* ӏu5&7(A y5fx)>ɛ2Jʇ;{r6k%Ӱz>G9k+;˿m"2kx/̞|+57<0Gn|P'b'df%^0|-?SA nTlZk +? Zy8{R({ğNF'7z eرut|6>4c/TGL0X|A,*mKkG!-AcM&"d{~w)_⓭`KڷdtYGWvov\cQu(M5Kds^+\GW~eɄLK_:>* 5*ClS=Lyh< (ڥ.ְݘ `ߍ|Q L66In2ϯBc>ql:[>רE߷ .߼n.=(2Fc\<3|Qm5kEXz:$f{~SN9[<)ibiY:{enT_;~/[cvOI8̩zS~DK.I!ɒU^Wy#ϗϮ]R@rhR4kF:sýgyτ递tʀٶxA_X,)e z=z=JEXy)ݿ6+VYb;\Acsy<.VuV}{RӢ:a x )OOH<AaT =I{Φ9ќ˷O얜@lZ u8 C0|l9a x0/EevB?{ dP{|QUd) Gg>M*do訂8|&,e^0+KznVz7 A5p)펱mEXOw!>r8)'p9,f{:U=%>m<ڙE7d.&0)XS؋I{h2Eyg?Hx/SklĴ3)>>9?2S:\T|8*u=b(S0ԑAX?SrT\ >3d! Ҝc@B @{v'tR( E=N*X|W##J;ᕎ0r3|5ڃ#ah~'3]) }gx,~4B2pL$5=Jmt{>YMuJGwZF\ >_S55 pH{fZסAޓ_B"Sz82CHv=՜{2p`Ѷ#DEO?^CJ}xW9kI l/yJ7,"A.~9((ʤ:T'+]`xU&ݍ\o?~2=}7%F[ /e!R~l%5t_ I_9ٺLV3yf:>g;{k <5#87nuf_yN^e(ef?`$_|ۗxg%*>}lv]o1ۺ^&e^7c-OV3uغZ'Χj-`X:O:U67Ct7l:`:x[~ ~cCw:S:یat ӱ홹hol E EuzÀHۗ1 ѽO(^,쳓k'VfTwʍc`V\~zkX'N5|5p^םO{HA;}g# 5pɴP_u|t)d^[IN\N//{(+k{5d3D'Zw2-şʇ齒ehcgPpcImt?K{LPBF3y3=ɑNo0*t>&A٪6^hPO$4j!J;Yen_zXC}W.\lP^W94?"|ٿWutTЙ̦gXOiWoY'4V  :>3كL/?:?"t\&|nӽﭟ{D~գxzKO+C?yه!!WCw[Mg/)s.yVx,>V^+VB\gW ~5ӵt됏U dv*:_̮@ڄHS^h6KddmK7%x:6XW'[6(ˏd3L ./Vxstџ/;i ] 3 zhh;#}޲e .W~҆q/m>U z]Uˎ=@bLtz7hTcA<:`Y>sGtGya'O_iUMHotذ-3D:s\? |s?3Z&G(F`=if yy {#1f"wV&DV`|l&d<3O&|7",uCz Rs ){eҷC~~ꘂrOȗd$>Iy{ٳ4H,8h4=8>,\:NMd%Λ>Jt5gf#>7w=9tyt?؀^Jmq?gG>9JO&31*U“P~ןWM֌?z{FmB\飲\-ُVSwB 8wXW3.`cWXǷ}ALLksqttL'͌Jjns@:u921[ߗ{P8sv?xtIŋNptş4 ]̯4NcVY ys ` ,1}t ]Fp +T_i]`vqu 'pܜ`,8_tΆnȽ.:!z/5TitEƭJ;7 x> dgKH0v=*Xnj*;u_Ab u<]}vEwTE[&1wv^_e}V*6me`6)J2/o0%/1 :xъIQُfw|xI+E,a&k(J<8Nj4|b5⁉?' bNƙ w2l~ŧe~~v?x;M=)e9{[P $oYuҶ=|czgYRoѳV=~O)m¦[Dttڄ {=A?YGǿ$^{[TA~\ocx>Ū3Ȅ/>8VxVg<ޗ޷xm4zrRkLh&{e`>WO)xAǖFGݕ&y.<+~!;8EC\! l^xY"t&su+G|OվO6 n>cumS{Z/5Я \{><0m}yKw_$Y6){(O} (Y^afht&܂֖<CSx)l Ş6U6Cܑ\`OM  tK?e{}Kåm;6V&~5ݮO}P968]Fi}: btZ ۾:ƃt;_62lrgM~d=nAWG~oEB̺2}Hت V~qeCH75zm&IY]8iQu@9dCɐbC 7H~}nJI꒸%\7.w:LVmE4W'+7SV=N7]HTf#O2e1E\WZVqB _dW|)i(~xtB$Ar=b޲]J   +3'vҕۀPh"j*ew fzHfrKNi|lDN< Km{J<9]eFַrU=*}WݏC+gc-PIO pnP'[\fum#-)_c^f!Dy/; ouײ!ٳiuؙ= P$q%d5*Fr&pX:[ ln~O&6٥~w:*Fd_1Z^23{0hK_ ~?$I__^tnУ\A{ѲWF>Kd9y;t-|7-I y;]4q ]ćZ0^?_ړ X2On`O:jh`;Ϗ؂4 Ku[VОo!Nwm'ә7XYL珍i*zfnS0Xۑ/MǗ>{eS贺 ªD ϓK>Ӱgɟd%lxلDv_N* lIv ȇSf|cODֆ%i+DР&}{2! n 6~IE=T.6hmYU|*{b`t>7Y ]tǧ|u9}`۫|3 Z&{JYnȫ t;_)^`7[Sye _8 Xd7^MvuO- o{  㓡O4ַi&~8Lu}S]YGŝ]>tvVEG`~OF*0Z]#PPw|~Rw, xT-h0]gcP`+ՀG^C1Rrty? ȣU#r͟= ^r^(); t6BKKdѸB=?F |"%ƾɗ&Wc6Gn֏Vv^w &tMw)z_{Vh$uΔa'qP˗3-Yg%@.kGkoe`roΡ;o^*3( |rs})0lYn :f^ʝk.:z(C~]pgL,z.>.on:.䔿dDcl5y0`~ 6n?N6P嶡ʙl4DΜ<#C&?nOwYA*e}.K?xo'i7uhx!6f~5y:GE"c'ǂ+_ogzhx=xɫYy SlW}R~~D1)Z7g>65L;R680;}.%Yc WfG Ӟ)+9&1 5m:_'~|.5>`\;*`&Zlx'-i)=IO["O=]:^p4ou y[~NFdg]#G! eOe)ud%cgBJ.>ӫvVXpD\]t<~U?]/ ?iEou#zڒΞ}w.̅D{IOgUOhDis~Aw'xu NbOH18QfzN!^L?9C#rtJ7=MF<l3B '۾rl?r[D6}~p)\~L{C8t^ 0)o^[E";TG7,t4NuzDOjx}DGfdMY ΛkPj€x5ѫG`2,ڬ|a7١O nlX'/}+7!PWcGtY=df֦e;tRV*{:o3>;R`>o-gp[@~A&ԥf 6m#iOnAij4_se_*zכ>IG_ Ypd ]\{ $&) W/63GX/xD#2|tnf>LGdHf̖O_ȥǛ@%Ew44a_~`2e+9=n oB:v| 3M /B\3\%ٸO{ KG{W]ҷc|`|3cH较f~<0zVc6<9/[_0.gE&b䕾O]E䎼N]n7q y]^)|t=)0lp/<4Ϊ)=^ĩncl@VHd +q|=x>@gBG=MJJABh)zvO,_|'D-ߗ |Yb_^ᩳ7 ůɓJO5<+bGMuv|(?v@wL[xxx6I]?ҵI/M?oѯ\2׽MdcS/&PQU\Cdݏ,}Y $Jsʬ<132GIl=8N7<>xuݓR^e`p R) =`ؒs\MfK gX18 hri`K-l><l7|.q8GdՇ%8*@:Roes>C~h1٣Uzw:[.%腃j~䝯S<>mZ PA;CP}XjBP0AN.7P/N^>4wLϝL=ݜwtUH+xX^uoBǟnzßtLo|N|hfc0usc|iOCW>WovvɅ`9u>̧jI6bVP&,;1t-qnV)Ond%__[;yta`6K7@mvG# 現l:$&}~?{ꉹ򵗂A.ڌ`N@ƹ K3|, M(b _{grg?z.~$K VeBɉ ;S >_+6bcOwmCzO~+Aڈ<)*<q?6N"et`A]nŕr]nHAxOXd8UpK߲Ud@xyci+;>)?N: Њc@xb/\axl oDo_ir`tO& J9'_[#~i# ,M'V øഽHC?0~7gLT[}/8m_%qJ'M/{u;z/?[- }:8(rv9`4 #bpYJK \;:)=XUI.|07o)r)p1:I+à3OI8\w⦦g/3 42U0^,3z( %tvT̡Qz@7]Y^p/ ,W5*V$;֑ @?'_o;uLSN}̥B8gpM$+0^|NzzcꊟNOjBU4<&=|7 ; ~Orv\DWxI} h+gM yio'ㇷZDž_SV/y-/j:FF+œs>|{6>_dJL?n+|Ϗ:A2\vswǔx("GlI. |OM?;*Y6oio46+n׮>`i~2᚟`>t">Yr::_wJIOk? vNڗJwq` nu8=ib;8& Ht>QEe]wO27Y3;&| `O;FW@RVW`/}hbuKKo׾=k2m,X:::n4?WwiG(@)Y 5XK$/Q |2{Zڋy\1:^6V#UF 3]_1"6U'`0<$o<+F~xM@:/nنw_ `֟1z}SgAכPln9Q邚^k PG[_gtt|m?_'?7\A_(CǾ&qɺqzANɳ+}-pR`?6!)W,w0IOZyU,Nx AU/m-gcjb4 Wߪ>d:}xMD`YXIpRvX!`d[|ΏFn9[>g1zF*ѳ"p丌ȇM<_ޖdH77Q]q 'WF]u6t4|lS'ê@܄l ޾ V3?xSʃ;0-.1r[XO 3&/|=vݷܕ ֫gvCF$޵_&VmC?WLvo78kvY',| wc|զg4Mw;e_9?}cwq "\6ΰ@}!y!^m"8I+o~Go9R /O_NLh!BQlE(ŀ*;9NyLb) `d(5,}O#2!M8CO{~ 3 0=(ⵁ= 2w+["#GHŷf=|`eWvΌރi@~Fsr<$AD>ɭe1FSrxY1en=b?'?+|oEG5,KWc*w;񥣳R|˃c;>/xu@Oe{u2xzOM@ߡqF8g[KϗR: ©옖 `ѡ)U}\^aNg]stc c+&5 adw@9$90: ¯7HKi :$\4גc+KGO7JWopI7њ!K6UA{Ek|=!kቨ%З^PSE#) N(^wƮϻ׮Mn{f6]s8&~؍ )b  ׶)Y'v1oʪ2t}րQuNXH{kuxXף/ktMVy8xx{7ܦz% &> ,leT 6=;6BJo]:ħ/zҹݹ%|#@xċ`:ʉ8;b(=;/r[vdu7IK`76 Yiy!U#gj׳U`BdL`uOCL IQXvdl9zꚧm5Q 6>SfQ>٢5;]tӣ/R!/1umQ`9Iw&BLk_~4`e؎6:KOW+_|ѷvJ.2A.MڹwmTT``%=Noh }>» jQZ`E{ #8)) pyP[d>G}ގY9A08ޛz=p?EWOz/_$ T05]~Exǥ/WG_abVNMAMt}pl ʍ2RGWbst}OW6뫼W|.$hǪ! 5r 8uл+O dHgE`[$\d [nK6{E:XggɅv^"A^k WVxwQ_ȅ]WoOƯDA{jd84G^t\ϫV[x Sw ^J_&U=JǕGxyHK!ɝ=ʔ>=):Z%)0_ nz8}?2!{%7p6\8WxJٷNn8 R (#:}8ʏPn}S˜wg&d`;clRn/SG1qv&.<WdHA+>xW'ra8/7 \+fb*\U3t4uL*X`Ow6PY/lL4 `:}vm93|/=ݲtźo98{,$> u7o>:'O%}T^C,@76 #z/:G;@[E0*O1n[tRI+l{ڞnd 5<3Lk$˟B]po&/|GGtpDg`yKGރx/;rSy ~07ϕOZ7 L"8tu'/\ g5VtvRΧ|^JVD > Ñ]Bs߯ݮ PG&.nl'}3=&tYz[NxLFt c ?_A.f;:"+o:7?_3!GFˡ- ߍ՟瞖:J SX{\D~w94 hbD1d~-Oo[%oDF&%S,c6 .퓇 MY6Hwh ӏ{. *X_(mu'ڣ{Y:]iӞw r\~H@# |.YεU yJw4iz7?YLQiݍi Tne~7&Zɟ%ǽG ƣ/;?BMSVp-c CtmZYzx O;Ui4=7 lCC |ڞ& >K8^zu{?yVOp =)Z7hO۵x#(']F”f恵8T(k\2dnO+wI~WC rkX]FЇc2EC"hv(qI|l5pFOSB!࿤-/]T_lú-.#+\uÌ n9dݫ&08I(!` 1md^Px^Gx |?~_,amG4L,jh_8JÃtpG `hmT} ([ׯ_7Qz>Ր&}^38e߂9w,wk;KNj{ t|&UPW0slO敏O8F\L$϶UTϜɊM@8: 2"gx<Γ|4wJ؄1a#&yt,كF@_P#y 0VleEC]2L[B|Ň-J]`!MLG>| + lSJ.=Qhh|||)>lQBooP.?lMi_[W#&NJ4s=I_ioHQ&%LNXlxAq]O(_36ùjЙ= ^76& n2=LB<Pl4?+γ X|9Q,Koa:BH|&xhI -+|xs luͰ`'= b̏V.!. XuzGghु8;w<2y!e;dfli藍wD.C{4O?9:O}/5mE?;)R Uy똎QY>tx/O^wtՑW6}m.ẏگx(f' ]Ӑ74RR ˮT׎,[ݰ 2.zQx;^䐦ؠ mdάc>Rܻ5o(O$^}7G?K7w n4wEuk/x5w|O-~xku֓)uaﴣ_ &Kҥ%d_נMzg.vCb<ӇJ}v.yW3;m9ʭc|׺,Lji6i۠C;P&G&PTݸCg( ҅rku;ZT &z&zᮇ5+ۖ"j'G;z::X)-:`:O@A3!ϕo˓S&$@靯2kwd9MRtD4̈:&EMmTJ' vu O4@E}$neҠo:"H|?'{Z)/{m椝o>{ed;\kCߖYDN vjaZLXڕߛ]Ё'_8.v{Q4t?YeR=T@}  ~p- JHk~ )Yʩ>т6Άw][KhK_D{OA[ֆY_0>CLN#` uW?#W޳8HU 9<{J t<lK{}f(rm/Nچ=]ad#m̖OPC6V6{,xWirHp<MkOY{v_{)o~eO'Sg"$?Ro(ćUp~5||ϫ %%9$ΏjVo-&tP~v>VͶ|M+L~onCFk9]F{\nٚ 2ʧco3)qQcEV}vUe ;jPfN~NwB? fqdk\y.6>l0sg_o :9-%lǩW,?g gͰ04.^ގS91HO^JvC1ΟxQM'lw%=3ܝ9O< |t#{q.KysOhNƀ`:\e߹u0١C cϒ+I;pg@}4WQ&kya.]Hx^{9BF+-[kq񲆰49: XOK_xkt\'W @e oetfȕy~̗=TܥэśtЧh@8Wסؠx4B.  tTߗ>- XVѽz1}V*7`}ԀM5>NN M6Y1cXl<ф,0 ;\_hkXT xB19f+cgu)ɸKlt!?i{ȧ"eٌt~]3Zs[ڔ/ +v2:lc~ۈ?Vڡ$II-^RׯFjv \ ~Oz696HvOE{ k氁^GQq&2K˖q?[9+mk3 xkяk$ϕqڛ53>uM,|S;|tUOP L~΀e]2ÓhÔSyT}GMEG_ނ %fL[Y0ӮU~3_&/7.Kn 4ij#{28 ֿL&ު}%ar V@$|·7}MRPj +]=#zh CW@炌xM{3 -]`2}q<']D|\ &PF { ~!O^ +% Ó]wO УG&"{ڧVȣifp=є%ޅ߾nR CO:[P^tlr ֶK}#kyh  >[So) IDAT%b7tE.7?vtttef>B;'fO<<(Ume݂X} mk/y>z~&fܤRhF\]ěɝMgk[UpK::>'Ytt^}8/ktp(t<.@;BO|}|O[Ut+ fG+8\l `+Iud^>WVyb5DOi>3_1d{%D/ξ-OnGd+>Dl{ګٚ|iژ];Oz!K&b|چھW}*!BJo܆ A99( 2fSo-*^Ⱦ1 ǯ>69LF~-^?rՙĪ_`#rlOj*7#Ktnvס^ Ʀ<(Qi^p] 2,Uh*=Y+3?"8h\zo-,T8\*jlVg`~e[:/_3]ږqtA3Oǂ(E'LѿmA_3R!|1Wv V8pdeB]\6-鼲pB:Okiuli0yJZXrՀmҀC{|Dgc~Kߗnp1?Wl NC*!xS|bW֙ym&ݓp8ph]>a!ʲ߸) 3GCǯiM`r6`U?rEn87@C})M}&y*u@4Y&uvf6F4vt vr<K n ­zdm'AvNGVyݝ$M>14x>} OɷӇNt%W 4O +KpiD`8V~>gxrOmiO :^ZhkߚO٨Փ})%~iY]WmG5ܗ=?t? TT>x+O#ٹ<:?7D/oRdY{S\:|p/cNI}_a߮pV{3ڪA~×<9_ "ٞ%2Y'x??>4!:)O\=:Bn@V?y\z ?ڒ}2k[ەi7aϞNcs.k?J>K㛎:8AЏׅ{9hyK4h6R|aR+& C%Lxg^9i0]k&^DM׸i6@X?fƱp䟈ʜ _0TZ>*!;~{{1%% N.(yOYaE}is_:q~jA bs| mM,dM 4#2,7cJ_{g~+@[;Q ]k-_-iJ=pğn_k{~y_Iõ=\aNG.txD c4L8!VѳzKN+8]Aԯ5yNWu>pW'4X4[.䍧r3ʠ idzOZbUȍu5v'ڎO۾"O@}4ZGtom?7uy|퉑pR <^=OqDZjm8 z+ xU\[}*g>N3eo[l$w4i~6dp,W$Rp7̮18w&t%8ܻS j@]_E19?ޖVA]S(tڟcOSy䛸O"SdF~·d$G8EƊH_tɘaxDώqPyY4[>~=NU ntÃP/}I8~ǽK` 6iߓ | W_@OL>FzEis h)6e<%dUɳ ~deE> "G:Hד M:};m|I!yoN&:pc K lHzG/p? :"Ww#lv}tzAm{G,=u\lFսY2'TOIOĩztaY8/n['ߟ2CcO\nxτhr vL X3a~7?tHw9=e6x^ }j ߵK`SuddDޱyy'Wmziϒr8^"=,}&a'/<:[+?[}ʐՏ0o]OMROY9h } nB;I\LJ&_"Lp;% )^toi/>Rz𜉁O*hP;hl<o^4YWQʈ8I6YsX;}:VN쵶w~V.ޟ;yZWd@銮( ŕ~/^&KBH:u1٨ =҂=ky Kwx9{t F5Oλ_yғćeO!e9~J9z.?` O uܝKq+FV1\d<=9%#AϾ'd|d%9 Wˋ%H޺l6݆Ѐ#ޮC)LV]P됝 VtJ`]0'/ g' fV }OE|'>;Oh驧MؒfӼ*d-V}l2 0#'>5 u310KV~iKl}ӛ"c=W aAIivKկdztnG_K&7^H0ڙ{JOiwMf[Pkb^_>l`dhg\W`O:~~xCg|v#T,OUO?mjAb_~ A#П˯Wʘ_į%ՙoc`OD;G Q疑ׯ_j' p9ܜtO)|WQEc] +go|');cXy.o]L8G[۾{{pd4ӵx ybbQbmp'{NuLV_? cyAP D$P@=l`@7Q~A|!dOHWēCkx+~k)5~~x{[]۝dC:z}A틂Uk%}#Pks$U;VFޖdi GtoXXX]|S҂`=e ѫa&5\t'h/虎lکdʑ{vA'ǓږxExE)uFO$Fv:d?k`v28 9Gl|Qy;O:x_ ɸ]P﵉l~Wy򒆗{~,㰶'MB"G(hEK%[h MluO #cʒS0ޘ OHOVV&4G1tI zQtf[¯^ =>OPg!@~gGC?XI eVKcL+/01dio}Y LxX콱Ia2@|Y_ vk=uNWױ'eo;0Xpp: ‚^O @;s͚Vvx,5#_6P+ka/7x s6<8=X`bJbǣ1c nHy 2;<L=crU )~<'<.%f ls2 x Ovs 6ӦBПeawixW1 z5CvTrv#4/J@L7}fn~7>$QkhgVoy*4\dτ<=Le:l|xr\5ִc~i̔p7=O:*/L%]8VO@?xkQQ^z@B@_Oj|`%N |ai]^O`Ι^kh 2_!I ָn2!^=_S: Oֲ<W^d JF&s:I`/|g>^)O6`KAVt~8+TczDme7[;@Z}uT.۽~]Ό];^|#% d4p$lۻkӦQ|A^~R]pWd#9o6PGK!ߧ;0==v_gvbuAP]Z$_<*W`ze1nw~_Ӈxٮom7Ya|"bˆ\{KJ ~n, /nd{ʧ,[%>ߌ6u9VlskURv`VOH=Q7fm,з>4#]  0/QS 0nLuaV \i,,|6g]?eLXN,a6[V] Oʙw;Jן,Yaܕ1qIي~|]^Y a >[]_tZ9xnϤzBĪr|F ڻߵj5&U ~7{nT)& |vTB^g"@`+y|8IūOtDc/@A';)ޏ k+Mѓ]U$|7d^0OF0cA|_Z{xا[gׁfc(ʌ`,R=Hkcus@A, X`P{'sI0 Qn!.+i @h,v(w筲ܐ(lZKٖKN)|](> ) =ȷ1t<\w%97{ݠ 7x+}$tB:Ieѡg@KMǟW-+p;'̝k὞hNN.ȗUҔOltL#o Sq*6KqzѲ/퓁c$M.脔cGyΏ>.&PM'ot.|]y:ٶ|5tlr)}NL3whxGGx~_ 2'5AƗ_;AHJ֣Y=z+av6U7=+<\:+8xRKգlV#y]aE Fgy.J.+S`x/ȉoȏ쵛LvM]Q9g+'Lڱ5g F;q~:Po (a&:>kiu,0Nn<7v?x8 w4 Sam66)-nV*4'%ӗg c!L^xZaaD{]م^NPQ |+>vAx_hM[pO{6ԗ, t~lS_8Ili2eG@|~>Y~}+-oB윜k[Z'ׄÓ-҅, IDAT_=Lާ~G룣5>T 76E; :%m#)p<:*>G#ԟ iʦNq&\\?~|EZ"nxtGV?qJĝ @@S=3?ozY/g.`.SYbJ˽ _ T=!{OZ?؛ⲹ@ ε=ڃ:U":͕5A!`@r& :~ܾvgtބtGԘ ՗F~r8]u?6 ZM~|~Fw[s"|2!)<|8{:4wt8Gn_ 숝ѠDMdu)z&x4q6?~_H$HG{S9嫜{wħ`ۄءN" zK7Cٟ{ȜXx ]|TOйpHm;{J_U*|=ۄl>ڸIZ0Lך+Rvt(]Zfgl'M|hedW(>v3`u /k8a:ExqGgox _WL7K_:vm:O<`~>|&X=#{oiɂZ2ޖ].صx_OO.㨮U%rG2/8cpJ:Dΰw^'_C dplUסIs WSyʃO㾳>[&s1|$-} lܕ;;u:MPcLO v!>*Zbij5l3|;Oƫ=IGh/2@SCûlOOV}jԁxØ( ԰`u>|9Ku@| |Kl|'Ot&7kM1Kk7&&yonE>Ed7}ۙbGu Go ApmALzg|WTČ-GIv7qdmRu`//i;OGޅ]{ɓWAl Ma2uy"gHO[ܞφ.MTG\I Z7vgVƆZAh0˒x:cO4'0Th/O`-|c,| $-O`9Ow}o2h ?$DvM40`LGkA,/>S ڳlg&˛x }xIT#$v}V(]}`+7kcV?7119q[ k>S;b`шOI/"_ LcP6:_3(H3y^Y&`']kt~cCyG1,{գ7{#P0 {J8z}q?W[AxS7՟#Wu*ʍ 2}Pe3rCgfp8$yCwOq{Ưj qG٠&6n7GԹ8̸5y1!uכt !եh՟'F=m Yt|O <>{+/x_/\>_>mH]b>8&0"=cu{~BtPшI,Ct8RK8QL:`g̈́5>fm)ϻ2X,Zmt?oBq`*sx<8Jd@Tti = ]Op\\c:|5K?A,9:e]C١sO)LJaml_yhw} lby*ꒃ O]ÿϡɋlO/gGO{Z|xcf.d0&G%i9C/)'$ؽ]&0S@,kup ]|~$ɂZF*_7? t$$pLY / J69[fu4S{ՋJyt@`= lj}Ou9dls'KdYiX߸[xDde2(&$L!%uGuM9"JN@̭sgznV:x4 r \YD~OKB||Kg: YmOe-z6 O_!7 j9#şWȾ1`[YXlWz3 gXY;{GCY@y2wCf 7kzwmYU򆑶_Y00=(ٗoɠ#rJjZw.$k&~:xߩɣo vx/|*UaS60) aaUUv|31B<"U\庲9)d )n+K[J2rM-k#S6E@ߣ!Q5``B/L69 nB"a3vgmfK}w]*aw!pu*6~ VJ%{0EC{l ~!xv&ۇ/qk6EhGGKΖGWB $K=@{'./d`gy|;e=r0I'we;Y>_H'l,ehX&VI$foB;DM/>)z W%u1䈉 {/G^ ϾsrGO7/ev=u[[]"n ܟ=3/xgcG/Xg:~Ls $ڳ 1|Dri3JɏNxf]]:i m{Ͽ7(y"9y!*RfC`^uj$LL3p4/Mjh\xhV:<ѦtrH'gt~3¯>22:5d|55/z˝su0{5D~o˃siAwƽs1{xe@7w0]ot!CGE8uh:aB^8ҟM ut~>a-e٤ qs}z[?+>%TuT axlH\tA6dI@^6>[6a%#lfOt,L$\VCWZg?2,Lt*# ـFјRDOM]= {Ĉba/?(3=ђM N~B4؇xˇ>S|2G5FV=Ƨa7&=`P0L9o>yjHKTu:vlp!C/;ԕn<:3FހZ4g]HɴM:8ϗuʿ ~鬢)$_RE%p]y, _k%GǍU!0^:A哓i40ccȿ#i?qloMriGCX+OАMmÇ?m`3 ƀ~]0 *K'hET:)V6e),mPt~Y8?b&[`"6xfh.bab/o0LD*OzɞXGYt2m!~T4s\1 A4~&'$Sl;L{j*&An zeõP+/$0 tlDug].N尴m`u) zUu&p\4NR -Ml[y<&vG7omNw_p&?mĎaʮw[ft20//BIbMO i|K1V$ɬ,^Al쭯?z:~҄ᔮ:o~bAWfǬVZ}pSqx}Ԏ}X0}Õ迫&o7ųhvh lӟ n"(ĞN6ª]ddQ:%}PAkW\/{ }_3FCyYG3.\;0r/Gp Z}d1oiFVYnp֗DbB? bFln"L x5cZ{n $h]NPQx|Y9:ft8Qn2u}WigxFi-- `fcvV7>I*_0B[{{;hb~t{ōgkLARLO^vбO|W&gd | }8ίBC!鞸O֓N~yȖ3N-5MmEm5ѓ_HҙTK_,\lQ|I2&@YLO;.uizیCWϛTmG>U!vJdKwؠFz|<]W^u6t&dKD%/.? vhOobUrLv2.My|KL6ByYy GXLk=nP;.-^?cB 5Jgpy6p}n/} ŕ}]E׎8+)5&/6t[ h}܋~f|Ga9 'QB%\@3meN|/vzw:ۦaoUol?yD/L=[MlDx7q6p]#sJy07#kÄth_f  ~l] &|-`w/}^ZgX:,_t= @Q|#4",^VYiAF~2qu*+ɮê }BP3tae^ !OE[<ưdSEdYE^ uN>#/b\}q8gt&+ hioq70vlckDx%?Nt+Vg0GZ1ve5\ Г,oqLomgHg/GpZ)Oj3iG&x1&/ _%Έn1:HnEY6a@s 5寛pal7t3dPFLr(|$*{7  %ĒS7HK9K u<7(t/e.c+#ş~V_ߏm>ގj+m<̀ 1 H9_S*K^m| "3k<(>zۑL]cRǽqn=0%ov_jw85#MF>H㦉.x=r;*SܠTW*hh"MU ;FgHڙLؠpv31;Ron!D`7i O mqy)\7ڻv#؏i2ޮ kKݶUsT1~#rF/Pl2CcfC ~gAt_><;Ƨˏ|.7?!%L˚;6Y-z2N*SyMp ,֯~kB*~-Į-ZLj;/ ge>BK O`wHK_5c/zSPGbr!KK?Xz W?zKut KGxZ- -F,K"ËoϾN9v.O"}-ݿMl ' ;]K&ҏS-xݜ^ۃ 4{Oݮgxl5hO~uiFu+䥃Iy|}nm>][y|^>$ 2m%|{fUrNt+Oɺ< IDAT=4 ;gEgkpdw}V:Y,|F:Qʟ{*[#' @,Gz]YSGx6z+D ]pT^55ݛt<ܳ{2Gmv/D3>o |:#+1H%.\ʀ&\OMP >~{L.Vڣ)} \/]1|0IpS\}n]2M^+WnїfgnGu`? 2I7⭃ w&^f]oҰmWI!;5XAwrXi40wlEiFYd^za3͓37X?akWw|K nbOl`?<6GvµᄅlIM}/ 2;ߋ፞OZ/ Xr"guK>m3Y͕0@[y޵MdJBJ7[n$KsNdg7NCE:KA[ D"G]] q"O^+#cD|fՁJ{$ؤgse`op_?*kcb`~ ~=`;eJ7Ƙ |nbD}\i8o~//Ds@I˶nŚ01YfY:[F=PL>~-ؕGО4=[9*+mgyu@U?X HN%}wpr%&dReOehHtl<{y&k+Kݣ!>?kct +hzrwX$W^{Z{܁~aԠ|b鴾 {)^?&(M -%)GrC1ʁ7_fqs iM/,/{vXܬqe0:xGg66ݯB%Q{+09{3˿JQGrw ē8?jo5.?7Z/8ug][OV}U(&:CdϿ`t+x&VV6]']A~{~+/vTf>-ґ}~[Goe6fKuI}qGK]_[_9-oĈ&,F0OGtlM 3ruˏ8_R5@?%I+czK6hl}x%IdJΆMb S9?He ʏZm糫(iaunVwq`×p:ۥ]]0WÎ~,H&.I:~sXMgP&\zJ]/0dGŽ^d^:k秳D.L`8_02\ C$xvú˿WخN mpP]=_Hu)ѵ5~ .%0'Aum/tF{)]QD鞏M _rVL#N Li3󁀹A-}>A"{pwKoi?nhT.&>v#}k'";6U X~k"NHu_>7{E]%cH~곇`XV ҏ] 8g;Mt\1;OGl;UMW~E|."VUDϩKGǭgRSs_ S\ea/ɬ^Y :~=6ef?~uc4矑̧?%vU|q"^xd3lbd&@mc{_DXN70p43ehweN 8njv( k.7NJ`|UZE;=M `~TD7YɦޤCp{_슇]4jM ʒ ^,p%&^i%Bѓn:[xD+iW]+6[SI+[tvFDϿGO w}'뇧 YeyכؙNT+9ԩ.Iڂ` p&2V_y?:Dc'CS.YͶi"G>?|rl[zUEwN+Q$[ꇆDgFGսw1P 0uDY n|Ye9u)c 4J;8H~ƏP' >[ Cg=l:9FDŽӾu,{9)~`鱉ҰKs94vN._~]Z07y th yFOvz|l/+`t:E;yt G5=uxt@:U˗lӯ-w3h-:!l,G: -~5^hRe>Oc?NU|6:薐ݓep4jְɳ#da١|nveW|-<}M}" '#pO-2to𐌓4_毷 Ӌk],3~#ʀ!fr%6YNW?i %~T|x8hetu&w2.͗WV_xm!^Iy[aMwnx ys:sԫ7+k7\.{>Z̤wa{%?Wfۄ`y4"gGH:XC=s}]c%a)vxWW"F~Wﲗ$:C>[DZYﭣm?U'E?H+^i#?7EχWd*\O~V@\=7K2^>!yԣV'"0mRoo'}֛:S=~{+7(3 I05@=vL(өҪv~jg<\mxV6Sln Ƈ+܋)CW+S,K?t` L:(|9<ᰁSAt&Gԣ.KG`% ;0Bx4ЎI \}N{`D'Taoą-,eə"d%np ֶ7q (lx JC&׎'n}|#fxvgמ gWL*̞&}ّ<&.&g|)^F) 5'4+;- SBVl.1^K77u8%xX8Ng9ʔ.1JS&mݟ1Ҟ` ~wúYK|OdpQO4t;ABhX/u+)NӖjV}ng3!sD@|?z^pMUt7{GmBDžBA o5j>&;>*hr(:t\ea>2m:o戾ܶ^K*lhmRpك&\딿ٞ~at9:3sl95ww? |1}l{7K{ƳkiXvypM O'QyFݖ:K,Gf0Anv0Nӭdɷ:|::a%dl/= @?n|t&#/lבlΧ?걁uo`~w=ɿou|l>ʇtw7u~_6<{]]]oKG73gSicmT/g6:_ # _gbf-|a}}}=mFzB/6:f:cVD Q7؃`|} r-M)a12+;4 9F=aʾGX[xLM\W s6_ iKs'oMIN~ 3z |[m$Q>0HKJIQmGhgWgc?\etЪ)B[K8]НHol&ˋK6Trs$4WױvQBa^ov4Yh7gO'Sc0*M3j;, Cxղt}Ⱦ4l%>.ޝ]A(YC'/gWҽoßmJ`MS̛/4>xIe>Bv;|Ͻm+σ:;U]a:|ʅmb›ZQ;68s*[F36 ["oYFYAO0M@i06Saub r9<'kp>{oNOrݕv_bh[dٸ{Ο Y9pZen\%ш lGϫ0At(?}Vp7:+ ~!7,DY,0`~<8GJN5&.a3H7fewv/Nn*w6ՈdulDjH[!2, tzjܤgP~C{_@'wVVm'hW<}}޵2+~ >W#?mM:t&ON'6`3]ym:a-/.z{'Ii7MM׶ɧT -Ӷc!j/~:o8:V=lOG >u{_4: ?OפETAYug&9sQaPMh2>k9yF\Oy籔MFPc/-8꡵a1f?vcw/Ek]|86mR@Q|M$TZ)`2ݣɡcP/+SiI[iSҼMӣq)C9m"vL)G>lV]W; iH\[ 6E !}8/?0aɊFC0Glt:<SA&RvL9JMZpқ:c`HAuJO7~'M29ŏ[g9^`F f9"F.cqf2 K3у0B cs[XOV|WTwpZ~bAe{.: o?5Z!g#ENNFS!-n ':^~[ǯNwxklH|cɳAd(٨ o}`rm9A9.~=}o=2:U'3::Q#Ne8wU-thʷOW 4Oτ詈?,wx|~e4T IDAT[/cȏ)WGp3(j|D/}>& њQ@m#0h(K]sx)qد/FV̒OW/]YuÛ^Vc1T _VÏ̥x/c;nbNF!ױdYsaR]'%y~#7 R+!; ]DcD ZB!\I7X24}C⮑kH de3أ=rVۓu~텊HwzR?=,)쑮2lPn^a񪾙xG? tǏ_g󱫧J$^uw9=2dKc}\Ԗsսaeg}ebJl>X߷me2܊Z(TNg~r=aWzuFXhYͶ1+ǽ˶nRH Qǩ{K /: &г0 ?6&DW~MN{ikaK}aTA_|'S-:7A 3HOb6K۟|/NlുKtuw]\ce&Ab/.^f{26I@[f|v 7f”ؠsMTVGMH}/k7пm4hWϩxDA 6L+3{YY̮hu@s8 t/\\]9*؀r;pɟxGBO$+|Z#m?trn!xoxGA b5p}4|~Bi?Lgɰ0?ڣ&XIg7j~;;X>kI]bOt_&4 &!,(t60 ?9fMbr #~d ' +>2LؿMd++rg} |NУ*z`1y+ jB]ArkHZzy{~G_C&MlD֏F 'M'p61ir^7P(r2D@~ L^2 楪jS5i?E^ޕdϖO W.Ld+ l:&s!V?n6 ~'obiy&ғ7>ò4はyx]%ԙ1 *V F5-r[#2ȞKȯ|"և٢V16:;хß fxP'l@`O=oO\Emu?=-ٸxG}Yeq/<$#r|k5{>W'}:렞-=H6jcKh *oq/4ɺ.S ŖhmY? I/4tM3rBu#Yq DrCJhʆ@5yر]A]GP(렄:p6pl\ iAKz;=]S7 T>wecu/tke.:wA=fQ7hy_5x)Uxi"& }ڒh ߩ{bϯdG:ް糇u60VՉ| XpRmy~^uؤM$2lʻ[%cBY)ؗnt2,Owb_`Q s;ōu4:\IhYyL>"0wڝ\Ft7l6xж{d]tgq؜}}O@%z 2OipC(VV}էY\8o(X)H=Yؖt:?.fj3۲~EV= Ua8@:A 5\c xx!+z1e ,_ukpi^G@H4MxDd{&%oL[a.O>eC: W:: ӧA,vyBC켣x,Fb L|d|t[{\^ W/u&~Axv&:mϟC69T^0 B2,?A07/y]43hgpgXm_; ?kV}3dhЖ_^Ɋ(au*3WQ~qDr&MSJfoug]!N+{L`3ı7\fos̷ݒ%УQY.>cgר3ei8pWӰht}5BLHc|Z./6b^<~Dc#⏷T:+hN֏Lwif1!9X~+,dA^y|V^ &kfV[y$cю06Suܤ8tJЎ>4F />TN‡\ԛèu&7:[48q̏*d].mP\Қ(*6OMfq4Ulh _.bgFtVd&?%SP.^//%նN ^wablh|lS6zhQ pؐ=Hi~"|I>j:'9?&p:vj;a7aV鲗b*p^٘^'9 J[rndV-LY>OvouG,Fr~“>\#̏qZDGʭ+o ~]2e^^ع:@%ȍ/~r cB5yt?~1Z˫cK&<Ëuʿ01mc~|D'N>=Oǫg[ylE =Lp7N< 9eɴۺ3K9X=?>VO]JkRջ=3î/xf }ᇭxu'X3t h#LݤTiV7px=GKScatvA*~&vJOe]W/^ti{~O*+p}>Cp W7dPc_=\]n*x62n't߸'fH=o[Q;(UdZuaN&7ۖ.&F &hԙ'ȜWv^-+{yA\_} n:#Ltܨ:\M:O>lۑr_;a]xWvkKʂk>W__Y{^M(n+WM:@ i d%ށvVF]&jG/>{E{{a% cDtUdeX=-A Ц' oW3h_7Ix_M),_Nr1#oi99pASMK3ϺxOj+7N@G wls&bN6ٹO=tƇ_J{d*7'vwlZUg"UO 8BKd+>AO:>L6x-]>~M'8W'mDA*?/LERm6[jCWw@Nا6E? ~Gk=GJꤕd{_j>!e1g'L4,M~ /!-bh@:_Qh1 >F?}3t瑷nKׯr͛08L 0{‹mb8z|l_t7RDpB*9'Ȓ_%/XV}0 9<&+l< ye&( 0ѱ]]:vs&&x \wm@ߌGB&_p&6EaV;}ê5)b-cGl ੌ 79"||{LlJL6$ sҎ?LVwTOj!; _re{mDg,owSGv~^>I(ߴ=߱SGG7/P K%O~~~gIMh/,=.n~I7!"۷}EȬn./;E<5dK|u4Ǯgv T2p>vF8Y:n4y?; + aAoI&яO&2^޿gd !ZԇU/aO](">wѿx}_ 59@ #K6{iF54/$KF >:`%Y]9C\ӑWw40ұ =w.T΍y^\9Dt3Nclʁ0\t,/ uhW*aÞ憎0M*z:~y<^]k !G ur9ˋ?oV9^INxNۀfK<='{tВ_9'|ov_<% 2#$3vRH`o(뺂q$ū]6GiDB8|.BXeuy Xi.|cyw׈P R9?]Χ&ji]4<OXVfTj/l({UgCے56f؉{*F Hr0OnlgOd #ypRo&p39<׸[|MzF}&Gr¢bUߠ@9/*djlVdD/8E{+a|97!Rn^>3?T6JW`pS@ș.w8%ußߪ7K/??Y'n/MJt;}& Z2jg0W|˳AW7z xd4`m`<<Օ!)=><}#骓ǶϯL%&cf?oD!:i*d3 *O Ҋg a$MgPG4ou.?Ѷz>؆:SW7L;dnGVAů| s~҇zXݓbʼn귺ş! L;wt ׭fngz]yn>Ż3hKR` ɡC.kT-:B|quŻWxlĘ0"ٴ@F[MP%꧞cob<7>/@`y|zAA48b$9W&&^XZJC{] )[nCd8zDєo0F׶9 2)6wO<fei{ lG |1a;C||S>3[w݄+H?t5CsypS: mOW|o>}/GW'+ܤ?[\]dy87++0ùX'(iG8|{HClra&wwFm]|[YH>E1<]\3o2( ʒmOȄ {eO;Yl6I齶d,6)0v`WqM-?iG۹t~_u NjyG˝:n mr2W^Wg'0<'7n76a*lCy.&Q¬jP2$ҿhq o-ssқw/SI{ IDAT詬?('x -`H:f_R~b^hɌ9hb<OiV+^HqR 2̉ ]5ߐ*MEXNV"lAK;Fɿ41 Ly=^.|G/koK:&4*(<-olN/j#:d|_*/1$O OEߗbvV[PbY~ X_P lـgS(7a^ 7K{O\ց!o+5U)7#x6b1|BTYZC>vQ>+zy\$@_@aa,^ȑWF+⎛`0 2*-#V5(  Ke:$R؊dlIt8u\7 uۘJ9c[ 3?bةkE8 $Whu#ʮr (m@ w>IlW'u.m߽ G~j53{ qȯ~:jyu^YZ56oL7pv] (-6_滞={?>z rv6:a@dgvk&o< ~V.|y>:6^mR^ƽ,^ɍc9uݧ g %m:uCK]1Y%<gKdjEV~6옺dB!8ǭ۩Q,xlY$]_εA3?>e/z?p>zۺVǶf8$w { : YmC#s6v o[ICp"o?f~x)Daچt'/S(gXV) {+~p`+N=N߅A솑?c-@>`__< (&@ՎHPϵǟ%xIcc;%Ga_iʆ,_N.^/V郧 #ص<^zd5Ord;~=2d_rIMEghLJ7V/c Γ1nxuSd^[2=+ۼ&S)@Jʗt|[LWߐҬRת }uD2A$eGENF5Ra:6@$`PxjiU1jEouT:>_˲AH0|f.3L\:$U\tZgZ㽎Q2+2* 5y …0]g~:Bp,ϰ{FhwSFt RddC4FS/9VYu]guFhmlPJϵsGFz5lTŠK|$n?ydI|a|+^On7^'CtnvHR^ f<|OAߊOo[s񔲋¢WVxp+nZonpsOߒO\R:wc 7Jo/#=<~zayO2MHҗ*]18۱JFWgӑ-sz:hcGrDp-"6 T8m`ľ:~cm~?VA?;|ټIm'fX0,^x|&/޷-dZ><5۰iOXc=A:JEja%ƃl +6za4{Cm{303tzN[z+5ߘ𬽜D{~zu,oygڤFg_Ms/6psrN&2CJIOS VNԍn^^"<MI7yCH٢;\` &stibk+[P^$4aXN*oXbr]{+N)|xE{+[F[bZ<_~h¥ '_2 D6_Y{ϭN#<>:Ǖmf r/^}g9=Oo ɴvźK ,W½n/kp8w^+7Ft$Ӗwh":aV2'7@e7 mc颵``=a.K@V4 > V7yЄꗌ;Ù<~2-OuW& k_=f-_$DrϿ5]&7f(&.cɀζ;<?͏)A pQaۿ>8>@aLi' θ!"_ic;;O6@&uh_d -nׁ9]0w&vEψ6_40Bph?7;/Өk)owymmd$p +L'_Qr | ivNty''݇v,k:yd~ʪ(fc_moE|65I1HT|0rmb_|9%p:\ yi&XE!Hs-u@+kDUz Y1;s3nʊ,ŀ{uRhL' xBm$9*QA eѹ)n:&1GmL|ysܓ1^N DwG_Y?hl<?|/N5Y Fſl&ˑCS␰U^.Fos{Y&`SV4` *aO/ҸUQ] |?rYi}ϋ0?*"B(^kquKiA®~S/1S/2 XڵIZǮ,W|;LL<_xDK.f0Ng'P;x?N,J# "Q^]'WzFhz {49YQ jhk\" _8L4a5 ӎҩKʥyn++pܴ_9;ToJbM?Iv*c6ntYl1`ŭ,>?=zl .x0ge&SrȰn&]@۽tHVfa665 aF3hv'E2y0ґ{yMk0]J/{=BXRG071_qZ>BVTrbl`%iE/~J|2zSIh=wYz9VgGN ɳVCam pd#onߢOګ0W} tNmϿϖVjE gux4x_pP؀tTٿ[.܀ixF No|@`^/7=u ^Whu<]MHGzē rdI"V?UC 8(|p19 AaÍ ȽM&A?z4˓ iSvI2=}u&sOboe"]}-%?gS^yvm#v }t_cmUJ/E)>Ӥ`ل"G gK{y豯&N8\fᳵa '&s~~&q풳3YT^ 7l > 4>etU662p~WvQX|8[qݟ|/7~&N\^o+aC1] oz܎[xzuSYr٧+xܥK3%S}WycctӠ.;dK[a=r\֧Q_8g_G2 P t\ !/,ʜ*_J 2,Q6rJWN"xKvϩYWDGNF?G"ֈsђ:Ʌ|~O,u<ǼH)z+FsrC:aY'n2]']91s :2 x@nU8WڭFw&Q  wx$z2džS GFGŹ@뜗5|0^%c:(3)?ymQē x\A? xm~!4tQV;*^Gnz-襚~ : #O"{^U|[E~vQG#/ k6q^G %5P6kP ^}6eK+?S, ,'ݽ8>ߠFkJan[٠baleEbr|īўI '`?_*`6$cJ{f$05(dfG NoVk:w{ru_yz2ҖǠ_|2.^Y+ItsVó=.SgѪHcNρaK/2 \ְmht'!aeqiyWYs}~3\趽Kޣy/六w<ҍسIeu #)6hϿ5qDŽ9yujDsmx<\~KW~\ǟʳUGaK+&G <~kP]a:ߵLo@٠dxئ& k~0dI.}Ll`4ԉK,@ـ$&_9E%|Ϡ8=7hG=:>eu? Ldыvz|zX76p=glN" Kha& G֯ɉ_0P?N8&-/_Mpu 6@0[~&4.ы k2ohä0  Y;=6 BD^ϹzЀFΈ~܄E՟e靟9L j&BUԨRAĚ uĒn($V߳M }:a&[zE>_yqacmC"m,]!/p~jѼ|]aK?1ў,኎1εП^9[H6d٤j|CNIlcږ'ε&NpoOOr0 F2Xuq8@[XKGO11@cZ%['̎G9O.G::S@(u.W:L Q&|k< xԴ63^xJ [},.(+bѥd$S-t:}}i[XZmx*b)OLdi;=_i,!Q(X_cUp~<5w2od" fE. r~Dz_BRR`΂ɽ9(X1O^ZKPƎ^xy!Qzw_ٶŮ ;7;ױ%g5ݤGc+74v4'MWKɯ۽A++޵_+ /@u*=n r_,349턃C<(m{*k?-}u:a@D99? [:Q{25mځqD/q. tuʣ]`bNh/;/,G)م>[ׯz7xxٗ`w;tKߺ~V&\z})I;q/G?GF<sgQO'&9?K*P stOyfɮ]{N:zU Xbko FXDW54exFhӿ $ʫ 9 W2 1Z_4P޷}xreW$rsR{LClţPHMn9bngGgoV;mEG&|mEN |;xT7rt_?cZW ̶qGBv\tMh>$Ӟ` j{RNn> lGg|{gĊ7]x_}Y=:|+,{|xأKԭ]8gJҩ M.`ꥣ՛+ o6c Ѥ/J 蘸&gw}­t<-o_X?J^)>߷kPzr:rBvHӛL ٺ܇՛xާho|QkŶKyv?ߵsc~.f NzhV5x4fӜee]٣t'*x[SX*o.yHy->}OLWCzP@<7x ~2fd kmT s d֯`wT:*޶/2 soۗ?Y_+7$# Ώ▮[eŤWA/ߗLnW'+ AGؤƿStFnzzޠ.s|Vz;IxDb /63Y1e 6ɲ>'̏>esnB ޽DE~W_<c08*u${qL}E&4 ʘ0f7yKs?|#'_],T G_ܗƦOt/peO=&*3_aRg2&#^?M^EOX7auQ0Yr_D/6@g=߯W=mrޫO^<4}͞wD{OxM&{óWΦl9\'Ig1yqLp9Nmݯ]$?og4 x8ƅ)X2Qryx,X[uo<>2l'^cW)щx6WYC^/fi`f{*{:v;Co^_Ɍ@e#.`|9JIWa1* N:/Q IwV*:a1Qk v`~tN+{$}Pu 3R[ <4ɭ\ W82؊wsp,'4~?\0&)F59]tuW wxt@:8*;FݧCxo/\!NG {⦆ ']9>`ޙ 츜xw&>eg{ MartgA)L6/(\:F ~M'3[]:dVӯá9p (蕆OtFa]Q<w^iF@( (ǥ=o+݊(?Ct;=V?ʊ5/Kugu DZx^plFgut2Go2q?/<:4?  9Eb:*@g"KCg?vؼl=@Ь=7F|gj964NpO}.ĉd̎8^k6|Yk7ȏNlYRrinwdm?ʶ] lf訢Coϸ:I 2ñwu;:gO>3.Kt9x c Vg+պ=(ozYwN6/f]G-~J şrȤO|gc787 H|>U"N1cv̎c:a`d1?kWv xBچ ~wD|u@P)w^ŦS#O[NGVhVK:U3 z59WSw 7bdGH>@_$AxF0ddHGß{Eu~]I[CÖ=cM:le&|x5]n@g3 8~t||Q~S'ۋ6ܠb`V_C6QUޔX9ls?xz)_|[bz* Vѝ\]6p7 DGuށpNrf gIɶ÷ELrLT4٪p y;p. Qfxӗ-.V+I7]]&Zu_ =_L\.=9/lY&t*G0eٱ!Hˋ^&v^}$\Mx'&L"l__.N!"V{>%NF_%(Ѣ/&LSr!'lR<2ӅxاEEC2㟏a_1賸 'Iݮ2{x_rk__ ~Jm2p~E'#1i;%{Tgq2Y ~:٪i|$1;<ybGvvхx R?}T7/;+=p2$[?L:;x F;;\1p+)(1##=uR8NG`(ARU`)bHQS<ʀp(j?.\&z"M~0*m`2<~pr񻁡{ O|ӾV!p*u+2UZAEpei6饇UeMG'm lM=/^*rdB=>׷SqTdԣ;voUN[ 4o*T=_n_O $F /۰E[) ?>ТP%ބC[e ץ ?c_Em`Ul:?͏ 'GO@-w<񫚢o |CSXpS7Ő6MpxGϱJ5ZObPvF3=ES^K )฿y{,Nקmvv2xpGx伎rL}إt[]VVBɝ\~z (Chp [W<轛jx[?CĒٝ;:θx蚘[\,m^Y/4#],3: +WٲLwkkvL~̥S;ib<>/v۠|NVd*=Fvmؑ^GNK.1ouuF:fO豟&Qx;mu w> { Wm/[%t6W2PΦphT1/$:|o6mo| v=:/rx }xib $ (8$$J3H#._F/ڭ(۶\I۲-~{tAڏ|+ص>My:yA,)-7qj>MƐ IlyΆ32w( ?&J^kw4k&nDqmͷ6Ÿ`>S;`!Ѱg2!,]p:rFjʂQWЛt&:ԃNcOpv>؍WW|&ʨlz%o|= b3>oA|lxϠ߭Os}}חq~hp~YiUseW &6Ik?7' ބm%ap6aMN?Χs  XΨ>nq)_`m`ox.Ų) C.6Oh''ӓ }O;SJ-xcoDǓ+fv_&/uKKŬbPfx:߽MP؀/ €xJq:v$SgJ+?!w\\h|;yP.|)/'5ROA%8ظqй#(CN%a -fpop" c.)%:*,!:15>?] ~>U`ϖ\Lے2SUh\e9+zGzF×ɿzu v+r3KSQ7u"?Jӹ}dCO*|`(9ܒXO% x0O7_ #⹖W| `[VY`jf26{@AVuG#?x/kAY g>]OT* g ;y\=ew~!ALOtLMjN{yC]ȣcz\.n4ZPO| O?\c1:y,i_+1\ OOhk?ʄr@$^ei?uP3}fw%zlЎ@`ENwz':QlI^ XA& p'w|F ʾ = k6}M]g)t8Пo{pѣqx`,|]b5ћխtxVAz 'mgXb w FgkN)mo _ytgu4}ˬHԝx?YS_ɖ><6|]n {`0QPﶳ\OKԍ ,}et~/<`|>WJ/<ztlO5͗/,` &Tbjhmm5*/O58]BL[=OOґA=KlG|c7DH4|⥂xNϦZ76>D{goexPvuk>AMe~@ųGigSOl`กS± p_ z+kKzߘ@ѥ!~_>/I S>8 %g[[oL~t EjlӶӕoxylq-bˏbxw٪0YtoUϊ ^I Tҹb+6~ @uy R~v|f^~̿K71B/-o7\_DDRew>^g`?{q a%>yV*&t4鮼 )EJ~HAJ~~$<.<W Ji7p>M[%Rx c 봏>ur§*_ux >CdxgA zx0I4g|߿#IL8u(l&wW_<^, v7x3g:&|ɰ[&fuxutu@䗮 -mz7}Ņ=Q jO;4!5ty\218e}u8_bG[LGSwg}Jr"yW{YIG~x>\{PO9qut•LGx:-gxd,ydP{怳I.p@GlGgw/iR~ӗiFY>Y'?Iz4!8Kiboۊ}a*ZȤ|&7PeW;]dSW楣şҁb G[lmHW~~ʏff;xakqK(ѿ}ee$.-Zv\c/|2 c_L,ztAwFz!Ο' p^vff𮾋a;;]Gء| IDAT]_ڈ:x?Ëo[=Gƻ6v22ƻ l;Ec2&#M]?;ktή?xM`M 6? hWdHveB]ç^~kdNz4 (-yS%#5 sBQqU y{/tò7yBcyOѢ4U dkp?: =J#`|uK6 w$cp =>ľFЁ*2fd wGWV#ԁ[s?_[#j`Y xD+KpGh6f9~鞹Ŀ]Xp3>;)2\RiWu/YtIs C[Pah9 ʼ^Mp5:M8ҥ-jF;Pͣҭ毣i&m68諸'of8/s ?+ AE0][-v7w ʣGFCZGrOxۣ*?xᘼS+f=gʢm$A7@[>x~CwHw#G<byt*µO~s_0!>zM?i7g*,/h:"%{$Nr>_;5VCA뾂:LżVBtUr찁WI'[!<:||m5I'ol&<݄Aixɧd}?/Q-$tV2`-jzo{o!|ŕ|eq,:P#`I!/xKUkM02f}M:m|0!6Pt> p/ @LUv&[c?ߛC/S՗8jclg>׿1 F 6@UHn= *]1ӡd#;/nW_g51gH經קЮȧ$j-dvZb avzx|u}o7a$+~~;7iw{l:aY!}_o t:YvO:ûG?'[,oz&0Hz$3H4P! EKmpveԵw`~ފ Ʈsi@}:U{ ZeCχթ7G1`֊4MtwWd8K& _0 8[.-Yyݠ-h՟x(݋L;xC*@L{7G>j*KGjNVVz<~쳸%&G] \?d{`zIM.Ŵ-c7!_ "Ie8ca)~#^—/?gG'3M>,_]hVnL`op$6ն3cw<,At=!gX˷kǻ Llsןe}?J&OO7bsJ3xސl .$G1-.Ϗ3vZ8vy٫k5ܯX^d jh#K'wgM8oBuz㳮l ݫ+X'w6\C,IѝoBMo{:?祍l~*tJk;u/t$C*þG#7Pʥt7#^K0d*} & YGӀyD4KfsvQ,$A2q,m֡{NgcTף hW o?Wp.hD1 */(CS8;s+7;3#o]_0AK'XQ48W.ră_c%^~<'uv{iL:dR!&_tǒ9~ob|(VR t8?S`߻0]:^J(٠kz dV?h[Jf2;xgs:ËF6u_hW$1I+X b/֩?GG/s]]PL= oz t]SЮ}0Swx_БӳFxЫwZEGo6=X+[#e0~5~/@=AΆwq;O~\[M}# ݟ^Գg`O>/M<ɳZ:{{?20tn2vwq7g{KGc@TBױج8t oY,vl,/tLʖ`P?!1ԝAfr'2/&s:ZkO'at<sX/K~"{}}8IuZJlVuIOlkΣ.!R_'R:jdqs_;Oivv(kv:ٳ~|m) yb4tfO ԋ^y-2g?ⷃ#kV>}d#?~{=E{lAxG4fcz(~D /e.~w=CIl;h:ҷ߷&vl7 Tai.ΪpcV+>{_3slPd7sIOX^Ep +O1Ͻݪt~xq?Й]blX%/}.$qv_Jr h5mpbbPlU^lx>NOJn͗h'b8ćAwח*WYnU7i޳x2H=_z{+nr>7?hѼC=v {|Ϸ GWGvjorF5@gbR鈮}>[?S7|l+.[^sوO||G&I?>:S]' oDŽ>g9bsH _\ڂicitYbxœkK.:ģrJHBoP?GRUqhX¹-6<يwV ?aN iħ O }U_ ޝpm~-{Y~Bx ;9;WVoQԣʚ]lm# F:\>[<]7XpE4ދ1H&HLo6d{B9|[|`}DL=6E֔q/ +(a 7=Ѕ 7o/<^hT\{`}0TF]h=V΋kׁϷg7{Ǟ?>Y[|[ȿ3ɵ2/:t>-x g/LG\&+*goytDo}b_[@/]?՝{~Yg3ሁ׳Gd;o~smV^%g5yMg=ʼnhQh+W׿lM(SWX\֎ t.h$+1ߖdYauOx3?֟"IόLz~|IGioje>׽r7Ã⹷'a-#Z x8ՙ`nۣN+q8LX8(>^UO!: 3FI*o7M<$lb&<6 уg뷼ıx%|}c%GN}N16bb;x\Dg{3{i}hs`/lLɵ`_Lic vO O鏎=;>?U #~:OI*40!E*W1xC1Qq3@0|8( ~J[tKaf=hDuFµ{AAC1wn̖?L"nH+8hb'b2GSmHWѷχf'kPC1=shkN>b]O/sxIk+vrUqT>>7=zʭT޿Go3AS?Ǫ#Gn│ç9?e1hp^HU#+C] Խ B~-?zA|uhېv]A?Wv|UWp'L6,/^p*Ne]#ʺzрO @+]A|0n|OO/A1uoH stO~.fF׍,-+Mv|-Y^YowuT+R{߇%^=džw.[y{ Cux+4ie:׫e=6=?>3 &kvlЁ_f四a.:4_bX;z:ې;/CMHh_4Hvj=/e^\SŴрypŠYS5gz YxT m\W\xx5㗟VUfo.&}ڸ{4:݇ $ C{ֶn+{]%|mkpLu hF䄛-6EՋeW.[ ܧmKoG\xڧdhp'cNVSp {:J~ lߗ_5ȫof-n3#/{ua:_VmU:Vm/G BvyA]fyMeumnyԕ19>tt$^u# ]Qm[YSXIࠪ:[o>&61 Y>"vX)nzf}Rލ._mW9>?HgX 98f v@L%9{A=iveķ#aGE3mC&/?.҅QW+y x!׵U]6#ZeϿ,6+~|U%|h2Ky$#aΎ*>׎DǵK|x5KL Ld v58 Ϗ~F,(KwdErVW7ۀ9H|{/cpOB_K Dx<|I*O/er'xx G7\[e&;̹Q+KE~}u4"ѤO|Ydc!te> 'ϫ w'յm$D`bS*!*|}/x)2ƫ#|X+^<&nՇo _gp3L {=4/,`s4ǜ\oN >7c>,_:G7k#b}G kb};?/&ďljV0/u*n?ĴGG?mPqwM,^x}mQ1;܏[]Sz֓N/vP?>e33dϾEepguiG5#erI\1>̧#zڑtmFqvanrtG6Q|WەKɧr>V٘ymM[9;m/-b`ɔo3%/sՋb@:bjĭpW-k[7'8H':Fdłb$CY"` 6W{l#!lM4OG|;mM:@=U_*5ߵ3_\lXg[?-a`/$>WOG{-L#ͻ|>~7;MzǝzNOHCT\ctwySyaUAL&|L6Xgzr/\Y@v>x4yq|sS&35:ihڶGg.bx56"Deus+{_ZI۶~ h r+x^G3՟O>M?#5t&+@ʒ)0H]sc`% T}I{kzZ|[oFD8knmҊ&nMb: IDATX``g3Aw\(?=yԀbR?D7#Cl?O=rF8)y*'V0_13Շb~yw}[ѩo[PZ.M&ۑyrcDӄjl2X9^H_i#tMmM51 d8˾ɽ]q&M&`ق˷aCzsx)+8/.?vc3e.Wg<D C"Bxkēkӳv"x7k= fP>:sY-o{m}ѧm?MZ_x &ǯ4fC@6_x?Ӧ;w.-50M)O:_{\i9  &uNaG.R1!(.9pLe?e>l;^'s'ZhJx*m^tSq#I9KmZq3iO㽃!61M Gy/+,$tn6 '4v.{tf}t?T<:7T:OZ%ܞ5OPQ0xaf4{;cIrċR]/le;6mSv] f> 0zpaX MJw-Z=.t :G OǢGwL?o姸 f:_=;k?IߙDWL`I~6M._~=Ե*aɏƎJrl>;g;_ zhZ$/3YсX)W3G|%Z9N.$S8NKTuje518'.Zjl: 8;1d+W%">R)ZcLAjsq45Nyn:q2Xy|:E.ѩ蓡?b9gJ :Z/Ɋ}pDNϞk7gu9]K|tAgxétxIVT۞ l/zZ 738t^G.#7)Li(Yk14?Xt< -K  WUG7pV|7`o _~׍tx:kvKGKツ?6X:c|e6{2H/ oe*O~+_;]/@? dh.KGv*սOX:< Q #xއp|@o ɵνm-[#Alv?N=xӅr~z/1ҭxd{ F#F>&s*_b+g&؀7d7H;6p_7&>|sȚO}y+BWWOzI=#/t_b|u:@ug9H{uy/q]OaGs. 񀯭[z$ӅIpn"Qv}eW:sIKTCѢ9]tD0%85'Vچ^>d%TX1hU&lUFYKuxU~2LMn8ڡ ~/, GNWtw;'+hF_fuu^l9#+YuɯCՉvė(XLWnEG~ q'5Syd_925{R A&490 rpЃu̟vџ |igv{9d|kԞ};/DGl=VNFp2`ߋ7 yVAek`g`J@g{,CV:z;lCG_}U=ﱥtvo7CC#&Isꅊ P &C񓌛 䍝=߽cqm[;܋yT;+S&+Meor/{&Zpu((W<`2&|6'v]/$w}]ĂMNWdR15?V!:"dGv$ҖǗTlmt@tlm/[_'Z^:z-k2Q\dO@=>$]܄XѶ,D=޷OlտJgyR[OIR}t4yF t$712Cw_zѧ;~oyE/:0wYK<$G*,H TW9ٗhgB'\*|B.NV){_|}>x駲{Kul*5x<W鈝`eU=3ԙ+G3Yy*m=9}ui.]^v#^M傁kolW𿸷-cst{8tA> (g ñX^_0k oX7 #tMH?,+ãUmJdw`WY>Mu*ev?#; 4llD}K2 ŏV۰ﻞs7r|pS+uA:(̾/Gxcjg x6J7 +8:#O{7o{|7Т[L JPo=afB+;lJ߻ɐ}:/Ohe`Yۮ#?/rm>i"z%]}{o@3Bx-&*|8`ϚM^Gyp*NW;_}џ~ߗ=b O#8ŴlǷ;]N]o| NlLLFz6`nҧ 9]4n䥋W|v/cO6Nܳ*Z|:v|(oxzqs`i/_];K[avW8Vx{?%H4SOq2;f{9Q)-N( +\uו)-h^%9'^n6CYEa:E?s9761:a1ȋ)pVu^ȹw:@1h &g u*ST ϣuiye10/̻ʸ<խeN>}@LL9'(;g^DLz[dtAG_臗 ]5|-?' jW?..an 7_:lbpaB #Dt_"ˣջJt2iium{镽fu(n`s&Ń7:MonizL`91I!xϗN$ d}?-F̏^=:|/m8ZV ?{d1S'|iz;y>: :7 5*0䅿;޽z1>+Sy \8;"y'xq 2쾺aWǛKlk[חϯ siuoun} kLTf:ijC:b` ?dE7y>|ڮ w&:>3[x޾|Φmck]PR7&L7=jG¥2&H6L3_a14~_L)]oRM5JOy)l>q`Uت !Pv"&^0sh-BmgmbSyw~pzY}/g~Vp;"m8*11S ڧ쇙ɷOPɗW}?;pvDf\Rš|0!sKƣ6 lY~ e>/,H<Ζw#:p^a|2U?ճkQC-Ie ~?OYVF8S:Ty/y)ĕ{iƞ3N/k5?9r(x9KR#'[G#xT`No_ `ut Ar`c>l| Oo$y|3П s`[qV`T?]w;$at>e2}m=tjتr{HT̳'o6ٛUy&S)ȣ~dHputrv*s?QG+rFJ3>et~tWU̓{t_ nx}l{ n|qMOj@w!oXz112=ltfo2{pҳm{mbe\gY}/k{qPY @W+|/hU@kŇـ^>>|V[-\`!p53q}~³$*F]|[ǿGDΠb?S ]_|b&3Kxh~֥`B _Wxr_pEoWO_Ot =~nDPP!ByMl8PN+ A `6)5XR-w z|z^韲V;|@Ε p+4 ,6NzY[@|Jo[霄ʪr|݁|0}ߟ^|1}]":3Yjk  Qjye2S 0dcpۖKP.[޵)]Qҋ&%tHtPty_[[<@w/ Fg +~p-Suv|]o—3g_XDzz[I%Wh.örC!ttYj/32K^G2CG`!; ;/¤VewɊxP2lUPc_"Jt3 j乗ލ9_ł,錾^0e=U%ypĶʼn(gr<;*c`v.*umkb]! yc/+U>$|.<иc|Zdz6` U9 v"LFzSg 3ɽAa|{v,]GiFP_*Cu`2Opk K&,ѹp߭Gѓ6G\K&&JlK2\:\Z_t?9EGr|a; aC'SKg'.N1-`M\?0WgN~KWM]g4@ +dy;1C>~ce]dokϮ頲hmvk^p]=t8f^IOʂ{My0 1ghmorQ ]Sqܠ5ц-8m0b+x01{)۽VrS߃:Gj M}wɞ # =ήH.~=z.8 BO:ڞsý: #~= g}|MOSvyd|k)9\&!Bu᪝\8>x=[hO֟\]}&3s$e5aen:.,]oG,_;oPec${F]3Oa7hLo(jꬍN8:ϾyYlcxU}QäU^tp[c?'~͢@:폧\~Z WGXOQouu1]3w$??^,9k7eNɜWfxB~2-VY |kӈUl':{kuC'1?K#]L_8X!/*']Z>zMvmtʗ} vS/l8v`~d6 #2o㻺Kd?U98|W]Q @DPǿh9_H98bS~u@|- DDOa>'j_?:}t<'+uĽc-&-b>%v^p3,:;jπU1*=yV8ύY\voqdTl F6Ɯ Fgh4'{U+?ᠭ-0C;޾k;Yb?I:Íkh_OO>w9l\c騾do{W0VL. G*x+|0>j#pEd9D+ Q#^ d>T$M;hK񨡻{4`NM:)~taT +PV4&wC/tl7X^sRL9aPɓ?^%dOlr '^ L$'GU2ُ&Sz2@Y\QFZ),++Εdt:z:_d}}߂ş4d>u[;'+;ؖ:L|@8X>2ؼ#4^R89.}r$ɌkC4 ~n؎δz5~z-VG=:5&dmb纣>S:-<w8]!<&F8-H|܂9E x6J/}gu۝WzQ[dtz翓Kz<:L <|%ٵC_M68{^ lbr0b# h{$Ê2 Aa6t+d^ծM^e넚:=Y4#}LCFNeTtO4QB|i*nø~`jxQ|lW?It w!bu.MRKwض#E/@7Ա8 T~W|牉0V};'Hv~o,?^:QO>d&an?}vOL-0}dx-`R|΂[|%ko(hSh[t8P^!6^U^IܹkG%la钟.I??MRcsY@?ҕ*ow3vkmQ,{B/ilt9o(һ4+ԻT|?H 8p;׌D浕wc= wpQ]'?;ҏ wAņ_mĈs[J~ ^OFr%G#TPp`2[W9Mx5v ÃCrx€hQqAi2 XpJxmenu+|ŧ&C}lIr:6@֨DѫNx)Ѐ[T,_'e&Ie]z:x$v٧:+C.zdAlVD49||Rq;-{1\Y!G 3)dc?TvN#๞k+ars>U6^t~讣 R%u>h>tOVr-„^.|{Ѣ'rޢ+>{0K;4M؉d v~WN۪s -v-65q Us> zWkyo 0Hd_y;̤^S31FG=&RgIasnwwo _՟̥1 =b %[P6c_لha~G!ī-Nh<)hq̷ˏV)bI^c+<.:k |v>[Gݢ?+V0uh>W[ zŷ_Omwko>NjOW6m;b20K74&}oPɐˏ`Bdٯh4^0Ġkt- geX$ŕʓ|9%a9Kg}[3aSdhe&"8`zanr]C$T*np<}?`EML.Ǔɧ m믟 5;"Ά~}]m.4ъއؔ-сӝ=[Zl&75{`qo4N{9/)~w(f/݋ڢkQ~l"䶏>ܯi-&Md]|p[ƒKϗMGw[R&l8^]݄H&w* .6/]k?h1~F0,a}͏:woM+W]:Ȗ|mӽt;]a5G  U~unĐ@ ɵ{_ē_ڻDN8̴\ϵ 1QͱΧŕٱ:#2_}B\nwaJ;z7o8&bE1Z{ rikWo5٨XǦ'#KH]!e}DՍ$qߚKH@sunQG;?ϷK{? kGȉd5;vE}ծPF\ˮyTBBp5E%AE ls,U$d˲GWc1#'WwtA*+#]ҘK| p Tw'cန}Niu\`mƚ•Q䞼/oAmC* 2sd[7Nտ꒓\o1w ?9a1 O^ޣ#NRѭlGw6D/Z: 'cBW\9>Ɍ. 60w.o~Vz򞤈(흗*+WI+>7 3 t[L"@0Sǔ:|2OX ɲ,4!;][u5XwΏ~lW_X, `$mUgzlpNd >pA[|ߝЏ{܄prȒa⥭CÖ`Q,.vz:8.Juە_lrWD8U>VQ5~q?/x'M'g&4.P<:xi צ(y6Y[.q qq:m203H{%C?鵟4c{]e\DoӵjUH?1L,(u/C3߄6w}N&Qg Z 5 Q2;}JK0Ɏ:ɂkDBŃ]b]Vބ')?'m$ ś苳oԏkL.uqtPY`fO~k/<ڽ$M.6Yݞ\WW;ϣ&׽Q=c7љT =3asA<>kcdxŝҾH6v7Lva5,cK-@ WW{gk7/l^+ugm%^/}È!vk$t"*CF㛏ze7ѷ TQ;aU[~_<+ ~x`~/ O/[t{},=:aQ}o8o#i,~>ɼְ,3bqU9imFQ(̒W*WUQڱ_y,Z׼e:ώ3]uˇɹd4\L7/q]lW/D G^,|[h'0W5>YDc>-Nm̦=b4՛ hMy>hݎhDS,04O<9>]{{x2 Lw]` vIOD!`Nـ[R`n g`߶N5yhvHhp:o浴 u=z<&w+ RH6rY 2,v^qOiFqw` 8WE]xrA_2wC' ;ѻHz5$y Ipuܰ8ή ]Zꐾ`yMbjwrrx({xlb]=aMG5 ` >5R*2Gu/p7եg̣S{^戦/y!?7pYjK9NoɎ,[\?/ofDޢ^Q>]Χ/Oi& bhb҆QCa{z/ɳx+O~A-w_|d*hLf_L-ndۗ^+9y<-w[W'K ?}8~ݯ/g:(pxj|@fe'١2m#o' zvz2_l1x#x+"o8Nefա|~o Sb-dc Ȫդkcۼ7HZB{'Hts)Uyq6jPrm?` ц6!-;ǖ}h}F"I8U_X~GxQ'-|!~ޝm+BR~Ozob:J +"U86P7xQ/mp1} I>]~lgI݄tvO;z&$0?~ݦ݉|k@n0Lv)U.ʼ>O~Ogj@4?bsTD,;vm+Q'~`oɵ~2T1=?lQW IDATow(oz?ѿ$~MZmnj7t2 eUp8G'w{H6CkQٷ?oRQNkp>&]9 &:|$ٵWCdM*?gFp%zU[1mE)q'NhlGe6g*E-,c &;Wt:\m!frTO,_{&CeS'd.'m@CduυJԅm ԛ*h#?{V8_e}ě-"ŋLN$tWn1`%u}4k7A|2:aIYj-VH?`ʝPi弤sv:k%C=At- 9_%{J3<7-HZt֝Ӣ77pUL_xG;($Let]- |i:kokWہSk@[LFJg[yWOY){Rw 66V& N78=Iy2͢4EM fd> 1@}4dz0ԡ{>B4.|rѐz3vKDRc&)@d6 ;aP$_XpoܦFۼ?|򝅊hzɀ=7ʷ(R&%ogL卅ح'77N/ FIfEho C{}6$׀'+yΚ 7!"Qh߷rM\ ;<$O5#AIw\]|—y+4XI' ~j?Ú^wUY#4[|&ٙ-#ؔobQt'+x©r2k,XOĀj܏lxT_[;Ymw/02egEo1ąu틣%oco/ zrgc?B?Eu{OqVs)sTɓ>;њ}phg1|c[wfo !};"*->cv܄Y_<8QI'}͇āUԧk68>d]_2m&+#w7*wTdz8gK{՝P,ǙmvZtxh++)/?ڇ.hp+iիû<zŪ@Qlh=8'O9 /9H|4b6L G_Œo ?_Y+SD3Ο;+C!1C1zsޥm 1UbSӕ3xK' T%r*}zJc]mL~G_lo4KĈ&bP9'ӥ( ܑܓS.D9<=oR#W`O߾gh-F+ {|ȯrm2oLْ酋& KC d](]xvl.*'Py5UÈϤ.dN( jc|:L;Ԏ|aZUހ9z߲_Z #j2-45HtQr32{:}ew8w}o7 k DOt3x%D_r $b?ۨ$cŵ9~#d'??]R8iءS<ĉn>;B?'kB3:%ߊg. g|& + GCE䭣еզ /ʛ==: Ȏ)Wsۈw/zbqUhSq|fq4><΂?FrrT&/'3 w I~>;ζb^toX;j{H_an_xθx;ۤlewM jHdBuc7oO@gZzy[[cju&ˏd߳9cN* ݋kۿIdwwɲ`[: G;Ż1^L]S3LF$9#¸q%svPh/psY5BgSM@p9bQ}0S?+V&-cm7Q?֫iA&~74_L+,nLߓ} L'eTd ?-UBXyق,̓j}/(O&lXD罜m/儩EMh]|~7cORk76迶'_O?r3pʾ{+y^vhLp=ÍXצCdUv;T8!DՃQ" d.ae}{-&VF(nX~d'& 2vK)w},Oŋk_{2' N~߯/} Z_Ӛ_'Ŗӷwp0t"8ť/8"Opg`•vJ\Ṿ1G!, bI}Q2s$F=GGu"es 'z.T-ݶZ3 ꟃ d 2' 8#y؇uqe  a]_ټjhm]0蟼tx-v,ЌK~N@}z(;Quay}Vz[4tw^ZO^&v?9aIx>цծ'8mODߢ0j͵/~Mno a4˟-,{/[am DxLr<?3{D =` 39ݥ%=eɓ_`_İC^wg]|O ϕ;M~e22壡N8\:#3}'7ᾎ~QYWk#x\gp^1iey\`L RR EyC0:_;Z(C}avɅwwFLO؞kj-R>|u'{r1gt߾FSOM 6)VGYX(|z%nU0VcXϋt"|DF _eyU5:2~xa`z*[ڛ}z| )dH60oEvvHhSSw'7=@x^t>6iiۨс zo{¤?&&[R&VY//#^5U}K}1o^Y4Ket:70D:k;SK w$[M ֞L>7OI*j[|kyUXűWø|g#G\uI^׆]6>h#KMN7!1̱k?2Tî<;+k{-3yȡп"nyXO0/'e*dŪibѷ;";&uG[j+tOU0k1Sڶ-1+K^h6-Qc|LNrξbK1x>uWPS]i!&ONH[~Gd5!% N;&6)3˛ %^XGpȌ7f9@"~1=v(n)K%p>Z9Vw2VfBUkuk/]]fa#lxѮM6Geq&OS? S.գ&31z[2?u ᐍ2J; sX@HJCѾb" %xg*v/08070phd+DZElH@92sW /W$:)=w}ELg2U]U69+?CuELa@Qnz GaU!N9]6#>r T6w2}a4LbTW?0xA%MSϗ?`8+NY9}[\޷K/ix;IQoE)}{/?7~̄D-9CƷreazS=ݿ]C>|犝+?l-(?y1-ӢRL }gu5Qt#g-jdwȫVGd{.Еm b<>#ok&ukhLXHɤdYOVr=t ;ZqU,;{vz? f(O>b6 Kj2L;JB#Dv/N^c: 'CFcqNg+j>l^hH&w:6 =fll0bرTu_x4W/$&akB-$@GK֏ߵ(By %9O@+f|0LM|6pVD"]@(L:vF&G5}&Uw,T kr?ѝay}F}|aghEgH$!<M9zйxswEd5P8|Se6Iu] (7&HٶCvŔd];*=_M567 NO]_e%֛OqdW&tsoXcN~ զ?k?}lYP_}'<}y8svlGtw`s$ <"?:Ky./'Lu~:sP] 1_]xdۢA3rwڕ4*MpwY`c}oy.g`^|mMtXICᣱxB&ϱE cF.&|'SAz?OFJaR4qn"Z?'-8ٿ.Ry vyuo?dS|_Lp>^P#Ѯ԰ˀ,KUzȉ\BaelceL){l%6VŸwVPbc2dKB'kGaȟN5HF0p6#Y[`)/[@#jx qz͏XⰐbƸHOLCᅝ} ,|W8x_ʀkMZyd;-n,Ub;V_5%#~2?i٣2_G@:c+SpL|f:g/ak[mŞTA]K'Q,(M;7>=|T&ɼ#oҰ sEj9@Yꨎ^|& ,<4mm9]?~ ]-`-Vjm}X ҟVʾaD6qʮZt6|frv~qzWP=cUO'Ã,{|'E9vtXED."ݴY5r鳻3Hߑ?)`&۩ #i.eޠ? 0bL&UHtKte$Жs_>G?MA_Fkɛ0?o~жύ\[֟}Z}MOz~ dG;5.I6BCl\< Gy}LJMoy /&d&HՒԓT0Ad/outrl"y4 jNٞˇ#^{}u0ig0wzs.vmNx'c~5Mq+o.0Z劔ړGWJ%w1ϐh77WTxgA}=z\Ogb$DVc8G${}56^{cMc&yGW1b %Wg*/<:,h@s 3|oPmœ)2[Ymױ5|}8 ~Np 3lN įauL^]b:caI8=?/75? `3 29.bK(GR ::lC |,[[ k2l[>SA<&Mt' w99iWvWj-fOhkaGײ\'96:? p+2w 'i;cMݝ)cWN-<enwWS;ITS~k/am+_? (i!P,$Ƚs:C|# nq8-̿[j[+?`s FfcٳQ}Ӌ|E& ߘNwfݗO# w.=L>JG}&tfUĶFQ5aGAa4Ao* o O IIg->dc?"obD@/Xnz>/$,6}" szF~&*^~g1MV.,YU~gcm-wxYxNMWA;h3;Dge[,C=|Lxmr</W`t,0 _7~ŒᓾW&(~Il"t?},zxj/%ƘAluTkrDC}~.eC] `Αd0Z~WF[#ih~ 9F0ߵYͯL;ElRM<|5[~V -B_1cʮV!,Tg1.{|\ oH%/ŵ?6z17=:U֋f(*x fbs̮,|8GS5^ ظ"/l|&|lL+<E^NOۛ4s#_L,eVB 3\ Bi0vyv `[_58N&ðriutбݠǮ9`$ht^rOw=RF>E5:,Ea{p,00`0,Juqڜ9;I4>oy˹ _At|0D{w9"Fw/!lk/҇ GaZ0,S \H򷓱ԇ?+@.<{PvV f:_ݙoe?좃sr0k̿Mפ-=H]F2>r7jG :&Ċ:};?GW鯶LXG͒iĂW۫г:lH4c0M &V2~tx)O7'm;vמ>R/tst?;F cMRM(5q6~yџ艻JH6w| Ly]Ul x?3A4xbAtFïto% Qrv?9e+c pwwfO0`b"W]v+DSڃ{*7_ȫΨïO 6,ቱ:쳸ߔ-Ol&4_ۂ߀I@_ظ 䒂K6. ;7ptU]]nUcZ{7)^<#S[CےNb;C{I>_4A;Z8VoҔ. BD<^" śg2铫#s"Qv(ߦ#,y ^pfhlCb`ibP_;_G&Cdӵc sO(r-͐'#H'p]xiG4,M@ B]8!wo6>!j٢6= =V0x3>~v@%a:ً{s~<:wMM=gUom͔~̳!|9py]~LMgBPԉ_~Uk^ٽIQ{%W}#*\c']:t@j#NĞ_wuU 0 t.gPCiK6# aè |V OгBNm='%|ґg3-'CO{wFz^my?M2k1*,?9>ksp@&=kF| f8V aIt#ѵ ~>Kea#ył_?a}Fa=6?ױ 1IMZ`xԝ!I~pţK|OOu4tΰ\ZoO2L&v}ɾ-9ۊG]@\Eb@IAݭ6c]jٰZ|Mg@-y ;og 9e&SmLW옞|qɫɽocVy*O \g{,M_dhUzv}5)GeU|՘F=v77Yo`=ýr nQtճ;C!JmО*`UQi{?w"[Wlo^L&ۼw:&}ڇg/[Pf?xf*J]$a]^ĺ]|7>}Mڽ\NXn UzW[_`冣]Dtd _w}ȿ1oՙ%,_k[@?d/Fhk󓔗^O.d-H _EmDێMNgi#KY׾h;+ްoL8ڲ*}}}/g_ZXDc/턺e_"獭zOd^,Ι5iH엵K;8Yðޯ‡[t\LKWoOv cl FgY~z%c/]?YA1ޢ@#OvtUovXeųȏѝcgR,՚X%dts^ Sn"t`(~譑zx @HtĘ)* 8؎ҳz6ש}v`Vhnܠ/9'jF;| Os̉Oi pK99I-k9yИ ҧ๳+LKK߇`o5꩛^K۬-$7<|S]CGd>;^6S-[WvNđ `8Tӎov/Xo[][m 9F9pS^ ͝*]~ .fȵhK5K-=iw\h(ecНk]Pzq݀&qeb2tHcEІR|ůuG[Po l}m5V>|:n'ڐ照op6/>RVN+gv3/m6O`:p/7ܢտϾ(^w7m uGobQDŽB4i_ϯ Vx^ܸ?52hw+ǿĞl}oAO(..ޮn`frv}L5>/a6G; h(J{IC؅ʃ&&MHf*gA˿zg;౅E[ S(ֽ5wL.v*;|Ӥlvp1űAszlq4MvDǀֹ-̞7pUIeBh˜_|aF|6]P^x(U{~R<6YA~ ]+I90#}%4N6AO+48U彇U"Kt;ĵW<'by8i?f/HOa嚬kk>ExƏ~ aُcX?$JWBV{o8]/{8wxm3]ik;[.&j5_ګ|Y|d|ga% b ht4FkdL$ϧ~]ޤv?5oS&Wvsa*2ƿ%ʋ/<=6=]pg5w~/Iε/,G'N{|a Plx.<'^F-uqo@ܯvN2:)ݒw5̇ƗJFw'>l(Cܭa 6*'[DosXf66@'ïcrv_rX_|"?< p}^qx/tj} O+0!6ҘPxc53 |5Ylw` ?uoS$Qw6 ^w@Ê NG]OK5px_bȗc2) F&;\8|./m 6@WqO0Y0yN~2-,>o2"1q:8cbLu?u.͙t|dק9vƣ0ld3HUD&O"MZc/VTur  0t`侀d=[MMf9Lrh??c_-^0"?^YpM:68Wg _Ӊԯ*3 zwG ?VFo.#kh{;?_'AgޜQ_Xvǂ ) 6O7+g(l0HxO\FN`(U ]=>7|R{ז;M]L+8SFj)KTojK0F:`\p^ W>>6sR+F}'b٠$l) G?ɖN{ŗ 2 Ldxal:=El=3&ą_z}/-P*WY lޠocbU&ytɨCy<+].7vo46[|C(Yij8I ?LP5XlEV:m2eOڮpl1;Ip6W]vHM \ ;%|飌|l.:h@ۢ|v-8aG[ =vfHwګp6+Xk'&;GNm +Fs}؝G(Tֿ=7^bAxOދ=vWk3?~OspX K8X;JW~u"=/M|f@|~h_z-6k/>wzFr~.QhO6x:}GG,|Xo^<,0 ?Z_L&H̬l`{dUop\<5X#.OlT9u|o?o~]>(B+{0 U ;3KDz2lV1l) U&7ު\Axʾx%bLO1_Ȧv'R9ߔߣ[h/gnrt=K_q]jxk:6At+C6gg_n^Ax~ܣΥŰG3ػ8%RΎj||0J|rDVGyv ~Sʽ['~J n !v!ϓA٠xl+5K'`g9Z,8 UȳFs_;Ƴ+$&D ^AʫY؊hu:7^LKTCF|njza'Ap ]^ݤr:5Lf~aS 뻃:%}?`_ًTpʯaJ᲼wV`YgU`XXĮ >[=w+΀gDٳ9_$ЭN\;kk˦@)m$ս;|J&lc5zn3_-c%K=[|co`WwQ=$_Adyps#S.ŭ:= }<>@`w9£W3MřǦcu|"/M{3uA[..NO||eҷ '֫]ӝ|G0C;[g۫U&}nS l%қCARCB)kS 6݌`g͞?M`N>=`pc[[6g.03n'vxFFNpOPrNs ǖ ?r|Ufq|z;?<~|}~|t*^@J3O}]dm5l?ɝ0>pxhLNpkM< P{`{"caGpt6q:@n2 u3Hݭ&`ח/~hJmY!Ovvgـ?9z^ɷlt? x.]ewu lŻ{)cB x{m}!bNXx[>h+ߑ7a?C:vOZ*A0x&?+/O['c AT•Ĩ[~(qf 㚌ۇϛP㟠ws__A&|&QO[pE.iO/>XjlI.8]J^O-Vk'I1?-fӻ8'^U&;H@M`k]x֦>xr2,ȁ7wk[F^} vY7ul]D뫢iBsW0Ű0 uaxKwl>b#N'ccupoG7&_>Nʬ>nafNV\ 7CsnZmϪ1lXsjT?BNF{K85%z*mF}Ԟt c[,*qхh8Iv;6?o_AwrQ+H8> u&5sXRԝ3nο[gX<8z^ǭE:06 ۷I"9ɀ<;dQ4 3YK}w'5` ?6& XBN?W;W'&ogoYQO rS3WIMFF.eҥkδ}Ζѝ>UV0~ZW~FLƈSN{IN, &AXgO N>`d`C|~k| 1L :q,Ga4n( f}&+}Wn 6 GB]Aeèuu5 :wfIs׀<݆?+xJ'``C-訓~7[t%?-v`xU)w> &EQZk \G--)^'OzЦؕ]'SeDg?×OU5,f맳}0W! m6.Vhcu/=yo|[LbDm Uk^[Eùr:#|VOz66yעAtX.<^?AS&[GiX߰ɱ6thmb+싡;=u a`+ L&!a6OعKEA2oY l;_֑[rWEwcs\nnHG_푼m$O)54;?ߝdoQkij?-7 V(}Qz~/|@tavO?4LBG?M `M^($7a|6ᓿ6*7T?\n } Ի"+Q%@==OF^Av)Z٠O[$r :tnbw&Z\9&ۆ[yx]~LG'܁#(ؐuV3FvfײG|](WM/wSܟMW18Vw;tn:(4[[P Gr~qmUΗKr7C.߫+*4 }1՟,m%y^Ve!@i"' #91xF<&#8pDJ66ɪ̭z<˄/"褷]V|-gH;0>^vq*ձvtB&(1z/G߶Nؘ{xOn2KBMNl[Ӈp=W-(/}c}WxmKuL&[@,nOo~gt][>]p-R?ħqꮅ]P1Q W'.OD bt_G?oK(nşJ[9aǮAwpMhrpJvPvy# ϨU ?gMwGVv:ҫ ۨM2xaceL>g ^Fc?Jqv:w aJ/٦39zcrbL W>Ggӟ;߀; jyjTxvOO}+1Lʸs-G|LA{xȟvwrL]?9dKL̔69-*Eǯ\g`#݆>-`}%>>WrbEe7i>'zu##^GehV>_xxPIit,8[Hl}uE?thH9C鏊#`5L;:u!{%?p'a6tՕ}m Ou]a᫑+eRvtblz-=TWaW"_=,ާˆ::z#< A:u:t6tŷ`nGئ&xҡ.^ΈGnP߭nd46h6ba4O S*>#}o\"hfNUʦu~Oi2EM ˆXks_յ^[S{YG7ylտ$E+&QW}dQ]$3L:7NAۍRlLG=ZWngYlH>Yx8{:}ޕ׭!V Wl[v>UwG|=ŏEW] Ъɚ@w䮊/wņAV|r? uLŽ 7[i;#O:t5vtPB?kl {D=0={d0:1st1|cP?dE~A֓kOynxӷCroqBX6{o0Á{%mhr|q޷ݣbj'WD6|{HcK ljퟲD9?o=ßbM_d]r|>;ڋӈ4۫oy1&.]{qWM/6']^,`qX&<ߺc+G׎R{2o4oqTچ[ظm[C0}WƟ"AȊc3!uQ'O3[h{SPY*8j`Q .#7%1/]Y ,^Kch2Odr#4+]u: &mkx\M~ OobO C5Rݷs>㗎svgl;)ϕ=ǂh>]΀ҿG+G%oW!?MWg|X,ӹvy/32nbNxᡣ!G5t#X#e6Y DO;XL%_UƓ-)xu<)bY{Ro  ?NΐkUetLöhwEFsЧʬXt|? ^]Q9 ƬsalVL`~)]xnc_y:<͹{ee k78O -yW'+oȿ I2ԍG=9uZhNzPzJK,1]: WD{+Kv'w _Y+0JȰOFLfC 2:~ܓ?4Y{1ڽ<[ꥃO)*&oVϵxE1?6_VǼԧ!d+>a͘)9F\LmGONbJ;xwHq eo%T扣x[^]S/=R[ٔ}mp ݍo9b]^|DvW{u~|n8)y>Zy ??$Ug=fG\%_:Y ->E}}nۄ<|9φ01t3AR]ݝ+MWkA_N{DlXƓwuVeo LG5NèWFw*Lbyvы((70B~v_x~}x)#@/ɡcߕ6Y?MFM=n"?KQz͢ЋpBsx^(n Mv4lnx pѧO%ѿzp3~H:WȮ?q .d^&̗嵉{)߻N/m1=;Vx:V{Ώq1fclU0߶IQwhm0|3 8V?2NȔ! E*Uz0@Cp\<`ܱ˸eՔ]'MIt Ҋn}ݧ ~Hef?MIPO;QNgsϑk(KgPhh3ë)3#Ά$HnML^/8_4~an'j7iXAj֎#MP{w2|5^mw/K_eCr*69Ee 酸3wd8#>H3(44IDK{')?9>LN6atr???E'JI.$O}cZu`O}we| LXй_XШԔ=b%Z%>èOEҟn~?jw Ez-[/[M_Ru|ducVb:/[۵sC /Jy#G,u3^{x?}q/6?j@||6TvߗEz}lpo{٤] `LJ0x C?=I:"~ ݁ & %O,X ,7hN62,<5kx1Nf cσx j}0x_  uʼF;en@gm;wL IDATd˃tӅW~g)Nև G٥Ux Nڱd G`/}G䋋RaK&,AEǿ4ZxY|-⮾do|J&O<\=W}.,7Vf WPPη^a78%sWT+t_]]۪ 7-@›I^x1;͆%c}g3_Mp5~7]j_ڧL\%^-2]]s`/fK G߱_~7u& ϗ"nϻEqy&T {.uQ;>wvkNqO:YOfYY{~iQr^]u/3$97%LB>Uǯ䡸vQI0s#o~{v1g0Vzq6:=^oO8۳>)?J^5v'x+8=M8ˣO4O5zͰXU/|nbjmqh#Dp0ZFaeL>W7΋ L6٧uӧ>6]ɇǝ!020B_ w>㉣=ăzX|kgc6;傑#_lE3=ۧw^@{.~㡠Z̯'VbO<( wudL~(?=>χ76-+od+7^RG3=?H,] nrtbE|קQ%j^vx+O erxئ^,`) }D5.F!Ҽ;JR2rKMLƝႿk2N&1jYj]o[{\-O#-'osuV.gm@6]!:^CkK(Gmtem5H0Jg X,;8ns2;ï68w<si9D& _e;b4`ؠ&/^PjA3Q<]"ȷW[+M6[d?& jNcOwu hC8_ -=0jR'=xg3AߥclL p Fo %;ϕǛx;<7h+uuջHze]@XS;;x4Y :]Yot?4;b>m12wU<Ҷ[o)n&Ѱ VɮAl" %e+>;SO {=/^|00dэ^0(. r'uc/ZW~#U[] faDǗ^X}"z*2_7k1ImXW:[_h-=j(eS/{INW!Є齉qbN?߷_{_qCŦ\7{9caZۋ|bү>< ʺpQ)vFm寽 `ym6uӺGdV^;ΆS0>3.> K.69xucsE|S.xǁ .qi}|My[qM޴me'%,C[. ٜNƟo}uE ma?vb"%+1uܯ"GwͰ3wۿ11A|8Vb?'\ao\_ɶL n-~݁k-d;mgRs c6W<+Dx^N8b& >̛xXTq=Lcdܹiq,F&퇏'o'-Z2w6[~U6i \m+QiNex4=qt| $'|Ew%V10tYbnP^2@m1y@Q=T &`pҧU> Kҩ)C2 d^O5JPņ ]g &og< e+ /.?pFT ƖFd8_q0`Z|Z" EU<*d>| #reƹ(Ţ9*avnʻApm̞}Wbo|:]"<<<`>?-(:*wtt |?~qqYt4\F/7M(MwηecXNO޾e>u4e=6m;IY]3di+ۮ7ýo#50A٣Hym!*ݫV-ˆ ءOJ5[dz reYՏw|nQGЈ3?^+LgAtζ90Øwovn6Õ.qeUʷ {;o6k[ :M]=?ucsFr:g#ylB3zϪ?VGё;`uRG o7gH,i7Yb̀_|ٮcV'&^|L N7ǿvnԭ򟵠ǼTd1k"mV,oϪSEjrkf0o77mnWn_V7rE?^5{fk)A+o[|>y6~(-w.KN}w:L,b`xbgM&Nf"&oP2~銩qlE>ETt<`VԂ~H6?~0Y<_W8s& ;6lo_bK'nBAwI 当ѤŊMkk/{chl;&?jwZ#wgA2«Ds-Y]ƛ{[;]Tڶ4c`].^f;|9IL|LdNg'rIcW;\WyH0=kN]`x;,_V_G._pnV۟?FYؖOĨ@l&Ádϣ'Owz򡕼ڪ8%ut `ڇeԇR z|. >8.`xM]LϋR?g/)bX{Mm|W:7tǰ#m0ʥ1e,Rv-+]滎a_sGhŴ}%_}-:!CbuNɿԮ>v(uxKc/zHaov,yǬ;w?Fo#)Ip _?6ڛtd?b]~٘ے{)伭]eKCqc( U_`B'܏ ]` |63_.Xz~v`LUspD2mpwPm~'FUr jVVV+دO2>sK~A;-t:Mgf39.7o}ౢ-\QP}m0M7p K[0{!uyp1 O}r0yWWf NÒv ӷtrj>zeq,ѵ@1[ۑ[ס[J{q^bЃDRWI>6ِ/'Ȝ-ar^ysob_6ske7ux]Z1 'ݟtMOJSWѿ~nyecGoə@BcS~'%<^ul4XÿNp%l[_66w:a~mRZtD`2ôX8=NoYÄmOtbش#i|; ?Vȱ>ɦ9Gx>J Ym 7^'^7@,1f_ruڈA=us6N`0O~]oMNϮϦ6I:OѨL7@U{7ǯk8t=`=d_;A&>0x@z>EC6ЕWR~LK}AJzJ; v# Enm7u<~IΟ#{o|\gXm7d0_ =O<&5{?%ߔ U{l|i|ѵԤWpDSd-^}/ctB<^Нe7FX(-/{gKz#cG[2IfaT1!@/*g7N(E2E1Kp1 ȕڔu82 Cvz{_z~JzJ/~ѣ9߭mSkSĕl%c3pi_tL}trHݩ5 ْ0էOW8XZ[$?-݂KE`m'[>FEv"N=X1_ TcD^վ mtJ 2<<&-F̮=ŕv)6糩2]`AcLH4xqo䗧 :83a[ņEv{gh<VB_uI;m6GVll9q]_>?~-9*D|z-}6N.o-"}ق}#^sT>9ݾL/^Qq&ohSo"{VGc!y.{ \cF|^GG[mJ^OQ4~9dhF~b'_~_;Nv]m 5aB6<mr6e(Iʛ?)-u rUY`x᳴vw2<)?7gg|UmK/G-5x.ܢC9m|/mjkq=w:>dlwIW~g?]$5^Φs0g.߅I|~G ##(6}y^{<>pa]yN Dzq+o:QDgtAs?#ke(1b%(M&函eeUeدL<_<ăvz g2mSd1Ku8J6R4uLg9L~Sw_|K*ѻgr>+ EG:.jDЍ_gs]);ﷶ1/t}WlZg a<ب^-/f,l;W^`PUl:&󭨎hv՗^m|JnՉorζ <(C>"U[9^rv1Rl\ /C٭  LV`Yc߲3\aۿ푇&ќ|LԞg|2ugxzx9}G63cpw^LLp>)IQ馞?Z& ?x-NE:ETx{u+]R xX¶tamo۞|0X`*cvFϧl+#o& D]I@'ZW_nz ?Iwm7<97?WaaMг#"\΋6a 1v$)n!cd?p@lض[ۓ_o{!u kvZN˘wl?sI?h÷_hM$o&B||7Ξ ;k^8,зšoՇ0/V\{8J׶t".MrO/EVm[[9S@'%b>5>Ռ^[ Q?MC;ɷBT[:WV"P7WsOYQU!p\XoNe=t.l{G-:v7 aF%v>^k7~=R6=f:9Gwd =i?z+aXm[{ןc{{*{10/ӭc;0d=+5ksNЗ}?_[ؗwL}d vcgUGvo`!V#͎%d3ݱ`/k%X=x0B;{O?gg}W6zSDݲht{@qdt//1]k3_k&_&)`d_28~ͦC4&&9Z9- |Ozl|G6`Ng:dѐQ0Z O৒>3aȢf x"Mi+daTUőuˇQ̲k;t_3y$uLQZ>!,OP +_vm9UҰ)@ 5suS||m+#qsKE4VQgxo"l9xt;sXm, |J}1 Gviٰ[,,+k(X6rY~ؿ:;!cUtۛ'J㓭,gXƫ=wFwؠ2F;XKPwo@` UU^Ҷ%G~垮GwG?lgg2lw^ w2IXo</~u(n< =\- V)D'f/ ,}o&*c?gukzXyK`ȿNӏJ0jN1 ['2ݶ13zmL9:f+zzX|ܿE}ۗ #s+zEV1(I貸2w; ĀmZq?ڦ<>Y#{f"Gcq7}w<<_+ClŲ--0DW6LDmF朗]g6k4 Sm;M [ݥ?+~z&Y4;nqu {>(v/d`GbԮx,˚* IDATm-eé)v>v$nl/w%W _{8>+. $F[v__O?J/ `7?w?5Gp"w4iL&*cs~^>o&gTG6"~4S.w{^ $}bju>?Tz6Z^;'_:],BӖZ? kߋc8d]B~E;?Ǝܥ?/iG|6(GNEyY>;]IJ>ṶKYzJG9OMĤ|}rIҊoK'svO0Rw,W~` Km"OJlqT|Vo0m_Σ/Mi#g~uω?6bx'oa}GLJMR˯|ƚ}z^9mpg%;*/l{?8ǵkgyA<:[e:mtV~X]3)J4|Q}F-< DweW&[7IHE:cڣ o^E?,'<Ï1Ԇ:vQ=7\44a0c10/f,{΍_yX{\}TnṁLݘ1.qp~?!g/EIs:ӃSɞã kvxyqqkH B<ݖKRߍ_E (%sigKx{`κa<~,=BH؞$ qj)[X<@Q8MKoaU3f"X@5`t(4a-B,`-c;U,w)ƾlS Ñ(Lp& Y} L^,h&lˣ0CpmB£eC]Ezx-cC֣%r?֑)0Šd,g{`Oml+(_}=d cnAcJVɢ}d_yxS2a ti{|MD8IS#[G{Gv}a)񑱆No:y|1-xK)7 <-JUxd;cvǫ? 6@|o9o>NM\bDxR龸Ӂ F}z=aknt9`m aQ^|AΒ9;sz!S?k⧎'C$ob2 Wn= 0+0_'&nc>,6Y?igxHB®*YzTl+Y=r's9Wh8Zኦ4Xo>t l[Չ~}w U^,>Mqyj wIKOwz* #l7:}>{֕p }tآMR(QJt \!~>-87o#crGM=|&[\mv/q_ :2=LM2}iҼAn v| s [Nby4MM01hTlݠ}`LiW7=i^_UA}.Y ז$Wh1wߗ_>;V;9Z ۇ_>m^5^|kFw<lH[4Vq6񁺅\]֏Mt ?ILz}WwNt$cG^uyiؖ^V_I4_<:(ϵ]trMĖhH[Ni㍤Fg9LdR5Op _t\;.6#Oa91Kj>eև hc_XăYnX 9+Cuv%Y[h`>Lc#1BaHثlfq!+VП+O,F66kdabqirpeoz_8+en8>߯O(P-?+s:DWbg{!#YpHX[pO?sXgM:4@?}&\*.ncB#cݫwXON_untGc|*cugHƜI\SxmX⭨]iڀ28C 4.:z磃x>d W=e h{vwg[1,`rY&`Ѵ`ob|w^glٻw)` 6[:oyh.8վxDȔ|y6ovu>->3xS=GLm +gr%n>_jW? dE2] hg>MgӼbl4i=^зzp1p⊭OX:~/@vk'$Lߌog7]?[ /|c2mW޸ uRۥ|(lo\oB{CdW|2X,}wc5~)"齨ܧadҰZY8vaƂ6j?{4,63I6 }D, ɯ-q޻SfMz蘀ӡ~tܹ&S3߻˘sa?w7`:V&w;&ȮC)&pd(8:S_ɔMgחVǔ?£1 ?%6?>|,Ki")OQ&"+ *oBXb$AWd/hmo׌wn`1oaYSnt^JYھ1`(N׏攅|2dwp8_7~nǎ-^"-ݶ˛bl{ֹقuzw_=>, 4xs~}K?-T|'wfY@SIh[گD5`)ǐkX55jw B[4c^uRh.($ƒbȷ(+;Љ91|ϥ{{LW)ysؽc,X|s~έ>}M}nèu/.Sr5fϋN0яN{U?wbrK wXcN0s~@wW~:GWYbydÂ;#ag(n`/Cd>>E`||޶_> | ⩂ߛ8͏-vWG\^ "xG.iuX!c'#><(JS~uZzeVx햁ܧf{~>?6l|Ek؞뉵啿Yշ}m#r8 [=po]Yg8Cm\O޲P6/ҏNTQM9(v׆׋:GV:}on7nekwKmGGΆ|˚c" r,b+,9QtQܡMxϧ;;#S'?HEX?=|%M?o;oM^<v\L_~+ڤjR瑐4~4 ڸ~7X|˯wXXhqQzm[kc1F=oPZGw(WyVFm=g>~#X\9~wHDFQqxmAt%bl(evɞM-sw),I?2M͈ll^} PF hY,=_?e޶Y[f??+s߹#Wd̶l/τ(GLyTJtn{Aő>W9fѯwOyvhŐ|t@ǵl Y ]<5*OVyGenc6gB3C)Zbr8@MPvzZ}I)λe: :]-g&Yf-0ROvyOKu elR6-`4nԶρ- A{I򮭎c>|-5\l> 8xiqxGi{v-({ge\;::__P">jۓOmJE?ϝT=7W\-Ww.K79$oRYߖ|Fyݿvw~L~׾-ėƆ`Lt.ee?[[9bÏa7[/{9أp?w}H|/S 9{t=6MUE66dyb]Woa5ꐾ~fYO&RhLvڳy+?>oGm \@A1Uєţ :yWޕDmYq*˯*%`W1,w1TEvz*irkɿd̳mWue-DtWϿi%X|ןwsU2 MAv Y!:1_96(^|4H?ueOxwY'o|F&?th71w+t:OcR?AX\vtۖ~ӇKK⪰oOc+gm͓._Eralӽy_z8T>Oܗn@#ۤTApL#·4eZY1|]~Ub\S5}  Pup_pCKC#W1 O6>dxΑ>>x,bK~W?v<{H5a$Y8IϏÈ5wJol{0yik ~Ho[{M_1f2+nA|pcn: KiPL);R/~6|g9=O [p>h:^{ .g:'uL?]mS:V`:ei yg^h侐Ql݋ BΝq6,|Ua;]Co4!n{F`p,pԛwUNPɵ=MK6k˖b?jceJSM[vUw8j0H`'Q>w}adxŧ\y ;mr~Wrǿmӯ#vxۮFq]>}]^bwropWFv%. ^ K?-Hg -mXbh\S~/ϻ "㱠S&gg1K;!ܺKD[fwGL1YFݾ )?x6s EJ㥰|w4f LtbT^ixk6?7?!//ha~.7/O ?SS>>_=bkjxj:MNv_uҸmwr׮%v팶2)tcl`lQ&,e+gquW=,ɻ&^EI=jGxj ??'}= m dӰٱ ] @;DOx/aq<_ǿb4eڶ6Kl;S|%lb6y?2U#M[=~ջ'Mxx%dDD]㍝w»mوHXeYbJF J ~it B~MHt(tB7~nϰMd< @POpӁ~%wnVglB?uTyo\++xM̗ԭ0*6`55h=uI?JFϧ$O\tk>M*<* Wn=߶*eڥ!~dWCeɽ/:3 u?b6O 1WL۞8l/&F|-1 "a$Ra4|X]@3{Mvݵ6^B;]ՠ˓vr5#W7:KkŲ*&7ii*ӎ>7~hѴ1#I/:EO:f?.|&+똴PLKaj#Dw;I?ٓO^Ju^b-^w^*(nՇg=~~sޗ{%+X{6y&Xa>Ag%+]߲]{$ V%>/'Ŗ > p٥_~z%T/0/U}d<?v}>=E4M {OYŴ *Zڎ/-Z*軮`}/, OwmpEya&v /̿kryw>@c/kL/ -~l IDAT~+-JI0m;| leQB<1$ %<jD?~HlaT䮩/wxBN/酛v>}1:ȉh蘴tD!N;_bwgmNd3Z8u*`c-f]ڽ]Us\42ɯ$`љD#jOyޘO(ྫྷmbIi4]$]k}g/jֿ[1w0l ^>0}WޫgEw8[k:4a+/_Õlu2F7w7qłw'x <7& Fxcl6[Z̾g'/~ՙ]N_i}x>kֶEAc"i*sm LNlNdn~=>_Oj[U {JF~_x `܀tBU %>/OD6#uN9(ՠʭ.o&g|b lkm_nk߹+VNs()8&!4tOJߒ 0h)nAF':tƗlhk*:Anπ7PQΗci"?٧v`OogKʮmǺLF5>oNpN˫vbj87X,}tѴs H:v(>ՅdmX|KuLGvx/m[>Fs|e5hF]mǮ>gWԓ+FG]/6kW`dc){OK'3|gz8IcK6)9_vh(;7|2, uz3`wk5 KpoO髮,~v]n*>qTxoudNo翬nh{m9,rьxo4D*=cbi;YT)'ѵhZtV'Z<0|dTvmbw%_z,Ftjӻr{x:L|_Z76dpK׫#ycmGG|8o׏6y-GBCA-m_Mɯ7{,=>kY/AWb+_7 WLaR`wq-|ۻ:MGwI0mNw^ؿ<6/6.+ u}ѷ9^+8HvݩMHݱ~'9jAW/6l7t|R+: SPС [[L<rvTwwWC=b8|c{!Y} {G>H- vk_F n7Moo .wZy9 p58W ?s߫p;6Y[L_vx zSUfmz<DťSmvKuqt>5ʺšg)_lU扱!,M쳷o}wLm;AbBG{!6 6zϗq{)`4FŦq~H_0s~օյpŸMs}ζ1{EFx>P]-ndtb0n퓡ɞ/&y_‹90]Ђvru++pSGibk-how׋aO܊FWjui;~uaR,lCM׵y5a>SOeor}5g-<wY$ tRJOK}h_]Kr6&Ԗ w";w68 `uzh+mQK 6~eX ֨ 6krBBcds~9̶ p6竰+9UT`H翰`rH yi YC|:T HF="x6q&ulr4S~j*Iaci&Jڂs5SgOh#x?:%}~N !ldNиH7YN,숗逤}#5^/FQj0D;:,欁PAhu0>Te~jӋNAbt"dp-r· C1 ?xɝ؋0uN~v5~ۣ{Wƕ-ub:rM'4᷶ǿ4ePאo9N{Ej8N7tNpxt+JU|ǟuG)Zk7@8>ʽz+?>%m^ҧ4L.(]$Ozm rW6= ٦R tt F";L 6:{t*fckʪC<>o_T9zG`^^voh.aPE+>i;v(%+ORo{0W% ricԻ|'Sҵ4fWgɻ+|BG>[SB}^;q+ŜŁ7}q^Yx4>?N TOV4(=&y6*mhea/XX&"Y,&vkjeʳ}`qm<;m'KEsJl۶I.şȺ.v>^=f=1_ck{aFrcF^ ZHm|LQS;g:> 9 ~:փǤE^j/&G3!tǟ[РK{1ҕmq"vtkŷw (ӟA{zXRpf|J펖X}C /p0<7ǓJη]ZyqC*~M~(/q"^l],|M`kOl;/v8"8y0g?jNuŵk?W/Г/,6&pp̎bQ|ɛMtFau;^KWW#F4i_z}5ms'`_0a}g݂<ЉMo{Ϙ=z|+0H@qXv>;~O;-mt`7U>zƔoC&tl"M[.5]1Ot^)H}.7+{Gu1q|Yyq5|xzhc"b_԰gr|O{'͊G9<|t}~|4ϴ7pxkKx͕.lhO& ~nTQAIFb8G;h}ʯqq ovnt/UPl1q ]PNezW\="#8;cuM2a{?`C?' ;`7t_6[Ytè?aInp)塩~p+f jģ[ʧ7or%Ok_is'k!]O:W?.^L*WFg~g 1XP iW$2~m:ioe=vش~-&<l&Qa?ǯvaxKPٟ& Bh/⽶g1nN~ >įF,~ #4!M6~tEn,wbmTj|~:/VG '=p9+,zbՕbKWX7°^oD9>uڝsm0DoۮVϗ)'76`9IoKYCzn Mw%myqLX{Nƍ/.mdSݦk8 owl,q,d"Na+ kAvXZ|>.(ݵ&Glw7z}:WYJkt+2)ŇH2Byw /^xm!tmY){+:/f>k=;r5 ~n՟M =N>EW{>mt.[ Gb6ƒ̫DM[)ibUL_H\vnrAӔPM9'b^RYl R9H\dNa?e'@\yk jԛ$߂m ;(P:%*8 6 W?ϿmϿpG>5 o#٢xfm6lF/{*Ott|Q/%O33:ӭ_Y'?r1< X {EB4GF$(Hoip*t*_e8=엞Еo | :Ќ lOa^ y-(Ͷ׎pN.?LW䟟 .ّ;ϾMRdNӖAyzFqw c~ KSl4Kw+m~|-ag~/op> kF$俴~ i` 50OiVsx5aS|퇣OŨ.iVx)V1.ƿ+_d)hWWgbymOE]l CUֵ ~8{\(b !?l,<‡p1#2q@cN!kUsH$@*UW|?eg3{57$VnՊ_/*6:i+,RI9Mx~J_v՗㗿hט}Ng&M0ot} eAl~c —nmR6ˑW??~50 oogE["M<%鸶PWl21[T~&r Ǿ;>GOޯaoMX!|&^_2;xNgƫSrM8䥱s <SXvujX#7˦$o18>㕝C"!,\ wY(i4FOק#>b{Oyg8{?$aJO cU>-?__14~BG짷t*r&OVFGcw x8e}tqA NÛ?9<^GrmоH>|`5Ƣ>ˋ-ȑGnlO/?և.N;1`ۀ~D n\PR࣐k  v`_03l('x :g)ϡ?>:ql"Yx8;@u~ֶwI'7M>2}1 h ȟeV}Ώ/j򭺺`?y6vWܫ#݇>&Zm o9~D/+C[;]z4^L9ddzeΩO2y9{VOMme:=e`S>; %G-8dжx{+b~CWoC^&Q(Y~p#Y<991jo%^ڍ~AJ<}nPa'@V> &t*Ll`vwG= 7M:=)lgUrw@xـvv|U !zdYGM?LE,m5koқw‘';=u;E.G@Y' >9NܕwK7 PW&(u+oou ]S0Uo~{Xrb`v]픿H|ض[T:n} w^hoRMLFi!4DvWt|E$=loe[@`XO`'؃w-jKy܋Nj IDAT 2`-G(u%2٠?[|V͓<.&Un97)ruo[f;oK7>g̮6]v\q~d ,(@ZU-~:?`n Y}[W)lCmbOi::E3pQV7ʈ׿M  {lhgA"|[~yģMh}_#S bxp&Kukrw;dɚ&¿|,_41'y&|tgr@g+_yj!>0Ѷ;z:Z]no6[/CM¯PlK)wn>|3~99=Jǘvw\O7!?n wkC%V;|ݱ}U2/=B]8'$X᫾2~etegc]ȏ}"{WgưtNƪ./OG_0Y{nk0] d"4#ͩ%_r CLJ/1W&OݒYDYjW$#x>s@3==!Vd,j+L/;~~9Ib'~%xcG|x$[RYF'Z /^ImlDhᙜɾqym޶$&_.:te6h8^.Lq,ЄUj=2ɳ|U=/;B{/p~W v8;}!0=thyvEi{|)K4'SǏ?Ĉ"t9O£踖3‹M'uB^N9~(8+W?o |[&in@;$#C-ӎx8u.ONB_'g%3|B@ C`˞Dk/ra#c:is|M]+#A<nS#|؊v68l`O'&_l`)(&Q&2tO1fjܟMNȅ} qj `^/tǤ@xdZdQ܆$Iftƽjn<۹[=7 j^dx=y6GuyV9(_Mc;mj|!xoQ0}&@Ε?j D/-^:/?!ڧ?@&M0^-€, ;hapWU^\x+#?ޤ>6?\ޣ+ڄ)F+)> W෸71-c)&Mu(*,X2+!|w%qwg݂Dz):سNF9ѭ? [#?۳deo?-80Xȥ:4zʂ]g#$BH2* >bBy@Ů[8g&4xF`C*\|I:= <=Dn_Y'3[+.fZ7o:yuPh4~ext|G4I}Nee>tdKLWbE]֐<[obg40~Wut_2?<]4~GtԸBds/McQ:Y&1=C4%{O Ug5!N T;7<ő M(E>|x=xTD=kW>s3f1>'Cc~m/@ی@ћ7k賁Jt0c0gA^OȮThq~}^?z ^{dC0t`$YS{IMLH|M`,~-O٠G܀hP>K\i%G{(c ObO^p_p]j]{J~XtnNm0~϶:>_xKGӝ ݳw D52򉇏ӃM)8,>RNW&rM:=^ce rll2gl#SY]=o>Mމ=rl,h{WG~6;o]gI?/|< <~cBwJo %߀MNyup'P{<݊OZp"N~?z`Վ^uk4>Kn٣5 y}5d8fm低C?_Oy!o~et%`T`71IQɁ{x8 o<֘ۂ6O<2?G;Zdtj/ D7w>z[k͋\睓'?Tl+} 8Iџ|O[ L1;aɜkW_yHeUCt Om7؉A8M͞E}JbL58po<3!~,|O: rx ֻ~u\Cob:xiO tl:P5O%ҝ .q&A|Tӳ7 w[r3ӫ,Tjos/dO6-Nr|l'gbZDr[/R):.{|)^ͷ.~kMֆ.k"Gw'Z|f:˃SdGGrq*7 }7* "?>m,:]=C~ww[MtG6DWYYxyaV6~(.Ȝo,C7|y=u<:Џ]NOo᫦r{o+\;RK!rg]FCʓt _o!͇M*obHN29Gy.N5Iwn?[x%8rgePg>p4.NaoOւ6;y>m <M?ɒ-m;^yқg͵ܱ xCr2wwߴɎnd fgv:أX3eeڐuenƯ?XݶH Ocdz2U)90ݏ)9&=-Z;|tƏU>Kf ϷǠƂklLJp훐lB0KqN>9'8<ɶm%w1'F۶0gE;z%Ӷ7QHL*GBVM$Hr=雵!GoMɬN≓ɧ =}{ vw ߪr2+; :fb@n)cY )havNVUWۦڂa>s7=5Yn/~f\iமj~ rCuSPWo%h KǕ`r(C'6_^V%<ymy賯y__D2_t@>>=z~b&eϗ,[.2D/o/&.BV?/ΐ _l1xmhUEy;t@Ni~ʸI;kZc& C&ڷPuuWݤ~:cQm}2n1};]R?:ZWjq|ho|:KՋ뮔zWfpN'mb/'"7X}N/6h3bOlIx,߃%6`Mvd]Lx>o/ا Wc~wَ"ALx`ZU8:%!/ ~ ^L> 16m`僦nu5'z#PNB|ͷ LMp"Ipr$!79N<{:=^[x/_kl={DwmQΫ~82? f6-W[ p_<^BG?1~\V巪ۖSQ GqN>}m6]<n'qVs}ق,+_;yWdgܷ8 U㌗ň½<!wWݕm6 2eH^}c'2Z* [X?:9wB-|ɯO.FWV9' ޒBM5Sm MH|N{0scrAFh!7.Ѥ$K>& 1紶k_A7P-qi:"L0dXۇ> &JTr $^g|/ǭ7#lH!2i" ~:h{cIAI5.Amو؞%Ͻ*tgyß#t=\>-p1?8(q'Yr|F~jϤU]Id+BiO=Y6z>h>7ht|5  g ueÖӽʗ*ƻZF|M1?j_8zpϿGg<9#p1nc %î6O`W:NFOi<xx-OuC!=`kG.~̏܁|"%:KF8[ޜ@<6y :2W-?]ebsLC?V5U04go8w?H%ce:4>At,\ئnzf3dcx4 ?|ö6cT{}s_0~G025مޖSj=/7[h'#]/ wYWT:ܧξ82yD3W_l_~ٕGmGے/k+/~6px4Y|X0_?͉}+"{FtXOr} 8ﮏ}ne]X[MGdb2Dkgj] =j™7ymn#&a˵eؗ6Wpn`< Kzyi1M6W2|&Y: ܮٯM)3=M틻BhM1/: }kLx>ƶkZm&wboW#'rd?C@8(\J UxzGQv(gpR_؄4<ɵ{o}h|Isw еXxM o/tKw>: ˷Q)qE΅-l_tf{9:XDP]F{lEe|t$M[P~c˩5#A+N6pxS|-?B;LlOn xAa9td ~=ZC>|g2Omw17X2&}p p,Y8x-oֆOL=#ƞ&w?uqxux?Yܧ M~ߜ/ҹņ?vjzw #zl:׌٣br0x?c2 Y 䀍QN[}dW:c' @:a`DgOx^0ӑE|2c=?D3$yCw>}ǾTF y9N5l6E}IlX?y$NpM849N >~=q8G wvA3'3p7?1`tN2BNɩlX% <r tN9 ͈[鄰"pV+7y XVst Ne+Û+ VɄhy&yoŹhxm^ʘΦ+s gWuJ=)JG-ov_6l6^ ^>lp10t2vP=!~ssM87[lO*?1$_F_E,W=[N-K&x*|rNP;B϶ 6vle8";hg [X 78n2=ә#~(yn9>eGN/~v^;ɃOPn4=ЩxtY_*  a9?↼=y|SR/<˵ŚXW~6ٷu/^ \]_kֱw5dM_0n?Zag],0L͏s1#"#pًc^7wJt6ùVn3b ^xO|ջs>+cs#dzar`z/KMMP`L7< zb 2p3=,?^lN_-"87d I IDAT{If4>62үύgߩS6 ypN?QO8(*LnheWpr?u[Y,]_mˉWl]^r _ɠq|>~*'m}q\Y~˳tފeCɋg6N*ǾlhlFgx"V&(TQ,MÕOCv8z'Kt_̿x5!{p2?"=s3}${y{/T=:ma__鸺\re WvMS:Vd ''l׿^i6Z6tItPyrW9|X_`-|l ՘znoqlql͞'ɟc1weqd|᥃ 'r5>U>_~}|o{K| .L%a\%vZ e]$r<5k q&[)?~`:-l7ϏNGxGӿ*mʛ=ZxϼWL%-CrG~^lX:M89 apGO uѠ{DX>2 MipП`%lGVNN3ɱO60 y9]c 9]WD[ٕ`Mچ/_y88 K_pnSxvo:qx2ЁCV-<;mAV@=rU経g^kfz }x 9' 6هbk-v2Z7LG;po_aj$C|G >q[AT@Jytlq,!Y Sm'J;~mO#MFrY0lQm~|\|EO b(z˩` Э>{o卯 <~֦Cozth S t>w0GiҜ%+9>m@7(CVp⡵Erm!xTA{\Uo;ݱ P6?G"Yk4-mC}T1Bu ?ٳsW~0zbzxۜHt=aH;{'Iܘ}.O`ϓoN 4GZ<~@V!c@+V6^aS .۽ A8kP6MDͮG}6H:XFwƊ o<ɹO,#^xr2]~>?O3菞 ps66Ŝ0hMyx1Є&8Eh/A+yzo>:lKkLG*.ݭ5]t-|eϟUX@3SgFlEo?h{3D j쳗= ٫M6P'~6v^ߡz^d*9.c{燋 ]zK/b [,ug#{z{}#iM\GxWjЂ6okq`tAn.1 0tm#mLt?I1`[?CIq ;y9ϧ[8qAfhde}ar=l s[e4>|d<1Pd~ۊ?މRO6xL~/3^٩>G;|,W} b0Q*nלc5X@&Џ iS4Ϗ`'U82t~/zn]^ @`*{&>(W?>n}{L Nn[|qU qݟx]чV(6_Ǿٱ:=vۜ#ߣ7I|SrV0U :7ZLGlO徽AW9`ziAOK^/h>蒡d:zg FV8?'۫㠿6: f}|Yc{ l3^#q_) o|h䢓]Ӂ&k Ž]?ҲNt;l +Vm8Gp%xZڊ=mL(|;p=ItA[1vzw^<;72!Ք*+10|vD_0?S ϲmxY6r/l M3m7V 89WGNplW-Zҙwqlb> ^9$1O#%F#gWvλ7vVJ5 #@6o~xU),s|Kbx:mϺJ?wULίl0U1RM+>cx0x؝ +Cs`s>6ܙ_g6A5ޗQ&of-"[Wm|b:`{Z#>6(*{x&n\E I淬 ,0}m2}mi^ɮ݊?]Gcә_>/}%^|)Gq2PcGlVErK?fV䔣\&;]ug󥣟0>ԠV04E4J>G Q p%FA,'m3ḺpY0͘FmFy}N"QiBz9j6[ &/i^S7;G䮓D ڍ4u&BcCp:%\q{&*$A:uZh5N?Ѹ]t4*_cx|>T@25[gM{N=2{Qq珻=܆-_wp`{j|}| S #MYdϻB}x R\K{ R2x4&K8Щ_?/}99<>ux#a-<84}?/#n'K2RK`tS:>0ٟMDLOkD9 E<=ޡkSnt11oNL'b?[8Mۧ#&_Jgˏ*iKgKPx"~dq'W>Y#]Nj#|sû0658?p[b Ȱ l6>|xt=Z7Yq^؞'<\!w-붰W5S˩`ز_zXtma'{ d˧cX,隟ȯ^[]4 Ny/gYƙ_XBi+ '?iA;E3V sh̼ ,nW!·9wN1 T6ڇ<0v >YcuhLgk0@K2Gj[ ݐUQ~t4^Zkz`nÊtno -{v>?ߎqtUgar2Dch?Ue AwM ǛT#'!ni#X3٧=r_6*2>>k!I,pH|7!GOG[1axO?8jM h۳C /oD_??SO˩|Zm6]-ߊ;{f)|gOvKKo{WZS*狭8~·<97_G;ω‡~|wP d6v OlAf:&|۾G YN& lio@_^{mϟ~xo>{y !1H90vN69$V 86BHv֋ڮM=t^A-KN[xr9pY0=.ewیd`;ږòo1B3\vSτv6~(` 6MZ0wM_z2"7X)_>>3Ͻ|okcTb>)jr(7 {]lU%񁗴wrt8y1T|Nn2 [h5+gPٛwyI@v^5ŕ]i4ó?ԅ׆#+'ҍIg']Nw8&Šj_gWrynFSs1:=o#Srﮯ+mN>G/i>Vx|~b/-&Y=!8% /'a^mxwv@[$鴸M݉2}x>j! rQP=ɳQ{%剛=fߴu@Hҏ?/_z q§<fmAm9 _m(U̵ >\ tSG#y)? KڟQ.@ ]ޱyZqnv䬟9=:8CnArJEks߲Z-&g 6+!(Q$ 4VrAKڎ:`Oj%t>~ļ[tTp_&9 ; t'NǏ\&qVq%m,' k ڄ'.83%S 1~ś~202Zmzp,ݻ*ZhABooNNifW_;5WJ n/·tO5Mu;0&돽HNT~g&[U>4mg  /&-XcWW=>Y]29.>nĢy#y(![ܣG6bP#-eWRow߳ o1{ǖ/ JwW-{D A-N_hlW<51q}v93J㛬M[L6aJ1`}-5= w.`wFCcu#MW-*0|OΞDDŽgohWmщ+~r] ;锭-$ӵQ/Dnu;(|nt/5ͯ7۝2~jAw/=ymK>J'l~S9-,qwițb8$;|axK5X p{3wV |^<@ IDAT7Dp:?ɿ+c]m4_%\eFHjO?R9{u&07|SӦfmFOcWgˋ'-G,`qA LRܿ_w}ɠGkWٵvb}[8/Ab]~̇RѴuLyR2| _˟>'%;=?g ϻc„wjA= OBx~-sw 佟Ht>vOL]M盘f6~Cy9k8pA6λ% x]mhbbb+~V>9\_#@{8?Gov12ޝZi f 3gɃUm%/n{ h"$ZOLt达}~5_rgd_#_to98*gU?c79nEO~/x$':!ఉ}Q &[Dp YUwCvg; y F, *p *97 ;F1&KJܕ,k(jL%ah>cD|ǃ?ǰ|>gѵ1$y8a'M9>ɴV|Czxf 1W]s 3`]oVQ{JpD_S7UF0r?ptcC2hD\U;t-]!u_v;nN;%GFoL-~lP?\;\qx| 0\͠/E|x4@/ltvLDʕEuKnӁ^<ڏhJ.,>x}[|U25> Y;Yj?<7ۍFyXMoH|i rޚz/~?h?|B:W|xt'Fɻ;~xQ>QOyd h#\ڐC3ڝ:E4nmq POOz.c'U,*;@P,?]ly~RsW7Dt/'/?y&ʒm$Uѭm7n+߷8xl0t5БjE}~٣{zNWӏA6.Zw}϶`h|ޕ_#hLwŲJFw')?ݣ_;1ktOj>1Rho ab.fN/Et (A+7}]Kϳɳ{@2)YlExGr:No?K.s*3mq>)tr15os. |%:lW2.?=E ^>Fd,3xmvt3^ m E(dx/Yܓq%쾹`15ԗL?m":]$-xۋﻵ]9`;~ceKroB;r|X|?tr>H#3^4;Ϣ\ B~:8# Ht}Ɩ'sv]D{gn[eIokږ{A̰e{`<_>{hDsx ›*YOQO|$˕-ntOS?#9hhv6dw6oGkx|`JLg6dGt6Ct2x`n+W.Zy pOق=\bq4[ѝXvCcg}Ѡ#/Y]셁/K:8 ,/>_o:ݖj߸`:*.I&ӅW7~1lDɯΧ|@н- }&wCMͳ /oVte5>ztluy> ~ZgdyrC`ɤ?fm@d ˣMр~d*]چfeOpܞ ȏ: 2#\SD(w5Өᱠq6o3c>^ϣG"6=q KtnOX !|${tYhJaz&cwFeCt'0۳agI2ݷ 6|x>rP3C>| H>*{\ir-(/RWfM+g!Esyr6/}3̰w-x?<юc}S&9,zzCl+Fz p޲!4v:pr\mЃ1@\W,jj$Ƣ9vUb-]Ep `6/U,W? >f7ִ?Ki u.3?*oLW/da@Yxxty>Ƿ&(&mQQ9{E+N^/ψ}-Wʁ?41^mEƛD+cx&>nqO79ܷᔏVr?#zۣIJNdz{?E4丱xxk Rp)Ó6磓܂|{;)>N"wѱ}q ˃]pc p{n,0cw}Y@6G+XǸJCD{Fc+5: ;Acq S)δm9gUβh,9OVvIf/ ~R.\-8q%P6p&ijgag:)9OЕhC]!迲 < ]B E/y)׾DIi sRz}:> vBxҔܠ׀%ᢣ$T9m9iWj[ ,`щ^4:xBG&} lHH1&qr |{Nֆ/ Ux|b|S=cr8:A|]<~jsSx3?-KOHlB64ח_>A~/ڂB$xm.n ۤKZ|=hMȕx xW)X7??ڳ tEdݣ~/&nq˄jx|b>EƎ7Y#$x/=p .M^ͯ?q ^.4xu6rl-4?nvy+yk_گ} fv`2?) Mr>C?k;zE:(3 ~u6zƜxn;Fbt׏2rXIi ѶY;<<.O7o*Xʍ!.X?E2mR>xeC~vx@-ߵO րo]k[Aֽ\ >~s0&ra#y:G\LڳQ8=8?3hW|xCO^hv:pB|r L:ͦ/y_p=%ܤrtUx0N⯅m|5}^3TB'N{ڱw~$gIzчCKX3¸u8"qv `׆v!H hAT`k08wbPO9/ПK&yصmh^qxׁ96؏< %X&:pR8 Ws@49IP+{4oXNLW\]+ܬv=5yp~LjD7y >$}/*Qӑ^2/mD5G*{Id7]+3>' _oοeAw6Dkk͗ged%'>|?e/׮mx3 OT7"Ȼ[,%ڏ :آ"&锋݋GŧˤC)hTL~mC]T~qlrф6|tn~TQ 1:v~cO_xs pGgóЅl~o-W~կe"ǧ6_-}TTafMhV=S &p?Ldx.9^^N.޴3M.{xt09d:99*ooR&7!#Ԭͮdx kw/& 'Ӈ6JoRs]"~ւɇeg/.,=WLJA,ug1Y,|b?{k! L?*vBߝ F;&f/6O =j/?ߛMoa~߃N? &kO?x&}?c0P;:Gr&/w|C}j3w' vdnUk~ Xk'-w&{srb;(y[kV}^n gCCrU[|Ǫ;^_rTm^a.F ZV|<'XAPWe8}aϠu)YK ~D/8< Cz@3#1nO> kUr SeZp s^! q 2EGxޅ `5S^l[Eu!_u:K_Ar`ޮ>u± q1o/9t:z5Ngi+^Ea#t=| *:;'}c4L2A;GcJv ~^7{qG/E_|Lx|ի8SAFfpOº^ w|?# O_?7܌'87gK{x?@|hϗAOMh;`eNLh V|mEWNG0ڊtӧ?~5Mtv;>1ĵ #S+u.+OF3|wRBGb+?5 txXve,ڕ3b7|rbw,w%o|mo}7(u=_ xf1Y`-lଶP6X@`w8?C؏wD.9sWN92 GV'Z(Ň7: AC/6t4E ͎\mŏ wv_|=DMk׶8AKZ$,茟+3nIɟ2+&:`uWNGnm.w27¹/KquF)([ RVNʆQkjb\ x NlK<ѯb5f- #:ld.WL1Y>Z,_wD&]kOPZ~ⲍ<|pbD˓?R}6;h7F?co+"oh >/N /}wۮZPv|rhɏ;|n}vE샿=-l(>ugџ#֏ 6-'X ~y';]siMk;\nЪO?>&}c6q!32?Ud&nx}uU_H'A Y{m~`\z]O#|/د~^7yns켼kb+sɊ%}9}0p%evZ<2?[orIybe^+IfK>=zke>~B(¯m_0zڝ;kN.^gFKC\fgOxl1~UGEBy{wiοy}CtȰ^6NW}Qp_VccOVxgMGM75Ȁ/k rVvw)PTXo(/n`^xʦ!6+G7)7CybX+u%ބ' XΝq*&6$=>?MDRv%+<;p"bYϹ*6+2M!%HhOu\p= 8-vwEpz#~2MNzǿ wezqlKL6`":b䋗 3K2OlFΖ[I36l <)W5?l/Q'){ Bl@rʼn/>1XN.h۽^1Z/ З+zh 鰼t9F1m{y4Yb-Џ-~2Q7>Cng#Ѣyc#cJ1[/C1}j.ʒoLcNr8)[Xt|<ѽ>9B?;jed'B1#G`=9*=)p펽C|B~<O~Khڃ? zGiXKb,q2&%!UV]ToU"ơ.}V#CD{BLGvS:O5D.kvjTsėMz|Rf͜)uOEdbx,6Lz!Y/(3h;5e$/Cr W $|@dӷ18hbqё<4!(|U?X2 `m||<[?gQd~~.|6  MP>ulQpD7pWDJEљ!c*{,,5~nCn[il$ W,Mg9! *l|Gx>b[,4yۖ(%uDx˄z{h[dc~ooOfmE *~q8kd`k4ΓO n u;xvwKn0[b2mi䅗 7(Fs LXL'NKw-ͦ\ u89; Vy2]hx^46WN8^u*LJ_l $7heR= k_`J:D4~ ??{gʟ2X'ZھS@t}MAn5m1 6>ah/oы7G&gk޴Dž|Nbv'*=-Jn:؟Ĝ/|MbA^*vo8MG,5l#bVw/<.^BJNq/w6ޤL|&>h]sIg\hcoBnrl vC֖F6*ٿs'Unv6@mW}h!~]mvs9X{,Xʸ/ג )? m[nXkmeqw>& x٠<.O? BY;hViH 8Pj7pd]z ,d[W Mh|՗3&;Ͽ^x݆ mE#\ pp6<(k+m|s؀\׿糰v~Əɨ3ȦU7:b?OxLʳAʝ҇XNYW7'i;vmT^UgHϿp66xD0vix1:l!ULɈL:Br-޵?2U tx_r=z|tFŵ+&v/yɦl_& ,ώ9`CǻxSx7X>ڳ]ѕ;Uq?Gө򙍾ń;+_x#/Hi};ᅵ\ |OnocK S?O{≏iW?:]JGrC,'}~ﱸR& :vvptuοmx ݓsCBp,,kNG*c[t4h~;x=62pAX׎گ~6$XTٶ“\} d7iaj ^yefym+a6S'_="ϻ33ڏ8w?:`:k]{&hM^a6[;s%՝)7>ςB.o8vmk{ >cF=@_5`ϕ2#68c\ղٰ:6c |kK vk;L$!};&hlrNǛM9W_p&`J71Lu_݅;qxIv~kCehL=# dو6hMO=n(F귿`w_=@?:B G,D4> pg8Ʋ4{<7[A)}6;^M|1MT ]-<6ĕ qo?b.zSўņx {$x%+}4?9]{uW19H|Tmc&X˫mc1>3Ϧ|. Y`6}k T'7Wߴ #;sU,.XƳQRl&VAow2*+{U^[Pba\G#ھ`ْ.R*&Fi{dm8->_Ha@14P[Xup :Q|2Xh)#8eJp1p2<B13se6O< QfĪG 7dXFF[勮J/Hy 6mɜ Ę 9r}Ohz|C7r|D4Or=6ic?uh?elcMMzM}m#Tx2?_w@շF^Ox텐ɑn:NO/½3Ѧ>?cZ{=LLyug32Wͧ<ۭË-qLpШx[~̕[MΌBAۇ%w HIŬM; .㇨c<[u0l:T>>1Zф߉亸ǯPv~q`7_or=xڜO4ѪLQ[|?ݱd[sck!]̜d;u1$>ؤ ^dw}IS5=廲ڂ2~'/[r1Ц_8r*TzO[ˮmᱫQ~Ye&϶Yy6m [i`2b s96~M,ծeo\N ]g V V+0_z1ʹB1q?*7e&Op?w5 -y0}ŇƇlX[s{vWr3?p/F?Y^/i/_j9e@}rtDkOX}}Jtw?}΍}|q$?P0[2^:v_^&|]^^ !Y/`#jn7['{rţӇM_x0&Vm*=|gOz)F]4~g1\ qcO|ۏ/ho/Fe?-ik?v;i&柈ǣ6F/f*۶Yx[rѧm&&{$8b5// 3ێȣGGݫkd2!Cq CąӇT,wqC7th!T,F.u.F_nD1IlM|[erFm7y}vf~8d6';|hXw%maI0|4=j`o[O.?GN%{W=YV݀Xթ< #R 2=ضk4Gm?7fLbM!%_#;>-+uvHqIfMaf"7$t Ρ@W1h dpՍCk3 z2-uphlUٖ8G3Kz*&V >=Nno"=">7;)<av%s `m_@);:e) 7KQ皌WOǘ+vAT:<,||_$*y&x*Hgۊ|*n?rR6=p%xg#~+xhNWuʍY pTuSN ؋o jhnP%j;+[O٢WuR8A@_4sDe >{OR2VlTИ^7>G]k[No1iƩ=NhWx4-h2NXGK=U 3r[#1+|-n$8s&XxU~b|ً\4Q]pdɶ.4V|lP?{^$Gh=#?6/v6-]7r1G/zJ:s>=ccBlΛ ]GlztF'9VH7>~p)O&ɽwQ/]!N^d={P""OkbryAN1ős6|&ϯN$SG3> f|Rr s9=Yĉ8Hِ*?YM0ku&Qq~CnzӟWKئb6}QW7^?g/6¯&n>VMo2#G_.o%@6Pn?{ny IDATl(LO:,gvUu6ܘw9H r\[vN|q0DbMFw'Unp Y+K*vl˫-%^_O<'ygB63]gEZSl~_x,^/F\'eh'g\3>_ϟIblrMiCkVtU];,f'~|uSl}gH1I/ZdFޟZ؋2nEFqSo11RU؈np8n&f- upy/Qd5 4_B[#pO0+7EZ73np×lx%iAQ ~9\9mxMG70t)(Z5|+VMƕ  ؈-}=sv }\,MNȞ O'm{,]و _;W}PnVyxk0$:Zgʖp~B6+`jBSLlx[];y4وbmo<yO ?/@õC-/ؕ3|$|r|ElczG}[ Ožyb^ S_|pWFяޫߋY0T#דh>z 䜽NME0| *Vb콶:|p&:siG90Y,2*^&Ok9:G/ mmmZUw~~#d?Eڽ~Ȝz?t"&&{}_#寶ߨSEml_;@6ڭMBTFb>MP~ 2~{d$I?IJlb>b_x̟*n๊d^c2Cl?=3}⒬Jmwٖ+ tYŢ7=øGH|'[zb?Urts\ ෻"bByƋvlo#X&՞\_;iWTy$G.ЙD-Sl+cD!gxm4{w%Nh\mӃ8 p?ֿJpXJ&L]_]+Őor.*,o;xׂGQ"k_{Y>?;JצikO`cI+`)]ql4uc[ q` DZ=9bUA+ӎ eao3QvO F{7)l`K+w4>P n얣m.^ws>Jdž 3 ?ϯˏCvr;'.hv,6ػv.hnNɾ[S=_ر$Y E8h.&篟D?}&gmޫpwXweꊋ0d*loQF60-GMzNhڃ0踼Ӊ`8rwrmw4ѺEo{0wƳUONuqp[eВ;OPe- {Rˢ{l,{ʟzy ߀J06f0D D5ѡm:jOg ^|QmeKymcܑ=feNoO[yhC=/i|x.7zC/[eo~~ olp{X聟[r6M9rv3&s`o/:fHxgJX"d've|{Wl l})B~ӉPvIF4~(FTC?/zEov$gلm6;p_6REoqb;ɂOMNp{g_o1 Hn7w3O#Ľc&$(aNzS'$Nx^< ?i d>Z;~3}> я{;4{'l;,@&k+\<K M.(й2'&av%Yrcmk g?r| _Y1zƇ?.}&5n0狤KOG:lkG|-`7{ uP[lܝK&x>.`r ɷcӞkpr .Vv78WgO_3w5읍Vїt3}B;?#v{b+y-wrg{ٶwǝџ~dX Vv:;8vd~x hG΄\kG/dfֆwr+^N'ʯ.#C9woe.=A-fЯV己'ɱ;r>lC[| M9+<4ߑ#XBpGzܪ.>N$ڎnzÍyMZO vُ{alGxUr9`rЉbsyu:U\p?q`g[#e:~2*Ud1lƢG@}m7q4sO<$)z /=:h)˿(>lX/$C/՞l\9AЀɿ>&b%(6oUQ}tr ;˂Ԃ qm^yybEg`ΰ?nD (5(7u~/=!#8G1 &V`΃Ё7Ѹ F/:̜4y5=E.m`NyF;MkpK-~Oj,. [/}/tL[|v?]+}w h3H~!CVA?NKIxR6O^v}|h7?9S mFg~FA0oc$Jxwu G2㥭u%r0'VSp&3G )KXhKjwhOw&47^>}ЁgPs_%C4޶:>l@{2-4қ T ~̆+FrMQ1Bw\FDŽD:)y/>Y{>gMg{2%s6of^8wשbFjUlQтJ1Π o_x LB~MDhROnq-.~r5Zr>8K8O#'C-;Vg]u%/bt6SvP8hI|{,GmlS΄R#yVx:SQ*0a <hsW\Fsǵ#೸.]죽[ࣇgbIslp8H|3J=&]n&jwO5xS8H􌴺%k;l6˿  ';;[QRhŇ.Րw>[a6l_{>Y_J٭:8㛯??s 4kK&z?79}d?;<=}zq6 gz~&kv" юNџ}o{Gȴa6c Og<ưMK1짍}ә O&!MExe6TcٽB*[KcGsxLfew0g;3OH$Ɩg{9.d?1.m)Vfᣞ ?}sK:E/-F!\w9d܆)$FxC|Fɱ[rDne/GS{n˫MGř]/=wxeJg'\Y?|Ӌ4~`O(E-v'S_,ԭLpq4JLto"tc8&+krY_S $i$$O7 $> 2kjLy ;%b8D8y}lK,3ڑgA,菇|uo:} t ~ 9tB?Yp_'#x%mVJf_}]틇Nc <=_=ʢO}OYdNU6Jd%dW\>޲J _vǗB=Doa<µ 2+Z>14l?ouM䘎U1yŢ$;#A6:l m/ q9Ƴ-yd tnteUhtƃUb|182Nd\'(b~gG{-ٴdTl|v*MJق} 0uí~cőXŕ7.N_ty_u68Bc{%6a$ '=]6{597ّ HY+93لg:>& CՅwp LCuӱ&R\\N "K+|t־I-__N[;`Y3򼗉ʧ{EV@lbr\Nܩvrmȝ|BQ_=7[m#f#|6٠Vε]-Jo"O~PA_gõr y -l4= kkSj_]_;&I }1GVaKNfn#ĝxi{G64]{c]/ru{\m{jCM@,_k ا'nr򅷅% }b'q@ t>lOh>|'Lo?w&$YKe6Eo[bGF guGfjl{B>WY\jm@o7mQF ?د{ŷMMr6l0Fmcp?gѡȋuGh+V$cOs@нp^t~c=vZkVc챌|myxzdј;*Iog_!txgg}kl}yt. )D;c/ΪnJ  ʏzu`o8́d8+wuw+ 4pr?6v#h@x#~|dqsܩ? ga2_.eW'NtZڇ} "*W] y?z۪$ WaS"lo&AӖ Me|_ﱂAzbw>wgMqK}ُُl*٠<|4G3 ѢGEr~Ecj/a6Jo5699d[}6 ;FHU:qIOz{< ̣KsYǫh\zdx>\1 ţXycXOhu % ۍ%3b攣v `~G4fg}i;xhK)o@h<5M/"wTvҠa6UsW"^2 GNdv.g;<} ~Jqtz㓍ȌdflWۉl_{SJt1s2yYHlA |b~paM` `7.ǶbvrЅɽ.g1Iz(őA 7X ,np}bB 7W3[`xxdoZo}zXcw1F yn 6v- dĎ?,b'g]c Wٷ- lY{~}|>R n3zA ,o;o$۷L ~e0yߡ|!nwG{\ǯ]{쁎rgS~؈Onٿ*'<o_ 6z͎-]65tep\SUr׃wqLr?_>8I>]vN:SrgW.W>{+<[gW&o֎(qv,o8_wglUn2+t~ttv48(OoOM&bt+>߄a6ncCy: AY<(v;z-;`/^u7I\8Bܷ.u>4]}"cGezL`|z/.D8`%ؕm'-PnB4ö]G;:~zƏwL݅+'c\G[]X"lv9V; IDATWvnQg:; KB;:r䟌g z: !梥v.Ƈtb!Z(Y^g1X9l,ut_K);_b=ox8/w\[!8g.Hۘxb/C?ovR@;Rj"'ƄBUҌVrX+ſSM A Lvi_|ƠdFvf+=JYx% ,A팷D{sYld[47Á7e%N9~h} yf6 %fgh j`{9[kTLGFҗn:DIkv~R6V'_Эr; p )' }3y/I'4:9GߢcI3Z cIyp G`m ٷyV?]2m2Ջ~+{iwGk>B&+{3hv'bڽnvA߫cDm?{hg#o~IQ|#rۆu VI_wgvO|ϖt{mH.61nO pqt-wGL% w9[mqIt M&keyr/[޿xb}G T$ۿ_~;ĢNZqD;˹aGݠu6Wt޼eѹcGA@mtyqCdʥ`FtWW_"\'<7ADьk~)abǝ&b#xL0GB@?]ۢ|$oy3 {+46Yeቝ|2yeI qО-؞ky<:`Wh(?>ډ\ >n}T2O0,G'Veϗ%>4fs78Ont͋d ImWƾauޣrlD?1B!dur_ > ljA]~7~ A}fbӗ3鮺.ه` k&Ke{t>X$g{󎫙'S2b}ʾ8b|фNɐSpL`XĐ# |e#]_ͯyA+ P65nS|HV_Ǟϳh ǓdN ;Pן>o[ l0; lrYAgW?NО{퉜]x$.!g@E >dJ矋.}b\XjoяV25;'3kv<=*vN]WɲA' Q,~.=9ݎhLd&ɾ9_%]{[JʐB2T3ȹҭh/ k)0c6V8;{h:^5[7?nm|n2S]TimeӡWǪғ'd;vXwN A4VPSV.;,a8bV6-!D涣,Lk w|itk}K q%MvC&Udu!oaƴ@-`CQ8'6|c\k0l.N/aLfGCsG'<6gp|)) V6+oJ 4W 1M,~ȿF - `zt?ޒt#Ol[wSbL#+!g2l#>ANkk}+8!m w\߮Rk?G6<; ctASe3e~ n`eb!o, DE[~Ԗ0A'IFg $l?->,EmJ)t[{Sx,bNNɦ  luM`\W~0\xh/][oJ:fm2ة7pϪv񟝈h&\N-<Uv0Ν\c U;&8?zorzr?r=,֦5<0}8Ο&.6AF~GHyAGxQ,/7h']60l?s~Gzxy}]Yǿ_e 4`֦ӳrwf6Qf}}YOBz fqsWO'v?)rf#%_I}zN<)# Mf# t☣{vg/ٝFʵ@'ǿVqs]5pm>m,WkCgcx`]-[ܲgrmY_#ؘc}b&m#|."HV[xMg?Cs>}ݕݾ]nmm?\1+?]{WZ*g1-?돃YLhW{<>{2I}=n=m"QW}nRcDO }LBr]%9ݦ u` Qnt<`ȃmF_-Xm6N^/ALK6wN0@6}=:*v~Qw 쒜''<10&"RҜxNx\&\>xGw"#.9:_sYO~2 ;џ7s :dr&"LN o[GWcI'_dCll>"pLĂKhV4{&-_zln.MW,z&1K om9n{W}+VK'p>r0wtGk\Jh./^}gї;`㻿"K]^{Lo?6dvnt5>_a{ytz-^s4\[}GwJerɆQz \yh߷]>oDΑI0S=&gWt,9M΋ټ>[0݂|L⪦FN[_1Lb~>p'A~E`xxdQ(|c[}['d(> zM-V@h]};g7u6\C[*ӟlZW]߹->{vNJIO {d^{qU}6ڣny›(6^GȢѪh,W'5:NT}D psHj:S2>YEԶEnm:C/А+7iJ~gO|n XwS{گ'`ޣΏ}G-/OJclHwrD\tCB[vGM lV]m=:-"շK4i.g'99͆v8 G_y`jtp|+_ eO&agdf'>g[xO"<#OKƁ _06ꗾmv%7^ @uWOaÓv3T9 G9E%ۈh/2JuunsW_ 6kĂbN&x^xQ=Y8:PNxK}ZRտNJ7S,t\ 삔P$V}8HLju9;M8%y`NF9'⵫};λĞ6|XP|N|F =n`x&lE kp͞='CI+@Vz &? Zg#Џ*.!-Sޫ1Š~:~`>+FC8x/\\6VO ڏ?kG>(-(2%Fvv%j H,O>vEg4{vUgiGKޫqo:Nҹ}1Zͭ/gN֞LWoңzN,_\m=8o&Qry9 7٢N)Pp$?`bP9Qyؠ Z-P_onPHg?Y @t|H{%.?<̕:Ob-t}Å|i|zf|%ͯ~P :A}ʇ^/~Oo Ș2U4uI]E3:PXߌ]H8|X\Fևɗ錷ҶY,:_e/>ql4&Ɉ pŒ6A$|(A,v{,RubN{0p/:ⷿ;9-svk#3axW;VLܝoq|PnQ?.Nsr5#71tdctB_}[tڤ샃4;8PLv+C_ >nV.Q勻H8^oxӍ:~W-dNN ˤ䩺↫[ѧo۞ş~[^zW~ _. f>e ^[& :Ӌ]\ŌM՗of]_1Dÿ݅Ԣ]ՏuM‰8:؞~7G&t%h/nxm&؏o ,&U=YB>l9bby.OT8[t||)<[i6}7Q+ ٮ8;}d~vvj?|Qg7=lDv(w/ߠ]m\ov>yqɝALآ} ˑ;?mɛgm#prؘ tvDda'x7{~#܎ jO'c[:b۶K b Gيx΁^ahɀ!Xj jOƒuNO1Ӊu:roe" ^O#_ E 6@m,T/, /kPU7!` tV| y5N ny~hV1fCy`#8k4`U\^rF'L/c)f8>bјN ޗ;MM~c33Y~M8yчR̴'C輟yյE(ItӣSh{+N"L.:/w<%;ZZҾ[BQvx7c1003dxLLۏ{w;ٴO'rsnsHdvE /mBĸ6N&ap WS ^ u:n7ZlDن`F煎.&{oP~$fdtkeQY{ ЍF]g-?w\ٰtNwXTew#Mz]j9{W?_8̎/2l_{A%X,h]}k!ikwOw)]A7s'tUp?|eX6|`xh!'Y8ۄO Y?zܲYQ_ä6|/$++޿| .`u2 uvlwO~>=¹\[Y#G<=?=w#|(Eޫ_4&-ŕg_ߋ@÷u>R{ ) '.}|Ćhqί<#kݾC/;f/Ug4)^Կ98x!.oSdy!?r2[|܂M ^a=&G6`3H-tm刄ɹ}uE-Whv/ε/_ Fgk+62?r?P:b#U>dD0dUne`O4Oa~8 $ 'G9+c/6@{ ^ {c3bodO뿎8csV-P? a|0Re%w2$kL^r.#Ud m9$!pcD%pȹgľ_A IDAT?}ɿ Ne=$xaV4CLrYMh2LI{dSbgώd rr8ǣp3he5tw@n=3rx? 5#P=Ag1\Nѝlw10W$Ҝ_>$'F S:|ǶcBEb:B{|8n0q{:M =6zT}+|U7 [|OӇ=M`m⢃??֮>8b1l f^kdh恁 :~џ2U|0ztxE`Myz|pzG 7w+M(G|N;5 0?@;9] f4[r.`3{+#/deW~h{1az8싯5Qmѷ(3NxpRx;m:‚lد'_J~7y)T ^q;d(Eml]wkxmrwp_:mkc'f6ad'1<+b1d~r'yL!^r4h/gvņ3p/7q !''G7a~ >%W`ļa,o̦b h}-`QDf'v-ţ,6'ip5<.\㾐6d2-'L'wu& A%WvMԪۤV5Zth=O>uF%_`HG)GoNNE'g1t*{~~lr? &kxc[z,hYwDO2iߛ1<9Us>;kW,&YSjf!l$nl,|dا;l2o}s6V^WU6Yxd(f-]"gc/U-ْ|Cջ"`Gק}|* >E_Xuq6Ktce/ޖ/uSS 'Î}l ?v]6{rS?ZGCbj> ZDe|Pa'~}%ᄕqf AE̱O/WMwԿ|X9$}~AqsZNp8n۷g0xJO@܆ClZes^ \2:P~h<C+ӓN +]ОhFr,Q fEhhl6hI0oO" q&sv߻n?';䂸՛='/sK[卙5Vg1P^n2Iqt*$k9ZoС'm~dk yY#D6)6t륙L`?ud:)GӮn.Wp8>lM Ԧ>#Zqmmc#W|~ w,.%brlwՄw&9:IF"ͮ+Wg$&?~|BƵ{@ƇL,}2HYVo{qɞH/?$hOEyX"~yq]Gdq,J!3Gn{mhg{E>O܎)=xB˽ASsAϻNi'hg"s<26VRBbIʹ vYXޖ#2K'~hm0U>4-Ҧp8:+\;<4'g'_ JND&OF=8`ea6"{qp*aЧ&;+yo6 ږ|[Hy|}YUt/ٵÊiv׮aO|6ɕ|-O\(?Y h9o$x/O82t49F_3-h8,crrz2v-̈#Wie"4|#&`oPM.Gdh_86W2 [؞/Tri#؎lo9 ?c| olw ,Uyt''6]:B%.0'|͘RGO$بl/].w~߄n㓳置?!a  ;H̛r >?_6+uQWL,Il~>_}&:.&5?}1}3OC](Xݢx d2wSZ1_x@>#Վ]=?6˿iBG6XVwgL6HmHyt\Rfρ@̝7.Y/V s=ٕ>|@rӫd=O,tI` =; :]{y[Y>NtH+7! _ÁOnR3!z ژ2tg3P.[)fU6 Hbkg7~qP윐:3:$fZ)SݿYӭ QFE'Tw~_,(/?+Yd<&>hȧ~4H{?Ko Am셮(gƖl1m:O6*6_LގGhCgz౅x> c ؊~[5lл%.2#_O7O&3l$AdO^jb[hH'o` ߷pY38_ >41f#q3|uɝ_(k΀x&~Fsq6j?q'M$G@LDeU!8ל6)PP\p SuVU@ u&w35US37NЁܩO.Lj/>l}r6b9A<;Q^ىڧ_{ b(mœ'nggڢMb3K.l;[$slkJ}7yDC;Azgy]mNd[F1Uػ皈OJ(n~F+O}Wvm;oc\|$n[|TutԯnL]_bqC~̧o$S~c+xsd%Unҥ4X;8Bo ׏~_~3go}q+ۆg .or?'Ô0beX?&Ct\VwrON Nǧ/Y+Fezt9GBZ/{7$;,_ߋ{n1 kXp>UѶ"n`D0h_|.4_FF+L G?_OE³M#ƞ)|'r\Rt wN@Fz wc}b\gtN'қ?d8> i.Yg=Af Rϒ#;yT>l)W;~+߄:? K/:<|uU}h54&([0OAy'yѓ>92|շ]>-x)ל='~3ml6f#M@IL-Nv;5] "9F݅bR|峾g ۻ:6%V۽~@\w?u#>ɷOl,>#'x'[}a1<|hqN3&53y XQg_|_o NEN&0u˟xokcQŢ;}/<X6߷23jm}1.ENXړMwGXg6pmo}=iϽTgL8uhm{W?0>\]zs,¿eE >QyN=1]j{^r[?7oFna$[ax'@zZnJwŸ9Èt V7jg۳Ю2^'Zh=^x G |t b'f{ IP۞磣]?%X˧c/{NDqa_>ͦdc葌d:e67[#ߟr7;݆YXOSh92lx i1Δz^I}ofX'zs؄w'l;6VmO|O-xfg_OC|e<`Xt\ȡgNZ}thI_T>*OlV_FK\*'t38\ا=1vlr}wYDJZ_WLS;w1__'b>З?3-ݾUI=#k c:c J>`9 " so(C7۟-NJꓳU9 ʏ %gl_a{i>}'[+IcG˜ǦƵ{0~xNM8<6h䛯?6IxgYqɖU6ܾK~mk'~U=WMJt/;>,( -E7!@k:H*7HO\aKϷO;2M6yuNuTt3,MKԬm3&ݣI,@uWwYvھ̦w葾{yݒX6'];M7ԖJQU*E\ ΕcXAo"#Mj5nL}גj9h2'{x<}e z})aoaq& |Wg 6k1^[98 .Ujxh&ٛP}9l/fo{V:U~B 7[yqx[(Iqdra셟t4'rޏnc~9i1?N`13٘ kaV:{01GhϖW?FWXSPh;EXʞ>O}N'!mLiߢ-L];޶ݙ|~M~|0bSUB~{`|v1`%V~ts7umi79[k1fK/ֳp9a-9{ ^w{xWp\ux|ݣO^>:bfo|E#rG."bAqgLse\(Fs BOv:K9^c7Жw&3   XjkYs4=U|w3|4Ĵ0V6'M՗?@KnIYv3thsNpN\H86(젿:l||v6'ϬIy?,^ U QPqF~}څٮRGq[4qI ,\"BcII&k; ,dpIA9:3EQ|agvskr:1tѮ}}ՆdםDp>/?\%z'%}R=n1O)|VEfw? IDATz>Ջ59}v<{§8܉ ؘ6=5vӛmwef}3;֧ [4tecv\LngUWd]2 };ٟ/]oSó>msODA%w5<}ey`v ;y0ݞq5Q1mp7k}Mc/_l_>Bڗ&]qw&jtO>Vy|ۈM bMιAo|=<F>L;+ׇx;]AD1Saqexe e=@ ZN &|tBl>ԮN[3>llG9X#>&cqtu!'}/vH&n\5IV>]bc|v*߽A}UAzexg:}l0~ct=ChNF 9|U}Edq"^zDw^rr979dt#R_r~qSoc(XE~_cb.fQ=yɆSa򅓅xm\슝5Tu~˟uMf.>}V^J=>0f`/ho7>tǮ|sa {ï2@J!_|d. R;:Aŭ;/e;|ق-dO8ۆQu][P 8݉f8];Ǘ1=;'T8Gx1CG./0` '7vWK}Xwo̲_~ўNrd ^l0Gr6[05Go7#)ɷr AG2Sm7Y&`^wt8>ṮʯOBpF-~g#pA6>Je06F.NH.y ]ry(cqXa2ArNΏ>^.ha]/Oկt=AK10IbcTd'ƣѡ)vm}UvPҩsp!j?2nq#٫Naf{}W&_?늴US?1{JmtIWG}'6}:mv ›rIfX*OU4%u|6яg_x J'J@epx1@S/H%Gdȩ~Idޠ57߶h& O~@g@VmSt~Cmq>տ'hcaoqE̯b/mڄvN K't^2?N:F+[|_Or.fnZt]F͏`*ҋ%?v̷;qxmӔkFqd#xMDښ0c1:@Q3tHE}E<>NeN8Ϣ=mbF%'6Pb8=$493 닰M޼FރhK`F~R-4LvF|S}zM`_59 Ư&?n c$J*xV~k|@t->nq}J X9F\.83S=N< 6VvԷ&/a \W6ӟbȇ&BLm>l}oD?gÍpZ'(cľ s}P]aM J'qήjx?Mtg '>f'3|؝@8_ҳ؇!<ɑc^jYMcmR=]?z9t7>baD=68Nϗi{9lp7 N-ݍè©~v:k~~]"}$oVĆxmz3}Ax!W^x?O]>锤'pWo#;\H6WqhWvmM"?]H{͖yƗ́PG/mZYud?lU02㿆M>.7'[,#ݢ{m?Fsg6QxIɨm7~Sg3c և k'd&ܻK>qҍ%{mt lt6'x//NWNtBJ5Obm`e3}Ywވq揸g W^H;Y Aw"f8@ D8!Ϥ$me 4 o0W6ʍu,N  kG S%:|@|炫I:tW\NH9le'ֱarmz g&(V~F7_ŋmM86wK9%sPX뿩60qb&bQ/Q:i61WɗfWvOGV83[+$=c^UǛ!Yh%$zn #&sbl1Dž/_tI/nI[<\ěɶw5)F|-$߳%!YO',}ƓK,mQ6?G^b??9Jr_Oo4s+(_o|c;^g׋>s@9&_8n]D;\j~CO_KdXag{lׯo2Ix⿅0w${wUk#O%f79#voն韬g"=]{BS־Ź/^\ԭQ2ecӃCOwӹ ٌ&vu/~nWJ;|w'-_M>1Fҍ0 b.Ċ *Invq?[ǵgl}?PU?dӗ&PP3=#Fs~gٟ=2O4mto&&p/{0wKTkL(ݾMnqf &>L<#{\ !p`̋FGUUٽ[{',0¤8n,8ks<i0tu[uWp);~xVM=66{[_K|gO i,_ a_^޷|񕅖4mS-|Ox/F@6{laߊ\ f_- a,:n5>f|0.m#ž+[/SlnIVxG%AlXs:16ɥ+I'Md`}ύ)'kwz ɽGN>~/7|y>Yr߫+mR_$Ŭܙ̈́έՀQ lpе?u>,lNͿաڢ>쁭tߧ2*k~VN^[ NuP .dVz~ؘa1z9IrC6`|Gѕ]fh̞>0Տw^rc05Ͱ~vO3Q}EPa4: 8O_ Żb|gB TbS?ÛK"π1Λˮ?Oiς1f @rSܠ4h TWSFe%n s3jFJ;HHl",_z& ڍre0rx<-X[J ][fpL&ݞ[x<z s+@[ui+JJ%mk6xCG $6}4v=7)Z.A}NT=B* V-Tl"n dN:,m=,>ʊ | PdCE6A(?*COS~8ð34K)V^v&Odگ>n[z+&0>wL+ߖ,/;%2:;:?maLݲjl&-Y ۦMыOay`kkj#T3iJ~e^zubDѬ,ܟJel^|OP})ZĽ1s/ by/'Ov}zpx>R ]8ܿ칸/:!M6d_}v{iyJ2:A+;{˙uX; vɧcAnaf\cy_]?[hóEJ9aV}` 073+_/>8Oɐ#/83,{+I Mw4N<{62?7Ɉ7[#zW>[9!˰l*Iwα?Xӗwܰ"#~JA+cVs@VJvS>VK|yhǏoO Gތ^çw`Oc&^8#ƚg/>g8E#7j0邧+NL$uvrN6ZW ?XG!涠K=YLUIt-2_1g-;ַF{7"i{xcWuL/ܘ]b;;FwXxQ?|%6Nъ?d}?l!nX~)EהAV]ÛtmqqY?!n$Chg{?SQ-:ŞX۝u`͵u}p.m66ln'3{1G<:-cWv#l4$W,QLdחr4_'iJ3\MpU!n`Rjug{(:C xqjF#pT[-/m9oum@|WGjw|#-um6Ac s r;p&IdhH#LxGK٤}ؗBn>FPr_r:`|KꗿOg|,fOLC!aRm{SK*=`oz=v'gI])6ɏ;R,eo0:yuO>D8;ɰ׷)E&vo_M+ogALm蜌þ']?wUݝν6:?itgG 鯹$}L8GfGkoKL.9><_ӫ hA%Ym~nt h'$쬎`#Z<7 ӻ;]?]&¢4-&sJLd\P<ϛ O+OG~_WTf(iGo*X_9|m{Tb[6av$^qG2wl#d*[ ;;?booKU2zbc"hѶ]?x{?r^e䉙no|̿f=/Z3x =N-ϝ\~emx@ Z1II lnX}zub*?>JWo^&uMһcL|p }ڸ;5}?+hCw~}\׷67I6_'Cl{q}a)} |FM/~޶e/,ϛZ Catxdv23 %YN_A)/8*ŏ_C]_Cg<w w,dՖT׷w*T\z8Lr*&7/X};bc#aȟmب}aMp+v7^WC͋ ~?7_tJ:N;o<뭟mt*j] KW8`2L%o+w.}/>c' .~prD09]2[m]fj{ F).5?[^n>gOny#['nxRl+ܱ*Uԙl1htx?/?=v1wTg'l' {2Ln"M' ma^cX>QX-h,_/,o|={bGZ.O:+'kbVaýpk3U[|M/O!> vB,}(+*:L&':9\Brt")yV̪R((i]X{O337)5lO=sRҊV ]6%_Q';ז uf:7G8g+Ѹ#<cB X+o6*wR>oͮz.. 7U?%5P;?N'?M>kϾgV6cm:acMV_z~]1MЇtL$ Hڶ>튯n{6 óq:<_E ^tϞcl<w8jclMB,𛝵+jv80VcǕ6lEV֗7 60zX~DZ= ?g 6z Wc_]Ot|~^}'NnyqAg IDATq~{$τU? bVH6o8_G:lrAq:ϝtS3toկ?j<1W|/N0ONTscMj{W U{B>i_|IYf>^%&k}мཤm0{m7 ŖCJxg edD6]9@ىaRi..v7AobN<;Suo|?[,7 66ގm8M1p-&}=܇ߴՇld'p7&w{Wɬ1< 4vlB?=faROz&39`xLgha ťqn>±M\\`4ؿ}'&+bŧ+mno//UvWۧ'Uxtrݲ]Y E nW%ڕ=a Ƿazȍp<;_ 8 a(+0pcM-6Uo>(vb;x'$|M|WN z{ 鵼.$>'jL7τNڪ= _[|y3jt mˍa.cw"@q17~9 ?;^NWĂƊ{7}/OE voqCr[xAk4b+gGɪ~76Ӎۍ뫘/Pt7[lS'{ŎhQ,*-Fd,X.n\Ý!Z:ӍEg>_v^+hy¼]I~+;a1"WzRoaA\f,ùtq;aA.csٕeVK[`3~գy?!"v|,I6=mL}S$ *VT[Ev,CAخ~ rƣSx-`tl xt@@ DAwI~WU~q:GN#\dk_4HaQKT=weCkgqh#gFh sVǾqe^&XQoh:-7I z~Ǔ܄g B~/ؿDsvd@XX9ړI}6D#YjxjO>㗮:0: mRۿCeOlm_;L T7[df&o{D\rwt覷w1WS͚D{K8{$gmxt2Zݒ0Ŗ& ۧj$VLJ}^|TA -}ܖ h Uu,F7!4X^< ]ȶoZ_t!/Fb',X}g󞅗[kuyn>چx0ۉ6p_d81$籝 *?p޲jew>B@5vO_Yq2dOwtޤ~00hEOW*Gp?#y& :|h]di~Z>ʰ+x?|*~1~;֘K<_<؇bʖ]NrLn\XM;DxexUp|}t 0r ;fNlWOx<;E"O\Q{J&!w=0KglvٸY=?zv齘$V_Nķ'^Mrpy>y~roB_|=N0cE0~i"N O[:wq.ɝ=i&A/2 tҎNsj<ןƝ/Sx'HvR}r kIo.77D e'p$7\FKr|P7g{N2Y>͏x ы_侍;ē$<~.gĬ5\6s'O&Rkޱ>tqQ ol$wbMxx[̸[{5^ڂʷ--~ 9'x?6[~ِyq_oΦxbi>0Fl~GkϮ3MVO1oq@,n&kB~_Cr<9{ޜ)Rq XΏwđ؞-/}a7 ?u1r=>|tѶ١r[=K8"N05,' V\5VSk4 25JK^D7'*PJHJSжƳ^tL &s?7<{vdm_LpntlgdaX:I+{^͔aBNs]|b'0}ev0l ' Phdpido ={f?R}Ao7Q]ߤ&&y|Z5m`'#_j;V1Yx78\!>H7uuhf;+N'G*=ɚ 6T/<GcWcPnŚ'XOqJ< ڠ=W 24Z/qA~.'^2ag;U[~FDlxڨx5W/& ]a{% 8D EmMN`RA߳l)w7Xqv<yn8\ȟ&iַ3_Q2bnvGcS!չCY~XnE1{ 1V=>[xʍ6(`/&7w% #ҩ Guqdb{UM+?sG{ދdÍS3v'3'vy=†5G4'l_?EW#R[بs@y\Nxh .~T^xLݾ{n Ug6|la-Z[X:^|WW|˗VݕЋd ɦ$^usnϖ-&lF׾oGqR\Ѭ.x}_f nL/x wߦ c~y 7ۿtErPzCt ؜F8?p+[ɜW?\ն8pߕtxs*i}k^gy'`m˶ӌ{$BxQO>^icѯw]YEa?X͡[GퟋQ>=[.6o|X|whZJO~lES6~hkŁTeH}edimǰ钯`mog;C~^L>xῘwXpO["Nhu|V9#ǬvJQsMK7jn<+H5,&y$+\:&ϱI#& 3/޴CWU_QoQn-]t |t]gIwmEG_4W'9Ѣ'P0eAzJ޺ɒDzkɇSJ`%n̮I~c\Vж?nEPx.I(jB?tӿ$|o5N$~aɤףJĮ~{Gljh0^h`OTWO{n~?r'1>l5xt䷧q}^ DQ}0zh:^hOqn}r:N>~|>w|wrs7$y|6ԕl {j{rOLQ~鴍-Eu\pp?v'F%j/|x8tW@="8[k {fd $o\]n7acNPs2b~"~cU4d ]+<޻  ^~>lH0;=l+vE>?,mhxO#"l\N>y2l壟k ]_Fv_^vݹ[j.F//z,0\|_{,e4/,hlb :#lv" nW6O\ŗ-CbW?!qwIcΏT'G]1|Q]2Gv5I6Ykn@o@q_2Dư;?$ƥi)DkF&~Jf!MLiެB x97A ]NZ< $[Hi׳ u/(y?yaPᏕ"F}),±եlmOuɱ J=ϮM0'pc\7G=INu4|Ge#|rq8ý[WO@Mhzb30HNh=b1¤Z ]ptTfyM(DOAio[!`F/EX Q8׶O[!>|i1R>[Z6ip.k8;h_0a[u/GQE03U ƿ1QX?5~`pwX`/d`oܣ)[N<6r"am'ᶟVVTX }ٿ{>^p{1? B8Od>ɀ«蛎+N~~4Wq3wOVf/Enܺq0zX%8l쳟G}%&h?'#(kodl[>._ eJ'$]Oh/W\}e2ȷ(<:+/||#@7oNoxnQaf6{ObxYWpFy?6#[OMg=W=Fa͒%Zxwp|pC0{ha﻽y}`&n/]8ϋC ='eU}Vr^xŲ|:5<4lQ_:+x؆icUx4f^_ȒL/$j7\Q'K?Lo;6-L+L_1;ia]YԌڡ =J-]x_-.L6\߯ V^ t̗BYCC \wgA%?^avgX(  n](bo‚2V=dWUPO_[wQO{9yvtaYwch}#r.;ζ=CG;kر(_,(; %4&@g<'>N"ڽ:ེġT/UT tZX"ԽE(n}Xh7[9>%G=s^[˟Y'&=IiPIg0SΟn~&Q +/1}mryo dgb?w'^rH赻$xwʞ6,E{XwgII~ 5)~y}NZ.&.a|^e;F,#7w$Hl瑳_=TW5/wYz}Ońg޼dMz=z'&d;{}}As_lbdi|rC6jّ+l^?$Mjm&XEm=:SS!ٲs' sO'SM:o1m v|%PU\nN"fgӵ<7AlMn&!|Ys ˅[Mj58s/omد-s<`rTO0sC&41[\av?*WpMWfoW[j/d⩿FlꅗL=}It? P&k3<ᔦQ6sW IDAT☼}|v(MT/o'{U&|v}/R^5YZƛ]Y؝OҺML3z~B.һ9xׇbbbxOY7d%M5f{ȵUKow'Lܑ:V͟-~99?D҉ٷ2k1.ks;?{ `6}>Y씤KSg mDjw4=_A@]k%&^orxV,`.0LOޝg\6tp~{|櫽X;r-ɩ5o }n;˷XndNOm ' ät =o~;AGw'CGH6}1IdEƅݯ~]5;t'vbr_pZ`ltta6e(yT]dF:K|5.fGUߡsx M|;`/;যmqaDѢgWաɍ12 .N|+T_5=B |~q |u< ;.VF{ `ɋg=Rمwb9{\wk9ƷPX,jcbb̥c/&u͇-/qm3n}b!?& IGעy>O|~xmp_q"lѕ}/Cq#{-oJ_olԯήz) 4 B2#=pG0\`vP0 㵁S9I-mwm[\";+yX+ 5H\[}~/SFS+^=f$=ϓdmf YdK,Z:ALy_g]>Y0U7jblyőUstDǮT*ڪ-fJRLߙ~l҉+(abLw@hsۉF|f!&E/I~|Qg{IQԧMZFnO=]iSdiD DoKѨ?UY_|l_YNn1)޾<](jwGdR#a"I鿦H<&× b?/]gP9[н*os>HDϸ{&7?2\M ?58\JG2g ɛk#>M_q|-@K& $)ŭwsÏms&;x⌏[~p;r\^x?/bclUܲ@# ZaG'/Xؤ@ ˏ+?-"=ǽ/rCo_0X$x$A<^mPQ5qX7LJۤ/#xHx}m;_Zml=g;5o}հb[~l~lvڨUn5կ7/, んC=ɰwly0U5]0N.8nl :oG+`k|tc߻ч 10Ki6ڒdaL~~ 'Al82j|35Yt9y1:4t3}:?i<,nQLc_fcj;Jp}Mec5>I>omAh V=y/'#k69],O/WAz9+zqR}O?8r9#7rbsR'մ\Ͽ(vdz'O?u<_N>B-4oG1%~N3FcRԕcf0%:c_30yx)[K/rh<R^ϋ}z/&n1s/y_x0Mr|齼 F:~->oB1nx˧0lvG_?5y$uhG^NB+GY^zdđ}"2'v/[^{:VF '<\}}C/ާV"e7#e_>1dN;Bg%KĚ>U suO}:N[Jl5Mɚ\G*?SFܧ|Ύd$um@?mFm{By_">O'\0{6j͇:! 0\} ]P7;RG[ddicum?o@m_g~x"I5/% uVʓi0Yڿv':p+~doYi4Ví3*ۿ">ˬl?5 :d r'1Ҏ/r1>:c>oۦ|GﰿzqCEt䏼5պ-R tyb>}A_-d OiZxGWk6/=/Sf.o}3iFBhg^O'\4Yw8a>& JC>cOӖ=}"'rR-5!z}ß5~'N <bfc 7Yu8< oa@ˢG.Ff̎>eb":0n)+ww6WƜP]4MVx+#?[T~ows`?.!Q FTvwUn97'h&-muEX W6剿|AGcjJ;zҰxMXkٸp2a.pZL->/6eq}Z|8&͋kb,{p\ỶT3E~.~qq - FI +˾8m\vr^HbtۜQ%h{ 4/q5SqP}turu}',lA< Ȳm79Z/6h(HtḏKLS>cȴ/]{ q!t8ÆN0ᶤ MFьЋ,<чLd%gWēSW__79˿KatLOcё$~;ty|/_Ч8*ٮ%o6mt&r55_~gMJx%KS }佘$' c<:`W^o3Qb:>rŨq6x>|\lȮ; \/[\#[ANdG%swԃ `x!H''0 œkx"]q-7bmwܙxZYcp}1(&W~@n πIj/ɉXʊ /[] NzCwIN*1Nm)OO$w7>a$e#oOʶ IěDj}Ս->foLF?Ε9yOgWmἫJy3?-t褙F[xt14ZO7x_pST,~q&]ɝ]_zS;ww9 bcd3u\}mhNse鸫`Jo}B;77IS=ޯd'bV+黃NJ/v>QgR_M/sbln Q-| gb2x&$/'+]៾%| +o@<;I?b5m2}ϳ՘ǫd3޿|n q="ַ+|c=ҡO~%p oo`}˗|+d3Y,bo1 S+Xk#S$||ձwz۱&:~Zp:5tN셟8BqL+mמj[mӸGZLGm=?~;oC_>txrlbϮSA:)tt+[]vI>nGM/:wsq.4\}1?ϝ{u]W7y~Ytaɶ7d>D[ gbI_`6tD=,50Nt7_߾x1tð逗!KhEe(޻0&Byp]p$7xnqdF;!u~f ٥|E[ݫ_2ڇ/[N+~sV.Kܜ¨sd௽hcdH0ǠIxW-C}W\ydn;f< @2x{7q8o̾ڰ[i!DŽNq`z<FD_'^dsL6ߏ-VEhV:&dѡB|Xq#c`D>&^ 6Ͽ26{vǤ `e>[ NAZY;;!8 -_\a=oM?ը&w}Ջ6!_U.Ϥc|_{|/x/З)џWŨw/[`䫊se^d6g6l;9l>Uor-Ȳ4Û.#22E4Rɧ* 8#"UADP*V{evݓvfk7֜bt oږs:ux÷ƀ;klg{`ӯq8ӱ:hռ+jG[zHe0&w s1]91mZ!k'qh|E5Wˣ|9DW.}>Ĺ^.|;eo+ɍG]=Z`FY`9;lׯ Y-یev1bbl~$V7Hl vY_`Mɔo_ם {vbla [ ï'Azq{]F]}'W60`e{+a:Gu[[^y\ 4HǏ||[׍gf t|Cv#tәV}]zǍ,<INZ'=\{6bv6Nmmٍ*C2yo;᧪q/E?;E|[!^|v^]'3!Nvd~lۘ ^} ~Bϕ] MRYـߪ|vrqVH}±o ;lzs}l?~fqypxŒ:vi?+dEo<_t6kerѡR2zz; f_[ag_5o1H fO *Kગm FGK<xW> @R@vr .h.gccbc%lm*E`qȩւgL@"=!G5O8M7^Na%k4 BOND8s#ߒޘNmtm ^ sQil`J-%Mj d; yȘ>n8l@`6Ύy4b:}5`N'<z׋ն`5lwC}{ߛH|3ޏG|^.eUݒ*vfCG}]Uxhpybw:~#}Zf7~|V}b;; l}b#8olC']Ɨmm1drV$*Ix@ h^Eˡ~2my2 UMG <?uq/ck[A.7G/Ox[:>pO^m٧XrJ9hq{ i~r:i? X?-#X`<hǞc<ճ+3ٖS=6h% $g^}v!^v&U̯bK|ز;:4;p4 Olv6.O& W>&h1Y'hlז6{aKx O&t(CzgFˠ#gvջ"v3d.>ț{y6_:ڨ>bS6LzQ}U9 ^˕k++rW VQ16|~$?fبO\-v%76 [o Q"f)}( ބ L,}}e1ﶵ7 IDAT8;r*;~ӷ8^L_?R8鸻2׵,_Sxaf?Q2|~}R|Fdg>6فu>7wU!^0˞"ɚ<ߥ󍟒7Z7Jߗe7{s$n>=MۨNc6gmd큝~zN%e!FMnJ-W{?lsp61v~Il cqb4C|RDseǏ,-U܍GM't`2zz;Dakqet}E`q?;:n><2'7EPBo:c4}MbR6x6t7r;?:8r=`04fk lϛgVbdx hJ swqÊMDӱO6Z] ?+9q#REg0Ѻ9)'m \d^Н ??y={A@ U sfecV? OA,F| ,/ \dRgd'8: *WT#X_Ede }4$\んg֥#lw NApkx%n&]0&hm ^1{ mfc4%}_O&읾y5pnd{1#Oo3[|L<_LZ}ѣ?k0{Ja#|1.KAau3!h8R&u6/?/:bk̳`%tV.|'~CJds?/"aev~G|&Jl؁=|cScSr Xg|i1< wv*yyd]_3m.Pk6)b<;^hd2{un7;O\l"{n̖dKǝ9X`OqK\~xO\uGg4\_BO.Ņ}qz*[VcE'A`{&tA/2Nbt痃_tAE}j!Jw7g/۵idYun*+܈h]8ST.^No'73wˏUy9`|Dsc}O|}y1gv&ɳ-GKG;Iv=Nt!OhQ@w·PX)󍗮HFv_mvk8~lgb%ǵ{gld䟝ٲ~6lޏ0.LۄMl |2Dl Gݕ8<n`:d^1Fa$;}} p1t{Wɾ1!м>m0¡܄Ԡ{.&/Mn%.,&yz<6O8ҟ+fݵ&nLk? -5!>쐽k|u{6N^<$;;)fhNS kJWb}~&bWhk{ut" Grkb&`|L4'_FP^FM;ٲb_>}>J|Y޸$ٿQt,u=wqU'ksl"Fw`;=jo{lbsE9m[=D޵g3mlcs>~l?~觕%+N!v.vܘ-;-\ggd;9g|BsEGdݽmk:Y( ۹ ԉd>Y6;s |*81'bMYtLG?ۘ;pn苧{,iR龟rص"q؜]{>ҍm_;r0Z"|䉶_Xh8ғ|z6GgOx w'ɡlp_bx/yc;WJ uAV7\8`^_WI.|YE ]p<6~C!0%P 5M (NmtFE#ɒ\C/.fgp `%&勉~ lI6hΝ|J.0dP_"D}فɍ*qzmtUrl~mԞx3N`lDC $Dmn=bq-!K䶒Sz!֔]91xnyƶl'9GgH1)"9(@'K]V*x]!N`1 g(EƧMx/N'&dM?w"uBmk| ywFb8k"gW7<s!d08? sK\;^?:&|m{xFlm[ V]6[m@X'm7(Urܵ G/Cxm fsWc?hˡ0io`ӑk`IwC[.=Z2ģ[}&npɻx3_I8t{^!GOoB?o.;pIk1B,4~gd#Xb{de?h2_;,ɉd Ε_3ۀUR09ґrxsd)W?R Vt. y lv.鼫ܮwio!o{W?I++b qȍ=^ w'Izz?w=#6'~RMn/6C曯⛓)A(ޫl:`_mF b`78}6K+r!tIXgɹwmLj:[ݵ kkzx,ƊZo.fe[4KOg[^O[pg81de#rmClz3r/Ӽ<|ji;#9)>ڰv{XK׾Gt;9 tzDvrHF 4ҷː#L6 =!NKu^hco(3E3rqcI­w@LvRO'/;1y/hՋgk" ODXg0V% *Aa*8>bp*S:߀$a?eH` yսճ\'={/6R;y;1ie!cumG? d Jx?+gksZ ǫo /U,\9_tUF yٛ~J߫@Fٖe9/&_o o#^P `!KhȓID|mu蒼_g漢(ۓI^/ oS4U@KF(O[ ;ߎrNOx0c{V;N4?|8Pf/019%8 ԭxCl6Xޢ؝&Kl>3a!BݱNg/[kB@sz%y0lsvFMfa]Lf6~mM[,T=yhmy _g*o.%]~67w}6xʣ&O;tKD'wuFU`Lw+_l@U.t {<ш=ʱxbɎ!A/~lHM._~ i2ގ7/Ŀa]6}g0dYɷ- ,'T#x6+|nzM.|u;^\ͰO~ǁ&Rl= oeoN(FlDv(h mo }&Wp&locfaкE#u{o[ŸpβX2.rL$}O2,V{8"L-𸓁~8O-.,%Y]:>wxK]A6pcc'O+R`ts,GtƦnDp? }q݆pGM_W=r"kW퓝^KpEO{WM],ه~_~x~m1lm'ˍ%0_{OM/'3y( x\pw|`eo.7G{4gʧc0;?]{1#q9M#!/Vӛ:6C/.nj<ˋPS:~G|~@>] ɐ>ϟ?q,0%u8+MMf'kOgh "o~t? i5/'Or2zAܒ5O{Udy쫄;k+D";HCf; n6l>?t#f&+4K# ll.(&wMem%/[m#0?I6ڇNoct~;Xr7ۻ-v>a'xl4 Ai{J?>ձ3mlk8WD[\[moHG,q]Abm:l3Д||G${Go Y{`| {3b-N.ʱz|bΟFp(>w\7ëdȱg}3wcx$uk~o4}p}>byսԠ6?1)dX;Aܵ /ya~q<9N&v.;YB]a0Ō!j{b&܊?d;e.t]v4?#l&`ov7u8Ӟ7i}X~nw51덥'C#8!٭O<'lnqB8,;;[T7N|se٬r9w&`/vv r"Mj<;`_Џ蓿hk&D?&Gp T/B`kql mAm.QAG$nS֞gyA>+`GTmrż$م!CvɫIGeLO|ﲛ$/S%S/F|$+Ahl} k*c8Y=-<8$?~#N@#' (51'gVnGp7b˰-T)b;-WLy싇ٚyٱ珶уÝ-+tBLٲsے8R'f6^w|vp7lfvU[lc2՟%Gd; jSt 1E,b}1^]kw(A<9r3^b~ s[o#?`tvkWc 6FmT^(Rv VGwh @t,?eWi (%uo\,5PgzSb^y8G\6uvਉQ/ۋ7 t܄VlԐ( Xezi@l$0]`GUڮb\2 > AC_-#=0G]Ae/qITW xOF5\`k0گ;|uπc_{GLo [6NVb]רɝQ?'ǣ$N&3a<npP]ТPƙ.Klc7ldJ|f[$?6#6@lDxvu\@ ه}u\QqtmK^ j]bc 8^0xhGeD6_ lmaq:O.<]q_v%N閼[`0[{ZQ-쵁SWņc?*;'٦~sLGGqa[[3&K:>qβ|\Lvo թ:Slpy-]CKFXt>+H-8E܂souYt&vkV'j/6[d)=!+ >(=zmRɄ:Fv4ȩs1 >v%޶AC|q=^Ml''[+ڽ6:;ߨL&m*5:>=G&mMݤ|w Zl>N|~_>l\WؠsԄ:A&elAFI648? ̃_6r~4hׇ`:/c׷{iI~41gA3l%#@,y sXlh_b뷈D'\}bK;cůZd,;曓 hfᱮc qbWtr# CAlC0[ 8?l IDAT&JA.|:ow5h5#Ο^Է+/  7>ȱ8 `n:TUd2g#D뷕+zGN]_h䲑8=Uͬn; ,i/?~]@ك'>fS߿/Š7(vF>xaW~$6٩z)'^_΅nA9>nZ{:`Oрӱuuā@m; GŴx[Byzʋ#۲넘nd'Wl>+ח7#Sw*3)6 >J#!L=a0&ۿ4o$n1֖6)t܏n?ITA M37Ug#6frM|Z 1:e|b7ٗ^'k # #:h-vmfG!g#E?>C&y~,J8ױ=l`ѥ~lQdI)U58"Ds0F6nO|nQ0oJfM̗cMc2/f,ry} سnmT[.#w4&gS=#:Nx<46PRѥ`yߏ26)v~Ra:wgvbO}Ox:დhW<6UYݮ kKid29B Ic[Gk ǃx@{;k`IDYL14]O(n"|ޕ[u񼁰Nѹ[|@}8_Xώ&}߸IbxVW3Sk62=[MaD9^^2ӀN 5[&/9;^65]{g>L 4C8dє. &c]L\[J/2k?۫a6޿1{1dY_^xl%h~ʶɻm/<~m6iv+3q΢뿞iaAc,f-iM_ |/ S7)g)no|l{&`ev›nY_!OS{7]t~bS.[_^׏/+ڗv1rAV[T(߯dq|XyƲxK!˖ƽl%֒wx=Ba>MEbwv/k>KֽdE|y`qo'~4ѼgC>p@* Vٷ%ˁ[0]A$[~\>t0_1ssml kq,|p|m/. }fhG8SM%1H/ĝ>?=k0&9~_~-p OH$KC TO$3M}H^.Ij56y#k4nDwXo<RjPm$:1N%j\ '\5, tzJr2N^9f &9J~X8 A'_^=X HbnE;~/j:v@n@E[qe pt>mRIo-F|}&þo ج3){Dc5fi1>ܪdg4nw+k'œC?X1ۊ%\YԎķn][lw 3 ,hIV~VTdY-Oy;NNd|`tk59*/W= alms$$8ekcW+"uIWyq汚o'79V _EO]6IM6g`[<#Cz_I7B::d3P ~(KdS|-|r1 4<~1/+:_?dbؐ?1Hoa?bBdggh+Ole##16ٳOU~9PؼX@+o:3Uyv$ѷUwh_Q|?d H7af2?`#{r»>^)fF?n\=}2%څw/o pϏHuMLO7WSc-XuaKƛxI}xŃK-v6GTM?e&YD-n 8SW`;_Ɋ$V] `ēγȔ֣xDU6UYg6.Y~g𴛦[dw|vPrrq>M ;`?6=@mfd0ޥ%+~_O|h}6&-{8gEl:_9>42!|9VXfydN; :.gMl\nOrR^OQo[ȍ3JbG}|Wёf@[KP䏿'&P/ ^mrQ[6@<ٿzІW Z29;~#<  Q#]LL5~rrWb)ć(?ix7.\ѭȦ}U4~aL-'Xy_?Ix`Iuz:C %X4STG36`_'1h р}|fOnaC"L};Nm :Ei0|%<:%0F۩; Ln{L0n"m>DsVu;{ 5Xt+@K$S=]60xUpw.Ao—m ކ&t|cCf|KGV؁׏50q$&#,wwot~\Ho?ɯv^'9L{_@<ڣJŐ#)y;W& N1Q}WU{a`ѭ KwAibr/BO|b#{ٻӉ6)`;7-@Z%E~-N- bX̰ بmzlq<-#DA%wEz}t#mCQqyL8rIĭ ^fH3|TFQq%?]9O4x:W.ǀg;QޕrpkU7V5&伉J ^Gf ?oB_዗i19M\}_h`e ҳ{spT*& |(Ƌlo99X.h=bCN;\1X~+7SqwEc>,ϾFn,:蟶A[iT7"~֝^yZ~&{]*O‘W~R/sϗ M?6~7IUwEc~/956vl1cZd\nӆ(#]L Wo~q|]3#_UL$+|~wI*s<L/_S;i ܜS(&?=њM̮y'. 92}EީU>z|FGGo8+.@-_ML融F2n3&=O&84CPkg'hM 8>6~QG]h36?et&ϕ]3KG|ވa꣯p{YG4#k+вs1JnF/V#k,{[Ç\p,,_] ~qeyX>vUmHP7xbl7?'!01: m2K`+}`N$^ \~7 *W-A(K5:|gRy2a?J`%GƑL+#bzNj@W 5{v:%/0< ! 96~P@u<6'rhK66#A- & 4b&B'DЯЋ(ާC)v|E &oܒ ێm`2ҁ JMwz>lh ]*J>y;#tf5m/~Ƚzre1tL:N2+meMf?Go_$Cߏتx'bg?p ;[q<|-96QM`0ImBV!a2$lE!|ߺki-|\LCJ@0'jyu&'w~'~ 썆O}&w>ط}\qDldp/*_-۶8Ȯ4#dze]SL#&f'(K6V.6W&cv|^#4Fئ {NX73lǟ=SRh촜>;eOvgP 3O&f^DQAV*ꖳ"dm.N| }o6[`5=eGm+|⎎&]7wAK{|Pc8Sdm_P$vMLg&=OCadupjk|jEY 6]~ۀ/y|zqq9x/ 9>>,[lmu>eO6=z,|^̦mrf;=-}^o;,pZ65o` mdHȗO\:;[G{&&|_tG~WZ595i"~dv&p/AEvNt_|U+|%!^hG'ּ_hXX[.;ߘ+]? =rC7_}[g,_?'%#~sfgcc"~g|?~x&Nx['cM_ Hm{y4Mv@>M7QK}l169k9(.?k{q UY嗇ѷ}U?x`b2cnX̻[Xl`} E Gt/rV:ތY'IRmD\*A'NnDPc x32%PV+ #df*w;~V\+v8\fO2J 8~r׆{vQ/X.C1뭞%kۤӞΝ϶k$^AqMpOu!׎s#?=h64patN7og?1}*&xMf)!|?bLួQ}lsl{Y}MENr ػ32lhi|d\UNˏdNj]5݊+c! D*(it]m6u9:1P ^TNG냇vNHzGnWn!-|_j#~ 24klH޺xׇOC|Vaׇm:u7۠JWT ;||&+PbokbQlhB_Uy9L M?@_n'K?\||?qDq'EuЛ&/&}_wu^h'=y̶^3v9M D[3W>wHbxDgNz}Mٯq5zt}'wlĶn 7=58g.^LGqMN"?ѥҫI*q쪚yh,p1Yp{c\C&bV,wÿw*?`.VMW6`a>O'teDo9~`ma0U:YgS1?'m&m"2LWYĮ;nM&/^]v'J66lkbӦidk8Oё&$:Gfj;0Xhe|ϻxnLFO;0Y:;]&\˕,6Þ۳;ŗ\UpsnwN`['>8xw]d6}#B-]H]gtkh /t6!R|n]6 _ʏ#E'@W>cgsq]ˣev;Ϋ֪@Ùw MuH}.K?t*'u ;>>>T2TxbK[Ph,عmjфko5 ~1р3! 2]K 6_t襮y:.,ec 6{XBm 2Ϧ=t߈-^lUN9/7Cf(4sy82z~6dʩ#;>7Ύ5CW왜򢍟ـMz";t}΂WZ9!zl*WOv]?mr\bL}Wr2}v qxp$ r/ކwlse4?Egw'Ye'^d֢|;o#wOʧ#ZbE#Hv}t j+&[֎^JQN7~$'e<߼wpk{iM%ǰg~}4M2T~6jp/_L;$rB6y&{ ks|xGq<'v%P&X{bd9&o*Gcnqh_&m_ '{$b[3kgWNb=XW G yoh,F=`4ԷM^j҆z;d ۧrW]$誼IZ曇b(bK7 ~| U8 <'B}|As}Tcg|q4ʧ-`h3#'|Qݎ'kX_~MU+:h'M~pZQ}6>`࡬mJ+^?6ݣLNmiBw OpgɕAvXI:8cp?і=>.jEfy[,ltspgv:T~#*IaqZz fOcl&&GLNlء><2G(qGN,(|+ѝ?hLpQžX|lH_~ ᔬKXyl\8/S||ntIrDJq^?|\<1F޳BzIs}Ɍ$bA%X !q`tjzu%*A*Ё& 6b:{{I?CdH5 [,@'1DHI":M/\甝lUz]#DG$;ar|9_ ,48Rֲ:tB1^0̗o{ ) B+&H'%x-qx/? W 7Al2+ |OwoOعN5ޣ.& Qcڂ8p-.?8n7Yt} ,:½_FbW~lekkYg8%[(l[mlNm9>˳j{e|_OO '(9AK  ̳)l\Uzy*ųd%\?dv{?|-sP}x}|Mvr0nwDnGl|v?҅ NGr[V/~I UpApwG+t> ,_ vvN-@ܓGM6t1]=BT$S6qd})6Ȥ\ޚ H=`.yL w,oS4dged 4kOp>Sl1fw>ݘ?8>mvg Jamm&w$vW}q m!:&Uŕ)tcγO]tG(W2sy> Z n׎\bْ\@N61*O~1@NP 9*XǗ#-Oͧ>mor^0]= v7φŢdvƗO^Oqh~{G:wܝM-xMl&>?za<.j[/d[Ūv2ab|:}Ѣ&ɡ!oa%6Y'co|B!vnw%H*nq|y8ź|B{E G1Nj8DgW/b^%~oG5 `(:|::%@cZ ڬeu' &T5o`Q >I}5@!6As Kg\P}>f ˣ,C57 !nH|H2pnudg# i3[ HauohpKClS](>ketz(Ͽ)M?&p%//[1=p5`t6 #ˎK?g;\m>gCqXy.ӈD|mՈWLa)Vb)K 929Ve0Kh_ X~K68l;K.Sm+9tqM1/MsۈF걯h;{ن_svA;۳v吿ŋ;_9ʅ]AD?:߱~_:LJd: NN.d'" >A1j˵/цx߹rjkz- v~S`2v=TԾuzn\2Bյ䃿o8_n=>1|hWvgd8~jǎ5qoKlcQkSe:o?y7howL~%ɇD>Y6i΃ ($;F ~O\/K_?+OG.g[7 doe2~" Q]kdGm¿FYbqoҽdp; 9}wן [q.oȷ>|n<2FMWǮ?˷iC;<ʮ\hp';3^GX}__ȉޗUeS<~&[/X??_xvKɔڇ|N7'x'j 5oN{ŕtc5xkóx>1NNWmߊO%6UrmʆVZVv{xX]eųg{ } [d+V'˗tLt\4ےq:(f~" =c}zY;mG1V|W7'dN֮ջڋ`^e)N#?)Q6wWŹIdSh$.bF=N`[B$"!?mF?;W2Cu>Gom\4goK\gzf9L2fL}D*rm';r񪄱4/~p 5t0/tMyA?ދќ@@h Ȝn`r9g[Zi/ %gw6z}_. $'1Th5(@ 9&w56f|7%CMڿga2ʌ#ǚ2?зӽ}>Lv?䛵 rNhd7 0Xs d 1r?s>phOnq=c|ǿJ!MV Mޘ/}jױFsEGمE-a!Com|Fi#<>җ*։rJ{gf'JW)[<3_π ?2߁U1pU*W𿎓M,Z{mOwTݞ P.~l}Ge.δʇ<^m7WbԳf_>@jW&۾E:o[LdY_>G@v]eߣlu43nf+Nqɩ,Ӷ+rWlF_[/62ot٘?oe\%by74B$m_7uY \+mrL LLm|5Xl<\q3Glu1W𽤏kO{/Y$0yNx vϯڮ_@ɉܮYH|@dOL} ѳ&8gWmd+X{ŋl0;,ygWth_sq06)B tȑ󑷻/$9:c0h/QDl&3NMHqok_ش+*;Ǵֶ“#~s]eQ'oytOh%ngʋcl\>ٓgrcs]aO`vJi:TAj޾:ů9_ 7Bc{AĻ;]n nG ؽwAXq,grR|ѝQ.Yמ1٪ѻxo>]=b61Lw*]?-O;zlpv`x<v6nǦ.$ #,J4.ؐ'C-ʝŗΈε.*s|s`FSb h8`w~%3o;shl d2i "[>D+V]Q$.~8/Y*]2&t -՞"c Ch>x+ 0~e85@pC)nrĨ: M\&9I2,?^pgdk&l/H  iޱ{鿸lcj_wM6 ރ? ?x y|x^95QھI z8{ϫ|u8Ʒ}I>}&vŋHN~ϰg*#KPLpᄍ-'freU7\<I}O}}Ju>>`|\?׎z+:Mw[G$S[OhNRr -Ϣ]]^ p{Ao˓hvT'[~Dm7n2L8O1F&}k]zwDk}/`}1x.8o߲D }>;Gj/|ɽZдErjZI֓LٌTlpzQ7T*L<LJ|`'h~nIۘlL^Q]+9ؠ{p2 WtQ7n_Ur5Ԁx䆏=cU4. 3U/؎O =ER<+;#v(cӘ(?~OH~oO㕈 kMoSq cr%$&wLNvJ;YFn |#/mc:BI7Mʆؙ_>+eњ,1tGD=7=|IULUE~;{Tv8v%7o_&l=\^{v&op4iޤ;5b_9G0eMڵgmcʳG*+s:w'}8d8Se;-6WCM-z[d@A'Rz?~-crW{eJ. LZYlE}A?dbc-M\la臞6 _^_E<ڶR^Ddb NFE>EGG}er[㉉i?2Rxo_.P輰εI9ѳ8v{p@-uA>t)bLJ'<~_Ov6T' +gq 1pZ#v,cH& > W|JW@;SU&_<>34\s$0jS?"|RAF}@%lx%qlԿ?x%UVkJG GDﻎm a6=s m}Dנ~* IDATȽWz+Gmړ-{^`7١[<_6yßMp#Op6%GLhW|;#&Pk RLhz^WeG47^8z),LC{v[ݓmLe<{7̫{~&oO~LH矙FگNGvf~ɧhr1FEd_Kr9d\WoPR ,=9D:}xeՉ1-\7H&$?5XޕAzEl;u6dd)倮N7_9N &ʶ*yj=7)>߮>|*m-ï 8џ],ÄU>Wp+N/5asLvqOO-/v(`me'ë9:(18; S/SaAjҏmk;+sLxWQv]eWCn)l&ב=U"!ğH%\!.@-\Vݻ.6oVu>ZkqcyX 즶|$#rOCE-CD\_Czwqltola֖<媴tUG va}?.~D/@L8^dse?qwH6DgG?>Yl+F?9y->~_>S ۋG-=egaW|3au>=yN +[,X9Uw+LJnr䳙x5~Wfコ6}sU۔$M|v/~֋'19Ûwgbk1=accӷ}քb0xI\Pō`l:}NF~m"`lr%z~8r3kn׾O^8lXx1U\6A8=|g;l?}pv0q6]7 om*+ ToՋd <W8m(ߕixφkq/ H;(wXPO~~+㾣7Ъ}d[|w'_r0hd=垷K2!Ww~c.*ww ^>w *Pσ/sw͟kw#!o?]/9݆>K,I5`s[VNU{Λ DU~b>&̋|nß0+t>[}`}6,K^ fMmMƽ?[8}鰯W1'@eS':Yv< ]!N咀C8\|)ٕD ]_pw59g2btd V o!Ծ%ќV[㱡8XLp#rwPoc>`пV~3^f+m\pz&lC$9/}k?`D +A (NX0HDg}^&8bv.ߧ %Ŏ 6a94+'W[? Xhg4`;G{_]߻ubO?qzdH|g"2_O>'Q^ ^cq:}~m3=ClX|1 Ux__!W?ZL9N:?4kv{f8ߨ퐛ΕÑ#zAEBg? Euʵg~?Kϵ#)GgmwZnRf/!iGΗg;?_#/XD9.Mhc+ƑY\X7|ydήC( 䏵zӯ~Uz%vm¹~{b}bb7lvb,Kek hdl.ȕn18l2E?RpIb<`l<{ rtޱf2- ї{qm>yx8Z['_Zӥ6ڴrw X-T&7o)]n۷}}mhy񆋁8Sy[E{ m9 {H>-fkįL/ʦ2G%_ uv&'$-,nfh7y)ҷ+X MwdՏۅ;9G-rGƏ2OD=&sNCy;Rg:+j+KbP-#&vnxX#$GfP0b؄ yGZUF^sn΁pھ@јg `;JO&YhUPOb4.'$H{BuݕV9=Bs_4򁁳 V_x\#kah`:l $@Iޯÿttp`= &[֥=v\nAIܣ"#}$;>:G?kѪxv ق\^5Q-b*BSP*laƤ8Zls1NNnMɏ 6>HWWN% t r3ݦZg!iXI.6xV[c S|F:NTM~J_k'#]7h6Ս&֡}<2J; "/|F}qts/sIh!̏A ^{g2H£Kl删gWl烪.}\E#|2vVvwŵ+'U|6X1.fjU/~+'hm!M,1[LōXc*ՖLxsq6ċ}d z{>Uz2$ PL9g4>4xg2 ~+W7]O g0:Ņ L$] h]n[Z8XCbҽ{em)c6T9\;\[}_ rL$==_ގaF׳-%6gЋß vn|^U+*+ yt0!5@H#,uo.ݢhZ|pEEg -ޣ J}lǏ&~[6nI{բJt|[i7Ǘeo|b cpWj9g|kozMƢ`S~m|mxv[Q vm9l\ŝ`D{j0O#~sBz{ٝGMP.X;)u؂߼0xS7p [9-lRE }=1 _>.navF6RZh#l{wǨ蚳iGOɑAjt`2ؕL㱕M y>F]BDolň1eN&7MXIU>cvUNjGr#ydY(H#e?ޟi1'{ WW_ʦ+-^ 4x :f\l[Ym׶ЪPz/v>7nXzsj۝/fB]rf@ml9 `?Cw:4zFݦ<GuvLۗqEO$26'-@`NC @BCp (R,kPn}cc&I9vq׹ cxы+xg{s{Mlj莸`t6ق+>C==ȎOA4|E c> }lYV 5ѧ |Ůd>n&Fy?<$xt#SȆ'b#^W߁ȇo(ST?70h?fto>%H:l^'N"v@ n)Ha;{pAaoKr?bķGEt,O"xdv_^%>ocpvWbv;^ۅ1%W NkK%OOqͮLJ&d\՛Lδ|U?7F~dhcz&n'3*Hu|+οM7pMlKGMq,!Gۀ 56җ}Q$sb$ƅr\>o$oſl>b?/Ӷn̳0q/= ?f⋘Wې*{vËQ&\:_;?Gmľf} "Ċ v8˛ƒA{r+_>x6ZhLH̞~Sn[x"o Gt lŅ_&Jv?m-](b9ob|Xdfb`/# y>|ொqa\4lbƇmYѧxIC6v&%n{˧gBt0 r5k!_n.oۿ[, ;Fl:{m~摐6_Q<3SM(<ZLolŝ:,C#vbU$d+e1%rFy"co|ޞd@p# ({r~>Q.6uyv^Ϙ:x&K}nr/5کX>-w\z-Fj;5,(]ÿ ,O9S#\t.;JOr(m(U?_Q>q|.>d޼?ڡ-vzׇxFInC,C?d@L֨ Qr%pXWѶxMd.bK,|#[[r$߱2 Dvꝱfp::g,p*c}gm޺Fs:aΡD%x㏒Ѫv (UwqGyIop`kL H@jOXdfBbA֒[S|l8e9~xLmx :||gg?7t44 uyXKɖq~_z&i[{×ܪ#?]ovk 9x}6=;1HVjWڗLDFqwU:6ނ%|/۲٤HG>8&YcvW5Xuw {VuBO2 }W~8  !ԭ^C&xX8@rNם&lmKpv:5;zKmB tbikr$>_'踓6%Hj O?Sw5>?N8Cr'bQ[({';em seoLDiEսs'վ:V/Ѐ7dx|8c` ź_9ˉ> h4<8ga8wV5RF^>\ic'M ':[_4PaMgH rk#O!?[,&ҫCCA6~Wgo~9펂OO.:ڂ$>Xkk(;Ncr|g;y<"޿Ed>93`)%2;ԷZx\blDFL=N쪋vGϧB{E[I\Pn;xd3Й b%Z{v}O_^nomzt,K Fƹ;^,׏$>V_-M`َ|m9 dBB8~w+ul^ P4 _tE-o&tKqZ*atJntpɡ#w7Aq>wϏUܷ]6l. ZCy{+'>}bd>["ѠMH$ V[uX߯Gt7ˮa|=:c8S^can{lXteWz,8 $^i`7;מo;TzF1Vo@)s锯=*R|MFc_Bu ϔNCmgL#SZ,{ý=yw75r򎋏5tZh~Vʫ@ (|El}w=XJ8"AGО% YjuOڲ礪0Zc (exn@١v+%1`GǠ)* !J9j+%#[#vFK螌7놫s1}Ⱦl\9':щYbj=o{^C|Q-9=TtVS1?('Omz^\~u/kJ,XȢ#qxfق}|#yER4Yl ߱1?7]=8-dyyş]Wrzp !W|~.Eg{vW>繲4<8ɹo'|QKlfn `Ndq|1nℶ>ԝ_w *Dx IDATS FVxI:V ј[Cjvr oGsb٦nI]k~D?uLhv0;Ń6(O.|F)F+ 9-elC^O,u|d>#nIA$c$Aٚ#ȹkG7rEY6 "I#}'6˗og6v`KW&b|Pfs$*@OiG7 IpM/~[%F}L]U}mcLm}r9'|֋nq(riH';d ''_/NV|JOڊO_Ͼcus#v,rd`sJZ{}}c4lܠv+rP˭34#޵_ ?fp߳?lLgw8T~}&(L8QɮQlKM.sI!"<|ݿq1Z6rkt.!J*O!.GxEŻ7J[icGrcsml _gA L̇:"#hgX2 Wmk/ebycB\Jy2b q1!g i?|J&QwƜ7a@D7E[DoS\lTNܶ8 ؄II.ń0K_ъk7,>/HQW7 ~μ9`(B$I9{$*_P?}}$9T81jxuDݻc18{"X]nzB;"'x&׮^=Y21N^0m*_;W+ާGpؘUk@Q[7ؒsG ^@ɞcp=l,xo2C}ς~զ|̧9_{ݿpۍ+1߲G1BOȇ٪;~)8k pux#Fw0: J8>eљ*$Ugɰ$;awNG? mVMPq ?T"U &&D`Kz7}(Mwk^07Vʣw66hG7w ֟|r ݱ_MLO ܒ@f.oԑ%ɿQG5R/Q3 z`?͋)7_[A_;hlr#'ɺc \Ս?:^_?/_.{`, bD~rm9z'M뙐wr{pJqv"^O;]|o?0{cic^B&m7uXMvd0{Q@  \YI/ot=@/:K|>[C` KGCۿ/>^ 8gdY,{%I*o̾t'wc6⧣ߊˣDs:x'+_)vA#E?S&d$ }&'xhNRTvmӃ[dqR ?,{qD5Ew8gZlۋX~de:Nq,} `yvGN*m_,΋Gb:e3Ń΋PQ'cW̵WrTUgXM T:\V/˽;.O+ L2v)kz41QLo~rn*#c+?*,Y]Ucu+7\bDسwO/+lX%fe/2Y|6#pcMjnp Z>w?8o{f_Kկݭ_L[P!n6r!Ghh^BDrW#Y.2I*|택63/ߗ^dumwylYLl\ⷫ23qh(b)gem&b$mtPQ \8Ga9Zf'~:@e <^;G?FjൃgX}=}e'( r^BR 0!-ޖoqWQΧcUvHLN; oUIpJ>,? 'Ȇ=)W%uneš!F(wu=ZH~RW&HN8kJK}eOdH{8ʮQU74GW#`/'DLrxpt O8`7>XrjD>Qj& Um񞭾ĩ?~'χ}1PwoE :S|tMw幷{GjKN8q( ᫭r۱F`)aiT_xCݎH8@,g0`*-<윋B}pg3ab/F!7mɛ,5@F[̳m|Gt6BM _/..$ԡ/{nQZҖX%;%O⯺:ۂ¨ծbnh$si𩿶/JJl0D%m^>[m=ѱM;>UL,.w2y8oydxq#˵u%I0s<-wܹ0bgな:xMxX2zS;7~G_f'lO-wnLJ=~sh^N=_{)GvㅅOڒxw8Ε{T{NRKp?۪~t|pq!ɏ׶j1&l])%c}lfe+=X*&SqQw0!#`xmk/+[.f6`RAﲉ_[%d W'LϠA$/OXMXJ̶v7E]c:?,6|q=6wzygі(N^5wq$4 w&νmΠ=dg*Dђ7>{t`~/,U~1뮓rßnX+Vj&T?ɵM+6#㎣Ů{(ړΎƵdKmj{3egv! y7!joݙ}Ň-vry="Ё)zԢݕCQDO \AcG3 +Q0uE?m&;],&h'd#M~ VM*h=v|t~|H,I{`}&s}J(G~f'$)ۣ/yz]w\W,0=|7_<H}VQxڭlμ\X0lS;3⇿iwĺC' W >brA+LR71)>rxpʼn0/g-NHYeɻC l<|2>~;χn7NIrRΨ۵A'h;^,_}fy?0(^%;-% t4Gx/e'6Rnc/?יY$,H> 8z ]{PCGJC?4|";Z:>iФ0 c*gc"۲>+'mv%p?6lH>CBՈ|Vl77hv=}h1mO=mWs FЕGc~JkoXm_uw[^:y?R,- d'|!v8f?ew 6|Fh#/=Gw~ym58ڧ2-dI@Ckqn*{b#ֆv ꠝ\Gb}mɱQ>@)vO5QeMަkrˍCbpͳ}Fbⓟ½A_Yt/E۞{2#+w>o~݇Nx=6xD{[rby33qw=N5Q?{aYT #?Q%!?gI۰\~ l|>mYvR{jy{{8Wr8$6U xV:s=?;?1;\?Ո2ӿwI`(Շ)^[}HMqDQ΃eh-4tp{s/GaW=ITu+FŞL|:_#t/*VvշӇǀciO]\HNJ ->%ă\_>&c[@&f2Mhko/d~Ԩ}Czy 6:[SkCKJyߟ&aǿn<0]%qNrދ!CpVzR*Xب'K՞mw~זnGOPqtX;{\ Թvxbmi&.io{x>czJLdM(]*>d^љO,p[1c>_K~q-tؕxH}Ѻ"gc`-V;F;|M :2&~r9YWա+_Gw< #:_BCL{`;jf8g;+d&[vq:η#?\Ӯ$ǬF-+@mgcu.-/z9~_j E[dfGpdK6lII;ȯ3+V8{3MށY~~.սyʳA^ys1AG+66Nwp/wl/ ACkq՝O?/w#řGod f %9XM13ՇCNc(sʮV@{J=2gLvut=3.l x,^ Z$N/HbH3b %ާ O0 R\Q^Axo5Zm{ޥp_{g( ±OqߜMn $@ P@@9/P[A}EolߕYAGwxmkd]P*gЀΰ܇F}F]y)bw1V.078|Ç.xq lqmO+?ه|h ̓H(l=<#H#YY&?Dq/ъX3~-bNVq}}8XW2?|d#7j#FL4jCPKN/iSgu̳:)*lsxөS_|+g_[{g"A|$e ϖ=<)rB6?~[^f="!WXɶ"^l2p6W]SW/atʴ~1s  qxf#rZT6AevDTh:_,LG|CwzV'-"yiwaJk?qsW:&?\\Fqv&Wov"Y0/Oܕ xqoJXC[ N'ј`a"}Wh^tw5y{tvT# 9~OCӽv99OG,U=v/LF"sadg *oa|ʣYu~ۄG,$G~;x9-幗/+ai%3c|@>AUfWI?7aaf F>YFW{ x+{B]V7~pnOǏ9uIh]~\c'&nȸ>;$C{>^dg2;o維/_GnLGϞ Ng]>.ɯI&2=q9@Ec_FWI-}/+vpM=M֌m|Xko1#X && ?6/;8nמE Ϗ]lʇގ~7cf-+W.M];Xc3M?\MqG=e9Y Un?ٗk[sr^\d!˟|lO7y1;RQ|.xc|}WdC?=&虼b#|_](a3G"FvM~b4Z_# :!Mr\==mTծF[hVG't_qqvpz3DVhq~}7 ƺՋM2"E/;6wbC;&^?en 퍎>!(WsgǓQo+:fҲ 5%`to1DBΆMx U^ru ﴸ㙡X<ɟ=YELd|<^}؞6p<٢3UɳTwlxz~xfG쪀w;btX'dzIcdI.Ҟ|N _*gJ6 bϻ5˞0۳нT6Vz؈.v4*\[>r7O >.')?f4jq>o#?holɒ6ܻ:)iu9;!e~fv~طoX@InϦɖ : +kq)M -8C\|Эf1`L /o__m^G|W"a/\ IDATx~bnv7X].Vet_w0X=\}qN"~Po``k[0;.Ǧ;GWhtp>9 t I\Lh_?nbg/fWhnG.mѧ|a]ѠAK'} jDU,nm8i._\ֽ\lmnB"7_'.3cy^ %O߹@ۑo-@ 84u/Nv%lC 6^^CUG#fklxoM'g T(]+t`yw;Rݵ'YgOojv@uw@>5w")9H.Aǣ @ НIA~ßh]4 ih/,HOޅ{QR cCNgkY|/o[D:־ޱt*|"c4}'gmST>#JzWݝTwl%~4nrOWpw"'`Bɾw>}$Tٟ>6?}#K?Fwd̛=A-r-3gRnE~=$.Pi}@~OkZu ;xcb]b"W8!{Wt}&وlѓҙ]%ífhQ3e.b {-W$;Kg;~2\:v<0=N⨲bvN{*.-tVrW,\NB+NI(1&|ja\`7orásgFP-'*lޡG|o-WEӓ3I8hxL#z8hw_@ `3p!3D3Tkƨ|"]WD[gdLWXF#:V>>/>?XNq+XƤxMݛ`Ut0OsWGThT#9?%l|H'֗THJT|gWɦ眭@ ;AHInU@q n[g1EҘ2:;"Fn`DX]]CDrCutm&бr|rߎۻ9ptؐFdmT<s0g" 7 r>Wi 'nܓ| jzW #^ Zu&Kd^>HQ_m 4xqbcCτForogŦ>;p;@}^~y\G۝q)71nd[ޙ߃Y̲8}&[<Eo3h#ǢGrcŠ79ngƆޗVFvCՆFh~Lze6#doLf0 6mm6g^UjMoG,WӍ<ӗ 'ǽHq,lIǞu\~mᯛ6e% 5K6ϒi㷈S{s'V~ý:_ă͆D+ra~H-JjoLL]F0pH6:Vϯ$7e d] oyw By/|a?zՀɳ2[>dhG?|omr6bX4: wKtGO>?y7On_= v苏'FƗnZ/+f ~-:+nP/WgzIN/3?[M0nVjk]n|M(~_lPK&W\=x{/ 7!FMتN|c_{Y O/Uԅ?q ?l^;φw`>4gwT.vpw͞Y~ fMLM~gnNq>2pW*M3#`bu؊s6[aaxmX'Dy _ h-crxqtϺ|B>][ňZݞ^ޅK~y䀟9l9-:ȏJv-FF(^Yʝ31ҭ}}W|Zf;Dv<<'nqL/qQ$Šľ͢'Ǐ,z}!lťO] ՘_;oMУ:|x{gR~/ 9j}~s#^]&ȍe!&<;3=0d}0''ͫ~^(.Տܩ^`+#H\M-hEK1ZIIfpJMUGgx*4}%;Zؒyt^J,\L_[l 㭾IEuz9~` G.f%FvUQdy?<>bS\<._bz[tL[!$<. f/-y1/}m;u5|_ 9lD_ 8?&wTvGx'[>>{S|TFkT:/X-O &Ac:Sl[͋uWd4 <:֧Qa{|rZ}I -Gҽu%I׏Md#Oܦrrt&bطQ2c7/>;;h5H{#x<>iAm3Hg/"V~}qyj+9@c"IcMSy9;m-ӯb'Oncg=:o(ѱ>ML~) {Z(w>B<2Lg/;e>mk/N&*.TGyFgʂџu|dyH+XU cYMi[&MAGV0ZޙjHG;6㗌:~ }vt:\u^wNW;WW-O78(\=L`T&R뀟+>`sJ 9^ []_glX2ϋުjD`㎄Gd5ǰȇho/f|VS5M<oC>nP04r` Or\倫~gzrm,=}: &X`gp~M;7$MmOGDmj':;׮? x`G LSnVa?) *od!߂ # mNwG8osm@Юސ!dv[ 8 ;hΣw?f ᬝ$[h<-&fl3!?~cƀOq~fcw尦W#ѯ9]tx&E缿qw RtRn^@_6Mqq||6:&';tB燳lT_\u\_:QoaB#fեRǕVzv勳/<>ٛ[őw[lVp78qƋ/z6?Ż7O;U]ll;ђc_AU+_[ K`X JwT_CCrNi\ -gk9t\8خlVAwt WFNG8C:/qA`4X1A FG u;OK5Xh?d 5%2-9fM$z?AWᩑLNY]?˿|O_c}\o`+|KWOXٱ\-bbC=׵|veOfM*dD"b*[o{|D'|⳶!(_ 'D|dpњ>g~ўY^l=o߄'ǃMn{mw#bՁFgW9|rǿ(58g{v2;^{S||G͎-\PYX:եseᱛ?tͿ3F0[͞*81F k"?~V |CkGNnQ%O#:6xW!e?hz(|EF wG)(G4 kqv ٷYiphP*{O<";Y&oP|j{?Ccuw8D-w6?0m_F2\eע&XɅ9h B-gۋ_U ~ؗUoj*Ml$[G >d^';mns]^UGSl`rcr!}N!/ZYۋU|otxģΗcOW∎-7Ip+N緋cwm7=.L5<~UGG}9>?SقG.'Vo1 Nm Y;No b@_*Kv^N cu`"8:O|y)u6 £>cg ܕ{£~hWѝɀڥ;BCp6q=gM]Df6I_$S|} ğu^,ً>.OY?w耵>X(X8U^h-G%ٍs G̏^/^E0 $c GNǤl5咔ɊO?PKh OTv r>ݕ=o Ũo`Gx}+ma[nGv7 T24xؾ-4{- &./du|w8t1Ձ,lۮag Ο[!MYlJl+KfJ$nO6ȳ%$'=@ɷVWFwmiLwWJ[L_B$=%(IURmG$4jhQ/6?w b쮟t|h'*BeTO~ɿO&b<3"v ^&%pQkN ڗ0]}ߖ'Vv1der4;E!md]bHs6nWJXLs'WlΜzT~gK3W-.&\ޜWG]Y8|otL/NONۗiOd`ʉPҿbd"h;h:]~`{p;^vn@R|.m:v{h˯dxz;h=^@yg=mx&oнmvKN7/ӎ1tKKt/3ӿ>P͋@6biB?m ]&`Ιksx#7== f-}vԯΎ2o g|^^狓oG#z_:N[ ~ɿE 2gᘜ7dO`C>;Ύ`MFr &I[97-W#T_>o~OLDi@x IDATM=y9ꧽ`n7frPι/V w\鑭mBu?Ǘb,(˸imr/ŀG`g&'k|g^KVthM.Arr2#;Cu~G}8c!;ݍ ou+H ܳtZܱZW􏅖JsWѽ҆_Vql[C'_~g\hۯ4z~>}l%wG8v@ Fo/&U~v8$:}آv4}qkO}\߅*>s-{T~tHk[}(@鶴;>Md^O=~Ntyd h#nnt?l Kޣ `= w gl19GcS/%4t1X)%\wVVQ&>.oQSR5|Xnןk/Cį^C{_gnA>g#xg0܌+zd4 g%34C2Lpl`oklO_}Zo}( TVp!,`/8x/ VI'ٗ Vo|&$<|<ދUoEWr>"\F:D^roDp /d!PD;G:56t mN)z*; >ѝ͔=8ʦw/S3kro<dm$[?tE_Rd+A e]0}3v>ہ}Vqx&dx0 8dA)`ÜL~c6p/䷧~Mu|^pf#m&ݦGb{ss|6yU| ey6cÑ"x }D@/=Wf7ѻp/چ~R}>Lɠ+!~}:,]O\>zodO2O>*?kѕ HxOգYyMno=V xG/"x6k鵶Q?4{*wbv>;A7&]h7Y_I䝢, #N# ~}翳} 8q8~gM#5w]̄S'MߐYȜM~6xm5h;˝rt@gy!Gy1/ot<84n^lGѽB43O^U.0t1K_~a>pDF}:]^EţqzFyU(hTnwX b3ǵ{d}->엝+!ѺڳԻ|UvxnwX˱!sy; of6b9X4mP>'xЄ䭌{;vǂ9_G&6ʼwW<9;| i{]|@2푃w,ߕtwȇ=&h6y]D9=}po87g;\O. ٓ66/~; U(J[Mn㴽|$Ά~r#L}?6l?t̛h| g掫^}cWXN;>}^73=幍fӑ_8:~N}1)lLÖod qvt_~ .C6Yg;;wf<0Ə$ry?'6I>`7;pq lǦݲ/] XNocKq0OՇ_;|a?TU6V%W}dy'&$1 ^6v8A{ye9ٻ{ל s< Y :%Q)Ar;KHRh>be%# /(g(:ڕq;^̠ y}+l8/~N}*`ΠG9nB#gX!X4^p(AF ΏnP,QeH?/܋4b4P-Zc~}9ƫ} %Έh` nl`s`8O055ƓU']u&?kxȎk'[ś ؄A4߾ w5u%'}vnpD^E4Q,Fk" +am0ԩv;xIE glrŶa+p1:Ʒ% L&@{ڽ# ;Fta<$w6>; .\|mK' -Q]\'6|c֜SlճOEѕKYbj2?W&;bG3ʧ=s#٦7=F{=&L>|0vۦc^rEOoD9|lz1Xl7$)y7 fUdoW~2 Mfm.yOHLGytGz.eqsgw0-n^7 DĀJX6<<(s rdE1L~ńaW/a*X J)B,O1T[l4zTRU&I@Aӳ+5t~:L>DaXt=FEY+p58N#Hrd@]Ӑ #_"BXإ\ԧo;;uoIY:X]t,bhS>q_"gX]tp^Ʃz,`Vro >ũ鵠`;L],oCv ;BOY<ʞ4ʤ=QqT^R62#A| A&_^"ޔ7tRIwW=1m *FωBdPGXX=(V>2;w#M~\ xW=땊X8K#MƆ!6R-o,\tLL9Fv\^0 n`nߤaT=:h*b 81~4cJpyn ?v́GQl@*,MFsC[6;QWw6[1BwҊ]1:~~B,M"f4+U^onvp[-WF?[oh?Auӿs{"wȗF +uc1&C}|8B?m Š%D\M/ |>#Tҡ2q35\hr"dZR9 a@uOY7tF/PN.vT_ `Q6X~>#αϱFPN$ݽ'uGP&XxO -G?Ž F.NZC%HOI6]6{|E@ akCJad*VtgAƆ֋Od!|})/ 9O< sU>y v[{;PnrXOP6Ǧ'!/H^C3Ja>$tW轊n軣qd^SY%.F**cj뺲i3#Ocr,\E3M;)__Rk|цN`ԩJ J  c_(jv% F\f(:q )1G^@cQ@ǖv@UCcرI /"[m} ;YOX2 \&H_zẉ_jGqQ:- r ƪj`؛ i,3PScM_|1:ɂ<&Wؾko3RG|Rkb* aEף)ʯ;gb5EΉE랺 Xh'nc\Tu6' K@+c[S R[akFI'$ ek3!wȈ1[!ɸJJD'\f1 c'ˁV-~P{o$8I# tOU 4 o\ $8HnF4l桛i)5ٷVG8̀"!ܥ|۫2@OYuΠHf+i滉b=iIJ(SAvV^Ȳ}oaiqg9])覍·[_ĕ4my[݂KaiATɠ,e6ʤr_x#KRis|:`e# }^94Vfՙj@B$c*i0.HW3A<6ewɓt/Hy Mӿ]pm2ޙ:p1Ե#[;,rNJjg[zeb1R%_*HOcܜpt_\;F(*@AiG6&Ϣ 6+uULZP}ŐM3ĩ2~pz]̐ eX 9QUoŻUY ߴqʔw IDATnNN[VvW%X0 ~O3[$™G)g̉~%p)qn^妮ٌ7hΈ1}is[;FYC)Վ]y~/җs } wlD3yCUx!RKbD4_|Y4>qu%9gص}=BVmT~y܁`_{Pܮ/_Eɓ>2.K?% شi6wBFyCw bJ%>pW@bۃ Or!*yAzE0iLgM[@V#>e'dpp28h deKKu3e]=)1Ƌhx¡qʷv:^^S'ӈFZpcWm5 ӤWV6CĕP(TL+ˆq]/-mx:eBB)ᘙvG#\ɅW8&E V*R'3sZea_$emm_C/iG&vā5!O[^8]z W!WC۠ItY;o}|SuL)Ra:GA5@3` y:8iM cr(Dvmݫ\Y [ :mȶlՉN.}DV0(QG&<ӇX8 p-u1)#B™.E¿*'#?v)VBoY6tѹ30&hYUG¬ðVѢL>ad_#s׫  ENOtutf9X4F4\_acx ImIK?e z؀ʻuNȎo('~x bH =7-MӰ+_mgSm"#`o$\}VǒEHb8>Az?"<~ ll%|ͦs%Mm6R 6ԙ51JKD(Ԁι::pѡAɳZ/ovS5DgݩC$L|bT2Q!:s<6ԯ~<7vظP>z%؊~]|?E|b{tQ{Ƴzjΐm݁#iA7i,m5]㡛lj 1[s돷bdMfo`8m*io_qM;Tbg ,0/+eCU6.c^BӎPc%,,U:]#r^y[/h#4i;q*0) >ջ걃;`ֻH.{Տk-y,* "+ Y苣_muF*f& -[!zdF7p~ǣ߫e%ROÛ?1J-~ٰE']ď've8f >u49&.Eڞ`jnLzH%mO^@?LBϔϙeNT;)\%6%z]?L6Z'Lz<,c0r僲mg}d/^І|;k|g}pZlXǶPA˗?:A5q @\y~qX%d :!0Q%qh`NK6X*!U7[oǟ8̰t+s{ߓwRBەBB[)KFEh-@`-Jo^F&o} !hCA=>הܡz ޑ.ʭCz2,e=N|naa;ȃo&5 |-,Kf)"/pl쥕b767SɄIhkepU&t0O˟AhWWG9W4fiN `AJS^fn[xm'N]AQϣ |T!36qƃzX~Nkg UIu(ŨG(ۙ`Wt+9H?S tu< 'yNJ @GK^{'S !,F3uP:+ihzEL?9O| d&X6'F8aYTZni C/1x[V);2u/T_I׏Sw[V,a/!fbLxF+-;Vu:\q , #F9J ?X^>UD+bO=b6ͮHc7 RbHLnT7S(ꦏ%VrW2ňK\YP'xkdk (^ib7(U3B^Ƭ ;)sdaȟ`z[9X[x9'Y'bv!0)4􉟻_7|uWax'bVqUu;54Vg^JCrO"ׅYK ˻ĹJÓ׫JR5NB]MG鱞!dQɇ 2}mƓ|Į Z 'G[ʼnš/O~.TTrFG?6cL:i[>~uIZ^r{3Boa̹iwe4_;t{/&yDŸݼ&N۞aϼ-Vm+dܱ$]4&ٲo -8-߈`fzKqt/7=>Y!,M:'CxHO.z֣E$ }haxo8 4+x&F}^tASf UD4Ƃa*m.Z+۷Wñl趋?+36_dilLBP0ai6u7~0"(MW?_>2~3r˞c[c%M!;T:m~JfXP74J[GD' +tXE=|Q(dzhC-wd|3cR (qh' P€.eUIY|I#)rCNU!3 @/"8eOu$/ :kS28Cmϱ:z#:w$0J6O9%WCc_% PgABQoIZεE;IR:uܗ&9`V.sU 니5/ Nd]_ m\}sb*Lo]$0~.?CgIKtIO21Gܤ&ximLxSb3ʈPjL+q!ӷR.»0/>h9Uc<.q}M), ^蒫t|N[kL)<'Ԫe8w)B²`ݴ$=N1ʘ|uK}3Wkai<{_Gi>Jq._u%f93D_nnc{#sw=rΣ^1:ȣF.8kU cu:MihH(oy.-ؤ> wJBlCJ#T,_^UB"r#+9u>;݆62cQx7u!e UlG[yqde<,el6;Ա=>ml ?m~82DpoGR]KTdrWxk :;Uc3Zlg)ᑯfG ]{xglo Y^`د-mČZƞV vЏxwGXǂ|s/'Ӛ&ME<P>24Y `GLyq vC:#"GႼ>c覮G=BK/6v+|y._n?^F8Ǧ, o. Go3<;f෩3*uC/߲ݴv<QdDIRXG~@-YTOyBCLV5! N}늶Sq(75tjKoA A놔*fMjG%C:V 1HiA}2 s2em)':= J#`YQ{JR?:f9Pd/HTl=if ^Q9!-SF?hJvwyv"aZA;rI$l8eCKF04-da^oI4htʃF_<x *Wܬk_պ#U{^d䛓cx?9ڒ⿰#$b'jybιL:tþ -_À{`ŒMK^z)>X$vBdX4}`ރd8I+U^C_I'ҎA]@sԵ-#ޮИ:Q?l&Vfe[ڤ+HÞ`k~ ʱo~O,KgB,>\3Wy^7#ōw; BKp&/iꆮIV_+.OT |jAW_{vWlLu\OixX?Q}ե2zı k 6d!/W)ܤ~d{څQ/8iFt IDAT?R72y=^|25)]}A|=F4I;i$&&Nbj0nF? *?"]&|:3j*MuMyM9^}M>ǥudLdK׹r9'O-9AF}@-J\ VTm.X`ygϰmآ]oq}L ]hhĈͽ:zO{\$Z UՅˆ zqe1 °W\ҞXHu9ҶgN>d}WIJ9m(cBTu}*NW  QV>-HX@ù(=U8mW=MW)}/;q}K)FI5/IծhGmm&c梟-b=ƾp?:$D[PÐrB]TU2(d瘲O9 `xpUB/J? Nm{tYcr#3 #=/0dYM9AP*#p2KebuQD$Lw` iQp1']R G$&KvB49$SeK?BlZuGp`ξFK0+:$DRؓA#||}И1)(H:WQ*KE xo_LY0*HE>M,f1w w0#U#:"bn7e/})njc@-w,y5c֤Iې;4cQW+b ӅaSXmS~*λ~+ϔ{%؁ &ЖuΉU4%=c>ǔNӇ_q'Em \AѨؒG Kjh?+C>ͤԾ_&c[^eVCcQ%F8ʹ*挕c~TDZYn6#6ee%W]aDK'D41BAP[`@̤M_ rVu';h0W/^F#ߺ`HGqˏ\h.co؈57AW?u Us0)?nMl:%v'-bxaQϺVP=?#U ]WX[<$@p6 6!1A?SO";{,Pc[Ӵ7mQ?/e+=Sj=.c|cefaY/#tMXLUiE,Y'^Ҥ-]R4atCh i{w!5vͳXa1$:"+wWсzk}|AY`wa~7#g~]k8S 4Uz  5 ;dRy|Pu+7?iiE"4OȳW;!7m;X)-iHg fl^Ǩ_V"CxUv+Jf:YyMRm1I拵x/st:vMލ8g%?Eh2z2ڴjm%9TnWՉw4$'T[dQ~*T4~{J%/@,Dq53fă ;(=~sW0#-Pb S67fXߴ52LTXY ~cNVV~+eзm8w_W}ǞhctNUV]?`o0vr+_ 96dַ(1׶vRԛlPGS?/>VOS-iܹh$Fg^vAT>#tPmNmJKɞFycClZoWE^IZ[d9α</^=hc/c(}cL[n I㾉yʳƂ6?uu=gA1˿~N>]|2Pc/߲ؑQeT2C=95F^&>X:ӠUAc*oZwR'~to,`W*ǤڲX8νa/QRVUx֝ y|UD"*:w^n܊"[bc5~cXOE9>*WGlfc511yЮ#w;-BS/_9n.8ktN q O|6`&@ |khOqc{mxքD)lK!Oj1T[ٹF8۞8ȶ;>lMLq+iʹEFUG]ԌSJ{/8+sA\@O\߹?uv#l'.yVW1sGD9^ZV|=CKCp`zK4peoBߢa˱Hx|tmHqñU'ᅙO?W M^0"!!fJ]:gǖA|OT{(LקאE% / y׳&R]*6׭GOWv%y'lI>o2OaDOȢLWHFҪ/P}d,iz[=fgC?;^&+uc~yGz=TpTosQv6 HKy$n'odYR^i#㲩8G:FrIW|-*?ALH>nXX.ڸOz^V`S.a{G1;ΙbufJ ;ixrE{x9 էZF|(TE&|܄:A_#/B.`'M~ݮ\u.MȊEJ-zOS}\lUx/Jg{KcsEt  *oq_'2H{Tljb6dEf祡1ֽ 6yʣ#a%ؚ/L+)[H3 B(J``?SJ$ؘj2;{ҭM9O2Pvcjj|]$3wS$]d.ӢT\IoCU$JGsAҿ~A#,vOա-xjTJx ۠{EN2 0#} $ ,܌9×Px_b$:AX|z1>O|ɉLuJcrK8.|g\L "m!!4~5A䳗2#Xž\ai]X݌7ħFWR[n Ob8I7M;*$&Ȱ? )1 h2> *5i8>DL^Կ+Hb>xqlgn*W3(5) }69m8iWѺRo9Bsk@maAB2zX?qчբ@g.8_aQlIWÜtu8Dfm[ ݪ͵nӋ#;¤Fy )E 87AJɲz/'D.^b\?}q9 WCq ^9Hl u$zϹ}ɶOq+MꝠ@MڐgsW2coacկLU~QXpDž\!ey,lptQO}ޅ/Dp2;r^`^Q(Yb9kg8ԕΪi33a<h?Zn_d&j]RWR_*ltjea`m*ɣ9ii-VW` m&NʉcOb/SL=~ >5:F]-8 )xljo=ʳ#F(Y_H0_[̫}qZ>%f{ͻx$NO&>'G:~ByM?=!lȰ2T H`ݟ%Tz d@RW5 8PMˡ;pXtpL.yŰȱqX˧z7gaqE xv,Rkڐ7 U]H8IW hBj[N`1R8RGdp^Jv}) c4à$n^(+K- 1xI Rxe r|J~bv^foPf>"AP}@h9%;'k#>2 :U@$u'?/ o*nƜqVq~xlzNJOmɊEȓA栠i5^Ieu7O5)GNZԑ3)E*j{ĜzE7IW\]Ή>!7 -uϠe# iVN&]1Wxx"NYuq'>ڄ,)ׁOya+3-U^g`:VAQ7Bo'Kkq z::XܲGϰo|m;mlښPrӲv'LXld>:$F,M{xeS`E-Td/@n،'"FgQxzeߗ~֕Yx{>%|trlU,[ Gcrl/Y'#x^Pc"WmzԹ:>d`? čm/|}@udlcH#KNmθz'EyK$|O䁞g $mݴ3> ۶ަI}?b]".@M&Ι`?uQge`J傛SQ٧݆_oo*dt+ҥ/L#3i녇U]z[ޯQ&v7: M[̣LUO1Hsg 8X?W^%֟nG xXM + S;gv5@EdZF"'io˶ЄYdR 8ϭ_I`x~(VGM'.tM[O6vl~nSR(@ H(kUqao FdcPˑiO$ǔ5ߊ16i=W>CS" U{'F !ʬ,O'OSe7NMrPH#҆.33V+B^ 1/(@ QݖĥNFpgQ&+y+>!Y|;t|G_<SԷo]iz>(?x[D~K 1@ii|)·ʗ/_LGcXWWѫViI|iMR1iU|q6z_Ӂ'zDb,i֑`y$s$f8qN|oV:0>;^u6n'kY􋅥41=fL8@Ijbq$:38TGESAst4t~ z |IP0<Ȋ8lƼ,njnw!{ xx#Jw],7bkѪop~#{tvB ~ag}qnmRG sR_2 :8З[ȵ>t+.DP<OQ/g]\LlX7y[|uöX"u7698^~*#|!M0b+4_)n:Dn~nɠGx#7qF`쩏x3vOI|/# N}|ՈW? O dpճ` h{ Na ' Kܙ\q8C ;d,`[O ećŘ¯AteC:tJFvKGE_AYEq8 @r if?wȃ|c:za \zmƪ8eGQgw{yQnȸQۡ aW@Ytv;w5)NteP"DAɃb*ʈ?r 75cfn +lS@\XAGCRvCnޛ)ra,o&UjӜ(F_Wla^(״7)){d3abckQ釔N|z=w076S1/sb79v߽'?_!VWm?;{w z|`{C_}}m2_]yv/oW쿼]{m+xmӡG<23m"0L&D`"0L^qgOD>z "ƛ.e;~x_7Ԯv9K XkȑGiGw=zP?mwsO{wm׮]O]odxJ<L&D`"0L& =w hLbK+ vݵ״??~=C;?׵ag~γG>{j޿NI畜 D`"0L&D`"0mOZ}~Y|-3G>~Gq۟oNhW>G7}oO';;n`ǣ'={?{4l|'cx<~"0L&D`"0L& j߷{n 3wQ{>;׾kC?C.k]s- ,={y ^6D`"0L&D`"0ء֞ƿm;v쌀I&D`"0L&D`"0xW?Ÿ/+Y`ɽ;;H{C _8zX;uTw__kWmԯw7s?L&D`"0L&/9Dti~>$gϞIӹ]vӫ\wY 7y 畜 D`"0L&D`"0\P.9S'Ooz+m%fbh>H{-mʗkyy{^ގ=qK.;OȳD`"0L&D`"0|}h^r {]r%Gs[޼omw+^?xtߥCm=?b3/ ox1}JL&D`"0L&_.r^=կ+_nWnv㍯o^WWvwk}ӟnr?_{ywx D`"0L&D`"0L.,|]sۇ>z&ۿnp׽}ꓟl7L_vڝw~:w<#y 3a"0L&D`"0L& Cm_%<p>+7[?7o}7]"]]uUkU}<o<MfD`"0L&D`"0%{/ns|;nlo}뷶vonw~WSgkg?{wy xvox|"0L&D`"0L& RK?uםymnvGo170t{9p~ [y ox|^ə0L&D`"0L&G`?o'>;vo5Nk]}sKbۼϨy oxgD`"0L&D`"0L&g϶vhkk'o=vO]ז7׿[2w浯m7oj7uk_֎?ΜYoGkwM~'/vvzT{2mǮm?_wu ^xڟ| ki۶m[(x{߅Nj`"0L&D`"0L&͛ϻ9rzv9rzil7xS׶_#ȣS,x%% سgo~o/ʶG oxlJL&D`"0L&3{x}kk/:ˮgo>>]}ڏ?kַj&W1֘"CjX8˧?'u/y?Ev{=CM}L&D`"0L& ߽HjD֍7]zg-gϜ9'r_J,o+{<<Ҏ}v{e2~_Mn`O[YYiO.=}gW|_"W-oyz?,/zyK+ZX~B/kzυ8&&آ# &hPcD15H4XDiizΔMȺ1ȁ )%@UA*$5Dvy3o޼ڞ33wwϽw̞0)0`a yy#** "s@W~/qʕ8=@Á3~b{~ёhoom*|+V-[0{ܿPP _LYr?|֔g]r BIЋRKak wD?j<և?EWg' a>{h:#-z.c1}xʧhy|]:!e3)h^#qaX9hZmu]FOK5רD3y)܌ZH;:G:PBoKFiѢ]@]5+0)`Rl{"/YDXϞ=+<@rx“`Gw. Jq~qC:GVYf8¿+ QXlf̜+8';v}O2) ?!)?TՊuGG~J;zh5)`R??vg`+8 xVfpp /ze%arKro,ߥoŇÜcN H@@i/pXW]NMgoVz}8+\$4ac]G{S]i*s߸;` JY]]RN,wKXheK}uHޞR:c ;-i+oVp-cB 4ɡJiaՌ¬5N PhzPK2ANaPWU- ]Ѳ9pr\$ގzlޥmk ^9n}m-=i6D+yQ@cs_Nl";yyNõE#ѰGI_| {swZ<ٻLjӜٛG{:eO0&M=?BA[?.ZyO2_=Գ{~F~v9W*88=| _⾟SKś9M:Fz<`zj?Uie(M 0/2苕-o*L2e [go 8w--@U(lE"+sIzsXvJx,{ $a&lo*MķB[a?y%>1WzbeQl5aUgd҃;QfOD?lGCxxŠ)L&3QuP U(<#G+2/bgyTH|f8>Dav"hD^ej§W܀ /f`o5 5STȼIDAT(enX؆m)kKrbE ev'Dd!V gGdVFߥGk`۴EYF&~{*7ԧa3PLBzMe!U5G\ּ6>mE7pxl /WU8C[6[d *NkO$@@GHס&_N{&I.9Dr+\{(Z7yv1"PA\L5;ytr5|Pu8bV%`l*#<`޷G*YϑlÞa yRQ3| 8 nu֩[jlxϩraJJJ8}HC9 '9CedՕGڴxZk#O4x҅dlFTa &$Y ~UߋxgqeQ^ \Fo7ǡ Wq8ʣ~RF fdٛG5:S4TT'| 4{G)gAٞ"^GG2Y)^"aK>wWNI&L  aS24$>4S\WV q:jiSOw7p_JY8%};&rjɘPrI⑇ш0{s޵uKwK$ܿF20 R+Xp=P;zUQX64rYsV҃{IZ!!CI9OWc*YX.݌ 1Q/)E*VoX8.gsFD*Uq(W KیH,>#V;s<"e$-}b]_h3Wɸ><qоO]TٓG-x7D[_<eDLz&bb.ov}v3"2.)><$Uݦzu!&L %Mvq˭ M/9󹜿p|t= ~:U5@+PdKYp_qJ>vmɞ/mC6ÜyJSK.7igXJ* -jaY urF*sww7!*| i cr8\ Š #aR^kEwk-=%9D%t/e64$=I\T,lb 6MΊbIw({Stc;w>~H:* zyBؤZzg )2q !'1 uxg#fu"~`3bt4@9)5JkɲSM+%v59M4A= {K"$-:)ky[@є+ 8irZi ͉(/K ?H.,2z~/v)#Pͫ}yF y\^HFs|fG}]< "_D&"[;W_8}Ҟ#ƶ 7)%,2be5T;2Iȩ%ۢߛoݹ*űtȆ=nC&adT %&{0JwfK(6?$ =%GI=]A9Z>Q?֙px C=r,(j\ړf}c38틯zJo0Wge>G尜/ǏW+_]\tN<(SNg!t1c-܂/kU7t׏?3o-*{2Ƚ&$/F3UBIXN (P. pBgc =e>C ˑ3+Po::eaYpO ] 'vop F|E~m!Ӹ9;?%n>gy7N_ӧ6ĒR|[BӧCj3g]6xE _A G.住d Q`|We|7=hWЅ'щ.ל@<#_DәW;AEq2E;᥏H(x(j|i58ISh(:Gij]T{|9KU_#w_PO_ 2 H+c ,<,D)=Da ]Gd@5*-M{TMwFCsolΧp2+;q=cxRbxn^7 5^ h{D h?o>9t%$g;bnzdg? ϭ`}u&0=@p~iBZa5e[@Հz*aFM 0)0`ѣGO9~xq|B M/!0fϮ``(pB u.^g/_st@ӧOwy0^s/|#]w݅.c=| \_ΗiԒD0 8_472 <_8˯Sd4NK64qw"2H2%}@4*)=)H!D<Ioj%g"RsaILCow7[ A+շ\]hm2ro³e!-RWA%rEںisv2ìm2- s v][+1 l1Y0~rFs'i;{p7/(ySc$QO8O7;dDI2h7iOw63V<t6We2pLJ{μ| Qt4%hB[m!Rlt 5AYPB~:ʒS^8mьҼB_+||9:zzCcj#I68b/?SZS6'4s{Vz,7g֙ΘxC= `{W_tZ}3)`R_`-t~.88rlI=@"˵_S)ʝdsdċS$̊o)KXk9˥ܷn*,.2xax}DVVTeG!5c'4#)_Kf 7SBTY$3w~ǘ(]¦I)QNRD,DG.ұ.[4!3LܧКQN_W jV#F?Q5# ؽ od2ݤSjk$6P+2."[_ (r'jq<|<Mġ ;R%G}Rqpe,1O<=2z|/NgD̟ij+_TfwiL!:?DCoi[\DPƵ~txΛhsY0F~gg<{YҿX`^k,mRI@(© ld!Ի_v۴ilW;6ve?a|?yl7pF~uoǂ t{ F`$)'}D, [ GVGG8D"5^z ?DkWX.ʺ`_Bg`E|C=Dud`'YFJ' `:½P0E5$EfzFn!!:!z=Sڱx snX`U+0bxyD.z|AK eO`ϖ}(7AG=6T A ׊;uxΛOEBwjrOӭ@6 r㽡5˛0)`R`(Llak/TÁsPYA)z111WƒBNIqY1_=O~M'?cBaf&doeX.]7иwn;.OFz&L 0)`RI&L \PZ{GW-|9?V.L\)38??cCɼ;čtSiN>yJ`hz[_hgԸge}%.eHek)@.r1 | m\7Gb&&L 0)`RI&? ;QjYtv,z8pۿWI.|?{\$]liH?YiEyXڮc!ngX -Ͱ0{L _|l?v;4 ~8a4 *zX[>AD2AT4K= QLY@* 6!B$ qB($)Bd YA; AP<eAPTBU&tAF  /B !PG#,N/D"FD!{aK,b D$R)TG"m{Xd2YC!Y2 P2(-凊Ae*PMsjMBКhs:A/o/tO ÆǨa0PL*8sӋyǬaXNVk`˱wcX:vGq&Ha\)׃-6xQ&OƟ7Ot&L'hLBO"|'BD =1xXFB$1P$ <N2422L0|'Hb$=^IR3>iHee4ggڵڳ:::tfuu}tt ][ԗտ@ aa(hĘbl\a=HkcNlΫZGC 96['?Q|~iqN((;s2)S5ȂB¦"rQJiy?J *=C8f̪\|"eA*ܪjg>ruimGX]i=>~a \/l7F6694=hVknni9Պhop%K]m2m._W|}u嵾E۫nPou@]]nZqKVmەwX!dMݻ|/|n_<0o?ڃ4n>R9:X'*Ontw,+!vw'VNn` )Ei2%R3\e r%sZv_PXDy M -J*.i3l~5!7";b:cbntG |ǧU=> %Ň ?|"8my9 Wү&hMONθ72 7Kbb>Y&~Ҽ v|8ٲm? r qtEQ ht3F3݇N $hf-2*JZ{ZktJtO08aX`tƸʤٴŲf5gpӠ+uWپYo!o BVPdpUpF8-5XTGb,ρD$䒔}ά<ܙ5rSű/8~ĭN-"aP+v( ->S]v^HD\5~vtx.nnm^jt Uk%ڥnvwv޴v!NaOݾ{=Pwx3P8xihc ƺ}:kfZqm썹y ߖt?nYs j7u~15g@ ! (MQxF!QZ ]!b0o.8g#Db!y"S(6sY|bCyOMaN%3_BrUr+s? EO%)#T+l$ +*#L,^]-")E%!#$J@J'?pTLAiTX]_uAM=^CCQsUk|O]'=i}Aa1;63SsVyk\ulmv+o`\RZV^G~oyр `carVtvL]쭸 'RRoO?w0Pdfa,l#9zG5)K?!~RJ~]Q%JY)gЪʯ^VΥ>yz#oKܗn\A^uvxÿAͬ=^˾'=&?5;O}b9k1 @)\py S%Cv$xL@ _+@dC"HGd9r%:E3mq4bNK8<.ׇ kD^b.q!ɘ(XDecS˔`"5%;k2`gfoPtĕMny B5BZBEEzD}b-4@k('% d؛˦ʽTpVdVQ*TvRTyڢ1٢BS{BL]OoI1ɢٸ )E_6,vŎ.ܮnWNYhY◈O_YXH5ud{l@ː h!鎬AQD}4탾g{1Wx.[TBaEc`#n13v1i2Y0ّ% `вp(BC,D\P|V*+V򐔀Ԁt 9[rEK*e_ߪj!ښ̚Z={JuTuzmG Md9LP&V̿XYnYclm-<]nθ#JxX{yU{1 ಐa#Q)+qf ]IeLiYF?Wc'NvΟN*VwUU:\Xl( lbb׶k;:oR=ۓK7|?G O`610B« 7w?M;^޻ht/.+W}qwۺІݯg7_f#퓡eD\I@C9w0ژ{XK. Wt KǘdLb 7SҨ, p'^psvp>s7/[QBHWX]DETYLI\f(-)!&(ɑU+ijkQOD ^ÏT S_\V'Q6vfnNG\\Ϲ;1}n?o_0|ʫ'1E F)D7݈7Mx䑼(;$ٝe=v5bœO. <<Quxt-|E#wSmPk%Ͷ+.WG\va\?7x>(2T4xd l3/S_|4mlJmZt2+Ec ŧKe>}TlՕV_'=ڏkkQks?>\W]`Hݠ2wMͩ-խ[sǶ'ߵ\n\~.ͺz8ـJo?fRvQnbޥ|^ pHYs   IDATx`Eǿ'$!@h vvzw)g ;(E:B %M^K#Qfwggfg?73@ a6>@_Y4(%PJ@ (%Pnkvt.zce4PJ@ (%PJ@ (%PI@ p:vxTW %PJ@ (%P6?Z9u>qizJ@ (%~fϞtݺuk0&PJ@ (%Epw6$J ۇk"''ϔ#c -- Cbb""""@Ƈ 5\f rsYf T ڵC]UOf7J@ (%ZOpZފeee[k~c7mdNFּ ZPJ@ (.r!337/#mڴ1k B[l3Fp! 2$_Jh#F/,,WM-s…L$RڥN06l2_㕀PJ@ [W^Rm0lpřH!))*%PgCvyf#ҟjpe]`Ϟ=+F111afYYY%--˒I&OA>Sޞ=9& ݻwotVSD)c=󑓛2SϰPJ@ &i/-`"c@=ٜcǎf|r ª/>²}@dE}"4' M *ݎ-[7cò(}.]\|ֻ`\A8SpXvUitK (% oܷl.l|oJ50**4vחI__(..[#M?=ųU1nmֈsVgEI_`ڷoo:&첝,1\W&Ynwmr[J^SC w.WJ@ (%Z̥E^A1J31CfF śb)FA|p2,zq|"=حoH?{<gK)|{zo:=PJ7HzٲeàAF=v]^ "+Wb޽6lƯ+נ@vvq/d?h57_F<.l߾ X&/y|Wr,f\hS_;wDrrzk`Y82Ÿ22_㕀PJ@ 6Rz#6J^w`k-h W\R㮡@zÃ^L{_cä́v9e_'|!f:唡GWĥJ@ (%"ݻw#0]6VٚFYʛ8 %7YYYf?V\3pzsz?n3O}YseXngUk^ $ ܶmyV]ChXQ=J@ (%$v47 ~ vUYge{Qs!()܇шID|e-hۡ=~l K)'%PJqRRRPTTdOJJ}i9X>u۶m zSq|n=TX[.Յ&-Y" А t5=J4L;;6mPe: N,&s*>L>Vמ'H])))UfLDL wL uIKFcˤ@]1IJCe+%h-sIǛ.9ǧ~#<2LR"iw-#5):ds˴"`s AO=<hOB3PJ@ (%{hwu&lH[QφgCg+R5g|btg:O\_ʤ>NN)qSNM. |<[zw zL (%O wyY3@ހ}L+bHWWp8fO)%`ҐI|k۵kWz2V5O}XcOk)k8%PEM =ZWJ@ (%f2XMVYRU_]+%PJ@ (%5h @E5u?4OCۿ2=PJ@ (%PJ@&PgZ7%PJ@ (%PJ%iB%PJ@ (%PJ%ъ)%PJ@ (%h9jh9ZPJ@ (%PJ@ (999(//sFGG}HHHvLw2l޼֭޽{v͔;bСo 2uclsjYJ@ (%PJ`&@=C!&&Qt2W+%"[eزaRڵV^)QQRrnW@@[y#e˰zjt">><].9]bȑƐrp\}㯂_" v5WDS*%PJ@ (%P/+W"==z6 = ĜMOm6P/Pd5ЀѩS,ZYkiv(B,'''عs'ڴik0uTy晭yfMݻwW^rAO cg}v >#Fh-͞ 'WzWL`ZPJ@ (%^,Kg\Q0En hu5jTUuMu8C5v!a8QZ!JR4pժUXd׽{w+A5+ R{1ɏ޽{gŠӵPJ@ (%P';kdŊvm^Mgtdt׬YS^__=#'`2`iiNBT# d48bd$UE=(`>#⤵/ [w2S >8.ɆȒc`:&oXZj)->q-]~O?~+lѧ;;!RRR8l")*[9(ZhM:a x>;ӧOw]AD=` XչsgyN#ZvPJ@ (%HoY3:8#l;et[}> gVkIs…܇ؠwO#Ÿ!zƀ܍)L~(Rvk5pzV~е’gᓱbCf'ߏm/o -qb 6yyf pOzBp9M) ";… 1v|~Uvk12pX_ֺ.+hPJ@ (%PJe P&Vx)w71Qv G(DֱZG{Z *Е^b -J#ք8 ȖoѻuV:a̳q{*T-bH: wF<=`|_YHプ3am[[vAi&p6 3")<~Q~_폀@A>|R)nٲŔ:cK><bYbcܸqȚ^>m*&7"07L*Qr,A%kҮ~!N?@ξ4xe"ln z$ExB#_e.;nErsysNQAZ}sDosMqOO7 Xn1pv`Z. ĒFв$Z%PJ@ (%k$ "r@7mSSf;wT\t =|_.SH#].]Xط[KY3X\8! f<P _2>?" ?0wj] bNإu/Q:Яq+󰕛vӚm %*@ ϾpY<%#_vKâ5i)3BtiWro,mG>;w-Bzwr= >@'Oc7 \E…8ssx J@ (%PJ@ 4f[!yc4RaSƂrъAhՄMT+e.?`ǡ`ҕ1XB⺵nhm`@;z>I_.ņez<,]P$^.@s]B\&<^ڱUrӃqҋ۸wp4H}1^#guhеPJ@ (%P#@7w!6/"e2YPί1>i`ls|/+-3q ,[ ?{ C K5_ UjtdʿnX\Ry -@ŊZBʺ0X7'>h9チy9>͠4 A iӦNkR_9f@jq3%J<$D6Ek0oX>=rb֝ٳW,$=CrL/5[lӳS%?رÌ18>Z:+-3~{YWV5/"tv }k] e,cAz-^ԉGq|xe.B)nÃol I(ty2<һ"ZK۟dޖfz}}^?@! 7Cam\g˄V~B6G (%PJ@ (f'.Ԃ,AC-3\ ^< 9U#~NT=]V< iszB639"?L39"X}HКb& {` 1b^==AX!0}y,`tCDkgy})]#`9;$JD! ^'d 9c5'u[ |V,Oc5vy9|Ygff޹9 d`9̧A (%PJ@ (#m1@7pta%^bD/1^ԛ4x%~k#8`;ϳ'?8`xƝrPx$^l5?kbuQ )-rs!"38BP[p)XvK裏p)dGd{c6ڥߦ 2SXDI_-@AY|H"2 8`;h=r`;|g9RbZlYpbyS&- @q83iEBc<_iȲ2Z (%PJ@ ("wwh>  ٶʤ%2`ECӚٹDIM$Os+{E)渥 XGHMln/}?-g "7#FkaL/f/wȘ]ɿ?Zi‰#۷EVz}dtV PmPhq8`M7/z%PJ@ (%Zzo&6;Q"y2\N69*ƒڐSF߼#{_jCjwѶ4WqG$ʜk>|K'&]$z<XEauVIh#-"l !˜>UAw&@׮]+/..֮E⡇"11N*tyE."!3$MXmAkeX <()ڭ8ea-.t , XV\PJ@ (%@ ~|P:f;2FO--eQ2ඉx7[OP'QTbk:1w^DRWz cIp/ IDATpX_75'j1V.tΗRM^?ېI üp F# RFA-mS` 1cN>*mԩSMWJ7x`3u0,igRDyЌt-w~A ܶ d;ttVn{R֪:ʂ[xU ̰]Tt rq7hO˼Vw _oeq^Y~n1ꫯf޽=e`@r_%d{iv ~֠u{u{xې5r?>֗ / u-] (%PJ7H3 @iKWfw;adỹe~7ήaSBCP-v &^z"R&ؘipKKZKKK ڬlP06Y5_p!lbZ'E$ FNCNAQ\ fCS_#[>C֭3Yj>cZ+Z 5":+%PJ@ (_jFzRPp$-`޿:+ۢ )Z]5ݪO s\ͥ+6[gV\NfMc5p;9w(:b52zp ;?|vlB=ʁmӑX.hI*X"̸|ɓϟ%PJ@ (%@qƖQL4V֚k *.bJcXͅņi)| &LRŵH9k^/DLGv5-5"__ (%PJ@ (%ZPJ@ (%PJ@ (pYPJ@ (%PJ@ (%pphcVm(iFfΜ٪Uc[v5E%kas6}II J~&&M&MPJ@ (%K`ߖUXye2( \YD9eff6P/>y1Z\vX/^y߃QXn7),:=ց9JQ3Jاbe5/u vkn[/8SO2ft~f pf,J@ (%PJ@ 47oLLf3:u6qKW7O;UV)IWkL૭Cԓ O ;Q'0!ayPJ@ (%h MYA*vO~{vyXřƤ]!Eɦ'#!ƃ2)(ԛDzB6NZgUf%Ej-fT/}7B*)ܵ_$Zk$"9\ی+҄%<}ŵ1U (NiѻWb⥧myJE@1zkqj220V.>87QpMt sk2b~|'oۋ{10-&x腵=0xEL0L~h`'L<}_ ^DDYǡc$Z%|C}؈ M\L{{:zFzH;4\^q=`u45VmWGd?KŒKgn<"uƽN|F /F7ʔklêC  wF0XiP}FbإhKԩc4R^$aOƀv'".CrlC 9 <:as#5IBĢp9ȓk)xH*%PJ@ (%da45#VQx<0,YU?4q?\pW6V4ڡB1UņْªY/˷7c,:Cp;omR#0@L)t3^~쳦g+GIAl@er^S1;Nvd^<rW6x ծfz?ʊH{X=,_/JJb,Je2N[/c0?w=Ӱd[lᕙ yӣN[}bդBX5=xq ~xj|t729xp? ̜x)j|9ȸ $6S__Fhk>t8Rc,#O0} +QC w#븮PJ@ (%hJ3_Cjk,uf Gzrt>#8I~%ᜋ.t=6 bGxʊ{7#|Stun|(\ Q8XpI8󊙘6#ƞ?CLC\ $ԩc̑TzҖAyIʽiAMv~ɺq%6) 66"#/{…7*V.Jv5dh+%=GB<ĥvDZ ,q&=Fvs֊C\A֯FYQ7["wbGD2hvVꗫu.&y%}4fmA yvSHʪKS (c\.֩b̅$6nAqgbTpK+}ݼcP Wb7JՊ5;++E4#:&ƚc^β2.2m݄blQ?Ai$1g\ Ā>!c<ŧPy`4_gغu9;~4E3v8nL.d9 RPJ@ (%8 EmDVv($ X7 i+}XRxm?& |4 .Xw(+tkA;3_Wl容H^(o>6mW$F$cgb/[}!"aM~o~4ptH@ /Ƌ.Ë~a>H0z*uL{F=Zq8k&Ѵ8GWA0ƘŦëdtGI{' iwJ7qQM?[Ͱ3pp?I{+)81 IwT~ >#??<(>:wwC*lѩq7@QCG4gu:>\HNqcգ  c:VM-OM_,C3k):].B[qm{x7ǨߍOҮD:ycgxj*n]r[gBe;FO'g{&ɽQ!؋bۄp!ii՞wc+ o"#FsxL[,9W8>\ggٿ(e[Ŷ3*!hJAynv|? ,}1b~,w/@z{ԠPJ@ (%@c80'tQ6+4i+e:Nب`ot*? CҢiq/؋!t3Z)h_8cNE7ˎ@2UJH=Tâ!m.OO\0Ȟm܆6"˃%&^{ץD?跎)' VDĻ@lQq 5RJ@ (%P)gt>KMeWhUJ@ (%PJ@[LM8 }?dVf9Y8&yU4u,"jiv1s@UR;o}ڱf 7PA 7-EmZn>aɀr _%PJ@ (%6i-oxZy׸yfEROPJ@ (%PJ7NjcWJ@ (%PJ@ (%ppp~5)%PJ@ (%P#PJ@ (%PJ@wSQ (%PJ@ (%o-/7GKM?zNjļ۰ dG:숈tz!}0zhrPJ@ (%hf0sɦʥgkt_ ($5xt#Ncg`H($9d٘WO7S@(\vqһc Xm[j{ڥk_:L.~j/]=PJ@ (|ظq3;>Mٳ;NSJ@ 4@ M]_u}jB%'PRHtyS6c z~((E&G|eXۈN}:cQ2-[q&u9*пf92=|P#@ۦJ@ (% (ƷnB`YO?иƳ"<{h4gSJ­9E~a$G!#-٤-˟.AyOa W!1.*l^=@x%JnxB<IsFO3sh3d(n eCsw%F?b۔a΋sq"Ɲ8L-1Y| _ߒFݫnެԦEqbwaŚ3h %x_8\uٵjo& j͟hoFMh!OZKIeG+W#@u2E 7sFWv}\tȰ>g :Μ҆!A8'cm^ 6`.vl1e"cbg2CHӯYuuO nڢFAG{[b*qm6UDtg IDAT'<䯞BGPJ5 xD tsXu\}IxWhiPM9s<|L&괮Ua[4&|ϰlUJ@ 4@ {? y!c#vIH@ ,oG└<;yye\Dp3Á-@(umm]^#ЮmOO?0+ЄeۖJ񟛛k߰aCpPOmM͈1{7b](0y^ꩨRJ@ (m\[g"7{$Ak$8d~6ٷEtLH0.x}^dddnu??\]~Z $xA (%\2}aͧWi)rv0`3hG8=@ks!@dr2JpWObcduU'ކ6.ɰِTiń/3q}b +#m!aZ;}1s#S5p{-g׮w aDP˶"W<3׈ky?̸!L9P-E-VݶBזe(۹g=ܝnHIQNYR:&>icCdRwm']#%s׺Ъ6{>\z(ά, | X7EĿt:iPJ@ 4@_.=a9>-p bw -2pѣ4_HiOOm;a4 K؃˰pE6b]f16m,rYQ+>ElHrby5?ڵK^! [ |2OXNs.=ZZfuLP?>Y"Woً5{{1ΓA (%Zc=Cv6,͋!n21&{se\މmǮ t7ϔEBSS^mStFG`wuGnQ(ڗsΩisr ,sݣfOp=6tӦMu,^!s 5a{|q~qǤIx8,tW^}?lfn_LysέyUPy3ǟ17,٥vͱSN9Fϡk kZoA8_c[k}@rjO)&zm}f} 77jNJJ[=%e>KcnV\yBҊn`/"lKL1 C?,kSLUgA3g VٛfkgYShK 0[~=ȳ裏aرN=yxZ- WҥKqwȑ#aC&8L 2}EofeyoˬSﻯr׸qbcb#Y_:tyွH~zؠ@S k,Ơb⍵Ոva۶mXxIe'ɓFvI_߱dc߾}k+{֡#F9 ~i1ZV^f~hFN!E9]u9~ 2Dt7|XЋKaCR]3jժ8SMGD8ZA 㟯1::Cƿ|O֕ 7V [7Y_j[ڬ /k,sg"+ٍ6"\ks } Sцxv]7$-.^X ;\.g!ݐD_>;ˉcW)nus:I{׮]NXTT &ÏD?y!-޹窙(ya%@񣳱)X>ۈ+5Z<bR'}%h1lQ\C:ؾvs%+[i_|xẃwn_õq\Q7~ӰGRs2?U?#‘߬+**Jm0XԘ1cpaa"FbСի~\CԊ` C Vg"s&dm}lUgFGE#"YߦMl޼~.b!{VhSN9onh}ysýXzvVg{'y!U+Ww^UF[a^$VWNvk3:N1( PZ%6ovZ8ck}6`gk:O߾K:yn:ӑ#OOIw)_|QZggη}vxe˖CG1U{]by4(NbUޗÝ;VoAzVXF5zPG!9-_>豕w-WsݢĚ0K@EWVe\ .%'O7ߪ*1ŋAl鏘1#|x`W<"t/jB!_s?]s n?c6| +4~া:uW_yV]c8 5dmބˁp̙ ܞ#.˗/CƍxGľk<[dλo%_"PT+\]s}qYg 拇6=9Zb*wGZi(b0 G rs>HNϞ=0pzTwm<lK-?ol޴<1RiWglEy0=xr}wt/CٮڶQk7 )(`oؑ~- ^}]5&Eڔ^z w>xc|IsTw hxif\ e^SqCGU8I+K64PJ`%]~Ub4h\?2ϊYbo-\enYG)-t{{o ;\x<̳xgPT\hy4żWxc3M8a=Rl4Xh Ze=?vCYu,ifw{UkwĺW3ꪫ㏡ .8߈˱">G!Op駁 aCHE`V]SS0Kqg 7/_}UsPtX;:̍gj ]ѳgOX#b>~^z%wɺp".!.yy(CFm% *^o66^~e&I}Xh|vmóh<âE#{pػw4l>F.Pev1KmW* VMSǟTǁQ齐SпV>z/&d&42?s,?MWx} ONN-=]z%&o?|=Pxܦ?o.222 X_65˲)4#7r5zKλkϑƢ,}bKcAiͦjW#UVVf,y cd ]s}hJJJÇk>0ָD\O6 }?W9|Ki#Íˊ^8d{DY[{THڨU}2cV/w+G`>&PnTPJr JKLoXRZV,^_J bcik5qFl=+lAQE-\-X%-P{lD3A^۝tJ@ (%xn5K~ўuޣ=vMyZ/_o4SqWê^B`WDm]p(/wItGWg~7o$ASx̙g A^}#Q񗿇 )KKZQREbk?ճgШ_v}Y^ו&v>c+bn|1bDeiǎ=:;belЃ$cǎoSObk6à+ +z޵S4//Vvnl ;c;8Jє_۷k ^5ym@uz,Y1Mtht•-ޡ3oċ'}=wq㌎٫<B-BJ K`w /74qLb`}]^/-auRGݤ.l8NoeL?4`,z,'FGKk˃o>fO 1cs;% cdYѥ< |N8D# 1cFx(nY1zi,<ܮ ;ѭ[hK$u>Ĵ`/箒} &c~qY&1njŽc/|oˍwVf1~<YcŇsQZ/}. tzgqF/>|ɘ'7k 7TmJ6`=ֽd!+X/-~sIbyYGIϡ_E6ưO08+u@?n=d2xJʑޮν@a9sJq;;uļsMKHRRr/))g"'LXxsˀJ)gǻONߞDZmt"]"Z~iZdw{} 4k3=2aXR#UIJ@ (%$?3nUHBj_8u^u6q.lihG ;vo37a̡44fitkXZ׮[# ʻGf𡸤tޙci\bHwFV SO=ټxc_2,>#i0;'g  'r \}şB yϪB=@szciy,;b] iyǡ-M?YenڴFk?$#IJt]R>uѵb-tyv4}֮[s@hƾz;v4kJ6Z[{ñё=`Kqi"#mu!NV4tg3v JWxl&TJ@ (?[)CÕ8?bCA7}'??)iɘpr  ol{w6`Kޛ{z~g_LL$eU+D.m]ؔ *A_` eW+hAi( ELeMcldޙ|d2Ĥwf~ys统QVwG4D郺 ص؍O^y'˙' =>+}pܴn}?O|ޓ=cNfW ܺ>ڱcÛFΛ:/Sl ]$C;}v;^pRd+?NO~4c/ϯZW_'Ew003k};S[7+oggc ::^x8× \ޓxN /yL*EV_+óuiKc>ɷ+~&׵}gkضKV?c~NԿwoK;|$5W쯦o,_I>s9ki>byO^yEJ1?yo|U{2 u,'3._y}wK.n3fz& _3q"fu/?q(¾o|_Ō9.,;QXC0cLH13~g/(|oRzQODDi= "{.{N(}g7_{ޔO:/r>M衋qOش(NpP IDATk;pwO|h/ nO\6w\Ot0|&~C/?viN/[_ї'` ܼy{r8ŏOpF'Qrǿ>[W{r^W_đLw<>ϴ'?;[wフ;JWNk|^X(rِW_cp9FAtֶ qW1|wvh>R lWFwӻMsyOyJ;xl}Ư}q}ӓ/`znh FO϶!Dcpbk\≴N]wum䎶Ļ4$$SfYIٶe~E:` >۶>DtZ3!PC 50k`wsbr[_cŕޫ W}7_h{?3.b+wwy~ޕEgr`ѝ{9m~Dmedo~];^{ewq.Os)O~rz&;=_s֞]O+kPѡ'펁 8ԗgxռB]gv3[< /nYcwn yYwH祉WH{;Ukm|CoSF{?穑W^Qk(m-- I(o|-}npUmԱ6mյݽ5nfC[}e2]tH{G۳} ۭmi_Mh>ᕗmϽ,'̫xU^O1oskWcϬɬ׿7nmjo~;/O._z\]*~sg뾍~t:m횫^N;'M8PC 5p4vaqRO^Sk_ۯڙ}ggN_{՞Cpig`OkW1Py+^^A| oyҧ_/oo{r3v3p, 3ǦAze{wjg̺?/śnh7S?v1p4p}'M2^4p阞[ .Tk8xt%@n?8n{qӆC pyϞ9 90 /} lkiVmG/vɶϞ3sr;o|45nvYm sNrVvxdEknF9mOl_0g(]np <$CMٕmӹK^+_p'1w\:xk[:O"^n}kSжKw 50PC gXFY/3خVa1zW}ṶgfQ}A{K?4~cq~bn3-noh{n^`>ns.⦅1&֭vXea|f;#m^k9_6?'&tLjQ+kzkyoԟvN砟]gj׷_;ЎvՕi?f!ywo/ժ+Dôj`{ɉZ{s>W|ԟxm_v7"\x#^6dA܀ZA@^Hnup t4ajmkyZiyʺuK}޻;WjWN4v}ȷmٺ[yX{֥'?i_ WkyH]=ऑ j`N'w1/lgom@a%w爛aP^wm~S7}`g$WSmaYmm ߾}Y9ᄳfg;P{ӡCsƫãmeΔ# >a{m)9[z2 yrm|cn@>NT\U֮410N+k;=:PC 55?O$gϦN \A~ʄĽu&.{nW~=d_8:g+:.b?MЧ C 505pi羸*㣸s쩛gO>^z90f5~ϧݟ6wa?_JbbfG=my>͜qֽ!qaEe}G+t<n?]̟13 8I kW}^/l*'5HgN\0PC 5NdDܮm+Þs/o_}k޽w4vqXuïoП'說,Q88N,|S\U?vփ' my]ӑ_g9񁅹 f\{9,  $pLm96,G,i{t42@?"z޻{xom '/G-sd:SflD-mv^-|m%!ӖBɣ2<->c7?QEX[G}E8|~'p'J[;C?+oQGˇ1em?fZ~GvNioL?2}v«5W.#EtK|ltėtԑ9'BQGO |Yoʓ-#~|ʸ:2.փ *jut$F ok+|j0u*}D$!+p"'r/ѝH2jOuaˎ5\ܥ6](e u8.[^}W?M{OQQ+ʯUOzkv{? __iYo|&}vNj_?6CzAa9G_G,>ݮI]n=.~m `KL6W騟J7e\6>2h3nȓf$ܓ'iY)cb9maߍy(ʣ 2+LUhc6=ZcMg;:-Yz? :•d$}\eV&4u  ?;Ũޡi62Pi*GMŕPi8HsiB4vHc<ʅ!¤ڑ햽3O fa n0ױ@> VсLVeHX4υl#t?+RNXtY#WS}:2+6HCQ{eo|J>N\dV6>%$S[ԅQ+ By)b_}l =5>]wbήnA(o@c> %`)=(J 7`r!FD7*EȣybxEL ]|&Tk}P2щ+rs@& xL|86i&x ]y[6>!amٔ+e.?s‰"XZ7E|S@2Mt"e䯲8ʭ:Pt5%Lo北`n:aBCO^H}¤ c`+#pv~TuH;@l Pz|y7u@-ya遻дtuLYky%}ulL=!AOaG'qTo M  ZQmЎ Ҁ+[&! Svԇ}:tP`C?ݘYD~ȓ22&b{# KNay/f/?iy`k l0O !d(Jr ZCHՁMWܙIrN'NW2сO{U{f|F~Xveh$6t2>~N?#.6$N..~%NR(6 '%2HMЏQt{aƒDVa2XY'D%g'b[xR|W6+o"˹l 巒ȧEPX<0xS[{,xK)mr Ǡ&dFE>kL N(+ kԁ('Wu/M2೶ɭd}/)8U >c LОyF|gv#y aOkQX}2l[1F62d;N9@|90ǘX m9.WXtgҖ %' zIc+G>دLgb&tc4 ʑa"ͺ5/ᅵ@ x';'7r%hn\,@ 0ɖ]q$[}/n [w6szk}XR&lɏ.?G ia$%ڬ# mn6{t?raz ϊ z5Iَ|02 zH^jC}4x~S@E'DoMY\~)c;g'stm*[?gmԘ|0|GqO_| ~QNA̚򪯔m1K ]D4տ|@k?GLSLNDG.R~d8S4=#LB%;I [bP4ԩOISݐ7tʾ偶kin_}EW)i_pKN/} l<SlN"i,y2^>3/a":9B#dz&+Hbn,8"àA;!heg:kgyנ ( 8j05"PgRފ4WX̮nTf2q[',r]U3-ѕAHD[[ς*.qOGǰ;㓜J2*qU)+!.J/ A ]ʫK/NuDi0OO<|xB:yqձŧeK{bg^q% S)X 2i&Tz %yAt(C4yj׊'I^Ft~A 98ƳP V>"S/EGӦv K}۹=^)`JGQѯr <4c /et>D:=Px#^ > v5j'R;ҸRI#Q, dPw[eiHrvl-ֿ"\5x:I[F ;(PnSɔ|}b'iY'98w IDATdQЪG.7vDBC>ggobQHOu~;J|V1A q+Ґz+tM';V4]¯@F2_;?!r---'$qvG?!uli u0_1PqhtmhC9?,[vA2ū ujGO ES[NxOj%VqKuf.yYzˇ]ӾU3;N) }];Y)eNܱi'<]z6\#ⴓCD&hZXd`VuxhK_^b4|' hG#0`K'uILWπG?$ YCp*j|lnOnq?NvVn,;N`N ތ5(~8wm\㛶2q ]˩|JT]Ng~] 0CZaV"SЌN8ږ ز#vC$<&뀁ޣa R%vVzlƶx4,Nfg+| ؎Y7m  u)ΖM!QYZ`:;xD3[> 詂cZ u[<䪸x`@uz,6t.黹!x ձYT]IӌזvՂ~3a||k Jҕ䑮zTpv)S`IPȸگIy5rJKxoKhN4P#oy>&&c2leɣ#)ȯues䟺Vu^+HGMҎikyI?`f]|2#^R.uUoQWҿrSr>E!ֈrKgvⵓ[zq?d3rc0fVQbΐES6'-LN8N_7\6{p:50 x&YagqmI*yg5q*Y@\S.TeDQh GUf9B*4ePi Wd_U/*Au QyH+4z}utjBIf?Q|R Ҭm@I˲FP`ՕWix*PpS3F*Sp awϳ.] Q$ë$v:@W: ezI!VE<@g)"9W\ë,>^>^̦_B #1r:&= /H lGVqN4譣~ctc5߾~ | 2W*KE]7ɫ\#7Y v)uB0 ,to'í^v:՝ ֿy9uUK#3p⮃OXLj?L>J\A^ӁϲUN_IͬJC@ ."H{n8{ѽ~7~CVaIѡԏn}U-gtwgMY> qMoϮO8(cd%cNG@A!RMoBK&"a;25gXVƕ(PBH/‡6:OG=+ C@em. oN.I&餞FQ]~]Xƿcw؆mw&&HY`|֏el]7\աu?s"!>4Y=fP)ˠIʦ"L6b 6e:mvƱ'tFY*%9}vdd0>5 ] 9EȗOq q²5=fN6=`k}M ]"}!T0 M}$ҁ#?I*|fUY )mFdF_{ڝc %.3U|C):rb)f^2lަP`Z?CK'ueOt _^QLn޴y>[ֈ~MvC=t.);DEXާD$cT_ 02k=r`]z__@'mt~W\\;j@1ȫ4!~@4Z-kҰ?QvbO'i,hL|ɠ w Fa "_ҘeKoM󖢨3i~$-9Atp ľnoFweZ9h PauZV%Q@קpXEBk^*/yRo; NN%1O@íUM!^f!TqU'jrdcz2Y 7xŶx ,b@YwPFz4TfGG鼄o;jmSl:ґd( P\3MJ[+q=9ͳ*eQ_!|8sp^5Հ7)l9sWti vJeG&t@Gٝ}=3qc۶}};t;,'鐢|,q0`M'P6M4em҅=vSVܐ: <*HmpˠƤC2ղP/g) ;`q {JV6aY)lov"_<Ȩ%}tJpO.Z^Gя::YmmNu>{ b0\]ޫ#/Nm8T_ Ե)Wp=`4W J__\,/[4㬚'}reb{_><*swX:SWD%>3m)<]-{dX<98|Ë(~x| QH_UR*$ q*F);7QX`Dٽ $-FE U;YlB[lԾ;OUPQf/m'f7f;Y~a@'jϼ>D`7vX`.NA38R8 i^\ć?w:BG7V5VOo:2:^t!l9=ż頄VHYx`'ŁvAX.mu5VGz']0Lϝ=#ro`tD|2Y'e/υd):Q _]B4C,yWHʗW_l.pKizKJ_.(8U o.Y„\RvDzgfxx݅I:t'gʖQ}HǃD;z8ue'؝tM%I[BS6T$}}d83^L5RT(hcXĊO-t'p:k)f6nZ-Gim[3?8nD6s/1L}(#50NQb1>eo'#2ԗ ;F"=eVOoVE] I!hΝ,KQ'S_HLM +i#/4I+ۼ ^,lUuWu Lhs kgO<3O <%AcvE?K,%zy< :O_hkV'SO'5ˊe 0g,>=V:qZ۷}[e}y`Rfr7H9Е͕7?Kq͙ LF-kQ۾%!9>6HC 4o:5)A.v%B,`9iI šP)ϋ& O˿}."f9PGY]H]K?)7,ԫ Roq9<NӔQ^ l3=ED{~b;p $-3Aa>Q=ohۑ/x[&=΁G6W+2=r/|E JO{vo;]C\QW'H2I?U~͝:m+)SNCfWuHY /{fb)r|ԆS#iY'[Jrs oH>&N ~͘L2ήE+CҏHSy4V}e _[L@'z.nč c@.}G>>yW鯗۾vbIX]^ůeɓ4,2GvrDMt/I]%̩gv+m~JhLɠ=lGN* q&? 0P(~\;gN+qr_XVmeO@f_)"^_%%}!癏!vJP s&[OU FA#;v˜ \)HœB*h ۘTj& T(ڠ\^ B:"D/hҦ"N3|T'ܫ*,)J(SY./PpKGxug7Nnz dG`CS#d[5RD|Бut*Cœ9Pe+^RA1cdö($W78{HD=Y*U ͮ? d^@ T*3;[]rhOxLdFƾӇy3 fGV९G|4|!K94*WY]?7ԏe`~KLkuWdM?֓v[asҪN4I0] 8cjh#;h{_5H-p$gsڠWclҊ.tLuuUohߑѐy!&wɳ:9fmEvf#2&' Εה`^e׬&|?J4SWiștrgt37J@ '}VT,q4qG4cGpR2s:ܲ; &!|䛎؈恧|y`_ߋaUգd@E޼,33Nv3qyVe?gkt=$tSNkӬޏ<_ r HM/2ΠMc<):aOl/vg:A XP5{6JA X0d,<UY?~UmBVʝ@t*lZ+xrX!Wt22x0_ʾzѯ9 W*MxOIml>n9ӾjҺ7dG>IپW&SQt.\1&KYze[9tr_i\Ȩ!]AtLk0sW g0 OA7΀CM Ht|C}(g:yK kU=}:2 tUr@=7EȽ!8pR^8sc+U=@|*NQ!;$LN5?,$Pncv(}./w#`[iPVE~AtJ0-b28Cfbd+ZS*1=U ]Ef{"&;g /圠: 0k &>x[wQաr ,iy3+Rqe Lĵ XHʩpJ:/A.y5^ !G2)rh}!4XGb\ 9NtnA`seDFB:0!aVrw[+(zVo::=WyW\ͥc"8==խ6O29" }=g}v[fN:9ԑSVm -v # eb f6я/yw+[ΖL!:2oUJO"U&gE/9SCxm-v~hyIWAhv"$#M+ I& {%;em|kXhـ_ p),O<;APZL4b:%2!ע`O 3NNR[I,'/:JI3dG-=SGu( zq0o#;γ]!vp{Mcv`舚k".շ|"FO?di&۫0,罡d9٩Ы})pw5(Xڰm߱fZO>Lhj8$ 81ђUFyo:;+UR/;q?If@lQkOٵ-ޏ7B˕gn}2CKlG hkk`ÎѺ ;x^".mqrr#/FW NOIbwH tTvNE]:2ʯy{^IO~2F!.t¤lW\~sUI fr2:-|asqAN>}bIA1Ag#Fg Geu( N >&|?tz: YՔm#EUE?N 9xq j7#ַS䑧+K|%,YDrP儇 U<9b7Ę[?G^rs2J;YUK|2m2&ݹɢxKECr/Ʈ&]-ՃbfYlz/B*g~{tl$HNGB7::yoK~LxpFN>h/`WY?k=b[c!)+; ~yNfOTg(q/bOEr~|!K;W_(qGwΚnKa?9W&kW%5ݽdu8@fe (Q@PJEtI$ΙT̢J4`G|4LgCe4`ު֧qd7?jkY3v=Q ] gq]%`vU>*`ADj+Yt(#]}&pjV 0%Ty ^Lt3 *8t$)G;Xc;א[e5tq ^4#/z)HNJuP:^KZ!C^3]HJKc}dC%-}:Lxx,6Yi-F'42(6Ca& }5'uDbe*ky$9MB~[VY1Ajlt{ޡdeY\^+3k9 >;eUw(dneήdTV=DGQ&2ST9 *Cy(0@E9 Z^S蕦yLF>uYi=|*yS Bn/C;+h#\NH]]m3QJԃy>IK4"#e#Iʫ$'| 0hz!:ɀHt;}tX]:P%$=y>^#t +T9:@}% ~C{0:6)8e@d.~h/0<[ IZɤh=fmpo :yrgxʷ)@夊qXIWZvԔA,~'Z vȯ;ߥG6)OB ȳ@r`o3d39v՛%R6ÿzGoWw ߾ Ȣ/4A+Hw@+Jɟ&kR{F4|_a:@ٵJ2gU_g +bIΎX2Cph'|ɣo.efn *nq#E8$:* @>e?t6R8> ɠzp_ ^#|Coo&c~B_.F(+"=miA? Иٱm>s7HF|QQQ!`?l8~9&usԭ ^x5%cv0p[ 7T|i,sR6i j.Wu@WЕħNT܃._yu22Y__]ڈU|d?8OV]ȗg!>SՐ:o3!3>?+8w  rMC+ӼL M┆7^&n/j2P NmNyL.zc ;lRY' s&Ԕ̈C]:RvKy ,iޗ3A(oP.Ză_ClOEʂ.Ǎ]WgQ;<%/SNj(Dt:*?2$eBA~OĉCl\-lb9&Qh1GJ|ЈQ~+1 !\u}I-%qXxw aġӲ du|^: BaH7-U>(*{KXqzɫlpL~ LȖqrt[Vu<֊wِ<"Sg\B(ߝ=T|!"8`$ips~Or)S Bţ;X(x[}g}"J(ɩ^HӮ-VJWOK&/T0ʝ앁,k^ ެ,_p%:E=.}:̌}guS=} 2GgˋVʋY^D) OOʯ:Sm|3m"# ;d b6y&e(UHLsG,h"B;2+錮lb?vԭ:AWīm2Yw.<9PP,UthOئ'YgF]at*3k2Go~CCۑYg'E:FLD}j`=>Ke-+sj;03r]kiܖMKћ$"yq 3^~W6HW>էmsmyv2@K[kWWa,)upё )Ϟ^=T,0 |dc[W?eY sˎǠS;0wW> UOX! ,nShJZ.ca]'\Hեu|J3 *= *Aَc@C6S2e7HttȎɩLESJ- aϲ5x( So8c{[OˡXj ,eޯ! Wԧ6>-iKʚu>meFݑ2i>ԧh[Ve%b1Ԍ0T0V@QTf_ɢI\IE^@?ѝgԕ #N2`$OG#ꮔE h#_qb.. DO^4*GF=Gޙ2^'ܧ?8ka2];0q:z<|X2BI7|iJ[p<9VhUPvD-@rש$@^рnvo/f\#8&qe;P}[ʄ!$w7":h QzCM򮞝ڎ 5[O77Ҹ"G V H;y!th0l:?pG/@vkyO8 MB:Z B;xX_.'ƳSwdÀ( Zmw9#̫#;!<|ǃQ @ `G̢ >  Ie&h/pd^Ԃ&U\ǜMTPoLut".ʨ>#ȺY "K]—K 9CRpC齏Y$1A|3x<д`U갇zVE2.gՖ,=!D^F%N]⊌lWӸz`:Şz/=IϠ|}uV6PKm}DmPNS wlS\TX@}|})e6QovRC阘xGXE]^|-7rҿ EZ%#WFzy8e.2`O`i0l=)Y6Lxs:>LGK[+q:iv"oȐKn<ж+xNBAZ;QG}:]tlgf IDATЕ63+֏NtWV} ]!은RsfV|r^G ~rfB߉d{r[C6|wJSV *dV}hsRG _Zfj\=X /ruaPެbq?tcpC> Q=ofA?W˿ '.e l*Nη7㠿,l֮G##VUW Cw) y|9ڮfkR6׿w։M&S?ru kNH9u(m;YDCyFwJK9p6_޼Vq?`ّ2`=')^v@?Ue]hI]k7u ֥g2WQZ3lj$*kXt:P#!g> [WmERd W _xwFt83ض!g2mFly88>Xe_Oo@TEa_QwMe >eZ#Y9tw0(;JOwφ͑)tKm~7`xw \W3IPTQf``+:bcv-,N7p#S ?qJԋ9G*b ,M6#XQ:VA8Gg8u@%W'PK0ܛ aMBey/KE}Ґ%wqIp߼, x(qHuSt‹`w\X'WC&j? 5my_FA[@KA>]+uMg6ZiGO<נ4,Ӫ?\da6xK/\hCR|щGzuTW˟ٖ04AuR<-6,Ň╱ʻ%9p.%3W**ŋ9^U2 xu5i[?^kws[w=sYCU6q@\?3{m0Ǫ~~2u~1v2h;xd~.gsᣓ 랿9~+bŷ :[୬@Ur*O'(՗xlc #&;hSlxUrAΗ|1;9&87B:$ߑ tȷu.x pdYڃҞJ xU-;x*[a,>3۽ɹa_:>-[G:5.9[%~S~ T_\1tG h 4&+<_Nߎ >jc&V7#7aOLFWfםN <@m<ꐲ?'?}h߶YFw0d2l)=ۉqw1y} xa{03䨞A[O6 O2ޅNߊ]" w}թ"=.Cy@/9gC.؝ݯ΂$oY)?6鼭dyk;㠝G !qkV!mL1U;\ ]:<'',x ~W0)ȊME<:Mh+mX Z۹@x1̓&+cѽ#3hȓAHO[fl:9k G6\"|O&j̇ wԿnlVF~:6mi:_<}סQECh?O> 6ǬoE2e9䏧2{!I ]~w__޽f t[{d (yc,8t&%>;\蛍EDƶ}|힝Agor݊ƌdy_[&Uݒ}EmGM6 m8}t"}=(:;4k͏d[GkM<,k{A%Ym'N67πY[b#1!nUl}̖=q̗Crypth_+>7l]]jd0?A Y/4 >Z!leV|'&rqQۉ?HO ?A˂*a:A0]t:b}sٝ/{ϛ I`EY 7("nDDAs\$<JC$A# >e|]9 axtL-Rux l[(]C,OCFZR:6&7a`WF)kr293(w:V(3M߽AN~^2>V RE `n+}2dd_.'K{885'\lVquWgu>Z?BsC?:JSHiT9 8RW%.T+icG&EJ[GnTVlT{8&98]aCjjkxg{ez)|}MwE <ܳrf"~_}&#ԝ쒉H{Ftdڭ_tJa&z6rV>8Ǯ-xT6}MR}Ks{xΪсg[σzTCO,U॑|%oXEoD f.'C&37o2)z#мdk:V +E2$m@AW5~v&~Cz z\yKױY1>s&j odS'VWI0مjTG.~1;+DГ@b}U=UE`~LiϗQס}g.2OdMe_dH*O-_Mǿ :Irxq =< d~igDJH_J$j-× U5x!kݎς6@Lɯ- =g  tzpDp;c|橱As+a1Q@;c^m٘?li#i6BNɊ( Gf Hϣ%Y-.wrsݤrJ5@?}MMބF x׆V+`=طGH5]nDnwRĿhkC / '|I14۸ Yp8:~ߋ/2̆q: v^Dk v5_5̞'Uh|ec| : ЊFYlI_gvxknM&B6m6n~H>3puxilQA 1ѯlgv'ϟ_~IW-+~:op'*Ihd7~ӱKu1}2Sj;Y۳kK/ 8cM} v, ?{Ъ-b׌7+aGt8Fv)HC0L˛0%7'C{n4l /=?1sMFz*{&' 6:.d4x6ɯ-2A[C{cStI+Bj3WT^JtL79 e峜s?e;ǧ{͖6YmE~+L"$M<͇ wSB?BYn&5_yP@@~`}ƞ7̡G?{tg5neG0U`4CTuʅ.g@we3G{jg:I;NgˊFz]ݠǹO;[5CQt2ѝckw-Yaa`cGτ`sg5N5ªL DW0\݃oP%ƗƪUf% ]\8Qt6[+o`%%JÊy_pKY~npw!>'[qa6IuG:Q.G.Íw:*^峯C{qy&9Nl"9:F>ͦ8+49tOvA~\AF{tȺLhuWٶD>y{冇}W[% ;|گCv\t!WY%][[ӶQMdDZΆ37Y,@rc- bn6'LMՑll6<ʛ~}ɴ2,Ѳ7&BoL8d` ?O|~~I0rhjK7Rг/7P-!A*Wt?פ=dn_|6V&cxFK&;8oˍ>}>'wOF fDLL'Dm0Ym4%/w~Kic+5ܙy6徿Oӽl2'Ӈm^tO_|U_7>C mt&* ~ں[H}貯d5gP!ReWUvztώ ԭMk0~fi Ϗɨ $5^9r8mdpE`5~خ,LpgSêw2Atm[uk+M*5Ǟ6鲀/Y@l&؟R=s^MqszϮwzxȞmV-> ~3# jm'$Gmӯ YpbX0d9'#HZ|qh '`6y. ekwl [GO&K]8?"CyïDr QVq6w}?1M.kGdtVO&ccQ.@ZpY׮pv`=9>^,];Y).-&cw#iW~tUo=WCj8 ;}ճwNɮo=%91̯_Q Vl~oC@C;t>Z'%\zp =7曜v?S,{!#HOfv/{K_!Aڲ*Io}mg, ^xlm_+UҕL_&7o,} rfw 3:OrM˟7x3ie0*B/>%<ְʲ]g. 3)a#C>fK膫&P+CoUEypɂWϋقҦ3{-y@}W"Py;^kHq$߄qxc\iToC@Duʁϊ;![@;Wu?XG2<YFuSns.H =cu7`|h =}stZ5;v*yhK1TC7'(]x-qFukxX5dpL :i̮#nuh>Wb2-[Mm>2Ǘ [ o&J٨ sd:pt)Mt|PfIG0ب\xfWuL.7Wsm@7j7Wde?]-n`o ;"㺇p̮; mYrxdIA&<MQ#-Z.r;mwU =MWMth;ǟ6n63 "mLdȻ cu]*Y4`w}\pK<6R7[ 7=fF JD/^slV$/>< ^yJW (ȏ^}dzιAU}(?xB`> ͠4\wGhbp0]phk@'J|"И/esʇ~AV M8~mwErK`7$K(agxM&!Xj>m&:Ɍ ^n?YOɎ*X>+<?9` Ao?wcr G?i>yI z:J|ng5c$g$TYk~[V~lo'~ BVugg^ Z1:%/vj@/0] }ǯ=v[0|~8kAvѯpr*NjɅfڃ\ V ҏGfhaSaksI×=EٱLfۣ1ח6^(ޣZ}jbO|{l#yyc}6A~˫Oߊ/7;^FGa}2|y& sm,[pVC~ip?I]hqqs=q|qDž-y<~"`x{TQmnv9<fMw\73dN/ \gPY;(B|0Bj!)#5ɨ.dxi(㶫𧿳 %3 w-FO7%(2^xwҪ\=׿ScV;u䷿&}R\۪|oq)^$!?"baۀ3-84Z+vdն4֡I R5A—mէA( tËR0;5\>Oώ=RGpտ9rp@=5%+ՊyV$ W-T;G|܉ O {,#[VwÇ?Cg? g2R.`5ٯ@Xͮ9<ʞ6s'yw|c}ICo8DJm}&_πk~[n2}}&9ٔ ׾d-eq#u*~o0xoP8TWlê&]l߲>@[U(; sLO B)Dr^ǏT沽hX=ƻAݎV>k"~<1Ntm!Xdg ɥv®?ݗ4V)'P]G , MdՀ ~w9xl* #.;_PbSgb'&ٓz~[lkqՕmHX}@m8''Qm%u.6і6# ?][lﯿDnnR ~AWR h"b<F&0=|˯>߽F x]{~AۿKm"*R>9/ V?Boi OOm0X] ZgmC!sq~2CY_wQCAxv~PϥD.t`-oom󱁰Z &A9#lH[RD޵[[1եOv{tN Xh[;(VbsU?|SixgCgPhg~Oq#|п#=?Kf&OngeC=DYvhϾ:9j' ShWY 8t(GGf7tSI]pnM$FC ^6S~KNtqSۚξg%<|'Oza燂 [!o@2w5(>]]=1lB6dKhaW`^[9;3;]בm9~d[hy ms/iEY@'2-χ9S4xNe+1sFevm@3]48o| w0e*~4\- Tq H^1֙* 7[~ OTޘd{ʗl0Lz Һ8MvjHgWBQ]lj2{{mO=-ЃS#h7@j3rV;Bmg#jE֢Rm,AP#}neIP&  z4 `/m;bIwזVjl)'юv4Wp~ fM4az{8B_~P YDѶy=& Mƈ>>Z d~AF#'rpx{(hT4yߣg}-%&W4؎~ݧVow[1 n+uB|oPf(H&- HY ihUrkc: k`ëlLÎGsQyB?VV@I Q_zXy< B?I(ӳ1k<3ވx6M;uLr%< t?E˜ƨΥ(->NT_{p@ YM^cKl?Ygz-QBx]2 㻏~3;O;BzF޹{^[yW?d~ݗ߹'cmV[?|0wQ4Άgkf|8Rot_I[H>e mM5sBb>Up(7HAݬ܈(C019Tp W2 q}lRoEil0}Y.. |FN|(V{U( rswf V3.[ֽH HTtMR6f&m7Uëd0x14w莦[v?KB:h]*Hxǭ N~iݵBlN wd҈䑢]Jn [+X7n C4~ ¹zǾhu [<51p]UOz&[]="207&0@JcCstGk+x3pC: J7gsPR~nyV7ӬYSK.!U^ տ3]{ \ꍞfIT'w<:%8omsvuz?[mŲ{ &ٍُ^p>Ԡ8@IN݀V68#|#8>ax8/ٳ3|ClB絵>;Udv3=xЌ[5)㑱w{.(bk` + pÞAh[CKrm6PtlOV2O `v. H$yeҲ}?IH߿}]''wЋ\/QM*8Ƌ&rG~g߀|tdmL{k6_?n?pSl8|OIAKnA;A~ ˛)W;'3|q${dHV+1Y s.krC`oC[Bv1E}Y{h3 d{N7OO6!kvYI&?|{aX}efȠpFz7 fcG~ܯ?ڷ8ߎ[:%#(x.Mfk:>jg|V!}7ݗZO :yl*\e6DmBOWfQ?&$?)P%tAXg6lMV68콭JbsXzOJ%?N ,ݖ@Nµ8CGxuG ^! xM%|3wih$#-m&wh{=wkgGPt<|W 2${;lǎ|ۑA}k-,;2\Nmb̕I>S=6O>\ww/~~f;}d1n{v\ޭ ox%Bwd XlAERތ@R2 mP~?: a 8en#V;4_yG y[.x3~])O] sdkl>/(ux H0ot e|#-]8]t[)K$Eã[}<;A"0{9`߈o07@ *[#&Q[)JGkt:+}1:jU,\o?q %I$CvO'jJA.m܃%=8Kn&ؿP!l 숮r*;]gel͇c;||*M` zmEsmd̃G^{4kA+y |䧳B:aL~Mo;5l\eCo [9H)^SyߊH4 |-4r$ietUDՙ^@B~u+LJlj6JFE'sYq1 ,EGt2̩#1]F.v/wgE&vmLO@kKl>M" K/HMѹ  ]/B|lzw3{WGW0WahmօtdWgeaG;(v wo_}Y }dxego D]gwϿ4xLEςS*5XKeҼg t C8?`r£{ʄh/ Ivtm}}nmN.oLx2ॣ#y{\VgBN6AW=Dil"zׂ56yW^]Z=:ѓN#`#8䜠l.֨v&!?qx[/m{?Gmy-n5sO,Ks{V?76 'N B mr!tP-Gg(lpU'DFkk(/6qb<.#mM BO/Oth:z᫴C] :d&|4k{vBI!#pbrrcx0ʪ_{fja]$|g p [_/~Yn|R-o}\ FvMxÿ9q8C¶̿{W=z(qobNw)Y=3~ 06\5@տ޶뀬S7 4->WtSrJ}-€pf[-1oG08l |.PvI%~t[qUš8 ~:;`)'_ސC iLtH!=2 SF|xZ.nU%S3%v%SatKKS` Υ\g`H[reɅ1UC-;(\]`*떎֝s9*Sҥr+{EFN`>g=kOf?>sPFpy[mBt2Nԍtnfè±"B 02-.et5~{vj' 7Hε=&|z3GfQm@0;m)|(V#U{ٕMi}cԥMGG Ly{Y{*GF2n`ք8~ 'z%_ k#ዞlod駕&:pg`44[y߸>lXE=F;W]x8;C V_( qg YY[xA>qUxv/֊w{}Ht-4%3pq?^a9TOUxj.6 @م&lA ;N @h>0UZKwҝmxQ>\v`KZ<>ٯC+|!}uM|~#Ov`/{ӿf"ZnhI? ڣ/Q(7Q?EPO0 |Y PzSimjw|QFO&ot_;9=7[m7/a|]πto>_ނp0Ck4k{dk߯xgjEE >9c{hc/X"JCe&xX>X`S g 4X|1yJ?|c U&*?=kvq|er)golA>? l& lNt"[u>ђ#Gvs8#nz,MlwOݮ'osa4GuLli|[ s IKEOWo娽_t2 edCp N-| &ojh geE}kct=N 3G[ٝ\чOxSOy<ɘϕ=3D#ɣ{ zԫkʮb+v pGrM79(K /;]^;17Y@:7}l’$Ϥdl(8ppm| ׍]S4O؞A]Zvdet_kM$ekbЀhB|,膸2͊.ݬEu'R8ңyHjds[MϱNqK8u h13 +lj}EsVE<L! -rc%i޶Jz^=rQ:}''E3GxdzAAu<x_, r?|4מuVʜNfr&GVXasgt0=+:/x\iKf/.t&DCm~~N O>vynٚaXo3G,4Eݏ˿\8v#G#T }~l`eԿֵV|q r:0qW=?+"e 㩲ѯ#~\ NF uZvb N$.&kr+Zadx{d 4\+z'#OQ|UO;;"@:ç3l⸮ٙq*+g29?d4 _[iFFht᳕}8e?8DRŎ]` zu^:/ Q1:5?0'=d6%! hNF/&  `Wrm<{ms>9} z7^賁7)53Gޠ^?{eqGׄꇑ9YAic vp_l1Y`I0bPd{{zA_~a,+=[r¿7ЩGX}3zڙt@;x ]U҂VMWzV }muf@1hpRi%Pd .4a$}6{egjl<@oϰ ȵ'ktm1]^1'G=oBmA"=]0ě* wZz:lA8~\yu D z` RΕVL'#wڥmyDF>y}~]Ƴ ^g@EKjx5x "sthj4ؖXȓO߿|hvep宼wr7ֽ7[y/(?C9xkc?`\-m{4>MGtU XTbH.tr0U>ٺԹ^yNv2)j`?۠6g&qNJ;w^|\ sg5}d?F^香cGV]rf _I]ݥ+T3%_GՅFen D̮[Xj_e}ziv_Z; uU IUȹAd8= U~27UןWLEGw. 2o>&xV}G?_m@hjYO !p/L,kvBv\ak쿁z&mֱ`:.^fV?m@3{o cpț_rxKnꔿc:\ :k+ &oeyڤ˱: 2ȯhgϫ:t˖(=W ͖|<|=od-,W }lk V= :{Y[W7?F6 ҺfAy&;6+`ha+㋝} 66I}]~~g M/ 7_hg,q_Or8EԘL(˳`mg:|g}աgd۳&W4owX13͂c6fVL O/|u*GM[wmn[jtO&LmlX ޅ/4M 8y@Wx5I迁+Ap+~ֶl_z$\`{yzHP:XʩQ2of_guO& s/{hg|"xshԷ̤|m{ohDXcAw`39cd[at7ϐ%XFGжn[!fAIf\wvTනy풬C!ѳcO>xGq$%Ss:x_}M ;m;F3nKS[%vݠÛL@C>>\6FQ 5c/,^?|jS$܍Bvy | :?"٣]X2]T]9 4z|ō49쿏6O@{z/_ldTw̕u}.\ S1Y]|=x(}^pT36^+=OC$_vUWY sBY3EARxR8tWY?}pp2N)1f00 .Al eնʁ ${܀ ==WX=Aս?YJԏRy. HtyNZ#fH%8^S_@~9iA>VW׶:\`kI]#\g dĸU<#҇z=.~/^C7Ќu'ztj\t"9l*`cW~/* w _8=Wb?"]ɁK<4\ʖެxMrՈOھ[ӇF+ J̦Ý; }<&'CrZ L|q`|`Np+:Mv~dxЗ*{[}r._*;\v_m_VGڑnli' O{ Gae2z^MF jВߪN#t74I{OŽ']x;wqip5V}󃭚ҩ65*#:=u^Tmރ֕5 rl*~ TDF}nT`Qm@p#XO}9Wd}7Ckró~9푇l^u9㞋ͯ> Id5j~QWLXNI>4 u ; Mt̖ZPY}/#m;]M˯o'~] _6d8̣z_[L_◿-h;+b{.]@^}? ܵ5d66;?!)`.ޔ.m)"nTNoxi:k |O[ dfG2!zկ22,PޘV[m22lBgwYcU€Zзoj_i!mUG;iC=քZ酞xpу/ 6^ds-G50ygq37,z!d])gk/K'(.XpVB0端;|Ʒr BTڮL2X'cL[+ͷ*laxp/@Bro4ix3_}J;xxW߲Y* f&?vRvh ϋ7&5؃5ޘzϞT-x[]vOw_?Md V?{{=_fMڰ#O>զ9>ylcZ~Gݧ&ȂݰIsa@:b5/KI$S<82"cS]vHG~ )?[|po `5aЎ1^}_k z>+Kn}`+lB9yL4n@Ruft0}^I_}9(L:ӳkzT+kV. !*\byL}?qm'ӿ9/aAd_0Dw_}RN~+i֓3KY!F[iD ˻7@$:hs}v;o]<,Puwf`6~]wi78E*q9523pst_|}G7GV$zo7*]kkGZzr![Gc{oGJa*1;:ۭˊIlةaE֛(ʣOi>l u~LV@Npp9cm?r(ȫI,^ \@wvesA @tAOGɑh!_a*pZuVc((؊aFgs:Teor^q=n3sXS&R"eNk\O><9{3O &Kآ:~yl g/guƷUx9 ٘']xFh0?V:BdR@ȶc!3o0YA&#w PK@/`.БF_;`'N^ |&#Gխ7|8 ܒ?mg$ykG=m]{k廠VG][ymӘ̦9sc]Gw>l" TUɧWh)oW+}Ll6L"(.JgxS IDAT5U=BEU֖&ِI %:Iw;o`!/o}[u_|S𯷗VgKh[;So _^A_ ϝR'̆ ŸK3mv+U=h[y#m$wi}[EV{‘ܤL0 6Q7'3 x lǾN}6壻lҁjO3pװțhUGȽBm},\A2BkvlS~hSB&}e}[wxwʖ6`? #fc^S<T ;6H[}ɏ.^|UMOdR@:A_:H7 zFgH>ol 4;vX<ξ跏>[~'I`CKFE (IzcɠhBfk8po5ɱWn͙ Y0|N}hۊq ]=]FpNjSlmS6>!v:l r>;ТEvB [[:{)sh7OۭՃwݽ~>9m!& %nꆗٳ_Նx6؂hJ[s.'#B_ڸ MeiʲUK^o -7ߑ0;*&3YUeZom {1Y7}vn@Tg4iG8lmKG?_l>_FL+_Rٽ1 4:OYAZu7AiN|߁6-Nnpfo4ьjQ.m&܀8hrmUdXvf *ǫ߳ =cGA%Xurks'0rQ)?=4``CV_'ޅ>&]6(t(_tr=ULW})>6w];Së@F3H߫C?;08&\veuu7 ikќM{˖kIJà5ph@ Lb;=bPiVF{‘̎)M/@nl=\:omVy2pQGoRnXVuǢg l=^}CkqEA6k uLL7~ $͟4QCnh\ۿVדKL`icJ?05!?ڙ+ܯz\Gp٠m!Q<bp9e`qah `|Tp *gA~+j?{ěz/׹&.m^0[x60HnI\oBiA0*u rDNϙĤ>ݏɻq]^daaSت0Y;+Ĝ W7A &sA3>HcHKV /VڃڄF՟]UDVw$`^K{b.q'5"F\Gٕ۔^}a#b7YaBu9,Sʎvxe=z`G@p<'J.EFIڵLt h5K D&~~Ks?ݨ,] dv-&o[y僅hk\{UT2+';K^=sVFY vuar|5i;Җ];OpDVWv͒M_`y~b#?׽͟F]?*?=-J_W*?_=wΕ=D/ M7 ROp^{O'gGy© u}8 zQ朕1nuVhs+}qNXg#\:37K?;%>߆??jz2Ks}`S ^i?n^88%9O:vk(\ٛ=\r:8ie|P͔~d9v?N{)g况[~rVJʰKl2jx˗ˋO׉ [2To褓3*SԱ)|=qN:vMr~gd0\}]]$orq{oEs+#~z.ͮivtѷ5k;} lN}*ƛ $/ts0f5MaKlN#W_AӹPV~جJgyPx6ɵίѺImz9ƕMpy?рo`?kw$݅6mox8U.@9Cv)tak31K W6 bmkL?mh0 ;m:Z5dGM p4Yum?rsf7G.=^]+ѓ[+(LcNgAA]UV:oUEn/Dڭ0-8Ꞝ TCgBrn۷ {Y;KzG? 8್h cP .'S_qm?Ǯ9cn|[PUi솟2<5{;?{*$@ ˄9 B*[wAs7;ۜ^ffٮmϵA.~}k6ڮw}.{E7~ n|it׫8Ook~86@Ζ -lS13{M66BpqtMٝ6ےdi}?wr̬! d5 z3x]{kk{xPz*= &)B' >ݧʶsk۞K8?mJjқK۸~n>Z:[(҇cnUKTMm58SE6m )V&96N`UyKg"[PS;Ӏ#o8|E;X1Pd+kՍGytyELĻҴYvax'LL 1Uq8 ,:4p`.wUmGO=<.M ^SGFUx8Dtg<9#PcQɧ73,q;86Yy{.۰,qXLwĄ08i0՝OB+`*%ܙ7yޟ9 P=9[ AUFy~X?o9 ճ4܃Z~axr呆|]ј׶/_me 91>֓\*+e &;%l+"ϻa)%_Q.K8*х>^ǐ;z^[YɃ.j:it=}?e30PAWKIr)/یV Gs^=H.3|Kp &Tõ/{/kAZfUw-Vg9p)4:eA[/1y8$?k ` ֹ/tm-l"\6(T'}/֧ltN4ʮ鐍&JȮ0ҐxصYuG-ΖyWtLd`P=kqug"_xcAs, džMFڥ=\= 3qM6uk}Gc;+On> "*V"h>hxPتٍ;Lүڧbm:Ϫ|Ѹ8X5-<,[`\-Aީ`HƬl)v8?OJ9kT݌S qsXY!rMIXOg%ǹ׎{:I|yvK cɁ a(鞹kZ>?Pygm>1w6`ବk?exȱvӎ7s<ǯD*Z[rrXꘀ~PHV*:8~Wcv8g7RxóyS(9T]C0Qp4-zr3kXji+*C==9.NkK5k}s:x`O xE+ wn 69ǁ{zirp͘+w?g#'aK=۫ OAnǕSg/8ytxWƮܯE~(œkU'?E6 =}[+yO{LxϿpX@n]^SeЦ?23X?]EWp=^Ҋ"3+`[09|n6zN Or3sqW3W}!O<NxDfhw| N^:plokf 7,A*߀a&\1/z7x GoϫZt$6qzҷهk5j3cm([O4c@?| Ƨ=aR|۾&@oȴFq^f.z] lyQ_~B>ޔ.]ӂJm^NۏOЦf ֫9|8v Wg|?ڍ|_5\ç9sѶp' ,E<#_:먽dnl*ѽes?<^ѠR+̘O' ~ઔ-Q{o4\߯Apawó"e*{cՂ&|plfkeRO7ݽAr;`Abor<kv y8`EҝͶʳY+{p ޵値c=ϟ?VJ@0|vT{e;OFWGxq9lrw6!{{g !}qՌ!7(0-g&t#/@|oo}W<,: ^RwvE>ymlhG7!/8[.ClHw"z֞3fsyB~F\ ~gZ׈ohiȠ`jis)wDaJMWhlhotݣW5ߊ+f =WO5fw5{З. '*>Ξuky1*ms3}9ܻS/:UWS9Ǡ@+#]ږ{Q3qAt8%]-LG*c<:zKBMp'E.ʎwkp=zASnI?Ysmo kZr`/pth󾡼k:; /4[U٪€Pkߠ~iB>q+9xpOhҌqוKIwgz8Lee@}p1wƃW&-~sC^TO0TJ\Ҵ9+&2nPj76Q2f*tk;6xx/`U^GH*8YjO虬 VQƱkvk?4w-;$aTLkkX\TgCH93~dK^jv+TkxU[˂_G^;^3qf.: ߭^WxVՓ3sf_~|7:vl,W5>bU\CN$z:\sJ go~эr=omf>n|Yr?OdjVG]6#ڟ`8OVYSDom$䜚]mYKϦ*@ӈ~eW T\plvoTf'+Z=+O4vAWO܆kh߇R8ʀ;asAɔH=W!k=cԟ3/Xsz# ifxKW^)Mzr1[:h~WWt|CmILw9p0{ /~akvՄWן@O`ug쬺Kܒ}>rlO?@絕 8=Oѓ`Vv{ͩr0䬉wO|_חN<T2\&vr^+u^5%siSG` ?u "?d8vҧ6cJߨѩ`fxx &G,}gw?If`;Dz٠VBp,4 ɝۗ2p @{UyfDg<`7V'?߫N EڪI< tW=x'/ Iۯ~y\|@LWC'_~w 6*=5 o# XiV_EHAbChxj2?v.#t+2%ҔEZ cF~]Y,,sV],`wߛ_|_]p=+rXpsfγ<|8*0xz!'p]e^琲r~Nn+:`ǡr7R1 dUW?6x-@Q5 |:9zquRﻴ|wIzP wi?]Wԃ6Gomd#o0A#RV5>T^_=meZ1Y'UvQG9L ,c{!ӌ+34]ܿyR6m[By/29>e+7OMpA'{%<`KG wtU=4ó?x^P]W,/puٽсzIePGm/dNhuЧ~@ma'}YE;_[#z%xxsFd_8Ykˈ+.rpsp9.Z#wT (ᬯ8K:R9J(nɳ bF 6 G ˜9X }X4i*|:80p]x+ L7P|yD?»`~=QB;1 Fnx ѽ>UXO݁a@$n`sxS 1VX$(Wg 9V&~snp~!^omZ<)/|WhB` -k#G?gQ w. "*E>I;ޘYZB1p+ ﬘].\Z7+~c;Q|GS~d6~ -9[mA{Vtg[Ug/:5'w=ׯo~o`Π$::5jڹd/~ hّK[ z=`zMh WVO.{͠k6BҬP>"$hڬ:Q^rg07K:J5|tzfHyҶᶠڡ&4cgg|jU) (>{R܃='c01d2:]g@;cGC׭#eVCmNY>ƓZWP he"tgOݡ| :/$C6QAnSejvZ{:>u&AXg_元ջy)-:QdO#tћccԱChN.yezfgl= o~{s7oQu78{г8#MU#DqEp40զ=-mj}Kő/&q NcQƥ@KO] 3 _pø_8 @?6c6 q D(޻ 7˙ٻ-U,ߖ_v짽ߒeBRVu :<'%< Q/(Y+x)<mKYbln0༾)uƜ%Awd|ᨯ^x蘼= ګI~'~qc8t^ z2'kW::ԋ}gz>nʀ>|3(Bz~阶Z#<@yW׵:p\2e:Nṕr}wxtV",P?JU 9vx&}˥x1|s815;3Fq. p~i4a*ԗ}v{u;wt08J 99tv,i~?pg3ձz%'x͂K?: gM&dz2߳=?r__SWsQ-F&"~|}rfq׏Tf2ltIR9L,ԆZAqa&/Ne׳Oי}9`r !^QShc} V nw41fth}t쨾̺&(} ^xn9Wr R FYSs(gSnCicn(@%v= 0&$%q28UoFJ T Ȥk&Aߐg{ `p[{ۅW4K4,o>=-5WO.d:~ 6ld7| =gsmw՗G{ ~)ڬlw{:˥, L(3qg V^3Чb~X{oKl iVxEJ̵fC^|{_}}[6% i?EpnZqOGeu(1nh*) S|2#Yr)] hpݱ%tF۾ [SwVKP`N`Yז]CrW)="3:FxeL:u_* 4jcQ*l2zaxE8dx _cρo Kdog|ⳟ"rR'<%!F?}V]pQg靖\ip O8_w6굲@\ ğ=B6;wy&[K 6U׾`>ro;?Hxuu,+yH]|@4c^HOoy^XC*glǜ |T8e(Lcb<4@Dc8Ϝ9 eڭ &<WeB1FG5u>1ِs9`(VG(;gtNX'̬0'##IOiO{w/J%5 ~;gJ&X}D6'La8Ѵq )X_wٔ ?Or0q3 !qOҤӖ+;p݂XN9uAF`j2:tǷ'rc՞ 8^TnA7CUʯS]j+N;Osrv1 Wf\O gt?wV\DwA%'=vu>v)zAZgް,P,9 _"-;^pls-I\ |c5 +ortGFfv/q|(^,9"=wcAC*vwAZyD5Bt Mu?m:->W O{ute+-g@DZ9xop% )hP1^å̠e(aRAkC6(4t ] tq~zDR_ui|9Z_Y_Y+p_dGuȩxcD=٫fYȷLozHc[IW[˹$&ʣOYa3|/=}{G[mg5y` jt{Is"Wgϡu;׏N'mPNqz.R?`EOZL>y:cǖBנPYa9ΏbN&9._ϩ~͘{='Kk6z]yv.ݶ6B_LU>kА`}?9'Y6:}mg%p "Kfūsb"ޙ]a=+H}Y>Y߯ʷEZ, ۀ-nAG޻g9{:ʫ{|Gh%}hOl[9(m}«?< Rg|$]ߟ]xg|Φ54C>ƴl~|g3Cy< XGnFټ+h>4#7C'_}Ffh 6ܧ dJ;@O41cg7?&7qbY;:#on~Z-]hV?/Ʋ-6AMIvN?ok"x4]' >M7bYlz'ob~zr2&s:~ 0cWVfWc\.gI4P`Z09_^m jJ;K }"n.n#{M*(Q霯l<!HScKµOalߪ̣ ee^~u(gߑ`gV.6T[Ï9顯#&2=.>vG?}W_ pDWp[yP#{"5܁0^kC sT-'G:C?|2H[Ɍߎkp9i2`S<9| Es7|?Xl3O%v{s\ݏ.ŶUNy8??'y3`#N1󣂜ᅦdp 443 OKNml}^>BΗZ@Z<{lƅ=oPet^M'zxxi9iWm/ (Ӧϫ;'Op,}ܬsPeNah/m`E>5sJ 6΀AgvvW zp{>(|e"${W'Į=Xk> :GGrTE?:v,bN> LuxVA: ?f{ی 9ṾjzNlf=`[ 6~?.<Od鞳Fx>:n+WEO aqeI/!뵛R`Ƶ WXN%@ ޮ*W͂b霸j<ڤ{HVe IDAT0C-Y\I;nr`s^yWYr@┆V,.󝠧ޡы9d쓒~36d/xL}hϴrG m3|{ƒۛ_]mԬr4J b@d3r޽}X{; 'a헌^YIǑ:`/MֽN%Ubs-g7`+νGfp.wѳxQ;su#]Ӷ߻r;^?|KJ&3w=S^ghGr_;xd{Ÿu tO_wr7? To?}>|LW/i V|ގ:"x՟7}NUZ|kw.GsG =lJOѥogW߃g#i &ͻpȿbqgIV?lg{sFKw .&S29Ó!_圝\P%) DRgXْ!av_q̙x7!^SQKdcu)?$\k N^|UlvQxK,/TWH/>]|Uo^< `oe1R*aLӬ%lH)LQOł@U%f5:3gx@8?3 8_ɑr\A̓|H./roq—TVٲuy쉺o 9Y0&ԏWhM:crJu=Ǐҧ%ifQ7P :肬lxdU+z8_y[ɲ'#ѵՅ G6:_}ufgAO1/u@e堂 ^00x} ٔzҬ?zrx ƹ9u}:2n &3j(IvYqmx1$L9ƈt̳w<(=3B˱mYEt-ѕ'#MQp !{m~m0g.@O~[uz[dCSOx 5|hPp<2ͼ{A' uml:(h~8a+Cu{$<휏ɹ|oSތ?=|&/mEy#9 8ԅQOf~&DoQw}xJ|>2A:ܜT|3?z@xʟ\}D3~:NPYj`tm%κ4N-~_8m9]ޒXB VŦ@>L;mEy'ңd\9hσ)tcG5#D O]]LF`tΜl|J>ZÉ'%~5 Lpȟ?&o? >z73 6n}mao`A}(xV 鄠fqKf@տ)Ѷz,mkm+ v%9 큸ߞP'E{/nk>kxt£SݽWg˽_k?@d}H 'ƴ>ok^3 4 n{05 T%Ҁ?PEkRgvK'fo7%اc-GKwpf7ҿQ8R1aԘ;C>q83O(횧,pS/2p>-h ƟY'-xkOh= ʛ>*}I</נG|:*XgRQ*l2N7z=v}r*(ҳ:N.<0e@*sFa\rʕKbfL]@UpWW:zPtޑ:?/:)3X9| ^ST|}M1hX2JTY5=V:S9dugMܷfɢgpIFKZ0?=CW[ir] 2tc+~ շ9:CN9 !fGKGyP-7,63y+.eˌU5`*E6xԿ n% YY L?=.mVnFn ^уFTG O=*,[aGkP/Z"+NwFJ$x2F 4`?.7Aګ mϟ }{mpF_8U_%V&ylzg|#%2dl)WAUmٟ99 `wrdU'%38?yW:حZBe?ou2u+˷ zЪzN1]]tqK0y(NLOvTZ*8DAbki]&|GķQNqDgЌY.9ޏm2)mU h^forNѳ>{O{u] ͠% e\{&_^LC@zt,75Iӻ`%~3t1q&pQpHƃLo@B5$8 <ϾxCZ݀e HuD~lJҿW<4[,?}}l Nn 7`ˮw!7]679~Y٤ipuҶ?ӟ5=x0^Ⳳd)8Ge띍g?@tG}ow@w9FiuBۏߣi<   J`pG[Cz:['[5tvyfUDCmY|f%j?}OnZh嵔ݠey,/ TVFv7xddǃ_gt#߈3="1m,$@MfտҕҚ*C.~ʥ:x%z 6[[ e (.lPo0uC.02z' RK'N; \`O:Czͯ~uʣTY</ i$ZUYpxoӀIg`}w+Ox=u=|@w7){{r׀p ߭*.~]{O>JO C?]"F+Q˻mJ ⌧[%:vhy_ý~Y὞ߩ~+g[gAҲ{J} &ǟc sX)3?k3G-/;T8)D=t :Y(`#wLrr΂ *TusF6 3;$97鞃#k>cQ5-1[_.}NNgߠh5B(i}QkuR|yֹ;${#~sv-PO =p/L|ɭd2OW4r,8Q$WxFUi$=Ww-V<}t:_kç:PsQ;Gk@AS =`ep=0~琔ktfWޏG$nj^lw/<(}8 n#3h|Ɠo=_/'CKw?BxPj 0е Ξ]6\~f?Dbɭku5x|'c{HϘ>$z شg/I*OmcɆ߮ίs{wA[VxpxZ%M.^GxvCml+G}MXC)|) L/J|PΛG,8@Xx×_&epDzA?4gח{Zvx_9&LJ.ߜw3~l\HOtw]Y-Q>wTV/^q)w7c:S=#$>g6gIwWx~l&Vy?h]`S"OѥifFz |LēgI0H"ǁvv՟qNN\TaAKks|Cs $G<ԃ<oxEg9g蚽zT^Q]Xn08W١=c%z=5=I[]7_ipj+!% @k!=Zz\[xAE8^`WüYi >(Fa1Ȁ}6 >YghNWVt5AA_!~W8?p\ tacgF>l64Hv}|۽﵀ |gCy3fȸ@ԫ{YH7N*OpYt1rtj|Q}B ѣGZ#;m^9>~k( Hupl '}__pNp%?O݃mdi-䳧tgCmkV1~S}r)wŎnsGE4t@'; |gpGfXb 7=//yW.%&#/r7j\m"}6:]$C. 0\-`(v []Ou)N:DW>7[2l (fFӮ;:%^іu)/'~{Xp-kS 1Oۂ;-x`+ l8NCbs:T='yop8\%_Zyzj]h/V=V%כ}EpKy6n|y]tV1nQ>,d~x?%u1xwzʀ/ ]7 gOPyӎ(S)F o|H}k_#a3n#*%DG9b yM':(s%`q<1%(Ы>uIN-<-(]JvC3^(oS yAP#DZЌߧ?#, Φuoٿ!`'+ܮ ?^<ϻ<#s֞%yQf9.+ :<̎KC$xGNl馄z;%[%x{l *ֱZ-djS-d6X{}7Y+˒+F[,/"o=  6(\ѫ?-+5p>^6-3FKQh@ ӂWyGoD`78]0 U\Η|mms_YPƹ!g5dLt3_|S>Ƹ{|lNY ߎ{7?O[9kAxG>DZ?7KXsƴ6.sβ)W F"}΁4`D]/d%ȁ`p$lKWiկ9;CY6NpIvÇθZ8.縗\Y\[z;oOr-+|||Ff,`3>w g 8>} .v˽xT<`U#[;}$ҍ1,`-3WЅtS>5nH3+xtnRY0]38W1 Oz Tp 9e!fk'g/}ꀊRoMѭ C?kGfpcAڟ[ r~_ZW hV-:<ñi(ؔ]`C1J˵}d%'OW|Ovm[Q:ށ=o+Qnc3'i@ʱ3mH{]قEz/ z7~Fſ{}]  䧇M蕃 操wOU5x`A^kj4*'Hof}M([G`{W!^4tjIJ|;$tߞ7?=;k FF]rյ*;>Eh=lxJzxoPTv| t ~*`ӡl1 \]S9W IDATZOoojS~cz8'nn;s4 |FPd^yyQ^O0v~L+.w^(?}kCxQ!pߕba4 ː/kDoEyʢ;fAϗrWy`&ĵRx;b2sVvvѣCGwuVdZ;qePhaGO+=@爞|ԗ};蛉]0'[w},@ vkS-..Ѷ%,U/+ ӗhyШ~zmf=[4*vW:s#a`f\%9>W]_DwA=uW %6?YFJnգ6ק-E_.{EӲG }}xT>?Û~[,K8㕶Gqp#X[9SN6 `n/9}Uu3 =L t-Nfz\xǯH+_~5X9[pqd{o&|N^ea?.H,Y 4g3o;͈"z<4Qo2ao`a"vB.}m(= ݛ? FTڤeQo7]vhȜMh^PlF\_Gһ{]NC^Ǭ*rny_y:y: m?!~ >x/\5~7$YP Ofnץ\xi R![_`0|kEEg 4Pť1T9+py_* Q8J*v\dU}2Yz\sIJ*{#r?ydҭPW k@'dt)e_&!Ph2ᴍWkϪʹ|=Ʒ=,.pQ9zī.T.Y>忶QpY_] ]f\+gGguOl-|"B{7?K:zdY/T]y㵃 .m6{`/#ʡ7١RN![QuV>|*>"ɚ&9ٸZhεi]`nJڦ/6XeC_h`GW7_`yd[`H5ce^i;+\Z*Yg%U{C_V4T7dr / 'ZM^{3a=O.xnJ+8ɻ<>Q~8X0Yt݊كq 6][WUȅ4>lϵ?xtR d9pRXpswVslVËw߽~\釼3_3?ؒh -϶姝 *8WSfw6L<Սw+p|+m5mX`3dCL>+7XM0_ )6bs$7[F6 2*jI:(7)ͦCN`եW4МrNe|.1ʀWnU lxYƧS&C_(vh `/=}۳z.HG_6+O??x &[➬켷~m׵pKNoMw7 ٭=Tlh@ dGSǽʼ7wV]¿!xɰzށz&5 ol ]Nؚkw%8nkq_,(8Apd [/4Uw3@:0ix`_P58˳ U>ukxnXT];zFMi p@Oum%XG~f?Ү|~l6fJa6tȿAONOFeCUl|p _XB;ʃϼ<ϗx_#ܞ7t(+A?.{Cߤ{B~W)!<:6ǯ)Dަ odz/~Vl_'7=ʻ*Uv XtW2fa"eRqP1_g-KR :,cSyg1ux'PWi׍scԺd.f(s87sv' )۱8<PH/<{ĺ&ЁabgtU'FYY QI1Gte.uU=-mvm]Qx(l3wGx 8E#o@|e4E sWۇڨk ')/ !8:[-ҍtI7h]N÷ĞU%րX.!NzpH? ܻೡPmhKxsl)[BF&)}NW񍳇Ffc)drYԟrG[].I+ nR]׾B9^B4e;gcj>;x"rv)ՙ CӁU߀yh2`@׽FpV)E9ҽmez2[##ﲿ6 O|{z|9#ŒѦLϖ~K!I>pk& Ϟc6Q#hj$;2ɁQO߶n'G0)䏬M zTd<,p/^εB_a@̜0PVi+ , @wLlЗd-XA|ϙx7V';xY!$ lr,Hg|#<keJD<304d{b:r csޫ#?xIGȠ:kWeEc[OG0m(,@MiY'?+MMNOXaIً}MF_ߠoNr/\kVW?e^v#~}_×\UFzofox@-9w-{wz7Dzg`b_ذ9Y8qO7e=jUDսx W/no~JfFxO"w(nK7SU F[@p(ڌ*m lBchuKrS=/E`s?M/Oi}1a3CG]{:ꡇ@Ged~h~T>\.}~z:^@ՠ&]vQ[Ak*zFpX®^pBlTg(esةV*ol`Ovvu9|7 teAv>CcWilP+b~FuHN7ȔşߔR9]ɆV x\Gi bshx>lHkeHz̆hn:YEI|=Y}r&{}RŠK5qYPpmOiz|+V +zkk+%쥂M}ero+˛We i7;-l!= vƬSwH R:)QS~K57` E9\n@A:~{58enD33rtC`j;} Ky_#>)/yd8ioG|UYFx@ q;, eQ6ۦ];7S8 F:RXmڬYP6nc 3+&80|)1t)x،K錑`spRN?z1J45wNmpzto|(![pT *n#W*syGd9eհ#$'h6g`% vHϿӫ>z{?!damW4 bTG7~$OKqL`ZG>#w?sytQݛC2~yu5k{R>8yS|}奝ifUw tg;⡥ #d+]p<"eOӟtS,pqH0X;Y+{ @ ZY*ZɠLw}AƷc =cOڙMcmA2Ǝʫ;m.Cutmϲwpu4#佂92WC&mor6'-?0ƛ gm-;Α}kO!05.64g7<dz~U?>z[sdnpS|0sud94n92υƮյtTte QrfIks8!׏SۻMR;v~1TfHrw?T+T?GF 伞Xu,c0 _d$L@9kel̂;[=~@`07*0GvM7ۤjCmzhƉa6{5+^|DNszado4x)pfOg/팦p@TXG&_| f'lFeb'6[2Nh:D}Rz\ ξފ] @Koom^p83br=ۗ8p%>4h;/]И!>z[ǞL%Y+ljc-3Gc[h^''7ޖ^U^)d`m'd*H6XaԂ A>Y=}@DU{tͺk_,_AVk;nxJPHۮ dzӻ%:Ԏ7W=tqgA]}CkynShZ<Qk[\bBONzx?G{) kHV<+Qď%GW|m"]}g>yvsۦ'?.g*g{Uw>ݴ ^6/1`Wۉ235g\qű]ɄTj\EIHJ&΄B6FXCBԭ~w{}>W-L\s>{^{~u0=K 2TU(SSG%=KuU ?d@t{f3ug)Yɣ#|.`I6kQ, ʤѼsm vcZD1j@YՕq@Y 锓jJ! Yq"p*ޥSaFuw_PJm ͷU(T<("4Xo=ҦP% kh~tnldgގw6N~L^6Z~毟>"~c7rot1<.eqlxOrFf # PrICc'FWGHT֥4IӔBRG,r4-. Ip*/0sq6,q "p)%8T{ց.猂 DZ°mP<0͹TMNT3yK3 عK#u{7;w(qNM]hKVdSk& ~׌j 1p~nݔajNpmdڴu#⺔.p̨il 7 Gb 7qyeqC+v(F12Fn֏^>ox(#E.aC$Dy^M}rg9BЌ-p=hyc\>h#& F$k|d}.^`9Sr5O@ T^ut .2WGstc{&N8t.v߳m4R sF;qGp !_@S6#}ɣ?p琾k7c6#N#ː?T.ʔsrrP  杣.WUW%Mگ<64=m|.s;M _YYwe|ևm[ Q+m2P7"7؉׌=mf;)d2}t%&\`8Ec7出Q el/}##/{>4g8O+w}}|`ۨӰ(g 4# vQ~eo|pD߸W1K u8#z #ڟ}G 6'2!vPҮ@>n} cAP!k`^KÆ2NLO_w`tK6}IÝ8SDRW>֡/&kMh2;*h8" /%T^L#8; -a7m;|c|d/N4&/X:l5t"/HjNHxba+K3;z|e`EG9c^ A'b@i-U  *{;~ H/g+F 'st> C~*$ BcE /?z.O6TmP&gEuF< xTH):uPQPUZQR%x$dT<0aG5&^:KB/wJ( Y:.KcG/zyJz8*z|3ՙ B5oW_>8%tfFʭʣO\nj' hH:Z΄ !:CL_~4Ɛ"\ A2/+r˃U3&"%=u%tX1MӗQ>6nkpQ2BY0;Zoc]Щ,=E =E>mUegNP_ { pm`%bgHDxS&17ԕb+'! Delr%O`b8 4GR8uI2HUIY32M>ez5w&Hz#F@xˤ:~ie#\t24냲ؠ-2"[&`28*~}ѣv6)vH2a :zt W[qlE*Ao8#YȎoW0 6 1ՖP,!ΙlgataelMCc$(xet{*3`su(#ۼ'c0tqd;q+E=rdFevwYG F0  ;91#chs#jc]7ouqYS7@P BE5,t4Dp姱9N2@e暺Od* k{o2O1~e~`ϳBL;{ ng ^ٖ.XH:\cj[VgXywm'kK툑LYkA 7uv䡃ee:<3~ NyK٧Q/v F',۠S}œNSް  C?}>?8~)81U܌. \.MԽ:L^Hsu,늁SDY d<ˆON.m!!(0QgfGyuN\ĹGÑpVM.=%um̺ff3h^1 *˫l{`3d3;g*?z>!JQ ~sC:*M4>)k1SyUٶpgSTzD݌nhZ=ā/#$ 1MW΄Y|ضFL?yI>G@vɥYFѣI۸}R!A?wuEy76o{USN&(O;o# ,$<`]7d~%.YJY/ʇ˜C0d8_1ȒZ/ qĐ C*꧑2K(߃BUs!8 ђB> D*U?gLԩce$ꓗ/yKĬOh J|&*CQu:@n_<g_Έ҄s3H@%t3%ԡN r֭KpW_ 0.SJ3oQT%>T\iOwetCD:fG{?elyQLIDeN hq vYಌu!uF92=_^zAw\q'=2$":G3zy\)pdqܴCp<(02>Ne MvPݰM^O99@I_|R.A=J~: ]vmڲM-$+ڟ: >/RL>{Nπo=s?g51?RW 8/w"|F\%5x ymKbɇ]Ց։.)fsݖ'os_}J)~Qa1!5Hyo[IURז3fǻ7N+4#*E0&/:+4C)95;<+kK=}dړP&E7:d?lAs$1uɽT>+Y^`~$6)3^I\/]J/}7}i魟;h:&Ws6Y*ʅUE4ֺ 23%Yuƺ{[̬8փt֐Q~ik 98'N:R#us4 ןoW6Ɲ#1got~6軇qj(J?yrW>uLfpSbQsu^ <PUG14r6mξ|:+UNɖt7YOб^~@5*%B mrI䳜:H9)3e~͍9rUw4lًf qF~gXFzt2NaSe@z րiҪ G'M䡁2Syn`>Jó8ȳ8@c=Qvx;w}2v)P(?9Zl!Wݞ;Z A$g'9␻ 7-,uayJKx~܎ɿ|qRQ&u#yt飊V a=u̶(\?QX{νxEHdCyQ)+?@<#cuQ*P#hkinL#BA*פK+5AzteNX_<{#G^ހ/@bz?#hd@fq<32('Tkp @W -!JEV"j4ᔱVöp ' l/orG+"¯_7SkyRb'ЇT{2LȋO㾜o+dJN֩i+MC^|u4: GNh [/ ˪EN?˼ˋ*0K6`T Gtvp]FIgx= $ 2>hC@i) ҄a74~» PY(sۜ|;mݘ3)ZTPbT7٪{ MuzYZîrmBzYhu1 nkSWPM G  m'Aϗ)5u'\ K~4i%#ya/>}/sG;"}}z}S\m r]xI&,Гg:G]f4Sf > !Β63v>tRw밎ve7`Tv]귲/ADd sQԵs}5ВM,kO#*iƊct`!O; N~aaAfv0 mhsΆPl Ƃr 32ԫpk'`8@vH':Bz0 z*",:î$~ .nVl ~3 'u>U.ݙ}0S_y, _l 9T*JèUsyQl/`;mq.ș'zh]׈c/R+s;PO1xr8o:ҕD6JOtP:?ѽUd W:fqɛFi:dvZkEEJyHI:.`Uųm5Q A:By [woݛ϶QآGǔ w9F[%GՇ%fikt$f?mtBd GFOڀub} 82NCݫ>ʳ/T*7u}I?tɇ'tMlHR?ss:餖Kq郁qG!ec~ફ32Q <5uJk̫CIA2vA'H:t\wA\ԛ)/bL3Eo\`rJuMv"#t5Υ^N3$M(T 3g.Ćy+탁g.RVƞ:cwd|5gyšqn)'& U,bUW8 xcSXg3zﳯNv4EmǶ=\<1}>b]MVXo`S4)#u~tqlf}1>|} H u.ܰ=vGs@{"uvȒ:aF76SNajl($u]#,T<թn뢲fրgT;RR8U'MҨtwviQQ$beo )A 9th~B8:8/p0GV7mr<ͼ֏D(g%YW֣nij&# ֏:!6C'f u+l. ?8YRǵٔN' n!kMM, "< Ү{fa @9i2,7nkV6=,17T5~d=l7 M;OqXW`N:_N?:2+ 3:k~gOBGWG:Mrڵ\'m+q"W=,KZ%9*눺 FܤeLK usQY eɲ|º\6t'=.<}>" +>mc-wA?mpcf3 Yy._y'ta}%'E+F~n;Vt!ua+ [e^YC] 1R424<63[/\r O)24VH{ z U#ؠSEnuP:Gɓ&EĺґQN:qLΚlHG9W4E&wz#7yeQ7Zq8Y,(/EZft=۸x%hcܪɿ-N_ueْ8Qy}=3Rh "[Vɂi@Sgǃ.aB>-?[d$Am;wǎs(Nu%!~^8:iR>k֗oȺlB($ԯtQ u#xcFͨGq~R=3>9 u ui'^{ ZNāJ'nV^zFb#$_۱S9+HB޷ş##?CuB&G8-Ԃhx|a:v6/]*.YlCe>_Tm~r (^Yh2b%:uA shhDîRKy1;щ;<.4%bp9u }xr6N9`NƲrTf=6y)ga; 'd:E3rW:4 f#B2W̧S;dvǶvl_!%@#3:(3 rWqjEg)Ҷ]'EчcmA4hF2vrn ~>w0i³`-pPǺ&AOf>)#uHk}x&@F^mȀD˙ld{/M,R AM#}o=PmJ̜sB+lV . {^ٴM6 +ר7z3i59pS?ngNJqm:=䥌:2L/!l^#KF 82!G3x2mBXz#$u%<6|c,gVxwpcJ}K3wi4oE=gOctVm )RmuyhWMiMC0:x`ρ۱G м y n@KŒCc$ B+|bʟ bʈ ڐS! % Y۹fc4%)h Du[ѡÿ)(xʱ_ AG%>Qmۺ5B:qLÊ쥸 1̵ !rQV8 JN0#(Ɣ#ʎ%m18։W ~D64zF{0j=t.4~d'#u'myYX"M]Ȕai/F*|t)#0myW --gN{'1-25X0eGC]>P_oXըaOY#/˒/Ρ/l~NfHTߺ幎XĶt;ٌ)^K M0_[]Ĕo c`z`4M9p KkTzh(ШцUU3ɔ<ؿx,p$XҀi`78NHrIY\2]oLDdc['WcZrW^z\hx7=LN0Gg4iKq1Z;rFt x,)n-^s;3@ʨƛKHSi=±%nL8:ώ;^Fvi\ a&P!LBH:#Fr^^uFpG2 . 3mt$q|r[;+22ȦiګچK&pKīh{Uywf!z2_ u{<) SF[:p@vJGG/Dl ^e M'37|@L2Gt_y(<`ν~*WZ%ə?lF>&1g0o gbȯulsMo]z=_a,fUk36-q2$OVt@y\qpO;a?q$I80E<Ө$@fs@m03}\X_L,̘UlF U Px708&Kj*qFhGo%]rMy~Y#.yQ<F>=g3?yYts I$H: @oP"#S6rq*ks5CNF(dvN3TN-=rIcݸ.*:)KG %!HOxS֛4#60NfЌup(GΊIh֯H0H= kA/iAs 3|.p|LGBJg!]!_g:)Փv;~X9]/f򵇕Sت's/qe V=q0cҀ'm>|@twbHOBuu% m!? Rl KOҔ Z䀷8<7HhgM/ N#q,y 8Ps ~ leq{|"u3+?顼mBN7y<7O~{{^^{cG *6IEPڣ'8y zo:&GkSz@:u >2Qc6t3R wk2MУ3<_/rH}>ͣ~)V5=/>6#rV紺f63#'hw\vQ)WȯڀtPEWBˆؑ:,r1:OHOIWZ"GY)A%Q'<Ìu}]|HL G{C;LZ<@O\j9or)hm?GucSNGy؋=Iw?:C;f+!!vZ3b \|Wڔ8ܵ-]" nOvy"A l, .eQG@f\*2͟e_P\URe+=.s&%6~)O䖥JHkgF>CH;?#) r~em$*/uKZ8^9AP'ͯ.=@Lz@K?H߃k-MZV 2#b8kà0uDPAy=%tX.)>MXRm#f eG l\y1GN\.Y9 E1l8>sbv fPF!!K#H\#47kƪSs6b(맔9dntlFZ~+QP{/Ek&gKO(,:\>`@tk>~?i]j0?+ % g";) 6CTq]&}88aT Ylԑ /&Y/]V(X ,(`8)LHoMe1y^ YF@' ;aIBY`RELY;/'FOk *Wu%3GCdN ׬g`04;|qYNήvAj8rJb+#:@(62MC ̯#o}y4(ԍ;2QBy:c0C ("H{)+?}#uSV&~|uZZ?K} xeeGd{Eff;lihW8GodC)W .dkٯųm~&ba/XpaCQӉBate;S"F%~ ,U(ԑa(yr9#z:Q1u8ʚuY/<,gà hn2#xȗ_㌂\ DE - p@O6;㽬0ԩSYBc'|nc{_?,S L%0TS L%$cgB;z 8,/Mi} 8>bͥ-3MàI+u]i0a! .!Vv:qLϲ8g03]5fbI-qEmG{uUuy?N<:RҗaGt6.)X | 4`;'`mCe}Ɖ7MYyh ny AHte8tFpJ259[FAU >s@9kF3 2nnL;#hLkZNrFy֧A pg}LAGh%KN@[Q۾֧v|p]_ XyXg#hQW~#艱0̋eɒo kȯ谇fh֗832%uD>f@.\ IDATM&[eS 8t)_ů20M3pFNT{,P?l$9tvLh7:yҽ{|'PAi׻#G)!.'=(Q L he(vi]\ABDžm:Gntn7avـGe8xv~a8ؖ%?vp F?7yz$} k87| rwCG}s_,dSo}87\Sy钊ȕh f&F\ϫυ"12g~hJSg8k\,, s尞'W٨'=rYV+._ҕiM%9΍33f]ƆZQcveAyf4Rߵ,@rdFݗ ~c|kzd ,"PC;faEHkDWW4樸vDp 0co S#꩐Jhm SGy:9Kr7@E::9q(ne'ZI ґ l%aZd6(d~&ŷ~-m7m=m;e>1O#ыooWwfP" 8e:סQt8uQ4FVw3avn33T>#S)Y[պt$g_s^,v3=a˺5sG JJIuş HZMq5n˟yG|pI_efF6(|?{ ys颲M!Ӻ@NߟrEKC _P>KDRUh:ϗ l"N\b%T%\yx'?I=@"T{P%T<# +N6:󉎾䬵3xeB(Gxyv(PIoRBB2Yer E (wa ` '5vWD;zMB﹥'j_8&"53*Ե+UnɎ#ʸ<F8Ké^$acv ar3,)wcx sXqrec-C1 K䡟4p=K:YR&2R=p*X^zzYÐd6hx+APBv=}xGc"JSp*\skG$aIq2:GN?ϐeRt}&(BZ#3?`:S.Qg X+o#pgrgO흭Q׊\nz˰fGncAVv]!}}u?㔋igx꘥ٲe]smn?&?+ӢS wm-?j?~o׿ 󲋞PnhNvc(l=O3 .F]p;0Ae1ʳw= ~Ч6yufPUMHlqXeAKptdO:2Ey(F"W5~|Vvȫ)ңӍchXk>sJs!.~\aAGgBkNq]&C #.f31u>\te܏\ïX'ݺ4#5֩vz0u~̈}ct4i7mաo ^"{+QOgK_#p#P =c>7~16'g υ-v fwLe=6yw` /y6izRm#so+g_} k,7T04JӄGD>dX$'!@n!Dq>6ϳ9N%Yt@҆+l\t(;nLȰ'xG!44ug2Nׄb&q6c# 8e(Й4x*0z_ػwoƎ׿yk6o4yDm 7t\D!^`iHڤϺ g\ʀ}bi:7,]Yu9,ϳ^~c*`9 3d!zT>%#V@]dx\ eci*幷n54I/Bԭظ}ÀcE7Zރ<]Ӓe?fR_,Ht 7´3kLQ^%J j鰆qΚEFuUWS |J~m2/q_ϙU~_]6򎷵}{Eu6Iħ? o?c](SCڕ|Bgz=_3{o*?k h34~uJփC'~5A3:q^DTn*'$&v&N,j>G߁V3 w~;8(`rgN#d5vHib#U4EyĞ]% 3jc4t5ξSG:ڥu#v0$L.#lsD=Η4M$0f0]u]gHg9p`Pw8u8~MYanb i$AH'ajn|n17t,kM:BH48^U pį4: ?;3w#,%q~))ng*2̡-F:7Myv:Zu?I_wϹ` \ d|]sl (f ҄ 3A__x"Q3KWYiJ\Y_tw ֕Km[pȅ`osLt~%X∣@ǠhX'=HUN.Jr0=T\0A9–9e؁e/'?\讲q T^F)ֈpD~rʶ Ar*,’Lx;ϴx_AeM8ɣn(Spg./k_ۯyߧKx&{)X/B(G3wq.E?lO2Mt y*zS-LYCSε 41LJ{} n`;4QUt368h)M ikuFHs#=7K<ҩ`7+}|٠KWea^A:m]h,<\8GGpl+LCJF#ZWF-QE{22ɓ s?qS7Y-- -}M7(/|ETS |I#8?=wf7'=nԒ3f/vٳ'۽_y(7bH_qفveji.6/,Xz 3ivnoy!mW^r|*x+1JVG~L^6 {״_z-$x۷m}J|董=/3}*}3a)>uvWh,F.b&Udw*o/ uqYC)ؘ.i G:GM׏4}}lY̕N5v}%0F?Ȭ>ӷ/8jp@艣ҀS0ȣc U.7dˌ4`h0Eؔry ƛ7acv0cmå 2 .`d9S8: ,;?&Md9m]~nЯgi|ds8m؟f23Wx' ?#sKrL&PHA,+GG @'nֈ/Ye{ / ܢ'#rԙ YQt@Am/f 4ӧ {o`@S,@_y?џLH<1d32k'Yqh"7[aL&QAZ}aٴ bA[ Eɞ[Y[jMilȺG\;嶒R%|ы>OhBEyB}s(|ej`}^">*gm/h?jϾ }. n ?ywBJHx[߰{S1vyXl%\Q#kڠ尌d$$"tRu*8Q^u({tL <6C )A>opV%:z}vM裺4D2Nx$E} tGL R|ū ή `*ڣ7!@ʈC4U$dD)JgF`+ NG+춛aD|̕E:G 7O:ۚ?~=OXַ|v 7x-=|g[޳e*c*?g/}HgubH=s[?<7]^g4lj_zVs7+mk,uwی';~==׿qka~}^T?a̵K{*n7=i@?O}{g7?}/$~goh_Ĥ}k?F4ih?f6ĭw6`\=w|E{ޕ҅b-k_%}|@<=_< K{⫂so c\]=b^8>Cs{؈~866$o3*=ν?G(%(6pCQP7v vMf _ir]?6rXaZ40e$52q^\NH#<=-u Q~/Ά2ѡ&07Nw2ckk;7 B://]/ z.ѐo䉎SFyN<NM0EWՔ`ݑ&_J~t_zHeJ$J\ʧʦmO>_uI8֜S:b OmvǕ}? ǯ!/q5_ \ hs3!2eG=`9p@D|KPү緡;=H)鶽di2\%8rQppDĠSYG $YQmy#P,Hj"ox+Y*XAY^Uss ^O2CFX$% Wjt`)7;- svϽGX! i`|\D"XĥHg_oƒo)u@[y:CSi<}}?uJ:x*f(pS]@+ 5GW@; n'Crj[9Vꌶ'ĝ._B{=#OUzC4?8_/3\˻K/V1, zB `L[:r|}ɟ7uJb*R̶K.GOYW`?y" >M7Z]6@C͈H=KNS_PVp %^ӗ?^}^;k<;s)=ojp뭷oX7^N%){:ڛ_;?ѿօ kVڇ?}7>{i{ތϾ=|L^~M/ݏgp=f_{U{ڽ8@oxmGohn҃h{E/xk}3 9?vm}J'.o۵W͒BþC ?{lCm3}_KS f<OVFGjEɛAAk_hnȝ::`gwzLaIi6ry㪭Y{8;lvk`'&͎x/s<OdkIc+?}m>J2|\ 9`.t:AF0U>(;ٜGpSεڨ.֓23:zƉ<32,K?J:l6"-2ڢAKhywIgtB'E^Uo.=L IDATDjϟ<_9[Xt6iС\%D2 7L y ɇȆ ^F XOγak;x}?i$僜wfPȃlt`XwZ9 W_yWu 兀 0ȅ(h17~*H؎Ru\jū*0R QEOIpq̃U5CpҨSiv,Q_lL0}}lr[i)z Z2}HTE\8)Z9[tVE22$j>Y#maaS8O?} 'Btg HL6E\<.#Yg፬"pu-e\c|G@:xNz[{rڙv3ցKzC.<rs s`ڴeXCv49[B+~l]åWnO92q)Axϼ8uK xg(}rFI/+3a)?n7؊3ҰM8-g۳$}"1?.;?^KlF:KpOqk_g3os,4K&M%-j?x5eη}Pȟ<ΰw*K8|ގ!БdT|~e7.kvnni֣~ɻnp~îvn:t pnٴt/)ǿtm+7 R%l!t%qR3_C/isȳΌvs9426rc:ؿ813/ IY# <*ft=N(kP\MKy/֤̆cs坎9 Yb{n3g 6w͝Y|NeJ9Ψ#v-|S|<#% I 3X*C/]6_dY(硏;#p[G;~yeS_qp WN& /nvX6y~]&"sH8 Fune$i}\Ld(CiUOǟ9}O:=3) F)­̦ x&ky`ko~h~29'^@c?v\{4K]Ύ+L7Zq}-~yuH:s SEp?FlZcQ[D c2("0'D$RUUۿRTE*z޳Z{')K'ٯ|&?N&=‘SwIu ٞ ,ץ^ 6y IHȣp!-}AYm> gq* 2m/c7ce 8`/Zk(: g' B+ie:*9@([PVq`l<זE"[FoȔˊ^v(ڟ8CbtǐB٤|ݓ͋vmlcfsg9Y?_}cwg_-ʩۉ..>d|#1tRY{$VQdǽύQEՆXiaM01_tufeAn_Au05cFmfYu쓼Pg3Q/0!QN Մs,zѸ3>?|IM2T> ^CgM~L+ʇ}e j? ց:?|]*rWSr7AquWzGdUq+o$ anFhG؇]Nߺ\\C/]mC:7@qGpwrG?{me{O??_N߰v pti&XόiTx%ݗ> 6PUذ:@Nؠ. %0fA}Ӵ H!B4 k ^) i:b΃Qp՝ 9 Ȍ}pr*0 |ubӶ1c:mjSnDn-@ S0wu&ĖsÉTU]N!ZB/v4tTv=)@K|Ѧ%)_oE.+Nx`ޝk3UFdwF4__<xuII<3Ԓ._tdY}pfءjP0"}f?4Ii8pXÿ3;3B4uذщ">vl8S ֤O`X8,ϙwvqZHl H@l~c :l\&HjmCe?yάIJ$&h'nYK-4 uȕAl6 ǡ8~b:\z=NbD:0DpDžcC;5"eeSA@Rp"pqAt2X%'IpȽ㬷28Bwi~<ۖXMgTڃ'$Vw~RQV2h=%"E00hsEG=PS '2*)ҰV`!k?{O8,WN%.%>!YKLhi0Vp0lR0:u?Wz$\3C1<[ s!q{wH@/Vi\# $˃pfyT j|#ͷgI0l뷟7mpZ֛ ߸l޼ |㈕-[+ߩ]]'=lv;%`΋*s4M=ҟ\yc_TU`V7nK %:qt!}o, V *Ռ_yP׾ )O#i!Q^&)RYo، 1vmpkdR0,@"tԍ'''o_"^~oE/晖B]!Gja'={妀]tQ.zj3MH'@!?[J</(>K]Ӄ]U~g>][75|ƱncScoЦ;Q:3r+:3ȏ~ӏ0{rrG^WX~*OE~~ay{۟ q>H'b 5$}MS_(~7\֑汞ðccj;RAٴ';~#]O!vFҜ< m_P&XIYFRBBe6d XѱV >yi&A+8kt@;;<1Kp MF}7ܠ Q&ꌴz`Jx2L9&Cy R:#eeI;Ґn!`C)x|vǩ 8#UߝG^a~j(pU]u.ic%<0&ybCGWǦ#CgH4El]XLjXRFCD*qpQ.Ǟ \}n٥" @Vߙq3?r$q*(/w i4y.ʆd ux9,. x~l[:i9aފs++6u95z m[e)lu_aωD×A iRH#rhߖ|9HeL=ņI|ӡaiAy:i tLax{sr|>G84 >w'?Ҁ"}/"+9c~Oy=8j.{W'hlQ y5K.Mcld/tmqM)ugfRo>Ȍ<b;@Q)f)Vs|J OqcU<+if=l qA;ΑqPt^>tʗk+y.:nMNWNICeg2sM_=u d7mm[^pIc 41Bg)΄2"\x}P|2 TuS I!AHh_lDcD&ߥʣԉk%/o@*Gwi(#%}K<}X^o~u+߉( pp)0nYd#yV}XN(ح<47UPNrקm>W {D{C{i坜O}1hdv6./ؐ ̘c<*u&NPNFp#'8/hdR3&%c>üYTq3=*_jcx[Kxyu ڮcZU{W͌k_:JrɄջiO5lL%BSĈ`)*yyߵ^]vs͚5e۶me ,pzy3^vǣ{£đNp nyزiS~ڴ_ta8e7&TJ;mw4o-?G{хwu G?m7Lx<+8b{[?RїN" ԿU#qI<2H.?v].ΤѤM IDAT;h/b,fͮ=A)Y$L Қpd(v p7hgb0agֵv/k} NN[<s:ﴧ7p JaaV|} obIDN6X%Tg;P?8eɏ])sf~f~0J1~s Gc+aOw׎.TNdzPVu؎ʣ܀s r'3*Mn}de3ư"t Ϻ}o6xQ9Q(x0$KtmL>\^Ńl(ypE ܻ_6Ć8E'E 9e$.SG/;(c)@v|E 4eϋ{n}xg㰐&q2i#Q§&:tveڒ/Ƿi^eII 5L:Pf+ﳢ+-M|&-)kxlZEЈm1S}㍭2QPQz8O\s5ȩIé1xq(cFi`- {awKp†0'@y#"MFզp[;}0ҧXC#|z_3-hm/L;2`I(wu^c\gBu6MFs66aoAînf^ m,񅸀uRh'_~dSda \9BSά ^)ƚXd~-g=m,FԑV[[ Q;4 [pv!Wg}#cGBCL]@a#DMscN'Ool08Zk{IglJUx߁'7+Q'τ&@:eSS6|`*4NjٟB䪪Ǚ^ڨrJgȹuβ;Vᡕ#%#4OXNc> |u2ρI)Z8ݾR'5/ڎD=HɆʢh;-p.Ti =fy~ZғudWTc㮻u%Pm_ qULv9`og "c@V2Κ7 =;4eqP!)/ PatXS/Z~)/y!6hӏҪd"t|SyH[ q{CG갥%c_ ҥiY_yPzч< /^Ex:>z~ɧu%wuA۶?θ_?o䥜WUIƬ/)y[etFbp';;Y_ng9m:c8Ck~.KNuPìw]j幵Q ]N}B2۷5"Isn* dȳzGH 8RvaЇ7,R)#3aTp$ZHa ^e Plf4([l.7ۼ%e^($=O/ -%d)Z%|ǫsC O>3C\ i6Ǭa$еs3I>Էm1 `e9eK`CKa qhfivnZHydO 're&qbXzuLX)Jj#g!X}ݔTmSɽ*ԩT3M0'cEtDZ/xpDxzB ۯ,+;*si5l*z"<"w4 7Ϳ>fx؈ӋY_,ͥ3:ސ˶|ѫ./?xFI^VLH# 40H# |j`,呏}b?{w/i̱a;օMc38lgi΄fF [oK%8a_'ڰjS(6vN;s1D}WLߴ [{W̔k&]%uXi1˜a9,/9!}Y}& {VaK) oj1vfQ7>{54޺ȿr2M,kWOcwqSO&[zڽM{q Iakii9dcq?N L$XԹ&91!;&zi[ھD  nԵ#Ȅ!r^q ɏ R>}=93h 4e.fRo1}sAI1 ;$Ax ~qi+{W^ j;]i;,Qk}*(6 b|@DeVَ/ \vy~T)_ x}h3I/`/#y O!$SgLx7K'u*/IzseR ;F9q;,цii3D_0 .rJC\ё/<8}AiF"!Cgy{ HںuxܛЌ/ 8GuYjc[!O?z8p$u3~40H# 40+?)XJ.W54'vRWa;]'v e U)^scažJylFSo/ h/묱ol;uD;q4@nuEGE!t.W;M; cS[ClCH:fG.NZ0@=zk=,6Ǖ >`vf؉L,IX ǑDNB<5{DYDUi@]G}fXm[\ m(t;ZG:%i{,ڛs:yċOAu)NMO2N({o&ggF"O(uNw]DۑjasQ e: i<#`۳*O${痵ӀDkv㾂hPDŽ%}oڕs+\ñ<[bZh]PQos:vc?IS~H?5&\3BFa*:jCo/kGPuȹ}yG v{Fi`G5pfw؏i03]l74uI k/v8x "9K3Lu8<8rb_Nfy ,;]{u60z4`6 1Mg 2]3D`F=$&~:U Zjg-9qT#hu%_$ڡLпء; &YS th{xa#M&~AvxNܩkC)W1"ԭ:Nߣk]N&ՏrhӖ.kYތ+i W&uD:3ӏUч4 #:"MuhKigu4pkMW8qՙ_ Ey20Wqy\P.l!LXt+@pasw Ȍm" K*;3 PhyADrnHa4b.>}*lr7mJz)an&ZID1ҵ=@1:|Α%S X\jz/Ht0dWo,P^MfleX[^S0*&O2:Pxha=yv6ZA}\ܧO|Ž4(h;ʫפֿԯ/TRi2DS/ڳϢtƳs>ov<ԱE3&I^#NN%ϵk^ǗB6'R \苴E_sVWgPL \K-%}YO}/1 xQY~›lI «h C yV4LՍ{0jw~\GH# 40H# 4s+XvL14M&߇)u6ĉHLm7jgS?|j{/V8 S*3mDaju"t,ҶNI̢./:2 uSOXb;AElW \dLٖ< GZ7Ɨn[:9GQQ`H+RNH[}$PK'@m;FCѮIWG-T^yA7K횖PV/ՁQ x>!_:n}x+ADǰO&Ǘ B9!@&R{m//1RDGbK|z@!-RͺCғ @nB˸Oodӣ#w: M^ Q۠bu8jޔ4u^WGWôkzC\ͻ#JE`YtșfkڕƑ\j?4(M8܏〫.y >9K}Y@ݬ}ڽ:ҧ=]# 40H# 4/Z7| g1ۼ&ss=`G;#vqͳec;j:a`{Ŭa^;2+L齀-O ._Ñ{l6u ] @]]DĆ\R) yV^;PNLCDzD+$JU̲D~R RMغ]g$B d(P's#AA02o.`fOו{$~F́A;n07 .\:5l IX^:U@dΑCԃo/qA[ʠI'X~QЯEԡ`^plZm\A V+hwCSFGz79@&|z/)͵x`6 (_5;E)8]A:3LB^S= aIVS;O~1>vz@;<I;VuաNE~7It@.:R'/$߆W>U=O#Q:W"IWҳN#cA:\E"G9σT&_d0kR*!d$"?֑)cͱMf2AKsm;?V(gynSBnl@f@MfL+ |sEYT>ז##i[W~䩕&tKB, xh3%ErQ,e|i-:ij CGZ*ý5jA>Kݺ\XXpHOiQ W}խn-w_w6inh?|ÏN>sfZyOMhF \yBLPT@(VsYEl l6 ȖRM6B׼6~ *xRS8.op +v&Pg+^x$ Dʌ37^ﻒr^V^,,u! l,E,?sڄuˋ{,+LS6l|)rxv 4!UHh֗.?vWk[3})R]:OA՛/ddB*}QƎPcgHmF%h XWV@;uLB/d9U-['ɪ<Ư/|^_/It77)O|yl;$2H# 40?zY$.g:B= *f)"Ήݣ EM~i+bK;k[N.î#ĝ@qzCw9/AAR;q g#y0i8GD-6!KWj9.p]h>3F GQvwB! sCvdl{ÒT6{wS0.ԪS0^j2v09"ravb0)҆6"lA(>(9x {iWPHrCutd /=t#Kk2K1dZK[,i7m?2#$fUSbPu, nhayD4ڮJli 9o:3շVc'"0}i7z+2*$?|i%G?>āFLt_Wl3{j[:ԉ00eSuJ\K!BQ X #-P GCKzH6D;̼ HP3k7o'b?{8h%.ݬ>e2Pݴ:6S= ouyȃW~)}ϲk׿M*V./Ļo5嗞Se^6vQ-oRVZQUa^R~| וMwʟu^yL9^_xhٶuSyӛP(Uۯ=޽G^_-W[e/7U拓a!J_KY}fiy<`ow~_,ȫ f|XMV릏fX>O]?/ \-_/xK;#6@(e-4)t৕:e#Q:~ >᥶eJ q"Cs7nN?.Cl]&#m}.ϋ2K#~y~Q_[Ggr퓥H7.K!ߧ2qd:.v#!0-C]虖hV<: k!3ڦ7H^u^e=/yԙགྷ%δ;bW cumMqP@8IDc(ϥ a擯g`]ٷcæFD"`|㶲g7"b  \ ʬ*/IAj"8-J6 G/62]!XAODU. 2r1&XR0ejKDxp IL%Ё=ȴ9Cvϊ0@gʫ$⋌_.~em^A~w9;Bgm9卯}Iy?ʛ˅[+ʷӟmX_]Vs;qEy^.~#EQ?_P7הgʧlٰ׽Q~ǞT>o}kٹedy^~)_#e0#^V[ѥkp2PZE9 xi_̓dҧ jAmnTn{5ϼlӎsDžqf1~Kȥ&f|Vv߅^jef5F7 O?w]k2iOW ZIN|b?je)>'zw_zr\S^@qo"m/\taYvC94 # _WYW.}{># 40H `̳q\cY97RÎ0:u٭_>+ Fi%|a6=v] hG/yfk}w=f`vg4<9a פALh<9YW`g3Ĭs̭NAvq;)d(f)P29] _hG9+1@NH> \˛NnѶvrDbIS &I'fh '1 ^ж,ZdB&\>gYy1ٙa%Lj53:VO~ (7u\r`}V^uR,||)ȾXްxgHd:ؔ;,otPI&' \~ 5ܑf`zSkIB}xKXJAh_^LӺ_<`DuAOI]R^ԇzr',iSNjO}ai0tlsS R8$6348#vqD 9b?ODR? f-&7g]#mޝ280 s\OQL;(0tj@(6v#@ݲyƲP9x\Ζ -y@ʫeDl/~}?.OGO^2kWwyP>s+^#rL> // כs~'˻|_ዱ^>9ojYяyL9p`%/`ln({s?,?,1V畿op c[^ZD}0<[i[#-}00ϐE1.s ljZ_Ds9.RvFzak;).5(_m.]Dd<u61=^ch }~}fuH>G 2P)߇lxL"dyKKjOEKW6 ҬXuT|#[ϏG^JM[.- P.wg-RIڕGsdq:#6䏵+?er}הpb't5]'?We~"/*s׿}~w8<7oitH# 4mjr0!6҈]4 h>{H,71v=RcH@[&Cߺo,/z: t [퐯 d":6 IW̱y]5 3bg : vqF9Pzn2xp uT8|7QVvurx)" t6P&=d>a;j7S΍ⴳ%؉ #7tmthNu|$Wp~'6y\u@Ѕ$΀̀[΋a6rY8fLMyQaڈvi)ش΢kY^>FH1z4BguR9t|A0y)O t3 mk_g,E`?w\_#өbeЎ~ %6>( pA6bPy}H|hv:[Q L| m3zLDِڂ۪j#lB4*@ka$p|2nܾ['GDHBYZg~j?WMחn1'?a#c,a4, |f|iiWxcǮ2Goņ{%or)<#x+:s6Ae ۶n,۷o)_'=HyQp,x J_TN&PLF颤M& 3Ͼշ2.<ڌTԣϗNHF`UAٖKJ?r 'Wp.O|wz8ҩ`hǹ/4rnHh+i]Iɯs,ϔ|V଼|<)єg\Ny2ˬ'FKKO?|?|MZ(ꈐ06]. ;.'QB9sMQs=-t ]JdӃ|="sm~᳟%q_Fij%h&]۟Y1´? }ݢ9)phK%Îg5qnFA?ۦj>a]$A 4Pgx@W`7f&Nr^X$F]3݀ m1je؄ØOژW=6̰ ?uLޤ6+ }i(?ei [ݶ,'*I][ *YagEvslj{S HMtW7)P!W~A'F&GڢM LxM~C>USwa?ّZ|ap1~$]l׋`Ճ(/W^TڍguiGꨋ|F8f>4هl{$M~xY{;h:mP+} =L (S`|D>RR)E}AಣHSR>e ߇8a=M9zNz@H\kyk#o /`LB%҆uؑ5$/ẓy0A Q"z#x/˓IZ/S~'~<_ݯ_]=Xթ6]nyxjt`{ue~V/wSgl/;㒅ʧUP۴БkXn/~<1Qv-[2"$ r> Ț^ԁOJ蜯MJ-'U ,Dpf*4} O{쬽=HyX҆Ym4k ܼV9a[]._i^y!@N'| Gz?`9:=i/iizBg#E=OeXeJJ5hs.:u>TIa7 [9ۼS$_|}^ RI@2O)ǘHN>sr%=? GO_9x?ATg>< ]W7j`Fv50d@L m`&X6g¼V3d򻓅bǴet`h1UbHG d5{&eDP$貨pqg[!ڨO]3zN:.Kĩ볱I̒ԡͱvN`L &I=Pp' Z;`;O4Ҷ΀JxAqbn;i0; Hxfnε.6$:/#*X!3Xu`;t,A>L(zv}I}d ͲbAn儢dIreS%ǩo:UA0lFfdk ,WP#!b8q R%Pvoc*'xQDz:*3:{܃A=&6':(Olp'2v8R??a,vQǵwt>8Dt}@\&x|XsrnںtE`|PNg̥sµ }ߺ< & :W>+-E3G>F)BʟlOw63)+Jua6{K_]^)OZ,~+竐mOE9S~)/,wJH9Z:枏ik0,pE9C4p#=3ݱ0eǮ.}fᔋ}!y?>no^t>)O= $3 _3n)=reO;|OEA!/_C71\Eڷ:RzAghAe!A>NȄv|ѯ"KhzF<0!BvOgLb >i[gd%TIY>bll[O)oہI '<; +)9E@& )@abA13P6U茀(%o^k9$LfWa+0u yX{n+zO_{/W98rۮ=ixnys%/~q۹i90+eƼM)s?[>wayǻ_x\Y^ז7|}X:~ko{K_o_2ٷ`yUޢ n>TgC M=VAo43wDs=p Kdu$ʁiC}֧Ic4W^Ě~ a :.!fD IDATvM#yw<16wehR-I=ǽ Ҳ;tl4M3dDZcC[^ ڸv|jGsJe"?mڃ^ST4 1$I?ݦ9o=~2bz6c];n4:b ! g-ܶc:tNhK/}OyŗGQ PFN _{HN#P/ LSz"=:Dg}oێ%#FђAΧ'euXڌݷX?HQ7oSAYԉz >!{:8nXkGF1TAY)tIg8-0ho'Nyq&6wgյ(%5 1l!6F8uaZ;* r G!4z,*y]Klʵ$rէ-ؘʨx=ˡ^ǹ,*&pjyX9ĚܕR~.ӻ{D,گio7 ߲ ej˯,C1w$MKP_|S~HG^~8*H}՗}˝?p6^_;YA{ec {U:qX Tu١D_ <3vwY*[zUǏC2@q1 ~5gÕKKveD$Ԥ)L+do33/h ߭s,K!ׄhe'wws?#r@{ich),%cȣ2y[#N"&Dgq;:4NGa>SiTI:"T+ UZi<+U_d3?qYr ʆu9҅h9q}=|S Wþ,:㵔iF8vwNeL /FxaZΙM[>A!2M|>}1kcZKS^OYa~עxȣ##ՉeM푧$_g|0fgq s1>.7qGDYI>hkZ<5& 9)5`NDNdOD}xi`h=˼B̜Fp )XAF4+ Vj ljp43 !,8ᳩ_3b\[cY`tce㔙{fzdLH `s ao9Mhw&\ycS9 -52C)6>lրYQv&pK޵8\{Pzh'쳄x@SP}8uK b#8L2n!gGnD|I b<#9N:6}*u籁=:FNVgfibn{&ј==Ȟ oX)ٱE$9#.XTgnf}jgF|n 04 [v8gǰ _b gyEyUCNmZ3S@Lj8M޽[o =uDʨ2:1&#/dWRn$ɰն@Uh= G7(V`!k% m($`FBBE#ȧ0Yfu@wب9ԉutyv@nÞ"x*PnL!I|dD" $vJ[_ 1wu-@a0O*_{5X>2={xWȪv/BۉS:YZ[:+즲tл(ݱlh FgD^Y qnhDGcś4ƎG)/ʠ>(b+7x\ߋЉ0Y] Nxξf8KE !RI 4;NT (^AjͷW3ȭAPCCˎAn q8SlIeg00"3P{0%6.ggrI1Ա IT5 #cj^MR^ّπgRNPOz4_Az$%Ԫm_ RρYTN=nȧ-nJ8 _@(kFj4u̘4qzmKC9;iʪa1e`]y奟[ Qt6rCtk%ę5ϾyN#n:vs~o᷂qd<?TO.9Rry7Lj$oX9>qn.LZYbʌdW~AJ?09XcЎGG|]/Eyԣ]6lXqιW~Z|7w$Oz8οоNz"ֱ3Is+'OX棛M,C wcTtPvV.iOF1&Yx&PKnz!RZgŇ$^<3) F]2RP *z0aZ28R Ubȳ&&-ܠ%y磗>W4VNN恭Q WzŦF֡Jƈ7D;6|W#@3<*߄u2W~YWڷ)b٥l:yfBK=Yr4-\WҚ<3^|%?^w_V Hw`E@yGcb ԙ5\' !4ڌ#yX[!CF~> $6oCuߥ'hdvhgQ} eƵ6Hy)e:*:]?lanŮg?_?^ʲvr5הO|v%jy~47DDǑFi_vbG` 5fSBZ࿊g}(POMAe,6cGbچpM֚6fTM[ЖԵo 6s6'MEs؄1pdVYƤ]2 Vpꬮ@&À^m[p-6J1Dhľ ] , Y?p/pO7H ~h3aoFU. CuJ|Ir^p*6-R(uV_p쏎 Tɧ@8'n]+ VN;w]U6d$$ MAD "*ARHI}osg&$$$psvY{9w^{A{F"pVܔQ>hζP]^XaCù3:N> 7G (:ܤPy֩}ePGf' !͍>~uUV&3!| wR|nwD7{?e#h .% `:#fL*UPuͣ"3Qg˗J~S\7 3 JwL , (nSd Y<P^fSCPGFXi1C^#NdXzF*,-[q獇9_K)>0a#||:/G@Z3)bIxEP>x:y( iR.!DoF)E4ȴsɷ]_E)FV'>VB!OPoFO\kkl=NMӌ!$5(+46? ^Vjh`q>(# XO:jRkXljF9:e6/xym8CK*t)'.{dfU~~lڞWNk7Mچ ڽ}7:&jxb[7_!5l7on▷lrHG>:t9'/~Wvv;e䧴?x.~ :WW=/кv~יUȋNbS _QEmV'Rd+2ilvJ{~/evP0XWΌm; ؉ig͵pQ: 0621RvT{ _LN`9kސKBlc8K;HF)}"@gI ut\n7:FqOӇ݌r82]i(֗77tB*<9c`<"ԍP^" @n< a&_8sv8 s2ʎRNLLNG \yxmH# &H5C6uG'm2.rOx/ZOpH]瘎^Uh:"HO}<\a7=S9}mx)mCڃ _s~{ݫh=H7=8np뷛oyK;qF=Ї?]F凼O{~緟~q&5g'=᩿R_9ՍG;9 }8øxsNy#Ӆ^ojx#ۇ?va]m./fyTh`FtAf?>Z~qD8{/p x2c.Xs5I_61Ìy&{}YgչŴezp.og~)@ |4CGF @;_~/p09 dZ&TlQ|kWˌ2ha;)ćtmGee0gpf EؑX L^?v^5ȓ3FNt]ްwu &:N>˒ IDATK 'HY̪Dg Չ]Ah#_t:?FZe[:r&\LJ r:4@-*wquvC6"]B97sr:t@skҝΌ #;<ؼ/uRm_6cOh8.<YSױir.]@FHW!oL="sW|N?8=D{?u9 F&17+@':oǪ> uyƊ˰Օʞ1ɗOyU7 Ƣ8c/^CВmjqL=:d6YpY|8 n ^Oa(SN $]i3{8 byx;έ31*,;@ʤL~^iwPWVeMv<ddd@e҉;qiG fX\'lrٺr Xuh#P!DG=He7{ic>w%+ 1 aӈԏNlkkJ׷c'Cc_a YՏnct7V|>w*n*@]=%'/*tYbQPYVџû|x8g]FM8|wqycƇt.y矟wwgv7}Ҁg>mciO}﴿w;y;te+@hK_v/K |_DkRͣ3:)Ϸե?k׬isv׻ܥqƏe?Ϸv[ܪ=[Wg[6ryWS;Df?wpG o }y2Ok0tn| ڛiыx\W*|g={L{O??D{rL40DD 9/6ϯ3p&]ߓ':@$d':&X ČZ{hi!'Qf*f?eEiY\+0kuKϔkS3`ffn6ײ+y=%g)e\[J-q7tH~4Ih6B\7 ?-duUͣ vb7ص=% +HZlb A@t"YG]Vv&XFq-Jkn' $(Ȧ;(# *$yM tΉ^HdN,-hJ<5~`>cz:-3olmcY>@-?q>|QJz?u=vXp~jG qd{xQH+974 Noɟ߅'&ڔr@ ȋ(hQ g1 X! 5 I#""h,[=ArExP^Zɳ!_x(оͻ JvM@,g6iCBB7#9v̚YV7mCpJv}uE)KZ,p.0Xa"fUQ՞Gk 먡ߑvW5+AߞKɷ]D ^Tn's] 󠒔O _8r!~8nEt_чrI/ lBF\ҳ2گ>W8bZzpK[vw2ǎJ^'jK}p(\:*>s;܁Isrn;묳-yի^vIAÇv͟{ ~<8.wkhR.91 _e Wv^xa'<=am_YW}i7바u˿|vZN}o/~u >\Kjk.'4ۧ?w۷οyG{ޏ|_M|׻f~w߯rJ-1{pBg>:_җʕ+>\[3w}**>o0t|>яء_ 6:;ns9'>= }k_CO{z袍WHҼҝ L405Q4, ?dΙ_ϵئ_͢seۼ   0=8?g;36dV^c[Gg{uИa:<S^M9@-B]7/pf HGl;wm3ٸm }rR5C~'D=aǩZr`ni#Ǯ{ 񤭳@+61G~,e##?Y+5C@ #&!Sܿ`'lQۨ^ߵI(3ڃ2$2:LK87y 'z=o;2Qb;G'~ӆ!b?Nx*эqM9(c e$6^︄a9Ktt]!#ED}"+U-3>r#P^q(H9ZopoxM=thjoT1A`F Dr PnvJ T\%{7qC]7e+}vu\^]9oL<,TJ5@2*W8ć͛ƝG*.'mWKS-[yH  R6GHbP\L!rE aMM2"xDȈn0)K6g{ɑ32sOq3 я)wyuUboOU{˾o{['>v8!}ݷeu_iD_d;.wZ'z oxG<3><9a6F%/}{<ܫz'>^'wi7_xԯ6>ϵ; sBB{"þFmĕyU; ׾v[ߺh_y"zQ;v4{ FI\C`g&j f4}n95fV[f>#09Y~X9͢L0"Tf 3~7@g`{ZGڥ(vXq2w)4v^_xxǁ3ԀLykk U$jfGF3T; hYq6Z·3F(؂Qt<,?xUe>uTuk񅶾4>76+=lY ÝM8q$|'U&N3?4ꕍ,+z |tglmanrP:;ݻLj|ӃͤHJ.dW[ie鵡8w_P/ 7 lؼe|}zid4ױvL m,2KS4\o]u+-Eu:gAfx!pbw_ksub:RRk1:"grRz\D*O: ܰ_c x= G:V"ϭZ|{j.0HA!2catfގ _$e@y,ciעPX࿄ygkf|3j{y)tl!GhWZ, \/`ݗqWmz?tM;6_僈T66[#80RL>T,gFd=DC瓟T)z~>tԥNJW罼N&h`k\'cYf=|L 8D`kz$`)fj2>ߵ C{E{G.rߵSfv_Jͫ,K"Cm:@.<ҋlz'/ڥsp,o(X`? [ɉ-7V7@ygvjClk'.F|", Ùܤ ZeXSE83siOuB25C] Tq!sVZTQ4p{-Tv>m Pc7Nc[~ :2  Y0b!migW\9-D~/@ ^:mO!혟~S,#XR7/-xCqɝ^Gx_DF>uWұSg<΋j LLJe#0F? \y2Z=ʃm;Y{Rr v|hVyIk`.G GƪMYKYDp{ן˼L/v“4`q:ey "} 5?A81=iOql A|WdO(UVD(W1WumO2Sѩ3Ng-/"j=x2:ŕY]NP14҈ P;cTf܏hM/{#˱^:@z١"?h֭kzj{3R},&+lnzyCg&;U{o^MK)9?\O~g խnپpt4On>y]tQG/(#Vj7w E,COq3N;x~w ވny_^} u?3snYg֡sge\2?f۝x8򕯶?|PFWMoZdnlڿ2|ۋ84nJ۷$2+}p r׿ѥc,D L4p@@Ԁ`8o<`98;cX"F_\YC{l7L='q/b`Z>"KYᠫ2c|wc;<h:$M2+m_ll۲A[\ y61<!K qPs@`bm8 "Y`+6+Kb-Nj+f N BikjAl+Iugӡ7%v#]K3p-vQ6AEhs ٩~J@r8 HΌ:l;[ښΉl\G]_kRuvF<,$a)WF!Fh0C,^Lp%rQ@Yg=} ۘIÎбsXnDj7 ōʧž-gwbwFFʐ<ŋίrWdlc7t}J aέz)շu&RpH}x҃Л^aQF>uepGtFv*?5sGFtU"VA3M u2\+9a:nW MYj/v+{uO~RX'>q7q f l} ,`5Yf>n[ڹ>oOQvѷM}پ}ȏ/n(v~M=A]z7{ڗ`6;+~I@=D0HG?km\|{/c~4ځ_|>A6t=:+-QUFSp?^ɔ1™Owe;]6,tG' >Cr{WU2<.Aq>vYg_̯+z^cWRן=ϞD5tGOg{]62=};9&h`kf1Z[o3C!y_\pڶKvHwřBwrBWM m%?#t0\lߡL-_Nf-/ak${@ ]( )2dqMd68kg\߁~T '_Aȅ,9&nv:{1ӛ= r3 ڞ\,7A\N)aq@ }`-׷4 6+?<,@H\\N8inggƷ۷P[֏Y>'CUѶ\m4J{ IDATe &*6v(+ Yu10*"(zax!I"/Ǒ{dp;iYƖ26zR4D9,86,܍4FFzN;.Ƿ^U(]ۻ=OG?{k{yؼqec8rNN<ݔ{~8}?r~/Lў-n~G۫^vwǝqDZud}\eJ{}埾'ܽn'G(N-D/p+9oN6nL np'x\e/})믔<;D \4DfJL@B_v5P@_QX,_;|y 9o 5ҵYeޜ'!$6v fr1 GgIylB7sqB P|χ8id-!Ra ĴKL,y'aNd7lmb0Z`}AL*aڿhK $OH0?oAo ( g/0F&+#g&'BM"xG,]IM ǡB1s\>)aDc3@`R5,^9376@!왖2tNi7{n΢;9kӾu!`zkie2Wm{I\3q}|~ ץb(*ӑzvRڶO%)ǁ`]eʃrXz J 8<ԏTH3>ͻb<$ܛ ZKXEٴ:%еYl ^W+tzN5]Ҟ1JطYQ<H]䩧ФSOB,澺S^^p^z{4}g2NorKyyIפWy:R+n^͌ś|=k?2˹7㎹V }WZҀ}'=h&hsv{^!lz*13 p0k75SHLczV=Ljo5Man[Yaج`+1Yl6Kv΍-/5YA;3vY{: WWG] ڡ ,M(>T[pF_bW>!?J1l]bڢ)%3k+(v8k(+u\Pb6w$U0vY/u_Oh(7C|ôNP΍WR!-2q)iےȘIC##[zTv|~T~Gp^ݾN#&l,N;Eʓ 7B"#mr_E"r 0a^%nס| ~0" Qȑ!LL o o7;%7 "NY2%aa; C N"NBS8Wzh=|CI -B%4=~oRA\)j]*F}cs [x:2|Fd$;|4`R|۵&-.b߁rc w ۵A_Ko= -LaGRQU2{G~s7^( M% b[3<[VC_j]Ko7y"D,"Lҡ.>,kPW-)HYaBiC@(X(+*,(ô/:O|Y+zxUW"8!zP_8(vUǵc#;|xtrtwȓK14p۠7/'GN|isfLO40D 56`)^ٌa!hbxojRe-vE6:ӎj a: 4f]䨵syÜfy6fiyhj u'!Ke#QNGu6@H4X:Mp̆yD}b/`ՙ+ O6 .LTjmHq hšNq:hi&zn=c lya2Kbjf;ҌL|6Cxs :3Nh'(4<3g!hxǍ YB{t%{y7h0u^عgt"7R _ؼqdQ64Գ|ϐ>W7T'#pu]RGq0e[={ ֆN&7K6&:arRYAC9+8\4y ȷUԹH:s=,^żKfjf ̷ z 3 6 V7y \; 6\5|ǃ@ Yy`M XAaSbz()4 Xŗ QH1F\ d)dOʷW\wdlI~ rpuYGEmesF[t*<ַޫſ >ԏ×z}lb|һ_t}O˛̲13y D4i~ Vӗf<Լa߈iBy}ꗒ7XyQ>\$&ʘ1MqSc)fܾ /з3/:tv锱r?<vɏ%BQrz<:񾶬oG@E}yߧ>"^Fͼ_=y& xYT7}l)E؅X)ɓSNIԅ`bNfv[zi~7 v{|]`4k55M:+@&gi DkMbK `bMJAWk۶y9 3HҰhcc %?v,Ld^]PO6y*Y#sݰ}Vymv{7.Z@\HjYi@w@v'jm>I#(?z5[g:д+F#>?&X0>:BpNFc238Zg$^t&^Itx/FG4|&60Zq%z$M 'r"G`K^U,_p`^t β}y|aQԓzX~h &S!? ~:dGdž}mռ@Yh膼Iw_Lxʞ O~q-m0FC ލn`*J~|D2q U@thd4"J3oFmhGSoW0ۃս&tYi/ۓHS 0 B7M Hw3.u#0 fD>98*ag5P鴚)`':l$ťn=(,K%ؒW[6Uj4J DJ,?ꡗ ~ ec5Ut@>]`ruבKO'oMyD$A}pۦu~2x PMd pMl]{c,s}~ t2vQX#qNQ@NŒJdRUP>콟yv|(y:zKP RBgwKm&ёcnZX1e~NJNu|m=ͼ_[u>{&vkk?`gO#lI:_$-MB6i.)|X3/H6vn@`/vNBL'$ :I[#m@ˠdY%sDKaАyhSl>VH*@~NtEC,+fsrg3i}[m݄CوnӡI;hmlے m6J\v_l8+fCڸ( a A}҃%) @OJ4p)ԁ2( ց}Q^Ш~`zx׹0'>_( :9:|یe,['ͱᡃňJxa0ִOSP}6ǰw)r(gW": 8ő }g0d 2:LpB z1zȔ$[`n(ۥ(ό}R(iﴜJCe'ߡ?9B:tuxg=l3r_spN?6ɷORQX&Jp\ԁ~ƅy9F~o;hOy?$7|DZ(sPu)KtBD1Dp2`&o8eRr8G k)'h`r 9/ /:=͹o2.v(Dm!SȺ~c33P2μ;I=50g}%9il)%ۍd"y |~&q/}Ҍ:4M `7i୑o0`}iXՁNNg@[Jzصul/|8hyy e6*BL36@> pĞZv#ByǽrB;b)0‰Q!kfYϡ覆t*(i_/np G`R3kVXaZpG礌3;.ڪ1120rnT;m):sܶu2!L:55"p 5NN7WBIx} -u"pQ)gk: -[eSEIY>eـxOE~'VDFQx(}3:pc?o_aQb9'M/5hfNu 4T5dK6}Ec@W7)J9hZխ S4@hB<U t˴tI{|Ȑt#Dq(?G蔷#Mltr p\3ˠ7dNS`xȯhBjlfhOv5t N^^GZx~n9HA@E*a _okj_F$FߎޭQ:zQ:!]t1-O$>`3fr3Dt$Wd7«?BFT9yj4a87=`ȇJAjwlGr/!4/k/%ߔ}r?6~m&hE'ڙȩtmjm ҵG]\:s,R %Zp-`ߍ0O,-$n܍;#c_G iVMe8"ɇY]eH_BhBc!=2Y$zƋJA[vS2Tb{r34 Pm fvKFIhbh۹`.[BEW4zaĀR;=̽ԖCV6ѓ_Q18 I|g|G&?<]9x"8h6\?KW#r7 b#%=IE$\lՇRC!^ M% y p!Yl8:KsO5upg>uQ4#G2IË+Ŀ}_ ΃ز^KSi@;Cڦ\B;ea~f%Y p ~Y%8x;/?:p(,?0Wv06M@kX_J@QFyۮ<[F2) ӓĵ+VԝZ+^&oֱvE3#ۤQ0"5tHKd*x:l- /Nc[L$@HJ7Up߽L sʝ73!CB20qS7B0卜p|VRݩ'ؖvׇGR7r9 Ц܄nnSޛ:T8:k#)7>ۓOr#n:.H0 1+Wf:Ƀ4W.Y̏ǚPNB^rۧS)~c-TY7K#(}{j^Mkc&M40D L4vR~gocikZI ˥kI0$IBdjjhgh3 QN,}%G^։m{&쬋3H !Hq" #l}ƹs&?6Haj&uՎ>)H w VbSb^c2.2.kqni TiYp`@YJ̨g_%1"` Tm_΃a:3 `3Ϭ^-^o @MK;}jqI: 78%N!:Sf# ;M+SAȰGҜ]gsč? 3n:+ qqPt5aBkYnp!3OQb# 'l]} l oi.`(٩ur"Т8GvcvClӿL9`7惶}$fy=$0KN|9e1`;a%;xtBC~35fH֭AJGC `y d9ByUr3lL;s kCS ^i$ >P: 7pSumɁ:"#I]RNL{i^ s !?жf'X*[тPRtt@b!LOI8Qxڡʚ:.H۬<&:op×%i++]* _Л'!t ᤹XRr W6ShM6Srjz>ܽ)Y2#U^ft4@:~~p`9H9tˤ>'䲎ΗoJv?IJk^#u/Vc:T$ڇ|W?[dY]@?em %αQ y`wtr_??_؎>D L4p@ ~CmnӾ|^nLFi`Jָte̎?؃]!`'cŬQr)+^SD }[y(lPC(QguDI1vv<8I8( MSMF> É,깃$BG, 3L,#뷶kl玜3礕cBJ/ԙ M09QIW]NZlLҡD%$2!Q+sf:^,/MƔ3vNN^~Wqq<^㩧v?ZWz ^#_ye ,p~FxN_@G+6rpV{7c:|1[YNXzSl12px c$yRlm!d()@ܰ: ۏL٦ \}˗7OX]e{@=Ǘ'Q͹(2]0~7h!Є?6KF7>77Ct2T8:IxђoaoNl7ZjnTMF`0#XfLPmۑ+i)΁FP>D?ޙS"sؙO '?y8ůiq@ 0TS V~XA3X9 Û UPwFֆw#`0@6qYˏ'D L40D Bi` 3`[6zyvy p]skgofYZql'r--2&mZ#f0%iX1dEĦvPL*6H0V LF܊e z[̒D9З/XieUr̡Kq@H3C搩LnBOg@L3iDMڤK Ƥf'SsC<N{XuMb9hP=@2ovHJ!6.?`8|/a:'/K,Q:i"z$66uV( 6_&,#Fp_YH$p~c9 +Xv`8BZLq0)H>z:Jf'w"Q̶fM;Ά|G94%"nhl..̴adgHҧbM:L䵉1Ud1Fe. 2i&VO`5t?#/p'؆~zMR= v:(9tnlFNgSod9)_ i?LGQf2}8p=Vae (#Ls"bnvحNh}⃈YѾuO|+wr{ɟv7pl'DEp%.aGτ' pt Y>uL׻AiҍN(ngy[UnNG&1r] Y\- 7,׶o^m;ujyd2:Vsi<Z-SF}סHڬ][5@i[6l'NC-[ulz#"֍1wlG<9E"U&mS^lv獺pNJul~G@ z8jl_K=DH L40D L4ӆ9Q Q 4Hj7ۛcFw~' o5ᄰCG0 *N*jg?ut_ءbU [ݻ0lXLc+2ٚWyrH9MMOh`wa ]Dkmn*+R`Ú"_ CO7Y+p62g (VV q'Qp)p4 N^A59sL٬O d!׫kKe7jVN3?Q&šT z cg/4l9XhW3m4 CޞõY0GyqTҮo`e /vrFY;oZ" v,$僈DߦbY{ l8ז?<"OqzP} v( :D.'x}aJ4BGxuI['+g~wGu~ `Rjg8_>#@|"t0CZs8ZHd \gD9.fP:K KLQ2d8I;|Psp2ry;yXi>spR;fWfwQp-S<30]1WG3y%rP?@Wɖi|sB܀ih~L *϶_Cx2f|K5m5+[^Sq0;5 E+QK#7QAhe7P-}BdFVV26:Jj6sy ғp`4FCiQƌc&oôC8CMz>d#c^ƭ$W1ͧ-/1:QKs}GH33D L40D @;`R6 O77Og gxşZ\2(G/ lf @hKszF*u3K?V∴4۵HkJj[9M&jLZEm˵K I,Ԧ|Md] ]E~q4a]~Ćetst!@yQ\} m=/7]ps5OYQi%6]=zQi5{f}}tc-|Q~e78,!FP*m`u'F Kϵ@7y=gAa<2*cċkҙ2D\1ro#˩[nQ_O8ِ|̐KϺvga )uԑRȐ0էĴzF'*P>?FwLF3HπA(y<hA?o4@3"@ĭd92Ddi@1ț*=pb{V6bgx D2e01CY@7O^ Вa Zr<;:K87-HQ:iGhxBX:97+2ޠ*R-O݀CC~=ڛߞ[d,ζuPqcw!c{ ?C>M4kY SN \^B9(ȏK7ϱ x^Wo^{Wի%kg}06L+%Ck$!n#H;Cc'u-~x QKz@?^b*Rzy }"eߊ fv/tR>KO'Bî;wcG;t%6 g^ ?(kAWچ3>&<>F"1D L40D L4 2k)žPeL, jg;di;tL۰ؗj]KP|> -LD:(~0g5iY)u'| {g J̓fB~q@Me3ˤ:ثd-؈}/3کR_#.i-C]]糬!ѽ,#y"V_Ѷo>odZ03;ؙ ha euڋYPth 8hllEut PLԎ%yq3OKp@o& W]_ _{{v"|4mHwJ^Gߎ;È>w=Qf[Y}!Msv Nӆ NU`y,!#۔W31ږz+#g\t~D6#ji$w; :5Mdg7(Wu G,@G:tz7NλDTE#);ś SC?eMF$y$ ˜!: #C"F  SUpk{C竄4,5y]wkO(0z٢0p W@F̶Jc]ً@>8̲ᠥ K{H]-i_!WYo|{=y(k>~O~Mo[liAnodptWQy3CM役4N:XV=l>|)Cڇ{%RƿL>PEem ~H]3K5ȟ#W71J;FN8([i! F蒧#!|/i K6-''ܐ/Y<(}B>[_SuLc&HӥFG NKGwI+y.8co}}D L40D L4qXcSشbOhchViVr6h5fLˉvH4ߴH}g`y85/iAchQ' 9!h%jZZ3F*t4Mm醆V6 ݄}HZ4b{pҴVN@і& őXKW,MJVa*]6"xdTy[| :$bYrO4ݙ>̖վwBNUƐK<@À}fbk 3cA<,PIWp[<2 \ a1euFsEZs'Nq~c7ɚΥ @h..c@GvIbAvIC@/:4B[^ym\,KF!wms 6y9ň)h0j%t"~3 Neg]aS«U̼&y'f EW*JG@7!: v4{ڜq3pu{/U!bFU+\bsG; F/_Ys"2*FR/3|HgGX0,S%j;QGg+yŠ: .Ie=EW~x|keWCo1}s@!?p40Β1)!QD,!avm璆:MrSR?h?QM*}-Ί5R_j-2n2U6LqГ%@ToMiH(w ;eZW\@˜$Y;]ep%쨊ȠkCjfZ DGFfL!0Y6 }äwo73Kgv]xɎʫ)9}SMM~0;O&;舔p gJ'hs9ѽѻ?4vmq # 5;OڄÏQ6<A,Pj_7ɏIÃ}h}cJ56)M`D&e&&&ąB[;4„eL, S&=έ8a 2d 3b~ͨsP{V zs<3J;ZGle Nc>֛9յ|OT۵ $iGn}8_,Bځ5/5d!XwdLŗ.GJ&Ɣyc)Ky I;2>TkiSSGK˗EO3P:N)Oon,cpWOd$Fo&U93="^o [E,97I) W's`S=Ypg[`εI42V̉\nV3^w2{1 ="_tmU=Y[uZqy"huLƄ˧mY^+߇^ vx:>WѱGDO {iYzZ#?Rd![6sKHq?zי؏ѻș\yH_+`A2`pȗb Xx D9[ Re  XPPvQ<i@#OmWV >Esj9P.ZzZI[s9I&(HwR,{M֝9o0#o˓) gL.[G\-[8bZy\<*M7'i^8҇N_3< 1b,m>PNU"}~>~\HdF+2B~>AKn}v^ "CJ22wAqn5 :EX5 0qa~gj3n@D[ek5sOI|`r~U^,"o,K*:~vF*CK#d|~ő/[sZ++=)T6 VVRH{'xd֏L򬚩KB>rBN: tj Gn܋WUC1FUk%Ǚ|Sc&' pf@A@%((U?ޢmEuW}c۹bMTjA3 k}SőEu/U?U Wq@_?ՙ,N$L_{ΪLu&1 ^ofm'g~͔w82zET}nG(s4UdyP':k腂ZW~h>EFq LW+ zzPVz*ƫr$\&׀vHęxo vmQʼI5,A {&lگSD }A^Ǻi#_Hae>$ֈZ@"Sf}t9d Rfq0A((SQmk2* QHѡ)OGdOt @!~|PO;C?m4BSHi_ S+³&BΧ>|Nb"KLپ Y$(B˱X \[/- fO$i۟Yڎ)+guXm ӷV`H#R>}qۗ CcgKdsu@ Pi bnAm:.RYc s'kpr,A'_Y0=Am/2-7+hH%Ƴ3l+RzTKr6׾vW Xl+ge@>SD9wZH5\ N: t$%,Uţq#@Tu)gw+LHN.N@΄񖺔QVu6ϓS/%+1__lǛ` #D]lK2ܰ<4$V@kLb60== tB߻I3\n@Q|)3`O`)߹](g]wDD'A֭72!r"E?'ur`)&bg =4Hd?Y]F3(o6s%X顠{PgOSN<z}bg5Jfjc}MCRU9}L-DOt yHsd[|ȷG0E$ .;t@X<=Nak2WQYzn^7>v4";: A)>A=\Xտ1`h{2䳬Moq#ܹͶm߈_6e&D*_07}xApxkCe>HVh׻n%F2/^9ұHr#lTw5ukL,W6k|>?8O?߱'P';rkiMǰ'2巵^9dk/I+=Cm9\z@r߾R>/ <^ _<q7oe').>9b2Bd; ?$LË?MZ{%7~Z*z?ҧ|յB'N: tZ Dm^N~|j9(Ψ3, X_xvQ1I@eL '(K]SQ ؄ZQW +[1^ TShmLVyif)MFvb{kh 5^fk|p-AԕKN7;Ս<){FUNz1>+61TRut֡_#Ee"xla TE HgW\3xL9O:<Ol{|֙2`c+mH< ]Js8 mrV_^\Ђ|Ax4[W Kso +cRꑡ0x5h2 dDnyer2>kBۀr=^\{/F %ag_bXFԥgr4[*cdو]Nǃbc B\w6m~vPkbl q3 f6k@[hRw% M=P ZJSm|;ÒdzWˆfSW;˞BWg뗟kZޔgصSصȆC<`>ͩL /+k_TUxrTyN8A}Q_ 9! ?}Pe yiNyaRF~j,I,K-dǴ#mOc2kg9*7?(Xh:)>|܊ $RdN5D>1.q;?y.!ܢ%` m[&}\Ql5VhhyAxtDzʕnrS:V۾;eM t: t$I@'NK`!LT Cz0qK *c>k(/ jԽ@/b;*6M]? R?nv[FZGkJ i1R3@Wj5/y>?kd b[Tv,IS Qg07%x -ꖧRN<# .Pc]:~;WICre`GFdwzscu(z-@+A2ACc(Ikb tTߏ߶iAJ* -P cFV++:`P3V܂dQ;F ka 2BCWrY0H5s]z:qlo͘0|߽M^m"x'>|<ΫfNh>jD䦬6Yb_yj2AxPrf\(_ LE"^Sd:5[6^V_v8"F0]]Uǡ[8yïCh8!Pޕw9_H@KԈ92v ضIj{hS(,51оZFYVmzz') cB>=X"}CV1NHK: t$I@'m[>Zqw6}~'8 :xDUF`AofQY\mT<f?l7yr&_uK gvY:sr<^sm|A۝?tO[ƘiQ8NGpjmg#_v裿*h63:ĝ\-ޠc2/B䇙Sԫ9'XUGLcaqgϮx(wlT/δ[C 0:\Cږ=5,@3X rEO|y< 0\Ї v5k59N![ Iz$[Et0/1eFkDdX;M#s=AVm"{fz=tP%PD5]A;{n{ԫ,EA/zkuV F/,Dogٹ}g/?Ч:7ß.޻6sdl,|36FFhhfWe|(cٷ/:e6٧*.}ZrF~FM]M? 47m-]8O ǗV^e͛6rn<1Kahzoҵx><{/SߖAGgcH*KEjꍇ|9]5KR`HԺ#zGrs0lq6 Y]=^ Td;˵'6-6/0$I@'N: 4hmV5hS`_b=VW-h:z=.Ant)f jO+Ɗ"."Bԙ6 ^Q`̲A E!N.2wёԑ4Dy8M 9R_vz. {T 1ix6X: ]-;w3: ?hZىl18=?v m@^]f[e :-LV( J2e19N@,dCj`z{BA-43fL} =52x!nP2n@6r:wNxq_09Y]`AJ ЫOkhHLPS^Q '?hw>dQK"4@ >3Rc>fd|[βC \l]n7G]޵C &lJ S1z~TX: IDATv*x!A^4@Qc]@ɻsbP-6;!c2ʣDjl}tdƬ<Թ Z8(` Ll7ioJ5;DFDB#`\Sa5"GGPwFfwN mk /eWor=օG5e70 CYw:V;YOЬkAfps̊ۼ.!X^³``>juw=~?2Lt&t&U۪tuf?T+cpA: :q s7~?9k@ {Llh! .=ORq_O7~ye鲄\\dQB=;) saUA&`uw7 l2w6Bpu->SDgĀ'GAWވ4yq?nkeEtR΍,=}>vwQrq}ÒsP0^!vqMl@-?9.֫牃c5elf2f1Z7WH PRKO@ܐ_Qh#սKFŠAU䗾@01=EXM>Yg'k5N`D J?'bس=[(9G&HzcI\!8TckV:c@K/  1X6;K`# 9Kɢ l?ĭZj#6 _5/6R l ^QҚwN[o(d}qݱC'>1N,)?PyPLyf\bß?F,gMK}̪|YH@P.A_E//KO/{xegZ>{ ./z&;k~ௌL@'N: \i:{ 3Ы;Dsv 3z2u 2lły$`cf7[ZQf{:ɚPM1Z)v08.6l;&(/ t >!Y &ХrryX}twKOR} =r X#U`z$p>쌇 j2z35~𮮸uf{d2p V&of%m &o^ngל̞ Y`3LqGGVO@1ٓx;+GohW >e@c\8~o)lM6#ݺ֝_ n].`QU7;cL)@Mqm5b'@s^6eg g }f׭oK 9l:B$^&ny#I8  v EpFǁ|jT v?njԀJ_yLpX2ǶBj94AM@CY<Ɯ;*ENZ|P [ OjhGaLЕh]G{]^ `Y:cQWvpbuY`uvwU\i:uz,w?]W̝'ל3pJfL7(f} YkSǕ ƤM>c{fI2AǪ-r MYYoid9B[KC-ܛǒ-K6 Bf>{|ܴtm2UFѨA?. A^$)Jk\4 ԟ"[GI)?WdX?w|}[9pPySVߙk?RLs\Ʊ/YncſT.24_#7R~o,{h˽o,yc)w]y^_?WUmDr?2{թc ?c?d?O:}tٷ8`͏IO}g#O./yΣ2 qr7w~l5g|K: t$I!]_[ zDcTꥪ-^uL$&h^sݨV Bau\Yp/0 K hx{unn'ewXkgL~䱓\qV6^pEYۼ2U{Iu;u.52\|@&gSmA}mճ].S Hى )J%F=`g{,53Cӯ `}&ÆKCiA|\ĞgGRDz MZ^Y/#+r7?xÑQ?/˂Ny@c^C@?-}%oa##mZuv2 ^DPu5OibɹC8x h}J:K)Œ!ɜYs^>?ǩGdRo=uA,#1#|B#ƨБtz##) 5%| 1 " ߖ>>F$εFRF޽!n[Ys~񂳌Y@U9.i~"j #Y B|xHxaېQ?/ \`~'˽')xOӧOOK _@[^gECo;}x?_ַ𒗼U,O,~m`hbt;e?׿yh_pԩKsg>.~Ky/꯾%t嵯y%F{t.W#1{_~<1/fgG$g_k(}NJnOyԁrlrziZԛ|_>u̺I@'N:j#eRP.]P.ȨcqmZ{yRV/1 0(`z~8߳*+AYNɊn° u4-NFa]JmutgY %g"誷znִ!8GB\ aRҶҏrSݻLĸ(# LR Ǔ1n([ꔊf(+)F`GDא ݉>vtZcgw0ި~xG >4EXռd1Bs$<;K>sIF&Na{wiYhc|˧I^ogɮ).϶|/Xcݥ(2F)G0eBL.1up7l lpڶ-+܆ջKZ"^6NtIʼnmՠ~4:7&3,k`qr k١ӲY-4 8 @ a$ok(qy$yw`ha?D3/IVQbY:Be¿ Լ K[K=L:(y$]hRΡ1˥-@{x<Xq[h^hdԐ-/xngw}w^?&߷{ueGTW~/ϸ;OOʓ|*+G-kGNFϬ?r?𙳗%;:GFJ>OK鶕\.u$I@'ПW' Uk|XD gt5u Ty>sf7 V)!kqC toygpMܖlgunʝjyȏk}fI'ç,/n@Q#m`j ʏ<ݒJjh #xM B'"8 ǥvED5qkDۛv0o1d,iV{94&Fȳ$->$]˳^0ͱijn=6X\@;!ԥ^&Mn:oԑ]M G8G`o :J+ZsCsy x"2x,o^bp.;RU=qukDP ֆ1%1ׁmG*)&g5x)؇T xѾrlQ00 oddf_Yo0,hCGY&t+.ZSx AjaVt[kⓓcip *X -1:%s2!eO\dS@b>piX:w >49N{S&MUHϬdI3DՂ\h{\(Xzu},`=V;rv3٥rʷ[n}庣{@j-x7,жy1x(pXf`+%eR *2,3,~S.+"/6 P;0]qd>(BI0Ol[2Ǟ<%D`8K #cnǓc{|KЏm}Ip\ G#ڴK7Z+xb3m(>N5h`,e?yC Yf`SK˫ȗKJ>ڶ*S2]ubs3`Osr_q/|a]Bpω9馛/OpoSwNZ¯ @#n~C Mf3e4v ?{~7`/QUIij|${$؟{Ѩ]$I@'N_ Iٷg5]Y:G`[-x<Mw/x+8NT/fF:DңAYV`x;*赋DgI|Y7ǂ큶m`W䋟F}VRf4\v>qԠ ptnqĶ3 @[n̶+2tm)PЀMVt!AFM 0 LioCxe&3ܼLlǹ[M3ԣw:;>,UK ɓU's`i$e('q6\6 {f]ZŤnS]M ;̘-=tf[x{=`%ِkyPƶ+&yj&PNdK<:1XPz su`c[!6E=rh M tH{15ǥ86jak t$qB Oqs0H0e ",G)pMP6u15ȈnWZ9fjw;o:llOk!3rn1Cf0W"0)I`&sgum|SwDݻvBa\EESlyʓo+@Ա'ILy0iO HkH3f#ce왅@ $@YCSWsrS֛Dތ?6d}"g n:/)vV?|ȏ[CfC9`s/RCv.X? aߖ4%m<6O"k06m:ǎ?0|ȧ\_w A`=:>Mo]=￴8{^nW\ts\;zh {YoiO/p[oglrEG<'wN{Ibny?Ϭ[R( ქI!ol?]$I@'NK-8E8)ATV%UC@" yߙJgsc]'僟N3a8p김;m>مQ} v|DW63*iSK pwb`謭5H޹,@k.і 0<]6 B~ˢf>Fs,7,2zQe}d 7.>E &o#{-dbr@5|b("͍u-wI(c*(EUCWsi8v nX8R,8א  T֠۱GC@_^X^ZρKCD{ yC7 i.=gxmgT^qYK8aq#o. G{N"Kνn9= v#W=ASgFq워Sa^A_ă2Ƚe| Qd\hc#-Ncȵ12h)|m!zfYD;BNh+ہ>UQT1q+:¸Ņ GK IDATRV!pH/f'TAs+V LYnXj[H sdsxkgn(vؙ{iYús;9ueYDV;)NB='a)#cˁ*!/,-$,M}P4<#!mח%kXu߽{7"˕g=YӟLyӛߜgh'D>F܁wWN<~e>Pst?hmWz36ʳ|Gzݮ}ڞ;$I@'NBm-/ :Υ 'z:Ht*b}P[u~] AdU4c׼7:p nuq6^@W}!:>&v6Q9Zl2$ԡ `wXq65[Smue!󶏏צyBXñqrtR 6k CEGF v?&6ҶRf7 uW`/Ψֹ}H|k|q&ކjŪuuA5@13-W&!RdEmqx~lym =W6fb =qNY>^}!Ll?V=Z!ˋ a<Ұm_?C'Q~[;I8 #-?ɤuuoT^ _c~27qB,djBHւvh4m '#ު>(D)a6@e\:OPKf28i Z;DfY'1r1\0hNG;-|{D @9|(er~僼%'&KdYP4tyg oCx뽖uXW{[ޒGU4bd9kc>n'W.}>z_$>ߑw¢p/-x4^숍snQ?{WYYgB3 rr2x!CJ=B>a1R7tu? !o^@~ -@dPv`~ԕ\OCn>͘GNϕ,eɡVL40rd1+^Š>_Dn":#Cc[qq:7D_S˿<_>O/r@Ǖ'>'>W^"vxiѭJ;knd7+ hH(W^)[EIw}<o.?nO\J'ھ3sU;#r򼆼.u$I@'k/gRE<Y_915t(WwUuJt*T*XG+Ҙ ͵,АY[ onTd dXdO`Up֯Mkxl K:pb@@0K拷J>᪬ayt COy'缗| Cnς_+ }@0$\_ -gyu z KtMhH.\Ή,06.R`t@ɝM3K(̐\,-̺Mu{xD#a3S^bT[ぺ{"n} hgR]*Cjk!*3&k^xvj+8>K/ʆ~8:跆 3=)3Qx6Yw}|&aE ܛ7w+e#M e/Gdcpf0+ g@#Ā&oÔΐ { -(6T2"_@Vd`+ ":5M^ G}ُҧD y=DKkIl"Z)/mjmEٵϔg5؂1$'n&׌/9cÁѢ4wyjpJN4x/M{u\z=erܳC]5"_d񢥟}>[\_x!i}C1F{XΟí雾q3jbR{S<0}~ ?6|ro_|7Mۃ#] gNj>MϷ5.~j@~?l]O^3ܾ`z;$I@'N_ ,[ " ܝwTu=%3;AV"濗moP]j!jWx3 p>Ǡs5;墘Ug/!{s1kё[w}(ENk61 3[F2E<ԛh ~GުߣQC_ӓOK+aFnHEb48KJun9vH $ $C\t}ؘ%u LqV#6"o^g? -~j*V%h_"GD+mxtr.<#hbLZOd%;-{CV ٍG~5r-ese^tK˸h \1ta#i/`e;^Z)3,xqD`cbΖ3V KU6|1/\1s}# 3`le 5[AMj>!N>=`e0TWAǵݙԦ_[γbqWG $ǀ."&K0 *`Ƴ\>de"IuPË'ܠxDiC7i ZF~I!AQfSA01 ky.k4z@ 2,\;ʺRbb$s`j.>C9S!'jM#c}e !/,AT墜'q֎sܾ /{ ]l+\Lđ`0zo5tR}̃2Zz'Ie|IAKPJ.}^'[j=P^^\j/sm&FmNW䍑_^eǞe5*LӴl׼`--O :&[Mme|#燨zXu)&eNDdci #^Az ྂ"]N: t$I?3w-u 4z8k]-ӲlzFW8y%xc~AT*%\GT蕬kk;$PFqcv摿ۿ[Yaɒ@ c LZO]Ea~CZ\$bғ&0jIƍmRJavaXFP s6f G\GT@Ǐ|:tl04N=M2q炴E EK=FĠ$g`1hu th IS~1ÿJ^Arv{<c/p]\J^[z 8uܬSI]b@Nf\!sn},#?ѲBO:)=_o;K.Pw cA ,qePlr FF^jʋҏ>?7HK!X/O A@9gMt.tv?F~|M|[y8qЎyo44yQ1^eF6VAF_(i7 .XWB<+_5od\\p!93tʨa1&|)[{Q|kq+N#wT#<qWr]N: t$T}33I=DZݚ ?UDU =D ޹橳rz:E6LE zQtyO=P.#_I]"﫻GN$tN ScmQ֙aON/ͳc/eu*L-_рz'U+?统*R/0r_bl `ƺ3M)E^xBaK* ۷2ɬ Z> #@4dKșhy}ex6dG'cr(4 &p ςQ-`̅jgv-Fr <Ł<+vż}, а~h@(@ʂq_qLqϐ1c8L >)rt(=t܍o"o1P^#oM5b(oMD0KJ3Ck'<Ȑõtvrކ#:t>DvV xY~S3^)04`+X JoQ`D`c%f2|%Z^f(< ? J py⺴CͿpjHa>C tpͽ` ?~q mfڪL<,x־8E2Hk^Ⱥ>:uK?)jWw_$f {Ү2 O,_ o66х*oa-#{3/Еdx+)[ ^M%%8O:nSG ?^{9]P5q&)eX8I&g;ƭ5yie^ mRR'N: t$I~ dM "t$]Do^5" ߋ"sk={˹se : s^r,lB>M.sBigt=ہLPKJck#Rn>ї3*HЙp+F;I=v[u'`eɶaO9f~6.n ^QFUZo'duSz./v޶$YNGI(0tvɳħ..<\b9$œDOjF&Eʘ7n'd\HWޡq@eWUāiיyiXD.x{I9ʛ]Q$`"ձ/ lKV(|[)f=8.ċ  $]`!3ؐ|;uL8(/ /Oy8F-\\4TPCжt rp Šg܌tOn>F#I@'NEB0zz4s+n Eˬ*Ex.Evw{c uQ(8WϝcmqO n:3XX3zZ<ɬd'31lH+ޣjmIz(F5:o֑RVZ&eh\R᪃s]ػX6p]SuJe)12Lv0kzY-_@'uWvBbـ+eagj\lrCvqw;F_OdqT 'ߖ^z ]11 8N ߸v^K}ʸFC…2o?xq~OA֥AA%NY"ȶ{_?!@-Y6r?!m̄^|f 9y.tso_҂`i+磑BVcZ=f-,:pTG@U5ACGZ G94@c*VMc @!! FX8c#jP 8d񯃂4lYNjq«'|{-7d];ӟ~{KP_v&og}9sofk$?^O,i =/qopgD ]3=%3VLflq֖>,~.KkK',=kLh ݀d?ƞXenhqcj@Dl9r]9wK)R_ғ   -T%_HvlPdSQC` B|Bců{ez/_Q5qTJ (?WI+I@'Nm0COh̰:k3k(td@> `4npg)g΋9#߳PZƓ*aagW\C?>Tq9Ld숃 4]> S^HRw.#3Gx h5ht.3q6߀_ ]g i_sl2#ydv0x, z ƔYp),KuDf5-$؜DG\jyۍN?qaàtT,+ =>i msXtkg._K: s@-e{]!Wvn (eihcvK~nl%.yvx|ޓ1rU6ܓDU'׍\N r "A'ˮ}n.s0f}mR4l}!ZϘڛ ] vd=NxaiApO$rnCcXQX~T*[OvUD+m9/}f@gX/z>̵3oOf0Z춀?(a7×5=C>ggm_!Z)+ J_4: :He?װ ?>^355"qÏ aU+2 IDATw^z@uWG\_g=s˾ed,e Q#Zy3 &Y`?6:D7xFM'eոN!x,Xm##:AlF=cXb6+ #e\9m zW̪:ۙ{v ?匶Y^`M{:>vـaRN",}$_E!/cs3콙lLj}\i%a"Z^5Hx18O:T]$I@'NK Mb\>ʭ>{VqhS_ fVG u6U;T{p]̶{ -|z9~պdIz+sl[̼$ԋkn$zUρWtt#f[=%3F!жhj,&N]c7lngRuh%26rg$.DžB%z3KQ 3,Р6\,fG~O*[puxUj1x\힛ZPQ9{ +H[:Q.2.k֥ Ũg]<6dnb GF} MwyFq}0iAm#^ǚ6g|聐4"BHI Ob cWyLG.G&^{Rl}#Oia,oS>}Ev#yhAF+k3r5ɧs:n*Ъ.T C>X,/BR Oi·1`s4[Ef1S\aطK|o[9̜Yf fe 1 ~c6IzLc@_6 S_\O_*5K,Q:T0[e )c#_fEy;KdB%/˒RȲz`/%!KS>I'ώ#K҅Fsdtj^̓ v&1/ ye:)mUͱRHc#m xhQ5D7yh}C*\;r"/!{p'F^}.fegtM$p7g?{/߿T;": t$P%cו<{M7ݜ8 1^zX Dc<'TuR'@O '8zQY[wb @ꂐ`>җkcf=|{hA`o")vIcD mT 8/x&K ;P3:H 1 NB/"pCuU)P2d珆uZ0|u{V'`ib0^B!^mݠB c](ћQP~*1Πw^p=صV%Aς4?V*SǗ_ADmZ޷~i5;'ĘA9y`4*sPPηQ_᧽A7KfV݁>=6FE4mnfWAKxD=hدFβ 񎂵448`\RnZJtN 2H˱d:&z,tg<s q w>{oUby™~1H plVf2B đ33KWg1Z23&/c&U谑2p"H=aH/m:>"5Nc[agIfM>O SW{?wkx L[S$0mMQ2b>JP"ޞY0|@ǮM_Z>S"}ƋK1as jX3R!,O=O4hȰ,CmN9/uۤc<2}h3?͉VmQϷ <`LhI;61Y101`̗ $ZG!Y.8r ف ,#66˃Bch@@.;bFZ@7SO\pT,FW7{Ȑf j01^;_>/'=Vj[q/| %B4'0+<\^"3F V>>{bo_dn?^CoTAq F}OueY٬ilKS LopP5(n^+4/=uXgn?w$qW @,ЍG^ՎГ&h_xR'^E|C'zX5TGqXs S|%>@j9Ω?i3c;/OGKQhPFcBhR|h14ҐA%hvoɤSԫŜ#{3k/s_ւE_C,>Cv=` Fe:}_#@G!!"v%j5zq&=L!pv$#25,9p8."#~5 sJ DlVrl K9of}H X6(1b83H2xUo@nr01"F4cxΘ"yDJ$)fE GE@s߾}Ҵtߙs޵VUjUmFR֜+h,%b`]r+ L_UV\Ppy\Dv_wDS"8h#.ZdD-}F7^:*WJxY?4Wu@3)f\& 0TF̩O|mt:*Zؽ,jxrM~xNYT5ӠKSudܑ ĆFi^}`##%ˆR,>>;0kcmn䙔?vN:5}Wdʛ6ɐ,-ז^Ӛ׍8] t%Е@W] t%ЕH@;%6& 38#a]8&qH'L1]wpR5Ur}FO~2n @H^D` jPbjTsKfNOeV[V6K@ᔉ3>"5 Į uܓ_껄`#`>ᵈt lWajd8-}Ӥ;Ift2wqu8GֹjYp=tt#  `5;ȣ?bR8:D0t>7m3RqۀfEǼ: •6v t0^X}RQ"d&\ywvIpD;׵tؓ9P-4б^̟~|UnIhL#*qa3(CQ:ؘӫL0SCM?Np^LE~4:1nꂯAħ06~K@ {)u8gOH4NjNL{ zqP"\uDa44H dҮq~z(Z/xp]"<ǹ Gyg )ɴ%ඟ}rAiCN#\ @ҩ^D&U3kxa޼l<"L۵m١ ȿ>Yf[#RآyAC[? 8pzqn$hm+.3+*3dEY{mxvB/7ăהM`K_ ַH,~rͷҎsy~jŧuo`wxSAh%Q5!q^8wԏ7X! h.eYspܥQ[_0Qh/*ԵN&'%]Y:.|%c*Av^Y 旵FeM9U[6g7RTFώ 喬/‘3UDp uhh܋#8&դBv0PDf^b݈3&40r2j1q@C.@J*p83rIJIp9=~1AZ x,R-sYf K4Mt-Ul  *FgͰ`FYm}9x8\@6'goǘ+og`AC(F|Q_U~Ą/O8kMmr^tlIq?B<^A`>(Ir1_e~b.ߑQ` f^%es<{6Ѫ@l3OZ P33ȵT%uw{Wu%9Am[u[JuF.PW?!p )Z3F[Ԥ.<;DZ0Wv~A~?vBY^{4u>=|kw@LAxN?s6Mw0 v`։Џif!(х~_ 6\I"Qvcl_&Bpl|'{*ڞ:nk;%#9@q9o5%ngFܾ*&Yw,gRsI %:h X\ޓ?iÒ @y7~mgRaz 88eGhK/ٸ:Gy]/E)J1@EPtU^ڶ68GUL>y(`:5z uG{hEs҆2i}ii*!B6 qJapVC3%o:e𲹅ؔmTOua&x":>YS}"QæC8t mS:2oֳUdl-Ւ-F)͆n>_Z+%L3i)%?yiA WGQ+L{ ~咁}}rx},]U_xcnSG` `WՓ~f 8vPn+{1H2z,zҮW={W8_u*%Br4 %f @[Iz6XS*If74]tL] t%Е@W] t%ЕFp= jT=7_Ecl-Fu9n5c 0DF}_=}8 LyX)]us;:9M; no&Yb)sz:a_-!j"7dM8V l]/Ua/0qg=ʈj}7{vAkzn.'޵S6J^rXCꌰӮU:|Ҩ-nu`uhm?k>4W::3NxGv8ƹ%'$ =om@S#f>&3 (J!d_Hp!+|( 8ׁylf F}gs>uE'VÃYqioAS ?L80k,2}'a32d;IG&C IDAT@AِoӤg/bu'6&e rRMV@JiGr F {UHQt^D\;qx:,4 qK( ȫgRB*j$BP`XK V0&,iT|[QZCjxOhʑl.NNM[SfF.:Zơ_VçWg{TvfVbdm eNuP'DrTVrm#l2sVY*[d?p #N\oui}#ڵLx-~N >)y/ Nt QTg֟"g paN<{h]"spxnSuE4| /z(*2Dg'yt C7u(l`;c2?Щa{t%Е@W] t%Е@WK@AW{A"Tia:wZ.4NcHL{% Kopv,5&p䦘)׎ϒ؅ l7FO-ScgjO:z]OįMPBZOᕿf4l9?uPm/Lp@۾ t}Án\+/2#'^;$cF^LcdO@\蓖&;GhmD )B}uB+HazrO{`oi δkg3K.'<y ,89̒'à g3su9+gu|zJC_K!ʧ8;8G8ʒH#̺2^ng*>9ӿ xɌv=uݭ>^3$Bh(3@?vpT~fHl QA:?#Ŗl<.f ^PMcmITNz= ̡gdEe(/f5'`à$OQYutATvm#nkֽC@AYťS?C IQqrV9 .#p/lr19 xckY"'μ&z#N:9 Դ4Ȅ`<ڌ} ڌJ*WŒk~gNu+n~B9Jwqz+,A@WG)1>,F[@vEYSQ:pٕ2وUoڔW;#ouK'5cAղ<$%n8H}o@Ɓ49xD7}4pZSX*:N}dkڎNx5$2OZCgm]+D(?8Y1").G1 @W%;Lh6֏BP7 + { o !,i;]gCEiTi#)Epuֻ;͐΅"RJaYPh>(atK: U ;$C{MoFA+u~v|#u'mJi7O8Nm95*NzZUvkY<2L '&7Qo*|1Ôg!&F1°| :*mqnΉv(P)ySm "?efSK~}Zp8ձD\f_-d(՗&`4ez 025!r>YPb[::@Ԋ;U^#,oe:=V|6^iLR\!`:vèn>T(FF} :k E&zҧ:Ô꼚;{kvT,t4w9LCwlں[VM#lIgUg3:)U.;?pǀ'#.oɽC8d ímf2HAedGz jho[^(xe#m$!~`{dl>Oi>@pFI Pԡnb}f}>: d:JܓQJ8+mX>/ѹʄ:9N3#նvr-/t:^EfSyڔ)UqR;dhx֯ a3״IwmDό:s]~z9WQDuN(*rЊ@Gɓڀ!b`T+B0* si2@YG߷b$y_G Yz"-.2S+x}[\eΞΌW طpH{!PN3 bD-Bg*(O@Ļ1gW\|w?}_VoGW] t%Е@W] IJ 'kN3D; #k̇&Ѷq ?ft[q:qڻmfZl>y)6 AX1tnjhЦN@2N9so`vھЍd c!\gr'dUVvHmb : `k`&0<6s J_-ceA}xƄ\Yr;οW4@HRE Nr (ɖ,0DvL[.77v 6m3 `+2cf#ʑ]ܹl5QV': *LK>::Pm3Y+>Ll *-C:\˓ לy|Cì *l neѻVPb>Nۃڱw[?ABǕjx@(:SC dʀN3l6,s80WvpnEG~K|r_ \A| Tc昁uιg)huhUnhR#-5oATE*N%+S=ZrHP_XKGe_Dx͑rbz̬̝C;Кz!4rO4x) Q#"֡,%f U"BtE" ll ɫRl 4`:`0B zm ~ۀȦ24(~{7Ssp.뒸6 LIIOᢲ05\M?aJr"*cqGu,H;_!.Ǖ.߽{K_rySZ-^Rjޏ/|s=UzCv+ܿ[rzȪ !_ǽr0 R:/ $J-+˥zSȍVxlS&t8p[s.s`ꄃ+G|oS}`gʈ*4pyGg)~X9q$oۿ'Zk^|%w+/RֽJ+k]{vزS8n8_lqmzwwV,oאO,Ck홁/V$P}S<]ڠl`c6mٙ2ř=†n)[5|'`50 Sϥ e6: {K"&522M*'.6,D)?K:*6x>6K#XY)rETpz?O=vPdv:*OSK'ۚng^m+YXT8R9Oȃ)5a6C^?iʓŁ6ۅZNo^ vd7~a)ekpQ5(t&$ۖf.PC]d=$Dr ]H=&%{(Z=NдqnD~:qJ2N 2 \@=,a|~teDL`Fz{(dT)OhPŧs8Rdh[C:P8*7tKE>R挿3Gp+R:T?baQ}QuJy %U6} Ѽ9'mSe.qx/~2ofYuK(wa,ׯ^:FHzT>~o_,f>.^6 T;}k_+7) 7<6?] t%Е';8+lb:ټۢ֘H@gD{S_DVs?IgԩLʒe8Za<: |G{YuohD0L._qҩ#go*(~'ǰ}kA{A)a7H6t5܃Bfs/QY<#G|b}l>mi`GRW-҉|Ǟ{nML *d6twtg,0s/\?[]%Pl^1mޙM`!Yw[20{u|9os.oUZ3Iڴ1hyq^&q) -\6&~7SZn߀LτbN{:f`>£~2V`#[Aߤ60-Ӧ%5.c0l ONEB2vȒu>zP>8E/~Qݍ7S>rq-.0M|{ʟ\s58.e; gyf9YJGvis);fFְT@ O~ | 'P<_V7GQ= yyWl\+˗o|}\<22 _.>!~7:o)/xq7]6GrzSR.wKrӟ4krOG<ueOu&86!yNx5.sιd<+o %G-[o)񵯖>ΦtasramXuSO ?] t%Е\}r&g{'( ׎vt ޫB9b;;fI{SYߔ9@H#gQmVGPtΥϺku\v?.Y!,qjXq6#O` e 8e`pÔ8 UZOU~<}wGLvi40H:4#ʋ]kў0 a'v9^>C(} pEYy f:G|m84 >׹ 6,oU)a:VpO'XF_m:{W:;3u^xƇy}mu3=Eyu~E;a?`!sly- 0~\Z0cN  9AvC/lԌlnyaQg x?t|sniӘnGj*4syeBKՁf/0X9GaY[N+30'>arїO Lgf\~ԏS05^.~ 0[!s^ 2otW]Jmv!70p8U(pZyPzˏ.:D*nlw?YOOI~]9Dq Ce]*nt>" `$w' C@gPlffC[%/+3ģ_̺wAMY4H ۶)1Q[S="WS܃k-ihUڡ`.;;Y7 l>y`26$ 3 ![`2N ӷ nra({|g֯g GCy@ޭGAy`\{e"vGtpȏA,q.|2Tsb!6 6}|+_)xQ/y YѬ?眝F>ב6Tj瞏*+q'r70ܻkL k^c=+_rso} *Rփ:K=Cw߽ o(3ж'Arww~y)03z;ٯr)kO6Gw[ۧ>\rɥ @\z٥裎J3?IO~OH0;_"qکbx#Y/x[{;.IY{x96 kgɓ/xCInhѕ@W] 9J{1+q:nVc:aZ9bg;;H5_b`Vs/ԔgkL~{^ᚦ>?3Uj i'V J`Է .wdIz7\SXi sҀdAPVjCgZC2PN-Ğ`'rIo:m'wό1t:xh!ܐ+יofpS`&[W\֕lH`F[Vǝ.}ˡI@t4 17jV0}}0x{I62B" Ϋ=8ljb5jr־CƝad2ϓ,qm|Ш)8kH驺}2*¦p35P+9jzy"b*Bi;]eDn3T=QkIVRUmQ$.DK,椼@%ԑőX;&J/GbQ&}iQ[һBU %zq'֭du_fp},7 ;[[=Zʚ0nQF.O m;ۻ8UהeP y(_>n+ck+d"dԀq^/r |unYpFY\59~f{_+w]'ͲAO>$#\i*7G8<~Ӗsxt-2m$Ϟ+Wu2kF5̘#Oˏ3(vAiUD,"\S.־ ]6!A]t8~:moo }֊j LHrBFcQ߇|̆(ՙ/?yS;rKȫ7Wk-_ hfzo+]y.!E=|myr7>=dgn }K.+}g=>U0av†3}˲e< 0tp#E*> P8~? |w:f4\vw/[v]g&F~mp7;P>Y/xgY9dO }0HZfž!/YO5`i^>ؐ~y'0 lLs)Cn^L$``!I_g $b۫lff;__tx֛s0N iO2<\ Jp£cgk `R8uz6SucXQW'Ck2D,8y}:rCiC 7l,W_rL~kN{^[_riǔk~|vwN+<;E *8Ӡ:y#1Z:H (j >HxxC"[% 0+C9/>2(!!c#kXʂW8c8?SzQ[/ں\ޥomYDy{Y^w[ŋ{<5EXd.M\oxq3)\% ^HŬ[뱏-nM[mΠ/'(%u`sto q2U}hyN{&F~+ ?T>_W._Of38%b_B9+|y#;g[v ݍizovwZJAq@EǾpMlyτ0v_~CLy)vktjvFIs6%#z ح]E0+FFAkHA_CK|H-Ng,EhN:8zaoV^ je23N6w -̗k[̏՜voo6z] ]F91W%"ӺD ,ͰLr,8%I_Nέ츾mIʐ&UNMNڠ ʆl38Y>a D6s̹);jr_(;#_\^Cʓwr+ރQ؟:}WO2?\S8N+`1γ*y'ꩲ!DQKtYr꿾|TZohcG?k^6e=Z疗qPY0tYO|=G.>D9% quǒ9:d0̿ >,r`z?ka(fRȹ_p1YTk$E{3a;whB) F_@Xt:tU>kf@{uꬳ@tQ>u!M8 qLC_=Y$>fÀ/kȈRӰYdQe?cywy^o13'tНT^W}oꪫAfץS9:O-:=γv7to7&`EyRLWyϱǖ<: po7DzCx^{lΆrɟDy#O9y&Rv4*?z,q+|Py(2[V'o򲗽.?#F46 γCYո̱vT߼|_hڽfvou%Е@Wia#ief,>'&0tbi dS*6|43)Ng];vv]$0F:&;l,#~kإ8+NXK9${QOr6äp [skaSzۓp\Ӗߪ>xeEh,g(sv\AmD]2黎OG$sào.PXcAm?w>(WXärÖ̡!dp"VC+؝ 2zʓ; t * ;m2r,, KW/_[&8뷝GO涎 `#Б8o[ 2n]'pa qTI2U3ۯ>Pѫ ]^9yYXv$K`k ϫR < "glm34[L]w}pDh!X`E:?a#C_-+m&`pQ[xd3cfP[sFY  o+z[~0O}PNObr ~ ^ Aݡv2k/޷͖[[9C_*/{BN%>R7U[~S$Oy#˯m973r9'[:ȇP,X\[5D{ה'?~(}stɧ~ '/{BmB/P4Du8,#lkU8VП(|~x#/^g#$s0>Huܩca| FLh'"4`1'_pTPrt@ځ9۪:i'=)ΰycr#{xW_|63tx9m W^rء`͵S6'|Ry:e73D0XqOrnyW] t%$ɩC&^Ȧu&t6+34PA:ցהř>7pzp@ L3AcSm6a~/;.-$7E>56Ycɰ(OĪ#Mm>$yvڅcɒmKDj|!:mu/_Snr;F҇e:k# ~9XIJAn b>ͼ\k!4^yƊ:c\MiE&]RMAҿ9 yfNn6C16|Mb$h8 c$o>Lk?LF:YO%H0|c^E $$椗Y O'^:l2;[tW~sWs@ >{55_6Hp6L>K:j2V/X ~3dGHx$DZfLQ!%>MI6Ǿd7rlbzE?o IDAT(*uc:18XbYIf%N%̢*!Hs=耝rDg8Q(w× ֹ[':yh[v^uYhrO<:Pom͒&| 78|oUHyGE[Mqo=zʍ7,yC, m#Vqs;?F_P?r?D&8b< uzMr{eb=~}Gok:?KK%8㕖=w#@TÙ9NPC_o9lUv2DN 8_VF wvC a~i3ړ}9ݰ¦]wudR; }p`cSrۘGvJQ8_^X8^Ƭp&M2qcWŽIsReb5[D锫W3xUfĉ\zLg38ͺVM96+Dǹ3$@ހ#b[>6w€8xJ'◦HKUFA!;FWLfr./x|Ucw9]o&M:{MW٤FȄZ~֧*?MƼ݋cc^4;Mq<*be+b%傁r`DȚV70^K6:3~ε/Y=-f AYdZch*bc Cqgdfڛ̠:Ș#zpqZ >.8MXxPhC,3U^A \O P)gT]JC;o`O5qulddg}g 0A0d.(Ԓ L+TD\ %Q*YcB +jsX-0ʐ?TdTPr* 2[1D]i;3:pxpx4 ^gnja~]xw_Nja% S߇ FY){c9/(˱5>oSN9M3PȏtÏ~|.זCx7ڋ ~CW^ܧ׼Y7͟CчP^񦏗+k!pv7iTK({T3LkX' K?PY^S._?կ{Þzh޶etݝ3^7~ ^Sn}c9# (%-/e<UT52h:AFџ K۰FOoxHۆN88|pHmn{ ]W'dd)ׄEK 2M5YΌC' G)T9iM!ifIa~l+e$hƏ0PrMCԁXgU2< JFfGfM3?{ `tmz ;>Aױ߬xM%{q6!kʮzw+u%Е@WXp>v&H i:S&)3z8(Tv6 0g9&͞:yk`Xw siL;GtW6Jp΂c~ٯeVz fUڑQBv3'2qZ (qY^A'ǀxR؁!H`>1`VuY hǵ6v˵QzN X \;쀼(u ,C9erj6~<tKD N2-3z2hW"WЏiBҥn!@>)92zZr 9; #pxPvu#ˡC @xTo@,d!T%= d3@UJ.D^w[ex |{YXl}AޥCoF[{ 1B'1y$ŌVq/i f(cy4Te|r+S*.uUpFVM73qAY6~%PWoȠ8U'<"WPC]i莎++xCcx Ohy4)  Pp<uFF\?a˯;nHW%`Zݥ_EC_\tJ/QϚ͢ϣӭ݄m;VoDGfi|#4 Ce~fΝ_0DoRM{fRȬil@̿vզsC^qBg׭5-4ω? &=An2u!^jV-gBhnvQk: }>` HVNO!͓ 1cR:{)9~PC/&4ets_;=rΝL2}$a|9KП>S'OE(FF >xbJBdM̵vhgO]-6 Dg=\MGV7,*XElSΧ&Vס P 1mX὾%e`xg`*+.Qkyegɭ˺[..sxՇ<tfdt)%" Fgو2M{DAȤHeru6$09:}iMO%LG[]DGŗ# ZC&8/[3!aqetQ* m g)(hpx'*F5X }2f+"`M6̃axoJܡi)ۗꗾP^x]vJ+_*]~wc'v{EJ ?>z6g!t9/Y=ݢH[f;mHM֯1զboɵ`l= _SS8tΪ-R˹{ZֳKJXL(gcQffA t$ٕ~jRC _ڗ_ ҟ( 0*O]F¶nشzI+x]1Zy&~t1BL+~`Q7@fg-F>؆ \`gD^wJq['XZ[X9N")_;K0E]0.7rȂڦ:^/&!{nO=q@hm[ʥ+pCOT~uCeܝ#a/m'[F\0yn' >qkZ6\.~uƩKffAg )p/K>Y.wwr8>7 4Pou^H/ot?sIO6}bN/"pZ9Wqҏ==W V|k t&y=B6#aH4V6Wx:biW2[C@M`rJ-##xr6s,'k$8_vf}gO:8Ñ(R{9&?cvSi~м-ʥgCBi:3i v-, jrG19̵8yivTgӓ5A($ rF a cX"ـ & -`̲&[9fWZ#i4mosN"nj,A6 qCE9i{Zcҗ6yaxFx8xlzZ䡆>4F /co2w5rw!DS)ǎ|riBvqڌi۸ӮyPGe'ݟN: t$I@@{þ50U `:~44p:it6d &j3lYхm\*ُ>ILv`FG3\j4N&L;em#TT=5~'f }^ (:1NhxRo*Ϊ^n :,c]ܽз*{Z{\6N!ec;}qP.10M]x80mX=Xơţ7 ɞ q0د52A_XfTz]7 `w}d:y# O˵3A&}q*L/}[htmmLgqtuHkXK’μCwpvj-܍_[=ceTΦ{m$A4 b~~G `}$F{C;'T^@푄SNY  4ɸ>o]8ABR5b'\tPynm$*yf iবWkB^f pU#h&UٖWJ? DǤ 2ގ}/m(G`cu%@'N: t$>Ygt%udC 7F^ݣI$[3*3TfS9H|nb= QuƆEOods=̞XٮF շRC j$pE[wd CѸQ4|tQKUhO%T"*.|%~>Yl*%1OU;:i8)(AMI`D(AiEO5/:O~"z ` O%n'isKS'LI-!ε \l:} 1.Q4nC3q-`W14-x# tM i`ťc mAh೰n{X-_rA : L(=&/e}q#N$5;:]oaĂ|Hä#O@I0g 33G vq@&1-@cAw8ckb^C5103u\@ ꧟d-q B?) LŐlUQ@4F؆0茂RjYMKRh|f_ob^Q{Plɗ+$Ꭼ9i˜[iP '>\$A՘h(r]<҆"Z-x*pBdKYD>Rk񭑞5>4}>{/aͺ_S_PqFDhoPOԀH%:^qYz1{++22U4[H0QoWCdTi'6(ԙGAO#+7Լ L :G%Ƕ>9  /B]WTs%FF"Yl/Q|.u$I@'NFrRv=3f׵URum#)g}kO3F:z* zeXƨ {Ah= G9=FCQ8u,OpƵ=ױ&7QPC0e1f;imLGEz%F XXBi҉.CfTW7-.o;0DNd.τ Fah $m"fLq@~~WU_bYOq¸+Gh!,p65kLza3j;a<2\[`?3>ϥzRؽ'2<`=v Z$E[A9y8/qV:؆(l R~0`͵jK^t2|]a}h: WEݻ)6h8Y,n%N haHQ:c0M š$i0=gv=F 18cdhPE =4y#``xz`Wjͣ YCDRùCFXBÇ@HM@h$Jv1țORxmyhpNajmA'.G͋,.&L AŠu_yye6 w U_ڄ eK[+{. b`G]&6|\R9c) h$dݽ2Aw,e3 QWKg^sϥɇԧD~ݗg5k?7G \yX-˃eU&2мɽxyx)KSҶCi#XY > \2|d: O: ^>Ar,UxF"B"K(޶NCͭŬzapAeU6O`YblSeo نÇG:,F<<4W玕+-n% 4VFr0c} Q'|j .Գ? !{Ud/,!3V#}܁إN: t$Ip]{B)ޥBZ?rΉ~ɷF dWtڴhc]&&\kh&Ih&)R 59 R4v=˙}w3}mTQ #1,@Gk j414$VȢSS߄u&VC#o-A`V" Lh8B w.m[1fydv?ztdBuPaJ(~4w7`NEhl9br0>y^[@[<̮/! A vCfҮjPmDH43Sef^N7ۏ=])OSڸd%gEu|M]I70G"g-Yf1WˈDvbΙy70]fx#%y0&&%<|I[6v.Q"5c a Lg9LD'42 $@m~ևApePW7|VC֘gC>lo ( *>r]Ko?I8a{DZ|6]c] %1㐮Ȫ#@Cnσ }VF`#eqҙE>ζ MUcV8ɋY#TZ1}e-n؃lG>x"lۏO]"@UPy 3x72 :`4o.'M+1N-I ob_.35AglhAYp9#XK_)7't8h@I`x?ƩVq>:3̽]Wѿ5co!rkVqE6\H2|^_. jHI.2D.`Ğ&em4>hRnTSA&l̵r*|%{9F11jGdYĪK##Q>yo&TW;0=ݔnm$QNRc0̸ j"]}] gԵH ,X`d)(/gyIwclj\YlBʋ&h{)|=Z4(ĞKXƉ> f/qAzm~O߄SaGeYM{B/4} rض!zeDF) Z <Vi!RorǔCJwʿ肋qU>)Тa{U9:ώ.3Cs K-X _|{tL5f"-VF7Kj@WXo -ؘk c& :&AGXmK* /Gu)GG9zAz3OCc ĈX9b'fvP$UP:xhQ)2f~xE ߍ$?8axBxls5I/e& N\m o+ w'N: t$K/ژG򪃴\UCqO: Թi jKFCG[~[Vr*LQOxhָS% `ӹ$/_OLZ=*$C+! WBG Pa/8qkDF eM$|i(q~Sƽ-k=93 z tY?1i :`R0:L( ={jPO'FUxdWjkDsr̰KT&hW+@*sa;$a`Kp,~?bvF=DZ߾ p}SaI;rmnhK pm 뜰|Q$mS.^'N 3io9>ZLB_Y+3CGQC zbA<,hoB bA18x$9F__ ;,IXD>2  ig)×&_ Ga4/DkM uq`ؾu]Wn*#:3ox<`C_U1q7[7o0ʯ2&iS$o88h[_‘?sA|VȐNVëp(3*Sដ`6ilA8G#:FGTf?9p).a|#c[GpC{Y7z8` FuutVe?`0+ǤG-.-:q`iwfot78odBFWRDž2*A,XB>^޷)NPC8 tJMg?9Z/I.u$I@'N%z҇nG@n3K[1FX&T@Ǣ U?}C^;Q~1Qϲǩঃ9}љ~Sfkj?m.}ݽnC< !iGDXGve2?Ú~UCwW҉ | tȡ̠׶ұ8wAo€g-;> B0ƟrU Lʦ|)J;7 Ͳ -cA,|EdCCVgQYcra(cEgJT!3hՙչ勉P7xoxdWss/CS,<:5ЗyF} T tِB4A2&vZȈe#7HDpI|д@ p'ox eڣF.@c5tǮR)3),YrR|q踐w$b w_6$TÌIwkVmTD)C5u*"ipL  L|,cЯMzx⁒ܺ,4!ߑGQFujĎ* (m1M> ԙgiBƆH 49>!_ME;Ti})M1i˝u= ˋԗs 1'/c~=q>=>^Ǹ&UzR'N: t$I@ h DC7UoҶi k~h(*vn\)ybLFQ <`h~F68|00nc7]NtUN QVk ^"~5և+1m:㴁4e3|tbrm]C]{쒯CA}PrGwfӻ,u0uoPhe&Ʋ3j]RG>cAFp 1fe?uaZ7>4ۦMD6muHIv#0lt|c,#Nt`2է*C膸j[\U=w`5x{%s̢$ШV1/3~Gxq.xt+8;!ql =fk2ix\0}VsjyNh퍭)=còt#k0LwBCПC'L>֣4\0mZ;Ԧ#hc' Nd@}ȭ,p;|Z<#Yly??pfV](PxjlX6{nF&:#)u3HoG|s̈|?Ыu=y HD˅ץWp3IP!,ycPٸs30gm"a/(Cyr)R-[gХAZ#HXӜ`oj8]_HxQMxxRF3evD%Ċ6Hd]SoGb" n1G GL(#@Dw44*Kx{,h"{P,,vL%-CNaJ|48֔cJ|෉&?: t$I@'k$N ǢǠsԵUUq>kPCԐ '9 (fUzaؿ+9e`GX=oBٷchN)&Ͱi< GfơWUG^7JDHEvKGa}B1a}qj IDAT70j<<.FNRLeycgW}gco[y4!rc^e\f ΀DhhˬG7 aX0|n[H]a}k[~kgo߉f0|_#MDk )Q Fq ٮ`#5p$``dx#958}xj3gB)MȻlm0L#%ynq&8`pt_"1`P6|XO#aA㊤LW>G;Syb3 `` H-F/ &M5y)H}4uzn牛K5JB/=oۿk'6pcS +lM _x@ 9}"Ui=erܒpzA.r+y\"w/θT:-q.Ku>LPoKq#yC쿰)_u9ՕYldoD1E]!JW0:4j?̾kD$w3v|Q|[]O0D߫h]ΞoVm '2Q6#bo9+΁2X>ʧ10µ٤l/yB?̸#ic##tCW"0:TH3>qB[@ʀG]z)64'G=H?&ycLK#Da~L #i=;'@=uVUDd1.g*}Dc,së1٘}D2~@`āzv$]gԗ5#evD >}#@0 L`JsmĶcBc֦E?L 7| v=\B´/WhHP:p֭+ {vWXNA7Hmd[Kd* L)oHNoSFU4$d7m錸04h .ZX ;;C s1v<'4pi]xYY"f 4M"ÏFHc. /% xo +.( YưޱZ}-v nVkG&0jи(30 T1}Cnxj`"1g挽pc|ʪ.`d+񠅡y3!Ït h.zt<+q?vFVFd_;~2^1;- FrO܈v|"4^ϸoj}?8ߔX]cj B :awR<}Gǔ#en~ii:zK{-f8BnPe(D $3ѮѶ\`=gXn~vMyۺ,jS5[,%a|7Ax^&è{q玌؇}F=OQBv> )n sH-AF!pq 2㵐$q 1? MpS,M¶5K0([K}`*!o}.pJ3B{SaH=aɳ ~ \R/}ɧSİpbqc§4Y/?Ct-؆-?z#{A:H1%8%dK:*/.[Q*LtOwLԥU{% FҜ@Ve"G;> #0W0 mTXTs/Ax q6i]88,(.IaS|e XV^ig˳tgM^iLiK/7GR']ϝo~,g[Ww뇌o<]OXws9o_7 T^ zoR/fe囋0z޽t69Vݜc`E"mFSWI/3E4յUG4|_?z|b} `?3sZu{k[63853BcѩkuȫiZjnxƵҡNdFeu'Fҧ]kn[CZ=+^ۆ2+2#lBmrK ÿ5Ԭ%'_#WUҜ`A'ȧ|Yh!#xd1~iEҥSq0`ONCN=:%1=#޹ ʻRYͅ)Ǎ¯G `:1 2݁ KdcY:cg~J[2W{(#ȊI߽W.C[q1<2yV0[ò32pwmNm1\ufik/>C~,3p<'K:|_m8L{ 6'Shoo@`_eڵK96918XA?u9 ô͗miç} Rhk;Ĺ@l_F d# 4Zu:ΜHßRX&B{g.&ՈkC_WNrY,k#X}[RN2Cd3WԶo rgw+na6:8ͧo";~I|JHm:8 D}8D̋ րM}e,s5fy0ú}iIŕ*On#qn\`HzU^އ6`tK[S#EKpY5@:x( iՔjdkdHEvI4˫}AݡэYEW88 ɬ~s\±б}*}_,-zB'i>1)zի=8d)=?XtiӦγyw!: t(V Ż|uE=̉ahn CR{gїuBQAc{kVazVV |gzUB 5x;VN6Y?rvvӎ6tQG‘1ex|G "H 4ԡ FX:a _ĪWF \z*,bvݙ~I>M23rz`L(*;7#J Qؠ-F8hF&MOev_OQoc>& <5*a"N_Ro_}{%E=bkFOu-zH3Ye;m 9ڞFNuK7A0q6]utN|YdiІоA>KDz4_3KSr_RհVAWwhs$ƹc'քpj^FڔQ+D38(jF:g^01wg}4O{nv `zvw 9HmZOuO շs9Fs4v !c s|4 Ue=P8?яʎ/gF lh>]GͯO(ؑe.lsv9G]cK!,L)}(! k̑gD\p ~"`4tNPl'xդ ?4)jơ!6j5ձ)TeSGF'*@vnDA D^n(<_ q.d̂;t3CQ[q_sG]+ea'?\z٥m 9+y ²Ca'jy;a{nW:*nGye9H۶Of}12ؾo(m3Ox?I\V>ó@'N+%PHT ϊG)jD(k MWGA ?=GA'" ޥ̜N=l΃^;љpewzhBo.$r 4McǰŀO{*Jx5ؘn*C%sxkr,-;,\@V>c,9^=2r̤a"3_@ˣc8=|4۷sѨrq#+0۶tq.S,3v󥉉Ib o|c +^>SO-vX">@4@*xӟQ^+.򕧗~ˎ;ʧ>rGROxB$O~˧>یse&'pB ?8*^]v\| /q<|:09^8N:rE}x{"EWꕩ=sGS`pFJ௄q$x򉱱1uN{׾V)?~saeg˷u^1-Їai;;>é>\c8i|^tQ3?~q\y啩oۻ?,|[ޒs1{{[>zG}}k|ܗ]zi˝t9]gb3p0<"$Iu$BJ_T6SW7Q+ =PUhlj ۾dE)T[Pz(vyn*LzF:zSt*.MMu% K?Fn&]-5=;3 G Sї9ZeЍ.6BXz,4Y",-x.@F򼃨'hK;{:E'L,)&mh0BUՏ)$?)34#|lTm9Ӑ2XkyQ s쇐d)RI)`jQܙGXLN?`u4mh{Dpqtz^j^Gf/9u8ӏ z} Y۴ i= v'u7N(,򬤵ڢ xlzV!KLʀ 9\8Dqrh}חFm']1xacJ" M2%HGoYw] .=, f:c`j0:- 8 Cwvi`P8HO3 W ]݄0u3EE —OI |W:3/i!Y'-0Ɛxm!F8hLBR=k*ie`$Oϱ\$?ee0(a;Q4s yPE`XUfe:{u[DM#P_7e9x|)[Gu%Kƒ#Fq %1شo%|y\ܦ|7rө   塕<=,<1O87 3i='N=Y9f| C>OHvy ѣݵkW3L~pYUo=»+ =/@z^/)z߽oV(L0Oh}jYAZO&rt08u%`Wx׿0o|/xAO~YuZS8J͛=q8Pn ;x"3;Ͻ8OqW^-_/ȇYk cqGUYv#7J›pBHceeRQay_se7eE'N:6z kң/a੏eC!wFqCmqv?R3[hwCÜ)MY\3(X<86g9onAw{DCQtZ!|Ѫ-2L^`AƝj &&=oȨett93ϐ6w IDATCbcc{^4r7g=pT(#q1˽AfĞ{3LRS|4)rz@蘭7 9jO>m=3j7Ӧu9R(zD 1Yzr{eH:ftx-J[Q Ų[Dߒy^l?=c5 |I?Xd|Y}M)ў@06sb:~ ^y#" \{,a&3‘S\7_[\ze-f&fуѧu5B3H4BEN}ցzʇoIN6eE5:OhЁ#!MLB|tuqYkȺu|(+3n2t0O|IisS?O/_vy9cKQ'c~ƌ~wg}e"ԧ5* %S>YX1G0z8QTCQС Oa@!Csɗ0i fgCڗy;zW.<$!U}<) яdi+&]# pa{.?qZ  &^Q(k6C9rKr" ôu%'u ,y#bhOQ_"!g F26<[•};k/9ml@ܢ<t')5¿) q Vtx: aJ#"_(Y๊ '3!_݀IՐ_z_FYUo]V3$J1|Ŏ|"ztqZ^E_9!8Pu0sbq`߀)gAC@5,5mM#4=;'l趾uB"84-s);[doZV8/y t8[#xRf:C K茀^q5ʳnGSliS&7AU=q:ФReރ ܼMcYaՙ,wd×ǹ|[*ʥ(e& [12U[ۧ1&x0CifVCghi;I:5q$x L>z2tSmJZ⼁|xɶN~_ XCFp 9p}駟^wN+G}t{?ۯgk7>7ql޲|p-_{D kp'?Ȍ~rǦƧ>/aV#^֭[۟_.8ce9m۶[U.8F~7h] `1+e׻޵<<9N:|y^3ƓeK_V.l!ۯ@N$m?|dkw5o{|{^Fg /8?K0Vb;yC)xV; t喀5_&ktvڂNk4 3>W}~r#;V@19#KMV=&Y3Hi TQ/v6 &P6J5vXїrV:4!d۶\KoQ" ˡb Ke1=2 =g u8 ևTxe[*!S".zjY:C rU0|rw "#/#N HKApބwi9m>!.H 98+t*xp7'e m7*Q6(PA$ nfz\i`فx*l|zn76D [¸6i+^#Ih$`wwO{pE1--8CuE#׬hD>"%3c>UĄ" 3Cesv:%-Z7L7Ί9? |z]&p# b Jia"y8R Cp6 XW_2m,ҙ\#JiKRkH" .i"0x4tրͺuDL;?jL/F"Y(q0UVϖ-qGoW}+N+W8TxkoXx^FoW el/28Bh ,0؝}AQ هhvr(G F 6n;ad'QYCz̾}CA2> Ɯ?JE"5j[e~ x8\Q<~zd>4D +/bL&nxV%&]&(:95JLqb1EFyx}##\Q;Fc%=3`(S0926ҠRxqM 8:忇4k\M4amvI'xbٳgOygSur)^! F( Mja:C+v]OhN:͞2|t/!Zru0YpY|g=x<I :rGX:7u4G\ݯ=`ƿ+ٓA$8=t +{s-O}xPs6Ǚ5[<2>߶=<; t$PM8y5]*:~Ch9<^Zc-zʔFW,i,Fe?_:ZQj^}tSv^c(D53~燽Пx:-(ԓ>ArOtCty5~e g_ ׳=}ffgk0N,:ˤ7icN @N5]H#妉 F:&?}8Dedd$%m4* }B8br׵kp,`$ MGBo F^c@р w׀Wn5yI@Ϗ4f.RƊ/ )տ䢎uzB(yv5ה%7Cu/41oI?MQhPV8̦Nwb=!lđ\]D˷Jd@ʅGdTdo5hYg= 0Дk12uW2VioF~hh뒃ӡ1f3 ;/rkdS)B0OwF4lF Q$g ֯2Tz·=pBHG7Dxs||P}x10fh*j>L~‹..\zy꙲FjfĕO/O]ܸܤBY3R^;^gN%SfĐtж}g]!b߹p(#/Aw$c{i8|dNKN@:knƏo/ePy=w0d8mYKnbÙ8=@tDB5\沌rLQy?2FŃ/-Œ<cf˿YAM]88CЎ2môrv Db'&]v36|~QGdg<$kW6V9F+D=Y|^\ =EO`/bwHxTN{s8Alvݲ?sI𒗼4kȭ=o^{L;_(_ۿҀiw087Dk v௄}hfd$3ӏx#rc\KC\qx: ^y+rJ-[>={7Љ7cp9w{vK_} 9-Π>1D\`8Աc`Y|VWg?-/KX`_uЬl{cxӸ$I`։jVUl%1z+TRp?e@` Mbkca,:Ez9..  F[3n2 a!Z>LM&Q G~BWu0q$iv%̽ P%+e 6JY]JX8P`&@\xu]8jF}#|oהØS& ':8)@n7/ VU0CH ʉu6Ep껉7oܴ!׷m1S֯[ϦdWq,^~\}lھ`J\y $ajz FV:ApXvmt ʢPOOV}"f7# Se+XN0KTy!> /6m 75H~MV$U^ ZWdfM$0kwKkhnpH@Br@1'/c?7x!ʇMVY'kkO z|Po?q Ik7#ʢ]BcNOE^t < Rg>]})ڂQx[yckܑ 4l gэ]ٮ$psK_ry+N/ܠ;x: tw!/G>g_v%gUߪVF[Azz* J7t:Tg1޶;3 &1!H-t֣0ܸ#L`UJ ե_m$HSWDifGfbXf5  C{x2$x\бaex{)}ifAUoX]}A!#VW)"Ʋێ%5U.~C757Bې|FFCz,2Н Ǟv鴒O3 :f}L/:=| 7@{ ,E[ yHɰԑ y^?' 1)KmT\}ݷ" `1k#Iì8)j4Fùk֗W\\gA*b;˫mJB}1(`&FB44jH)`׌̼ 鏳IUHl 6kg'a|=<; yyz}ea.r҉aT~R>͟n0g֌fw[[Q-3hya†ro}8 vx8pǜg<|῟[q_K/ u֟+GM Գ-pt$N~Ű%wf|*e-NK|fw: t$I%̙lN?|_]lu _D?hMDԙW?,QOC6K!YuL64fvl鬺k</Ά‰a6Œ6 IK걃"РZ'84= gÃN੧>.橣01у[(H5Q|W"v^K^"ĥq}oM ~\i[U>tge ȨJ+ݺw A(S& ΞN~X$.=g`ig3bkp=srr#K.wazBVw|esO{vñV+zG9Qfypl#N 6ykV!{_H%i\ٝ,+}ц #-@҉͵_ͽ 1O1+m_4=^2 e")]B6} .v{6> IDATGM;0F"i|@c~Sʓ9p\K1>ΈJR]S'C9?*. /!o؎c ٤ VT Nn.2 ^[nHxOtO^ls5{zɏPA|wJI@'NI̲Jj\]LC 52#4}.}Yρ Lap18aRDO7ȶoH)gӇyxP_i SVBN('a a84?#ǰ% v.]rC=zG"%HgАv7~gуՅE`g9"MШCڲJʽNq8}ݘ'm/ACDC0in,?KzOS|:Nԩ]P3p.mZX <(րǬj6s6)C,M8S@E;XpY5fΈ"]0*<7O7kogOz譬JcA;6XYǖM+˖Q>| <wK7/('FXd`.rϕSwX$aWL?|e;1@: Eà y1Oŕ>}8H |9V'ACuY5uS'IJ@} `'!</^9e߼A`z8Ӝo@RfOGuفWެ[7nK!r1}>可֩a[3h^tcdX]oFY|}yё{+ywyG=<|K5|]?U˫^qd~-2:r}F-wEY~&Y[oީsQi%,U/BL,v!϶iƂ)!c"缸XsrdgmCŦkcQi3;_ >@~h[wXyإjs,9__akdij<0 c"?\DF#PeCi-'q;ki}5fd |ZCsߥ+-SIf؏~ !#7I'M:ۘ^4旞弎&mK-hK-ZЕ[C`q#?g`IUT;\D">sp-IC2` )UAGouft1$ {m>]Δ˓tsƑnf3kܵkLC7CByABUUǣ\3:dPO&\mIӶof^.ж<@]ގ޵˹Wߞ–)~lm9?o&2]f0zP<(AO>? mݶS`\Xv|w1pES\Qtи{f L&5|fB9Fࢰ}Ԅe,.FNGT!8g3DI|+ŗt(ټѲ|mIn o݀|0 ] {N[ 3܍xn︫|@),,VWƺfFhr5wCރ[oZʃ\>nGW*_nceCq*AVee_`Akp)e1¡:-{2Kn1 aWS4]CO|;جӀzB}&lg>:Jat$Pwi ᱋czCA<7Hr,UH~h]R1E{9q3ғW^Zw?ur' >:QRStv gq1#nr~R:c)'] a:cDcz58 Sh|cAі@[m %Ж@[m L.3HUu]=䏬6jD/~ULS?eͯ=e {TvUVӪ3=s*6w-M-a5  fxYG/$@ X.ـa񥧧zo/3[b>'@dEO/ƑPOd@I}RcɺM7ZcDnYV Džam +}׆z y>r]޺ZGڰ 5x;>B (XЈU~xX}UGxc@ȇ.vbM$ bMx;ÂLu0V; F'}Syu@A\NcE?iv0} [ČH=AvW,OSsJu81Yʀlo l/w0`yx:U(k5K24A)ǰ*+ؤ6e](5Il: xC `4C'ѩSnndz@_k5X|#((4r[;//7|sU'>Q|6^QvWy`s99%ۯ\rŲ]}IW..חʅoyI-.'rkY?HU{i:< TYrxmp!@8L?)E#CC*ӸGc @yXjX4(_@mz-a9_ k!gxS4KˇGI녎`l˖A踱l\_?e$_k[Ó2:ΔԲG{mer#ū 5)녏n^l[6VY~Ԑmd]ʟAK*&A2\18r%0.[c˗$Rqmm %Ж@[m %Жv4f: .T}uq@!:`ԨJ 3ɡFf&`iF)Zrr=t i \1$yLau\ uVvYAl $z/,N@udjDž*=̄tXdfS` .e&XʄDSo2%CQ @W#[eI^L;8ȱhE;soAѓq-q姜p S6JDZN~GR4 ^};e6kvHxH9꣮Rbh.FЏ4Qlhm;@5g)!';n$  ]&U}dyGʣK^Ѯux(ҭhiYA[K_e2}ڵ{.qǼgj-W.+{}]+g*kV-rDz;Xͫ@!^!6 7 (8]e<0S-J-kܱ"flL4$WsRqeQ<χG.mhz5c0|0Rl=n؋ՠ%ض' ҶNeW31C#F*1Af_JǒHȟ1xnU-*P&/sϑK=F,{ݺm< y~L"%c#_}D%Ж@[m %Ж@[Uh#.KT92)x #%T_Ц|8uAqy΄n)fPIK5сH4[PAHם|5L4*VlC[`+{XbЙy4e;|VvwzHst@<']G9z'h&z6y("Pҧ|RRLڜGh0Su䲖 bgYlըIp F()6rk^z; w{Y͞ >W|,jrU(wuwH3/$o #_;i3m//u ˢh1pˇkS[$&A`-eǀL 7Trd{@Y`<5$XIl.;_ @[?Fе]CzHCvz*K-:v~pf?ikgO7TC1؉99B \p xC4U9§D y-NV7x-hhXLLd# y:A>OЫۊna L}L_1G71u4w u>*ꢬ2K@!J3&J[~"(;5t[ESuyO~dd?Ha|3iWyqLZz4|PF zD8k󀗞ʌy+k}<.rg2!*sA>yx@ņ ֍z c.^mM J57}PbLxnkxhK-hK`w ג p;~S (U4 Q\ h>lR:gQ$D^uON0̶^^^H ՋbIpv Y8qS|g<s9:ZAT#夋k 62 ]l~\2,Tf;Q:}SK˺,G]QObd4Jӫdl4_+V$N(,%c^mxlh 0@)|Gk7>Dݜ2qi2n}7F6Siep֐s+Q` vU00)~ ۲LrՖ[|,_>5cXxl 3j|<#&HyO& f#?ǒ~N~9\ɏ(i'/97ycKR㝌U:cGkPϊYD>nfi * ȉs#%umIS4|P*SG[m %Ж@[m %Ԛhԉιj<5*>_<*zIrZCA Q[ mmT8W0 MTj P<W7ikՓjy5D1{W7(<  Fh'=#no>|Sqtu-? V]UPwHQT;}]`uz<i0B3CʩLm6[-fHheT1uSFcBֱ!lCtTęq$;G Sxez 6<cx@{ϓ7F'40>蚯-1~t}|q:26ck:ذ||a|](8;L}_/z1mؔ%*vwi^]@ mJa&L z䣾)`|a$.I`<2ƚOW皷oËk.hB́ ho#Oⲝ g3Ta^mMƼt4VZNeC Q(#M;w.*˭o-]wm9x ,(p@+@oAǀpXr%fdY~Oap=w%/_~;,+s2sy}̯@ ߕȇµ#Ȥ 3?_l${ONT+f[ sGud0SOC3~ee%s?}Jތ˧{Bg7k]lLߴKeTCz L[_10Ve&ꩆv:feb|U-.om˙qSVЋ 2ok߈o`Ke b1" 3:S3< ԯj֑kcJ) $}^yr-hK-^V@j ۀߝM `Uw1j?; ָUϥ UutA7$Mσ̀.n6DU _̬@uSBz[)%B̰Xg?\GMvD3n@($OIltM;À6r.Y̻F f7;.U~NFnr^ %z2פ{:η샎9qWJ  Or䌗5X葖'ީ. 0r: 6󜤤B7dA.2aV,& by{+ W8*´| j  ڄzdHhk9n% wxzeiGK C.4_zr=8KT8NxR>RfioF(}كYgU~~/xQ៶Gt`}=ǝE,.iЋ¶z?~fݭ+RW5%G_ ,M|"گٯvҭOXPf& 1lYY PqTg!m @g!̵:9/\@m^ڒZzs4.Ʋt·$Yw b7JZϏ<ZqSF-[RƱfo#UlHW.K~= Z& ؗMEImӖ@[m %Ж@[m <. J^˲G^t-kA;#Jz2~Cf6 U_J{,h1oSWQeV>z qQcTL~)2=)S窹wv;ߙdg@;@faDxdugp 4LуߪdK0F4|{B]L¿UF;hHqlN$;09_͇HB@F5iQ8C9"oǍrhV%-*M)v]4-=R9GZRap0C;͞9{6 #-7aрcl:a'9_8F&='\S܉!tw?-u<c?u^hC7$)n|{0N0t &Ҡ8 r2v?j=g2e gGAW z,r U4simwrn"g]p [9e\,  *}Pp$IJhd&&cACrԙV'֭@lX:FJj[;s=|!(hG SOk5|a9B)t6mHlee˖-+GuT}r)o}[Y?/_ko(?믿|%=|le [psE?/`W7{QYf£2,Z,}iYxeҥ4k"ue+k{{dG~ׯ)-[\6yFW,k~AMWM]yQ$x;YFǗXnyT^JgYyWz'^Ϻ䝱C_ƣD+y^JƐ}/Bw+Sʓд\ư896A?%_:7IZmcnd3 a1yr1&3ϸ|4U?-) (U7xUҲB< K=hK-hKhV%SO6ܱ7l]aDHQU .`/\]Th'Ȳ g}R˭aF 8춁2a?p^&%; <^qGʴҦ mtczId(r2_Me`=gygj$Hck։@u++ PߎNQAp {e+?F5G$(%_]ZفOv!;zH;5caKͥ}i _\>3739VGb^.5Y^aF;*6:È0ZϗvkH1`J_sGmrg0A6?-hK-x&B(50*k/-XtP!O~I>#GNjX^~ zc p#&˧GD7|euNJdo 9?@y[/[3Ug晇'iCTo^uTq<6ۥȷ?9_?JzrX?Tb[&e1m#ז9w:0}tMAOgbV#\]{oN $ϸ盽!jAo3m_ NM:m؉'4` 0Y0@,1- `Nc|BώtX7LH}.8 " P%] [3-s`{-A!׆jh&sZU{- YP>rM7ܟXח7?tbK.ey/{i 7Wp#_x떔SN=\} +^{= 뮿.zk9mƇh4с/~+gZILh)v'+e \N. V ͛aR>yB0l38EA&F˯vhf6[Hά*f+hy>m^.%<6c؎9*0W zK@CQAuX^.ȯ1lb,cH DFydȹX6]u4QdwIJPeZ3tyؒphfn|xz jikPH3̇sݺ~=UChK-hK-*hSQQrhcf?-P4t^t!g=5&,t":NPLE*$/꧁Po3 lGz`}Y U~T 0}𐦝Nc/Il}̺wV8=nuAeOc giXcL%@#qiG sFVN&2褡A/ 2:mhDwL!Skƒ!ʰȶU&lZ?$@c-=4Ylف~}uyuU !.P_lG/~p_ ';x\iC=ó&_i od5Vc"N\:d ' ",({Ry $byi9<")yљK3O̵2<|?:AS;)X$#gWL:[ !3(7Z׺1WIAB͸y toL;F fǹ%`HaH1Z&-@[rCWO7\^rKʭ7I*_濖vJJ9ˏegZ~|北^~Z%WsrWpja_reeC_𿔀grD(NAζCP/DW~dU&.fOKEw s2L?W|eBƇ2L'8rL)`fZ]b8 M@ymTg M?F 8\ǰ @^}=3"(e =3(K-[F-VwChg3`SDNlpᇇՈPeZA?4>MyG=ʢ= Z?~G~XîoFa ˛n\zwJ;3_ŷw}%Ж@[m %ЖsRz).:j$n{tuuA{58Tgi%S$BpQiVc ͨpФsXO~TsAࡧ\kw"\CCKwo n}}5|Rc[K&׳A{ qָ0N,%ИQsMs;$xُKÈ -w¶z0L̳ }Ld܂ _ qP7a}#^oOO3:6e3CžXʂS04"~&14(hۀ{`afty;f&byvʳQS' 0-𷠌@e hTݶ#Gm1d)|_ϖuU_ n;-r*"2 qEw]x=TUTaK_)ThB9_`wGZy/ʖrt{4t|7>~e<+{ q%63r`E~ + /7t5@ɋRzܴ> w,]_mrvq‘l^%(#hf׀X!X۩"4hd79E2@}k*P>HlȬʩ+Lic\^LWО}V F24~x X2~_&ZCpY˨A00Oϝ}X-h'|l~gP-ves]hמk dV])zE`ƞV/Ԓ4B7j$Dʸ5 @꯾9:A=:ˈ% Qުcde)GAѠɗ}.P t^q=Pvڇ~x8r=D)թ=e l)`:@w:Ӈ0`'9SL&}.S3Y%   جJW` .0v ϽyԭBx"? hX;*2dQ=Fȋ\~8ۧzc!zMb$d74}"63'hKkq& Pw>-H)쌽j0eN6 $䗉ޙ43M^fyKz:y"0yې^ J,ǃQ3A?mkXI3(! 떦|UĠ$w'Z#1*i) l&2oD_ؿ6p-7xaXp0o,GuxG` `MG,*r>|~؂r3=r33%C>܎ݱ &RQe ov6| \VZ7Ỵ`Mdܾp1pWe:'_}5C#{=fg(sƏCf<݄ }cs\swuf˥V)yJ> ȈR?*7ƝmlMK ǛǪu6^H h-ki7(DȯKlHrn{`T0]\x%z1C\P*sj&G%jly%\Hw}W3b//'xReޱCg?%4Yz5ϙCph墋.z:#oa]1tg'AN\eO^m@@}lR)c՚ܴTs)d7F3ACsK@}qqh֝[_m2d'NK?h?{֖MLNyifơϐPUB]}yWB|u#hS! }^=b"}HVsg+"aih=N_W=wavy+_Yo?pyܷ[hğG_! ]ߧLB܂BF tzOB[#O7 W?)$A/}'?. 6l(vi{._g>xDXfO_,:e<|{ew/_CgeGr{bٝ _\rw1Hn}:UYݓ3ߞ믿o`d|W9oM&Q_\K5W cN7;w$y__~STy]tq24T^O&_\7_z~,>s;훶ء&'oϨB[ol(O4knG'ӑw]2&w\3Qe[@օ#Mˏ4{7_ufK=3^?s@AAN@2}һIg٭qr7[~cמqR[p_`?iFO9izO9 Qv3?xw,[0;[Kw9ufwy)..gv6/tҏ#hC6 e^ H<$MC?A~ /NPFcʣ[+T,n&}};>,ئRwHt#Z*j=K|up'k1iiDW'70˱4l1yZ,nOё5 wSwЈ]Gd匽,:;#?10S:bKG}$ޏ~= 2IHVt۾2`.:` N^1#"6P6^uD#܀ dG(2:ABWgGa Fqo0|[xg֗-#@ po?s`w;znv-u֮.>YWq a4Cnx `b}_~3 KE 0,dg S`񭷔!`λ KlYNvV>wO딣m]AO_rUQ}?F 8L?*L6j1iX  ǜVZ2m[3@YcBA@*_aaK^*\7@vpf?kZmy&@͟qqgq[KD .K$e nt,֚h±fKtYW#A8 Uryv'eΜ9xͳd#:x˪Ub@o3ߊgJxc9h0_o>3^vDU}nK-OIuxihPFP}żQ1; zx;k^t5'?? {cu9B\eYO=_Ay?.!@3޺v/ǸЅ55 6{=<[GݫG+)]NA0])y"Xβrx͚||3'ߩ!ɸ1\Ķ-\Q.;گiͶ">ʴ Msd;Cc4d E K q$葁ʛњZp$lYK%ɈGgĵ@{ HCn(tBAQ~D蠎J:%ÛZ媡B㸯-8޲t羹\x33KXbci/9%1  ~S΋X㏻? M \-,8# [.'_Tx\uk,dWeDȳN2rPȨ UYmwzסYR$8A6*A}~* 2N%ݸA& '~n7gu3c@-%N%iC;gxylЪƒھz&ȻUT$˾M(k/C#3e`F &2;qԗT4EozӛGy={~(Ǚ+?S,ח^v^gmWu#||WyA{/;1SO=O~So7A:|(3,8t[e'qombGr{bg|\[Gcnv&G=&`^+VLnY}{*>{lEy"[֭&?xyw7;-O7}l#Y숎\\6rK\~Y̰$U }2,,;>+)}s;]Hcuo|7SOjQŊ- {g"f9l.HrH?"je bK='BOKle?q竩l ū*n:ɳ v({TY<9+5;J]l Ē :0L\ cou[3o7݀xǘ|0 &Sdj> N6$-$sk}k}\8+Vu?8se^<&'X2Xtg#91+ @ϧ,+g6Ⱥr$[-4fͫ@vluXe槌R4)B&ژdr<@9 mP a)c l6`8\iF K}SL<ʢΰB`p,'oyƙr<nr`#{Yb^`k wؑxc7g\˿]pi/;,3׃`!gA IDAT zq?أyO5^]ƣV/XaUUr[7ׁ`H NOXm4N_<{ge2C֍xBD^Fc*Adc_!?ʞz@A9S^Hӵfw+Xj(eo!scf,8n,O킫J>sBh3"#ƙu s(yU-n1vȫrTF|x[9M3tga]{n .,'tbW]uUۿŶ]_|K_.]x6xl{L/C?ᄏP/z:画ﺳ̛7a,ɶjzaƷƌ̸)xؑܞX4f|Y03g%V|I;*{Lo._\؆}3Z9?yH;]?,q>cꫯ.x/{=ٮ`-w/zCվ|OQf[I!d&Afk* נ[E\&>ߵa|4DY6oꯗA?tH׵C_7i,^ U~ͦS#O5yh4뼨$B?bɒc6#b-_>k]O?ͳ0c^DQ/W<[OF[C5Q<A9Yf` X@LfS`W= If܆~x\Iyn Cc9_1lE# YicAc88q.@"c%ab;@3P b@杔sς# ~l#Ù|.%\z|v552KG!3;7iW/|}?)'GO<+d3*T Jw9O,0ؙϵl +H Ñae 3X+N nνSfRD60Qu')l?|hathj<[xȫ<[. 2g@i9._\zEOu0߱lYYHq_7~ᶿt{rG k/{ G;9@֔KyˣY9z!]\2C b pKqzf֑;Ng&aO{=2٘Uʇonc6A<)kr Ww#weE \DzfvejC<ҏ;/e7>w@p}?F#em_yR^ad]z4jd Հ4-퍬$Xg(3>SȉZC|T-V8G^ m_bެ!= '_x8Pݺa 潤F^v 朏g_yUkA9v8CmKq~ mř{i9>gb[R0ZƔqVs|9#1O:); >ev{J7mԩS^L$,8)Q~Y_} =.7y AQ* fvE< .`z#:O$l-cgrklx\ngr܄CpqIMCye LlY}N \Y,ۮiu˥|[Ou~6ޑ,vFSO-k֬?Q=ܧb5!fǥ z黤O|"KFvF) hK`pJNUP.%83p3> CG :c^H/qYT!@ugGhג]7fE9ktM5ng9ǟ:k-g~~є?]#с}#m|ߟ!.m 88k˨yc?Y|s9m?e tY>v'9Ϥf4 o"-܏x 6Rd>pV!ÀFo#T@K3S#d][<4t < Zm FIAۆNp9NãK ]o4hBu$trH̳:'IC^%oOXb~f#L̿E 8:Le2{X(塝NN1>@s9R)Py(f R3P.5_څaclF%KYoPU*޵cqYSו:X~o/f=ιeUƇ+xxyE;n>b tFR*lbx ܅O*`C\WyVbgenhAM qP(|b2B8zs%k?KCQ44рtio֌}i1^p˒7c|\l dLSL5qtycx+#}cG鳔0 |U0w+'65.>O"_֍(oy$F1*s3|+\N>E̔[rk_wu>۾Y)Qw~YoSO9%'p|g7%HA:_x owDxwy衇&g}s&D%Prqǖع`.nO|KY0so_ ./Wo'e&A0;nٙ&6r}xk|l#Y쌎q5|_dFH˗񏟗&>╳3OIؖ@[;8j׳z b̙Ϩ:^VuEDJ2pa@nuw:&h8\?:s.;D:lz nXX`)NW~y}}{w'ku8 U579ڦCɇuDDVU)IYmmU7Ong j1/ܕUcQNNee4Rc.hR㥎:>0痿ϔU+y&?῔]e:cG<-?.$X2wp ?>S; ~Ԗ@[m %Ж@[I %]X^~|s+_8 '*%jPK8v3U$XҎ޴&WV[KPE49`, hju+]IL vf?@Ht*nFKS7okZ?.Q]Ĝ=46G$\m%yL<ڷ`X/ޛi~Uu޷ꩭtf/d! |DAEqfPEe^dS6U@ YH:IwBY;޷~y*݁>z˽{:s=W>lQ^lE2>I;)l 4fq˰z2 !Sv}0fs|maHPӆ>㖠ZKmK`Ҧw&bQ#})JѭӒ/ !ʆ \r}c ~ Hƛo w^.;_+7T.]Bl 3eA=}q- .]T2ߪelo3Pe k &P6"  ltߺ+o_kSDӒ΁Si O@q/ʼn k@Nȃ /;=e NzO>ʳT/ e1жmxܓOj\B >V6JY^{hLڧr+u!3,q܅oPP`+x2hMG8ZjEW2IY߷2Oxv1F?a'31q >ƓhK-% VDpR}e7q]=Pj%OC '7_z4ݫI?aqn5g>ם-cVʳQ,c zTT,C 4T|L6s]Ft5rQ70H0M娓+k80m!D {h\YdD3 3,|E~#=P fL.[>>_q5m}"p3.5 Cdbl?Nߐ㎹K]mT70"Y)d#G~AKEH4=+ޙyv`~Q0a &"-' `Y:s/`2T=LY خܳ,Y9e9tSx0cՀ%}EA*;G 2!tHA5j\;,;i]9dp`^d$Yy ᤱtAO|J[ip[8ljA5 |!,5,_}b8JOYrhR!p1=h8;B\عGn6;Tm0҅% ~3+{Z׫ ]7N(N=}[W.g6Dz[yueYpM_I@?]Lg-rpm0*xM/+1.lxGt-HIgB{Y_OK<p"%bdt\pi[ys?re~!9 V.^%yKڏH-?yf*Q@T@4?+pE'հ?3̸Q- SiKzϾ{&hh:Ócg<2,&L}[$?SrMbpXK^|UBQ=(b%3e7dlVY~n>tsM [[m %PaYQWFo-*j3Q'K:tUC/1o&5mGҭ:\Oi(Fg:[YlSΠ{Կ2PJ4w130x#(A@A0>eB79Bj0P"4|>|n\[ 8I\N; vlem>o/_ŕ̻e͛ʅ^Tn߸\ r1w]_# م\TԻwlt!.w/rwir֙ˎ0NJAva;?1(>΢ۡ2㚛bsVz*#5lAfXѣFXK6k>*/u`4#p/}777i/ ڻEi~Uz \!=S/Ç(߀nEx9Tv}ĹuzH꠬2ʄX~Y ҙ2á|o}޺V'V&zbd@`8Uc1 pZ Щe4Hb,YTy] x ̡gV IDATC#2MTcwvssMdtՍoYu NRCA_+NNj`vQ/Eҹ}:ͣ ;  jq+F/z8W@2H0Tr?lڥʗ ~}#|iW^"($jՐFg/і@[m %Ж@[m Tzh@[4ϼDϷH*%tZwoE!# abA]>=14TmeA^XVt-I 1 I_Z_>E |Yw5f{8nZH/<yËC#x,CS %$:] M@gȨ Ba30E槠. ard_3 Fk;LDn3%"`D);ȶOCqA^.CG '[/N" GA>.k=J^7 ;T\"1"/[Y63<+._v9_J M7ǝ;(1} 7! <;&>7nvhʖx.Y3Ƚz7`M$ OgνZj=;A nA]**e H^䢋1qS#@!^y$2oAKZn? |L6▇~aF^zCgAIť+P۶d4FG5O='Zc` ˋ>tXYYjYʊeٔb2VW5t9֨0Nqv,Bzf+ao,`[yahS&;g вj!sѼ?hK-hK-%qJC *:'}}?X<.#3tsj eY&E;kg!#"z]wW.ഞg2#?V ))1XDŞ2]k-O2c/'4"e:%]U#kJ]o<v{Н8SS,{l͈<].ga8qp7"ay>#[+}-]?4D8#¸O 3`βc3,O. ärFۿqR*e?(#;iER! ;kG0aaiΏ_ cˀ~nϗ`}O RPīŵL(7]IAA M~pŵLj Xa?:7-`m&źfI: "#[v:*2qn4b+t8q@nh7B#4^qd0mݿg?f4pkZf)anzm=5m:/ 6n]) @@W`G˙'0L<o<f5ST܀:[]}Y1F^Œ>D..H@bܙ]0`  U<.-B3£l߶ 8[Y#r<}ۈ=Ș@FPdWnZn8(+r | r-9BL[?ᲂ3pGi!`I$m}轐~xt^kLeH[.a,j`:&>Gʵ)_˝w-,KυLVSx̺à01L0A|N'b[F9CdHA*"yj?x1&@z&v-hK-xTjs0{ku#I#Ǻwзãi(%` Aͻ}OfQzΝ,V=3(!@ݓg3;z|hDSbQ*kq> 8΅_'աL0kם8 x9}['Y(U̷qfVU> "״ ҨλUK$b]4 L14Ԯndj02A>./0&A!M" 7@1l;Yl|U$tY,jKVqsf_Y !:BV .E026nC  V=`9qiYFA]OjjCT],~gwhggAK2s c?.[-uN˸"Bq.: gnЮ}:՛^ϹF8ߍ!<б5ep,@|`7XY{ḋ/,.<6TtfQ~#132;XA #cs*+'A\Yg5x"5( U 2ZA 6F@8%吲u <Ve>$rm WǗ#A-]k_-Ti1f]kj$h:k_R6PMwnMLBf޿N_p!sy76q `lx ?s\( 0ߒN0]n[?:`LƖy\ 3:YotӾH3ܳS:>x@HH0G9j -C| 1>~ˌ=IפalF~UeRi hGZ\Ceȡ%T#]a,t2܅qjQ'ɛy#JMj\o?>VP!5/-|VBo7_wϽo ?ՈaqE9ʻ(Ch/ª:=J";?3db,O]t꜀a(L3^C&XJ2,P0g# lXʩXGLu&FeR E֭|9@qyNѩzh1&H \0\u`F[c鲟Hp2=з7Ǣ(Zgx6V2)?[A{{#;Ʋ1Z1-ȦM&vBM ٮeenLȅxq+gTs/PG0+ ̕Ìŷ| I3 ^;6nF)\P4W?}wp6fS;wCdfI0 Sec`)elC\ca#fЙ%{α2r{t)'_{uIO*{OIf/iz\2<\Gn܈%8P Xig= ;fl12t4*C MH1;@cs @i?NO:]C7۸4f'Ims @;KyA3ӛ7@X-b0%al#}\.GX*ŔT>1Mj$rяXA1 ȝ1"2 hl'|Uw)ʎ VBNwrl]M-kZg2|7OtJI&WO[m %Ж@[m %]VST8GgCW5;'`~g\=%WzIm9o; ݈)ƌ~\>y=;)_Vk*4uess*eG^4"p4u& ːZ_tS#8. tAwKɋܢLyC3;B/s]8@)Tx!XNt[묠Wsgaj\a8$ڃG_m3ab5/y}`}" ?,Q=yVbY6[Gg ж`2+ZCOOd wKuG[DCH (-=Eѱ㊱`DǃD x@!$ 3?HZ1*bZUlQ!3cg=k)oa@2&Nl p c|8r}='/& DmC׵D !=k(7`\*#ixfIK-,oC:yLD5MvZn;`!hK-hK O}䡾rh5*~]-6.Qh3;=O`TŸ{Jo9=̦\Y Ah 3^3"rLA >-oyCOtQ4*I`kq .糿0.̞ҡ0c (+={sfpY``Sn@~^GgV~Z<l7-@Gj ;{3Vc["Jx fG[X`̀c+K^8Lm/d ZX1s7yrmz qeB<-X^2k84 o=x jthF#U ,R#`ۉWB"˯Xv:@0?Ņg5xs#ˢ\){o`dcz`ޖ +JbʭM)a@Qd+V3l!,Xt1 }'e;Ppu[;ʻkrm5V˶;'oַt( >+p[V_ /0KH\j1@"Ivڔ!Ӹd IAG;7h]@ NxkdN/Gu1%@mLzv g*6e~D/X؁> aB*GLnͳ^߀znW ϲ*1aZoLۄmǫcsOL=,k(8 ق>q02ˁF'OisYK\ɯ\{)KǧuC+W YV` qin 6Pl4P7]B`yhiZ5,7Ԡ(X湦9X"p>u$Ʈ#O,UYu(VsIDʍ,  k^uPf8a~fzAZ\=YWAOH_ih@T4eq7O[~Eʏ V$^Àchu.01”zRa/u MwZ6 剏,3C\?&=[ X*BP~b @a2V+,OoҤs"{[!89 4Yb%luxZgMWTxd:%MzV>0@2uэ,`o_k_?k`ٷ_-o+e}^vu ԋH!V#e2 O 꽆S nA @4Lio;"7qz| Elɻ>מ IDAT+"%}9g`M< TcJG}Ie@џ/Ϭ<o? !>ܕcHE)wyR\| YC uEAQHm/],~i@Ϳ?7ʊz$C_Ev2><<6_NzʫJasvV<%Pl`tjރTG}ɔ7RL/[p>/`wI6?a,F Vz}XL0,hp̈́QFp@x!*aL K|Cu4D%2m@7X ýCeYpçz_@Hs'3# w\;^2:q:,Gc4;w=,kpq)m+w?nmˋΊI&8#F  cE(vp~߳ yalۺ}'maqPA-<%YtP۷&;$3Tp$I 4FFx4ރnD ̐SC=bn|j/lTHlʾ nQ !闶DŽF*(o4@5G;ֲ F."Ccu/ uG$mѩi+hRi4eN f GOߣk:$Sv甂hK-hK-#$ u#* 3 f*3Ck: Ah#(^z<2 @magyygffVՈ GRGܙzSo!C5GꅰeN;QݸGB@qdfQՌFoLnBǥT_gUnHa8t ާ;t+qP.p"8L|PWLeCD.`"FhPυ8,Ux^ Z?g+uif,/X{0{8(:xTdbZj G#7rs;3vИ-,<@TRC'G: ln_Q bֶ>aUHS yHg@KcWY].rYjN(#<:3@5RQaxu`<o:r:oR֬Z^Xы(B4xKΡx ¨#w=~/>%60`֝[_hFO;m|: p;pWz,JL׾sLʏ@,luetNʡ~|Y6LwfNZ \?hTYVc{ұZ,;eHRq*'FHl&5-ߔc?-2 }qۥ/DYruV ݼqvxJ84 ^}AggqN _fAKڴe[uba٤q^}l}kY^\w)I QSU/O Z֙n(3fv. ʵ[qSL AAGwu:UiuL~&&F HhH3\ёGF:aFY T< 幆ԠW5 _|FY=r,f6oI$Oy)scmg-htԊ@Ï~Ia#d~eM[?m [%$Y̹ U.!mo|Ժpךk@ƁCtaP6;id٫~^ |yn1L+%L=j=̶zڲ!ǀeK`AWf(wG9x`|3_@0m/ neM`MYe8;=滣uF$$ƂmOm;.yޖ@C:*^D)yϙp nK`h/gr';"Yd ٣ގJP #>`PpOۏS_Nܛ!Vĝ޼v "-훘 Ni?A5TO{Xdf-rm/;X q' }K 2LkhT݃k x8Ï#B #7ҐQ+g̶ʚ(*6m'4v}KhD^~}@Z~A(U)V0m}.!uB4/ksQ/mjWA%6N(Uv1`! w #bZ=,\Ld û5/V@liWEi  . +txzp_}eN.e>K<;82xRVvv?|tK5@;.7PMb4̾yw(xHS٭er͡i?jy L_>,Hq;oM_2 oК2ѾAϳ֪8c%#2(\ZhhK-hK-`П-/~fǙm0S2ETObٍ;IR̓HS7%:3: 8W ӉÉU),KW6a71axp{K̎r-{oEĘ˻뿵)doc 4%n;v|R9+臘`@&ԒC}ɊihZ2@v_圭Ioܷ)4wcAlh,W[ &p`oe‰o@5 lDSʲeʖg]mhg9 ~~T%7O|Dz4hp.ұ O|6VeLv paE[m_N944?.RL2B_"$tΪgaPR>LBD7 'MvYHhZ`߆Ѝ߈6ʛNOswXG>njҔlrF3P- oM@IPJ$=$Y5!vH Io4sНxሿwf(#VfbAG 4ŚA0,s+:3ʖC dcx歃m֙Bŵ:\3sYgsI tU?pKLW ^tyv@#t3hL]g,TK`ЉkIrPfN`6s3+(P e _ _eȍȭAI#Lj eO^k@[o1u)yeet>^~1 ү=uC9 1%jٞsm oGG18@v~cCmjɣ_Y4 $^Жy#U1د(frmO.ǾTAc_(K3`CY1xv=/#eRw 4'k.eL>7Uޭt h9,901#K2lX_'PݼgϞX'opx|کhK-hK3SR hu{`Z8hp5GEGQAو oԘTY9]{'5:Bҹt8p˽<#w|7tTcSD $@WS펋W0}%vJH2 hT5lVm)3HʲZ_'|^vԨe^@1Aͩ.Apmԭ0+<0DMsQ8s^c#z-fݭ߬ 0c$ugKD9H~лm=].d釆P<"N (z,ߖE+V2|o< |XWNf{00ʝ'"@<)R'&46F] N(-$$?zv\mdEo9n9 <͇qGXy2F \?}6t}\ݚ (o`iY4fM'AM=mlA> w / TC @"Vink̈ 6K?R0"H=3˕^nypOw#G ͭAbml0{b"ԫΦoG(}Ӏ"X;zU+ x҃kp2뫕e>%UF"ʆ?̈x^Fh(1(+Az 2u>ka]uw/{d14!uUvt4oaT@H'h3:&}iW}hO_M <țۛ>?'Bi)#XB~+K'T=#҄e*|/mޡueoK%x}u 5>DMR(ib< e-LW@5dȓ7/h )'F)dª ơd[ D/=NrsP5yUc[дSȓpƠy f/4*%~~B$^`*o0o+7Ǥ?Y~nբ>hK-hKSN'GB %>^ÇXďίޡF:ቇFgG7AWq;wRpk>Ltt4 :WIߥ^,G=Okk!%kP?ǂY<MĊ:I>DG UB']dCwy;](w! ˉh?ʺmˈ̧e7gw) y,s=̃1 r"%9p`ON}3M2gY8xT^u2H0lTs߭zk|wq탌H>9N%"y=_t}SnKW ˘Gʓ3F^O窳dbXEŴoH+GZH!B`{{ M>K^g'1ŀD9 $ ]>f9)KA_3_1@?^ ЗZf{Ϡ7JHեсjP?NR^,H@D2KAHޛ:䩧(kA~dC?yA#B?m /--,|{6P~u/;/|1K|꿺 Xu3<1/>r͵~${x[뼾%/\OkSna)N:T~XNjİ vHW2\0O5D*M|2=aeOu[7x:A58.V^᳽Zl(Զ4^ce_(X >S3EDE=Aܖq1b)/|~DLvpdytιЧICdYN g!2Y/^[|3p Lr Cipj3C.D>=Vܦm5Fh9_3ui֣PDK!frH7༣F s5`9h0 &b<mDݛ2\,W c##eA^nʊПzF6txx:{j8yȫ&X:ISʋ,\Q4GsVr Ot`㢮 ]jFȘb a75Skh>ᶈMÏfT1v/M^t6 Fz_N5XTӶSuSFK*I7r ;HIЫVҷWhF"ENxd mWHiH?O.1ࠡ|.HmΎi,"@LCVA d~Q+k_˿Kawq{Voqϗu֕MwQ2/(sNyK_z\|>ysy[7Ii͚5ߑ7ҷ[˷e_B&,m %OjpSdF5ڂCbBp&_WqF{hMu ogr7:V01.6M31g6%8Ξ&L?nxQCvq gyыLcd&ܙ0QyN 1v>:Ku* j-(K%P0{yg9Ė C(UM'vT&1(wA5EGaȇvn嘭s$Iݼ(&ziQMgg(UdHTMEd?K.? y_P؀=%E aW嶏ͭudZXJ?2DV?K'fI IOt'؏&kkp[^!ˠG\E41^rֈ2]JgFuvU0àعLɱa1>h2}h\hwu(O~BI "؅Pr,9(6ټŗwz/D4\ [goNk&: +ח5zܐ_em_|T8"||]rŊG}euvPKO,/X9+xUq3,\2<[yM9Sʩm(|YM7g>Yey_+#?o,,I{OEE ӟ.[l)_җgOYvm9s'>g<~sI]WVY:#]z/|!k֮+\xQx{ы1RܻF/jȐ?rWiOd2r~z9lw88:^;VGU}і@[ToU'u /I[UXR`"./=H; 3խ*5\n)b52Dw['ٙSh9`F@d@(T5(z7a'UԛzUJ3r kܳjpz wif\jV ޔMSͅr4M |*ny+0NSS 7ͱܭ;='xr,Zx` -}?2NL(mg˖3/ ֋pc!~z9m:mO=kU' K(VMtLK 8- $xUl$+J8F"uv1{TNB~*v0л3N%XLliE`3~,-6m#׋ n,+8(S,wvZwAZZ`=M:4*: d!C8t7/Lk8fosd){65:kpXj E-—Y[̙r,Sl2zw2Ǜ_QˎM?wYvYo`y|#+x]`۶]'5o𥌸XF fAf +K` Qe$iJMiy̵mPAWTG;*sbdk=311/-19?rx֒yELdtM~]#h-_ݷv az ]˥(y~k8,OW}Cg9}#@^9٧"o0P5bsɊ(z;tKNm[m=SeJy]@mh;e=W򦜺0t>đ>?)7~eM+z׻bx9;]]>w妛nN%YO\>L?~ oxQcD۶w+<*㽘zwyw|C@; H//_}ٸqc9bpUW_SWN>餯+Nʯe·k^[/{YٻwoMxg^Rv S뎯ڦ,TKtOuK͏:"S(wе>y.fpGͿ%.uDl&iȟh_ejxO<W>ѱR4#чuu_} I]{8ۜXSeC5../12 ] >('!ෟSY3AdEsT0 i!8L €c̭ Mm4r(n H0^a#5jD`AÆo3UN !Io]:b0x޼Eµs~sq"lKxɺed"л4qɆ;(c+?[aeՁ!W˼Exu˕ uX=:4ܥ`zO%\+TXh\K L~/btR]*<#㢌<( 0=kzˣF&12O^Ez>תWMzNsڥ n<Ҟևå \^1˟' e`C=-O^W}HWi&tMŠd̲me; - hei 2 Hmwd%fQ-#@CX S'pK7>y':}_)$n< ԁ TfilUO5v~* fVTΔ_seв7u] {q`%+WK/֫_]}[뉳>IW_Vtǻxz+Mo.o z3mCxÇ3l}+Nʛ˟c^(GyW~/:k}s/{Yy{:ǒr ?p}yޏXS媫:"űO5ɟIkE;Q'z,Gny;&qJa pݷYKCobi4=MdчS28˻|vʏ,2]?94vȬ3ҹL3#O!̼7\z9 cx"ә dX`Cx9NROZuGrh8!ŭASZZTa6rM! ps2Ԥ2*8#e} 6ʞ1$ N# 䀶dZ  Y\(cN#b@!<8LgC fN(\֗CMD<=ΎEi4S˗?{kyB_s3Y^~W_Ppbe~w_6(zӒf=ʯ+_ۢJɟ;tEҍʿ7qOuRP'<\+]޻P]&juYU~Wi{2#-y~1S33~vkpf5ȣ/rnYa/ WSwUw1CVϹ2zpWAf@eOig XԺt6CyШ"uQڗ"Z/a1[o^j;1#@Z!O-~ICC0RѾ`Ìe؇ɭ7C&t?bW! @ߕ䧏Kyq"խ# .>n8't9[sK 8㌥:e/{ic~v0~c:bw嬳*˿R__N֟,g>ywޯ{vƙgսɯ}[駟~ԣ 6u}#3h j#yGsQlٺiO{Z??r睛_珧O?>VFwcV-$^F'`BUFKN^^?~܃NfkG4k6!XCMw=!VfՇcet̐1xI2]uL b0wVH5 &:c?FzGLyt5e@mrɧozFOU_cEW3܊݆ K|djpz;ia-̼wwZpj=u<34`#$t6t,}/M:z-wN*਍{> ;UN`< Z""K6Ikv @#9tA<?Y|YQMI=O/}Vk"zTm[P}z&8LB)]ǜg7= GCJ nCX  9Ӎ[|)9_Ovy4"n5G>uglo{WY`yC x @ ?74ona0E_5Xvd W# ǵlgY>e9^87+7% \1>yB-:'/nG|"+s#=_&4<1v,'ajiF44z `1fߥǪUlw?C֮S,-}عsg[F .~_Bq]v< ~[֙g{?GNXWnn_벼ȇ۶n+'pu|#}o=-u;vPd{Ǣs6:^{FڏhKDl`u ZY~Vh> ,4EmcAB];jMAxœ pYhig|F{[VyF\P:& >eü#OC3\x#fq;ïv sL.T0T^@'.q=.!AEREW.$h Rlfys8!hwʡgFB"ͣ"p@%[jv} m?xʨ}ˍsw7[֤UWI1VV4S2؁Ed?e!+6q{d]`/a}-&lsC^ԃӛ]Cdυyxl]]az@efpdP8F}Tt4ie5@_B'Ϡ'w6 IDAT (AgiuL' 5`\&7@ Ҿf5r{gyL-1~GL!coi3NvܙwRt2/ ?o~ ɃNO|cv'>qmM'E*0v"N7yiqsg-%CZZ_+(٦A\ VBH VO8w$#!uW̻= o6w6j$}*PՑmk}| Oƴ'_>g=%DP}[ob؇1S>kAVőaU ɟm~'~"FOL1~/2NqVVy_UqE Bmd=y*t?O`3.?+Ҿ/5'j:⨻z<~RS{(?h`X=mcn?Ăbn8`na)K ")fދvvEFũ>;"(U3G'nF%?1h.ImT9Ɔ ?:=Iy3vU(󞦤a{-30hꚰmi""N\Ɨ rn95PмEX"W׉Ev =1[쒰{ܻnwvڃۓ%/L虺`!_AypbwyA`nzīn]i9֖t[[b|."0O@' NFGjo3%e<>(k׮Mmy#չ, h[&:p8/0H v=^yM{=i!M;.{Ե{jxDjd!{S p$z>BK!(QTg=[##ɺK5Y r峓SJqaSrߑi<3 褌|@Sg/uʋ)?gD "[H\8Ul)]o[|ʃQ2_1N`eYio~o|w~'ۻ_ N{׾{z?WmRy.D5L Gwy!ȂKC'E^-}a L!x{wE?􃾼zvsLoRM:{<Ns>ާl'gSD. :obGt.mY/zpI%2U?P1A#!q"YO}+;7Kziˑח8j3dѧIF$]r/C{x0:q((mI;EUA}&WnCˬd7<઻~$owv Hv}}s=ӷ-펯ZVI{׽{T.\@ s7 )ڇ~C{~@;wxO'3?=gJ- S?S|gF/}jozC(ߍ7fo_{[g k^󧳀|9dS}eJ:6b{J;$i9r5HSyŝMX54A] mv"G8Q.s!v8 oUK4 &}Hg!;"g>5WNg}K#whnVlSq"8z!:I ?Ɣ',\N p ox1V{!xߴ|ַ͟9=:ozm޿7ïw؃g|G>noag?:3g_>vׇibs:i̮ ꘾!kUe(mm^gqvخ%gDb PO{1[l0R.WG}MP(ϵ=v7HYҭ'Vh~5 W&:6s? o\+GuayEcvV C'/OWUnWt5}Bqiқ}m\?vr\?/mo{{ey G۾.sr{t?!+{7xś-M/sp2h`A_6 ~x meO~/3[^l?c4cx F[GAsc,\;Z|\}l- 7* \=]Ñr(DbƼNL6GB*$ڦ$CVȎ8Zܸazb+\gݜ*ʳ8 ?T >2/#x ;%]f ғ/ =җj쀚5e04uE^Wԉ|NSp5se=Dlt1[]H wX؆f@;:<:Tdؙ̳L`(2!Sn bv\C<+uxzxG16Y볘>E:V9B)j)+Qww&ͅ\EǂzdHF>+[!~`޺ƈj_BZ d$ޑz>׶>ʃ+&P-Njju4P_ttܓgi7J߇?|L-Øvt+3k\vjXnw|[_|;w \̓x9=#ߥWS=^)n_s!`CAeWOH GϨmDyζ=G޷8;bve22>,݋_Je?RnN b>גDi#x:".GR&uWR}BO^lG]?zcG]wAD2~1=珺$Km1<~\їdbxkgл7N<5//䅦!`8?B(gɀ s#79K"J>Xfܴ74!'{\5 ׫Gk_|[; Xg퓯౻6oo`*Ї?|40h`/JmXB1B4]XC3=4U :Q8_繘2~'@ Lw֯#?,K? Yh#2YqU-FA#THt=1QCSG܇Fѝviv~7@<'N#>oBIk2t2XM,zZ#Գ^k?!(3(xu [P.w };Ydž5e,xBu E)^ _1J8Q+'[ͱI9ǖPO1tGV@aA*}y:T?N8./E(#e;a|8rmZ/i+Ҋs-8eQ3y;`Y8p䡣ȹzόNUZ>JD 0zW_X^ 36vFlpT  I\ޟ۟jnͽo_j_}߾/m{/!K{lc=FrTS?B)MuЫLN-,.GR*ivV$;yy4 #t3ëISf.M!~sSϘs/Yl'ڦˡSӦa: uM<\/RWRȞz#'!}RGl<׿)c_@QqOh:GߙȾ#q3I9͋>(K[ݷ[-fWJnpBy4 e. ioD,(% \C5'OX%ϽQ6]_iٹoI1Xn5w*A xzi@{]J> ?') I<ipd *@ؒqP૛ XO pݤ+mG+gW"#}="=M oj:N;rFf_\I@<&I M]ed!r:Ͳm9bi>N^ Ef2ް`]"@K 3g(OyG}Sߎ=HSGڋҵʴ3b]0OljPQo4lmKc62q N ˦3aS'} '/c1g(<>v,pdq=cwxIi8$|a!66ӆEʑA}[a Q/GژsY Ks dݓ$)}_,r՛~byC=&+$^Dlq$W h2>'uĩG,d:EWo?Vq;d4.T@ڪ^;u 9"%0bIK ݫLEd4\@oo~cADY, yc`L 1g wz̈<4?#y鈫ױH˨>sԷ}&Uajuv4%Ӡ9MĘf|:d.g:C=~CYy kK[%iHT#Sycm9r 7qndMh2eDW{bil&lGG/̶,g[G<tȫr.eĄ.XnávT8ČpqL8MBm k8k $:VX|Z>@nȳHv9>&E^2r.ppkѧr ]!JV+Z5e'7ytksDeYo߱(`)Q;ym ȏ ]_@Otۆ*iy#J!"`  V7@`q;G3 LXmŮh*\{Y\ ܐA@Ij"*F&l|Av` F9h2VyPGʩhl#Y^Gza]#z JY 0@PO}5]W.<Юݶh~-m^4_' /W%y#Qվ ODL0-lG'Xțk+;y:wPg^'ێO>,ЛneĴ$ÊMXV)pڟI^hqaZ$ն}5N1m-`ѵZ@Lm@)ĕ3R:}Cd 1j~ s^zv-k8"ʔEtE~sjB3wFX&JZmi)}CK^=}Be]7&_eJ&͝y gQ'bzqDG3d}3L):Fs}=L.N^_il3hOJ IDAT;fj\.U ,¦P Nm~23!*a| Npgj!㔩r^M#uD a_Gp@curٚN*kg@]By(0[.uw+d|]\?rN5RȾb]'t>n_O)D*.: rjgKtk/\R:&p/ȿ4KZ{W'֔9׸UwhNHw^q$u*mAYoo(C_ݷD;xI9]3h"/QGNVޗ7cA 4x hp[̒C@:#;Sl3!FMiA9I40V2%Wρ:#OZ * `{-2@,fY1@vw>͒lťf" pr|x7&_? q|-,ƎԦFW)сv C!G9j5*'ׇ9O9Q!ējйyg Uk ۮ~&়s\$qN t&DŽ/ _y֓q}*?NCԁ T>-cʨ|>鮙 m Ӷ׈sGͪ4dךC1 #Fps8Yu~ ⑇m0 fPTW&ypL/qet碈pLpB#c!ط2NHoY<:,cPa9+bjqat{kd;u8B0 Idna>\]B#{N8զ,$ S 5%(ciVR| ~k9e`PV !wg#;*|ssNN#dL;BϺ 7@"ҐWK4“:Gti"?> >XD4,xdOUTOi*1dNj:7?/= kxEO>? 40h` !S<ͦFEǀاGFhshk=v3J!=-?" q Ef_ŒǼ=6s]#ך8Nlj.1SF+ۻ *qR)Пa.;|#[ Y6] FyPoXBEq%=@;ع]>C nq:4MLdZtՅ4@ΗP{ td'/E3n:4rD pqL"S +I`?CK,N )ҧ[fiW:] g9:+3C:鏬"nc7=tj*31eK=82 {>It $ڑ< 4{KUVQ UGdcV'k3ըyzrgڡ }D"~Q+bw; <WN/?|_dpiv~(|(qbd90` zS"/mY/ҭG 82.-#88u㳢/!h{{tdT=ysNkt*mgڼЅ: =NUbDRgvqkoˋ{ݙ$}>]H2Oܛ tD:2q:?q.CjixHAv~y3|yL8zɯۑ7Oxa'j,[`c#8ftj%9љfg^Syp40h`A &%@׶S8?`>pn7՗rQ9=:4CGF fW`>",gp~7*n^zZH''Aml5v) Uv Qm)K)%2cS/%.$:\$0<=W]-j@3^6Z:oh= UXe8\E(~Zt&1@tVDGCIFUf[yb:>ҾQi^\nR'Yvn罎'uNЙ@Ƣ#}l_Fa+KY )J=y|YW;>RV%qR|5m$uy|'/ys[Kיv=#=1OCdͷ7^BVᓿ9֌!^K$!N_3}tG(qo8 40h`AfK eaqP1x?"*F#`b!'= ڙkӴJ.a\=ӳl; `L`jo&v4aHN#m[$MaI+pI#%FmqL~392#)B9Ĵ9IsN8-toT\[9^-<8t\n>Wu4^/r`TcKM2.2rUR{eT@AyFѓ*DG-0xM+%.Ɗݹ ;QCo;-5qO=$mhA, 9.m9d(eJyb>v+ &=W4!SxM<㭰pe|_=O/>ŏBW 1L 'ْh+{vx6}d Mp+m ?axpOvѳ ';zlX @yd:a#H:%<,83:F=*>N@8GFfg= |Э ]_h? E3Ž~'tN>iJC9!tC o5_wi; K:uCމX3yXM{Xz"+$vLςEK?Of/^8U“.b4s =AJK(ķKi#qExΣJOHEfhͯ |yAJm^](2 40h` `h,gFkgi̞`4X 6®ZƮFD_w0? –-^wus()"*džXU X&~Dv = < P. 7@Xr)+iX;S|gx Xt *'\w:gG|f?.WDf֥<]5ۑov֌׀>e PeG8!掠0 Z); 1'f pQ2Ξ!uNWPE:brHvwGf}965zsc >99Gip2#M|BG}p~uSi ͰC܊s'gK|eOIҢ~#G{2wtB -R`>S%l|gTG.)eACci(HgN!N>ڶOxMM;9tʖN >1h`A x&^gsnh,x5jrom]@(605[9{NdHr qI[t/cT,7xY@#3ϫlicwy2BBm|PiCO/i: bsm`.hy=Im8杯wjBe1. |E/%VXyr;M7KYDw>fܔ b8" 닎l/tR[[#/|Fo޺hdⴎVhhf;9;W3?ȷ/ƒS9H CSdSB::Vy2-;="mS0"?mô[,7Soh*cO{>uw ,W&d6eTh0 t(ז6vCɤ =&:U!NE!gGVMq NU ~u:?[) =(3 40h`Ԁ6  rsѹYLS;: "*Ȣv=jXEwTؑc`eW\5=Nj )g֍MDehi?i3chq$Qdh u@rYO<12r8#)@ A\.M#mB\v~{ٺi7 0O(GeR2 K~aPx!meN䍼͌V{e냦N[sh_끃F_ƾy/98uv|m?dw-)+S'/ QN.TwJdC'GPyFTiwd{@,!u'{:p+840h`A4{œFDZ ?ЖP4RZ>=m؟% M3Nb =\$W, LEPӅ[.zЕJٳڿ'|<&e×6+`"k` 0pT8=`) NAQm/؈%(ﱫIp^].8,ã<E sWW~MF XdtvK{xN+ ʹjk&(ta0? ~BГCe?DW#8Z'-|ۨSGC[[HLr!#:#>GqTwKkV>NoQӟR}&H߇!)sL٧߰jr3;C` `ʝ\H`D\]Yd<2 U 9)&P|;n_6 }"ޭ}p*6}i`c#;h BɈnAf :}>S=sDENL\qS6LX5t*z@AZ"*Xrm4^S1g-kcH4LhA I9ն^ =Hx@)S_I xkryr`OG#G@A{NtDҭ1PQԯ'Gh;ՑK$8%(=;z%n?Y-6WǾwB[} 顜5M&z,ƋILQ#W3s#`yZ ȽґihA",`4mPz ؇,C?FWuzȻe{z?;"~x3ůs$Z`_kid|oB}X"Q|<*s_0=BI(%$Q,xs=O_'Yr(6j IDATh`A Qi` d-ش#4I n”=6yw_TGAv_,>2m3ꆇ '@8Kl-oc"sʘh| %m$_ˆIj^y{xO@6y vwzҠ|؃(@kaA(KvځruV(NFk &#.*n 2]7!ef?<ǬY:(`JԚzK_>#:U.^m;6!U Vdz΂z4W6:K^! C* CsӴ w2`gꀦAq Dt΍hQL #Rp9քu.S@~ҡ(yNiYfbSEPa@W*Yu }@g砘%q Y;i4 GS88:-dI8|haԞ !g󡓎~}ΫMs7\ЃU&$Τ| "T*ʑN OUh{ ב\*>ů>twe-3o'Ǒ}xnkrY>#gR \45`C"xGϫw;uvPNt$Z!ի#=^~7&.=:|}Z8r.Qͼt@rZcroڥ%'chIW(4BjgޗGer[7m?RW@]L#:6HPh[t3-kD\A> Wk%N5 +t:!`z</gBiE oN?Dोl~tAry"ҧXBGa5?٭B=_w|hICG\'#^N^^I '!tLARР=y޷9g~/--Jʢ$Tu[_&HDCE/Υ=$zt|! Jy!%3|dyE/8 T:CФ(\g ^n{2wRv̽7?G_m[uLJ;r>蓴ԍKp\ґUݩ/mgir]˵Ҝ]>0q;i aزd 8:nh檫CU؎i+]H}[FWg 7oM陇^W0IE~:FWUa}_֫JÇ ]&"O`wx0Kѹt=B<_?j*'a;Ky+Gg }Y)/Zc /9ۮ;)uځDF/?!ĵw:=p>beONN|`![te?$<ߤPk̼qg#w9 e~@鼴/lu::rCꖄֶJs<^G @s}a4$m}] ҿԆ:|I[Q(l%5Nf_@Rgߜ}TydW1ZXhl!0'zMuwTtA? ^=vW5;Rvp 40h`A>C%GO_j}+Mp͐Ǿ@{dpd~TO3= g0}:먹У|SP(<`'\[e6=A$]miԺscrAۍݼdRyH!Azn3bEg!|Ni!ś,⡈mEsiR;/E7Nӱ2nv+tgsf͢F)(!y ) E'dȳu?וF:MeYbn&7 # >y`m !Ks6̡Eq/Ȝ_:rh38&kl߻]<hl$VРHG.8΂3@|ݸԞq j?>݅kw:FB B*g:Jπy,Adh:X| <>FGD5tmӧLW({mQQagOi%u"ے6*eq(#hGGs:.~4Ԙu[he<ML3аsFA|\(ټ0oIS`Cޚ@2h`x-eX>z7 ڇ<[#[ β؅Oe}[GDKum"a7O>Nr[F>ґ:ߊےDGiSG||ڤ{5-7Էot=' /UD ƒho>Ջ5+z,yo Ot(sL>^vkNKOPmߢDY޿mgq ^\aۋo` oCʧN.qX0bB #["|я\ t \ҳAOy|ëxoG'Q~*tsBp 40h`AFzG62AZ8flGs8p_ @; 3T\DlFRnqW޴naxYdGU|AҺ(8K |ImM$iiǹ8Y;mfUL&qR:)Ֆ2X3ig5#C٣,:dtȷژzXot5K5^lK“S>(TUdw@0c~(2: չ|:-@k'0`fDbؠ$(u2I,=# C:: (V@Խ+uOgPjM]($;tڂz!:V4A!ywp&VI?;;yl4@ǍstmnF8 C #ft vąD*KTwұ,=^G[JԙK~Gōx6ܓ1y}{p&VQ#p%e&:FdY]$½(7o|ߺ6΁4錂RUjrn%o;SR7 amd5{KPyGMN@VY('s̓>& 3486|D@'WV3F\ QxH[tѼ9;toP&i(=el/fKB(KKb/$ӭ{էw|p>|ck8trJW#p @O<4Kw9Վ@nLGU&`_!=ș>ʷ)솠 QK|uU=_&<oT N:o?uytxƹe-ʓ:"_WSNж>|,a? Z/$ZQc2VC^dQGYì9D߷{AO q p[3Q^ɓ:ecCsj  J;yPvٴɭeݚdh-2e<7Jv@H#/ 9Ѧ|3XBp]ReK`G˽8 1_MymDl}jz=QrXU`cYH}tzZ TӠ/I8H.R;U~>>~qs>pJ&W=()y%?b#plC*Ռn8-=l8\0BGե;$QgGk0r@N0n"4Su_3voD~SP*8u6TEKg^q ]|IgiA{ lfĄ+(_`; v t |3nK$sa6޼U9,(<`;7@W܆Ѝڥ9 QoKԍ352EE[R4lN݅nN&G )pFE9tϑĔ׋:@EӑWN%wtd̉8ltO"i ~mȔGSa:ё! rLu^wNSrm톛 C~\(94#y*䅊ԳqGx? 9 )u z7m#`7D/Y%UU1rV/ntW25ɶ;ܖ#K ^KUEN>j]A!i>Yݻ?!qBʱsXo!7YSg> )ْɂOSnp]ΝsSvny >Jj;DYG9ЍǠAfnW^m=@Z>dlWWڭzV{ֳ-ߐ6h-#8}NZB'1 jKFbFcdcu=pn08/e?^Cm[ YvЌT: ʙ!AБ#%0n&`H[xؼȶJ$H-YGݒOC%r2 Fƭ>V3CQ 3Md$!t12d DuKn(y3DBĭ4 L1LmGMcN^yʋ/#Fن;W?*ضylXu茰}˗xN{nEٝ}-˙ށ1"ߍggۣ4:2j9ơ~GUYmjr?S4,v/'":FbN~W'5օT䳑MOLv :q|p tʀT)'"pq?=ٶ?Sg+2:}nԛQԎ_)D۽v!!xr*zJRR"t;˽|gK,  QhbT׵X[WT 1O:iW һ~hueQ PI[}ANfzVYב3TW,څNyPwpGǡo#:ݯ"5`ۏT_;h}5:N}nvi\DU0uO:u(f$:'|'8;N!P]@pF9#[jCs# u;޴{#zΕ!ؾ{>1FВitp*sYrVJh m3@ǂg[> nǽCCt Gg,Ѐ7wd/Պʽ:ȻSR',y*Be7sLnE(|m<,\=|(#K|w};|giyc)GT#M crwġ`N=ޖ~RKCxNeŕu WV( _;tE]`gkI(_^Ԁq礻1yuRDOU˓~4eJG/Gz~^n6ud~ӏ6q獛]!>d բ#96_ėg}"fϰ19+_&2]D~a|\1h`￯hgn*8ttv>zg{7ૠݿ\" ۾>`oELK*p}ercnBl# dg!Vs6₸FL%rحB l~/7ȧΐ}m/a_˃v~t6#Ǵ @v q> Ã1`,r#G4DZ)K]4c Cw; Ja}̓)zg^҉^uPNriGe4}P2mR pIVmaOmN,ߎrdw@"l,zuNFdKYeSIy5ó)ȕgVtå]]*o:3DEzF3G{}3Z5uWR>)!7ԴFF #/]WL_ Opr%R#e㛜<.:Xy }Kli'xͥ]B]>] gEwGɹC 6;f\٫ۇ3R H>=l{O;0X:iƟb7- `#e\AF5#mkG&)&VmȱX0"B+l+վ>1ptq\@khiwˏk8Bh_ 7%C1+uH7ʽa Յ(դ~unRb؟NNiASv :7 Ψ#!Nimk%u=t.ylu~H42#8p-^oF;W40%p}D!Mn«N*uE)<{]NV.P^kc"~x^$S}4F唐}1`?JNKmȈiVLNШX#G}ߣ,A h~\POi?#(@yKDSt T~ _|RW qbbZ"t.XVak:]<ء&?ِpÌ gDd'Р\*y'჻>& ޖw,gCCKzb#k:=A'a[N).yjTަ㾴Riӗ&rvt}(:49]ϨWz#˴r9l}1JЄA4Y5|v4gٙ9/=KlT͟ՕUVv3|TJY]*i5 D|zZ^GU,SG|! J2z!'ѥD+ y]jUVUMXBQG#שƻgaMv`BL\(+eBnvt4@G H7G业ast4p40S͓i/'} ~`4m&>,; i\;:]WeD#ʶ,CM{JP!ΐ[e(%0h_?[qAXk7RG'Gne'clag2F]0$8ͣr8"pCu&$08~L?fK؇ʰ4uF"P&(zkw+cD* PH}T~ka3/vj3zGpX7]%-PV 9'N"ڎګQ6j\Xd6sxúTjG备Y$m?A[_ 5(~W7db` _a5ʔ `R _9XVEz{]n'5υ G&.0(hxll7#n.t!?B2}尳YHl(41~"WMs.9ZP]h&(`^p4`6w^tWCZ>#Ž.rz},S "  p}z,W,1ktDx vB3Ѐ,' vqWt(m n }F9aH0J OW4*d5芕4ܻ>iً2QI)|(ܯz-Mu9|n(3/2{%|{V/PĨ/LǨ̓C+=$2zMgEsiPGg#ms})yCЦ_ev\UsWqmi۹eDI9Y<2leH?lD:ɛ}̼4r.M0"EK٤*ɛ􅧾j[S Rh @uP_@yاZ 恚fPwEZs@~J4V^pOb{ ::GG t4po}#$"?Bz'4i-)om3 ~oFۘg̰6Rcc`sd:6潶-潌j\tX L#;E\^{Tm ph?af0x ! ?f˖ 0無sA YAY6t3LkRYmc u7IG Q68zRhE^NPzq'&V~y>XGw; ) y mोaBʩ)jGM#/&boKG==`1<deFԋv4t~ID!q!kdr.OK8sP̌@K[Yhѩf:|I=  :bݬ[vUzirVH뀉EW9k<" JoJlݪ!%i]g_7Y/]9s/wx0uv Q=+ \(W41מ3nE&]s58(A3 Vh@; 9f%!s8Fl-XG4$aLQN8,^#\yd4Fci 1ExȌ M{oP2[ʟɓ^G_6wB+OO[2cvGayGn*ߢ qbl{'#;$mSo4gʂ|*mRy\;+SF89ڍ~BL_^BJ]ޒ8!:Է4T\m'ENcTꋗ?Nzցʫ^mod/ДgJ?2$]i2kVIUCR/JDVY9ש m>N̵4;?$istɌϋ H_hN Fx.Z=xBcEԽe=eϮ=({:h`A [G sO|w4p5I$HwNGKZ@HAd1biRibxo?{@È)bSj1qCm ?n,4 w=( іlwǩ`a-;&bJB=[rQܱ+öm6||g>A /D^IjܟNਾ# jf.(zKϣ;À< yE:$l#y(9j+{| _ʤP䉃`8`1N JFij|Bg.@mp`8l}3 5Dn(gbUa2@Q nZ/`[Elk#F\_2 ݻ|PQQ%far֥/x6K[l Γ:8®_QuummXH׌:1x@^?Xm辸(9nt*;abfLy6Zpwlq]"0 n).K$AN(RƖIWp l#FR2i-:O[n/1P"؁Q̓06iL !80bj8FqB(`HШ De$xa? y}{D%d>C+ז;n|SWWqT˞dr(7;j i#Џo<ֲU"P^FcrN9u a)dr:/ n-Cn^IKk/r/kTiFG̍e2ɮ:6t-i#u|AGUZuH+kP |"1{Sv%җGw|e4| {}Pi%V'qlOS׃s/)C)Ë߶Q#[2PNgT}^K ՛^NpA?IJx yKQ|]uçN.xsO,湏]ڲc^zMyTN;~2D[^?T: t4a50޽&+Agq-GnCEh{wj8aj^ԛ=݂I8>v󁲟X`@nڵь.mtO.ଣڮTi#`?vTLvU'Fa G`}y[*] HR[_Vw1g%Yɟ45\2 J{HrKV= Uu|8Vڭ5tHV虦<ɧ 6if;ob}FYd7"Jf>Y WVvFB B8(u\8qΩ `71uS>\vt"Лi*΍ $k+kni/dap_Ynlr) ],TTjfpt:={zz}CfAt"/]7p4k uiS ]XX(/ϓTU<ދAl4n4aJܱe'vR&o,Z+ j.ؽ!VTMŹ (J%έƔGИ(Z bHv5~m[Ȯ2uX@ʲ}C ط}3zGIyՃhx=Ao<1ܲ"$M'V:ŹhF&a×RuP+M[NSGh뤼 DbQx7o^g5:\olsn)eFDCHz=\/#tIh%!{_ ^3)89H6]%6X/ȀvdI]Y"!iY:!m #h^)i#?6Mz59]_oZJ;C0`|I?[ =8g@Xڡf7OY:i8NrmN5n~/xϑ|5M:R5l O)"SFKyFzbLە>ҵA'mb+n.]7u9-cF_Vwض]ꈝn{謑QxcrVh ;= #]ЂXNQӱ#A_N`:w:IF[>S#b;t:.#K_=fVZKY౩KPGd'ЧfGN; ?uh/$$!/EnuO1o,z^#PVi}x|Vm>d^H=W?ДE_a^oUISe"d% : L^ظ IDAT$ei*:hCD܆[g #A_*q7LKX!C#)7gi`;>/gʣ򒗽‰pK_L OCeWG?淔3ЇZ.y)?u|ԺuÓ;М_lyc;?vݍC./~KʯoQĆik7z "@[=ԧEmLka(W`IϴpF6lA@xpAXS&#/BJ.h/b4. A᡼GNx6s;9 ԁ8 uDԑu>}nK>]4/!ZNpDu ~Gx^FȍH{W#M? ؍>]|g0dXGuԴ\kד||JsFn1UcC'hWnˆd/Z}8JRYH#4DtEu V~¦dzi]nRx I::i+uDUۦѓʰW9C8EB]:}Y~%i(@+mx=_tX>a!!.2BIue!d ϱBJڿQӟk_:L=x*/t2Q}f>qx!/չ2^VəWwp_{MY~CyⓟzD:[\7pĜ<)OC(E5WZU{=-^ڲ(|# _EtS:w ԑKK qhܙ*tSCO;ܟ.yC9k^绣GK kvQ(6`Q[s<-HǺTCw. tTϊh(O% b2 k bv~ '-XBjt&#JLP#lG> r;LMK'M#,B@ ]"M]d\,]F`eߚԑ 1uϥ_[ y-ǙJM᝙`@ɨJONp6ӹ X!}>$:jBܶT(1+G'M]:$zFVX@]#ʋrvKyހaJu3 .Vb?l UOax6tj2s$oꇖr!0z`4n:hؗc"O&)ú#'$Q>TVNZ2mü8'T,_vD9շe++V>(C.}U犕ӷ ˄ QEw͟~\sݭL1>yY/_yi-%\Bhdy׻lڴ|_+rח5k]{/|ay;Qss˭Z^&Ō$b=S?˚{1ĉo#3|TF 7y4M{KOs..;묲rꔿw$s9oWR \~}ߞKr$ͣW_ڲa1W^H|Η}~g",[,~7ofk9l#e~崇?|-2GHvB.O=e~G?o*8iۧu!#_fq+A7xCs\F5mcǎK/)O/0i-I߾};#_*W||w}U hU󿯽r#NOg$g!< =3{9:poy~We˰FfjQB -9Hw40Ǭ/' ^.|5 C , 'p9zY n 9]Z/I{s`"8#/>R.t-T^yU%z$cB']6P(o КNZu 6-X#ANL(~ K[#sFl՘ivuFumd;FUc'){>7|_ڴ;C ʫK{b@3[{̭}e t`@Q&iPZFWҕ4'XZ؆G>!F[OASGT;$>I>D ПWF)k;[ȟ1Bҹ:E8lv>ayؓ9џ2-b|VWtU(=iY_J:=۷oAz4:7tc/@yɋ_\V^]g pGOߖc9|{s˖-[/~ɋ-6wPx 0FFFʍ7T}Ux?rח8 ߷o__zUy}نO_5+ʡup}kmo-}oe۶m ҜOcyNс N|@y#G{^vhp /d.*o}7,$unB:_>]~3c!{m>W\pGCb{f=-#唓O.T:sBPDfO˭RN;9нCX(XC9R_;rl*='PEgSp/^\. +cx=uH<;CgUVkG. E+oz ݳpoZ{9%g~/eۖO;S?s -. |g?—638O!LMa픣J7 ?\Ώe{C݊b8\E^nkxd75;7ϩ #/ڥGKf |oL]0sI(M 6rP@!}.LY|SzOEV8VeF=Olz|5z@[wmi ra{(r}XU:Dat t$xMINMyQ:ugdI*DҴuϥQ%(e4IHF~So3rg:qn~q{砃cL?s$4~ad~jyv ʥ݁ qlwKR3<+A MRzP>JcJɈӀ_M#dcrF%8=K,3_4,I8Imj|2V$jPmC'M#CS$+&j 4EgDDP'ߊ˪ Rygf-׬Tx<Mk? $~76 SnNUThs(h˷Om@immxy| |=,J8y"!b{ʪȐuE.ݨ:@z u?E sOΥN|彤p##AGVQΕN \ѷ:=Ulj/2 Q٦^ym<(ҩt;'.M<<\yj%/՗{CUV^xʃH~[t|<>7܇VFکNS5-/-gXDkU\NАT" 4I16mk6jr~8ФG"/]+w8ZGa?ň^Ґ~|Ǽw*xϑoX DGO$YU &Z0]~SEP.v;坼XM:}Yñrx}Y#Q*ʈnuNL&°iL^pvrMC^[z@J^/m_EK-W6BAcuȮm)lB'!;AD;$Z#\>vQ,A;~=}-"o`aʝ8jthxʴ^2j=F﶑1=U+n .ֲE䭻T3 [Ƒ!>ICv`DCC˿8fG Rz|=^O@ N'^K(ObA +m@YhHc}U F&?o6I'?뗯P}GU돝|Z9Kop)IPH7 mC 8e{dѣW;ZN&t\fjΑku\d BmB$?%@SdBz_BndmgY- _R$HZ@O+ y}>¢m̻ lT';/٨#d]P8#ӣ8g|s+:z%2XaWF?.dsjTr:-&OMAgh9 aRw˧ ҅7ǩɑgоh-ᚗ}&:)f5T_m{ J>K#LПDf;>>+i"< y`|@G4z4AmXBy'O^ dtvvNrCH'-?=mr߮O8UGQmƼoʴ?([7[,giʇNȨ%\R|X.&xR›%vge_jVѾ/K6ˮ[.NÕ[wN:vN|e[U.t-pՙD51w c s.O·ϱ?bܒY2(a9:,gϖknDW\W,[fkx=*Ep<*X0}MQ3- I4#S%`Heb0Yh#m Ң}MP$M!e SVҮƯdejHSVLG;1~ ]iG~TɃF}I2L84rk:#)K6Zfeԫ33=="zqL.>UGj}t"Mm@dΈ-tz_y(7']-Ur7 sDSۮi"3۫ s* ud2qH@߶Ji[ ╲G!n5IaI^x4Pxrf␲I[LJ8R>bl/`t؃cgx2w'DSuJZNZo&DIӛҵ;oGs_ՓZ`wDX8!jdУ:M߂N^'K˫i^Ǎ1&g?}N!˾tTy|cv?oxC\WsǺͰe{Y&tMe-w}y_.EOG⊯.s'^˪wh_I:lܸvۋɾyo]w}O;+W+V(-l?B|_\wu+z7[^[aݺI[۶r#ݏzԙVFEPnz ۏxBt>;z5?w'1jS`!CiNq'=1N.h߮.|m)}w揠ԇ\7oZ*ww}˞{t@W7t#*kmIpuIu??[zY^v.՝Gpm}s7;' Z<>.H繘 g|O E=׷O1F 3?J;f})ڙn(-GEUﵡv7ȠIu>Ky׈I#g~7 ޚ+0FN|giC< k?y(ah פ։+`Vn:=6TO6!.L'ZOOWr4mE[:)7Wa`[xzlw\mxO!=Fi8o>iHTxLv@v[] eΫOAeŜfZ\wOuYg҇%lE95|D,ؗ@^CxDY68 `c 9}ȅ=bZl{NS_\ĵtz#(`q5)Q؉mKN6 3hۓ`mziwˬPP}pC@!_rp^6sUo rheq抓'=3k-s!`稵n?͆CǨj곓 ym:k`ɺJW9I#Иf86C``r0r6'9 rBFȣBPbNG QKFL?|깖5 GA5;Pt0j.nO]G`p UgBu#msS>rȡKo)OTyzئ1}-)[PN_B.6>l1¶ tj4zӦq őFwª9lN9iKT<r0?󙰲нCyu4\лX"K fFQ ~wh ]NNGnӏi{i#Y=\԰ 9 /{QB] cM8~BSZͬI! 'yuW':PWVmm'NGODnz9֩f 6-,fy`ڀA1K-\} rF3Jo98g6ҥJ.*0;ŸtX:vKm݀FHL :ͯb`~֑,p)38_l,9n}k"7ヰ 5CqyA^1 egtQÐ/h gZJX$X`(u <#!M8C3-̢Mț֚΀긍ʇ!u RoA([]yeώ]Th!,ΉdCg'Ljِ =!¸j궴5 2Tr+y7r_C@$9oSؘ8ÚdOk# Rq؀гC(q2l%3Azi6 =uF]COڅ{I|hI\> ,CbQ;QzE/;^,,]//6g񷏔=YxEyov?sYPԇ=Q/eW%L|~i=A*{{˛i~ޓ(hvm\q t? .V}4ٟ'L<5g>|J/ς|ZÊ_VjXudHň}⢔bS8+W‹~u$/T} _ޡu,w3w}h]~COa'[~B}g_:OA<O'Pc͋ⴺ#o/}gщx :f/M~f rI:<<.&b_ڀpwnhs/]Z_+kV-%-#}2qk-_z 7'>i?FƖ^绣;J@EgŎp$5󣝏 atnPO9k@9yEo @m6!ю: '\.17 !2zƒ,N7+8V =xQ><)6U|X\ SbQ#2/ߡXi %/vNd_}`0~TVVх@~$SDC!}1=e(:QB_q;.S+W ֏jR.~|| T?ŻVmV@t 'Lom- dEW pRhH#<:֩PG$E]v(43^i ;-Z,D'c1(ҟE™zSD$UCYC+8W8b﷎Dq:©x.CAC{1i'yhx0|wc?cz?s%2qQ C'3u@^ZqU-xaA#@!M3TКcOy]n(1| T\26<F ȿ gn5 P`Se8ZVa썡$9ud>tx5KOpvnVyO~xI:xi4F= hԢL6|CmF(C=r/P=xݜ$#3EA;x#GmYFHQ%[1iô ugs9:7tW_0-R5/uH hp' eoPAu46I[V]T٩i'H?<$0E¿m]U'p 9ȘaBN4pΚ?kgjj'襯 $koẀ+ʷyeF,ikW_Z4rMs-~GG 7ܐȆ 99A#kyZcUC =䄥EBɕ,qA^g so4B>1A[ (=Wg [->h5 w9`GG[q kvyd@$RvwAe$.HqqnC9e vLYSnY'S/۽7u'gZDr4 ./)盰yن<|ɨ|'XzKtS;eЉs9X@,LDI+7<`A17փ?R"p{| (<uqASA? ё}ԗWSF?@l7rEycDE6ԯw6O+{@^4MNj RO+}6SZ[^=>'L:-^V&k[>1C/UD/8e.Q;GSgqfy4iZBt4ncQ|˶oV>g#+Rc^`!O(b4D]?!c~΋~w8E`5 h}{swb!ݕя= Jv~̱8Ә}892Œ o~LҎrvjlp HG@Fy1_z 1Ӯ * Ŷ֖WEgȱ %8|[q'Hx}$L}eT&7s{0Vt[aږ W/d] ZtYk6O %\Cw1s8<ס"wQ]. *v-]v:J4:\#Djc@}KGfq&8 N,m' hGIj {}m&jc:$,=6q5#PqCi#HSq$Qq( o$5iS`(ש Ypl6߶wm/wBܸurA T l?@CVMN pU$DG־qⲉ*ƙ+_K_r; @=:"`rj$lNtD0x( (CߣCO*ҍwP.친AD#5i}gMS y)PIqKa]eUŵ!5䚼VΓV7'77ͨp΍ؚ|Qy> tw?Hi'@E1ܩ*M9#/'>M#yjΓQDFV^\Fջotu0]AZYlyie,Hg }HQ^ vu~2kqu srT=[F6(^ۀ3D\2U+;6+"蘴:6L͈LY[UC>c,:mc)k_J}2 ;AVqIcsrs}X}%*:7sAPݼkiY@!ߎuFABꊯ]Quij>?:iSN9R`cM!?̨OM{avmlEL6I3 XM~2N!(^ƨs< @X#h5׀;GO<{ׄ?{V:ʏ 2ZRQxkD:X,0[JYRkecT>e.iUl'e.x.gzNy.8/l.#ksJQ=>QyI>>p|׵)ȷ3͜B^BRYBZ/eUO շko<F9`9{7ï4|)hʶk\Dn~^P8n^yt7h[Qs 5ݻxGvA /)~KGޱw:XYz0/ IDAT“Sw;ejr N +Eφ:Fbw0'VQEv1x`ŠuKXwCڐ}똢=v2-`g0:Bd$l,D2֡+4P P!Ʋeeeob &iiC+615,k̸CLe2*P]A3VHě4ٰH@wmá ͝g2isz͵4tH"/νLiU^r$a 5\h.]i`KPv(e2Fl(uZ@L)nuh3YdnAS6:1(-#GՑv"_tNYԭR2‘rCkU>DUl65+sDVGu&5^>РD0n [G3z0{43E}XGͩ|Pf]U~~|+'=A#n_t@>f=WA[{Z'tMIY",z<:o?.9c#4q^"{)!m҆6hVcҎnnH*` [mlym<ڲSg¹tI 6sݝ$j@CBfdޑ6PW}DXXҥY5u];렣ti1:)U Q]L?޽kasO9/reg[+_9{T?~)̓d ̷y[>}q/JE*ҤK7W fouWG9<.b05D;#Il|9ʝ^xjHO}Tl+x0=0ʒv8ɉN=rdڶzD?~"A?77rV#zA)ewKUYS:.WwxٴsD 4~`7P !G_/!i:PzY-Zwcޔ(?f)җ_nD__J;X/ [7o|P^1yC#'gh~5{mBnxl|-[ؿGuj{O>U xLȺa걗bKjh1@yūXnics7&ܪݑ_뿌-# Xٚ|S)uiև.8:xKqOݧɤ o.m8Vr1> m'1(@he$Y>xzm5U OOa.rYy\=ǩ 4ug2F chE:~֬lP2}wvPiXu>‡s 2kE3ڞrDt@ s&}eADz rN>X OS)Gudɣ x:E6覭BN`)ޢ:<|`ٵ vnc۶%k: N CF-0}FZf<^sUg|S ?rKfۏϔ:_cyYPH : /ϬL.a&,/(@:emT5zQ=pI=*]egc9>I~ ߮bfQiz'NMi>(=./%k‡ky\*(Ud3V;rzo捲6S5(F $xn?n~Egymꚑ{YnW%3I?@#/jO0=,vmA]_ & _K;ʂD^/i訕>f98J )'xMc}?WcǕo=ҵ&0LٰwtY2@>RhOP~ymlZu r)þLa8dW>v =FGN- 5sN[Avtn^4Ҕ{Y}LD[*fAA&yv:hྤ%?zN%C߉?>у#eҥL9:kX/0vXTn E?c`9DuHLB t3*:jH(6H? s8f s bN/httuvZAbdߺ6d!'9uFaA 4ݣnCG%V3,]Z\]J:azs^gM4"(z7vh&MLO4{!]HvHomBd6ݬ]=}rn%?TL5ɖ裿:S\ y_O!cFtn䈲v-,PGTo* >8r|˝DD7V,aqź- u]rgnA6-qQ6SPU@n$Mc琍ChGHЩ%\*Sdg:F$8imzK%y2!Q3uǮ2a%`pXiPVtF̷93y#<^ȷdv 3ՅjY,EώWL#A CxhDp9S^I˻4lQ8[^8ԋx/Au s=]822la: !w֞) LCiedpTp+G櫓3бhVꙴrN8=NM:ˋb7E'W,XuԴ[6+wTN ItJufСɇC3‡>ޫgښS|s:T2z4+-]m~x:xE~yFеc>C(? 6/[s!j]a"*W_~+ayEGᖋTڀ,[=d[Uu:hྤ~~=r͵ߋKYe'r* a`ʑut4pX aW.@=aâ} Jgo~FTW}c9o&Gy97_lRkҴy_-֧#+8FU2%".x0/4f.H&aKRVfrq 8mmYٖfGw+l-c5$N[+/Gs+&lt.Pu3J]Z!\ )h/f 2;CD ThXC/":Cm>hX \t?krIO8=] Fq3MDwp/YVLc[69ʢak;X 2Q/]xv8Uϧ fL5b@c}eؙ]<Wاۑ梀qШ{?Pa̶l\cUq$Azt' a~$st i{nem B4Y N u *y;L#P.r6 P7"y4|<0vtfd @T2V}O2Z`A;6-3 Z' p|vUx7B O鰞Y_+`uj=G@!B#0N6˜7mKF5䡰V}}z-P|C/!S7YkuD!N?uaڠե#o$ kEǶp츼̔QkL;ij]UUu֒q+K"FЉU:]/GRq?մrF2jYAf[ٞ:)eR,%K yqLC}ۚ>>C\zH$‚e`:ihci*\~ޟ6QVY4󝣣6$1a08Et%YIG_y^(KNV$.8boߜ$knjpLfcSyl V.p-8'~\gP +;P54۴Aj8)-mA@o9 G*vBx݊{Re|zF=H[뚭 y=w1C:pQF2ϵ+Y6TS C\pzN4tcnB# x%]QwNCoѱm%ߔ|e \$jSXZg{ CmA5esq F k/{ Pn[ٟ>?72zO>?,7oha#0m}fF,LUj" u+cT\­~dSuztשKeJ:Ki:,,v"?l@NnPon} ?i޷r^M9O)n.7~$WН&tuQ̅ ȸFK4qpo ` |lkfDl`!c~|v{9"ٽ%2n65/K1uFiB#i洆:/|P37o"F#*O '# S+e*zU)B I= !` 胪*2#;+Gnq@vLӐf,@}:[~ZAYA:%FN.qwvn@oJ7JK: Rnm+ι<%Pc`t䥮LY}H/:ep> h#Nu씆s;G_^m!u4TC>}lv\^"m{SvxrpԗmO87 D(+;i'ekWe 9ӡk?vUG "_7@[)ΎIj:ǧX&1C=esB/k`5읇%q{fva "H)z'A'//BӉH@рX?oe`QtqR]]U/YYU#}n|:\Du`_Pj mK+Ζs+[VNw$6w~Y &n1L\>/ P~_n(nW*ChW9#C~'?ulB2DVHa D'"'%Pb~[W)!w) R+ Y?^g]zFdt.7Ͷni$v.гsT ۅy64p~tW;%B/$: 6.]? Z,-MKT[줮ȏ>jQEXLÇ<"˽y>F.᲼:6sNwF/ȠD_3T:υJ`c1G_^z ,?kϧxs|6(O\a?[ / ]ӣfFsfr^Gٕv#Avhvj7%T^+v5%+Ҁ4Df19 3 CZ<'K5ZmZ+_cݲrI6] L0!Wt va;iTIή,LVnE<8§_oi@zꣀTU k03rKCC4hGL]D恐r` p>xV4! 36k_s(ͮf}3֌w}%?:z}L鮙FbȔmgwPr6Qo|MM?fwpӀP֝o(.B?Cty$dCI't\_”6cn}{zᘲc@>2B:5X skoE^/STDe(F U5hmu[ 89U&=)KX"-Ai:bJG~bʓiS>t79gF :f3t,\"R}9# :~DREoЮPGlk_ BSY-8_R/}qnԂ?CPfͽ8wIjW՛¾h&W:_\H96~@^z 5n <~n|bsKv_9j V q5s?lH6k4jb9ksn 2=*{&@$ /e5ХN&2YdT q,½!`y ~:oݦux-mҒa&b IDATH3ۍoѸV* W숰&ba]a]堐|Gt'W"MWהLE ˶>A%rj/rY^P%ϵ7NMfiaQ뇉=Mlϙk@h} udcSVEVn%U:vri4BMlZd+NX :daN); zHjgk{l1! Oz-S~D۫LϠg"?d 5GY&a &YHΌylA]s_[^\$wpro0p2쬅BZDKDd~2l^,#NE%K. @ SPR~y*ʴ!O[P}2<ȮBӳ @q=|Tu~}(UU0CKfGwuRUsŠF&H e, @AR'~ y"((9e@9QxƜw*VM90Z>=Hp"X N66<:1sZIܗL Z>nSr q~B{29ة+V޴eɛ+SplGu}>zVqweQĚ],TT1ѕ>ԚCt/B=}FN۹n%ײF^G7ߦ[g^z 5km h=s}!f~1wq O ؝ 7Ysc$k _^bP`<K .4cGS'I,V- YC`L~<ðzy݋Hڙ3m:m-hbʩj;]_&fA#e(9nn5ڊA&@y #x΅q>,0ta/u ~d ;#6 'PUCΌ&s-9wI=["1G92ːp#> 3;v= e{,Q O^nN? Qw6u6,3HZj5FB8!|˫Yf_mF̚ ϰLF8d\mu8El` AX+@dY"`v6=1LNXN$ep:#,blCCͨ$r#FZ f,?^ kV{ٺz>O>lǡ|Ν|D!TxKIUKO 鶻:_jT -c?I߱dki?p}(Cݒw=dlg i_2m,Fؖm_ M۾c 2?z 5k@^B˯\4w53 Cǯ_q5VFeMÀI {0IGXS҂hGw)ve7?V׼hh]!bu` ^!]mήiae-ϐY5, Ć7NN952B/ lҥE $u`M\Α38 0 (C8uy3]~ _+ێ)#I#4t HU'4"vOqRpl1Sk.zo{;eAft.@FGVt}wXu;@N3xR<7ʶz^d)>2)^@:sD#^}dt#6X W] < +\`͇-2iݤ4 S'`*"vd"Cjkۗ/06H~FGq8൜/]_ʒQD=qh+iDopv+U߰=%ʻ ]zX7$ʔ$Q ?uÚ#];u`Хȁ^G. Ij.]U`CNIhۆlkjoNC_ɠZ'myB[##.{ݮPQ|bq}L`\ա3 ?ڸDrné{k2!Rez4t<2,8>?R0zO :Id8ܙ474u`Sct-Gԛ#HOELeF"K Tg{" gk9G!kh[R^u8ŗzir$Ud6`2 +4ھPA/$Ma\jD۳$9j): wTC:>DaS.iWL{mY%ξJ)xٷՓrn(ՅG^z 5k]xq՜ec8bB@𓝋@5 5:lLHL6MkL$۰`g&) ƴؘT2cngnCǵ$+8NG=`UpD^GV>@'P̢x؋4KK,uJڊ{#]XfQqG0\' <7 7֖!-+׎& H@6nٽVвˀe=FB~,gr*9'EN8˟cB]Pٓ,)0^u$@UT:?eeצƀv#Tx!>YZ؁fA@hoM+!{|.Aԉ ډon)aW FV'l+mS*^2 mWgU~ T *=ԛUff"wYO1A&QÁ:.'چXg`q}6Á~|0e[QFa/^W%1m'?e# $I9Ϭ|nxϯ5+n] s!Nunq踍?\w`ÅuBQg3b`1UxNɣ Az_8%_`v~2u7 WҬiz΍!eT)1ˊ`+.n1e,`PyP:ӑ+e`Nw7^X@\r+mC"`ih yxcv9d8]^sǷ򀙏S睤hdŠa9u;uD-d *rXL]ȥ30 ͼl) c(݈#JcIsXoxH Qxu9DX ytW"+ɯsʙ iшCȝm2?mtBԢꔶ ף8ദT-%?z 5k@^Ҁ`(C[ LaĹq߱S 얉_: К: g"k C4YB^[9}Y]b@D:"̻ %GD3(>rps2?óe&Y^ 7Ѩe׶"W𻶮.#Mq)+'ND qj_#v~֦;ZÔEw`RWQ e;=k<|WPXq!T|T>%U =)@d \# (m LkuL HeTעI  *˓MQរ!_XbmBkGoz,J9#3zP7>yqy2mȧ%݇ )bJGriOʞ #![m]>|A6\E'|і5AW^9ܜz@=Z7ZAlӸԧ9 R|G#zTvPG#[ k e]Ӆq;U9ԅr+'y1|YmlOow(]7/@FL*M\=VfJ}F`C%I0r<+a[fO_oEU5wmc{_NtP{yo.)gy?p͋?xqf:|..®074_I]oF2;pk}!:mmHdHx:YYN^վccym[lA!؄F0 i C L.r4ydx&Fg.e«_b"=Գvcp>u:td{qfO`3MTe|hea6֍1#*PYaf(VH:Q2,M sm"*Nq8SkJyXz#8w1&#mHu -&!Aʔ&Lq['ܢJUl;NS/"qc H'k;5e mqs]W>7B Z >dM7eLPc.Nh&x%"p txFsW)#J^&6D@G=hb{!(Nsss9عK3R:”gNFS?0eR$xs5ޙՌ=0uR"Ary- Ϛ^c)5`ّ*^A#̚u:^>;#yX-;"#W;z+!UWF7ʂoȮsw,ӂC`=o1dZe@@TO^v/|  ӑ'@3WC9*yQT m m':Aw?  zĹI?tȨ֛=KVuXAuiv"s zFV~ZBO 9gGurjq P.p3i^/]Vu*tσ_Z7/l~pI4@>|K_j>eO{,ɐEw߷ͷq{yכg9wu·wخ1]H0>SEp`xdDB`)n׼r,XPU35WrQ^S:IjI9NI|}o@( $/;v _',EPrdj;[1#ێ|tq{)ѭYD,h( oީv\\}Cp !ݶܼ +R[d$=WH QK=ď:JH0g6ݺz/8*FaC=AC~#k'57('\-0i/2 焯-v @:Cq({YDC:uZQ6#JVObE"dw ,(`ݶ-C%Tj[  "hc+0fl0Hp=ho>8>Wؐi$gNE RA_S%K]./*4#NT`2ES%P7_e ~&*8Z -'/8>@wWC4tu(<4P$yOP̵<څC4xZ 'yKC;yXC(Y}ҷLᏴ%Wo :bI@qǶ/]rQmݨ\ue!k-Lxw)svMvD/x) }9*t0_r?U^{0qK< :y?lo5jEza$5w'|yqC;e8^\x)i._x>|,1t[hFv~Y][|{f< kԢڒ$C`3hb"aFi&Z`0PN,`Iy:[HhUBҷX_#(e~֞}5ޥsħ`Isڏ1?EOZ ԱG μԧNQ|7\ ¤9vI0ŁBewM_HUt @2{VʧIljNGy[z,:7L^k?6!k m-Md3<޾uѲ|7cٙ[W^p_qZIgTNߠ̓? H[qv1a0HEX<֟ =xOG?^):7GPuܞBmnKQu?݌ѹ cDQw*6_8HK4 }kA?7S  6߉ kE؅/ ^AZ~А߃+)D'(pr8R:^٤FX LY&$o'R#ҁP9,k]l*ϖmqWMQ΃bw>P-Zyy G^o˳-Gy"_n&a(o~$uYjCt| w_ XW#TZzSGt$?pH$(VXzH~؇/:cH@D!5o1mG+Eڪi~=Izਸ਼/Ӻ'GGkPWU/I"x.%Yd-ʼnR{7|i_,'>t!ϥ#k0z/p7(J~~I醾CZ>vy_Ҕŵ8BO9_eUCeuuϚyo^%^˽1DO-ƸpۅD}SAwg67'uquKw4'|O7o6Ǜ擟NGO|3︮Չ[OOq[{|G6pਵ7޵QbäNAvrh@Tɳ̣'nmsIk虂oA;7A::vݱ0;,z!?Ƀaeͨs+d*{H'b q1(Ʃ ;y:_ҟ!継߶%%%w;wPf$5掶T?; i!\kmF& ʵ4`IQoOFD'*v6ާP*޿~%0,ERu"8Z2瘳k:@r1S?9sgF:|) 2€mA'#4# J- O9;:'?UYz8^lێ|EG\cf SĊ 9*nmCH^gN6_ tkBNޖncz XA:DG̭JՕ ~?#_Y,gqύ;WmemQIjF?$=^u(cǏS"K۝.-fGat\}r-?8 ;i釕f}T<%6SViD_(/:׶^MskQ4RuD%i1{}+_Nʪ4fΙ(#n=o6{g^}dY),<> ( ߧ;ٷ5\Xcɑ{yzyW0:dzm­m< F=sis8G.6Dpʃ;A}Hy8b5k@^?&7T'r`Q=[ T00@O}-h.Qe Xđe-ͷ1` sÓް1d[c?`bC\[%tsrC1g娸EmD,nF= @V+dg$v je~A% e _9]Sii]TceepT?TSi ֏ZӜ~堵u#:S@lQI*?MsEo00e}Ω6jˬO.xrP{s\=e<؅f$Ft;1Q֚i'v1q@2oTS)f0?spioSK(!3BB1B9R}c| {<"Dt\`\(ۖ^H?zMApZ'ż81GCÄL-YT=.=92ʉyO-=늃zxO88vpܱn@%k/ru_ MVߍleZ6ͮ.+.~Ǖo5/<\MxǏ[nlYcԲ~F=yz׾:c13<:wcCD TeFC4Np}ҥ殻3>r_7)7Jg=-.]p tu tZH5٠[ a)tY@֍ƙM"K?35k] Bm.^?%5em"ls oՀFY1UHwt <  ms2O\3Ĺ(8ɣI(E( 22?K)44C)m4Pf.:WxQdH4@ƴbB4]\jw4[&bSWö+WWGؠ .; =,$,!Ի{N҇ѩg b!\0%⠯E-qZcܠm y/zh ]F-u>n-fœèo(+lҳ7HjΆ6ާMj"/,y*UZ3˛\픃W$Gdj V-QXV!lʷ?4X!吰 UD勎ޑQh,qC\u&_,a녁M? ȷpF|Qn;i.N_U ~SYh7 rk5 Z$Q@}#ӉNO^Q+N ulDPއ==6ݲD.쬆5Om)i3Img<|rG^ɾP1MwQsiDHK@ XK8QIO׫O&U{^kO3Ng<IgNR}Q9qHrQ pgV]V[o|Ct5tѽ8ϝ/Q[4Rsu?'7^\{rukYϯ]|;ͧ'u|̻6gϝk;s|,Nwqzk%ӻp+:,6YP.% -YDpg;fCG<PS3P5yTr\NKPvScAYFzhCGzr…*#ܚh cCDtdܶϝ8n1% :Mx#vPߎ੅0G.:6fC#C*3` 7=ttΔ`uF^@(ؒk#x7y^k>&s:};o 7Uű/o>Ϧʖ ~6ǘ5Gpyy?l>%V?pe{?s0n^2օg?v<;) l4wo 7hΜ=o/?ƬCguP~ ORm@^4pv1O|Ӏ[6~+ :jgc-ic`aʑ7MV5ʟc~i?j{2RRGw5OZI0Xu$D"wy8o8`ڬ͍q `ZfybR]Vo_^3 \ALGLZ Myo9)׌ -MͮȠ\@l]!خD'Qp;fո&##yLXƖ35Q ֦F."0/@/a+չx\`}klwPlJH7uHkA<>Cq4d$_sKC|V4W A[!q 𩎩Q|yW:^QJ "d8G=ka}oi8@Sk*rN[)9>q2ΓMלVV!# Q IDAT/"Oh϶Їuf+;Z@6'e##G`be\`Z4"eZA1q}9P<3՜F@V:{m](oa7ݫ3bY={+ЃL ȃ3Ϝ~@NN㞣 %оsOс4ee|,׏RGб!aqz=x[:*@z8HR8\:Yi>7 ֓v Z}l+cyaOUfe(:6%䃇d9T:p! OԃY@pO:(_q8ԝُN3D:H^9t*:"_&{BC9slKax G/ b:0¯2їcTmH H{InGUvI`zfBr%Vws?-GxPG˛vG~n3Erjר@uhq8ΩU/\GaukU?7~<ӟ u_gQ +5;{_n~ϼSbz?vϭ?O5?xW%^Gq&\p 3|oKs>|㙯eJ½ޏSq#ׅY;xǵOs~|#尹ܝ&_N8= ^z M֏޺PC;Yib.zVfV+6('Ox 2I6c`̃96eipmEHʩ Qhzt|=FǏhW}1zVuFABQZ 5`޶= `aoiw~vfnJb肷`70r!,j:u?MDR 6)?mؕ?N# I1RP,Xlu j-nrBuOG3M ]> X3 [-$[+hrZeDMst$eE$R\C3=cZYp@YkDg•W t6 Itؗܽ!|5uc_Cׇ7pmH9h>ʈ0st#7{wrmΔb`@ґR; ~FIA ےY+5BO)Mktwi_FuķeÙO?@gE$@Z>LqA" _X0G){K%ۛ'2!pI}JF)߰o%d^:w O#"pBK",׉γN7ȍcQ;v-~F4Q N6ٍQZ$ůdt>]h^/U/OtTTny /TO?PG#RyEeISyBzU8k[ڬ/ 78 v|.s R‹Bvޯol$B+8!l7OPh:dD7O}-cOۢ?ka`?zi75ҦxeW-i/1ߺnF ^[˻?xh?iOP͠?ON?8__d{ w<7M#@^i߈Smp8h vk]Ik:zHxY\Sߩd!&&,&LFBar LdQg[57-sȹ 0+.8-NpV(eq,;|癥[QS!5Ph甩 qc=G.8"osl|xFa\X iF;GrJa4V-ΡSc@yN-f5\ʟ.6n䮺 y]E . $?G3FInц5INCmswGIWlM3s#Rnx6[l?@aҥ0es."!Vx;?&E'US{fy]86 MɏS/$oT~[C(c;Od់_d':L'tg:@"qvC7Fjt69- p*oI&9H|j0rí-GA$ŋ8*P E*]>6Czu4QSeguU<SyT`L퉛:2V8erH[T7=yM#CuWSst-+Df\!,r_jʪ!P|>dʕG/z;,0Bo4e߂V[PN6g镌JH el|zm0/-J\+o<|[U!̢bdT 2gGcr&٩ċyoY_8_GT+{U")V6I6 x97/6OBDJ{RmxAO vM62$;/W޽Ҽ}۱/(4ڀqc׸,\pi1X80 dޫl)wm˭Pm]q:rKAHľ^G3p2A)D8Up.feȈMAyGscXQE Ui\\e`F E9t ս4eB=eb[0I:EO0؞G-/̑g!u=1M8ql4q 7 P&Vn'~ކLo{V%*?P( }K@QRqz y SCp:UEH+) sEek?a,Z ﶯ|[bFïVh23 <@QjRVP1́Bќ)*A\W\q 1Vڧ! q+Dـ\e{%"j[s,̆4ձ,C T\WSM]HZo=-#iqP> Z,kؑmGI]8B.k^=PB' XV,}N1ң>uP# ŅG3ȳ|X:+`Z0+1?'K!C#iE*|\[+Z5]]X|y,yH)תRaŧNɧ~VfB}sSD>Ҟ_d:>ziɋmZOiM_R&S>׵m9=qp}ZͬS]8(*/Y%χq@kgt`+ |i_Έ/'PYKJ3k@^\ `ȸ؞&_'Mɨ3&Y c*ka3:3J&`*0H4V26۱c `eĴә(:jGyF&[mėA0L w|g5GEkFNޡI ث# tÐiHC/۴e oysu @Mi+u8\-2:NƔ _@!_HH04,y]P`Q49[0qz2HtÝ0Q: PG9-"&ԟxot2}B&P^@[ߛtsBǀkCM-3f@zv!mkuN D! ('΂ u\ڸܿYʯC7Jh DFb?kLDfnG.̗-qݡR(B&tX!(1ikv!?UkLsPּkLvG1~R#@єJt 8)2ZKRVZ Qf vݕ{ZĂʿH,8+=ye[ޠ@3w=dQ,!go85hp$.Gb= ty9UɧZ#5/Hv?uw}4l#V/&χ*"##<h!_ڸ~sCɃgG@{ >*O%kqOuo!waEROqyW..(2{ iQV=Y/Y1JG~q&b-Mr ɣySa*Z{P%[T,r}@ʚ_N\h kKY]f́W uK@#v |kG#U[6X;shR$򀺼6BC[_}@`/;e%)Ν`Z?Oi[мT{ y:}r@2ʬ)ڬ1-@萲>>ŬEcwN~\nmMŽ$>S,b]u;=,qlNK"m۩3wzpyׁkn{t G' Nt7#,ly!{j A'RH QUBќBp1D9 "O\i{0h[|* V/ҲoDza V#sCZUWKëӎGm yiT4jvW*QGӖM¿"kx2rU0-SG5/G{>YMWfJ|N}:4+':;sSxOXvҢ)S{:_ŽP68@8fȟ4ӺS!cTH;p+7ꅥc@nQ/*It֖5k@^z j@GsUcdsY65UWVH9bhon9Gc` '=&9"vӜ|f CMTU: &VF;Xz\O`,َM6#Bp< [#rrT:1d}/C[kmvKipm]'@hR"#^Yn@l'G;d<9~Dm:A 4T;b8u(. ɮB,(]F|b ":"ru?e/d<ț}—dtX':!7CiWiGò}csI^P:b":ȴ !Yb{) ƥݼ LmXaQ&Fs/H/Q=68_q((Typ$`JH-͕YǨ[6mg jqu(< PY l[-ŸHu HIv ( H<||QUR2ğ ˎmyn 0HO; 1@9ӹ}uZ%uR:GdA?a\rΜzN i>;\Q ^+R^c0}b/ T^ykXȇ/`O겻F1WKHSFgUPёxEսv<)|W:߶|GV/ȟ~*k|I3Yl gEux^;>l ![K1hUt,ѷNs;}PyqFn8A2iށHS@ Dޠ&#v^CP[MA%E~WTV@=>] fdUS<.@&O/ gwZwh/-9g>Z$4 ȯҀ/9zjHH;9IƓ?4Yԅo遲c>=8QzZ:8;A&-ʁ[$IF9lyV]x-NR&4  9d^jEEӇ*a.i*<]Ž&ϧ:PzOG/]w+GH~7vMt/ O;L :Zy%Wѱ/jt~BtH#[X~ɥ߽ґ*A'Rُ3O>x#S!C( L95S~+9\Α-2?Xt"k.?z 5k@S 8:alM>6Km6f3a,If~1;)lP:[i0 u< q3<d;HlvX@vX#[YˊZ#ֿjo]N#NAy4+4Tm DȀ<@]"9ILk#YD̋\p ]'ElyZpmdsՇ@pTusT^05LE;EѻymOMFéw6taH*E#bʭXZ#ُN2GR8LH "Z-[ICEc/|3aϏG·S&=M{9$$ۋτ~I<򥼅(!}&(ߌq8wG9A-+mJ#aQga>wNWv Oā3uKgLi;QNEQ qYVBp !T%e"Yg̔P d'AÎe@#'L9PDa\={) ҈txGwy0A=G6jdwMGzrȗ|E)#IVg8|墅SW+& KW%_7M=ؐ<OS%od읉eWuoW{VkBHBh !mbhe+N;0NY`@CUuMoW{K-XVz{Ξιo}lH=AiBtff5z.ez͢m&`1jm$N氬JOuu}rp ~Um<ڸ+Q~-kq>w ߓM՗i˶)yo0]7lUгlDfG1ovH\>i=0Kf抁]ߢKP6=r[;>}s<43<'YD]9.}2ԏ^e蛚z -[G D|9" ? Mf%3[ׅR7{dZ#&{%> vY7k2 Mq3 usX7kx(5s)`ʾnA*Hek0RP`]A#ʂ@2e:_dnf?̛7plʸV#Ď<.|Sl4X4.h{d7▂ՠ%=ɶ:m l]vLWkYffZ<+Ft^[}VTOV &#WYLQ__?B)˖ˏ=lx62p9F\57󡥡Xz ]~v'k]F[Vb* dd;Id@3tg'YD .}-xl,NhR,Q+ ҷ̠Cd ʪrIlŀ! ݖN8Aֵ4;AyF.9#'HCA+QըK~a㛍q%6+D@똅ECKʘs5%:'7Wϔұ gG}uӣNPk󉫻RL4tFas]ݪ5 !JO𪮲yR cAtW0R(j2@>C^̌"f~''Q0eZ{ހ{2fJ~]4%eV񋽱/=wYUP])ʫ<{j|`CC]dvaDۯ'm =7AVe{*~CU3-:E=9'aaec9أvBeP(5Urէ!-ZW_kܳ>vi Uonln6=xsTt?:j&sO& uo/o-\kiI4Tn/\u$aeҏ,l\ zoKIq#fԚ.+[#5S59Wrlu!]NaCN`b**#;3&9f1#'NpQ%$Goh!_sDuץn6Dl9 )+/`5E8N)E&eSTTftu78 Dw,9Kp6NPNGW޸J6uwy&cpE=%`fu\hn}6mC>j8gHLWdF!]i]6$l{yywbYV. 1er;=Q{=v[$4$U R-iH{6f@!?BT?hH&3 LNK;3 % dBvDӓ%G{ }";XE?8OWImVe:rdRCׂ2W]ǰFĶ| Ed#C6A"@JǡrGv⽀~.˶LY>`l2 T@v[Qrz|֦!p-ОBzH!#|J\k:h/v;`K\-k%< "7TΗm $pDfH9{٧7ic_X'<|IwtεEVV*D>`Uo xf#uq2Ƶz=Q=ࡊp3+7JF'RIٟGl8#ʾ}iܘ6;LԺ0*>F躵O:Rur/>V׽ yx6c0G6L2vG Rb (p!T@_ۈ$S/Lhv<оTrt#l#tԪ5zdj\`d>' 68'Ejz/ zO8Ysp0CF 򧿨5!/e_vؙw>dHFV'#QHd0% Wp3@e a#m*L7OSӨ }2}zˀ]IH#+lffoiayD>q%a=ƌG[jS庍gP.^T ]zafoi:="|ho7!6 >Ҟ֔X/ն_.6&&bb' ?S&X[ (alm֠M^>dvy}"W ]=Qu`@cknhXy"b/namP$HQ}.[VO]٠@o~$ ,4Oc_7;*?@{es|U 9\|'voT[2BlES&sr:WWئQu}_=*h- rsZ.QRrI`iV[W MܥC2  eX\nȂlKGO.* ̲.Q%ǵ[{NdpB]bTTfFX<# Xo=ǒuk̐?bf$vd X c#nNn_ h6mv.z7ڿ~q)^2`I/f\epS]:_םm,߲-;CI X~26-/=.[`d@s1j[>YK\!nprj#m$mŒ'EXbliu9fD􈾔ݶ2bcސm+\~kq2gRѝ 9wJ NQϥj&"#Jr!R kH( aO()CMu{xN'jѶ 0|ok j}CK0/ С 4clr%gAdKG0*ğnv&FSpSQȐ)uS\誇!Ie'i: h:^kmKM!X͊xRήxeZ6ށ>yȻ@Y@YtmQVnh,-5hGۦ1aVґꂗIrO4+.9hc>`$H4n!U 䗇}[Ǭ  o>n2Ճw=~6-Lif;J9CP)>zzf?b9OE!)vns?,K )/+,Δ Lʦ1`` s 5eq>Asw-r,.Tn}ljȴ)_$ =>q`6+dZpQ~p8e#Zb3 /M4~v( RP.¼r"FgwEЫ?^*fJ\H 1M>Ke Flw3#)k-0{6S&$"$r+_ahR#OGNd@?k'XAM DʴN bg_\AƼ.EXs{ .~9 %}lOQ{1!#;)T4!D `}ۀGEh?+kSՋd#Ğ\?- x /Hh#U^|O:3ay)Xi.{FljTV~#t5;*/Lus;\F&(-w,18?0Z !IQ}=tK`{-!D9n]Al,Gn`Oq}T#/c@v0 ˓%~i3(6Nٱ+ [_T:>* PFdkptV6L cJ|ln%WRF]y>VN*VV_[`ЀuO6(h釆mC#2M/;їQ{T܎xq>b,)j#A}> O"i -GpN>9iGn˦/ս?z  ;̼g[@o! dT}VT#N@0GKF/HJ[~V|^~?exϨ?:8<۹BФO߈.8(?T.ǭ-R 6 Wp<lG@Ee`ZIj[W^<,mD\ʓ>X2#erݔv:CLJwEd~޼,g˩gOI%."zm2XXZ & 10d!l HC]TRyxDVJg%Q+[wAھaPϪ`&¾٭{([fGvŻ—5#<=x(,1=Fϭ~FVkZ#;ߐ8 SO@UHm^A>X\E-[@oz n]1G*M׽nMDN%ERGY-K/H)}lWw)4.#yt,ȵQBVW![ VGl@HV㇗iCesS۟מk^',t-cz]>W d&Tn,R3P@̔ e 6Ԧ=]pqyteĴ_*{@cWg^ch*ʡ ߎA){a3JGk.qjf32Aw }/נe-,#LO&5t "(m-뜕 *t2)cENI]l|@M?*뜍\0g.з[/jm_ &e6V7IS~i >#s^PAnZ-sO'eaKX[`đ#H{dC{h`f',}%\|}r퍛%C/ g}hI!7e x?^=0pxLF Κ_/6l9Eae{".mefulK18 3zwOU,N?z -[@o[@WsKg? O:8n*At^ʐyY ?x̌ f ^?.Kƨh# `WY+LXxqEKdGcijY +S榉 <21(0of^WeZ%Ta^i1"\c^仠".[@oCSh t"%*=,Hǟió1f!dQ5eNXW:9SV7 7寖m/?>). L 8c\\= Lo2Uy-04~!'Ýԁ9ݭ$s7݌|]䭝,gGv_ȁͨ=BKbԟ}TZuSm>?vebc6X P:-1 e} 3LBIYAhU/KѶyɜɬA| z02.9;1}֮`Q E6Qڋ\oE@&eޣ'O/ֽlRۥkۙ3",5ȕb>1!s5C"2Pڲ;4 >4|NьBtINK&\ CO;H'gysp6SCƑTtCglmk#4RPb^~.\cc7Go8r~uZN*,,>ޓ7V =[@oz x΃.>ƈ_1Bk4ؖ -ݑj|ޑ[}|. #s!~ òGlw(&Ln xV4uZ(< s8_j>0C'džgǯom\>j@9k?mp Ǥ뫮#qd]9 GZ0Z),ʯK89ۢ#vD㰟ajj%#bNL @dT=>X2@x431SHV~B\3T Xŗqπn޹VVRFGn %ԕMUW>9j3ݿ~x,jx3xCQO9Hʋ#łk9JϳGz<,j2u3-уU.OGn:fa:ӥN`8zJOCu͜`&|"#tU>ʩM ݢk2<! ͖HG{d$rD^QgVrMt ُ3; ?;W^F#yD_~jq:p~A4։dsDGEoՖ]oόjGOOY{s{B[^aک{ky*GlC$m/{'ɄE_xN@SYlS(lKQdбy=@B*zdv*||3¯X"md7 -_6r_u߄m( z4дZճ4(j~{ ES9:Ty/}Ϛ_~-yxė{ƏZ-s:~'yG͟Dޮ{LFwwwg-[;oVwṂK ˡ({ؾy9キ`VzӸ;z9Ĥ>dy2l,n <d2.0wA5Aa@9E]pOwQ_fTf.&Mi;*nVh'z-8TlB!-< j;ǽO6C;Zi:#v hFFuE]W&Hd 2 .=|7miL \k3qa=|ؑv vŝF`Egb⏋-e!PNF4R/).u- 缡Ƿ~fsĺoӍdҾU?[]bksgd%ౘuh(uS>S msQW؋:`H{Znj7Ar+w;S1J_@5'{mE&UveŴ* bpH5`cs4LVW:[3J|d?Pi[ET̅fGoO|ԅ{7I؎CimXH80tn|w݀ _j o9`e5RE&|wsFpmWB_Yt5lЇv<oڵGmb(fisagY+>H\L}cqh;zʞWVnm sma`'wXXhY'“>=qM\M1hf;z+폛~]Hlh}i% $HG[Q#m6[0Z푧;-PFVȢI /ʰm9nf>X]O9paH>%>̼)،>g}>he0HMR糇<+kȃW贲K_yLvypYg4ZqH7u2R.^?൸6m!@;nmiCS4'No[3 O AZm%ˏʂ a5)7?W'?O8 ]~b >`I;_xfg,:A:NM@FsM]E/=},y @3#i'1Ǩ mC}i}.h;枰ylgCÝdX>ʋJ#]l_xb{qFY3آ4[j$YӬHOUk @`<7D-w$Etjd[-rS 8N;g~7:1|ԁt[8OkBHܳn^xy9Mͭc$w5˯4OK?'>|[0p\|%`U_yFZG|;̾'ͣ>ƃz#0kz'5o ;;Ï6<P*r_$򰹓|?mlxk_7鹅 {. ءց/uuTF=e]82; dg h)²ѱp'CY^h{"JgsMzNWz.a_ss9 ,[ " eaOQ'fo{LyїS {O8%t s]7=21B)'W]C,ҨA8mAu>2t9KRK; v A<MkFD;5ޥ* İ] {hM:7A Yx(!  5|#;f͘Q;iŝ;.6w`ǬJﯾEݝL``;1pY[m]FmӽNfm}o)-[@oxswFN̸٧^0 !n呧Rq ֩YiaeD G#ϟ=ࡊiRo2luρHF?N _o ~@FkmSg2~Ȩs7eliKd:etxmApWp\WC1/b ;-Tnq9!5ii\Wdd P rZ .>hXٮ|1[z̯ 7'5&Dq -X̸WGZQsPbqж.]9DňaE㝗 O#)GZ2KZ~m|<<7;L8B !הÆZ3iܦХ2K\% '"UO;30A-7|F>m\gh?h匨 5O}Z0! 62<;b}5G;_܇]< A~%4`LzGm^~>Dķ+!]O}cDO2jvz?c3?F0Ĭǟ|2Vw.أ8*[܇z xZ@huN@ OP osu"`ŀx@mR;Di:qt' , uqjF.̔ g;rKptM+ [҉lѧ* ktymo4jGc1=Rve9^ 1"u/\_-!py2φg %/n._ϐcC;R ̜"wm >PNp̅ dgs@aT۳M@0ݗcP϶Cod_} 1Mr-˜Y `F @Ã"g )ϔ`U6ʔ F"B 29(%%GyT05F!<YߠW9"i##LWr j>d:X [ tH9o3b r Iu b(s^ϊЗS$7Gib_I(hzs:~rS]x9C={ SlỶO /qgmdkHH[؇ xcGa#]})O;v1V&97~&e'GeT} ^%n{ͻzآ72~5&`Yi+.c,X @1I{8K~"w_)LIZe4Yk{hfѻo?MRn4[#~{ia]T^l,+ZufuM1!:ʘq|y1Aux;=LP}Uꮮd^w:ގR;VphS/Ly@3rz xXuǦ^w=,hhdlFw`1^1~hb֬G%"ë*΄(YAsWHz/ 99,M`@q]_~^{ڴyk(Ph܊ś؅~3l6Qlt058]!Q@5 7;"oZ>u=|BzvX26/@+hEN0a㌲N]37HCfa_ˎ4r;x ` nhP]`LI]?''\z4Ho[iʝAΏlG6t+8`T~;Cԗ3`+[blUHQa1Z>/((TK6wr5=j[˘SC|0̸0[@ݽ)D$"f3)Rj1 2Lt MSH FvDwxrz:rPL;yydPM6|*y>۩)§gR΂O`dՔ9 P<5;Of̱%"S0(l8׹q=Gn,{g=mYLlJFeSF0|Gl>;.HWZdeҜý`[u 8CH+n`ޓ q ݟ׻Lq#L}h[f ݄#߅+׻-Π!tl9endovʾ]J!9?R9IS[+l'YWZ xUpdG5X'3%Xdy9c-9=zNkw„4y;×<G!Al}35{ 0S쐐`SY_:Op9mCcG}k-_w3lA[U~2?ZtY̻QV[>aK%#lfj8OqgpVfc8o6 ̑\A- 3mol:)G.Kr.EHF7,hP @[PE$&ooA+'ua)GqN3 oi#" vÞZ#frU^')IFiVK i`lR&>`6ZxJ5Xl}gtQyh:qxYh2)FnZ.&]_y-|};e;ϗh;xaAsAw;#vlٴdw=rp Cu}2yofLlYd@؅b}˧@)^kN!\C"\AJVx^g?f`Ϝic6R6^\vpTV)]oo{ Ľq=57wOm~Pګ/{kMQY]eGz@>[7xpE?^凞5͛Z#ߗ?VR>Gݶ>:pZAw0=5scCٮB-[cO#\b: . Ͻt@̿kF<|/ی z&M*2sa>mň)֑z}>i3 !>SH33b_|52z޹C_@<3:,5s᪻ `we6'S uw[Gth6Q&f/p`NGI2 8sK{s|:MKr`N,55!WT˺@lO|[vkd"^\#^ph"?' B|?tgGfoqS_e(K.LxeGLZaqa4P-쭨eVFmCβ=Eq\nJ;!yr HqHwpP:YHLЃo׶:Y>kT6"帮ݣ󼭭'䓖+d0W>Hկ>^~LN0+gyޕSz^~<7zYV]Չ@s%}gD8jQ޸\ع <}Wz`'!m[m|hFxՠ>C?gyzr~Z9"Ȕ@om!?Uԧy"y _|,;?W^i'_j>kS7ӿKͳٛb1x;.x+WTs^yŬg z -@|$xU-V}ZGgyqgnǿK` +s Qdj4SwRbq~c3;dơ;u' gDVר!ViǤ"S7A||! )6H^6]u 8w㵅g8'{rͅ|V@%2^#L] @/f(S@me4SGmkiҞ 8^=' UK dQEh)d,1S?i VIC;bc_l?ej]Wո~xR<](,&`]O{s|tA-;>9l4yF$CmcNZiZ0D:.y݅-{L h~AFn^dCm82PBkv,h-`BbIJsO.$m -@kɺw~6`"7[!s5j+Ф! Pz['i#"#6`.;=E/Xdĕ!B|NKN#D]"DGuln>$(z7I8-.ԩMV0;(Kunv%8[~Xp>%j ᨽdGoo rnikwV|r5矛 YyQ{,1ߴ2S?7L-tm[Q}B+2$lm$-9=gߊVS&AyF lENȘmkTԕDe}@4{cgMroϩ(Sf6hRHo˪n|Ro_0ƿh|ٶ +W悶t~k/mjĹ'~/P s8'ȯPO~ L1CO~Dד|9[z_eZ>̡4/Bs}GnA|iEq'^q?&pוE <{Goz ,ltQdH=볽A%Gsw#.Rw^WgHW>X},\zou6oT u(RAu<\4,|69; M<!679 KY! _@<jb|!Y(Ng,2H1%`y8k_Hg'MEF44B>' 7 o X˹g<ڱZwc[[7ʸA!V10QٷlQ AC"s=eRnFL= x8͕*8 ^,q10㴊 5dE)y|?Ks]ɚXy`w" M֒~#BJsWWN9C%]enT {IԞш)VoBٵR;xDgA:'lca@;=i2=68ZJ Џ@Ae:vG ʪ;qn}KE2Ď.^0w31`|lT`.z'z%NC 6r';ښQH =i=tJ uFy*DޘߔzW??|q ?!!zx5 zzyu*{?7ѺFsDweɝ,=`bN4nGk'|'#wݻD Jz xZc`@ؽAѧ4ꇳ+z+\8Y*s0,Vkٝ4k/ng40@T縳׌{0uTTW(ˋsRΔ:GfR pQors=+uv8L0"n69d@r 5/06 !#ʈs@ mZEY[;dN.'`Jq)9(1$ZT [ 򯏉 .,k EzLw\sJ{!9#CZb3{{GL5MIv^j.߽\{ݿA7Hme3n8ː0JBY}[@ڢchW s=A=rtPk Q C @j؛4 _glM0@VH7wNu4^rJC:[A7]@o_l|2; ЉXA~aH[שAS9bt`ZFOA/]y y <63XAqu{J:6nʧO;:ő뜷}:YA2q޵ L7B t5vu iFA!(Џ{i4!(VZ_qSw [kNA[+p9~%g;jm[_ʚTO:u|kBN 8LqZ5|aztT/>3 [d2 ?pm>TEgfDdžj[mďj8rw$>Q>ۓ†) j_llЂA9$hH׀eoP9L Q^?LqwypBx2_!|i]$B2WEe^HrO5iAr(JQʜW:ʨ9*]eeQ PeێgՆt7iTHIώ0u1>-u8Ƨ,AVPMY x#UJV IDATZ\pi7gxžԫ€ j_:x? =%i) GjUYngs6r+}h$e=h]؞ԚƠ|F6r,R4ߨ;[+4#I6OaQ6y8yӦYBml90;=܍iД~ݱy9ܽڗ\1%V#6~=ZH!)32eG)v,gKI7e~f^_~]}=. [@ow;Op+l.^Wӏh};W+)]"fT5}Ӳu5.x'+.S}_ ߃la+,8h=DPHݩ~.6-Ծ1tZKuf}Cd 5/d՚\& li/9 1_b5hh,wEIXŮH.|[[?W AZ2m@.\#?Gp B H=Eܪ΀F%ѡkiM+&r<= \ƒ%&`#R@`Ѕ]ams| 'cʵ֙I@)ώY` |>Lj|!`l#-;=l!dG0ӄҔ%HA# oWn*{_Qٟe0^P:Avjidn;]=Ol+s=0_`rzH:-%G# MŐBCG1;^jΈ J52n&ip-ynR \`u&;L}6|otb:^4;6js ^vLJJU#gtS>+pl~Q XEuҞsdlZYN=}ȓeEt|WS'RD~iNV 9? omk:sT!*ʒ5;-Qg֖ژ6򑾕6٥B[Lc6֭m;~=~KC;4˶ W*}ç~2lA Ӷ]̗nUQtvLz'nZ u3wVHӾk߀|E|Zf]O*5EmgLūb R:A6Pnq#76$ku rV2_1:8*Wx ڤ%GݱaA'ʦ 6/$01Eime ![6| .@5E_GYJ/{CsI8hhW&jJ;AQGW"7|N$\y g`y a4b@13vP(wdeT_!]ϋYh7'$ ٕ#r <,By•ޑLE`0۩+ٯA| b] ||Aď7~N ǦO=F*YO~0~4'2s-DAq mˆg h@I x)De/d6cEq 屻Gur2-6,I+ -g qnΪ*E9²{L贴SbP5Q@S%5Gtt Rn6e)>kG+} _5`2A+y޺ܹ; ]( )_~lz؈e)?Ҥ}cm9h˶ib﬏z I, hQu  ;3k0}\ 5O>|􁵤ǹtmo$P\\A)܎b\UB!Վ`b \)R6G!Y"O\9d&UCrjHw1ڗU} R!mu>tR.'B|"?t .2(Ō?Ly,\ -jv1aK4T dZ3+૞bE/F*K 1gyZGbVkT Z[OP\О׶̒MR@ϙy{MSP H7}?S5|<ۧB!aA%@Ʀ9LY +32 NJtI}:` w=ö׆g3RW~UE3i<2[O"-$ہo!|AD[vV'9:TF* p(p©@&zv,<17C WPT Ea @ Z@-eQyolYMQ&`#bj&N]-ATzUrwa`/0A Yk!T `Pbuh+G` ,j+zҶCZ+FwB9A:A礏e--'ˀ,G#vmA߽#$mQ孻`]cZ/y!ah ![+y"a= dաcM:f^?Eҏ>Ǘ訍`JDoM2ɜuz|XAn<pPyc!~D%-[]>iEٟ9wn4'5}@;n}}Mq0r튥Իu@,؜"[nf}"N;fMvIa;&DϨ@o?LiFpE=HU6FQR;^8h LdrUsE`Q Sa6Nfl|3 8p f ldVP"{ZGŠ1@@>F5tk#) Yz'=9-+V Teg D"Qo"G]Q:CGQ>*yC)_4}K'›[_ڎw@ߌ8Ŷs"+x *9oѵKڋ24 c6rNv:¢S685ԥ`! 8b~)A oow?dOFsڵC||z -bP>S M{|A2#I't* : zs1U0p$}̀W}_Q\9 f94:*zH A>O+x-Pzh(_;b*WX _v нerRva5 ,X8b,0@ L04¹l *)C yñ0H@bٌMǧ T/b-?t#ѽ%h򒘦@f崾_@L֭FSB3iayʒ {@~ޒd€#v2c4.<8~s͝1} 4 0㥯7^lc# Fe!`V@Uw//'I}#OW98M }7KhcY=lYH6Y# ]mpJj?(ŵEu H SoO xQ>/{odu@7$6 >Q#Ox/[HWF]{{UVW7zyջ9y2/yˑ=Nrk[( Ql Bw=ʠUw H%x¬6)0lb9n(/"-_r9 VQiyu׻ݯ{[> M"弿j&I#c95rBtUh G՟u5|UԵ.l$$n`rr@M]|=|6\)YF ~!y{_ Io?@" . GGeX7ą(>P-7$F'u[ YVތlMpemcWT8,DG+8(=mbvLנ3o@UOȈ>v)S߀O<Jqۥ*:lz`ya"묒fkyvB\A[{i^I&Ah7UPZ=޼f66oXhm%({UK>QW$##.;n^8;Vi'S6N5w7 w۠֗ 1@˖+blT\};JΟgx3 XZ)X pk'iQ>bLUڡst]}c`:%BN!`2!Gƅs١|3m{39}d?>)b56$ n-ܻN5g0ĞCcgMn+>Dn\;>v rMT;ROж/5L [Y@'pBAaWA#A {?ܝ_:&d k\cdJ9I9GYaW j,Gv5LE1:3;\ok36&zؓNeqCImuc8Hi+7D"m/dzJ" ˜}b! )"ͫGّKJJR{%Y|N:rEd(y 0}5# P]}ڋT7E{[ͅ8кrstyhghSdGTŰJǎXWɘYɧHBQκ yc&"Ҟ!h-P]m1Gw1^hp%kFۓд4fkCs>ߠ%4kd<``ɻ2KN z ZN^o #}!C>[n>e]53Ȇyt'?/@Oi2f}۬1u&:B.n( bԏ o˖bmj <fyE#b)gw\F]LϑΓԟG:GZ'7؞`y__8E@ 4]$W+vQ_ŷ\++=ӎU;QOE )ֺJхVdz3_hSڽ3g<\VH9>sD)Y02 @!dʎX^gV'x2yE\HJ0$.msFkEO[1z`3( 2‹LPNq4$C፾&cCj&f<&=z0֩-{~ϫlv$ni>I4je aA"nzoB#c9 ȥ8*9tX[B_TǶOlyO=f hsBMUj =5C+S]MP 74紣1؞7"ԜLAҙk?6_AZ#g- 6>dpOڊ WiU!n\Mہ-(Y(`FO+]P[]7:҆}~m !cvWQ{y>`dd4GJAVZ9X+'eF8'ر|&Y-=&CB9Ë5e쌐W: ּ"dO>-YQ{"%E@ 40@ 4pt#N_bz:[.N&{nXnV] /&0"X1@IXp49SǨ: |->Y|pe V ߀u3 t $A0j0Iij,I2{ElJfxוϵƝaznJ@!-Ȼʵ@}VEa%KIlCSRVzaOH# ̶1+V6xB}t2;!##?t\4<`:E9<'luTniOF1D"+5᳍:o5FY;Q:ё bVjI9:yaG'vq 07Ƒat |:CK5 m@t|m_QҫDB&l ~h;ΕJx}(r[);oܜ[Ftu}y>d]Q_ IDATtf/BabUZ\[揋>m͢!dJ7>y( OڕGs-&Ǩc1``g~^G%WW\/>UGhjV@ 40@ 4}zkPDZ$jkL Qy5"CJYRMAZ]ҏ5rؖm]EY-ԣNDF K݌[W]`&3cڌk6 s=;Yzh$l%;9Y.NmZ< -ԝ=9m"d73JG҈Z+[?9`h`h`i`D]7o(tHBy׼" ueNAXI'Wn7D9SS |JlQ;tS{`&S6`2k YuM}^70@_漳_J8'mǸnx_ZQƛ; Ō#w_p@0 u$k nf^+hNK{"_ëm~-|WXXK(Al?yB.~#5hE4 7*P_>0D(΋̵(wyDIzHEUDAa:!7+s%KS,4ӷm<1uQIA4e乚)+QN mhPwQ>JnZ C-]0ZTK?BQ{s1E'fCʖ>,ĪgV2z|i>b%ty.Bygh`E?CP"\7lAErEsN(+j 7_0nj~ Sez/d< /u2P-Սk+ZQ}0/9 Q|?}gHu}ο }g{''Oj=>u{8O'\ljK{c<`MϹ_ncNEɌ}ȯnȩLzKʋm.@^gs\rڢӑ7b)sK&H_Bl&  %%u_<|=$IG x#1ͫCψgo@z@'o[EgjBc8^G%EfWëzDP.qugFN1d{d^!ag.c)$c@<-Ƿ|@!j9O]k~ H4ɱzGCw:~KD(#X2i[QGLӿ|6jK9$RbsӘƮm3fۆHyFF/ `ڛ"ܢ.aj-wHdJN Oթ[=cwɒu#mCC$ѩL#}ҟm)zM,m<_j7e2O˾Ol==j&LEۏ WFFU4L 4x@ 40@ 4p/NJ߇?l+m.{fƛ3x?r]\m>N]O @̅u2mW׵LV]X/>$>+٦>seb G w ؖ/?rc)Ŷ'/]pb+1!Y l p49`Nf1@':Zs3M=TvGT.udz D8E0-8[bq7.>nFڋSF٤#y.o0Qgp rOM; @7\r1Ptumpl)2!F+8/7 @ky2Kԫs'`G0še;u%݉qmǫ i,Pw{o@GD+Eё嵟@/7@y:A= 膧8﹪o}ohv[hoyDnҞڈJ|P/4=/.@lZr2ۡqiLVWlbD0S@1S{%Qy=q?|8jujn;*G!֩fx VxbO5qzMrSa(5FNQ',eMBЦ[fG'vө5c}h mkIG00VH_N)r|:NM49h״ :4026Euۅk*PA jy^Z #;njfU( ~juJC77ںk5@]ANۖtz_i(huM{7 7 "Y=uycm6/6lC$}ڈ[=Eʠ4R)A tAFKQi>TE^> oK@zkgGPovl1 4pjh ,`#C(.TG}]B >:N/y>Oaɛ@ 40@ 4p3o,ܼwl^ Oȸ> /ˤeV# ]\F9&ݟ'[7.0"uhJȗϺ^ XE Oޜ8-4 h>d]$2P@K`,x[_Ffc\vJ !}D6kߔT1m\#deZw|Xg] 2d^7d̎^x`?pm@q`>BҮA-Fc7Fꉝԇ~0 Akzs)܆( FIQ^|Rfʆ9Cҵ_\ B*n5AX^l1*߶ !gC7 ĵ(ݛCT neųGj($rcڪ Mf 'F =3-Vxroȟ T.lr(ExG^I֠K+yꂒ`E>FYmc!sä1J,UzQը9% cEj ) au$ \s-?<ʫ e @^F4 ю")CN^'Du|ۀ0z( LYlj,vzm+վ wC픃oS N~rJ҈פ'?s^kO[Lc[ul+뾪O]hr5 t5ZmG#;#+Da0殟|~ŽRs/ pKi[-a!\:< gEES'$ǥ; n>v.pڕvN}yOq6bs,"諕vX)&P:E0LcG]D$:]fu~2'ĖzYil) MNWЕK֡lOs Єh`h`K놝ft~QO(ǂG{ny]$@~T-(pz\Y_Gk60#Ŀ 5pRLç (o| R'zҪ ~"ۙ9pJv~+ܻ!Ko V%F  :Y֏\^F`E`(F1M"i(9|n٥ʙi=u K M- iWw\7"-GcC֡?|}0}*47F0+?5A[z[jmCLWe(}S2_GFOKi S|8hT^ʊQ\T#̽|Y.7>=A6=49N Y?n046sdTt`93s%\0ڨVU.425uǺffL1쎬@`+}`*d1t `r[e-j]-T8̓<4C QECV7[_T,w#Y;:WcA}y3cض4KmlbᕛXƧa$hrHem 1ENm w95%.0" x6^ӆ,u#s}tbqqZY2u!41} $o-7m䋞CvӦQʝ`*b?7F[FM6k :6/]6ώv |#_rT}wQ/t~ p1"^$lI!4 "6׭HJric_ʝv+D(Yi78c}c$ mS`A36Hyio`hN7p.m@ 40@ HM,2{9@R`@w,(|ei˘x/ ipzCV3Gl]]M3kXt|i$!#ږ|bKסYyyXOZ4jʸMJWAs9/uY/0qNϚ g:pZ)'N8Wem/4%]$P A3eBgӀ r{݀KVRcrW{DuB.l;_ϠE#!AzQO7+z}|鷿h/"©Ed.I/iSm7LCUm@[ >#YN6˼ЀS#&aq-` dUp&t}{\Yd&|$kpkY46C2G?fSVX~DR rNiW5cA o2S[ Ǿ W`-V1%vbz sF5> NPdSKp0,EVASdКJH2.%\ `) =`r}ycLY9sd[413,W =xG]a“(,#}q[x'S<4>$|eEGOŢI:?DzVy>un#)1믰= 4/Wdfxi +юR8RoW][>@yH&4 bF̡g{l{jΞxc ;=ڹm P1Tennt.x|`ɷ}~7):3\dVVIՍ*|x5C&ȃ@an9h;|֥\7_>l/}["7?mzg\s<<3{キ{.V[h#;/z8fů[n̊כ}(]eN?<ϛO~ы.E 'Y͑nʶuƅWk?^|#S?i\^Ynyĉ6O4ؼ3|ޮg~y_ͭr'Wpy-y5=ΖvJwPnkU8z/ljUyȑ@A4yZU98s,JWJHj;go]AYs } Z\ŽnuD z$5oefRuajqi|b/8}Sl {eE6ێ74`]#ť +NЏ񼒐!˻Vot|e:# b;\{udRN;Hu\Y]W`'Y|vAz+#=4}q`@} ^@s2[ ڡKQn菛V[sPӜ-=`~cu vsx ?ʢ bX \P}}{,xŏ n#`Hx14#QB7@HZݙ~uP: ৴6E $<97y2mˋSw0τg15;6ՕrQ%OcӖmZ[6k5FoDŀB! *2tV @lDN-gG丮IEPe\+ gbTk0m3Z(9^(u|dڵn'ruc=uT:KGȺ ~5@m8Om;@] ڶ~xW9E X4m#uBߵjSu]jzZ)yuF'g"t3{pTRjFo1fmdQxeQ'׎ 1̿mYkɑ|Krú蹲]?uu;—]9ZI@osMNyǽK>6ǘ8<B co(/P<\H=%\IÛu1tZt+M`WFJD]z>l+;}˙<-O9 @dNQgp10b|чCСLG.:nBW-)Z>kB(n2W?z;F 8;lMZπ;1 4p-j >o 26GܓZ,~M w% 2'p߹.K' D@H~eA ) 8?z 񇏵8{• *?, tPM]k|&֚J -}/@m|sj["V# :2*>ɢ}Ё^\hN%W-,!b)4 "#ߴlY)U|L}t^$`DR8K)u\zUqq@oQF0ʋ#4դL׷e:@ݑi'}mTû:gy'H.(Sx0``Shy:F:ƨoPXv@5H |̰(|@dAAyh1(nD(2|çzԟn!O`ǾTJ hBOrA\"j T54WPG=u.Ev a_'hNEtb(SNLGyli=#8{dxջYU#lfG9:ek Aau#M#*?%le4 !ER][1Ԓ1WY%5<gצȊ֔W֝D*֑ۃn;'?r&~?JVi>(Sdž7dqfAank4N/(iX\r ଓoLF/ ?-XF'I9yS|󃣾zh#7zL!.Nj۾<Х Ko'}j=S1tIkb=r؎tǵz#vBS^r F936um_S~?_} Fwo8ty_C=/#~w>[殻 @r'@y,`p@k=L@w>_2}( `cB@"|فIl'K?l>YÇc h8:mnfL|n.'Q~h^Bʃ^RCeu18E|{_ǎN7 Qlݔ[ok~^@O@|C_wGw ?Of:/ӫ:xȑؼ@+N}<9 noǖ{ߧOp3AGE/b씇fqt8qD+` H3=/YFڹߑytG_Lm9 &m zd3X?u*Tf_iӸϲhUp~6,8BF/ Ȫ.H'x~ʾag0)|YQٓ!> wdlU7zqۥ^%)稛 *D{PN,>΢'=5i))kH0:ܦ j{2O9PxSjmH~ .صN;0Li d%Ky)5gA,muq%䴖 е1r)yOөhXFyJ% uW@NhDZwzܼ̆MT:<6\C+%306JV jW,^/h.䓏rl`<.oN'|_<}"15 p'kNM1MĻ׎d-?cFJ4;ۿ]Srz;v-{/ ]JvyV>a^[3Af]mG]ݶiTj{F1ts:@m>}ŶG>,2yqΙɏLF +m?y՗/W3CC:t#WP이\N u]Nzey{pm. {`nvK)7x3#\g% mU׎J;=Zp(X㮻_7hZ#Vmp[y8#e {Kw5*OSg%G~gϵ?P <N_g㼺-́ʀz V]tg}{3-`,dڲ J1y|C-hh#\?yl,` J:.W~xs( sY'U)w}K瘶VGQt;oxOdյ'Jm_'>7}gd?/x/wKVee7-oOV(S ?Q y3N 8EJj X3W>o "9壞o6i[98~g LC3E?}cm f!7Dq-0J\\DJ Q:YZ_;(]w_T e0`.ԴPGFy}BDi_@i9kC!e`nx@ȍZ{{ꔫ6S}m >n\jkkw]ө߂NtKձ26-SҧL*m%3hc{DbkFt48im,( ;wZWҮʐwu2m1Q{o:w2e^˛HuA.:Vi~D.l`8|..6pGw.4 w/7铌s6 cR ne5aCҌ=cqc߮Զ‚v#)nf$.Fsmg>~^b;rzlj@S`cwvN亘><ɲ´_^_֠h-E5S&s ogȃ b9|tצ ٦ς?cۖWluN:}Q \Hڶ~#GN:eUij)~;jΧzFz+g_OG ߻wWA=srnUOw\uDs |ey KxC p:L940t,}ai3.]NW}m-.\\bơ`keي:+{&)Mt~(Ò>멒ݔXvPG IK7X^h}8דƹ)#ڇ e''5kdt<7ڦ-ȍ$,SqS_MC;❕:ަFlB;8􁯌~#G]؛Q`H],}ISkx{Qդ[A!Nd.mdURmʹ6PY/."x}W+\N`/*mJطddtN^v(_aIGAwMcgDr{zy YtG7ca,6 +.۞^m=Wŧ{z.Fc޽w9@r=42{6.F~%sk=nc;u1˲#/BB9/R$G1eWu]~>|/x=@\]b/:dݶ$ys_ܺnP@q!/]@ע1WwשhYusRG k?@4k]؍H<;.s5QqF)5M}7#s~Zge5G-s@>9o82O7@m0x"~&]T9ċ >͂i5޵}~̎{]0 QJ4MY rя6tv%))4 5{9 5ֳ{Լ\~ b \˵Qv'|5<֠#+,@EKÀ 2Pñ.:ooET#5}./̗i֛ڜ3Ym>Y7޶fk2urvy$bls\"wsTʔ)4.%C[jS2n|KҼAX!J98pt#*URaK6چǶdENy\,sQ>`/[UvˈTEی:, Γ`dwa_gO~q8Pg \lW߂ݿV8|^\Mk- mc^ ޮllum CIx0E0CFωz;w,Ï$XZ69uM.?= }>|0[o,R%q4}*x3+~?Rsw 6p_'ÀahL𛶋 ;CFyxZWY5>>3F7a_G&p>$9 _1eZ_S@tX>' [1{lM';s2_IN*x, g 7b*qG~ѧߜ3 36|D[* }TUő@;T>ENRnw j7<ɚZR├@w´؃җ#4}d'sk..)LW>zЏɷB:ꆩNhzFE:`|hfDPs٘ٳ6ѷJ8aS6G4 $KC,=>B̽%lmhe3q{O9t6^ t>?oaa-`ifmf? ~%XU|rT7dXesnDG┷CmKP6M[7;E DGLNpy>$ (WeqKt9;Je/c\;Q-zB6%)뼲M&+j`GoMݕGN6o>?}_ko&lu S¶i9~Њ)J;}jnjn[>Anl F&X5AUoD&u+ a7Y_9K:4Am@ @ȝgS/{hg.i*;BbhĶZtė?(ƒ ;[ jH;=Hmd KƧ2}c(ڠSAMOS;&J.N 8k_KRN'?/|o| ;}4/>?(x~//˛ ٧.w&v9밻J"K* N2 K/aۃ ]J9{Zt;io]Fg72;@FWn/y %h*4=K@c>߆W~.]JvKɏ֓_aܮ?؆s/̄Om5Vt}~YGg1G|nE YeN(x{oSKn[oܣlkGx;wƮ/'xdى۹~ !7[R{c{_[}&`H Ŗt6̹/]N \o{5k`?nkUעNmH!7GIwx~ k>- x\6@F/9r}#o>Ag0 ? e=ٵ{2{O3L%Yв"8y5e3cj X}0@.~_rZ(8X2[N?+ 9'N7}@3>/-&<.4\9EBW9(Yɩ83,lA8hN V)ˀ7.bE~堭s]9\Ref7tT_mr\i1Fw[U3x^5mX.؏kІ-oe8~$}NE?\?~ v7)S,_T^Fmb_=ߢ@KB L|GeF0+uN8 zhw_Uxewiryxom8C)n()\ o8,nk?%@!Ih[ *{s;QKGDFc?Ў\ BN8m˜ JG0Նy|ЎPY eQ<& tB3dcnZB tՉktLDxՐeQc]'I rMt?, K!³@S/m١_A1Lթe8s]<=jn趮: ^ZJÄR.XTc\<}g?S.uyu[nr8.m S z◜Lo.v8?S/-AtM2` GKie(BOfvo U t7 t[-C=A.XFa5KY?!!xOP&E\-|yz~VfU|;'JeMG;q{vpv1|s{/vs;d{ 6@};`emh; (ikmn#7^tOF_nG3Jm݀Lt~EOtE!8_*(W7blLY hL3,OҦX#a|#~7aC'X=_fmaօŭ(C@Gp ?ܶl_D^_lfRTϥ?(fh>6 Y$w=8%דH 8CSV)2bi VO,Ј7qjz- )l42Gt&`$r&ԉ)7 bylϥvd+ݾWeO:^Td]-yuDY^QVUiN*,2\uP?G_^6#W &mT{tLoCSvdv/_"7ȓGA:QУFsVۜl$Սkn}qSɳي<, P)4Pk KQq||7uhwFr}Uw32SgQEP;&Oދ6[avl Y,i9P3c 參z.h~͚QJt$ u'IAnzR"%{dp 7>#=ꌨeUZ@aݪLqXe]1oLYW}Tėůۓ q2 J䘮g-!k#щH4ͱї3 }9F3J5^V8eFޭ-a3`rB#fZfA 9c.qnmwX_^PD.Y۴Agv Vf [ulMai8KUևv[L/WM1cI4 d %T.(0Ҋ f&bۿ`\ਭ@#ʚsiңSaF(P\`TL;lGG\A%,$ ӥ^!F]P0hj6ըS UJ~Vi /;r\uΰsXƋ7]D[Ikn7,mtn7aL(c :~Tt? &ȏ|v)AcWXPJbDlϹۨTӿӛhۖQ{CUCȈlL& wJ'yFOT! N |pӮMY[I9:^V?jڠ _>В]p!E,iNփf F4̴ADhʉ c[U93q*e M=⪅wG]~ݺs_e晤w#}~so?Ł#0:b f!3m:+!|>}1f|7ʹVF.mJf$Ʒu]PH#HZGOwÿlZ?ץlO  ,Sq- IDATNO Lh_QrB ן7`3`WȭyM{c'@+yyAcF{>E.pTMv] ooy.$x&0*xw[m_83/Lpn})m ye+m΄udM`br \JFjzCI %`4-O|w@; RRJx}YEa\>7\ yw>ﳇZ{߽^k=sN%wLSiaOl@h$;z(=fFt}_i ڭέֽ=s ZLZ:CkD;ublj#tsJwz!A[3X]с\p)%f7n/Y' Ykd#)b!?Cf@|d'U}3+3brZA5)OAכhZs7X`ۚ %=鄻#D U^kڒNT oJ}ro]16W^˃֋}srp(Wz^{VG6w9I]:,{(qoq֘'_k>,}2xG^{phXY:+Q0_z^߸_I5Y`m0}f.͎O?~y͵lIlp옫fT2ml#ՀAEՕg"33]Ȁ|yݻn 0&2#6>n%8 |o|d|74{:&^imhV{tBGB^3o>zL,k( 3z+I 0BEMV%ƿ|z70z(]}fIJ6]$׾ G!3^OL!Ԇwor3K4jyvzB>_9$` WMicalͪ qwړv{>̑~)"npģ%d OW"8!zZ~O'ߛNu[awx"xgcؘ9EHȜ'&;pÑ~V (Sە/Mdk䠢hK99a2в(s*Arbo/O{FQ9k}fVUze'xKxQnxKc%-F֬e! =T)~R`7y򻙂һC4O@ox6(v>ͬ|yCnќ;3+?+>nk;0:hf- Sd 6 Sӎ޽$3`'Oj-4q2,lEM(T M$txEN.!"AZˎ4(o{:P[À/GM+X9)Lm&l|imTS')2Jj2rTP[:t&h=h6t=_;F^.Z+;P@,= {ʞ 8L?tfUOx.cRm0 \䤲Oap5K2*ic@ ̋{ˣ3f?h>9Fv}_y@㹔.NۻyEşUx#|N瞣 k5"Z)PVt>VC>^{ 5^{ 5M˽3;~{߬%}y7q3:k7(p5;92v4̲AxlH!A`ܥLǦjP/ϯ6?il{Ĝz"rfxgV"$tϒj_>xrx\!֘ǯ k?jhǽ_Pִʓ&KٜGss !_U/f,TQ F * oEk6V|p  Sqg;gPg09Aze7LEdlceP YZV0sA?(_y7{|Cxu:i߮Ǹk[Ri=ЯmJ9mĈ-Mpн#t?ijGm:j̲:M>凕׷lΡ5gmcȣRI@S1ۀ:kSCc \ځOA ̴s ýK][u;E` 8-& @;yޏltGnPA !-򡴵rC{ Fi[GCc@N}A82mutTIIkWp!(DjȷH޷z[2gOis.N/袿PӒ%Im明<6qΩt7:B?'ߎqm{ /B{|7̘Cd3WLkd6>$Ɠt C@̴iJ۪sSx39Gi*ј-%(KGЉgCv"eS[x otyh>8<Q/Kl]<2:k%>kk`45v`;]alt?@-Ͼr?!̱ Ȍ::`c)[9jo3vzP+Z= ف}ld,3h wFd(PKs8*8E!,{i&XrDu"&hʗO׀K4jprʿs/7J*r`v'A}P(Mꊈq@'-0wiKD(s1c C5J:1z|(𝭊I q|ưёHQ14u+; vOc3w0z$yp>t\~h:9xK6>e;X!e MGm(S'[c?-:@Y'⤔.ki/>:5|]^π2nq7}X 2V* T boW~ a'quu{Ic@y[ 3/xɳ2ޗFC'e5hO\ eO[»jg;pG?#^~0ڙ<(ͷWv[Zo#n5N'@ q/Eg"*1EQkNfP z눩k^c632.nfs٪y>~9<}{9+;P݇#=f@eʏ g9U-_DEr(|6JG[vsqyٶ/m4M@GF吰\n=oyF8^{ 5^{ |&t$l1s.w6kd媵9mC k̷^`vL6Owc(GDW*]Kg@R@n,#ڙ}iOZO^\U{ e8vl̢< x?xP |f^kx[ Sض}S}ϙykH0fenyj_YDMLپҮ&b98&?^<Z$_Ph8fͺ+\#)Yhzy?so7tt:ݯ*^'jfErs6|nyc"/3.' k[QtQٝ^ߜp!qiWyGrpG~e-[t(OHDDQćeEH ~86FkR2.?L+ZwY>[x&0<vνԵl&5;w,0U=8yT F^ =Q4лi8im૶ Hadjq2INdK/5oD٫H#*7`TYvN hfsK4_x٦W/ـn{o֏ฬt~6y,(t.fo:EF?jk_\)(x`us74NI|DQk|S}H^>5V^ES9GXhxwYP[bF 葭*DhoocоQ]<3ұ}NNEVª+.q u[;yGǏܯoZ4ڿ}|O3qN}f6X]|-H8 31S@{9b(P㤨Q=m6'/5[k\sB{t?&޽`+K?.DΒ֘[E-8Zմd[:.8'ȊC1~Zѫ)yU30 -}]ծ6 3~0> qX6@O^m`'IxyN*2ch5^{ 5^߬PYj3w$ +EkKfjt3B,!/%L;Q3l Y8QmU*PdB1:8%j?A4, :&q whD{^yrVtѳ{Q&MwZǺ5>@f׏J7)?71@V  IDAT/E壱H&hcF-]A-!+_nmt8;,CJD_fۧhxoUAEpfجo>`0xC(:ߧ_JD.ćV+o\~ݍSLG{>'miؙ8P}%m{/语m^4Mk~4#Yv(jw232d|W"n,wG.OR^+d5c,?/12zqХ:ay}{`wmV~e^lC$7={=KWOk^{ 5^{ qe@#P:llμ7:mn6e+}]?0>dW=3ߥYK}u[ɱq̱ f.ifʄ[6Ov ^&:-O<YF=3Io#'@6ѯ;GÆΖ7YjĹWn<`o @n=ZăٻAM&r]?p䊶dzU$l7Dw8 2oFX/,IQA0S=N1\ZpƠAGFGdʓ)t gH oW +aEomqx]K J/zb~tQz:qoe>} Y)tD'9hy5"gę0d$`h8[}!a g81*s^>mx#yFuMe10.t7%7:k`k`4~kן͚[W HɊ2v`U6է rl1݊xZR6~rE4X+l!,!';zq;SkzZafm8sqS3OEoVyx89,cEif96vN_}JcneY'2qZF@|ь18v,PӆDXsG;ON4F@t賂ư#-O_D3 z6UsYkixv t+N =gLTuNҳ=5<"m2{x: 3MUs(Ep, 0hV6;U)@ӊ0gmzb ʼM]vhF@~@a2Pf Z5z d3f'\Wa};n-D yz$lEsҪtT'qa9hO;[~<ܳiwLJ͉F1"տ}lvڂ 2#S4YQW5@`[zWW&Akz"#2֗@k8MPx{xudc\4>Сg5zdg2SpsyhDcz{@5 ,7ucy6% znFGS+cCc#/d,_۳?zHen/ՕMcYN3/:N:IqfL߶v/o[{{ 5^{ 54@Q z4$nȀΚ0 Iri\>'OڷiȾoV] #kXs`0pe>Ҿ.Ϳ2{b 8dr&cW@VLA>egּL;}v-vh{e[vv[n6 0iKkճ0Ukr:z =?Zs-t8fH^;o'# >Ef ALҷen+r BCɩp6 G6gDXk˱RѹAT:;?o\# ̨Û~@l=~'dlN4v^,dp#g, 9hkl<$3NQ $γsn% ћ sǏA-裟\]&GWKMLD͎yʢ4b~²5tۓ0iU>F#0`1w_3fyo . 8\A-=04[ JS93zT+g^3tI<^+X`vyd=$?/BgۂN|N6KÇ%,]poPEy~@vBt:3pvtq U1|ґ*lG ]XNq.hwہ5fT =gRut"BI.*_z*Ve4'ݳ'oϜZQvƻs.YƑ7`3N+X-ޣw6~;{:}𦎒>Nkd-R^R-O"`4$ٶZ4{9RիmS԰:K!a~o>^{ 5^P4O7Vafg<1v6g첿Ap{;S*| `f:u۬l,] /`o/l_̟<4_Żc`l{1-~%w\OL:zEM I^a+:{GnBOGOtxWL'ĨAek1fo~c2w'_WHO"Iˇ[qblWEԎv9m Y_z>Ѵi8>҃q(3q+,CH7f{ع :M1!`; lC =?9yN(!cXKIk|d^MPM7ͤWѵO%6>*H[3yKT׬7јC7A@~, 0N  ܲ|/fFg_Кmk=Ƣ-pFxS\Ly,/M} 6(j)~gVad-lPty3NgUXM혓?e Q}ϞV u;k6zݕ=3ۚ:fF9Cjr׌z]L~؃l8M4] SwX}}Ohm) #̘0 O?J;P =< ɢ3׸YnbPeB~HdKe닞?}IPq/ynکXb2onX8gLcihuDK/؃ԧщ1ڽ?7!:}toOc?h^߾k``W71KYYu >03xKE0D?3l.b^> D=Va{!`57B `֞lw {h%Qp'/l Œ?qנ@385igq8p[Q{ىI6-4Ӌәu n"'z霓fZpmfvm<7 p:h;`y[mde6ں?j<$'B9~*]W/>n.=mV4{@b@ث}Nԝm&F''r. , s[6c)MU=Xʺqn4ezP_5p?d'< 3&謶bu 32 Gs =%Ț.,iЯ5ĩ1K! o989\lCbێ/ƱDc`朲|@IK'k) pΙ[&7s.=H1Scz8 SѝC3޻\6\F p٩覍Rv;AR4Y fhc*5>Uf{f+--f&Rly6NE#TO0זζbl+FG˓q E{k]\ҝӢjE2Zuly@94vrE79{Kﲄ¨oݦM2gvG#[9n_|)mG on.G^P]\buiGwAf:Ljn (5vs=兔^ 8E3!^=t{Y`\_3<=K;Ǿ 呱 ^%k~ߵ_:nnZQޯa/B+B&y#O ?sa_y__/797p$S]9^ż_\P'Kwz ;w{oo~Okk`~5`&G|;03FnTBQ,c!Y[ T||g+;g79P]Nv Zgְg,Y̅VՆڹ_XHџeLd-skZ8.N-M;ggٿT9 q뾿c 9蚙ľOGcf_;3c\swt nٰ$G'βc5X,0i`ME#gb5N{@nR;sǐ C8ʏZj:G)ve}ï> [F}q`6Nlv[?+y'AMrfn zs('O!:{!]X3x9V欠{ ,{Y*;{O)º99Q/ſ?^ @^NBųfK? psDba&a9aBp1Лc ]tOG&|};`)*I MGPCIE Ν/^AVos{{ 5^{ M~iJﹿWddYec,#4όf Ά)5&JڍE3ll/s_1b7d;6";?r}=OvfFi\g3y2G)56Ք5{c-@]x vOmV]ۀJ&= .82. &cUl0uf={6&L|6 NUQ aCaȂ"9+fӿ~uf# )GؘHh^ h,͍&Z*,tI3BmD !/?i"4ط)@<:|g{ѽj Y;7?9K99B9kX7M,Vv Y{ҫsNw:uUN Vzpc,ԗ@I;2!]An @ɫWQ|  Boe>~NޱCFZ8jp "5/ [wd-El. XYCS1\JD㯛Qv xq^RQ05!$kH x>@bhHN;KcX/m4CB[}6w]xFfh)7]TW FW]Cd = ,;t7tf+;x';}{ %@ۃu,Pv3oO/}._4<k -tqOꙕTZ?/"T1rHsNz~x~u{}zdy+Z9aLzx>\<;W>(VY^V/x6.>B/̑O廟/#ƞ/d e,3z_o f{md6 /m}}VLe?}ofC7˫ggsxTp^e0<oֵϖ<ܷ^{ 5^4 ]5&añ4άn SۥdYufgdKasV`2fmNW_^^_9|pȀ9I8|&8_ĀMrfDŽ, x4٧`6kw6o|x񱥲RAAme񶳨#@.`ã0{!hY0|`oVc(}.9>׌ڔ1mEsgkdGW{;'mtpW觯J@I+sҌQ{9@ys?mxfE3x ; T`=ӥWzB;=VCgm,MFT IDAT4pĘIKKEƓ m@ۅL聞9DNtD1{յ$@M3}G]N/B]O3 g4cyaAWtV_ڮn"߂2WeK`ѹKcN?{ 5^{ 5[ | yL]l9v= YHLDG2,x%f1?\Uc?0ކRg]&;gM6+}NaVw5Ž FH)w- 7O>!}ƾ_F~m9Psmj.7mGّM 0~,̒'`vo Ն֍s:LAm 3% `{taўzђ&GlG:t5mυdq戩$dFEЅ&&"]ca T7;Ɩqzg39g٫򣒾-mQv9hf~8^p}djI$Vāњ)_;m~8˜&~ZHY!;rzqd\&/PoOg\4Xp,Vз?E];A*R)-e$\@8 T (@+E)fC45m'f)Z4˭4p Q?efTBSSûo&^L=0o]W nuZjԦA0?IX-|pxr:tv9}M>տyt@i\o-ȧxNTtNl`Ҳ FG82۷|x3^v}CKw>Mҵ0m1n<9*mjek{ђ7/hYl{0ZW?{*vzK &*~Нtv{Mʼnp5^{ 5^߬6P{3S.cmb1_B]Nl~3eC;د Zbg]v7K8 ~UK_=lò+5@ ɖ7!i6cGZG=6cHl=k=.+*8?eW  , GOe7ch&=f)mi'> m4H&3W^&YT^z.ֈG[]s.^ Ɲ0NݥՓ'kE'.i{PƔM' ir 4__GÖ3_mp`yFs%UK0 m6 _|Q (}}g&:OsEw YB<91 H|3>ьWbNpPx=}W:#U4k!As[vQ2uј1d՗m^iLKsExZ/"z$wz=<9ϩҦeuҢ8 t\M~zc+O>p~B\y;_{ 5^{ 5Vaϰl o Hs9v`P7)[o3f=@1Z8]TUͱs+@ZzZ+ nnmt0>eǖn مNeccvRgc/:pay_l3Thh2+:v9<8rB 5kuT>h[tvrD=,]q?JOfgOΏ)mF[5LG:t,}Klz3&Gtщu[_]hv<1dчr铼#(bmxԛC8_ J;o1 2( "jGx^)ڞ74ƱU&e:8qc*8а4cKDh9Sq^K|#.:fhnhހ0Y+S8ޚ])s@37Ю*Ч x6¯_!Kq>Dd3`m[ ktCXG]gi~I5^ۋa[l}EɉmmMś5cx dKt^ufD jĹ[ uqWr6Ӫۛmxi `яЖNtd{a+.u嫊琊FrLb=haz28mc ߹|Wϗܘkx׶:p'oٸOKFk\Jơ=/icBx:!:+^^,gqDSd{g_{ 5^{ 57h'QM|(fy[_KLufPG02B_>>cƦ~4yd6z]e@͎][3}eyN3> sy:c:+SD^9z6Vv:]zdcwaQ7]ѐ@e)NFc4sZL?j3ga`#/8*EGjGh{Zg3ck;KoU2ؘao Iֽσ J$s =r@yՓ:#Ik N~qMt6`Lwwz5 _B=61?ѢK2w6È <gx9k`k`dY|Fɘ%3C9)h;Sk:3;5@hU gw9f;ok e&7O)/ݷ=:afuoB'<-d#=3՝ֵT,͛ꋻdk€9c~jFj'Wn\3f˭36We'4fmI\r 3#lݛNi/49 QǙٳ?I{E63[zxtJ'g@M>:k칊^9 {a0p, ^ѠBپe@<{5mYڐnm}pB3ˎ`eS FG#0ST_'3y'Pu ז%(hLD@rƇ[)On#ʒ9J79J06,jYn—;Pv#ٵAI$/|V4XrsaeSnڅaL緎ҮzڝXzM3Sm)?ˏRzbjg쯇'EmÓ*) OJZf<^<]nx1J̪kKH>lN+<6Ev[>:WU޺ {TO[^ۺ+?xv)50Xl-_GWioxcnl(-ba%%F.蛭_,Hv/";@^yNjjyԦ91}X^j-yf!M9rr5tE -Ε*|w gƘ?@q${̸$Ш̸EId𮿅YyCO;Āq)=KGB쯽k`k~~LvMvHl,!`@$dǎ$9,|D0Ɋb>!_?@l6MtdZ'._Y@v{X#u/3% ҅Xٛ43@mwZǍ%E E'LAQ p ҅6(@Y f#/Şj(=ſh sݙcfmMJf˭)P\6V9&^,{6d6<0\Q; _(k8~$g4\| Ωt9:,\3ޜ] 퓑)p7:"0#OF]ݗ/Fy@CHHmF]>'ƜpU=Zucrzrdrκ_}K3}p}v?8>NtYrZ\ds@:#>flVEcʥmt7mD_9~~I9YdtM {;3gn՚M9?G455zk\6orYm#1펣`e?AI_3Am\#[88 d@Oz1 kk`?~8cgge#z@PvǬVs4Q` 8hsۛl{7@ԋ4*3~>O1BG|j)آi<" (~'Ȅk ?lN;R~پ f}D! ]@q';umY ?nbXC dqHφ:1⥨Y>= (o6du&6qzDlvl@9ơKJӍP}5mQ)u7@Dyr\&cϰ3r!a,PY/h=h8,ČA|hòeckި<8!_qmWJ1QY5[^>lJQv0kJkmc!իO|Ս!Y*gҙ%ӛ=h'hko"Ns }}LzZ5uTWkmᒵdToIX!Zm>zgs|n zMWUO.)%L}u׭ v X+a yҫ(A^Xk~X0=S,Z` p|taœ7rSFG~{x"_{ 5^{ 5N/p_kR{Yr6'fVBӾ]Y)o>ل+E @e-ӄ_N}"]l"$ڼoF:+.{gޢ OffvȀ- 0 zeS>K2F8.|@';*-9`rBZcWyu̪;"CU1u?5/ZF'mrhυqpD:`dҗݛٞ !Q:2zMOTCzpU Oz:5eolϾ 6Ƀ?4-a>L9uIx`tiųo` gI m4D]0%8 {:|XxzFm6?3)%C5iQs5 3 -᣻6kQTY* άM;;4`$V@{qB2)Ӱ˟>?V&[at# x2 gG̼,ytߑ:C6s0 KWhS7xTG[卞%ylu xT3tƱW p=g=rhߘ8M*):Ħrm·#UJ{<yX`5@M+wk]q@MGO_rF]9x,>20>rϊH~2􃰠ʑҞUN}b(^{ 5^{ |[4 ]8ݳ͌ ?8!¯_`fN^ PvaY`w/Z{dg|4 3بfcגfa6REl2iFa=k+4P4rk=}Lh4KK|"J|sE[t+[Itr#o]%ڏ`V<M'>[HY֬,|?mJ~8=hpNЉ Ǧ~ZrޏA,ʣgSOˌqC7"0#ElBH0+mht~isn?[Skfz7n) 3353|nRF qo/>j]8zEFZ-OOgHC*09@M8<N)vG܀V[8L|4}#<70D~^, K-ݡ^֖dde/ U =u2{ Rۇ  Wmqbc@|&yP~^'΄@K|o\wQ6 q?=49668!Tl:lj @ O76r]3*Llm(lC}`hQq0ps`6SS;ֽv!YWw_*-Pkգ??>Qvzv8@YAހ o >=óHTݒexį1] _uE/F?a)-_?h~ϿO?1~}NEs_g]=[ ͫW_ /eg~f_/k_8oFy~!{Knw}o~o?ߖVnğ7 _,Ok`GB@^6PFzñm2?do7՝cɲUϳ;hly8a ]}>x|`1D:Ve³U:i8Gґ-tr]#ҵfahoe/*{.Ҡ., 30OkwlZIO|K_5s0&SjLڌ/~7?`Tv_2spPy4fsUxsP=ح}?}z2':^c6x6; ['u(x7`%:!3q? f>g[:`HMq"L?~Todt8֏q!ǎ2p 'ya,:D,{dxP9ۼhf֗^鰖ju?T0RGc˛Kݽԋ)ʳ3;k̸V_z=bd{.udӦ5L3 @#eE[3۫mu:4`vJ NXƐ6guOvk/chOeN}dS>u`/|?Y}g$UgGKĀ1q֘ӟp`՘n =W/$N\\ k_}SeyBfoۘi\ȴJ6Ȍ-`؁Qbf^=!%H!o{jdu}6ݚ`xE˽k~0A^ΟZN*_Q=_,9=ާk^zOYY{%m?, *A]H@5{}AG߻C8?Q/m=("NaG[_ vi? olm =IKc/(],х4}m<_3_%*+u34}\p}\o0&Y:Z'ypKos6{ںޒመMVz鉎̊!_腧&ځCcqQṷYmx[coh P8Nqlƾ˚So~G[g)^wkѪY?o;N6L? {7_*J?G~nw}4/7,]yU?}v{߻uQ d&ٓE]^\꫿ndඟOx7\EL=..}.?3ʸn'-AA S~>KPǑI#{W .( ]~L{ ZAvZ@Ρ# IblqVi7 'e7|2@kDܣ4ҳ9]rn*."w .0 XJڷ C@n$q >#],νE]1\&(W Je[!vg0学s}ty4)=.NB׀d1ѕU.G q hϵp󭬾O$|!΢ Wt`#yJ0sY7Slۦva`CrwDZFmQӮ()locеx#;1r]1>3@CȈ*(UvR薘B nhA21>MmwPk z2ҼϠ]4P6FðQ DB1-xϧ#*JO0ViT O8#EI PAhĩ^i ێNIm'ﲺŋ| Nre\%0*)ҫv 2DoM:t$SEvZMWPG&-#hpB͓N]-K/cUۙg9"̒Z:f.Rqu .m`@uKM%t%n3"U"|LR_Ь4j*<\Mb >)~ m3s})'e`;tD V@GV6~~~tO8r}-?9l:wH: E%ʫ_jKZ Xq gSOnzʂ5 4 _ܓ«*? tNFP_B{#+= ַ6y)/o}Cһ]^,[?p/yϷP~+xG{wl+4r '{{ F 㱝>?O'r2 /x~{/ Y@[[e~W/:$vvzۮ=^Wy: 4t hvP)<# M h<\2-s- c9>xv3 Q_]( G%6?4m˄A\6=)$;˴A]O mS`BϾp=:nh, x/ ɏktS3 qFԽ Z%-`5«.u P pvg x3UG!:$4x}Jy xfO P L1^_N %gʓ4_u'iۯ:wݞ~L?ug eizL)CK:A | >z_#<" Ǧ4_F+P·w#薉 Ϝ>ğ6TN)P _hOZN3mB mSK Z\_=q;E ߗ۳kM'EPIޥq-c\t1ibzl&mڛ:-.fsVӻg=n}B>0hh p)㺠%sùp%uZ=d Ozfڨ`+2Сv~#º _|y:PT >_?}J: ?2`")<=ȡ# =*}`T 9~փADAv35T2OjeRH[KzHv|'雌JS_=P:#+r&rɵlQxȂs컗2p &l@SSߴ5\O rGt ιص|fxmJևGB>lё~v Ў18?,|Ey M7qC  7NG'`73l+y*ŠGJ _^u):#S.;pyPrz·z:Mw!۬d{^8Wf!lwi/zы'=>tG \hOyS&']a֝|m{< P ͇?a,`xe8׾w~;e?򑏴{eyץ\|5AG~?EnF'g<4u2<}_?} ECVL](2}01Nʟb$WPw22;cl4M E.j1x:x,zCHHէ~s%Y }o3/]{q4zkȗk V!psUep yl7"KAwz q k'SL޶f@])ΒޟEU\ QjTZaJD۳)2-@Kf1:zDtlRda5]) ^ Nuz#CZ49YAw'&.h} )g@J⣜܌}պ #)._L}GC0"=~+6Y <~`hJQ$':w(GzrPrΩC]Xr!pzMRt)*!=ogG1 |Lo3Fp7V*Ԑl+t8ަlXۈLTqy&| kRvD 7;%mW{AE߹]exr-kcV)pv-:ExQ6@"n0 !,O֠NsՆg V㓻Ǹ ^3=F%Wɋd-AYS:>+2~oe/K|k5x^ 9s#/q>wbۏڦ>ئzq^󒅷@ģ>o$xulOȏ<3o܀73ngłFc\|Ũv 7^ri`,M0Ì_~7_sN׫>>~߮.[;+\Bxl'vޝ6|40h`m{) IDATrnF^c*^_~] P~šv$I@L:?9NH:0SqZhP)Pt$PŜ~i R*'ں;7 ]P s(3;L L1)6Nau}}Նb6^b\S%Y؞kY8.W+LE) ؜ Awi” .U6n%X]9UO` `a<27%us/eЁ>8 75HFmTsUL4NqR(Yݐt4С hu_vMfeGێ[yULa&PFqwud;`/ +̛WoҞ#-qXnm_S q?{_dFo18XzMMw܇O#곰=%ԁYRjaw 8lsJL)uZ d??Ct,Řioszⵊ{6oZ2|CZ C@ \ W>ial/QwsI2M=܋ .|~^̆H;ڧҖu;2eĵ+ ^4ga]uvEt`NحʏD8L Qwڕy^8\OvJSW>w?眛z?`O?a%1zy{q󟧛}wvWo|SؾycvgX9Ю/oW̹_ _❢ԧ>վ?|+_i]myΏ2n?ھr͗0Q_YYwطo_]MN6_k| itӶq;>|Nm;g> 4p; vm2lKAj~>>~RW }k h>w<[e8.sK!wsΞi.Ҕ)Yi㺸ۿm0-dUSAHp|J_ Zgng3^N{ʾΛd)t`~ueL z_ʱ\{bl7NB  1ͨ[y+]A7GHN9>-rhBWCK|`9Vs7`'ӿUF'xp#G-!DG\p?tǃ, Y U'؅iyn]n{+jS J^th/ آc __ G\o}mLkߦ1n-wrtt-3h 'πm қoAxS,6h@VPf$`!G|&u-F|ԩW$ھ+.=5KEX3txY9H:L.C60Gkn~WߺyبГ|P۴C=#F$ Ӷ}a2maJgEؼO6BjlUaiS f]c g[euckOնP6pvb@j׶nbf?:edǧ.e7eStooj0P~LDܣ/S>UaBKˆ.^O%^8$kiA3@2-!4roy{[25b.(Vhއ>z6a$0^<ٽMQRyb#b݂}JKǎB=IȾ:bU IET),?$Ly8]#CW?PB9 2*ogXYDg 1v6#}=gmCq2CF1ld)^gzI}۟x_ޞ =eΣ"o_xc3/Pk7^_hs?x2*x,5׮] Z/y< O|" ӹ@WݿKj7Cs#|k_[ck`/wE x1 _࢈.'=}]yn~'CL/mݖ@qZYNtݽ;KS>G;9{A5`~#[]"A[uWDҖ܈T>~y0.lvyVGg\N L'ɪ^8faYXX9gC5[7= Y E+]iV=[cK%Cs+#Nd$Fk&V0򵳥tN"~p>S4s`7heRYi9\rȡb_XY(uiŔ耊$QE%g)v`!Br ie 1Ď$Ol9+^.A9"e-t1|9`KB@D+bt!;Q"ŀW)$`Rxs AW=XAQMGV堞='I6[dDcF`(mzҭh%+R ~@Wrzh@ #%e9n BN#ydAT5VM̜r;{ufJz][ڹ#/*&&(%XX ^4r???uk<2::sNV \㒆@-bt~#K@~~s9z:eJI:ro,tҮƛTzNW1J^S?SΛYiWE;gl P>óߑ F)'AYaA:0 ѿyC7I'cpBR"HƒCY#Sx*( #hnlpZvFmk[:mm!,>8`4싼xi1&SЇQ Py2o\>ȜdT;/>qx5igk;~x{ЃSذ| :Ozow?m|#ڣN:^Toenj/x BLN[9NJ7W]pEMozS܃3޻#?ɸnwgi{X~wds=h` 3؟yUG;PCŌAPG@u^zn@+g'=3Gpe Zd[GF3ߦKruLHigO̳ S,s~6 Ū;~<%+D3 @ mhOYw+o A 5`$5TW-rM !prša@d,R P቏2hD2*/8I")lc5%,cqV]ƮCB9wBCԗ3(<$Ӕ:+LL!Pmoy@=i{NEC@׋BԃщYFʼ(UÆm ȸf,Cl+wEӠ)y:Ԣ30svX-Zex v2Q&2OӎlDYFgw;><-_' `d,E)Kʺ|'OQ Y;@fovQSrgbɼPuo96{,-SDbeyKG9NϤ0x$1ߘ;_VS!z׎Ms%}MDwD rxf\!ݗϼ|"ի/LV_؉AhgMzg`RdBt `t_ڍπmum+홺x%<MfHrEҠ_-Zޞȉv#л{>jJmw4cʪlwn_7YmB=G/+_*]?bQ 40hNO|$o]#ed89n7Ցk{12;vn;ryJavndSnjd7 -HT́#nSmvǛ_"z@!n,#lR 0?e]˞\*i:@ئ)dtaELdy8G l(Q/@]"m Ǹ* X記ow3PQdZ: H Y.dg|@‡s+ q8iFw8Tw0oG4zf>P,`-cº T_y}I+ϕ,A ׮hdTk9#g>lPٜ $,b3 e{fO)JJFuɾdJ Y:` Uvǀ? eFfB{4u%t*[bG}Ee7_tn ^z5RӢ9 N1rQ3Ϊ+;9C<|{xH RPA+>*jFiAɐZs` e=L{<|Sn m^:ڟꄿQ^: h3@vFEEЧtԓ"#OZEr)7zQt Z9_t]m9!\S ON( =hkpI8UP#kk?G[ 7D_S:݃Bft\:)IC /ctIu?yTSOT,}U-=er[*xwPl hDgC۬yЇ 7>q#;Ǽ[ž"N3sL)]p+>6oڎrQ!|?kYɝ>#wqlvM7+?=㝓/jTx;o֝PqA ]k ;IFxa`IQh1Nˑ)uVxe >D t2jnzjأ0}Ƭф{d33SWct}qL42P!3s ud-%G,4;nf=5Ss73=4I|ySf}U@"H[y L D+x|2;.C [o6"onǗ @' 6I 9ީu\eR8rW,kH $TRQ6`JF@^d i?}h+4ct ?QYma(P!*.xG 23 z~yKZϹA>ܖNeB*_ W|mcX>2ot #dׇCK=WYEp Qo tv5{0EBz<|H;pTVxP|nee}ikoGNTh>ꐟD9yV]xO6y@Q@$噠|rEl~m\SK'4#r/h˹~P,+ @M9](pvښWN.—3 ˎ;Htgi[:gӱI/L[zjtWՃ23 BՍrCcI=;nx^o }01ڽ|6!](#FH.0*NѮ#08Z62@,d7Ld%G+v_lu5W җOD/fe}Ȁ,9褭%.iAz$c1GյF9v&>džԥGڻe}b(E=+ڻT}l%"um[([A?D0\pxkبPvp-r,-JN>Gp(FI95MA/O)$lF@6U: _Aos2q6c-sUx ]{T@ߚjoS~Xr%eٝlMȣ&@Az@W%eۤV&]kJԷ@ЦA S'ʒ~SV=.() ]{8Ou)\APSR-1+{-hqO2qQƲ]g$'&7Voð; (պ>ZǢXޢaQW0Zhb9so-fBz ޵I;D@ bLQ^ 8m'q!lkp_^ y =U͇*[} -C*y m&AxJ4LF] }sШmYIED7F֑Bo?xi;zy(҄ש]yy<#NkH3]Z2Tg8)D>G(7VIA.Jtz*sBnN,KOiHZ61>3~4[:]pkK/''A2*t۾/]j' dL0)8f?rR6O^ر6J:\g. _ ޳TNp40h`A04T9Fb1O@EgyFq*`0'%}K08h݀L';w@4.^| ,XYtìW %ܶw*$:8"fWt8n5(A8]d^r2.Yƾꬰ B?4,=3Smy W?)JY2SME;Fqmˁ$#d"<>CLį)o9gu w |uy6oPFyW_%Bj;@ɔg@3bSj]w e^*LWԥmi KMmO{6<m~B*[NI@%Fcl{: zR>EdhxBF?Ap}ֹXxhxHw(K> Voa`i+mtu@"9.ֹFDtI"4 :@|ʻ(j*ް^ x9z  |rHqʳ#:[BCl"i8G|" S׿NO0>ЀC@71Vd_} +1 :n8R#@m :ߓԷ>eo{Gg#)˪#,ڜ_ZoiC-&PAJ( :U~ EwOGz:fM䪛@s>:RÝ ƻ$؄ &NN|yO[䱂0VwiH? <+quϘJztmӀ(:Ro*G]phw* 7bU]NL@B#KFkDx dePj/fp MkO (v1.DWW~QcUNp ~te3Cf墧i^<.^/K8-5p85&d7CK9Qe[Ga, ۋ5'I3amM9 4U3b (!®# q$_Q)K bd:FH+ (+*v7;ئ+H>, d (wa2^i{hvvჳЫn 9e7eԄ5bbw&mKod\hvʤږ#{7}53EեYxV<(sׇ)&e' (@6sT4Uġv> уz ,yԒ#>YE",KZx=t/+&c~cr亯#| ^>N}X=Te7P|hS\N4-o:/imFؒΒ%0 }^A>h׶)?8kC8vXY9!8?~^ >3d`C+AsdQucf,3' dEL']I[E5}Ѯk@mkLIȷD^ZS e^/  Bb1h`A MYM?O7ߖܜg>3>.@$`ZoCK(绠^(K@+Oy2&#OE [V>­}GPKJy' -"/ԗxؗ>]kܾwQaǚ$x _)u~՗`EU( [C >icYW@Ƒ.kKG7=-aG^<ȠF A-$|4HvӮ{Zut(rM>qh"&P'tےcy `d^z:rk ~[ /'hL%1/ ^K աZSa5Ep/|3 G@΍9-E/~z~>4ה [h_cM6e%iB]v8f+[ξ*6쉨ò[t==yȃC- = LRf"|΃.Ȗk6AXfuVUU?/ |ц=rɿLfㄛނיϢu'В]';%#CERw`$HA 40h`i[Sa15Ӥ1pRJ+it9UgzbQdT^K_SI`hPxiRftt}ԙ`v+8r|,GPom΅l_73eu\^U|Uwee.PGq`-qA\Y҃W侽;)G;а+v{uj^GhFN/vdaaCV|FC@); ]4[}w^KcY䐧qpE{U>g*̥֘8X%p9:YwЏov[d+:'a0P8Bs@E]R]4~K]0{M2E2nK#ŶRϩ'mr7rLpE)YI-/9ߩQ=i@`[S}VK23mؾ G* `!?I1%l \}aD䞲{Z~Z_k@eo:mG.#'R(ޔq&5suG R/5 «|'}dТgu*J>OSyN o6zJ@4-IGohC;I`nzh*sptriScX>V^m*ےSo+gUH[PP>Ъj?w\hB{R7Lz蛾co{e*9l;0YeUҵxu6k6(74u%|wz]z9N (Ѿ UJR L azHA 40h`4Ooa{o;_xVwzt /h']pl깿,Mt.-GtMuQff5 }_OjkI xd'V ~"S"'܍lN?(,P.D6,>N}Yo0[0 +VVסE,TsedpG=97ʈԾ)@eeҵH˖L&@%emdOFBuPF?z5b 35<ŚdK?s}S[&%V0[,xʬhd`*AɝdaA_?7JL3X܎Rޔݲ !M~ev_wzV:&M91(fQh~ ՟"N6Y>@8@v5=#s O 7FddoK >E`Cr#8YK( 6/Pc?GIcײu9.-$v5"-oIlÖ@[wK6!|2⠗ЕH>#C ST@t|qoZ޶'A?\(W]xH,g79G\nEjqG|TQpS2;J ~bv=#6Cv r];G&Μ} 8Yc$5/N:-#wyQy6+(Pzui{Dm-Nk$jl,֭iX[<l{fzv7IV"s{QFunA;}[eLe(v-lf={ RAH~5nʈ<4ڦǵ.;KD/)8qMAfĤ_ϠA 40h`KW>b"yןd܇%):/_=,pg>ڙ="S;6"G93O$O*}m) #H[͑V._P|Iyߦ@S$ X9Sf``CLTw'UHOAe'B}DW7s aSt%=S.\mdvQ 8@:6Uuu5>ѓ4Qoz2s?2gDZ?>?w) }1jw29dliYH5YWe~Go Pߩ.g y@Gngi:q^̴~['B[j2/qOk{9&v{߮xsQxq-GV CUL/`*P߲}s.TF}~3H"H{,ʷ'lΎ< WxA` 8B`n:V+[:{o8! l)4rHkú4kki cVԏÓ9̈r_@*:Ӡ4:i~Kt S"lQצJH#R(|W-z(#Epkn["<>x @ _1U$j>Ph݊&@ -LyS\#=DG  W89 z#2|Z2A*W֔HNO\] 4sD Wlz|)wǫ<˟xbooՋ},LvZr\ yY/ Q豞A#2Zܤ<옂%)ihRz\YpaǠA 40h(c[l7!-B𨋡!.tf #@S\*z|)#4>@rDtY{CFquwHl;mg +zB| . hi0H'FM+vYr8 2lVc ԗuB$ӌ늫nj&G>(SV'|H ?ԤfhyA}C.n妦rJ9+7tp 4D+^RlNc-4=^P+s ;bd4a~1;Î!o#_'G>3ǭ.̈j2bx+&X n#3o\vn ,am韓W3dTfUkBhPS=_<zIb$}5de3!A 4SütvP%/Ű G1SʐYA u2;C<25ZʻQ0HWH$XPfj5tO]0T}$ (R2Y%J]Z):\Gt ЮʥLҁeQCUyOA~#ve9|ȊW0 <%QX.M]pw~o1ib:J!GZY z=Fvm'k?~WA}x =ev:BF{A%ҎY9 Ҏ]C}Dv)7hT:KS =Fɜ-N_e }aK&/\)ơV'~-M}a12UO,30l!nVA 40h`4k.P@$SAAhC&IwN /삩 <)GR3ή?-tsUMsu Ư1|ޙl(b hn2BlGi* `|/I|],ږ R:ᾲK7`M[#QgJuG=xr( aqCQ8Ȃ@0PY#~x)Nv*r#mޡᨾz3횝N̊ʂZܭTvv՗ @G;CM-Ln"#W:w?sd, G|ut~=6uh&/++5X`†(#88{ 8eC7 ѕSP'nNOo߷MeXPuIڪVsQel'is13GLsq F}Ox0bĝ IDATGF-,^@J FX-#ԣ\st2‰fHwnjC[#H (.`O~ӼCo]-bcb%Ҩj-Lb iYX:Y@Y/+_u5Wߖk(CU?LQe0W߮:gP!FO0`4){EXp!9i8ujze:̜z|NX}%?7x<42o%2+) K=)TaNmTP*(#-#oBH; iI5u/?>jя/ۣbNW_MYF[eΓ\D7 ^൅%ܺbږ~}PzPg ὕx1E")@sl/+Ih$A3s`d~MS?t._F|]dˎ#ϠA 40h4?ϙQt@\"#1'cܛk@V!3#9"=)lBj׭Bo2RJ ,gp_-~1m K`A~@o\R<i/yԢn:( +/#&gUdr!>G' pO@.U4w y <@n=2N([s$#aݠ}2C0 ` !Ȩ=7TE1s*)|d uG[m[Nqt1)O+->q+4a@w `#>M}e7 εUl&AqJAXm͍%Oj8hI%SRY5Ply6# p%u`*w?)X3E㿔My/tz~ ӹ.]٦lpKH,ep"@1  ;r <+!"ܫ\"|#*Y dZ@ [,t^J0#"(/:d=B˶}yvLp]' w]ۮ3ʿ2ej$}O_Sơ_4t/dt#;݀lo9EDrfdS_\&Ө6OЗ^6 }-ɴeԝtZƶ)~GQ€BJ ˗ m(ц1/R:4\c4~hWA{R~`G+zfpftj?veW&ZRu" va=,Y^f'~KgC#d' 4EzA 40h`5}q#"Ks;4%@OswvzoxAy'ژQ|hY]ʸ#h9͊|.*((,iO 4HoY) Z- 13rJx#+xʴ%`N|u|)emBld<$L_"fO)eF"Qwm]_i;<ʇ27C>13:ˬ341Uv5 "+W-K{WV,X)jI1 4KiN"qԨՕv&V);ADMQGw61T@ƼP ED  '0j#,`z93«ʠ083}mE񔅗Z[ P)  5/7D*UW KVhJi۾ȫo. >5(2['Iʹ.k;v'; n}鯿 ="<8fn._\my uރrOM^N9\H_=F}>c4g,MFŰ#m~T*Wh-x/<\yJG¥iLmy4EzPݦlp(mk'‹*%#B d0HP@ޗ) Ny #PlNfs)3~Ll'iߦ4U>A eV_^|cA 4pG L}v.`)@TnD |E7=Eڢu_a^}S)D?JY:oSȥ!hjI\$7YUS8 Ԉ|+Mq5e:wl;r[bU:S~Ϧ_ICtAՏ#Ο\6S93' :ʿNeD]=,*S 2E]i ʠ2xb_(1uԀ7Hhc2W;=DP)xF2]?,#󶫯)@)~I6sCG']u'`02?&ψ}U'n@4}k?6N8_6bf-AXT<:u$? z>` 홡~ 9Q`}{COx'=ND]N N9݄)_2h?>}ws`pŀzຏ*!S/ %9 zGBc0=ys*=6z".D+TOA 'zM1.][R4@ IΈ8egDm*~{XU*:t>lk>˘spҙQ?zM ~//k$_;Ohn9,E|.:Q/ /Pܱ+^V ϼhkÇBPG `Q)XFZKP uLBzQ4t[q#>#OϏҾ+jugV|sc.ٷ^JE[,~G|aC* 6ƝRю`Վ}%'aȗ6њPN]Gm3ضu;}Q^^^*.|zHG;Qi!kNcsmBٻfl{}*PE7$t2(dl[]+,?E@K< Q+~ʧ.K.p/aG_dBolQuOwq`Өᦝ`  Kf9>x3J7aG, hz hx֗IsOC/r@;mҖJ;Jo##w(Z~$+sӿ׈  }ԧgií*܂# /Źzy$CCs(rg'1kKM^l{_48޾]ۺLg S-|_=hWƒ(PMo;TT ^L/l 9 /+u#)7hXW^%9.?/j\ e}s娀 to ^5FysO~l#QD"m#e3Va?n6׽ ܿk+rK^Ndk|s֍ǥwG?}*s׼WSLEտ~g~v';_pC{.}g{>~qjo߶[P1h`A_K+\^| ܚQ|?n8 8_+7U ׽en3"M:Q|c lz@e[goZƸdŋӇZZp5x;xMWX_xLĿZF\=-l˅ MfH6|xj5w^wp68y \5ŢWomCyL2'0Zƴuu~'A9GI͘b|?˞S3 f 5t4uVݙɑ0xpGu/mfb$#BHw XB걺(uF ڻkCQ淏Mbț 6g=@}Y$*(aP'&wSȑ2]Kӳş[""cNzq='+!;L6* /v+j9Uչ#~В/|DHӊ+G>4;&fy sWu/M-.vB`%`"klƬc?)z(?#}tzr< Ml:dL} PU#`H.''>۱p5״v_vݵ_<=Yn {{~wg`\g3}?m7xc{׻/>~%/~ % 40h۪N4h=. >s=FX({㫬3;}wX@pV/.o x'f+5Ov*ɹ Δ'6|i.2YM =tQFl|Aæ-ۑ ɗO7h:β2mQDOu3,{Hnڣ@X / 4`{\m012p'.A%F0 #(Q9jAz.hN55|rhEf.YPm> U֢`_dI6ǂ,B uG:\䢂`'@#3x=JvX+GHͧW{ CCV K Y;2kՏ65F L͂âkeiGZfgQ9}~x/l'f!0^}*:V)̍u~&sL'K{pG5JGm@ʰɷTVr-9lЄ4۬βL9"c`cSۮМWtO;SzxOwm]珒r/? (KupO+K%i c'@@Y1nFT[$Oal/xxǏBun#: "2wN)M폨K"ޱ[cDhnZ-C7cdPd ؉}?*f@~g 7&ж)h/8:R</MѦ]<7tG>k[tu}RBZE>:WyxȒ>TWepU50bZ6֢(Ȗ!<ྀF+4u1.g@(U&^%5諯dPd:.@LJmv|Llȟ`jR&NcwtО'e[tѣ‹rqSWI^<'W]z{ݾ{ۮ/b;1Sⳟ\W_?SA|`_mBSvz}rOvm|#!=ۋ_syz~A (\-ÏWN0*8b`:2)pquq8$w#Ȧ>/@6~QxWh?'#b:}]/-n|\GY@>' ҆ ί+F`@dpyK]N۟@֬Q ;UyA294zOdG(:>{ej[/sѝXL},Lh@& 2J?m#lYU~#d4C[|j?.Tm]ޅf/N{e8sl#''`Fm̀U2")lʂF3$G 0~y+:ĆF%S8!Q *;Yc y&@f.h.S_#i_Wzp$N;5 i1 H'3 KYV9" \mB1qA уN 0T TGZw^ 4xM2+{͋Y z!EPJT.#G'  T2@ߕEI}WOمD}p=Gyr3{InHL1I c+Ei`P2 bӊB-T Ș)G4<2DØg>wN?ܛ TIw~{}׻z޿]俀; zAa|X򌳈GmQ6*ht9W]H'g0DV5Ԕ#u'2$4-EG^trࡶ:FL= :@5܁<,1 ;{`G[8\pd!#x'J͛-/l6Uήj^巍$l:" b9ڄzюχ=g.:v p=е\,ms1>I=), ?#(Lnj$U^"OF_q*NޮQ(3GQ=o.:!:o x{߿Sj|3w>,t;@{;`o}oԧ*}N|i@oeT3pGǕW=9iguV{ғhG? ^~W7~U< IDATwݹ}{fXYYikw0? ψ뮻>>ϵ?aϦK͵zc3=mo{{~Ǜޘw{=^W{?iOk'_PUN悔?ϴ.җ乩=Om~-e6\p=h`!qv7F/2~n?A@KSdNй{:| L8^g{]NPtZ:o0m{u\nwi0۳lH-O2_/tJ\z~Sӕ] +_M2GAN.kO_n.1@P]n.|KGT n Şf9ʮoh] X~~(hn+9uM2HBc>+@X!~+AmFp{qE V߲=n,0zC=,.-lԮW!si.FhYjv{ع0]}R, pVױGz٭iԏԣ6{*DC>* 23b`L| - C?N*|o" W)uvaC,((;=Ԇ|.Y 9# X@F#NSD^'Gie<ӸBXZݷ@/%Hߏ;_9E FI|(j>YlX݇փڡ2W|[茿ut`$Tl[ B{drsƬx?>ny'DޢKiTv#qq+o`DGKxG-evKa{σmqCJ8x*#:@܅sf !nʢ>lC`ͳf:@FkkGD8oԴ:]:GZR6mp߼x-3"o)& Mot?W_}U1='==!';joe S"LxVlK[y!àAЅp2CF8\YǞY;~Rqp0&8:xyP!W|L@nr2rD҇Md-D}00!]ӭ;DGXF BMYOz/Ă3r.ݸ>ɟwTxC>\TP'>;tsNY 3"".;>PdN/ }>RG`pwWH ǯ^5bBxcK+}1yoY P\t4EZ}auc Ycz@zE UJʌB"=/kG΢w,xkj 0>|!K-KDڑR4>m IQڤyvmkúb#SHlkx3M[vgߝN04Gi!7(3=?y5{ՋЃ )ƱM8mI櫧dõB:pOv_ߘ{>Taߺ|iwMB*]A!>$2}H;=^K, ϱ.Um^,ml,G mE:#ݒj'{0ha!lQ>kIW0<ܡi=リzg02?džHJh޾ ~dJٛƏEɢ< ^zi[?_;ziCG_7=;]tEկzUa ' zx|u^׵ic=-ש B H>O.O'~}' 4u7sd;+3ˬǤmu{9 WwU􃋫xNܰҭ ?*h NDfOV lygnp7 ϞVӷN e` k]ZeI$'& L@LmyQN.ϲ<NetʃxDLr7uۆvM;CtC3A_N!DL&!6Էewf* $ѱ(6%ջp`YnuՖ/~g퀂"~F Om'G?t`fDa]c >}^ -%8 ^A& ':Tnv7֖d*zbmb*ЃYOdF;/<9m* 0birZ6=أo.`-m 8Rd,մQ?%: zq@`$;4џ: ~R!D8U8@h0{a.ZC f{tr 4r4(CCs-%bg̈́J g^N}dx~7#Uܒ`P(/2OE` {D[2j@VtNԑ0>U?Q&_}_0kSA4< 5#oX/@ћ:~DZ˴d;΋ha½NMiԫM4]2%#nć50%?v]ml'JeQ =*iGťutTݗ | JꟺlWl什m@z{weA>( v?CI8J26i3mۦ"OL̋LJ͋X**}jc|&^&rm:FxB Q6iG]i~;_vsoK.ڮ~5@Co}o]k[-z#xF)A`TJyܗ!#kQkS`HiO5Csr? Ae~apٳ y.B7!PNZ#vG Zv[/{3#puFZ|7mCխ XNRJauN-FhfXu\SjN$[nA_gqţOudܷ^;6mtJyO:?*3z!`[#$^[0%aĚIT'bw aq||m#mh;p .=(DFod@̟1N ѱi"[ 4l:vE *7uA3c{2ӱ[ejCkL5Ek ` <J39FCG=t@n*7*POUma(%QM9(o灮hF@dSdL:(L 4H=ԧfaζCB(9=(rz 9Q1Rd< c!BӺq["t^,pѭ 0b]ҡ_`H-)oWl3*Z}Migۖ[ ./sPu(~_ P'`ޱ Myp' YT t'mL>He/Aň8:+Y]~с&|Gy{C/WWL<_Tu탿;,bx{;ĺ{&s/e],g9UYHχ.Nu:Jk/nǹ)W\+saGC;~ʯd'_\Og/_v5ݞɈ??iǞVdA4_8 E;+쫓Pcg| .p_| ].2lQ `;YGnG/J}.|C<%WuA@A,`kup'c5:jMIpJzyaho!}UdWqqe|ѧ-J6}$⣃k ^faG.7X$@umKY5@bͤU|:s3F=`J5LtD>?y:O=,O?z vmD%{"j3DQG<3YNUI`fױcλ'R&;j깖Np n2p5.Ă*4%3` M_~Ky Du[YBYgrC,-WUE| O0o͕N^["bnhz&5 %4:K[ 0Mj*GDSX$-Q[iI1{;K)DP%kC;FqI><Ļ*(^h"d$t|Q`PG)o(ϖN%" P h`uAО{݋:o^PEڞG77ujِ y^_VyrK{J~WytÎBS{"_ 6$Ӭq!It^  cG%YS蛄]<Č v0/Jm;-\[:_v,w|/Mu'OF)^FCK ?ex:kDCINW Op} o?cԇ>{ ^;z$?925)*0EL%~54[r7ʳxt~,| 2!#_AC޴l>p#!Xhhx_<_W?f`O])IN"1I>2*8/"[~(~uq% wuZPwσQ_ VlCU& _JxK=!A-r($E4.4JCJiLgU޸!ZDGW hѭ#=yL|N۴䡤P|4Vcޖi uL \՟yMpz>Df+ =  Ԯ=Ck W5: U~1{_V*<@@B)(ro0H H+KQ:+/ *مzi ڶ?NiP#Ul]ľm_7e ӻ(;=,Y낶|#ߗ}\_y};xۭqn/a0链o8zi7 5~6>O)<=Oj?Bc8 4pw}.:njW]ws3aI5Lk&Ȥ߸!{x , ['Y0qHw/00l5g8g?}|;tFF]=da~>x}q ꀘϞlGPI;2usm/#'GIn붏S.Ck‡qQ)l @FqSGw`kX*@G1V|s5 s><nKk}鈲 }mA'<=:tȡ|OtÑy7J=0gc=7,YƏLJ_ +gP',Q扯? Z&4 l=Ҡe{}ʕip욂fQEۉ2wԀMطU VV髋#_oFM{9M3 ~#`< :K hLVWa(#F.h`-@s>OJn#{꣐E\NF6smZ!F.u i!TV)WGc{~l^u@ IDATJXrPo7NC *3ںSPRηzJ^$GhPf ~B[ܫvܱ+erkG h'K zڍyK7ǺBkc-ajzG&{yT{j#iҰcCPuTɔYg;IfOұU6Ng׵\믿]׷.ZA Ci`.ڛpv1}c +z{%ߑu=]PsocvꢬC-%_j `:au?^m H07檅ǟ޵v?"fusMw>@MTJx4˷C].Sfɣj7FO,o`HPJS:b >甁4Y}KS[`iq:G&y#mnለ-bȢhKqNa($ۘOWd!# iN^.̅bGE\ӢxaFBSGZv͌C]擖&7?MvT,ۆܒBY@_^Q]%p`ukgU0U򧦲Cm}52=[Q.1M:ſay(Xd$q [ډoVߨJ-s3|*{OxQ`[ە%uB=>\\lVpW?מh01d=E&G) O6dخQYİ׷6q (4NM.3zE=OeWP22#'A#癨8 깇FچEhikHP|[l8 ֛TMH#vQzCڌDe3OByvLmQ !M0 pϷg CvW~+70h`X{f?>n [5~B[$+HpV'c9{swYm? gWKve%W;|Z9k-r $oz{u'X!N]{plӨGФ hNO,@ K/h Q7`=uWu]U:pDYږWAɇ| S-tE}?sgX9Z4+Y?!䤗)z-sR[߾SnT}",DïP0(`)R4թG08*^ kiYWS,hh =,CVw<`w=z($2~C_YhS8%~dH`rP l'2b 2%{y q=-].:]n6mFOȷ-HЇ/,#S=<y ;ųQ2N$FX O ޤLjɉ`[ FDA) nW$8\s LQ)AzQ0͒!/i8{M8 GYhY1u (-d ="P! o ?LH"Ǩr4vm' #,@Hax;!.Nn1f^Ő"֯B0N|n,3|;sN]wvg|x2*RƹI; |QgF?6]OewVGc'_#5H@ / [#l/y=i !5. ʟU4rlZ{1~} J.p 40h`]K}뀹M n8_s& ];Ox]>3ըEVLeUu5TJ=YA'+sm|Is5yݺq60pmЊ(h+natv,W| c3s=PKۻ9]^pHb~[-8eB#C9`t2<i[|سD}34ŕЌj ?z`b;NmqnBf kr}Dg'[ط;%3ML(׽2Sw.Z-vʂSF {$r#Y+ʑ@)5NI+~AV1; XW=`lcN2BzTʐX IP-#p^V+Uv:B; F t*PVàИمP>x~{;#"`\i̢o~P INj-&HDL<$ Pe5rD_DF>*PDmjez F=3+Rb)Rw+&;_^vdrDG6䈀KOtwb9MOS?zʨԕ92%(L|UF/|Q=>hikPҴYǡLi;HțUySnvydw^39稆.#^2Qv}ztYvySa+_,"D0zɪi?>N?@6FJ^S?>7YvGN4z kkM8׎cA 4pK3}^@=< i'vغ~-S ,#' 2X>.S#*<(}4;3>ËBȃߦ1#Y^^?$ |%Smjt`AO?O"u#ޗBժNez;$ vi"8rMt(+=eџVZ.្áGhNWuBtM^G@SQGwc P˧V^(*h bh*G~:j+$v}_ʭ-uFR(W2ȫ,&|p?yS%IkuE'ЩnѢsDĠȬ DCitr={(z GjZ1r)O/ie#0l>A`q@jATshXRyf *BpRMX(՛h>[/Aϴ74,WKȂl ˁZWDs79<њXOTi)l\||4r#tţn\ L(:# \I0.%ndp>KfE@<'ƙ^gCꙜCUᗲ#]Vbm>tu6!'Ox[sdzfҘ1NL> !{(>枺8C tRy]-lGA $@;m;)2;~@嬇O.;-j[iK6DPwS\+"^NHޓ/Υ3iRA(obkGLȏy{u2Q[hmאkVyà/_A 40h`₤7A6z2:CV-Gҏ긶 . zue?2FaG]\FSvU% YZO@Z ּozsCHQ?Jb>ngxh g6!: [~rߑCQf "uRfȼ~t3dw d4DIGY m7)ui)}{m/C_?6/yj0`KyF_npwZ {*F` y`u .pK^Ro:(o_.v(t$67G#C 4#6H`[ѨPk2v,Bj lQTg&tI;ӅhugL [ڙ&MH,uF ̱}\#,/mӍyzu'nW<2ʴ20 <hx؃˽DWt | ^]AI/Bnwज़Wrj 2 r4dU"|Z9*y$yL L^s_"nFZY " 5*Uڕ@G[["tG%t7]Y`) +IgT\=I J]:l7iPo'pZ2a[=lo@auг:LtVc=U̇!a 0eWa-w:3>A./'H~3";ʯe_5Я˔-?L|;:ƙV"x#bD;jh]rŮިgIϔßqN =k ^q4 kU۰]Q L9T;b{7wu3vfh|w>?kwv}>|/,W~sS|)>=ș)ݗէ '}fh.)hQd^qnXB.ݠw<+#gdSGV8%@,|;_]j0d3@#lO9rц|u]%H`6_d3Ey((ءè=E`*&?;^ga?= ˁ\hv^C4`$Bfw1;HNxB~nF|3"i70l]26}fld3D3M:Lj!Y#^c],ᖌ/qv<ƹuBx3@2P,,Λ} u(8N@,Y_Q}!0At|jI|y`)`G3:TnKr.`SxK9%{e>Ɗ;_Z%y|.2Oo4G\XpM+llY,8~ճO@?Y{k KWz=ut^-/g0̠YX3 ,| ɣu =i!y@f'pIk',IAwڅ C9X=/e _]:\;)+ } `}it0Tl@) Y~'ee} .ԉ;2rm~1 -G^n1Vb6G{҅V 7hW)1fFFJAV3|3u3c[i)}b6UbIE'hx* lȔّNu>P2Jta(LS !Ie.}7K>0uFg(9\ `p5uNLUM{ʘ/}QގD}<2`u%zѡW5BYaʰ}%Oq/ mDؒ2E{o,n=˴xWh(*5rzE6 j$ͤ(#Jf~=hIm'B#olŇ@/q }` :JվVlGF2%@1%Sι_ϒ*eЭðWGڪMg9OEڍmE|ɧ [u: ._.<3e}aΗʰALJ=S1ŗ< _^]kA 42e|]sLEE(b~a--@s\$/zGHg8:.[o/~qWDŽpp9Τ; \XoY28q_>cNs]<έm ҉$(CG8Ll` A}2T?Tx5?VMt<֩CO?_dP `l?0p2b=5u4 !M);\N{yf:vV3ӠNpmꪕdV;=S]ô/؏Z`zn#`3{xQӆ}-A]-:MC#wq=J9e_h@oUJ|cAb%-(X=tjIfNanׁ@i2ioc8@8E P2҄shV S ^ӶaZ [~ǁ YYL9x:]Xi!Ol911@Л;9CrG&o.s"XYFA .; N ]$"mc4|zG'-ˊgR0sTi>&ӈK+| E9(^䗮[?+xbT S-yN>(u=Z3@5Re4u0)Jm3IJȣ8,@r/RRٕ˗up-p-/V3ObMdm!֟0r&k}ѝ5xrFNYz=Zԙk)$)ԇء+Ƕb]#0bѳZQDWPb(ϚePNh_zO%~/-ybu1Y!<{a[ 041>@V.N}Nc8Q~їA]Wn}U=3 H;9a Vk)g@7[lї8~孍ty7 IDATLG@45GhuEIO'y1p FPڃM2 }̔~CM bsQE}\u?22Z) g ;|{M!1;ֵh lcȴ[y5cSϣ6{76Vq9o$  [`/zij2`ţi)dK5%,.pCJہ ]N@C]ΘW ,rLB9YA^%ïJ 46".lrꡜz>\C;<2,;ͲUk9ڄ&ykj mfB;3lv&g(vJތ ᾁ6ε֜faOMk'+A1AK7eս\ u<*βXqE8W018G`o|b=0&#NME1t,2*h B3rQayPoYTw3VmT˝&=^vC G8eȡ\>xdt@~!\sڝtYkHȃeUkGo+ "s,kt_ҟ|r}DJ*ӑ #+q !//F4+ /C@֗|}k rABȍ Ոv5,;)OT mF~c;Vy@W mʓm/V|0tzP#QbUa* DŽ4uFc-uiP@;~yX$9I҃rYG~Ur5~G>9K) #di+#>S[цУQBBgʚ.l.d0gJq8 U5p݇m_OY9xU\ ܍4pn\ѿw7VEt!=]mq#۞ E;|:AhBw}-[׆~UdǹT3䴶x{#;ut)k $eaW㑕OѶ@3sԩ_'8/l ȯKk@1=!a5=:XfԀ giUt$ RH-d(z~*,0l|U"u{ʖkLзL2 ;6N9 AJ)o' /9]yʎG+v{~{Q|CY^Y - $paIyRO'@^_\jڑ[G}-->u􀯬 93ꒋ}mӾj$m&wQCy-+c366ZYmL %S86v;#lT`jiAN6#Y\$b sMk5Td ʌ@2GM?ֈ׉YG!9K^IAO'T@@{(+'MjC @2] A(ki1T'ru2yx:cL-*V``?Ko%#=uDg0"8`129Ч:Ts8G@Z lT:rPA LW* v yH/?E=աeY.tۗ "_Gy/ArڌuV$`э 1@D])sda8 5/|}9 ޠλ︯aO 8=u8Mp $]~ѽ̽{їZ6+knid4=_?872[? &'Y{i|# lڣ-)6ȓ zw0) Ȕ8=!tG{!V$5F#xS}R#oku![!Pt|b ,g@-C8R2T֥Qg}*.L?Ɋ8`&PF;ŕ!.=0,LjgF[6yt`[k xOktg p,imÌ3s R+҉^lhNucpfgQ`ީuo[$m@ǶXaGYWngNcP^uQ3RraL3`WL).^Z0"7N`Bk(V$t5+,=!X@0f(#-ҊO50'%pM]ˠ}devlnz/FK`C)(/}.$օ'[@>Us4_[@]/Ryf3;r%XEE&]Fե N)rȯ춋`ȴ:Rɹݹ޺:5~8HiЉ^G},0ꃒF:DFAm*`] ԁ^@# :ټ aϵT7e7-:&%|cUF%I~hbhyӇv\3nh(yR- #_G($ਕ7F{̋l:̛E_@KW>eP8p^_t+HK( E\Ǡv]y :6h`N,"5ܞgYo:.EMplojzu=Gzл˂_K>|Ms~:[ɴ:UhBtCJ oKMF,fLV3e A?L9p8~g Xdڿ^|XK~-O޸^!, r1ۘUtS8pyS9 v+KXp.cCk%;#)(h~-GDF'UpC6{(()zާ\ X]G#^*.]^VۊkjܰaykUގS<~GG5MҲ~x_򉁧&@gXmihzCf w#lwկ8y (= DO$]S'-S7|t]:(m^4ZttUEڀu`Sڨ>noA̋vX0vIxlQcyvA 9ȡNd"3W}0y>dqD*>EԍC/QGӦR/u^?m ,ޣkF}ljV`F8v1MtgED 0 40h`XcMP㡃 >Lk te{ķ I,n==}h蚸߆ g8'/C|/}%-hۮo￁I:? $enȷENjCg _>#,0'pçMW<:RIywx',>UiѯV)/q>s Q7LզfSv`+pN# v1C)FKNaZ,iP{@~id둦܌1˵RY812եlӋݤ#%<)[yE)@FO F ŗ^>K2pz}U_',/m RM;G)d40h`A ׀3o߱8 U /B}3]^тVp]ՀnW gdOru`QM$ƧRھC\%}p¿`Χ21An\5|,Gqp4qxrqa׽Kk\9@t0{-⠥]BU`;6{?"@?֩>? I,Aw~?O|O_R\PW@ Ѳ@M3=w$jpO2u@f\C༾S,>VO|2S" :f5bb[ִlx=O֕б!nʦџl}fhYepGUpϠ8ÈHl% g4HU s=UffD&U, ݚ z=78 l"`g+io_{([ng[HMu() ČPuH! A Y.L_^WL@H'2y ez.¨cNMG;#U]k3욲ZvЫ+Pϒ{7uk{my 8}\.,'(wާؕ` 0C˳~of͡ObAڙS@U_VO=e}">)嶨NVǏ\%Cل[n ݿa9;Yo)Fi RN IV4 tQ)71yGNZE{BpΣ7ZN1+#Fm2%2P@4팶Ye@v3 @]qi=k&*h@KQX0)TVZ9Sח0!Uo<4> (W5T%\/ Q 9)QqoX6l{Vv s\ 'PE!͕#=ʘu)ɞH)L<Z~ja ꡱFkP,uк8<ڂ0M̷Ag} (iHXMHá]>~YƇ0gÈW8Lܝ|Q衫M[:|K;vhz:y 1d=r`Te%@OѼ|fЮA6`޺~}"j$Y1$codH0:YE!&RYHyHPYգ>69K3@ l0+? >R"_ d˃MiT0g:ՑPKN~_:Jk3x}8cA 475 ՝ͷΥOBtdRxVa8_@e<>VczQb}Cgi |t W-A\_ɞw ,-d_NSx4iOIئ}zs͡QrH%n={X o؋/M}z]N&)ӱɗ3РxQ@[Y(>lzւNxWJ5r( *>u0*uhs4kL2".=zAl%G Is<=A>|v42My\CoiT3szp1roxFoQ46MȖ@7{2b|h 9؀KK?x]ydB=WzOտJhpY3{. [u.nU&'*'udtvή @6%a+GYv$I"s>V"B WI9$#˃y<¤ mAd-r@uFZkDvxZ*x0Y"]#+@ٖjLy87D>zY >`yȼGb$e,6Y\=N; TzٖE;?UF=`4sX$?Tw׶U~wT\_*ؕ?A}#: &5]O*f0#eM+ّ6~ݑ [Ald>/ ;?| Z$M._ز'3vu St:fB MpUn{/w+_s/~)) w{ \s5Ӌo.j}ڷjk}C,+3d8ɩ8|p{ы^?/y9[^?W")H'z}s^W,od k@aɵ] »NViT@;@<o MphyJNZ+ - }ϫ,Ai*w@?P21zrSt$@r̘e3ɑ`tWq qvmz4rx*}x.Ik Qz1^kd;08Q h/3hOȄ_buy0<pbE`]KKVo`.t˷ku"ܶ1:N EJc!*um0_cTy, D7/}}9"Jc= HKl]\N&`*0e~}r+Ngq1Heօ3m`ѭ Y dxsYkZ_. %! [^L#Q&)-+իI >@G| * CcO43 Qz(J eRlDHc+`fæcc ؁_P(!R^4IUB[lM8w~V/׀a!Y pm`$J>A"+4-;4 w=_t>p!ၢwؠR'PnE: Vyvz/s,{#}l:]A}K٨V>I4Ƀ7S?/"F^N=}:%sɨA? czR@a&˂O=ћz]# {vO= FdVvK^GGsB+iG9mGZxm{Bz;LxFlбN_PrkWZjmk) mh-)_r.ckᮭ˿lW^ye{K_z;A?o?S?>O+"@#H;vX{s۾{p ꫯn^{m{k_{;y'\}M>H^$8O~h}{;Ξxt7wwowt.p1h`CIa} +}9֗E?['I`|aMs8e’ y6XS-̱;su!e9;7}%ig>[q]ZGV~ &k6K = ןb@"A h-m'>k >ꔡ~'#{6}H- i =OfgFëa-oM*r>uZiC9N0ۀs(PVf`F^ɋigI^0;ޖpD4y49qeL WwȨͥISu v٬J]N1[i23vn{:n~a @C€w.l1]!4\2)Og >nlc%YO]m[8L @I.-ࡦm( "ɫ|RJ0[%ļ(74TFy42&*"-CSаPdB|O eݾ\4+/ϥ <+.p*Oz`6(mZ ?1!/𹽇CV|i; -s)8,tJ ӿ|V>;}Wl8l4`Y;zG=²'lWF#=xt/л }yP yӢssZgd XMI=[s{O|szn:=/6ӱy+^V‹'>tҗ=яg8Οhgiۣ'>E|s=-OOO͵aG_~y̩;ӟtV=.4I ]vyzrx3=OzLŠAw {@ë D g6{^},I?_ s\N9(&/ P2_K 7+Ck;u=HӯHw5;xqκ~+%(IG`Z8V)\S%j0~V|+R(ȭ7&M{u!a#!eU˖ D\,owAeU}?v{0+DGaE%Q :PH塨 LДBRIiP̈ @ÔD,!UFZq3<~|k wB9Zksz}~QyǷv*OE;]/ K $@6ۭz- SO[,ء ynp:Žwmh.O/9_`O='d޴윟|ao.-S >d@2VyaJCcye1컈< ;.Hpq%V_[#ڽۡcdU 9z͎3BdbS #O^ 64ڣ܇h%WjȡdyO?TB3\0X6Qβ2ݏ7# iKorP~0̷(M %/Ky mCƥ iQ ةx/7FC#o죊'zny׈>#;| RI_Njԩ^29=b,_vs|wh?ѽG_}w7xgn_v闻w׻'2뾻{s:wo~˛3[o~ovw|SSG_q{fx<{=ó㯟^u?S?Y@ OxB''wyg|}z ra>WʯMozS3N>Ŀg*̍7ޘ< ߐz B<V?1Ya+ Ih(^C՟{6淗pL/0Pj<|>mhʢh蟶ہINmU)uDrHkr ?:vb=3cf+ H H[S p \c~xNJ]Ҷ8?eoR}hneY= GृӘF@0 <HG2Yo&SsvN5rvAҭ".nИeΰcp QD&[F 3~ m+&%lL0mH3BsŔLVS˜ ZsX0,f:u)9a0uXk i)neT Ҡ+'Pʋj+r/(d˜oX(e44GI{(CtQ:qW\0i#i\M>Ģ~ NQ ʕv C);6sD8)(!Re`@A4ѱ/ܨ_z%^aZ?hz&F#4>Flkþ+z}r(vrR3~ח}?\/ 3{XA/xA8?wf/v Fb'_9'N+^fگ^/z&nE-K篺gO}S|8. 7v{2@y2A!Qw*s;w.So'u]w;[[Wt]94iN>k_з31h`ϥ6,>.nE7v;;5.j}G1+᮸B0{}%Aluҝ ClWc>떞|F#s-[ lɇ"L&+_MhSg|\iV0`JlFNt,K*92 G{%R_H`}m;ͼwq\ؽ^3gFND'?Ozr>? rOtoWiq{04WG?}Cg@>9`~w~ꪫ>/=z׿;sL|^ֽ=ɢ~O|reexY <时m8 4H8f^>@N@'hK{rl0qȿ\,sQ4b(_I9ӗq?qyᤎE332`x > 9lgU\Ptɇdd} ]GɊEYqҥb|2N>Ƈi #w<:Jt|GtqyM{W)5C=Si}#XaBN\LP?,RՖO,<VъG]YXG22>+R >1B`/]Gr_.t3;EX~'yW ab҅HDy)2]g4~uKז`\,?\L&֘f"?xc/&hi0]ϝeyV;3%|E zNm*dMAA ܲ1Q`9:]-7!Sՠ9LIG=D,hP%`QyALAcɡ "y ѲDzvie҉*5ӗ$S)ᆿrp5K+FzOy>@C瀖oE9x#FLSJ@D"> AYYIn$YPpp+#H}(tal3hZ9@eEꋬeC^aϖ~_(F[ۧB &tv|*:mDm9Z=!˽ST϶+1ǺOF$xW6 FN ^]i/-WBŠ\Q{َ1d^7@8dK _\\سz6H<ˈVsޛε/>ZF@0|񴙋si7@ڮi&W>i[Kkkz!eʩ.2_;B*`ejI=P@@J>)e'22eH酳߇(vۺ^EGտ_|Uz}t/3ob.hW4E~}aU'^ssnp\z24 oxC@v91;:~'O_)g gȏfƇy]Ӟ2f}{xxzG\^ n(ߙdg_q͉vo7PntsQGCAn->U׵r1#f<>>QAbjٮ/Y^h[L(L ,p{A}Dys=ɠ5?T:F8ԟʏp{>eTAB5 LcYuq8LPNB$4;RWbBo`utlpb"~Ez6ogwБ󎌨N*{3|xAv}oKl>hۋ_Btfr6CO_P.lkSӴIA$` <o/5YCe||O<({h*9ṣRa=6i؀6h,Fi IDATQmwcmtT:́m(lA.E9ikfrlg!o_T3ƈ h?ՠB+%F2X^ضy ªVArJvz@:Dݫ0#E5w3׹DkhTAK%6(+ @q^T O갖˯=FFCKN H<֐HGkOT/ 䡀m5 ԓ<=݂MѺ@ũ{~2/&%Yq@]rJG5)o> g܃'EcG$ N-qs&JiݜC=$gT `U4P`w>t.Q,n;]Kϗ<" ʺ|1+39 /E{s{io`7(t~3Rũ!~B݊-9%<ΞÎ$pgpa뮻.; 8-9^u\Wy0^h<^~IA\ng@(_ёwh)=;| ~L9JQEf=};lH}^/">iZ^}nsoש \xmXnܷ l\dZufmN{eIЮw5?@e> ˋsu`jB NA}]PQy8o?T-SL5 Z_@ oOq9d״:P}x@w@=Ϲx}t|Ivy֑8wC:e69%8qĺ}ݮ`GtI0αJ<ڂ3E0@+{moH ev[? -Pv뵞@~IwzsV]q@J.Gt $p@0] <šOCsym*RЩ6%Ps9hYn_{p*ee?Rb >\%'%ӇQ IY&&FQW9hlCRtis~J$La4ѣxm(Gz}ܓ'2 z\]1!#,x*p`27ZC5a䍠C.PidٸU_D"״m;LHɷICe2Z9$U-RgC^>c) y*鈡\yKj˛_# +sG;pqm6NbiK6 ]m ƋHo*6yF}~G4_TLJB ,TmEcSA ծ8 [#GsùrpL3% #<Тec~mU7<=8n+3̙3̍O}j7_{̵t??]|۾]k u̯~K_ڽ`K^u^yxu_c Ws5,| ng<{ӟ~y_o~#Jo///v'=IK^|0]o>ߩf0\}GwX[[/KASɟL#1ʔux9h]%~tsi(읷/O#:M+ktHZ Yׯ?gImX`uoHSmgbFBévgZ:"U졋zVM/{Z-O vhdzu|3k G%4i +p ؎~GvtdO@\__3P 7H:PڛO6$i]d]tɷ81#zIGl+|^b`lxc歿s7{ʇ`*S*}/M&/tC:.Eļԙ<Qɣ* ݗɋzT{OxHGYr=k[<Q>M4s}:"`{*["-?JW{t5n8KO6}>`<)Vʧш~)iiQbk_iϳ:N2F7S58 GeY%?TNzzFkn0eA_L8$iR(r |&t hGs1&sj4P D>*lZifޢLB=ʯ4cꤌG@^0"|ɆA_uReSW%\K^ڨٶz&D)JQ%9a AaGkzm'[\ yٸOmdTe6-a]0ue_}$'o?~zG{^r#6pHyS1hK~+^*H~ j40h`W?MJytw|uoi@~fr_{D}cA0P#Xs<`+~8>S@۫*veV/ $ :w}bdBF<{^G{qz{mj|qEO>!/^4@3g'|`֕3Myob}/P}u ) s/ݦN&$4Od>!Ѕ ]ۀn$eI*GFmd>6a݃n/G(felC,#}}P,|."VzH"۽ Aҵ8Ϯ>=Qwp:e4;(Ø) bKv?GkkcumX3ġGkd!•{FgGJ@&ثGF&m#6M(=&ܒL32ψ#2lKN@ 9&p"X<[.`KFVPyz[LihPրM^bH2\k94e03c4C]yM+zt%=m C:)U6/ǛQ낣\k\G*]J.4sڹi@ӛO$aonIZ̥iaYˢLvU:)! ]ũ]zR|5e~L_ :}xO e`S fXGt| k H{n˹5iSۏ"Xu[4]d<Y<ڇ<gġ Mz]!ʥ$C1 pL}0̓VxVv 3TmO!?g(@u '#fy؎$/Υ[-s\:ٶi^\SF|]?^ U ?T40h`AЇp8E}yE\`|-_˚P0Elmpso:W 1_Zʃ-~vo 'ʟ :zG  [oEqo mY6\[)k@?;˧ F|dЕQ=W3zT&𵵩&CKwS]ހq?x>[ *3\WWҰGYrԜU/w}+&'z1h`m[#8E6<=hhe(^@^#tRw+9?rIpEf}`1dFx-HOiNX]?H.eJڶ)⩧:l758|$c\ze+yb AdFv#F2`²!zg:=Q?)![BG!T"yKRoF%w95tcwb HT9r56 `g]Rܷ:#9>*vўePexWzCc++Փ7KWc,ux] N] ˋ&3QORuo)иDMGҳe-Wo?x1+m3i#yMA>VPMz|(C#Շm*zmΩ/C͏:@zۈ a^PC%.˵H.p=CGVg]Zyeд)ӈx_is/<AW"Ytk/j/FE:Oro[Kg}}2oA 45>f#Pm/cV/  CTUGNwʓ!ӳN?>Y ^]qe]ԿFO9VSU ȼ /|Is +Ck7`V Ymv:txĪ?L`E7p` :/9w\ɬ? @GZֳcghG6@Q28@`u& %`Hp;Q/ (~K/7]][( ^Aǂ}d XH@On@;WïBXi%`bT8;G@O#ulVNY2u6ڻ!6Q!XB;O: 2<=Owv~( ![*ܤiD =F$5Ι9TiQ*$U!M"( mZLAIU("@hDVmCۓ(hR24=*ٔYW `keqOA^$V| ! Qj5>#HV+[U« c$a΂n Olth_ v C1́o5!>ӰmL}0Ghe1Q= PGIQaR|(2eif5266<V'd$2k3iyQh'ڜ|`b3u!}Ql9 Ubxˇzۏ2$InDyIM$rmA4J:?m.<Fd h9MEog0]` 3;[i ǠA 40h! 8Qo#[?|=#xm'Neu3gp+uQ9.n'f|/XF@z$]@Y_ F/1䛵0/zov3gUO\TP_S@l+{hM/>s; ڎ62-jm+7;Lٻ/-]o"z)0ipEpQᵕ9S rN%PgS8(Pן:]ПfeN?n;I V01䋞mbUG F:Z!`զPfڵNq՟FZBG-x-b*-Ɏ2_oۦ23K%+GS'pꖐ&vHt}x:z yomȅ,}vۂ0~j`$W>2`JE|46XlƍA/:](n*k:6IN'*D64,eiGܚk&-'=u@|XVaa'kG*zֲhFB(Iԉ ^=<(WnC)DKZY ()?wzny"0ߞz(|x]hO=IZjiհ!<Iȵk^bK7:wy*_&d_Ԭ@' @Ny}XW0Y|@' ҾCŹ0:4" H| n!N 4Y%VNI\s^ûSzY|)j٧^ *ض9.&hq\]񤨿@#uJ) T&YG.֧;g^eD<#7\cy[m4YTXSt a3@o[554Q~Gn]A1O㛫FFL(1tVYpSckJQgiGۊ>Y Ȩ 5д:bR+ʠտ|H5#ot4UquD=m%b$TG 2{i |v<#>@ё_fzi6A !(Ǘa:<">`~$Ϗ%=?ئn| ))_B}'!ַ4)3w` }au_Z'K[tM׮)4Ǘ]=[Y>`=PgtH/!G16bؔ훂aҝs/]OYn¥NnQbǴkDdԗ\]v_Ay` )^@p,gX}DL:'<;ݱw\#ޜk X_V%lW0]*Ctyz/#ƫ3484[_,1zJ ~`1{3d>A)ĹjLu Vȿ{GwZHep]WF=KpI:#;KBԡ/ON]=FC|SQϕr6"`H 9'Q}-%.NWpkUg/} h[vok󬷐-I[>-qA($eV~ŵ?\^`=wxwptFԹC-N% ʧ.'` }]yn3|σb$t&M IDAT E!<ξj*${ÂG$mUӆf2r!G`"p7Bd ΪPpLW [:S&`Q(]C_>o߾=R=Ԏr(G=k!y =&RjIʛ4 VγFգmZKRR1\Wۓ ,8W᧼@EƱ_"Ȁ>oOf`➻d{P^mTr (4dVt,DuLl,67i~WXySa?WZVɏQَh[p6ݕSwVO0-ڣiEG.Mmmkny-5/V/_xEaFSk+u*ys}WL?K/v $1^DJ_r*ægYYc%y CJ}fcAnw Dd!9|8m;@Mw>O[ä6FI7;~Ps!'+ 'X ({N-/Z\YL &I) jKpاEN{>WxI^뚺@ySw3 DgW7^E$P,(t|c}n /1t]<3zSGHCP}| bT@|c;3Uj9a; nin:ЯN O1mlǘlt|zئv> 藸x < 4 8w VW>n|`Щ:cs}˜:O̩$t9S'͍Zqz:9^Tb4}ws /~|4k0@Ǯ˧@;=Шծ 3a8o MG,öW_]ʩ:tG4^}z,e䅣"@n_GcD!GG駬=Ƭ&;G|sdHBLs|u:XK&_G=]1P)&n )~}Z 5xl/ߖJSإ:w%鮙w9mDVi㧎K #̛ 6Qܶn .zC64l~FFߩ–eЈ~K[#H?ڄr 82Bܤ/+nҨ <)O96'2gG!NYN#fZ`&I&pSeH#*-Z8Wd*Ԑ\ @SeR2m8 fcCeH(೯3iwg4A0\YJp'% D2:g$d^`Hxދ?0p Jm_ȭW]~Ewȉ>02-_)&>h GyѠ~n{r5HިC>#üˠA 7\]Γ /UxYMo(^R-7$/GfNQ=h)h\"/GٰnO[FIi8Ut*E뗌 lKC][zea?vdn  H EҐ'r7F) ѷ'XM:J s|[AΜ9}~{/AK < 4`Wwm8:,#Y ૜8+oCHv(ڱLآTո0ӬN?ߤ[=v\p0`bùwKY;o, ʝ ꔅ%= gI0`KI,sxf6*]08 @#:N(nrO@@ŝe~<?kTEMBk rОn}IZJ^b/OtOԝG1 -Ânipb2+&7 (tks|yi-M[V.L,A:^mOc?>֧E+E7 ǺeSh<П0>-/n۪_I.GL9 OG>Xni/ࣔ^B*хC>` O},#+,%0i}}k[jn{M<;"P>= cB5@k4 HBgeq$F^_ UF䁏Hң|(/8BA@SՀvž4VPb( <|Q.6 sosҲUhZ]$C5p,`~r2\ss)S#Ц 0Xq1ۆ?lAMDݪ PƎv&LN O 'v!/Wx'<]Ud8IIbr;е]xl"QY-;s+q kVĬiV>5f@Q:!IeT,m(Tа"RaYYY.brdF W3K)7 R 8'qRSw'`hV=ynC$V)gf`/y6c7'a@A\td*[:!ACiF~cXҠ0Pc&-QVYU /lh+w< ^nѓ: Js)'7|&_ϼ#s-TXO[tCݥGxnz*Z;#h$4X6/R shk+G^&իMo I+ jAy }2&Hb^C-rȓ>޵͆cA 40 ؋\s|) AR|~rf%{mMND$u9-:I+;Z IS tn ݆lpev<[ ? :'^ 7Ot (#Uy_0~-oSuǎQQgzyXBo Pu4dWGel3A31Ү鸦}T5|$x}gk6[,+(8b,6( lo[@(BCOE"P4_aNh>~+(.X)PNB<`NGI^\8˨jdpy <3\,ŵ߰N|ahXIFa@I~9ȝ/.'i*RfIVl lyRGT[9&+ 1iCE:- =wgLU#Gz@, yQ9ո7Yƒ/bOѢbXD|6k|[t.EWڪ߫3κ?%(0( - D POdl) 1! mnKuԯ4HcXlZ}2>4٭U'O=*򺎂Y[z֫g:,Wrd_T7`iG"Aoq]"; "JҲ|(=}@皣R;k܋aqE~ Ҷaq5 5Qh#G֓@YVӎhaL5w} n s>W/;Μx:3##I2A ,[ژop}n?[v o٤ /]Aʱ` S.8Wee[|cYÁ[i%[V)GϼZ@%ՌJ=W_:q%nF%iC>iɳօY /z-9Ecy[:I \Q Dff|Q%߉Jh"s0NM_y!w]ymsn,Ů6ۆG%BW v ,`{{d"i*Խ ;)#I-9;e٩< ϠA 40hB mte]q~`;U\6cX?Y.` ?%יf}SV\AG?,y**9PNUY=7, ?_̹SA]zR[wI]/F,#郪+݆=Wu!=9 ŧ# Ÿ![mc'd19:q2 O9թ[&'}quִ}F>Z>&?Np'}:Wv*CNeM4*b˪C87({X1*";l#~k}قy?v[ ^%85Kql c@VRtvW'ck}ob+>˅ͳA_m8NvړXz4 Ho[Fi m bH&BQ4{bdOSK$LxP/URY S:2 Z5y)GΑ#'<ȭr|Rft囹TC 1ԡZA_ikHQWU"#5؛>>`\`7>B7t£.[z@NyIQ%NIpS&<`[hY0Ct^-.BZ媝z>pt*߮u(ÆvS×l/Nyuee<R@ bg1AfŇvqA)h=lB#]y;? yA'#`|'R1ӭ:m?p:Y\p 5gXwK]AA.i :}ozm'ֻZPbuaeƗpQ2ϝ^x <N_>sFOW鞀"h8|Y0+'ӽ;A5 IDATWM_&> xN26.hCPY}E5)h#  C s$ߤmС ' ,˔3*җ䣟N.ﭟ?3r~|6xt%|mvP/Rf Kg7խn4=u'KS>] (Ozض6C&gN/A~H Ihr./+g] 7p0z c`d,RCߥ1-Vz5ƒ*^3^M"h~uV\׆et葶ʆ dW xzҌis+mx &f贜8!VSb,⸻]\gGfzd> Q60T- O! %7LY\ґYRa u? X=>Qo+Fϴ^7<EGQ&&: @]`jU>e2*:0x02>'uS XTd蠗/pg =PuN;snvh5}ٮ@ އ Aq%.|5zѪ}f> MIخ2xDŽv=m͇_kXN3Zډ9l/-WSo1ekةe!8D;~RSAw>$TJz(Ёy:d@Jw1b^RO-zԉ \ ` QE%Gϸ|;- .mZT(&A;V39 /Ly QߙO^}X$.XZZL a  ~O+ڕά,vM9׎ckudm"=˷{ -':=&.E @v c*#&2B@t NBjC0Uq^%Áy)ǐ;# [:sBP3Ԡ'ߣsܑ+-턈#@q'ƙpԶ>+腩,XQ?crɫZ=jQ\Y46cO!NښpyR җFx\ޣemVv'蜪6!<G7f1"}/2lg]پcsS9|okOy&XBix!LQ?\ NRl8^7IAn OV0iKXAA5xыn~sҗ/U yՑ~.&}؝=t.W[:+,6y1ggˡ^[$gJo vNmy~>h #nz)wIǾMZ2!^CM> Fȱ}.r|xF8, `y~8ͺRMsP=˫Kvww~.xWo/gq\B-m?Obt\JKN˻S&\ط]h:3{L9sb<.#l&y+!X +x1ɎAٓ7" 7pQ,Ƽ{G= ++pTqd#9 ᇁ"ź# ŧM2 c|NE;P]4G@'T|nOz)##)D$nܦ.8+,&g -M |ٞu>ԣ^4zY4Q9&%PW$.V!vm\Nb<#w߬vOV'Ȧȣx%#(ܦߕBZ|htAF4@1Md\$Q6 yGe#"#Ï纆Y'~/|neKbe;vki+q[Ck;.& b DL, A;[7YO8W{ c/ =:! `~);J0I+ ͊]&s/,HF<PQG؎=tB_YŊHK A̢MIL]QZbdF+,#9QG6AzWNAABbr_ӳj(]ZQrO?LG)( ?#@% @i)#Cc[#1 S.FڄTӀe%yUjP}۔а{ 2S׆=͹|ʢvYF0<4Uui6p_:i|:S=RA#<4\4y?bG{l誗#y,/iWOïNvOcM~t6GOur5C>=W|r?1a|-R sܣ0<Ȫ؈<2R.#SsḆրCr@ڧ.gZ!><`ku+?UًV% os x봇/CQiǠK\:K\AAeMp~[qtװ (rPzH-ե* Q dT-fTxpLp$~Ϟхliat}oO)~Zbh|>O @~uv4=}5iH_vMvu}̵w_@`dgx3РwˣK;w T#Z;~8|u+O{L\eLX3QنVn4 _ B PZAoȫc~ǺAF*<W-#*Yj3, ‹0X&d 00k8T a2+8 ґG>ۆ\Y?K)!!A+9]L56CY5>GG)B@˰eX!r `~s` 5P! $PLi|P5?4rIž>Jzd7VqZ%)| 0Ս05it('T{ݦNFޤ]C;bFÀb0ΣSi[<`^Д?t!BX~o;:lx_>_D%ڂj?zv:lwa\*@62 ={0a,oԲ{omO_^ 2TsF*͑ уKf;uY٫_PQV9>Äd=ĆH;jlF+#dLlNgJ[+0TsC%Cy@?<b~/1%4 40h`kyU=`0ߥ79rN~; THz2}{Kߥ=m lIAA3sîExaO hp`)TO~?0\ x[6t{.כMЁ{ל>]L↸[˳ԓ :%DG ՟Q UЪnEzg~7#o_:P6wL3Q״˃nQ' ~2rCI> ;N:[ ];SGDEՀ4ǩ;eGd _aS_h&;:3!hнsN$JcУʠ_dJ/U.[ukt),w5W3 y/Џ8BRFj fk{-F6N<y| Z^U%4>A5 HZ*k/a8#ьA@b>S܂N  6MZe-7@0OJ=*ZKϡ>(X 2Fd*B~[J%-͞Mvu$ hR[t-~uTÐ$U:춥4PՐ GtE2Ç=zJ` ;Wd|+1T<']:ѩ0T/&Jk#{䚲` > whhUt%WZ{4>Ӷ4YV{Y@pQ h#A`|%9#Q-<#2X]> N-.vz}M;|#O? } JKʢ2߂e}\; $`:eJ)=|3{#CJ$ߑ -A~c W#P:("Ի^ʲ br~@~y醼 1F,.QGf A;taϑnOʰF6},)zN]ԗ6w?LN]pF6}a#eG~3}$>0-"W>(hDkD (1._FEHKL9\ۡOxwܖ{QSwl :|«:m `4yul?S6:EO= *o}|کi^.R9}nMގa$L |KzcA 40 B,/*+ `Eup=Z{F`Kw* Z,*qmgР|}g 0 2{¿cQBsk ] P$0v6) (z]tX-c6 2v΅ .+n,@ IY\MT7^?C87 {h۲{ݾ{]UG#UD?F#M-iBgt?: cԡ44 ( cH@)Kyw{Ϲ7}߃ e={\s5>?Wz6̰rp#t&]8@=TO0e^u|`}(`AHq)%nR6k9ϊ?`Jj(*R:xwY3oau ?Ok41 -2QYA ۿ;V5>ckv ?]v4MFPv`pD[6iױ׵eHi?.q4I D 0G (3B݉l#; ӡ# ^JQ䉃A me$- j$1Dl%-y#}4֘@6!"^?a,TZxܧ)H_7 B=mEi]gpCbaI@gCP>P',Cdà uDkf oiISBu@Kup-,!Ooz̮C1D|OTzC5ߒȖr~ F8g]K'6!opGN2H.rS(޺#Nh*ZGT_7˯ԝ}1bcՍD{&༡VMJ}צ#o42ۘKC^|@Cp4B { 8ζ$%8htݸ 85aJ\t+sqlJy^;*#yL1cE2g?C\ ǠA 40h@ .!28R8~F3weF &;\|UG>{EXmF0w{sUշ%/y .Pwug<ϔ,uT _bl=W͇nF4#omPm5 MVJ܃tx\ 3'-xr}LqGym;1 D]3S~.>6o"| >hCJz`J[Jʬhжzyz07ȩN 8TCzEe&r&`LUF#*O2[6pWOs_.^? nr, {(yS% PO~V (3xXx 3s7B~P.<[7IYCz`[W,'?^O;abЖ/h*S#uxݫbl;\:1/y O=瞩hk%ư]m?6!R vx/7]{"_#bܜCUX@=E~="߹]] ߶-#tmpO>9 v徶/Y;ХdFSu+Tz"@rmǨتvfwq׷܎9˿|h=iW\o}ڟtT->GeJgZ> TЧ*,j P0M0ջ9}{i. w=q# ;ǧMSܢn: 'Rc%fa})zdQǸkQG̋oSwKKGL9ހØAp2k>GVm&>z))9+8zVZb4%|W}X&[C*DOl.(\G}6 :Y\ fxr.aV +%ɢ<1"^v4kޟ[س;"6`;MylJˊmizL {:rjzq{u@'0hP=k#R&VwQLwu~t"!Gy|}v.!cLNܕG$Gd0ڻi|"n*׿LfgwQtR6= W>J ʉ@ҫn^~Ao҉@7 \:IbGF aK-E Uj s!cnW^{x[A As4Ӗ.s|#I2i/iC T[|PCP<s e /b-nd^ot\MB/b[lyCD=@Ąy `G9R![|)+u9_k?&if[S}H-ڟv+Q1*_\DvGXȳ/J>3dq Y|pGDE?ggqaao |sk WI]rKYg?9MK^|?n]|q{̿zl;,~c2̿>ڿGCW\oM޳tr]|I+^ _"vι絻[{O$?2/3?vy}w}-r#e_|ehy} 9sf3񌶰0'=k~kǏBsP?ܮ|F>|=ox89[|"#,=3&{=8w[.@Xcq?}%XӕgV0*PZp/7˽9"EVзءSMN>"C1S>v7d_QuBF +N񊿴ΐs ;jC;k` 'U~{oo89v euO-,?! Y B$@vuP#3>$L-i\g89a-']ˏ_tmEյ=s0+ooSP,ͷ 5ڼ5#A *I]K+Xa"[V?u| .:_=R i3x>YQCM=VgpWKYW@b7;@ uC?Wc F_$Ȅm8:`cyI;]y GIi#hDqp"6!&dgX<ֵ}at b0xׂ)V:dLϨE D I'٨>û5&xxrx,>b1>|r*=t|T=f=R1& ðb"!h VUhLCJh_?OpnL^f QI {${K(|+`0P^4 3c)N 44.a(+z],CL6 hP ߴU$ki^L᛼~^߻.9H-ٮUy`h.E/?xsDȭRo<:%E-yPb 2Od9." !TWaTyi兺}fWюcEU,rV ǯ&@/A$Oڑk^>{;HDP%?;;ۇ*׿} }'?V?񎷷wW)k oG~m{ސgC>׶7U׽ߚa߯ڣ'\K4N~M6p7'=E/l|SwolhW]uUO}m{;K7>_ϩOH;E0 +/ǣ?3wӀ|g=_=y϶nkk <NI |J>c=A[wԧ>= 4p40_(8| ta4rf8DO<î?]PWt(>VsqI|6ummm[}}&+H=Qv“ㅺcKN SN{v'<}` }âVbщ[YwJ8)3XPZtﻰ)iPJpS ozG_p|\{-kg$]1AGhkjQFN[Qz@oov"KEX}VNu3rJpIV?>v3"S*Ҏ:4Nnf4~6n XWC¢[ǟ'AyWn-eF.Qp~1Ggy Xe 6VjǟmG!7""aP#^rLVy:++++|+Px 8dzC~GbWOY[ExN6HOO4uMCɋ44NIFJkgϿ ׳$D U<`%U^=V EDBfL$WtnZP*xH-* ?^Fc=_!ϖǹ->ݵVi7aC*!L{wub;i ȖmЪ=uj cGC˞ nX?PdïUB߈@.0)NɶG[gҌO }RuЬr~OCm0=ߔnj@Чm )S8(3Ծ zJ hGQV;zv/ ֕]* IG=MBQ;׿ mfA}QY ?-@OyI5:Hf U=zؖ֋6OJ~I>t6Ao]ZC+dRӨ6|6|`&/(=s-h:`2Az`o C륱4~Q=Ge|:PͥBtTsW$xCt:E|1XOyJ^o|Xj| y\F#"гw6urs 7__m~C__ ֻnP[3n}=yQbg>vrRTi:?4$̈2 @0}w~g{^^ >򑏶 H|w}WȨbr=iazKQ!//^tEפ=Ow|9 !E932׃  8_gX¥~sxx| g@n6G1ןXЏUܝZ`bo,L%n'Web@~ï\ .xW\_` 'klf٭72)U J`OI t_cǎb=Sܳ'Z/Σ/|1]P6-"#77ހMG~<4 0sYztW syBv":ߞa1PX*rSz]F;8nH6`Ӟ`3لD[X[Hs$O&Җ3 JJc )~E#EA_kja L 7gMs~]YUvwS,:Ȉ gK]LT~w+>Ԃ;$C*ԃ:ܦ7Oܚ|Y/wH }m)Xo(W^R{W堛Q F`Zo YwZ;[΅/$U : pnY oi!b^S)obP6"MO}=\ˬ;z)}[/ɪ;ëFݽ^9zlsW^(/(ɑ1^2dq.YhYG<3KG @cϹ!|vY_ed17EO}>1aQ>2r _ѩzAL浜5sM ۋ. iМ;rn,[vvi#=uF.Ӵ/$ptuR"m4'38iQv;ϻ<;CN%W^^hK.F‹ћnN{@١}ӟ&Pv_E]H717n&}׾wUywroM Ωoo{yv]WhG1 RFD|?Фt*'g韶s9g_^z~~~{Rvw5|svW ~~׃:nѷPM0Wse̲و{W#xp ߸$L],,N{\|}򺓌͒3,o8 t[otv{7?(29G9@QkDs$!N .8n?q$N]as'>ph6s:-E0bu^F9{8~"9p !/+/(;6aVR?ёcGB_k'Y~oUk:QY9Ve#{k^i{}{`&G,2p@7>6T;*7lagU)#X=mym\NEOPZAuZ J +DZsA[*aGnl-&`-,= IDAT8߈O~Ԅ5kk'E:6hI:! MFVd?Gw(~9(k|Qm~xDh UISw{v$F6aK'հi\#o9뢃i@>(;@H$ msQu<$eDȰsn)ڗ3 'el _Rvs+wsYbt@чȖ4e0A}8ia=޴փ-mGJ6lG>>4Rӫ-ؔ:27<; ˝~OeqQހRT۲w] ?۠/y^\G[!6c{??ۧ;.UgatĂ^r/"5<ˡYX':S?ljl^5vVJfirCh7|@j7?cD;ydO=.lM$ۋ*H~?C{v~asA+~~~՟|eݬ[29߅Qzӛ\=W]\s ŏ6a8]y &,G''_&w_2#/xAքp*;iO{Zi>o&G}{j*թnwk˿zއ]>:r 8G]Wda}ο Y?o 1` ^}YXOGZwt`G=z{Wקó"N?w||1 eH4ysmL?p }& 2O=#%<Qځ2n.c}.-1rn#5zc<|~{|ɅCKF;5fկXx@lg=*x QW 0s2(,Qst s sҙd_HԺa-j (,bx}hz#OPNJ4B!;D@iW3i*^uL5`gq5 nmLr hY-t;AD҅ZP}3L/TFem@g1f/%4`Ӯ˟C[+xj/!jȖ6'̀/xh Zޞk@kNR:ƔWNsLG#{xjleb#2un>.,\`ka _w6ʠ3pHy}fFu$?|s@er!'Mvm=Ene\l)62s*8eYS_> &۰ΟǷP|-=N8X-Cf"zOxn>|re/8?7Ohp'<){{{c >z{yK^%׼59yNFwy.1lx pt#M"*ÜMv{*APjFrʂ.b,8ógqTA@_|D|ޭNҜYoCPM]cbf`|Sp%tŲHԯw\T 7fhEnBF͂ոff ߤKǼEn/9u@?hj;]T˓8zķꦡ$8V$Bg0|`)5S ./dߌ- [+;%6ZZ\f~9sk'[Ӳ.:v24wFz,Qœ~sz+ln{샶UdKt6:iO|l%ӌtdH{L۬4f9ۊԝDr15"Q'ْ$/;`Ml'Cqu.gfg yƌ.HDĞ,-2|0/G`c(5EYv5AAo/~b}Ui9e5~uuq4s/HR;,re||Yf~||oŞ=\έ XwsEv k#x7);O-Y\I>|7yG5P^Wis's+9dzkn# )l 46&Ϯ zkuHV)ʣFFfBA^<Rn@m"S?duR"A"u))G}IO2A{Gk0h<knza@Ǹl 1D~6>o l iwAIGc+=37<,0KGۨ;mN=O3CKqļutitԑCwGl5Oڌ<ګn(jc-G Qvٛ0yO_ICl$İ)BԼ!x+L?gF!|v >? fS b?+OHn>6XC*9ZCPէJ5 40h`] siNO>&=vd$7 w$&k^ =ܮ{\u?I 6Vbww -]aeB|)}MVs~rMeh Bȕη7L'hY5`@{NF96?F&p:9>/T= ^ :eQA@s@~0Lj~Iy'"% G_<,mA}czjt|3OSA:@)n#ESsztPF~kŽṠ} xN{%-#`F.P\gzK w4t|]ls0:B|BovZSVgԮl솁rg=ͩ)v`x?3ib6KT9$ #̈yxP*bv]E\cv6:"AځpSvVLz<؀* B)=qL5)\dEٕbj};|\SOPIYU _GkNQ(xZ9x ea in 'MeC1L6u "pBtDt-xI[zj.$ӈRRxQlO=S?\n|R(KQ/}A)CYk,0 }B[yKn> ;.ႍO-NumʹA;̵_v@އ;W=KަcL!4-#]\:-ބ(BglY9O^aw@}QoRƟE:ٺ;A 45O'i}S8l.ldzNoA˙lOmV:"z^K{td;hbb &zv.@TmPT oEk'ڜS#SyN!vHڀPuvH!Nקm 80#$Ҡ vJlGBЅ: $$òt,?Z4Û+)sl=sN$?0듟ɥ)QٸW0O!w5jN]r'."sl°>Oc;7M_ӣSX-Y4n>zzSV3yz޹[̷Uu'ZDwz"bhhiމeSه 40h`^#Ar1wBڱ!ŭ֦)7+Z N0``(n@Hr8Ӥ?Ki f؍}0{4lrͭD\ludtG Ъ? = }qi)Qa9/zm?dO~rY8ʐp+q*AS'M v!D]kUz﭅ QfVM!vꂲSOkW A߀Δ,_%;uve{; K[(ڻṭԹ1G"v'ny  h+k- EDO+ tHjvǰ1z?r8.i%_0gNz)OEQVSVM@]â4РlP&TQ@ɩ1C~ ιdꏎ4a_( ?Nр\@aS5yiI7N'Xn@"I*4 9':t.48ɀݗF|aYBFS)e2{^ooڜIYʌδ+)C! uLJ#u%,!yFBx3z3JKG/t,&P/PSM"2<^s ԄyS^lBltȋö6a:|vLNC_ݟ^D%|e̋Hp 40h`AҀijܤ)C!MpB}nM; `g@:3ޱv;*>74@,ޡ߂.:^>| :d?~{C|8|,g?ATe>sJp0 t^o+L 800wFpK#u I0zy3+ G-Y ЖLQ^yiؕGs_@ ;oc6N N2O>ԝ@~C3lQ?5[-gξ5\Ks}mxv7/9 苝\E1`{ \}_{vENOJYoe;V%5 e^g{tm~NU!#A)н 9J ɪʢSQ!u,p4A+);cODvF}WljmdǬvķL YG3XlJgV!kNMGKLiF0b*;4@SM.J3$ T 5<u*oZS87vvMԥ'D22=we@9$e HW4hZBk$`FpSH҈N xk%^uYSz ڔ#ju?slaU9Ԁ)Td{1̦xa'V{% <顆^gu0+"KD*(u/TC4փ!ԯxh fn^ޘ6c[2y)󠔼q_2܋].g,aAA:A-37^`G r 3ޒ~o|j:YSy)Ƿs7Y9~`u@tow IDAT'NèakxsN(S&@D^a-?j(m<#:PA#\p[=Bu7DYH6ÿ2⳥j5`{%mC[/>s]GڒQ=ߤyBK5 c%w4sx | jki,>T=zw h$h֧Џ),"#+ۃL)-U 9jD Xs! \̟9k7tx$gx*ė\%\AF8z ڣDұT>Swfe|Qxf5=cI '=S`˜Q ;t>f+@| ,ʝso>m?>fSzqKm)b|\?ֺS_1»S -^f䱨=w}Ql|qQ#Ysd˴^u#m}"kcd;C,}|]U{mu-aD&6`oAGu]PLdi)NctCu٠2󸷿A6׮zL{V`,?kH,෗}ȍ a4ʧ1rR|yiͳ5/56]Cg:[w4F7^RpAK&uOgoAX~Cv'>?` 8];w︯ơ?#&{gNx|&x5_Os 3mi=3KΧ)|,v(G#M=Xy֟Y1_,(\c~; sR\n+b=h44r6 qĢɦ߇^R2Qy.w9:Q oG.ExxP{H` ':3/3E8uv˧ :R70u%|ar/mr'/Q6&z\HR cMx%ut*/: F„oyyڼY @ FPAœjFpMUig `ec|]\ Fjꁸ{ZjMv[t hXp:c>}ɱ0~ٮMf Qg|)x5#2/ q? ]?ay2$yvAP'.g'p Kh@b.$`B-,S1mr!aiR؜6Ya_N 'GGE?ܧ`*T's k; %oe'rϗodϳF$vZBތU-]z6_vj ]l-Ob DGܳ\o}*@25:HDb8 (稓. Br`GJ dkti >dIq7됭[)#$OzeKI u:'}@e=X>o.LS YO5\^@>h `ZH_E W.A 5 c(^n.=kOҝZCmP*>%S"|hô^{|IzK@BDz|;˾YO믿 ݍk_ Iu!d0fxzsJ;h;u]29冏h<8 w3)\↮O>om hpuɶ5|UKfow|:hAO 4\RoC X?l"`|zeWUbYGnZS座GHY7;۪EOQ//y{`YӨ>|6FߤhDx|(\A'tÛ_@7D?KݎHo0лr浄<[z3|z)og6{`q.byAl"dKy9Y:7/*ޗFb;.hTR"%T%$8&e˹2ˣ$Rf|e%oC->}~jzwȗ@_)wFj+]=A 40h`YŸ4 ~g޿ޛi5HgD(F8B@8?ߦ'i݈7H<!z pp|.ET?t'Ȱ.<|3o#0?ZmЕP&&o{'/+ }]5[{ǀDCG|;O}gF>\s̀ _7ŴڹC%L' DT]so'τ""`0/L/|DoqV-ikt Dj 0v`e%@||5jʓ\AGfZJy禹 c%XcU믎N+:,SOڰ]MH镶q=iV~?Ab` qR}mtf[lc9|hr>tcim з5Y7qN0 9 i-8#"x6 V8B=J؀.ܩ<0"9d5=@ e؝@]~*KԒϢA  zmL & lvt=0,(62+4^ԓtT: o&썦aoY,PRxLY2{^Z? h:'FͰG00ϝKKb`\/3y»IP6P`00Rj\Q&#/Nk@B:yXm^`-` C-/sox]3^+ezihC|&EGa[Sz~-OYiz뱙ô;p;Ix-#/l$#<Ʃ[HGmoC0T_#۪P@]1!rP#^= HN!o^2 b rUY-^Қw ǠA 40h'\->ݳ]`O'ЌyUpfOug2 `f| ߦ,w[qn +oe.<lS [[^ĭ~6?Ou/}j.@|r%jxu9^ `$ :l(my#>2ο8EOC_ZE!eiz{7TN.ʨo"}x1V)cڄ4L+?s~(eB>2|3p\; 1}U-Bt֢#r'ZM0ׇ} ikuj}3: ?Mcxש$:g;Ghxbm3nh3^5&!F>}{X:s=PO6--GvPfn(1^mW$ avһ:D3T/$6D@EEɠ C (r!S:Iue*O.f5W5|r;rY<#ë:@Ȃo:i ~gc)/Tx3RL ;&;6/H7W>m y_~1Q 2I'Ruvb~ZN[i4$^ZSsЀO }zxGoUiHQCi{~hw=U|HDѝIS L9̗/DG+ԕ߶&R`z<o 1x|C\m揋:4ϑö֪p]cbEb8 40h`Agi @_bΝ:pnG?O}׷㫌}q~;ïjMoZvmŝ.ʇY$|b.H,O\:^]TŔ=Zo] #,/o%+duomԞ{.Fi ( u>JtcfqX"J`hG`  ^| dAwl;ӖS ro v1 ہoAyQ\>'O`q=y!m eO3v2` K_`?QYQ5RD[74&SdrZ]_+Ymp 6љ f\P\_sOmvLy]x趦7>r|ndRuzR;ػh&9'P?koR*tL b8GS\NC+үtX{lѧ|کv0[]f؝_CԶ˭7^ yXG`>=sCǜJl~5>" JfLS6)R.ۅ!`# u>{4jc~,(c E m\ t$#/-= ;CYLn ŋ1j}>q:PO~iׂ’Q>0|O1R9>u ;z?PhS mNngu0=Np@,9iX/-_5r $8zeXWzLA<(Ne#C>8Uwcgtq/ m._C[iz ^r_<aLS0 n:*꿹E ܧy; P., F3^h[t>9Gp4ˀÇ@~R` /|/|w{c4iUFpym,LgEl'4!CyiYzlGa ;#*VNg!یdC_&^[ ig|x5M‹ :!Xb:6%;=C*f{bН GSw$azT@)|Y݇\rm0- $0<%Or| 0A LI"Q8_|wǞlW@TuPt rf yj0 y'4yW<>10<ԃy{oXA Ѐ/>諶i:36 FPa(#57^쥽,Vka%V_f7z/<4m$h֏=֥?^#SY&Jt<=< zm]Lp f8k@32APG+Op'0׏;6*`~䙀NHt@G7on)G^'#Iʵ͂}?M+h utC&Oe#k7[eǏC  `Bt,[zdPyծjʋ3)UdS d$.[GmRۂd^|xCr :FovnzP%{By%?ȫ WgErr%e׿Ǜ*4FK)Uu$|"tz~4Xy+ā.pTLp"fK=R2XiK0hY'3O$_@,w/d{O^TuyYO*t:l-yb3F;. *}Bo0$rH#O>$l׽*7e./.p(dpC GR, @'@ GF~HFz\uvH ƴ"EK[}z-OϲtZ>1B_K5*~iKO9|=2pzy#%fY')yN?D:60# HC;BXSs/[$2޷m1 tv=L"BƑ9 %} "E{T/ 7t}r9eᦶZy3hjkmza+n<<1h`k@c%v4=:)#̛?u΅vG -Aּt̐7կs_>*`ϹP-)vuzs)0wW6>- 7_3q5vv V9zioЇ m,m:(Au0TyO]2Sd|;?ZڡdN>ivxnG9zg `S*p=ǕQ`%#MtdIU՝hsl:6rvF\@Ok+zl1L ÈӬq'ЋK@# R~{;UvQn8銹AY e:k&+.u|| 9pcyAZ/ X\o@å8E3Kֺ jVMm6WC#`ٲ$Ăe̦|{NKlrh;AEϘ@D'؇Pt8Iki;5Dn DP_{$dAI[*whߜ}`O^w,ڑBqM%s ' -28ƽ(Mk(ܿI^xC6KFg7f j?eŚQ|h@Ԕ@@#mAOTxPTEFSʧ?\>$=a/U6(Ne8V"TǒG]CCۑH7;v0j僨 w}o5@<@ڎ~X"aiv"礄(t\WȂn#Wi;G >R(4<2@Ӂ%`N8U^$I;|[_=%MyÓ PlSmAhs126=?@y0o"،<~6 ^ݔپwP`=)++rĚخEfoB;+UAd#i]APA<Ŧ}fAvܹʓ/Ĩ^Dy"S, HL3+QTЫ *7a \z[b76T,psɧ|}7kWh?$ŭnp,o¥ѭښ8N !Gogcn9һ]lS=$O.#n"#MQ`;K+N Sٞn"{GλnY53@?f,p}N{7KpO-:_߷]ul]$L?oonRm@0zcPfWE>X&˙ӳ'j[+oe>"/>rY/mJCOf[I^|Bx;i Jo$)m v `u͋hҸ2[n'#Iζ5:{)Y~($8e g?({&h[V N*-[ "ߴ#cJH\ 7_~DS>M6$M rqn. I =>rx@CD xbD]zN:t(1$ bh K--{wX9z(b!۩6M@zh{1K5kSN#C;(cY4T[CS2BoJ9056Wt[dT.IAڗ*Z#1UjX9Rfz U(},`YSלȠitB"#=|Y6" xS錖jj#oFIHv\ oGt1uwD"|JPKCgm5Ҵ e);YIP|srb@#BA:%nP|uƄ>L[A:,=<YN?zjWiC'lcY~)edәs J>$7;6y> y鴧hܔ7/6ȍ׎̖]|ZM@6@U,1Լ$0 (trBSލWA /\/Ҡw)d(5=(M<%+rU@~xGkv20R0mki8 ,0X``, Zl| P}+qpVor44d$[; l%Ɣ)yM%ח5PGK' &N:o"#|S ߺsBǵ#@!)8bI0#A/>`W f;<2Eif:kjHCjpRE(tjA-L{?6ʲ9 ge#;O$ <=R9Ha+xN IDATфP\\l{mFէ\R|"76h | V",[<3xǯ9^ ~ nC_ycd'}$:EvF3-F*9~p$=EZ*'6Œ h'!ԗD#±wY <(툭 %c+BJ)*TLu"Uarfk[ N;CGP]c>PvB7A@ll7#:娯Փ'7h^:"ab tMDIhnR ޴#XmFpuCK!2)h{v5((rQeuH}DtPԉ[΢h'yRxvڀ~n ַRet,!(t& Á6BN3YKƟKת]EjSGQno EnF~l;-Se@>x6n[ɎKQ/wl & 88zZ6T}ׂ<}xIӪK{I9k!3v&9}}~cs-Ol OlpE{+~9o~sh.,2,8%.w[g>{hgn m=;l90Ls9sPck# >::uM1à^Hݮ=3u+.`A6fL)[+ZۂM*}ܶ=R6־+l?I۴,YG68Wߔv|*F>j?:ؗt "҇ ^%4Adz\@rښ<? ,QyN2GhK֓NvW mi _R]hON|>X˛[ xk]Dn]?&yd̋BfDdrx 9y5 *POدhg][¿n WYF } =w:]ezV{}+kt!Gq_O;[k%SOzi#dx%آm.G o~`Rs65j$a]yr<ݶm[۾};#wl}~oҗΨݢ}~7_ړկc{^{ޞڽi=Ӌ,\p1MO~Ono|.Жᎏ}c_cˌ͑o#?# oxC]s5m/%v}މ'ݪ>oٟMGNhQ/8RUW]nu۴[dx!~_n}oGsl{Nk_߇zyxK_ t=O/_nGk:>O{}hs#$ _Doܸݑ=YpǑx?sc9&N;-P7mQn44Cd=GpenX_-7Hʒ]nhpz.#F=ĵew}/D}Ƿ%#cF5}i>!}wB$ds@+w>wן mǷ4R`BIc  ڲt٥^g7_d8ϻ^6?`P:lߋO9%,.sdzԶuڀWKnj굾u6oǦⳭM"ά3J=Y@530me}WHCj}c^E< P"ff.p_JI|saLዾ7~fiߚ!l/ 0GPi;dS7`{mj6J~XWV &FY'%E<tHX4ĘU^4H:_RIr*{H)\i6,V&M@e:t5_ciPܬ쮟5&;jȩs*6Y#\qE/ ȣڱhFHe^_^ƣ̒ Ku")蓨0IH[9 ]v4m!cQy^˺"pg?eKUODzNݗ4G}Nrl~bWhIcg*=miw .J%biGByNQ o'NߙRJu}"Z%^NEڜQredNG 4v+7_NU끚ӞNy=-|2ہ{j6alO}ѿWgb;.Gt&=7k(3mA\Z{PG?QӟHgϞv:~pf ]j;wo03v~~^.>ь~sޚ~?N:~< .hg>?ghAO}:~{c1:۝zvWz'__3j/g=v ,FBo}[{vg fmoknzyxO<)7xғ^W<תz;ܡx%\>7A6G{WÀ#)^GG~Gf4$~7~uY)C?Ckc=Y-9\!m`M@\n@ / ſy4k]8ڛW Yw/ 1_) @킲ee|\u>6sXv?Tď"=R_tDjVmJuxf0-QSݔ ѝaKu#2[q=3խffp/1eDfuN< ꓑ`gbcg=ɶg;7vT4 e5U3aaQ[, mfelrK,,3AޠL\g۝6}md)t/7x҆vq (sڧ+;grM>{9B"#HW_.Pg|S@d!+"SBϒ*m$jiGޫndeNA$%]5 I:`B-Obe3oH*v7vq3GH2V?M&D(]t+X%k'bDҸ."MG%mKF3BNy{e,BГ|^]y}Y<=v-tDXb\˛M _3'%516kmMG Fޥ+;t0O_Sx|š6iTܩ0F-lL>XgOGHPdwNlRiGo4^̍`ei{IHQFt0*9֭ jxkoeMҒ!}Dt}(f2Yy "ei!@\SG:ҏ G1zQ:VRKkc1~~'mDbMp}e P)[/4l!:פG^ZQWGB6! \=w{͑oG۝??2^j.3r-W;S0eۥ,kU}ЃO~O9_/{i{k~+ڿ3۫_󚶓WxI_א;r}c:YO}CQ|d{?ǷfF̀#YXWW3uGj>gS /l "hHpy߉Ñ:= GF@@~<.˿K_R޶K"u饗g?@WP>șj> \i}Z]P92*P3eP iڮwݵS%\z6ra>S6C?ݳ~5yx7}VP` l8>lrL[ۡύշl'`-f;@z%7Jtn`_L! ];F>oBO33尮z mHZ%Pd B, ![ّ˴DyR?72t?vycfFohd ON9~H3! -7kI5 O#Y0?yVc[Sj/n!Iٛ;Tu\n82hF%8QeAv %FaƩ'M7%Jp" F)`1[c=QRǀ5RO:z$P^te7Iev6[Y|+:tԎ^ſAS F>T@x'ǺlGS~vۓo[? }C<$H\|I6;8G?:)c}8'kV}=o>v]mȟi=گ^k־/`x9/ :}ÑG]S?SA++^3}(;Z<\fpYge&ˡ3,0X`Xǜgm'{NaZoތoXW /yg'{apf,TQtfN)hkmyN<_N#I\ÑR#+L_2dyG=S&@QHK{Jo'5FWȧqlndzEW;lwS?x⧽"-d/!CFuNqU)F_Rt'<Og߄o)E IDATc'`93}\]]_//g?@}DZdDpF. p\>.Lի^n fQ9:묳q[NS΁"lCd=p=X``b@X5\tk]U:ߦ_(PMYgU0}J[jݺuSm2 foX ІA\Xb6Ml%0-T&MmV 3l/hkAďuI:})-2Tض"uWa Kx2Qp6 h0׼ǥ7/%J/y!K21^eѼ: Bxh\ iBOk73wr%N^\я0K6GgL~/' )F^xp""ɖ滮c[:v i+'i\ I:$2F0`TC2[]]#+l'/єt*NG|bkʦç2t (q~!h&+}W};AZ:+d!/m]5:w?}PZ(7?{)$7*_W\nM#A jl4bi}/WrmkmOJϵAknC9mGK9{Q͠a,hFl}LrJEsZ zg?NCֈ~Q~tv_?Tzw9><ܠΝA,:z+pӆ{noJ^0B|Ñُ|vn?/`]?/z{R=7M>O~)N]p<"W^?9ݷ}z"?v9di(̆d\~w>z$7tK  ?6a ~/vyXOVe8u4,0X` lkkC]fk~Nlb~wwčS~)2h#@z9 ]"Mq4y%qٷk7=|TY sz@UWns[|,+Ⱦ-Fl5㩫c}uP yՍ2^>ty! Zg&ޚej3-]H: &BJײ@&{P@H3Vh HqP:#ֳItm,  ;il."q# SdsG"5 S.;;X6t/eP45?&Ktn|q!vLN*t#}'}FiTT|t엏 PCpHݒWOBԌ{D{%Z l!bOH~ȖAb99  zbPT6(!^i4ZU,಄!CS!) C~:/-{umJ&-6FtXS?r!zOʯK uC>e|cY6r<~+Y(";{{.sD6AhvKdS/=TiImlr0 7u`Suў&ZVSN mr~"L90~T G,-dk?_&؏!GOODDwmdse뎾ÆՍ@rD@td~nB@6㍐Z c}e}{*t<!A;u tJh+~tnhFzG],ٽ{x@_Ǜ׵٥[:o'x\;3Hy|=}xlwv}@'d;'%~GV8sl >/mS|+K>s`%pvWQ?.)pwc. qc=Yo<7\,0X`8 ?đ`GE v\ōsmJFmu!X8g .^0KP~L/O\ٿIJm9l,ve L3Z oP6})g-J\ l.=̮Oq#!/ H|磎4C|#}`f(hg9Y֪GߙA`TIktF;SWqi/u_0/06@K` Z?`Ml? pFw&5`[&֧ 8'!tyOfЏ\0LжeR}Y'.m- Cl?$Albk7OL.'{y_fⓋ1ċϠx^$1D+vXJ:Ұ/8AeVqIw 4(f˫(n@Z7)a}io1S6` Umxۛ߸%ecpFgDU\[/x 6M-7K;@6FG˫I(*%FJn<:dY#]-;\"+R)Է<Ɣ .!nŀyMĴ4$,o勽ar+%@Tжt휇 0,i*|csuΪ.]hGSSېNFO2<܉e#xԫ6Ze(KiQ ڦ#c_^vhB/)oYhw'I=?]L eU&ە^bM/褾bP-o(2خ= /mV9 k~ﻲҺ=C)gvr?o?Gӿ}7^ͯ}kp0cOo~̣3$-g /lo>M7(7 _K/|[( nZ?>g[X\.~?ykս ۛǻYxm+hm~^Cqێ{8GB~(Ac 8Z[`)b9 iFWcဴI7l>_oZPh\ʅOOi}cg*qAIh!gT =Asjzng/] 8sl e_LsGz-_iMp5H.>olPnGU/K3 TrPR@|}4Gxh+!};tUf0p>tMop Q<}ҩPTX3QDt>}6uShx\ʌ' \!= U;P!PJtt/x#@nܢ1+Hdʽ1@rëw3ZhU4xiE"縗E$i.xF%W@GKc^0lV~>0KM}[G}>H$lvꖓCC\c}> D ]7-.mKE3<)fNxgiaY*?"Gl-NͽeKֱ/ȳ?*ite(MҫvT&*Q7&?ߝ5~Og?zm~'w'䓾$ ,ps^[ـYG3f| } VL4[5t A/[Hɦpp0 ;>D\` )ˣOk6?rw8AGOW2kjgS՝B]૯=2K}*dۼ)d5_V.(2bz?Պ>g֮ڮۺo`iD%Nw[/2mQԨ=_O=4"~IҕqesưR/TYPNߺՙLŧlE}P cDվ%R:kbXRҕ'oXعA¦m`!R6ˮ9Ntӏ8>"PT=兽YHcii/fѸGP1d hy kabmoP7hOd$Z/H@½cJwFm4Sa$ TOZhqx*eN6۲ c;KZ]yp36:]ʞtUM"Zn ԡlҰN6Y$P/FWy@oooD݉)wQwT,a+Aдrr 9bǁ: n@ީWĜA`p=rŐá<j]`|%<Pl/o$KrTgNyN5@Ssys#YIztdn0SXxcAYzЖSW"mʐi-W-(PiXIF}h׵K`JygGtAƶmOO;I z` Cw٩L޼Ca jK%PP  wFh;Ϩ,яYs颤pJ|n+|ֺ- ?όlk/u匂'Ȋ>_kkilB0㊫H>s;|m a>ko/gPPn:_M8q3;ģwքjNur+:8(w7G!M5O{aTjlH^t&ȁW=m_gHLdX-?y2- 2a]6% \,OUN\T} AƠhF]l򐄎4opصj= LNnDn1=\:WWi;lGPWw.o0UҠTu>%˻o2 Bt]G0IQL# A(j(4;3L9 CDkF2x,: \#1+T(CDX!`#&?oURJZ$ kiDrD>V2;לr4Ht S^NAohzuXܚ L@W-PFDWeC| P8#^w>Rk;`DVd>]yyI $2VAxp I 2ԑv@x<F~Br޼>ܽUoc[)t_>><v|E1`{wWs6rs˲[oV;ߞ<~W_~G5W ,p-&Kt?ܤowCC;:~nZz/26>\bI'r}2ol~,'%|oL )33#Y]hm + 4 \J@G)߬QZ +TS՜(lIap7laŲ^g9EooTs`ZڵG6rNo# f  (R4]I jܝ=]~"Rי i(4m/!v@a:#|$p0}vB:0]&{]g^G,`u "8 WA-0mgbCW9Bke)֔3[aT`d 6mL:{y~bN,Fؚ/Ŝ$(0ܼ NבNX7+Q˯(XZ꣘yF`Sko.r>WH&R/zV_%Q<%7_:!i琦o^_ HeРWxl$9 V1)yɺ֤Aw%:UdO O`J_V0ׇf ݲdAK照mn_HYЧۑtԽtd,PÆku_˶@"ُꜛ@z33Dʭ1hSlةc  ,͜V>*}Զvdӗi7uG^k_Q71pΠkfu:I7WݱHMdFEs8넴-dS^^=;r. ,0X``٥7$rӌbg~|dso}8vvԶvcGUl#^5a> #c졟@F|))}& (L'&ِ0'e#2ƀI9E F,9+ߜkGk;4 @r;W~(ު O_,p QOD[q`ԞtHoQw==apF;M\)}e(@=C#ĶT^fA&}A,B4جVމ zrF9B^R_8_.\[fCe0QR-_@*җ:}2Y 0oaymKIwY $AqFHJSY}&}%)tJvP4"rCB/@h T)0`ZQJTBԻ2I ( ƣ̍D&H/Ys (EHWr&*P _J]/IWg"3.б !Ň'3"i Hc% IDATP83hH:n[E0 ]:d轍|x TǾL7'`^汇IwQ8b0$F\J6#]6GTvaLԍة '-#tqhX\^ 2@A6Tn*oy בqsؾoDlQVnM9mҖ0g%?ƶ%)@:2&Pٰ?"wGoh`Ç~ʭN])yQp [rtn ,p@6t}b3e6@]`tnG ׋s4̖$Xiq9ߪc;AW\N:.Qhneo)Kx?t? WwF?ُkդ[u@?\HwHHdi3k 0\60] .>b (C,)@>pb$J n KN>O5n9Nulh!&Ԓ6;4W @N8&d &A6Oa97hr =e~z{Su Z*WJ [j'O (uĽnڲGt@'e.#T4/ OnPXrPDA8ݰjcU=)^Fo!ܕE/>!˜~mNf}l%f*H6B4C5:D.ghW\q/놥vpFDf^@_j!זN"v7q>s!y;X&k[x#"> c`7- | ϸ!@sd_QV+8n}M=% ^'Ap$Pnپo0;)h&o6A>̖mQn[ڂ+5U?9?3">%*~TO2_Z4ͦl?鋪T)v ͛f3u1| A'޺$ _0Gz9긴Α|޻ŢmeLKw慶eG u. 0p`AhȮ7tݣ-3+qD޶N#6W(D tu=@otQGb;gI2;׶s6>v@߂_plv⮐&z96m̶ B.Hp娠6e<}|2q}Eo fn`Z6\fi'ʲl1p21V=-aa/'?MsDo ,!!YYNYٵ]@|hK~r)m`c2&` Ŕ"|Q^KOh BQ> ߔ/aQc%n^owGz÷=* :FɎNtՃ9 ?rGqCؘ;m>6V;tByQAKh`{M/Mp am%?ՍL>}qٍ2ɶN@)ݲi8}HfTbd|ަ[7`$GszIr5ohe6t"6!oyL!W׏ [7V'&J[JKW/ldڹ$DFȒK1mұ_fde|5b߇Wj|}7d+L-7E|}9ڊ:`I!k "sYٻheS"u|8mw(*Nhwٹ'Ie4F7fܑ]ww[SK1<<|L5񠏆>Gӝn}g䀑>`k &f8?`n7ƗNqM|}YWчW- HٴQ.Ʊ6aҔo4ȹx@]īh8/ҝBm`^- @oG{3x;gf8;1#W ݣ2ۀ.wv/ং.u,oPve0@2l[,`kC=<T4ۄx` $  |ChߞdxT{MўвOe0t\c'>f_@-6*K>|3Z컘!'mTյLi'K.nIdGxš: ((M $ M@cvҍӕ֌7@*cN#vC |Qb#tΥ9j~'`j35CxRFH*SL}w OufVCgYa0uyP(i VD<:^ر:&ykW"iM^1_=$.iGћJfG9 -Bv93DZ<߱zJ)Yٹ e?~t2ю4`'*7 퇉4`N>Ї>}#絷MC&ʃRn^pnG4qߍczf7.wGw L PW%jGk:"PE:_^:TG&֋ yS/˿!0eSAYq+~k՝Z p-댩2G\r@7Lvm?$#SʟY }pcۋMMr zҮ_էO x16vGM '@lGg*r / xZ~r:7 Pt+/K #l! b @Ɏ_QV CqаoP'[U|D?/%#޸i Gvic7@'9N.ȟ Y= q|g08`jpHO8%. 92h,rOWGş*Z%nU IX{Ļ aI0W6O jE@"@^9W= Xxj` ͹w vL جܴNנ40rj5;ښF%嫨ȵK֕s9 -C.C%i= )d*?Cl4'!Cۺ;+)uc8> kT؈N#Tϵtԙ A Y&Ix({^@tT|HZF16HMyCCS-?.+r ,e.ԓQnFm9lؐLt.O9NJ6L5( 8RW ]644.βeccm'Cc[crn2CdS_RUA!JGdd^s&>Em0n;ޱ ~ص DQ\@ىL_e[Q|;Z?K/:e=WAkPA1.>t6} O 0X. юO;eDW= zYPIz>,DRάq&I& TO en{w3z-1x A0l? ׾&t~ftϳkQ){f3F~q_L#sB$'.el'?gC,9"a0cw67b UAI6J M.fMZdA!Hyy6cfA2t}C ܀0560)-Ͽ@k Yo=-Y6Oyg#@ eX>u#X>ɅFte7I3f ){ oL nB4.0`1=6_!u'ፋWn(- pM!Qb T h[#RKEckg:%|u=\D[ pɛ9Ci+bƉF=O' enfzh X|ґiPn$X#c[ν쁴7lC42'~sZ36BtnҰ4'}]I[az '.] xĮ֤\bG=J?:P6K8 h yD6͑ pi4rwFs SxR%:%ZLtA'`mۛI;Vě;] +'rF5݀Bd(9:v|"nr@a⏯0Pu Up ,0X``kަV[Me,#`CQug lv܍; 3jV[O?FWE?S%09z,%rR.}O #K0_'R@2n6ǬٌLk 4Wo`8g=5eX>޸{i+ jZ~Ⱥl`kutu[ޠ#NcqtA;Õk?OA䠳 1vg]均> ҜE[_KV[٨ܐW(r rMƁ{m.p! [Icr:%%y "L.CWe-we]2dRV S3vg} oL&ڗJN먁oβ fw62[ PO}](@/;t윃iC2!hS`mQdGM% &AxWNoNyo(&+ p kjɠ!Mf#841Q#rBEPlv 唷ͣ _2+*jS@cI׏ywR$E :R Ey;  C+ߖSlgJ4sޡcGf#v~,R$2iRO Ҏ"}&AZ&i󠏜ڂכ1|HUZz3ugyoUwnw$c0, E@ʱ UV$!00AaW`F(LRPfp(l&I;v9}{0pI9{t]SmbucrB p&)sU1;T&{$;}r 3S{kVS!Oe Q?CTԕ$P.9m=x Wxb+Vԫ_"ݱN; 4N; =|m]nA8"Ae?85Fk__qw&^yD£nrf;6>8l[У_%4IF⑧ ACr}*k|"r~|i}>o_>(guF1 @)f>q6M.4XDPL MFէ]{ IN/$Z`S&)z ̀K7II\3%)"me( /J{Gա `O% BC}\`ww0X?|!Ab;y= o^X&!}ewH 9Ӈ% l-[-4beޡ1ty,w׆fNmPaAWO}uIKVU/h?37Lȿ D3jzOsnZ6zG^n R=LXyv7m`>p) 6)(@q:]LN?uls®ݟvi`viTmj>&kǭҧM@VW"8k l|Nl* f ,^`iEvuõߺON7g#i7p3v]X/N׮껹_~2Zoy:&YZ*BoXQ{L#o9:xcϢ V{m  PnC4n:zPy7h5pau h~R d؂ug[K]|ϨxZ) Mt*:r}ӔrSMO5Ɖ6}.Ⱦ `ȞYlKpobpҷq\CWkI{TM.#&]#p0Y F#{۔#*66;)q3}4ICK0rTj,`re/ HUp000AA 7=f9tY:5h`]@#ѓrԉթ6qT7MY^ͦ=\ֹעPM⑊q~#~ ypK[>^ y:Zu<44]凞|KWZ&Vԁr7BCv.'1~ՃQ|DOi6SfdC|@^lBYBxtW\`]7vƊpz Ń?vɨNC\6.ma$ٺV^W݆^ K016/ćP?ˋD;AE6Y4N; 4N; 4d  UgvVX_7s\PC*|߶@M*&Su_ហ*_6zγV|hVv-xM \GNׯs]7pD#Ԗ#p德{r/dq "}CB@Z;@ ZY]pCOZ2hPg2E IDATS+*;?UYEAhHAzWq~߳aA_0Ae6!4Q!f)&ְ]~5y %Z6)sGIbLp۹4΢:Rڛv_tz}]ӮY3d^5/ڶ Z66 -[ySx!7Bh. @W|+qJ_sl)'y?t .Sg5+=h h%JS>uYJtKu]8nvwz@)G&`7U<'SS@2(CP'E=4kHglþHGw|bk=xFm"}xfv!.H'[Ty[|2{x_,l!G ;8@3y'5.c_#|MjȰauk24w@op?d| pʠM437 YDB9 yε2t%& x w6]o{l 4w7gTN;Df*y-|l>7_7@>w6Vfe2YNۿ#ɧ+-k¸i 7ư̤Aj)ރ?dY"#wQl,g cm^H+z (ʬJevwG;ˤ ¨7dΪ c||GTL|Hw:p+嶷#NTVA0MJt 5:HEV.,\E ~E/~+ I#xp9J|oImna8AL\i$z3\x Mø;/}e,|٠tVP&H>~~E~KqAW\/N9MnfK-e-,p? խ]o3 Nel~Z'L\qGn-!~s <ړjX/>C3,3$ "N"BZ }?$N|7Z . \dp C,JGѐ] rn4ЇI@ : PDcq 3# ;AO QJ+Uh nu0AiYA s¼[ n;8R 0!hNβ a7]z ^s3 pz_̇;vi`vi-/rŃLǷ_ eCFuy7h߲NwiKE𤛳[XNwFΫ3uTY߹ vZ.E.ݙt<8A\H:|nkokAV~D HȻs{ԥm5~\'.'3AHZ҄r#qX/YGJh~HkC{M!#m ]ƗcG%!N[p=azo\@3vq?< ̹:Z5> 7}gPEChvx o97hxt/,݉a8ɅAɏW#N,`]G#N'ij S6pXgVG`=p2|hKB']p=}mGcbSp`elɎm7Cnj<7` 2+D( 0}o6A@^a謙l׶ CmѐN: ~e)9^헣_[%~6|? MD/*4.lpO6,]CX~իoN2;; 4N; 4jGY9\uk͗ĝpd62ױЯtH@f|m p Lǚ6Cy xb n;ވ)~ox% /1y~`#p(kdWπ[lBCA&lS|9=^̙zrkvDA}f.}%gэk bot24+;K~Iʘ<'=cEvǥ}=zc1V.(Ĺ l T3>puypr mQ~#3=N[cH<$qtԻ3[ӋRn 3|hf$ Ҹq} )3JLvHy3ݡ\2`0$ 0 Π<(rv\eyJ)t%Ԇ:Hۘ7Î /|u4DeTvٲ K`}ܳ}dLg0C#tZbmlsV$G ʮQKoFǸ~\#R,>tWZܾxR2-?S^X9k@MH/KWwpӑ<`Mt#H҇vuRot74r!?~dv6e7 - {.<7u^Ej.tMFj_;d?gl`$0> C^KGt"%5~k%rkcMCM˷=fys//[{>XO7\Dwxwi`vxԀA~yo|yOqwI޴C`N)GOZCdN͵uAAK ܄ϩݺ4Zo6[Dq#[ cn;У$AL&r#G13>׉дŋ޾Qj^g(8.Nwwz#񭡄F~}>G};m+3/ GN7l3=}MO 8n)@P'q` ݆o9mB֝^y&9` zч`Sp۫1pw Gi}t_o˟Wf8y(֤_7?ep6/:F{xCYyr/=M}%?=Ho7&\,%N3hJV%|գ+pup5c>lc'iL_v568$/B9ʌ  ֆy뵰RRƩX@5! a \^TFoG䃁0CMQS7tm'M%lM^8d伀0tŽ *xPO %/_\ Zt1Ï:,vK:wuNe\|~(|ۜu{}21Fӎ|yMup'<*kڰ EwWg}hdl]aב5TK h[# Im{āk:P50*TimZWȔQĿk] nzQgPlFyg&K$;vC׿7t.DV8 &v' n?YJp6z o¡ S>a`u8))fmKകs CՎF_>GHEB"T?[7GwoB-o<|pbcӏ@a}fDd ]v>Jo`h8_?hH4N; 4F4-GPk5zJy=ǔMpGFPy`ЌsȺvGHp 68_g $f9n~mkOGz]=F  \zvqq\9i Qeר8, >@mt]p\?gͿa! LBlfO9z/0sB*toyGO_䂣wے_x}# tiӼ]$ /בmx^:^7Zbӣ:oFxOQ7 ʅR@_|+1Mҟ+_T{H=H{gclE'$i/vr7bF`fb1+&08RBUAPߓr 4VFC|*؃ Yyҭ4kGK2;npvY8DΪ{یJ4h% ^k֡tZ*NCMJ@н!d"k6Sbto;wyCEG0JW>}y`g짱J?'jv4n:x%eܖ"LQj$Iw~qʏ8,MݨQ/$/a"[?Rwtvi`viMomt·hy> h } ߖߧ?B b3b#o`wbA7Cs .Qn5C&TT`Ԁ>?YDzEr;D*<˄nm ҨNQ\W@YV.m%K@\5p(x-p9Cɋi`̀.pςcbujdi޿heυ7`\?e$KMi 4M(!'5(wϸ]3Y'O[?-63PxuqĴ~(RS< ǷūK$nYXh6U˟nԻ `$r}je$Я nn~Vw= Q` o 1\|3fw ֍]P\_k̵1CRuTk01K"׮}˳}j6Cn3ީn,^ͷ6&kuޚE⠘$;1/3g5?(|wؓZu`'o>m3l *C>:Çɇ/_ LvN{wr~%xIQ"Ynq! FtjҬRIqXXEML&+mgaM?1IXSM'ٶˇWK rƝу'Pİ/#3NawtVH?vQLn87ڪxe_N]C}F]MA?:>uɝT9mqtu3[=0?Za%,%ցY@ԑ7F8Y[dȠ̉O݀թ[7IG}._LyB@6C:B3Hԇl+P;j%^ھЀuN W4ܦ[vMqgO  \kf3kM]:E+_f2$> ps [GP{$|\Ch,@Qh9@䛈05.}"Gl Yo(#& ra!'/_^.SEvhm g,mKmGXLϲ!:P?M9m71`"G*K0 5ሽ!ŒwA5x)s ϥcKw൮ϖ0q}˗/COpr̆yrF۱uUžnnQlm5 &݌/m& %gyU=>uY1sQn7ʐD4ER[KN)>8f$L_\pbg˛JpƾVX)G<CI .h= 2"( f  ^*AiO (Ð*tρU()m>Wi߹][sHvJ.8ʲс vo^\ï!zӑQIo4R?> =Gl-' s zZm#>oP`%bEd~Abq$%^ |_yALJ J 3𒳄бNnI^d.C=OuCk@W=G[mK827} xP~n>ń/uԵB'Kl2JNhoNۑMl#lllx_ԙ, }ӇoHG\iN; 4N; 4j@_@ӀB_"g}5 ^7AEae_Ɨ0X|1|RSuܰk @DsL6@瓞dP^\*ztС pD:5^osۘkmIK *c_P,@u0?tׇ}Fق N ✆MSfv@%:sim^g@5Ar9@x{bӻ6Z+>a~ \V?K&`7KZF4VjFg}: ѓ}PmeUĀ'G Q"0=+d] ~G]h#3̡WRد &Ϥu]Fyg96@+ҚČ ӥ'Ŕx {jmsER\VQ Ĵ :A{Փ.ώ%(`7 -镅AZ܍?R`"yuz SnF ީ ynK.f;npȅob0l~,JjƋ >;-7/pBbF:[ጯ$a#eD37ӵ F%ӂE9E%n 9fcaj{l 1p.FtqLƟ4 O5Կӟ̂'8 Kk;Y>qgd@5;^}vƾFW|;Aכ[ʢ+ Qsrҍғr\"3< W 8?8tJG{"p>Ími'[$%9ƳK)l˗ľ8?bg$k?KhvxxK>\ѭS쎝vi`viiЧ7֟Хvw@W{87ͨkM X!N"\;ם&0?;>~ r]fSg9 q H<67WX/_Nwc>$'ֺdqԇft (Y7&q+¸A\)|;Oϫ\[?.!t]`3 RN۷ԥ0+߾;CslRIl-y]gm'-Id9cbb *lG|p6xhO348U|Ul}b];2;G9 "рfZ(̊ 7Xw/{H:Vzr \ڎ x@6E#kת dK̈k}v=8?Fb5WXѳW O^f_p$+0rY<+'1'7`_ *j&R_Ѿ-fDHÇmyTW)Llb#ޯG7%{lL[Z~~sW2 ew4N; Mh]/|o̎4?)PmQ\j/Lzf 7ӴxsL7@&!$S!`wwW.1`b+={gcDؤE#ڹwl^FzW3 4w緽ܼDdt4h%\` nLk-L; wfom;n~gK N&#tu7~i2Mg\Ctٖ,1H5=A' ]ϟ? Mй*;<ڧo#\O&|Lܾ\9dWS\Y'F+fC9j.u cO)xԵvV;h3MLi0z<TGTNNj_يCn.^e)Ø셥 ؑb=6<=Ci/&KhIZn/pvOO!:3}@ k4cp ``=cͭ.L~pH0S87P+@nA:PڬPi܀|jCSey. -j=4\ .&zfVaYrkT(3Hu` 7Xe(@!2cukɽ/ovǠGj+/c$t cxPsd`X@+j:6bx:Ry\uT mKºmZM41Iz!H^r}]GwkmenTlڎcl6y9 P,`D j>8^7T͵F.^%sw `jgzf5 UkG2zܯOwrC2-BV)C7|Jڈc2iu50lKSH0YT/SϿ}_]zf#oi`vx ^ڇA'WGq%6)N_u$~#}Zی~ &0>Y3I JE Zsu3) kCx`d@GF{78= 3) k (9P*搟䁁wN?Y\xHxcc|3ur?{|4c{7[Fu {O>ym x n"BʟO%7Y\8ST;ɝ\.Fcf/gFp ~S?n7]ԐM_ߔ~Yz? 1a_ƘkG ,[\fvt\NA7?jllY z7ow?{sx?~mxvS`)S|1:^> gm6N^ڲq@۳n.v4*]+Z`aFv!F궃:{oJJmVqx`Pވ)YXdiTtKB#3BNq7~;,^(S_f`'OeT;Y -˒ . >& i=Ѷ%dX+X+>a7E}-G1¯/Ξr:qʓ}E}zCMsv{@6M~+pW^u ڤy*5rM57U&F$3ScM{`K<@|轤QzyD\~SyŔu^qHp]2k"D7h4jCwۿbɧNl/!~?Cy[H=#G}Czw?tIV-M,pwUj>xyx9[;vi`]W?2_[^4?ߥ#hgS5u-NF!>5~#|6RN[@WRﱉiEyg4NF )"mq Zo<oxW2!%ynZwA jp5R8nc#o`>/7 B7=~ƍC@p\Q?$eNW6_= ~ɗU5*Ӈ>;bIK69KB}_W7K+QċTWFcՀ0 i(Fp5|o,oeg+$ { ZCXKr=&.#S'^J? pM8eRCf~W U'്4\:Û6_xj:X͆+rqKK$i_)2> )d 5m?!H31&q_a+ 8;: :|wOP 4i%L0JX+u/(PLgZ!Kрt!, ʱNJnVi G fu"4V‹p !K:5rw/Xopftaln\qn:j6H5:3~H_}&lSn}M;by7x;CZ=X>[`j5!`Ǝ IYlWo NUc>|ź60_&LGtz:⬠߾zuCmdyJ?ɺς-ӑl>/4s>2YBrMtmu<<݈qwUj߾x`UNvik@M=&p$0˸&`GzxN' x'x Ozݣפn眺Fwn35Ae G?e:Uܺ URp ^);bm!⑮٠ ʹ?b`?~Mv8.uf\rȻa1>m|3qێ uj^pxTSe@/2Q)yˆϛ<&,V{3dyכ#eP҅3Oi&x{p5`똽 g?ɁfIǰC6nqiWt`2⭦s~仪#ea63T>goc;\;ۨ|d\9\4ztUŷ] bF}_gKWKCR<8cƙǷXzmlbY.P:ϺNf8Kϰ wa}rzŅڋBZ$|?aij!4 O ȭ62d/x^j̀}2`{:ٶĥ&ΕE'Rn}4fk3[ySNy[\MG~}K30uH}[vIke 롍s֥c!ΤߺDIN; 4р~M= z1S/]&("(7Ǒs3r3x ]m9$K )euzhfyϷnZCn Ƌkyv[j]"d`ûAo27ey3䈻<`7A$j>ߍCj(Q{w7qy| 7sE1.0`W2_5|&)vɄ8fSBFёK#=K >`ͨI>у-6oT/7M\w 2IpNz If{8 mgO0kmL.p6$ϭ?nXZ,{/}+9 ''|{kxU{Olai/#ظFgk<Č gSk2">\Erl1,cvq.\ l:cxn>x,(lA'v9)s;K2F\cL mGVeV[Łn]}.X_3M1JPЋT$*rOx]pYVV/שh1igp955X-fHcQz3N&WF8:ɱѥ|x]BۢxĊ2ee\C%ףnDLs#y?pq x 3qI0su# IDATm4ӤL\Ru\ϛS/6\[߮6EO2aB,v'~hۃBҴ.P%D\N ٍΗuk@DA}BE@+ ;*ַkdR|N]1&׍Їd8Ľٕ/LAG`jԖ}6-mmv; mi靖Wo[Bi`0)`$y<G ukr?hwa2r#1D#û~G.|(CF=h7355/I`Gf?}6lȶN8Gϰ;V~SXO\ ʇsYb^g$>DH3AeG?Anj3{[?ux:W&fe8{Lw:NO>Y_1:C'癭A8_fCܦ?ԣ3]1<RSfhol_;`Ir%:TR^ Sa}; *rȩ//fh׭*:#N+p k*lOL4ʼL2k Dx?mcIblkZ^ڡttN!d_j>W>KnyGFNy{D!`ґvu딸!C#ڧxkBkM F /cvi`vx tOunpE-)Pa҆j:J} *(iW{ 6_A(?3pc06A?K l @P(]50vV\G?oID^\fHMn|$w3Pv !Iww?l4Vz|n]«Wo@nM o/7u7ͬ Pg/0~[.c4Q3LnCA(7$AUĂ?M,ܸnl']tm8sٷ/'_jJv@e#hV~C.k!%z?Ƚ;Kw5$4O(-QF7g OÝA$' [憎čm 8=d۷4+vx 9qRFkmpHtԟѺ *fI֤ [ A'h(qinD *wu4;EƬC5^p{7Q g@ )OGD #Tԑ^M]GJ ާ\);{]⌨he|ʆ\3n>aQ6yrЪXX>׻nSOyi[v ~{^BK`~k*.Ŷچ7'9d[m;=o>NGR,nlIx4Haw2mG/E5ef/uO:{35uz]H8Gu$}tHN|Ҿ†R8η6$X ;qyPi`vi`q70_EF_1~;}atLӧ!@cZ^#(4>L_iq0cuѱp @Ƀ3>r=1K4(1 JI6`m=xɊMvS.?,ș-TCK?.Џ'mMa?VSdhU@R=-!i;ll!]i1SyK l3yPe|+,GA Mz(T=LtL7(/HVk02#‰*`Vs@ӇʈYQ+7"% Ü[ r'4cI<(NJB\*y,Ӯl^3smA&d5}3M4ܶrvk)+9֞ԋJs*(uzf'>=QUxmWS.x׀0$jTƵQo&WGm>IpRV\ՎUkkHZDkk[*z A9K>OF+t|wx5ly8{ӑ+L_lf=:T~/x:b|ݺ|QN(N-ih8:R׀CW0<0mڰt|QqC=ʘkc`{LNȰ_'"ę=Jx-$R* %jm F>mfHbyԐ9 o5IuG4Fi۵ظv$}侷Ɋɶ#8 K(xt+[:+ie[dߖc+8XD) d]u ]`|nN]<~x{l#IUS: ,fߺ1pGO7LrHG'솒tK-cAt25T+] u_sM'O|r~3X~~ ?``_R~臝,yw\w~ Gf<U}? N \{WWفy6 p OO?ɟ\^-.|C?C/{˖_]uyz嫿sVN裏.|t5_5\Q}]^җpY?o vWN; kM rt% ?o_(69k3covĸ` W]uLm$X.^`%LTh_T=fF4~Y7L.s 2K uhZ?D܄ q;> 9 OA;& c%o.7qO8^<˳oP_$ٵk_ 'Lw@+0Fv/d B}aUgڼ}wfNsh-`/xHhs5Zå cxH?þ衎^L\rDW :lE}Xjc*HY;6FX*'W #MQ(W<H;zaU*t7+9i]* x6C%2vǛ}|d lb7X Ѝ{Ѷ,9ciGЌ^^š]g ctC VTn,c>WOgg'_Wj~e~=/wwỗz k|}%_%-߾|}>Ӗ[~~koo} Ѱ?3//.?S?|׿~&_~~`ݾ,^7'Y<nwN; 4pONU7s$yfp+tr}էp9x=yQZwb0z{u;ڹKJ|_r$[?.Y.#PmL2\ry@+oz.K6GIWD&y`c"]pɷ4a08ck ces W"tdB2?LhA? VTY|Y|$VNI->>oiכ/aBU@@c ǔM0h$)릆&/a҇ V2<25p(QP0NbhQn |?2IOOFOc6qN X逦  I·׵]ֲHI@,yw=!SjNui|gi:m-y3z<h^:fs.??dmo-|s/K6+#Oꈌ pmGUx]4V\IVN> - o|gхCWX pޠ]n9&'q`qFi2'(rvk_o/N\>Xp4HyAhM ޔq7Rh)+O;yC̵|mb(Si7{C8;7xryw~勿 w~gy衇e]_>3=cw}{_ ?G߶{W|W2#?.Ŀ_yEtZ>v&",<-{ɥK#;w{w[;)__|}O).F m |Y7N-++o|)dY|~,"> 9'ˑdG}b7t1_obd:QE/z&R˗/}t.1ǟa~c!]N; 4h@`չ` z n j v7{N}Û+!3Z3_yp82" f&1A鎖 }|!Hkɍ9t{M9tnfgܡ{tw{a_yVۑ_ dF~ڠm!3'qt~xҿO'ryt@@-qȾ/1}h-0iy' %O˳G[ ؜Çz68^W"AVp@W{>w/o=CYm[p k( >cCo~_׸A}3P>cbPi#9P>`Yh#7_^=C[EO)3VG#;@- CpD”!TgTe䴑 @±*qEK`K hDa m4Ig;?N\A/c$Xھl7S 6>zYyU?gX^783ǎk|(gڻ\ҥP ##䴃 ;|j<2d]MwB͂nCɋpC#[YMm~O M\S!|+Xvɵr{C8eq`+~UЎ1xp8ԫ]`-Q?_77O ^O8G+^|???X^/_~Qfykyg|g.__5?^o_?|-Sqז?a ˿WS_|Hs}Ju؇$?? >O?2/x_|7~O!_ӥb,/x ?__/ s;I|ȇ|sHИo%/yI0A]O?,^ vi`FI?Fz;Γ=}nE?3nwCtItkx׽k!pZy]=o_7ou#hLeQ_ &~|z3kbψ9A?G,qOf0DYo O'gG|`y垉 旰oނ=l&> 0萶^ـ5~u77IW,|:WDk8~6қiGGbԉ;Ǿ k{e] ;PAp2_:xN|mU1M/mn1͋䏲t$\P Fl]Ӭ"?]@CLl1lGON q"YWnPT[04UŽ+;ܭ; &<:2(\pAI\vō-D\כRxqwg1Xg0#S8M Kt8{HǛF6S}p<+U?(06^ IDATlGhĪ z̕tּΤ(-;atXÒddLA#sx6-ٛʺֆݩWgJ:/>喨n aҕwȥ6 :o l!CĴ5YΙڂgx aNi?yqG7]~`M!UkbAoOuЀ(L"p΍W?:9{^XܺNEo]_/(ޘͺ%xd/[V'/%O5Ӓ\^yv+{rLJyVnVyʓiޑ_# r?]#K_5ˇ~؇/HSkA-??|7}o/\/Y~c:K^|g8YF?kWq)}Wz}|_˷}۷-8me߻|~SY>pwN; 4&k?Fkq% ` K_j U} L µK#86;O/F#G.kCA;]aد~S\^SBh| _قSkDpG8M[xf?`pȯLB J˵kN}L|F- >Y;'K, myr#8r8ltfB y^x!LWފ'M:82]kma ™5<zOV{j3H7s+Yum3#lu`#K+05$ l|JHd SQ 5CJEBÒ2S;-:x(Rxg5C{Rw@0!~qmFJW 4׌K|'2_Mp!ÏWDGLbu?Wy{`֫0sN;jD m`ApE`# 16`*Ǝ˩!NYV#N~8 0.! !ɈXv  $#z>Cy+*~η;]{;;trdhG[7 g(lB,/-sGԙ\Y1>8a)8៰'Zh7N ~@У/ue0CZl7|O P9xG"yp/(SwU:;XZH֝hmm|Tx (lhێm<}nH:;ǖ~NG)`js W "_ 7A|[ @5tlt|$"g0hi;!+#;h䃤 `2L?" 8[qָkюO|@;\Z!G|1/ʈжTZF\Zf [ @VOX)%ܧt4D;1vJ)\oCWjl".Sberhw843I(lwy+(7qT,yn)eGW_Z!z%%P>P),˱VҺ^y<hi}џMrgʿ8(7zVr# M@U&@J[+uAywpwkuJܼ4'Qfߒ'=#>H?ܮyQ?5=w}w^?QaGM/~ ; xg/xU?z|KgoOwz׼} ve o}/ٿy 6*g̢x 34vt~iFԯ3>F>>齪 ~4`MSuM6 l$îX'_T[d=VNDc;yC|'1^+gsR_i,k5a v&wOFtgq}hЙ jɤvj?b6hJCa zdȽ'\\ n緦/?dqޝȱФ ?qC*AfRM=ol.׀/pC_#./ϣGݝYc6;n黵N/wx5 _shijcr{ly{r&N kFtwBT?0n9 d5">p>:ߠՙ  PgcHmfK.wT|A83i&p`mn̄~3~qDˠ}S%L0*5)=aD(5Ԑz=hiT{cfuebyﻡ-rZԝ FԑZFHAV9SꐘED1 )9 [H&XY·kgI۬Xd&NAN cوd\)^{)Km0QՙD$ ~<ٷ=Qw[ky9+>xAGT~KtvDH6^ڟI:$t3B$` }-3_b]:Q/e7?Y & ;X3׾6gԈJY?SF{Fx_oQo¹w?-lvhzy>}S\B-Wv}s9!*9;)@ŏ;۾mӝ(~  ^`po?z׻bMozSK>?n2膑$zj{π' 9~vdF˺8poDVI`&M[m O{y҈6 *[90jT躎 iz:>bqdzYjcs~qЂ.>^9nނ&h3,m:G\B_8&q7'Yz5t'1)4dkf%MiLPCf~آتܬ|YT# j *s8NQz7ygQ(G&ni޷| %w9ыQ6j+KDA'Ұ ۟@׸FJ(SNs/"EkA3$ RDMz&{i0>)&2ϔugQe`|C'']ʋvEr6T#:q>(ȓkt5.! *E0,ΞDR:7cvFfUyPǁ6;x:Ys?\?U `x_>n2A#%x@A))U lxd);$#h g1D/qXoiS<~77A5 ,E[?2F`Џw=ְ %k0`$?)i/޽S? Gwkq֑?5p2苾u_s$| aHw9Loooa?ʱv |K^/_wŷ{7茻/~qGy3a2qlص~ I[g:>|_$S| {f Ǻ/Of';h*w@kKY[ob{w2yu4|ٗY 04 dg2OΑ:qK&0.̮y-*Vܨ%X\S)NN2Eh+0ipkCL+%rhcGK' ~`duXb (TV]ŗ%0Cj2_vt82Im }ϙ5b CŕWٗ+~ *ie!хڒ]" M#^=p{s> q~[<)/? ]PD:\=,䦮ߤ3=20{8?\#M4}y6#:gK A!dF8AeqeM?ke- .7ϚFg%Ҡ,\aas˲MAX meeu: ď %DF  l?sWQ^Z$}PIdaOF(i, `)G{}*e3 <%*]$bݼq--}Ffشޓm%@YwyǨ9vkGh+_: 4ՑQzP~xI@³!#,_1ZvϏBq3a;lp@'(Gbqps¸̣pt~<1v6=%Ɂpm;N`=%ԑVYxv.,49׬Ig{~m;n⍋$3ҵ*9@ǐ2Ҡ|ߺʝm]λ *NcGsi6u.tecuVJ=3ߖ_ pа敁%Sy2'<$U{@ʕM[eXrK= ҏ:RʨjT>V^[f r^#_7UG G߽E$҃}`x?V7Y#?@ښn$I`&߻9IvnH6fVWMadf̈=Boub? n:v IFāyBq3鐉l'~v8؍|߃}ot߼ev?g(u !yu଀+O_Y 2٢iG*;hvm6tk7h.(j]t d㤥-e 0++1gSb_ǘݨr.ulQrT{ڒ*]U-!u>Q[ڻkwX̷!Y?p)^Vltg@ڂoqzy끧&m|$}ܡt62<-GH/G5,,Q?BJKCz1ƺwpǗ~򔗖bd_@g*s}u@L$GtY<Īy2 ԭO+.T}K7m IDATLy&Coù`hg8FKډ>>&[M6 l$I)hڕkVgbrS̩(LlcƲ9svTmU޷N ^M48:7{G4eWt;ZO9N:UL$FaMB_F= m\SfCh+9/iT|-(iVߠ@G,[Ua -&s FP_TX "r4G񑔫ln}KQ{6c=0@;!He'#(Na@2Oy9Ϳ` ϱ3. &;W$lGM ?uYÍV?S߀ ˞F*8_m҂ R,BB5ԧmg7ePo8iKsRQЂ,k՛UF'?kݣ u&m+nˡsɶ$⾩I) ? u"*+Ul;d(E.9R i8le̖N?=2I>|H7ٯUe>\>|܋.\^' ByH8BWS*An֯#YZɌ`Fx^"qkJPam1'a[od⡻3[0ex93F$irRFS^Y g;D4Yz~.gsÖ6 l$I`&@X@:M%ϮrP#q,G8`7Lda8ҲNGœoq_Ǯ:|@3yj5 0h3ea [ghQy07P`r>mז9xVYx< nN%f}*aAQo:3|dIX񉐴ʻ>Tٱp?wonow?`Y1A+|ͦo3C|79TUg4rʉEK};d$hoNTkUdb*XBp5 ?gZo鉛Pcdxȗ|&xBf VisZ>yKo-.'{DJ=)"S]腪@BxKă!-1<9P(l1)#D$miG= 5At|FF<;<\l xY`}8Px+I oe^—/=[G>Nn$pGƅg;'ʷI;}cy&Z*gaٛfæ2͵hv nPzںѝ#:7N_~s]۶hZ;}^[v`DtާЪ-i4SWCXZA(>~߽5;s} tĎq;NտxHO 2\/9(\Uki)Xoj|C{(h{j_;:) M45fаg;^g9_ܰ/ڔpM'# ?X4 Wg~r@˾ξ.`2;o+tdHw5%^3,Qrj:2(mL-4 98c_IWwیVʶY(ݍF{fC|{hׇRHѷɗf| Cg7O뫸2a6tU*l*YA&ѓ˕O&j\Gŕ04A?#:?!ޛ,"VHiζ̒C+%85&TkT \4 {*V$~aDDBZ^| ̲~6-EQ/j:PovzTҮ'r޼ +G~_~޿kR>9YUd*#2A_脷gLt?+OI=>w JH"NV"ƇڗScm<چ.KJOJ7Qk<&d4 Cr%BxZMV4/82B)KMQ>&#I9 B NiE|T\s69H?@~$1Kr6`~GP#2Ҧ_8dIWFx3rS'8dz>PiffH%ڔ w:80mOV _hI-u/ W R/a5uz&%,)LvHIOrDNHPGgMEh9dەPq@>xr0n LHTUUOp/tHxX-+? r+ K1&47;XH 8yUpJt@R:q(f,/[E̴Ph5/Kk\SF95^z ë,t r/KQa!=qi'q 9Vh7z W֙ld\ۏX(te60c8m,:i}Vp(2Yg\Xg }glgV0l+~/z}-=-% /x߽ԧ%S6 l$T  >cG2-0;P 9^ͪs4ؿ9@k.trM눽t#Tv/?{+aƌ#O0tʵr̴mt&_dm5o5TX}Ç1[:t_4kTpA9_QtşOc|Ù ں:ܹaA^U5 VW)M pKfT\wX~LFM9يADd0HqKq3^pt`;h77cp=g8r8 ,)?kٔ!?vE?$> PIOO)ևVe3/([nv;OVi<7ʼn˾괟d’^Jt<$fA6%rQқOl[xaQ02IH%@2Һ(>sS|x`e1٦rg:I RQvT*":~8BTXi#xG}zjJCGIQnqV( 9x}O*=!rzkg|08M( tʺ7D ri! ˿z:K|W^Op-; }4'/H&g5;.2PE|QJ %E.poʈ"+"V<(#o}#.=7ˇN!/&+=vljp8&L#`> K]8P2LOH^rm%kQ6+' _?NAMN?g^x P#(t'Fwn>,AwS} ~7D ?GYȫRq&O}&~--6Q_^?Xget<x$I`&#z׻w?syvk௲vR䞿݇qti3}ݑ*a|q?'6ز#BgPWg1Sk׌ Ì@3p?pi;k* xkijc鐹^;4_([!ZŽNpttsNwfOO(@(= mSЕ=c8LXd?3IpTlNq̮!3|8'F3r,/7r@2%@m[å 9\#Xrg%9@ǽ6t-jV"Wi- ʥسr_~}smzs]NǛ6~x@9eǞw98=V6ͱNk뻢W藸T{@/ 8%?y 7/"F^jث,c(#~b UyToe; x+PDQ  ]Y!j<2q #\Y^Ѡ}%iPtfbHhLT_ )Ňi(ߑU״.`?g Μ/zn?t0;D@pÀbf,);i޼lFslɛx|&kLG3gpA=2'|Tq74#\@ɝe<ڞ6dK1x-փKHPeDC(a"\y5xN}/(Ϗ5*v Z_ c=e0E./ߔp72F}/x8%0x12tI&a{n_B)c#]BCs;g9Fmi)sv_{Oݯ1&ueK6 l$tK^w/pövC:&:g6 9}ecਹC NbaBP񝳐Oth]]=[uE׮{?f^k[Xearu|a}-*Bal jZ%AR)lh8#>3@0DA:ŭff)pS2^>4꫽)# hH R~<~~.?Ca3wΧ൭C٫h@`;7 K~\K=fY䯍xtǙجnC㺙A Z}t pY j;LɎWҔ$K| {źqy_] >GK?23$ou$-$.2p(P.LuKhf}Km(3U}*G@!D{2ұ1&>PL]$n`輯;$<Mg$!2aS*p 4 T: eGK_L.,Βh˸" />!*D2G^M6 l$J@ {ۢИ ^|k+xAZдq 4q4Qlk:bƬ{TwgxFlluF-wj-Yw8 (6r:Ips<'}X\oA3!dZtWwm"j}yu u&g"KSivdEڜm^wI ֹ! qfClŇdcgI]H=Ի;v2'yahNv}^ I:u^B_y>8G =l nv~o@:2)w*+oeXT>P=ㅴ%WJV" Ljl`9~ u 8J|F@ 9%N@[$I`&M6 ~m2vd{}6~ؚ6|<{)v%6cF p$~9i`"t1{N1p_s}wt lq~+/ v0EH-KX}xL} d) فK3+"WRMaUq`'7rN%Τl ֩sr+_^\>YOipnNMa9Z:=@!ͅ-K5 u!8W|e$\dW \ b)SOtAa7wPؔ/K^*IBSF|4zHIaҮ[tɋYxRN%i< k6 )%C}S`TmvvJ%D63j{#P V^-k;Ie0e˟*MWpV̰/Uʒ9y ]9v^LaPG⪍mfЭ'TjkTV+3v`MF22(!^^ri;>UMŽ_pQ0(BD_|vA@t'_Gt$8V IDAT:_=Pe FIaTW9 zN7 ֕v)e88ȡ>_yN)Q&dZ]ym%\K/nW|+IW'V|KI`&M6 l@Z 9$#أ(#:rxEpʽ7شnlm4!lit n/1SŖq~rpiO#mS%vg q >Af&>tita OLV%I%aJ˜ۮ#$e;5Πx2TV&,,o V`F|cAo[3ߋBfΥv}64:A;Y^F?S/<]ޤo_Gp̔*b|շ=w}9U,zf#ӂ,Lmnh_oA8$Zg_`7u uv!0"MWVcvi9,lmtd`fx[2P< =C>IK.c"yȬ,A+tޤ-4r"z@ubft@cZE9k*=M::>tuR2 B'9[2%E1Oڛ|4aWAO8|G7|LG4XQLf4R4zm[d[ //Vĕ528|6L\Qag4x9xyQZ*X9gcu;ӑu,d52ed{e '{}>CyKis<_끱K u)T/ : v<5Gh0yPX;M喾гg}#tN82D281p}A+f$/7OQQ t"Je_p;|= $zw"LNO"Sm@FGF8-ީ+TZee-m$I`&Mjhc c%p<Ȧ{ǞoXG@i0Ifiڀn1qm͗qir3k;p%S@{RiGC7s:~6 v'%޻i-F3EƆlv,%8{,m0qS olK`K#19!G,[HT$iL)'je\ ΢-2r[摋ʨxRg`;R[Z梎{0CD.Ȼ|ꗄJڢ:ڦqO! i h=-.Zo߃R~]/% np#Rt¤k?*}+姗EG]̇^uǕ OͶlfl{^ _g5( rA}׆h/qrg z'[0iBI3_z gpE:UQvdՖ6 l$I`&Mgֹ3ņ8aS[7nyN.66sLFI\ّcm?N .nk~2ok7ohKS~:}.p(~3(06pq3Sԡ.&}ҥs5flC:d]t 7}{f%RmC'p¨5{%ڻ7KYc#נT󓍺c86!t+, O.:4shqΎ|Wʔ_Qv5I#vX|1S!]M(¶ 2HUm_d "L *ӈ^n)C:iC@Q'O] mȻpnLi]|t': n,< ]KX̳ ޣ7n8SmA^K#xcx$O\,ͳͦ3<=:<)VD9:h\C9vkD^oeȔ'(2ZU[*>T2]S)PTR3J8Wă)>3raG:鈂O)Pp[^r̸>KР2/3>I-vݝ+.WqY@/F&ͬI>Y+,J3ٓ˓24&@kD *M}dֻ[] g 6WЁZh.a~ᑿ9}dק7>^ &\s&#} kKO+ /7~7MO+6f6 l$I}J}^?/zd4INSر95kϬ%OU&YGmTvm.Gvʿ tDj|}gBNG]ʾ8E3ܴa݃hs2;ؕ<*68`i"33Aai)B][88 5'_ jˇ]7t8K}5B㋩jQ`voշLv/04K(^{ -FݚmEx/O6^{iUY" 7)LK2yf}בAT}v?,9l ӟ6)y =C^<xMwh}iW!I{sc ^U^rAHb05H!#ÑPRHۉo91cbd M(".4s]9m Fp4=aus ,3ϞIAtĄCM)s5 #p2$Lxٻ;Wف]MaK'{.]NG,rK縴 \ nt6"k[8- ҩ*x6|*+bp"p#²rNUmL4I74a{/p _p;*'gMo/6uɇ.6~/m ny؀Q}Q>=rʧԱt@U`LMZO0Ӌ\妚r|#G^o\ 6 cEbϗϔ\9-L[qfdKO; mo=[$I`&tBok_S#|XfWJ{Sچq(OQD< ^L|QA(.![:Kx曆qR Uخ/xts/:$ʳOzq#7.@tcCqY^?g>Y^[" vB ~UH;S.\Yˋ$7odJr`yyCu|/wuTN(m}|G|W@VZc::;$eNg Bp]Q7}`' HytR6#OH K^H$tgx:~J_~%gȊWTm( NK<IYZdF5\@n_O+ ?{˿x`jdK6 l${E_j7~g?I՘CgAU"8s VdFJ||#&8&S#mА9 naZl0ܑ8ˋ`hiZcٸa]~y( ֆe@7΢]71^:ANL' &CO+b<&xA+ MQFMZÉck}qxLN˧Yntb>g*mm3ukRG;pŇZ^vX#xyhWIn`PSwxSlztkO k==JM[x"4P[$OP3?|2޼r 6&u pr:dx;c^QqH(?w0Q\3; 9ev!V7!,WV`xHt;r Gg.sZ|fk-΂t>Cm-<*):xo]R[u̲;#tpkúl(I,w9ddg$u@޳HǤ䉗QZNIOF*\`AR'On CαjJ CN(Mpw <4Z_{[^K'y/QbKN{G٬WM : 8ʍFW"/DkEk#=x`J[a8Q80RQ&K`6t D:+ⵏ:}q'3ɗG_ GX|$# θhp9zF}-Lm(֦c<9x$I`&'W/ˑ=9!ġ99o3] '}[_=9sͿAwc|3; <7>3ˆu=@4"+08r&V>VquFYLT 2G#2#( FGvSg0(@a(+N@o7zD:f_"yr3rXe4ҧ4Ѡ \zͧ3MǷOEnJ]$lH!F:SvtD0HiȩPu*SX3Tlʼw[;9#z[Ј U7PpҝBA$QƔJ/Jd}D%vtNgβRZ'NRQ<;BЁa^N"}ᵲrɏDp7`ăUqh m8N*?)c2L¤W&a|C>+p'\e=2 Mg_%}0W? |˿&YBabvP*wA4%#`9Y3OL"iE&q !>йdo|󲎼d 璚:6KvS.?>+,C:bK޾!/Zو-l.dI`&M6 lxR8m̶Nȸ!Ȍf:CcFȱYncrEGumn޸WNp~uz8D*dLGoY3 L:KOK3्-MƔ=l"'4[, pC0?bʽp3N3=EoϱW:hCfC~d$68E*e_ۺ 1>PxtV=ĴY?"x5+B<#Sc݂@;͏ӊ]ɽ}䌈sPtS'RG76%[(#?I~\5N\Ӫ ϴGЦ)Z?@jpnFokGU(f|XCz*/Lɍ |/,'N:)ԂcmWِL`Wi~2@؅= YwFU^UR='\v/M}TywvJHA2Ba oarb}A١drftmf(,.jhZ~ᭇ3T@i]!t@^ EF#^Tu2A-N_ }i%xVb$<8)=>So.Or3DlN!DJR/C{@ISW IDATĵͦn$t%q?vЋM(DNfs>):K@yy}taĻ蝭W96LQ,t#%U>yPY3aS {fM6 l$I`6A&I[ȑKlG.7O{%rlm ȭõkbz}Ú:!__Ge 8/n]c\FfW Lц&6B6'Ϯ6jGـ qᨾN:/>tsY_%4YǦ vÎ+*dR;LH^fl[Ѝ,/0}zJ/ nΌ h Oc[_A~ fk̓7v>؟RG ][%Y*1_ѷ.L҇=yp{ f/?,7h |oK(\'#:i׫SGg/EG;)^_ը_*#Rh842hA>|Im/&hj3䞲HEϑ$ΌtC*cS k(#4_A gy$pA[~*9(ByBh:CP ,L.CRY;y>Hu qVCu2K:tpԖz(E崛N3?3gT1}$_z=,uZG\cY)eQh7$L魓0|IP'&Ҷ={ɒG^nK;gZKxVg'Fyʪ,>e䱈Rd YeD ꆴ'Cȃ&^U/ q7fr=uA}]vpօ[H8Tև-`94w%/p~PF+ڎP]8Kyz K)^Mr rbDP#8cuYd8҇ A3w}dI`&M6 lxRn7޼~-ql>y!f.nmC֟~lbFm=Mčm@ĵfcv{8 ͤ%IFϑv-3mJ㄀nf;t6Ъ]Lonc0κ6N;68xp@V_]ߣ|VxAG\~$I`&戻ezlɰ6=|3cOqXވ-cSwyO8u4`24cl"aiFySـnFf 6N}*ڼL'(/LLl'vx~FM™Mmm]m1ľ;Ibg?-bG/ǀ62mH=xx#yʭe`"rYp{.g$`ȋ3`lLd',:vE[O߂f <_H_Suiu6\C׵6 \cM퀟8ҏ  <#Lye 9'>k e#̏n^#|pܾ [lmn,`[+10c?dh} DdYYNs3@xnC6qvfm]@2nƈ)}BxWFʮ9`?ʼn)q)V'! <1_DvQΙ}WG\*mˆhDY! 0aGL8&iZ363k!>)\:>ܦFQ ~7Zq7T^pZ_ 5Fɒnr囎1)\c̩oHTy'ԋvhN^8G7*t#|!GpѬ mЮ~( a}G-C BDXm^,pd)eDGK AG@D.#x1WO.3$o |q./-\V/+E(s NʓI|K<_]Ϋx+)F?䨡w^~|+>Tp+__ݯv?Yz??{;O{#ޛMJc$I`&[p>kc!~8hl /"g# ,~f0i'a81޵9:8wxm SrB}#TZ'9n<#( &W[;# 8ut=A{^al0+-rJh>XGBqvmv!Q~߃fG/tɞ' h5#C6[t ˴rОNL@A7#PmvEؑ6&}cu#ǩH1A#]Qf]^;?.XdC:\tgo_HiOZ|kd|r {]&7/ZD[0hogJ#\Mdǟ-|!8=6 Mhݫ_=;G|y1/_rœv׾|/ݯ`^G_'^񗿹ƻ߽~h>7m ;=}H@Syv؛ ŎFXQRq( VAcG56UC@D"5]LXv 6(w}w.^<;}*Oگ]iO[^/yz{flv; 4N; mjG >.Z8SLG^>jtMn[`L~Tp7hz 欴Kιg-4w{5[]@$>~3؏d '-30G]`^H$|&ܜ m6|F'~Ov/3қR#GG9eimmG 39үW.sS/\BsaYY6֠Ҷlp9Pz㤩~ý#rbmtH@KLbj[g>62,H^#=llc7\r[V㺂āDGnM`6ߝV^`;'#=_zє"m#Dppf‚psXQNA&t>pw>^}&>|+Pە3 RWoxJ"MGpa Rz8"F4@/\J=4*u2-O04QBp#&{?F+P܈6(&|z`-6F4 @tcУJ4J2gŽVi;ؠ1J.9j+z/ `z!Lęw?:3$ҝtj!,O15 >ӇKVPGGGSrDUwdFlLhdm ѭlct`A hoTG6Kq:y}ȣnfP(~xm0A;zdr0`kmqJ0<#vo' 7\} V _` .6߆tUW-Q?˟ɟ?|u}w/Oyʧ-|w?^+]Y>>o[׽u?e 7},/}O y~+_/^OS?ˋ^q g<-S//|+򫕟;wnyIOZ~~~qlWѫu>| _o\}wN; 4ߊo3giKWo>~>5MB;^T:(/a,ǯ9dr y}migE WZ0Н OkWkO7s%AUOe]༂ 姁}ScJ} A|L|_GOHcǸڙ]LL\0&)',>b+ps9W?)+fY˘e;;JCX;e=XI;A$ukՑg*pe)cF.wZdm/=<{l*es 󓡫 c7&UbSwc+b]PՏvS֐ΑQ=YI<.^.fW~u[AC:YDd"U.k'Czlp P[B'; IE;@j*a$ܛ;u: ΃ 19)T`JcT|'N^ jˤ3(x1N^՟uЮ ^TQј$ : IFE+Pmd <}d8'!_ ٌȌtQEDtC>7zwAjάɴ]WG#lmCI]WumH2:bmULI98 N)oTR^m[ |V69^;PJkNhЛbʄjsmbg꒜t7AСԕ:&5Dz`ۉ% !䩣mp.K>xfїyC]DρB=Y4iC#\ ߪ/?c73X۾Sx/,+˗G?_fĽAA˿_,|g|Fɧ:{oyph_-g99χ~?\ Oz{#0_ 7&3Ahʯ[*MN=|䁔z+纸H=[8FGzo #|Թ%=tęCЯ,`>O/ß{I߶.gu|m߁eeF|NP@ӟ7iL&'|D:W~EΓ_m ;C,at&V[TԴ14Y$K6Gpb6ߠ6_@{M}VF>4QGCC^j/wq4@tI=Պd8m.o2|sm=We?m r876Bxh>==`_ퟻ Ze&1ك#G}b  }}gVs;c+Lc@z7|g2mA-寔7-`%[~==;︓?# X=}gSfL~|Ix+[9>If ~yTfOᇻS  Y9{Vg@K-MZa3f& ݬ<8ʖ_(OsLͫQO\9}mK5$|\4c.B0\ƪڊf偓w#1%Xݖ֋6JGӡɧ&Uʐ<*wB(=zUΔO mz" AO\Z];:|-"_.ġʐmhktm^~0a; ΈU~c'$W 1&G^gBg=9HWW ;Xn46~* ;6+~ ̩3l +[L87s+$Am:U5ƚCBQ[pgPSh:`hyE'1bRQ`%)6!?}<*j8\MgDQ:<\=3ӨmYe ~rYjM}?G0?qx_]kWGo~t#߿2k?Ïˏ.K<pqt%Χ<)K^s>#>byԣy%_{mxK_|G}䛄KK//\.: vN; 4KkPgY~^'<'{w B.6$7|Y ;MGE?y#/au`ja|_N9@U3-PF{M ,ҟk<~x'X՗ n<@"z9]d^quI_LR1i]@txUDWP|'txlz568ZAMb<|Sf i#8A.#]})XMV[]84lL$r[] mkл^cqjcm8.hZڣm?+!hS2#ϳȑ>dΏf[Z2D NuwP> < +sy{ FQerQTjFFT!ZfE&Xbd4œ.QTҀJґ fȄFH-W>mc93]wl16 )lXS}Gy1Ϸ ǫ%mt05@O|!uՑ6%`M+!QreWYu2Xq ;>7ԯ=dSfL Y2pTW7^uPXm/l0~ ~GS':.:z}eDIGĵ^a(]r\Gq<ږv\W'~[ k^? :~eY][?N6ģN7l+@6rV$s;󪖺 ˫^/|l'x)=WzPꧪsk}?a0{偅W"W}~Z/=v1//m zы^M>Uʻvi`4pLq"ݷw@>7.u{ >|kD3~e.vKo^| Ə` !uiO27M ?5 X_j|ˉ3H0816'Ya`?;+lJ4nՏurkҧ7I:`qPCP~ӏ̲sJsmJ)iX%o`]2]^K @w Zs 6 *|jÓKKjpAUk}eL˨d'.\֌%>#EuP6+MG/q" "\J!LD#Y@|ɡ |FoN=eC ;׵,Oo}5ͨASWiJnhwعs)@,Aj q$@SF`I ȇ]K89j7O_YG9][ |)4i~8rۗgo; ʭCXrt~婇?v_kWtՑGrD١6no?ӾkZ廿;g}7,n7/|ڧ}},o"xۿ;~,_ n+O~_)u_3 [!x z9i_7fcwN; 4ߊK'ç_N$Cz4#hE^;Y32~ AV ~OK;`oG?k8 q9d _$Paҟe.6/?,yZ﵏<9#/,b.5G地FX!_K180do,"U6\V_6Zs=!S&^˧9R|ꎎ ` HY]0.}VVFڲ`ֶuIueΫSl@~K[4@Il!.K[tq5Jq^!ߣ`6C!C]{{Me9hϭi_ۃ'\ql5%g # Lh*}=i4|?ZH| (7.]?hKJL#=`+k|k}Gb@! ֓Hk02;{ Ǡ,Pe9C`\!pl| i9\.:a@} O$tsvy=&#ԦkƖ7$+X&xKte L&O|I{eA:%GwPBfekFGmdA)Ҷ̕Fˇ/tý*龑8;,cC&ɋHԍߤ!'[z8lpUѠmOy#- ? FC}Ԧ:j#Խ:.8/H{V;K u#&41*.vڧ\7c\C8?t%?r1݁= ƇPe9kq+uQg‰'E[n9Xݷǟ7 ɟI7>?z_RsK]ut㡂G7Zzғ䖂po_x.2hrez z}ֳ٥vi`p 3$ə.xՙ',^%G2-=|#||}4NA{9ɵvN[ "s~~ \Fd$ +`byVXU~+y(r}Opcjޠ>1|}0&1xXsF'3dgf_ph5S/K!򉽂ĭ ,o6Ǔ!PZԹ >nFu@Sɨ3P X"<\]:pn }AO[=q<| UoO+T##W01D8:=  eJC쐍h+ dZ9 mtSmDr !pF?HM)CO\_<5#%jCGK䡥l|b[qa81h# 0``KAvDsiu_}%npZ@[L ܂nۗOl a>L{(o[ A\ mT\{ hU<#h[ıRI5d_[ Hއo7`~޿bAx4F4kSTB`\QYА( !1aI*DB'uU8. x;^;hHi4DO h2$9}Ե'[PCG3Z46Ķ2L! ..Rd-"SI;PCγ'^1 ]1z^FOM h)i$ B6Kم' /}X2sK]ԑ V7N _ OrʒY qm6n@Wz[2rmT^aґё聡qWA?:ց8K|m9wm[>Dtz*W?d;q:Ut#Ou_ |?-6 g4Y;kyĶ؃9` HmF.[>>n؏طN; 4N6 n\f z?err ' oJ_*[m[Gk [}y)5k@K`|3U_ _\`h{my20OgOMpk[ZeǛyž殯w:A.I1'w!$䋮`t7VRA=wڡwۣhdݔkK!2ۨm໸ <㿎D޾)n~,>8mENi 0n!oژcR\WGmb ME mm;BC(E)l`Vܞkbmڑ1Ul02[nEeQ7#a1 <3XOݗQv~(U&&Qn0V@C>Gѝ8{{_Hy_F K2yWAې-i4 Wg~=+  d\%h4F%RCA \U<8<Q4+ [*3'F VVls.ިXGF 09sIeo{˹[24-7A" J3MY`ekְ(ЀԑGTy!CT%z A#YF$qGtk0;8eP3ұmj༫U|yе.F4  udD^qX;uSɃV[~0A)+G+H50 gT4;.i%Q>hJ:V.e1x(Oz`:ԅу?ro_#ھҴO_ T]Fա*L;h,mtx =j?mWORcЀr+@v; 4N; Sk`|\+> ߤIX}( O$s{w7I˗諬/M#HA3t4qx y/,2rdgo@Y_9Yj3>N=P(0J.cп{Sf L /L9ϗǼJ_A<LC|`Bq H,-M&_+0|ԍ7;l#eV&Łvn8Tbڄ0SǝmL(VU6ԀO'i+ 7VW PZ=Y/p*N>[;e3[j t̽|zڿ<]L|$1!`Ls^L6 c e% W% Rr -Ϡ1\HΰdFUcX(z+*SX 7MP@ oS  9k7 tkAIk,A0zUE ?:Y|:{ maʣgF}4Gxd&7yY[}!5RyPWv,Gu+#Ad>#d_4N/|otuz d \A83W9ɓoj 4T'Lfφcig6^̺ .ZSzH%W:ol`ygvс ,g񞻇UW_wrNuDdY4gd cc.lVYB6c/,^$j/:Oxh6a_|ᷭ&r`bXJC`gFrcB#\ۀ0S Jڂ`51L|iɧ.y'ϋ[,k*Td185o{Y8^xy] KCq&YN#Z_v,4 XV.{&ֈO>f]mK~o,<?F18)CtPnR/cBכO<'GCpz`JI8u&a`ArTXM=ڦzP>ﳟ6%v7x_Q`{mr[z iFǾ )ݶ>^LK>@D 8e~M H=3b@ 0|r8AdPOk>T%\-G;h;ivi`-xn#鴴$[2ᕿRmgBe0G&*:@^O^W Hk|8˱Ev3frۻ; &rV xi߶5Y7 NKr7:i+}ap{3h8L,=ts?^ l#hUѩ!>xMQf@|UO,Q[-7[bEK/ +ѵ|G^TaB#`g_<'cgrXϞD~rSD1H pW)S7 ayV]:(;k`qθxlڟ߭>NB`q*L;ҟIY:lFn0ۀ}߉8rgD}~n0iC[iG;P%C7RFJG 3m3U Hgd1J` A܆M h'*ő 񫊐.ao)<CҺ*_u5ġ;+R+|ﺶy1Kfxl鹍_C3tՍ6`}0| %@^@pK*UCcBa 觤~uRAwcЖO}4e/x 4ь_{D;t{NjlgF&yWe[SN.G ؞-'R?qț[LSP82JGGc'>#x^l)/i <xZ~-]97op;ˇ<=hGu/yˊ y+Qyg#E^K; 4N}j5ou?)W!D8UvKYeY>`_Y}kdpV@ďPi{/mgKG'HuɐU pGjU_X|+}eP^|<'N:?+W_sfz3㫎}H*H2||CjȘB B ;y^dEwk oD*k38Pf.<ິWVF6J3uH[!A:$M wk Qc݈U((O(S婠 vMy!jl!GBWEb@1-y} c]H̬IdӃDAASv^i$"/V"FZ@ʺ[^r]Pgۈ'qdzP%F)=@E}@U ig`Π#GlNƵ=%^P%d` G#'|(.>yfwBfL}'6R~/sŒrGv$IxO;Gv怟XS붪`]Ā@ƽӌrXcy.zs&ц ܅s4жB^);kyN/<#m43vB(r-~xM)|3iiy٥w: |?~y py~S N; 4߃|7߂%5zIPOZIflч^?Nl3.gO'gu8/H'>dK9"^+Y+X*u cKI2'Pb,g J#+~t 0peAp߶;3n%UOŗ`a 2_k&>m˪$9%隚X$K~j̇'#]ZOD{lST QZ W^L*$y6*0N؏6'4.:E|tԘU!0V~tsޤTPI_"u b̋|}ђHaI…/d ʞ#4euԱ7ꨡJ6ϥ/w^~ŝn"6dEx=|5A,~ Z탏=ܛm.mꥣK A g^] '|q߃D[8_leZG˶ᙲm%] ϫ3r(iS#WWuVU#~T}Sv+-#kAoD.6Ud߇<2lM8,| /Np>m+.0#,j9oY?)riOȳX T˓ԋ2K]h mAy5{!WJ? ?L曗OO^~'^nqw4NoA.G.IOX-xkvPZ>~E ,Έ3-5لa2'2WkZZ8dJ\2tJ ?x `4,?3!]q;\\WZ|d+A л`΀>ӧ,>=s͍liȻgp ">,꿚'>z`,^Pt|P74;mtrwr(+W2^utJ(9˛  _se؎W/^Nwgm冔 -/:h`z$7tH|sڈģM$ٱz1AC9岅p -?0~SGqA\IZc_u)0kߠ`erLlaK#VŤLP!K5uheFAUi5n\.FƔ0CL܋BS 1(EM0d|,h=|:,+swx_΀{FL c[R6eG\u7Ť4p)~o)y9jHC5Բ![Eѣ4;q4̃>M96VOM40>fG/H>6yl]bFN^m&ۨ00嬾zC\xSXB[GY2ݪפOXὶ+wCzvd\PCp2iz9`\NL=jg\ .MHGtYjP lBNǼ,~vivi`e}<0c| 'Zw{;< _9M.Ё"WeВy>Gle.y@s'˨''D Jw4:(@Tcep?zX0 _o&ORl'<-κpm`?<'?,'#fxu+#<1!޻hЧ+oև-t1Y3s 'QЕ6 "1hYzRUGի †;(WvCէuՎ-=(I9)l9#*icӼQ=H&۫C[ߠ'pN; 4N; \| `9GЪB7unMpw{18]`n)xC?+*G ^ /GW_c+_{vJn4Nک_E֥u~z'NAo2%|9`21~)+zgؕzo g=q4CUlgt ?]Ӯ*^`Bn .@xCNmq!93X\F*bÛE] *T{8UX R%#jhXDGm2-\BF%k'1"D9*gHa Axx<)q|E82[Aר{(Q2o=&o_?j4pDy5} GeFSA1_ikPC/fX0A+GduWzt9ⷝ B}y 5"t5|u_x#<'0 iKWaՆúT˿ EV@eC8.]/Hzȧ} ጚ>/{r~@a m829J݁"儍N=%сt{wvi`vi`MHz(L_{y7k{ K)xZcTq|rej 8[ޒ{}q>q>k~ eeF`Q`1__H7; /1[qFyL^|=6t½x~zx3ܟ-zL:9 trt߽r*}YI1Pw[g}@|;!ܴf!mǗtӅ/uo)"`pXof)>'a;z#t)zюN_} N5: x7Ti4V;TZ$C &Th3/̵1p۠en(ؚAcUksƎԡԽJEiEdzpNrʑNAJqM4,V]uTQ{elLy`\3JAZ/ rBE(  fh#fO[*}&ԩoddCʷ\6 U Мvʛ@|>0*P@تh|o:c|[ 5x#_Sca*r|/#UFS-/g=a=K528`h>M@xNK7Ƨpw녣p=P&l6%~?vW=:C՝2S7&!o &St|[-@˗AR~t >WL⦧;x 'ྯz  1r$|ѡ#oCLW2>"DGVWUׇ:]A,ރֳTtۤl> i{қY9HARo 8'eħ e rA%P+M_G|E ǘݝ`xejʐg-[#>(=͹VmUZ/|mvcHp=gA(|wچ7v\OwI_q&nPPG2&k6Dߵ33xFt]_EM2mLF&ϡ5vKK3{'/9E2lTڎ t%FerHovq N[sT@Z `s6`Ng1R:00j}+r2{•AtXgp=3Qi3X%]uиī|ٿvr|T0Niw_3|?,ExEVus5pBPxS^F7!&+>;sbl5`HZ3h(#BNMY>/ި7oGrJr GGzl;t~N%VIL`)tVeTԵre+6/Z&ۭ(^e w F9_ZWKtԇ2#iaHO j449r4ԁӇ4o9<+Mfj8HࠃեS|uf/~GG yn?Zuʀڙf8eiDhk.豁y0ԟ=o@ z<`<("?gˌ|.4N; 4NZ]BOiSN7Cn}+S#>+`W8g0^ |%[I1@Ik&teʑ> |8Wgȷt=}cGFzz- N Аћ:-W{F''O]Nz!#<å_9dGсm"51;ړSU*n xʵqCH׆F'R*AhԂ{˃kTY]6o){SV9F7A n SR5:ySL8.Y1`h>0%`2)Kx՗z Lwͷu[ё/GuJH&YE--1IOE[qkgUyV^йш71e/4f95QQi t`>!0ߒqXfՓWKxf[qG,[l^vz:eqp~+l^jӷuj;ѻV96v4/oĖΜZO2d:9-\3ߧRpObߡooapWpϤ(\>"??=i[u@C] [p;*51$|:|O8|'\^7yh~E߂90@÷]Ce:fs $0}ɱ{   )J|eO'9<.V *_q{~k[-yں~p/W /_ڶIsw3|kAkSӑyȗ舘z2fԞЙq+M1Q^k)6!O0?3`q"v'7 #ӛ/ A/l;k' .@]Ƴ= n <˝T6|CXm&yhY5DX`̀iL6)~̰D:dl8FҌh`eTUW<0$Hzb> P[zpjT`%DG ޶AL=!|O{bd!LgiѱK7IH 2ɤ(V65 VuS[CYwQ*][P&{:A[Giދ[ZH=c6C#q8/٬5+'vFH!N~[kd] T>3ʏr9>tW+sFټcxJ^YqŕVyv`Unðyth_4+x|ph#cd}` W#hy#p҅i=pWuMҶ.4 C_v:HgCz׼5_2^I#nO; cj0c.!7.}/y.Y`; R\o wy>.?:3'X}Y9/8oberP%4;o%fqv  AO=  .gYca3DLG/C><@[]%Ͻ- ex28 ~rmr(G ܝvW_I|I6z| g*Bޠd=O[G!{eedrSѢ v;sY r.hOVIȁxKScKßvT%1x-ݞO]L =U #“=|8>b%ՑȟC{IF  㰉;IzlxjQ .:"t̸#h]PǕ+X.!*9U+J AƨiLX(0p> ..#C 4]Hxk0rZP02>A^A45`S?im̷QoV;6 &g1 쬲RHêFUЧ<@;Ai0DyP :]|ɫ{E'Y|ȫ>6>ۥ~g~zy?eyG?z2VbNs?wyr#[4zG@[>Ӳӕ Pr^8]^-U.>E3HiHI@|mFOY>v~T{ookI>š;Jߕ jBx DrX?:@ࢃꃕWRW|C귙Xc︔c!g¥wU. tvK!ٶ>oZ APW_. hwgVEl[~?CxkC|gϛw?+|vS@̊ǿ l <>`^_-l%uƹuWc1$)g(6.`7\gR޹Vmy { e;:N /9@p*;Яx7 8-_14@=@R&+"[;cJŸ^S*2gB "`F+P%jCj,=n1nIo#}4K:;VY?Ek0o ^פMIHNW~:ɡ\ uGZ V}"cM7b7:PGzW#f~ku I н_%5KQxzZ@^SQ\,4 ->[ 2h7&q_3ؐvۃL=r;=z_Q_\m+KGq k=An;v\ȩ9>'p$N6#[-@R⇬ (htɶ<Pηq^LO0JtЪܺ2DzLG'vN'roY`Sm{f (ijWs%r͏Mz9{S_[et!zxmgduBM4/Wbe;?>߉уg6Co4(u V{mcԡ6dx`L6yd @'l4Y1Cqf#)  rO '*F20[o#X˜F.s$t +II5IACa,vPQhh﹜CVANaNc5C^ \h9<+FZPV(yi6/,]k<2uupďl Xۺn{SO\L"<&C>IzO:2裀| ]-1+;2+I3o (9y~6mv=ߐpɑWٰd]҄4Bv6S#줶Q/ !r(Xid<.A9_;zV:ֶ'倷- 0+ryޥ\8? 6|P6wx &}.]d]ݖ[9^; < .8 }3k0o^|@pBƇ?"H_3"9>/)0ESX|œO7>)_>9>>|2p1챾0>̼o|*e~Ap.~}8[@p *2G*$N1D1V'r#|kR铼&jkriƗ~&2v|XŃfЂ /V|1A3RaU}qJMCnC=}m֒}՞|늑5 )%N+_Y{#9:>(s6'|e|:dGN\鈗oն1K8e F9CrfР7h/svz=?xD̐e$ BHL l5AQCNW tf;"QD%QcKz>柂ة HsȂ L g|3nƒX1S ͔.E:8 mf_Yn1{F>i$+6j!2d҃Iv8{h(1~Z:f]TvZ)8 @MO^z1z\N)UXʯ<<&#jx͊]W#kL#Bp Ck)^^oWglXدxF&gy̞]jC;6F>zgJfIm'X9) iWgB7ڒf&&[HR*Ele<m! gл?; 4NG:N}߿kceWa]4@ˮ!ΰm\/ѫJ>Gw{[p__F%K3, 0mUh OpQ߽|B'/ދ`cT]{J>~2 ~:r5o{{m>pjᗎwhԁr gOVa_E^U; gLBj uǟ85j iAp@vvdL}6TϪdpsqFpr߃FAi'β'ׯXbPc;d)q_|ז#@g㧕&gNiQ6M^mLwtm`\{@.4Na|'Iw񸾞>O(}ps3)<|X'쏰0H]=ρFj4tCG|S!t&tj Q m?)҇>^1nr}m5M\wκ^qL)A? 懾N!jؖm7+"5vxl=1>gݚa 9!GY"cLrN9yWaS~n Taڷ1b7"N#<&:rK yҋQ)%4?<Ĭw/mǁ ;VoC1d H@FH!HgAU^ %ʋ7'^˫ "!?KwߚqH'T?[}p$!6ؼJ@ 8.〷+8ɏRȕ#eRU~_޷j-1 -2C0tUDSWj`2ʬJƒΆ\R}frdT^uaMfi O>L{DۺM' ĵ g5Kxʽ_#$Q/Ai؋4wՙ!0pXZ@^M786,8(G^aXCW]i/2̃+bDG'ꚬp]6<>8*W_x,z'r#)]lCxicէKl0d,z8ɯFtXalN/{Ne-65Cv@GokrW.?׿.9b8.jN; 4|.+_˓Os?s>/})+Ž& sKɟye6-+??~0m^+oΌ?]ѿu:+z \錾".~u*cp Lg1㋹wZYr#XS~ :NFfs䓂x>y7`~ON{\lOe8u@qoA B%sN=ʳzU7Z.G' ^ޔ3%HA}mG@.ۃfOu h%/Me8 q#7)ں|)|2zJ?NyA޼5M4Fo:¡8SڑxվoIPp S^VW dF h )p(_V@H} S}F3DHKUt VE[l645S^ ɽ  xM(o[xU#E4.t"l}ƾCÞ(G<56 5/J ,lj'T*?\B5Hȡ~v0!}ڞ+S:X;pYVTrQ`iʓtMvЂL>̣dovDs;mm|ը@"4ʉl=+gkq`j1/!Mn!OteVbڧTϕ牁)aՁ+%L|6$p~!Hlx^ySj)00>!_Ӆox3xP}?c^o_nS_?Y:]>?M^w #y;- ˯ʯ,|ٿgg,>~ԣUb9g IDAT/OY?gGe^|=uo~_i` #voω//YdK^7 4vր~L"/[#z{u=ߡ\? g-WY}Z;?O9_ 2Ś*0\UEy|poz*}oGN6ܛQ. *n>eQ㶠P3kk@ /W@"'䃓 }`#+"eg0xBy,;3e.'Z&Jm#VE!kB(*`Bk-u)@Hnh)QtQDI A >o~~>|03y9{?gyg gB8B8YY -h͵uCJ:_ 0xxf_yp%B*ҳ]>欵+%ͤ#yV"Gl!VgT<(ܰ=O$g2ΓuxwR1.z2JÀ&hnė!_Tu$~:viS39MOli7% =GຶWA4z]$mݽәy-Qp?dPfӎ_||SރG0{8).|TFV8{3Np;nf<Ȕ2fk1}zrHsKXud}hK~_J7$ː$ k_~_n_#Uz?3?N}soysǟ_}wr/N]ߵ?ދuEG|G0p=G+{/LYoc'{oxRi oF7O.aJɵD%zNA_23{hI< fn'/Uf`? *Qw%t߶ǟq yN>2t{t Otf0j?V-*{*1x ?;}#_#zJ; ZLQ!z \MޮLa@Ǝ$n[Ț[Oa, aeV-ȶIXq3rrrΰP-fZZ6 sS",N' Rc ʠunTzO=> h$ǩ{Ky+xll_<}$Q.FvNg$Zy]Kcud =X:wǝI.6au)=q1<;x <5#\S0n(ƒ|c,rn׵-:6 >>ⵄlƎ ˞ GXF/Z6up%m@M:ဗ:|ֽ}%AE/?_9[M؝3 M%: ~8_-ێkaClG[CQ;'W}t=2vP )᯲>Wt4H~| o?g`n嫿Fr >O۞QL/~~;;QlyͷWk_/s5L,;f6^{v;}vSgW"yW˷OMM7i{_Ί~r<ϧoOn__?gxԲ#p8hIwvf72xiυx堁5 |qKwN_g~{ٷm f28k)hs-Uҁ@ JL@DBTX ~6y̠B<ʨ_koԍG'>R3:Y!ѫ'pʓ+ȃ{Ы=_@O{,H^ UC?Gy_67ZGu\PkfhQb Wo?Wր,@>t6hm;tKAtA n]zLdN|yQh>z/dH6g !gGYٱSݗ62&lGn?T;ܦMXz'6a5*2F ҐIwo#CQ&MV@:!6 Y cƃuvĚ`#|`F'جqiH :}Sa; %iJQGM'1ﵞf&: '4tP5vnwlNO!u:t 5"؉C%Oд~kAt/':ֆbpgS=qmbѩS77: gQ- ){{KνMfA1}QB™䗺ӮzPT>m;ym}h9hBQU{Fr#a:-͍rf@ֶ+e706Uf8\ TYVcso:|+(*NGp0WVv!moƂ?cOO|lwq/}s}%۷~۷=f9߲}}wUgq|ğgm_抇OO>[^;+\)K^꫶µɁm[A?;q3w{>u]He;|R>vy~0ǓR~k~[JV} \MG| p O1ty1_Aw1H,PS_+-~n1<߫L xe&|I|O[Ou&֐cgɗf[mhC mgeID'DG_~2oxO8bn{ª[HGBy3H@5J/L]'/Թ_lItnLAl$ vnŔ.W{㌝ N )Q~JocIzy Om ofՏI6]zlOfPERոIZ-k$"rS l~3o Ēkcl#az o#"mo c Β m֐p)Td08%3$k:'UiJ[ dii5ٍk .#v*5RsrLvH_MGЕ 5h"+) 'tꠋ+3H`1Jv5[6xV`@>2xLȋT.2`xAoeZkl{;b>v㋠kdvqyڣcf9JUD*/&eSUf'p`K>S#tIB;MJH֛6pHz|x!OU9(2#nچ.~00ڂ:G|Jўl IJ/5z_t=yxRyS7[4(~P?%7ܞ>y//noy[]ss='suߺ%/Fg7#?}xlJ2x3}'rJe/{ݒ8KtemG*PvsQo}cf^9xAYG_zWP 'J?A8'fewKi6 X *5>wDХ~0_^+ߧ b,7j4!Rg:#-Vj}ʙsa,71N 'v|=W8X4J(St-'km}?|g@Z OǪb }+(QGĭZP6Dh* :a9lBR_ZY3W&"KahMA^3φnζ؂zLJ.2oEtd~4>A)Whրx7D̹ "\mr+Z.4@|ED}yo|uAs#RyC 8H3AY 7L_]8NLě#Րv>ŅeɢcɈUA3kA9u ؠ}Y`;8e JqӨ*ҷ(l]T H!=TLr$|Qittcz P >a>iG$!y7?o߮\kti$Տ5\')c$T{r6Wiwiw)’y]M0lkMx"?**mi# H&rYfGqNy:xG'/v{U=u1Fe%O?׀]#=XPw!eKmAh_xT}(}O]~)['˾eۿ]؇m_o_~~|{ӟ=9=1=Y/}ٗ5rW^~{x;{Ln{`oޞF*97~|A#&+Tv ' K\1#>4yso_{;S_>Wޘ/GD%k:|Yo?1|RW}KۀMZvBA>;&3u|וr$/UQ_*Fh>OH蓖+-=r7vQG)+v9pW+?p/n$q fmCӏ8<-o}7p+Z8'I#+2(f,UI~uT쒏6͘@ᄝ6Z~Q.>|M![╽wH&ctīƁyu]CgDFK9~lS۶}q;{d(mOmo} mmٔ싗vPJb[vug h_- %6h%E"@fT ؜9lGqUzqƝ# p hh*F]r7{,Q? Zpĥ$xҀڇI6K>RJYh1А |dFCƜcd6s^@/ɠI 7r{е#H]t"07>N+Ǜxpm<)x!8swJt}:Oѡ4]um t%39K#`(mls Ƕ2xt){튾fCyHLPYmdVvoͻ} $[MJʱm`mq eG d ZC`+9/[i%bI 쒳}-ڋ\ksrH<#x3t>>Z|u߳7gU~=m_S.OoVy{n|"v~_O'] -U?&зr].OO۾苾x{35޿/Oo7y} _yO46~lW2y~~po !kj~7*F?#?r{ӛ{-v'xc>N&;8RyGf*1p=qC>rIwU\Nb2LAg; 6ݼkg\ߤkdi%~|eɽĎ(Hzg_]1il"#eEF KɓYFo"24E?Nrf|Ld7&Aϲ nxh]c6!_c,?YvK~'pה[+lGl=:O fs v@@f95 m O,^BOS|Vp`$n r-eN~ZPwJ9k j&yڍv&ZBB:fS1/ck 3UU ={htX}PHhOW%x;UGjxV3 IDATk$uG`&e5)*mC; `M).oVa6G}A`^>\/Iylx%P ɵJoTIܰ|ڭ^_F8̵}8 k$߱3$ۙ[a㮚*4=\I7}^6|hOmWd,%>D9;\7^Es ˕=IC;9]TqGнװsk(@BGs;jL :$ȶ]2w`Xّ2ӎC~Io1g;Xa*DZn~R]>]s6Y^7-;_Hƻkĥ,26<'g?iG̖o۾￾Y;so}=f+_3_vWOߦzJҗſ/|ɗl_&}>~}}w~wJ9HZ߲uݾߘ݋ ;_eU 3]qLrM񿙯ci&B;ޕ3VZtK8Z;V]c,e Aun'IwAخ$ڝt5Cg&׏+B X6ACWX~− "CP:q λ!tfK!B~p{g9@d};"K,n']XOL Bz]Ăd8n!I`24^FLB?ȭγsacD( Wl[]Oڮ}kwʗu,`@o_ʄg׬~>*ލsYfhu Lq쬨UB2+0cx} 'o$L4$xﺲ@,x~;x ^CTѿSnye50H:sOg X3&8SEK}(j#yeMt Cy->7&} /7:džwc c /he tA87a$|'<+# L ]9:boՁ;Ф$Vmr_O^ͬ1T ^VZ' tM,uiT{Uu`ƼM 볣l,I e*CR c?IvhY ¡ȥC}Fd[k_'J;4P~ +E/<>Pj;?Phe!'9A+_|m~lj3W<D>pp6Z cܻ.>p:o373ر~>Rɵ3lFІ/ߠsjj n{%dJ|b;__\/A~ܤM5OD֟T%OW 8 cp*^}6/4Vc,g'J^A-r:by9\wkPUx璩omlPp+S_];8?>37-,GG6הk/@vP85+ґ`τ`q_u1Y'x.-M3lzIEx-1>ʱ}!9N5-'A2)%6fc]; dup/25u `z'y)2ʭWWi>5[h-s>loPF0\ A.vN ۽7*(g"Jn^Flpǯ^`bt QVG 2;m||TpƠ\N%#W@LqINn)];hL}m!N?<̑?A{nIYls7/{hlv"9Ȫ %A?+Isj?4`*߮w˗qΩ\->Lr<7OGN`ՃtOyyc<ylȡ cZd=U*L~S]z,NJcx?{<rp4pЀOO~Cd^o^; k_^a:;hɦ!7{g_kw/ li%p{9c~^tgg8V~L+ l5tf"0%hyo.;fM_LmNGn \Y*.'h_u Bٺ*Ĝ XPG3N{vG}{+̀I;7Bx]6GS_Gk> shqe,Qi9?ʭBF6±'[##PM/r]2W OyEK&KYxϽa@u963+9DщH[j*0H}]1ujSh ^~콰h6osb ~4a{O  BB`4d: 4 P(#B,:{ӷK0S^nGuO)s APwQհ|<' jb6ǐ'J\;``;mȂC V* ,̠P M5eΤCG@W4^%vUIYU=\΂k#*?e}uoJ/H}h.;A )?x9-O.?+Q4AP:GJ{2'(ƩcwVNX2  AWّFQK<ˇemgkWeh;\}q:6ڰu`$r,"$ Y~wv U_uF{@pA jȆWo_E_oC6ҿ>hI4\+;o~7^.c>F{n|17]3|~|k0k ;T dhKsi}V&fz=sWђ $~,2{&y2Q>~%| 96 ͎>E>MM@o Ag> Zmz `$:p7PZU(svӆ*(ۦ, 󭬀n.R ڶobΖk+jճ9 Eeln@T3B@gު,+w0"hqƋU,!DG3+̽`~yUOZ+^g捜'dsc>Ip?6hψ3@b ` Q7F0)r 585.E-̇p,݀\~ 8yZ@ 3kr ]>T /7Pp˕¸N ZuO1 N֧2 .X}roE0zrA]1 bY j gyNHG˵FB;ΨWV;mZL=ϡ:֗p 1biiK ו2DrjH5$g6pwgeK<Uɏ7L`tژ %]U{F(9]00 Gp}xʈrUwT|O9 ʪQ櫿]@ 7niTEg;PztA 4k /g57t8_Sx!*~= v!`|{kgÍ^15QUx70 <"xWxڇp1;~gNEɗ!x )V9@@u7rK ,? Ǽ_+!p/IS__5ruUi)t_=&H=w}99W0hK^%pƷ?-Bһ9xgh;,ԇ|#,c8-%wYޒ҇8-+čf#bzrvlS600Vr&?M/\24~/ūчJ F|#&ԅ+[d᩸ {hpXX]ͭCɻ)&֔ΦnYhZ(OǬn1Ť.e> N\ SdRȽ)Ttɻt/p0BTFf鴕$685Қ5#_rOuE4JufM\ƙT;Y 6XdRh~N{#N0U!Z:~mY 5gǓgpUՑF줽.Ճ6ʬI _nfTl:ĵKC>iP˴v3ኲ]:i],ttP`gؤS.cxՇv}|j`|Jf 6#T:gw3D.i◟u_rjAD;?ѓ;'2)(s/~TW.JpkSdA|%W䨍"0 p:hࠁF<7upQetFGpB2  ?rEV`TL!.>nb6>&,46mǾH~>n_e׸s&Iغ,: w$ba(4'vm6eo1A 12{ @܏/YЙ/nU-y˜,ɻ|~Ru,|2r2QX uR|HC}&| uxW*!55@BZqt~3[9X{JcoX>wè,մ4$%}'I@bYқeўwٗ}6ah1+dnWw|eNPmW ] +C3=ĶLpD>!b>A meg5rdjjDa<2c2A70|'~:(2 Q(e5יznן%D6!ξd*&ev18%)êH>wo '(RUv,-g p IهxnЩAWzbYPc|tڮ -7a[oGƳ`PJ!lze@A|I FGBҫn뱙l9p"vvg]lv!L`O:_4(S;=eLf7]3i[N>Bl5|j%}9An 7l67ݲJ,-t7vx+ɬ\_̸CEhLk `P s؂;|{uTШ*_]3DLӆd:رol}=_/.0ؗ̌`6,6}t73WBm(k`3x1=-t־mK[_ ,`^Nn&^Lpc%iX\/^S˚4LU9u <~5K_v'l%:]6|*0G Kv_;ri_m۾`2ltXB:{'YKoY}l`krDDj૞H1 Zcq+sTXιt0b|2&Zw7yka8f`wTgrU%:?U&/W.Pd3*Ut{np=ã2s~!.sjw.CiY,xKv(J<Yyl5@峍4pQSgρz`P<'iD߃<~f;=bu[t3W&+ .b'#bVv;m ч|(Z.EڦT=SOYj#S^8;!Y,Q=aJʗ΃* ]nE߫>×޿ ^vDJ3C6y)cO&AG<gA)7wj`eUw>d3;wz\.W'V/xeϣ'{NЂWH~'K—,F *E|l (?Tw/S:]NJj\͘ tF7 `9dLfD^Qd3߭Ԁc_IP.gg_>OLP<0c0 }mt:/MG9 8a#}uYނb)c݆Sbcf,?:u  ph[E-9sz`,3{ٮKU_d-ǂ8]fezEiv(~9g T̄ -\꫁'j 'mGaөdYxN*"}}E棯wuzF/ݽ{pjsmw6ß'>j}KPw`o|=&6]swo)݁~L@ <>5?OrU?Ҁxf^w 98x{a[ b&0dj0e笪[ݛoe;c(]K#9K|N5N]![n ܭ@o4}ORm] N<MܾxͽoPwWQS?j#bu<.mr _8AJ'\> &z癍ґJFyu بˊItst,H&_}#2]: .YtM4qcQL+Lѕ7r}l">ixA<cp?%ࢉĘԫM-GomQ;2 ҃"m|Ois^ oڄy1@ܨ_ګCjh@PŁ6yr#6 Ҳ"nb8y4\ Pe,D- w9 .Wf%TIkIiyynpA_yJ`(kBJD!3ylw L@@ L3 M#5o`慴`A2nr@`ȳzZ`ʀ!L|mg{Ìs|iA^|g4.&Χ35ulr2P(Mu0u h&y۪E;Ӏ MsЧlueO<7?yQ>(]l}YEÀxmw R] ƛ_.12pz 7]ɏmvx?Kׯޑ{}<g!|~AsfL"/M`-8Ie>H,hpSMeŷ:D|@|_ߦ;>"3gk6 7\*32 [,7^w/uG;( 9YÙbB2f_Qv)O)B^W\D)_F=xo%va6{WXuaa*;?Ӏm 8*:9AK솛Ρ{g~V|h8C~l{<|u5E:{mIAmW$M?'n :kxGqt/x?mݻvW/NF:re}oV#l>m4Ev؁. d+j1;iȖ2JJA ,wr1|:>L7q;,. ʇ;K6ē$n:IB'`evE4; ԗhN:2K]¨zkx>h(#ޑΚ YQ l F'e}Chz%,4͵O1xAj8rSZ>@ mJ'"iQQۥ|+ yxs;زpU1ܾ k>Qڣ#u+  9l tSGa  ^/{E"N+TM6Yn pZ tm3co__.3bͮH~e3zc/d56d}:tY'G2o՛+-{j#vbG@S<頁>m;j@w 3Np0g hmK/(0rjߓ+Ovvy=C p,K/8|N-)W?JOZn骓iOӏl𢏆w߻xu^EA}Wtx+_)`RR/8-ɤgSq ի:\^@sb29ؒͽ0Hw`A_ꋿᴏd6 \~8N 礡Z"~M@LտIń\Tos{{@5sY~oĊk ~N6m`ب.GnZ0+KvP|xnrM/~v{ѿl ݴ$F1RtLv:Iombo> zGZ)# 6o} @gٍ)A-¯yDPlǔlfŋadikXk4ɻbCdv!Όj)v`~6"5{ LkIE0Gh V"ŭCf:42:03Zί ϽK/_JTUv #ujT=٨-QY<`4 U׋Wn-Q!*ZѪIwnM\$R˗cΤ}yb_.:Z8 w7MePqNuf;-or WFC}W*h~m!<"XH7;B4q-Zx}P9#/霳Am?GFhO_?hɇ;`$19bi{MNաu;`Ӗ \ G|K@ ->hG݅dáO5n5_}.`n 8˫s_[neg"p-Od(q'dW0gkC}Kw.fx%2?^;Z̲^tʆ͌e4h&C0n'Xm"ß!N.X6+S&FFbEWSgvbl\.?xr5p fRIp߇12g>;-7&t% ƀy?_zަTW,S$ߴ\9J Y{IFy7:u@>eI阧L¢>Us a6>xM}7s8W>lՑ7ةt+ʭ-œ{ӫ}\4,:tA 4pA \E0_x{D ~h~4b usۃï?d0>+&~hh50@yg6Ο-q"Z針b#fE/<8Fc5 Goމ_h}7KȮ񡜽S3\Q+Kf`]Bs)gwW~ZM`ge@t2#5e#Pn,BUBCg`^g$x8eD1#X_ˏёK7 N3'7drJdgieW_ush+[9'^BnOI,ym@28j]H֝XĮzc@IA;2p𓏞o2w4ֵ̅ yMc GM,S$ *sM#V`7669Oo.>AF.{M+THMf$fTPU PcWA1ĕ2Nc Wө_ȷc&`lPс]ʲ3Pb 0HcIeNxh;)W(txL'Sdtz]ة 9ۢ k&JG0%dN^(dCqA =hq$mH5_(AW(۵!A>yx\Y頁8hࠁ~Si}|U֛55 WGjU0%Li3O;38 IHәXt}p{9|DPp@.G_rM{Sκ@n8X&%}MiSP|*(K * 4x?~.#L I[YegWME"6WEn><^6:^Ũ*ĽʗrqXё3z4U?@%~@Z& )]z-Lq @v#TY"/^V$<:5>i0fԀ,X m@txyx6VՑuv9l+_ ,,. KꕶFZ"%4y0pw\PL`L]: #"|[` m o)ea|Mր3(A4`0y( + j_҉V+;G+FԊL{:O#h]~h`jLYExRI >,NtЀRKp@lI5xep]]In XObq_= }y,^IЀؑ].:V3! }{ՙ=(>.l}:˖;0]g'g!4a֎ґ,_L*>˟$ʕSYIoR:b IX?\uH 4pA 4[# ѯ="*W[og<|&~3H0b>)eL'6ς?|h\̢i׷o)|^lYZ>4Kd.%-cp{Mc_iEq tSG ƫS[IT B2m,f|,1/!gV:6*tHW u<{YW2 R-^0S)S ̀m(B8?vQ拘ܒ[IlOpO}i[_z1OѼ-$\ lփr4jlkeS%:W<jP&L $t&yf'vĩ$e^T`HBޮkIAfGїn˸騊|FKFAc<$_0캝M/v:gb;K׶GW݉ ܋=:+L1|})NԫgX2fh4#'z:~ԡ\#(QS9 k'I2!_uj̬H\>5I" eG ֜?A# 0 !$~lЉlx~(<^Dfpc7oZ3頁8hࠁ'X }O;QO.ĬЧ!G"{ɦy=8[j0",!>7s֝kc59>z{oo& u&,໺1.(ƠLv1inE:WsWH f\@ L@V974+\1 L]!^G=4gob,Fi#M< r\,X4tїz#oA^%iAFN j{B񽥉N(Uu̍g^aB+g%7QGwtzG^p4@_L]FN^ȧu s_{KӖ <#b^ήԑ|p6Rl-S~ ff@]L̘ÕB&}z N25;Iù1^KRx13<6 zf'3]6Dvhpk4ѓ>\h:E @p}:)3兀W 򄥎YFsSB~8 3I8˦ST`x$e-gnO' fY.R }8>{8IG :iYw(uuQ k9xrPC ރV}Af9<:QO-*Gm.$ΑKt}2ͮ/~TR+U<aґུjoYeםyd y+<8W ֧sS!*7_N[gӮÝ׊e4|c xZ;.#~_oGG}$8hࠁxhAfG~dOGd.\n7 dr?ύoo_Ol@^~"08.FW?_iu7 Fp`e` IDATL7J|*Tgs}$Ox^{ X$hs_KwQ?ᦿ?W zrϵ+|7T'ztQ1 ї68 {BZ 'k<^n}r" 4'zL}$ wꋺ#|N xڲ*)pXR&4&J'ž=wv1uN+Ft=q7wK@kf1@1:[Iy}3S;=Z8m>_20'pF7VN:t]y N)!-NIJL U3:'Fo,3{8 e%4i].NX2I?{eؙN->ᵝAdL,ICԹ蝄]RkeZf]'ngJ:X)ECAgBع(]zlz 5 A'i< pH޼"! ,/_eи`Y|=.W{H,Q xş_Z1|?zPg޹vE]kiꐊˠK>ґ5 lr6>%R`-JrPJ Yz.L/x`m$0NLޤ͉~tG 2}:JAa}x2O?JǧSYYa@]C& _8N5B*Ke otS8hࠁ8h7 J}wڀ,OR0d05Y<9@`,4~u?ZNY@eMCgx e!AoV}:Y93#~>a suD2._I' %]ڜO]WXWغkUn:˺)?X4 &#焗:Wwm_wzbqCL$NXFK[a3H] bjp,+xlr`C~?jSWWȻRϤִS1pV&6P&yF.  gE焨>e^}LWN1!ъuA2buHP eg)0WI|v2DAnJ05W' U7a06(t/^v]#i|,r;(ʐ;t4eA)OtfTPX_E+)2io쾢 g! ᒵUlZl jvXM@݂݁D<1 4\=d6 ͇:tī9>(0W hx=~NxʹP%y7+vnR̈omk_ӀICAtB_i?V!pn(M&o_ ?fk%uH3`*d/t |@Fip׸zF&k@s`iN,_ |y߀]կ<ï~izU~; N 7=wk0)=/^'e{ve(CF̏4 }†Rџ ޺ĬΤēOmvwBqtmȶY5$=b:MƯdC=~RzY$ͮ˵Gt݋@{Vچllznz{RB j(]Y1EY|"MڰRhdphGV6P/VՂa k 'TeCA,x.*\O5n]FDfI  |̀$G`\,J(.&`wO>J[! DnjD)$ 2בgb} *REjl[WV6a2"0͊_{ nINTGކR mk7 ]0uTLHY|)vVFN9ׁ 14}5g}r/5: ͼs=[‡y1j2t2xDv) S8uFWf)Ԕ+b5ڈgë!G ͽNlcVDHGؑN <`F>TVl'uBbWթ2XS?T]N:m:nr}SxEd0+O~t҄| W1A}:/GY\|3b~Lb5ܝ#˫Ax 9 nV=#+s(nq#j=7< #S /usH ;:o"]d?V~KDґRw'պTb}f/W{G8wն9+Gf-Y}x3Pn7U4 4-hYb7 ! x@ beC{APx-ԘA]3o~+yoU U{okG>kEĎu,Mm4%A"vP|H{1.Rng1Jq<22N6FڏsBQp-֦TVRvHXYr٣1{YP^Z?Ձ:T:|dyS F ^N&?jO,7'!d)?ʅ]G|ԣֱhRLfs7ZkxXH3BqrD>6FN@0tt>F;t2hkyMJ<U̇u cȐ3cV~iujPB7Uu+kGVg'? ^4 iaoēht>:#_ |k^ 3ɬ?'.ӏ엇7My3[1ʈ'֐vV:՞datA1Q;x-zÚMo!Y+`Ljha[R*`v]zbϼyQ>EW˪?U:[Nvʇ0^~@]`)dju Sۏ7!0^.~Yٹ}ͯyqJ`_/wu(9mކRr\l A_ _Ǚd&y JFGtn})q'cy|4&(X1@u@?N4u]{ sφOexW!]l 6;Bq3nwh)k-~#;X>1%7tVA07OMOf}+{12>|f3ȩS"]'nCVGdW o[1AB3<XJҘl%!1#m'?a Nԓ8<³ *Epdsa/.}\6P̀qюC2lQ}Shhqʳ?Ap4fC]'숅kڪ A@>UJ<߰ #0k125QOFRX}j ٌVz4X2)q}|ЎM8s|G (&ϡk mCdCUȷ.kl2s<NRtaRKN댫:;4O?\v=-%2<]ԇ<;WyAmZ6k:=ҍ,36(Xeَ͞,ڂ) 2u"@v fgc~ "c;|"X_\m7!mDB^ӵDh۷S0:ꪌPr A ul#######&iO|6#+0)ƭ03O\3)uC+ ȿ6 g3> }(™ʭ!;>-?ٮ7a9x৾& Mg `o}-=|a4d՞% =^bϏav{nڶIM+k|z=:@ӓ>Q>eɠ*,X?*1|~ t9qw91Ygđ@=ic+n\$B^x6B'=R(]Y@lHSQQҕ-V mä9mKo;~͠~_3նE ([zіG@.<M~Uf` }TZS9T(}ݥ*mʹS*f&ƉPvF ^ nc~T@5D:J һQj6–WP\;nW|O6{@/XC1x͌sP䑣g#)y+dǃA;O]ث|<]0 ]6ۨѣ ^~LuAGA1@.MrVySpo<<:bu"zW-]^"bAKod1J8OiKVdv }D&e/|.}i'ݎbUwz.g3vyy|va=L}# TD6-譌91ʁ(޳앧Zq_ֽ \ C'c>n龼eaЌ )+~)YlG]a-|m^rsH:څŗB 6"o7bՄmʇ!Lj̡V|2Bf2t- /XÈc 9hZS(tSruΣuJAvȷƬ 83`C` V5|[h snTG>.j$I7+h˛+0QEX_X "\c !ƣ}sF^)0AI޴&$Y` ԮSXn-;s!Nw o|z_~ +] O@7^'&Q?\BFg:YkOiH;8mFy<V7Oe6bh>NULgg'^WD7nfrXjW[tQpIJ <*V@\Ʌ^{a;;;;;;Rx剥O4δ6cKݸ4*xkW*ߨY|$|<^Ҏu˸Dr{~\x#GV*uEh<1N'o8ϞQȐFNkzm /l1^vY&n>6 dbz 2Ó%#-Odm+v% zxuz'l}M||HG}Sd&Vp$y+U5ɜ7< >aD3BhĒ`IdcXTIgm}^xS`m̕ޛdđ ]s+О7H+&#"{x 60+XI+0'ahj:V2]ӈQ#Sx;asb媋 )'FU.餤j8Blƺ=Yth#zS7瀾28ƙr1^řC1LyhGy7ÞKھ6k=9](j{s&#a`Y 6`5zO==r-~Vd&H0-~cswdT'vwGjog wfU~E?χs>pO~%U[=xMxul{~>#^ A5~^~_Aۆv1_qAO+m5ou'r vk`~:c,=bZ (_@ b(ܼNiof h~v\qK_cq$p/.!ŏӗg_Ҙ7RcEિ8[ 6Ac1cʊ| IDATzA  x:mAvul.&[,6:Q0klB\-N%A/!Zj~\vdki<Ʒejv V8Y{@L"ؓ1&:s'%xNMTbQ{[{9Wo< Z*?N rG2 Qi-J)R&@OC5h#C^֙[Z3jsz&k* v6< CɷJwwwP.|`2p`)hZu` 64GZ lgkӛ^džbCXb'nQ{Q٨G)2BϱJf.=mTaCy#$8yīC7 Se!]NLinRxةcX ʓFu#c>'<']xwcvt;/ЉgXC]@u}zg6вߎ cCz@ pAC[lK%p|Ċ/GN<'u@ڣfv,?uڒF~<?exhhÌ+L1~|/u܏'prA<}m=܎ټ(d(5;yA<>A|z:lq@Я!ob%VG~|rOz윐_]笰c̤0xȲ)o+/WgʾcZ,=yvZT?ڥG";I{K_ZbN>J uv$^ %Ŷ\Īғ2KSM'םOy5]4xflHz O#R,pr(Y{ h e;}@Dd#ly:rgخ26F1OX'$㡍oW],[#!3::K[mhe]Z>2}2;$YeL?c`ɵh5=",W}\UA4؎f~Wa$s3,S/b2 &rcqWZ50Yr=<7SS7䪧)g})aFҟr M/:9q3JqX]s4#######fM 0@$`2<?h9{?GeHL }C+.::DN/)U ߕ/K<*c/|"|Y;nW̠K3[N(TfB_IzcBhA6[?O\$R q3;<ĖuXqoIW~*X(G<4A%A?3 z=6A|3ДwvحS>탻wٷl[_Slm3`w ү!޸kZJ ηG}0#چrgՁ ۣ+7~?3P;c}9xmeAœR!ey utŸ=b OTw5֏~4(N۞BK~$7< _1`2~rCtoذSN'|pAnpAJTq3Fb 2>H褫F(đ<P#D;Kú(/XJoydrI]:D'&ɍ_)`ŲYAQp"+X.3'F+> s!9r|OA:zd3~kxru\7#>-ɖN^|OBL2Rl6Gd2Qyٰ֧QRO(i]y:,/N1^23o~l[ctQW1Yd]m8ok?x;-~/}\%VbI#O[7Pz[^Ui-a|JAbљћÌ6bЅs1%SA;KʟY̠%BMEڙc$]{2^VLG g36+ {{V:Zj7X#4^vT=<)KݱK; }F ni'2TQmV5lq{@v+7Gmmqnգ7d^{.ws`]Vd eIﳷC/;f\k=@M#2_ 4XZ^44 mUD–6 Dx8!>M(=;A)M}1C ,ڣ slgS1^en`džA@\$G}%,%ck+bM1<;b#b;;;;;;;oB@Yǥ˯r Xds+Ph~zI|/] } L1~y|,|Io.Ÿ+wSPAI;}yXh  P>̣*h$ 31ԟR?I0yLmR/]574D#rr:kO3݋E"M`f !J{'Ôyqsu]|) g>~j _S^1brlQ]9V48(yqbӡbK6Pr]C/7BW;ZQLFj:3қyl{Bm4uL0®pnh)8I `e9W#6oJ1>mb3|N[M6Y6c_9}59j0Hy},.Q ?ϙoKSrl5i$=:|}' A_1-Oo,o&yM _N_VlWz<Ho7⧳D}A دa@#3x4mNRںWSx?6)h}?]O7m14L}k|b_.gw_0H|*z6U.gL'/;sp-Dmom'^% \Xƶݜg8RpA@ Fo h+#(c8]L"W8~$&^o zaN֫x *fa "D2s>A9fF*(26o}2!= h 22eH[ʋ#3J,@U]+`L'%Ү>g)2Ѵhaa:3'n*Ҹo#tqL|lHJ#> ( }ē:Q疛s]#ɮ<@zYLG Y.68W 7/n#}F7ir~jC5=8K?; DӍ+T/ʹe{Hږ^)g۱uggVʭYť"Vg@;z$߲@Œ@woX,RJXԉe=c7,uҲ~fp.=҇8VtO]16ŵ6JcY?mrGwG`G`G`G`G`G`G`Їί'+yt?,q֏2y|g}\NH?'_gվo{v@$}A*}=/ttJ\4N[|}a12 *_M %ȣ0W)w^h?|l%f wz}9Ƞ8Or #}wW:Y&V- ~{͏w&C/֧AtېV'mDda#C T9 |G W9FF81ՃK(mVm`/ΓOCtW=lpjk/R0hAY=9뗓"LShVh}݋J HڋA }D ci:FtJb6Ԕd;[4Me QDw`%(ந Ārl/Zޛ [7zǎЃЅs- = ~5t'MN /x^EYHK$s M@e\yu.;~u87|Yi  _bfn[|RNSAW`wս^yegbͭOoݽ|Iҵow#SL)*`յXUx ӽʔtupX ?:3^jK[6) ioM6C^!h'_"jLxI/m | #y[W?~)m=؄)~;4n+Nę&Ifk۵>iX͉qm yf2b.gWd*+Nֳ2}24Xg_Ї#9ҭ^ǖ w`ʑwzY^^OmbVܚ9o%ClPZ$dr }o(|)cPW?}5 *Z $ t6r;VW-ix, Srhz%BNglwSfIqd>a:6v ւШy\A6!r_YtO-^y-waM#a C IDAT{0pbgUO\ݫ_{䖭M:,K4$xyC{w5J,1ƒ~J,ҁ?sV'rvtz|.V8ΥڌLcJi f5:*cU._hO7#B2B䨋"ڙ[م^RV'-EB?;;;;o s'?_ө{'~d4v?2F-b$N}>gm>T 9˭ǁ[qBP#!$l-Hw#BgkzIb W 2Tη>c+|2(6xGJ"҆tB׊PZ>aҵasɠVݜP}Г@[Vn3!6ce|",~ہlRw#Iq8SU i +V;!j?< uv͐[7>ɶkQW1ԹMJ4yqm?-d{885PD&N-FK_c^۞3 Rzdo0NBC~i`R@A,RĖVNN#0cy؊}c9\#*xc:`G<iO|[XD~p YfM"DO'OبLչ )s-PNu`3-7hSfrpVhGlcu Pe4H90*O@ vrip8`ZvH`㬬KȕMl3L&G?m#UyG.3O>\1X/;p>B[LHKg:!\K>cp/׬qA\d 2>~Y>4^2 ߣ^;>!G5AC/6u, fo;C_%0gr{e}t|;Vl2#ˈtW 6ADoڰYZxn[?la<6}MhR\=w锼ycAoe:lPo[VD-{\e3?L\?Q8d+)1h=>d눥v$~٪6eeiiu6ݘρQU6|eܑտ|oSցtŠsmcx [E@T8^&d턷 TGVP\ Nfגc\y =uct}-1cWCH~NExN&˲x,gH Mύ@NZwdGtj2>Ny_:yl# Ei0GĂCz3njU~f3[>Zji惕XieHfҹ(gi3k6S(?c7omgȲ߅_' 6ȦCW>A=8gP#F7p_럟<c>7fb{lowDȄ\価A>p]'<.1NUZx.O^3ڧ81%ЭEMCg m juqBo}H/Ε1G̀Oj( :⏫T_ &@U > xc\qc=J nd"= LX\?5l\?"ɝx(z}4V}/qԡ!( ˾Gk[9Oia@ԫΒbV|7CFoV>@@]r F-S1@L袁v{aQ`&: puF;yGXy16Rp݊;tbF ˾T-O?dLbtbk*#oC:.}]qpp*}*6 Ʉ`[ڭZ~+xNmBDhL,<*PזU?Kyo[RLT'>TAujF:pRzdه*8|Lޏ~/>S 3t}g?̱ca( \>Kud:Z6:)^_^U; kο3񓜨ȟfA4Ϗ߶Z"wA㌶xp^jbEkj?忩\?׸@~e<xX`s,{)_3mWT6?/FOPɷtF6 w fdhxnL f> {w^e*LxlmB~8fpѥW bQ?UPk/?"^x.h + p7K(ߗۤhM7طL&֣ 譮c$ʺ~Aڣ`>:&@ƭѮ8ͷ7p&z0Wm$u zp U:HJ( %#_؞CMrSɱulҠa~X6aMͷ!m=ɀFT'S9b0řC7I>,[7]HSG:|(vW2ZuK۳bt!M]V1th:!O}!Fa17lmP#4!<*ו4cG`G`G`G- ŗ^dB˯t8#q۱yXHXjG`9g7 "r={[G L[0 *8ҷtY:]3kꌥ @G"G?'Ky>ªNrwflIAY@~5.%8F8&?N2,>%ԽG!XC j+[1֮5ZѤ@=ՆcxW>*e4Rp Mè*28ye( 8&VF\I1Gf$49nu4 il$Vt\ߕ[%pU,cvʰ0Ρpp W9&BUlk$La㝑Ze4>bٿʕW`iV L%F^iD[,:L':Ё '[XfqZ:>֑E֠>?Aھe|Y;^I>s;zlz.; gA}V]{yvGMo>#yNپW1`% vdf9W& .oS8f쩌,=󉇋>0!  Yc%5Fc;;;;-.-s~A0?qL䭦|X/s@naN8Xd&X4Wֽ9pzͯ2}4GkL6YI;z|hعaXT9xz #$(V@j'C1_6c!Oi\qlS' 4YYyrT^y-C_Vܥtѹft<?6taVoeSX "{^RG_G2褁W܎m+VlS.8xMA@TѾUfvܹH~vo㈝2@3uJPKɨQntA[@-ji38H[:nbǮspO|#mbQBDegx1IWiVGc=hzt1VߢgmҶ$O}!.ZuoK:pU*OāWh:&y?vvvvvvv@@U!6xO?E)BO'?$YT@sL@8ӟ&? |J>BxDD+iS&Ǽ/Ґ/A*[͹A&Wִ<\iIJpAZ@,33._WLrz@+ ʠ1k-9~fkb=YY7+\zo3PޠQ .MHi؎rq^9ufJPke\ӫd?u#[Lri k B4wA$mob$̥)O~LI;IDiYFA0~DH0B=z 45*fzYi9I>nfős[r< q;X2-EN8QŁx՞ᨇ xHT湯kh$P]^j|{2E#Ѐ^ UbQ?Bܽ5o1r81P4ro4x}GRٓvR+@ު,8E&E{s̛lta!W@ ~1E=c |8P oP(Z/#{}݈o Mͯ.'۴ˏsN`]ћ}ܛl M}YwZ=n==dm,Bԉtr$ut[-cENlneoߏ=;( 5C}}$77৴4_ssSk/Ac0]PE o$ -_sϔ+3,r7Qzw<E7׎mb*[@#n&n&_o,U#}D7vK+}3Spޜo*kiW61$FPG1 ruP?\:iskT7|{IւJ?dopS)&F:УPz;Da /sM=,OʜO\xێԛU80yNguM¿̷CٰN ZmƤ]XדGo8 3ϛ:v@lSoB,DLȉeIGG~\65Cg}UzV^yg}~~f(b*΀8FmlT KӅG_g''UKyVGZ bi3A̴qO3Oൽ~0vXj~SDU[ko~~7a|&͘| :w]iߋH[{ 'Z ty=m#CS6ڋRSW &]7"erJ|,db4c'7t?;Aj9:zg2rz|Nvy9j"gV퉕 @Т򸲑]\ S?皠ˋ:_'-thxZ%0@7! >Ib7\7 L75|VGnن/Fv-٤C%wyk@P[O!VK_^(F-HnqA> zoduim0UA1_"m9*[Dܟ[xm- PFf`:Hmyb^]ɫGwӲݐ;ˆ/<BXK8A<IWzi7B0KHcSa<ڥo|SEkmUy y=s֦`k7u_u^\6\~nݺuqs?sˇ{U7U>?燿g=\~YY>ܽk0y>8/8\\敍M-wн=җ7 ?oz"%^qr^d({JO34{ͤ操+xAw[Ġ8 ?umRu+X?.oSFc3 \Y I!}d9Ɍrڡ=9҂>.1'\`S˿?jp >#q}6s%[/ݴ>%YVr1qLK৪{ V o-%7u5kVAŨPܣ N6_[_LJ2, ĒmōaJW%0yM݌U/~\ +A,򝅷-ezն M]W(cҶb(~ ~՟W`dU HXXaZ {(7 MUAXj 3U-4YAɗ @ {yY7O>VT*k+r~x e@l-6F JA:_v ,ՏTcs(Qhavv3U,d3xjڭJռMlR^m7~8P{@Q3?}}uj7(֛~%vZgӰ"] :ږ9OFƩǎ[Eݳ~oo~78|~c!㿆הHe e˿__==(8}~Ỿ_u(uH 6Um}瘀'^C37LW7ξRYcun/}{oJV0y;K]r;2wP \9g}e7f A&2ƷUH9uR z<JK'ڷ|mS KyȘـ>r>A`ӪY ! U`O;{i=d|lQ.:3m]Gܼyw}}_#G?'?c?~KK pO?~G~ Ȉ۷}۷_0@>V U !C,,H pL"A  i~\uF0:nv~}e㟵Yr׮]&64,0sV) X薻|}MW/QYx"I_t1YQ=0*/0a+Q OHзkC8kLJ460BH [Ͼ 6=+Rjm'ޝLoJKmS+=DFeۆeڇrw3lX-F{o4KhdHys^ѽ}/yMA!;mmm]3-ooOOYYꡍcPnC}mgl(iy7 xH䙟)rLKOutmr] Js` d:wyjJvyr9a nۏ++rs++?Hoo?8 a05_5lUySYemA&[)m|a۲Hޔ]YgG]x!y~|Y[O=zyyoom&| 4{>?+k_sMT9o+$zq%Gl|ʧ\%-Ҡ&AK5mV೜W[z臱}{?ROߣszy3~&yesTzFn c. \RBMIw2ϒOS W'X~[čngGG|A7(os '9vN۪?7~)v*k{NuD ) #JF-b2񓾶5Ηϓ[>J*8?u(Iai_硟z\9.|\d#s"Ά hԕz1S'M;ڬSFG/2L\Y*8[=%0vCdG N_}vUjчU7֛2- M;'Y*T%qЀW {!^pS2QDЭ8 %qup2H!yK.tkT;2?tS [0,+GJc,yfbO${;%36Zh0%g'FAwGrkoFOx*~BMKϻUǹǎK7 t}[Q:TOu2oȓ.9:x?Nٹ_UJC[᯾ tENL =)o;a'F}3ʂC6|pۥGhoB۰e%^/-d:nua/ߖy,y9oc7(sum'SY.VTG1L=fk/-p IO.[####V8cX>^8+OÿG/ɟ1i=mlX9Ky Rwk:{pyvlzo,mݸB`~tO;?FZo, ?cKk,&{9} <٫≮lP㔄&(}щ hz7~ei? 1hŧ{ʺ2{%\#c/,g/j7} єG{O26 _|$}7-9u->=;/nߝң WKT' { <@m@x_a=>o|q!|frV qc-^օx:+4<25W8nbG_&r5>(, [3L3=U4/v|aO4%`jC1.'@9)yP}Qp 2YGhGwQǵ{̥-1(`Í*nV>_|P,̛ iId.(+?JFKi>k@h+ӾOqyC91<~^D;4 rpS5^8z.]P `EJq["*Wdh?1> qG*CYL/y o b%3BhЃ8{UuʁWRPH/rn^π:W>-qWxShZʐWy, 7@[6 d7/&4mY-vsɗNKS7չBoY6y\nmeO޶[?C7u8_mi&F5 Dlo(+)Ӆ ;Oģ[u}[bG5͞ŗ,o!pl1Q%Jѵ}KԎnmwv=1a}QTʹc~78Ot*/,6H%A;}{[E'>s>__<7~oU/7q 7n{[0kr9ϥ7$I@n46Nha0 fFN$H`&Aʀ,.t}/yުwiw«^[U}^?g-;ʯ2z3>Z3| X3(?ǽruۉ%ڐ_?oO)^>A`9[m'lk0+_)ޛ®[PS~3GA}o^[Ln⠞u5_fCfǯ2țlxc |7LA E0K6[u"?U}gN" (.EG?5=Iɍg[} fm٦6 ˏ5>v[Z&t/x ;EUZißW Ʈ=lCGkM2'dX g6Ω!;8ݘB]# ?LY%ŋ&b [>&i#tFk#Y"Aazh l# cՁl J/lJA&@CUŗp֎JI'Ei`c{ DY"T$#Ľ+u1 ם? d|Ϧ uΗX-۠Y 5`tsvS^y(%i/p̈́<#:RyRfKjBh{ỳJ~F76™oޢ#9yuŹ߭%w&ٴe; ّe<-kg`wP/x Sfq;}.yJ7m{SQvd2[OA-) IDATUt iKĥ-ҴБ~m ֶ+z8N8iँO_Wx_K^l~Z[5n7qV-7}?? R d3`3_~^k qk_zgo6+^8n/x~~4_EW_yps<'2xfßN/<'![ߗ^tɃ<Ύ/_9>M/l瀍\8)I ?g) <pcA"U īomg>m.@Ü?+ ZL1N KS9mg?e˭*F_1E|OGVtXuxӟPݭ/ekZ?*OUxgOoe2/P?N ^H89`^}qGzC6sK[3rcf#-f"ϮZm[ MO^GP $R6Qfϲe3ZryqlbAP(9(;HSL``Rڀ^ɓS:iँNa4(֏ܟ_?Ϳß_v_U__O?yn_  4O;_:>/ Nut_//'H~qhIWno9 ,&I۝ Ώɝ>O~,:|QY^\At< XO]-$ǙLw=F:Z2bo@l^- u oqX,yX Jν љWw[>cʐ,¿/G*P5<|^#[π:ھ>v{}:`_kS(Qσ)Oo ਫBz>qSoh|r>)>MsNG $KhǩQZhmR} )W]/ o pgVÄ6&#)`<"~vkjs@kΜIV)sѬEO2g"$'4󍡸D^dJHe0c] (ɖa^z 壃1x;pl؆Ml!;cR'H(ɝ1 ֠QI_ nS +x1w8AQDt1D7C\@ބ13lr%vf׼wϺ7Cd'>~\1#pi`' C'*J%]ET˥; ü iʧ@Z0}#DFuqFP5U)^pʸV@ |mրA$Io?me{s6-n1 y"? =هKdwWn%NpQN\2u \4M W'B$!瓈VCϠҠl$;6ú+|;yDvO[:1Fo<үt(fHN餁N8ik qr;2P}_hw} i&>e?ggyn7/?3qc&+_9y7??ɫ  Yt[s=Qo2  B_f6.W-}-}ka<+6H?LLZm6@UH/o*C>?H-Ip-cxUl.3~20. <_8AW\<w)=zVL~!>1UwM]ηПCwR/{T@Ufe1$ x LELxG렀" V2L0JNpg 41Bx0 0-v.X)" .7'Ѹ(,Yx8ƓNӉ[kC  vrͳWR, 3I@-~HftzVE 9c$t7NyzWH^ێ솬 m nSۡ^-.:]@KF_s|V ́)BL3Q?"0\G:iyݱ2?{G"1'ѬJy3@Ywٔ9M4DISv\|J1KI%S:iँNpn %/<+O/8x|__O_zZyC 4ް Շ?_G]~ی_&~|\/ChH?&cw@"<p_sVY'TD6+; {l"g>+t=o̘.|S)PCeWs:^|O@mEib/K"E&Bz[B7_ja S/W~:5t@æ' Au48noC C'H3kٳ'@ħ| MH HMfz3e Lp$grQW;kpC7 4Ty5ɋ2K$!d~Lo'{wu&]O KɆ§0٪:؉t oաEd8.j0'3Y~ GNtX=d,l@[̲:C,cF@قlO' 4pI/xo}0B?hs\2$&|_|] p#:o{L^胟a_7\oWq+y}tu <.sHo|܍ϣU|z|ahAy=N_J?ƪw9m>ycyCf|}ٍMD8;Xs@?ɗ~yҔ>&t9_Н ?u!oM׾| <]lof:[>q'Fǎ"}wO6}íw}Cl'XlGglp 'm>8lxj|qRD|4. h?~Hv>@^A!Y-4B$bEb&W]W|Á0uPcYgt햣-FEQLqf)‘W ۆ$6KȖ(˜xפضI u0X8 y_1ZGiE$UFK /42 AK;/%hps`>z _W#YmMP?{p-p9iL  `Hvr8Ž/&?x%k}&[kI^UtŅ2Kٟ0e|{pYߧtI' 4I48o't4pA%V\Mu܉lk@ͭBA!gw̢c\7Mp%j//j07NQ>!eY¿:0g|~W,^]?6g|'}Ǽ_TO]Z ơѡr抏{_hODLo>K.Ӊ ni}_ |ay֗U]7ITO?zIۜ"[Ao\ۅD7;aYUbhWO"Ufкj^zĎCL'<>'#Ws%=C.';0֕zobs^9Ð*Q<1*͹ŋGzi;_ʴ&b?aEV֚ o{>g׵X^xfKN!3<ƞd``WˇJ-e\w2ᥗwoGwnS)"1VcMy`;P 1ykۑ0PkGts C?u9`GQ u&埊[ e4V?io̭g֝C`bMo4 >tD M~ychE F{脯_NBg=^B5sK<|L/w \=R K_-ئƬ޸- mDפQ߬KP:t=vq`h6@d;3B \9GaϿpG=uL=x{ɒ-guTq LWˎWhu2D2. c]o2uGabo}ҧAtI' 4 5Bz'O?~5t 4@fr>dz`YV1Ї2?wes'K>88/%ε;- r໾O$W {" n])yKfg+&'7Z?5ֈ_~3ݿl'b!:88xݬnԽnA6I=T ӹKL"ѥҹPp1& <`tz,&N.;]q 1?.WњC*fĒ$>zxJ{2:J!;el_57Y^ ЉEwD]Ox|A12qua]{Ph j9Uaf +@9"2-r×'e\UnUb]zȱsWgcVFR<2@ﻂw3Gb 3 c:5Akk. q4:XHurՎvRn(ESi:QO:dxQۈK] o{845]\Y:W`jǒ-Y-sيT|u`0*kKJڊӏE^3˩y!d>G:%?كɫQב_<0'*ƅ޼TF. kBgkGGkpՓ5:; "yhCv/ix_k&M39p(([Uyj eڹf Cyaz"#!O3wxʧtI' 40h߲3?$t(_TEJ8}C`3|^rR?_s_d$!fSlߢ[?R(P\ܺHT$ܓ\ۢ|]\szz WrWEqNݍ 9-}}ۜv[_ཷwdx<ϙ8 1YUn}?[GǠlWu~WtC^>2@= ץkPy?"5. XjؾDҀ $ x)?]OP`)ܴBt׮<6f e:?xd=Ѣn}+`}~Reb)\Cw b8v+Ix{Kq/o^G]p`K l7XLWK/K&1 $R%F+D$[U&wf9=/sV~B+OO\w8ĝ_Km_&OI|a 1(C{d%xY'7k|1I@G z"*cS>~4=۱k YJg.~Z^'!I}CHyQ^'L, ^Z%NMϵ-W''/E}IuGe-*3>q F67ÏlCۂEс, lCI$u?;Vyf1Ͽ})ؒy3˯߷n'H|)qrtdFkkt G&ze/QvcH)\Ė+:ɳ^K֝iO&ICgz:Cއ>tx n3nF=a^p D?K0\+`OadTX20Op= B@ 3|wj ?ReeLg IDATevl`j$' P(LƷ }=1$?0p1w[}Ȑn$mHb)|Jl@Ԡ%XQ&ێC̣h>?^ 1zH?zZMoRW;~K]i7wx. 69|J׬3D -Tr)ll=>d#BETOBRO6\пpH&?&7ACJ)}2&Xws. `%hA' wLp'>O]|$TԿu̞r4([?[ (sGc2 ~7#_~mcBH9vNO ;?ugY_.& xF[Vz"Y>J"V"zyXr}>x|yϜwBgp(_tlc4〡7qzIHpdLJ`;e{2.yD"|<`&-\&[-QWf=͟+?0]v!S$[y9M @<]rd/j۷"#=J}S.x78 !" U%l[aZ $S yaKS :eyaAĽ%Q>j(;Xp)ZLdJJi{}6[g q4S%La8MBiVc2Ա8@lt4_dg[u8K%0[yc~r0s$N~^s:jG'( {ЙO&_4|ŅL'-)n#n:Mh $%jn#ncv|/>aV&j`^iz^b]yРyNBH$$%kB?l(/mщ- ԵEϔG6}#n3"#LQ䥈X=9iँN5s_?/?; \<;O>Oszg?}|:򢹟DS!a|} },m^_*7 & o+d|׉ nO{d2 k>@BR L{U~P=s@ɠO3 4K |v?/_5k[!A.bN:0nvkvIlכ#R@x&#oǫWZqO7g&s 6Л0O>.GlwNvf}K<o#8p*-+ .jXjUG,|4xD9$/|5+z/+kMO`dlFU1SZ} ւ]E07룰bQ5K"Y8(- L) SueW? صgq<6%A0 q`@͉KDJeA%؈g u"⬘4!ѳ28:<5Ll0ۦ\p }HH3Jό I/\Q£Z܃O/P/ ydi-\qay 30}T0A-Oѡ,SGRn"h%b L|»%[{lw^}f=z8д,DoƖ:pȟ~:lKɽmb~տ+? P;Ў)+yB)z23lBg*MSnWNHI;1 @>xs83xc١WhMZ[/A:b_tYTtI' 4bp ?}S?S/}K8N3 k HeUNi^T;'}*[{w0z+Q.K=={w}~>Ir} /w&I69J\jRD]yڽ] KRO~ mL"R4v_.ו\~\Sb➩NIFc<{-?XJl^5zL[@zvE|I^ˋԥO@9yޛK{ȋ Yh@n|۹s Ќ % |~>Tu@G{&+Ѝ F0&e qS5%37\H:˗m'0Jq]q q5ge~'y|Dm~c۾0=GɋD~ȶS^ aD^O9?iVN=}!FT4IekϲPFajҀ1a9ΟhuTSt>yi23qejkȷ_u&끓2KWWaB8Nn9Vge'5߿OOً᠑΄_m chqH3S `P䨛#2"iS_ !u$h3H>h:}k@7I%1Phg1[J_ W _S_`pܪ3gi ̟NVGv1j(VpGla Cy_N=iʏGz˘g[`B{G@:Ae:}A? &u+^?:zHH|ѹ?Bh*5k.\}?p}HkNN餁N8ikw338Nc 'X_}K}]?pUgEFo0dZ;ǿp'w W~A-'nӧoKv \T_h`W|3)3/[aZ,F_a}e}-6{k7/o'8sMG'1ꕤ̈́.<-2  zDOmTLJnR]`n(ىbl 1'7w<{iz $i<,;w8^hcCʼncI=wpIX6Ùq?\4Vݙy홀)zг.z󣍎}E{6uvd <.,k[(ٖ`ۥ M*<N8iँN8ig8&")2rƟ|#O)/8wO`d G-Z0~oGc9T"2( |2ccI`4k=A_ /`vtb}5d08:l t\=l@Ϊ}?6:xW?ҔO˵q1NNY /[ uia'(~_^* <3I9](nstIݙx䙸l:̵mmb&Q))R 81Ai~ >ko9 MU'vP&xSE~YJz-W$;~eI.s{@|yW(|,wg ; M">]Ot$[!N Z1.6"4 2ӆΆXi2Rb 82O=bu{i Neic &;rAʓxV4F#T}E]AxXW@WYl1(Q_#g4ɋkz䝱A4$3w(SXHĦp#0NG3*%+z՞=N8iँN8i9 g7{N{\u,. * :C\շ zr }g~A.Yp'jD nt8urw@'r+~%,7ŭ9CbFJ),Ȣ+>n@=¿ | 3.ޥC, _V n; "#Inx3Q `gbpT 0M8@nwH7$Nx/2.(ƒG4 _mtS4k苇_xחQ m0Pmm~4a덝w&F2JTּMI2d@0"+ k|Et ͳ9[xa5h?q@K Fa1  (yZK 66i@bD>)Hh)`V˟ZF9d(F)`g^>b򛠧z,iwĩQK#]n[T|*#XQ:Ce vH5IAiPl}cL|G?G3c-erd᭲0hG;̤v=̬Hol"J N`1p:n6:0'ۍs oxGV];_L>6o։ YEyӢ;N8iँN8i#0LaX>~>_nqM}k?x_C}'Z8_gt ;~mﳍZ|~5l?'?)23>tāLv`|| :}{H[9׷Jʊ_n~!w6__gV0-o68޽C<3E,sAͣ| GJw(d`7ɠ_lpÉ 1:G~jb:p'[ O,#Oԛ:] wiIL{D^^2:FV;S`ccSpu+xe1EPclmGlFy-`ϝ'!zSgOp!=9C'N.:LZ/eó_~Va ,؉݁v1juŕ!l"ӷ8[9c  6 j zTkYe ʊH@Ǚ@Te06<µ}*;1K\$u$ASMNu}D5mz .Dpd =hۘ;9f8hEvg ;,ExW+y7C18Bq(}霅{SWʹˣwpROyxΨbC#+ dvnPuuW0y㠝N)kP|6j?ꏝP?BEK6GҐm呯m+7>ٔf&6QrqV7;N8iँN8ii ?C__2LuO<|*}]#>xV.b -X1P/P>l?ӧ\wm-<?mPƣ|pԀ㷓2&^3d?~,81"ϠT9]z? K\MNQ݃C4;+տWc!\~#/Z勎~*pڂdZ~KW:rA}8}_g]R)/ccLeĴńec { Ղ.Yl,F8SSUW۶ĺZ>' 7ކ2YM\}ɶVG6oL̩c7}sa=u,j|.tܻE֠@Ҷ!r|t4ƔAc,@2VUH%âcԓG4@Qj$S\ھ YtrCꬕQ™B{)s杚al4'plkGO}gqS)Փ?ۃMX[8S ro2sgXOc6@@+3=tzz|hȞ gL&+[WkCĻe;2ڤ:&j1|jupuehw;/#":3)F;5\;/0f](Bt!5K|61b>9O /8Ĝ ++4|jOBCXZ_X{[3M2_FS:iँN8iँ>Fҫg} -|ykZe/<}ZVV.\O ۨs{Olu}Fu=3):I@ '̉[~*1:='2\|v?W‘| l@ݨ?uD:x||~g|ѧz1-Ҷ*h9mYam= m!OY09_{litk'^o;--eĴNw8%W)a}:/1َ7$YUAEI"%R$FyCD|ژ# pWJ4*(t2;,a4]O|(: ]8)z:^BfŠuXw04e&gF mh)~O9ha9&`ʦF+/jH` v8(2fۯux+'W{JC[8K2)YQogOCJ(BO9O_©&)ft~m[_v¥gH|';7S)S=4>'8n-5AY@?6 9ɒMs?h _W}I۳,Cw< z] IDAT3;52p8N8iँN8i#>'{[=N=>ѣJ0 <<1(7WtE߸A,Hx7Sw{r:oڽjܑnDNG_2Ӄucg.hOb>/A?#OՕWZZԛ;;m'@o1̪X;Ь2>Mh>A9k?ɤ@`nVeX]HwE8v'298}ʐͷYKwRtk^;؞N&)u7׉+338`5 . VT @!Jx^ǏJ>a^*z(4:Rx ]ɮSG^+3(%ic|LӖ%4-Ǎ|y\&Dž7)٬>.c3Se8iװ!@bA%% ;cSqTkЊ`ͪ;3Iil'89&?б-}#4a g˻4n%J=C#Έ젣DI}1ah}OiK<$s *2[r o6:1tIo pMK+Om$EP_cUjƻr2vڪ8zKtR#ܔO`~!GHO hl#wD'`±Ԣ\񚎜RFSvgpUUԸ\J_v㆏YPǠuk_T}g}U\.<8ww`~^+2'o|-s(Wܸ@hRd||Ay`t_NNS$S ՃLJW&kc7мx8bԟ.Y>2##;GUg f 42++0a<zcs;od=xh34Mfo:P6eǺ-^?T=#Mu(d iF;pgJv}ȡb{6 U 촋=:!n?Gm^}p(ȐīL$#62N6,0} ϓk 2fT\8 Vjb7!g1͋Afh(P2ϤstsvCLNHT԰f|y%!LpЊ$ g&#9tjg?Ep=T<8z\1ZlK[ }aUx;Z%}CJ .ppY[ZHPl8:G ʇЌgvFÝ TȎ#&>Rzvi&۔2ҁȭ:7cuup9^^W2G3 8d '6Cd 赱ږkkc2awh)0̖6T?27euGpȞv#~ĻD 'V}I' 4pI' bm5W\ ~;`؁$ojNS#njS#_6wf'rXO_ȠE},uHL8\p09W*wHsːG]ݧg u\.g*:}"w{ -'dX~S }{CFT  P)7t$rD̔^$.s_}\Dqsր5iG;v:l:,J]>ő~˧>Gzjs1ж#~W*%u|oێv1{hh0KH$qΣ +XmjTg0#mTJtPFDRؑ(&AӛQ܁"7HI+D%_3654LF(yf|D2Q+?@OICBژ)k& L0S %`ZV30z*-4Ku: YmJAL6㟝G^zo1K6<6HdT5wtԥ3 ڡ.9? 2VڃU:8 bnl;t`C7x3XG&=W]8py&@욉:7ٲuͤ߯| ANCo|;k7[beb6l_gvvl@sqD]߮M94XP5}o v/>&¥ gla,rDrEQq[J, yW+V`CTݫ[g+s=k=~NN|Kqc ak7ۀxu㹯uD7W ǘ~; Xv$tLN_}uw8[4rkO6y$ɣ8Ps}/T:Adq7<]a'׾A+VŮML;D/ 9t-{Fp؄z}5=n'fԜK{'}/a# @; ^#\\ ^PmG. Hk0 6`3 טdx51K+Ne{:O^ М8^nl]N>TiYg(|ꊁ)]M9dxj ʖW=g fE~ 2 .ٖ"i:7٢|]I5@Ɛ hұeՀx$[+2]!ߥPbi{rxLř\҉ yP)NJ@^jr)HzjW_r~5>|1JCf&o7s-`ӽo~=oQnS]ئ\YJQџ0lc.iã./q: P: f̙r񫋈I?_><IJ`Uò'hd lZֵVӱ].PKz_2$)s360?8ygkqHaȋ/S6%]y cFm$,sf/y?zxGĻi Ҍ[Ը۾hQa<^X6L[q1 b+ۑl_vv?$o|M(iJX@R Q_MblN*>,;jR}NQ{M; <6w[1r%d|sL6ݳ2(_*mn8O66,z; qeޑgr)9&l/_eK%^(q;.\ʵeVk$ۀ'lDgm4;9ߕɫ>sхѓtut (iU l릿IUuj<-ڑz7koB;iw^e(g_YBFN<ŧ=yիv%|*^L[~ڋl 7N]rb=dsrZNǷ6--d\;kˇ7wi`(iTpqЇ%lmG3+N}ܕ(#W}~*r̷֙Šе-{~nQle;|P]+Jk}ϾCĂkSh> M[ݗG]O:7_LS0s5@ '^}W>{ =2_Sw>Fҹ>c?zk۽jw؇[i~짎4t.R7=G'%g'|F}I\Y܍T=_Woj15Y|C 0 C fJ+<$4p["`>4xoCU#ӸQffN$X9!t$/5[@th2*ݕ^9U*f!t_j ܪ2mL-d#i8$Cz.K t1 WWԾ'~h½NiCyh _|ى#H; '3:[TcReUKp9yDMr E94!`Zxtf^A<#\+7WaqBtx#xp)0;e=gCCl,C^q77 NxuLS؉r8h-]>* g!~AxB+n&<qS;8?G7pUz?x1(#?1ҏ4 ԎI޸WtŋԱ|w0i luq[/-vͶyUz~9]ޗ{O=[x +%nPYc[(r N\XL߮gUi'puoIV6-H;[zm6䯤oF-<>VfoIAma|+_='/PҎ'RT~-o˗ȜhM wVۙ> 1`R<=HC H'otr12'FA6H֛fx)N ~'=.tiZ}87ߜ%~AҨ]߻(G05;%^mP4FI ]}ppUEҋh,=5n#HofllB4+]iK4tg?qm˯.@H_A\w&ӯ?h!o-#M]G u]rs8=}LN/.>yں{~J?4NۻomNz:)LYv6\UnUײE"K}% /PgFPc, 3$9tmlI]mCf7 υRY-|ZK`*-ad8Oi }UWgw.Bꖏ3 zs4PuKn6?i(g`;Oq~ $5jٓ}oDJO>DRw_0dt}.H`qka;hkC|!=7~(0 u̧O;rto?9s4!;vFtz>[SA6T`6e͏vζ ?oNcӇb2yY[xL? {1g+oO0kn!%OQN1ݱto&j< 4/S9>5 .<$xV'QpTcŝyg9.jGauW}0&%9;@LG&[h^¾t% zOJ=_3 QTu(%m%NhZD>Lh%4[0L(ax ;PaoʸSBCZH`ƻF+[-h.mcרK. fxBysi-.[] W)4B)vT#k|!;^AQGtl߮|c$ 5Q?AB:#cc=[Hq E͎%is,Um0xA|=>m6ŞzTNqI_f6[¤;]0HJC kIdsnZ-=PqӪ}*x)R6/]pv5U_ʓ˔mAzhyaCߧ#~e#]ȸlLZ^O U䗁Q㖢0m];cvbR}6ӑ *,ߕS&.e&@l<>؈Yť]lB6<%Ąx+I|ىBxIˠ-n۠ZwzRPwemdUȢqxtllii3$_ނ*`Oy."G$t% 9t~i0W h~,Wi.vc{e6Koc6HqkⴍW$C^\˾]|:(1/nM(g*/w~ W:w|O.4G~M |KoiN6≮H8[³5V:yJ?VvFCg@ݿXmM]Xy&?ZPOt^t͛+&m%"ʚ@: y;҉}rye剠߱*:[ud6M19Ô): hX>{~푝QDABa?SC#)k.8 IDAT݉-j(I;+h2HƏ|&NR; Ĵaf˲; Eע΄\cґP1C79:7\9_ _\FX_Htx`>jzs{1fV-A]#]4ܶ30ȣnUY^}@N߶:6{Y:ڍҧŒ ^qMG=zNݨ?^K7q{-˟7 kLMX@/=s.Ly1kBrۆ2@L}IdƦ.-sl޶9鏳Bۉr˘[-@3ʮ5(T&365}^)tqBOI+=na~`@Is(]?ФAWERValg+ /:Q&Y?<NeVhרĹ<Xut/^mqW؃vՅ"GBW]=Ϭ"r6abAkZ\i+9X |UTGҥvMqtW="?+m <030xtԩ[svW[A'V[҅3n tյ#:Rn@,^X,Z',G`|c,o@*>؅pha]jSuXN\m [I9:J M}U'ld+kѮKGzg+7+lH |eMop1זo9=+~\Z"/l䑄m"OKvG_`9i!}Pk.S4YQP`r-cxH{B7->>͌I ,cAe:[/H_tJ{q$rgŋ`;pnW ]v/͓<{ru+|;p/wWqWΥUuSip# w7i(ЋǕ'>WZvD8mߛ߸do+[ C5|7n˽;EjcsN{R;.z{~[OzHIU+"I2ӣ灑V𶔏=ë#N $([F7P$yw 2CƎ4lcTO;6#7UN,dBv'銲Wxo$enp.%vPܢ)k},Y*g1"q ʇA7#+pH0D)JgM0([f p2C|*QʘUѡoiܒPO|!{w@wPŞīM;@=ȿfTF;*@h>cuۭԒKWN\9I c{$=GyIפ#{*[8֘dIFo9 dyv(d{ͪw3}h3PQQ"U[=&ƴƨQc^b1MMb>oLRԨb%6PTPrg; "F%jΙy]Vy쳏;;26y#3g:򈝕Ԃ>ٖ۟Z-qu:0HoYi3'/Z+ЫYM~\0R~O*EK4J+f0\WYN`24yF`eg4`"dE.Onџ-^uC`bۧqU*Hi/˄G($ȉ?l`J~6#GQ@&C]*W'2DGK~GzEW$'y!ih繘=[2zŠ\;AyےQ?x|*Ƞ-CɃ '\(x֧c\~&n=e{|g`$[OzMXO'S~~me|'0 wr>d߷ OgeU'SCӳveɨpwC S 6Җnɨ#',e2ge-u 8׊ ?tp4]4t"psh.Ԧ+@Kk2}UۯJS/eL[fzi:Td*aumTz5E5xr@7ؑ>EE˞+V`daeW0p^}-'xn]S/(lHXJ{5e +d"'e )DX{A4ٙG*gԛֵ`biMk&0HdtC?m*|rwf Dl*H0%̮ȝUS<0j9/4p40LĄNQt )zq |bTVp&ܞY/NR;sh KM4k&T< tq"f(m07GpO`C:}D,!0#? C<5Cki!™k!p +Ѱq~؄~BLI֡ '6gd~mgڒA+E607Lv~CINa4̧7zDC3~  J_f:V9b'9~gTz*;&/]{sDc#V[ p7bwL`N I"xn˽ՊycӱVn C ~OWmX# _LN_dpYw$2 G?\g4Sslr<ʒ!ljK5TsMPJX"\)aiK>SI.C`,q֏upF*c})E*S&m^6|ڎFC7k]?tP%ryJ:ȫ^ɇr t\1y%?ѷՕ:EYx rg'Yyb{L8z?Rf?XYX~ږa?GS+?䵃h҆XoC y6*::ډ #iAOuƨcJV%X.q:dLo:S?xR6}sA|?& T#lfJ;`XOYהv ZB+{.6Ά);IVr;Tikea`c(e("zmnviW2V D% Gԋ#6I^c+-}>pY@]ڥ@Gʃ/TJ$,ZZʥm>GG'LcXt#OB,eʧԕh2N6u0yd x膗ʮͯjGQW(Dó1Ot6i0'F o6ZL$GuyO~}ڢFBW%S6(;Tx`{iS5ql ݒ3@* 4#̷EʳeO!$ޞV R'2s}1wq bD]uZWR'[/A@.~mhv;DQO>B&3[[=wMB)afZ*|UH5@a ydL4rP0Qx=';Qnó{-OCV ZQ%o:U0lQXB3t>=fSZf̵ xB" q- aèh=ЏBީN^&tPg"0iXkJXj[H^1cr=ՎƵʁEQC?c0;Q=b 2s6䓱.L<HG;z!G:?Z~𬁡vJϧI;sV,GsqK,amyJ0%7rH*mj vn29F0:_q1[ GtJWF;x:]VGrayŮ%wiOWޏN}ayNRQEd1[16Tw|r˳.![(#x mrO!J8-+! #dp!+EvŵF=Y9UgTnǰn#S"c:ݤ U$Qu* ټo[~{&6oέ[S>l&?iKÛbdd2R&;_ez!L;SJ4]WHzFh(#t./K4r_i[.atTLSa>Ǚ2b>)t>_Ν~pt٭S4j,v~^L.G[,3E*&ڶt-G7)9nzt•H֕pl(g̵ƪG+}m>Gs kV1}SH6uQw$ W)<əpyHYvU E~iP;N扷O$І8#WAZQMÇӦC~#4Se\;nȀ'v;m;Wm[~PߚlZ{*!Ot @Aù*'j,8! ϓW#Vc& K'iQf-׏Xh^daƚ  me2h%`]dwm ytw`M^"JWt">YkRD#)4rZo 4.u}Ky:.$O}+FJ9Mٴ!脟RߔLS]M@^=MWMN'VB֠yĴ=L_%/qAsKs]9B;J Z39I,=i͘{c(^u|E$Lو<[Q啉ٶi\&ዬwVjw c#) 9dO\U(qRM3_A4 y v+_:tQ)'Z#D1#o.UD_Fx GZFiHh.=e;oU[{ɷd=h0}tOSa 7n<|ׂƑti[ySgAW,QHQOvܗnc^M1 `u.y"JlB Fx1oPJCO{ǁ銃2SI30!SM!% ·| RNldX WvԌ}A6m+2E7(ŤN*ƎH(.iQAd tҤ M< ,#R{H$>zH^az3k}LL6! <$|F~'|%&6V6mĒX !dFxtVzJV߁gQREwo"O iB3t )47s: =fyX[eX9JOWFv"0ҷ|ʋ 82ځB$g+"ˉ<5UR_IWtZI*|حNY0舟717 +n3h #c Fb[:ӡҧ )ҹE:D9guoʷy_8ifWi96?H\_0)?:J&Ó),Ρ^Wδe°F\-GN=kTXr.1I+B>)cqm 凾'/"TvՖv3dPU IDATl~b6 N]DiL9bx,e+(eeO‰2)<2%[^Ea2=\n&1У3O&RϠᵾ ~1/K#x( 2T9TLG8ǶIRW';mt_ޑ#2ҭ<}ȬntĮVڂtXb%PU/+$u1c[y;HOEWڤtŇO]/ GtQ˜{o]wi?ܷr!^ JܼN7!(R67^/[lKL6dҊQ8wUo fb`Fq/␁?<)3Rߙݝ|1O&}YSi4Ȃd//LTyFNh z>&14p\9Z|yEϮ!cU,gF1M &#Y%I4"D7 :`zD˼Q2PFrX!JOn>w剜d68rS5W]!)g9=)粂p=OB;t{p,jHۗO &&UtȠ'~-}a}lJy9b0(<-WeB,v _bd]/tREeE Ҩ#/nXm f0>uQKm %/7`,Z>նSoߔ[}ɸ,d}֭F貅}s{;g:d6IψChtȫ__&WB3eWigl-MTs (?x;@+2Rž;KgryAc?lG;QaB(ȓ:y ,M޹.4V?YYmN< u*$:;y{qPl{vrgz8ɢ}LM/|i#i' ,uOco-ygUyqig@(ec.î+Yš0tDXw M%Qю2nK=;;Dæ60zJOp1"v+tŒ\b86icѯYS$Y9c }Q+W^"A'@|=b6Zv+<CxT[)-'믾 ORX1" @ h ݐt']0RoCu"Sq$ҤiEʋ2!%_>sV&seNl0屬6I+-|oLMnzįB N[['. {,k劮e2n+ei߲@:`Tk!FM/4m\)ITb_Ol{RoVsS9O-Cy(c$ y-YƜML.!L|\gamK9SD&mbע|PNi ΄"؀I¤'\0nT?qn˰F:㪚#zw=Lxxm!H$ps?3 kQ@aeP G@0 '/Q 'I CTElԢ0\:ڡehx+q 47&מ *q!gtna2*H`iUʣ&2?m'fu`8UM!G藯,2t !ywSO$F ,6 - ir$u+ۘtKgJo\y@EvEo|XVQx8rW~¨{|߲὇ƽA>m,'66:pV.'=u70"iks柲?E +yH;u,V)o],ig艃Gp#~l4Qso^iPO3 "m6២/ YG"RKMn9C9ti+Qq_y]W+e;F8;ac!cl_{:I([~,OŮƧolO^d"אּ}饗Dlr%ė̟̖آgaB `^A+r:HvI9~K֞VE '2W`u|Pz:ɒE =]:\uz`NveDzH r 91:@=Br|if-="#uZӖ7#*Ks5o ^ʹ16JنI@$k&i#I&yOx; \HۦSno"o|\GZr!>* sr!UdL)U[`T6}]>&l PɪiئC}s|R]eQ1U7jU`5h S i]`~=ClKycV;U}3jtg)XgGۯ`*Yk>_]bK2AusԈa]H] w'z2xbL8AY,bI59e4zA> u yyȓM<&|ͲVW@ . .U/.S˷wsCl`!ioqNY&])ӎ׮{wvlMr7DgNK)Q[KǿM u*̪LB )RމKY;W=嫜J<+p\F~)+&e~<}C0?}B\TQKt7l%@C=WtD'$gǨr P j#7fxxu:T1<I7d(U|²Y{y(8:x W<Ч:jWt74kdQk(x$ugH QI".SQ/F5s%10"Җ\/!`$2)b}z6'xbaڄǏF4c,~xw?I%,,>CMӍmh_S KXC=)/Y-O ovYUٳIw611?|lob;g:'t nؼ OtbSo~ٸ1m2aSq .]}G1eCVՠ|nK:cJ~Ut+%G^O};l'}lų؉hoEKF]u%Cv$HA? /"JF<4= Ty_@+v om4ЋHŠOV\EMAI>WI>ćus:?|'u)Kqv`!/AqX\bLJҧis_!#*~fb/VWalDٓ{,:Cŵ}KIM7[~cs9_I=!Oob#LJ\ ֯ePi},㰁y; ]K6."I4Үq)kW5CGte0blY'tOrfPiC :%PL`7n$f2qrdrJٵ/n'\KڮW=U;biODes_â:<>ҧ3=4>qx?O>yI$63KԹi)u qȣLon۠UC {tھPt%Tv]SS+ۆ`[}cs/xCȥ>P\ζ0m8rW9:ɾTz>G+`eҏ\}b!A"KE5 UaqL^3 qmʳJN9#O/]J 2 :!S/0#Z^Dn ̩bT1te^thБ4gĭ*l]P#~:R?w WX' mJJ"/*gyRlٰ !)tR𴷛Yg,}cutF XY;۴Y9FT"Xq QI h;;I6BC SLDO%ͯnQ-UOjTRǼ̵?\[ּz,d{П?ݠCתzYKFGtg{]y=9R&;F;,0f72#@ʘ+#Fy"#Rql*c| ~<KkҦ-akTpPW cuёTx#Woُ:K4䲆CN;:(<1ʐx8 C6b{5x(r mhr:=`XV龎|Q>גۿ]|2#Oz/i~ 0r&սQY#4b{[kUaF>3ROQv0!bXB*R"_ RYx_}j3NQC{w;9x ^߁m[IG IL}=m1=K~ғQV"-rLÑ/4_yԁhɧV63?XiX Oʎ|eIżwV^Ŭ~dN:rd2'$vUz^vqa^vHf:eD<8{Gۖ{κ8ΥCc֠IaZR[?߇giA2)']|Яxe)R_<h,&>jē]CGLs5K{UrF,|0d]dSqoֳ6QWC iKϺF YmR|[f鴡4WI]= \+(W &z5hSϥ l eX*3ui,#17VK|N_A ץwul[14ro~|Cծ'n~LD+S I}]E8 >(43(ߨl MmT]YN;3Ou_NxaRϺ'P6 *ɣ,WQ:ү/|T_[].ox+gSb+}4:!>M{/;܇{-]䱮ܤ<4 E^QY VĮ "Ru`(mC.RZ/)eIYW:o =$w3[a5;++c;2pBn/;#SNI9R^4 !]jqH'Ӡ W #OmГ$]hەu7?SY7.L7ҘɆyBgm 6@!W/uJz^AUGު!CxZ]bMAcמo-NXnQ2*q*`efifl̺ӕ/ÀUBuWrq mSϊWcZO5 eSNshmӥ,g},)SF&`=+WηSKWf苖ـ]ɗv<\oSFbd|:eDLGBcT">GY"&Il9F_C&PF0TA|{،Vikeupek:eute }R?&@8Ik}nMp jGyK^iTޢY+ֱ|^$cW IDAT,82wf !+ߨ2^o;}X(Am?V";ґhfk%сRq]˻W_~i LXiA|{WJ'|2= rz* v` RIiz>ie%u @׳*5 ϊ^YC_S{?J{eOW]^ɗO;se"_#&W@ɤgBJJzdy;OioCF}SdKWFtɄ:IS;[~PEOcqms}^&W|XULW0S拏'WuRl =BPpV= T? U=[ס]e'+ C^MWD1^R L`xi=++.jLQiH^G0kѯ&T$-cTTC=Cdr!j)7|F#8iO+F/ظA= "<?8 U) `:FD* N! aC`b t@RJ:=/  -Lq2 ?O 1.=4$I -ܛe2c4:wa9dbDy`ΓN bE>pKC 40ЅV5A>lecpݔ%P^iYzE:%ΈS joH#.6RVvf %u@0J-!PJanht*pr<ӁaT'qNL#='z%],bUrP.^[a̿.DFKµvS)ca:ф'1q5!͔5|_vW:$%_"Ǭ2F̞Tpʥh,7_a7T#@z^"Z! VEuCpM! F7Hih2_8C~*a"pm*i芑x ND"#7A$]ih+IcrezӎdI`/< *֤F ߈c^g>zH9-A$ߵar(/pp]S] 邟rXQVMr>THq\yr'K7ޅeSNQD>YZKm6Cd+ĭ"uRbOH<Էא<ӎ(vg=vw(Cr'riҦS-|QX !'iǴD7Q[0XE9svAD ?F_Wd^\.LX*wfbKn+H[˳jwbqp/vpQZi@<6򜅑/029 Oo9kc9Đ<+WH$rQwV!|DodB =7IG؁UQnlhO:Fm_/N(MU:3yGvr}jGvSJeO + wSdIը|A9I+9x PtZ0K,+q /7,]9<إ@p2F?ĿC@+B3=mgPȩd?azG`$-.>0Dy̓W>w !؞DŽeg:ǫE (?Gw]wXNZpol `<# 呍# ؙ&W2 l=6gJaV?S'-%juc@?l啕a+'2 oF_'î隚TaiaKW\MCeҽdS6ҔF Gʴʟ!kfC 3J f00N BLkt. uЉt*ApX?؏A,TSuVc9N_Ey-wKy6ezG=FC5jjmB̬HI44PY)`"rW1i,JF{BҾJ6Hc24G̣kjf4_s)3Յfg2^S!%YLH҉"If>nf.LPgh>Zx$S>79@eT(B|NɴЮ&1+~C!M+#jЉG!/05%^J/;)'b*?} %S%WPW{W ˼/htIrW?gi3lU0t&V68ioqMiᙆ(eX'&IĤGgJGx1:H SҤc$v&0?o ']@I'ܓ>qFY]3qRvÿ緓c %jUxShX kd KF$&u8Wx6۫Ds/^ڡ#zG5e!7YI=3'wVǯ(PG!N2xDIզ,3sRBs-۴?%3a++>[`>}`S}cY,ۙ*ڒxl_A^%U|3.}Xnn؍pXF"[?ǽ:]ovB"uR[}C|e QjA +.We$yZJ2*zH4yޅ0Dp'Un#vmgy7%ZK96LL(;U}?믾8"M`Z~wmɫ|$mc7ORL1R:8DRW"kʘ e`'L"ا>zU=^3+L6b1U2qzW_KgjZ'$m~1Ei:A< OhR)lv O: xi.eQN"lˏAm$xN,KITSuXIrx+3<"BwBlTs׹U(Gu/:VBGȁ%BWR#1js׃ڲ^ֶ'ܧ-AÌkJ_ȘzG^y2BŠtn(UbiO|1 @AU0{BSYtp rXX9ϧ|z}3cT Y8֐S!; UYHݸAWuH$%Lo> HcgHyy %_S dGQ ``G^Xi!@4q ]L0\>XY:XgԆO^ҀD Fu !4z yWJr:֝vOK؛B-K+ͯo#>{#^F,§QN?'|dXIE0ꯄ[ 4"u7N5(GwFڊI^s̔>}5yON4ʊ'mNό| RS>,?g5O{w)n Ō fIo#Kkqq pdP^17o#gH7U B7qgex}6uMQ(>i^k' XIh"4\lO+?iGzP[IK" $H;'.3(<}烈d =BbJ:e>*\% Gcp$o/Y#x6B1+6Xt9^{20?ƺ''&^39Y b^bV+AF귘q)'Y$W3:05 7҉?[zgl.$PH9`$?Ru}SsOYY!Fgfxrb_Ωi۰Yj`0)6]ē|ӥ-ÛY*3a ,^Vْwm~"Fu]S8Ĉ#KՁ4l1ҴA[҄dP#نvЍ@` :?w &I w6yzUnDiV ]?7VC|w/ =ay@\8DZv/TreCoeK#Gf[K[jcDAe$87|2!!_^k_Юe >(L yI#+-l ˏZ[W_ !&շs0OZOl+}T}#k΃ǃvCqVN+ek3Y}GMww?Naלm;c] v2Α՚`r* MҒ zBa]sYiɌbwݵ~_c"YGKGaxE{ց#@FqM]•S(m>W'&^`u!yxyM+(GKJk4;|aUް~q,;af #<,9C'XHI0ɗzS= a8:Ӎ%IZѤ _Y]뫮aOB1Ѵ/gn|΂ GKn-Yh^0N|zMe&8OhJoT+~d4$.~+r({t*9W=J/2KcI1(c4 ,Ay7'4y:rGe *K$NxpC>Be'ЎgT }/0m6CR'/,$;١Rj+P坟 orIe*Ou_d㦘34K.L65LlSaLLUh+!U~Lʤ"^h(ˮKR{ʣ &RyOOOٷS WNy'qtIwȠ@[L=#hЎKnG}Sx- 4믏Y2Zʦ<o\dG%&q-0Rg˛I@cBwSYYRN7iᡮ)`|'>å4{Cn#uL3ټPfmcf/WDit0=Glf ) ߑ?uk]DcF^ЇSI ]: <e>!ız0~uH(1(Z׻lGyπdq8$d+ؚʛ}HJ2uv#F~fghZS*)c)LjT~!.փNҞ_%\lcx:AC/Fg~hߨ 4d8av\>2-qˠ5򅉌H)#nm~AnAAΗ_Y A?XvI' /pC`!Kdvyvn;n$v7.j| aGozgs=wyo~k_rI[w[\g[zn=vַ߭nKxy}6]x~9/|~mmͻGx IFws '|=(|?n:&&&&&&&&&&nr.be ~h;Ixxȡm6(A5kִx{?vCnfY3\~ /hW\q5‹.jgvʩp\~`X}. t/nAu)@`Ŋ!޵}mO_&~ l68!0!0!0!0!0!0!0!r)Î;dw{ߢ-]vi퓟Dwi'xB}h'pOLPY;%ȫُ߿vO8^Og]ؿ}ǵ'< m]wmխZʕ[j'㘿ar`y>_io|g/\;!pǶ??߂7#4]LLLLLLLLLLLL9% IDATL! '7o5k׶qD;mn}`#vZS!w}o /"[-9 '^OW3oek.=.F8Au"?KlΆy֮&Xcm_~m-k6m8?Ŷڒ%[~ ` e3\d[luޭ}뭹 =׉?xp=?#Ty2۱G_O-zCvЁn#w6K|Kn|7;꯲v}گ/>7JIۼ r/68m'G>9s+41 pfSۇOm_ml{~fn-O/nV9vYo%V篯ƾ`? +-n1#9?蟿%/~K}G?j[yk 3l90 Q\7V^=LK_-[=$ ox?6x_EfFt7V)݄5W_x۷{CڪwK/iguf e E=on}Ytw[sŕ"y׭4Xpov OM׶Mnj.C` t>.]; _WBô7Dkę7{c&5{.W+_jB۹;|#ۥ(t }oߞVwwWƭdQ5L8<7Q6@_'omy_v38{qIO|BK}tN7ojtPgG>}j{sv}w^%8]={_{a_>GpE?xS> p53Mˎ{s;M/zI{_}{1W~i&u߼7s`Vyԧ {W'bYC`]wk\xQ;2c;19Nv'ΧrJM;}[eJ[M/ϸiFy" }mzcەW^(pUoTp{ӟ>lTR '} ַg>)Ky)?ٓji8aS~I'vۧ>򑏴]=}яzDNwlz#>ߝ`v[ߪ}2藽'iB; V0KP7 ?`D-d$]~Yh:`߰q}7>|[G+ab=y_d_ƌI7]nF<α͵mL|\^??CW\vvʩhbECzh{xl_9t`G nǫ~vv+T=z>g3'ž}G7pB{A2#L lv;wI<>ڟ[ia1O{]w-[^`LssX!G==>N'ٷ>m)%r7ט5=nL\pO YVóf)WQܟ^-KY¿]ý ; o?{3Yp]62n\Y=a:0|ܦn }acD{S~Oko~[ɷi3"4Uj!LNr02? jU 3VwyqVknwm2ʀN8ݎ ki|ȼjU[ e[tP鿌(ɀϐWxcy=k.I>/my>>flʱEIN;s #9综ӌ]dxh<緞p)-gۏ3,iG{ϙx>~i>>v\ }|bb>#&C">|{ءr0xⓟ03#xxc0i)66]MLLLLLLLLLL#ʝ1iV^G`<kcVr;?pv'Oi {\jȱ `$e9_q7y^I(pmS;8?Kxg)s:ɀN㰻-乬~YҾ+^<ufX˗zK0!p3_7mb{-]Ҟho?l{eR|iY"X͜aټYaӼɑN}Y,A(G?zLGol}]md1|,)pl[=O{pӟ .\cu3̊N8kgczTԎgo& g۴o~wlVl50z>'>1̿L?W?$|~m X'n>-Z^n7o}3v_މ}iEdedK`n~w/ w /Mxۯ/#w #o!#~{X{/.{ۣL@e/mϑ_*G?z[f ,l;J;lxC1{-y (N}J#X׾W!.9?NC\τON;4~k_;eks;'wi6NX}<_p&v^M Wwߵ`qG7Gt{ģn4Yp`y=vWJ^;wwWXrM޹1 3._rnʪeKm_җYkj#C-sw[2'||YX.nWz܏aw}k^^״[X p;#s'[tf8MLLLLLLLLLLg."6_}_ܢvYgfxW_ʼ>6hv,ͭn`/ ŗ|V8|@׶mʛʷ>߉' . gw_z5N/}֙ &[޻泞^5&E/|k?6?!>=s,prVd{ݼO7mܹ :_p~;뜳ẟ`Kdπ+V?vlٛ+ FY˪% K,vN9O'ױbŎ/~a6^i>Azk>j|f?`ߠh.i;J/*>|Twc{泟}[0ߋA2 pyo}?O^ԾWnC'=mϪy[0yuk׵{vg?'ؖ.]iuM?,X(_68;3fNlMDŽM߽_Mpn{;oNxȡmwsi'k?p?~BlIe@TWw 8|u:@D@" H$D@" ~m73H$D@" H$?<N:w?<0D@" H$D@" LܜZzH>D@" H$D@" Hz#{d!H$D@" HtqE/q]waرӏҎ?x|6^v|q_[Syg} lZhQWۧI>W2H$D@" HxӸ/>Cu2l0jAUv_.FtïA={+{|,~Oa,YFP3 s $p3w? {R 2ēA(q1sLaQ=0jH?t0?@cO>wM/Ǐ4yW({3.[P[ Ax@ݡw9ĄbkaT\e am$mv +%͇ja5^< o!fF}2OV|XzuP>'ioGb;rD/`eV[[["yy!""!!!"@V~/o/wIצr<i2ׯG~~>xpd埽0Lbʧ~o111?q#&_`RWvFӊ9QU 63 +zW^yŃQ`Æ FI6D"rkhڗbq"##la{6J}}ah#gY!{$şYL(}eD_g/LF}诮ĭkj/^18{ɞ1cHعs1>de4<1.~f󯁾w[c1ᓌ~ OzG#:۸oO4X:l,NGdzS_YiPf*q[:PDG}aoFa1.BD;ƫ="w}b̙3霯'+z$Xr% KyA& 6;If8ʿ U?>&MR8n$2Rl۷O>1m2+ޟ$2xacʴu vĮJ pOw+Jʰ6\7}'5yMǶZN8/Օ DlDie5*)kA#* ؛ /"EqLcݹ:-lK7RQH,0GLIDATYM9A#TOr8[Akױ8@a5vbyTdlg rwf{,ҷ]"(vf "8܌)Auy)WMֈ֚2\~5 {CrP^]=pFh#Xف=[gX>Srv9aXoB!"g%qHr9WqG ^GQӌA{Fᡜ)AΪ)j; bX6zWŨ_krېG<<1煗͵8MW[` JjO$)0M7 ♓JԚ.(F7#ٹț|/Yܬk|w^=U"ڂdLCHs$ecOɏ1<):;;h+iV ZQp< m)HʳqiÛYMDFJ8}H6C>, #9C%EX+Fca_%s2t^kEyCd "P"Ezt?32pVh( N3ڼ2gYury6u1j[9Ye3:ŝ:_ʏ9@pȣ:U(ړ+hRڹX "6y\~;ǫNdD@" xaEYx2a&N|ҹsD.U~`')6ϯpko_W-z+Vbαs|3~qT611Q|8MKjYm޽M|+*<|veP-|u2.Ƣ֚R=Fܳ:7H]$h؆߳A"%:3=Lyrp(w3*圶TEZ2d*ӇåK+,cŪ(؍¤rW"ub]_Z8vpz # ןK'x4p4 ܑQEUD'S~}E;/ᡘesid.8!EW_W 0Rq;LeE( 'FEՙ֡ccfC+Zb}#P` ZL8f (d:mErs g,F .JH+[C^ĭzN֤D!`C.j[ISvI-&}ӛ vLd%%G/ /C]d7;2peHü͞2j;q&2W#B"#=yOR^̡)*s3&)::ǫ;]I$D`ܸq`꯾ w|{bev5at/}GӅ 8z(ux lXFWY{'{2j2Z*m'CF=qjӴE.'qfXK*VWU#QY(ߏ"߄>Q~mTdi? 灜Ze*OX6B_1rl`u *܉1JVNK7B$VκisO> /!`ra CRZyIa'靡s+pk8X4JNօ8+Qh/lCF;&5! nD-y$ΚB+6.Vvf!Ф*%1ʩw&B ZaRCI ZLҮ ZV^xODW?dY!J itPw 5Uy m_Ť{Ƨ6̌b1ҹTF|o3`!t aXi{E>M}gAMLΠy"ma1]}oM^E$ӎJuLuuxܟE :@1;lI#-FsDL-Ld2wl"` Vqwq ~SD\NOކoqDv"m%NO[Mu/(r)eI|XA?nKHM;V1 FFgۓ9MBc1SO{l.{G﷣{{H$?Vܕ'OVv!Ws{5_Ǐǯ~+8W9!cO^_<LVq4ix;\n6!/^D8y5jL~C$' y^\D-y#?ubYX t\(/qBb#K>" =j:^CIp#k}6^:N@ XH+|Zީv!W_mfɅ@ԓiX<[.V|7\3ޛD'Kǩkh;k9sO`4߶8I ՙ"O#6J׭ r"oA4HyQw*l3a{.<8ql;VD['Z_~q5OV:!~#*ehʓ  ૌ6LFq_łNSNc-(:FK}D2JW(/|o_ ҝrUʠ(ɄNr6c Y%We6>,ǹ+]nf]ǝn^qg:mtaq {X%!t=>9sG[O-49"\hϷ?:5Dw;*c}%22^ gQ68(p<_s6ѽ- @gzAD@"Ы9|p|֬YB!RM+G+¼ךw޻=gKr{A@+0a ?qzP{5nXٿ{LBm?P7=eU@2["N|N/b |v! 3]ulG}I|&W* 4F'лiSݭ]4"aАc EQI6k\gI"XsfEMDG[#>o^q_BC|6rד>۽ mNc~@x dEj?ܽ\[09DCٍz<_ԑ)nMUtXb,)Ǒ'OR=29CUez8ߡfZ|r@>B?4ɧlZHBX-+N~3gxO 1^҆>ޚJVKLdH" +GSύh!1((H\8=ieY&F4>@wڳ=Zfbw8M=,ӽrOHUy+Vz{y͔#}|RFg19rO?ŲƼ~fg<sӿP`g6^_H$ ʩJb/Jw9>mqD Qi}S˿/|Ϧ}iM|'|Wns=e=|V+4< "oV%m-+L|#+/ofțplذA^lo~"׿^ ڲ"c_MMMBg`CzuHAFJJ Hi8df D55H1D'd^xS>8[kVA< ɨ_-3w{[\Fq1 z_3|RgMf}3xn\f8`>Pzk 4p7m"s޲h.ҼQwdҟf:xa' ce9D@" H$DF@R@<'jOY_~?Qs9^(1s&nOwvNG@;+_u[ɣFF~K 93)| u0[z%D@" H$DCݱRWG{эVI~v@ -Χ7_*G$6LCD{{_ݹ{! `<r_0TXb zv:_*U9liH?YiEyXڮc!ngX -Ͱ0{L _|l?v;4 ~8a4 *zX[>AD2AT4K= QLY@* 6!B$ qB($)Bd YA; AP<eAPTBU&tAF  /B !PG#,N/D"FD!{aK,b D$R)TG"m{Xd2YC!Y2 P2(-凊Ae*PMsjMBКhs:A/o/tO ÆǨa0PL*8sӋyǬaXNVk`˱wcX:vGq&Ha\)׃-6xQ&OƟ7Ot&L'hLBO"|'BD =1xXFB$1P$ <N2422L0|'Hb$=^IR3>iHee4ggڵڳ:::tfuu}tt ][ԗտ@ aa(hĘbl\a=HkcNlΫZGC 96['?Q|~iqN((;s2)S5ȂB¦"rQJiy?J *=C8f̪\|"eA*ܪjg>ruimGX]i=>~a \/l7F6694=hVknni9Պhop%K]m2m._W|}u嵾E۫nPou@]]nZqKVmەwX!dMݻ|/|n_<0o?ڃ4n>R9:X'*Ontw,+!vw'VNn` )Ei2%R3\e r%sZv_PXDy M -J*.i3l~5!7";b:cbntG |ǧU=> %Ň ?|"8my9 Wү&hMONθ72 7Kbb>Y&~Ҽ v|8ٲm? r qtEQ ht3F3݇N $hf-2*JZ{ZktJtO08aX`tƸʤٴŲf5gpӠ+uWپYo!o BVPdpUpF8-5XTGb,ρD$䒔}ά<ܙ5rSű/8~ĭN-"aP+v( ->S]v^HD\5~vtx.nnm^jt Uk%ڥnvwv޴v!NaOݾ{=Pwx3P8xihc ƺ}:kfZqm썹y ߖt?nYs j7u~15g@ ! (MQxF!QZ ]!b0o.8g#Db!y"S(6sY|bCyOMaN%3_BrUr+s? EO%)#T+l$ +*#L,^]-")E%!#$J@J'?pTLAiTX]_uAM=^CCQsUk|O]'=i}Aa1;63SsVyk\ulmv+o`\RZV^G~oyр `carVtvL]쭸 'RRoO?w0Pdfa,l#9zG5)K?!~RJ~]Q%JY)gЪʯ^VΥ>yz#oKܗn\A^uvxÿAͬ=^˾'=&?5;O}b9k1 @)\py S%Cv$xL@ _+@dC"HGd9r%:E3mq4bNK8<.ׇ kD^b.q!ɘ(XDecS˔`"5%;k2`gfoPtĕMny B5BZBEEzD}b-4@k('% d؛˦ʽTpVdVQ*TvRTyڢ1٢BS{BL]OoI1ɢٸ )E_6,vŎ.ܮnWNYhY◈O_YXH5ud{l@ː h!鎬AQD}4탾g{1Wx.[TBaEc`#n13v1i2Y0ّ% `вp(BC,D\P|V*+V򐔀Ԁt 9[rEK*e_ߪj!ښ̚Z={JuTuzmG Md9LP&V̿XYnYclm-<]nθ#JxX{yU{1 ಐa#Q)+qf ]IeLiYF?Wc'NvΟN*VwUU:\Xl( lbb׶k;:oR=ۓK7|?G O`610B« 7w?M;^޻ht/.+W}qwۺІݯg7_f#퓡eD\I@C9w0ژ{XK. Wt KǘdLb 7SҨ, p'^psvp>s7/[QBHWX]DETYLI\f(-)!&(ɑU+ijkQOD ^ÏT S_\V'Q6vfnNG\\Ϲ;1}n?o_0|ʫ'1E F)D7݈7Mx䑼(;$ٝe=v5bœO. <<Quxt-|E#wSmPk%Ͷ+.WG\va\?7x>(2T4xd l3/S_|4mlJmZt2+Ec ŧKe>}TlՕV_'=ڏkkQks?>\W]`Hݠ2wMͩ-խ[sǶ'ߵ\n\~.ͺz8ـJo?fRvQnbޥ|^ pHYs   IDATx`Eǿ'$!@h vvzw)g ;(E:B %M^K#Qfwggfg?73@ a6>@_Y4(%PJ@ (%Pnkvt.zce4PJ@ (%PJ@ (%PI@ p:vxTW %PJ@ (%P6?Z9u>qizJ@ (%~fϞtݺuk0&PJ@ (%Epw6$J ۇk"''ϔ#c -- Cbb""""@Ƈ 5\f rsYf T ڵC]UOf7J@ (%ZOpZފeee[k~c7mdNFּ ZPJ@ (.r!337/#mڴ1k B[l3Fp! 2$_Jh#F/,,WM-s…L$RڥN06l2_㕀PJ@ [W^Rm0lpřH!))*%PgCvyf#ҟjpe]`Ϟ=+F111afYYY%--˒I&OA>Sޞ=9& ݻwotVSD)c=󑓛2SϰPJ@ &i/-`"c@=ٜcǎf|r ª/>²}@dE}"4' M *ݎ-[7cò(}.]\|ֻ`\A8SpXvUitK (% oܷl.l|oJ50**4vחI__(..[#M?=ųU1nmֈsVgEI_`ڷoo:&첝,1\W&Ynwmr[J^SC w.WJ@ (%Z̥E^A1J31CfF śb)FA|p2,zq|"=حoH?{<gK)|{zo:=PJ7HzٲeàAF=v]^ "+Wb޽6lƯ+נ@vvq/d?h57_F<.l߾ X&/y|Wr,f\hS_;wDrrzk`Y82Ÿ22_㕀PJ@ 6Rz#6J^w`k-h W\R㮡@zÃ^L{_cä́v9e_'|!f:唡GWĥJ@ (%"ݻw#0]6VٚFYʛ8 %7YYYf?V\3pzsz?n3O}YseXngUk^ $ ܶmyV]ChXQ=J@ (%$v47 ~ vUYge{Qs!()܇шID|e-hۡ=~l K)'%PJqRRRPTTdOJJ}i9X>u۶m zSq|n=TX[.Յ&-Y" А t5=J4L;;6mPe: N,&s*>L>Vמ'H])))UfLDL wL uIKFcˤ@]1IJCe+%h-sIǛ.9ǧ~#<2LR"iw-#5):ds˴"`s AO=<hOB3PJ@ (%{hwu&lH[QφgCg+R5g|btg:O\_ʤ>NN)qSNM. |<[zw zL (%O wyY3@ހ}L+bHWWp8fO)%`ҐI|k۵kWz2V5O}XcOk)k8%PEM =ZWJ@ (%f2XMVYRU_]+%PJ@ (%5h @E5u?4OCۿ2=PJ@ (%PJ@&PgZ7%PJ@ (%PJ%iB%PJ@ (%PJ%ъ)%PJ@ (%h9jh9ZPJ@ (%PJ@ (999(//sFGG}HHHvLw2l޼֭޽{v͔;bСo 2uclsjYJ@ (%PJ`&@=C!&&Qt2W+%"[eزaRڵV^)QQRrnW@@[y#e˰zjt">><].9]bȑƐrp\}㯂_" v5WDS*%PJ@ (%P/+W"==z6 = ĜMOm6P/Pd5ЀѩS,ZYkiv(B,'''عs'ڴik0uTy晭yfMݻwW^rAO cg}v >#Fh-͞ 'WzWL`ZPJ@ (%^,Kg\Q0En hu5jTUuMu8C5v!a8QZ!JR4pժUXd׽{w+A5+ R{1ɏ޽{gŠӵPJ@ (%P';kdŊvm^Mgtdt׬YS^__=#'`2`iiNBT# d48bd$UE=(`>#⤵/ [w2S >8.ɆȒc`:&oXZj)->q-]~O?~+lѧ;;!RRR8l")*[9(ZhM:a x>;ӧOw]AD=` XչsgyN#ZvPJ@ (%HoY3:8#l;et[}> gVkIs…܇ؠwO#Ÿ!zƀ܍)L~(Rvk5pzV~е’gᓱbCf'ߏm/o -qb 6yyf pOzBp9M) ";… 1v|~Uvk12pX_ֺ.+hPJ@ (%PJe P&Vx)w71Qv G(DֱZG{Z *Е^b -J#ք8 ȖoѻuV:a̳q{*T-bH: wF<=`|_YHプ3am[[vAi&p6 3")<~Q~_폀@A>|R)nٲŔ:cK><bYbcܸqȚ^>m*&7"07L*Qr,A%kҮ~!N?@ξ4xe"ln z$ExB#_e.;nErsysNQAZ}sDosMqOO7 Xn1pv`Z. ĒFв$Z%PJ@ (%k$ "r@7mSSf;wT\t =|_.SH#].]Xط[KY3X\8! f<P _2>?" ?0wj] bNإu/Q:Яq+󰕛vӚm %*@ ϾpY<%#_vKâ5i)3BtiWro,mG>;w-Bzwr= >@'Oc7 \E…8ssx J@ (%PJ@ 4f[!yc4RaSƂrъAhՄMT+e.?`ǡ`ҕ1XB⺵nhm`@;z>I_.ņez<,]P$^.@s]B\&<^ڱUrӃqҋ۸wp4H}1^#guhеPJ@ (%P#@7w!6/"e2YPί1>i`ls|/+-3q ,[ ?{ C K5_ UjtdʿnX\Ry -@ŊZBʺ0X7'>h9チy9>͠4 A iӦNkR_9f@jq3%J<$D6Ek0oX>=rb֝ٳW,$=CrL/5[lӳS%?رÌ18>Z:+-3~{YWV5/"tv }k] e,cAz-^ԉGq|xe.B)nÃol I(ty2<һ"ZK۟dޖfz}}^?@! 7Cam\g˄V~B6G (%PJ@ (f'.Ԃ,AC-3\ ^< 9U#~NT=]V< iszB639"?L39"X}HКb& {` 1b^==AX!0}y,`tCDkgy})]#`9;$JD! ^'d 9c5'u[ |V,Oc5vy9|Ygff޹9 d`9̧A (%PJ@ (#m1@7pta%^bD/1^ԛ4x%~k#8`;ϳ'?8`xƝrPx$^l5?kbuQ )-rs!"38BP[p)XvK裏p)dGd{c6ڥߦ 2SXDI_-@AY|H"2 8`;h=r`;|g9RbZlYpbyS&- @q83iEBc<_iȲ2Z (%PJ@ ("wwh>  ٶʤ%2`ECӚٹDIM$Os+{E)渥 XGHMln/}?-g "7#FkaL/f/wȘ]ɿ?Zi‰#۷EVz}dtV PmPhq8`M7/z%PJ@ (%Zzo&6;Q"y2\N69*ƒڐSF߼#{_jCjwѶ4WqG$ʜk>|K'&]$z<XEauVIh#-"l !˜>UAw&@׮]+/..֮E⡇"11N*tyE."!3$MXmAkeX <()ڭ8ea-.t , XV\PJ@ (%@ ~|P:f;2FO--eQ2ඉx7[OP'QTbk:1w^DRWz cIp/ IDATpX_75'j1V.tΗRM^?ېI üp F# RFA-mS` 1cN>*mԩSMWJ7x`3u0,igRDyЌt-w~A ܶ d;ttVn{R֪:ʂ[xU ̰]Tt rq7hO˼Vw _oeq^Y~n1ꫯf޽=e`@r_%d{iv ~֠u{u{xې5r?>֗ / u-] (%PJ7H3 @iKWfw;adỹe~7ήaSBCP-v &^z"R&ؘipKKZKKK ڬlP06Y5_p!lbZ'E$ FNCNAQ\ fCS_#[>C֭3Yj>cZ+Z 5":+%PJ@ (_jFzRPp$-`޿:+ۢ )Z]5ݪO s\ͥ+6[gV\NfMc5p;9w(:b52zp ;?|vlB=ʁmӑX.hI*X"̸|ɓϟ%PJ@ (%@qƖQL4V֚k *.bJcXͅņi)| &LRŵH9k^/DLGv5-5"__ (%PJ@ (%ZPJ@ (%PJ@ (pYPJ@ (%PJ@ (%pphcVm(iFfΜ٪Uc[v5E%kas6}II J~&&M&MPJ@ (%K`ߖUXye2( \YD9eff6P/>y1Z\vX/^y߃QXn7),:=ց9JQ3Jاbe5/u vkn[/8SO2ft~f pf,J@ (%PJ@ 47oLLf3:u6qKW7O;UV)IWkL૭Cԓ O ;Q'0!ayPJ@ (%h MYA*vO~{vyXřƤ]!Eɦ'#!ƃ2)(ԛDzB6NZgUf%Ej-fT/}7B*)ܵ_$Zk$"9\ی+҄%<}ŵ1U (NiѻWb⥧myJE@1zkqj220V.>87QpMt sk2b~|'oۋ{10-&x腵=0xEL0L~h`'L<}_ ^DDYǡc$Z%|C}؈ M\L{{:zFzH;4\^q=`u45VmWGd?KŒKgn<"uƽN|F /F7ʔklêC  wF0XiP}FbإhKԩc4R^$aOƀv'".CrlC 9 <:as#5IBĢp9ȓk)xH*%PJ@ (%da45#VQx<0,YU?4q?\pW6V4ڡB1UņْªY/˷7c,:Cp;omR#0@L)t3^~쳦g+GIAl@er^S1;Nvd^<rW6x ծfz?ʊH{X=,_/JJb,Je2N[/c0?w=Ӱd[lᕙ yӣN[}bդBX5=xq ~xj|t729xp? ̜x)j|9ȸ $6S__Fhk>t8Rc,#O0} +QC w#븮PJ@ (%hJ3_Cjk,uf Gzrt>#8I~%ᜋ.t=6 bGxʊ{7#|Stun|(\ Q8XpI8󊙘6#ƞ?CLC\ $ԩc̑TzҖAyIʽiAMv~ɺq%6) 66"#/{…7*V.Jv5dh+%=GB<ĥvDZ ,q&=Fvs֊C\A֯FYQ7["wbGD2hvVꗫu.&y%}4fmA yvSHʪKS (c\.֩b̅$6nAqgbTpK+}ݼcP Wb7JՊ5;++E4#:&ƚc^β2.2m݄blQ?Ai$1g\ Ā>!c<ŧPy`4_gغu9;~4E3v8nL.d9 RPJ@ (%8 EmDVv($ X7 i+}XRxm?& |4 .Xw(+tkA;3_Wl容H^(o>6mW$F$cgb/[}!"aM~o~4ptH@ /Ƌ.Ë~a>H0z*uL{F=Zq8k&Ѵ8GWA0ƘŦëdtGI{' iwJ7qQM?[Ͱ3pp?I{+)81 IwT~ >#??<(>:wwC*lѩq7@QCG4gu:>\HNqcգ  c:VM-OM_,C3k):].B[qm{x7ǨߍOҮD:ycgxj*n]r[gBe;FO'g{&ɽQ!؋bۄp!ii՞wc+ o"#FsxL[,9W8>\ggٿ(e[Ŷ3*!hJAynv|? ,}1b~,w/@z{ԠPJ@ (%@c80'tQ6+4i+e:Nب`ot*? CҢiq/؋!t3Z)h_8cNE7ˎ@2UJH=Tâ!m.OO\0Ȟm܆6"˃%&^{ץD?跎)' VDĻ@lQq 5RJ@ (%P)gt>KMeWhUJ@ (%PJ@[LM8 }?dVf9Y8&yU4u,"jiv1s@UR;o}ڱf 7PA 7-EmZn>aɀr _%PJ@ (%6i-oxZy׸yfEROPJ@ (%PJ7NjcWJ@ (%PJ@ (%ppp~5)%PJ@ (%P#PJ@ (%PJ@wSQ (%PJ@ (%o-/7GKM?zNjļ۰ dG:숈tz!}0zhrPJ@ (%hf0sɦʥgkt_ ($5xt#Ncg`H($9d٘WO7S@(\vqһc Xm[j{ڥk_:L.~j/]=PJ@ (|ظq3;>Mٳ;NSJ@ 4@ M]_u}jB%'PRHtyS6c z~((E&G|eXۈN}:cQ2-[q&u9*пf92=|P#@ۦJ@ (% (ƷnB`YO?иƳ"<{h4gSJ­9E~a$G!#-٤-˟.AyOa W!1.*l^=@x%JnxB<IsFO3sh3d(n eCsw%F?b۔a΋sq"Ɲ8L-1Y| _ߒFݫnެԦEqbwaŚ3h %x_8\uٵjo& j͟hoFMh!OZKIeG+W#@u2E 7sFWv}\tȰ>g :Μ҆!A8'cm^ 6`.vl1e"cbg2CHӯYuuO nڢFAG{[b*qm6UDtg IDAT'<䯞BGPJ5 xD tsXu\}IxWhiPM9s<|L&괮Ua[4&|ϰlUJ@ 4@ {? y!c#vIH@ ,oG└<;yye\Dp3Á-@(umm]^#ЮmOO?0+ЄeۖJ񟛛k߰aCpPOmM͈1{7b](0y^ꩨRJ@ (m\[g"7{$Ak$8d~6ٷEtLH0.x}^dddnu??\]~Z $xA (%\2}aͧWi)rv0`3hG8=@ks!@dr2JpWObcduU'ކ6.ɰِTiń/3q}b +#m!aZ;}1s#S5p{-g׮w aDP˶"W<3׈ky?̸!L9P-E-VݶBזe(۹g=ܝnHIQNYR:&>icCdRwm']#%s׺Ъ6{>\z(ά, | X7EĿt:iPJ@ 4@_.=a9>-p bw -2pѣ4_HiOOm;a4 K؃˰pE6b]f16m,rYQ+>ElHrby5?ڵK^! [ |2OXNs.=ZZfuLP?>Y"Woً5{{1ΓA (%Zc=Cv6,͋!n21&{se\މmǮ t7ϔEBSS^mStFG`wuGnQ(ڗsΩisr ,sݣfOp=6tӦMu,^!s 5a{|q~qǤIx8,tW^}?lfn_LysέyUPy3ǟ17,٥vͱSN9Fϡk kZoA8_c[k}@rjO)&zm}f} 77jNJJ[=%e>KcnV\yBҊn`/"lKL1 C?,kSLUgA3g VٛfkgYShK 0[~=ȳ裏aرN=yxZ- WҥKqwȑ#aC&8L 2}EofeyoˬSﻯr׸qbcb#Y_:tyွH~zؠ@S k,Ơb⍵Ոva۶mXxIe'ɓFvI_߱dc߾}k+{֡#F9 ~i1ZV^f~hFN!E9]u9~ 2Dt7|XЋKaCR]3jժ8SMGD8ZA 㟯1::Cƿ|O֕ 7V [7Y_j[ڬ /k,sg"+ٍ6"\ks } Sцxv]7$-.^X ;\.g!ݐD_>;ˉcW)nus:I{׮]NXTT &ÏD?y!-޹窙(ya%@񣳱)X>ۈ+5Z<bR'}%h1lQ\C:ؾvs%+[i_|xẃwn_õq\Q7~ӰGRs2?U?#‘߬+**Jm0XԘ1cpaa"FbСի~\CԊ` C Vg"s&dm}lUgFGE#"YߦMl޼~.b!{VhSN9onh}ysýXzvVg{'y!U+Ww^UF[a^$VWNvk3:N1( PZ%6ovZ8ck}6`gk:O߾K:yn:ӑ#OOIw)_|QZggη}vxe˖CG1U{]by4(NbUޗÝ;VoAzVXF5zPG!9-_>豕w-WsݢĚ0K@EWVe\ .%'O7ߪ*1ŋAl鏘1#|x`W<"t/jB!_s?]s n?c6| +4~া:uW_yV]c8 5dmބˁp̙ ܞ#.˗/CƍxGľk<[dλo%_"PT+\]s}qYg 拇6=9Zb*wGZi(b0 G rs>HNϞ=0pzTwm<lK-?ol޴<1RiWglEy0=xr}wt/CٮڶQk7 )(`oؑ~- ^}]5&Eڔ^z w>xc|IsTw hxif\ e^SqCGU8I+K64PJ`%]~Ub4h\?2ϊYbo-\enYG)-t{{o ;\x<̳xgPT\hy4żWxc3M8a=Rl4Xh Ze=?vCYu,ifw{UkwĺW3ꪫ㏡ .8߈˱">G!Op駁 aCHE`V]SS0Kqg 7/_}UsPtX;:̍gj ]ѳgOX#b>~^z%wɺp".!.yy(CFm% *^o66^~e&I}Xh|vmóh<âE#{pػw4l>F.Pev1KmW* VMSǟTǁQ齐SпV>z/&d&42?s,?MWx} ONN-=]z%&o?|=Pxܦ?o.222 X_65˲)4#7r5zKλkϑƢ,}bKcAiͦjW#UVVf,y cd ]s}hJJJÇk>0ָD\O6 }?W9|Ki#Íˊ^8d{DY[{THڨU}2cV/w+G`>&PnTPJr JKLoXRZV,^_J bcik5qFl=+lAQE-\-X%-P{lD3A^۝tJ@ (%xn5K~ўuޣ=vMyZ/_o4SqWê^B`WDm]p(/wItGWg~7o$ASx̙g A^}#Q񗿇 )KKZQREbk?ճgШ_v}Y^ו&v>c+bn|1bDeiǎ=:;belЃ$cǎoSObk6à+ +z޵S4//Vvnl ;c;8Jє_۷k ^5ym@uz,Y1Mtht•-ޡ3oċ'}=wq㌎٫<B-BJ K`w /74qLb`}]^/-auRGݤ.l8NoeL?4`,z,'FGKk˃o>fO 1cs;% cdYѥ< |N8D# 1cFx(nY1zi,<ܮ ;ѭ[hK$u>Ĵ`/箒} &c~qY&1njŽc/|oˍwVf1~<YcŇsQZ/}. tzgqF/>|ɘ'7k 7TmJ6`=ֽd!+X/-~sIbyYGIϡ_E6ưO08+u@?n=d2xJʑޮν@a9sJq;;uļsMKHRRr/))g"'LXxsˀJ)gǻONߞDZmt"]"Z~iZdw{} 4k3=2aXR#UIJ@ (%$?3nUHBj_8u^u6q.lihG ;vo37a̡44fitkXZ׮[# ʻGf𡸤tޙci\bHwFV SO=ټxc_2,>#i0;'g  'r \}şB yϪB=@szciy,;b] iyǡ-M?YenڴFk?$#IJt]R>uѵb-tyv4}֮[s@hƾz;v4kJ6Z[{ñё=`Kqi"#mu!NV4tg3v JWxl&TJ@ (?[)CÕ8?bCA7}'??)iɘpr  ol{w6`Kޛ{z~g_LL$eU+D.m]ؔ *A_` eW+hAi( ELeMcldޙ|d2Ĥwf~ys统QVwG4D郺 ص؍O^y'˙' =>+}pܴn}?O|ޓ=cNfW ܺ>ڱcÛFΛ:/Sl ]$C;}v;^pRd+?NO~4c/ϯZW_'Ew003k};S[7+oggc ::^x8× \ޓxN /yL*EV_+óuiKc>ɷ+~&׵}gkضKV?c~NԿwoK;|$5W쯦o,_I>s9ki>byO^yEJ1?yo|U{2 u,'3._y}wK.n3fz& _3q"fu/?q(¾o|_Ō9.,;QXC0cLH13~g/(|oRzQODDi= "{.{N(}g7_{ޔO:/r>M衋qOش(NpP IDATk;pwO|h/ nO\6w\Ot0|&~C/?viN/[_ї'` ܼy{r8ŏOpF'Qrǿ>[W{r^W_đLw<>ϴ'?;[wフ;JWNk|^X(rِW_cp9FAtֶ qW1|wvh>R lWFwӻMsyOyJ;xl}Ư}q}ӓ/`znh FO϶!Dcpbk\≴N]wum䎶Ļ4$$SfYIٶe~E:` >۶>DtZ3!PC 50k`wsbr[_cŕޫ W}7_h{?3.b+wwy~ޕEgr`ѝ{9m~Dmedo~];^{ewq.Os)O~rz&;=_s֞]O+kPѡ'펁 8ԗgxռB]gv3[< /nYcwn yYwH祉WH{;Ukm|CoSF{?穑W^Qk(m-- I(o|-}npUmԱ6mյݽ5nfC[}e2]tH{G۳} ۭmi_Mh>ᕗmϽ,'̫xU^O1oskWcϬɬ׿7nmjo~;/O._z\]*~sg뾍~t:m횫^N;'M8PC 5p4vaqRO^Sk_ۯڙ}ggN_{՞Cpig`OkW1Py+^^A| oyҧ_/oo{r3v3p, 3ǦAze{wjg̺?/śnh7S?v1p4p}'M2^4p阞[ .Tk8xt%@n?8n{qӆC pyϞ9 90 /} lkiVmG/vɶϞ3sr;o|45nvYm sNrVvxdEknF9mOl_0g(]np <$CMٕmӹK^+_p'1w\:xk[:O"^n}kSжKw 50PC gXFY/3خVa1zW}ṶgfQ}A{K?4~cq~bn3-noh{n^`>ns.⦅1&֭vXea|f;#m^k9_6?'&tLjQ+kzkyoԟvN砟]gj׷_;ЎvՕi?f!ywo/ժ+Dôj`{ɉZ{s>W|ԟxm_v7"\x#^6dA܀ZA@^Hnup t4ajmkyZiyʺuK}޻;WjWN4v}ȷmٺ[yX{֥'?i_ WkyH]=ऑ j`N'w1/lgom@a%w爛aP^wm~S7}`g$WSmaYmm ߾}Y9ᄳfg;P{ӡCsƫãmeΔ# >a{m)9[z2 yrm|cn@>NT\U֮410N+k;=:PC 55?O$gϦN \A~ʄĽu&.{nW~=d_8:g+:.b?MЧ C 505pi羸*㣸s쩛gO>^z90f5~ϧݟ6wa?_JbbfG=my>͜qֽ!qaEe}G+t<n?]̟13 8I kW}^/l*'5HgN\0PC 5NdDܮm+Þs/o_}k޽w4vqXuïoП'說,Q88N,|S\U?vփ' my]ӑ_g9񁅹 f\{9,  $pLm96,G,i{t42@?"z޻{xom '/G-sd:SflD-mv^-|m%!ӖBɣ2<->c7?QEX[G}E8|~'p'J[;C?+oQGˇ1em?fZ~GvNioL?2}v«5W.#EtK|ltėtԑ9'BQGO |Yoʓ-#~|ʸ:2.փ *jut$F ok+|j0u*}D$!+p"'r/ѝH2jOuaˎ5\ܥ6](e u8.[^}W?M{OQQ+ʯUOzkv{? __iYo|&}vNj_?6CzAa9G_G,>ݮI]n=.~m `KL6W騟J7e\6>2h3nȓf$ܓ'iY)cb9maߍy(ʣ 2+LUhc6=ZcMg;:-Yz? :•d$}\eV&4u  ?;Ũޡi62Pi*GMŕPi8HsiB4vHc<ʅ!¤ڑ햽3O fa n0ױ@> VсLVeHX4υl#t?+RNXtY#WS}:2+6HCQ{eo|J>N\dV6>%$S[ԅQ+ By)b_}l =5>]wbήnA(o@c> %`)=(J 7`r!FD7*EȣybxEL ]|&Tk}P2щ+rs@& xL|86i&x ]y[6>!amٔ+e.?s‰"XZ7E|S@2Mt"e䯲8ʭ:Pt5%Lo北`n:aBCO^H}¤ c`+#pv~TuH;@l Pz|y7u@-ya遻дtuLYky%}ulL=!AOaG'qTo M  ZQmЎ Ҁ+[&! Svԇ}:tP`C?ݘYD~ȓ22&b{# KNay/f/?iy`k l0O !d(Jr ZCHՁMWܙIrN'NW2сO{U{f|F~Xveh$6t2>~N?#.6$N..~%NR(6 '%2HMЏQt{aƒDVa2XY'D%g'b[xR|W6+o"˹l 巒ȧEPX<0xS[{,xK)mr Ǡ&dFE>kL N(+ kԁ('Wu/M2೶ɭd}/)8U >c LОyF|gv#y aOkQX}2l[1F62d;N9@|90ǘX m9.WXtgҖ %' zIc+G>دLgb&tc4 ʑa"ͺ5/ᅵ@ x';'7r%hn\,@ 0ɖ]q$[}/n [w6szk}XR&lɏ.?G ia$%ڬ# mn6{t?raz ϊ z5Iَ|02 zH^jC}4x~S@E'DoMY\~)c;g'stm*[?gmԘ|0|GqO_| ~QNA̚򪯔m1K ]D4տ|@k?GLSLNDG.R~d8S4=#LB%;I [bP4ԩOISݐ7tʾ偶kin_}EW)i_pKN/} l<SlN"i,y2^>3/a":9B#dz&+Hbn,8"àA;!heg:kgyנ ( 8j05"PgRފ4WX̮nTf2q[',r]U3-ѕAHD[[ς*.qOGǰ;㓜J2*qU)+!.J/ A ]ʫK/NuDi0OO<|xB:yqձŧeK{bg^q% S)X 2i&Tz %yAt(C4yj׊'I^Ft~A 98ƳP V>"S/EGӦv K}۹=^)`JGQѯr <4c /et>D:=Px#^ > v5j'R;ҸRI#Q, dPw[eiHrvl-ֿ"\5x:I[F ;(PnSɔ|}b'iY'98w IDATdQЪG.7vDBC>ggobQHOu~;J|V1A q+Ґz+tM';V4]¯@F2_;?!r---'$qvG?!uli u0_1PqhtmhC9?,[vA2ū ujGO ES[NxOj%VqKuf.yYzˇ]ӾU3;N) }];Y)eNܱi'<]z6\#ⴓCD&hZXd`VuxhK_^b4|' hG#0`K'uILWπG?$ YCp*j|lnOnq?NvVn,;N`N ތ5(~8wm\㛶2q ]˩|JT]Ng~] 0CZaV"SЌN8ږ ز#vC$<&뀁ޣa R%vVzlƶx4,Nfg+| ؎Y7m  u)ΖM!QYZ`:;xD3[> 詂cZ u[<䪸x`@uz,6t.黹!x ձYT]IӌזvՂ~3a||k Jҕ䑮zTpv)S`IPȸگIy5rJKxoKhN4P#oy>&&c2leɣ#)ȯues䟺Vu^+HGMҎikyI?`f]|2#^R.uUoQWҿrSr>E!ֈrKgvⵓ[zq?d3rc0fVQbΐES6'-LN8N_7\6{p:50 x&YagqmI*yg5q*Y@\S.TeDQh GUf9B*4ePi Wd_U/*Au QyH+4z}utjBIf?Q|R Ҭm@I˲FP`ՕWix*PpS3F*Sp awϳ.] Q$ë$v:@W: ezI!VE<@g)"9W\ë,>^>^̦_B #1r:&= /H lGVqN4譣~ctc5߾~ | 2W*KE]7ɫ\#7Y v)uB0 ,to'í^v:՝ ֿy9uUK#3p⮃OXLj?L>J\A^ӁϲUN_IͬJC@ ."H{n8{ѽ~7~CVaIѡԏn}U-gtwgMY> qMoϮO8(cd%cNG@A!RMoBK&"a;25gXVƕ(PBH/‡6:OG=+ C@em. oN.I&餞FQ]~]Xƿcw؆mw&&HY`|֏el]7\աu?s"!>4Y=fP)ˠIʦ"L6b 6e:mvƱ'tFY*%9}vdd0>5 ] 9EȗOq q²5=fN6=`k}M ]"}!T0 M}$ҁ#?I*|fUY )mFdF_{ڝc %.3U|C):rb)f^2lަP`Z?CK'ueOt _^QLn޴y>[ֈ~MvC=t.);DEXާD$cT_ 02k=r`]z__@'mt~W\\;j@1ȫ4!~@4Z-kҰ?QvbO'i,hL|ɠ w Fa "_ҘeKoM󖢨3i~$-9Atp ľnoFweZ9h PauZV%Q@קpXEBk^*/yRo; NN%1O@íUM!^f!TqU'jrdcz2Y 7xŶx ,b@YwPFz4TfGG鼄o;jmSl:ґd( P\3MJ[+q=9ͳ*eQ_!|8sp^5Հ7)l9sWti vJeG&t@Gٝ}=3qc۶}};t;,'鐢|,q0`M'P6M4em҅=vSVܐ: <*HmpˠƤC2ղP/g) ;`q {JV6aY)lov"_<Ȩ%}tJpO.Z^Gя::YmmNu>{ b0\]ޫ#/Nm8T_ Ե)Wp=`4W J__\,/[4㬚'}reb{_><*swX:SWD%>3m)<]-{dX<98|Ë(~x| QH_UR*$ q*F);7QX`Dٽ $-FE U;YlB[lԾ;OUPQf/m'f7f;Y~a@'jϼ>D`7vX`.NA38R8 i^\ć?w:BG7V5VOo:2:^t!l9=ż頄VHYx`'ŁvAX.mu5VGz']0Lϝ=#ro`tD|2Y'e/υd):Q _]B4C,yWHʗW_l.pKizKJ_.(8U o.Y„\RvDzgfxx݅I:t'gʖQ}HǃD;z8ue'؝tM%I[BS6T$}}d83^L5RT(hcXĊO-t'p:k)f6nZ-Gim[3?8nD6s/1L}(#50NQb1>eo'#2ԗ ;F"=eVOoVE] I!hΝ,KQ'S_HLM +i#/4I+ۼ ^,lUuWu Lhs kgO<3O <%AcvE?K,%zy< :O_hkV'SO'5ˊe 0g,>=V:qZ۷}[e}y`Rfr7H9Е͕7?Kq͙ LF-kQ۾%!9>6HC 4o:5)A.v%B,`9iI šP)ϋ& O˿}."f9PGY]H]K?)7,ԫ Roq9<NӔQ^ l3=ED{~b;p $-3Aa>Q=ohۑ/x[&=΁G6W+2=r/|E JO{vo;]C\QW'H2I?U~͝:m+)SNCfWuHY /{fb)r|ԆS#iY'[Jrs oH>&N ~͘L2ήE+CҏHSy4V}e _[L@'z.nč c@.}G>>yW鯗۾vbIX]^ůeɓ4,2GvrDMt/I]%̩gv+m~JhLɠ=lGN* q&? 0P(~\;gN+qr_XVmeO@f_)"^_%%}!癏!vJP s&[OU FA#;v˜ \)HœB*h ۘTj& T(ڠ\^ B:"D/hҦ"N3|T'ܫ*,)J(SY./PpKGxug7Nnz dG`CS#d[5RD|Бut*Cœ9Pe+^RA1cdö($W78{HD=Y*U ͮ? d^@ T*3;[]rhOxLdFƾӇy3 fGV९G|4|!K94*WY]?7ԏe`~KLkuWdM?֓v[asҪN4I0] 8cjh#;h{_5H-p$gsڠWclҊ.tLuuUohߑѐy!&wɳ:9fmEvf#2&' Εה`^e׬&|?J4SWiștrgt37J@ '}VT,q4qG4cGpR2s:ܲ; &!|䛎؈恧|y`_ߋaUգd@E޼,33Nv3qyVe?gkt=$tSNkӬޏ<_ r HM/2ΠMc<):aOl/vg:A XP5{6JA X0d,<UY?~UmBVʝ@t*lZ+xrX!Wt22x0_ʾzѯ9 W*MxOIml>n9ӾjҺ7dG>IپW&SQt.\1&KYze[9tr_i\Ȩ!]AtLk0sW g0 OA7΀CM Ht|C}(g:yK kU=}:2 tUr@=7EȽ!8pR^8sc+U=@|*NQ!;$LN5?,$Pncv(}./w#`[iPVE~AtJ0-b28Cfbd+ZS*1=U ]Ef{"&;g /圠: 0k &>x[wQաr ,iy3+Rqe Lĵ XHʩpJ:/A.y5^ !G2)rh}!4XGb\ 9NtnA`seDFB:0!aVrw[+(zVo::=WyW\ͥc"8==խ6O29" }=g}v[fN:9ԑSVm -v # eb f6я/yw+[ΖL!:2oUJO"U&gE/9SCxm-v~hyIWAhv"$#M+ I& {%;em|kXhـ_ p),O<;APZL4b:%2!ע`O 3NNR[I,'/:JI3dG-=SGu( zq0o#;γ]!vp{Mcv`舚k".շ|"FO?di&۫0,罡d9٩Ы})pw5(Xڰm߱fZO>Lhj8$ 81ђUFyo:;+UR/;q?If@lQkOٵ-ޏ7B˕gn}2CKlG hkk`ÎѺ ;x^".mqrr#/FW NOIbwH tTvNE]:2ʯy{^IO~2F!.t¤lW\~sUI fr2:-|asqAN>}bIA1Ag#Fg Geu( N >&|?tz: YՔm#EUE?N 9xq j7#ַS䑧+K|%,YDrP儇 U<9b7Ę[?G^rs2J;YUK|2m2&ݹɢxKECr/Ʈ&]-ՃbfYlz/B*g~{tl$HNGB7::yoK~LxpFN>h/`WY?k=b[c!)+; ~yNfOTg(q/bOEr~|!K;W_(qGwΚnKa?9W&kW%5ݽdu8@fe (Q@PJEtI$ΙT̢J4`G|4LgCe4`ު֧qd7?jkY3v=Q ] gq]%`vU>*`ADj+Yt(#]}&pjV 0%Ty ^Lt3 *8t$)G;Xc;א[e5tq ^4#/z)HNJuP:^KZ!C^3]HJKc}dC%-}:Lxx,6Yi-F'42(6Ca& }5'uDbe*ky$9MB~[VY1Ajlt{ޡdeY\^+3k9 >;eUw(dneήdTV=DGQ&2ST9 *Cy(0@E9 Z^S蕦yLF>uYi=|*yS Bn/C;+h#\NH]]m3QJԃy>IK4"#e#Iʫ$'| 0hz!:ɀHt;}tX]:P%$=y>^#t +T9:@}% ~C{0:6)8e@d.~h/0<[ IZɤh=fmpo :yrgxʷ)@夊qXIWZvԔA,~'Z vȯ;ߥG6)OB ȳ@r`o3d39v՛%R6ÿzGoWw ߾ Ȣ/4A+Hw@+Jɟ&kR{F4|_a:@ٵJ2gU_g +bIΎX2Cph'|ɣo.efn *nq#E8$:* @>e?t6R8> ɠzp_ ^#|Coo&c~B_.F(+"=miA? Иٱm>s7HF|QQQ!`?l8~9&usԭ ^x5%cv0p[ 7T|i,sR6i j.Wu@WЕħNT܃._yu22Y__]ڈU|d?8OV]ȗg!>SՐ:o3!3>?+8w  rMC+ӼL M┆7^&n/j2P NmNyL.zc ;lRY' s&Ԕ̈C]:RvKy ,iޗ3A(oP.Ză_ClOEʂ.Ǎ]WgQ;<%/SNj(Dt:*?2$eBA~OĉCl\-lb9&Qh1GJ|ЈQ~+1 !\u}I-%qXxw aġӲ du|^: BaH7-U>(*{KXqzɫlpL~ LȖqrt[Vu<֊wِ<"Sg\B(ߝ=T|!"8`$ips~Or)S Bţ;X(x[}g}"J(ɩ^HӮ-VJWOK&/T0ʝ앁,k^ ެ,_p%:E=.}:̌}guS=} 2GgˋVʋY^D) OOʯ:Sm|3m"# ;d b6y&e(UHLsG,h"B;2+錮lb?vԭ:AWīm2Yw.<9PP,UthOئ'YgF]at*3k2Go~CCۑYg'E:FLD}j`=>Ke-+sj;03r]kiܖMKћ$"yq 3^~W6HW>էmsmyv2@K[kWWa,)upё )Ϟ^=T,0 |dc[W?eY sˎǠS;0wW> UOX! ,nShJZ.ca]'\Hեu|J3 *= *Aَc@C6S2e7HttȎɩLESJ- aϲ5x( So8c{[OˡXj ,eޯ! Wԧ6>-iKʚu>meFݑ2i>ԧh[Ve%b1Ԍ0T0V@QTf_ɢI\IE^@?ѝgԕ #N2`$OG#ꮔE h#_qb.. DO^4*GF=Gޙ2^'ܧ?8ka2];0q:z<|X2BI7|iJ[p<9VhUPvD-@rש$@^рnvo/f\#8&qe;P}[ʄ!$w7":h QzCM򮞝ڎ 5[O77Ҹ"G V H;y!th0l:?pG/@vkyO8 MB:Z B;xX_.'ƳSwdÀ( Zmw9#̫#;!<|ǃQ @ `G̢ >  Ie&h/pd^Ԃ&U\ǜMTPoLut".ʨ>#ȺY "K]—K 9CRpC齏Y$1A|3x<д`U갇zVE2.gՖ,=!D^F%N]⊌lWӸz`:Şz/=IϠ|}uV6PKm}DmPNS wlS\TX@}|})e6QovRC阘xGXE]^|-7rҿ EZ%#WFzy8e.2`O`i0l=)Y6Lxs:>LGK[+q:iv"oȐKn<ж+xNBAZ;QG}:]tlgf IDATЕ63+֏NtWV} ]!은RsfV|r^G ~rfB߉d{r[C6|wJSV *dV}hsRG _Zfj\=X /ruaPެbq?tcpC> Q=ofA?W˿ '.e l*Nη7㠿,l֮G##VUW Cw) y|9ڮfkR6׿w։M&S?ru kNH9u(m;YDCyFwJK9p6_޼Vq?`ّ2`=')^v@?Ue]hI]k7u ֥g2WQZ3lj$*kXt:P#!g> [WmERd W _xwFt83ض!g2mFly88>Xe_Oo@TEa_QwMe >eZ#Y9tw0(;JOwφ͑)tKm~7`xw \W3IPTQf``+:bcv-,N7p#S ?qJԋ9G*b ,M6#XQ:VA8Gg8u@%W'PK0ܛ aMBey/KE}Ґ%wqIp߼, x(qHuSt‹`w\X'WC&j? 5my_FA[@KA>]+uMg6ZiGO<נ4,Ӫ?\da6xK/\hCR|щGzuTW˟ٖ04AuR<-6,Ň╱ʻ%9p.%3W**ŋ9^U2 xu5i[?^kws[w=sYCU6q@\?3{m0Ǫ~~2u~1v2h;xd~.gsᣓ 랿9~+bŷ :[୬@Ur*O'(՗xlc #&;hSlxUrAΗ|1;9&87B:$ߑ tȷu.x pdYڃҞJ xU-;x*[a,>3۽ɹa_:>-[G:5.9[%~S~ T_\1tG h 4&+<_Nߎ >jc&V7#7aOLFWfםN <@m<ꐲ?'?}h߶YFw0d2l)=ۉqw1y} xa{03䨞A[O6 O2ޅNߊ]" w}թ"=.Cy@/9gC.؝ݯ΂$oY)?6鼭dyk;㠝G !qkV!mL1U;\ ]:<'',x ~W0)ȊME<:Mh+mX Z۹@x1̓&+cѽ#3hȓAHO[fl:9k G6\"|O&j̇ wԿnlVF~:6mi:_<}סQECh?O> 6ǬoE2e9䏧2{!I ]~w__޽f t[{d (yc,8t&%>;\蛍EDƶ}|힝Agor݊ƌdy_[&Uݒ}EmGM6 m8}t"}=(:;4k͏d[GkM<,k{A%Ym'N67πY[b#1!nUl}̖=q̗Crypth_+>7l]]jd0?A Y/4 >Z!leV|'&rqQۉ?HO ?A˂*a:A0]t:b}sٝ/{ϛ I`EY 7("nDDAs\$<JC$A# >e|]9 axtL-Rux l[(]C,OCFZR:6&7a`WF)kr293(w:V(3M߽AN~^2>V RE `n+}2dd_.'K{885'\lVquWgu>Z?BsC?:JSHiT9 8RW%.T+icG&EJ[GnTVlT{8&98]aCjjkxg{ez)|}MwE <ܳrf"~_}&#ԝ쒉H{Ftdڭ_tJa&z6rV>8Ǯ-xT6}MR}Ks{xΪсg[σzTCO,U॑|%oXEoD f.'C&37o2)z#мdk:V +E2$m@AW5~v&~Cz z\yKױY1>s&j odS'VWI0مjTG.~1;+DГ@b}U=UE`~LiϗQס}g.2OdMe_dH*O-_Mǿ :Irxq =< d~igDJH_J$j-× U5x!kݎς6@Lɯ- =g  tzpDp;c|橱As+a1Q@;c^m٘?li#i6BNɊ( Gf Hϣ%Y-.wrsݤrJ5@?}MMބF x׆V+`=طGH5]nDnwRĿhkC / '|I14۸ Yp8:~ߋ/2̆q: v^Dk v5_5̞'Uh|ec| : ЊFYlI_gvxknM&B6m6n~H>3puxilQA 1ѯlgv'ϟ_~IW-+~:op'*Ihd7~ӱKu1}2Sj;Y۳kK/ 8cM} v, ?{Ъ-b׌7+aGt8Fv)HC0L˛0%7'C{n4l /=?1sMFz*{&' 6:.d4x6ɯ-2A[C{cStI+Bj3WT^JtL79 e峜s?e;ǧ{͖6YmE~+L"$M<͇ wSB?BYn&5_yP@@~`}ƞ7̡G?{tg5neG0U`4CTuʅ.g@we3G{jg:I;NgˊFz]ݠǹO;[5CQt2ѝckw-Yaa`cGτ`sg5N5ªL DW0\݃oP%ƗƪUf% ]\8Qt6[+o`%%JÊy_pKY~npw!>'[qa6IuG:Q.G.Íw:*^峯C{qy&9Nl"9:F>ͦ8+49tOvA~\AF{tȺLhuWٶD>y{冇}W[% ;|گCv\t!WY%][[ӶQMdDZΆ37Y,@rc- bn6'LMՑll6<ʛ~}ɴ2,Ѳ7&BoL8d` ?O|~~I0rhjK7Rг/7P-!A*Wt?פ=dn_|6V&cxFK&;8oˍ>}>'wOF fDLL'Dm0Ym4%/w~Kic+5ܙy6徿Oӽl2'Ӈm^tO_|U_7>C mt&* ~ں[H}貯d5gP!ReWUvztώ ԭMk0~fi Ϗɨ $5^9r8mdpE`5~خ,LpgSêw2Atm[uk+M*5Ǟ6鲀/Y@l&؟R=s^MqszϮwzxȞmV-> ~3# jm'$Gmӯ YpbX0d9'#HZ|qh '`6y. ekwl [GO&K]8?"CyïDr QVq6w}?1M.kGdtVO&ccQ.@ZpY׮pv`=9>^,];Y).-&cw#iW~tUo=WCj8 ;}ճwNɮo=%91̯_Q Vl~oC@C;t>Z'%\zp =7曜v?S,{!#HOfv/{K_!Aڲ*Io}mg, ^xlm_+UҕL_&7o,} rfw 3:OrM˟7x3ie0*B/>%<ְʲ]g. 3)a#C>fK膫&P+CoUEypɂWϋقҦ3{-y@}W"Py;^kHq$߄qxc\iToC@Duʁϊ;![@;Wu?XG2<YFuSns.H =cu7`|h =}stZ5;v*yhK1TC7'(]x-qFukxX5dpL :i̮#nuh>Wb2-[Mm>2Ǘ [ o&J٨ sd:pt)Mt|PfIG0ب\xfWuL.7Wsm@7j7Wde?]-n`o ;"㺇p̮; mYrxdIA&<MQ#-Z.r;mwU =MWMth;ǟ6n63 "mLdȻ cu]*Y4`w}\pK<6R7[ 7=fF JD/^slV$/>< ^yJW (ȏ^}dzιAU}(?xB`> ͠4\wGhbp0]phk@'J|"И/esʇ~AV M8~mwErK`7$K(agxM&!Xj>m&:Ɍ ^n?YOɎ*X>+<?9` Ao?wcr G?i>yI z:J|ng5c$g$TYk~[V~lo'~ BVugg^ Z1:%/vj@/0] }ǯ=v[0|~8kAvѯpr*NjɅfڃ\ V ҏGfhaSaksI×=EٱLfۣ1ח6^(ޣZ}jbO|{l#yyc}6A~˫Oߊ/7;^FGa}2|y& sm,[pVC~ip?I]hqqs=q|qDž-y<~"`x{TQmnv9<fMw\73dN/ \gPY;(B|0Bj!)#5ɨ.dxi(㶫𧿳 %3 w-FO7%(2^xwҪ\=׿ScV;u䷿&}R\۪|oq)^$!?"baۀ3-84Z+vdն4֡I R5A—mէA( tËR0;5\>Oώ=RGpտ9rp@=5%+ՊyV$ W-T;G|܉ O {,#[VwÇ?Cg? g2R.`5ٯ@Xͮ9<ʞ6s'yw|c}ICo8DJm}&_πk~[n2}}&9ٔ ׾d-eq#u*~o0xoP8TWlê&]l߲>@[U(; sLO B)Dr^ǏT沽hX=ƻAݎV>k"~<1Ntm!Xdg ɥv®?ݗ4V)'P]G , MdՀ ~w9xl* #.;_PbSgb'&ٓz~[lkqՕmHX}@m8''Qm%u.6і6# ?][lﯿDnnR ~AWR h"b<F&0=|˯>߽F x]{~AۿKm"*R>9/ V?Boi OOm0X] ZgmC!sq~2CY_wQCAxv~PϥD.t`-oom󱁰Z &A9#lH[RD޵[[1եOv{tN Xh[;(VbsU?|SixgCgPhg~Oq#|п#=?Kf&OngeC=DYvhϾ:9j' ShWY 8t(GGf7tSI]pnM$FC ^6S~KNtqSۚξg%<|'Oza燂 [!o@2w5(>]]=1lB6dKhaW`^[9;3;]בm9~d[hy ms/iEY@'2-χ9S4xNe+1sFevm@3]48o| w0e*~4\- Tq H^1֙* 7[~ OTޘd{ʗl0Lz Һ8MvjHgWBQ]lj2{{mO=-ЃS#h7@j3rV;Bmg#jE֢Rm,AP#}neIP&  z4 `/m;bIwזVjl)'юv4Wp~ fM4az{8B_~P YDѶy=& Mƈ>>Z d~AF#'rpx{(hT4yߣg}-%&W4؎~ݧVow[1 n+uB|oPf(H&- HY ihUrkc: k`ëlLÎGsQyB?VV@I Q_zXy< B?I(ӳ1k<3ވx6M;uLr%< t?E˜ƨΥ(->NT_{p@ YM^cKl?Ygz-QBx]2 㻏~3;O;BzF޹{^[yW?d~ݗ߹'cmV[?|0wQ4Άgkf|8Rot_I[H>e mM5sBb>Up(7HAݬ܈(C019Tp W2 q}lRoEil0}Y.. |FN|(V{U( rswf V3.[ֽH HTtMR6f&m7Uëd0x14w莦[v?KB:h]*Hxǭ N~iݵBlN wd҈䑢]Jn [+X7n C4~ ¹zǾhu [<51p]UOz&[]="207&0@JcCstGk+x3pC: J7gsPR~nyV7ӬYSK.!U^ տ3]{ \ꍞfIT'w<:%8omsvuz?[mŲ{ &ٍُ^p>Ԡ8@IN݀V68#|#8>ax8/ٳ3|ClB絵>;Udv3=xЌ[5)㑱w{.(bk` + pÞAh[CKrm6PtlOV2O `v. H$yeҲ}?IH߿}]''wЋ\/QM*8Ƌ&rG~g߀|tdmL{k6_?n?pSl8|OIAKnA;A~ ˛)W;'3|q${dHV+1Y s.krC`oC[Bv1E}Y{h3 d{N7OO6!kvYI&?|{aX}efȠpFz7 fcG~ܯ?ڷ8ߎ[:%#(x.Mfk:>jg|V!}7ݗZO :yl*\e6DmBOWfQ?&$?)P%tAXg6lMV68콭JbsXzOJ%?N ,ݖ@Nµ8CGxuG ^! xM%|3wih$#-m&wh{=wkgGPt<|W 2${;lǎ|ۑA}k-,;2\Nmb̕I>S=6O>\ww/~~f;}d1n{v\ޭ ox%Bwd XlAERތ@R2 mP~?: a 8en#V;4_yG y[.x3~])O] sdkl>/(ux H0ot e|#-]8]t[)K$Eã[}<;A"0{9`߈o07@ *[#&Q[)JGkt:+}1:jU,\o?q %I$CvO'jJA.m܃%=8Kn&ؿP!l 숮r*;]gel͇c;||*M` zmEsmd̃G^{4kA+y |䧳B:aL~Mo;5l\eCo [9H)^SyߊH4 |-4r$ietUDՙ^@B~u+LJlj6JFE'sYq1 ,EGt2̩#1]F.v/wgE&vmLO@kKl>M" K/HMѹ  ]/B|lzw3{WGW0WahmօtdWgeaG;(v wo_}Y }dxego D]gwϿ4xLEςS*5XKeҼg t C8?`r£{ʄh/ Ivtm}}nmN.oLx2ॣ#y{\VgBN6AW=Dil"zׂ56yW^]Z=:ѓN#`#8䜠l.֨v&!?qx[/m{?Gmy-n5sO,Ks{V?76 'N B mr!tP-Gg(lpU'DFkk(/6qb<.#mM BO/Oth:z᫴C] :d&|4k{vBI!#pbrrcx0ʪ_{fja]$|g p [_/~Yn|R-o}\ FvMxÿ9q8C¶̿{W=z(qobNw)Y=3~ 06\5@տ޶뀬S7 4->WtSrJ}-€pf[-1oG08l |.PvI%~t[qUš8 ~:;`)'_ސC iLtH!=2 SF|xZ.nU%S3%v%SatKKS` Υ\g`H[reɅ1UC-;(\]`*떎֝s9*Sҥr+{EFN`>g=kOf?>sPFpy[mBt2Nԍtnfè±"B 02-.et5~{vj' 7Hε=&|z3GfQm@0;m)|(V#U{ٕMi}cԥMGG Ly{Y{*GF2n`ք8~ 'z%_ k#ዞlod駕&:pg`44[y߸>lXE=F;W]x8;C V_( qg YY[xA>qUxv/֊w{}Ht-4%3pq?^a9TOUxj.6 @م&lA ;N @h>0UZKwҝmxQ>\v`KZ<>ٯC+|!}uM|~#Ov`/{ӿf"ZnhI? ڣ/Q(7Q?EPO0 |Y PzSimjw|QFO&ot_;9=7[m7/a|]πto>_ނp0Ck4k{dk߯xgjEE >9c{hc/X"JCe&xX>X`S g 4X|1yJ?|c U&*?=kvq|er)golA>? l& lNt"[u>ђ#Gvs8#nz,MlwOݮ'osa4GuLli|[ s IKEOWo娽_t2 edCp N-| &ojh geE}kct=N 3G[ٝ\чOxSOy<ɘϕ=3D#ɣ{ zԫkʮb+v pGrM79(K /;]^;17Y@:7}l’$Ϥdl(8ppm| ׍]S4O؞A]Zvdet_kM$ekbЀhB|,膸2͊.ݬEu'R8ңyHjds[MϱNqK8u h13 +lj}EsVE<L! -rc%i޶Jz^=rQ:}''E3GxdzAAu<x_, r?|4מuVʜNfr&GVXasgt0=+:/x\iKf/.t&DCm~~N O>vynٚaXo3G,4Eݏ˿\8v#G#T }~l`eԿֵV|q r:0qW=?+"e 㩲ѯ#~\ NF uZvb N$.&kr+Zadx{d 4\+z'#OQ|UO;;"@:ç3l⸮ٙq*+g29?d4 _[iFFht᳕}8e?8DRŎ]` zu^:/ Q1:5?0'=d6%! hNF/&  `Wrm<{ms>9} z7^賁7)53Gޠ^?{eqGׄꇑ9YAic vp_l1Y`I0bPd{{zA_~a,+=[r¿7ЩGX}3zڙt@;x ]U҂VMWzV }muf@1hpRi%Pd .4a$}6{egjl<@oϰ ȵ'ktm1]^1'G=oBmA"=]0ě* wZz:lA8~\yu D z` RΕVL'#wڥmyDF>y}~]Ƴ ^g@EKjx5x "sthj4ؖXȓO߿|hvep宼wr7ֽ7[y/(?C9xkc?`\-m{4>MGtU XTbH.tr0U>ٺԹ^yNv2)j`?۠6g&qNJ;w^|\ sg5}d?F^香cGV]rf _I]ݥ+T3%_GՅFen D̮[Xj_e}ziv_Z; uU IUȹAd8= U~27UןWLEGw. 2o>&xV}G?_m@hjYO !p/L,kvBv\ak쿁z&mֱ`:.^fV?m@3{o cpț_rxKnꔿc:\ :k+ &oeyڤ˱: 2ȯhgϫ:t˖(=W ͖|<|=od-,W }lk V= :{Y[W7?F6 ҺfAy&;6+`ha+㋝} 66I}]~~g M/ 7_hg,q_Or8EԘL(˳`mg:|g}աgd۳&W4owX13͂c6fVL O/|u*GM[wmn[jtO&LmlX ޅ/4M 8y@Wx5I迁+Ap+~ֶl_z$\`{yzHP:XʩQ2of_guO& s/{hg|"xshԷ̤|m{ohDXcAw`39cd[at7ϐ%XFGжn[!fAIf\wvTනy풬C!ѳcO>xGq$%Ss:x_}M ;m;F3nKS[%vݠÛL@C>>\6FQ 5c/,^?|jS$܍Bvy | :?"٣]X2]T]9 4z|ō49쿏6O@{z/_ldTw̕u}.\ S1Y]|=x(}^pT36^+=OC$_vUWY sBY3EARxR8tWY?}pp2N)1f00 .Al eնʁ ${܀ ==WX=Aս?YJԏRy. HtyNZ#fH%8^S_@~9iA>VW׶:\`kI]#\g dĸU<#҇z=.~/^C7Ќu'ztj\t"9l*`cW~/* w _8=Wb?"]ɁK<4\ʖެxMrՈOھ[ӇF+ J̦Ý; }<&'CrZ L|q`|`Np+:Mv~dxЗ*{[}r._*;\v_m_VGڑnli' O{ Gae2z^MF jВߪN#t74I{OŽ']x;wqip5V}󃭚ҩ65*#:=u^Tmރ֕5 rl*~ TDF}nT`Qm@p#XO}9Wd}7Ckró~9푇l^u9㞋ͯ> Id5j~QWLXNI>4 u ; Mt̖ZPY}/#m;]M˯o'~] _6d8̣z_[L_◿-h;+b{.]@^}? ܵ5d66;?!)`.ޔ.m)"nTNoxi:k |O[ dfG2!zկ22,PޘV[m22lBgwYcU€Zзoj_i!mUG;iC=քZ酞xpу/ 6^ds-G50ygq37,z!d])gk/K'(.XpVB0端;|Ʒr BTڮL2X'cL[+ͷ*laxp/@Bro4ix3_}J;xxW߲Y* f&?vRvh ϋ7&5؃5ޘzϞT-x[]vOw_?Md V?{{=_fMڰ#O>զ9>ylcZ~Gݧ&ȂݰIsa@:b5/KI$S<82"cS]vHG~ )?[|po `5aЎ1^}_k z>+Kn}`+lB9yL4n@Ruft0}^I_}9(L:ӳkzT+kV. !*\byL}?qm'ӿ9/aAd_0Dw_}RN~+i֓3KY!F[iD ˻7@$:hs}v;o]<,Puwf`6~]wi78E*q9523pst_|}G7GV$zo7*]kkGZzr![Gc{oGJa*1;:ۭˊIlةaE֛(ʣOi>l u~LV@Npp9cm?r(ȫI,^ \@wvesA @tAOGɑh!_a*pZuVc((؊aFgs:Teor^q=n3sXS&R"eNk\O><9{3O &Kآ:~yl g/guƷUx9 ٘']xFh0?V:BdR@ȶc!3o0YA&#w PK@/`.БF_;`'N^ |&#Gխ7|8 ܒ?mg$ykG=m]{k廠VG][ymӘ̦9sc]Gw>l" TUɧWh)oW+}Ll6L"(.JgxS IDAT5U=BEU֖&ِI %:Iw;o`!/o}[u_|S𯷗VgKh[;So _^A_ ϝR'̆ ŸK3mv+U=h[y#m$wi}[EV{‘ܤL0 6Q7'3 x lǾN}6壻lҁjO3pװțhUGȽBm},\A2BkvlS~hSB&}e}[wxwʖ6`? #fc^S<T ;6H[}ɏ.^|UMOdR@:A_:H7 zFgH>ol 4;vX<ξ跏>[~'I`CKFE (IzcɠhBfk8po5ɱWn͙ Y0|N}hۊq ]=]FpNjSlmS6>!v:l r>;ТEvB [[:{)sh7OۭՃwݽ~>9m!& %nꆗٳ_Նx6؂hJ[s.'#B_ڸ MeiʲUK^o -7ߑ0;*&3YUeZom {1Y7}vn@Tg4iG8lmKG?_l>_FL+_Rٽ1 4:OYAZu7AiN|߁6-Nnpfo4ьjQ.m&܀8hrmUdXvf *ǫ߳ =cGA%Xurks'0rQ)?=4``CV_'ޅ>&]6(t(_tr=ULW})>6w];Së@F3H߫C?;08&\veuu7 ikќM{˖kIJà5ph@ Lb;=bPiVF{‘̎)M/@nl=\:omVy2pQGoRnXVuǢg l=^}CkqEA6k uLL7~ $͟4QCnh\ۿVדKL`icJ?05!?ڙ+ܯz\Gp٠m!Q<bp9e`qah `|Tp *gA~+j?{ěz/׹&.m^0[x60HnI\oBiA0*u rDNϙĤ>ݏɻq]^daaSت0Y;+Ĝ W7A &sA3>HcHKV /VڃڄF՟]UDVw$`^K{b.q'5"F\Gٕ۔^}a#b7YaBu9,Sʎvxe=z`G@p<'J.EFIڵLt h5K D&~~Ks?ݨ,] dv-&o[y僅hk\{UT2+';K^=sVFY vuar|5i;Җ];OpDVWv͒M_`y~b#?׽͟F]?*?=-J_W*?_=wΕ=D/ M7 ROp^{O'gGy© u}8 zQ朕1nuVhs+}qNXg#\:37K?;%>߆??jz2Ks}`S ^i?n^88%9O:vk(\ٛ=\r:8ie|P͔~d9v?N{)g况[~rVJʰKl2jx˗ˋO׉ [2To褓3*SԱ)|=qN:vMr~gd0\}]]$orq{oEs+#~z.ͮivtѷ5k;} lN}*ƛ $/ts0f5MaKlN#W_AӹPV~جJgyPx6ɵίѺImz9ƕMpy?рo`?kw$݅6mox8U.@9Cv)tak31K W6 bmkL?mh0 ;m:Z5dGM p4Yum?rsf7G.=^]+ѓ[+(LcNgAA]UV:oUEn/Dڭ0-8Ꞝ TCgBrn۷ {Y;KzG? 8್h cP .'S_qm?Ǯ9cn|[PUi솟2<5{;?{*$@ ˄9 B*[wAs7;ۜ^ffٮmϵA.~}k6ڮw}.{E7~ n|it׫8Ook~86@Ζ -lS13{M66BpqtMٝ6ےdi}?wr̬! d5 z3x]{kk{xPz*= &)B' >ݧʶsk۞K8?mJjқK۸~n>Z:[(҇cnUKTMm58SE6m )V&96N`UyKg"[PS;Ӏ#o8|E;X1Pd+kՍGytyELĻҴYvax'LL 1Uq8 ,:4p`.wUmGO=<.M ^SGFUx8Dtg<9#PcQɧ73,q;86Yy{.۰,qXLwĄ08i0՝OB+`*%ܙ7yޟ9 P=9[ AUFy~X?o9 ճ4܃Z~axr呆|]ј׶/_me 91>֓\*+e &;%l+"ϻa)%_Q.K8*х>^ǐ;z^[YɃ.j:it=}?e30PAWKIr)/یV Gs^=H.3|Kp &Tõ/{/kAZfUw-Vg9p)4:eA[/1y8$?k ` ֹ/tm-l"\6(T'}/֧ltN4ʮ鐍&JȮ0ҐxصYuG-ΖyWtLd`P=kqug"_xcAs, džMFڥ=\= 3qM6uk}Gc;+On> "*V"h>hxPتٍ;Lүڧbm:Ϫ|Ѹ8X5-<,[`\-Aީ`HƬl)v8?OJ9kT݌S qsXY!rMIXOg%ǹ׎{:I|yvK cɁ a(鞹kZ>?Pygm>1w6`ବk?exȱvӎ7s<ǯD*Z[rrXꘀ~PHV*:8~Wcv8g7RxóyS(9T]C0Qp4-zr3kXji+*C==9.NkK5k}s:x`O xE+ wn 69ǁ{zirp͘+w?g#'aK=۫ OAnǕSg/8ytxWƮܯE~(œkU'?E6 =}[+yO{LxϿpX@n]^SeЦ?23X?]EWp=^Ҋ"3+`[09|n6zN Or3sqW3W}!O<NxDfhw| N^:plokf 7,A*߀a&\1/z7x GoϫZt$6qzҷهk5j3cm([O4c@?| Ƨ=aR|۾&@oȴFq^f.z] lyQ_~B>ޔ.]ӂJm^NۏOЦf ֫9|8v Wg|?ڍ|_5\ç9sѶp' ,E<#_:먽dnl*ѽes?<^ѠR+̘O' ~ઔ-Q{o4\߯Apawó"e*{cՂ&|plfkeRO7ݽAr;`Abor<kv y8`EҝͶʳY+{p ޵値c=ϟ?VJ@0|vT{e;OFWGxq9lrw6!{{g !}qՌ!7(0-g&t#/@|oo}W<,: ^RwvE>ymlhG7!/8[.ClHw"z֞3fsyB~F\ ~gZ׈ohiȠ`jis)wDaJMWhlhotݣW5ߊ+f =WO5fw5{З. '*>Ξuky1*ms3}9ܻS/:UWS9Ǡ@+#]ږ{Q3qAt8%]-LG*c<:zKBMp'E.ʎwkp=zASnI?Ysmo kZr`/pth󾡼k:; /4[U٪€Pkߠ~iB>q+9xpOhҌqוKIwgz8Lee@}p1wƃW&-~sC^TO0TJ\Ҵ9+&2nPj76Q2f*tk;6xx/`U^GH*8YjO虬 VQƱkvk?4w-;$aTLkkX\TgCH93~dK^jv+TkxU[˂_G^;^3qf.: ߭^WxVՓ3sf_~|7:vl,W5>bU\CN$z:\sJ go~эr=omf>n|Yr?OdjVG]6#ڟ`8OVYSDom$䜚]mYKϦ*@ӈ~eW T\plvoTf'+Z=+O4vAWO܆kh߇R8ʀ;asAɔH=W!k=cԟ3/Xsz# ifxKW^)Mzr1[:h~WWt|CmILw9p0{ /~akvՄWן@O`ug쬺Kܒ}>rlO?@絕 8=Oѓ`Vv{ͩr0䬉wO|_חN<T2\&vr^+u^5%siSG` ?u "?d8vҧ6cJߨѩ`fxx &G,}gw?If`;Dz٠VBp,4 ɝۗ2p @{UyfDg<`7V'?߫N EڪI< tW=x'/ Iۯ~y\|@LWC'_~w 6*=5 o# XiV_EHAbChxj2?v.#t+2%ҔEZ cF~]Y,,sV],`wߛ_|_]p=+rXpsfγ<|8*0xz!'p]e^琲r~Nn+:`ǡr7R1 dUW?6x-@Q5 |:9zquRﻴ|wIzP wi?]Wԃ6Gomd#o0A#RV5>T^_=meZ1Y'UvQG9L ,c{!ӌ+34]ܿyR6m[By/29>e+7OMpA'{%<`KG wtU=4ó?x^P]W,/puٽсzIePGm/dNhuЧ~@ma'}YE;_[#z%xxsFd_8Ykˈ+.rpsp9.Z#wT (ᬯ8K:R9J(nɳ bF 6 G ˜9X }X4i*|:80p]x+ L7P|yD?»`~=QB;1 Fnx ѽ>UXO݁a@$n`sxS 1VX$(Wg 9V&~snp~!^omZ<)/|WhB` -k#G?gQ w. "*E>I;ޘYZB1p+ ﬘].\Z7+~c;Q|GS~d6~ -9[mA{Vtg[Ug/:5'w=ׯo~o`Π$::5jڹd/~ hّK[ z=`zMh WVO.{͠k6BҬP>"$hڬ:Q^rg07K:J5|tzfHyҶᶠڡ&4cgg|jU) (>{R܃='c01d2:]g@;cGC׭#eVCmNY>ƓZWP he"tgOݡ| :/$C6QAnSejvZ{:>u&AXg_元ջy)-:QdO#tћccԱChN.yezfgl= o~{s7oQu78{г8#MU#DqEp40զ=-mj}Kő/&q NcQƥ@KO] 3 _pø_8 @?6c6 q D(޻ 7˙ٻ-U,ߖ_v짽ߒeBRVu :<'%< Q/(Y+x)<mKYbln0༾)uƜ%Awd|ᨯ^x蘼= ګI~'~qc8t^ z2'kW::ԋ}gz>nʀ>|3(Bz~阶Z#<@yW׵:p\2e:Nṕr}wxtV",P?JU 9vx&}˥x1|s815;3Fq. p~i4a*ԗ}v{u;wt08J 99tv,i~?pg3ձz%'x͂K?: gM&dz2߳=?r__SWsQ-F&"~|}rfq׏Tf2ltIR9L,ԆZAqa&/Ne׳Oי}9`r !^QShc} V nw41fth}t쨾̺&(} ^xn9Wr R FYSs(gSnCicn(@%v= 0&$%q28UoFJ T Ȥk&Aߐg{ `p[{ۅW4K4,o>=-5WO.d:~ 6ld7| =gsmw՗G{ ~)ڬlw{:˥, L(3qg V^3Чb~X{oKl iVxEJ̵fC^|{_}}[6% i?EpnZqOGeu(1nh*) S|2#Yr)] hpݱ%tF۾ [SwVKP`N`Yז]CrW)="3:FxeL:u_* 4jcQ*l2zaxE8dx _cρo Kdog|ⳟ"rR'<%!F?}V]pQg靖\ip O8_w6굲@\ ğ=B6;wy&[K 6U׾`>ro;?Hxuu,+yH]|@4c^HOoy^XC*glǜ |T8e(Lcb<4@Dc8Ϝ9 eڭ &<WeB1FG5u>1ِs9`(VG(;gtNX'̬0'##IOiO{w/J%5 ~;gJ&X}D6'La8Ѵq )X_wٔ ?Or0q3 !qOҤӖ+;p݂XN9uAF`j2:tǷ'rc՞ 8^TnA7CUʯS]j+N;Osrv1 Wf\O gt?wV\DwA%'=vu>v)zAZgް,P,9 _"-;^pls-I\ |c5 +ortGFfv/q|(^,9"=wcAC*vwAZyD5Bt Mu?m:->W O{ute+-g@DZ9xop% )hP1^å̠e(aRAkC6(4t ] tq~zDR_ui|9Z_Y_Y+p_dGuȩxcD=٫fYȷLozHc[IW[˹$&ʣOYa3|/=}{G[mg5y` jt{Is"Wgϡu;׏N'mPNqz.R?`EOZL>y:cǖBנPYa9ΏbN&9._ϩ~͘{='Kk6z]yv.ݶ6B_LU>kА`}?9'Y6:}mg%p "Kfūsb"ޙ]a=+H}Y>Y߯ʷEZ, ۀ-nAG޻g9{:ʫ{|Gh%}hOl[9(m}«?< Rg|$]ߟ]xg|Φ54C>ƴl~|g3Cy< XGnFټ+h>4#7C'_}Ffh 6ܧ dJ;@O41cg7?&7qbY;:#on~Z-]hV?/Ʋ-6AMIvN?ok"x4]' >M7bYlz'ob~zr2&s:~ 0cWVfWc\.gI4P`Z09_^m jJ;K }"n.n#{M*(Q霯l<!HScKµOalߪ̣ ee^~u(gߑ`gV.6T[Ï9顯#&2=.>vG?}W_ pDWp[yP#{"5܁0^kC sT-'G:C?|2H[Ɍߎkp9i2`S<9| Es7|?Xl3O%v{s\ݏ.ŶUNy8??'y3`#N1󣂜ᅦdp 443 OKNml}^>BΗZ@Z<{lƅ=oPet^M'zxxi9iWm/ (Ӧϫ;'Op,}ܬsPeNah/m`E>5sJ 6΀AgvvW zp{>(|e"${W'Į=Xk> :GGrTE?:v,bN> LuxVA: ?f{ی 9ṾjzNlf=`[ 6~?.<Od鞳Fx>:n+WEO aqeI/!뵛R`Ƶ WXN%@ ޮ*W͂b霸j<ڤ{HVe IDAT0C-Y\I;nr`s^yWYr@┆V,.󝠧ޡы9d쓒~36d/xL}hϴrG m3|{ƒۛ_]mԬr4J b@d3r޽}X{; 'a헌^YIǑ:`/MֽN%Ubs-g7`+νGfp.wѳxQ;su#]Ӷ߻r;^?|KJ&3w=S^ghGr_;xd{Ÿu tO_wr7? To?}>|LW/i V|ގ:"x՟7}NUZ|kw.GsG =lJOѥogW߃g#i &ͻpȿbqgIV?lg{sFKw .&S29Ó!_圝\P%) DRgXْ!av_q̙x7!^SQKdcu)?$\k N^|UlvQxK,/TWH/>]|Uo^< `oe1R*aLӬ%lH)LQOł@U%f5:3gx@8?3 8_ɑr\A̓|H./roq—TVٲuy쉺o 9Y0&ԏWhM:crJu=Ǐҧ%ifQ7P :肬lxdU+z8_y[ɲ'#ѵՅ G6:_}ufgAO1/u@e堂 ^00x} ٔzҬ?zrx ƹ9u}:2n &3j(IvYqmx1$L9ƈt̳w<(=3B˱mYEt-ѕ'#MQp !{m~m0g.@O~[uz[dCSOx 5|hPp<2ͼ{A' uml:(h~8a+Cu{$<휏ɹ|oSތ?=|&/mEy#9 8ԅQOf~&DoQw}xJ|>2A:ܜT|3?z@xʟ\}D3~:NPYj`tm%κ4N-~_8m9]ޒXB VŦ@>L;mEy'ңd\9hσ)tcG5#D O]]LF`tΜl|J>ZÉ'%~5 Lpȟ?&o? >z73 6n}mao`A}(xV 鄠fqKf@տ)Ѷz,mkm+ v%9 큸ߞP'E{/nk>kxt£SݽWg˽_k?@d}H 'ƴ>ok^3 4 n{05 T%Ҁ?PEkRgvK'fo7%اc-GKwpf7ҿQ8R1aԘ;C>q83O(횧,pS/2p>-h ƟY'-xkOh= ʛ>*}I</נG|:*XgRQ*l2N7z=v}r*(ҳ:N.<0e@*sFa\rʕKbfL]@UpWW:zPtޑ:?/:)3X9| ^ST|}M1hX2JTY5=V:S9dugMܷfɢgpIFKZ0?=CW[ir] 2tc+~ շ9:CN9 !fGKGyP-7,63y+.eˌU5`*E6xԿ n% YY L?=.mVnFn ^уFTG O=*,[aGkP/Z"+NwFJ$x2F 4`?.7Aګ mϟ }{mpF_8U_%V&ylzg|#%2dl)WAUmٟ99 `wrdU'%38?yW:حZBe?ou2u+˷ zЪzN1]]tqK0y(NLOvTZ*8DAbki]&|GķQNqDgЌY.9ޏm2)mU h^forNѳ>{O{u] ͠% e\{&_^LC@zt,75Iӻ`%~3t1q&pQpHƃLo@B5$8 <ϾxCZ݀e HuD~lJҿW<4[,?}}l Nn 7`ˮw!7]679~Y٤ipuҶ?ӟ5=x0^Ⳳd)8Ge띍g?@tG}ow@w9FiuBۏߣi<   J`pG[Cz:['[5tvyfUDCmY|f%j?}OnZh嵔ݠey,/ TVFv7xddǃ_gt#߈3="1m,$@MfտҕҚ*C.~ʥ:x%z 6[[ e (.lPo0uC.02z' RK'N; \`O:Czͯ~uʣTY</ i$ZUYpxoӀIg`}w+Ox=u=|@w7){{r׀p ߭*.~]{O>JO C?]"F+Q˻mJ ⌧[%:vhy_ý~Y὞ߩ~+g[gAҲ{J} &ǟc sX)3?k3G-/;T8)D=t :Y(`#wLrr΂ *TusF6 3;$97鞃#k>cQ5-1[_.}NNgߠh5B(i}QkuR|yֹ;${#~sv-PO =p/L|ɭd2OW4r,8Q$WxFUi$=Ww-V<}t:_kç:PsQ;Gk@AS =`ep=0~琔ktfWޏG$nj^lw/<(}8 n#3h|Ɠo=_/'CKw?BxPj 0е Ξ]6\~f?Dbɭku5x|'c{HϘ>$z شg/I*OmcɆ߮ίs{wA[VxpxZ%M.^GxvCml+G}MXC)|) L/J|PΛG,8@Xx×_&epDzA?4gח{Zvx_9&LJ.ߜw3~l\HOtw]Y-Q>wTV/^q)w7c:S=#$>g6gIwWx~l&Vy?h]`S"OѥifFz |LēgI0H"ǁvv՟qNN\TaAKks|Cs $G<ԃ<oxEg9g蚽zT^Q]Xn08W١=c%z=5=I[]7_ipj+!% @k!=Zz\[xAE8^`WüYi >(Fa1Ȁ}6 >YghNWVt5AA_!~W8?p\ tacgF>l64Hv}|۽﵀ |gCy3fȸ@ԫ{YH7N*OpYt1rtj|Q}B ѣGZ#;m^9>~k( Hupl '}__pNp%?O݃mdi-䳧tgCmkV1~S}r)wŎnsGE4t@'; |gpGfXb 7=//yW.%&#/r7j\m"}6:]$C. 0\-`(v []Ou)N:DW>7[2l (fFӮ;:%^іu)/'~{Xp-kS 1Oۂ;-x`+ l8NCbs:T='yop8\%_Zyzj]h/V=V%כ}EpKy6n|y]tV1nQ>,d~x?%u1xwzʀ/ ]7 gOPyӎ(S)F o|H}k_#a3n#*%DG9b yM':(s%`q<1%(Ы>uIN-<-(]JvC3^(oS yAP#DZЌߧ?#, Φuoٿ!`'+ܮ ?^<ϻ<#s֞%yQf9.+ :<̎KC$xGNl馄z;%[%x{l *ֱZ-djS-d6X{}7Y+˒+F[,/"o=  6(\ѫ?-+5p>^6-3FKQh@ ӂWyGoD`78]0 U\Η|mms_YPƹ!g5dLt3_|S>Ƹ{|lNY ߎ{7?O[9kAxG>DZ?7KXsƴ6.sβ)W F"}΁4`D]/d%ȁ`p$lKWiկ9;CY6NpIvÇθZ8.縗\Y\[z;oOr-+|||Ff,`3>w g 8>} .v˽xT<`U#[;}$ҍ1,`-3WЅtS>5nH3+xtnRY0]38W1 Oz Tp 9e!fk'g/}ꀊRoMѭ C?kGfpcAڟ[ r~_ZW hV-:<ñi(ؔ]`C1J˵}d%'OW|Ovm[Q:ށ=o+Qnc3'i@ʱ3mH{]قEz/ z7~Fſ{}]  䧇M蕃 操wOU5x`A^kj4*'Hof}M([G`{W!^4tjIJ|;$tߞ7?=;k FF]rյ*;>Eh=lxJzxoPTv| t ~*`ӡl1 \]S9W IDATZOoojS~cz8'nn;s4 |FPd^yyQ^O0v~L+.w^(?}kCxQ!pߕba4 ː/kDoEyʢ;fAϗrWy`&ĵRx;b2sVvvѣCGwuVdZ;qePhaGO+=@爞|ԗ};蛉]0'[w},@ vkS-..Ѷ%,U/+ ӗhyШ~zmf=[4*vW:s#a`f\%9>W]_DwA=uW %6?YFJnգ6ק-E_.{EӲG }}xT>?Û~[,K8㕶Gqp#X[9SN6 `n/9}Uu3 =L t-Nfz\xǯH+_~5X9[pqd{o&|N^ea?.H,Y 4g3o;͈"z<4Qo2ao`a"vB.}m(= ݛ? FTڤeQo7]vhȜMh^PlF\_Gһ{]NC^Ǭ*rny_y:y: m?!~ >x/\5~7$YP Ofnץ\xi R![_`0|kEEg 4Pť1T9+py_* Q8J*v\dU}2Yz\sIJ*{#r?ydҭPW k@'dt)e_&!Ph2ᴍWkϪʹ|=Ʒ=,.pQ9zī.T.Y>忶QpY_] ]f\+gGguOl-|"B{7?K:zdY/T]y㵃 .m6{`/#ʡ7١RN![QuV>|*>"ɚ&9ٸZhεi]`nJڦ/6XeC_h`GW7_`yd[`H5ce^i;+\Z*Yg%U{C_V4T7dr / 'ZM^{3a=O.xnJ+8ɻ<>Q~8X0Yt݊كq 6][WUȅ4>lϵ?xtR d9pRXpswVslVËw߽~\釼3_3?ؒh -϶姝 *8WSfw6L<Սw+p|+m5mX`3dCL>+7XM0_ )6bs$7[F6 2*jI:(7)ͦCN`եW4МrNe|.1ʀWnU lxYƧS&C_(vh `/=}۳z.HG_6+O??x &[➬켷~m׵pKNoMw7 ٭=Tlh@ dGSǽʼ7wV]¿!xɰzށz&5 ol ]Nؚkw%8nkq_,(8Apd [/4Uw3@:0ix`_P58˳ U>ukxnXT];zFMi p@Oum%XG~f?Ү|~l6fJa6tȿAONOFeCUl|p _XB;ʃϼ<ϗx_#ܞ7t(+A?.{Cߤ{B~W)!<:6ǯ)Dަ odz/~Vl_'7=ʻ*Uv XtW2fa"eRqP1_g-KR :,cSyg1ux'PWi׍scԺd.f(s87sv' )۱8<PH/<{ĺ&ЁabgtU'FYY QI1Gte.uU=-mvm]Qx(l3wGx 8E#o@|e4E sWۇڨk ')/ !8:[-ҍtI7h]N÷ĞU%րX.!NzpH? ܻೡPmhKxsl)[BF&)}NW񍳇Ffc)drYԟrG[].I+ nR]׾B9^B4e;gcj>;x"rv)ՙ CӁU߀yh2`@׽FpV)E9ҽmez2[##ﲿ6 O|{z|9#ŒѦLϖ~K!I>pk& Ϟc6Q#hj$;2ɁQO߶n'G0)䏬M zTd<,p/^εB_a@̜0PVi+ , @wLlЗd-XA|ϙx7V';xY!$ lr,Hg|#<keJD<304d{b:r csޫ#?xIGȠ:kWeEc[OG0m(,@MiY'?+MMNOXaIً}MF_ߠoNr/\kVW?e^v#~}_×\UFzofox@-9w-{wz7Dzg`b_ذ9Y8qO7e=jUDսx W/no~JfFxO"w(nK7SU F[@p(ڌ*m lBchuKrS=/E`s?M/Oi}1a3CG]{:ꡇ@Ged~h~T>\.}~z:^@ՠ&]vQ[Ak*zFpX®^pBlTg(esةV*ol`Ovvu9|7 teAv>CcWilP+b~FuHN7ȔşߔR9]ɆV x\Gi bshx>lHkeHz̆hn:YEI|=Y}r&{}RŠK5qYPpmOiz|+V +zkk+%쥂M}ero+˛We i7;-l!= vƬSwH R:)QS~K57` E9\n@A:~{58enD33rtC`j;} Ky_#>)/yd8ioG|UYFx@ q;, eQ6ۦ];7S8 F:RXmڬYP6nc 3+&80|)1t)x،K錑`spRN?z1J45wNmpzto|(![pT *n#W*syGd9eհ#$'h6g`% vHϿӫ>z{?!damW4 bTG7~$OKqL`ZG>#w?sytQݛC2~yu5k{R>8yS|}奝ifUw tg;⡥ #d+]p<"eOӟtS,pqH0X;Y+{ @ ZY*ZɠLw}AƷc =cOڙMcmA2Ǝʫ;m.Cutmϲwpu4#佂92WC&mor6'-?0ƛ gm-;Α}kO!05.64g7<dz~U?>z[sdnpS|0sud94n92υƮյtTte QrfIks8!׏SۻMR;v~1TfHrw?T+T?GF 伞Xu,c0 _d$L@9kel̂;[=~@`07*0GvM7ۤjCmzhƉa6{5+^|DNszado4x)pfOg/팦p@TXG&_| f'lFeb'6[2Nh:D}Rz\ ξފ] @Koom^p83br=ۗ8p%>4h;/]И!>z[ǞL%Y+ljc-3Gc[h^''7ޖ^U^)d`m'd*H6XaԂ A>Y=}@DU{tͺk_,_AVk;nxJPHۮ dzӻ%:Ԏ7W=tqgA]}CkynShZ<Qk[\bBONzx?G{) kHV<+Qď%GW|m"]}g>yvsۦ'?.g*gkkYw8ʬ[uY #m$0=hѠǟ@?hF%FH #$|oխYUYYȈsoYFtXךsc9\לd{[m?=!~|ǩUBOGGu7\OI=r  b,$ef')( ~cz=3 jjDy6;J!ew$Ӳқ_>1Hy AX):C͢$f wS(AKݟ"vXSl@@hr66,sLgc]=$x@#<^,}Anh@@cH嬣G0q@;.`fL k1ct83e8ߌE5)%K8 o46dDSu0* _wu\]~_'@ uqY~o=w1蓜UQ [*%@+ts1UYbg32`O>@vmY?.rQlՄSpovlSO򒤎I@?64|́B 񉬼nA|\b:N|uЎieφwKu];Eumj'GR:9I9;E`3es@DZͯ pL\~ЁZ>vp]۽ ' ":l--&O_:5^>ʎ}W8'^ԯf,OJ_J>q*afݽ~g^۩aG$d\_ IDAT{t \t=~o056{;:n@u3:뿫 Vyfh*`קom|4[s,^5`{?YοC,NxD֧Nv7V4"^lO?pm/nV/+lN`'fmٲi\Wm4foqb  n#fbBwqfM姟z <(voMBՏKpgʭ3CT9}{Kf78݋*Whp.ȏKJCkLAz g2:Dg71%Ũ)-[}a絏oxqF˲t<6nO@hux.Aӧ'[{%~[?zW>ٜy+W=|V~vfh]w8V'^wy~VR`Ն|;Ӏc4COmߎUnNft2R%i߳n@ yÄe&K* ܮ+yet}OmdǓExm|";xPEmP_E3eG]c`W;p#H *o;xǑ|rX,s݉%u_7Xh JxMVտQ/zd~=Z]A7ػx8W*\ oen !q]VC}x]2QA GGд 氫}-:H ze溛bg "|+΀O qI ;RZ#^}tx<],H*_إ}GgU04^h $}gd[6H+;?: ã@ػ7o ~ƗSڎI.ÅK6lV|0N .U:yf}]G͐Nc7gdyR=|A3AU)7zƜH9y2>mUν~ ht,DJ>)8sO?H8Tu@==z@uVF<4"v}2]gsX1]:;҆hM[./ 9jGKZ+ lW邤qJ%Oil϶g9@Q: y9u_@VX( +K7^mM =-,*+fx "G~[<8O[p T:]=It9nll҈Wu3SnIȥ:Cj~JH~/1jdonǫzsoZ[Z^_yT6h*~u ƠhO?5Rj73'=BOcB5`xmtڟ?6 c#Om/ҏ +`G肄 cK )CdYɦ:X =8#YF45J?5S$Kd dN6]?# ؉Y+9U\/#n'ggͰm`_V srOǧqx}=mP`{c߾ǽbG6 l ćw'xtEŽK J'X{I6SKGCM!eKiY ˞ ;+i_{k?Yy~rs'igo~YWzxtx;o|wZṷf{$Mg_xՆ/nف+dI[=ʟ'Ln541tNxJ:6su~UZtLrV|X۾`V/>zSץیlw8o>xF@@uޛ6 q]͡gF]zE1[kB@$br3ur1OJ;lЯ⣝7߬g=|> pBdT9`y܆/boJGx =תt4r#K2G?~ǟv'81gݧcʠ2Vah?ouid3C1ЏG h3ÿnJ'.4  }O'mN_MjV"-̶߭~eg&]<2}7*|9~dHAAѺG{;ӁwIG߳f-vӡ!:n)|\Ow~^!Pȯ|N;.{|]UN f_x<| #jw:ۚ/.VtVDׄ}JzE=%څv䲢,*{/ܪK 9ţ}fk $IjLɬ_lc 1SGbS3ன|hSo .땿i~ {*v"}ЮOU&8m%謿Ժ/Y 'Uc:IV*K;WYa<АX[gA485ղpޝ'UN=:"X6qp 8yBl6CJwEn̸߻I8o <5] Ξ \33~>[2} |7 -U؅|  %wp;7856şG_?|+.TQ]!>hD8up] ( V_L[D͒NB$+4W˒_edQRP?߬FOwjR)B;ȓ?Z <xze 1̖kdGV7Z|Vs"%kf_}YQ_fyp[R]t][}E,lSC/я5Ӆ5 KÐs͡7v ~\6]* -ҭ+V^cη!ٔu$ZU*EYu.)%z f<N|$ *sfy4ZZ:V * :'dFѥ~Չ#ÍHWtmѤHpFO\YbKQ85_{;{jMڝW}1lۧB;uD\D?7vR0v0v1,?i:ޚ] ]2DrG?W+*Ȇ=zYVJ܉DM}g,瞕lmr%^&.8g%G.!~4#եleznسѰ)"zѦl-P$韠`}["MՃ>n?pL:2irHVtI2#.Oo~fĄ|e)ZdߎfڠG#~d m <oK^{{|> Fr \BLyk|O]=*M$C|L?_E8=X1?`rA̶&f?>hO@v6vY.ێ|x;OK؏ZMhJwӷ?/r5"< ׆{#?ͦ |< ޠv=h s_|БY$hb_͌[}0K'Hp]50;̽_+GG09pM7Ba@S ѳ@7/$mvf+Aʬ뻶]OH 7 gUG㏎<{>`Cs;d*f8. J琫3سSK+n|µ;3a}{L k8֑A::luGL: cTV>ogʱU|0~#O g>5_Wfܩmʎ#cZ|< -lcal##_Kdȫ©UtrKG4 ЯX⍁;.&Du]2VRm|7ʳSNOFGֻգ;t)DUpJx|pJ<+ed4*(,pVFǽ['Ӯey:FG t7 xͮ}:A[j M_2:YU !:]hᏺ];x|]B80aM`ׯ Uyw7Of=CYyzPBx 9C 8||b9zVsY%. '?͆=&eGvJu&gUQS^XѦzQg>#!ɠ ĵy,1IP5pב{'}|wͮ,9}uzW9[] %I ǂپSWRlׅnS&|T(Rlqrp$eAg8mi˨1n1Ч${Iq?^l94ͯߔxzm/Jȟl6z>y/Nrg4e>ӱY#m&3XІT.tm_@%Ł v^#$2C%z $~?{fyz6{+O[%f6: @>zJݷ,?yqgfN_;|MF/^ M쯃`-IO߹ĵXf| fg7x ~ D cxv=]Y#z,U.>:@, Q; 1k8VjxS&}ϏVVҧhcgpc쫟"Ao}o'GmBj#xd:~(GW(Yo屢nj4agwrRv+;$£=rѤ{aߪ ~ 3燺U35tbvM_jq2 Y:gw9VOv]u4# .wX{g"2 ߮m68V|_&g6OS IDATƶ|"?mp[]=Y_k3<9<߆ *x`O;:*^5,`3ԈS~INq(e%,Yqx;Pv]{sH͑P`,?~umWSZ]p{%ioLgHfGeW^mNyN׺̵K]i~< HepPUmf ̋ @S ԕ:q)3*5܏ތ E19e\0YlOYч}2XꐁUSSM)L.h>|]{ӖpXpAnKz+#59+&:葘22=|I!'ʐx pK&d%{[,]u={k_kĸйA(qeAAhʁ%}cB.x3n_`.YZyeVf\ ^7 SpDUnAl??yO$_# L^kvy|t_ !\ AQ bZ}4$O;Sގ7劯t( G<~H; " Kxr/9J6sՒ ]Yl1w|ŅpWL!I\Ro]ƇYy2܀> >i9xUÓ)K>TO^Zȇn#L/^|d} RxNI_*[k}'b`ɐ C Spgw0_o݊>'`0ZGtш7\D~@ w̉ W/}3c:eǖrlfUX{|<~U[x߷6d εaS争#jWO2@x|l2y>Wlb9P~}C֗As|~v0Sc7N~oꧣmrc:?qgt9Gd>˪`Gѧ/g*nїn#8>3Bϣ⏽q: gz|/[>k>o'{@ʂ'13 1Bvd崴?k=bڌLNQ^FY F!rBj$ ނ{*.93K7K_8rvW[0'[ ѭ9'ȝ3b qP n4?73f6M>)%{^):܇d!+#mɫktaK~Xpl0&$r .xT76 VN lݲW z XbOvO8^ jCu#쳡}@/㗺[rF 'KĦ'l'_?l3KʃɦPqx,IǪ?Ֆ$?k@cկl,=7uIߑNf<\ތ z]пXx??.b$YpM:!be}ѱsV #{ t z$A9ɩp7K(ԓt/Sy{5 ǵudwL6 \:x+0JAaKk خ;lϮ[a3qA /oگZ?) 0~鹁[*mc3==m?; hS$ӗ^mo\}]c3ؗ˲e:$OSBlL H^nJlL*=;Z6|H76^pDsYmK2%KZ%fvMfzl#&6A޾ֶr#$Z0_~>~n X_k@$[jd&fgr[>d VDL`{ɖ{.\}vSv:#u n~р;[xWѳ`~glES:biqçzp^o^ǃ1[c~ f`䞿@+/oL ʟ\|훽M`wpT- WbxOo}p-_~1=6|Ma^*,}Mo|nWDro(@x~|И3~ (:@ss.ZFu#7j$ p9&X%S1U7؂#p ׶MI0߂$/[B͖hWu mVm;pd_B)؅7ڻp=wxwʞy/_#G7#mG;)!ƣ`Lyt.aŷX|6WKa\ȫ"#+xm)IǗ9+-/ <)`o|=-ɼ B`KPOg TD2F tfyI*aPm5:xD{o wg* =ZxgM;eo1φ Fd%{v_$/'ËfyV:w7<}GkwJRt[2xl.m9d\{xF>'V--.^2 -_oOho~Yo:G;CZx|x $` d`\+G`jA=pC0+ഔz7^z*sVwu'X8ىE|'% v6 ưڮls\ fʃ7:=6xQӥ}ѧՓK}|[}%d=ڰ>/}Of >~5%OÓ[>GUcl ȯ D'\B =gS]<5X56oZStUh~bͳ<G '@ H=o]o'&-/ίf[ t9z1(A?vXrN!7 pc |^1G)$`xt2Qt52wkKݰ$ۢ|%tQ zL|V;do~Ʈ컁 ^$01(Vqm؉Gr@gVu dyD&3fN;>|Q‡M˭װ t⯕Nger3  Dx/{bUH쥠=RW?ߠC: _~~ ?|fP/Λdte7$ ?u˱zn!3v}o_v@ l le櫒hR:$ӡd#I_&Czѓg6te O\0Y8)eA|p_.F5pV0[G<1oPȼj;SzzάN/9D&eSx+6^l81p~K=AxAI:w᪽QWߵ=v;JGս30:՛nܟs7gn~Oŧ lWNkDڨá8g6 ģB[$ L66 %P޹r3ڴQ u.K+ĹB3%T;G/9uD2 [; D(:{?ݽ&83ѧ:6 dy,S/zf~1YHnM0>q`xSr:8uLW1hW5ܷA5}x(I+Nr0.Fi? 6ECW>>xP~&!,4i6>^Vnrtḳ;ý`IpﳤZgj_p~{?E^fc%Nр lY@#;4U?|J zmwg{C,).DCug~+^yRwgkKbAdFZ`<%G5F:GMtdfa$K^mCH2{tpK&ެ4C'f 7Et`PO~>I2 }p\}U6x+.gCyz׷)f0-nMLsg N4x@!o{_@̿3Bgk^ 7A1u.O0=)W.w0~_ǻd]z,3&dc{iyoSߴe9|uꏟ{_`o L;|lpxɏn^~]܇ɖ?~N_}tm]'!F;?H}JQYީ=z.>ouCVD9eVoI `y\#(~=lA }5@#%$h\p+ Iuon|3\w GΣߗwpb"rKW.f.ʒ"eK|B:!@7;UkE.&ݩ\t[vjW)`ExL9/|K#]77?|vd|~IϽ.k(Ͳk`|[#O/oKo ׮ -̋ee[9 ;d=iT>j`eK䈑 goVNx+ k'U$ku4`ST 0%ij:=F/jÙ uXAhW%P8FEwdWΠ@dF G{5h)˭uțdM7{a{g{sjzH< fUƎtwZg IDATd|ww({MVυA5Aßg2ӏ*6Q[k+&8g@#%؇6ģpF\Eh%f6JOw 5>nE ۪#Gl@9ݩ<>=`n)ȵg8?:gÓ2:9Ug_2:&+ /XOscK*^WM3.-㟼pY>$b^xKt$d :Gh2GŞU B2j73ŧґ/~3[[O%{No]'` X4|3]3+qS^%f&%}v6`9%`0;l29m$cgrKV~g{++MF H{.:AOW4:z֠~VС#P@__{tNov}W㱷,D AZ$Zz2Up\)YWȹ -fDccEmڪ5~p(hX?# X4-fN7>@`Gn茾6{T 1m!6XWu=ɩF!Xm66= Gҵ%9]/O8Z#=aV 4mODk$n 3(e"7\P\eZ߾"-K߫l YO w6927>µBߤV,l @U`j2H{j٪'xݓY'>#xGgx<\N -h۾l V7IF.z)S .?MC7xJh2Q7^w_W~-"鱊?iSnn~'OcQ"qHNK D/Qwq4n a5QGq\դ_8 r=FΩ :+Kobp\pHD%L֡]*o 8-^:_WF`@ݿj/Zeӊ.3*(ItRF?h_ P~Ew9H|h%SSHqO0 7xWxvV$c;J:1s箣lwrZYUlwզ^Σ<팞^xg{ib8<=\^#z{;~l 2,_p^i}|NÞ}9~܂l0#%|\想17_|Q aY R6+`[|4d|T|~㽞WMp~݂D̺^2(1hpvB)]Yߖw8H=*ޡf{§&lCI_ P_qOIٖ[0يJ$b fK^Zaݡ!XZy烡[79^ ʱp۳C^G^ߗ6/ژt~ЏF*t5A{48wٳp]P}G bxU_p5 MbxH0 nq2oVay蒬)w^OOZ⢕O]{Klno)=꿿7էcq9<*=Z ֳlo+s * uzDJ'%)jvXMGD׬JoW_ $8ݸ$耄:!!1ԍ[m9g}|,7,Sʸ77pP-f%ɭzE!vPy3[hnj6 tyvr."o}\h`2 e}mGE{Z ~4جkں Vv`{$zf]_7Yƺ|gD;AJ5@Q 7tqtSµz~__okkZ@#9G#];_abJNͮP} %1[yx. Ǟ>Q9qn7;Gu_k-| 3W:;8Ζ&v Į]`?/(]~mq1p:u2Q 0zϮԧm<\bFǙo EC=lM ǂ3x^h|uy't0:A;VV2VN K-8}&c:W"s.D߷6Ԙ`oy綍4^uL;eypgcu 3#"! buڕZ ۂ{_ l8lx~I*Dhp5ҝpF?})+6&՛gc}VzcE0>kLG? $xOJ Gv<{mɦQxĠ71H0fb>ED#;.l'i/% ]W[#G?ȉn{ΦTg\H6 \Lo!;Wu9# f  v1\^~K[:]AX[(aG= x0>x}ɿ=O ;|*}S5)-Yye`mN ޖOWq;߇t] 34Wnux)H?f˭zZ6MCc,Ep]Q~% {>`؝uzֿg[ Xxc9GRbٻ`*xN5097xƋ|e90yʮW'tpFFW3y_߲ !ןJ{2^]z)ߜ ho.xM|n>{)}r h y&K3wڱΐPl?4c KxAƟsmkG(*p>䖆FfבLa<:W#kd?nn0XVk MtxϭCeƵu6-4h;s]Mo~ha3;[b/ f V k~F.ir?=_N4fom6cvc_"V l}5VQ+EIgS~&V2`gl2 |ځ~)]| dM<~}8X讌[2U `~~D?ty-~wݣ6[ub;d&në#Nv\'%~Z`䛍< %<"iCy]o>V~|f@wC;_@Ew$4 IWe ÐvbD5fxpak-vђݯD.7k8`SP֖6L`SniI$͒o#77h w2a-ݗ)펋b rЋ?20_ŻFw13x@[Oߌ Yڷҧ^,c %DG9hQߒx\MHV'I&x>:ã2>Z@~b sc;1Ȼ结0'Am #!6 Hse&O'!gю Nah |r zO[#=৛mscs]s@.?=77cUޟ J'e fpѥcϱ7LͯZ}Ռ},}'-)fur,ȁ!`8 ܿK}K>W\fp~@K:ًzuD>Ɗ`H6j Yrx2bk:f6S0b'ώ.~@+|pp<2xUh62Tpǒ>LUѪQ6ɕɒivVz|~>h#{ Pm*xu^q&cImטW1wn`n:?}?po.3ÞWC SR~ o|~>^st"@7UVbe{銾^ǧ-;˴ߠU}v_UG6Qp"aO}?“^ :y} aX#~  Mӧr7%ȳԖv^Z&&{ӣYU_A $~{6M܂Y .oFV˯oP*.~3ľ!JH`nئj vh3c^@ژc0??m~{U2_ər]fnmwlƦD_, ;ӿ .5=)~<9(H+ Ѓn.~`DD#sJWFp8%woe {F?<ţ=Xx0!TLgx~on@2{[|VYt~dL%%镪\Il16bo!{G[Sϝ?z dL?hz ~[~E}oS9|Uc&9ʺLKp&So >䴪c8=F } ?NHw-..6>*[xhmo=`H$11l.wNp7 BP/A;$b3_K_8bwS>c .nل`O'! 'XNt 0Ǘw0<}6Ⅴ:k?(yQ07l#s^< q{*z`R)Gd9FkJUA r>m!H3?Qp.~n5lHl`=-^3~c8:1D$){bu/1Zv D$GNs[oiJ+;<3Dn8ʝ_ZɊmG_=`']pߐ;./Tp9GX=k?|2ejӞd W߿\xD+ŝ%3 rt, 㻀Q> @,ӗ7] $_yڀ ~^x,k v;-cY P+\N 2!/~pBSl: 6*kҤ^\,!+ ZF,{SU6;=K0Yg=T BCusH2LՃ/KfɥM)w2z`OlSpW nƺȉ^umtkƦkEyTmUK3^CgpX>["o%\,sNj}~${vN䦣7e &9uNlUz]23RK>R8hV\3 ɞktdJ;KoͲh< [ &s{o}r嗕k>I+t+)]Q!>_tDmp|%ly}2o$UlM 90"^lcU2lpoս]{VdWt޽D_Ư?,7h؛3Ay6^yy~ӑU_4vdzV9wτR d[+OA'4%]#! `%6衍we7]xc SgUAhUR7dV=~Z̲7C (~eH)R䋼] wK_7?ാoBL@!`8!$%1$O#hW+$54"[N6( ;8LqĔw 85ENAdq(jT[Qc\fKFWW)ҥ _o?wo>o}٦70x?V0`f.rF.?H)>4CBh5gkN@d ?z Т3S+էS~V$/xcH^ J} wtۡ}`K]([2Ht.AWgioVbm zfu Z`[7.|;kAuͼ?ֶh:z V&Yhđ;hچvokg77{mrhصz_yŃFxNЌeC!\+xn0~4D,w]O3ækhŧS._ Cp@}v YM5x-{0@&Dx㎃~*Y0rx%O~'׮m# ~FFW^#?8hd({4!Vt`sH07@_@ 7<;܌f?*b߭3ӱhC]+1 nV*O-؟dAֳm 봣.QږJjg]2PL-8eéYp  fN SǗ$lc C+4sT{SȦ$ӗ`#;}|)KݓD,UX`9f27}3l3h1?8+:6:/x_F%%H6{wz ǒpq7^lKܨ 0`A|7HqXIPgdU ?q,g G.}P^A>m;G&' K:&u:>}4 \ɔvNhpp<̿50Ϛ/u(~Wɨz|F ܓ@O{JW: JūIgXXaf;#)lڥD{fKVǠn[3Y>5H x+0!NWٿ7o>nI:|޸>>iY0ɛ?Oho7;R#G%Qodr:f!Y7ߴg7Ϳ߬Y۾wgϮsҔ&EVր'# qi}aQd4p3ݭqO Vls}Q 9OGzdgpmWIT/x lN^ ?gU?N'sEd|ǜemV}g"v^6L-sy!rtY7+[6dr؄Kǟ+a{vOvd^EMJDk`Ku/n0Yp7^yޣ5i_~.|pWwLnA1 +wʆgN0Ζk;^wGV=y4dWtׂ LD&fJɓD[h%2k;O7\riwG"8/;'E%J^WԫM 40?u|^{٢a~{-^coz~9|~`+t޽Uu9 {=po3aٽɀ3SF{m2[U{1 ]޶QC,$GK $HV`W +;%&Q CTGRsFm ߰iBOwize[7NJ{_FcLL~Dž<=WNFOqxdrt^ٞd,_v80X-UQ^d76A6|`EOZx* bl-CO~V5>Gcv,µg]G dć3Gmح pq08+pJ]%qxҶNʻ;.0]冩rNe~(l#JyT~ꀅotS*W?վѵpj~H. 6x3J8e ݿg\ԃ{w++n>9[Gwݻ/?2{\jNxl}?}oW[rL+dh7#t/l*Y ~%#; DC8@qe/쐾n7§~'~_ j2PQ?߀p[KΟIBZ٥EƯrbp '=tg,ibى>U4*tsjqΉɗG[8@5=6^39m?)@v{tWJ#^lz .Em '9i{h+}ۻ{f2YmG4r|7:}WAQhn#lus6whC^嫎/]; Va;sَ|Ϋ^ r&5O>n'@?h{m.]!௵_>x3|e+#VaayF4_MAB<~/~y.$sz~A_xHN& 뻶`R9 oh1ɛM챮K^+ȸ+rd}=a`MTW0mF -&-fKv#?h~6f`|c9tG*wD(fvsX=rN&TldAG?M^zٛhSOtoSOɹrgNѽXӆ3YVB(w9=-&sHG܏&+>Z[6ր0[0ad1F[_vqHD5}J)vpr~! íaBz &j[Pb[YqP A[) <ӜQF`f?"G̀[z3N 5R  S8أ08E|Л&ݿf8I'ǿOP.$i`&>쀣?T&sȴ B-L>`pqՠ42: ɬ HX;{O#Y( WxxUn@u{ :Y`cupC Uѧ#oglYG!2:rpn0><hnLAT7[(.;j9 ϐ ڢ{FUw %<-iƾzz*,dĭTl?m@ tEM/^x ɣuz=_Wnm}zM$zxxؿdZ@|J'Ԃ,(?ڷ?Ϯw8VMu8;m=Ru-;ޒ"ߊ R:Mo2.&[m׍Wz{߹{&1 m.zl5 G>hJ9!d9-l_E ZӏIoBaڤAniڧ ^Ud|}chb'U TyV.2±`_ts٪3):Bo]ht[j/h=HkřDNk| 摟V߽/4N,#KTha*6̫)]o6Zas#*LW6@ZF~vs ^~jCߪ|ce$B{_w#N5 )۾v۝3!Xӱ`|JwнzHv1vI|Aa1`}eh? lURrO$O3&٫&^, d@] A7[w?+6[}tY|LV&_͗gイNމ,t|Ix75BdzNG]C[tIz!GPU: >>;s|gzeo>k< ð=xw+D?GeWy$f^.9p:|ȳwGtVꏴ._'GfO* [\E2gr@0 Bum`>C]wR.WN`kYMaTjO?5{7اU1y{:qzgfw-umva. o{H3H#Gce2W*J_Wݿ"ogu7@/r+NL98}N}&EΛrVMRș#uJT:Xn IDATv Nb9ٟJF|ѥy8gV󓏎]p pCmZNFLvb*[`s`"=(cgpL[Yρbj-WN=_[m E^B %'qe[9Rk&{U/} JLί#;2gu~V8Uy0g\`ȟ|ccmEv`u o;uaIN?: `?ܶVE3HJ#䡝 _&ԇ絀qڠ+sJ[_Tb'gm`Yf)}='ZY2d+ Lv%F lMXZRc>ޗ,.? 3?~f¸^o0Y5N/ |yyΣ)  8w3|{Lˏ |o03`OAv@T@8gՓ^Cdyӭ;VvxhV#ΡuOM$f;CW@~ywh5i-Yk>)G=#Ar` Y/kgr,#4{T`Uߖ;WZr{7/=FNʮ]&"+mۭ  a; lWNgvh,vj&5;G/c8֯SW~kt-]Ud>G_lpz?+)͆XOvJg+'Ope'W@}v]V+o*MK; v_{աU&Sll@*.M[uwk:{X7ojn wyId?о$["ynel7k7ފfڐC"Z5 ЏѠA^ k,>lZG%c8ɧ$,&ങe ֆ~'w|֤ZӴGK{vTʼn<6l 'ܮC>Xmch.MY;ٿ3;tұɭ _~4ت Nf십'~<)~3:blcS]~u `eȋf .-:!F7;\`S 8!q;-tS#g}}tǍjW-X7"\ _툏 |!ѩ˸(eRmWuMg-|2͂ג~8;H"Ua܈PF(Z~LT#JO#J¹z10:[#`&g 2ׅ9zӡ[3(=0.r^w.zVr[U-r97M~k+*3>/^g˞ wט #ﺽ|}?'=l5Kal/Z}uCARͰnFM~aq]qDh?h0k[7ᙽ W0̇qHI8s3ym޶fo, 9Ҫ0`T&g+Fk5xdꌖ~ɇd4n]ݎN4;mBuHǩshcd;lQom=#G._εC3 {7skJ5|cG-t}^/| ^osw[!e#AP*GF#nx#uʯ~Kc734>L1 زMq2uDƧջ0y_!h^ͦmauƇ:,[DdѶ ;`/MxcC˾vctChTn{&Vo$MAxGY7g-x*eh:"Ѥaw[V!,(Sv|98gsz3Ѵ(Ԋ:`v P)6TKhɰz_aÕD{ pd, yͳ/жŕoPxޱ>]BYe(K2#'yV&USp}/) {W;L>/sn lrnj/m՟ۚـ/|  A>xOV'N?x6A_>v]‚{)@/顶 Ab 8&Vd[q`qr-yn/sJ}^='.xhs ?ş4*gt{zn>;PjǾ..[q g@#6y)UYW>#wfi/M_cɚh3"]c^LZr7&{ѳ&)߈zoL. UOϾ+hi'GihePlFKMo^+g{bb.xެ@0G2}Y'[,C`#C bLh7]yU>W½z V#\hwlÛP]|T0Yծܩ\lu8>y?x'd]<& UU7μ2/z=])?<ڄ|Dv6Qxio?vs'd vEw MUle&BW_BɈY~ <k9SL*^k"{p5&T{G,Dd;bg]O1w6M kBE*r?푇~2 pc;x%{ ^? 9h}Gn42g.棻t;|I`(E< wѪN LV2#..b D#VVb5Pܬ/UZyy Ƞ8 5S@9A([q{ޑOr+Zپz@ 9 &w ?{|߿y[}omyo!箷 刟fmZLNF;AzOQ*|8d]G9}NƗ_cNGk rk^ai+ld]' >=)opNxMSV|&@n7} g!?5fg9ˋp,x-u4gáMfxsWy4ʻdtd]bloU50$ t,`]V_Ș%|׶/0&aI~ 6-4ȁ,,W+۷{=|+\[Yׯh~UDXvh *#mm€4 ڦ;⫿6. L/P;X0/\ÇIotm?UT챑'^s;6x)4T@Go>ðgÁDdڿࠧ%& 5~$]q{QzxM4j$ڔ~9ҖX2Kޒv>: &gQ W֟@5xgCRm2(:ӂ%8& s{=u`/\nWhʽ՟߂7޼{.+MEeJqIx65ÏrkctU锩Bz}jG$I [\kS?eѫ 9Zjj61l2?hĕ1 ~c,nalEٖx09~oOk"K }[1hEfx!mAvǒE:}Yp~Y Rewn.Vg7Gmӑ>/3ѸDl~˾v]W|Y>G#950:u] 3Z|gs#XyMO7iRǟ^K_Z;k&b_8}; oлq;99|HJ7>vLӛxd[TNrso7?; 7&\ ,[}I0>iRavk?_>YmGǖ:'_6Y5oE?&q@FѝAMY`OM(5C-V0oGsx< Vm~QTO!::\~;M\1u)qVqF1W?r?>=?ww'~'??'}p߿wo{Vn:4s:9[hNv2ÿ|үK%OݗkA=^=72R`$=1qIC݋FnG e䍶=+#GOL|)AWG [ /R`IVi|[f+.60꺥u+7{LˣSꟲ|AGu?NwXt;,uLXLn}Ge+uϪy9[=6[[Qg6iQAd~wMo至 ȅ>3s00 al'~ 827C_pMGND߮e SE|؎;ץ|/k$kY oo9讲ڭ1!j`xv報 Pmd4m 44]Hk3x &8i7FGA%۸ 2'|&orY{'C?ԝ0=഼`Bdy5MG ޥEr _y4+~$9s-e>T5^[ ]nl ʄ[ ۄ߄iW&nϺȰ7뵌*s D%qʽuDw%I": mO~ P~ 4] %Ѝx9Viٳ[p ,,mA{\vvxfO&:.r~ ^AAꞤ~ $ep>Yu68x8J*.%;e9F oӗ6 پCTpdT 939\ O·^ v6Sqqq,z67~n;Tw^Lj/U`B#@I/}Cϰ)M>^z> S@Y 宽M*;]vpb3/gṖl`t wd7;JDdfB8-vH'e[[kVq1|u4ӣul:nsAۅؒ m#Y `ؔ}[lfv[;&6VndplE. 3ZJp7F" [I?V-$ʈ^J/kSpΊ$9G_/Zuk}o7)`F'cX~o zaaIl8f=s۲<3ѽ?MQ' uy%'0YZ|sV^ѻ3~rvVVaKh@ 7Z++&oݟY_F 0IrO?L`u*Wmm;\݄Gt&WSAkyh:CwWr2V6-V;d\+Z\RN6NF5P/j%|.+%=߽| f u IyiLhK5pea&+'yݷ<ے?9SϵW^ s6wQ_gl/τ@ Zp .sPmV-;ҵXu«7Ϡ@KSmx۽gqd՟,M][x* FWs2la-o#țLTDdt&|N(VM&ft>IqZ]6jRﴺQo>g]f+du?{Յb5on&K3~&CWi(;˙uO*}+WSSoFûi{N{{u o6f{'?~_w~Q{ЙXQɿ"Ҧ?2{5ɀ*t0̔;+:`'pҽtՔ{6ϡh@YMIg`l Q. z0焾tfl+F9#: ovV x g9BWn}AGMN.7[6gxdΤ˜ Ѝdrd-`6'!8lR pv.6׻سieËKvO:Nh9ʐW|K&!p*[?wTd xy/$ϛX)~{TDW D/8l:;ːo T9ѤSV?3-/ɁY}QӡG;;ˑP"e7*þ>oWV'<\Wf`#WuXWL'_@@}ecs'@3P.KMz xYZgU;T"Yv`Z%x?L9Wz_~N#G^lڵ2!g7[@A5S75'gM{ԣ=MA~Ob%hvlwk4w d oGEmL_Zk~2C''}پԂ!uV׊l_`6혀JqR0omgb=b( pW?o:D䛜ɾB<kuzJ3(O"lG5Pg L'`F'x{˿̣At )3/;5kYsj;;ڳ -o~eoiժhRlo4PqVǕA|%U@QVˏځTq 0*gd6Q-x9{pAAk؅|V5bmN=`<JD$[Dl%;aKG'@b696@,x6Ie566i;=m:_'_4b@fI 44').> Y4o` Bq7GȻ  됀yfoDa9Р<.ݡ?CuɅ*C*G~EVF;-؁w>D[F hih)o5T}~5[F#"cJvw}󱾕]oOdd}kuOwܨH&=5zg6PHYڄ}=TdZZ]4p}ùszy |SxQ`UY_}C_2 e@b,ẄtSX-H0E{[?7?cL1CIne&[?tBOCFKF߂90@HsCt #. Qo"wûx~i^O~bTuSqr)w?_ӟ,8?ݻ/kӟOD=j'wo?ޫ wP??7Gzx$ɑL &ߟ⢑LVNhcGFJ{9 &wι N~ī|UVH_x Rrs~ ' 07N½7.@2f{~Z9LNf\Ѱz%\p7ϑ#El}Tpz]ڶ#aS:h22 &ⵟt0{5{;Hgo5ݞɭ# g  * ,λœnY|[Pm `*4tMN}&8`p W~2%:3{I`,J# ]c ;t07rK^4@V2`,d?mp&~ oG[9ңDg6H ̐&ҶZz18|Wr/n:s~60 <q&jBHP_X&/=dZ0^> n`Dl3Em%b{7ηdk9_^U&%U쭻 ;;רg= ֢lByFxB,`I+O\a< aaW_z7rW?n|J۫Jo(=[']S:M xd`mN,_|AzD{Y V^~ Vy k {; i\Fv^JIyNU#MY|F^#\_~?u5a~s=*.xk;>E"|78LF&_$FhO xWz|:ؒtR[ԞM*<7#:@`[}l`<~%{5xj_t5{m^N~~&PQ`g@1*} ;oUen1&N f4Y'M_r{i=/ʊLic 'N%r F#ú5EÛY a_F2x7L(_ f2(L+6m #-nbJ#x"95p7Ov&&?ٛpuQ&3WOyЇX?vW8iݳ)/N$ Z,n߹{q1B'=x{wDto/svwd[o:cIkw:|ɴ.?lǷ>>v| F_'8!.'zndpɈ*Ы{<{~|aáL7ÅW{?W?  ':M0!g-o~$^,|Sy/ɫ}ح?g~\Y_+gL?_+i''GoI0Jʦwr8-dFMʝU :m65g,V:lApM.4ܮn]c:VʰͬQNͩwPށAyº.,Ic0Ɏ,ýws>]R#ɻ V3(Vrks@ZQ~r,lM5BFG>c}styK`|%?Vg+T7^j_E<ӱ/b{E~r"_aRS=v ժ'_kխv)hGv+9ZrO\~JG7_RVAyᅝw0_Rg3 ?x겥U#|Dk{6?\Xy+ D wyev}xNfuM~Ovx~A~Ϯ>Dk`l?85NLes/#`")YnAh ,&LD[0Oz\&!V\k@g`pGo_t"ur݄@Mn$p$G0xfwt܁=lIk.0vKw_:3E rU,O{N/;%&#ϵʾN/Va(M嶂5yzծGw~.DI=WC37o7h#dD;ͦt2OcMNSoDR*uCL"~ٳ_;R|/óIh遢و/&'GYi='p&緣`8] mݫ>Ə7? +îOZ9vY8`̣.a1 -?&*z3zK *Ӂ>M zA+]I9iRoH>*zI7*ե÷jeW ~*veE葘vaFH2dښ^k#wvDݻ߷e _cm+Y$sDy2v>s$ V>)Ǯn.g.ӽH7܄kdoqFy&u}$?3])h ݣ'_)W`(ɊMoh||GG̈d|ydDptIt4)Ko.^3|p?߀=ѓ[?Itߣ m]UzMjK]i.VO/o+V:1l^yE38aa~w1,S  2`op|4sJ"+Lw'A*m0(U֖?Fe.ه_w+{mdۻ~(CJv 2m5>pY%_tN-#P ǽȟn/vNB񝀟Π%9@ius 9)t]_t.ٽUdA&(`Nm238;u__V:;SwE߭> ou)|g%-x꾖!PMqѐV)2%Hڤ Bto0={6 nk ٺ tlxH?oYǀíq&)1ҟd0H2oV9c<1:R>$C@Yf6_7suPz\sv{#mp=Rr^DDlt]OvtD ms_4p"IeGt.w p`8o ۝_Nz+`E|H]\ N8 ?-(g}Ío8g-`&6x]Aޛy4#h+ 아Y![Mغ&*ǯ%4 6@.]5Ak45TܵJ.py;puدc/\6Q2@B`eAvqg+MVsesA]_t#75C<`FɡBv@{>ա nr.j?{ R鴓ã@E5W~~w݄X'o%Ny_ NkkcgIwV[` i|ڬ X)v3pb=? f㑼Ai߰{\cVK9@oV7+ xgeo󠁦-ۖGK `>:OsINgt d; Fɜ0PwCy" YA~~a~LO6xl:tD>u A&g+ftڷI `m#ޢP+=XBv G߁>`&"b7Av?|Q*}>A$VvPzg 7 #ޙ| ` ]`\8G|%u_]מ٫ $fLJ!rMҁ۽M.K&>ڢˮW(oc`4)7p$3vW;}Xkm`k}  k)΃\v|_~nN3/|r||xl-{-m&7 V8g᳴8]&*_H.v6r!|poemO]Wٵpڶ{R]|BiPQ|mV?A jj:ꏶOh5$1Y{3uv[99 ྋnu:>Vᒖsi. f=xI w~Qۅˤ&rc>y"dr6 tBdPAKnlo1v~ȃChO;%[AGg ܭdbtB^~hIYŊU> IDATwz%.Z5G?-T6OVѲ d96Hdf[WGWMԥ8y,) ?6ӇK;Sgo3hđACoooc廒%yHFɦkAUNt.+lDz]u^nlӒ_V.8~B]޶(ANOzV DPN>(evFxƟ.z],hz *H[MсoSڂ"YONQ~~U@ -xfd?DwzjYܣ#`Bi{[S=} ֦O{I_6ydgrRlNƎM4g'>&wPć;R@\˂+/nUl/9+Ή79ߪ<=PY4!FT/rߙ!-z܄m?6WG[An fˉX:O{';&4%%~|o7x6]mO?ݭmMvX<&߃i)=33󣣝`@n^WgۤԗI@ lnҋ0;gfLBm-mumٍAV9j=Al2Ms/2i U]yn6s6LkvobU.ߵŌ~G EGfmQsL&O}>QM}Im[;-vK^O6Fc3*Oڳ"HɲoylcVtUy1TVom_[~=X'6-  ` l`p^Ov{#i+M6}1/2F3=Y4KǻUee& xđIGa:⮳~f@upѭw/srtCh\?fG Nk^-/K9DʪL7v0  ?=^سrOWYQv8?&G]QymuMk(m@l6XIm{ek+xS`\#Eli7DzOBָ&+dPJ7;#dFg9: +&Chlsɧ_Q2x/JkF^|L6`?\Lp1]x=;խ*8bl8J(~_ rozkU* -DZ,@ԗO فAV+ '-N?k;=(&]:V еAڿ>U193Kv<|8v U9ݝɲ} +Fϲl+iٱvjĘŦDB#e / {Զ|; 50N"…}TkK:ao{v_LGFOHЅ &}O7e\@|C >i"@jKȹe`!W03nt{(D巵<`70ZouwL %Q7ݲixUh{l._ʜj#zDJ3µ-dh9Lr vIVՔlgӋ9|o{">H'ׯoַDVw:|ml|Em5ye]x;#-ߙvn84)6uYGw>Y ;Dl`v&&%OG|`a*~(d8:խ*p/?7|ݩ}_+]9PtUwW}E誌 tGT8 %p>C  :z`Nr'C}z9AcޗnX>BߨbriVsh)c]]]@)<>`p̪]7bìTu=pT>ye/_#ۋ8]`|5d5{ߩE C}^T = 8X:8<ݲ iFE:}Tk!D0w kt%kˏ?/Rz&\PE ;0]f ȣ2Š$Gϐ ]cׂ}+^?~dt{\V6!A](l| fɦvk ѵUB~:#kb :k}0=wnJ:؆BG]Ev2t:M=o[{M6)&sGʾ{$K@N~^7{.I-=ڢʽ7wjhI'76yY_k؞i{dA갧cwp}vp'7iz8s0,$XM khȰؒ[fpCmn0$d |pvAiy莤ux7d. x=i.m|# uȗ0qycD-t^|<;m!~Q=KjkdM.ߓ};AvfLJM]^ud̛o߽ߗLl vy&2Bk#렳7 rզ9;|KO.VѦAmzo;#FYCv).zY)-ɂYd;I],MߌS05G{@jq)kF~r/Afi[ڦ 绲k@z2[crU Efnعĕb">O/[6?}/~lp#١!Z6q.=ef". }2T >ytMT~w虡"oW=ox~2?>,Q2J.KDm7m7 ; rHT;{ʄQNdgː[tW^q=#bSF%60aJ.m}ksщG<|e m AvDm`\6`-p }_cU@kF/ClWx = }fui /%}C]|+9rwŰ`2XL}39D(oze{-c?@U{3MTdgsKWϤdo8kC{=h]2n1:w1 2PlZ.Ž"Y9֣ 幨Ik MHp< *+m*)hPeWԳzvk .%=ZTҺۖo6Ѫa )G7cWѽ2\xWqr D0&`TO3YQ 6$=?QOc뫠͌FV-`2 OMFm≣;1j8y3b`< /:d3c\2#8ϨrU~yy8#~Wz4z9X\h C۾U0=]R#\Ǥ]s `nγhC7iG7X<9_ mp9ʳc-C<l}o/PL->)Y}5w~C~XfŔ=WTg8d2;z&G팡>G# oR6C~.4' @r¿9wy5Fۺr39~[iڶӦ'Hh)L=_o[u.Gy1]=G.r;H/,zF4.=|炣>47(tCpNtmwq,NCm%ͯuHH>o''NIW~h0;"%]`nSѥ1zQk7ʩ2?=VMʨ3@8&p:SmC;Bwxݗث ־U^~7Z g/CpZ8Tǭѫ>30zAǓO}x>y`ks66>vw鴥|>>hK(wil]l #:5,N: eX/yIG}ﺾossBc"6 @E`$+PȨRET*)%rS,TRPL$y繜3ډ^{y ޕ\)j) }tUNt:Ysrz699LrxYpN`~ -=Xq7-/,v~fWx?aJ?/RSjk5m w6{sapثHXHl YѲWzɃߜڏ(ɽ?+8XtY Ix O]h%>[[陸qr11$l;ouͩ93˷WGûٶ}f՛V >VMbJ2 .Tiێ',]ܠ@4@f3_o<(8*;gQ@ f ^JV?/|9t^WljO>iLv*o@j;~\py,~4V(oČ7^=@SysK|4C&ڧK>\ F%bO_.EYͿ >zɀs MO4tt?JsV@Ot< ӵ=hU~G^po _wΦx̀#?Pg[ "h9:`dhU#3pfʕQ1t9]T\jc]<OkxYA:h\m[tP!NOй b|.Q]UYCoSm3n'8[1ԳɣO牏\~40r%(=|Pl߷ 0T>|xo{p4zz]y8xB|א}|0?K('{&##jGӟ<_\<4 FsIbJGFGF9*3r{:U|:ZtL{-&}:Ϙ#3vwd>s|Wz`('|Il6P zuS^t=҂R#s'4%gghZG!3l8Îq~ۀ:iGm9ixN?6*&؆NGuS^(9 _̾19bO`ȣ{ "14[tE>G-gyg{t胻e-WM/ʠodt )\A?~79x Vmz3lV@L6/8(.C>ϻe|[`w-$Sч#-h~~{%- rkʬwyvp3<ړd4w>'[lp )_>o>|⧄PA+VnFzIx2(L{ i0"g~9[ޮ*fG͛`Y[S%v (`7 m7_70o@\|N5DGr퍁(|QdszY5%ﻞg<cCu܀""YG R: 8 mO)^F]:ΕO(Y&&|mI?-)ݕ^!NE! 6ZNS TH`:J<(1y0O0@&_e8&U^2*heYFW%zVdwӥ%t6G^u:AʯK4 y_uZ&W6TB6 mIC?|39@l |='tkA;cb[a޾\bp]W;)5 ~4CLOeQ|?UkG[ eWV?ؠq-֡Bl␰dd؇{m9ٳ&o 2[CBmȑMҧ9] G4܀mS(͒1|G ~L/^hfl1ʵס{v@g:Fϵlc0iuFr^3gwY-&يv[=%6b*hH~YuXݺ٧WЁ"|WW϶ʳ ~pw U(;˕vD3b`R;¹]qli>:8{ P`W08d(Գs/׹M1o? (+3NiiKxяC{ JGȎ'o1w{ɫs\ ҍz'gѨ3lV|r#4ۺ[gmoyã-lN! d{p%m%sxgcDн6)og2pV`iNks_{wdL`t3G|3ϣ½彽N9 .8?/@#ӈc3lH}Vl>܌#2M̻m!Q^=vh Miˏ }iyO[͘ m#kYpO}[4ygً/Kk4&Aw}@Zۗ)lG6`c!Dkۤ/xlмdMـfsg&EWVJDy'"{lA\e%0-ޥ^XeCGxɞw;վ\3.liu' O T]ۑ Ыbk#" /:^" PƄ[,3`Sn_芗GYT~kS͖x'@I\=x#'~M6]ˣ?vhoE}+<􂱠଒ ?0{ +$<pQv ժ^+OۣOVz^{~ɏҟ}h tTs9R/r[ѱ\2:l钼FsqWx0\=]nNjpx)5~э ։7:\>lЏS`_s;< 3c΂gE2?FxupP_/v~0Xk(~ʼh*}rbWOg0@ޣ|$W4;w`W&TzOm ʟd' ŷ̜ZP0N*"y L$a@QJO{Y_e &6Lʽ,]-oX830 o[t>2mo7(/U?gEO<.>4ʗMf4Gp}(o=*/n9o}&^4`?h=S*7Ļo`G~Nx\ &4 BRh}|^); : vg F;7c^J 9y+8\tm#C~ZL?R uprԹNߌ| Fonysx[[,VDoUA[1Iz[V˱k{ۢ黖WN5ز-3/-g&Nl;ܙ^GSTN*]}}1 Sn>1AəONjVZ>Oߠ~#oŃAi2kv{_~{|6 Gez震:l !zͬ[o94v>;13sxʣ,:\RVwra2Yj`@iĭHFڻnm*ʂ63gmk7x%aVrV;/~hŢ+s:@r@(ҌɵNN]> ubt U~NXʮ)s\{u1&a.:823@Ȋ<_AW<˿o˿Ogo]~Oi˗_=Rќh&xA_ƹ85D\V~rXA3|;_oW/!hyL>U9lo!w c#U<7,F~gxݠoςq r6Yi;oZyU WEi~/lT`8ZfK+]JٕGؔ ~df2aoy*ıZGl?W(ឌ^N—vؕΟy|>oud =zpo٨uL\ЯAWʵ1^fn/v Hί'Y ?st VAdv}^\s 4oS0=ՒzI.˿cu@|f O rl?v""9S}+ـu t.y+r͇?8VpγdCBC/!@~Ay'?Lv Dd#?\6|'~M}V~yQd@<Fm@zg3GF|U<_m0Ak п*mpdѽ+` OSeytUtj{vK<3|o}!q(ELw/3 >~R=|! !ky׽J ' ]+|UriaW1A1ci_앇 .oe_lMϧ&k*4.}_z 싟!C85Ǿ7k_] XI`H_e&'y3mP&)){+1d3b'\˽d2ȭƺvC۪׵ 1˟UAY_l>xm60;WLK|vD4Thߵm={kLJ7>G_;Gq2tMxQjT29r#OaCt΁#$x5u&hLpSû ~D -<~?CEX|Ñ֨o;oߞ~xyݗ/:VO.~O|O|u7_}~ʡ>|\^)|_zx_w?k/~彍^W/_? ~k~./|c߸|W?x;ԏ̟/}|?_w~ï_sj^ˇ>_ =/?헿>0{.c2[Ct:gq]I;\}gN>Εԇdo<쳎&ѫ7{}[ZYJUvܳe;zUp8hud"=%'t{$xyy4=KF'ȓC]y6k4*f7t4:V.l@爔p/xKffF>Z߃8yBS ^ 0OɳKUnג*5" }ń7VX#-1 ]z+w~3;PC7G>=&+VT-my奙MNʷ p'!~P=1W~Ax'k6+h%a2鳙Wx]_)^w@nE%۾Lwد%+{rѺp|o ;6ITW{+<+)7XG_|:Iouv#+M #ál7]VgrvWѩc`y>W>a=a~{^e^GXf/x)m Thl pҏ:̝)2gdGMN SP|fU|(`+ih]l\PGއx[:J͜Ae aG,ۊ_JK Xp*OZVy͌#t|g S,t> Yەf<~%ٖBQ\!|-,Ћ`*my fI}xDE}Bt>H l})k.7?Jr/[[dMm Ȳhhu0q~}  tgŊB=ZCM>{>w[Apdl?xf{{B+uҳ u:]{yRy%y~kKF)nf[Pȩ&.OWY_vIl@L<=4oX>b{kOփиY?9&@I SOLd>̲1}` =ȫ c_}IB|f|.} %2{|LIGhe(9OF=B'_ gLso4>O#W/߅&S| ـ{ σrx-@ag6m>jyΫVe#'hW"0@*㤥#;<{wP)!2NaLڜ8'gF:_+ P 3E+^,N;aIJ"g_too?W5S.\~ݿ-zt}?_~7}_Up_cF?I?]7]S|Oɗ_ _^lD9|ݏ ȿ{?/?gO/?u_M?gDkΑJޏo|w]{7]/^_/s_//gGaKv˟/`3RO:<Ӂ{: ƴ͐w_39:UV^uՉ 0Rw!8ў3n軟u0aUph\#bx` 2yȅdCdɡ_ɕ-wpK;Su7&p Sݸ O?1&A VޕopLn?DHGeAڕ+H_FW#$2O1ٽOgKʹ;_"_3FD) Q}'pӇ|rX5JV!:{t2& IDATf๖oB?>m3+H Fq35ا߹JԈ/]MvmظFKps+sf Wl9U>i[CG[^ JO} sED:. 7|;-]O7h:xx>Q9uy<~@v}ǫ{GFNuM# Y: 쒧Ysy=/ߋ7Zɢ䣓LjPMp'>" xFJfY}a0M!y۷WCZuuw@G̤˞Ӗ%u/_Yc+Swx ^$J,ȏ&ؗ7d)1˯luIKVOR8hҍNm}y :G7 VJ&!IAV4Q1u;/`GWՇmǧav֊e4z6KǻBVK{/O)@#V\1`7_]Fu2:<8Q[ K5dhUgTtxd>Ud+&nӂ|mNmч;sbllBU ,K`ߧQ>z.u8:B p*bϟ~n$bBc {905MbC~n͑ot׿x̪ y&{({dtfRe=Dp _g#X/rP.o~a2^?C?E%OK['hˣƖdV78G6XgСfo3 u@t |󝹣|'AmV% ^n&.kL|߇h1ВȩeLogүz`¯^mtHVܛ]J+N7%]Q)1```=oVûl/3 vN,!=qً`Eo;+oʵ<{`>>}\qQR:T?h܀D>!o01 Rnd'oGV|`z,G7T+w8DApC{N̟/`_ jܑ/oP| dW PxЀ\Y h`An >i[^>>'~Р'=\ѯ}pĩm/n?82B ]_kzC_tI'h7P,i| ]g/񳶸fx[/7E*g pE<И`!` xF `̡ rJ?k٨|dWN/~x\>ɯ~hh@#.Ͻr`|٧?˛=O}\>Ofɹ]dV9q~嫾c+w\_ nF=m _9Frc@hJfw\oAM3NcL# n8oh|];{7E-ot󆥲r13ɟ,lty`I,ovMjl>U.<唣+nĴκv#w{> '+~8Q' L$couGdTw^ȶujdyvl]f-Ռ D@pp,&ݸe|S"9cKFד)O0bNc{~˴S%ci?ʣhrwG>>+ΰ.1Uث IӺR2ldz& @3B٬pE0m \` 4[-m+'ȷ2WVy[ m=[] |jn>IWoda|= z1)tfz(^C360Ozz$ka1Ap, -6 ;<|DW0Z|pX«]=sVf4&x\TwMs}3\ɟ]/w6[]v v>I\AsM#Ht4XW]>[oJN|]3~Zώ>zG[(5T*I#`S"&q쥜|^N:VXUG9=netx*Nm0")1y:%!s~f|5\gPk|y~}Uu8%~η@w*cTz[J?>*=Wq|,'5[:y秅. ]iuwsC]$ >*j4W34¿F!yQyu蓽g DV/oZ7w;@o2FƗPY{ri3kNGOrԑ0cJ8{կLէ ::xa)0(#|4qt}3%B[h!*fAu]~}/X 5x`(>?{ "Ub:B#nO .!=kֿ|_&<4 Er/+ԀEa})uy8Ա2}SaH*;e;)_ 8O@6u]MV={`I |}}|lǀAoordedY?c[@߅6xl^W>7|(eYOCw|<_s c^}eTH׿} 5nM*f,nGۡO!(}._2p7˷|oϿ\S|m ?Ͽӷ+?~\f^1_i4sm4`oyso7|G^_?~y=Z)?|NK?W.7_q'cϼ?'.?gݰ훜֑"]tdcJGiaX^OG'7cZcF`tc{u nflyU38ӀAO烣9O>6 @=|W#[}YV> <}^|5Go6s["o96!X5d];:pA`ժ3crO0FN |-LMˇV\^="32fu9|I-mdzDneAⶼx飴3k5<`v=sn=&-oo$kױH;$Ҧ4d6Y-T@KXIi\}+ܶR`v7L5ryN ~*nmνN}rb .[$#U= m4wߓ=+-li I>wO&W+.|(IDqmK/X[TR ~Vǔ,/ ߣG]S7k\NX }[NN߀x7Jm-wt~q>6>[zjW>}+9Ey?k͸i閈[`l0i:}W@lo|9X .!{w,vP&PGo?G/Z{1zCg ZKp&˵3Y<춢fbowG)3@sfP+Sh FalWϷ<G`]tB[^jKŖ76{KU\[m1jաnFZpaԋ+/n8$xT7so. 0KЈ+v{}>ؠEˀ7\Kۓf(oՕ:weAf .N8xtٗ)8%#H8Ù~[|CQ3ʀ?yE?͊vQ,2)-hy6MKN?:׆N?5pg|TbWpg[Y25Mwأod-k7C/dDʍp_򲂵@<\UhI: 2׾.wlڟutʌ>s(catj# kֵ N?yg>t0W!ygT01nAs\o5\]~կQ#C|7_{_//o?Gˇ??XmFa^ac|?.D?y+{|[~˷]ۓ6MV5';j9\'hС4K;QI{$%YAهF7 DuN*~VCM7u:{6 6iHZ0ƞM@J2GN PrT`Gu5Hy44X}٪: {?\?ҀƑ]^y&Ovd/'ݐIv| ~yNۅfCy[ev>9װ^O'0zd G2޽YVza0z%'$zi[A+L(oc"fg&{uŃ>zU#_C+|>|g?omV(  D`fgFlX̡,^5ґ+$cIѼSfnbZg0J=@̠:N;BmVf/,(JlJ6)qmwyGvtdѬs3r|hw'- <Тq)%$\DSxVU8(=XY \;GʘSgކs:4~tJ,=) 6k l2ku^MWzopcـNdGc\V# :WjmM&Oĝs Z)^,W=#,OϪk{UQ@yWlٸcfVO}U"/]<[dV{>A]:{*wn5J +Ց tsl&[ ؟w2c]j^~eAjcM~};. 4 ^r|zWfg!eWz&rg<D<&/%ͶH>2Ӭ)6;Y`0B`_=ї.~ #K2cIytfo`bD޶@e%b+Rš_)2ÅƧ~O7bLe+ [_[GflꅁV}y''S6ymuAVx_f眊}=X,Fg};Oȁou'_"]:{WUzsҵ + 4~VOk.˷p<+aఀ퉙V,#/Pݪdtt͙6]|;u"qScR!um88p$ꧾg%싡qB~'xOvf0z>Qꚡluíi#V/xUꇠ^ߝg>2>).G69ǀ.0 `0,svs+ 2S[vɎ(Vi7;_cp)'7tnZ画ݓM/M` iN;T{[Nuy~_3 d=oF\`mL8mW(#R3i(`pƄQ!2O)PD)9U4 Ca3U` muUDC}sBݖG{>Go|yjs:~_^?9Xk_~oW'ğϓHP|u8 gFpn '/}A E'o*rhGk>../}8f@t|`#sJ`$1P2J$:2c ,B.Y=z^ÖlrF?}f(3\x/yp)xX>\NJW{8c z.(c ^H^ُ D]mr&ꃒ`)L챟iZ'ȿNp2tHfݫt'ǩq.Ϝgp0xEh>FARv|1 '-X:nFGxt̖bv]앇m:g_tuįʟApMsAձ7? %ϵ'`ã{4 Mtw^};9E;NosZcz{t\{жWЄOI(k٨ٌs,+^0wom2t:6M :Vd>4/;}7> N>Q78k+9x}: ^wwvq+6:G VAr6om'Oa |G?v~O3qd9.(gzyA'pIu;b.5"c@`FI]]WzUgwd#ͪu;r{2BR|Ò ]fhG@7CG?~yΗN1,8:8d@F_6tbe8(ɋl^hO|tXBNH>Aa:O;@Awv0/۠ZNk8g@_^5a T q"F}B~ S:PԻꕕ/o1W2Y*譮~=j CqmoUhM^7l6MU{izz+`GV^ 1~k"`?-Yv"r3lQ];l\ ~o2eѾWd)cnzb#˥Cy6C>8ti2t@.MwgGVHضmW"&p l޺êB!8&y^4LeIbd5{W[j3ll{г)T 2\V+l{@Egw7h7;?iO>n= =~;[*h;Y!E F"c2c"YI>ty gS ? 6k|[^[`y jyh㽺q|˗.)=ӽm\'hŠ!\۹ ]/Y_M!ڝ#3p59Qr|*Ε5Q3k-:3ðL4I9u.4b"\W)[zkg G懏H<*1'lV_K4%iPCMh-:Li<( ùD>򏕣2{?&s|5 wV)xlfP+ςƇL7^nr%_t:&O Dkiѹ}[ãeNd`(5:L0g;vm挈wE}}hSZ`0A~ttQvfFf` laNrG:HLKwn!S:էp t,u 묲є:%Kߌ.g]=2Yx<5x(q'0˳פ&A|腇DluA z~j ( 9m8v_ /f[vk\3޷4'IssJ8!:Ԯ>%d}³Yk, dN>_筄wF-蛬>i`I>PxBw`{{O `|eu4Lz'7^!d@F_΢YZgڏd@HG@lfd:nV"|;|w*ټ[猼 .S?L:R^J'((L" )?OWM럅Q7Gυ#[;vd",#J޾L%*VlY㲵1 r^!gB#gףs^OF.. |-ޖ̒>K^7V*XVoW}cJ ΀KVj&og%-G?=iSPVEC'o! IKGuھ\ i ?/fboI-4qtw׽O*R?G sAa -JOp "[CR \k9j,A_88@X (`3AGSu,~W?~H¨ӡgfQXf4 h4 zѷѠr壜~TIՑFGK>0pek|y: u:!*Ot-df赏iLNC͡k Oҡ'ot#[tsdWJy?p:FF #sJ5& ʡ>J<\6aY;8eV2^SȄ7&v 28u`yK﮼|[n{o>s`ߙ`tH/@tv:vt6] 4Ww1q}ql6xҹܷdqxrl*C}`Nyxd{~8;z@qj-lsٕ*WVO>j'尺c2+ϖtd9(Wtnump4vɂ'hg7W ^=O}?uA!޽Ȟc5MfG\˭rϢan_Jn=;_eG@}BPw 肓-f{l A+緀n[>o" {nSmv|][v2F7Fᙲ"?ief6c[^#_'|ص|1)j< jG%vYˋf(XTKDwkgg4v#z\(`"v&:/mLÇ.o.m[P-]^i>[ [y[llDpg#7|o@n{3g+e!pN,*B[g%dJ2)$Pޡ}[ѢNL8҃rbM!|hz ƽRG*keG g[ +ϝI\r1 IDATVqm#8t-;O׾E`8t0=L{x2X`D"fGpW]|7`-:T 6ǟ-fӶrzjh}Bc+ *&mn&6g3]F;Q%lJ*>"ח;i]?I^E8=[0Ua19Y+™:Z?}o09ӡz\b~PudЀgA pfkۀ8r͡W>S.=vN6*]*{0NΡP>ZvE67K&2#O xhACv xt|v3Jc&jgV 54;.Ng[Kq_Pm:Idq=u) uxV*;s/Nd %ӜN @xpѝoԛ8pUoמ d \Y'ٖS }~ɍKXӍ>s Y9툧'{ BOW71kxθCQ&VPb~1v̕/ / ;lÀO߮ ^7k ~ ᶢ{]y[}qPWte/~ъ:RkrU#sdXXM!9??:1HZxW /Vr8҃zSG?A:?p9c@g!? r<4|5:ߣC7:?Ǜt:O SS?tVbQM5l0zOgᆇn]ubס~xIt5_yu<)(~%YFKuӵîWNݻ:Ge[:bBhwv]qZM>)mP_PYwf~ ^Pl&QSip=mUƮ leL%|8tKp폟.\LG|QWlA/=6(^`gfw;W&~/#jࡸ79tMO0$h> ,Bzup6xȆt`uγ^I`tf7ث3"GuʣvitܳuJ-A*g}.?ib Hi-'n8]i/Mp}`IoŴn =>8'SMT^{VM[(;ʔ 6YY(Wx<_2xלּnqXC<}FN:coS35ѯw=0\һspp(,r_&Leu{= ``.Vg+{ԡ3~wv.Y6pC>nP6(yE6t{!v?gQpj6xS8+Xa&ű_42.:V?cA8=lL*=X6t։ސt97gPl5pv ,hD'vT9}E:b&`(fIt+E_5Yju|ױ :uی69IJTlx> "NNCc86'aF\ @,EΎQqݱNV7-vwROGa+3 W#:Ng63)'ʌ!) >֭ɈO~=0xų nv5R&:j ;=U4gsw9ٿ)u7:6\hѪ¯<W>r>rW}ou֝':97rJy4Du{}s<19S 8$OoGW0>|G2:gюTv5ؓ??{>[(HEVəyT.قr%yt&{ oE~c3h+,lN&N.OLյP_qC8>|7Q32+]/. ؠ}Շ=._y>wlC3g pP&}d.-&vhGwE[oa#~BAAmHtoNlć3=D{u\߲6|3[L"َtLu I JxU7^}.46ppB=vWeL-N^%gmi&oڌpD?}3b蛶wۧډrNnE>ɾFfՑS9bGZ sq[ lSW(K& K_lNT{D^dtoa./٠z ֦U(]ɱʖhio6 OVV[gvHur <_ui=fy:(Gޖ uWt͋^  ?D.@XxZ& |l`@Nي7il7Ңv!x#j{_xӶ{Y1م鮽?Ł *G:v EycQϾߦ4T? .9U[lW1>q$gM>~p}\4Q2=\_l Rw~;fo=|qa 1)\J y~iF}')Fko'nt1h53bO>nP~VA 6f@))7LT[bF8l&!խvP⃢ýoeg %X'K0=o4s:B?eomeت~%nAyyDJ>y?^b`:dsMWv&{.抅ǹJ,ZɴcΘg?TK6:<b'/MT5 M0 ٭K/h4'Y6h}⟾zt&;&~w_MKTS^^ =08Ym3v{TM?yk*EL#N=fv.\̡|+ tW*K̾‹#w` ߠM'ymŃ0b,3:gh5c:5V=:;!` ӳm9u}lށ wuЃ4?h#Yt]#xuxt)곺@;:ϞWg$g"><.};^G}8`,zP:}Wڄ am=Vґ3KD*Nug{`թt  \s(t]} _~{ܤ\[;t7򜳣tOtN$2x>۳2.BҷrC7߼}y?lΔtVbKU>f@Dq+?g5ÓgOvίf@t7?u `<3~HU"@ ʏle /+pX=gۊ>/+kìbUjҺvM̎W*2I1|a<}b+u&y1F?lc>^~8Vt_J{m㟾x>Dೈ^~׿5˕ {V|=~9s  +%wХ{>~f>i3o8hoҀDmF5y<bTeM{ϊoaqϮcqC m]c3+N6xubT6@tW L7ٲ 7b7ak[.;6k;6lqN]0qL]Q&&99zED&QgUlq$ZS_+_I¤x%M [ 2Ozމ]YB*>OdU8 h/ڙ5?hVMx8=UX ttr|6^ţ 52h9w{{[؝өm/9D> ~(ƙ[>><'ne otV=ݪ{,Z]+zN7%+Mt'g]綢d1  ꙾,9q|z_NsmmiDtAU$|qɣ".U{!-t*b-gEQfOV,OWGxiut_Ïo~[!`c g #m0}8»:WK(M_^:A;8P=hK}2dsl?sh= z[e$ >z hwwI|:N\M <45iU&LGo{v5NUIGn9}>-Wӯ7m!Oy盘g2\ @xӹg G;Gjb&s-zoOE/ Jyhvԟk@gCv?YAQv%Ŕ7)űg&g;{|aLDv85xHE:8}bdI4NڤVɉ]~MF'~P쑃_n7ya=Њ$ J˧{_0Pga$>V<.EVdPXRxq}-ډc'ڨGVp1/+&᛾RAgÄ|,}](]'꿸X:8{i =)7ANMhW,xu^nc >7H>Xy^l}9#Ymoc/(tIGYS v ߣDMX{ڜHU׷8I:QWL9=xƉtuU+XZ&O`sʪ[w,KDWxr?}[֑~:]::2Vw*ߵ99.L}|eJ_i:h| BˈaP/-&=a)Pga$E&~`^Xg*O k$g1˵+-OR7M˲GefӇ+̐"罔d%o"';F\ l@'O{=DUyTWm~~UțB,i>aOZ;tėe ~`"e+ŀHHґJ~|9>vF4>> _!|َ-\?3l_ \xҩ6A=ӞZp\хH>@&te"c[gMB_ 2=4-p[/Nnz;#mG*D[n}8WPIb|Ξs/ߴ&/Aҿ1<>`B?L^x1 !CvG5 /:!~ }YN:,nn6ݛƏWH6&U[yR<JDYw%@x=Fl1%bzx'ż]]OJ!Iqp.s)C^s6d/K~[N+klMfpB)/u'-?G&4\^ "y ~lCh}tt[Vd^2Py>j\Lo7&xL8x_͙dw$ dlv @POwJN;߳>AZ+a]rx: Rv(t rxz;xdD:ӯ$^Uhʞ J?r~7qnFܔ&Od0߉yC= Kc[; E%}=w`&0Y[zVѕ>9byVB8=㓓}|^ _u<θ?R2(Lҹ{z[ "ƀ!mnu};l*ůĄhةO؝X_N겼Sz|yT+W{ iW<'9 ~ҟ lpm0c6߳s@fJ ?[i+pPdmPB?t^t=z:M漭M?g0 w[$S4 XGv*:U,SpJ؆ә'4RڠItt_/OItb8~G||.](N,.D_ P孈Xvf,Cܳ>^e/*<{c N@}|P_;֧.2F EЭU[u $/q஗ LO=yO du,|5߄ɖqt|E!Ŷ$x:tj|g 5W PON* 5^WاH/UnB# |bqtyTeK>).4fm_CW:29Vz^G?:Q><ߙ~R nJŃ`T|C/K-lI nHJlDDz |8H;$qT3W'kޗ}f@<ӂc63VK ɧկRs {/ xNz;|@z,ƣf|BQƒ_6~hү]^FѠq|؍W?ʁCx;?5=7yTʧ>nѹ o6M_vܱ BM"y}XTo ?lvVٱ SR ~̰kxBN@w"P҆ܪ `-'|5|t+V6,(5+V`"AOZ0<UpS ]!g+y{GGqVF+ 9ʛ\˯t[~ɨwܥ/myIәHUgB"pCG\ѽtU/0 F&łS +Ⱦg.}+\y܏џ/4B_ǍU C<[1YT \T ;anT_+ՀzPRbBa%wHZVu3 eNE# gv,>49~{#߃VFu tW?=%\u\^(㉑x-s-#DI&cb<]gp`gp*FwԻr W}6:hqXrS>tT$LG}{]M/}T 3خ|M|뭣e;I<tm,~&n*\x/S9h5݀;8+~9$ZXí re>w[ynY6ơIW(̾/|l#V@@MSҊ}uVw+c%5Mae:xr%)OП:xb*?xqow[=&wiI3'kzzlhG&3[5byVƒLzXGKeu 66vSh yt4y3_pK: &IN'-%~4W.^.Q|+ { 76l͊GV6iörie)̀Q_(a0 d57"ߦcuKOs#PnV/ p/g J =OC"JI=4't!? xդ3:Q4_b@Ll;:>r?||jB8g =/ܯx۠;hxZ w_Q x;ܣMet9ev{4$?yg"t^S5o&wv%aI&~7cg&H?s)gE>Zͷv1eYuVv] z;b?M!䀿'|7zۺ5nM hEOK1xŷw_Ȝ+W{gMs@ jz0Yj{xG/)*Gp.p,&i5.$1VߩWg =;g ?%x@|xLRA?վw^s"߄YŹadܤ*a`̒1&U TӤa\:~ΝU(Eä/%o?}rڞEOY3_lnu-$Gii PkkS^|ն~|nIjѿ.i[_(kL ځd]O y?^}m ?ٴߏ;:BE *>,<:*w:51_9a&X%X<.[ X֌Fq{} P9kd:Y4roÅRO{Qm;Y@b $y ttFĢx Dr?ݗ#S1YAtwEGgZK뼢τ]wLιƋA[#6J;=}@vE*d[tD7Pz xϬ@-_#sa#8ĮSA,On]ޗm$4nJ球(OWgcᤣe >PBŮGG<١?ؼ4 r 쟺áRkt]:FKSpu`[˛7\rͽnn78OzaRpλ9vpNWW99;UI (6pT_xo_+",.h,5d#gNjX5 }@J>m[@r* g`lLW!.qs<ݻ:J3^Lkap۟2tr n>ׄo>.%8rݲlDyFѣOxy-S]:w7۞weY։ǖ¦}{hcC5UI%n:RJ$_uՏ;i:;GTLܶ2{6/S`LKl+_$Xy: ^TD(&uvDxx m?(Gbv]'&<~tW\}\/>K:a8'g.u2ՙr)4sY$ݯ<:*u<:pQto(DQ#MrEGɦ[}DQǒ! N77`'/ z&e׀A\} i6s?6m?8N}E/kpgf8!:WGYBMBڂ罟5nbOb +cǃ9$ 2ǫ᷶CjRdI7 _Xz@x`ù2o{t ]1ۗ{yϜg?qhA;"DE//Roi>3!ԙv3dsz0w+[I$_;W1'և&?&^hʻZ22S:*shy6wOG9R2ʄcغ}T`v?/&_mbyg]E=ްUjH1-#dH a8l)g.N^c qp]wn+2D|$^.gDNwY'OBCqJ'F!.rk}kC~BBzٯ|p MfKΐ\}Mc11~ϥEdXJ82' <"q=+1;>:"=\t1yˈ6;N >t7AT2">-vU^s%\^w%< qIO7ɑ _Ku:VڞpdcҤTI {} `4Lh]K^} uCIbvBgq ~x1^L$Ӷ0#9-"6ۤ8S}{w}o}u{[9~u:^g?nBTq;lIq>rO`VGI@LdtN^g5&6`obm}בgU|/ݠ|r#S2 F[|.Iu? tؙ;QrN |ev(R)U{'qoq =" ~Ahٗ&4c+W89j>m WDZHW8m Wh\{4ESj#so@&|٫륉pE6#d/;M63~?w08j.m}=,0t2xm ?@K)/efݕի{nJ،aem"s8ݠpdq`;wL&ot>c'igp 5IT Y3~Pv_ᄍ&>'z+ŏ֯On0k])8: MmQ9|$<&f,:"AV:w/_l Ne/NR swpB~ l8Cn;6j+ iJ3=XyM0>+C ?M`ٝ``@0M py磊l/ΰ3=p'K(PނElyŠŚ}ޝ/y7HL *M|pHCw c<_'m }ktcKc+P*ZPb뤞Έmbm/aըʄߎW*KQ77_%cZƲ7<'ftd΂2cV)k`4.yo{8 \e]/\: NSI5wY鋗4e|ٛ@;8?^:g~s5Ja0G/֡8("s^^4*ttxUg۽:fȬ!1v^A<9u:J;zDj$nʀslet xҞa5#|+>Cvs 7|G7h\CNhtxK',/ӎ#dRF8 \7DuZ9|ig2_v,k.܅$[2#^ZO3N\\4|P*4\?7ȃMv\*Ao-` uy:{;p$$l7gU{u>n;[gp{\.pKci@~6Ao%~۪+ϝnŀ%XY.^:Rklac~+0/~ IDAT  z^ ~0tɞwb @X=Ϗћn|[Ai2Clr֩z39`t|?;F6:O<׮uUϮ_r 4K<=n͎YC=E NIǣ#G ΀'kv=+_Ԑa;'IbѵBZŖƒ`]B|ة"I9<_.ev{,|YS\MveCQXN~gH ~ NEGy #gY4A ߤw`*vz4<|t-*n@߽x֋ v:ɟVӟGhek`ȱK`e/Op NL>\:0atvuT2h"ܦԿrҧͨ{,t4dp Qq^١!K`u># uyK8t:V`* ,҄YF7c*\Jy~xҌSlԐAt|2㌷uKGXb r:o~OG_n{8mh+{u7c:$:99%@tv+ 2C[ZroD494|Z!:v=fNya=(\̥lUcd>CM:x:gbdx 9c(c6avd+k~xng00zxxtG+uܔ?_WWV4?:JLcgMjuv/HF'-b>ӑ׭hCųct O7cvz8@t>C18dV/8B?Y4w8!rz|(DvxoutwfG{ȓ?XxOrmr 9RWݾt4OltNtVs!f'4U콕DaJf ɥWG_k̄@Ƕ'Vwt}~p:!5?X^{+r$p?z?5ՀP;G7]м N+ޛHU^>xŃٳNJǫnvy9 >ɠWɃ}dfv?gwmӁ[._cWmW&FZr ^hFLLa~rNV\)FJ˾>Ox z~VL=_qOiuÎ?gly6W4:ɥbDvb9!qXX[oH΀]|@!y >tN`ՏtJ_+tv[2/p3!^ a,hw(e럆d/`/k/sC|`nIٴ;X y9qIXec)%]?qt/?e P "8;y& EAy*Q!nf@ڑnU)L=[v*G9Zvc,&v6@{?B̢KyP6<}bJҸxOEW+x_|^L;Zl5u+U1_1-G`u\$@Z,+>n+sÀHv܈S$xv#+^U|剱{>ףi)lo| 9Oū鈬|ã/ )88 S:y p%٤G0!@h zr3΃o{+ Ue~O3нtHn;?Agvoyݧ֭8wăv'hU7_$d(x7OGg*d-b}Y='oYA}&o_J;N9 *Y(:S Ll;D¿W e.4OF9ݦptI8CƐO#8p|2z[&ʐȱUrC4UY+J(;dܼ©L#cpnIV~qt3pu4ݍ'luI6(7r=e< ,G#]I&N.w2#ʼnwMɖD`Q9j*ٸ<?Cx /@5] ~FN#VuA]+K\<((Kwpt6HG͏ZC@tw-6/!zG{|~{on+t߉' = +QxuT&~LSi5-G:AC<|Yݽv9a;ډX=^c *mV >eo5 loGiG4 ~79^ƯOFNnO bB:' >+!HZto:bv^:C}ZBOe0ڶɓ (la;c|>#<זu{'chQ7%2X< |Dɤsh|6_R:R |zjЫ?^[#-SRAiS{62p¿#t -ĶB/N(`>&Gxly"7xO{/=̾~ld":z+_=)|EAޔ%ϪL<6]}+8I22e]xG5Gw߷@k|f/Y\[ ]Cx:6Q)w>m?eqK ] -"Q&,l]X#^6}^Sx&C{@%M6?\+@  -&G`{?@gDž(Bt`6.&\g0]xjYޙ^K7|;]qbf1g6a~pK+6hV4J!<}M|_ 8!Vݛ6R:} 7wNZ$@lo̠>cm xᵅ(ns8?z='fy|29舭ѤR&LdǟPt/|k2!7iՉ-H9O2pc-F?PHOw@N85xC_xUmP_0[IݬBQ3֮;{̐X^蔝]PrNҔ ]Rt (~{f8{.P ,/oJ-w>(M`C]Cj(gt6n<!3fœe`,*tÙ.=rH3G6󡣓`;ÃmEMo{ġ6؃hDVKApfoПT7 ߑMgʍwaFFGドa #U|y1т<$Ztuc?=ܕOC1h7}a>Rc={ؠ9eٟ_ c-Z~V?zs|U_# 5(V_8l'ˋSMJMJq%:>`PN00_sv1SD~\ltTy"zf@`_[}[b%NJ>xʩ;'& <"yn?GdGk50yN6̞ RK3tMv:8%{h+>_ߟDn QF>Hagʱ:uUVw3\}ˮqɿAQ4fGٙ~23G.lO2FKM ?!m. ]ãxw;x}\&Gl̽1Eyk:X>{Yα<ՓH0|,^+gm?G} ' dC#f6n3#U]mݶjst;vCun]MvyO>n.φ~mq2HW;aN *lu|+SKG}[ Jo*7b֝fV~Gk]}G`VI oր?L;8FN3+=k=](e m@Q򃟔.Xx=`PUwx0׍WHBb"$zIxl@ߞ_l=Gq<}`v+';Ŀv- 'Ged׽y,cKW6Y]M<-2o1΀%VcK,v6pT@G>xB}v N8|-2nOv}11;"cvk{gywl*LNNZxpn%JI[+Ϡ5Dpo"$#[0o8&nccᒀcD6>h^rTFܞg!3 Xsfp |G7t_Kwir#cry#'dv| y=% vܖF:4NA:/?m7~#A;;DžwN?\/ GCzl7;il/~&RqѝDchCI(,}q 始U3yE?g.pwW1i R;t \_ՓG{ӻ:/~*~mu@1yx^щV?{>lröʢ"{)a7=[0׶&U?m}3Ll2;EavS7BD2>i צcg">74PxxåCS'nkaV/)tyUR(3јTw@X,DөjDakk淿唧 0Rx KV_rO38ڳ0٩s>v^UYDc/َ[J/t2K:u[ѷ2kP{SvJMv]M(‘1_cGyf*@#ѹ{}[Mپ4^ǼI//;R@=m DMMGdT N{~ _ = x_"uv9>9љbnx jMy>[BZ.Ť0I㣿ՋG_',[/aN}pÌU8&&FvytV.<KcTG}T|O_a{~X!阭16kߘJ<~%لO&$ÝC1-Ǔ&05x j0+F(pimmt=F{D6,-Ɔs|mOx)x duErHz[ptne]7}y8o'g/ md<}@т+&O!$W x7W 6MxQR!T66O9yBK`]@ӡ*1Ǿ# @ T3h0*bC0:utHNaq47L@:0M"ωXnAGJ}}NN]'=|'][ǯ]~|+Г_4pOKwwYVKx񇕿O!7>C!Ѻl'ܸS/O\s)LJ?:#=X\8oW17/@ݰm_U+ pi|[ަ=2@|?9,Q9rPv5 IDATiw&!HQE@dC1̥aȱ}~ [MUƥkl¯G](CﶔNcڱ&[4^_Gg?\ҟf۪QG$@+Crcǥwޑ.Y>„7_ ɻ6fg:dBӊ{zG.?XAďYt]鶬Ɋ;O_ /mk`eϾs햐NX!m6׋c%n<|v?9?xCgb380s}eќ7XW }:>|sc: 6O۹;)3NIjGBI%^Hnt?]ma'j#~b6}́6 >vk,jU1znq?m\pH,ѯīCl;3*Hg=ƃ9L3Ƅ|tf.d]TUPe/>29O(7_F??:꥛߄G6:Êqb#k>}xx\RtzW*y8wf'lp;W6]% Jπl[=HOXty% ĠR>^m=>H< 8O<:)nΏлx!ɏ 'F`^9w:ewl*? f ˩QhuM%W{ R /Ycho"lTFK 5^`VjgtW^N5 #I> dZ|dM@-Q:e[OFNtu A%M(hP֨_9y .Uk*xTM.6FNꎉS?10)NNNЪ (^f'iǿ_䓧txVt::mHۦ3kқC7Syx*mu %xFe(bCxOM'~gN^~*׷][qtͦ~Ŧ-`[~[jjtoיO>`=Jы>=S}! ;BtKE+гf~c*&8X~(C/E쏏GNup~KOW%m!1Q Ρsgg8'&XoU^ҳj;2!&6 5ѩ+]K6G0y`~+?T8i;*Lclep{~Eg9zj߮7XHo|J:\wq'O 2,6z|LtsŇ>Lx{n-DW3v#椤}d<͆/*@pys}p}_f×>o 9g8B)hm1@ < r8QAN |p' +(;Rڭ'eYuV\?LƟAWurR'K?,c `d) Z|H#̄<'jpCz;7>blv*FsP辁*;b 27Y(^gt it7^'xC8wx;l+0?9::fʮlM={[Auʑϖh!3ɫc4uputյI5~@N# I&w1TfB3S77@-Ic+<#[%LV0O'ܝ^]\طml&0 "@B`[H$Ȳ !!"&s@0Z&AȲ jp=cͿ^!vӁ~Zy}"gQOF6ycq}S` c_/Ƒ{ÉJ2˩{נ3s[UT^|IQs^>}d.?Y,l] 4<'#ץnWX ɞ"OX:v<I@,mNF7V3|[(~U \q:}ء97)tο]>!sTٽ1"fo/Btʈ{uETŠ:dU j|c4{n%^v`ӡ|pLɅ!^ԡ (=؏9 }H##~Vu 1I@l\'-;8C3d,W,o [ hbշ;)=TGzvv}x<#%WȠϽVgh 1`ʭ9@,ۼmċsygӴx0;2 R7;}% ҒY~YMǁ|ְS6Xrr jZdd1<@{| {zc-(f t?o|ILܵ£w}upmv2X·V_Cq\"D"QpLxR.^t+E#۟~4ddp8%q5s(Ƀ?n7(jPBw@ao>ץՠWW4RBC՞@)09hf'"\DpfO 1ffv(u&,,W{o.,Ȼ2?OGdxGA ZbQ>Jě!8PpG#>֧Ohp۾u]72 4[xOjK\PZ~WiWB{iݝ`V^qv]|mBk_fkm:ğ/cf z%wp:`쭒Ρ @ٶsي3^glg/t XOgsfcD ` l#TlI @ti~3XdalCk0Kvz~)îNFAW}:Eh=3zDߙ#@?~W:%-/> :(ֶe o ~\N9l*|+ُ%WY[Z~n=ZWw*OIct\x9׽,l՟ ~/ģ3Bp>.(s/MN}h~mj_8Xs7[)IcrJ@uKM~{<&+4trЪ b$~_m_6^r`ELϞʕ}ڵ4 NZ]c3*J;uԻ~|퀿g)N|p8mu>6{ +FE@TD[1Y9˖v7GubOۏb͂_ܓiWt{_}H2@յ ٭Ad`})/PV=a䥃ώ(h߅^+D>ݻ:u߳T1htJq<~~&o0nGF$/X5k'{b$0t_4;?vG |DWExwSLf2l o{_3.ȏ..*)sNxVEXӖT` FKwRtZ|ϓ[̹s+?}RmAy1k@2h~YY̸N !h "G2^g:`w'ߚvo`h/ ;MT0kW7K/: g[M.?A%o_uHwpP׼tȏ{S G PSxxЏm-+|W,,Z}Wq VDd%FagBEVԡq+G8rp9Yދ֩R QByƾ4L/?PIo|1T^Qe(fN: GX -ЂHePu:xI =Cݭc<>xy,QUY4]Ij\/z)es323_EW( N4йծzX:1-+_s)JgzN[M!ouaQdxΖRՁ{[t˺U35V|m &ן@OgT>/6jzR<8^ȮJ9$ӉAp^Nt1s>Ҫdb=>T?v+ip)6VEtHFfn׳2ɧCޯDdo|_{/^,g(68'd~=C`@*Wi+7|S֪,|^[@6h yG߮Ck:=f`U-yA;06i6=Oh:& W0&ǭP~>\47ر`>=`] Ϟ4$ ʬk ( MOI#>[i[",zcKf,ߩ?Uy׭is IDATA쒍#6pƝ߽B̲Y?h:5H' 7 `_ý}v͎Sju~ 4o#LdlKg$(ٳ7cNo`Sfh1 ـl Oau>A61q;u{ry_}}vޤY'kVwۻm}B㌉Ϸ7{(ںwQ:3xooKb/rdd9GCצs؂E𐋁MOz>,eyI+@H?Cj1~_.ySN'/l9SV>, āy2hV p<s/u3OeIrŎfgP$4hrAxidP ʤxd U ح$:Q 2N0q6t$1ЪSg1:k݇tdGWcQmF '{=; ѠbUn2wo `v"NϞFL>! b3 PpLOa@M-,60'D}?}JifˎĂozL-ߔݷ7u[m%wN:2 ij'$IɫczLW%lj&+{rԉ>ӧ+Qx ۞JeMNՁuwIMfxWg|{Mfh_Ei¹pǩy2V t]ѩ=Zh{L[vGn>5,*'9Yf˻8#oC0mC7Aʶ2q4n` ݷn_y.~plY=,R۽0̖_|G,/ztթfZ _iФow}d?~~hƤ)FKyV`f_=;"gK.p5'؎)ea d&YuAr[[WGf붑,_}Ew{+/-F;9)L ɘ$c1\Uw̓DEhÞ5;=g^Jam\4uC 9БzlAZ>A=ؒz4dtg15Gl6ADzwtl+5(wߠUv߻ȕf `7morV+mkZ8MוE}+sC_Y0ڳP>Y8 Wf,]>ibϻV ]|xSdd778SQ}2=W+&k ߽0>uwn{n =foɗ7Q3~}/E^g~ Xop^:0b>2WNi-mꮘtNCT ͸yδNc#fQ Ym: 3"*tF?PLI5b3ވ]P@/|WmCX9lj$ϼ(T\81@ .Kǿr?Jc]__y參vџlF;dQkaXÄ2뜍GPY\:Vܛc8yEfnL _du{FFY)(sϰT Y97I#쌭g 3pp^ܞ TFw{vs =YGaf\`pZ,NHs@ ݢAl Yo|l?Ɉ,Q:+3ʬpi~᠛s/c{6-ծ@ u:+݄=l"#Ϟ&jt\`ӌA ‹44Ol?g't5Xdo mVUg-XqA]/-nT/^Vfu t}9H|x;\,vv7r[=n)"H;@ YA`![յWZf]}S_ $>5'~Hpst=9t~9<9%/ϾlV?u_GXڮh%Ťl :OWgF(>3臌y&*נmytd6K\CfX†aey5v]t8FFJlX]:;]Ozk3~+xr ғ P[]yC(;_Q{@Jw>qFP'>,'wA6{v`rB'} odx!a5Co,m {>7 _K܈wۜ[Ȉ*p2y،d52Fg&=^Xrd|veѴQ=[@#w@]dbPbctTR6"`&۳!fؽMW}a'ʡ" 9KjKԣZL:ѿŲ'W0odICl~Ogb{t<灻״ Zh=ȿE8I[;TVO6k- V[.?KsC>A V ۭTIgZ+˷ ,Z@~eBk 6V"2(س~ fRV5)1=Od]X0>7&f-vu2[zJ?dʐٶ\}og7YW[iUYTKV[Gvr2}T^$ :{YSRmm"^I˹zt:o1O .EID&W͑lȻB mB!=)8o;_y_zMl9ۖM/o Cw-lQp heKs:F#cfyaU@`̜H xYW)\+o spù/qod.g0Fd~a!#P|h1Y>[W\?>U4`8\@oto0quV-m a:<{=3p/XTϋ ˾rA>-zQ3*Um;<tDȓ4Wh7E~FeMxQчGT~ϺՑOnޏɗ/Oo?^'Սqn)VcN|-} huU6W:!t.\dG|:򖻮Eǩ+/?095X: Gyg|}y"Fց -, %ppώ+!+3ِ,MΡ 2ͨ =t\^C 7 IF]9VgHʞ[>P1< w9i'WZ]{f+̕&`~jQ9AݰȢ"Z@18@Cy R{k| {\>+P坍L9.=zG~ar[sϙ=QC7]px1 o83SNu|wW!YC,"N'>.[IcI'ݾ,\5.vPNp| Kd˻y 0^Gh(A75=k, k(,b|CrM4Czo<y==JNgA1]@!lvdN{,&Uy>pha=frU]UQٽNW`!Y%MM_Fܠّ QD$._h:D/8A哝4 K N}9S'l_/í^AlԹֱnA54㿎,ٖw؋t?Ldփr|j|Mr =tnЩqe:Q@͇9\= nm!+>yS,{Tt'>p%Ln9ѻΖd=WR=ȻZ/U~tQt[ &!w ^13+&V.h?˺}fV?<\AXےLGK7pJty>bV~}S0^o|C:\WFjȮ|sFL̀ӫ~}dt~ b0%{e4;u炇WLx6--ͷ:g?".P ᷏2 UVL6x&Tk컺@ϝ'c6&>[ d+Q!EtFЬC;g~>q~ګ ß4rWa[N*ボi oMpv!\X]j]' /dM Z|l̨A<2`L2R뛇v/X;#gQѹzǎl%__i`k ʘ! NbWO BNZQ9f6BUm|edU%1k043Ojy|Ņf3XE#<# 7'/{f?LG8W-v lw_<|{X4I[2ϑ䐺tfϣW 5Xa'.,o4{R稑sr, ! 8Y~ZFB NV ix]'x QҪtd4ǠvW71:@ces<]e LյK+:F KZ?CEڷ$5]剎ٯh[ "V +gyЌLFB8…?,_f䁷֩SG;Btg~Qz7'mXPu7Jsս-8L3謙Fc }ܙMt]Jy@Avb ؟U^2y;MoѯcsÓW"d!k 12{Fl}18lXb 25gƑrz5g8zyx==l+p;I?r к IDATdȾ2Mi fpvl82/|0$uB`W7-ٳ-2*z窧$HT6>9 9qh">?CVΑx :w4/TgUNpR}/ 5E|?CG tL7eH{\ ;Ή)?TS# t֯;&#ɕ3 ;fE4uٯm?1 l&63N1<"[|V E nE;ҋrzL}dS±:+-/Vpgwe?Q"aoۧlF7%]n 𸡀n3|ߴZ@/:յ tRE]!~PC #Y=6lݛ gkJpٛad3o3=3ʁ/$@:%oѶ>?_9>H?O>n:,w ܻGorG=X^}e77EA{͟A5{m 7@*B̪/0q'|@cA {Wےs xΖSsPa8`?vNgE΋QW lVv $g~v>K;߀›jg(a?u%`(Avr筄N9c, ܂ZUg@7r#{R7X2 `|tWZ n@p򪯼mY~T@5Ct7ض3A/`ΖɠANA6.t:_Ndʟz{}Z +wyՉ 8,$Lm:+mahRvC @HsF|)Z9|66׶6ߞ,7XCr:;FzA`7L3=K?ڶ LdLb̮k֧g#S׵ߍ^6nghGFFl[Tmavn(@4)jOf{B- @5 !QwSdײ2q:[90sK<.eu|ttdeU|< 70yR37ɿooNF~Sr?}y뛟ݿVݰ7S2^qU9L|wy$s)}R]Pf''hϰ mQt1 OFTR24r%Fo:R<]Dn6[ s04u@A'E'a_4h3sɡέ8>M=*O35w,_`ԡj\#^O_d{ɻiVȗ XJ lݏ蛌.A;@u2[=0rfvpCۡ.+>z(.D/tᗱ:0d# ~ -?3Gfѷ+w99_|AaʕN0Nev5c׎:EFYI'Xw짃b#; փڪ}F#Wu`!ٟjHԳd-#d ٲ}+?g|}WWzar[t7,{/\]W0ؔHpWad?ϨsԈuaa)I0فghI˦-erwO,o NI4IypY=䠏 Qz*iÒͣ[TVg7أ71>Od̮ |k0FK|l= Vժ^hHBѬ=聏lzd?pdOIO  r6Y9m+6I?dYu ;Y5;?Yt>Ö{ezxi+9lAtNTJKO(:xV.P{yg.PGsгn }P_:FYQԟٰ?m fWJaAj ^+8z8^7oI*Y)MfŒ#Z5Gateǟmοo_{v/(Z)Lz?&xK/ul&o;xOu;6wu@]JBN҇O:,%owq3=`RuQ_mէgdttSvշ)TT`܆%[+?bxHDKr4ޗO)xzo}t+ܻw'^ץ w@QR/ 5X9Dڐi[a+.V^d <@.woDyML]I7?F^d(@0U;4vϾyM,b5ԫ >\⬍qޞoG|luYo~J ^3[ &9eO`V1Mz~V%}kP{m?mg{]ۂmm(LWK/ݾWBm»t>UxZ%x9?K[ܦpxLv۾$8}u셯Aݭ~ ;O9h^]Vؾ69q9:Р y[w՝ р͍0f g^HYy[loJ{?;l"aRct:T:6؅v41zGf3a;=tϬz)8HUpFCjO3ot|,g dnLj;oɬ^%Zf&XyL8g; iUfϵkz=^SeyvGdͫ_cu .txiO'bc>bpF-)v`*Zg-mo[APYq?fK[I4vbp :@8[Qt2239 *_|N,"|i+;r)޽_=:Jo*lԙe3xYʭcXoFZ~A{{ٟAypB$C}`h;O~I JmW>d# 6rUy:vDY3%u3ےRS{1@3|ٮ/ zf`'}1?Wу}I?NA=dø'n'#x jw,Hq6+ dSK*A|xܻV̇$KlL/YY:X?cz +; ѳS{oA:eV}u MGV?q"am2|Gq;6o V_.g,7ZkH[?WfWt.~n ڞ۶r|['(1gJ=;ob|;Vb 9~4&?)];~ez)liU.~s};~,MO|KQ\a~J ݯ\4吓1&9r9Ύ8ewG뽞 p3 JC,ɻB`яޫ ˳UX!1Mӿ*uqlͩH@co/cAu:Kjmo3Tzn'| zvdp][mHk{Y(ɩ e>?!ԁ.JYgSgf_ u@;u_ຂAћ\{h ΨR.rfb%6`w-B XQy>dUFُ1Y #Kk?I'33|#/9Ԩ^ٶi}|:&`?讳*$e[26etoy#x)qx6O4$h;锽Pss'#]LF1F2>QFS~nӴ]riWx]WAVcYUf \h.?Y6I{PVvK߯ ͖WE,?+ %{+f3'&z[0N_$4 ^! N]> u7`%Cʟ xOHzSL1O7XsF7i<ٮ5V'yR<uw#8{=4S nwoOA,9`A^]z]~Ӭǟ>yo~ӧC!X`Qcw 8ڿڬe2:z[Q%V9p.5n!>d,'`|m<wzMlHPN/TV5T"u>r&x*_bR\u@o {l79A=^6e~GR}4[/ }9p-ȸ|p[|I6'v%`tF|8X2{-|UC/&`^\pS~϶zȵ]XۋiUO gY4m`4Yn?5g]嵈Ϳj; ~˼6_y]q?Z܏ -'ycǗzZɇ +zu}.4[O=âϗKI_,-l8ţ|/@W+meή eE9om3s}#DmyQy3߶<| jgKSťn ɊN?VA>R][ZASAp6%E?ӗց|7fک E 6ޔnmGݞ1G 9 ]P ]۔6`OOa}~{KA[SԾ7Ŷ;<;4ݎ~OE=';ګ`X "qa!7~o3RV~J:7x>7+"SM`[}h]# :H>Ӊ,Hb/ ANq(dT9BJJ畄{No:ګUrѹhmCˆ `7#ϟݛ?mOy|?kW9fȉF<'3=$8A^rFkUY7^;|5J'ҿ5DzP5l H4yNs Lѯ1f> ù G=+IF(nuDo&+i4;Ozr!]/gu+Jn!nt3`&s "_`^ew?#j{vmz Ϟut^P?hWQƓڟ~MvOl';٭OkyrEE4Q򋞕7ɗ3"CnA.>ottґ;]&Ox{ ^T P^tG<=$<֡d +O=T΀ : a; 3*G;FmH~tN{KxoƼ 2i˯qOm֙67CFW9BFMevr٠&xGpw?K&6q~ml}Ί[UN'[dorD+7!ԑde)'h߰e0-.:A^_3 ɆNG~:"wgo,ed.O0ubŞ&WnVoϊ=[z&TN7knt Yf_miQxk;ɸ@wTϝ:kG18܊Ȃmze;_2Gu#}Y:x* Lډ!}ݽ=ğ~AKSUh~3ZDj o<+ӗ_e@ϟ~Zy/~N_(>8q>.>^3AfYC~6}fZx=6[G:q+V#* IDAT3jYya??;աx #7@.af6 1׀f7*a8norO[^oCbo/iC{cS>eNh᯵%#*I Xބjڽ/}UE+;A~Xx0ŵL+1؎}_[ߗ~@?T44Ҳcz,333z x8.!ҷ % =. lmAU ^(E{O z컶Ul-Y>abowӟ_4!Bg}s\S'ܧ +}ixֵFmUQmqjp^hV{%tXvJCʨײoe~ׁ X` ZЮ2 gX7twu,煭[C9\Lg ?L{>v"x50£Oa=:N#]#~ ȓu.rtq+ٻ+dKGқJqjc${9g:@*+ hx&Q]oʐGPK,K.'C]ҕu o |vMp* . T77WyyP= G[s#]P<'O"K+\@ϻ^;A˹E}lQ}hAt-sեCY:L;x0(}aA>$G/`f\5m'˒][_\p|=n(P~\yԸSFo=C:_'?C(:g[:~ߋooxL71f: Orf1Dmz?tOpoM6[Oh"+ԧJfuҟAmuhFrt!<-XJu2AhpV".;_ii)ڀ ֻg+c4@=A*> .ݖϚ-ݲ@?K'4o}ܴϿ* -է.z~2};d3l3ڮ:o=V6MnΕg4v2:祽I_Bzh!8֍{.Y3gYm{n/A2_.[X$|XYсAF ;}̖>uffG\c=<Թ,A U vϗyMH}#AҎMuo0C].|eFs]x{,:NA*A%5ޯ̓~ox '+'Bt6H<4k -y$7`Mg&Gw5OUL2CwHϛYGʦ:dp>雝m2h՞>lUc"O>ypUWM?%)m}/^1A`Y126F&+{ E}RUW JȖoP*F|gD`|M^sy&hu6`mƃY ]Uň;=Z &V~LJ>{}m5 XʆO_ v+q):̹]{"Nxd>"8eo[B3CboU^/Zw;A/?/_[Sa޹1$J ^'ͫ6a=yϕr;P?A{3Ɋ.V$k\s:׮j ZM"VU&>:7stmd/:%Fp7{mf܍ЧhwZ^Ry ڀDh&z.`U{}~ͤZ`z6P%7g|Khfdmy<|ZW?K(E0ѡ{3xNs{=}>Y[ь=݌jgk~W)ڦ|m3d#\+#LNw 2Y kt=n@ouE{Lk0T`GƬt?*{-2Ks~/9=hL!8~ˏn*V6۳GHLeWF)3e<^ J3']Z~_ErvMz[VK1H&:dyѾ̾拟|Nk e 9z+ ́xa~;@$,c8#g/SeXl{ӕF m ?2a% 95+C5cf/mzK>zݪp)W 5/Ŗ^gvBA7fO}C6}lh;,̺2VHduV TJUy3[n]-8|KwU 6=ѳ d -휁mv{[ @4m']%^3x9٩.uziA5剶"F :*ftU=S ⓹`bWft9.=d$h#0|ah'#DD3k~Aɕ ğ7Ƅ̑CJٳP CO΂Mσci-4,~;- _Kݕ_Ez?N =GmO/tMlpDzt@c¬Pɻ{mːѹJw!; 3/eysۉy3ITڿ ,}=8.QFGTwY~﷒aGɎwE v .{^9aGyMQ:E.S/:M^Y6S>sҀOmafdv`5ILg~^/ס=o4 0)Gkv:79F-C{(~ܡuVO L]y #4`?"6x.xK@xhwXcUI@!^B-go(Om%)o?lfؠ b6\f ]Z2Ioف XrS?,3 *=??Ob5 h2xZ[t)ˀ3$^A^YuӪ|Io r[o}#,ny>sƮmP]NڝMٳ6 ǸؠV)}zDVqӎt{Xԙtr Bj/orϵiv3r_E" ?ѭ(O'-~'VB׭@A/9V5eN>Ih(8|7XRZgF5s8[c“sU&H]`c5āvj^Ln/<됗{σyq 0'O|ː\\tJ^9HCRϼ~VA,+#'[E'G7]~N :W{9 rg9MC_]rYJrt7\:9%O6U)fUxWstƺеO>vq =['4=~aGѲN|b]+Z'\~ɽgP̡MR')vٔu,IʥQp:WVI$ŽdӞ%#yh2`;928U? Opi?V,%5sg>'{H۷TOseƋ{SupU'*Ζ{Z=x1u<g䶳D@ Tp fʶ}k4T6CF4닗m|D-8m<7 y:#p;Cwϻ`ɽ+ ׉nd|k5ո:귙 >tdD' ߞʽb<:mp4c.tfQF0+3Nd:XWf{-^=i+wY~%۬Z7un}2;{VK^%4f9-))( j)9-ٜ{2!4?Oo!~D^?bS"czڒa)9@APIuzu+6>>u7fSwQ8 tvپՠE>e黼U?59z;@Wy:{`߱I?IA{f:+_992s2Ot𴲿GKV1ڽ t<4׃ %{%Wߵ!d~ B_Bbg>(Gp;PRѿth0/6Pp+~Kk#tHdF7(S䜭}a:[p-"E ֮|Lu B~(zBgux(9d] KA׃>iM6PV hC/$C A~%Л+ᤲ x^ V^?ŖdE.P'g?o=bb:&_7na ]Z}$Sz$7#4oW+_]O@erh"65р ^D4c @Bf:{|7fb=IprL7eq߇d-UG X!+18_*n^UV(Mu}6PMO/ྺL`:Fbο ~5OnЄ&2(*.h*VY#F`Q*ǜÈ?x10gw9!܈g.pYs:A ޥ_#st63*uI_>cWsR*þGyk`<}HɱTm9 \)L5%}yL'E'8U1]{aNC`xl(]oIx].;>8bYW+'8f!A`iѻQPSzs;g ԏ#?S!]d Q^9 Ew;2֩hOwҟ.Y0L7}O_JMF{p4`qh!8͎G'CEx9m삷[Yr3QA4mNl4V!Ć)asiBX:3=L.աcV76"뀍d- T:?d j};[gwL38_#;q]C<{|3{ԤzoGJ6`p<+kхNrvD:Ea+*qm-ғݓ Rg2j IDAT_\S~҃? .n -.{":c  @_xNJ%802nPd+FИէЈ7o>D8g%h$ށ>f{];|O{RͦtX9mН첳®O O=od;·EE.+'Cn= W0 uV 2&KN@1k%{$Uv+awb?-f4l߬[0 :^`]}hc5B%Iy[tDYs:30H %+xز qIF YL3[_@9䄜7G$~5GXK+6-+]c<'6, v?fзҵ$r[ƉT;۠[qmmm8r/ZdgUQ[ Zmf7mf[o߹;%-!X^oy?61o`"y mf|dm'2%3$Q9-)NWN_rZth"sڊ_dV zr"QWlzh7ģ`[#ntv+1;P)t];^X5=XRNAV穃&n}w ^A_f/&> G >c"{pƏl_?o3WvAY _$ml{{óA gtUWЗo[6`~:qapwqqz:}h&k(Fc[G1FYjt}۟`vK8paTN88csujtqo -Ax ?4Oӛ3/Wh[H:FNiE ,f>9[Ꙍ:J^,xdp]L$[@Ae Hh* #K ,.S*F{AN,ʝV>f<;6cYj^凤xA5㿀擠^肕=N|:xq5d:}Do6~IV{eW$oя.Ɍ6eb' nwx%.-Ns&Dodt H*#edmݠӌ&/t_?FC0ԩ[]AkWOƗpT|0|%1F(l0SVftѼ)7G lҗ:N^MFL5I 6OS=ΡZ]cF0mj)I/I{.) N%U;uPi: ;v5 :2^ǒ?.X4ƎtW/|,,bO?+Zf794TZ)ݬXǘжd3\6t{곍ɍ]&`0g*2y CZ~ VW(S/, y[͟7oH= XhOWN,#_J_}hC;D?_OBo%u*.d/u6}[gu@dBٵNv?[b>f \_7}ϗYARcL{7sLlltCvGŞ7؇lxf*r;'\iJWLM\t7T[X |Em5gf+ovG ' ZVѹI?U׭aʠѕk~zM>>%{>n"g? ʷq6/K0(b[F?`٦kf+Y(ۻIjb?w>JfW>z7Zz&?$#f RBa`7yi}VPuŮ\Wr/{^KG^K69/Gs{FhX\ͼ{( W⧒kNivԗ<%wMtj-AJ:L~|w'lYW74o~2~:08sHfs Zm>2gW|z`WWYX<=s$g:.%Ϟ6Zo@9x27X,?zWF87zo`*5ҧA ï|ˬ#y.f?+n+ɏJ$AQxVBHgʬOh݊ %~k1%f5~>?=_o|}p|3⊽j7π 63=~IB6>z+.][zɯi8/[a}&XΒv=74=Em^y!Ѐf .x2,BegXzoKqGkC<; ʹ^ětR_[kl-xa$t܁ Ux`܉%F SG17yf,JvoGLrq:`i:<^F UC:Y ɧ_??o9=x`#kN7'}Ctc2`@Nd:UgjNN39IMu|]pRU&?]qʎGq gtʩwnZlEF:8 ջ[ GEpFWE{c_hz:~鈎vd8c_0Xc?m}SٮmS~kQlxtEdTN{Cv,ϱ#$Xʎ^I%[,,ҹttdžgҿWo:զuc1Z&ǿS@02r/K>6;U{ l x!j1Y{d-^WН)x|~sm'B&'45AuvM>OpK6[ *D/5c%QL>I hJDsV|M T.wU5ϑ_g%G6۬X|/t#MY'tNg'ꢃ &7$a[nǞ9 vlP{چhx -ohu<6Zσ} zfY6,V v/ ΐ?EgYJޓ/oVi:FwxnDpdztgLV@Y+;p؊m83H,nҫ vv2 ]X%l. `k Qk} ` 7 ǽf/@T|d%o/Wp5*܁f0 u\Jg#%Oq wY w:{-ݮuvf{~]yTigҶlrֱRQ$zv_OtФD|Nz3{ K}ßځw voCIW&u)1;vO<n}64w g& ~d)*t w9/oϫ9UV詾 #˵8˖YbQX`)vyt6·G*g|\Fя7e~tYl2GS lc&4?KDk"!?9#F%l~Wѡ3f⯇Lt'[ `SFLhG;=.~^-J>EuQt-kFk3z4\eǃn>h[]V6ٜdT5^֛'̫&7(bߠwسaVp#k_ f[4|oG1CユB]L>Sx${6~xG6jCN'$3V\k`v/ duFx{i$T}W'n>sʉM6m):OX>[M}ѭMPyA{?`? @$wՙ~D r+V_qǝ7οH$Rf4%juO{|L2usr=)+~)>.D u3_ǡM!5FGErߏ=,ȬK+ݪNzFn_ #?Okwo+~޾o|p/nO7o}/?o7˨t>ӓuf];9  aF)Uv]e{^YxW?,QdFKڨЗ=0!@@e]_:Ùn+efuGp'@K܇٧d4<刪)EON7{}\|o0XҙbK:Wma%!_\.s;<Uݕls2^:`6[ gǞFRN~տ@쨺_ͲC6oKN :7ݷ\LN7>O5٤Ei0R=ه+hd3o4bE}*\[kU :x<&#XߗliɭVtbM%Ixng69ƫ:el)ʺ4\}4][a&RJMNУO6/ wdD玫Xܞr ̎.~2fos٠+WWՂ TUkZ+Ua O=>8K?/W=|Rz W{z;RF{E}{3Tw O͵ lgv._y뭒p-P$5=VXu3ۼ7 .%1&b﮿gQE(@9idŸRm!jG?|X_Cc}ILGdz~Rsҏk=QX2yq©O[tm%L&&o~;I/6otE tV Թn˽*@>/g5:p&kC9s]u $ޔȽ_| z5p_ep\E5l9X).q "(%oiU8~B"wK+]:2ݣ_|֋?xռ[$2NW'."؏@~D9|kɣ0[XU>'G"닛`% v_l3st Zm_["/G6;+DK=Jiy%;t7.2lI/v?9ͪ.,_peɞ̒>Q+/^~3r (w]SylyAճ^{2Ou䇷:hmŘzJN|}^BB97eSk l׽aeNwh߂S|dCguJK':c+̧9|bYҭn|ѓ%V!k/ˬ\YGRr0 v 3PԛQku՞D69 sn^ctv}nࡄ4,H@5:%$Dno/9Z>Rop1[A?xxibJz>~_As$fc|R&ߒ=9עN4[޿D95}aӴ'aES~|p^tMmgS4W_5Xr/w y'6=c[6קN"=kv|@o ]+3Flף 5H&a@$twz۽߽i3SuL]_@<DȌ?gWf"xvT??5]H nho~l ZoMF IDAT!7fe;A}Ϻ%9ɮvF/syJd~-7\I~[d֝d24:\6G/~货;X$`9`¬5Z) *gb)ĖkO[LBPg}?II^Je =^E+|>Ό珪b #ȅ1"k7OɁY' vu׏0x> ÀMepov:^fcb 1<;%j8Ո'_Jx75:,yp#4JT U5tߌ2" Y>; XT=k0${ %wg?n|߼#-JOo~ok7?KߎDC t}HҸ]$U*7UkͽǓcxhOiͻc'tttf逎9:C}\NK)F$8JWō߁8w~gjDJ#odՅjJf{%Hl5ic%^7mG0ɑ3xVlyѳz9ܠ]U,a zYݓdFi33]F6lV~9=hdu)Ρc$x|:$ptL\G'Idol opfO uˇs:R@b}6#h#Y_M'ү>VQ$+<㙬Z4Xd[C_,:%a&u!Fe4+ _ H j˃|~;׻U~Ih'd;lixZ X7C` 7{r2q'ߵP݂%zPxSWzw/~f̧c[o5׷o̎?y2'#ve Y*yzb2zc [6Ԡ\{,X2*;\k|n5}mڃ{bRNq}% |{xg^Ȫԗ n?0A,3}1+ҙ䲄P@;<`m0eZELF3 <tſiK0ho\{սdCLE|JѼQp1OFR{|e/C8L8jk}BI3g 4>3B٪df+eZؗ uk{#d{dS}4U=Y gf}{tk lnV}MDv uG jG55x̶^/حmt"Ƶ9twL\P? ]B8[ڝ(Yc3\3!N|Cܓzf|bYo*y=56gW[~\6xоOfs/Шχc1rIz]RfpDmU8|5| u}^clhQ}JYR, ._+?v@ rYF(^K-G{`zo7Cn~-M;7՘~͟9_7n~ff?YCEzFW7Io NWAR`k~v1N9ȐA5I?d!N׳ }1$ct&cG:cO#b^y W`K x6Nl!/džӱ祣}kCyh]yŏQWbE$p‚`U}p2%~{ʓ=Zb.^a U`±K4{vBۂ .l8/qr۬ы/ԁp]o`otV8 VE_.u}̶m~ ;;},3AH盍GSlr{>@Z>iϧtU߮__t%l w%K7S_voDe|o90{|f}|+ = 95^v+ْA߭ng`c2@@e xvQ;'+0-yEYo)8>0XMXM+-& ]x[}1Viz>$sA.lSb0 \Ahr#% kdw$ ^CWxn4N6tt=r[3T_9&mVh~V=/'l` $i/'Gr4mjE_l6Uy-"!}\~'D Bwp]!B=Ȱ?k٪GUT,6L3R&ة׮*gMERGbYkX0jɽ`y-2'q ;fЮч nMd,he9t`vw}vpg>^&7{w?(xlr68_+'^߷WﶪG2{)e5#~;;#}\ޤM}_nd G >)WpYX{GgL bh.zD&ޥW6c |kh՗غxd1 +n&(o^MW- # x }~EB~zhq#j_QM_֡Jo@ D£Nx14ztu;)JkZ?E&i_$ݝ'p rB穿~_kvɂӿW7Y˯Wo~/n6og?Poh#3/|oW: hO\_dʩ\d!dJ@.vl wFU͜n.k ј/ڌc];sG5'[GQDZk\8pe3h([#>dJo%D߂?~ g`wߕI(L2VeDlw.ӝq^m#0`]{b$w0"N 6b  2-ǝu;'{^kT@I9ߒŃ?3yn)qkޠNtMoglsfP3l,^Y:|9^=\VfG糗9v=rt3ɣ?z޽*LO_|v{x"ʥ޾l$F'gzioPd4{Z7YE =}9fo5 9aA EWd] 7d bH\_.Z6a5q?C)``m9V^_H[9PU--}Ь*Low {n2@@J dyk\Bo4%6sCf,fH;wW,^DÞ'ɲVf+3s/۫ u :Aϟ{♅}{gn̈́t9v&mtMx Pq_upnzޑK#C=l%3á~eA6YeѦ~G N^z>R^Y[:ٮ/hZU*Ś,!7#bc0stn^瀓 t~ke}EW-߭6/>09wW O֒ъmHz 4d{"[b>Uҙ#W^AFn7U_*;-W׾$76 tQ ܓ̀,1H'A`.DL&+|cV v]ᩔJ;e{ \¢ONq'i-^ Ml>:ݡc4V3@hk",i޻o߻LfB '6~|=~]!}9e]cؕʐّbp>6n-䏈pWĽftӿ}Yя\: NYGwmbE~ܦRni +c nU|]NFƯB=~NQ_3疗͖Se}Kf[& /A?ow?*: pTv+dKp KɥJ&>3Cȓ&?Cy|=1W?8 ~BPAg_ ;n[8I6zW̧^ kC:m~MZ`1=4z~ j@d^k{6i|p{J's-Z}վ b|G ѓ`o 6C 4r3@Dv5-5C0kaBpDd(TBuwMuGp\0\lU / =cF` \~?Wn}?eO~˛_/?G?oJzfL9 ~߾ `_O~ѾfSZw;?+ܤ_nH0[<^ZN~6ӰW{-CN3k'N(Ѱa.MWoȌ_Wdsƣ2W2^0x7uaAPFhPc6Y'5XEF&c=;BMu3Ыu@t͎xj]̀{F ^t]sePqJ]sdgGוWB1{&qwϠ@ UGF<0Tףw?'gbq9v4S8;̬U^.Ty4n:>O d꾁lwtvUɯ|gW\=U#6t=V7/Hj6^pv ^p |/M~|EwY dx GVhC(1W8GۤnaɅN4jYo6FG̮klֈdFF~ :ݿѿU?:(`o̻of跪Cq6+$x>[|JgogIHn.]@XBeV+1Ϊwhstyϩ?]k$+0 :p_辍&K;Y <+~tQ;3uyH@jTΞgtw *wKiwS|;*{%GwzLI=-ų.x<h*u=gv*'S?5,Z#tAW^G﵂ de# $sZztn@ceFuC{%~:jX\btY͔K sޢPoqf}2 n {R07y!`_fZEvՒgtvkqoջKFy_r5O]{7w/96hGeP?U$6YIFݞY  ׽KV ;^ƿ?G2ΒalQ\b`Z;ɾ'ʫ~/K!-s_-j'>lo[l+:Y{΀Q8؉GŒQyQ6FUu_L^^tۜe!w613 MDOBNA.^H~u5XO\<= ӿwߊn5}rf꧇ MX8^=p Ů_ӄ؀ 9ٺyɱag|Bp+Aza'L[h-6SՍ> {>l~Xh /6 I \٬:CG #>|,~ sL'#;:|v$*ͦ \e!*nWߊ=Rx!YocԠ&w mGj7|G 4۠S M H#@Cgߐum9"ڌ:ecgz5x{ 4\up Gp*{0_u_]{ (~|ӛ%+/;r zhv^4> Ah~9]콱c3F(U{.~{VIgG`K!j:Ƿ{?s3-n[kidY{ף?3lV #tc89>L}oZv۶)θQf?!fg&~MwIz36$ޖdDu79]wUfxwox^>zMqVqщk f bW[0vaI``֮V2Wܞs)O2An/r[/i\b9 ۵-!orŦj0y'-?~G6"Ybw8O;LЀ~e^CQlr^ o8(|{Uex QzY58Mⵁ }s=Fg(g@c+&/^k=ȃvlN# ႆ*{dM6ܯ3 ʧ>ś80,YOp֏ɌJ`\G(bTrg5@ud 8{s0\X`a_k-_Mquo'Nՙ6h3y (x{Y pH: "TP:F|?wp5`RS0.nj҂Rvk !v\G1=v!t۱hXB\ zy:KkWlϧ}/FK&pOӮV!}ղpiy,+5Y y 9(ڽu nvO2qt|Ƌh3Ko6?{r '~Đ}ruL䤮ϲJh3gzm43΁JǬiRe{|r(N#t KkU9wbs>3A:?W‚t0'\Q8[ ^8h:>,Ud$9]Qwy|Qjz;~H%_봡X!W(#8n;Oh;syw |a#́1-ypX:v:IקLGA9/Pon޾$>oҳ7٩ٜpfU`{DѲ[e$?C7s+d*1`6JF#uWk8ĄobZ[ $'ONUu0\0O ,8n)ٽ qg[pD [s]iw޲飘`2&m/Xtlk x.98$~Uxp>H++vQzrJt N6 于Gv~ee[KdHbmIJZrvWpP?]|kNzpnlyV@l&wVH% ˙K/~up6͗%{TI- LGZd䛵'ikG6[~]}Tm!t2gjIo y|)37NFJ_헼$lx"+G>|O>kUPxcU={2x:v;|ALg&6;I./2~ 7[7غR[W9=j*+M)GǾ7=t)֠郺 w\\bGwxOYէ n!Əx7;]E@YSA]KQr]UL[v|0خs\Bc277[rUFڥoPپRU>Zzm}߆B@tKܕl />Avk`yY vplmB0DV$چd=9J^7UɟmC;Ze%f6Zĭ|Rw@Fs4>wK״s}VoLK\M1NPv<˿?/B%Ͻ 0Ƈ7Ͼw<^4hmUCK5^} {28G 9C'0l/"K"bsZKs_%!#7$|`rĹ6? rEMNjG;hѲ>Ajfؾ(^X1I #+ } ^#X : B ,&Wj})\ DZhME| mB\qw9oIzKLq&B)tAthͅ`?߾_Tֽ+\8ພE/BOfB;K3ؠ ZBJ9\ߓSd(/=W2Sde ?rv3K}N&l$3ڂP l&$+~x*S ;\vs?Ёo\+A_'n@BC ppk9ۻt:e::Ƞo&ɩrGF64Ъas ޵})v "_aetxQۇW7}hנ +̍.:d:IyW\-Iܮ:rxO]htI.F|{ rlƥk똣eTM 8t~?ltiMx=+ɨ#x76DŽlf?_I/tl$|k[F䕌"&V t~l'WK.G&srLa^2 Q*tGr#%rk7;uvC$A+bA3[W*XOYU  @4ЬTj!Ô!~>榋t&$Ys]̞W]q)q'+x$g$2z|Q[deADsǫ06cۮ_6wC̏ﻖE&CIԋd( 3;6c~1#@IO/.RѦD>B]A dF6J*pn + %1ޓ@ٚ چZZ8%{:Zdo|]crLGxm[= _{IOS;J$|{MN>{`?ixxvV~JSw3^߹:'OI'B{]@]:Ȭo7ǓY;syKzW܏w$X9v, 3Z\ɻ-w%?dOd@>^>896;BՉ.ZA@<8\dZGY|%U˄-S7> {[8d餟o=8odٶJgG} ߒ"[']` fV|pK;GGe#8e^[}4;W|J}lI}}|e?nH[!|c7ˣc2ogwՏ6vVl_o9 $v/WtkB|#oAWp#Ͻۮ.;e9g=VEp0bBKmf[BAIa{K}n0dFb`m&B<3Rty`Ǟ&zfvov!oz|J3zWݽWh%tD:i{tXP>8%n3DoX/h"5GWh5_z/YOׂ앍@(}>#=BUz.߷0Jnm [U5Yp=mAzm5B6U6c@uggpWVl!FiZ>R{ﴇ٣ioo7ї1!6q.`ڒ<UGB ~FԻ պrd \ oEoƀH ^BOQ'p10JTQ^]! +,qqgD]z9v)eQ4^̥ރ<7z$vs \{pT'ZԷ| ::_yJ\'_}we+|ՄL.BP[nz d9k!>᣷-'+_U=WM .g{4h#}dwY™˖m%u@Z c@iోV/s\ P7s8%#sW_}, ѻe}#$R;Y ᯒ%\hcGyHԼn/x髸ʒk:O.-L>+dWl6OnE3[UWW0̽?_!e08b.Z YqڢGů>;K%6|NO{Z95A7ûm>lwgĦRRd*/~yu6vICZr,`+-|^IV? .'Ȏ[]-y`}'VQw+[>^ >,ݣ-8<* !qnq~y;;"7lƹd߀(Xm4%c@pd?Vsy}B$eFF%4b2|U}V:}DsIN@׶}7^(aٛb=z<,C+xp*ܵ[f%{pH>Z%s[b1mf-lwZ!A#2u+s2bO^{#ھ@p(v=.v|(~k?pӾn|Vm58o'^:7ɨqK.K %?xܼ Eyfk\.dz};:oF$M|Bep0zeW6wu/4Jk+D_|b ^~sN~~'ML&ԇ lGQ.okw[ $F_+ɪxIW|Qe{dA,Sm&# l'k_4{o&5}1ھt:`vx\lk[654 YBmz3F'Bw "bYǜFFA.ZjDTfnv 4#ne@%@f觛o:Iӿrtmt`DW&$Z8.yxB F@{$'}>^/*ޯ,erj(EhIFAgK`e} g\' l9?=ѹu\{k`@Jͨo&cBkgmmhތ|ߓk𘁴rNDCS]ox]w{㍎Ͻc ٣ⴣ>hOp |?m>:_x|Tom-Om#nvxh>k> =?V.іOF 4g"*U-*דp $Wvũ}=,X:JOН<_ā DچXْd>%%Ճ׊xݠ;uN0AOfSbeR[>n5gFlq򠗱vdƣa3GoKJ|dn6Av^%W-W< oEYAm_ŕfhJ聏N=ZMjWK.uZ*uf݉&Yc[83P9:=:+{>8 sӡ $P3= [p&,,#g|9fɢd[ T~[B5бwB$73u.9=W|h9~_c w}leIk;~׹s~ي iؙgbpdJFlpT|ÝRydg͢OްFi+,{jEǾɝl.`vJq(.WvGsBG3K^: rV IDAT+ĎtmnuvC[m>+]HZ'[˭8^U[O hxOyԦkoK\^G0tP`gۄ> p-1OZupko>JGV"TbŮ';`4#ܣ/Wv3[kX[OfýǾ|ea;{PʭKGAs}me/7X3rr)f2s$>yiU)z}я?~/rklF.QƻZ? 8{=|A1|5o翴N(F?N֯O1YW .X<;Oe:N%~~.VUhQ5٭̼C/)-=#Tw,{ |w-mAM%P@Û8˔3-Gf8xmZgEu&?IӃwz>曳*g.2ri\Xɫ Oe'j]O>2 κsST2 7[gLCqe9\:]'_q5hv9 {?.|ʓK]ȭ-áuYj`)'.ɣ܋cZO:ebrD$kO| X=4͌٫<-V9 蹨~٬'!3L>Cp f#-c} FC%ʜ(;Wmͷ_dd'݅Y5?Q+d$ oG}RQ6Y`p9rA#Oz$PB4V|xitu?+8ylEnYHOYV:+Y@~U䳋 cOZnɀ l~DD+ˁy^r옌֑Df_~ҲtdDu{ne}vv'y_ ׭\*fB̶ q3:@ .#Fݵ ,v\ ;an`;?l[`F 6\ܶLcZ?M.Blҁp+; ,h?ͧAq?seF#3s:m#{\k[~(V:H8X=pAdm f߲v\ }Y068|+aV$<9bMtIГ$U}@c~2thb@+ N#Jmܫ-K<~ovc(fO "rk}>e{tS~ =rOe7SCד;TR"CnlȺ~ouQd+ nu)$1hkCo5d7belhUv/ho$~zߪ.[aXۊ.o,N矟8%x kȣ{<]=|둅>#LAbNpGY4+Nؗ%p??:_1tߐhvNE l.~c0o+3CL7U=7W|ҝGie.ׄ4=/MHo7;_UVkA ,$Xbcqxv'd}I&=x!eb=6Ia1 -E+Z꽻|+%!%`oyw}۽~z(df/9l<(W9>z$e!kBs?y-l |U9f/F a#E(۽8CvŃ I> ö.,<N9!d) rr@`rk(ƦG< [@GӆPj=4LHe,$P!>t-u(:,`ǧ' Cz(엲,1~'t? LlhXL?l3G.(f>'r}P)Mع F;ۈE$3k}F^N~'ܗ50QJ-hozDȷI,,[a,?r}">;S M>"mFq7vk ox\W4]~iy'e_O ђj<~I_ԙ|) fC5Phh-UN ; +X,K X]jhUT|?5- mXOk>+l{ h`mU4xurmLk{ t!0q:H*>o:`jKq893>{m_ÿM i넺'@Vl#&E[̵^BiN|ABe"Z_j1CF~tiޛV~u (ԏiwNjRa:z6 7ErۤWNs"ƘEJtanp'^Z+6{=H^0'܍<0\VXn+V=9WZ%䑂DCCb=5<hO6/@҄n~-nՕ] .:3|&ۥ89f (h}G0yƽQ|p5-E$,eJ%Oy=Fr| d܋_ʣl#CL!Z>EF(o"$`GghbJ4BAB[UE yO~7cSpW_r\1&Ox̱g rcGk.-Ap1H~T^cSar9D8᭺OR.x1ȪW pd?}¾-G 0!/ruʲD_&e}@)< ֑e*Gi :1;L<kHɃ1Q}%%nPd)(P6eFd9iTflC5R3KzHe?r~2j;}خn'еEi0)#ԍqs(OJJEPF1;Ic9[4KۢRO`ȗHଡ~v}L 4m.SOٶ=ۭE?lɺv1&hb*}|֧M0_ڻN߲U{)j&Ӻd0H?RYAq%O(= Lcϙt7mxߞXvL&cۊ~W߈0<0_L^wɸ)r[*2~eTz1y,xg ¶UCs_ ȯd:1^)[(a؆ ,Vy̸mT!K2)GqHQ'Rs[ocUQrFޙܾ`90M=aY74 q&m߭sr!ѾCt;`8)7GNth0?BHi2/K>ZSp,!\FM#Ҥ́Kk@ڏ:l9[:ָ?sooDh&ׇNK?sqC[3hG72*U?|y=<)z7% p%)_ V'R f Q=:΃i-:``2ځzK >wNRhOŒkx*;F%59w]DkV!Qpy\iPs ڔG{sRNզŷjc\2 =PZnQ(1,>hkX6o_L!~+Ͷ6RFiM ?eR'r`ti0$WɳL\BdY)޳B(! R#C׍Kzz>fh3kX֥>,u tsJ!o?=\_>pIؒ 9mAz.C Z0đ(4xQ+uM;Q6*ė_u 槎xYawO>Pl'ʥEC(A*}>-𳎏[w@B ?C'9 Z6IHreL0# y mw(ÓI$]m۠?Wչ<&q!=ybd><bF~uӼ 4S^ L_G"PHQ|os+ׁ2곇ub$z>qp8ʼnaVzC˸m]nh`PBf2Tvd:7ôs5M*>GްIFuj[;`U%pp&Q i#UvCWo+k:پp7Z*Ad)_j4Åͯ}<E4U'"F϶XKt|V,PA~ԟC☌Es 4$<%/h\.I5(b jjEW{sP=Z&<< lҸc(WO&4*Xq \Q΢A~5"M:@T9#w26hPtU T;"Y:е}fDǐp,iDtx1JxvQƄǔ# 5c^OO]i쮊zYmVW|6[p߸xZ-#*-Rbf8[Z'N>}pvFR` _|=)z"7*wz~-CAdό1a u7g̊ O&Q~""W;dfPw|1PE`jtl{OIXqxAt鈔(_E|%H/=7 -/TLyrw1,5>Ρۚ\bQBU{bd(^^=q3,ʳs}:n0jh+`r<:˅ImvI n ¤jm{۪kˠ`ڹ}Wey"0x1,Jyi%tDI^JB ycPT8 E Mv{r/*(M_Vj%eq@#\]ܐϐD$<% F^ mE<냱֯u)Э} Hyc?;b/zɶgOL 'O1ğBc+ *O =+#3&h2~er(cJQ4j;ˁm,*8P䜲ыq#9Od "^C*V8jp0LT/i&ixEE jUU_NsZNʼ\}rF/ɣpaCo ~&NqIE'{g>|AEX8Mi b2It/l:V \T7mVlYIx$(8 AXU Oؠ!`'9*GD)Gyg.aƠC\?F Ыj-.tO ol+p%g UJqN><'a|@9ˠ.:eFBwJ($ʌJ^dNdʾqfViDhxOn&Jo\OrUS<_Bx2wo,VC>0Y $l6b%JHA x(ȈBPk[7Uqx 锃T !$ hZtpDW0upW<p/PPJ0+>4 x&< klЂ,wdENU=#x;ag!rpyЉ{FTcp M*mAR 6D;@dyP)K7DF9<Z7 ~[Oλ't&3J.*Yq|sRJ?.4~}(X%ZWyTXeTvl[%Ӊy um/ D9&=qa gd;{ߕoG nk+nx[a7|9sKy?zBJg7J)J@#C'dc+^|dW*V9ʁU<#88*7t޾S(Noz1{^-QThyx lFYQ4v˵̪p0kIy);S+"0k Ā"0'P2A_Dr՜c /!9dTxBs64/XO/O^ ՏیʗS:cV[`kv;( e 6b3誺tfq<3́<-UZI#)5`Z ׵\#Rz@+w 17#N6LWU5FeַA?{聥U.%Ȃ k%L }  ,J>?["`Xy]O?l# Bo _w6H`{vɢ dWW- /h9>+>/)a1xx.4}}`vlzڮ[\gX*NDI8tX>MklFoG?Mx߮1_?ә8SUe+g ^t_[4 .uՏ5ʹfPXUrf\#~c#a<4WOt qnT*U)8 'hQ>0 WO76#L=UD#cJVV@Z%DƼqb<"oֽr>pJ x]8wrtPޚQ%Iv ʋ[(w+!˗~+xF8,gv-Pr'Ι{CTw ʢ\ Db"D}Pd![PBZ_ȣh\ <a6->5v :: EydĸK72rL%kWRT*2p̕Ҳ /J.QbqNY,_ErB[QGjFQ`({ ! {-,ai6 dSAvK3Jw,<@4@ђdx.j>yc]:&mD* Llڥ|+H~vL~F<|vXSކLo1rΎqB>"mY{ *E `HgTM( _qf14`.cѺU- 8%=2(;dsHM(Xl |f0dy<O!:eo] 49Ntf#6lB!O^LGn: JCrU4xZ/Z1a/y>@V-38pMPSseLy^pNNMa{g>BNMWrN?v" ^Kg#M2;lA?^r2 ]7|d:T|` ycڞN‚xv MŻ%^yiaHZS$5, WL2D*Lq+#D}nJ}&o:rbH2tqGp4Tɴ%||oItkgۿƆeX*VB=pd}톏kv޳>%}Cў٫ow|۳9n=P|F':7!Na^sq29xƕǹ ?L9P_L.8 JPEX{ԭK"$KN'e0 s{'Cy1r 8+ 3 ee{'oԥr_ LvWDYx"W~xϭFFCCϸ+g;g SiU3 SN>_C'*KWqI!T!(ZRR%5DnXǙZAF @H0'Jl<@SzQe@DdSfS(+DÀ.ʅ~NF(9TخܻvO]UzNBSJ Geua*~ciTlm)qsug@[w]9- 6D|0XP` ț=ʖO5eK[89ZVPcXS䱞%/.|-#7C%pEacۗρ|@DoPA6Xmb@b f6ɆS^A$7 t10 IJĚI%ɸt(2T+ҵbIv5pYBQQzsHȰ2h ap[j_x.JNp;iHly/٫#SUhY6-uvq\_֧uXIR|Ř`DU)&3ϴ;Xw6˸ Ok1;FHG?Cj}Y@QV4^p.wI|U",EN&k&١;E}">i1'|/n bmL*םJ SbRBoX9mv1`^a]vzHv ;۾, 9m /:n`^ee6:C2 K~eA @'2rY _K&xV UF(p[AN''K~3^lؕX㬂r4xFqf,΢H QZVc7o ħY7D(tϪ1dQ F`<+OQ{_z0^@e'y5J(Q Acp,S{ip;+$.E!,ؑѕ!]8(l UӶmnb0VwN<;@rs0+lw?Rdpx "kih J[^uO98P{r2pqt"1FЛ(߯!Wg@e{vZ~n\kxstmU4uOڶ| J5`#eC|:[?]q>Tx_H?¶fO"ȔezR, ~"'ط5_q64;j@ vfq?'bv$Os"(^#_6 ̋6Wx'M&aNBGg Du6J2!NX%h>~' 7@Vr`[́ зkFuo"ܶ}ow+1s>/'9Xo#d(΃1JCeu#vesSpFY45GFſ3 eNsLB fϼ)SPak0 ,P9[(Jt ͓ZIC \r S?F dy8d烟KFe/ #Ș("gT(Y`^3'IxU,zboxD;⸵)B9rz}"㢕k)ݞY=kȯn֫[D|K8LEilrɭk$g/ mcnAEUaFK&f\ࡢopQ1/'fAw$P~O=<@PzPd& \̧O91h dT9U%x6%#>*@a)uWN~w4McI4M'0h Qn<-^!@Уb<*hDCwC| V҇Ά)<MTFÓnc%EaHL$*)?GXMrP(<!La& [>{O נRgC.cѭZ,:YҳvB$ :gJ< ~6Txz:`oq΁{[3i_h=WAҽ*{p.;`G'DɵAvp|΄$ٺˠpy 3ktۨ-W ^FwpI`>xH\BGW:SG—v I 0lGQ7LX@ 2?W;z/h^'r}n8J9A<H  :!Pj~Mr؆Om#} 9Iviwԗ_nE_pL<3T톚y#9%~},3'?$p8~3o~W_)We) 'WgYvѤdc`tyNY@&Z^|}Wro%t8+L*'0ϒcޗ! __H PA2ܜA`KnS{Y}`_0tsSȿ Dg LATO &!'G٬ҁ-T`_s1ƼȣIr._W;,(f>!K zi^dA->f7d;:vC\{>\8blhO8/8詤2p\⠱McG@`y l1JJ'8is+ƍmp-l #HhV禁Fi>dYm p&,Cw U__ wYߕV/'Xy8|-eu;pwQ~}jW\FO~mk|mk nZۯj9}K{K_]xh ⤑o~-lyn?[ ޽|]z't&u<]rG ~}:ד!@#_uuO|v8xuYee6 ̟Ge ,02R"z&ܫ-{"DPSS mN97#M *1]e8f%_BA>8 0 wҩ@jЯ1҂kyz ԍ_5"Lb\ ]I O~+yD2?n=Fz|wZ:0 uS6nг$uP ,yp@])8Zw.ʲ{>v+ePđ_:N( $F}Ѓ}r]Z,'"DI G-}I=U`눕qO *AƁn2ߗy )KkA>pM2A?F u c9\ay|i,D ! =5 `pDSzB~ypuZ`?qpCs8dTOԋ !nO1?u_u,,7ֻL/,79 _c!'gZu,s /̣%6yDAAJ!N1EJ T*>yO|}a\j8pwOu 1jCZda~PE^%`jh+ t I2Օ[9^/p-CQ:-b>DcWt9+t2hNvq1bۑ{P0܈Ä5܉oEo\iuR j]9CG ܝg#{4xRl-J> &u5ǃe؞=8K+̵q y˲xOmI<HxALd;%π^t ދ[vKM :?y<?N Sn!pB+mDy SPǫ~LB+{iظ.jtx+L'[}9Pc-wGy{/Y7iw@;5q.)'ʢ@aIUW\|;ڮ,L̶. K13%W]\;bܕ}ٴqC{sjc|8om۶zֵsN uwv.sh}gmlW={7^8ncOFؾ乧w}?rk۳: [6AhwnyOx 11ڃ&m[» 'lõ={'[Nݹ /vWۏ<|OWp|`7} zm[s=hr#fؿzy9-?]c0{X_BӞ w(}`oǃo>NZLȅQ[OʨqQ%:{"Lqږ5ms0靆UkSk 󧲈!s8\d< E%^җ,.dP'aJʇh*/8[ `DC76r-s"lfQvfEnQE\XI&Y rue? D$]3(Oa>uiWqwC4v^<=_Wetr)R$?i,+H|=$yL犾[ORYxF/yX`ꞴY@C"8X 4hz;pdeѩU9zvBYC۶<8q2j5Ii4$ n5 ϕdBu{u7_gնwӛ瞹>9w7?ªD?k9y^)4ˁv۽6ql3r}j?^z=ϧYR}y_5=#x7UiK_miTO}+ommv2^6= m=[hOn1k5_"ʷ?vG}y{V-|_ƫm?^p~߀ O[`rrWyC,hx5CQqEsePe[Q/? T~1~G?z`e YM<([|9_#V9yWbR(tPh{<g'ŗ_ ;FHyDZXޗ$1*<ӎ.@(AzJ[|Iz#xpX +؏v9t(XR P&?]ΒG@+!B4_|Z?oww]o{+?A.jwn{ k'> vu0W=<E}}{[Q<=xEdh/ˍGmAFXljv|?XpY`;N$GѷU|ޙsiᶇoy瞝h̑/LK8vڏ;C'x񉤏~om[~>[|=?v-uedJ>݁W^ssQ+˱{SwjrM!g_Lm]e^Sm@}=>*N]#@ק}Jұx5Cc#0"Q`7P'‹Id^L (|R>%9J8!W3$ }zӷz3ף8 l.A@н"pűpqѰ<qp9)BzWYrp yyrŕ[_Q6x Dc#FJƇ?k2ezY=u.Oy/?;hك4?IGZ4K,pӕ_"dm_`=WFɃ 5wSٴr%QZ^}x\MMR7 =>$V6P C@ ){4Lk25c**fQE=`ZȬ0 cy 9!^znNq!;>z_^·N?Xg"^ a l@Ǔu<?SP>fCiPs%1 Mbxo0KU9 Q/IfRX@Ggє>4o ,ޕ4^W%еChKI0M[iT2ȈhN8DVMVBZ)A\]85Pe\%q=&*n-buFSJgDB$N;}ln:ً]xI7d︝é`h :Q"_ ]`=sK)Cނ ~"idԏVΥ) V϶Wy~W>tݝYM\2#m9[`\31k>qGB?$.zV%1Vg=ÓW /HY@oӶJkn!N9ImyOlµӞ_qd}Y={q0uo3t_wyxI.b~LJ5g19זh*=A σT✶#RF9L~m Wou5 JHMF_<"s+7\ϙx3|;z 9l+_){sF( !KEd `R9?@F1}9dZ~Y5(I3l)05䞢KO)*<{g>q^ayZ`1Ra'bLu# B'u}B Cݞ~~{/PDI v=xg(#y_ֶb>BBܒ< %u1j,_\TLgyYQ`Qn*Nsw*(C( o[ EY}A#A: I rh蔡$U@YvW=OJs^!,Q M^6Tvkkd/Ȋ9iT=P D^ވAז>,eET0@Y?zO]N\ 5BoQ[B>) ޳S `yPzg,3bS .#2@dWy鼦&E6,lDxk"8G@])Ik0X4Ҥ!mdMC4T\+2 7V6U9\yQ]CcFy$)A:mh-\hNXH\3\+.W:In tZw;y,?=>cQ3tV%?20V:Wڷ!M_50xR}ty\ڃ0,npH}A|/.F h/ee!wȓІϯb~Xz ^D\$&<:UcLV]EO=?&}z_qL|&-Y'emq= /"ܗT^Ly)hciR;ȧ?:=֕?`hv IDATkm1 \~" [ߪwc+^ZlXA _ᅴ 3x:ƈ뎥q l'_`E]r Z=W[/~{mozoCfぱpō}xepLyT\ {#CeOU_V?24Ooyy Jr3╯+_m4m(9P URQotlQ4(\]I47CϜk-Y\u"NhyYq9gVNoISϑ8`  Ex޹]!^HrxiYqgpyL!+67$+xadS*KQPV? :(_ >mA#D@"V# T#@,J1yYw@ނ "MC1(LyE h'![KO.zgxºRhy;CgR>6sm-{sWTvFc|;:5*,Kbʱ,<0VYDEyzFMY Oķ\i|U3Pqs~8\;_|Lodj"e\/+IZmWܡQ+/yA-/(]@TTF^UmW}9dYb{U\֫,-4_8('AoS Xme1ntzMcW kJHP$`oD0kw5Nu][yG;>tX(h 4 ȶNM R#/BK%R [E@oflK<; HSL q;X *6 +}a!e--?=C!{pqzLXԃ-n̒ fјd!'ǂVu>4;3 2 `Qfy(V\|s0MOl??FC&ʩ+C%@'6^X*`61H#@*+V Lt]`k%\k2Q 6rq <:\epi=^ŖnLo6aQ2ÇwVnJFv|meG1$|xȊD:&3ᡍK2`h.il3gW!P"'z.LJ2)BW1r~2ߕ6x&Qig= u#hL~Z=U#ыZԬ2 #<+e 뚺@Lmfazt}{g5Oi]xրuiڞ㊾p2%,8aq_Ahv6=q +9D~OԬvׅLt]ǐ@e{W$W $Eڒ8a4JRÊc0[LxW$]}9hp9gnyEkxO>~=YՋ⯿tUC9p3˻CF%7oġu?z 켔e{K3!^؅=inN.~ީ(gs  W=wE:о>΍E9d'E~r MrE(4L/̾?16nnIWrOnp͉֭+̮?9ߔɯG8j'$Q/45_a$chp/aH+Azn(1၀(([Za^79mGVU*sGaLz(,,"^wt4^%A<-G;\=%_ p|9 s>{l(VRggr8h*KQpAvZ7~Fo =lSq-Kz qLlWHNXi(dHiK|*OMkaWxB1l( . F&G`WJ.]Ctx#eF| 2DG̶ 'jo)|UPvBFKOurKvUj^2 u}g&tJOA[n>!?mW 5} y 1g\'tq&|w3O/9)p<|)n0S\őPU_A:[yҙzw?W*$|Kݣ>oyK;tOa/p /%c^N<r.ޅWW_hGfڿ϶x ?{ON=uG}ȿvc5'zρ6{U~i_~/,禬[!ڍmÇK nǖxOV>{$:uq02`aK_~v㝇ڳ}6cO G=?u/;(_{_-/odw?k.l_}Oߥ*-ܱ}҂ƌ]ڵ7ޓ|-jXYnܵ뛣zx$VO2t' |{E/`J#i8 +7i=Gz04S"0$BfggQxi(1˼+ۄrNZ/bXƂ@p@(+]J˸󥼵_NAV#T|0aUv$U $Gʵ\bGPf[a'(M6P&ELJ5E*_diC|)x*m>rsoM+,%Gxg0as8%Oe%~qGk B,_P]ZUdTuR2ew+ƗcԯƆ,N|=GT7Ӵ[o-]U]wͪnK۸F'=$Ѹh  F10wpޫkznq}z.svιދTTqf_R^ZFqwV#"DP~e"Ho[LX^6EYU^Q|* EkK ùl2dúUaN.a'Gj`A/F2=ho-S^W6VIZ#)L[ W=D;w;򫆁,rVԢj /.%} \xCcMne2L=y6\,ݹ @݈b7/Y@8^Q#{WeGa5 XGD~0C;"W1q+lhҥ|̳j>Q ;<ODP~2Vn¤ Kq 2nQ<Iϴn;0+ߎ(idK.rOڇițm!#lB7 Hc V%g9EUV:نC8b p39~aeeײB'+%ާ9$ѶC< V{by) W?+>P'o}[ogn#]/BB~y˝|W$QG.W t}^%\!wM\޲߼}/+r#ƣ޿͜-wqfmM9Q ˺kaܴ}G9ۗ N]rwfZZ0r!`[.wMk!ըg?x?2j#ogأ~sn?j6́eU:sT~q;1G)?53*翻q'=|A~6yWڣn۟a/4vsk񷆿yQx_/ק=Xs03k.^u|wWu͟Jnt3Olk3}sߔ =/FdaƘiVW`:?U!ŗ8u% OF&i3O·ʥrށELC 9{ͮD!""F9@n˓_bJYG7"ȳ BݔgxF!'0 BKCWNYCفq$+@gJu V׈1%$#zA/CI,Px HPex}ü/d@mȡi_F(׋^w1F-Cڭ  (ô븏=\VU0@C߽ (n^UCձh#̇v8t\1^ °@ {Lrʎ4JN8EMz+ʪ-eS։WazO,xʃXgH}a={ô2n{霰S_}h;P,_p"#r6KW!my)z)A es}~NkT_:R8ΦmG-/ kp DǵܝhF0w<=ۛI(yg"q @ I$&tfQ6a* U״gxKd biԷiS@^lm^}Y߭۴{RZ U}뵢tN=&ξ"CXe O,3(Qݡ}k.dyj۶OmsT{ߝկ~5!7XWW^]lUGpU[Dy\6(s@P]p?>m~n~||W wYNj؝PDۧa#o/?zKX?0lwk-e@X ~niV<;GǡBhW -;&_Jx?@ɹ [8náetC5J0nkBx;nl X2OK0ϖue+wᶋP,Q0|l\I(/ IMٝ_+# ΐ=ĺ!QO(O$+Fnon%/u ԍ{Z8YF.n0u4,ܫ\w>l*nBto1kícEu't@ع3묦ob[H1NmUGWݵM/\/2?NN7W4. @"""->6V忼6T?A Nb,cP.|37^|hZOCo<'Q-5\5pl! X9_' )+9lh˂޺t" NڪYiС#۴ifrxU#ҴAs/zar?;' GDO4ѠDOy1[kJ䀾liEzQ>YYe^jq`? ǠC;>K9ZF=44? _]~+_-Vl(x~l[9΁Q [E?q{W-K#ߧ~@Pk8r^im;byَ߿qպ`N"T]!:vV?,)ߑ2uFYoR?a][Q8C&’T0A! bUSg4m %φYj#9rU8~lqSDQy㑦^0&*M]tE?Ll!sJ:nеr|o$dHWp_e!"3:-S^^&ÔdOiԧtV&E:FY#Pu(0)om:\ׄop }_bi&m3S\a-l#ҫ#?X704OSv Ϭ$.EN2|"K p ̦UU#@9"w]4F (Lbb,<ʑYٔ)!Ի_ܯ/#v%_a˲~xue #n'1 r50?fqPO+t+=@,=uW ^-z)=@llx$ /p]tf >:cIp4z_p)S<*2$KPT FH\Jn,'v.+H$8äyO*$֏ "d嚞}߁FH:$3xE9iO|Uw+w8r;^JX9=gYbr?RzA=:o:EWV<?餓i/:lX|\p)Wأ+nY/M/*GrY/-7\.׾H`"s><)kV,_ ^vN >u0k/4(CU };rчm7y/DYE/(y>q|f3NmA{{I9^9ӟ̱ӻ/(Q3T"mO#k QzǶs}}p7G$Dx!RmJ87LGvԆ~-(N_Oxn{~xM {&.VsCJ &}5g'&Rw ̾b/N>¾ |nz@#F-N1ȑ~jcpP!L Vx)2 ?aJ|%OY/O-SZ yPe#A:4~ OiEҲQT#-ZVyι7{yk>r  Msu! rqO,T?7[.oʡw<8=Y~ vU +xXf`]dS"n=]碠cd,Щ *'8egeyb8T@pfSSF+z8GUhvLLiW=װi .3\CSi& )!u)9@Mʮz&rȻjhٳ^8rj/ ixB+8;DdAWX!wrulAQT]yfVY9ʉHkeӁC0Le\u@>-54Anz֧W`W!W0(I7yIYbcAըG.$J]OTC Y^"/+ݶ C6@Txy줭n,vp?ps*;H\iߒ'5H,R?n$Ȟ}MYkɫuy-0l*.`vlYݼLȭgFtzXxd)rg\-CZVÁ2"JԭwviAtѭIC9&9'iPwn+bLne9:r` B}`s~wAO{Aq~Y,vT y-:F?/2pDyQ[=|.g%I<[iGQޭ[ir_\΄Epo7wj=(L3}iZ!ccC{D外 >ZEiX'ߓ|<,Դ+iU 3$3prH+tw;r? w.=W=dGY1tIR+[ +r5=DX?+rFU8hgtut7_˝°e+j8"d=)B(7 16xh$2*3P梄[M/ad d. mW9t¬O'ERIT_qmƹ"?ͫ q.濢u_wb {؃sgIN^+߸Uݵ|;Wq+ʅ屿r}zmghm nǥRtڲ~\r_| .^Wfvo-cIx|V9缱:[sg}Seݚ= ,+Xº?sDb~y]=c Vֽ.o>iP{@EӬ;ER!+ΉDⷊ 9FlU5z/l,J'#e9)D'1@P5޳@8D@04j(p:2FԈC>TQ_B( z-}OZE-2Ƈf;*U8IY&22<$ESQAْd"x+yT!5Y'o*f@R_~!TJe#TOf'l&TIR-DN]uWKz!zt-|sU F.1ڱ . exjCO3z:}tP}AƠEJ>n顳1ep5jy(LSo:>M1Eio)$[1'^#*GgrR4RY|V2D)@0Zy 1V hq6"wjϟVɷMjl\DU PHmWۋO}9ϒw3|~Jrb>'g1緽}+Ph%VVkVIW)/_<)`$TP{^(̩(Sşw;yDq^`~UY5(빽`; Q0ˡNZ9?@݂Ul8߭#Le¼K4#x GyFNɔ/ohtK:b'TF`jhP60fi(F`1t5AdD GZ6]{fAV= kLg)% /ʹn6@Hڭ*`!y$DG)NnPa+)-NK'Sʧβy oJ{b&Wu~Ixа4I;%pފ2Gގ2<#@|:(潽,D{iGWfK[Á+Zdt`6 8g'UX R6tpb%eꥰo< D:HS#Bo2zŜF uN[nqۆ<~pRvTk4Tk] `XiEU@j(U߬>peZNz뀝Q$!h.,Hϐ9Өmٲ&x-\UOחׯG>a-9-ڽ'}:qLyaƛvg=xD{- \)&6JGEa7޸3*"w~ئ+n,W? ar_ >.+6^`tvA ]wYqe<*NR6B\#}tr2ķ< /lI^k޺Bh08_3J5o4\ G 0Hܶax1~f"r]hOmN MٶY ۿ g`X8m{6([ ~|Rl{։\`b4pvpz7_4i4 ƕGΠ0l Wfawp_. hcQ8V/Zc]s(D5PX>խPމ ;ezeT*zUς$ãɠr[ '-dv ;LT>9@}9?ً6b1o=\A&|pޛ313j*ΊCT;y\\>+9}+8xK9-/)]/}cg%_j*!%o-_2ȸ?MY} Ց^02jlIEO-'?rI,}kfتٳ SBy*>cN9]orW7K:s/G X6"!e]ڍ6\ޟ4K;I" x܆X*T)Á;-4oy-4@&m;fQb ! %qKĩ|GO ge$8X5٫TQfz"Ibۯ+y$h„Q@|YYâgp쫮h4BêQ>[#'q1TJ.ugj-!3a%,g6~K`z_mbjt\muZm|>ʎzވ>sρ>~~hkxMy;>d|%0DNL{nAY_󜷍eSpHBAWѹP4_rYO7UXI+xqn;$R(w>"hUzXUJs< PPt= [\?E 0;%EGXb%6zF: m9|7#*KceƯ]3ʵի6ʑ/\3%Lp  _4|BK#7_!Je{⤇:&ƈ{h} `?(=ю'k2o|+ gy x ۳rr߮]2F;5͗O%D&lV<j, pmY43an p'<wP28uʗ?wa>76'=O+_trݭbOE}Iy[^dS9W"o92XzϾ%<˷8F2߰m{9g=g1g=F|gn>6êy:_r;R3VkӞ}:uVGGKx^٢Pyj_M3H'?eON{ryYGo|Wȇ.(>@R;yf~ﻰFW򧯭<|'<|-w5[O<ͻ~eU̺h#9AdĥfBJ<ʷ;4݉}Evld)QIGQŗzsI(ayU.5 qWMtJQ\iF?5HE41Gƛ9tghR֥xʉ7 @rȈ ύ 3\\l7<⍴Or-I <_efֳZggux_Q}6yݣx3g sۊ4,Nߩ[XۭABe 7YNsρ>saQW]yl?{QǘG pb93 g՚tu Up oأsLy->L*\{e`8%Sʨ.ߴ/EP [ N$w<]WoQW02#R`++\t?9;OB僞 %h2p?a@My 4GY9?)O|[/?!N$E|?s+xvBK +,(gyY9M܀-v>uJ٥N:]Oٕg\ǑA4i!LQ&bzH<[4Nh[㬛ԓlN"ʤ˹[*b&n;jRお$̸*/vۯX`z+24^hEQVvQuW67)3>f*dd {8O.uV o{^}lng6r;q.[8Doh;`\(o_@xDzj{0N&~w0'Q2CFՒ,x%ɓp.1#eˇT8`do3L 'v}@{gP`iMwD~/--s{Oc@c0nx]bqc퀹n!|sezw4'an,S[?[7?ʧ+(CGyϗUc=/J+9[XgC=p!:ep!L_UFVt3;9CYm%|h`Lbe 0N^2\,o __#x»ߩ4C8|mڇxVϻuo٨/l1UV .<{_$ @km#<ZLK3f2J{䷈9 i  dL]lgPl0bҞ1X$!8]Bwhx&(tN^OBCl-]_P7ffnSNdsP@L縐Zm]9[7qI̟T^f8SG\^:Q:t/elGۙHC!Mo˾@8@}9@% (2{1GʣFFdл=矺a|FVQp\Ϫ>22bL̙(L䍁?YuAwš[Vq>/%HÕ"|'ϡ.Fn ॡ':u uMq9M%7ܢHFf>mz@el4A~1'Fsb0@NAhf>8z.*Q`\?RnȊ"̣\<uI\5:gx8E@uWS{ yM2N.7= I/T]bgȲlM λ۾8.,RDV7PjES7N~hLG>JRlW!Ʃ zTߚ7 re+s8XdbTpp޳CJyLH _˫$v`h] "fSNfZBk "g!Q8R?elպiKCGNÐgYsYwW~#҈MHߨqwF16FNkTӘ2 fРqo?}kč2veJ$N hm+-eڏUuy+/!B&32M#t0 g_#n5萟s֑u>~0ٜphG$A6"#޴ʿxEĩӶ[y*[9@}93@U_`U;vr sp#d),)9'Lн^Uzy{"ۣ +#2RoNCć9v ~PtU𸊞S)7gG!RVV˜i,/+q}t gWB#ϕL|ǂ2(4Ǯ+y2ڪ| y4>t3_z#Nt{a"^+=ͰJ8H& 'Vy ގ'Œ m6oRASw~yAPT+ $?ix MK+97޸Q'i?<R#mQ3i+Pg c`X_ KzHWWc Mz5wJoY,}H%F$\\-߲ʭQ;Ms@Z;QF^:9+2K l+Xp<ʿ(g=Q90@8GC 4h@qGA27)<쾁FJwc X,f*eiWkIOX aH05G/a_>DZ[a ѽwS i 4Wl#7(TX~ 5 % 7K{Q2iE"7T`ѯmVdʅ~[~< 䫊T$w\FVVy*dNY0yxleC:U ><vVTEVj#9H#Ոډ~͟T0~I-7rv6@j9F /N$h1yu(M UC@Xu& 3(vTGL3FOXxaK1o-&24ڙV @"~;|$/k`~qz6W Nש:A#bkK+KIsρ_2DfnSawRiS}ك8tƼKˑ*LwpudtsSfd@r z3B<+m\UI'SBH9Iُg`yh\5|?6⎂#Wt: ucy`#w+aD5PQ`W~65zJĸP 7!8UCz\[fGu\W-x1A˲&nc,"8kq$G"Op5:4ܸž+PJY]y $y;M]\;TvԸP0SeI05:H rg?68"VZaA俉# WPdX6Z"*ޞ͐ 'f*^Gz_w ٳ7VO-9(\ aq]LTo.,'`!)'n";9- .3D\(Vi*%WB%BWm󲂺BޥoP?Ңr5 aW8Bf`z!,eN:Cab B+Ǿb?wfAҶBI >M[8mU {W 0($>͐B!ϲTJ#ʻjX:;Ɛ4ZqRV qј9\<#ZixjGCE-b5mg4lҨW`Q3SOKqtE£WxvnaIIov[$Gҝ#Ju`p鮭 ˻EH4q@82lițfq̺rf0.a*z8Ew@CX]K@M0_+lp`p֨TXT4%W}2ESwޕ'? ?A=xJ :Vwd Fƕfʗ!-7e w\f}!E/<.J6yGq=-,/72܏"z,(yftI5@— Kfݏ`*n5 h!$I S) Q2`."jXP.ep+9\@( 8WӚO$ki/^T2DMT0 EāirFWB4JXxmXZpqLAf80(m善C\ p(}|*FqW{tf 432\7Ghxi.:+X>ώ=dx*mi騶 =*tREv$6Yol~~?ֲE'K[0t1V]Z'!ZiI;M[1|sJ<5 0 h"҆Yf} WÌ[~\ͨ ]LDڎRM۷< -yN-igŎUsj:sρ+ϑݙ#*:  IDAT+P<32:H [U%;q뎞k%ӿ23oEUQef=0ɉq1p9ֺؕ=!n6<3͙1CJd< (Z71+ yBؾABoz=^i(ďhbd S6pM%[d!G O~&/VՈC嫲 Sm Ph8l8~+r woyֳ $h8_qϼ5y7 3.&_XᅘJkCSSf:tR0tW4|N"1g]F9&h'[ xS$$: pk{< _ij@g-۲|h15"az/ ciKAN xSǖCMe[JyƧ< t_4Ӓf70sρ>~8Po`~cjSYގңԪ¦t wC&ۺ1+&NV\@F}Ώ%O':אn̿>l>'G9e%.2iVvµ^eV&ڱNREbi80)~w_60$ D1qFYw$ "xDJ%{n[ rھq[ e~,S \!/TF)oť@In BvP>dnsqu`˟(nXj&ꆩ% ,$RbjpTEwV7&5!è*D"$J7t槢"m+m0 # @8DaDy:2ud%MQ]"M[/u;_JzK"Á 0.:J}XvcۥA&+KNo 0+wZ< llWq2yrY3^:lmd2 ߺ;eێ8`+ ݷ/')jA|N!6G|^@iGfxPCK^'ylw6*? mk!<|YaAi7쀧igˋa{xt<[ꄛnE߂{#r!7}J~݆k:vs儻ݭ\|?SߒoYf>귁[o21v{¿NVMÔ<@m\-d=ݜC(֤u߽ \dG~=ߙ `JWMt-3мrD_tc(~fFS0Zfݶ'*~U]k"ul~Yy1y1\-L&݋ |8{sgF'dQ4$mh0 ]S+=Rn Gi gi'4HAxPy1U yt1( >ᨺ#×.i-.n@K<&sN6Wċ"QѺa'a3:^+喃\P,X'JvGvq/^"}7B" *fiarnf{ѧ!ZZ1D A>t՗ ¤ #YOja|=/\2V-=\X1Zˉ=n |uYzW=R2o;P6b×jx_MK>iՃxd/ ]^]$M`%=UH@XdA9-]aFa@^z>s:{چJ;+ĥgĵvʴԕo`|w[Yeڶ@D킁HJVmˡU`"ΉY3aLo [Z 2և.N$vezV psB3ƍܶh3 oԇ8il0JZdePTIH IC>* d. 8Q<e+Zygm^?.W^q>o:Zsn;"Nj^e<6^g"놦cM9\1OpoC$Q!ռ|%EBJ>^NVzVzX@/l|l,|'™bȸ+03Cmt hߜX[Obcᰊ?ʸeɈ|h@UQVr$WQSʚQS`DlVʳJّ]ހzt_&l=x\WZT,KUxeV NwyeuW&А!=?`.~/pR+ܤiixxg @k̻+Qj)4׶Y``{mQbia|c؋lZ#ϩM^TD"MŘ`[fr`" bEFP?YF|wS^zcKU߿:+"EF۹Tt xsݜelJ'Z*/x5HF $~4WqoTG74FY Uǀ•sSik`% xPX#'p^oFhijQ4є]0Tk&UhOڸ/-y%iMVՓ =0i6Ϳ ,`J|tkō:fQ?PW QtZ9֭ 0i} 0/ t~|֫}s q.h?G0,A%xȏv mFĀ‚MgݘV~yTˆZ3(6I1p,kP%J['3gǢ^Y\+|[FKme^z>>wS~9ϹUh7ʣ/'VS+Cr衇?ye/'~;);v({\?^=~| _(}Â=kfRTEX(D''(,О! `BTٵ[tvƷgJ7/ߑHЇkEٚBUV瀷D* _AT׫ #_j=w-nfHBǀ`t\oWfz`+A)s(>#t 6o$8ϊUm)?||l(;nF O~W%Ȩ0\b/n´cז9ccpIJjD0+c`vu.?76D?jhqz1Vy7eJ"vu5I\hI9neJbm- +99ca4DDVvSt ըWdn,("gp~6: s<̗|QM P)вBliEd$^]-"? VT]{Te#*' Ӻy5<(OxHsV$/)gE^{f!(>sXe}?z D%DQ%|YL+:xFw kd !o=̓͡A֥9 +5d- jHZ=x@t{% e7T #eA9|0E*q*d]4*􏬄栋R?c$kRg(![@Qڊy|dQ]#* ~傰}B]@˃S.d^1x!{aσ#[R¡/IhqM\pxͱ`en'Wta@>,d4AB"\/nS eA?y1m0iBC#[Sqld`0Ou3߭0m!$Fv~_ohi=N%}9Jhuvh[4 cH!A r(_._]yLH frT*gau1|08k,D뒒wS CE-GP&|@/Pқ7&zO xA&mOFBQ'#>}71>ŊyR.hvGctnipb1 lr/O%vDo|z$I88Ox wm&ȭł W]T]*><4xXCMXh@BXx[S@y2yFuQ!`fnk!"w#=#+7߿9װ~}._ү.p܍zֳe_-qQGez)FWUO<|sR|ꩧr슄|ʇ>%-]~˸ݖ5U,k֬)wQW>/sρ>~Y9yIZ#[ݸ7Y? wp9FCIr|ܞx~t󒭴dRF5"8{,{ ̼tBuq&LEi9S3+1@H l99nu1ų Yk!xF;0.,Oi#Ϳxl4Aa÷L+Mzo-?dȥ8eO4ea\+c]gx[oP:N13]c+14m;E?oR3m<9PL=ۀf.䏢,~fیСݻ/[/hsfqqVYXb쟺8i g҃_L OmDU.`Ӯ}zg3|+Fl@ۋj;roΥP^a lRFTEz{xefC4|t03ax1.xx8+! d#V=k8axk\sƹo\\;+'JGo(1iC.xE`Xi5NOixkCˁ24 ܺ.)\y:LхB@:y$$F>!yZvz(>$kurt)UbetݡBڨ?a({kgYiB.7-W_ͯzCZjH H  V@ `XȲL;I$b[^yRJ IDATWs}Un"a w{9>$);0c+"CxpG(WGjf@ wvM-1 |EQ*#%_J30ur@͸[94,ܯ/'j( '%,>V.;(^ߜ7 H.{P$~D~P8G Q5rd~i$cqA~=I_9jO";6W+v xP- !,K:Cعud!> : "W. j"_/y#ǥ^XX\wvxֳhz-هW˿{ܲ=qDf<-]>_hyz, xCϟMZ^l/o'~rɓkK]9sl:90\ZS猑zvÎnlvG1 g154Ȇ&ef'Fym̸^Nyh֏`./Gwnf_}yG9%qP?om@v: sAza8P |:nyybdkܖscsᐸYCBgˑ:`Y"uN05Зy|gd~= [zp0kAI0P!z'q3aYVIۨpv 30]NV Ӂfq7Y` p&Ʒls0S Zoa?>.CIr4 k ^bӢW-)4ZWG"38>ᆌo?8}S6h\x1ڰ 0{vرwy߽C?[ ,8 !Qf\{tǏӒ1s-l4,ݜfԦ_rÎS|tPp#/;}L5˱H{%GqF`a/ppY`F[ 2}}c8* DFƒIm uT}i gL֢)S yBkk Z+zT,}-o_]UZQ.1B5qF2(~qg=&6SEwgqm6u 5IfDX6qp« c#}vƿK`0򙴀ǥ #=:L, TurVT?-.90Wz$.kh8i&" F F6VdG x[Xլd+( fcy fcMg,CmCY 8y$ ]f0 _g6{U=Ad80QtaS\[/1V.rM?w3LaIgO pCCnsc Lg<8ߙ,8hxd(8ؓ2̶74B߿,ԔQ1>M߿ A^DKe+TPGPɠbO>h93D ?&zfQ(L;^يW6^Fv]~{ol Ole/vǛaPټ^>Ᏼ_7wWҗSI˧/vڵ~6`?OO!c90gYi;zC\5QhGOj }kx@舉>6:agє2|p6 r4\~}O _0=}-z@ o|gck,o$0>2#@qu {9Ux%@#TݰWC7WciLט1C33z:0ZX|1ڏ/ :{jZdRE,Q'gٻ,b1lp>sf{t@@< 44x*&,Zu)QPqqW~\ ozgvF nҨlqwsJKHQn(G~6e9,H@MK\j 033Sę!uf!cp$Kc‰~Na*k:i" :9u{5`ýpY9*=x v[&9tvy'vpOdOX꾦׶rƻF\7 a="9;X;Y T"_ |P@{UcbR| "Pn&{(oFNؖ8PlMO thH9Ux m>R~*<+C;)kyr԰5/ZȫޭIw~OcFI p~1M.<{M'v+Í#l~zS-Ȫ e#HxzrY(K*xISdƴ44:~4P- x.C't[?2 ^O74Ozz _Wc#9\l}H◼}˷}+^9 9_5pW7?~~E/|J;{tMvv@kБW Ȭgbp1ch IE,ֺQwU [7ǣyy=1${» 8p!8O tK[KIcۍIz*SG?p; #W1 Cu+'OΒPr'!|B3;gl.YJxGʈW` &LPtxҩK<ӚT| o0O0 m>wG+ q#o|- xé S:L12;6Z9|#|8oy{kY9irNI1(<)+'vB\xD!¿*7 9߆ 3CUnH[uQI'ߪÔ/0xW#ɣF#]a,_ylǹ%bt .`pe _}l|\JA^xߒ4s`́/8?yۯ|eVC&#(N~ʱ[z)wfZۮaNpÿэ;֦pNg1Hg/ 3m/ǩЫX(@S`ӝnX lY[=WqQyCot@g 7B"3hUc$-8y3:]#|=]|`MC C | nqxyU~ylrY}26{&.=tLt42t# ͢U,\$}pSLޑ(/*ųN Q,i{ˁrKcsW$eX[̔wFX|p ψ)o9~ ‹;@Coz NM!~VGmZx몑Adz7/^@eޥ&Hr0qҳhbmUdܼk=&RWHht߶Sl0uVn7?E8LV^@ c*k6KZ1{_MM6g We#9;b3W7cE0qb=q}ҧ;J-.:J0πd\˻o\ioP4e׻5M}= ըfAp-oo 3 5Gi%qX //k;S9DM:_HVN0a{z |.Z3cf"G #@t겆t%E2ʌL]򓲕^}: f3@g{d46.26t ԅȺٙF),C`7 K8'\f'/iJ \_pGJj$[6֫u(-0)`͕nD0dRxFz6h#N4`L?m&hs4"qRΔ ȏ"GVY@j82S!- EiC ~8:BSc#vK tj6X[: Oz$ԏ$\>M6~B/$Z>qc9@6SOb a}nN#J=.tmY:`:v q: z)ie`CWJ3Q W4x>_U8F[_o/wAΎQ^d? 8b>y;CgБpmZO5Xgz{āAp&4ɛG= ="g G'Ś? IDATo<7#@]L:;kLX-6z{L0|2?~0&&" 4ds2lX8q<6p+ |pS$l` 墠 Н]L aL{:qWWtJ)&s&` S68?Ƶٰ!낇52¬~ ,{Ɏkq?G!\<ѥ.'<R[5, j3; OBAĥ \Pi< /. 2* q>IYREH|4[LјP'9wr`qx*8nR gC mFn]_yTRoèɿʕD$F /_^\WUNgwS&qF]h;Z\"rq~^ʉK&Ҩ_uv$|ZnHi[v-(H|ۄXl;m<i6TumEgt3huh_6txezU<O 2.p;muv P<2o xh!^j8&Z^a8l_/x`WȎ3+`*+\:9e )@ qːVh0Ce\4@h@xt )\1#po7썳.f} {y;h8;K0w:'#| ]d1 "N\" UEEo0%YFMr ȞG0XAZ46^Gpš n#ۙ V*ˇ8x+'=Hy9^3:]F\ Gfs}F&~% Y* n*~? MD-NdG-p'a^. 'LS%K%uriD_t"9^ #()/oxf'';+GYY?.\p#|”;1IݵȴKPR&pf#N~1u;>\^ש3+0]"Ouͳ wzyũq?N)ؼdQsNN0oQBNFWm_"bQpRϒc6#L0k!e6. \O7xx(Ю͟XN 9,Nz ~uv~%⣠'3-opn "\"o9Ig814TRJaQ/BF% ~"! Ry4 &Eq_h<=wgDW 1aPO{h4)Dk^HL(:BCF%xhQQb߁H"`s>z~r<FyUxa8l]ԺhvҪ$!*8LKcW<,>,}:OaWǯc90c|9n,z"]ؐMVPW]@&s,Yzafnj_W>n#xe;T`R F.6#4Ȩy;<7/{މ/?w#ԑ\ l 6neZF~pS?S.s,H<{DS-8=L[ZH6RH044+QyxtO>Rը(<$S9mzJ"e208_qV!k)'V ڠێf뽐6iH$,^W2r;3׈p5yg8K45|]*@8W1Nȷ0]ٷʵYi` Z9G [_68%@|wO& nzwsCq ^xAZ\ :p c# w5 Ùq|h۽>m_w0(7}Dۺ;[40 DhdbZ>K\yݤX)|0g#sGniWF#w|YQ Ud`'2$kIxolSchwSi]c ,<Zx/803>K i̳&21}dږi;sl^kmG7N$%z׊eИ7W(/+yG8lda9h $I#3o)wkd0b:^Yִ~yMuO8A'\ڜE  .:~Wi]pʘTi/[eZO{HcZ<1߈kȻ6bxG8choy)/6yOP˹k?r@KOl@Ir;W.;hϮte?%<~5IH9r5WR'SzO߭[0%ki\Y\ϼrYF0>rQ:ߵ <s`́1xp~.M~'ƍ}yXf:N7xf tuκK+(̳w)nІaȽƱ/IKX i4atѾK^]}$,bh@ O\M40 D4t`0a&co9uCc;RL1-qԇ8uktH wfŅlts⬾3o#8{ni(].(~=L:BUHSO', ԥ u2 }kqF"c,Oبqn#SAӺ4BƛQ \MC7! ~1 c>PH U卭d)|3dՈo2uHM'6˒r8(ײNNᇿeaX1|;?C>zp9#KYܰ1">7svRxAΦI6ضF(6Ed0,$ vIC ҡ2'NwF$ublƽFQ{:7bZg4; U O.mP&[3@ǀ{`|.qIAڏooIj+0=(|Sq5O @C-S5 #FPYٷ[9:J V2&Pok;*I=e̷!-G@.d Gr,PHI.ѐ) R#Zx'<[úIOuHIy oo~HTvwuOۘc90+Q*v3 %}yηO{?kH/5idz8|1"l}/ॾNDeA <ϓ:@rj:k~YV,W?yKqzUu\!H8rUh&?l]@ =2bQ[D+y 67Pv&ƒрq^l djXMg}LY':uNcem:]Rp. 0<Va')!e8CF5ML? g~z*Bý1`ʉZX&QS2) Y! ơ qwrgvQ1F@<;;&qYob[_q >\w0}O8:~n:VsC=kERzg tkQMמ'w(` Yaf&8].w+ё"SShY!T;{D6YҶ^Hɉ \. "Y)m,@`G0Y·Rn=wLn_``x|=8Ѿ%߁vcCCoh宏݅rrR;R;w|pB[]>ʣGG##GIOxBth]|zt{ov;uv8 px I@3Q9b:M=&ȓGs=y@2Z b\)? g68$~/qH:> #8jS˶dftq^X;MwD&%ƪQm=ˏ8y+{PNըeӤ'Uʿù뵼c hK'LQ'Yf;?? |S&@OWpm*aup;q8@/J[ <2I^~"tmhgC)D$RV+C|XƐFƁq"Q{ vy.p ΂tiTlFʻ2cc۩OպhTor g&r;a?rLVEL}x=Әc90=._9;;;QgG;.NR1֧O Ĉ,Əգe* lNqn9EG74r^7g\~0ѝ5i稺pimL_sewςt#9`M \eW3B3;3CгFD+ DԮ1c#tZr EނTD4^88nuO&`-bfYu 8q7+ r-rhS0Zf6Ghɐ#yUHQ C8x]NNJZ|$8ԨLPDx>6p!jfJk.ַe6E,;_."F=yQd/ 9 6r 4 L!PgN) bGV›2ϴ~NU(9rCE1Q<ހzsm=FĎ OZ N{ Hz(=e{`<epW:{AAupiQrہɗ5TYgsByOC^\ ,%.5wR808]>I˭q :rSFmt÷|½_%Ze\ťvElJ\$}P<(<@0ʆLl HAq X ;'@1;ȫH7oN1;B3T2XWIpc}kYdz>;nN΢Z_c90c|>9@>{C=eFeaf Gq@1D?W3}ѷ/aV_L_ChM'ska`P<}3N8A#rMdj pU0e^ IDATa֟`S_;"S Qg?К麉 >.ԬT*~< LǗzLvOHW{rz8x[M|@ȎSrbhiAYF! Cb@re~PPRB?|ap~2[m̺!gl =QrupгYNVuT^>Jy8〩qn8XYȂEpr8.=NQoG> cAc,|ŮtcAg7.xiI柁|u8CcȜ @Fk/0?e8PW5 4>z" LN'P}EYǸC=/@ Nۈ!(,B0]`lv7|WBlG  I' tǝ\i|KK_gݟo?Վe/{ȯL9ԒWV7l؞[(Q;|r ]IOmyeu{~_vpq}+_/Ugoۙ'} :2KsÃƳiYDS'`Yvΐ0\;xol쥼,cgL3ã\/Lo\+={Są #Fmzud sg19C BuFؘXCo=@wH(pwG~%|`D#i۩J+\KGp;F;xdV$FP b?! w+LgE9N ,#[إ{cGݰ@Kϳq ilRJ+m$;qUV)ݜA:uoYa+V恞:~uc>fd_.m-'iA +z7f|Fb=tSd88]ùH@u* HhV f4F("6H䟣B([v݅ \VqS}DMwMwt|֠"<RRl$J ,3 mE3iΝko8nط +oo_+o|[W??ϼO??~'~ԫ׶}yj\h7[DnhAs׽.N0]iW-[J[Fe[|ͪpY #aH'*etwZYakl2*3sJ)w5΂C!40eoƱWI*3rr<?r{5,\z`#呲 1#8͏+#z/fQ]<OȢy)dd~),nS#OzIGj="3]@2#ni0JJ곴%(Nge+< g) 7Эl`Q.._JzG[Gtḱ108xT{9jyey*4*<Ԟ[nv`#ףvkLtU^ZXt:ǖ mqivݍ6dF@ $EQ!FZydH}] >3{&k -N_Y`oAfEnAjx,*N##` LutB(-;SsHO*8?fotqs #x*K6°\td+{LfT=<.\wVʃi|{Q .L iz;XAuu^WZ$n$ &<04aux2ӦٲãtbY7[S'..G1tswy*:E*& `ȇ||P3>#/gAAM9Dvqi ЩlNr ^ c:7˶yI|@`X~cK,~PGGY$=YïR6 o;Ξzf H |wK# ΢aZNS8Y\cOFsQhoYD!0e4UfˌdfbǤx"GР! a5T#AP@Lf:a'DSso!\ %b{VO%8 g4 4`Yn/{_k/^`Di@7ڡ[O='PW?W~y_~oj?_Mо;/H!uUa{'Ep/c?CMKWlP*Ov+Fh Bxu<)YV +JI)yq.Hk"ĵy*Gí$=JCWeAY RR|[f UFv zs<#XNEK <9!^"k93QfK`K¬|ax>X/V  CxT1Zp+Vt!]jș:! wP2Y<03NYDZ]ܱU#x犍8ZpHdQ>4rH:[}Z[F97xC_y7233!w%kDP.eHyѹ=dz$SMN>Ĩ &ۓn[jz{Ηڋֿ o~iu/fW}Km/?NC]u}T,p !k(3x<4E)™U:t%8ݽ Nd 4Gd"WF}W:ҐSY^kT?8(6`S xڣE ޖ1Xi(j*K j !a)#e0N߁'ʷdjへ‘Ms|t:TMg_8c!GMJ ,wᷟ0^(?I',Oh/%۶hqd;cLGRg}^8PSROpn1zS)0__'ڹ}[Ӈj7wqYW F'ɀ>d7IpoXࠫ@jwKHfo(.LܧRz#[ɺxv@}6}FṰ)'LYL2QsS?JI܍%ZLt<" Pe#}eE\n|iaK9m_!0Y8M<<!8ZֽC;Q``N~,tflI0tqNe:E7;%^N# /M'nih S"l5\#é[>I=T/gfHw.CAT&a0I S ;w@ 8 3Q^ȿ84X'ᓳf-͞8A8p`sf{A~O%& O<_S@:Q\{<+ u ȲߤrB8MMɎ>Fi@s62Eai3p&0 ,o TwzίAy+PA^fvׇ?04ad0|5> L[wi{ HFp>͛宏q;SClħ<-_5Fh>ٞCԾ_w|뗷W}7{b$΀_wzW?|_yc`@ë¶||_~ٟYUwMwᅛ8hfɀF 4řc>Ոc^KM is~4 `w pLJc9+ e&? 7I&Ksl'A»efCkH궸yF 8ߓTN(Zos"Nḱ1}[n}Ynn׮^Pg_З}2;gty#K#fcQruU#r::zNs~3ˑ6XXڲ_g$}NCC2|Q ឰY6u Ҁ{9ԱM0&Č~]6TFsLAr,',*7KK\o@DF"O7 <'5W ;)Du΀N6!amahjkzL= ֹt=}o: 1颟㑣`.q#R{L†g 6/_c?8/B680ΒO8{e_klSd }3Wt!ѥ ő3#{ 8$ T؄hku5JYMv*1hdN 6\1 / haG&X( ~FK58ka2݂g*_?m}{* QF #%6p?(luW{/~\{ ];ծ\Nδ{Xo_ڟB;w~o0_~{{h?/k{k~\c“ng g8L9ɟTc!q\\FNhV#i#͚o/Zʯ '׍H*Ri)gp]i" `䍗ʖ 4*7eSZ5$ W +G!NT)JY'i{\5tQL>W<&5L\eao:okoCGVth9F{}vƀrB,iy\!'K%c N4Ls.p&d PDn 8S4"Ζg|W\/5n8-y<ЙC?yq#u\م.4S/b:1@CEKL[Z7ikpyBuzSadL&Y,btϲAqj6|tdP-w=jjQxS\kx&] `wuϬzfW%<_F9].[Q X P$}0Cx#cx.Euɺj5u>]Q'1e'g1 3zoFɡ7tߴWPf6:VEc~D0@e#zGL)WIAsκm/e=4"(M9ETuQ1ckQ*[A,Ȥ*`dcHNngpFA~0#.lt@y-rFO N^7"Ϥ1w #$"-m>vǮY^ l󔗴ZKћh,kCd-eʊq&TD }KWCOF}: >bY;rId=L$߁7Q AG'pIpu|nF8Ϻ;^o \G3h\d^#lK#lޒPmr6s`́1x$r>>Kl C 鞱FNC<ňv癪9NAwTmfzYweb0ѿN p64dvnڃ+2bAu|v1ƆN)7ODADG bсx/*;q=F6יu)_FS>-)Ldd]X{Q+aL5B񬑪aOj)ql@Bx _dG".'^w9=/ė|mR6xwyN<_ DDOʹT3-³`T3(_yI8a #z"QjwѿF+s<NCRZhQ:pfT>!p`={9uc _'X1=:h}pCaʲp0ߥ ae16W';8: vylG+fds|Q$fuVIyn7$C)_q8Ψ0WcYpQAXZ"]Ae ӄ`Fna?FQ K|X2.*.DFd`H 1̂`su# 2`00!te+D67TJ]^cgw|clv=^=ߕtnw}=mum;~=pt{/r:z;~dy</h'O`)3(ėw7~4~:t][GI\c"o)L-a_5j5|Y"2eN#vST07?"t4Pej?8#e-K?X('}ּu:ICIUC@a\S.1e+ 5т)k\l_9Ol`ɋ\˩'GԁZXFM& l5@"u[eq17g(J(?,NI6^[g8+b=co7qZ}]St,Kg[vI=eu}gѫ|g[hko{[zӟ6h+ېb|}8{vϹN]X;9zD'w'{3s}2ԗOjS]v{rOߖ[[zmɒi|byquc2͜nީV|Ǧ3z9Jz \cZ Fy9:Kiz *)9vNVC[g$u;e;1YYg7#,*P'_gNdh7M8+ thAsœeDx3FC7lLݦ}[P @U܄Pcu9gU$x,8TLc޽S`i6~V>`\dv]pF8>(,EQ\@ko`;C^Ml>w6wGtbp#!S]>t/w9YOzl4s7F$$:nFL { {vc)z 6eصPQC% ʲNC nBf]~,ԋv8|=7H9ų1o3-?'C}"1bE0Or9e4yŽ7vBkinGOY]9OŅAip=7>Fۆ QXAAMUl(ɒc;ufK$'n=$9'gwY+.˒%H <^|@6 P~ߔ;w)ΝsgDP?&j*F)P$mE;w>[{׿^Z9uʌ9Sv{oyˉ˼O}Ǯ ?F6|)njt=VFْw۽&3( e\R(sOI!vA1Q!йC:U(e } >aΘ pNZ16gRɐڝiz8*{88Л(sYQƪq;XBv-M%a/15?@pRv$L?SVl劲µ-b 7 dWڠ`S.Px>Ʃ֖8G"~Ғ'e{dfXa|Թa(J5(Lh(v`=v*8ɕ@=0AUF k q xyM!C]őa8FHq(p!e*lDdnVV+ +͵PZ#,K8df9 eRFu+umty(8|A°|#|թ(V%(dZ> &G~ VBI7pK8lY & 54Io:eQ: 0sc05ck5r&uY(c 8daY&B8?_!%p$ igAӮo<+ BŻmly}G* P[&Y-BtpᣓXfEXsZ-'5(!P`UM.w" q%\aPi"po&Skfr&̞%3։S4A&u4eE|&>gZysʩTo}֎ދKPo۝z4߽wD ;ߒJ؇Go-[ -Vi -;z| _%B*?ˢ0UWX~;9TN_6Pfy?% _;X]fTroW姮`3{(W\zU #2VuGׯ|/J1VL`Y2el>\;v}_J&rJ_:R7~(?(^ޙ;o l-+*{g1w:}YAQ檦AxŲ2phg=9{N "o㎲;mOlMz,nVcX?stJoVMOB]оCyS77qۙ,eq EsJM#:(`q-dI 4CEDcpEEWXl5FW`vUPk Vq[~(gPcn09@0Uj0'uQ{?*#J)C KH$( z$)Ja8[s"Eɦn eiKLv^ĺW7`@9Ťnt9ֱe)Fh*}Z !7&EL?r8D6u+KA{7JP|ji-si03ח@0sl*MJYLӃɏrdLR'Є@($()o׃gܙerp([ ܵ|-'4;4nq0aNBpJ;xk\O vd9Q*`H&YaOML*C*߷pHDL 7SXa)4s`Zn ` i (ba򍎶q|(ox<Xzu9'<bك⠿ p,́.p&X ^ -m)/+`c9a"?vy #dlLf/:w'[O><(Wf%e`E9Bu.(.sW'5? 3O l\a`)>\M7x~m|4xvzuʀM_2#827ܛѺOm|b@$1^w*D0*RA^ZOU|i;#l7֓Dmd[NVM,QH*#6(t?p*>&^k'ud-}6+(LN"]:hid6yz[G:1M]z΂47)X2Vt^я}<{PU w>gYrK?s'cew{=sĤ3;gaQfg8^^'V}`[_.˗L| fydxr,!;8qsf3\ZJEq9_m2M+vLME$DeO,iC(T6i̗4rTL4̞߅~M 5heDNeIH)HnϸMNJS |EX4ߣT@0j40AFL1Y&f (Lb*O,|# XK l`S^+ mZr}_T`L?Q9/(g8C$: ɜ[8;q](zXqQ GW)]T᧞< ez?eeT`mSG"]ؼ^R5ҷkHIBUMmjBg{meU'ID6*nzդE޹ȁݭ>䣺: `؄ (ϻ|%BnW-IޘI/XEiǪW*{Qy%Mij3|oiN ?B}d[Hly {Sf]yeqᅥcf}啲k_/K31V 8]G{'ʥ_Uݗxfi]YzfWvΉsȡIvZ-ްGd.06\N8e^;oNs9j!w/9ؖ8+o#R$aSoa҉_ۘTα OY˫_J3BAtFc[N뇗\v~hF)8`Al;vÍ <;l;Bu_2C ίxe7c IDAT@1t9'R[%=;v~sf:w׸Sg;짟h ž>O+>x)$NAҾݙ k|W탵^+IV-+ɮ,>4%[&|!Da̭5Wz ;j&=Tz[:p}^)c8@pЕLXCG\7$ |Qy D4WiO ䷸-`zɍ|V(iW7!Gy[k Δ&q=8UN^[v{講h͗ENDBadzꂝ뙧΂M; kG/$#owHg~KVqp!_; iNs%41a\JY_\de#◹p]1 jIcӮ(=য়m[XӺ9ϊ o0~#Yå]!exǣ ,N(d|b}9B+&$~"ƃ-I3Lb<95Uj P'qGw+-+@\DH8Ɍf~ a OBq@M^zacgwrc\s ZgoŸ~<3ϔs=+eŊӹA`k9iIMओOƂr֙g\p套6,Ɓ > K׎J?¤ .v,05_hvlpK'`Vc'zҘy ܣnY4@ӱdkߪScGl(屢 UU\ m.ZF2\x6DS4f7C\khSsu%g ٝnLZV^6B; h[6fxĿvkUnb sxÌugknͤt vQҁCCpEֺSB6rp:ݞBx T\C;m BG lRP<ʾ*O|y۰mcq9ᇕޯJs֓os,>m9$w N0q5垁孝;9p@o rOM gjfnF'`׿QrI7Ɗ͛Kgkg!"`+?231 k~mi~?o籂=^+3|Z!u=ESe2oAhVyg_X*oh2 _˓ bvtҍ$1PYHڷ֯/9\,~R\SsQxQHpU]owgvE=g/g+CX(P!ZasAf-PQ'ϗw1N_ L> gRu_Ҧ85=H/JÕvjX( cM6&MY%Zэ0 ,CѱmPLDGBUEXNmFGHRN*e+Et V2T7Z,XkmjBH6MC(57rDqі (\E ! J@Ț'sLO錢JPp :qaL8kW’ nk *xJL1Lߎ֧i5ĭoWc† 5ks0XlټX+Oz,Zo20ʎ=3oR[sNɣZ:n^Q>G-9s0Mm4=sn{.{a4[w|[zq~'rT5-_+u|Ҳ7܏,O#л߻-o~,wqWλi<. G8l{W~,XLaA=w׽ʉ?3ȮL11.YQKǻ\߸w¥ {kpږ2焙9s\?aCOI苭W jZ|_ٺ'~n+}`R0'lOb3%_5e4~{(7VLnn⎾Fěo=\mr\xmW D9~JГxY a]Mf^A%[6/ƱWm[6SWֽɧ Z0!CK OQm׾9X1OD0#5}0 pE`j= 0 *TNKWv!YG=k*>BghZe-RAQA9Ag499;o#\VЏ D>Jg?eEj {,|Vc[8 ŕ0~3Jf`_ƣfŵ&<([J'#xX׌yWMAv bT#p6C?Y;^\{ʜ@CsW ] gdYsy13n@p}އ˺o(_壷X0(;Q\W!TzV/>T?'U9>W:#hE#|&-ʓR}j4;F7˘{ g}x3 ^6Uxֳ´ GziPAK}K`Ynɓ=1(+7jR0j=œ.9~~xw3rZ=*A>*yBs8]xU8Ozsۀs|˞-4ZR~hd Ɯ XHSΥCj67!+PW^xT E20g4k{]7 X *zV҃"@˂!!?.g_8s`*f%ty:3y,c+pv_⌟yvB+M3#so?/ē|PX3S )H-LNC^ 'mڜlfE"rVӴ7Tlc~}@23}DW~hs%^A>V_<&!=Dgqgޜt*, @QPt0JjENRpJG 2Uu 6| s𡸐qsf-@a:y,aYW[/dn`=r:SAѸH sd'm\ e^@ҍFռ1wkDHk<@5_y(g˖ > .VjOyK1W80TKScls~=e]VuYSO)CA!; ?øU Cn\U̝39xG93!VS}~/p(kye}e?oʡ^,ǥ悛kSѣ΍epjJLLP8HgJڥ-FyL|y q aa`tXiis5p1+"ϐ.SmG߳np;iIǡ#(vr>vt| 3.H.Z;gR@S d{rݛ.E!W%Ud0DfY!]xsDQypN0&G (ʔ[Rrtyj'^r\n՝XHi7rl{vP`e.$lp3S8`+AZ?v)H:- 0?/WI ]X 9L)r(r)e7yfo-`BЄ_zW\lsPd̕ü_ZmP|B-Se ֺx&Y; ocȟ.rC;'WUV&OϓniGɃgSH+@mBp`޺}?8#97 i>ÊmB:6n*%bPEV`gՔRh:Y :+\R&o҃By?uϻ4WZCy^Be*q }mZn [Zxx]]GBpw4]Jޔ,*C;M hx0yȕQMk,oOHel \ҋeoH$_AA++1( Dm:Iv#<*g;$(*EW;_Mãp g [iaVXXLP|ڱIse^֪gͫ9nפZLƾINFP<.=xDb@"W?sGbTqpC'`JȉSK( vq)͏* Cr/ܓW_}X3gab֕#5Ǻ0+>r c!+%S*W%_^.d+ל{1OE1\ye%_s>W~Ke%/_,/)3o sAغrhlWigr6vV~8OQ:lC 8?EPD(rneز$1oْ'z%ц")akv8R ݎwr7V-C(Iw* \8tWhxxB4Fa`A<{NG|7c%a{4g|Ej|&(_2M/SIc)(†Iy{EFkB0u4p_Lo>H0"j ETq] g=a؜D uLAy/nhPY@/ΐU) %7'$PVTLSW; |#|BANŁp(k-K)1f*Tݺ`@@~:i1!Nҭ@Hvu"C(s*ѱZ, t&:I9·9y:BIۖk%ue<%Ocp].|k -1T4x.[-"ymH-X䏦I#+a+T*1s_Wv^eI]i l!MHnEbE \緫O'?Fyma CM0kZ(мMevF IDATu%!$e*SgZnN&zvi˴#cSiaȬYҫɶ p)#v^CT &q#-qEP'dV,9tMAf+a-L҂kd ºX)N)Y„Vyצ"3邙!ʴ HNmN'{nAMU{r>s=lXxϗ\w-fֿ>|AZ#sߥ)W]a{\sOM W}W=˃/Y]6jY{ejSJčZ88f.np o;5ʰfGh:) 34276䪋6-XM%$UKj|c#ˍ1)4$NA#pi#4gz ``#_-x9D`;|;0|B_< z82<2  ЁDG!ɳ0xT>oݞ_\Plݲs#8/@z.;Cx?TQX3{@X?|91O=ήQ{cRx ;+-;vncqELrp{?(.Ϳß\9gVvݬ;S Vltnndv@7]X۫kttLR3|pq~j8vܯ>ġvoIڟ>S;LG&.e$٭;6aN!dҁ_''V2:WfV%=c0N#hlr1K`c91\7K`´ߋ"fmޣ `6{+&xeKX <Q&4'nS,[>$.&ra cpŭ[O+7~d.#_C9z7g88z8{E.ŮxtmY(巿'I\Hp4[?D`)\G=]-4R(a$^+ V kty,[>0MR-F *\dWl ^e,ɖ{楢  ͍Ye'U(k]6'i \:!GX׮ʣl:#]N&0.DEaj<q, _'D.IL^w6OYe`]du7MPa *=*n"弯JLpp_u=C g!>h3*!Pƺ_5AOVahm~k|WPZ\XY58x $C5[I„_H_惐:1U!WFA((*N@$Dx s~n\[owbCHVаs"P">|yH تHjg!fesâpzf>-W^ueyg_5*;ʇ/!!V.Ȟ /\[gokW~Wg9Kk./ϲ^'8 G}j% /]~iٸi## $Ny,%$#<+$`¾Q)mEC%u‡,/,("W]1` $d:k歀4r@l1;"$[ 4q" |epg bSFѬM#8cOgQ48PV&w=1N My2uܺ_XBu8J?Dsx_LEtҬҙFMbвbZ>jv|Wpͣ? Էuo kh;t 2Y}Ɯ$څ+Ot~1 -J"iA4IB115_;i̱$'p۞!}Q+XFp9#_T}?c1JVQS^ߎ IŴWW9u>K/ˢE'O~w."e?Os4f8Xgq֊ ֯/[n :=;cKMi'-5j o\[Uղ_,;(rWx=e߄5DžɕC\!*v/HݱSC9tnwl;XqZs~Ha6?ښ*$?g} SH82xׅr`:3K + I%nVpJ"x p ;9 pqyQ1,̪o1VoU?@L1Ssrr"WWϛ(-q#̵eWqmO nsp6 G ~c50(H zQZC#t%OVِ+*H͹ÜʤL>¡G|xIK! *0] }(g\1/`:qy!V l7!]~*grHRՊi~Qx7vvQ՝ئ ޳ ΒᕳApKgQ7/u{ƎC2w-[FQ ):y:NWe8uΛYҗH^ < n-80O{,7Qȓfsb oYd Ob.̡6boEE*IFQ#gKWޥ 9W5; -<1,\,\w4RDd?d5vRuo$hU'g}S$" GhdN3 ]*9s \Cy?hzLݵd[k> ;uBFS~X[,(xϡ!'g!]ͫR2S7sW\M9g1Ѥj,/Zvt۾Q _(pm{WTDL,F^ygM\uW7(KoucqJr+I ha8еAce~LBtpm~[VTJ욜pCvNf `==lLj~A(X΄$i;T8 Y7:={;Ӝ9{ W+@@V.'p5槥=p_֙pyM?4ucNLOWgM'LacŞx! m$a @B:@J$(Sdpu!Mu@qh": ,;. HUQ/- nl۰ DͬS? rI)i2] *<;h ʳ~[Hs"+3?ccW*O3_%NL/,FV7>00>tVE{m,.**xQ9HT(I Oi|1}`,H|)`w.~y3enG&c66bO`ME9/Z D.(6:`E¥ó@KPEr.KF&Ѿ?E|=9JZ70˒^3rO=v /l9]sw?P|;߽0@?ikQl|Ypi[/{Nyчpny'9Kr߃0X!  !(H{lBwu'@O= .E=XҭqyO.Wx:H,n} =Tg+Ĝ%`៕qw"nQ8| 0 4.V/ yS'ZLN߮ +>c6?'waEPB~ Qfp*WkdCq,ILJv M'd}1c~t<2e`|mGĻMb`1x!ʦ&Sj6KVW`YK{A$%BC~$eopȭ0() ;-s퓄aum喏~>ryJtg?{6mLJ`n랅M<1~Ne٫g*G'c8㍖SN \Yv\D8n e˖D׼BA~Ay[;9<Ɵo>Eh 8rWN*_+qx#ʹge?szr0Kwd[:uW/cJ<&~m[Q9-9eMnٌesg駗8{:-jY[GğΞۑ_TI3 /نRkYg2L0NEn۹)oP)b .&xSUEsփ0+c3'pB!,7mVoTɺω(NBT9 Oc +_NGV|4q,/moÔ\ o~㴨<+Q"caVՉ4DV iJB P:w\v uO8耯+ ݴ9zvA/_ҩ:o#uV^ S>7a*0gR@kš}U6=r'`-YXT|D! !>?}!WsU8 3X&V?Ci0|!]$8;بSYZ$! k2Pʂv%GyEtqPǹ@!LrP^ GTK ûx)ً*qkLʷ^M H To0x슂0d"~5W@_"8qx+> 1{-wUTb,YzBƉK7ٟg_Y_v*s oo X].ϵ煘>ke{EeӦ %rn <\V{[6b=a;6NT XM+%4Y'Ɠgs-zֺ>Vva8$BjBPkLJO!$N6=hM7J(2i}zp%:2*b.,mW@:E Dbq@+WwxNqG7~gqLHgFʑBSxdةV 2e;g>_mog(y&K)[?U|k[EI'\̝zkln8XϹ#sM_,kmXJy O|h~:0 S'tG#M?̥KwK@TV2(K//;,(C aGH3'(.͏4SD-Xy6?Y.jҀ zc,6Uc.ApZI^V;-gĔ+/y;<'({aPG:m> l_Z5U^K:(RxyD`S_}+(6Lࡁ kp%G%0oL:ANUzQQ|XJ<9iE9ϭ+*D{"ޫNVNBZIHOSr|8 :6&j~+3i b쒈\'|Sǧ&k5zsΐARέB n %| yK!p~ꭝ8{vi塗dRJAz `>rkn;#F҂P~h)}R|7 Qh)-w.8GSJ#-V8f`&SoPO*h#{Գ l0 2&+|پ2!86HUrr"{Ef J7/Et C;gK>(siw` Ì)xyX0X8"9"h6U"H*"@V:K`pGkG3&;%^]MSbL&26QD0VNMOIo1d P'7Ͳ{Q _.CǼ^O>\֮=Z&kxj5W .A+9[Y<أX"媫*_g"7tqygg#xx^XhSZV84 c/ W0hL!|c٩!m+hU~9?B7()iB6r3$.l$=̥^pRp4Z0kiKan-Ϥ8'({|Q]H4J&R4S=[}V?fT>ub8z-`==q8|+0-?;>ktrmi_c%YN,Ɖ;C؎jYLGH)  I IDATNllᓻP&5 nkZ1n_P ʹ Ϙ y;4u,Y:#+;>]]n =;یNO-dGÉ~?{.\TN8a Iats_ٵ{.ʷ(դ8%NB-Y4oݾu4& Νdԣ5t٥J! xɒ}C[ LwmOUX$xU?|/ݑm2 ֩'Q,/[v? L2gݞSyTJZ]ݥ=>چuqOeẈ`bEd YBkOi@!yli|I'[HEA&g)-XHj_y{)#gQDPn)'X(gv|NwySH2.w45(6ۛ^ +ϋObf+ƙ'l`WG5won_a;7<PFlY\/Yo͢FyeM$s7C]d[z!L?(nijzS:ii?^Bjh2O<#y{hzDK?RA>U%O΋n+Ura]K0ϐTM9` VQyll`|8x2W6#()x4e6^uxH0>wrı/ VDϚª|Z锢RbnL؈K %p]pbJE<=L sGh rNpϊ?}\Lz4w[hҠ&AZh-cY<!#;=/%xũScVm5-PI$[Zd3 Sdy j6lb^jXjUd ԉB\f.&9w#p qؑƒ*< Am@b$*@bK?S$hzpjG&apΡh} ())B0]TټyK䗰9uyyKү,6;r̟ĕ37q17}|+kW^y)WmjA?Ѓ< |FiSZєW!h;C{4O-HW%) gUO9"Ku"SW&ʹclEv2N-Ձ 2O-smwIoj(0gdkЁiSS4,g-T~G9ָ[[FPބ}?XOg~[f`t8m!i激dW2K_Xw/kV2Yrruriݰn:oƔڮҶ`p<ꤓ{W޿/~+pB9vp޵ϳKd,l;@"a.HΞхE 4u,u~0Amݿw:,f9]i U'uO5Y^7GXpK]5ú1zF,o2_V*9[{?p3Ĩx~?+i)jksl6?*W)2s)(tnoymDq`?%[=)_'q)+ןfM ˧a o^wuoOSHk5g3,^X4DfPK[fO*Z!(ًT7P)}`Šqi)xͱVT8a 'ʟʾ}u.9,nj4;9Lɇduy7~PI?ܭ 跰vDCIdsP7|_q%9 +]%#X _X Fk_ր5Yn x\ .ࢵE=3xP2 n~{wS.q[KE:vEpNV `Jj9sB骀}ξ9Li/7yA=I-"b޼$xx I9u͓;pܿK=@RUt*?LpfFeVܕ-Z#Xq+⩌^A<ț)d$'_+o>DZ6WkH_Ԍ.8-LJsx2(@ c\ߕMִJ|EX#-,\Vs/D4#7]R B((iabdVaD- (11n,X8koia/!TD`p`&OL{56O#'LZM~ʯe(X { pe&_.*O>.'<ʁK/+9g|t-,wk_}ySr}>|a4xAܠ&UEnH0)7Th^x:ҧODTqW!/)©4'n}2;4txaNmvd:_`j*],> *:~tP N:=ywW@S۫_i;FoТN=vf1HU9,Ȋ%%!=.}t|T'n38ӽ\㥗m|lǡP~se޾yeǷ@ws̼{ec۶3 V_F寔gKe( qNFȚ ]@ )Ll\v3!ٖ|?z?`.N\=2<0^lu+祶rp[WY3r‹(,şty+_)Nc:M"k,(m"lcSuז_&~iutgV%32duDptHYgʪ`;\9 U3 aB~h9-'sK0E:4Uֺ= m7 4vt*0L#ب!lHw Ot9{3~M3``Qi4l[!p׌X\)4Sat+PeTK"OsyܩVRŋu gLu $e׼[9vK*Pbr~5s7om.n6ի&UKCȎ|ؕw?Be?u" 3)Wr "脃lg,ʈk}w?o~]o z]x6Wp&@ fCGtSQP[ fpxTGu=]jI^pz 5, I]6$&@ /$@踀`mɒl `#yyfΜ9s3gL)E6P9e+JڇI?< 5(l(P@ZWx=J^k\ $Dזy*xDI|8 ʤvՇA~d}̚<-)0=S5h ʖ86X;ɻЪOEe-V6-u0HVa8z|2퇴22rh |kBj-aP6J45; ٘G#B÷Qdւ> 7G%=`Jkc%s'YVH0 wKYP$b`+S:{0Lbizt/~tVp]ꪥq&=zV\v8rӞVnO9#l+aV.r '/8qeX从Wnr7ӱ$kɧT]k!3GtvjÂGBQGx7>?id{Of["aI`-,(G|7SrE1/O-W Ml ͻŶgiuLk9hh,ńQlS:auk[n[6:s/ZGCBO4ؾ% Q &<&Nj3-**kX%|.S*!t?⛗e_!e>P&˗.ǢfZit@JL-\%K8rț=hջ؎Vpbz%_U('_6l\O[rDVUI/\zi]*_'38DL1Whb=E\vrMSI24q# yɢ3p[}ӷJǂ5 >@7Ѝ+8fU:v,/:ye~RuZosyɋ=K/zQb,Xw5⳾,dØ43K?ώ6oc K;<;((<ݓ-~V.gk^O'䳚 ߥN&+Te~Sʝ۱X0QfeXVd;YmZ0wS0Ff }>2⅋;ʡ[E%3 S =8q1Y.N·s~rTU(b鎒FB91n(JIAQXɦ`)ᚦf3"v{>ws`78R*tg]({i>e5,UƻyUQothD)'r Gx*:60 (RMs1J;s^v*] >ϺukN@B U( L׆6ZxRDrz9h*+#c=2EXw <uX26đc@9µ\7on#Ł eCyX+U`<._n|m8|ɋŸъ7(sY?fO\\g &K[V.ѧlp &U:^fOK1ma4vFqWӸ&͙C,ӨYJ`8Y}1o [T:˜K kihU0Sp&f#T*vJYRSv$$VW *A;=8< s`ps97ߕ[rL5~G?[1==;:[v8Cp,<1;UW}raŊLI:dܥ=_jG>)pB.)07L\g7t'#tV`?N4Q [π X'B_GlIrPM!4wѺ:o5* 7*֒WU0C$b&lJ'5>W<Fk(wUxCoT&jM޶#2 6h[Q 4jG'g$O[neW_.-/@҄~JCâˑ o˖-chmxrhQ7j>>̧SC}DG83Fĩ}+[/\9 ퟅ`5;-l؁w3eEL2~9c`mi1~lgzZfw+wn~ٹvMSq IDAT t#v*5]Zf9erS?,]3"'+ꤍ;)ejƫ:,Lvq fEI*$nRCqƋ2V{S;;n[Y8l>/C8mUVҌ}ǵ}kH9opO ]XMYԩHUamdpՆd<ymWǝt,ĹSl{Y v`I 1 ~UN')P+g-~7"Gqb;eٸb" }CϜ^C!r̶ t:RfL!ף(Y0x Rې6sLФ+Gy!$x!R}(؏bt! Ѳ;q*="[6mwUzEI3>z</!BRH RH6wWW ͢H/Q\|δNI\zQ(_t Z5hM,I|mZHgNt25B 1Wt0*^X_@C<EM*K6=B7˃`fD'uY V2_BQ0t `j!H>;Ya)p+dPæ0}*aGV^~7^4bLAkrcT{7w}?r|g䲷;)[*_h\O3CuHt|Nz= h*^[M, :t~t's=.*vЅL%rʺwsŚc!% (=@LYw Gd]FQ),^m︳xrǺؒl;׎eKKaGYsLAg?7Q|ͷ'~*l H ;[v3"C"c"Xj ;Gzαŋ}pׁ $vFBۉ/W9ڮ@,5#~.DТ`p_La ~}10ΰe.uj4py{3qndHA58@>wX2`v{Yk <ڈ,y][`qi&iCۓRTE<1L 4E⚅$3į+T`)9%FR"4g>A@$祒| 6T9%X`q_'+[lBq ʻy6MMGcs,B^'=08$sYbA`PTy |xQ[9!U f.ܱ>XBiQ+B͹Ҿˮ]xc俕lga7*d*_W"al3u~n+9:UY>>pou-<`r%*.BRњ9 3pwg9S#sιeu۪)׳47p]98< [o]6JM7P8:M=OÂUK1o޶H.$H=6$hE&X)Nq4LvG;2 OT~ hFv~ĆX @fZM#naLl~\ԓ[ge֣m/M6|H4q$ߚ0VW3he>R6NiOmŁT(/ڻڅh?i) OSNDay:?#*,TU| ׬^Ņ8G=g[@&iZqVX'>T XݬX6ℓdUFg;2@TCN<,tN͇|/l tv܁aBU&T 'J2; X4 I>Se`V^w<+ʿBG{afV(GOOijFd#Bk_KxHZEUM ,4 qEB?25|>V,LG9q(:茰߃5JROZzhf#&UOZDc2 jB(Ϯ\+"hӆˌ~iöj#~8sJЇP@{'c; U{"HmHyCpPv!ąYkb'&vBX{$eu`֢FN#@99|)e9+8 i"0"jy/c)٬?kH:F`)pXy_t@ >qI`*0ڙKC:QUy@V 3+iθ-,n~*`y(h{\o#,tZgxsoVXH*v !xJE)iNY,OB} __ PL !ͤJ"f&ɽ,yP;#^rt2;3q[rQf6`v!FϪ,͑8o4rR 1XC_R]kQQnnP"a) uV^s٘K)+`U1'oI @3X3ߵ喛%`|},ۨ{޾rZ,e !t@ hS[qhCPBD9(H8zQgJw ꧩ HZ袉>*l$Ҭ2pԀKC,| #~--g#'uD :VxT:x,70'>/=uKao1y @O\bzdu^im` wү%h_M>/(qlkBEPfa&Pup"88l[Pc5:HŅ62O(3iߕ;zg5<` m)%-C MGEƏEV/NQNK;WB^hԹuP.X>-8'yΤԫ 8t/վӟɣmҫy>-M~!]utg8?BgNUJd)Ȏ_;5E5XH@`!!"Qlw!H=g,+e@\O|Q80*9`f>dW;e\{ݮaY\KCΩ! k#!#h8"EVG\e6zTЍ$ߝ/t¿X<9m~gyr 怃,,p9$ Z)h9ݎ΅WY@9p&h b?#)QXd\}HXa k}EP?}{GD/05!]Υ&[ӺY !` pulUGa8*ԟ@ >;J9 e+2ZSރF#~soٟuVQh&Sxq? <|!@?V,`Vj-k9bhEpL2sN Wz9(e?-|L$"Ql"c)A2gD3 3 Xz=gH,aϟ<4'8CP 0 W1b|YߕkYPΪ w/?`ut50VQZi8(~$4P,FFfZ5qRɏ&@_4&qDkF( / H$$!w9w- pGЂR8!)dO?T$)8_'s敭v5vou}~ uMZS&*g>uwS9g}vR@SOaE~XT2Mqo[@e8_:y㝴0>p8(,:z˚ :sU!=HWp#7Baa16DzG(IS> #N`֘9Z\ۡg]Q@"qnu*9't Z`.H~ ٹ[^B*.Z/TM:Pk=;e UT7TBҽN}0^sDw}e-[0,(<n$ ^uۇqum!kO!^Xх #Ԑ>: tAvwNh(}O "DVrcQhs8ނ Ŭ6/^̅.>R>pqq^z'|.mKx, 8 1%W/Y~[vew9DeO14e5uDN ]*Y-j$My Q=Q&\q5D)Ҋ? 5]Gh7B98YX0p?r&Q (93\', ,n06tN8So Vc'9 7îݥu\w6,UO"j'*yEr9JFVZ@'[E|ݷal/߶eGYsﺔ',i˽RZy%>v&xA^ j LjU9\SHl߫;waサq8m GeU\YWOd%_WB '"*O=z_ʉcKxE{˷.V~NA`I?8A2/i@ UTe `DS2+(P"r-'m_^zWkHVk5eX$ęWeО֓Nv?6X8& yȺ~hz&4ItjrGt5?ȕe5~*²2 VPtYU ޚҷ!\oƑ@"NE ePKhD:yt? .ɗvVxSO1*8רutT%9c41W9Gx|< _/\]>`+F;Нt+01m;?m2*;@BZ=8G1WΥ׋vIl(M(ZӭD@U>iL2pvBlԗF*oe]A>hx]]Hdޠty :߳x v"I+H97SA >߃0w d[gڸߍtV؞T*xSZz,g^nr*瑙ZI#λg" "춂3w6Rv'FdIݪDAĪzj5a~sH6ҀOO- ܅Xюę $E, Li=(BW֘R/UHqN)\ E O4ptYPz8r ' hb|+>0ڙ7\S.X72)?GA{tKw#2J+ No#V^a&\: W8/a?g~4 as0}[T+ˡ-33B-@HFC)^k2q,:;i\$T-ɆvYs֔0/[^~,;ʹ睃㿛Y?ap*ӰppfO@uX78#Ҽvܿ߻bhy!md5Vh^)G9VkAܫPpHCi:nkX07i4kaeռ.LômlZ:ឋT ٓ&m|3i#QV<ũ(9-hR2D$L=nŘxVe7-I~V64;4B*gBx7KyJar*Z)p'%lՆ&5B-xiv͠ |(}Gcl`\2d  IDATuZ \;Ҋ߅l aPt楿&,H`6L;5 'ąO77kz6<@K#Yc=qej r9yub\O9/7hƜi ?2%8;N\`.]VWbz;0{VٹS1#7>[^H&>0MՆUgiF@X,x:-r06Y@^6Ve@5A]GZyߵ`1y[̬gQ:ZtI7#xL|eF[Blm-[X8ꧬ*W:Y"vp_[9S7"$@}U@q'dTIi,kJsm-[~|?<wuW9ou,V `>N8| h frig&g?ԏee [D!j Eu=sa/~RV9eHhsDOŌyU4ƮB115BqE%DfPOtqrzZ?Ye'zP-lla1mP>nQG@vo(C,Snz|S" Bdnnq R>1bc"W x~5v~)pޖ?8h^p0 ~(#>2+ ټW5v>Xs7鴈vnCԎ-NVnYwy>B}o |;WD{L}@Z DTEx xhQ910Uw~bNKgu" q . MA_UlhQacᩬ/,e˺8ΏYMraƁN@,PrlBC,U k 7 aDR}w_K \0!|y@ IspFK O`ԇ2d3'DA&Mn=,F`nG~^3[#76toiuK<B'[ed2GၯR7J0_dQ ̥EG" K &[˻%}EVn_!.A',-XXEf m<^^4G7ko&:1{to- )ӟ!8H4y?hIC 5Fn&!)sb9YUGaA6 x(BVŝιTcnV옮uA:S*x!He\'C=;t ~/(݋Oo8u9aAGyҮr&!#mc]cY'ݙ;2GATBVͬܵ9@eaYΌ Χ K c9R} `n8j B*H#yOs.(p Y , Ь0'3n / |;I6<@.N]8~U~4_˔$ʤ l+|ѩtN=j )l#cš(iQ6B`~j'$l@6x?suʖ=x Sv%O [\؎:Sʳ<|)͙݅=м3I_!3BKft a5Hi=Ii9@b#83z xƚݯm|)ېybL^s$V7!x̚';0WA4ml|=$12'tg֖C~G@g#SKh7`ڒs:*co2Ȯ- l̂8![?ݛB4 Gfgc0d/v2YNė]*-j}PpUP) ػoS]l|裏*|3_ϟ!,9kq-D+q9t0 |wɹÛmx͵+wƛהa>h?r4~YQw"*F ~0C=^=}Aov:2 .d & Ѝ¶bmThUP{ nD1;..CO}+Zmg_E%Ggyn=ኢ(>d ug(ycHgBN㐟40;X͢PׂsDa[Ay"BBB |q~4d;$!(>ֽ2QPwdRqtKfZ$lGڀ;ZDariU1fG׼%W:!S^u uy "Ög~+3 葎-Ѱh(1~¼U"3D{?Md?N~R J^)N s x9-y@RVrLvAgv:~sԁt3$;Йq/.'W|t>t.u A 3و[efu|`ބ f@`Ner7ᚬ<.̵c _<{ D4N 8M̴;xwA~dIzJ"Jf uCZh,MTZ(E#Lrg1ع\MSFV?vgxg" Pݛ)ww4xU˜5\VA%x;:p^T 5R1|3a*70姄ga|tni3m]H @h͖8b;8tJ?+ZpVFi}yg",g5@j"?$e~[\ IsȈ\URN}X{ܵZ)+9b:s *<ꗚG^ro6NI?hT(YxRp=B}V<ܽy'`7ƚ+YQ@p>!m[,(qwXU|PV~}*p,PF<"2@#!r,QYhd/W%R%OT`!.%ikξFwc^ΥE\dx+] #X0@H$`;⣘`flxׁ׭7 A4BZYJw2c%,H@mΊw+V .TM:ݷ B9كpèԾr+h,oY[~eON?lj>Q Ԑ c9;M͆֗lk`2Z6oUV߿lؼt|9LI?f)uKGbZf$<3tq#J @v Qdpc%a[}Eh01BცdfCU됬HDI4T\##OK 8iN6^¨AF}LS{qW)`2y[Wf<71J+ Qq DL&@] VILlxL_t  p>eD_JiA+`zFYApO?e N 0>?xNi?َ'$oؙYf;(| ARQM:[cJs ]*U ,LSOY_ۨagYQVX{_Ҵq#<7~ʅ^P.MߡO?П6~*}9:oܜrm۶r*ݞuƙO+s8#ɸ.U;Y^>y͑l y ']ܸu4ß3QDtLM[(L!'E<̕*DR㇃'p[DcR'g @Ǖ`,V7.nCFqުY$%x ~GnA̩oED"PQSj㄂IT FȗU@Hce0VAiT2&6#!qB|$9ʠ'3V TN|eoRp7N]F<O; -[6:2&R3, _s.Mݽ eVLUy@_ E{kCeݦ\}]e]h2o jovH0ChrR`0B(P*&`ڡk2. a@BC W|D56pʀϻ'm+:Kf]X<@>&\ΪЉk^>!(Ymd9x%b+>E$&<-~<')WX!V>7`+i3̲-|mc K yoҳov$^l#5**g2**BۆyAА7B??r@7哾K(e2X9,n]t2`QyEilIoh\S^amP_RJ(A)cK[W||_߸'f?[ַ<Z zyG>a?ZaOʻѿ7.` _pʛK6(./yKW\^9GL{qijG%?j!åO~ .('˻}b+-|4?:o/ y=f\1K+)oogtucsL[_~}H9.cj&UFdgH}xBU ڂy;_PSr594^r^L Sw--;SR>v@;,c`O ON1} 1Lq,XE:Itc:L*Z6dr4G Z7+` PN, \Ta#ߴqRǻѝ2wa><ܐvX"G,*ncoڡ8)Vđ *:v& G95qſAi@ITr,I iti Ѧ@ު0O~؎ ! e1Sge|V v Q)Al<-94r , g݃ &<'!Іfq =̱0϶Y0u.-YUpI n-Z)8QN :bqu koB:ujS<Mmr%h.ZpOH|q(Gj$VS'` yt!J<Z!*%[ ItN!Hِ)Y `g hҫWРwpՖ(7ypJF~9 fd}Y%+ayngB=GmT k֝廗_偆S\i^MPG|ѦRqHL;g⾐="XfFWm/W^|{WqG/YW~G䊻߽|u۶2ʑ m5 F^&PiRօL+]û( _+H%|}%.|P9eMM>%ŁW;TIG~Z#?p;Tҋs)ADHMJʈ8ltR~℗݆@X^@ h;e:q&'i+4QY~Dx(хqaRf%RF5FpQ ,,4-!<(O&kzz;? IDATlX'ӆX׶BsɃ\ѷ ~q`Jc<ßB?<>):oцTe M9y&rJL8@7x:tnMXO}oy +VNJt^\>dw(R?w~J X37kGs+g}NYFY^Wu<;w*_k^oy//~KOm#w?/,[Y-坿K'㫾>/qƙo~//? ͏~1wP_"Z?X 3gv9˿b_<'Ba_Nwo?td~ o^+\{C_~s-t3ʗ|^^֮][^7y|mo׿罿05K-/_첄_Xf)=~;0--8~Ͽ̝7@ǖE)qze=O/,]o_~aZsϾ 0%\}ÛMc=nO?itm1wDV(DPScwx?`O!Ы<0cãyGs~Ve/ahI'Kd ΁c#lt;w~l3bRv8j)go'O3п"Vrr>u@;Ul[ئpP@3QqϮoVʳt'ifE:GQ1Fz:qdGytI?=Ey >/fz1¤+|{ye#z|+`[7.s:^ s#ևaKU\MDd(r,Hg,ɶVbJP-(Dlm8 F ,s_`{yd9kpU5 ʩ>V}?Br(hG | K>X`'=]i{*SȫOe2-S#ϫ ůW M%pe#,DXEAF`V rRڱJopU{wKă疏s|^&P!afoE$ gt,y8w\3cKYq]{ҚwbLwFmdZ7sނt& Q&NsN9+? "`KtpTt5- -_I Ew)ϡ-w%eJcCxע*>sgg0 I}#٣ ?p`T@H#_>jԟB3$I{2㿢^~esx>ذ ?5֍c9 tvrXTy"gNJ綆U9 ¬$ nÙf+<4oܚeKRƔOg\yk_S~sx: Q:y ˝wQ>*яO}}N&ƿkJ___UI9Txtp?+n*|o;nGKtY aπ뮿-`y^06&|ƍ~M卿Uo|>T.fu]_9/_˥(A_|%YQ09GuTNulc/ث{U?M]'w:3m;?ՙ'Ьuf[ FQ nYԿKy++k^jY_He]z]vq_ٲyS.-Z= sw?8ֹ Tl=s!8*+d{)} z7a}ΜNXGPV\}s*w v huQl'N/c}̴,k}ޭmc- wng0nwU;f^W9a> +|t w P$(+p޵iܳ} ,:I0? ~;QQi+<w̳ݰ,96ng,%P1UbJ #f&+QJQEpK B cI'Z8L"J8Z9_ .Ǭ22h 8¯#df ]\9 %;FE(vV(- +*t ɗ'"aiPqf@[\fXӗ(GRhlS\RFzz̦a \RuU$..'|T^eMXkBi⻚9n2VZӖzU}W-futh"J^,_QnWхۼ `kTՕN;P+}#@GWSgg5k A- Og\<*Kl+e"[ $uf0bj3AĔX ~Vaj*˞d;* :%@/ "- в@E!XC5b'!#AX#|; XᲵQ>7xOXLUs\/4k%D&J28 ;q/xtIxςmRk /\qԽɓWŢG<U>S!?E{ء$-&S:FZkp.HfI#,>Dj |o3^*6q힉#U{4~"!F)/pwwk_hg)zj>yNyBw +RnsJW]U~Iqe2<v)'OV&]l~sUbSoy^V^9?o 7H8AQ`__gU7gG}̥N:~Pn| .~s:oҩ2C`gfh<b~}ZPG{R?e?[آBԱi7Ϣ1H|-{Nyk^_WWY7/x֭ ߿17en_ ;h0/̙Sw1YO7R <8=yA؏DCr=VI߹[%/~Q&ԶN7@>OumUX6u> ן9Cn3$L8x{YbE}s/mIucl VG]/ЈGFtE0cbԽ~y.yu>‚f/TJ9?:s+0Iq58|*"X:ϋ <+qwki=`9L3\p(##_zwYa(i߬ɤ/PQ$n=Sp~\+x68?~=dXXN%Fj *bQ s܋zwˆ4_O_r6NB#DGasZ"B^jF!`6X_| ǀIjo"sZ8820/ Z .su3ԧ%z!dVHvpGZna #48POí޷J|"܈#mxL| 5>rdeg_+&m?\>ϥX]^܋E%UbΙpfDiyĥ`Vqx&a`ep0yd縦q3gye4 S8VxHVFO5욵am k0@*1iUmwʣ6LDhҙ[o婆PlNޡi(`aCn|-tc5`:|gԳ-h\9JxDLA7p雞* &v&6 FkyCwfd6혓-~ .zkʅ^ 6P9?VN>$,qw/ַ߻Kʋ<d+^[l)G}Cyđţ\|L!iJp2{eFyƁ'?]ג%KWS>_>_x +,g֌ݷR&/z=MG`gt?iȑr&+Ů޿3u֕#8!0U̯{#| _(O=rE] ͕ϢP9Ag.|uI5Odo||8 _,_җ([k9Ce+lY_~lc*寔=\o~#- c^+~zvmqLH}"X|7*{ ٻc?Q.!Kus9;t+lāQfuŘ97>gSaG_!DѐWfXMq W (WOCe|o^ nG0Mؖv_kY S!ܦH o%/Ϻ ZV=z{ > Ю!$Μ((Q@ Xu>m/WxUH7 &3',qvNEgѾ}#t2 Uǜ6Ҙ?-+P\:]pEKX[Xq3;ʫA([Z0H %I4&c4r |ZhZ?Ј."ZuHvEFo7Lmg[9unW9gJc"Uc^[E*.8y^<9Bңu\(?XVnݎ 5P)BY.Vv0Rدo}o:ԅ9u/2G&NN "B ,`-<![a 3ja AA6ìBi%+. FMi <'+ofǭ*\]X`B@/^4Y毸T4+\F rf"`虍P̄׬BL3 GEchϻkl`"Pe +hƦ @rwW|;7yXh '}$.{>pEJOV" 㿂줍HB[V ,;pݼ%7q1t"a,!R$=@ԫ#D=+rL=J*u#.4 MV#K@VAag|}p:; 2Sԍft˫ rIz%)BxI A8ėt]*H7 ED`@)&)+ށ8bDKCzNamiCY-Bg?%7xn:o &:Nʎ{,$rqǖs;,9dCLGyޛN^tq9ϣP7Qri?R:=i1aCPL_`El!0/+Ԉf~ͻk5wr3(Gyd}=o|(LsVCׄӼ/Kd/hc؁\?,]3&/墯~3j+ ^ͼ86|+I'XN"#HG˯ sx=Hq>͕䌍*~%U,E%ӹ<+1q >+L**"خ1VNA(zr'\՝t<p]au;c:bEasΝTVqĬ|&\ee]gAaR ,B`,Qt0wqu&1>(6T-W8{p<*VZG| _<827¤XM\9pwB+KUA/e5߹c763>hB L~5 *Ev@*7VC^ÍreZh:| izAֲu׮{߮1d & !,"]Vmb.rafݵUAJZ2J2|]Iw瞳{sCX5(#eS>3g?x@'F+󴕼~B`i[)um nF,02b.N:5#٦P^2w*s7ț yfXn~m[C4(Cse?VU_d Y4 6hC xE ->;>{8=x,E̼ZkS>ʼ>EV"l{+yOl;9RпW:s`m-x[gwj+)X<&Ƀ m)/TD6VZGBt6dUD8-:1k{8pgo#3:y˭e?HW~Wcj]d>|]+u|5ϫkE\ʗ07~EVp~}կ<̇~.湐Q.nx[ 7%!֢T~5ޞvַe/ aiֹ-/0ߏh^g"[8dUIZe!m7#+??s?TP2ڝy#}nFɟq%/~Q"8 _`~w{k_):B-~|k^۾/M_=0;ڭ*xaj[V{[ef1 e|%e)F\Ĩ{r@q{ރ?`^׿eU/k}t/p|=GX>Qr BcL_~&*V8/\ AcQuyA~ByN跜XEC8H.-(*exB)@1/zC Rڝ!m2cx疊3t=}NPA+"[>W)(TbYP^i]y-C-3H8b75tF| CupZ!i[COc,CnCv>?j#kr0 ڤ" ]hϺp=i3FX03jhGT^vwuawh"O!,䷌7+>SS6c>)L[o1ԟ1J a8q-u@xm::uڏꉓX8MuHGfqXC=& ?_&J.GdH8Bu9C,S+|8`z%#39{ pRoucꅉ! 69DH=JK)Dh)0-[1@6e|C<zwm'G^wdHHIJ)?JxD!r8h<""GFq:ho` /?#XF'/ "7\:D#Ne%d 7|z=wN~,:et#&cѵX-WqE!? K>Bt"Gm{қz{]~&5eOJ -L3^F981u`KXAE/D 0>=8~ |3b2=; a|8:&4bil[Üw;گU_◠p{sY~SaD0f܇/УAteLYx# u{oh??Kk,Fʿǂz~o{~1 ~ӵbgڻ7]}?_{%~{GX៲Z YlO>Ci"[Omh-2u;C[/]e[ۙo~ {O%C=*߃>ܲw%Lk A6 ߎ/w=y#/(c4mw%`|j{k^CDž7-mg?=A-lɽG_ι3H_h]q#Σpvx0L ". .?zur_ɖ7\(=;'|3v?c?s_%|};'׼5bڃe.yN(./ ];ZF8^f7[U?h+rϺ8\V@\fQoc71/- Rg7t4sf{` {~}&JE1Թ^WeAFU%T8k,j¡dvT_$FLfA^m}M+ P0.9g]Ȩ:BΓ7I[@^X;+5hcw0zi78‡F 1 ~mu * )~i2$`abù潋 _'N?ש\Exյrtg:HasEKXT/EG͍ uU{t:b0g]rLT'MJ/2lϽՐv1 y[H۬ڸI8댉M0Q^9rE%8nGg$rϳ.G#|z6<&8@+Lj:`=`AA)Ո\S G 1*1*^(lCē&1@ " ~G$R5IS/adl=y P2W4v3H;:]Z2#~ ԯw|jt\eR/=\43C.^Q Qofd8 ࡭;O\hK1(ZQq))>.a9F|ڽΑ y}6:ZꠞN#-.)GhF9x`̀mGSq*h”c)8!,_F"xj܏ύd uZؼ:.6l+(qjp>aWQX$fY{|E+wc lȠl d*λ&2oK[5%u}( 2"lѓ$}:}B:F < wZ s>o-c *.>2U xB|HChS [{M]uD Ϝ~!9_2)U砅&i7(1ڨ.c,N~/-"IΆ05u&ҹi 1SsIт  QU5^UduO0ENq<,y̒ );wo_jt/6>"&CxxO Z{ڜ^8xhcpEm\%<&chtmH8u+ ,  QOec ټmwJ <CWi3+"Nw>xJN k|@r` O;4ۮ`pg ?O32@5>itiF䩄1m -<+Kz\ D𲠚 jFëvmdTORiL~du`(QaSQڀƸĀ /:>3~N.{3diK-'Eyih`rbx`9i{} =&ۏ\J6?]<-Ƌ{^B uӁ@h%خOBw$4],MC68Z%yWH=?g%rF>.'78o \sײ;5M& /?ۯm 9^ٮk~gvg{ ̏}}omk?T/9n𯵷韲! =F`*8P\'4_BcH^.<k?n=ZTDʀ\<~Wrk| ܉8i8[H82N&i<8"O^TO1'2|ᵼCcOYZ^v6"`!{~m`5osT"vqcxG<gÍ~Qf]wr˦-HHSr ~fGϻl N1QGYwewL et-)z}G=#nvp w"cx<xCV[b!/:|2 yY\wu 1J` ~yEKp`(S_L=O_ۣhF1.=F]u#e.e NBrx K!5贆ۭg7@ڳMY3bhX'(#x8}#PTUSsjDq Me=8h<ʀ jGa~,a5’FNGŐ ck@b魢&V^2NE8@@sa|Gs_')t 8Eg |qsP(#O1N7p \/Ep8SU>wОsJB'iR{E9C͵?dY\D'.B#c#5ϔ#z—vi5wЍA@837a(>h٣!NepKƼ+G/'3Keʠ{`,Xe[E3E ,]8 mU&wd6lh(]@A? []ǷeK.v?E@Sd<ۍ3jƸ4F+פVO8 ۴כkxO5`(1Vu7fdor2W|Q\`(4u|Oi?vۧ}kWǷÏ;smy|u~;끉pHIYG(4R4T*"oS9CjIp-@@iQVbv#/H .Zo@ pew@92Lg<\shAd*d.#)p=? Дe VGF9&.>˨2P^rЛʲJMڵY2ou֖->U;n}9\YnK][҂;pN4B-^[a}1if>i+ ݴ{k(y e> sW.d&m\w]I'S_ȍg?Y]w>8x0_ȷa ~(Br]@~cpNzLx0qzG*ݦp=2{v KЉvvySDE#.fh9PuwnԲ^( 1'd,b#M=r67?61Võp=JkR ȄG[e6bVu ]6y2GhzE6uv>w3G^WcmW̑,k8?Ap Ɩ[8;[Yv$?//'YbznÀj'ԵK{;Of$z\UudK::91W8ೀkp>-~*1FYG< 5(w1 H:=dymҷ#Hl,#K:2CɧG|r%Mq1J;ߝE}ʊHYŏqa t ?趮8xJ-eqC\99>KgN"ۮh3eg+kWH\gv2YR\eF{Sk ݳm%?Iƻmڲ8"{G18Ȇtru"1_3<xst.EUO6ϐq tv Fuh4Қ,?`D=˥:BGqU0T?M=~=)(=v XFexk=_k-$Φ[*IV,L4?lYK>sv H CԉjΨ{R6C8Su' jn!Go]cZ}ǬdK<81eCU/UmgC.-5:]G2CrضB|p?1{yAW1$3 @2ULWEĈO(?pV;ڛ~_MWL Pt15[\除MG#rd08FFVG=;$BQĉ58'ޢ>EI] j&SA}]@cuw92֨5:no{r|Kg]9ÿD(KJ<G469  IjwX_EqC"OVG"t Gl8ap| aq!6$>3A<2RΨ_ !ܐ<5%Aآ=mZ niV--*Ny!^ʪmyK<_MYձtکd:jM4C 9(} @#r u/|2{r ]z Ɲ{}ԞTҾMcE)`;նOal+{mQq1yfQc6 cOoO%: v6%CEu[C=BExYP0jA4ըkP۝ۭ/=߾ ,Ke[`p9DmY%n1=3TgYeEFm,_̣:~9B:[B{DDVdN]{2"B[F\x>ct[[&3b8 Y ^W񄢆G$@LUIE$p h nwa{sO쫀H= \e{+/2c< nZF@(p.dpMex1A5pCy8cp}f+WXA^$,w褍GB*YoUDtT;J;I3ХlusI}*6eM=2-6hɔh3Fw``8a dtl*pug]bstN ` 0uun#o+©PDu&Ġ:"aW֟kAP4O^ ȱNzͨa#*h)g:]+@80F$`uՈ%޾F s`QW 410G , eGȽ f+jjhp 0EcG?xӡ0B. c4~Ƿ]K_ދs}Q?Ob3/|]/o4G>6]8rOX;,lynmd_U'0܁! @i"<TU5e%z/~l _J^rBng/6" +y-Xge|S&LĪZBD|w ʙ@2`L"C̞yasb@OgJH<D^\Cfn`,>,?C 9(^ϼm.G9%_};v_k,}!>0,Swc>CLtYLNclŬbCFz4t᎞ޱCU7 gD3OϝlûY ޵vԽ٦˞šnʼn[N -͂'@Fi uW^gDF:"@ œO ?{\m#xCgyIzJ[dJX-8ڻ* _BKcyv!g*Qw-=ÔVw7,m+q_WJ>=w\BzL:E-)1ҏ7&|8?7z{+Q!`ɻe>:lp `q?_<ꡍg1lIsu+૜؞DHer ,D,'1-h]VĘSe]b=? !n_8q&O)3|Ӿ] m䆖uj//.T=OkdWoxyl Mpi8_`|tB ot?i@E@in+Z"#mA&;`{* v+. twwôOoȃ f+z'f; DZd`ZlDޑvwgʁ4/<#^qF%b@d$P0=!e! &#3O{M")5"t1 jH*pXOQ#Fu7/ }#? m 8/ 'SibB%;gmq05&M= v޾[ ?ɇMZyd N΍CrNK [ |=[ڧ>vy[>~7Ϳ}C{|#?ζ[n|5Fkkz1zDEРeĕsh&<%dj:z$^9ˀ4-?âDxy'Ygsc`gRƦ2  \񏷳g?ZxԈػo_lE \hLCxW*j(xoCαSF8DiU., EAa~M)x֐ 帏nvpfiqz6 ,[+JG9A[`|T`=2bUSx3@C{8ep:s]Pr.0,ևiE~yh8mEX:_g YsJe-\baQ)qc(r!t8*ۀ0Ok<@=Q9 .1]<#iz)C sdb ꀹĮB_ H:> ! gb$ @ ITX´lkw'?9,^Y ^҃9>4S6;AUE( (YsHC,p?>]NNrq?l; .)'_3/CIă'g^8nۗl)fIV&I72R烸 :9y4gXz9cxF䴑Q ,HJ;b}$Ua omS4X۫[2V$酶|89 _\@]~21.r]u@W# _m\\}w};7;uخ! ' 0u ATh j;sQ֜CxvG|xr`ȁG9-@ƣ!9=1.V0l@c IDATQ~~.H 7ƐF±߈ }q~?}MboF' F6hAGx}m~=k7ѿk_v}2/8Og1Xqq7I׎pKjXC}+<؉:kh\gXL2MH񊳀.0gUHyLUu{`v$0..N7А݂nC^Qx]7/ v-] |CѹE=Y|(\P-7 ǟGY+B"W,~%@Ë/txK GRԽIYx^% &ȷQ p a~M&,é+ RzLŸ 2np`—8Bʔ y\ >yfiif#BK֭cFזGvBy_h;zz"Qx#w 6m #F4Kyԙctvpd #z\W Q HwξqyncR؏jFh)yJ'[AP3”x"[#DwV/Ȕ@SغL\\K*l&ezP|2l24/B(D4urT͗V3dU{v#i k>D6Aq'GuCPq. ]T^!ɗ+r1X9~Jzþ{W^ЧqG}]Ѻn^_nrN} SBQaJɢ}a E?_G36 2[d|}{?" ^wtM,OOי Z"(?w-Mu[~x3C 9OAC}:G4$cp:Sٗ߮ξGnNg'XJt!hbNJu!P/5eB_ol om0f_O=fO{ PZPܓyf{{fϵ|…gT4EWTԍ'l+CfjAvPnVy~IK Ar +Y @ ZڴHnrh~¬*(}0Yz2@Ab?<EaFM12lEtN-\!bz=h0Bks!㴙F9 89R")Eq%Ey`{{/t8jm6̎ʡƨ b UF-8a LfkE _;*c71B j1.Z@GךgqH^1 o0s+Yi#lj->}xOw+T0=;лֲ 2:G$42#9EpҊf':WAE?Oc1]{H8B`5iThRΧ>v'on?STCQX8#SH{_|%[?BS!VlD򝁬pp0B)C< Y_]QJ$Cx  PbLh2ltNv^ @9.K}3L9 G *iHx;'*;8\yWguE:xobh/og|^3f[֣F+05!(IԨ-#&ȼ"p;=0< s?~ɭkm%ˋ $R&{ e we@;dž hO:Fq֏i+4Ce kNƏWR ewN'Xxͯw˙gd)!xzEsAJ4T%QҎ@!r섧ojy#Ƨ| >Z(z_vȁ!ro9W45a^Eq+vkj|汓Pv)tvjfrg>8:+nvxZJ_j޳Ҿqs;ϵ?@;5j+;Zx@#V}7uˠGC6z8A}# tu @:y'F"Fǁ~t5-Gc]-iD J<@Svq\~6atp@+pSz/F^Y##~ =!cڷKn]'\y< Q-'AFrR"Qi1r&1gdK$:,nD!]apwȍS$&93,|EWln o5a :;|թO8N35GG8ߊ$Ψ(<3_82,yR‚:\wd윦adV+vm ,bGmV#u5)2I!Ԡ4Z4yN6# ,JF~ \ xYV^cpg8)gڲeFͲQ/P(QDG> )L0 ^&ro[yrxo=( E84~nM5! 1V{.V%sHi >8$Ni4x۶ٮ/)sGuXwb7ě|r7v8|⦑ȳ1doSj<o3a%Lt؞07֞5&Cucj D ҿ2Nqf oc v(g3D-Ux0Ay ᙷ.zp=AI'zwX[%^V&pL , }E6C8"AyvW/ĸ $5hoY?V}?bl۱?"02\|:tD7k8r&hWKYҀ[Tn; SR1ي.Ϧ׋Z7`CXp^Y\ d=ce:4hVZ3ؖFZL0ҙHPgw-9!lAbT,DFA"cXV_(3.ݮ1a4{eͶ_u]4`rvCJ (ۢq>jb04p[%].."19{Oʪ識ZaS' x8s?sW03 Yy8y ꥑOxsbpBe V8ƬƕR%+AF,ʗR91@Dd8U'-1 k~ xhL:(PHKT›۟.Ӥkp lҀN:b^x,2%%-K[KY=QwGm}¦Q;(Ņ~>ljo; dkIy騟i^\lR]yV𩁇#)lN򐯝Fg %go^o yfROlL+{#eő:,_F@9voESJR_>9 K^ңl^KGO{u a#u.0lぃ'.1;ɧ1"BqE3^ؙgr˾.pC?#iKûN- t}[JvC+zzC r|6* Cį`pJmOy&ãqN3E(m$/+^cȁ!r`ȁG= cڷ3"v Fϔj1KG3{QmU\  +ަd?;2+_tN8l5¨Zɜ0u hЀi?OHFje`h{lwUzQMY!! џ(~amF*C nvѾ ^6#ힳ+Q5z]t .rHF=ȦϿlyCF#LvՅ,/ztFJΆkkiW? 4mC -tE[GF]Ɛ7S~Iym1St,tXO>䂧dvN/^XաQI8@Bp-9m6 (0;N/q#QziqPWa@142|N8>~tɈ`3; AŪ.V = AXnlp:=rYn%zY+a# (wq0tv ٧1+.,a(4hgOFegBчw+.dj@ᘘ]'[mb )RΑlvF§ C?r>y7TIt=W< ^E([ԁ&ܓYX3GB^HcQZAy sϱp5|gXF),+*_7Xbs D(ºx??Fm{.A]~ʻm _>.1a/5 *+ X̎E{ зl3.ѡK7΁(N @y"Ct#+#?uQo;Z[df )t֩{<>ڌ,^Xq7͵5Ncz]o6S$]#f 3@zGh =Бs9y<В_LZT){ѯ5|Q;yXaxݱnC6X0h mXGy4Irq>FLZ01z\]0O5RC eYv}k$8`d?xyRݏYteq>K]U:uA7ѸV_H"L~–mDo جug)b""s`|O_~S($'F(8M-GyѸE9fdx+9Jf-˓%뚻1.W0@>hyn]IYޑ}.|C[XH Fa<`+w8/0icOg4T:{LJi{8]&,pti+wj>mCf|.u"߇ϋ z+3<ȥr>2>}1x!2cki_uh똰l(z6k,cb9z i`KS%d|QWއy򃣼T+Td;KGD+:+ <ש4# `)`xdEQ /ur$ШQQm*.nw4vYE\H9Pե2k u <\#-pk8 Ľ3^ddU\ |; ^5ك4m 88, F왝DoR:IiU^\_xYZ !ݩЋr+D/W m,>}:f0[Grغdx`lL@$[+TgKl/h`^h1WKws%R@E-BI=i]Jiz"9¥`$*/ (P6Z5/=5g~l?#1.zbCaƇ| זTăbՉ0|bXOǗBF&I7Gkcyp[z0]B ITgֵt>tdzF1j,C~\q*rPxǤr

$& 1,/ض8|%1=F'm^y B#oҞj?!inŻ%^+5|`T<|а4r:qFG'veAu.'Ȼ_b񬓠3@`yѳL=q/|{Q17,"'zu,kcjusΑQۿ ykb9($DӃIrU7_n>~njw_cmui^uJ听!r F} >u㡎350S@>Ff ѥ_Kwk";yKGL#1a$l/tpuv|U/ޅĊ~cmz9?%$èGGGM04zG:;Inv#.>;9B;,Jm.[lp""d1LiFc6t)gP _R>Lg9Z IBOueKʧ=ŕ;ixpcS"Zj*p/W~ڧ_^s/(|j+(~C 9uG>j(~s}Y K'ijFKi8ϓplF _Hܻ0ގ_%kʃn7yȮ:AXmg;.c;Π|[ ݢFDח0[0Ra;j^[ڷp mvm i3\c&ۭ8+N225rN1N-NgN/ 숡 GJpylSǣv?:6qy'@+0d'v)ܑ9Feq^M $ݨϺ NBnś5]8p-Z4RQu(7(}iBeHj]whXĨDX'&0 sZA=ȶtΧ 3c&P,_BϺ+iO_%H$42i:kxB =8'^7Ku)kOVay^ͽ|Y4c̕3".G@y3m"07۠I(=/|~~nd(,Zs <|#2MY ki^d|>۬AagGie3/AIH%xTdI>Ra#6T^WuV?F;ah NDXC+ԵIw}) 1FG͢HީҨO:4Za~SLuDozkQ' : q6 lrF?xz,]$wh I'֝.Z _TΖyx^/F6yF I:EK -)[?T;0ZN/Tq~ =`MbOαSU@13MD“6y¡\DPӰ%r[>xhK_>#3Ș2G۪w E/c+"Al6d ʼ3m5!9$ sn4'1ݞF4Fc0%h|S s։,>B0hdM YȱUP"u"Hޓ&l"je"n:lB2DQU|CRfSBYk.ޯKD/]pkݹwGS_c&a hq 2"q h,Pn !(Ih mSxL8Sm}6D/wST0H 6/~-1v,kEE0i_]>GތzC'g,7d;x“]<&.kZD^xyQG{P,ȓ"_/<ל #LomB'0l1_^:NLEh3/ONR{fT6ip@>lZ C)D aWi7`I3ma R (4 Ƿu3P͢PoA{`[4re%!a -Fj(lf Æ9K :B8qd:O#ra8rg=oz.fey˔;3L*(RĎQADbbP̦Flh,Yhtըi]5f#vZazs{sgcV"|9oy<#"!2 [ӏCD-n7!hOBzQY " vJ+WYHn߆;IbD_%CeÖ[Sٵ}2nȲw91 ' iϾ]wB%pOW_[瘍.)k<lgt".p4F;4չT8WHs:$eiAB͹Sv:ȴ?g-`Z!02 /]ie= (;yٶQsp33%Ha>G- `z!-egwﲽG6vrYyzZ {K.Ag˩/JdjO ;}sT;;(vf#8yi8ߞn^NJlvOdG`9˵fЮTFqiy#X&e~^5 $"?3 S1s3>p=wمЋ(CQ˷)v S&`.0 <"3, 8ҾRWfB̖ۘqh&4hZ1Z .{YAn`%3#Q4@"%[Fm/BTCtƘcCC|u˗!~`Pd\w?i<3qȳ;f2>s`y! ԃIEBssap>_ܴ;e7"v1x}AX3cjv nNIo-$҃es]D#5GS>edII/[SlLx57!n&plD}5"9VP&iGbdsPԻN2F8q%Y#7(;$tώ=婌Lmo >;+75TzMPwtO4(Pg!NJdhm;rT=_32Ra x!oEtqZVqRoI\rH}=VJre?Ep/{}{Pw/u;ȦtUWۘ2 c:֍S Q9*<W(6r;]8sQ:A=AfԸڡHL)l _q̄G]`ҧFWiΔzHò\m(3#xqW\hm:Iu'r[s#YҝȷWPZ>KჄ:vQEl4?ú9u ym ֣ǫxԄoEE4ooHk,1*N&벊;MByPvN{':;UΔIcVp=7"Af}).teF8¤iK/SÓ4}˃ (i7ά CJ(q)d_ܔecO0S|:cdYr! Y"* 8zY1zT+ia}W?+i7md@q6LT]&Fgr͕7HYMpt=3;k7Y} 0-Q zySDsCV)L|akO<en. 8Nyr~E0:q2 "dJBh A7-]g?g|@8Qbtp|s2 㫻'ODy5 FzPY.ZAN:UO:MS iCtyOhoZtT$n& _Y΀EJNFU6jT+n۶nGX)Ktx^ IDAT&Am L0_-7Q=ZЉtDnfy+ݐ'6d~#+N*fOy+tL#N7R({+/ ^o^Dmv%gވPF4+zWzq,kį U|W;2-)AUpYSeUZUz/-:Y$:ғEnHޏ#kM#?}05q^v11Gg{َ~7QNڑtq>.KcTP6e^$pN;# mLx-HEo /l{1}Q?/ u*}|h<5kڝc'tktθdʻ9j@@l,f$282 Gr~|0M N#1AQ1q35MdM: 9G0]#3Z7!lp1 nxZ*zwF6Nufݭx;_<צ Qp |w84xh*IZ`V; 7[cko܆OA7VЩ״MԺ >$<2 IԋJtշ_]]$p$AA:l만Է vmmm)yRf2= 6 L j"qȤ aRKPxejj{jK+qʿƱ]̋Ie}V#q6~j{F7LDiQc` $,_F9U.=G--kirMBSZWECL*`=4@63ƸnڈugbwG_) B 4̘AipS"|d*u lD :e.Fs f?Pfqf߀_l ##K 9%_ Gu{pNMs/ `a:+,1B2dDr *0ZD=i 5ziq]S'Q©H=n'1|C TzTȯS8P !k8j~ZO)M0A!Ѳ1#E-<͠G֩܎8 k VZ/K Hh|e4xA;ݞ?7#Lw&%ll??^:)_vڎd}K'DRE6iEPāeM d81?Br_U_ӽT>Z( pL ǶV'y%JS,55edǦ҄~? 5 GZ^ ⍞6U<_eއ*[ӎv2\r5o â K#uFPå?QzT3> =/37^vUu+?ͳR qsmAE֋e%p{]:>WPMcyf;}xy_{B'_Q2g>2xZ{<|wqz(KzwQwE3aOyA C5, Ө>,j6 S;p 3~ϔ_F)yҡnRM.G82h&cE9< 3ׁI9aV&21ټ>P)ٽ)qGxiT>;.nxd A%$[G ތ:LUN#138mQV ~27c>wɏ q2?~O3B+(7l^=h J8ˀ49;f&\=gxxT\uYlH_?ʓ+xx%=ڠF\*;U31g[ hʿ;,a ? 7asX *N>8XY R$rR@ڑ(wDݽ'v/oڬWfG3-چ)ٷN, @Ig0i n l⫨,@$@ cfݶ3$PVYԑP 7Rc{Fj/U`zG!x+Ym\4[FQD;J_+l*\$җFJ} ΍L!]'x r Pm#)N:%Se-iFM!uc;xSB G4QGdeGr*n:E%\Cx|N"K͑vz6>g@>޴M@BÂԵu1 0\) TYk;}y썆^i^&9ō"G;Ui@2mZF|nck6#dȋ>wl)f#l=M{05cca{)Hǟk3jK 2e[CG%ߩĉn} lT];Yr\֮p0oamRx@V;H 'XsWyxkLR.MD=_ M>GԀ7e.wXZiw2EPa}/d%c)͍F,H1Ⱦ>92E`RyXGk|w^<`VWS!B#oj6tZSҫT홬o2Q\8!n#`iwM=霭phY:1nƑg:`*NCCzld#+ղ::Dq$'* BήgM0U\0;L+'`լ^z n;7(䊫C<afN)Ȉ6׆e ]8t:7'SPg_nƉ= ˚Y\C R\t,Mcŭ7S:(A.4{٭CC5y&vKi/=hGW&X>U=dQFL! Sʑzz&r^,=֍>:N#{{*ԼBx@,Qѝ̦̚PFʧ>WړhEP(#;FfI[% ɳ{vmo 4 tdQXP:?yxomc0kCx:YAD:<<{pT]sL/~a ϯ8rvw*ul605s. >Af6.:m lz6M{9S.E!󿂠NXfϗ+koՃ+>?&NeMCoB~-'Pn1(9Wmdwl%qKlzwuy;&e)fĞq8hΨ-),0;Ig9iʗHmhz+rT9Д p%KsVKl:󽜓*$`("\('qiy'^c~u:Z?[Ϸr {#lS}9>i16]ein-6{K8T XBW+TȌSo  @aX#﨡f^JGEQ 4+|@m;@G'dZc+K;F "Dq(U&S.ax>_*aEE,F3LNFU(6!?_ykn]hIF|-/TŝSag]2C`CX9&RVIalnBTn+% SU; roQ) n%f%o"U5A#8Dz&Y-_O/mZYn zҟ@qP>28ڸi*;ګَ,Mjgu RA3@=˨gIq8ЫN@D&>dG1| |˻F’W]ےe/R_yZkD4,*KW-ÎT9n9MOlےSɗ$'eIfb G!:}: D:m?IT2]y0씵]eJel{qX.IPg5=Ox 7#:@m.9.,́>OudqoY87nu4-M q VW {[u[sw߱YFI~S),κs@gr3p"li).j6 9^033 )?2 "Y ؖ8u{!oM ݅ @$'!xtSWI/fUGUl#Dm`0`t%@7茂$:rT|y.)~ v'YtBYL,wo=qz1ʽTpp[Z&YwtO>J8]U>_39{@8tP.+]-wX]<||g$#.Wޭp" L™־vt2'b!(Xbf/[ t¦zhF.n{F&c.>f\&wJ۔iat ;2aM)4)O6=b#)JuĶ5`?cyYv2O H rJʂuIAYpQfP0C1tsI2 .kϨ#ؔw3adc/^_%˻ $990̌n,1u(ZڽmsŴ&t0W҂.N\qWT(otd@萤dob2sAYؐX@\v SȬtz'ҠS:*ji˻:r'J<Lu#ö 8VN7Noo { 7d|I]#k=ny6JAաlY7~t60{e ']댪5+#%o Hk5@Ѥ]_h#X^GZWl_p!e;2j詸 țF6N٪R-_╯|ez9xQo|=}{rPm[}\_3uk%_-Yܯ<;?=nw͞[~oV:"Wپnذ?>-w>_הfF-&Ɵw=KvXt@uW⹿fyva&t3%בw()MA>e0*#a)_`R>6SM>net, IDATQuVA/<6uXfĥP{Cֳ5 IFX3@.jL~ _Lx x 0hg߂Ul euY2p_1,:29i8g菍`פgߍ\ׯ 9# =lDF i7O @x r`:=as^o^u杇8c:LY, 4& s9S,7z? fW[~:Q_NqA k =tu.3 ,;s]Ot[ttgAPy#g4D(:1pI1twxICnG,lc?4s#j{{*z_#;Yc:Tf4>$`9-zCV>HH9@Oÿ߹N< _/=CG4s Ey,"YjRA}s;j02S$NiUie,u3>Xa&._ ?w]ƠntQt:r~ ~=9Hz%M~:ExYQ.D&a~264oLy~@v*A+Z'?Tj;;u pW Y'{;EFHf?ՅyY;z4WV]H #ڰ/tz7JxAuo{`>|SgYYg=]y׻U>W)O=O+]_WR6q9㌇7?WT/?,[6o*/{o1,DFܩpսT^9o/[pt#u?jhIpfz5Ε#мcxc, 0Rjl gС Ķ_i~Vx{͕ 6dFEKqWVִ.dKL9 8d/^ C:_wf'o!>7vxq4z;:&~Hؕ~rpbdpA,E-HU?,oml~(4h:Kn(Sw$OE6vT]ѫy 5 e >؈m \i/iH TS藿xSeƭa4G&Тӯ%nhp@19'AO9 ^P,4&VO+=LL [e`'Gpuـ'K'T_pӜՏ *3*!r6An,E!H;(d97 Q/B t,LJ=:sS9#O?/ab$S_:hGǺ5G0\ q>N4E AlHP9nޚN4·@*IC J̴ Jo7yMmnQ{0t@ j7 NxQ8*# q rnxUr"6de%PNordʯ|B=ΪYP1FPFo u2VիW;q碋.pXQ z~.,ǔ۷.,e?vsZ>- ?<O[~)O&WN>1" -  O>m|uv9&tRQqu(|՞6kƨ;X1&ڵme ނ!LuOg>',1hvul|h$jD3^WZl<6X3Y\WQOu" [tT p ;YPQ~"O刧ެ ;a'kG33F>Npuw꼹ߺ8.lf0@J|.ʭ[Sj ܺT9pݽ< 1鳽i!hȼml=qe_b۵ G0LKϩ_%ft2Xbr@f|m#i(9y뒇MO ]ۭʈrGegC&&` /OL|ڎg{i1,c?L䕕?ji>/= t\߃?&}nA7drlcN+l ?KkEto S v=gpqK# 0O@3u.{Fhnl@8Q'yM 7H̤ t!`%˾A[ANyITnW 2vt2ɳjD6 x=tH&ˍHdjYZcg|y1aSlwN3IzuPYңХa:T1ZldyGm{| t)B.yKـ-S-lLכ&Una]9Kr>"M ݛj]eLtWFYI6L{ؑ>f@N^9a5'\ڤ+uctOz>,>FUfӊ /4S$?ysuF=8nA$7Kv#| =lS/02`tl033 !VrlܴbgemhґuH4СL"`/h̆,l8܀*U+F*MMWv{ddMȀq'RRKFYZ:v!Og6 l E}i|0 oj*V>ip-Us0ޖ-[˪U%} qy2N߷l2X4O}e\u;O¾cO7O{F9|`<u{]?rwbf“%߻fp?w./,/x?.gW\zcD-wct.nyӟ^{Xַ:^z)-)ws2GwT\q޳SzC8'|,"2uY|i9rX^0Gl*W|ⓟ*7_2x8k|΁t-z׌lnysrS~-|+_LۿH/EO*?rᇗ?'>e6rmCE ,J`^qxtqn`vgf"18::q\q^-Fw<8<$z: W;R f:N~8·If]NpG) g @t]{m2M^|}x~:W7aFeU6C9LV9V眂Gf+f7qͬb}~S YFAWI|0ݣt!'gaeo9]\hu&| ~1u33,cvxlcͻp8;{KjvQ-4&JġI&izHpdХ#8O@)CCߙ9s 9i*'iHfxTvwج )SM[po>ԟs>im8/ (]ct<}°{-܊dZ IKE܏>lvݒmzYҵ%YKEfK8:S"cKC 3WCK pt^su@1]{hmz,osE^{,7\>.rkE.64$'QNd WmqeVo$ʾ#>qIh)l7Oܑ iuN;:f5P٭qk+}!9seݺuOct#+(M;6Ճu횬ޛV[<8sO|feAf?쬁[<%/yiyN(NӞzN9t9c2 ^û j\`ы^h 83|Qg=y1N;|әEo< "rS{f,ag=qφ~Y>eB5ZbpO4AHg<)0;>5rye*|ןt,zs{~qK-2;/;NiCwg9,Et~}=3֬YS^11SKuFR%($ 0%ev0gx$iҧ^ID?Q#٘QFy6 w(}]6#&g4j9`bu9<;r=7IH]>0\=geOMcƝ.9m;N.n=8ʮ(n&MQ^7V$b%qwSLdO 6%Ç ONBf|+ip)YΆ PXw&__针:2 G 6z3}ԉ,a0?dHfpA.|N&6̇IPgJ|`b\ەҩbooѣ#; LϷl/MռPn;m- dP.m2 Y}ۏq6?b N1.}ep7,(s7aH7lt7g:x2u/ŀl U0.\t8^]a2#E8SS\rDKey sRZS[{m匋?L0KV,l@+A8ÿpfo/oU۶Aѩ_hX$^nWJsIrMb--A :11"_~9kK!go aA@GINhFKP.'[@7B'kR?J*թdCyN:6IT.x9=0LgPq휸nO6Rn:h,EtrSNiT 2#bivwfNZ#|I|ZFY }$]z:}´ $椑tjtU 9&S!CH&^Q&i[)Ly,kOnA`MgAaY9k(w#OL~x/)CrFFw[:=є$Cig=hgQ%`?aZ:yXy4՟ZTq>yEu>1@HwK4$"d]aRϜLh0ޖgaBY3ĴSg KQu1g)Wgk{VFscT=}2;vo}\S>z~Yp?-gR~#<85\+O>Io|٧1+ _bk8|*nTY^:G<7~ի_ ou#ktv;ZGudηm^e6]w1e]'Ȓ+_h%^V^җo}B.-#qfꩣoӦMe=ӯzGߌd_Soc>H].^UN;U\ hPxex}>KI_Sŵ[k3gsm}=r 'p ʿuo-^/J`QK@'@ QeI.>i;r?q66M?!㯓Ӓ]}v e>cq$-2d2=ii~Wĩtۈ#Tj'=3qw~q;i/H+kzPV'K[_W}8îwJ^uZ|gS 咙 scDe?i$kGcwH]oȈ e 8:5m/VϚtg.XlFlG'q)߈;#V_{Argl ltr̾`f=ؑLq32G{T'5r#<#Ы"t6-[ $S(_L˩C M=W/mGimᡞDgW2,Es͹L̰͗؀ҪOЅd C|0gx@i:lh ed QA{e췡{B3V uٲaxYNPc-K:iʷY@"xE\iI=iNk>kc\ O0} |wi#b v.'/Er@EB1>;J[wq. 9t, 懿H,5u2ҘqJ%]瀲y\Tg EVm2v6^X^r.8k[u4qzSKW0¶+Olaje鬚gB#h fMb IDATD³iJ9RRъܭ*:HWyW`r˙,%F8N}YeK^6=Œzk&q*0!ufNeСv3^s'AZ_g*e/M FՙN7TgyZ8ԖNϓgB9i'/0]^u5p&i77 F8>fn*%6"M=*ʗ"f7aJw3)fȡݜ61$Ϋja)azAF/Hx3p=:$j0jSyȃ=< 2y.sK߈6)_>Oضdp{_erQ0Ъ~ T<+m7j}3\_yWHY ŠR/ef<|ChxQi[U>2A6;?7p{fO'>I!}//~8"% wRvzqIxN* _yLʭ\udVo+_*S?Y>ˆqmyoB_M9Jg ?|- '1E~ \~U JtV>S7oH|' ɣMoJ{*Pw/snw;C@%+_|qyk^ˆ_ˌѾk5<6kJW*̅}qݼ̭a*T %x E|3# _Ry_PyβzsX-^-J`Q7:ɟGVuyr{pMӱg8X8uqt ly 9Y_Mڦr]2}ϳFl s$+3p1ڇGgo.6TsTց+C$Ny _-LF<7ڌ8#9a0«Mc%a1ȱI@ڀ!}ֵ t=O0Jc2UGMxk 8moF9/ڙbV>R=؁|bjl73`"KI~̕((qOC)03;سD9dMzBK$p43FQ= 6/uzO@V$6$=@8f][mq Pr}C`vԒer?VG^a꧳2;Όuo]ekHwAv:Fa v怩Y?1-g ibe#腴|c6Aa{qx7x$%&  o{[Y] h4#:2pǰRvw+ ;_v!y7Ϧʣu|\ꤪ~ƾ͹iMY g_뮻 ' U)>1eK_JzSfNoLIwTOcfYڟ,˸kʅ,9^lF~7fO]W_CLe~0__񺟁y~%?:Y!-gBymݷ 3? #.o,xF*ߞG'/ul8K}keߞ[XJǘ&AN>2-:x^F]CӲؾUP,e\_fYG;-2FH`'Wٵ~C{{rN_{bhiu_wH3:(} p@Kw <@Dxn8 k{K˷ml]/8WBB#G30EfN>I&&Xug*O"h*ׯO颎 70"IsI4eL#,ЭF8sxpߣYޱb)o_f6oh3l,Op D;Dŷ?|rS ùbچkTIt-4*}z.mȵΦK-oȶOkN'A]oL`HY.%C"h Y7@I d vsinLۯHmi=m 4C;OVBMDp]dgOe5*+ <ۥ’u%:3q#:CtO50SΓkzf ղc5e5\ʇDG ąWOio[x:E) A:t!#uEyg9iz()l$)OŶGՔKs-_1tx<+7яzT_\|9]kO./yʇ>mN.yX`u~ ֿ?0{8u\;kr6y;Q^7d}hh(=W,*ԛ?Xޛ% n~ ()O}3f꽿,~s h*ֈ|>Bg-[zMy;["T.M ~wXf_y9l:iwsyL  5*Oz{zQ8P>FpH+8 <؅îæӼu>~yTL?-z[PM/ZgjZ\Z"^h, :StD2Qy-_V1|M NQ w]ÈrAnmRG5.6A0c!JN娹ӻu.e:p$?7'4%?Ypė&MZc騹u![9:LYpp HdM 떖=~W#ŒxSql;Mt@֞Na78SAl _+8Μn$T̜TF 4d_a%m<[T'ڥ U]4zsfte N&yݜ7W&jҴW(m-߶Ud! 09ӠLHVFe,'$as݋ӯjv*~2͌G݃}厇M/\f ݞ?t4:=$!ҞIe] 2Of qVtD_e6N mU<f uvTcV'K$DZ GTeJ5[ed4lPs".nBf!*}S124 ˿u գ@(Q9JFE!]Ѕސ(&inh[ůJ'wuQұrxmG;`g&F)Lwpv"K<h|o wC=8=Եn}ȣm|VaZ45 ,Kڻ[F\>۪d|'wpedD(M/ۡ}Gn^@S[saуa,y :]rԽrg6^D&|Ao:ꚩP&Q9 \ٺʊ 0r^ la -5`l;&HPS@'~e.%TQf3 0Ι?'0.a#'yWKuF|L+^@+ѷ`xaGRN:uy&ϝS; >NĚ)F‰1`[ iHچv`9W^^7rRzBo/z9?95"E &%# t3;#sQ-xyf:Qs::8U} {窇ӿ݈or{8ʛQ2tquj=NE dՎn=#ʳ pyɷzdI~5z% z" e_ T!h Ys7޴Pi DZH(ufg)3Si!R,V\Y؃U"\ru6r\+mB}0eљ#;#_OD3ibC<7NVu);{ ?lM#h[xA"! `m-iʃ^E#IeQ_\$TAEtkRxbz ә6vs2 4,ȍ2)+#WbPFPBp ;Bw,nJ0]q|f\xP]t,u w6,Φ29ˍ? gS/+E@b M.c{s8f5r{PauLUwۮ~: 1H灂1w5a-S(vu*3:ejL&wՈMA$F _1]]h 'dpi |Hdi'_0CXg6?޼y#:#,4/|fѮAєYZBG=ZK4ck~t(;D 8PNY:?Y֡|t,-hv&:,&Ն+> [خg8qy<.@vS1Vzj;ҥȐtjoĄͨaTYQیaԡXKa(lQ" Jd #oK۲(2=6|)jhNMicKv#/Bc@nA)9p9iS2)3lPWaQgh ,2e75AF+e ֭F ozc9&p8`dVoA->m&m0&# j~g4ujjdd+ɫQ'2vplyP))S\yńlEpNǓr+ؔe=OiM>ów>clv&,{2wWϡ"ʩTetƠ>zWbȹV &/T/C##k |3 NxB(E?-i=V+M1N'߳-*yhN\ϊ8rU@Us/+Zc<<,D GEҍ\D_01,1bT/[8ƾ7Tg}/3B=C^Av3qd@k(ygg mqORH` ;mg!!\ay1}1j1whuSXQ)quѽ_Fx=tl cÕp҃O@|2Jsm` $j4id1) rѭIK>AS'6|ʅS!#/SP`Ie G`zCHA}K0"kjɃ֘f.'fj.cC^{e4[@C 5ǘwYWSkW}c>aDӄ7[@KMn@tDӷi*#?"ed *B,aTϔ 'J!fF.{=Z.)#|槌6I(G.&-ʕv@~iN)GHgZv@p҂‡uE7m!?[T|CѕN8ZPC\>tmWl[>%5.{g%L2ZPJ8c(ڔ{|Z pb>sK@~̴bp;R;v{Н!Is[0T1|GL?"7dr:(<9XC1z1_*l:f劳xûi]8o߸xH^ePL;I$NPDW]UNІ x2kJ~;g )`j=2 k:O?.c-_bp*x$)%dr"c >aIǑz -,_tX)`9O4mg{Lf9^+]*#T?/;Н.s?V"//5oNR3c a{0M"`lwtFp|: ͼ޹]:!ɖ:WOmXlkYPMm,d]C j.R-Yatex-[ 0˽jBm0nh@ 5n~M<7ƒ'SL=i ,-$v O㯯uƾ-qre'|om#$NxMPa8+a}սO{/¶ӱW&F24ْUnS26tkjD26P,E~JßɯCv0Ȁ|ka=orORho [;"l .z*)k i+Cy+EPS?5qjQi>.Ȏ O08չeD^JV ~JD LH+—? Cq2(sYqqc;pڅ cj! x >ȒFr.Yi~(Ӿmcߙ;y,etD"Cx g`NVF9Ga*')Cꩤޒ24:")GI,!E)e ( 1$g;z΢ܿ"xpmK :ysO)U ܽ$}ǙCg:|U~yq0LXÙzW)AUo q`|9ockqSːW>U#/wYԑt!hgvw,x3aR=7,?>O` 2S̃{o!(OYZ1I*8³NЧh^^[bAi>\I^+=B2- 2WS]T`&[:65M)%KH$)oYzH6%<4!CZWTN|IUE#궣P'8{IrP&2,*ۗoqTAa; >q_*r+ *plw Q WN;`*;3!$%M`?~gU6i(V=z7-d7vm2Uv*xiavC5tpl>Ӧwp(U?y흎b\im/Ξg FYzQC˶K:X:PԕGvB8?0blGnapop,GHy<@a*>\e2pA˃XHaۈ+?R^̡~o; OyF:L|<Ͻ!y^XDPrK9T}JWomRx e?_uսٽ'@㙤w陲 ܣ%"={xq;xιg+WsΣ1+/cDlZbCƙh^gTuxmDuZqgh7ip:F81* )j~ a+' 53A'/:>xjp_h9 2r}:\Ji9|Nse~Inp:$5ga.:3HKx?3eܗ g>4:E(E`V&#\ ]{p䰃W*#1|n9Ux¾yҜBRo,08Tq^™||: NUɶi"TL'ƺ?ejBȟ NI``/k蓮"Nh^c&N71uj_j u| qpH X̖m9I]K0O@(_8/ǙV蜚f+ƷN@*MyJC3Bķ;+e g y--ٞl_R}-vzG hA5 ܛ=2Cs`xP8[c0 W )MmX?ꐰCӻi`pQ[^vhE#Ap׊ҭv CJcy ARCU$` OVw{(<VH LAC`}H o*dp-AP[w,sb7kGANFy- ?yc-"2 ZUR`ÊCh0(ѰV^w. :xz{V8xGi :ZvQh먼Im#*lV@\t ; vx4ըiAܗ ,70I4 d|`ӖLݞ9de%-@LDq 8llQΦ8]F84k{u:&7+|d!)EUoȊBIh0&aG QV{^)@^hGF~w/}e$p 󰨭zbuD0r;GpC[:t.VEϣk-ap¬2l^maSJoSN۵{s︾_p`t@ $2׾kW}.ٻN12Zgsx@dF<jTg5+Y8L,ϬF{c\V-p+\3ȵΰ!ys!ߩt|݉}&Ek`LCL+X߅AC/5F@bT:z<#9ӄb>ui'jb~u2fکaxJ|z5Ȳ&*JrܿbmX =ПV^Uhg"aSSXHuj-֮+s\nirNXIVc=8X²tiIyB2' D=g@ڽl𧌐A@n]:4p1Kg 貽 Īw2)\% 2_tN[<@n_7BY3DLi᧟vU0BɓC胑 N/GHN8il AԏDנBv7g]'Ҡ:::t|vP9B:{Le2zn76o-6gւyO<: PՖ|9u|IHD@JoaHwR0҈+q ܛg=-X[Kرu8R44KAa6 :&p pZk?yݝt@ ~9i7- h8RbJ]XH.}TKpd$ʵ&FBtCe Zѥ<|v\:2I;N׹ ,pE^߆aXQAV17tU](5kK:/#QQ2m#ǎ5F@V;T!w}*ԝكxv Q4 k55ЫZ J9iJ]vl'>848Q^5߰-ɟû4cu O-]2;UO.VU]lS:F{@(\1[ HLo^>06NY<\m,Sμ_A]pRC e~g:Ey%]rvDhTN,>eu79;PāH(i}?Sї=N!gUqswN 69^k;;:;]!Uk55ѝdNx1(8v| 8O{w/2m80ʭKFƤ[We+qE୸Jyw_g2|HnmjԷ]ĩ8[]!72 m8^^Xı0/ |D?+eOD(5z}Yw+|Qϕq̑,W-sK궕 :5Ɂ?3&}>8uiP󸒏,>.Ҷ=SamhgPfU]{ј\북^F[]lt:ʵ^HsjG6چ6,#K;m!s!ݳXh֞Qgҽ1qC݃-ơAC9@ "Xu_QxZG:ƎEG* m;PmaXMFne1D=~l%[+"NGĀ6> Ct(g KoeX&M瀶 gMW`|NHZ38-ݦ0˼[!ۘ%W IDATH&Cz 9I7vU/nD>_zD;5; ?QkN}B~G"-J_±}9i?9AgN FW [,%dEoep $0@ $8tX5c;:Wа3/{蝣0\ay/[6sQ+ƈơoZJX3e3SF5Bre1Mϫ1>p*' jK 3wsm9⚲OXVΏ0|J i{yN|Y& &2''[j'j=-B` iΊpov X2PFJСrgQ yWEѮ*sR8(A,7K[!/2=L1z1ˍLj?cEGA_iw`I7,ԍ2B_з${V#layG%]QFro֐v}*Sz@T?=w>2An[+,\!\$!{QbN>)u~eЅHDHcPȂ~y'2ÄL1@;6oD'>BW: ϗiPַ/(4.M-":i$Ok|9ó iఄ(jZïx`ŸZΨ§$4h_1ܔUV݋tR*0yљ@WCKI"-+e}#C9KꡳF?#>4|YU۵7[c+#RNhuas"/B|{GNj:M!8"H*#[)O~W'7t; ׶b!eWTUq^E?#,Қc:E8+#N00o~ţ:ՀqI 6uV_s$Uo\ $0@ |%%p8~ç7Sal9&+ ˜DαRCzeFT\(?zvuC =שѷq4aDxK_bu Cιa?wn<0N(95/c6/Уqx/R$s梛8 d)5d O kQܱ}0C, mYUΉIL5^CVհtL2%+G8o{ Ws7-v2MqөފMwPЅa;tW%_!].S~|K}_L o-*>Jfi)AKyx)jW&"ΏrF8qJwi|=|9`/#+w#Gi㌾ 5pk/ $:5Ȉ|x.WL$Z\p&aPԿ^G_ӈE<` {$iZ=Fx8&~S˩,N͠C/ȷ2|Gn5BydDhȀ3{e8>_IDw0oK$:'k2#,HP)꠽BC qLp `aK(6jgx(i4*inC=O0x/1p(R$Ra[SS+pY2x/_jgiVǧ DiexHrG82;W)k G4c;c|T+p\_FZ sbɨm7C,x.˧,, ]t͢)Vo.i!v^tTdÒ}ra9&d'Va\4ߒ]ڽ"p@ϒ#v @ԥl aJ~[.L.Q3_JdvȈ2d|< 3^4&t(#u'O-q([7́FDxQ: h^EF)>E H` ^pOSIdSMT [3/tdLcwȷ<1h3+0bI ; LGF]?Ī+Ǝ &okePO!P*,cɩL%c2FV._NNGП{S҃c 'z&F o\ &D:_ xI|sN"}Nji'qnm !Ǎ"F9\*@5hX981 zCP+6|oؿ9 Ey'j:|QNP+1$ \0 /O[W0VXQJ[r'Ϛ>1wSTkrOWGڑ)S \ˆ WJ/4[:Ҥ\ud? z ŇtM>?A )T4rD@O~/B7mJڬ MsUX)e$ߊ;uUşp }8:1X!8h|*866ؽZxo"zy @+)>$T)/?zGG/lQ|Qö<DPk|ȾXY(+dl]l!Dq؟zΥHSF;^@@>oxc:rH ]…Fϼ@N:O/@D6b ڣw~(g-HԐlg@Υ=#,Poe~+ 0AH` Hn$y?\cyİk&?,TқT:OO~s:CnV ;! Ró4R.Xwk T c--ƥ֊xvVeC|Je|vOԯjߴw 㲵Ä/xڍ+svC`p4We 2*T(꯲/`a`$9 0(*,ojEZ!ϞscR'  ƯWh[<p^"$/i|h┵VH$mH|ꈗt{aEKA- oJ:iGG4`-sD78b q⓽u* \*C 0ipwWʕWE(98D{yݛ8\)<57<`< %t>Gι CmtSl\$-Nf;Qju=gYٷsVA8?+m i%Jen&׳ev/oRGvyqQZ@*mVK~d/5SRWiX  _&jSiNb 5N 0}d@KMcfd|6y\c3JY; i=qbIѓS)|Sbi^⦺Ɨ U 8Bb,1:4y$Eǁ7E .,5-nqCmh W^ƒ][ysmfxNHI 4$fBB7frTEik巓%eI#)'yM[zމ |C߂Q@%#V䰶!D`đ'1ȺV[]g+F=4E&򴾲.D: +݊zoA29P Kg̓4qGm4 ?=:"h\ $0@ $;=lj>NcxFS1F wl\&TF_1*04/de90ã.0gq;a``0[ıV5<c2GFz;W| 7|=cm?˘7c]yr|Κ74('gNޡ JE<%Ntprp9M;/BF:*=quNA{sʴbK?}ufx?LB"u+idN]j'wa)_uݠQZt"IrH_d$rv-2M ؘüνG9f<ܷې ٙ6/ 5Hf!]kڱyKi+p>+1L7 LoT Zd- >|WW'AȆ+)h},ppqgc ɽp2r) ~ÓݷOjAn(AC3O׸/| :BHG‹ԏz(4C 3X%nEsԾCa%*+&fguYwe[g : \|Χx}"g|'/m'>AUlj94e9 H3d$O8ȫ=R@^|Kn|!KX9zd[=aeXd$lk 0ų w2G(#9ee}t(NFW)x %-'[=+޷qφC)ّץ5:&$|/"'4seKQ2:&+:o<0}&9B?_mn}kTx Ž<CĝkW]e1\7vO.e9$# ~iOy,#@s Y91R#O~x` McȨB͜Kz!@)""lnOwT YQ,=DQcR#8M>r=Cѥ䕻cmwyWi$X>$_:)!EFiHs~ìt䢽I0 Cv)FČ8 `<[茐ZՕ6D[n'u$z: t d$oyIƫMN`gC[M}_u, FL$r,ae]/g o8ybHygf^em}Kkan, M.Nzx#(q;tM;yaSCI $- ԕ7?ٵ`O:NJ:+^6NVbm R`h2me woBDDk\ - !"_)u{pY .;a!ߥY+p&@dE]e4jTAwBXY)ouPg(Sr[w($‘dJ]{I4_ Y8atљb7gm#VlsJ)̓6WЗQzNٜimaom9}}c@Z$0@ $p7@Zc0i$j"lmנ1{Xq-SGYh?| ʽ0;nR3-xentauR(Ш|4A#p<,0m>wc_h=vCRK\MhJ 0 Bide(^7HFXOZĩJ=[Nu6ِ.aɷB*4򏲶$*/9 P1-pŕ(3-Gͅ-%=y 9o~ `487K1_ 8N,@F~ڇhF\(#pPwۏrv 0PĮz9D̰o|MaBXmxO̕eaFq1QFÖȴUm=>mhOEG4ze'd"ګ/qjcToj IDAT(?iQ2:0|cE`w>Qw:&О3mGe¬OFDTك a۲U]0Bbnf-~#[$:|C+zZWH#32SV8x|d^DeD^W4[ F ;;J cسooѫ*T4[=V'*En /=}&"3H` JjI.†<@carm1j4r )6r\(pLAsYd|0[]0SNA wd(qlj"0lvP;Oh\7CX~\{$#`k].Y0]a `O0q*QN _$:i1R?և# i#ef w(> Ã"MJ@0lO.c<\B8rVvY= v?;_)#\^wBW|iJ:~H,\CaGSn3e.^`6 ,A-R6 U52>(,/ZHh}hx6sSٷpBISon-7[Woo[vT28hX]um i;au0N;?9wRx4ॐ+ekC>,<3C]# P(__:NNjw!NiGaF4];Ps{x$ ]$7  ?ݣ2o[Ak!Nܕa5 `R 8Yte!.dak]8RjS'}k G0r.@/~4ϫF,uBWF`qgIy6e僩[Q5b!(UګNh[d7|%HZe}_t4 |N3 "Q,=‹>C>&LrڣV)1H7@. 6x_Bꍼ&]Q$I>)]]49on_q׽u3 _ 'i^B;6;K)C6MEwucpAem2Giʇ 'G3ex$ PCЅ$!r42CGh:KJaHESvt ^^^: qy &;(a/_A~,*%/"ZWh13}O/W꩓\vc#}CKzI PG~ N#`yeG'#/@!g`\AE:Q9O8y}]wٷ-@^<oyr{ߒO=''Qᏸ4񛾹Юng/ʯWn6U=ھkǯm?~[;/| mw ݸCao_1 -/e{?Eֆ_ wE_|vG|ޞ!k_]^ /-`Z8\ih\9:{Wm0|v=rNgeĈd|ŋ4LcJcqտ~V^Sʝƀ {)AN1L?G.h`8.`}থ|p6XQ1\ kps_uWR( {١)4x{=ȪBέӠE'H7֑NnU{7/1NǨVY,WaXK6Xŵ BӘzY|G [[S~˧ Sࠈ3Źsʙ@P5}%]`@jp-Lqك%˭$oh[K?X('AV?0r czzDT$vYbə 9זiՎBgt @1:R8Oq^[6^vtBqYt:LoNd{.cuoHaTLSU@\9[9yo'uTE2:/':Da$:;a_D7h`4OSxzf6NQ$Du|ȸMWUr|% 2r QCBp!茹jѬ\|(1IJG{S<6{5] !aLʓH@GpKƵuJ {ANWz|jRUF%\0_Y).۾LpAsʚ Wʳȩ2¡J MtD,=C߶(d<45QǂrqP!2`UUBJM1E$0wC5߉3RD]Vg:^I;>XѝtTը/ȟ6)ʵV<n1 ~O$*(j'T=$~21r2q%t$r~cch}iȈ:tX_z:rؤrVldg~jdFglW`| 0YscoRHaN):H@6ެ*ꨑZif32(d={?a{a8w8g^މ ^?m~+^wNu jۯi _[wȠFiqOǿ* P-?sht}tsUPDb7cA+OI'8Vf0BBɎ#@Q4B:D{8=6hWhmd՚9I9-nAKxֻq݌#'[6)bl#`[z$g8]wJ~ Ȋ}ǘ'JW 5 Z 8aHt.mulϦ&*H5~dQtNijΫQNFg"aELהV&2MgT\@XMIƁt6g6N }඗땇ר\=EvIMŐ $-<0=j>FR xGBee<A2a]uE1kԼΠW:{1FA[D%*:R.t #[ȬMiBıR )J~S?A҄nhV+:'"/QQ~F#sL9m$S1}P++VNGOm')vIW[2+$xf8DKm) x!IS|˾1i19\S7Ru2iB&Q ʅGJGyP^-²-,Ww $1 &@y#ЗK.=o^zi{.>=oO|W\ў'<)O}j{MEw~n>W$,Ézu{Y{;ߙ_P=#?@ځ紇<۫_9wL׼5I;Wο”AjA_WU'a5e?ӑOϴtBcowv+,.k w=UO{7|cp>统>w|Oj6}/yxd%/yiss'qo{;ޑȍ?i96ekg;/`?j ɷ<[9~8N}|?3A+2$Ax/' ڳ]wiU-oyKoOv{gMٗ|N5dmΜIv_sUw67g;)Ogjq&n/<|۩:[]<;Oozӛ>:7~/ÕNqRo8Ýy؞ƷWV1kP\1TJŬSa=aWgf/~:  hOj8c>a I I.mOh]zpMak۹C1=P}Q.Qs1Tё~WYrH]GV`⬪djI'wGR8^W~nU>O;W 33 `Ab .9׀|ΑwFgȹ Ca\.VtXCOkŷ2lu/iⶂ89$deoL>l8wJ=l)fC~o*4T!Ywzx33@TDGӒGzCVTŖ6?ܶ+M?ǑBG+.d88, Y_T :'0q-(c Jb CN5}3@0g(fuCu~+ExqVtr5[QX[Dc! pI* a=$u``u0mn%;Q$GCsyXc+5PopcoK(A['Ȏ#L2p4`&D;]X/FBaIgV6yer1Xɍ\ЌX34[/ĝrI*j!ִ8LSxdW1͋dvqśLUJ6  "1O>5\I}t4tܩXAӨ#}fW[tIH{HgpeY[Lt9,|;xڑg7uBe8 2 JT {Oϙ0d5g}?^җn!/rRe?k;F~EkmW}//'O$΀ÇǨ~ _^W#oj{}{345w?wN% җxáC~;rHGĿ2Wѿ g׽=hC܆=\;tuY|f۔9ӏ%^-o~S{ȃܞ1S ^׷|o׽g3~;Ǔ<>Y!1n,t|C1 tdݙ.#yiۦ/q׿..ɸȏWǝ7Ο&$Q?y ?ur˞&A#Ι<~eSÄj1L+utj,8 ,Ek0۹Ff .:p->X2x8r+)g/06gxfy-RU8G-|^y:F/)aL4H?(Mzv)C7f@ yY1R!M3NFhz,@@Rц' Gٖ9wMkQvm,L}٠=9Jm✼m:WfEΞz\3 LGqBOHܔrT'q7>Py-MW3Y .:wƿxq^=`ۦO'Rk'ޞގ;4Dފ,huk' |^3//>;`SDI>;;{(_sN"tr|9.]ppRbdr;UrJlYV.9o*{\ A|>y*N`?ӀnرS1B`7y'|s*๗Nd@suZ[mx\}t( +ܸ7i [SLI -)kן od>( d"H>˷Br }t8A?8#² ekAbpw+ 0,6@!,p1p5~gfs$y_sF#3t0g4?K  ϒ,QP!ĹQE::b: gYQ7RuW$, S\=+ zhoi8!Έ4{#R_(Z(n92ż-"]lߐAyRW$lZcSL - 1gkLԱ2~"md8FJ59+py !bj y 4Ɇd4^Ա\)#²do84Y‘tb(lS_]ǐAt<\յj¾4Th*dyS'[4xv qNROC*ő>3rP6?%8Fk"#{sieJX(r@*To6QNdŕp+ ;t^qn6gЋ~t*s!GD 9D+;xΏ^SlI 1 lm:؄ln&HM$@6&1$Л Ɔl0T7ɶ.=o}~_?8]sgΜsL9gp ]OGy54x0R$hxTOG޸m Z!1NˣW4WFVVʳeV\ߎM)ȆЋuq52xZMA |忍5 Fo;+O3HZ ֏ 4s+ "“5ZyX7rYܠǍw0gc˼a <iI2SYvȀFtA0P yր({Sr^?zMnl勦v5cMTN=M<UQFyio_nC?qlgBpGQk'Gi$MSG؉k:"9%|sJ|óh|_D֦B*/b% NGeqIGy#ȁ|afapTYƨi)cn)πYJy zT]f*j58歸F2f" O?Hzp7ЬL9m]B$I1>@ZѓU_\1Z2ˎLDyQ1̾ٴz@Ԕ|^wC6yi^K =.0 H@ЀKV,*G6`xr$:VٯaRO r^jKр1 e2}vmyHq0MOC ~iq2x%(Hg*8T)@8#/x#lCo/ Z@rJ0@V4^B̻ ϭ*7[4r!310l8GQ&y!.#!d~Fg`AyhlZv^3W}&|N 9@ىD66Ih\&Lɱap{;ə>kThe?̂dtl萍 j4y:DnLpnk(RݎIᛘgx-aQb֑萿B?ϋ(q`HM)Yoom<"Oy9 (B4ia9[v`ټn{2" g$uƊ7 GS1p(c0xLNAףBa?m>;wc ɐ<,Ga =m|ڸ#ce& 3eɺ1:hC,9OA۔F:t`h=P6/aPؙXzȢt07Ty}6'檔֚l;Ppʿ |9 i*_EۿPWuq6[,P ,H' 1K fh0D2azXHb(p@!K|jܹ`jjQ^3O*02}`f構FhS"JT HZ4qWSSg@4Dl V)?@RK’|Ʒօx%.\_i0Ċ#k&Ho81bOʎS‰{Ed;KNRR^5O`gi9Uȶ|" 9f:#W!WҮ2!./ya`@U'*i0ˬxcd0`&&]X|0eO lh6"^!DzM~ k=_!jMfF4e|뇀3#$<ߤejVlʠYxǁ| @v#sL;OuRzierǵ~㍳ý h|߽X!ޕ9qa1)$/D t/}婳?OܲOZ:寂4[Yn/#I'f9ɇ#c-vX//] iwY갯Lst@9q gկvg-[7M/xaKNN2 ]Td ~kovҩt[rD\ ;k:[ go}hݷ;3L'BgPg;RXIm{(ulmc@O9;!] ];뚮R3{^,0~p6q}_F{WN;*;{oWdEūG& zͳ/G$q=^WֽYemwLJPsNջnc=m K>ϫGbDm !:dD*n2DÂ1yJs%=[Ns{hP1(,ElTI-I戳=(o̶饡@~Xn- CfgA9 >ydBf9#Uy )1HA4_ L;, zֲ˥2Ͽ`"/]G#UU+ӹ=Ǔ\A.U%ߍnY|8RUܤa/l&x!|5_NA$bOqx[ZyL %M?r84Yjf*iRyi`wdkejz<`𴞃{]0LFJYHcbb3HzWCk rAa2?s,eI"*Gǻ#e6r`U8f5 B@d'H(~$m4(d|2y:5kJCZ4*cz8k{i&Dl״i(ty'ǻ'ʣi䟍WihU^Q jm)Ph?4Nd"'Eᓭ <ϊrů~JZKԼE֊}%VQ <$r<0Ƌ4^H!7⃣R;O###eJ+cքp:7IHdf)~!Pd;a D/֤ b>֓ xå2 >*zڀGBuo(oO|ғˮ?wv \g>)_{uחo/7]Ne媃R]6m~g=t¢yW^~ŊٔE/~IvwWz8l?3_nXOE6rx8| o̩k/A'wr)T}YQv˖-+??Γ0ָ!^]>S9>>3b0,'q +pm?2 Ӄ^~ߗ?(qdN)ߒdoixPussyn$3/tGSO{TY߲TYBیv Ts{)N҉ιuK҉?mn~EwM?]*3ܫozk{T 1W;vlrca,Eņ;p3 DH%ZfWU&+Y?y l,\=Z~#(;X%!eTf'i"1&,}[N;9] .uA:qW5Bqm?~P%5<%Z\pwE!.;śn@IyVf-耲fxpi!Mtװ[G#E7H0P\trݾ81W҂#.s~8nVxh3tݸ8U2+d&t.+hQ#S O?<iN8';,gǣ[TIouiKСSS(QXn*Y! qD: o);clی,~u058~B].e3{qaxu6 P?`@2YIA:I<%oFR.=F'hm1Zeq`Ws46Cg]j nDȔICG5 Ѽjŵ;" g]{\γfZQF 4*^b[H`4Lh"r8O(P\&r;|mr 1Z[g>F~1$@hX$4幧/wM7mחW5q6`~,g=.i evcdžb(:dɒlLv7t9g?Y5W > h,,?᧜)Yw 3<| gNܴ?rگ+_}f*sn9g ydl ˓ڽHܼfuy/G~?(AaR0~ΜjV{kN J+՛c[?P4<@}I=hy*YOC(>Ul |P@T>tҧdF)Rb2Όq]ӯ VQd9cu=ovx*ĥQO;9HO5q\iM,ћ g/iQ<^^8a=[kx6T喲a I\Ŗ.q25dE4P;y\c(\QN*f1!3:nuL]L)dB%s *ȍWNV:!BZ6?\X}eP#A ~zbfX8 =Z+ O@J9;̐#xrbJ4ʮ4ycCG ☔Kz78` rS<ȟC 6Y)QUG"1+),w'R5qɷ?Ƣ֖kXʻ8暏@32oyڱx/xo LO0^ _.rEncPPM7Ҡeqm[fpBSYd ˻PRQDBeg|'Vo҈六 D!kx8ٙ,SGiuu &pi0#M MUFqo (5JC E mX)qM?;Y~zSVv>;BǼ~|ݞW.Ĩ7q_s8pw~:+vZeb W6 ܭ}%c#(*UQt v`Af?fv(* gʱ( i|.m v&Ij c#q5:cmxS0{A86Rǀ̲C5lŽ8v>:qE֣x8F1T'QٟDsU]g2o֢ ZISuQG_~ lC兗rV|+w˪hWRtP ױ(~ _z OW9ʅ"놋}$fP$:&iOcQY+g"oU!,[Yi$خ/ n˭gM#Xy8q3,7 Pl;@W&Olrmul\`$&'scG Z~͐IDyBDz@:TܜXŀ4 'l=0uϠ6L% d' ,]:,SǓ%C Ed Р#Cip2qu r楁!@Uo]l,󺛲4$cTł_GD(C1U]˃ЍBbGMx]ظ1x 4&ڍ{aAw(+Hc O< *0B,ݣR.dV 򯫛1 c31$#n6?\Ey k`?^3\X'b@`)}8*0_\8W83Q )9[ &ngO?`w7k1.I! 2>d1˙a^ Gޤ V8z?H$e(Cl:lhP U&pDV;LYz oGwnG6'elY99 8;ab~“WT ϐ#xLF9&<)nN<:Av0u1k`12 Ƿ avn@9Ȑ g7:baLy*ҖlFGz/).nh]3ß B^e.6dzuuM IFO3s%mL%(_\ƶBe,]X1<L8?pjl(Dd8 LV7`+~qDRwnL5!QzC&LG<uŒkaKĚMuc"(ɏ AF%Sk">1aJKMq( 4D,Un;@Q i %ӪI+-G#F->h@G2_*)!x+\;xl;B@6B<3_ÓBJCfY54n7xFe Ec^?pW if9y\[:hQD>a& `z$Lg~Z^0]VzpV>%!Tl&3; eD7Cf)!J5cʑBG5hwH -Q䉧kބnCfH+'|u1L v&_˰#M.Scn)aIv|hAp Ӝ`/3Y35=.9b&]~)nB8;[WC' l[G?w+ϵU ugs3 Y_7K2a6?e7mwE_u8ݺ3cvq1slMOJ_IkΥb˘mE_Q^-})Xhj\GK2,3 SnDLEl74DbӣH.xdmv\Q('bW1$ fCy$7*}ή2'7Ue"GB p?ud: }BfɚXDAf-  CE{L|$NbaxuW'?g< %^r7p ޴qx[V`FW&(cwbS",lg!3[|;vϤ裼eL|wyeT|+{n](3qA0NBvNqLcM4u7%4ZX^3[2d1:ȚJ7I V 7ҧ+Ľx: `2J]sy"\e#H Ts4+xh5AY܈Šw/.=' 5|0< yg~= 4r&l#UT|VK'/wrSSd@n1bxi|Ge>)J2ȏ",pC"i7HI8\/ 2Zf'X|\AYNc7d',! F!1KAoՠT9M4nʩ$D G|7u@4[GX6= ~*5/sȡ k3; { kysȃ .fPOW"|1ӞRH;ekw&ͦ'M6exƍ) Ͼ goذ>Ye88E)Pqqxz}{ g=&<| cVm넅=Rz_UPhQ`TR9E%n1]Vz 1(>etK T8AEd^q'c<.Sg6MH:F8c[ޅQgI JJ9S*|gaQU$TN&.LMq.dvF7yg~Ri nJÒ1"q7?FXHJo\@P8fz$CE5" 6o O+ڕfǬhZ<#0ʼG:?䷸7K,6|OV cuX*Q .2ODxs(2@xm(V9X@@3b("*  ɗXt)7x Z?Q&M]~YzmG/rd>*Ҟ0œ5DAomH*5EGF%4nz2#>pBXJX0q3<B$+4t*.l@nY_g`Oy㚯6*c֗Vk]^5$ɣy XfSN (3mnՆ6*]cƀ,i1Φ Her_Xtqy_8\/fyt/~Q}{N a{( zop/|7ab~}__{Xн|[|pp~p.i;rU{=i28rxG(Q>r(aQ 4&PE57u(a(ewɵ,euo4&v3ʧXWC~0ݼKC8eyu$G׺}Kl9 $?YlIn@O(lyǨ1W{=әwY6̹ة OJCȿuG~wvKyAK>P ʇ)|sZZtŁgog'M~,Uɮ2q߇4?R*gOarGN`B<栁r&뒟|Gg]+P|_WVfDxn禅nj8J>tNԀ3Fܐt(ʋrf|̉?!!9p|Bh px%jfA`:$$~p&GUXYZqFx?A\fϗl\'vpdz[$ዏK/b$o2 1QE!o]=Y璡%4ByKMb5Ye=xNqIJF=51bg)nKI%F"H&~XTibn喂0 Fe`J$yBfP"!F /px0ݱF'4H ׷pQ.A50g.E8,"WCP!g+B Bj%S!M.[Ix B K ኤWzmTafYO,?/(iJjCQM]$@^FFl֨4uEA^* Zߚ:T N\ y,/RYf H,$ЬOxe6Pؘ j` G|50Zu)'bYHX\u '> R8.QpB 3L`Zኳ|D<7ID<ጫi@<xXA! SMˊ\_=kUx.VqJ4 *xNYԐ&[cANi=M%%RU%#7KWx G!:cٸGIe'OEFě)O(Y kpfŃX–Pqn`m,IISYр7QXĵKu)R>,s.?,; ^Y7ei^`yaęvxRj\>#S=r[gHk2}Jȼ$DVk.-uA'dҰDNz*bYH'4_xEL>D8@W hə?2p{'Ƴq{Opg+BzOXpAYтzf:8 Vή;x{(: ӧ;oZǟ(v;>Y#62=m(Pd©bQTb,]K8r]C58A]eKa}; ݕot)7]K%?n3O%`ŋM)fڄם,/2؅yF ^ I~ o@gv۽ AeS)<8|䝸Q~zzȿ(s|Dq i.t\ 3 Y:!UFTQ$g4 W) @,@z psZP #ZS P90DJ;)(& p)R3m(g}́08H=J7|iEb?A>LjТ[nTjFV![.jæʑFgT"yJxdy³{6ȇ(Cj}P#exfmG?|_혭5hDi_|bra#?G1CV.^>nݺ,^3};馛@:uWw_"LW4fW}SDkI'ɾӮ0:;xwwUzg;Za^xa9ro7 !(ËQ2tݯ]Xi*l'l Flf8Vña\qHq1C}qig1Oѯɝώm޼0]~A@BEkBC8W=G1ĵ8bT%/J]; Ҩ3vc8sr(fzhX6=,;nz8HmOPN;8#YϷ.sSY 0R.cǻq 82E aI3?^wn,0Ǐ$v;,]Qo&p@kYET{;Dx9^>|v_W9G;vU0O[ƐCn_E݂zy`vYXw@#KrpOOY2gPwc=9cK}WYz1\(4pu 㓳,|"0$%@'F/I, ĤU-o&uebYԢ@(a 'ہr:F\/?oURJD%2BGCe]n5&I%6T餕Z^f>O6: QHW- -ߥƍ,y>ii%ş#t8bk|*qI^7e*kZFiي )|AJ:K`iM Q|O]\FxW^[~ <+G!.U^Wzc)*^Q7`rΘZkQyijie5񫗇H l^U+Ka'\.ex2^e6T+Zib{eE6u- 7ͳӶ@ׅx{F)Q!~OdHgURY!w ][Ґ)s};eLڵks|7\V^"m䂫\|[V~^zif8l_~Gký(Xu-}{ⓞTOv#,?i-}YוAe<嬲51}\yߝ͛7%tGy$/5yO~IO~r9go^Y ϞѹqB=|tD93ܗ0u'˭l7!`%ǙdgBW6zv;3˻$}"2q߷EI%_*>wwwWaƴ/z\8~n+gHGI9l)C˜Tf8qgf |'gL ]y(-O1B7q*¼ʁr4.ڦ^˷Hēo;0ރr.€Gn6EG7IZ01TNxEr߇ՋROI9Ne!'#aCc5}L?Iҵʛ*n: =-d{ .qc@3.dSG8.闇z _FסYUߠ͕♱-=5ۋ, Q"םeâ4`9PYtDijKC*Dϙx3LAF *ϻ V\3}*XA\ H!d~G>3 TE^mC$v K(S( : 3f@$oؠ!K(RHA]BEBV>? pj-]`l|%PF,'xB)804I̳Qu 4;%_1;r\V6Uv@:,-uZ}dc\MKֶ:YmLZp,'G+'4K`rx_qHhjCNXVGqR!\<.OZqx`ĈB/p7{T{{/drG/ g2..]ZoDQ*5kʉxr< ݋W[o+/yK˺u2h+^YOmmW\>я~ʹ :>oNp(ǘ-K?z}y/;|Hf…ķRr^阛}sr. c)wȇ?\w}Á?sa ]ßgF>4yY?4Z<5^?ϟҘC7Yz7Y6x+̹bY7 _bʋ_?ǟ"= &]%GyD3~."]/x/(̽: E]T=hʻeqў?/dk2__d7nP3/;PxoB#墛˥ o.m+Q*;Ϋ߫{k]3>R:Ba<,c =>Y]B{# 1}Iv 2^@/vx8bႸQ06am*qa7rO XL^:Gәnnu"1^7׃wPXG~ǃA:VQuޙ_+0yIZD؄ªDUTY|`1Ly݈xgƕ G]63Ύ]'TUA&4I𽎩+*c6{CeE"b=}A%(gGwqlTa(aBZF"\C H6Sx8[Ɠ dhGhе*|Rvٲ}ZR@ݭޱ_J IfgPgP*cYv+C `3G ?ea\{Zݐ9rTeF!%/(-Lx8׵Sx3̰j扞a9goqx1 . wC$(ra9rG P7cByã{p'o('iyB!+5rB4(>#pQn\+83hp ֛[guc >1Z<nd]^W|aV~_yJ󻊩e|_p//}{y睗 _җ}Q/k9^QQi bc/aE>f|޾ 0>۵#ìs2Z‘]w]7,XlYyk_[[7OF^{`() /xzғiU#B|XrUyCZ>ϗ>9~/kO|:M/}^*|+я}x)wc^{s@xI^;я|oh@P攇? wn?; WS{S>{d_V9q=7!ubf+OTSٛtto@iw"خ>QTT`3~n}Tv= lnFkaQZ0A7q 3j*./qAlIUIsxWcj'f#I/w*ѽ(:(/P Scˌm#ie4qMhCHxs6^{ezݶdc). 8x-裫xuQNډf)t=@}Y|ۇNxw/{W^HUi{Չ6-7J}9z~>闛AK6bc/80}piAgUho}ܾ M=|g|ᐂn:yHy.`YJApft8*%M*㤉K<j`3e7p;+ ;+ q, :!y[Y%8ZroPPp3J_{C x0/Y[l*c({bnq\ `gurXe}>{=1u CT0>-scr#^^nrw5`6M,y|֫S~Su2&41q\Ҙ&{G .|e٢VRj7=3Ccв 8i,XnLe*2D&c4Su@b|*ehrC:2R OqcUʅ 2Cda\shW9Q OڏbҞʴB[dPZ v`eʬ puR |CtFV/r]JDU)%)RUL;+ChbxO\"֥%-T TE"J#ުc&]SZ+@HzxC+ #Efu7WՐfF%W@"{9n|x3Ƿ1wx̟[ڰFA.M4WʢDSn0K qe^Paݵ $#f35_e%g।Ѹˣ &O8 wih&^>XV^J+e<[HNi>[EA(t-2 [Gjx3WegQ&ZtQ424iϓAhFfQ 8E |P.lH};>Wm_jWF], @wc݌=Q:-F."ޑ$ʕ+0=_n+޺2}X-wwOYgU~>a¯헒~Xq{ezY^7p#wR>r͵T֬Y](pW}'y|kY {;K';tf׫S>.r+ݽklQ=a(o9cYbMׯbZg3!DE3?KNE`֥ T(4 \3ߏ>爳&n0ĮT̒<>V8'Jl27x>JyA˨pIY_5cR-7߁3.u}s }n1ɘd^ٌc@+Y1u ;.(ZzTѬhpYgV5>-g($pcTxK0 CEM#l07 zfG&o(3S4٬ͽT?RР`Ypl8pqGL*JN$U.x]ncYD3Y<_iC~rK3Ƞ'+G7hRCriE;b0_Spl%gnz S!(}1S睗 ^ի//_ڥYKHϤ{yժUx9,x5ν. #p>k8e?=+GJchZN776um14yl/5@m5e;&FB$:}Yٷ^:V}u6ANjХ`ı)ʝpQ #vK.2Ծ50~Qg!?iIc~جB^mcIjN8O:53垶j,mUײS -Ī|a,Eڏ?m]1Ƹ |M _qH:K#ܜ^3f4>Ai7hP+ݾSE7%TthqbTݼ7\nFx,[XXk%6/riAH_ձVJva @5ZǧQEŒz&,S2\mj;O3[Ol:G[rwQ[7g Γ#6Ӎ0t\xFO*'xby;߱;iпu˖SSMpk(|lXr wXf`:\x<'wٟ ψilv10)?LNx3w]3k'[tw[:w '{?>ʯ/|g>w9E$Mדol}_`)HW*~+ꠃʆ;ٍ\&Kyߗ/~{{~@rrdrOuYlg.q.=BNe߂C3xv o79~:=|s|3bI)ZN;eʃUwE!׶ɴnm5Qq9z@ZOj#.]cfY Hf8zoVթ>=Nvݑbϗ-Р& @pgjF0=JQkۼ4 Sv!%P⹻F^޽j+inp% ԰51%K1Ȩ碧LcDld4l.t3;RmㄱɳX4tȓ<|~$Q>\}).eTI Uy7qH;NWrK|M[3ȤʙVB/ 13 ޑQ*m0zjFz)`u5*l: 7:=薝 ̴`V28>&GJG-!`?XP,gd>: a"gBk; "v3qAKU^cAd\}˟:| nމW0L}qCLu_KQ%Vgegye%4z Х=ԍ,N~޼:;^s.<|L@/1;1A¯9 _tU 4CP3b 7PKEI]HF`[` 4`VLԶ#8.gaHiMW96<%N̩j/|ˀY`Q&= RnAj&ɚtyW^L Oy0$}1^^3zLWvE`'>|Y '$ IDAT&y& eDKtȈtwYiҋgޢbW+r eYZqH .HáS^҄SPQgeX7:Q%2oFltE:cDpj 9xǁAzgW"&Yl[iOtD}xYΝw}]v?לyVٲݲd1]{I/fì?ʕ+3ʽbŊL{ng`׾VV:! ƛzM7g lظ)eF(K,)wݼ:[Vz'痣vhy£ 7P.184汋ߓ]zzw{t0{m^'>Ja˿.7|sfmLw/+ץg6+ʹ!߾|u9锗w^>і_y9t8E36:v6^sT/}O:riw#i]4- ,: 4t&dW~vҟ&k .W{`TC;Qb43nݤ>Yhn3kxy54" s/%Lfy,bd' hWHݑFʻO_;jLcv7oKnƤ24uc_|nFG0X{~F![G&OP.R55:3'LY`]PN:!t>w@S/X Xg>Agtt{9sF- T#7rr1~tqFH]sﰧni2L/e%SwnF!)FAO~|{Tl0Ss8ut4#3;>zK`q" BëM*gt"sqXϭ`7jsJA꛳k34̬wm*eA n6LG ?@5:ehGAkM[s2;01&9?wmʣFWFu1iliXsM)_Tótg7hFU4Rc3z1Dl1)"o *SUK]E,\giFc!|Qqh,  g] vAFxS .lfW! @l䅿ar)Lh*Lb&I@l&^ͯw{ͪNKI.+82'"- 4Қ2hIJDE<Ye&Ip&8BL$~qvNGPt"2“R$a\y!N$Y>Fhy(/* m2CM eRrk}@`:ehZAKy~8:h)6U_JΏ?F'WC~ǏrA| &%,>O[ߴ`_~$/f$IlrG mͣȻ^vgvmGyn,aذy0}P}K6Zr`\'V޲i,<`1B͕о< wZ{>0`E1+[։׿,7ff\ W}?_߄RK #9ڜ)Pm`Ԩs5͚mf.6vڮ}2,D_HNp] x~l~u]nnx榅nWٝWN6Cl.6d7_mv?yOw xxN_x##I[Y <߬DL:(Vf3(z9Jk?QiUOwqҥ: CC/#P}g_( +3;L7!#nx˝#x:nXCQA]?˧CT,G I~gB8E>iYHL}Ap6YfDK"5 ۘCǓ$G *4IoAN,Frdi7FRMe+2ns1O F=WF0=i3;>" 02p?q( +y3 MKYNpτiK7ˢ:F|6苫ܓBDUUz0\C  P";GiprPCK->gԉs1p,y-e/kg 2\|U:JKW!]8ċ5 =aahXňsH*:rWk!ز$V1Cz$/Fq) AchF_q{l%!'1vYaֈ,'9zse/N[X6cQ6lODEB>S[;TY2Ri[;垏-EƒʶwSv6 :@)]HAaޏdz,V5}6+|_}˗c,KGt2Dt5u:L^kx[7끮{ohQ)wUoq7u#k+#}aīw-tYQ:aM0ލ3uv2 {aaN c}tm' ^/Xo(M<"koOOYpK+ v;N?ͤב{GA\G6Zi73f.il< kh2q-qt5j;ch;G3* x3e Υc@|qB!,قn=8F lMXg,/7Ƴ2" @,hhIQbϧ TLQ0SF#5Lw+x?YzG88ILg.!4ֵ;ZGy&;Gv'eT ܞ@ w#;.Yx1 KC;[Csl8R څ+ P>q\OG<~_sĝ44|8S FEvQ)/뼟_";%u}]2߮o+WQ9o:Gkcg+ F.v \:Q<#XX{-z@ 1`lAKmyGə Yr0I':A9nLN]De  y5xyyèbdD~i΀8tM\W;&+ xQ/ 2\ {Ay-Р<\( O%P0NZ"P![vrV-6FHa~NbWKZ g&h>LRFH|hkغU{db'ϑs^AT "PȈ `%jT^d+v#\b# >G k,ttc2zgs@8@۫Wp\w?4wd1BU1@P7:C#ȁ]0 #ml)a"&/r4ZŠ6%CtHpP1 {.iDAØk54 WFyV-< e$ơ(n(]GSQMppL/ylwj.^c"vTal& laƵ6.hiޖFyot,KyaYTG\CX}NdeP`Qo$z : S:j1QTJ.+b`dG"_d% aH#t|hB,Qh4Lu 1SZֵn[5,~2C¬;6ʈ2CAe0QD1/S@YA[^^#5vRRj: 留Ȱ:p57^W+va"?4Wi$F GbfLP(z򙿏i8֜yۮW$ɼwn%r!2ͨ9:vw95zCsr8Y#q٘Hj=bDDA;bZ^[ ]cΠPi`e 9rv 9l:LutMyfV^"BxЩ@VFz\,)myV˙ΎظBű.ga^oft_g}>+}% r1e:/EgPec|'zR}dadQ,ߖ8B5Y Z;š 3n9 v TGt'dm/N1'8#>HfyM6- A|wMi|= WS,wuI(gg[:MzqL jᩘ=ʔ KmQ]PRb-&c (|.ӶN#9#sy .|jm]wyXwj҉gtl gT&W :OFZ*q3*Oͨ%JG#!U@4KtkwG>؜ꎶNc/ "WڥpA64TWnRhFUZ3\Fl]a"R&4PTc(NCg/n:LLC%)gֳ/űU7^q7pyIgM:Ig)S"-9lajy._⫓Og-:=1LtE4RmAK˺k`7!aQiK]u&N^hdƸ_|DF\i$\=JY6ѯߡ|dA=8R_t^'.꒼ZP;^W^y%k${ҳA #8'<~io4R ?8t覧,͵NMN_)Г)pS~3- gdGw4Y pwTU%EРu#$ D─菎113ATљQJu8AH|x:gH'4h2 k_= \sS3 -좻/@_w35pXoXMge88?A֨GȨBK hƠOmH:M!q(Q. HeDڵ0M~UJIAM}@c8a8 cgX`{R+dN5hV.w:WyX rxlp z࡜k S |4J\AW -LRLrh6WLҦvkn;!G`mx8D\fΗ3L7+ʔUf,rA$p# +#ezY#' 0S˨F!hʰ̌0),O 5Щk)oieH- Z~Tch5lYNdA-Xz@ٺ 9Qq|ĥih,[s7Q|<18:|Y6xj}T=Tl򑏔K/FɎmlY J`VY xĘMӚ{05nhfx; eE^~M: OBY`WN{B7{ ؀*Ri{<(A mt,cV%ܽjh"x hJ>c&dm3m4][^?f)hN5]oqk)=ᷣ܁ţM.0]6:m.tWY EQ<xem9|TL,g?zaR IDATr#dtApKI9bc \9I˾G{px,\3ᄥ:qʤl0]7z? &k[#*٢Nyy c<& <Sd&N{AyG&ݟrd!@[\Ћl+fWCh\YxE$J?zm߁3eՃӤ%DrYGS:2t6vH#DQGe_Rݺ{y3z&J2Gvw)Jc2&q~1X I?MD\#_m?ڍZs"qh9aboZ -V0=w9Zތ|& \(P482P0ƽFK%<5TQ-T Hq4C «QC*ƭpШbz5tg$?%nj@&}B=GzFZeewhW ƿ]"FYvSܾK[G2XװLuZC G3t1րV%IFÏ_Q/ J% QgӆrqƵ4R(=R*hX1Ϛ9z3G4t%o9)F?ƒgGɭr`Ss!8 pkR:k2_g+ہ?YICNw#N FW%wN?rq%_-1l N >4ۜ:1U87{#0?ڣ\m9(lHȆF>8X_\o =Wx ߇.6_rT?<O/ׯϦa֭C6Rub o>1Uwտ?KҬf%0+Y t[k1etRT͚i>LٗͰ;C-9K>.y3k#wڕ1DIWp7ys1Ov`_.\OLj74ݮx .{ +aw >1F/=>˓pW[K oGǼβ?K$Y T!e#ON Y^)\'1WޕF̆gdɢet[ܤ6bPnYǂ8(t6/&S-&q6Fٷ`prpfףU雇Ng2Rt8}\/"iuo8E@܉G9e,I҃;687)/l2r, \vWI"tƪE {ʆuuyd]N$l(c •&^92jXN"2KN8"AK9BUu8ΊQTaspcAg+W:xt@Gz4Nt.~ O:+tajYա`G& g _L2*uK;ƐL69,›82a:h҄!N%, v*01RU)m1֨W sn''h?64H>s,G5~] J_ ΚĩA:¶P 픑#w|u3^yqa^2Jzsg >m<1hdmSS}<@k37tζ0g9(Ceg˝ `UّNy7^>:YC8&We:\7zfb"  .fT(!҃~eeYb-_Oʞ0+eD\5SȦ1hx\GM@+8-ߖȢdi8Iu"i+wҘֆB oQ CÔttuTy7:RiiC*I@8~O-O{[pak_+?+(ww}?(W_}uя~T~򓟔k\{E(wyg|.YV'gn+ -)T9\5/+o{%iws:-6m CC42>D/;@8E?t?t=^vr?Sw$ev?bg_/=rдJkHECVQ{.~50W4vE̗i, v^g Yz1<\߭n1FNFwJ_VÚwz= ۳$X1ٴƉ2}h=P480rhA ].^h,td|6Mv{tzϿ Iq>i4ҿ3!irt$ҿ QZqn?eojjX׵[Aa#?W?q3S#&MXp@F]>Ŭu9-<Vv?ςeIٻ0Ni荳Ytda|8{0ͤRÙ 8#&I ZۓNQ5L_ P"]+D GwN2 4^CW=6=@0̥ABp5d<8y>#1SBMCC%Q6R_l n]I =KUc#PgH7k9~e ߟ(3ttS+1]qn:m =,e|ke'+yStoto뗖O~җ%q>+߈l50n5\?p] Gmq$54zGZ{k Ȉ-m\C3!0544,1:q8[j+ohstb{5ǵ=}mK.:협haӭq.raqXy~*2/.1{~@oS e/0 3?pcGH4488,Eh߉6*>FOݤmvwsZ^qpY $o}m Lvjx)Nei^1u$.P`_?ͦ$@琡Fn'Sud]Fzʊ~0;y?IC~EK rXx] O]Hc7塧RE8SQb$l368Z:P LfCBGsA>6X+mlF F^ťCFQQ.y?Z~CΌ  X@NWa4܇BR)G#AeG@jUkN9'( 4>o~o^ ^BM{ީ|TFc{d- `Kw#-2 7I[u]IO~:z![+KmqO^{8`W~{o54\ut?N@W!x?^=}}}L/ /xғT~wN,'E/xA9a ??ҭZ<'d <W%_JyqO-K.+GXY?#񉔳q)?)ޯ .=ӛS;^2կyMҘڟ<-M'AlCI;A>R4rP}i8mZcѲp;8!f PΡ^|s 0h@Dp/}l!537-irDF"FƤ20'G 54d3񗼞leO2 HC CysFƾY5 0_(h(=Q؍ Gl۶":u;]g@ |cG}^x5qLtGG$J_'dv?/~TfuGsY6ְ#ZB2 D:24{ؤo):S Je@_#_hЎ PyNTHw$aH޴`28GP;aBO`+L#webY`rq86cBSA2 &xׅ_e=C2.cM_a*"vbOéݠe@.~/dC74K*:@XkPZZGI8;hܺ c.8BWQ)[} |^KCt)=p kg$ W#:?t#o N 8)Q&dXzM#$დJxC"0t1M҈#UkkZ:0@SI7G @`=#(ǃŪ+b"U`RD|@H9Y"y#ǃmWF|kiX_7Lx7}HlU^e"),3/gTzxՉ^H{M6t)hCw1+;SV!/b'G`Ы.~pySvsuRP>_|ȩ5%FI/f_/N +_Uwﺳ}vAfiLt}|-/?4dZ^Sso}|/ʏ[{svzY墋.i^qN$$Oɳxڙ6_?(ײdn(_6j>SsZ+_sW*M7T|Jy^N{ʧ?3~ NuM ]G/wH:Sͤ3/3靺rQ)bgnS*= _p⋾Hk/ѻ)f; aL˻]  N@_C_~h0NHKjc̑w 'թ`p.dv]!^6i_m.\֗&y#A[.ɓl8v&σ{H?il505 l> o2ƨFt爓pݡ4I)҂؅њ$_Ͻ>A"3:YZZq/:QFw3+֮>w5ĝ=0t6V7etvɫl{Y-(PCt15A>PeƂ曆1NTZ0jyABX#qtptyNwp;Y{{ŐR@1Ciu#hpo90s Hm_ؼ𬾊3N <ЁLr *ѝM׹1ʋB( cRk=}ع%XePK:E.qOL }/xeƁmruF)TP; OQ@yޠU!pGp[YNd&{S'tT9C3]-K+=:iX1F 5ES,2/#hEOM #N.l{QNN#Ԙ!NIx`EhVghb@6|M℥|k+Je-xxBdC:ZzKcx+ツ̢ @!T Q"=U61*ψks C]J #Kˑ4E>.IdW5Bb"xt0U '`B_$RirțJU9/D)?y{Y@CR,b-sҐ h>VUT7p+WL-W'5DDx/ouG@ހo?Pu]ozSp<(g _BW7?ww\<4@ӯ蚞gG/^\sʓ_)K]N9dH6}咯 "ξG&/)o.яGկ;.38TSXQ/ng`uk7a`a=IKA|mqװ˚ ty;)KwG:KSc2v(kx{lLB71/ǍgýXI\XJ.0\M^Y%00Ƒ"i$u Yp)#us?MߋėDz_x jjЛICDf76R18EetFQYKA9яžAA`+܀C/NwTg4(,*t=k i,Kodl`ٴ4 Qʷq*\ʪd noQ2E|8HA{*J^@鄨u^: z:kotDe2ۓh2la;aom (h6 >y1e82k'$Y!M ]uDZN*)uh>$'@֙.EwGoVԲI㻗V di~TK g;5!2 [Ha38D @d':|5܍Aj2S1?[*kN6t=#h m o3O08II.FSVZғ5YT,ɃBYIJ}fB+#K[4kS<쑋$u*i5ȡ#iEyO-0 ^0~T/B3?6Ο geh8I`%.2*>_##C#fxAͥL:xWYV6/2 =aiu2˫YšnrJ97?tŸ`R |H6"?iɓ{6ped_EZ D<ǹc *y^AsWcL1qKљ97/+CNGOqEb->N%Z1̩/B뭴R~~70Ы@R@PR:%zu]W-]N|`:zoӯ뷪h>O;ӳx/ FG^Zזc=&F0g[fmYbhW\wy^W&w5g&5wuwfs4V@ýWGOp䣎̈<怟Fka?2M:l3#i`T#LA{N.S5a{3TFuo n]>vf;m4m]X1ye4e`mTֹA ʊ5 x4,s: YQy/LhG)Nk_ld8]6}r簯!?mEYe;̅{ϝH =~mP7O8`G)30Hϣ7oA'eL: q;_B=P/4;q,Lʧ 0r ?! IL{GX 2" }?3** (F?اs@K#0Y1`h@MF5rLeb#: 2j>~o `Hl aLU~͖pټ-eF.Y1۩t^.C kZ:eJbdaBTgpr.. 7: ܥ^?뜳tpE4 >cu:x>N$^ fڸF\Pt5t"MK-QԖމYG(vν_ n޵5(A ACW#  ;5GI ')%!RjUS#pECtIR233P ]y,Z|YnC /vyͻ/s8lj 79n=]Le+<ҏ}r/!w^VI;dn^n6CYgܨ|Igy{4N'fʷ^fһ}W7{wo{_o_;g~ hDއk,a.44edh_)Swm ՘P;bYoYyI.ۼxv?-(]P5!fBnb ܡWjcE+L[oh?;`lg!: }poc0ǘuYn1B+a N ONL26ֻѥCxX̔ls0Ǜ[BޒY4 Bkf hw\ }[<.5󻡟P++ åj Sc q K b֌ko 8/efzA f ( Zs MVh4g3/ ~ҧ.!ȇ7ig3=Ul1r!}7ip u`Ah 6XRHTB[|pFgT T]@&ⷭF'DfK9}w~ځ?VhRzuxYh80W'Y:f|?Q 0e+֝,Px1L`x,$U?GZoDݍ-u( ;{ch$%u-TM$d4nDXA1@q ($@Op;/PܐMJl#xwvTP o[Gy, -l :_+JN\Kx,j ,0hS.|e#ůkhf!JO m.z)#nC(&"7&q:(a- 7Eʆ0aj#WœJFV~4Emcpʌpm-GViE#liܪ1\蝰ɓ !q)dJiXC[#~-뇦~pԭ|RQ鳃}49j^Uˇ[E"i~Y䝼ř A;1ƳdB*ƊgYfv=b^K92 (:9Tt Mi\VܤmKJe#-ma~Ae~[Ω3.UCc?Alg!afHH[KY~T'?x[Бjr|{J780) X&]n`;<{9#ᗿI 믿r8!~~#O-݅u'?Y;>>[\vK{s[83ɻMYzk_4zLw݌m,װ=Ѧ {N'fn3]o{_oO't?a{6C(7qn_6߮Z׀J4Ly7ceΊJaXnH]>\~ 7} \a_kE6YlG|AhrzzFQ ܕkWe& nϻ_9\YVVyS{| &`rʿ=a&L?>\&uKgT^ ae DS/\ՋaL\ *L[ˀK^)%(LGGdS:1á^(7$wPG&g:QfiG^fkCkfq ym@FiSxKp؏ O Rg5Ր1/m LdT_ӪIrt8NN g.s%HP30#2 yccᚬ*n`+#"ȴ®ܨ_T`u/QdBW?SmOoS«agŲ`[E(\ _hUX-#ZI+u5YSTl xj%H͕c.X9@¢WNG)54Ik62wznebzwK:-\Uyn)YGM\eE|8QƮqhV>TQ14+nr|aBV+5U" *#:ntJ=^[gmzKw$=u3SVtN|=<[)*cK7I'oϪU'=yÈwx&zs ;gno./X<Ǘg?9?}L>5g6C>?;ßuYl D_;ꨣʅ\P>s[@8fi~/K_T> p@o|cF?-{;{N8!Ʊ?xKL ۛxc&yOO7r.,Dw?S2 xz9=]rJ);8(wmt3I'fʷ^fһt;rL7/$^7܁ٗ]$gDpͶP;,a?FkIlO5`]? } ӵMuv^t'Ud#:F8<}2Z_;g}qKv&H Sgiރpipʹ)iftt-^MxE &{ 􂈤[|WWf#"wb:~ʥr".VF1'oْ;F#ɟ48rt \͇g鷒Ke~[)4 뒋8 !f4eхI:#l.iax!OO3BȖr}dìwĻ~'\u 'U:y1gSDSʁg)v'r?:U6F4(a Eb:ݵYw(Vóɧ,sF2>+pie˃Bj¡+2 Gyȗ kyf% l IdF6 ;zn!c1m}cPvYu>t秝Ⱥt8,v2=Cɽk)};7}騗$mScTJF781HoJcqwJɝ :v$20\\Nh+%)ߓpug ,^Q~q ˷yizkO#K [` bٯdodMLr!fٯ"?c=O/A:1ҜX]!03IL|Sҿ *'SFqEWFhE9g_U:BZ*d>8_zg9H=,C>aGtu j Dҽ2:huD½0r p:5(+#:)\6*ljF⣓c탇Vg%m=‹$QƑ18]5Y:t?GP$@<=ny/8 rQ,>rCm: Hot,Rutя& mȈsG-62kЧus2/S0 BA0T8 0"4V CVdK<\$ohM"e3U܂$ύ5*䇸lS楜KhJ$NqI,(W@i* ~H 3@b@Fm _efb-\4qgޒ92Dqty`edTzHL-[#jrn򜏭~#@1s;[v1t 5led+ٜzMu&#֙Oz ^Z8Ȓrnp5Fe=LYM1hOZڎWxD:XKBxkc6߮ҟёi1H)#@8 zh =imPC{<*s rހRNB Q^ yc)N6 wٙ |t?v7?_D2bֈeD1hPgsB!CvfMx-w&eU}w޻oePDH -bAPȠQ*h  2Š2@F@S!6jbDz|;/ t ^趿s}kgpɠ#D' Ppuw' L;V]J ",ԥp@:egy rֶ%%WW&mw6ˆ`xCރ/B֧8>}~ J'OoN;@MO!5?֘?O_i6X 79_ !*3m*vheWYqmy ZĽUmali~έ.~&o:smlg&nyԷQ$ $ĊTQ>%)r YHˤ]J]gJAR6(C@h3J& gs;,h8+"4|'SF:tVam AuS҅\ANي9'FlH*島Er`&~eY>Qqi>> JƨbesV@heM~۷A#kWJ U*@B|ڮaF`0kh1@K $:zM'U!kX G 73{+KpSt@25[rf;5?|lx 9}Me$b>կzU˿h r.wm>2xc^|)> ;_k45{tt5r,GG3]3짱5`ۭAW &eQx:G S[ܶ].8q"1`mCnX6f8Cͪ$rcmuHa)GgToׯڧjah7&_Cz34εGjF6,#FH'Tw_׬i(@=SZʑ_!0Uo~?S-f@<3 $0-W8K/eoޔ}"'-Mkz}Av6@p) 5@e`2fWthA~\ 0Oo9ICg(9amC>z5:v<wpe$]C&M֫-s⣐9I"EB)cv2Bb/+/#_`-^ p"ݤe̸G\XRXO0_wuIkWLujgnh;ˌ itg`lu . p5冃*-lE88"6_>NG1ñ'muK]W*~N'vtNMwwT48_Acւaaé͚Ɔy:Yי&F(G7saKAtz>s+ L\r3h)FvIo'qM --zWa0dhIVe@BۆsQ^D3Asa+o׮ >]aRpwMqíI4!bev]Y=Ҕ߀:٨AhRΡNTW8n0!*BYэh߮F ڮa(QTIPo]]! is9GŹ'0nsԌz@:_;1ؼ8̙,0ưWhz\Zn1PRVH錳3U嵅D ;#:/;:=҉X"jv$p操̢VY8&Qc8M=mxud45LzokIG.Mx3|3gzܹT'p%@jFyu\ ސ26&h(tj-NSډ2S< QꬫSK1G%)UNKfZ^(.g&s|oXw/))_)k24DWxPo^Ós*쓮A!i><1DY:x.PQ,GƲg2"0̓e"qPƍZn_93>/l6@ *x2R{^9Os$ϡ.m'NѸ$4.A8[ 51#7-Y6UdGyNȧ_ߘMrlǽs9<r`ȁ!p #z48tWi!NoL NH5nȦsjڗAp")搃-[:Z~,i @/FtH \M&:{1Smr0\in_㼣?j6Ѓ w:ýBDېÇ35z3x썛i>X4,yFѴT&Bt #p.n'V Ήdq8P*:B` kFd0^UQTg")hj.5+qTrTV6Dͺ5pL=}0K9 HNEE(GN>Х}tDI#i]hMųzj%zwyb {Oɹ e9y #KuG(=u QCnS{EX~~ Cf>A!鼋yO>yqupiQq1%|!a6;ˑgSIJހG`Ly !h

*Nm4={-?G558N܌WZӑDsuj2˵X~kSY ^`62Y9=m/x ?yX˛AG9ҖVV)A~/|-/@`a[x|; ``i""sZ'׽ C%w6C@6N l@Gpwp|D^^ܴ֩b`* B4)_=9Ml:ɽ(kin~q a[Y`t|ppc_rft:< l'n0h [dwߴg"T>on@`;П=!ȯK-/PIځ.u)LsO6z$,UzE :,֖I{}Gi'v(ҝ^ϠX.u$|aV(\`i'e oǑ$|&y˃j` +#Hpھiټ(<==2 pOA%ipM :XrɊ04dVws cj$'V/D ZBu§ ǃe3ڢᯃ@:OpT&nUF3gm0&\b}@!ަ2F>`[ZegGS)`_@F2io/+8KSF}H+ ^Q g":Qdr'#]ȃRh|z T>9Pl<)MWǫ PKاT י[ː>D1W:@ay}G}( N0E:;;"Jx-.pUNj_vG",tF#䑤\Kfҏ3JEL˃ffm0 &y Cf` g"^h*tW+(w?|,(e'<שIpDNe?{כ>.3?k_|= {';l'a \z)G\SM::ֹO%r"0 EL1c=$( | P^^ӋC+7"pF9vS``Ǩ!,NewEf \ZOW7e ru:R Ӫ=6Z([ Gȹ~F5rNP@hzO92i!l1Y7FPNwTX|}_iҔ']8:ν!iB$gd`c[,Xsleqn&[2HIMYpr8KWGfh(#٦΅ VKrWy%fyNRܜnٟ 8h4c{dlН MھZG#+wɀY4 M&te7Oп՗#_ `Uxcd$FJ<0A%1bƓ4+{7(JlTɚ בn_%^Ά~%%Jqwp2堫Tph \qïW\2(Sd/X.e=:A6qR9oT)ܜ! TGN '3t IDAT8čUPe-$e&dg| ._viqxH! fOɠny&Qn"*2L*2^~b//s73C*)>(9Ӹo湁P^bY,>(ᑴle`8C 90C8@t8e5ŒIt#vrM{`@,h'j'inNjsƗ#nʫpl@GYǷZ︚nQk.J8711=iLg(yq4<_2cfvYݜii`A@_xɨk#cg ,(Sñ/thuqR>ufJuǨh9O2ZC80)Ea<W+@UV~)f J'~XA1_1Hi&9̌RSˌ!<#k"Ƨ/(RSȱ+~zn0OQrع@Avԓ ,>R#^L˃I>qmT)=NۼzH+ǁL}.QG`]/:r]X?kܾ,y:zǟeO0%i㪏mZϻ 7Ty#t~fm RXqĠ5Zw$=Si>\}ܖ }xKYJ$ǵOw bf8l`$+}P3(`89Y[n]l` SmAyWʼnkm\R , esoTO.mfy82K"<-MYJݓs{El v~|6nD&|@'BtY/WɉvR@p#8r ,BDc^&-:"-9 F! ^86Zqk# 1@GFG,+-m%rk`?kwRHaK\7ybE4P3Q$io<2kȃH;v]:d~?2;yG+Yor`ȁ!ks)g堏s._G9#k2h&@oFeGj&(u$q2.88&n&kF:a"*B$EJ>ݜYG3#:ZK:>ypbMIdpLK|BG6',]G0oQ7  g~2g%veP 1])/z\6S5c5L,?.tFK ץy"3GF&HyKՔ|q&8V*󐡥U)͚[scļzkhǓDK C eqց[KW%.sPqrqa`Yquf$2P£8_1z9Y@)l~&y+t V!YMmx+8,N%сY,;p?r?cs:9@ \#>{lO[ue|v0R&- rȣz`ŤzvNDD:Y PӚ)&k[[<=3N}ΦcP92ݎ 1 d~#T:"|,fӌc)˅+济gGРpsXu Y7yJe Ҽ>+т7i*k~[#Ld|gWzOD\3A< \4 ݵ*Z-zxqK0ŠJHlR_D>#pŹ҃F>` h<|<@ly:_t,<ԉ)uʜ4 iQ>(1UG̞>X<D`IhpT67!-/KyiR8 B}Wg+q07,̀7f+ה% J}y[9%'enBǫv%T xd$_ 헴꿞cO K90Cܩ9;k;J'P@۷h9xݝcǵMaL_kKX:޷uuvcX`'}fZ'Sxc;*II\>tlPO_;'qNoc]Wz4irjܸL*8Y$,+^qukvFBgX^LXE5Q@@fd<-Dx$ h pt3 l.7\Ccufe2kرX@e/>}JRgo&:eM*߄ KΖjd\n;N93#D|~ykJ9)Cw ?5r2˵N~;ēU|8,P:ҷ % vth < @>֟fzj?e@}ZᙜP/-.?C״൤Й"`!)0'kMf$/ Y-f[c2K ?Rc7f`.wM䇟e2z BR 2CFs_Wy ODt@:$NOP-J[4erwS=dZr@KZ!QM047 |f겱GxXwp33LdO8yBʓ.oD'SmMV谩DeV9Ҟu'o9j#0^HVmZ/,M:4g:1ZqniX ȂԔswwԈ/)vw`KX)NFøٞSıLSqa=.uZ<'a~; %Y,BHB^vt'OyE&K 6j:t˲7rʝ`WyO8c8%q6gvsh _Zf&RIQiw;ު!|ᨇdHݧy0 0(ì\k2X\ê3ɛ#e c5S:#SǾ/l'O j}-]?RM ۬0#3rW^0>ೃ;dž:!r`ȁ!n쳶uRYy=\9\oӧwzUL̓,)| G~g#ݱu~pmnBgU;8r[HG{"0Dn!3<#l}vV}s4aTtdi.iL^+35>^mmh9Y[f牃l3[2yC-e'!3p8WG%3ed,ڭEgL ㈽Aۃ0E\w8 23pC = M18k]a};8DZtuBAPc|n42FtFspÛ5MaHi:ShGs )rDE5+菁#S?,[Zw8Fq \Z. H;P9s (Ef枿,8)}ʣH:RExX-PtFC` ꓆ԙF!mc#Y0`<|Mwu{AlG::WRD˛8R'W|MG PV^!13CL%;;(:Swx yө@l5' 1 | "2\<&I g9隣Ko j&pbD^#_&Ƙ;K:ܤTLA^rmeo\'M8&gPhݦ?rׯ=$2 Ʃ1@(}PXI/1D÷,ȎOgtqāL0!}m"b` vZ3 R8M*D;K@e?W!%!hl9pzdQNe; ո3ݙ O>(/9S(n7 i>(^q?iu8A|3K##'!?  ^6']3OW+&6ῥϬ9;_l8;Pr`ȁ!?oeyE_Gɹ}\BtO'9=zB`]e>x=m]W}= $hpL#g_n6EvT&??Nr~p#;`d;*L<xA9GuipٍR n]{w/0:iݘ'8Kt47+b`C&SbkfgZ=uЏ 0"@25FV1QAGKXmB3MٚF9 ؾ ՝`gxƘ I$ϰaAObF/sY+M34y  XӇ.;x~Poy@^(g>Ė6Ll{YO34$+"/6[xu>o3 c`Xg~2pݟ B2yKQE&QIT֮n`v #B3 #G%3'i[#̂f2@3ɔ~>xPWh2K(HI٨d;u*ߺ; xCP]QxKz&k G-Ʃ3TCeN^h%S tHN eX_<-LYҡcⲭ#F$yhMgnU8 cXG<9{%*:682\Σ)̿Ӽ H|<7v(|#$!aPj@ A)g dg!Cع>y0NqIh 8xaϒ@} y' \aXYO']G6!)G9ϻ-lgtlC>;/j}طa\gwEi>JUd9*l]X8Hk~۾8$qkȮt92=i՝J IDATCbkX_G"޵[l]9%V] z؇'C9Nl0;Z W?]5O~Gu".LB؁G7o-/9. \cs]o&kn='.M0-ǰ [UpVW+k͑v7-&8q%+PEkT*rn3W` .6$9.3C֕ZVL6uG0,yg̶ef0^Dޘ_:²޾`C-G-:qꖂ0%݈o+gBH#.ȧdlQ IY 7zM#1A>2e|.7qnWBm.cg zKwlL N08}S{(eJ&h&0=Mt꿇43@x:$k{õ [X<|k]oSKro4*Y+`~J4rLLCNJN8SR_r*O"sTdqÁ @^RGO/L03_?ZFV*XH֡ȥ>ʟ 20 VH2RsX![Q̈s}.|6p Ut W%&gd[ԹԧIp.}(a,d0sOnyr]YanaZJdٝp/<"b"ѣM茌)o0'4{{sd#C)p,N]e LUA!T,MPN<hKk# }m+ǺH|C<3Hycw#,woW/ yq*+H9P_1,21]XuswadQ \(]{8:hoj _\'d ]7}БtfV{nW{Xpf;p2H^GECϊUMu)ۣCBR&$P)d~l(O@;yϷO2Ă&edpwH/02J֏s>kju#o6?p6|-k260#8cbRG t,|BB ^,wM*OS:؄|ͬ:Ć'Lc [kc9)grg am9`ff1A8@q6s_=;Y,4q, T]uUt>z G*ȡ ]bH.~jN:+x[ً@yK#8٥8+')o0 $, J+<UlT`nt[S~5if(wJ78#Ξj Qښlpծ-S:/!M 1{Y~ʬ,dr=)WXP>>OpFm =Z5̠vwN`ȣsjAL-@>jd3=7#4bB4 z1G"ѿ=3M|r4頬-:3 m6|Y9\`B6C7MYr@9܂MS&fg3n^|FH nt]|e$FFG:PaJB),,cy44 e 8*p~8w:yV聦A(3* 3G'$S_qSꗯ-빼B\Xc-!w&BN=L ¬`[x dş[xd~,( Ot0z- M9}W7ɴll(_;9"md[g ڹsgqA+HӠyΫ;cNEk/: w[ܾ0& f#@DGg4/IeDi|u&e)=6lfXꋳG~t1n^k ]7'gTM]O44O-!6>e=hSG{ڧYN&%Il{N0 >43p}\IҞ\p\QT ?W{{8#24lD=(:ș @Ngd!?4lFL¼ʪgpXqc4C-( 7bdxo?0sov XZb-j {ѥ5%',K99:v׬'Kn^b]}ǯ@'ɫ~d䤄6Z#7-R+<6V?jbЙfSꌂ*| Kn0d ;oEZ"}Cz_},U]^k'f"u_(%$^z.YX݃|7k[R.VčÛ,|i!ʈA/䊯${ʓ)> A0as$"`*M#Zofv*6 5*gk :7&LX1B 2)^"(є EGrtp!SU6'ADv\r "Y.UUmFsȯW8mOODn3DްKL'sev,U8g}2N>8 zT>4$&@ .i ,x(#JGRf z@TQ Yʃ|LSEpFyƫn1(#Z MבJ|gĎKf>wDhS !ꌺv3sZUg9 QGؠŇ9kP&' ZSdz|ḳygxW]/zim}?R;u;ȕ^d]Nzo~]s /.݃]_=uHZcH+/"+SȟMzv)S1& 5]I!c|2Śx };R>)46аܞnͺ4kFgL?L u/.ݎ~} vtCOD+L/η5͙F^{,Τ@jN43/5jiQ6H5S݈Qܽq'ȣT"}RHgI73HDRRJ2TeҥnYF7:-sBcl&p ʪ9)݆Gy58qG.d>M'\E#k9إL0~sCgp>6 +8u˪4{98LDڱt@-?A+!]$3p'8.cfpBB/坳W6k)#A8Vdz $GF>G vlaѣ.3)ĖfJi:u$0wr'h$77RAӎBs%[:OWDX'3')\=!KU.\T10) L)D(yepdw?oNlFy{9e78+p/E!ኲW\\I]ʎFoÓ^0 ҽ]׮#{_GmʇIGӻ,]ߣQq]=yGd)o~u'ux |Lt(o(}r6#OG~0w-/~ۡC׽u?sJ}K=_zkiOyS%\ʨ|׽ݞ_UJooG>2o+{siۇ>_t@} O}6x[n-߹wK4Ҙ]:l{ֳo+th3½9?"==鼳vYHF^p_b$kF5Q!\, ~j9vp ։rJN j0f9<8Zϱo@U\_:MG9egiMpfY|q4C\ 7[=J_`:Иn/1ȭA5qD>FS36¢~HL 9z{g:}}Q׌bëF~9A mʳ]̹|ZTnr3:K=2ROgl(tL\Bb>Fo::֟%#{T>X. τR4B~Lf1Q2$06 | VotS |p&hd^1 9ru&. of3\ppmP? X "E:uK/_I\GJ\;?>tHd0Gg8{{Pa CU %]fÄR!Lt '#K(SJ ?}ds8D(򔐭}O 0PYFQf4n4q jrr͆tJ-?ؙG8"RBy x:Equ(p)u gdUW=AB<?Pp˨4$NJJuM"0M=D2-KptFO826j+>.Fsx-qv:<#Cw#;2.⚑qpŝ_i(#Ir*Ql:J$6(C!:8l'@ l f(gx'W|΍.\gyQ7?:E}&QxGi`uXIC sѓo 2%7]/rKwx6 ;k|l`i/|Ak>ܞ J,Aen=w~u'~y&0!^O﮼IOt>W^vs?g¿Tpen__\{?9#]뮻<Ln&9{{_L\o >*?:7q~Fo_GXʝSӷ;3Hƿ_u8Riagwls*|:XSaOߛ{AR6:@iA>p24XNJ X^bNWIh0:<i )[ŏOQN/\kgrah3_3/`+L7!Ź쯰~ԓY{1*љg|ڽ pB1lMlM KΞ*ϥ\pO0QԽ#寎Ӹ99%[YWH@ 嵵衬+;j5մN/|`e5vAg:зߏ '?nY7;}k! <" `=Cy.ρL,Us[sOy`zDy2jD|Gm P!Ȇ_Ў\Gwe' 8ԋ,؞ۿe0cQ~I]ȩ Y=fH)Ph_쎉.PT \O֓TY)8=6+$E>ŮV?8O0X:aJxTs@[P:. yssۚ:w,ԆN#>6%H`i&F.vR3gCW|Sι"t ֘&"Q᫳ ܉ca^ì F[/jԉ4otatt4zN[ız|p5΢wp;N)CޢKsZ69@Fũ 3IгKE_TJi]hDJ&3Wy9뻸S6CKt _d&K.x5 ܥ`6 Cl H<:\7%?N% $)Dq$ (Wy"47-}GCMiR-V%Lo\Z`=!a~>%'k:ZR{~R8vXκܯ #\Ks/$heN2_Ð& 6۩#70 |cݱ.0,yDXƌȤj q OObBP2E>&X?gKL^50@^*=rinEsy?:|kۘsSG}Ls\evwkz׻v2[TߒAO/yI/xE'^/}.xw>;;;xLMM19>޻wo?MK!嗴?{ ^v_~=ow4oEپ_j5jyvja1bP,3i>n/t6i8 ԟnh5Goh"ص szVgi L$Sm߾VieCi;etَIP2#B+kB#?{Mۂ:WĮsc+`3P_2fmm"L2K9`]n'ZF#)Rg8G:ϚL}֢dMt.uGܣ@Fj;+_G=Hjw`]vu%EDg\%k:Гi($pg+#AGwK"L}Ǝ)wÙ W4͠"[?e*bExto&fCt)/|+y&lGhQ驋k ȯmE_v2Li Lcb6gœak=lSlmya{a1(t N IDATIKvlC~JAe ~' nwlpuʭr5IK>ߢz_x TchXz:PR'-MTE6 *0g'(}BtC/X>ydJQhjHP$OU8J^^SNI ^\U]=iI=I>s-^Q~d&#TF y(<]6[W '些(Gjw$fE6WuDxӛ|'pw ŷtx淴/| ?88&Hq{Ǜ}`xы^n:|c{o]uG,{z;ƴľ ?e< ^Ee!Kx%F>8ޚܞ'wňX;n=?O`xn//,h;|?_-oofn?gx.5UY$NZ'WD@U'?{Vur+!ꫯN7K_]qY^skjv{{2Ԯ=?m'>zmp.~~^uUm<|/OϙSqV26Fցpktl2J?:qY$=d;ʩe3^dn38<}/=1|^ҕg4lgW]ӿ02R f tZP'W ΨdD~m֬_wd-vOxт- s쎌n0e< zb;+ \ @Fr,uti,N6k OS:̍G7g ?:٠PPWKguk$+v`5@Kb݄N"#.؋'4`98Q4r \o t!;LOW7-'ǹ"C- ]3Mc+#-=ip!xYPZ zmP K>NJ xs)A,Wf%hYFH23z+D/ (!S@!cA>_Sh~WfkSuU?kAq.( "6Fe_U*usa" c\srDDa:,Wy0vX}l}OXL'~G[}m?|>9"=̿wVa\q;3+?샧?upsˏ^`af\-/+8t{(חYfUN8oMnQjǏo7@?C?&8yC |{oN5a_կUз}O= Rj<=}yȷS usG<"gG._3߇>! >oTxr'O28p=@/>mo{?INCsˮ 3o:²RKoU!mc>zGll.zhh*δ_4^ɘng1l)g7,c_cgy<f,v#1?$>:sݱvQȣ8煯p*Mwtvdo06 Úrl 1x%16ӜЁ96K!Bg1|%s_\(>֚z-`b҆)/}r&\#7yܥ^GQGOn Tftx CE|Ф$8 }EΒ0I@ =ck '"t5Qk%Z__Ƒ6RҊdG}2U)cw_2Wy tIkIlG13Yn`)_ec 2Jp/_:)bV?ݩblLcegQ\8#T}gKݝ_=]T]oGOm ,)f)7)Jb`.|i-z*5C?{% ׈P6lmmiwhz< CH$2ZhuogTVGMqTyC䓈8r{s*5MDzaӌ8E&F#pdRf,K/G3=E86Gz@v&y7 <3@ Ari?aiSᥛQk_w.d('c'<"To Ξ+\ȤIE4#|m:f:CnuӀ}@If}gbS'2a#:D%xNzf ڀa #  ";V&s{y\PydkM);yeU4 N=~56ʙ0^p@>?>[) ˧w:"[ù<-t'z2+L&%ג@3I0^~; 4(_,>r Z 0j/(x3bom /ca _.{fp 𕹯6 x'rm?.,ΤrN{y׼}# GZ?)÷ѻ>. ;}7]v*v8ėW'?IF#מg1=wt|l~5,7 Gl_~yFfSnD%y9y6:h7j ,?.䒼ζ윊}qja׭{JYka89fRU|@ xsq0V9$ƘBe2DJOPՈp=ϔ)uU;𔠞*uJzMѻHrgy 8)sήhR )m[tc7 H<;.\f0U#Yvq0Rb'F*u7m{NQ&mcwG0h"rSsm `:l(Ƙgklċ źQ IaV.V5Dh° oQʆXEZTmŪx1D{c33(`p <`r38ߧk[ۦFE6p|Va}DwGt8ӟ|{f3yʳQ hHrlr#SŷNȣuo,~d|b_^ZT\;Ic[Ug |,/ iim8tÐppmuͶ9zZl@W \ Xe#G8˃1fLNqdSA7Cwp.V_%E~|Ny,Gc<ÓȝĭF呅*`4pu{qHxoVU'?B){w >- xXO[u݆yoe) ~ ye_kk2>© /3èptEk̆^̵U<3*~X⒟-n13OD?V ΰ>ƺ!(#[c-F13i_9rtt/[VEqMH vô8Date?ٔ> Jy1sq < ^ p4tZۚI!jSi_ /U&QMgO1D1`F_>|5Xe,~⌜?xKUMh1Dä|QȬCc*CqNS`e# (HꇶQj'YV S%/?B1⑆ kB&`V{HWASh[jdf3ùP_>&6le*~HSGʪ(w>+[Y<冒)O;o 3HGD#$A NQ|ܧa92oDʭi!:26"Tl"6pˌ43(HR~[Hn/7Dz"*33@j1 #Hw?MeY{%:ۏC) .0b8U^G0D>g;駔|* [xum4S3bR즮S!p2wކ0WߜƔG:<A#Ao{?_ݽX\֫$ ^ǠϽ8mCY9..řB 94arV&%p8m\^7` Gc2>~x)zy"lPZPkC-Å<.1i+aH2bYxVtԾ{\f^ <ȘV[FYއMKyv-*y{`(k5Q6XϞl#Eop\&A7d_2Rڽ^%'QZs1|JdŮ];*jcO?waڽ3E&AS?ӑ%y\="NFO-wggw:N^\L;׿כ}u_^u#׽ך}ыΚ윊}Zm^qGCTW"6tQ9 3ꚴ@Kt]$*IA]"SHt9䳺<kFsP|#{̹:ed${9uW`K4e(Kb>_'_oی1`a"o=v2 KeLpo.jFM2NNe6e.u0C#|i{`GfA9l u ȇ>;qNi鶁,4eC 3/Ƞ 0$1Lcpr;6`.'VxntTֵp%4a ?p~#%b}plaԍɻ: @ [1B544|!A. uyN#d3E%2!/ Ay ɽ/I~`<}c>C4wAʂ+Oq&o[o{[?a͡Ç?|ڼ_җ%y{nG=>'~KsՕW5/{KW؏6|vy]zb7 t|# 1,×͓XR}%o+[BvWשKm=r4Q ݵ;kl~mu$}CI(\rɃ~y˛;wT齴ynKg1=!W^j}pуfʑr2]gw'u{2bmgx=Ӏ}Ɔ.+e%\c z6}Us.޷vouq&]ѕp(kDdq !B5;BBUI1g86.޴mm{tj0穹Lgٻk|k ,Yi(.NW9@{ipȎ lo3%KhjLE>;%#B1TquhUSN :ycaH[ @CUVAPLK+: h űCmSȑúxNLH/g]fΰ!udG7J&CxlIN`0vQP Fcꔿ?uCmѭ,kX 5ɽ濼Xwj?y+~cc;.%YΙk>{u<9W "Gi>'|9M[׼˿V{΁==<sC>hso8ܼDmCrDrTeIf*7k3;LcLc1.3 kD9.j(:مV;c0c,8h8:u{?}f_s=S,k7܋fxKmaRm3bp'4y+]Й /c°~' RY-ox~|+v:~mʋYFw ^F4d)E07W%YB~#O+m4ȢmdSlCc(@YdݼY&$|q_pRk>iͷx'$C5Z-B.1xG];!k,8sve70=Q'82PVAIx X82,'/Ϙ}˱e^fR!${ 5A S4r)euWG0kc1,NA>0 F[;.`nQ̕rXcи1t8`p"/?=tT>mV Mp~") ̎b {W;;R ) O'GܗKLE8M0q$߂4?iPU ;,2#UڗTg}/rʽEzeJK 6Df[wo(.䡛V>Y|!KʉghP.G95i uşz!"pf;'P7LgJi;v!:u ɱ8ʵ51+//osAWK{h` =)Ft<4'4;/xKSW ñ[ ?߄fѐ-Yeif Sv-NثăiO/.e6o"rf3 l@y6h?0?|?a6Fo|cޝ]\qKd80nqoL |5ͤkl:^=L2gc^3f&s1suΦ|123G-11\eKc]Y\'IfwtCbdfpY45lqYPX$ׅctn6GYHg 7D>Nv6D\/cS F*3^8I3یE-R/B~jXY4<ә}5 KRWu[-E7Nvw+DuFR@#M<5F1Qvs/כ3vq|1̈[Tu[a :ѰtF`OnG8|XUƴH:B njv^[FݫYfi{ :gO#J#U O ysud14,!Ŏl {&ofM}U,`{{>||'4X}N~dRZœ;nrg#; OKԉfj f#3 BQҠ*>:;,abl9s) ߼AHSr6Y9:Fƹ:-]Q_mqnT }x,cI1NT A#t,@W"( cU#/$yVF6 R35!@,,oOAmYuQ+z3Fjk`~9Scv^icDվ-+A3|O] ҁyd{anU&F_iKS}~QI0䵵i5π <;+x*b-%U4ʃgwh|+awK"y#/ԕWXyAo(:> ,szeг2p:rb)$l{W膑OD?6΅8YYŽmy},T2rC>َdo p4%:kI É4[~dQ[HA3mx!3 dJ=K 5 /QBLU'J8)ynw zp-`Mp[ ?7€fyڂtZ ȔNV )<4}q""6¡d-(nxqmYo{XCUew'-FT:%$e"IC \-3"#fm%.\9of@+3q_p`]aYa3&C-tR^2\|bV*m#<:Y uઁ,V! d )m^9zSqˆg(0Ɔx/?D:(`m03>S0-Tr!a\Auݒth U4I3ʿy2H R罙*thÛTW0F ԙ/0|8 t[$K )VJ/:ρ?77>cexW8(3(cR'gu_Sq?H~oܟ_a ͓^zp[ܻp U0{mFCFOP0tXQaD Zu ;:o%p,@ҠFsF;=Q?|4-+q@hعdW [od#pơ3ζk \@C]5^Z܅'ne@РYq@~$ X23,w}x$Ž =OF} Xqm4:bT8N=QZR7SPV؏/CWcTNE˱1=nXlV.%Oߔ\ieG騭 s(|zWbSiʰď _+Fp(^l9iM4}{H8)(.0wb)q`\l/ev1٘OԀs#|+)loR4د5!y.dg%P u H%]|AKf(Rm/=mX;|g>8=`"y^8#DP 52b/܋o@V}*#ySht:%FOǐh.]|i*}ʑYM/J鎑*i+:Jc'5*mSiH*Hiӫp\̀K3ӜP2uV{hbtvҒvvʝ?03ieydf%Stg—x1*UuDK2yAQA?4 ն$ꔲOh#= #,Gzo. + _D.J:yop:?sSJ3댁;xhgG1 pvq1 agΨ ѥcpugԨJ81ߎule{T07*ԫ j={s$f 2ǯی0C.FtU0=wgtwevwI9uNqwxsf#[O6vӠR4zok\-?2Qg;@vfOAFx9;΁]ǩ nqtVLA7DyƉqpH8`ɩWc*N QHb`nP=n~ljh'nXlWǑ2sIG GD>\8pI,^kt8E't˨> ]e{=<N 6Æ#‡qި3sd KL]'mEϕl<1Hf^n/y^*,켄*/ `1|[O" or]cyOԣ>6αK+URNju!Qrh땯. !$#THHS+I{zho ;<A5nvt0©&E%AF8[BgoTc "/ԫcBܨM$_ˆ##,'O{/!V|M8pd[y}*$~leiјҀqs1.pqj~ЏXy !xƟ WEyjW_vMsD#yrIW8IIv6[$y3V !叝ʏi;|fd,UWAT>CmtwZ u܎}<#syHqڀ 圳k69pp@Bp>: g_G'ׄ;xc4GWṺ1pr3}Cb4h\25: }F&q f O;8Ora{!xgd=NC֏ƶ=V?\?\V*Ԡ6 u'#f^CՍb,5COOEkQ?L8xDz8x}vh LpR̜'0@:[T 2Di͚O:8ȆACJ lÁBܚu/GY񩛖ex'0Ci3UR ,-/gf_:"c8߶x˿2U3T哺32II'01#ɡ|G_B`Y'}(\HdaH`?xfxW$b!4T,| IDAT:lk b+kʭUy<`BYN#1eXWusliW VGY^` S.(MӹѢqZCrC]@ľ!,"g: ER.֝\$BKk.s k)`1/034(qQ0Rm9 +]cfL- R(h/1ZD,OK(W~zllCkJDŽNSoixb2;*1:;Ә<2!<.G9f&َ',kwQ~1bq_! N;p?APKx-\ְSkay 2:WQc<*/ip Qt{@R<ߑ d m,I)o);X6zhc m,K6|mdm,dv |*wїH+K.9R672zŏOx^:6qΟ8@uKvۗ{Rc,?a-[r܀(5}G}^\E[! ;eC8_X:KD5ʗ]{L8×n_69́/(ӎ/ΔkLhDDIPe[:jO4tPû7q6϶n1rLeT|sUpޜ#*Qcqf`#5U3(!1=90٬y[ά:g[_PZugM5FQ>SǭQsD#q[m2; Q,a$jYG3 C'曜rρlު[RT \Q*c[ ge8W,Ul^#V[@Ӂcwy ˎ?/3NQЖd}ψBmSb7l·膊䗞85 9q 2< : >i9ę`!ť !, `vbV1K_-jH Kuk8D76L>T2cYAk:Q~-1!(7P4:\Gƫk5(\ g9UwK7]֑Fc܈QX3Zޏz Ή9?gDZWH)xNwI~־hG2o2F ߐrCa פ ܀;Dr{/gq[C\A;R) T_ ff{5j-."0&F8BC&=uϲȓP볼G'R(gL^(D#=w鑩]ad!K88[t }$҄W̿X004q# W8EY<^Tpe\ĵ^_88uo4˳NH-ޣ3Bh t"evJzmmN 3FLmiA<4ȳ\YSG헍3|R2 l>np-IE+I/ G>FX*׎ҮsDں yVpX@a)n-i8,:F؛`C]gpi8qoC= ˚Y-4i1^T9 ]cs*.IT n- >LcʭK2"GyɃclGFo`\dܜh(m`69p?S Q7"- 0ƾvuiFD(#0K KGճS%5&NܜFCu'q ;K[fwBj4Hqwt,ug{UE1ѯ gS ̼d2x*C{'IJT#H-K cG,i|M019\uwswߨO煳a!u_iz6|t5ȑ%Ȟ rIu]J*0TK'p|;)[݊Ҷl]8|"8qO#jbafnɕX LV]M !7'[a*2qVIJywX RSf&D2 FWf1MOmFNl6b,]Ј xJZ?#<q$ã0^Fʧ 4$\>pdsaB1]u8luz$3΂Sz46ScfbGGN1WVC[j~g![U}vs'dMrQG#:4hL KWnI{6* L ctg}6KaiA߃n2񷞾ID *O)峜e Y+=H/GvKC@DD^ hYvȹQ<Ʉ"/Khtހʃ%T0gV 'Ɋجx)ʘhR>c4{3rby'#D] dQ}O\G#gGƏ7Jb_33ƓEtĩbS2Q}J&@Jj 2suq1=y|Sh=0Oixhz"&㳾gz@кSU, ٥tʑbۋ#͎ A)l&!H)5.Na gN:#r#NU /)Gh3 C)} +)W Asa¤+(|x=W 仨T871 (g739j"`bm"}ywQ3{/?imʫ op9Czf]z-/e̾\WdK;-.rm?`D26 m 8I:v;z"#ʝ@ Wz;GaRH;uH%:sNZs/|/ǩexK]y%`m8pwfe̫Uwb0ik}1yOkgp 8;k;iDhilF'ꆛyO77]mN \hp| P82îժά./h@`0@nU4!iC1$8Ü\?<E<z^RՄ\b$ jjRxE6͊|sq'N~CtYve`SaH7-4F8;u0q=D 9kݭy l?t!~ޭNdxN~N:RtND`nq& ]gGX1X9iN"F(4V / bj%Z3:]QO)`}8tg=:(ϴ+'w7 ]5.gOa) 8X>Lk: @;OEٛafȭȌ O #V:&"$$`<-І./NNk U>X1tZ'6 tlx|# b`GgPݴa15.EoxM:,9oڲi}60rqؤ wLƉmFMOnJ^ É$r^Q D0mb M% 7A]M[#5bu$9`C2 3ɼ2B9ぽjbz 5 uZux,鰼2jC=7F9`AudDWCb/m'3sbV[h[ywDtL!nfM0zp+% 7(.'Qw~|_,3PhjdOy 3'L (NrjMXys t u36@qetiإ N ^bˆLf*IO?Е1Y몇iB@.#( eAF=F5t Ad oc*: X! _7$I(8hݙEK:047-CPWe6(SQ1} wG = ,c|pnרnH{kw|q҉1ݬ/|G8p޿$:hlc_a=]aIcP`F)cbr./!` K󻾫/QZq6b`DrNQGH^"'"j}!E/voHy!IyW6L2&o𛜡[gm|os`9(LkY:yXzIXt7WagW1n֛}_io}yOx@6s v|4`)uK$XpAz<LsC!?3wY1FrOP4mC$lt6LfPÝa{چYjFxTa2FphV^%8F18np@yFc׮E7[zx%kKjXg^;ЏgUQ!\;,XhJ6HXv`[淼ߦyaTz6n B-‚PEy] _'/E{KNj*p/Hw7t֤Ck9xpD^1uxCm@]H{pJ{Jrᕐ Wx' Yj>kǴ[z(S蛚¿*-s. ,X?r )O:UaD eo )GAN[MlVGO|S,b&"7 L ^yⲑ#BTYj#\ٖ:#OyFvb'Jf';'{{νDo@?V&6Iܻ~h>Ϝ{0rF69pO9C=c^ *n>LںLB8O]]뛵 :0:ócg=ƞ#l΀k~_uȉgJUcd€ZO fY0<|y D PHa TDwgglHnO3㤑;c){ϤkHh ^\]\J!;0| sFWC2Hـ ~HpWxXD IDAT: r燑=Fuz H"@YsHޟ>ii;^WiPkdng9 feź3I4/3DC#IB|%ϊv\U ?9˟@Kس3KHYLya+GeN;p$Te+08\~Zd_8S [77 pOݶ/Ce;9!  mop} >I򢇺+ 2*$##r|Qg]+9O~+DŽ={GO3}m~=0Sduk#M7cc6?ibtsg\Q/=i{ʵ!_)` @#:J+[Yj#.`?͏X`z8zt~ 7ceĊhk04:] O,v4qBiQiUJjGi=QsI` /aXY c{=:xFY s&*͉UU Â.qȳ("Fd/M39qV1;zU%1&ܤ*=0Hc1:TcxWKy΀M"p dF2׳#:Pc_)H}=SX.sm:,) ǩ0>k*3BC{LE)3:<3V WG*V\:Fp)UBQ?UiD[JYaf"7m= :zq2kdLSNQfMPn[ġa)`ؗWOm5_YgɏL )E "PaѤK5bH`r.ܭ:pl uP)UINe HQOzZ. $%,`n2TIp"駨H 8t,8\log2?r3s'/]CFwP /^xf(izQqa`K~6/mb;л@UKl(o@ :amM='P4]S4p"CL]&a- <)i;Jw?đC;0qqۏM+d 9pWd$\~So7k__{Żޙ 8׮^sy90\u?69 .n~3koi&y_+{p|R<Sw}ˁЉȜ޽u]y‰.ÁO-0',Ʀ;Lb,FAX!K9c_B^q8[cB6⮽3͉oT C̳ ζM4|'|̼{?G'@ gBȋPDq|Eeu1tedrl?8i>9& qR|rGInX蝑A-p'm9D|'Y0\20m[6|5j؛䦎+}ȊI M=ʶ'/A4-Hhq_2[\K75P vTqXM'kP&;zFR.Q.Po^%o`(;s!,>.E(Q]觼L@GbLV2XI(+KPx'c QFfZ!cR-N2961}V36g )繆 _g/jK[m$nx$.Z[ftw[rp?Ჽ ɺC?'2ry@=]؜ٽ7kg,?`ֿ! \ @@`d9$;^A^āhVXxYS|v_&\fmu!$}PGARF~d"m'3lX[8ʲ /$|GSYzD괠\{sotu]8p+SK/Ergnoom53 7޿>hIv];qs^s >Gkn^h^ԋ#ψ2r'^ ras*9qfU}Hޏluyi{@sމD͵?é!gz7?y_ݼ o_k7o?j§4G`sS.k^7# Sy9hzl#6( `nv3=ŒFٛ3A͟|晏?SSƳ}r,97_c)"M4FSv (wXӬcX/Ǵ9JaTIN>y@^g{C˼q {iYnf5f08 FyYD߳J> \.-p&[[{ gg0:4 ZIp8*N\ƨt_8E/ęBO\;bkqb<Χ JPu6T]UFYl6Tcs<h#u ΋%fUٴ0‘MсG 1W=}u<,JY.נqNy8E'.ڃ:T <Š=ETxAaKE8n 90L(A]bخ8O]v- "KHCu˨?J])0h&rԔvf]zECؑQu(H2G !k:?+&lIi"MN=$EIȱWTkCt->:|7hTRʸ4@o4 -yY /ze2^qL_vrl"~,_u.n_\6d"?up&_3~h+P.2M40 [g€ᄱEEX4 ^ Gt;Vړ:܅|-!t.ߔzx  HF6A]`X;\vʒI"3̟Š2^ 1򨔑2"Yt.]Ⓔ4Zm= 8!ή{Y<7o=_De43T~e7vR Je}|ly!_=*?L|Pt}{FYojGTM_g#A_Pᔨ}-c$reNw@gm(?- M~i_(l<^v-@:oG!]9:gWy 1R8#>ڼPw|cHS5?vﹶʣ tf+nlPW77&.? ]sN[7|Cw7p.~_Kw͓o5>܊sknytp ߝg<щ?|C`c ]_.4uN#wՎ2 ]ͻ>zG-G }Wp *)06j8F:l08A]}萚qL: F5pL v'Uwd$ a($P1p*΄.jhb= 1;4]6 qf,7!j8k?js _z|%I㒢ݦ-1ƇqfY`YU0F&538Z\[ HKWvME,n߶msy Yƌ c-=;<:vvh3jy=ttPE+y&S!þE i[=28Z:y@tKY?N{t0c.m{/ƽNx$B'fklDTwʎQFd&|q@;9U*} -&mi*NڢC>SNX=p?:Bq"cP84mDFPF(tTTct6mHYӱ6=%'O8?qN\gFFPR,HyN"D(HmAJ,Q|5dPuQDJ74 ֱL~IxW %FU;Eh1#_c`bNx1$ہʌMj75u.-KmYQvpz#[/lzT>C">l( ]<cwj:[AƏ2{1x1tXWg@iSYKU/vHo_Nÿ_z8u.Ǹ͆q8!z^SӒ.CS[ #d-O_Dd^*',p'eY}I%ƒ7MMOJi(.TW_}u|9x` dK]`Ub6{Лö{~5;ȷu]acdo Z"&Q롅hMeW8t <5ǩ8kn/?~_<7:kYdʈ,//79a|)_>c>J*p7/:rh/1W㸫Q"oGwֿ]u}]FFƀ 1'i c3Dˆ}+ma"K5jc43׎< p>g:5Flj4Z&0^=|6FF #:~a'y'<CC.Dr1J':<~uv?;v{(tB=l0ya(Ef!7U!x;btI+F{]z!!+SXa~Ͳ[_Ơ'#3.ŰwG 8b/1FâӨyv!8rkc|*^C|7ѱl[m?Bp&@Ot"Z}Z(#8+F5vVv`'*v=KK@k5|>|,>31?pa)\yoa*DaOR7Hw4r j`pٴEh4)4a mTmoDrW"!vp@ e_y6Ωfg3CTWr;>IT]LEmEu3???d"CG ьQx/A,/]**njRP&&[kW!=G,2bt:al LUM%s*p}3>u7Y`%Jۉl s@hdvۨsˬEDvZAzȗQ|lAX!å1%.nX旱yPe׍~C>**R}E|[7e+9қjе v/ۅOil]Q3 b1Xm9#uvpJ': DƠ}% a.k3,K Hba?6v.]W|~o_;׷l6zkf:'/f`ۥmBݠ?w-3[Kt1+}%PG[Tndyk_}8eKn䔌M=\ :?zޫWr&H IDAT+oe7dߵ9Rsοl/З9l62K9j'95 q{̙+:wO7?w_oWV!gj:Gm 6ֳIq}Ƽ [0b> dzl`&[:3f_7|͂x*r{md5d6iߜ<0Isţ٫Z^}nͭ7hi[*+/$qB]4K9[miΒrÓ{$J#27׮V:+?p-8,5A{GtYZNO{d vN^trCs]WrlVP>NݑX TŖo ΃'<^G?I12+O4׮w$&I/cYHg}?0h\&yf !h!Qf p,Y+Ȉ33zFg ߐ/1΂MʅCpa'ѓj7l.yd_Hb4D9({A~xs>FG8r$ >0rE*x<B1N8Pu]L3 >sg=Vp niW͋T*(ߚyб3rbMp"{".pm/x;bKyT:yY)'99%Wg / wagF>5-4rr}[//kgz\\G 3#z:k=% B_Few:)_"hY0K |Rf#b/A6{3z\{=.^ NО么(gQoGwÛ^^u@ŢsV:B^ο2.uTv8០!\x}II>l/+|2,`6" a?>Cw?(< 莏 G{ƣAtvB+~];~wnn_ %ۮ*6v7==cA"sm{> ݈[;֧eԿ)zNC/[|{_rԝͿۼn/7.0[jap_K/|Mp1g67e󁯿J^|Kߺ婓/EmgNݼ\/Fx^K|2_ So_ 8;?s9DSOZϟy3}-DދCP]p3}-_稿p#]dmfq\l!_3Ry_ms67`zlZutQޱ_[Nk[\K'~wkKFtE֓rQ{3؜Zw`qzf h)vAF8)riw좑g.Z+giAWr96C!鑍cFj?w\])gkCNp1ُrb8&N-ɯHzbၣBR9o 䭱)RRy֝ 8\If_y QΕt]ܔe'9Usp=% Tsw֘5HwYҗKXTgHQs|3I@fܖ%2/&#yS:~ehՍVW(?pՒ׌1^Vi]I.sJS=?Ne5M^<Ǜ_kFLg6Jj0K E ̤C Na}V]'F'JE9׳44dvi-.&X̥_[z$9-䣬YէXucsVY䶣-\t&,Sڔ K7` )u Df*;fopȶdQD\P!(F{i3v?O].B=m4|1f~p]]|#b9?O~_sioyuF- M/]i$]Vm" i_b|?IuYowtZǿ7 Z]ÿioOn?olg[V{-cG(X{=;8%/&wB}n!տ[_7 w:}O?o43x7ndnz n|ٝ{f׍}H~yHnӋԷȦ>t'Ԙns 1ɖJyL R;Sƃ:#08S{$w!d^ٿHw5Gz_;ڼYЕӨ`Ytz]{>zYރ᤻f 93k1F9,;w>&g\~>)+-T {֥GIW3<@v.e?A26]AfƏB@ y X`=#gY%ݛꮜs3i>RN7̘ 4Es=răӜţmsG͑,]9n'C?lg Hq?CznL9f6m ?n/Kcl'Z' (!*K*&7>i6'fAdP Nɏ},KM0*&ZSc,Q4|ic#T3d  ' r'rEd$~jkf6W;<ߪ.+.W+黙٘B=OUdz>bY{e N';*fq<0U*רu-maL_ȹwXokxŷ̔uƉF`Me2m~t sK5nkKw9#x2)l[Os8#pOl,ܻ8ۼZNPM/4V;\G9C\!/^JdmղlKpw`Ӆ;wG?E%=P^y=Cc52 #zWytN߂ O;H?o%*\vO1xσzH\pujP/-V*7/ҜaԹ4׮ex zݎHȻnT,ѳ: U}^{91x.+?prli99Lw5y~tOuc9_aJn]to Cڝ|#ruN 8**۳1__/m󁙦:9`7eZ~ׇ6_|;vQi} (\;.g/gfvR`_wt.W/?6G?}3Sy77T~~_ݗ2ł_Ҝ~y?e?+_rf{^oG?K[z0V?~zW;-p] wN)Pi9[󐓪s ?k׍RƉEgsQm)0 Fq] E<oaD] H\I|EX\g̫; X7'ъ$lU  #psr.7; PAS \h$,nm=9$* j4,_굖T.Cbެq̣m uEGys[j{S}Õ֬XDb7m18D10K3KCZ y9@a~c%'ɟ ݒYy=@6|4 qHoebP >ݏ_Uɥ\={1GaϕlgȬ͗>fpJF}JRmE& 3!-ͽ)tYUA{2/U)X:2 ZZұ]LNpHfOIFQtR } B)!7#:=`wO6,d?mܼE_/o'wf_37w>nӼ /ڕeʲf9G?ѹ 0;,INOo~o?|7SQ?6?z;6OW Bȏ5Bk<{ %)3Ghԇ?L3|m>1iv?2dph>=}?;v-!ka tk8c:fg 95B/I9(q%~~F״~elFuI:O{L6~#9#޸<uf9#pIۼ̬ E+sh76o#º;*B6cS.M77AQ7ɈJ3=^3|yܔkNf69/@dʑ0LU_ XΌ§t4]|n`449-Qp#>*czN8Skɏ|o&v۝=|/o+G68o:۹s~[Y8ZE#+iwmvGZ2#^{ 1K~zWYgC߇6ޫNf-TY,P0åQbG?tӅkfݖe`\ AN3%ݸ2D88RyW(塩#Am?`@,%‡@ܔNֈq\Y@kGw]ohF+?9CƄAԢ8>SNcfΐF\\dtqnR;7|SkPLk>lY{TZf`#n>z+Kq.Qsh\ gǎx.pF%!4(y&<_pi G,:TҼ8N <׶! [ڎ6v~> >=BD@  9vv ^O9eꣿXyqli5-o9$TS@ps@@`~Ӌ6|u;cy/NBO$=:vNttGAd"8a?|S5fM]}gy T4_)g.r۷s߾`Yڰ ^_[,:}{߆7W OlʹW_}3Lk *If`"ڎs{2BG-u%`G/ٯ)DkWB!OAmFh8F6{ZC.v8+11ҘQܰ9ήhUK~o>/ف y5΄{e}< ~O9^-V,Z9xqD5]T>T>Gp͡|? +KnL{p*o9q(KO7+m9[4N A}tE[i_0N7hhH9(T_\{Ԯ9hy?2 -7R+y[F{F#d_6G.~nRF^2-c~˄y{=:m1 ^ʭQ-wyA똃[ݐY~ TI @זV=GGu2zAKǏz/GffgfwrSy(wvq106&`IN6 A2{!V5mk wAC5I&_EFˁ_fufS?'aS{w7lETpN̂}ƫtrf}f2'3`9^3| 2ܫWo7ݟzklo``)tz,s$=1E Ǜ?^ɉͦ !fV82 s=q?# #ml q,WR\lyΛ3{SvA" s{`vakzsJ18j$M}ܶE IDATJu^E}BrG ;Yx%xh6Q*s FWġ8*\Q&KdE6%$smv?m0٧.;ݾRRw.Pf@W 3S;#}lJv,2:nJ KJC_J3u~^7k9>S ҕ>SWnyXݣ)ˢ=>kɂ OFzoBAwAϮݖN$AS]W~[/-eZ5ZA6^CTr\R+w=zUCgv8D y|^i 'YCT0/*;Gsg"#htUFKEkm8=$M E{K\=a5kb+I,xtbގ{x'S93uXHWyh5:]>eNҧ^5LHV=I)iWlrZ05a<3Yu=m#Իq3 ±t:Ω^!kz4\pCXQ_jF;&©zF%oc/1j V ,jK?n>~V~O+.t5~= |{:NX|%NrK%{Zӯϲet3=Q6˩Է:#3`~[Α.WD}T6:z\yi.`r89>msOoֽVۛ7;UDY~l{4?>/4wM,#i;`: f3(C# Jy: 2g.FaDU{d3*6:38o7:ٲ5#'^ՕqF_{ٹFQ9*D_6y1I3fI꼙-9|7$ %?W8;} 첗^H9o3@fFrX雺>u_v?K P,ӊw,H""ӳ6*.!F'; o#!/:3AKxƋ/ M_l¨h3Z:N܋ a zNnP=[ f%7#8=*J<|[msˀ|hř;`"ޱvwf 祂6+Q؏'GoATFRJcu\=Goy\}y]U3MoXY߻ñM\Ϋ5*Rʦ*)I~9Gi66BqHكv9 Ωy)TWŵq4]ŅIBtC,[qxcmSAYMVL?/ɅÅoF+;GGe7MEr88U7KS@/hݣ$TFSrϒAeVdC>4qӸ82Qu[$&p.+buwmC{ӋQ-tO8hޭΠKE|G4ZkKN-p֡;od"/TNyzދiif{4.^l) ha-_Q@c\ﯽK`/ߘoǪb87FtLΞ7~T(/G7 '[,R}oD-6}iϘ>ҟܫ?̙fBSטҽLeɢ|ي?j{~y-GWsDoB(3 9 'zaV@nibd8 ˏ.7anUʱK'Di\ mcL<&Xa,~e׺ UAfZ<\]8f|i{iċF8%c-9N0:s9{LNyG 0Qƨz٤e%b흴-3ˢ[oS. |봂I]v/8B#^hO!还GR91vG#XEwܢz|SmA_ IcWwlDd>eα^{!&l(ůd)u'{n`n,B fMN*'8$Q+аe?q Zf3_yAFl7Uvꕈ6+f-fyP02/>egFȖN0, M2BT".*a6rˤFP |ֳJ< Z`#U.=i} ǴXyyxy&nrP> }*~pM% n`twF\ek*b鄅 )=q9=TFy_"<]U8=_?h[hϜnyEq2ShoAh&fH"CJ$'2y4gHʰ>4)Γ 7z4hs^"-@>@#.%4`61܎ϗ8-KHٝFC 酪 6Jb3jxBFﶻLawdcļahVɃvsd JL oooC9b3o<ʫޥe^ы^^;=%W\FO4ҕ]=2do9xvuKӿ6](9o^2z@_?K"K`/K#m5#-nj(s6ste%um,S+܎ÄDs ɮ]=<'0\9`ad뿯]yl8d4G lGQN1=zFGFI ksTF%3M1^KNs 9)rx`MZ_&~n_rk mx#(3al;m3$2hűyBћ`fQ[VןgZˎ/Ȝg)jYU Fu9r|o DSOFqNgǑ_e8? ]h#KMԈM o3#onvK+geE#Wr=fp^n\c_|pF9-@AQeg=krw9=ʎ4A%ƹ'+=x|0 `=0gHf^l m"ɬ^GٿfDJU""/u9e} 9NQ 8- k 7dSPh41{̉Q\2:gC3`ԓxݓd3<>v;1zfNv孜l}PyƧ>p=K-I0?~[Kc2%}nkM$^%DCtްl*lpL*h8!Xemۆ3r$h~:d[`т<٪qae$Rd\nGFtW V=2'Sؐ^). EZ/K=bX5# ܈n DoWQk~K W2&ti ݚQi6.h |h`HN~e:u k8wU˺*._Zsugr& ǒ#=N[i99 h O=_gjI0|# J*ăZVƛoEuf8q}]\ˍ v2'uyʇ|lG^8T@&(˿Y# !/#)rgA%6SYYmğ띭ӟ%noɅ 67I|l#0d3;Ǚ##L9a%x$7sA@[g{t=ҞA٪dB q/ F_լ 0-N7l`{c1>^_}}l2%Ϩe;c y-&GV0fNd(pYWX\\ċdǷ\ W/{ʮVD:O@!,u$ŒvJKݽ&_ƼSn\#>f{ \ǁIi)5^N (]13A'gu2)7|oA<]2d 7}n|JKjX/CP@ZpGJY>ALs̎ = >󕓷3-1Y[㆞ D/ݜu^5G$9 Gd:}e1`ѕ 4Fo<{e~B93uoh..4_go,uP)ɦד~8S}39F 5m^/,%~ރNg/^TVcUw`>tα3Q kaVenxd׎]UOL[f쳲gLirfЬ%+q]P &xw=ʇzᔋG-I?yd'\q4e1N\''Ic9*H.( a?ƴHgʌ/{,}2W_tHX>/:p$k-yG_y-SH&SVB>d@ gq/d 1_@vhg݃էsM9()9^۴|7j+]'umax(HHX^rye CP׊rnM6.ߵe(gTM:δvQuJV^AOSG±`5z~Βq[neyDh/v,]gN PaF=rxdC®y=Z\^v4|Szo^1>Ud=ptMѼ_i;=K`/]_^֏MZxSyF9kT8WV9# =3͞~I7[`$ŒhG7+Ya}0'fzHH238{0#F;h:|sgxX/cs#K͏&MCsCm~mM3!zد,O7gvrJ#2.{J9gcn{ ^~N!o1 Û}'~F\an}M9-cx\ yȼB%xɇw4]N=fΔn8[rSrjZx-,W~Wgf,'AO _Dk9F9SfC&Ze lk-+`$ VkaU`9;c6_?eGM$9sÿQq29{8,1pۘ}2ii` FL~ .k)IfE٣Cl[#Sz IDATxX8]9W'#8yosRE2pZuJvRx=ۿl,3NBZLpF"h1||1hJ31B$+-]Ѩ8^kqIuB5#eЧ`*$.L%\dg!֋%Z8Sf+3KNH]ņ4ɋ*g=+ q&AR4`PZ4*sz6n5xas=g3y4 Ynx~wgguE}N6~3vFʻv+E (6qܓ yCr yk^XJ9Qbp`z>=n1ܷ3QQכRuю2l֔&mQ]3irZCǪ-+Oew#UY,5+?9Kv7[/Ց+ǩl|Cçc߾UZǕu Ҽ@V4tM4g;N*LHR{? };_BPNcWuʝ6CM{gA{FwY.oo"ݣU{Tt1Z6Azk/K`/u\11N&Gwҳ;L%\^psp4O6uxFg:t8Qa#{w,%虡lt5&~y+g6Ep9Rf'p96|뭓˯|'1wy F|a|/> X $b!?,xԁ'h&osVȊ0uV5y .G3v6ukvEO>hx1Tu&Q?[+1_ >lVa7b~V.R+N! WvX!)?ez3@;6>sђӎcONg˟[4؏#Nf&E}>hF-p@'@FhcFB^S9B !HBtQ?E4m2!JOdۢ;AY66`xp>젙/<:.{)xFӃܯCWm h4[bGd&W:y/Wn#H}cr9*ڸݩ+ysA,)ݱCkz}<_kɓ3nmj;=m ^{ %^ 0ϛ:_Ŏ4}~NyFo9ºaMf괎4&avӇ?|Hc\9`N;8(n} w!.眴5X Gg)Y?{*P?<#+g=V0OA*3TqS?dw9KCذɝmʁ/7o5-W)Grg_ Faԉ 0viJg;=ab0Q!| XgD~lIpYr_dFx̸#$遥Rt#ǠGrpߚ` qݞ+Ryo ֨wʓ@ \NȂdJh3‰iN 't/v/\@`.~Eb2ˑE0{ 89Cz9:QtNfpi4sNFHֳp.絼Z"r~#ņg\d=&_/ҡC)0 ´"]Ϧ~vsutʳ%8䝁r.Z.H\ LpJֱoІ7E^|o׳r^{9$:A nQ|xy<Q,}L2ql -S.ᛀg?˾hzpGwznuNWx*~ȹw|ux9`O\6x[תՁop]DžV6A&)v\d2. .Nݬtܢ3rI6 v9Ǵd=%BJCFv=J_{ %^{ $p)b#r|2a#iTc @;a")?:#nډf`^7͹Q\nw1}w]v#}d-{j|sGϋ͢Q`9-]˱_خ}6^lQ}O@8 pC1gӽ/аF38hȽfC]ow!`hny}Ȟlf xg66}V#gH9lr9ة WmJ[" g8Oy { zj9hp,|[}LؙI(;ܔyF.忰N,cӑwϩ[3 \>Eei"оGO|MDtE,~8}F?˳b$qit\9L'`/KQI9 8Žn_"-w<zTC"F' $o&<[kgn왡ߌK'"72c>n8U:N;(Ȣ|ڡbr[jsɂq A6JTs}h$J](irc^󗯯{EQĔNpVc\ΆFQ9p}Ηy;=+0Bվ3Lf#ž+;m o@/bdu#G3 볞!}f(L\r~>&eX2QGe"4 ~˶K`/x/HvewaA@} q0Ix#o:} .#Qhsd4gϿp87ǜ_ve[ EϷU0$~6 ku$ u HHC}c6ݦЬBE|`9Ty[p#8 f̔I0N_qqw-h>i-f,x)f}>ދ6ol\fyCjou9e@)ç#;D 5@u~lz5Fm0>GFl-?Œ09]Sw#E-9#8W:Κz>-'Qn6Q{t߅,G \mK;e"el D(һ-7T @#u&RcgN#+"K6.dkиM,!@AГ<]-/,9@J8Hj4s_ll#D˚Q[)]>mF |;o!m5z2z&jlr5\3.k=0/~'cu1`KTTuߏbE8<|ralo)]єvf8 ZO;s$T!Jm*ݷFtu=kZ{ܯ.m 5K^^ aG}djxԋY*BA;X0!%=o^@r[ʫ:[K-79x]OB䩩+67?M;>?x/5?uS5#aUi|rr3̩W\:B>9Xv+e"XOW$?}G-=YCiP5pȤ}QFf%FK\a6ҵ-m{'NV0zw@堉fq9 XSpth2zZx r6CM\&[ܒ`vNz6Ύ! ,ؾPK`/x/H@oh -8GF(9s{iz; g+/7!|q@Z+i-#7k(/L|Գ_85xljSscTLpc4&I  pC=R~|ػ,{&-.(9{H@f3tٟ5Y GaÁ.i!?/n~|Z 32޸f-!q޳$|fF=lC͇UI`%vrv H95D 1 /DI}N|?ϳ벟SAݚ9Qδ~ x'd'Zʀq.2k⹍'۝:]rbQNqFH)^*yDnNA*%-zx9A`cwND/qxsv'@(\9\OYK(VMi5Nث;6L WN9gQbgIf`o,Ћf'D6nsdkzLU 7-w^0'Z_l/8!<.(wc;Ic"=(]#Jb"Y=a5]8a9J0sz'bv׷{RPمO~N(#KA{4nq 8m B)_%v zd[Jr&ůQ -ytqܫ&O`{(k[iC&a gPB |$xuYHVJO~ Yg@yV/RBWQѰ/S!zvz6j0gʰ{囹1#V;ʣdoDغq.+/~]^u4 4(1{uy8zH$Jw^$$i3:M 7=s^CfhzctCn5}Fov2.ɿf^&"-p6Tc(XZnE^SBKWX \w{x1._ܸ>.2VV (YAad0%^{ %ޑ>hFWӝaiH~6z};g5Mϡ{ofY:P?o4 ""ǁnwrՖXmwڅͿ/>#Ĝ_i8G_;O}hCu'v'*nW^3s~f|0ѹMM8[ ޚ'{! swN-L0k$#̀{KFNB|VgsL|wFv5+p#bڿcOr^0Ϸ^|nfrbQι쀸 '4)S˂qԒ i?*a~*·3aqb}>d8AwQ[cY6)ݥF͂P(J9sh@l]t(x\kýZf$=;Sqklh%ͅf~Hng^'Yֽ׽O֏wdO<oe3ʏ-z|ٺo?^X Zr= &86s> 2Z&(]X~.X€ݒ z7fA$8dX18`Ƹmh8KP6]Af;hԞx̫#?93xy,gE u΍\xP IDAT YqcS˻ }䷊H۵ 0 b*7pgߨJf1S<<1RPjPGh*ƴ*/EڔMvr<ѥ)AL 6cv1 1ƓE5qqFO~3 ~̌+ m Tl.VʾK`/xH4q@ۿחCr9:r霨KLfg{R ,'Rm;i+LeQ /{np-ZpѲ,g6?}Oۮ=ۿ5rZwZ?_E6!,Ks0۷ egl9v]F/7'bgrxmp7GEڟpcm-Q4CՎmxcc?s+YId8Q] rakO|vrCl8Bnk|_'$r8T}ub_iyBAtc sNrrt:ثVh M5g{YpqyTl{vh|8F'8.yl=ft`͕t'DO:šSh%A,V`6L9FDԏ"6sL /]mV7z:((u8\흐<7 =ݎG6mջxN@1-r c ⳯f73e`p.Lj);vAi"' yrƧKf.?W;=Ս 6>Ap_ >I*ĖlB^[4fɑYUxG9>~8Yj PiHIKW_j:zk1Qe!NoZ -ʻGgN;Cʓ9wgnh 8n!ۋpǩT2zzù7(Wv)ǿEL%k*TfALNd7N޴d ]ph r̀Y&`:ILCPʛ,jFsYJʙwE)5eG>xM\[`Ã< -N26Z۷ pV}4K#xk[?ih?rlA,m\dK`/K=$=H1SRF7 CпcFs'9 @֥@quA\G3uINe $'9NtltoŒ\S﻾yAȡp9n/D&L036#3q0r9n;!u30i= h(M%~<9rXsvC7{#SOl^y~4f7UGwxZ^\p|4jنzcpɉݘoܓI+i3v81:$[W6}5B=FS+?8HaP8[e<ӧ9O |FdGXH٩Rrv9RA%,?QpeF]/kt{r&p8Nz)gMSZ6D^|˷|?s; 2$)TANk(V]Mߐ,8[=~ΫpmssϪ,?QR! \n߈`/uySKs&~(L3>[:a׺s(k/l,P^U(meNF n#thxUDV5Cv_tn_1>c|Ԧ)ܒw2yAj'7ꯗvYixf?h>y.N 7us,\O5?U0:2_SX6p]i`oһ?i&Co>WT-zӇz.$gi(2UdzfrS?k/K`/ӷ~" cQx¹nj\Ɯ*s_2ށlS=)n߬g:ΌRƆP^yhc;і-Ʃbc L֫6ѵ^^L,\P $c#gs8|Zζ,`q^(M`e bL$kD-sٛ67ZLf}(#F=̮L$]$ps_A]qRL`3&TN ;l]G甩{kTFL;Ji_el?U. Vh8uY^~H2z[~I;pߴs<6ZٵfbT i*zp?t LyPlhƁKNϽ/Yf']p-I[˪j}x>㝐f$4 Q-֪=+`}xs\##L9a}W޵U h0:v00-whO:q\0k`3 l-S~prj WpSwE>$gi9FҮ}1x[={EYq=kqAOu:8pЄ_(|5QG Uب[#Tл*{}_ɱܣrlUUR'aZppViv+IE' ʿnAz1myBۢhd~&h.JEoe΢\?+) 0l_qvv%"׍뛟u\^"u5v娝nhCɌN_=e>V?U2?Csq[?FCڵAekd:0朂Y9O 苯o|ՙAry2J&4z8cTd`T6@P `T^[DﺣFl㩓$vݚwW;NNO?zwO[árϡڃ|}%MbqɊE,d "w'WQO7| `Ҏ9^yGelts2\@Y3ZWjlDC#9Kq??߿njSqLDŽ,f+HpVG0hgE &h4FpDo:69xݢP Lfc `M&O[geoٯ?:޿=wחA|G+crΨB<@NCL8R {" @eSC$G>N+_͎ư:MW>|9R$X^g*zЯcRW46}ajK9 & _;|5OyOfs kw o.68mϪ土`Mt뗕Onxdn ;g k 9n1A<(%}9dvR'hyo+_uho'[<4,:<@TO ؁Oڊ2iE Ƣ~CكylyPu2T=wF=n%p+[ JV?- pl6'snodMp<;W9VyV}*vf'RsxIsCz'#b+#-G<8ȵ*?ǂ }#oT53?j$~Nj}ey<]}%hTS#m ήyLNL,/PQT;s/΀?. 7K?6~ &\ٟc=*a *r&r67ahsMryA@PY`nwsxbyeiʐOf+qsSںY/8Uq[/m 3.OGKWw[ذU2!+I5Z8s3 j[&$|1;6vi4=x^hLk͏ sa`ٿH8?eGv|67{z;aevO1t=ӛ;5@37")*dAh /ȀlĈ?iFm;E{ m|"q"Ond=|{ c'#!Da*DAg[-υWi:W+pX80{#JGܩc`ŃфT)=*+wڭ IDAT]uO].rP^9'=[F?K= >~NPO{Evh):sȆst<ϾQ9~1A^k\'bmӁ>;n]ߚh?iʑZ C"(ⅆhKu.Mv\ѕ:EO *mG;Nm[xWTS縎qmaaGu&Gõ nuyӔĸz;ݷCqd)7Vx0|^xGsmwd ^2e'Z 1@Fcz#>6 0>Z$!%W?vۿ`D+O8|:Ouѹ>/U@"wm||{wM{C|9Tr+ku7 Jÿ@~{z+[ JVrΙsl/@)#ŭ9^D%YWk&'UlCpLnmE4Pgުltz! Tvp6d (>[a䨰71wy6K sV2og<7id="K~8;;X흓*QN? Am ؁e!8dsϗ9ss 4ltL\/rcjJDYLኊh=eb0lQ->gGNg+ܑ/ghЏ*L,pWzx;s 8sHz[8}tR T`I6 *0Z|6 ]:ʰM>sFB^gϣm:S렅Ė|H@5lxvdN2|*/[CӣOpiv&l-*s >`%lǺdKEjG ~ХP?4]&G&7 U '?%y!|Si"5@Q TE;È8\#Iݻ_{m*-^jza\Fxdˆ\DBjыq ~HߣZݜDi3Zg8lO _\匄q}&ept\#9=JyB$w/sJSyѳ ?*Np(7qk-8֋s5z>5Ұ'Id1[D^`x8A99/4 mp H}=-@YO_^4O ];M:/!oP`]X&&qkϳXjbhcN>±%8X'?Ek\2ht._2b#ֲZ8- # CL:I'tQ;yڽzgtiO?"/ǞAqK~  d6Vn%9c}y4:9yޖ'\g9\]jy)oEwo7蜊Vg?mTzGĽ9rr6q;m79/rT/SaK,@8}m׼ " N`L{_gw\~Bccv^hv]&4?oOB>ltE':ORJ>|~]$aZ1>q/` e8K@&h`q0ɣ]UV_JxۻbŔHB6d.2?&7\HP5e *gG x-չLަmM Dߋ^UKoNpg2k2i!`=<Ȍ,~f8=5馅ٻMը== tY`'0@}xm4yd>{F Lm}YN퐭*SK5%'C1nQ6?mнle~aDWͣ}EXcD:]s߻{t/PFB= d$ u6Ӌ_(A< =50tNn&ݣL|l]K~ݙQ6s` 0r5%|UFABP(<`tiDV!dN`q,L9=l[|ڜӁFG5՝z@>@t>xBȥ: q&z6r8v8#"v}sBh^n:l퍈vdDSԙyq pFۊQeQ$/e϶[2eOl;LV Ǜw?:G݉cn]ya <]th& d'3%3@~ANvMGG\"۱aS 0*n:ٙGςgH4~'H%|+A GEe}kwNAgZ?ඓךZ,8c"S!٪t Џenah mar)Eg'@έ`v /uxfvwͬ ~0wd*GÂ$sykܧm@đ#BG ̃MGG 8QCh_S9e~sF27ǞĹ\CuM1* _ݪQ׈/_GN3K`CqǖcKoQܜ3ފ.5$(GHz^񾄋^f+9~;g?g.xH.G跠u?j ٛANP5tO(;ޏFuH}9"[ת{8I'ϞXkB'픠ܜΏl"+~flweVܹ5y_@yS|~0؎2 t3[@Vk#nto&~{/_᭴}ܼvZܐ3MklAÜZdlcveSTmxè>9л/ZPE$'MxSvo~7M:T |Ms@7@ǔ]6 k uO^6JZ`#:|~xQB< Y1z7<>>NЧ-n! ܵ uªZlNl QVteX}}Ӳo>$,1_*.g׀M Rgl~oHeRF+5Ό1@2&خqᄟQĿ%I`"a<ǘ6IRS{xoR1s `8<:as~ 5[X33!bY8\ O,ҍJS e䔱ć=99P6UBC?тv'S24塬!N>gQ۹ϫ9 gw-RdZWy[ʸk2E`A_y,cx/dV:! o4!{}vc`m݊HxB=ypzuVѳpm<#q;$/zNMNl5'?+OMa?>tz s %I*ý kyCjtC-sCC;w ʅJ9zӣj{…xHfezke$\ B%F/Z{a0msׇR.=5b7n%p+[ $`4ob ?ycFq>vn@Ck(Wn93_řls^ e/0X{>Xgp?Αs9_=3k݆,sf3.Muz4e|l{W7/qY[~N7]^ijI@z,h* ]C>HAQm4p'GxbӚx Uk٭gp|^[l:kiIzt[92MC ,+_:C  #AF'/ tfA1Me}0xC( ~hGxSr:҈uas^ ɴbъ $ s`sP hL׵Oۯ]D5/&S#Gc>9=ra J C+vX"FՑ9# w|| BkS /~a,Iʩ c֫&wG9K=zf@^3ՍoͿ9#;m]%ȃi8=r~,"aL/Dfo|`Nytsfolz[>؂"x2.]36¨VTۢs1/li_ t8Hl;q%V<9#m_ǎ%hf>\̘yg5ȲvHl4Y}e oGQ O9 (8kΗz#ydB_f!5`zugU= V]z]Rm /[#[ς^ٜӁpt(F1s~PrT49MkT*qs|Alt!0NRF5zSߣ-a]ut&pv夋w/q^8Em'}:NRo:.v6T~/n_ە'?SCO{5wZ@ֳ:Sk}S.t.}>5OGm1Ѭj;C:^#_Sw͙$d= etdm9;h4=E$}I!9$@}sD>#.^G/uFViND=9iB_!~;|A-FеxT-~H'А#d1ܵN?Y໦l[vz _)PY]$G_`5wrWZ6q&e1@4|G{ y(R;`ե>؀C^jVn%h>uk1{m$<ωb 1~:jFFeVs;oNy>d93'(khe/{#6W.xsl z:'?*:_|ʜFa9h< ?6R2av\W}2:gn@T ωEhn#ۜZ eK|jo[v,{O9ȫ9FYS0 3ɱsƕA{Ƚ67[+`L|bL; | Etcup 7M$>`SM-omܵ*[{vbZt$)3E& 0L :ӿlFY$s-'h)C􇦌^@HI&1?bx5^ V_D,glb9Ǭ 1횇oeTvu-?NNS;V]I=@SOp]1DIg2rҫKvm98W]Fυs.1GubͫCۦ EEw7I1EGlAx$_/~Bqzh,T-hq&km窠{X IDATJpRKÙW3:##["?0.=YSv/8_ip/`β2ږUɿS/_8C Me}k5ć]F8R1O0sc>]^|u}EG * Oz;r ]|A{;<[ `)> {2&//4,cR@ ='|d`urSyaz~|gVCE{[ JVOIl9;Okd:;ػa'6T]z՜/[Pb#c Ɯpz#|>Xϟgz[9h kߕ|p/[ml5Kz.)<61Iΐ@F"SMV(! ܽ]78 A'Q{ѳX_CaW!S=iFh1'߾:[2}('o ptڷFy])5_|͆1n,K6eCھ}ly{٨Bwy0G񞌐 $_kh#c2oyg?M.c8s.m2Nl u}2 7Y]W= g@^|J˩wHɂ,g"RDcvCcwAB~t܍Wv)u|$l>| <A8*9';6!ߚ76xZ{঩\ 2ch"t٧\$Jid7-ho[+A jFw^0dkz=aT nr5?rg̗ wLEpۡ#Q2't H0iq4l>t0Ǡ; M rp5t,uik`g8Ãus_#>1Nu|G;? *N?KN&}W,_m9=JѶ辎lzjdrAIөߜNtC8[ t?4\_u4O+EGr]\$pVvz.ٹ9~w>FX'aWY5WH>="fTp+MP.r\҈v/g̜D[pv/V?t+Ⱥ#7G׹_8a223uųiۿn%p+fczhu1{DVs9&cǜνgq2|@ONP̉~۠}ܨ02XjpꇪQܛ^TjcSވ K{؟`hxzv]<8nal͂~hdx\*lV#"P`9VOěC9g7IT;f3}dgB.C,8:7oQ֌E5}Yf̀%^uچQiFWn"sS8'P۞ dtBږ,7,2}Leo&d{ɨUdYtmɟ[ "\d_%7mm:gAG':`GwwkU_{[fB> =N[lo[ǭV]R wTteÜuRg V}tdDGJҟ .͉L$X = Hx[U>hAI,.+;oZ )x:TϾuwZ5'8,G8 B('G$ Ov?ipC٨g,IUo8GN8=؜ALZ9sh[o{Rp'J]cYѕ\zBwm*L+YpmMΑj *::ՓLFkF}m)1ܞ7<|xm(-ڴɨ6HGoP#Ӏ}!~ODQ-=QkxXmGN;NM?;!\o4;΅ЉNݫlOe"wyLm@N:i] ?zcu*}C"sGF_:^`^lgMË:'۵ Gu؞ h #2Q7HI# \c`nJV~2ѳxwNYAyy[b p&-w2L9|׍Пj֭0H4Z>rmwhF'FjcCN[^FO=FsuZҏ79Z8M8( ?`9FsiM{[k=h"7'=M9)ixyrzuggv 7ϟ7%O9XF)ߥC;irP7cZ"F3|Ƀ1x-c vC9Ϋ4l5X+Ub#ACwBg}ҋ`}E[-7/^4.hG2Ǘ"-!;3)"p7_Lsiq9O2"A7>VJ}ǥ槫9Ax"7~Mx6X,>Lh'5^lla5yi9zD?ݼh{ڣC3=A?mq 6t_yWۿx׷;w/$pZ=[{Ȧ\("R5>zDZ器^c _!d~4>S$ \J^ _`+xB@ 8|WGd#o q^ w=!ktssŁ_HUZ;m:/rӈp/ŷLkܞSpVz 2)Ƿ56UXЉ̅Nx.(i9&ou`&xs:(0bAtn 3 hgb&Ce\=z.K櫃KƔ:6{z_'vKM 2 FGUFKƑm4'w5j meU?U':0Xpa}APӎPAYl;=tc-O N__VMvu0m:3Vo3kެNߜn9؏{=8ON0 hh1AoFDTmrsF׌[L}A x<_AG@DehGfp#HsΕ~|ՀSwкTW[u Px+ |q+ ;蓁&ٌшs g& Ƙ) ܅Za?8yZG''k D >ѰM8ؑhg]Ʌl@ -}skuf &rmCdu<+|X`rYE7A 6ukWmW"㣽ۚuwV?"@8曶"$sb݃2Nœŋ?Աh<p{hM%+[BXt8OveC [=d[2a@tS6+d`$7^Ĩ]gX}v+{[: }mLK m/ƫUߟꬍk5b?Í^p=7UNT ]88':L^@kۂy OUSXZA:ݲ6j=ohGKRW2F;Tdt' %xӎ n+ ݂ZIG vZco_$I B}GIxtW}/m8Bg7mG=OB\y ]$ǭn%p+[ J'$s6doİwqӼ9~~F μndl!WG.+{bD}w8}^Vq#hf庽E,|l/I(%| E ; >_=|{ { Gph Zr9sX`rלl8n,yܣ9y\_7\ 5/vFG[o3M [}| [gkޚc܅˼cA~ }aϿvOF78dc -zgo^?6` ?6s`CBNhydJNe+9b)]w͍. "0 ~g!# ;H(d@cd ~:j5FbtjNsOp$F8n=0 \ -Ջ(y!2e Lm]dF`+m輀u C&ʟ(qOsFR<DE<(Cy.7xtrXѫ>`tR@ 団F"}Fuߗ%?TU(38:'0ths)WmI6/|8w$~$u(9"Er Vb;p.lA[J9ǟ8kO՝wM,!Mֱ&';Nhׂ#M8 dEZaІ~Pec}Mk$}-~`P R&X gfmK08s 4*keJlKm?H҉] hL+ӧR.GmO .+<:ɉ|n%p+lK6G䤡3)JO#{Avo?]SQ[͡#$Wr#q7ź!1`(02xǻUs3 +kR`,#Ώqá 7>;;Bzsn4&x$+4 we5,ij<&TQg{kOAKڿ:.\:f#ˁ-e -[N R^@ܠ&JˈcWmx'd_`{v~0wfux{zӍW֏(2W9Tcpq~wh2 ),>} Xv~<}􀳮@4!qdJ:x]aّ3[3[wE=}3vl?} lmy_ W0maK~ ӫOY̕`o`\QKk.[&Ǧhh;[Wl_⋵7>I&7дe 7}]e5;W}?2 FvAB apC޾BQ}NVA$TB~1`8<1;6un 4m~u~^֢Rѽuw7[¶wF!'g9cOQȵ*g;e3^c{M!蒇UҮs:u -B⊔-P+O-+a.8w~*ꘞ\2T`R}׭`䟾] hDŽDjJWCbX>!(&/ǹk3NhGCr^F3"d{gFW v_ 8ލ}޵z7?zG`LO0ӻM paߨ3g9^2 (}N\8ךtm2j)5.> #|nGG *'AvSJ-ߑȧ?}'8ïgd/\OysmȶR׏|qr])v<h79 Rji~?Py]?f/ 赍2M7=Ry؀Qc: O8e=o4W&W_nghaOc΢I 9gS_[YP._{v"/ ȏ A`o+| clH ^NNpl{eΧ!PlJ:AsALh ?aloU9^bOd #.Y| >:cde :/5> +3{?8 "<>Ԙ>54s}羭ҴXI 84eKq}{J2k#]+ñ|90釆 l_h^>]ӡ4Qz(F_m FF=2%>V!s>4b7S#GG5 du::ANk0INN׭:?%ypj#Tow9~Wu!u s:S0&#[% iѕ& 0GHIµ@JHaD#Jyɇ}&տc[q$[|MɀlQ^*΀NϚNa@|2܍oo E`Fhp {/0u ~7m19_x: ޜC|C @([᭟.Xsh^hg; \ŚgEK@y7ꟶ!OKbȮӏKZּX6g:`dVN IDATn%Ϝ`#56#+]z3J18_ޗFo/Nٟf2v,eߜn֜k7߾lj?˜hG'2ȣS3bhS `oĿ+0=Sn' gO93g=|dU1t>N >8Qr3Ά L׍e?8힠XrfpNL\ R@-}U~T9i|v=ꁅ\'[hمF?z̛p0G $ *|_d+e%vkd[4{ <)ګ ƛdWt0[SuGd1f}k٧P+kȸFo}j}dώLvϟ?Y``9=p?| aY16~goJPNvӂMkЇdG2]FuUB =5|ˆ@U_jF3VO9LʂZGp{$C~GDɮ Pϩ?i5hg)zx/V9FR5 /U]4QPi) f$Fc'EP?%g&<)ʮt%M8Ld0`Vx%LT:~~^j?~j0RdՋ#z|Šhqu VGwu:Ȧh0DDJt&m/sbί( yVG_ncsqBxdvx!;i8ӎo4-Z7a>)|Q^v{ܿiMRj (^sjK+,ls3_{񱇩 U\qU:YG~LtK;$#2GGUVa\_jNZ;;&) l?A|x4m?e=4)g%R4 S_ew/Õ{,GcGJ^pGMn%p+8s{7ao6*[%T?sY<{xN 1٫|] N-+l6^?ȧz |p9=޷9t;p] f4zNFVFe>F 9?A/Zz ›`룉n̋>x?8G9Ovd v׳{Dzɟ;+r**R[l_ǎe'f7{/EpB.l~ޮ|@*_vڟ)l'9''̑UwE<;8o#tn2-XF .&7~hup\[Ex[}2lQ R\_ބ%v'}u/anEH_i QQyQppP㨀w@:ѷyWɳ:IL6cr{FF9r)(Y_zZqlMѡ.r_"N0RhȾӟ<+q҉ʬ]3^K0[@:;~u#ϙ>^ Áns/=|d (c yNu[q|glK;᳟w굝'N/@KW6~>v[o18x8G/V?\ HP>p}ێ\\:xҮ9Ӻ%/ŃozyiTu/Wr2!c -[g}]ڵ 9k \{U@= |{dD7j;:+wT~[W_"T[mzA$VE<>o j<0FG&̹Z. L~ e)&SedKR/~ sDwvcQ#c,0(fV oe'hp+h:mDx$mv~Φ];Y֊p$s<8_ ͙n)^6``t*/pC@xp\?21SETqZ?liT/x'жdrnzih"z$:x*]4*ۅgeY VqdM2d 6'~E^Ч;~Q`O2c8:tOٓGqЛK+:lIW7A Vp^=&syԪV[?n%p+"ee@I7:Wp#jiȽ۫ކ{bΡu| 0n]p0'b޹ݓοL{έ4L*r7;[T`0>@.?'|`oߪ?[/ >_`C"g6!`l˸O?HUO6wxǛ߷Ea8 $e/~Y#dLHFʑ~Fʳ-#j8;_s%sC?xPąͿq1F{8G1#9Ok/wzs"db\\L!du;gG|L&u5xSF̹E~>tEocpBq`'>唳p]CF8Gʒ«~Z"^?\'7%1~ɦaO^}ңX-"֎*K MՍn2 iNN o}U/2R6s5_,q+[ JVI msR{WF37BzV=UAm7Aq 6]9Gq_(uđr<BՍh#mWϛ>?Lx<9_鷆@Fzd$Ty5ʙMT_~y'mȳi' <*0 ۅm"g=d9fn-'7 gy]LFdt\@l]ɎcmlBLDo;΍`؂W&x_jr`ۏ|ct$xv N^̑lC -Ѷ/m`7>OKeAyJIm+T-N o6/gDߚN"ùuۥsz]#A=?g*!{8-h0 wu5`DZ@e;nNM?\R9A+7ޱc\# z qzp%v)ӵ UY$6/H$(w~t%uuoOCH^zd8^e]!`P}RZ4c AnS#))׃y+ Rr)B)j]J 7btMXjZD#mFT5&pֶfJ텗]F/SVR)]x[B-'5sn%p+[ 4$oe^Rѭi^sssKFPV߾l6W]b<0baQ>+xX>2;L@FXyV0--CLos栜Qyv !x]?sK6;:y19˺c4>Y.7JU|㑽QlyB :h۞.;d -§NeptqFjW+<M⋳4nE0ރvh۶ܳU4Mzm ezG6\c<@},я7m"c"xtp~Dbrvm>&k?:@׏*@>(6H?N pL11QΏ9uGNk!Ơ@:ʝum5h~_4 ~rG!8uo;pmABX?S:ϧڣ`;*e7 #$җ3J/HyߍB4ma-"I-PTVpd `DX v =W_sbkG>I;EP96¬A^4A-g8e? C@uX9,I EKCI.r:8&?ޥ s{={JZE)ڞA"gȈO/eH;T R:OЮ b(S廥l0Ce9Kw}2p$\{X]SNNFM7ֿ"ῧNY77#(_Cΰ9I`v\9* =O p~Ԗ])*V B F0e?D+*;js\*+pqWd5NiOs|BNp]24> Z*@әZNkd@p35kPH}o}͍<]{z}]L)qVn%S4{eO/nA;src @dàF ͹wLW΁_w/p| .qOJ^ol$vΙ;g?m^}h1>& sI?n- 7_f1g"-ID^j7J#d`B/㥻lk$q m54p޼u2Qjl>xNrdp:r&U+3-`OKEQyAOyX]sbh ,R I$. 4C#9{w- K0cw>q;=#W"7pV]l@s яYGRm=jmkY iCVto?[o:, o'z?)O~`_`Sv 2Ǣɥ5L&{޷i|g__umY"VX}Xɟ+mG Ng#Wo=L,@ z ZeO%I4M%̬D7 %f*3#3|bYsݎ&,,tL_[h?/ˉ7-,Y-t `(fpL0w0(Q(f qz5(U'T\Wqk >bqhz[]:}c_V?+>Z4'0P&^+v4q([ul7K(oM$=fmq)glT]J>js;R-~?YB(uݤ`\~0/&s׿z8Sx.(v-򖜁L"RüxmGJ'_E*10IZA x{Jї 2pxy-39a3f=k;EF)tQ+KR`hj͝q0}/Cw ?6y2_} t~L]8{TGQv8p78MZy>ؓ0=ς8{qJ3{q8!yNlz}|l~9&~fJ._.ο4gf\*&-|pU\h Lէ5#pA*4RY@RHdvfʄyϡӥe5DN0^۷z޾шA[eMWg0ЄM3u?bI6T_oe瞉Gw6XʂWĞ/8];vqҟq!S2?7A_t?Gk׉Geޗׄϯ: &g6k…0/q`_u#NEx̅xj1ﭝ/WJ+: zyvͧz5Ű]fL|NÍ2'εYk8n[S~ ?aviݬmhe& U%][G~﵃裡6l/.k¶pX6 O-#"#}hLY-F/ryG/ :dz2.:0\Q'8k[i d/Xx黿s:+{ 9^hrBC4o3K?tom=R1Yѥ5@8MHڢhp|w_Am'~ XQ?ЈgN"~ [S!h ɁyzzHLX^1z^ʱ2M&{>4قkU@}zTqƁnqasr=ҖUCm3tmtN=ð[6f V?zog~vPYqsWƶ ݫ^-e9tf@96ss7g:f+?NC[ |a=; 63@y%\u! ;'}k^Mo<MN5g}ׯ?"ò4{]aG`\+\Qגh&w㻰v-8+o^I#e¢r)TpC[[6ItA{o[R`*f:u,Wr*(@}Oz/z%W:O;GqZ TnuJ~,e _uʗו=ݵAoZ@AK5lpypfbbo&ֽeg*jupן&Y{R2yv݋,xRfVb2M#'G<}}-wlB`Ƒ-чds;!74"q>fvA(O.oQ.X4,+Eifm^RXۏ?69rk zC>pݷ#8So4S yjeલ(S.?|iٌEzua)U|5 }+<1&FX5tx,{Z6o§wg!ns|\O!ةߺrM*7^U.@:*'=[-8uMp5ukp" ßY'._:{{:9r3{azwp:uop=:yF{t,L{f t?S5EoxԲ^S"%x6CnIk{2pv6r/:KW'_?/O~$M(Im5&F}p_v}bQ5P_q \t~ld(8:yV/|D6\=92f-ߗ.~G6D+mx;/>Jw8J ϫQQݝv{6Ce>BЅ\l ZϏq'eu.(!elkl^.wgW+)1MDSoN @SFlw#{85L0H>RսzxC޶]ٗ^F7=6>2dw+9ُ)Epdw꧟gz4 (=fwCz|~m~vD5>=?)U哖%+WPx% 2v=x__{ZH>}&$`5AꏬElظ]7\sCto8~^q[&¾\g~2ZuvEl5^p_As_SQsP<)`a!ZH T ;~.}ڪўmx?.E?Y@0(X\4=t mftPk)j|^JO־s*SmuݗUvY6'R\0h{pAѾ#6M~CR9] 'mG ԁOHYm :2]Z_;ؗ\Lf/Ee$%g2*74 ‚P`_Nl?2'?}_}de|^Tn7uw];.?:mwtS~k娀B OzT+ ïB?o7onqƁnpw]NG' |4NdOaޣye(G)8k8:Ǯ֮wMុ9X=-pqv_6:'fvlVnv~^(?٤9;񜪜l>f2jG6O]g=pLᜍ7ex.umʱ}Ol8g6;Qv~k5ljB+"+̉[ X >x[uA @t¹:~QZ4}<^]gN \t9=eQ|Af-hhguMϿ>x˙fL^3Kf'&'4Gv?D g>tGavd둞_uڷcR:OdwPS`w %~Osk:v0-dDk|_l9ub&V?Ɋ=}-A+ 5lN)@_37g<{vi}B:ML >eRġ͍]Ygv %~>e嫁%# Sa$QMC6c8f"Fjp08GNd}|< R<#$wL8ՙѷ(MNaҺ>7ѰYE vm>~\tSj\~aǾOAޤ>AщѰs2bFMgZ똫g hnkݛu xdmMxM}:M?<{xuӃ#\#hPccQ/i!zIنFO+0γ۬@G2w3dyzЪ]tA_5r T5Y*g{tE$n˓&=>cШN|߃6GxF uȕh;>~8kmէyS'z^r%u̇7-7‘Q/Tk,Za7p9{sK.SùJpa'7o-iHV>у~C&0)_ە!G؇8ҋ7g}dt 7\3( 鸮ٟMʜMI)E2H.YɂOKwlp\`t6d3V09d}.UдW7~9J~MoxŮ ^p`N/xiǓ|#޷5ț9`>[ln_(tj:Ix[} fNo?obG- 5h0@p#{s7{|WxFO}q¿:xvâ`L~z2+s&' v#e6ikˇ99s)c (j׆8MҜ= 0X~Cωx;c}67 P,׉R#ȵ5҈X]ߎGh}8ikxWT}]UM`8G+ۮݵΜ/G,xQ+~I|u&;J~YtJtfHg8`Ƈ: &BƩ|XG{\K>I^a tC6t 5 (YS;`O>Z.r^8ߜXUJ`}9G_L%G ^t`wڛ nZ'= VGc׃A.%<;;_qHйlNp0xA xv/ pڃqk_7\ãg-H`E]$2;*Ce]Ɔ徍KX}gz%lu6F'KyA:tp| qƁnqwΑ홙C!3ʡLylĊ-cs3K~|q̜]3gͰ>~Un^]9wC̄Ͽ_٥ѳA$GLmYѸ] 99zr𬼙{ 7 '"ݠ{;}K+voN|Vxsfשּ~ȹ'u8;|S$ߛ;8; 92 B̀ǟVvlg{7k ~hLx^Y6[F^xTLPz$u(_?ZȼJϢ/g?_W'R/x׷x$xЭ8Пt)--O9|)>Va5٘=ysOr<ë7{xboO kl>F-;w$hRRZfG}ܽQp38g+GP5OካO݋}R6 .Deq?#v_oe]0i2kNWh[ۘ:ӗH:[uӕ?tmxiO-sG)֣#[@<{SE8LTvoVf]k⫫:|\ʇg_4/Œt+Nu7Z{C~ȶ{9K8𕂇\jxW8tiJNWb:Ix wUc-;nsFmӘGA5eI]W|XNw5z^]b@"؃}8/z#96tT?բz e9A:5#84ZGڨ1C{F9p;_ڸ A2{`4(xU}W:+y'hk*BoO@GFCE-ݎnqƁ~gtؚ}wQ]Nn3=[w߳3=&[ 5any~xUsffYFKY:G=:m/l99=mqq8ߛYֳ>"Y fp:7 jK.tNT5ʹ#:g3ѽ8:1{Ξ2lke$xkL@DN:GvA9Tku g)Y t-Ⱦ87&ɂ¡WֽlϥԳc܀- P_guDl+x_gt ; \3[65^FMx?!OSwpʸXxr^o8[p worr>#A!xNf-\2l=];vx^tV-v2g[1;c;V# ym5!̖6FN76I<{"7Nr 9=6;BX:}3Zmrڞ}u.YsMAYy/gj裻 D(c'y ,j)9Gn1C{X_GK #ĤktK }hqCz fSn7t̡<83\ )^U!]t^ /KJwoGJav\3؃:E7^ًV|xR ʯ;t-F<`<БoɁr[CdF%挛IkfI;q޷#JG?\*Ty

7H1: :Ew:o<%@^{9J/},{4Qdpr{sYh(28 sk(wLv$Gd3lYXpl8`UZu*O ax]y֮z㭯p}T-() t?87LⱾY-"۲Y:~}xt@̽`ЃiCIoW:78p7>8p>#i s3oՃng sF^q+Yʜ6R >'ҥ[&y{s0>viVqxͲ^mT!q!>8,8ÝEYsROyo7 :,>c3?]C7-hMK,Q\9߼xҮ-՞,w7GS$Ng.!;lر d CXJ8et-Zv4ioʞyK5Ҷ'mіX"upd6F51W#:G?pVh.Q_&{5I\lmvtcwg`,s&~T4<ٌq 8cpH3#הClʪq][A&1"KVz[ E98T^l氊90Յh/<{ca2K}Gׂp\б<ꯈcUN.pIi '9]?ɡroMJi ^2҂zƈp]vNXsܠ*Bq,}J/)ވ Qx+luۉ Q=|+ 82 v'#W,p{ $z2FNSrƊ^DW# y\muazd0/YU[!g\<"ϢW: {Jnφ Au'HFP~2$<ԆkZRdGwwй*FK 0\&] *oMW4 }ًqƁnqÁ={=۷csx{62 8Rl?۩5}o>x2Gԙc\%SiLkZ mg=??+rTҵ#{=sg"_uaMlpf\c 0l7Cձ`!ߵ^r+ Fsփ)=\!,vnC bxkg'|89Q }ܒ u:e#thKaxYMD}>. ſs^.}vdM$ymT6^NWm?N9bN5rKf+J*/+M)8OZ#,p9FGRO-Ck=kdկP__ h9?|I -=a''qR _ɹdY;޶2>A畡&Ѻ~t%{Ŝ[{]\.8@1=VWޱ;_>NCxEgL)ePH1:82x#}cXڭu叶Vts=/ElMлqԥJ ͎otKy8 )`#{6캾B PLΠDFޯI9{ƁnqƁws=ߤs8=wwڹ;äm(g|9߯r 9Bgf N1<' :svgT9ߴi猑?3*e(l7|Cx%GSRǭgsrte V{rff;=93v?= "ʬ? JTZ;o=d$ZoU*̉P1Iw/Rfk,|ՉGxYK?x5nc%6?x6ґD6:{'X;G8??Z?1=M6Ms42?)>':)^, jђK7j7_~6G d >[}R0vrrqӃ~>.]6 rA A^_v&]{7oYpl9J8-&L LpG?2w[)~w9v/#]4` q\%u'@sT2ʰI=8M NMDq՛8XλR t)Ŝ_;gԧ'l7,Q'3EyyV6\CڞgկC ]kkJ" ;B|<6(''uP;"3RSRXՏz'}l.S^ v9Ə.TsL9^\~38Y糦Y 1'ӟ<˱=FL@Tlo+׽g_WPX '6 qAzx%4M҅GPrpڬΎ LJ^vXnz4t% i"2.]=jgECD7T~u |jKŇCOG>*CՀtL/ h ¥,3o1`:!8lIFp;468lu[#6=x:^bݻG-`LoS}nǍ78pܙdf,=˳1or9ȃK=K[D9i97;trw@;5v =Sߴ}`)Py]`{ql84Udޛڷgs,W}4goTjm" :؏?[_@3vxqrgeq}Mɰ;^RդBs3O^$/~qbH̦9Ѳ kSDL#4.K߿W|N}ʱUtp|_ u`S& 75,ww[o|*o޿FD'NG||Gp:,[_5Ɯ!7ۍy8v},~/b51½]Ϟ'zLJRPþڡ7AΦh2ZlE^M~*e0ѠoMw"o5g,/^}W&[FY]A%>Z.t3'1.$9Bm7Kk63BxʙkH]Q Lqs(?kp;|T&K)% ͢L;9yQ{q|9a^M os}f[m̄g 0ڠ.ɌQn78;7Iw9 ~2'wNN zuZf<L>لfg)gDthw<RֲBsjudeu 8jtt]A{+'/EבC;~Mk'pJz.||t YO>[ѝk[J'Gν?bÒv Tp+V􏨦 C8' pG5 V]id3urx7 G8_G+~6HVd~CZxl Ѷr'}z4zPng<{_ۡq78pvRw]Mvφʼn͉}Y 1ylcSknVX0N6c'6`N9w/=_Vϭ,afO,gOrLiSӭgpFg4hKlC~myWvNnM{o3X[nA͡ mynƓ&L2#bv)7~/?XZ62[R?}D[㭙suƙcfevn3=Nf.iwơm30R˷a-R׻a^w{+9U ٳ$cS׬q?mtŁ6.'Ll XYfz&KcAtql >'^A] =~?|~m{*3=`PJ~bGgҦ R[&q2a˛|{UtL~e ~'c0*SLRYݒ(R%]g/Y2Ep+85@`ǞxO[V@CsYL%OhT:D㛲 (/k:fS ~δ\ϩAɳcu;Ǩr@m&t8YKA@qrn:Cc,0 ZU,_re2S/GF zfMG!q)8.NºM+<<(G`wt'8 rQh:W4EB/B`vuX7%~)ZixdGq!9y_+HOa֚`ݮoM7 7L]\up!QbMΝW^VL)C]I>h <_zyWf 8s.EuM͆D@OFֹ7V\D,]/i:+Yp$~0oTp@7 7r {plgiC_e5'}ȀvL*~N)I4j 2 6`~kwhnmwG{peU}.?oǍ78p3|nY=2 &ԫ8S{>WI ='~3f%JcGYf AyvnG?rr (G^l=+ɝbYks~=F5L& \n@ ա/Ƞ ˢ6ي[G$;(z8p'Hq쑗CX5 Kg?hǜofڑ?G 7o-ScQ 3xxMe+xe=Yg|&_7[{ fZ_1at/~eqm [Jq6K*8Vs:FU}V.>ċM^z2Gh*w<5kd, 2w퀣KqƁnqwÁ?=acLYpFE쑳Y#;ӵ޳a+U9вN^pmxiKG ]u^P7]a;mÌyc8t[kW'N[0<ٮ28 Dǫ y=`9W @$i7gP{;;66|(<ܢ}mY뎿ޢ`f{K(JDқ>lwƯ3~N-;fOڏ-*FU]jaIij&yt+${c}2:8}N [2٬n/.GWA-f Scz ޗctŗxk>WlH vo~i6H!q٬%i1f&|8!o/b|U ghǜ`nmfY"%Ю6ͪ"\,9Z@E9g2GgP"Hfr*0jkN+?.,7;2舦sxSPQ5^ZK֌ qA@h>}M)' h/˃He@[z_z9Б gJI1+Q۟nqƁ~' fwG~>=z~i J̬ї~2c>+08spxipCw*BMCyEY xg=Vvn0w_m_K:R``}uV'9w/`D/U\!SheMrye ?6V@)&s}]_MD-H2G$l(k~߽CՃwog8_ s?FhNV'qc~Љ6d}ziG_`ßI| U]Ej'odliFA"K!lv@dX<r#ޘ -Ѯ«/= \wСk@4\3iA+ ]^* 0h3ڕޭKQ-Ѩ_oy@2e_-v rϏ^P_y4+muʎ_jBj#9.idf 2lnnqƁnp ;p}4=bW/o02ۓ7" :cOT9dfe_>׽#yV+f=gL\3?5s<ӵyLy!MIތp8Gك_ZaW/&{h|Yk;7r|rgoxilg]Z6Km xwL93ν:o윥WOF^ox|4 L瀟76sd% 5_8ڛL4seCWs~jl'o'[jtsK^bk?woÇ#6Tr0v=./>H<˯Z~MV'_U686W6}{۔S? ]UF_ޖI [\`PGwhW}6OtL ~~֘ht/ClE4y#㔘uA{*蔺H{3;HhxnTܬ vrxڻИ?]X9~Um-Fqgwd0]]AڇZRR?I_pvz \7 ^vRxAZ_ǣ2V|o=zC?އ LUwݎnqƁ~GP쬌9fqQKl-+VEf۽~c=Rl"N-gs59| r(-ڣ7=s&z;ګR{^sr8[ o^wC}d}1͜şm*[>l|%m~;eFNlm6Np3sU}&)-6T?3nfu}!&/ Z;fEb7<ݽ7R᪌ l ž?8vgb}|ݫ=W _]G#X[g} UeG^&K+J"+z܎6 Z&n n \ mCNHGmps~O}w%&ّ&?p8ov]ooڬvk|,ryIOVo:,#j]eC,, 4ȴ 46hcKn6 >ep/;-ɍ,f>B[?9)X|w`b0] `?tֺGj Ft9a%];HMhV0GĜζdzwceLLtmL^ \9 :^?œCCnORݢ~ʨq6'@@@Zw Sm J 4ĹVk`xu"LR&N2fs|HvfuOw/8 z+:b<Ҏ)(xxg_=:\_;!Ysw-~NjD?):N?8xFx5Xp'}O6ȏ@2ȩG? | q;%]N}~zNi!៼ukLKWE|<1k@яE2lY%(tm>yMx׳:^ѹAu<У\VvFƄΉЂ!2CxwQS )s;nqƁnqyOY8s 7̾{wIf{yV1Q|kS\O޵1kvNg0C)ps}3d=hsc@i ,8fQ8|ov{)gމ.bj>ğ?p{};h a[l9f0foTp)N{MbW~hG} qrJ3C3+ix)xw5psf+0;Wdl@vHϛ0de HH8Si@~tMFp]௽zeHpIHmzSfe +C|P6ҹGX˒\mcre-f޵#]O?<;+?@׿ +5ۃ?evY&Kۛ*.݂'9!w5pS6fȺ _0/WKyjt,{?ۑ|DL>Sw(`D *qrC|3uʯPq@圳;F &X'W#V69m 6,;"=wʡ=L)]SNU6|.H9Ѫ~4%CSuh:EU'0N?q%uP)mBwm ѱNkjJL|Wm|풏YQӅEQ < J/I:hS _:vwGGO@wMι(o@tܳ/ᑶSoA(7=sO=|nec|s9ߵ~;sy2KS?B!L5e`zHYv2Yޢs×>L/l>IO.?$[ KU|eA*Ek" #8B/4;4q с~z2r:ާ$k烋W6\ *?u^Rp~ zB? hd&S=ȬL&M/9j2-$[к'o=Ι8w'h̃@l,G`ȉsVrr<7θds|0p0 fwɕ3 UpfM; #Xw4 7!u5XY XGJ&hmu:qspC9w@}Kkov}Al8?8`m_>t"AӢad KFY>)R3{MUgr *=x/_K ~⣭m,]{5]z`xq@p CO  <7(myC0R߼o2) ?ytn, I#޻NkgiWǠ>ʏ Gv B'S:զkq-\G'^,E .#B3=VNᚩ7)t>pXfc<>^; DT VmS{t~/e1,8 l.[BFC:yҋߞԎt20ŋk[ݹ78p78{lf0eڬz7};-;zoN#mɩfol'9BiY6Kȳ%N$L y~jT@fѣh6Wz9S9/or^07 ٳ~)9f-pLӷ Ky?׭ɾԮ/5>S?L5RGs!G}z<%-GX–{~vYex5_IxͿ)KǶtho>xl;MDpv@^HgJy~w|v^wWoJ+z[= Ӈ! m_1/_fzC6r*4^-Cle OE*irS9|f>ͷ/ʢy4ſ9Ԛʾ]؞B$dȽń:wp:9=yЎG9VR𝋨8ӳ/o'+$VY;u= *6F0I9ރv}S9 |0HoBY bP6phw|L\*Fp5>3~?yN6Xa`hC@+ =Am]ϕ}8_ڊ"mH/?'rȿ5XRFr-|'ݣT 9ns' 7Gsmy~ k`h P:Oox{_MTuipbJK} ڏ_ zFʣswpjuGϿѥ?5LJd``Iok7G  [/E74;7^eA~X/ǣ5bG[>u j49<qƁnqwçc ﬌CϷ^5;`1[ճ.{=#rKǎ깙շ6)OWrr}M`R1on6+sՅV4| \~ fU.~Mw+F|UvY9G Sk 6qޗM̺Ey֦ҭmT';rY]xk&K,! KK/9Zl/K4WJg qǩ0*Meo?f/l~֭,'6aǟd[|J>̓ C}L~,hi܎Zj\o9'"%Y{Vg8m@Pe@ R|#nRdo6PAt1x\%}î֥Q_Tv آ[.`r8Ts3 65L i5` Nh&PZcѪmӯωR^p ѩp|pǽ6~1VNo!:c,Vh hd6ZSqth|T.#H+-+:Bm-e?o&8:3hj#?|~h\rYÚ՞op02'vg\ Ogmʜ F̋ pqtJGY7+xhpwxxwu»}P1NǂXGk ^'d]XhD8O (:tW~X@Эl5Bl4pOװ|:s{lVzs9 gL=x63ieV#K+Uwܜಿ*f~3&3Yvpl:fYΛ S>iq9lj0GS&ƣUʚFGfqiس{;I DD/s8lGx1Y926^;vb7+ k?> ĶJf'cPUE IDAT0pn%\v&kNNr巁`vޑ 7gb.rs1|BF'b TvCo_lŰ_DS4,xy+#Dգ:t^Ks~0i$3ρ>A7CKJEfXN%8Lm}<3Z`P>N`py| x*\0@oyp>iaF+wP=sd>BA3};dhz%QF84jD{4`pz=2h|MVsϿf74/l&;gvۺF6}mJ # ;k}s8llY)Ll)'<+8!ZP|Kф'*O®'6 &gA<۵.뢛ѕ?5Cc;aqv~>h~S}gKGKw7tkɱ:J/NDmź6\$٤ ~G||_z 樻7'-i昍G/re w BJ wݲђw[]7ȼkIB6TԱX&AwH?LW߷W GmI"gvկ8HJdW3d`˓2j ^s'].'@w*+{}8a_ B6&w倱֗?뒎:Cf(7O! Ip8Xq֗\\P餺u0=q E@,[Cnp2``7蹣cZnLt 9K;u k/}/7:nL5>:OfoǍ78p7p=7cyܳgg98=WS'͘zlq ۓ~T'=7{ Ա/yg{s*]cH6}~)p }'؄`L 4n%P辻+C}τ͞t8LmA0QCLMM=2C(q w`FkHQCf[letCad'pӉA7,W}ؤ+kOETE2ɓ2 vdk}asggx$z_tډh{.Σޠ1:O {k'ǟ.6#/s`hԭ'bZB0;~lOppzE[ސGk ޠh&fol5 '):&t%ӇNfr&o!x܀|utwmE.n|t`W{2ӬdF7I16P` ƓhU[Ζy >:ۚιV4*>@vc4@yg~<ɋo>bu2:=]U'7U.]t]QD@FJr5Tz lUk|CYXYA)@ n4B`.%nA\n4x4H`pGJPc$38`RC((oP G;vrL}C /?Qk҉k~ ڣrW5fG<{@?VG4ƚٳ/%;mu v<p2 ؘFרZ/mɼOv8/S2`~cmlwyu}vѳQGqOrH Xov?ǖ܏> #[p ?M>XP?Ovim3_HnI%~SҢ8FOSXe>G;gu]w %pI t_ߴtж9CewǪ7k( ~/r$mت:S#UïPm",0Lu<}1kԚ%Gc4f3<uH&a0Y~z Rp7ޑTd~PE~ :}@KMO\7*C(kbm JMF| ߣˏ#-gf+95L;z~?mym]R>^ٗߔd5y9b< sA)$[>wNWmo*A'b7V?{kr$?VJ;Y <`u^пW^\`zm{#ta<*Bg+_:]~m5@=fCv_[zjp~۷UJ3CjGmo|4d_ʜ A?d:{>%rD*=}$|Kk$`1(NinU,.W {UJK':*e<|%@VUE*{gp[|G)hULp.Z]8U>ytmy(SyZ``m߻JAx5B'c ,@AƠ`+:! 4(2Al a iX?yƨ>%v˟ Hi$_y\XW0q:*r=D>[ф33tvdWg| ]qXׯ&oSAW>7Tů m}YR \ٓz%+y7hIFi!-Xm ǶV\:@~e!_~lЩ{ U z|n~4(ψ:h,mm ږ|64h N'} .K.ߋU ^d 4Xns_;^_4|=V`y?*^CgeSѴɠΙ>|OCѼTPi ix@fb HPo֞{q/WwCcd, ZJ VCI[|>Gq Z#?j tz?xvQ 3 S܏8iwԖW߃y4Y|+ç{mk>Z8ưO CUKo@6y$!Vyv)&yd-~Vn:^y$ _$fdOp^vW_{}t]MHMPI DYyv:YK+F7O'sgxv}cP`Hw2@q2 cydr4X/OWoK$EkixwMDmUlk9[#+tX/ ] Iv*UabXb:#b =tYZ) "N S0 ɿ_lf$,MQ/݌?z`NeYSRנшG'`K8PnPZcꃥ} lg&a{y:if{{i7m $CsI!=gY 5u//O.K%V\`VVeU?^OzT&}ж*XՒGf;VTaw"e^giӥ#{p6ӭKW>g3Wk fʵ?fvnkB9gdN֓az%'vRjV$~$_K}{v&Q6}wسC'onSc2~Qџ= ];bw?w %p]w ~$`.pKyf-c2%,>_Qo/_V4F`=N?V*_o-oaz>i}xM;,dx^GD-{!p4co)v>{Y Ĉz@P&-7 C{ K|r?}*X?!1y̭'-z?!h4 +1>1% 3!@|KO, wuy<' z_~/meT9-.ˏ]D'V߲uDzmM&9Z0:?lV^V~ӵMvQcO?+[E-ނsOલ% *Gz>'?Xli~pG]tCaZvA_U.@ߌwNLG~9 qWɳ{u*ku?oA 5y zDndK-DWѳ+ÏZI!X<Q?unBUP}'M\!\ /6lbuK~[0^ ٺP߶Ͷ6ЅZ )+6e S''3+S^(8]˾$C?=I-'[.xe't=ߏ$nAA3 0U|㻝OUj(^A>[1t.`V.FKW[ |? Ԫnoo}Ʒg*p~ի^sR?;tfOPW`*7yilO$xD8Ӌ=d&KP/& 6gV{`?dY闬T֛%! sp_{cx4ml-)b z>MCƋ?'!8oNPu*5b{Nigb .ȠLK 8ҀW}31k9V?< ,)Oрe3| R^eO@~l>vw[\R W S_[0CW"S8( IDAT (s'~X!ؓC2l,yȁö`c&Lw[3V%0D?Í1:l6xXJFZ /o&]|Q{g;`tic/-ekxэ9ܖ5=y^CG*?<|ɰƽ"+ͪlApc+Ifwѐ|~v:&S<>ɦ|]ztg@誯;^L/pw=ה;_{k@rdz`>3Z_&]`}tB^WжA9HXdSd(P2"?-mvA]_w %p]w ~$ `\W}}Q{i/k]˧.s(\T}b܃T]3g!ߨ[눿Z B/ˌf𿥇{綢s><í^E9-|n@A?! ðl~6:,W/zN70`0it_tD˂Eexv cZ=t_cfnfc7S+`/"~kUdj,{ 3d V] Gn| ,%#-w&sx!qLoFã :S?8xOz[-o;z&w?5sNÿd96=kwnಂAmg6} zP`Jm) }[q$-M `m \?K'3df}/n/1Ϲ\`A𷃄7LfxP.}&ec f,+(0s)/HY߂Ok Y*m0nKe*" NPq\Z^WFL<>WZH@ R%js%śƟAN.{hW"߼\FgJQ/-YF'+g7?b  "%Y4BLnxF ULfO'`S`}SFwӯ@q3"/,CLfW (8lg2zL2)ݣ]y^?Y1}htś#2Ml9Y&U˨[r@%S'_?{']ZCo 3<={wVz(i}H r0Ѓn4!M*Sh!$Y{hVN{q}|Ǻ2;R  G| T:]Y h>q^C0MåK.K!'V{oc·>}!5s}sOPt'>ڂY>%_%n6 57oA낏%Pn'8Y@`?w?y V@5=gK1Z*vr=ځ Vs#Y̰)h= t-i^y}Lyx_v_Lg}nvv8P,@]'F3.A֧Y!7o|懇Ψ/=7N|ovh7;ՊQ4@?hUz ]`%KV}fϱT2c} loedǗ ,;=xNj%O( OTM6_E# x!ܓEdwf湴efቍnŵMV6|ږuT^}Z^W^xR,ԯ=Zi]7~[jgrsbfl#\/ן{&ƓGCe\.M N'7n3ZBhб_3 _J͚3+3TJsak92FLpNf(]_C;~~C^p(wfۃsVwfwd0m&CHJ/ 2f7,S-ZHMvd5+GȒOY ≯7P?yuu$3^C67#DX? rh3,9&A f~W³}Xп|<`N#ftCr'zпA:KxC_Mgsh=(\Ej;Qm̾@OcxO&{(70mLHe?i:&iPzϳ`^<ȷ"8JrٖN ˑO&-Fj6v \C[eHVP Ig,}J_f}ݯK.~O~B77K\RQ6"¥kQ4=R^ЭO CW[ 1Ӭw07ofz0R!'\K h(qP8o_w髻Ѣ$sx]x!Ǎ=8hok9%tvmF6у`* B^ X|r D_c/ kYWn%^7Neޚ?!OkcKK(?/u9}fl43_<91R{xd9]%h^Z rȯlK}*G@{QƵU)~8*QvKC$ g[!'s@0@ !aJ"$O>N)|H O [BP*C3~+JCT-WK^_3Qeiތ*h($\q#+aK: ZtD5&U }@)@\r"FjF&WNNYs?`cm^!0` qZ־F.?RO q2Dѧ.uY9 d%c#\i d'['2~Ox9#]Tp0k-,Ov9qNgI# 4MF]gIdԖw̿L鲖Uxl9 :{ tKZ =Y5烃<++/ǀ Y:ԲeՑI ⁋~]zӯ䐎;Z %٢R0޸(q2 i7v`=O W 5ZI&70?}% 7_w %p]w $ ns#^?o,͚ 2e>ᙑ>l9*;Hup~jٴn3쫼` UfWp{}{uoWeWMBgIz}2 (د9޲w޲rDn<^f>ң?:ȣGm*s, Jo? $5`cG F7q2v=F}G7O؞g!:[{'z*~j ь!X('M 5ĕX0y{y# AY8qe-= (&<` FC׌j paf%1T(ma&Н~Gx_/uR,CVU@*"k-Jy0z|%G^cɧx燷%'<@\~_βɏ.9q2Z:LMׂΎxɌOmYPuonj.29\<2Nz4\[!2tLlA}.2x!Q06Ok9۟ =ػ+m-U F73^\b`7|9o]VС{߾l@}/7{3m@ARhVK;`}Cezt*U4g*&ZT"h˻-Ŀl-?3x/*!n?`r#s@J&O9}ioz;v*_jߪ}Rv$~yo_*F[0OF_7Kl*MڅM8bOV"$sywmMi2s5ɀv;\x.%!t#N Nh%_ukhr3ݓK.K#-BTH Yr^߂pK~7a[߂LM/g>P@*|ʖշ۸_e˧:V>ŬWսѲkp1]Oy3-?,Uo>nE6fҟ| f:oItnR&X ,{m&lV?NM2Wߋ#&S¯7 H2U[YblAm>H/A&;y.QALYcHіn]&ګ}Yjcb`$7ߡFQ%^|}di*8w`#aSqAaZ'A0fSLnO@ 0!\@5$V!èǍTfp`Lcz ZWv\OJ8| cH5mh@\|,xd0pA`{כ1Q a\z VF:V?;ܓW!=Y\X$˽rӗPs!`＀w b׬h4ij-a_l6S"x=_㏏hY=-}cdK.z>xx׿d\z쇶  SjdlP}rdx1;Ob)ypDiv3i}]@Mς+pnC.K.%`6ѩ F벜y?\df-1f۠83?tz;O`J^߫0?aS*MI[7 =? =>G^(Iwn^eO|BpZ3ܝD%_;hC{?/T@@E!r 9.#ɵI> 8 gء&AWrAd.orLñmK~f[Oo_}Dl&?o0:їlvǻ H6.z~.m5 oә(LA 6(uq*_<q{Ao TAP3Xc> Խ08-7zش;8>h* .2y#m7iudAOnfi>nzSQթF"g3CJ6hEioO1'yg dAiJڣΫC==@ 'wg-l\r@%Gk]#me=}6MFCAh)r+r"\б4=gK$\'}O[6*QcyWƓ2 ?V] u`LlE;,F&Ώ_|w?@FPg.* , MxuvElC<8]ʕzoTv?lgm.K.ߕLd#.Ԓw3,D䛡8O2* ho2@OZAq}jL<g^>@u7kI|\ksua}9p/VtM;۹BoY?lYUzuGᆪ'w/$_`!=qL2:`? 7g/,9XK31?OD5,:) vZ |E_mQ`,@> 9Hla Q[s𓫕xQP|)XȾ2;[R_8ѷ"QtOVlw (Q0t YgG7z6Q}0&G*yg>mo%0P0t(XgӶs_4V/?M_}׉[Q5os>˸ ]]eȃnv2vlIp܊Ǎ6}if;DDъ(Mʇ;X&f`6c"9tPILngP6Lv93jV~K)~Gfb "HȾ)~,=8FA!mLxԘWռFZ\yAB$W`fх |LX &9~l%ܤ@ [xޅNu(t|,OƧ^ `2R:Ocd,ς 2 ѽuL=@/Fg9NXe2O^p?ʘW~1ڳ\np>J0\p/P/_tts} KGWd ۖkI2}G:^YFd PgAYOF502 {bAVX]H{]/g Za {小b9XIPe|eZ@7:TM2y]0h=U?;p=r5]ՉA&ҿ0X{fޖ/S%gz b*8`2tG~%p]w %MG9^:g U7RB}f#K؁bfaL[YѬ>weoƁofͽB~e@.\0l|(A& Znykጟ?|w_7Oό[ v{W6t- _rV)ǯxBDx9 /ߤO3vx[t$h=&Gu;e%ۧV&,@C5y'>c_H_n ^u㛯N;a(Oo|-%0<=O 6(MGU4`+ۆ ~xWր> -?sĉVvg_{ل+|ɈI-M[n+caa/ @ U)何)_;Zvy=٠87B5mV]mW|8ܵoK !\ վu{voj~T u0v(!(Vd;g?_@Is)V7<<>V(nJ TJl/a=N|jd}LxMi>t/L%-ŘW`xGKEg7zb|yh?Zg~SFo Ձs<Gf&k}+[D1b:,He?PJ2A_A3YxoA  Sp6V|`r2|4^2:ŐQIOWƖ oVc`au:髶V{[Aujƒ*Lf+3;MG߻K.~HN_jVu6)pm{-RsD?k6mչ.BW/$rN!p wt׻^'`o|}(PA룣DžS j7>f}[_=Jǟ_Wo'?{uZkX `k2 ނPX>oR@>YRoKW>#[S ^YZ~`a`|_U{x^Gf 1ʼNpof~1YVnG?W?!h|̯܀N^9ogoYz/OK tL&o Qr{m]̞nI%6:>Ǿ:`S!3ʽkyGdp T0YmbO/~7۱"UlIe潺4*5e+|&o %O-tb6q|;7C/٫-(z 불 q 8S>É1)})\ qv͸-Ub+ɞ+2%DFʺśF{_Z<O]yr:?GU!46Gt'/Ww]ys>[:/Dְ}lD[%Y~u`3 (yǽ`fjp T>y,39i<_~+(uv59Q9aQ^p߂XB} &8K"Jg3҇/,A1ӗY`&7)K!7[md zß{K@++2׽9 SA2|W1Kuv~ 1*F#XJ#, pc}rW[a,}fp|f|Ƞ4:`;Q? BʷA A'o7m'}|u\3,|6ZvmEOfm_10a`hVY­6(ժ^ !T^>V;zpsi7G>p#y=o; GXdՀf#hy7DW߶"$ YK.D' Z5009. VhAf%t͸"9ZsJ(t4J֤r Q1:19j=|RA}I@\gd梻 2f|ȾFCoYT[RR \Sh8Όbf@UbG>N' <|)4> sٟ`5a-KFtnfzy~iT0 Xt)AcD̮ċ3h CUdx D $73-OFjtZƣN<2840 ~QLG:vU1B~Џ x /34zxo5΀IO"6 <?8< ӛr0[0*퓭W ܁s;d`_/5|-E%CmoV%=uU,SAG{E6#*+v8z;mT-ZΕGJ-֐Óck󯏌糌d;T(Aफu]w %pM^>} 7c]tV0Numu^ ȽJ}_W@_X?Y @2a}9A,>h@][i6.}8O8-oZ[p[evh @UugݸkKښ#lN5]ЦPbiCvaSV^QcLa3C{E$nUU2nd2{=H{]!~[nLsi 3Nkf=:@@8}pQiNFVKt 75`GG`ygPG8]@! DkNUUT9q.@-;1tyэ7V7NgGpjb.X=F_u5@4K._0tˠYOg J0;Ć=`쉼7ȓls:7~.zm;;x+zxv\Ö^Q:'/N׳h&oaʯ-ePBL뢟  Ҿ<-:GT; |C˖mŵp@ތ& 2{!mK.K&-oOxշ tW~>O4}~gnt +u ߃ObZZߴJk3jqZ L3^Wn68\_r}.Y킓.ydS`ť[m6S+(2 )V}G&O3uh2>nb$EAr*go@> 8.+#vU@Y|Ir[$h?-~_`o_^)o[ \hhMf%W3l`Jٝ0|el#/}>bpȾhĹ&w|ۢ}ɋ2ˏllq <>z?Ox-E&̯ڌ+ʙhz—-Ulx}zȎȮ~vF 8'S+S>&N Ί๲:|D^<5񧔀5NI6ర0JW*NF@||6+E Qݟ푖ѭ WgA]+1_gX7ŏ~.|{!oԡ MH pwpQhk4]ѸMxdR68Px+Hڲg{ NhD[|I kDoYc\-Ȣt1x/+F?8v2@|5˄ qeZm_ih> %==}~%`c4YVEUC@9Hx# b_߳ "@GtF+=].Hm4`֓pk[ʏNu}7ί*Ny+ ڭ1liv۠붭ǀ/ Jg6Dgf7TZ}[BыfP@j3nuLF=cv(iDFH2!'_w %p]w $Wʂ 6CYZy.H`S}-.eCw. ں|[g[Fp,Z-]7oB[RkY3p v]8͈1`t+*;v|}n`% nW<Mx>XW}qX^Cۼo]$0n׷\ZUavp1F 2WxlG F~|*}O?_DpaON~gڶQ/Log&٤-YTO-j0$e9|@ɜ"ce nMU|[ii 92 /2* (ٳ5iʞ@ދhmsW-oAEWqe/xVXN?dyGidžN;I^'K^ql9Ctn):y~6O7(\{%35z6TfvV=cK<Ȁ$GvϿVl|xsڸiž4`۟ IDATl)8jVwh4|)gّO~ $cʇy+@R U,K#z#n zHYNȊ}h[(3e1E,EKu@0[.*-JF F:.]T`tÓ7[&# ;2oWÊ:|]F;}TlN@I'.K.ߑh=)8~Z@@Y[Z4m)2G'Իw۷w|w\պmkqh=}%%*|_NѰ #OC4/$bI3~sFIh6Rg|VP$}?5Vlb/+ FSZ@.P4W.—6qc.N0g h?y} #ɖƷ[I&7/ %DKc-tqz|mq |׽oqB>T}@Y~`}S c+OER_&2H1e Ft <|ٖvbpG}zL9V.OA|/N%={OeW,\lm *@5X/(:ܷg=4. }#{Lo2^[ͧڡQ؁ru㳇Zq[0OJF[2FTKΰ}FA=~u?#H h]zw#O xK ̈LNl)3]U'@댏n|/V@ܵW[C3doĶDE5fJ0A9- vsK.]IpݽR|3gb$Hݠ݌ E@fM+8^reR`~/ тyOUKPւ}{`4ss?7ں?Yϯ:)}SAۂc傐%P{,S_Hn40]̾?G0 TVcԌ: %" ;3xb"!~(Z/PL@.OL¹y~mɪg$Fߗ/Ltx>㖴6G:+xھx~kխ( ^-d^i{ ,nKg_z&OhZLwR]5XOl~gCejRH_O7!իW[ %qQ`2zOHݭoT2[5jV?1i%(0|mEU]ǻu5v BUpeK.]HS?6a^#R"| u;P ߭R0`J[a}7 *t\_> R. :} _fKO5T^}nًfVډ=7I4 me~i5*,@7V{]Z<$;uAڶTT}>|ٺ93@jNx[/{աYZ!C~=l&%U"[J ~;zM/3(!8LG_{sbj+xXߦ U6|g>=ٛx;h /|ly-W_h&ȦR lp%Ьo[q^[3rs+^|oA? )Go?t4y`#(jl|Gߓp%LyWk$YuN`{dxeP& mENⓟ7Os=}E t~&'ϣ[\njHG=t}~|I}y;3` @Ac'#XiVQpK-}OsOQVJ\@ʯGk"?>[;he½mC4lC?!A8ҒQߒy]poٝ&wa i/|iy_suk P&/HW-_yV]+>nߐjwt400,h-с~.x;>el<#1ZN\~l(ȱz:&A@wklp|쌅ʲNcv ]DPTZ*|-sK.Hཥ?ghH{\ 9|':'_6Pb}pln)9u/YԳ `{}z}`ӵWmہB|7b׽[%{cwy跬iCo2Γwt|˩[q{^ fpU~ ߗefͨ ĹV'.opjpʰ --?ثlζ*'&%?2Ōß.0`.WCCy :cDg8cNfA͍G2)0襓krLݣs-/qVbs lAڳ? /àOF$4Hh1@rG?\fK;IEv) o%R Fr V~ xw%5* !-=Gt4U$[pr:l OvhfG7U}<>ُ'AhDikqhdaa`=goewu9P?xЃ9;`K8xt.K.ߛBxA7_|:O`8j}? ~Ut͊^@-[o0+P~0q6CN}}f?O>͊bY<~~λ٭ H&K+׏> /fY :\>$rP&&S2Ȓ _E/TJju>}s;|2[_o>\3O^W&˃aɽUeHvbp&dg:ˊ??lūVPIM__ tݫ"_vf=ʹp٠)ӳ`S5ل?&VLSF=E|'OҪǶ~֪Ͼv_<%[gVi7 Xo6N.HfܫГv2-Nxm=i)NFXGIՋe Rힼ&)@C3>'M2'7AV-S{F&06Q<@ڄMM9n&.orrp:%UFZN>TPB^`  ,QP*AP'=[?DlK_uZFNE k^+3^TSx> >W=uC(߻Ch 6a"Qur@dKyI h? VG w4IU}:< ƇVИv"xoxBʈ` Ȓ,٭蹏rԨ^6 /yJ&ٳz3lnOlҏlKdp{Nw?7ayzxj] lYED)|op$e1T~QzW\?{y:Ulӯ=ۜivRo\yT/ƶ4!}h%lp:c߱ 8k΋V&azh~%p]w %NݯZ@'\w|4a;oӻ~i7\*S} R/( ]-mڂ+CwӃ37O,]ivK]W|ی,t7ёlU{/GOx}I͒!򟾏xgrc2F;9l jp<Z_MQV`f:Ο"fxөY'}*&ʁa~7~O*z׫mloؖr7–0VNˏ -i/ou9 wu*Y\~Er<~?; b,&es_]b'&;9[N?ϿE&Z'' гɣz2Կi6o$/v6?l(v4׹}[6x^yǙLDf7Nvf󶴸;߸^ ! +K[L"dqF anF@̈Lqjo͠"4 !95z#:2Dgc`\ǐ%^)1 O!-AޘMp8~tV` dTeˌVAȬ'g"=#ەdxe#T=O~C}*}zs5l$}z0;L+Y./ K0IO8h57{} \uط:p^lדS9##2!p;$6~2؊F~63p@십oJ{ gyάٌrNfH\0hG4  'e=,O=s')w|GM8K/̩XG\ ;%"ef4#:sn{5yY.N?:uv$pM7 $BfFM(E+ǯCΜtS(h/NQWFo9:z|hA'2qχ'w--#k;|\|mW ^ @jAv)h1-ȿME78}T@F/;ebYgGͲgTb~a7:E*҇2GI1tacOox"kd_׳3]J\+GB=ߛ?3?أ`uLH[lkxܩŭ:C\GF+ǘM>ufD ʙ k/SLwe<1@'VHF؏:3•$L,+ iբ:Mҷ=|C@|_fX:֐~nI&n-I@{( TkR f;n#x^N]kH #Ӷ֖;b\M' f ԍl0eSxGpC;,:F4xÂOAʁ~ϟrQn}:]Fo:=a6 |f/?5^'E&m>hAFu2pen!MC" IDAThRPΨu/#t)~PFF_e4ovZv*}%3fVq=#G+^' l?գݣ@!22#%z%<k6n4Oo{.xlt+a{l#l{ԃȺeoKAmla,Vq8YZOZy G/fuպ x|AMy|QUi\|_~U|p0\}ׯ-h[e#;7RO>^u6FD/8 l:XN\3=\:)-_Չq4CPV}-o:K6[(qU;Em~m6XzwUk !o( -#?ɱ~&<;~$WOh ͧpMycoB4B:ކхۇ?w|]4 df`Avtg\w-7w=~5&_VJLkߌ/uCWעL]ȿ)Fįh&ϕ~gdo|32FX~boGT\)Z5%읎½ 3:wθnӻz 'Kz33Tȟ :a3SYԵh@{򇂍D.as{)X ږ)VsRوF.G+pX#͚fն ,*1A;om36`?lĸ|ӻHpK?,N/sƻi͛Q/X0 ooںAOA:6Lv ?;ܼ(eS ~h'~-8)}۱h8K6 bSǕ!| ܨLu.<u(~D'6B:)6C&m|0},Lǎ{M}7qTs#dy,?@T~F-XAٓcO~+Q8V8ӡ'O(`YD_,d 2jϚ:vh>=&)qTF]#.|7G+ sn>|ULybG>R:Tu >b,y0+uT༯]`m̈t޿zY=f3/-ShzAW<+dP{&ob7u,Lʘ0B05S]}ώ?=.2'7ڦ\va g]56 19d=r fPޗ 2pf y#^8Q‚_c&~2%3, 613F'0_t<^J_@$XBmFp#e+d*_ U܂0lTnVxա?:g$~?ix=&h*xlW.U sҶ)+w`]Sy[EO<0*Ehzh~dRqjjIX/W˽TF}kȽ)OWHxpWr̨*x lT//l}2"1:Ed+xֿo)]Ʉ,D: GoWl?>:(֡)xiVvYW8/njp+q,ⅵuD`i`,ߎ L`<[hAR?60uh% =>쥇 !=ɇءݾâ:ç@Q>G&#<6eȈXZR|X.@AC ˻ ӉC@ܦΘGmDuG≣{.>A^-i }?c8  eE,# .'S^,2,_Q9&gU &˷,3<@LHP{4c^*M9FhIYNnw?MBghEGFO!_Yy&?3|ͳ`:orcJ$:&n0 LlGg;*!%:: r?~Op9+7'Vp~)P"'U8:Kt|0&]`R's )V>gmPrEɛ18OpWMdy[O4nIuf_`#k=oiu #џts4]U$Τљ2/ħWQ&#>zLv>*ٸr]dsIvl6r,磯ˋ01WFHݮN:K>;e> D[/l &Ofݯӥ=z2 ~@X0c'(G+ ^mj w+| , \`T߿t6RMxû'،0|囝euU{e#v^g<C$iw4߈.>ۚjm+{FWu|9/fy“O+݋}ٮG.y2/~] ^'Brߨy~ :ɜ,:gT[w/-}h3: 'x[+Xy|"KMPYdtOW7cA>ئ}%b>~-Z#t}Qw|?pDb|ܾ\t|yzh+^g ʢųʸS`kULQNY ;`̓[0zAN䂿}re hl`QGiŋN)ot&h|wϷdk}ˇ÷Z[5RwdT+tx vx gGz-s}UJi;u: VY=8W{c2YOόp C&ߑuDJqp~ iz^t'x^1>47i/`י =z>!:&{r܃Nq3i\ҺWG:`>{ѯB&nI&ߐ8v:SS.QovUŠYbrA/;)}/N)êV@u/@,H;/F?qoD|FA`MOas~ F]WgB &^|愢~QpQ$13ſa~tӓ]}9ϿfB? K<2:ّGww0ŋW?(O -f1 Mo$<#Ob&uxzΔzt`g/WFj0ѓg^@\ G{xt#lYr)_I6/N`鬻YkflFGyvbPD)Ŝ5e|z_&S6 Gi| Fw['h6QRGnP%Oh|^ #DWVFZɵ:Y{tBho/W ΈE!lTk] *$`Vӡ˒4r,}1< e$,˽ 9Vis7?xYUN3m=?{&׀wHCsƮ``+=;/T^? #@7U=Fr=ܦ}IϧG\brN~8z]d6'>gGF3W:WxtblZO8unEg52ݮ .ؙ9,g`^\(ȏZx`S}YlmEFO}OnC1\uvi]f$e虍=4~ܮnI&~Cmm54ͳsS7n*wFA{ՓvzF ` 4:6@PQ{jtu#/p.am@8p¡}4S?: |φ{"|BC@@v QDF#qAWf9|eI61_ 0{B:uyubd'F' Ȅ+x;(?|3oK|OE;x /wg_(ȟ@[Ji2 z>$k{$H}GA&/\V^M/ѧ 0o=[Ρ΀#ϖ>sa/8le~doVұ7ɩ2dpꔲԠ%~}qwt~'X@R,Y7F"ʿ7fG%>G<~uK'Ֆ,/mZ9V$񂀞RR^p&PRrG\Na W|')i@uyI():f=3 GAoj`.#ju sqܮWSLJse/p2/2 o{)F^/]Bw䰎#LT=~j`{vKg|~|zXQn{]db'!9@=H &.o>^;C4L~%Qe-C~t`KO"[)JI&nI7$mV)0&_%㫍_\6^-~]viȾ/4Mϲ< }5:յp$5\P \ P^f>GT^h@m~i舗׎A{mĦT aݳ ?Hzb 1t-8>@k'1f 'qRZ Wf Ϟy| PF ./k%/^|yw].zK6΢ :,zӏMP=/H=N~5۠utdV[&ҕrb lMpN( _>'aUfyhгRf.zSV%չbF ~ AFOhPKi ,a,X6r+N\{T! ͐3m-/t??DF~ IDATowtSp,ΣF,1xm|U}NyGd?$U˿lAɨ;rPqPwZ tJWLe@HB2;u,SNwV0ރAQTzF_LJskaY9zM{0XF| @M6%/#9 k|7͕ d9{2o[Ϙm4\ljc8/ǯ*a5?Lw:h^/Ve7;Ype) xy :sN>"Ʉ<̗3{~n075x'|౫_?BLE;(;и,4BMT3^wܧQɅM9#t~6YM,G;Z:F{&xlX|1|=Y$lR<쌲8ɣ7T4ߑO\8=q2leՁ8F9ku)Ձ${S xuP]o^9yLoVeOL峴~{S͏::+ww?98W|: G)mvI 0xQ徼 k|LƗg)~=- LG6|tg32\7zTh9Lgq@ +'p p)oc֬'k۵,Y s|:/.O}I7 Bu v^dZyl|0~iӚ#tTn0^?m 3 *G5gKCHLJz:?=;?9A<]vt7x5e))=I~ΑKf 脨&s@};us/K<3 8 r,)^%7GeCD g^e,t 9x9[=WdS9zV#YTh/5 >xguO;J&nI&߈F/@ؐ5ӛ_O'Y`_]ٽtwN -#02h]i~ w;K]joD]VIؘ? G~C}q`3>S\W9íŶ=V \_\п~&>ɘl!|V/M| IYcX6 Wx4 ڟ7zmG;4EDĿ ͮtn|xn@F-}׺<>.Q~}?湋=7nyJ޾1} g>aU(*垭#:hy7smut?}3JdK`<ءz&tUa>ٱ s:Ae)'5/t"mIe g S =9 B]pk{XGn6ŲVJ?36L&_f.fEb$td_!_=2l6O~t;?wTf!2BT ֲ”t3x_,mFd NYJ0 GYRʿA g~Oq#`.tV\Z9pQsh3^2J7#C&-_2O'tmE<@Lt_%ɨ|j? Ǎ#=ːlJǂV2|l*;㚬7E'@(_{1x^hur${˜勇m8j<\dN@ "HF& ˓zo?Y/2kll󍌪_ap۩+{ySwg/zX>oo/Kg4ߗk6ԛ%E~'z DQg*l;:$+M7 $pM@ottm̎ K̇T g_`DҚ?Ǵ]oI)܀[R'4f{| mM:ք8ixQ]WW]uzҷӖ'DKz J'T&~mAYYu줄hz.#hB|xl»Ӈ|4 r#,?āχ+ihX[}_!)썆ۈ;< zj@)^uYk4|o_>E;ސ~|D@tC9V0ʱ!l d4~&|XO`O~tLn'#9tOeYXr!@h" k'ct[bۀ9-c{Q}ÌS6p)?pLCs&gubtu~ ]t}?1t&,aOI!~7X~.#cW }ru,F cQ8<%a{+^ "al. <_' ]#3ʤƏieKQQ`k0w^hGBp` \[E, c;;.Yvy2UNF*J<ނU%S(.rd~TzvKK.3YTYǫzINӳGKmw0v>z+Yx;G Q}^F]Fy."&^"*ZE%ɛ񞊵FfO;?9AGdzFBxsDgŦ $m숾j/_]p2G /zCKQQ^/xHר^\,:~ ͎xYtX?[g]v^Zz9}uz~Ȉ͡ݬp|zMW >=oݗ݇gz7 $pM7 f$ѷDX/'amj? v /"tvϿ2r_^jM(Q}v2Au4Ϟ>zGϥ~J~j;u#Qz<lA1YQ$Ju^-b`N7#%##w`u$*prN0Ӏ|=idST1~k۳ l~"`; [˟7 '~5%Zp'q:\]}>F?x2ٷ+H:.dASU}t?6J !]GxDXVHɏ$-LE)).'=[FP%>b]}_0W2MmFWApixY:ؼ=+(ͮF+xfWv''p.}S{ N$-M٫t^Ԉߊx`!* B1U>E;]D#5=u߳Hd:8Gtyڼ`?:Jh=Uf/H>СMNDFdI*l VJfr! 镜Rry^]Ug(s#[Ez4x8rd2=2g}`%u)CS3]t4cGGF=Ɠ? >q,5;TOҷ~/̽@ +( d&Mqց:~m=>W^z*HNxή1 gBQw yޮnI&~chӿ4oYOֶ.8﹀͏sy=[:; . ʯ#A'@cQ~>&۰ɭ-~q̦-Vc^#ʂ9gԖO2U|g_>{d~Ҹ/X `/4"`4s᏿/})D2B!_1\ yp_-?"/Mg׻}:zq$#L^h_F%8elw*|A' V)[:ȳ/~;4_]N+(`O~dGԣ=xoFͯ/≫4wxvg߲Tr'p'_h0dKM&ߧ+>}'"@w^(ʲ៪3 3CgӉ-ӿMw')0?tԣ:e_̾b63؉tEDq,Xf=1;H3x^Kư@Y ҏ񙠻 Yk ;s|^We΃.ܝ]d`(`P$_lpwY86ϩ8t^u]hF=zs9! +œU>BxRUa*1_h)-=٨1#3^ԔRyW t_/k }5c.<=xI=B צ{k dfVz:*t*@ә zKLFWHy蚍r5`AVZ80TWR W {Ȑi䰤}G[J݋>.oVz{Tf^}\وi&5d8AYt_+sJ:kN γlld0{W:k Mf22Dg+qrїqH٬<94fѬ\ I&nI"q(8&e玪ݝ{G/t/(VS`c4v_sK1匔-XC#^ޕ Xw}]*p o} )::)-?O~ݓi6&HxP`XxdžʶpnW9*O2q{A$+q\iD0KWNɻY4:[#h7OVZ'u=xO/ޓ}@ˠWA2xѻ<åq2^it9sc(f[n IWр~.o?oN?1d!A(g:*ݧߝGWgE]:w4%>r)0uX:\0j(3< ފϤ{$ѽYʀYV(Cd2_Bs^/|tɾg]Gm~0zxş {kyK 0"Yﳎl%kj׫zd`2M-ngBD:ل0v$:LVU 鵲۽t,1P^4tgd R Eͬ3,Qq^-]$voS?K@c4\ x`i`~ ĝQпe^ V0i_s8^OK4>wxxxɐSpq}awg#ԙ==G"$jTXw| {&/)2/zSSge6DJt= Go]7 $pM7 f$`2mHG+bM2_o'/_ oTtk4I4{6G7Qx>B7}8֛FgóFw_>kD4zd&wgDg5˯6nk4@[ܦ+0$Fk~|1J:>U`6Fyk <[ڂh_6='i3޼4"mx92>jts#=)GmΈ$7Ȳ k:p^%_{h݋y5lAuSQwpl?Z~5!o<: wW} |?]mۤ䳁pΦ:inAbd-?Q& ?}#J`2;:x:k='"t[`m2z[g!^MOGӃd)?nrAalo:A@qd:&c$|/=Lz3ÅW_;=LnΉ7fSb 2%o+ߞceN97~_{UXh|sWZú7r ^&gA"#D!sJ@rgQ%}sIGrĂzt9ȓ?ۺG$t >(C_\IuR M}jS2oӫ70Y}2.;xQ<'?z3h0'ʃ5y\d?޼T밉5UnuR(Qy Цܕ:PkJ|ok"֑p*Lz`F$ˮ'SzҔҎEޯK)/x.3Oҟ޷"vJ4?,8ul3#Q:۩|.[@o;/dl OO}yk IDAT8ŢzT}/Ϧu`|*M?Z9@z::mς ކ/ .ٔɗ:ZI&nI7#S^`oҦvrOFA؂ qoQ_Uz+iD?:B"QYKA9:\|_`5o}~>)>up\ |E kpv"w"| }s|!:XnDA ] 5lw(#v7Z*p[~px$`:|[/nWddd}|7|g'3k(ɗ~!R΋~w+SeNJA3o ` :v%8{}qІ0ݬӢ2:ҏ6_7: [c(1*g6;4k܂hdӲhKRα3it 8ݽ)d[e;WeYݿ)Ƕau`Kgг峏{`{A}WWj{6S33ߓT?Ӱ/^Jw7?遟Ip?t:߾.ؤk_ j#F) 5?Be}~6_,Mzӕ=lGqRta4LKZO7ռOr fLjcSCV|)@d r@o0/K>‘y#gf@h<G@2ֹGvy.VWY9?PSt}<3@O^뻞yeXx^ȅizdž:6",2%uheQ*EtvB^VE=Ț]أq7Sl5;cop%rW"[58^<)'2u \hePϼ̼, h`_gÖ2|蔃7z%`Ύ0أ5M1z#[5W+'ޒM'^\|]o2N&S8hW0@t'#NζuM7 $poG3>ͼo?yH]kj~M5P.-F ՟l_:Jٟ;~.Ať £} <)cw F]6(irF2_lb/}4_h~ˇw?:( ;-Y _={,l(h%˂~2FphX*ߵxbaGU.|18N7ѽ'Po&?Oek>_@LuX<=a'v o选(DF_P/=[96=_PCeg' m#Q&}~(AJJ:/]X~q,։7-Q,̨xO;!AQٵ)8ӷߐͧG%zfxLGeL>YŮ`Y(xcvqeK8u]zxa~icLxMW~$= (]RlFa (s&Gr ƈ􅦤:N])pLSFJl\kz)h:#ir^E-Ѹ~UX}\-81}OЧJ63,F^uX=CO;=+zŠ8ҟ% M3 e`l2dU#t)oiU=|2Qů~Q^|zӎ]GJQozՃP?ΨtY\cO6< L{񠯌*6zItg}g4; oߵ+u'`>-6eyN'Ѫ^Η,h}og=oe)gY4&  >#|?7|d~.yt –_ >l7&@ ekDNe:<;[:NL#<||Oqq@z޷6Do ڿ$ʣ Il_l'$ߞmlQk(!}m١MŽ_li˖.Lɖܲ!ƀYOl78pٯaf ml!荾7~ۍ>Xu/-a^ʟIo\GFIҢ-'be5? z郙.Y,N*;V%+ns=HBWdμ^V &?9Asz:*/A,x'ȫ >,b €0xAݚKނ{MVASZ! ovGi*4h[tўd{6嚇\ zrs/[<=Yয়C~| ٫| g xp(3x7>/JW\#2 ׵t/#5 c4{6: {"t,SV9M^ѯE򳫩3q}4Vr{VtMM7h^2~zY^0{!FyjՁr:F`|]:?Oq-O/-!HVИY+ЊF{_wrgK?ӳ+fs[]>ts_v#.h<Tz]=xzzAc@z:ÃtP-0%dxcwZnM7 $pM h3m;m t4wc &ԝFU[kZG58Esyu}NZk?N~Q~i5O4۱gA(e?<|#Oo:N "S+׭' _B&ۑ||}w$v!:.L~\`l?EU>Xw+/w Hn7[y3'LI7*;lt!@E677k)&|;,Fp^dƫg~uq}]B_F6@t)Pou4_^o|lKA;zFq_73"ˤצeC-]Vu |p [eap˼t2|H--l;բ}K?[я2/6f>3RO>d+9yf\5nNu3c8ă#wHHw1]91X:Fꨩ|វX^ˁ F'd> ˪s Y|凢)ݞs8х..BnS1LZy1{ N%+=m]oÒiڷ<@}or4q,?ޥ\yW&B 'LD @W!&B%d=>C<%X?8)W1"O*A<3 1<+ E/}K쳫2{,wrF&se<_|Sds%z x]uߦglzyɿZЈFKf4$#rMg[[oEF_ѦBdod^I?ȯF3Zͅf9̒-q\?; UP7[eX'Ax8SG ڣ ϲgsiZ +Y\daU=wAA;ėN% 9t,bCnoM7 $pM! Xfs^~kWFc5jهWGKKI/~10W!f@H׀y8\iFn:^T]:_'|frio} S(~N p$9?64:'Пnx'-6/c r_!|T2v$ؿʯci:b9ա,ul9au2Anu0Ј:ݏ?TUFH=uHK,-r8%<L~⁣Ոzw2,Ag_7<ۣ-ӣ; fOG36}T})9@(R\8csQ^O=}ytrjீܮ! p\h@G bąOBi̘~VN`h܂e^pEЄ"(er/#ᦳ_;7u!WF|'?0¹9D oظvP VTx⅜^ c@Ѳ^Cx4]x!p7*'?voȂxKgӁ"\@lIy6*rl+ݧy(/N"dt tH :Rf{NFQAt%3 wvIeWݩÛ6{!:'g%Q~ci]㳼AAMա'{q^6.Wrf/2Ah~7F˒/ u @Ae:Fqsûw^|*+hG2gKt?QYY@rzlnI&nmHD0/x|&is.@)6kίɡO=lO0ȡ Lm S̾m}΅)g8[`0_Mvkl<_|u?B*Q "L3=~6殜΁'{WZpn`8xTo<SFPBL f{p.Ft+UK$9G{S ??㯟0s}llXv|At_5-()@%u!%i$؉ :N'~I\{t6 A[Xg J>NzE&,XLqwhNve߇oxpf;z#d,,%_>~ꙙe,urShD0Cq fϐ+0YR6[V\a,:y1{2"`ðo)H׉ŗ_TFicq/הx["r Lp<Jd#u< D*-4'(}1~U.M)b}4F% 'mu)cewb=3v{?_׻ ͖g=}/l}C]x5]?hdHG'ߩۓCA!ʒپ6d:Z.vθ=l={m>`6u#k&a:,I&nI7$Nl.f_@e~;O[xuk16\sh=#`> ׬{*Hf#g{pԆZ, =Oy2rk翾36T{\AuTmvp6Hp-(!9-G ⁐:>To^w-HfϿ׍Nɷ8&u/)@=9쨷:w$*jx袡i_e/:;SFNT󭗏>.:9!+.<; _kYAo@/Fw/lTYxk鉍w[<LgOhʾ:=mIN>p:cI$;Vr39|2aofsptV`@W;ymGY1!!>\Lt:]2DO> qbY\aǁϠCl~7"_eDigѱ.e[ Vhߓ) 8x1~'s$@?591Blt\Fv!¸/rkzQvD@- vd5O4׎^ 91Ql?ti87,}Fz;=s`vY{Rc|K0nԸHv2ܲ+FgCxzp۵%8GB}_q{Q;]7 $pM7 %Z}mFեq]y(7D@౏i[^Bk δt:8my,?߂*t0#<|C㧂3|_7z`f7Η}I0D.w>Z.:;7[>ֹku|l| ~dg}EA>4Dt(xY(LqU Tw~ݏa9g"K~I24hNsf7(#^E'|8NqNS@^L ]$gG6fqIپZ,}ݳ_u|h93Z{Hc+y8rmWCdgn39G9 ۦ/k.ˬVFF.a6q3|Q^4Gp~ Zq9>Pb!z:;9|K[>dmszW'Zm 9LN@!i=FZj#bzՉ%65W6cfsޡ )@ IDATE@$tO!-} Axt{US>ZW,xz2U Jp? ȋK`[Z΃/H7}owgi"YO0c>>9Y9A>~#uza!E`y˨NCyݽNw>q TGKKf/">}xVݚt·K='  m0٘ő+%6 ~u.J4%Y.4\tK[HN& "=( h X¹Uǟ~s~2 0v#\KrsВ?rP95_EI$^wpR?qJh>Y6A7z(x߳f\.H"P0Cuc`T| *nГ^Oo_/{ƬadQ;#̄NRYO 8KԞv; Fut:#_ms0)U.E / tѧS/ 2ۈx ǃQ9>j$ف@/Il?wAQO(8b^uN{L/8>pV_jQyOE/'0b{bv$pM7 $[]j{>up/@@Y{ƿ *FeaO={7rn4T ߽js}p>.m `~% {Y\3H T½].KR xO6sy){'oGg?f`feWWtףC^%uU 3@g;A8x6b{|_O³t``'w.ot~Ox)H&?efzkii-#Ts-M%V6RW?#hjO wM :|`>ީ/eA W_1/M?d 2JL|o^}F߾m@6KD urXY$,!օt5~&xA&k_v7}Pd-)ЏOY;x= %u6ڣٷ~\>O`d\\@OhV|+Ul~-RvMK`O.ӑZd6Mk;f~;sm}|1@eٜ7x8` ln&Sp:L*pV_p-~NINi  u\3m?KpѠ`Bm]wRPA:]`DG+'xgu.'zI4/Pp}FSdq#x''b ו=f y{!DZwI]f:[MJ`밵q^sG8Ȓgn[uwKFYlVAU%["n\ӡt]>.-|?g!c~ɨNn'(懾fLQn4:dY=5vmf`N舷[ggtFfnHƖْZfg9ǾI&gc/?jsK0$!\`\aIhူ no3]w %p]# l=)=;7]?S#~(3 u傣^wy(e /.oG.-1`3;^C-{w#^`g-AY+3 ^X<~GM $$LGϷ߿,` Wf3ӝ5pփWSTO?^p UMK| o~xv }Hv'o_xZΦ_C8^l@RxM>(Yl=.gWV-K$$q3ntҷ gOSs]cȡ_fKLޞ _2trm=5əW:@Fc7o_<@xܑEmΝ#gp,^ue:B]eW͐Sf[ZEd0:g?gA2H}z5 ׮ArH+#< oUǨ;RrMk @?K_{nF`ʒu%l6>?t&n %."= :kpu-ٌ,ɫ*kJϦT%'߾щ,d&?zѭKpcS@Pk_5!':N7K.]|xؽ1=:tGfeلֵ$ lQ7*p}@ܨ<d79_ݐ7W*v#kIh঻uҁKjN |Ŗt~% qK.=HseW`GٗEWy~:>=7?ڿ/`}T`eªz-ڇF̟QQ~YAE#/}Q݆&/~GƼmNW-yt}#/1DCG7g>JzjKޕp̞;~;}%+t hl6xi]F,}}PYޅ7\?|L~K]N`$6$Jb[n4,gxam{ ~m)>L1K{u>Nj `W۾< Nw[[ݸl$l$:~O!]ɦ[/ kI!|}( Cy!K2tPFW:jMɗx A-%OjK|L`<) 7B*²" -=Zw%hZJ_&3#>0tR;H{6:|Hޙ}wۋƼ~"AP_f'H@/~vQUѽc^C_Z5o9ct=`!_Reʟd4wWvk !(\u`ntL.F r}nxVzcE3[tQ)7ZNz-}M.oUZBQL}ysc(0^2Z?JFn&C_e󖄩REn?^81-[<:?#ݗ6З2KKvs: K"Y$qhPvw}vnfGm-1:nlTepvΉ#zu7g~}\ޯ6ed.`9"UJ-_L`mu|.k|v: ɝAp9u>z `U~fu2AEf\Ovjf}cG o` z_cKa:BJ' .K.ߏ^Ih`vN{ A}uyguFo hi ZozDF݂˞ ̂F%/bVh3z&[J00 nLчkWWB=d n.-p5RɅP&(4jC^5 oe@܌vW<فW8.=Y}9c','*YO Dd<Uv<}&y䘰 ZKwv=µ#cI'jgZE=ԪB'81#`4l}Mp*ӡcْpljKX%n9J3 Sӌ_ E]{tBwOY ;>N]t[0%z]pJ^~LNLnrۨ폯Vbu6fcp5!؍׀o )pHz:Ͼ/ܡ?UF(!P&UR|"zh=M7lbϫ/?.G_`s,EF 5f)Rڜߣ'&#3+ǵh)}c$9`A;p,J~[_0xoK&gng|F OgG=[@$o2I#x #=H:4t戮 Jm8:?qT6fs#4uM~dӡtO}{pD8H=CKӳ{>r֚ 7zh 5=s]ϖK DtL\ާ6'B2]IM9v؃s<!W_VOL 4V =mFir Xܷyi#1rxK.K$-ol,G?զ,q N0=FeՋG?dsz Fd/M 0GOJAL2{WsӾMվ=_Yh[ r@͛<|BF?ߗG?5n$GcFlC>5B mFYWދm{v&U0B]}vG`?.~ks„˿'w1 6"  %Ok-Y' Ir>b&}\d.1t1CJ G C7Z&:-lȷ>=mc7h!\"^Ji֛F_kǯo̦vAdxbbܫ/y,,.D~?7$$oxȏ|Cٴ6cNوև+CBAb<IU^hb[Ջc$H5=bv 2`Z@rvf4|U\aҚ/X _8+hN -P  ^K0W)L>'QdYɵz_x!:`V&p-VYnVM.xw48hp{u袛CO|ԙ$2|ȷ VkݻJ^ uv}W6X.vm MFLtv]:Swβ-Ak(-+1+a>>L| p8;nrFٳ)b.gW}:ZA2cGz2hu0QM4G?v,7P=?KkGy[w %p]w ~$ (~hҟ=Oo{gz~^Fs/VǡĀ~G3Wm}~p/獀߽-y'Xpt #{MFfOB2>O[;%h cȟm ld8|~?v]H ӯ;{ ^{ lx0@b3rjKfPGKK%11>{nr1Q:.n)G9?+L?PF1_/mqvcJQOd`J%P-pXɎIڲk´ޓ|O~920#ci >hSK0%g$_IxlR/ h'ŅIOН dO޶d]ozҴzU6)P*">a6Gw!1zt8r|M<tA.\nHrd5!MҁWmR/VqujF<:Q́+'Lz' b~S\8F,u]t+So\ &|pD ,HS/`n~ӯט]uьbzi: c0>ԇK`1 }(^?,H]kM5~?5>ZR:74/83":nl+ah'Me’ÂO7!Y2>n%#-0$F6CC@zMM7 2f2rl[#RqV sl ==$ǵZnj%ι Wox,jj}࠻N[^"UlXI_/O"*<ǟg`K.=Th_x]C)7y%cW6FrN`- IDAT=b'/hEP0ZR^~ɶ'屣"<|C wMp6@- lmoAvq]w %pK֬Z Y,O=z,oՔL}Hi|W i ~mg#ڰ~"|@So%ȱX>=/;SSv ڄy~:`>Ks !P&PzAK7{'|wrܔkxDOKx *4FG.Hl/N.g:;Ѩ]Uvn?(.͂]AzuX9kEl/ȇ#Y:-'ŒÒ lu[Rx%+:ܞq$5L7/lf(>d9Pa76!$Z0OMC keUShdm⛁5;JF~Mp%r|$_6E@d1`X:V}&o6W?nv(9l%ZnvCt;;Nn~d8]`|n{Z)_C{l;T̊C&H&nw7aq[K![g;Q3J^ɘPZyWp|êz]V~k=-'%,ntu5RO&-CSF7M|xiڍUTL:jW=ڀ+2/t8XTzPѷ]`:I#[emd 8(hӺ]gԑC:K?/|jgx\ 3xy[ j8. ?qF|MȤSڰ({ KiԛG`^02e D$=57xڇSng|hSxB`cO_~x7;V#7vR}I)j fG/$L'zQ~ɱ۬5٣ţGWq]w %pA6?AF{Ӟ=ʸO #z>K߂W [)}r($k#sj tP\lOK ,P^iX|b/kK _ 'B"L]]u7`: ܼJPd_~l/x E@8B$Klg='y~6CO$ C^Ƿ}߈6棢gኇrfҋ'Y2R(ݴfWk꜄Ee"2pYЛ=ӱ1yCv}R[)xoYÇ2}7!h CG;}lh x[^ [=w#gUaq<#&H*WgI oX#\(DA I [ѷ} XL$ ʆɞ{vm&B4V$:>bc_SF%=Ȕ&:Jӗf UaZgZm߀%ɏ'ݙ%ڟgbK`.ge&F2 tv7Q:k-&6}|gw䭟ck͑OJ٧7L9 خ p |F )L@@Y0wjI"àWL>ٕ򷦳k>Dpnr\WbU`gxhi[9 TQԻWu^4A^N?ܰəq|:f,crSVo3#N5CUuM` |W2s$s+s;@Û?|5r?ǖϫNdfOx ԵZOWGp>$Zggms7dl7#k O6J] PEE_2Q~p?"G ~Q.y92Qy2Bhq T]|;[vp&R_]npo}l ڴ%yk~;z=E5OKFd_SA#dgٌie ߏK.ߓzVq ,S{ hE)ufh\LlJοDȬuچk.0!]!8/|% oYA fԱfgJ-Ht~/pE;/1ӟ`>È>_]*'W~^M LZZm|, CH|1qusp31J4ZVc#Wvzt| POOvƴ,+`vug, N^ Ou~O[u:LSdT#W ɚEZ3΂Hp_"x\bK,qk Ca4Cx?/>L~9ep,>.ωF[n@xYfBD ^\fd7=$*ח>iɸ8RZ ƻ ήJH||QD#V&cyA6A#Ӥ H*I%x48M3gMF~8m/h[o ni\>+1 a2Z}9|r;?+$ ihVz6hL6D_7unmٷl4į \Q2GKv:̀\? t=Y`d6#KK+?Ϯm5+PRuljw*=h+ %~ِk>t?w!#r5sgzQwd7Kkdl v"׿/ l OzC{ ڍ=ٌx;ϒ.K.ߙPFC)?cH匆6`lTuM=k+$ (w+ټ֧[Nu{[^`|Ln6p[UWi\pUq3lʵǵq^pm~;G(y;ϟ53*]2y wϷviF/Λ~n/Y2 xµ5=BA`f#?z|]#Kbz7Z֌ǯY_lc>,@ѳ.^mk+z {z-J|b c`z|ڜ=m6i4k(t=c^97VY@ttk5&޷$Fj#(i-mF ۰ZpgH~pL +dg{J7$ǵ Kt;zSbVS>|%~9>du_`a^?lIWw O~6~ɢ m;|u\іӮRD<| r0Y}1/ ,bȻs* Ëʆ9^`]tv<7#옭99w'3v4?~|n3KsӒ M2a@ٟV8=~ݍí.r9!,}գW?tqoѫӻB;+b`=i?7xGnPw!_/@gIua[r Kjx T>7Z7x'Z֔y2TqoH 8(l?᢮6ۇ=uݫ l讶k2t#ikz}g|tFO/7^6Dm&ėw_9zq M^?x crp!K}y=HM=\LqjR?q .]ʞk. viK.K&g4 Nki# ?G`OF(~@sUJO6kWײ ر>[㮛_)x1vG|m`q!o*[06jCٶ% Wyޠ^`ՇU#ggx 8oijV ps-4@bE]A\3| 0Q|L\n0ߒ/[F0<ɣxF'! O~$o!_m3Il(~P(5*窆c.{ex`_Q! 썓?'Y3Z^4eJLl> #V8FmAvd_w =K,)5l74l u4&AbtAp` f:,[x>TO4;]"3q9$oV١=;[Rf 5łK2g vqkfS?!ah;gsL {#pk١cM{ti 6kzoڍ$Q'czSS]𗱎OJnӵ?}}{Chz"z,kA, /JY* ,pXbg{ nynrwjcu7\r^]'gB{0GgGT`;u;ןrpQ%ES4svtCEEz-E':\ncDч\O:^oSdLnC}Nv#Q43Apg#`J WEH`@;t24WƎyAV -wkϐjUwc7S#^Nmor g}ᑾPek\H88ORIGy?K.I@0g-`1rʇ(lx{=ISOM[zkO-}|kC=qmlv@} Eev҃&jϧcI壟{#@?Zo}DԯJ@pyhَ K2xk5ڿ ]pI4ӛUm6n\~rD6[ +^M'O =i7 YJzUFPЕI~wm<ٟ~6=F+b~p*ob𪧡#dW, 7 K~h " Vw V+ZκX/8*_R12nܾ/2삑 ljW"xp`~֏G_Y-mDm.ԏgn;ww(8ܓ-|~|Uoxj?=Yy ]|$Y&X l_r]9zC~!{84z0|3rɖ>e[Ϻɨnj6nSYzlEwGdeFYI?~^> `9m { 25|CIoluM͡!ߣ06i\3-.v#Xk=Gշn</=tt::$dO~]Mgëlvqn旈jN[?X:ol?Ň\5`hB#>͟ξOiO;U'::P]w %p] ,(Q-:4[,Xyug 6gӮ*14By ]2Xg4vN7 w=`ȴf-}k}?TG{#ۀO)|[f|m#=7^oCY~^ ?߼ O6>U$%3mJA~ѱ~WqonvZjn Y}A-SEۋ- #K55,\:# {[囵 /^ 7$d؅[`XM{'Vgqlb=6-H ]4''Y ]UfD._TJ$Ml{2hK%K:9ס zsJ鰁YG=#&mO ;.L`GU>6'ߵ]G0 w6S.kCk0:Zpّ6}Ύ*lVh&{KL$2]sqQdĠcB:Gzwp2PvcBi#.z-h It}G45~;H mF VP% R&]^j{ BrS;%Ĩy0U? !/pH2'*λUdT|Aǟ}]X@\0 v7 (*{5[2NJ?gM8z$-CGB/28X{7k Г`KF! tǨ10^ ѰӋ/38FK1LV_z W["S{hx:]5Z۱B7OI dp >P]#{cBCs;ls emzl镝_!;%/fRSֺ0C;?hMù}`W>6D=c@eeի{K.K"W=aY@i_|?@W'Yp7}^;`e< ]OˇPp=ͦSi4'vmW?QFW7mFKdXwƯNJ(znf(]xoˆm>i5 ko \{hӿYt1_#6Xs>z+ؔ@(jM#Z. <5?o+6`o־MA7hI\]FF)s>Ghuߵ|2&rvTt.stzkt |g2>2r?eWlF FJ:KrԶ*' 6*g&6L~c3Ŗ]]73 Pf%, 5B]l.fH78 !Q2t3b IDATux l7-7~HqpmoP/Wew+wƱ5NN&WcAhw 1!.+Q}O;wH"!vq.cïr|ߤAϷ6^@ԍPTcz2+/ODpuf:*K|ݮW׫Lk;| JF ?M S@pX!w )ԿkS'$7xיu%G-=zR SA/gjQjl3CΈ920"/ـ`]S4n8lB Y9|B;]bj3Sw`yv ԩV=Det1 (٥ 7=L6r쵏7XoFLp{m@舖@X Jd'"Ŵ:2kC ktT ~*^bB;&w2I6x\xkv hc` |Ec3=_h٦%?it903vQ~v '}_~:5޿K.H`AO?~^GPsGMfQ8#֔~oV}k]ڦ{v(6\九?Gh+kj=%%~xK@g۲B#X@3?X)ض4(Ͻ:<=YnJ:/Rþ?y/& +Zp糖7?|hP/7֔ "燌|ڞY##hJv6N< t2^[/?5}ǿ- 6R%܌ɳ_ n͔Z-:J4RV|0qDk|R'fU8HF7u?~L_@p[%YkT6NI{Iv~}MhWҌMKM[8͂PvBh#jngɉ|,!u{hned]etv^/Gߘ)c:{797r0K&7pѽ(G~D+$+W@b+XK.~OF|=G6:Gf=yv?|'s2z'7szt4E?( ^dTeO?<_~<17]}AuϞ\-`;; `"Wc?`txl҂vcY*O-;~R |=i۷(QKl5#h#okDX'?#x )Nиɇ<LTno=?4osFD-0J1^gC $KArLOK"gv *{^ۈx~DM600>K aOM%9C<s3?1О zeFAM@>pwI ]o{4iRҙў|iv|xA fJӃr`&O~:l68Ȓ1i0l]F+3JyH,Lx` W)aʵ^zp`N8@{eCpOS_v2C;A*O.'XugڂGpM ޫ݂Y ?:F^"&nJ?x5=JC` :tynx$MpM}(y})yUKnmfP.K.߉<~'<+1&̂iقx pX\7v\0#P)ׂ(NЍRfz>+)~| {Xhat1_Wb-Ыևux7{6>Aհ)b9_tY% h癩-{rs,0B5|6?\\2wK_Af6R 9h@ҞF| #0;:nS|9/[*o?~6-8Um8l F|Ǚ="BomM՝=H&Igo- ANɐO|??oɈdl~k$X ܾ~[d9cqt|cGj 1%Տp#Nglx _u +Y:. fnz jYȒ4EkK@& $m$58o`Ro ^~Q}|0@[yF|K)/[/:;?۾ڵ.+D 0k-s: a 6.hN(,LȔy#12!-f PEU[ jkjīu;t"[uGomI|A#k*8}unLyrqv ݦwPdn>#M_e?~"Y{h ?`VfpT0Q8l9ޮGsӫm:q1/w8q@y}707 +e*xש%Ru|%|,ѱzڍ#G/_8k1ٵ {(>3>GbH pp?sK!=\t؀%ͼ>Np p}_g?ؾdL'xlzꚎEGt Mty]AO2l(Btmǎ׷Y@}& Oq]w %pGo ?,8zQgj@# |l&kYjFOߵ>s <>|O VvvL>0 $#rM/И3s9z7c.o#!7WMmzmG1?|n% n#A'26|wO%ɸu#'+`̀QOL+?O~ >A&2N`:k/* O]_΂^ /^Fϳ^6Vl١{Tt14C {y8Z׬2(($)a>Ǔ@{~dxgS?o6A:GfVf,|$.ح$$\Mxdw!ɅV_mhTWRʌ;T~fƳ-:7jZ^Av⮁f|J$oC4ۤ_xK$X.ශmXpG3BіNw Z|ʖNdWGyۋs6X[</2*T:0 kGS~Zo j hۑawŔ.,Z>܌b!acz}Gx 7\h'>q9oiս c$ױ[0&k=w H|و+ 딵킒7ܶ4 K|U}|tez_2;Zre:O .ixP ~2mpoA$l-0hkq[z$ړl*o'@w4J |X k xy}߾̧,$$nQtoR}o/OP#O]7rhK# 0Fq8)"gQcPZm4vl[ /ۖ=<+7mXgF>k U%nd_]wr %}4F.Iŏ003!M- Kd[FoԽ;;fb%;l$h`X0(vkoov4Hxe|@>'kOU v9 *J8&A3/5yF?Qf j-O[`SN}[M%hj dtȈ {ggQ<óz uc>O40Du)؈DlWoM;h.i|ɐ:>ˀW`ԚMGFh=0o\, #ç7x̵>funWIUGPb|`hDGu)9Ed3-qG{o=_&; N˘wCF$i}䱛A$@en8f=L, >)ɰL7$KE{7c\dɈVf);@m7mM;j ,>;^*߷Of. čptxvzT&6A']w %p] 0]{KܺC>Zӥدwvm"}F!k,-CQm엏1m/E7k˯'8|܍? G ~rf- 0ZJ)gk~htujyϲ7;2AA^u%W \]G=tīo1%d)@Hy׶a<ْSR#M.X驤O/ڳg`骿 <$#POGWmsI 8͖knS%ߖ k#Y`6q~6|'+ۇoIF)O0Sg{[%1A6,>=u^~}t'6<|S.?O 께,nq?}Md8;i/-0=:N"`{8HgBaͮfGG39b[&-M?9ԍM 7#h:F+NyQx1!,0rv Uw{ F $t50M 3:w'R4v~>~&k8G >듩UnzYa0n*ڵc5ME6\wL?mDj#PF[[S6*Z?K툈^2zyZ_׫/ƞS&ڑ?~]`A7 hl]Mx |7n:6͛gC7(^7=46 2`<.xFoW9d2"jm <1*uNwp?vĞ*W=fsfU M_JΛ=nF?YHU<5܏K.~8S#sמ+yνvlj=;{VVF@5W6vkd_weo_z H:H}ٔn<>>,觟=7>$Vcm79 Z| 7}\O^T;[/Z,PS5#fм/ X^'M tvNV{[ܟ6`oJ?7*/vA>~bT\ mNa`D_npm8%H+I* Rb棙.>;7 ·{Ad|Uan<ҟf٣ zL~!DX/tcI4# A}{ Ilο=(;.y=zΆ+4a M+z>$*R>xևp>> */p ^O~6v.?=zso#7}[!s{ kar`#>+9]s?g7;NЀWRQ l9a]W> &cw?'H"tW₈gMÂ#>qF;ӄqx{ap[_ψ>wtGx<9uY_q2Kb52Dhkx.>IpDCl2" MXfb s?o;9^SNtã$Xdd*M`lzWbf7kCh<~30varu bUg_5mflA~7Xygl<1=WdT;Sx+qhHnBF:QXbVuu:t%ڶcgt+;:{0o*$\zY 7"{n qCt3]-Lvn* IDAT4yƛ~Jގ٥d_3d'"MIޢm5:Ѝ_wh!HF 2F'旿vLm&/4~%p]w %;[[s]{v7YPcE@`xL6X`Q|Oψy_oFK! U> UU/؂j.Γ?z`ٞx{ڈ,+V":{[ 3\hG}|{U?g:2u~,:o~p3_#`}A26> O`d@d |~'(7]L;#BЩhjK д :6yeՍoڈdͳ&>o$> 'Adɓ#bf *`$$Y,Uxk&>: 7&+66XWԖ]^x[b(O-N%3G ,4HBl&4ȨjE9Үl⳺t8q5 \FaNI^}ZPKXffB 4]]ӎ'hlj@Λ]vst)~זp"щYE9脛z]Hh)aQ|D X|訮gك:} w=k0:}𒬗]ꂹչa:`\pɚG׌M+LfKw/ozd#$I7GEpՙ>Hg7qxj6@Ogq2^g &˪xln->LYG ԉZ38J KC쟌)}ud/&۬Cwؗ]^PjK{Sj6nTmL骛+UN)ٛF6={ePK>UFOfi_@9\cwwLNsտdYsу=q]w %p] F=8ڣ߂)/[ÿW=7_~ƀ=豍nh>њdTc# ̌ ~{ 0_ݗ.wƁLp~?kC'H=D2<ԒOy ([=`MtDP"o69S>h9vAbڣL|/SY q<UΧ2X O2o0NRP_߉b;| V|} 赗\87߈qtO'7CU>D8 $#]o'IaVӖ*lfFHLTj[2n<, R_}~`Z:<<^oJB+8:]فG^Uh&$4QNf {iA'bz3A}3[Y9LJIK@Z$1[v)]??G] "Y%+c8f_m:٠QPsKd%{aùO0詂D١ɲzϹҫا-T׃']u&:RAx"\z0Hǘ\p%~/Xō`JID dO^6޴C}FO7QΧ~ƕ]i.htZ9K=F4`eЏ ~a#[c-xFfхx3꽑)] z eoޔw$ čP'/؟ʔ]x҇Ѱ $K?n3<`՛V?5mK U} SuE^YA%{0 OV>ܬ1q]8LdMv0?]r+?{OmVN;qsOv4Un<n4B~Ko{$eGk7'Ҽi g_043Np]#?K,{E>y ^[7u< c]˿z]M`Z):~}h6($|oz8>IL7ObVA'p־?q 2Ț7e+}bo|s\!g6‡wb j>D˖b-X7buf?7ۍ-ǒ۷)-7m6s$p2| n?{?嚏ًkY5_С$%Q=>7?~<`~o}৛NO=Ëͦ3Xx{+߷#1&q: FwC>]y4^vv@?}S2;XBW.^-ķ*#0bz ?g:>\ý2収{^}%hL |MZwt~*@fh~uf.tVduΰGOe8XF487^ %6'u,2Y[20=6 C:®W?:܍ɎL`UNfċ@.Ob+*nBDmvM?vS}?\~n8j){>%#l+ Gzw]Rz60Ne ||dd>4,^_gm/Lódlx d63G|[}) P{8HXRe#؍u0I1rUOMnjI]W_p(^Ir<#wm8kK}uN sc4?5b>۸:37ckNvmtXV%\9CS<+볎Qf'9pqdG'I#g zOqկ\rg 6x>tt8I%;$8ksxXoI'pEڏ29yQQ?Ė ƙS+}c4Xlho#՜^%8 $v_:XtۇɧvD5ӂкs; !O'Ɵ~.@w %p]w $.6Z,|=Ӿn׳ͣT~};]`Wa;/`oOeTS7*]SE;BMlYYO~FH9X'K;76-9Uw[cܧm4xW7@r`oTf}$(7o¾hJdsg$k g򉎞m76M]ȫk|Tۿk_!=}Χ{;W7E!j]0ܭym&c2|׍`I ώL2l06 t[O$aϮ{T|7o<qA- q [֫=<Ĕ؎=f&#x&`OFeͻ'odv 6s6(KT`>jJv 5{Ҙ6gڠ7^\μ9 ieFw} M]6 }>fфɄۍ{IS3fvnGɍew|3d!]6Mblp[&tq]w %pH= {T zJ ([se{gۦ_㏽] ,<+f= HZ# o2'kҁ2~Mw˚M݀`0WUeec+m q[o}i5N0ab:7_lS{Ì={֗ߦl!:||{E7@0e׮ x-o|j7ջ3 pԡk{A'“UNYYz&Z?/@>ؗz=4܈]'_f(]Ǎw|L0|>'%< &T0mdW#ȹ5:g:C##C@~]m_M ~3^.#xcCyN6_Oe$A.r`@G?L`N@zmzpvaWP.C.xYu=AS| N_BrF)f O CF<0\1,@8)xM(hn`(3i*U*(g Wer_Ѓn}`'([ ;=StwJ$+p6"o9wڧXi׳p˫<ܠ[{ϝ=*+ {MN=z}T5\eiʂfgld?{zq#yYf[5NF ?*C>mx>}90#b<8تUq.Fcp Ya צ'׿00z*YtG:!>lPPy)Y}zwEdq7#ó / y(c=e.ؙ{v?K.IʵAӦw6 3_bZC> HS3C^dARefofoomRg`W=v6=yQ_BSD(Ǐ|=_ .j[Ƈ܅Fm_9 vfDF٩>jT]9~%A u:L*\A 7!:okuA:uZ'۹? `1w>vq絎A1*:=1e}'=/F8֩d񐿋CA|GȥÈF0Ȉ'/cBwfI]WY{eW=gGO 2[2p?l T#[JL.tdOthGzhM69:t̜T{s[tr:R-OQL; +9,d^uV$<_KߗYw}+6..K7&!utK=1 BF?2(:xS>}񗦸fC~ȴ]BZ`_?µ n SX~ @*kNQWM<:Kae(jZߎo ;ܫMPA< 'hR 7&Wn&HR'/y_VrarO_6@v>=7FM_ g|ePq82BBbIdk!5/Y~#O @Y񁿃9~6ڜTnSv|\|8ɨ[ 6C~x&`!FK>k`% /i%NX}):+W$Z#X}&tQ|>u2l>xfu)Vak,IHA^tCKK ‰csx+&мo0.vfGPzI-XUOMyI`t,]p\zb*'0zC_ d&0Ψh;E~ay+KNFK(Kh酯S+FD7.K.?75Uumt_mhHw~oۦon~̚N𳎿feKT5z1BP` ˹ȚNn@ e?ˏ%V.X[!Ѳ5MlU-(ڄ NEqUAbrB׀MXp6n~._^9Glvr޾uoZ f(e%;u1wϷS2h;4G>=zü9G΀h/<{ 6Ӌg|po)_ǁ@zAI]>n2s$?k]',$ß?Fݔwt ۆi}!X@x{pvܒ df6|?38/Ih~{>|x_ ΜJ:.k?pů.f 2lEqb63s+{{|ũʙAS*'1N6x]͘a)=cg\7O[yE@fB8ւU=V  9!.Y0A_0xU4yv<auJ- upi(̂hƋ~{}H˧$'saY`O2{k:fDcܯ|Oѷ (<34ަ]>bx ;30qO_8@&׿| ._"(h+< fD6,$O܂}*MltwF?7-dOgf4?ƋsgiEl^|yG?t|r~'}" ;u_ﳂȹ}`ϒQ[>WL ɢhe酭0 Eq6 ,+u$7G=8ڣC䝀B@vxC]Oy薶 խ$g$?_M+wo14D?[,> v);qf@ lL٨u cvxHqB ]-CZLS-Zc`[6rN &o-nH#aB #@#clz IGC1Ad{.FP-@'* 0\`m_0uZMވxAˎʃXez,h*0bp6S&L dqz ;B": 3B2;+?XU .*n6*Kkg): Z1pOH-Y.g49Ƭq9[G蠏)lOkDq`wl)D(RN4AɓE7zhֻ~#_!<. I`tttUfͰ5 \gPnzT# t['}/Wuf /Os1[ DY gGn:]cGbs^x?K.I}6ZS 'yojL5V^}ւ}ϙԿn/md3@ n8Myfh/ *zZǦgDصШ-ש NP;Yj7ͿTpgFˇ҆w gY[F EIERi?ɿŋ@e8N|d#~7gF`-޶FkY]Щ|CӀGϧhv׋%|-h)e'`ϯ g^5s)=F O9jFu:i*وO;}qqE'x%}6^iLM6͞mm1?= w2yϏ~C ě)ӌUGDKV ̛UuON0ѝH?o`(lޙ-+(d+dzbCIȢgr܉7ȫΐ2fĴ9]2gWxR!ғ%7Jl>,3]ye}'|'{ZAmD LIGc4_%ƹǐ2d, .b yf 8~g` O? ½kҮWvxrWx5 :$QԭW&}S@ǻrtɢ2~ݔ}VJ90=/Q4(Н̔n9eQ4bs;&z6۴R&'Lm^Ui&%2L~B~5F']8QAGK p*Ⴙ.ǩBhفE0 dXO^IqMV/B2MC0g7S=?Mr* ^ocOVQTT M1 /:薊`V$;볟hC:t=W+8l B~e?`DJ306l/nϼ8µơz/ߧO糘hſON*BZ>tϒk,b{dw:'Ojz]%ik3|nj9gt3O']w %p] H=Gf;zͤ 2߬Yqc%Zf)ǭ8X?m o&oC9`*H3A2~#0b̏|bÂFmfvՌyf7d?,|f׀v?>XULFPr$G q-f\ /F'`(Kg0ѣo~hx㡎 xCCD2)|{3*Y1LOF:Lfk-)am>y -i Dm} KC=i~7uO/Hѯv29=0>7 |?>ۿm6Mi.o@z磛%o\jA.>~7kBi<?\dHl:~*cVDBq.ѷOVJh{Mշ?nրNtScN2 ie]]E?tyxVa1LfuJ$oq3pcGY*,Վ u&L0!921`’M fs.CZ{~ DByEʋEPcR+5z2ˀ &,5SȂ.ܲ+ۨ)R/WtvhKj+X6.)\'ϡO50 8 ;]ig2&?3y<{, ,ﭓGpHNݿῖ]Ypi}ċ´댰+,zxAȈv]g _e]R|i̡)vxסNhOpEl|WۗeY-zTiL֙=VpЫ2~PЊmy*,=)Or$1Iͪ@GLݳ?o6 Ѿ5hݮ: ST{/oAF+o wW0- C X^2//s߂t\ R\%ieaq;<&C|~HIO^Uq)c>#%_qF] N %Lax<k#`cswq>⍞d5 _c2 ˵QSON/KN=5oJa0@xG۝LsF X LM:p޺۲?tϗGw; =ߵ:Z=Ss>G mxe^u-nZ{\|0C5V)䎖[mP#B0aF5?64lWu(/kWP+ᅴHe|uP:\u@:_衃w}`5ͯoKD Mk ȇ>VБ#‰7{cK׋S0 ;Fnzi2YxXmJ!d5|TV>QQ<`enK,1XP^P^9$"MO dF |.A vSqiu&,O^fKB}̈́(i9K,c ,iMfw]2b/<&R:3AiG')Eΐ1ve:8|U]:$TW-=I'x _?6C$Ŷ`gk_7,upB2 Ob C'X9 =G`ʴRS`0N0PApvf@ۉyB*4Jтc|tS d<'f.K.?jFE.}zNϭiyA_r\md}? |FgtYwk{W12r 0_Mc/@ygaQFs 8_~)wY *?!-Chw$"_63w/0䟸>r艀W+y x<-l8@{#e9 IDAT4%xӱCkw/2|̷MOWO''_TМ5~'2zqAxYaggG:~.;:.ax | =lOf#?ۡqp#N[c#g_u^D#n6c8ԧ?oFus}6Ck 9yf|엮[~wGXAyqwD?f2,N̿WKe`xAu?gON0Z|5Yrd  &m|hY6lu1%C:|hB`3_GF=97! yO(ܙv=uV(^ Wm1 _ >g&ȚTF#58FMuxl3(xd< /j&"J4 &gIݯ|ȣ('@GL8qxe'R~-m/0!t { >(':GC}yu}g2C[΀JAuDh|ᆌ6/ANq`<r6k u~C>U7ЖfjLFL:>h]+#@ljB0?- ·? ./ܓm}G-^|vp{OC8+^jGul6A:lb?}ol^}] i4=gQCI {Y瀦| Ϳӏ=;<\R^vzlw+X;7[ OGkţc2=~ A{twpv>ASDM}\G C6S0<]~W櫌Ѓ4ߙ .z>%c;#!UNUP}9*zKQiV9*Gf.#HGSD/3ʭ(l묨lqtbUF:~ӱs5h(q;.k~&=Ti>iNiZ5N}یO cmӭ CSCyF=ʃ7z|W-M~4濾ύoԽgANM=/]URG>hB5gs%--9῕hǧrgGFrW|_+ǃ\f# moBj3[@YG [ a6@l<Թ1 z| k<{F,}@N:22]{ldΨ~<'udCFlُ}Ӟ螌~: yK66{t;,9ؔNdX6X.ngO}䯪Hb"|[fR[|g?%0dTmF2^ N_ Z f-+.\g+G &#edoy4ozHd{|ٴĝlLFٿ7[rZv: yJxOL3rI;*Av=_ш,Q1Zɪ`&!c~lE:[nW;ߏK.D(_]A6367M^ &-.k'5RX;M~ڴq4X}# 7jyFM(_](vX?0JOPh@%>7oAy FÓ'cGuls@ʂ~~:YiD+Qɓ8ԁqf=gpoӺ' nz2x/~m7D汇f(۔sw?4s3?uvf(:mD4u t z&(Oeɺm`=fBOû u5K? R_;MG0|_W!L6Wާ\ :wԯsv]'0y9\$t2-sX$|&Wj_<^c}=Qz* Hp7j_yeоW_̵h 0#%~6yqjEpUA݂w 6%"tS$d-~Cڨx+`LܲuJ|{ cU(8z6X:C?tF[tm1G8n]/ӣ w'(9 )W\p& /'7ui fGP^|F ]~~t/trҋ. {0莎tclmф7oF늵Jd`=l˔}*+ώ1ަxAg2(g >Ȩ٦—n-Xu;55;a2Kr!s2/lQ/@7˥fVЭ|/8xEɵ2o]tzH:|Q 7^p&{!7g!9TnJ.{H{1{iȻ~{4KقK}4|Cz+CYA~%p]w %瑀 Eh#8A|BO@ϦqrAGSM֤~2:q/p/ M7~ _y1~ XFO;pMnc4[w_*"զ?[u3`hh&ߨx;do{~s(:udG,Bخu<$!?`3c9|FBg^tEmpΕp'$s6 f3kcQoPzـjO!m*@3rH>_.셭~MY÷u$``<Kh g{rs2e:NP-'״!OyQ/4xk:8ßRzNK( $]ES>,t | { ^ UF|&|em ׎ ,+ldq3?kƕC O~]\OPE'M^_32<_. aۗ @lO'x-[tt |cFBpцOdTy=U!hnɺ}*l_wwxo_@J79>!lI%|ղu dS-{y{yGBxh]VUݲd4ּ @,`I n/:B?/Adܶs]Çm'oד^L\cR]ETT\2F:]w %p]2 l ɔ ¬JmÍӴ&~HjQ7ڼ L;  fstO/T[P`(^# Yp0ꇳX'|dͷ 5: pc]=zоM6](h7BLj9q x~pD)3nv>xoh 7>=wBtI).dzR9/F)㭑zS;~,3O6vС`cWȬX_n[w?9 }JFtKaSU:3AY_x Yt'Ywr ;޵y#Ӯg>:ezϩu{?gpϋM&x2Pe6Jehp1J~)?E0Y*v(`W (>6lh ?_Q~=SGEWia{"I@ցXҫo'؛͙YS{}1ƔRHYbSn$΀FT6]>,[}JgT!ܹgB@]F4$=M)eAIߍ3|xSm4.AhS6KFcXpBFʌ>G[2:{wT|ġ_hw_v!/ZGWLt*䁖WOf_k=zs 񨂽4}0ڜN\)StzXN*' X7^6Egʻ?e H/ue74K^7UN ^Ϋ([Gt҃O9FKg_|"xg^,\` s*N >#}W>ّ1:N]w %p] X,2 k|0wJӮ >>hPHk,Fok5Y⻽eo><`rp5Fb^p1dΛ^amPx F+f^P7t_CrDx He;,:Iq1}AћW0`\Qt<, /FEjί999[p[|ޞ 7 +t>M'nNP!A;Q6[͞` %6>8dGϧ/|T7cr*[M,Q 6՛YF/6ll:l6Nƥ[Hdƈ/~A{>VNeO˞_Dsy?1,ggd9l ʣsL3f,q ŒA&p2 T|]pNgY;;["g;%ŇkېY:>8 =,ȨW=(+Yf AǫdNU[s>L 'HDJn+A6*Ge ?yOq1.3:vȃ3s|pJg{B=^ђ1ţ*:$ Zwx1h&#}. QNF=[:%C3EpV&|x;A M˵]o M`6Cܽ_'oxƧ- ?|>}F z<2rٷƦoW>:y:JS>职tзD}!3[ c[ck!g2$^Bt ט:l|QN77ܲOOst5"W<hxmF+spр OИ\iE ՟>3|=!FvʍtQuށ O?t?OlKTD{ 6[~%p]w %g@aZ']T;&@R>ky6,iÚ3/hmtmg#88jO3+8 -_0Z''A _@gA1 6ROu ,-/42QMO<?zԑ1w,x B{ %LV6}:G0FNr_`|t|Kn`X>pu>1?\lM{_``:>'0as|h؈nݣu2I|eO?67`3 8<]#h8Eg.g_Ӧ;!i3tl2]B UeGM҂:ױ`c2f؆>gwuMn)K!Ia m(Y:'[>իh:TUC6&n7}aYcu<]2BMQ͖Oa:P' Ebi6?6@>ukI~Mt'63|펞?IM~Lx?#䇁`u5zITP˻5 Jbfh` Z<5u$e2>1|t)s;BqrWDFBA[[4%_01$J.tlt'*+e=eƘ&#U:&; :2s非~m# O=@ tA"c1Xxٱt(6~-_03=oGJS :UR9^,b6,t?ynS#WуgS:W~H* IDAT oV$t?9]cKGWɈ:E7xOe,J[^VƧ;u ,Y' k4 ohx1,{I# y+{^V=#n׫_,eQ#4uA.K.?" r_} zAv{_)}Ld! FޞYsʣG/=X˛f_3,;c8u4 BK恧sm|ΗmkA~*`f@;<W:vxU>ڞgVF b~w6T@Lf$SYt,s ݓW|\22y"#3޴á[m  |u V-9cC6ҟN0@N&MGA!dڌh8%֡ n(z'M]ad'O`t.B'!B0/,m;s"(‡hX \s6r'xJ!N/0;Xޡ xCe `3n 'fc(s:1\uP_yn4]Y\a ;/J_J_;4xߡH,ع/h[9dI3x${e/,^|2?5~ cxl僝?u~CvyFܷ^vk}~H)\x{ C>O'w۬N"x23xB9XG'yכּMجi7Qh8>[ , å;Օk ٧?4Ob~~S|d |68.F{] v[Goߜg{~l(чgl4y,x"u fi*Oߏ3[Žt3^EC|Fv-%,|>^WvYg ۣp 梼xa:я&H=vDxyϤ?z[p +xdDķ=WO$|q Ttʀ0Jy;NOsE/ĮT30G23F2M {6ǀ# 1̐LDr&dqn,_Y!+1rֽ݃'/|b6r)`c{ H+YoOm2Ƌ!j<:[uF#/+q]Ά*{e Ӎ\{-3ltƞ8S2PWK:L&O_}[h"H2;l;YI=e]{:"tr񏽬-^|=?䯕U3?EE?;V;)ei/u-Wy\OuzMd`㭗0utlGt3u:AGp= [0^~:mК={"lv ^cpd_5{Hm Hvw %p]w $s߾zUg j * i"O`ͳQ\/v/, ƙPYKoW H963o8DlL>cNF<=kڳ`EfWf1A>|el>x=?|k!o{h_0H׸탵Ox6Sa;ۣy߽7XWu' U/^'# `O{זEt3GYwYs3OU/\`SAg@53b#ъ-D|uل= t8-СAw1`&6vqǂƮ}Iru8|Z֭Fdzs0uCx'5mkK &/}fFm~q<|.i6ܩ{qL7D`d-]+Z?'lSh?Y]}aN\$X/VѷlQ9ti41Krz[KX^MubuaQ='1twي:V>+[͐;@_ "|z,KNiS{Ʉef)%M@./FF.ˆBձޯG9% |L24hWN[OvodHGQQVv*&e8yF^<䛌/z?_~0(}@݀)9uMnz V&Wv{6^?LSytMh$ɨJlcTHcԗVٽtȣ|oIcGmTw+t 7좼Ñ *4e+w0񭃥:@ YxhCEGɬgX/V}}᝝I<{y`_2 K#<Cxʟk6F֐$cNkFpկ&[~Ow %p]w )$`:5 fkjjqdFhmF )邧y: \k֍mdqyki ?YnTՈu2h+,4gfA~Sع}eB| { ֣Zo}AE`mZ).'PF|ui/% A׷r:gFzX@[Mc_-Hn i  ڃ!.u^̀&3K0)hSm6D/]TtUyc951`~O[|Y%xOWc/qֱd6+ 2eڲ93d_tz=!C,,O|6geNGE' `p|zKWw'#hT#@ً 7!~0e;O- syhO7p-߱\W3owISBKp#z/xГ%!0@Sp_{F| \_p88` FoM?}_Go$~:{ɐզHKT2Eɗ2H6gCgexb2<셭,^w( ;襢@zFCH>m̜ܯ^N~f|Tzp?K.sIQ>W[esϵc{vin^`h\Ȉ/nͷA덴kWk2˒|@Y~AQﵽ&ӁZArtZ=*\#؜'Tڂܳ6/~!dg"ct:qF5(-&o=GKnM;GCK>~,F=o]d'Gv?~ZnvG8#ՈqDmDx?d> 0&Ƈ1fP{Ct<(`@&>-_\@w!.ci~Nk8|({ 6s"`qyq1k73EGod擗RvAd}[,fءlB3RUvG_)yן B:.o-}5 uHXd4;{3 M6lѳBAyxy}d[fX\©\ ;Đ 43Pz||o=M]?sCF k" ,TY-s30Y /sf;>M!?Zl3A.F~PE6+5?+)6j>0w䌶g"dܧ|gVs : e4lB7k[3(zv/h֩dxiAh-b_'9}s wu\$r@]w`2Jnt2򷓗:4x0즞r_yA=LdT>he0r>thb@<8p{x!\0o*г6:o߾!cZ'G3< FO9ǧ83|:"vͱxl_gH3btɃ e+M=Vܑ׷r]~B<1N*gVEM&H00 n)-`);zI;qzn67[YA +pLPˉ-ºhK7gQ`G>cZOמ)߿y9dL@g\|5ؕq ~ `x뚼&#/Ч`2Eq#xxr)9D="\#K;3Je$~ ^c_|[rkg;;< ,WQə\[^7L=& }FO=wmʖJWᛌfH>dT=m2/ړ]WdO΂*wdi׮Mϡ?o< {fhmӞĂ'XS 6i|QE{OVsi3-}mE6Y@,ښ5(m:7㕳y ^܂F&| S̋YX<4L.~ƇO6/٩3wtK>A9>~gߖP  ]^o3= [3.^L2Yu]6X}OpܑX|sKFo) NM}ݟ?tDQh9"oA\! `GhL>%K\?4Fg@XnI_e103y7w#`;ǟI u b/ 333sʒÊqb z sew d;ҾXc7:46+D,Y+vj7T^=l ŏd;ϊF_0g_]=~2B6Aؔ~Hԇ 1%Y voc瀉ˊEa ֛? )l8&$Jj\_]ʽ>pL,g;3(F&[dP*{2A\V>Y2pzxMQQS.Zy4E1w=Kik7*l+3NKzsr;к N@Yȧ"Ȅx;G*JAt//MYq?ۮΔ47=G_vQ'=Z 3>m!9x#l2+\>ܽQGhv,1{ /`gWd":Ȏ}}h{<P&Ok?<;g䅋~4f>ox(cdp,ǧ؊:\Cg4\r^zLh*oqүzm`Kpe}t܏K.ly_pTqS<曗^c/F|픾|MmS6W㳖H)|j : O6 Tot~N[76"_t $`~, @57M_> tFu|؍ *6WM69N ySe'ZMֹ~c~@mST!aaF C~Z$ICG?v13ZGŽN |'2zosv*d?W{ IDATR} B?h@__E8t[3 [> O`٨ƾ҉\gF8O=&ot͆.} ᵜMSQ৛~FAѾ r"svG-y?H"h9qldunI袁-MxN/pL;dNJ<{Si:y5ym;": T߳Ȟ9f?kZxUo//ث3vRԀ~w %p]w $g N4Y[5-Ap{&K 6ncf~k|DS73tq+y%矀Sh6XTX.MFm _ בy|m~OZ|isl494gMG N_sךu 2'4o=m] <Ŵi[!o? 3,8'ƈ]YԡpE[-Oeg%|$2=}r`褊t_/aaVopxU,P9& x>PfF;Ͷnz2k#3_[WMs#>g037g+#[Y $0"%!39س:cC꼼=TT,OroI#+djYCd@, ;ُtEAo~a #}ꂴz WMʮLy})M_/lp &3 { `OWnp.tJ[to{2=@]*>ѫmWL?a+L;k/BoX.ہ\ʺb17OEAvn<6H~]6_&0Z+ Wҿ>ʯ(o6]=7l-;Y@_gؗ߀ Bmmv'Fڢ)[rpvKɱv\./F7l胝 ^]Ud.U ʬg>^Y`䂊O.{`_|U,䩎r;wKCwۍ=W`K^'k^I &7uE Tb~mޖO/0cA菕G p4ï{ [ RyMM PȂW v^9rZfn6ƴ^]'Fq0d>Bx~FYUyhPVtt2nJ0N/uj/Oqt!;, ^x πFXʝU zB[Ύ vXd6t|{DlYz(@͍Sj!{?0 ? 7+E ](䛶A>_N+>\Eq'sE9̏?8^gL] ~xrbs @Ds/?wfnS=Wӥ[y v `+7FEcwyMV4K;6љ'nH0,w:g)en}0IU#>bauDZp%f2c%+GSpֳq$h1ޮ))0¸rY2A-0+ t I ; |2yz{pA^4 / xhM+3Qh&YY{7lVTt_Qߊ yюgW[YOVa4붤` ɢ=k{~iɽ'v"Mn@] [Y\Vp8eNHlzG]x Oͮb:lEK硉S/|{&;ea_~O~7!lJﵟCtN`{dn3l-/vb?)g933dמv߁vV38X]܉ aF'yvNmkH/<֯K֊so@Iכ"[fhW%~)dsb1| Po|1w脌9{_NzЬX1)Wzf &<E6` my5ˈ5ݪ3Չs:ч'|? }~ƺDu?AFeg;mu2,6А.mljg=V_5B#ͪ.s37NtU~2xg/>u›z\No{< W=o+LbLX.r?⻽fG=K|b+p\SρkojG!}ڢ:oxk* ]`eEg2]+:p w­40ܠ*7[dס#pG;y͆/h;i'6np{Yd]|{ ȉfyKo nhl7c/eoAY3[^/X-_8ӱ÷zkGvt^Y{2@eJk{Zt0[k[ d~[|pH<v mUCwO=~٣MLZoj &~TІ|8sBs}oAOr@7!O,LqvƮ6@osg1m_mq|;??m23ᤕje߃;Q40m_y <<|/sr@] S=m aCi9rK ttTvJlڪRXg!31\e6Zl[[ӱ~SzE+1Xe6:qgu#0UL~$e(Ì;P| Qa`N@ {hۡ$Ze?pbB^z443A=i;a)kgM,h9gxJKw@f0}h<mxNV;];~Zuq8*Z W㢑>j-N*6et/bCγtHvr`y<8p%Pcv]lD8fg Kzyz+?1Ie:7 ^QҮ_ʸ֌;X;bvy?.NxF3#yn$ll)9^R:u RPY}|[b_uqVg:\,`DչlV 0?:b#EOid_e/6"z0rOkUYzO׋l?6*oY2ֶ0w#pG/ P7I վ'_5;̻ܽ?6{v>wpﰲ??tvfmy`u~ lje;?d=~ (o-?Kc36/hޗ=Ұr60nip6Fg]0AmXM'w e~#M=f0 NVLЂp3ͷ_)N`'3m+¼dW/ʒ+~u~:Q0>G'"{{iʳp4ME.ϪqdTFC[)3J-N<+sWMkW]ɼeh-# Ļ P~P+z?+~Iv@!c U\8=j4`2G.:*(Un,4kʅrnx6㛓y\d|屨Vk޵㛟fXttx0:lp'떉kcD5Vp)8%-hQ 7CZ#-Ha4t%F|4.k^~P9=^ɶo YJe ~fy `~ `z e+kt4r',諸/ULg5ȹEBZxO3@瘜tf͈j7! ј`FK] 寎2>S:ݎ=*N1%&-~|EۅgUvQoPHǎ0b{8S-U}*7}o-]飞չ(qNuꞋMN; 멦f[[t]E)64 h.G&A65QLYY8n0j_ꆉ%{a42:*~yj URV@fx{j]Mn?Z6-ـ34x/;w g5GܶCT0/qW 4\@ml^wL_̬/\6g̖ m*r~ uѾdڭy~?`a*X4g>fM,>[Pmd p*X2mS[~&;nU}}tm ?9/͈K["/{~ >Spڧy=O 8:wH3ς떹7fFܪԷ|Fj7Pwvx.݆_n&[[ye.}'g6xAZel:)dV-]`?gEY9*npLO{d~{ȉ%h}w:Ekr|]M ԰1*4 xuvnO|Yg-Pv3bf gKܿ-x_!"듂E`4yv}~q{Z9mb}ԣ8yyQr5n0j@YoCU 07chӏhªDžYt-*3[Cw$Ƞ. 8uO^Qߎ%DKmw0zy^۩U#{˓>, VvkvrjͲOdZ'=#} Gy_տ]fud3]LUWZ) [v4}9?O:mYP3nLnGӶK{. [:n}WrmN=o [{Q:ן#gX>H@m,FT5Ю?62ѧ:?{Kt 0z"=GFcH#pG;Y۬r}ZW]ٽn{|31YZA A_%HﭖV һg.H`̸{˛ |eOs3 -P[1qkk2`>jI 1 {jOni zQA@du83&h +yD*s}k- OD?1iͨ_p&US{NmGA3)fW[B_,g#Xhv [qpM^vY|v_~M4 H"8_r&6 YA{97@yޗS3{ #j/v6c7g[?uN{b'] "^Fb:6)*X~ 3!w: xQqQ &y(w32/o|t%Nto pF%xhmf:(RNc ;oM l@h`r87%‘U~a;C٦s6D[0=Lԑ3ڤ =Vn^+kfX@l& ]{lumpNxߨmPtlN)z3ׅ3|u>,չ:VO_~,$&xVFE6@/u12 O;|֫X\@]d"޷yn> GetX@\v2}a-ޠL/7_ 6l nh)ްg96w%r>J`3Kw9ozbݠd-[nC{tϡ~?٫6#pG;Axqs=n;l\>6"{}ނ| KxƓWdoۡ]8~.0y[7' [p 4Lg8'.,^|n.?NYgnCY;aw %S|,o` <߮NN6;e2v-ÒX1 $mFѵ K{[}Q ]2Y`Z= FOvO)~VrK`oP%?u$S2ugS˧ BeLu^OPF{=dN IDAT!.hf0*+7UﱼU|Ըe1 fk~txθ ȵ;#m:*SEɊ\uiCo{U [_U"=3;/`A?nG1TE;>a+>KnM6 ICk42a+tѹbfW?67fȤ aӴtASsH  UN?`ǒ` ~~B|FW^gVƀł~/8RSʡ=c|2ҸQ͖>'/V`N=:!}O<.Dd۾(P'pV]i7 }EЛ>W\G>wu%x&E,z~yim7l'w>{ڳ*]w:yzuc6.vE>ݷ ma?sm̆;F[:v:c+앉#A u}ӽ$^] Ҫ 6Ev(0f#v s0jmmx &F}BO8)~wWNSP^7݀Fh n6G<3f6 HNkQ*6&@Y>mTtO#pGp+}׻ͽqx-{wkupۤ8`M;C #^B6::K_:઴7+|Au,.}tx w\_4.!~s{} r{=>h5*5]+~/ݞZFoU/WYt旇A7AVfo/`S6l)-X .]^ < I/r*-/8K:6U(f:W[\U 9:Kfp67~Ooj~'?2Grc >TS3#p,kt9>vƊړn-}M䖕oPqzj7;[%!0+Y}0!KfWzf2 > W;+ZzpeEF年JD6o\:lEDdi3~:i4A)3B-#:;3r$~xq+./pUGmF34*=FQ_eoaVƨ}t=WG_X1)[ NY:+NNj.Zq0l4J+vxLfl2s-/tty]Hf~sBGΏY_( \90( dFLJf rV%\i㿲 A.vA?"~1=omZ.+;;8Ɂ6;"Yw)Bes(T) Y%K4SV0=7e?.>= y;w |_P`C4k+s&ݳ{6 YW_VƤ`:?ZKK۬uume t.(O07\lvgU3zʾ{ۄnn_6oЉ qr&[߄m_y\y[)N _nÑ;5NGw4&[4\[yL@] O<E>=/6X1٪Q ?,:_'9Wk @;otxáoow=ar>&6ɧ-ϓ숢l0l؜AkUqݿcowPopcCecm|~moy'qF>= k`欂Igv?Oo2ZNғCޫt;lrm @dW V0<6UY2W} ش02w&}^߷"|Vc !cayQ=6:\We ,ovAހ& !?x5B"VBE]sN3W쀍څ5Ax& C4^yToYR4P>cru>+#6!|ܨUlí 4cWFN<xd8MɳZ'_憕rJvī˗vw2!C MHڑ~A^~w~M a Kӧe]gVW,aC=؈(ac\{AYa\ܳ8GuKmVrk.0vټ3b< $ f}7Bg;w7ٳVsjCdA/|6p[Ze~f7R[ +S*my͠٤[ F1\#7UMW`^ i~0mԧp#Go`҈y#ysG;wr8m=FnA喌m;@K 70߲{W |hpu3<>G[0^og*瞅Z`[>!p:7;oS쟼Lz0 W K8(s[N㚘`o{}n?L_LVKxDoa `?2k| G/8q<Hst8`~30ի} ,Y~ikg"]ݻ07q;&Ч;$#G& )}cw?~K%y\ג~)4C!̪{Oxn%p~*|zk`>~ -\%ngV%(g,K0 |kj$p?z\V;g7b=!vC,x=)o+Мm\G]x$`&t cckB#F$>9}  :|:[|}Xno XₕY] ѲED.PCO1:A#ԕqhx((?5==RIݱހPfhV_Ɏ_j,aғ614tVO/5aF+>}m8@+,( uk䨊IԹ}u頱OL 7up?Ud k?Uz]^}0΅Qt65 q~,C G貃sQwsv#6РʁFP(oʲ=tjD3rӗĿ5*]iG3^K Kt] !?} Gyv?mOFSXx_h5VU[Kݓ_~á /8ݕN_}]z'[vdlvm]ҡMgãn7ɑ7 D<%חxmwt,_]к<>v^-?O)#pGo^wWjir>k| m_?trlD{{͜;խʹ7 \ No[qge3dpvbG9\|+ϳY?Θ }>Kfbt4B0>Dދ"~әHmF%j;9⊎[@QHh,Vgq칾>kKU'YJw"w#wrq4tN|߂:-< Tz߰}4=w ۻwnvdīx o罞L E4d@;z,t)S=-gyx os{!z%9~?:M||mWљS@Qc6BfGMDƂV O^n]F9@JMb}+Jܰ3`\^/5Mi%Z<ZQU=\ .#}mm }t-)`]^q0mK4j!@HЁC1` F@z)8RN@>c4nt/[>]xgEgT5Zm>a23h_^K'$x5 HcXhd: X־VZE@`נ~=QѰ-fnɐ,&v R>5ӵ:HǷRPfWM<kNv0r!9tAFJtx];y^R^M7[^h]z ʴNB4y.*ruR ڸҕOۑ:۰=~`˛}yP]E-P9\bdѭJmJ٫d ׽iKe[.*}#=&=WTfKUU*&][;VZz4@lM=v\qiտEoU7[=OpO@N;w,˿[۹ϹWKwO|@eNw;.3k~SW6ڟ_7_nzkxάm| Izj>2x]_e4dr,/|P'}Uqoz]cާSTVd˗g܂@6 4{8* ɀ@fc3mؗ^͞ѳ?79Lpá=`眏2)z|߂G-<;LA"Ӄ }h6Y'_<ϗ=!*%]T>y 3ݳ&:TتZS~Q00ǰ[}f|uۄV Ww:d/mJ^g&;ivTUң~W%/oxIj~e2eO͋/h]XȄ^ӏ֧8_yC]{L8;7ي|[.i$\L ɁQ>q/;86/ ڈ,Tw?0Ā[}=1kü3*(M38јk(Ҍ6@aeo2QQ^ {ρ60qId<:Ȗ_K8qd9|!cN 3RUjkp0-SA 0ʠ.]г4u.2cٱ&]H~3vGuWVUH5ua 0Y Hf?X@Zӷ:x:?sK6fh>hFKQUG0`]z,a J G W~0#=ԣ-q}zwa6wS;AevF㱮+7 ͦxгw>YUr]n$ ]Pvɦ`=! ˝( wGlg+{4>nkĸ~#pG6}н~{3Õ{&*c\ˏ2! X[vį(@&Yr2,lxX|!<돷*݊oyd}7k'>e?[$m?&/oPf#`G4(8Ʒ@t2Ώ:1$%*Їtg6ׄ78GǟS4b6tW:Ga7_sc՗x5%~coʏk;?vorm\|V/6pq>CM2x8|07Pbc /vx-//f8oЭhH3&IZXsӫ1N 6#iRf4kpu|oEOs8ev:AW.7z, ,6BwN2:kU34X} fThU猼W+*w2o_9\.}؄c(1cE`>#b %9jy[qqK)2V*VO Og@Q3x}ԾFy|w g}E'- WobN=is#&G~6(! 6.6GDi obwyk5+o4\p‘}ik|o#N|.00`K^xVtk 8nPT}èu!ޗ郇U'VE/2໺Ju}ybe;|SWn c+m&ÏgOG[`#%R~өӟ=NOw#pG/ o t~(Ⱥ η{@]UP8,3ϲݢ-K~U>ke_m>3/^z=׽{˲q<~0Ѱ\{AFs ?e>  8M~VTsR IDAT=3B|@/{ u‹iohl |)pfWE:a'ǂRp}A RV ~fOϣ\h7)ʡw|Vj|љL!0ycnV6)w6޲q~U)S>|R R+%+;x&.[/?k7)[/5XѿG,V 9|tLa>G\Z,lO'·WV=8+,NYiVŠ=UP'h1e F Ǜ`Ͽ4[D6K.a0Kٍl6Ig}vM1@oU,{4ɎmpjS@=-]ಊZ::Q Ie3ZS9k0y%e ܧ>( {҅ƧlvnGGތVLbWq*_|g$66$1љ}yǨ~sHOfT:ڡ'I(OCC#7=gF,q;2dkݴi.~V5./ǒ]L-?!=F#r:|_G!-w tUo)bSڠsDw#4#Qu<7 mq:;~z 壜޳vTMDokd[g83Zm4Ҡׯ'<7L D?ؑ;]%gc# rs ]0EN]?znHV}pnm{s~#pGԟ`A"^^pD~F=~`om2ijؕجfM ffPǯuo?>–W]_;= Wy ?mI&DHP{+%/z}hFۛ~ݽ,p>K>mgt#, vɔ6ۀIzE~8|]"0i:]Jy[?6vX.2o̖ЁώZu~t[ n\: PϠ®# IQCqFg&l'c|Gxdothc_‰~gG+''81,^Tlsy\pNk'xhD{]! ~'*]1%h TQ[ߛʁu% l35Xȡ#JU? ( kS_o <{ԚeO~gcX@V>/?wYF9o=25 un3d@ Bro8eTZ;tsWo*x:matwt>m eD?X_ΐʊ9\Hup7ViX~|\L{FFk7 yG{dEw=+b9Uovk2ūQO$?۝~#pG d2'yk>r<rQv jr}>-#w /~/^ I| z6])gOp]}|B \vK_JFs˯>?eyfMh-ǿo0RX :WZ ^PR|)(%AVI=L~2zsF|ۊ6^P`X〱0I_~?<4ys}|lMoiΘ 3\XNC=}Y&l8봓=n (Dib=c .i< :{oeLIα$v/.)v{FT PFFBuKgDޫ(HMA3q9SH^yk((8U@,w\{Etj  (wx)Pǿ_͓w? iIdo-g8'eaA׾h߰{[G@M{ggW`z4{ f]VK4ⵛzzT[ 3,(M>lX^ҵ :G.ڝ%~VٛJ}ƖA76zطͼӥ:LǏ?7]0z?ll5:[,ڍ2ŋ=#i%SPwd? arZGTq&WgOGK>Xiw=6!G;p"w#]9?<(%·yf󗶁]|x{Ƃ.Aߥ,J@]A_5rh|9AIlm$ 5%f duv+'7L^'- Pvw|T-=>Ц~ҕpX=+hx=fp\ç0q_͓7?HEG /+(F+(Mf_~s޻n~+3v~`;lB7%`ɱC^Odybfا'?}jKÛVMnV|GfsPBvz]`wpiۤp-(l6q&wk&CI?VAD8ث붪#]fG>8G̚w۰o&J:eA#{̶AGϊ>#8 ӽУ:WyV"Wv~> #'~XV=mA%T1ԦʦA,K{81X/or2GcsŎt0VN;XLkk`.E DaȀ; 0+ ᠨ@|?N=M"h ,ֳ~^bUwɄfqɶ2r8hROȴ@hvorNcW 2Zggv:ă[N~Ψ|d` YTd㖰 7&?ҥzW\A?9n==6f $O;]V]0߯~e W|aPO)Ju\0@'䙚y `/=׆PB%f|vC^oҫ׎:ʡ'g+O0y\0fGיo|'!;v#'ᴕ7ٓ=o';w,(?{-rK3ۮo!4:G~AK~F?ʥ Jyy3zjݫ7 :_`E?a5Mnp"È $cܒ]w$CkYk6mpCi u &'tO]S`N|ߴ^E~*&B oGb>%qҁ\^}x71$ςlPxfjXxݮ}FxTMXGL*kmV7^{b3ݣ{S?daA)/)`I{ ۨװf짱cPzƵ^R_5VU[`KxwLI6,cJXEq[Gت nLd䨍&8F8c{JTV{uu*7ɰº }tu LH@NrV++(ob:QQ?zh:t<S'NscDC] AY6M TONңU?S1_VitW*#Ixү$̽DBq9}`N&vO1aVzSྋ yU@ `:3fN0wL&id!|aw^y~Paa;zp:l7Ѻ3goO{~#pG7~>]z,Hi&ɿ&GnoH@œzJGϑs͏Xh3}Yu m^gA Ou<+2Y|KsYg-otTÇ^g:\(x= F@,j7j(Հ*Fg -,M fHVyXM0凿WQ -KoC]`^ר+p m#4hკ0]bDyVx@.3-MѾO/^;kӾdUk?Jfߧ"6 wU9oH|wO~oYkzkVؠ是 42<,&KOv,]k ט\+?͑[POu_}Uv{i'Bc }T>"4[=~R47ѯ R\P~ojH˗;J]w^d?{Z跲{5ߞD'jV|A)߫d~6n_}^_dm^^I$@"!1Oö>|*c)9l! pCIF>|zfQ / d d%Og@ǟ7(Og{M/'ID ʓ:)Fr[xt;a>r|P&,gw)Fxy Hϊ` lp,8ǭGp'ۋƛk"+Kŵ* 7Bm,=n7] ;{5S"KV"kLe:+m?l'J?5S/|AD .MiAr WgambU&~tcu?G8/hկ_o=z6:VK LNg#k!@Sd* M( qAS\2*3Q聲XcG` ;17ygD3xR񣌀G:ZJ,=cXe Qy *"a{ ɧpXȐ3fx]`OrkX Uw}8?a[kfve8mF$]4'V5G>֍ Vjz^@8{gAieqjLPɴ+$h_F#O(D̓ ^;)u~"xl~.V뽤^}voOx}m#0B\ L=>ncxuթW$]mPಣў]%Hn|.m70Eֶ>R<7Af ~l= & Pٜ{nAW>VRoAX2χ7 -;%g_t:bV%/(j 3UWm zG:{b| F󷐃dVQ d6\T~Q{ ?XFt?l>3foogFWv#'Nҷ֠G}mwâ+#ս2V@5:oT`qJ,Ru!]d|e;S#]p4H,7S0z'Ȋ.t93xDf{ %. [xK8a|:FN<;>eg積0m:^17ڼWPɡ_0C3dxڻ.wU, IDATK!x2G+F[ R^2~6Impo;e#s̎vk tբ?0?p"U}n0Rn4Yː>?l72~Wqm1Y9\pl+X)pPFUToq ʘ~afga׶m>3&PA]/-On&D[h; r}쬲>,Vyh7_*{ã˼w#pG/5'5{Wu||`~vWVh`_ѽg7C^Avw?EG ^ֿ{UfC.O_ī`V\?u,6(нK~ߤ|&&plwvh7%B6('ՃтW_0>U:D˳ϣo`W*A${DEݫN9%,*x,y㰑{vjGu?ل0!*x(血m3թGDsf j<T;M >S82Sf|q3a\bO|G > h|ijb_]Meq}x/BxG4ߏ|e~YBI[r}$]YmM2_t[lӯzx>xj#}}KOl$$-dLu{\:_6X{k}j;:׵#uK)޿joEG@d<!G$rO4@ʀ?ƣFb:,'=_wє^u hKXcٍo`~s<HPq.j4dKG n0񺌵UjǠʮktt4 *>+2~[_Yhh"E}M[tЩvq;(p(T;Gpӣ vDɷ H@rxYb'xěm}# w1bC_< x((c8)^rO7boOۅ du= mʞ>Jԡ^dij1sɹ<;]|hႾ<4'>RCbݤt.Ј"m7hlR';GGx /kgorsqn1؁kLX}ooaǡwFGՎӟhV_AcQ+&JcEO+wٗrDO |c8<ޅNUU9.saRN^] PFGUq)g]FJ  4'2ks?CnZ{DFܳWrx'tF;C;حqva(0֩=,vH]:MqޞBQb\y~#.E7xczhT~c)  ;>lar#"ۘn68aTs{ղUu_0]{ecʋQ =NNKS~N&.p"OVt$s}E\]ĵˑ/'-¼AA#N0Þ(!p}?t#,B++K=Y]l72TF jŁO6-LRw>2M;w# f 7k&u3\og}דví v79!}vqї}v.0zxmb' 0 ~`Sȼ rV|۾Egjxe+~OlB'TH?_܌U?Hcщ$_%~\H ?m@a-#l[q39:F@Lns5i|p_\Yǧgz&ߋ6gaCYEt,E8mε5\ NyP%_]JW8 jVhj~v8!#liVY^nip舎6c rcU: zr^RqVJ*\0 ri3COO4K=G?Xc@l pQ=騾XՠIt`|񦓆Mu'קr F3d<#"tgtEL)au21R9kFW H\u8{<@ w= S7i&kFQ5 h:F5$7 5=Os:jҳՈѐ/M0 ПL[ݧ{9j;[|G2_û60!/7u йYW?;TuUgر:J:x]m2%ɣOO?uvU~f}puf߳E Ќ `v>Õ o+lI޵g3F:.vMs{wO~V>~-[1};MB}-T8?+G'u  [^_uz:G߷6&o2&1DYzfpP ~ˣoojid$:_`TriWfvڛ);c_vH69KFc+_[o?LtW{*T_Ϳ?;?w#pGn?3[*<}=WMC3MgǧsYP,#6˷ӽs>Km}_%*ܳ5ފ9>fݏ{澀Ϻ. mV{szΝ ʫܼ@{ce?ޛ Dzn(>y |m?f2ѣ(#^ȗ(N? nFi^g~}x[\vW5e3̤~W~6%9.jے^ LQ"k `#'F>2[e$oxeL?Eʟ!N hEcZnQoRl]זw9DNO5;tL.X<CWme&WK>rt~3C cih,>+) [>Jp-ROnZE\j ~#0*p3@noːUƂBNui@Ү3F/J>:q#{2Ds{퓮tlc ~V7DhGgp'pP{bY|]W;:!%*K +w귬*/z(B!Ba\kڄ̈a9h9ۨ=t%`-252҈UE{~PҌ{9tgs=>{#VAn;~Cvvi`VW7ܸKN۱_~MOߎ  r'0]$}fOW;Ƿ_h{Nz'3"/+Y>~K' Z{|7[ GK@U-7Q%)$=p̽aX\  m { y}(;'^i^-k ?}; ϰMC_D_̠OgʏR+'_:ﴲgoȽ _[?ʚi/#;n&{T?hO<~aa7uO Y &ʎmGexڣ yds]u=&ڜ(HvՅuE^&}Ƀ2|%uگ:Z]6Z>NaY;t܇4 Y&ژk;䑎?i{ҵCv!J0NzʵvT>>8mt{ie'; 4N; siAN:3H2_tk,_*0t|ftgg?>W~3W^ɒ|^5_uJbԥt< Y.oG J͋7Q3rh>~(YՑ~ s`2oNx'<ꎸ*Dp : irq dc܋cev˷ U[\;C1l>D] xt-]P&y{W=gN< @ lA-ԵuܣUD[Da&Ny]qɚ?ή5T$Va| (s(wdCة+Cl bfယ`B aS3 "!ʒa*Z_Q9bq7Y0HR4*`LRO!<o_hhQc1]~JPC;l&xrEZɔTGL_Yhh*|*J` |H(?; J|cҞ T6|Dڃr%-Sɷ =y'ɛ?s_qdoN@h"su[:Z!\.ϏbA:҂ԛGkpka`)3kTG/nm)Qm}k7`Z|h(N:@>G2`t. 2Dm$WZC^f;@:gFo[hQuK\ ny~QF';vGͦa <*ALz4.Жw|k0<*ݱN; 4_.{?s9lz}]Rͽ^@wuw}&o@K=K,gA }C_ϩfDIɳ>m:~cK.u:őuBwǥKyt-ޖj $؀Ndu9/CfuD~1ݏ4Jc3) f0%:s|#+:lE.v3] `| 6V ; _PO耺TA X^Y2C9 Ob@4)'2[n?rf1="'%Rmm{1:Z)xIۢ|^SNտ>럣 Xy9~f5C1P[]}Wn&|De@+u]v4Ru[ TGƇIDM)]vz8ccȐ TB)@Zʐ5򥝲C,&U& @/Uz7dBa%yC17V|y`Gp;0禑I^8;` [E[32 YgZ[;O:VtN; 4WF+k~jρqwLP}$gIu IQ1=?Ēbz㭁eu+ Zmm}ۤ7ׇҲۖ OoW$} $'Whhp5Ȑ/jg\eDyTZu:x=BM#&/)30{T.Ed2`}. nFc :LqmU^EF1*Sf-PnQG|}9ةO?}$ Oc ğSڒ_G M)]|u|'Y+@ tŧ @8JK!\9O~ (wq.)ǣyQ IDAT<0ڤqjqRV֣Og+DCj Xzv̻*ښs,h7@Ћ"suvõA i֗?FFxH"il*a `._/8T7 d`e*p =Jf#v&6SP+vBaFQk!YZRx4h2| t Tk&Pm{h,Sg8\u !mll:?+4;O\24Q kal4k=lgFo1'lpϘvpÏ#C{68,Mwb+)teiƸ|СTߺ5hC% vTRҵn FUٰa͌}cSg')k mNF';[+/¾Mዸ>+ p;.̂\vb p\ cxhe+N ~ߛ#Θk fVg &8sz0;\ FЅ+zս _ϗ,t{T>S1KnA+є9&d f.޼x~.(9'm"% mE?2_{`2AKN_ >^ntŦ8fƶ:h7ך6*{"J7Cxcl瞶f,g[Ķv\cOUcR:_zk/|"hϕ:V,Ph0$ lx`י}!1P%h`C('!PU$̓0N&0~)MbB7C4iXa(>*`5F;33fА2fC*KT X+('4xjYq[[%e e幾xKl7蛴z~<6$yM5n:RwJ O~h;k Fס^ƚ<"oz{ӡtWZѴr"CG] B'֥0v7B ^=xډyLFmý(_Y<7qp({)R-VXrQ!zѻ|bl.b4Vm?b:R&yПճU=8(`f(G:x~rwvpCzTG%m/-vd o;G/?+]6<b fyOw ww}-ۿS+qG7oo_oӟܖ׿//,C,??w_~;W~Wc}}ɗ|JwU/3_˿-i`7PSy}kWۿp9mpόnjt ;o3H6(O֗Af~|uӭ̬t :vi~K}9^b؝e]@whU7H To|xWEA";RJ?= dO!c&wgYpO^HKyt-=՘@7_=@xX'{IjKa=fo;?xV?aUA?*O&(rCk#wuV76BkynJ2O?m8ag+<;}L?{qS3?ї_gl9midO'vV];+U@Яm9M*B~VByn(ŋV}Tm[+:˚7&o_SYY}߷{(t'|ﻓ7__\?|s?ny{/ s?W4r5_˿/~1ݻwG-ۿ]1i`Do[ؿkwu}[}?%|\8:5ҷ>>`v2w;}5s<{g v%w4~M̰ieh3{n/;{x~Ё#G/?X(};446;'ԏ;O=$k*ZU>}}/>~ M5XфЪrO Гg ]/8ťoan]oW^ʋs,By,wx!v_rٞԧ,x+nd_}7{ț/~\~_^Wr 7,Wާ~;so6oZi>ny}kZ ?#|7~k\nY~_G4.___^җ67.HdzZx? Kg>nm#oߒX[X_\>3?syx--'~g,__/aS`zy˷z|.ӿzoo k{s?-jOzr#XE/~򰇽?8=[~~y[ymmokWTwgWw_"Ox§ei`7ۘL~>TҙSG~|K&z 72x߽VC_~@vf.g &n}BJuv>u[_ЬAuoϪ| p:[Jn]?ckW=.!6=@lˮrf,jDu'nk96cA_~| }g(|AܨWs@=W^G>kY7~i|ȷ΢MnԿh՟rgC5_ tW nJ k_G~q&];vztQ"SκvѪ+.d.Uw!-lx/2muKKyM+;:*o _UgeBԺ&dP]p??P+ߖ>bZK \ڢH͈[d=7D(KL 4ǚ26.CF{!SWLllj~]2N-6T8҇3c}RiYV^:"߸z.k}KX֨5(uH<0T@$mllQlwp\D0`O Ww\oS/Hû~ƦYŬ|щQgc'GmH?iFсntԝASxX,A̖яo* M>68FdN8HR, @|eɏCKlʬ,X;/3yp]l:e>(̩& 8L䩓?y\y:W;ϪuԻ<~lOA|؏Y~!K?S?m/"b_g}ֿ^ayOdA3~G}Gc?c_Wu}g馛[>?`ˏ=SV{w_? ?/\yUݏ>˳,҇-OIz_.O}S ]gvov|/izGG}G-pۋY>11~+˗b`կ~]iٳgY`^WE'`->D ./bys"wz!߻o?&O!_~Kh; 4ϭ:GzO>Yqgs Ǎ5 f)=R@;A~E7>H~ɤf0QA~P5@wi@v;߻2a' ~9o'8\Z/A7~{dw3@͏7B{uŽ!6Ib)FSW;pW6ͦ .,w5. &!S=UsA8..:':ʫ>,-xMu'Yk^z8 ᦐ4֓!}xYHC V܄<S/Uf~V0D ]u(/zr^7֣}%RX@؎9@:>dt)\g40~䋼ptNzaSRxzU !nGuCl߶]xDz V^3UF.?3YĽڨv>^Nz<":X1irӑe+ŝq~Ogkww/?g>Oު>C뮻pY$ǖ//W_}5_9sfy#?Ͽ=;dmߺ_q/'"NڷG_Xo P|rY>?}yO⽳{靖˫ ,'d { ㌾;`_}|73аhڱ~ٗ}i@u~W+~{ywy|7g?|<CigycnGn Skv?{"i`HkG{U.-w&?}fo0Q0fXh xIYPhMH?FOr M>~r9 le $>/kjKˍYad %:i LJ>"&ËΦC_{&и7g| '"t "L-nƇtiIk&܀|:͌ˣ]>c:-X=ỳ4?]FVt4W?s~Ab[.xn䯀%x\`?^7HG7V< 3XuŹj9$`U?H̽UFxpʺeSj0)OZLAl61`Ґg/( 2Is' CRy |*PyiU=3(m`)32k/.4АOLx*.evW.䉱2݃:O}&i߉lê^Lnmz1@Yciqڶ<\;_%߇[<? ?_*fw:fd:BU+;L?Wqhi|bqW#,|&Vԋ7U/T#gY]N!3gR_, ߾j]q^= IDAT鸌O|8a%f__ث^*Vw{!y2!Yķooc;q<җnx~}y-;x_ʯh˽s7љO7曽ٛ&Co(6o6E#q\okg{ߥ4}Mdh5o9/e߻^N2ӏLL?/#MN1xׂYկ"_w)կ~Z%mG'z}˻c`[aʢO*RY7s5L$UY Lw .(u+b룭R܁; pW|K}h}/xAˀLXmeC WtZkZ;1˶ ?H_Dv}i o&V'., <QO (XV}O^c9' ^ڂWGgӭYIA-_Xjp;[Ϡ(z?I{}Nn9[Myvhʳu=̠ޜY/Sxsf_} ^lC/"=^vG}xW&UT8֗߸!^P܀ Թ8t N@t}pOܣ.-= A!;Rɴ11 #١seC Ǖh벁Q'۠NZ.5kvbS(MM8l DkNP0-Pma@%*(^%)(yQ aNë ?TL!Jj9/ JV6}@`X'<@3y,D +lb0t(D) '|aVz\Mম#5Ufq8 |PI2aZ4d>ת<"FEsyEr][W^sx݌؀:Ҁ-X@z E*>Ί[s\ĥf8+TʍIMr7 *e1 e\lys =m0L;XC@,{Z`~nF-4 ~ů{f JGYOՆ;Vz0R($#`;mhNW௮5q͍ ?e2'%CP?}*O8jF1a[A'wuXG.>.?g7kY~n'؏Yzywz#6p7f_pXs,CUDY}7v 7^-x}y-G?ы3?;f,ҽ7F7= 0wǃy;//|G^i`{;Y/b_`.yO3+ϠOdP|"gv? -[x' l- ™eK0E AE?GID;\Nu }mCAI``{œ~{8Ir $[OУj >h| g5@ = (9qt9]o &?^}sop72AAA~;e˺2~F(h֕ u ܎ $3JG` O<5B,!̨x%8AAQ&EZƬK"Q{li:j&;rY|(OvFQ!u~EC3tK ͻ+X|W%o,  3|[9@L@쏿ل<6Ȇn?t@[uX!s+r`H,+7Pē^+g  Gg=E}o.jGt v,0 *-QvWbP1 eҊ5h l20Y@-ŖSCOv%@+!UBɏ'ʩdY 7T9d(Az*| yR*tWA N8d*"l =~~c̲Am3CQ6`;4+s (LGZt*<7%O<+@HnP!فψ"&ǘ48[@Zbj3K'yv4>7*(P:%SmO8ʴ CzI=UOyIy|D[m:F+<䂧.:2\i'glAuHoqn(;["gCMe Hx* - dUB%um3:`hdGD(!{!nUܣZ;u5N[ޮr8,j} Z{٭7 {|߆nPIof[^Bg윥'=;Z¿=.ݭ[sW ?胖??[g.~z>>zy^l5_̄w|w.p;o\q''G ;O`*x/ʯiq_go++O{.O}zw$W4}}{`T=\9/׋ݽ@׋x0 d73e 3nkΟf-.5=O Πۯ>~ēni謹e<_e@d_@Zv)FM0+07Py1;Z_t`Fu%ts LYMCcNc >I*]}3ec͟4X_YXAmLJ8:p+=ǫl_ur5&x%ݷJC yZqH6?^n=h@~/ndg3Q,'LZB6|K3{ﵫ!̳q90 ?RoøHbAgO@+K٦~ˏ"ӡ\ȳpz B:2G^v{56-' CNB[b0N"|2QIpymOF3>Ā5؟1퓼[LX7sS'~JG զ*S~{AfX:-mΏg-zЃnֻ9}Nvom{{np;$.G>qmz>0wg-?c?<..O|an{kwzwY"/_̦w<\g?؏#]og/',ǎQ{Yz}%|%wq_|x6 tw;;/=^߶\ Om߃Os QWhcH(bF}+\ D>O\{do:ۧ>1컱~vABc9/@Dg|kVi?!'#vI?'`: W2.}67z p9y>O2>ȄS|^ pՀ>bH#,:=vRpߌ㳨oL" יj62:>>|7LL]7*_W,yoxߦWq̠+})Oq-jn%>ͤz%(s(}pn >A~u Zki ]SVUG3J׿UΦ9;zk;Gٮ*>^+:R^3ft! 1ϪKcT\7:\} ,.7nM(〜%Bδ#wJ۪`')x`qj\)EJS<kMfɛ`?Kψmd!J0<71ߌ "!reqy5 ZxMr #ƀa{> Ou>J66Au[~ &k;4E6ap]Sh4TTJ`0C'c 'Z n+kkz'3 r:7@#[& 52O=kċ ^7ʨ dҜrxv.F\N'Eb~8>`5s.fs1xCu4c'yI]֧z:H$Zc_fY;^%sNZnW?)S+tQ_ygp2pd:JCKoX s_jP/e<ѿm@}0tm`jp OOL__i?譇.v&d#"0]i; #qGٗOg;` (ɠ }|Y*~DxqPYmt.em^25tPnIƬn˯$`##[={t^ }c 833ȸ ϖ{Y:&UjQ&{X B`*bpQu7݇Mt((H50UX?hۈBT(B<#8  vM&tׂ&(i>iQar-\-6q3F.?w( Ȭ4yd"mGdi;V)Ȉy$y6Kdx9g['-yvz|Xoa#}#4 fhS,6lI^^ |` ;!In5R G*K[['&~ӥ;\YٳC;$fs}[?zXS7ec$ilFA=zQ4M(.2uUݠe~GIkt%ࡠL~LPA&g?NՃHyyH;>=O}0@:ΎCԷ:Ҏ❲ʏV.X{P?>-kѴjV[E^]/=zp]7;iЀK[x3/"NwG3!_ 0]}>% lؾ"ȭrfpgz}=fY2{U~ggIL4uA͕,zIG5P//M]PWyۄv$ <Š4(Iݎg`rO8/: x0bK :Jzvs3[yTNO߿ٗgu/ƦZ䣘CS_×4ҕSAq~3~݁YGK-8O^.Ѥv!:жl+ TTX DvgY^۠l wmN&9S97EY,1t92?]QY ~Ei'XMw`'^h^CHb #>?B4V@xxT9Y"Ðgu]G1n% l KKQ(~)@!iJ\Ox`Rg86 gxAwsp @3qKH<ʟU>yLY\BE"a-5 a7U[+}f {[ᣇP?z[ Vg I^>YW+AeS6h)6uDxeoP@3[af9/.qxOoցT:#Чe"|NG>e-уϺH)Sj|P6gڙG|ϼ#EC+Q%\OxxwogyTB٣AǺOpxfc0 >Cʁ?#"6Rݟ ~۷~o$?G;viǘ%u753ɵ~]*r3.f f/-.M/V~8|~'<7(o0KL>ļ5|zsOڬZ,l$o`Á1.PgZ7I 9arYw՚؁,g=6)gu駴_X&`&lYP :e\Ƴ>+ 7l=*BpTJy_K?_5Ir: /hqH>6^Yή=$_|mPE]*vĽ|j, X8yW>xW?fsLˑc5UA.qA`>ygOL,FBSuL;96JUMI;@Kbe\u1tGmGPۋ0kiu;M.2(B|4@~AgN`2&$iM=f:4dʺR 4,<(ANEMT)&,IsYzp58|T#[Yawc1p;y7(3z'@Ck36 jaڱ Jrģr @ҕJNfl*g;2g2Q/ ¿=-+J[`\42i'/*侠@F&FS>Ie[:j &6|3Nxը IDATIMGA]g̓Mnkw4lfW^|6KF,8 P=1"|( 6K윕tU[\znhdpPdG7O aGO_3J.'=g\ p>RR^h+vDG k;(}PZ֓ՕF{xtxd`m{~u@նg}1#r@wsns )Woo~,\{PM4oI@ Uqk;np5J]m0_ق-8vINۮC}躜Oʇ}}8lOOKD[o?ħ,[夙754ocV|77K\HS(Ai1õxpڠvɿqx3Rj52y|%ق>M~CfeWtC=[k`(d]&vFG /E֣"lIr7ãrF:pR+~D>U,,t@Co![Hvx;#WԵ0y CyՃWK,#oWMӵLma!/㟪0*?yI9dbm׮FSˁvt.U^QIstߺU|ao<[|l)BE%uʳC5PqYt60]J?n\1w{ S2+e֊q _R!yx9gT 2#L6gh\CCLXʷS~#/ 厱Yƾ߁4ؗ 9jp>郄WF5" A92zK k7bGtXKXώ>@@h0!!َvFALP6ehSO9Q' n?)UxZqR3P:l8McTzKO 1z=#= W2FLf%&ڐŇK踲mЙ^l[OV?"* GR);YUG+mP{>^T8S/RA^Qہ^v/Np4  )WgnAf9÷; 4N; Q5@aWs{@~Ǝ-751–S[S7;+R~pM t VE0g{]pĠa[|4_@5R:kQV||- n̷֗W_iXV0õrv{x61r)n~7|@)98"BNJck跈g|t:wn`\A97nsG7 L2 @zȷn*Y-ԋOtAZO.). v _^ur/Ӥ;OЎ`h+\w[u+#kc,x^LR*9bo+K&pPm=N9' Vte^Ȏ]=Oٔr+ z *u5sLYV.`hD-y Fw+q`XzK`:c8":[k}69xMF=3v9xؚIO3:2=z.1H`BG.ٸM+?+H¬ fdRt1$Q׆οY.ëTP {7$PLBwOj(p -c1ByM_ǏgIAa4 d:j@8H|gUUda GFRv䶳?G5;R β0u C6u6PL,^eq n`z大tE[%Q5 \`txQ>;\ڮmdH&>ˎWκ8u󯻎. b^! VƐO`+%18/g,mZŸu^=rЇuO[i"mGdc-;sʛina5=D7t@tn sw߸}nvi`7tS lݜ}_N_//_?E-]^A~q74x=q|`.eOOOO76 `\ z}zϛM&.>Ί݋];P~ѺJBZ=Nyh =R0eg,ez1XD}DDʛ\:/]dqFgՓ(󔆮@-F^B(9I5lDm~a nS{cW)/._)KAhRvW*<הW]駉֛YeJ}"`>|('^~p=80p+w2|WW>:?~Ҹ x@U<ڃlm iK8(`e u [nZxp#W֧6"~7 5W{`$so!O1_CGQy(H@3k+x VFP,>PhލbR*V./C*=ð8P$VG42r?pfmv- O^~F|x (w'QA|ZO0l49 N< Br8 iox) MT^iRpg<zcH=˹_q+GzsMjϙ5A`5x3iʝ0tC8iCkZ< eٖS9^1C^h)V+Y9<vIXSkht v 7=ݱ^ w  _6#p̽69 եɳ>lT囀wPɂ/dߠUL6U6`fxu]D7bmh{Plu>?т^GV-<۱~,NՁ6;uCA.Wh>%]98pFMلch?({ ša/.MLV0P6?b-Z|)+k`[%~K7~_xZ%umԛu8F[o֗Vh=R^p//2vQWbc5ql5H$&8 J էGP`mhjAӗ_\8wscK.!d5W2:Gl˕7p[{u2Hϩ+[hǣmu*}CU\v6~WL ge/~2ޱٱuBE -ۜ0nBu6"_Yl)9dGj=W$q W+[x-hJ-2mNB7 rCa`0py~.EaP` \$r V"8_ ҖqRlmKx5\1^xa 7jVr=_Nr;]}zɣe]?/G ]^a_/ t |} &қS^q+g)z(&ߐ 5 yNfY15@!m9Ƨo7|'xΦ#|LV:+~β^`F~vAW#Ay~H`"nKߔQ͵y҃lc+?@Д9,m1;>ϳuLZ;]Ա"9<),uz e|B^pMd3qFd][W_yTܛ']yu}DTJSŒ|}-'v38zLlZx_hhL,V>%7u4[>>:9'謮<2Q1PJ)<|eJkl:NҺSτ>ʯ@G^x+d>XX*J-Y,'r>L㰒Oe'AY8&(y0R w7x@O#`+N09/*P@>Kl6bd鐮j>$€ 42ccO9߹WT Y#4-,YZcs(?,DoWxeO5ш717C1mE LֻH>W\F%?0Ϣ+t|-KrWr";#5 Z1N I<,w$jGXNImN=%mb}3f MQOD>J?;aLa[^Dx?/Y\q>m{[>xUWuI+;M)6ᷕU6TY9E|s[ZC']8d,[SKN; 4N=50'6rw9F>?{8'\Fd0/B}~0?>}yECZ&>)y-h£q@>r,пSe{]I`0+kʠѻ ngP}`1YnOwFq1 #_watW0'F313n I rʫ솯.'Wtm f%>aIʖNe;["6oAV8{k|(Ϡt7e9]W`[=qapkbfw[_oLCt4,u ĴꈘkZ>q:fLH1`ktP%Ywc[t ʨ P6'+ci AM{` 7p'rѺu߄"_\u62 Mb{~j7}ԑq @,!B+Fd+3ҳ 0 '6a$Myriƺ@2Q!`Z+@T>YTaI&6Xå DG "풮; |Cl942)rC1t&ťQ.e=U VQZCئ#{5@& z:\>l[Ciދ[ZH=q$vmFBV䡙_L/Fn[#P' 6^Wt]IW(?Ik=֡|" Ի.rͷӚuVZ}@OCʒith_4W9f x(o3:+  2zQ~L~h'۩)$!Hͷ׺]NZك^,l><|uS&RdYy sVʓ'va}li$Kv7|vi[gA oZ/7ygvi`7 g5)Y3Ok8OV_Gz .r}AK fX@Mz0L_Yl,+p#y*X_4sct2sw}Q:lPf34:b^eWgc)GRG6;oO& ֠8mr(]0x_E0{l֓/*ݩ/Ys HY1 o+O(s/%n.x/Gݕ ݓIl&=6<ᔚWwCƦ8s[ !n9`|hkp{nhQmW  F?m6ЄʾrcKR~ cfaOw7+D2%]~&o!ԣ:wLHO؋?KQ_bbdpG<-f/N鈿CUj=9cٿjEc$Di ̽@papB8lHao92;Ѭˮ ĠbqUaԀ=Q3b(ڰk &DӋnP`g~zpmKJKqFG\L`ԛkh\zkT1YBn`)c`ǃyLEE>< + -"E7Ww"kpeg џxQ::;i35!f­v$oҐ^~̾Fщ6p)VU

:^}uoNLk^/#x.~ٛ! $x,<..?vKhdc\|٭̌?/<;Y9ۙ) E Wto**G#> ]޳N2 n2\9 IDATPy/w ox~yr3zR6Q_~]t\wIEgGK.>9Nvܧ$=;2W œ1ac' :p 3@}:׳uůz;\1dq׿\kM2ITWO To2+.|68 =K 㵃w`Ov+.?[Ku4=?fߜO'/`<]~U]ŏdދD|1$/gc@~ -?]|>(<@~&hiXm<[2 z4f] g&m4j6?ݓ3#T'x?w;9GCx;sk計oޣ}2ӎT,.7-C;̕poif2-ٝg}Bѳ8Wnq^:yWUC>>@Do~s}cC<1."<⍝\W 쳎=YН 'M{yU /_ȷQh(^zt^lK|{}o'9fLܡ'/Iv;sߠ}wFk'X4i"9UBЩ~f> qƥFӂwo~v ح'D aO 3LOƋSY1xG{p/I/1,¹UV|$O>%uj6+{fie* oWq!28?t4Fb{NɆO8c?2Mohpsl\2ܿ`gǣ֖mlSnڞ+ ԀO,N7\i?6k2i=Ń*&`\D|64QGvD/W04kCwD$fpW4 jƃ~%Q[?|zϊuZ@5opW{Άw/6#/Wi?_җtW;x-Q:=J%`z/~J=١m\gXx+W~b6:Tx2 g+kyIc+QMGad[ 0L>m Y::M*!m/£1+~|$g/[b}:ه/tm?$uO{ ?t|69a>WG+=w8[uool5ѦbK|f}&[Gϛ @I ?ͦvn~|Y?WɻOן|~!>DhW^56ZtǿO?o$ yϷ1  cM^~Ԁe[nk@ڲwW~^0x ek ¹8% }yosv|idOy] |߷ xHكvՇ'l.#| rb,Siϔc/Xx:٫fME_e=}c~W<~6UWy4CS{?[2^AvLO^VO7sw2FڛNKr~m|M oӓIvtz \6\w {2(:?h!q}9&YIGzu~IGj3W.N`,lnRL“^m{ꊬX\g`'i?? v*Xzy+&c},d'g{cz#_woOO_<==wX}m:9ïL6 W}bq}Nu ?ڿf_?_;7rJl^Pc'jz k]ݣXU!5|<ƙU-j+?zuw g{~o?g[SQ,И6A /݀1՞G!dFN{I ?$̜kµ`U XZ7LCQI)KQd:N%6_+`ا:!OnFO[h 9o~3ߕ/h+]ݹvs14qD|_;2(|0@=n@7(:xǎwT߀4)YG ?QB|I<< LjwUoCk>IK+S>9<~8}XqNw*KGlit}t?ӯzޫ`⯧ t~:2(a|z羕icAgzg2Ng[[qq<>6RNmю3/xhrϿF, K-x髦#9k4gO:6 TMOElml7J'_fZKK*K?#ߟ/ȻUV6]-e\aӳaPd՞Tc>ٕnv??r*d|<:kCxp 7=}Nɰmom>.=O^<l"=_`ֶp-H6Uo~᝿s9$%->rC)aao蓡o";," /NV&krKM/(?7s֦rA 1?Mhڌ7X$ n#sh~E >;g.xڀrpլ< Ju ++bc'G?cq8|6ѻW9 B+Nl\{#>5PFÖ?^v 8fYaHor^-Hn nWABʣNMFJ_)R1Y$LJ&Mrf6<gyr vtRh&+?'` }>~׭w[߷jt:ڦ' co{J*%ڑwINeGcC$6]5ꎏaO%? _g_z2 \ƣg2w{> Gw|P]`G +&I0vټϦf=;T饃eW~s|ï+CUSh[Cðxv1\PF~sm4.At~go)N,>&typc:< :` ^^^[,șf'F6nw7%\ ڻG%|ď-7XdFlIk[o>ItF~rx>q_olݠ g_Ɵ0d<>ryVno F\FnU럶pi/{F2j}{oʠV\QﺂɕGb~B없Tڣ&l "7}wU]ytl1AMYsЅ &T3IE j[d:̣#X-uo!Gt26 ; |@qn~xwNxXB"N; m|#Vg~w}Kg|&]~叇0yht9%\Y/-'jΕOjcIK' &M~~W%^<w|7# cip_ն9C,.lwTv1&6(ǭr;6dq1W=1_z/5dxOõ l1m7wW/l$/L27&M}e|X:|o[̾r~3—Mw:~mq{w*YDd>NY`'PCT`D'>?h~BsvȔEO.4g}q`w2[8x^66ąm"Zx/*X=@t}sT]7U/Pem{ɯZuZdzmg i'olLי+FqM<I '\! %/pr3n(gK!guѴ} t_lEk/_lnu<=&"+SG+x]ji#-2=''<ʢ bXCOKr:nΖ_}s%vIS;z.^Ե6/h (08R?ަ@U;:2״!l㑕Ya/=)#Ke:'?6?.>;ޠxËzz]L?:NXqoV5}3 wtv:@*= ǯX:; [L "4>A F)pN5zhNuG5ٟXF/ʪtW=69+3=2m'%5~t4ƞXZޫ =?We:6>uz 8ur$ ^ѪGlNP귕_ɔnw;o~ɐ|s衧=w6 =\t6g63]nP |B?6]鎇&PM캅0۾ g]ۗ]FiޏЀwxN!1D><ێ$&m@b ~ǻO+ 8a7/+1\L-@8Y~uj; rvw7 ر .=٤_'nHWʾuNP6ߧ,عma6WxS\|~::&'z@|^O[~4*#O>x ]$#?m/kr=%Ѐw_W[?yFvHk+^/dP Q{E@@aNi`}zmgPA wRק zbK~32)@C n<`(J(ȏjgd$&)Ѻ-['3#_ҞNv|X|n{'`eYr bAI6@3G!g_DΧl"Emc6;L7t``cj L Tc?>$﻽tM ⅾG(+~6}m@g+z!{%& tRCOK4x {Dt:moevzv:]eɵ_rpb5}GG_ ؕ #4!>)?+81KM0-7|f{-<y>ut>g0Ȃڄr_v?w}[IzAҷu/@6' ?;q~WgKT1?omr05I^>`9M/KY|?Kt ]_DQeP|MW-MMM^-aoٯf)%mn(\N,ɿC+_`qbzůЊ'" y-qᖛąx$+|?KG{XcÛMl*cG]W>9W )b\UEu@6IbgO_Ze4CQV1R_^7(tz]#v}'-&9;|-lk<>cj핡 yO_~!sԛ?-m$+7wL귘,ڿ_~)x'[OHGL-5b_?goѶ6td&ݝa+@s}cqA ݵƟŷŻ/_3x31ņt#X}EϻP}G{zDyvmY1Ɏt7{G49䥋gp&l[Fg&w e:z ϦGlw!R#:VJXI%\ `&-3^>\e,ɟqw1AY'<ڞ` 9>C/(ٜm$!'8t~џ34$x,Xo~&ܵc/CLzJϬwMr0מ?396 O]R,1 ~ofoф<u0O< Ie @H耞XKO[!HΛd.!8KGlӖ+,t3|U`Ou`p:im OgM@K;%UTc/:mYR8fu{OmPC7tT[Qc>7zxZO1ǿ]< g6WWgvu;)F{&|gk>0}/ImMG^tj{uSoxF`u#gdk^y:H:Nbz#GwW?*bhz6>:HsOa4N;á Fmݪ|ƂBx G ^: w'~b/?۟;&߷7lhH ?|ϑ|AςA|S>95`q+]AnKc ?{sgT cȆ%QL {JLO}WF̯61!3 z޴׽c5?cŏ?wKxlaWWhט}Ng&M0ot} eAl~c>_Smq"VyˑW}"qPW}{;-X{ɀ7? +0j9q/ZWDc_H F[t"M+71Ц7.E*zPsݺk_S+-*\9όGW^c_ZLh冓x (-u>)_FCLMwFgGk;Yk ( x<6u֑[jwֺc}S,,.MGt,Eo`Ç7-q}[|AU4Nw޻}2 ž! U:dX1m3f!Ek>a].tɪ}h)u⑽ ^kS>M<:&Ou2At*tm ɇ=0{Th,B@? '/O;٭sBo\ ?/?9l/uvl')Qȵ nks\g61/ل> Kx?N9#kxb& ?)s*C#Ǟ Ek  &?4?zN*|MFwYsuܒ_l5|[pvT2ֶwI'?5?BУ%Pݚ mm+haH_L>LKlC~|HL3CA誝GVM>1A؀9^ڭmup~m>~VOSzWGWMGٯ[A>^/|<ϓ\yy@cܔmt@t/..Η]k ќ@`t+=9?=-7)/ŇÇ v|H䇓pg"2=}"]E~rD}Ē;H G4OQmGh}Lo R z<em~7 L?{m;~wNEDXy]f?Ѯ4uyO g6P%} ݏ7!,9{ˆ6|tx 7y":yOKxG+L^wM!jl.m?({8sWޫI\2@]@pV~A Qia{g1*70dm70<?z$~h4n_ ]^&& BIWt|[⇽,p q-̍{hEE=umy˯{!pͽ@?}x[ dC " 6rIrnP~ n"O->g̮6]v\q~d ,(QtM#ZrtdtWٻxˏp;v/cU:buxgϘ6pgο$Y3 n ,x;ﮆnBbJ.hƃKDO7Y[ÀhKт,#Yhbgy&|tgr@g+_yj1>NeoNU m|+-oc|Ã~Z)W"R>;O' OߨsΈv]{0 d68nTp:ƃEBpH#F&7y}p>,\};ޗ7𡛃՟Z@Edy(]M/>_w_o#BPfbVaC-㗡+\|m$M02leu3HsgaapUW8_cu2r:F5qkYD5VJ@_^5ipUG{ h9o X+g<7/sfOcD{t9O[b|}ooE>|ӽG[#xC2F4OW%-TMƷӜ2сvwHGZX ݐ^ֹ`?9 }k|C"Qp7$jx: wlh~ަA7twt,h"ANc+::l?y[7t'| I k1fjܟ蓯̏8d̫-A7W,pͿD7)kn<۹[=7 j^dx=y;ڐc>{V9h2=}F頶)_ϧ =m4?j D/-^:/Cj#7!ڕI;Lvw˵0*ZUlW*W3;- Oޤ?N?2ery|/ h>'6oqo2c2[ǤSMoQ(u-LtJ}rzywWpfۻ >8Fn1NFZ_׿?4`M9n&+uoZ쀗8_P5)ޣo.&pR$1(ϔt/rEh23Mp#6G aہstn{ R T=I~o Z>(Ąsu c«w%K'dW V`۲=֓-hC4cܱN\ILṁ'S0pze'lCxnP4(x%ϟu쥼 Obz}u ]zkw*9C bٻ<6=t[:1;0vӪ}tM`v_LCΓW=_XmXLxy}$jx3_7:ی1)0xힽ[n`& _f,,LlB'>Nn7 w?$c/趺ϻ-~:oMv/BuJ{9*nLdM #&Q~Y^!䮫_,7a}vI38~AҖϧ*_XƮ ".fAx\z?ÿ=1!2zo?ߟ./ޫnmƇ#-{f~[vm_vdpd ɕ)oBx'C5?ioH/G~'+m&'G5N'fG;ZddlbW\gISz`OGSKWyU~g?A EɫsSl*GW^x>I1r$ߤڬ-G|Ib:X. >Ïs _|6hcs~[ڡwߍõ;";kU}:yrRč3o|jtn]䳠3^LI&-y]&w~o?u&K`;n|f<Ԡ /G$xFh>u_ ڬ_%o w[x_;`y!K>Ƿ GG|rzw}ڐ &rwwT߶Ɏnd І*=5?'x }.}?_xW%")8kx*:'XmL9&G>WޯBKg6^ryN0 ִcu|;h ꌺ  q2nx0c5X [ph&G<?}~$V[vt_d pP{[<;IJtPѳx8ZAuM~4C3;a٭h)BStN: C9NwXՆےhM?^[:·ڨgb~`xD9}G7K#>ޔn"y=.R-Z7kk|tMMǓY-/:!'?byu^ݝD෪Ο 뀎OPtF7?lyu"Ãd-kdUum{=/8?w׬zdeoH?jfϕ{ _xؚ$mg3q6[@t\ &10tbEKw .F</~y_G2_t@1?CO|3./'- "ub+^>qٜ._Q-d?x9,6 0[Ag L2n(u!9kHc:ӡzkI.Lvp}__]t4ңOq 웼K>ks6ͯ[ _f\ލ̧ݭ^_wMֻ7t"`Xd\d_lχk`?13{:c_%ޤ 4yk $mV|'/zMfO/8]$Ȑn#*jwʐ7]Ugr tvz!T:0kN`k@ޤ ^>h]H0 6|/Zmsކ`6[Ɨv36wkoɑGɱwA+K}7E6ֳIHto\|͏:v?\νcvS>}pǟ +to F[GW߶<[߻矟plc>}m6]<n,M޽#>Qs}قlUt@Ws] r(T8#EWU֮P]i*%).d"zAX۵*_[{t!'[ ^w+6^(fp7z\ ?vDG˟Qz1@hF*h$(>`(gxⴺL{FqCG;NfE _pӦ Q̏w<Ȧh-FX0I{zxgw:]7Nw.d{)C[)1+o ~_|NE8OG6 WeߦGwWe9(=nHwnh}4?u<f`'Bbʡ%9`-)D_Mшdu.Q+<޿`ڄ\Q2GMK4)-c:|;&`jE8/s0jri6mb';(t ,`0~Tr $^g[1o?>KD2i"ӓ6~8h{cA6'!L7K<`lD_ѝ%Ͻ*tgyß#t=\#hKF}[8(q'Yr|F~Ϥmb׮.+{<NW[usg?oޠ5  /Uu/-i;ݫ|ibo XdDъ`>|qɦ?/ir9G'n$;î6X|#0d^)_~>GCR9~߭ O~8}'C<#w`,}~ɲ1Kh&ӏ‡"e.\NvD`0ixrUy~h-+l_l.KٴW&G3\n?o8/vl1 otf MGi @⇎X6җmm/qǨ]] n0O-̏䛿[LAerZ6;5zhwG_Mo ~.OqA`Q/ wY _49_uW<"Wҙ/ooo~ՕG`+.Ʒ?wHlKxE'o]o_h,x_g9nSȞ37oQ˻#@_t[GǾ{YwdAz_-g70?udǷks1yiH}1:߀6w;p|nYX^~`KthrIu93#KǕU M)3=M틻BhM1/: }kLx>28L6~oɱߕ{}ɸO_Đs5Ntyb~G._eb`d`w,#Pޣӥ 9kn < .}w&jl;_C?c}_V{"~v6/:M,`W(.#wN6ݙϽ-m:?-(~1ɏSHtu^'8[*ȫ*- o{Ķ/ҹņ?vjzw #zl:׌٣br0x?c2 Y 䀍#r ~Jaܮ/&R+ GOQv rlЂbs1x>Ǐx^4#|ky6G1Id}|R93`:Scװ'5Ssg& U@6ñ(0  o [['EC<LIF, l6Jx x)蜔s( @"/O(G`mtE}tmJKsNI|D:IzM$;6o1$8P9&#!Ѹ-MWF0pU/ڳ$ONjSja,BlXl|L٪1:zcX7ad-J9;Fеq~2~m|66[lOn܂cChUɂKxճd܂+4tP%ߤ_ Vl`A~ǯNjc+>:M&:8.c<>~:?2mPS[Ot;=e);rBR&"x#k+l9'[)ǣ:9?9{7~14v^۝ڿq[@d)6<_gS=>9)mbP[fפBeW7R{YOoUc:+f/C^t㏏9g`ym0388ߍ<[a|?vј}^*켺w~3/;5FC@gXr561ַ:ul0^kɞ珋}*ky~?lg|}&e$67_?T ċ|Žx(i/z+zצz߽^+d6R[g5ψ6xo4v[ ܢ>Wnė:..?YNoŲ!~m>̗.ߒ(?04q-.b9{juX0N'!d %l:/_x=8=s3}[xӽ{_jP=:ktþ*d\re WvMS:Vd ''l׿^i6Z6tItPyrW9|X_`-|l ՘xnoqlql͞'ɟc1C0Y\_<o'Gxx]z_rRSU;x37zqZU>'G8I-z\X Jc\%vZ e] '_䖳x9^:zÃ#pN2|27w"D왟+* *p9~`J'¶xtw46Jo~C|V43ɰc_#+۠?VN`ly*CDaK<1C뚣A6 |%dxn;ܟx!ug=ew .~Ȱ s. )CmF;G6nk?vT֞ЍWt}2 c> MipП`%lGVNN3ɱ)f#s-^eO@%I_p)^Va{KN\u ҮMG9.O:CT}ʣw-Ȫ?GJ~26kLo2x?dS|4lprO 絟~W[fs^ 6b5, \~xW}6ɬMҙ_<OΎG|]q zz趟(x?UΣec>J u"1k}4ҫ/= УT]šGߗbK/j׵srjqv(|atdy`XZlozthuj?GM階iZچvヒٷb-~g;p 'vGin+;tt,tEl#OysA$/uqF٧GVw_w0Gz.v W=>:o iyUvuk WT*y`^_Xt;mg#6'#]O-pI#vd6It硋xvF/n r?%̿1ItCz?vfxiv M'g3\&8q9QMt+_ x-`";OrK숧\LFw 뇓O{<w>8g3o_̉ .SM/ܛ0InBϿjq>s:ɏȢܟpy7}#[E$#A_"ge/]=>}8FlEop?h{3D cGx{/{d,ڇƈ{C>zMv0]mW<;w޶pM_Rqw 6۹p w3g.?2vrõGl *p [,v>iF oڿkz4Z-^*>eŎx}%*~hη/OO-oO 7M^v\~M:?c0;30Oٞx!Scp|>ϻ~Q5?<1Y}C^X'w|sar߂wwm)|d<1d~ۊ?9YO6xL~/3^٩>G;%},w1 (J7 )% /A5c'Ŵ)G]eFw:{=` tpWw ww_W79D ܪ[E)h|qU qݟx]чVSA0Fώ*^<p?Hy?=`ft7}A%B$ #v徽AW9`ziAOK^/h>![|ҳ`#|,ZE+8_ɣ+;&K4ycD{77O`SX]7'-4Q^;7xN`e߃6Mބ?iuzm+6ռ~>/Z3'R2}$d}bIs^z׮yƮ[Id8Cf#orUe#2{hÿ6: #ut;u4TR?#.[HOӁo Dߧ3KU>py> M:o z qﺀ'd.^t Ӌʽ]2X Aq.9&>{b:<&3Mۊ'=/>?d3\| ZB]bc`7M|ɧ9?}<} nBք^^I٭5 IDATq|0ާS˸ *[ȀMvzm#xw?|mE%v[_`:Mu,b!{"|uwaRϏ0NH9a> vcM:i쁿\^cWBkq2rWqGǑok?X1@.Uә_`h??kXE9· zrgqʶHp?u#ŵYU'@,9(W 鮺K ԠV04E4J>G Q p%FA,'m3ḺpYH }`NhP 02S!y`;DI smi4/)Ow;G䮓D A!wx 1V .q+M_I 'Ѣ`#B,AlbЯyI[pP&Oj^Bq+911Am&#UJ_K~ =w|KƏWNL[#:O߶J#&Box ->$LgW?+ \y y 4=-*]{:zB*,oʷk{4gZ#6߮3͏К[u@qC,]of/zmt_y m;e]om-f_7{mvX钮 Y^uN9 &ɪp| =>L*N?2Sggyz{俆{(%20[OQb5z]V> ¡b߆5`SQ??uezRXZs%oߓ7xćկ*k5memPrm̊^L?Ou51nPǾ&'幎oL TKW j+&?1-)F.:+m~ڳhm \j QQ?{\џz>^/!wkom6tdܤRh7'Pj|CvОObV6odkON]1—ǷO/0G[Qơ/7d,o~Hw>T2!Ro \ 'MJ Go87tR{{/9U߂W >-j臭1 de^՝2wJ[&m o׽i^9ޫ&K#n'K EnBC1:1Dߍf/MtgyjcgOӧbb{Oz?X8Mۧ#&_ U-= _5'=18O$:yr(\]g-pnLdmN+t=Z7Yq^؞'<\!w-붰W5S ǷM/=,#׷\]4_-;bk~"c{ou;ܝIrى>q18^~_d%gzc <ځ=A 7h~ti= A|39C_U ^bsc w0$*>{>4GAkNi{zn40R rV+)d: }x̣Q6lH $Qf:H$o@;5dM] 35f7P@"xěYXˇ}b?`/Ctm!0t ܣ[ה:Wl][uX+=t=F+?F|Ho -b:7=q0:gar6$cl`BUe vMKǛTK8_LA&xFس ON27{xpZ<9`М72@}~li&tEsB\9_zz^9.~] ˷-qa$WO:t\ E MX ֖pzFu2wz=Y:_1k{k ~Fvg6Z<.G oM+x|ٿ7[0\O8EJ.ݵCq-.b=IwLn1Xv>Kj6~20>fS~<ޅ9a'6=m%\>_4)~*2=>몆(we m܌ }j;'a>gc']#imt{V[:Y}J c`s}5O'A<>yN4OБpnшi{wPzGOaM??qD2tNiW[Wp P!&ɓ#4GoG#G\]>LU°>j>c2|gsX!mLO~2P^ra,./rL=.UwLl?!}Mq)cB:u,k1OId]k.ؑ ňbM9|mt3|ocT|&9jv(7 {+>SO;]Z[vrAg6TpG8̧Tf>@P=7^k j#Z62v!;MwW+G.wB[)7SSqwG2b>]ْ>|>B Q ranQgLkٱ;G& OӝG-ļqn=ٳQJĮzokҏ74}Ky3>vnY]uQ,Ha )ŗX>}paSLJ"xLne}S@l8>FTa;^ѹZxڄQ@#@|;_c89б[DHtUEO }i,/n w|z>Wo\| ~DP-q;=`D|wV`t Q%˟SgMr ?c8<21nNT?vY? X1/&ۗ5K}}3>aɞ-ɕvEg~qIat9}3wW1_W}&ȂQ[<^lev$ym,|C0zI]EpF}1lfp$;=E5l Džlwu|>A?S}CVRhwiN[[(GyW-m6Q|qWɯH W<"51T~cIIӛ X[L6B$ SR fF_WmŐa으,7ӕFK>@DDŽgodWm 7Pw/Jйa?dux.VX& ٟE|]T]w6~׿q߷;_>bO!+m^ /TN t]Ohm8w򯝊][ޛ`rE876 IY7DiOO{VγU_qBuwL.>]m]I;uH> GS8X؋DA_ -Lndn ?V7ؤD2SήX{ƑK z-Ql'ߥ6~OGm#NBCp}٣rfu׆ƻS+T&oFNkGۤK>_!7#>cYO_Ӂ}}ʷLWUЯW,# <Ǣo0I80c7;`+\.}EBGvW~M7:HNZN7xIcvid=,o9ڧc^m#6>:;k9t%J^>Yʱ^@huM~pK Q^#U^jGֻIrDQN%C?uux`6ySߓz'ss[`:b5V#՛n0ڥݤ}XStëu=Q:??z|LϮ4u|EW7UyenإS:N6Л剭ɭ 0u|y_:=_ZBjD#|z.wxj ^|}v >ٚXgo%Zӝ>}WOmAtKx|}ox!}$5nma0;Xԟ-p/'?,*;@X,F?hllBsW7}$_4'mo˶cUgyl:;l o=r9&%lW1<%ݵjs~϶`Ȉ|[Wn`JZMwŲ|M"O0R~ߓ_=mj5V/jkU}rct"À} zx1!\}f?8:9w<.F Q7^vٿɳ{@6v~񲶕 )~8xK.>}*3nq1)0 ugsϵ.ӢwE:]يNW6/>ë.zc>Et3xmk$>:'^zQW~L#N0=>' q٢J9bɨ!2/[\&]a-o+XQЇJL&o4߮JY;0A;uٶE8䶵K@TXoY'k:U[yn[ItEű̎ؕ]YSH\wE>;o|΄C2px clFOȑ3~c+rec_?ex}H[fCPe w>`6͎hϘN\[ۿ=|Mͧc>?%:tXQaʍonmW?tlMh\o? 6'·ibjbc:{Y;A%WM03l/Aofw'uvTdo{-qCҜ᫋GF2*ƚٷտ);8w8O}vt X$%ߌ]d6Ә.x1 d ϯq:E<&]F־j(n\ܫ{E? Dpx[Bꗝd.ΓGߪ۫MWMZk$K /Q8m"J,V/?38N_N_ :}Q<ӷ̒N?Ƶ&.3G3 sÇfبG߷i4Qtzd0@o#=7^Ԁоx=LwN}|ECޛlPtm1(\!R њUV/=rq`a:i:ݳh>t|7]F_e)V^y`r쿆 TlV$Nxisb)^kGtvڊ_ob_xKa/ :ݝ9y&g VkSy|>_o;\{5{_Yvr^|o{u. d /a[K}̳_% Vx$!wp7'۰ .UyηQI.&șӡ}Z31`\+79GC`SMTsqpyT> ;wͦ'^]FfeOt0x1jc ՇO}QjOǂV.7N>[|Ol:},S`1LpB-VVҧ֕$oڞ̪~,{406ˆ`D'4~0U'&ɰ{σ` 5Qwu^y ~(&什Յ";L:>Ts٥ma! 1.]l*ˋ!%|W1<[qwϚji \|-Up(1?r98[huW^abC ?!vv9.^m MTȫ-j4H^^ dwrb7 ް][ܛ-1=Eno߶~~/qhN[P^g~aXmӝ5m{mM۽zp5:]^yzGD1I3=҄?aՓ׵ g^˕r2a4HLMo2bg9 IDAT1=[vx69VRr@Q"T~mn{4I)فO2bq6[}2ctUtM`zGpubT/gFIY;kx. 䠾w'ryb?.8e 1tyb:Vg%GGB=bXW?cVش;C/)0i;W}xf-3cL&,Vx!aG'}&ćmeNԵq 7V'|.Ջk{G&Es> xa?H=ӱO,0cw}Yl8sOWq'5&Zɻg4RQ\4yi4 ڕHFS~b: WKiv&5\*❌%.vVԟ Ҝv4_҈eo|V%=?~` >0@ Am]" $Oy)W$yݑ iiƜ +_##NFMԈYb BHaVPgN wC.A<$&!gp"Cuхb`:NIË>|R} 39u1sV9]z}bWi[1M~8HK4sՓwTo O|Fp\ ;dFb}cW;`?2ع őߢx:_ÓoW7'ަC:m mjm}C0ږ-71M꘎Ið KqdpC]_v78Is&8:rҞɫJ{/^"5n`@KNG MtJ5t7%>nmWؼ~xNxS;E$zCz F=m[:z;HF~<`\}1+]jMǮDmm߹r70];#'Adj,4`t{tT]}SW);R[_][ 6z0vqXKpmpޕ '&ksf4\^fE6C'5֮M=cl/q0Ztky\m)t;-L`IFN}[u/]L0'#xy|ݞ=97ۯx_S,/sOȳߋ$fA!> l!k7oҢVnBL\cӇM41?O?ij=+v"iXtI<~AWY/kG.iɚG/=p . +ֵ/~~GX9zt蝳cXoIQ''Y~Z.c'o/7lZdy"7G:{Oz krb>;叶_uX@1'ۦv8v?,&|xϟj7)xGmo8=8'GC^z 5KPGȦMFV:[(LD< .y-zޠֽ\bph1}Ʋ)\ ڇ|ԞXә/7:y1<_s .Nk;N[QbkY? X~`6f~S޻ /`Bon?G>J=FL|[[Pɇ^󪹠-vW t`]=;ھw?3Y;J^HשϤg T)N6v#XhQT`K'`pwbP14ٟ/zYȻ)r`6-+ībv'^vd'D`3$H:l\y;,$Q쩧pActgWd>s:lr::xśnɂS.Ǥ?;;5f¶TW{˳%!&4Y d (w0·"^-E>};ʽ`@C^öA$N>zN?eɛ鲃ަ_<+9>$,1ѹթ-dOo>;xJܷsm0@^'½^;ѥWI:S<)yUX>)kh}c''cb Ķ07ZH|ޓ|2fz]C/3Պ~2{gh.:/~rٳ̫S_M_--ɫUq^\cO$F"]\H׊v[`X'g/&W1dnakt+#텓-0bB$nCO\6?hu6ŜO'u,7)pu8 5o+m݋.mq_sXvw^'-H|*ߠf6Zw*`R&s.|`nɢ:]WS7x ΦןY骤ņ6)`T{!#)0ޛؖQ]? [(B1t{ + ks<9}mӟ=IW*{- ϣ4Kz"IϤ10OsY`;xإwvI;:#g9j}t˧|o js FzޝlE(؞A{d⡸zQ̝ &oby=ߛe<~&cϋ^aZ֎gL4^0ӣH[ms{nma9;"p箥j|h< C_UKð7n1dUp_/ S|Zspy_{Aދw,z_){cvcYȚYFG;/VvU.Afϓal.8{|_[՝%ʧo2.mh۵gؼs%9v|r2tN^5~Lf9( 45]w%ܹ CvOn67zW-͟m{\_M?oMF>&:>;WavSHyTZT7ߋ_ ‏4?:jd=glُ{th7A?\B؃^đ7<(': k06!7lcȫ^m,iؿd|5?F> "]OsoR*MnG^'=Ƹzln\Vlj~bF0:b* !>5{ˮE5ZfU|#f G~ONhswRW܋hŌh+ Up3H8#͢/OHW<6grJa6͵::Fm ozNT dM : >}_zm2 hmggLيϵal'mjMrIN4_Fح wFno>rr/KȽqubBzWoFŐ1dZ=f9₉~[p0S/;_WQ5W0^c_Mb;T*!9lX_6}IpU\VH՟actF]K5FP9+l;z -}Ą"_mPs_S"{`J KFl@'kj T*W`ܶA aD:;Ҷz|8om@g_ FNGxp#甙)}v|pqR}vlcL.~ۏfz'wT %05xЛ^/F*b.t\~j;À /~ީ}or1``@.O}.|ܶؤL1y~8# !=y~=}k&GmJ?bni~~1In_' 1";akӥrA|^j+ 3[9d:3v]i;Gإ N7Y>6=ΞUg}}a?w)/,bo-2 v;.?.?4 ~FmH, #zۯۘ y;ӳn!)mWw-0Swzܚޕg|~L^6|#vI$'S9s up~V` tKam.naMcyukq?j7k,%t16LvW{m9~8pRbS-~h}p_MlB^ٗ_sO|ia?|;NÇ.[|F<dgn@[; ˇkJ7c-C>_3m<=- ;wJtlNnkxؘ]h&<3~+|pWW-;bFrM̊wkhF}Y[H 3Wo˗[.??zgbX\FJ|_3ڤ$‘m|DŽŠ V\|^ųh֟!ZSNu4gT8ay/&b!JCJtoLWĩ5xb'\^}nm !HEx-`1^)#O)~xU֋3(K7ߘƜtqR`,_}b@ޝyh I{KGX-ĨPRm}oUǰf\]un|]{9PORfWǻXS'_  #Ja-{LSqP*\ToU"&sO'3[[ / a02M1"=o]CpٮNMP)T+WLv}ZgfN:w;lFg bB=& ՃcS.q(co~3WɅΏ/=_~A1:۳m&bVti'\Bw 'c؉%2>t[ o@D_\z .ys,]0 `9XɌܠ1ƕ-E{bcq8?Mw6,<Cmr8oI 4pA[,f9!!`~\֮0G-B=/=8^cK^YV<6$™/v}IقDzjY\t35mO{zOwLYBN w- |M5?e**O#nw|gm:^u*a8[Oʿj/aŏ+x/6~z\׎5OϪ94Ay F8rG ;v*[ywn}6$h" (nT,'"S>zsRmciU ~x~hΔ?EP'^wyh Mv nGvJOz5(#7Xo7|N+lh1)Cs?J/<+Q/ӥd~x1|7O̔kvUEй]&} TFI]k;z_n,P-'^rlpN sD#ծHgέd4n}MeAaw{BƾO`}b Ȿ7㽶N/o,-a3[1Ap /7f#}Gȭΰ}iwRrrH}8Xav]7sn3]>hK8Z`rjG$'w<+yyft IDATر7%796j!]m~۝:E\Gq8'Ѣc4>Cg U9Ė^ڋ'oYroq?/ +?m[nKX#kmŲ8ɶmx_zG xa간["cGOY+FcYnԛlc|Iko<1ߤU~?9vrz@^kP;ݰw4[lNӧjmqxOCcd^` i<|;'ZX,ft~˦z|9;*Kqt NŢC5~dUb7 ñS[tVFWx|</dG.|5:/o_|Zdhga^␌;8|6PNJ+}ٹd˩&4LH4>ZudͭbIN+N`WT&tFԊ^5MDN{ pBoRkƯpĄ`'Pd:Vn̂sW:f1j?kt }rޝK·wyeg0*aa;(TuDj鏭ƊIMgtܭdae򺊷[C-/ k 5cA{Ϧ>[ Q:Ϗ}_$p^K(f;gu6t]z;$+ߺHi4/g95MLw'kxE7$=lcE` hSޕm7}P9:<ؒ؊̓|3v> Kh'/ڷ5ua:5ɉ?n#g0t[EBYFO#o:#8ڀ˼ /-;MlMyɌb|/;}snd&旲sÝoiGg+wbzWnMaR'XoZ3X=}c.gD'0, 7.oEش ﱥOb3 @/&ziMth6IxGrC,'}_LXvq(}n w;{_ f>ӯc λ6wy,(0Z-]oڞB~qqadOM6`r~se? q6 |ع3rߵi)]L.?o]nO[1&' (GSxdIn[ҧ6]X-0z~qlٳ\ǔsi #~`g˷o x-_LTg7~`늛 v;cޞ aÀ.[TV$'rVDi4{<7,`댉px~~?Y4?1MT ["-<~oJozEIqHm֓.zSp֏hOx,^'ˉ$;} lm>o9]{mwbzQdS]?r/`:pd]gݑRwa@>0 ktNnnSG .0.NǷgqɾblJKmk3Nv O͵qX;«s K>xȨ1*Q鳟Bxn>/8@?RQǙ@hO?FWa /t 6-~SJp8\R8oNTSE )E\T8"X稫' 4dt;}J/IģegV~|ĄFF'{9r[u44#츢m \?3Qǂa>o Eө7C7LPhKч?_w@C=Bz dG錷:8?յUCuLtYT }e{=ՙ2m}>x>|Sq_%"SO;^̳mVn}8E\>/F1+>/o+gHJ-f 6}z'`>΋Ps!wn*W?<{](h;?WWD%&k/tlWe:$ f=_]q^صIMT".f1y|2TfT_0'zbO{;:)FG',=~e^&dj h i1N@e0.黸'VņBdjE#tH=Bq$J{InÍ}d;#fys6udGQ 1sϵk6|=77g{xoJ6xNU :/r,<3Ն0L]1Wf%OyHa+ .;d[{f~w˫=ݭt?-&BN-7b[x2\}SuS ?~/CXb>'%̭}ܾ1DZdgWFt|vuz:{?ŶG^d7W?)6{@e?yW6oWnkN5ɴ`v7߮muw~owAG,#+2썏Ͻ?aSvWϹwG#"4? a_X7K'f$`{y LMfŇڬw-N=9&#TpLa4 cXT{dH%}Q?]D8_3׀&Hd<9'oTk;bxbTyar }v&[bWgLzXnk{ikSm[nb,D< a]O/wY\?d/G-Y y̮E㳟;,N2*ӛVv sX]ma{Y{boU!ڵCө7>X܊\/7f10_ n?M*3`?-حlOڙj(Rd+6s1A{|-:TbI[&0x!?糵/6Nj!t|VNkDk+BuVUN9`lz [ImFs|+ͣxXݓqOU>>y>9)XG{WqIm +r,88OqTf,4yF1?eJ wGst;^Ρ>ե%^N='tcKox?;ӻ@v5ot^@ǻػ}0qcfP=<M}L4#MD>u#tpVF'XM{1@-_Ǩmxh_άw{ooJ Los6/tb왼GmW2;ֆfc>E7)OMy0\u6U.kN݇0_\=IޫiqܢUܵm_?7t9iTm=8)B~;ǎWN qNF{Eupx s.{u4 1L oP%{b5o9e:<:Nw>|RAjg+.3Oe|ʾ7:[/o`p><<Μ)l{xy3QyT9)\o#?HkN+ޝ<m`_rۘj3C?jyMklevAԝi=02A> o?0#MMr6f6,rļ}>=U 3r[#>ˢ+=?6HqM ȱ𢣫5JjpCGl;Wcj 'z #l)u7Yc|W(mBoOkO,_./XPu|DlqDr;u<}7@7,iH- tS/_r0dkOW zꌘ&,0 b8$.-<%Mtq7Cru3uN^M&n>V? >kMf>&kma: Pm_:yvC1D_OtWAn2S>_6~)ױޏȯŻ% kN 7u~³WVpm˫-yrgxfb_ )~c..,8Jh^To"'E0"\k^(x"0TJOV|}GuO8{\s-w*1I-2o #spOdOGq;]-ďN,0qn J"|N.`OױV ڠ`^*\xy`8>Qx1m^xsF*dö-oO9͋h^L^=uӽ$|u&YBaw 0q@ 9cz+³=^y`It6?[mtWuZO1~܂4[egUqD4+ܶ&#ߘgXcV؟͆!k_sU92;I+\7<NNWtϻumI<16Y|pWƤbJ椵NiY0TD0VG/x>v FCNz/f>>mď#G9WNὶ>>unLs߸u"],2cq< 5Mn>:[ޢǔ[ :w~NVx}^ yD{[Gk+|#m~8sʴ'&> W $Oel0*~ # GMNLޜ-|;1}H|W>*%;\d^'e:KDmhDe@7umde∯'=ø˧^jp?aAo59)jُm$omw;=[L(x1߮mwu+dث̦] u#9bt1Hva!֞b ,BJqVݕ'~f_6Ŷg(SXw/&y!ֽ}{ħ:9?|y&l17]9z qY#ӱ6ߺ+ 9c#Q6a%֞<cIh_ܾq*L!*ا/"U@H Uw OuvR*L?Ļ$Hfik{x+SȔK^Awxc-}-G7 w[ؿ-|Q?.ƀ(2f2,?z a{wN=S/obm&1xཻM8%|w >|~}`?IU#~i} ٝ6;fӋ%txGbQm<$3=Ń[l$2S:SaOtJ]|[mh؛|v# 5x^9fc-?J+wW)5|[ljwr7>uGnQ7Cn>ƣ /~( +g'OaAd[ʓQ?e\_j_Zxg=/O(`*az{*c" eĒFgG7 H{ݦ :>: @ x!^+'>uuS73'#+SI Xz,W|rMK*9_ Ƨpxw#-cC>GJ̎Bu{ F<$g/>h؆?àAA?mgeZnwob'amQ_η?L{c^ >OcNc0I2~EhCC_fCèsVĎGq!1{ş{e;[yxSnO ,gKuJa7Is~~Afx' ls~axapsBȵh;ڕ'=K|KNvX~2#W tifA;'<+:Vxs/[l}9&=m+9ڐǎy=:xǧx\A (^ /g$`.gÁmm&?:=}>#ou/>XiNէ绞)bNp' +~K{ŧdyBF?ЪlTan[bd98H5=/hKzv&mЭmWG[1 Mkk$K>bmI53xG/۷vh{lE|wC&{̜&(lM_|994vjgeO×JE?[\ـ}yE#:Y=[Q0]`iotI>o@=Z~.o%&O[[X ~I@5,_kGoz++&cާᏋu?v6d0狴KO]PI6];k?1Cj"(~ wgRJ 2LxBj}])'O{5TXܹ݀K~ǿ?g0Fn˱wq/H{~B?ƟܞJ_ ao۶nj-y]}9]}_?Թd.}̈́\i4I>o 6\}۫W\㽜O_?],GrVk? p(|F߷~$ōM* OݑG6tF)8Nk hC=EM>uF IDAT*/{ǭc`v-`v|+nSnrgdp.e m1ݎWUFeOZd>=D:*[. @?݂Mt o6~:*௝10;QP_~ě8΋'ǂ;V/dm8>-U =r8`1;L_CFNJT0NoTaԫtp o_ wԂ z'bYuzn+:p9`}Ik36,ghh=la~/=d.Y0MsvyD:PN/M!bs=LgN>}úrvNy{幸WG%"-~KX׀7. {cɧM[m+TI!??MKpnP!<^%n~#n`T,H'eS$LA~1hEX,~MOcO΋[3?WFUޠ?gx:BB HУcOfՙ$JJF3s?eg Me{BaG={b-ի\#6kK?LAJ"Cw&u>oPJTӃW3b4 }?q)?޳b>짿pn9V؎`v'6 ʼpL=SNͻNZgjhA%> :_K`*~pm"Fʨ0~x}BO-xė9ŵp(#óz7p,'wu|N=t2ia&6UQ?7ř,gG,]=x,Gm0u_vglđ>;y63Y%~udru3U<,bn[[:FcVa: @, #q~oPC"M_Vl[cS]z(؛wu p6c6~Q@B),bXANQ]Mw8t޿ۿNG1Q{M,>XPS6%]|0Ftn刵A) uϛƆ"YF83v5|],'k0 C߰iε0FO]k Vl-~i+ƙ[ I1c (^Q{*>/дw>Wgko1] Ɔ|gkunfmptD+I,ΑQWi4jkg7Iufl. G(aJ=9Os>_{׽#dz{SvB1gܾ i㇯|l:DuavF>ZU{ˏ=򧪳C"z;sxLgeՍԟ-<ӻ:)Qg̞EFmӞ'F=⇟-"gN?8K.6w@z@cO~H)#:7{AؠHyF=xW_WrԬ:# $vu &&iýIxW'SրE"7Yʦĭ"w.HLX= ]C}sFb,?0Kl>t|t_nc:9pf*>}]Dx&sx=_?OYupuj>_:%~{^u/!Tqx4b˾g8/?ݝ|T?8]ŧn_;~xWi#1fkP١H‘mQCGۖ>K:4mh 6@r7^ɠGcbFLAo01I)oVO]y.?hmx9=$;kWwuMFo"W87И׭ u&בX5]v>>o2,foq7K=~ubO&a#E۞˛X/Qm%17p9~ӑvO鼧]!y=~0S#V91aÄߞn}OV\bayqGp/TgcwcvZ*2`t:X׃vȊ7?6iXdb\.)LLT+߯|nb7 ?ړ; vfFX,n#N߰bḠv>8W^3kZ7# 2,d~f pm䄼|?-ӰHVkkS0Ք */{85-__HrSrRl[`Űx._&bɄhrcz^+87GZﰳ-_kWQ|-gi;\ {'fl켟[Up6pEmu, d;<#U N6m߱A8؈#c| >%c8Q\sܣɿ4Xp>+{b}}ųŗy[:~:, IXPo񪏱w ;Hx[^%ilPiefvVmq{\m{Ud'}YNN o (<j}w}RJlM^Oc<~dοN6UV'[$_/-rPx~jk1#|h9lf ۛ$w#omDqn׿b䑟>_ћ].m4 x·5KEo"/~S=>' kOMxYM+>b^\vY4cgyumó1*;_x9gl]b6w+Co%k _ҹs1AFAV Nf yxWOkJ^d|߱[ .8ȶcD;Gq mcţEoМl2Gg%o6:{ɢ1;;*n~`IMeLzj/ QE4N0e0s[ blomT8+}}4pOdWG=6X"c'ȃs9BHK('1ݔП Ӈ!~&#]ˮ6/9]靌꨾m|C ݚ>u~1g 6Ur+['*+(lr s<#?t6Qo_:,yկGõOw{x+o K>+=8#inKM~3b?)GE+?0c#i[+l*; {,~3HmvQq{Drs'M0)m [5w%B;XNoryս\slo:03],:aF'6fS+Y\ѬR&yo3b}7>`Vl᠎L &7c"%`+f[ڙ{xLOE/ JlR`u3\6Y xM3P0bⰣ7Q+k>W=^,1:('u΋vn$ƿO8be>鸼snmEY<яG]U+V[ڏmMf1|lOE.Xv0Xjo;/'X|};Twҿ]Bܤ&c=8ړ6wgt('{o_[!#v_}vߵp~wN0^[~-']-iZzOب?x9M"]um;??宧zyȦ?uJٙ ˿mW'#|:ˠ9Õu?MaNmJq8LߎO] O $36?c&ӣzd LmIT7M6iQ6[<LCFA(ޝY ۻ#:V_t{n~eC%ޛ$ '-~T:_4"wË^M9lW({uٵ$2Es8X.] ަog(HPau`{c8[{7~M~qzٶpd;Y?wROm؜A.Xu~qرE:g$;:s9ڹѦQ#"UtWދ~B6ivsYWx`dAUG}>ǡ^q4u RA,1u}zwXVMgvru;~d$/r+wv0^9տ4ݲei~8GFVFeB0PF㖌2CIsN3߽Cz}1xe9}/_ f`NSR9:&DON 4|;7 JZ󕲵kqzOl*ǿwŚL=Bc{YO?g<:σh QXgKR,s,;.Qfbgtk^,:V۶{دze/.rj{uky>j+{1¬>|8kGҞWFO)ƎF+F|6:lPG^wg vx hgK6ztdL.[3}B}$qѵ?ha߂5g3t7yQ&@i"Xn_6;DAeTwE_M·GاxMmltوyfzldcg϶4~}ktq8>ڂL\M{[ gPb^\X4/-\J 9pV1MT֟h1,7FN.?^K=_l Ќ}70=:i6`bݸ C}##Ä km#|Irۯ41n֯oOhg?kEG#mtw]Sf3Z@»]r'pϛw~MU;Ŋ&O<|jpN9Fhwj捅]2,Qv.ίlk5/u{]7n-,xl< 6a ui=n۟4M7K=_^1cѹocRlhmkw6#矋]A"~أM05;M`FȚOJLuz?_+~叙,t2ؓd'<8UD.;EnW#>^hO 5C5x = dΖP㑿ضߧ\~܂Ic6._lhLJtp;;q}+~shueRRb7OQfǧŶxmS cU rǞiB{ϟtQ8huXmۓvayYj~X mO] |itEk>~EcOɒt^_d| ¬mh KRޜA"I %0*XSl?<31 vizeN\Pm{;pA~du9$ vW(쯎| יzri_'7AZaC|aW|nvw:pWƗ2mumsM_CޢN+/ Ǐ`RrZCv4Ȣ!w F- L7xfK|*̈Oъ1V lV?ezp__V1y>gǕ.c/pdC+{aD{>b}n*j@z81]TL_[DXuH[@z&K#Qі_=%B,I~bڱwtv $ۮ], )W bVى~1lʈ?x eo=yF倕_?wTgUU ɟy|4.L\*;WHUNZO B>ͮCߗcgr.joa7^\w>ru~9l/<I_GzL-껗- s,ړ}aҨc^1h,Ge?NM+= C:#w~H~gط~zN<)}b0ݭ䬺 وj1k9gHLӞtp7JUE1aavѵM~bG'Ъ&&W^.vSͥss^w}lZwl~Y:_>ku86.Qt>BRǤ-Jb..N_.ض[6) s~6#?a姳GU;yj9p*룫icdg^.nc$/&e5.c8߯X$`~ϾGb= 0'|$՛xpDOb9cvfk(ۛC`9ŝ9x/_neOcJߜM,҂G-ޞVlK 2 Ax_sybs:E8G4=//{],dQu,fLj2)Q7h3KF'- /̮dxJfW1,z}܀76|rmq oTv4ZMvvaY L< P9~Ӽ}s˝[ IDATakFPAs?3NI)Wmmbo&tD~D QN)d^H֧/bIGfDsvJS~AΫZk4:+8{dhfg. R3> (3*y;Π S.:ٶ HKǏ]h'MƳe'c^*?mu$v $aéZ4/Om}W>'U?} ?< tv.x~jʢMY+vtaul ) Rx˰&᳉=87=۱At H?l5]߆38=|ӗfk6XtrL7+3ȯmg_l;XG$>myoߧ6iVI8kps_8ӕԗVْR;679`|s}{+=c`W^7[ ˿}?>\97ݪz^=y1-NwbUMrﻼ;g_4Y;9l"bL>8wtxf'rTx.a'qdGgFF͟8 GےagX/еUw|ǟTO6}hr^r~߅c4S=;:bz6o5nQ>&qWBNX1uTyc G]/hGd`nBf5H󍋇=:;Z$C!&P0lq5_w/Ct/l:mIvww Yh~}<bj#'&CTu}Я݃y]&h_u7?>٢bYAhd} P-wt'O7NL4pFpa[ 1S\%ԷEnvvd+w~􋍙籙b+{܂P$gOFxޝ瞾/ޭzzO|o?W'gޱ}(V<$gCߋ3bHãtB_~G]iGcv㣷ض_It9;zcb: _y`jWNwV<5]>b(ag]v}6{_Slۢ9k칛Haw3_M'1 ^-W}}\t%'חK׳Qk_;x _o6GwpO9¤GUkdߢ 9N:hS.ge;;>&`ߕ!1ώqdc|[\Zd>Ǖ$a=@|<_Is._S{d>ݓCHe]ʢI^czc=Bg_lp\=~|h6ϮjtGs>{ZأxH׮XRos1M"_\Ǩ6tzfϞPEOƒ lGw\b@){lݫĠ>:~`>G+FWu6d/\\6ր=q3?G h3[x_$[߂݉@c[Dx.fo(4UiՒn[^:7ٸ_(bsC8ٺSɽEFӱzN-o[}}xsW.7εN->[.t^zV$F7#\N |T6&`xxo8}[> E&E|D>k+ou NFBQC9۟I<U<oa1F>Rໟ6ʷ+O͛/B5xO)z]$gʽvOý>wcK{fEIEOF? g77Fjsq̇җ>1L?dmA$|˃.)ѤKC1Q]c2: o~p$.n>v _;ҽo5b__? x+^Z/ɴF6_챾wVWf؈ #l?l鰾9XdG;P_6=I=jvrdO}$*8,x)iEpoNq$-W9([U7ٳ DL?yE$d9i+xaFmxOM"@t VL=%3N{ :|sQLI|u9¾I;u{|lC}Cà"̗p٠.. ee/oF9q7]h 0msTLP{NW zHu桙? 5c;FGs:mk{|<IX]@zSN :7h@TýZTqa#0wdtz JIo,Щ {P@||٦s >Sn`>4(ﱦ&{XCzCO~{m?ӷ,f#8m̳Orv\{uhw<)o~vMumK_[̄{~|3S?t-'nztJ㏼/6z+A" {L^ŽyPTnO~;2=/okǻ@}xæw,=,E&Ppɗuycϻ'O?]#_[~}?\ lb[%ajFHmCzaݕUՎxX9ev{>#=/ƚxŸ>ᕜ?\i_p7MRCY|3$o6Xpgj@煎.&&{oR!^HObkeQfw`b&,ވg;lq{b,.<&]j>jq!Lnw2z|U<۝.AE;vvQNw6X~pg${L>̰ηc'(OcgG~bs~xv4c"L,>1?w` ,NoX-Ob}R\9<ʳ_uֻ<t[CxNGB^ͮQn j ; liMz㻛4|>1!֐ͦk2{-E(=\Tٷhr>*+޿|^]#0A\Tr g{~mOO>=js#.G|Z;D8"#}Mh7bW4x˖T_"Xx-Z1?t#e_ -i+`}u!iӎb;L ߹\;“v\?[_"#ToN6tU#1%xx'5LO~ yl'fIF gԯ| ΆKU3|LMG3GO`v9?/;wa|Ì^a}MYYy{zlrLcc\ȿŹ|E}eO դ#6RoR_׍#oh`Yþ6q}(qمtWZ$hTXṞXw3>[ Xs]E 1 wA{ƷdzM qfu #oJ8Lc:_gľٿ~>ÿ Ae=$ETZi{{AS->_KݝtLAmHñ ώ0a$i)96vۓQg30QqǏE_m7[?/agY cm.ʟD9NBO0x;kV,V]h{uؾwCxgt ix~zt~#[@cu[4}jbsr1yb4Qb]tܣЋ#dJ-8$1 0vڬOgc4;CUP0o"Fe& =ďY QM\t0}'gTO2,M|8Flқ?g8?Ǿ#l?\(kmubuz  {؝72e#9z6C<0X1k;لoA|#f8 oe8\uZs6O=+mD^L6:cMp`FpBiEK0 |j")xlۋqw x=\Cp|),f<[r.b{glWnd};_7?Q*v?mk|r=nz̰;Öh/^ttDSlN>Ze}DyӇCڤ`4fl%?GC?l5m_y1Gӏ/l@$O,ɤ۷Zg]0d'1?\3b1#dJwBBv>b Ĭ|)wL۾ '~>%WUM_EX>Ҹ˦۷).iX/L;Ζф&DV<.pyKtlqa2\7wq!]q]UZxѡթPm qF7a/ۻ\0caoS*ߑ~"[?9Uu}/F }w:`L6xlK$tؾƧ<)|Db4Pɯ};}=Bώ n1΢rO{\T7 a..M }UB0˿\C%wsi*I^xTʓxOY |עi vٲF-*Y Een Uo1VjRŻ^QF|2nS{{pOf52qs|A/,m:Zuxz0wS6{Gx..lnHcO_v~{pSc]E; 2M}gKǶCt?oj$ 6)Kկc*Ҳ߈Rgx6Z8,=- 6Sѐݎ܇{!T Puxy^ Ww?W9]A%saRkSم?.xO8nTl'V6ze(ykpF{/fќV;'u?z6^ 48D߻n\+\w8됵x/Gl57f֬?[hIlX:Y;1NxMC;|Ir^٦[;hv~5FOb{^::~wS֮$zwA>l NN$ 盘[o~h1r|"MEO9Ẻ dxj&_] O&lLȘ=a̠~FïM75Kgⱋ䰑 KDG]((08K]WEEgЅKa^\7xt1N8" #:~p7> &9n;s>=ٛ}tO?@؈, }4ll㜳K 2/eOt~P&SU-F'-WҦ|/7lsv 5KhMPYFX{8Et`/Eݕ0V'zDj;+Qo6 -oqilZUtoI8GI]pĎp ɇ|~xٸ~/Gr3ߘS߉,iAZ4Vt4 Ɍ򉉷_¤I<՗E^y?k$ HwdF?>_oxaE{_\?U[,o>-̈#w3_UM7a3ڛgV}.G0A66wn227~?g#WTriKlwoMwXYul|Yٳ-TNv鳋|~UG8({c=} ߈L;Y>69]5];D#,h/6-~$bfXƏɡV͏~Eq_KLlx~E׈˓OtP509}|Dl}:}OC](4ۧۛk}I'd H寝zy]?ֿ-SiS+x3}~mqGGh˿ Ő woz=VְiFG"? E[[\-*b~E|.F?u68{knxMKQٔÎ{m*[[eotxtO|tHq65+Eg1]p+5v3& < $; :@;ѝ[cEN\RU1~ڹS 䜐:fsM< ޟfQ)ϸXȋb oJzI"'v$FP)Q$> ̂5\ٕL|wA?&i6YdplKD96(N|rvѓYɟ7r<7a +g-t&;XڪJ{tV= IDATr y u_Oؗ?-~6`~?I6ᵏ/T7 (gXmNZ:4ŝ㝷UGvaoBqD+*`sv>˯_W8txʾpο=vڃb{WS7 k'.sS-U 6߄jTiI%,:p0)ٓLN?dGan1 PiGftG2!Ȳ' '.޹C|kxq"K(,>KJO ;^D9[fkVH\9?B~X61;.V?rmc\Ŋl4헷O?gwb3l \/|o_Ä g wI͎c$4i=egf@cwq1E?ڝ;}voGn?W ,ؕ( 1o=SIo6"@i\UO內~݉PAמ[TqI{3}"@U~uc?|A2ʮIpYXy ?M7oas1rvYӟOFd=?v؊o)-x4O 9쒉uQ`{u4l/lr wgb҄.5=0wzrXz9w#{x+aŒR'x ڽNg[+/1MB@CM_g/ ]2[Hbr9WJV㓍a7ظ3IכӿbwA7am'׼OObW {]] 8}x6{g {SE?ə~tXOF:^5_xmq_G׏&fLYL-.8u]?GcB1G4;ex}{ h ,|jer1OW'g[[U0ۉ0d9>~B-f'ZߌA&6U`>md_w_7/\m wo̦nrڸ#;d{ͫq1c +]]m }1J/ENX6kOv4=a!µ=,~E3xE}{y~>:x8v~JV$O^\os:Z ˧鴟[y@lOqTOxMEl{\;3N{ö }qzsb+OIGw0'o!c_Y)'a7٪]ֈrf-oZmVvf'G~l 'l\3<-OWm6}k":AOtm1"GV&?޳/>X^9L;Ulxy$ L/DOuU9t¿'~rrm;7VmO|O[$/KL<2~?WCז`oچrA }c?40?>tbւgry1;~#on@0ўR"7/37t^'nO*9E0jb2~y 9IPRC; fZ»cūN6gG&wGou9nj9Q 1^ Kؾ'.m9'|e|"}f/G w&kv@JLG:3!w}uW=[$^nD!A|;ML*;Se)s}J6h&\YT6{b,T '_j·!uw_,өtz/[K=dkڂ[Xٹr u>~×,42͊e^K=ʜ˯XvYW0?G\x76 W>ٰ-ݤI\poy(qRT}F&6ĉЗVl<-^7fdiL=!`Uz n-S(.1Ȼdт 0V,JK%^jkt7 Kl ^E yl4pl~ 糋hrL{l1F1ߩ7?Ebs._1z>Fϒ5ޏg񌊭3gBl &7P*/J;F'/˱[ٝ;2)~Ss80p_ s|3U߬67=ݝ*>6ad[|>o}lIžIx&{n6}jzt\hE[&Ww.n<>If3Rrt<8v1əD7ξ1[e'|@ɉ (C71M.߭__[N<MN~ۜ$<ɷ_vBjH6wqGl 7O7/No~޹ٴqw|q^xv~;{#KWfjkj7;f[Q}2>W8O }w=|%;bOn|7g+OG 7]5mO>?Ǒ]gc/uxi.c_#H헓d: ͊Qq ? kf{R$R?]O1cƷ0!fxg}@Wpɜ\{|nk.4Yr؈NU57=Ƨ8b'6O\_&-ٓEX1{|^^r+~twn,XϖlE8z7޳wg˽[?/|t\J>͆^coЖw/ ȠO'Haȿ56h8U| m3!b("dV6'tM՗߸V%dGŀ{5Yf8HK[L6?럑XSrً2_&}ݸ([M^?e4|IfۛW*_18bozԅ ģX݄&Ϧ7ABEM06MW88>c=}@|%Džep쎽WJ(qbIn= 6Ɨй|;U ꋭ I*<Ӊh'._ӿտ>x6}.F]&b$cu!=_^`txU_~cX\n!ѓb~M>\y/|8)Z^.5s/QE~?&t鲯ɫl7gN6;إ|b!^EbaPG]pljCVD堐qL_MVlb.][#, 6H;@ͭG;/eqOnꞖ`dO8feq9 q{q>;Ǘ1i*ViRyW]w/}IlLa]yb-ad>+01;vs Dۄ bRnXh9ZIY:kwXwiBp> e.1|v0#%m'ĥvぎ{Eɞ&Cb,~t]ދٲogo~g Z$;WU2Bѡ)vm;}d8X zm/9/:g/ [.أ6.|${ 1;ЧeM5H[5s &- Jm_={L;[`&Ml9G@)9)dfKO_EN[?h<S hw v1o RI=rM ~%z!q]x~?HU?, %'{1$4й3F@67y棭/@nY<.lt|KfG W=e"N>|c2W 9tNنQ G{|l "J*|V~x-,Gg&^ *M/ :OnqDv5ɹ\p3UAL̳Ɗ<#H&/MOBr\4j#|蘯nbن]cp̟O:c9$mӃ{F^MDj=l|VAi_b1)Hp<HLXGIl'oܛ϶L5gcF7L-K?Կi8aH-0qp? \.Fnǩ,=t{g emhވtSOa1nBeY\T+[0WszuWxL4O.2>mFP|p}bwr{/_n?]cbOrX1ϩ ~M_]5^]>Erh}m$t=wq|w'&mfcgG8uA\LVF> g 0k~~../ FvNs&Ot'¿:e}»J_,)Iӡ?.oF )Mr.ߒ}+?'xw{#kǦ?]ln}w\? ]Gt"lxwSчt?߽Krk=l6gJo8?2+yjeՑ}?l]l_+se cO>.7'h/n=N6џFs_Ug:E2ٟXj5LEW'O|h׮O\tc =@x]hQ\>>G+[t~;u>Y\h\0o om6>T?ylñwbu#NNF, 2ŃO@WX9t7Y b3hbtBId۠͌fUp1(6T$ q}<A!::@a#ȭxE< K-4qv&px5;(=fv?]l ׆N{xmb4G|܀5*^tk±ɾGʱ(|婏uH~`4&M\fi1Ȇ7P5tjbM͏pgcx OKu1MP␬ڿ{mL6\cse#&scɧ/t$sGtcnI[<\$\qnksݶSdqbY?;udmqϻeݤ:T|> &lf1ξ6ON/&:]7\B'O'LwوsQx0Ƃc6㑑o0Q]H&`ﯳS\k}{><'}stqBdž.{Y۷oὰ -?iHRrm'{\u_/w|y>f'?jw}.ɣWhe/NbVG̈́ΣՀQgf]{QOb ؉Y:4y^[߇>}@z i7\+<1_ %p>x/6&dZz9IrÄݣ{^Ȧh̞>0 C޻^r1tf~/ޟ38vPhtx]9"D<}qr@oAx w~ gB V]y[cφǖDJ7 ;5]{wD&ݾ[x&@:@w¹GuvavѰmmF_Бfwy6}4v{<76ɦ U_KC*6IxÀ[txeF6x' d(n!&Gٮ24 >PǙ ]^ǟ^DOz 6Q~n̎[Ӟ̳ 3$æld vqǖ|L]gRߦ }0Ӿ.FÇ78^[@Mke՟Ź}XH5FM%m6+B[#|!ȲVΓ[?wt7 nҼŢ&%.=B~(rBIowg ăn :G?&a>{<%Iw)M~9YgG/ʃXg/{"}6оw~,oqk6<[f'1a '`C+ٲv'KO?컋Ǟ}2MHg+MŬi,ll$L_;̞ ㆎOa>阭6>&GQf}VI6qjgjSF3v/~';*/p>Bٵ_ji[O[ɞ_췴rR}eίNxW[peO_lo K8)0ŨFbw/'i>mb ͝QmAqe!NsC8+:u[ 09\Da[k}Iq1Vz?"fז}OӶ=Fbkv4Õݿ_?Xcs[Ѕz|OVJ8wWNpu [dȿbh:T8mL}6h1t}/n^xHff'6E.6?.~ !3[a/O[3w:& UrЏ~PIbFq.wa/ =.6o,5|ٜ@\PM/C_G6v>.fQO^\oyqZΡK}e6O:_~gm<Ku-x<4{G>~- O"xg4mnU9)Z-_A7765P,sASܠ/z~c#?=}]=Fđ^.o=1k1`ѫzmUxE0` #?0]:Wٻ= CO@mµ!sȝ3Fjqާv?|Hr P3jJ(]Msj%C0&Y'l fQGj ]w<ޏ9_ٺ61&&~ :ytSOIRѶߩ#$lľ:8p <#}:J\';;tqG7?U}g\VӉc6ݱ;Yj*OE,Uzz{&O2 G<$%?Okmv8R,o{NӝћO/(#=.0odt%(?ሞÄOX*}d}k&6t.ka9ܣV%;~.WlGgSٟ\@}>`6d(vmw|^r|x| Wu{f|푷|͟m?rfh$>o[rѯ?z&poLփ1GxF>rD\N t;M?&bw\Gw9x"'[s7EKxeO;*St DÞ7ѳXsG=,yjֿM="'W+cw<#g 5v$1w6.`wM9{=11eh[.vFƁU<=OS;lu3+VBM^'#z_.ls6p<6}o!s)ybmcQc?z3/]ۖ6X߿E:L&':9Y:{Z瘤:fU(({}tO}P=[0s(.~SכF]\I H \9Gzؚܶ `yX\.F4?m;)/vw=ߠI.SR1%Iqf$>w_|v:M櫛Ew!ڦ}xgyc2+3XϦ_u!8[}Yu+_ycX)cl0鴁ቃЉ7W#6xOXN"Ͼr%y:Q=Ckw5 񛞵WvX <=&6t%"F 6l1^H'3s okmq7ʞ|r`׿цk:uB|:9<rKr<N WP=_cq9LṋD}UڷWկA\9h|V00+ʼncIX߉ 7xkIU{֞Bceb/Hao~͗R6v(~Uc%OC=;c?~ZNH@gL|6LL]Ȇ%8g8v |g~srO]VXnܯmlRQ]6{fƱ@,~tV{Ol-w{wɬLw` 4vnBy36T3^ag=f{q/ 5g/ĕ˅Fc2vmٝ}g찗5&kl9NUJt?z蓬.G;)^9K+,.jwt~_'[h._v>N$ Yv1=Jx{2y(^;}H,7jGy$aH'^x6Ƽ)~fm1EݭS mEb!"7p/w߾w:rwq"4VܻOV^x;U.ϴgC-{AcPkz~7{w=$_Evqi)~KF-j={wI[YB&Njp/ؚݘ!c9_栞swۢ}y|d/ر}z.OsQ og#qSy2,tq=4 ъթmV=9G/ ]u~˾Al^?}U'akh}$O\-,pog){>Ȇ|jye~J镜eVK[`3~W 1'~4Cvlߊ_3= :fmߊjNX%sCl89>^  TGA3 $1Lno}3u 9.ݝXpgޯ ^ $2M\DsmaRv}_ 6riIN@8:|g <`rdfmZ7%b>&ٽ~Ǔ܄.x3޿ B~D{%l9cIxkO{&)O޻Q}w/=G mRq?VD >&.*X~խo[зd"VU':tMV5O}_}ȿ&쎱$*犯'3]V6#ŮY<]Jl1 7RGقBkC -[{,-YTչDC܎X^{+t7#ݾ?b}'H\"WO_ *y߅]䄵}o>چxPG6pplB6 ƐGwC`HUFhb?#]sd&xU{?ݹ*gI|a_Ԣ=_lrw3':dMfzIz|a+V&Sǯ {tP/>f/h֗ǟDiSV{/p1|ǧwҥmwv1O86bd9b;M`]\1HӞn3&?yrNQ9h'I=~43P=c4?'͒nkaNl&%B|GbRXX&d<~+<;N[`=鳛03[4: ]>/Md= ~ix C[~<_/koD xx6>r1paVMو}bw/ܿ˔n/>x}I]{_c/~swK@{&5Z\)?ON|6ђ9+ӽJ.4?5[ԏ^OۘI ܄'t9#fu,Q5Y>wA4mr;?CG7ok.r'Fdowqy7y_o[Pů!r/GgPf:$kmW?6g?abi>l4;u 6Ό.+|ƶɊS[3\>n*Zxv鵝^ \/! '*h?-v\<; ;+bEo}lA~3't0O x7f5d_+!?]{,>=c߯k$[48u}UBEU,k Glx~y\%c!;9ޜ)R_qg5q$K_1r#>|h[P9}v_%g8"I1a4mw7UƩB0!?ފ+R@lOkK^D7'p}"۝0شC}w,cza # 27/vdm/~Kk[ 7;}I[XcNQF{y7U3VtXB8wsYS:5~>a-z@O-خt-ԪBRԤY06~%-H4y/ED(Bҩ$r97,Xp/do ={fV ݛH.o&&y|Zm`;p$_*vciص٘h\!ڟ?Tzs>ʢUXdȿt{d}ԥ76*_v=xg:Tػ+rW`58b y0@9{ ;U;Yh ;pv]ykDfkWFct |5h6 c/[ _r|9ŏ^c|_`Cf5~l6 0aG[E IDAT'&J'+6Zvj6]%IN;5~s4m+I2t< k4Ol|\+wL6|SGm tder5_ ]vDXMr$L`u$>OX+&b ?(o:.?hFF{[bC4_4.}`\\gZl:7\lDEeH)WM~;$鳷'gq"MǣJ|Gr2-ӧDsN2&,bO]bz| nvmP('I]ɢˆtW=,6>b#]M??mXϮ7.WO^ڰX>S0x}l`ϛ6̮Hgo{i[W8+\pwWd3ӻ '&߁ &/Wܺ~LԸ]eIu:Q/@oG1)l]*p|Gb7[<نg˜(ӔM /W a{O@3+ӈg A6Ӯb򉍵媶y~Ifylc W0ƫS_&`li{$rycw̢iuW]WVoQpXoct1Rq ?MHOϖHn&iԿ_#Fa;y>.ޝݫ%WEQ̗glqhZ*mq,Q᢭6~hkŁ *}زz$Vy2شkcX_t1/=EPx[ӎv6?.& ?YxÊ6qUL?S0ffR&}nys?n+tGmjS࣓} =;ޕWO~N^Ia6rل+FV/~-HAjpSJ`56}ͮI?K-mgZWH]#!-5r_?9Vc:~\)Ce' {GM&l;qz%~1ɣx;*[>;.?ke|eu }YjF'+?ejOXٳ #識M3Glq!vƻA çeu8<3vЩۙ ʮ76?{ɾ 0§C|_'۫:ْOS&;H18+:& {Ѣ,$<: v'/6[苯a$N|p`ZǞhȧorF|F9c*I>+/K2LCFl6Ȓ6){~"}nQs~LlvL&b@=2Dx+2'nݲSϻbFYb$':ɿXuE߉pHN};? 2G|vk<-jB}+%UW/f'}`-:9LVj+>'Չ[D5m9bX(۝#gM70-2MD&aHt: `:WSWfT6ҋ->~@CO6gy0&ܱZIݽ+ɞɅ#'_n82/.tM]yq/ 1?կ>Ư$kѽm 3/m pW';]N2[ [?;+ ?_X۾s7$y|6ԕlS/ ;R{j=mOLQO?ש_7[4衑&;1w/{竟g5^A|Loï5Yn&{/GS?5F_XmS2&Bd {*J|MF >ƃN0?w;iԩ,7;Ө|oBłu*|GL\ <8=d 0+T웾r*cKټ$zc@L18{]3`zWpOCǸ1@y[Ý7q^pW mӧ2YG_dp{_zlr}`ڀ7/.1IJ[KOyMð 7#[x/Lq ; YpQtSn/B^lFػgBbOG\0r~)bMF$_Yꈋ`׳O0WF? ޠ 'ҹ{u[r`+o'xn o0jM-yZy}p6^GS}r>9O mu#^gϏ 7PL{a2'o@K?^*N ]=f`A1ƷY[ WFKF 3mnƋo3E1fӵ;|u nȏcɹv.>G E۟.]J~z{B/=?J?00aɈ>}Oy܆7[(c:m`/(wvtj⧍Y 7;G:&s4n/_{M'`iόz?I= }A6S:_R6G{sN>7p]\hF-7#wX]L,?w{;0h%n.'eQqw7!Y;{; =n M!.y_~nu**&j'{T=JwB}}c_Gp"miʇ&Aߝ:˦-֍.][0$W9}?H,WN=XCwPK׆{_싛bw+}u^ſݥkvsoK*M]a]YԬC #zxB[0:)GH>/mXUȋdO|.m%vwF\+9<~L_,H; :KSu(rPY,`Ǭ'V=x\T:R_w c<5AX fPW9h+ myьC%*+4_MtCW@ Be{7RGħѠ9,{9y<ɖj8:o2{~sad]ix)?H}iMo?ߒɞ bƆNr]x ~i$l x} =kF~tWrln 4 \M]<8Ÿb =<:KbŁVOb^}W#l e=~wDx>?kB1f~~dOe "<N0獯 Adh(Cq~WD}6N"+7.,~\&dQN,_n1,rZ`ltta6iQQutMX5^{x>aV⺻;tioCXXnzhpS׶0hѳ+[^UW&| sCw8kdOa/|YiØӁsԓOz +nb9{\7я|mdz:G(,11?c؋:nGaKyKgی['|.胣$ُE|.n?O|zxmp_,MԳ>P(=RkzSxc#y)@Fπ1JA80)^pA ~lz1B]yteƀHFr78~+,[0{@\cX @,㇗ߪoNN9njè2Ytp؎N G]![>uc  l{8⋏$`ɮP#mW8Q.\c``_Fe#6g/N7ۦ4p)yڤA|fgKślR`᧪=L^^:hGlɯ2oPD\5beX%?\]<$t:&)TV^{~ʭqDokhW?7<$NV4|xMx.ʘn1Cb yst /PөgMA~A@f&+"Ī _[x-ѵbM9tJ-~3.fG NG]Ax>g7^q ӋV Db$ć K. hޠVWt$nP-s ?=?l{}qG-U1uG۫Mv/t#}RF~eqF Ùt9<:|nr{}a5yٹs%HqoG|k߲ ' `(Glۅ¨9n ZOw<19Z]y|mw.ky)꠫aŀ8+ Q+j_n;_{86lI0RT2,>vgڽNb|WX~฾2~ͮ v?nW.(0? ԯY _r ?A=ȶ82B&f<+X%#1͚(3+qs̵a_SDEJ_Uj6Qm] )Y nj`h޳^ ekk;m'],O'WAzmV⤘ٍ^k˱ݗ6;n,'v*&jo,Sޘk 51&:_]|@Å>OO/+Mq'0)jcqXu13;Vv:|S{>G([][xE+$kڄ~sitp“W:%׶8jo1jwv>udьzamLp]/E{m҈1}>B)_I0LbIK2cr5p0vXQJ/+0߮t sU9N}:O[JQHn? ܔU9+40} H&+:m?9Cm8>Sg)mEV/7ar|мc>3ֹmw:]/p *YF-R ty X b>}A+n@? tx|eL_/oƖ;൓;Mټ\VNZ .o#=6rKg`5S;6w,:dztg`ъYMkWO'\ht4| &%N-x4u1,{..D&ڂ+%U[{ЀA~dGQ8k+4[Vf /E&`6M6҇E͘Cu @t4a4ݦ'gS6o}t(/Rf"K+Bբ `[wK'<ñĈ[aQcmد>{ǤC +sD} `!},>m:gzB~yRnɤ;A _bGy&LGm{3q!_宾E3?㊻#+tʥdνﯛ + IDATDM`ο?}7 f[R=rwk7ыgwMgKe fx8[JZ"z ^i,^&ԕWfK?a5SWqtU0-@H(sz/Elv}H?_tեE8yqMlsV B>?x9ohz#/~qq em z|lRa[Z}Ql`6c;I,n<4#xa#? ^ [9' qtRO/{,|y=_W_̝016ڭUE3>ѾnbTܯ̎ۻ2d\<Ȼ'6U|M;W'~|VPxb EX)[bᎇ66b+LB^QnM/cbln Q]ngd2xR&$ϵ_&KXz] vOB;}c{'ls8}1#^&#<[yʻ1[+({\(!wn uoy k=&C o K-\!ѮT[1oYTf㳸/L][ J9^#VwmW{7hQeI_H;ϖiS-[`T=z|b&oP\u|!ONmM}:3GW1՟RQ:ucz~N#.my=Vڝ&Gwx__=t4`]hpչb~g;M7JG:vŨFG-t1m{o| peŒdt.X'3:@Mcq5[HYݏ/O8 OlXG+-`UDkޅ.aI{ ,vo!k>'3mon W'6h..:{y^pXW>|s8ToMlnR4?&-}/]'/ss B5|>Hxn8ǠIxW-u@}2B:pUn:9_pAt?qo}&>^9fhe|Zk0S\יax/2l)"~ndo~-VE3񂢃*dѡ$|Xx#[gD#?&^6Ͽ2oLckBq0p0AV>?ux7co'b6@2.K"b0+V;Zx~'{ !9yO]+ll@`~xпO=KG G܍DŽeWyVٝ7'>$Kap J'uboJzm?64:k侼=zS#k|Ws`XVGqk M5:|KIIm,uYչ1kΎ{lNdk/.qȰٰň=o= ]:+O |N֥kgJw׎\Du ,Ewu}bIޞ[IYhы>>YzGאh@/g¥yt.]h3kɳ6:߰ƫn\tdڶթ;vb> d3NMqe&+Un5"&ŴYL;w҄x LWN%@tM6 }ا[*H6Z q k/g_6`>pזAiϺ*χC:l8zT+_LlƎ-&khNtuwTXKzp}zo6hRMf]l0B\׎d=t;0{K[:2}^^<=zQW 0uY^` n8清l/tR_[ 4RƙA5!Gyt.쮽'FίR\ͬ"SyǍo dMZQp?2BO,2faWkJC2}5SY8[/o"_w{aߩ6wbQz~ x.ڐ&+P€$|8ƹ8^ˎwoc$=R ;+mvEs}ԫ0Q?~xڴ٥"UOgCK~V0q?ɞxx31xoTNQ'Շ3Qz}[t{|IPvtSKCa o;w7ѻ3ս0;te tNty~N^@:}&i?X\?ӪsKwg |ы w}%lsмOݎ`2 ߳49Xܨrm(-8~ahTO IFxyi|1cbv=`5I?}myh3E('+=N`=?. aO Jԏગm-,EdSlA9ÿ*e ;=F_4 9N2a;9"J `qșx`ttwDBzq%lTA(~ɉ9FoBCVF_16)DقUnW V|l:ap[U5(>a#x>Ƒ@qrOg9~v' Dp8|TK"Cj7MdDgR *1};ďeRI_rI/ [R0{\b5}ݤM?틫VƏϪ/D.L^q>|=l?;+̤O#xo:@~0NדN"[jړmchcg4m56SWz;MFbtw#6iLr+[7Ɗ\/?}+>o gǕ=}յ .>Œ;Wj! m2zK'f3q63~=x:ʇIL)Ҟ"RZӽpl)W_v&KnMO&f>cxjG6IvjL}Lh1Y?6р0=yեbzǰ-}i0r%dÙ?tku<ov̻IN+ۑA &ھ?Y9x C/^ަΒ:JOaijj.'f`~X2~8 &/;~tNUMrl‡&gSgkeċlKe7rٳ?DGr]xw'ɯ>vd7FژO~`0v2 e~:E)qK׷?ZwyblRXًij߸ wh>Ӧ6*A5 wg`ϖLuU>Ex)~/ZD9!?XkOr1X,FC\@Wɤ23W"*wa7Hڜxw#C|7wK申X/!]]`4,ؖY]aoz788! ˟tAtn"1i풯ND_A<8Wbof>?~b/^b~Lzf[N@K`r&O_?o##p@P"`0m5S9_Yڄg?JA $27`Ȃ1 @d-TxwEhx@1;%{ٚ1߭p=zAuv㏇F+=q,ic#|wԁp)V1azn&]0 %O[Em a\}Uv& wGThڬByۛ5#lBOGeub%ȠTi7:~9|aܓz&1'~5pޠ0v0l||ʛ?KQ[}_m|$>Wh~_ ?٩B klnwJK;?ފLLҹy{~<laS){vΛ/6'Cԝyyt][,}m}}XP#TK(>^}y:7> xQ[H枹[<Òx3'ށ1ݽ6b^O=$M.wv=dj[%Q^qv:_[e%6rV0Vzo"O8^WO8;ѝ_æ.MTЭrt~wGr»ɫ>]6hA&%oq*>bV;u~(]Oo#f9_XX%q 4Cq?`7N&鳗c?$Yo8]>h>g>bE$~C K5xƺ:,gxw Np+>2>O62|B]\Yør_/bR@ۄMlK7ь?ݦbJF70+ (0 #/`tkixKصKw{dNǖ8 &p q{a܄mk%ڳKvGbɨgǃ{u+fݵ&nq31^YPN<=2bwǯsr{SmxHw:GwR?<l>U bk?+ѷg(0G*>]' ~!,f"&DsuCežmQgyNfoNj؃,ODW} Y`}r|6hOY޵g*m0E?-{~+ع|BSp{L}&'8h<Zx=ZYDKd3]7I!ȣ Ʌ[~Q~ĀK{+NE:/9'~`0:Lt%-Z&3~4O+[lNlUy88z:=}9sƗ)Q:ܻNVVUd#y$srP/^|YE ]pL~|TPA߄Jm0mb#Q4Fgԥ;.Bx/݂1Z Stze'cXvl3p|2} ^h G|EEbM{5% ӛ]e6K/Ut%0J6nO\N`$g <6B,#,v.@>~dNOGL}lY8xdQeh0Oh8ӵ4:~w˂ggGk& Ш]l"L2:O\FnX`WcW8tN~zc'&$v8ztb4u0[#m@X'm7(.Ut=r.=Qv~oO^ly!t]SajlXh<ZUv8lg#`&~;NOj襞]^MVV.g{_|x@ϖpyx<ؤhoBp~v0mӖ;=͖4=G \rvӋh8y_ Gߧd$+92|`o.WQ[@_y8oA&qő:(ذtvKlaÉ]p ]vվӅi ;Yήmnqԥ=Qq(>wxKZWEdzva0DAz]yϦmП&n0La1W.C{"v߃~g]M>#wUl{g;ϛ+i@nMۯxw&O]ClaNHԻlOx-hMj#[yҵWwXvvRK#v- IDATXd+ #ߤ݆O~WV_~͟,1&ed_g 0Z?Ç(Y't1o2aHʲ^q dɆ$5$yh [1&"7xN f{_U/}b-A_sCBw07Lĥ^llgD"c%Abb@?#_L6rkP ?|4 NK=DvM#)}[hy{84~ m Udrp mȯ 2Q֏;/;Dy/h`ib ,<c~Ÿ˙iΟl u>A'G! 1E5`2![xɖfG3I{O0Y0록bV;d7}L|8*l*xotLPVVamN }8^tFkJV$|\e Cy;}B`w'Ŗ?e9/&_TC%X<@U~;-]#U\=1g -]lO~18!_}WV4WUkp&l4;9;ѓmLl][unwUx_:ySlx[4tv050Lv+;r::=?{٨ئ_?&-U!#]svyxx9];/;Pŗ6+Fۯ´B.>/[U k#o.ޑ[~6P[w}~2kSO#S(vq_@gc*}o0&;^lѠU.t ${2=ʱxot'~lHNEGiDY< lE/$a]WA8 r!{{-t8KLg& &}X+gC|\cds_t7ΟE_}{M`>ҳli?nN0-څo+}e3ݼU8{fcw{e_{q1rdnmwˈJL=+fsW^.@6ybV_wdT~:luX P{!WaroO*aI8%le7Q'c}j>c$O?"Έ{meyupc:EikP]mox"]]l3a~eWWu'tyځίg |B  +Wv}dMp+؎A=:R7wK_|.FZцU~O~ed\V_jFƄhi퓷~֒qJ<GIw2oh߅Ţvr 'fOuxXjK]A6pcc'ςԕ{)0z9}Ft&oLH? }q^md)[E#l;ݸy|}1am'EV>O]ȞɛkM\?B_u^l:k_F_7=}{ϵt}cxjsx}u .o,o{ub9DկɗbRE}tßlS47=.tL£O,XHu8.|Kstr#xgc4;˓{/]$=Еh/v\f7>cu0!qbd&Ѩtz3\_#aNxG~> )-i ų?Q\ιgI%И|1ıP49FWOgh,ގ}dU9Dt|v( nuAtz]Ūrl9}CPN|r]Ѕ9Slewr86eU(x}=ع5:JU^XwQ~jwɽ 9,e[p\bXFo {+[ۉ/7z'/"xTqܖk;2ND]{ |<(tl>0C$u~P/*-[\zFt'w/zeǟ8 /׻ʍi媋Qu`ߑlŸ>I6_׀~D_:f/elyho->۔asX(+TÞ.7ǷpǕ+~_WGh.Njab$_55&6L9c}~ԩќ_M䅍6{8'i;+,PT^_O+~9G"nqÀZ]v@wmL鵷*orGb *o0&<ɣARiG͞TG#WAV 2lb ;ʑ[d1 >|V9s+bK]>W_ʈʢ{u>Fݝ>b"e 7tjQ\Mv.m꽼Gizw7yMuQCYbRa5ԦoMxmoP! {R^jXLNmյ(SHd_FG + 'Bx)wWX̎擵_ e5dL^BXSJ&'?z<cQK`;՘W'E_'nW|_xdC7Yp.`o?d ='._éaPr^zG\&hGMz^$>WP&RY:~pâp9~x ;*5F!0MCLe|'N?խ9;/qINXjm ㉽a__~ h2:G7-<;]uJMp76!{va1'ə2WQ|cT:^'bq6[W?·ٰ\:<8;fm`l{0q{G30. ^Gr+` m/?$!"F|`F>TWφѳy["{lO>BecGa4_tu57.,6E+ ݮtmLVGY:-@˂؏l8_fɝ_ɡStl+7I{:ֵa4ÕlXhvĎOga2!&Cuju-=]@ڒ*]%q-8LDEJ?t[Y W ] Sǵ۰x1xdHҢUp-ῺUFH&a=ϯ̋q%d)IJ9AǻG89Ȥ-)>l:^ϸVO^p#-BY\xgdCc9-W?6~ dw8NjœZm6<'zXZ̹~*Wgz۞~]'x"wg~cw[3=j7Uy eOo)9Rk-0B/6/1жz/f1h*?oZ?9)y;X` 8==te{~$.C/^L`C=AZ>78Ȇh*&=qærÊÇ- ]N,ZE}20aG? s<[g`sXn6a*Iqtaq rVO=v/G3<&Fъh)bU5+(fN j/ߕ~q|~wlj}}/}1@oVFM+wٽy3Iোl<1ghC&NuT6_e͇#S;pzM8aOS*s>cd-hg`[~cSNwvExʫ6q@w(rM zI/Zݠ~D[iuW\EsV[i SQM;/ t!3J(dCMe6:0$lp4}wO!o%O&:(]C gw^gl:6U E)?[|Wgw.w*[]O;p-?&+/eud_4.xHN/O4}Lcmb-[-⹉n;N@X ,NO=SA1d\He`7nDa_~Jk{ȄѤep)Ilh[-~*1]ɫ\mcu7GKWS X]}dh#(Uy q|NJ字>+TmRF65T-+w&+Lu/C۶Q!1 y+=9_#@`^*׫~t^*r/Ss?h]aeeѧ|oA}ږ f=_F?oY]CS5,+!駧 8 P&!>P`k->tr[;@?u+pEۇNk<p/ u<6Or Y1Vh0*ō_v{u~[;\lu&+[aEy0_FO_ʙ+[p&lM[_$ONh5a+6@jb-tFV{^h?c8n O4MNLJFG|0"Ux0h0?rm8b1:m(2Iddw#{d]3|?ݞ|GWԦ8ts`': ~k|)Qe~H=8}-q6wZ 3YL'Y۠ybǠI9;_yu"ۧ{LϷ?ɿ[q'`t$ξa5mTg><: ņuy՟ݮ-6{1Mnp//FZ؀k?a8ND:NxLwim\}Z;& >Ia8[|BhKDS6p>1Wϫ۫[lUX?gխCʋ~F?qwBvy1)%޽C<=?jGA}Sbqd ζcmѥM$ju[ߧX?_MWG/fMv]$+sD79^{|4X%ۇd|Յ=5dOץ?ɫ~@ .-=n[։%D#+b5xb+z"˰Qp ,*h m'c"UD : L9 p mOtl:q&I}:Nmɞ:m>Wa'ۦäISwL1L<>O9ǫlg+(:_C29 ҷ)Z 3(? ."] >Z5md(Y-֓.3z|ʌc\'.>*4}k>ڇO8?G<=-uFoa^';* ZL] ~_@F>LXbQ`S;F6.a$og'bj@~|KjSm6(&",n FxL:nF`׿V]}Q+06L߰ؠ Q)h,NfŸ*~d!_:ނ?bQDbUn+9:W>Z[i°m1Fr2Ad\<{W'OTl.],ѩ?-yWѭFW-z P^6Ld>O HSkmJ  b\un_*6MdXeM*=oԓ|8^a}Gx6 n|u 303 Cul29Qw&<hx?b tԵG:M饉ӛ([vЖgr{vImIVtΛ?FfMB3>VkwCA@iԗ<:b gڅdIi aeӶ}zI╏!\^Ğ ĝ+M>&,Hgm}llcu<X;vzlT$& ^14~"߄ /:^4 p}뇫AnvKgOϽ Qy^x;_oȈJR6lAPEZLHKX7$~΅⬶K鷉}g}Ma1gm~mO=JeugE 9'Ѯ?N|MLQ==So7+x/%ƆS܎-{Lkga5DJwO쑮xO~Y|ظG15Qbwxkc_rc̎U:Z3,Y,[k3%a4'm3&\2P$Qؔl~1~IK[EM^F.~/1,Z}ts?^16;Ѫ{o]@ I<<&~?y  u+~}HMq<~ґMc8KՙqmX>7ͩgZ.P+*=v:%/0p@xmtϋ߃MBAxD+G/xq<`} F|$S4N/oZdGA *8x^Yzh5(ZCO4<87;?*/Ktztxbs9gɞZ Ęs͞/ x.7WlvH ّE jd&iF4j5 UYdfP#qW;6.o',YmrmÆ':j%e@Cg>R8[|zy@?oyX6 VF+ܰmy"E|nwb姺&lJv$kmpzd+&إWf#qF$~ь]ݶrܫ'Wvs6`L:J2+k";l59zѵ_[W'* ٓ/x8_|At,P|D6zFW}yc׎@$ 6eʐ0 HV >Gc6׏4w-M\+ۢFs|(ݬWg">GbO~h9b њm}o_9A{e'g#{QzoܶAFgp#j}2w|8BLM6(|_\lMk' ŕ#!_ M6hsÛ|n})8O >{,V7!f٩#@ B+>h`&se4!:?kKr~\ )wxhpoTV*ogh^B} 3%}'.Ntzc ,gl}6^v$]=#waOzGAKկ<> 1k'̬s*MO4M{ޛT@ P4l&*KvPٟ|H5#-.?mb7k_Hq|[ݵO>̞lolyڵv/f6 s}' 0/>h۟Hp)jSc:x{&&|_vʯ*8k"s7i"~dv&p?_iLW_~m+|%!W1ʢ)G{1ּ_hă}욮?*|{4Ӈo@W$n)/;&Xs%%G{q-"}<[mNNj5q+V_>ktU|(1N 1څ;c&?OﮕOC wR?:|h]̦ͱ:k9h_#s>Q:vE[^7CF8}6|}h_՟';-Z-ę76V8nvb?LGt_bV:ތY'IRЭn1ϹH3g?*gŃ:CJ|ձloMFl֨™GzJ◾rOe+{ր BOP/؇.C1:yzg?;~|آ ҹm]# "-%f#dKh{WxUu菏6n>$n%v[|:_/iB ]M5)Nu3Fq)s '4yQYCj?M{kaǎa3|mVI u^&meKrhgozT顣zye_q4ڋsX~^+1c'g#YU:;Y壋WK<ڭ8NޭcJnUA_[hٹ:1|̕ɝI޻߃Dyx۰b7':<)ڧM^Ld#*;<C>bjmW]NƳ-ztJ;E#W&8T?q|W=:;6bMJ7XϢ]}s,E;{ʨҫI*q:^(D‰bc\ylixh~ͿQshw!j"l'K'teDo9~a慩,?vrt~>: _]+:2Oo^z n`r8A7雼\{wiwd:yx''c6=kSidk82wb^?~gfGn0}?`¦I-h6Zbr۳;WlxT~y؉lk!Gt~]X&gIXYf}*4~F')OCK>yq\ ?yM?O]4*%k,]m#iqJ|w|j3v%3qӵns&N7rPx{~Ā:MM“Y ]%x&gn\1a!}E|4.^xQf1g ?qD\QΖ/Vӎˇϳ+  ܄%F%?I O%hZky?0:aɐk ?<xISs8K8%-0_CT{ny|8lx*{09Cc#/8{YwdhBT7{pue &Ndyj1Y*m t}d= i/Xai@>IW*xeǙ>`љMxy||VeeIm-Z";zln3ZD.QGuFNj$6Dx;G#>6[y>];8_s|.A|3{+(0 @oxl)Ȧ1 W:c%ؠo[X,jB߱Gg;i=V5pb#\;sb댴#<+ɛo{ys:S+z_;D۹p1p4=gM"gw~1р3! 1sv{rO;\]3t& Uˇ5=.v]:#TdM;{{dr:ȩ|:o0DA{6Eg3IxU܇~A}HG[Y)`7ܾ39sE?W?<^Ezw?:ZYв`^+g_2Dy6 W9N_M]xJNFBG>'?yr/ޒ -vv!P4?Egw'Y OtK"Cx?}{?+O]%l mdplnM, 84dI?Wߗ݂SlW~Q6\JlWɿd#/F3c/&ةM8뇜g_LhWRxI~w?7|Co^ahۧ3Mcubϻ*o҄- T7< > #|_y>-;#c&=8~/#5-R]Oء׿컫w@tB6EKU<`n/iEYͯCYU-VOݣLγ3A LtJ/9xwTq8p_h{J^!G,)0OGbN6_嬊3d4 2YW>6Dœ;),/nl[IM۰[V]/vqW/_NdO{Q!^Agezo?}?tþX|lHD'Sr#d/V^#@JY0 mHf4ѦᅻJ_Ӈpp;N2h'6lږp _!H'%dטpx嘠;}Ȅw>xl⧻7'Z\HM* cbrpt-X?xoI\fЁO:{wK![eA|ԋ o|^džbKwg5>lnMk*;?wx[z0b[~=Yߕ & wN.T>BAizݼ 2d''=դSrMfWSA.E'+y&c3#;N{I]ݫCuJ&ڳK{d' .v?z@xmyTv/16@/lpvҞ=ێ߯~7ݚeH+@\E wwJ ngdd@=[y!ky`IG[Ʒ%NXg*Sx=/ev{7(=`.yL w,o 6|ߙӒ~c`$> n7-ܾIx na(g Jam,׷ÛArhw蔷7FΆTWvov99ӹP>|ЕŽ xcaG~p%J?bd|]?؃>fN|\oW棳ZGw|{;9Ҳ}Gy$}y#?dq <Vu;Z,i&`g0Sf-9\39Eoq>bB=."MF[~X~fq_h_ BjvWBtT|y6OŞmT&nq-$j_$N}Q*9~Ch?ʙ3k IDATQ @e`wvNIѾ$6 AB5` (#gx=0^mx/X>dN*CAt2LM f&| 8-F脿хFîݵ+ȓ}/цx߹rjk4l>A\1\^e|~4 ?کX}iDgdkOd8>L旛SHO?+]}؍kK \ٵ5W[K-elA./Oru>Ir6UO.Q7`ңl;&tDll?o7ʓgm^}b|7:-8"_W>xEEɅٖw; [cd\W|`qcHn2#6_d77d28aw{rV䝋U=?mOķ|;S|n<ҷ 71{>gp׈jWcy@;)KMyWaBLvS=xxu2c21Mċv` p.:d [~͟dx萍J<"ZvqW'쇍X9Yx>\ZWwt+uu}uehAHn4b(׾oLxg~kf'r~# d]GA|q>bd/7:ob 0&f ;=uo=v=, -Ls|N>l衝cW~[9 eW4lM^>wO:9ů)X{-5;~~"oClj}mfK gwvP_lO/=fX{rrxvqze;]9|+ڿ6?aj}zwTʵ)Z[0Zţb{*/}EB@>ӅJ+7%C%]_KżFdӮ/6/zcl,˭둬h 1 2m?S^] YQ['"yNOb7T>.\ j=O`f\$#ϿtQT _wdW9TF[:י^=~eT'|9 ǘ%RICl=Af\TcxUXߟmo]`:["螛&Z1hgCCa<<緛+OlKkp0{e^;'Mx,Hd?5&-Ɏfoc_OM7H]ɬq!)ڿg|2qϗb-XS'vχ#?|~tsck}NV M$hOmsz(cKĉ';7PCӉiOawǿCejtMfƄv4@ھ:h|~e]^62hG?;Acbt4껺u=:ҷ(EQd'9O~h'|ͫ<&?xg_.A2e ۿ ~NU`gkk.Uh 'tu,fwݞ P.~l}Fl(d̿s^yQϾ/ 8_⢿:`ngr;uw2a⧟xUb'3W#T$1Kl}_MH!?G rg!j##wԯ%آg)#Zљ@,Dmq29S^;tvgن}??K :N>Nqɩ,Ӷ+rWLNAA+b@?G,2o__RK{k@nWX^[bǯfMWspή+XՕ]Kئ[HٕdQ;G]MV}mcWuXdqL1(/$9:cGӧ ov[]`[tkb86! &?&sY_ٴ+*;Ǵֶ껅%;gC[t)Feϟ}ۿ&&5k_ng:UN%{LnlNv>+X~OIuJw UY-Wl^˕PHwLy9ȯyyC1}cm|+gh!݇/ obGQ${==#Vy-_Bg҆S hm8&w5.|dCzƆ'۲[BIM"l20>᜼<^"Q'?2NǸ#:~uD"?ձ5zS}p7y7o~ó(6;+9f?[~Og%G|ɧtHPzilOa?U|<JVb]} ɏ]0V6վWl ~;mLd7xxqY}rud΄ ky9lOl27 SxhDo񖍖|xˇOL?J,֋E#];sy.@^90'GĢ"eOgѯ5~ykrӯi$qV%k{A訿{Ё,!/v¢Fg{Q\+9ؠ{rG˄w01Kme}ۀpB-jL~gg>mVG$>U'?-g A&hMhP{6b1~wqT0r̈+ G~Br~}0^ ^mr}cd#OM,U½cr&|b[ݞz'k >ovS8|ܤ&e× #D㝭_ ׌xydGg࿜_4kPؕpޘ¿s~՛Pprܳ0yۤ!>8ޛtY !g<渌Iv |ڣXpr  8d8Se;-6WCM-zV;Ł˟NZBt߃jsR9i[᪒Kck}p@{:)?ʰ e3]&}f6aw>ۯcr'{^`% #y7Y.j4ܟ&#%Z6%7c@5H3^j#eρЛsXο::Ozh,7Vsr kЋc4VRi߲we/M"-m &#|,غ) P|i}E6MA\ΣA !< =Q};H'cnubL~ W ҳ ;O wehk ᭳ѾGpījo5_9N &ʶ*yj=MOe'#pd9O,UoW7XxζUt*{|@Grg|&95=l2ȿl l/>'~o;?WXʓ;ء胂mGx~ͧEQ|L%Nhך_0 @5zJI2DKw0s`b즶|N?/aCD\쳿gjWC]ܼ6_]9]%2l_A֖<媴tUG va}/>n/*K)h-a0>x|KwldNH_HGw`d 򔸉n [>f|*7d <W8m(ߕixφkq/шd-_kɇV?b9">HO~GC8|AS 7L|nKAWl2dYt9ḑDv7"ƒ|>{bX<4:܇6$m e9gx +F~0gOc0B)Sb~m!:uR<2>#8zbMw=o@e]i4`ͨ+ĔV€` $fC? }|GcS11?Fq Ɏ&c^s :%@߄S̡uK9FF'LˌQw}?<:TOcOFDOw 4}V=d&Œ%py.7MFv|>ꖧHsFq+B;E:XgZ]2o0|Y#g&=~w ,lϗ "K0:>yGA'{A8Zio?;qIy%d" 6@ޮ"?}OgK٣9 cCgqWTW 8>O.@C'LP6^?!+݊ݯxFKlG>.ܭ^>#9]S ;v7?2]M_ T UQñ`0]bb{# ql&Bjgc4-v,_owU--^۟t1Kڶ\!,w8zv_|~OK/Jw|%?ܟԓN'hPu4ݱcwщ֯~Mz&g Tcb~`,T}9_"sG)g]\Ig_Fn/[>rӹr8{.K -Rm c:&O.U=&襊7?9K9j>l`v7Ptq: 0{I3=Mw<{L8` XbCWW,]\Xvo7Y<2gk!tG>ߤw]kއ1ʂsuwBuiox3:Y{}iѼ\hdl.7 <~x} 'Yf|x:{ rcd[@/Z|3lI?~Zӥ63Ip~&6[A%t‹|^#P08,}׆Ǟ>oc/=UT7/V,ʏSb&~`: 1W6b1\[^'쯿Ymhxq5 :I *7y)ҷ+fhm&~C:0c'爱E_ Va|^^0d0aLgeV Ybel6:?> qlbWpl{J]9Y6ÿ]aF׳-%6'y?kZ(7-b 4/GR4+m.ݢhZ|P'pY_#UkO?>f_R`o#nI{ߊ(^ޓgfђo'wSq 'o:/_ހ&XYnZ2g|kozɋ6[gk}66q<-(pZO{mѢ,zo\},ճs9{oNHo/3\&(G}׿Khpq+9ƛt\,Sb=p$QB_x dHsq'1 ]|l`c;UsOFo7^0;kO})N-b6ZnӽcTVWtY4o 5re2uvO4lR\ܡƴk>] %DV7t6L/~o,Y[A3;fkW{oQtXVn|$7o>G񎾜_1"{1g >R8SȭRw@g[ Ͼlbu@绠nfer6oV@b'sQ 5Zb]}nw(bl (J@rridnv=Ƒ %(+?mQr*o_)>ښL-wfQpğn'Bsr7 @R|S 3a' $Iv ~) &3A0S6z7Z`p?=eL?&Dt[ݩ}Llurwe,cp%E ?za~,@, ظ@jOOxؕ \gu~:O#SȆ'b#^/euq{ al9<%T,_.?~k^)[A X4H>`~W_BC9>d>q>>d0菦X-QȌD9dWNjՍbBD2>.fwEI+'+ޑNv6A[:A|OILu}0Gk٧=L4xV)Xy`^{"ʶ1O.9aWbվݦ2xcqLk{]jr[{6GOdKmb|מ%J';];_OFg1,G~,ӥ:J۬=iCdOG%k_cDŜ7q!Wϛ8_U~6z gO.ֶn̳0q/= ?f⋘Wې*{vËQ&\:gCs7׬/=45!Vo`|Vd|v7/,lvWޙB&6ח]M}c89U;.˙Mآ ;5txo=㯄\vO|Z E/Woef>bax݁D7budIE:?HHHcMvqjϺ/~۾6>'y7F&ŝ:,CU[ݣɗ~Q{X !-,Nl -9Hs8ʞyMb]?׮G|ӆ3YG RڏŁ7sV4&[ExWр3'K璙D\}fJ?lTOvw/YS?k$G;0tqj!È] Qr%9j0:U-l~<O'XKiG#[[r$߱2 Dvk'Wfg5W6{Ww7`M\9#`SA -#8k4B s b(14Ur ա'Pe o:5֘|:0&_FbA֒[S|l8e9~xL8^Cٻ$/ : lf|r~144;k7n2 .Πz&{۰;/v{l~„^g! :s}Dl61y˭}ꃽX5dmeD\T%|/۲wttN_Ĉ2C:X)'d}q4S@x'~b,S{"Y1A3k}Z$lb/y-_a 瘯SFGo_`X/!ȕwrx99f1W-6s.]'ޒIM'b6Q0Xfg11jαmxOV/ЀfpO3ZO8Y%hΪ+`\Tdpx= |vNUoD ^-=<{؉cCFW%!&ǴrUgH rk#O!?[,{=s5 h?嫳'펂OO!W<#r6A{g/L]m '.g0?e[-<_?Qkѷ31~ 6Gq=2Nxfwu< t&~FDgm?W>}ym\iw~c48۾5ieoO·26xW<62.@2x'638}Wسȇh4U-h */Ͳl_odg#gzۛŌb hzWz,8wXdžε'v?;ݘqr: /f&Ty _9@:|J 'Tw3)G*|ڡO#SZ,{ýNx7qg.⽱㍉k4ضr|r_{]"e/ 7M&KJB &0lOb ?0Ս:{sRUH'l\%84eh\3%S+ yX4 Q2QP\)MrtÿNެq}})Xt}E~:~aȥC۞؈nkE@ hNg5p'A?6P=O7ktlS4k,*>b@,<Εcc<6`;,uB&+4;v7fv(FlCg|K10+fO`f'xyt-قy, /~poMolGGc>.źɯ^ m>_ę5ٔO}pढ़ԋrdd\{-X|qrΏ#;Ɋe9/c0^I;o_G1ݣ5& G.w-<6oP< '7r7ۯk7䄳\ճOynO,u|d>#nIAuJ6y?,vtoG7Wz\~tş5 "uG?zO>O׆b fٹ7b/Ձ#ս&)WQC4)ȣI&} nv>__+6ހ3O:[sѾT^g[O.d5yc1w6uwȏ_t'?-.N(<%Ypr`MmGd~gKr r<|Fdسd*=k+>}=h*g`l? C 닋WyޛlCI9%ck$lG#lp+򮤫kR]}5; !>=~A~vp .BG}>yDW>aN˶ؤ\>!Ҿ/ƒWeH(?Xсm TSK-&ҋwojҶ6V^csβ+4Uvj31N)gT\Daho#rPKFxmeL,>:ݕP]?dE]-/[a?R}|՟|o _>M\{k#rxJ/ |eD7k?9#*#A.6*֎W'v;e[l¤MZ^ń0KH.}k7L'|䥅#oݙ ޱv"dxޤ=ޯ Bav_I|c.v٢:qq~ >{"~v\| T9c0~b*ggo|,\̒q"lSڹ~t]a+dاGpؘUk@Q[o;:Ր~ɹ #b}v / dOrݱA{?y6XI@fr?$_;,o}mi~Dמw]}|O8" \٣'l?VOV[ ۮTNI@,z9d:J)CohTp$d'8=X`ӱu&{:a#pׂ>+A4L{/z7}(Mwk^سÀ;k[iTn~Rp?~XjQ877,G>аdq> b=Vnng$wh?o?0{crEILM5 NP`_6/C͑{p;;WlDK|m<C|>[C` KGCۿ/>^ 8gdY,{%I*o̾ϓMwc6GrzpNd>k9E<\gă6+?3[( }&'x }4^'>-6xyo^#K5 t8v⨉`1 P rklq<ض[gX2MFevTx>l`y/vGN*m_,΋Gb:e3ŃM(cW̵WZl58 -@$>K:O佫gvrAk>.Uֵw+G{/˽;n_򮀒'0UήwD3i7ɹȎΏ}NdvwgVu+7\bDسwkp;n Av# N24<<>a7(6ٹV, o8sNo\{O|%V|;w8/[HjA2 x[Q—J-:_{ fjON|>#Y>gg. k*zCgv<& "\zDP^@2Xc]cCmt= BM?AMNKlL'3M_cpr]nzi.@X=%>6gM_8S] ^}!p 51l=9#c[ՔM?KKdtT!Zah n$ԝyp[тN%ujĈ|H^{t{XXrq6'Jo+g?Ekq &(y?p_WoiН,hP ؒ>c^bf9ȡ`Rm+M*s~6MKS5@Fyva4?şBM __X\HC#aM9*:_'z;qĊ0!#`xmk϶֦ &[=MlVY_ҵvz4"bt4er <Kӎ?xv*EzqDztb7!fq£ӷtЊmmz38#і(N^5϶=|h~&νmΠ}Kh2ZIElGYNb]'o} 9&T? ye25qdˮ{(ړ^Gh\2[j#lW{#B@Ͼmwg׷^7;^1sO]N=XML㙻*@W-FE7b=!zt{rQgTG5.W=7bGdkx_crI85 vX{XL>!d#~ #CVm*h=v ?O3֊+ aO1+-ooD$e{쵷C󯛴=Է7w?_!Z?~m؎y Ǔ㮬?15hLtTݙ</k,}Kr&^ў*WN/`OQ|g>kgh'¼O~L[xi+[HZ`m[ǖW3gwb֎M]fCll+{~"v/|O;vT]*#  Gh)gxXߋ=wmvA^0܊^~13o9GO:bC/EwSp i>UxatرZɏ`4tƕ .  И&ϩ>5Z+9h ޒ*6wUs8K d~MmvlJ"sM?K|!>4,7!bϾM Ztnc{ɸWԃ '%C IVdۋ8l0?FVB.^NlD㘯踲٘œrA:lG)ܯ E౸ߣ F6uW|àh1mǞW9ok#bi|1?% k2p۟߶ſlyxHK[lImSv@< _|=mdc̮F>Uнm&×=χ=;9q쉡X%諃&/YGĀmrqӾ?tmpݠo ^&r#yCg@nP4Z.>VE2{QG+w>\Fv:6‹>7Qn@ֻX@\9vDm셣gQ2D#䇗^_9)oV|+܏vMv8}VOe+ImJn ap~4mx~Ӌ+{JG,S)G1C`.>7 b x£I{Ru[}HMqDQJKhsbXJp_y6d[`îd>_{˸b4:o,n,_#t_ 15i /ǀcyϛRW^^X}^,!Fcש:$vC?K -#Z[|l48|V[! ^`&b`:T7;IG:[Sk6֩ ו*?Moz3 UR\^ʷ@Krދ!C3ܯb}v0-'-F_=YbM0&pmv}_|ȉ>:B9ڋblspHYs1ض!q]U-d%mtgLUl1aWO2lx}f+n>_|p/͋ŕ秋]g-m#qx-9b(2V!^bvHndq{uh"t+{C ]L#:_BCL{9`;jf81LMtmm 2xg-f;ams_XvcVgb6ڳ1vߕ^-(7Sj/ccGpO.]%Xnjי +w{,Oj?{?El`^Z 7 #$ƬQ]Ʊqe2<>]>{f\ؠ!ʌ3PЊKpǀObHFx*ndzƩ7hw)7P4>awas'8o%hx 쳯{cقK֕gЀΰ܇a#6*O>@qu^JU;; $0/hx6=)wH#̓H(fGd=?v$;zh+`e<woBX3~YC` \pՓ'kl⾉Fmj鈞:{T :Y]ϳUDNW{9T\^/Wt`6㞅b>H&-{yRLl9~V &{DL WrCϻRwvO۶ Gg>}eZ?p \qxf#rZT6AevDTh:_,#GOZD=2 O+V~?r=6yĉP]lᛋǎ^\qRov"YÁtWٽ]:ɣ "NJIH1tϺWю O&>-$[vu:mBg#EÏ?Nv4 F+O|f.by.9 "8b募rwq}l3Lc*G� ~y!|6@uo1'N-⭋Cw82`[_y\ǫӟwN;t5Z`+M-ܐq9|v`$;BܶOv_{-Fy;{yt&cUg&{d"CF4_FW';0;k&Xt_k-fD@ ԄQ>tЭ}c۵򡷣OxdÛ.ۮ_\6vbm7EƇ􋦸ࣵ5e9Y ewşrv tNkS,W;|D^NtmQ&R|\ $ gl^LEC]|[簙vf##;& *_GHQx#uL$>uwhSsSG6T* hKÊn~Eo#cycdYNysX' FGm!n\P!Ģ:ǥG`&^6y>9;.[gR:3:` ,FYzL "r*VoNWVWb4eO GjyL;Y8 "a+ZDk-( :6Kp[0 >*dysAa=KvzFƭ'?Idoc@=hS<޷ગ a-{Հ-|; ݨ$)LNq}&~W{}w ﴸcb8WɟPELd|Ȱ~g}؞6p<قAl0yv^*ɧz<|֏cόDgWܽyMВad7VU{}VmNQ$g/{^\GK&GlgV#od[qr[صiTmepybhv18?QMNtYjq?o7>olɒ6ܻate< L $+kI)MLL,ܘE81\Տr Ĕqh11vթ;<8J$;O G'.2щVelw@ɇ{Cwn}C3/`v6\wF #g_ee>9?ŵ4yOIt.&vb'/g6VnGN8,εS>~`Xc,hR%Yѭ\;Vߍ>VIֆJXr3ܰog~cy^ }K~pׁ#ұF5OG}6O-v/^"X\0~xUg#`7͠^k[:? ͮzIH#bմ^#7˛g1-~#s\so4'@p=mrzva|tgCWo I. Yi,EJ:fɻX./}Gg_mc=ⵓx%{守}O?wGjm34nW:*->ōE.dEwWMaRq N({W@} o7G0O|F\d_&xytl̛=-r-s@ gmpm|΂xt?0Ɓvv~ׯ|y}R_ٻ_dN Og(b&ݪTt-o b.b=&O/߻2 :t|MώvqlwN;aƏv\YTNm_Φh|9r|`omDTVe=[`҆mT7zz߄_}mHG-?=p7~X;WP'LV Dm{`{U{kdxI90~]QI+_->6mؙM툿`}mǛ.IG?Wwl[}<xqS9~3G}F!%vy?m&MhǕ7&NigŘ ݗVV&St\# ͏aXl @}ybӋNㅧÎbFv>J޶bGLVyAUj|L%X8[fL`kפ:h9dN?k Nf"zl$8dKgy-܉y^?~/`ۆ!Ċ\h,6QY p>i_UI 5&igxa-oW\;tbNV#ݖOg'Cx׽n|xg-><`O>&m7N-6/#˶^%/Uv|eNâ{mf7M1&/ԴՊRWtWP|_nRK'W\=x{/8*^ކ7:q|tg=5:ɾ_y* ]Pg=᧗8/0gԛƵ]xu1S'wR^*'N~ kpAq>2pW*#l>zbfɼU=mݵtjקƩr_kx-r8> B?]_=SxǑ|y䀟٨dvOgc?+l'q2;7g1֤[{1|W}z^_b\^~ƒLw0_.-ifÓG{tHo]JӆX^͉uӟ=o/](pkKI$/:`A΍cSt1"70q~ޑ9Mx] t,KvW?rz}cF{ҹt9ݸ5,"1YLקlQU/ e6s2Ub4}]tȦGM1p$A- |WY#y^ARŬL*h2bN:9Hz?@\s ^3F1r-ahtK\K;yʆgoMtU-:=y1#/1VўzƁ[M1 t~mڢݦ:;ÇӱI bWN|j9'xEvmT>5wbPWl&e/dj[FaE~F8fGī˱ ^'8/?\1LpoԞLpGDaޭ+ÿj0g 47hvA+;29h^Z%hm߄dAK=Ͷ EW_\}}-_&؎h&,dǰ-4;!6vmq2;_:}Љߚo)Z8&gf7Ytm}gWŮz$r蛷\ IDATR-p|t29UVw}(No ֨&Xў&~J:)x8XF^UX#vIPɝ^\xlHעmxo7ϿM}Jrt ral&޻ 6,_c|Oyae+Ogy#Oh2M&M*O+er-2vDh$_{yF4ɜ~?=4,[R S:߮]mgqC_hH$z'V볏b'mDW3ʞ<п藻a4ɹooZnk*kS'V8zB!~~>,@eMgX,_cSxh\~xYlmW_'{WZ,\?^L>d6C?6ll(Ѿ>ML~) <-P{[;]|!f#fճi/0§m}4gc}ýh4Zڿ\v<|*pDZ٘&po_usv&gn'Yx+xxmjhG?K[?F>[`z:|:7ǝC|NF?7+ 񩡕([zS"^uL7?'r 袍3dtzeU;F-ԉ㎅}ui` ^,s :x~oC-|]Lp$_J*S9W~Nio䛝Kg]~M_:)]e_?CdXa~yؔ0.1=_\/'V쓵H`We/8B_ى| J/BGn6'׀}$tn + Wg7AmY.'Nob0r5zB>\``dF]? =_'⽓LOG(ŹN4y"]QO[nǓJՆo{X^MZ߾I%Z=eI;&>y*M?bЅ/Gg2I;kʬ.>S ^]S>^{:츓~s޿ww Vl' ǯX 7&~9_<.nkx bF7E;fp:_TFE:QoaB£} eV&ǕVza&H }k2ᛌ7?;>wkQ8n '[<]MƋ{6Ż7=ǰZG}W&c9`6""\}#pG{qtptsY?`ȕ}s{}'&I^{"^gOϓwЗ@b?qas0Zlcb_Gt}VSBb;ь';ᰧNЎ-[TJ>+?:8uqll-e^ň Y}e00S/~|27oW QNvx_ѹmԓ+pX;>7JJ⛶[DmFgp`5 ٦w:%ǼMV->Xٿgk%GwUVS*q}˫ݷP=ؿ6ύ=X0~VZgNve͎wh%thdm'8ՠ{6)1K4&uH(|Ƞ{*yE챜RWt`vU+lDc^c|6<:96謪Oxd$ڬI}ݯ}ezW mWOگ±x. KE!X,<|8- ǝT%E*[o{>I$|u g?g7]1sZuɻOmI#,F |1=3{?겹6 %-6go6QYG4[vt8b\;LR߁ x,Vǻ5_3{+qT =}tE>ybf6/n9w.w#ykq 1kF"0xQ3~mbVќj= ~WY}^:'z1CQMоyc6.l1oP~n{jTתc{}_gvwAcX<1Fp;^N a4"&:tg?݆X6ی=8 Vz?X)h *k/[ٟEojj9 a$Ɩ>; V6OlOdp8b+<= R`9e&?^1.7wW&-ɥ/ZYۋUŵnm)o+(Y|>Rbw'8g xGv~?Sbqx6dn͞_e<'Z;%??:]ޓX fK'ǰI KQӻ{"#ґ ]&jŠ9{ϵNɏ^w~ӣ qYLiGSf+&v3{Ц7:t#}M^)BW_|^w!<$B}]Bw|$W|k= E}1ݶ) mçm;gɭGVo1L=`, oelin5r\|?oO(²r>M/Gaz:c ;c&Χ~=9^`םo8U>yhW^绯U #|H|bMhgM]DůmI!_hglQ+b^-1mly3ڏZs2rLvR5P)>YՍ*rT{ǵ2i>"_0杤D ^qgp%1 )m`+Ƈ =DQmК`u[yow@gVv {ۿ[n jp8H%C}I썶TK )DZ0$fNPdag-Zdvu>Kl;ѭ~+7~ē鳭T/=+=Yc82; [+`]}ͿWFdsN_xNg+}wuITl(VjN2c6: }jէr0AHQA(_>cӛmwp:]:&'OhG;{\Įd^2 ampַ|o?A_M v8>n߷*Sd(zQw.]=mbna͸_ ;ܝqFzJL̹7NP'iFVM}]~loY|+㉂=^;s_Ak>ƷM6Y k⓫f#Ĺ~͘ce9xl?ƫ'rD 㽊乃f6a~X}L#;YvnBR|6/s`D,˯tx㇎?{rzo `<~37 ldDvߤ{pK7/ӏсa:< Z:ˮbp܏ ^ƙ_Nnu}N[$lS4>E]I- Md76ޝ3Ȧ݃ţw{v?̊[}}ָ6)7"¡~~v"Nr_ # 喢¸G#k:C,) U{ljy?{`ƹ\0 &x'-Ij<]?1_mӍlO/n%;n،9wߋ'79)Lt^MqsA,`1̛֧*[ (ga␎ms~_58B#^.Ywoz ەb.`'wm<'pxv݆g~驛5l3qٴq}}oʖsW6 oX>t~>NVWۍ%ķ@F}8HDtw*޷qvmht5c=<&.,'ާ{Ac]_.?/G7/ɽ}}5wV݂mo8g.ZOHh$/qUآ%(yG޾xc {iNoE{}/nEQ?k>wDv?= y,F2{ +d~&:Yѥ8rgeB&WB(nz釅Xu|j79;.&o<_ $OCct/-}-y}QBc|p9odg'jlnO!BIa6' 82m):]Si Qp2hr+x/qƿʼ g%&f%g[dh#}Z_K:j2>G@]bE& VI٧&7OLXxdJ%BFաIVzEM$yּDp ld5yx} ګc?[o,ɖmA$Zo9##TeQ'LG]e &7[9G2᠏w KJ,zePx+͝&-l{u+$<:\UC0]'ŰVC-(mwq㉝9fT^0sZRG'~94 *N ct)ח]dG0uh<ć(JSRNur^؟.Щ2:ۻſ67U!СFѻa麟WߚlϓƯøWd|I"f/?UngmqO 5+>GmOl|N|`('V.o7y䓯_S}biѕȞ>(Y-}}'iqS?Vw2K-7guh12hFno'Ra2EdOiWBq籌Ay}'}l'췟nl?|O2Sc'q-^nNl;V3){o߳9Lq>xMޓ$;(!/F筟oLh#Az:љ^M/h;`~/(ăbKN*k ×o'aE_k`|]mx9>.ݢqbyU5xLq:kdqɯ,$koɁ_8WBF'}v=类:g\U]`q/,o?crFB D/&1[I`l+6\N'Nۇ22C'ge_'4L}sWwp罨xs'x\->3;<6~?BG{%ZϦ7Nq^>k\d /|?t26oh" v1^Ӌq,ߝ?/Nq>4lF~wd[~4ocA/G<,ߪXiT[B}0^?_t9_hxhMMt~Nr}},nwZˎˏ?]N'/gw;7,SzbyMHD T.ߡq~ ʆmuj=,dH~&җ.{ye;1A{ל>08&M:;32w l[su Y2}\t<B YvOmq2NT'\Cl9V?>vGQML qet—ks"_ b<6lQ6-A(f3ߤXeXd}:1=P'7]ugZ(# 5guMjp8]7 ֆ꒱[S őmt [uN`arN 0a>OYO=I4j0igڲ$?N15THMl쯯ˆY}[ l1Ϥ2v;zIF*e'W)kr+_ >VFFSj'Qg+b %p5>S/|Ҷtq^}93m߫/GW"WO/e}bfP9^B{cv1#pK7.=:mvcNΫ1l`^]d'~oMze|tq'!^΃ŜbǓħ~f'N黓h"2O9ە.~YGӧ0嘓]]d+dai81˃ jU쎏b1X;csܫ_c[݄*x'v6_Q>]UΆ7ޞyK>s4lVdB-~nCfq\ހ[xm:3MB9èhx?ٳw2LFo_U[yXdTp&급/9|8;kU4=?ę؄ g?}uIw͗Dn$kbK0{PsXrVDŽ=߅HdYs )W IDATяݼ#6Gb0QԨk,GPL\T`>*GOG[O2 M]FL~9ƇMyhaȘSng#={.6"_{ŏ1)(mI^mwQzYá넿~g^lΫ̚Mϋ}')r{~ NeĠ<~)`WIn"saZ/Nlg~qom}$bƈ0M u(@GQAAjJbGO:]nˮA<>W͙D}' vX ~徫 }o6>qS:؇bi[~ػ*[u~Z*x@TVVa͗ #Nإ0 ȏ Zqۋ%ohļpfJRV#U/M ËWwbR#g3cO?2|tlN!tN aQ3$ku & -clNDRLa߷:2n ?=Fm;$3^|L3I77x_M`fA}*OyhQODW.|ߕ_$g|a߲ކ$>NG7ئ,\P??$RP؄]S!Y4&R[/V DnݳؙvŕD PE76Y3=?p[7[E'%Np頓5/$<1X 4_?Xo@![1x{ABٕN<ڤ;̚+fv_~bހ\BlD?j|pZU.A:qk^b[crc˄kWa_տY$ǫc"j };ߺ46'X"4{|v󏺶6YB~>!OSħSa#8T߀R!8^";ɗ+[yNt^N7^} P}.F-'nWjmxWݯmɕfL }㉻ ?׏wpX%D;ً>:l埥+zw@cĸ04,?,dx$btƐt&bd7~ttLo'0 Hs4yӕNs ;_z Ixco>&mj/>k'7\0noDT.] \5Czٵ~a_5igr~Ki tDQK57ei6lK“Cf2L߅WlE3Ϸn );|!ߊ# vFu}"2J?z~^17Gl_HcxZ4EQN̎+w2~⸗p~egn~~_\^xLz0}2Үnqp602 CQqEΗ_~|]S3qwGn#F~XXldtd[cW;,9eG8m^DYc*C~5^? Oܠ=lT𔮆}m |^GxuE{e>Þg&o+;_,n][wl\3w`N38ُ{LЌCn8_ ?7Tʽn8M> Vtz7V XgA] l՗l; %tc"}!l's&C(xF@};ڴ?0[X mPGfS%ZDŽ#̹g H=>dзXs{h) ԐuJ%uTz nRhPJ9Ńx]'g&h6 ӻm!Y_2>/۾xOփ|__Xmt bI2!b<Ԇ@H`G?vOverj6 }x[k-6[:$5"fٓ e9:v>0eUgIQsvye0J/t&_ɤߛD%z+vڔQ|t0bnX 5m&_#{-!z={}/Kh{WT&X>aǓAMx3jwb\]] la@6aCݒaUw-~&0C kh &ϏS'=|6-Sў]|3E&MF9frĉ,.n}P=-7,c8@Fbv'@59xqcXO;xn9nXMNld׾,Iuϗ$cy-~tMߵoQ,]|0#M?R%yp_lюi`OuaZlדsUȢSv1O|Rw!f}~Ŗ1vϰ[$TlEU_@#gFõrDբr'ߵc8,^Mmt]վ//IS,'jJO&S?0-/ŒX_q0xɇv}~4ݾ8l nB6r00<~PXϤ|)xtUE1$׉-zzV1C3{;wYpzjb/H`8'0n[<#[ر`daA b0<[5v 9_#5u]aMp_2rŔ_LDzċI?AS׌ >N[luNGRk]?Bп9NVL#axU%wҵb'? }֗a/ޟyJZ>0a.=ʢ{˂of T~7]E/2~I>̝rn8b/-eh̰BbO}ѫ(9g "{L__jwZhL"Hu~Jx}6^4X=BǏvoqѝtoE+6>ڌ=kBtn豈?ZxV. x2dmJ2v~B3awL_g!Zx@=+3YLmK&%/3OGK]"fI8$%&^rғJ7z ۧlMZM7ЅGNP^vw̏ V({ SČ!F r];gW6 5(Uu53h7yKC q(#]d9ѤK4ɢC%0 ]%wI&0Bjy:QADbb(}^4!46:T$S t}7ݲSY2hVSgv & QgS=+[_NjЦs}ReN{ xUvl9 El\܉hNoWljON@ŗ{ؿEmM6zl|zP`e8Z\HtQ ՃL-y c[plM+vm268np2dKwEiOcgq5|viOđ2_~3,`L>×k?Օgg'6H^97\r,Oiv] ]?M_mm%YG /0 xwV;aS>uo/>&by&M43=8\\O8&' N6\9k1~M\{\F>U8BO{6ovqDgƦ+Com9?pѮ\|јQciJMIqîmMůhĸ?oOW}*݉xfQъW63d'tx{']WYM_ ⿜Γ&{'H.9P kZ 7fq.wFvrWME{wFK=wa|-Nt|m1CXzY=70߳B[`7yw Ŭp2bly1bWI xKW%mɸ{^;`tبRœm-|mxV Q䷏pFYm3\PW|/v"''>u2.l{F2@=Qʼn/pЮoSp:LOq~ܼNw~ԞNQo>4yl<\Qa*0"ka?~lo^4?]m\/ydvjx#)T,&ɩۻ{Fs=>U[QcsE Ô|=΂a4EC"g*szË?_[9rq;d9++x>~.2YLm[;xWR5ǜ2VR~:qQ=B %InjRP=Fw&Q@7h]W6H6dk;pyQɧGc1CaF?mXsy &f:f>GEW9m{Qx7c~vd_d^[H |Us[Sf .'g`>xO&[%|=}$Onta 0tՆ%KC3&N9(q-ͿlQqRv~D#{׉{IA;&FWy/A8/&/lh.%|U<4EDqỶx蓬 `zұ R;!vQmuqPsUg_GaQlйg;B7Lo&gkb:MM+ܪ<]ņ@k߱v?mqP=ѷܷ|lr/V& ᘏL6 عb x׷&yiv?+5t㳫tnUNR; Fov+CP9Nl׏MCmlۖݯ4!;¡vG0V#F+|:m ?񽫠1~f*|9CI`v}q]qx] D'MMqm[\Teg/EamO\]%o?ZW30mNWz|d18烳wj_ag0 ~Ng~]-{[o~'Q9ěj'\|"z8n&r-@,HxǕWXvR':%pѷ|RPByj6a} y~w۴&t+[=;bwmx`B\=k[F8YOMoQ$:J x| v{}B]~Gsu'o6'z:Xݏ/$kw~M͡|Z`G'6Ox͗캓{{ _7طx~նss! o}&a'_~]:]'{1#}b?}vUXs6L>QtjmX]/9rϿ;-aߜqQq8=;>׵[ɣ ]ɩ|} x>w~ |d_W#[("JOt!ToN:g'z;tX-\S1trJYpy0Jo~ܢo5[8ٸ}crdoqGv^tQ:o̷| 3tƶlBxog>ܨ1ݩXJXE33"}Se_C^F^# v?˃t *{mRӇQ\ud#u) ;nU7]/xM`EtTqcx+0Ͼן}wfikQ2[%&w췍ΟCgK$I0k=rIvM7`8? dguëoF|$:A-?xooҞxP*+[%# #Ɔ&g&#g1by1:]_űMvp x+<Xv!W2aT쭿U-x)^?(lN2IlgѦf/1 ƇZ<;10b;ŅcUc1;|%seX^Y|NZ]9 ?;O'o0e=^<?[h8٫/:ݾ$E۝$ L7nVm_.OV6`wG ^-nڹb'a wyB\cx56MoEŨM}ke U(тƻ`N/o-XEc-O??ɜg|*g1 Cc#11j:~ō*ܣdo~`XTڽG3҅cd/KetgxDǣ%c+{>gl.WɓSX/'4)58뇕-i\$_nIN!чvww l,E(x Ρ\J nm$q:|<=G_'"2vEGigA&?x LĹ-tnHz}l\MNpX=n %c?k~nEO*92VLYNUOKJ˾;J`lC%6^^!M ti Țt]K\$>φ'>x=5'ʄX0wdcIu]Ҷ:4 O&xGuhk/=yITE$*G 6{~ xX„oCT'и*1?K?o$^l?5c%C@} &3~^_][mIF+s|1*3G$"r#~}}4*{>ӫzuF)&{C61>DK%-V)N?'C<縯>1xC;CM.OEjx|&*[g/>T &|t#ӅtIKϗؖ߳J>FmVؖ]+wu}]6i~KW|/-ƍe<~+Orժ׮W]~}0޵3a[f!Z<A|Xq;-.ЗTٹ+;A&FmkwuTo 4iq;uK:Mkz>9X/0 ev,wmcy|vX<1]'Lt6|NT+֙k+I7M=Cю<>pKde'ssaV{#sE &SpɖNEE|ϬngNs~MX))_]}TX ȝom3-l<哝C/m]9*w1şlfw %;rc7Hv5w|ᤝ.%9Q}_HsNkֶً0Nx%{W"Gc :Lm>7O 5-vRB³=a!|Ƥ͉ žҫ&yWS%@a.a]!>7׊QE+mr?~У(᝾y-8ﱀfO/Wc{tUE=Zwr>ȃ&7Н0mE+W I>p =~_n.wCg+r]lzqv~r[fAu\N/X~ڐ~틉ѱ"4ɷ~iS~_ gj$_l]5UOhwɰ/d^qAxhl Tk'Pm%Ǽ 6 ^xgB6L@0JrD{ȉ\IA; &+5vAh$A# dO~}r]'*Prt8=d Fg\[ DSWlo8?twZL^h"c &>2Ɍ|վڷж&h-v?Aym--|>9vstED}/%n.d[{7cW*ý~t*؉aXթ>[ >j|e Xnw(䮾d/v%TS'VCc/Ov 50JHI*4Vq|=o|/WWt0*Ib*uA0Zr'N߰9o+4;{;clN?6Evh#nlx/ۣ^wVjQ^s<;/?oZ5?-;Gjjj89Z[fÇ@tml~?rp~|7>͟fcԏĵ㝬GR_ U.5Ƹdx8X/ٻl$Kj2i҂|~hݸDO}|CKl;;əG3l9ɹXЍTnhqΝEsMKx9tFN M9jbCb1;7'u9ㇶrG<}^5c{+ -Q=@>/]s Gq W2ʁ͑LbNGIWSF~&(Ѽq_bZ~b.]XS6VջkTnw2}Ca]Û5ъxXW,e6le'S/'LCs}1Ovr}SrO4[ \HN{%=}ͣw/Lg=fIH7o gfWͿ䕸~O=^np?imcg|7ü?Fϯg_;;W&cY;,oY`av}2Q[_ ;w=KIXWn}/?BCw7gٕsc<zbپ8~M饕|rcj+2Mq?^;F='x>|+LOߗ/kǐiXCe̦[y+hW>Ж6WBo'Nf'M[w;W_L{Oh8AN$%k7Fm|?<*}Xy1;۞/ZHʯW=hįx>'x3߉><;YdM+/U입g&MX>{q0:S8?vj*Wt8kb+/&#*'p1s^IO<}<n^p>e e'|.$t8]DA7i~6^dO4R ͵d%3v|q}&Qvt>E3 }>+&;ސo'9tҨ0~o70ۜ&q_@!ZF|wʸnd| =\n\,mtGޓ>̼d~\Ή/bb]aor%,wT7Rϛek cg(hůmu99|NaHTKQ'h Gq%'<9^Yz*>-7'xI m#zʷgϾms'stC~22b*ZU% ͮlr{=-?-~PL~@?߸;BE&¯̵HO6_^ ji9^Y|`N)p.(^Ўt3dM߀M!, g'?0NcӻvVNSaN,;.O,!2]R&, F}ҳMٓ~n:},v;$H)+ޱ#:{ 6VÞ_;@Njp6.'k;}`)%S/+I` d:n;ٻPL]uق8ыY+qm\P}]["MaD֌mZ[{4uL]l 5kǎaMp있n)>vtgwi3/}(L.׾:p|_c6k`!} rD}E1G:Z)no{GUah?dj;c=Jo*HtڷUK86 _Gk,ʁMx+IX::B4ym)u[9XM&;]"gc4x>`IXxx<L6`1ބ uy\%aܿVo:2:<Â|EIߺm8\=i𛼟ӉGԚ*IO>I ;_?8gruH|d8AOp~lUDwtx V?m_v/VCNn@ Dj|1@i{nzg >.Zi& ٿIwW&~7:;rW(y~ b xN/}_,th=#to[ x0xlpÅW_{ci8!)gCIU>_YjTmKkv[BEk%9L%Iqa0]s3 +{߼<}}?uqO=B] ^E/fNgRQo!яib|i٠:H޳:4I28p`XgIyO>! [Eiy话"a+x7ʻG@4iԟ26 όtL$ƷM W cY}4ryq@|Əb\̔Jehmh*O)luz%4v! >ge,hQ\izr5#QUMzuS?hh36?:E]'&=PF,eBҲ'^F锶FV#̤C]d}4Q;v#/+Sɾ@=( w sHhST>MQ\÷v: ^LӬϟ/44o=g;fSqS3qA8?)/1‡1Hߝ?D'im`Tk#*e.0Ge:|W(!8雟~i|ij󉊪;Q*##JG4+1Ke{ƣ um0uXN4 OXF#TIuk3;x@umd!W6if.ʓ,.*nN6XSo5@1g1Be|cHKa-tictVG{0e#6 qsx!7`4n{,_R2Do'u*c ~ xMN H^eT5/$xBJNcmIgc Pyy^Dž  IDATkhL.A}`Zƃ#uӡ{%Hig|E`?Szv k^ p̛hEz-DnS@bH@x|MoqxE:*ᢣ*ygz"ipc3~v;{DSVTE4ą=lrE#KD{Iq 07Ț|K+3*-#gN3yP6-`o'IC' C˨_8p+_#[V:= =FB`I,r@MSY~:p#kI-?az!^ݳuK=I1_f >s ^>aNLgo02@|Xm7? S?=y3/`q0YpƄ&-.p e>.+bП24 FT)QD f0L/UȬm1e A%C37-Q5F?'=)0=&/ +򜏑ቺּ̎i[|"_ȍ(:Ү#ˇڍHCى7y6СzBMz:kk81eCcKԦM03=aZ͇e뉥7*/xvfGvG2"# L(?7E!(AzD=9ġx⩁ &xZ@XG晽3oJ{{b?&TC跒 +McٱM00'󇟞bDZ1}X>ޕiұh>; |ӲG|CNIګ !PglA a;ƍ bsPvB47Ǜ :te}F cyri2}0_l`y'4OySڔv"z8Qn>-&< OwlDJQ%/ 6,pfy&р|028az6meJk|ó!iKO䍂;&iab\,C/a @4H]2)1*9L=C2*NJDbzBކ[HuNfc*SDTyzGxY&/ӟXVC9시gW&|xe FΦPG@)\6l=MJJB ˗|3hLG/_b{yhj\ҳڠO+Ӡ ARł#)>"ِK$s,焊̅O:e-NWIQ#<[ϓ^ј*S}Ch? h3Mid%ʃE]bv@WdZ'S_yPVa =m0C=X?<54臟uE33Q?F|8loTF![ c\/"Ô鈉F8}&_!pbbe MS>4 ?&`g c(XGqlψov~,;z`Za8e y eW,+֏B͋Uy,1f'PG$_^ 5 5"xz2޾LYX3vC|1W} pGu{%{qxN3d3ҙ6uoqr`ya2's2y .{ Lf&"edP>3S]ghGڞtzpёEpxϠ)O\"PvdOC|tq`f/)( 4'$0hjb@=5zx3%iL1,K|o8/44=y#@vÿޑˇɥJoOS[y7<+_HoF9=c6Yi"-@ F)P eԊ 8KT0͇)=j=G(T&5W<edac͕(#VJO׫HQ9(1(]v( .# zkV?lF"Oq`I|h{I |VJng:nxOU<<()8dɣk8QH]dâg*0!H ]<ֺ3tQ b:ɴ'2c0Q WcG/psKyc}pg"qu R-6W#t*a ~0 f|tُr1ZV*?̞hi> tLv/ ;lقeBڣ|!O ?#&*J ~N5<0+322eE:WƩb0/1gZ>p&l; Wp꿡`L˗5ROu ?Ȅ}(OH_'6س6!=eea:O;E)/G 387DC܀ +LJ#ӌ̂Ѩ{ !N1J,!;2w57O?fihUr&cfbaɳi9 7l{T +8cgq.v2fcc@By33Ĕ+qf #MYqJ$GEe2tUߐ^,wl( wfi$UANboN˛qzn ly! i@aL_dV勫9Pndw X QVi>3 Jꑙ,+Et]D@W!  ?UCzK[3Bot/GO q௲C6=2qz* &юXPe%F[R^Y̚/3L tL}cfjT,X_"Kz,AnS^QFwLβBuQo+xÜ)*qTh hhzKQL)3^z#^f8:4&vh@Zhh"a/7 2jΔCs Q7Q@Δtzd^ik, bMc?ˋ5X.eRwvNIҪ3?XNOK@Ȯ2ƽNSgYydbܲbM)_#qa;HLncaxg:NW8PVKE5<h'm7ʅownn#QQA']3{:|}>=42t'JKF#.#QQhھ0ӑ}mS OnzOFW< H2hZ~{xҰDz Q^9NdN>qq/O}OT9{!^\Q7ÖB@2bE|&>R_=I K@F9zfp@b"KJ߯40 (Iq!@3>y&!xçL`čӱ^r[gf /HS󂎁MOq^񠺦:re&&|&y+W~Ы? r֮WO߿f<# q3zF\+ PG^Lc6 i :|'x S`/<#">)MA W0rh;uO ] E'peG*:A>6߭A}@"su!p8C!p8!H$7`όs)Y;C!p8C!8`Zn׷iFٿP8!)25jԐm.]p3WcC!p8 {vKmr?j _ڼԾNe9=!{d̽'3S#/UGZRN]S"()I.$7r ؿ/%\?|JiժTXQ"2\~6>P1Or}sC!p8YGf{mY{:K'+J^;uؠ4-y%sGiڤ>'5k;LVٷ9rll޺U\"?STRP1ȁ~ZRT !#@jҩsGm:~eXt8C!8?غyYr*g-/սU17IF WIB򒞞.Kwiۡ|ҶqիlX6Mgق|'}PMfe _M|2(B+/>}oc8T\=3-[xL.(uW !A >G!p8CCL>,r} /,'Z\&>$ڷNnݻʚOHʵKjj2a846w*h9@_oz>zoC _?3|V9N^jժr J5/^MG IDATy08CP}9C!p8>>Lŕu֑?ي)'pTq5IdMңvme'e!rJKlժPG[?^yr㵈S׿$?x޳C --M'FQ܍C!p8C!p 0Cus{E񟗛vr/ԏDNS˔&eSzܩ+Wnvt?x` u(R?P/ `:$cEG0G78C!p8CluH/_ds9Bʗ_m ۴n` NPp,A@ΉHyqO>u\ uFt6q ݷmk5YN[!k`?mw+wW-G0&=7yH瞕ӿY/~,~ݨ)7)<ҦM޽FS_OZO~qpKߏwFFYϿrC!p8@A:0O["ؓ%ՖZ8IK\PO(?wggv's0PjպP:u(v}]Bi)]t $F>!'V[o-7|S Ԥ-zYB~·ixS- W>'?<%wŊʄ_R*ݯ(WKѹܳ5פ`c2_uxY#TK9C!p8IX iѼwԪQS }/V'aa@||Y[4&7#Gתqa! .(i+&FNNCc?F˩_~6$5 ~`Hl| /o l۶;;by}ۨ{={/a8&pS5[++W՟ࡷJN]7f07cOW^%/1=4s8fX앛9_<̯†Y2_h~|p@ݏIWoN]⑇xP9dby]NңbfdJA _,q>9p8C!p8֩+έYvԨ^C`uA\ L/#M/T~Y|TRUvlZxa& ]Y' EX_ٚ5vzٳgOz8PA~sNٲu$VUբ,w'L?N;Bp/ nU; |x߿"p<}vcI[Zn:Db>G)A:ltAn[eIڵq׷ޒ_zQG翳@f<ēXpD^=tnE8>}zGFeͿscٲes(/G% ,Ny^n=\qE7ٻ73@5_3OUW@I}s/3~yխ>W_ i/۟qer!p8C!po\xa@ΐKar6eɒŰ<؜Z%7o\ +In/vLPڿޟ`LjpL;;}o~Y+i-rQ 7\ s=w݋s WbTVˆI?dȰ;Fa?-0RM4+W,~vЬYSmCޓ ȸLfà=.?OɬQiKNzҥF7 PZl!7  .6[qKd :3_>ޢJ#|*ziTD#߮*? 8Jr8ҤwJs,BYP={u_ROcXA<93#sԯWP2lٲ2陿?Ȥ ?C!p8CKװKWg'!0[Ɓ8JČd_ziSIn7o5q =- ݯBǴ t$h&| }7VǰkqС%5i2] 0[h! <"AAn]u)iXϑ_<ƭQ`ӓpFnɨIZ.Xc|X'ؔa{ӦMPN{}^7[4)&kIrf=]l4!)PLE14L瀕>.y_55 #36١s4ڸHswC!p8CǏ@ju6=m/+?X^ ˺fr m۷7aW ( ;O6^L php1px?׈wh73 3o{GDl7V>utx4uM 8)v S/pL+_U,:ڷk ?E&zo{-PN^/`o7:2N7*o_a?+2LPX,MgO^5za4NsޗM>WýB :? //3;2/y+//yxL-o$LRҫ8C!p8s8:sǷ:zÆҼy3Y9P͵;uV 6mD`}:n6 \!i u)aFzFg`ZCWY毳|4?w(j/Ma\?7?:w}?|''1u>sfͻ&Fsw4}Umioz,mo'ӡ?Or՚82ȏp|~x\~TfqId%?1Qn=LZCt\nq[uIfxgb_0޾K$ T{q8C!p8ՔvzLo&uֲ #-[O&MJ/0_WCJR}ބlnGptM.@Gug;g̔qܜ=8 _Gy cw'3we7Xxhv?s y4faC!p8o˼m=OܰfO/~/lxip5Ipr`VòsnG(NyjWX? UʤgY\m]=Fꍼ{ *[qDחWPAgpN/|PA];w8sB&>-Nu׏<,^1C!p8"dG̓v6?%We׮ouxζ?}T +V"1%M"l K~zJ.-:8ퟛ\pZ7N+/xƍ5`߾}z.uQ*_GXq!a9c4j$->@oRʕ`u9C!p8C߇8̬:`ug@ժtߗוS؛ȑ#;;[J$+W:<0N(؀#ùUȄft8@ ~ǍiN׺PYOp8C!8EN'#W$j@sOF?Vo԰0)NN={_|8:|S`HJtV?B{ ޟ9)|'#Bp+=;y.ד >|F;s8C!p8><~k@,y,o9,$ҾSgAhgs?cX22sR#/fg#kb A õe0[>fT}'@f8]:S>X3's9~lPyAr+qr,;&!p8C!p^!wn"}nÏxF2W~i0xQʈ71\LyMs?2SMĞ)Q8a$>p!p8C!pw|C!p8C!G̖-[Bm!p8C!p8Y S 9YC!p8C!P o X  C!p8C! ={Ν;eKեN:ҠA(֮]+t>J۵kWc[l)]v-L͐!OmUK믿;#*yꫣ{6#=zT*8ŹKI:9C!p80_}YF={ʈÅWWgx.ϴLӻvyPw&hͬhϞ=[[b}^Z,X fǰXUL8Oed̖\`(UMʜKdHϞfz%]옝ò\XVf]*7h ůϏ[vsCL @cL5$iذ4o\4bY 碿;r}߾9ܟ #4#G3f_49 cb.Ǐ;F @Kyn_S bg9yܹL!R P/rpcƌ T*!dcZH$@/-F̕}oK-d%<m1^6gY#GY7pddB4Gk2j-˴Nq#n5@Z񶜭 -W6<0AvYI t/<5seDvܽt/S+9>9ZEsY#X' H.*l^-vC˜A =--Fz5a21-UzZe+S<7*~3f[N8ŪKp8~p4Eꪫt/ p+Hx t&[~ҫWIHҦY""$.Sw}"D pE(`hݵ^+M/4`3;ǰsɅ3#;~⋲qƈ,/v DE$ZJ!:%yp3e]Gw̟@M*I~ۛM89?)i :VJLKe}"Wr->@'#xnQUƔ4AzΙ-5:{;HPGe^dcE)y;1MZf" TYN{EI*I6ɦudE2crQy&cYV  _Y ˴h$G]v7=9ivzE,B/C ::f{k2|!h›snJ_n#`W$E'Y3T~GE;WBGR¤/WUY% L YO֣3]~a;}',_RO2mrX.77/a{X8tq7T:LpƋ5iDn(>-3q_\w&hHcu` ;V]u۰<%q/W^)?&=t1@buL?yf)D@$~!!?~r|vaGƙ RÍ"iΪ|s\n 'lzay 0Pf?h7U9g;Ȋ<Z;R?F޶i`-8^fa=Ћo_ Fi&]M$u֕IR&)jH&?/sL3|M,{͌2riKpyyɴ?-Ƈˑ-ΕsL; '˘ʪ/z|%󍈝8a7b0ö٘I Jenz[[YÊXk &#&Ε ϰovy#dbgȪY |zP8?b̜otav룦^HX*5vRy ;4fn`Hd @+EN)g'ʯ2d%cdIyiegۯ FȂ9d#g,J*i83tϡ2UafrROyd=值4O:Vz>]xY|%Nf͐^IDATʥeƐV^j=u9Qf$Yr̙1Dj샘|$Gϙ!%/3Wr32U.4[pLyT Ć2i0(5tCke;_^*Æwjf؆71bu;v$L*̅q<-++v[h /Z ht?i3右iSRR{1lZ_{I/*M(?k?cx ST'51qKɒQaYlu睖s:ζ sCTmScZ0߂ LCJgZC:\w L5ЏM˂Vu "fpRR?!4}޺x ( 0Ҡ2GKՖ1]tj :O[:'ޙ[)/k55o.˟Vʛ0\viў[E1urXdKwK"hC~93eS\6s.9Qt`T3'eCv$mv',hU&ў'Ty&ǨMaRK4r umKĕҥmK[@tfdA:ylyc ұ͒ #omh~岶 e5i޾-vmI^.]ՖK s}!s(_r:S,J7ɓ˧#t Kp-M_ 5t]QGVkAA04EtkIhG&g [FΦ^I ov)|UHaE[Eo u>Y]8V2 ܱ=tU+E{4 bxI|%tym&:R| xOZ4@(][VDw4$&ԐC-4)3MVgBw^*]h $6A:`ʥ@W#&(Z^o;yhp]D9XGv}i^  Ooc.ҎxIon MFQRd'&C; ]_ݝC!(M5j$^}au:2{az3xO?TݵK>3qx\аA=`[1GYK&G /ibqi4 .6w禍Ui#`Z0vwMG?Eh7@Zv?Խ`/|Źk$+O2 b58Oas6] 6% ZMn[rMHhVeoMS6ꎛtKf`< x}4v:3D )074a&erHwT3CS[ËEW9qҲvq-a-*Ի&Rva@J2~V4Si'g`dg )04 pﹴD`U0#Wjvchy\L4B ]6^1dk,Eki2 Y\! \r Ṟ) 1䒥7 Gԑ"O,!lHSFQ߱+^ ~—A4uݔc1"Ol ZdU3yMtXkFO!h]. /k&kk2YbJՃv׆hHzu#M"eGD('$I`-*#LOC1 $ɿI6M8 3EN.tz,Ajݮ1K%ßr B'ɦOI f44z<'2Ztcvҧ1Գ▤ " ~YPܱWLݳMsd#P9!p2ľ+6mґVN!+p+NT(=94KQ<$خ磽a_vWC|=r4~ űu-&1.EMjՒK`GUŊU_w-0 L;~fὟ$&^d4$!͂O@"&DAsl(WWsI>|؍~z<U!qGu^Xp^P'65ZlQi2 XtNnj7!QWfM:ΟcT!:ԃ_Z*OT+~>L@cTO'Mf)LzDW2&+ReTvȓfu w2?렻qcƝ$pбSp_XvhtmT&&nr't,AZ&!۱R6FGEdM5GKI2vod'cdU|T_Lȕ9z@TNeUΌ#|U)Lպ&ۿʐkJϑSӉ@r2Zf;On/\b~ސͨl/c}8g=\hqp߾b6KLV&X$Fn!)i ]2RjLi+,*+R(2EƜIqԚPSKw݉?6cgd.QD7|-b`+ɒ#R0p8bB=GbAlpg^Ld#`huScb.DҌf8!X u .0XL{bĚSw1ni_g }.sagkԇgƍd=2V^-=GD& {ݳgO4IKOb|jta?~tF(kKϞ!Id8*cv닿iҷGS}nع dOZ$ԗ'GSa![W#{cJۻdK92`N) /̃jGVi+& %SLXqe|os d@&0y{yh:'ΊRFL/p#KloLmHK2);?䫑P:ZfaCSd4Tl^ՃIaXr1R)Im 9V*BXdr,bG*t$ud*C!:~qRdԑF4Z-nf-LT.9!S4ڄoRѲxze$`R~@8YZ>d|"t$"9L\ 9>o Xx-\~q(Nz=\&x=Ɠq?U Zy귯<3)h4~cGKdҶIlG Id„2i.^c:q]hS/#ݎTvTx8EjCnɱ~ПSn2xY~}}׋qc=K>]TM/{DW|ꩿ&֥#u# _ڠ,Y_~d5EY~ а-V7}U:_6u9:9GQ%Љ`Ba"! !]g cW_{W?mjbپ} vD=XK`"]\v`8IF55tD KAtS4p07R> A ;v5Ԅl﨣E#q8/Eb_t:[dEFPbE:Gmx+{=:WPOڢBFfBc9NVqۀ<·b}*6r;3@<z] kO ˱cJᙠY" $z|h e˖rqAa"]/vLrE  fq?/H{Qeѣv8=7>LstC!p8Ŀ Ê3#4ywYl\RL,(I?Lǁ:HT ;No]+\oiuvQȱ4d es@;y3KJC`G!p8C!8th]A6T:EX]WE7r}&h_IN$w-Uq{]hWNobӡ(\޽'"ً]I]M܈${G|/x597c\@IJǥu8C!p8:X`s=v(w&hL K~8lh .b~qh7;ZrP\ڥ._p]igC!p8C!(!4v%}&h⤋uliH?YiEyXڮc!ngX -Ͱ0{L _|l?v;4 ~8a4 *zX[>AD2AT4K= QLY@* 6!B$ qB($)Bd YA; AP<eAPTBU&tAF  /B !PG#,N/D"FD!{aK,b D$R)TG"m{Xd2YC!Y2 P2(-凊Ae*PMsjMBКhs:A/o/tO ÆǨa0PL*8sӋyǬaXNVk`˱wcX:vGq&Ha\)׃-6xQ&OƟ7Ot&L'hLBO"|'BD =1xXFB$1P$ <N2422L0|'Hb$=^IR3>iHee4ggڵڳ:::tfuu}tt ][ԗտ@ aa(hĘbl\a=HkcNlΫZGC 96['?Q|~iqN((;s2)S5ȂB¦"rQJiy?J *=C8f̪\|"eA*ܪjg>ruimGX]i=>~a \/l7F6694=hVknni9Պhop%K]m2m._W|}u嵾E۫nPou@]]nZqKVmەwX!dMݻ|/|n_<0o?ڃ4n>R9:X'*Ontw,+!vw'VNn` )Ei2%R3\e r%sZv_PXDy M -J*.i3l~5!7";b:cbntG |ǧU=> %Ň ?|"8my9 Wү&hMONθ72 7Kbb>Y&~Ҽ v|8ٲm? r qtEQ ht3F3݇N $hf-2*JZ{ZktJtO08aX`tƸʤٴŲf5gpӠ+uWپYo!o BVPdpUpF8-5XTGb,ρD$䒔}ά<ܙ5rSű/8~ĭN-"aP+v( ->S]v^HD\5~vtx.nnm^jt Uk%ڥnvwv޴v!NaOݾ{=Pwx3P8xihc ƺ}:kfZqm썹y ߖt?nYs j7u~15g@ ! (MQxF!QZ ]!b0o.8g#Db!y"S(6sY|bCyOMaN%3_BrUr+s? EO%)#T+l$ +*#L,^]-")E%!#$J@J'?pTLAiTX]_uAM=^CCQsUk|O]'=i}Aa1;63SsVyk\ulmv+o`\RZV^G~oyр `carVtvL]쭸 'RRoO?w0Pdfa,l#9zG5)K?!~RJ~]Q%JY)gЪʯ^VΥ>yz#oKܗn\A^uvxÿAͬ=^˾'=&?5;O}b9k1 @)\py S%Cv$xL@ _+@dC"HGd9r%:E3mq4bNK8<.ׇ kD^b.q!ɘ(XDecS˔`"5%;k2`gfoPtĕMny B5BZBEEzD}b-4@k('% d؛˦ʽTpVdVQ*TvRTyڢ1٢BS{BL]OoI1ɢٸ )E_6,vŎ.ܮnWNYhY◈O_YXH5ud{l@ː h!鎬AQD}4탾g{1Wx.[TBaEc`#n13v1i2Y0ّ% `вp(BC,D\P|V*+V򐔀Ԁt 9[rEK*e_ߪj!ښ̚Z={JuTuzmG Md9LP&V̿XYnYclm-<]nθ#JxX{yU{1 ಐa#Q)+qf ]IeLiYF?Wc'NvΟN*VwUU:\Xl( lbb׶k;:oR=ۓK7|?G O`610B« 7w?M;^޻ht/.+W}qwۺІݯg7_f#퓡eD\I@C9w0ژ{XK. Wt KǘdLb 7SҨ, p'^psvp>s7/[QBHWX]DETYLI\f(-)!&(ɑU+ijkQOD ^ÏT S_\V'Q6vfnNG\\Ϲ;1}n?o_0|ʫ'1E F)D7݈7Mx䑼(;$ٝe=v5bœO. <<Quxt-|E#wSmPk%Ͷ+.WG\va\?7x>(2T4xd l3/S_|4mlJmZt2+Ec ŧKe>}TlՕV_'=ڏkkQks?>\W]`Hݠ2wMͩ-խ[sǶ'ߵ\n\~.ͺz8ـJo?fRvQnbޥ|^ pHYs   IDATx`TEǿ[{!!; (x`?zr;=;gQ(^BHB ovfSv R~/y3}oft. UUUt:}1HB@! B@! o;z_EFFnБt:_i}|_^! B@!  F㯴,l6^Nz ! hM=å~k0L[Y~cݫN/Fּ RB@kÃ>85eX,ʕ+Hllf_^^]vmcFUV2c(_Rr"bɈ`ؽ{7U@S\z* II*`T={]KB@"nݺ)jFx^8A#**JFr[*RB@!p06v=VS[SRR/ܲN]paF~Yҥ """efggiCKJ$ǩM#'פ-! B _5߿p{SBxx8aaa;P~#@ZYسx*ۉJӴ*- peQ_`ڴiXQG@\N T&g+ z#\(sIB@"˼,vVDqz8(bVm۶Ul~rjl0[l0x0as;H_)wo`K} B@7S9n(W "ȍ[nő#G0h P-Q|^ȭρZ`/#y\&_qP_}Ū6yyA$$$~\O`0f.l2qer@e ! hmU6)c#2^X=}?aAy5ذcX{kӻv1ɧpnr־OP7]N^v8p`іOqЄ.P ! h7L:tFR]6Vg8Nk,cܨ=|p,_\5|B*@|,BI9I}^s},0P2Y22NOr3nT] jUOv{k\gsӝS !  Tl(h#W@< [`hZݍuTC ~״Ctl4f3^=ǗS ]HZ7IB@! |{F5oҰt\ȜT48i 5 laVs.>pZί-i P|i-Zyi洚P'MS;c+B@! ~OEsk\sq8%`kWBZÁ~_UY Km0Sh4TX˅ a<ݹ%.܅.ØF'SxB@!p`M̞ ]M7}s[ݡ2U~\1MTsoqߴ&v+k<2~ji B@c@\tb\VS?oe 6Rp$ F'ǏEU6 Ow:LGpL?>E} M*7sUc(-Z +biDD̲)B% ^&hڹ25pEXG4 KXh6>zZ6r{F^7N7Jm;i+M[t AS!cw :UP}k˖B@!@<>77'L<=O ]rܗ ;;[MD59[5m( ehnO4bL(4P/8Bo>6 lXQ=.B@! %z47ᢩ~ }jZ;H;jl STUe8R8D; _Ķmft"wXKC B@$%%BM>>>;^c%Y['&&j,4[=  l8` %hA_?zkO[&>=F-E7 kVf1M^Z,9heP2ْllz@Cc\&[V+_%^! @kXl?^u ,駟'ily 4ހopXiZ@"3 z6S/$2zM7Hfm! B/9ac"^+ozn4uU'%sXsTUbٝ[9Lvg_XXx]vM.-,z8p7'A ! 8 `5YFH;h]m ' X4|M! G;k_4&p` 5k {R׎{̆U℀B@hjԒ$B@!p"hH7UkeiLB@! B@!p<h EۺƮC ! B@! 8 ,\&B@! B@Mi.I ! B@! ,8foTL! B@! @@˱B@! B@~.(,,l< G6mS& î]pXV5"sBZZ틶m۞ԸxiBZ3fKSB@! '23qZ#DDD 445WfYYYkbw=zQPP+_ |uS¨dgdB622(|bd߸q#oߎrFDGG9E;bСʐrb\}W_"+ vnW+")B@! H`֭HOOWz&`&x֞}ibΦ'?pX/&kvڵdj5"%N(e7(X ךa̙KZ.-b=:nݺ)00G~0ؓf)sU1dȐf왃`̕+L6+,! B@k8ZKg];En$i e5lذ&*XaIkUނg`vZY+g:-xE,؝WvvMkU$ΝRG@F`qԈ2p:iكkת jhi9|3L>={ h ZwacT߿r2z ! B@@NwDOjvpCT"`c'BvNZcfbVeeoی0̦*ӹXV]9Ca9׹sVu|&Kyr1-n첞Z5BO3Tz8 7{tA…  &!ʼnū¨+Ejj߶m֭[uYKzB} -16H>|X |MسBڽ{wicUhZyB@! BN#$|! .C %1 Ej,Zر^(B|t4i CXCPox|Ԣƹ54V~ӪТ,`>#I9ؚ a} Ha{t9 F9KMIUeqk.ۖf_Uy[lQVE")) .-B(=ebdn؈rd^'x~v̙'|AD=],埍U۷4-o=! B@ߍ558LVz?w8X ?]S+zuNyrX-^>[r Go6Ww|kzj{G/,(ݗ3D"ƭ' ۻw/x6 5"S,Kʍ s"*IzJ pLS*`WeؒϱXg1|ǏǸqTK?3b%Ǚ3$hPYY'XNB@! 8. cZACRo08;60F#_vJ*ƚJ3BtH]9()ӣw 'XjIvra,t5@k50Cgl@Ҏi$g/^آg]x B@! B@4fkߞBڐt݃.djeqh98X`2I+Vn"u7j16Y8 C)7Gћ"ѭ{7u}k tcEBZ^Վ=P`HtY}i:G2aۭҾn;zq+ >_#x; T6hAG>!Ί6p(#lm8B"mr D& ,==p׌'ښ <6E̛?15m[v?d-B@! @;.!NmC:A <MS7*:5@5;ӖzwHwum.tHe $D5jS[5VV4>rּ`ՄvaZ"u`ˈp;p^}ԫA0@n-fϞI&p/9f T*9CAt@n{csbhN-. PzQ1d"|͚g~`Cg,kI^^cӄӒ! B@"#k7 NlQ'qbφMȢ[ Q+ukMq_ m}-m->ǵth1lqwK_ZսV~s+q &NeMX>'j$W AN)4B)2e[SsZ@lxX8y8fRK,ht n neAe4s /dDHQ.wޭ[<%rgl,\4XQ_VTJ2x=ǚG87ބ$%Ÿf=pEPLaK81{E&x!K$k! B@! ;HPoUmD-Oz8Qli"(>ײ{JQ5mŵ:ڧua|07+6 $7PHF;^ .~K7hL͡kZg#ؗ! PgO7tc8\ǒg8 ޽{մ}]vE4[W" ׳j9ÈPq0i0 3!:\a)/e Ǻ݅Rk7cOk^bw!ٰ6{hM{q B@! B@R5^Mlw ? tW[pT2~`!b,Rs"1֪Յ EHyjï~4b 6Z/WAlL,DxR޽ґ+ Os>Қsw; :ͬ ;vZ_2{#\w܉SOE\\lF7 [+b =4 T}谊'+{[5@3SXXh/ ma!P뢹u]5 < ZeG! B@ GP0D X忒.H}zn۪3o<\p-TN; 3gT]xP봇b~^QjF:P#XB+elcPh A-CY> ؚy8h6B@! 8 Wnn A5ǻ=͟ѫ[՘Gg8ǷNt3AV7#q Ayt W"A{9NբE{.;;jz5Ȁl7t#9Z\3 "ƍ|Op_ MհS|[-vL|Z)!tdوv+ZZKJJ֦`f9/?F~W^kIQ!q@Sm9a|>4!<3k.5טj\}8--^[}9HB@! qE5#{a ãӸhu>.lXHՅ]yŒݪ97x5\vYV\M՝xUb4ff)0>`oHOMPf3Kb:2R)Ks[lgf2O~$! B@! NQLZ+k5 *^|ŨFkqcu.7OKA0a„*Ex]k|O պ5u"?_! B@!ZB@! B@0r+! B@! B&Ф9^{?䣪U?~Vi*Rm&ά-&kNkS\UUU4$B@! '.۰-cȫ,YH9eff6`Ɗw}L7L+K.]S֊ձo`SpǣQ` }ۀG%¦0 {"p Z_Wjf6<{DL>Ɉ)su}q*|m ,s㖾q/YB@! h6{>>3Κz50fl._z:<x٘4.iS!6w"xŜME(oDwÅȼ'Maw)}1͓oj;d*t#^zxB,(&k1u $ =J޷jOc;\ҋ!\ IS-0Ӝ1f5 b[Xjr;Kc֚Nxb*XFMiAnq]Ki/Ďo> ŏO>A;d9KaZ^Y2},>B{SF]]al0EVOgAE! B@!\FB\9Hw</F鹰vF;'c[g@`GOCoCҝq)w&`ח_(;vsf\~RtXkos0c!Su7|0e 'lϘ;~|{|6@Rx|%TE+wwOӝױUONՂ |wohz>fs,N V3[stKhtBҝ0僕`gySx|X;h~ %4a,EX9Wrg)S>ÞR7@x?j0+})OLlZΟݬfܫYy旄w{_k{*j1۳?W8RFmpmN˛s?C9Acy8Uߌ__ +(MM/?ܮʸsSOF<{i}y'\! B@! B}Z-ώ_c+O_.B͎mBnH yr fgSf #{ɦ' & osUabSpr+S I@~5}{xJ C~YX| ³גyvG6YO_]B]rK<_TVPm_OnO)]TXu[5\JEbyOqT7.=7P̵0qe3y6;b,3rm>"*5pT "yc6Du=g{4rUeU5۵ d}w=r=^4b, D=LWG,?vsAر:—L;aIIj)C1s\ۗ%1 +n8??~Z}sUl7lAnz`{Yy,:N]^z T`7;0o5U"4hM`q}Ϡ;`ΜEXJiy8˦Gߋ_}7\?33z,=.U@o@7],B1m ◟j=#¹7zMH4wQ{ n,Zedgx(ZQizbalV="-Ss B&@n,rbWkV9l0DGv4 > L~"2DGN~(GAmQC.=ƖU} ̊CF;('EF<,SZ>$B@! h2_t?z􏚚IIXl<V{~6XS>eۼ[sPibE >Ǧ*9}\uTQXH78' ݇_|}. 'L%?{ K&ujՍ%^X;ӆJ=zuv6Cj r݈qmg`$(\jI0ڭVo |DnzcР8q߰dUJOFjj]pk:pRg(!.B;Ya쪡R7… Uxу(v~pß W ;.|/n)'' j7R2RM?b ͠qE;x  nE;}+['_t;}![xJ_Wu؟Fqi'S?̽WW_Eݏcw٬upV3Qݔ7ߘ 'Y@p,r{^%'v6щa Ćc۽oihKz&4X1un o>5θHD+?Uzj:ëĄVz f$EqC:27~=ƭ= /9μ =6 >dQ9lbܦ4dw!1vl< 2b,c@= B@! @08^R:օ7?Tjȫ waF5 }v &91Я:ia -t4x\xZ{@z U&TxrKHxOVєo]yQ &b1nh;bS|lgdLuG?FMf;cI۽{ %6FXV.B#;g#,'pPNM11,p`tUdC1x;=atQit+#b(=ЇL aګն>$Fg*ʫ2!:*6H %4@Z( -Lȷ.Tp0e!xv):CT˩κP?M!XU >Be%e_Sy.?Dl.1ᔵv!C# A],3r| بF'*+OV ,*t4^AUI FFʤ=L'T,:v@jrH9 ѱ0UZi>O(]'1=ccirbCd,~?sѳWeEuDuPvN,lv")M EP]I*! B@!p0G!J\A.i"]h|X>rzקȔ֤Ȥy$j7eѩ~k%CKF` }ոF:B>Rˋ !mRIሏ5v5u]g gu%]o8i*Lʱa$E4K獈i扅Hz־PMT1nv^~tLY'Rk.Z9곫ӑ'rη۷NO瓖79^G2.%[ï%ŷozN|b=4#CkR#B2']p`̛Ńw8ow|޵itn]Խs X󳠞Kos}ćvߛƞc{_9?ޑg-B@! B@Qr1i??3Yšd45Ѭ;h!!WOkSjryiǺE4;ZXU>%Khm»]d 88a&{ JwB@! B (8dqZ^\! B@! IN@k<1 ! B@! 8 UꄀB@! B@B@! B@ prB@! B@! NjB׆1㗝8Pp䤆q<]KOå{apRV `ٱxVzL90@=BBHQ> g"B@! 8薯zk: 4)mڨ9Ճxقuag'1& Sz1=$-@tpa!~۸ w^< :%@RH5;Kazg`@bb*h*25: 7\:(@_sǍGߕ0CtUB@! `ڇ`\]vyzB@ |~KHIN :Ӭ%k͒uAۃN+ FpQ1ށnݴ%Pe,J$]OpÊ G('t j~#}%pAw0D!`ldۋK/5#^_KCnD! `1s wF:ͷ~7bbk<VWB@ :aA ʍ ~GcidUp3FDТ+C '@W O.WKʑ4vBw-Qxk0.+}6Yt(\ } _S/qh""^ovV HH)_@۷Nm>X ARM:ě1DL17^bemބԡY P{%>ܠ5[SWFz! qڦWD|d[16e)[ob#B@!R_ ZZ7}(:n&-!o%&>E#:NwFŞpލ/)1zdpvrj SLo܋GHS;! @s /T,l}?g:}MYLq(8Rxs~U;g-w?rjw"{"9V]Mm_PP@/Ed[=iFlٲEx.Aא>ZZu[ $?pϓ A! ZGRzuk*?__1ENB\ {MdLBEE%3E(pSeA>}IJl!-#`O'q8w<8?&EwDp^% Q36(?Rꃨt%"gS.zFlRJgDU'xgf7Z-V">.>ol6-N'79&gЅR?-zn'u$- x !n/@w?:׽A}oo w^}ۀGo݅nRWH$Q@f|̽{% ѯ8t u~۸6nPZ jQ8< ?KMS \^|c2 بr6U'3( m{S'QKӖbD윾=q~d-׍Ni3^id~\FQ}OO#RpØvld*:&{uN Wq7ұkt78< ;0 nmCqp.39-vReg#\1*ד'¹K;k,>#Meme֥!^78tY+$1)Э{<%KOgԶi*͂ ٷmێ .)Hs?8={VƎ;G0x36cl6-Nt/p z9%>ȇ~wS#lՠ]z%^.|d0  :v{ァ=y?|o≩S}cI]Oe@d#*Mx{W'NvmۋmQQ*Fw^jDxLPP UGlkrՌFrr+a;w(ǙgƄ cisfm̴KosP0ҢK4l۝N+jUFȾB@nQ\}:̵ݹ }Ϻ΢poU#%y`]_` yd΁y,Xubt=e}4tNmo་y> ~hϿ_aaa$lkD֣2#Gb:t( nݺ =g}y~ݯ -5qiwmD殽޻7َg{qѻ}!}5NVO=7^/7 3ϠК1'w@ <;D|Ck׮mHJJsܹwVa6jV/?3>U~9~x'j;d5jjgKnW/~wTq^x!,XH'cE׮]зou9c:ڵk?&M xm|"rFD-lc}ظ7b2p7 z;O~;vATDŽ??u;#-SA! FY`./2/|=J.ǡ׬MJr?tÆϣПܤIs^W=Y/~o>Vi~VwxW--6|0e&{Ho>B&ny tG|B@!_-Eqo(o;l~|V^Ɋ66C#)1 >d%c:ۨY3TqF^o6|-TT{0i꽊x?~}&Ci 1ќwF˺9@p%;iqeyz - 7*r˭xW&99@*%.Gh9; W|#=&]4 ,LV~kzQT\ŋ΍pv5נ<:,LZ_jXWt7oƵd@Ѡ=c|qƪ׬ABYYY8aHLm=ST㮻7pJ܁.w[;v ަFCn(fZ/W\#GP?ms'N_]B} (e.MO2pX0Z&һ!#=һ^{/A]IS5ώ݂LEx>!9C$ղaޙWE-X Vt'>Rcy%5oA 5qxU݉ev%;u@sJ)_ZiwׅG,ؑ[PlVe*S`|~ Stt<ЍV_M|甫g4L?$S+W,GFF:/_$SO=U}f*[qqw`Yj?,yjgqxa:ٳg%KK/gqntérJO3.=M/: ʻ \gyڿӨu@4b=Y Av6V }}qȷG%s*{=6,;̛a//hf9v dHu0!,e0ULJHBuz5;+,9Ֆkwd_5aX{^dB|tjX($wɿñ,PsxLz6BIN";B@!"|}ήwᛧ '$UkinؔFJ,rӭxwV~4nM;wo|Bi4Cfۿ<$wJ8,Nlj;{2p>3mS2lzYMdhh? 7V׮}@YW]ueוJ  K6lP C N;z~`ƏƏ˯l!n>T[{LhiuһW_}ƌj xX|'!]3dݺ6ec=ro`O˗!::SOq6ڭ;#ګ_j+.|)8OKST bйwn~Νp3:Q]uz/Bՙ`^`|~ɩ*9sFGMk74={?nes!dnk5\OﺚM-fݍ3%tJwN*‍Z8ReSc(bb4`=/J-]|De<-?#k,6"%o W5hǵuN BHWذa_9r &s I_7y:_-Pf}sf!DO:S? 懔|<)ddtG駞Rp2{0nXߢ^ _p`W~Rk:Ζ .f%CeIMSk8 ' 'J/$}dYjgÔ$l.k^u8'y7zXc *3ғˑn;-й|fz^otmщg_Yev|+n!G~ ʭ־SB?e? FÁأOJs-ϕW^Żްw^ 4Hw # Л<`Μ9NGݑ z7Pc}ϝm^q*{qn>(2*Rˢ4 878h,*e`"6 F7v&`A{ zzmѨ1H1HH(Ц2̜?o}80>_[m]Z7^.9{(F77o^>}˒dܨ +uݼZ;Z.֌dJg?OM%9X292֭#J{QaV/n"w٩E|ȴδ5k֔7055^w]q Ue4̵zWI/6a~toIߴ,G {4̲`O9G0>޼VA9,xa,Q,Sa_r}yejCoiϖ F4&Jrj.){\fK<cqT3/~瞓xtt-^P_-Owk>2}:ܓ?$Q~#'/~{ؚ==e`Z9H'LNCe5p J+ȿ}A<)Q̛ӟ;eɾB|ru@@aK_9AYww3CWn*ο>ϖ;/NL+Ϛy#mό?rӭ?}wn.rCN>|x^7nܘ:,/Un"WN ~A]Ϟm.M".:(Om@~wq٭ǷΨ|I<0>;W7u|L'/8̧$ cC;ށ|>k{c0 pcʤ]yG_W"_/s rշ<`̋L9\o~7.-~ʓ^_~yg8pMfŲx0N5슳Ö#vZOXZ-!`P]YAgq{x#XFCGZ{`Mn/eݵ3B?0XUqFIG,,G. qFtg*{8;Ӹyޠ"5SȏĞ pZP#Z< %_*ߦq԰^p2b}C87ps/3E]D_2ͧitq }l >b$u2+1 (lT=yw:B=}eC=ܾQvl)S2loi=/l*+Lܰ׏.ǽr.,S㥵Y2ײfN6^wֲg4Iꆿr)erQ٥ IDAT\&6|LYs¡)cFkDWm/>ral^q/~N$@M䲿lfSӖ3DRNRsЄv3t%Е@W] aK:i:Ѳ`.w{vm募LKs޴aSQ8翀Sa|Wбɲgtft:u 8Gg19=% zbm7ߚMMr:"GgΝGۯ[gs/WXӧu;NHL>GuOk}d/7oyʿwW.B֍Ĩ`gߩWW#/aqo[}o`[6o*w _:yv|S ^";:3]WNF/@@ͣNu\ >9?y3kyýȞz~`! JgKz;^z<?&tH8#^~+|S?oC;_֬@!/,7ozSl` '~;SYNOo%@/o/:6pfXwSr~|Q3jG2Z^#ou;oer+>둇/~c3,΢07'+۾Y}etKB7}W] t%ЕJ`}pZfqoelv5epg<#/'ޖ̎әF;ҺKvi>xagS;G;+~ Oi0Ӹawx9qf!>rH]z>%|w?nqfsf_:0cm_{,pw}xo8_X@O;8׿ @?9KQ:i9uͬmO~| mwwwj7;cC" \x;߁>?_=傷-~ 2yþgn Iyw{˷g=gZO~G^dH 2{g ;oԫ2AwFy 7%wCw[,k?[ˎðw|?9%3M)Kq ;)7\}AYu+J$0A1'?2cڻ$YGPYN:|\u8<\^r5)l{uy%ﳞ=ݗP>._jsA?Osi|( =1O>7*= O;k/yJE7g0=>kH-w~$p#=tq.p)cƷ%gh':{= '=߻FMS#G7m-κc SN-_(w0Mp7Zʶ^FgsW+\|KeetѲkDG'˒Cf~ s/?;i߻N}DFXlťlpaf^5`F(1%+X7ܙ7e[ b% p8枇8c&>xK m++=wt%Е@W] $0!^f&qɉiI廻'gʞٝIV k>?ep?淔-= 33x]7{_'T{ԃ?~_x^+b/(WGGW?Hu=tc[=3ɗ.'>wνh_臗%c ގ!ѽwCnXw}ғSO9l(_og<4>}t|z˂r҂ҷMKYpY?4P3ToͶr^YFp˥YfXГNHMwPҶ%+򩿣,Ԏkeo!G<`5qDǂ]G3?(ٻJ+J`{400ƭcǽ\O7֡SrO(߹[e"n,O`ڵo'7i9uXh{es?6jfmڲ F@M?Ĝ;؞^GпTn}#: ںGW?8>vIgO|=ӿ}ңiz=/l. ~h44q~_Qf'&7˦3fǰ}@\*3ӭu *h;=e^}ņv3%O:d֬#u[~e\V?GF?G~DY'EwԶr(zǯuy3{ r)=4 \k{E7g.+JI`648XN[i~ ,sG?S.X{Oopi:<<t$8?^-|͏sua >V5, /\_n~qIA7yG?}sW@;pgGz_ -:so9rq̍۽J+&S_ڲo^g\ډ0FW`|KN/-~oro+rA#ȃO,o7ٕ{'?Xf7sLyKa2I6|-}#͛ r/.K>nО N<3AsE,p\ID d`)/-KhvJ+OϿ7jÙfNYGu}R@'NsT^hX}Mv#_tܧn_K˹g ;A\NقfPQs{0n®J-l?qyhxx9jBFeɻ(e!G^<ɺ&K/ &R?.~y^SWs|wvx,<s|9Zp͘N;2*2{v7@Mv(뿳O )=A>ʊ+حyz si5q0Ъڀg ۩tte~粓{J+z?w嗾,{t}wovngΥ7I'X/΄dc~[qk NVprw;aΛ+ػx㞸O(={{}#׾ En񛮸/ vKI R.=|Z]s S!0kxٱsG>yԢu?g:#2tJ+&x'D] ٕ@W] t%Е@W] t%Е@W] GIchJG&_] t%Е@W] t%Е@W] t%Е@WwJ >ϽI+p |//yVéMzCY oNϘrFp']Oo_v_9L%OǍBSuf!V{zwfj!Vc& XC(s<5}ܡtn&yZ{S5QrUVg~Cs_X1?I{2_kRV-. _%R9Bar27Y"'n3a>{-Wvud-"2]ݥʯͽh1;ݖ=|^!ߒ0GFb'-AN_Ηm/yhL֖;p=oooh!͔#xBRMמ ˳1˴Wd<{T-2Mթ/u[yi , alX{FS^zh:tMF=H>YnBbQ.~zV.ݵn $v~ioRWԧ$ɑ-}ךfñ;9{+ˆ>GVtG]Pd'亮>WFO1-zy;##n7ŕeKZeo| 'l/i[Df&y,8i-%H͐sFDM,d;?&4S}! >ײᙴY6_i< [WOe3\[ Z@)Zd+: M|c^ʡ"iAO,ΑEH&ϔ:XZʉwʥeϖl^.t=5ܢ.Df("v`Sp-&uB^n:Q2Qv:iS[FLhM=-2K2[eӧ8޶šAss}YgNVh5?epul?:Y}̪8N~lꖘ8PQqAxRH`}쁯QF7 4 uS SǕQt1TV#U,z ^A.[^Z|j=+,S4)pʪ Im+롑*w˲od_ieKхROzKٰ7̬-R6j}K o`P΍YE HX!:ފ AƒBtrS0W]fvO4J4_g*Bm!mk(oҿhu^#pMb!Ϭe[-TrBkLGaCVDN7iB#>kOC:鵉'O6\ܳ-ñݣ+B hcPIya+B& az٨JahTC#`{ $~=x^i(jjg#&ZMUɜ˽F|4tڦ&N^A3H%u8Nlmt Xhlix5,Ct1MN6v1 tH)ܛ?Fl4Iyi1(XU$*}+tُGH6xz\,6yt';9D^)O+Co 1mX:+kչ0E5^7@DF]ڠEI^uR*76od8 b }v,ң>]QK+孌Fkb6x^B."O 5 gty2M=mAܰ#mQ.t">դcќ zDj/}΍e_zUYԋzh 4RFVum]ƦCylG8y>roS_owv=]Aȴ+ڏ@{t%##T]6T-+NXUqކgVt*SoۘH^Fy [um zK'Oc!iC_GuD1Y2SmpO:gT:Ϲ4O4a!:Ὅl \x,A$#MLFG#|`+ 878jh7xCBgl9Yd}!tQ='i c;t5ȬEY; kش4ɨs*< GCrq[ZtX Y 2SDK> IDATlH"-H ;tlԸ L HLx!:vy/<8-Wu"H/>;00LSV'4Ң`mγ%8xLB)UO] Iw@"KEt].q~9y^92smί2u' =T([#*3O+΅e56*2Lc/! ::r _;OiQpPՙ.Xx 2d9r I_{2d;p۩ֶ$qLk~=qĻ:i(Gql8 νgF-O鸐;-Cu6t@;(w K~D'꫶21pgsFM:cm]L :Տ.:csxN3|̲!\QdW!#Հ!hC΀OIN'#֡~^h@:X*KV#{[Ytt#@g8yCӝ:tG,['9Xՙ^Yx)KŖ*}cvC]Ө#:.8B3u4/(CƳܕ•H>oG0m:>R@#ʻSV^#;Nk#3윌 Y$=9BHPJ0J,8jt潺OzL-SeO9$f7¶nXOUmxrs*SӲv:;ی+[e)ea?#r=с>AcY6pF@''19u2T֭2gYLm܌OݱQLzg8q;i6h[vV{be_'[kk[UB`'nL8 0?/s rhӭ.+HQ#'xuυk owB6<^n)>!p]8:txS,\dX[$u0smnjC2BҜ{ $f Fm9PVZr hh]dS>ZvPUF3a78rIP'cPctl<2zA١"yoU_2 ]L$C"oeo3<8ѩ=gYzB&pvt:MWեB/ gWl-wGh\!! I!/%%#ҦSmH٩㠌%X)p;5WcP΀#R5-/߃ c:c,N&P6E:Ъ,HpJt[cKw꡺@^5hpR=ias;eq"[ Oڀ>ZpDZf _1s(SfMޝB\a  ĨF2$m fh^+;203:,eѹh#!0 =eh 5y[eoFЕ>3bp!3B,[Z@2Ȩ:˲O!ч|S[#:tYY?4@J)H f`sӢS3e[q|svO4Df(`V ?|ݔMi3r! p [G@?k+gVFi4ZO%@ vxgK~L.W~yXLiw´k,DĪZ+Vy2ch`^F. 苼bb| #) נIutG\A2.,|{ B0+u6e?""_gNڝ6Rye,+,;6Ҿ3"?Ygg끶Nd_ˊ'ml ȂNpP+uMG"#Nfx=}.fQh}S]]vӈ47ҙKޫT_T~ 3] ܿԈ* u NB۸P1I&' g3tj\71fi~&@ՊfWAj1:o%E; 2>S@͝7ZCbŦӐ4aϤOyHԽz6gaȏ4iwB,8B :m;2^h9i:t˜zp( Qڲi)$< QkVT# 01*}5oxi 2J:(sL\Y#: v~:mRNybzqȨ# Xڀq:SYz~e7DzGCfR WF9uaaCN^3A\B}-/)yrM74"iuJ0<8w!Io4ZNי.Gra ]HI,|Ntd! (m& 2}fY.qȳIRI@%1ڃZ/F-Pšz Gr.+)ڨ8Z8Vç@:-[̀eaL:?:8k=edUHA2;48ägvvnԌ ˒CeӭÏA&69tp;)ey%yXFВ= țuAYYΡgZSSȫNޙG=&nL8Eu.R ',H#hpT %7ݶaGu& { Ttt Yyw/Z0$ºfTNS :K5boGԡkg 9| e?{k< L.Lx]# ;B*@2ĠUx1, QǢ>uo}w3r& T~K%e.`u@:etYQHXJYp摣+a$Vq ,zۘeeݱn8kA$ebZl =`JV:Zu 6V\pAm2ִ]Jfp x63L:3SlIZZR/>.Q~{h<6aKG332˃Q>K6!{9s.`$) 3z$4 iKn)e-/Q#m֦XWx` ]N"<`J_8ȫ.qյJhާ쀥7uhM 9Zs)e Jn,CDOyJ@f|+wĈQARhԞTtj 5)iHbÀQ4G_4* FýR ?1=_1$3)T36N[;Fɴ\y1"= 4ᄄyU## S|1bxxPɪVf _h4yύl!]>FA=$Q彼\I{c=B)&D8˯}\]##ͣD[ѦMTAѱMD]Z!\Icʹxɻ#YeIxB3KBV-_nO-Ceg2WyYY ~O[[l;ӡ%BRFg 'ˀ;#nQ; .:V]qA*:/g#gOG,*Ug,;Լg8rdÛƩ=ZWO~%yp[t YUvl:m62kݰ k`d7O >b wgci8L@}[bi#zΞ@jGXUv 6(KǛ#1r9eੰ:'u/N:y`Fn9gzu[WB[ /坍Lgh41%_ZܰfOFٙ0:wDv (TҞY710妣*=U`=:u21ȅM[R/RXLt-^g`q>y,uĩ% > Wڰk!L׾ .f6Cɋ6=Q'O',gBt:TϦnⶾVH&@RlP@daRɣ^H>@ TͺMk;&[6I#j$KxQH='e IRuJay'姞䧬SY -LE+Al;C[Wl,^>4Fi<7QZfFμL+"eF+nɫ/ A'\M)Cc>ol57tI;g:kQ<8 ^-ț[h\rD_o䕶WIA24?H2,<vmr-!G9m0?ei8oB uZcc@Һ)#tg\ Vx28Wv5kKRtM:iyq(0!_ Ny=Yn.GQ JIg^#o/<[?yH}]*xHg^&jgpҝQ$y1h' #=v ֙A8Tlxs@zne:QQcMtpIlo[G2z%z1rU 1NaݾQ);[vbɧG*cd qˌKwnckDv$UST)#E _^Y6薳0ffݩ\\L)x.jg#~tA~n:H:gt>6ة>Ig43uk ߑ\|+ko3"okG #`(ttũ{@9:g%ovmGxWeMZce L mJN<:͉I4t2}] ];gKGWݟβzN= JGCأlgDr^ʡ SˑԿ8: `Kux8;ȯu&r;DŠ_gL]ƤėMY}i'dYGNN}'=ʗeY'-xm-t|a 8c&eDk[p7 蒳p:bMd2Dβ}u:b.}̅SeebQ V*mU\YO.izĢKFt-k`0NmK20 G)/E)T=@&uPWba c`*Ĩ $]<_2Aښ8lϮ_O>A=eΰ3`42e'i:┓WgHS$K7 ^eAڌ蓀za=3+?HR9(ApBc]z`YK@n08C0->@t)G鵓~ޟ ՌҔ0O lD\t-KP>:9tMn=W_g*Im}IBff"u2G{;^3?\{ƍe႑~򑷾xƲ`l|k~ M+6Υ^t%p _@KC4yjQi*] _>s Ng`S߲fՖEUqW_(#TD\ #ɽ41gitp{|mHtX&vu:ej!ɗ:4G:0،8:ձ#*0Mkrqng&ÿv ^c)Ve*l~Z=3J]V0J5g 8:NЀY:n`,XR6OSt2t~L:]ngJ4y;Gl灲'N8!rs:7lQ\sv7.$' r::|ǞKx5_ڧG-#>Β ?و3:^3T6py#Ot>#$w t8 #M','yX9kh钲psc:+Ԭ틣nM߇㟢V=m_l&g7wi1%%2MrQ$f`530;e:KBnkY!> Lt[0^ Ͱ؏"_L r(KG!)Ld53ki?m; bVޞ͏" ^J'mԘ3NwO({E b fo]O@tӺ7g,S噠ہ_>q m. \LpHSvfѡ]\@Gl0u HRR_9{!R<P, `% gZhjۥZ]:rrC`#Ljh;ܳl4Iv,{Z;5@J޴ iМ~n$v@6҂<VoGsy?T~?ʤaiǯ-v)t6S!J}βa 1LW}YSN9nmLܕIছn*ԧ>lPu'ԩVt(nc)u"uhr50g.kx>WQO!NޤAw _O}TC3̦LK3aF<Ҝ6t;"1#MpgFiO;a0186}~'v4nϑJ`Axzͳ=Vyˮ_e9>eL}IsSI u?q^1v1ڔ~h4aN _P䈌촊7Y"#Ase}%\')| Hp GdHs>Й|KbP^EajvNHdiLyɽzDyP{BhUaۀ#E#fpŲq:HțrM{8Z^7Β<3{gґj]SWȂ̄Wu?n:Ϥ>~t$*#dعI9CWFuTY# ts,)?J,[>ٜ }pD|C(槾= %CVuv)$'<ΨVtU;S)|՝ty/e=K os~zkMВC_+eh1ʶz'9eFdd' 3_N2D4]o \;qYשЮ,nX}0Z2zͺR(vś2,Ow-8nZGg)鬚63;oayLˎNYkuT;:'Ff G^erX/ @#t|该lV:K{*~50]cQ&Ef~ Z?kfHG[C&VΙY(>qP>Wh0_`j(gI&,+L甲",ܴ̾*K .e-@::G-2R}Q4 ~(" dD}x#R'A\fu!1%=muֳ^~+c~P=F ,XWu>zD߽,gyA4Uެ0# eA i7$eч0Ϻ8~EVe!(vR{J |Kژj=(?s 𯍍.|Fh ?#qʥ1,Y V)p4ygD+^u9lRs76@u &cW .'8sd;q; єvYJW0FI>ҎU|H_#?ɟ6^}/=cD[%~[ {p-$\O;#Л9:>5$-YIsx[ = +|T>0~inD?c`6Fv~ҧ^=rlC<Wc:+y؇5G렇2C̜l T_؏T ~IE:䋊襃43(K Az/m|d}yɓބ!i˺W' вa&Fi=<ʆ۠\+}zʦ-ʣqR9'l~7 S.}PX'6O?s1XB䠂`HzX!Q{=sK۩w{O%wM#tPh'<*5x YL~WPx"!v^\p3~LO{k9-i<%p[5.nOz1`6`ΆjhXB  Αݜo0:S1ay( -P)kL0t(#ˈ#rl5:9rhy?`G8:?&3#eˬƔj}<˿,G:6Xq$ƃ.4Tv]+sGD^Wg2?'qN\MA "+h^$jύ% T^:kХCdǟ%W4Q## s`puf7ue  :gT۲ ] ;#Y,ZZL :y*ޤW#;^+Ky3ÂZhf:vtؐZjz%eKKu3KG.:Alg;k9L?'S;.ס+YgRNڙP.B]3ȗE̴?*'ILCAiIO(㶝]V(qL)| L8Rۡ p؝>7L_3GڌZᏺ@0t0;0 df'i56`I`A/ 8iAN‹;gʃcFYno;Ng٥-b ~dʓom|џnP. /Jʀ3 2@'{=7= L/])[˪ڥ |'µpV rw}eGr`0:CFݗ8LΩA4NbuF4š3,r 21.eǚ|g2ml)oNx7@<Ju>BeCx4gWb_8duр tc,$% @n Ѭ^`ⴘY:훓:S SgI}nYʼnWN(G<*kf3V"/6MԬ[|P$ FV/-KZLBc:o} VʺeQH ^0: nZ&6l"ƒ.뫛b_Y:k}b@>>(;!N>8⠊-/I哒 F{;:f0MGu0 v? Jc7v&'(!~zbSgwFRwdm꤇itŗ-'d:vhS|R>lp-;$6CRXcaG9zkY+cezzZ' y-6o#xcsWƆ$3BtCs?Wꧺ'#],g 1*3 JI>J/Gz䳅GtֵjBNj=hd. _#i7esb[YO[u]wp6KaL}kd:?jO݁TmKyeYVI?i脃 0>o)gx^9l1e/[e!\>㴧\Q>Gxu7Y`f9W^^\qr[7ܙ*ow|D/.|#%\R~!'pB9 zzrYg~a{>qe@OUrԐ8v^lX>C_V ::蝪Gōi#tu>K\8t9m8a%EBYz4\hi A֦逛Y!iL9ԡ*,u&eDL}[ZpǕw+?GG&$YQiS h$:屇aVeV7c4m@ޒLyGdN"3` ` vDe(ܚL4iX~q0ԗNy*gynrѠ[1,*KaS&2WQ/ (CìYؤZ.ꀴUYNr12 Xg8Je@ʕEd^NGyXADFեQixa׆?di3nq;.6۔%x0_ $hKHY:Ӧ^bq* ,GWtqڎЅQ:;{N:ꈰzb>yudzt*O 8z3}LN8,Lh:γkCCyTxSpI|u=22eHS(OʙI_}ed٢2Cɑ422@xTje@ +u8;#l8'xUC|5pm/,'`@r N1?NmgDXU|+-ܙ;eő7._q&8KSOyl824`'Ln.Ҧ= ꠁxB7EhPwTR7'#W쿺ҧ,ȟuzr-YAcp f1XC.)c -Z< kv%vlje*(! A#!fH3M|`2΀ɯ?XpF /U,meI]ӦS3#u22 EU<4g`!?zQieJaozϑt]48'\ 9 i0%\$\p~m:} Dۦu3|־`Lh+2¯,Hh/N!ؚFJz^83H03epf{m"xԩ304r{3HY'HDXO#}<EOkz^r˦3h_\!67QJb/`viDm-3}m,y(σjY'unI=|Zn[`79'igO4_?#.˺ue]6uGzqǗ|3svyPZvmy^Lzk_[VZ즁#w&˩Zi0FZ9d]&c&o)}Dlqp(hwղ)U:qp"W/%8_[3\ϧ-So;u*Ϥ^ Sǰu<9eF];Lz%Mi#t'uA d99e"l-i7$W3/C+;\#=0i_f&e/̹Gϙ8)SѕNY$^Uslݏ\N/I7 ȂN}@SPz -~&uqé֖-SiS/a8:&Ov[DΌ0YӔ@Ύ(!pT~M7f,R13+vΌ;D‡Z)qyNt#:\2P(a%t_@ul"A zjcJt^儓)ew~6̦ǮN{OY)38S6Pձ [Q&ElA.GbOdfE Ueϻ]WJ]3OҒ2mi^ H(#c^9u=uXOCƵ[6kA9iFY^g'rTg8ޟL?Q',mH%NHsG^3l GAsp ݶl=8l_-3H^YY*L99Nϑ)gh$h/?,(!pσ f! Qnwlie .Ym*NFw\k>G3aP8e0K{[Y<ϯ(6 GS|J|l'-W Dyjhᬥ^AKz?yκ26_<:VWI9/du0m^$)kdYZLoe8d/?uuҶZwmkwu0Be7-sϊBC=cidlYlK5mCM9: ì!6 ^@׳Ń#4&1 Gݻ\wb[[0ke3)8ٗ]ղSOg= Ȩ/i;l)y*'d& E~AaFޭM:4<>3A9*sruw)h.g@d>Ɍ+_J[*wM};.7wlNK#6 gCo $i[MAе@AȒ\̺Ds7mz Q~kޒ[wSYuLq}{߻SLA8}oyK^RV\YsYJg=կ.|o|cy_6nXn׮]O}jyӟ^nZ>O??+' vYN9W28ns ;vHl3ad IDATֻ}qs9n:eZkȑ~gDG,/h_R-aKnz(HO}yts(~ҪsG:fU&@_q]rv G9'}tR>u$I'd #?{YvwUwUuwvahgb2A0i P",!$(䯀`!9 #%1Cxl_vzު[9Ʀ6J/NR`[~s%>/ })aqfG$F͒)63H@Q~@svEඁjm@ v/<^6}kP.݇kSlvM"fKy'{Dt >7d\hdVM/za}qc'v/?uys=;ҕao[韾L/pw~w}cey'Y?̎9}7|ݽw;pG'X^Ooy[|η=d95yMKLMk6}7}S~~zk_;=, l>\\_gF!7L__lXиPˠT"}rT#h'Q#KiImkP(T(s$_I]kL0T(:ޔ8c ak\;2Ռl<%ala4IRv6%FzhĈWIQ<PotчLMgWMKTqïi&nJ4Ԍ剁95gU.?;X6Ų)X\.ɛxBQ"hf]*leZƨygff߰F殞{1,x`7#Φر}OCl_*SDyabp>$ZrE6!N=:eI;8M[{5O_8meCoHCN.2d^F)|T#,S+62cetOC(wFoIOC_=scö- q5j'N;W@zT@m4N]椻q̀$쿰H51zoetԍ7ﱋfm4O ?imD;d\ryU@zѵ0PhP/&^2#)fȧiO>iuҺ N,f[8m:r-}T>  (S>چ?ukJí7us]z y7yLX9:ԡ;S`'8Þr9!ʽ q\4JSET~=\v^H6V ] 0p K:hXA#ʈ+6܂ChLj3eC͂[ב kId@Au+ 2~ӑΪ"-S |^!OueUF;U>_={}Ӟ '~6v/0M 0Cb8O8|.'x7/w@l9mS d@~,5HCoXBxg)7OnGxڇli&\'Hx't ڻq#Og3~Б'@dkmG= }ކO<<pNq6#^*kĠk}l7#f9lgTeUx-2>n ۑ8wiKܑ ۳0i v´\H-MnY9í ЊPv(:Ư<0 imBNky\ؔ/ZŹvGH:'Xb ح|/^Fڴ[*~Mc,M4ぼ4)ca_ͻ`BtFߙc7 ?!o>6}q>ͯO0j~:sL#o}[K#p/?Z#ds= 'xbzl g~gZ--b^|/ǗJ?HH_?7AAzmut2l?p4.?]7_5My#D zXm}^;r+_tJM6c, >x)(,WEḬXַ!$4 >wx+<v~ns>Ripn]dYn&K:YjI+g ȣu,NacAH%??W-Gx LlsY*',sh _::K_|"O9ԣmvϦp>]A`kEGO:l!/Dkj^yi ~NO"R-/ɩEW߶#A:wG}/ <:#DoAn7) `C+~ +૓ \coƯaY#|' NgRęc9etIFTEOJ M7\.)3a= z8{4$ä3S߃6Mi o;c SG;|-_=6py$ ?`t6P6`GF-P9)>a})žez ֔ x|ҫoq~ ˥ ؼ̖h,s۱M $rظi욃Qޑ<ֵލ  eĆ!/7ʀ ï;n:A_1j]yf(1Fy6u xNYҎ.R2qsf)ҳt(m ل\k LR |c+$]svGS!;קs>l\黾@l-Nf1EHwo.\C˿'we?Hwӷ/`<̝WW~={vfxb,Sԟ{/`r7_..W>/DWm'ޣ'eY#s萌(?xJ0**ms⅗ay#2$2QG> G'hI|pXi ypA Cl SB<%L>9|O4nuMb#9@ɣ0i(|KY9l`"6ݑk32sV)G0 \c&#K8&܋h&p:T 5hٗb7+%F&0z ȹ48ڽ=F;6E#Y:,xtGrܻq^am 7uMb@:jCB(xf#H' ڌ$1*Ky=vK#9!3t̋\5T2cTЉS RIu'Z/g>D~ YFaNvsrk'lPkQ 2K^ Jtrth-8pm1Hoӿ[HJ{Vv#OpGPK֍ zPw_jG QkȪGy= NJk>'<\y}ӡ+SoՋ@I؆&A~NgFLXF ^:-vN`{Uh+j]+זah(&W(dͶC6 U2 0x|P>mf$t>tȐ;~]~ ÕlT isYG,r yqгe]o=;6iL56PC%xʧF@S$e+1ﬓ;}+Xd/|,K s_XC,lˆ }R,`NrT܊ ҩ DYq 僊 ȯ:>9jVfjNwfPp6>Mh?mA?w.6wk:e?tM uu77|g;;ߙ?S?/[[x7qz;ꩧ`0ݵ_=ν>L=//La|%^%~W:0H#_8l*M7$UڔƢ2:rrZ$FӫǵJ#㚛Q㔝WQf$k.8r30=S֘->*{|:tGoNƌ;ls:Ql;JڣJO(W#遻a1oIvDUjO(d\|(HMy{$TQ[ia-H~с)p}r ,CYqUw ̸l)7>z ܱfkp娦RFɻͨtIezoYQm/3a>W<_r䌟fV@+HC$~`:v 'wt쟃4q5jć.{=umV\\w tAċr2|RFa'&︋?A1|$ECCg g[URS nGLO0ڽv]ҧާ6JjP ]%hANs IDATOMxpcGXB۰b{#h:X;]i g:[f0HHr$q·[ϠNLe٬̄ _qI_=t*QO'<`5j- E? >cu܋t:: )q/C4s}m\=GYm$ޛFpSClmJ'\&u0K9^[gv`R1z$yO~Hi\ MM'ΐ-l 0MޑteciSB* vGk|$,|A^l-~5REH]լ[\h~Ϧ灿7=ī%.8N^ӕ+ӧL1">1ǟkY+2}7s6|^79韞~{{{(~&?n}G~G'OS`΍\{{+GG Vߛ… wӲ\ ++g_/KTv)e^E+uۢ;k< 6^1m6=Y 3IEcQ6ٝ2,'4 ,M##4gML~^(L^|Cl3Zplfh:G;>K. Y?3Csɟ<c襠-iSBmhѧ^ 73cS( P[Яi u(9:(;;ˁU٣,>AʒmM.%,Zqs^Q8ZCjD)x]7~fQ /|l5ym2qVNю(p4Q Xyp:fTP~2EHsDZ[r|F#[~YgQYf,0@"6PI#.E`|wYAB]4 ܥشي<2/YAh֣Ҏr3ʼnkZo؁힭lg: }, X8#'}x~"3 HdhQ;pV.N0 Ұh62i.n1hЧ^ߤ6hlJh)4`7"lCɀ,kĚwoؿ|n}($Sx!sB7 ذc[uࡓKӆ ͆v(b /A^V &9[ަM!Y WmuRXKNkTuKxV&/`IJsonrȺm{ZtQȖ)- $ t"+ʦOda)q۔Og!+{ayF`#ĀG}d!X[TP6?Ц4hz;xS\HH E{}g>&'Ϡj`ZG#G~[u,ϩ rKUW6\)3=AmeNrɀl}ɚe&at ,N>Գ(lQ=r:d X6z?]R{ޟ{9O|/h4ۡ K kkomsrFPH9ʒ6ȗóܔ5 J7v1>9m;tr:6f;|˺J(ЂN#BE6 "߉ÜP\Rj26~fTgB0T .>Le7}b>U9{|.+S|C#spĖTKE%WR)gbfagI?뭑 4 e2}:S~DWMCYX3MjZ{ #^M#MS1g&t Lc;C'O3ikˠa@\ wI`[|@G>lSGL٥i2N(9/bt7e8=x>!T+U(%{:9zQ3xƗ v}gԌx/au=gGӠ{5ayG=.~>lla?N{֭]['qKD^]^+( ۗbn9rq X u4 i?K704]&m܇"lűNL=` G}8OĈt(lzsgg ʪ7H^CDlxqmןs2oHK_u]B-Ι#™hʼ: "U7qykvD8,mT6>+7sܭ3y#h:ϔ5 x˭G#?`!fWɯ;AzAVx^ kYrTHə ѧ@6!ȾU/$䱌2'T2+\kQYr01H|>OC ꃩmܑtGrVB] {a0ڱnܚ w?WA:ɇ^н78p<}O)>wIf[z Aa҆P^Hf:-sP)+*4 Ḽ'<pHC>4̉7m-8J|K?6m8L?p72?}m'\kĴa^:"ӊAu"kPp>=KHf$\wO:q絣 V:ʓ W8OC:rL5[Gh5 #4Ŀ*b ȴdaO~RǘsYSAYgEI[rX'Jo=q1;9"f"NWy"qH.o/7'mhU1}/O52tXӫP 49 ywwrO8tT g&8"D-paT^N흺, yym+ 'x#p3VC1_Sg2lp`ĽaRW+[bƏF G.FWhO٤iVY^bd F#7AσL_L~znܸ|ԑ$?GK4lXrIgd` cZq҂+8R2܉%f]pqĔD|VLU|*S) kWʈ'c|U6sS7٦qRZ-ǵqO@o,'_山Zu?Gm3SDcZ e [LmߜS}kHhʘq 6-k!!:&iykD_]>l[)gqpVD#)vkgЀ8Kt [ AN(!r~*hw۲W!~|=rFvkj v|.Vʱ-gj[6r2w)ru#r_.j9#:_dV}̻&fF _kV &=)fA; =%a7ô Bc?5 Iǂy'># 1ud3V.i{Y?^g^lX|Nܲ;y2xd!Y-ʮ%#ϑ+ﻛ<-H"$g!-8H.dGNm@ԋxVA Π/.bDO9{CH ux~W@ZU4w]@tٓh=LA56E4++OA0٧w{Z? '@95232#?m.ɩ R~>}ó0+0k7یbQG8Ù~n p o\i vr”[ `: OGrG{&/#)Zu8" h;FĪ>y&-Zdxq}2f&B?%BH~Ilc*Lڝ(cFڳNFKWif1"hWA[g7ytk ^|Rڏh࡬jԱY61~z_gFәRZT6rbC7 ^iV^<=xF^ Dkn48ʬ.އ0ϪZȩis{%Hסu @{9,cGCY-޺٭OD;˿׌bhȹp5҈GejtO\zȶŴ> Y IyE-}U$ޥ9hY9-v#W !1 ;trq& kAc~c74.aȈ,vP͹|phJO5u^]ۡ $gKQvwNP3k՝2k8enC&ƈ(uƏ:äkYA9{t!|#Չ4}(nsC k s~#_n^4A?0YuIDʠ۞R7|3@!i > țzVO(sL$zu u `q%ȭL;;Q5ُW[L2ķ8eAQ^gutA1pgV=)%LkLg(w*[Ax,e]]='ﴯ(7C?|%#|m`}8)t3rkWXyQ-_ N>>n}{lLc0\ػ:@8VykEwm^S>K\~B<۱0rgC'+ 1Mp🠲e{n^6156[»M gH/L{7_3*>IWiO͊yK&xWߏn}YTf]>jqM~T/6sj;sM=rߚN~#_Rӟ$`!>yJ#|<|LgwMǎ>rczn܏2w_llmG4.!Iq`l|4|;e7Nm͇b* \~8'ߗuf 029>gY>'-ǀ2ؘWG/ v}x0p#q(("FQSR)pFk˨!x Ót ig[^`$Gr4#d@^&9Kzœݍ.N:i6P8ـcB6GKNz*pzz3L=úCxs]Xu"] > ^@eK0y-oȣLo'XGz?7d4Y4CD8ܓwGK/ ? (d|}A7>BA?By3`BKқ d CC[&"xyʚY.ؐ `=# IDATr(y10?A 6۠MJ;C/%$7^tG`o7Hʒ2iפSC'I/$~H2Dz 恲!$~`UsYҕAN#zҐn5(~f֙끇gH/&cO U~/KٔCk|jL#XWq-xMC\'̲#n7$A 7̡bAR3XC74vb}֖_dn;t {HCW fbtz GP\#XWzL/\t^5|RVS$`%Wٳ)ٱ!f:TfCh>[ NZ;SZ68e|7&ߊ_5ptW٬> 'UOAăe]Hh;,ħFqJ4tr (F9rn!x FJnGG.i ̹OtnTZ1YׇON<.<'~Q;8.!^v &f)LWg):,qcQ٦D!@^jo.7 W<4X]} F?/]= ^CYAE'FXQg=,Ox(CX}!9Tۙ6..o@관kە,aQ{~Կ xw蒇PA79VehHE^#ꄽ,RoB_Ϝ.ag(;`2AQcW ٞͫA{xm::ɯGǽlsK8ùfrSxsm9I+g Q'~D4wM,z,o,%0_VB+4X=[`3ˀGVGY?ɔڷ`v3C?,mt{x4$0ڟ^x5ܣ#=<Wie|?ӥgwNoV<'n]34 9T>kQӾsȏ*i`L7 _QS * #zٔn!ns!#>r*tηAf\;晴[x貰0Vm$X6再SǑN[ai|R9:" >aР;?M3xi3"!@^6SLeFNv'c6 zg_t&OsYʓX:MU yB讷_+Nh'(Y6wy?viY4! qu8i1HSe!;>KZX:}%WL!eq]^!coP-߯g"a=;3ww-vWIFj%/u-K k€}zY1ûU·?<+ʏS<}g:{B0df?T|AXVp:[s`$`S-l-+ YZszECWVA1>kAkZ~u#ry^p=vY.|ݸ2 *38H3:Ĵ̺:G"r4[֠g?>+7C{좱iG8*ߒ v{Y3qⷴ+;k|Gȑ}糀9(kBdf]LtjG+CVro>ϰfO[YFTd7RSA ?eD^`6R;cMw3Qj86Jϳr!._uQPq/`,1c2]5I{g[N5 h _J.ZDa['xS^? aͼisj]kE#ܷ0"/ J I,~zL0Bi%U>Ls|_{3]ч(sjYaxzrjYCa=/sP̱t,딷LCy!@<;[Rʞ~K0ƻ1/mҺ[-.8@(܅K('#uZg0t<`G(5vQKs1:ka]u/ֈ'hYF,KWc`rX#z>Gקk8wfU " 1S)_BHB;>QcVD$kQOu3r8[aUic[}CGz:un[` y^4 q%xu}2IO2utcco:WN? v8Q{8u28 42LȽXV nz㙎Hۖ x`* >@Om gGLס H5u5ҡ6^=h/:Sܭׁ8NL~KcȉuH=C'XۆpV \m_cߍv9YpHNl`Y婣W2!E)wօY7=!+iw{L;4;2Ӏ5ps.  ! C}MAQg"]_LG3撺=r{!:?L_9|:1 44M2H(Z TS"MM:i^ O (+3l-{V{aMFg'_C^I=x\V}`kf]̾91m[|zƠrdzG +6nL6gS4 ـR"+ŭⳌPMvOGȥL +'C=+>0-q3'bbzI=ɰ|ڍ7{lYdYI 8:ZB0(gXV>{',4#ۚC11x 1˖5Fm?utQwR]VBwY<<" Dm0u_eӼ=75Ԫ$ P>C;| VR٫|*QxeOy>eLڑl[։4;#nGLk: pd2<c4F>uX/rGHM8Zތ4ۛeeI&dYY-"\cYfzy`By dKxn +|Ȋ2b%|2CIӈ4u,7ExٗFЩ'fl2ݪ5qQǡ/K^~ˑh`7ƵnOų: f "!BNdz ;Nn'\qb>*24&+[+Wu`_>QbQ߃T޷GeTN6+ t]R{"hp#gjtdR tfe28?/)A}z7bK^sogRf}4"#թ'(G?Y37wVrEz1aᏽ9 !]Ʃ(ЮM}3ާ;vMѳ'#<Z_M"Ӡ @ڋ'먹򁼬ю0#cz6'W\gCpC%ϖ@fhD_3\6K|s^xk:Y}χd|3@dYҙ|ư?8@ԷMo`pMD/)j2%1f$yڨq ګ˜≌vM=+k% ZF> >啣Hw)sK_&!E8%Ҏ|z-RN6u <lqx(liRpiK_>hػ~ 'K2?#)'|Mk5w!q0Q Oc38"]^Aʙ=+W1h5{+72ōCE!G攚 dě4Xƴ+w3rfKJ8v\3NÈT#8:N)?qҠ~tzSuj#^;c!@<ul2JS1_6/YAs_ֽM ‚@p'#OrNXxzei30Rwc|ei6PvL5]JQ7bb̯/ch6x_a"% IDAT& ?I{ 9x(K;p 4x$ZG)>c4Tdmr 43ttSV4+І#.ĜkqԐAM2\g] ẸP+HeCkꈩ: ,WGS>?r@xw%Fܭw*@^>A_ڠAG{9kwߐn~GNg&Sfg'E~]6*$Lr\'vS]YŐձ'Z^_9}]*\ K'x, iH׍awoX kۿ2[x[_i's9f)(5o;VH+@j9$fKLӝDzYg8H-ubYkN@z;^VWe4.4/ '_LGĥ+p۬Y-^ʕ<|°<ӡ_i?i:Q!^lwrA S9m$~f0[ :QN(Cxe{8|O4 :_siۛfݐ~ C$L3M咀OUCbK5|P{7v}mEXk4FrzQ6wJi=цh)|Jvb4`hpNY gqc: 3_=%_htJ1RtӼ ǧqɓ!D~;J MF3xwǸyݨUFJ |g>L x?fwԅƁ4PePw ŹVn8iق ]a90I 5R\N/OrHβm2a'saEJ>0yҎ@W<!Silk- zT/O=םut~`=-.Εb9ݷ} D <\}i&;ape {[֦@VyX҉0xg`*xHLF2M?40{a4 \Pxջn}* :Ӵ6!ʖ0Ø̓?=A% H!S'ҍgբ,Ӄ@VմqtH'K'Vnr\*6N=E9wSS ਸ਼Ggɀ' ''8YJ;(u%`#OOlؿXD~)ùөW7q߮'ζhvx؝=(7">^.,CV>9;'LLkueR̴Z7d)ye8cSjaNIQ1 G~xܓvy˧h;JR 7C^,c9lPmV~4߲I4);:u[-S>:O9X[ۂzAg>gU pS [1 Abc2d.I_۶J߀n^ukl{p=ߝuA3NF[9qGD|(c_HiO mS4eDh.SLG]GJ|.# 9/ ۖzB]4|\Ul?CzC$PQYw s=| ^!vhz PU:$Y_Fi.K}$᫲pk'!/ZɠWV坁fʅW.>Me;^>X' ޸H1t Ί$g{;%#Ys4S^E?,p/q%׶1ñF PH'+ax >/'\_qEW=YM#{ydQ-k L$OHw3sJFH)]@I{ג #ph)b d(;F9gYe/m2uPq-|Gu^󻱷\iV1J'Oð7)\h$HA]?=7s0 4,~'f~`ӿs&3;1v ͝:]h?"O8Wbr$5K>=ˇ1=2 vd<`U}p LgC^ VǦσ˺,tvBps##_։#Áz|;l!XiIj,;t>,{"*ReYbGy IA6\d&4씝~mm[ ?ⅺlQז 9?YWg >Bkh?H l1 MĂ2'ڜQZ~s:a()_ˉ(;(v#L t@8ne @|Ko2P#,ˑkSvط|Jg3MSK>#eɯFxVai9t4$hdj(V3cHȢqJtYf3=?iJS8X0M}W-^})PeS8tȢӵmz:t*|^90ʒB"GqT?h"+Udcˎث8[;[ idzMx&|Z0}J}g1xq 1-:Ixg? [, Q\{'^:6cvFEGF\pUǩOY' UP*QLLg[m!@!ɘQ1]H 'q3>c(+O=ȨO dz`;ZpV̢/^.ۿZ։t 2d;i$k쓽VV⦾$xhQ'<qޙ}R}1^ d. ",5rm[rQ")g>S'5A9Z'nZY]Ȟ.}2TAxaK{, ݂ u҇<'I/Dynx xq3ĖRt/t~];$wa@4FcDY Oh$j*!'UCI Z3y1H?P ƴJVwF:J<7Wo)rlN(6g ;xQJ9IN^#q:P>\i SIJ6d[,!a''2wa4ޑ wPR?k#MY,whQ3 1Zŀ籷o]|Co e6dA4jH F?QP@2q0""C$%1`w#P65<9L+=g{ZzY u]˹|GK>A?wٻ8<߭fsnnfT$©gt H1n{Y9=UBeh+{T!q'{+-# Lw{~uAWzC8Or '܎r.Xl 䵎1H b?72:CA*upp3Q5Uܤkѱ`Cnn dO|l'\8|733 >GUtdKAo7dZE#+)um<7S3| Mh2CwAǧ5ޔv1Jw9gG^nI{ 9G2݉=lۆuʫsj?mxz; wTNFSuBį\Hx<G9Wf3~_0J?9tm%O_oj_Ꮵ>   ެzp6+nUKfvCv *mx'?<٣XfjVY=bNe{,sr3lP ~^f*vAA<'nZŹťۏ-Gbwq960kf.Ctپm:J_m>pX{,ʍx?d,lRIC}wB`E엯k[sk'4@zy}nN=N?O|YedL ץT[C!xQЮ_lρ5ʲ7qU1Ќ뾶)]ڟC}_lA~X}ǀ EK?:> 0II'+W Rӕ䭬6miSQzx-OWWclݎy:(|&o'6v`wYlƃ+*x>lN^7U6떨g0N_xgaV5;h{yG ?`|7hE&ᳫ/7!쀓I6#k좶Mۮ>I"KsAA0cfY{'oCV7~zxZPYsN3(k,ӟ#qRqn! LM70&;0K\݇8. Uӏ@'?<꫇,'xL xw(+Y29a^0 !0OeaZ๶vks:OځrsybM\yW'l/P <fѓ-/lE HBѭ]_N- ]y0_iӠlYG?_W_U1\uXUONk_͙j3p>;s~ҭ}Pp9:x^c :tTX){csʒlp)O&ql mthߵv]h3 {㯀MmU[|tzϗA&3 nmע2⥓seu}Ɋ t^^ rm/Ar? 4Cxf֖ 67*[+'xVH7.c wZ8jucO+->냒)2{w:(0~y y襟Y@K=WX^~AM+&Сn M{Y'k +%_G#p0.tX$@ɓ\R96_W! *X,fxO E=aNlde ƌ' -S{V&S0.ރ /}qz^Jc!ZـA>䈗NUePO_b_N)&At>|=N6Zӛ3=`jЅp/}W:}.AkxP@3]{|4N^x;&}koKʀK3X&ģpAWp#Om+Or1]]N޹Z99^]XKbe~|+ )8~I{Qx5ݽBQU𱁃LYOǟu< oB]2z:"#{W_-Xw.+5:Յkfgo/Wxn@̋;Yfj 4x@뗆=_'u1imK)$q\udd_htNʭA<~]c`P78ہ8to6Zj gX JY9G ophV'b?Ik;`Tspį b_K09xU{--oc|_g]9{1x}7/)=ozwzo~_%ɫ}ϑ ]S! ؒnr渳W*ݪx<-˪rW $%|fx&*sslxm;Y IDAT ;>[6|в#l|wNHK0ؖ| p]k!=B|E˒jnwd1ۘ5,R>hiv)6@Y0?t) ?櫜A7Cٵ6~`i:&^ԡXڄr{+G0=UoUJ{piϞgt`ω+}?:~Loi`k;b` 2rPy!ʶnY>NvitýVpw) g@PWs>yé=:zvX FSC1VF%^1]JD7! 0y~/L@֝S/(̱:1*kWH+Vv;@63> .Hʂ]< *X?z:ã|x3N{g?1Ldm_o6AqR|teqY8y)YeX?G chF_7$:RZ|,uCl~~ƽ]'PS]xx0ӫk˫ ^|S؏1 a l|F:[^E!kՁ;o)>p:\2W:CNG퓌<1R[sV'ܰ43w~Nl8 cVw?;h,c@U P2XO>};uwՑ ?hܣ'ߩG-[&;>`7~ "mIw:|fq2ӕaSka/RJ_nI3 nksTbz?g J3ȽC;lzD3tA=e7 #x)Gёo3 `V23<`̣9~x( $VqWӜ`jCs3yq*Ç|L^7jhpG~Ԕ& ڻ K3*hcЖaώW[xig3{Wڿ, !l  FYSPT9c97QU9 L谄޺ iw^<'79k/;=♺~?G_̺oL+>8"g=ܠCiwWuN~'}lG|`^-hƒr38\۲616vq%L7w}wo=Ϝ%\p?<.j v2GUS!rLG.a@s=Isr:UΞ&p~W%o|v~s޹:~@Tfi <]"ҏg88 N7K{ zj6z* x3ܪ@a<?J/]}(*r̶B}dk@.%Yh<[]s| `(X1@W2'36z\u~dܳ$ģ9eMd8 թIdW\眬fm_A{93>;\*v\\8蚜#@f`=p\]=꽅/ =ZX1\.fؽP~p4\G&^ٺih7e8?t+ovC_0li`QvmulG<=:x1~S]@^@s0Br3scr9m FK6vF<ߣMpwhYow]! UH9 F 8. !'s-QU;Wr&_O])C[P9xWQOfl Bʩ uOv #w|LJY5AEw"n5GFD_466p\kp7NKӇǏְrWK3\kf!l(|^xzO3nǂUS"]ΛO[-F8\,ꮝ/vJд8^4q@HapR{҅ښڈ" z~x6M:)z$*vZFxT=O]{1ȿm]!+ޠslz6ufMmG{" ׶;XfOWg<:xdLi7]_Y@*=$Atk`6|ޕoŞx:3?c0h%W&;5NwMjxW&vʽnЏ2Hsgl@[i7_lp0m+i6x%`A]pa34TAG- ճԳ3\"zY\B 4P75⷏ѵs~ pے{+"o˭N sǫTد 饱b<۲W Iԃ?9'rsګWBS<\u2 OKyt&m:LV|յxSՉ;n]c赁 ̉Llu8c0g2)8/;XqBI|xu6^~iHjiOwТ.- 皏 N|miVnX= R"ʧry~c2oViΦ+d3uۭbY }:piĵ=eVy'x+:aMH]SsO>weGڻ៸>|LWiO:m;o?}򣯵 ?7灯/oLvW1>+=꒳Υ'7mUP{n{EFxtEc[<Ogލ߈:T|/*Ǔ;VqTAYm~ԲS #q{tpeOnO({O_io8v۬䓎[IV{l]x AE~ts#MJxeGN,^bIӊΝqK~'}&pX#xhxxIosBկAn38ww9|= [}3#{-^vFu0aQu|43\=4Xig`@!{KNdU@p̚Ƒx;v2c8yf7{5+yȢeж) mB˝}]M{e,:!uVềlOVl A8w7L( ÏR<|AFJ(J#)j)-V#ymt(zmWg{á$lnͺ fd>ٶ:{?S#{EuǍ4?O~նGhL^7{\bm7s/<6pp1@VG\e'Шڏ&7pݵ'>=OI}ᩪƳG|2v%cBW 4-vp`"^sÁoǩ^7fڔִ=ߗɚs]+CsxTRKcvc,^#-ݯ#ˀ87#>G:\N›&}NK jpX,ۓ>9 x 78bbtk㑓r^'<ޅwlp]4[ngx[̙ wd3Cv#케k̒ŭ 8ި:{]lx53oA0' Q>|>svr|Ys*pgGto_YA%6@a7 ~?tAߟi $-'7++ɾNU";G/ ¤.92tQGRڲu'ѱ2-ЭL|_tQN?G9.yϮ|jPY!N.xckIw6h[vD8>mYaxWΕ%^Gyvc(o{Bp]ɶgGбҌUgUzWGA !nj7e+VvItfE.p-Gaxa!XVrp&{#zef‹CiY[;zvWdA3F3'vA$Xyͻ~*굌Vo鸴1D+; JNVV~t~^EaLV17fB=k|7{A'^:o^8p_VA 7A!Rb x+mTP~q;G0; NY%ٍ tH=ouCz |+OgԺ͑pliN"wǡo@ ߛMD؞>lfp݈8}J,A;'TgzHM~]qj n, xYMe>x>}Gpꡣ;'ۯ1n֛\;nfwk?ӽndG@'g|bU#Gw nzfqC{ץ:`t TlLϬz~W>Q)}m4jo,sU%[ tؙpC]e{IO4 k)t8dpJS J+7ތ=[1h ]]?E=e5+ohgRno6 =w)Nxs2OT;F쥶.=z2a |)s<w䌊GaGv^[]g|H7hTGl_pFv^O M/xTHգczm!|xGh.s<ݠ IDATGl@Q#ztMEn:x9<ۯ}u,K?Ozb䷌^u<#8sS Qfzʠ#Cx8CFA,<Y]{:/"|J2bm6!+SNf8SZthK~Yr _kpnX5LwT`㭗_N [cˁM} }?^ R&L.:ݬYV"pȺdlbuh#48a0kmieq2 |LY6ԩWV uW^}y9cz~( O .YpځOݫkde_;.&WۡK+h+ٟ'xQU6LlO࡞tR|3r𞽺S@8 vj6]7s08=cA>ZfYJW ; `n3鐃9V]+rJ-=-x6P+5Wff7`Ӭt|>=dAd@VhAf7{NxY2Zӛ]:vMPswuOFGo&}I>Χù?$Tr`z.PlUz9F4Zݕ#g諌d mEiK6Op8<; y͏le`nx'd A}Kğe $>vxV2# ~z3?.At\W0/OF߾Yg͞_{=.}}|-Ao VWٯqz^OЗ/Ǐ/KӿW?{;iroxJ,_@1{qr^g }@50ghrPC%6L(h:F*͠0&9/(9bp8 %:`.LJH23:VPE>7! q}գ؞˃hu~Qi?]WV0\FjT"q7³*?3lVv #l湾S5>WΒ=A X /ͬiq'S@Q1YVXy :L_Mx~e9/G 1$/ ]`KiJ~ro18  j(mUtVc2ЗЁu:d\uuRw_^R>q#4͟6 !gm/ .jFNh6覕10p䭓/vVAN!hY0zAѫ~\[fC b֋DhP<j>yV2b`vS;6H5Н 'MQ4&t^L7KotKޣn3tʢ|nnӛm@zʩ#fTmW!Gz%3?=^'D&'WEӑ=3[݌`ot(?JCe< +!gdv~pzfnU tN,NoE3'q:6| &`johy=,O >}ܫ#p 6`&9x+G U6+[;Ψ^`y< R/ll-o?]pj7ltpFgS5C  so:2 8궒XӠQ ӻ: UN~M:>YDz '{2ûz]|0H39ee vhm{3 fYNuwoe7)1neNsORc_GݏϼV}٣x=pƒs'rGƂVnl ;O ioHK?UrH'zc}Qı)`1Hmi@Y 7裟f=\: z^3=(of{ySmLf.pա ik5[#o3p㥙^-`_wdWgafӫW}]'1+ > V7L=qp9 /e6Y}hdf (N(Sw6enKKl8!_[ҝwמ٧P`@LW-6u9@GVl>E}u4UwFx1=b &W );3"`ӡ&,p= hc wYHCO!'DPAl =.3_3-9U::b_]>DY;zdGfA1AYvt; rWٹs~lVO: Y#=1_:CoQuURYgYm p= ]_q/ݷn3@4i_?[V}sΎ65&D%8|sMlz. =ٳ~USx#>ɏgL5y ~ QzRC4yh}ϽUX-J@Y=To-$805zlYf[omL _zslP6W^ÖD6p|1`SW{mthF< 7%U# g4CM\np@fKW^t@=}+.ejWdApDK lv θ4;l[)a ~n`(+ыw`j}*~ONѯ&QwvAwA&Ԟoi~Lo O6jk( K|n#<}l{P2y[.*4HqE6a|} ڶ:ဇ%gz-НdmM{lHU>B;jݔd Klt6-el*;\95.g}}'Nn:6hpWeAc+Լb*}w9}7w{_?_kO?O|_8~)گڟ ^_M.{6}uiuTk<םPihn9dZ9-`͸h 9d4n_06^ _2Gw U H): "AQ2`Ep6DO:K}P~_ջ乀l1<@gF/.<.5iߙNQ=: ?&:#;!q88p#荰RvfXᷫYz*{ WX>8w328V/G44ဗYxÅR<J !h.п Oh;I.L^CSw#'C-?xlIW*gZw5&?&h]2[Z[ Ӧ 1Ciϴ_3c]G/_y#I6h0X~lݮ?c\+@o1(,H~lgY ἄhߛsQ ٩dAx$rc\dߑ48#vv8 W8! a!W%Z,(;xX'[i~g:{de&{7ކw??s .qFZk $ ~sl){{ X@!{.ANC5;p\\p[D/ICG bi'Ok^&0}ڊN* ;tн`u}A_p?^G%3;Rϟ|jC6«A ,u5@@k-e[g\ #u>ri(O82;ak{٤ oPƗO|k+1\f _@jf@@S2|4 1 i0g/z7^ ]hP tWcM&)or>O<[Թ$ ܊˞ 'K GIC`NEpD5xd uc|ܣLda~:K`Nhg糟_xO>;>\UF敠ۊ7r~{J}^@ӣ`N&/?Bk6+O'zzs:2SP(w _u??{?o|#}][jox= 鯶wqϞ#soww7WۿO?tM]!=9}b?N_Z|C雾ԟj‡?_Ztk pë~/:r|ρ T8r6#C m q@]KXs:KRFa]sGͱʀϹָ2 Ӏ4BcOpHTJ9+\>鷞z{o u8BhJ_ X=szFF e\ocި 4;ɸG:ցBqAW :Džoç4PUdSg;-#=hVog* F1r+[ٱDAQ {tgFL=Ux;Z1\N.˛ TAXZSfJ:BSRr*Hw i5)z_S-ZV9UfHuDs'/=ƮtQ7yv#:=K_pvnnw( ^6U#Ezv6Vol)@>A<8dpXޞzC棻К`AK 8ZK1~mr̢xv7-pӻچK*OII7Ϗ66k4 .@q&`gሱl\p~sGc߲%|߾v`k{tz͇>fdkVȷ4~oeye;Wm x8m_]L ;+ɊcB^jVlc<+aLHOozNxBr NW݌=nL.q/dd4I7 6c[aUq&ү>\Iיwl8]o=k ޕ_YKVei%d_-{|Wgdwbe~Ʒ^ɉ\=~o-?!>;s~ +~O?qz+{{O?xP9o IDATycm |S-~է_|]]?g[[N_K?<'NX.0jRF`pmA\r[xpZtnCNY 9e-K`a*YtR ++/;S ̂3:9,GPTg~i6x;Dde GH?j]*=4x9PEUmT<^a}YC1 3[ǂ T_]gJQ|>5_u+#ݤvO!RxhiݷrsܪB@{e\~#!Ry Կ+zue%-e$c==nKYsA2`D/L'kߨ$T] ̣s6qVxG:>jpk%'w@CcPe݃KݏWsc639-NfҺqe[Jjo.FU~Ȩ:G1W]>} (gQ:tty`#pƗкn. 99~& %Zãq[յٸtt3wdʝu!,)9UV-/sXp(=T2pp[]eC$bB3ٜI+VSBpg3dv33+AdsUkNT/yXupB̪hQ?Ԏ٫o}^鐪c3@WtÌPxgތcy;87+eX(N^rӋvGSnf&+=H7J[n*48ĆZF.r+lt{%`FNɭr(+}i.X8m9.?Iew79Y9Z^ueتl ,ޱ}a3 rK!W>4+d{CߊGyKD<4 _3'fxGgDrVh]'/kӥ7[0M< ~={R ŵlNům^?0?{`xvhN0c|Vwϯ؂. Al3e=h]T?9Z>{}>lyѓ)>ǟ#84G϶Ut_s6@.3J[%j>w\W:cv cf/O7aP gHΗ3W,߿|_u_o4ʀ_ soթ׍fD`8 |~;vo+Jk Ɠu`T^ ଂU)t4Y KЯ{Xguf3KW>CqtVgFb4}diF ]Q_q$ޣˌ]y<~C;}F1{ټ&DtT믝^\푄3l@^ }U9;i1Ugf=l f5kZHYƣrl%=sf/s)xY9!;,W=:/&Wz[ފ; 8\lWf8 ߔ Bgv&;h6[г : zWI7\],t! L+K`'}s9ե?'ͬ=鞓zT.ɢ`\mJv!+O_Ԇ̩Z$ܖArm -f-p3Gg_ͨf +ɏlǔMGd gf.oq:C)mi40[Es_c97i'Z惏B}}7dV*pA!p`rښ6IV*JKpy 4xHEY_Wgݩ}">vc~ ꏟݟCwR'fAUm?ޗl?|_N7N?aK/3gr \.>򑏜˿|lO2 W_u'(a@_b482'W 5: -Rp$~}3]F[ ávڃ>gt!s ,ddfX'4eRxy2PZLi`3:̂oȌ h>^wCK,w0嗤wpgϱw>R<%#N#Ncs`S7}Qd \e3˲6 ^p:GH LΦ!)|g9/Po+`W3׬&:~*oYqe@ 4m q뵑mCӍHy<pA=@46}/~哻cowmfVer~o;a>{wf^V.{cqꚙFtsDٜ ď&x9<0C͎X@7*3PͰ\)3r8V){e0?rz˾, >ĥˡyK~_m,f7/"Ow_hs7. V> ioENR/ȜvfU`, [^npM7et|ǗdU]d=b~ʉ97,d{f9Үj?nGh5ZO1yhk}8%&CoEx)_)M&$+i[έtuQbP)WmSnu rA^FUR]yOp~2X-p{}מn5Ag8g7% +Ks̏e{ڑ䶁- ; M}[S}-B6ތ0]0@, -(omJllC|w7pA~7aОŧg(т}&)tEM?\k'XjT~j /WA< jCxՙ]>{7R &&ʐU/~<89=Wul8pI|CL􉼃!([E:O֧~2+Vl ?=|9jGrg믲cBfh?L7g@O&| 9EC9C2G-/YeK>ewLvd6Ck;M|P3몶/~}}3O~ˍHb4` N?#?tz={.O[[g{_|f?gK_y |w~4)}?x2oq_?ç_K~ɶ|ӟ>[OwDS2}}·ۢ_cV.NG!cw{^xs+QC6bs ,m0iܵJ~-87ѫ_978aFlXd qB.F#s'F<8rkuC.31QWJ=UhReP`-o~~X-h18F^@-t r(ߪA:& $r6Z%Amq" 7Rgu+h93huWg>S8T?ԀPwKi%:<p\1Ep ƈ(mk 4@dok:t/E~J:@8r8u3=>hSo-%9מ9+ϖj3 $?Юd敃mIGs7Sʖ)A\זei %oܒDY' wތg‘}.ٳilfoVz9} SN(X_pu\{c15cuA6T69ǣ]}zo?ƓXo^ ٚ`8k0=3H`$=:ƆU:KɊlƪmG[:^]t&8{9~]CfmJJnk=rfzd 0>l:Ɏ.o)BnoE8 :eή^핻=V_.<K8ޥ ZЇ{\>n'>=_uO;dqg<;:}XYAzΏ֕ ϫ*~_lA4<m n^u;|۠|JZ{<ŵʢ':ɳ|'~<>|Ń'Ad ;ٔizTܖ/ln}>䐮<|7ojz~W6]x$Vwۨ9.ePlgKW}lVu]R|?55!O?L7}~}#nX|Mm#/ -o /~o[?P%Fuk@Y ꀟ'I5ל~ $oͧ~_~wߙ nz#sW_Ca2]uJS֤s@h3T&f_ZdkswCrEW<ꬾTHzK`2X=Ũ]*:Y F/`Zwv#rs2xn5kjo'/t6c,83VolVe N 2f3iAk#ggOmjw|,2=&BYdF==Lx<*2 7*o)r\?W7o`dEWV40ԫf8r3׃䜝o*]3{0F \5;xf0W<{N|r 1-Vqٻ[,osgFddS]=%,D#F <% zn!ae@H@Ǔ̬Ȍq=̲ D<{kO~}rYV <hֽ(9g~o /MazXp]7>z3Rߙ(m1f틆m_;6/;IOi%ho>`|ar /򆏒ه'_F86.s'L)@Q@69[{罋ۖ~Ogl)Z`ݎfnrgZRDUhX[[c, W^CVW`/Ζܘ) H5ow/ 4+W !>6*p|grA%P1SO_8m>17[J逾ʞ?M*s·ӏ{>ז'ou{_-dAqP@*./ IDATv6y~Q"ʉ%0hq3 Vc@?^]Ivtxp=Cc~Q??,UJ<}T WӃy6:[10pITCl2Ó|vs{mvꝯŖ ;hƿ>k67³Cn+|6 &6踏ܰY>}E j<­-4->{cU!Jf̂.6fr~!D >J`Ĩx^̦u$)9QS? v>FFk `p_խmgavc46х]8ۦmk5|l^0??p`GmM+fI mX.>UL>`~9翨G}m̟񣌬WrW~a?;www߽8k]o//oe_} aWo_.v3Ŗb ܟ?8G OR hj`|b}~Zy>fR=xZŧgSz~@ٿ1(eN[k=^ptp9,c,HGJvʹ?@u9??qҘpPm!?1b釋g"*ǼV6lXAR ds𑐀_NZdI9qYQ-Z_vt &"yK%(&/9p1ʣTwq䮛4i,ٚ$_^X 't0Md?}ɷcp訶y_~@rI2zÛCMnoVv9m:'{$o䈓锓se5Vu#K݃6F' s2!K >_*ŗ?}he0Gt/}gp>Wod>h9DӖϓwvۭt I U ©saxD3|9:`%4h_vp\P_lJ͊;qJ\Q^9A<[!C]'^w߃'Yk DU/5mgӱC*(=.L b%v8,7E*ҥ 4x`_[$ q;d^xR_8[Sjw6/m+ 1??&#]a׳9:Ρz^v_/W2k;]'䟜^|of0 6)^@FR z쵥asfTp[pNN8ev[9*Gz~˓\T3:}aI,dlUk09CkC  4f79ʵu$=A?d)bmn)h=ᓙZ/3Lx;N>e=9  v,OAf8pA˩ƣ _5a`I=q޾/i Cz TTz +<).U lͨ o (ƷO :i뜈ZЮV-[0_y ^OrTyo?^jAsIoX+˿]?Jd?oXcd+ H8wF>K%{W \66c`ѹTxjA~h[i * e\UˇF]HK'O㿕&1F_~}Nno xϹ_7迶[T$%QsM ':FܤQz޸xm6٫}^W㪿hEZxӛc6s8aa0KHhwr3_%YNXHz8O ~D9/?4QV"K4]3xMWw_kױ N/Ï.^u]:\{2}5"\zn="EOra 2o?~z`ε΂q푐Q˵_8q| b422F~[r{Σ7;9`8z|xl#9;oY4ձqzH2ĩis+g#%Y2gj'x׾ Z5Qp0/A`u+ noؒh+ 08JV6l^V:h[y 2˜m39x~ƚh qL4zO=\!.z9`V,aoӊ;0X{c8 nDmg>Vs݁7I ɦPfvRlpN_Y 0^ Oz}oǿ`A>{WtIPS+6V\8߽w ڷ3Cg6>+Q닏>|6}2۟w6%P$wUFMWVxdҫ7 Oˣ W}l.5>ݿ?Os}"1"@C{Mu!K{7]Kg0هWxF6mAzuA٬XIC_.;y+mٷn7!m Fn} /ҟDO%gKkzI6 $ӳ&w'$[`dmf$ nԮ>l|ZvS`8R;p}0Z*Ck6!Ճ{߼xtEI`}'ܳhfےXl@l!l1}/~~3 wIꐽ= lr'}mgfsQLƮ q'|ekQ9 dJ` t)}ޣ.K& raCu=΀2f-yxαK\}d4O) C 1ePJ e6# :ӛ^ƣkKFc՝sMS0~f 9?ٻ40P a( >(%NA[!!qFmj߽[rp wScPHo3['sif]WovQZbn~7suAF:( -9zxqGF9prfEWߏ 44^rI]}pj7&|?uAi#^L+'Y}r6 v%ӻ`LN$ڌ?pZ…3Yt{z ǏꅭwڃuHPd?0Jw/ ,(]P(:E_ ȥj{TOVA/Z-@ }px2jyߓCOZJzzpfrl92F% df{8=T#uluhak>PUלEgoYm; GN%wϛg{2|#dأ?WT~k8G)\r. Wץm6'sxo{vTEL4;4{fl19rxPś~  p~rz̹r$WS[L,'sp9,\^՞f' ,rsBěq`i0Cq}{ߌ?.‰6 VA|vO L .zv}O%/zw_{ϪۮA]|]OE_,w`[u|2+'ڡ_&)a~ƫ*\+N:!h5]FK#2QQpΏ~^/hUP B?AKfYjmTǻ/ÉN0{~jrYQY_[Ym8s]Gs:Q_\v~AK4ě%lB|0ibO{L*3=p$"l%8\E~:7ד_UK?OLtޒ`yD4[bcKt"E:z]w%/Il @w`' ;:Ur[{}Y׭t6+@f[3 >؎n\+;;@i%`IY OkgVvJx\> INٲ?rs[D:KA[RO7ԾKcIbA/Owgnj{m:{~l$#+i':_7_ >m3I=g~g]A xhܚVf-UVPx\ѶЄa|'{ח>׾ _xs}W4k?āޔϠ.Ɲ?Eex S9pCl^GYTŲc b4/$崟݌㔰F¿3}OO8>uCc{=`u̼7x1X 7 ~"X1 h`xũ>ѩWE˻4|#%|qofBsֶ&/{U\,[[[,Zyq/0'^͇>C>:ާ~օ~r*ǩ VA7Z%3 7`X,G=.'t~Y-=G; YhC/ã $M <_쓏+ˡF-] VJ2Z+:s`0 }ʁI{ _䜛Ǐ[3][ݛ~INc jΊ0 ѴzutжjB>z"p&(7 8œUe\iUn{@ ump’[(m,;w -YW`n4YhO΃GfWN$OSx$'7h>E{[]o$L+On|ITu>~ _97ma=Nd3 [K`2K6-Wq]rkx+ɞBoDP!?[׫:e@5Z'}89ݏ2ߕ{Xr!8J>.#֥/~ >̾#%V$O:2ޓE {|Dh G-QkQI-ǻuӛe*?{2׏JVOcӖK>|rz_y2~6랅q]>n}lp2}z.^~Ϻs!.[:.s >۞|%m#!F;w V0<ȩnh|؊2 j`]L@%{>$+ӡ<*AwߖI$0GrR'%yfMj_p2pگ~{' |L-]CRtw2^-Η'ΰ3pa*^9NG2Z 48ګx(r+Rq6<WnwWVqT{>Ab)`vm\B;f$]e3[9#%Fp9Cİ=/4ow`PII0>ӓ? Fp0硳 $U(lsV9|@JH\R3ڲvר:xA' :鱃+|=D_dnїo[6N! ZB݃'e]#}ՙa>2+9Sa _8`Ƀ`]}=`}e<4r,_pOsNw_A^x t4yc/)Xx>Ćsu'}%V)T( I}L3Sl*y^ҷ99lENO -+vEۀo{f]ܣlE8}ʜNg9Җl}67.@'%loS6od gGKP֏yuq3H1nptw!Nv/y)Z1~ݷ/i fm-׆DA^ue/o5Ż5M5k?|b6$Л.j؛ ήkE wHIA@dg>x-oKRumh-߯,W;qg?fhI*|Xcʿ~9dqO~Y{w%y]52e.:;XgrMAB_SnCdC~id6j&He)rY~>ӫBdWj4 p7)5Q,#mP:6mmYέ|m HVM'ط}&}3^R"\.{y1C HՋPqx~-=6#Y2ZfցEC|ֲݫy@{q8\!6) ć5f ,ȾX:ƐəF0+xw4]YyK2Cu8y۾`k{8VjSOrrU ֿ xKsmm4#R7:YY3~\Z_NbnlM}x윁 y#‹?t9#}wRtݭ_Hwj7ۻ!ۜ&mN7pǻ:ޒukˁ ~6Jg*~|}^8]ߐv/[F5M \9`|^#rwJۧ  +;҇me.t .,S@Mf&W>+P[?sja. BDǒKDgܛ=6>H6|:{.@kU[N|̆/u<*f:M 3|Vz?{X`e ̛/`ɢڛKP0qm[F<`֡]l˧t xod#e\JG!.@`~ x-p +2ޞ)}[+ *>M@wV@i3 ?_wX{.ܠs`~+=̛V)vQw!ڐ2C`&}![m,%ۂ\\f8Y%. d *hHl{[DׂzU?^^xA/xV'˶\Zcf$|!KemJ) o_{즺wr&a4Ve5sva2㓭 OgÕm TVbKƱ }_'7۶V/茀H|k(́/y8>IQ{]5x8sH.o66vzMTb719)`fCSD{Zr2lMmPzWu3Zݓx5#"àRʺΰw/iKuPC *+^t`srhw_`U5˱c`qnP 48|2]>s~ uA22q |> '^,O0* {-wh͑e>q5k-B#jHhľLmLDzc.;op$AK?w?j[﨧%e7͠,P }җ=wf坁 yMGGN0gO0G[:݇% ƭ^瀣O'w GlG|_$Zڑ٦.pSs=V?fO-Ԯ;>|Z_GP $̖;Q{ ->h^pY g+¯B(9gsFҧɃ i&dCf'Y=||`mvEA:rz[{fl YBgֳ[ɳ4 xtg~!=wx5M^^@=mXG=C/Ɖ}Fp+ vu㥜Vq7c|`.鐌Dqd덊*ǝ1VcGumXWB ;=d,6tύ=xv#T0et{E~WcfoHW/]-HU$=rM:؃-/?~ݟ CƇMzb[^Xs[_|/3nE7c[_sO'.0`'CYSo΃IV~F7:G=Mcmbs3=[xhX]4g17Y^y'5NoN[pϥlᗰ{lsdFU?>]8ݕb+PGs6C<јܳV:ꣾ1Whݹ(|#{K`Z<9L>fS«+N+^sH[R޲ ^ 6 pmȎ0}?d8kڠu.C`deᖾ=:gJᙁjj?r }ğW+{7/r:'^u%< 'h6C|Ђg7Lx}7F300l&A_UoA1GAnɂ e@epiPr,@(:Op%z{5Cׂ koG]ViVHa@Um:?.XE`ם^$/ËOCm8y8 |\*7AUx>r6|p,rR `%fn>50}+p;V)ޜY'|.؆Q~bC>j _*ƇʐC&ӿ*ϹXY֝E,p|в۶p$o[}Ksb戨zq=xԬj<'k<ܓC;2BVCsoBSQWh4Y<3"lV2q|!>lor<&4y; kj p~e:C܂a/oJ;p:f nϹY&, @_q6։[qIW{ۜEKv ژ Y0`?6K=I}'Gr3N~p.gp`X0|16o8qlUgr%]ls䤧}\ 9_?9͞ɜqG{Nn @b2>Û1NC?ں|+$l!Uϋ;e[A<+0bxinĿڏiFw~孶Է­ Ϭ? ,?fGR`M)_|:TEdM?.>Nwu-^ >۽^V7"}!V_l\PnHv-M-w}2GG/v  x4 }]p˶RvV #KO-U;+z'`y|qruF8=LxJHH, K::$%4!~}7mCWmKA{1~)xX1ҏo~<ҍdނUs4:Y+C-+Kԁ G]{IF͖Okp;UBxP>Ҫ.F2sYJ\̖k'g.}$5zھ#q_e=8߾Go]\ z-PA/?wT@Hr|v H~'ź?MdMVXۗ{g,5]! Cg_[3gM{`Vo OkΩAk?cv˹M^5O̟u|k&kVWH:sK&#]1==$$<8୊;o lo\,{nYdpWrd&5Op3R;ԋ<@p)A`V_y)xG%tr2ܽA0up8z=Ђ/o}Ë/t'\!W|U4N٭h,tN}6ko+7\7s:96@!0ï _&^_<7tSzl>yth?r%.&+6Jbz ,(9?Q%A.CoO=y_/RZ2{8 Ǖ r&|gxxl\Q Y!mOtb~LIsϖ< gڲϛ3ág_ԇ3,fΞslfOӃ IDAT6 rk8wh&AEV٬GjkI2+[Sr(`"DtQV>?`cN\_qО}OOE2o$UǗ#'";@9:CW,͒'~%^}6#Sw>/}6Y@܄?ao?8HtNlY\*ϲC蜌Vg|N֖8'&Z g&*!SZ1{J$j w~ +e|g;h `g |߭2ĶM5ބ&N9H\?\M4v-Z[!s:>Of-ڏ yQ10'DaF<@>rѵKbT^??pQ8ȭ[ʹwh *Єs!`U  dT :"˖|C"Gc}]k=@toˡo_[/e,5C7f'& dAD;fO%`WKmʗo\l?E+qO`GaMa߶|p  4ncA߾ష|^M5L.m,YF֖{߂Uᙶ}9 T^AKYcKY\6`̗ +V>O:[VoM֮5@ =ڷ~f+ʠI"`_De`g-7~O‚ MJBYWhw7]2?6{^㾳zh9.Ƿ~h_`[Ó:GHgSa 4=)G,tuOEm x\ 6Y -ooF*IQSݤ~'o򥇃Gx}Oxϝ݃O b^PL9Pti>+7;$^~D`mrd[3ll \_accL4[YB!Y5ndXb!i֒Ƈ3O59ɠz%VW]K"Uu:iB)֯PmN=#ʁ }Үe@ƒwM<,%Ye`('<܌d /AO\Y:om,P30=3]e;2Ѣ~o 1~6k `[[:#wސK?``ٳSoh`/ԿjfR"av;q'4/~[:ʸsK(0r߶dLh,`8k#W)G%~߬)Яy;2BBbEFf'Egٲ^p}ѧ_Dֲ#D "ٝYQ4V$;\CrSy:+ﵩ{d*llvl3IYA"8>3BJ6ʅu!\h{P.Y|~udzq[9E_57bI!҇DiMa},WI2kv  t)޳/[NĹן2HL2! vO]'=Úarn1kцwe GAf |<ο ^]8̩mY;ѷzG7חѰ:xd`?ܭo ~UjЀ`qs)::<|8s>~e}` ,||9dGspvJ:I@[u~ݯ5nloAǽWWr^1U[;͸i*`>Kuum Ow_ _xugDM9y_O`J_`qZ#t dIH@q庉g9K(# =D9٣}@Mz9$TF8t-=LD3%G}#| (ymMܶfbBeg= 3JgXO wp\a,Nj ,= ˖z[Dֹ/m ;w텖J$ȫqL[Lt'Tfj[5}-Z%!XwݫM\~&*#詽)dMtUTچ g:l ~$YA9x?ډ~_Q{}? 6m8l} =̌-oȝyʍ}LPHr`} DHI7WW!x^!s VT_ѓ):]I^wme~rs'Cl4T bT%œm fϖ%WQȂη;Ȏ-VxF'S]L6ze2 ucᦿ=_, ٲy[g8Ӿ?ē` M[i~ &Ԟx~ZuSN[Pf tUt P7u:4؛0 ^_MK@%*/W.[l:m: h)jo7]x㈠w I-9nˑ ;`.S [ W4j}q:?G3͹ފxE'ԶC>]pwh)a,#)|]l>Tm — 6~Ɨq)_nE;kjC˒oD… ۹ ?ƻZ}}BPp"hq6R$$-}-9). QW*!5SKjp;n =;> A9^@vV%*}o=]H<@B Bݛ3VpFZ"'tO nvKpY>080A_МxY @AzNh]p\g8ge'C=V'c?qڒO|іSnKw6k ?@%8')`@\ԕzš7,AܲFm09lQ>pnM}CNzŋʝ nbNɃ㫼\G@k&ϪʫG{('=|i߻ﮀs6Kh+^/pagΗ*Tq|'vk;TWd}gW<W89ݝIfM՞~ X}po|t`y8l@A,F6پxYoDSO}%bdp2dgỴ̈_^Jl1ln,)H,H`gSmDntdY tD2õt)[R o-tsdus${p-L-Ŵlw#N\Edٵ:if3+3}Skx<.%7Ȉ$޲a^}#^۹plZ0roi?{:Z*cuim\%ⰣW%[jk+Z(?t9p#ЬC䁃.t_ՌH(u>壐g(7+[.$B[mЩٴf%eغ]em zWGH o L 3#!I{;\7T~He/=DqxVy%5$ovȘmg.+^J. R1zfWĠ +W{vB_'+>7w =w_ԏzФ耄0г=ןM+fXʐ{Xx_҉wS'u?Ʌ,I[5=9'mu:{_.&'>!RpfkۤC[@תg\u#[el9o\70#%S1}r}h,@3C~~#Qg/܍lgZ|W/U|zF`G,nmlelC ׽遝HN-*%,j,9Ȉ]%y{2[n#7.oCkU?2_ٴ '1b`dScDzˀT5.ź?}T.'}#F;[%ɖ3 m}zcɽ n񤤔ˠJqkGI>{'(=~tꦞ`W0޴wrVlVs8{Gd@ǰso&3[" Zhnp9Txecp5-̩/Z-1]ZsЬ1u{jw%9;bK2q0\d`,H0dF<<[b)}vG ڲJrolEri~q9`dhԎO햞\@x}je+',' CFࣃ,9Y6rvO]zm^F!E\Q~9U,Wŷ1 YR^~;)LzƇhfm~XpEmX1g0tv:|Pe3 .^!:g7u)W~Y}"~~ثfi?}{Gѿx6NΠdD<s( > '?;KO{Ɂ.籬7\lq!~y{ ]d_Nd_XH'8f^|Rh\ -kUU|V{}CGcl>oITk&KlMf{FG+{S8>{8oFO[-Dg/f M;v`:{ "=oݻu*Q@qOG!l$=gj>IIU9٪ {fʖj%HTnʶ$D@u# ׋mO[j_w5v-ɥdK+ytSaL Om^0,x𢡊וW+Ix>Sugh쏌?IkzB+w-_=+M>˶Lht'~n%IjL,ŏP^:=O"/zOkSr!@.ᖑ(o*xҥ*ޖ@8PpO{U\=¥}_W Dw"^ؙ7]V`WaG^ؾ=.xpȮ`ABUYmjz}W93WerToa'׀Џ:Y=\3;`,9lfo =Pm>~.du[IƄ'y$m?p0[$B4ݬVHR>w[!^-X=O6WgKj *mr.}_ XI3= V 73;[eT vw{ is #A&xӽ1-"?!rsn]`۟+> NřZ@=Fʅɝ6 v=~_b*^Xų-`UW&nRh^o q ϗޮDCڶ{<+8ɒl֦k5}Wǃ$LI?SnV= ]pOf]ڛyEKYq+ɦ@ow?fR6P  jf@Pb~GÐAcg$ܞ1+ygڄ 1Հ۵CAKeTgC^eϳJ[DyG0R%N8ˌdSMh=GmA/w5zxHFٙ>3A=VïȣQƫ2^7siY`,9`e <8xZ+[?(uoTϫ@Vo_]``9}䍲=. :<-l:*&c=uCO[̞V^Y^,'~ok|m}': %c vazp ^6|χd^ X>#_y3'䋟Kx"Y˗9W ▂ vo ^PpN!RYN;^4K;/m|%ُNA}`[>p΁!7fc5`3=]7;8g3}x'ΉV4G Km~f^c%Opƣ`|3A $%%/^׌OSKLGepɑ'jf>)c[>쾠ڳ60 ^r6g6{vpp$"ֆ N7أ?xs6j, (P9m2[.aw?l/NU]C|G\}W7-i~>:8{g}ÒV㜸 p/݊o7iհi3ce:j n;13XV?f;qXUCq3ѿ|x,QNw5H@Z ' ,0k_OVi{%׏_alB=쾕gXgںy6h_\<6CDwl"dڝ o=?lJȆ klc-;1! 42ĥVz%[ign%{KiN7Γ35w>p/[$+Q@'oG͐z73ݹ1N :B>NN6>`>q#4s3 k?[uw[ɖ/.ɞI82-y_&&K-}5;/}0Fǎ*g87&>ha%|zcr@2b+zҁ_?[i,cO%5>h?gmE~^t+ >rȞ~+|s4\zJ$E{Y>=׾FU-ﱳ(z @RT9PpqkV[%;DYTvUOD/ҽE8'|O9%fG|Dc)3$ O[[0E1.K[~W?ӋϿ?G2_Ϳp޷͋w_xڽ?xoV^}́&~’w :95qg23zٌMJrt^ʵoJKYg(w'Cİ.ZH誙 $D7 G 4Y>An[+?]܊+';{glU}sgd$ 8@ 0b3'`c'FlH8B9eɀlc#$ Vo~|o$Ty}{ki֞v\.i.ir׫r.#.ޗI"Dp"ͬIFYjx@ݽ)?#xg};T)-|Wp0'8JG:,Se+o#.8;m8n!A*^-OX]: mv a(o<[ғʯӎW\ jCI=uLm Y]kSMӍNRè8&_Ke~ĝ4kx`,P|&88g`:s!Xi2Ოl'hԝvă%8;䳬!=|%MNWlpefkD1O#(3/|'N8ʢljy0iHeKYڗIN&b?$x2Z*gM:r(:YAw(8/ ":I ș%]Ӝ6HfL9!.Tk"3t0g)ؾh!CIC0}gC6N635t@ 890n[ ᛼/[(蓰^KB hi yw+ڗnZ$"'pnpk>;PrWLK *qi$9OГN]Ƀ+:")jC<א^y9LǤS:dTG_(#A,9ujK3b? B%-w]]Ww__f~|#^='Uwf'qN%Ѕ񶮼&{ 9*H ]bjvY'T\ ().+:X 2u4uL I: x h!Fٙ\M1{vK~ZS\2,yf dwWp3e=%]t2R8T}SW  ^YB+>ΨC8 kSlJ!ot#rn:9A>98jۏVyɺN>씁ytE|Y /(晝a b^Aw%(U:ylG/Jx0Zdy,S$H] NS=NS ,1hȟD_v d%5nW (:r;)icN%88  eOgB~[fq; dl'!>9<1! aRkGNEzozdUO~4\8)ϷDZsJB|fH9R ˆ|O6Iu ~/GoϴSm/Bn1=\?j^ y-A{ZX<.UMm vA6O (;<X7ރ5@s 7>lT;#U~ۃRۥ#& b`B'pNh]98u/M[=OvrI?^ E:2>rUI:|}hreA!8֗:aژbm|3hK4{kh f;`;0r`12dfx ,} ck?\ʋ (3ꃆL&O;h䍲oF|8g H0͆RN!}R DSdqeI6u:Q%<$ߦSv眶qh|`>u?䯫\f|%xF&77^*|UCٍ[ /mK{)OyM%o~n_ۙGڥ|u2ľ }}zW]zsn9k?/qpgRfʪCadD#@H0hSOn#*o FSƚjy+LcWj3ro f0M۰3ֲ^G+ȭE/ﷵ,;O{mIm%wD!vY9002HGb[t7 =ρ1y3HnUqLw}e|rB93` [?2;o(z!P6#ϥS :A |Or9.;UЙ<;>[T0~V#.L:*LzA#Qtgי+U RYW '=IHZn~6,(&0֚-+8f+ن@`~!:H8OJK'VL[aho+|ϝSo(~c@5|G2(`%aV:\yNIw+kfUM4#<ʠF%\*7<8c3F_OSxhJүWw:l$v9@e'@Ai|AgQd4fe 4A8:.A=!x $g8P!%|,Be& Ң.:"*yRNˍZ)iG?bCpU o,i tU?1fGCZ`lNr޻Bzݳ=NS]l=4eՕR0F.^ We)e% J ~QV<[tf%\e'n]PiY>PVd@Hc?c"] dU#Gh8 gBZ)/ᦡ<68D2`L}$/]Avo+_hSpsA"OW6!Hppv99 4+aev܃ۣifKq,<GIy}'+-+zĿF1+kϿζSW}]?v!>>~R;’ʍv^ >2uF/x ;[WƭwV M7 'f 6Fn̆CCDAs;铼i }qRٶt 4Pt83yg:\$hla!up;MYc3a1S$FOKF |E]fRy}$3}Y 1+(AA{ 58>]nuT >(O^aI?"3p6|΄.$;< IDAT]1 I,8ّA0 hilV*1gEW/*Yyr:ez#|'q#g#g:]dɗJ]_ʥl j_GE:z5pү\tjK+qt4nYNl?V; TŵNlwO F?KܲeC;C->Հg 3 iA/Weؿyk^i" H#o|-l=G"2d*e3Txpیy\a"96 Ӄ=+h+mCɗvFY MvV։=oЦo *#mO%_ n/4Ͷ*bVeq76,I4w;+ ھx F|]2l|ST(/PHKs!˚o\'qOr35?[?awE:Kc!@+@Hg\$,!@ zRDU_';ˍ) Fm!qi9ea^$bL[(&NN>zQټ[8+'ӡ:3@*}cV3tb:K'Jqi7qŽG:e]t+3gPgK17&Y Щ^)gʭ/uάH ёAu"S.LMWAlL%8r_~zl.<<̀nK^ڃ^z~nK:8J'{u?lZ9C^w6|/$Zg>ncFxy^i,-هM(STGd2u/"XLBs;x/:EOe;ϥ@ US~9SMxS䯳 ,K~:Yvac\WXC5+HxfiH__ؤ.:(֘NIQ cȟ[`OݑoL6#S'EvʐUփ$VX[Ho^,g9x2 s| gx[hQ>Ϡ/\zh0bhyc5I@0_2m?<<OOmfz\`AY?=Aŀ6/|w{:䃨"9g -nI߃/MuDtW! :+ .Av0mLjڪ "^"'uFU6>מ|dž#yҨON -^|umݭ|@ib$4dv P 8`^? N#`sPMG }]$\2/ -~>HK^9mJuKls{ٖ_q߿}=Y _h}hwxjěڽϽk:vwe_lKg>Gq ;N77I܆ױcǢ9ƀ :_8?O;vܺA6Wf:, j)YWƆ$'@3v5ƨ#$([&Q DD kgFOE5_`ϊe1f1JbXC/4083G~`FAy G)xv`|GQ<19H\[ ] 7W\Dz~@h iY+ ~MtK_:[b%y: {k8L" ON{Yep&zYHD>!ӏAqyk:Zomesf ɘA m@ÚY<Wە{a2Yp*~GRKu^2tY,k N"m 3KxfC:gyoE.8P%<*fLfr\Y+ TQ2Nԡ 'r*%|p\E&3_' 9)@H1Q6yR=M[C9?p2r Rg ~:ukG "vG/ۥATtГmS}cۭKB~ ڮ_X:Ϊ_;ݾ.(H3io>] ec&ٓ|vJs3v9O#o}e 7si{G}kjGOڳgO?DU[=ї_NCێbBC{[!uCis,6fYN `.Y ocɪ?:_W_u&:(F@~u}1t$U,n0q$ۙƀgu,W+4$c8P☙w`>ROp_ƟZhőoSs']a+:P~>j6\( p*IXc!(4*'.uuk5ZZ`ɻ{YV`G0v~w-/.0k>'.%Κfj[xLY;Fx3cG!_R3igV.}|[g6܀:ѱ ϙyۈ[/כr#gZ!i-zÊfNgnaIh̒Q,o@INr9%gVGjjo`( &(}ufN[z</4ʌ tSaھѠ˼Oۘ$HA| ݁; m1dpn"~M~+mw* Ra#gWlG9h:21e)KM|-2qNt_?q?i#ҹRW&R͈ 66/z:/$\ԑvm :3$~z3Ϭp6W7AnhQHҤ?z9@L^qD'f3tz,fe@5y.@р7/9Rjf}4!jokd\UFVJc $X652P\,F ~CMˠ < arŦ1WS0YXmYERHM l7Rfߵ0yA)PgNl`=7+)lsN" $\0 ~nPOmzۿ!3~X0Böȡ 0r^^^'H(]# ڹDeYLd::bq`o,Жi﮴9Umkp5m@A$.-5O^ۼm,b?pӞ /$xNW^}$2 m7ZKJ@2o3bDZQO%.{ MRI!S%=l$ofQ. {V-p2+x{ WL'6{R2om<4`o'v"6<3YN JwԶje@<xOQ᳥c ݕ*p!%$~β{.0Nm犇͂;o-܅<-e`*[Au}۱t>3 Пr  9x%h~?+WdE>rQvsh~{y9wkǿvlmg+cӾ{|~j{l#ۉMVvĉonۿ~38=1i',NvСo;wv{܃~j޽گZ'?G<hy< %/y Phs: xgig}{_~&Sχ?\oV4|`Ymǁ~`++ݒ3jc\@WN2FYA-R34b,czc/_W@@9 ;u:e4D 0 Uħ;Pm$ֹOK&i9R yN"ަ3JOPH @:e ' pZ \``uDG;bզۓCu}AK!=.uLu,|;{m2Էc*]F, xDEcW L;4͌4R^ #!~OOZg9u2ҘrTΠ!zGSyS)O6x*H%ӁZW{0=fn"(N+3A HtK0Wj*?=J>򂘇y"<j+:(tzA0rn/0u  H;SU`JYnՍ霳4avf=KO0,ySнf̠?eE/[NŚ'N g"bҖXM>O.E2 m䵜1N<^+syz_+{6H-xb[>NSrlԊ3<28^T7U(3D:caE=Qu(jRSv~ 8ॕs) @Uq<_gʶlH>I*Y.D9ttzY-`K2CnF1Lae͊2fX|]k!`觸[GASDY;h5qq oD LF|n*d^;O^<-{ۿ[̣C,y"Cpre:a]^:^<'0JePiRn$ ?[đO ,uν{Wq3LCi` ]50HMQP21 J zζKU d~m>? iTڦe 4mkRPo*ІeS:(ÿeN\BrL,U.m.'M!ݍ!ʑS70P:*,AHV_-֯ 8T{~c׀Ø}eӎkeeֿf:-چ(G6ph/zmmrv~ß?@/˫D*Yi+ r]C1\[sxa?` ?)6tc\pG{֑K~Lmo]QeAd-a۰ELtYxJY[[}6C*6:큖V/F l9%pkVv83ohG#^<(ZMbzžHD8xVofƉk :g4C8,JΚkCѳ%G7m0 I?|_ G>uNƒ*` IDAT[F $ͼ4,;QQ;!p[aJw|N4Ӭstv`eE-fw߹܏W_ k̥mq>m׎]v=v;l Znh˻_ [C<ٷo_3ENm~>{^YzV{^^/~1_W_r;/}oGmWWSM ۻ4o|'<ԩ׼=iOk^{mԧ>/| 88^?〃}kӑA 48j{נulkH hDb=u;X _,y1<۠ 07Stvy8dK&/އ0#@/,MN}ale|<.ׯ;`E=M7X?pH>zl[Y;lLt@~6y|9( Gvr)ѱ8 rhG'|\q=6%>+& .vuBs ֛(|2_ l}ȼJrޒo7`+-`1¢y՟ V7b;;@[NH%.C!'ۯLߦprs=1~|"];x$]j͢mSz{v;Sy6xPMq YΒ [gG/JV&,q^㷰r< J¯D*,ϲV U&2 `oO 'y^'`GF(^gŅ6Vlp W}T}Kj3eUl02Bg} F@\zx*g^53M>|YS:rvS}g@WMejP.7rvmC`1 ֡%m 5-rжmd{sRiTPp< QH̱=Ddl2س"EY[ o%[6塀ҦoS)Cp:f>EH&V/}/<|fP pGV jǼ*Dϋ$eC5٥4lq7O<,`2o/^Ӯ2!(/|(@LPt@K n3~g2rȡЙ%96`=}(YxI%5+VvßpBȷZ=uM shW~+?ж̝46}]z᫯nv;Ɋ&nw;d L{&e b7=am޽ 'MaQu/odIծfWFA8pAg,=mx3ߠߑ]GS+`ۆY Pb0ύA%pX g4/2ajP)G@dC!8er! 5{GRt?- >N/Vy=U|24O-~v:kZ5!9Nɺ+Cr$L,#@`ډ;DO:K%&p)EgO<>y% &2БyN=:Jw0Pgl`zu้ pDH%^iBn?ّS#:YGL_^IZ$Bgt>yjhڱÇ%opPڨnxhy`K9' % [`msTC88gzsDgy]4dPF,+3[->T^SK۬י :zy:!?8ikY1xHެ.Eyo1E= < w%ŭRCm~`p\f_'H{T'T>YW؅0/p(~R,oEYFd:+5RrL`|| ֌೰IᓥIk&.؅&zd {'S;8f-GCߝבVUx̖G2Iqrt@un)SmkkOn.tv @M7`ȬP}0 q 8JK/ s'|dCtE13=)d0(mrSQfe9u }IxJblxNC\qe# >r8v- yYf{ ɪ~rsټ-ǶSϩ|4up&u?z`IhMt lS#πzru>x̅t`;m_]o·!'nP:cw>B37K#[OϳN."hN}0c)yP( UMj^QMBȠ \ 6x02's<a\|XQQg |f4}''Y@~'5PaGYp'GbW(&Ц=hwll nBu*&էx<= 9uC?6Z:ΰJ@"%7ş˷4x)?d-_ w>@)-i {XdҢ W<đvU:'Qm~g]{SX䍲 Xj;z䷶'} *+;.w*{L8~S8h@gd%ern48]3?nHJ--_~7(0zy_+4uc7-'\ sk7"'W'|j URC`H+ 6Nr.2<upOAnp@!yo|-.>؇;ߟvu{S/nz]tm7Y&3AzP[ϕz9Ms=9C򗿜6)rPZ`=u|ڕW^<7 Y} }c0ۘ_fE[vG֠MD)ȘO4OdEaN~LԭQSOUYj 9N<.NAgEƤ p͒&)4r<t8Dv&~qdLCcnsmFdy ;l^-ʒ^u1|ΞG[0:֯;g䝠s}XUtt P~ L68.{Aza dq0(SG1$tYx r<'AZ-aKJy "~qtE ޫf;- e 8Rm'gxuAXt砆 Sy<[,7[t | .:Vh#FD>@] 2RLKL Jo0=+"㋮!< _ d ЂSZ o.z\Pg'cu32Ќf<zPbݲ+_pB2`Ff'8$KW7kljft*U6gW!q:hz[c۠J(2~$놬XC}W v"M#Q|Kn@&lL ["j-a =/@ Ԃ lE`>f(>$h $= bK C #9` xE%V{}bO(:ڲmڔ>Mm1 m9m-:yt.`ҥZ,ӎcUyg+ $lF+nCm@ُmK~qi sO;-"D@cVChazx >pm8Ůx/\`d0W4˺/ \o.'x1fD7FȻUbI54y9c0#d=- /1z1dysh H&4Ne"Xh0IVyxJDґg78qEX5Q2XkMl بcgKW\x'^d"=>㓾>+Z^'<0ѕ:~~:vBe=@|o$V]ǮJp/w#,Ї>UI?tk@ygrc`F_g^g '>6c*׿]>fadȢ{q~1rW #1{ŐHI#=M]'+i@/A%:(e`$@O_ ]텧uϣ|Lͻ$;1:?aJOyf A:"b,rOL0i%.eKB*^G4ut5Z:lĝ" (ٙk}^m,fټ/|N|wmM7N6]#tPDnD:ȮhVmOcj`3(DY5Ee 1i5;V +z~LD θi{Hpn'Xnμp G|h꾏atLA#O$@=s g<"ΖY'S#M-s%пAea_=,CQB=oUg}}C ;7e _L6CAJ;Q)SӴ`ؿ͇&颌qxzd?ɛXQԶO8=$vo1er oZpv&+@*78sbsr\+~? yz72OPd`hG=lg^$x9hN0g]e0AIɨ_ne3=hη^ܬW^\B8YJ- paQOgpr;t m6`\9 r(!t @;#AcrEf] 2vuPrxkcI;̲t16ܢIvfEpŠz;LYgOC'rFy`( ۊ8p 3(MK8d? qvf՟ҳ=mPL{׳L`xL)뷳*g&}#烸UHT~kr :d:֑ )by:#lbgh_;WDBI3䉗y ܲ"i87G6W3 DU#z&2uQ`+*?4VAst<ܐז!2'Dp`{ggTqyK}m~E]ZѣG۷v耿F4 At  ݎyurя~tvvhNbgZ]/G7mPv$6$ly>dh.4\2&m:$a~!6Qؠ13-k km@Rȼ6ng]0y4pRmf<^y.nЀww HKiAN7 $A]Ye4`AƑ #5*t9#o@5u2NVHe08RԯѶ 8xpW$;!93(d:H ۙ8Hc2dqB\vR/喇 8BO9:y<2OW7OvëY*e/[}ox9.O$EV!D{[ofvBƽ*_3~:L5;5䛌hsv=䒙ɥY*C;[Ұtɷ$p3\ylmHt_vif"tm-|( ȁ~uOfi"GK&ws9rKͪy󐤍R6--pQSgC:m1XWG?!ΧL=䱬Z꫓juA%PaZ;qI= 9 2.p9`4*XHcЂ[~p߁vخyw7̵6.8Ʒ?p{x 67[,ICv_2p=>x;?O).w| 7˿UzA o|ˀox39s`Kz <$t[nAog%ٰ;|x~;˥SA2KK T0X7m\|B@+\pS!T; 2q1d.1"er~Pg8 mNqL->J7S IfYrހ*aJCG.q# V*@>i>TC<_te;agטuso~t<PgRF -O;M%4pWPl*O³)Js ˶K5McpV+Y&౯[%0U_m<2X2|p@` ph#pH2ú b_KL񔳾q+U?SiFqRJ` /`G23;Ob o]xXEg g70C<Իtʨ^]KbK1oD yxf_  Z9^;x AneM#" k]ٜdO2I}egWN;W"/c&v+ c؟!퐷 a"/ ff7<|Oš\?LcƷ1Iڐ>O7X6bg6jpvVRƙY|s[> < Йq|H19 h팲NA&cZ=675R9E~~"Ap"" V sZl}ZeY;m U&- ȣ팶v7=Lj)qQTZgi;ef`q־)' Fxf99(fGɖ'A4FD>cU߮^o*@@b5W^*n-4G XnO[{2?9SJBM1Л4_Fb^>'u<nGrgg矏pۯ<ټRowfH{.Z\;ngޮlϿenwz7Wm^җ~)~rK<%ƣk¥cGBE6I0sk[xmə<FJ#tYN,GCWfN~RƠ섧:f`YO`vb^8Uu| ܜyK3OoM^.0+'_)-P0V)h\oջa1˻Էpk|I4׊ O==C,JW8$J3~nͣovK,MnvfQE]xuf un7O"ݢR:{xFu:5((F#lo+5'e.t  R<9&,7JE]!@˙"u5 }^ MG=>¶|%pG(2N+^K~؈Lx*:RRNGcPN+ug3VZuXD6'l _ha_y[z%O3a~8N' AF 驘8!Ϊ(>>vPd)Y!%AV5:Xa6VH;joϩ'mtEсD78$3k-/2k-C='ywlރ{9~̪jgR^"aE8:eJ u,Nz'2W${f/8u] 2D!:DZa:zI.p8,"rݦU3aw#38fg45c8X RF6y3)~1X3ŌA1?ɷp}_k+` #=j+ d9*epqˇz|OM_ x,.`{|$/L`AONf_{tzˆCY+'f7B@c[l.?{9-AΤlv*@,!3?޾}B[w hݠ +3g{NeYm_ z)p2ƥJ/)xOyf:tCyZMwc}(-'lSvW?π{n]k: ld@&A{MldmI8@t{\7hC#TqQ; [DP:`U\lÞ,D`n-3 f *ء% hɃS@6@!t|k {T'GddJlG6 rVjYpwiۢe,Z-neZP\,#`}p HY>a8Q`G꬟e@ WD8䞳()g䟾UؔWh+OMIyF^sr~|K.[~W Aη~[۶q]vMםchme~]Վg۾o{jg?Imҋk>/K4n18О'N*tAp2]u02])D!.{x1bq]@vT5<^;]y|nf4Bz-:rJ=+q>z 73 -Hzfg{SrɒZ߳"E Vl_a!30J,t;A:['pej+YGdN9,џ8xQ4.Ry$ JM8yҭ+FUN[03(H]d\H)"N$ˣ" :pv6+<.z5]uʁ(1 f,~.-[1 8f #Budv#QLUS!(hqd7'(hSs6!_WYmER`SfM@Fbd7e#^YNq AgZx+r֙D=:g͏^s emG%/g8X}& O$^h]CgujAMgrQЂF!y*,kqڄdmme6&G/ {+K,2@ˍ`K}'Ny^fpSS9bNy6v_21fe2s.gw8):vHg@'Js%hɠIf \<.ꂑr(cOxp+ =_n̴,ec|vt/|-5 r<(M@J|󒃕^S s0yh<7pg |OW@.ҸJ'x+= 5nL{]m7P(aۻ  _(\"e>WEXG{?An&E~|EF긍K^H28utP6aH7g?f|=ܾާhog9bgf=fvh{a]=m4+:r?.;/?yzXJkp|fCKcq؀w ƧJM~֕glgi ~2;Ð:mppTuJYpct\WNОZ^;Qә^`P%ڿP1,xUGA ]A5+t$0K%QU=Z7ǙUxNs@)3 yK'p V& O]x$ }Ư[>CD˥7]:_JvT,( !RdH5 HI,czH lZi$BtHc Y4[ %qlcpN:}9gu_|?JJ6Qi=6c9cyyrpB~78F_UɷK|Kw2i%s_&zxS__ZZend U9?O{z#'dE=dvgIOpB͘~H?/݋ a2Ar˷}{vKɈt}2+g@?8I.+K^3U69]DS»},Z 4ۃ.J'R6;\>ܹ6iڄL'E4ₗC#lhq!2_ҳ'6+7|/'*e:*iy|Tn0{Q] 'ϓ/9oHzUigAk{R[["`0py8lt6e_'J;Ʊ3|(2?"';Kx.tr֠J# IJAeNl[OLh\.?Oqoh kt=֬o='_o?'/ſX{_\_k~W¿ѷ7Ǘ_˟}q$f>|/_Ǘ76pK?f*#d?I=*u4(YFx԰AXGS$t`35EPg{RzmtpXī2,StH,ePMp~l0ֈ]#әuCZsyvr:e}`I=6~puן!IdX]w:+Gh-Ѱī4fSܧjsu|!h5_*_]=wh@|lr`(Sow0w}Uͩ:UA_.{/:WVȡDc9BF {QV.}0zO ۳Mkpdj IDAT?XCNAYۚ9hW\T_umZ͘PtVx% u1]:fjP*zs' TbHq8='0 drry-_F"83ZAQmR(̜}sQ -ׂ=h]=F7:ɷ.~b)v[uQ@DJ:ӹ2u;x鼮}5odAMit?Xt WW&\_OTAH4*#GQԃF^!xs)k*?d r4b_*n//~kՇcT,yY[()pO O40U@myx209No|HT&Q;kM6t?gs3%g}x&o˸f4*#_.0 Zz_ >ykDt?&_ndb(#W8rzVvato>UG>wR4lz#_.d4(mix@ sw]ox}c4mή6]=o>!sG\>AοR`6A#6i[_n_jI$&5挆|51NkS|^#[e|q٘ٯ/? pĿt Oe\faׯu%hn10Ξ閇.#h+a^ ԐWQwOp˯ӆK6xUC>=+, 6YٻZ Odɒ{{7_@~h Nl3*ؠcZfbeMPx컥^Y1_ ʷ{lx)k 6Zǖ}~ݾg쟽|߸h䧗?˿??~/o˓*/z·ӿ\$u.?^=d 8HNctf;@ wdk8n3wO3LzSсsZSSޟz0=5:\;PpLڐF};];\^Ū&G@lwpDӢ)uWN]u8'5ތ:w6b+)=QK'W #&J}MK{Oy;4ottC-UW74je1KGW%P2xM&>h*k`@Q[GvI&Tk/A:}q^ xG=+`,=|v gs[Jc3޻Y#+Nv^_`iCѲzosKT4^h lIm493*- #.&꠲f0]n(eWɍp1c4y.7xtÙ?9G|xo @{^qE6R}:w ZB0hrTzbd_ t]&Z* ܜP0"gڛNow!Q}[V٭C_9*t%x̊$',A۳`=C]iĢ]Wټ>>ٺ>GvL&*'r9&h+aS;Ƃgez4нF[3z3>_sy6ѐGLjI^$Փfh>SXF}YsN~aA=ud#RK j5#f6wr\L&z6|][v FwMM}6.سAWo£]U ԅb0!<8=G=}f'*s>fx-.ɩ}@9$s_= 2,H/3v_ ]pSٝH-?/}bK}_zc\gpiU@ܽ|'/&\.yx;g|:`8PDN!95eG bs0koTTgD٤fN))U1mQ%wueE53ۃÓe">l]c#1%]CY \ZsGx9)"ߪn7Mh֍ W9§-w;:߯0ިy @q9 ]"2RhSJzT^~48WO@WYKuuA^ˍ"29a#dX}7Fbhݳ-kkBv_[)]qN)tْ4l~`׹P+0+kD&h]ww봟l#,8KOzp[i[tL(,{M.U4=a/Ks^{J-w3D~0]Qxie|d3r _NO0fXW*z$ߌƕ'sr< 6Dڙ~F^èK7`ca} zGc(G-b6ur{>sHf7>K._njg%g]1a%P#MK3a:[|ЎBKe }yh~smV2$k0#2N8ОB@Žmkז_5rdD7;)^^f] .G򕯶t<'@h]svPzgT7co' &4OU},zO.q#ih`ׂX_9vKu~WɇW9. ŷ2O#Ј>wsfbn$.'f&3krɃšw lʁJϒ}Pb'/wZ'giz /ES.`@ Xjvbo}2,)?bS<Re=H9f=f<"quOV|LKK66ف6B^ 6ԔRx96l#Ö8?=!}xNo@(Ч8F g#Z}vȧ'ʷat*T?֨ nq7-;78x^n|" \L ~־|h6%2{6_vA/XîTMF:Jk 8?'9ɂ=Jc!e<"H@FK+_O/>%{dp⑶%_? ͍/ȵ:6<,+U~QCvc6N)`_˳{ot)ٌ1OP|dq'=(> =o<;=AJ"E J+rꍚg=0yo:7%ziŋ0ލ?e["0bJȇjzPTQ)[YpWoU'_k4{=Cw 9挞h˓k2)qŔqѣu/@athoOa+\rѿ- 7 ڑ7_tMiRx#ǘp 2契<6Y+9:hԹ9́ˑtw+ ۺBP\p|2(|FmQo䑶ket1͜z[uQ|wf)lcӵFsT,'F"?:B]ZSEg>'֊$JAT8C;Ku_>Ӿ&p(=' '9sJR/>VzjW'PJ.ƯۆȄk tn8,Y1A:Cc BlyHx^>^@=h[3<`[bߖރ˗e_iNth]Y>|&tBC_!Y95}9t;˳NK89_s/O|@M%m~B~JZz nWzC٧*6 ϪkKΌ2(q49v39g'\.+8~iU&cNfO2ѫtSќt1<0L9] ,'O,8;ױpѳ&gKF}9bRBq$E˦C.Ix[оB)ьfWpun>qGtslC|0O]a1/ > Tch< u§ƺ-84\~s #>Vs#8D^ Y9bM"Ɵ[mmxldȨ6k%INLOGdsÕwQj|%'L0 FG4G 8DiOֿE[>$]+xr1*kX~5,kgOH:#Ӕ;rl-M&}t^YOۭ e9 :/u#>mFG[FOyZlg ?;G?9[\,:h4G 6&WzLۗ I\9 ģ ҾK^p\Q|sYqFѫ~np!誽a/lKրi|2( 7AtlILGO/ >q;;gOR7|ʳ6D(|,AKAT9o3Knw?xdr҂ 9(AVc^.uꟜቀ xFVC/xQ̸qKٿkԣÜr0G%ȶ9`Tn(W6mnA<ԍrMGkKbNA<ݞRJurFHxF]O1`+T@qݖG1ɌƏ=3ɢ9C # a1 [V3 ̜pX6#xRڤ(҂cպw3f8f}cp{p>)F'%1ڼb)\Yc6 ]phhiMS'd ;(x:1ŝc98:t&y~ҭA(E'1$n3>˱lBG eKtS9hT9kW$:v^9#'%-GUZt sEI`[19} z͡e/,-/rbIrM| !<lA<׶O.X^omkh *ˬ tЮѱ{ cnyOA>&?8 oϧՀ`ՁkD KZF:i%xaqNrW d%/Q婗p {<5z'CxVMoMN׆Iga0E3K gF <3#=f*/A\f4}# v0z |7:Xq]";Hp6"TݽK}їgodzF_^_NtX|n>p;BC4C{׭=i㊥z?=FuY\]!9N֭ېbpߚ}qze;#!LvUv`ʹcֹ^$+yF!Ŧrp"32 'Я gD6{ZYb4;6۳ĺ*i`_ǭ3/ݻl 麩æK}H7G-9xf#M/9 6RAeħ-TWޫ?b@,9OP~{$L Dk P 9|q(l$m޳[]!-Mwɨ;7+{t7]+h~|2z\Z6 -fLn{(Ҧ֟LJ>FqT6hF{ hqԞ~7sy=ZgFfiǃ9q-fK`nND'{ :g7&8?*Fycq0ӾS2gDNh'הfdhȵ1)u>5 Ր]k)E_GCAըw#`}xCoGsdթ2R*a99W@dVJIB7 uLÛL7EXvt=:<8Ɖ~MN:oGHR<˹]aul,_+(YHj3eаcw@حQerƣD#u W<>Fz IDP%}"J/g 1NI|1% T$sGercz3)o2&ɇ#m#$j{ݯC3rd ;O#Y,Qyx"uhFa2r>x%Օ΃+},+{f>D?^;,a_Y3,8N/ّ7!H{<'3-Tg]1|MV+Som"X77RF'H&WMn"IY07ydzP&[t^N- 8w'><{U06(4Z-W? mO\-}ygieN%}CFj1 ]x'p󦫣$-CdK436\cV2b:}3^h8^ÖA1xfk5cbi8_|磇-#.>;-h4Exiڧ6b̆>(P~zM%x$LnLI8ҚAqfONI^]ɂO:-d.<{}Y2XsAi@ fClkL6ʎ Jts_4ؒ$/:~e6NmS#TYI_l^{QTk4M~IJp+]4X|wxYfD>8d]Y=ޘ"h8i BInfrP9tfC6@/GߡZUY9\ٍ^'f2)C` yF ~gAJ3}f@O] LФ o4ާjh>[]PPﶬQ< fW<o.xp_o6Xy'suG@ rX5c._d4Siyu{:E;d8ornr2W uvOV*GCM0LDWԑÔp2u[g& D?j}W6ٰo\%)݂Wރqw֕qY]Q6:< |?pաk/5~pd> Jz.ٟ-QtG?tC?pҗ)*{'ד7i&cx$aE} 6Cρ_>=;YFb]o[m" /S^ n]4=Ag m*#Kɣݗ#3е2t VCFh-/CSZbp,H"g{NnfPvv>!m`*Q>QI] RvH~_V4P3!H-ZnF>ɰ_}ٙ۫p_ŷw?"̢(Ӭ/?"a3}j]gt?y<+|]KN*~7;Wxge'[{הӨX&x F]n:k&Tw/-96ڞ=U7AGЎʢ}{qw zY_m݁ ڀR OW]oQnwMv.z^4 i(|e|Zs^k2Y+S_$ܕ/Xx&Ƃ rz0Vw+D@Be|opli ,ŋ{apv)a7{ ~UC>hJrsܥ`6xgmλ{Ʒw/YHdw?F0J7)ٻTGB;> up<2W"}}of>wv^ rUQuvLg<R# I{.,k>c-YCi7u'GOZktʿB4L)dDS2nMYzudJF8 gj= Whesm*4Fbe8F3,}-ӡO'<}4֥<9LN+o53%lH3gpT:+^stoCutGK(?oq%V-cgNķAy-}(!Q9Up~M#G:(r1Htg门{7y9N=+7ͺ_v͌T>ML M%t(._s2j+OOU8B9232F3Lw+ uAcrx<^`X%t[M+WO>,Ë{{5bP VG־KunL19)o^lrhFyp@o68gDyFic&O&nco E2CPCaz))6{jS`d\ྼ NsCFv|_X =E|HU<1equ/Gѭm9M%G߫~֊C_<:3>%6˰~e׼~?<u8į{_ԙ{F0ɁcH_;1xrBo }i8 <>L#R7[[)ze)`Y^l eNs,\ԕoOn|LOEƧl?'TYz 9L#GORy'!'yFHHg1ǪKbT9aA|߈xOJCV|T|>E(UgmO_>A6Yθiu5  3Q.ޓ#0 lx#RY甫7;A1e옎* 67\0p~ OE7,]=[禣nh;=]`UhF7+ޝ^ό2'sHX`3^[0/Lh cS*Gl#CB*3F7ߗ_{vCS^V<,3u"}HyGj >~fO ޻M zNG`xJ(?ALOA:N7˽?|iH׊Qcz4{Z|u(P *T;77qC2~ݯ($e\9:>!+t/LK'72wfA`xG]P*ѷysā[@ZCq9F"ca4_74s59k6tm,/{LB{x~i>gp .e9\)ób4mff9m*MϞS<*fuQ)T}v/=52Ss bYMY#*kGt(sFׅ:qf3<'OV?Z6 kp ^h jH^ L4 $5ލ܃O HY_'G~~4X2z(XՏlT=8*krN~#W|e\o9Ѡ^zL󮋌( ֪OdRs=k\pRr:?QLk*uM_M!Wgrj# >q{_)Wv2lKWl aOx e"3MVԣ= rYz.C ѩC~騟~36Ȧ|<8meP`t"s-8&aH-]~RQz;N?o ^=vL5w ?qujN3~rFLeᛌՓe"7yh>~ =3UG6!4=i][M/V&ѣX&/3}ݣtZvA IDATfeuP^h15`seӖCq{LYBf6s-{,U"-}@=oN4]d\r9mZy疫LN|I-dtœ:} 9K'ӾR[~DkTTib&e1st h͌{29D\lmn#9ۡe;#]T`hu]sďkP|:!lm` 4 j=:~њruA2: F-P A5x6M *E-8s SG2Y^e)73cr_\J^/t Vd *K^N[[z$ډл~LL^6ު`]z#?`Wg+9 h!=o k=בí(8lFMW;~LqT'H`+dzϫX9wyP쇌{6RǛd%i-c1;~k'%raO~bDk57G$^W>SڳZPwNst ~ /p,{X85kg. F<~!'N=;oiAzrhesgkAu8'U7\ҬѨ~̃ _d< ϪOd>wԛ@[iO?;E#Tjڣgre9r㺀AhKSwG *1`A@ A2My?iWbScF/gM__& r1?x~~c.{(s}Ϛ3<韋dCFm#)ֿuVm5«TA68PŧGk bEzz;Ǟux'uw0Fiuk&C7MGOaA`çA<}\_hk>% kPcehSWw9GHkDwRC.oǗo~:gE\~w>~o ȁMb(%jv u0|sjptF#<=3zNnig]WT`Q,__'Z2K7dK6pW-uաϙ)W@Jȗmt-g):Zѥz?M,S:O}6EtwȮ4byW;zSy6S#j-x_F<<`)OC[]-u {ȗc> ]FГv=iq=~## Œ'pV}>SZ[CkJ<_Lcsl朕֨FDJd:~ď3}a=>6pgmNUgyRfH'r,ÈgӞ8ΞMUu}~ph{P*gf̩ҎQܨ˞6 7eˌ=0qsO[AC=m6-@КڽԋY*[IňF1X[/0MΰǕ\V{PO8eS(|V}ldި\!K#Yd ok_Jk ˳ gr&CY@On9 Fwhɞ.[j߀'\m12FF_ڠՏ/2^p"iLbe6ldK_)H03z%L?zZKi 1rnѳ(>QG~;vH?V}P uY2K^3Ɍr=o+{ ̴x)#M&M7;-o5^,э|F&`g]GFc ɧwSmI| Y/͈m틜Ò- ?+ڕ9Y˾`V}Y4pDWȫWn&8BuF[MͿlf (36*]~mep T(zQ|Y1b6EVgFk /mhZ]gK:X,=Am_Y¹͡bx34^/>V^|/p~ьko _8܀(NkG@nUEҷL'GkPWE˂OKl n{Di A-w{p7c`{ܔIK?n\Lwl\п<\{~H9ؼ;/}./<)Rk`)ium34^^>9@õq'sAH+/h]Oߜr;iGIn@E"A/vs9-˦鰮7sfP68%ߺ9LƣzfJxx~KF>~}S^xOF2|#ؖH3z2HNYYW63awF1ȏ#9nsd@C:gL }14.貺^1GdK^k77Y_7cb>2m35\9O v,OpZa챠[s|dR_3)/sFO=Q=)|;#m'7 >NwS2gO^&r^cu`d68+s9BOZ;;dN=cx(:rXӻۗ?= ߓO&X!YgDN.?=ѹ5cC,:nl 5(D`Əct \:hX`ǹicpR MjsbLOCKu=FﴇWBc6RK&ۥ ZۜU*ǿgi&YA{ܓ=fFl= F|!jBީ~6\NAWmg{9^#Ԃ(UJљh9~6P\p:<1巶ݨ8.gPg&3<p6RvT>|ŏ~sʱַ`p^175T^mQ})P>{VG/$r/whH{=ٿlгAOG,^ VԦ#O98dgr^sT`{}^-Èp[gF+'$w,>Ch5OJ;\F[onA pl.% ]ʶ( yflAx@ teޖn^Z'1`KamV0{D߾o_៼|_o{]wM)?_{/?o8 ׷Yb|) j(4ֶN=rh:֎Lqތn@g˶ܽK!O쵬;6`;f *tH3@[_}3SP:|œC3H:"2g;< k^g |Ό~V;^ړ_8/7Cji V7>ʛ_:n~Zz뚁ćqZK݌o8\Wt7e7yq2')k62bn6zS/񧴾̀Fhq<53*ȧ6Oxh {Zj#z3@3z}쭝#z|JF<E@ٵ.}hsϚ6Is<}٧C>ƠD+Ma,9Mg\~y9`9W|o}1p=d0{#7 xC/:Q|сڔR9w3 wX9ݕTm)|᱖z/>'536d~ҖoAOF|/3 FcsE1Td >+5ehbʇ[63b8ҕɆʩYԣ^Tǫ>< l4g^*efk7 ^hWRprJ} {~N)uW~aMNE` ̳Ȱ?)>pP%/ KRo7}0ϳTk7pFg}FLBgyԨ4! {L[x^<^ fgxnzgDe_凳<'(~Q쵛HkT=Am8(フoU>Ht *vwZA(q܏^Ę鬲{/Ce]+h~杕yE/@ fz᫊o[#a9Gcu*,y|hK(s6վg7oko6\_>p jy ^|ܬ8 `6_ y>2 ԯ>%9U] ҩ/Ώʵ q[V0ʊJ^]_)AJa X9Dh!ZZq ?lFf{r~32'kiNZV0ޝ7g/ hC^6Hc9ƨ[m 7~U+G~umSWxo|iѺoy e?R-kOcLjyˢc|u?XWr;wVǡUa./Sd ,Pn.Ax1zE6Zc;g@g\IWoA {S׶K  2Ey㑆:~e$s66sk=#8e`ei2W<ܯqf&6MgW&c/gh*ym5C5\(n)ì@(W]qR dH_7GZ' ~_˷T+͚jŴwhBkr efv)y<0EWd=$ز_ɉ.(;_d'[Fi"xQo4>gx!wwPL6|: f=[CNKc99|zG7~ \p{>/9:Cu}$ӄx 'P' T5]6z<O |Qg B[4[y -|/aAgdO\~S}o_q~$}st&O2/LqSk(pzuޜxPdߒ  ̉1A/y<0u\"UVM2`4quce|[î;kyS*$3j{fЕSXߌlǡm4ICxq?)pt +| ϣk .D[4Oanztxp+w҃sL7Òe+z D3%spg{4~@$F{t9*_rVo'o 850Tg]#߫ ݯc}P['+9n8yyykɅ)L?u~9筮J7{|cm,%qC-T7;@Y:r=';o0RyL6'[ᩓVF1,;P Dte&?&^.Y!F2xV6ѵQDm;_]08Z#6fBU+I8~aoF*IasجAa1n<,plnGE޵`=G֣Ϧ~ՋWB#l}Ug=NwshC; b#hǭ_r]dCm}ģݣ膆:3r95iQ'ѵL!&s ݃&Ga'4{\IKk8vSgjw@nz#pWu2Y0A} V׶LWPYNrR^j=;okF`ң\o'հD'F-WYoC3ZJKy!fX` +1tpE:_V%7!NSG`lxa&Zt1^[xX=f-7>SݡSeTІc~R#6PT*!?r7{E^\>k'w=g/w[_Ro?G ~s??w0F{sLg9md!Ih^@F1z.3D8e٭k1SZ1#l7,ݟ(~۱;I ))"H(L`TP T3T"UU T& )HtĠ  (Bvls~w|ޟq$Q>mZ{Z^9rvѦ2v:&ZCYy>Ezt=HJ_gAcVvLَѤuaf.gCp)YYtGpx2N}Ş5LKt3`݁' ̋3VWWŀuu~# Vh׎f/<A{3sGONnԓώ(K_{Q# OdcW7xFT 2%`]%`Q3*1^s/ &8kKg?>DMÔ#liG#P5#8x/8(Un0p 0R@أxgS6}j1LGiQ/d4n5uFdt gXp{F.n]f$~h׌yBdR^ߕw-y{sh7C:8txO*ʌvOF<Ҍ.F#TzɟD6LT[9lNGDO\= չ2]v0s8o2^ $l6sNFѣNGqވ.kQo2G $~#fk/|\s>x8ùg cx`c8ۿcϴ!Gd}LjVHo09]2SC# Q\ g(\u$+Yvwm>3̰HTdxg#=Ͻ/[BwߒzХ:[Q8fTFl=5ک: N^|GSs܁lg:ϳp@Ί+5=Cy՝!*C> w|SiĮFi}kg0&Sw&8M" $:<~@$`<WYWshK~ͦOwҭ_ȑk!-z8·(Ig x+מۮJ0@k3n)zaOgZ᪑8O塕8( 6f)'y\ԬSx"l]xkWAlҁ9z `K2GieܲWy  8N.Э. ]a?o0Ρ hvͳ=pƗ3oiKw&+e'2Ms|S~Kv>?ǟ=}oH{׶޿J7c뙾OGD^]T<O=zn>я;_}/?}7< ??kžfd} AЖtdk5#SGLzS3eZẁH6a$)* PC{| ʣ&t[[?P"g%Fx΀'gC3g@rm(9+|(g x{%x>ZF %4u Hi2nn 1s^=r:({F`8o*xs抋ckG:$"#8d&0M8)펠F _ , ?B|{N(|uGNdq}0*ŜC6f7mEHKeN(ݳZ[~DkZ/*t Of0ڔ.Q^}㌂aYd?qj-?>ѶQ- lxwyMٽ֩OD:ޖO[,Ӑf3om9h;=-9ɰe 2Ffqk{8ʂ(#|g>?sӽ}zW^&[e>7a{mAQi=DIa$Hd1|RRyh،nW_w^m -9K/xlD&\hd3^LN@xfM2zF)GxJx}omeCUМ}LUjXd,/޽p4Sbidy~#3<]FcsFriѧqUs}r~k"ZSų!q'X]dRb@HYbbpc{zLޜm=S@nt|U~[F 0Anq|s >#=O?n+mFֶk9ʱfOal]D'?Qުt];(ѳPȸ=]ye*~xdq# r:ZY98 |@ [fZ}Fm-M}C/2އLtӧ;Jzv ӱAHh,!睏>{P>d.!|ȌG J>(?릍O{}g`Ą5}/-Ys7Tlc@ |I;|a:fo/V W-(1~OR n7w>}iwپGuD&U1~!8UEzGQ>#d__t LA4C8`z_`SI>e4$G6!Mޜx}:osC>VY HfW.S@)= zW~K%*^ѠgI{$(56 s/Q0]Gպdο[]{1y}TGSleu/Rث]V#6s]{j3uIvԹlYF9hՎe퐿`e/~AD},xՑ=Ϗ˯ۧo盢V9r5|泧/fӟ;o)̘Ӑv`4c1MfFVh]]H֙<.i4=[䬝`1_Ǩn y (é^.I)]dCp0Bߣv3#b=]?Gg2>gL/Ԑ+3 w=w#gߜ),Agpmy)*LS9Sa?F3P'obM&o>u)mAq(`#;,X[^xib5aѥJ'1tjgcx{' vLfv4=_8f,+e*S?d2KBAwW m XѳzԷQ_dF|{@؅RƓYjxfq2S` Y$z?Fɫ9lFq:(g@+Hn`_; ^F*99ޮnzk.°QJ2'8s+ 3u~{%ePz ~/< T{tw Y7lp} .-}hxtv"@(85Ut-HƟ ~=g>98,iS{>U?oxog^9~ӳ_fouzO>[?~]/q?Ϝ[>|W-k=rkiտz2 T9k>}ӟ>}~2??ywӇ>ӟbLv)/}-}-8_̯%~-3jj5:$Ű4̮R 53jF@/ ]'qfa]no1.:3z6 DKsZt0=.'3]G7%B!Lwn"\wGʑHS+^ ~Jzy<#Nsx}n旀j(~APE;*eh鐜"^]c_{QGAbf|ήh_GtveL XUX#-9W~}l/Av.iexE&_pSMHD_gtzwBE敁^!OL! u2jڴ3NFy3^͞/Cއ@‿7Ȍ`o32Kn4X<܌N|/z7uOt~vgُ~Xţү;rޛM~yNc*j2#m8gq7|Qjcyg8jkaC$u,1Yy wߎWws|d&XAA 0)DX_6#t4R9;eUrڛ dH'Gӏu2>c9Q쏴#ŷ^xN(rz?,P:^q0d5>\FzLs=׫!mJ.@  >lCAKF M}fym sb-s ͞[puf2n^|Ԧ{onظS=%όO(:2]D<] F)  B~sOWO'O/i.*Fre鉅xӥz(F)D7\j wl@wOf62ş2:p/lA%mq>GW sMh8rhNQh2Wb͆n-\G.*82uA e.jލ ܦOQۓTPC7L.UaF 0Xˣ:;^Lf(8[b6 -ɩ"` ="(oLj7A[ZFE_I-=w`vt(~Sbe-78ZYJSD}#yjiJ_{,$z'!qi$Fq<=g[%Iݾ/ \{JV IDAT #A*ח6=>8卶MW7.W`p$،lОV໗mm?}RGoHP҇:.y2JHfvp7@0VK8rDP\< āLE:^5{v \]u_ O|t ˟_~tz>|<˯ؔ_z/9}]WMӧ~''}[ejjO?S?u'䟜~g_<ȏփ?x]T>}?N/fѧ?gv>25}=Gj`Fڏby-h\; Q#(_ޮ_9=2Q5B8Ԏ !dΨy| Оhe0$KpnǦ*Oc:^p6QxYLS_s&8gzP y,ǨtuXz|1"~]R :ڛfu.:=(w\+s< 7_W>FMߒӌ>^ڌz3I@푉lp*<]gN6yt}j%޻'Ly1v=<!tn{Od wyrDxK/{rM\ݔC^ f_s Ĥ^lE֮BJ@mq>%(xR2!ʽ `8R%iD)2[a \sh+zCл\3xnƋ뜲sKpzt=ߌ 4EH?'8Fp&KזϱzSkD`|;l 4%J=n5`_ۋ[쓭_X)0QY%;}@zz}`Tk[fdw4\A,~A_E?.meTl M-HSi+ۖaM|/#4 c(е uMPs%E} 8dDj&Ͼ#X}U .X8l?d=Yl9>MY,MgheUJmBrmFwkkI?VթJ/zr_ & +K%]>k ܂kߥxj OIҕ 3C6-]SG6R*?R,ӟ=# \e\ 4@]lĝM/~xEڗõ:޳nU^hu HgIWsһY? OZmJXYfZҥӍzZf Q& ٓOf:ܬMfVa}T£ W=>W=Nnj׊~.3_|_xmgA'5mO~_ uzCjO~om+p?ǖ;;O??pK/-uOo}_ ί, uHL{;t!G#?Zfj[ã45eeq1*3qnZ57f:'8qz;:aUa=+MVG }Ss{vt$~́&6>\ױwt):Oe+?? V5C2>pK1c¨™d60aƀ%4}P ^{p,?S5Z&8DqypMn_t1Av -`vGph<񕃍=욧;WHL7rt){4νW=60f靳  /^rx < qޗ(e$\rAmMϦ!} N'=:n!9**klv}4¿TǿfDew̅ۍ_&|*ކk׃㡣Fd𕕳GƳ= &nK,;9f%*m`ش ^~Fs/6kd`i`ac2 ^&dۈjiߕ~A"[+||G(OZ;4|59wfrh_9(T;?:U;'@r9JSh+Bgnaa>kjnk+;*t|[=ѷO@g9!q3l&!lΐF΂F1OQK@D $\1@ƅkUguN'uL稆UWUάv3Bfcѯa샖lh:C@CќGSayti9@{_w,u~op`E0y[~NoxzN?N6gNԧNMk)trw}58x菮`?WEDۼ@TwED 3Ldȓ5^26GJuL){6@ks\.FXyt?e8A<{&)z4RcHᕶh?(. H0ʷa8`fL) `)G;G:DPfJ\yU7k_k/0.֜h8vڏf%nRӿK+hS9xuv~L@ + pn&:K,PBv;Ww%^}~7}0ڻa9u7d<Arl: ;F rr|xXG)귲ȏxfwUF(mj32zGb=@:>: FiL8Ϯ7; v8g[}WFYa!S>F9xT?3~N'W݌ M|קICHsF*!?mr),/佼6ZCCK4fh%ܒU0Cl1md}_{\yɒ9p +(365iAg1l4?O0Zfz]_Vm*xgxrQ0ϥ2D=;dekPz8;Oh|jd0ǚ[5_7]Mūwӯ):=.KO q/;ѧ OojcF/y [Fg8!+kC$QqU}x%ʨǫ9)<27 X2Q+XknQ29tV@?vnKZ}406=lσ>Y4y3p~u3 *OKhno (1+o &q~: p63=ڟ`}[<yPG`LGK0t3ֶz,^ DwMZ_s8F9c%Gﺍ轑c|/ftݳι'Ղ(r\ g=?XyHA}\f\idY~C<w$Y\/W{S8ۆ3 {APqcf(PYg:eSN[FÁ]t 9F _<wVw0oQ3گ@H?{ ^踔uU?;tA?9S騴~|ӧ>rӧ^ypݭ{y )z?zsxt>kW ӷXU2~8o즚^Ytjp-p~w/s!?{C}M 6W#VSN63W721]z`x4HX(pf-3ʫqJs8!SL=#ʩj$„Q|3q ES`J"2 ÜR@;P:9V}8UЂ{ ަCReuAx1->dAFtafPB5~%R` '|r a#X˳;ӂh8GFluEAU #XTg:GiG;g[o `ᔩ}{fEWtso2hyF:8UV3TCYQYGZͩ\k3g{u#G<83@_-of[F؃{/[M3%/V68cA#8£7iF+sFϚ)~5o4>T7nFd*&`CY NH{z#_Bt(PM_йFnTuY7ϸ1'^/q?ddtUGtNdHjOgꗼ/^ɦgh צW`?F*#\+Wt0`1saB{xwQ8z`{8Jswݫma?F2Y.wwa.S)T '[rPpeHCY0\O++ޙ-a6oչḿ=%bqEL'}@g߲swF{=GT7':S!AJ#^` 6d@33 rݾڐA:sz̈D!) [6'Hҭjҡ#Fwm卮7k?}@5r xR9/@EeiM?_p_GoD *!Hsϐq&`߂Sn4c jN}Y.;+Oeiӳfg F,/xk25S{O'GEޚ;틪u:p4;}Z]WHK.h\P{̻`{Ʒsç+ f_t~G.; ^ "xG|J|{d:%pζߏf<< y,/쯶;ڛ%sB M:a6*]Vgfν^Txt?U|^no-ݼWsl*3-|O}_yt9}s=ZG?q~r_oW-_O:9~='~z3?3;oks)No4"9+R8֠נt(aRڃڻt,?U:M)ѿu8x녽sqVNJht cֹ{?q\#ꛆ]D9.;딦MӦdMa`y30G88ԙQYPx4@`OaYSČ; PYw௼˥9=wM_pMmP|GďYsK!z 3:$;3X:9x2~:@'geL[ӛ9~˿p_z1!}6L3fTǫ,2<ˏImprbSpX(yGf0Eǯ3Y]Ml3b7 `9gde0q[yu%mD_D9 ZAOhOnt|u<^d*Y2/ros1PK\L#:>WH*2Z7)'g \[RtF@1V _;`t9f=:4rCosKk7g}*3m[$h}G>K{>Y *Tg#^]{^sLlx L2ٽr1GҦP3ry-D!Nxd}(9^Q&㬀@5CݏUr|f2hLX1Q=/d;LMF{Qs q|Q]dHio ѽf#}Ŝ}׳ԭ'Ɏ6sB4< Em ;vZg:OaQyscf/e) IDATzY f^}|~<7݉?~N>hdЫM}%JQ=}MMt, vcID_eK3NLY Gt#_Ձ ::m>~h2B?u=[bslzBi89op5҂Je$?l.:*}Yϣl2xD9fqd|ZQ2?XeV7۔w1,p&:%G:IN'qKf샢흠UV.6]wzχS9Ug;&GSYldgtB T ߂>yG3 'e<{?ʄOt Og)TxDЇ([x}߰ G--P#k[޾ 4S9 rGX0A]Tojb~: =/#ȣ-l#=~l{AvsdgN?Ko^m3W_}F羸}[jr?sK'pNO??yoW-饗^:Oӳ>|}?e_߆&^:^C)_nXizȜ\uf:ù_Yлz~2VL5pE2of |kFYJr6eYQΗHcp_ǧ!=ÇL;3!6jѮ+;#VFA g_wR3(WGBPqopu✑q̈DF@(rgTb-h N.)<1z|!(261` L_]vgM&K+oL!&D:uRqϡ`toђlX?+?p 2Օé=pn=Ǣ놿:?4'}!*{X{P熧2:oF'81fL2h~|h񊑹:'8GF'<ViH`T1y`ܗS(^WY\t]\oF~!3˻3CEv iPmf~u7is捍B=NzHx8 %/ КQ8^rT ꞥE&g"ru|0&tyL}K΍FKh}|(AKouW\n7,eRFܙGe `cw2l/s#Zڦ z ;|f5! lFdM7zӳo)4vBLҕz7wt桧#pPx,sBmә5>w3f.f'Ɖ`߱?$>6e#T>>v v]i4nd^\ n琟ӏ]98 <ُ6 *×`j~mb%)  _l%a0ZZ[o6ABH;_==g赁eaq[7ŝ,?j}0G% 4"D)8zg۴,oI ='1JLXtҽ6t.8FK6D-ls0J7ˣnөX9sDJ3Y% :d;IŠ8HTF>fx@ĮOt+]{Hng^^pUydt=zZYam}Ni>ۈ1)~olXӮxM/EE>zfk-+ӧ/Lo+he:~׀|`OY :4&:cg?ta я>}:sGM *Q#FzYQf!L\{>Ǻ>my|H8*Z@O\Co^eSi@ 45R!yKkm KJpD^>â/XVv9d4= 㷲 ASAWULC'3v0^pOt ]}%w[e{X_F_=k/{ yr=jæ<ݗ2,ŽΩ$G4=҉]ny1(wS0}~Q)Ͳx>e w169a :IwhS` })a4DxI`Ks=gn9q:ӹ#$g#aKJ)9 29`1EPHB4zS:c3IA+&0s0!G:2|ePr$/A;ƈ,Sޕn< .\GἺSb/\@3s/l8cz^C}~4r8kcpp|{Ԕ˩]QG IZﴁs|;/(ױ'G#3e^^"|f.,+Kπ{R$R(m8c|2%ݐAۨ!lNuT/t*t9Hñɀ 8^a+~s^.l۳Cʡ$.Js臃ui9ۏ=Wg_N^ǣ2ƻk$%h3#7r70Vr:szr#Rw@mAxQ?升|Y }eV+oss+ ^A/b. TaW ?ڬAdJ{h8K rQA_<n N6@$|!/}@` ߂q,KhAqԵCzQNAKS@z rFi8mqK5ݱ~G?zXOu~+/~OJ5{OgOXk)R~~'N?>szp7ߣ7_=]AB)?=wq89tym^F{4u[y3dy9)Ej/s&N#^J@\OF8y>w|UgGufKE !oY1a8FGs̒(ci ONTHx#eq>s w9UϏ})c?tg)"f):ǾWk<09bxD#|3kgk,m HE:~p<~p:qΔ# NէSחM:wE1xfu\_)q~倐 Fr%opM דuM0Jke_'f keWD(dӼ:vq%gTL0XM@q. p`3j$~\tƽ#[ F2N: ~e1ƛ`lO }N|6 =aG:ֈC̠ΥWVG'G9Ճ :XWa8od@Sf#s@'K%竏f#QQ=1`zYӦD&t1&yWO9A VC˭fѭW6,9xj͜1CTgOhSGIa;QVPmq2ggխ 5retL`O͸6Á{L97*P+Fc:+NJ Ѿ"dvϿWA#;ʺڭ%~fL^]:~q8ccӍHO4s Ư#='L8 ȳFv9e<Di9u/_O?| 0WƩY"Ǭi#xdF|{Qc_^zn}{x*Ү:?-D2Ɨ'̈́2z32n4~cY9r=Q~erUH7K^1M*#'ޗ&*{ r{xM+\ȷ),+[MpЃ+~YuTƅp5G_'GNKΎ}g Ո1<饞ot:M6GmlN#tN/iPlz:BjU>"K(T> P ꌜx.6P:7|eoԽڇ'7KEj ߵWxx׿t oi=K?{v9y_ __cF?(ğrw ()׀֙\y(p\v!E8kJ2CЁk` FשհxLԩWsVl (pLß"| lE8,!ER3T/|O{ӽ28<ߍ[o>Ҥ>򧘺:P)YxQ Jeg:CB1{>WֿR 9͔_n.|L9f3GSdybA9UEK rx:Ļ ]?`76CI]b=cZ;ujNw4G3OM>ak /2!P xEQ )C0svHoM<]fXrm?xλ=U[3Ǵv'ԶhVE@o?=@M 37ݼM-E@O pJ΋)~p;_w@` Z'_Xc>@z`2X!ZuThάG]d\f́};,X?i&}{n`8o#T=[j=ʻlI[Cj8hXÿC̄;xk|4?>#L"HJmc+#`~Kw ϧbFc?@SM4Hl6֜YmIO* DɌ+3,׎əSY1\6kS@gDL+jߑW~2Ւblkgo 0Z 8mGߐٵg84?eй6W^zOD+]ԝ@^ -_Vvb`| {~[.WY6 uR+2xp' ޣ`Ñ$t[MQ8LΏ`/V/δ6!\!8E=\UCkxO)v+hw$#x/^wNO /t$o&>LSԞ9=ϟO`r*ju{r_nZSV.E+`E Cs5DFG7iqXvJQ!$Rlb#m%YJ .5ZH25gsYsѳL ]F31ΏIg#N䠻wᡨIS1f;0|k|0 >J]0St)ȯST1KutNNYwn*ӡCnus@⡈7(.A3z1foRG?}Z.S>Z9ՌPZ1}~rvOf-%iGU>O٬c,uH%HFWz 3|CFԚj6l΃4^WR|MSCUͦgzpoVVe+gβe \ˑZnsǣRLgBbx1iWY8.#g`hc88'ě-:ei'Lk/(3+O^+=#ҟ~ tV>l]::m9}S،d,my,?HNˌ!h^]uᑀ8O=;Fz3A_e:{,'k䀓 $teԒuuvN`2FNa:앇 eFcrxOJ}8!lK%e B7hCٌ^u:6m terDsa IDAT 6'I@wUd3lx49s)fGԺՓ z1t l#,_y+ʞ+9ӧ|+_SecW3O3 5 8p@ >}7<'hb(z᷍*}I ZolQ9*yK%Ϩ_:V6uLATCxIXJb*AI/mn}"o,Qoɤ;zΩ<}/S)  `0=~@C^ {wz8~Ƥ^Kulpϝ2_?sE@ٷ i+`i^`l|Y0ݪUGusY9yW-'+M(s8RϻOi?v7 ؅2Cژ@r\)ύw^p4׎#*^ϨZXyEvjOk[ǵ32Uq/զiuP8qV0GhPo_(>0;Cr'0}= VO0pT)>đ~uC0n.X҅rN<6Oh=r,=K -k!/\G>c CO83Zמ*oF3.~OoxĸNLsxcG6K"4PMV͎3v+N ǘT9WWѤ A{ >PA`myz6>Ig36Q(ހ}z&]jl k_0Y=ʺݘ0uih'(LN t7 h<ϮNt4 bfRp<ꀝrGw<;Xz3[/&$X:=sBǝnW5m +:$CZ8*w1ao9SF8+P#m`k(<>r5#g BKNJ^z =ybődnp/c3XS&h\;Т;\? \'oƃÂ>k^[QD29XovĐ6$: > '6lԶnRd.Lz s>>s[b7{OL}o}]A9ёT;Э(gޝ[`ߍLB֊N1uVf tNԃF6>#6 tҘf0v /' F`‹_c_>jʽZ>'x!?~AtdAp$[pb LZ)>/ z[, o£K.]E{/}9uq>!'ϝ?8}`݄o|ӧӷ}vG>rz)vZ~,pj9v~d v :(~}}NV5H ZE>F0]=DRh/H7qԡ){ A^C޽YG)A 84zG?ũM6fQD-m(̉cO%.xcMvۥ\ ~ uxDlD9[3"(^Fʎ'7s*nu@_xqUO7U}W9P/6ȳ/|+aAIX=[xOc5,xp:-HW~s!43tΘCfn6y'FS|f1XGvkz,EK\;x6 ?_ eM # GGoO8W2"Xvq*-5~o;W[%'9H䛅9td[ D}4u> QշtcZ|Fu`8q5yWz8מ3XFV ߃gz8 fn@3Od 1¸xY>F5zwOF˛fsK;n-}8glFWrkCϿƳkOgL 5םWtuf:ܵn5†m# >f[K(οTvћ99>iW"6wjt.BAG,J61X(@3R!23^q|aJ,B|"0Nùt##ʡ׻f^ϹAfV֏}Yz[[ao;Rη9n}}_0 |R&0 Ny3&==wsڷ 7YOm*>֛!\nE iT.*m]h׳]$S<.QwxT"CK@\4}0]162~X囖 "v~[NVg,w?Y|>ld^ӹl]F%cKx\Q`zTmt`vrt%{W,FՀctڙ-M /j0OitНt3~ݑ65'#k׽YKT}LM RP[Z}{6:кwh{29(Os='ߖI?Llt"ke?Ho;zNg[3t=xHbk/ԃ{_se/{%>VZG}ќ=dӅJ_Axܞ=6^wM\ {ߓ}uifw|w4n1;@$pUg.N?J9 X$n=X/ =\uD:) ґ#kA:{5fe-@R0Ր5Hʭ3ÏC)˥c,]ǣ6ӱ^?uPCߚi؇st:?tubSɶn\^wu~QN m26S?ĥ xF0h$ŮGI@YNL: 4z(en݇Ü#ģ<)cH=No2v%SyM zv@ݹ6{`FQG}cfSɖ|M<󈼀hcDpЫG^c}dA>[>.pe< pXp&9uO>7%R}Ή9#NaHb Xǩ׮Yxw5y04nfM4#:Me쒵{,[J,=ݧޮGaOf#)ص<8={fL6>+ P[ko?2>`xՓ"3NfGuS9tQ:G>}] 4z2W~&SsE |Jo>˸d3sN>9쇜%׳٣Mc~[_z/=0TTDZ+6a]r7ZTo7zoV[F`C<Cf  m4>|SՉT_f5#Ӌ׿W%9OJC.5x K H"SM[jo{lVх~++E~eXo%շϖg~#XFɁ YoN3|$LȗZ ='[= VDՕ{8-x%yGԊ>tF^1_m \ 9QB-IHW F%+f^,PG8abGvQGObSk½tzm33r5;hl5R[u\֕|>LKnWႁݷ-}9Z[kbBێE,"xi !iE7!&Z 4DP"ciKtIkn{y>y)h4bY~s1s1oRuԏ٤+xif>8q#k[U <͹fA`8aa>%y}/M:lxtA*sUqix,NDx>MVN>0~W[Z7ASR:\J ?rKV_m<ڞ*Š`Li:d#}Oݘܖ3UG9sU`A۟2"ncX{l&ф0{_o1G?=i_aꩴ)[E>u"7+µKC|z}ʁ9P[ztS@5[k`]3uT[')i%(_ok))S\3S19}ͩk7h΂Nv h4NGqRHB~Jmx#Ep<0>_ Uci?utay)^_8LO9W>֡{pKM/8wLjV9 .Бӳ ̔gsȩ96rǚ{o. E*ք @aDvI,` p=':e*SSm-/w9xua+<8 ǔswFxҕd# Oyv‚c2K MwGT'3_E]Cq҆kpxyF]i8wZes@\db@ =Ȼ F8Dl ߳60oFI;n0d|Bձs2i^:K1S!5ڴ||;6Ř^1%wr;Zt-V_-سk (ZV?p1 Q?1H)^pǔtx*ppc-ؙeSPV}v{F(3|?I3VaIiJ;zZq|JlWvnӦ#2yAS;.}gƃtzt2SZ?|6vZv];:ONz]#Y*A ˞#pu2Bۈ^v4"-xz /EC^#L:YGh h [`}7W|\wy 0<4s-_hv,͆)ji-ld>6ϟ"RW>>O=0VNubO 5E=;Fi5ѓ|JM)WH:PGC ְWZawg'9)w8TTvt;yS"ӣ9>P,岲#FN<8tLtp~1}vL*3|R3{Q:LR?F{x- 3\_nW> ەA8IY_/ ǟlc2rrtBSctM7gŀ3pλ8%1g \Mg-OWnxƄ:Q2kلp0d0ܬnȡC1gqO O#$8K̤ m3~#h:@-Y dnҾ cdD:i!< _LC6^5C KhcF/<4A~` _amB0h}L-(X< Gr?H@#aG(*S:gAK;lV>.sXݿGQY W?ӛrt7cV~G%)ܧ2d섫1ʠ+#`3j2[q#QZ;|.Fb9_4M1eܦR Cz{enBwgnJEaLU }vc,ox" IDATE GQʠK̫\3Pp ~rJ)8|ksf3R7A gMOG%7~-Q?Hk]:,ҋǧ]EM'Aߐf ^(9:G m9Mys6sNkƿ*.lX'-Dϑ͠թ/Nܴ)dd@f8jۈQFunкv{Kbᑓ 0FeQ Ga;}6GCV^r"rC]G6e{Z3ZW7vR2SS|.:*gXC\A3ߔ8˿{ƘT)}_8Qs44jDO9ҤhH1d~9K3&3p4Δ`D3$(ծ9@ײK<7[ģӺQ7ޗKw =áa]o?w2ÜY]PT}䂗op?C$コ؝@,xx؍*O{)FX@`TC`z 3~l)VԇotrN}M62tjGfT7:r 2oՠB_)w!}|Vx9IΈ:!07"`ѺQ+YЌ~fao C|E4 ^UiNplϵuK8g߀PՃw?]3 ڌ$enKu~rbF#oSX^N2hS?` /22X#kK;$& "_ey,t`l=4|<7JD+g#mthڴ"ȼ(Zy O|(=h*I#19#]_eΨONGdSym XoS_-ZD;aOvw;}}7}7>ݔGF# ޯ S3#ss low_}K$cG.7%3,> 7|jr~ջfIA bܟG3׷ى\h縝 Y3ww-2#tmK9=3c:/k9Nt[`4|nDfz~Z^/.==ۤw` >Ŀ˕oI>do4A>_S|'}M6;uw}p2ojh IS>ʆ|wd\fWGi{.{/R Nu2}fxT^qƪ:){S~%WFʀ+خf0O_SbٴuSn렛8^_R§M7J˽gp:8y_٦/We&i pw~r9?4ʖ>Ezʩ_m uRNRZ߼O5umGV.4.<.J`WT?wLcxIgt:uJΕ%~]tph+]yt1x^O9q2=sUʅGN݌Tzk یp/jӃsY q򔃎S1pC;nlR+/f7£ްk># xⷩuOZ >d%:Xu)kuvob맏cq=<@%:~bFi+G-f{WĎ ~^ud  ka;$ڴOY<3cR`FkdT ed3偍O;|0S\p{MGTB8lAk_ij` Ņ́JoX=0.FaP>Q>x'rS۴byT<U=O&WqƑhR9lddZ0%Ѯ8ch6S„#|2e/S|ކtͭ `]u)h:ctfxؘ6 neP\r22gjgzCi\GM|0jFF{eB/`b{6"קl"@x?y5l='8[fWgO1`H?9gp^n:xTKgC?4RVF9)콛 .`߉wLۼR]k mHG'*} @ ΁LgK͙}%丄,~FS/Ѱ~,'9hSJE@ P-lxŃ8'&5r2u2y,xv\,V:wc0\9NQCx'H/@z5/mKE`3D>r}oaעJZP O@K8۳@ 0RWꐂ1/`e) GwǘmOF3;u/;> sK9;p;Ozk?|dZ087K\ǔIkhʾgph궁لtE·f fA-g ē[>@u<,3 ,٨]F3!X=ϛ3yX=TOID=f8ֈu )Z ە94ui(.i(GE8\SZR&[`8Kw/1&Swi::Yk^o/%3o#~Q14IV'pf4 >e#ϥѠ Ӫs=C3Nux׳Yy+N1 CerWNJwg 1@N4hk#Zr xYzwLjUKu=-:i'Wj pq $CJ )l5,UVg%CO".#Js6yy!2ZmW8qh ttO 93*xbj6#qc#%šfOW2o|Ï909ŸycAW_$_Ynu6ci >G2gC+= )朮)(U8aG ٨#N)q=7@Ìp :z;qLy33֒?L|z~;>M.Puc#WU/ɑ߆=22 ?yцpNy0֒u3RLo\{E/L {nFdQ3I>g^;;4îw<'8:^t1ϳl놩p?~x0p<9Rnjf#9(鞣K6x#Ek# ]l7¾."PXZ}>u9bIj#t2{N<(6su:~CQcیX%~ud?Y]>LGݪwW36Rd䴫ʿ L=;KWz2ʶ96B<^ 3kHwa68U]ui̞ݭ%7uW7s|kcCp13˂t 􄏀0Uu avmx]Cz9Ŋꯄ>5K j$OwMo -2EAQ@wtK]lt^xh>~i-mv(lcv\ ى ~oyO_p4qĪ^^5G5~/ߧ 4cvuwE|۾P]CZ7l(0\~|P8ў%lKo4f^ >84oe[^GT7kAt6xw^XI ,ezdz}4>Mů|„ʌld]?LoM#{ %sx|Y%g_qӿ]y-3t8U^B__؋ f0 ק)āz$i4MPf h]Fg|ܥn¦u:; n wPg+l c<8=S0%id*%$Zp ɤK nYg9e֕sg,7ſД&eE`ρ{ ~FHNxh"3(M sc8QjxR2Z{zfp\gO]_ >Sr./1XasG^ե gҙ/jߣB(^QZ4ݫ1t (y4r6'\Qsƒ|rtO!|NcNvRIΩ,OďwhⵂֹťTX|Bt@W.t4W)]ڌۍ(̋=~fS':͝ m(hQ3H?rwX[8! !dSCAK@b7ߵeh}JK;-3*227~_ զk'/&Mh&~:d)}5\A-8ϧ9%xAbୀT.5?SKI0/fWm1"GK9|ϠQ&9[`m-6I{Ԇ?e㞙AFT;9"6sVG}~Nd`j^y>% ;F212{x["Q6ʥjwr |m3wMW vepxt/x‰W&9ozS :cQ g~zM>zt eO.+bT>G7bټLնt@PCҋK)X1s7;S9)Ih?־gӧOݿowrz_~#\ZGG=ɡm{"ǂT" >YGpαt~Φz$]߽{E 4Jp;Ug3?2s:wMzOל=wxIS(市&4:{^Ԧkcr:6w6O޲GZȶչv\pJKoϦ>)L (x#>|X{ϵϚp]_L9m**koewU}&_XTm:鈟OX IDATGbC_\vm4dȧ=Nn'% YiK@5N>~<&;#n+u^'R-H8xi FՕ碧mԽ>{Nx4t[ )b[y9L{tDgy9tK^6(&zp<m6%|r7m| _0%U@c?L%gW|׆ʾKVt4 3-/x$|P'6[vdA9ճrg<{Sm/hco?tFg?׳ʲ !3+^r&'Pl]ƫ?X;ߙ}-2‘uѭ-FHji=F.%:Ǿ9aS)S~4b)>yw`OB|3ǔ >0wsɧަH QʝBѦxd m=sRN0R^u SSr1wNĽ]Ez?< uv1 ԿNqigDUNv"}^ƫIx@A~.?cN'Iw0&УyG +Y^Gʡ-'8%n|k8fD;*Ρ Dq7 k.`qj1"8LJkFUDh;:ȍ+FWK:7>1 |Ѽ1A}Ewbڰw::79 I=mȵrMV_s!%ޯ q<2\ v9xʱWUw(xI&6ۤHG&ȝr<!$/cĈ[[.E/oT蜐f$N"c{H9n9镉fDf/CQ3;`Wv>W 3mEYߟ7cA {MվFp`^0'[1;rDO4>+hAK^3֞-SM Π~xGUL \ 0]; Ͳ:W}D# :>1Q&9 DBw+;28**ɺ듏#gE_>>ҟ\U Bܵe0F hw;&R駝 sZG~l峇(ǟg@_/$M07LpQ6 O/Ïq|_CyQxͯkD#Zp/] A'!|˯wYpHȇmpYe*J#@f_dX2ut"/u~0C~3Ce.=}Fo !rџ(˹'9pFm1ȻY>}e`)\W 0]n>q^}Ԩ2P~{9ų[{? >x}mZmoO^}6BxtrRآGA_A*>'-ȾYs>oZ?KFN${L3^. 0 4Lʇt<> 1J7ɗx1z|.`N|AynxF@j2?ToܼiO9/#%4)ՀS59]AϠK9@Y5Ե:_ R:0tIwR^g|!}aJ:e/OuRs|ٵp*4"Q8neXg=WVSGD-GÕ{FO.'ѕe\+̸|)g9gkY %xni8Vg9e>:C1IJ|d4JO3pU'k{8g5ZJ7#Hcp#x+A#ԹV?QS(wN6P7sXKD?>U?dF%x_^  TڙMӖƓI^2Q. :>N|NU9 xěңIO?d !4/HW@0Xv_1czAdŲ9,0F`f7'so7Ci _o_ҏ1i#X`LMi}g7Zm>Lh9락 p6+~Q9Xo, r@]cdɹ쪺tUo9:d#\稺[|~uUttlڦ7gb dƋTM7]Zѕ3>Q`ַ'fR}ҕ =uMW4i)% /z9/{-[YGٓs|D颃VʃJv6&&hApADAEoy{3p5g{~*'9C#Y2o/W9g1w*/\qЃجBեrO^mroH@WJl@][^?S0Ȫn@Ġ4wㅥo|^ U n@x~|9w>OTG^ nRTw-1;.3ڼ}i;U`yUIs:琣Y$8;av#v\:6Ч*|o}-=W E|06gͲӳɯl #owD5lwT I)h'~n~~8~d6cYO vѹꋎ8 9yqx9{E?Q}=+K?Ʈ|Xz=L}2G݌@N><( duoa'{+֞mtgxl_փWS~M}B` KWL&pvП_@Pe Ы0G֢U9{.eiGGx |m`:v`^ƣFz):lS~XY DgM/?o/_־HKn 3/.vb^G{u@Fdpv7> ̑GLMV?s_ -<So3WVϓЛ^>xՕz uSUtgᚍvQ- =n?.֬335t +3sC.O+[rTU६O}晑k82 263#G)}c X0@M>Fl xƱ_K_~l}pA,҃0Aݿ◾VPx5YQ|){`J]pt4W0YrӘl뤟Ѱzs Tf7]/6ez~K׿x? R?y :E ^ro1&(k=Gϵ~P^QHxKYtw!}j աɽ2L^ )5;<^S"R(׵tJ3# h8DiyTDsh":qpSLx-㔘|+ZvgSKcMW8\StRjF. aT<({_xtMh?Z-8|du P*~7o}ItU<ryrVDos!3Fp1CqК^Ï _UfQ@ADH?b nZ](/=9G9QwNٞ F/'OlP|6|o|/- Uwt aWfprLD<ơS%(Kٞڝ&ec0}-S;>x,X '[Yg`[U?+\|N#`xiXҭȧW1ROVf2dk7e<3ɝMf#bNz~1&ҍ}Y]Qd@C0XN.^{JÑ!{D9r Fy7XkmFw$WmjY}؎Ќ#sM19v3 \p|e:S~?Α6z0Y6{)ԟ{?y%9eB31ࢽM~zGV@d@ql]m?>+ý5sU6eqKZ6u$4*|{B%= gܱr=69Zt#T9=YSodTpd^95%x(|7_y~fmѳK9ҝQkmTO߫dAmwyI~#VNm f \a\ܒoW`A;q#g~']E*0omz".ιǿ#e p5:5kt }I3/W:ZݖJ+^k֖?.s W^o~94 fK5GE'. mݷf@_N;];{}8͘3 rxH X7[v ~ !ؽW]]ѝ}61gؑ;N4K 8lfdsM6 i{ѲڗmYpV1ѿ i(6TDH8WO 计|gy~n[6BWauЇx_=\% e$ r\ڳtlǃR9H\gy#N3ZkͥX)}]Wg͐2UkWu0p0}'[)pSyLIQ4+R3G?tX8sZ^Q 1j́qePL(`[^jha{ AO$nJӄ'P&?P9g{u3t38[hm EKrCQk?QO8Ϗzɞ| Da !e:1^\N#j ď4i?+{+F/@a ţg+swwūӻUNp]EPG 2yF'6 W{ݦ88<XHe ꔕ1 `_ۑnt357mpƞKVj/&ּېl;3j3Zkwshx͘ݺt1,܌Cёg=ȡ2/T?66h +Zfⷿ궂 0_Zi6*}#,__?C9ѹ۵}?hGFR8ָ&3U60UE@#fZs 6dN95~:0={㎕<2Y^>ϰѺFl\ Y |Y tcedTMzm"xf9voZ'};B3zte@uWbbWp leVhOg ] A43Zz8$xBfa[:M>2L#^`Χh>~{{&#gGf>޿^[fJ%fD$_y38O BϦVkc6;";J1q]PwJ quJd~WFpˀ-ݭ7ROgG)]]O )OББ.0~?p#(kGf &藦ف79t%.;o6V^n_<%t~c-@a0`ǽ*~> {˿N_6 2Y0=ۦ}0mҲ*>L ~; '^}-3LϢյ5|s~̼VG\~9zؒ fJ=Edyl#EvR>ic͈̮kiev#쀗]+W:5@heGW>g~X HO薵h>M{>,:3J ?y/u_?ѻotpeq1q} *{8[c6@_ͮP$8jovjlQe+[>3\Ң+Ћw/<]߰K}ʭm챻_xI}/ \ IDATTSzA9۴~x/sٴqLȭ;=:5 s:rW[^֓?P /k,/7o_ ~Ϳ?o̟30?=ͷ~[73-Z)7|GI妈(e3Z/^F߹ n8"^7k]}Ep(ՉKճ;Yj8= K:GƥߦnL"O)/gNN:ƟJXăp?Je Inh >Ǩ8ќ:q[+n|bnw+KQ?[rolWRRTjmc4e8zjo%)uop?Z%g ih Q~_tƃVU7 !(Xv4qEdn}u78GdGH.O/z2a$ܙ-ċPQ\jGhXRօwI4i'si$h7)Zǥ{>9FGbeg#uF2+Œ9:⁣`/tmɱ=]~-Ze.Ry 5wLmFfWc# !Y(Ѭ3^]:x%e1koxIf<0xpWpypg ''fu:{hrF+"/ vfsVὫ%^-SиzlF8"w8m BJ?$KGSՓKe⏏:2JӵoP㥱\V迳xƇجseܠ8\zVIU!;+y׎}7g~6r Q&^V>2SH'Ԟ㮴^A>9oP`*[oGcYN^Nz6tYoo}7_Wo7= \T=7|7{>?)͟S'``X0]55&F#OIi]7C{ǠaSEVƁ9C7i^6?x^i3jpkh:1˓lEۅ+޻c. ʔ2{iuQ nrۼ7C|8kFftw8|kYU-oϷl6:xh^UѬMpYgg>9츹vuod'^!otsxE)*ɎIlCߋ'˯oåowf7Nj6G-ƻ9tLְNgX; N>tdi\Y>Z>Q\yҠ(S{ޣv^? )͙~mÑ)W$Y n Eݬ~{_qn޺@s6-1 1bBh.qd:N.X7xtƐF379Ѵ1Z5%ύ6JY7뙍89[w)l8Y`p _H9x-`O~vpf.r75>[H#κ:ih`L p}-F]- Ђ W%3A` Wïg'UAr{O /Z~: M뗇xSp).=X02eӔ 7'tQBS^'/EݗIG{_r7*z-X0p6{VqrjE^_z; \h+Q:p {>mtAH2$5aISC4:>#gS Q=cF :jOC0^jF0c#yc-{X9OaAMǴtήJggܾodC r/^G=&g$/pN[{#U`1Î|DZ\t)G`kQ룔wy]Mao6<=NR1|2֢gOvMٮ\Uƣ`N |J65b?LY?{!FeC/٦F@I+KO2GӋgv=y:`KyB?Ri/q_A*a03`%ޛmW}Ihcr?(,+0'^U!oT x]s+kx=]?M996KyNޛ"KKͲxR3Pdŏ>NjjA7^,z /'|1zP \a XDLf4ַڔwmQ#4YxsZdGє`vߥ䈌eϾD[NN}DDg:nG' 3O׈{zqfojc{ F=W_:hHi+|z5."qg4' \6trb>O''W1w \|F Pέ|Ļ͛?GG|34>axENsGm<~+2@}[~ѽN\tx; vM\a_,삛F ՖԖn;YN\Zn@b9]k\-~<ǃ ]7e_;?;~ϸſs~/ok훷j\7rs|7W/ ?ͯuW_q_~͟rAO2\O?'o?O_O>P\Y[0,)KGƤ6{m`PS{myggPpv?#55¾),f|:J_lS5哝b XH$qz𑖒.*gN¬=/;W:|g\ ơI^,*Eàzs|vtg2|3M1)=_d}{7:]".1s0VXT\d^RbpK93`MfV!xfhT Z}rtz>pC6Qs@%һq_G0(8 l?Z(=t_Ω[hrUJtx  Ӧ8FW'ouKN y3KWtCswuh6Q;fP1+ok} Q-k#:m8wsB '3/NuoyژQdKRK}!0yX:S\t a#f1ʻ#_ D6Esm< K6~j#6,6WF@<{\v{)} / &rF#`tjIf=5~ *£[@]f QwDG g'5Ev2u ^ j2gf8ȳtixC%r.2–&!{?y(q&Sȹ:0oie!Wpɏ_m=e ngiלKFr$vwMIøFX_ҼM㤍w9p]0{FXO4=X3C|W&t~K'ͫu^ǰ *41xG6^)=x?^iԌ"|C`pށ@,Շiur(pO/ќ};ʫ_,N± S=x6Y1%WÖ s |4:Svy*ߎQx 175$C7[nMTje%G*wA ^[HzzX;(}X̼ad+>@PA-ޗE=] I Tz&.@zD)/(렦u \i?^oAև~SB}Sk?vm|ra:> ]=XYb/(N_ |5ۮic!aCpAk9_Rɫ% PW p]ڦ`џKL}pOZt\l{kA|`j{[?G~Gn~om7?[~կޛ_korgy睛~ _ fsn̟#;|7]kO+k̐=t4 v :Z##\:SbmuΜ X [sZKsF_g\ ka2wq!|^763ypI ] -q(gv{ [<(%*ձ29) OZ޴iĥ=eRGG k'K/:Vys|g(80u^N|9*ş]Ϡ pc3.qgNzKІkxd Xou"|+arxrǭ~c8l uM `}^m";F'[0&NjoFV]84bOxg?6|ӌ̬ ޙl3C")o#*!cli;+ϏM'yvi"EN^YQ /jâd4C l@vv<9(vʙ7|6ş`UKWSeӑ(S4=8/xɶr! 4INC_xoѿ~s杛/Ϳ7?#?υ_?n雾滿67x==Ñ77??xw|`n~7_0W_yv96G >~\jO>M몽Mi o0R'\kk[,j_{M-ʚYMf\3 ; AMl6R=# ACH^hudm*Q`122Z)#wZ`u91?c|U%wQ\pBǭ~pVX2%WEcb4V: 'FFN+^T:V]sZuW>G>o;1j 5L{(Ob3Fܠ1 yyW/~޿캭w;k^{퓽mƥ P $$VHt"Y-?@mVTjv*!QB\d@a{s͹9o<62$!}c\qk\8ݭZpXR"NO`jSGbӢMFۂ{̉)v_XL>Ss9ѕ9!t}u(>m8ݛ͉%5@rr^s @V/!.OhOWnr0*gήݟF'۝'u<}q& iZQ yL9۠MyԼ! ͗`y?G f4wgX@ m<2e+uslC2{Q̎T :ӏ:JcS94pի4 3$_#+6P:tW?^S's\@rчu"4eA\ߖZ :/;RI`N[v/PɨhQs3-y1͊)-:PUR'F6[~o2 vl<ی72RtRnzhfA['Er:CV0vQvF ڤ~gu2J&;y m~#ͳ3>@NGSN#c#7.heGkmdLX v;xܼ YU !2}_-^pR= |{ȃt~*@__-^Sys!heޟVgwmK*#H3z)z=~`doPd[JiO:ApLW<:梵 J6`Izjh'ڔWm (hNX]YA ~l|^vs+NNڏsc#4e#۫p~8l}7y{lїk&;3ղVG)zf_|[,LIthB"eO:J_?/x ᨮUZ"8 Zy1nym_e:Vzt/>X7<6wwsGPYu|O7??_iOYӡ1 ~)PW|?Փ]VW n >Lɴ祭GSc&P&O o9 MA5޻3x`e49'F M= cXߩF`-.X]Gj^K>S 2^r:oUc)չ@̷Wfba3vӵ҇V}pz_#u?g"шnRv5'n!5p ߑŜk4_d4QyA_ zwv{AwNHft83d^'x5ʦo{<%:BY-H~Lc5ULӵdDv4/pd׿Q@" D(IF}3g_S6ԫRpnD~ }Β@~MGnDUY#6Ci Д>DcQu^|YQӻ90Oԣ;>壣9hT)z7^O>,I×Oֳ˷'h}bpᦇ]F݋O夣(*Su@[<@$}{UujM$qӡTd8:KN8E#~>kJ:y ?zrn?ao$OG_.f :uީh'vaPNFSt$ҏ[[p<^B Zɼ?4SR Yg=IF3Q7M(2Qř^̢;A&;$H]+B#`fRZuӺY98$/7RX]l-? ᙎG7;I^=A[4/OYteCDl/~=qL` ~dLѥВy7x h~sVYtut,`,W uLFݻ;N`z WyO"4}D˱+9dKdQno{:WG?nƅۥ2oW]fL( gl-|íRzɠXߺN3,fkʚlYޣY9rnaOدC@qzk>Sx4jۄG:7ȥKuz-}%t~]ѡ˳CW; 0\ԕ+]lYY<\Bdt% սx>lշhS}#g0vt?ɜݮ-rI`ɵY,Oi}=J S>S#髰\╥ (]/߱~6(w} =Y !\:NG܌XY{fyNJGGl _MӶEy!8(4 7?s7~/wyO|{0W~W32F>K~߸;_ot<@g//Oěǖ0!e΄_qzYg-H/<(K0Mt^e%_ 6Ku FvIwkd8b\ vtYF)h܍Mߧ9s?mc,hMQ^`mmI9vT"G8:E!f4[.hTY8wrJ7LzMl{X{uYQV&9r<3|2Jh jlA,3Gwژnsw ѰiݞgS{*>"r`SrO=QKWmqr'82jClȺ[<v_[u\ˣMSMU`~=nԐL7{lftJ׬ Im#^GSP1!{0{nEJvU li}혠nY@dBc~ ~ jL<]6C>=x=fD9 I 98;zȢYpZvcKu'GE+DktJN^`;cjOuFkf| |et- _=*;KieOY(+g_)gic9aWGB ֎H: ;;{ɷٕFN<NuEvU6StL{B~͘.y!1U0WYgŖ6r6O6/QNl7~ ;X20'_mwmZptcda$޹bK=7/9S"GwW^Kr|뿾,~]m8:ldX,0"DN`uo(}U;M_]4u6 Qp6!DO|>m:;?OÛo~O_ 75kO?q_܆ߖ>zooЩ?-uЙ`~6s?, /n_kH /QPq<9vAuθr<{b g}nTVܫ^tgv|x8ݥ[(_K#: }_0:w5*s"aLоi c%-xpr(@?Ovۿt S3 GqOedތ_~'v7L|UquxvwƫFm-3vy ܇ u+ZfCl.ukR8q%=ZN٢:gOj4ȟN"B2? SZ#qFlGa)ter˷ `6*>f|YǑ.Cdy4y\+V~N/[#~5Y~x804KsƃqNtLfFӗQR.[q o-wv\s+W.^mF,p9pm"pmWB}_+LVV.=GeInszv:I]$Ƨ?D1CfϱS4x|ʱRr순s#{g:>&G~A=:k:N<ѽ2J9^&~dzEX'0ŭ,9|OUGN=iZ:1HwzLw8_dsI:oN[l)Ihϻә8÷6oqx-,4O?ÕSٯ]-upc:+т!}. |'#ʭo|/ǙPv _ (FsK9Go]kQom괲F_u;9S]46 |kn:3fz'V{|I!$+ ].zd"tTszMdvMmDy I[mMIB|h#!IX49TeZ1} WؓWRgE:>7J޳|t#~uÖMӡNNNH[SNj4IU}`zǫK}xYa.;upx xĥO_x,?nm6sF ޝsXҺ-AA o+tU Z QlP'PέF_?/fVM ~Ӊ1/?΋-o i?+V*t$^`5mey{Dԝ@>٥m]ڨ%h^nʦxJOhYLnB@WaGΞ{0 <"?~_*Y׿/?o^p*ћ͟~m3?3?ě'O?Yp_?oIl,GϏ$ cm/[z8ó`#!9Yݺ83PUj{ uʳ`PTU*Ҍ_5nFs9< uu Z3y 2h1~s2$yF8[/|' cځ74nju#<30ߘȭ޹Lk$ܮ,XPc%>Z0# Ӝ >ˉ.-RYpHсϙBÜ4r]8Nz·O@Tbo0/=pQ 2ӡ! F}jL7Dk#wCSd )MQ7j|9>,40sNy<˓fQ[Kzbւ#mT7ӍGࡱ:1Ͻ5ȓ񥅵'7ɥz?wHl -~E#'>WFptutj(>[uC@qdzLR:AhOO9Zd@'I4+ne:^]r={i6ZWwEJ8"w IDAT&0ltwœKfӗP?#G9}x: Dl_z|Nх,S HD֑('(Ǧk}CG^mN#:KV׃w}VFeTf\=imu3gvo)mL$wp Oָ W 'k8V76޽ :nlz.{~hO5V'ܿWcxQ_:ʍH4ӗ}kw|kJKW۔9-0!R  #LeFiMYFP|UY*sv:l<еVZE} ﷛iOS&or7&4"_; n#:%p~w [{4Ō 4F˨A]_ANOIqc>x>O^-dK8>޼d,z~P銺:Er LEuBaיy0:9t#GF:b |zr\Und;=KY9yVMU@qVsJDg ^:_O=F蔏`@oWuvCdUct(=7X@:g4vI}{Se:T֧ErEC 8`5 @zDPOi(ϩ(Y|'9^Tl3˯( M0p `fzeg>ANWVS>3A dANSoy'݃ˬ_j%M>\ln 7R׀8'p jhTV|nf=aG/zXvܽzej_^pbA^X9Nj>[[kY@_||5rexu`9]]>=.[}=B3LJx39\)̈́!n{F=ZKHd\k3/6;i;qJľۨNelT+J[;#NaSڞEkF{?ҙYPi9|n6\ Ï쩞!H䨿] n]ԇҀ-*nN0TGMTnxC2*ߩ{p֡^V/:DХ tRѴKF1Oy|LdN\/^! ש=WP__鰼xc2}m37ywežfG{PxAkd~ycZ ;_^IpM?'>-?D/'__Go6}!ނKZFU9To# :gc坡T!T< 末eNFQ Õ>ν]t}WX_<@go,RxB^Ή5׭}H;6 b=kJds#Xn^ʸյth:gs^ S֪U>eQk ͬ tЗOoo'pHp+{gƈ-T@;{BW$$,T.YrP6^PKcMʮߐ:ؓl:U# PИzu@If ⷉq2/ 881uHgT~orAFwtB9Z9nP=oϬ\e{%)[_+RxF9CGѓtJbI?C 궴F5-{)}[nφÙppB2Y6YƆNaD|{+7PZW==@:3sPʷU=Ur)p8;pغ'W;[G/]a:d%mv&}{-#Nu}㝛_ZzDTʸ֦wkI- a޹(~~J~-+[2!l0zFcL?l߉px}[]~ 6H#aO{gA3n:K{)nMj`p_Td~}V =号>LnOտuޔf6N\=\v~0t={UFWF^š-\tW j4]g:%?7O`= Tʰ7O1t`<yS~ =sǵ\wRY ;؉9mUU1Q+ͦҟOýJ;}%Gëm<xn!]΃Wl948莨%: ל= T9N{QF>^QgٞXŌ=Գ^)Vm]!Y(W K& }쯩9vT@& )s/ڒoq,;G9sD*c`b'Gw-(F_ZO2Up谆^Hw|ί|!~omd^O4߫yתqkĠd4%o#k)({d< w4V9xT{m|bdxt!|щtb#Y~q r۽P@: ]u(hxh s' GSArL[.O҈Uѽ`[0''CJ>dwmY Vٝ~&dX (Y{sk0Ajzv/wYq߼W|zޗ6~tۛ97➙Ut< I ūf 9<7Y_g;J>O" I㺴uﶶaI٣kGo֫clHRzӯj([jmYiwͿ:wK1+dIte-4#yiրpQ\J5Nu ԢKʎ]LtHhvGoIG#\h!p,[] GVL'#qȍZxe{ps}+@  mA_Pu!9ar |وU;./BWFUnE9뇽/c C"7)HT, 1U|#b#{ ["u9?zⱠγU`'w<R{G3VVѷLKx?4:P8Wɳr(vPǢid\~Ni3e'!^Yr<7$dCl)%:sý|ܽ~mhxǾ YP%̛K֞"cFBT_ࡳ~JN*N3&fȬ,^Wg~^[PzGrԥ.az6=@u*:/ Oìtތs^W -?l+eĻv٤dGGCkb䦣A'#}Y1=ՐY95GzՅ)y|kmbfØ]mp؍_=7ӌqt1u~o|k_ٛ/}{7~~|.(땫ѝyVY'Ȩ0@&Ks*{sduf? h" za T j]Ib%BۙphNy̱ŃKί651L:it>|'MSzܴrh$Bg<'_y=g<$zhrWy$KA9 P9ʷ Q7sƅ)BݯutjSǍUƱ)z|!%о}2>0G7П`(uo 6j$Ng"^5$.o79|[nm懵 /e(h 'Ys!is:б%䑼vYKO`eJچbA с?$5:R%uCU'[:bpv;[9t- k# &YǸ{V^`ձDvyuoJ:^9ԫٯ.+ PGLeُِӋS奬~f$pu׶Q޲֓{ҷB,m|:[y6zX?>j/CGL[Y1~4;3%kKW Nζ鼾k4lo|@H63XnjYt;?7"xwIo~RO~7KЫٵWS}+_͡:7ηn~ͯگ}/?v/зMS^F ypl38Uu. 'II_z %P{ Q{i7`6 pxvt09'0Hw)e_ܡ$#`Ρ=c?].yZ`(|#]xI|mCvI91mMjȦ1y]%?Fێq d 0_"Oxq':-ch<\dmxKd01>A9|ྖ}n "t~J,lG] f9H{LF#o%+AwN>zGNˮ= S&.) ֳnkt`t0wSRg|Ak)[zqʦM9rp1z3Z2E:lfp>L-+f#ͫL+/`a|Sƍ/&#z#GU{_@cʠ:KAոæ@irJw_]x{ȸL6I&2~ʏ]Ai#[L)^ӂ7>F9=ENFכµ=]oKḟ:^ٺz:A)µ@hCy@:*g^N9G|\dᗼp,JϨ5^>)A 1}o (݀+׎m@ pf?%Qnh\ G6zep7|=T0h0tl-Iˡk;KPө=sΐ]OQ>ڔL;ϯ ­;rE߿'ژpeYN00|^'/06R_Kwݼ5|&w@h` t]ّO4u݋/:+r!e>E.FIN'S/%l%ГS|5,&N'>?~X@/G'ыl4_pWcՇ:__ӊ`<m<#c'zC1ŇQ!s:D:\/޿yLQduG2_X'tkvШن|Cl;J1}쮼swzNv͟463x: tl*~(Q1u-,Rh}F ftnU{l@J۲3jyt y`)*&+ y`x ;_V0\P ! a-q=A NXvIG.t 5a荰( f!\ 9o >Gs08Zٴ[&`B&)ldTetgl㓭H+Wv'd77_2=Z?_/?{ǡ]~k7?{+_͏؏mfi>7$)W7W 3~9# yWQT bȸeWFʧq㭲]U&^X@5FT} 4P3:/ !}}:Ar|jfĕ.z̄y-$s fpX͸Ic}=9_䇶W$d#YP7YWZB#m r#VҔayG55#' @#җoTwd\cJ@b)fS{ÃO܎xY5ڹh]p2X9PFzXNȲ#wmiKS 9c?Kw(ȳ>:z`(96Kwv-hq/җ}' l(ϻӥFy<4+slύzK7\ʦ7~W_!R_iֱkx*ڏtO3DFÂJ=tFOh%sx=WoN:m;<[q48Aaze.M|Ѿ[E Π(uUǍQ1FFIgyPp PRSSٍ{Ld7l3S(CK*X! d*Ӯs' >K]1B-8k?.T,9Yr Aȷ)o6㜎hD`$ RQY 5Jj{G2bn{\ߤ9Y&$zim G {{Fo˗0uZ[gjxd鋾Mv}O'?(]e+X<< NҫzDF2'Oe`t3jDo.QHz&|6n3z\v{uTSä[[H`Y]_G%M(7ADx^_-9zpcCUd)9$; lwd$TRyFf 9)T)8=n~#_13>XΕafk9tI`q4D2ގ~q~[%9aJ*z~N`J3_7n}e=n{gpb'3 8ja0z1).n+& 8Tu@j7inw#^~R b{gU]˲qnC^T_dtBk@*ws,Miߔc`z釠"r h2-F ϭ ϫz?vo-6*IEJ;X鶇Y&q]o_%D<8ܛ= ,)' J9ݭ.[)裖:I L0lfa6S/zFAcox.49L>,@N+bfwzg /:|K̔itmd3v82Gl޿G'{ X2̈r}v$[PngL9-G>winr+gK7Ɲչn4ʰÏr^}ͧ|Cb4ɇ~"KI:}O6ϣ.LBztצ~R>ufyٱ-\;ZOtA`)lp,ṓMmn/Wn呖diWg;dK)H|:WA,R7<G3^KȦOA,~B+7XG|'J/]Gv MѦt{;?01l=DžN~ X6CM[yN~_:D7LAe3'ߨkP'q8nEAZmwbk|yD$hF3Q> xeS1෷t8":yVӷN0} 9 j xL(}G=?FA[tJN:+Lt\Kh9z)\ѧ! ;_z+JSa A4 ZN#r?sX`eX1/NfS^[F7:!8Lq|BS9lcp{||)S9ʨ|ٔsՂxWE>1Fd9:RB9fHִBT N9!0Ǐ[L_|ayЦ|&;MP؀^c.N6ʓIَ`dԁYB n4Z`cSKAFpӏs?:Dyo@|6s^ \0>fɩ FÌ_sso׻}:u+&|:rۓ˔ĩu'[: CQ{6(dQGDsɨdag;F^l}qϕJo7o ro[YDNksh&s| V7s!xW@7o(ufGʮn<;BF+e`iE9L0ΏxT>kVC~$7=:0;Ͼ!$rtY֥,hms:Q6/T7fhyNh=sSel*Bڰ~KfѮVU14j_6 A{aB&n]l6߻lw6O^g&؅_2%{sNN#?77^hu7{MP:h7]l5SVbVkWOf.ܓJSDƔ+L8 8i9׆^rҫr; >F@1 O]qi7ޝ6mc6ie" !D-#(dN#/pٕi2*/أ?857~lWyʄ l&yK nk49k:`ǛQm uq"#hXGJIuI I3xm3rVNˑ1[9q2Ӑj:6a6#htT%;ihe$TJow]hS>G疋tv> ӏL%+?GMcN8w/{GWƚ;+\Rҽf\wu#<.k^GNKvr%J ppQ`6ȂEY'ߓzϟK+vF_jjmk۠O/љ)MWMv4˩aAWc7y4HVrN-=E.sm6C2 םa#%'-Xgx_գ<&GΦ)1E#$׃L7<#c<$SDzT}_^uLTwrln%ߖnpLNeyfMiAx_ȠED&`#ٳlYޢgL&ߣg;,Ñ]JNGF8й:sXys>ΑZGϥFt&m}e/Ոr9:Gq[:I_Fo:fYxFt[ʼnTq:| Is^_\>'s!Lu^,ˮ..{qN#A'-.g[k|:G~GnLFNP,`vhc:x>:ÐΘ^7K*_v;nvhKwm(uX;5cp2H1Io׃b ݋m/k@]N 1N| kVp\@P5mPL//ڽ+ا&h \0z2hg-GwAY~@Gc`nV`Bp}}mB43/oA?Z֙Q4ۣ7u{r-uZN'S? {`o[i>g=\I)* 'ya86ոsB*zYrFzFU >#u=p59/~n҂e?GwʩW#ȡQ= 6d[_sN|cvQ_p8v_N1`GTFvn o2V1*h{ɣ:s$ןE3mN-7Y5e3%|pNWp43| yoȥ h> 9!]ݰ_)\/bmS\E+);`2oh]9䔍;l" ON{E\_)=Y8#u\\R^WCNMFjoiZ9yzT5+K]Js(@i1_C]zeazjM:9iv/8+ש@uQYvQk#Rk3i^swɷkS9itoϮ%['~T8:E倜4[!nߍ>?p/Gg 4E1-d:gdA@M6!iu4'yz4\7AlYKO]>?E.+{s[Y'=+˳TpJ0hў { +U[ꮙA`QuraT7['ӑ-_ dV&ۛ*if/̧<>^,> 2O\&pZi3"HTsA }: ~NoW`Oz.߹2[vWK]& -ҩS8(vyX"D)d]Xԇ:Z1q!2R;޵xl3u9xx:+bk;b$TY,;_uAA6fϷ`<Ġp<j[a>U2p5{I~_ulYw,+K&o!+:=K`(z06lb1N/]BGEt^hry!xA([{:{s2=3.¿g*t~Iqk_p߈fIPŖtNߞ&#S"PVYql6=' WU Sies7aA܃r uvT@@KwGPr`  WM)-.:+v6S:|;$@V٬6ߨ;M*va)]K_ë=4g4<~baաkxGH>zmY7Atˏt)o6lf.E pS"4!w¿sRȈ ӎ&::@r:L擴\m}j;WN?Ϗ%UhŨzEl%gȪ,UUW9TC8U:tNNXET:AZW |pBd<7USWp~)ѸAK259 :غqys*6V t1ʀα ~B>54bXwf:8uuu 6_-dLF4ϵ)dxcYZyd0::".1|X!X&wSg3[1@k*Ԙ pFvK-W0UNkvkQz\8 &LߩToJF=Z֡4ϙӛ3#kF6N]y=r?m4ywZ.iMn4tO~7~o{.3#Β+ˏ(r餤}H  }Jr=_#k 0o6+3D:rWyIҐo6YYq:>/WߦEK:nub7U{uYNFAJpI+ytקӀ '8an唡^י ۧdNWe|(I۴t 8fHsW1ɂЦy ]Pf9[z"VoǡC87#'_tG) _GzQ2Z}AD^`=yI#Ĺ8AܸlP=ƖʷQ:nS7ݗgkH~ڙǟC,l( Dr5oY$y2U^[6j1lryWhwo>^;ؿÛGu+k𸠶C0JWv$o WO$`'ܟ5Fr“tO:VNsA 6n<-Ht{Z׊iVBzuݗ(=L= xfV7^O 6^t+&>2_mz'-.weqp{pӃ`=sZL@==Bl"ܕz0u|nv[pA'96! .E qNʗ1v|]u2pN :ֱrflil䝖Lp+B+w$*'c|~DZx; (fĭt`F+bg?GdG' h >B({kxTJA1y?{C_U ?!8$׉F:6mH~Wkr k7ֵ6HhzO|ke@fP!Z6y_f$aL__CƦU.>Fr@wҞ@'ȆvShFN ]r׽yN!J_g[NL8+N>?>\XcXT*?`Ls(gN.q\E/݌yZ7fu> :Z%uU:aZUw.{pp.#:#/O7VWc2<5 K۩ vtM }A+` `Aq6C‰F4z,ШS79ԜK'1 #cNb ~J>Ϗ\`t\r<ֳ>7\zN!\'S2zv_q[ct:ВJ6xޫOS+ o= "<9[cXtp,O2 ҁ@d %5 {u!3$'Bk rFNɑ3jTȂ"&z4x/ 8'ݿujn!ps\HW`qOƗ?y0|_3YLLסu*E Y ]Y'C2 ~s̎)}΂@};9{`pB N W(\%pUrJ=O'`=z`ʙd_Tpp83:WA]ƞْͫ:%'}r؉^ g pFwz_ 5hT4le-tziU޳5`)pezC17'k}ۨ3G Sl;Ҩ3:aװ|RMFYT[c< w%=Ɓ#RGU]{FSm`){SĐ Z654ZP&!AHT%a(TJR Ph@.$-PsBȘxnsz>ʥ}~{^{^{/m;/4S[2WEO9T @vGVfrKۄe p|z`<>s+W|4ﻏ x־];d`pa~N?}*.8vAGkpx7Gҧž^?%˘8zoƪ \_ލp W6Bj$ N+oxT\`NT[jgt\SCOd=m 9Jdh9`C̡up 'rNki)qv+giz>>8#緞Ɏ#< 4y9䰟s9לzKr<9Cꮷ jȜH?xk슦 xC.Nt6Ȃ ߞ LٞՑ z>sp =y9d6sC\t{,u=svc$?WO أ7zXI!0*GX0l!۾;p~d%%k_Nq}.u9?jy: ikƪ~T':@ڶ*atbL^ bXvZ{j۝蹁elY˾Y_[3b`yOf,p5 Μ'?!A (6YB׶}3C6=m>9$p!qͿ<2sɁgh`$Z=C ՀY{ٵ 8@?NIFc9Nn>8fc‚_w)O=+``UCmӷu-6] >c<u5j3O弹jde<{#4 f|ewoۺ 5&@yG=٫x> /=GL]۸iTv[=&G}_V%3zm}VgNFG9VV/~`bՃs٣ kKQO?Soy `x_O8pk[ea\[&>P8ۗ~ OFB` Ns ܳ  BO4Πesx9 lz><ƺku0}D3ꜛvͺӱ>n6Z+qZnòl{6xclaN5{,hp"m`%g\,y~s n<4q-g+l£ xT{1d_cookdc&_=}Ӓ=*YP#F,W_L񎜎A&3Ll}F[d>@08Çpjno|u= xlb_Y<Π3m[?6Am4 f>X  2lxW|X;x{L"{IԬ6~ޛk;<1<ѥ DBAK~N@eiͱY{+9Ьr o|'Rɳ+ΦR67>g-h~ze}K$}C*%=PIPGxN:x98h՜:*U;ls?َY1>Wrox[U kU;o#p&gϕ_T]Dp5O7ZUV#ԧK8))s3F:g+#*n>Fwy90jyۯhVOf&M RGp%'Zmw>tXd#]ʨ͜ *Y Qm3D ~̪͖5Ax+KC C]zwr=z֟m“s׹XHvlx_HI*94+?{tWSz2cő2ʌe`DIЫ $<3C h;)ɠix1'N)OP\ \A*f^S9'H~ᇕ=wo%8hݭc8Hsն"6/kHxa-(}:z%{[hA2/كޟc5fj#A!Dײ9;DAғ7^}sdfT7Yt*W{'3b.b/_~wV2Y4C$_6~ԭ?DoC>9Gf0cvɪ3.̀/mx89}[EZ G^8L}x[ن]uF< +83#`,է̜<JHfk.NpfHق\j ZPtp29G.{tճfhtݻH'O쵂Vc/<,  0U\EB[Z1c=Nx*+Njc: 6a6[Nx>8L/n\l=roo[ j+ = +~gՖ l9njwSƬϞ2\=ꄞGL}+2Jnk[e=}57>b|W߸`+k@=n遂V|Cx_ruC>Y \zO7JLpӖ}paLGNw/+XpTX?GVބo^;; a^{@W~ӳQӷ5nyd~ǟ/X lLX 7@3[Xhk AWcΆ#kƼ9ɶ A˭r]Kpr/p"U sbyY{joJ_(W~g}> #pC?N~?:=s?'O2kwǁ)CR^uq(vsNr k Te)3 8˽rG^1mpQ~+ҧP(μ$͞S9R`3嫾)Owp6vÒ!voY9WSz, uKpS,A&-tV8RJI@A >x'tG̘¿8J e9@"1F,>I#&V,Xd`x\i~XS[NV: ߀E;\tC|/tovfM^ԧs{$'}[23.x%wuAIAyqd}NLZVF!||<bL)/QrfӍx107OșsUǻmE}ǖ> AC)"+z0d]GNޱZP ǃ/Phu "v5z{ n?r7\_ s$Zme9 [MPԷm?~,Ki\} h?{*1ܳz9fBrTq|.p]˪|mT3^Ձo^UꆳdG\Si*SX,&n!1x7:xPn/PL|!{;gWq؟sW6xԵH-**un^eKqW9]_{3bp1 ɯ$2Pm6[opڈ"D]?+U=NpSc=w>x$!_ 2g|~xVV % N+`\z|u~sJ{qqϦL}3@NGtYˋ~/ #"qmifz<^: \ㅫb_iO?ni9W-dgA%:M_ʘf z;b`\̣u͕Q-dU ˖ KE1%dt=xPH{h*ЕIa .?v[MOm0 1kA> el!|WW~rR|= opI>)N?p"ۻ??d$]Si):e!ea)c/5pM(2gyv3t~R{vST'+>ѦmxD]}iΗ=G OYp-۔*e}ŗa`Xa0񯚕_ɝJ1qu( xm< Gz~C>Q dG6WO>fȶ,lzq|CO)> sk'X+ݵRpo%5âddϰ^mQ]p)pnN~P>6 hc3[ @w x[R݇C]|3ONCOm e{ؗ9Tf2vxPy`*`nAghQ2=zRJ~뱿_Ze 3Y܌VՄXs8*w 6Ά{X`GN^;,Gf'7Y`#s,u's6Q9 A,Oxf>f tQٗ-7:=2*Yd9xh bU_] 5+ލeԾ;'D!@'m/9v*éDnzru_Sׁ]὾CEL&۞r.pL0_Mw}Y['ݬ2ZeCєL&N[t:|5(_oMy_m\Gp s($ Ld ~|tWxcdl-t+h o$c,&< sBvӁΘ?U;ãsz<8#Y6;8woiك(ۡ:vm{VO||!#m:Ƹ0sE0^){(@ΙWWنNh_E+s^um+8[PB*ոWy4!TF-HNlrj6ɍ{ h< P<A|^_=g$[lz˯|?[zR׻~lOt-EGA?2VP0er6[|W!N9-kzgٸlٓڌ4q*r6ó-WlYꞣ/ap!{p1Z&ی42ȠAcW.Trvc8Ft*e|EC"v rQ0=kX7[[3+7/3`OPH^o&E0*d__mG>{G{ue%e}T[XnLN;vΆ8xf,#GkUYsy֮`z1sj\p<sGph7CE* cҵҷIgV";=p Ar>8WͮoȻto`s-E 0k :9ۛ 73iK+M4C&->9` xmӲ]=?Țٸ>x] }Y>I'7e7y_~[{Vi;0| ^mb&J{N;ixdt72K.ƍ㛲nKO,dA{uq9o=_+M_{v'wTkge0j/-n]LN:iYٰUGl+2dlC[u^Ki1ڮWGMW{$7lvc\~JsGK/7W_mӧ>77ĕ]|0ݯu?W'oÕ߿Vscj˧/:lv :+#θSQSxCpVJ% IDATү딺V: N)g3a6xUK/5+GYQ]s BUsw8X}ԿV5!7pcn/ykF(pN G :8s^Kdd<:x~߅ySdP6x`'L;䜒0iF;Aj衁 #G˜~Ms{gXߏcPg[6ƝxMɞ:/4|&˱=`9O#|ek8.HqgmPégRg^#+z+2=8%ӏh!3$;~6' OQyW} GZT%SMfOTZ墯.AlOԉO zg\ƻ.(>Vc%x 05b >~ԍxVɐV;AkÏ߫OW|?v{u9p@L;|1~o O;|Zcõ (.Zvv(_x? |خ94Kw4NZHuU˧7^ӝW{?N?_AO\:}?>Ϝ//>o}.~"|8?g~A9i::8:zzÀQ`38x;|@psV ̇w:_cD ( r %: :u9նsU {: (!=%2j-G1^x˃=S#å4zgH0˷p,wAzrnjh gm0JZe p_}f@Wā#yEۏ6'~DgЗ`}5s/43=>e ?Vh;Ey"μ_ae@8p-w<,k<*_w:-ѕh|Q9Uxu(5O'7 +N40 :ǹnSQwpbFcr~ 2?d~& J dV*"TY_[\s\v^2$/oniU:+3a~!BNVzu)a[]?S9Qu<9f5zk Uж1\V]a<춼gL'[ϽWgWgOtz6].j"# =<~)p$Oz=kRԪӖ"Ш9ߡSCێ|3}tDzRy=@OJvlMС~xt'ߪʾ2F~<%+VyK8=*r$x.mux -)Q.iBY?dz uJ v ˳2 :LЖ.+&}}i:p[<Yt$VC{u鹯&s"~611p騲Q4 > ;s@)~4 (5{ZYk$t7 p+ ٻV0 hmkGOc/ o`*F:*bt#R=G? O?_"_}{oo=rӿyOUxA__~{?o_>DcJ̻?r?~/:uN^sT2֫?J^wH2@.o"3n_f2E¸uAַ&T0p֜:ix5a 8@Mw$Wͷ#=6\h{YNӆ2?fKJ3C 1Йv[V\+1|F氨_ǃS9VNv87$39na}eSwy vLIDZSAevCP^|og .h8 'e(C0e?pF KV ;ëf߲UGue 7u['a+pݬgLd"?A$* NaѥE`b؅'nFJ|Z%2Y6#w<TcEeS7kpKey_9$%[-~!xvW22NJEVj'V}b^ }A5=TZI wҏhqF^U52>/N~PYC V}V7F#K;Z֊邞Ѵ@.{͖Sj 82K6R]Sekq{Isr.̆-z.ae; x&VuWn9mq:܂ÙJ~xw-ri;-uߪ9'Y|~0 POpmEm[Y_%s8I&Pt.0|OGt~Ж׮0(ssNj?mBFR( *:YY*r8?݁{R\W{ӎ\`)1=T]}жl1xzc/<,q%5…Ӿh#FW> 1ۭ8{(EGN7:Z41ЂÉ⨾fGIm69I?ݓ+[Qupw|拧_e*W]]cV3L*v&wWHLثh?zӣ1!ܕ?| ?(?oN/wמ9NN]j/O޷lU_Vr~~;_+Oq>O~]?Ԃ w?'o:}hN8Gs 8VOf_hSJ~CF:q 0xzcjWtua Ϡ-Aa{swnG n3]RL#leRXqE(+L^g.;Y`O njA7% NYꬊ3$ 8"1b6T fb˼69U@d?c_v[?AAif}E.];7{1h8D/19d+/g#~ڊȸOp/I.rA߲tt ߌs>][3~Oܫ7}G{{!=z`A vG.1G>)ϱa@W;+82>T0gU g`ItDZYEFm5h[]fzoUڰ]mUSP^/O9$GI7 B}"S}iC23~@rB݂J ~sv; 5>ɶvd)l5@0ӕp'k'0Y ~[$|/UYWkUm2Gx;j4K8_*A;"2C)r71Y׏sެDX|UvIoxz+-wCfSذs$mA#k>w͢,;Ҵдb Q#6K9[JNppOhl_Ys9nQ@[޲-J(4圹9L䴌5=s3-aX^EWɜgu6jxƑ*FG9HmCDAFCY:.N}NݕVLlF#*'a%A|^8[dXB6FĹ,,rr0arԮ$oON zP'3 =>N(po;G/+B.pBV^<5;2(p/[?|)^ 8MnAR/ZዦF4X%OTv Ve=S$C<ٕtml>@PA95ІC2i'Wn?D|/hSh[@‚rY3|^};]KM|ܴ^C_wGp@DmͶZ~<&q.VGK=$X䣯ҕV4IK+BAlZV뇾gXʀA6ֻ4׼_t[:}k_z%u?3_7Ϝ{eoͿG=}w雿ON_+_pSW_qO>;}c$W,sͿ7OV%;mO0,bO`.A+C)q"QV4sFxf8sLc4M!=uؕA"B p͌ ~;pIF= M>ӌqpRQQm<\oy=tωef9!10ޘɌ!G) ˱)9޾x gbP/% xDQo?eES3|I3>}7[6}V^d4s@kh BY87͙Xכ;Ivs8.N4t<іE~{sHģ)pǧɄ x䚌d?<=ƕ]J^6^ VVrw{ퟲOvo?O~=Ԃ7J[sgЏ瓓lc@ +{ǹ㵻qUF>h{yIz~v0:_VJF_[:tm1śȈ[ ^a|Mڻ|~(/yNGȻ~p.Q-V,^,ps"~b>}L~[q!ƔY>펰6hܸx(tKbuJt__3X3ٖy6~Tl xW2y϶ O =.ckS{X5{ݫ&k\ho[=͠]>gFs瞽; Rĉ^'ZؖʆT16{ 8?`kS߰9;k;ȮNcHs IDATƒ{Y=V 6^ڒP|FzEOMb[cCO؀MAc傠E8>~VkgI=Waxc?(6.FkL__b7魷8Hֽ7OգOG/p~;O黾>yzoW?f%/ӯU#/G_{Ϟ_K_}w'>?QXMK~/9+?{#䏬 ?}~XA~۔ R##cA̘pj:DrK6S2D nT12BrRFh{3*wS2y>/matK;5^ nkW7",qp˩0n|c_sow=\db+ xYbRȞ7\Lo8*Q7ՋGS~/8$-5hq< {qǫZ0P/:33+O9uɚEyr͎2nY> 99XެjA0*pieűs! 7e̛׎ʿgm[eer7bx|<ֹ |*_߁)̌NwpifJva}]~βxy4Y;.zSW|?ƫ3h F^खX]\2+[DÌ8U33%z4m+py Ĵ1VʡVp~s $rh4\tG,gg@kBh 1#w\ov|8H`s,CT-Y osq\~t<ҡvblU{+0 G>0o٣g׌g9G Ǫ+Wsx{k#+ y+OD*TڳJ<8mg;v~#]&sT#/_P% x͜~s^+_@ɻ5m SCy:{{A3EvpQX¡"s^9Vg&-Oys戴xm#Ե>t4_FNT]>|;H nJ^LcpR:<:D8qgwK9V 6g6y@ǻf/F$k 47:љ WP[GGU<|ؽOOg_<{^<_e|gK缓ܛG%@W7Yo)omvSo wܚ^&hjkW;thlDqi0kѤcƺ«W/&4ٶ .=s)TZ-$=qU0zuKi0>'dϡnP Ռa0+JQ? 7>ЅJwx:^eyƞ札 ۘ4ŗj ͩ:ϩaem42i-oBÐu.ƾmiց39 Mǽ!GA;<9~˅  ?VhW/JWHjC78ǾrL+׾C'YD{ Yp+w/oodD._z|[t}TT/o@Ydȅ^i<:2y'/1-zZZяZҹY9p/۾ fmge0v!{9뇕c2-~'CS뱦?z\d ʮ9%9.=_7NW*.F=:+^xo^p*Ya#;<``; =|z4pf G&AqɃNʇ^}_vum'oˮ՝MGN'3`cZ$Q^beE͙\3g$V9LFWǑ{+@GMyc;Dr(~]?1 ?\s^; /VR :ߪ*m4xnKw9xR\*Gk_o_ypyN\ 0*C.a}b HOl{pՂe,fo`~̄fzJU=B=o/\Wr3TZ,/'XF3(z1-Cmا=C޳(>̇Y2PGƧn4UmkZe䳪zL/P/S>=p£)Ӿ\7KJу;ӤOrzuNzh!'{cw+Vn]D{,|{msy+*el>cX# vc҈N"fok!I6{<r.GVЖZ6Rʬ8 A7^$I&y | \iksyz؇λõ l1V{sʏ+ȨsV:_h+V6 e~"\O<}OKO7?|7?z3O?7^"ַy'rO~C8lv[>įЇ>R޶O|oo|^Z.W>S!g7}7oiNpp뽔@ŅwAWC)1g)]SDrn|3r=M3d`s|764n߶44TYn?c}|Sff̧T 3C)+/ǧ_~g~iOlmm >Cs H3 ]?~OO37c:{U=7G9?Þ_,|5/;IoZQ{?#)%Rdl(uFsx\f3rK۵=\%㸔%38f5XjrS ޳ c$xlw4]?iV'\#-t%y04%kB{qǷV {l n܇6T mEh8:%Oj۞r ە <]3!WqP=nB^sdq?2v',YOwmڬ8sf6>R_Q|bG/Q]n>ë]U<oFO'(OIwǻ9~ڠ? 9.PSY`UO>!ǁ#ḥ#ۧ~ѳ~ (xwV n%t#l<9߽m%׮(цo)>W4&GM[@ :_|;;lG$yܵƸkCx*|\ʄ)la!a{mB6 a%BT:,zIe&JB휊~ G EϽ[|*JK}ݓڡBd&nqrmv l+;jG79M:@ *$y0Wo2ڜ={uK+_pۙ'sҍd5gj ȝqK[WL5^mi8Zv)&RNfv56w|GW.W7^ZmKi,=r0A[/' .OxK.~{V.YA:_j?qE׸/~ow>?я鷟^~#!I|G?z#zeS_K7߸=_vfC~WEvJYg\|3?%~yO]NpBZgHl0J&?)Cjz0ӳrPtgzti:m~B1ԑ P!@FY N89E!'VRώ͡"?}Tx30CKzO :5d_<*m}QI.F{>3#\E r4f2ĔF>r{?{ܫ⇤G ` WT]`~.Z^V%.l jRA'G;Z[0Үק&8_ںg@Y|˿z'w ɏ%T 9*j=Nɽ7duAK!_\=!YL&em&ofPٹȰ8ߪTW[yrnm[|1?+ʛ![~rs~‹l< N/I/8Fj̳5:]H fN9h#_XqF}W3ޭyы X,LP ̄~ :;DGS! %:NF͖C䚽aC/ۭ^yy pm5Lp5~԰}=waC6c3Dý$6+k@8^uz_GN}Ns?C?~ԏ|#_srP_N?~ Ysj8ſ7#k9(L 3',d=~[gyK.<# 1%N1Iàslb }to=rKuL|SD;}폿= V/kIY~~=sH29Gp9pX/aʐRRł'`RVGeC)wv. !?G x4>w_ڨF]xUM+[I}fl3hU23#Aw'Sѭ Պ^.ο3 8ڮAu9P]3a(>=3/'w< F4T{rKËAG< Ny N*|?] NS#hCS <-7:2zbۂ:h8g`Sd4G=cmH `)G=QqpW`բKgmfU >~ksx0WVvMP}[ގW GAU2f{.z Z2Oa ,ܰSϿxy`nZ;m\9X!{S? gQ* ~,PۭRܰ"iUp㹗>KuByp>m}ʈd#0|[NT3G1 NE{õ>1GEH_g6] d[nJqN 7!zeO?}n:m1>3P`*A<`f^9icE٩= >GarL'v[,1,wOKQhߞkwN\f=/יk1h~9,6y<=`p+s|EUfͼ9ŧ{lr '{C:8֘'G9?Zh.@{N5WRg9 IDATx 3=Uơzٲܮ/m~^k_ϩs\*)D `#!HK:R+`N" w FcPF%2RUS>k%g̹TUJNk㹍gV6PUMV}3Z$V~p5pQ@Q»_OHf~eY>9_8tZ~ӧʾmE.4;@s $і>mْ~0}Y9!+߶^zeo<ՙT6l m#Pߊ xZRY uZl b[>y؆3jgQѷ6~9pI[_98E#duދf,[F`~APN,*iŌ(^AWoFBV g^TS ;{ՖM,>gxx&W X>[yk tˍYq BpibGǥ|VXʄs]Bԑ(6*ph5|JX2s3~ў-gLҕGUEYLȖ:!* @"[0ճIo{K]F=py$ & G-&XMۀyL@:]x-;ԏ^z<JW{ɺ276g=z|ܧ!c0Zûx@mJ/{ShўK? v`r!^I\/3_Z[雡^Oį|Jxg̪۽N~V~`o&ykoglʾ1M>໕O mPGfc{+"}(ڌS+cn6&0կAt5V&ԇ7i[ůw6HCW2C{ˮBdz3Bv,J6X|Fz^#|]7`[}:|?y /YT%m.6r?zz!%?ImkjK##$m99JkȻ4rJS}h u ΐ@qx#rfkxZ+?#5, *js-44 ɛ]Xt0&3z C'Ⱥ]z9 ٻrm֛ ,/:"sYa{#z~ gNznETymҞ E.ޒ|Ol(~F?_ʒ;< nRȯ/ {j43_~"'Vc굤a~99Y(wm2ka Fj|=00ne / hh;)tKY6ЀUL]:`}][&r`*(KJ=3>Fw<`3Kmw%ALvqB8`sHlɬ~?ӱ~AbxڬxZA.uAYe.C5(MA9`?R rZsgxR-tf63ysV$l9|9Mn`==PʆS/\ᵱ/B;Wy~nI8s7ء1J xCϿy2}gjo;xY\;\Z}yF (=b]ug^YܴJ~8 Nxy|Sc&ƖvRo~oyc{t_zo*[VxU{Axr.{0Ve]6&VZӗ]] XI&^6m2R3zR?Oo~7/rɏog7_T%>f(_7ƿ?rϜ 8fՌ:F]u',=TJe} rXkh}s2^`g{3nj hqF$Td+,"O:#& q┒;9+V pS_']#G9{ @OZH^\_w3smj9#.[:]=qNb5=u@#'c W~Kɬ3$)[e#kD9T]m4{ٮ27+1ֳPA%UɉT(c[* W~a)b24nǶ(vyiM]rdvʄN4o__ͳE Oy/ns) }QKZDZOkUC^-YɷƓaa9NCGJ{Y};!*mvFϹAf֜Rߧg;F:[ƫ'Q(FNth$Oܞm/v]s:F_7rʭ{/C:X}:&_ӟd䨋|VNh8J@0{|ogKLJkBt Gb'1qғX]7-FOƿ.SYgl`p| HsCzvW{ZUpog߼?[;F+סO`-5\}\P;vPQ0y ̹ek?-`[-=K n(ٖ꧓F{ <7[ D}Q͡2 _'?h "*Av^ -'ɱҭUO1;(u;`LN'C7!:Ց6Qxc?gP>Z7~z.xDmu#dsl<@hd]KNtL{T|ۜw͐}0,LWDf`E(myZZ;I)0[ޝ3PDK9Go(2ayج80y<`m.NؙcztojW'kA l+լZWQK'wROGIq-'^JNϼǚ ,Yf9|_]nЮNA}@WyAn7h:^ UvI^8‰7q;uĺJ|*$&@@̨!jB~[9`_6Wt,A0NuO t9A}"l9>n4k.I2LK4M#wȰ ,7&hlH1m)6y㽠@Pi8t#{{߰_z/g)o‹`?ڟ>3v)26V.,P_jD[ڋ.gpkmR)UfϓjUW3"fӇ蚠Li[uxo!ڐ*0^G6ã8Xsbxz}k@dSVe>13XO__־OA(O4;@S]??/d\3-=05ٖ!퀠?y}R,Ѿ Ѝ}^6?Ͽ;6AL* x7|%ZaRcС~ ա~z{/O³1 FE:XΓ|RnYO>L%[`*=舟oLUݭfo7ԡ[oV}ԃ\嵕S%Xb%ZG7A߷b 4D0+) Gi40jזv0d c_mWG'^ꃾ_|>J߆4ŵT.H "bhJcgƊQ1*:A-UY|<ߞke>'-h[ F`㮽ThItfw2ux©;s0Ȍ |H2R`23\$N9GMr(<*lhuu!f (?\h/h)Vv{ы.e=dN)`PPMzZLج 0k͜]K{%gG&Y ƸΏzN I\Ӕ3 oO+7Q]z^?HfK7rSӫ+:~ѹCu^dtl ϡvHW3; Q';c<\|~Y*mξrYDlƀ˧̗_~6̾նTxkG,]6=i-i_q3_xdbʋK{ÀS;Q?Yӭ@ArgekShg'r=Cbi{ϼme9tm`H=txlAR/XPoyͩt3}y@k4(`~fw2N_v/IlNX]-+{?G6Yݥꥬtf)XS]mh yQeRz$h|#PY^]g&8}KpOѪY,A++H' hp7y+rgc,{OGxT˦>vixL6At`yuنbPewyi $ir9#NYofpr|0taU`QS0 IDAT=Gq@1cť}Co`N}_]҇-Ȉ*MV'оW9O;=gE;kiɨҮt3X/wշlCuhZE@8ILK|N AMX݃@`MF $cg,өHPЍ] pejoAXyuwt* 9Y٧'@@ݾO4`w_J u㑬qL$")9:(.YG[%^1;LhIeI׽a+ C[o~?uM›.m!3~&O3Lx^=gWvAXBP!}ڱRP O2Rfg Bo|˟~s jx,ƙ1.}mMjinp1F oYʽX+&g@Ó1y4>3 _[V_X9?U: 9Ѳ&ߒsLL\:f誠_vunn?"C{ yA#0*o~sO?e!t'[ήԀ8S}*kL?͞kKpx^xެ> n+K4#O!M {0'@l )ܓѵ39s<#Շݚj |J{`p$, XB>/;h|sk!ƱDl}@ )$|N" S۞͒F@2Z_z_[#xy 9sY08WH8=ϻ-\ȄьRO}$8oZ9sƭa,[Ka9E)ϐ N矾 &hזv̅@akw[ѿN~,  9R ]3Ú7r Uͣ , E2~i0U~,.Zh۶Qxnl5g)QJGW}_dY@x 5-3_ ʬc-oMC0;0Ѽ}}-iWXCZǞGʳ-֦g+Eckv ~o% Wi4*#|y~h h6裞ݽWx~L3Φo @6+?AZxS1 OeZ+xD7ȇ쁾m Qpwa5vf?F uZ2 Gr7tG/jX 9iݞ(e{Jޙ"ʗXO:I~pʱ'dփS, KL ٕIj OH19 eɦ߮2WO7DzI#m. Jfgc1ӤWx;U{-|V,W,_-տ .^;D0!RexX17Vd`BeTSe_[ũu[a~ G D,AHFJ ;NJo_wKjO3*ʝQQ&Qڳp:5ck 3F9 K cOK'ڂ8o00~*cv9wf޴lq(Z\H~0fu`dua ^uz<}OlLwW!}݁bN;$9& ^P}/;~鮾O 9ܡ S-l):|29Ofd<ҫʞ-ՕgɡgY:~=-pV ko4ߗ!n! {><!}PW6 ^s ,NP/7>Gdo.QrǓ6yC+}ȜzVֵ_<);.Iehm k"z8kS6-u/p?Ϣ ట *i2^ 8Btbǖ ^Y ;s/U_t"O :ṕt)yEd=VOQlT?3A/:ZE&`(ɜcUiV!l}y gpNHd[e8[ ;Z-~$+skYf?W@/<+P WI}|wY9q hTυѲ&߅S 2:涃NiP◢ x;1~U{5 hW?RhBnNN}QoW705[mFykb'jowXd\J|0f6V2D&+ݕ|O'vu-ޠ]pOk.T2udэH|8C~ū[*`i%ӳi<vl4Ϟɂz6 %|x~2PfV?VlТt৾>]p|hc6"Oս?^b{ goPNg *o0vR+d&yyY{C~o08!'@x:v~4YdՇ׽> k`5zYm$#|'v:j*4t3}hV1;44h0]BmD:x~s6]^P 鎭{·K >4@hfsE[LOZ}1ou' rz) okpoڲl_oo|59 'ޯ/k9-H-L+j)}j`p j4Ҷ'^ڥcMT礤2 83 +Xar5` 5(=#d8%rj 2|)oFh_хw߶_<]E c p#Vd<129 ˃#1ڏ~C AG'Ki֙[x$]s06kF_"seSГV@!:&^~NU"J72gdq'{;Sw|]$=u,Ol , " 8==Έ5>=kY^y"{sLJ. YEP9*<נUr+Xj/FPwa`}!o#[p F3_'K#tă-,@Enwճ2k$.0Q.J`vWplpt]ڜ/rÿ; p~~kCZmmnywɆoE)+ئVʻg 44+5"72u_ű~6ʹRoP" ^o r:CCW;VGײzw%A{eDT7XHMF\r|-+<9fik6U{oqU@3J$0ǧ'ʜ^ZVnSȮ =8 gA˒{ mkK5)iTujz {ΊYipIgybwZf "jA[1=3,rt/?.H`@5xSf.O[2,bŽnFx:A/"r{Trqhe[bQfU$EUwo=a p\ُ_CL=Ohό= T^]/0wyulnN! ݂Dq~i΅1р[Ck]9#( V`4pe̓VYp~nW>o4hs!^Ŧu{Wm++hKӗ:;u0>̉ bAL#A;9ʂj&hझ F$d䠶LҒ2^ouZ}JA4sk/*ϹUתs.o3s:^E,rūA33rUu͒+nzw#:L.Zo9[iTvnZ3GcUv-/,W/Ɏss' azcF'^eNt5[-f.+7PB ͓>ytZN@ܶ"F1ߥo%KWT%x;z!+ʫ~*ty+^4#n" r+O>؉p`9x+ad$0you}W?':8 ¬\vגiݮ#wΜؓtQD2^VΓۏ}6-/D~ ݥ^7X=q_Hsms+m|'9+3?rK$/G8 Rǟ QhNVvj8%q_VhPC5'ҵwl穞RD6V|MK_+%4˧No,=v݄,ilRy d:;rVgNҐB>٩#a T'?[6+3f[mӷMlяWϫ wf 6fv[lY/*?YםZeĦ<,^>K$!yTV%W}o +s"냾yoOQ {NxԧYzҀ: Ҋ]l]I R3^<Lj' +ˏmof_/~AU_riׯY۳e[z[mM]њ[m[У5~Û?y1I262^~8{op*]}>JϜֹĕN#lFF~Uأ{%q!eiT5{Gʾ]2g'q:[ArH޽6BٍVɸ <y봣Cgb9g4 uɶ@_op~2\yc;"J]'oʯ>t ?d9h, J5L]QMGk4)H7^1asZ?zڀp;%jF:'+O_#ʰt!x9@( ,7Gzth ̞ :8/`tf|GɨzxRMudUF NnB@I~={w-Gf.Zcu2=,kmУn&fvgeek+'4&)CKvtj:_e%i+P̡ۊ:|B6ONyf %oykGӅZޮ:nM❣>$̾у6Ki^a'l`=zlOe䍤hOM)jtwс) <~IGl6pW&rhL"҅c4$;zbMO|o.I ^ȚC؍S֡Y[CSơj DMn'}2@#/KtTAG(UlN,yXmPu*|Ij#A(0[](ɶ H̨ ew8m2 '[$V+e0E[d4ZQG]ZȶD |Ǐxn޾w}]g3c4o@j= \W.\Ξc~3hYf'TgEN>w{3 3{3Cq;tmO7gCۂobin,$t΅~G_9gk| Rͻi\ k^v8ȉ7M2/hMte)Hml>r5u]2yVw,jL@?$t|*H}+6'^6#ъ 3f0l;9b*xW|&Uio4}.%oB"x5Xpx#&ly'>I=B I؇/f IDAT~_a'=F{wxEJg {A˥eҹp:oa4v v3c*͈Ud19fZGۂ$(Q׳S2l(V Yx-^cm9d@ :ڵ $ؖkkb%A06wϮ[FGϐ?Gry\`<<'qĠwW&+DJgV2*/XKzoI d ݗfa~ \FƈCOW ނ.7ʷ팁JA4kn5%*k8:L ldu3ǬY!U.[ '",S'x~kw!5Wp@?^j?-PRXWW/wѭΞJ:S^⡴%V^OdϞ7o]>'9>)qTȑl?+?hIْ@YmJ.DZ *YW[6{ gVVbE3oV%5`t=N?iVm8,a-U nmyBAQ6%}PVŭ<6f|_<^_q7|+t4VN1t `Á>zbꖶgg2R:;K+kdyM@rftqF9;Ō=i_pz5 oHT(?'_#84QusyNV^6yN'9 dw<:\_Ԓ9pve밫?u8'+oߘW}D}xvKɯe{qXKj:ou`''Ec4 $#9utČ@2N#^d|{0{0[ _{`xi+ kro@zu`3X}op(f-G]zx0+ݮ. f})ZI~Vې9G7WX&EΤLsȣ|&I@yhWߵ= 'wOkZz&L= OX}l[Q$pK !IƑa̮ϛkhTˬ E{ 3FmsL |Kykάty۾3,s,`z@|wg3 <- ,a?mu@eRΠr3|Ax*~G0}3ҒȀlփ>G-\Y`*.?Ջ:@ `_.2udd 7]R~3&~Ê6ɣNb~6pW#r92}u ڮ7 l'n`6"+ <+C cXpPhi||{M/'8N7#ݗoK#+-0;q+th{ryh2-EÂur/߂p m u+ -LFq!%+kS]A 'vo)_Xau{u+z&KB-u.=9yġ vj710~ >w.LJoy_T>}V^h?{#7;.16;핧C*Y} V}=Jߞ-c8c8gVOOsw|e pDʫ |~]I=><ҳ!{r§z49Ǵ' mu3C WhߧW=f6+I>i,0`ꁅ, \Ez [٠EҢNw{+j/;y]%jw3PN~ho/gEu~YZk@n3e'E"Ϛung#ϯV\[dN+C^-em]/cC=ϙ:;hӿsskɯ~t ;N ұc@ _} ͢_p=W;9wICyvdڄΠQ^O.-^>@ӥ^iO^=wk5U}L7_ӦBF^g#uuھ4ȃ5;"}I ~uZIBԘSܾ][d @ߦ%@ VϽ-pwvu9kHHl<[o!~l*3d7?m[?U/=à8G[_)A+68Wu򾕒ˇ>~a<+nقG6 &Ϗn `p=9>Q(?S!j]ęd t{ϓ9B5ck@Ԁ~@՘j1 y~P޶YSחUl~gX;ͨ~uTTό;cto` fQu3}"3:/9eA9;Z^k>ASNӀ@:GcAFfp81 i#yƗ?-ifӵ s*+^).*f0ecUyd[Vە~W+2=@ҷ?pLDeIJu_T#U4Fmu1 dՉ읃ҳNց A=u:;o"" m%% cƙKS@^:A'|ե`OЦ6,M{UW7/ZQbvf{>}=3ɡ`;&/yUg}Ӂ򬽠]3uɁ.;LUs΄<[hL因҈dg rO/WВE[Nx,F afK^zFl$.8Wt1 Z,K+cpO?iwǦ8ow^+8KH?o=8Խ-Cԧ3N<=d8saޭd [)T=`]Dw`##g0*9ѧ9^-~_6NOߣvuQAx?\.?l]6{fV&}D 1FYiNl*?1K  $o+ߣQ8gmrY`3! TPUw%^*k$^iXo6A#ۊ~}+zj=3hmԳܷWW2=}|ȪK~]1hatX^v#0v:{#j{D]ي_~Awpjw~N!2շ`vliZq{jVڣ~5>|2~ݠA~3}g3{5|`r' ^ؠs"?mE,O?r>qM'tL\umR|d}=Ƕ޽[$emk}?k G ٔր~ +Ӭ̂ft5ҟjX٥j'+/_4<5r( ~mx kB3/9ݟ}ih0h;NjytV(O08}w[Jeƒۅs\xKgU\p4p msNBS7fäb?KNp?O>&_ʈ79 7-),;xg>q+([zR5ӳz$։3wM2X} [-!6=\O8zNF=_=`z9)w4lxÇ8H4Z9cڞt@oV߂k]VNo3tYf5`!8?lCrh{};^Jt\h& GdԽF~ xOd.h`~p0ͺ*SN'!pvoP(“[pTUڦNNv,8?,;C6I _ݾW& att(> \w?ޫ{-rTϦC4=Q#|W0[t!+=.\UWo ]Y9Sm)[4Hn=M($ ty20 8Q&}g+ޮ@g ր+be饭EEy,2-Fl5GYϛwv-٫ JWE/VҞ@M.A2a\`u<]Hqk/ɟ#."AX)\]]~>7 7Ue%ցS6*%b}^-XgS_-){j3g3;oZ=I'^-]^;foɭHVz{ f_NQffc)ѭ@|xZ.H]@ƃ%mᨾ7dIJ>N00X-h4@kM?c퇞/[L2I,^ȁxevk?tzdX3;-H #AW߳}Q}З`/=6Lǻw VneUh}nxӏ' # \2Htߗގ@VX7s p#dLמ5AGOx#ْ`TJ #pf|+$zKѱF6Ny^?MҗYU~w/$O7H0&6P7ϾEs0TX;rMsk/lV=ܭԭCuO5[^ȸlKgJX vAw| _MY1ݼy}|%e?(?c.|35ŋo~^AAK2/Vk?A)2 2}1ӌ3ۯ|Ab2ty^= gk htm6Js6gp8q.i%3fd$= FPGSF1•csj,+Ǐ'3 9pฐվi'KF oޘXl8cN] V`^'e?ԉ!s<Ȱkȇ%TL4ࡌ J6;;ç:f?[@zP^߽ 'Wk' Nmt(-%Y> 6^gO=xɶQx4Kk;7I{X'FӑѴ,o IDAT-\~t!K>!$M-"ݳhzG_Qp6a8O1Seg6=`45U8i9uLrέItxb)\ gu[ǃ*(p0j26@;u{tQWՓgNrŢsqJ'$Gset@;:@|r&h|Ӄo[zV|gVR?# ]XfA 2VB|2ʹ 5O4ѰYx񜌂@ΙE?2GR!m>f&ׯٻoy;f/b{ ff֫ rlZ-W2O%}Cw|jyx޷a{sn1xS޳Z9lBnހA@(X lU`͠tYFOo`nqu_' Lq"vx)vOhȊIvG K \yaǐ[tifEKw-+Bv0N= B'y7 R 2=K7Oc<~XHkkxٽqӿ5B d72Vl3Ƴ_==fV͊=p!bƫvgA`y~upQW8':-GAAZv2zU0 |ګaw`|͏'e] 7mӭV4oCi`҆m)(CC;>DmIؠw@#C[;w|d@*V5d_w.BpZ> s_uvҒ[qݹ=kh+C,WFCnK+Z01^lw3C|r\|@s`o @I#h6X5YѠ&:\B`kУzjN:[#*_R6;ܺ J/Pesz<{qM}u ^Fo0=坬k; $Fu; FQt2}`NȽVU:#(|`$ =G$_G VEpj |)oxxU-ʮsK6|0m=NVS`8>WG?gh72fO}5cUGș_gP`gG=IE}ݓsJ?F`JtAqң:62R sd8o{9PхoLƥMhzIk|N8՟}y8u6IIA8,G$ (&xsm5ElfxHB>gM=h3JOB]}ٻKvf'޶O *xdom*\ۮm50" ~ 4'3٢ = =]WzwpJ#0z̳*{9G:V9| Q}>,75+m+l K}H+r H Sgޅgzɹ|U zI7~qpK_zL?1t*e̗?gZ]:W~CQl٤puf 2ڟ<~rov4ʀ` +ϒkE W>OrMVOu@e#s  gIE^%t@莐eFwJZ_lo C-h&(`";2C;*;" -/u: Sz{՜rm|yuW:^m~{m^T[,mHpiWz^t:еPeQ;9y>@E3Ӎmv_`6j[ʃN,;ۦ̕`|+ Pb'ϳ pե4 zFdDl`teGR`W; _z}ܡ rȬJw.At|ҲWaGv_X6@򾪾Tdmk7=G4@7bёLPovIUA'OO7pu4wzUgiw4.zW=?M/4yi)k! [m1-{O*Ώo_w'?BG=`۲Sׂ[5"1KCw15s|/VYβE9}6ɔ1`f1,h= ݘ=Z\g.Ki)>}vk"0 >_|aar4kS6L|c͜v2N䠚mՁ{$8ӳxm{G`7+'s\,W 8# :+4yb{f?ʆgv凡cYbop nO1 :)߸-]㌫+S7ӯj2|pδpFq9¥<÷]GZw)M?@E[C,=rY D&K@ݏaOo˲|2RU*MHU&`@@ h $FQ0@C al0`$ZL&@@`16(TUνORG{^k^k{#>ѤshKHH{ć9 ouG]_) ''n1SU/]o݃w=ytw#Nj\6w+l@, X>>̆QK01U*5(qe@\Km8\+ӵ }A@_o+tU~t<^孽H2y9xGPS4 :_)h~ +)+ả)w㥥 \ewECN=>t4~mJA˵]6dFȍ_{h&]< WU_mFWn>hd 6~ ?Mu3U?t^q{1$>]~;4p49z+>==Əu ++N?)G_yگ5 q++Fڏ, ͩsh8i-ݭauן<=Bv4?Ֆ3kkTzNٛ@e_/M1wQ^(C'Bh@8Z99UkY {8d3YxqN켼F {QCt_r(vmF.gE/c.gsRjs>(7JrW$΁Gg 4=יdhaIřEprd]=ߕF-?397ioV :ESFqg<s9s:c!!<m>*h7rxTģ`ms8E/:>:'~|Xq{~'>x6Y!o 7YCvQXU6=V"`-~q/:H3͉v`F#g _+b=_@۵ 0'd%4ѵwc(,g T.}a޽ޥfLT/ϛd+ smr[Ǘ{a$k/T{gyn<bU]2 {/qO]  +QJrxn0v\:,hJ&+?Dr>!z֨m['KE*h8 FOVAɅ6fmL"QzK|̧4uxf7RbϜg|g:&ǧtO7Óa4oyǿ;#*WlnI{drh8+f0pTGZNGI}m_#hfO0 wioDdA~FW FMR[6`h;#ءd>^ (5%۞j l$"%򜲮mCgOjSt|34>ٳ }Ӯ[׾#x'TP\SSG`Kx_^.xFkэsq8/P=Hn%>+o\zWހZ/z!]|k'=[N^Yd;GVFd מb9_=׉X]uwN <~Nk#Ws87&O6OզcVO[=zkr@`4ѿd2]pGPtJ&G=$Op1l`yor,7lvg9-fsYlz Ԯ6,.^mENɑ:`O ΃ <@N&_x~7=2UJW8[䧺%ΔQ>=ϼ^pAnS -qы`հMj_N?dwt/Nsxy?7fSNS9s|(מ_-Ҝi ґL)lxqӧe1Pih:#m5XQ:f0m8^idgvz視^ezuV{s0"s<3U@4cPHRM^߆oF"s0<~v^yYP(mv D60k| 'WzQpWtN0 Qtvӗ*YZ6>=9G8+֭d\Wz  :Bbo{ ,ю% |5ޏ_kdtK`>-P e>hpNg{^g]<;_:\ Hzq^RF -č\@wEm@_x9=9Q GX$SIP֎s@!(Tݎ'ONpUx76/P>&V {hmL޽sd,2NHL8kW6WO;OG/ v_bM:?kw=?e*rxp|^f< tL'j)P>k3BbXro軝|Ỽ{*yfG]Ag_'#+JSA״5u dhY4C`3G68# _kN3F)NrL+r"PT6mg^9;R֦,1X V#- YTg;ӽOybS92`R̽mG&8Ƴ"g ;m*Y vl?}˷-N|=ҝ̀懊#;^?N/_OGo_{#M1qBe엝c@s:ְ2kO>CaxIu?I!#=h5lgڕ!ʕ7 JҬS9X$QiߔFKk? Y 1)*o6:X9f@~y_/thǟ|;w>_91:)ӱƇ_^1\>^}G6]ÓqК jJ5^o$0< s hӳ9{_ ?prfdLF\M䂏>'2zG[woi!<ąNh=CEtzQy6stlG^9~QX$PpE'K<'8gFc5SyFu7[2u}GZTdzǀуNF&>My IDATY9pKOh+۔ mhJ߿cVyhkm28yhҚp}*5eF O^W uRtuz%ں"U{ѴMm}D[x9y7I8dkp/"v"5|*?^=)&|?;>Fm&FY3{qr0X9#F;=`qT]_>ȴ  ^8݋-Iy>GxY[MuxijGz:Kodl$>q[W^{[7#<7>:j<,Mu!a#6EO69%SzCxӝ0{<1^iZ={8͉Co>&GN>h ȉ>WcPL>Lju2x3{g'S|+Oh|xq>.Hнˌ-Oȑh,d!j`x:2 \[9+MHuIX~QzߵEnW]yʆ*[W9V9%Ŀ-<>.;|58$Qvv+q?JWԁ:ѻ+ @6vrXNIK?6=x%ǁ@wAᯝ 9gqxp~;k-JF4U7c|y2E>/|^r}ۦG4 g\'ޒ>Kt{F: ,G,۱`|#ՃY^w?R`3e V4]soemDvY"++ٳ|XЀ@Ѯ>` 0cx/~^rL xMp5%C07E+ZG'S병:Qh'ryNiKBQ׋LcpnzSۆn!F.ʓ1nindB ;D=.]h|w[7Šy`AZJ^:̍ ˜5p׷D"^'q|Ats8 lup8(17`O(OF˙'wAh:*^wK u~C^9Ɗv0L'ކ: umtҖ^P#)_g1NKꁼMMZ%:,w 66䁣 TʻȻd:N}ޚm;}ftAϨGα`^._: E%twDS٭Mz{ˈu/K[zzt[?*wIƁ1$萏?ʹL>d@[DXp>tg&>;)Cf0f `!?o@yI/헱9E:+=912~WUkLXH"SD|7*#{,lOCC >gs$ x[IkjQÈ%KX[C"3)ҷkWΔЂL`$no }l`yלxrs|K3${6Y. >y3\$H|i_iƮFPIJ [Le96k3AʼmD<wVިpK;@6MGЛ:ÿeyuRDNW8^T9& H@׼L]i{kx~~9MM)8,ܺrƴc}}N30F.k 1nA=> pF(ֶvGiSgZ.[- \@~Ѻ1Bgy6B;8i1nF 2{ ]K.nNh0X޵S7=J6V:4z#uV` >ӕIksXЭ*}jTFad0wt/e{̞nskO߹ ]9p_y`aIl15v`j硠$p[Z؄P!-st7HI{иZj"|S9 S$exk3(4)-7kB=39{4Xm ,^7\ɀ鬲6ؔ| *qs=L?ΰ8gxuʣn"\)fFEE!k*xf( D|,JY`m`.Hu.Ѷg3J)HzVx1}NZo?8:^|#@K>8*騗WxԳQNQxz[p;= GaR:g;<)3bz٨VX?#>"r'GhlىWK{/e)ȕ2Fki33R.c^iqPt?wf/BqCe:Fo RƋFmіtp%dpr40k)LFg ^/`.;d<|;^y)_Z]SSKstJGZWB/q0laԡc$cFl8o!ڽK. rMPaye#Z^zatчIl^#c|W!`Tdwmq&{sr~LjFh4m e=eX g4Y U)udfp7SFquH8Eh [>ו́To$o<2;F3 cWA'=(13HeKF+xg0pf8CwovR'_O)m%Gb2<.lԨ/YemX#ls0_:sjfû.ʢ}zPXݷިШq8cokdd`؇'"{?fKT>_uytR+4uA 9۞ $gz;~Td7Xt'YhEg+W;?' z%gGQ9^]k!l\Z'Ge䭌Ϻ^D]\\4U51PA9J(<>MD_K'dzi$uҺwn/5C<g~rV O]}w|WpEA~0=[G] %k_Fvp 7Ԇ7o}_y~K7%?58KWտWa_o_է{_)*/#_;o}9ǟS;<ŷs=$Dzlʻc~ 㱛v 'Xf`[#fSp0Ku 9Q2*wKkcL>rtKNÏ0 s}?#5GtRe2;%4=EpV@u=;:^pdh_uo10\t :H>>-]k_ʸpD!ڳmJ, ohKV;:h4S`@SO{=NLq(,U c`P\|>UD6?k?h٣9$Wxlj<ʖơ^ubakVgn?Z^`tz4S3Ra0qF|`}۳$Lxq'[OxcJІaNGu*,k֚>kO՝k6T<*h~v3|`k^#Dj--aN +}Agy%%3*OG+j'V U_K频 ̐o[wtɠ[2hPǒCFV2pd`vo֦[dH '\({Kuv #apzUW6Fn=?<|8$N@FhtSJQ9?"zNyFrDṪ>\<>]5{ IF0ɶ?^yT4 0%zCo0?dAhz H͑䗷Cdž.BŜp:8`aDMW+:F 8o9#h<>w:ޥ5_vo-';K*oG%2T} m&=;c.9Iѿ,㝼x3xdnUSx*ҡ)!!q87S'Xt.br-mG{x#}`w28Z'.@@5w9$)L5Dfu Z!|:{YY^QzTD/6kGh#xDK^~]΋^.P /s?vgdva ޥPMiu#4V;'ፘ{N|~a,^~O;?N?|ڭӟdD'<}gv9p/ӧ1?d&›[ycjM-~O?R(~>>z]O?9>N[NoƛG>wkOJ0E"t.60d-=ųo:_q}x+~RwvIݞWL]l*|Bʉ#eWP`0z՝  2렻Uic"~:Mo_GŰaS&OLTyڨh2|ՔNjf (#Jὖr3mmtSp|Z Rÿ?mz6RXo~h?)qtp+U-"܌5Pg!勷н QG,xx6J\:M# 9| _ʷ O?| sO_j:/` ;x}&CK%ϣrL): ?alZW~ ::Lu:olNz'':=_dN f4kej4>|3Zji2tmm5 ;+GIc1my˒x4 xEٹiݳaDm@d+6?9vy9C%u`c./# Ttv]w3,P.{b4w30}pSʽG`F38prWf}fW6L>۟p&^7 pXpvʯ:TF>=嫾myr!ǁ^OJrl~zW9@>Jc_ ]?#g;5y|D"-:t+@tLݣs1G¿P<<1/:c+f.Mp5g%=oJ1KWziOoOWfӽXܝm(׽p*RK@1C_Qxh8܎LOןB"Ub6ρWѪjDWh% Y|wu# _/9 >֌3|ԽQ'6ovkdX%ހtHfh- &sꭩ[:ATHge %:Io~w{Vҗ񻵃rr6r] /x6o6t>]=a?Wݏ5u -+犷hjp(ʽDJ/CDt#l3]U7>0+Av|!<^|>e{pfu^#2,yoǖx2,zC8y$[Z>hɒS d>5 ?{aFyE 7 Q ,hQ[hH{C?^(p@=;'̵ί}ܳ2|ѥ \{:|f`[ kCջ+|6{ꐫ1*GoBCqo3lA> O_+O_׿>:_/(K|oNb77~Oɧ_K~ɜw _KAO`NOW~W~+Ի/?6@ :_|^k|>/>N?'B}?7ׂBw)`g8ǫ(е7XQa?|ϥ?J\:ZO8Fb;Xcp6RU#T3*tR 29|;Hq25pՍ>%}aisR}畢 Q"(#å!tcr<?h oC IDAT_܏zs4Pz_$[`S5uXgu% +hN{We[#W7x<q|˟/S)Ms$[婔(X.|(x5׍WݛCw?3OTH<Wg[ZmlOPool/rw?/.k߻hG<.Wy9%ɨ8] 8Mw:eSX`q[g.2ǽ0" 'suɿыظ| H(ڶzAO +? tp{JA2⸭#p,(-ʲkӏ{#j5X61t,Eb 63t7CtV̽t ܫ8HiWLwuwtu}œsR`}ZhڧC:^ݧAl{Fa;dM9H@o2]sC;٥  \*aZϵ18s/[e\P1O ݨd~^$y_J ~}>e 7FoM]%A1-O,adLYɌg[ o@O^k|rMet@"ƙf-ꦔ~sd@ vAIAHkQ`;mx}g9?9SpXdeFٻ8}RۍkUWzfhډHAޔ` Mrvo\Ⱦ\dcNy+2(Q!}z9|Gk(_xv]BUTf,݌33F{Rmܟ!yg[۷$cg}O6wQ_!k!FT#xs)̟ efC܀A躢_K'lFnvEDyYUƃйB}2\v?pz>T ?m֗-Xs/dL sdЌI3*Nvj|A4]!=_egOQawkm[~܏;}ʧ|}_ܜW_?G9ߝ ~[S[#~ďxD0,SOoY __^;}O;?oG@KK˾V Go_u3>?tCOӟ3f_|41_71㍎P@,iT>:RqZ 8^kV1tQ03Pzx.g<9071d:]h́ 4Q) -z (N). -mitt#/!#NiϺ8`d)*  rZ ~uXA0Mw@8:  >0fa$8r̖p?ޠ>H䜷3*(QFQ V3D`GPї'+6VPhl3F&c n.r,ĢI M0b='_.ƿ8@޺W; ,@rcå瓣1B uG^M:[ϯ6<|#7' ק \^6Ó^IZpTחV^p (݌f6Iw<=8{)dt"T_t#rk {;q3sjw`(#[:н#ژ,yʞS.mMoj60=ׯvH<UGYzו|.^_?+ 6^_h]mn%ʖep~!!PLH+x.=Щl<#\j $lvȎF/!0gbQWoz| C9ߝviqq} ߰oo9=ٳ˗kS ?lw9.|}/<[u Ni?'D_㛭F>>+܌S/r^OO~e 7'vA!`Q]8qw}td2^\fTK+ʫ<%SΫӽrVJC9pSg'Y{-엢ZXw(;p.zR.Dk){-9Ilz[ ShJ:; G'_2(s.H!5δVCL\IJou;(d/r9:wsv]n#E3)zm3v҂&d+z]ֱ`\zM"7 '@:ec(_Sۛ!$ɟ|6 N/=ѭZQd=_m%d W|~vݕa;#YaY=.wG0&La2û{v,*.>9$ qS]>q8s\:ZBpFk4Cowt5rv(. } #0lFio{?4rj3 6zUPP~'^ˉ(m͌ڡf|y:xrmA2qr7P0"0f%y3w1va&EhZ]` 4L7|?{p;{eᱜ*9̐|"tF'6>x@+JuQZKTͣ}/~ 0ޭYMlڲ`]͉8LCƍW{khMBKtsRdm J|#n@/M)=F-unL~{eHTfJo;Zas/'`rEb>O;AgeZ{̽+?q+mCb{;s/N<.ss 7uxv.GK^hGL#ޣ#!xo+/ 6CxmY;dXEyR0 :k#[S>-SJhs 2 DDPݼяxRʨVZ+F{'mvcAC Nf_W`* -9ݲ1}A~ע-=8n࠳8ƃff:6d \Lf|~6){rb]K3 XŠ$ǫ ˯\'4-/]u~o e3^g=Wz047: :sħ@ω O|;Oʵ 7dǣ6{f SU_U[/~=t~/Z ot|WxQ>pdś7*?{ 9 IM;1A*Ô=夁Ԩ,'#˓5"eI!wr7K2lRe}-C{ H8Gf0{}lԾڏ1r?y$ZģC(`[o鶴%ᒞa(rlx"5Գ7#opSαÉLB NxJ~lY;`\Fz2ZKa\1Ųstk:LdF? oSnA@12Zzresz ě;bykJIZk_ܬ*eD֦⡺p:`O&9Oh3c7 rXd䨞]7Oovu@dUı߀=`NV9^r${Y+)񸲷_@Ȃ} Cgxw۬p}%;vϸ,~"z'ثPsa".ݦikLݷ^g2.[ѭEl~gAYPlrxyzR e;y'ص.z{5SmTt=}u ʰ/ 3f ޘAr;9Ԯ#҆P <>LOWhPw{=ٚc_L8੾^!@R|\ZA2x + r-@9n3@h}]yݎwW>}3[ B7d;|}o188yQ/މLӺ9z蚬!%+T3:gsKPlPnxs4 FIs$[o'6UEi ;z't#u޳M ̄ДУ]Oe7[9_5^ \lL;h5U(9O)/&ZsK&D%pSt|tNzP6=|]}_uizhO[CG# 3F@.ޯo(K^;=Uy vU a8ThOpeŮԷUFxTfL8=Á/ _?pF ̣=y̰{W 6Ҍ+ޯo^L5ӥţMU:Tٵ"(W~ԇho FtG|pS~g~> ^7%sּ'~^ h//83$w~{g߬\˽};[Nvց~&{޳6S5E_E?֣_*x}{,pf|}f?Ve?g-+x'{wYzNU~È}(+ϭA9뙶 "(qLq|q՘NMwmT:cPJKAd5w_LylV# 5vZFA6:U|4`]^JG4ǑQѣFtV`FңcFf<냞M)hz/D4p $y0)鋳. NzKisxFΪD ,xi6OiJu*o5$^> ( `3Owz 0+{ Zʚ쨷ft $_OCOSF܃ӷ}7';u4堃!h1 GrȽ}WY1k:{P@7:!n~|QOh5x}L,9^1{io 竍rMW| ;7jpPc/~Mf{`$bz|^qwo¼p+:}@æ]2;Q/:L}lp#;>rSs`O株glVoÿ<1P|o`8J9}ۇ*3[h۾e+-9`!SdQMp}x'\]= jtFU@fpmlXZ\3x[?}B^&zKmvHmdݓcy摥19ɒ\7[O8}@ s)OzpopoTFtp>.N]D)^ y HB?T6;?>{%+->W~%@nOI9hqz=ڏjK(vmׂC&.߮T)rOYxs#~82\]pfϞo2&鵓ӗ̇?ZKj>RGNplsdmBW}nt.@k]kSr'Jel{+?Rvz~S>~-(=ȾWeˌQSYdꤙU~l'eL z@6nq%{a` {ˀ i:Vsl ڿ@凛e "پ/P[uf P#&(l>}g}5uotܟ9M0t!(g|c_KO_?8^ymOGi8??NT}-{8/]Pn8erPVV= m$=y`8r~ v!G>=#.ݔҜ;N(\r0|kkIaTßN0Ss􇎎A]Cq\2X9C.[4R9e^Ys4G0Bki;tѿ޺h#_r }W(S|Səe3/l#w4~`gZ8vO]W_9X}QՁWL).z]p>ugGuҏ|Ҡu 1n|:gт\= H`sԓ4?ɯS93SC'gJ2Zc2z>1&Fp#іr3U1R&`ƂDQcMX VIw^.؃txmQ9p~Y}TN#XoxDK) Z8OgEϝ✚ʼ1rlW?tFy8y|2e݂0N/,fLF!n#ms0'7K"҂~㡲7p9R*5. `6𻗁wMƆqI1`}p` z_)JFrx7 ˋS-e˰ei63) YĿ4yvV3X'܉r5 xx+-ڞ>9Lês\6ApXМ7twfLo|9}#k9o1@Oj~sr!1H#] :J|]~ Nd+K`yk#>^)6ʡܨ*~{sGYPo8 _<*J|ޜ=[;!CXW,p;W|ߧO+v9}7i{c@ ~#w6x7zm`s9vM"X}f2gW w(H~oe=8KH;l [y*悃2cj)_90].7OVq &6~ok/2GNj`ñgg1OO;7> 7q6g ggP6?5F " Cܡu^S7 R1f=;J[,Ǩ`߁/p +k#j:g)~2??cK\μf|+6CS{h%޽i=Wl 9G:ʗkBk/ ?ͪ4sanhc8#%3t'yyvi:ʁs KnCFQߣՕ3@/ǞEAky6S#g MnxWhȈ4!~ui#p0&tMٜ&*8@IEc^zxưY%s{λ(%Z=|$h"+7{ȞW?ɉ;Y|cH埃>Q. Bwx9q5> Cg&t #$A⇬{'seDh9 fk" as7 +3BPl]13+̞~g6:y_p8whܫ^M~-gPhވwG^Q~14uy't{86y.9bJGZ+ W31Bo tsSdS_8ࢮ4ʍ|ui,#k/h0N @c_P:{䓏Sod`~łs_6:%]ס ˷aS{.??Q`luk^ׅnr&'}'~S7QeiqN #?I7c d,=sܭݾD?g琗^uu]uv#/7yt_- tM 6<%n#=Z1HP]6rWo֩-!*|yؠ U/5~+]cxբvYꀗVXwB#~WOFɃYڏ}ƈ3c ~q[R"M9kt<ߦGg%ZiOjf2lcd!;:[sC5/S`e'A1Yf?,@6|$f٧~ "+S,[+~v%m_t Lo)+lv7=hKO{gyx3u_O/{ZlKZD?>v|~PLeQ`< Kch~e4=pjhUZ39](3DKQߔzk}ڣ`y|;"-F0ἀDE"c~<1>.aHLp+Őrl pA^3"3 q 8otYݞA]sn*.OroC =bv2Pw4 ԍ8^ OX=%Ͼ=z+1s겤ZtXF XP֛X>tnD4QM,SspKo}#a6HkGvq(Qf'^Qs"oNfoQ/qo8ݨ Z9gʍE։: 6 }dU2MtA-u G-ʢ?d$oWz1U: pؽ RvI=|;fL7 oG{2C l!!scNo'1nӿ`(Ffk/V3}]>m{\ 4F`mP{zHWQ'y9jP ?z}Ń:s_Ir7,ac <- w #?z:+.:WA&[Sϓ۵]6_¦{IOϒay_ۍc9-De:,Un<@Vg.tTc!/_'oK{;W=n伶_SSɆ k]w8{rKlmt@-|f籦TG3>_{x'> >h7p#}l 9؎LOUT`]1pfWӒ,˧Ln!gs+&ߕMK"| b1]x3$;#pV4"N-f SilI+EFȄO7z|2x:zUƍzB97o+iՑZ3lZ)9 хw+l8|,I?_r/ӯ?33C¾IsբjSR:%qq5``|I*BS#?iYUӝnz!HIH `ALb4T/XOJ~K*~J`AR`L@"4 m7MwӹgO~zC76c}}>{^{^{? M]jL½:bTS[k`}pnQCAǃJVkT/F Vg! #/ uMyN*fT0xMꮆ| Wo,I^)e<+^'-1 Uģ|A&ry!Egή*(i%R፰|0VOsChokNƏjgygHj"1`v7w8dLs,אַL&m{Z˱x"AȎX7ʄ|2G^\3ii: &<pR% m%:': ³2>L rnDf9F /COG!eySj?b"+nd#p{+N%GY,bTBZ7veuC­i=G3jUdre9^[k'^(( CȻ5Kzl)1adfS[? -̊*)߹1L!cy(a IDAT N;~=['C]7{z>ER{7eI/wpUOWpHg1to\.s6"9k8 mȲ': ֝*]"J]o*pڏCУ:qr9/F;: j2_J;u%3!m`95;,90 : #NOZ[ko;sz}0t3"zCٳ?wmre}f83M(r{ݷV1qߔkAv~:I~t Ļ>_ɹ Ih$x~[N%1w_١7M7=01 F~ela}~y= /!LJl"|ezx7tǨ-f1%!5 ]͝_`՟:Lf:wN@#!8txPFWd6WHgPDHB g,Ms%QDچL\1(/Ry&=#`UyǶ&Mзx, ԣB9 ſ} ?F"ytДF~+@ 8:1$:2}z&*WKnyfx eY:+*Bzeq @͐dC%Q&Ծ#kf*$ڝ@͓}?sߨGÍkE1 Јα0jh\zCE`S8Tm\ur/a =ҡj/' MȯU/Lj9e y!ye5EuU@qW0‹ӈ|ʑF>vgOYp^8h@yeKU@b`HKBȀXDv3<fw񭵫RXd2ErY7iV#9l)"ơA8-OHxH0܀N8T&4V$:% |_I /DzL/gwʠkե"hQ>G>xf"Ǔ]2U$8.ԛC'b_,'\aY" 2E u_Fci(Cّ^mC\!fBA?[<0< .i4Xf.D=x yN%Twf} w K˄meFYE#Od×Ao<*Q~:miށ7J2Iz";5gN7L+͓_E!$4;J nSϊQnࠂg8s?^P4iksCe*=exԫ0_tRcK@8";gT>m`@?h %oB^> 6t5ůs y$̤RFIP9Ա%ӌc*niwqJ; oJ{eoj2ʤ?pQyfye*Z)[/faD =|W\M]KM}s~22j}}!>L"'&Zߧ 4k@[ ǵBq^Vu$,hmlbDZB e8ixo98(5/YIGCmc/7ǝl IYV}:DJl5k@x4 T?$]HWډ9]ů1Vl94xB*PG[8nh\yaɑEșYa2F7;y%|qܾ%&:KĶDK>xC wYNH|50$:ko q\d;iU, " ]ulfJ)&NREGV.L噂z-f GB(( JnxbEcǩ:P'G:qE:5,4wr^`2qVҩ!*N> <Ϭ;h0 i=2 7I{QɶEZ8^'T\<ӴSl'GGc x.`Bi7Fu8[ 4gE2)+8H s D`\,÷z܍!y`J:/Bf$<…'%CyKO2wl~k,5X\gEU.()ǴE|JЄ`w(I zҍ?Ǯ̳J~ql'r>V &̣ nu,U>U~ynL2]KֿcO:Qęm-ޑ@Om"t@u66s^# &L[Y^i+sm/gL++ˈ3ȯ:s@% Arp ǐN)1eܘ7%{՚)}#FBvs"#N.82$8DlOW0KKsr ^]M;CC) mlH N o]ҹuc\ʏ@~zXkXNExHdVF#O!.*9VA *6iKT \]X"L/Un_)kȟ?@IRRn (H{_qԼPYvO 0"*4[|q3F8!p|FG?S Һ6 >mwx슂4f2JLF6ɣr' F&_l%X$xP&5AE^鷽^g=Ar ׺U^DS]'wM Ka>CJ'i)iRG .Х,PD?Ey+(p-~Ar\VglHɆQze&{偫`eDZ::+[vZ61Zhl9x) *?#ec{|*\cx2#ܹ|ΰRioOĀ={9>G٨'LC3x32oOn /=G2RCY@)+a03H%榪8#IH.}jQ$}nYqQP6+op"Wq1_pcl;Ti80n] N mx3&)tC(86GCpAz 9Ήb҈v8Ѹaď/VkG/eBTUAP ڌT6QSb$Sd|QbmNN=CibI<xHSW:\q{@JX+5_ a6y,~;͘D~1S䀢ylԡÞMk11d3d>fyen"Yӹzt6^ QWOXp?V"3<;ȱE ~3'C.42AMiuWێO~>}tCN0K'-ܒ>ݏ8W:#YyWaV|Tr f5:A#5;Ze]LeuSN ;^:(N9PDƲ"r.n e;ك ť7.'RSGeMiPEaId5'Qe|QK+:P?8G!3mXd']Ȅ6/L#s@K#ĥcz>E *)O3/F#ぎ "" l.9eUCYU2:B*8О s`iT_:z&8z5lIEIvD&:XLvkD֊D&i.9V=*nKp+E']EM!4HndX=J^ Rje]xSd:D#rCe%xxD]Y럮iV* ᯓAey%³vjuࡖne+a4xprpU ̧#O1bIB U/L΃w8 G*w`$Ƿ |u/2 C# ]O DErOxt~A+Ut۩T^ }P:i#xPx$sKu(kOUBzc8/y~L#҇}]wp,g%d$RV9Rlj^;b%dܕbSQ># \~[~h'"ʣ}f(!R뫺9Ր;mzD<8w'g~RZp.,ʹ˫;q.el ?bN'YOӷ+3u`jg[Ra,7>>x&l ^xL&^XEt buYkDޕK#<ωԱk"ϼ{wđFXA¾qTڧi菧fũv5Հ+a :87&"_OSR1C"GaviˈG c,i[+QN^eƉfR 8>:3ob$$4[kq<&7pW 9cxuEAś$b~8Ϡ>j*\p&cې>Sm+U_ẏ`8F^i?/6 ^y;rcS2$ۦӬ:'݁ECt6hc`jg6!_AdBxykND~c,lrcpoa+?!ߌʉg zRwQ+\E^C!"43!Ra~<2MF.z[e}'.S9OQra!34b4[\Q7{UgZxY%.eHã8h(yw:K. , p-4{c.G/n~WU6 R$2~s&M,5y1boI)!qC^#nc4d})ʨ% f 582  rՀv2|N2'N2`/!էTV4&jF9RF-XWcXoW4G8)n#ECِY!5i<1Q,A%!W)"htwI7J,O}OEU1}R) =OGX^ԸqJty5QoQ(1x5n:sbz&ҕ+m mkh Uw#-yatjlVIK{&Y A'J\+h@ԥā)DHW%cxː'#lyΊig3cl(^iD!!˻D.Q.܃yo?;K ' ?e6;R^qж,CQGG:9Ȑ祬rm<:h-}K5DtoWƂ #%.g ;W7iyHp$9dsI}NZC o?5l0ohlB8G5QQr,oB\d#^qԉ?תd a[> O:f;ycSl!#iN@`[FqQ= o16G61+˼]`ݓ,M d'kT(E.5. uh_u)u%p>YWPEw2() ӌM#j4ۯq*Nl&fQ}+Pe-whϙp|=1}:Eais#kkWCr*8FG*][į@ɕ֊#?w2 ayۅc>8M ,yk*Ө xM rQȨl_[#?ߌpes.Jm;`UzdU]b|8Ou9JL~s$ddm5vC2;:&۰"5(}"SzMptZwT0up٬kāy3( >?I{]fCz(1=wN@tCdbwaUMQk=wzQL9)}3<}9#;5(W$YHw3B2=HyKaŴ=2y[ 5?NykyO/Jz5(X,0*HX:h緷Y kW# #O~Bi=ebtzm1HYЁvr Zwph$ثH# 0l3%I pPHf/Kk6Umu2LySCuMݭ?L`#~#s[jNpʑ3'2*LLf"F|DQR7?P&]rri{i[W9<#U.OJU7N*H-;饢 OK׈Ҙ m;ȧ(xm$ RPQc15+O*.O~c&F*dZX3iBux(<9W`5T@Rxuu c׭cmH2rA=p$aF w( ٖg*5G! >T8S -AGkV N%d1<()c_ GQ:IroKl\*Ja`qӞ6{<ʡq40|=DkV?V`EYrCbT>wDу- 088]_c(G1=,4]8yCts{ɹSQD?3RAWMb{2Lx~a,. 9Af F U/4 mN'SL lvNzA01;t^^u uglhT2lGt A7ov١M}rא,{w7By\Wu@)X3ԡ1R4+ye8B oI5/Cpq˭751pd_m'2m; 4kuU3|f MQtiʼ0 D?-5@yiA[||MC&aP܀4*IұGuf fa?c<ʅse&@Wh=،"{wc9ަ_:_׀a5: +fON_g0hovv=GfPWfǙf%4pAS 绤#y.):(`uQ 8|[1R,`6^c8_>ȃ(cmy)ee::.,e-}]\U״[@a66lօйĚvx+I/r_iXiqAIC->A0Fr"5HcCo(:jk f# *i5 =|g5EWMJe#+YDIA rC(BoۉN%e:z&YJ }.JMg%>9+ ރ )s)w^+$ 2eJ[8Gx^w3-!IԂ :64&48/4QKUٟ kw_owNx ga}3=F@Ghe+Q+؎F(#zAf(m}}?Ud&qr1#S>IzTr( “\-  s<c%px26;.Υ k4z}\y2Z 03. NܓngQ"=A A; 0\,Sx9kz_GQq-.Ovx_S(\.׾ʯ5ӟ^{^cD#|Qd^Gً2X~ƨ8$<* R1>' JQUVWվJÈb2* &c]*?{2Ap<0TP& {-Ų%M$С6bEýRBoEוxh_܏DQ#:z6֠6`L`u許WTPF l0:J\PFfX8*H[Pkk藵 %O(1L׹`&yo?u/ˀ`+ ~)@~T~쳪\+w"|e++9-DJ[q {m\uQt)3\\][G_9w=,ԅo:TlG}m<~6 '}C`f 9Ns:[Oߵ-tj% MTctD@̈́p>L%=6N CLc]~~m}}P^{p_uBkG|I{ud#5#Ƶ,CO25%CyF֏M_m^rQ٥ G'̡8QLScKFii~.m\J̲_.o@ՠw{A¤^ɖ>*>owAUύ8nbA&hrYFLgncR8RDCttݓ/ێq9xWx3ĉd^}ďp=ͪ:Ƞ@!u&цP:4#;IOɘ\0?8@u/gIBBetDDԦcMƅ,Y >IOK9Ǭ|L0AL' nTR.gl:>bhqydL]9Q5)*oƏq7Jٙ8xymF p((2Z RVDpWuSW&zx&|+( џFq`ā&A«%qy `E1@ `p.Hɓ^&lagq zitʁF h U&u:4(iL_[ Yd];u,ڌxJ8-,0@cZj˕|hyL% Q_ Cc(Q*՞L7-[X1L61ٶb%)oFq!70FY Xq Q =`q+9vӋGB:6?w/m'920&g7-n "\:(>jV&Fy& K 4Zm=쌵yk(節=C@5O^Q=dbJ{]>7/F&iz%@:L//W[ѾjʶO[vjZD? ~?N눁ӟI|nqqU##K9NV+iim0Q^@ܳ#Yú7rJuO#$"Ao.2оOZ N< [( n!pXzh~əs!/5·ШLBcK"^6eh5rmP{"QCM'O }NdbDV;s7xBwʙD,5mi]mZ|ۈ ebOu?oE h9<+sc&O~rr3s[w*x_p+6h{N|LVWfѕlotX %|'iZ/k8Ww3YR_έ+~1`רl5xy"y 9N+8rcNi0tyXC~=:kȘ]q<[/~Pv09h 'Pdxͣs#xs)59sL~zӬ[F 2o "V/h (M>vJlΕ M:} si^*8:SOi{&^@G-l498FX&N p.KuXWr;H]#ȁg>ݶ^m׮Gͪ6VΝo7x7kā8UO& <mxZV%Ϥ 1.TUZ CRAp"xUpZ7Z: ڨ19IU9J 4b^S(ޫk3ARy7145,Xm|LblO Mn0Y{cznmz`^9B49/ (%0=uik( 'AǃK%Sonamm +B]x1%Q0h0thB"cFYQ[5"mw0QuPk?#ܬbʗb&^%-9X#5 =hoz/5\|}Al&Pߩ-qP!Qy_*@FJbtCu0%_<*<EYӸ?iWɊ([\U Jc/bYK9Gy5$'~^VyVq# ,粊Ί)CTꮭE*ƼbEJ 4۝ozX|^cek{%\_G!YPN n 0i=qG9Ƭ2Gq1k<W" Pqa`=q%7sBs9 6_6/1$N}[lP6rVYF4p=b' &a$'v|+\^|ͶڝQG KȔvPw,<{ jЫ ’!{U:c헞~n4ph]R^4_}v Mox[4NT2fw,̪ {xE+R ?TPQGS,=.{X,,Y[7= F{d()Tb>LWYWFAvC <ё7K>e:p@輯5hq&tqCB2(d1dR~FrWyM2#?8xRØyqr´nYp|v a=zBŃ*WNxQhc +Յ=Y ~ ˆƒIg> %"]gǓ>!)Nщ ޜhI<\\Z_ۻ/|yuw^gT IDAT=m8w?{q)`5)zgo[_m+T;sm 8JU`N|ܹ٦ ^ɉkā~8 E j!U>TsgWع#*ZoyVt_E;^R0sҦ6S1AAFYAi=-6]|0(@Rr>p6fax!CCe@ZQT412'}LJ85#qT,AQ>c.Jt/jtb}Hޱ>K\ߡ<[PV~ cñ/ ͇(ibC !$+:X?O^q*䑲!K5Q gXhy`즭tЦ_DzVt<1 ރ|wza3sgg<_2EgFükO3ժbb٬Pl x'=4VOW?eLKw5M"-kxI8Měv8Hpӻ=Ž mVG F,o>J^a2|B2##u1{mk2E+:.C-ұ):=A=1Ǫ}KY9 ,@&e i,#'F74b>`f7hDM\ @'L Lz {[f'yAU^ h^s+ 6g0~shePǠˢ$`C/Nv-#u4X> cSSl'qLYCcv\%5o9 37,OObl u7Ov짜(tts(!e| rvwMqxS/Nq+q4<󷿔_Np0\cPZy {ԏC3ߖ#}oz t'->SE:S?K;=,<c(}8'G5=u>hnU=S{6Lg`:Vdn!ND T^ŹAj-OG_AI69\xcB)aV=tޕv/ =q`ā:|mG2[k@_778|DŽҠ*eYôL>Qioˆ^ b9Er(u bĠet4VmePVwRH 59uZ-*`YM7.aZn;(gƁ8%;0|(g#'7 *,_.>(q95HC3K*/Tx;Ko{,,&$RYo'CyanﴹB~+K ŷ^{Y{=v4uX$:oNrP{ ZŨS|"c錡%xym&:<?g0Putbiު|b}=_1߉l~)"w0d└sk6 ״ퟭc^ ϰH8ϽӮC搝˾-4O>Y{IPhx)= 31-KVeg&xۀ+Wp>/}G &/dB$?$X8 kME#o_($ONXNMw#*I?>R ?*1>{񙇷3g t u#: zނcWۇ,>k3aySY3\k Xhђ<"YxK)!Cuz,k^9q3P1͆# H*TG̃8wq @=g,K^do浬;8؍aoȕ8)`(N0',pōt/Uxp2_N`䷎k8oK׾'ɏ_xl羴9s⯼v˭5ߠN^doatt8ρ>@?l;×xͰ_ooI9Fq-J-SJxs5Yc*$.{R]e0f՟ؙR^翺Ä#HTu,Uz,l$PN(Vh]V|ea@WE*Ax9YUUZ*TF^9J>!>6HsŸ G؏AR^fw#8LWOGF }3v5ʱ[QQxPefAuh`X.Uoi׀b()'U dNC)VElK'[(0}%v"Z7v8 %ܐ<n\aщ)/Lp Fix,lw n^9]I1}%zEH˦(HѿCc%aDZG+PFBb?bOwڄacItiehx%|v-=u+/i 3LinKYƽoDp,Qiu~2m+EkYi+rNOwoG:e-E:&{]峊]&Jd&߇_dɨ`s9>lfQy🷿#~ Vy$'D~?Fm9tm$Woaj'~W70Op z4hp 1N3Cw?g"TeuLΆ^6alPf#N.y}]q6APΔ~F&CGVؕpY9t'6Y5bW=Gy4~t m;¯@.F v̖cYqN±e+#"V'B^G=FG<`2F(wě⨳(L9W*yÀ>t2%T^3i7-ejciLF}Rde_4&e,8Z$&ȱj@$3@ĨZ* Z-̻Y ɬreK}X[? tht'j`@J 6>j-^S2*Ac'r#()X| q#@EfЈ[ի.*Ty]4E4\U)с7jPtr uvQ#.2J{pҝ}C}0)0EY7ÛC3 !mjʣGUlj[KC1' "fA780\:аR.),eqyIma| M/؎nߐOVK]n"3!eU*[9#6V_q~Оoh<K\u4C'o\́D:zcDV./I#>8>j??}Zyq"-2Ǿkٹwzx5N|~]Q҈'_{힋zwr;sх m Ck&AʗBg+=:r<&Aq:g '!+3ay߉?J&^J%cZQPc(>* ªUQRg ԅ=~aj\8ީ;׶xCڠbB#T4ELxoQ^H7Ɇ(ĔMh8ck|ZG#S'[~2˸:5v&26ܒ 9Lyq2,{Wr}5S MO^_GBGpB5(-:|Qӣr#u]%(&YR)N) sgrV҈gJ(F- |1"#jQ ̯ pge# B,]p6uKrFhqcxc3eiֱ N68ZP4K+shpKzP2Nte_GȠ `ʚ+|@_X`RmX7;y]O?/r&\#6d9M$Qgڣ)֩ky@qϱL(m9cnk0yp7} M C$*GFFb\鴑7nජ"$ˈj# ټO>2dߢneаG~ wo+=x> cr! Ѳv}xG,ϳ#pRudL9Ms<_3߀X&o]etPT^D7Wf9m~pL/r)*5Yw˔FAF] eC&x82eԥpS`ŕb) Td(epDѻyxXc;?56cy[|C3L'?x|ƍ7>Y[nm3mlv}#wI 䕌RG<g¹tYqظVزҗ_ЛkКGySq`ā/8PydusʪcVírQ F Jӓʃ J򮬪sf,*>UP[ƲQr $x ]HzcP _fޞ7&2OMŐ;Ba88< cgfv`zX{ m銑qN6F߇.uz`3xh<@"-h[̀ Pfau-(on1xDd5ɪrP ?bڭ޴*Y.AëA8i'ĨjT"[ -&]WΎIR|f S^@îO g /-M XTѵ=XT96ⳫJE\bBĮnd,98vm=:Q ߂jZr4/]4 ÈSؚFHy'Gݶ#"%znkz%?EGWP9p\?q4 B^ qܤ3`i}U1E) ,9y|~;p)Y(yv?]@U8㋰eI.򥃊+V-49mP1Lj _i4>"#22/pX2ᾋ2!:+>0a3&·gy&Pp[OljI\Qܤ6 .y#\@%{9<~d=PEXw\gKsgCۗG8e/(07>OӶow#l;o_`)ℋG]K<žtׅ;vU\ktMU7_~%#}p_B1YX^nxvsV"O {}LN }KR%, =|9OO-g~gڛ/護K.T3>￿vmI/RoKf{{Ϸ D]|5/ WVVk^?@Wt}}_<o=O%>#"bk[=.&kP}߳ħN>B h@m IDATf-(kk{1``gm9uT8vmѰi%dRQd,Pad_cI@ߑe]!tݟX n-GT{G.),̫B 8Set ҽor(Oȑ֑y3`V"i'qg>@ }1p;ԕIh3p w,`ׂ1bѕk="m9)_,g޸:ci1ox'Wu@Cd 5=&6q+74z~y*1~x:XgJC~NR*Rc9{d+ҽa3&dXYulB yWgqLw/OYf*4?ݛ/eXđָJ6Itf_;D`/Џ<ցPf=ʤ['zsGW-s*`uN+Xt)xx-soUYEt@g,-uaBq\ځx./О3=POŎЁ`eKL΋&_lu$H7m9jUE>18IKo" W9r~\WNF<}gL %5Na>'J<Z߸!ގ(a+s=ݱ&|AX>H< ʺ=fTL^-ta 8 Y:2Qs8F=-80>,"k}Y%e'RLd3ǼA\8 6hrf0OH A"ߠͶg~ڀ3 '^ҥگM+{Bo=4~7箴zR?+Vd>>|%&=k{H믯gaH< /냗+_x6 xK8a;v/rǾR**o}[^|o~9Nt^}]D4+WA{yϺw_˾GY48uyCs;R[vאP-2f O< U1AZnG(Ic-Ng?:y5>]ɍ!a[3Q?Rc[IVр\d Q@QrE~qQPebcr+bO[K`kp R}:Ip QUXpr@>prA'ioؼμ?**ܗ._PVO 6DXsv'"C|-"JW"xګr1@uͩTI]Qv {mnh#]B&[p6rNI59{ ?khY@+9?؛X:ҦS%6K<-hz>kÇ^;|9;XM?}}$2{h޳4ڈ+tſ>tgYKp÷Qs)S _BK纒݈ӪU^xayӛTn$=YMOOsM]_7WL{IJYrUW)CXuW mo{['0$,SG'm~MuY/|a9|p{mhjMd>ܻd~ 1QNhwا:W>uRWURYWwt@Z'zG? >R֨>k}TUf}AL Fɥ\'geg@7a(sNHwrYQGN:K0`o]sV)T|3sd 3'6X/ L"H{hP }4H1QiҸp]2b-]zܖH+k|(Ĕ5%BqTb%Šo"mpZdDQ.jһb*Pe82,]'i%H(ӈ٣/' إo/Ō@/(e` Nq'mu׮1Aa$ƥeȧ =U[NӥrF=Ԙ][ :. X2s+Twkg WQ5h =&_iP8y'gSEy={ ߌ4PU$9Tx 鸞6`(soeђʳy za'_Hc L )g sO,HkV0oM}̇Zwٻ70g=41y;ם_;81`UC"n灩(wLTe&rw ?v?y6pJ=_^QPQ'ݧ70\zϬ+ O|iG̍bsOe95,>՝s7 9kI_ەK1|=чi'+mRj;KI@E0ju W Wpd'|xt}M(ׯ//>Gs\9?W:+/~:hP'>{A%Jn\sMyu{]y;w}kY0qlKK_(@׼ٳgiޏ`t.Oy!?#\UWU~w}FyQEnY.M+mWO}*[6vp23=2ٱ^o{j1;(va۔u2|OXV9!SE3Q1[\%Pٽ%8˹NUN-*Y(! |~Uv B Z}e=ߝD\U4 h @ATج׉.L:#[KjkU$BjD0A^eASW%zu dfS*2I>fu&nT, cfgUFLSB̡T[CH(<۱/%anejrNpU tlsV@r"c. |E-'*\ms=[ұ4N?5[WduN+Y7Ub|oZe(4$L_<**$ M+- 'ac| %Ogndhƛ.vxZ* wؐ2иϿJ=W 祕p[qM@ /ү hx=pUTYAi03+gn?"K0 tnM~ncoon+RI]O|x~4c(5|EP**YA1ȑ6-nx #(Ϯa/*?J %kE ɖ=c> 8c-.L7 Q;TTFqqƑ,,RƬI nKaqpz?AEJIo.o}:3|n\*ґo*~e߳sYj;B i%-DKX,Me}_9 W܊1q'z-4~nwcrP5i=}*j}e?0p+*{o̊+r .(oy[__g=+^j \[mU]8g}6ӝqߝ?\__H2V=TNtj@9Qn|+}ǹ˟ɟʯ7 y `Pz\.zm@)rB_y/\tEGV=4HO?H}௓ƚS<.^aך4vVͤ©{x@TxS D.;3AX & aBL7B钝ԮtOUr+T8˃FQ4x RQ`qpE[B qYTMi[¬[jGckOYU[) CO3AR*3[eE*C(rNP$y?Wĩoڴ{2u/)E Q<%Tc$?*dm,TozITl$)hT% u1J¾@)~g}i: _O%&UzAM9\ؖ*!]:n'#xvL¥N>JcQV]=IDg=GjhS<^i`SYn &$<|iTr{l!)A(}ϡ*s$'ckҸb,$qNw QYݠU 3P\—I3X»i֫x } 1J5C{,3r 9,nw#<0ζ{ cȏ>탯 2SV?ZFADjg ־A.MP Isk^I 5Yw= HVk+Ę"ma!׷Y ^9{Cp4(KS~ۙC)ggl-4Oc_9 1I/}<ٚ _6٬[;cuPSo=cFl?F!tx|)5$QE~ 6+IVANF> %&?aϳUMsm;o"5޶SOI֭< }Z5y(MzyMHٿgw9-a}>υߏn=G"YDy|mV']U@rC-&F aA~]U* gSi`hhFTh>. 27+?s+ t2IR%{ʬ+^@(@Rn[V%v,)ֶs6z80F(%Ox2qPwoG~Cٮ,qIsWH լcgR =ZE :Y)[<)jZ' mf GH {fPaByg(Ǩmj;8*Wݯ-/ Bwd\QZ mʀ Jӷ,߸y `ʷ *>K.htj] nm7s O-ܩOEKXLb8 $ɱ~3p4Y%bu U6Q*zv/hzwgb~O{y\{Y3&(CCN4.l@qģGi# *9p7_ic\4NH;)#詼 ~f!k<% ]5lTg=9[^_%{8Ώ{-"aƁ2_JWȟ֎7w@}O:4 lc~󉱰 !~hsW+Vsp(49 d3= T1Yy~#QVw-u#${Y1c(`pX;jr{m\[^zʆeM:iNt:a5~=gw-ab^uܲ,{ {uɺk_L3o=Pp9y`2+Ͽln3=W]}s =/|҆O{A+uXWv_Fu]o}dwg֭y\$믿4/ivoy髢KgyԳ?\_Zi',O U~vܙmwIlֽ܆`GBfcIn+?H}OT=ٻ{,qgTXTVCRgB2Ig$(.Ms{R%Ac>.o\Ԟ򔕜3Uy`|+^!Lnٕ~%CcTciqbZe73B]1+}B?;i2 vhHq 4{i")OGϧ s' Rg1C1hwbKu|\@_V79i{X|$ 4Y Lj4HXOQ}`(={1ln6 / {@W;E &HǜAqj6'z͐4QD,'j 'R.U8fC<^(3I_+ fzf7"or u ƻ~z8繏^hr9z3-S?ƿ1b1-~ 1w&J灝xhM&6]$ykcg n@Ёlʋ" urZ/8qIo+l=Ly.+_ƺ>a=X>5 PDv`NO9wU>Mx$Mj;Y4F߳ge߉WǶJK.$ xuw뀁 ^DpDe.}cx/H{ g?{Ѩ|O8YW_/ǣRQW'dΩ0 ~3b2 !< E Y_*L* Re\x ؗ2Rҧtw(@tڍ{0c a2|G ʼn7|tU%*ֺZ *5 xPF^vXZGSW]MOp^\qV0\(%MsZ4<rUCM+tZ& ;(VֽC wtc#R+6r_*%|I-?Dh#9J򂂖H0|* -4XV7@oi ( 0`bzsACʦ [WqƭYy`)8.'3mrھ-Iw O=ʱ[7A%gʺ=74 ▓?>] #àa 5yq[Foa?rb5yE!ELn߱Uz䢍3؞j8\W-~@ŃE,s}@l@ W;j}mi4N=ƌ3j9x BySmw ORNj;)C %КGfn]r R/=R_w?WJV<)S1EMƀ ^Ss*d{'yXOʿGFG0ugm* ^8Tq@9A Ǜ=VvЈ);^0J a,N0c+m~s״ Ȗ&?awaZ{ctIVc42 ^ j\ck5iPP/wƐcfj SMx<1DH ׋[v2`#5A[c&o%N/a93|by2c:9,O;`~u R_=pN1s"/VU]Mu%=tXKGILF^Kهdl(dt=Uct;sOG+y6ٻ8=\=aI{ 7ֶL ٩z z骴nN< g$wO h<dzW?$ ^|WG?viY7 {-We.nh P/i{q@G:] ]>Q5[W򲗽))xW^O:^´h `T}3{~" U}-CڞONdSB73VI<!cu{g``Nƌ !lk<>U3i]=% pP BAʫ < UUƳ2D]A1%I[%C#,{.T8Y&/ӖnV$2i8guWڥ쩤uO=[ zhY"b1(H5?+}6y䶋+}K4⬢ ;lԆ N>YZc4Ykdr ? <%B#C88'=X *u¶U "D`1Q+BP) w*f]!UU`42mŗJ 3kpVOwm՝eN}V\Il )Win&OHS|@6.Kk@}%GD,|U[ZCkmXÐ_pp:g];!Y[amĕV"QQqR9_y fw(t ,C>H㨈F"h[j'/-,< XQC˜xU 7ֱƭ?qꧏ8"6%&3R.} +]t*|>N*Y:'-b+Gzխed.*7t(04-OL*I#'CJ6^g4hՁ݈2L'O>^ n-XtLRye8Sğn8h_iLuXx |(gAu(\aJWub#385[yq)JSn\E_C;QUuB\ 7u-9I cSo1f aچ2/d\e.΢nAB)sXg~g^y*ҝ3;۾* GIobv:KDa;OFT`K/)뮢3pZzW9̳86n(ϖh(m۶ Jxs=9) ^ESAI0I2ѫlx-*nΙɗL&(#12h<9W:BXǼ"HDw@b 9jfJI\** 7(b4PXe `2}:uyc9 )|ԛˣ,B N5 IQ;. QwsL%=(l G4 H?8eEЫ(bJ/@hN-@*ѸCC$[ʣtd=ESʾ!Hz*_pOÃHppeJA{\F"جXYUߍ2Y7JmJBsy[G+D"{xߺMJ?Ϯ"lWy<¸ syIKW$B+:QLgheۭ}Ҷ5-i>a(G*(漉/|\Y[&ʽZ65 ~u #C#th|$:nI߁^)/缳(aIqEѶr{2)$ vIcrsSC;(z&tӇPkk +(o)P2ȧ`b-Pf ˀ&AdHᢀxS;F;WCX8mIǼKW/qH ϧZ *{)wp漗rVwSnB,< IDAT۶ܷ*gl<\| JV2ƿ jj]SN2p[΃%>̨G(a_ZNXa:x܉;)'zao.3޲evśm>= XZV8Z8[N܁{";,_?Z oop4]w]>-&>~ôek@*J"Jn]ٮ,K*^\)bi=[85 3Ʈ\zf^a)7*FWOpAs UVHzɜYGD($O3H A)?SlT1}]3#YR^vV5.€Y^ĻjaMƏ M X -▱X̽uV'mLZ%눯dm- βNC0@:Y^U@L8ia<9_~WU!DSuBz!{mky5gV!^,|c*o ؃Bڡg?!EEpCY#(* <誚02-OH(YWC2`-vLgmtܛR\6m}e?J8=r{½FگA:h2YNI67+JU0N~{tAfVbVUG%q,Vl@M^ FN>{i4rmǒ>1bu_MLCvY ~ hϦO훤ߴ #qKzQGZ& N+f{ * *"IlZjv bNƃR)(N'64 m ^?f 8G~xβT-^Ow7i0kL]Ƌ>&'>l+[OR޻Y3\V<ɗ.W'&.c웾7`$183$tzdwmbo۫-~,P@ {hT׭[_oHi".nzNɹ ^]=hq0y\)).|/~ B6-{9HA<ߢq'G{zֈ WNU q5Ue͹^~B%0/'6WޕTVlv > < ^0#! +ؕmNE:&l~WL7;WǏ'XWAM%.Dpi*Fީ! mwuA@fp{R4rRD5l!He8Kc\!:$Jg2=(omץF, yztcdq(8Inlڎ 'u"[.x4i)Ph" 8nȕ7Wdxj0EGxE[wd l; #Ⱥ[ϕ( UPuPaø TUXspXF*ptd~!?m(lC-8B/l[3}_Ͼ_J5~誤  >(mGL*hT40|TEE_H#riq: sĵDK!]<<ݪpImk}HYŐ4j7#m/dE ^_d1RY#.^2]+| {+л)(Ez[Ww? x fYuPV[fKt$6t̒VX4A@C7q7FQ־ Nv1:}fim.@qEܮ5TƯb9r=n]O?ܸg"8{*YWr 2dMxFvצ^ecLwП-?m'+O|/jAF> ,5M+z=FZ9:9'9UYt]%| ܂BQa7 'Pm<:OA1Y9ViiĿ\sfW :?^%bmG[bNRN,*/;zC%\Zb<8kChIq۱Oj'tg<n"-4;_ێ]uUMk |-26}dVj@V}4pf ":ϑѮg+0g})1F3PZ' lu 3g,B@/gv$hye@GIv]esSZ8@Df] i_e :{q4oK%tfQ]Ay]ٲ)k_r}'?QxxX't'ar:gAգr׏pZ Rݓ}#vJ(%_\G*j?ųAyN;1㼧 B!nQ(jT-+霣]CAF<5E80~pDA s&02x+鞮"=)(_~{*5qM6b@@"4/@'D; (@BգWyW 2$#aUR-ZFEA<0dI>Hڎv.ihܫ3px:Lr8W(*tKS0h`Ѡ4M C0j PT ֥@B[(I稃8EIK'r<{UU Ӧr,vܛC>E~7WJGuP`[ua_&>q=ュ\ʱ8k*r$! z J HIOPcwN-(@޳F><&F*V@C>A KJz$h@pm"`0 ʠXc5'!Cwcv&.!?mJ#$o=63o"+CmvWfP+di S|o9>+)9 C̶y`Uoa31@{gce=8]S& va\tG 6#*4h#` r]B9M ^i%r6e clCR)v\R&x)OڵezSȌc)\GրsFJ8hirq/3K@UKǹOy[pDYXޝA\z62۷mXUn׽e%+ {pٞX]F;6Sah(8L# ^| mǥ ұ+@8־#n.8_rTnu>f;AXnwUPa<ʵ–6Ruw7XUz0]F:Ь62Q^)ʑxbu|O4`2ʹTʪlKR +n̉LYevBRp+1<+Et] p%߹gd~N={iֆ#J +pt0_;Qbȟg )AГЅcW\\ÌBR r^MjRNPpRyյͥU;SPx|(yu5tQۨB' Q0Q6m? BjjAdSqV4YUSsv0Ui<%|Xy~$B+ҞKZҫF -yY?FiM]uzrP|dz!АZu"mY: -i┫3]]gUȌtUI ^(1*~*ruz>n7MVUUXl i*p^`Za~Y9ux8/ٵη $mbP7#&t%}%J #o,J¯/y[$2kTŖ[42tո4ʊ'<}ugEG4D4*\U!Ы~,N_S?:XG:49?L3I;xt8cKۊ[mJH9>R:vA+n&=Vc wh/ Qҋڧ( p <ʸʈ,,қRYmm Oʺqvcga>ENYy4W]*j^0V]oWs##VR[>sp54iGөIg[1R0V~wṯ/=eغ"w_H"løu{sܻYeS3t7a)?>|Yyݯ-{^X6ll޼97AnZ2)120U2Ts" t犵omkNU(n&&[M(To@. +,+lV`8oW]ͭ; x^g0ٛ.DnGByԭ?,)8[ɳ(Re_!ȟǻngڧ :)eF-;C %L'xY$K]+NMYǸ7[VU4(E\rǶv֓> ?0XQ Pe => }<@-[oTWyl B+"m߭wtkuRC*SAnGKpvž!=ԺGYHw%~EM *$Gz|'x]Ъ䫜XQ#wGOc҉8xlccA p?/R*xo}8QIF٪t9z81 L)oE-`GnG:%!DuE+eɃܛ-ŧfn. jnjUzZF(W!,Vؖ!e: K)ve++t_9!ņʋX=U,f{>;?K,5@B=c'4K~r<vژ.%av7%~˱BJ$Iy'00xژ&HeU7>k߫Tޛzˣ]LݯH3v U<1p>x!Xw<>x#SAen)\ wy{ol\>dqbPw ;)BfvѠFI6lc+a.6`,?mIԒ/vx+s4Z`j X:Dx(1F9Ky|/+iîAY]VgB rKQ'qt1[ )Gy]w~x$e{A`ȄTpv۞|]Fn3ڿlv9f`G|cbaeg7{71`pr;yg9ű|.,kVq&WDOa{KXoZv-z .љ=b槛" o8ie R9(} PU@QPurJAL](qa {&_v='$,[XUs&-}*Ld?ʘA쨃usODWjBGr^’Rx70/- 7]@WM%6G 3]q`DH#]ݡe[S:h!z) };IhQӳRK>£SV[!tMˊ)D5!ҤLKlkPi#DXv6=_c+FF*ԻJꪛ{%j$nNyhIKVNYKÓ!fǶ f)k{oϱ(x+@3`"U)48S7y<[sWzE兮ήf Q6ci3`ON7ԧ/!qJ %*u0_(bnJAl!=ֆo/!pIވaLjvw?W ˯[KPӥo_ x)+3@~hdQRhTS^?Q)'uR>Ql(InAX&ey}V7S=Ğ5Nzt?]~mbt4R@aͫg  < :ILc#Rf^htH-8OR@YuYmBji=O aLqkM!_zR.kޖK>˞ॆ'K,IIM1¸A)nP^*͉}`{W<;⢎+[pFMeUH\Ǿj]NavkdZP ?KOQ8}:y"=%Nk IxMp95mX`(s֪,€.#UGYy*Hy#㼗y}J̭Χ~.8o ˸dzҪmGqр^FY yfe*MC:ɟjQ\DAj3PpK/_qB|/7Shq6ߦk:-L6 h(D|^+J|&@٧&"{#""80d։Do< F_MEVK=;^[{4*Dh\ IDATJ yUNt%*;\7x`ef5N†[<+ `dzl/Pq *{ ZdFf@R }Eθاwh 5fCOX#A;Rs/Dw5b;^]]9.*W0GI|ͥ>w%Y"BC[t!xDcV͑6Z ߒ0”DʈՀ]^U5kP`*ua;pH3x mQX-KAf<_*46, rD 03*6 Q mS -% $Rrղo~Sw~@0BA2JDe#P #Ihjt4m*[ȁdG3lS**~I&^sK=C')4qE{ 7z}xvfwpS ~[||e0}1A—|l#&>˲"}UkYK}=M|DdS>:[SZ奔"tˏ |'}KMҰi#T3nQ)r<y,Cc0+UKYrx0JplƾJ꠳ȑ x,'ĠN1*[1` ^`Bw2~(P;8dZ2{P9T؉DPUEUșT|_z"ϕڙ S P' ގv<y{%&tW L39r*,@EZx™c2Gҹq *ݠ`Q[91p`옆뺺#9Q:!@DS'4=K$`˪qjI]1CYau?̊\I1f<o@)w1H >$I6B[8Yz[HOroS:7Rihtbga;•9WrCy抺AͺG)W*x(]ȉϞ }1Q#p2"4RO  Ɓ͖/sn:GA= R7F!i4ƴVUT\eDw!J>29(+qqN/+{ʛ)]c <0)#{Qp8a9 i ~ .my=h:}Rn ~ r){6IGqԏhT1lGkExe k;(68߾mk2ԑ{y^z7N,派=x01>@*u#=r8 bQ\QU ><;4T & )Lk۠Kzf3Onҋ|ZSʸn .8v<[F7cȮe?J|D3&KT`{Fe8 {zU"$~am[,!><ր!f«w14.ELxR[o,AaZ?K~X ydrT-禛'[Q`!b;75l&iKW[Cn?@xNXa2e3i4 P)Z  jc ״(^cP'8x]h±~QihKD5NC|JhI/X)0V ;֙q&60t@Q30PAc׼76X@40_ǘXs= OR ~q %?,SNeI>뷌2) yRBGg3f%IQ!c{ǩy:gʷͪQrkZj [ ;ey%l#4Wĸ $Gq&s#~B404a*ӽ쟌Bcn##ĨR%PHe-lфyo5Zukwʬ2 ^(=`e|G1X\p~(3 =2Z>" (%+ǂoꯂ`T'kBm]lHB}ݛ &ЗҡȧkDy&PČZR~E֘Px @*pUPπpB#ϫ .^,Y#Ja$O(,hFW^ 3#EcC'GU0*[G8>MT&puZ$m!$?/ײb6Ϊ*5zhHlIjT #`lRid?G}ii] eH"o#*/y>=%k0Jg ء0l -5xVʳ)l/mMN]5n W͓~[+: 񥇉YOYk;>nu/@- pRމE],pjt~'q>q6hih?Ilmf±\qF1%*􋰇c!eG>(Ӣ98`mDw)үEG /q gHiXooi燸G&?*H t( Mk^#ƚ=#&pc,XK0'"ʔ~R(j I7B$|.C&zr"AX#C3"ϸ-8go!cֽ[W ZL@5ܠ;.'ۏTqeg?Nɰԩ/qGo4/_;+99rc噸+xUBXl3nvo~+|-S1OsLe P}FufNcSRpɱkUeCFSUU,tgDrPPTXST 6|&mӻ=WAK:ATW=TW Kuս )b;+s?R{Av#aN, z UB*p*xKn`ZJU1Ce\*S#FO#?T!˲]jytYG?Pɜ% \q)g]=r,ůSJ,8[WmAWȘ䥼j q¼UN+O=zXUdqT:P:TY'eC‹`GrY0^%oPCWRA[bUqܺwe.Vz(s">B6ט`qCCk >eE 'm@9g-QVViOޙ&+ʅ+i w}4?tB18Ҿ1g=i]փ*V>:ȪgV)~Qp/a7"+YqxMcHu90iT@ tΑq@4F@Ixhi1 -B E~X4-~b%tq,顽pD}yS>}o02&.wdy}[(#(inHL;(7 ND^XGWClvn{?O.!yJo{f Ys<,f'liC%ϛ&AhGGf{Iƀ:nkxƵ2H4K1xFZvv+E4UԠxɛCܤ#]ӧ$n4[SnKr,SږzEZ~wUU'v5xa Kc1:Ra}xnd˶OBMx\Ϙ80=;nߡ HcՅ_F :[9Xw/G y;NS1:ɜE0]›Ld2M(0^H/ b}."*LcRER"^$HJf]Eq h;W?,Bظ3wH;{9[0&ee 1r%?2q/>v$oq= F{+ӹj檓,Sx쳐fg^_*|qTy7^6kax,҂ļ%2c ,A $" Sk+7O%tYf\w뮻ʶ[Tnxg?X|s-}S-o-/y??_c,OZVXn.oƅpwӟ(/𩛃%_ރ'GBLᖺ{ޣ܄e#C?D1ڞQ2m`E&^獛0e&LI'2`E] l yQ(OtSm#i?*Wf;4Lͤ%c2)A|Ǚp9W'{ zQV*>XɄ10y܇<^3=̱R +V&X(4㯂2L904Jx[N/Ӷҏ@16: ΏαO}FsP5U"C[WjCmk@ի)wՑ6pq߸To$|xe'mͤF*8A gyłvK`'ѧYVOH*_W|=.ݤju{#)t_%G`N ݬN8کyMJ+iipQjɏXyB \FES:S5:=󺭫tjEJGAH(+<:iGVУ+"ZfSnhT:JRj}ʽ^ }T*b`KO:rϤ5U<\.KPD\)JZKe"<c| Hɵ]@iEM.TlkWs|CvݭEg'M(ku@Дc?u.9/ 晏w9cޛkvw{RI ! kqL``3{`0iw#1efvG102i– @ ZkQ޾yS J8zu_}}sdɓ'3Fx=I'7 N?p$;ڎ0k7^m3^q1S0N\TBn G|.+KIqh*|-B~vF*'UCK[Sžw[ipFYT8ʅ(uySBRaS1$->E ho_RNrpD*̿v}7O~mq2E, 3vt>؆7lk玵Yk{ohH#Z9ZKin༞xS+lXm_Q6rxGQ FQb]_N}lG\VOTx ΋z)GN|BEt n:4|4+BʀbʷZ`BAiD(UhIEIu9ω1LPQ]GZuoUx9\^U0DaX1N3;TgԏDuu(yAPjF@7c#4E 6OF5xP\)8,u~Ճ^ut;s H/{$Bc,ʼn}ut1@r.˜qc8ڼPx5@z3i1FN5h DXFks2m2"-K<'C\dg_cs[f0 -2Cֹ([+b 2$,lGvG0'IY^NZ$WHd XL C'(?0YɦV^/ ֤E9O9!M,A'NI;fwY",uFqC(C!:1;T#@/#E1j9AgPzQg}ħt{eCƾ<ʄox4ϴ)l=4Ue[m7(r#L?@*]b|ɢ#ropVGB~"ӌpR8 )n#/='M:dn=3JZ?stqZg~EwFJLjx7 x9L$ig[ TzD>U€&f2G.-dʟy8gOfvH3a' 3;ߢ.z}#fR1SSݝɊ@QfO ;K30y7O 6P#GZ]2lnͱʨ]Z@#v7 Ϟ^n'm?2:  sK3M>g^cS H`tr9}Xws9`۶BonY62hc^6ZHzڍҞ)! 螽mͩYrA H` z+pޙRI MsSpBEYڭ :$ycHxoU)DCFB(h x\&z%Z$xh(D㼚~B#$񇠄/=nsmfpQVzG@{*0J }z-kg8N0F)Ggġoc{D{ۿБFeoϼY/HZ!=Рg]ğ2GC8OԨ t`C.1c(SSLsnA#Z:;kK( legC _W1H;\,D*V#5:zFO}K/#C[^D'Z3+0>e yD G0jxq,"AolH󁻆y#'672425D 0k Y*kiӡ@V`0 F71 ߙ^M9PCp=̉% o劔:aeW '!NxA~t`c^-7i<ځ?"IL%d3`Pn`*t7CyydgNй&9k_m- w]o)] ,EtTO ^ΤvfkM9fV?N`t8^Y+])< 1< [IO9  xYuS{9I_ .9#Y ^:-G|t\w#; V~", peO)3c|  .f|uȜVMd6C=%lڎ}?=Q<#fxgcN0;KQ%ШAE'W@yf] `EJ&5 'ڵ{129ʀ,}-&$U< Z|HXmMD $:G`y+ =57# x42RVG-\M^?l8Q q0CXI{/ DZ)S!'\%5YLjS3O"JFe"L*$A q\{i \%b=gFњӿ4[ 9S۝ \6-`7=Sem*&Z.rU2v""9${l  ^oh^oi/zы۷ԩSIsmwmz dd `r-ag 4jcersJ[zϻw+NjZ),pou6&^W} lx"~tVe|+t@J.H>Rs|p(G4 9RuɃ9p<8Ns!Y{L]6Crit]fMWO$^nI@8[aJb8[]Xkapiwí.Ot䎰^ , 4\' dykP lZo`x$v 'h/Hk"RZ5*aغSD:F%jyg\kl^*:i,;"|'>y{~O0΀EHzC]VxR/L"<NwiLA"| (#h<yuZ6Q)cݨ8p:1Je{pZ6~l^H>L/_s ,] W`ڡu>mǹŧv~gs 43\o[!CPFseH9jpY90Wp蝇[ԭ) 80sLy) *̈;yɻ8WG{JeCct`lrP]:)'GZ‹#J7iGK8\VlGYԦl20;Z79ǭǗmgW/*QqGb$)YoXBqĠߴqBW>if]{ >'$sA!g$Ikt5FcA|-9^zUء{R{}f?V;Sv h @(~SeR]CBEN[J݈K(  aS^ڧ4  'hm^e%`աǩpKP@ P51}KNX䲹 &tRV\ku3Qo '؅}0(M,BJ"|gITY=3}#K$AN(ǀ'JX^*J8lH>$/o #ĎIf\}`sԌ$2g fgVEOge ǁO !nhOTuS,+< $+$@iwf`U2|C9wa̕"\kc4 06q)5d(IS&z#4&d(2.{ҕ`;}uȧwqp}Ƨ"V7y;-i'W8 a Tlv=eY`|*\qj<=N&޵4wv6).k.CC]=7sαn?i׾zs{>'hdއ2g)8ݕsYf*[.I㟺k̤8Ȕ)I9v$8kLsᄒ(6#V (_q/;ޠpة24āFa['B'Q>tB "~e#1_iebr\/q|[?ўTJ}ȁЉ^#QYK@ ݕv.;9:[,7RK:KiiiP;N)LUF ]/]gq؂)f_SPowGxctku82SR_h!^ugJghѢXVPJ+ppcXjw%dѠOzMѴ|L|ѐЈu! kSx^:l IKI-OX~ o 9p$ 1ySQ- 3іx%;:5g勺jF0V z ԗ^6).XG\rfݾ*^o]?VNEdMyռ4Ƞ)Ζ`N֦̝gpYG)+gSJy?xo7=4(2J=;+˷C?t]_Es7^iH 7zr$eTq李e;?ZC>)3=W;-9F :Rw22x䛑|'̫^EPL5V{b{3K'!qûZ;^dn/q-N[S>hg AՉ90>Ǵmg,(f ( ʺCJ}DyđC8qcl>4l{`7eoXI5mr)W0rQ^i2K~cd%&s=D,a0)Si0́@1w~5-aǞI”RYBSSmf{GXL. ZTJqP;sBq&-҇D˺A@C#kɓlGK.iy͍sRa8~ǠHd: G&GgaˀEW𢼝VD<)afNLbVnFY{Aɨذ )"t@i]Ꚇ N)_]Eҁoqt_*>H[Эh.^FOww4}:XEU\<8zK|5yPOdɨedR QHr\RٽaGk.Ю7-;Gߊ${'j/)| y4:r v;6K\5BG3-&țr9[# ͳ5L -lQ7w 5y|1Fy "Q_,w \s#_ơsu ~$fP񲏄O[pD |vt400Ĝ \cv8X_qMuG1:Wk` .bwQX[ A[\1 A:%_Խ9cQL(SEs:N#*o( )ΝuS:/<})*~K?<ؾʩvʽgZvJJ]8y~\^䍤ȨAdO:-:;WN\A#;Kg{+QtY7c_Vۮhfu}"w 9jCR^*qFEw);E= [DRm `Ycm_D[rdbC,ˊ$~5J_mڹ n!~"-Г)L' ԫ=!$iFǧ +_zc{3Q|2N?*XNmg3 3U! W᫊;?׮+e".rO k,*=ADynw\3:>4]GnJSwPQol9j:qP/ y-11 0u7ŝ  Rϋ _ pi㔁ANc.Ѐ40bV hX[o3YX]\fsJ&ic`GG` r.t< f0 IDAT-N6|1y!;9T#SnCLx:r|_)/"$?vDtGF(Gnw`mXӹq4C/ -^b,Hqf\Voz^G=LS5g"+g.XYh=|tF>6[(>"!vl7xfP v!qm=uY.N FF79y'Ȑ^"W3.`(:)Wq𕺗1=:p:IQnʈH8}+X?־ qh֟uf9OVa  USD"?YxLMhAҗ'_˄nȴY@#PJʾw_޴>!l4y@= Qa}V `~TV.ҹ| G [x] iqInHЂݰTU=֏hO;L(nGi*j{iWF+㑸^b!QA3S@>,ٱ|$>򾳳H%AH*%@\@ "SE (),A8u2B<菶G'IJ%)) I@ڔ-,fPq/A:\K8~Kg:|X'F tU{)o=6ؠ1eLMWC^HPA&Q=@XaJ}6w/q)8/c[I_} φ5".rȔltoAwї:x: e Gw[..$2y>+yD*?ov=3xD `˻O}ǔz(C߾׸tN38f^H:>?@P8QD׹>tAfcg}O$4G7eYDpށCӬvrht8 //x_R>nag9gmˬw&#^M`F79G@Þ8P:N1( nәQwfi6h&a4ihn;Ś2E7:@ʄW 1JZ>H:]= zeɧLVފW@ js\?VycwL۴1F>+NEN&CeO^mkC[ L<,ZdCSgY- 9rOqV  &# ~6GJlbQ_f D~wvi6߆&ii5Mo@m ~UJ]+E>q|xw|vY"#H#Ui1qEa|O Չ%d`JrJב=u8$ܲZQ[ϒLwE=+o{@Cdߵ hﻙpdlԼ̺B<, €1zd1K003o+]ΉDߒpA|J;/&\E~Sl)%JZ"^|̣Avۖ Vf0Uy߰ʌac̜ROX@6+uegoi<~E3B~_Of2OЇBެe؄C;IiJ]R]緛=Z\i}.џg.vd+vOK7s0X?gM&kcN9  =,k‡Eogam(0gb4\c?32N_f/y n| fO-4#*$D:Pʯ=_ bFȏ+"*/n 2X :;ڄYP848tmY5.In穱WƒO{a=#/7nxJ;þfY7@0_6ODPp|G^*amM",G<(w}iS,Bt SOLeNLPZI 4yTx>K*7*;ߩ]t>;ceCF07 ʉ"齄DeCCҁǚ hegbZ\\l}hA6o1{~~OnQ+<.P9pU8PHWϠhlФN30۠f>yu\n#E+tUiW{3sO <06z;u|]WujQdFƿi4:Os$_-$u zn#5pnG\C%;㵉{8o3U^:2$~LɐFoq:v]#`7S(_>/.=y쪩#,ua'IݟUxB&kKУ#kGy;*:*P̈8u"3ՑU1&s[A7l ʼYu:-pqZtq{Dj8(,+} .ѿ]@/vU>˙ W#:%`Gz,{3-QKGo<4.%͔ O?7H)Y^DϽexUS:lvAәn q3d}WnXʝv>S{ˑGu4Gfz>i)j/,UG hqi'O_Y Nws%8Pq^~M?Gŝ){ wgdcSr::H`M'nZzrMx|K˛%[·Oڻv˧>N>َ?>;?#9{6yy7bzQf<cx㍡djMOO;|L:o/7MyDoFKq*4V>~=Gs?9wW]uUG>Op1 : RDWQ\׼{ $A6GU?ZH蕘3pTodFZCo۲Nl#7 h8*2TЯ_7dtS#xWwd\#c ǵQai847@ o-/B"M:(SokpM4 P(0 oH': ۴ӕu_C)Y'`:pUHOÌS8*ZߙF5ѩ[GSy3uѩtn{du?hգ7xP8ҵJtYi"IE,N\I?j!/WL=^V%nqQh\#W ,ϺKxVӽSt)xIW Agc]x şoO 1˗vt֩Z~x $_pvYx_\cዧYKo{7<n:KcYcCI_udE8Zvʷ "s|zj]4g̴n _6Eqq8NN4Q:=(U.%cW  ᙷng=_$3$;oGE6dU`!qDuHdv(ZOn:G}^wZQMjyw AoIt+ægVQt${0 ~ w>hYJx)K:F|T|.}&pxgI"Sf3n䱲TX H2pڜvCZg)6C~稯U[>Մ瘙Dl̸Ph[zF{K{L]D|˚=' * ociM. 6~9F q 殻t¼cn W_"ETǡr-=w &-, L23RpEZ< Ԯh; h,8—o"KG ,\=390r">]S G+]vv܋K4f vo{wN{|O[_; dcF[ȅw;;w~ws=ww~ __lgϞmgΜi7|s;p@ovȑǤ;.u{]k7w۾m`$A*c7B]1b,'9޲̣3A3002"O1w:K/3(6n!G*?gcf:f]d l 6`*!fpC K!3^[uxEhiХ_6+W(N}]z \D[)؆S5B_, #}+{7m kg`tHAYC83_>iuk@{lS) gt8Ί]1F /j_tQ.}:p`-N0M-JJ IҢFaKlM,$QFL4=rMTQJn]m~L]~`ƀ.ҋje흠JS֡SK2KYV­8/oX> tļGdHڮ"i ygwuKwOluK>dT<G||_&b{0[/;z+)+,A\''x0?R{У58.C0E- ~*@b;3;XnY:]sifxߥ`8Huj\@/r͠g. F3Zdt)>|QGjG&9o~WwI3Gm(pyrQeS- 4w=5 lrXyiq؅b:1DN yY;i DM=yk!M g#c3xაHe)L%Xa]4:)8*`f.G|87YPZ_a_+]Z`"|f= Eԁ_hf(>&xd6xi!3?p d ŠIUz[O:6Kj!t1<#%:< .Nt:~x(/"(d^v8Шx'>4oC<6_ ]Q" .BE i׷7}ߛOvy&*Q87̬pҺ@A'~'vN|vW'?~OO?? ɶ]<ݛM wkʯN:߷;.o}mQ?z{^W`'JSB3CPg>^09.KKmcLF;~G~]^җzկn馛2W^ye_rex_zwx671, S?3=n{uٸvU!9GY]MCS+:izJs՛? L i>k@ͭ.CqPN9Wt@li^8;RUq h8ⳅs@v.#e.R5 ~G` wk5StrsN< vݻN}F`'lʱ_DW^yyf|XLoR )c QК=y:ˆƟfB:8 +8]]Y}v["XӾ,"җ 08Էc:Vf7+z04+B݊ML|`^E^!3E'Qt.2SjS{gT il:X nީ۟w͂x,CWg^Nqu^hV!{60ҵeQ{ -_>0;b^`T2^;j HjrZ^;2Mf>W94hLtU# R{e0A1u _ANf|KYlL$iek' :SG2#`K (hɑs9Ql&t~NVŋgƁURo5לG5 Yd۽"%rRd*ץɔX#-&ϠAO;<))c? b3AC;93<[w7S?ʡߥ$/BIom}aJ' kmx,m?‘@>qܱ"R0H>Yb)5luxS1Hr{ /;=1\p_W%B’5Az L ;f ܓg& $(}΍cNk@ cm*zOXzd6"iB/%rq@PsOo[9iz(uF}eΆH6>hPygiHeyG}WGɋ[sL.]ވ#ؿ>CcHELA>˼7WH߀L /L곟]RȥqSosP.1oP?;XGuсq0a\>}^?s?}|G:7pc 'ڷ|˷dv}B??쏹r8ૡoohO}SKַjn0[[3c+_vwg 3>nfG;vh 7dֆ[^%`ӗiyQD@&:IOr,:ue.yw>W lU:&Bnͺ~Uxz 6#KWJeQ~-:ǑשK;  Z.eh3Cٱ5u&HdhbԩWty:#̔EltT"5]AN p4Тv:'Lt2}Jx1u F'ydѦ|ƟS[eQ0?v#,SotR3l"W0UsC &aހG?. ̴^~[Nf@G[4: /oWx<76Lq2Lg Ia|8:$3S;3G!<;j]'<(πk4@+:Mxķ'AJ6JBRrSqVa[Gic}a {L-/xnL&^ףpEoD:F [?uR_oNITʄ52XU1bR (=G҄Gڕ[+q{9/$qZHxCq0a|=$GZ3vF}#;p l=gKHiM5 q5Pot}e(y/GV~@| Xy#(AY|n[l$"T$E8aڷmɧ=aSSpJ lϞ`DM(PW~Oc5V8wd]Ӓ" Ϭ8i &2Pd[ԍ 4_^FXu]=K TAB*L'ۺp? K`Ȭ0r(b~;ݥn(OIgq`zG{(7xVǚ:`Yv)M;:6_4H r/Gوs+&ukr*iA(|h@؀<2`JqLݞlW(Mo b4'=_ sEOu2N}:"qJP3՜ۮ+ݤ]ˏ A)tпm N=s>s/ &" v &ֆTeSg2'݄P' ΪYd9sV!&kx9ý;dtc9Pi>F +p}Nbe'`r*] P9z\FgMa*EkQU>pV=O<bzuA~tx OEJaQmY+ JZUW#pw tUKcu<*q##XP +3":đz屸p%PVI>'z#Rҡتh>IZd i_sU/rcF=)7.t})54:/|a8 jg!xk^F9K`aAϨeaony{2-Ƽ:GC'IO- VoD'ѡSGk0!5t3brZ|6{2rf t~{R g 08*xtQga~SU7_*tmJo $6r:ǡofe=;L.Lj6էU?/:G0@xD'ڥWy𙀾4D_]C2F;ү}L /2G+B1O?󌶻1eY.rX@Fp/n\^/NsWx\?֟|l[񇷾w7sm2aQ"z 3#1rU8fj:8y{gr t}L8F뙮E^ȓu0$ O&mPhD6>Ŧg]"CZ%_(0]b]]]ѱP.y(C;0J8lJ;F9Ufw1l8^䵨bO.3g:V-/7DEOX?P ޫeLUa ӝ\H&elfFLAN{=ٷ5A_SXx|ά*Gy)ehPµlnz2_5g?OP/^^(^StN&RbIrtcv`d qB8ԑUs- i dQ z+68NR{c-d2jɐF\Vf_2whl+sqC%3hW0d@}m:DU? gpP? :ҟYET__7ƌS"'ICsmrW'4X[?;!rM Bh ` o/>Sqo92 d2>#e0R;tTy|7~cAl;ȃ (Bd<eY > rZ5*SgT*arwLEyA0L)Sj.pI_ ?~Dgit`Ͽ oy'O&#v_G/tϴ7]joy[J:?<%?o}Wi07tΣyx4QB`ٹ,==8]CcKCw5DԙcaF8htcޠ1WHk6!SmQ;Nʓ 4vgpֈ7xCt(b8[$FFSUpgaH ѿza +N0k? '8WauװGmdqZKot2emяXHWǘ&RI0uHu4hiAh=od6@α_cXr cl↍z_ftYRGɓ2D" 1=*e`;s v9l  )9I·ic3z4jC:.8Jy&b383 "tjeG>.2%8<3\+p65urLChzoj[+z4AQ,_0vywva"tb <[:q#!.昺!3:a<RdAGYɑUFura>p4] }ڑXo, 0R0L<6zU^xl8/88ޞqhcrr;AzܳR2*bwp4e: )rxn7a4 3*"Ga?C:B+:1 ࣛfF#ԑKg3 >eƃ0bFZ3uJe% Ȯ' 6qO^ :>oPX^(@ oV풙.|n܈}G,OLG=Q"(r)_}FWi[f "ϙP:qχAdkY|گޖ9j2g)~roFZ+WO@_Vp z‼'[l2JeCdORd&7| #x,L4/ČةvCi_f.:@^X^l0njpcNL2_`"nU.9$w tj}vmN_یf4>ֶR*eڰKYCyevߧ6eGBT)gt !t~:uWR>*'fiaArLW'G c%2ڽSF`jz۰WQIΞ <0HIkpGTZ-0M$i` |Z; Q7 E G?s]_O==gg? n>WKcd̞J?T;z(rsioo7xJӟt8tP>pv}5W_fk%L5GO]CMs=n'G3jSO/5ʷ8x?KDyR' 4fTN"Uת2dpӶM櫙{obHDQi'HwЗ.hXqWRq{p67F\[*g`ɖO(7eMq 1΁U9e”'}Ct_ {c3ڠ~"3f;(yC=mLg:dK>U>'Gt8w;|Cʄf.&ϴ4$y%xv'FLo-8љΆELIxZv|6Ґ-$•<ԡUaQ+4r/{7(*ȑ(P7M"<ʕB{`oG/߹ssmn~>s=ᇎj##'Ndù]sm{ug<& ]N9_gmQϿ\#?;; ]Ldmy]/w^קי~^w^OV﫥'?c?~~+3 ??f8colOPp&E4GOO(mrK{;}ڋ_(}ZtPG'W踌1k׮vlq98,7ZCkD5]!E:FRW'ܨ4 m >T.aΡ@٥:e|gߠPu}6ɅopBvSiHeM<|ϟ|6x3ow*Q. `րey3ߎ8O\Ul`"XVm ~<׹Am IDAT|-KpDAԙ}=<,|q۾SlGm'I+NpI׼ k :x_fl`Umfә)~ĵ993ƈx_ɛS~['eSy2E1~8r%3 7}v6k`,QqSL ɅG)?ַ9A&`:)7m_^x|#r-Kv·mDh16Xs Equ+Ȫr M]lva{%, Eg4ZlO8'[wh\L3_ϱuk)4 -ld^dx. lGgNaЭLLG >Hk X'KXʽy!4ԧ_~kgێ,i0{e#=mE8@ ~;uBdgʊS f9@&J̙3q}fyB!B#*O('4(] }\sNu:cۍ W[8[pF=MuGJOS):z;mL[v {w^Oժs:ɇI|XŠР% ) ?Z "EFBMiNܶx{Zkժ=kێ$WO=s1s1<}tk.N^s+[OJH;=di2WO\{. ^_@}ۥ^H~2֋x* y1'}cz#I7)G$W{<;Pj,]5-$Fw@X}(6.T[;"Ng53ӎ3yqlC骫,HQWi7胎keN{ \C6`w Eg{to@ļ ]ӥ;,J7}?Ip-Z}W[I <(3=QZz;mbg'8Gޘrl"HJX_NB+O§!qp!Pv'm>06Z=xhEa4sp/7`81a<:O<%86;pč\6?vW?gǨ)0xsIPgx{)f ZD߳wvd|6e" rL)}Ž(CHDg㏺ "kߋw t`-utؙO>ɩtӷ?:}wO?~/__?[/鵢gp*g'~'N??~o[Wvdm> !_qߖǏw~gb3կ8˿uf!7; /忼 '<fh.P`逴/g|w9p.~lfdWMo4jS{:׌/Nϭq<,c<ŗJ1"ϟB5jnՂ<,b(Ng(ESݏeoa7eûX͈нPn=aX܆@8SHZ9S Tx\Y0# ]8:߬mv<9ךF wi`F;8[K,.g.^q,=$_-^|1i>È^!'1gC hY{PfCC}{8dc9zlj~4hZ@&,̾QtC#>,!R:8.W/LaeKZ|q)sHo'? !8/s߬ F=s}~Jy3}sޫc44P$}mT떠OGCHo R_ko$θW?=LgA3o?3{L+ߴlFsL "k~оm6@'Zp"7c- UAGIvpD|z5Eau_|)ٮ7>|4v&GgUWno/νgp8ͅ3GɝOv4&mpG%'5SNtލlgf s# x;8;\{xqv1= /dm_:|̲Fʩl^[̐P9QǧzəO?.տ'xc@3Vk  cI#UdesiZYIv)}jîmB[uxL [U2l|z֥nѦW+@er瘻GSߕzT#tNw+ײhn[UG=$| {>_vQ#:.!~ˋ7xL{_`RzS=o_0>xu*XB#gę;{OHŅD\3=j Eٽ(^<{p'٪>WܽF7z ZLyܦ<#ɋC;ߙ~~۾̏/_~+ߏF{r~n~+7u<[w ?ﺜw+.K'ђ3:4ux}:ޯѻsBYfFL~ QX4soq,U  A,D{e$\s*{F b8}ʻ:7ZPE2) /LK3(W:#FE z5Z6Ad}S52qqm cemڲz,lrhWY_m}*L-sHώF ~^@̪Ƀ֣?Έ ~ k|Å ͙'y;'q̽mhSJϫ> ( E>hs[_M^%[ɩ[7!NOϿFn_~?O[ ^|"G 0~ޙ5H\Yk=Q&?Oj1C䯵]};2}1\o9مbqD*fjXk<#l9X^lAxpjap҈_:h. BpD!BMȡm3Hvmʏ-w?}~zNB _uGRg)9Kv>+Q'hylzDoOfPP{_2gn3赀؃|ᗆxbLpu̦x2iؔn:0@?b+.[%8Ν)ûo>-i ~3|o}}A)rF{:/9uio/ A>Xh7,ܰ K/\ tx[SLE8ua>dşto8hLK>,2-3aze5GOעU*,ծ_>}DAw< U_T6^6oß~=$O_l3~3wʢS8,1* wN=Iέ- ӷlwuOz`bY!rFfb4B6sPLhO^g!29*\.M;YrN_jr(ֲ'>p$Tsa@{&imζCr܌1X#E~9/:Tqǻ#߰ "ΠKMc~mwAa:-FxFP 9|EgCW^i>F {3vF<[q1Lj_gJ5tNpg篚CÁcv]L|0KppAhw96 rf2F!j̗Bntƣ)=.ۿL2K6/LPJs(ѭ|37SWrӿ{T/1l3𣹛^̹+:^s  8k3zk>`mV8S4p^6H_h{`SKKaПF_e3wIz9 $q_{Hׂd 7O>*iz<xiem }3v|N?ۧ_GExV34_?n_kLxvpMߔK6o0_wYuL~Y36YnZ?f+aiϛ_O<F@шq"9sV7M_]YnKd1  6aC9`LGcBO\mĚ^}ҳKHܬ%KP-0"&srRfik.ex @Ӗ>e=5 w# ?< 辒wrtzl]ka'HҦօ1ͦoӖRxW;`[ְSHG>ߖy[mH\, Hً­~uvm>3qC#tgʣLו. "kWlhųF6_k6J0tqwN>͇ʔȅgD=k$x`,mZxwO0h]1F#۴q(cij̣ldh h> (T!6՟`ѬbLLt&o{#r/ ru*pηbmρx~$w{(CWX^ V}60>zx[aa9ܷkM:0*{u)|'TXG_s[})hWx_sy&h<2Df92Lqڼ$Hwhʰ)Pi'~v~f Yk8 8}N϶_Dz!UH3v+t֛רNW9t`H[cMͤdxa:zRkڊ%=muiLq_C&gnKU^k{b +Hr2&S3:8ЁIo\g.-iEKy_^ M/‹לxHwQ,k='ԥa닏~Fw1ZtqpIwu)02?`F?v\V F["l C<TroB.a7 8l G!2o1m<<'0Nn(aV&Tvx>V7\|](#sxXnt>F V|g{7t13;1)k*&g *Eu]ks9(5d mԟq_#Ј.*m?(_ m(2j4=6țh2Ny >:Uf/(C >>FFp*^\8lvxZ`8Q`ޚf) iW{cS?nʻ. 7(+2v:xԏK7EJVYᐑi JM,&2Sk{3ᛦ=5lY]d۵`Lejοv!TNtтZ -Y32~7O_.wjH6h_/\ȱrWm*Cz)m&ys#cq vCv&Xvi8rfF-d}D>~LlG٠ pVi|_e_U=E9RL2D LĐ9{@i v/ƫELvf]-6TzdG,yHWf7zOV9s*y d_W=7-YLq_;/TtOƐ6 hE?bRK:Hy!_ČG|;ޕW_ȷ`CfN fz@OtЂ+]fM£x-jݤGS:]>eξHn-8z~pO{N6?_njzsN= Q8#ctYK(2i8c ی<տ4u"c51a9m*! g8cL`~2c >|Td^۬=Z_ pt .)+]<"y._ku$Dh %?]9SЎ׫0{6^"eF4i\}REg^?ýzڥ+UޙnֵOLwJCyN;2zw]t I`IYV}//TtkH3 l֪Fu}GpTG3ި$l3><=H ޼usFfD^5BwNww/&CM7 w;,Բ^9 9G?~+Nj9(]g$3 ?9dD.3Azx}GKm5;ÜᱮKSY֤uOG7".ʺt~тFfc>}U[=h3Bd }c֮?W@ IDAT-M m~33>yH-ܴZ]*>֍ӧO_3IM-reFa?ǻGpYϫ+sܑƃ9ѳFǁCd 6md$TUl ba s.DwoIp. zhFmq,17ؽseFy\ry%P<ՃϖWTc\`CFOWy#Ь֪Jc0{!e!2+584h9 QsNvj_ڵ_ɼ|F"y4㬣;ɍvs-"8[?kU_xr-RZġ&c6e/2$:>usx]7Ϗ6Rw|))p76-{e#CŀgAegs/nb5V*a&;1h/lycf%f4Q"&NCߎ$tGk]o֋.[;?['`7Cྣ87~^m郃&rqu[P6{X*ʉj^_a䑴*;wHK<UTdU }7v''_]pЦF{L5zZu)TSU  `vi \g*_ p42oӓOWebK\A,Q-Y9miTp!pߚ7?zr{]!^݈'99T!ljdnD\ BGr {FP٤qE`9Wo[ GBVMՃ^xF¢xnFxC5$~M+P3f/5sVw+ܘ:эˎλzGrSo\]: ă^8.Kn̒ _~O[S?wUЎkad["ڳ`ik\s/7筷ܴO?|gRKǦ%}<3N0$;:zdȌ ?S'X՗Lo<@1Yy`)Cl4맏v"[~{S+ӟYb>e,6M;aبF%mb3ԳG? "kZAz5mwCv`AA0Wq-.)̦0KϽuCF!8p8\"I\)͍x_ 2^7]~uta'38 !:cB__F8wiBm=+C g2q<kӇc෫nUV'0Qpf 2ߟf/Rwo4$S9;ϼ{fhǻo^mvphY};p䰕5e<ѨN ;@??Sl5ڊ5#wf}k :5SG mg69V˵VEQZ.:l2)T_5sDN' ޽tFe|0:8Fq;mŌߌ'猐бcZ2\q^9'Lj~s%8r:Zѷ8 .lY]|s#ϛ>y=R*$ {Z7:] ߽KǨKy\s=h+%9~oNkCO1a3^^ JLQscz{-(WNypTt97 z|×}T\,*qx٫,XpOЫ?r@=Wl{t53e/*:^I^t)}R'8FWK|JǒuniJr<H32O_6LsYΥ͞vYzCג-3٩ z\.9է(C0b2o5O;~Y$pwz_*=H7? ':Uzr7_LnOww@p 쐣xK &w㕷uF~=ikWmTo^s_D-tOQڲRYXzzr< `2s>G]e4{c5RCK1d[ST,#ʼn: /Ft%gL/f|lj;RƧC7 tԞdoV@36KùOB923Ax`ĎCњK=p- #ec6wk@};/уq5B߻QNērm1 ?N|F~4X?jsz  ,?+9dsvkV]ZUC)V=i}*ώs*BT(V'7\>ص@Fi-={]&#y,W>3Osuq|gMCO O=\p/qG}\Smy9 F837Z0gw#_]c!a '*Sٱb40y&/؋0ЕT(Y9k+Ri,{p?=$ڮT_U.>jz彻6Cs (>#Ĝ bX N)FG#fu_w6G:[C ]g'=@68sՂJxv֫ \QN|W Eq Le/ʭrMyf?n%{aމ6{xu w@W.:/CZ\lT]'NuiuH90/B#GktF_oI{%lľwsve"z4YQ7wY!Y"iyK[]цFK/ptOݺ}tFzMCaԑSCk kFW0 #m:iBn2#spՙļG>K UB@tNMmZ^:>/j8)^ ُ۴fxjT_+l >r5^}t:ϰOO?[Z۾U2Y#Lnv`4 t[ 0Y@@`#TUov`ut/KS4:¢ џ˖ϻ[|zĿv1Z8pzY:5$FBQsBq5U6x_#3HYUr ?ڏ)UGgN|<mƀ +3CS#{ _ROÂ3uS$#_ub %I2I od4αwJ[++Ü%@NE;yuF`l Dĺ󜱕Sc4&j9g0/#k6]$:nAvZsl1J'ityajiti d03zw3/Ӛ=_)W/[6|t;|%%aݎuX<@tENX` ^1F<4eۅglkuvWO&d!c0Kw+AIh?'u+5|I!gkC;c׌ݽ7qmCF~W~&v hWϻ0lVTo^|*(oSN57I4zх=e39FnDDQ"x<C1,zfh/z\_bB8Sg/>apm֝S[.9nr/h 63_ρD@&t/iZ0.,ўdoO)]_ /(+ 3G# 8l [S;i23 ]qMGn[쵲8W[9<68O سkxF ?*qVyT3pkt{NwM ;+”M|Af;?oƷf2Qpw>ڌԚ}w3u28~aSuiY ?d,t,"_oƚ` |gkkB(FqL&{Ѣ^\21KWctl;ahuó}H1pxF 9ߡ܋Oh5T739f/+[e2("כN3Q$+x>]&[2Q} S|+_y1nur _^ 0{}+clHi&y9 'Y7np)E/|z =Ky)W$Lo}A!J>3;d{>7Wrٗ&TM rq+y?6KHly 0d5h>W^fbfG ƥw|O>X++LTRɠOwy8Zއ0\$IsʫW.3~ﳗW9NB>{Oïo]{3~L?xh5 D>V^s5@gQqtS1?D @N'Hc)GSBaẻs贀`x-(}9o[N`|3S 6*-o27 r8K >瑭K~ǩAQJ[LbՎSFKsWߕhȎw1E-/}\fm? Cs+g)!Km5&}'Np2pDK~" ́'stѡ7S@L<-vvdC Se㽶MբQJQ3As|l:v-tz߃y~$2xCo_oADe2PwzF)+6RHXP ejozhEK_*D-ЁU;1ZK8 HO^| J.?];*n{ͳV IDATGea``|ӝ[hvӯ~hzWX+Z#{W4 voU- k&P'l7=ve2 XԷsǤtZ39!㴾pVI**/ d#ࡧOo":ztczw9~ u+ e Ⱥʸr#,o{#5oF7bԦuLD|w0Tp|BF .`ȑ|[Oj&6;^'a: l{'$|"S )Ѩ!nUFo_Ƚ2KgT)/< ]ڡdunT΂9<~ /+m 1Qy\ƏwGY~W8G/wzv4ȃ,gW'n;6 8GEb(Zq^͢`qg47"|c3E9:$WWnN9;7^_AЉWp =ګ:}F`a^0^z NuGn )]NTY}F9^Vwo7u=ciɗN@yZ10e2Śݦ\rjS3w\`8n ׍x3._ iwb'H\;~x0ҒuKЄ1>{HoN^2-G{8+3a8gos:1Jn?UMͺg3 `e'?4uvT&WXurN.}(G_i8祚=V#YsfDVoJ9/ NݘaV X٪ulx--WLd$yv Avry2!/Wgc+i3*_pCV^imD9 vz9{V7:p#p,9 fa)xڋ xEz^8xga ^wh?Y'sR0f[(sAic9EOǙIR"i0%[ؚ|`";;N?ۑsw?9l}n`tu8^ 4^2 }dK(߅wn,pkK`]D U3 $oFAHr$K\`16[d%/POb)vQ`(lF}䄂hԺ[qPh[?3>IvCoVyx. @A`C8T8-Cg4Ÿ>D֭]e\㋟uL.|3npK7 0FKCǕ97k`+/;:8; yWu"k@>9@rND|@6cωNl\X$]8~ Ep\꣏?8}釿r3Ɵ j Msh%_?yE#Qs܌9;+/\͈CNY*(n@08 OlGTD}tǨt7z_QXnhuT 8KsuP~!LyGKf PݪP#`oP.ۂTdVT?-C郏b݅1=/|fbL,;H TgV!dpyWnkRxXK2bR%wLq8].bi HlLJYՁ^95rQx=Cg3a%۴.p9?6&3@JSpANj?8Lsf{jF&8\V#`7^i&c' 0j1U:zSVd8>a>K>d0rłF %` o6ɐG[q$;glF cD0p]FG'9.4 6 e3PC-Haz0'}Ʋ Teo ozodlñ+r碻]+O RP ?) R K;z7FQay1t]Lk>J :2pJ|f/M2جe> & ߃<^v :_)gK T\V_:ޔ^K1ۑls˯}L>_Z=ygy/\?F =[92ƣʇ[xQFe?7#c n5S-`sJW^+vUggyKB⋝߿W?cmo:fmv҂$OV>wGmCrm_ѠH܏З}]ݮӬ/zs>n(yEb /4!,HXE<. !oqQ<ĝ!#o| $7O =8h7p~Fl>upz*f?ZP2./Fʩ-$f%ӭ`x&|OsǍS 1^rEfū@VKȃ0+iBle ^}Uz, &m>B*piӶwd.Ϋ|}*XMwusl)#7"SO|sz_%3xb5\84pBw8^۬`:ܶSrώi587Zm~`ʸğMIf4VQ+ni:j< -n=8r9={eυ>({45<*M|לpѦp_&3|\a >꣪w~ӟs4rrS9sMV륭x Ȋ}V:F^[lׇVOrֺ螜M:9kt],ϱ;V䀝QEpܦƧګ7?okC>Z.ʏΛ7N~q.ʘC<~/{s>5G>i!#Εw|)x>r TripeݻðKxۼPeq\7n5sAK$5D_#Eh샐DW(`_p/dwja9g]C BQ(p,:`|[<3zh䟗vs̄(`[S߳8xuMr5yX-^Y^3*Yc2ǯTnot[L' _#.~~g~f_9+r7.iFu3E?:>5J}tsέoEI}#Ǚltny8lI'DY.ƝeOfNE߃OvofApT9;po%8sl*#:їxsZJ=>GkS3-\ۭ}@v]5&pY[fΓݰ iиtǨf`2tO$_ՋM\ʾpM6@yxrGt֊~pɋY CV&w0]X: Zl.9`N8"p9}.^>G˕Ψ?ʈwɯM7F=Bk]G܃ZH-@wژ NQ_}Gݔ7si+ x2Dtwif8mB7㨯M V7E~|>xѣɏoP'#t9͖lm*? I6Q (3OnMV=D}Xy?VkÜ]q1aa!HMn=Gqv4r9-X}ƦF̯$oG9wgfpQ皃uI.րF#pOW. U.2☲VgG}WJodwޭ#6-xoƢ\z.ݕ6UElӹ`OՆZx}h?I ZOQzEntEFιzHFF)MZ@M#t!̌͘ɭ9.XHM#>\M~ANG8ZXFŌ^?xXylu@4cSÏ65^_40GB 43Bb1R|V'+=m}Vmbwxgݖ!‹?׿p΄.xߒ&ǮQo3Lm]``50rCϏ*'||W~I! ]x*x:c#OnC21,5nrCِ5~c)<9ogp;ם#o1gqne? @`/o@vd3R/UݑH<hTQ9 K|8:YM=F,yeoLV̂ˇ|tzѵG4E=Ż8]hPƒjG0 +Cx5rϙ6sHu\:6c({:hf:z CEWur{QP^c_Y<}= ckzמy6.~_~upiƈ_xpɌLB{U鋀#A&p9!{U'!H. i64*P1r]&ٚ'@ri;!\wbUr,aAP~Ǽѯsz!x~ nx mua(ԛd}@}M_㵵,p ^iTCL `@§=c?(8%hӰ(p^F,UrX)00|UǛX\Hď<{<X׳cFBC׌0(x=z1+ 9pPN1;嶙 Ǐ'זZi~BxrpYc[  &SQ0!Y N*>BԒxD?/Kj XfElZ+?`2Y'IMBqX; &?Yl3g!sv?䨌+ߵ2:`0ns W~~lVkCUù?;f8cQPk[Ihqd^_QI*8 o|]~˾WoP1< 筓W~o*6DNus;[,!xQ{pAmz#%N^][9-m%FISSܣ?4EN5F Fu ,k.dgo`=pgO4ܯSkm_KEO?}s AO'X$^>aݽ_oY=}I/J)Я觷HTӭk+ǔihչ_Z1``0zᲵYnjf <ߢ7B΀LpΌ{Y~W-7I)#C>a(L}|87~F&FJN\6Uey$_{$XteD3=ӷse;΀4g,6U%x8+ dđ ' -#|7Lֺ8y FZe}&AlҖ`|B~tz e>),m4Sj^u%f_p IDATeYO}1u2eW%sJb9 N4)tmZx F۠fm?iá-@Gʩ$ڔE:sYOxz ufJjzJ<~χ\yVt]uj^n~$fVC7N7+9}1([I."Jb ᥼NDezU%+`vRTg=^9. ۏt`qL_<6 u# }fOG]ϡ(Bfأ㏏L\ɍd*~ %ҭy~ՓeN|4?w:6=WxO@'h1]rsFoT / j]pv{IȔ6}d+<2Kv~Ȩz{Z_mF|X`:Ǘ?Qޣ;nܢCQwEU+BQ/-]k :^qȟp)Sy;&b/ *7FLcUWҴۍ쏆)1yx^>5J]x'3,h#h1z7=Wv/U-;Z#ϩwEW&W|d/$I*4RoI2otkM8>:|^XNt?ʴOd#z+#4GMBpLʣh 25=Ahߗm唉OY7T}Q?闿>:=G7O۟Q)4ݴ_G8ѯ3\^9/[>;`zjDu;=}bv.gMzf!c|ϑ\p~}O`׿̰h$g0 gT8@aB`a{ wiC>M2ioy+t} oz3ͲPc]`eGҸłsV0υ+v(DF>QUȉ.ͰL怏[Ϗ[07Zpe r+/rMQexػc7뻉T}uFԩGQ|| Ɵ9" $b[[?[}m91oWL S&8~AcL!9L97ڐ̜/*!=:OGen=xiC1ZoxB!I\2a*gNi&K䓂/sت d\7 F6*qA?Yay8ఱ#铳rlQ̻fvӽ=Ǣp*|JFSYʴl|N"v6=ԞfI!` _~So_=_>9"1XpdI9_NOeq9= 9"LKW7=p] dƾs;wj7d/79 Ndi+}ܼ3ֹf+88=F-P_ ,`I%߾#c:#vr60?ٖh;;|OvJw )|m}ȃýF%-P?spe h).ֻx pV~zJGYVCM_ Uז/^ &·o{\JLcvy,K,HkCա%7翀LA3(-+WFm.0~{;zyz~fXes9\?kH-0tɃLw]Ij;6?6, I/˴|s*f`v4",2P!=BBatqDufEk݄v Ι3FLBzN._}gM(3|FZcn#1:./{&P,W/sI(t`7ҺCGq8yg HI{&e?kmwz9>pѺTs=~TUgx s6d k ,~cN0xϴAMEhkY<䨼GOoH~_ h?q9A?_~_o_?/Ax5^shtd~үӕ]dze_Mt:Hhmzbw?e\_]zepu 9+935NTwG9kpxNL?0e$C5ġ6r]k:']ڌ'ӔhةyZa|Dל<~A{gdCmpd(n>Gizg/9"ÿ%\=?Gll'fLU1u֗Pd7M/ӂ'=bp;=vG? QYFUÂ)ڜ?EPi2'h/O9R~)H iptߜf7!ir/&(urD/_4 XNUi#Qzx(ṅ&zG9dZF8iPH1jTFfl߸e:nxD /^Wڍhoѭ>n%{]|{Y:OC`U[FD]ps#ϴ@X\:ўF#>ڃz!f1ثiBS>ir!nj\. 2V̉#s' ʏ~w٠k.uęl=Ҕ7|R3iA}I@DdtpU;N=r˿Uer>9~_<̙Mj}rTF~)C.z?x0,L[5^Wf_H=On揲$Jݲ-%Zg!C|.ƺՓo瞝>Tt[=K7<T Is!S8c$rw3pmN#-u~6(i sɸYӸ$~l=GfcD8!a&^ګg)* C~盥iszO\1]g.*ex6 `CMη~R#s*hEc};_ʀnf_Aפ3^& Mgx3\HݞEgk4k8v kCvlup)A}d#F*#t|,CHK)˦PW1CAì W< `UVvCCa Ĵ&?v] ߯}h_z>>߽}z7a p(o~~_́*usN weU7۷dFQDq>)JJQ1U?t'g*̉R  I`NwO9>:3dǫ>ݿ;^{Z;4N7 4{y[H~v&p1۱u؃ 4NoULv`о [T?'"e 2)[5jS$A8@d?5y 2;Ρ'1';KJ5gǁ7«6ᏇbLkt<2py`oPЙ/Ig%ԩmdq"׹d#=A|[DJWш* dp}X䑆Q>s~ "'tSƥOD'f` |bt>ڞT(W_yq{J]wdU_&ё(!h囼 xf`@rGRwn%}Ό:J;3}%|7de BP ~(O6@S ΘH^88g=+ puGjyz#U,Xg[) IS<˟Nc?F "?zm^KWE}Q?0pC>@_Vp6C}_vo}tthWki+lkY1eBYqdBݠ-푯,Kz]qar"$@O8PϔWzݞ`;+[F:݇+x$=#|tՙFGGW쑸QynIqgvRAz%>ݒ 5F+۵oiVz8"Z"55Dn)0xBzndpש1 ǚ{,cش%h&!t;蕁%Qf~1U3( .`?a;dgt]򉼩B?2/tG>HGB>8yt QbPGx2sm%%! _el,h1+?*Ɋh2* }['0YƊy@42o.IfDz`w2A @RDL>]Hh2,V-d43>/.gt:JJNK,%VAd<{Ř4NΥvfh Rd \=tr`pnkC+ Q0< 4A %@s<vﻫ=!~3bGi0Ri tPC4K%\SpyuNgi`_P{ž(98ӥ"Mf9* ț~DmlM"\<n}-V K]'oIaAPgk 3SQNWfZE׃u4Ӎ&y%33G(VГ`df*ޅ,cj;]Y,n;mA%VxYh2H2pr+rS' UuHRzA2|Mo+ gEIuM6:PNL|WlĺԢ]QاZW&@}Uʧ>-#xOO4zryfº\V+QuRm#OLe#O7{S 8eh^VCWLU\  ]qAxQeٸ˺ 9-)_wlu6ZϡGDҋv6 /؈*b,/|=() ĕ\Ҟ9y g?CԜ x ]Sw qyXB|U(hpTdVvp Շ\$mzl[|qdL/#!cx?pƀ v~0lˮr̵](`hUwqklsg9$ %Fea l„c5 `N*3'e<9Sr/gw{$(QͱbA_zlcW=I,pv6 Xulʵ#[|Gد(*۬^f9uG2Q>"$RPtV FcHr.w=>̥,A4c L bYP61>+1 avf!6N0n1ņ9qXxC:'a/Jf5NWw*wۇ8xd;yB w*!۸94<, ӱ߮]7&S2ӑ2я@0 |Fpܫ]Wyc46s,(G{:B.7hL&#{= :I-O&>oC38 NIm LւvT::Y| sb4q L8by-t hoabMe)yy iw0EQ'i#˓ _QlR&f݊+p-劏/{<''ƥ. @{?/F닧eϥ݆@{W~i7yai'7Gt<%=Ю.4@u׹vnyӯk7>1~ӯmphJӏh]%|9~:>eT3=Kہ#\y0.d,F>uŁδj3a7tJC=A~. [|-CmݱuWC#Cji0K5׉9gp@qä#-#)uK\+\J\(f_ҽߣua{sjJ gBGfw]rpV4KY3e%ea>]걁Wʷ4gf1pdn\-&~ۓIw#fYGۿd A~o\3].cpN@Iu+=y%d:oE(M/nʔ#KqpBF(>+82+ =[T$y&?ܸK#c,K,hi,̲ I-D\a QM00]VMKnԌ5 HiׂhÁ#tVAxčS6I䐙Yy C>^jQ6:ʵ^X}uѝpq6g@uQ,Nbx7rOQ⠣[2oS]RUN}rY(O& 3˃s dQ'?1U6 *DYajY塳:*|cH 7P;}%'PN1-#n{aVls*[as`"#F]YB ל,GvS TptpDpY=@> IW=ܶ^G3BO-.՗Dk֭djA2_ Lܜ(˖*>"rp' t.AcPk>CҐWj4V@`jܚRu1w,C^C$982/~_*ԪWvDP#hf`yWNGMclVڂ3RP '?}.dF\ l@i'H#CDq)&jz񏽲PɗQsty7ו/*HC~ߐq'/Juo6R@C$Th-z)`b|՗P7\Av{hAN,r"l@M<0)6"Yac@| IS&|k![.[0B{e?;m7 dD4~dvCBٮ|0\|Jj0H4YF७?wwp_O\ f/((m%< ׻Ea>a9p@>U^b]V ZݦߙFml,")& Fqn9DxR4W>=Zqz1HTDzd9tf5f]~㈅gZ]p6HWYyWBtL|iPh]F/m UGh[i2:J\ssM9RSxoW߆IZuc=fhc{/{ʋg-ne#o8HNa5x$gxʙoab-Sď&+¥!㪎CEGWWc䎌?C/|ɛeu-I[ i yA..@ 5& "V#ɬ:Q//nҲĩ} 0%MYL:R6n;,n`mYO5iMʠ*@6Anp>"@?ˀuAi;W!" 1<"=0x<#O|Y>de@GyG : `e ]v';|&q1x{y'eTLN^8<%W\{Kd[Mje3&;TZ_>tnux10!E4mnn6+S>6{ ym/zB)Ͷ}¿3?3ܹsٳۡC3vѻe5c̀x&iп1u^;?`ןZ}T~=ɓ?'}nagKq`046I:ۋ#(#اi1l;5bW{C>y l:0tX<2>ڙ-g E,yYGY.;A cN[F`A6&>Q3FtW(&Nqܧ\JAi߇7 %8hؐ\EʽtG8)| HO~(Op4$8GtNL2{d*`" y23.ai ;HL_k٬ǥs,?5(=a.'SJ/u=9,"_-_+M†hS<Ѻ E-Bꆷˆ*(socHwPMՏj$gЂ J0\d}V[CZ/xtj[4ȃy/v ,{e jQFSyzy,Lۚ,~/tM]v ;lo)^.Oik%,о&MssSϔ:R0@6?I\oM<'jrBt:H#l_c!dxO \"Og) a"и%`0?/%LXs4ux,p}iJ܍a#m, GZNޣ*8j|FZG},?l1<?5wuhZ&m8V8@d<9jc$MZKz5Qp:SfU ͞y`/Z2R^n``8YCZPmؿ DP6QN}m/Lr f9{ZI^턧,A ]p#,=WjN ͧ JE;ӬJo.p ]`:5Zq!/7Y"'4G)s+vXFUmҤC9'+.+E$tc Ͳv)r g l&(``K<\eao&s U`d|瀄NB\>C(i`ZZxzwdfUEwWH8"|ߜ |?^Fy\ԣ ͊l= /=0ޞrD2-Qǵ'ifrKq3s%N\4uvpeu2 d䀆_@gYȈz¨ &guPa/%-r0oI2Dih/HS >@yۼU@e8l~ gmW fŏYW4rWO7@MI] mK-Aj`T:*%O#iAq-ɬi48`~I:ryw2X3JS/*"vSDܷ[|>Jwټcl'xcmrSL"W.)95(`+HR5mZ2܅Klˀ7vr> VhhqJ޸.%8 5esh| 7K<ӲJ*u8mTyuqg⚸:l;ڍ h 3WV.yÕ+ܑ+/ɉ7JK];='/cԡD*mU]$+ulF⇿S{ns^Y!fW|x<>" Xz@x{D%uV)@WؘA[|Yάg~7r38B>U!9>*:a/}08;X'mĕOpGHht,GT|[@g8goXIcU%<g7,ڪޡ]{D*Ԉh-D*Z.)!Sx `R! P#ՎtIu}/fg 8 pWY7ǖH]8p@@Ƞ8I4m<. v[^YBʾF1, -o+tӸz.ʯ'>7}>SݛnKE'8gc캯zWin"XlpV֎_Z? N Ot.{^ D~VeHc<ɳ+|?(4ڸK!Y}_@g 6,| sڟX,d/ӎ?޾+2{{n v!Ka` F 8$vۛWjF9Fh+ljY(=N:T;aO&p7hfuZ %' ݲZ~!a<2"@@&9|ږ.Nk*x^/p$Gq0 Da0Cj0IJPG\dw!6 W$!p?6;{˃G8mZ&`?隑ViB6T|EJp~ʫ́oϞc{<o+!/{g"o$A"nWODCA.W?Ҟˡ6oeu( T3$^L='h IDATU ?юWK [+<pAqU72>emo] BRYd}S,ifҭQ;e] \Y p([g/y>7?|9"g Qi&/FqL"o;@ﬢ<DtHQm+KWb9)pNXCgl(zfRt2+I,4`p\2l&r!9ĐM]D[Xq:Pl6pW1-ę'w,ڣŠr ~!z;u7e eDہ͙NJqJx O?{-g[JG(`tvkֆ`I4:Mz<7̙KzXA-0 m81'XIlaM;%z?pC^H~t 'X9[:2O0(V:a&p)N% 45zwbe%.E&('CP]UYiDR;F{j 2/[}HLÕ ṔO vi/oiùAYx N⒦l|f^y2+mCcSyYʯ\?-G7c}]e49[%>.4fwm([R#>L?*r=\ x;ޑ껷ÇgKW?#? 9(/gO~rΙ豱}}a:\Jd~}⩼j__IVa|C M>x3Ѿ>y Moo H/OT~?Fp+_ʤ~q{+^)-틾.ң:q"I3E4Kuw& 9 &k=2!JPOa*fm #vvIfѼ:>c_y:cb|C 3 yw u̢4:8Μ_ng3E}i䤼(ao"mh+vȱ*g éS6 @ Kbn9I_H2W}p [UKouޡWIWO<6+roCEa-/ޮo~L`6^*~[ r#?p2=j"b_4*Ԧ8~:(> Ϡ߷qNw]&LZƷ@T9gho_*E&& Q,9l(J^6 h|K%%:_0g-=Пu[~*H+Įp_z~yp5ïi떮KV-@T.U}%[dS 1#/D ՙx w/eแ^IOhЛ2֟k2{>׀BMOwʄA{4D@?HfۊMQ/I%}#DT@_:i'T/ ZC胃q/i} ham|~:Ǚsk`aB6re=RR7+ԫ\#ڬ4okuT?Y=ƫ$VNS4RYɄsv\oo( y^X\M+Qf*GDB.;g̚HJc˯~ $Htro;[,paN6ԑ|FHSAa,2 +00rH9~Sܑ f ϖE+=Q8T3ZtLI1=E ]x@6x*vGʉ:)`x1.(Y3enlT=+{)#:kd0eS6^1C(L2x1z-&%Ru>ʍOc=-ҩvS&>! -Ҿ 03ОWOcqxwkc@[ǖ0 ׌k?u˲.,g3~{c0ooIp@F>-egڕW^G<.vY}ٗ呫(^׵=i93}C;;u[om{y«_̾E|:_\y=﷼-9 ޥ.fѱ/T }}K?mrB9:ݑ,Arb` ŀ#>oO?yfsL:r,c$8[x_آ-iKLif8y<{ñEy̆K>eǎÍg Y?KR^̵-pyF_o;:JWRLS?f@eS_sX͠c49~{9 jj@gct]"K>֝pGvg!I^+ꨪDe0d43o5ȬYx: )3yT+LH+p4E%ncl ,g r]h$;H9Z:,wJQF<{{-^iYuJ|Ӵ{;̖#N)}6{)5US_vP^ LG-]ο. +KOCo?;p)G- =n}<:I!8k.WNK?Rx+AݾOo`IWy }f8Ea"ql[@YϢ7͎8\9{Yܞ1W ȿG mf wyT#DR@IY*W\8 e4e?/~g{h>rV}pṲ25h058aҠiiiRw7/aD-mD^(Y6h7 2I~9Zڕ|jCwy,nJbd4Q\1))lU0gրiQvw<|Ό"3< [Yw4Λ4dV$F , Z#wTDV-fuB$bG;5R\W(=I~Q^7$ VКɳxg 6)ֹɌz6E@T+tSV\'t*{y(ņ@bB^gO_);>g%N gG#'h+.k|VO1W̭G>p}oQ tztW9N{K n=u4YzV9Ko{;v,{qگ@a/*=붬.ܽz<<={oe]֮ڽd+tˀ.,,hnY+rp9E:w~'s<'?/Gon)v[}ݭ1̟ei'ڇ` Nz",Ʈ4]:" [ifb+M,l;qTk(AJ1C띸VIl@@Nu lk~W/֤`: lζΊ,}7s2W(/ϬWas[GWKq" }Kmya%4kFI*ym:RBt'0uά?q8=Đk?cKd5wVc },sWVa0_QAެ@ּgCdL>wc@=SrYގSCuHN~WZGκ\= ~X`8@0ry09b8P~NE:#Lפf<U g!mWz 8b)#6-e꥕[ ;y #cO9 Uz&"p 3^ꟁmK_<䝺f h|S]TKq1O+tpw 3YN<f^`XN^8\c-GPJ{{HP݈iw av@bF@Gy' \X^Wh>_TŠ?ɑ'|ok?t i jPi)iЉ<*DB(yh>VvZ \ Ų;tJ&ĐB<а@'zD2B!]V6~Z-pT?Fp2N0kQ8(}Dɓ6" a{EϑUTԛ7)3cW:N}mVo8rKg "sxEA=<R)Zp߾Mcwb kAOvϸ_)((^[ߞ6}pŀ2P~ygeZE% 89?ƒr >G)"Xhu]zdn:0c91g o wņRoq2~lJIZ5SaSߡó2x qg=QX"`8V]p†VK:&3 竞TA(P)$5P2'OGN FY)>ĥ*wOhqm(sJP_%{!d"uaYymQ.1 / f G:Būҙ[cMFf ٛO٥?;;?_rG^eSc߾KfڳlۿҞrx==ϞmWy^{m{}Ѻ.|A~[y~kG>~~ ^3>nNLMMeAIwEguū7똱>OqM7ݔ}VՏ+ ~1Y@C,X/}i{88Ye9yg?;w|wTv?O~W52M nmLJK>s5^իhZөGcEǎ]-TV`ib|3: '}:H}Oqh? }>N²>s@'ܙgn9{iSB9L]w"}0np]h꧜Q':[D3)xGx&KiO ~@bii59Xl”+(NY:b=Y370t @0Is.x,G:}Z/]'} LSg[/(S=aY] 9gp<K;Xa5s`;!ye"L>+ {2AU<\zA{ uQ@Ve t[8?O+8DΜgg0|:첬as {?'Rwg)թN+<2`>n e$o[3&m{?BGWNg_]i3,%0(T{Wà.d#Yn 8p?/kh9[Y|ΙM3䡗A u0KWݓ#oXtNЮSKX=G)KkmV@l? "1[:vaʅLDK@g+5c;.Ξ,2\]W_K;䇶Oĥ0:pw`F#KC8Cuye +0??[)paE?s?>\x/ qΛn}WuI[څ0.8~ qo\0hƧ'\< @6[L[lѮuw-8z}/>\I/)8W̳^x[΂F[eCsu<ɑmSp"}::ۖKLa, ke + g}-wSb \j:=M߭3js+<跎|:8e2ΚZ8p5]rkXHh7ƌT> l{e:SGg (u;òʭ q)w#/ba)CbMC ng(b!>q.jс7U' IDAT_{udP ϏtEW7 X3pO v `ҭ݀|qec3ި'D#WRI_(lR˭~ u |sKkThK|*MCh N'n^k1fB=<###o10Oɴ+^@ &ox!$ U`@z\]/N3J:Ѱ>z끪'@n4wʹbA`c~?{ 4To,@r]yknLs;DgYG\"O)cea]kGs`f10nhP:8<8:9[bdq,e%i24*,uNA2tF=i7+ۤم;=-K)rfyf@ :Ҥ4>|q d^?*usD; 8n{x=gfs ˓HjF~ wsܲ@:rPK@G>눎Nb~\W12\{ G~Lyo~$'ua+[41 A~DԍjTE8mMzo 8i.`%')pr9,eE~Nt`1c]IúΚ0au.2% ) LXfJJ|s@ 3+5t,o<aUN{xX) 3 U 6zeden/~*;-W+H %bvM;Q|Bi|cݩv/a\[aJUlS7mQ~Cs'ܓ+,iyXO~# ڴ .>S $:xeCΠNeyhB\[sb kD>a`Nt,ǀ:?ʄ5]xu>n}7lՑv哔oRi `PTY<" 0!a+`Qzv+4'9oX턅nv4 B-dr~FRvSlOg'i+pF _@i*g] !t"`֚!W(jR|pպzGm^aOGZ`-5rna'D jF@ZbcuB,e56dT`H|uhG2cn{Gsެ@)#]3 䄁6p+g)@g:i㷰 SG} b`"{-Ѵ h.RGFUE<Ju?e= \e(qr%.ᗗ}dA=.s/ݺJ?k4]*~r@gƟOm({icpfwg(;m;Vʗ`Otpda Ls9 g`G_K5M#Y뗰j6K[ 3{J8g;6m]f=uI㵇n10X1&TܳϽK!u:;fڥ p1/ d谁8!w38YŒ-6 20͉)O]m%\QkdԞ{D AVGLj3/V ȖD ow2翄d|#tw*%zw6L>0]([QI}gxpu.AD2y>%pSIG1,uĠYy!}>2 d>1AE$`ǫ_88Sv^z#_ Oq훽YJv7:h8o-,-B3xۇBpILۢ/Jo9p ;#V0 ګ?v{:Ͻ~0+4+a9gH1,e0 yPL]B/Uu πK4ӑʹdzw| -,t{<F> _4$ֺ>K\Itq* B%\i3D2JB><G{3.e<%ju'e\ՑiFOx:a34c YgHu eXWQpKNdND'2HW]V =c8? XdhfuH #7q\#/Ǿ1e:G\ya_D}8E; `//?e.o@S̶zj58Xo>'δ.E3X=(N.o ]W^_!JO>tg R)i - c2C< QK>j+v5ce}lAvoA3XLr(e `Nң8g sV苁r;>?v٤2$FpT8Wy9pHr㮞hhO"Gxltɋ/-׾F&)* Wp3qqf= Jt8+D*S|/& r G,96q[ ׀*D7m*;W%^z_f9MJ2[}A[$>:dCna[O矃"p|3@m7L v43{G2_zqOy VV_On]ne\i KA˿q>iBO 5'Z VD W7d0振Z/ph4vb@~g3S/ L)M&0co@` Sx ΝѰMf(G*l <휬[t>|Kr2w%Ab/eF~<}zg}$\>\gC@ѱ$M;zKY SмeP,''?0 \?yk,}TR:K:[ ]<;ԍ1K}^\+XZOg|[')p8X.C} :FEvgI IxyVP3ҶR$]&/d&ԕںA:+iȚ }hWrBĺlt?ALὃn=P9.rЅz$'k4u i@j!T N^*x# A)׭qdYK~S잗@_FgCP?gvHZ.b{}/]8pEĆa{pvXޝZ.БӴM9ž?O*)p zq;سMȏ>vs\P9K!:5`#N2}a`![aºNJHw6SoZskxA^tg"^Je~vۖY}OC҄ʢ;_Ⱦ! ! R B# rǁ ʈ J {v{~QHAcGϚk=39ǨQUFmNInT͜ZG )h~QR;TF3v/>;}2 wNM^xA,vYu& w}ӽýY]o7+)64r1}L;1ٯF P@a4sv!cnw ]w|4m2|0ME`iGݐ󣍳 t/I혆d|ٝCg-GFd'?oBZZ*Fg'܄ Xb IDATn.U.l+[& l%Q}q6F5J{pYD<[xi~fOZ|Qח/NofCNN2HG}vK_=_2ba4cy_U>=mXe)^(Օgǜ# /#Cć`z>s eԂmUя/XOw Yez>cg?9?4SeQɻDY);a<;10 Ne/]Pw- ,t y[_B}LfԬcWWTj\ -,xUjeݭk}G\粴] b|?gِ-AdYf]~W愋|@Y;<{<3.[^տHG~[X c:E0[1+.Y t%Qs͌ x vT.گp'6ʷp@6?Ӿ}М珿XeP֏ιNqtG;}agfE%2|sbևH>z;^y~4O\7>X/Fj[?( Υ.]{~*e%ZRxqֽ3΄v^9Ǐ-KsZSݣ~.-PI1Z3!-vrp?ZOVNr@uE#*|-ao2 [08n8kTD9 DC "-=8Clpi8+1:MU ?zFtX[Gyǟ:ȼ`^s5%rK5m)WU>^ۑtQ:CnJޣsL0R)=NoQ!8F^2ڌ\mzm` NvnDSC;'8(sx Ǡ fMJ,𠿞*~fcg)K΍6WQ.z^&F8si([B˻-pJ;ycQ桓[̦-›jz .Q,ڱ.@KwWa(W49 vF 델ůїLUx/{,Q౱yC>Am7ޜ{%¯)9Gz8LxߚJvMnÕ5п?[.mWڧɎͼeΆoh:@JsO a~={>ճ'S洐~ Tݣ?·zNOeFn~8nyKE9=,=ޗYjcpT5CP?6@gr mnXA.fiz +׵)A[Q!HPbw\9p g .whuvJxֻ* U_sӆF3miƿ7b)YH?||0\~bl߂Y2r U{=Kf {rIAfrG!ENqu @/~ީ&Pz3v!2ڔQ/ zm7.՗vmzʦ&ս>}TGΜU~+#fm?xyl&](Fu`_ѲϘs'MbA~{}CS]^ַe# ӏ L=3Cho^uqeAw\ .f܊FHKH9UP|܈^ž;T5|AK3k˞v$ʹOWE.僼Zp md_D|mCDcFS.X4 h7OOk !a*Χf hX*'XmXo_lIW Y`9*9J:|bny` ޅC>+gJ\~`ش|6ԓһ4A" z$0XqY࡬H(spxC{0,rjFFI`##`~Cii&h# =A=Ż>,GѽpCmȅQ%ܛz8a~|~'Z_Mvh?)"_[ x́ykFNf0frrKP\ ŒoMk('G`^9fFNpS_ssB(tT}[*ö7a}3FkN|>2ee3oj 7vRs8)YSN OFUFHƎ#,3jq)6"t&>GCC<3ˢwY~h!pWJХS!G:Cר7ꢍ:=׏ ,yx ~N4W3Zwu` \} F };9_WT"p_#GQcʷo R‹/FBϡozW [8Q9=1fA;B``Z{E Oo2:yп.uf3X>No0&_1}~1zLP{Ƿ0,"~' M_m/gXuiޜ\2K~TPSzSG~q֟AS¯h8/KK (rQY۴OqgKֹPTQre]Fg]„򠯌g_?D'yNp):B@݌p:Zn$=Ҟ%:uH)A;.{&),@xI& y.Mvw%W(Yh`ܻ?fE̅2f2SexD)uXG=UF?{}^s5FMg6|5O!2'5!t֓ P-`p>immzc~2N AZG-*]Sglnv] BE5x289CS z:/$FAKy8 Q^N\TuP=ױ3,_ͨ"0'FXeIlvѷT1JKIۘ[Jި^4C{B^vqyq 6)XRe~+IABΖ^= `铂<@`9|GǖCIS9*עƀ X"2O!X%zF䪎ӝ`n'M}w\߿t^Fp20P59י=+I`-t٦~7#95VySFdPkl6MWa")NNKq UK2|xI6ptM.wt*.gݵD[q,? 5R_UT&8Z6j9n<~m?;`A{X?xwz|2ANrvaP^Mn0,?uQ9ߌ}d7=^@ 81k({)K{FyꝞ.A&:LVH;:^MhIJF{w 碷)~We] , xLɲ׫ٽW.rUtSTTK9 9K"ts0?n&LCS}N+ >@nlt+@["=3; ЃGvZLrfIn՟qD_; Aۡ`]sgu@ةPWQ؆|a >!͏jԏo_cIv*2O{_ 9fx >TA}T6[i.Oy=+ d \wwײ:/EwxUk 1^5h6{Fcp4m cun' :v CaZ,'xSQ)nf׽m̼b!Ū1lfC^SQm\ 7f?|Rٚ5U|voϭ#NhC<0;cߜs#nJyXgtm|p<& (tT^OGgrp3O>nyP8O>u|ެ1u8<gY}C{Fڗۜdܘ]Y㱯{s=-pcV@5ǀ|lFBoB7{_qZᄠ:%sѽvҢ?ϽQ`)g,w ʱќQX7sIˀQbm]ڢ򅶙2Wg;{”h\Geg>VYu~N&?l?GS4{Rr4Uɦ~b}f6:s齗6CZ1S.iG{.=BiSxU~G&L8],51˅pCM6 A{5(}Z.X// d4wNm0OeĎՍ= zRo='ǒf%g6(o{O?Iǐ];l/eDԎpf:=ӌ T45N vN_s0~1=]Obܢ>s2}' WVw,ԺPo˜aiZu5\$1`h>p  IDATgzC'>W鶙4}p{;Zi$W@>6UaC,hU^ֹt ʉQ f Gβo ZJG$rVCF?ܖҢ}M>K/Hy RiEJ|HGF׽^DUmP:ʡ߁<lić:p]ywt R[0ź@.B֫Q)-Ljx#~?o6ͮ |\}^y:~Z*}fEVfϦSe6 |ٽFqNow=w?ێ.xnֺ38hcir?0pt[ 1W=SA7޸3je{-j zsX8h N'w r1hQ̬ 0x0/uA-v`pL\8%\ adm~ri9DÝy3?@Wַqt׷蒪p \'9JycTsƞ4]?8?UyaDN7*y2@Ye* MtÒxb !dnf cL]@ߋ sf|XS!T~g7_}bԌf/nyOݛw7+24_]^=#A vg[<>oEzވmsaE]/~3x 9':Dl&11njPxxԷ%9% .ƄoT2wп[3V`KQQ7YҳY@#K6سmH M;z ؍d\y˭|H0O>~?ޣ6uNe+p۷*ܻ)?tj@)[Kw:6T\|mdg|: N#z>Y=S`5Rfw/y| J{;76]r!\!&@}"X3W/tӞ=]C.z೫mW@=g>f;Y컖Jr"RʺB%6-C+K~AcS.zGR@V/AWǑ =mThps.|TQ=3KFYS\7K+l] Kq)[2y7$HO{}mҫEItseBx YWO5WAAer =A"^<&nFA0"fF홍L|i"袯Mk PmbqA%/Ki~W #7'J!Q^. ψjP,#b1٣{%!$b`Fk`L䃘IepkYCy'W%`̨,8ac~4|Ă^֣ ~[14U>dy^7okf\ϖ= ~֯>Dw? hLqij <Қ._1c.BѮ>;r:xo^ EF:/H>ϻ.{tCp>pKRtw<3|!a\D ݑ+kOܸNdPms TY9Jg':@#YW9t[Jsf:Nx Œ,!}{<3}o26#9Ο#̱o$nu̠33'4="%UΐgF/{/`9*z: 2( q5 ?ןWHKF]t~w|_TȤG/E]%w;&):5ƌ%ꋎB"_ ɫuQuџC> p,3Sα4tC9uֹЋVc:+ۣC2 pp?m'G~O/8 ]e3Ʒ@W cz;;4^ݫ|5 6_rȰ5ÕSdg^>}Ժn9Q_oz;9vN΄M x y kT?ecNkgls/ VY >f/, JVt a?ڤKeJ-3lcWxm9T6Uuho^7 ~0Xf 嘯sh]MOLBsbv &k9gB&~Em8d?ֵӟǷ3Gaˏ~qDt[y؋"ឣ3>G COaȷ:z7n~fj)˖W<\i<<;pm%*Nѻ4&^}NM<꙲mkf6ܪeGkVG+h6%= :|31,Q%A ؃=o6SZNxg?~{ "@o}ӧ?K{~ȖR`R@Eu64lJDLTIJWhIBhww}/"ppu79c9O i;GM/.`0=rξI:I2!KfApIwidG|=!r_ ,λgᏤC2#*"І@?+G0h7rN9P^ Cm^(zS0|>6\5\p%r Jhi+'b ,>|*}Hs~g/!oeBWך 4*;K}4ghTfSY"Q5k_8-\^25RA|5^s'j;]BWOWb]\ Chbz?kG]KXvv,Yo`$Aw7mXջ.nGᣟHwr/ff{=t[?*`Qu0H~#2Ѯ?rưJ@AQY]o:} 83@e9Rzv~͖60h}ugtAܸLޞ}^J5)ӎo!HɁfFybkjnvC}nXFq}QxD^>]@iWقaKsN vʓt]MqS>jH~T[^=da]i0jFUuk`Ta{D ޔ&6{%4?U[E݂-_6iQnQoRfFiZeYن3sz=7^Tǔ[e<Mn^%g9wri!U59wISګ/jfTQO+]]aQ;.H^ʺҍ%c̗ZNgrY*U{o<)H`# \_F_َg_ZS0Z2q":hZHfuXFh>鍺nlIQs =G]#flq{wFs=-7d5ɓ%'s֨A_ȀOkO _9b[8]Cݴ͔n;}?`i(e)ꋦ{[}Yz9tќOYیN<}Eq8ìwf9]?~/kE1܌R^1(IŦg݆͘taD踜[̀Z3lƋ9޵iqƏ~x9PGm4vZS>}J9܌9tSőf^XiO^ g9فM]~Hw}xth]xl``S/53Bpe92_Gu긮z#Ah3ʹ ֧ ?\ qw?U'd"G$tf 'C"FK>bkx׃>yk; |^j[kO"++ޤD^$h+jC(?}Cm`Qp7>c|K=)}PQ*^yg#m9Cp^bXK+X.c9l,?F&DB`ƔsW*;8*:˿2Go hBoSC>_k{ޣ_BFWLGiۃO wڅNTźQrsntO&}.\tӑ(E 95)(aRVg#XzO}~<"PƒQd1=gM12pt5bͱthuK2bJ T1Zs8n">e# rD*j^x7eăa<5~ėĕ{VGu *Ki2כ.bmsDlC8f - oAH*]F*bfs?V9w \KDr+L5Bx8'Gj_> hqakN7Q0YbSdT_:ǍlOC?Z>m☱F56P ӕ cvⷆÆ9f tNXN<rc$cc3{7Vnih"!1:WOk6k7˧/j342nmitFR,MԢ/j}.^zr~!lﭝ hP0\!Wl0/6AthrpB 7̶Qw{U'1sGZ]2KiG<~EDFkz|puWZL@~9v.8\ 2$l>C(~1Y}C2Zr^j屏E不!۵zZ4=׀*Ñ-Ybғ%yT,Evѿ"2*νP<}rU 4h|c&쏾R3%!S,L2çT=+3'[%Rw]y~­H}rq} @wz'\N;_4vӟ}iE ?^y;_pPWsh5>*tA0wnUXN1YkA3z?,bE9 HDNc+;oǧ'MQ5hF7 UtU yW1?Yf#</<.4xo}?;-H=0Cuo|gAjCxL<Ԉf RYz_>/9o+ߡR)sрP#@?}̋1[}EFs(ۅ}:0<|ݙChVWK[g(:Gz#)x֌TN.F ǴC ΀l~3×qlm^r[<BN X޻߼ Ҽ,0#tFfnyiwn+_wr\Nj' Cgx2<onՆɹY7N x@ڜH9)ﵬa3jģ?UVzz"y$ZP%vyE+}qЎ>x'߱U?'7~Efnu+.<@<p" UzVvM *}0tMy"> .o?*ζ@MbY3, z9 u؂=@L`?^ӥF뎬g1|qt=|#p܃f!oF.FYs]SH EV*ߨ5=} z8sNZ`hQ l+L-M2UC:Vh (Ubug;a,ḕg_Mmq~vUh/m0ыmDNOpU'hEQy9T^g|/ϴ\\ӛ9F/69F#i>3`G֤ g6 6g0?(C>oW'sJ2HK?+<*n]LiY\5H mUX;72wi3}GOnмx6f˄6>qi52&ތ4Sj33]nA~{f`sޝ>^^ڍc0Vj~NçD`䯷}0g(A.*h(&07^lAwo"&ĚYl5l\CC$]?< Wd_攝~'x-kqi L8Fȃ} *eD_m釓]AQRZd=/SuVۦX1V~qwoߜΡ[Apm :N0;=/8.r^1PO#}O?nf69`JA ~M-.߾=/]9")+ ¤2X6mfޚW/.*[+Q1C3jԻߧ"UtRrV*AOza8)zml_zpx +^/ ֠MpVRoL(r-pHʇoe7p D|0pp (7=|})  Y #J[iPK89u :`"ʧ\3x&XF(y./Wy?Z)*=BC*oqJiWV;?h?0 \ùtxѾ5^s'tvteRjva/t9ӡc/ؕ`:9_4~.`]Z v@M[whN屋uA㓜ڍ?rȩ2\!yƺ9h,۩Pņռ=5͜-0af0+aÝ }}UZO@ o{,-z9MF,*e5zOTnkc8hvc~3P_fĭ?eT94:;#[+mN%zu52~l+x;gqoGz6Ց~=s茘1F.7$?J-{ryuaHy}kSwȋq' qB#EF6[,BliM@@4|87?lϵ6HvwV;D@,oP/nrz3|r.o*T7 y^q/V7pӎ{Ž2mvZr\J[G 3jkx%  &J/[;Ӯ]) MsN5)1:I@m2~G(ӆi}gNwޟTd"XJGbEJmsLhGs ~!f"Gx=FOFr#mgf ^ {|Ҏ0kóJXۻ>!x.X<ZpFpb=hDA+:~,M8W)ӡc[MV`̰G<=׶A\Un)g_zW(Cyt7WX%3#ݬKᦑt#KjG==0%^כ`<:\3G-{=zk .Xظ˨,e޽[$zouS^)bYFѽsޙppoh9`݆{Ȟ{~oh)qFFM5]=ڜE0XH\6xjyl= j{cJfgd,Ka0 أ_VǖZѕgنGj0ӠOګz787ʫ*t4=^EMňz}8ѨM%pjv[o6:k&£6/s}Mw6m~iBh\+XFd\eFV??k_'m@ 5nӝ~ exin =p4}f|n;K6 fKΏe!F,3yG7=5 61zp^X-r-~q2nE~?Q*CQ,|`||{U8gD9|,<68q*s*Gh?ƒs> 'ǃF:zKF۴W:W=##Ԁ? Dm-JXnvWN5Nob>\6ִ6k?,+N=敶}2EVP98c YYYc$?[Q]k<QϿ(JFH:>j@me.5bFxZV% ,Չ J!jP_/#Krdy:e3R6 v@Wi2*TrdW39; | 9CӄmK! loa/x8V9ـL{,˱usDs|tNߛuwN} IBǨ\p._vF?*RE F_Ս7o:'sɑ\hܒ9{3飳4WWLž_f婼3ZI_TzxU sC bDEh?<|1bv,/'@|SX}pSh:) tmOܨKrPAwo?/oogִOƿgN96+1Hc:IN?LW-U:HRoRqvO[w:c]өO(p;1T1؋ m'XiJTSj8~qOrz=jWFgyu FE\w`]懂d% ]:є%Z}ʨ՚;8TbT+Z_Db]W3^83 %@bs0DY+=K?zuȑq4xacl|X/pGf^T~JfxWA ϠK']iyr{N5&seSg|dӿxj(|=L:xI^_/gi6Z}w(2 ^:&1^C{krs" fD? Xkto9F|KsXCgyόA Hr!)!p&F&\o_;=9 e0> o~ c.rtN{iY$vvWnee~9FG|VE/mG:L9}#^pp -7MYC8TץۑrYœ`  @NkTI67~ؑo[R^:x Ai`Z?}@C%,((:8ʳLd ^{N,]m9 )ٺn_6s~r0\i{0=>,TWc-٩^LB0]"]% ʂ2^\p%[&û?X(XwA~LRql:no Y3xc ꔎESԧ낑tFۃ[#ґi-f ֏tlD=ps4g w#z Lk5z;h?]| 6T葖C6;!dȒfOGz)hH'å N{PГP{j[vu#ӧS~P:Ud.Ua}p?=fMfuUj}n(5n jexS$f)w=yxo9gs|yuJo'qŋFcVvJqGWٯ^3-@jCͧHN*nv~8#ӹ`rYT /J{F;Kɤ9|v,C`xULO`]t|=d6ek}L 438z,:)+ߛ 5<tm -ojt;߱8FɁo?" 3p cGkE??pqػAݓoۧ?g~{6n;EJG'5bk]k=gx%r8 ۳-̩t>޽՜a\jʿiEn) -ѾňMCerq1u_7*?/Sumk7OSr2,=N[o 蹒Ǟc*>PBH\((0*ZW72R"81֯ŔEœ$OE!&hq)"~)‡ɽV@W+gIga ҢQ^q+-`^x[1 ".oYa#JX Xz.8 'w k6B]*3߳əw2磄3=Vs1}~ht{nFYl/09ÀퟐXsCQk92vdߖ3K%?42 bsD3T9dgѬ >Y|[ KyLeS-I_P* ;]Bnif;ޣ<Kr$Gyw8 ).ƙ}X9{gY!nM7pa;^Oŏk ,e ̩Y{NgM{=o҂)g_{դ0lxr-"[,ق6C|sρ}3G =N`cp…#o z? ;/F HxQRS'?g&EQ9S>踵xsu64Lg 83ѭ.-ؤbFkKIo*ݠ@;V`E]72gilxMA FHtoН~A 6^%O)سk_⍙Xʰ߷= Hr7Ե5O)^& D=Аƀ?T-`IG!F^"VTq7|!Frj' z·%=Ǐ֛Wv:.7;o 8Shq \~r*d] /= $8=x*)g54Q&l&>>7kuS9Xhts Wr`AǽscX '1 L zK/(jPےSzϲҟy3JF,9d{?__Z[D_8J{Ճͯʯo3տ~_plF@UT<4jOi}זoqg0cm?z*I_ ?0 muε-~׮cJ.ݺJ.]n[PVGL]mi~3)3hq_^7{AVlN\t;33|8miiSƥ23-7ӖrrxG׵8+[?_Mt. &coBe;ZΠ6f# }g:]QYp#gzƓlPKI0,]{YAE L/K*WFL$+]1VFvW'Fǧl."GqxD9DͩSft2_ ojo&} r|/Vctj"{O6eݏdɞ *%Fm=#_~&\1Fw7NZ~0ބxPfk(ۦp+4 ? "G@-<,?I]ݭ׏SknjeIȁ6e}zDSMNAo2`5G=5 }(K<93Eyf]y8xN&*wpH} Og|~O =M._;y7CgKq.0 "xpqYߡV=|p㭠ޖY  ݮ>2$<{8zvs7G3ݝTuF؜Bv%vY1 TodBQ[^^1Rc qU2 g@="' FK5L P.&~LV~BB \K2::uFQc]}SE`Ƒc3<՛w'ϟ8K#blhgx(.@U4NfX]% v7Bpy7<: a4Ee8 35r,8P Ʉ%Y#UVM7U{MLAaګ>.\κHr_㦟+3Yx7B=MK  v,7}TQoGjf܅)3"@4 ~ozn:Mx(*3L̙s`MZan6g91z]44sBxꈮRp?6c ǧʫ@ k4 +9A TN7tʹVWFW'9Jp<:BLf,_tf N AUwW gMw?jo#XxP#LvL`?-S@ȜjND,զ s89ygN?} ܚoy?M==XP)(9ȶ5::~j&Etpȼ{|xC}Uf"5e0i6i{#)4YyaXC-ċaP۠]4J|;j3ޕǨ8ќ*`jmt~zkSY7(P_3fz7 >nŻRn6M:AĻo}x7؞}Z6$0%R}pl*fj\Á6OLNNXTF"hsQh/dQl4%:j?ttJLg?_^`%VX`9h1x6cYufFDž_ `Ah$v|v2HEu׽Q>8lFLA|#%pScw@ DlƉim%%QY"<?p-d#.f΃wݮοg{@0$h!Fl KZD-*?TRMKV)`H*@((Zm!b2Ows~gg=ܴvy~=>kkT U;qҒ9{bkQ%r[e{d!ܪ *(r`d+-Hz^WO5C=>׃?` O{.z:vϧ.a.x8mW urQ]#~ 2>k9 Wڼ:ä+M'6*o7DL)c\{{g;;7Ϸ}yh>Fal}VL_~(噏w }g}gm7n^Wlo9sf--s#C//ʯ3˦WF_W?e+yի^5Q{wmmKWOO4O?"__Yd=SUOTDտW|tc?p󲗽lٳmL\8|?9uyы^t+Ǣz[4ܾ>1q9Vgd Ԇjϟ|V *n1[ԍ4NY;چ<ǁu}_t%Hr"JUvfp9~ 8Qu#Cr aO?q,< +0X (Nl#Y/}}`3FH̲ʚ>cO7ccVd[mZ<2>syey&r+l=ah2\S^ͼ }:suc8`qX>2[üO qd p=hF X>}NT^ʌNQVnj׶3UYG[r>Cz0o}5daoVJ&'1GgH <+#K~³j! ~m.;^tkEcyϛ&S6tXi8ģޑZood7{.^TYnhԪY/䏒OcX|O%gLsO3?/?͗?IO9} ow}ډ}oe|~c^HO޼f$ܗ3|Ge'V#oG?v`<1+Oi^|<~;lN@Q;Nݲw|]ޛÑWU>q_#GEk)] E8XڌvKҐR%1pG<}dJugSIi?:G.yfit`>4^*/*hLj %rfP WϦ/7E`Aۍ}wfhfiFq嵞<rQ#q;?{AGMQ`ih=_] R쫏h.̬Kfa{駏L4yk`#fyw?B2P*bիsg">}lp>n}yd\pޗ>~Cr<·,g>|cAYuqtS-SګxCK/̊}}'+~L]|bZP]Zvu%esi^Cp8iDے\Ds')N\? @`GA;6秀E2~taJ*k`Kf Pe֌*k\iv]>ΚC-_&p@H 0?N)I['̃`:  o'`Ӹ7-dMʲS4< s\o7?z}+Sÿ>w迟Y>s_oo_~?/`1ɟɌD_v=Wy}kE/mͿ73Ssw{{O)8w&8O o͛qݿ{$OO| 'p|z{~~t~n~z衇6|+7OIhq/??0//<p ݿ/+-9u3jm=tb} #nhu޳AeS5lګY~{ˌ+2ڻ1 y1 cDUchx̧3c$#7SpZAt'sz]ߗ53hKپ#ҫtdUkb_E3-bK_TOb*2&U;'@@ ym -pL>g@]Ӗz_,e6 3'=zY}կZm6J>&?ѾofX>C"cO7 ӊ0)qճ%B1[<ȟ=?+2F>?˿?9qRQotޭ_ />9~E 6pr_o8ZӼq9_0<#x;6/˫W#F9??:9֮?8 0?Sk/|w}yk_+3.A}^Mpp1<p |˾l|yJV^Wo4ͺإS`} <-oͿ93;vpn8ui[ןHp1;@=zv@OР1"Jqݤ>*ni|{=ӧ+;O<{kg@M9sT?#@8Fo,?b FkF{g_tωͯ~LCa[?}葎j9I5G1409F2W TNh})ax4c288uvv,!Xk,H&d/4flmiOo~uxqh!Gդ(ipk EDgYσ2p1"љ0p S:-n]B0OeG}2Bg#?Eof2}՞ IDATdK`w)Trơό^L,iٙ`^p]C]jg1E.d؆&*/9Jj/4W1CNe*=U5Ƅ.xri;`N#@Kf¸Y83Z2VIsVt먶:Ա{{i.(zs!|p7V]j\*{gʳ2XҨ~xt߫͹p7 ]h> &d^jԱsF-YP~.g|O4ChY4d4dA?~V`LNL9r3u%I'rRiO΄~td>) δ+cX"p93!,e..wy|CxMjr| c om],{<\՜S0+ȱWȂ:դ[>s zՏ~SYGӋ#=ZgBd&ʠgT/SUw$\ksu(w}FMexMpI>[qëVnOFc8^W#pɱA&X=+b#sC6N,\!ԑpWI1]+ Ez:ata~QvHH3¾ GО"ݍwusS^v":[y5(:xx'xՈ[҅~ &?xps38~.@ q䷣Z_k~pkgDgbxg4pi?߸. R?[ 6>gPӿF%?^UFCrMR6gSA2U cET&2!垿5}8*c' 9SWF0ΰ Po =V{*s}gv7[772]s/|_4u]~oK?cS}9_qF9__?I?Ϸ/lY<֏؏{K_}!x%/y|62 ?7KK2O3Esx+67~7n?G3o_/L7<OynVM;.LfFX4rt#ޯ? A2fF18}F.JGYnO 6zqC7ӍXPOQ; Qҝ0gtC:uW1vBFHYY=LOeh0>Y|ڑؓh>Fr0^jt5knsV/>>. =SmI6[dX_Qzr\8W|'y/k5!~s^D.5\1nP<5 oy?CFsn }_/9jPfC1ʸ>Qx?}oP9F8@v)j#ARM_I6sCf8IS 0t0l/ 6ݥRAc FׂQy-O&![SWEڸϴe?l#/VXF 8?|Roǥ/C7~:Qi;LIi1Tjvѡw%| ?'2 cWx.BBYpL6& s82\!#%fq2ҁYKSznɷr]@)FaNl œ%cD '^;@jnSf|MHcms(%~t9Fk䗼: ?\Pdp*V%AX2slGU~02UwWP:'"S^y.;^ɓJPIY#l(0;s1"z9rJTY'8 W2FtD#ipHOWks]i99@jtf8Uk @!t¥>tbe`gi&pqnemt5q`X_m0gW8k%ov˥_@zR3+^kޔ[qÃ8E|e3^\\hӉ6C2#; |_O@3MJ#.g[׳KFZADz-~mE !Ө10"9C(b>g@G]MSXL=rWaM\٪HVжru7ËaWy(X\=0"N都IQf vw~#7W 4sU%Q*bhwz[{*lsBV@C5z ~,m `92$W]/ gʞpyggCps~h0.hJzgp,bm<-U=FS`W'=VbTZИvA:'\ʁ/q _[7/asל)n`{n;asz3\>;|g{;^q9 %w/N>eϾvkܟ/7w~g~3o3@ܼ/[ưl~h/0f6yj[c̔9᛿7hٛ`ƌ/RSu.xqpc}Hz3}2zc>сe铞1 '!7AtN/ݜRnkYz4SN{6%g%: .̈a^d1|Y'/Ͽm~ݏg\QWO@u)5<[z3Fi'YXY>&M-a:_y,=9Lk^?UF`701gx6m /kFrڑ8RlB`gɤ ޯdiz/率nFޞOpU'pthFd>tjz: eG6D+hc2gt51 x3N;r[ApͩRٻ!5k'îg;U2R,e8#ɁFTgC9ʉ=1j Bl0w/<(9#=|1 \@ /Ah}$j-%F0z>hV CƩO"KDůnǧn ,̈,s<>| ʌ:,nJJNL8ݿyG6مWmk!`8ػ> Ya7EkOzPQib<F V{H89SkXvos2}.G\aqzxRj;xdfL'Nz,I / zeEBkf_$oC 8лPqr.- Y7s|l&hmU90͐kc9bGNjf3lԉOR~p]9Vg9"|irc-׺XzxγFK\LD#=*5Qd@1i1>P!8W *9=bkěӂM0](4Qt*} .!qz㽟?Av=`^) /McB̊sd%!FߤzY[-iK<(̾j_G:10Vp=Ro]'~!4M.ӽW՟[Ln9dtzwy T%dYޕ_c<~EZ2zv0I9/qI# @,SNɕ *2&4~A h_pbpSȽ).i]`R07X0Bh*hdLfnn}M}os̸qs[]HR *kd #,$ext؋w sI-hQ]\>xkSJg][0ks`y'm~#E?sn??M廲9woN6睛̓C+6~7j#>={hZЮwkʟU3~Z''gJ^ͻ͟S&rk5PƙH3q~;\ }`ã>y޷c+;u4jdk/@N1_i2An^Wo?Fqַu~~8>$<OK6N^TWX]`d?]ߟLOttr4P:;47ej V2r$0.LѕWK2q?ݺw3D,cΠF.!=Pz1DCAqݜ}Me?@[ߗAΪ\ϤÚ궫9k]/vNG=Z@f *A :LưbsgOHi:F-rm4bTnRTLcaw_x\X>Pǹ )C1N;&XWb\,q2&'F-4gde(5%K7k >6al[zGs]96&+#ݳ]rBw^__޼u*{vig7}&ڏip\ 1;J3M2^pl-vK\AL~fO}ŞsDdu3cՙo:V? LZNi"{wKd~CQެΧ]U/lɓJ8.]!N?U,$l}ҹSpc8h\ʻ;LJld ^`}`-swԑIq,Q 8݃o]Vגc87jϬ[FYґW8t P9ySoU1+>,]%pY:%"Ts@4 C:jj4^oJ{DQߘT^X"$8umxݖènp?9sha'[x83=?ٻh*4rʶ7IA^S*zDFm>4r0UՋ3P*MʹpPtHї^^qxKO8*&8o^@WuFh/|GH }/Y9f}{ulÇG -:Ŧ#zrkX |=P,oAIj2~m6\J<8U` Ps>O zk_y[޲/֦^j?=cFxO5/Y/ |(p p F]U7}7m?g[o#dg9 8q=L>q?>e>||Ӓ}w|3=s(Qm7Mkkw2G4GE@CɷvXCFf(g~H6Z20ʙ$,}]8~|CWK2z9첣,J0\2 21J/`Ju_Y;kO!Td#/}Qk3i$+bZ^v?124W).g3on3ͻK]zsϏcˀ=8㼝Dma/HO'0z6c;ft\᧫'|K l3 RJꑀ Oɿw㤁{։A৏2ΘE'2M IOu~=MNpMkt,gKa;~482}F+w6evU~mL&2 1ݯ`fS M˩Z0e@Eiޭc#{ϵ#-iO#;"3"[桷{DbF-@s>$)~t,pŧt96\j : Lc$):h+B )~{0Ns s{,9h N'HLB.k6F #Vi7]Lg>юP9 8 @׷]O32FFQJ7,~@o,:>{6ꖾgdу~~Γ]pUJiC{MwΦZ\_gz)GhOfzܡmtid$2&eePs2L)f ik/-D=9Οgt0NCJ G9$-4㮾99/8qB_b)#8tƴkF7ǪrK 0Fo30wKCPr?1gkG5gjFwLA7T*og XYg(]޹w0|Hv T2l lzw~l/UkpLF-;P 6NHĒ]Ob9~fLk9b/9 䭴3xp3.QWosɐ?bUmh ww0{*Cx|דc`%WﳳP8&^3Tp,/_L\؎O&;ZRh_3`~O qU)s1<9|xSi=5λ,pqi%4nNqw&pUK{)S'%l9@NӮѴ٥3@}zቋ$l"GG&Uy0j, #8k iS3t@e%L>ptx(׷:$<6H}qd,<1}y-9 F9>7پbL7gLh:~x>R`q[u*=ziQ7; dr=rHDn&.YsEJ#SfF{UDS ݎXcB[̳1n`roeJg>)'kw߳9pߋv|Q'^q|ۼ7i=yc\l,P;sߌ||~wo}c(&q^nӞtNޮV3zaQ_/Ћw Dq@R@я*3*'ݞ=ݥHa}hI{L3clN;cL邍\FNۛZ̚ðݳysFouTJtF2yr``(x?Sw?p&6hKA<و 1?S+稀#;~5 x<ƐD#^g~#E,7f8|E<>CSFH> A 1JVl^pçM7Acl/ P:ub "WP,D@]kM2!yy+.S.emQNF?x4?T*62YuE_QU$ |]ކaZs|dyMƐ%!P56] 7;NzxO|LsSxR`<G{K^T>xBcMlfY+M;gBx5pHhלGv$tZi~%O(oϫp;}:iNUwY ̥>&qq>'Uzf$8=xfɏ5 klL|>-@\,ȐSbήkҢݵ_ ȳ1}k+}VǸ.̴P'>?--0Xd!3eK>g[d4+Ffgrmw$A{"mcC{lDX+ffб 698%VY jG6xd F>^_lڙo.YG= ,;&MhYHڠg4Zt=}E{RM6 G^4zEԙ>KV$T$y3;c^F~fÌmJB5:l5F#i<ȹh+e1|GY#F\#[};`9nt=`Rlt#bwҎʽ`tƛn9^5! Ae[h_7p-G2Յo /%G@lb9FW kcZD8)z`1Kw^ɩ5p^v{0LZnWw\H⽓C[mǡ\WH Wh9݈8]Jݭ;?`w}m2tlʅ὞wܸv ^i+Ͱn:T@2\(((6]SO.= : f` \T_p!;?MVdJCB*MYה/<4H7N9?g7xn~՗l#oäW7O7nN߹yqPPόjm3Mhk]꯮Ko_.9T9v6ioW>ݖs|豎tk};Ic,^CO靖?>$_b {K4R>clo1Ľ)l 2\&uCyb)y{4LQ)WFs|S5ě/8]ʸȑ?%G#'n*q!}V+O=ψ<{sVO{7s.7]K^A9.707?u8&EbƬNނhχi;ݟP3Y:'8e`8Z~é|yDi\џB(e ]4镑jo|tç}J gkтtg~f>5+\姇({<\/)sDdzleq#FMn-#JWO[ Sr Oq 9^1'2T'BBBt>NpɶnZVF=,h_%ޯ[U9=N_QF9Шʻ6Wv+r3¯:RΞkfOf[o_xiLrD^w]˒OS9G7A!]6%DS5Ly(IШ8 !# 0U+J`)xk;8BM#ɄzG̩W>p5<̒ȇF01V>L(f@'$}Ex+֩[t>[iZyhR7eq4iLoQ':cwD ^52E`iq{%"B#x~-=^cdz P2·) @@])Q[|3%3A kAwy'Hu:[}+.,1-^ ^8VưMco 2E;A2901.}ۛw;@O6GOSK3nIH -Lgeݾns6>YrHUquKtGN밯Gqsf<Ƭsټ*Ir>{,xoN3?,qlXX4UtA09G.? <+9XFc/%WS%Ѫ=q|lᕱu9ccs0ud4xԅ+QY3Wx2O6K&Z;NDx\nU?jt Ev/`Li}u]4_M{9S;^Ofe\53>=\Eì7t@vk@N> )-h•W\Bڬ-2dK{3(%@^ɍݫmwQ897L= q)&ņ7{lHFҟO6IۯٗM?1:~b2mXK n(e7 T>f J[c3m>J=1^^Mg0l^w9}:L_-`+6KI~dNlN?#`i?B4,ocr^tu%:C}O4͖ntdj3AsX z (Uo`L 硒NvM;:"Y0+(Y]^>q6]=dOT,JR95S{6 Avَ:a[!z:V +Zo?'@IOx~۝v!/JhHL%q2<"SnU4ΏG"(:8OH0g^Ρ܂㔹J+"^s6 *iC-]Q,sƟyV+]%CN! q;ji^zKoMw/wtgNJ'և洔akL76Uh>EMeIt YX1r2:ots70JgmYSЧq`t.ϨaG1փX9FyHgۍhp0z=4'.|lTK{7kSB隮oS9֟s$y)wCg}?ZfG09!;i[AYNZ+R. (gkWd;?/tatd2^jǑ T`#H-@^ IDATdHTƾ΀gz1BV'8Yٌ|Wg)I\ǫsdSαd}&q!.d_em nZO*O)!C~4yeU8SSg6:k'r}WVbPƛVC4l֧ G(ZcIFhˬOA&O7ܲ#T9xD3>=Lhl'\NK?U{$V&]J3 %AxTEï4=Tntpk4hsxTVZW-uׂm;>ys OȎsrQћu)`FoxH 'jK\mɎ#C4Î^^Z?U2niw BUퟷ9pu90w:FAɼˌ6jf75#k)- Pl`:2m3Hwbc4LNy:jz߯ѡo3q}E;\ Psd3dq"7:{ zt4,1Vq8Zy=ᶂ9,h 7^/~t0Ș]E Z*rt HΪòdwlzUf#I/qm.dxoghczf/hDs]3S[",.=)=$r DAjFk:9Sch/W Dȩ z2f}dV*ȱuԥJCv#Ǒq8N@o1Rw3{Uq>̬5ץ*[5'ap G+#H^.hGNeS_s_}_*ɯ/$>.gɦ0,\><,CbAv (\j ޶}T6~2Hm4ήA+ꊟSWKql>.'4:jFĪ8_2ySZڑdu4T` ڿ` sF4HQҒA8k)Nl`(#v+7/Q[^'sQ\%SwT^ _mW]5__h]C͊8,^9 X.fLC']ɁUuM.|ʯ1KGa#ɐ<˛/ 0sT&;~PG\-Q B#'_3.(ih=q*jմmkה@TY*f#u?ʹǶb˩e٭cC4)s.S7Qm؏)C1\ =Y"C~kX1tUitVޚʿn @|5j>`ѶI \d0{IY#,LAPL!d-=[8rsjA} ko CN6M~o3P# OpEˎ3x"\) Wns6>I8=8 u=Q/em $w3ʩa8Gdk2"g`ߜ9> lr N) py]Kt *Jmޭ2} #h%`,C,hnAnc4{WaZto IZ1D0CiSBN͌RhxCqs̅cۛۆf`_ yhG2v8ִR-GɽF g3YбټMtMߒ #Mnv1c4JkB~шR֭NYIW:nP#3S7O4}sLT8쭟e%7UxѲqSt^-|zBmF',aF~|79d/>i9(N@{-9YhmZ1[lj RWq4ppw?O5jVʴPq{Ja%tft$1srZ'ql+3991_yokgt1)U'Xޙy"wBuه'"bhG6K|vz;UNѩ:h,,Gfmi33^?rn[qɳ]96q1XIgyI߈ݖz5@avjS-#o| }1ܺhsѯT+nkn 44mX\k ܇YY,=0`{'ܷ~P8~ Ƃ:ZͨGL.uKg^[Gz%9Y@!0ÕhL{tn7乻>I8'zmoqU,* AJt8Nxo6Ogq²}f )V6Ay47i`vԯCA@sg)5FU<Ʃ8*Hg!-'歨>U({$Dq7z_ FK3t |PG e();#%`"*='v]0aj=GeϘZ%zhߢǔȪ۵\@cQ{ͩ@g$ެERit*"=E.`*b-H"W1g!xfjHź$\NzCUg蘠}9ӛMLS $nw urssØc6b0ѓ}37\FS g3ݱ' #'6Spx0(t2q0LkԷgr)3l;2Lgkt38a n0SAzz9p_l շg +6֔]~FЪOtF+8î郃״]#8I;@N!X0̌PecdFxQ|<=]h \? zb3qH"z($ . 'o[߬O8FYl?ymm#DB]cwE{?6^tYkpiC\_$~tطLR55D,Ol2':4)gʞ:SS0l-~/<xцjz%3wEhHjhԣvU`}[p X83O7nx:VHftm'Bpi5#I4}PzIpHצnOGea)B}bʠZ}[F!vʧnԯXi+|<zZ:v`Rʔz9FFk)mÏ*eL.*Пpg-R.pyy\}~W)`.CR)3^zF0^Ԕ'rw{ƸР1kuӭ9h Z56dợX:^+kAm^x'vq4@9hÿm¾Pm !bpF/CrG'+pB8WVOcU6FMOˌm5vYK D,ڂjy[ .h֥$&jdfOEX+ft]L)ljZэתS0O;IL8kքWUSq+L{1{+ƈ眅^ )vˆ3YYơfL n>+!\][+j n4$xG >/:=@-8p䔣v3 XNSk(}ptYyF\pAL0xU,'ֳ\L~hMDQOk[`i*zLgf)CC_C_U,{p=Z]%u]I' q *:DZ/ql y{K/m}iFqgEEHVxxArvk8.z2Xrs`I@n^FWu,'ils] y> c'عaS[*Sω%=׍Cܧݕ;cz |Td(ި0#;82"ƹӦ҅4{0F߬ɏ_Hi78@Cu*TNޥ!J~fu(P>zXp!.G `mmAwф%t΍6ݑfWV|!Ţg/pG^c\:㴉!-8p pgb 3 Vںr]X?*ݎh<dX3j~xIc? sG``F<-ٮ}~cp\l.7&Ə8tFyQ*iseb >2t+ 9!Fl_q/݋F~pE}lI4i)Ii^r=Ds pd@pnj1to$#.+2]"+78 Lh h9eː-eū?xz7s'x87r,#9F۲\dzOt҃(թutyvON\>鞰?r+6X@ghCR6C uhE'7p>F}mpfׅމ6ES~久Wq>X4.?x͒_m`{>xxXƚ~OO}r[?=_ %fm̝īʶgM,ÇU5IO#ᴑv3xO>` w,U1܋(Q]n3+_p9"㖏g^`Ǭ5SLD!Wd`c=ԞNP>-^}:KUIOE?%])1bZEXFAI{v=)ke<J7',tt \[`@- W`RQ Μeyg>e9_0|V>E #1:!_I 98xBH3Ğ/ J|{n譪eXΊy(Ӂܠ Y:N?q+1Gn IDAT[7C.\EzT\{e$B\< eΞ~25R/^{(w3eɐgIJݯL -o+DN*ux΁'~zه?+9TfSß>hdtI7Rć^JS I][%iB%+o3F_gljF0݋ ph5c*h]H3~ֵ{ ^s hqU`$Jpl:XmgTlS{~3YYMzAX-ePG?7:CÐyl򾶍0bɛw`F,aurt+33d 2~g_i>3~+K]s@RSXѻ Ãֿ2hSǒ7lETa N:ɵi'6ͦ2F^N'xV?/7jwQ]3NΆ0h~vF8`2ۋѦ15ƷnC8Z>bmtX aճ9pÇ}K8h=6A}۞f^Yƫt?Ǡ<2om; N]r^K}.I>Ϻjߥ=i_5sA0#>Q1 T(#Iۈ< v 8fu+Qkiuz+<渙5`6O2r` 3^`UkuŌFf{;h|pWڐL/NN|o̍Ouߣ-d[ฤs>?>#U 0i@0kf8k(~s7+i<[&2O\n0As<o/ (^}LY$'݆CM_Eg,/Ӿ%d ]xwy_{8omrlj-F8tk /YiWz?6,Ơp. X٣H;;X(rv<Xt:}<`i9+Z}"٘|7oȼvMrϾ\iW2㥙-ۻ9% Z0{.ֶeu*/ ǁUB)g:jZX6 89L}͂.v4P-cVM%I}I@%Hx/F;AR.޴Z͆>x82"z^x' @^{& ģ FF5KoI|tgTfcDtQsHNgH'ΰ?l_9?8:t6\q\ cKc=2OߔP~s}SWqf._7Jg~of}؇c?Krܣ 7&]jЕFfZs Q=p;?_֟mw%9S`st[Ljm2X`ңn Hw-*߷SR6BV3r1_ʘzxOG { V]unjazxπ]f%Ѧm>9?`-JakL-/8.#=gr2~nO$h7r;S<^lj &ӓ̡2)r jW޾[m!qv>7Fquj/ N@oD!瀭Qx=>gP*wH0^r-{(| ދ,}[δd7ل{X0ΑNU'c eX.x{a_أth8bV[Q9 O{w@>’)}a$oM3N >o FP2dM ssV)an=q>zzU;E_@ mAlG5.8EfǙ&Qí4lO͇x/=Ү'c (eJt̡o2MoH3Z>|T]N_^ 8kg xd~$%bh Z>x=Fmуdj]_EίdzQ[cOnлO{T8^{N&+|tl/K>d5vIGEo/#pE)-3;rzIp_(bx`NAå,i_lsK>6n c {̟N#=L.^}}a  OS/}ӫ-;evGD>Ng rBlư/͈=MT0`8MK@"@s1{x,hN b-HpR`+ ?~Pü,)ʘdHt'헩{p:#S$chILJS1a22 "m)#;>牾~'uoD8'~Iؿ}PQHreog[/mpv3 Ka1RUhC;9 fYֵOB:|FA#nct?PϨ;n$XF$ ֪u,5G0+tel9F|?h磂[~ZN4}c8+k GYSGY*fa|ި1ÂO^8 &#QM3$q?3d৯L!MWȇBi{Ǚ{q}_Ħwq3&kpެhi_;Qv]ނ1~LHQ7|"1֔e$;iyy4 ޳){<MuڊJNj8^zVoFA8cYB#Nw@3ʠ<\a j8%^]?0y?Ex^7/>q.W_s)l;sdRsSx8L9sȭGY 2^b_w8m 8%De;G+0R8Q/h]g[U$/w4ʩ?ĕ3lM$mTXUU3l|dx,r5Kp[}x<ɑl%Lne 4{t~08|ղ?!y@38~+Bȿ4p-x5c#xTvcfm_3K^ ) S?/4)Yʳ) nt4*=8=0\r{@u@y/Ň;hW Ɨyxo2縲| :/e7Io o^;^%P!#W;CcilH#|Gi:&wtfCWmqeEVSB[Wp//P{c38ХN fgK$}Gvw[&no,I4A'mƑ6yOv@U 'фa~?u6J}D2>vߵHAA~mBu1X|8ʁhv?:aJ41;$'5ݻ,<|2*guZlQgrrS'PCsQ0v.IVz΁y:õeP.FsUMգ9tѼ1@T pzH3+Õ7'g^o&SI t:ݸy#̨E`ssiѱ=̧Ё[b63z4Q4bz<'? Ww7?BkqsVr933B 8_6#H4QrA3f,^SyR aӔ=6B2.![Ǒ]ch ?5A,=C}ԭhr3zh4+8'7ެOsvNVcSSV׫M']Za'p՟r-eqd J8]]3{ 5 cR?O0A~#9. z>_|ԒtI`@i%sgH𪺲C:\|;wlS],d%"oW #2>VvfOw_+wf`楗.wB9f7:{mDg!s>0n i`kN>߸zor(zzS:%;{eH_DpN >w|ՓF?>AۚgY>5ye3q#0觺C UBN6_ɽ.^BuuiO|"ḍb*z=B*J,(iӑcr*mϔvQsh2^GY_͂d{K_>!uhףfRA-*q77#}{WৼtQ&=)p=DYᗟ[om:s`(1MEgƄڷ>7kCK+9ςxMoƓ$韼ùzF۰p@oTlCK|P\m&`H>hÏU_] h ]dz<>#-4]~+^&[||7Г[2h3E#\@{V4]ڐ5rk: S9!㾈Nsv0<2]h^JDG 4" tpcc|BnW 3k/P aD@ئsdᏻ52<'@"rRեaIqJ.Cb[FqG`Wg&yJ)m5wou?~8))cu2){/Ӈ꒰3FӅ-`p^ܴi1;ݬy ُQ_ @4ϑ?22ԽKǣh 7>h>xw($.?]uF.mv{C6qú.'Kov]XI]' /r4f)gyPzFVfޟo4) } a<]7[pz<l!Ill XFpL)Y M.M`o|3/wz^Wpt?13 !N2̬\>||~ Q'v ҽ7d*ɵh?oC[>y[:32;5.]﬽ҮiOP3/]ؗӇICz5ɇ="^+XvS/2Q8GKNԃo[ݿUP]|\XWG!&c'~"\x|n8Sχxe"(}6*@խNتft U jֈ*{>MWyJoOt-Q)0Iipq j"<Z B#q0l5pWZAy7M ϺxU֪QHmRNK*r഑]xa:;1P]е/ȢEUpC!<,ÞSahxVף Fk?~UGf<~ cRu~@pcϞo}/؈^ %9fo#uMگ_C/ů?B"ձT?n]yrFNy7,Uަxbf/8jzťݝt6b/ebFo>ƘqY`Ѕ1P#O{~b-w^h )>u@O_|)hd5܎HSmqL'9 dw $=ҪgDsZ IDATi ocLog]7_dݚ{1gOX"1l?ǫ\tX kXSIR{L?/қb_Ӟ)o$(v TdU.rl49`;NgeKxJ NY9s%w)4pD6T!W&=[YO B#:]q !9 6Ǥ=;J21p'`|\ cܖ o_lZ}`.Q}Viuqޏʏ?Y:^%GL`WZ[ݔncK{3Ҿz݂گ^L@&ˤhEK yиsTWK 3ZAآ(.]9X}a꒏Z!;_TW^z|Sҕr9=\:4G1U>Op8uvZ| r/w:GE|d/"d#Bg$g,_m3,&XVNiC"LhPO?Azi (^r=%0x=:0^7%#i- %ȯPhFnt[nlԨ83J;#. ,{ ^|{//.gSn\7??xF!7 zwq7I?sqGEs_0RO/ό9tE# ߙS'yбfL/GK;n}#.덷^x=Q+9F5=t\ gߵQ5'ц}m>u+Ktbآ48}_\R2L^8/4؈wzdRvW'!4#vAK.~]o u|x`nGR)&Ui>w[gS뗑}_e)w VF z=؛֎gh7h׾+4+TX3oTc[:<Fj%Dr8a/G9jBǛ2*yn)j<+ \gcz>;ҌWg9NpهsC'H}]F:lFx_n[aC|EMDz~oH@͔~4 pe2wY `ڔ/~!}{-+cyEӍڰupᣝoq{?.8>Fq?s[? a@aMwС]ϡ[ 8'9SW^9|99# }9/V!@޺4j Ͽ[ d~mUߵ)8pXǗ{G^aSw&>\}p ,kzvVx:` ij$yGHOHwm:8/Wo\}SQ/J7HJs-XH̑ҷ"Ac6pwoñޯJ2I*tpՑq,Q`v no zˍ1sOBiKW8Eo]>)b_(`1xv=z%>g}L{FO:t+__l ѱUcEʡ\W+-` іO,YȣX{GxoO~wE Z ~pDpN]mȷB?n%`@Vȁ5RhJ:q)=N_|M1{>nD~B9x!$}  L#% ^1E+8:Yo듼 5]Z1 kSgcDx8xU9?:3.vYϯx΁{D^j*.M!(]FI9v:0¨Ovɿ4tۇK$3)O!έܳ/ ˂Z)mx3gD0pzw6p]Џ>Fu=P߰A(]M.0]_9'պ[?ET>kӴ϶x0p‘ni|Sp=f_oF|\jƪؾэI9F:DwuȬ%h93"oT ^Hwܪ+ 's&N.x|h% >jf'7#LjvGF8h9Hg6 LʪG#c}iM6m}{>z~Y^;G p}x3 Dzni8(ʎ]d/Wq{8'u-!س>).~#Ay|ȿWj8^&Ly^SVFzyC{gxRbC'FFOj(_؍4Ijϒ6w;sܬ3q~5o{So5z;pUϾ }_`2F|4jPj<ϵ͜luGwp FLG}-xH]7wel~OmTv֨(Zkzb! LjI-x RfG{E{M>u77K6+hm/88W 挷dxa A`*Č~swLb B)6PkW;T?^hn׃S``:XR_Dþ^Z;ǑV^ ud^?J~Ah9ͼY >ŋ>;_i lx vGk(Z t-9 Շ(Iiyjѽ`T.ݥh&wd|\PxB8PMv|bnQȶ0RC22/ }oImz_}0=LENnN2nqO:B!lDhSG!JeOd@r ̤0'cGf* 1 ڈUctr96n% ^p@׹!&pR$~ί#;-5''4h0!Lh}Gi4zOK^zd<^?U?ӎ8|<hqvXBSݽr7S@IwLi -p} [4Z1e,(z% SKL^n̈gn`V1;ՌɷuDZrΑ LHT>_n{0MN3>L¿/i_ e|v [޺G`r!ڋ}d+f/=s,j:,y8ߜ9z6zs97Ǩ[m`/pQFͶH@C53Y5'/#FK2}$ZGʹ~~k'ޟIA=?J1ۯA3&G;o^l/]nNّ3C0'[/XwC:o':`s?ۦy_xu낛= Pw ӟ39 v7J]|1<[Bt#}:|W7 >kGhڰ>ZrЇ`~S;lK}=)4ZKx>3zt[nw}zR*O:Zk>]c f+t]Tǻ#_:u'&9TF"K9Fn?ȸtrz6]kt_u7xP}ݨEF9hASmFw C‘A(hat)@8`Ht֛/F(b`<>ߑxƍzfT2Dm<sH3߫p2=1{}XL9;_>P.Lx0Hf3F$+f[p/VѩA%"W$#Jưཱུ/]O5?2Cd"Ux%cOo9Y{e q[[p\sN+W'`njcy]_ˉvE ʒfu(Zϒqzp;w;ro8kI㮵<3H|˔龕{uQ<fEٞm 3gpWDGLӘ^h"Fvç†Ohvit?$}j77a^ Qk;__1cmE| uAJM7HQpN\;8lj0goMx(Qy^7u;v|یsF"7{WH:\K ^^FQg O 4Dxd)Ǎj{pij`;<W'l Y:-LZ `d~-8~[oݯ,+3:?ŋl/^ GgȄzs`FC_]f dRfkDKs-6', v-;8og9|rf0B9zv>j)4'[ }y~ܠ䥄m{cu)`f0W8I#BQT)wto8^^%6#=N)6f #Wnƿ~ WBɹ.Ff~'}KҪRXhAΨ Q2{*ci{B\먊2s(!ri{}8 Zq]X3}5NeωUN+ QRZ%M*<,)6P\K cW:n`q~{~pw;_:#NCT8cAģ'2@;3{cPĉTFwx ]V"\1ƇΤ[]-#5F f4㓆օ`|-￟}[^|K?{A/nݾՔf2 w޾x\|7œ?W'8>/~^c?c{Otmm?o|,_^/CϞKkqҗ4>k~=%kJP}J6! 8TL}PQƂA:f0j߱N Mgפ'ťki!S)r1&xCPc8x(}FG)ӕ=72/~Qhe<92n4~GA&A?ˏ(ً動⃎cWсmfi.i+Frмr?gO?\Oumoƾm{mt%XF]=x 3xz v_|}%;1}ӗ+vtr8uaĮp>=ôhn O6+ni)Xz;'g=1 vwbAILC&U 9]j_flm XxFg]nwnz.Sk͹%KY(ohKk'Zݛ8Op_2`94\滵iBں1 A,$C̲Q pz=.0d^ܩczF,Z'c76#lƟmk0MVFpP;ŸC0sŹhr@W'r+8=͹ zmOV[<7-HnJuz%] N TFsf|Tv4vţ٭Ҍ ȲYt_NKV b 7e=|&GrA7 tM -o$ tx0ǹ&QRG/QGJ;:BZ>bKuWp%̀ڌ@xऍU.xh -(įufAl˶JL^v< VU?xtmǡNtz >hsN`|0~~%g22!7|:A[eޏ6T0aĜU<1XN|(?n]YuJtawȮ6RNj/6P^vGX$0ߵHoNU5`+p4_EH7%Dᗫ]9dp黉xH/?s]If4yĥ[#C5`a>ʂh= ;tCqy%u;nӁޯ}#xLbQCщ4g<:Ltl x>;S IDATqnaLJQ2XG0Cn,F scfU){'dntS+Cɴ6tz t_n*`$C5:ny rySws> ]5ZFn=+}@(EO}eG3Eϐ}rO|{{.~'r'py 9|@zvk}Vs~6#1[DL~rGvtgm*M>~;@PRziz/ӧKŔČ㤜uMn[>}52+a؈2T'cA1uqq8_j@9giJ`h+#sV8<єjFݴhy݇MU}PPk>N%p}S9Kﷄ̘$$#/0ҷmgDñf&X]azxZ~V]Iq1k62BބߥL"\+[zoMۯYl. AL$Ɩg= MSG nMTW?ڈڥy'h]p~zx|PEczApW;zj5/GVNR Lx1~JRޛBepU6 ‗'*Q!Feo9._O]Yo/J)G;@dI#p:=F'' kxӳ]o;Z7|#|}H^{?Z ૎@gpRc2xЎgrm^z饋_7޸_.~/%߿t}oeыOMro(e$Z7$<Ϳ7_Oom_k~>K~Ν.~ٳ?s$ܻU',uza_߉.ae7f٧e Ml.y{Kk أ4Q` F};ZoJz7]~6 -J/H!~/GTAO0o$kCo]"#']b*'c^ {w4f>~3xhj72?g ;ZƮފlʯFQፀt|isN3.z]0co 1#z>8#"TXLm?hF+͜Rqicì x`1}J3LѫlLld,h> q7+f4-Gň{f<0m|Ʀ=e1ٮpdoJMc3ԗ8DĠ~kY婋/;{yFQCp$᳀@%3P{/#+ɒ) n^7!G3LgsztV7զ_{ K;2m,rkZ͢X%pPs ]Z؝nd꠼h:h*Np[sd6|"5YY 3Z~qd*h(3&@dNtQZ?X'=ŦE|Ө2`7k(PIx?}-soof0 :BBufJT:-+ٔ!}Xk_ʽ½wM񃥝gօ%߽n#ya: 6LJ_i %*;9 xyTzt˸J(},Ė+M_O Ov4J;IƂ/EG~nq*p2z#L, !n:.E̿T=u,u6@пѐ$ҧQ?UzjP>LTv'kIaKxfUrP!ϕ27>adC_a^_P6l7$4xe `D/?d#;H"HUh~ kZe3o7dkyᅧNY7:m; vsc*pc9ϻ㊸zBztm*{yqHO9LGxq*s9Qr}Q$n wʇ`Ǽ*ݳhӍ׈F^xt,u辴 5@ZsG2VTe5_Ǎ_?<@|&otQ_SVn)'56tOYܾOe=ZO~jNG>؂sߖ9XܜF!w#Tq}<{ݷb+~!??lG[?G~J:YS߮|ϻ{m-o;w\wRF).;⻿F'z΁5t v"sN蝧uڴ%D-Q2S Y^ hҳ#o@,}}M x7]99`D{yN3m;gFe1׹ ޮ/-FOBQa/c0=Ng1Z8ΣMk%[6m8(n{m4Q[sg| .t7^1y8v.c/h W nj p} *fc1Gg w.f&@zUONF0Z?猢889ش)츂 SfWaU'bU>a]=C{}8Z=ΒO0%|02Dsu/}\N(Bn%]VOM]Uz0> fv˰C;3zzA/eLJkCisK3|ڎkkk=#_OԋǮ[m@<{_.x""Vn \os(p:mzLLO[]4L}S ]!sCu¾WdPcW*׈*a }>qKǀ8yN"B+y$#_~}St,ms+6Ҳ(T>~0M36 4S6CzbjcFUXr*8WJ37bM )xXzڟz`PoiʫWg_='03Ge#ǴmƦtע#ms<WLSONcx[/H3^{F3¶VhY9NUөl~i7ƇsyZrOYef 8 ubAZtA9geOPY ,h^CRֹJۍ2 }lY|/ՃKis0Y%hJTRs>zWl}Ç,^_' `LܜDhڕ}6[|sٿHۥ=ͭX°1{&7gBv=|M=iVxrx;N=bQW 7W6kĔ9kF_=1t8`sW6:LS7{M}6j)Ud vЁtFWu_9pm]oWo~\.h5^kNWb~v7v@ CƝSu2wz\21`2+":>01sd)9| f(*|\t0(8F/O~+2u3V-ˬʙ槃tXeC7d^+(_zt |oTfYʣ8F?T*UG^\2f5A񓣄I7S6=[ b򇥏FAlYu{>ͮQ 8Fҵ5>I7f ^*9yݱ_i"x) ]h`Nk_*CkF('kX:@-=CĔ́JR:͓Rȸi5h/!GHt~9OZ]!hx{weP-W78qx<O KK֘7^>5sV,i/oxxhJۘ8/]< yy.o*% 1"E\]m-őgy^a?jF$X]H$@h`һTÜc_BvßAcvt^#'Lbp>wk>9;/ab KxZ߾=ҷħmXc7z4ګ6@: t{yg2n}/Opvƀ4A;l9Q)P8khto!÷2tCx|϶~ͩCGas2%&ς^Or0'](`-+@bCqu_.f81$Gs/*eu# o# AO'RsTyP˙,^uG pS2@h9l^,|e~7߸1|W7ǜ"d@,';sǦy!qVOq2:FU_' F>)6 VÚd~L"sH> ܟ.*Ci9ܩvJ>OAQyz46(s z-?0ǟ kըՅa?'9A_͙xQشKWI'3J̍$ɋµ14=&pC-}K5yVygMG]T_=pͼ#OzhGR9uo~Y_t9-#X\5h](HmT彎ݓL?{%oXm 3mnr7tLsF4~8eKy39_j~ J dl[ ۤΐθRcNy <nj̍ 8WFY797'p2eI{K?nRmхd#LJ@o$$ea|ktj̶`DMdl?nTeHFlִl+}Oroז'd1]I_F~hJ423<=@׻StDWi5SÂxJrflv@l3ӝZi3">W:AphM =ﻖtA e#1-(U2jG }>q9\Ye ā2+MHo;~<+k30wiF^&eɄ2߱CM/ Q[P*?Q| ƣiW Or6<<z6#(6 +g:q9I+Y|s4=l|ĕOj8/% /Nl' R=oM碱{OhmN%Om4끍*l$G;.Mj{J$?H2gޯosK|Â[ omvу']_sZ^hls{'fKNC#ѿ/Xf𩯟`Fab)'o)d'bhd;\jT]3LjMBн'kGӵz'H쀇f!UFi\joD5jw脘jσ[_YrNH~262/LC)JxPk+~Ss7즬Sqh6R 8Vс8KsUћ08M|p ϣ#oTXL?3Fk9%]WڝQT:4(8]F>nTYѲY#^KF;KWdjΏE|ZSǰ8 9oF3)Ut(N¯|д9P`2`)p8'fDG j[+;%#/Wtst<ƿo.S_MD-;ܻDs4:w&_K8MO_r F7zUz2\6o8Az.ğc>_+^9 ~mI\\?.ԟS_ j38:F]jzWjÞ IVN$L 4@xFoa֏7;A (_|,O;uVre1Tù;hNw˗zQ{PaPt$:C6&ǀ7Kvx}|#Mp28o3O16̨`<=Sa]Ms(,;P3"]džQtcTFal2ld34>^FYup"~{@G>ŭc$.\N7Nevx=*?L<ݣ9-s FFtgVX[l GW bw+>gZ[6.xuh}z>paxqh^ʨƏҩ%#Pm4{k;@گ5iCB<ƿSlx?|?dovRgvJ)2u'(hN##[9#zÍ);;?OfݟrK~jrҌxL>^bnfJh]W~ ƻQ7ye_)j8~{3I+ cBwݲ:U%%`XۖZ:" iЕs42Cn;>$ЎM0H.CBpn;*eK*ծU:oUEK¾H$sc1OVq}}ZQ&[lH?f*#cFtM~c6›: v8NGYl/GB;Xe;1 R?l&:>]dƎj7Vm@7k`4ۡ=>B[J/G r=[b>liL>O7R,vїmuC{Zz s[rҊL[bd@34 3Y\eUj`7O>s4i0-iyiHWo\?NGZX5};d(b7紕 с|WCp18µ%<.21kk:KG*ӏ$\@xFD>߯ urҺʠ[Ja[w0b\ 7 Sʺ/! )i'h) E`ҧx) sMvMй?WO\/_ׁ\'ٯ^}ցʂ_+u޽?{%/o//np;g_[o]~ɹkmտzo|//mp?*+rh<ſ[u27{ِ㹳;f7=m}Y0Z}f|[X4zYmI9EKgصyX(6kANd7Veo<>'B4CWtlbos}4w:(oPl7||E5f;ap,eoej׳ebȐÇ\mi%^g91M;Z( a:N@H\!4ڧ 75Cq.G.<3pOs&ݿ-c'7,A-8+ہ|׌W>Z+8;>s$C3URVop̵r _x.u`m(MV&yדfNuQA|gе0xff^>f 3{J_fwEc2D3LmClb7̶qݥXxx6 z62Y>w92׶ n:zlI~2 [3V5vHnm8&= ]9l>4fk:ndL :K dtR濗aMO= 3y @ xRO'1PzLͻKtj58\~sdZ_mUGv Vc2x1@l:Zт.VuN/eɖ۪Ta*J6 $Z׈ \t YS Al<=6!L>7 \b6H`+:5iCo/˒opXՖ'* Zh3zmP bY'Ƚ)S߾xq&YbyBj_ 1Tܮ-ݧt@`U\)ڜCͺ!GYE(@^H]-%}_grrl!X<й"+CpR^ʹ)Ak~SzX)_tMx]o 98H MSJxoau=kD*.齮 QLn8KݻN}Ӂ7_Y߼~O[\H5Ίn@Swh;mn_{ܿ? 48o.Jl@˂sf ctkiFu/oeEϝB]}_q A<޷>>'ڳ8n5{ef\N[R.hq,fK8py=1W>N9׳vlCb `C2o{o2u3Ug13IN%_|Sl[æ3pKѶ x^~޺nAAi)x'+Ӈ{`}B̮Oo)Q|*dsVqQ}9b|'~rSjUkzV?h!Y~x`A+(f_F;%:^*g pzu{tZ>[E'r("3^꜄~E1١%u۠Qv!#Bs!p#Cc V =[Q!{M Ntl1_d T7N8p:Ai w"#2XKy:pؓչR0pVѱ;Ӿ_ꝫUyOU ?U $>oiص`ɀd]W^ )ȂR8B3b_tvNgA=x| ocWy'1k+Zp\t^ُ?h,U3F~6]fA^o7ܽ7j_tDU`RJ%Kf|ߺ{4f~F|`$ <\Q<]J4+֏6@Lϓ~hb``_~!i_@ʓѽIԗ6끁ɕǿ `"ps%8wFXӏVis¥ߊ;'=w1}i_cr<ثt]( Cf]!wkd=ouo@O0С?ETS_╦zv#hf;70@W۟'68C/_ ,kJE! )VU 秡] ]@K{ODk2r(]x<,ǐ:s^w1=,73An6F!"؅{X^^o)۶#p'2n-V 9qd|ӸCL=3 %,@C|% x"kN;߿.]lq-Mvc+}E9plE4Ds$?P@I)>[9om7ŕ/I8## oe3=Q|W5'ϡoF[r6(u9gP-܏7l܎>MFtOE̖ag9t5]I J=;I}@E{x@t\,$(X2 9^On/#**Xկ: a\}|2hh8(owzG'`^ݷ6%Ip1R au|GMe/:eUE߃Rz8#k" ,~ޠ/N-6#Ⱥz{Ey$_Ull̳Y+i[GYwܸ`-&aCC3m/&VATWoy:`:pX"`lV1 Ūb'(]9z|W˾-@@dr {/S&;6>L?5;3&i'ޔ6ﴅ`?,<oR:d9փ%7P~o Tiҷg’HNؓ yamB'^AIsn@ `ݶY+ߨ|gv,@VΡ(8y#_g*Ud"BpH䍶^.x_ AlNcNy5!}PYYp5/q)wN4/35Ăw; h(auίe@.([ V Wơ`5vpBoʸ kdƗGm.#m OI6^HQNNF$Y#߿_/~+o_Oo\}Q8Ĭez䜎4ͨ}A{ \ί_]¿`H_zBo1x}̿^ f=j:|{fsM=Od6PV(AT~i0AͽqD>h35l/~%Yr,׏^ IDATclbl,^+LKp Ax\Sg ^h<~1>ǣtp8g=)r ,ֻ͍ .7d s$ΉY0ʀ=#7"8i/]f#-rЕ}~>ZnV?+2yr1dl5c`(@iXIp AVsɰ9h {vJw Aһ!P]K0=BLFb6 Me5~+~çW^"_ '?`,H >Y$31T]e_]79]U(O Ngmw9;!B[ ' r|?3/[}/Z2~v<ޞg:->3zT8eQPHY!}Q䓾?Rrl*QzyfdV}G^Ś꧊-߽néA28u+:s@>T;+)麂/_.JǿBgl6|#BN :8U>.>A_4ԝwo_}lVc$_$Ļ_XNDa,/fc"ے>G pX@(kM.f+8BʋGʃ0Yqb[<6?*{'Gpb-6l"߶C&S;Nj[`Talu;{]CKXm[߶xl`ê=n|~7 $=kB-("tO08b`\e)loyJPcA F{M;/{nvU14s+ F>4Wg;%*exU@x F{tx. h$ S(^qǨRe LOg;&)hL*tr߽Bm)\'\e:k=;kL^]Xj.aGԣNf1dVx+LGA-7| VT<(Ѝp8敉_fcnwk1.w]~Ւ˻W/ NLCg CA';w )Zo_}[v2se1!k۔@6`0/)_ ِ7ًV 8o6;"FyQTH*)v-̩<ګ6U3-Ξwe㰄Scyf;T#;|+_174,nV9 9gP> &T8;h]l`,]}_u5gUEgs,=6khFWwq^Mx,orO_*F˜x2+:}TOJ>!yEp~[C.=>{z){շ tcNTG?1zF*#[A2'',6q= \p}XKk%V;}wyV7l$3N9$8^W t>.9D֣nJWh M4z<ʇr7'_;}`e`MG@y=-YMA3vCW-NS}A]O08v^aУt4*{lOݠ/eJg@@pׇe[ȓV5Y g`i{9 _y˫xV3_l=gm0c?[hhneJ|Y٧Nٶǎ6zL{홦F~Co<;Ԑ.sXEGT{@7  l+ϭY`~E胉6&U*pL[jd(:'CܬžEW[%EhI_y:H_@=S*+:ob|N~ѹAd7Sa)~oZ}Hul_>mQ6Wy78*Ng@XYԛ^cغs `6|6hۆ%'7lo?!ouT崅\}`ݨcr= -ahoG & @ }2TsYAG@wH[[>pR7 mG5?Du؝hae0  >GY݊@u|E +ʪ23b0`NM8 K?8e,:3޻n/~Ɇ`Jg `p%̾ ʚEA% o xSyʽi ?qߌ2tox. joQ?CO4eJ&k6',I}{=$|V:ףR@c-Pd8 +DȊi?]O >S;5mk/C',xYUNd$;>6pmS@x& YۖEoz4+ D/>)ɷ!A 0xhRޱΏHN#WSDĺqm #} fU'{mhdSG^_iIT^Xp&=v@_F.dkLNtF0*Ogg{h.p1Z Z0[lMG'Yb%uࠋԜ=(zg4߸qNƯnB Owr*7k[ѵ@_=ҍڇzG f:vlN2w (}35 ~,g?>٭8ëX $Q~ lg};4Xb`wr^ m=8/o[xD_&ޜҿx319=at߲v(Xڻ=۠Drcv{V0)Eo 3>wAO^6QQ+H1[_$R;#U45b%>C~[>ً`әZ14*.kcΘ(̎UMpGϪ Kgpܭ?B0XG .ǓIiwruuOO:ZypϓiAj}K+ر_]dV1[`pFg(xYt\-Xhz?:Es @NƧ[)Z|I'Ȧtf}o6BSr$9'i򭿬M$Al2y X猗=&^ 9GӀ%BWBYӳST!Q`p=[+o@VA~d;c3nJ Fb4FQpo͸ V8!&>j`r> F,ϑ6`7".ϵ|tVw+lͶ b_*2k>!*;vG9["\+/ten{[?xh.}],}~C4"x@:\Voy^:xI6Fp⪚]C(@^k=?BJWO6G[ew)l@pIɅ=I&QzζUإh胷n70xϝ7 і2=Z Ƴ>r63ib 5 P{ݣ&tm$nLXMaR)eQmGk'%MJ`}o?:y[MlO9IO~W?ϫG5W?{W}N~﷾qu%쐬 ):Nه߼+'׉%ZX˖qt6Vm,f _95 ȤfC+ &^3p8>,^ړ(=VrCp#=*GtI v0ع>gG0xqPfb 8WZ,EWtqFv!w:fcn)dYɵL]Z.@ BT^0ݿ/4zw;OAdw\}lo.|ͮfFrn:}7Aͦ;LK vqi~}]p;hY[v5gn"J?LN&{ C zV݂'F.`L/Pٓ~~tl; gJ%q{ǮVzH+o2`<>Qڵ4~WWNFP`1yk[C}%y7D>KDFt x^'(Ӂ`-^]`EDЂ OfW˪xG4wZiσC88ao2r`Im8mzFGkejLfE< >Xգ=ߡpSJ{ou|};b:ݩP9y{٬j&Weq!xI#gmsx ,Z |:&Xi|ה1z/\84P1|s)D\s]O~J{Z%;`f&|z:ۑ([G^G,)Nkv2sY1;h@?6;dg9,-|VgXqAr|Iv94ps5  1xl.x옕SuLy'k.eabv|{yt)qto:foBU̬q3K<f?=]w8's4'aƪɪ ™v{[媉V߼Cܽgv'fr}_K0[S_{N͇;] Fapm`Osd +ubF_Yq)ON?K_.~򍯼=K*hYPW|мѨZr[eAف^mz9=QxK:/ɑӈ~WpuY̗>iӫm5HjK`TJӶc0w,?+Y z[>~ I&NXu{>AHPNzyG (2}XCA L[t[hiž#i]2xt-LmXm F3%3W;^T`+/SM;+] 4`/O|~ފΫuVV(9+Yy 8~ʌɿ;9m3daIW%;BEz>RF٫KPJWޡtU=xg/}Z&Z>%츞A"쓺,[t2 IDAT~=I$~`G~Xl\{ ނZɆ$u&3 rs+j!Sכ9(w;Y znNbz/;2Pd_w'zQn^m % {MzIvV756@>pthg/Oc"pN+w3xE@|%9wҢ] )=NPg 9{yZȟqkAk5p]=o+9Nm^B{yõndW'sȂ}-}qRZzi@ O ʔ_(5!+ԎH;v]peZ@э3 N߫2%,0-գoNp[,~sW?s4V>_=Wwyr 年g?w(dIxFku ^?~d =Z/#Pt|^ "D\+Ks8dH X[mcm[{ }kBݠgQCpȞO_Z_k @E qsIKz&Vaoez-[`]ع+%(/U78sYɈڞdNA{_D[(4Y82 ){d4`i5eEk[3_6 ?EݓN E?uz}1_幦L'6;=+x6S_+6Tu_ӣzW΄_$[ &v`y D@ױA#hu']>hwT|7ڏL'=ffҢB\GFI'ǽzև0gfV)`}trAJZ}}*Aj NFmʣ|F{ /l'-id'oXvs ̍ll&{)تأzJq`ߩ:{7aE} R O_Y uWm֪ u[+O{GwEPzuNхIJs~=lQ3x?/^>[a g?*}!PR!f:[EPu1IJRT&\}&n|3A`'g˴Ӏd߫/%>8q/ڣ@n3(1U$mp;cTm 5xp寃cҽ_x8|ءl։cEx͘+m}QoR(_!*P{xSkw)8jF=~V85=jsY]fxlfk#n&g,h&?\=C>t9ӽ]_w˵'67Y=YtKduN0^kx' _Z4"@V-v c*3x Ga޿q?^OmA2ry ^r3dJ }%4Oؓ`P wj#;|ɸYlʇ>C@tňAmzDp$k3upd~pq3~Y<.? ?@\h &^ٹ[?W+*L*PbXǻ`AZ.&u-[*+[ 5.q4K$Gd3kudz4>[}CI% Y3B5QGëF' N'+}f.kp ^%-Y[\Ei{,+.@;HuE)2݇KڔbglT%0h .TN\U_qCrx:y)DyW~]LQ/V&s?oPʾZ@Guݔ_݇de  .gr2Ҙ$Q"W p|.?jW˥gq.|29uqg.ٷ~c8/Zoo2j ʢgڳ|w]R\^K~$ XU/ f6`nz&/lٜ9[lK.9G=4t=zԁ  ,M>U][ r: *vndѥ[t2HsՏUL??cL&LrҲ`L}:lAn9fj焛xjD&5Np,8B 6C{Șsۏ $h%/ |ˡw@e9^ׯ {' 62ZWeҿ%Xn:74r87o,>ɊٰPd?߯x[ԅxW<Um6{7 NưX@tQt5WhfP?X1%iy8}lIpZCzSa\0a3{]'*taKUOA>}v\e5 Fw}_+o7aT&]D/b;2<٫&=ϫg,ӏxGj/6A+\ςP}+NGVOuf_TZ8 mAmW$$wˑS`е09ݽB6\,3S7V%@E/k\E{ILnO.#deu'^;VIp>w ⍊?՟VV^ɒB[4{e\6BFk,X0AQ@~{?V?}$|ղP p [Vvx 'y%zVEѶ%xҼ t婕 YAxNEVT^YuN? Qg|'>y# 야U[0 gwe1b5V`Fе ;~3!؛,V~uf]vG9<,_嫲oOQۙn; xVE[y6Ҫ;ӆ|~Gm gcS4Aذ %x+l5 Vx%ʷA"$߾{d|TVd-v鉺x%i 8A6a^'aC937v]F=odS6q?;A1>؛lj&*ҋf @{ʓ]OO :lyxjVs+[^8Ϧo6q88!#gYk{r[ sށF(oN6ۍylpY|_`,PWXج- WyZ8gq>7R=ۊ`9J,_F5=3}Ne,~,~Jf噾D0hvP]UMqy0} xNg,3O,^.Ux=%k4-?sùGpVt;yꈧ;ȫܾ!{˚0}@zVdjF֌+,YE}֞<ŇU(hN7W\ݾc\6;=1.g[z.@~ AUdO^>ߣwW>pAH@]ُ>)"ldђ v%&A|cx{Gـ LT]ËTQdͅ  w@È۪)h-dAFv "O4ELӚG|и&~;O^Ef(4mte#뼾zK'~=뫏 ;4Y3VOMу nx2w&Q >z+zQ5gi[{qӳFhDsU5F2Ҧrad+@JSM/놖Y՜2F78x#t/ЛMu0w?F/j(}Eۅ_%Z/Yh&hUzDgY@f{ أ ~Mto+ ¦9F/< nS_aj*^{xֿ`N[\?f*4' [ W,+=i ?{,[>r=PCбŽyg G8۱q!G; vۏLsGL \M$K] ;jz;iNxP=݌xfJ.`VK[Ks6 4 i=r6PzL&'HEeqh=0қpsG`]o+N9eAK& t#}{gkX_Tt^nuKQ/ۛ_(/Ookꛯ_Ͷ⡺om}culG;!H,׆1C`;m WwӣO~O^m&ƖZv}_p ٽ:ܨ J>EAwYVdpV$^^$xf"8+8zUv#]8dם7흷no''y+HpE\9UW0PNW!ʝ;2Љ~MY'Om,c6ڪ6@y귿?L:k^3~?{i "@Ljrl0~:el l{땈-?8Fٖ=H7/r[.P#PI'+bsUE#A]Gm,8w5vye.VD"laf g;t\P7yL1┼m۹]ȹ R 76bk[-*xY}t>_m|2kU5>:;0` Ҿ6Xpnj TE Gozw ^/HdVD*>t I+;Ē ~`[a'㿙]}?Bg\xgS# Gi'Deb2Js7ۤ/Ao7K`["$QTM7+Z`=m+ <蚾hJcW>mykD*NJٞ6Ix]}9&JO|Ө-}o&D 8g*XmUь`G*`P&X3J=2bh>IЫA~W(T?W)@,dvtK)`Ww\\ɵ|%ޣ79X A5?+^l/7\e"7µWhz.\K?uStz-@'^[h7ζ-l< &)dls&;d8Mz4IO,V+\_PqI~ܼlfn>x';&HgTxΕ8fdr,lx]*s_>5^|w;H辙3KIme \y~/Gá#sdˑbbK'}  rv?*PlhnvAn{?Ӭ{-oYG@另 rfN: =~KE+gqziѻ?z,L fI{4ħ[L'poIj b4$,e'O2JX:=%|neuG}XIP0iP7J8 ꨢ IDAT4LG]xd '#D=%hxdp{&]zYx 78it"31ul[rL~dpf@F8kD2h: j&mQG/*:GG \Gg1;[{w4nF KN;7|}lo}m`*bW$.T*'W\k &vK?wN3hIO+v3 :Pi3%wDY-SC݀Hiځ6I.[[C:ح!d` Q"[`)P[ C>^m MzMDW?, d}F#M^y"$: g;вmT{Kt꽂}י^KSYQ:ӕ*O"kyVnnΦ n.͸gɽvnFNȈ5Z Vrapt5vϴmum Ult#|>Sdr{q~z}޻ j*>|ګ 'j9KpTo;F5#_K~X$1lzF:~ q=ulwn,+mٓr\MaoA]8ff Hfg'[~7,ʋlgh3ze6m1,plg @GW-t'&#+^fDEI-=f]̀/*ז ![8K'ӉSVэm)o0& >|W<4'q~_cU>9$_C8<9ddߓgpv!Dr7Sc.ɝ :9]Xf\8>%xE eY]o) "m5D$>ݓ'E>Wza07-:Nɡ+x̰sWH33k2ƮeP`򴏘MskVDtpɈnH#Vdq)՗s#k˅ 686h_>~3Ҟ%~TyS>IӂwÝ/#8 }=hVUx{Oqq=38`تpOEҡ3^]fW]?~ltnp4Tb0y|v,vfNTBlp861^^.H$ΆsFԑGoo9x:xef|h 8z*d'X 5ⶒ盽*~h?oEYYdn|JS_ӿ`O6@\kt D/f3ҋ`mv4!KܸcKrIOuM/i ;W;(`S~c M 2^Xdk`GvͶbٯ^z^}UxˍXۤ@1zV#%io_6,@Pj2k#!crΗ3{0 hCΰ.dh.e}䟤j%+.{|ьlflׯÖ\AX9 ; hXs  ה׃5F2}DD! S0U. F\GPɤGa>Gœs>]+%73ss.߹|WO)X*C.| oŇŋVNˣu4o6(8Z <`#pIEh9Lt=$87:]ssϾ`wճ+\~WnЀN[ڗW_F"~^K 'hdSnn?`?>}7g6}o=jFVaFvgAAڿmULE={赧/xѼ%lʱ9Mkϛ 2Nvퟭd:`==T7{YY$4(9:TsUk&֥9;~Vld :̴(yީ$^fi#]QZvwb5g_yNfT#L2,Nf`>%}uͱ <Ε\,X7? e#~ZO $mg.]wy}/W5<`@ڛ@mNw6Ü #m.x g2}fA:\ѡ.η; %?+;q#P£K]K|'dӿp񸥲^ՁWS/@W=j2d4_5yT{aY=0^z}O>OOI Xn9huD<{ؿho4`8ǟ{d/o+£2)nՊQÏz]`y;7ZcE ]҆bm:Sx5"<xVEBSp:`UfO׾w<9v+J](+1'o,,k`q[V$|Yv@-ȾC3@',8nޚ?_{-*L2l3[՟܇A{ݿ A&Xl]DO1!z@ntغ At؊/hs銷<^/S[}j<@` 704!!ň\HU]MVշ奃,6m͌~asut W';@?u0BehKNU;Ȇ(=V( TV*X;K >k5I ̩(UYEk_fô|e@X0ܗ(XQfA?޷RR9#9Ro W_d=uV;e/E , $^N`Vs9Cޞ^7`8xx 0_`OV5WLv;,?=Y%7ӓܕ֥STFgnl<{^xNweΣ/\?NTw?7y:1vG>,l`8z<c%L9'saʑ1j8{oη@eg-A9+O4Ĭfu5=Zq=Ξus/x`.r{Q|b?.>#zUa ͉I`ݹGN̹lpE\ƊDe燭̙MJ6[IWrkzs?ZOBF 93=o)W9ӂv'ӝzO{:> - {M]ʈ3\\^ꃖr^'Q:i> ՝nNx|`Uq3>J^R^vܟҖ eYÓ gf+$ Zo {!(qɖ?n\ӕ0wwJ/ũ,.P,kl9-& ZiGMwlXItK@k=޽sco]_|+H!{|u=xyk&ZB[Ojw9sgם;7s2)@Y^C՗̩?-nqv ]os7=k#~^V[#+|l_h]FZW$[nTm:#}| ;f@J?^Pf@VV3UUwGÍ욺v 2x+G >j=؂ ڔvГl4>E=,>GLFc쀎_ۗ~o Dvʆ:̕rVTTONQ9}F*YgFl=?'{,pn Az?Zpڊ/a`NuQ &&vNu9DNc P%C40TO>)uj|@ 6کJUP1~ ωa%`HꞁP|O#'zHpҼup\_g\42 փկ.56i ):w@6q?"5̞9"e[U.]Zy1 C^辦K 'h=')MR^ ZuvpVGN`P|oIc\4u@{4, zxǠ? =DvG Vu`feg<9Yd?3h\f{?R>Z*9_}p='Ogx>_ɫ',k I`f066W~g0a+[Qoxf-n+؜dW}l zN`z vL\xP}jfl0{eS>z_A hp냮;nഠM@3;]@{鳣{kl,1kGc߭ ^[֟u s1g$#6K@.8)*HTU/[,t麝7.3>7yk3E$A͂Q͉ mb UtezhvGN7yM颺Ag  `z\e愆[z~,%Zs1aÖo.6 97-烖 f8f'h{++J<'[h"[AY+Ae|5.?{ B'CGf'{e19Y)e,f/˫wZ.y-ٝ=%kmA]GNu`րޟew3sC \I[ $ n@A(ɐB $4ڴ[A15mp7؀86iWխgk%1Pfuhԁѣ\Z\'\_aZ 8:οLy]aPGKOл )<({ī\@~}tM}N% -rs5ľqe{}f3='p Sq1N0822Jl&YԐM/SpĞMK'o^Z3$ f]v>t@mA`zFa=?}f(^ߨo1cQ~c鬏3."KLJzD*7 V^ncfk3qw^u -0(t>MWIaA_ ??Cw#T=iX^kmd;Nl[fdaRb89a\I rխ-}/{|֕uz zy]Ϻ[sJ@[~Jx"3+|Wr>fLze=RuS|XK n?̹^oWW^ŵ{Nhy^/휔 o pmH^<-0R\},0\I9.sgVg<#N=y $A丌)hަUUgoMw0C9#+}tՓ.-?&yLЇ4Z2ts[n#GcO!>g!Q0 f>ts'}|b)h|mZՓ55OȸYٵGn%O;͞QѾ!*}{tMk_=Y@8hƧ ɀ//T:EWq&ri߫nѱ`vYc'[.*iOW/m&,.} ;V DGNN)e~L!3{7[`x}͐(Р\}vg6fxdŻNY[عlrS/8vЂSNmBo/ IDATʆO4 KKU AEN  c;.uF4n'\9)=@GjdžS.Px?pvƖ2xI0jrhKwt2uEltu<9u0k95F`C *xS**}IJWA2Q$iX/Up1N}TO>}?Jy.?&zH? Gg#bÛG3~[}}Ӂ;%MKS6 G6GO-Po93:Wo\` 8o4[*.9<{6̰S4Ltd]ʟнbi3NFWwѕ!Ye/cV.>zUׅ`TcQ>d B8'v73 s-y(GmM-H' ~JdԽfn8*{__3O9(ô.LnGx#v` hpGDدAUQmdp2 +}A̱/f.l:pF%F. g^uknJ yNi#44h5g1d.#opwT Xٳ|*G6^<#ώ0hFWoKRьh%m6vC vwE9#LoxPfnۖ*0;ۚp6XD~6ɏoh%<MoɁ!}Ɩ'Kt!gDY& ;FfKJhM6"K(\]G0n)W=Lnt&o7>G-LNk{?Ӈ n|ro߼ӞWWF9|uJ.bjgЕs3.O 0|%[տ! lY!7~iԫGaB㉺K:]n=Z˩^AdX]?KJ@x|d0Zj+)|Wtk0&şѶưm}ߧlH~/n)e!2x`ww[deA64dp`hSG3гD̀"i~YoZF<0!r.3?l |$P kXw%%GRSps%p#uȽc;.xF4~2gD)@h#i>A ®G71ZAмhIʅ{>u5";x>翷RkC7!@)QeFy)Fk4sФ¼KR=V4k<*mxS#<|tu`yܞ鍵?pkͤƒ.No/[G =@,m}}AQ+E;٠QOM븎p2C͛7O;!H\O8t▓ҡtFct'th9U:/Ӄ窜N|v6r]:'adf/nOg5ݛq/#| :ԠB3OF>Gkkm ^3aoQl~t!Խ͙#S273^xmʚX_2G{eu9O&9!7*)0A#lqg;9>yH8ͤ|yȐ>Uo2}t|ܜUfǕN}hB?]I_|ů_>JM` fD^|M\{{:oi@2'k::JJ˷Nf%wRxڃ=lM 6y{f0zOfYc]6Nhf|ƳM{Ԥ[wqz 60+Rw<1s::vzFwn ZmM 7"o 1>_EWWgd1$~FB 2|hx[KC cD1 ޮYE{{$s㝾F[ݗ+l3ɒԹxY*do96^y*Ifeo&J2-b( HiFwc٧ϊYQ1:oVvU}*5!Mo^ZN,nKkV8s "-gF7a޻;`AE,}+oy&ÃP6| H[z0`9e-dg@iPn{A.ulmƴF^AaIls\SG1|JD0L?QFG65'XK{&]_hsF >sx(:¯?|cmQN1w2)oOW7ouz^~oo87Wo>Oׯe}Mw'aSNǸ }i3gFT6r:9sYd(0%;XnpBHkᆕO;^ߜ~mb [sV8֤"ÿ=~=C?TT%_Ȭ,45/`ndd^~Ku3&+t +WejG+Zz0v ˹̓ڑKG3g]M+0w>x;Ǫy:"40 iྫґu"h?sJ'}<^}r32F9"{C9y9g#0^4x*`EKG<־-L랃G4v6f̜|Ѐ5MbsKY]!3 ]uv%̌LJ!k32Rkgkayѡy}t ѾO檻%T"d)߽l :5nݦN?$oYVw?|CDǦpDrML/`6B{ }_ݾP(Z$$n5! Qi.S=G 3K{r-Tm#%e ,@|*7wU-ՁzS_Y?݅ ~_p1-yЗ`LxNqQ=~N?@!m=;1 W3OG\sr'[!5i>p D^lb?t>~#껴[ dvBrge%KA#c (r1="vVN(D?ԁE_3~}G)0ED+d&&:hZ-d=bR(cm jtFV/Ek] a{~m~?< ʗ0Z}\~(N 5sȃ|FlNZqSHӡl]UKxt!yc̑]wwQ +gi9Y ؃6oo gHe+f)C brDI73 ϫk|V/9r #09cVwɎmUO_ӯ/;}|6|;SkK/q;g_}ӷ}۷C{䓼O8C(xF>D^OnRH9NVyv"K:!quPNNVLgHn#s[*Nٺ}:ý!xi]p<4=t# @ M#k&-n3mswF =޵7MCYǿ2ަ@fVF /Zo/%D\7³pSYuX.#$oܰ^_czl`g0cŀeWGmyzwl@>rMbedwe<'J N[#9*O0xSZy\Bht9XJ#>{f: 3oV9/s+^yosZN>猜ѯ'o־2Lp.N?G lTwdi6ˆʱ>?87!ZWKcrLn'Fhɢiߌu,X "9 p`e=;o6{ÜafF}unilLtz!#[%fI^{$NdBt9ͩʃL'pt"l:h=_nP/Ȧ,/Ɛ!dtܩw6#ZX6.Qs.ئi`ЮaҤ^ڳtz!(M gG=Z~D] uu=#Yÿ buO'A#;/zc t&0K]2±ʻu=W淫}3cSރ[2٤sdfܾě g 0g}`)s2Jom-{'97yj3FPhgбKoI爓5r#yFR(<8cLw,/t}3Q\_k/V&ꝫk6fDM@m%m7[]hE.ۦ.OkB}^Nrf=,[F=߻ڐKzzȱ@Lg0z?ji2g1GQpXx03.F1l,8gseKj r4q< Z52`H,ȫ~ÔCVpGKbǿ( _|w]_q?~kHl@e񓽌ȿmo1w1|w|_^S>SNLCN(?~]oo_|#{Nyav~:ſ w/`N?48B c쏝wg\:_DY| '.XOӽs>µ_<=, d]gOGyVFG>$c~S:wo6rg|g,bA]y]7_,RH0 ~0RFF/t] fSRL3ӬQ}vfA܍@E>1׌)3qȍo --901BČpk&bttjx;nǓ`r9aFLyT@?ƨcolޭXqQk.N北o{8$o4r̘`8e׏Ww*sԟ}yJG:/?A3-FQîŦ3?;"yxЈSM~Mg1x_xj'yS|yVreޓF_ خa$ȃ}N_Cάye6TM#ަF1WTZLƲ ջuiV3H/TD/ʑT|kÕrr߰ ;} s&auʓ,$xmJv`kXho·׎A)[Z3NWN٩MjʺKs/qJ勆pȴaGoO}/bhv'!U4zcC@}ȸܨ6rWlJ|u`ˆ R9}!rZ]jhyfaST^k|uGK>謭yUPL,#M a7ҍGxKtR|8k `T{C+FwoW{Vq)R׸n''.dNF!9miOoj g3wl ˞AߧNp>Is}}pt5Wm6AyvY{=M#K!nyZ5=]N \BK1f#P{H"'*_}Ӱ]9]d바 zrpR:ǟȑw 磪߃o0C(:ǏB.․G9 fPF<W9K{r`p8*ui=|5pTc$]k2snC<  rŷ\g<앣~&$9 oi ШF4#weGKgF#)lnwG9xg8+zew^B?\\ ?%X{?]=l3GAnHb\&:U]m .u.Sg j5 !\fWϏҲ">)i4s{묎Ș"/Rʏ g^O?9}w7xz׻u/uo IDATkk}VoqGi̟3;f:|ٗ}>N__z}ͧ_cFe&0!7</N>\ y.耧Bf7ǔp2tRO?\zT)w#@W,,{_tѧm(t"]i:|Tӽ۬ K(:WLsv.k3*qCا2r8osY!ۅ/CSPHP@H*g/;;3gpU,{|`KחRG+8_ AS785.huN1g|F('X}UR79yG09sA|sBr~7)?#X[k:$skfݞsW!psXP*D~ qLmSXR1.mz'$d~)/xeВPA9܇1]ɬ9YүQy9.+?uW_i_ 20ucL#ЄKxI0oWå?>ihO0>W"p)H aS LL/0 X#;ٯN#8Gs}-x3k`7\ŠZdvp)A9.t͜ʦ?uLHjuT26-Tl{Bx8L}^ze* #]}@3`1rm xenul;!WϢkW_v\S1~әÏ7p.كP8;rs|t;[3uWoFJyʑ?l8cCpēZFvcdO5ms9q?3?3E},#ׯ_Xrҍ?G_;_Ni_|qy;x܆}=W|Wl9߸eGUNfW//{D4.{r=ϔ錓zty_>{:7ճϺӁt~ECo)sSXam6>F!} L'Ooᕎۙܕ>.m`^y7[g_VP3kYMtCws_^h$#)HY^pvRe8R0&gSO! c(̖0R~nxΨw=; OytƐ l׹͜b`/#2{Է_>o?}]K2HHO~=筭?pxpbz AK7;=Fov#Z9ROY޷W,3xse޷j{]œ}bбiܚI/sT+[=p.$s1T+t!ZW%.|WlJ~@v}Od0|g\lȀ1ger"X>wQv֡8g3M?^aYevzfoI,H)iut%;*o?yK21G̏6, 3*a^j+,\瞅|}nhUf씁_`2QX@Ƈh7B8uz.PuNZݐcFKboWD<%FHmP :•3i3@WgEf>ۦ{W Ƃ1l&+Aq3& Z\Gzrj7ŸNK"ȯ 6 ܻ qY/^yڜwP2z18͙NEbʢ5ʈauB)LWz!QU˫L*r+ǻt8 FS'Z,ޓ61kӌ_tNj;yzl̜FWWg[A\C0[]}sf^ %>ֿc )?U?ZA\I:]IңpLy4`N;̞_SoxxJ,D3l fu0aok4?O:?ldHǺ~~_K~g~?_+s9|lao7}7_˧گݽ73C?wOn/`  x)=<ߨ0kq, 䧗nJ|$ȵQߋ>qr11q0o;v67уUl5n_Y^m"8;5ǡs?\O@|o^?%x;N?g쏋Ϗgk~v>Z.?~OoC_s+?~pKN}߷}KdAKLwO6`SCk2cx ~8tzJ|s7N'O:#tFSeH2tӕOt#x;~mUcVJ_%+N[:@Ӝqr^2*nAҟve;<4,gF9kI[t4fy*W 2z']cLM2j]ᑱf ?tc83hgϙcQl6׏\*QEXЋ:Ҥw_f.ޗG lg.m>fl>ו /7+6xFyrFex>{>|l[92sR^`pwb)3DF|N8hިQI6 %o+?6LJzF+mU:@COg&pQX Xx~XIA} ᐘث8l }ev`9uB} _E~F<7C=_7N_ӷt[__--pg'.n?g~{WGNGpM?|K/||tN]uk >տz_+_K~ɂg}g>S?uiks"9:GH>y?ӕAMhmޗNp)+q~#} ._qh[\j$Ba=)8b1Fɧwt վmn3/mH?Wͣz_lnÍ< g?oCcH}+c,#G^`9ܷY %+QNEs;^SFύ¯sr7356@M?#z3|(6=8EY 2WɟY lNn g?/vꟼ]:aYl9}8@yI-w 'Ni=6H) &lzws{{>yBxG9'} tB h9di%UT]F Kmsz"H l۔~S9'9ɝ6NhVKV75$3J]*NJX3&䭀P:~Ϊ^=On8Qi6&\w,_;YW^z 2“4Uګ}>b{㌮C ;.vz^f9Lja9@BYfl_`s9/>u3I.$\ Dx?]1*y q/yMC$b!oY|q7Rd4PYqSzIn$}=c.P0}/FWEMQ*yxSQᵤ'xXy\ֿD >#}$>mfe?l"gh\C83ТYWN4*e1'`˟R/6rGwl:E68x1|`'khkQ+oA3)-30:9;1Oz\/xir Ọ)`9>Vx 5x])@ ywaN} ,G0'rJ)uYPz&gi([m}7?v|;; IDATڳf|\^ Pc3?ǧʯ&|6-巜~ommkIIs{Q?'ğ8W_r]__߿˿Od)Nx6>t 480.8FPF tKQ>4#7L-MǕ9TLd@ 8X3jwMP5G\yޡ>Qb1D'O2 +O? 7Q#~w#W0r]~BGA2IF p+E?8j ;Fi8lvx%(vW?kqzsx2!m0_x" UG nGrKFﴣ4rW\z*(vp8WO/vh AWUڼS[W|$܃pߖ@=G9 .Y҅n _-YPNH}ZcNju|4УfvGro&o'?x?Yp0|ylCʀ/TԬ.*+Y|c5m&!;5mF+b9C< R ՟ dA#R.v-M͂şfL,}ϝ@"r/l}k/Gk#LI~3[._2ì&ȓrt:"=tc7\ha8 H:~ y=_-P@fukAP{Ff?3ԩ>{Wnt!{K:Z=Iu]i.9Vqx sV ƺns<4r8dS p>WnNhUDL|*̀SxHɇ0bZUZϯ𞦭2 J[G0P;%Bxc#4S P vw%UzxƏ4⾣0/@t2%*XУR ?ц!@$4))eP EcOFQhT7.[m,5d~STcB q$xg3hk=HرD:h vJ8nj\i!40(YMmF]oK vƸOF*0DYUKv/ =f{TSs߸޴nj-}Z1b hPux[C7UTE!5+iS3XIpypWQ~zsۛ^?]/Ot}ZF%8޳`*8g{^xM&_w+gxMwʶW7JuћF=G`ئVe̓@or"g^kYdY&+v3 ✗h8]łMρkW'F{t|E·jiUБnVΙ6Qx% ahi)2Gg43D<" *qZ_n݃9Hp?{VWvF8s'|9MNle=9Þ3юkQ3:69|U[Kh;33v`Ar\umUM4cs:(3T3a缔z:}c$=Ɖ>[}X94ڀ2+dW Fnjb+KŶ/ѼnǨlyrk"F|^6 8׽(Vf=s,_sx5u^9>}dlNEFФu,9 Acߑ0S)E,<|L->ֻȓ@ˣB=lQk>?% n}K_㿿M`O}x| ώD|PB{qb҇vl}C\ڄt ~z32^O%'o6Nd{D#PGUYm(}N)Zv Ǫق>Ff (?'Crn~JKjw LY0Kw^BLȍ*Y~λ7r^lݛ[F_i;]?ouKź5@oViNdD+唭хӕ}r}Pnz!h6ep毲Bce2$ꐺ_ !Daejz j:эpXP auotWUbσfzqK ;1c5ɖ[F臣 }tLxa e Pˠ \C@@yGK(28]n&]ޤ3.ڔ"|pC䶜 8sVų".?RkZ^-QhԏGf:>y[YG#. 7%| x?9" '>03 ߡ h 3!x?1d@ܟsS·{gJ<*l9CJM+eWN\sxẖA2K=t09IuQK뷃V}è~/5kP^3"Qٿw:XH{|-Y!&~qr_zN<VQwNE6Vf/ͽW1ԕ]̉143bb핌viϡp51?+[L#g8w;oyY` 6 '7e^-2t4mu`nw5vn9ǮʿQp l,vi#ڇ]u- (ݳDԧ:`lNqz|Å_tcύ60-#galtJ N&2C npB筜F2˷[هvrvh7p [e (ٗM+O;w?WSf{} j$M3+x%䖔V7Q]M?G}ko}[W~K\r?8^8c᪟+M7#"g#ZII Yݠ]5z2 {/GA֝ P>-۰! bUr]jV#*J B?|V7u?ɩY ;;]t}4(TPyDe_4uL1k.Y9t:‹M1l«ž _*<GזmTȖZ$ڙrup4CcJTԞ)vk/euN)q'X=<ſ&{/xodx#FJ{~X7Ç:GñĔFu.1q1Pǰ de n=#Tvݡ#3`o #y_ꄁpJOwo|hZ$fx<һ?%E4~p?F+f*I[MIu]qcg䐇bLO~A骓Xn庇[Z^1ܕXUUB8cFQ.uzei&h3;\ymq- [As3Y`ӁdS;w6 dx=[QxTZx/Dzۛwi܌ ')6/Jvܗ]uw!ly?fih8 "I^|0ɉ:y| |=ىvܵ@Rri+~ؑ[}VKn0~ر@2F.ֆ/,8 o_$N?NROg=Sqll pfTPѿX?"Q!ƍOډ|7mDڭK_ `N}&uB\Qk| `, y/(=9ƫpY #y9&ڐutxm<p.Z69r?ّ( ?1sPAc%Nn-#{2[;WM'EȠrlxYNu z^;'9#^yXOՍm;XNvEW4[Us=zQU%6oQzKϾ=%w}FSշ̾>"1qN*c_ZY ρ%\}C2=K1FiS[U҅FI(nEsp:l?pb0XF!G @3gVV}`ф'IƒHȞ)E}+E'9О3O ~ i{}]9 =O[}~k m'N1R`

d^gH1w? ZlZo>/kM]b~5OJr>%[c-K G^WڛMկYMQu%kzj6H\&, b۴As~O$/>)1??0xiE0 4f$Wvߙ#2"SWȰer߈<̚l?&!ѭ7 j{ؒpC%ɑ?JV6yz`I|J5w!٭I4OB7Ҳ< a$dw<@3I@/Ev |H:PX3w.@1:Q u\ugڶ\9͆U3mMnof.fᑖ@2^/CWϥwJATDhIvEg'C+[ L4ɻk K/$43ao.L&yP /qR1ąYo3PR|Kk.CT-R#+ސL׮Ϛ|Ma//7&sqӧle;oz0mSIv,}߳$g8i~1]JU2ߟLgC[X[$++ !uAEU^)3fAG@Йu.ժVf͹z-2sU0y~L>rJ<"5sMrtl_1%Ǎ.b51 {NNCM>˼@cqϰa >6s駟 [sby Jp]Pȼ+d-6Q&>Deyf+. @ @=授>t!O|T.@~wHܵjז;{NL%o_MM}DP=ץvH3aef̈7t+i`ƩNnf`gaw펥m`ER7 /Kn}c?4~ L>Ƒ$/X@(z\EwxDSP]چ.ZBI3BKS1-Z/Y5F 6ٔۋox$$._qh l'y΂@(z1&m %7G#' ul{#M>;# 0@@@?@TIENDB`pacemaker-master/doc/Clusters_from_Scratch/en-US/images/f-13.4-partition-overview.png000066400000000000000000005274461217637305600307630ustar00rootroot00000000000000PNG  IHDR i1 iCCPICC ProfilexXgPMX`w9%眓sFrPQHV""HT  |﫺nW3==sByOtt8n{o& |~hw^ydOEƲ~ѱ`ƣagƃ8<}89Dc K}`(!`{6F:""j_1? =}|~QH\tO߇[DxliH?YiEyXڮc!ngX -Ͱ0{L _|l?v;4 ~8a4 *zX[>AD2AT4K= QLY@* 6!B$ qB($)Bd YA; AP<eAPTBU&tAF  /B !PG#,N/D"FD!{aK,b D$R)TG"m{Xd2YC!Y2 P2(-凊Ae*PMsjMBКhs:A/o/tO ÆǨa0PL*8sӋyǬaXNVk`˱wcX:vGq&Ha\)׃-6xQ&OƟ7Ot&L'hLBO"|'BD =1xXFB$1P$ <N2422L0|'Hb$=^IR3>iHee4ggڵڳ:::tfuu}tt ][ԗտ@ aa(hĘbl\a=HkcNlΫZGC 96['?Q|~iqN((;s2)S5ȂB¦"rQJiy?J *=C8f̪\|"eA*ܪjg>ruimGX]i=>~a \/l7F6694=hVknni9Պhop%K]m2m._W|}u嵾E۫nPou@]]nZqKVmەwX!dMݻ|/|n_<0o?ڃ4n>R9:X'*Ontw,+!vw'VNn` )Ei2%R3\e r%sZv_PXDy M -J*.i3l~5!7";b:cbntG |ǧU=> %Ň ?|"8my9 Wү&hMONθ72 7Kbb>Y&~Ҽ v|8ٲm? r qtEQ ht3F3݇N $hf-2*JZ{ZktJtO08aX`tƸʤٴŲf5gpӠ+uWپYo!o BVPdpUpF8-5XTGb,ρD$䒔}ά<ܙ5rSű/8~ĭN-"aP+v( ->S]v^HD\5~vtx.nnm^jt Uk%ڥnvwv޴v!NaOݾ{=Pwx3P8xihc ƺ}:kfZqm썹y ߖt?nYs j7u~15g@ ! (MQxF!QZ ]!b0o.8g#Db!y"S(6sY|bCyOMaN%3_BrUr+s? EO%)#T+l$ +*#L,^]-")E%!#$J@J'?pTLAiTX]_uAM=^CCQsUk|O]'=i}Aa1;63SsVyk\ulmv+o`\RZV^G~oyр `carVtvL]쭸 'RRoO?w0Pdfa,l#9zG5)K?!~RJ~]Q%JY)gЪʯ^VΥ>yz#oKܗn\A^uvxÿAͬ=^˾'=&?5;O}b9k1 @)\py S%Cv$xL@ _+@dC"HGd9r%:E3mq4bNK8<.ׇ kD^b.q!ɘ(XDecS˔`"5%;k2`gfoPtĕMny B5BZBEEzD}b-4@k('% d؛˦ʽTpVdVQ*TvRTyڢ1٢BS{BL]OoI1ɢٸ )E_6,vŎ.ܮnWNYhY◈O_YXH5ud{l@ː h!鎬AQD}4탾g{1Wx.[TBaEc`#n13v1i2Y0ّ% `вp(BC,D\P|V*+V򐔀Ԁt 9[rEK*e_ߪj!ښ̚Z={JuTuzmG Md9LP&V̿XYnYclm-<]nθ#JxX{yU{1 ಐa#Q)+qf ]IeLiYF?Wc'NvΟN*VwUU:\Xl( lbb׶k;:oR=ۓK7|?G O`610B« 7w?M;^޻ht/.+W}qwۺІݯg7_f#퓡eD\I@C9w0ژ{XK. Wt KǘdLb 7SҨ, p'^psvp>s7/[QBHWX]DETYLI\f(-)!&(ɑU+ijkQOD ^ÏT S_\V'Q6vfnNG\\Ϲ;1}n?o_0|ʫ'1E F)D7݈7Mx䑼(;$ٝe=v5bœO. <<Quxt-|E#wSmPk%Ͷ+.WG\va\?7x>(2T4xd l3/S_|4mlJmZt2+Ec ŧKe>}TlՕV_'=ڏkkQks?>\W]`Hݠ2wMͩ-խ[sǶ'ߵ\n\~.ͺz8ـJo?fRvQnbޥ|^ pHYs   IDATx ]E7~^$} .j@YqQgdt ~.ç7:fe#NTdW!J}#$;Nz_wgUVֽV{KJEO-JCb92@F #d2p PCCkѣ-aqZ\booGFF #d2@F #`"MMMF \ӓd2@F #dNt`B=^WڱcDzcl+#dtzC~aܹs@F #NnjQ<Cɖ-[z 3fq'&Lf Z>lJ ԩSog',Tjg??3WBps5׸$8ns#X8+Vwܡ1;we˖i4 8(6N9zSN4A]sͻKmr@4eojl@gzF #8XfuQ:o"1^criɘ1czL8`N-#df4 UnyGuӧ,,` l޼YgE8#QF h6WZ3˴iM&&NP;P{7oQh?>N Yem%?@fd2~%TDt5LRgΜ%K4x&K r"-ݻdIO(Gk)GVmIrɅ=ɩ@F #q2*pXzɇ} mmmK{[[[f`MD v-6k,wwɓ'RY@69pڴi*(X"P_'N}ڥ f,ˮ _$'MѣFi(?*+3utʶe,7Hh:G9Ms @awɽrm3JƎjv鐻?% VrY5TTJR)ʜɗ.?A9b{X9@F #__}ɶm䤓N>2W91_/pVK|9q?.z!g@֯_r(< bƋ u @aڵ:hMV:}xV[U&-IlnذA&MyOΚNcR@gzF #x* оG߾K.~2_=(w]Z&Oh1d f 1t+k&{.>Yb/w 6Lof+_FYc[:d2#ooڴI9]}s9`vB"7:,t2φ;!Apv,z1`trRSɖ mr`aϞ='}G|0 L!Ciyd'vHS+ҷn%].MuhƗa VJOp쾅?V;;;;q s%2{hu(CF # 3\m4g#w✭}h}t4M5$5BC#(,,_K|W>bB'n*~zCtF #x!+[lo5r؂cg6,:gP2@F``+^^;R>mMگ=l*vwIK/0ej,.|kYߐQSQ^}Ld2aG&[Q$pcol q s>Pν;=; ]&z6sPCY fsر*J > CTd2O1\s2ͣqoډ:4e筇uxk › !Mϯa֣l2Lȗ)Ie5,9µ\Cީgu`w s6|i,6 `} Kkǁ߃s:#<hK?UZ͕'0+Lֵѱq";wI 2א2^zL>d6#w,1sCF #`i.g ,M.c˖-jXӳggyq~,.㢟\۶~Vd2 *G~Vu }xm:m`>ޞCF #<p7 5uu77yɝq㵅2]-b^]3-#pd_3 j)g2@F`pj& u<~tsd2@F #?C.JMF3Tbszd~F #d2@F #04?1~d2@F #d2{kKY0#d2@F # @d2@F #d<>,@F #d2@F`%XGN/s_O7A}QYlcc6fʉ'7|f3Ø{.,3d2@F``}Fߜ M~{$7ϭu_HwF̊p;&.@v@~<Ox`+ghpg@F #3kNo{ vM>Z{{ U}3&)=utTCPF)um-֛.7X~`rʛ0a?OAF{κ1 "vz'>$T%n\rv<#md2@F #C7m^,ԑ֎2wޡҍA_; C ]|BƍEy(9y\`A]K[w=g'h0O4 rg{E֮*K=o#_ ɩG>t'M$۶o7?Rm>@+-W]т@ &Ph>XwuE/_G{08| ORK(CF #d2OOM nҷGF6 IiEy)ЉKeH{{qqc\ =,{( :8Rʵrh=LI=Ҙ^Zm/s0JL0/X@^L1"֜%"8MZe9٧@F #dt<**hXx46i_LӁ(Œm,*J*y7k ;x>2x:˦n[>w6ˣҕ}#W^K:\@ 37v84aG4R)@6xٍi{?.(-O mGtc.%y_m۷U8Ƹč1% ͕ KF #d2&ɮsiIz: oE`:D?3!}wI9ga2a℺ z^n[ eV-{ڔ}I,8U>ݟ4c6waaǍ].ir-[ BFРw0Na`|B|=#lO^+޼0w6r$ވ6g.-֌O4Yxt!qgG`$2O<9uϦo9ӵ2@F #x#˼/ )A뵇bک9iVKJGG'_uDxn ;e⎮<yIX%}h9jWwkh_|}"fQ*2sJY>f 6`WN;oxp?Laʨ߲}|up"ߋn4-A֑obcg9% ,&My6ɆeQ{ڤytz&ڷ^z'Ikى;vi8pG0)g@71R+>cz,Ȭ\ [._L02뮓 /p9ĝ;ȎZ96wG͗-1QZ5#BGdҷ˶ PeG)Hb2\Zř%Ė-[bɁ[N1">G+{d2p#U0a߉g?*xIڥҗ#M3\āH#^NGkc[g~8i3]].͓6af@qȰ˰ET[ ۮR+h#rXڮq@\pn@|bxWeg86^QnRY+=rͿN&b)ViixO5CGOl/3φ6>c֟3 cz27!<RR笛d2XRž(L6aT閦N @U)>^+olZ~BޏN#Xo?1e04'RF6;;˫jXOBnLQБ#g?Xy~.b#buCi^ocҴ oTL`ҊNuc#.<< :){ bj~V|?;D<8 9s㉂XXB )eZl CZ@F #<G {"@hi fG;WyQ译U:r+~\#[^Xr6oޕ掝?bҔC ?8t[k~ъri)Ϗub;pq 7ȫ_;OoX|FǤo)/ XbM;p`&6@D0"˻K_^pT%2a1apcmm|6I1AVie۰x"`'@ڕrd2ģ·Ai@TLWp#vLO@ y>|q]oⴑ"?OyCǒ|C=6twd -\8Tc(ti6Gb`|~ks8H%ArԑRei(fz)k0,2m+əCo"ݸ/}PlF t4$ q4 s`@挈'ΞCF #d2O?Ы >}O$Zwߪc?˯x1ʱ);'+4Wȧ,vwZSd庲LY ^Evu4AWϟ7·!7=$wf@Xaf?n<ģ# s \x025 c<82k,Y%WzH&<2ai!jG|#uWEuqPq34Xvc>%WB_^àЧPnR]%~$$IN#s8Hx^G'6fϔUJkf@pYv<;ct_z9|VIƀ{;\LEN?`% ;-QôUz0Y;p3l}skեX|(z @ IDAT o,}l#=X4Z0C"yQ y}Bl绻9`ˮynu~]d2@F``|ޱeĻH5 ]  }=X-DWO?eY,waL>+o>d6}(߻Me0:z(^j~eʔ)qըQ'@o(@{"=4Ap޼y#Vi ҙg)~g;8S͙"fy{dTa:J'=FWCukN+4:2{lޔ:~$E:uB#OPv8{©.x&@o6[SN9E^vYsоwF2|  )/:L?6|;Хl3gΌ3 Hp39Yc Q^(Nb{2BwO~l8kcn1=b'z姏ڍhx#2ȐnlܸQ;|qcQ9{lC17xכN4u07e@&N?t}0oZPukʾY4Xhd%yiJ`im۶I #ѣF7qՍ;B5?GY.}Ny:/Ǐu쮻իW\gjI5CfζnwRlYpst?k#|*b_9)Mi(t?x9d3@F #g ؇Ӷ\Ě鬒 0v8RrY L{w.4צwɫ}j&N/qsC9@,_8lGa!khm#&ϒygǻ6}@կ"> fLG ē/@F #d2Crc3r~Ǚͦ:U'ry axƬD9bǎrm ݱ#jLr@F #d) \gF #d2@F # d2@F #<اwlq}>Nr.zi-Z4(wl7sYĺ _;./$au@F #dF'V/^Y>Y>@_ }&C/Xbg@:ˢo|Unh8= tˮF[{˿,KT|T3˾ϑ6"W~Q>s?7M˒Eߒ#·>kDH>B'ʕo@?{ݷ˷:EՉC?d2@F #Gw|ŗAfc]rnC_{?|SɅ f`k| {\_D>rzo%VV(4N{Juf Wr6}w@{nɎj ws&ܵ[ayxgi-oM,]no\ʨ2^%dmhzz>_$_ޱZ~t\?"ӛ%mҰ61_E_mê 9/+|y:R?5|Ku7dϗ[e~L}T}[N:_oA۲oIYXZ;I_gsY'#d2MRiǰA ߳*xh`W} M͏_- >as or\rD|>4⭨=9\9MićDk[|\nVI/|t ]MZ/VڰI6n);mQxիHEX5lLco.\( ^m"ޢ嚯}ևIETم߼U"_|,v+H: *_چ/4OfOWz\|]-ҋtgw'?{rL6#bY;fv& wrX*x{UC Yq;^ujum[,w ]]n-\=Yb ߓ_(6\͆5vh[Xmo_~ ؋>a{]"[*m2} z/Qtr4~_4ɕrїʽ(_q./wʯb.ȴˍ -_ɻƻkK+7#>፺$n!#d2"yoBfVƞ^Y?kX(X.[xMg% <*Sik/R FV^P.0`藢$Xoh>]{O/R30޵L|B_x7oByۍW_(_6p?ptnsT4S_.goIo+HQ.|_6ݲ :i\sgP~qa9/>%G_TdoXt՗=R~xϺB!].-?xHϝ.}\/kPPu/X `}Ee鯓*/k~ FrTv|{E2__.6[+oWO7ROȢW42]*5C.O]Wˆ.\n%_B:xo|r$o~(?Qk=+cղiw*r+CC_3N{\!|Hߑ_x.y⾟/V#}軮S5 eK̎w/gߖ6]/]ܵn,(_tMWM7|U8 HOe\[ϟ(szW9x*˔fz_ܾRzˆ%.z7AZ9Y^(ʍ(wR6-ȿ[m)5&̙l|^9%'HKni>W='dy_ͿOJǎخZx^!s2X#Q/[1(7j9zܳ;r5&]H^4J*fb4Na~n;+ɱhwL{~-O}.JsքgT޾j4=-{'Y+ln|qHKSWmzϮ["$-ʥ?\"(|N<#c"=V&rwEƎ$'y2 a}K VE.[/r*t99SһYx_uT#O?GA(!9ߍmHAVgm@F #CQ]eʱϓ"ٴ˟W=}sj}կc0xc7lw%u9Klkm7zDF7B@Z uس+/{w?xpxf@^t+׼]-9'Js9D cڀC]>ipe ÉL c,dF^pdenu~3@F #x gu5eb>QZ+vY`dF;MfZ"nѯ[mAk&yݛ&=д(M~ԁ =ɷN/7M!qn>]Ί;;kEy׼},2؀*s/Fk{Bn?ʍA;o]=پK:{qy9~yd#^c +e"Tm7ʄg?x:Шl wwGQS&ȑg$+&cϔӦɘfo C%>g̔_!0d%@).н{k>_yC!X-G\~;}E/У9(zdCdڴ)СBtܾ]ϘDK37Q*ji~k&' (=J: seV4omYLwȭA.y䎕2sh)7)k?2r<1MtpLX(0[K?2x{uI}&Yf\+q q7-v~܁d2@FIB=ʕj=dѻk J.h}pr8$zKe٫'7&}=;HpF,IxptU>dRLnG,]xNynZkiX9sE\$ʽ.joN;NN:9qRi=V_urqv t0 70vZ$_n=,#2K./_g*'Oŀ@o2#7}N>-@o[LRab \ڰj[A7bxgk&uzW˳g4Pr!e2r? )zvє,`k~@$F9cE rͽsO;_ |K_YLNdǿ$ג3v|:Z?^۾S*2f(bO<}عxbO ʥ7 ;ƌ+z|Da[__un=Oz|KSYvlw_cAuȣ-x^}ʨxoj@S#ٻس-^i8Q1r߃ɘQ2$}ha;cǷHniĒ7ŧ|DxN`^14˨^{3WƷT䡫Z^o\FC+ 2@bnR@F #(MmcdLCt`IBJK~^ꮴx:wD_j_KDj}Wx|E3|n >],i= 7-{Џ>Mҕ68=xtR޳mC۱@dVtrGg&EoۍnlѾkl6 =;a!-[x]MXsd@$-uz |"E'M v͌ZzِŃ@0·RNFniMܸn'|b<m} x}ڽM%Iw}~C:"T_L%`Zlv)/FŪ6AH |#O!*$dd.d%4T缴Z)k̒,b*^-b#\/†*YcQ)P+|XPhᨃ)@idex"|W-ITBu&/kT,!|n[~DQ*Kʫk>AikMh,ƅԆo^|\(Cb|UHXAW3XCL]>0:.A5ne 2?Z@UH X5Dz슊u ?0Ynjc$:f+K}%ߖxM|oy$QΏ4*h7fkB@?PA!S c w&IwAx7CEM(D\8Gyix/R8)Pu Ffa(TǠ(q&YYNw6Zl@^Y;"͊RITiǒ:B:ndV1uT2Q?1hqSƌ" 'zޖI6wlU|*ڱm)Q(Z4m4~Z3 8ިbfF5T o_f[Q ]jT+Lx$%ZM B?aF#biڠ< IWQ]嬘s3A.3&dŤث#Hu{:羃Hܝ SU& ZYKUIz,bA< Kƭ]F! H7m9l=$xW~EYP܎hZ8~ЋkT$WpI*jtoQ?r A4b֭UkKrum t٘O@$_NJt dK!Qe@FUDQ~Ruu У7hTilK! <:YLPH02Jٔ4SdDbV"ZT6mDD]!+JF̘,IG6m6Y)Hi{%Ap2(4R+@]"i`[i>" DU;T]|u.-O"2SuB=NBʹC%9vG3@KiνI^QGA*JpA؅&t/mwdžJ݄ 3N:eaK'y z TiC6hL h<˹^2JWE&Bm$zz%LBG)siYI:3z xJQb,7q]!C Z\~UCCg@ȏ]EPѢLSz.Pm_7ٙ jN7j)r]ANY]Y\>mQX)GT :!R5FgY73)D5IbY!qD1UQm3,qU2HM!JB t>MH\:5 Z 6J2)Z54s&<&zl&x `ƃ]9aPa5A6gTEj~+.QRJSY3tyR!MMD UX`;֪I6ft -gm%,rj.$3S:Ɠt0x olPZ/K'P"(B:%U#ÙVKRU@"H|fJ.!$aA.7M\aϜR@!:^?1rgfd.#0y-rC3҃L^+ P[ 5T!`64Ta $b]?fbQr0t5"_LYk(e)BVh$ ڜ6tds/\1M*im1&=r̾k-ҺS4 9OYehA8!E$jBRAu} v&TO7Q?v)vnHMg܏ =_)tYu't;{t*i0* }K<StNM>D[S6i ["Mr)j"ŏ8Kڋ2Ev"b'HV1uG P29ľUWh"IPe>u6Y i'<G*_Lَu^2{<Ӷ+C*Ѹ".u?>Sҭ7sUT{2 s 'kZˢ %9PP%PFhmk9=6=֍IūNLMOLW ZF)D"fH0Fʥ ni>a$H0[M3H0]'SdmP{̳ܸy`e>FT2E̤QHL/*c"ëS7=QN1;uTD9"@ipY}nj; hv1Rs)Ɣë4T6+sT$g)#0L۩$v4L;Jiw>whQEnT fA&zE2-SZ!EueU \g`yZ@2oWb3 6B$mDnNˏ;Dw2BkcBbVQaL (f T=+Uu"f#LJT, 3;&E:"QG+1\LPyup 6'VFPjRb̈́MCY*Դ,5]%`Cs9("5MuhG;Gw(׀zs th4isDp濄65<2 }Êʁb ,VVn6P0׎T1!*m>l7Z2+MrS7p~h4hՃymcEMYmHbE0fPOIm2Q4`ЙTc ?jɲ͞<Kr}*Q̫BP+qgq/_1ۡvHJ1mltt :R( r9خ !J ҧNIP,$Mt}'x8uFT@!c'P- 2S5惛f!TdYi!L\tӌJeص@.}}/T&%A11C&Zb< J僘E`$2..P n<-NnT! LՉ YۚRQ^ZtIHΠzE DŽSڪ|%)f Q-&+tʫs 1pL V{(j lXrfAFrJd,h !0+y*YMS OUޡ|6]iD/SyGRTc.:BJǔaZ1SLX!C^mHi_s%3YI$zB$]U7j/t]RB=ِK \y;gOw -pvJjQ^d&BAႈc-_OC;Tt,왕͝)UUHBW :1t504 /҂BCBwaDqU |'&0 VqzqI# [m5UM$4+زNd1 'аAIt@Aܵ<EmJv~E1/CʨrdyPʑb>h nȱDȘ $O)o "* ( "f.:q 81SI~F9Sui竬T"O!^0 Kh6^!kۇ%!W,`݃D؝vzNjUU:3c<ֽZƋbi Ro~]QkHs@/Jw(_j߂=tr&9 ߯45ψ_) ` yD '@A-A=} pTcJ' ABg@ۗ [ =hN\'@\9Bt&S(Ҫ2$ P #u:*m[XaԎ!8nL&\c` (fCp5f&!v`, tX֜6gU?vQ). t@U|ǫ*}h=ƱL Xp6Yy.f=~?Z0&%\ڳ#O U$S;^˫ x%$n29y,)m\\9I%o Ɉ]IOA[RR.mPiCDJIAPb~,=RۮF4RJgݥ d&$seSX =_$[̀VE P $Vq=V-PkSEJĉAa\7?P3񪂯g'r;tV * v+<X+Tyr7.g@K@rQtC%]Lc˘ ;A=% 3Ap^hœf˶VoyzC] 4S[<ۯwbf3L;_K¨u ';M& 3S"E(^Wz}Ge%'- IDAT+u6B #q\a-jhq4Hlr#{I~U"P0.y++`BC۵2lʥLcCxʮv|Kp=8&x.c@+<LF2~6JQ,IpUŠf{i>Qȭ :| Q,t5Ȩ?-TFrjBp#5y<]c)4ruq1$1c3c΃D<IOtA7?D:*&/p3fQˡY;lf t EiFn֘^ 2&j8uZ ES.7s) XR9&fDbV- \Q yT 6$EE?M9 = -#F]@`* sL;Rp0s'Q>CuPA 1#' vJV€w| ji&eY4C)E)Jw&bWMHlD! 'rVRBdzćX;S:f= ciݭr*#P`ݍ- 0fܘklW[i׋[޾i|cf3C":bbŶ1PVƤ"8IJTJ.*O0 ʒh6 :8KzW(lB̈́r!Ì`-EIBM&c>LbTp^S i~dPXR5w}M)lu<(6&jLj(lQKoLR0 m*Vs_o17|0UJJUbO 5#< FJŽ}f I XRDP{*iNl _NwqƵΧҾkܬƩ3\!Ҙ7uUPq:n9#dlXKI>H*SE^%>z2LG:6i:̘]m ⒡E%c͆X c) Q vMϺkwYk>:vi Hi#2B@wlh;$ `4@tM A)mSӯYfZ]8:?8y[6130ض\/ʮaI/ᒟq9xO"B>]q,dvG}t_s,URgܱ*dq9H)aG4~ZXtacm!' G!D断qOPvb~47>3bvCl6ң^Ğ/!8g=.գC<>KN~kvJӿsνvqX { ^f?T?po}Sp+zw*㮪 ɹdCJX^,ZkAUq%!ob3@Rͭt_|&QTH }e8vq\k N90&Пn L|AsIkI.nW4hΕ` Y38W3⮫P'k^MZrq54KӪylp| ]>ό+气r"NmIq)el@0`:u#Q\Hwq(s<&/;O_^P`D'3q&[ =uda T)"R<`Ƒ8v"$jVt ctp9MLTsaciLl4EHPCId|Պ*\b0Wlޕ™yj#.H=ޔC{KcWύVka+ÛĉpRs`0%~)p;up}b|{ ޴!8Ľԥ7bbC%Aڳ@S1Hj6Bl/ac [c[8 0W ˸hQv8 nPiP~(mY6'[Dz$6WLRL@%*+ꀱ eC#Y($' 4FMRCߝx!;k͆۾Ofj)zbu* (RYN/1 pu$;mÁ?r7pyegJqeI S>`Xm8:!^:~pMWu3b[`c*WĄʛg>5hD_\AX5Uw,%NKp\>0gL7~1>\0;uxR@ɺ趍@b: U#}kЏ^YǝC&/dr~^'K͎^wBWnL j؆J`"ZެG+B8ĕȶ] y(@q3M-56֝ @ɞl8ǽTS2&2s#^x]\T p}!ξ)X:191ӎqQq-D~7Zr&l4n U,l0 ?V{=I{ } цpI5 iZ|ű+~x8]KAQ%«s^\Qk'%g=Js tT;վ^Et>iG)@01DŽX+ڀy͇_͐sWYץυƋhCEޠ WE]xZV[]|E.^Oo 8̗Y垫e%Uן~M}O^|WtC'@4y,g=3D XسybԧzNTEF~%j^t ɋ(Xǹjb&d2CGgؼ{ݣ ʤEs;1#C6| 7KҩvxJ)A_ уαsqk[J&pԐl筽ga;DGՐ} vlh?옮Wv${up):gO*9:78d_V!r<=%HoY&PGkwGY1uBO{g8WcG\9*o̭hP۶qk+WÙw!]1&O3GBnL 29ƒɛ%7GVLZ"0u6*~4n%Ad hMu%d ށ'zn p{3Gd2{B{e0rsY|tHKJ-Ӏx,ewa!(h`^P(+{X ∕H,a9e3-\Ds-~v%sn 00x@-zmoJ\9=X5Soœ @Sl=&W7?$Waa8f9ӆQYm pET蜌G'rZc̸quI8~Y .40dsS8l0;,tڠg;³&B:汙x_3&&k $v);cp8cTl)TWA`CSɆE 8W`<}A/>&7|և Cl))hWKS{l v߸{T + `:і|nZ f^F٘jk\'FqΐhI#1mM '!Ǜ#=Oym―{ !Orqa Q^tv$1!F:;gdRei-.f9eI6! 3䕤e9%cVr[89;UښH }[}O9A"_HAɼ]`rrvWm6tA=O@EB-t1J sR|-uf%D.tµ[}60o IP0#swnT 55W5l!녈`ãW;[9P&zH.5;·KS/ĻMKs `Csj!JxYO]靚qć^dh@ dޢܓ׵dom+ςIXr1!#MlX ,3'L0dZ'=xYmN臇b |2 X9 wāio5:;sp%:cvo&q^dEj .Gs|j'9g{SLVy&~70>k$H>2 %m] :S]3_X d!cZ&o ޳WX _*'vgCwDoߖ\IݪQ𳆌1_zex~/@L8il|1jb<7^x(. dV9%&9h#xË0/Jc+Ћn3!8a *uRsm!B u#Q8obagSwW͚c^'cg[ydv:}|c馷l^嶽4GZ/ZtR>WD;"U|JgnAEep4ls5vJpS;ڙq2KXd $ZU@k{=HۤPso2!6C}(;΁wl Z$'ގۀ=FBA c[%Nם:°-LAX?2 jZG9ДY&$?ئ p>y%k].k' 5xq,% v|^_3y*Tpzd*ӋRј6yK?>?l6Iψ.G_'ml];'>Cuavn.odZ1{||v?wİͺ024ol Ne toFW^6bYBjPӏ5\Yڽ#c8k@۸`۬& qy%d x:T8NID< DfSCdcXat]Țs"lN sA1\W"vO\K_9570inFJaŋ=ռ>?P~5owNFe'"]Q+T%zmG`%!'\muڈ9x̴P݆_Lvu=d,n\vkve{~o.xJbvv9K1yaQ  Mq,Si'r=5q0|W7hkę!c_C9HSE7YL'TOA.Q8L#nt:ܡqq v>j t;u 2[’T(ޖs3m.K<{*R mS!!!4(9 hj[).73jǜ?Hʕ l·7O v hHOnCKc} vLۣ+ۚk1Fe/7մښ?sS/>:WI\b\+.I<)(څZ`o$& uYWd/W7w:]TKHAjaß$PiE b֧a)#a0eÙdd*8qW4J܄ߨy{[7L"ne 07e};ء/u Ix30COה(Yt°gr$1't<~@3!O+=S\[2fG]F9AfauP^0aKgɄ`<Lfĕ|'[C8ںyVŖ;5N&?ˇ&gck3hGVeπ0{ & X}7cc睅˾byb$ݸtbi->[>ŬwNTh+,3 _xQ+f"> Yu|12UN$u P"};mfэ|$/ %k:qnl`=ȐW_Qr$^4Y0I^w䟅.eTf,eؽGxђPt'QK͸eBe0W4\#ރ M;,` .^ Hv5&xf1cB" +FXJ cH1s_<' IDATK&QLWܼfn ME+tbI̩[v_=\V-]AGK [}F;}OqoD߃ rW\}gy#6N64*b޳:@Y3!nZńY!?1֘>yȊmhSJq^VXG8|#y .R17^_o~{{{?p{˚vadOzs2OyȁSZ 3gSؠw;;evg鉠 Xֻc.4Vs5Bny#z&?71y!#2h`rhxud^s x$ o^ָǓzkM bM<"H^ٿA:unh%;0P6$O !J(Y4oܲc5{?;v ߔ y~k'mActi^LڪǹKyTZ-CiC}faЉޱ/%ar5Sl bA>/J1V?nYgt,ݟZF E7|*,u>P{ 6ϣRC46QҚlTM%Ѿ2vNv ۟+6?aS֧Qܦ4|H;5-پZHs<}\t)zjŇ0c9ˢ}# J'Vpf3<6CrXsI carWTF ff#0r ҃ގ+.2,<ϰgх_ڵ$V5.ٷ ~3`FՑ[G stݲ58:Ρi7_pCrg71&.vP[\<6сqYrLh:KikWQy z;Koe L~#Ĩ1*4x<^wBuٳstUˆfj͵wWGYo5D昊nH3!"ˮ$HP'y6l,\* 5Xj.\[!:Q2UG\}gjɆs?5iί֕0 T8'1;#Ys*2~3+!XlU֚\vtx(òbP0Of` f4]IƩqjy9R:R:%^FF8hqS]|C:6XmnjHqv mJ@8l]ih,Gcߎ^BۤeȮ,e+z%=uShGqa?uL2uGY:g柉9T )隴ngѠ2LaQzk3ܩK?ܾ_ʛ|/ß|SC=coZP0>3O u:Jx*`Rvt 5i+z'cYFp}wh}8x֬0^lS9raKCu b KS{{9&h.@G; {5|f BTs{9{3Ek 1L'N>Z{[iض 00Gy )3| \"m~Cgk 0rB [Wo&Dyf-l$169V#!%{f "wFRy<%n|al&8? M|UPn(x3uFkz<(J8ɕsɦ~ ANo,rٽ1ڳk5O،pܒFAM5pxO{Kyd3ul:l3x:O{Jbo&g|+_o=u9g6EExuɗ{C6^t\`9w}>QsyѸ~G_^m+"Iy/? ^[`80{H|[!CI'ڐ_WuGW.t?nw~÷/~/﷿WW^9C$XkN`ș-%UuL;  %>֐Wц hy “t]:a On;LȣZƹQ[LJ,GtnW?5ūATna,)xHˉH KI/%.~eHZ[S6Ǻ '1bX aq'=^2,.!RI.Mf0!c8SE`vO2fG޾9/mIel|ȚS|JEϧa!Ͽ[!t^#zmfXFqc7tu?5\rLs+qȵ7}g:6S 㜼38IBS9dO!́JаN#.b346 ҟ :|E3^(a%C|΋k5Y5Q8o꓏S?۟C#?KWo}wdЁ)G5g؜O%rZ^bwteRa_FԘlw26W'~YGbLÐAk\Dk8(33,]`UgH Kkd8AO kB*7Ch6Hb ?`|p,&Uϯs@m7M*.O6S1y᫉f8O'یI_'vv7O>}~T4|L!fyeȧ,yYRP-7ssD9oH?cJ3 ފ}"t{+6-*>VPyR1R'WMF$N$gs/puQ^\o?hjm%xqYGmfJȬ {.8=/ `gT/pvD 59rs.8+݄(s>S|0k.gM{Qq+$cS);[/r<ꏭ n}^x+_{Mgpz~&=1tDK.|*b| 1Qp f!G\ :w3"edD.~RMҸƖwܸGWUFŲEAw44o^9aϐ\Z jl{ ++)Z)Xɞ}X%Ajܢ k'Jh>w濻g>{{o|o|_|ʷy?z{)ԡc˝#`ٕޤs[=.cvliљb(/@R@0};Iw,/4FO~A#UI $h.wGe3s5"}as”(' *:`c U=ӿhg+,M/u9Ƿ"fiv^"ʻ\6ਸ/CGeRU9ָV0T*, +uEIp`;bq=9Ń($t HLX%O7Bbʎ5 ,~I8<ְ'8R}׾tү|1e%8?s{Ӌ'^O'Ft^rRs1U *hTj,1LjO@pNp5)&biUr}e1u:J[lg,øpK:/+ r>4́^K:h=E6Y#1Gj(r L'IY9q5w_P&"ٳC3d­zEO"~zS*i\/F (Dž\!Zmak uX=1f;un_ s;Qg,d؋'pABaK/'6)g6xQhh^>'=O'5rxZƼMtZm.@6F/q,FFX!lMsDn',W^>(FPs˅,3sZRa<EF쫠N ~!c6$}Pg]U,jӛQkSf0=ڡ9ř@9.YOp 9Ԋ>̖y¹&m ag]U(|dIZfX91wa=-=|$Yu lWձeىy Bh!+rKQ&# OvZg&.wMN'屩ޕ"e4+3F-W X3 rr;cUK9nMNya?㬥Wn<*}_\g Sag>{?uf_K!}xkrժޫ?׸eryXC. 5]Ϟ▰e@֣]zspEXEzdrͫ-K~mfI:R΁$~bL/< m%NMe1RBIFH: k"E ۳z9ʃwLzN#C +z[ؑ'-a+yq[PXSAzRb G27ȐY=H8i[.. `tn#qo|y}iu`χsZ1ų;}APLơ;"#ʜEi( <<6Ӳ\>'dGl'Sڣld 1r:GHSՀO uLw 9+ƹ&Jŵ1ҷexݍL{<σ[Y͆f=4*0yA<[Kfr{z6,w{I>ww~o|ۺ^~k_n} KnT-s;'QdSOOmið=XY`ݎPQZOڪMoS0n[r60I]rh|lbSƖ(?!,8p1yVj|h CSck$nJ=1prЖUzrO%˘Х]%8_R8/1gp#&Cg٫+]'x67gy|tw67v:Lqhf22ZͮgQ|ZَFl4r&N;{u&F"3+ybbؤ) 9/=q&^gYLKҸ-Zd|OBtSaXz=dTPSYـѝ`G R\U~ˎG^El@lٕrPQ˃V v56)/,a30s ka·l25dMBTh\wXvn%# e O1WHT^:I6ӵD~—y ?6.$6og{o(%y/!3>b i-|#c]b>πl1upZ⺀ DZvԙ`63# @=qq,`΅u&J@A"Q#6؋ڦ;JģQ;n8oA]w]h2I`r657^%pgC"GE7NdλZI׸Z5c`ّTq刷B1uO߼{>p{W_~ C?[C?_ODzḱ-yt&gן2 4SKPg@#$ړ:AUB~Q1Ǚ R퇊nLQG@bG3w]%͋bClLlwNe PM' ΣǡX)kxc^^>PA[N){P7r2)'k\$ =mS!0?z@X^ji"ւ<+n%ͧ<3Byރ8-fW[2C_ZyNdU .\>LFB0YvÊ2CƁf`ԤbM/B fF@(D2>9Aϗ+y+|Bi SK<#c,x1O-3@O? >iVwgy#xד2$wʈxZ׬ =ĄA^IFT6sかΧn5;Lb\|b'Mc3gT ldd"F']؝ʻWOz 2{nxh1YN`yM\+<A6:_Rzn zQǘA`o?>^ޙI4soWh+,q${55SaVt&5?Yx Ε F Ȳ:Jw67J`/rv>/'w2GYK_~r{AK_}Cs3FRHV[eQ}/y(Ӳ+YΩ5- ty߻_}5_qʗr)})6cq{Pe7CƨabS[Ÿ虭9\IoMaK~^o}#;=2G䗼V?3~|{w@[OGThU]OHK|r\L %$L DEaYҶ 똢0 M‹䯄Lf<X3h\= c/BYgxӭv׉Y0ZVClkrܛV+hj2Źj;`؟SE ;v򤀅_Ʋ*vsTStѾ$SdĄ.nWfa@vfd(Kl{τ2'ѩ9!WG cY]t|KHƠ5/5 WEB(` ~EQ%sH͝@ a["l{g6*뎰:an6b{V_ɢ0A_c'bkZ֝-?_F?x1 +s 7Z/==H'۟c?tr? ?g% DN3&5rV/N\믯؃ط3ُP׃[zN[>`/|_?{Q;ͷnWbOSϐ|C}}ut+2CAe _/Jɼ~ V.@]7\a#'cBcC 1|D8hyBⲞd=ú>ژx7KeX&%( fg[Z3^DSLN8LUP52"9(ڈmmsW +\ 0X4.PYgi9D4biϞ Wn<~Wp<٤D{U^^|^埽Yޏ~^K$ʷɝ,=^s)% O@ϮXj%Ee* G${H͌\ ~DǞ* Z'+̄J-$rat K=Q(m`nGM'&,|z˥Xޡ%CYWgX&1K' 3iE:C;Ps4E<60]9 ދ2/Ob9p DOşn>RY  ={u|ӌ?ᑨ\} REzxva xA()yR9I]g yp3t k OP%+wsH1y|[: +jrNxjݪџ8ZX5!麯Ak)dC ?<-8cQ!?' bt[pq]P"> ݘHm{oX{qTi@0.?*߱Q{X5k/B>aon8*NBw3*U޸$= g1#P_! ԊߡRȍc_7,uIPMu̻uS<Ϯ8 k"'Ïn_mfxO>|bSyA L~ccFvzL9-aaRP2Fkq>sml5B[|A޾[('!z|2~#yQwJ9^$2Cࡲg&VN/k530㙤V' <}~ }2u7\#;_x /KWf&R˸6hz}qmPYߩ/Z1,S?VI)Yt;v{a ч<)iΏ&szƬꁽ; \aPDlz(18׺+EɅ Po$}{^]gX#ۙ,xXޔ+B^~_Wh92q}DDZYQpV~z&xa{|m_pgGӻQ8?jxh:l-}rԿe!z {ut49oK)Z>o{;$9WG5A -slNOk)ܯbw#/KZ Hu>y_}4v_0zV/|5-CR5I>H^{G&E>tIEn;cLwF"G\2xfp ` oHmW05_ss*wr0{7b 2, =`nr@q];"u3 1 ǃi;`}I^?]2&׳%lq?FL٨50J].ິ/ PgìZNkkqmv3yu%eԦ҃gbB}^X*}G8<[\㺱OȒk΅'"cc[-'PchDul=.\]e*LGlzp6p @;],[+~[ 9?Ӂ̈́O"mMJnryAޗkv4dLe#!}mOPk}tyƨ osAfDyIS|]?;?T>!_K/>ߧܪԐ7$U/g]򈪨?0mv\3+4Am8cԫDBCsk'zT*=73a\0B{M<|y>hc>0eX֤b ]<c$ D=dʳITg=#ɹ$ӄρ !LmP6dt %>QŸ&'m4o49R*bDj9r9`.R\L?PB&mpy=<䚸egG]@<ιu_.I|+́x*:V6$ M*H\uPK7QB>رYQ8xcSd1ScLeURf+ᨣ!1}zCV빲ӬdHmnY{:e"A)xhWapHS>~o'_;9T|A+~@M;<ٟ95FǦ0 cSf_#7$"f$]}Y. ]T^N?8j7@|#L681*A[ xkvWؓڲ RŴWƦT@Ƀ:Z`:+pω y~~I~勯?7~9ymPQqqb : -sBNc-}Lc˳f´a.6ģggX:^7SWbG])sbo~ޞ|~֕륗nMI?_7>#/D`}Sh|dݿ+Le־%< a=4pq-@ܖdc:}l_B@N-zf!2%#ުyh" Ǧw>y>R[搭'CRbܬ)=W=~<ޮ2gMc.n {nȣd:[^HP.'w}xɹrT^\;. SeN};2&obQ?ބ!Eی["e&znjܬp^UJXBLe6<ͅү}y=ڙd-sjJ&ie=%f&n=Gxr}ƴ4LxO},^$$}pLRifcc,CP ĸ[b&w+ׁ?,ly2BJ9nو1#㊳A027V"4dɅ-ӛj**Eh3{)lD#A)߮ln jmfѤfolYd~ބ=;h6wzCM'N}$] {.f] 6zr)8E`( ?Ծ9֜wb ҝ"9T[( r`r%XY\F7eYiGаvexR1a/ʷd=(jwʗktG揝=9 IDATx'FYiP̉%fv;A{7̒s#One$p !0uu9Ɂ@S ak;0j~nDB &ofI쵊Ksh\ؐc22K#獃`{N#V32?hGVs1|w'9~W^JР% %eƸ"]65cC!v3Au_;ѐ F#/t'aua%#@Ķ{Ju]93Znd']'O|{?GCu~(}[/س5] !g:YЙ0!a o)Ԍ3¨$g?`8%P'q|Gĕ~0 |y>n&Z*gRN=Ex2lͰp=gfu[51gDD:B:43KH 0l1P9ӤɎkbe0't3h8itpO~㛇?1nk*.!r;:QLN,"3߉%~c ʳ);!z̳kHPp>`ܖoO^xWoo۫ow_}s__?_t']G>o/?_wys ^)yKX}~d't>~rBzL]T,_L>D\Odط>-5 erRCW[C՚ka*lWanh%l0v~]8sRzhAA.C'|;ӠS_ksJmzh0ujx w+ t]$4&Z1VT~>ܸ ?Vkѯ|Pէ^ CC n&JN?9T(A m0b@]'j$vό;hE [F6kVA8fߡ#忠}-_ {&k k!LT&w2ȯbFpGV tj]?iLAm#> Az1dc8e Ğ2jI:u;:&st7ew9Rc A\.`G݈pG}H g#(J`6\sx  >Os x]tEO iXB 1pnM(Jrw:tQ%'lH.6r~/]f u8p!d&)Yh%C ' r!) 8ossP3d= aSruqPs ݚʻO{G?ڛGe}sN&229B JE8`QպtY媫NX ]U]F[VDEƄBB朜sz}뾞N]}w~~{G>gA™TY/xㅏ~sz[1ks沏~ Q_G^^\~'uy{>?|[x'}}zG&]pm_hҤ[T3dO|#|޹H~ң/}:c'MoՅ=_ *j GOz#;&ZO.ȽB4pV˻c~}?f[vwk~ {/?Ɵ<|.D<<jVL9IiNHtɄ~KN}TX#`n:r9G|>>'ޖW)ř,'Rɺ"7m֓΍h'%4h; :cSءC}o$RVl cia0A :wM^CtJ7`cl 9m";X8z-xuc.q5`S7ଠ}Y(e :|}B,ŬͫÙsK<̑GQmc8ƆIwxfāvnשԟ/VL!|[]2Gƭ7kNw#n>_oDXbCugn+! a,"c2t#YҳKF#=$DWT2)9ր8Tf\1_azQ\ fCJК#mBX2ξWA_.~j,y ܩHw*Q/ XM쏴C؎ OR;NJx @J#'Fz֊Iw`!dUO>Ό)Ꝋ_ LEǮYqԸ{Hr+DsEap: *xfgg=Qm1ZL  ]B!?%Ұ`(A ?nRڡYDxh O)vqҿn  }H{s|s w<2CI;N:Hv[g=mRkΩ 0@1jQwLg^ÙXG%sH{k"Rh@ClV QgGs.=1Dw1x'94Kqn [q6U4&r]T~SF܈7$[n]tôˆhɘ꯱mub (mc:}|`j ֟jftg0ܱ$V| /ZW>K&ϟnk l{j]y \\ǟ=MH7(@}*]~W~,{_Ͽ{N\U|'+O- `|'>~Kױ@F~Sw'zE@/_"gO~?z%)orsG@uktyk֒i{ӏ [z/Aoh?pȽ|ޫƫ!)z+r6c7{6<*=ttQᤌRvNz$; )غrĽ4夺"\Qnڑ{m~G^!g$[p1ܛ}hmqj&鈲b۫W#B)Q͍~|9HwiX퇏ac֋S9J? hK4SR"7 l?F"-?4';al |b0pQ=)Жop\Y1M1 $NЍ1RD:wi\_=I7 ׺p7z=Wy/[7!ꑓ{l''5a6sփ<#"Sy ?&Be`(a4g:m]pٓ[Z B:[-kӹMʃ9`+ /oQSy?u fmy,9472n7yֵ}ڦ ~,zD3K*/ xt<2"NDǒcVǩt\Lpz G햭mݖI&2怋wx8rrhV>:m 9B ujLK:@\Wێ6'F1NvޯD'r^AX&P,RړTFR0 Ǣ"ۼ))G^tcGO|^gJo7]~z+>_M_S?>߰|ޑngW;gzCMPBˍG= En@NVo_|LT\,-|nnkޮbmPs>Q7UЏ[?[nަ}'._^q/}>P~G߼iE>!_m)K,¦r\7#y=Bmi֩@h?I=&ejhp+uZ> )r7#f(.i=ִ&9?q0lF擔A[Lڨģ[VV `훻|&t+zHlḴ Rr58Ģ= ;- UNNֵn3}nk4"kBclLj>N'rCբkߣrDz`eŮ ˹UO>15E*a,kϧQ(+rMނE֍G01}9Tvwq^o|ߏ> ~ͯx+/!z}%O_ŪSnoK?tKzD7_aE_K>UC>|~;^ӗyӻܫ>+_tJ>=u򳗟=뉗eϽş(9W~ׯ}iz%a/߭zy~ݯσ<˯u\xk^vSU>ǝoAߪW;>pYE_g+쮗?q{TUOL|Əϧx_пxʅt&fIKdͼ8OSr3Hj z䫿94X/HI@ڜ9MَG jOڽ)تLV^PEpb!7S[5d#+n<̟5q?.U]:u2#q!4e$kCi}jg+}AGT4K?[}iM>8d^z]P Qp .Lɣ'K'ɲ=D\[nӊjiRnll!տ7xsTZ(##5]XfK{g!Gjo<q|'Q'<WQ؞FG{&3YӠraz[*V8$`;rxo BRS1;7 SPä4ؤl7vr ޚqЛ \69zuΈwd_mǓ 9"<:8*pd8d4i ؂vƀ, q=TD&TNfkLѪWeW6? s.Gs0. DdEc <'h?\\1$6'P#ob8;s"rmϳjgl6sgS7Atu^[zޯoMzK>i#'/_#?ߑ>gk _˗mGߠ3K#}qx?4@>]f=sV9sy'R.^_>u+Ыoܫ|!3;ޟ9s^_9kA*o[?py?|゛^70^{.Wx'= P^Ի.[~=}? Rx} Sv?ψyy/ Q}{~g./\xuOwi zDhc,Yg2&۽Z) `>.x NPpsdZ{˱Aj VmCuNyH/} bxGD pvƪUgs4j.0ʭlLK݋mAvxRRa!*nhHѳ9 fL%]m&2Hd㱤vWڵt:P&16i#EՆ=TC) O(3$37+&6yg5^4&SONd֟C/9Ʃ>kf^aa Eҵ01=d Wb>1~Z{kd88Au ]ȬQH=,@K2z32ޖŇvMK:D;n^oՒKㅴ1pmbNAI: fUukO Ɖ+W#;rp^{:}$&~RBg&`wu e9VCYp~`T'1簓ւߧ4ٝ^ouƽgCsпw߅-c4RekxD0|FNsBotl!؅junq#ޯm6畡jNŨ6.r5;1> j܄4vlR_ʠ6NMŚt&| ø\˜=Nj\&xI%?!oкI)gN+ZZ\`.[\>>M'=Ưh,w_wsXG䕑||.ew,;|_cۺ蕏c&7H:oOOuI݀}+!I y1 _%;۲ҷc D6Fozv-e9fsqRGLi1vzAFX %.~Ĝ㋋ޞ/f 밣Var)&c9*XSOJv3u]w!\h?3oŇjZ u 8@4wc+J g;}]MT7h}*+ Iekjyĩ;.$8fLj:xh IDAT[qdip6X[\奋G_/oJDŎ{lÖ5)aBf=Y\t5'nH)kx{>&Zn1cxKKxz?Ƅ2Т7Z.f˹[ i][2gy25YoσGp<{z[k`nFK@量[xホ~f1youqn{){|! - R)h1ZݸM@} bd\1qH|d9d^L:_.9Y'flʱR`ktR_ږYZ),KϢ&z̥̞o|m d5 !QTQGu˞BFߌu]Qaa1/eZt6Wz6rnyA>^Kiq )[z@o\Z[& Nۻcֿ .Q3b.;0er6XjYTycR̎83o|^ylݼNO{/.2Z}-\r,|ǫV ]@Ozm^M.AxCuܶÏc>_W~w6'Lxʼ]yVz Շ<@Y#Ez^{偏e7vW]̮+~ScQSZնOٺG2Wou7>>Ode{׺prmC7\Yj)LIizx:r)C+C2 <a-s@;/0uB V* cBXĽA+DBDN41-9\c+_QR#6񨵰|@o_kNzUn"DTGndMY=Nr8EfrkvVb'"].Ub% >Hv'kyQ&4KrފcN?IE'fh 66B{qK >QL=l Z+xO`ϗ9re㐸| i,mB\ӗwXMz&;=*v)й0fnEÊ5ƥslcݞ|1Y-a7;0=}$a1OMA{ࡋ mMUǎE95@ 7і-Ys[9JxUPr]OImZgpF޶b}+(_ K $c>6~Ap֣,@XMwd\}Bv-`Z\ku!ad:4]Z(:8e/\sދ.{7'_pL#8)|Dl.6o֙V?zbR&3.>{F] 7*?]zo7Sd^_iǣOՇ[|##c7{?GDU-~*@1Q?Z&wٲnQjomn5h1*ۇУX{J=<0PKzXQup^[bsRb)Bx!ޣ <:|v)]/>^~ϩx'|R>~[ᕏw A/QgUc*#7 J.EVaa}sPn?=c:Mx)C)#7$'ƛ>hpXv}JNqS(m&!KbbK֍$ThM֯>Y!өJǓdo ӟL "ӍTSȶ0hbgރ3`9R9e,^QTiz<`b5YfY̱4y ޜG]kz DMqF5PPK'"n,R5B3}D; c^؃iVrA]hmS+V:)i}1":֪u֩AF #\xs]1&oz0M?mQkHIV"9=dtg>ԓrH}o:s|nivKB=UUUd5.&!RCelrbHFA۹kKn]0XN_:.#W1j[Tiƭc7xG8tU6 0j_I<}ɺ ^:7+x iu3K{C'@NAǶͩ h;n*98<&uvۻlnvנ9 i/7BuYxZ J<f8QnjzH&ʼ"zV|#([Tҏ}uE>1 >Y1OA iiYw }#ysǨ9;"'44,ªfr̒Pil~e@<)eA'M'%e"^2:<-a]kǏt|XL%O,W!D<@L|0ڵTy,O2%r9T^MbzMSk"Cimy' +Jt'+G>ɬ)[kGUAlE=밁2EL]7gRhB4{Hfsu g%:c5Fp<-Y-.Sphw0Rɢ^{k~i^>y>9NRWw/m-k0z/d*bRY[1Yk6H%WV_ҁ#bĆpk6Y}wݵm߲7^ƓAZ!};.}0u"ҾONW?Bh?|Ts & v2(гC{y[;滱$YOۻgh~9ޯ:A9:GL~ru;ty`l@G<715Ccv}0~HqT` fĢQāAIg`*Ii;2Aoϑ`{@!p̹etIԨi2F{j}d:ՕY'?~pNYr Cu'pg;t 99BY*T}̯'@`p4 #VP…(9F6sc!/Fρq3ҵ-8)pP<"/q[ƌ(;sߏ&yxv&I&f@~LC@(~Bq)M=_8֢׾|Mi{ Ƅz¯Xlä~,Xe"`*FA0eTqMX1Usм-Ъ4Ѵ-.vm\ mHidã13Q#YUM52cӵIAo8ml~bAm;m^[ln`N ¼R= &Y,A-%݁U9|LI1@Mxd=_>ń.3>{@ O? ~c~ƃ5<-=۲a5=Y^uSN){/|H_ax~0Oˋ粲'|zg K?闿=oN:92.m[_>e"$봪knmɈ@V.UD+LQcȎ"*I!XU;lUs=U&Xc܏N=ia;{<߹Y;{rH&__`pY6j$㆗sj h/[(gB?t\2$񵰖<vD3xs.|W|7*Q 0"f=D 1BH`jI]vƆ/8wHI Hrƅ[~H³_uQjK/g\~WY+ ش? 8Z$_imN=>K?B5/MiѷH)W-$r~H zr|W>BoZCoW ?#Sk q1J΅i75>"|ΓaL]Qu dZ=^$Z,7Ta!Vޛ,څ:3蛐M)IS;K{x!φ^䦓>C7Mi.7 mKN^VNp&ml B~DO[4t5._@d?ׯ'GHʈqbG5w1yx缲aѮ/S-8gp8scf?ZV8>8VF~-J]]D9\m H35Q[;M%ha1 _أ_>3>E p:O|#/?~^8! HźQ/V'<ǟ}5y{e ˟V>}~xq/MHx/|v++fw|ϿDW0hxR5H?wy_D5\spAv꯵} +%~ YIc}YghWNY(YT57EY~IIPatI٨]jH _ݙN$w1ρ@*{?o7O/tF1<GjF dqؽg 2 lu[8\۠~rMvf\XOkDHW+ܘ0.GaMj7ςiW7UUE$mc"(3hRڎF^#Q0u t!AJgjLʂI1 `ÕNEYe 5w98 Zc&JȔ cw%cDVlƞ*Ζ5kЎͭ@4Wg^Փ󓎩=(e=qi=x! |@_ nm. m{t^WWp[~}uyRjz zǯҷ|/s_DZ5_mVw\ޤ`|~o> ͕e˻ noEU]>%O/RƷ{1FYr]?~Z8|Q[\>/7g/so#_t~/| |~] (ٽz+>rݭ}y?x<Ífߣ1hNNk#x-M8<1J~*zYPlETtwFI2i?эvJfe^Oc,ʭp ^KPH< ܢS`](N5K{ڐv|{шQɞy]% BWiz.k=+ ̃JxυЎ3$4J`wÊ0- Sb]n\8GR5YvR 'n\̻9~@F#᪠['x@kR뎨=$ޱH{Kjøɻ3)v Fsm|n!`a(=Kw?Gj*M )VьNCk7I_O^ 7Jpv#?דXغ  cw[`!ߑd7NrgA0ȷ94v0T`{$` !JXnJz^S  u}FZ.ъHT%1V}UW\7 &musfK0t^8d5<c7 *d%nyB촎p( IDAT%ʷT x6VX:2D?YAɣ[|H巂^W C/ΝX!(QvL"7 Yj._KbLF'*JR /~|NgϾe^~-x~7"?~L~R}W| Ǟt?;^ç@o/}緌x7_=ї]+;?+gc%Z7-t;OIo0z&1Vyw-}IY}.= y`$߷-,cdޕz7Ɔө[Yjy3x3?Hś]ر InY%^bU.=8- IF.jj$ȎjfYiߚVrR[?݄u`P􁍢"4KnπjoeOuL t]W?VenuBELԬ)t#a{lTe?3_GvO%?lZ^h0kf:7v+ю +*橩|N"$˹ӵ@$4s`6%M;FN}5@}r{Nt5Y⺄9! VC;Ip v"3=cJz=:9Mͺo) v(yC@v7 jf尷}sW's8ˆ740ot5.W8cx|, k?s*7N=x }. {Ko>3w/_W/|яo:Ǥ')X_yu]o.3>T֫$^Wos+8/~μjr\AussN!m56º$.`{aZv*쉗_o@RiRIJv1Ă)ڣ~Cq0nqi35@ocF}?k`?l3ʳ(}4UٟŦڷ@[z~Cv;- 9kg &1}|vא$yC|l3uaxK/_jFZkzۚ 벶AVvH7p2Cb|L |\4 aWb]mƇ]ocGT;f)gi;fFR[= kG Cxc(j$[>t d:&N&o\x`\3 8'!TxWU`:6Hʓ:Xt֎B۶mw 3Ix68v7;`Ǧ$wQUVXC6w;~,7rn*_ۘn}w)&Ex4^/*{@\Loy|۫~/~g CN/y~‡)Yz>;k^_WY_:d92CAzcz3v;o|_{t?oѫo;?D6m=zj)Bë׾^[>蛲nVr3.oy.ߡǫ> 95ˏż>xɺi?+@y?j/zS.o׏2M~*:0Ik03#ӽI dF5jj]~@:GyҟQY!dr[3)زaχd3oi_Xˠ&Cf.NM.ĢqlgY-|;|1/ϵ$Z+N`HήV\:XL\!9/\ịrW0E, ?Y%)Igp&#J\` BL>ju*qs$]TX x;@ ͇$|T?3i,ɑA (o݁H`z/prebw=lo2S訚kTO=kⰕW cя)s) Vx+W<&l :4m7/T!/85ҹ:ѯ=[s!&/I\M]5q;"tU`?)>w~՜^qR oŮJp/X zbJ9G%|h`sun-I4fBzN.,MYQWh2{m0 )G #"LJ[iGĞCCq֊}|ꠁѷ_ tgsgLn1t(Z/:+g,: +¬4.;&s; gT(z:GǺ`o߯ ]-(CZ]|vywȽo{|DyXe?JP0{4| 'qA; Z8+x/q*7#lwD_6|e[>znFU emn17~m J}nROv4I]W ?k1y,ւ?>[54cj5Dm㮰ceo1s sY m^8l0|ڝ%nFЃ.R·*FG*Bi~oU,Ne^kLf9zHII@,MΣ2hijn@1~D1o!n+ͫ=֙yO"K`'|W ?0;Cƛv0WG"aU躼c~}h4u7Xw2fF-`h*v?ܼRp327"0) HE!\ɦ5&zwS[gQrq6GupNL07Yo!9wŲ%tskMcODc1j\HzDsqx6dձ䑃3yFY2CMWҹ _ m ^]n02,=ls|,غ ]ǯAs?&藟ui}Z`E ϙ#?D0tȩTM\rbUT*E5/쭼bF9~tJ'5 6)1=慳0Zik!Ru \ʸ͞鰀WCx E&ƩpݒY%Fdk M]mk%hA5cշ~0F*Xf[JV(R{aǂQ-Xyo泽c6$i1=#O9 >H!ggzV,ul9F4VC>relO} 'H\]3kҭ L րŮC{>>%'e+kW p"g0< pC(d!';#؃6fG'4.`w|l7|Ʉ-^p#9b9fNwiaeqvP506g޶5XYwg|J((wvxZ#7:')nR 7N&-6Ԍ"$ȃ+>Whts Pۜ1FCl#ZsA/ >#5|t's?PXܚ>!3nۉ<0 #;e>qG ne2M9{ZU5@mG~Y0Bt'bѐ;Tϭ',rtby F<9w0M<`2 0WM^iIrf"ڍm2|.g܁÷qMRgޖBn* хv7 ߪh!ՍcYvV]hev$h+Nkh}ԉy Z3TΙ 0`6g?Ce0HHkڝ" ltg=8nޢ!ym&X(XmR{*͟,CsJ(3 Qo:ôg.JK)\|4 !e4K܆U]@6F掠<,<$tc&wh(7208YU`6aS€(5Ww:FVgTF /2=kͿ`vp9pYQٮIJ1OkH±jc"sYμZW2 qLL,)1MC[ 6D |xb⣽hQ_z͌+(SdNaș\6- ϡCnl鰏BDL_׌^MrbsNfd1!jz7x~ݖ\!ըrt\qKvylrݞFuNÇNINɞY:oImᕽm<#~x'&?8 (k: 4lD]eyEraNWd;&qq$$;hߖM8di }s56ý}5cdtp]jm|7R|,R˫8!3(Σn{su]Mfd11(Tn.<Q=jXG:b;pNY/9Lduy@ ihNL60 F+4P2rI¥wi i0 yX7%/US 6՘pјc4q]ˁ@N7 yqoZp <#Mj1.bam0< AD&g{0.ǴsxVq=C q~#J^EaL7Q46֑s)2(GX/b@ f5:p876Q+ՍX*Uhi'^rx xqSrV1D^^Q m %(#1GJ.(I87'Xv _XX t^> K pD7i ec[XdqW6<0Hc4gdákT yz}[Ӽ{hWs櫞OK'y۠m&NNSӨ8meu"CIF_ؕ[_GZ=RQ_^k|ܙ.T>+օmW&C^; I(gkH`ajwe)|EVvkᬢFo|U{6\}j+ RYy-. !PWVLDqp 9sv# ݢ_z 7˘0kXdo,Wv5וP_iomHn۝z:BۭŁ\Κ}l;FLjqp#A͘Z"R/OE08Q"ч=ju3\n@HIcM$rvv:M_Id6 H,򰌞 7_ȑGa>|`bB0#$SfL`ᴼqT6]$_IIMf' K쉃RiZ.F>@;Ʋ1|{jzsw썧(S #zY} :䱒؁Ǭ3$GIܶD&EZnZDz'L{8|t{ Lj"f̓<9d-me:ի-T[zT?yQQP;LSвDlmOP,0Bbz3|ߞE3q&ȒҀ#RT[5 |0RJ<9H߄7I!o/4إ1{N@05ߝvf8)&a j>RUN *ѢI\bGj`Q 5`mHxf b7|aR83#9[H yъ+:uw9JtVMŖa9qGi%|҂koO& IDATV뺃nj[iz<biGT8) 3GkT.t+͑O!I.51hL3UEEs:0j6<޷҃|ǦȋV Ҵn-16C[uRأ;!o-Ix@h+uS, ڥ6gmI GXB O]Y<})Fpy?kj .wO jnM: K2ioK2o+k,66Ɩr>}-XZ_פph"H.h|EPsMBܓd(`Z1lVT0l{1+3TJ^>D;N" v$s:hpYBsuV:axţ<7(|kS ^T6v993{3@Tx-s юY랾6!}rǐvѩR'/aUmFd C7cTd< 9uweDV)hX+5u0 k'kr_^]adN:9rffv}n׮ʴ)N2ۖ\.~zu-( _gߔ7lK5SH +n,ug=ɣ&=Y8(&Қm#'m-?*|cY'.${r o[C(܀݈}Er8=y¨棷#r[5Σ.uƆTD;h~mOj:cx\ ilm늺A`Oз,'%eu4Z] I۔y#sf{fͷQvԃcVkDrDRmɂ rԎ'2b3V;(R*QQzҢاz;^9mH5F; 6iH$Z>hIÛ~W&+h9M!SF~RLfa`Hs ?z) b ˃|4(372Wپ TO  `°ŁajRa.jD9xd (`Q]jθ"ZG_XiW|CTbJqFm/Lk cb.%o%)yN!11fW)~ܥqZ~xL3 I?2ExψHZpLox rDH? 7ܴ&nZkM't bDߐI3t{$eBQKA1X: һ?"3:܄DGZ~Xxn} H /&d#S5P'Ki53c]<8-p5b|NLMk.VOW&fpOd}T>h^~[s/SX*_DN軡Sӎ]3s'yx~sV;c چ Fɩ5R5%'ȽT|>:R(t>J_5MSt؁PSVTۺ>!*ahHT9Q5X8X(2D}2}Rj  OIk9Jh[ 'S2SoT]1@>{nזRz(GE!pZG1 ҁA݊c[ MQ94RHK.߉bp2)>TVf+;݂ ԶÇӒcU¯'o=Vr/G* ]SebFv~ؗ]pwSe =`"jl`>mjdow +5.iagM=jvp!u:YWK;qu4!KSm8Σyp_gt#f5.ޥُp{c¨Dc`j֟nGw,2(Cm/IX߰n6tkЉ?A'LR0R*M4}`ȳjq 5bդ9HOFqRNĺkeR[7==s5&姄kgm+tye `~&=0Tb?L9[#l>Q.Ewڛ ڵ52hWY$=Zk(2l)u-%Ex1bfn.kZ4F+EE.YH9{%'z)o5( أnm6 o{brFۃ*m/{pGQu'$*E:ҤH-"(H4 4AAPtP* KG:^Di =;;{끄;ۙ;gg{v=16 4P*w9mu=b6hۜ'@M14r1@Uve@}E86őd0:}_ϻKלL u,Zwq \%cTaᢜE /Y؉_ҭ{f6 :bFC C;K>JnB-W諸fL9Ŀihq6IS+jC=v]~4 M?y!dDm]Nϻ4QdF |Cc q<R^DV!K(~÷V`gUBR|}K̒liS sQ$*CyҰ.7P7H;cx3]}W8ΔJ^-]eziоLdbG$vX9gGi8ax-8?!&Uf |hM^o:&N'8X$'ӕ~i8%iIHjËu-Ѡb y[4z_7jnDMMXa@S8Rٰ#`C3;,LyR 6 L7"ş\A˟j`50!:jF*ڗ- &:'3YbNTrC an?EE7߂'Li;s* Ǔ>9bh/f ЇKx% VQBss ?G6د2Vy4TlA R8z }+UTMŁ 6:6 g:و222t]}EE{{mVR1{j+d(dh9V`V`}҆cv(,QYhHZN?@ =+{VHo2T[Q X5%8i{6l*px쫲s$ޮ|+;1Jߵ8!SW'o۠Ԡ<+gRPY1}dt}Ӄ|D^/|K< =d,5K"k2\ ¾hLP0Bq~܂%,XU=}ZmlP\-aD^!0>"t3ǣƂB[y~V)PΝrR"J`C-F=ءU*_Pn\Q&pܬr3B,Cs&x(oɪ>e<+q EmsW.wJRoBb "G]X4ݿU|B-"Ž.N-MDFq\c$ٸl BMo*eI ®EO:0DH~zTlGš4"d:P|z8 &A) )-7s̬8VdW>Jp8f$:f$]b!u击E_LS^i4o gZڼ }&tHvOeK'" ׌ppTJ6:r";MSURmK2H,d(^kϷ/3֮mݪp <Y%ت 3no mf=pTeno.!WP)6|>>pfF3Ҥ슮Rd4>/UjȮsTV6?T[ z3&>43[j[=ΥQi啣 v.0tucXxEBVGqC{]z^J|^ RqyT{ܨѫIU zt\W[ȵm;0(>hˮl8^-*oyX5QLL24[UgkKzhZ +h=P]uej,ƅh'Z~ V@&*++`i V ]Ξ =&e q0T}@L+mkB1OLJφve[Bnh s tT"FCk?…lJS{"g8M:=(^?-ṩ05$ǁ"*jnZ4Q\EU_me[8 Kғ.dC:@`\ uBLk+}R(dzt ;Jr9$iV}Oq3Wʍ}׽3-cA}#帴YF l%HzCnՀsFo iűue-$h 9rxbH smtjTeFVWzoy ]wlY-WP!6:Ϻqq_ GWc: ٠8flvY)"`wV-uOMK 'J;6-! ʨa_tQ=pva#Yl#Uhhyd^-arAtҎ][sr y]'0ѵri{WTho敚CS:1z>mXo/1 ,rpٵ@jU*|9fN Y%eTw(Z=˶9n-;.|mq ņXe$BCaxPe:`)|I 1oG~%( 0=l&iJxHDAV^jD3R>Y+.l]p,CUKeaQckcuMx8DeKQ#{|R)cJrgЪ-ͣ3RS,-lϣ5 ?He8U|t8%H)7~ ^.2+YPVjN5Ǟ' ^~+<;@?m|> |ݭуCw *4lJ)V9C H"-aޚ]*|g7 A9Р6hރ\5+[XXh`[w],x`ϱڈͶ>vTs=S˭&LKA4c9IL7.FL/ epj$j #]HʗEW #FSӹl.V5tHqX!+[蹷ZAb\q8rEHENґP*J8V`zevTT^쎽YKWf8ga-xipR5X"I{q IDAT6h"G8ʆ6*6ieiW$=7&:cjrSA^wlܙedt[hD0t3Ud=RDTrV(D&f4'I]AؚfmFx\ɧ:hћ;>^(2H߲Jk5B~2=Sц"cB3\Ǫ~bd|aVsl=úVtak)JMٮҩZ_[vұCJI%&tcB&V_7TMG5/f )JChx`<1'N|ڟ<:֮n5jN\9Uē[͚5pCTy9Oh$s`DG-4c,%:y'!D'_Ou-g*ibT隀-H)U+"K+/L/b3jS!ҁ}A:OA u@AtXD^&yQ %oT ]e2&V;)N>DimRƀrsq"*{27! $N#v9^Jsa Tf-g840!\ 8)*cќ:'E)_['{Ǝ*R{$@'Ѫ)! 3m0/i0ZKƮJyI9uDh4 ePX֮Uf+ d,HEӁ| K#M9,fvQdKf|PHj>.{=-U UQNN$ o7;EgFl^U=SPJ=J%CS @]dyqMO8@۪Y8 jp}:bčhL聦9kcykŃBgYjt*8k `d"P4P)z!%N"76;hY CSic2S K`>PG3y"1X2G n/ ',[Op B]G>ڐwn5 Gӣn.tZ37 7qS p19 g;va883L6MI)٣,,{_KKi]9EvG"T \ !ñ#r,/^4G/"8a2騣K_gc`#efBúe\y|VX <7XE.w9n&EYd[}mPn,vU_m~Yl%+v`.:n9aR0ZETE]o-oj>Ojh'UB ?)nN >5Cʴ9Ae1h̻*N"TzuWI{[`" cE nűRm~TS^i _eAS).h@mjͤ|V`blf̘ҜJ^U עو]lkPX[s蚉)Md{V#A+*Rc_f*BNkWx&b =HU9Vx{=5(B)lWqӢXz>EY?Fa-f+ xu3Q]t7H$0lxpeApkSȣ) ?T x{(\yÓ@fƒ[@Ir s|2?T|х- 28YfGZ8#( v0e[e &m|RzG ;t]Ů, suz81r٬% [q?MaI+AiV\E\dsΨU1ľU8| H(4Ⱦr|N"Rڙ=4X~Y@E-:|K0:^΃Hz;\ȿ-`u|f/0j_+l `;=/6 6PI-ZROw47-ApqnƩ1Լc9pbAG^97*MWYQ)…GjYl7.,י."w^pʯa[ SwMp(1:(3TBasnz{GB>~РO\ۗf7{i+րGaePfZk|tKK[0!׍7Z"ybX1@w+jvlV7x%p8Yzx򢝥ADlC7LJbbʆ ar;#l<'S)hn!%AlN*1zʑK`juNw1dd-ʶZ_Ցp_yY7vE&9YvT(hB*#sRy χMz8`<*\ܠCd:D)og続B%O{t0'ducЪ-p,ᆞf9rPe[$1ش X"㡡 zukC9{@"',@A d(0!9-Z04S7- V")n4Ԏ (㙓T(X(#WPf/aZT'َ*s4TI!0]ZИ eO3̚aebPx&+UgoPb&_g_`]uC-Q 9W9LX*mu_گgnV gEMga0 ͩ .-&OlHcκig#ںMG}Xb }D'%n~rv1gas+)O=Se'Bxcs wtCG7̯|PY#j 3 EAv& 8[1AjxT`狝$+D7V2A>U,x_/@qx?lC? -Gd~RiɖP1uYv 5E+H6Bs0yj+-H`EV3E4gP3  x_lV' qS1/M /? vi.Y] 5<<9k%,^C f\o*O^³>F&P9fGF/DH2ةKeeG)vL[>[藰7Pp >E&G%*T;#q!W ,b M8QviWlյ%UfX95D]W1s@|IؠO>s+Lo/ HnU^ǴxnUN,ЛŦ0))Mn5`̃ J[7Yd:m 0(`䅁 ࠳&n1B>| sD]'hZTиHP }dP.ηjzK))et»Jn }ošjْz q$g\EfpOqK,AB]5VKW+UY5 Y)wXŒrF5Vxb!胮4 V1BMI}SJbl &@vȽNf@4DQ"Iy?0y x|Yiol7`n)ئXL'S M%ZU=& <Ȋ1bML1)C-{hV t*-Zd!Մ꼅.6ՋUfi"lXj_C\KB>23 [>,7? 7Fn_i*HDgśL ݙ?Ntfl?r` kQpA6wadXہ0*5o頨<:w]שo#TWl6 ap_GvUz{Xcx2y*o{Ms=kOIUf[|hl7b,&[1Bi#MtPj =X" b8GanIz6R*)2L)$>"|ˤ4sH?^2pE&:" IJEJ2&Ӄ_uw#ˊCfteED+&tC1;o|fAa /Df)+TZ4C^%ٹ&] '$(h쪪P6) fH 0oKS4^ꂭ#(BېJ/+V y5Ϋuqw6҃VuEu62R D[jcul%bɆ"ۺ!chQ^LFr& ȎLv@؁nviftnW8r%x2dRjfMXʑ.(vҍR^ǐ{p\FCڛ^D&u,H_xڸY%E!jHZ(|܆ՄٵhKlzXT ĂuH"Nin~rU׃+oUXmL%Uz̊"vWH%D #jo q3`Bʠ:ه GfcRh-'KuP [0m':4]n]7ʸ5;tuw,㥞{+Zu{raR}+VhA(2:+Xsb5U~|Xy6]0uc)/2s)T>4Dv{av]ʱ ZSBUS h4*IoBVƷff."_u0W n[ui#%6ʡԨ-9Re_^Eדl]FU[vei-zɋs669 Tq? ]599)&>JMTn<=J^Իe(Ej8v6f5r׊{շU2r `W*2TXs+mJ9@LmțU<:㈑ܣ/ xP<'f#)O5EhZAb2bbGR}]óQCje"VM8Fp"BJF/]ӳ[ :nveIRjr:(iN[W-a dR0H5=9pk*gX j451'55rb|4:5uH,.j:mh*޿ N "p7Dl~ i^CֈCz:jA4 %$ 2 , J?T0;uu YNIn+CR8ߵ*7yU=O/eYI7`@%m@3lᲦ<dڽE.h:]9{G!5%lG?9kPT s+qv{K'cV=\$/φ & `B;}qLA1e–,ρiq(zH&J`@4qsVN6g]} iS"b-KJ }I7|S~\jϷ>憛TLT+r~ c!>6ah"zyG0f1$<Ej4=T5DHl!sh^yՋcWUZ2̿1l j1CJLqMS1_{Mg Ct515D\N×GYGP.x1XSJ Z=x.u v%1'C^ߜN6F0 @0 @0 0 @0 @0 @X^0 @0 @0 "Dr:` `  G` ` `` @0 @0 @0Pg  u> @0 @0 @,@܀` ` :` ` ` Db2Ȗ IDATt0 @0 @0 H@0 @0  2 A$7` ` `@,@|D/` ` X " @0 @0 ubR#z@0 @0 @00 d ` ` ` 3 : ` ` Ad  Hn@@0 @0 @X^0 @0 @0 "Dr:` `  G` ` `` @0 @0 @0Pg  u> @0 @0 @,@܀` ` :` ` ` Db2t0 @0 @0 H@0 @0  2 A$7` ` `D]qiHoF= u/zc[MjO8!-Ē'?i-eeh/;˰n8\oxz.86۵{@0 @0 b OeZv5\7'trMŖK{~5YΈ#҃ܟnV~Շ _O'ra6|}ܴ910_xEi̘\sϓVJ[zG@0 @ JzgSO=<#o0nβ{/~iUVɲv)2}OC ig?3i„ iM6Is9g~k\\Uy@=|;[oI[.W?ģԂ` ``d饗N38cXlz˭_ny;6iUW2|ODg޴>$uߢN81Jtɥ?<fdBgxuia7zoM7ݔoI'/{w,rJZi2ˎH?\@6e^K[OO.x:j^o};̷E]w]Knag#Ks-(3Jkq-"_ZBݕ<ēvw_F-|̃kw}f'=O8x>KiEo?ct7'39q~ /Z;yv7:z?6[>:n@0 @0a CW^)N;碌M[o ꣏>Jq|͗O_n4ti˺g:tЁ;=˛KS,8u֙xnBf<~abcg-N86}YK.I|?ȣҩ>-G?b'\:eGffc}M>`Ki>5O寲Y3߬hǿJ3;?Y8#5c970>:Cߖ8>t)fOm7GNO>T׿E-Κnؿ{ynea'i؃>}tWB0hՓ99MP6< 裎JSL1EͼǂcK[l} h@0 G>/@j|}]w\oF^9/Lp5y;X$,]tѴo O?ow4jԨ/|f,w,ۼs-W LsrV\z𴚌{=7㺠yG_W<1ڼ m5H?N˘eWXο9$ TZ}C8f|C}ibpȑl;T3,\sMU A.WA{lۍq}'? o"uHdY^yeR}B7d K.DW<_ZSw*=.?2g6 ԗv!-UW<wm,-E;\ S qߘCJ99uub˴,XٛyNw\El>1` 3L|>*nej7Z&Ջz(w<^ܺѥbe^a 7(W[YdGT& \p~Ů4])1v|.KM\sMkera:ꖯV9,>6tӴ{vy xj7Vx2:}̱J+rL -`뮻n-}knƏx,ZVz;'|ʶcv۵?u5 қy?n M0 @0 |th9xxnϟ/W_g%N7=袋pqs 7ļG6x:mϦ9G^a&(2v /{?)Sݧ~&-B]^ .$aaRb-Z뮛~c=&E JҎ{W;{wy? ς/;6y晛| @;no BWroݕYbO ,0?9( z(b juo 6txsSOeNvsr su8n:ȴ2K-ܒ튻v0u0 @0 |4dU?ᴭ"oi9󽃿|nϧ~759C>P^ߓPJ-xMO?!_|eh[vg:/ȭf[6ܰÀx(B/xWkZy6v?y  &V,ziUV+7o:ffMs4-oOo:PtWz.f{0x‚WFZp[?v8ƚkh7|3iK9WZhEk8'` ` & b2iAOӟ2{{ _{tЁX~WEvu4HK.5^|tG}&z9Xs5җefn{`0dZ]' :kiOkF#8"|-cX;?'wߓc4|kӖ[~0fo4~xx H4` ` @,@Ls wFC>:Lnt 7$ѿ].2aݩ]y[ ܖ[7ۜWB{tM7s|ޛv۴"*rn#G3uiV_2)Gy8rMkfrwM.h2_[}s?\$ @0 @0/b/ٯ ꫯ@EiŕVN;sz^v#oQZk͇njY2ln60^~4S֦fU0 K?O/rJ^Y[MO󟵔6pC.p;(yw{[|4-g"M=4ç;_`` ` ~3W@Ma^zi:y |CW( ͳ/9&Yf%=cqk|4j<3qQ@0 @0 g.N+[bO,!\/~3<$o?*GYgcӓO>fiwۯV]u 7؀fW_sM~oZMb>yρfm{\;д[dN8!-i\7YUWY%]uYZYf%-R}ʱ` ` ?C^_1X O~#RS0)` ``` L) ` ` & &g@~_y` .p6J0 @0 @0 -XVMOiy0~l_ ZO+_ @0 @0 ]$ =Pa5}z;tWXL3Los,` ` ` $ ȿ|sL_~  [%` ` Ir2tӥwkE ~2|6Xdƛ]GN'Q` ` ``$ ͌v]*Op{Ʀ믿!d pÍic}=xA,xd)?8VZm5ҧ4`oC~(B /`%_w?3qƛl~']vDͱL nf rhM=rb7-m `runM7okҷW;uG:ZUW[=p~|-v}חŧLS>]=P;.9{S}cXq{@7\ہX'N 3O~H?8xCH+^)-@f30Cn!×ҷAGq_t8eI$viN*X`pŕW+mW>u]wݕzv&m\}G<&N=唶>Pe|}dMǏ`s ᶙgob7vohOv 7|3$χ87`c7tKzW)lV_m'/be]ӚcƤUV]-mv\ʿra +(WvnH~xZFJ7xc39=2V8|z#u'Nq:G>7<`qA i-@>lҙgfZ?˫Lv+lܿWOכLV'߬jyW\T;[vcD)o5f6vOE oyl~?i`G< L3M~<> n܈4|C.sNkj]nnjQ˥2|i;y+"@Ќλ5eoQxH:DlPftwiΓZkIXt'!c o/~~oG;\[LI}yѣ > K'| nޛ?'e9∟#(Yx Y(  TlZ]~p봟 X6;tg;y_Zj5pvc2TS6Sw j\wdzl7tSZqiҊo?Nq;6NjJ}ڛ x_wm׎Ճ}lG_ŗ\?<3&o,_r33R:[t#pf2rqv󲷱{<;O?}G .4v+/O$ͰO\ D'^x kqW4,fob'7|?R4r.*_o'{7]t_"쫻& SɏӼ*,lfm<̴\ @.fovNS묓F^o|1'_lXt6lXg?6fNSN9erԋFw< d'*(>Sl`n6n?7aۍvd IDAT78wߓr9<btZ{ڼiwmwq:Ge>r{ҬJvJ_o)q;U5՜Mk~_D~0 W'SO5U4qPc(Cc^0e1<̳iLy ;vlSnsU9mXo]v-]~eixƛliկ  依v1:/7@n-ϊxh* : |;o9 /p@[6|ӳ7 `\ztb|I2'<6Scyi,nuwn7tg rˍLr渺 ,H7WT25:v펣2Nquܦ_9l Wz;=^3Ny%V;JfG}?>X> Zhkt7;FztK,D\ 9 &쎫Nu lڍ{'W^xt.[Lf L |5lXF{g_6k?طڗ}R{}[ rIN_X|ӬC^U)~Rx WP?Ig~ ۲ NɧySM=+^|۲bK#-=|r[to]<^}t|ʸ(V! ``b3/88!‘#Gcb72ϧ&M7tsΙd1)&M{WY~%Fh10W@y2Cݟ͑^tѴ#ҴMMziWqxv*?a?Cesʤ_BQ/R|ċv0 @0 @0 ?W^}yc9Қ<Ǭ}i=kӋ xϤ9S fD믥Y++ǷxW@^a,^@0 @0 @nz酗~[~yypx\k=Dr%S =/σTW4 K,dz~`tRtzk)[ Xxd饖!,AG Pl` ` ɜAYÏ>65XNoHVYmt/rK<|o״FrwvWG{}O>dkw[xn gy2×+&͵ US= G` ` `W t}'+qs3/ ..15cȰ[??[+O6t*_|<1t3ȕ,4dU6ī=W=f7skZ>Hz#v. G}L,@>#` ` 膁AY_{vJ}ϥM7,}{+ڕeF,v44۱4mWM:tlC9~ cL]q/@9AL-OHm-c>'WЏ`^J+<:qmV>7t3 ?ֆ쯹*=p^ #,/%75vqG+/Lu_/MesLZ}ՙC&` ` -|1ӿ{6}bFmo!Cq : ) &TW3{+W@O[}nkZz,o?4ey?U+rY <̄ RJ!_1=3&oLv>[/{cAqڹ]v5ۮrʙgdu&jZ~r+\SOI~WJYtI@0 @0 }``P %X2zM\sCzˍiooڛ^{ܮ5Mf[S8^S)"]p7rHՌ .ѝWX!ҧY'r5jl, :;Wi>-wҔdp r aFU⧞zR7rrzSO>vT&` ` [2]pjv=* t/r!W;z[_|ek3 @ 2]r%ҋ/Xx5] Ǝ뮄+?.cZpyK1v>~;tpŕW+[ :l.& @0 @0 AY l.bJҘIͿs|u^-v[ 7e2mZk͵ӵ[滝o]>@p71_Wv%/+~SiޖozOVYv0ҵꪫs$Ho?.F_G)my]^oUa?y×<蠴&gY;}chyvd&Y|!SN>)lȔ ?} b7N.袜_4` ` 00(^aSS-PSțg>'+.MmQ:bT*o1Px\o6G+"m>4_|͞g @0 @0 ]M<~._.,>ʗ۸Īۤ䛾=眉6@0 @0 A_ Hp+/:].>*H_(k/D"WOk 9眳u ut` ` IIlW/5$Xt4_S|5|Pc}jI~V` ` Ab`Y,Gsͫ ~kh_5 cil0 @0 @0a`YuE^£ G/B@5 |˶Ǎ:` ` $+~/>&XL TU t;[7` ` ` h$!b!]xZ| N}Ҟ@0 @0 @ ۯň_h-XXor/:+J0 @0 @0 _گv\ ,T[ӫ&}[{wR`8On55njѱ2x2|8o21NnO&e>V:E*k?{g`UC,Kw,Hұ4 R GH.!A HJ*" ۹ܽ{s[؅3̜9{ߛ3IWផ˜93-\;Qa7n<&*p;}}۷)Pe-ϋgΜٳCM%K6!+8/]L,mV4tP:r(e8+4i]ʕ+2eJڹs%Nݲbxt $oɇnޜiִ#uOڵ8#2nx*Z,r=콸pႊm{O))U4YF5֌0ʖ+OUU)&Nן;vڴmK+U +Z# d8ZXn=:~ӧ3EfP3w>]v6|}1VqJP:uiit֭+xmN˯ 4kծCeʔz 1BGY[NK.c~DoO  ٳg=;=H͛7S ^ӧ!4i,o޽X~iV/ҥKHV_~j֬%{=KnY7VϒWV9Naퟑ+-\HUVdyoܸA=zHow[ąY8^L} ]ϟyOe@(==bk|A*]~g]ѣF"蹨})_&? ?V5k;oMʕs[ mDO2Ee=%a0t12b{|RZ+ c1Fa|N>6eHQveP\Y@V-[ҏ?HюXԯ-ZnCBѨQ#e]ޢ vy3_-/ivxYitA7~K)]t=\{:=_^ 5tճ ?r}+gCl*u?(8ILlٲQڵD%-ZXK៿Impp0կWOǏ#G4$mڴ ]V͚TByYAS/m۶т?['{D~ A ͚Q6mUtˣnKDZVȊ>8|ҿkGPPx^:yGuwމ:+% Zue\9|X;?W\T'iɒjҤ1͜9%87zȀQΝ;GB{A֯_/z)^-T0|y kguҘٵճ䕥{ESXTNlJ?͛eիWk8q*w0N=4$]v2f(Y<ˡCwLB }R(yѢ=ho0\&N-[M˗A]-iO6Y.]^/>B8͐ݼqz͊5HJgY#;gUb?& x>h9}[5rsG *Q}v$e_0s+z90NCTre)* .UE["E ->*琵Tf'Kf*:-+0Vea*H|Fy0<c5dP7zX4޿&*vۈ%K(DbUx`KX3zf{di,yei޼gC)MqNrpM:VϪ^U˱*@}w5oL5OPx"\T27^Brިwwkӭ[WzSgʛ//ȑC~[N/c<ЉuRv:X=kV^(V @kXԂey"˽o%ٲ |b;IaFɒ%sNvq 0SL~ŸTG̉P:.P!toG-fyp#Wws0 &yaUVF5ʘ.tT;VE׎;AaxC9.+a2'xB+#*Q>Yfj\ɿKQ1=w^YZ7^8R4mtM]7I]kN:VϪ>|9ɇnɄazia|Du>VmZ>{!p0N?*cǎ瞧rʛ^>έ)S&o> `I'?IUq 딎ݳO,_𷓏 z5ߴI+_M3b0V}&a ,a7=[ Æ [#F\ǎ1QpuK!߫^ѿʟ IDAT.=_^~tzvU6~Mc,+@ӧN뷏K-X+X ĿxTWi 82~TCV 0N`ID͝3>tmVjC/2O4BeΔ(dd3vN4 pHeL 0&`Q[a6"ĂJpĉ `?vL 0/ -`L 0&_/| 0&`L 0/B2&`L 0&6@Ǒ`L 0&B /8,`L 0&`~`/| 0&`L 0/B2&`L 0&6@Ǒ`L 0&B /8,`L 0&`~`/| 0&`L 0/B2&`L 0&6@Ǒ`L 0&B /8,`L 0&`~`/| 0&`L 0/B2&`L 0&6@Ǒ`L 0&B /8,`L 0&`~`/| 0&`L 0/B2&`L 0&6@—"gʜ6mZRA۸W\tȆ++@;vٲSrݻr4O{o ρ`L <y@%*㹩V:4{ΜOVEzɚ5hR !` Ri\Bb!e=_'F4fXhs)V]D:t(ݾ}vB%róRiW_]@L 0&fI%8e̘O[nnݺSBxHHBP? :A,Yc-kiĒXǵ2r?էˬ,X={((Y2ӧ,۰w+~ĉS\.]:U-\>l }r@&`#yRϞb2Zz:6oެiuU7.|}x/J}^=;Tx[fr i5^8vd0g\-̙…Э[}ͳX9ڷ|խW:${͗_w'/|Ia0gѼtFuș;whq 0&H xXyrZi'*H&N=!zF ҙ3gdK/|̘1~ʐ!;#eVY )VL6+W-ZŋelҴlEJ;whսf͚RӦM;wDC_&L@)SJ]EOƍt2-ZX LʡF mR쎣 7a5'OBÇ(ĉ>}zaXaHfexj8jax,_B>;RUJN-[}wZ<5oNI:c)7LD# M6Q&Mi0SH.{+5}׮]+K DtFR2ghǎ|`L#.O&Ms?WgiOժUZ[PAnZz5ED 7BEww%CKҖ͛hߩ\k8&* #iʟq CGU>xy&(PnL+^AEDҫ17=hpH-(J9sfQ_MOh![ʻwF*V˜=zTeMYfjAC=0ZEЦE }=@0~cgc˻]2m۶Qmez3Աcr*ц^pZGܼ>+UDuU?h0SN-9۷O>c<:@ʥٳwv'L 0&El] pR*Uj G- }݋=zH8W)w3̤8q,;M6]:W_{-Fx?^>‡?s2Fh@b3DJRƟr ij0;Yۢvƍ[Bp⦌TL 0&5lģR7rȬҫB'qR%~bHo0R`Æi>lN,+zGߌ//FPLOTf 9 kSL,A*^t!\<  pab8i"PIǤa+סórna' ѣGQ (#?I!!ŤT3-@,N?'6E*ˡJʄp(0MY  V\senͫQ΢Sqm=-"tr[zkKTc"rnt B,}D1&x $:}oPL!+Ga>\>Ln8*Aa~+9 ؾMdL\۶h0v*!Ka9Iyq1&xX $}X3bӧ妇EO =Wh~7J&Ml޸sNYoҤq3>rX>xԩAnc>v؏ 0&  .aKrLl:-C @7V~XX| C"SL bcL 0&= Lh}$1Q7<[tXMceJ˕)\`L 0&= ٽw7NZ|RѵWx{)+tE*RHlEq<&`L 0&,$XڕwF yiRώ 0&`L 0HH [7,i`ùW3kFWb )bvL 0&`L @4@:B O]mNk֬gI/LX_vm߶vCyr:k%k6_eI^uC?j"ԩSި1xx"}v~Zrb̋U9Bc%<3f΍_M~DVaW^wbUtND~6Z.UNu:_;֋3I A v:̙*T,Oyz/]D%QDԩSի(rZz[oݗtD2gL ,HpYXƍ?FV~ZrbKQQ̈́/3AP߯y UVMڼy`2P+w"Of5PM$yz}r =*^XsX& W\b~\4i}uNժW*6?;~W=Æ='eʔ 1jשKJui;Fmڶr*TD`n؏ͷiaD謼g0ʖ+OUU-&NdO&M,uCoOh޽zX+ġU֬Y#e+?U A$:|Xzg {AlU.ʧ7x!TiY% ]?dv1@\OHG9c^}+7_ESX0mI*+T韫,ڥc>gC%h/ɇ_-ƩtVeФI9k y1Jcvl{qbFYf(dSLJu +v)pTw>~{e}<gWk۪ Xx ɓkkb0l+TIzh{x< .CuNZ5WӆԴihC`@=UX DDlٲ|R:d( :Lեk7& YNn6XkӦ5͛;nͧ#ª58;=4b{2͵;tڷo'áQo\J 0nr (@uˌ3!sHe!Q,]>/D1;^wcƌC8/4ޙJ?ij{rqn/rvU{P/IfrW݁;,Șhvaqz vaGFFR2e(2(WOd¨[ގds򥎐gzn[D?z`Ԯ=3a쳴p"aoFbt]YY5B =or=TJ<$-YAؙz̙W9 P{j˕gbxO,pC\Kz0vȽ^%Zh!+K7o.e̘286S7kF۴3((Z<}XĩmVϋ^pvl{'6nu>VyrAsJ\>c^bzfF]pO6Y q/!z:gH) 3| x 2~pBZHy"^T 86Uӷ/}駓0dLė-$I-}a@̱cSa2 ;=|al߾6%uAc'чa]n{PĒ%RL oؠE`.E9pQG9,Hwݔ^T.a93Egld{cmyI* :=oFVyϭ^Sfչߣtg}Vr#_/Ǫ 8^0~"-Cl$bxvi`L 0&`#gĊBVDP,Yǐ3cR˿(3 oFrd$֥K)XJ$_N$&bL 0&`L . ĉaWgODzJLحa5~;:w]ѓaN z4"QE8]{ϟr NLYD ;&`L 0&▀O..z?+uai|@Lr?Qb!(Mt9*TPQ+Šŋb}E1T0&`L 0@ yسo5msUhbGP[Ŏ;G>r N.MR zGĮ rG];ڵө3GN*R\N'㣴ǃ(,hmZNrl#[xu6TNhkC56p;ORRThQMcߡóϋx IDAT-b8,7x Ӧi2qVm1r7m^Ç`YNbIdɜY>{ &pO N b֩Q5!*V% ǎbzJjҸe3gE1#UԢ'+"YV1qATI,[zM<_8־{iןRhPC8|NȸqcmMIYTa|,]rii| jդb#GZF΃b%gy>h͛fkצOgK-YCfϦժ .STe8eHŋ! g8PA?Ir/ߤvɹ؛!K/SĒŮ`L 0&@qb_XhM_?)MGHԩ]+J!zDp,:>vuU|orMn;~GdiD@ ߹sgsd5kjZ؄J*RI&9sիbb TH2A5} wY*Wۯr'sߗ8Q&*(pVi+2*ڡJ4!gX?|݂-ʓ;K9dxcǎQ}e"+W>:!_K׮]Lurʻt~HW()ӺHj٢]40kы,OCڵlج F}:Xڬ8*/|IV6UJ_k DMd= x6{c߾oCFInݺ4@2o'z̘lW:ԤI9k&*h9-fFsafyܩL=z*ozףo;wQHH1MCۊ9s7݁4wwTU74C9l=Fņaaaʋnj;h 0&8 |dɒcF&O|bU$BsND?I96DZU;=I[}?x#*]V,_&vD?Ce˖˖!CJdukŎQoK>+&/C-poF,]8 4ڴiMv#ªݠ[Ԫu+jڰ>R5Ɠ.]IaGe3XW9;U^:̍ӈI`D:v */h;eW5YAbj,tU+g</)=F_2}xXC 5",g(X]T8bVZwyK Ta&Sڞ{\"7s<#K>=7lHf}'h@_|hA! Ml$J#G`Vi`ob%չ1͜9+7dڵbIe̘LAk۶mr(%N^C_e6NG%GIG/x^2iJv_Bj֤ KezFc:Veh )Sdr^mۿ&yf4}d= eVi<6z˜tnE;XBΊ5ˡCSέc8Z==nQȱ*S!=#'5oFEC|1HT@죤0I'Z<,w}<g(+кaV~1歠Wi}dݳ&tBEi޼لvڕٳ稤_;: Yao?vR'V ~nސ~HwH#' T##ɓ'גXN¡ų[b<9c޽ިcԙKiht'HS9/i<# EcSaR Rk,Zjt4%+Iz/e6_E߾};mâ &+J8q*g+Y,7~x'͜xV'}2QJz< 1Ϩ]ZdbŊ.y("b)}LAb? %eP d z.g?3&r tг5t?39lE>U|dL 0C j~pںu }1} u`ƃ 13=@(Z},e\jM4#+Sq ^h˚շO_b)";Nof) J:*ҥJ*9(cdع4Y/Y$M2U7ON_Ϗi$VywJ'SLR_7{RZ͏?.o/7nzsA+ϟ_T@#d j1z:ŋ^ 7M!q9JҴiӵqݒ #YYPȓ'&_Vs`}:Nvej73r5Djz!Eoe|K[l&|-\HN{>0@vBCXs|ҷ:~N?cݳb3_3&!gHR1;w] ((Zш !Z{$+jm }T$bI$($NNyt8^׸I$Nc|p}5n&Mja"3*ss) n4mTo.iS^L&&4cU_ իb~Z. }6l\ֳ0~z]1=NUV' ѣF91Ű *ʥNNl20~ K $ 1s0GyBz9.H*җۙB(q"_1"-1'$YJԆp!Q\Z|)5PN:G%8sbա>J̣w=pO&Mub8Nް;X"zyΙK~3Xҫ! /r^rӳsH8d>ccB|z1dK6$)Ibq4z`xnr[| %(q4:O1";P0,u6R Jl_~ߕF;Z?s'B4Q$|2=>\hhn$Ϸ2n,˜&@ = `$jexsL*?B ZgH#F ##+CL, !1&`L 0M {@}c`1C`(C#"?0<' z?þ<"1K` 28pD\e(Ď 0&`L 0WiDs2:1\ C0B0,čBq.!c4@G Pd*q`L 0& c(F00a4B$A4"I@+{H]u.o&`L 0&B  nr^uo]1" ٻzBV0<o EN/`L 0&-c237>p.q{ D#,_ )I41‹n} 0&`L 0HPo00z@`Dseô|p,c;B#)G1sO?L 0&`L @d`4Z,{%Ct~ȏo._oq% Sqd X> 0&`L @4@!2ovё uK e(?#@$<`L 0&@  @gv̅p2k~2eHѢ 0&`L 0K.z>aP,ݹs[L*@tw0Z`~Pmq""3@6 | IJcL 0&`L @p}u0.}WŽ›ݏ~d//iM60&`L 0&; ɗ7-ZHNʪ)3BgC]ua̙68{2&`L 0&@ӧNlwC1&`L 0&<H8=e3&`L 0& KubL 0&`)6@҂l1&`L 0H X*`L 0&xH  6S,dQ*)[n[~k֪MիQU(Kl/tBSNQxF~qqŋq8ѧg?ׇϑ炅 ;fX~ ^yU*Wu'n/zLJ2|y!KX;=]87~7ÇX]gzޖv/w-X]+(h ?Qu9K VSNY&KSyUI$Q:b/Uի4yg2gL ,}TƍO(N_@}m Tu3gh9tASfq~M {K-˨TҴf)Z3~*[Q ={V޳C;ټy3PQ5}:I&K`̢+凛VaQDkשfZLѳ˿ >}3o,yeixo3d/'9vgsv=UZf|Ϙ=iJgUM4f`% Ed~ZnMƍԣNjo|EK@\͌T~wKWߟ1}yTK3C+vd{ɫ ~V:م܏=m$*/+ߗe \lZf-T\9;wpFt!SZTvS2PC ?.#FG˗-@Y:v#ntS5alX)zZXWBZz5rHߘ1)uԲFh\uA7edAe˖U}FW^Ms-xԣGwֽ TaTRb24hHC!CiqmӦ5͛;W!qV2d ;%uW݁^AɂyoNn-~5moV~VaQ?V.煥>}3!Y")l]wK={Yؕڥ1cH*[eWʕվ =oղ%㏄툥KAѢ:=ЭU6T,5R-pqa7cXfgFd}(<ҥK'SЊ%P:^JY=3+wܷrV:ĶL~!XrӘDʖ-ծ]KTrKТŋ}(FM[>a% gVrtʿYF~f^Xڽ7^86u|q4yc|XN=;WM(24!Kc实=_zarbvyӳU>lP1\0B`k/iu(#5 WM‰5HIgWeC_7o޴-/+?ϲҍL . $:}ꤻ~Ԃe"UN{\Gu)B#*:O5dHDD9sO'f0X-k+D#TLo_ߊ@H7`D!\`VZ`#B,8=@d> O8!{ٰVcB{@L 0&`L E{@Ǒ`L 0&B /8,`L 0&`~`/| 0&`L 0/B2&`L 0&6@Ǒ`L 0&B /8,`L 0&`~`/| 0&`L 0/B2&`L 0&X` IDAT6@Ǒ`L 0&B /8,`L 0&`~`/| 0&`L 0/B2&`L 0&6@Ǒ`L 0&B /8,`L 0&`~`/| 0&`L 0/B2&`L 0&6@Ǒ`L 0&B -ɓt7%2dB"`L 0&0#Ɏ{nݢ_ !g\obw޹KʔIm/`L 0&@4@vMӤTtU௃1<8]t.^HE W$gL 0&`L@ A9~J.-]zܹ# ?yiҦ!g`L 0&@ $H$Eʔt KwEի5#+1rS `L 0&<9!qba7 >uVJ,]q|Iʐ!=aƍPd:u**d %QM`L 0&8iQ_3gN*P :t0ʔ}.]D%ʉIX`L 0&`CJ+I._,3d Gn .{OYiӦJƏmX)ɑ`L 0&) *z??oUVRȰJ3+ FuէaEP|%K-a>aL 0&:7zRt8`rs?.)?Ѯ\1e˖2w}E[x)ZH72GcޯSϚ U?^_vy3m]jȡMիioٲE;lj"8\8k*-aՏ?V  åKe!*UȔ(Ar婋0N9LnWaaե{LVG-o/i~|`L 0ĹrWT]F]sgѹrc@Ua"͛$=f 'uԔDTћa>1iRPa*y$Izsg٪~_bR)D&/]Բˆ]ƌjGNp.]+D~ffS\ Ô)SEK h.ܔk^ Z5I|_F͛YI+JqQ)cRt>{3&`L@u (v&߽{'u>}J*9S_(^RLAI P^\tFk.Bkr,Ye\ضm|3?*Zr0!W_я(CN04͞Mv)_ k,fdi4i]c:IY#R ʕ 0Lmлr݊+DH ,ƹ)-/)UƮ]$?0tN]2Dt"XN6q{ߩt1Z˻QG_n;*.]{TkԨAș̙2ou,Cз|-+kĊ]zIE>LLuK;D+?z ֕A}*W2 ((aXIQc+1&`L !X0$#<ȡb*d|Y\;vc+B'K&O)P+یwqaڹks48Fv!EMinx0Il|x`L 0M N b֩Qur ÇĪUVxyk.&&7;s ]?RL-zBz-cV^{jT;!17c/;zMn6K&7r<L 0&H:b>?CÛPWߡiWO+TxzEkS'îgv>zb?%bC;6@b$ =2&GcL 0&@''Hc%KV:ߔ'o>[J*̝;`%I!q+"*Ki&RZ{`.rq;owKݶZ8 [V`vZ "ܛnflo aJbժQ*U駟KQ{qNFz(c7:bgƅʹv~COc#MiBW^}ʕ@:>5*| 9%.3 Puȧ>?ƼЇ5ݏk'`L . > Ja̙H4HMlH{ܷsvՓף؈ƍdqxbjX!8Y8j]J=$=W=05[$7ЫVVw8Yb%TJuKY8`/AUTR2:8} ˛W_ET2]?}=JժσJsxOqAyYtLG'Ny0r2IȮV|џ+_6.tq'$-uܕyw( ]Qhh)1+C:O8)CxԳQ+Z\.ݠtXb-8pcሥP񁡄fJ"wT̼cuI`p̙S6mZi|h7{bjSҥ #uҐ!CgOF{Qƛ l'=2&NO>CݺuTRej۶%C̀?8d^>}Ů𗨺#8*_7o*Ru$U%g2un&MLao޽ReO1-URW|@رcǨM۶_-j~J*fܤ?ENG{(e=|<SaV-U&J8;VỲw>Zg΋Mxܔի~J` @ (6&q(>E%s*#0@ԧj[Խ^Az8d7*={H6lm۶QWQ1Y߯Փe˔Gh)xj.vѠah{Zh!;ЅjլI*-I^v`$ 22SyRƌ*=bP dt,ٔ)`l͛5mja #qe PΎ tDEe`O2(Zڷ'#gO+nHS/-[Oi3d ҈Wϝ&\ov/'yNFVybU/n/='c|kѫΝwot_/WYeܳJI }//Ah|sSх0& x(Rk(IAR\m@phAvQhΕ*Y^&Ӹq# .zsr؟ĪGPP} auЫߏSrϖB:8y Qÿn $,5q3~pCߪ ZWYBU͓'GAEj1-{6zN;ׅV\,Y\dIܩݿ?mܸ!P )T?VcN-!CpBwhĉUz]F[6dz:G|)""BY`UPy/^,̝+cywQ_@ TBoҤKキ*"M MDP@wDP:D?Ez;{o"5@̲-\B.egg޼ycn4e/*Xj IZP0q"{y7c9cE)ST,1؍+l7bd[vr/e~LA9\ VPP}:r4w9z7mɓҥK'ԵnZî?l>BD@@kh1K+B%MB 'ug>A@ڸiMg>Wr怰㡜uT8_GU~/Y|=&s;x J]|Y޽+_p]8 ÿ&NL$6UOիWEb5kaäC0`@z兽*GTw #XVVZl&Mބ1GQ?)7_rYv4߆_b%Wrz]rTVm'Yj1b o;l0͸x:L,%?` jxifXMm\._ފ}DǓcoۨ\>"{[[ǎ-gX{r/M74H>PB?ЛZէtjRW/X%ɣUXj/&?ܭ81mp$x"#a(A_= "<3SP2Y)M 8[v#ʑp͢aLj=}cȐ\ln+i3 10nxڰ~M~2E3*3Ofdtq*(uX@xnyg(!gA4?p)hϥ@p75+·a?Ύ1(GŘI`˖-ԻO_9w+}̴V+K.QcTIfk3`7D;r@x?H'D:$6h'trPGKxQ·P9p@*WL׭5߻厶 AڴiA@@;~ȦO 2vܾC7mSiZjpU򬝝?DgAĿUX" <> ˗'Ylz;FGC9}Qq7 ΀=PnPGv8TJ9=en D8 #9|3u9r0-+ݺ}ӧ5Bq%I>|H,K̔:uG$p$Q>Yf/:xv%jQ@@@@ oK!!! 'O?z䞮>M^O~ݻwSpz)sJ>/^>sͦ{QHѢ2hР@8 N‡:вK>\N͌ 5le̔[INd<ٷpB飏h󦍴nZ:z0KWHv)s(ow4l߾ԭK9_Υͦ4z1ݷMnmԸI9ŒK)K ,2m[8r$OS<܃sN|x%OÎ;2^\1!x q_&ڴmGǏNW ͛.\@/aþf>fߢuQ1C+tqv(:uM<9F8I$9rPꌌ]_cŊTTI''UP!\[F!T"E :wՋҤIC=~ڵeF3eGЪUhϞ=blz7nD !gԩS rrĪ?Ο@Ŋ;G?1ƍTPA.rtŔ3gHS>#k%͜9C_^:ܞe˖5kh0g\:$.مϻf;xfa܊dɒvAk֬?LNt"VY򌝄&MR9,;YPp!i;%K&N* Cix%e%7>rș3'޵ScfFڪU-j/RM,)r/$MB9rfm۶b SVjyA*_kˍfϞ#fMQiH3+W g](w = $}xaC9SiquT畫%lk{?~mݻW:%RMip$eͪWN { YnZGδar<̋.NCS+eʔ2γIٳgC7I()]l$ ->4tyDܼyK됛7nO,6«0iڴ_hʹ{91w"T5wR 1g[o5Tb~uJ۷׮<˜g?9_>T\9Y\R̊T*N!"v 8}ʜ9+}&J֌EPǎtR_ 3(:uz)Tz -E bi;:Z ٳτq8XF 9 t列H*aqH8͓>_||z4up'EVtA 믞UR%*+%ԕJƌZz\tRKxū.6U<g= A D|U<=~$XB _ܬ*3fH+V-xiӦdeC>iy9D ';pxCvfo%XB-ك5׻!Rb+ #>s9(z.C(UN=tI(1Y^')ĺ¦ĉC@ D勗hʥrspE 3Iϝ=#ؽ $85J>Ų5֝[2EGCb˖iG)]{xTX1X)صVﵡ!yې7L^π$SDr]qŲtY$*#O6ǎtқ:bt9bɗE$$MݸNL N1|vEI.r,]+ƶıǢ7]k죘0|a]0aYoƅ7VvVr{>DH,z2O g/;Iۻ¾ww4*խSVʔ!:}B;|2?a8B5\_T7n<:{4)UꈲO?E6ծYE=I&I&5kVӆU;tFH6UTpG1I1Ҩxfo &Ɔiǰ~6{>} N#c:]=w:j(q@Q2/on۹3҉)aD lG: ~92v޽K=zQN9_&;*CrU׮]mۉkLrԴi3pڵxCm9{RZu6~^MQ>|XﲨC+R(]VUInja*VbVjرZpZ.]թx˿'Ξ=KM66.S:uLwޕy~UXGE?@c)JL;LoIe!ʻ:8+<a;wRem_ɺ) ;1j U_ӻO96yqrv+uJ/02q1ϸ1rv0-GQ?Cffxe=f8O"P-Pr|43hNUg<գu,1r:qQ>O՜ng3/)=tok'ad]vzVV }ywF ;J9u_/q<8?(q@=S bf{7Y3⾐BTy,#]|~;]|̈́&sN[f%-_m7?&Jԉ4. .kZڶkGo6~S<)l mڸ^}U.2ĈbV5{2yfb29哏{.}͛ E @ ԱN8%7-ZxXDïӧS`zEK6}/.֙_0vo.\mhˇ:1&uϭ8.SSgۧ7\'m_ɺ) ;5k X)SժU%vT_ᄑ{aG1fNck1򞂕Vժ2-zS~rVu_DzFNǢո(joYEM{d=1.;=NsI4o\tݵwW\R5O⺭s>B %%y͛6H MxR*x*>}cxq= +IHE} \F5q59Kj_R5-XnXv9ωގ7}!~Z<00jת%K/NgN^x[SUtR[+I.ޓ\.͜n>Ï?\!޳g-*^}_T}0ü+/{thA?"Dž_նmz(k>}zYiu6su^xe<թml˓-NӼ/_FE[mU^_qv:v0M;ƭCb9^y괍-poҪcn <-#cfw/ϳ\֊o/mV!ou4+뭝f쾯z4cq;=F;-q^q9RrD8eHK|ДDQ[<'cGOq)ɼoO21e4<(O}by<_X ߅4p /ڱc\TV<=lȑ;3{~Yw_8pZٍ1c:h5n[Wrz9F]fF9>5ڵ(o(k<ױlțh5n"‡m+fc߰'Fyfi,{bjloƅ]=uʽN^7 ]Nu? >jGu7׺.YDCKڵPL~Įm]/> oy%Y۷4ϲ1!4nO>AHsL$#zyu%իW<^zXTZlp\[׮TJU)ޕ,Y2xV|pS=ZNOzn2l5Fq%PqC|F3-ʧ_&xqpXLR<άg uT6|Ǖ9}!l2[>빎*(uX5vO?ʹ#௿= >|  yQDo_ #s.+<v@FဨR|Gg8㡎,At#(UGK.QM(qb9,`xN 9x4@|D 馆g>X~p v@N3D~r:<}Q+ Oڴi[y3dȀُ| oƲIG #g΅\~%<>gAt;̆><ร)A@@@@l r!]{@1@8*`gA*v28w>>+T9[$7j=xDsBdxR\/r@Žȁg>q?     >!eu:%as2E>~WX|X7)x7_Ε[RyD~^%hݺu4xYwEin|}1t|"˭]V;wR)rE9`@>M ,\ty~#:IgRM|ݻ2O٠tۥҌG3{X }ywMͭ[(GΗpuj۶|if-ZCJ^Ȱ:zbTj57*{ SlyX_ե?Z}HݸpV̬/Ymn-9<9xkYvŬb)11+8|>z>}YA@@_9 1+΂kӄ[9\9 pQ3%G:=v 6PeQx2 Z|7-Zȼ%K][ռy3cuS=-[kU͛7X"rr&~L\(QB=P8X_+WPq18p`MGoRg$ItcoEuqutL/ .@~9VڷogîRi)]ZrEvrU0Koݦ6>A..`VUS IDATx1+'0cUƊ^ӗE@@awC=WMTr ԑ v88 *O9ᏼ˵Kfύ7~HLRj|3ZժTt)yΙ3f'O9yƍNhyǟ7fb'X;w, :uH… IvjOl/]zϜ>-<;p1MgIdO)n]97j}b|gZ0Oy}AAjN՗FUfrA3_,HK,%nnj3[n. ٢W0DȰ:M3o4tٵ.M81=e7Ѩ|qѼw^!" _Zдmמ.YB˯woS<h/@]„ l>l옰\.1;mۆy=ʚ-+O^LVU7׊5{K831 ZeXpҤ2/&LH5˜]VuKlbWlY9rio1&=o:"Mܮ}vƺ3wcŲ/X/R0M?<;]VuNbW]3z=޶O_qpBof@bøڥf,Nѧ7៦٧˺ӟNpRߩ-Wm߱j֨Aafi/^ zgmr :\xQ[Nf4tڕ*W*gOjT7Ke2 QڴiI-FAdQÎ4|H8%!hղ%fzݬ2yu/U$W]V"mۺ%}}#~P@e[ͩ@nr㍼*Ȱ?zk].2gů c+nxڰ~Mtئb(UP*288o#5E}IEdcQ_j%73 #ĖǍg~a…wއl"f4%1|;ҥKԸqJ$1>kVl?0@@@ ߑ     &p#@@@@@     wz+p@`,78 @@@@.     M"į ƂA@@@@     wz+p@`,78 @@@@.     M"į ƂA@@@@     wz+p@`,78 @@@@.     M"į ƂA@@@@y5{z\6]zʗgϞh,(Ujϔ)S|^ot1*01o{^ȃD=5x"jAA))_|tU?͛ *($#Ƙ    ;K44u| 8k%ۻV^Eŋaþޡ2ӷ~+ݻG"ER蕂hР@8(*l߾ԭ+gXҤMGٲFo6)9N>Cs*8G޶Q?ڭO۽{7׫G2g-^}Zz=WZ%u0G iQu3ߢ 3QZɓr(o5[v^_.q> 9rJ̙U1cL;w ҽij1M)6q8%ci~WF:|@q>W jժp:6nH9sg1cŋ(WQO]vSԩ)aa/RxݺuK+VLϒ%3JsZ@񶍺mڶ͛Ǐ ;whŚ4nw&M ϖ-[e;zGر4x /QzέÇԨQ#~Tv}2ObHKOz-Ők*˖-Hu,Yhfjδ~zZnʼn-[Jk׬KH]|СC2^B:rmڸA\%e:;+\òrCyҜe6Ϝ9#>-:9s&lc;8å3QTIڹc,YB 1EB7۶nmOM6QҤIeM.n<룖-[HV+Wϊ(Fohy>IĎI1$%8 x.g8$Ѱ!%KLlM꬧r*r9NJ5UvRΝ)Wܔ:MZ\K ]tIEMN6zҡO+_<1b$(YZ q+Ek׮-g xN:2m+W$2eʤUQR%&mڴ2֭Z^D#v}T ~**R?&/˖5+/Zu{۾ڋr    Q X.sz >tF\qSx@ FjidL,[8 6P>51en2>^xTpa<>I8Lt^> 9g>~HXqZ'޶cSuNGe]l&vxgyrr F|o>nM$Xq0,M[X֛s'}ԲE ڹs'2B]'xC7O&}\/q;Fy/D ȃt Z}=kuMXM_B˶[7Pçh} Ѣ+V\YvoA0p"-Z0OD,ѪQԶwN[þ#"m;Ni3f)8p@<9㏴B8P4|n+T ľ%xF ]˓(H8>'} /gϑE 8mSެ׊G@9 |xCU._JeS[[wЪeKjk~}Ŧ|TZu$+^Rm6K$I-IzשlTQ,\ݢ%ݽ{O#fZ8;xo\r%}=U! Ni˅탙2{zћ=uR:{.N|3g%2 "6:U99?}+ ԇsP   ]y$`rҥvrFML,=HoPU+1<ȣ)%=L& wL*G2D!oޓ՗$J@@@@8 ]us/PԱcgJ$cʑp\@'O3Z,^Dh' JF{@@@@8 i^W,SY} ʝ5x ;)fHxHO$?yh0U@ %O /v}GN<} me@dfP@@@@b2(q@t 7iӮCߴ Od5D@ %I8ux0>~f.\K]mkȉsjrO>Z4R*v"<^RT]nzEg&~!}YbU[QDcYlgv6.o#wY+;@Y8Ϋ_|'Y+O>bt_!Q!Xsʋ:"G_h>/"q_|#R/ʀ7 /~ٱU(6<@|?O~8Ώ޹%6 ~Y^VZш#h4n8R<=bŊ2eXYdɒǪof?@q<;{#x5jtDG[ȴ1ڌtX0wKlktehgcRJE ,4e˗S 襗V*ܹN>c*m^Q{/`E3xfkSbYΜ?t.s)Gk׮%~7plْf*iN*cD~x:iEu;M?רIW5kÇexxjթHѢ"B3Jx3v,uUKI)p}͛Eeʖ#勾9_&MScVezjYF hQA4c %vdwT_FƑ߀ݾn'c]zC߻O_Sz )gPN扡^{:6jg|AL Jnq/&{ݾunqyH/R;t3 AQb͛GӦM;wȾȜ9&e,N|Q#Cxoe˨Nn4oތV,_F֯.|L{EŅ_+WP#>p`-*bSo-$ïӧS`z=S6m,Ӧh5aR/_}vԶ];p ˾n1b8%M֬Y-t kO6m57nX/(cet;V(QB]^REMT;C|!h߲E 1U[X5YhZb9׏ y9` O2QՏjI۝|7=eտތsxN.;=uL}%~FnVV4iҘ͝7#+W)¿Su6lŋK{dݭq6'V:EQǏ:i$I/.n7% |]r~ҥ<+ΐ f{ݷwOOPѮmV z䜲d}vzH J U; @/[xHݢǏk_,CCC<2~BqArw H"0aB6n(;wپׯkvZ;sg\)X97j}]=vM߻wO ]w+WhpDVC )X}{qܜjLIg}f:Qqij=ǎX3&MWŝuMCm}޸ISMjJ,"NfШLFvb"?s@\/GvQ9"|wyd"ܞ&^ij/WDW_5hdBdm&KPzGO@vpvpTඪ`Sm۶w}fJӧeYDi!v.wE7v2s1b˲6:9Y^C~I*W9\pphݨ߬/ߗڻw/Kbx/zz:fd}x|kx5+v &'yNȓ.ގs&:Ƙ^#zv< سgQ*Ug.'`zpq_|GQ"`e'>zmSN弭  D}s{,VP˦c>|(P@:Ν~I.R|ԗW|Mm;/3|IԵKGX32iҤɿ>4$?r䈔={&QytIGu֚>ce)RL^@re˖#GjRNχ22vY{XWBhҤɲ_pL8j} J?v(/3f3ZQBy+ Ჸ>O}a밙{K={͛7 #s+Nጉ`8`Qяe4I?˘ե/Z}g7Kor1flʑ#-^X6g͂]=np].K^>vg[T{6G;*3ٳgKJ s{Vv*eos^˱8}u*69ͳk^ODްbG(N '4]TDؙsT#?2oj*Py2C#;#xc|ȺT{]rTVmf9 ܦA_V!:|+yèW/Xx2y2^x7o?a$y7fJr,le'.roG|7ӓ.)Y{XEˉ IDATỡz"\nXY9l;$$/y|O dyO8EVOeƁu?z_.uG%gwtR^7ܬ/Y7zd=1O3vh9-ov]=<~u:5o,n]gg2c_b+uWz<5'y,c6#G=>|e{T<6X"C εWDF.^PlҮKݻ"~rqP3ʉPG,ȥK:c6/*y_|8~@Z&63}%hTԭ'bE[QPQlkO G%bfa4q/ Dqciԩbv>J#;ƍ/rOw6+#yo8~W*c:FQ Dm~vJ`r>ԑ"R v:} `焝 >珚 Yz;$j,  _Kt*9·aKq@Hg ,;j Ǖc3חeuOEq@WZsV$Wo.ss⊩â۷>M@ @@@@@ Q3F k˓P+1̻'OӟuK^NCq@gN,8q]9<5WUWr^\MpaϐA@@@@@ 1h#Ɖb^E@@@@@ C;f@l$$6*    110 @@@@b#8 W&ЎY      6@ %$v HHlU @@@@b(8 1c`Fp@bcM     C @@@@@ 6{mJH     ثhPp@bh,"ۨ}qĉCI_xcE      KDyC6E/^<*]<ծSn۩V:eJ۷o SϝgbVL4H; O<͛7RACm/Р}Ύ)qDhx6Wӥ̰     u|ѣG7!0aBbY!uT&MRARӚ5kRʔ>CF9cr)M5;FO%JR(o4x˖/ +RG^TJU=?p:ɰJ8Ae˖OOSJ6.ZDcǍfΜ!w-Sx"}ҥ mF6_({RIƖvXeV6|ͷ?җCzǏK3M0Fgї_}E_JrM(6mҀ/Һuk)A矻 8!5k@&O|nR 4qchiy>o-)~q4z(z2-cƌThQ,Gz꩕J*ҬYS>T^f#YH\yjȿ+gjתE3gYPI>VeY ^]<*X.C 4?ϩ[2ӗ/.;tzmZtƪc5Z!D@@@@@,Y'~$iҤnMʛ7v3xG{Q |Ou!5kF޽{iƍ4rp-Ų% *H'NKu>+W.*Q\TK8!ujצ຤tXaWVf<2^R\[/ {s>|˗W |:zց hd%IĴ M@ЂXn⋥D\ T3&9rЋfUW_E]vӤII}Vvؕ53qc7eO\=^     `BU?&̙g_^{UMeS _~5Kl:!>Wv޽Trew>ʞ=6s6u+K իOJwޥL˽*kf9sJg̙TH%@ȕWΝ; ~TnOR|ϛ?]>Zh"tUڷozcfM2%cSnҨѣ}vHLH,c"ܥ ݻimiW)@,\P<]*^3;ʚLvB>F!CLr={2Oo#     bE}ig{FKΝOs>Xoj饗(O<*oמn6]r&uCvx{ʕ+roȵW|aIr ET4K| QpO:i/EGhfGd<    LH4Gu     <&t_sq.\-ߟ+ 3 čҧJJUe$L#a ĘM7(O4& 'Kt]:gn,Z   13 gܢEsP|D͈Z;{ZdwL6@q@?~Lq?x>aL<   Zӭ7nߺEdxIat}vNY3;oG[l?$$ٯA<'}7+93b3 wO{*TSYc/uEnc]=~~nR&о{hÆuDŋG˖oMҫ];w&MFK>S9D ,H[vM 'IŊ*)壑+!iķcL 4Igfmjls jYFi "1E}ѐa3F   1@yF?h7nܠsRMiЀ>WoF%׮W_ KW{RNU0<|Y:(a„)QhycZ~3Arfԥ׋8d^ō{葩qi_>Ջv)èrLP J*5ʝڶH9 +?Njʈl4ZSUʹ-y}%-[xKiܖ`Y[x!U*[\7k毲5dΟ%ڳ{&fPݚ.;Э[7e5\ӧNj_z['G&W9|PbסJF1+UNuʛ335lPN}JT wV*Z07 :XɺlPu%Xׯ-ri¸Qne#y93ۼqfW/Oʕr=?JjNrթQ/]f֘ ?NU_Y1S:Us*n&6#nf?Li2<ӊqNNSfƓe@@@/>q@̐'Y5k֌N8A}e˚t_wҜٿS<\Ornj_~BmGE|+uԩ[?&9Zv >iv:+^Μ9M/\mBS:+W@Ocܸgڭ4itAܿUƌf8 b8-\Z]էgt9Rwl'סJ߷bŀ_҂%:wlG_ D~!fVS >=>ÇҬ iiiIO-lPu*LZqmھ^{Mq:[hNfRe4U^~D?G|bxM 1F_+׋ "]lשߩ3Ӭ_U~3Y-_rE;=VvQif<   O;w2d-B6$OB,^Q|E+IՆSi4(o>HW0iO4krh2<'rv̔fG3YxޫΓW:moe܊]8mNxZG@!3dڴiTZ51KpFٴiM>*WL;vtDoD;s,Hǎ%(jAa'?]:}@/_b(\UZ$.9~_l_l 7xͭsxRmfY/yŻwnY;"Ņc7wZ4RES|٩Cwnh 3eLK*OcyaW\D;Wԑr UuB8P^֥8%{xP@GNl`>>rП7lԔCiѢ :Ν;Geʔ}QSԫ^z |%>\Lş{mۋMiUrI;&ϝV< q׿TrX̂RR\"G:W\8 G˗eT}<+2ן,\feG;ɧ;]v+ݖ e Bz='s啮e]a&1/)MtYm3]ǫoUw׫Ք$[^ #zH 6ѵ#N[0{i+B?z6ɱ.@m cl|U_S#s! Bz:obG;593ɵO0! B@ё{Uׯ/rg84K_ƥɔs:߅Z4*?-:+mX8<ƒ$}j3 0 wʦdQ! 7 ~l)M#)䣘IR)F9֊h]5Q_W/hY/9蚷{ވ ! (W@|ĥAPEA#"FX8Y4][>r%mB@! w^]s~f.r&@I$#ukVD{B9;yKB@ܩnN-ɷB@! ; w<ɫB@! =^[! B@/< *B@! {DqB@! B xO ! B@!Q@%B@! ( ^B@! B@G@xo! B@!  $B@! =^[! B@/} IDAT< *B@! {DqB@! B xO ! B@!Q@%B@! a%B@! G?_KT)_4WltlD%]| ! Bv~>y .|GJ.*UhԤ ʔ)hl<鋲sR! wlf&>zBͩ'OׯX% ‰cGuQ(#~R6Eyc㋲W! &}{w>hJʇGV|oEڵQB{B |K1i틲E&a7! B@&@k>.dQ}AcQ 6KpZ^QGOml<%gΛ\! B7_.ӮDɽi u/%ɕ7e#SNB¶-HG*U=jժ0?O`$஥wѢEرR~jԨ'ҥKVwƼyh) ՝deffSN2eNssud9e\{*"~K<~ n"Ǝ~ Ks2|2(;?lowy[VeӤI?ʖO  6T u֍Etia_wJxM! Bވ~ @ #U>1xPlIG`a7mހ1~Z"\zRJ.lܹsq!~N7 P0TZ ;wQx|ғhҤ)'}"oI hF-u7EժUJ}{K*e~;]8uÈa^ػoJ=hԠ!?6cWUQ#F㫸/NJ?} 2W O¢NǪVyǣ^{ 1F/+%^{1=䓪LƎZ5Evڔ:gu'B@! MiWnWզ/7=P6iiGмY ۯ)éJ׭S)'$$ 99{ѹv4k.h_>5G p5_r;>RVo'H4$W' ȼr&͔}-*Glq#w>Xz%l9i$uVt'Gzz:VZe燧h+OZrVq咒{GdZr"B@4,T"z՗oɌj=3Xys]tL?"wrks~~>ѽ[<Gq:/DO/bS7og3U@O-[g8^}uzABGw˦uH;qծO~ɲbg:vUO0idP?hd4 k2jԨCˡ\MFi| t j[\` 2V{^V]IfE m۳ǃicٲO)4QG~Tez7bQfM hr,G 3M`E#<Z\>G9kFǮ£wQ4DDD(/?G-quTße,41y4]"~<~5"Š Σ>K _&p&~RR~r8|駤pߤѬjw-[0GEEQEizMh;GOsg UTOH8! B@+Xl)qɷ:qrBviMH]n-Tøƫyy1dPT)Xm|U6)kt1x|R~B^FupjVQ7Q1cܑiFޭecxxhSR`MZk> Ci" Ha˙B@! |L@-X&oS{xwN:cmڳGwм8w[;+-&,&l.pdi&y.SF)# 5Z푣B@! |M@q͏P8F۩795C&ͱDMijת{:vTܰRcpvF˲DkeԬq3lڪB@ iHRF1@Br&B@^ݚ"9o[+WЇr%jpGxK;aڔ#o--n2jٲ*#aCHdĞ\ ! Bwh/V2gd|kHi$\EqH|! B#^Q"$.)],7RY"B@! 4D;(Q@+ -B@C:7//vúnO(MӮ˖˫mFs~ޖ( B@! B@I+z܌Y ! B@!p+rɰB@! yDy%f! B@!p+rɰB@! yDy%f! B@!p+rɰB@! yDy%f! B@!p+rɰB@! yDy%f! B@!p+rɰB@! yDy%f! B@!pLKB@! 9Jg;vsǰ򑔘2_nVAI22RJS"B@CGT_ժU4j5!nXщt颬ȣ,׮]yqt;&h#֭àAPvm0+V`ոr劝?v6lF=;O#NsRDR:6mތ7Śgyyԇp4m_4 !h=\ݴySPi1sfğ}|\dg r%d~v*pyanwfb}fKo% v.t_{7a[vKތy~vbrc_|dff8q7n)wT,ۼ/aF𵷦8dz&g'O bnqdfRVL-[M2Ŵ33fepuj!CTٿ`RB{4ܹsvQsy3=孷޲et1}t#'LzN<oUh=iΦB֭1|fz=ٚ,|0¶T{[O7ðT :TVo:ܰfzG9USM)_SayRݧQN+jsR}?ؼ3{\8~#v&7p5ł=zщ#G(ecewᑀ˫ѣGIj$j]ez 'K*VB֯_8jrJʇmVT8YCE˖Vc[)FVߜ7?$B +&~NQG D蘉Ec5}*?~?iawy7A|kÖm[;#[a C$yqUq+hz.]M H\DdO,|Zc~Z՘7p:r ܃".WgY&,3aE!(2v={m:,:(JSUGt/ɹwaP.6GF4H; ېM]  \^pMbթ~.瞏L]%3Wلn]2_ \[B>u] u`aLY[~ FxeN ů sjņG>>[h|ٟ͆yxwXq@瞚iZc>4%_Yp:VZ` ʞ\񵑦˜\ҥsg*Kytixcvs1 nZt)+|I cVFq( @{" I"1on6"C6ghp,ޛeIAb:7#!3ZUZ_;;i>^0rRYWP9CP ԮQ@"zA#?s/b/D6GP"b6c9ƚF# 8~R[zs0[q-:‘v[ĵ iD/`7i3,=94Jo5ք]XZMXKk1Xf[L O+fQ b6"Ņ܆G|ejg\YX;o%"hu!OX`Tj_'woFVVX:I0T-e6JBB led|krWD +V..^r 1[]غ:q5wJ*Qk?iX#7Ν;MJy?nY{V 0֌q :sӓ͊СC/9+;vc?fxcÊ+@eOOm-abd *?Oj坨ݨ ,4{u$5䦠RGLN# cX3Qctق$̌a W #zu}h;po,9GÕ CԐ8Dظv~ NGcItOӐis1q&ĭxQcI%eR^9 0FF`. $s8/4:Xܣ _ Ǵ}ƈ58s%T,o:a?Xz|[.rhf&E҅:XVKƋ09/A8ѣIFT >mX!jX=Kbi(l8l W#'r$RDiEy^XHJBT]3+zӠ]q^51q̊XpW.E0c.FK>9!1K3sEԀ:BzdFá!Tf1$3/`T~eigd2: ͱB]ÇtR(;.ǚl IDATWU2y׸FbX${D=(,]4&ږ rI%ó:qsęT⢰::IP0KM{gVkSلM+PE{5fIw`pѽwbmX8 uHɻr.qḫH}ե+~:c/Ţp;E=bQfʯjݪH]\WsO`Cl}2<7mև4;Ѧ3Nf ;fCG'\<l>CX.,yi*cXESG IGqS9{w8_uUc2#ֺU+7<]|ٟ͆*ފ7FH>o~[W2zؙevhYsV>؍nD)FDGGt)-8׮k8[nǕ),ύ-~^cJZhhۇx<uγF}k w܂!b%!fe긧'4#քD⡶u)4e|@ Ec)[˔͢$u}h\8Qӽ F.ePޯxyL_tjS{Vө-r5ѓ|H>stSyL]m>שE`80z~$QR/"/ [U$*B:}Q D56jAgbYݘ -Ө\i,Ezhu^|ԑB9gb+:2Q+DNA?8#S+za 9%*3V%Pۨ ˨ΆE@MnСTc"pqC N1upuC;u: ۪U8V'uB6wN6ntE @SA 3D.O#4j ]ۨZCJmI17NppM +PD 15jyMuC}喳^ӫK'zQP CuY/M Oz{YtO5Heiv~n>sm~ԕϧS.!x##2sYq߯%I&.]BZTC{ԹAl_؟{~ڵ -OjLᝰ{+5qhJU>Д-?OsXX6l~|vӥj2_Qcφ͌ߋєsM 0?3ӧkLg{ Y!Nݾ4*\-x{B0<0K`Ѭa["W.@ؔ0y^ntR 5XHt٧`QoA\fhs]ڇ`ݭ05#V(czC?yY5Eަ ͅ.0j/@LeRV,)Ik'((%!MQ@5ɚHN}*O+5EHR#9aMBT+0 m뫮ͻ::ci.eE,w܀ tg,Iɸ5K3#50.xW^viҹ3ޱv4sguIhmemhWRCoF oZR>^dd,i i~()p| R>`wePdUG2uQ%ᇣ4u(ƝeJ5 CP;=O;e4K[<{ k ΅x&TcIIs^myptYl0'ym={5P<[L3k=1~^vZ׿wὋզMUurqٰqC^k;c{ +MifXئC_g]\*Z/<1Fٱcչ?K̐ehG8gqG+0=B Y3Э`$l% W 5,ɬRhۚo&a@;Gk0wu:1᳆ьuRtfLEj0N]U *>ʺNXjfzE?5O\i-bnTε ]Ϧ2úZCb[caeiQj*{ :ae]˩֑ZLD,TvnHTeI4uD]ĸaT6!+] P46Mƨ0ciwr'Y̊f Zazi+H~]o &XZ Ogh̜ &nI[%jx"Y!r طb4 T_T<23nōOæJxfj4.trea,6.SF"7Q>MEQGEώRF~5k iøf1QwQeGmSN@t6Z>Bf2ȇȉ`𤊨^'u eK uKq/ЁqA Hw b ?qsPZ+=lV-ׅد;ܳsMFŮ֊YasCjN:W. :r&BOzN M5Eeħw:#GBԛ7nz3u uT5"l[Gg,=Kgeg -@i͋?5.t?sUlPHwG@G0݁a4Wש!fkm9?wEڴmJ*;4Ԧ-ikgu<[mM_;VMq7EoOb97Tv۷oŋS[kB՗5%D#!zƌXw=駞RhXV(4h|uVZcƠL2/y-8ZGq#Fe+;";U ^S @M C 5|*zƨ\}.h\de^B-H/PquDRz ꝓyP~:}rEY?rۇN 2r эOy5ȂS9 N:'.#eÊicTF?<[THN1g #eʥY1mYvq_8P|u#$Fq7IsK?z;OD񹺝fguҝdz Ya+ꞯظڒߟ:x/ժQG9#S2ݶVpxhqqo#qmظQvzп sz]))'N3FFBx?o|8~駕eiӠٞk~zz|𚫭[ZGBn J8! B@!`;͓>x!^O|1-!1omM2|hq׮SS|իWJMܵ#OIӅFez^M8q SFJc>jJd#_GOHqLEEB@! tƱQ+wMWZ΋Lqԋlcy+-o iB.t :Ӛa-XW6}i /x OliH?YiEyXڮc!ngX -Ͱ0{L _|l?v;4 ~8a4 *zX[>AD2AT4K= QLY@* 6!B$ qB($)Bd YA; AP<eAPTBU&tAF  /B !PG#,N/D"FD!{aK,b D$R)TG"m{Xd2YC!Y2 P2(-凊Ae*PMsjMBКhs:A/o/tO ÆǨa0PL*8sӋyǬaXNVk`˱wcX:vGq&Ha\)׃-6xQ&OƟ7Ot&L'hLBO"|'BD =1xXFB$1P$ <N2422L0|'Hb$=^IR3>iHee4ggڵڳ:::tfuu}tt ][ԗտ@ aa(hĘbl\a=HkcNlΫZGC 96['?Q|~iqN((;s2)S5ȂB¦"rQJiy?J *=C8f̪\|"eA*ܪjg>ruimGX]i=>~a \/l7F6694=hVknni9Պhop%K]m2m._W|}u嵾E۫nPou@]]nZqKVmەwX!dMݻ|/|n_<0o?ڃ4n>R9:X'*Ontw,+!vw'VNn` )Ei2%R3\e r%sZv_PXDy M -J*.i3l~5!7";b:cbntG |ǧU=> %Ň ?|"8my9 Wү&hMONθ72 7Kbb>Y&~Ҽ v|8ٲm? r qtEQ ht3F3݇N $hf-2*JZ{ZktJtO08aX`tƸʤٴŲf5gpӠ+uWپYo!o BVPdpUpF8-5XTGb,ρD$䒔}ά<ܙ5rSű/8~ĭN-"aP+v( ->S]v^HD\5~vtx.nnm^jt Uk%ڥnvwv޴v!NaOݾ{=Pwx3P8xihc ƺ}:kfZqm썹y ߖt?nYs j7u~15g@ ! (MQxF!QZ ]!b0o.8g#Db!y"S(6sY|bCyOMaN%3_BrUr+s? EO%)#T+l$ +*#L,^]-")E%!#$J@J'?pTLAiTX]_uAM=^CCQsUk|O]'=i}Aa1;63SsVyk\ulmv+o`\RZV^G~oyр `carVtvL]쭸 'RRoO?w0Pdfa,l#9zG5)K?!~RJ~]Q%JY)gЪʯ^VΥ>yz#oKܗn\A^uvxÿAͬ=^˾'=&?5;O}b9k1 @)\py S%Cv$xL@ _+@dC"HGd9r%:E3mq4bNK8<.ׇ kD^b.q!ɘ(XDecS˔`"5%;k2`gfoPtĕMny B5BZBEEzD}b-4@k('% d؛˦ʽTpVdVQ*TvRTyڢ1٢BS{BL]OoI1ɢٸ )E_6,vŎ.ܮnWNYhY◈O_YXH5ud{l@ː h!鎬AQD}4탾g{1Wx.[TBaEc`#n13v1i2Y0ّ% `вp(BC,D\P|V*+V򐔀Ԁt 9[rEK*e_ߪj!ښ̚Z={JuTuzmG Md9LP&V̿XYnYclm-<]nθ#JxX{yU{1 ಐa#Q)+qf ]IeLiYF?Wc'NvΟN*VwUU:\Xl( lbb׶k;:oR=ۓK7|?G O`610B« 7w?M;^޻ht/.+W}qwۺІݯg7_f#퓡eD\I@C9w0ژ{XK. Wt KǘdLb 7SҨ, p'^psvp>s7/[QBHWX]DETYLI\f(-)!&(ɑU+ijkQOD ^ÏT S_\V'Q6vfnNG\\Ϲ;1}n?o_0|ʫ'1E F)D7݈7Mx䑼(;$ٝe=v5bœO. <<Quxt-|E#wSmPk%Ͷ+.WG\va\?7x>(2T4xd l3/S_|4mlJmZt2+Ec ŧKe>}TlՕV_'=ڏkkQks?>\W]`Hݠ2wMͩ-խ[sǶ'ߵ\n\~.ͺz8ـJo?fRvQnbޥ|^ pHYs   IDATx ]E7~^$} .j@YqQgdt ~.ç7:fe#NTdW!J}#$;Nz_wgUVֽV{KJEO-JCb92@F #d2p PCCkѣ-aqZ\booGFF #d2@F #`"MMMF \ӓd2@F #dNt`B=^WڱcDzcl+#dtzC~aܹs@F #NnjQ<Cɖ-[z 3fq'&Lf Z>lJ ԩSog',Tjg??3WBps5׸$8ns#X8+Vwܡ1;we˖i4 8(6N9zSN4A]sͻKmr@4eojl@gzF #8XfuQ:o"1^criɘ1czL8`N-#df4 UnyGuӧ,,` l޼YgE8#QF h6WZ3˴iM&&NP;P{7oQh?>N Yem%?@fd2~%TDt5LRgΜ%K4x&K r"-ݻdIO(Gk)GVmIrɅ=ɩ@F #q2*pXzɇ} mmmK{[[[f`MD v-6k,wwɓ'RY@69pڴi*(X"P_'N}ڥ f,ˮ _$'MѣFi(?*+3utʶe,7Hh:G9Ms @awɽrm3JƎjv鐻?% VrY5TTJR)ʜɗ.?A9b{X9@F #__}ɶm䤓N>2W91_/pVK|9q?.z!g@֯_r(< bƋ u @aڵ:hMV:}xV[U&-IlnذA&MyOΚNcR@gzF #x* оG߾K.~2_=(w]Z&Oh1d f 1t+k&{.>Yb/w 6Lof+_FYc[:d2#ooڴI9]}s9`vB"7:,t2φ;!Apv,z1`trRSɖ mr`aϞ='}G|0 L!Ciyd'vHS+ҷn%].MuhƗa VJOp쾅?V;;;;q s%2{hu(CF # 3\m4g#w✭}h}t4M5$5BC#(,,_K|W>bB'n*~zCtF #x!+[lo5r؂cg6,:gP2@F``+^^;R>mMگ=l*vwIK/0ej,.|kYߐQSQ^}Ld2aG&[Q$pcol q s>Pν;=; ]&z6sPCY fsر*J > CTd2O1\s2ͣqoډ:4e筇uxk › !Mϯa֣l2Lȗ)Ie5,9µ\Cީgu`w s6|i,6 `} Kkǁ߃s:#<hK?UZ͕'0+Lֵѱq";wI 2א2^zL>d6#w,1sCF #`i.g ,M.c˖-jXӳggyq~,.㢟\۶~Vd2 *G~Vu }xm:m`>ޞCF #<p7 5uu77yɝq㵅2]-b^]3-#pd_3 j)g2@F`pj& u<~tsd2@F #?C.JMF3Tbszd~F #d2@F #04?1~d2@F #d2{kKY0#d2@F # @d2@F #d<>,@F #d2@F`%XGN/s_O7A}QYlcc6fʉ'7|f3Ø{.,3d2@F``}Fߜ M~{$7ϭu_HwF̊p;&.@v@~<Ox`+ghpg@F #3kNo{ vM>Z{{ U}3&)=utTCPF)um-֛.7X~`rʛ0a?OAF{κ1 "vz'>$T%n\rv<#md2@F #C7m^,ԑ֎2wޡҍA_; C ]|BƍEy(9y\`A]K[w=g'h0O4 rg{E֮*K=o#_ ɩG>t'M$۶o7?Rm>@+-W]т@ &Ph>XwuE/_G{08| ORK(CF #d2OOM nҷGF6 IiEy)ЉKeH{{qqc\ =,{( :8Rʵrh=LI=Ҙ^Zm/s0JL0/X@^L1"֜%"8MZe9٧@F #dt<**hXx46i_LӁ(Œm,*J*y7k ;x>2x:˦n[>w6ˣҕ}#W^K:\@ 37v84aG4R)@6xٍi{?.(-O mGtc.%y_m۷U8Ƹč1% ͕ KF #d2&ɮsiIz: oE`:D?3!}wI9ga2a℺ z^n[ eV-{ڔ}I,8U>ݟ4c6waaǍ].ir-[ BFРw0Na`|B|=#lO^+޼0w6r$ވ6g.-֌O4Yxt!qgG`$2O<9uϦo9ӵ2@F #x#˼/ )A뵇bک9iVKJGG'_uDxn ;e⎮<yIX%}h9jWwkh_|}"fQ*2sJY>f 6`WN;oxp?Laʨ߲}|up"ߋn4-A֑obcg9% ,&My6ɆeQ{ڤytz&ڷ^z'Ikى;vi8pG0)g@71R+>cz,Ȭ\ [._L02뮓 /p9ĝ;ȎZ96wG͗-1QZ5#BGdҷ˶ PeG)Hb2\Zř%Ė-[bɁ[N1">G+{d2p#U0a߉g?*xIڥҗ#M3\āH#^NGkc[g~8i3]].͓6af@qȰ˰ET[ ۮR+h#rXڮq@\pn@|bxWeg86^QnRY+=rͿN&b)ViixO5CGOl/3φ6>c֟3 cz27!<RR笛d2XRž(L6aT閦N @U)>^+olZ~BޏN#Xo?1e04'RF6;;˫jXOBnLQБ#g?Xy~.b#buCi^ocҴ oTL`ҊNuc#.<< :){ bj~V|?;D<8 9s㉂XXB )eZl CZ@F #<G {"@hi fG;WyQ译U:r+~\#[^Xr6oޕ掝?bҔC ?8t[k~ъri)Ϗub;pq 7ȫ_;OoX|FǤo)/ XbM;p`&6@D0"˻K_^pT%2a1apcmm|6I1AVie۰x"`'@ڕrd2ģ·Ai@TLWp#vLO@ y>|q]oⴑ"?OyCǒ|C=6twd -\8Tc(ti6Gb`|~ks8H%ArԑRei(fz)k0,2m+əCo"ݸ/}PlF t4$ q4 s`@挈'ΞCF #d2O?Ы >}O$Zwߪc?˯x1ʱ);'+4Wȧ,vwZSd庲LY ^Evu4AWϟ7·!7=$wf@Xaf?n<ģ# s \x025 c<82k,Y%WzH&<2ai!jG|#uWEuqPq34Xvc>%WB_^àЧPnR]%~$$IN#s8Hx^G'6fϔUJkf@pYv<;ct_z9|VIƀ{;\LEN?`% ;-QôUz0Y;p3l}skեX|(z @ IDAT o,}l#=X4Z0C"yQ y}Bl绻9`ˮynu~]d2@F``|ޱeĻH5 ]  }=X-DWO?eY,waL>+o>d6}(߻Me0:z(^j~eʔ)qըQ'@o(@{"=4Ap޼y#Vi ҙg)~g;8S͙"fy{dTa:J'=FWCukN+4:2{lޔ:~$E:uB#OPv8{©.x&@o6[SN9E^vYsоwF2|  )/:L?6|;Хl3gΌ3 Hp39Yc Q^(Nb{2BwO~l8kcn1=b'z姏ڍhx#2ȐnlܸQ;|qcQ9{lC17xכN4u07e@&N?t}0oZPukʾY4Xhd%yiJ`im۶I #ѣF7qՍ;B5?GY.}Ny:/Ǐu쮻իW\gjI5CfζnwRlYpst?k#|*b_9)Mi(t?x9d3@F #g ؇Ӷ\Ě鬒 0v8RrY L{w.4צwɫ}j&N/qsC9@,_8lGa!khm#&ϒygǻ6}@կ"> fLG ē/@F #d2Crc3r~Ǚͦ:U'ry axƬD9bǎrm ݱ#jLr@F #d) \gF #d2@F # d2@F #<اwlq}>Nr.zi-Z4(wl7sYĺ _;./$au@F #dF'V/^Y>Y>@_ }&C/Xbg@:ˢo|Unh8= tˮF[{˿,KT|T3˾ϑ6"W~Q>s?7M˒Eߒ#·>kDH>B'ʕo@?{ݷ˷:EՉC?d2@F #Gw|ŗAfc]rnC_{?|SɅ f`k| {\_D>rzo%VV(4N{Juf Wr6}w@{nɎj ws&ܵ[ayxgi-oM,]no\ʨ2^%dmhzz>_$_ޱZ~t\?"ӛ%mҰ61_E_mê 9/+|y:R?5|Ku7dϗ[e~L}T}[N:_oA۲oIYXZ;I_gsY'#d2MRiǰA ߳*xh`W} M͏_- >as or\rD|>4⭨=9\9MićDk[|\nVI/|t ]MZ/VڰI6n);mQxիHEX5lLco.\( ^m"ޢ嚯}ևIETم߼U"_|,v+H: *_چ/4OfOWz\|]-ҋtgw'?{rL6#bY;fv& wrX*x{UC Yq;^ujum[,w ]]n-\=Yb ߓ_(6\͆5vh[Xmo_~ ؋>a{]"[*m2} z/Qtr4~_4ɕrїʽ(_q./wʯb.ȴˍ -_ɻƻkK+7#>፺$n!#d2"yoBfVƞ^Y?kX(X.[xMg% <*Sik/R FV^P.0`藢$Xoh>]{O/R30޵L|B_x7oByۍW_(_6p?ptnsT4S_.goIo+HQ.|_6ݲ :i\sgP~qa9/>%G_TdoXt՗=R~xϺB!].-?xHϝ.}\/kPPu/X `}Ee鯓*/k~ FrTv|{E2__.6[+oWO7ROȢW42]*5C.O]Wˆ.\n%_B:xo|r$o~(?Qk=+cղiw*r+CC_3N{\!|Hߑ_x.y⾟/V#}軮S5 eK̎w/gߖ6]/]ܵn,(_tMWM7|U8 HOe\[ϟ(szW9x*˔fz_ܾRzˆ%.z7AZ9Y^(ʍ(wR6-ȿ[m)5&̙l|^9%'HKni>W='dy_ͿOJǎخZx^!s2X#Q/[1(7j9zܳ;r5&]H^4J*fb4Na~n;+ɱhwL{~-O}.JsքgT޾j4=-{'Y+ln|qHKSWmzϮ["$-ʥ?\"(|N<#c"=V&rwEƎ$'y2 a}K VE.[/r*t99SһYx_uT#O?GA(!9ߍmHAVgm@F #CQ]eʱϓ"ٴ˟W=}sj}կc0xc7lw%u9Klkm7zDF7B@Z uس+/{w?xpxf@^t+׼]-9'Js9D cڀC]>ipe ÉL c,dF^pdenu~3@F #x gu5eb>QZ+vY`dF;MfZ"nѯ[mAk&yݛ&=д(M~ԁ =ɷN/7M!qn>]Ί;;kEy׼},2؀*s/Fk{Bn?ʍA;o]=پK:{qy9~yd#^c +e"Tm7ʄg?x:Шl wwGQS&ȑg$+&cϔӦɘfo C%>g̔_!0d%@).н{k>_yC!X-G\~;}E/У9(zdCdڴ)СBtܾ]ϘDK37Q*ji~k&' (=J: seV4omYLwȭA.y䎕2sh)7)k?2r<1MtpLX(0[K?2x{uI}&Yf\+q q7-v~܁d2@FIB=ʕj=dѻk J.h}pr8$zKe٫'7&}=;HpF,IxptU>dRLnG,]xNynZkiX9sE\$ʽ.joN;NN:9qRi=V_urqv t0 70vZ$_n=,#2K./_g*'Oŀ@o2#7}N>-@o[LRab \ڰj[A7bxgk&uzW˳g4Pr!e2r? )zvє,`k~@$F9cE rͽsO;_ |K_YLNdǿ$ג3v|:Z?^۾S*2f(bO<}عxbO ʥ7 ;ƌ+z|Da[__un=Oz|KSYvlw_cAuȣ-x^}ʨxoj@S#ٻس-^i8Q1r߃ɘQ2$}ha;cǷHniĒ7ŧ|DxN`^14˨^{3WƷT䡫Z^o\FC+ 2@bnR@F #(MmcdLCt`IBJK~^ꮴx:wD_j_KDj}Wx|E3|n >],i= 7-{Џ>Mҕ68=xtR޳mC۱@dVtrGg&EoۍnlѾkl6 =;a!-[x]MXsd@$-uz |"E'M v͌ZzِŃ@0·RNFniMܸn'|b<m} x}ڽM%Iw}~C:"T_L%`Zlv)/FŪ6AH |#O!*$dd.d%4T缴Z)k̒,b*^-b#\/†*YcQ)P+|XPhᨃ)@idex"|W-ITBu&/kT,!|n[~DQ*Kʫk>AikMh,ƅԆo^|\(Cb|UHXAW3XCL]>0:.A5ne 2?Z@UH X5Dz슊u ?0Ynjc$:f+K}%ߖxM|oy$QΏ4*h7fkB@?PA!S c w&IwAx7CEM(D\8Gyix/R8)Pu Ffa(TǠ(q&YYNw6Zl@^Y;"͊RITiǒ:B:ndV1uT2Q?1hqSƌ" 'zޖI6wlU|*ڱm)Q(Z4m4~Z3 8ިbfF5T o_f[Q ]jT+Lx$%ZM B?aF#biڠ< IWQ]嬘s3A.3&dŤث#Hu{:羃Hܝ SU& ZYKUIz,bA< Kƭ]F! H7m9l=$xW~EYP܎hZ8~ЋkT$WpI*jtoQ?r A4b֭UkKrum t٘O@$_NJt dK!Qe@FUDQ~Ruu У7hTilK! <:YLPH02Jٔ4SdDbV"ZT6mDD]!+JF̘,IG6m6Y)Hi{%Ap2(4R+@]"i`[i>" DU;T]|u.-O"2SuB=NBʹC%9vG3@KiνI^QGA*JpA؅&t/mwdžJ݄ 3N:eaK'y z TiC6hL h<˹^2JWE&Bm$zz%LBG)siYI:3z xJQb,7q]!C Z\~UCCg@ȏ]EPѢLSz.Pm_7ٙ jN7j)r]ANY]Y\>mQX)GT :!R5FgY73)D5IbY!qD1UQm3,qU2HM!JB t>MH\:5 Z 6J2)Z54s&<&zl&x `ƃ]9aPa5A6gTEj~+.QRJSY3tyR!MMD UX`;֪I6ft -gm%,rj.$3S:Ɠt0x olPZ/K'P"(B:%U#ÙVKRU@"H|fJ.!$aA.7M\aϜR@!:^?1rgfd.#0y-rC3҃L^+ P[ 5T!`64Ta $b]?fbQr0t5"_LYk(e)BVh$ ڜ6tds/\1M*im1&=r̾k-ҺS4 9OYehA8!E$jBRAu} v&TO7Q?v)vnHMg܏ =_)tYu't;{t*i0* }K<StNM>D[S6i ["Mr)j"ŏ8Kڋ2Ev"b'HV1uG P29ľUWh"IPe>u6Y i'<G*_Lَu^2{<Ӷ+C*Ѹ".u?>Sҭ7sUT{2 s 'kZˢ %9PP%PFhmk9=6=֍IūNLMOLW ZF)D"fH0Fʥ ni>a$H0[M3H0]'SdmP{̳ܸy`e>FT2E̤QHL/*c"ëS7=QN1;uTD9"@ipY}nj; hv1Rs)Ɣë4T6+sT$g)#0L۩$v4L;Jiw>whQEnT fA&zE2-SZ!EueU \g`yZ@2oWb3 6B$mDnNˏ;Dw2BkcBbVQaL (f T=+Uu"f#LJT, 3;&E:"QG+1\LPyup 6'VFPjRb̈́MCY*Դ,5]%`Cs9("5MuhG;Gw(׀zs th4isDp濄65<2 }Êʁb ,VVn6P0׎T1!*m>l7Z2+MrS7p~h4hՃymcEMYmHbE0fPOIm2Q4`ЙTc ?jɲ͞<Kr}*Q̫BP+qgq/_1ۡvHJ1mltt :R( r9خ !J ҧNIP,$Mt}'x8uFT@!c'P- 2S5惛f!TdYi!L\tӌJeص@.}}/T&%A11C&Zb< J僘E`$2..P n<-NnT! LՉ YۚRQ^ZtIHΠzE DŽSڪ|%)f Q-&+tʫs 1pL V{(j lXrfAFrJd,h !0+y*YMS OUޡ|6]iD/SyGRTc.:BJǔaZ1SLX!C^mHi_s%3YI$zB$]U7j/t]RB=ِK \y;gOw -pvJjQ^d&BAႈc-_OC;Tt,왕͝)UUHBW :1t504 /҂BCBwaDqU |'&0 VqzqI# [m5UM$4+زNd1 'аAIt@Aܵ<EmJv~E1/CʨrdyPʑb>h nȱDȘ $O)o "* ( "f.:q 81SI~F9Sui竬T"O!^0 Kh6^!kۇ%!W,`݃D؝vzNjUU:3c<ֽZƋbi Ro~]QkHs@/Jw(_j߂=tr&9 ߯45ψ_) ` yD '@A-A=} pTcJ' ABg@ۗ [ =hN\'@\9Bt&S(Ҫ2$ P #u:*m[XaԎ!8nL&\c` (fCp5f&!v`, tX֜6gU?vQ). t@U|ǫ*}h=ƱL Xp6Yy.f=~?Z0&%\ڳ#O U$S;^˫ x%$n29y,)m\\9I%o Ɉ]IOA[RR.mPiCDJIAPb~,=RۮF4RJgݥ d&$seSX =_$[̀VE P $Vq=V-PkSEJĉAa\7?P3񪂯g'r;tV * v+<X+Tyr7.g@K@rQtC%]Lc˘ ;A=% 3Ap^hœf˶VoyzC] 4S[<ۯwbf3L;_K¨u ';M& 3S"E(^Wz}Ge%'- IDAT+u6B #q\a-jhq4Hlr#{I~U"P0.y++`BC۵2lʥLcCxʮv|Kp=8&x.c@+<LF2~6JQ,IpUŠf{i>Qȭ :| Q,t5Ȩ?-TFrjBp#5y<]c)4ruq1$1c3c΃D<IOtA7?D:*&/p3fQˡY;lf t EiFn֘^ 2&j8uZ ES.7s) XR9&fDbV- \Q yT 6$EE?M9 = -#F]@`* sL;Rp0s'Q>CuPA 1#' vJV€w| ji&eY4C)E)Jw&bWMHlD! 'rVRBdzćX;S:f= ciݭr*#P`ݍ- 0fܘklW[i׋[޾i|cf3C":bbŶ1PVƤ"8IJTJ.*O0 ʒh6 :8KzW(lB̈́r!Ì`-EIBM&c>LbTp^S i~dPXR5w}M)lu<(6&jLj(lQKoLR0 m*Vs_o17|0UJJUbO 5#< FJŽ}f I XRDP{*iNl _NwqƵΧҾkܬƩ3\!Ҙ7uUPq:n9#dlXKI>H*SE^%>z2LG:6i:̘]m ⒡E%c͆X c) Q vMϺkwYk>:vi Hi#2B@wlh;$ `4@tM A)mSӯYfZ]8:?8y[6130ض\/ʮaI/ᒟq9xO"B>]q,dvG}t_s,URgܱ*dq9H)aG4~ZXtacm!' G!D断qOPvb~47>3bvCl6ң^Ğ/!8g=.գC<>KN~kvJӿsνvqX { ^f?T?po}Sp+zw*㮪 ɹdCJX^,ZkAUq%!ob3@Rͭt_|&QTH }e8vq\k N90&Пn L|AsIkI.nW4hΕ` Y38W3⮫P'k^MZrq54KӪylp| ]>ό+气r"NmIq)el@0`:u#Q\Hwq(s<&/;O_^P`D'3q&[ =uda T)"R<`Ƒ8v"$jVt ctp9MLTsaciLl4EHPCId|Պ*\b0Wlޕ™yj#.H=ޔC{KcWύVka+ÛĉpRs`0%~)p;up}b|{ ޴!8Ľԥ7bbC%Aڳ@S1Hj6Bl/ac [c[8 0W ˸hQv8 nPiP~(mY6'[Dz$6WLRL@%*+ꀱ eC#Y($' 4FMRCߝx!;k͆۾Ofj)zbu* (RYN/1 pu$;mÁ?r7pyegJqeI S>`Xm8:!^:~pMWu3b[`c*WĄʛg>5hD_\AX5Uw,%NKp\>0gL7~1>\0;uxR@ɺ趍@b: U#}kЏ^YǝC&/dr~^'K͎^wBWnL j؆J`"ZެG+B8ĕȶ] y(@q3M-56֝ @ɞl8ǽTS2&2s#^x]\T p}!ξ)X:191ӎqQq-D~7Zr&l4n U,l0 ?V{=I{ } цpI5 iZ|ű+~x8]KAQ%«s^\Qk'%g=Js tT;վ^Et>iG)@01DŽX+ڀy͇_͐sWYץυƋhCEޠ WE]xZV[]|E.^Oo 8̗Y垫e%Uן~M}O^|WtC'@4y,g=3D XسybԧzNTEF~%j^t ɋ(Xǹjb&d2CGgؼ{ݣ ʤEs;1#C6| 7KҩvxJ)A_ уαsqk[J&pԐl筽ga;DGՐ} vlh?옮Wv${up):gO*9:78d_V!r<=%HoY&PGkwGY1uBO{g8WcG\9*o̭hP۶qk+WÙw!]1&O3GBnL 29ƒɛ%7GVLZ"0u6*~4n%Ad hMu%d ށ'zn p{3Gd2{B{e0rsY|tHKJ-Ӏx,ewa!(h`^P(+{X ∕H,a9e3-\Ds-~v%sn 00x@-zmoJ\9=X5Soœ @Sl=&W7?$Waa8f9ӆQYm pET蜌G'rZc̸quI8~Y .40dsS8l0;,tڠg;³&B:汙x_3&&k $v);cp8cTl)TWA`CSɆE 8W`<}A/>&7|և Cl))hWKS{l v߸{T + `:і|nZ f^F٘jk\'FqΐhI#1mM '!Ǜ#=Oym―{ !Orqa Q^tv$1!F:;gdRei-.f9eI6! 3䕤e9%cVr[89;UښH }[}O9A"_HAɼ]`rrvWm6tA=O@EB-t1J sR|-uf%D.tµ[}60o IP0#swnT 55W5l!녈`ãW;[9P&zH.5;·KS/ĻMKs `Csj!JxYO]靚qć^dh@ dޢܓ׵dom+ςIXr1!#MlX ,3'L0dZ'=xYmN臇b |2 X9 wāio5:;sp%:cvo&q^dEj .Gs|j'9g{SLVy&~70>k$H>2 %m] :S]3_X d!cZ&o ޳WX _*'vgCwDoߖ\IݪQ𳆌1_zex~/@L8il|1jb<7^x(. dV9%&9h#xË0/Jc+Ћn3!8a *uRsm!B u#Q8obagSwW͚c^'cg[ydv:}|c馷l^嶽4GZ/ZtR>WD;"U|JgnAEep4ls5vJpS;ڙq2KXd $ZU@k{=HۤPso2!6C}(;΁wl Z$'ގۀ=FBA c[%Nם:°-LAX?2 jZG9ДY&$?ئ p>y%k].k' 5xq,% v|^_3y*Tpzd*ӋRј6yK?>?l6Iψ.G_'ml];'>Cuavn.odZ1{||v?wİͺ024ol Ne toFW^6bYBjPӏ5\Yڽ#c8k@۸`۬& qy%d x:T8NID< DfSCdcXat]Țs"lN sA1\W"vO\K_9570inFJaŋ=ռ>?P~5owNFe'"]Q+T%zmG`%!'\muڈ9x̴P݆_Lvu=d,n\vkve{~o.xJbvv9K1yaQ  Mq,Si'r=5q0|W7hkę!c_C9HSE7YL'TOA.Q8L#nt:ܡqq v>j t;u 2[’T(ޖs3m.K<{*R mS!!!4(9 hj[).73jǜ?Hʕ l·7O v hHOnCKc} vLۣ+ۚk1Fe/7մښ?sS/>:WI\b\+.I<)(څZ`o$& uYWd/W7w:]TKHAjaß$PiE b֧a)#a0eÙdd*8qW4J܄ߨy{[7L"ne 07e};ء/u Ix30COה(Yt°gr$1't<~@3!O+=S\[2fG]F9AfauP^0aKgɄ`<Lfĕ|'[C8ںyVŖ;5N&?ˇ&gck3hGVeπ0{ & X}7cc睅˾byb$ݸtbi->[>ŬwNTh+,3 _xQ+f"> Yu|12UN$u P"};mfэ|$/ %k:qnl`=ȐW_Qr$^4Y0I^w䟅.eTf,eؽGxђPt'QK͸eBe0W4\#ރ M;,` .^ Hv5&xf1cB" +FXJ cH1s_<' IDATK&QLWܼfn ME+tbI̩[v_=\V-]AGK [}F;}OqoD߃ rW\}gy#6N64*b޳:@Y3!nZńY!?1֘>yȊmhSJq^VXG8|#y .R17^_o~{{{?p{˚vadOzs2OyȁSZ 3gSؠw;;evg鉠 Xֻc.4Vs5Bny#z&?71y!#2h`rhxud^s x$ o^ָǓzkM bM<"H^ٿA:unh%;0P6$O !J(Y4oܲc5{?;v ߔ y~k'mActi^LڪǹKyTZ-CiC}faЉޱ/%ar5Sl bA>/J1V?nYgt,ݟZF E7|*,u>P{ 6ϣRC46QҚlTM%Ѿ2vNv ۟+6?aS֧Qܦ4|H;5-پZHs<}\t)zjŇ0c9ˢ}# J'Vpf3<6CrXsI carWTF ff#0r ҃ގ+.2,<ϰgх_ڵ$V5.ٷ ~3`FՑ[G stݲ58:Ρi7_pCrg71&.vP[\<6сqYrLh:KikWQy z;Koe L~#Ĩ1*4x<^wBuٳstUˆfj͵wWGYo5D昊nH3!"ˮ$HP'y6l,\* 5Xj.\[!:Q2UG\}gjɆs?5iί֕0 T8'1;#Ys*2~3+!XlU֚\vtx(òbP0Of` f4]IƩqjy9R:R:%^FF8hqS]|C:6XmnjHqv mJ@8l]ih,Gcߎ^BۤeȮ,e+z%=uShGqa?uL2uGY:g柉9T )隴ngѠ2LaQzk3ܩK?ܾ_ʛ|/ß|SC=coZP0>3O u:Jx*`Rvt 5i+z'cYFp}wh}8x֬0^lS9raKCu b KS{{9&h.@G; {5|f BTs{9{3Ek 1L'N>Z{[iض 00Gy )3| \"m~Cgk 0rB [Wo&Dyf-l$169V#!%{f "wFRy<%n|al&8? M|UPn(x3uFkz<(J8ɕsɦ~ ANo,rٽ1ڳk5O،pܒFAM5pxO{Kyd3ul:l3x:O{Jbo&g|+_o=u9g6EExuɗ{C6^t\`9w}>QsyѸ~G_^m+"Iy/? ^[`80{H|[!CI'ڐ_WuGW.t?nw~÷/~/﷿WW^9C$XkN`ș-%UuL;  %>֐Wц hy “t]:a On;LȣZƹQ[LJ,GtnW?5ūATna,)xHˉH KI/%.~eHZ[S6Ǻ '1bX aq'=^2,.!RI.Mf0!c8SE`vO2fG޾9/mIel|ȚS|JEϧa!Ͽ[!t^#zmfXFqc7tu?5\rLs+qȵ7}g:6S 㜼38IBS9dO!́JаN#.b346 ҟ :|E3^(a%C|΋k5Y5Q8o꓏S?۟C#?KWo}wdЁ)G5g؜O%rZ^bwteRa_FԘlw26W'~YGbLÐAk\Dk8(33,]`UgH Kkd8AO kB*7Ch6Hb ?`|p,&Uϯs@m7M*.O6S1y᫉f8O'یI_'vv7O>}~T4|L!fyeȧ,yYRP-7ssD9oH?cJ3 ފ}"t{+6-*>VPyR1R'WMF$N$gs/puQ^\o?hjm%xqYGmfJȬ {.8=/ `gT/pvD 59rs.8+݄(s>S|0k.gM{Qq+$cS);[/r<ꏭ n}^x+_{Mgpz~&=1tDK.|*b| 1Qp f!G\ :w3"edD.~RMҸƖwܸGWUFŲEAw44o^9aϐ\Z jl{ ++)Z)Xɞ}X%Ajܢ k'Jh>w濻g>{{o|o|_|ʷy?z{)ԡc˝#`ٕޤs[=.cvliљb(/@R@0};Iw,/4FO~A#UI $h.wGe3s5"}as”(' *:`c U=ӿhg+,M/u9Ƿ"fiv^"ʻ\6ਸ/CGeRU9ָV0T*, +uEIp`;bq=9Ń($t HLX%O7Bbʎ5 ,~I8<ְ'8R}׾tү|1e%8?s{Ӌ'^O'Ft^rRs1U *hTj,1LjO@pNp5)&biUr}e1u:J[lg,øpK:/+ r>4́^K:h=E6Y#1Gj(r L'IY9q5w_P&"ٳC3d­zEO"~zS*i\/F (Dž\!Zmak uX=1f;un_ s;Qg,d؋'pABaK/'6)g6xQhh^>'=O'5rxZƼMtZm.@6F/q,FFX!lMsDn',W^>(FPs˅,3sZRa<EF쫠N ~!c6$}Pg]U,jӛQkSf0=ڡ9ř@9.YOp 9Ԋ>̖y¹&m ag]U(|dIZfX91wa=-=|$Yu lWձeىy Bh!+rKQ&# OvZg&.wMN'屩ޕ"e4+3F-W X3 rr;cUK9nMNya?㬥Wn<*}_\g Sag>{?uf_K!}xkrժޫ?׸eryXC. 5]Ϟ▰e@֣]zspEXEzdrͫ-K~mfI:R΁$~bL/< m%NMe1RBIFH: k"E ۳z9ʃwLzN#C +z[ؑ'-a+yq[PXSAzRb G27ȐY=H8i[.. `tn#qo|y}iu`χsZ1ų;}APLơ;"#ʜEi( <<6Ӳ\>'dGl'Sڣld 1r:GHSՀO uLw 9+ƹ&Jŵ1ҷexݍL{<σ[Y͆f=4*0yA<[Kfr{z6,w{I>ww~o|ۺ^~k_n} KnT-s;'QdSOOmið=XY`ݎPQZOڪMoS0n[r60I]rh|lbSƖ(?!,8p1yVj|h CSck$nJ=1prЖUzrO%˘Х]%8_R8/1gp#&Cg٫+]'x67gy|tw67v:Lqhf22ZͮgQ|ZَFl4r&N;{u&F"3+ybbؤ) 9/=q&^gYLKҸ-Zd|OBtSaXz=dTPSYـѝ`G R\U~ˎG^El@lٕrPQ˃V v56)/,a30s ka·l25dMBTh\wXvn%# e O1WHT^:I6ӵD~—y ?6.$6og{o(%y/!3>b i-|#c]b>πl1upZ⺀ DZvԙ`63# @=qq,`΅u&J@A"Q#6؋ڦ;JģQ;n8oA]w]h2I`r657^%pgC"GE7NdλZI׸Z5c`ّTq刷B1uO߼{>p{W_~ C?[C?_ODzḱ-yt&gן2 4SKPg@#$ړ:AUB~Q1Ǚ R퇊nLQG@bG3w]%͋bClLlwNe PM' ΣǡX)kxc^^>PA[N){P7r2)'k\$ =mS!0?z@X^ji"ւ<+n%ͧ<3Byރ8-fW[2C_ZyNdU .\>LFB0YvÊ2CƁf`ԤbM/B fF@(D2>9Aϗ+y+|Bi SK<#c,x1O-3@O? >iVwgy#xד2$wʈxZ׬ =ĄA^IFT6sかΧn5;Lb\|b'Mc3gT ldd"F']؝ʻWOz 2{nxh1YN`yM\+<A6:_Rzn zQǘA`o?>^ޙI4soWh+,q${55SaVt&5?Yx Ε F Ȳ:Jw67J`/rv>/'w2GYK_~r{AK_}Cs3FRHV[eQ}/y(Ӳ+YΩ5- ty߻_}5_qʗr)})6cq{Pe7CƨabS[Ÿ虭9\IoMaK~^o}#;=2G䗼V?3~|{w@[OGThU]OHK|r\L %$L DEaYҶ 똢0 M‹䯄Lf<X3h\= c/BYgxӭv׉Y0ZVClkrܛV+hj2Źj;`؟SE ;v򤀅_Ʋ*vsTStѾ$SdĄ.nWfa@vfd(Kl{τ2'ѩ9!WG cY]t|KHƠ5/5 WEB(` ~EQ%sH͝@ a["l{g6*뎰:an6b{V_ɢ0A_c'bkZ֝-?_F?x1 +s 7Z/==H'۟c?tr? ?g% DN3&5rV/N\믯؃ط3ُP׃[zN[>`/|_?{Q;ͷnWbOSϐ|C}}ut+2CAe _/Jɼ~ V.@]7\a#'cBcC 1|D8hyBⲞd=ú>ژx7KeX&%( fg[Z3^DSLN8LUP52"9(ڈmmsW +\ 0X4.PYgi9D4biϞ Wn<~Wp<٤D{U^^|^埽Yޏ~^K$ʷɝ,=^s)% O@ϮXj%Ee* G${H͌\ ~DǞ* Z'+̄J-$rat K=Q(m`nGM'&,|z˥Xޡ%CYWgX&1K' 3iE:C;Ps4E<60]9 ދ2/Ob9p DOşn>RY  ={u|ӌ?ᑨ\} REzxva xA()yR9I]g yp3t k OP%+wsH1y|[: +jrNxjݪџ8ZX5!麯Ak)dC ?<-8cQ!?' bt[pq]P"> ݘHm{oX{qTi@0.?*߱Q{X5k/B>aon8*NBw3*U޸$= g1#P_! ԊߡRȍc_7,uIPMu̻uS<Ϯ8 k"'Ïn_mfxO>|bSyA L~ccFvzL9-aaRP2Fkq>sml5B[|A޾[('!z|2~#yQwJ9^$2Cࡲg&VN/k530㙤V' <}~ }2u7\#;_x /KWf&R˸6hz}qmPYߩ/Z1,S?VI)Yt;v{a ч<)iΏ&szƬꁽ; \aPDlz(18׺+EɅ Po$}{^]gX#ۙ,xXޔ+B^~_Wh92q}DDZYQpV~z&xa{|m_pgGӻQ8?jxh:l-}rԿe!z {ut49oK)Z>o{;$9WG5A -slNOk)ܯbw#/KZ Hu>y_}4v_0zV/|5-CR5I>H^{G&E>tIEn;cLwF"G\2xfp ` oHmW05_ss*wr0{7b 2, =`nr@q];"u3 1 ǃi;`}I^?]2&׳%lq?FL٨50J].ິ/ PgìZNkkqmv3yu%eԦ҃gbB}^X*}G8<[\㺱OȒk΅'"cc[-'PchDul=.\]e*LGlzp6p @;],[+~[ 9?Ӂ̈́O"mMJnryAޗkv4dLe#!}mOPk}tyƨ osAfDyIS|]?;?T>!_K/>ߧܪԐ7$U/g]򈪨?0mv\3+4Am8cԫDBCsk'zT*=73a\0B{M<|y>hc>0eX֤b ]<c$ D=dʳITg=#ɹ$ӄρ !LmP6dt %>QŸ&'m4o49R*bDj9r9`.R\L?PB&mpy=<䚸egG]@<ιu_.I|+́x*:V6$ M*H\uPK7QB>رYQ8xcSd1ScLeURf+ᨣ!1}zCV빲ӬdHmnY{:e"A)xhWapHS>~o'_;9T|A+~@M;<ٟ95FǦ0 cSf_#7$"f$]}Y. ]T^N?8j7@|#L681*A[ xkvWؓڲ RŴWƦT@Ƀ:Z`:+pω y~~I~勯?7~9ymPQqqb : -sBNc-}Lc˳f´a.6ģggX:^7SWbG])sbo~ޞ|~֕륗nMI?_7>#/D`}Sh|dݿ+Le־%< a=4pq-@ܖdc:}l_B@N-zf!2%#ުyh" Ǧw>y>R[搭'CRbܬ)=W=~<ޮ2gMc.n {nȣd:[^HP.'w}xɹrT^\;. SeN};2&obQ?ބ!Eی["e&znjܬp^UJXBLe6<ͅү}y=ڙd-sjJ&ie=%f&n=Gxr}ƴ4LxO},^$$}pLRifcc,CP ĸ[b&w+ׁ?,ly2BJ9nو1#㊳A027V"4dɅ-ӛj**Eh3{)lD#A)߮ln jmfѤfolYd~ބ=;h6wzCM'N}$] {.f] 6zr)8E`( ?Ծ9֜wb ҝ"9T[( r`r%XY\F7eYiGаvexR1a/ʷd=(jwʗktG揝=9 IDATx'FYiP̉%fv;A{7̒s#One$p !0uu9Ɂ@S ak;0j~nDB &ofI쵊Ksh\ؐc22K#獃`{N#V32?hGVs1|w'9~W^JР% %eƸ"]65cC!v3Au_;ѐ F#/t'aua%#@Ķ{Ju]93Znd']'O|{?GCu~(}[/س5] !g:YЙ0!a o)Ԍ3¨$g?`8%P'q|Gĕ~0 |y>n&Z*gRN=Ex2lͰp=gfu[51gDD:B:43KH 0l1P9ӤɎkbe0't3h8itpO~㛇?1nk*.!r;:QLN,"3߉%~c ʳ);!z̳kHPp>`ܖoO^xWoo۫ow_}s__?_t']G>o/?_wys ^)yKX}~d't>~rBzL]T,_L>D\Odط>-5 erRCW[C՚ka*lWanh%l0v~]8sRzhAA.C'|;ӠS_ksJmzh0ujx w+ t]$4&Z1VT~>ܸ ?Vkѯ|Pէ^ CC n&JN?9T(A m0b@]'j$vό;hE [F6kVA8fߡ#忠}-_ {&k k!LT&w2ȯbFpGV tj]?iLAm#> Az1dc8e Ğ2jI:u;:&st7ew9Rc A\.`G݈pG}H g#(J`6\sx  >Os x]tEO iXB 1pnM(Jrw:tQ%'lH.6r~/]f u8p!d&)Yh%C ' r!) 8ossP3d= aSruqPs ݚʻO{G?ڛGe}sN&229B JE8`QպtY媫NX ]U]F[VDEƄBB朜sz}뾞N]}w~~{G>gA™TY/xㅏ~sz[1ks沏~ Q_G^^\~'uy{>?|[x'}}zG&]pm_hҤ[T3dO|#|޹H~ң/}:c'MoՅ=_ *j GOz#;&ZO.ȽB4pV˻c~}?f[vwk~ {/?Ɵ<|.D<<jVL9IiNHtɄ~KN}TX#`n:r9G|>>'ޖW)ř,'Rɺ"7m֓΍h'%4h; :cSءC}o$RVl cia0A :wM^CtJ7`cl 9m";X8z-xuc.q5`S7ଠ}Y(e :|}B,ŬͫÙsK<̑GQmc8ƆIwxfāvnשԟ/VL!|[]2Gƭ7kNw#n>_oDXbCugn+! a,"c2t#YҳKF#=$DWT2)9ր8Tf\1_azQ\ fCJК#mBX2ξWA_.~j,y ܩHw*Q/ XM쏴C؎ OR;NJx @J#'Fz֊Iw`!dUO>Ό)Ꝋ_ LEǮYqԸ{Hr+DsEap: *xfgg=Qm1ZL  ]B!?%Ұ`(A ?nRڡYDxh O)vqҿn  }H{s|s w<2CI;N:Hv[g=mRkΩ 0@1jQwLg^ÙXG%sH{k"Rh@ClV QgGs.=1Dw1x'94Kqn [q6U4&r]T~SF܈7$[n]tôˆhɘ꯱mub (mc:}|`j ֟jftg0ܱ$V| /ZW>K&ϟnk l{j]y \\ǟ=MH7(@}*]~W~,{_Ͽ{N\U|'+O- `|'>~Kױ@F~Sw'zE@/_"gO~?z%)orsG@uktyk֒i{ӏ [z/Aoh?pȽ|ޫƫ!)z+r6c7{6<*=ttQᤌRvNz$; )غrĽ4夺"\Qnڑ{m~G^!g$[p1ܛ}hmqj&鈲b۫W#B)Q͍~|9HwiX퇏ac֋S9J? hK4SR"7 l?F"-?4';al |b0pQ=)Жop\Y1M1 $NЍ1RD:wi\_=I7 ׺p7z=Wy/[7!ꑓ{l''5a6sփ<#"Sy ?&Be`(a4g:m]pٓ[Z B:[-kӹMʃ9`+ /oQSy?u fmy,9472n7yֵ}ڦ ~,zD3K*/ xt<2"NDǒcVǩt\Lpz G햭mݖI&2怋wx8rrhV>:m 9B ujLK:@\Wێ6'F1NvޯD'r^AX&P,RړTFR0 Ǣ"ۼ))G^tcGO|^gJo7]~z+>_M_S?>߰|ޑngW;gzCMPBˍG= En@NVo_|LT\,-|nnkޮbmPs>Q7UЏ[?[nަ}'._^q/}>P~G߼iE>!_m)K,¦r\7#y=Bmi֩@h?I=&ejhp+uZ> )r7#f(.i=ִ&9?q0lF擔A[Lڨģ[VV `훻|&t+zHlḴ Rr58Ģ= ;- UNNֵn3}nk4"kBclLj>N'rCբkߣrDz`eŮ ˹UO>15E*a,kϧQ(+rMނE֍G01}9Tvwq^o|ߏ> ~ͯx+/!z}%O_ŪSnoK?tKzD7_aE_K>UC>|~;^ӗyӻܫ>+_tJ>=u򳗟=뉗eϽş(9W~ׯ}iz%a/߭zy~ݯσ<˯u\xk^vSU>ǝoAߪW;>pYE_g+쮗?q{TUOL|Əϧx_пxʅt&fIKdͼ8OSr3Hj z䫿94X/HI@ڜ9MَG jOڽ)تLV^PEpb!7S[5d#+n<̟5q?.U]:u2#q!4e$kCi}jg+}AGT4K?[}iM>8d^z]P Qp .Lɣ'K'ɲ=D\[nӊjiRnll!տ7xsTZ(##5]XfK{g!Gjo<q|'Q'<WQ؞FG{&3YӠraz[*V8$`;rxo BRS1;7 SPä4ؤl7vr ޚqЛ \69zuΈwd_mǓ 9"<:8*pd8d4i ؂vƀ, q=TD&TNfkLѪWeW6? s.Gs0. DdEc <'h?\\1$6'P#ob8;s"rmϳjgl6sgS7Atu^[zޯoMzK>i#'/_#?ߑ>gk _˗mGߠ3K#}qx?4@>]f=sV9sy'R.^_>u+Ыoܫ|!3;ޟ9s^_9kA*o[?py?|゛^70^{.Wx'= P^Ի.[~=}? Rx} Sv?ψyy/ Q}{~g./\xuOwi zDhc,Yg2&۽Z) `>.x NPpsdZ{˱Aj VmCuNyH/} bxGD pvƪUgs4j.0ʭlLK݋mAvxRRa!*nhHѳ9 fL%]m&2Hd㱤vWڵt:P&16i#EՆ=TC) O(3$37+&6yg5^4&SONd֟C/9Ʃ>kf^aa Eҵ01=d Wb>1~Z{kd88Au ]ȬQH=,@K2z32ޖŇvMK:D;n^oՒKㅴ1pmbNAI: fUukO Ɖ+W#;rp^{:}$&~RBg&`wu e9VCYp~`T'1簓ւߧ4ٝ^ouƽgCsпw߅-c4RekxD0|FNsBotl!؅junq#ޯm6畡jNŨ6.r5;1> j܄4vlR_ʠ6NMŚt&| ø\˜=Nj\&xI%?!oкI)gN+ZZ\`.[\>>M'=Ưh,w_wsXG䕑||.ew,;|_cۺ蕏c&7H:oOOuI݀}+!I y1 _%;۲ҷc D6Fozv-e9fsqRGLi1vzAFX %.~Ĝ㋋ޞ/f 밣Var)&c9*XSOJv3u]w!\h?3oŇjZ u 8@4wc+J g;}]MT7h}*+ Iekjyĩ;.$8fLj:xh IDAT[qdip6X[\奋G_/oJDŎ{lÖ5)aBf=Y\t5'nH)kx{>&Zn1cxKKxz?Ƅ2Т7Z.f˹[ i][2gy25YoσGp<{z[k`nFK@量[xホ~f1youqn{){|! - R)h1ZݸM@} bd\1qH|d9d^L:_.9Y'flʱR`ktR_ږYZ),KϢ&z̥̞o|m d5 !QTQGu˞BFߌu]Qaa1/eZt6Wz6rnyA>^Kiq )[z@o\Z[& Nۻcֿ .Q3b.;0er6XjYTycR̎83o|^ylݼNO{/.2Z}-\r,|ǫV ]@Ozm^M.AxCuܶÏc>_W~w6'Lxʼ]yVz Շ<@Y#Ez^{偏e7vW]̮+~ScQSZնOٺG2Wou7>>Ode{׺prmC7\Yj)LIizx:r)C+C2 <a-s@;/0uB V* cBXĽA+DBDN41-9\c+_QR#6񨵰|@o_kNzUn"DTGndMY=Nr8EfrkvVb'"].Ub% >Hv'kyQ&4KrފcN?IE'fh 66B{qK >QL=l Z+xO`ϗ9re㐸| i,mB\ӗwXMz&;=*v)й0fnEÊ5ƥslcݞ|1Y-a7;0=}$a1OMA{ࡋ mMUǎE95@ 7і-Ys[9JxUPr]OImZgpF޶b}+(_ K $c>6~Ap֣,@XMwd\}Bv-`Z\ku!ad:4]Z(:8e/\sދ.{7'_pL#8)|Dl.6o֙V?zbR&3.>{F] 7*?]zo7Sd^_iǣOՇ[|##c7{?GDU-~*@1Q?Z&wٲnQjomn5h1*ۇУX{J=<0PKzXQup^[bsRb)Bx!ޣ <:|v)]/>^~ϩx'|R>~[ᕏw A/QgUc*#7 J.EVaa}sPn?=c:Mx)C)#7$'ƛ>hpXv}JNqS(m&!KbbK֍$ThM֯>Y!өJǓdo ӟL "ӍTSȶ0hbgރ3`9R9e,^QTiz<`b5YfY̱4y ޜG]kz DMqF5PPK'"n,R5B3}D; c^؃iVrA]hmS+V:)i}1":֪u֩AF #\xs]1&oz0M?mQkHIV"9=dtg>ԓrH}o:s|nivKB=UUUd5.&!RCelrbHFA۹kKn]0XN_:.#W1j[Tiƭc7xG8tU6 0j_I<}ɺ ^:7+x iu3K{C'@NAǶͩ h;n*98<&uvۻlnvנ9 i/7BuYxZ J<f8QnjzH&ʼ"zV|#([Tҏ}uE>1 >Y1OA iiYw }#ysǨ9;"'44,ªfr̒Pil~e@<)eA'M'%e"^2:<-a]kǏt|XL%O,W!D<@L|0ڵTy,O2%r9T^MbzMSk"Cimy' +Jt'+G>ɬ)[kGUAlE=밁2EL]7gRhB4{Hfsu g%:c5Fp<-Y-.Sphw0Rɢ^{k~i^>y>9NRWw/m-k0z/d*bRY[1Yk6H%WV_ҁ#bĆpk6Y}wݵm߲7^ƓAZ!};.}0u"ҾONW?Bh?|Ts & v2(гC{y[;滱$YOۻgh~9ޯ:A9:GL~ru;ty`l@G<715Ccv}0~HqT` fĢQāAIg`*Ii;2Aoϑ`{@!p̹etIԨi2F{j}d:ՕY'?~pNYr Cu'pg;t 99BY*T}̯'@`p4 #VP…(9F6sc!/Fρq3ҵ-8)pP<"/q[ƌ(;sߏ&yxv&I&f@~LC@(~Bq)M=_8֢׾|Mi{ Ƅz¯Xlä~,Xe"`*FA0eTqMX1Usм-Ъ4Ѵ-.vm\ mHidã13Q#YUM52cӵIAo8ml~bAm;m^[ln`N ¼R= &Y,A-%݁U9|LI1@Mxd=_>ń.3>{@ O? ~c~ƃ5<-=۲a5=Y^uSN){/|H_ax~0Oˋ粲'|zg K?闿=oN:92.m[_>e"$봪knmɈ@V.UD+LQcȎ"*I!XU;lUs=U&Xc܏N=ia;{<߹Y;{rH&__`pY6j$㆗sj h/[(gB?t\2$񵰖<vD3xs.|W|7*Q 0"f=D 1BH`jI]vƆ/8wHI Hrƅ[~H³_uQjK/g\~WY+ ش? 8Z$_imN=>K?B5/MiѷH)W-$r~H zr|W>BoZCoW ?#Sk q1J΅i75>"|ΓaL]Qu dZ=^$Z,7Ta!Vޛ,څ:3蛐M)IS;K{x!φ^䦓>C7Mi.7 mKN^VNp&ml B~DO[4t5._@d?ׯ'GHʈqbG5w1yx缲aѮ/S-8gp8scf?ZV8>8VF~-J]]D9\m H35Q[;M%ha1 _أ_>3>E p:O|#/?~^8! HźQ/V'<ǟ}5y{e ˟V>}~xq/MHx/|v++fw|ϿDW0hxR5H?wy_D5\spAv꯵} +%~ YIc}YghWNY(YT57EY~IIPatI٨]jH _ݙN$w1ρ@*{?o7O/tF1<GjF dqؽg 2 lu[8\۠~rMvf\XOkDHW+ܘ0.GaMj7ςiW7UUE$mc"(3hRڎF^#Q0u t!AJgjLʂI1 `ÕNEYe 5w98 Zc&JȔ cw%cDVlƞ*Ζ5kЎͭ@4Wg^Փ󓎩=(e=qi=x! |@_ nm. m{t^WWp[~}uyRjz zǯҷ|/s_DZ5_mVw\ޤ`|~o> ͕e˻ noEU]>%O/RƷ{1FYr]?~Z8|Q[\>/7g/so#_t~/| |~] (ٽz+>rݭ}y?x<Ífߣ1hNNk#x-M8<1J~*zYPlETtwFI2i?эvJfe^Oc,ʭp ^KPH< ܢS`](N5K{ڐv|{шQɞy]% BWiz.k=+ ̃JxυЎ3$4J`wÊ0- Sb]n\8GR5YvR 'n\̻9~@F#᪠['x@kR뎨=$ޱH{Kjøɻ3)v Fsm|n!`a(=Kw?Gj*M )VьNCk7I_O^ 7Jpv#?דXغ  cw[`!ߑd7NrgA0ȷ94v0T`{$` !JXnJz^S  u}FZ.ъHT%1V}UW\7 &musfK0t^8d5<c7 *d%nyB촎p( IDAT%ʷT x6VX:2D?YAɣ[|H巂^W C/ΝX!(QvL"7 Yj._KbLF'*JR /~|NgϾe^~-x~7"?~L~R}W| Ǟt?;^ç@o/}緌x7_=ї]+;?+gc%Z7-t;OIo0z&1Vyw-}IY}.= y`$߷-,cdޕz7Ɔө[Yjy3x3?Hś]ر InY%^bU.=8- IF.jj$ȎjfYiߚVrR[?݄u`P􁍢"4KnπjoeOuL t]W?VenuBELԬ)t#a{lTe?3_GvO%?lZ^h0kf:7v+ю +*橩|N"$˹ӵ@$4s`6%M;FN}5@}r{Nt5Y⺄9! VC;Ip v"3=cJz=:9Mͺo) v(yC@v7 jf尷}sW's8ˆ740ot5.W8cx|, k?s*7N=x }. {Ko>3w/_W/|яo:Ǥ')X_yu]o.3>T֫$^Wos+8/~μjr\AussN!m56º$.`{aZv*쉗_o@RiRIJv1Ă)ڣ~Cq0nqi35@ocF}?k`?l3ʳ(}4UٟŦڷ@[z~Cv;- 9kg &1}|vא$yC|l3uaxK/_jFZkzۚ 벶AVvH7p2Cb|L |\4 aWb]mƇ]ocGT;f)gi;fFR[= kG Cxc(j$[>t d:&N&o\x`\3 8'!TxWU`:6Hʓ:Xt֎B۶mw 3Ix68v7;`Ǧ$wQUVXC6w;~,7rn*_ۘn}w)&Ex4^/*{@\Loy|۫~/~g CN/y~‡)Yz>;k^_WY_:d92CAzcz3v;o|_{t?oѫo;?D6m=zj)Bë׾^[>蛲nVr3.oy.ߡǫ> 95ˏż>xɺi?+@y?j/zS.o׏2M~*:0Ik03#ӽI dF5jj]~@:GyҟQY!dr[3)زaχd3oi_Xˠ&Cf.NM.ĢqlgY-|;|1/ϵ$Z+N`HήV\:XL\!9/\ịrW0E, ?Y%)Igp&#J\` BL>ju*qs$]TX x;@ ͇$|T?3i,ɑA (o݁H`z/prebw=lo2S訚kTO=kⰕW cя)s) Vx+W<&l :4m7/T!/85ҹ:ѯ=[s!&/I\M]5q;"tU`?)>w~՜^qR oŮJp/X zbJ9G%|h`sun-I4fBzN.,MYQWh2{m0 )G #"LJ[iGĞCCq֊}|ꠁѷ_ tgsgLn1t(Z/:+g,: +¬4.;&s; gT(z:GǺ`o߯ ]-(CZ]|vywȽo{|DyXe?JP0{4| 'qA; Z8+x/q*7#lwD_6|e[>znFU emn17~m J}nROv4I]W ?k1y,ւ?>[54cj5Dm㮰ceo1s sY m^8l0|ڝ%nFЃ.R·*FG*Bi~oU,Ne^kLf9zHII@,MΣ2hijn@1~D1o!n+ͫ=֙yO"K`'|W ?0;Cƛv0WG"aU躼c~}h4u7Xw2fF-`h*v?ܼRp327"0) HE!\ɦ5&zwS[gQrq6GupNL07Yo!9wŲ%tskMcODc1j\HzDsqx6dձ䑃3yFY2CMWҹ _ m ^]n02,=ls|,غ ]ǯAs?&藟ui}Z`E ϙ#?D0tȩTM\rbUT*E5/쭼bF9~tJ'5 6)1=慳0Zik!Ru \ʸ͞鰀WCx E&ƩpݒY%Fdk M]mk%hA5cշ~0F*Xf[JV(R{aǂQ-Xyo泽c6$i1=#O9 >H!ggzV,ul9F4VC>relO} 'H\]3kҭ L րŮC{>>%'e+kW p"g0< pC(d!';#؃6fG'4.`w|l7|Ʉ-^p#9b9fNwiaeqvP506g޶5XYwg|J((wvxZ#7:')nR 7N&-6Ԍ"$ȃ+>Whts Pۜ1FCl#ZsA/ >#5|t's?PXܚ>!3nۉ<0 #;e>qG ne2M9{ZU5@mG~Y0Bt'bѐ;Tϭ',rtby F<9w0M<`2 0WM^iIrf"ڍm2|.g܁÷qMRgޖBn* хv7 ߪh!ՍcYvV]hev$h+Nkh}ԉy Z3TΙ 0`6g?Ce0HHkڝ" ltg=8nޢ!ym&X(XmR{*͟,CsJ(3 Qo:ôg.JK)\|4 !e4K܆U]@6F掠<,<$tc&wh(7208YU`6aS€(5Ww:FVgTF /2=kͿ`vp9pYQٮIJ1OkH±jc"sYμZW2 qLL,)1MC[ 6D |xb⣽hQ_z͌+(SdNaș\6- ϡCnl鰏BDL_׌^MrbsNfd1!jz7x~ݖ\!ըrt\qKvylrݞFuNÇNINɞY:oImᕽm<#~x'&?8 (k: 4lD]eyEraNWd;&qq$$;hߖM8di }s56ý}5cdtp]jm|7R|,R˫8!3(Σn{su]Mfd11(Tn.<Q=jXG:b;pNY/9Lduy@ ihNL60 F+4P2rI¥wi i0 yX7%/US 6՘pјc4q]ˁ@N7 yqoZp <#Mj1.bam0< AD&g{0.ǴsxVq=C q~#J^EaL7Q46֑s)2(GX/b@ f5:p876Q+ՍX*Uhi'^rx xqSrV1D^^Q m %(#1GJ.(I87'Xv _XX t^> K pD7i ec[XdqW6<0Hc4gdákT yz}[Ӽ{hWs櫞OK'y۠m&NNSӨ8meu"CIF_ؕ[_GZ=RQ_^k|ܙ.T>+օmW&C^; I(gkH`ajwe)|EVvkᬢFo|U{6\}j+ RYy-. !PWVLDqp 9sv# ݢ_z 7˘0kXdo,Wv5וP_iomHn۝z:BۭŁ\Κ}l;FLjqp#A͘Z"R/OE08Q"ч=ju3\n@HIcM$rvv:M_Id6 H,򰌞 7_ȑGa>|`bB0#$SfL`ᴼqT6]$_IIMf' K쉃RiZ.F>@;Ʋ1|{jzsw썧(S #zY} :䱒؁Ǭ3$GIܶD&EZnZDz'L{8|t{ Lj"f̓<9d-me:ի-T[zT?yQQP;LSвDlmOP,0Bbz3|ߞE3q&ȒҀ#RT[5 |0RJ<9H߄7I!o/4إ1{N@05ߝvf8)&a j>RUN *ѢI\bGj`Q 5`mHxf b7|aR83#9[H yъ+:uw9JtVMŖa9qGi%|҂koO& IDATV뺃nj[iz<biGT8) 3GkT.t+͑O!I.51hL3UEEs:0j6<޷҃|ǦȋV Ҵn-16C[uRأ;!o-Ix@h+uS, ڥ6gmI GXB O]Y<})Fpy?kj .wO jnM: K2ioK2o+k,66Ɩr>}-XZ_פph"H.h|EPsMBܓd(`Z1lVT0l{1+3TJ^>D;N" v$s:hpYBsuV:axţ<7(|kS ^T6v993{3@Tx-s юY랾6!}rǐvѩR'/aUmFd C7cTd< 9uweDV)hX+5u0 k'kr_^]adN:9rffv}n׮ʴ)N2ۖ\.~zu-( _gߔ7lK5SH +n,ug=ɣ&=Y8(&Қm#'m-?*|cY'.${r o[C(܀݈}Er8=y¨棷#r[5Σ.uƆTD;h~mOj:cx\ ilm늺A`Oз,'%eu4Z] I۔y#sf{fͷQvԃcVkDrDRmɂ rԎ'2b3V;(R*QQzҢاz;^9mH5F; 6iH$Z>hIÛ~W&+h9M!SF~RLfa`Hs ?z) b ˃|4(372Wپ TO  `°ŁajRa.jD9xd (`Q]jθ"ZG_XiW|CTbJqFm/Lk cb.%o%)yN!11fW)~ܥqZ~xL3 I?2ExψHZpLox rDH? 7ܴ&nZkM't bDߐI3t{$eBQKA1X: һ?"3:܄DGZ~Xxn} H /&d#S5P'Ki53c]<8-p5b|NLMk.VOW&fpOd}T>h^~[s/SX*_DN軡Sӎ]3s'yx~sV;c چ Fɩ5R5%'ȽT|>:R(t>J_5MSt؁PSVTۺ>!*ahHT9Q5X8X(2D}2}Rj  OIk9Jh[ 'S2SoT]1@>{nזRz(GE!pZG1 ҁA݊c[ MQ94RHK.߉bp2)>TVf+;݂ ԶÇӒcU¯'o=Vr/G* ]SebFv~ؗ]pwSe =`"jl`>mjdow +5.iagM=jvp!u:YWK;qu4!KSm8Σyp_gt#f5.ޥُp{c¨Dc`j֟nGw,2(Cm/IX߰n6tkЉ?A'LR0R*M4}`ȳjq 5bդ9HOFqRNĺkeR[7==s5&姄kgm+tye `~&=0Tb?L9[#l>Q.Ewڛ ڵ52hWY$=Zk(2l)u-%Ex1bfn.kZ4F+EE.YH9{%'z)o5( أnm6 o{brFۃ*m/{`WQ'tХJ(-t@I M@zAz RB*=XPAB7;̝f–3ɻsf;}@ժrW96[qƺJ1smNt`i@>IMR _!2aWN bO27:},,w/U\^sJ0)_NW.SyK \,~gGP.Wq&d8U>jbwQL"t/Y؁_ҭzGf  2L%Czh~@k[53ߜKVe"VV[3 lD[M BCx3(MWTrl:oHs+~r! Rz]]Gk`^;lkp0(BTi ON|''1zCK'Ov,E`2V9Ńɑk7ccڨ,'-7HJGpN՞RIHUN*/}5c:eΠq\@_/Ni(WJe,懫u ju20CɓQnρ.NUpg(ؙ 7 軑9O=PƑMBI 1kG,a`Whjcb5B+B ug+.$-9CxC-6Rjl!~攧 '3@g*: J6X>4P7||>b-r+ E,2W0KzNIg@0QDdaM'P7c8A>+?rL_`BWfYN4*F&=V"CZ8Nd }A L!Ŀq(l!F8Z0C uä"@;d`d.5OۤR $5АÆ bɄV;^ڗ4Md3`mh -P~ETd:l3P̓cw sc|ՉM%4A2:Zy:#`+h[-f"N5#m!&iz2 x չвB_Pu3̢ɷg4G~*TB9I}r0g#! >_8M7+ ]ח6KL[`TK?)ƸJ_R@WQxW:@_8(a8]Q&aO T30f-Dצ% S[e / 42ٶNùb( aX7.:Z{KwJZU\I,hfvh!.<[\`Y V ]&r]dC-of |䒖"`U9MxF-jձNs)'*8RGp LWsdSY8ږA^lE(N>qdr.r@!|SC).z-聪d- \rbDPEj $b!},3mɣU=|)p-"pN=Czheubt|ħ(ZXL "vMZHDFq>FOTJqMOZڪO= I ¦ꉢo2PDQC$]?+# aF{ga2UZ>&*&?W A)\[ng̴aV`q+0/| C/c" C8C-*)i`d[h `>цim~+[0ul؈X6 yij A^oR[@?`Z%FC"_1E\ݻ ^SokFe}uwJ:2b,;URSmKM8p  <[hC@kӶUZPY9 l_f64#F\T~T>6rlks_R4lv! C#o͢sY@,,v(-tq O?xϞՌcfsJpEYKk)x#!Vn0q%mƥGW_7* Uڂ=i73 d1c,=qj,΋XU# ̿Eow1I-pbWrBHΨ&uRu"7 PIώ'!ѨnM]=k}/& pԦѻ<ćg x@'9S.>%m4| nC>'9"Q=!hͅ4=g03^ru6&Ϥ6@4QkhO٠IMB)ö:tPQkCS P |dܥmH44qyNxԁXe"6I0C٘.ȋlɃWi41x/cxx.Ec+I`~[R^橪j.4usPodV@OTmEfnԪ@]`*7!r׀[ ̀/JFt 3=kb\h@ t.`K ,5u- ZBz1c+K+Sd3\UJI6/Lx(rQI5jU E9 #`( ॰![?yZ=)w>sVRԈOZ`=p)>Rt >ehy#hvJ(uadˆ~{Q隆 -"W0뫇"? URL."+2ߒM/Ι@~>E1 %@z KN3IBP|љڍR(]en@^@ hfņ: <. 슬P}fiq3t)␪멜Jqp]uJ!Yg5`PMs4ˬ Hc.Ie"8B5kF4C;;ea'x/;BZu@聯uJ,Zؖ^JK軟l];{@_Ş}uwTs-S˭&Twym+FPs +kfc7\>dH:U]ٍ4/*[M%2F")\I6r/`;Ks4dʷu -V-p)v'=^SӶ4$3pezB*rTFa 2c4˱ta" ,+-pNE IDAT\:WgM3zɰ"-+(<Ӧl Z($:cj|Q y,Q1hͷ` 8WSMaR˩J;hЛќ/6c-E5+ul>u|:I$0xFC"m.ƆZZ"Y5masqj_s>hJ1>Asډ.cWpkvTؠ9k6T"fo‡;BHqt{E(V眔K41;Wټ1fd]0dN ӗA^>$07?i4 %4M^ZЍH|9:dwL+qo 6Bp~'}X?Gv' t(5\F.ŐRb &e}c<&$+ V8F>flb gv:[)y"˦7JB3. 0`J?h ^ꔑ|\"rM,/b$7ɋrlX.M;qt^UoC\!pϮ8%BK|ٕ*V,11.8| Ƅ@0}Sxv5]3?T0&Li 2*eь%Ce)_[GU HL)m! 5m0/47ZKByI>G!@cP]6Alm]L+H_XvJr.Xl-aN!MG]+{dCgT5D툺lÅo 8i.ڥ[*`cZځU+rcؠXfPD1W%jk[w:jH`ѹYUhiefR..-49Vh47lNg0, EMʺ̆yx>Y?tW5)``zl4ᨉ)rW (;,5Büs5PҎ dYHhP 1+n@u9E9/m#ZT iB ]Ret$B4ZQW@ll)f̘ܜJW/L !vu iAO %h͡e&"&DG*!AUO c VJƐ|ÊDt?d)*̟3E($|(*LrZdK(@2le!vFݤ@MD~8@-lͿP$ 4#\Y5ddh< qsC< nU &i֢@f 2;D$XsĝTu[j/灥 K.{_Wj-j'.d1vuIp I\yAp.~RȋBͩ$],D;:-(ťgꎉdR%È (4YQcEXE滦iqkasFiSK'%ܼPQh"(L!l䪶/̙5EԘ:ӅW&uqU5_ls)sqH7cUlA O&AHShWݫ2UZS]C?JϩPj֬*h_/wU@ {cG1"ܳƬ0hN(kۜޞ呐&l$hӯlf+mX{%ۚ#đbjMu~T55a/_7N4/Y9Bϸk)W[#YYf$o: MjdQˇz^BSl٪ xo6 9a/vGpy#5:1S8ĻVbsRR|--u=bZZj_8{}y]Wݠ%k=FsIN>Hpyl='yg/}P*dG +QAb<"ڹ&@+6=cHO2-EXs>k~,9r~eJZØKac*cr!+w ߠWfQGژSd-| <?Z\Bi+eceu 8O84g`MPƭ _u%J';VTQ4Y\{zmM+x0W0 ~ST&TMk,i GU5{cK,I#_1XdmTZot4x;abT-3%&GlP{ 13*jy(杄GgFRGBA((2}0%] ժO5(2wMO ԅCXe3HfMsٰv21x"Tر Ρwg_.8ԯ(+dɦu[;lyƵFȳ݀0:4ZN]  IQHGLɷK*׋2P=O oxϏrS(3Yl:/aB 2N5Zj=[i2d*rdg )D"]b^?z)"F!P(ʁLE gаSSaB7F^"o3` }-xYZ66F 6,1Q:oE P㑽SQ@V[s`1XMMSWZapp&@Bh*e4) ecVPw*ǟ|?0U;\]G"DhqK|T%%ΉΊL#ByeCq"Zތ ]G a- 0.lWC@TS)Jn!ws.SۆP-;>7n]ݾ5x Yڂ'RTxZsM(|LO2>`CeX˕fEn-N2ņh lW}Dw=y쁹X^̔$G#>B+)ypEH#2)oD{ԊU-}29UsW \4 pRT)!nSjy/3>rfG\D*uH^pxù̒"g$@l73aJ5f6 bAHR4T̤wB*3w+Tmc|L0+/_lL6-/1OPv2⛕V 5*d %zZN;`,3+$۶4iZ#=Oݰ' <(nuhTƭ)ASzflb}UEW}HV*o̯z4JeJo},'ajΫ/"y(}`vڜGEr+[nnO~TK!!*.H WzT$F-AQ6tvTd%a|k*lSUw! su^u:;-x-H1`_Bieܕ*5lcүWqt,E.yqNѭ۹NN֘.Ԛʜi~k2rϡW•r8> {YZUOšY\z-8 շU2r N+/\ M.'T+?9Yf)ُ(=8tTƃ [|Ó"VQt ڴ ,hm/+_Uߺs[x6*c(Wc}I[j(=-49| FXϼ3/KPN -A[)Wu|0p591pk}3QKG%Ě>%5\y872-%_3rn`'Eara)ٮO2(Ыtf0ʫQHz7ߺ7, GYMƿ̂ +iq2A(`T9;00K280mV!XQl ґv5z`싈2/"@~MIIUZUb85z2ƍ\#/ c~IhڄNXZ; L% *c3g4e0UaQZ80?Q4e ڞ/!t*@WC`pW%Mrr>ǁ7/ar=mIkhsdZU վPяk1 2x#7Ha[Sv6=+f]SvvG2c,aJՂkPؘW!22K€-cPI BHw_yr,9W ,,"/𝝚dπJ=*WZ̡ꁲL!w-DrPc. EЖSu''w9"+'%|Ce5X!o)*4ۮeUk|ףbcU"m @ۚnM7?52K#r1ڝ^Yg_ў팩"SOWj4tXr"aX%5FQyрj԰u^WI=sZL:ou:8 I㧊/Ȥ:F []vb4ww^Cր\Nu=ʷR5]i zq!rxC4t6~`zj>d9VZ1U%LTm Z T}/d9)c6ڰv6 pkECIFBt m8\W~&Pl!SX=b%$ *)~>Ֆol WАOev/ cj!6`6h -y6;E!aF{TA#Zʩj!eϏ2p[xU/RPi02Ɛ_EA1vkrο!j4F7DVcKc8[C sԟK rr/+-rx%O4&2!).e *lJbOV-l}gLN'+@ @ @' 9tp@ @ @XV @ @ t"Dpu @ @ Hh@ @ @'" N7\@ @ @XV @ @ t"Dpu 8 IDAT@ @ Hh@ @ @'" N7\@ @ @XV @ @ t"Dpu @ @ Hh@ @ @'" N7\@ @ @XV @ @ t"Dpu @ @ Hh@ @ @'" N7\@ @ @XV @ @ t"Dpu @ @ Hh@ @ @'" N7\@ @ @XV @ @ t"Dpu @ @ Hh@ @ @'" N7\@ @ @)Fʡ@ @ = 7ڤC:CQ @ @ t &bD܂%0@ @ z @ @ I@ @ Xq^@ @ ]Xta$@ @ ށ@,@z8G/@ @ .@,@0D@ @ @@  c@ @ @@  ]b"@ @ @w  1@ @ @K  .1 D @ @ ;He @ @ %HH"@ @ ws,Ζyr>믿y'|rx'ȟk{G6{_u_z%wD{c&MIQTk`3vl:CӲ~?Ҽ͟Xct9| 'CZ|%n|ꪫyep=N:+ ?)m6 ,ȹ+?oKmC3-BiÍ6N䑬bĈ_WA^fsj>aB o^|AR+@ Xt1Q|(sͷu-^kР4L3eٸqE_ ^[eBc+~ZE]>⋴6۔W}֪,O<^zvӱfve]vq*?l:/rZg}ߟV[m4|4|x=l;lx9rd3ÆEY$=iͷHw)i->wǤϿ i}vfv19H;3]{nk_B7@ ]Xtݱmi)Lctm#Ho>tH }믿>oxmIy矟-[<vO>iյc`vyW"\?eArkwnZwү~+Wg}WV^y[? }5q '^{--rMgyf:3ܟn[WX13ϼY֞}{{V\)5]+]en1;i~,JsUO)} .HtI'o W׿E3HzJW7{ȡ8tYx蕘k't '0zWM74_\yA@ t?bƬGeʁWA~ߥ1cƤg1 kvmx2~%|pb>lmk:Nߓo|z4S /EOitס^X|4v>N;| ;' ?AU ,8pV[v,H~]Z{=P=HSKeYh&?AZOnAM)UV^9}L7tS:Sr®6B*sQi'OCOJ8 vi+N9EO3~EYx6:4JcvqR w-s.;ʂgk Z̥g]mpO>馛onI{w/wt-܊6;cSO^jXU 1眛arUƋc9%@" ;v=&sqm[Vʯ\h s̑.o/RަQH%=8D9ǤN;5]iP ϠLlQG/omq},v.To%裏BZj%LE +Mo{no| 7>C睛. L\p<]Yw,C`ѬiJ?t}W_ ,`P06g?i+;ɜBޏɕ1t;,j{qzk18{g}6߱[P (\`q\smW^\sM%.ۛ ,6dWi<ovc=,9Z?}Yr%~!60J @D  szTָʁ8~~?vFam4x+ᷡ}'o=Ky ,Z?`}w6zquYIz^xa>zVhd%_䀲Ȣv8d+ m喴+m}L$4+h+nV̞bL;1t}V+ 01Wu?^&eav駳}ǝzUJtPzV-,F8FaX&ݶʄmjXp\"yyw:@! n6`=1]<( ߨ;i²oOprvKQb|[ߢ-ުחK [|>1zțLn)*Kcesͥy\ ؏}gL|;gyKʊ+j憂Я-sZZ\_}y=xr@ -z9FF= w]NYtF6_^uj O.l͖}$Ylb??V^e{_?+1(lq-\dfIM qy;C;L?o_=:CD!L]I]]vgnv{?!=Bn1{wmoxe袋&mٺ, 9ӡa<D>Gn<98Rn{L3Δ|㏍mrz53d *s4,3=~gDyL"md& )?ܒt!3xg{i3w{I?ߗ7W_sMoFVA5u^{?!ÿ=oPMkK5xt o@4=ȣ>Tŷ-m;afYf;c-24oq )z%fc9\}eRT`AqEHM7]Nb^l gr&zx_ylOY0 MOB3dx.~?ګx;#^WUWK+A o]9-Ĭ6?@C/\OB6`. ~E9X7nzQ+ǟʕ+RhmO]Om(?RS,>:`@ ЅHH%Z"W~+|!-W◾ nBiGz}6l[~@2`?@OB  =i4/׌5<̓Vݶ-YC@ @<ީ@ @ @ (+ %Aw3ɝ @ ՜I`zH!-_5 @ Lp7C/ [ݶCxF n@ @ = X@ @ ]Xt@ @ @,@zxFo@ @ .@,@Dr@ @ @B  =k<77fM= 'iyWhUFmpΨ?tiu@ x7Ӭ4!C9昣UG@D  _%#ۏN}W֏/rb}ᇱ B9nxYE  vgGt1gٴJ z%[et葧9[15~a~ZnjCҿ|jFZ{bKtJQJt᧰w`1(p3.h+gQv[}n4<=8uۯIO?bZf ˬZwxz{X51/1h@ #pQG#<2:tΧj[zHfzꩴ.d}Ns/FZgu([a/m>䓴j? ,"LONk-uσidRO>Z^&|4S忿dy,lB6/Ͻ?BcB<ݴ[Skq4@ & \J|u]i饗dmǧz9䓧vYH9rdfm^{q*bU!q2[ Ft7ۯfaB;Fz7:*F|g\ @~ÍIeiӲK/.lt{d!s'?$#{@iyn}maYuw-~s=54 Wor^o;x@ )jň#ҥ^oa /B+#+ʱ n!ꪼu ϔ\tQw}w|Z'lt߬Ӯ:Y;픞y~p[X@F  _5O)~6\`F OHx<~iioRA"~!>~{^tmw_[F]XNLEyCy@Ni6J4ς$<ݞZc{'{VZb=x:i֌?<1du0?ď@ 0q!nqM75[_|;4w&ns®JMݤf/@_۞pu+.@ tG W7p%#J X Tyh,kqՏ8J @FoRyo6^p]u U! !^qQp:n2\5s)ٱKmYxV@;# Q AV~o9Te]'ۧQmw同vnHz;s͑<,+ ɧ{[k&y-rxӅW>@ ozϠA\W^Hs=w:3$'|/XI4LK^x!}P F ЍH7ŗސ=h7v`QXvDnئM975V7E`?^}2莺X`ެw7<0{(6[7~pYgn*x@ =~￟V\Q׿u_=PߥQҖ[nIV[m0 6 vmWױi fWG 1ƃSO~Cywig^ۥcy-="\q-d`qiӍצ 'JV[K{EꖴݶzQxYg}1~v__³72*-i^`4tHǞx^R @BW'\n Pٮ IDATiji=B<nj~^z~n#wƄWЮdf_sW~qML ۦ ν*z1"_~Ʌ t^4<jbG$\ i ^w@zϷ@ $ .({+#xzСCߥ({ӼK[lvuׄ!m󙑶tBtubGoV_mϰg=EF[Jy^.tWf!sA~r^5x51|MA|3G}:7\D @ ;pՎ;6zzG۲fnɺؾkmÇ: {3Gy$7|D  CfzNgrx~ joNZpՏVeygi}Nߞ4paM5Ք鱇n&}ɇ-;u" ;4oA1@Y4+ \pB3@ ;t+,pgg2p 3̐jO?YK'tR5#ctv3 wit%4s@ g;cu$ۑ#nMoIGLæ"0ƎOZB]@ oFɛJz4?\ёsI3l&f-` @ @ R@ @ =X@ @ ] Xtd@ @ @,@zF@ @ .@,@pD2@ @ @F ~go^k%@ ൴Q@sH^w[h@ teϻr[ }[E@ @ @C  n"@ @ @" ;vy @ @ HH8@ @ ]d@ @ t;b,@ @ /c@ @ Xt!@ @ @,@E@ @ @C  n"@ @ @" ;vy @ @ HH8@ @ ]d@ @ t;Gub6@ @ z}ƾ3f\/st7@ @ & @ @ FbG=@ @ |Mk>@ @ XQ>@ @ _~ Vk@ @ the  F@ @ @ }ew8Z a@ @  ^?#һL6@ @ 8zDZ @ @ @ @& H+ yxѴʫ/Kw٥A/L'4zS_'x"A H܀ F9R4.yv@}͎yzY4zS_{4p&zW@z @>iwƼ~O*iTt: zf^iL3 !>Ao~h>\Zkӌ3M32kZy;G}KW^y9M;t/d144Ӧ9VOjOL;卲=|ϧ=\Nw߭&t<^[>`ZZncjG@oo aǐb~ؑ:t &߾}i 7JkF:3TSN~+GqSL}v]OҺ8Ɵamޖr+H3OzטWrDtΨ0_HN;m?v}뮻Aesi%cǦgyyn24zS_'L ׆@\迊UbY8l\?z+xnZpҰfCpt\YxS ӒK闎?7޹V:Æm/LW_}M.y\e!:iyMGydΣ_q8}WX}r6Jߙgɘxf5tgm4s_>蟥+Moo"'/YU`1iM75IG;RO#A&2,rBڞOVYe~OI]tQ:Sh/N^{m:餓]em&=ȣrk+5jԨ4\8p`{%9xt5פ.<{55?x9''&9? 7\ۊK/VA?\;6ÏvLof[qF:m骫N|t1P:.`!>]v׿-߆\^;žq'r{'܌4 , qoo;&4_hn|?HW@:Z@߾7i9p}1C#e6g}6ۮY,䒙?f;nO3KL!0߂n-OEXƥvv9i^y_oU&bs蓼UʀO>onJ{CZlM|}bz1/Uh- hnFݙY{_z:4zS_;c@kB` wkJ?–<57t(@{~҇~XR`?f̘Ŗ[vOn 3YcjЬ'tJ~&'xR_2ƕ< O=^xf1cϋ}y|?`֊ x΃-uCO[yt/oGt&iv ߁WD/@7_u$O`Q0o~󛩟T7xpNʅJKii38,%S O? j-rrg:>4`L lۤyjɏw9%UyC4TS:PiO~8]IjPvuW@J>,j7ttG~1[8̴߾ e.y>'vXz//>O嫚u`?}i5[vn(_|&"W_}-*^MUjȦUzXsoꢴnԭ qZoߣu]6XҞ'~5? ZF5@@` v 5zӅx40欳Β{%]62Ooup2`Ӽs37<„4h-#x\B^hE睛yk|3tyK.?&73unTcXѻ}uU/V3ixO˯b£qƹdv( J!}@멉1lyJ. }M:x˛JI<埏Uvޝx]fRZ5,}ܞD  _l#{NTyj o0\"hu&V>rD[K)-`nd"^Li`wboV+UѠk.y9]#"I3{LpajR5ݻwtaPG#6޽'U<蕑g Py{=] H[0#3 E_'6!~zʚSV+7͛(l)ɞ=2evᘿ_!߮k)5zW`DyA9SI ) 36&MHwߕԩSɎ;S״M^qشŞ} 'a-ē*( ] pBd*Uc|VXQ]_̜9K6o٢c\ީ&XS=-ϭz/WR?Ωa 3ey0?re=+dկ:U< "2{@E~x|lٹs^{vϷ_,z^O*T Ӣ;veGgyVNj\xQLl՚kaLP_ίK_GϟӁp}u N o>DyiղZCjǓa& 4G;= 8 T@&Mran~W_-̿!)3\Z5k]F3bHѽ.eQVx;Vڵm+բ*ߌF7մ e%Kzjz8~+4 #7jQ٧IbťNzzUO?-+;@RJez HM1cHƌ2;%NX*y~}ot}0Pʨ۶'[Žuw&)j QL`r.}ɛ/6=zT%·u b|eϡ\vÁN}u9b\exzw9F/,]_8הqaFՋ cQ,ESeԢX]Ļ(\m^Z=R,/o5eeHnK.oNaÿ TXI*E/.KttTpz"E@Bl ~t@8oλQuPta#[t^aG{sϙ,2sfϑOǏ@MS?7iw+Wʠr\ `etoA*&/v^G)uFo7N߸^y]/i49|H[̱i;/kn\VN^htz`+^~'NdZ~3iҤ%c^d)nYѓvx*Cׁ%tV3mN oW?ؼ&t$ǟ]C,umN~b1cnmyWoϗ/La*QZ`I \oX֭U/[T\?qiR8LS/RniÆ:vJYF؀ Yf\tI+mPfx̕[?Nm5Ba}[\LLfqRu{t`az[Uz qlu-&JJ%klRRla m;/n=bԮ sHHb`Ÿ!e&,Qۦ<|+SMͤvzW\b.l$xW=-be0]Bkmڴө^cIٳfد1s,틍@fMt0G0|U`ҥNXR֭'PTftǵj/*ppC[xR&ԩ?ވ^/O?5DY[(5UT\a|`=#<}5-m ."NTqf)@7H$@$(E Ϗ$ZҞoʏ?$}~Q]-EF/}% {erCl'O:ߔŶ ݺW2ˬ%2A/g3/ ˝;?xFsfKWm\LBsf> @ oW_#- Q=~#%Kf=Y>yǾabZ2Ep.۟"pz~oΛj宠> h_ƌ/w{ ͘oeq 1 zw˗׋#Gu?SK2I RH}@x<$ 4h@+>y&k?/:^U^=ywUС_O~W_/^\yB['ʇ1X 'An#wѩSG+WUXzZl,DAv!ҷo?m(xYtC}hno\RȻK q]uȷJy;څ!0B$@$@$:_%H 8|~3~*U"֭ )7!'[lyv-"ӶveH @kLB+-?/M`5vmʄ :o,joYUXA) "zK$@$@$凃& lnR٣)S&GfZw|-HHH DXaX`03rGv:Ӎ9Gs2:$@ktFˑ@y75ےn7A#+tR_|"hFh6`l. DgDcIHHHH dOSYw\     $!Ux+*&    0ep_.XFIHHHHJ HX< @ P 7:H$@$@$@$@$VT@JIHHHHM Hy>q֭%KqB!    $ I|vk׮njRn]g/Tܹsǩc$k֬ZIpCAoTi498~[RT)ɑ#,YR^{5ټys4I$@$@$@$  jVdٲeru"ߗYodɒŋI2m4ɜ9S װ ʃd„ qF駟\r2~)$@$@$@$@$ V@֬Y#bzI)֭K.ɳ>T= (F09s<&)֛k\vMu&哢Eʐ!CÇ2;IOKܹq+Ͷm۴+W.]&M$UV9sJٲe믿vs/իW#GJ2eVpaر3F3YjԮ][ٳR9`J$o޼ҧOrcdZʞ=Ό7dqK$@$@$@$DXQ^ZҦMC\?|$H@6m*frǨK˖-寿3y:nܸz"n/g}ɂ Q[e/O>DV\) &.],JW*G!'OAiK5(P^~ewZg 6LЦkJԩ'X^NXF9s[:t 6l^tQHHHHb+ @?L]-8FQ|V?CN<_~q B#X?b!]_ .XcP~{}{Iҥ_۷käuY`%ܻwOF-`)S&\ 0@+%.z m,ݻwMW["zoϞ=+83fr 9%JbyqHHHH Fy.SB"C@>9s.ZH`;iݺv:}V^xwŜBܣ>TX1s9r$D( ZiҤ4(Rpقp!ӼysKy0K]J`VX]n޼-Wo꯽N=zTBg=zuL۸%   |] T|1n` ,) ҽ{wmHh@I]nwwipo3sX@\`%' z?[lsA+/I$ZU*x7S[wܹ2j(I"y7EO$@$@$@$CT|>ursiK܈)O<ܮ_ЦMOł{}׮]9;vSJV\p*~k?<;y(pA%nv `amvޭ< /U|GXlQHHHHb}?(!$9@oe1O+X^z,b%B~[9L2bNy4iRiҤG+Wo.PNPd̘Q+VOkײ JӸ}/_^iܹS5!ϝ`rK\]xQAiqm*ҥW`xҥK ]ڣO$@$@$@$@ђ- /ԅ 3b;/3&p M9'7ewϯۇ4L̄ڜ-܋0%uaH2FeJ*Vʐ!=ԩS'redɅ _ok+k֯__X|riԨTVM8 cǎyHHHH fup,?Oڿ)f`o" _)PVJ$@$@$@$)KfDU(, 6HHHHHkHHHH@Gy"K#al '@ G @cϞ '@#IHHHH p P ܱgIHHHHđ$@$@$@$@$س$@$@$@$@$ PyyA    \T@ws    x87nT\Y?.U|g:ۜO?߸qc9v`⊶7Ҏ?nt^pAO61} :T:u$eʔq*ǃ!>}z1D 瞳{az3gά |ׯ_-… K׮]e߾}zqoҳgO)ZTVMڶm+SL #Q@(^ZҦM`~;:tHOL>?x@ .,Ν%K?>|) Ƅ dԩZ|W2rH{ƍ2i$ɞ=S_~~ <ҥ|2x`Yjď_tERtiAcPk+D_I$s^tIva݋@5nsp[ӵR(ǵkc}i}ߖ-[ s1wHHHH լ3LZl)#fЌ3JrdVKn.'饗 4NWXQ?1c> I(#P$`0O[nT{ァX`^u=i;wO'aټysO?V#{>ܹsu|NܸA^'Oԍ_U ӡx}(ʰAΟ?iҤ[}(6QHHHH_ H(8.\޽+˗/f͚c6Y"ŊcA˜>|X*$1.7(c&4X̠Fy$n3gdÆ Zi4̈́uh׫Uʻ+PT*SL7?y@DHHH3S@Ӯ :4jHUٳGv 4}%[ IBw:.LXq5k SNti yIlٜbsXB`03gNA\bkwAX@p/eXBPSJEw<[   $ H%OvJ= W,w7cĉGoݻw[ڵ*s0 KɷJ,+' X52gX6`s#ȥNZߓve&.}lbNXB$@$@$@Lo@ +V~dɒ Ok,C;F-ZY $+Ra#ZsN6m95[/Ыy r]< vu8i 2X }%&E `ӦMwzU,E!   &-AX=S,nqC4h_oF/^<{1XW^іL2q}n3AlX܌5J^}U=E0~1aGX 1W֭ *lqB`6ܒ ?uh0nyNa<zE"X4B/<    'S&͞ W^$p`"_s C,J$@$@$@$@$@+ Xq/=,xgG^4|y&b3HHHHHxxú;Aк'D$@$@$@$@$@+ Bɠ _/n&      @Fm     !!L& !c!D;B$@$@$@$@$@^נYHHHHH@$B !     0+( @},:F/$Oh0fGIB'A$0@2L -+g1ˏ˽C$@$@$voZ'̑5=&f`I * njIF͂Ǚ?zeL@Z)icim hإ<K$UҸrY9sS{ztCYzLW.JrO΍'w9:﷽ν %8vXRhj)%|=mB$GM/ߕ)8N{8HK"={jLC|kK{Zo"asʡ][Y%}]I_ DH1sj'r%b9Տ߁;v,y^e99șⅪYMIB%M2aqt\Ʉ'eױkb'|zJfnrZ]వϝ!P`*Y炲,\ zSC߾ocM$raO[WԹY *-Hi-#@)%I\)rp٩Iٮf6Y=qM7LR&OJw@*I<]i?3ޒtY^ gOI "zcvRH\W֋Գ~9:C;: D1'L=Q g%=5>kԄU eM*bxCU,WvRh&7ǨP|pz3THX6w7cq|)eS=ׂlv.N6* ((J(N\wzclI'\J u}gF|H`ۺeZL[ɚ 1eU$S DLT\ef "`"'cYYθzh2cS(ĂgKZ8Dy [zm?aj P60x%i¸ _2\6'qvG4u\I{ Kk>#@J><_5}\)UXj>qN:ɮ_5=b1*oJ0bRX!ʙrK%phٸ|zu>G$"ܹ؇=&w??/&]1)đ YO,L=Ճrw=)KL҂H - iAaJeZum6u>X*wr|rzt,%ʽ.lĖ??AU5j' H)=ɓ*sAczKbʭ;2ݯbŊx8w?k#]byY7%˷Qy@!s,2R.:.e*.~dJZM͐c DH Sq_gohʂk:x<ɵ{VF ҚXO@CGێԚk u4"<6CAU& [(M,T|ДǁWnܕ,jyZpkg.oo#F;ZL4N^ 0wW#$ʨo>b25ǭ7'}p NZuT.G q' ܽyCL+~KJY ;'3[UR8~=sVzHՙs`R5oHirP -sR.%j lO/KM~󨳢.y=d{aL[O[wxzrw IDAT_Ȭ%uQ1u{)e\QJ/ݕcZr˿=42j7omT %u:WS R׿ o rKټ䯃A1"jCfh|@HL#["W'd8,3eHHG$@`̄G2pІjI\Pzo>-d9m_V<^7*$n DG)̌|X9jXPZ1NB Hߒ VTR( ''dJ+/ʡ1rN'9ț)VVJ]-FqCW`ji6@o jyM {T@WT     pG ]Ae {R@>yZJ$@$@$@$@$c L)}3y" 0cq     ~v<HHHHH  NkҾco  @@poݺUd"7n4 @`>kԬ^*W,-wx!a$@P $d;vLZn-s2eȤI]xҥRV-ɑ#TPAV\iW ( %J1cXy! "C'ȡSAuI Dh^?G~Kp+"ٳg+VhZϞ=vZׯ|'RdI9{$LӰadݺu2gxkZWU;$@$$ 8L._'S&|&EHZ@8XǏ5j8'Ee˖9;>}+WNO}trG}$yŋK޽ } 0@6l(3gJ(-EjժI۶meʔ)Q76;-KET>X$q4i"<۷:O޴iJJO}sN+l"!v2p@]ɓu{pl(7&LSj.:v:Q]E#Ay%ٱcu_%Ν;ӧO˹slٲVGeT+;~I~9,lT@@ܮhHJB H:cƌڂ`K%~VL*ԭ[WfͪI&T Hǎ[17kERJd|UVx…ek׮2c {6@|:T\rEJC9yn eF) 2D?^oq>1Oo-aF1P>>:,M$cԛ6m* .gb|ri֬Y5a %qңG}E |K/pB:Iw6m?~`F+fvGuɝ'N ^xZrpフ +|]V*̝;WM{,_α -= @ Hp`EI"  35Xl"7nc $SLڽ.mڴX!}.\X>%e{y&ΙѬUStlY3IM2$@$*TBE&xb +\$l\vNA9rc( -vqPk,;HA  (]#ODweveݺ'x {X F]PDҧO]PNZ0y9>D-V\z]+%u@G @P@AX`YM.WÇ׮R'N 7o,իW fIcȖ- JٳuP@u'%iX  k޽2v`m@@t2zh/ X3͛'k֬ \ٲeK{c%+c]|Ye,an s\*`@pVepbй{nL%LlB́+%NiܐNJ4n .[v*P8\kV<dʨKtҩS'_|Qwٵ,ڵwX1KB Q>Xdn\͛7.]襘4h`N֏ MHAnVc'|R$OF+A$XΟ v EIW;aRT{@\0$IDusx} ("߂(/XX> ^qg~S~ XHHHHH  Df=ޛRfΜ)uԑ9sjDڵkrj*]Ν[Ξ=+/_K\~r6mZ2z6mرc_z˖-]?^jԨt-()E32i$ZSٲeu>42}t)WdϞ]J*%ƍC$@$@$@$@L &ԫWLαu8>| xD@8p:1ydٷo>;l0/eڵ:uj۷:uJ,Y•*< Ay饗dN^d6iD:h֭['qRIr˖-֮d.[(%Kt*j EV~̙_~ҵkWꫯt(@`YtL2E *^~e~X˟?nM0A[1޽'|#/i޼t>˗Oʔ)#7JHzAKHHHHtԮ =8$IX_xڿyiFO{%R]voS0nD/:^ka_+Lljtv:|>}hW2 >3`RfM#bp= O&.x$GzELUxK#^ be*U$ .'NHÆ u{p~,UTڈ4HHϔ)d˖M;v+Y>F^QHHHHH "Ϣ#Rε+!8=:EěKIܹseݺu%O> A܉;yiF+/zTRɮ]7Њ ,F)@v((.fɓ'>`{V3#pJ, ('K1bJ'O\+Mz 12{\IHHHHJ/t(!5k1!8`B^V-ZtQF%9r(ժUU޽ۺġCʕ+Zi1V ĠE kqr= A%MT+P^p1!P`` $P`)] މB!    _ u>J׵2*w!}?>b>& 6kפM6ɤIP^&L X|;w݁ʃ`$IO 1poRLh,P w#NX)a,7ׁ+\b>m ֍k?~|}9IJ{`=$@$@$@$@$~#ćWd@qhԨr`]1dɐ! 0`֥4tP1c>wUB(P v(sC`ؼytl)- X6@ qXrL=lG0; ڲeVVLآOv=$@$@$@$@$.?8 g.?Oڿ) gnը X"O:PO+Hd"%   E`Ҹٳj[@ի(: nRp^~ׁAT>eIHHH  1IHHHH|A_Pd$@$@$@$@$@^&"    * :HHHHH"@+L,D$@$@$@$@$ T@|Au xE WXHHHHH"     0 /PEA$@$@$DkҾcott Hn*Yd;wDB|Oܳ7n}嬑H LXjo/+;pgIB&@$d>O$wҴiS)P'BS1 O k׮I }FwYgx|>t>ϘCM n@O:d&Mg~*6Iذa$JȺT)aÆɺudΜ9rEy$wR^=]&|vP]gϞ2~J2+x$o޼rĉ;?p,]NLLZΦ $=w8?jŠhѢRZ5i۶L2ū|o^Zwɓ'קYF*U'}VSnݺI|m2d<|d{:|((Qc;&MU߆e_m1=s.\Xf͚e;vo$4?>|XXp"HjI ċADnRFɅ ٳ֙p9u,YD01xw<Ď[` O!}}W_9AUCyر<ӧܹsI(P!sBۮZJ+Ǧ &ȕ+WsΒ-[6t _~o>u%mI&z?uTi׮lڴIǏo.#FܹseРA~g odȐA,`TRE>giKUʔ)uC={O}#H"qS&|NG$1f$Pb41zԭ[Wfͪ?4<^t~2]P!/?L-̮dΜYOv*T@,,;&ʼnGZK_'ϟLPq/Z>4,oe+Cpb ڵpBK.?h$|g&ҥcAz ʽ{dZ9(VF)S&0`V8@7o.˖-ӖWjv:yb{V|ɣcEC>&(|[zVG$ PbPrύ7J|4h-Ǐn*f8޾}|guVfn߾ϋCF&9r|5nW#G I͛1' ߻?zVx;>/YZ7 Qd>tV`o\`I$enoJPH 2 ,YVcZ6Kn f IDATD_/O*`<1o<ܭHX̮͛ҦM wTto* N+]mPc#Yd q`2Z7 ~es<Ǧ>{}|S.зc;9FSX`3wr륗^rwH-y{h+Q4N{Z Ze${vt{.IH4ܝiPG VZh~bJBFvmvO:Ot:PݸXCCԷlb>HhI!\2z#6qwرC5yfLA(X4pbq ׏Q9<\`)3)VX! >\喛5kfN"puɮ ׅBsۥ @X-LRzu/IJÆ u(Jl`e#X {a ٻw`%5 TSH}b,yE Yv { ]gaqcou+Wv*xX},o P-uເ~-_\ԩS#+10=zyUq!;wnoȃ]ԬYS:SĪ7(> X8NNk+= vBeI4 98 .0qlґ?~ZסVr(rp%R9stv?C)(5e*4l{9rrGYw܉qDߡ^'sߨo~޽{סVErICc8B|.CXʺAesɰC=Vb;T`CS¡c'|PnA^Q*vġ&z3m4,Lz@D{:ʡ\,:* ];r䈕 S3j<@X ߰őpmG XW'! G9_xtEIW;TC$.YwPHH[ZuіG9c?%r$L8^7 z}@X{cy*VvH hm[u+zR$PQΐwSX @tկr.˒ ! tC[    HL|PHH "h=K$@$@$@$@$&T@„IHHHH"B HD\     0&\,L$@$@$@$@$T@"B 0ba     z<HHHHH L  xCkҾcoto @ uVɒ%ܹs'jg$@wƍY82˺}Y@Efݮ O> i>+߾}{={ꋌZ,5뷗K^KN hL  ,kז9rHѢEgϞrU?hPB]?yqrҥRV-=*T+WZǎ֭[KܹL22i$+;{MJ: ~@V/^\m&'~= \pA~رu'e]vҵkW}gRn]d/TPWȚ5w7ސaÆÇU>, #OoF !"@c޽;.SN]vI=elBD`g@ѨWUڵk_~ҫW/ٸq3FO4Pp+" $+Vh_:ҤI}1qJ%VX53fHٲe5Njժ,[L_T?,ȷKdd$6mdΜ) +޽+ׯwJ 3dʄϴ6 * ^ӥ\r={v)U7:x\~r+;3gΔ:uHΜ9`ҽ{wvUˆ 'ƤM}e5;!$|%J{:>dɒ@C壏>XMOVCJNuĪ˝K5JcRTH=aBŋOpa9k,N'\L*U$y>}7 ߡʕ+k{?7< BໆǏ*xJ e=GaTLCbK&@Fk0k(OY]-@=~;`n$_|;d{mL\]~x|VCݶVKX܃T[N.]$>S5PHpyϛ$-rJ(KG"9> 9sFO:t 6l^O̩}SNɒ%Kf#F,;Nǹ'O}cB+WH$IQbS3cǎ &P>0I7qCx I0֐۷[dJE# s}Onz1amS`Xx|W2rHlcŒI {|niХK"WZ'vϞ=+-ZҥK QH(No8q￝vK&xhYvhEXLcx؂{pZ!3ᕰ3oA{oi;wLZH[|g&:cM֞,-[RqbUzur8C?3XzT%@@ܮ|D($\8Ʃg!C=v [X 89֬Yc;V}fQ 'Y)J*4JN'l:{=#N# C=wɿC=}u|R@Ŋs(ġ&=ees܇JIΖ-[Bߜ 7ot)˜lٲ9u,{ukʪP.(Vs\Yɿ򋾶zm-_ܡ,!؜sA8droቑWQ"M6m+駟~L m,m;/{]"nH~=zCY#r>3ϟߡ S*EΡ8ÇP=p2Izkyfs: -eUt,\*j?_ŖX˗^zɡ*V)'eʝ19r6sQT6&x G9|p0Qpk,Z5j %JO/awIA9wY2d o6(1F&cVooW ~wߕsx7|#jҩS(_ɬk5kL㾆5pa{Gɭ[UH]Cixz'Z|?ġߋ'FX`kᮃ,~!ff,kCN K#GWS[= /Khhq5[(Ȝ9s)pef OӢTy+H%MT^ϓ_|8JW/l. DsT@@>=SH]e|M3=M o޼b7Lz <#؇絋&A`޼y NF0IA삹/@ԓQ( 2eKQFtL={dգZj9zNCw:.(sf͚z҆ yt00E| &paws?ye~{sٯm߷.|O^sK$@PD%~GP0<1,<\edfW~#xJ]>"Ɠ-J!n@ϠH @# VԩS;M|0yB:& GTa+|܍{x Lg`~_ &ʇU2P`KE}yS7&X}bkOY2~ssۉ(Ui0(FHCD;qImǝ҃"U` 9,U^y/{ \z]+%u@G @l#,g`YQT~: ?De7"p+`!L䮊q`_c ^a`J", c^)n VU'*Ap%er@  OXJL`x&Nh #8 7K3enbfhAҥKU{0q]X -eIDm/ຂ9`vy:#O]1Q}goqC~u6~so'ۉ{p; @y͘1 `Vc2o_7;\jb+|r=d~T [  pr+궣/x=I2bP^z)̀[{XVA群ͺH 0PbSXmPb  e0?<$&h,L삉%Q/X?IjX- #`Yc҃eU+E' g\3UTzd?O4Ik.!> Lݰ]W_J? V~_nCbu)8bEh 7˔6^1vb%,$_U{]S(h+;)FD@{mw 6u,?I}l] x`hV`I{ڡ=IvGi߱~"y2^=H HgyN9 DCx3ݴiS;d֟Xi #XL`"d0d~V먲R#~`j |@x؏&I L8^7s~e X\< Lt`s}`H:>i'CmF}%m)nZ2כ[Vj݊^yÌeH Vp&L!P\ K6Xԓ'x\v(O◢RLOK}‘" Sp!w 7 |:Xa%08IH /iW?szJ)S rr.~e_<<"`%.k8HHHHH"JHDqR ?HH ~)X:%%]tٳgsNs~iTT` E(ZYRIac(џ# Q, @@GѴiSTPkw mx4ts;"%l\qqqq|'&&Ʊ%pʫtǢ5knԩSf bK oWTV٭z[F qHMMu V> h{U`$@$@Coo&ۇUV|fggm;]FoӦMFk%)o7oc=w}"%Kݪ6l0 6@-j)jc~IH,kE(G}:t%KеkW4h۷dz> [l1+V0~ګ~ꫯcbŊh,_`+/s5_{G3g8S4!Ԋ@]ÆrL E~8q4oW^yN~DВyIߌr\wuػw)[:L@-y,h֮ZhaF'(eTT+@5P g]ٷmO>$>3wC s14cƌ3ϡ^[XFHH-mQvZe^}mN+0m4_K/6m//K駟6ҥKcO<3课 puv仆/i:m?uƌ?>#C˛:/zE  }ffyO\}ON8q:UrvӁ%0i-0$@$@F믿6=jHH %e9߭#(ݻwn~Oڰu[n3vsx[Uo9lE#kDG] dmTG@? @"`zde TWFM[QO \L:,vRu.k;,}gVeOv8~tXtF$¸$@$@O 5 'Oʳ6RJ u0X$LvY(B;ڟp鰸H85qIH vΉ.KXd]p 'k.8?% _ @'"G' zP]1:Xb'E*& H  |'{ܟ=){kU*#@u`F A֑"X]$G~$@$@l+V'cE+''WkȷGqduD0Bֶ0E$-RIЛHH.?Y8ZB|"*TFVQŋ?x1|,Zk'P~HKd"uP ); ћHHpy97o2ΜANR\.tUUAjٲj׮JL}Aֶ0E$YG-!$H B' (Tr/ggnXP2SZ])WWѣGdb:tv$`>X־R DhOIHHHHJ8 %$@$@$@$@$Ph$mE$@$@$@$@% ^X|    (H>6!HHHHH%m \!UZd$     OS!"P )D$@$@$@$@$P,p HP# A$@$@$@$@E 'HHHH B,  4@K    (h 5$@$@$@$@$P4)zb.IHHHHXR,B @ @h艹$    bAHP# A$@$@$@$@E 'HHHH B,  4@K    (h 5$@$@$@$@$P4)zb.IHHHHXR,B @ @h艹$    bAHP# A$@$@$@$@E 'HHHH B,  4@K    (h 5$@$@$@$@$P4)zb.IHHHHXR,B @ @h艹$    bAHP# A$@$@$@$@E 'HHHH B,  4@K    (h 5$@$@$@$@$P4)zb.IHHHHXR,B @ @h艹$    bAHP# A$@$@$@$@E 'HHHH B,  4@K    (h 5$@$@$@$@$P4)d.IHHHl矋^/wKBTTiOs Ca&4FyHHH .Çgg8uTq(RtҨZ*ZnlٲM g$tC$tI$@$@$@^ h4|6t4(ayRj z?6_2QhذJGus)`DB74@!ΰ$@$@$@$`Nڵcz&b|G@Gb SY   O2dilM{_"R{v+b1`h׬+H 64@ 7S#   dn㖞$99Tv:Ab!wP^;7Ln\ O0ix5 D1w& }zv*Tٳ(]: GAzÖn߲eY?1ν+j\2Je*ʶ˖ =d[~Ž4@lb0   (hѣ(#غmsuYJIIA2eʕ+#!!{ Z#q#¶1Bbbbp砻λ#$/g^nF7O뾮1H0HHH }ܚ[z#iF}jvRSS0>TZC U *^cGphR)=ygN<ծ]rʀr EY{; @'vg3Gظi=nZj!OQhW^yx\\~_A ߹sCY&F3g8[3f̐ݞdtׯwNMÒ;b̘1{_/(`N?֭_|'Sn  'N@˩}׼hݺMƍ?Vg_ HuEE|YaV`FHhQHHHH oYGj|l>1~:k-i5kWaXz9Ԑ Ο?w}K5 |/ݻO8=sl;#M:L񊏏GRRu1>Xt?قLV[#ԫ-x >PtSBǷ2kaN8{F`2F/?8ߏ{kiӦo^z%(7xß'nݺOyg5j0a,_}[X>̫eŒ #qۭ}4>LJ?V:>16hG=ƍ`sLGb4yذC Ej3ƄkÇGnG,]ګ˄1zhWݻgϞ^RJ=Fu1h][vnc64#%džxk WqH2E)s1r(}kXիW#<5t4թ /୷B^̨U3k|dذa۝!RV-)Smsz $HHHHAoҤvqv;^yx3Ьisӏ2_~aKq-[uj}/,߸q#m]si;ۺui֫WOqwԩSpKƸ{;r1V{Őh 2!7[ Vȍ75])6{%KAth+B% iݪ^oş8q":%Kir:ڥFu'Gn Tz_n#^(L Gmh݀5B*PGzMcFMb}X_ct6v|c4ng|E iGh֬ ΛK5,*}`РA<2u&vaցh,Z>MY:vZ1zp:X֊n7yv uӲד)O:RVmlZ [Zzxʖ+ Sلݾc;Fb g+2TfVc'UV0O~/̋];Zyie[Rq'$@$@$@$Y:&E+W]zB 8|YOpQTĐ\o#;u9F9?7| 99f/[etFNu]*=OƔ)@V5kǏZf͚ׯ"_:󟧡[ѷЅZ1XݴljJ\W_ޔldY?s;tU'ƨBo/ c𵌚\RaF͚5Xbȷ2Q͑wg[ϒ *Uw}qtXjU0믥9@ a)+^}u6F> //_OJzint:4IΚ5 G}5= N7rg1g9e#v'ec·q12Q |itzPիWcqWc8:Y'>"˧o=I?*c ь۷(L4Ʉo~+i\Ghv.Nbu:[ K;ǪU>},"?aDGW76#\Ɖs *ꫯn+1Fq,dɯ_=U̟?^, 2eџ%w{Ǐ)ZO㪫Ɛ!CpAgy5ULN8pߒh͇?_~uݷecd\%|U1Bի̈dX,-|]?裲@Y1gmo#W^5KNNo- {]3sK25쮥at Dd3MLݳ ZJ_6NV֬n|eȇg<.iz D5'Qf ;EB[zv^iV~6:QゑiG^a  ݸk=!+ƇN;t[ 뚏%M/4@t3   0$dNݩ:+dn7w5ܹkǏA!n,.6l\/k]+k8+ӍnԑkU{x$   H0m\#vMpAмq3lMi j]Y v`a[jUG LX-5m7l[b Ƶ5[$t!>udh Dl)u[X;wN>DNٝLc6::l[N>r[iS|¹W7Vڮ:jѢёAY܏4@yHHH"G@D0P#C\$%ޏn,>ԑE"H`F A$@$@$@!B2H^ P7^M  4:lYDɑ.49"Ec+ HHHH6YWB#._^qG݄ X&ד&%z% @8d*-P4X^3[kd ۲7nªLM'7\Xgd   (tQx΅l|ۇ3g̖ų/N*#H-[0:TJnC OM$@$@$@> ȷ;t p@ivU\YjfݡnBnhΞ1IHHHH$=A$@$@$@$@$@% rHHHH. =S&    GHS9 L$@$@$@$@ Ǟ) @#@ĩ&    GcϔIHHHHRT #@g$@$@$@$@$P)q*gIHHHHr3e    (qʼ%,0 !P?$TIHHHHJN*igyIHHHH2(sf$@$@$@$P{:tGũSPzuԩS 6DڵmgП+]4ׯÇŋhӦ :w|}2&O7ϟ?r~׸lE~q- [Ξ=J*dG@/ &ǶmLc[n5r$;v7C1ӻW/cxw^oͽ3{1|;v,l)))xWn3?= IDAT{S#e˖Q4 :ʠ89'm,$@$@$@> _|vE*UU5Q 7"&&& 9BN-=(˅ \}2΄NJ+зo_ԪUF, kXt)Ν;gO c-k1:֬]O?V".m5>y䑠QՃS4iv_ yv^,{{t$h;,\nGh24`εXwj1l_&:Ub1s2Rުo?T~#XfgJ⶞Tw@rw(G%F.߆ɉ3q42fbe3a٨{ @ 3b}Js疍]NFQ ]*{jV*wvzoK ?B#AБܹO? K'/Ð{o@E7[ov unDen5~z$M&`MX/ o5etqUU *j4-+K#mK IKfnœ':1`;Zn NOn- W/,lGvRkLZ~W"{ ט\/êmG\|`Eמ$.aA s뽳;׫^뒏xeUZVG1?vLa5Wwzwƅ.2l sjNG>x#[hzN5\Yf뮻g8q 硺j^S>,#D_t:YaPo}sEcsMH8UOS`Ɵ6mhg3ƇǡĿKfdh]~2܋Խ?ru`:#9"!1og^^L8oIs\gؘ4CmT+/2 d>持;rq`K5mN *[.bkĢVMM&@ܫ0?rvb=`$UֽeIB`kD! \'י6b-r;zǁ0~rlY>#7@^#e7jqg(U理l"j= S/)>j)Xm'Lq05e!v{o<)2Ljea˼}ڔHbκVHqt "kAժUMV~l#=X h; e#QpԑFfm%e^#FB٨l:qvσue-SI$2W<|Y|! LzcђdL=qc0w ' #b^̩ E$RKƗEr23}7i킉IͰXy\'xvJh> }?iU}Ad<̟o#e`/P_F3Oh;F,1? M[F>)u,9|dď}R:I;+M{_KIY5KzRI_F;6aN,%$C$):cO՗W"ou܉oBzˋbn`\zZjHIZZWbUR2R~j1<=mփ<{&e=gGVwQuGV";Ew[Dž,Oa* CD߃eoz6$d_zT1G8:Zj2FKQթ }7&? ݊7[FEn|[%R2۹g5a-zVCP?rw6A?Ka0uTs9]ʊ( kdEue|FFdQ?  羌+}]cFZ||vڅuĘs-~ \o"o:-1.ޑ66̬ 3Yvm2{5MƭmHdʀ4ny ]榘/LPzv]HA-4R JH\gB6㽩f:U:Q&o;l's&,?@Kj!EZ4Gf>iCfNF62Ҳ+~7_ Es٦iG\fܱQ̘0v~g+]v.Ϳptm L<&FCvxlPGY8&/ ] Ԯ V^]9㟜7݁]D427rjDVC\vyC91>b: rהnJ//<.EזuѴ <(r#yr<ʔAޒc 8tg9u$iSY/274lUCˮ hK>u[goR܆v/TXI" 367 X~׮ چAXKVu2Bʰu}$uy7i+o{ |C,SWL tD6V'K#5bz6.k254!?ӤFwSrVեwKPU)u%9_l%e])rnua.~QGs܅{1WVY:MFA^ge\G^ޟ['U5L$'EՐ j}5~Y#yrpt &ʈ8Ȗ`9|]šfd\M1--y8Cs7BVZr='i=wm\!?ѩQuӻn:btL׉t (ª!dSnt,x sd,0x錒w8oWuLg)Woƽ(uQ/Ұwf_,]{b$Ȉ!)conic>I:s淤~3egM.;}Ϟj_T^_.WdcӦM^si +z_5\(N\Dڨ+/ӎڵkmlPij^s5Z_vsi[~7V^}UcڑG: H2(.͛^q(Rۨ\bES_CKoLJ~hމEߩ$QKDV.}eg!)v*6}>5p@֑=F Q@ɖ $z_#0s}{_aX;Es30u ܛRHX^n$3u]gdB`#:^ k֘Wq  $XJ'3*mxȨnƇtz5iUNґ kשq7bKiښ.0Qk:װVk%5:P6N9kڴّL?JBRQxcٞ:?nUFeJ# dodoLԑ}$_fv~Ht h@~bq쓩=]L4g1ӯ4T,y}@ |R'b2UJv{4SoDXi{Wa"i._11pd3!5= 9d]T&m#ظq/ҳcТU6mk@9l $գeSF;52+wޖ lk2+6*'d}NeO,:TH ۤyHMDVډyf2)#1ɹ_\C̐2 ;oY?#/ŢS.5ݔH^I÷=޲'8f=y?CYۡ gte&cUr9z8xzob<)ӝ|9G}~?6Γb|l9+pGPƇ{ܮ|9ƭ.9zQ,tysEs)lL G6zg*ϵ_ثt]Zj|( I^![ TxNy ׅ+Za_},_/#mxNDiCN?ՍS?m[yϸr\P#g:L |x;0֟.^znm-:1VFcs;.)Ca<M/G5i?:]rG!Q.aw,?W&#YM k[7)ӵGo0Gs?2 3Й0q8F0᫴{KgfaΝp╆.]J˥Vi"Et_'0c;n]cf^qh򨱴l`3MƏ*A֑:\H, 4V#ڐd8O<0܉C,^霋Y2m4w R0gʛev kY̯r%JI>d&'&`xK UP7H÷^[b˳8 NP]/t*GS?u$U#cby O"u'ǝu/,_%rދ)7ʑ/_3+CGQzL$7K\ xZ͹o==?1~XiՏC|R<l}u&zJD>L}չK#gS&/OBS$~W. Ye>MFd=ynWwzj**ϮZG?g*];Kǽ@'D+;ܤOgYʠz<@uUty4N1{Ei:kW`u]6mۢrʗ|;YVpdZӖ,YqԵ3ֺƭ&D fK[u+Ӣ~'LD޽zaK/{7oƼyCԷS[kB|/[F%OGB9;ƇSyɗ˗޽? QvU~ ^gɒ%6t(ʖ-߹_ג 5Pْ4hbuOȮyF>t$HÔaB'0dB)oeDd(c}J̑яL]"&@8,,d)Mi^_rL=s/ed9 '2tF.Gz\^`?֥-9e1N5I#:44U+oʔ>|-=>:iU=W9~/YkⲐvٲ |tUz0˥ՋR(9l*eSnQ21=~u]+ɛ<e9vק< suI?ٹ﬜|b?AgY,pl+CCwZ~Qci};"quN ^Ft]v#r2]ǹJϵl;aiv*%afo{Ÿ_g+=kَ+' zm{ӯQ( R"X=j~IDAT2N7P})t̨̓tKo:}׸z;p1>n!le]H\4Z,FE@*U4 HЏqa +c#*Zvv@Nvpzϡ]D]7jvmJ:⛋z!1Ѕ?{u6`rW0[/C$oz|dH>:Y\?Q. & :d0 w{`B{bln2ѥ}ը^]:=m}/`K﮽G JK{y'NtUW[vszj2NL<6O>OS?l ůƍ5zn굧k6l )4Hd<   Cu3_(#"*S}.C8X g^t5i)X(0e /:ƮlT{suU,R\~N~sJjO"Ã{LkI6 ^֌kyL@?̚tq`K֜t:ٚe'o@8.ԵC_'26TwƇ^i%  (\Z~:go.?dzK'i :PZP,KSejwzSU46;.[d#?0jHflxz=RHrHHHHpC""PJH̷|gžƇ52O HHHHH ?_ixOIENDB`pacemaker-master/doc/Clusters_from_Scratch/en-US/images/f-13.6-partition-custom.png000066400000000000000000004626671217637305600304340ustar00rootroot00000000000000PNG  IHDR i1 iCCPICC ProfilexXgPMX`w9%眓sFrPQHV""HT  |﫺nW3==sByOtt8n{o& |~hw^ydOEƲ~ѱ`ƣagƃ8<}89Dc K}`(!`{6F:""j_1? =}|~QH\tO߇[DxliH?YiEyXڮc!ngX -Ͱ0{L _|l?v;4 ~8a4 *zX[>AD2AT4K= QLY@* 6!B$ qB($)Bd YA; AP<eAPTBU&tAF  /B !PG#,N/D"FD!{aK,b D$R)TG"m{Xd2YC!Y2 P2(-凊Ae*PMsjMBКhs:A/o/tO ÆǨa0PL*8sӋyǬaXNVk`˱wcX:vGq&Ha\)׃-6xQ&OƟ7Ot&L'hLBO"|'BD =1xXFB$1P$ <N2422L0|'Hb$=^IR3>iHee4ggڵڳ:::tfuu}tt ][ԗտ@ aa(hĘbl\a=HkcNlΫZGC 96['?Q|~iqN((;s2)S5ȂB¦"rQJiy?J *=C8f̪\|"eA*ܪjg>ruimGX]i=>~a \/l7F6694=hVknni9Պhop%K]m2m._W|}u嵾E۫nPou@]]nZqKVmەwX!dMݻ|/|n_<0o?ڃ4n>R9:X'*Ontw,+!vw'VNn` )Ei2%R3\e r%sZv_PXDy M -J*.i3l~5!7";b:cbntG |ǧU=> %Ň ?|"8my9 Wү&hMONθ72 7Kbb>Y&~Ҽ v|8ٲm? r qtEQ ht3F3݇N $hf-2*JZ{ZktJtO08aX`tƸʤٴŲf5gpӠ+uWپYo!o BVPdpUpF8-5XTGb,ρD$䒔}ά<ܙ5rSű/8~ĭN-"aP+v( ->S]v^HD\5~vtx.nnm^jt Uk%ڥnvwv޴v!NaOݾ{=Pwx3P8xihc ƺ}:kfZqm썹y ߖt?nYs j7u~15g@ ! (MQxF!QZ ]!b0o.8g#Db!y"S(6sY|bCyOMaN%3_BrUr+s? EO%)#T+l$ +*#L,^]-")E%!#$J@J'?pTLAiTX]_uAM=^CCQsUk|O]'=i}Aa1;63SsVyk\ulmv+o`\RZV^G~oyр `carVtvL]쭸 'RRoO?w0Pdfa,l#9zG5)K?!~RJ~]Q%JY)gЪʯ^VΥ>yz#oKܗn\A^uvxÿAͬ=^˾'=&?5;O}b9k1 @)\py S%Cv$xL@ _+@dC"HGd9r%:E3mq4bNK8<.ׇ kD^b.q!ɘ(XDecS˔`"5%;k2`gfoPtĕMny B5BZBEEzD}b-4@k('% d؛˦ʽTpVdVQ*TvRTyڢ1٢BS{BL]OoI1ɢٸ )E_6,vŎ.ܮnWNYhY◈O_YXH5ud{l@ː h!鎬AQD}4탾g{1Wx.[TBaEc`#n13v1i2Y0ّ% `вp(BC,D\P|V*+V򐔀Ԁt 9[rEK*e_ߪj!ښ̚Z={JuTuzmG Md9LP&V̿XYnYclm-<]nθ#JxX{yU{1 ಐa#Q)+qf ]IeLiYF?Wc'NvΟN*VwUU:\Xl( lbb׶k;:oR=ۓK7|?G O`610B« 7w?M;^޻ht/.+W}qwۺІݯg7_f#퓡eD\I@C9w0ژ{XK. Wt KǘdLb 7SҨ, p'^psvp>s7/[QBHWX]DETYLI\f(-)!&(ɑU+ijkQOD ^ÏT S_\V'Q6vfnNG\\Ϲ;1}n?o_0|ʫ'1E F)D7݈7Mx䑼(;$ٝe=v5bœO. <<Quxt-|E#wSmPk%Ͷ+.WG\va\?7x>(2T4xd l3/S_|4mlJmZt2+Ec ŧKe>}TlՕV_'=ڏkkQks?>\W]`Hݠ2wMͩ-խ[sǶ'ߵ\n\~.ͺz8ـJo?fRvQnbޥ|^ pHYs   IDATx ]E7~^$} .j@YqQgdt ~.ç7:fe#NTdW!J}#$;Nz_wgUVֽV{KJEO-JCb92@F #d2p PCCkѣ-aqZ\booGFF #d2@F #`"MMMF \ӓd2@F #dNt`B=^WڱcDzcl+#dtzC~aܹs@F #NnjQ<Cɖ-[z 3fq'&Lf Z>lJ ԩSog',Tjg??3WBps5׸$8ns#X8+Vwܡ1;we˖i4 8(6N9zSN4A]sͻKmr@4eojl@gzF #8XfuQ:o"1^criɘ1czL8`N-#df4 UnyGuӧ,,` l޼YgE8#QF h6WZ3˴iM&&NP;P{7oQh?>N Yem%?@fd2~%TDt5LRgΜ%K4x&K r"-ݻdIO(Gk)GVmIrɅ=ɩ@F #q2*pXzɇ} mmmK{[[[f`MD v-6k,wwɓ'RY@69pڴi*(X"P_'N}ڥ f,ˮ _$'MѣFi(?*+3utʶe,7Hh:G9Ms @awɽrm3JƎjv鐻?% VrY5TTJR)ʜɗ.?A9b{X9@F #__}ɶm䤓N>2W91_/pVK|9q?.z!g@֯_r(< bƋ u @aڵ:hMV:}xV[U&-IlnذA&MyOΚNcR@gzF #x* оG߾K.~2_=(w]Z&Oh1d f 1t+k&{.>Yb/w 6Lof+_FYc[:d2#ooڴI9]}s9`vB"7:,t2φ;!Apv,z1`trRSɖ mr`aϞ='}G|0 L!Ciyd'vHS+ҷn%].MuhƗa VJOp쾅?V;;;;q s%2{hu(CF # 3\m4g#w✭}h}t4M5$5BC#(,,_K|W>bB'n*~zCtF #x!+[lo5r؂cg6,:gP2@F``+^^;R>mMگ=l*vwIK/0ej,.|kYߐQSQ^}Ld2aG&[Q$pcol q s>Pν;=; ]&z6sPCY fsر*J > CTd2O1\s2ͣqoډ:4e筇uxk › !Mϯa֣l2Lȗ)Ie5,9µ\Cީgu`w s6|i,6 `} Kkǁ߃s:#<hK?UZ͕'0+Lֵѱq";wI 2א2^zL>d6#w,1sCF #`i.g ,M.c˖-jXӳggyq~,.㢟\۶~Vd2 *G~Vu }xm:m`>ޞCF #<p7 5uu77yɝq㵅2]-b^]3-#pd_3 j)g2@F`pj& u<~tsd2@F #?C.JMF3Tbszd~F #d2@F #04?1~d2@F #d2{kKY0#d2@F # @d2@F #d<>,@F #d2@F`%XGN/s_O7A}QYlcc6fʉ'7|f3Ø{.,3d2@F``}Fߜ M~{$7ϭu_HwF̊p;&.@v@~<Ox`+ghpg@F #3kNo{ vM>Z{{ U}3&)=utTCPF)um-֛.7X~`rʛ0a?OAF{κ1 "vz'>$T%n\rv<#md2@F #C7m^,ԑ֎2wޡҍA_; C ]|BƍEy(9y\`A]K[w=g'h0O4 rg{E֮*K=o#_ ɩG>t'M$۶o7?Rm>@+-W]т@ &Ph>XwuE/_G{08| ORK(CF #d2OOM nҷGF6 IiEy)ЉKeH{{qqc\ =,{( :8Rʵrh=LI=Ҙ^Zm/s0JL0/X@^L1"֜%"8MZe9٧@F #dt<**hXx46i_LӁ(Œm,*J*y7k ;x>2x:˦n[>w6ˣҕ}#W^K:\@ 37v84aG4R)@6xٍi{?.(-O mGtc.%y_m۷U8Ƹč1% ͕ KF #d2&ɮsiIz: oE`:D?3!}wI9ga2a℺ z^n[ eV-{ڔ}I,8U>ݟ4c6waaǍ].ir-[ BFРw0Na`|B|=#lO^+޼0w6r$ވ6g.-֌O4Yxt!qgG`$2O<9uϦo9ӵ2@F #x#˼/ )A뵇bک9iVKJGG'_uDxn ;e⎮<yIX%}h9jWwkh_|}"fQ*2sJY>f 6`WN;oxp?Laʨ߲}|up"ߋn4-A֑obcg9% ,&My6ɆeQ{ڤytz&ڷ^z'Ikى;vi8pG0)g@71R+>cz,Ȭ\ [._L02뮓 /p9ĝ;ȎZ96wG͗-1QZ5#BGdҷ˶ PeG)Hb2\Zř%Ė-[bɁ[N1">G+{d2p#U0a߉g?*xIڥҗ#M3\āH#^NGkc[g~8i3]].͓6af@qȰ˰ET[ ۮR+h#rXڮq@\pn@|bxWeg86^QnRY+=rͿN&b)ViixO5CGOl/3φ6>c֟3 cz27!<RR笛d2XRž(L6aT閦N @U)>^+olZ~BޏN#Xo?1e04'RF6;;˫jXOBnLQБ#g?Xy~.b#buCi^ocҴ oTL`ҊNuc#.<< :){ bj~V|?;D<8 9s㉂XXB )eZl CZ@F #<G {"@hi fG;WyQ译U:r+~\#[^Xr6oޕ掝?bҔC ?8t[k~ъri)Ϗub;pq 7ȫ_;OoX|FǤo)/ XbM;p`&6@D0"˻K_^pT%2a1apcmm|6I1AVie۰x"`'@ڕrd2ģ·Ai@TLWp#vLO@ y>|q]oⴑ"?OyCǒ|C=6twd -\8Tc(ti6Gb`|~ks8H%ArԑRei(fz)k0,2m+əCo"ݸ/}PlF t4$ q4 s`@挈'ΞCF #d2O?Ы >}O$Zwߪc?˯x1ʱ);'+4Wȧ,vwZSd庲LY ^Evu4AWϟ7·!7=$wf@Xaf?n<ģ# s \x025 c<82k,Y%WzH&<2ai!jG|#uWEuqPq34Xvc>%WB_^àЧPnR]%~$$IN#s8Hx^G'6fϔUJkf@pYv<;ct_z9|VIƀ{;\LEN?`% ;-QôUz0Y;p3l}skեX|(z @ IDAT o,}l#=X4Z0C"yQ y}Bl绻9`ˮynu~]d2@F``|ޱeĻH5 ]  }=X-DWO?eY,waL>+o>d6}(߻Me0:z(^j~eʔ)qըQ'@o(@{"=4Ap޼y#Vi ҙg)~g;8S͙"fy{dTa:J'=FWCukN+4:2{lޔ:~$E:uB#OPv8{©.x&@o6[SN9E^vYsоwF2|  )/:L?6|;Хl3gΌ3 Hp39Yc Q^(Nb{2BwO~l8kcn1=b'z姏ڍhx#2ȐnlܸQ;|qcQ9{lC17xכN4u07e@&N?t}0oZPukʾY4Xhd%yiJ`im۶I #ѣF7qՍ;B5?GY.}Ny:/Ǐu쮻իW\gjI5CfζnwRlYpst?k#|*b_9)Mi(t?x9d3@F #g ؇Ӷ\Ě鬒 0v8RrY L{w.4צwɫ}j&N/qsC9@,_8lGa!khm#&ϒygǻ6}@կ"> fLG ē/@F #d2Crc3r~Ǚͦ:U'ry axƬD9bǎrm ݱ#jLr@F #d) \gF #d2@F # d2@F #<اwlq}>Nr.zi-Z4(wl7sYĺ _;./$au@F #dF'V/^Y>Y>@_ }&C/Xbg@:ˢo|Unh8= tˮF[{˿,KT|T3˾ϑ6"W~Q>s?7M˒Eߒ#·>kDH>B'ʕo@?{ݷ˷:EՉC?d2@F #Gw|ŗAfc]rnC_{?|SɅ f`k| {\_D>rzo%VV(4N{Juf Wr6}w@{nɎj ws&ܵ[ayxgi-oM,]no\ʨ2^%dmhzz>_$_ޱZ~t\?"ӛ%mҰ61_E_mê 9/+|y:R?5|Ku7dϗ[e~L}T}[N:_oA۲oIYXZ;I_gsY'#d2MRiǰA ߳*xh`W} M͏_- >as or\rD|>4⭨=9\9MićDk[|\nVI/|t ]MZ/VڰI6n);mQxիHEX5lLco.\( ^m"ޢ嚯}ևIETم߼U"_|,v+H: *_چ/4OfOWz\|]-ҋtgw'?{rL6#bY;fv& wrX*x{UC Yq;^ujum[,w ]]n-\=Yb ߓ_(6\͆5vh[Xmo_~ ؋>a{]"[*m2} z/Qtr4~_4ɕrїʽ(_q./wʯb.ȴˍ -_ɻƻkK+7#>፺$n!#d2"yoBfVƞ^Y?kX(X.[xMg% <*Sik/R FV^P.0`藢$Xoh>]{O/R30޵L|B_x7oByۍW_(_6p?ptnsT4S_.goIo+HQ.|_6ݲ :i\sgP~qa9/>%G_TdoXt՗=R~xϺB!].-?xHϝ.}\/kPPu/X `}Ee鯓*/k~ FrTv|{E2__.6[+oWO7ROȢW42]*5C.O]Wˆ.\n%_B:xo|r$o~(?Qk=+cղiw*r+CC_3N{\!|Hߑ_x.y⾟/V#}軮S5 eK̎w/gߖ6]/]ܵn,(_tMWM7|U8 HOe\[ϟ(szW9x*˔fz_ܾRzˆ%.z7AZ9Y^(ʍ(wR6-ȿ[m)5&̙l|^9%'HKni>W='dy_ͿOJǎخZx^!s2X#Q/[1(7j9zܳ;r5&]H^4J*fb4Na~n;+ɱhwL{~-O}.JsքgT޾j4=-{'Y+ln|qHKSWmzϮ["$-ʥ?\"(|N<#c"=V&rwEƎ$'y2 a}K VE.[/r*t99SһYx_uT#O?GA(!9ߍmHAVgm@F #CQ]eʱϓ"ٴ˟W=}sj}կc0xc7lw%u9Klkm7zDF7B@Z uس+/{w?xpxf@^t+׼]-9'Js9D cڀC]>ipe ÉL c,dF^pdenu~3@F #x gu5eb>QZ+vY`dF;MfZ"nѯ[mAk&yݛ&=д(M~ԁ =ɷN/7M!qn>]Ί;;kEy׼},2؀*s/Fk{Bn?ʍA;o]=پK:{qy9~yd#^c +e"Tm7ʄg?x:Шl wwGQS&ȑg$+&cϔӦɘfo C%>g̔_!0d%@).н{k>_yC!X-G\~;}E/У9(zdCdڴ)СBtܾ]ϘDK37Q*ji~k&' (=J: seV4omYLwȭA.y䎕2sh)7)k?2r<1MtpLX(0[K?2x{uI}&Yf\+q q7-v~܁d2@FIB=ʕj=dѻk J.h}pr8$zKe٫'7&}=;HpF,IxptU>dRLnG,]xNynZkiX9sE\$ʽ.joN;NN:9qRi=V_urqv t0 70vZ$_n=,#2K./_g*'Oŀ@o2#7}N>-@o[LRab \ڰj[A7bxgk&uzW˳g4Pr!e2r? )zvє,`k~@$F9cE rͽsO;_ |K_YLNdǿ$ג3v|:Z?^۾S*2f(bO<}عxbO ʥ7 ;ƌ+z|Da[__un=Oz|KSYvlw_cAuȣ-x^}ʨxoj@S#ٻس-^i8Q1r߃ɘQ2$}ha;cǷHniĒ7ŧ|DxN`^14˨^{3WƷT䡫Z^o\FC+ 2@bnR@F #(MmcdLCt`IBJK~^ꮴx:wD_j_KDj}Wx|E3|n >],i= 7-{Џ>Mҕ68=xtR޳mC۱@dVtrGg&EoۍnlѾkl6 =;a!-[x]MXsd@$-uz |"E'M v͌ZzِŃ@0·RNFniMܸn'|b<m} x}ڽM%Iw}~C:"T_L%`Zlv)/FŪ6AH |#O!*$dd.d%4T缴Z)k̒,b*^-b#\/†*YcQ)P+|XPhᨃ)@idex"|W-ITBu&/kT,!|n[~DQ*Kʫk>AikMh,ƅԆo^|\(Cb|UHXAW3XCL]>0:.A5ne 2?Z@UH X5Dz슊u ?0Ynjc$:f+K}%ߖxM|oy$QΏ4*h7fkB@?PA!S c w&IwAx7CEM(D\8Gyix/R8)Pu Ffa(TǠ(q&YYNw6Zl@^Y;"͊RITiǒ:B:ndV1uT2Q?1hqSƌ" 'zޖI6wlU|*ڱm)Q(Z4m4~Z3 8ިbfF5T o_f[Q ]jT+Lx$%ZM B?aF#biڠ< IWQ]嬘s3A.3&dŤث#Hu{:羃Hܝ SU& ZYKUIz,bA< Kƭ]F! H7m9l=$xW~EYP܎hZ8~ЋkT$WpI*jtoQ?r A4b֭UkKrum t٘O@$_NJt dK!Qe@FUDQ~Ruu У7hTilK! <:YLPH02Jٔ4SdDbV"ZT6mDD]!+JF̘,IG6m6Y)Hi{%Ap2(4R+@]"i`[i>" DU;T]|u.-O"2SuB=NBʹC%9vG3@KiνI^QGA*JpA؅&t/mwdžJ݄ 3N:eaK'y z TiC6hL h<˹^2JWE&Bm$zz%LBG)siYI:3z xJQb,7q]!C Z\~UCCg@ȏ]EPѢLSz.Pm_7ٙ jN7j)r]ANY]Y\>mQX)GT :!R5FgY73)D5IbY!qD1UQm3,qU2HM!JB t>MH\:5 Z 6J2)Z54s&<&zl&x `ƃ]9aPa5A6gTEj~+.QRJSY3tyR!MMD UX`;֪I6ft -gm%,rj.$3S:Ɠt0x olPZ/K'P"(B:%U#ÙVKRU@"H|fJ.!$aA.7M\aϜR@!:^?1rgfd.#0y-rC3҃L^+ P[ 5T!`64Ta $b]?fbQr0t5"_LYk(e)BVh$ ڜ6tds/\1M*im1&=r̾k-ҺS4 9OYehA8!E$jBRAu} v&TO7Q?v)vnHMg܏ =_)tYu't;{t*i0* }K<StNM>D[S6i ["Mr)j"ŏ8Kڋ2Ev"b'HV1uG P29ľUWh"IPe>u6Y i'<G*_Lَu^2{<Ӷ+C*Ѹ".u?>Sҭ7sUT{2 s 'kZˢ %9PP%PFhmk9=6=֍IūNLMOLW ZF)D"fH0Fʥ ni>a$H0[M3H0]'SdmP{̳ܸy`e>FT2E̤QHL/*c"ëS7=QN1;uTD9"@ipY}nj; hv1Rs)Ɣë4T6+sT$g)#0L۩$v4L;Jiw>whQEnT fA&zE2-SZ!EueU \g`yZ@2oWb3 6B$mDnNˏ;Dw2BkcBbVQaL (f T=+Uu"f#LJT, 3;&E:"QG+1\LPyup 6'VFPjRb̈́MCY*Դ,5]%`Cs9("5MuhG;Gw(׀zs th4isDp濄65<2 }Êʁb ,VVn6P0׎T1!*m>l7Z2+MrS7p~h4hՃymcEMYmHbE0fPOIm2Q4`ЙTc ?jɲ͞<Kr}*Q̫BP+qgq/_1ۡvHJ1mltt :R( r9خ !J ҧNIP,$Mt}'x8uFT@!c'P- 2S5惛f!TdYi!L\tӌJeص@.}}/T&%A11C&Zb< J僘E`$2..P n<-NnT! LՉ YۚRQ^ZtIHΠzE DŽSڪ|%)f Q-&+tʫs 1pL V{(j lXrfAFrJd,h !0+y*YMS OUޡ|6]iD/SyGRTc.:BJǔaZ1SLX!C^mHi_s%3YI$zB$]U7j/t]RB=ِK \y;gOw -pvJjQ^d&BAႈc-_OC;Tt,왕͝)UUHBW :1t504 /҂BCBwaDqU |'&0 VqzqI# [m5UM$4+زNd1 'аAIt@Aܵ<EmJv~E1/CʨrdyPʑb>h nȱDȘ $O)o "* ( "f.:q 81SI~F9Sui竬T"O!^0 Kh6^!kۇ%!W,`݃D؝vzNjUU:3c<ֽZƋbi Ro~]QkHs@/Jw(_j߂=tr&9 ߯45ψ_) ` yD '@A-A=} pTcJ' ABg@ۗ [ =hN\'@\9Bt&S(Ҫ2$ P #u:*m[XaԎ!8nL&\c` (fCp5f&!v`, tX֜6gU?vQ). t@U|ǫ*}h=ƱL Xp6Yy.f=~?Z0&%\ڳ#O U$S;^˫ x%$n29y,)m\\9I%o Ɉ]IOA[RR.mPiCDJIAPb~,=RۮF4RJgݥ d&$seSX =_$[̀VE P $Vq=V-PkSEJĉAa\7?P3񪂯g'r;tV * v+<X+Tyr7.g@K@rQtC%]Lc˘ ;A=% 3Ap^hœf˶VoyzC] 4S[<ۯwbf3L;_K¨u ';M& 3S"E(^Wz}Ge%'- IDAT+u6B #q\a-jhq4Hlr#{I~U"P0.y++`BC۵2lʥLcCxʮv|Kp=8&x.c@+<LF2~6JQ,IpUŠf{i>Qȭ :| Q,t5Ȩ?-TFrjBp#5y<]c)4ruq1$1c3c΃D<IOtA7?D:*&/p3fQˡY;lf t EiFn֘^ 2&j8uZ ES.7s) XR9&fDbV- \Q yT 6$EE?M9 = -#F]@`* sL;Rp0s'Q>CuPA 1#' vJV€w| ji&eY4C)E)Jw&bWMHlD! 'rVRBdzćX;S:f= ciݭr*#P`ݍ- 0fܘklW[i׋[޾i|cf3C":bbŶ1PVƤ"8IJTJ.*O0 ʒh6 :8KzW(lB̈́r!Ì`-EIBM&c>LbTp^S i~dPXR5w}M)lu<(6&jLj(lQKoLR0 m*Vs_o17|0UJJUbO 5#< FJŽ}f I XRDP{*iNl _NwqƵΧҾkܬƩ3\!Ҙ7uUPq:n9#dlXKI>H*SE^%>z2LG:6i:̘]m ⒡E%c͆X c) Q vMϺkwYk>:vi Hi#2B@wlh;$ `4@tM A)mSӯYfZ]8:?8y[6130ض\/ʮaI/ᒟq9xO"B>]q,dvG}t_s,URgܱ*dq9H)aG4~ZXtacm!' G!D断qOPvb~47>3bvCl6ң^Ğ/!8g=.գC<>KN~kvJӿsνvqX { ^f?T?po}Sp+zw*㮪 ɹdCJX^,ZkAUq%!ob3@Rͭt_|&QTH }e8vq\k N90&Пn L|AsIkI.nW4hΕ` Y38W3⮫P'k^MZrq54KӪylp| ]>ό+气r"NmIq)el@0`:u#Q\Hwq(s<&/;O_^P`D'3q&[ =uda T)"R<`Ƒ8v"$jVt ctp9MLTsaciLl4EHPCId|Պ*\b0Wlޕ™yj#.H=ޔC{KcWύVka+ÛĉpRs`0%~)p;up}b|{ ޴!8Ľԥ7bbC%Aڳ@S1Hj6Bl/ac [c[8 0W ˸hQv8 nPiP~(mY6'[Dz$6WLRL@%*+ꀱ eC#Y($' 4FMRCߝx!;k͆۾Ofj)zbu* (RYN/1 pu$;mÁ?r7pyegJqeI S>`Xm8:!^:~pMWu3b[`c*WĄʛg>5hD_\AX5Uw,%NKp\>0gL7~1>\0;uxR@ɺ趍@b: U#}kЏ^YǝC&/dr~^'K͎^wBWnL j؆J`"ZެG+B8ĕȶ] y(@q3M-56֝ @ɞl8ǽTS2&2s#^x]\T p}!ξ)X:191ӎqQq-D~7Zr&l4n U,l0 ?V{=I{ } цpI5 iZ|ű+~x8]KAQ%«s^\Qk'%g=Js tT;վ^Et>iG)@01DŽX+ڀy͇_͐sWYץυƋhCEޠ WE]xZV[]|E.^Oo 8̗Y垫e%Uן~M}O^|WtC'@4y,g=3D XسybԧzNTEF~%j^t ɋ(Xǹjb&d2CGgؼ{ݣ ʤEs;1#C6| 7KҩvxJ)A_ уαsqk[J&pԐl筽ga;DGՐ} vlh?옮Wv${up):gO*9:78d_V!r<=%HoY&PGkwGY1uBO{g8WcG\9*o̭hP۶qk+WÙw!]1&O3GBnL 29ƒɛ%7GVLZ"0u6*~4n%Ad hMu%d ށ'zn p{3Gd2{B{e0rsY|tHKJ-Ӏx,ewa!(h`^P(+{X ∕H,a9e3-\Ds-~v%sn 00x@-zmoJ\9=X5Soœ @Sl=&W7?$Waa8f9ӆQYm pET蜌G'rZc̸quI8~Y .40dsS8l0;,tڠg;³&B:汙x_3&&k $v);cp8cTl)TWA`CSɆE 8W`<}A/>&7|և Cl))hWKS{l v߸{T + `:і|nZ f^F٘jk\'FqΐhI#1mM '!Ǜ#=Oym―{ !Orqa Q^tv$1!F:;gdRei-.f9eI6! 3䕤e9%cVr[89;UښH }[}O9A"_HAɼ]`rrvWm6tA=O@EB-t1J sR|-uf%D.tµ[}60o IP0#swnT 55W5l!녈`ãW;[9P&zH.5;·KS/ĻMKs `Csj!JxYO]靚qć^dh@ dޢܓ׵dom+ςIXr1!#MlX ,3'L0dZ'=xYmN臇b |2 X9 wāio5:;sp%:cvo&q^dEj .Gs|j'9g{SLVy&~70>k$H>2 %m] :S]3_X d!cZ&o ޳WX _*'vgCwDoߖ\IݪQ𳆌1_zex~/@L8il|1jb<7^x(. dV9%&9h#xË0/Jc+Ћn3!8a *uRsm!B u#Q8obagSwW͚c^'cg[ydv:}|c馷l^嶽4GZ/ZtR>WD;"U|JgnAEep4ls5vJpS;ڙq2KXd $ZU@k{=HۤPso2!6C}(;΁wl Z$'ގۀ=FBA c[%Nם:°-LAX?2 jZG9ДY&$?ئ p>y%k].k' 5xq,% v|^_3y*Tpzd*ӋRј6yK?>?l6Iψ.G_'ml];'>Cuavn.odZ1{||v?wİͺ024ol Ne toFW^6bYBjPӏ5\Yڽ#c8k@۸`۬& qy%d x:T8NID< DfSCdcXat]Țs"lN sA1\W"vO\K_9570inFJaŋ=ռ>?P~5owNFe'"]Q+T%zmG`%!'\muڈ9x̴P݆_Lvu=d,n\vkve{~o.xJbvv9K1yaQ  Mq,Si'r=5q0|W7hkę!c_C9HSE7YL'TOA.Q8L#nt:ܡqq v>j t;u 2[’T(ޖs3m.K<{*R mS!!!4(9 hj[).73jǜ?Hʕ l·7O v hHOnCKc} vLۣ+ۚk1Fe/7մښ?sS/>:WI\b\+.I<)(څZ`o$& uYWd/W7w:]TKHAjaß$PiE b֧a)#a0eÙdd*8qW4J܄ߨy{[7L"ne 07e};ء/u Ix30COה(Yt°gr$1't<~@3!O+=S\[2fG]F9AfauP^0aKgɄ`<Lfĕ|'[C8ںyVŖ;5N&?ˇ&gck3hGVeπ0{ & X}7cc睅˾byb$ݸtbi->[>ŬwNTh+,3 _xQ+f"> Yu|12UN$u P"};mfэ|$/ %k:qnl`=ȐW_Qr$^4Y0I^w䟅.eTf,eؽGxђPt'QK͸eBe0W4\#ރ M;,` .^ Hv5&xf1cB" +FXJ cH1s_<' IDATK&QLWܼfn ME+tbI̩[v_=\V-]AGK [}F;}OqoD߃ rW\}gy#6N64*b޳:@Y3!nZńY!?1֘>yȊmhSJq^VXG8|#y .R17^_o~{{{?p{˚vadOzs2OyȁSZ 3gSؠw;;evg鉠 Xֻc.4Vs5Bny#z&?71y!#2h`rhxud^s x$ o^ָǓzkM bM<"H^ٿA:unh%;0P6$O !J(Y4oܲc5{?;v ߔ y~k'mActi^LڪǹKyTZ-CiC}faЉޱ/%ar5Sl bA>/J1V?nYgt,ݟZF E7|*,u>P{ 6ϣRC46QҚlTM%Ѿ2vNv ۟+6?aS֧Qܦ4|H;5-پZHs<}\t)zjŇ0c9ˢ}# J'Vpf3<6CrXsI carWTF ff#0r ҃ގ+.2,<ϰgх_ڵ$V5.ٷ ~3`FՑ[G stݲ58:Ρi7_pCrg71&.vP[\<6сqYrLh:KikWQy z;Koe L~#Ĩ1*4x<^wBuٳstUˆfj͵wWGYo5D昊nH3!"ˮ$HP'y6l,\* 5Xj.\[!:Q2UG\}gjɆs?5iί֕0 T8'1;#Ys*2~3+!XlU֚\vtx(òbP0Of` f4]IƩqjy9R:R:%^FF8hqS]|C:6XmnjHqv mJ@8l]ih,Gcߎ^BۤeȮ,e+z%=uShGqa?uL2uGY:g柉9T )隴ngѠ2LaQzk3ܩK?ܾ_ʛ|/ß|SC=coZP0>3O u:Jx*`Rvt 5i+z'cYFp}wh}8x֬0^lS9raKCu b KS{{9&h.@G; {5|f BTs{9{3Ek 1L'N>Z{[iض 00Gy )3| \"m~Cgk 0rB [Wo&Dyf-l$169V#!%{f "wFRy<%n|al&8? M|UPn(x3uFkz<(J8ɕsɦ~ ANo,rٽ1ڳk5O،pܒFAM5pxO{Kyd3ul:l3x:O{Jbo&g|+_o=u9g6EExuɗ{C6^t\`9w}>QsyѸ~G_^m+"Iy/? ^[`80{H|[!CI'ڐ_WuGW.t?nw~÷/~/﷿WW^9C$XkN`ș-%UuL;  %>֐Wц hy “t]:a On;LȣZƹQ[LJ,GtnW?5ūATna,)xHˉH KI/%.~eHZ[S6Ǻ '1bX aq'=^2,.!RI.Mf0!c8SE`vO2fG޾9/mIel|ȚS|JEϧa!Ͽ[!t^#zmfXFqc7tu?5\rLs+qȵ7}g:6S 㜼38IBS9dO!́JаN#.b346 ҟ :|E3^(a%C|΋k5Y5Q8o꓏S?۟C#?KWo}wdЁ)G5g؜O%rZ^bwteRa_FԘlw26W'~YGbLÐAk\Dk8(33,]`UgH Kkd8AO kB*7Ch6Hb ?`|p,&Uϯs@m7M*.O6S1y᫉f8O'یI_'vv7O>}~T4|L!fyeȧ,yYRP-7ssD9oH?cJ3 ފ}"t{+6-*>VPyR1R'WMF$N$gs/puQ^\o?hjm%xqYGmfJȬ {.8=/ `gT/pvD 59rs.8+݄(s>S|0k.gM{Qq+$cS);[/r<ꏭ n}^x+_{Mgpz~&=1tDK.|*b| 1Qp f!G\ :w3"edD.~RMҸƖwܸGWUFŲEAw44o^9aϐ\Z jl{ ++)Z)Xɞ}X%Ajܢ k'Jh>w濻g>{{o|o|_|ʷy?z{)ԡc˝#`ٕޤs[=.cvliљb(/@R@0};Iw,/4FO~A#UI $h.wGe3s5"}as”(' *:`c U=ӿhg+,M/u9Ƿ"fiv^"ʻ\6ਸ/CGeRU9ָV0T*, +uEIp`;bq=9Ń($t HLX%O7Bbʎ5 ,~I8<ְ'8R}׾tү|1e%8?s{Ӌ'^O'Ft^rRs1U *hTj,1LjO@pNp5)&biUr}e1u:J[lg,øpK:/+ r>4́^K:h=E6Y#1Gj(r L'IY9q5w_P&"ٳC3d­zEO"~zS*i\/F (Dž\!Zmak uX=1f;un_ s;Qg,d؋'pABaK/'6)g6xQhh^>'=O'5rxZƼMtZm.@6F/q,FFX!lMsDn',W^>(FPs˅,3sZRa<EF쫠N ~!c6$}Pg]U,jӛQkSf0=ڡ9ř@9.YOp 9Ԋ>̖y¹&m ag]U(|dIZfX91wa=-=|$Yu lWձeىy Bh!+rKQ&# OvZg&.wMN'屩ޕ"e4+3F-W X3 rr;cUK9nMNya?㬥Wn<*}_\g Sag>{?uf_K!}xkrժޫ?׸eryXC. 5]Ϟ▰e@֣]zspEXEzdrͫ-K~mfI:R΁$~bL/< m%NMe1RBIFH: k"E ۳z9ʃwLzN#C +z[ؑ'-a+yq[PXSAzRb G27ȐY=H8i[.. `tn#qo|y}iu`χsZ1ų;}APLơ;"#ʜEi( <<6Ӳ\>'dGl'Sڣld 1r:GHSՀO uLw 9+ƹ&Jŵ1ҷexݍL{<σ[Y͆f=4*0yA<[Kfr{z6,w{I>ww~o|ۺ^~k_n} KnT-s;'QdSOOmið=XY`ݎPQZOڪMoS0n[r60I]rh|lbSƖ(?!,8p1yVj|h CSck$nJ=1prЖUzrO%˘Х]%8_R8/1gp#&Cg٫+]'x67gy|tw67v:Lqhf22ZͮgQ|ZَFl4r&N;{u&F"3+ybbؤ) 9/=q&^gYLKҸ-Zd|OBtSaXz=dTPSYـѝ`G R\U~ˎG^El@lٕrPQ˃V v56)/,a30s ka·l25dMBTh\wXvn%# e O1WHT^:I6ӵD~—y ?6.$6og{o(%y/!3>b i-|#c]b>πl1upZ⺀ DZvԙ`63# @=qq,`΅u&J@A"Q#6؋ڦ;JģQ;n8oA]w]h2I`r657^%pgC"GE7NdλZI׸Z5c`ّTq刷B1uO߼{>p{W_~ C?[C?_ODzḱ-yt&gן2 4SKPg@#$ړ:AUB~Q1Ǚ R퇊nLQG@bG3w]%͋bClLlwNe PM' ΣǡX)kxc^^>PA[N){P7r2)'k\$ =mS!0?z@X^ji"ւ<+n%ͧ<3Byރ8-fW[2C_ZyNdU .\>LFB0YvÊ2CƁf`ԤbM/B fF@(D2>9Aϗ+y+|Bi SK<#c,x1O-3@O? >iVwgy#xד2$wʈxZ׬ =ĄA^IFT6sかΧn5;Lb\|b'Mc3gT ldd"F']؝ʻWOz 2{nxh1YN`yM\+<A6:_Rzn zQǘA`o?>^ޙI4soWh+,q${55SaVt&5?Yx Ε F Ȳ:Jw67J`/rv>/'w2GYK_~r{AK_}Cs3FRHV[eQ}/y(Ӳ+YΩ5- ty߻_}5_qʗr)})6cq{Pe7CƨabS[Ÿ虭9\IoMaK~^o}#;=2G䗼V?3~|{w@[OGThU]OHK|r\L %$L DEaYҶ 똢0 M‹䯄Lf<X3h\= c/BYgxӭv׉Y0ZVClkrܛV+hj2Źj;`؟SE ;v򤀅_Ʋ*vsTStѾ$SdĄ.nWfa@vfd(Kl{τ2'ѩ9!WG cY]t|KHƠ5/5 WEB(` ~EQ%sH͝@ a["l{g6*뎰:an6b{V_ɢ0A_c'bkZ֝-?_F?x1 +s 7Z/==H'۟c?tr? ?g% DN3&5rV/N\믯؃ط3ُP׃[zN[>`/|_?{Q;ͷnWbOSϐ|C}}ut+2CAe _/Jɼ~ V.@]7\a#'cBcC 1|D8hyBⲞd=ú>ژx7KeX&%( fg[Z3^DSLN8LUP52"9(ڈmmsW +\ 0X4.PYgi9D4biϞ Wn<~Wp<٤D{U^^|^埽Yޏ~^K$ʷɝ,=^s)% O@ϮXj%Ee* G${H͌\ ~DǞ* Z'+̄J-$rat K=Q(m`nGM'&,|z˥Xޡ%CYWgX&1K' 3iE:C;Ps4E<60]9 ދ2/Ob9p DOşn>RY  ={u|ӌ?ᑨ\} REzxva xA()yR9I]g yp3t k OP%+wsH1y|[: +jrNxjݪџ8ZX5!麯Ak)dC ?<-8cQ!?' bt[pq]P"> ݘHm{oX{qTi@0.?*߱Q{X5k/B>aon8*NBw3*U޸$= g1#P_! ԊߡRȍc_7,uIPMu̻uS<Ϯ8 k"'Ïn_mfxO>|bSyA L~ccFvzL9-aaRP2Fkq>sml5B[|A޾[('!z|2~#yQwJ9^$2Cࡲg&VN/k530㙤V' <}~ }2u7\#;_x /KWf&R˸6hz}qmPYߩ/Z1,S?VI)Yt;v{a ч<)iΏ&szƬꁽ; \aPDlz(18׺+EɅ Po$}{^]gX#ۙ,xXޔ+B^~_Wh92q}DDZYQpV~z&xa{|m_pgGӻQ8?jxh:l-}rԿe!z {ut49oK)Z>o{;$9WG5A -slNOk)ܯbw#/KZ Hu>y_}4v_0zV/|5-CR5I>H^{G&E>tIEn;cLwF"G\2xfp ` oHmW05_ss*wr0{7b 2, =`nr@q];"u3 1 ǃi;`}I^?]2&׳%lq?FL٨50J].ິ/ PgìZNkkqmv3yu%eԦ҃gbB}^X*}G8<[\㺱OȒk΅'"cc[-'PchDul=.\]e*LGlzp6p @;],[+~[ 9?Ӂ̈́O"mMJnryAޗkv4dLe#!}mOPk}tyƨ osAfDyIS|]?;?T>!_K/>ߧܪԐ7$U/g]򈪨?0mv\3+4Am8cԫDBCsk'zT*=73a\0B{M<|y>hc>0eX֤b ]<c$ D=dʳITg=#ɹ$ӄρ !LmP6dt %>QŸ&'m4o49R*bDj9r9`.R\L?PB&mpy=<䚸egG]@<ιu_.I|+́x*:V6$ M*H\uPK7QB>رYQ8xcSd1ScLeURf+ᨣ!1}zCV빲ӬdHmnY{:e"A)xhWapHS>~o'_;9T|A+~@M;<ٟ95FǦ0 cSf_#7$"f$]}Y. ]T^N?8j7@|#L681*A[ xkvWؓڲ RŴWƦT@Ƀ:Z`:+pω y~~I~勯?7~9ymPQqqb : -sBNc-}Lc˳f´a.6ģggX:^7SWbG])sbo~ޞ|~֕륗nMI?_7>#/D`}Sh|dݿ+Le־%< a=4pq-@ܖdc:}l_B@N-zf!2%#ުyh" Ǧw>y>R[搭'CRbܬ)=W=~<ޮ2gMc.n {nȣd:[^HP.'w}xɹrT^\;. SeN};2&obQ?ބ!Eی["e&znjܬp^UJXBLe6<ͅү}y=ڙd-sjJ&ie=%f&n=Gxr}ƴ4LxO},^$$}pLRifcc,CP ĸ[b&w+ׁ?,ly2BJ9nو1#㊳A027V"4dɅ-ӛj**Eh3{)lD#A)߮ln jmfѤfolYd~ބ=;h6wzCM'N}$] {.f] 6zr)8E`( ?Ծ9֜wb ҝ"9T[( r`r%XY\F7eYiGаvexR1a/ʷd=(jwʗktG揝=9 IDATx'FYiP̉%fv;A{7̒s#One$p !0uu9Ɂ@S ak;0j~nDB &ofI쵊Ksh\ؐc22K#獃`{N#V32?hGVs1|w'9~W^JР% %eƸ"]65cC!v3Au_;ѐ F#/t'aua%#@Ķ{Ju]93Znd']'O|{?GCu~(}[/س5] !g:YЙ0!a o)Ԍ3¨$g?`8%P'q|Gĕ~0 |y>n&Z*gRN=Ex2lͰp=gfu[51gDD:B:43KH 0l1P9ӤɎkbe0't3h8itpO~㛇?1nk*.!r;:QLN,"3߉%~c ʳ);!z̳kHPp>`ܖoO^xWoo۫ow_}s__?_t']G>o/?_wys ^)yKX}~d't>~rBzL]T,_L>D\Odط>-5 erRCW[C՚ka*lWanh%l0v~]8sRzhAA.C'|;ӠS_ksJmzh0ujx w+ t]$4&Z1VT~>ܸ ?Vkѯ|Pէ^ CC n&JN?9T(A m0b@]'j$vό;hE [F6kVA8fߡ#忠}-_ {&k k!LT&w2ȯbFpGV tj]?iLAm#> Az1dc8e Ğ2jI:u;:&st7ew9Rc A\.`G݈pG}H g#(J`6\sx  >Os x]tEO iXB 1pnM(Jrw:tQ%'lH.6r~/]f u8p!d&)Yh%C ' r!) 8ossP3d= aSruqPs ݚʻO{G?ڛGe}sN&229B JE8`QպtY媫NX ]U]F[VDEƄBB朜sz}뾞N]}w~~{G>gA™TY/xㅏ~sz[1ks沏~ Q_G^^\~'uy{>?|[x'}}zG&]pm_hҤ[T3dO|#|޹H~ң/}:c'MoՅ=_ *j GOz#;&ZO.ȽB4pV˻c~}?f[vwk~ {/?Ɵ<|.D<<jVL9IiNHtɄ~KN}TX#`n:r9G|>>'ޖW)ř,'Rɺ"7m֓΍h'%4h; :cSءC}o$RVl cia0A :wM^CtJ7`cl 9m";X8z-xuc.q5`S7ଠ}Y(e :|}B,ŬͫÙsK<̑GQmc8ƆIwxfāvnשԟ/VL!|[]2Gƭ7kNw#n>_oDXbCugn+! a,"c2t#YҳKF#=$DWT2)9ր8Tf\1_azQ\ fCJК#mBX2ξWA_.~j,y ܩHw*Q/ XM쏴C؎ OR;NJx @J#'Fz֊Iw`!dUO>Ό)Ꝋ_ LEǮYqԸ{Hr+DsEap: *xfgg=Qm1ZL  ]B!?%Ұ`(A ?nRڡYDxh O)vqҿn  }H{s|s w<2CI;N:Hv[g=mRkΩ 0@1jQwLg^ÙXG%sH{k"Rh@ClV QgGs.=1Dw1x'94Kqn [q6U4&r]T~SF܈7$[n]tôˆhɘ꯱mub (mc:}|`j ֟jftg0ܱ$V| /ZW>K&ϟnk l{j]y \\ǟ=MH7(@}*]~W~,{_Ͽ{N\U|'+O- `|'>~Kױ@F~Sw'zE@/_"gO~?z%)orsG@uktyk֒i{ӏ [z/Aoh?pȽ|ޫƫ!)z+r6c7{6<*=ttQᤌRvNz$; )غrĽ4夺"\Qnڑ{m~G^!g$[p1ܛ}hmqj&鈲b۫W#B)Q͍~|9HwiX퇏ac֋S9J? hK4SR"7 l?F"-?4';al |b0pQ=)Жop\Y1M1 $NЍ1RD:wi\_=I7 ׺p7z=Wy/[7!ꑓ{l''5a6sփ<#"Sy ?&Be`(a4g:m]pٓ[Z B:[-kӹMʃ9`+ /oQSy?u fmy,9472n7yֵ}ڦ ~,zD3K*/ xt<2"NDǒcVǩt\Lpz G햭mݖI&2怋wx8rrhV>:m 9B ujLK:@\Wێ6'F1NvޯD'r^AX&P,RړTFR0 Ǣ"ۼ))G^tcGO|^gJo7]~z+>_M_S?>߰|ޑngW;gzCMPBˍG= En@NVo_|LT\,-|nnkޮbmPs>Q7UЏ[?[nަ}'._^q/}>P~G߼iE>!_m)K,¦r\7#y=Bmi֩@h?I=&ejhp+uZ> )r7#f(.i=ִ&9?q0lF擔A[Lڨģ[VV `훻|&t+zHlḴ Rr58Ģ= ;- UNNֵn3}nk4"kBclLj>N'rCբkߣrDz`eŮ ˹UO>15E*a,kϧQ(+rMނE֍G01}9Tvwq^o|ߏ> ~ͯx+/!z}%O_ŪSnoK?tKzD7_aE_K>UC>|~;^ӗyӻܫ>+_tJ>=u򳗟=뉗eϽş(9W~ׯ}iz%a/߭zy~ݯσ<˯u\xk^vSU>ǝoAߪW;>pYE_g+쮗?q{TUOL|Əϧx_пxʅt&fIKdͼ8OSr3Hj z䫿94X/HI@ڜ9MَG jOڽ)تLV^PEpb!7S[5d#+n<̟5q?.U]:u2#q!4e$kCi}jg+}AGT4K?[}iM>8d^z]P Qp .Lɣ'K'ɲ=D\[nӊjiRnll!տ7xsTZ(##5]XfK{g!Gjo<q|'Q'<WQ؞FG{&3YӠraz[*V8$`;rxo BRS1;7 SPä4ؤl7vr ޚqЛ \69zuΈwd_mǓ 9"<:8*pd8d4i ؂vƀ, q=TD&TNfkLѪWeW6? s.Gs0. DdEc <'h?\\1$6'P#ob8;s"rmϳjgl6sgS7Atu^[zޯoMzK>i#'/_#?ߑ>gk _˗mGߠ3K#}qx?4@>]f=sV9sy'R.^_>u+Ыoܫ|!3;ޟ9s^_9kA*o[?py?|゛^70^{.Wx'= P^Ի.[~=}? Rx} Sv?ψyy/ Q}{~g./\xuOwi zDhc,Yg2&۽Z) `>.x NPpsdZ{˱Aj VmCuNyH/} bxGD pvƪUgs4j.0ʭlLK݋mAvxRRa!*nhHѳ9 fL%]m&2Hd㱤vWڵt:P&16i#EՆ=TC) O(3$37+&6yg5^4&SONd֟C/9Ʃ>kf^aa Eҵ01=d Wb>1~Z{kd88Au ]ȬQH=,@K2z32ޖŇvMK:D;n^oՒKㅴ1pmbNAI: fUukO Ɖ+W#;rp^{:}$&~RBg&`wu e9VCYp~`T'1簓ւߧ4ٝ^ouƽgCsпw߅-c4RekxD0|FNsBotl!؅junq#ޯm6畡jNŨ6.r5;1> j܄4vlR_ʠ6NMŚt&| ø\˜=Nj\&xI%?!oкI)gN+ZZ\`.[\>>M'=Ưh,w_wsXG䕑||.ew,;|_cۺ蕏c&7H:oOOuI݀}+!I y1 _%;۲ҷc D6Fozv-e9fsqRGLi1vzAFX %.~Ĝ㋋ޞ/f 밣Var)&c9*XSOJv3u]w!\h?3oŇjZ u 8@4wc+J g;}]MT7h}*+ Iekjyĩ;.$8fLj:xh IDAT[qdip6X[\奋G_/oJDŎ{lÖ5)aBf=Y\t5'nH)kx{>&Zn1cxKKxz?Ƅ2Т7Z.f˹[ i][2gy25YoσGp<{z[k`nFK@量[xホ~f1youqn{){|! - R)h1ZݸM@} bd\1qH|d9d^L:_.9Y'flʱR`ktR_ږYZ),KϢ&z̥̞o|m d5 !QTQGu˞BFߌu]Qaa1/eZt6Wz6rnyA>^Kiq )[z@o\Z[& Nۻcֿ .Q3b.;0er6XjYTycR̎83o|^ylݼNO{/.2Z}-\r,|ǫV ]@Ozm^M.AxCuܶÏc>_W~w6'Lxʼ]yVz Շ<@Y#Ez^{偏e7vW]̮+~ScQSZնOٺG2Wou7>>Ode{׺prmC7\Yj)LIizx:r)C+C2 <a-s@;/0uB V* cBXĽA+DBDN41-9\c+_QR#6񨵰|@o_kNzUn"DTGndMY=Nr8EfrkvVb'"].Ub% >Hv'kyQ&4KrފcN?IE'fh 66B{qK >QL=l Z+xO`ϗ9re㐸| i,mB\ӗwXMz&;=*v)й0fnEÊ5ƥslcݞ|1Y-a7;0=}$a1OMA{ࡋ mMUǎE95@ 7і-Ys[9JxUPr]OImZgpF޶b}+(_ K $c>6~Ap֣,@XMwd\}Bv-`Z\ku!ad:4]Z(:8e/\sދ.{7'_pL#8)|Dl.6o֙V?zbR&3.>{F] 7*?]zo7Sd^_iǣOՇ[|##c7{?GDU-~*@1Q?Z&wٲnQjomn5h1*ۇУX{J=<0PKzXQup^[bsRb)Bx!ޣ <:|v)]/>^~ϩx'|R>~[ᕏw A/QgUc*#7 J.EVaa}sPn?=c:Mx)C)#7$'ƛ>hpXv}JNqS(m&!KbbK֍$ThM֯>Y!өJǓdo ӟL "ӍTSȶ0hbgރ3`9R9e,^QTiz<`b5YfY̱4y ޜG]kz DMqF5PPK'"n,R5B3}D; c^؃iVrA]hmS+V:)i}1":֪u֩AF #\xs]1&oz0M?mQkHIV"9=dtg>ԓrH}o:s|nivKB=UUUd5.&!RCelrbHFA۹kKn]0XN_:.#W1j[Tiƭc7xG8tU6 0j_I<}ɺ ^:7+x iu3K{C'@NAǶͩ h;n*98<&uvۻlnvנ9 i/7BuYxZ J<f8QnjzH&ʼ"zV|#([Tҏ}uE>1 >Y1OA iiYw }#ysǨ9;"'44,ªfr̒Pil~e@<)eA'M'%e"^2:<-a]kǏt|XL%O,W!D<@L|0ڵTy,O2%r9T^MbzMSk"Cimy' +Jt'+G>ɬ)[kGUAlE=밁2EL]7gRhB4{Hfsu g%:c5Fp<-Y-.Sphw0Rɢ^{k~i^>y>9NRWw/m-k0z/d*bRY[1Yk6H%WV_ҁ#bĆpk6Y}wݵm߲7^ƓAZ!};.}0u"ҾONW?Bh?|Ts & v2(гC{y[;滱$YOۻgh~9ޯ:A9:GL~ru;ty`l@G<715Ccv}0~HqT` fĢQāAIg`*Ii;2Aoϑ`{@!p̹etIԨi2F{j}d:ՕY'?~pNYr Cu'pg;t 99BY*T}̯'@`p4 #VP…(9F6sc!/Fρq3ҵ-8)pP<"/q[ƌ(;sߏ&yxv&I&f@~LC@(~Bq)M=_8֢׾|Mi{ Ƅz¯Xlä~,Xe"`*FA0eTqMX1Usм-Ъ4Ѵ-.vm\ mHidã13Q#YUM52cӵIAo8ml~bAm;m^[ln`N ¼R= &Y,A-%݁U9|LI1@Mxd=_>ń.3>{@ O? ~c~ƃ5<-=۲a5=Y^uSN){/|H_ax~0Oˋ粲'|zg K?闿=oN:92.m[_>e"$봪knmɈ@V.UD+LQcȎ"*I!XU;lUs=U&Xc܏N=ia;{<߹Y;{rH&__`pY6j$㆗sj h/[(gB?t\2$񵰖<vD3xs.|W|7*Q 0"f=D 1BH`jI]vƆ/8wHI Hrƅ[~H³_uQjK/g\~WY+ ش? 8Z$_imN=>K?B5/MiѷH)W-$r~H zr|W>BoZCoW ?#Sk q1J΅i75>"|ΓaL]Qu dZ=^$Z,7Ta!Vޛ,څ:3蛐M)IS;K{x!φ^䦓>C7Mi.7 mKN^VNp&ml B~DO[4t5._@d?ׯ'GHʈqbG5w1yx缲aѮ/S-8gp8scf?ZV8>8VF~-J]]D9\m H35Q[;M%ha1 _أ_>3>E p:O|#/?~^8! HźQ/V'<ǟ}5y{e ˟V>}~xq/MHx/|v++fw|ϿDW0hxR5H?wy_D5\spAv꯵} +%~ YIc}YghWNY(YT57EY~IIPatI٨]jH _ݙN$w1ρ@*{?o7O/tF1<GjF dqؽg 2 lu[8\۠~rMvf\XOkDHW+ܘ0.GaMj7ςiW7UUE$mc"(3hRڎF^#Q0u t!AJgjLʂI1 `ÕNEYe 5w98 Zc&JȔ cw%cDVlƞ*Ζ5kЎͭ@4Wg^Փ󓎩=(e=qi=x! |@_ nm. m{t^WWp[~}uyRjz zǯҷ|/s_DZ5_mVw\ޤ`|~o> ͕e˻ noEU]>%O/RƷ{1FYr]?~Z8|Q[\>/7g/so#_t~/| |~] (ٽz+>rݭ}y?x<Ífߣ1hNNk#x-M8<1J~*zYPlETtwFI2i?эvJfe^Oc,ʭp ^KPH< ܢS`](N5K{ڐv|{шQɞy]% BWiz.k=+ ̃JxυЎ3$4J`wÊ0- Sb]n\8GR5YvR 'n\̻9~@F#᪠['x@kR뎨=$ޱH{Kjøɻ3)v Fsm|n!`a(=Kw?Gj*M )VьNCk7I_O^ 7Jpv#?דXغ  cw[`!ߑd7NrgA0ȷ94v0T`{$` !JXnJz^S  u}FZ.ъHT%1V}UW\7 &musfK0t^8d5<c7 *d%nyB촎p( IDAT%ʷT x6VX:2D?YAɣ[|H巂^W C/ΝX!(QvL"7 Yj._KbLF'*JR /~|NgϾe^~-x~7"?~L~R}W| Ǟt?;^ç@o/}緌x7_=ї]+;?+gc%Z7-t;OIo0z&1Vyw-}IY}.= y`$߷-,cdޕz7Ɔө[Yjy3x3?Hś]ر InY%^bU.=8- IF.jj$ȎjfYiߚVrR[?݄u`P􁍢"4KnπjoeOuL t]W?VenuBELԬ)t#a{lTe?3_GvO%?lZ^h0kf:7v+ю +*橩|N"$˹ӵ@$4s`6%M;FN}5@}r{Nt5Y⺄9! VC;Ip v"3=cJz=:9Mͺo) v(yC@v7 jf尷}sW's8ˆ740ot5.W8cx|, k?s*7N=x }. {Ko>3w/_W/|яo:Ǥ')X_yu]o.3>T֫$^Wos+8/~μjr\AussN!m56º$.`{aZv*쉗_o@RiRIJv1Ă)ڣ~Cq0nqi35@ocF}?k`?l3ʳ(}4UٟŦڷ@[z~Cv;- 9kg &1}|vא$yC|l3uaxK/_jFZkzۚ 벶AVvH7p2Cb|L |\4 aWb]mƇ]ocGT;f)gi;fFR[= kG Cxc(j$[>t d:&N&o\x`\3 8'!TxWU`:6Hʓ:Xt֎B۶mw 3Ix68v7;`Ǧ$wQUVXC6w;~,7rn*_ۘn}w)&Ex4^/*{@\Loy|۫~/~g CN/y~‡)Yz>;k^_WY_:d92CAzcz3v;o|_{t?oѫo;?D6m=zj)Bë׾^[>蛲nVr3.oy.ߡǫ> 95ˏż>xɺi?+@y?j/zS.o׏2M~*:0Ik03#ӽI dF5jj]~@:GyҟQY!dr[3)زaχd3oi_Xˠ&Cf.NM.ĢqlgY-|;|1/ϵ$Z+N`HήV\:XL\!9/\ịrW0E, ?Y%)Igp&#J\` BL>ju*qs$]TX x;@ ͇$|T?3i,ɑA (o݁H`z/prebw=lo2S訚kTO=kⰕW cя)s) Vx+W<&l :4m7/T!/85ҹ:ѯ=[s!&/I\M]5q;"tU`?)>w~՜^qR oŮJp/X zbJ9G%|h`sun-I4fBzN.,MYQWh2{m0 )G #"LJ[iGĞCCq֊}|ꠁѷ_ tgsgLn1t(Z/:+g,: +¬4.;&s; gT(z:GǺ`o߯ ]-(CZ]|vywȽo{|DyXe?JP0{4| 'qA; Z8+x/q*7#lwD_6|e[>znFU emn17~m J}nROv4I]W ?k1y,ւ?>[54cj5Dm㮰ceo1s sY m^8l0|ڝ%nFЃ.R·*FG*Bi~oU,Ne^kLf9zHII@,MΣ2hijn@1~D1o!n+ͫ=֙yO"K`'|W ?0;Cƛv0WG"aU躼c~}h4u7Xw2fF-`h*v?ܼRp327"0) HE!\ɦ5&zwS[gQrq6GupNL07Yo!9wŲ%tskMcODc1j\HzDsqx6dձ䑃3yFY2CMWҹ _ m ^]n02,=ls|,غ ]ǯAs?&藟ui}Z`E ϙ#?D0tȩTM\rbUT*E5/쭼bF9~tJ'5 6)1=慳0Zik!Ru \ʸ͞鰀WCx E&ƩpݒY%Fdk M]mk%hA5cշ~0F*Xf[JV(R{aǂQ-Xyo泽c6$i1=#O9 >H!ggzV,ul9F4VC>relO} 'H\]3kҭ L րŮC{>>%'e+kW p"g0< pC(d!';#؃6fG'4.`w|l7|Ʉ-^p#9b9fNwiaeqvP506g޶5XYwg|J((wvxZ#7:')nR 7N&-6Ԍ"$ȃ+>Whts Pۜ1FCl#ZsA/ >#5|t's?PXܚ>!3nۉ<0 #;e>qG ne2M9{ZU5@mG~Y0Bt'bѐ;Tϭ',rtby F<9w0M<`2 0WM^iIrf"ڍm2|.g܁÷qMRgޖBn* хv7 ߪh!ՍcYvV]hev$h+Nkh}ԉy Z3TΙ 0`6g?Ce0HHkڝ" ltg=8nޢ!ym&X(XmR{*͟,CsJ(3 Qo:ôg.JK)\|4 !e4K܆U]@6F掠<,<$tc&wh(7208YU`6aS€(5Ww:FVgTF /2=kͿ`vp9pYQٮIJ1OkH±jc"sYμZW2 qLL,)1MC[ 6D |xb⣽hQ_z͌+(SdNaș\6- ϡCnl鰏BDL_׌^MrbsNfd1!jz7x~ݖ\!ըrt\qKvylrݞFuNÇNINɞY:oImᕽm<#~x'&?8 (k: 4lD]eyEraNWd;&qq$$;hߖM8di }s56ý}5cdtp]jm|7R|,R˫8!3(Σn{su]Mfd11(Tn.<Q=jXG:b;pNY/9Lduy@ ihNL60 F+4P2rI¥wi i0 yX7%/US 6՘pјc4q]ˁ@N7 yqoZp <#Mj1.bam0< AD&g{0.ǴsxVq=C q~#J^EaL7Q46֑s)2(GX/b@ f5:p876Q+ՍX*Uhi'^rx xqSrV1D^^Q m %(#1GJ.(I87'Xv _XX t^> K pD7i ec[XdqW6<0Hc4gdákT yz}[Ӽ{hWs櫞OK'y۠m&NNSӨ8meu"CIF_ؕ[_GZ=RQ_^k|ܙ.T>+օmW&C^; I(gkH`ajwe)|EVvkᬢFo|U{6\}j+ RYy-. !PWVLDqp 9sv# ݢ_z 7˘0kXdo,Wv5וP_iomHn۝z:BۭŁ\Κ}l;FLjqp#A͘Z"R/OE08Q"ч=ju3\n@HIcM$rvv:M_Id6 H,򰌞 7_ȑGa>|`bB0#$SfL`ᴼqT6]$_IIMf' K쉃RiZ.F>@;Ʋ1|{jzsw썧(S #zY} :䱒؁Ǭ3$GIܶD&EZnZDz'L{8|t{ Lj"f̓<9d-me:ի-T[zT?yQQP;LSвDlmOP,0Bbz3|ߞE3q&ȒҀ#RT[5 |0RJ<9H߄7I!o/4إ1{N@05ߝvf8)&a j>RUN *ѢI\bGj`Q 5`mHxf b7|aR83#9[H yъ+:uw9JtVMŖa9qGi%|҂koO& IDATV뺃nj[iz<biGT8) 3GkT.t+͑O!I.51hL3UEEs:0j6<޷҃|ǦȋV Ҵn-16C[uRأ;!o-Ix@h+uS, ڥ6gmI GXB O]Y<})Fpy?kj .wO jnM: K2ioK2o+k,66Ɩr>}-XZ_פph"H.h|EPsMBܓd(`Z1lVT0l{1+3TJ^>D;N" v$s:hpYBsuV:axţ<7(|kS ^T6v993{3@Tx-s юY랾6!}rǐvѩR'/aUmFd C7cTd< 9uweDV)hX+5u0 k'kr_^]adN:9rffv}n׮ʴ)N2ۖ\.~zu-( _gߔ7lK5SH +n,ug=ɣ&=Y8(&Қm#'m-?*|cY'.${r o[C(܀݈}Er8=y¨棷#r[5Σ.uƆTD;h~mOj:cx\ ilm늺A`Oз,'%eu4Z] I۔y#sf{fͷQvԃcVkDrDRmɂ rԎ'2b3V;(R*QQzҢاz;^9mH5F; 6iH$Z>hIÛ~W&+h9M!SF~RLfa`Hs ?z) b ˃|4(372Wپ TO  `°ŁajRa.jD9xd (`Q]jθ"ZG_XiW|CTbJqFm/Lk cb.%o%)yN!11fW)~ܥqZ~xL3 I?2ExψHZpLox rDH? 7ܴ&nZkM't bDߐI3t{$eBQKA1X: һ?"3:܄DGZ~Xxn} H /&d#S5P'Ki53c]<8-p5b|NLMk.VOW&fpOd}T>h^~[s/SX*_DN軡Sӎ]3s'yx~sV;c چ Fɩ5R5%'ȽT|>:R(t>J_5MSt؁PSVTۺ>!*ahHT9Q5X8X(2D}2}Rj  OIk9Jh[ 'S2SoT]1@>{nזRz(GE!pZG1 ҁA݊c[ MQ94RHK.߉bp2)>TVf+;݂ ԶÇӒcU¯'o=Vr/G* ]SebFv~ؗ]pwSe =`"jl`>mjdow +5.iagM=jvp!u:YWK;qu4!KSm8Σyp_gt#f5.ޥُp{c¨Dc`j֟nGw,2(Cm/IX߰n6tkЉ?A'LR0R*M4}`ȳjq 5bդ9HOFqRNĺkeR[7==s5&姄kgm+tye `~&=0Tb?L9[#l>Q.Ewڛ ڵ52hWY$=Zk(2l)u-%Ex1bfn.kZ4F+EE.YH9{%'z)o5( أnm6 o{brFۃ*m/{W`Wq'XVx[4/^+V{.[$PS-@)- ]|9gܷmV=;g7sᄍrp@o2ZU#f+mA>?89LLwvAC$ ؐ*SkvE@mٰ-$sӷqR5q>t2,RwvqiBS(vԏ(O5+ݪ7Q|}Ki! T8TPnvU;S͹P iU *neٸ5Fuot t?$7#i}Eu(.hz4g'c?$gjj3;TʓVg$ZJ˶h ,KybM6F0E蠖*#M-ɗCK'޿ʗX(z&GU*iH m*}99V{nJ%m iW;¾Q׌逖9RrM8 \(%[@1՗aJr{tM/i mQU- q6-g@ߍ̡|a2l?Jz\0Y˼>bE#GS;; (,ѴZQ` ;3?\q!i0Ǐx:Db{ #ŪF o=q>iNyjvLZL?2. HK6HSR>㡌˱/D،4}W;4]O|I8*+Bi)e9_Pm[7Re&C.?e:~ß-}1#PեkjĴl;!r3Rn8bgFꢲmv#BaQ؜?ffZy>h]U`ln[^3":IGϵ4J\^C0+T`!3<ʽfЮ; eS2кVE,y>DB5d%ךyTE iF.E7ښJ4QdF~|P dKpsa[+P )b)p[Ē!s,~,'[ꔴy\: u^p@DVdquH9?a<젎/3(g}ǑR "[,kԉFmd" #1`,M ;iHǗ7H>!7/`Q4y m0i퇈t8"X?K S6T<I>04d7X2!-N% cDGy; x9lot 9_j.1#L9˱ Cs9O1Ħ  Zy:#`+hwV3] '􎚑 e Eʹ 2 x չвB_Pu3̢o'LiT̩s* ]`>FB,|pnV@/mN/]"7 4C8~daSqɥ"-@a;&%Oi[92 t* DqPp#L6D(Mg`ڈ(vkMK*6H^=v^xHU+մ37YK>i޳@r4QY/48T#{ Y Ӆl-+MHo*zÊT 9%~`X\hlӅamYjzFOTJqM Uz@1Γ>4.DžM/Zf#dH~x!WtGš$d:|T=FMHUL'ЃfS$ |ci#¬Pu㵵J W`,6_\(90_&1L!6E$/-?JmQALOCN#è_)м m&WS! 0>ɖ|e0KV-v-1Es,F.^`4$Sܽ I?.;akf[WwG4A(#ҾS,U_9ն -g\F^x-B|JXuЅ)Xg`nUmyXUQdXiƦcƁKz({J*.U N:)U a/4RT 'AR!9v$eУzͤ54kl 33IHb[@i6ԕt %9'z>Rz&YUk(L˾ hO/%UA[U`$zQ{..V YV6PQY-YB%&n<1 9::w5CsTeJVWrBI IW-5ZAh::+vu_7Z5l\&jka:,NvRS6,uaQE|VMe2Pb'S;-]R~FDcxm ]{c7Ǒm$*ou2.qPfp':PiY^WFN5H-OCx]# DjQ6.++14}FxʰN!/} }S8ei8Y~_J>sJpEYKk)x#!Vn0q%mƥGW_7* Uڂ=i73 d1c,=qj,΋XU# "]LRy ܁ER3>`0TݶMTRoG@P ;Ҧ aP[Ӿ'!ѨnM]=k}/& pԦѻ<ćg x@' #s\|J l4| nC>'9"Q=!hzBK]_ \:ހ{gRn R(s 5AӧlФ&ka[SM:騵)܎(>|2 6~݉ mY C_66"[UM ^@j{4h>+ogJR8ևy MTǠCFU)h:jj/Ul* l]&DU Vic҈G :*U: V Y9g֟,0Ւ}ʘ;4}壡=Uq/snVH|:gM-۞ԙWjC杬I 9TP>Ff?҄ՠѬ/u oEmgrC!z?ӳ&f,LK΅T Bd+ RȩȢ*[Sײ%9ď2E6>|EZ[d„| TcVխPcxm0:1^ Ec\ q3`9x.EHH B#Pjn -/~Ni.іlП]o<*]},H oF{&ῒ!>\xV2;"P*vE)N5­=O(c^[ 6|xjf'GmΩW |œ"ba~az(Ph 8)]~_BA, bY+-Y8q~(( ܰX(DEYAcLE,4g _նV谅rۛ.fA;z3uj Nkhx^̘~ OlEv2NБyKbh7Jq'y~/OFƤDAzL(LchG) }Z鎇C tݮD7 @| 4E3UbCvEV(`_DşcZD<AF8z*w$eWvR}֙ff -xA>2kgR)*qR%jnM*cYKr !:uWRغ}  lK/%Ox`bϾZ̺uU;t9⩎VO*ZZ]ަn@\5cڇY$;+y#7O/0785dUWyv#MpTeKݢ$Qƈ<B>>e>:9fbUnElgiƂ YN֪3w+{*|ږĀ\°rwxLOHENyY(lAfsf9.^#R`K 1 IDAT[r|W/U$qbE#ueCesBxZzڔ-CPgLo"j:\A#:Kk:nL22l-Xm$€3|t3Ud9TSXTrZ($f4'AMX Em5}J]?5{q]G'd Fk< j6>(2H۲ ֪H7tM[wܟW( fLDDŽfaUD1̫L5;xfa* Tl՜5XP*3YFN;Ro4瞤||O~<(Hmiseif1vlan#Oak:9'-M̎a11U67o@ DBjrjx-,q< *BZ% u;Dm *`j)5Me0tc*hCy.0&"ͅ30SQJ1aJslP4!U)mf dw-a'.O1:,poX"@ dTOi U85my!ZwK=R \!BekZe _p.=GT4*谻T2=sbflU w )Pl:p\٣%:!jU#nNL$ބmzd *1['zS Y Ú0Y h͓01skQtFX4&-_3 Rq;6;i{ػ˚UCr#Zb shnd ]G+ *)r!%N"7U)[‘NCRI1 \_~`>PC3y 2X; ̸ٚp%+mBژ5 \Zb{n8GGp-Vw8ʃeJJȗ 9XY\JwE0lԗ;t=p%je`$uRzC sE=wd#멹]X̤twbR% 6~`R)P6WBҭW3s(UQ*^}:+Zd$)z :n:4qE&w]cZy`)Coǒսa It Y]]`R:\BW^E4oǁg@jyAZ9D@ܸ֒e?+G95$ BE9K)bV}GQkzhg(`.0m쭐ǒt-|)@2kˆ+A!8}AqwV:P@i"3L=D1^P5e%K6 jaU5eE7:؟UEڌW`jĆ!:+Qu[M eJ6살d'%yʕݧaȐO&:/Hq#(+<k[8 2a~=+5Oql߬xH8Hێtֺ}th 4((|ѓ$q(|HK*׋2P=\6zEEr1娧PZgf9ԃ1t^63d>fQ jTzybZ^Mި  UHe͋˳SS#aN^bO qS81eE[Hz\8YG%"TēZ:{P+q;M_Đ>f$FfwE<8۾pu)ZuN}cds_9"Jv;ǘQxlIР>s+ k/Ֆ:\,i\-V>M3 p!7[MR-|]02wZ@R6^:m gz䅁{_pŰ T'd09f'm-As5tՆiXIP:YoUySRho6:;&UqMѯ[Q1ط@ʪ<|)E*Fx;`v_ŒrD5fDCM!V0煘ԕY=)AaB4HaW4Wkb,QuH}a6Jr SnA!r>&4TjЍ|mlz&  sS˞Fw h4AUAنp9&J筨ASuCXo<; >,7-m_\]G"DhqK|T%%ΉΊL#ByeCN8K-oƆ#аksG6᫡v tJ)7~ſː9MmCvYXx~Wy u}dYծnn<,mO)rkE'UtUJmJ"MLXE'cv JbC I4Pj >|_C; LFr*ٮ.SAci7TX:v0+Gj_ = 0 J֌&|$ -'Qѵvӹ(Yn}YRdR$2vf:]̦u^bٚ:B,]<\>ST׃VNUCvX%sUn圪;r fMFP8%Jվ́jfB2Cb#F>^g:7 =Md`iV 6D>ŭ\Feܚ4u{lViK=/WPu[|Շ`fZGFV%5\<^AyEPCF97ATs"WͰBlW'UN3ըxoݛ{\݊zHN#Ѭe릂 |_fA  д8CDp:R:3VEU-4 u-.tPcxTh:ϭЖ .Cy֕JےnYjӂ)GntYfT3BV~P:6Wj IJpU.UR8qF}|9\x656Lgup1@)rZllY!-r!>vmM;\龈QmUa?9k@PB sƏ+qv .0V@fmgE{UsۂgB=զ~%q`D,>e̦4U&33n~(r:)fU*$j"4y]KZ n,ZyC|yKNQbHXEbr,sHtc 4^yaՋ8ThZ2̿1jQEr8/b -edJ܃:^6w S+ exH)bAo5m<%KY U  A@ @ @ 9p.@ @ @ # : @ @ D  =n@ @ :@ @ @ Ab҃@ @ @ # : @ @ D  =n@ t= IDAT@ :@ @ @ Ab҃@ @ @ # : @ @ D  =n@ @ :@ @ @ Ab҃@ @ @ # : @ @ D  =n@ @ :@ @ @ Ab҃@ @ @ # : @ @ D  =n@ @ :@ @ @ Ab҃@ @ @ # : @ @ D  =n@ @ :@ @ @ Ab҃@ @ @ #0A֭q @ @ q ۠KѺKQ @ @  s1"nCI@ @ Xq^@ @ Xa$@ @ @,@8G/@ @ ^@,@z0D@ @ @@  c@ @ @@  b"@ @ @  1@ @ @W  ^1 D @ @ ?He @ @ +HH"@ @ s2@ @ W C$@ @ b?ƹWrO<|^{??̳w}4l~3>,((L̿7|kԨt_"lϑV^yt/ dӿCilvis#˯g8$?[9ƒK-ެ /m.7igJs5wZwӟx 뀸ߤA쓋Zls>a3aly1F @C  }oƩm2kFmjiʲѣGο Jgc7|ʹꪫ;?}iM7Im!S[矷xGҠA:O>IGiI&InMy3|Q6\se_|1Z{M+b>|x}+uzx[ߚ" z4?mɦޣW_Mm)#<*}9O+mvq4L3{/NtJ+{/h7@ XޱiD%}'篾*|-7q :]s5>H~kx핎>;-Ē$m&cn횎:Hu;٪`A4 3M\ 0 ] \=ϼ{>ìCII7i6;cv=cYd֋ZoHvք>{/LBrUƋc9%@" ;vL~㦛oYVʯ\]ouӌ3ΘΗ\x!o(H%=rrϏJ'|RPAn9Y[|>\;^},ﹿ:Yx4$sƈ;LJ4,B7ݔ_p>(}֙BSd_X@4++By_7{=}V> -]7߼qF @ o85rj`ocٍL8anmm4xc*cᷡ}_p#+yUk9sZ/W^e}]w6|!2o{=tӑ>3<|62K/Jnۙ_2|EieqW:polhWЬ|k e]&{` 2DGq[!, @w/ۯJ7?yW? ܒ۩wU4aG.Oӫja11SL㏴|0W:7xapQwq2@ >@,@؀\@H8:levm_fx)jI)ƷmZ(|q 4+~y-Eeill5sQo̟{x^Yڪl#}._p*nӂ^Gߙ^/(5UnúJd]kK(>FYD{2^llƶz[0ۄWw_P6UܲŇ/\袋:% eeNLmn(b "ϟzž ֘JgY܂yD_ //cz@ }=r1vm7gfѵ!.r^o#yYB,O?}[zP_~UEmۤp;L`,o繤wiǝo}poO?#>~Qlt|ЁRo.kRW}ymݑw?[mmoxe~7r-jϲY8#,ALDcLt{*㙃6~(M5TSz]9nr)v6&s4ӤسfwD`*yYg6e2wg{.?6nj,xsy}ICV+ eXr%Z"V]5=#q9 x#1p8^~QGJgY<24SeL34i|s ,[R96@ kfM wځ^ o7xig^e b?LS[_}&~8й7ᵠO=T!ŖoJ$O?ܒt!s9;ߥ%p+LmPlבwo3X|xO=TvR>D OzoP4=_!-N;aߕ7.|jN;mG]NCkc7 /xl;5Z$gۨ6W/R UlWv~,Ϧy/sGXJN$oT2dt<(x.Վ֍imnVe|)C;q XK} a殱]fut߽t^d- @ zxG @ @ @ P"W@J41a @ n"Хt3fo2bE.X3G @ w1?me.h@܂@ @ XF  cp@ @ HklB@ @ cXe@] @ @ F  I @ @ eb2 w}_=M7tM;g܍:=QN 3^@{~12M7M]liٖn)oj@kD  _##뮻kȗ_~٩X\8_1돶HueoI'  6'8aC84LY3^{WZdEҲ.^{5KiWO ,@Zx\\C/Lx s=7ۍq?a:餓(2dHfimFCs}a^7|szb-\pꪫ7|f?ӻロ]tQb?ځ@ t_1aGz'ˮ6.ô;)42Y{ȒkeW8_zմۦ^bh_'?WMӁ[8~qmI^@ѐUS65m?קY=-T@gH^[ V[+2_Nv!xNO>y {ԨQBOZ+tAniOO?tz'FmD>P?>il#{#GV[-misv\qnfmN +85qiJ?x;^ F׸z8[m^[UWݜoqa҉4dQoV]e÷:TOhm1||䶴]zҚn4ۈ{,F2jk O[o~oKQw=8pO@`  cx ;oaߟp{ 7ܐ6|>4lذ1z8p`tMӟG}4~ꩧ&=pK-Tp kAK/^|l駟rp衇r] Z' (ȁ˳>6pC+@ Zc6pw6_oW醛Lo{?LiV&6Zs8QtUG:~dM"Ԓߪ ?\Z4fO?,8dtAX?;J?x_GB/..aipW>p~РA\tI /^6.NM4Q"[og ۼp>w}w S+~it E3ǯj8Mя[m.t-}.H:ۿV[Ny 6X8z}[%y-:}&@kG  _;W+ntۯb4$.c<㎼ >9Ҭύ:eOo)F?q{V+$Lp櫯j.x@ tfǯq 6xhw /.~5y#>Fnogsk-riA .&{(1toէi=~6Um0gu4nE  E0;ƳsOZwu="oF—ʴN.>~mc=xoL)ݕEE]⋴N;>tP>EͬΚwGJ>wK.IGqDZh>f)2<̏@ ]Zc60fҲ JC2{lcPoUTӊBұG3W^zJ]o8ɿU'L;GNC1-zwOε|>Gtxg["@`F[o)>_L;c<3I'~|o B[M @ :E_d+1~>['N?ytg6[fzG{syoU)E2&]Z\%@w"_Z\W^zj*NK oRyƲk-ln@ ucv >Hor#Gw8Z>q:txe/ʸگqm?@ 9 Q@cC)@ @ @`,  b8xx| &ȿW‹+~|c {.+}'<"/˜@l"2~5Bv9V2謻яYW"= <>@fzeM3; iL0͎ʷe-ZQqX 0TSUkV~ofY^{gy&=iJ;e}Qs=Z߿oON{+ NG{{'ӹW7D;~yꩧ+B/GuR<.ؼj.<,N;-J7mI_oO+LPړAۦg~lDJ~|Mk~y)۷[GnKy4_Q0>@,@+"_/2W0B_}9眓tW@Ygt7S_doo~D;~|AZf=+*7~: GO"ᄒp,Mo<.3>R2U/~s=ۓM4фiU~dKHyoZgto~GWݜlJN? f H0 K,ooc=ߦS ?DN=Դ=q[l͖9yqH"".owy[o~_@ n[QL/c%@J=) IDAT3nŏ '|rí%Umi2M=oy;K/ۓ53.NGa|t5ѿG]Z |k7CD;O[M6 .Х^~4 O9ަu1d.jWV(q1&`=u>&F \s a nELnUV v\f<#u̙\~rE'Ioɮ .0_³8"-6hA{?pJ~ OߓrQԁ@F  }z^jgd±>￿Q-RX'ⲯ _y^ݪ. |U}wrɠt9˕[(jz6n 6xheϟ%\ i ]spzO@ gjH^p g.4hРZnᆴK'\/Ygpޛp˔SN.ǭ]xcsyL9<@}[CQҴN+n/q|VJ_x,xS! d%ꫯU髮*N{G./L'vaaMr:tEצ{BVMmZ÷@ Y>|Vj避@,@ܐE@ @ @E  }w"@ @ @! >7dp @ @ wH<@ @ s Y$@ @ ]bw.2@ @ sC @ @ }Xݱ@ @ >@,@ܐE@ @ @E  }w"@ @ @! >7dp @ @ w;zM1@ @ @ g @ @ @ [!#l @ @ Hs @ @ ! o@ @ GbG=@ @ |Ct-Xoh"l @ @ X{ E 6|4@ @ @"pEw9n-@/>r0 @ @ @ Gψ) @ @ @[.9BV?_8uy֟:nU?EπC|6xѪO('48ӷ'~Z+M2d7Z|ϧ#\gIn}zwjhSg㵗JWr ~S2|O}\8|sîq+M 49gu]/OK'(Ӈ/Gi &H30zhbj*btM764KҬΚ^~e\0iɥJGyDN;6rߥ^*4=xռ ,i1vqaWn/@4lqiݻKv⿒^ximO8ty祓O>)=-g?tUW?U]o"F&+5C kKϤ7]y颋.NgyfMgLc9Fl~ ㏟~򓽳M7H{$ ;@ 8q/dq|0[c5;e@ 4?,/O?iaZk܆cFWcÏH/R?QNUNy:袋~gN8'{:l6M\st٥YKN n1x i }N]xQ{2_2_J!q,?yZr%gաmlꩦ"1v;m[F'u)[yw%߮\1~:ܗ"漚B4ceu՟k! :@č:0OswV}ƭ@Zqlfo~!g]N{}|?sҵ^ۊyj?\=M?Ì;_=}m?^J^# vtWJyۘ@/y(Wr/x /۰ܗK{=nTnTqf>\XCwι".buYgWg󅯮_LSiocLzb`S{?۰|b+u\ ja8}}v(lqv[VOT5t| A.^iI&oLqXZH{q>(曥918#+366[lf%?iVeFyy'O>K_|yz~MTz..TeQCY:Wӧ{/zii}a?| r!OgqW5?<\u~rۭWLom|LFn/rzI^\5ՐMKƱEinԭ:-[t~Wu^d}kςʨE_[?z^Wћ^SO=&6~kyp궑n?upM0;h YfHBUnaolڪ|-oxoZ!R{4tӥnΫx;lq.ւXsUڸNV$2dU~1s#On Ӟ{8 XZr%erHN~2?>ʑA|M>?8%%u6B^i"Y,?VRg\)'D<icyO?cSpG/u`8Y7TANckL-@0ꭑ]o4|պ8m0ȗ_{vޮ4Dne9c2׭{x|駓K_Onq9vG~(!!=ϼL8c^-g^+y":KCֶml ?|t?ewq{tv eW\~y:g?Kol*?y'sFqr$|1h{^p ž6 /m#L;eӭl84gӂ .(oƻow<Zh!ѽ(1 WxosrW8Zst)'(|k)=\{1֔H{.((E@@@iқ("" Ult);Jod7M!g3wn;3;!˗,FMGjF!Ν:5knƌk3ZZV"䈵* ff]N:&~0rq2Z 9s:]  rC˥=V2ĚV+WTKxlcsklRYcM4 lq׃ZoܹsZ2yHY'9k8qb2bґݲd"=fKh + ~~L$@@]+[6 /1zV;*^Vɔ) 6L޲)d̘Q*T(oa*TH,[L5j?lokL,#=TfΜIJ*Kq<3Nn=0=2N(z BcZoG l[Vr[[` /_|1KHGm}b=qm;_uZ&?ei2];w,PWX8 [KeCzY6 r4m , w CkXޭej%X=AG]g%<$бL^P 1Jks|)QI ?$a)Fȑ@`oRvZ?V=Idc>ww'|ZmJHU龷sۘ$@$A/Fw3wɄ j 킷+&w6nh%V;*]JX h{@f-"&MjlnĊe7lٷoܾ}As jV@${@8堵D)ޚ ;ZB3g=}4ަOO@WFBX@Awi'㑀;+GcALg4"CؿOmBLAu-kFlرӲΖlٲ-ְ4+0 ^plY=+0dAi 9τvx0\Ҹqc xmI*ٻW:w~Mo0Jp8&V@sxW ] pr*YAc5$HaKcφ Plܹuխ~< Sol4 D< o9YxعScךbj^iy.kg(/ N*9@XC̱rYn GrU4;d7>䴼 O /C{ wޓ}z_,X}֧@˗{Ӣ={ieF=LE._,sαjͱpM_.K+/ˢ^xA?q I o>?l9m^zY|ZhQ ,D~rcAFqv>XƍX˹&w_诿Ͽ)pEy:xִiuvgҳGmx2[VxL1CھU6uՌ uڵZ*$y< #y5jDe)ZLjשYh$Uʔ871Rz%Cv$_ z)dΓ _x)mr[9y] 3ZKbdKc{q.16d͖r]h&Z_:VQ+(,\Hǁ17 KE׳y5uѠACuE˱VQ]b(֢XwQ.勭,Y}y/C"=Z'+/R߰8'+T":%mڴ^p_i X@ knO}ʔTzðx:ocG; ?oX.[L<}ZNRpo6ntۼrMe7uMgcG`~}[T)[OWA?+^B߉3p 9h-,Y21/^z'15Tqq_Ŋlz0:D\ҹma֬{@!/׮:kN>bYhnm}7oOo1ݻAaN dR8L/ųƏ 7YV:!6`ߏlٲU\J7*9r'#?X͸0FX_+I#NXe*=u q4-? +I,Y%L.^H]V-YB$@$+]RPtŋs;_l)?Yy3`+b.l붑yzZ ` -f|,tR}ό,Q_l6mDZ Sx֮[ N:xq_F }QV/X@̛ѣ#>PlF^] 4ҲJmݲيJ$ 'ZF-?BdO'tM B K+,ΛH$@$`-Q (A$ԥܤ:u?gͷ.Zi%X`pҗO?|b!My1VΜ96`_m۶2b0]}ؚ7e؇˗WN[fz b}>ڶe LG2z2+W}&@wfyfcyA9^ m۵o!_{]dž늷qX\}n IDATt]2f`b*)}zXv?μ>YAp>`oʃٍH .1K񂳀b Z@bE k3HҧzKVp碅ٳ:n |iK۶nIȂ ,i2UP»&>7\Nofc0>e((!?[?"bWۓs)K.ՖRأ?*,QB_^ q!(7HÍ V-Xɮi$g獮]5 HHH t·$*wOߠ @nYO?nob[ ݻ+e%g-er>^f^+WNyhY SZ"Un޼KXǔa.ϙoNJ8r` aĕ )X1F0هUqFe7oaj@6l`V1h,\zXKbrs߲֦-F̱oof.x0l@.Y4 D&tťs{}@t$dΜI'˧Oxnط\;{Y|Sxgr13[lѧ+^NܴqY`/zm>, ~:G?8 /Rk֬~Aa-ei_PggZ AlP%MMXLz1a")9Lj؏+H;bPKPƍ5H|Rډr5}oΛ]ѹ!eȐA3fݷ*4?>ČQy<c C˕+?kv?X6wI Jĥ-.k,3hK@-עⓧÄ}m.]u֕}qo7,B:HWRS0#&SA$;ƍwzʕK-;wq&Reh )~8RoІBwMoHU,e./ݻuX,ewڅ!0B$@$@$6a5H 8v􈾈ܞ~*V,۶m;s)[̚~)5pE} D+ [lxyAHݺu%q!m۶ɕ+WYfA2&Ӌ/_|dzs7nH%o޼RH9r<|0D_t2yw}'>ʕK5j$/0̙S`pٳJ*#G)SL0LKjdRtiU *$:uӧk53M6IZt<ϟ״ VXQ#(7F.\Pl:3sLS- @,"azyfI&n].8Q?"$IiҤ,Y$H7GSZh!?;& &ԉ31  UV &W_cƌ>@6n(O\-'NT&w'P +Ut?^0[JT$2`y7oZs9 ;O?(]    G `#(V~AN>ar_qq!x~_WXcP>zwޑRJ_ݻwat"@ݻ'SNUKg̘Q*U$ RAO:X" ܽ{IENjӧRBYh+XpSxq;$@$@$@$@@pNѝ!-[LGfSuvuYUZjZЎ(-Zn`?#T(DԩSkڙE .[P=10͛7(p ӵMlÆ um\jsuǕp=ٳ׹sg3cHHHH 4JVlˇ36 p˂; =zPkF:b_8&[wYdLaUa>pՂ$A!h:k֬j9r]4iRU`A .pS .s6mܝ-ƻ|r2eHBC|MgIHHHb HU@(!CT༟yXp$ mڴT-Dc`ZLgٳgOW ҥKv~N';wn4XM1#pW |=G'k5k֔aÆ O`ՂE!   ]B>掄8 L#*FP%۷Nd+[yЪ)tdɒIƍ5@׮]iӦ TPdȐAƎc ^}U q+WN4ݫnM(s'RW-._iPZ).'Ǎ'iӦׯk V߂@y{HBWDdݺuBh#!   "b(D0aFl%zF`dRa c5'=1n|t|H#LM[l^q, }U•*ʕ++2>}z!{sΪKrU 2†C;_o|WǬW gҰaCZ>|Xf̘eC$@$@$@$ĻtB\֬\!:t]4x6QB Ed)Q2PvJ$@$@$@$̒FMϫV(x;#    ;ĝk3%    h'%A~V_楑~50HHHH#IHHHH w=ϜHHHH;* 9H$@$@$@$@q{y$@$@$@$@$ Pyy@    k3'    N cG @%@$^{9 )Q?^x -qㆴkN{94iZSN2~xٶm,[L._,ʕK֭k    7~cٲeċ%f͒իIz…嫯|Ld Ȓ%Kw/R*V(y~ 7rd̙RR%}]dI5j}7oO?C9˙?˗/ y=>}Z+(|9Rx~z>@\eX /^mԩu?HC5B$@$@$@J@rG0zjݽ{_^6mpm5 "E# aL;~p M ɤ3!(3_|QݺjcΝ۷h S׫*Uo-PT*cƌ7?y@DHHHb2S@ө Wˇ4lP*8]x ĭ&asrg&8V5Jٙ3gB;4+$k֬AbsXB`0#GA\brʩ , j,!)SHHH/ RF S~_ܮSDAⰂ  $_n~;Mb߾}v5E0L,x'ߑ-P`Y%9㰿!\lnTR=y=v*H|޹sii,K!   & A J@FDr 6+y5P~W ra>aԩҲeK-J$HUBk޽{ei]ͫUVr5 V|O>k\ʌFpB|{ >VUezO6m% ~ba%, 3G~}HFhx`_< %)cHHHHOfI5$|hR 7w2>tɪ$@$@$@$@$@y+%۷ʛ7l"}+HHHHH 8?oXw'Z$X20HHHH {,rdPHHHHH"_/yɞHHHHH  T@ȅi ?Wc     8B HruƍKΜ9%_|Ҷm[9~]mI&zjo0Yh7nHŏ[l ,q|#p .2ݿ_ŋ' $؇ؾ}^ 2HٲeUY0 իSlϝ;W ,>S$r40iӊ v?B $&\Jj߾}z#V#`"X %¸qW^ѦP4tM6bVF ㏃wqJ-[w jܻwONAѢE 3fAҼys(P2x~J!"(AQuK${x4s{]Y~4m~̈́ J.g^%?]mB+X :/kUXt{!WĊ`NptOĝbF0i/eٲerYu[ٱc &Kѣ⚃nF{n}2d>҇Fa 2 I ֮ߪXUMI[pkÆ er?uժUSnq+7_ŋMjŊ5kV>zX)`xX%JH`x!F(:#&Ic%`b6g88|ܾ}[B탅$@$$@I4+VSXY oÓrJDFٳgcV9a&fRqYؿeF+w\OX<9 Yp8B䛾Cb,(ҔOnQB '\\}}ȯ Y 7%d@UO'} xE! _P񅖣.\&N(XO>qĤ6E6mNSX娃0!+VA#@aJfܛnݪ1!@:O1F Ď .9ṕ`,, +;v*fr?>,wP+Uf1@TƵ\r<ݻW2@<`x |rVwXŴG(>,xɖgU A IDAT !\nK$T@yCʔ)B Q3xc+Ė`bK/IӰ|X:x'#(>sZ)0{xU ]W54/ᡴځ po ,jd.aIu 4V^x @K/|oW]rgH J\X  @Ӗ]<-9#G`'QSl VXXNvP@($@$ ֎ZWc]  _2>:C01b ($@$+/;?륫_ڞIHD}aÆHݑ @c0 @%@$/C)$@$@$@$@$@ 0= D* Q] '@= D* Q] '@= D* Q] '@= D7]¦$@/]$sr-/j m רN*U(%wlaIB 3H8qℴnZr%Kٳg8uf͚={v)_lܸѮs}߿ϟ_/.ӧO˘  "q2y`*ux\s|_ /vp\ꫯJldÆ j]ӧ*P8 [n| %JOҰfi7,VX;E`1AubP`@L@R495GܷoI'6Hz {X z:.("ҥSE 1BRL^!#Hc9^J ߂q8JoJ6Kɀ`y]($}kzA! _< (*\M8Q]> xǎRZ5 b604Y bL,]Tҽ{wX>䓚ձ0yA9ܰ<(3f1Mq]NnZ!*1#|תdb ٲe \(-Zb3Pb2իWuU,c 3}p[ׅrOlyV8l[Asc. gxfj X詧 |nh%K pe ֎(ځ}UakO1E2x!]pܹk⥗^ .]h$F۶mx e{A@PvBs^g,27͛K׮]u)1<jF"'z HB# ]ClҮCg7%̊nx 4iO$M[Mca Fa,iԴY sIHHhXuKz wI$/Ay[ kz#Gx*b> =^$KT@"`%e^dcI }l=2>V.[OE$PdxWHHHHH=ƀ\     ( @$ K     "5lz2HHHHH ȑ !d$     ]KHHHHH|&@gdl@$@$@$@$@$^T@KHHH<v 3>^ H&* v̙3˝;w`oݺ]iOwmG$@$@F`I mx @4 Je%*v'N֭[K\t2{ V/jՒٳK"EO>r }p'vz )_>0H&dzJx( 7 `T@ݿ_˙3gdڵx\Ə/cƌgyF/->00P]&]tYJݵ̛>w۶mĉlN4I/_.Ç[H^8P6l(.]& oS"NݻO+8m2ieĈ FʕSFYfo N,ӧeСtR[X qsG XqIy$8S/|׭[' J W^   `2 _>bMndѢEmZ(9iJt{ԩSeRzuɘ1TTI $sAr劺թSG/^\6oSm ͛WRN-ƍ(PM&/_VKUXG)rw_'l޼TZUG^׬Y33] V|`a@T@UTf$\xZLjV/o~騳] DŽֶm1*Mk,'Gn5;wTw4iիbe\*HA׮]ŋ+Ņ@۷Zz4~X0чDOǪW_^WB:UTv_qģ\rw^uBٞ={dǎRZ5uA| &fRoykA,Ȋ+<#aÊ@daDo {3*i?`oH5CzX)@~,xɖgU A ! :& /a_XSi< K:w{?MxD{(5Xvܠo< `wLZOu-'_|jʡ@q=z*)MFB6԰ ?E6V9<쳦nY!Hw@Xӭ[[pL2U`a-_]X?ޝ]}NV^$(! f iסsx @ $дeW|`</"LD`'Qf  @#ڱU\*ܼyS/},_\ ygB0K.]2f @\$a Ȗ-[tR7ԏLYxԮ][rȡ=zȍ7ri&UʕKΟ?/W^vIΜ9^zra&M2~4iGe„ W_{,%f͒ի9… ={TREϩL2ÇM,\Pʖ-+ٲe%K̙32&HHHHH DXz͂9.+Y|Q8P "N̙3G:~Ǐ/cƌ[JTrYvօ+Ux$I$Ҿ}{Y>ݸqc9zm۶M}Z.y+Wlɐ!Z.VZ\R0'{ԩSeҥRhQm1cF4h;ҫW/APXԩ(I @L!) N֝Qb #^{ݻeт['ɈcɓZsMlC[jŸ{ZOMu%͛7rx(]+KFRn]_D!    'i Nԩ ?8I/_lo߾-mڴx߾}%eʔo>y7T1& yW 9rx8swGP;B \ʕ+q!{Ǐkٞ={dǎRZ5I(Ƴ i;dHHHH@DXjܸqh"f`[LÒ#GJ5vofXMRJiӧpE`8{B Aum+W,2/ V݂+,8XB8,+C$@$@$@$@H ޥ\9+]i6$@$@$@$@$@1OfIuQf h؈HHHHH V//OHHHH jT@bɑ _׃!    XM H<9    /T@zp4$@$@$@$@$ P՗'G$@$@$@$@E ]HHHHb5* HHHHHPѐ @&@qyw%3g;w8r$    ,T@"$!    0 @dd˖-/^+cwG@_yҥKKFT [ԯ__01$E3ݻwѣUh0aHtp邫HBʐ J\"j=x*HSK]+ ?,yѱCQ<v1\=FAB;~ƌ%k֬Zŋ6VD 9`pU @DEGHjTB`q:uj7“˗˶mJL~ A܉;}iF}Jʔ)e߾}o"\ O[ 3HtӚF5wUp?3ɓ \`r#`\P4AIA駟VXZ`|b%    _ 0JH54&Lk֬*UHNdʔ)={vYI IDAT@Zv~Gk׮bAE kq  A%KL(DFp1!P`` $P`)UED @dx$ٽFRP:n޼Hxܳg|}| FVL4h #FPפQfϞm/$(X~̘1.ʃ`4iR@] 7AFee܍r>a@L?,X ܦ`8>'!)~8eL /Z`^šaÆj2N%bȑ>}z 4h4n8Yh5k`լJ-ʴA|,;v Ƕpj駟a ܶ`5H@%vC< \0;wb䴸8˘&    _Ļt¿>\rه*l`5*(6V:q(CЧ$"%   E`'Qf[@uVnRp^~N3+ ة|DMÒ @,#A13c  DZ@""     0 @d WxHHHHH"Ƞ>HHHHH"@+LD$@$@$@$@$DEA$@$@$@$@$* ^ab%     @$2(   ]!:Ȍ P{`׮]9sfsN.I {֭[9{$s.Rjk'*;s&<ҀiҤϟc!1~(ʕ+ݿ_EevaUVR#r9S17nܐ}F3س'`=.P&L3&@&0N<&7ϐ!CdT }vy'CHN?^m&˖-˗/k&r咺ujBI}I>}d֬YdQL%;HR%C($֮ߪXUQy(M$pjJ Ow+<4/^< }iFcWb,ozP߹si()F$6nB ~#6qwٳG㚼)0Pb&ߺG-  (X"(w^.r}6lZ?'N&XniӦ9$oJ6Kɀ`y]($}kz.H|!@ 0тJj$QD & ɒ% h(Jl`e#X {a 9x`%5 Tȯ)\O#%o(ܟ [n՘L0!p@م{7X\+?*UVdC `C`<9V\BP4&ϧMfU>]y_^W~B:UT(s={{^rU\9A\޽{ e< 6&5jߗ:h'Us ,(oP|($ X8N-ϪXD` rd] %pWx>s>i=Zhʗ/Ze岔-D+G.k]5:*4.+X˟yu}0X}r8}c|9ϻwﺬU\֤ec, |.+>ε+zZ=5vYO֤خcM]V`zR]|r LbG\Yg7 oeaR  ˲@,,;Z _ |}+WZ埳?W]'% G@x]lҮC4e h&p[B$@hڲZ>P@#0YҨzv@, PBU@bH#֎ZW=EXu9y2$ փB$@_|\be     zlK$@$@$@$@$* >be     zlK$@$@$@$@$* >be     zlK$@$@$@$@$* >be   o\~Cu /: !T@bڵK2g,w܉% @p;w֭E1r?*'2̾_;|1b|6ڵKFZQ%_JzRRzVQqI$ PKZ${RHӧ\~F!DܹsrݺuRfM˗7'N֭[K\t2{l iҤϟ o2!w_&Ŋ_~Ez3K>N:m<)Km۶nݺ!CH:u4˴/X`WȒ%Ko!Ǐ:4,q|U@HPqAy뭷モyɾ}gϞ~02!"0s~hԭ[r֭2`۷|2}thW_}U$I"6lPc7߿/7v&n տX&L(ҥxɔ-Z$eʔQa5jٲ|Wr Uq?~r$O\Kg,X@2e$+޽+~m|8d\$sG1 * ^^ Jٲe%[lRdI9sիxΜ9^zra ŋKڵ%GR@ѣܸqîe t1)D_ng"TϓO> ?o5j 4H=&%J=* 6L`5SkS3gڵkfI&"Ə_vΜ9r!Rɱs5I4%vkj&|ٳG0D&&nO7!O< ֐ݻwI`2 %Lx… z_2qDSի-@)0,{# ѣG&H@~ ;pNZt<,'_oo1|*nǡh 7s޽@䅶wn)oA4iҢE m9,VժU R;x(O?ȏ ( <. .^p3փ!?zeMB&N-[e3fLX ̲SLWʕ]`;Ozzw.kﲞ{=c) E,eMz\ͅ>pZJ;w ~ RٱӼy es}5kVa&^nj'w5 ˪\P쾝 ޚ\_zm_eYBtߴ9r˲,ɮLzκQ6Ȕ[Q{Ef6m\V ]n)%?PC2}&kawH8}91sԩ.};Ӧss0i_| ӥn-Ee=gv;dLˎ;\V,?"|,kvUg{+^oe)U9[K9qY1LL\Uk59 H1.m eb36aܣkhL#Oɂ/^\x+%ߥKI>YX@Oa&cX~ߖ˗k~DdڴibM:=LpL}<&AzkXC *|ǏƚWwE#xq1HkCb#3p,0`$] %X`}fZxפCN?}5xua3m K2c0fz+a) l2m)XF`ξΞ=+*Z_A*Ydz;g?+vV 8JWZ4|\qHb8* ^\@>=SH2of&oV<^p1xxaJVX!5!Hq@|LR` b ֓Qu A3FKQÆ 5yfuZNݹN3QN0! | 4\0Of9x_ξio1籝ig?Y. C$Caa!aBPd PAZb]VHŖPd_4EH DB}۲Iw7ǧ=ZahodmѳVi\E0!)keAvsdE1QO#FfΧXyҩN}~\Յ~㳿w};e]^h:"kF6i2q5C!?GB]W62{.3U2{ed~s##yanPC2"]^ 6 Qʏ"񪅀23!@ 7Y+ ZS^,r׈PžXi#TM@vD:R~7 ##X߉u *̢|bWшaAڧ̔5ҁG}d &>aŹ"p˹4|rw1Hyj֬²n8]td,<~⍑[Q]Z72 kȿtTEq.|97jc픅6(NQ;({#kڵI˶ҙoj`̳]Tjk+(**233"X]VFBtQ7^q8" =ܣ.e(gFdӓUzsΆtY\<:h{Q¢s_F\ P2@1QC)SP޶C)HQ8pSGRhK'CvLђeF%{1%˹ `˫3FfMFeZqY]~rt﬍ɷSv$=#VAUԩWY/%QY3%j9$Pڞ|]-m]62>lҶ퍔CoD@>Ȭj! Z {## ٪]4=tu·[r%^d - d%'Yf5=ؓEbH@Ns^dmqgHWdT YGDOf kZ W\\\>u5 2!Fc퇿#~(>4xyFfs5 fI0!#2C!ɳ-aHTq#A> `Ȍɸq:ۜJZo5!NWƮWf@~P6 L@vAQ نZS--K<'*;0G@/cFA04A?`:D @ "]##na@@@7*X6 춁ҁ_@ VD   %րjF!A@@@@hR4AHf@@@@ E ( jF!A@@@@hR4AHf@@@@ E ( jF!A@@@@hR4AHf@@@@ E ( jF!A@@@@hR4AHf@@@@ E ( jF!A@@@@hR4AHf@@@@ E ( jF!A@@@@hR4p / IDATAHf@@@@ E ( jF!A@@@@h&|oo#,@ #P򥋿2     D*Xɂ@I$$:     DH!G     P @)2@!jB3(r)v3(UJ󟉟{N&ɼC丝TIPti*S F֮9k'0]9 q/p$IgNÇ+W`?!R lՊ6n:Ju-v ;wn\Osnvuhh(թ[կO8ƣ qWw!vm!@Q% SRR޽Qf<TT[%S?۷SPp5l؈J˼sϧ]V&XQz"=zTFUT٤;ckXL[Xzt0% ܂]vup~ӷ/5a=<% eh_SZ|Pdpg왟鮻:RᔓjoYY2?k֪MKcG wX~mkĖ@@*֓O#jE7hHW],*ocYq VՇx rj]Z55$+Fȸgo7=|8 {"M ;2$u 묬L+! GW]r.k|C\35ab^!87(~W` : ^Qy.HHR$0K@T'>awTػ(*oǼt=-z/*95zōz7!C?c  P _iƍ *{ /PTT_s@ݺuS ˕+״8:;eճOt>{eJ*S)w@[%WRSib~hJTv-jչ\+r۷noS[W\^?A߯Z>dm@@d憐?|/_իWӟgںuk,6)kd=_Aܴ2ZZPgh*e9Uƍ뚕 9;Fs}UoX}Y<ɣ^'6\v}:w,E01Z\WF5?ŅQ9OLL *ХK襗^cEye@5. BM>K;vTz4hЀ:t@*-[Lu^㹳L6lPnrٳg{GDqhwʶtzyx*~q^:M0]fu1+VTiH:_ד{m@F ϒs>/]K ڻ;n@nsJ+yZVΦ\-%7A'm+ԏ?Y"A2?m\O۾J'l lq97o*/,qFҬY:cM6j6￷6z-ZDM6];w.㰨UxW}\ܻ3 @@ \Ep4!g7荨i_0Q͞=oM[~~ߪ /ʹs̡-ZЩSH+kСCĉOLz]hO+'eaݾuzG99;-߼NwwMF1rʳ0xV~)_e )uۻ[m6ٮ6Y!Â] Í4w 3ޮғdw]v| ze㩧7xFfQDUT3‹?g-pRjy(0?V`ƼԥKoRll+g!M7n5j]!fVD1r^Ol}znmA$ȝUF}jթKjNcps_^FXhԨ19|HweFNn#3*7YKJ"r)B|ZWW\~}9+Vd銉H::&t-*_Md!..ʖ-K[lӧÇJwe˖ԵkWA!7|p5b&&p\@C-!  VtuBtkv7j KJTWlZb҈#yD$3Z/k3d[&ˣiICt=ͲfF33﨎ԽA&iۅ[O3Y:ER~}yXrWt묅avbwLz}>u7Q׫Wdo~39}U{pξ99hMj/cj_Z#᳭ukmq´R6;D~ߟygiիWY*[[:BM׼ysչ]d-GFF*%5#bnB]4l^à$__EjҠ:ɮcg)ߐȮ\IUB?F'`؄e{y*"7>`/">3o[GdFITB}w| +ws`ng/h G/=vHIIzE<2>S om F/"<(xk9$o7۷=MQd^ݯ֬YcMCߑiDg#>2o~JJJbyMH=5`;ljqHoذze,3{RFݮŔRj-22/W}G۴u;FF~9s46^㗕v K~ڶkf*Z!D/u/BobStx o| ϞVw\ܛ0h_.#9ǣO>]֭2m0緰!v }7 x?zِwꫯԂ'x.\@r&;{NS[Λ /S6%IT8Y{̙3,KΝtdΘ4c˔:LwWޙʳWXٰvM(zEWInI'xovR Ԕi1Zx^t5!锋{kd{g9ıV:Ԫu[%ĥ^V; Bɧ~4"Zz 1PƳxx]O6^KW߷k\{)b3~g7k΂boߞ>d5>3gs5B)fӆ̇O(`rĊɧ~ks.,Lr?6UpG:5N{~xD#/~Nlo XbdDrC-nn*r%kPNţONb=ƕ'@ʗ !yr$>b-.>*1deBRX5 s1NHmR[] X;⎥; q_!A=|H`  P v6OIx:W!1G ((J-v:<2_0iiԡ73-˜# @2<"kvr5!F$]ۻ qW  PdgeSy&tݩҬv\ +W^|*lHH)[z+p# !ߙ1`mc?71G3~CbD     >'`I!BNHIo(?  I@I'@@@@ sp!מ@@@@@ j֣ry V|8ʷ7v5jiV8*C5VSje9x7դ @@@ @&|`>lӞ}RRBB[*UDtaB<wՑ&Ν?l(!$44F5|B|{qe?t'o@ܡ    P@DW_P_uLÇ}A?\tD푇|#=tܙ&Md4wԷo_QRJٸGQuiİnzt>R hڐvIjhԈeBH0~YVDOş,2TǪV=3$Fo&}'Կ5$|E(׿e+'Tu2vXz RV-.Smgu, I2ޤISvvUv%;^mbuUcCLR jִ9ݺukSǔcRש]5^XG{%Ys ٳGuZիj_\B?͛7pwt0`K +܋i$!Xe d qʾ&ɓ'TߧO_Zf eBd3!ZϖjXiӦQrr2^Əl"(;9F ԡ׬'j@&@@@@VV&eee.Zԯ-_n*RVݰGiPhP%wu=qtN5ِQn@;w}M͚5W dfQ"XT4jԐ̤'L=4i4b1㏬S߯ցH8|ec֭,0T Y IDATݺ !Q:=eO^Ud6vڴDZliFSOSe)g@*VR~G&&?tҏ6oL&>F5jP€ja "hL /.5tgn"Y$>}K4jҳNS;u܅(w_7:W/u/; HAF:   %OZ̵J*A/"?}4TM\?KsuTDvwz F% X2SW/,X-]Z@>sLUZ4uTVzڶmGGSNY+ů(BGXݵx\]U~i8˯l|L8UN$*!DlܼI͈``LsY WoWY Iw}O .66>38WeμyolL-cbbf(5Ƭj)u<X@@@@JNFX&v [\Xݸr%U]w_w^RGm۬Is*Ҹǫ܈yhСT%wUCTzJhQGݼEf>W؇+Ϟ Ts#   E6i&eCGҊ˩gTO&xl+=;UioڳGwuY]xQ!'pøCRHbGv^RNI[n ;V@YjW55?Cal*gr]L>ϡyfxMi ժYQKǶJ*쌀uEQFMi׮oV*R6jd;Y:҈Ac;)-)e[J|rvxx8ݾ}ˠ.Y]Tg6$$Dm[-UKڔ=o-m}hBՑ̊:(^!/4` B_awn4>#+׌@@@<"e@8R @ 3(iDF +g ; qǤ7u$dxxMztO+Sa<#'Wk\|(ġn< PMO    */O R|D{a ]L@]w_mnjLR/]|o8    dQxvfS%?Ni׮-Y/]Uꬓ*,ԍw(}Q7@C|vlͻaC~Y*ljf8lP7n x!A@@@@$=n     %W(0 )@#U9     GHG     P@)qU@Rx28@J\     Px {     %W(0 )@#B     CѣG)*@I#V(/"BLI@8<%''ӹsʕ+TZ5S5lؐj׮m:?#7Kӧ)''ޙZnM]vg/aB~s-[O{?H>:˔߂t XbA&״0W@@@(8y$ݻWuzI'L JNݬq$|HXf﯄Gq9rđGAK҅ 9!!}]zꩧWr/v#!>e?٥ ²0$@M@@@|;vztN*WZ*_Gn̈́X#⛠ ҥ̲dff꽸}8΄dž hРATV-l+WҚ5k6&aÆѨQg!*wV¡6Bǖ[#͏Ab-38$*ZBf%M?QT|dnwVf}f˃ocmylyyͻB;ZЈM9'ŚΜtDHIIǏөSQFI]/kvv6]86mLGYI&ѢEp|medJ}'0-OSj!CTݿ3B[nq%&LÑ;e0uT#';PJS[QIZ=ZM\NWSVh̭7Dj&%:=%U%/4/rq~/͈G*c:-,8p͋}ȒaՔh cEA lG7 .\@1ڵ=۳{V([7Qmb:>u.dR 3&jxvr~&.g>@4 6aՌDtM\=S˥=2Yf WO\>@SyfLF/{\Q3~dIoۗo\? "|CN8qB #?o/_^ͤ=Nr޽Ru^eIRJ!7nT`xqZjKC@ c׏ha>$;q+JH<ܹ;ͲCXٟH}@ 1/6?)f:=T䏯d$}CsZe*]aoRll,m߹>E4پ]a7`Y\Uʸ4z.[J7u+7s'm|goТ;1̻f'WyS= UYax7Ps!:?ܾ-Iq0Td9HafFH\ߕkCKA g2hV4}}Q"ۄ>$DnuiYY0cE0Λ[',\2p#lJK}0yqhwلöd.ld}%Q X6f߆ &s(Za;#v!;wr& EJ||QYh,FşYf/#NO,p_ !"$ܼyYp&:|Z|%e/nrbSaL ҹ3W>;qsHٳg7- CO #$>|92dO.g8u@!{PZlM7#i'-HڵՎ<<2HإÇӇ)$~Jq)ٔFZ cgN%9w8\$mR^~a;r8խ[©VuI: pn?SЂsG&r:Um2*3(l%ΪMG.t :q9lNOjHmw9%MS箧ss9&ubet?2"γT^NںiԶpZ-jֱSizęl`f'k^lc _m)1/h3TZ?w5 a f|LM^H4-zc|w  oJ]{w0k?"޷kmjkrF`.2oӗP ++M;ᰎRiƩTj~/Brۻ JLufѴu\/j&)#i=Ikf[iٔayOՉ_'1աB4f2ъ_pb'ݳ@ ,XݢĝYO[Ui֦9.Zӝs<թQ v.\7P̐X1 kg#:5y2]}h-Փy|Д94a]njOZrfk=|3#i. ZWJMshʜ4o%ϢYH4|-ZeSĬ3v -FORх25?oNޢ؝l#xߖTy&A -Ѵ:Y C-g-Uf5ZL:hh#r2EpmYWѺ?XR̸t!MDŽA~jY$25%]F"b,*k .9F&d?h/OjL"gP6u 2>$sGv𐩘 ؖ9Pj#L {1[A-jR G^ӟ:GRTmꔣr5"'Zο;iwm2:uI1Ɍ;ha8Բ}*Evl7JǏzHO0E?MD>mӍD;V.QK~7w!WC_번2@bͨrcL>>zSBM=Zw/# ?.t T]}5ʂ)gHՖ/1BGҸ$GD$ ʕ' gȮ`EXGwԉ`r[a> ZLY\fzB_Z"ș7-U93ԮLH഍b.폊=iwַϭ^ʩϒqƌoi<#FX.o_Ս΢f,3w "go"'mBKP,Z/F{6g uiTMk}CTFSzjDXxg~E2oH8u{Z&cӤas[: y7騽9hߖ:Ёwn+v;SUUnAXu8ڵyFwh縕D0 ژa;kngNK7&bo7/ kթMgyO'8ȟ=ld<ӱsNQsi ʳ؋ĈʕL$rvԾ}{f.%xGU8rGl}ڽfa{)A@֎;wNX&vF.ulָU T'7oZF Rۈ\B^CۈW_d|wiЬ!Q^L`MEa=/MfLb%4ץbk2lџH{kyM[q&͘C@nJɫԛ;YZ%REbhc:zfEL@68oۯ:{y"+++뿦CxctO#nB»ҫG8z fi{IDAT飦sz[k&!T-e(c Jrti]Dx^XۺWqK.ԽKYu-z0|`''k\.y]`e_hUj~D~20 PKW6ž]w.gqZ,M:Yd9rf鰎8)hXzt\W﷫Ze`z&⿓B4GE7h0~MuyY%msЯ%4Nh9|?ZvCƠrpGm.(־2ϢGGP%:<܈u;rY%HC\oquMӦIyJq3>xTmx ר7TޑQ۳Kj# ea:(_ NBկ~:dBewrƈڋy~n@Kf/Pke,8ﴍo.BEq8rJNK4.S"s0_Z1mmKLU#;K{7r{R^>h:& vK͓̓AS~lڒeTʗ!Y'd1\}U7=0.ۑkY~L9AVfMMNT٭Ik ΃mWV''l#)O"\ GW֟O,Wy{O!#x{*ʋ8ͬplewY"?ن/Qjݺ9\nNܤ#uߋ ‡7F4DL }>݋LحKSf=&h1w~{uo柴%a(qhW9^r? OSܙO j؛,]DY5[s2,"i{m \Su4OkL!i(0XgA9;h6z\_f^ 6ʺNtzN=?wOr{/bndcqB߲Ѱn -Qi;caiQJM1c/<|YŲi†etjAqFpnXw A37,QFZ{oZZ{< cpOoҨkhtwskŬнw(Xi4jsx gҋԓ?Q^ ~M)f3ԎRե/u5lG&# iԞWzh =my)W~vwg} 1IblYZ\N8pzvܤ.\ֲSFy.wڞ>uJW|Xpb6);bzcws^犴nӆ*U4owz叫}̇tn5!eXzj;f )S "~YK2@eqgĈᕝ.yf>d&HÔiB7Ыd<Σoxl2x* cُt]"ԅ?4 Jx(JvF?ɡ'g9>}Ml~s9.P# vČ9q8ҐTt7#Y,G|d#--B+O<_.^qjUg2ɠԔk ˅T!h\w. vDԟz߮\QV6o}o,e Ƕh>9pE<Ě_è\ ZZ2>jHp6o֬^ SX# LcGg3!M ?o(|SO)@wS6ۧ؇^5W;v΄"!oɌ)>d!Y,'fNϋ?OÛg!hXf-ZkO>IaaaU4u,]HV9jMd 2c5>?zȔF(#Ck3!FQEuƾS(苊+/RԎ?tX!B(.Bs1Yv oЙ׌vkyGΟOWJcצ?9EɈ:YS27ڡIք ;!R@(\5#gGq:J_vR.)Fb(k($.-6!&jczS:563&m&~OJӸ}Αa/|޶\m*g@@@t  O8=͋'|!|H"`x~>"λ}ퟋz f@k     ~#+DH3`IENDB`pacemaker-master/doc/Clusters_from_Scratch/en-US/images/f-13.7-bootloader.png000066400000000000000000004237211217637305600272320ustar00rootroot00000000000000PNG  IHDR i1 iCCPICC ProfilexXgPMX`w9%眓sFrPQHV""HT  |﫺nW3==sByOtt8n{o& |~hw^ydOEƲ~ѱ`ƣagƃ8<}89Dc K}`(!`{6F:""j_1? =}|~QH\tO߇[DxliH?YiEyXڮc!ngX -Ͱ0{L _|l?v;4 ~8a4 *zX[>AD2AT4K= QLY@* 6!B$ qB($)Bd YA; AP<eAPTBU&tAF  /B !PG#,N/D"FD!{aK,b D$R)TG"m{Xd2YC!Y2 P2(-凊Ae*PMsjMBКhs:A/o/tO ÆǨa0PL*8sӋyǬaXNVk`˱wcX:vGq&Ha\)׃-6xQ&OƟ7Ot&L'hLBO"|'BD =1xXFB$1P$ <N2422L0|'Hb$=^IR3>iHee4ggڵڳ:::tfuu}tt ][ԗտ@ aa(hĘbl\a=HkcNlΫZGC 96['?Q|~iqN((;s2)S5ȂB¦"rQJiy?J *=C8f̪\|"eA*ܪjg>ruimGX]i=>~a \/l7F6694=hVknni9Պhop%K]m2m._W|}u嵾E۫nPou@]]nZqKVmەwX!dMݻ|/|n_<0o?ڃ4n>R9:X'*Ontw,+!vw'VNn` )Ei2%R3\e r%sZv_PXDy M -J*.i3l~5!7";b:cbntG |ǧU=> %Ň ?|"8my9 Wү&hMONθ72 7Kbb>Y&~Ҽ v|8ٲm? r qtEQ ht3F3݇N $hf-2*JZ{ZktJtO08aX`tƸʤٴŲf5gpӠ+uWپYo!o BVPdpUpF8-5XTGb,ρD$䒔}ά<ܙ5rSű/8~ĭN-"aP+v( ->S]v^HD\5~vtx.nnm^jt Uk%ڥnvwv޴v!NaOݾ{=Pwx3P8xihc ƺ}:kfZqm썹y ߖt?nYs j7u~15g@ ! (MQxF!QZ ]!b0o.8g#Db!y"S(6sY|bCyOMaN%3_BrUr+s? EO%)#T+l$ +*#L,^]-")E%!#$J@J'?pTLAiTX]_uAM=^CCQsUk|O]'=i}Aa1;63SsVyk\ulmv+o`\RZV^G~oyр `carVtvL]쭸 'RRoO?w0Pdfa,l#9zG5)K?!~RJ~]Q%JY)gЪʯ^VΥ>yz#oKܗn\A^uvxÿAͬ=^˾'=&?5;O}b9k1 @)\py S%Cv$xL@ _+@dC"HGd9r%:E3mq4bNK8<.ׇ kD^b.q!ɘ(XDecS˔`"5%;k2`gfoPtĕMny B5BZBEEzD}b-4@k('% d؛˦ʽTpVdVQ*TvRTyڢ1٢BS{BL]OoI1ɢٸ )E_6,vŎ.ܮnWNYhY◈O_YXH5ud{l@ː h!鎬AQD}4탾g{1Wx.[TBaEc`#n13v1i2Y0ّ% `вp(BC,D\P|V*+V򐔀Ԁt 9[rEK*e_ߪj!ښ̚Z={JuTuzmG Md9LP&V̿XYnYclm-<]nθ#JxX{yU{1 ಐa#Q)+qf ]IeLiYF?Wc'NvΟN*VwUU:\Xl( lbb׶k;:oR=ۓK7|?G O`610B« 7w?M;^޻ht/.+W}qwۺІݯg7_f#퓡eD\I@C9w0ژ{XK. Wt KǘdLb 7SҨ, p'^psvp>s7/[QBHWX]DETYLI\f(-)!&(ɑU+ijkQOD ^ÏT S_\V'Q6vfnNG\\Ϲ;1}n?o_0|ʫ'1E F)D7݈7Mx䑼(;$ٝe=v5bœO. <<Quxt-|E#wSmPk%Ͷ+.WG\va\?7x>(2T4xd l3/S_|4mlJmZt2+Ec ŧKe>}TlՕV_'=ڏkkQks?>\W]`Hݠ2wMͩ-խ[sǶ'ߵ\n\~.ͺz8ـJo?fRvQnbޥ|^ pHYs   IDATx ]E7~^$} .j@YqQgdt ~.ç7:fe#NTdW!J}#$;Nz_wgUVֽV{KJEO-JCb92@F #d2p PCCkѣ-aqZ\booGFF #d2@F #`"MMMF \ӓd2@F #dNt`B=^WڱcDzcl+#dtzC~aܹs@F #NnjQ<Cɖ-[z 3fq'&Lf Z>lJ ԩSog',Tjg??3WBps5׸$8ns#X8+Vwܡ1;we˖i4 8(6N9zSN4A]sͻKmr@4eojl@gzF #8XfuQ:o"1^criɘ1czL8`N-#df4 UnyGuӧ,,` l޼YgE8#QF h6WZ3˴iM&&NP;P{7oQh?>N Yem%?@fd2~%TDt5LRgΜ%K4x&K r"-ݻdIO(Gk)GVmIrɅ=ɩ@F #q2*pXzɇ} mmmK{[[[f`MD v-6k,wwɓ'RY@69pڴi*(X"P_'N}ڥ f,ˮ _$'MѣFi(?*+3utʶe,7Hh:G9Ms @awɽrm3JƎjv鐻?% VrY5TTJR)ʜɗ.?A9b{X9@F #__}ɶm䤓N>2W91_/pVK|9q?.z!g@֯_r(< bƋ u @aڵ:hMV:}xV[U&-IlnذA&MyOΚNcR@gzF #x* оG߾K.~2_=(w]Z&Oh1d f 1t+k&{.>Yb/w 6Lof+_FYc[:d2#ooڴI9]}s9`vB"7:,t2φ;!Apv,z1`trRSɖ mr`aϞ='}G|0 L!Ciyd'vHS+ҷn%].MuhƗa VJOp쾅?V;;;;q s%2{hu(CF # 3\m4g#w✭}h}t4M5$5BC#(,,_K|W>bB'n*~zCtF #x!+[lo5r؂cg6,:gP2@F``+^^;R>mMگ=l*vwIK/0ej,.|kYߐQSQ^}Ld2aG&[Q$pcol q s>Pν;=; ]&z6sPCY fsر*J > CTd2O1\s2ͣqoډ:4e筇uxk › !Mϯa֣l2Lȗ)Ie5,9µ\Cީgu`w s6|i,6 `} Kkǁ߃s:#<hK?UZ͕'0+Lֵѱq";wI 2א2^zL>d6#w,1sCF #`i.g ,M.c˖-jXӳggyq~,.㢟\۶~Vd2 *G~Vu }xm:m`>ޞCF #<p7 5uu77yɝq㵅2]-b^]3-#pd_3 j)g2@F`pj& u<~tsd2@F #?C.JMF3Tbszd~F #d2@F #04?1~d2@F #d2{kKY0#d2@F # @d2@F #d<>,@F #d2@F`%XGN/s_O7A}QYlcc6fʉ'7|f3Ø{.,3d2@F``}Fߜ M~{$7ϭu_HwF̊p;&.@v@~<Ox`+ghpg@F #3kNo{ vM>Z{{ U}3&)=utTCPF)um-֛.7X~`rʛ0a?OAF{κ1 "vz'>$T%n\rv<#md2@F #C7m^,ԑ֎2wޡҍA_; C ]|BƍEy(9y\`A]K[w=g'h0O4 rg{E֮*K=o#_ ɩG>t'M$۶o7?Rm>@+-W]т@ &Ph>XwuE/_G{08| ORK(CF #d2OOM nҷGF6 IiEy)ЉKeH{{qqc\ =,{( :8Rʵrh=LI=Ҙ^Zm/s0JL0/X@^L1"֜%"8MZe9٧@F #dt<**hXx46i_LӁ(Œm,*J*y7k ;x>2x:˦n[>w6ˣҕ}#W^K:\@ 37v84aG4R)@6xٍi{?.(-O mGtc.%y_m۷U8Ƹč1% ͕ KF #d2&ɮsiIz: oE`:D?3!}wI9ga2a℺ z^n[ eV-{ڔ}I,8U>ݟ4c6waaǍ].ir-[ BFРw0Na`|B|=#lO^+޼0w6r$ވ6g.-֌O4Yxt!qgG`$2O<9uϦo9ӵ2@F #x#˼/ )A뵇bک9iVKJGG'_uDxn ;e⎮<yIX%}h9jWwkh_|}"fQ*2sJY>f 6`WN;oxp?Laʨ߲}|up"ߋn4-A֑obcg9% ,&My6ɆeQ{ڤytz&ڷ^z'Ikى;vi8pG0)g@71R+>cz,Ȭ\ [._L02뮓 /p9ĝ;ȎZ96wG͗-1QZ5#BGdҷ˶ PeG)Hb2\Zř%Ė-[bɁ[N1">G+{d2p#U0a߉g?*xIڥҗ#M3\āH#^NGkc[g~8i3]].͓6af@qȰ˰ET[ ۮR+h#rXڮq@\pn@|bxWeg86^QnRY+=rͿN&b)ViixO5CGOl/3φ6>c֟3 cz27!<RR笛d2XRž(L6aT閦N @U)>^+olZ~BޏN#Xo?1e04'RF6;;˫jXOBnLQБ#g?Xy~.b#buCi^ocҴ oTL`ҊNuc#.<< :){ bj~V|?;D<8 9s㉂XXB )eZl CZ@F #<G {"@hi fG;WyQ译U:r+~\#[^Xr6oޕ掝?bҔC ?8t[k~ъri)Ϗub;pq 7ȫ_;OoX|FǤo)/ XbM;p`&6@D0"˻K_^pT%2a1apcmm|6I1AVie۰x"`'@ڕrd2ģ·Ai@TLWp#vLO@ y>|q]oⴑ"?OyCǒ|C=6twd -\8Tc(ti6Gb`|~ks8H%ArԑRei(fz)k0,2m+əCo"ݸ/}PlF t4$ q4 s`@挈'ΞCF #d2O?Ы >}O$Zwߪc?˯x1ʱ);'+4Wȧ,vwZSd庲LY ^Evu4AWϟ7·!7=$wf@Xaf?n<ģ# s \x025 c<82k,Y%WzH&<2ai!jG|#uWEuqPq34Xvc>%WB_^àЧPnR]%~$$IN#s8Hx^G'6fϔUJkf@pYv<;ct_z9|VIƀ{;\LEN?`% ;-QôUz0Y;p3l}skեX|(z @ IDAT o,}l#=X4Z0C"yQ y}Bl绻9`ˮynu~]d2@F``|ޱeĻH5 ]  }=X-DWO?eY,waL>+o>d6}(߻Me0:z(^j~eʔ)qըQ'@o(@{"=4Ap޼y#Vi ҙg)~g;8S͙"fy{dTa:J'=FWCukN+4:2{lޔ:~$E:uB#OPv8{©.x&@o6[SN9E^vYsоwF2|  )/:L?6|;Хl3gΌ3 Hp39Yc Q^(Nb{2BwO~l8kcn1=b'z姏ڍhx#2ȐnlܸQ;|qcQ9{lC17xכN4u07e@&N?t}0oZPukʾY4Xhd%yiJ`im۶I #ѣF7qՍ;B5?GY.}Ny:/Ǐu쮻իW\gjI5CfζnwRlYpst?k#|*b_9)Mi(t?x9d3@F #g ؇Ӷ\Ě鬒 0v8RrY L{w.4צwɫ}j&N/qsC9@,_8lGa!khm#&ϒygǻ6}@կ"> fLG ē/@F #d2Crc3r~Ǚͦ:U'ry axƬD9bǎrm ݱ#jLr@F #d) \gF #d2@F # d2@F #<اwlq}>Nr.zi-Z4(wl7sYĺ _;./$au@F #dF'V/^Y>Y>@_ }&C/Xbg@:ˢo|Unh8= tˮF[{˿,KT|T3˾ϑ6"W~Q>s?7M˒Eߒ#·>kDH>B'ʕo@?{ݷ˷:EՉC?d2@F #Gw|ŗAfc]rnC_{?|SɅ f`k| {\_D>rzo%VV(4N{Juf Wr6}w@{nɎj ws&ܵ[ayxgi-oM,]no\ʨ2^%dmhzz>_$_ޱZ~t\?"ӛ%mҰ61_E_mê 9/+|y:R?5|Ku7dϗ[e~L}T}[N:_oA۲oIYXZ;I_gsY'#d2MRiǰA ߳*xh`W} M͏_- >as or\rD|>4⭨=9\9MićDk[|\nVI/|t ]MZ/VڰI6n);mQxիHEX5lLco.\( ^m"ޢ嚯}ևIETم߼U"_|,v+H: *_چ/4OfOWz\|]-ҋtgw'?{rL6#bY;fv& wrX*x{UC Yq;^ujum[,w ]]n-\=Yb ߓ_(6\͆5vh[Xmo_~ ؋>a{]"[*m2} z/Qtr4~_4ɕrїʽ(_q./wʯb.ȴˍ -_ɻƻkK+7#>፺$n!#d2"yoBfVƞ^Y?kX(X.[xMg% <*Sik/R FV^P.0`藢$Xoh>]{O/R30޵L|B_x7oByۍW_(_6p?ptnsT4S_.goIo+HQ.|_6ݲ :i\sgP~qa9/>%G_TdoXt՗=R~xϺB!].-?xHϝ.}\/kPPu/X `}Ee鯓*/k~ FrTv|{E2__.6[+oWO7ROȢW42]*5C.O]Wˆ.\n%_B:xo|r$o~(?Qk=+cղiw*r+CC_3N{\!|Hߑ_x.y⾟/V#}軮S5 eK̎w/gߖ6]/]ܵn,(_tMWM7|U8 HOe\[ϟ(szW9x*˔fz_ܾRzˆ%.z7AZ9Y^(ʍ(wR6-ȿ[m)5&̙l|^9%'HKni>W='dy_ͿOJǎخZx^!s2X#Q/[1(7j9zܳ;r5&]H^4J*fb4Na~n;+ɱhwL{~-O}.JsքgT޾j4=-{'Y+ln|qHKSWmzϮ["$-ʥ?\"(|N<#c"=V&rwEƎ$'y2 a}K VE.[/r*t99SһYx_uT#O?GA(!9ߍmHAVgm@F #CQ]eʱϓ"ٴ˟W=}sj}կc0xc7lw%u9Klkm7zDF7B@Z uس+/{w?xpxf@^t+׼]-9'Js9D cڀC]>ipe ÉL c,dF^pdenu~3@F #x gu5eb>QZ+vY`dF;MfZ"nѯ[mAk&yݛ&=д(M~ԁ =ɷN/7M!qn>]Ί;;kEy׼},2؀*s/Fk{Bn?ʍA;o]=پK:{qy9~yd#^c +e"Tm7ʄg?x:Шl wwGQS&ȑg$+&cϔӦɘfo C%>g̔_!0d%@).н{k>_yC!X-G\~;}E/У9(zdCdڴ)СBtܾ]ϘDK37Q*ji~k&' (=J: seV4omYLwȭA.y䎕2sh)7)k?2r<1MtpLX(0[K?2x{uI}&Yf\+q q7-v~܁d2@FIB=ʕj=dѻk J.h}pr8$zKe٫'7&}=;HpF,IxptU>dRLnG,]xNynZkiX9sE\$ʽ.joN;NN:9qRi=V_urqv t0 70vZ$_n=,#2K./_g*'Oŀ@o2#7}N>-@o[LRab \ڰj[A7bxgk&uzW˳g4Pr!e2r? )zvє,`k~@$F9cE rͽsO;_ |K_YLNdǿ$ג3v|:Z?^۾S*2f(bO<}عxbO ʥ7 ;ƌ+z|Da[__un=Oz|KSYvlw_cAuȣ-x^}ʨxoj@S#ٻس-^i8Q1r߃ɘQ2$}ha;cǷHniĒ7ŧ|DxN`^14˨^{3WƷT䡫Z^o\FC+ 2@bnR@F #(MmcdLCt`IBJK~^ꮴx:wD_j_KDj}Wx|E3|n >],i= 7-{Џ>Mҕ68=xtR޳mC۱@dVtrGg&EoۍnlѾkl6 =;a!-[x]MXsd@$-uz |"E'M v͌ZzِŃ@0·RNFniMܸn'|b<m} x}ڽM%Iw}~C:"T_L%`Zlv)/FŪ6AH |#O!*$dd.d%4T缴Z)k̒,b*^-b#\/†*YcQ)P+|XPhᨃ)@idex"|W-ITBu&/kT,!|n[~DQ*Kʫk>AikMh,ƅԆo^|\(Cb|UHXAW3XCL]>0:.A5ne 2?Z@UH X5Dz슊u ?0Ynjc$:f+K}%ߖxM|oy$QΏ4*h7fkB@?PA!S c w&IwAx7CEM(D\8Gyix/R8)Pu Ffa(TǠ(q&YYNw6Zl@^Y;"͊RITiǒ:B:ndV1uT2Q?1hqSƌ" 'zޖI6wlU|*ڱm)Q(Z4m4~Z3 8ިbfF5T o_f[Q ]jT+Lx$%ZM B?aF#biڠ< IWQ]嬘s3A.3&dŤث#Hu{:羃Hܝ SU& ZYKUIz,bA< Kƭ]F! H7m9l=$xW~EYP܎hZ8~ЋkT$WpI*jtoQ?r A4b֭UkKrum t٘O@$_NJt dK!Qe@FUDQ~Ruu У7hTilK! <:YLPH02Jٔ4SdDbV"ZT6mDD]!+JF̘,IG6m6Y)Hi{%Ap2(4R+@]"i`[i>" DU;T]|u.-O"2SuB=NBʹC%9vG3@KiνI^QGA*JpA؅&t/mwdžJ݄ 3N:eaK'y z TiC6hL h<˹^2JWE&Bm$zz%LBG)siYI:3z xJQb,7q]!C Z\~UCCg@ȏ]EPѢLSz.Pm_7ٙ jN7j)r]ANY]Y\>mQX)GT :!R5FgY73)D5IbY!qD1UQm3,qU2HM!JB t>MH\:5 Z 6J2)Z54s&<&zl&x `ƃ]9aPa5A6gTEj~+.QRJSY3tyR!MMD UX`;֪I6ft -gm%,rj.$3S:Ɠt0x olPZ/K'P"(B:%U#ÙVKRU@"H|fJ.!$aA.7M\aϜR@!:^?1rgfd.#0y-rC3҃L^+ P[ 5T!`64Ta $b]?fbQr0t5"_LYk(e)BVh$ ڜ6tds/\1M*im1&=r̾k-ҺS4 9OYehA8!E$jBRAu} v&TO7Q?v)vnHMg܏ =_)tYu't;{t*i0* }K<StNM>D[S6i ["Mr)j"ŏ8Kڋ2Ev"b'HV1uG P29ľUWh"IPe>u6Y i'<G*_Lَu^2{<Ӷ+C*Ѹ".u?>Sҭ7sUT{2 s 'kZˢ %9PP%PFhmk9=6=֍IūNLMOLW ZF)D"fH0Fʥ ni>a$H0[M3H0]'SdmP{̳ܸy`e>FT2E̤QHL/*c"ëS7=QN1;uTD9"@ipY}nj; hv1Rs)Ɣë4T6+sT$g)#0L۩$v4L;Jiw>whQEnT fA&zE2-SZ!EueU \g`yZ@2oWb3 6B$mDnNˏ;Dw2BkcBbVQaL (f T=+Uu"f#LJT, 3;&E:"QG+1\LPyup 6'VFPjRb̈́MCY*Դ,5]%`Cs9("5MuhG;Gw(׀zs th4isDp濄65<2 }Êʁb ,VVn6P0׎T1!*m>l7Z2+MrS7p~h4hՃymcEMYmHbE0fPOIm2Q4`ЙTc ?jɲ͞<Kr}*Q̫BP+qgq/_1ۡvHJ1mltt :R( r9خ !J ҧNIP,$Mt}'x8uFT@!c'P- 2S5惛f!TdYi!L\tӌJeص@.}}/T&%A11C&Zb< J僘E`$2..P n<-NnT! LՉ YۚRQ^ZtIHΠzE DŽSڪ|%)f Q-&+tʫs 1pL V{(j lXrfAFrJd,h !0+y*YMS OUޡ|6]iD/SyGRTc.:BJǔaZ1SLX!C^mHi_s%3YI$zB$]U7j/t]RB=ِK \y;gOw -pvJjQ^d&BAႈc-_OC;Tt,왕͝)UUHBW :1t504 /҂BCBwaDqU |'&0 VqzqI# [m5UM$4+زNd1 'аAIt@Aܵ<EmJv~E1/CʨrdyPʑb>h nȱDȘ $O)o "* ( "f.:q 81SI~F9Sui竬T"O!^0 Kh6^!kۇ%!W,`݃D؝vzNjUU:3c<ֽZƋbi Ro~]QkHs@/Jw(_j߂=tr&9 ߯45ψ_) ` yD '@A-A=} pTcJ' ABg@ۗ [ =hN\'@\9Bt&S(Ҫ2$ P #u:*m[XaԎ!8nL&\c` (fCp5f&!v`, tX֜6gU?vQ). t@U|ǫ*}h=ƱL Xp6Yy.f=~?Z0&%\ڳ#O U$S;^˫ x%$n29y,)m\\9I%o Ɉ]IOA[RR.mPiCDJIAPb~,=RۮF4RJgݥ d&$seSX =_$[̀VE P $Vq=V-PkSEJĉAa\7?P3񪂯g'r;tV * v+<X+Tyr7.g@K@rQtC%]Lc˘ ;A=% 3Ap^hœf˶VoyzC] 4S[<ۯwbf3L;_K¨u ';M& 3S"E(^Wz}Ge%'- IDAT+u6B #q\a-jhq4Hlr#{I~U"P0.y++`BC۵2lʥLcCxʮv|Kp=8&x.c@+<LF2~6JQ,IpUŠf{i>Qȭ :| Q,t5Ȩ?-TFrjBp#5y<]c)4ruq1$1c3c΃D<IOtA7?D:*&/p3fQˡY;lf t EiFn֘^ 2&j8uZ ES.7s) XR9&fDbV- \Q yT 6$EE?M9 = -#F]@`* sL;Rp0s'Q>CuPA 1#' vJV€w| ji&eY4C)E)Jw&bWMHlD! 'rVRBdzćX;S:f= ciݭr*#P`ݍ- 0fܘklW[i׋[޾i|cf3C":bbŶ1PVƤ"8IJTJ.*O0 ʒh6 :8KzW(lB̈́r!Ì`-EIBM&c>LbTp^S i~dPXR5w}M)lu<(6&jLj(lQKoLR0 m*Vs_o17|0UJJUbO 5#< FJŽ}f I XRDP{*iNl _NwqƵΧҾkܬƩ3\!Ҙ7uUPq:n9#dlXKI>H*SE^%>z2LG:6i:̘]m ⒡E%c͆X c) Q vMϺkwYk>:vi Hi#2B@wlh;$ `4@tM A)mSӯYfZ]8:?8y[6130ض\/ʮaI/ᒟq9xO"B>]q,dvG}t_s,URgܱ*dq9H)aG4~ZXtacm!' G!D断qOPvb~47>3bvCl6ң^Ğ/!8g=.գC<>KN~kvJӿsνvqX { ^f?T?po}Sp+zw*㮪 ɹdCJX^,ZkAUq%!ob3@Rͭt_|&QTH }e8vq\k N90&Пn L|AsIkI.nW4hΕ` Y38W3⮫P'k^MZrq54KӪylp| ]>ό+气r"NmIq)el@0`:u#Q\Hwq(s<&/;O_^P`D'3q&[ =uda T)"R<`Ƒ8v"$jVt ctp9MLTsaciLl4EHPCId|Պ*\b0Wlޕ™yj#.H=ޔC{KcWύVka+ÛĉpRs`0%~)p;up}b|{ ޴!8Ľԥ7bbC%Aڳ@S1Hj6Bl/ac [c[8 0W ˸hQv8 nPiP~(mY6'[Dz$6WLRL@%*+ꀱ eC#Y($' 4FMRCߝx!;k͆۾Ofj)zbu* (RYN/1 pu$;mÁ?r7pyegJqeI S>`Xm8:!^:~pMWu3b[`c*WĄʛg>5hD_\AX5Uw,%NKp\>0gL7~1>\0;uxR@ɺ趍@b: U#}kЏ^YǝC&/dr~^'K͎^wBWnL j؆J`"ZެG+B8ĕȶ] y(@q3M-56֝ @ɞl8ǽTS2&2s#^x]\T p}!ξ)X:191ӎqQq-D~7Zr&l4n U,l0 ?V{=I{ } цpI5 iZ|ű+~x8]KAQ%«s^\Qk'%g=Js tT;վ^Et>iG)@01DŽX+ڀy͇_͐sWYץυƋhCEޠ WE]xZV[]|E.^Oo 8̗Y垫e%Uן~M}O^|WtC'@4y,g=3D XسybԧzNTEF~%j^t ɋ(Xǹjb&d2CGgؼ{ݣ ʤEs;1#C6| 7KҩvxJ)A_ уαsqk[J&pԐl筽ga;DGՐ} vlh?옮Wv${up):gO*9:78d_V!r<=%HoY&PGkwGY1uBO{g8WcG\9*o̭hP۶qk+WÙw!]1&O3GBnL 29ƒɛ%7GVLZ"0u6*~4n%Ad hMu%d ށ'zn p{3Gd2{B{e0rsY|tHKJ-Ӏx,ewa!(h`^P(+{X ∕H,a9e3-\Ds-~v%sn 00x@-zmoJ\9=X5Soœ @Sl=&W7?$Waa8f9ӆQYm pET蜌G'rZc̸quI8~Y .40dsS8l0;,tڠg;³&B:汙x_3&&k $v);cp8cTl)TWA`CSɆE 8W`<}A/>&7|և Cl))hWKS{l v߸{T + `:і|nZ f^F٘jk\'FqΐhI#1mM '!Ǜ#=Oym―{ !Orqa Q^tv$1!F:;gdRei-.f9eI6! 3䕤e9%cVr[89;UښH }[}O9A"_HAɼ]`rrvWm6tA=O@EB-t1J sR|-uf%D.tµ[}60o IP0#swnT 55W5l!녈`ãW;[9P&zH.5;·KS/ĻMKs `Csj!JxYO]靚qć^dh@ dޢܓ׵dom+ςIXr1!#MlX ,3'L0dZ'=xYmN臇b |2 X9 wāio5:;sp%:cvo&q^dEj .Gs|j'9g{SLVy&~70>k$H>2 %m] :S]3_X d!cZ&o ޳WX _*'vgCwDoߖ\IݪQ𳆌1_zex~/@L8il|1jb<7^x(. dV9%&9h#xË0/Jc+Ћn3!8a *uRsm!B u#Q8obagSwW͚c^'cg[ydv:}|c馷l^嶽4GZ/ZtR>WD;"U|JgnAEep4ls5vJpS;ڙq2KXd $ZU@k{=HۤPso2!6C}(;΁wl Z$'ގۀ=FBA c[%Nם:°-LAX?2 jZG9ДY&$?ئ p>y%k].k' 5xq,% v|^_3y*Tpzd*ӋRј6yK?>?l6Iψ.G_'ml];'>Cuavn.odZ1{||v?wİͺ024ol Ne toFW^6bYBjPӏ5\Yڽ#c8k@۸`۬& qy%d x:T8NID< DfSCdcXat]Țs"lN sA1\W"vO\K_9570inFJaŋ=ռ>?P~5owNFe'"]Q+T%zmG`%!'\muڈ9x̴P݆_Lvu=d,n\vkve{~o.xJbvv9K1yaQ  Mq,Si'r=5q0|W7hkę!c_C9HSE7YL'TOA.Q8L#nt:ܡqq v>j t;u 2[’T(ޖs3m.K<{*R mS!!!4(9 hj[).73jǜ?Hʕ l·7O v hHOnCKc} vLۣ+ۚk1Fe/7մښ?sS/>:WI\b\+.I<)(څZ`o$& uYWd/W7w:]TKHAjaß$PiE b֧a)#a0eÙdd*8qW4J܄ߨy{[7L"ne 07e};ء/u Ix30COה(Yt°gr$1't<~@3!O+=S\[2fG]F9AfauP^0aKgɄ`<Lfĕ|'[C8ںyVŖ;5N&?ˇ&gck3hGVeπ0{ & X}7cc睅˾byb$ݸtbi->[>ŬwNTh+,3 _xQ+f"> Yu|12UN$u P"};mfэ|$/ %k:qnl`=ȐW_Qr$^4Y0I^w䟅.eTf,eؽGxђPt'QK͸eBe0W4\#ރ M;,` .^ Hv5&xf1cB" +FXJ cH1s_<' IDATK&QLWܼfn ME+tbI̩[v_=\V-]AGK [}F;}OqoD߃ rW\}gy#6N64*b޳:@Y3!nZńY!?1֘>yȊmhSJq^VXG8|#y .R17^_o~{{{?p{˚vadOzs2OyȁSZ 3gSؠw;;evg鉠 Xֻc.4Vs5Bny#z&?71y!#2h`rhxud^s x$ o^ָǓzkM bM<"H^ٿA:unh%;0P6$O !J(Y4oܲc5{?;v ߔ y~k'mActi^LڪǹKyTZ-CiC}faЉޱ/%ar5Sl bA>/J1V?nYgt,ݟZF E7|*,u>P{ 6ϣRC46QҚlTM%Ѿ2vNv ۟+6?aS֧Qܦ4|H;5-پZHs<}\t)zjŇ0c9ˢ}# J'Vpf3<6CrXsI carWTF ff#0r ҃ގ+.2,<ϰgх_ڵ$V5.ٷ ~3`FՑ[G stݲ58:Ρi7_pCrg71&.vP[\<6сqYrLh:KikWQy z;Koe L~#Ĩ1*4x<^wBuٳstUˆfj͵wWGYo5D昊nH3!"ˮ$HP'y6l,\* 5Xj.\[!:Q2UG\}gjɆs?5iί֕0 T8'1;#Ys*2~3+!XlU֚\vtx(òbP0Of` f4]IƩqjy9R:R:%^FF8hqS]|C:6XmnjHqv mJ@8l]ih,Gcߎ^BۤeȮ,e+z%=uShGqa?uL2uGY:g柉9T )隴ngѠ2LaQzk3ܩK?ܾ_ʛ|/ß|SC=coZP0>3O u:Jx*`Rvt 5i+z'cYFp}wh}8x֬0^lS9raKCu b KS{{9&h.@G; {5|f BTs{9{3Ek 1L'N>Z{[iض 00Gy )3| \"m~Cgk 0rB [Wo&Dyf-l$169V#!%{f "wFRy<%n|al&8? M|UPn(x3uFkz<(J8ɕsɦ~ ANo,rٽ1ڳk5O،pܒFAM5pxO{Kyd3ul:l3x:O{Jbo&g|+_o=u9g6EExuɗ{C6^t\`9w}>QsyѸ~G_^m+"Iy/? ^[`80{H|[!CI'ڐ_WuGW.t?nw~÷/~/﷿WW^9C$XkN`ș-%UuL;  %>֐Wц hy “t]:a On;LȣZƹQ[LJ,GtnW?5ūATna,)xHˉH KI/%.~eHZ[S6Ǻ '1bX aq'=^2,.!RI.Mf0!c8SE`vO2fG޾9/mIel|ȚS|JEϧa!Ͽ[!t^#zmfXFqc7tu?5\rLs+qȵ7}g:6S 㜼38IBS9dO!́JаN#.b346 ҟ :|E3^(a%C|΋k5Y5Q8o꓏S?۟C#?KWo}wdЁ)G5g؜O%rZ^bwteRa_FԘlw26W'~YGbLÐAk\Dk8(33,]`UgH Kkd8AO kB*7Ch6Hb ?`|p,&Uϯs@m7M*.O6S1y᫉f8O'یI_'vv7O>}~T4|L!fyeȧ,yYRP-7ssD9oH?cJ3 ފ}"t{+6-*>VPyR1R'WMF$N$gs/puQ^\o?hjm%xqYGmfJȬ {.8=/ `gT/pvD 59rs.8+݄(s>S|0k.gM{Qq+$cS);[/r<ꏭ n}^x+_{Mgpz~&=1tDK.|*b| 1Qp f!G\ :w3"edD.~RMҸƖwܸGWUFŲEAw44o^9aϐ\Z jl{ ++)Z)Xɞ}X%Ajܢ k'Jh>w濻g>{{o|o|_|ʷy?z{)ԡc˝#`ٕޤs[=.cvliљb(/@R@0};Iw,/4FO~A#UI $h.wGe3s5"}as”(' *:`c U=ӿhg+,M/u9Ƿ"fiv^"ʻ\6ਸ/CGeRU9ָV0T*, +uEIp`;bq=9Ń($t HLX%O7Bbʎ5 ,~I8<ְ'8R}׾tү|1e%8?s{Ӌ'^O'Ft^rRs1U *hTj,1LjO@pNp5)&biUr}e1u:J[lg,øpK:/+ r>4́^K:h=E6Y#1Gj(r L'IY9q5w_P&"ٳC3d­zEO"~zS*i\/F (Dž\!Zmak uX=1f;un_ s;Qg,d؋'pABaK/'6)g6xQhh^>'=O'5rxZƼMtZm.@6F/q,FFX!lMsDn',W^>(FPs˅,3sZRa<EF쫠N ~!c6$}Pg]U,jӛQkSf0=ڡ9ř@9.YOp 9Ԋ>̖y¹&m ag]U(|dIZfX91wa=-=|$Yu lWձeىy Bh!+rKQ&# OvZg&.wMN'屩ޕ"e4+3F-W X3 rr;cUK9nMNya?㬥Wn<*}_\g Sag>{?uf_K!}xkrժޫ?׸eryXC. 5]Ϟ▰e@֣]zspEXEzdrͫ-K~mfI:R΁$~bL/< m%NMe1RBIFH: k"E ۳z9ʃwLzN#C +z[ؑ'-a+yq[PXSAzRb G27ȐY=H8i[.. `tn#qo|y}iu`χsZ1ų;}APLơ;"#ʜEi( <<6Ӳ\>'dGl'Sڣld 1r:GHSՀO uLw 9+ƹ&Jŵ1ҷexݍL{<σ[Y͆f=4*0yA<[Kfr{z6,w{I>ww~o|ۺ^~k_n} KnT-s;'QdSOOmið=XY`ݎPQZOڪMoS0n[r60I]rh|lbSƖ(?!,8p1yVj|h CSck$nJ=1prЖUzrO%˘Х]%8_R8/1gp#&Cg٫+]'x67gy|tw67v:Lqhf22ZͮgQ|ZَFl4r&N;{u&F"3+ybbؤ) 9/=q&^gYLKҸ-Zd|OBtSaXz=dTPSYـѝ`G R\U~ˎG^El@lٕrPQ˃V v56)/,a30s ka·l25dMBTh\wXvn%# e O1WHT^:I6ӵD~—y ?6.$6og{o(%y/!3>b i-|#c]b>πl1upZ⺀ DZvԙ`63# @=qq,`΅u&J@A"Q#6؋ڦ;JģQ;n8oA]w]h2I`r657^%pgC"GE7NdλZI׸Z5c`ّTq刷B1uO߼{>p{W_~ C?[C?_ODzḱ-yt&gן2 4SKPg@#$ړ:AUB~Q1Ǚ R퇊nLQG@bG3w]%͋bClLlwNe PM' ΣǡX)kxc^^>PA[N){P7r2)'k\$ =mS!0?z@X^ji"ւ<+n%ͧ<3Byރ8-fW[2C_ZyNdU .\>LFB0YvÊ2CƁf`ԤbM/B fF@(D2>9Aϗ+y+|Bi SK<#c,x1O-3@O? >iVwgy#xד2$wʈxZ׬ =ĄA^IFT6sかΧn5;Lb\|b'Mc3gT ldd"F']؝ʻWOz 2{nxh1YN`yM\+<A6:_Rzn zQǘA`o?>^ޙI4soWh+,q${55SaVt&5?Yx Ε F Ȳ:Jw67J`/rv>/'w2GYK_~r{AK_}Cs3FRHV[eQ}/y(Ӳ+YΩ5- ty߻_}5_qʗr)})6cq{Pe7CƨabS[Ÿ虭9\IoMaK~^o}#;=2G䗼V?3~|{w@[OGThU]OHK|r\L %$L DEaYҶ 똢0 M‹䯄Lf<X3h\= c/BYgxӭv׉Y0ZVClkrܛV+hj2Źj;`؟SE ;v򤀅_Ʋ*vsTStѾ$SdĄ.nWfa@vfd(Kl{τ2'ѩ9!WG cY]t|KHƠ5/5 WEB(` ~EQ%sH͝@ a["l{g6*뎰:an6b{V_ɢ0A_c'bkZ֝-?_F?x1 +s 7Z/==H'۟c?tr? ?g% DN3&5rV/N\믯؃ط3ُP׃[zN[>`/|_?{Q;ͷnWbOSϐ|C}}ut+2CAe _/Jɼ~ V.@]7\a#'cBcC 1|D8hyBⲞd=ú>ژx7KeX&%( fg[Z3^DSLN8LUP52"9(ڈmmsW +\ 0X4.PYgi9D4biϞ Wn<~Wp<٤D{U^^|^埽Yޏ~^K$ʷɝ,=^s)% O@ϮXj%Ee* G${H͌\ ~DǞ* Z'+̄J-$rat K=Q(m`nGM'&,|z˥Xޡ%CYWgX&1K' 3iE:C;Ps4E<60]9 ދ2/Ob9p DOşn>RY  ={u|ӌ?ᑨ\} REzxva xA()yR9I]g yp3t k OP%+wsH1y|[: +jrNxjݪџ8ZX5!麯Ak)dC ?<-8cQ!?' bt[pq]P"> ݘHm{oX{qTi@0.?*߱Q{X5k/B>aon8*NBw3*U޸$= g1#P_! ԊߡRȍc_7,uIPMu̻uS<Ϯ8 k"'Ïn_mfxO>|bSyA L~ccFvzL9-aaRP2Fkq>sml5B[|A޾[('!z|2~#yQwJ9^$2Cࡲg&VN/k530㙤V' <}~ }2u7\#;_x /KWf&R˸6hz}qmPYߩ/Z1,S?VI)Yt;v{a ч<)iΏ&szƬꁽ; \aPDlz(18׺+EɅ Po$}{^]gX#ۙ,xXޔ+B^~_Wh92q}DDZYQpV~z&xa{|m_pgGӻQ8?jxh:l-}rԿe!z {ut49oK)Z>o{;$9WG5A -slNOk)ܯbw#/KZ Hu>y_}4v_0zV/|5-CR5I>H^{G&E>tIEn;cLwF"G\2xfp ` oHmW05_ss*wr0{7b 2, =`nr@q];"u3 1 ǃi;`}I^?]2&׳%lq?FL٨50J].ິ/ PgìZNkkqmv3yu%eԦ҃gbB}^X*}G8<[\㺱OȒk΅'"cc[-'PchDul=.\]e*LGlzp6p @;],[+~[ 9?Ӂ̈́O"mMJnryAޗkv4dLe#!}mOPk}tyƨ osAfDyIS|]?;?T>!_K/>ߧܪԐ7$U/g]򈪨?0mv\3+4Am8cԫDBCsk'zT*=73a\0B{M<|y>hc>0eX֤b ]<c$ D=dʳITg=#ɹ$ӄρ !LmP6dt %>QŸ&'m4o49R*bDj9r9`.R\L?PB&mpy=<䚸egG]@<ιu_.I|+́x*:V6$ M*H\uPK7QB>رYQ8xcSd1ScLeURf+ᨣ!1}zCV빲ӬdHmnY{:e"A)xhWapHS>~o'_;9T|A+~@M;<ٟ95FǦ0 cSf_#7$"f$]}Y. ]T^N?8j7@|#L681*A[ xkvWؓڲ RŴWƦT@Ƀ:Z`:+pω y~~I~勯?7~9ymPQqqb : -sBNc-}Lc˳f´a.6ģggX:^7SWbG])sbo~ޞ|~֕륗nMI?_7>#/D`}Sh|dݿ+Le־%< a=4pq-@ܖdc:}l_B@N-zf!2%#ުyh" Ǧw>y>R[搭'CRbܬ)=W=~<ޮ2gMc.n {nȣd:[^HP.'w}xɹrT^\;. SeN};2&obQ?ބ!Eی["e&znjܬp^UJXBLe6<ͅү}y=ڙd-sjJ&ie=%f&n=Gxr}ƴ4LxO},^$$}pLRifcc,CP ĸ[b&w+ׁ?,ly2BJ9nو1#㊳A027V"4dɅ-ӛj**Eh3{)lD#A)߮ln jmfѤfolYd~ބ=;h6wzCM'N}$] {.f] 6zr)8E`( ?Ծ9֜wb ҝ"9T[( r`r%XY\F7eYiGаvexR1a/ʷd=(jwʗktG揝=9 IDATx'FYiP̉%fv;A{7̒s#One$p !0uu9Ɂ@S ak;0j~nDB &ofI쵊Ksh\ؐc22K#獃`{N#V32?hGVs1|w'9~W^JР% %eƸ"]65cC!v3Au_;ѐ F#/t'aua%#@Ķ{Ju]93Znd']'O|{?GCu~(}[/س5] !g:YЙ0!a o)Ԍ3¨$g?`8%P'q|Gĕ~0 |y>n&Z*gRN=Ex2lͰp=gfu[51gDD:B:43KH 0l1P9ӤɎkbe0't3h8itpO~㛇?1nk*.!r;:QLN,"3߉%~c ʳ);!z̳kHPp>`ܖoO^xWoo۫ow_}s__?_t']G>o/?_wys ^)yKX}~d't>~rBzL]T,_L>D\Odط>-5 erRCW[C՚ka*lWanh%l0v~]8sRzhAA.C'|;ӠS_ksJmzh0ujx w+ t]$4&Z1VT~>ܸ ?Vkѯ|Pէ^ CC n&JN?9T(A m0b@]'j$vό;hE [F6kVA8fߡ#忠}-_ {&k k!LT&w2ȯbFpGV tj]?iLAm#> Az1dc8e Ğ2jI:u;:&st7ew9Rc A\.`G݈pG}H g#(J`6\sx  >Os x]tEO iXB 1pnM(Jrw:tQ%'lH.6r~/]f u8p!d&)Yh%C ' r!) 8ossP3d= aSruqPs ݚʻO{G?ڛGe}sN&229B JE8`QպtY媫NX ]U]F[VDEƄBB朜sz}뾞N]}w~~{G>gA™TY/xㅏ~sz[1ks沏~ Q_G^^\~'uy{>?|[x'}}zG&]pm_hҤ[T3dO|#|޹H~ң/}:c'MoՅ=_ *j GOz#;&ZO.ȽB4pV˻c~}?f[vwk~ {/?Ɵ<|.D<<jVL9IiNHtɄ~KN}TX#`n:r9G|>>'ޖW)ř,'Rɺ"7m֓΍h'%4h; :cSءC}o$RVl cia0A :wM^CtJ7`cl 9m";X8z-xuc.q5`S7ଠ}Y(e :|}B,ŬͫÙsK<̑GQmc8ƆIwxfāvnשԟ/VL!|[]2Gƭ7kNw#n>_oDXbCugn+! a,"c2t#YҳKF#=$DWT2)9ր8Tf\1_azQ\ fCJК#mBX2ξWA_.~j,y ܩHw*Q/ XM쏴C؎ OR;NJx @J#'Fz֊Iw`!dUO>Ό)Ꝋ_ LEǮYqԸ{Hr+DsEap: *xfgg=Qm1ZL  ]B!?%Ұ`(A ?nRڡYDxh O)vqҿn  }H{s|s w<2CI;N:Hv[g=mRkΩ 0@1jQwLg^ÙXG%sH{k"Rh@ClV QgGs.=1Dw1x'94Kqn [q6U4&r]T~SF܈7$[n]tôˆhɘ꯱mub (mc:}|`j ֟jftg0ܱ$V| /ZW>K&ϟnk l{j]y \\ǟ=MH7(@}*]~W~,{_Ͽ{N\U|'+O- `|'>~Kױ@F~Sw'zE@/_"gO~?z%)orsG@uktyk֒i{ӏ [z/Aoh?pȽ|ޫƫ!)z+r6c7{6<*=ttQᤌRvNz$; )غrĽ4夺"\Qnڑ{m~G^!g$[p1ܛ}hmqj&鈲b۫W#B)Q͍~|9HwiX퇏ac֋S9J? hK4SR"7 l?F"-?4';al |b0pQ=)Жop\Y1M1 $NЍ1RD:wi\_=I7 ׺p7z=Wy/[7!ꑓ{l''5a6sփ<#"Sy ?&Be`(a4g:m]pٓ[Z B:[-kӹMʃ9`+ /oQSy?u fmy,9472n7yֵ}ڦ ~,zD3K*/ xt<2"NDǒcVǩt\Lpz G햭mݖI&2怋wx8rrhV>:m 9B ujLK:@\Wێ6'F1NvޯD'r^AX&P,RړTFR0 Ǣ"ۼ))G^tcGO|^gJo7]~z+>_M_S?>߰|ޑngW;gzCMPBˍG= En@NVo_|LT\,-|nnkޮbmPs>Q7UЏ[?[nަ}'._^q/}>P~G߼iE>!_m)K,¦r\7#y=Bmi֩@h?I=&ejhp+uZ> )r7#f(.i=ִ&9?q0lF擔A[Lڨģ[VV `훻|&t+zHlḴ Rr58Ģ= ;- UNNֵn3}nk4"kBclLj>N'rCբkߣrDz`eŮ ˹UO>15E*a,kϧQ(+rMނE֍G01}9Tvwq^o|ߏ> ~ͯx+/!z}%O_ŪSnoK?tKzD7_aE_K>UC>|~;^ӗyӻܫ>+_tJ>=u򳗟=뉗eϽş(9W~ׯ}iz%a/߭zy~ݯσ<˯u\xk^vSU>ǝoAߪW;>pYE_g+쮗?q{TUOL|Əϧx_пxʅt&fIKdͼ8OSr3Hj z䫿94X/HI@ڜ9MَG jOڽ)تLV^PEpb!7S[5d#+n<̟5q?.U]:u2#q!4e$kCi}jg+}AGT4K?[}iM>8d^z]P Qp .Lɣ'K'ɲ=D\[nӊjiRnll!տ7xsTZ(##5]XfK{g!Gjo<q|'Q'<WQ؞FG{&3YӠraz[*V8$`;rxo BRS1;7 SPä4ؤl7vr ޚqЛ \69zuΈwd_mǓ 9"<:8*pd8d4i ؂vƀ, q=TD&TNfkLѪWeW6? s.Gs0. DdEc <'h?\\1$6'P#ob8;s"rmϳjgl6sgS7Atu^[zޯoMzK>i#'/_#?ߑ>gk _˗mGߠ3K#}qx?4@>]f=sV9sy'R.^_>u+Ыoܫ|!3;ޟ9s^_9kA*o[?py?|゛^70^{.Wx'= P^Ի.[~=}? Rx} Sv?ψyy/ Q}{~g./\xuOwi zDhc,Yg2&۽Z) `>.x NPpsdZ{˱Aj VmCuNyH/} bxGD pvƪUgs4j.0ʭlLK݋mAvxRRa!*nhHѳ9 fL%]m&2Hd㱤vWڵt:P&16i#EՆ=TC) O(3$37+&6yg5^4&SONd֟C/9Ʃ>kf^aa Eҵ01=d Wb>1~Z{kd88Au ]ȬQH=,@K2z32ޖŇvMK:D;n^oՒKㅴ1pmbNAI: fUukO Ɖ+W#;rp^{:}$&~RBg&`wu e9VCYp~`T'1簓ւߧ4ٝ^ouƽgCsпw߅-c4RekxD0|FNsBotl!؅junq#ޯm6畡jNŨ6.r5;1> j܄4vlR_ʠ6NMŚt&| ø\˜=Nj\&xI%?!oкI)gN+ZZ\`.[\>>M'=Ưh,w_wsXG䕑||.ew,;|_cۺ蕏c&7H:oOOuI݀}+!I y1 _%;۲ҷc D6Fozv-e9fsqRGLi1vzAFX %.~Ĝ㋋ޞ/f 밣Var)&c9*XSOJv3u]w!\h?3oŇjZ u 8@4wc+J g;}]MT7h}*+ Iekjyĩ;.$8fLj:xh IDAT[qdip6X[\奋G_/oJDŎ{lÖ5)aBf=Y\t5'nH)kx{>&Zn1cxKKxz?Ƅ2Т7Z.f˹[ i][2gy25YoσGp<{z[k`nFK@量[xホ~f1youqn{){|! - R)h1ZݸM@} bd\1qH|d9d^L:_.9Y'flʱR`ktR_ږYZ),KϢ&z̥̞o|m d5 !QTQGu˞BFߌu]Qaa1/eZt6Wz6rnyA>^Kiq )[z@o\Z[& Nۻcֿ .Q3b.;0er6XjYTycR̎83o|^ylݼNO{/.2Z}-\r,|ǫV ]@Ozm^M.AxCuܶÏc>_W~w6'Lxʼ]yVz Շ<@Y#Ez^{偏e7vW]̮+~ScQSZնOٺG2Wou7>>Ode{׺prmC7\Yj)LIizx:r)C+C2 <a-s@;/0uB V* cBXĽA+DBDN41-9\c+_QR#6񨵰|@o_kNzUn"DTGndMY=Nr8EfrkvVb'"].Ub% >Hv'kyQ&4KrފcN?IE'fh 66B{qK >QL=l Z+xO`ϗ9re㐸| i,mB\ӗwXMz&;=*v)й0fnEÊ5ƥslcݞ|1Y-a7;0=}$a1OMA{ࡋ mMUǎE95@ 7і-Ys[9JxUPr]OImZgpF޶b}+(_ K $c>6~Ap֣,@XMwd\}Bv-`Z\ku!ad:4]Z(:8e/\sދ.{7'_pL#8)|Dl.6o֙V?zbR&3.>{F] 7*?]zo7Sd^_iǣOՇ[|##c7{?GDU-~*@1Q?Z&wٲnQjomn5h1*ۇУX{J=<0PKzXQup^[bsRb)Bx!ޣ <:|v)]/>^~ϩx'|R>~[ᕏw A/QgUc*#7 J.EVaa}sPn?=c:Mx)C)#7$'ƛ>hpXv}JNqS(m&!KbbK֍$ThM֯>Y!өJǓdo ӟL "ӍTSȶ0hbgރ3`9R9e,^QTiz<`b5YfY̱4y ޜG]kz DMqF5PPK'"n,R5B3}D; c^؃iVrA]hmS+V:)i}1":֪u֩AF #\xs]1&oz0M?mQkHIV"9=dtg>ԓrH}o:s|nivKB=UUUd5.&!RCelrbHFA۹kKn]0XN_:.#W1j[Tiƭc7xG8tU6 0j_I<}ɺ ^:7+x iu3K{C'@NAǶͩ h;n*98<&uvۻlnvנ9 i/7BuYxZ J<f8QnjzH&ʼ"zV|#([Tҏ}uE>1 >Y1OA iiYw }#ysǨ9;"'44,ªfr̒Pil~e@<)eA'M'%e"^2:<-a]kǏt|XL%O,W!D<@L|0ڵTy,O2%r9T^MbzMSk"Cimy' +Jt'+G>ɬ)[kGUAlE=밁2EL]7gRhB4{Hfsu g%:c5Fp<-Y-.Sphw0Rɢ^{k~i^>y>9NRWw/m-k0z/d*bRY[1Yk6H%WV_ҁ#bĆpk6Y}wݵm߲7^ƓAZ!};.}0u"ҾONW?Bh?|Ts & v2(гC{y[;滱$YOۻgh~9ޯ:A9:GL~ru;ty`l@G<715Ccv}0~HqT` fĢQāAIg`*Ii;2Aoϑ`{@!p̹etIԨi2F{j}d:ՕY'?~pNYr Cu'pg;t 99BY*T}̯'@`p4 #VP…(9F6sc!/Fρq3ҵ-8)pP<"/q[ƌ(;sߏ&yxv&I&f@~LC@(~Bq)M=_8֢׾|Mi{ Ƅz¯Xlä~,Xe"`*FA0eTqMX1Usм-Ъ4Ѵ-.vm\ mHidã13Q#YUM52cӵIAo8ml~bAm;m^[ln`N ¼R= &Y,A-%݁U9|LI1@Mxd=_>ń.3>{@ O? ~c~ƃ5<-=۲a5=Y^uSN){/|H_ax~0Oˋ粲'|zg K?闿=oN:92.m[_>e"$봪knmɈ@V.UD+LQcȎ"*I!XU;lUs=U&Xc܏N=ia;{<߹Y;{rH&__`pY6j$㆗sj h/[(gB?t\2$񵰖<vD3xs.|W|7*Q 0"f=D 1BH`jI]vƆ/8wHI Hrƅ[~H³_uQjK/g\~WY+ ش? 8Z$_imN=>K?B5/MiѷH)W-$r~H zr|W>BoZCoW ?#Sk q1J΅i75>"|ΓaL]Qu dZ=^$Z,7Ta!Vޛ,څ:3蛐M)IS;K{x!φ^䦓>C7Mi.7 mKN^VNp&ml B~DO[4t5._@d?ׯ'GHʈqbG5w1yx缲aѮ/S-8gp8scf?ZV8>8VF~-J]]D9\m H35Q[;M%ha1 _أ_>3>E p:O|#/?~^8! HźQ/V'<ǟ}5y{e ˟V>}~xq/MHx/|v++fw|ϿDW0hxR5H?wy_D5\spAv꯵} +%~ YIc}YghWNY(YT57EY~IIPatI٨]jH _ݙN$w1ρ@*{?o7O/tF1<GjF dqؽg 2 lu[8\۠~rMvf\XOkDHW+ܘ0.GaMj7ςiW7UUE$mc"(3hRڎF^#Q0u t!AJgjLʂI1 `ÕNEYe 5w98 Zc&JȔ cw%cDVlƞ*Ζ5kЎͭ@4Wg^Փ󓎩=(e=qi=x! |@_ nm. m{t^WWp[~}uyRjz zǯҷ|/s_DZ5_mVw\ޤ`|~o> ͕e˻ noEU]>%O/RƷ{1FYr]?~Z8|Q[\>/7g/so#_t~/| |~] (ٽz+>rݭ}y?x<Ífߣ1hNNk#x-M8<1J~*zYPlETtwFI2i?эvJfe^Oc,ʭp ^KPH< ܢS`](N5K{ڐv|{шQɞy]% BWiz.k=+ ̃JxυЎ3$4J`wÊ0- Sb]n\8GR5YvR 'n\̻9~@F#᪠['x@kR뎨=$ޱH{Kjøɻ3)v Fsm|n!`a(=Kw?Gj*M )VьNCk7I_O^ 7Jpv#?דXغ  cw[`!ߑd7NrgA0ȷ94v0T`{$` !JXnJz^S  u}FZ.ъHT%1V}UW\7 &musfK0t^8d5<c7 *d%nyB촎p( IDAT%ʷT x6VX:2D?YAɣ[|H巂^W C/ΝX!(QvL"7 Yj._KbLF'*JR /~|NgϾe^~-x~7"?~L~R}W| Ǟt?;^ç@o/}緌x7_=ї]+;?+gc%Z7-t;OIo0z&1Vyw-}IY}.= y`$߷-,cdޕz7Ɔө[Yjy3x3?Hś]ر InY%^bU.=8- IF.jj$ȎjfYiߚVrR[?݄u`P􁍢"4KnπjoeOuL t]W?VenuBELԬ)t#a{lTe?3_GvO%?lZ^h0kf:7v+ю +*橩|N"$˹ӵ@$4s`6%M;FN}5@}r{Nt5Y⺄9! VC;Ip v"3=cJz=:9Mͺo) v(yC@v7 jf尷}sW's8ˆ740ot5.W8cx|, k?s*7N=x }. {Ko>3w/_W/|яo:Ǥ')X_yu]o.3>T֫$^Wos+8/~μjr\AussN!m56º$.`{aZv*쉗_o@RiRIJv1Ă)ڣ~Cq0nqi35@ocF}?k`?l3ʳ(}4UٟŦڷ@[z~Cv;- 9kg &1}|vא$yC|l3uaxK/_jFZkzۚ 벶AVvH7p2Cb|L |\4 aWb]mƇ]ocGT;f)gi;fFR[= kG Cxc(j$[>t d:&N&o\x`\3 8'!TxWU`:6Hʓ:Xt֎B۶mw 3Ix68v7;`Ǧ$wQUVXC6w;~,7rn*_ۘn}w)&Ex4^/*{@\Loy|۫~/~g CN/y~‡)Yz>;k^_WY_:d92CAzcz3v;o|_{t?oѫo;?D6m=zj)Bë׾^[>蛲nVr3.oy.ߡǫ> 95ˏż>xɺi?+@y?j/zS.o׏2M~*:0Ik03#ӽI dF5jj]~@:GyҟQY!dr[3)زaχd3oi_Xˠ&Cf.NM.ĢqlgY-|;|1/ϵ$Z+N`HήV\:XL\!9/\ịrW0E, ?Y%)Igp&#J\` BL>ju*qs$]TX x;@ ͇$|T?3i,ɑA (o݁H`z/prebw=lo2S訚kTO=kⰕW cя)s) Vx+W<&l :4m7/T!/85ҹ:ѯ=[s!&/I\M]5q;"tU`?)>w~՜^qR oŮJp/X zbJ9G%|h`sun-I4fBzN.,MYQWh2{m0 )G #"LJ[iGĞCCq֊}|ꠁѷ_ tgsgLn1t(Z/:+g,: +¬4.;&s; gT(z:GǺ`o߯ ]-(CZ]|vywȽo{|DyXe?JP0{4| 'qA; Z8+x/q*7#lwD_6|e[>znFU emn17~m J}nROv4I]W ?k1y,ւ?>[54cj5Dm㮰ceo1s sY m^8l0|ڝ%nFЃ.R·*FG*Bi~oU,Ne^kLf9zHII@,MΣ2hijn@1~D1o!n+ͫ=֙yO"K`'|W ?0;Cƛv0WG"aU躼c~}h4u7Xw2fF-`h*v?ܼRp327"0) HE!\ɦ5&zwS[gQrq6GupNL07Yo!9wŲ%tskMcODc1j\HzDsqx6dձ䑃3yFY2CMWҹ _ m ^]n02,=ls|,غ ]ǯAs?&藟ui}Z`E ϙ#?D0tȩTM\rbUT*E5/쭼bF9~tJ'5 6)1=慳0Zik!Ru \ʸ͞鰀WCx E&ƩpݒY%Fdk M]mk%hA5cշ~0F*Xf[JV(R{aǂQ-Xyo泽c6$i1=#O9 >H!ggzV,ul9F4VC>relO} 'H\]3kҭ L րŮC{>>%'e+kW p"g0< pC(d!';#؃6fG'4.`w|l7|Ʉ-^p#9b9fNwiaeqvP506g޶5XYwg|J((wvxZ#7:')nR 7N&-6Ԍ"$ȃ+>Whts Pۜ1FCl#ZsA/ >#5|t's?PXܚ>!3nۉ<0 #;e>qG ne2M9{ZU5@mG~Y0Bt'bѐ;Tϭ',rtby F<9w0M<`2 0WM^iIrf"ڍm2|.g܁÷qMRgޖBn* хv7 ߪh!ՍcYvV]hev$h+Nkh}ԉy Z3TΙ 0`6g?Ce0HHkڝ" ltg=8nޢ!ym&X(XmR{*͟,CsJ(3 Qo:ôg.JK)\|4 !e4K܆U]@6F掠<,<$tc&wh(7208YU`6aS€(5Ww:FVgTF /2=kͿ`vp9pYQٮIJ1OkH±jc"sYμZW2 qLL,)1MC[ 6D |xb⣽hQ_z͌+(SdNaș\6- ϡCnl鰏BDL_׌^MrbsNfd1!jz7x~ݖ\!ըrt\qKvylrݞFuNÇNINɞY:oImᕽm<#~x'&?8 (k: 4lD]eyEraNWd;&qq$$;hߖM8di }s56ý}5cdtp]jm|7R|,R˫8!3(Σn{su]Mfd11(Tn.<Q=jXG:b;pNY/9Lduy@ ihNL60 F+4P2rI¥wi i0 yX7%/US 6՘pјc4q]ˁ@N7 yqoZp <#Mj1.bam0< AD&g{0.ǴsxVq=C q~#J^EaL7Q46֑s)2(GX/b@ f5:p876Q+ՍX*Uhi'^rx xqSrV1D^^Q m %(#1GJ.(I87'Xv _XX t^> K pD7i ec[XdqW6<0Hc4gdákT yz}[Ӽ{hWs櫞OK'y۠m&NNSӨ8meu"CIF_ؕ[_GZ=RQ_^k|ܙ.T>+օmW&C^; I(gkH`ajwe)|EVvkᬢFo|U{6\}j+ RYy-. !PWVLDqp 9sv# ݢ_z 7˘0kXdo,Wv5וP_iomHn۝z:BۭŁ\Κ}l;FLjqp#A͘Z"R/OE08Q"ч=ju3\n@HIcM$rvv:M_Id6 H,򰌞 7_ȑGa>|`bB0#$SfL`ᴼqT6]$_IIMf' K쉃RiZ.F>@;Ʋ1|{jzsw썧(S #zY} :䱒؁Ǭ3$GIܶD&EZnZDz'L{8|t{ Lj"f̓<9d-me:ի-T[zT?yQQP;LSвDlmOP,0Bbz3|ߞE3q&ȒҀ#RT[5 |0RJ<9H߄7I!o/4إ1{N@05ߝvf8)&a j>RUN *ѢI\bGj`Q 5`mHxf b7|aR83#9[H yъ+:uw9JtVMŖa9qGi%|҂koO& IDATV뺃nj[iz<biGT8) 3GkT.t+͑O!I.51hL3UEEs:0j6<޷҃|ǦȋV Ҵn-16C[uRأ;!o-Ix@h+uS, ڥ6gmI GXB O]Y<})Fpy?kj .wO jnM: K2ioK2o+k,66Ɩr>}-XZ_פph"H.h|EPsMBܓd(`Z1lVT0l{1+3TJ^>D;N" v$s:hpYBsuV:axţ<7(|kS ^T6v993{3@Tx-s юY랾6!}rǐvѩR'/aUmFd C7cTd< 9uweDV)hX+5u0 k'kr_^]adN:9rffv}n׮ʴ)N2ۖ\.~zu-( _gߔ7lK5SH +n,ug=ɣ&=Y8(&Қm#'m-?*|cY'.${r o[C(܀݈}Er8=y¨棷#r[5Σ.uƆTD;h~mOj:cx\ ilm늺A`Oз,'%eu4Z] I۔y#sf{fͷQvԃcVkDrDRmɂ rԎ'2b3V;(R*QQzҢاz;^9mH5F; 6iH$Z>hIÛ~W&+h9M!SF~RLfa`Hs ?z) b ˃|4(372Wپ TO  `°ŁajRa.jD9xd (`Q]jθ"ZG_XiW|CTbJqFm/Lk cb.%o%)yN!11fW)~ܥqZ~xL3 I?2ExψHZpLox rDH? 7ܴ&nZkM't bDߐI3t{$eBQKA1X: һ?"3:܄DGZ~Xxn} H /&d#S5P'Ki53c]<8-p5b|NLMk.VOW&fpOd}T>h^~[s/SX*_DN軡Sӎ]3s'yx~sV;c چ Fɩ5R5%'ȽT|>:R(t>J_5MSt؁PSVTۺ>!*ahHT9Q5X8X(2D}2}Rj  OIk9Jh[ 'S2SoT]1@>{nזRz(GE!pZG1 ҁA݊c[ MQ94RHK.߉bp2)>TVf+;݂ ԶÇӒcU¯'o=Vr/G* ]SebFv~ؗ]pwSe =`"jl`>mjdow +5.iagM=jvp!u:YWK;qu4!KSm8Σyp_gt#f5.ޥُp{c¨Dc`j֟nGw,2(Cm/IX߰n6tkЉ?A'LR0R*M4}`ȳjq 5bդ9HOFqRNĺkeR[7==s5&姄kgm+tye `~&=0Tb?L9[#l>Q.Ewڛ ڵ52hWY$=Zk(2l)u-%Ex1bfn.kZ4F+EE.YH9{%'z)o5( أnm6 o{brFۃ*m/{GQ? BBwқDOAчʓhRY_Et!CCI~s&_rI$ٽ; ((m2(RUj#jw2.(A>?88LD76A `ȏ0@)FYY-M)AdU4V8DX?`gJ22p|Ww#3(4z#BH F1jFL1 c8Wjcd2uJ`3;q!h #6Ѻ?z HY4E-%')-(⇃N gDxxaDY&c*eFis SZMȸ+@#Qh;6%T+ ,'jJ++RTSa)f>n1@]A Xhe jX {ňAQ碯UXk ˜K2iPDψDf(_U]| F2VĘt(bɱ]s1OѿjĆ*! ~r-li>4ACeSfV(>G6Wi+<`_2B6 PzǎASAꖄϻ4+ -$НȦȓ@/[Fg]Xd&% Se +j 4ʑR-aTSd)ufխgdI"bQ 5*HrcȽ\I>~Y{܏Om&|UZ@^;i&{2d*4-Ryxҭ*~ג)Y*tu}\1sE8 aR72{MwJjUIN(PW#DMpK"`9>IIAƪW.18.̔7~.jg X*Z*@IZNY)ziiS6R5WJ dTДI Ā?~]FQ|!0XQ$!a2`Y #:OԳWt 5ʴ/Eq,q.Pu E?V&hAX|[<hl.e*Rlv}P {4p`I%*m e l]*XnU VF4TXCѪڊgV8ViW\+t`g,mX{2DKr)}+m P!=p$:lb9\$ϴVbɊDIaXglǝH-H VU87:).q{&gUX| R ؒ$H"*UVWYECZ*2RU;$vܔ QT$ϵVJNV/Tx|QIU-uk}0w3!Yǟ C5uA_kSo 4ƝόT9<&#|/T2<*͂NjZսqPF]reC{JvI_qT&8) Q7G(*B1/Uln$a V͸,er.C-0UILHufy@qRc8n,4-9JKIv|E)wT^+0]*GUP%3B/ YX,j5et_U D#`L_B@`R܊(@z IP ƢBn  vGVJ?3ư8Hy8qpUO!o8IJfz3{5(x 6M3K1$SU }bRB55%TK؃ r AYeP]9Z+YH0k`[Z)5!vvfem}Zj]CXl0!;=+_Qfx_^1jdqt"n*)_#YŕHURj[(}DO B?e<:1 ǦbYZANjTX mk(LAWlЩ[*R ʘ~:L9aWjeE17˾t IDATf"(-M0\:UGM3xI0MSĈ5w emK4Ӫl j.(E2uƢ TH"\qee`uL?WœSI!TˡJ=H!њ19@M^2Ś+JkTjByYѵ}2:+O0-9jyVV CTD%L 4WAiBTB t!+u@$~ h:2O̵'aV ¬2C}' `CVch1& &!cO"GA օ$1 "EˤMxȱ X4O5%lPLAR[D aj ^IDHK6UأoPaHyЀNÁeTaBr`>%1WiP1~sNO3l32Qz2ȻIz)",q.C+|g>-TXv·1fv>BUhXN΃o/TIvhͽh̺FP#QфBD;=iׇ/(ʯ"]# C Wn9Ms @؜\Y!b=by'!9C_?4O M.Fٲ)yfF*ձA'JX12︫kBO~D]1b:?U&8;AGڧ.\\*veK!-Rf@]! L%kʵؿXp}h8eas)dr)ǂ*j«6oB de>`GMSVtB]҆L:1 Pycɑ,D> ԪT ^*JFNE* JcgY/Ԅ萭 2Mm^87">5of?ƟQQ{ UYƸi5*(kΠ>"ES)jQҨ±9.> ]lc!\&TJd*IF66<* ]X;!;M<>ӆlu< !ͥ$^FAĸCLɼXl RdkzPD…$g$.1c.*cTFSqkyF摻N09KiN#Q.*xZ#7 oR&nõ [e0 5q&Jl]II GZYz_ 䥂@ޓX>D &WbN "LP-T l#HIACۇ}G_ƅYG!- k xy1aUt6CH(0dxpgA `i9y‡ qsC4 wn i"@ dzlx"[OiP^SGN`emp.e-@[Q[n@%ȕm%FKWUV&M ํ,Jvfa2=NZ& >SoH9"*tU<njR,EA- HABQės#RTUM*n$/Bwx;$%r,푿U [F]E_ ]K, >q8 +Hn=/2@ 6JԵ<6bt+hljз4xm6f9 JL/F*A5j$ݟT*35I[sJ^)ꅘB FB #wجxfl7N$(ב."Waq쮊bWO񘜋A=P~3V.EтE$`)eWͫ0ES䝯B?J)] SbV2H_/wQ@[ctڣ ²سPhx'PǸ0M0<0U&hR%Qօf}.*[Xj6޲Hc(<3XbTFPR-; &IEsl#3FThkb[7Ax6VP96]l8ӮYZZ-=J5C#le#3C*=<J8jKB_btx~IB+Dh f RF9+B<rAv8Q{򣜅DlUC\Ce1xgC8o8UaI80H@R 4q#v}V=\zA&EZq^ʡy#a홒dQP6BʮL^2 IgCJnSd9]@=C%5!lrӥX0AӲɇB EFMu0w200<,8Tر !?7g_ $vkQbIu[;yԬM͠`6x6/z>"9Gp(2H-?ƅd&6A~DуY7nz44snzd[h %K<Blj5-j_y7CDK>${V)) R#A =*H./\ tIQG̀irUYlIux.I+ Z(G9%!܎!̪Ӳ^Q,JRZ =>LlT3U[)De:GlhHWcAa,V')>.EZ\8~XlܜgwO@sWnSLY•^H zQO<*+4T-#'4vR͞EïdS}pA|I,jM͘1c%bln >}FCyD18x@$UŎI"H59uJ; ҨxJ~ܴMK>ZQ/ͺy@mI2:2a!#`݂jie‡')0'Q"9SmS/չ)UM&網+*o}Ja A)p}VnC ڌ_*-55 9WIzX6tf@t7NHLl`72C iY rʹduLڬö0'tNUsYQ7!_c6"ԮqP 4ZdTa#]]#_BwbuU[JMH!*w{d̒[rT=ʕ773GtELcBUVKW)UQ5`4f}& 0ZiwAT5/ؤ7)†4PZAd d0#RŃ};3MM%a*IPy\#2 {7W6M>X4eEAAlR@;)X…^UcаZ?Z)G J-R 'Xg j@COy^B2E]*2 6$5/uk%B>BIJ%ֱ:GXm5P֡!TV ::D5voC4q- NCHH$"p2MGJ<]Y_o! % i:PMCwx}XlYND.u"e1K|8oK#%/2$̻3?:D,Aݚ`]HlV#a9U%mbC2.crypU/ kqq%.2>K]W9Y&'YdUBСmJbn͋l4jE `Sb1f\U_#GYb &lu[nQR|ijfWpe}%x0dPjK3ZY8.(r҅3S įs !נn19.- ʕ@"uLvOC_pee\Lς" 'ـdW3aB5bVN|lHR4l|ݙq` qik9NcYvdd'R lm"y9P\en (hj%P+ebYTZɣ@bG+ejG[ۓ<4RwE|WlD6LMoM}y{J:qƶTFIWypZɚ fo%ʮZ4JiJm, aj+ /"y(m`tژGb [lOzT K U]/Q(u1z~h"ȺZ@CDULaKpE.EQD`_Bꦯܔ 51GXTWVQ+YPUd\={YJ _☢YsVyW,q=911)"8R ~ "k2|W%+ql*v* *4mt Ίdh}$eM5" daE1+AJ]4"FK&^~#KCvL9PT C˺ X)A"6E!q6 KU:ê jY6ŀ١2,*PUxx!UP**TKWd4z_ SS O"f ]CTA^ٰ[t%fv\QP1Ky$E8eӂʸ`5Ags$)4F!6I֨LYB.# |u.[Х i¹mP,[ UfUFM )# zn: ֒§R0L4~sL6fEu 3RMcx,)m@T_%QhoTLaxjI|g\p  eZ.P/eƘjdu3r"6%F%4]l5T9Hf<ȂFh^!ՓۮUZ0̿1,-" 95v9_}5 NV5ĒyBJ܂:^6v S- exH)|5\P6%!ªdBw+/Q@ @ @5@ @ @  H@ @ @ H Ӂ@ @ @ PG & u<@ @ D & 7L@ @ @Z @ 2lr IDAT@ tt0@ @ ubR#j@ @ @ AbApt @ @  H@ @ @ H Ӂ@ @ @ PG & u<@ @ D & 7L@ @ @Z @ @ tt0@ @ ubR#j@ @ @ AbApt @ @  H@ @ @ H Ӂ@ @ @ PG & u<@ @ D & 7L@ @ @Z @ @ tt0@ @ ubR#j@ @ @ AbApt @ @  H@ @ @ H Ӂ@ @ @ PG & u<@ @ D & 7L@ @ @Z @ @ tt0@ @ ubR#j@ @ @ AbApt @ @  H@ @ @ H Ӂ@ @ @ PG & u<@ @ D & 7L@ @ @Z @ @ tt0@ @ ubR#j@ @ @ AbApt @ @  H@ @ @ H Ӂ@ @ @ PG`P@ iS)K?ʡ10 3@šց@ _&"QB`>^.u 80 YtHZc5WLuS @ P (!;/boVXi> Y&Ym1a„4ϴ{Ae@ s$f1cnM9nOJK.I} HO'd8ٓzA>iSw>vEg sϥ+L(2$m6#Hoyx3MlFYLtU@ t@NWzvwE|ܸq__ӓO>FE:!0eʔ%x{j{}i`g@kv0۪`zN7({WtǧkU]zG@ p>!ˬoSOenaK,npm݇2.PO?L_&iRK^'{yeTH.7v`E]n;\iUW[o9{뮻>m& <N=6jtKxv6Zk?~I oCzG6| bzSO=-%m^xt=Bk&n]tQ~{fq-P >jxϞd;\ܗay~衇 7ܐX~l曆/K|֘1c8QYp$ soذa|1|N_饗Ҟ{%^{yws9')_L"1{ybM6I> a,zyguY'$Y:|pvaLOOzZ`҈#qW_ʑ@ ى@5L駟NG}t:k魜|)tM5y:&/#׿J+r6|=w|?gN<1y758VNf${޹yo/NWȲɉ#82=CW]~ӟ_ '{jhۮGyd?"}{ܜ~'?YN"to+r0)9CNƌ'5T i/iwbufяq9Y}ͧdBIGC~g1.v:+Ia-:F?Q;/s=u!deBzjzyr=~ᙏBO|p„uOqV38C&Ǐ闲o5J?~hB[t{ꫯNgӋ/)UJ&_A`ӵ^˻,(5׿`_KN;#e==6wa>;BH_c].ܭ /0}SLmùg;8COKQ@ :@z/gNB'S+.;kUpbWN?xdSYj.]v%&W!cwdn j~.{'_܍Fd_ΰ)%#Y˰q5#7v{j?5F<=<^Nb671,'(5aEr~wCӋrl/WgX,]p`S㨻1W_KJkv=M<~[&ɳ8'iX>U_c&p,y]L|rt? 61J;e6wtYgqIڊ ͯ~+!=݌z#@ f7n+Hb"/|! }Uqʏ/t 7뮻.&K7^o_|q9Q_]nۊ&7zL%w$7{[no_>w\.%i+Y,ꯧ扠˼ӪiX N;{yid ͳnN7cxz/ef)Մ{e>u}Gwq 'Dz{݄嘻[LpL6lts _DO&M4ΐڟҥ26K2Z&끏=؄Q._.E+ƎpҼҊ+d#'bX.>lv*o][]V[uU>;~iVk5p2oħmjyKζĦia%Iξ$X>gwc]<^N;;S\?H-]& WȦ/1ېf`_Zt=!~{3oFlb,`I?>S .hx e>#m @ f@wnNb9;>!K1><~Π|,(.@^p6= ,s3^rͷLgN>я|ƛo}C6l;ړq{R'?Iv%6~X:#{rEz-Қ{eSO>E^.T[1_#e;Oɋ_gOc]<NK _7+@fsf=qO>iw:krS_Ë xӟ'v;GX׹OWH`ْ˕e w=8y܄75Oxš} {uQGhmP㏓K.|b{ktɧ]tQn1tA|ٚ_~|s2c @ f3TNߞ0 q 2Rؗ '*\(Knr+*g0%\'my]ZpdarYgۯ.J[yVnȌ5vy~ߴ,=9XN<(w\vR<{·OHwo/~t8K)㕿:]>W s=W+>ۍɞM'QNI3}yNqY҈qe>}L_ r%x6>s '|<*^2<(y^L'z7ƙg%ul$ޚ/nWK/ mk/ͽd&>ЈI _> {l:d"ulZwuӾ~*≠,[nc@ &`MA?66>|l|`W4#}?_mwYfϙm~5?16;x_7skOo[;?@?@oo#D^t~nΊ\!8Q&mP~(|h Z >@dv8;|USxex>jzeW_??ON7P_;3C7@ ~3Ϟ𻗎 G=_/>^o$fϾ\4y޽Y- M:% N,u{oycA @ #& nh! Os 6 zߺ4~VL~8 B @  F'6@ @`F & stF#L|o_T z:uZ& v |;0f+m|\U?|}qyqLoE@ ̙dhU 0KG>1o,!8p,NiO/bmw3ҁ@ @!oG 3@ 0 S'OIO=dzGқomga>:DV?"^9$@ >D & }f VN,(*oÚ6=P] wp5~p@ 0G"KnFy N /R @ !@ @ @ 3bgP@ @ @ h@L@!@ @ @ 3bgP@ @ @ h@L@!@ @ @ 3bgP@ @ @ h@L@!@ @ @ 3bgP@ @ @ h@L@!@ @ @ 3bgP@ @ @ h@L@!@ @ @ 30O&MN&OJOg or @ З/ [@?GwMoZz҄Fx3@|,BieKˍN @ }@L@˰k&O$Ϥu]?-Ēiy1Gp3ĉӫ/z4diȐ!rkҌ @ @ HfD9?Ƨ0 [rx6mj2eJ;A0\rG~0mc2XZ @"3<1a„d9Δ<iG`С%Y@ @E1i2 |"7=R @ _; '"@`!~L@f(@  $y`M6 0 -$JʫX~c!@ fg"?t-7K jn7x|;.=4_9;t,nx6I0ݗq11kinJ;g=kJO@ }@`M1xRԉwNt5O>mn<D@ -`zGӋ/pGrРAiqy`}UVMɃ̮‹}'q",y{B(b@ Z"o& nԩm'o)r.pkNN_'(sMi!C&m卓'ONώxѴ[qc?wQ\?G_ LeR&ʁ@ @@` ֯^'{y~6| ~MxOzZo袋ӶmGV^%}_KozJ]w}xM҈G;mpi+FN<{5Xⅴr#0~Ikk\g>0oG'lq^󗿤mݖ 5.sew_8{xW\qEhs,C_=i8qG_s=7~~N>#iҀʫ6lK00訣Wvx}9iyȄo 24E_}-K+/nIe0)qǤ\uy}M 3ucSO>5GGYFJ/}usЎhb byCԁ}%"]{͟#=ct^OU')V\yE_ob1c$@ "Яt-M??;,p·{^y|q{gtRZcO8gyđG/2xzeońOOCe *_Oq=6b3s=Yf4zhYxsm2>w}[2vXBίtP¡4#l.Arw ˮn4U>N;2hw:?6FiNwy{zXN7t3HkAPY^;c2AXS&ԓOu@&Bx;oqF|0y IDATs1uaKeѝ2aGʍv晴[_73$Ic~ON5^7('M}4Kofd<@ny)͕W_}5 w;2^z9r2Q{w[i[nsa;nO?DZwÍ"nEI|1~dB3-.KX=#@ s\eƲ]w%-i 6`4I?C& ^aJimI ?Y}mr-?>]qŕʃqC[m"?I|~'Zi뭷NrLV~+>.e.WGBv~S;q˯q]_җc%w76N+rkgOo jѣ٦1Ǥ4Zr$7tS>C,Sg*촸Bρsi= YlhZ`ȑ+O>ܑ"< ,@Z}5O=hc7k^ZRB ŁUӸ=%~hOq=KL<Їr_tYgq\>R;,)$sNҐ!ɘ؞;c|,Bz7AywwVp?5鿋,",gCeE`X9Ocib T}쇰A0-p3& ]<]{UiIYdLz!rO݊I\jQkyX L%X,b|=򧤷%~A"@ B㼲 9p8y'_viu];te / M\K EpfzG\}oe976\{n'J>boԊߔm;mg_l[MJ[(w]]*sw!Jʼn0N,( ]wN×^6mi6ImEbƅ 6ژܽxc /XkoQyճN&]xyk4JxHسu"7ͻ}96֩j@ @  sVX'S<@ cO+IH }YRjUWegJIT3=_g>Ml M.cfr#l⊌s|7|FuwRv~۵>iFuVyO_8aob-GUlV[nɰ@,{[cR+,>PcJį!>Uy1?$lrBwF\x% $,X&vXBהVS~߽LSOeC̿8? %r&L4&2

&+e-=/ϊ`I)ϓ2i$Wug[尜 Ϧnw1Asˤpb|4w2Ew<ČId^wgp7uԇH>HN-|h?N\@tʱBbJ>h@ @B_M@puA28YiΔ /ʕˍ1#=0,oB‰NwigYR_4'|tΏxΗp2eaذYgɇȷο 'wCڥ5vIYnwꩧW_]>[翐tdK.<\s-y(xS'i)'LvKGt衇M/5F;Ssp`nц$aYN KikOO]}~'ʛl9~W%'蘆Y^C֓4`Zk5cnEN]UZ郶a2\@ ىRYuJXËr-xpҰV['<<+N |r{3.|El+ ,uY| Y&j=U۲p6i?t &"?pzG>=C\KB;ezS2U~|p{ay.q7Ȣ=  IJ-"G{qQyI^u 0ZRH_.'! 9E&ƮSb`%Vk}9n#@ @`V#6,haL('Nm*{X&)}'Ͷc0zw 7?/+SƉL,dJN`6<%2fw^IeijNxw=Zb$UymnIHw<,& M FVb4WH@ @FL@䳿}z7#&yEl@kpN0!G$F֗E@ @ 3?9h,Do݄9 |{-oo 0 }K*H̋,Ha]T 3bs ˁ@ ܉@L@~VCVϋEۍhf@ @ {b@"&%C{)@ /Dtr cE;4X6=#;V@ .B>yϛ|zG䕴fp7;@?],R @ 7`D 7- |oU9DZ wC|i}nZz7j,9z|x.א}`17D&ݏlF@ ̉3 sbFRX@ @ "πt0@ @ %1)шr @ @ tt0@ @ %1)шr @ @ tt0@ @ %1)шr @ @ tt0@ @ %1)шr @ @ tt0@ @ %1)шr @ @ tt0@ @ %1)шr @ @ tt0@ @ %1)EyK&~BoDŹNJ6+kAji+[*(@ ܊@#WX1ˮ/x8A8sSn ×evϮJ3}oW(@ #0hU:1ri%'|2u]߾tM75XsN2'MJ;onu_xm ލ@ 3@%t $M6-qǝf~ק=3-7byvcZ3FWZ=}cfjSoyiwO6* _jʫ}>o{;? w>4k|T}|7mFieM뮷~:I2WO>xqnn;pi+0 .fsfc ^c-p9SOKUƿƚk_/Zk3{9FG,?}&fzʫJ%E]LꫯLBzw6\]|_Ӳˍǧ~K 1W\ie3;=\b?!@ ~5q~/ʉ\t34l0nv[9,/di{ɧJsY2Z,@'[t~tǧ_|1 :4xM 'ez~rx~4jjW_M8AA,.[o5*i]Nm;\NK8﷎=6u_fOGK/#82=868[J/BZlZ̿8F1^s59g}o۬>4hޔΆ+Q;Sy曥ﺓ6۔4Lz\Dヤ4.ﭿm&=#i]$1yY> wyGZ2Y)70 ]srt-5‰#FEZ)r!믻6=Ѓ/"sL8{Q@J SDX9+*)*QPER ! fl6۲,Yvw[3Ӿ=+.]z}?BC;ZN?]~1xlڴIxu˗~)j+r( $@B N/D&M,^}\ ,?|{Xî?AHu`6xhRjI:|Y6+,]ԾױWvu+]tw:wl6,|%_,*T뒒nH$d9e)K,|ZM߳{ԣgZ%3/3ΰi)v~ҥK{:?Lå4n,'|Go<>DkߥKgR})vU+{={}!?O #P yǟxRb̕jgsv?N>z"C\834u _{7Z4%99YڵkkeXWj}/BmG ,[$+UhwSGgq|O6mߔ~Gf͞%k'LoJN8w2w\aXڋ%~=\O^SHeP#9;tҴ+G~ꕏl9@H .ҹRm6_IN8.^/7tq[~:E_:ֿOߋ$d4YVZmﴴ)SL`aGZ'~Ͷ^%߰a]} {<f6oCtNe$=zJե^zv>s3lٲvX[_e{E7ofå;Ux(L^q,I!  nz;$iݺuHO׮]N֞۷ϺN9KO?q*"{6V۶m吹{뿹Gwʲ;T/{Wv`ݛڴi#{T=#WaVDZ'B:^أk2Fyţ 5墋ʓO3rZǎ}"CEF^ ԫ C  PŶoۚ=&ǣTySß9Jg̰}VU>:K/w;cEKn3-m/ޢ ę@@&PC.9zI Zhp"Ӥ5dH*?\t?ӻ`@8@"Ͽ8 Z`nyè*V(gM(w2򁹵N ׹O }#ͱ  @ 0+[!  Pjzr*   D$ @@@`@ ƕT@@@ HV!  @+"  @o;i b  @QEE*# Z~]  @ Z,<2#  @A 0I@@| +@@@h ret.0o~~yBzX]9vyw.xGf33Cn bOrsHJ*%כ@As<v>'/<:\Rn<, |r饗ɒ%Tɒ6] d4͛˺uk!Cdȿѣ^$0ux]`gG~f/|Yɮ];5QFrwu Z\yK;G3sw/^,o 9t.\Юs~3}e)"[l6Ķæ  H9uN&+ؖAch9|d9nu֑GyDn2JFv+%[^]6t\2呾T&$Cv结f{%[gq27;n7O?)\ I|Vh۱N:ri'qg裏 zIAԼ^_|IF`R]۷ooGa@@ $LKVX){0qv7(y~lܹȣO믿L@;&Gb %:Av'I٫mՌ|ڎax+HZZL9nL{Cn29}G?-wutY}aI:k?C4={]ଲ吏z|!6WFK/ngICߝ9 jG-Bðti+KV<~MD+?Ge@(bz7s5uɥ^* 4Ȏ駟dǎ1Ŷop)p9&M ^RmRXtjM 8⟚ {^{|b}h =$8=WRG(-*G\Њ)&T*T> SOG@D@[ /ЖXotO7'xFm!qGPO֋b\y- ;Zfddղ 7mRR%_:~ܸLPr.}.ݹf^a .zQK?E@IN+bz8Y?7ޏ{"y[6w=қyґ!9bQ(4mvz$:ő@@ Js>qLƴIq]vig>~x{ǫ>}zC=(5k*v1c4;Nri`q;@@pY DO Jݏ<_/_-s='kב.]w#wyurn_a܀!$$@@ [9A/|J \ *mg_gwl1^Owz;P@@61 kRZجvn;D&W^Yi @@7[s@Ro [`#ab -+@@<)`f~$tO"Xi@@ 6 2#9@V  @HJJ{Ir27k33X/@ @@"0 ;Im߶UjԨ![ uVR+A\b*cdffʮ;e?euiFٶ%EHM.;wԫWO鞉 eLTV.緰o߾U Ҍ[H@ @rRiVf8֬Z#L4]z5K.zFٰ~LkYxp-h2e~0YKFF+񃩩h".V 7,GQ[nj a{H$xT@=,!M68222MG=('aWjXsD'`鰫m[ԩKN &MnմY37ɧvPիK͚5}/-.oyҸqc9^C~Wv)&MHe9~o{A1#['|w3To>OII1O|_9+vh:,ӦMN:I*T ʨ醪k+ѓ?^ _tM6nX/s*'|JBK/$<ҲeK;Dr{W6m$SL'zw}v˧~*;v쐁J5=2bygUމB6 zSC=sHw=i Fpe WOmGyC"]{3F4SufywO|yeɒ%~Yxϯ**Uþ42I=5O=ړY&xѣGkq⟧-룋:w 2T?7Mk{$ ~e :tWлhꠓïB-ܝtC{~agUD:wK(}}w*vJł S k9f?ФIV@{<8V~Ajժ%eʖ {\a KT%[MɐrX.]jMHL*?;>A_%W^y3Cw;dnɞ_,_g W^z١`l0]Z:˗E<[g Iz;Up#hXpNYb}N~Swgڵ;R:þWaɯW`{hFl@O uG4lo%ߠܵC3${\Is'ZȦldYDZPlܸNI/=Izr,^t ܎`'z^ :Zm۶Ҍ_m'I=5ߟ}{mb蟧i23XBY Ne&.: ;{6lYўh~o's%WC {;n^4T~lC"& (*y1O1 m۞ ?A7ij'_b=řg0)K?'ʢ%1sVnsub;:2ଁeYtSv[һbyÝ'D{b̼vϵ^{'t3L'\#I>}l=.OcǎuV<}iLV3B|0`@\M= tew tsܸqHć>Eoޠ'z, WS޵l#;OE颁v5ТY& 7ߩp5 i}uN?X@()S @Rl}k|=ח~֫,M>0=ӻ4+b&;ۓtlmu{=᭷lLfdYOO!=?~⤷1ջ*Ep!-sa=.\#-[VN;4]e`y:"}z~?{cj{O/e>oB`eԓH:GNǎkcW^~e!XҀ[Nߣ]ByEVSkw.:'Iea@b:N8A]w}!{q>U<Ζ |ׯ[+ӾZo @@o/#ꪫ Nl$}Ί\;E;2rH{PTB6@)0nkrA"AsCǿ'a_EtK;-u^$!Y/dkx",^zA.47TJ"'G<1Kk^uwʬgS&ݱN pT ߢ+sP97:Sd2ۛhtYW}rz!l~ xT@ #x @nsi~ 4BG*]r;5o]@@ ۇ>냟0a));3o.n` 6@@B0q=q/5%%%Eʔ)˶龨Yӧ<Ѓk.3f ~zNYv4;'8ѻb~^}U,rg ^n} $ @LAa,Up/Ha yx#  p4 {(@bg@@03@ uzAׇs   p\. H$  @l {Ir2MPD?wJԅ$Q[r! ^0лMm߶UV, n*UT5I $v(@@8 $'%K6me֏3zT,ιʒm[S䗟gKdR YYl  xO SnFϛ+3 vEA[]U2=H۴˔Nj$dP(@@{%KHӦM^ziU8)*Ifؕ.]&aDMC@@o ܅%JJ , N'k0 H B@<(.7l%Ɏ;<({b*Vc[K%bO$)@\F@\PflMIsH׮]Qf };kV8{jv*~tI., 6/H@@ @ @Ο/9G%:hX|~Ajժ%eʖ.B;1o\' @@0O?Oݑj7N]ũߠܵC3$dP(@@mwvY&aMxiz1z@bkWB@@@b@@@M!Xq  @ D5{lԩܹSʗ/_@Nx)   t.PժUN;Mx ٻwo;88p:2 9Z" D,|rY~Orw'|bԈ` ד@@ yl IDAT ϻFys\ve2qi%u{^K~+ݣi=Z@gd<ӠiwEҠA}v)S&K*Ug?233lӴ"СL1ii̜#)Fz#ާQG@@:x<$ڙmqnjyMze`5o\ʕ+'֭;I+5Ϥl>N_ @bR'@@(09NcH2e?_ /흸{lJ!Caz7駟nϛ7_V^meii֯_mkIҥKYEFQ]@jR/@@m{=jC^=ouA/r {\~ڠOne6T霒]v"(x۶f\L8A]w}A$M  . \碈Jq0-M\M9N\ػT{^K y= Nv  lO1uRZćH8   @9$uK v̷H I@@ fk4I+q@-(   ^CR4@fR+@@gݻOqTVBG].Em@@0 \fE)[Sݫ'fGR~m@8M2ǙrjRFMDbGq eɶ)ϳy{ɒ F!! @vUN]iݦ̟7Wv%o6RaWLR6yz2D , @@13xҴiSWddd ?{"Ifؕ.]&aOMC@@o $/!e͋h $̔iM@@   Px gMN  x^?@@(<³&'@@f\|$i\#H@P@]-?_s41KtѼű&(!?ԪUKʔ-]"y R{{|Rv>Q[Aa%  #`H5W;kxA~sIOψ蜏wK6MڈNkLRRwΧv$Z1G@"8dvT]'$3YntuGI3슙!l*ezBb;C  @~;ִ mSpR& 6@@ +K.[N:rmL2 TB%-퀬\T6mZgԗf͏r{$D͙M  @ٳ[wrni/^(;ʡïZb֒/V-[ʴo?7圮J2eef&iP~o?k,;Ϟ=._8X+w~U\]6lXgmT6υɗ_|";w!?e+cc'U@@ݺl_"&̞=[/{UPA>lYdIiĻ#Ɍ˟76P,W\r2e١AϳRRrv3s@yxk*q  @ hw_ɹgw7Wӳ{>cO3G PX|rs~/RR%+bM(=.S)o&wz|?c D>;f\h5⷟ÛqWN:ѽD  @T aW_O*!=6>]zr1 ԨQ>a0}-$ Nyz-9mSZ5kd.32}Ɉ#D/Sԯ__|Av7%%EN:$0`o-ܻS 9o2O%BJ7|ݷqF3 1a픗_d{}[< 5)O>ogyoݘWFHͪ帖' vf?7nk˻/HMަsnl^WKW, Hr N8/=G||o zސo}-:B=˩/ʔ/&ٻ0+O>BRґSCn/^X._r<kcd3Ke+{?y>ԑ![6nheأőr*vN$ee?I?wH p0  O`=_2Gy_nwrA>RreҰA#Ҹqi? AwHfgǢrv|` *֭4h@8 yeĉvf>?//\zvSN9EZ$ p׮]sΑQFIbrl?XNȘ[-.+5~o i\UzD~=U֙ y-̐ rmk$5Uc^*W,72Hz1[俇/h;a\t IDATWXn=ҫ9Rvuk44m숑2oڷ|]ӈeI豨q   @FFdddDg.N>MsTԩ];dj5'ʗA^̝7G64nXL&7dϳ̉rҬYs޿W ,ʛtiԨ 6T~}I=䢋.O2̟?ѠIC.v:u V9"=3ʶj,mTV]/Y$5k֖tSZ&[pԮU[6cnw ӾBnV)Q6= UΝ7O{cq]M/=놛nO<">%==gL/KeP{֡L!}ɢ6H_ NJ*ϗI3){5@@ pWP<{; 6[n9!-+_wН'b{$L?l>;.zE~_tV:|Fҹ$:]'ܹSЪf͚֭)@-ofӧI_㩧KgI^NDk6"~5mzlLr8$-mcm3j|&@ȔmNm=N@Uf~9YvL4Y.Q5 :ee˖-cA谮F& |)g^3 f{}r9b'NŒCCeCӊu$V9C@ do*Ifr;ImqzQ_U27咋.sk_ΡzB_bE_|~>qԀ@^wZf<#ryyR[5j,ZH^z%{Sti{笻\AOطnf[(3999r\w? {ONrǥoYٝtǗ)S^Np};Re]oz<˪+Dt >>soך>LiKxӭmv|rwɁiҡiF@0Ct.?T^%Mv] Z6wRl?c9@@ 4sdM7a9s.v^MaWgqRVYvԘ_ڜ`f(lbG}uwo3!{~~1乻.s];eyvbov.-?+^$}i\sqW9q@\9[}x|fgc&/[8Xݻ|3;+Qy"YvnG>YfL̝;[ީfo/7 Xgd5Zf8_:&⺚d EY@h']tuj˲K͉nEYreTkJ$K~In>;^ˊeK˯&!tisWjw^k7fOWPi;6$RkP@(b6Nz Uޝvy:>lpfzٶu]<%r3{&-v%kԖgL7s]U/07fH%RL*VdjW:^Z/KM]@@plpknؽ{V4oL~q|ŗRF-iv .Kl'}LOk,0斻͚ݻD.e8@@8 *Vyrv͚5f&qd4gxxaT<'m㔥ŮީmSsW,p*U:6r @rz @@O`X fw Bt`H3AwyGlْgϞ-/xrۗ~u-Eٳf=Dy衇W;hEi(&uA@<H&N(ȱqɒ%/֧OKlcF.:9(XT.[VOKYl]V5j$-[5k_4C뚙)~C> ] ")^{ҳgϨ5xe B-?0`@AzӢoh^h#m*۶mˑ] 4K9ˠAA` ZI$ CUuiժ:I7c[ 97T(ߖQ˙mٝRm#{QmS v#>ҪdL-[,~gΫya2l€ߞ7/[:I'pr;"KMlmrl$c6X͢*OYP?-YvxmĘЖih\OITy= ;WN-~x;ߗ柗]dec\'㬳β+Wu,PLۓr$[׮IΫw*P+&L2΃ kMq THs=Ws/tm|h5x~aYhQ"k\zL4N ׈?xgrIY9h_o?ʳvXvpYo3˘[;U&N)ͺo#1HUDT#7.Qy$s6dj@I^'ͻN9{Id>3ЭHmƥ7YR#O)3FW .K0[R"{_K5y]iΛOJ<{dV2d2|}oH~3|&-dxopCX&5x홲;`]WdWA7G2o)㊗$ҢJ{wT/G\>0oKs`iݪ_J߾uNz@& 6?tl:|=hy3W#1L\ɬ,?R`U˻]Se҈A?Dޚ?ﰼ?dLj\O7~oh]7igg-MMG;)TZΝ;mDqv'HW1mV*UdOjunj~B4uv~^Y{;tȏunӞp/"ЪL_Z^|/=Fd  ,m ,z-<@vn}" B8 ї.8m2=t:9n.M}/ރ R\1P_Se͉iͅӳÙ'n> 4L|-wfWFՒۻપ3q5簹(;@m 얆QWUH@9G=Ќ._*=Qk;8l#(؃z6zYwØiTd6<=fdYMLAϠh~&^ ;&ދ(]}[[MĪHd!f.3QO#eG62ũ]ݍ%]-;~po1knX-iAUyQ ՛N2B;rAZUe@+_SOM].BUt(UŏSH{= ͯG"ޏE|7V㆛V( c[̕nƊC[[PHN&$o3+@k ?]`N Ki m؜IٍM6Wg^||Ωo$wd`ݑ}_ރ2Dz/|m@*$c,]oUYF '|"!GBOz,ڢxGd<mA[KxG>5-ș} liQCL Z~lcclDe4nb5ۻ ס---2S.{njSO#0&޾4k델KU/x©STIro/W/Gvu% Mp?@vMb|Ƚ'?/8vBe]~]0D"'.zWVOa:^qEm  /NƇ_ }o}&[H`oP]nEhDq4upQWnq"8Ec/9_}5@bYNšad2hhSvא୘)aMAg &bf6ݥ ~B&`R\#E;Gc,л 7a;mYY e, f3HF& N]~@d<UM)9yQRG^*q 㐿!y!:8q"uyNd)#$,?{mH''%K_VYL/ N >Ӿ4NYIfW_'IOiGg{+_EX2gJ. Z a`EkȬ4w\%,%^qDM\j~e$COҌdl^dCLS8|c?2dș3gԉe+NԥB"^4Đa̙ǏeKo#e]UU1>^y˸3+"E6z#+N˪C(. ͓;y /G䃥̙nojA8|t2q {u#g`E8èmF{/ndo[^μ [Y=o[Y:%/.:Տo7*|u9:5+hv=X,ȹGz{^;WKv-GsmwRax2Mȥ]wH܇1^cKq{4|QK[MF;X˼W۞Eaؖmgh`k^տ;sD0dbB_F嬈1#WXncj:ׇI<[^dwg0߅dSgV6G<[<ۏGo y7=Ҏ{a^jTUm» W7ɤHe~ZccEP3ӽY2OeP6vGe߸?CfЯzʉ2@>0(_{1^ؽ[_%Jnj?4eHLsdrJi\u:o|h(!Dygf)Yɐ~Aoܗ Hޒl0U%)N+ʷUd4\7mdL>]H&Ȝ%KU"TO= <~K+ RBN;\el<a>*. +0qXTD= `"ήXܯPSzy;/3 i[èyRٓ8~S_/] Vϣn;򕑑':{u"ZiV{Ggo=gq藭8yWΘLg| ZVQkƿlK˓tub+U;|\E{qt'2G.*PicΝ ]DfurI3E^+ִf:{1 hCCİ0^pxt룢)-k;<, 9GƇpzu(ЏIP mbhGrbRcMg.\ΧmX^0SБyB7rTɸ,XٵT[*oZ{vlAqUII8l=̠lz21nbNI5F\ц(\juyVxQԈ Vkqdd%H\e8lOٷ\#˦G`twՏn.H@Gt>,|%gľmyHCm }y4?`N'y+oO7~tu"9?:v/t\])h@:~^nH<eDe0OΥFI!C+/.zNF?O?'rCX6vt@yI%{\d*K{ccV_~x^b.~YdǀxzC1 %'{n5E9 3;"洲QX܂~UYp4"sڑi?Rf}K'aI^'a]BW߶H~;*_;ƊS(~`zQW*XWĨHA9@@jji y4U&b=xGJ8Y8y2>D6{@Nj֟Pi F'0fI@#Pt1.Qi!o.PW:vڗ0[>ķ"]&,HnS!g]eę/nrhLyBOf=sDPrd".² WGp(ŸȜUOǢDlrB\levDXh(9.$ZO?~:'d+Gׇ834K4Nn7^KfKV /Ǯ7߬_ͤ{b8'cJu4>>eH[|z|qi [sꫯ|b d+J@)8@)yÊoKfEDhʾ9eH6[b MkC ݱ:W]{u7O%Hcx}UtZURك]45Ho͗AQ;C65NHq ŁRHq Ł8 0~Tۥ}qJI]6SHдgݱC7Pd_|xPfҭsb {FFj^hYm-.;a)ȆO;Y`)0HvoIƆcJҦ8@)8[qF]>#L%u*pԄcBOtm}FzI;YdqrJp36Ƈxl8@)8@2`H$[őlYI7Ƈ+F'[l +#k )8@)8@)80b_duWIENDB`pacemaker-master/doc/Clusters_from_Scratch/en-US/images/f-13.8-software.png000066400000000000000000004715621217637305600267410ustar00rootroot00000000000000PNG  IHDR i1 iCCPICC ProfilexXgPMX`w9%眓sFrPQHV""HT  |﫺nW3==sByOtt8n{o& |~hw^ydOEƲ~ѱ`ƣagƃ8<}89Dc K}`(!`{6F:""j_1? =}|~QH\tO߇[DxliH?YiEyXڮc!ngX -Ͱ0{L _|l?v;4 ~8a4 *zX[>AD2AT4K= QLY@* 6!B$ qB($)Bd YA; AP<eAPTBU&tAF  /B !PG#,N/D"FD!{aK,b D$R)TG"m{Xd2YC!Y2 P2(-凊Ae*PMsjMBКhs:A/o/tO ÆǨa0PL*8sӋyǬaXNVk`˱wcX:vGq&Ha\)׃-6xQ&OƟ7Ot&L'hLBO"|'BD =1xXFB$1P$ <N2422L0|'Hb$=^IR3>iHee4ggڵڳ:::tfuu}tt ][ԗտ@ aa(hĘbl\a=HkcNlΫZGC 96['?Q|~iqN((;s2)S5ȂB¦"rQJiy?J *=C8f̪\|"eA*ܪjg>ruimGX]i=>~a \/l7F6694=hVknni9Պhop%K]m2m._W|}u嵾E۫nPou@]]nZqKVmەwX!dMݻ|/|n_<0o?ڃ4n>R9:X'*Ontw,+!vw'VNn` )Ei2%R3\e r%sZv_PXDy M -J*.i3l~5!7";b:cbntG |ǧU=> %Ň ?|"8my9 Wү&hMONθ72 7Kbb>Y&~Ҽ v|8ٲm? r qtEQ ht3F3݇N $hf-2*JZ{ZktJtO08aX`tƸʤٴŲf5gpӠ+uWپYo!o BVPdpUpF8-5XTGb,ρD$䒔}ά<ܙ5rSű/8~ĭN-"aP+v( ->S]v^HD\5~vtx.nnm^jt Uk%ڥnvwv޴v!NaOݾ{=Pwx3P8xihc ƺ}:kfZqm썹y ߖt?nYs j7u~15g@ ! (MQxF!QZ ]!b0o.8g#Db!y"S(6sY|bCyOMaN%3_BrUr+s? EO%)#T+l$ +*#L,^]-")E%!#$J@J'?pTLAiTX]_uAM=^CCQsUk|O]'=i}Aa1;63SsVyk\ulmv+o`\RZV^G~oyр `carVtvL]쭸 'RRoO?w0Pdfa,l#9zG5)K?!~RJ~]Q%JY)gЪʯ^VΥ>yz#oKܗn\A^uvxÿAͬ=^˾'=&?5;O}b9k1 @)\py S%Cv$xL@ _+@dC"HGd9r%:E3mq4bNK8<.ׇ kD^b.q!ɘ(XDecS˔`"5%;k2`gfoPtĕMny B5BZBEEzD}b-4@k('% d؛˦ʽTpVdVQ*TvRTyڢ1٢BS{BL]OoI1ɢٸ )E_6,vŎ.ܮnWNYhY◈O_YXH5ud{l@ː h!鎬AQD}4탾g{1Wx.[TBaEc`#n13v1i2Y0ّ% `вp(BC,D\P|V*+V򐔀Ԁt 9[rEK*e_ߪj!ښ̚Z={JuTuzmG Md9LP&V̿XYnYclm-<]nθ#JxX{yU{1 ಐa#Q)+qf ]IeLiYF?Wc'NvΟN*VwUU:\Xl( lbb׶k;:oR=ۓK7|?G O`610B« 7w?M;^޻ht/.+W}qwۺІݯg7_f#퓡eD\I@C9w0ژ{XK. Wt KǘdLb 7SҨ, p'^psvp>s7/[QBHWX]DETYLI\f(-)!&(ɑU+ijkQOD ^ÏT S_\V'Q6vfnNG\\Ϲ;1}n?o_0|ʫ'1E F)D7݈7Mx䑼(;$ٝe=v5bœO. <<Quxt-|E#wSmPk%Ͷ+.WG\va\?7x>(2T4xd l3/S_|4mlJmZt2+Ec ŧKe>}TlՕV_'=ڏkkQks?>\W]`Hݠ2wMͩ-խ[sǶ'ߵ\n\~.ͺz8ـJo?fRvQnbޥ|^ pHYs   IDATx ]E7~^$} .j@YqQgdt ~.ç7:fe#NTdW!J}#$;Nz_wgUVֽV{KJEO-JCb92@F #d2p PCCkѣ-aqZ\booGFF #d2@F #`"MMMF \ӓd2@F #dNt`B=^WڱcDzcl+#dtzC~aܹs@F #NnjQ<Cɖ-[z 3fq'&Lf Z>lJ ԩSog',Tjg??3WBps5׸$8ns#X8+Vwܡ1;we˖i4 8(6N9zSN4A]sͻKmr@4eojl@gzF #8XfuQ:o"1^criɘ1czL8`N-#df4 UnyGuӧ,,` l޼YgE8#QF h6WZ3˴iM&&NP;P{7oQh?>N Yem%?@fd2~%TDt5LRgΜ%K4x&K r"-ݻdIO(Gk)GVmIrɅ=ɩ@F #q2*pXzɇ} mmmK{[[[f`MD v-6k,wwɓ'RY@69pڴi*(X"P_'N}ڥ f,ˮ _$'MѣFi(?*+3utʶe,7Hh:G9Ms @awɽrm3JƎjv鐻?% VrY5TTJR)ʜɗ.?A9b{X9@F #__}ɶm䤓N>2W91_/pVK|9q?.z!g@֯_r(< bƋ u @aڵ:hMV:}xV[U&-IlnذA&MyOΚNcR@gzF #x* оG߾K.~2_=(w]Z&Oh1d f 1t+k&{.>Yb/w 6Lof+_FYc[:d2#ooڴI9]}s9`vB"7:,t2φ;!Apv,z1`trRSɖ mr`aϞ='}G|0 L!Ciyd'vHS+ҷn%].MuhƗa VJOp쾅?V;;;;q s%2{hu(CF # 3\m4g#w✭}h}t4M5$5BC#(,,_K|W>bB'n*~zCtF #x!+[lo5r؂cg6,:gP2@F``+^^;R>mMگ=l*vwIK/0ej,.|kYߐQSQ^}Ld2aG&[Q$pcol q s>Pν;=; ]&z6sPCY fsر*J > CTd2O1\s2ͣqoډ:4e筇uxk › !Mϯa֣l2Lȗ)Ie5,9µ\Cީgu`w s6|i,6 `} Kkǁ߃s:#<hK?UZ͕'0+Lֵѱq";wI 2א2^zL>d6#w,1sCF #`i.g ,M.c˖-jXӳggyq~,.㢟\۶~Vd2 *G~Vu }xm:m`>ޞCF #<p7 5uu77yɝq㵅2]-b^]3-#pd_3 j)g2@F`pj& u<~tsd2@F #?C.JMF3Tbszd~F #d2@F #04?1~d2@F #d2{kKY0#d2@F # @d2@F #d<>,@F #d2@F`%XGN/s_O7A}QYlcc6fʉ'7|f3Ø{.,3d2@F``}Fߜ M~{$7ϭu_HwF̊p;&.@v@~<Ox`+ghpg@F #3kNo{ vM>Z{{ U}3&)=utTCPF)um-֛.7X~`rʛ0a?OAF{κ1 "vz'>$T%n\rv<#md2@F #C7m^,ԑ֎2wޡҍA_; C ]|BƍEy(9y\`A]K[w=g'h0O4 rg{E֮*K=o#_ ɩG>t'M$۶o7?Rm>@+-W]т@ &Ph>XwuE/_G{08| ORK(CF #d2OOM nҷGF6 IiEy)ЉKeH{{qqc\ =,{( :8Rʵrh=LI=Ҙ^Zm/s0JL0/X@^L1"֜%"8MZe9٧@F #dt<**hXx46i_LӁ(Œm,*J*y7k ;x>2x:˦n[>w6ˣҕ}#W^K:\@ 37v84aG4R)@6xٍi{?.(-O mGtc.%y_m۷U8Ƹč1% ͕ KF #d2&ɮsiIz: oE`:D?3!}wI9ga2a℺ z^n[ eV-{ڔ}I,8U>ݟ4c6waaǍ].ir-[ BFРw0Na`|B|=#lO^+޼0w6r$ވ6g.-֌O4Yxt!qgG`$2O<9uϦo9ӵ2@F #x#˼/ )A뵇bک9iVKJGG'_uDxn ;e⎮<yIX%}h9jWwkh_|}"fQ*2sJY>f 6`WN;oxp?Laʨ߲}|up"ߋn4-A֑obcg9% ,&My6ɆeQ{ڤytz&ڷ^z'Ikى;vi8pG0)g@71R+>cz,Ȭ\ [._L02뮓 /p9ĝ;ȎZ96wG͗-1QZ5#BGdҷ˶ PeG)Hb2\Zř%Ė-[bɁ[N1">G+{d2p#U0a߉g?*xIڥҗ#M3\āH#^NGkc[g~8i3]].͓6af@qȰ˰ET[ ۮR+h#rXڮq@\pn@|bxWeg86^QnRY+=rͿN&b)ViixO5CGOl/3φ6>c֟3 cz27!<RR笛d2XRž(L6aT閦N @U)>^+olZ~BޏN#Xo?1e04'RF6;;˫jXOBnLQБ#g?Xy~.b#buCi^ocҴ oTL`ҊNuc#.<< :){ bj~V|?;D<8 9s㉂XXB )eZl CZ@F #<G {"@hi fG;WyQ译U:r+~\#[^Xr6oޕ掝?bҔC ?8t[k~ъri)Ϗub;pq 7ȫ_;OoX|FǤo)/ XbM;p`&6@D0"˻K_^pT%2a1apcmm|6I1AVie۰x"`'@ڕrd2ģ·Ai@TLWp#vLO@ y>|q]oⴑ"?OyCǒ|C=6twd -\8Tc(ti6Gb`|~ks8H%ArԑRei(fz)k0,2m+əCo"ݸ/}PlF t4$ q4 s`@挈'ΞCF #d2O?Ы >}O$Zwߪc?˯x1ʱ);'+4Wȧ,vwZSd庲LY ^Evu4AWϟ7·!7=$wf@Xaf?n<ģ# s \x025 c<82k,Y%WzH&<2ai!jG|#uWEuqPq34Xvc>%WB_^àЧPnR]%~$$IN#s8Hx^G'6fϔUJkf@pYv<;ct_z9|VIƀ{;\LEN?`% ;-QôUz0Y;p3l}skեX|(z @ IDAT o,}l#=X4Z0C"yQ y}Bl绻9`ˮynu~]d2@F``|ޱeĻH5 ]  }=X-DWO?eY,waL>+o>d6}(߻Me0:z(^j~eʔ)qըQ'@o(@{"=4Ap޼y#Vi ҙg)~g;8S͙"fy{dTa:J'=FWCukN+4:2{lޔ:~$E:uB#OPv8{©.x&@o6[SN9E^vYsоwF2|  )/:L?6|;Хl3gΌ3 Hp39Yc Q^(Nb{2BwO~l8kcn1=b'z姏ڍhx#2ȐnlܸQ;|qcQ9{lC17xכN4u07e@&N?t}0oZPukʾY4Xhd%yiJ`im۶I #ѣF7qՍ;B5?GY.}Ny:/Ǐu쮻իW\gjI5CfζnwRlYpst?k#|*b_9)Mi(t?x9d3@F #g ؇Ӷ\Ě鬒 0v8RrY L{w.4צwɫ}j&N/qsC9@,_8lGa!khm#&ϒygǻ6}@կ"> fLG ē/@F #d2Crc3r~Ǚͦ:U'ry axƬD9bǎrm ݱ#jLr@F #d) \gF #d2@F # d2@F #<اwlq}>Nr.zi-Z4(wl7sYĺ _;./$au@F #dF'V/^Y>Y>@_ }&C/Xbg@:ˢo|Unh8= tˮF[{˿,KT|T3˾ϑ6"W~Q>s?7M˒Eߒ#·>kDH>B'ʕo@?{ݷ˷:EՉC?d2@F #Gw|ŗAfc]rnC_{?|SɅ f`k| {\_D>rzo%VV(4N{Juf Wr6}w@{nɎj ws&ܵ[ayxgi-oM,]no\ʨ2^%dmhzz>_$_ޱZ~t\?"ӛ%mҰ61_E_mê 9/+|y:R?5|Ku7dϗ[e~L}T}[N:_oA۲oIYXZ;I_gsY'#d2MRiǰA ߳*xh`W} M͏_- >as or\rD|>4⭨=9\9MićDk[|\nVI/|t ]MZ/VڰI6n);mQxիHEX5lLco.\( ^m"ޢ嚯}ևIETم߼U"_|,v+H: *_چ/4OfOWz\|]-ҋtgw'?{rL6#bY;fv& wrX*x{UC Yq;^ujum[,w ]]n-\=Yb ߓ_(6\͆5vh[Xmo_~ ؋>a{]"[*m2} z/Qtr4~_4ɕrїʽ(_q./wʯb.ȴˍ -_ɻƻkK+7#>፺$n!#d2"yoBfVƞ^Y?kX(X.[xMg% <*Sik/R FV^P.0`藢$Xoh>]{O/R30޵L|B_x7oByۍW_(_6p?ptnsT4S_.goIo+HQ.|_6ݲ :i\sgP~qa9/>%G_TdoXt՗=R~xϺB!].-?xHϝ.}\/kPPu/X `}Ee鯓*/k~ FrTv|{E2__.6[+oWO7ROȢW42]*5C.O]Wˆ.\n%_B:xo|r$o~(?Qk=+cղiw*r+CC_3N{\!|Hߑ_x.y⾟/V#}軮S5 eK̎w/gߖ6]/]ܵn,(_tMWM7|U8 HOe\[ϟ(szW9x*˔fz_ܾRzˆ%.z7AZ9Y^(ʍ(wR6-ȿ[m)5&̙l|^9%'HKni>W='dy_ͿOJǎخZx^!s2X#Q/[1(7j9zܳ;r5&]H^4J*fb4Na~n;+ɱhwL{~-O}.JsքgT޾j4=-{'Y+ln|qHKSWmzϮ["$-ʥ?\"(|N<#c"=V&rwEƎ$'y2 a}K VE.[/r*t99SһYx_uT#O?GA(!9ߍmHAVgm@F #CQ]eʱϓ"ٴ˟W=}sj}կc0xc7lw%u9Klkm7zDF7B@Z uس+/{w?xpxf@^t+׼]-9'Js9D cڀC]>ipe ÉL c,dF^pdenu~3@F #x gu5eb>QZ+vY`dF;MfZ"nѯ[mAk&yݛ&=д(M~ԁ =ɷN/7M!qn>]Ί;;kEy׼},2؀*s/Fk{Bn?ʍA;o]=پK:{qy9~yd#^c +e"Tm7ʄg?x:Шl wwGQS&ȑg$+&cϔӦɘfo C%>g̔_!0d%@).н{k>_yC!X-G\~;}E/У9(zdCdڴ)СBtܾ]ϘDK37Q*ji~k&' (=J: seV4omYLwȭA.y䎕2sh)7)k?2r<1MtpLX(0[K?2x{uI}&Yf\+q q7-v~܁d2@FIB=ʕj=dѻk J.h}pr8$zKe٫'7&}=;HpF,IxptU>dRLnG,]xNynZkiX9sE\$ʽ.joN;NN:9qRi=V_urqv t0 70vZ$_n=,#2K./_g*'Oŀ@o2#7}N>-@o[LRab \ڰj[A7bxgk&uzW˳g4Pr!e2r? )zvє,`k~@$F9cE rͽsO;_ |K_YLNdǿ$ג3v|:Z?^۾S*2f(bO<}عxbO ʥ7 ;ƌ+z|Da[__un=Oz|KSYvlw_cAuȣ-x^}ʨxoj@S#ٻس-^i8Q1r߃ɘQ2$}ha;cǷHniĒ7ŧ|DxN`^14˨^{3WƷT䡫Z^o\FC+ 2@bnR@F #(MmcdLCt`IBJK~^ꮴx:wD_j_KDj}Wx|E3|n >],i= 7-{Џ>Mҕ68=xtR޳mC۱@dVtrGg&EoۍnlѾkl6 =;a!-[x]MXsd@$-uz |"E'M v͌ZzِŃ@0·RNFniMܸn'|b<m} x}ڽM%Iw}~C:"T_L%`Zlv)/FŪ6AH |#O!*$dd.d%4T缴Z)k̒,b*^-b#\/†*YcQ)P+|XPhᨃ)@idex"|W-ITBu&/kT,!|n[~DQ*Kʫk>AikMh,ƅԆo^|\(Cb|UHXAW3XCL]>0:.A5ne 2?Z@UH X5Dz슊u ?0Ynjc$:f+K}%ߖxM|oy$QΏ4*h7fkB@?PA!S c w&IwAx7CEM(D\8Gyix/R8)Pu Ffa(TǠ(q&YYNw6Zl@^Y;"͊RITiǒ:B:ndV1uT2Q?1hqSƌ" 'zޖI6wlU|*ڱm)Q(Z4m4~Z3 8ިbfF5T o_f[Q ]jT+Lx$%ZM B?aF#biڠ< IWQ]嬘s3A.3&dŤث#Hu{:羃Hܝ SU& ZYKUIz,bA< Kƭ]F! H7m9l=$xW~EYP܎hZ8~ЋkT$WpI*jtoQ?r A4b֭UkKrum t٘O@$_NJt dK!Qe@FUDQ~Ruu У7hTilK! <:YLPH02Jٔ4SdDbV"ZT6mDD]!+JF̘,IG6m6Y)Hi{%Ap2(4R+@]"i`[i>" DU;T]|u.-O"2SuB=NBʹC%9vG3@KiνI^QGA*JpA؅&t/mwdžJ݄ 3N:eaK'y z TiC6hL h<˹^2JWE&Bm$zz%LBG)siYI:3z xJQb,7q]!C Z\~UCCg@ȏ]EPѢLSz.Pm_7ٙ jN7j)r]ANY]Y\>mQX)GT :!R5FgY73)D5IbY!qD1UQm3,qU2HM!JB t>MH\:5 Z 6J2)Z54s&<&zl&x `ƃ]9aPa5A6gTEj~+.QRJSY3tyR!MMD UX`;֪I6ft -gm%,rj.$3S:Ɠt0x olPZ/K'P"(B:%U#ÙVKRU@"H|fJ.!$aA.7M\aϜR@!:^?1rgfd.#0y-rC3҃L^+ P[ 5T!`64Ta $b]?fbQr0t5"_LYk(e)BVh$ ڜ6tds/\1M*im1&=r̾k-ҺS4 9OYehA8!E$jBRAu} v&TO7Q?v)vnHMg܏ =_)tYu't;{t*i0* }K<StNM>D[S6i ["Mr)j"ŏ8Kڋ2Ev"b'HV1uG P29ľUWh"IPe>u6Y i'<G*_Lَu^2{<Ӷ+C*Ѹ".u?>Sҭ7sUT{2 s 'kZˢ %9PP%PFhmk9=6=֍IūNLMOLW ZF)D"fH0Fʥ ni>a$H0[M3H0]'SdmP{̳ܸy`e>FT2E̤QHL/*c"ëS7=QN1;uTD9"@ipY}nj; hv1Rs)Ɣë4T6+sT$g)#0L۩$v4L;Jiw>whQEnT fA&zE2-SZ!EueU \g`yZ@2oWb3 6B$mDnNˏ;Dw2BkcBbVQaL (f T=+Uu"f#LJT, 3;&E:"QG+1\LPyup 6'VFPjRb̈́MCY*Դ,5]%`Cs9("5MuhG;Gw(׀zs th4isDp濄65<2 }Êʁb ,VVn6P0׎T1!*m>l7Z2+MrS7p~h4hՃymcEMYmHbE0fPOIm2Q4`ЙTc ?jɲ͞<Kr}*Q̫BP+qgq/_1ۡvHJ1mltt :R( r9خ !J ҧNIP,$Mt}'x8uFT@!c'P- 2S5惛f!TdYi!L\tӌJeص@.}}/T&%A11C&Zb< J僘E`$2..P n<-NnT! LՉ YۚRQ^ZtIHΠzE DŽSڪ|%)f Q-&+tʫs 1pL V{(j lXrfAFrJd,h !0+y*YMS OUޡ|6]iD/SyGRTc.:BJǔaZ1SLX!C^mHi_s%3YI$zB$]U7j/t]RB=ِK \y;gOw -pvJjQ^d&BAႈc-_OC;Tt,왕͝)UUHBW :1t504 /҂BCBwaDqU |'&0 VqzqI# [m5UM$4+زNd1 'аAIt@Aܵ<EmJv~E1/CʨrdyPʑb>h nȱDȘ $O)o "* ( "f.:q 81SI~F9Sui竬T"O!^0 Kh6^!kۇ%!W,`݃D؝vzNjUU:3c<ֽZƋbi Ro~]QkHs@/Jw(_j߂=tr&9 ߯45ψ_) ` yD '@A-A=} pTcJ' ABg@ۗ [ =hN\'@\9Bt&S(Ҫ2$ P #u:*m[XaԎ!8nL&\c` (fCp5f&!v`, tX֜6gU?vQ). t@U|ǫ*}h=ƱL Xp6Yy.f=~?Z0&%\ڳ#O U$S;^˫ x%$n29y,)m\\9I%o Ɉ]IOA[RR.mPiCDJIAPb~,=RۮF4RJgݥ d&$seSX =_$[̀VE P $Vq=V-PkSEJĉAa\7?P3񪂯g'r;tV * v+<X+Tyr7.g@K@rQtC%]Lc˘ ;A=% 3Ap^hœf˶VoyzC] 4S[<ۯwbf3L;_K¨u ';M& 3S"E(^Wz}Ge%'- IDAT+u6B #q\a-jhq4Hlr#{I~U"P0.y++`BC۵2lʥLcCxʮv|Kp=8&x.c@+<LF2~6JQ,IpUŠf{i>Qȭ :| Q,t5Ȩ?-TFrjBp#5y<]c)4ruq1$1c3c΃D<IOtA7?D:*&/p3fQˡY;lf t EiFn֘^ 2&j8uZ ES.7s) XR9&fDbV- \Q yT 6$EE?M9 = -#F]@`* sL;Rp0s'Q>CuPA 1#' vJV€w| ji&eY4C)E)Jw&bWMHlD! 'rVRBdzćX;S:f= ciݭr*#P`ݍ- 0fܘklW[i׋[޾i|cf3C":bbŶ1PVƤ"8IJTJ.*O0 ʒh6 :8KzW(lB̈́r!Ì`-EIBM&c>LbTp^S i~dPXR5w}M)lu<(6&jLj(lQKoLR0 m*Vs_o17|0UJJUbO 5#< FJŽ}f I XRDP{*iNl _NwqƵΧҾkܬƩ3\!Ҙ7uUPq:n9#dlXKI>H*SE^%>z2LG:6i:̘]m ⒡E%c͆X c) Q vMϺkwYk>:vi Hi#2B@wlh;$ `4@tM A)mSӯYfZ]8:?8y[6130ض\/ʮaI/ᒟq9xO"B>]q,dvG}t_s,URgܱ*dq9H)aG4~ZXtacm!' G!D断qOPvb~47>3bvCl6ң^Ğ/!8g=.գC<>KN~kvJӿsνvqX { ^f?T?po}Sp+zw*㮪 ɹdCJX^,ZkAUq%!ob3@Rͭt_|&QTH }e8vq\k N90&Пn L|AsIkI.nW4hΕ` Y38W3⮫P'k^MZrq54KӪylp| ]>ό+气r"NmIq)el@0`:u#Q\Hwq(s<&/;O_^P`D'3q&[ =uda T)"R<`Ƒ8v"$jVt ctp9MLTsaciLl4EHPCId|Պ*\b0Wlޕ™yj#.H=ޔC{KcWύVka+ÛĉpRs`0%~)p;up}b|{ ޴!8Ľԥ7bbC%Aڳ@S1Hj6Bl/ac [c[8 0W ˸hQv8 nPiP~(mY6'[Dz$6WLRL@%*+ꀱ eC#Y($' 4FMRCߝx!;k͆۾Ofj)zbu* (RYN/1 pu$;mÁ?r7pyegJqeI S>`Xm8:!^:~pMWu3b[`c*WĄʛg>5hD_\AX5Uw,%NKp\>0gL7~1>\0;uxR@ɺ趍@b: U#}kЏ^YǝC&/dr~^'K͎^wBWnL j؆J`"ZެG+B8ĕȶ] y(@q3M-56֝ @ɞl8ǽTS2&2s#^x]\T p}!ξ)X:191ӎqQq-D~7Zr&l4n U,l0 ?V{=I{ } цpI5 iZ|ű+~x8]KAQ%«s^\Qk'%g=Js tT;վ^Et>iG)@01DŽX+ڀy͇_͐sWYץυƋhCEޠ WE]xZV[]|E.^Oo 8̗Y垫e%Uן~M}O^|WtC'@4y,g=3D XسybԧzNTEF~%j^t ɋ(Xǹjb&d2CGgؼ{ݣ ʤEs;1#C6| 7KҩvxJ)A_ уαsqk[J&pԐl筽ga;DGՐ} vlh?옮Wv${up):gO*9:78d_V!r<=%HoY&PGkwGY1uBO{g8WcG\9*o̭hP۶qk+WÙw!]1&O3GBnL 29ƒɛ%7GVLZ"0u6*~4n%Ad hMu%d ށ'zn p{3Gd2{B{e0rsY|tHKJ-Ӏx,ewa!(h`^P(+{X ∕H,a9e3-\Ds-~v%sn 00x@-zmoJ\9=X5Soœ @Sl=&W7?$Waa8f9ӆQYm pET蜌G'rZc̸quI8~Y .40dsS8l0;,tڠg;³&B:汙x_3&&k $v);cp8cTl)TWA`CSɆE 8W`<}A/>&7|և Cl))hWKS{l v߸{T + `:і|nZ f^F٘jk\'FqΐhI#1mM '!Ǜ#=Oym―{ !Orqa Q^tv$1!F:;gdRei-.f9eI6! 3䕤e9%cVr[89;UښH }[}O9A"_HAɼ]`rrvWm6tA=O@EB-t1J sR|-uf%D.tµ[}60o IP0#swnT 55W5l!녈`ãW;[9P&zH.5;·KS/ĻMKs `Csj!JxYO]靚qć^dh@ dޢܓ׵dom+ςIXr1!#MlX ,3'L0dZ'=xYmN臇b |2 X9 wāio5:;sp%:cvo&q^dEj .Gs|j'9g{SLVy&~70>k$H>2 %m] :S]3_X d!cZ&o ޳WX _*'vgCwDoߖ\IݪQ𳆌1_zex~/@L8il|1jb<7^x(. dV9%&9h#xË0/Jc+Ћn3!8a *uRsm!B u#Q8obagSwW͚c^'cg[ydv:}|c馷l^嶽4GZ/ZtR>WD;"U|JgnAEep4ls5vJpS;ڙq2KXd $ZU@k{=HۤPso2!6C}(;΁wl Z$'ގۀ=FBA c[%Nם:°-LAX?2 jZG9ДY&$?ئ p>y%k].k' 5xq,% v|^_3y*Tpzd*ӋRј6yK?>?l6Iψ.G_'ml];'>Cuavn.odZ1{||v?wİͺ024ol Ne toFW^6bYBjPӏ5\Yڽ#c8k@۸`۬& qy%d x:T8NID< DfSCdcXat]Țs"lN sA1\W"vO\K_9570inFJaŋ=ռ>?P~5owNFe'"]Q+T%zmG`%!'\muڈ9x̴P݆_Lvu=d,n\vkve{~o.xJbvv9K1yaQ  Mq,Si'r=5q0|W7hkę!c_C9HSE7YL'TOA.Q8L#nt:ܡqq v>j t;u 2[’T(ޖs3m.K<{*R mS!!!4(9 hj[).73jǜ?Hʕ l·7O v hHOnCKc} vLۣ+ۚk1Fe/7մښ?sS/>:WI\b\+.I<)(څZ`o$& uYWd/W7w:]TKHAjaß$PiE b֧a)#a0eÙdd*8qW4J܄ߨy{[7L"ne 07e};ء/u Ix30COה(Yt°gr$1't<~@3!O+=S\[2fG]F9AfauP^0aKgɄ`<Lfĕ|'[C8ںyVŖ;5N&?ˇ&gck3hGVeπ0{ & X}7cc睅˾byb$ݸtbi->[>ŬwNTh+,3 _xQ+f"> Yu|12UN$u P"};mfэ|$/ %k:qnl`=ȐW_Qr$^4Y0I^w䟅.eTf,eؽGxђPt'QK͸eBe0W4\#ރ M;,` .^ Hv5&xf1cB" +FXJ cH1s_<' IDATK&QLWܼfn ME+tbI̩[v_=\V-]AGK [}F;}OqoD߃ rW\}gy#6N64*b޳:@Y3!nZńY!?1֘>yȊmhSJq^VXG8|#y .R17^_o~{{{?p{˚vadOzs2OyȁSZ 3gSؠw;;evg鉠 Xֻc.4Vs5Bny#z&?71y!#2h`rhxud^s x$ o^ָǓzkM bM<"H^ٿA:unh%;0P6$O !J(Y4oܲc5{?;v ߔ y~k'mActi^LڪǹKyTZ-CiC}faЉޱ/%ar5Sl bA>/J1V?nYgt,ݟZF E7|*,u>P{ 6ϣRC46QҚlTM%Ѿ2vNv ۟+6?aS֧Qܦ4|H;5-پZHs<}\t)zjŇ0c9ˢ}# J'Vpf3<6CrXsI carWTF ff#0r ҃ގ+.2,<ϰgх_ڵ$V5.ٷ ~3`FՑ[G stݲ58:Ρi7_pCrg71&.vP[\<6сqYrLh:KikWQy z;Koe L~#Ĩ1*4x<^wBuٳstUˆfj͵wWGYo5D昊nH3!"ˮ$HP'y6l,\* 5Xj.\[!:Q2UG\}gjɆs?5iί֕0 T8'1;#Ys*2~3+!XlU֚\vtx(òbP0Of` f4]IƩqjy9R:R:%^FF8hqS]|C:6XmnjHqv mJ@8l]ih,Gcߎ^BۤeȮ,e+z%=uShGqa?uL2uGY:g柉9T )隴ngѠ2LaQzk3ܩK?ܾ_ʛ|/ß|SC=coZP0>3O u:Jx*`Rvt 5i+z'cYFp}wh}8x֬0^lS9raKCu b KS{{9&h.@G; {5|f BTs{9{3Ek 1L'N>Z{[iض 00Gy )3| \"m~Cgk 0rB [Wo&Dyf-l$169V#!%{f "wFRy<%n|al&8? M|UPn(x3uFkz<(J8ɕsɦ~ ANo,rٽ1ڳk5O،pܒFAM5pxO{Kyd3ul:l3x:O{Jbo&g|+_o=u9g6EExuɗ{C6^t\`9w}>QsyѸ~G_^m+"Iy/? ^[`80{H|[!CI'ڐ_WuGW.t?nw~÷/~/﷿WW^9C$XkN`ș-%UuL;  %>֐Wц hy “t]:a On;LȣZƹQ[LJ,GtnW?5ūATna,)xHˉH KI/%.~eHZ[S6Ǻ '1bX aq'=^2,.!RI.Mf0!c8SE`vO2fG޾9/mIel|ȚS|JEϧa!Ͽ[!t^#zmfXFqc7tu?5\rLs+qȵ7}g:6S 㜼38IBS9dO!́JаN#.b346 ҟ :|E3^(a%C|΋k5Y5Q8o꓏S?۟C#?KWo}wdЁ)G5g؜O%rZ^bwteRa_FԘlw26W'~YGbLÐAk\Dk8(33,]`UgH Kkd8AO kB*7Ch6Hb ?`|p,&Uϯs@m7M*.O6S1y᫉f8O'یI_'vv7O>}~T4|L!fyeȧ,yYRP-7ssD9oH?cJ3 ފ}"t{+6-*>VPyR1R'WMF$N$gs/puQ^\o?hjm%xqYGmfJȬ {.8=/ `gT/pvD 59rs.8+݄(s>S|0k.gM{Qq+$cS);[/r<ꏭ n}^x+_{Mgpz~&=1tDK.|*b| 1Qp f!G\ :w3"edD.~RMҸƖwܸGWUFŲEAw44o^9aϐ\Z jl{ ++)Z)Xɞ}X%Ajܢ k'Jh>w濻g>{{o|o|_|ʷy?z{)ԡc˝#`ٕޤs[=.cvliљb(/@R@0};Iw,/4FO~A#UI $h.wGe3s5"}as”(' *:`c U=ӿhg+,M/u9Ƿ"fiv^"ʻ\6ਸ/CGeRU9ָV0T*, +uEIp`;bq=9Ń($t HLX%O7Bbʎ5 ,~I8<ְ'8R}׾tү|1e%8?s{Ӌ'^O'Ft^rRs1U *hTj,1LjO@pNp5)&biUr}e1u:J[lg,øpK:/+ r>4́^K:h=E6Y#1Gj(r L'IY9q5w_P&"ٳC3d­zEO"~zS*i\/F (Dž\!Zmak uX=1f;un_ s;Qg,d؋'pABaK/'6)g6xQhh^>'=O'5rxZƼMtZm.@6F/q,FFX!lMsDn',W^>(FPs˅,3sZRa<EF쫠N ~!c6$}Pg]U,jӛQkSf0=ڡ9ř@9.YOp 9Ԋ>̖y¹&m ag]U(|dIZfX91wa=-=|$Yu lWձeىy Bh!+rKQ&# OvZg&.wMN'屩ޕ"e4+3F-W X3 rr;cUK9nMNya?㬥Wn<*}_\g Sag>{?uf_K!}xkrժޫ?׸eryXC. 5]Ϟ▰e@֣]zspEXEzdrͫ-K~mfI:R΁$~bL/< m%NMe1RBIFH: k"E ۳z9ʃwLzN#C +z[ؑ'-a+yq[PXSAzRb G27ȐY=H8i[.. `tn#qo|y}iu`χsZ1ų;}APLơ;"#ʜEi( <<6Ӳ\>'dGl'Sڣld 1r:GHSՀO uLw 9+ƹ&Jŵ1ҷexݍL{<σ[Y͆f=4*0yA<[Kfr{z6,w{I>ww~o|ۺ^~k_n} KnT-s;'QdSOOmið=XY`ݎPQZOڪMoS0n[r60I]rh|lbSƖ(?!,8p1yVj|h CSck$nJ=1prЖUzrO%˘Х]%8_R8/1gp#&Cg٫+]'x67gy|tw67v:Lqhf22ZͮgQ|ZَFl4r&N;{u&F"3+ybbؤ) 9/=q&^gYLKҸ-Zd|OBtSaXz=dTPSYـѝ`G R\U~ˎG^El@lٕrPQ˃V v56)/,a30s ka·l25dMBTh\wXvn%# e O1WHT^:I6ӵD~—y ?6.$6og{o(%y/!3>b i-|#c]b>πl1upZ⺀ DZvԙ`63# @=qq,`΅u&J@A"Q#6؋ڦ;JģQ;n8oA]w]h2I`r657^%pgC"GE7NdλZI׸Z5c`ّTq刷B1uO߼{>p{W_~ C?[C?_ODzḱ-yt&gן2 4SKPg@#$ړ:AUB~Q1Ǚ R퇊nLQG@bG3w]%͋bClLlwNe PM' ΣǡX)kxc^^>PA[N){P7r2)'k\$ =mS!0?z@X^ji"ւ<+n%ͧ<3Byރ8-fW[2C_ZyNdU .\>LFB0YvÊ2CƁf`ԤbM/B fF@(D2>9Aϗ+y+|Bi SK<#c,x1O-3@O? >iVwgy#xד2$wʈxZ׬ =ĄA^IFT6sかΧn5;Lb\|b'Mc3gT ldd"F']؝ʻWOz 2{nxh1YN`yM\+<A6:_Rzn zQǘA`o?>^ޙI4soWh+,q${55SaVt&5?Yx Ε F Ȳ:Jw67J`/rv>/'w2GYK_~r{AK_}Cs3FRHV[eQ}/y(Ӳ+YΩ5- ty߻_}5_qʗr)})6cq{Pe7CƨabS[Ÿ虭9\IoMaK~^o}#;=2G䗼V?3~|{w@[OGThU]OHK|r\L %$L DEaYҶ 똢0 M‹䯄Lf<X3h\= c/BYgxӭv׉Y0ZVClkrܛV+hj2Źj;`؟SE ;v򤀅_Ʋ*vsTStѾ$SdĄ.nWfa@vfd(Kl{τ2'ѩ9!WG cY]t|KHƠ5/5 WEB(` ~EQ%sH͝@ a["l{g6*뎰:an6b{V_ɢ0A_c'bkZ֝-?_F?x1 +s 7Z/==H'۟c?tr? ?g% DN3&5rV/N\믯؃ط3ُP׃[zN[>`/|_?{Q;ͷnWbOSϐ|C}}ut+2CAe _/Jɼ~ V.@]7\a#'cBcC 1|D8hyBⲞd=ú>ژx7KeX&%( fg[Z3^DSLN8LUP52"9(ڈmmsW +\ 0X4.PYgi9D4biϞ Wn<~Wp<٤D{U^^|^埽Yޏ~^K$ʷɝ,=^s)% O@ϮXj%Ee* G${H͌\ ~DǞ* Z'+̄J-$rat K=Q(m`nGM'&,|z˥Xޡ%CYWgX&1K' 3iE:C;Ps4E<60]9 ދ2/Ob9p DOşn>RY  ={u|ӌ?ᑨ\} REzxva xA()yR9I]g yp3t k OP%+wsH1y|[: +jrNxjݪџ8ZX5!麯Ak)dC ?<-8cQ!?' bt[pq]P"> ݘHm{oX{qTi@0.?*߱Q{X5k/B>aon8*NBw3*U޸$= g1#P_! ԊߡRȍc_7,uIPMu̻uS<Ϯ8 k"'Ïn_mfxO>|bSyA L~ccFvzL9-aaRP2Fkq>sml5B[|A޾[('!z|2~#yQwJ9^$2Cࡲg&VN/k530㙤V' <}~ }2u7\#;_x /KWf&R˸6hz}qmPYߩ/Z1,S?VI)Yt;v{a ч<)iΏ&szƬꁽ; \aPDlz(18׺+EɅ Po$}{^]gX#ۙ,xXޔ+B^~_Wh92q}DDZYQpV~z&xa{|m_pgGӻQ8?jxh:l-}rԿe!z {ut49oK)Z>o{;$9WG5A -slNOk)ܯbw#/KZ Hu>y_}4v_0zV/|5-CR5I>H^{G&E>tIEn;cLwF"G\2xfp ` oHmW05_ss*wr0{7b 2, =`nr@q];"u3 1 ǃi;`}I^?]2&׳%lq?FL٨50J].ິ/ PgìZNkkqmv3yu%eԦ҃gbB}^X*}G8<[\㺱OȒk΅'"cc[-'PchDul=.\]e*LGlzp6p @;],[+~[ 9?Ӂ̈́O"mMJnryAޗkv4dLe#!}mOPk}tyƨ osAfDyIS|]?;?T>!_K/>ߧܪԐ7$U/g]򈪨?0mv\3+4Am8cԫDBCsk'zT*=73a\0B{M<|y>hc>0eX֤b ]<c$ D=dʳITg=#ɹ$ӄρ !LmP6dt %>QŸ&'m4o49R*bDj9r9`.R\L?PB&mpy=<䚸egG]@<ιu_.I|+́x*:V6$ M*H\uPK7QB>رYQ8xcSd1ScLeURf+ᨣ!1}zCV빲ӬdHmnY{:e"A)xhWapHS>~o'_;9T|A+~@M;<ٟ95FǦ0 cSf_#7$"f$]}Y. ]T^N?8j7@|#L681*A[ xkvWؓڲ RŴWƦT@Ƀ:Z`:+pω y~~I~勯?7~9ymPQqqb : -sBNc-}Lc˳f´a.6ģggX:^7SWbG])sbo~ޞ|~֕륗nMI?_7>#/D`}Sh|dݿ+Le־%< a=4pq-@ܖdc:}l_B@N-zf!2%#ުyh" Ǧw>y>R[搭'CRbܬ)=W=~<ޮ2gMc.n {nȣd:[^HP.'w}xɹrT^\;. SeN};2&obQ?ބ!Eی["e&znjܬp^UJXBLe6<ͅү}y=ڙd-sjJ&ie=%f&n=Gxr}ƴ4LxO},^$$}pLRifcc,CP ĸ[b&w+ׁ?,ly2BJ9nو1#㊳A027V"4dɅ-ӛj**Eh3{)lD#A)߮ln jmfѤfolYd~ބ=;h6wzCM'N}$] {.f] 6zr)8E`( ?Ծ9֜wb ҝ"9T[( r`r%XY\F7eYiGаvexR1a/ʷd=(jwʗktG揝=9 IDATx'FYiP̉%fv;A{7̒s#One$p !0uu9Ɂ@S ak;0j~nDB &ofI쵊Ksh\ؐc22K#獃`{N#V32?hGVs1|w'9~W^JР% %eƸ"]65cC!v3Au_;ѐ F#/t'aua%#@Ķ{Ju]93Znd']'O|{?GCu~(}[/س5] !g:YЙ0!a o)Ԍ3¨$g?`8%P'q|Gĕ~0 |y>n&Z*gRN=Ex2lͰp=gfu[51gDD:B:43KH 0l1P9ӤɎkbe0't3h8itpO~㛇?1nk*.!r;:QLN,"3߉%~c ʳ);!z̳kHPp>`ܖoO^xWoo۫ow_}s__?_t']G>o/?_wys ^)yKX}~d't>~rBzL]T,_L>D\Odط>-5 erRCW[C՚ka*lWanh%l0v~]8sRzhAA.C'|;ӠS_ksJmzh0ujx w+ t]$4&Z1VT~>ܸ ?Vkѯ|Pէ^ CC n&JN?9T(A m0b@]'j$vό;hE [F6kVA8fߡ#忠}-_ {&k k!LT&w2ȯbFpGV tj]?iLAm#> Az1dc8e Ğ2jI:u;:&st7ew9Rc A\.`G݈pG}H g#(J`6\sx  >Os x]tEO iXB 1pnM(Jrw:tQ%'lH.6r~/]f u8p!d&)Yh%C ' r!) 8ossP3d= aSruqPs ݚʻO{G?ڛGe}sN&229B JE8`QպtY媫NX ]U]F[VDEƄBB朜sz}뾞N]}w~~{G>gA™TY/xㅏ~sz[1ks沏~ Q_G^^\~'uy{>?|[x'}}zG&]pm_hҤ[T3dO|#|޹H~ң/}:c'MoՅ=_ *j GOz#;&ZO.ȽB4pV˻c~}?f[vwk~ {/?Ɵ<|.D<<jVL9IiNHtɄ~KN}TX#`n:r9G|>>'ޖW)ř,'Rɺ"7m֓΍h'%4h; :cSءC}o$RVl cia0A :wM^CtJ7`cl 9m";X8z-xuc.q5`S7ଠ}Y(e :|}B,ŬͫÙsK<̑GQmc8ƆIwxfāvnשԟ/VL!|[]2Gƭ7kNw#n>_oDXbCugn+! a,"c2t#YҳKF#=$DWT2)9ր8Tf\1_azQ\ fCJК#mBX2ξWA_.~j,y ܩHw*Q/ XM쏴C؎ OR;NJx @J#'Fz֊Iw`!dUO>Ό)Ꝋ_ LEǮYqԸ{Hr+DsEap: *xfgg=Qm1ZL  ]B!?%Ұ`(A ?nRڡYDxh O)vqҿn  }H{s|s w<2CI;N:Hv[g=mRkΩ 0@1jQwLg^ÙXG%sH{k"Rh@ClV QgGs.=1Dw1x'94Kqn [q6U4&r]T~SF܈7$[n]tôˆhɘ꯱mub (mc:}|`j ֟jftg0ܱ$V| /ZW>K&ϟnk l{j]y \\ǟ=MH7(@}*]~W~,{_Ͽ{N\U|'+O- `|'>~Kױ@F~Sw'zE@/_"gO~?z%)orsG@uktyk֒i{ӏ [z/Aoh?pȽ|ޫƫ!)z+r6c7{6<*=ttQᤌRvNz$; )غrĽ4夺"\Qnڑ{m~G^!g$[p1ܛ}hmqj&鈲b۫W#B)Q͍~|9HwiX퇏ac֋S9J? hK4SR"7 l?F"-?4';al |b0pQ=)Жop\Y1M1 $NЍ1RD:wi\_=I7 ׺p7z=Wy/[7!ꑓ{l''5a6sփ<#"Sy ?&Be`(a4g:m]pٓ[Z B:[-kӹMʃ9`+ /oQSy?u fmy,9472n7yֵ}ڦ ~,zD3K*/ xt<2"NDǒcVǩt\Lpz G햭mݖI&2怋wx8rrhV>:m 9B ujLK:@\Wێ6'F1NvޯD'r^AX&P,RړTFR0 Ǣ"ۼ))G^tcGO|^gJo7]~z+>_M_S?>߰|ޑngW;gzCMPBˍG= En@NVo_|LT\,-|nnkޮbmPs>Q7UЏ[?[nަ}'._^q/}>P~G߼iE>!_m)K,¦r\7#y=Bmi֩@h?I=&ejhp+uZ> )r7#f(.i=ִ&9?q0lF擔A[Lڨģ[VV `훻|&t+zHlḴ Rr58Ģ= ;- UNNֵn3}nk4"kBclLj>N'rCբkߣrDz`eŮ ˹UO>15E*a,kϧQ(+rMނE֍G01}9Tvwq^o|ߏ> ~ͯx+/!z}%O_ŪSnoK?tKzD7_aE_K>UC>|~;^ӗyӻܫ>+_tJ>=u򳗟=뉗eϽş(9W~ׯ}iz%a/߭zy~ݯσ<˯u\xk^vSU>ǝoAߪW;>pYE_g+쮗?q{TUOL|Əϧx_пxʅt&fIKdͼ8OSr3Hj z䫿94X/HI@ڜ9MَG jOڽ)تLV^PEpb!7S[5d#+n<̟5q?.U]:u2#q!4e$kCi}jg+}AGT4K?[}iM>8d^z]P Qp .Lɣ'K'ɲ=D\[nӊjiRnll!տ7xsTZ(##5]XfK{g!Gjo<q|'Q'<WQ؞FG{&3YӠraz[*V8$`;rxo BRS1;7 SPä4ؤl7vr ޚqЛ \69zuΈwd_mǓ 9"<:8*pd8d4i ؂vƀ, q=TD&TNfkLѪWeW6? s.Gs0. DdEc <'h?\\1$6'P#ob8;s"rmϳjgl6sgS7Atu^[zޯoMzK>i#'/_#?ߑ>gk _˗mGߠ3K#}qx?4@>]f=sV9sy'R.^_>u+Ыoܫ|!3;ޟ9s^_9kA*o[?py?|゛^70^{.Wx'= P^Ի.[~=}? Rx} Sv?ψyy/ Q}{~g./\xuOwi zDhc,Yg2&۽Z) `>.x NPpsdZ{˱Aj VmCuNyH/} bxGD pvƪUgs4j.0ʭlLK݋mAvxRRa!*nhHѳ9 fL%]m&2Hd㱤vWڵt:P&16i#EՆ=TC) O(3$37+&6yg5^4&SONd֟C/9Ʃ>kf^aa Eҵ01=d Wb>1~Z{kd88Au ]ȬQH=,@K2z32ޖŇvMK:D;n^oՒKㅴ1pmbNAI: fUukO Ɖ+W#;rp^{:}$&~RBg&`wu e9VCYp~`T'1簓ւߧ4ٝ^ouƽgCsпw߅-c4RekxD0|FNsBotl!؅junq#ޯm6畡jNŨ6.r5;1> j܄4vlR_ʠ6NMŚt&| ø\˜=Nj\&xI%?!oкI)gN+ZZ\`.[\>>M'=Ưh,w_wsXG䕑||.ew,;|_cۺ蕏c&7H:oOOuI݀}+!I y1 _%;۲ҷc D6Fozv-e9fsqRGLi1vzAFX %.~Ĝ㋋ޞ/f 밣Var)&c9*XSOJv3u]w!\h?3oŇjZ u 8@4wc+J g;}]MT7h}*+ Iekjyĩ;.$8fLj:xh IDAT[qdip6X[\奋G_/oJDŎ{lÖ5)aBf=Y\t5'nH)kx{>&Zn1cxKKxz?Ƅ2Т7Z.f˹[ i][2gy25YoσGp<{z[k`nFK@量[xホ~f1youqn{){|! - R)h1ZݸM@} bd\1qH|d9d^L:_.9Y'flʱR`ktR_ږYZ),KϢ&z̥̞o|m d5 !QTQGu˞BFߌu]Qaa1/eZt6Wz6rnyA>^Kiq )[z@o\Z[& Nۻcֿ .Q3b.;0er6XjYTycR̎83o|^ylݼNO{/.2Z}-\r,|ǫV ]@Ozm^M.AxCuܶÏc>_W~w6'Lxʼ]yVz Շ<@Y#Ez^{偏e7vW]̮+~ScQSZնOٺG2Wou7>>Ode{׺prmC7\Yj)LIizx:r)C+C2 <a-s@;/0uB V* cBXĽA+DBDN41-9\c+_QR#6񨵰|@o_kNzUn"DTGndMY=Nr8EfrkvVb'"].Ub% >Hv'kyQ&4KrފcN?IE'fh 66B{qK >QL=l Z+xO`ϗ9re㐸| i,mB\ӗwXMz&;=*v)й0fnEÊ5ƥslcݞ|1Y-a7;0=}$a1OMA{ࡋ mMUǎE95@ 7і-Ys[9JxUPr]OImZgpF޶b}+(_ K $c>6~Ap֣,@XMwd\}Bv-`Z\ku!ad:4]Z(:8e/\sދ.{7'_pL#8)|Dl.6o֙V?zbR&3.>{F] 7*?]zo7Sd^_iǣOՇ[|##c7{?GDU-~*@1Q?Z&wٲnQjomn5h1*ۇУX{J=<0PKzXQup^[bsRb)Bx!ޣ <:|v)]/>^~ϩx'|R>~[ᕏw A/QgUc*#7 J.EVaa}sPn?=c:Mx)C)#7$'ƛ>hpXv}JNqS(m&!KbbK֍$ThM֯>Y!өJǓdo ӟL "ӍTSȶ0hbgރ3`9R9e,^QTiz<`b5YfY̱4y ޜG]kz DMqF5PPK'"n,R5B3}D; c^؃iVrA]hmS+V:)i}1":֪u֩AF #\xs]1&oz0M?mQkHIV"9=dtg>ԓrH}o:s|nivKB=UUUd5.&!RCelrbHFA۹kKn]0XN_:.#W1j[Tiƭc7xG8tU6 0j_I<}ɺ ^:7+x iu3K{C'@NAǶͩ h;n*98<&uvۻlnvנ9 i/7BuYxZ J<f8QnjzH&ʼ"zV|#([Tҏ}uE>1 >Y1OA iiYw }#ysǨ9;"'44,ªfr̒Pil~e@<)eA'M'%e"^2:<-a]kǏt|XL%O,W!D<@L|0ڵTy,O2%r9T^MbzMSk"Cimy' +Jt'+G>ɬ)[kGUAlE=밁2EL]7gRhB4{Hfsu g%:c5Fp<-Y-.Sphw0Rɢ^{k~i^>y>9NRWw/m-k0z/d*bRY[1Yk6H%WV_ҁ#bĆpk6Y}wݵm߲7^ƓAZ!};.}0u"ҾONW?Bh?|Ts & v2(гC{y[;滱$YOۻgh~9ޯ:A9:GL~ru;ty`l@G<715Ccv}0~HqT` fĢQāAIg`*Ii;2Aoϑ`{@!p̹etIԨi2F{j}d:ՕY'?~pNYr Cu'pg;t 99BY*T}̯'@`p4 #VP…(9F6sc!/Fρq3ҵ-8)pP<"/q[ƌ(;sߏ&yxv&I&f@~LC@(~Bq)M=_8֢׾|Mi{ Ƅz¯Xlä~,Xe"`*FA0eTqMX1Usм-Ъ4Ѵ-.vm\ mHidã13Q#YUM52cӵIAo8ml~bAm;m^[ln`N ¼R= &Y,A-%݁U9|LI1@Mxd=_>ń.3>{@ O? ~c~ƃ5<-=۲a5=Y^uSN){/|H_ax~0Oˋ粲'|zg K?闿=oN:92.m[_>e"$봪knmɈ@V.UD+LQcȎ"*I!XU;lUs=U&Xc܏N=ia;{<߹Y;{rH&__`pY6j$㆗sj h/[(gB?t\2$񵰖<vD3xs.|W|7*Q 0"f=D 1BH`jI]vƆ/8wHI Hrƅ[~H³_uQjK/g\~WY+ ش? 8Z$_imN=>K?B5/MiѷH)W-$r~H zr|W>BoZCoW ?#Sk q1J΅i75>"|ΓaL]Qu dZ=^$Z,7Ta!Vޛ,څ:3蛐M)IS;K{x!φ^䦓>C7Mi.7 mKN^VNp&ml B~DO[4t5._@d?ׯ'GHʈqbG5w1yx缲aѮ/S-8gp8scf?ZV8>8VF~-J]]D9\m H35Q[;M%ha1 _أ_>3>E p:O|#/?~^8! HźQ/V'<ǟ}5y{e ˟V>}~xq/MHx/|v++fw|ϿDW0hxR5H?wy_D5\spAv꯵} +%~ YIc}YghWNY(YT57EY~IIPatI٨]jH _ݙN$w1ρ@*{?o7O/tF1<GjF dqؽg 2 lu[8\۠~rMvf\XOkDHW+ܘ0.GaMj7ςiW7UUE$mc"(3hRڎF^#Q0u t!AJgjLʂI1 `ÕNEYe 5w98 Zc&JȔ cw%cDVlƞ*Ζ5kЎͭ@4Wg^Փ󓎩=(e=qi=x! |@_ nm. m{t^WWp[~}uyRjz zǯҷ|/s_DZ5_mVw\ޤ`|~o> ͕e˻ noEU]>%O/RƷ{1FYr]?~Z8|Q[\>/7g/so#_t~/| |~] (ٽz+>rݭ}y?x<Ífߣ1hNNk#x-M8<1J~*zYPlETtwFI2i?эvJfe^Oc,ʭp ^KPH< ܢS`](N5K{ڐv|{шQɞy]% BWiz.k=+ ̃JxυЎ3$4J`wÊ0- Sb]n\8GR5YvR 'n\̻9~@F#᪠['x@kR뎨=$ޱH{Kjøɻ3)v Fsm|n!`a(=Kw?Gj*M )VьNCk7I_O^ 7Jpv#?דXغ  cw[`!ߑd7NrgA0ȷ94v0T`{$` !JXnJz^S  u}FZ.ъHT%1V}UW\7 &musfK0t^8d5<c7 *d%nyB촎p( IDAT%ʷT x6VX:2D?YAɣ[|H巂^W C/ΝX!(QvL"7 Yj._KbLF'*JR /~|NgϾe^~-x~7"?~L~R}W| Ǟt?;^ç@o/}緌x7_=ї]+;?+gc%Z7-t;OIo0z&1Vyw-}IY}.= y`$߷-,cdޕz7Ɔө[Yjy3x3?Hś]ر InY%^bU.=8- IF.jj$ȎjfYiߚVrR[?݄u`P􁍢"4KnπjoeOuL t]W?VenuBELԬ)t#a{lTe?3_GvO%?lZ^h0kf:7v+ю +*橩|N"$˹ӵ@$4s`6%M;FN}5@}r{Nt5Y⺄9! VC;Ip v"3=cJz=:9Mͺo) v(yC@v7 jf尷}sW's8ˆ740ot5.W8cx|, k?s*7N=x }. {Ko>3w/_W/|яo:Ǥ')X_yu]o.3>T֫$^Wos+8/~μjr\AussN!m56º$.`{aZv*쉗_o@RiRIJv1Ă)ڣ~Cq0nqi35@ocF}?k`?l3ʳ(}4UٟŦڷ@[z~Cv;- 9kg &1}|vא$yC|l3uaxK/_jFZkzۚ 벶AVvH7p2Cb|L |\4 aWb]mƇ]ocGT;f)gi;fFR[= kG Cxc(j$[>t d:&N&o\x`\3 8'!TxWU`:6Hʓ:Xt֎B۶mw 3Ix68v7;`Ǧ$wQUVXC6w;~,7rn*_ۘn}w)&Ex4^/*{@\Loy|۫~/~g CN/y~‡)Yz>;k^_WY_:d92CAzcz3v;o|_{t?oѫo;?D6m=zj)Bë׾^[>蛲nVr3.oy.ߡǫ> 95ˏż>xɺi?+@y?j/zS.o׏2M~*:0Ik03#ӽI dF5jj]~@:GyҟQY!dr[3)زaχd3oi_Xˠ&Cf.NM.ĢqlgY-|;|1/ϵ$Z+N`HήV\:XL\!9/\ịrW0E, ?Y%)Igp&#J\` BL>ju*qs$]TX x;@ ͇$|T?3i,ɑA (o݁H`z/prebw=lo2S訚kTO=kⰕW cя)s) Vx+W<&l :4m7/T!/85ҹ:ѯ=[s!&/I\M]5q;"tU`?)>w~՜^qR oŮJp/X zbJ9G%|h`sun-I4fBzN.,MYQWh2{m0 )G #"LJ[iGĞCCq֊}|ꠁѷ_ tgsgLn1t(Z/:+g,: +¬4.;&s; gT(z:GǺ`o߯ ]-(CZ]|vywȽo{|DyXe?JP0{4| 'qA; Z8+x/q*7#lwD_6|e[>znFU emn17~m J}nROv4I]W ?k1y,ւ?>[54cj5Dm㮰ceo1s sY m^8l0|ڝ%nFЃ.R·*FG*Bi~oU,Ne^kLf9zHII@,MΣ2hijn@1~D1o!n+ͫ=֙yO"K`'|W ?0;Cƛv0WG"aU躼c~}h4u7Xw2fF-`h*v?ܼRp327"0) HE!\ɦ5&zwS[gQrq6GupNL07Yo!9wŲ%tskMcODc1j\HzDsqx6dձ䑃3yFY2CMWҹ _ m ^]n02,=ls|,غ ]ǯAs?&藟ui}Z`E ϙ#?D0tȩTM\rbUT*E5/쭼bF9~tJ'5 6)1=慳0Zik!Ru \ʸ͞鰀WCx E&ƩpݒY%Fdk M]mk%hA5cշ~0F*Xf[JV(R{aǂQ-Xyo泽c6$i1=#O9 >H!ggzV,ul9F4VC>relO} 'H\]3kҭ L րŮC{>>%'e+kW p"g0< pC(d!';#؃6fG'4.`w|l7|Ʉ-^p#9b9fNwiaeqvP506g޶5XYwg|J((wvxZ#7:')nR 7N&-6Ԍ"$ȃ+>Whts Pۜ1FCl#ZsA/ >#5|t's?PXܚ>!3nۉ<0 #;e>qG ne2M9{ZU5@mG~Y0Bt'bѐ;Tϭ',rtby F<9w0M<`2 0WM^iIrf"ڍm2|.g܁÷qMRgޖBn* хv7 ߪh!ՍcYvV]hev$h+Nkh}ԉy Z3TΙ 0`6g?Ce0HHkڝ" ltg=8nޢ!ym&X(XmR{*͟,CsJ(3 Qo:ôg.JK)\|4 !e4K܆U]@6F掠<,<$tc&wh(7208YU`6aS€(5Ww:FVgTF /2=kͿ`vp9pYQٮIJ1OkH±jc"sYμZW2 qLL,)1MC[ 6D |xb⣽hQ_z͌+(SdNaș\6- ϡCnl鰏BDL_׌^MrbsNfd1!jz7x~ݖ\!ըrt\qKvylrݞFuNÇNINɞY:oImᕽm<#~x'&?8 (k: 4lD]eyEraNWd;&qq$$;hߖM8di }s56ý}5cdtp]jm|7R|,R˫8!3(Σn{su]Mfd11(Tn.<Q=jXG:b;pNY/9Lduy@ ihNL60 F+4P2rI¥wi i0 yX7%/US 6՘pјc4q]ˁ@N7 yqoZp <#Mj1.bam0< AD&g{0.ǴsxVq=C q~#J^EaL7Q46֑s)2(GX/b@ f5:p876Q+ՍX*Uhi'^rx xqSrV1D^^Q m %(#1GJ.(I87'Xv _XX t^> K pD7i ec[XdqW6<0Hc4gdákT yz}[Ӽ{hWs櫞OK'y۠m&NNSӨ8meu"CIF_ؕ[_GZ=RQ_^k|ܙ.T>+օmW&C^; I(gkH`ajwe)|EVvkᬢFo|U{6\}j+ RYy-. !PWVLDqp 9sv# ݢ_z 7˘0kXdo,Wv5וP_iomHn۝z:BۭŁ\Κ}l;FLjqp#A͘Z"R/OE08Q"ч=ju3\n@HIcM$rvv:M_Id6 H,򰌞 7_ȑGa>|`bB0#$SfL`ᴼqT6]$_IIMf' K쉃RiZ.F>@;Ʋ1|{jzsw썧(S #zY} :䱒؁Ǭ3$GIܶD&EZnZDz'L{8|t{ Lj"f̓<9d-me:ի-T[zT?yQQP;LSвDlmOP,0Bbz3|ߞE3q&ȒҀ#RT[5 |0RJ<9H߄7I!o/4إ1{N@05ߝvf8)&a j>RUN *ѢI\bGj`Q 5`mHxf b7|aR83#9[H yъ+:uw9JtVMŖa9qGi%|҂koO& IDATV뺃nj[iz<biGT8) 3GkT.t+͑O!I.51hL3UEEs:0j6<޷҃|ǦȋV Ҵn-16C[uRأ;!o-Ix@h+uS, ڥ6gmI GXB O]Y<})Fpy?kj .wO jnM: K2ioK2o+k,66Ɩr>}-XZ_פph"H.h|EPsMBܓd(`Z1lVT0l{1+3TJ^>D;N" v$s:hpYBsuV:axţ<7(|kS ^T6v993{3@Tx-s юY랾6!}rǐvѩR'/aUmFd C7cTd< 9uweDV)hX+5u0 k'kr_^]adN:9rffv}n׮ʴ)N2ۖ\.~zu-( _gߔ7lK5SH +n,ug=ɣ&=Y8(&Қm#'m-?*|cY'.${r o[C(܀݈}Er8=y¨棷#r[5Σ.uƆTD;h~mOj:cx\ ilm늺A`Oз,'%eu4Z] I۔y#sf{fͷQvԃcVkDrDRmɂ rԎ'2b3V;(R*QQzҢاz;^9mH5F; 6iH$Z>hIÛ~W&+h9M!SF~RLfa`Hs ?z) b ˃|4(372Wپ TO  `°ŁajRa.jD9xd (`Q]jθ"ZG_XiW|CTbJqFm/Lk cb.%o%)yN!11fW)~ܥqZ~xL3 I?2ExψHZpLox rDH? 7ܴ&nZkM't bDߐI3t{$eBQKA1X: һ?"3:܄DGZ~Xxn} H /&d#S5P'Ki53c]<8-p5b|NLMk.VOW&fpOd}T>h^~[s/SX*_DN軡Sӎ]3s'yx~sV;c چ Fɩ5R5%'ȽT|>:R(t>J_5MSt؁PSVTۺ>!*ahHT9Q5X8X(2D}2}Rj  OIk9Jh[ 'S2SoT]1@>{nזRz(GE!pZG1 ҁA݊c[ MQ94RHK.߉bp2)>TVf+;݂ ԶÇӒcU¯'o=Vr/G* ]SebFv~ؗ]pwSe =`"jl`>mjdow +5.iagM=jvp!u:YWK;qu4!KSm8Σyp_gt#f5.ޥُp{c¨Dc`j֟nGw,2(Cm/IX߰n6tkЉ?A'LR0R*M4}`ȳjq 5bդ9HOFqRNĺkeR[7==s5&姄kgm+tye `~&=0Tb?L9[#l>Q.Ewڛ ڵ52hWY$=Zk(2l)u-%Ex1bfn.kZ4F+EE.YH9{%'z)o5( أnm6 o{brFۃ*m/{hIQ !aɰ$ A$ ̊Sr ]J0< $K4䴻}_U=a{w=g336\ZU+F΁n6n۬A>?89BH (El !UֲەGmxX|=.Mܮ^sJ0)/ XnN()nFW4ku%piBSQrg'da'~J&Rmhh<7!JUT( /q־Z`*K^eV^{3 lZ'pm~@URiyrKlFKvw%:9CI G1 j?|0Q>,ݥTo9K+ʲXcX<ؙVy3o ҦXY+R 99d)c% _/NiWڒ-˾@/Vv(y294)mDUecmAؙ 7 臑̧f(&qa xZ楌e,B]0"TovPD,6^kWʪ4H:pŅ%!?-GUNM 9o84<NNPH?Otf- g&2 NlK6HS@iP&徂,Dp1JlNZcW-'X5IрmTT*0pNjtZB,sP`7ԸEua^>\wNT03u5 L,ЁT?RD dT_뺍QA1:5AnNE7|ȬںJwiȌnyPC{.PJo/ϪK"+%esi=Ҧl 0HT* a]onvǂa:p)zQ[KrFӠ{ĎHr&q4- Zp:HCMDFA"~(b Ha7t(`_7LZ!*9bh/f ЇKx% VQBss "lJ'_eiz؂BpAVDϫ2+1 lt" l02udxed4JCljڬb|cicW@Q$r 4U#Zd+ ѳ@Pr!YfHXN?@ =+{VHo2T[Q X5%8i{6l*pYZz2[:>[FkAi>"Tʗ >I%M 2jԥP\Ju A.0j/5t<E2<ʇ9|`1O{\ HkQKRжXHQWy*M/xPAŁtSxKQ'jib6n2ۂPS'dyCrAQlā5 QIO/-ȣBXљFLJ5UQS|`*4r/`44[iPۭϱ<>-!"n$a/Tp"paGt`A#.ұ<^%նJ[)/riyA| kh(9c֭J7*/oCU0C͌ ͅs[c9X**;}ÆOG[GM.UXDn*?]Qd'`ng&CU]5Tꟷp6,>@cJ#Uyxgj+06+*tCs?]瞣gEN`<@1:.tfS\?9ÉFrL>Ԑ؊ iGQrpMN}mT ,IO TsP] 1!UK> ,L[(Amo"g"8WP{QgZƂ@GqiF l%HzCnՀsF iűue-$h 9rxbH smtjTeFVWzoy ]wY-WP!6:qq_ GWc: k٠8flvY)"`VuOMG 'J;.-! ʨa_ P=pa#Yl#Uhhyd^-arAtҎ][~sr j_a =Lt\U57uyfДz̨|[9[F9GK>aof>'\v-G:. E쁙StVe.Ud. Vi-\lsf}qݩppQk &{o3 b > 5yE,C.&)ļN'~hT.ƮZ!pa&cX2x(QG8Jl5&̙zho3D! p9?)IC\Hspqi 7U >7ug*5-`"#45Ĕ }- lqCzh9']&(FUhWqZs& T ]'jAot 7 mlG^KJU NdzuǏ]5Fs@"@p2m p/TSu6msP5ldNeUh:I-ujm F] XޅʡAY^ /6!x PuuP8W ;h:q660R1e{;'i*GGGb_X&+<ܭtȿ6J{ RgY5"'q1Pq<A԰Eps6Pȋv39aӈ> ogvŌ+h׹Ё)mй-*Jfuc ikYD%HփUlU[EPfnG/HQ^*5ٽpOH^TB[]a(ھ0wKC6?z=6V{ 梹C "+-|?3ƴ8Xy:AF8jvI*fz3NuFe.5 aSQOm,z0Muo+N0sLW^̚$o<0ݸ9 06t&3t!/*_]mb+)sCCONrN"X"6ǁBcA|[ojsw#9}KGr@(X/ISSzVv _4;f/]QD#RKu䷱y IDATKElBD2- p mTmK2ӮlIzn(M*u䦢:"1ٸ3*ͷ` Ј`xfīzةrTPMhNP X Ek5{J!ۚ#nOwt R7v}Pd!5e jH7/ez; ; [3&~DDŽf󃹎UĖ1 !`,L.@MÆxzR2BhiHq #IE2z` Ul5K77S^&^©aX Q9t1? U6o7X I"!v 9K5 W<8~&ҴJ:>@USj&/ -4TeT9\K M":F_:&t#VؐW򤁜R#et!5ڰӖiYߘ> Lϝ V8G1fbUb mmPw){i"P` eoPJ;[YOU:ˮZ6}~|mOj ,! ]]&(n35~!0^ht HXo~ t 7N.5F1RJKs_3ce47ʺO嘭@ux:frU5G5+PoVũM7H͐ee萟bg41ZP3I=2K9kEhLԔ*Ukq+;TbB777:j:y5T./MQGó!Iu#m X՘;曣sqCVOnrg7kX Q%<́VUЌ5ĞN @/7Zx TĨ(-+5[&RVjAElW^8_vŖgզ)/tC84t#ѥ;tL>Vr722鰈^3=w &yQ %oT ]e2&V;)N>DimRƀrsq"*{27! $N#v9^Jsa Tf-g840!\ 8)*cќwuvOɋ1S m 7v,V؃ I:VuLi U87 my!MZ:6vUKa#RD`G6pWƠl(Rڷv2_Qp.?@%cA*tcl8\lʹ`1"[z4B Twc WiɎ.jBpwr'dxSQ,B>0`RRQ*Z9\`Hg[o䰭06Mo~Igc-N܈ƄhoVj<'ѹQ<*t15F)-i;@}B8Ci @9Ԧyh8يج:e)tzF ML6, ND`^sB䉈0b9Wu>o(VY!96x0PVM0AA#I'Z 26 xiB[ DpYҽEjl0^Jq@Zv2(h2Ԕ NWϼa4+pnL/).Zڶc̹WjFү4JG--@*#O`a94x!eIОcbIX:390ZZbm4ČwȶiQQ)(?A TJln\H 7%}ey_"r)NX0uo8(}!=#,JkGqV{ٕ]萵fnoJVcrwXqpfJlP\o9.bS GYNY+P{/"c'0s3CEhR#IYIIC&LJcGX;^4G/"8a2騣K_gc`#efBúe\y|VX <7XE.w9n&EYd[}mPn,vU_m~Y$+v`.:n9aR0ZETE]o-oj>O'UB ?)nN>5Cʴ9Ae1h̻*N"Tz@Iz[v`" c2@ nűR~TS^i _eAS). 4UG 6 f i+}1TSfLiNUoklĮA65q\ 9 Db&2=U^U C}/@m3jD'5DVpDl3d* O|3E(EA>_*\rZK((@rCu}^;Qw(0uO+{]F"aÃG+ [C&M'ȇ'B|VsC$2LҼŖ;9Öq@.D$nafV/2x%OO?!HNV6ơWyF %U跃)*cH4iブ};ȭM0ܹsl*veÉq8Kf-Qf@BiK}tH\ J\**"{sF%"!-GP`O@BEsy RUw8(jICX)rD*۱Gk NVIwiîV0)]&h oAjb0jDТ%8vGsS@D0lf*M[0C 'tstEM5Os fiqka sASKRn~^^(\!|䪶/ xOjr"+qu_=cvn"lz8f M&0jLx*ZGZ9= Pg}7nUJ߽Mp]nȉG٘ܳƬphD'QǴ&6' H+x/2ТVՎYa-4fJa&dsYyB4SII+aGG-y 8J&'ICq {yXͶQFtl4p"gSe ͹Y h&A>qm_J}Wsd[B)A(CdFGG)#=Z8k-/m\7_Šb6V*ج< 76;o:Kpfy5E;K/g! 3b٪*xo6 9stv㏰GVoLucp V9()G>.u;Ő*ja"#<+nX ~2Y)Y7MrPфTF;3|qM'yT9Az 7t"R>m5aB[J!aN>m)ƚɡU[X =r~ʶ1Ha)c*%i9DCCq,*GIsBENX!8ă:P$0!9Zv04S7- X +T8@çdoH Hy ֆ{ xtZ:ބ()b'I G#Q>bFMoK*׋2PMv_xrS*m0ٲ80.n0yF3hIFyTbV^&oTWm2 Ȫu&ѳ j\o*r078+$@`q8žP#h]#X.qV5D`6/<.nkcvdBăNP*1 _08J5mE>LJ|&ֱ)-hQtcfq+UYW3j 'IӋ 1|\tyb$?Z.ں;]V&PyԱSK:z")i?YjǝFqOv3\]^]ReߌlvXCuUk_3w ʇ Z32tkfPk)ZuLfZt2o@ Zlj] ™b+6^ J2ke/Ԕ7)ưj(h׋d Dx ( T$<&//|;+ f&VmA09Xi{RK; T_c#TXnba>ԲjKo@ҢEI:xXMh[BkW [e&+2Ɇp{-< ,,#@h>C'[1."T|dtp# yk>33iiI|@@ 0!mRdJ4 eR| -hiJ.Alzz(r`~6i ,,}.M:' ?+dJf μG>Htz跓%7cVhX G6(RZ͡ XN}e1p +ǝ<=߲&/d*U ^+z:פ;*j#66nreYZMNYE'cN5bG W{D@;p$%ܒl=URXeRH|/E:Ii -#(d>hἋLtD*AZQ eLF ǍˊWL`bvޤ̂ReZ=_R0Wh0POåJsM OHQ( *%M9PU!mS>uf-@`"痦 h[C/3>ra)G\Q!U}PE_YW@gjWu1.b4EV(l䋜ldƥ6=`{pJĒ E,uCЬ5"-r):MMr#{W ^=mKmܡbN Wp$v<JL2)[3:&,H@ys|tTqx1-'Э&#Wys5QI)=R}^?ă6~@gIQH3lV;ʾ3aF5av7.t]yƹSA*lmU`u[0V9*yrI^%&&.d=P)`1QȢڇ9H܌mn`(جtе2Nr٘Ԯ6ZɳrG;enFG "M@^yDZU׹G)W{h:+wꄫ_ "C3r< ;'Vs^Uϣ9rOyTq K! *.jM}+=@hT!ϓ߄d5o!ۏ͠\`W*2TXs+mJ9@L}6 dͪabqHQx'_L@j< DEo3|?[`M b11F1#r_aU}.E٨ t5m&Nf8z~! Q%[֮Di7ze;˲$[)59ePEӭ İ2GvZG_T욞53QKG5䚘ғPfrgFa(sPR!`OvjMS,_HS`WzG0nؿu4G\݋vLOѬe /`GZN2mǏt`EyJ  @0 @0 #@,@F܀` ` :` ` ` Ab2t0 @0 @0 H@0 @0 2 $7` ` `@,@|D/` ` FX  @0 @0 ubR#z@0 @0 @00 d ` ` ` 3 : ` ` d  #Hn@@0 @0 @X^0 @0 @0 Ar:` `  G` ` ``@0 @0 @0Pg  u> @0 @0 #@,@F܀` ` :` ` ` Ab2t0 @0 @0 H@0 @0 2 $7` ` `@,@|D/` ` FX  @0 @0 uM7ݔkK/3y|iY9~{osX׌?92=\39ù vd;FsRc4iY6sqensIOc:iX_` .f.~8X\*SU7~o|3vکiuI6۰7M7<=أifꊽJ+{+2,]m*lƮ[W<6m=-آ)SiaLFM6s N7NÙoE[oߊG@0``-@ƥ|ftۭ?GM'NL[mez;9{;ޑF=T=ߛo)2̙}ܞR7|35*M?CNm['67\ U#6eV;f&w߾۷Rs@0Pg`݂z}h~ƭiUzYgVԯJcfTt{M l׿ZmCp-XgcӺ<]l{^xvCv2uW?P_`AuZW_}uW?iF3oZn^1{-th`㮻ZxRK#82c5fj`i61?\syy;ӌ3Ror1O묻.SO=sz^;F۹3i$Η޿zwӲ-<(uB\7v\^nu?~u׎_ֽ3^[^ziZeUssӕW^Io\ht뭷ߋw9 ~شs%No>xElc1+/ǽ+;,/N\t'e>|睍6$;o;ghچr,i)i;sLKjwtf?!sw>:|_i^pm㏥ˇ#:Rl_3i9v+6~%y馿ܘ~=ܓv5춝&hߍ'|2}y.L~zOb/!{|%s=7_9G睗~3Jm5#k 7XlpMs9'ə8sN'xB:L4r^Ș^4t{?f~/7`5O~nb/ߡ7czXcC'xi\wui9Hp~;ĭ 9Kb&iΕ#/`l)Z O_3Ncb8C᥹o>O +_9 t?y=omsui̵ X SC_o[Î;_D'K.(⊔?zʁɉv!ϯ}i_w1v,3ԧrX vai]wM'I-bt :O0!misc+/ /Ͼď{f۸5qYV7_5;/69"ޡ_j>67lznSN95t҉im&* r3`x&7n;~X*~s"w%L^w]>& Ӯx5im nP{_wsMOφhsLC她 'q_[>*w(ɵf0\pDc de$%,>} 'oU֣g3^}ՄpnYp.(jyYi%]!`:n;8G;#+y͔RK6,m*7,}[kc7ݸyUV^v|or~xmp,Ը*3,3S43Ca=/?|w4~parK9;K/6~n3{;\c~0=iO'tϷCnS.N8K=|nsL G^7T^ppklw3x[_3՜,Xm|'ۧ3& J͘-6~mizmioup5̡N9󰓾ߘ̵m%O3/}?|dnzco5K7춹ȱs96oww_c5{.+k&Ssle{[~}ܨi[lvcbBf|(q,mNk6Uw {hcmy+@000Yً/ၸW_{qm ?@]V<;G?fCkU&3H鮻LP^f7SOn .Ee&(7szHm"~Ar/?|n1[2m,1>6g:dvҾ_{̡~p(9ộk>ƴ>>VYe3w\ \76eBvͼP3+ߡW^"ۮvm7~*`yO[~am<<ܣ/<[vmW`O_3NcbBܡ·]z_F:?Ζ'\Z-}_.xrތ` 6@'ÄxTy@?ŻOAwyfy,X|i}<ӟ,!oƧ/4*WCEt7'Ers=<~gKK- ƛ|(Zs>;tolh-fJ~嘴p曧/|wnf6s<lmn9W9ʫÏ<<\7~eRv`3|/ߡ \uBeṀcjïۢng7>]*Gs&׌<`yqf=8N~}o{!r^k=E֌p:7` 63OO6R,` 39kC_K~6ڝ/p‰C-B @2`JX@0 p2e+5ssl'?9!+ކ mc@0 @p7tڸM0 ][R` ` ` nR/` ` ,|G` ` `m[Gkn51X/c)MԌ=c_{^z)CuYiߛ撿)nS~QGY6ƠNZze#fp|/SlJ+{+2,`0-i5/I -Hz衇k._v9v́@jeH OC5_OwyGx >'~g=ঈjJr5Ə?6zG6N 8?;Sl>z$o&p֔V[60y(jg/9.ܲY e`j@s=#iĉ 3p 0?9/{vx}_ir͹?>7]pteSN=e}nf#i+6.O}*uY\s͕Zk,Fy8yƾn/0XWc?~/ȣsu<2839[#|$bz6bM,~ӹkVS^rץ9#] KQFVX6snM}ߋ` S~˷_Raǝ3l㶭f)_uzbҊ+Hϟ)i䍯eЯ}5mmql7OmiZh*]?%$,Kk:IƎopE/ ۧCXWx_*}s%_<]xEi~_~9~K{ɇ=ؽTG؜rʩ餓NLl5m0UVY%W{m?P>/=7>췙mʻ͸Po?]bqO~폽`Q6 >p׿6wwqG.;єc#|& f1˛㾄ܪ½xF˽ż.RKMCn6Em>-tE)\?G;#+\p/dJC G>W@KH+mo^VYymX.oS#Woujދ w_smVnxfvwqwCZzӵ^ܱLSyfm_G95mmh0~c'w?7os w8)WAXLO׃:~;g-e2 ^9ֲ9vـ,m_ Z )R_sd[m)oo3WpS5;e_)r4 svsy>_9h"MJ;^8uw \s Yp꫿EntÍ7櫻mPu}ߋcXQ@00% ^ le%HŔGy4,߼Wi-fgy&ʂl1__I?+H׿䙏%\JGȮcY ^^;ݑmǒXtފ0nܸn\Ywn%O3JAr|~WyioB^[ny5c+t?,zi6~_,Z? vWK>y/|vgotN>w]i-6O锓ON?|:[(Y+1vԆ;+(\u\8~zfKfsꩣӿ<~rmZ([:sUVE3rٝi>qϹ=cvuUj3ɠ{m?3#Jyp67 r}V[rvõ m4#` 4/0!;<Jȳ:,P7-q5yc'Ǟ{ K/kO\J^g/^*V{1g7O|; IDATWzqw!$qO=8 6\t%땿&\od= ~΁6q<^qEJN*z^6mcﵿіߡpOZm}! =XZs7ߔ~隼ٙ~sΙV]eմȘ1M#vp0 @0 @0vcg6ǟx<]{F}(YlEƤӤIƛڞ41 驧JO3͘oHub6p` ` )o/,ҒK/n47ӛz7^}+/_~95*=:- ~SdJ1q` ` f YlD&r/7J,@'` ` apL34(O?odd2 ` ` `&=]hteYL0!'"=GK<5>KQ,rKZ`K/Ts>h 'Vp]M<&` `  `qǸҸoMSn_LO?9>qU~2l9i~!zK;S~I(-&<~ŷ|>g_{ES _~%}ϝiwk}ptukܶoqu EǷz]>`Gkͫ&>$_~nz5\3 . cXZwuw5sJ n KV-첼~P~\]@0 @0 o fiNx4'r __ny@J鮻C pVAvmzW^y_}mV>`u`K_[(=9~&nmwX<87n %,BpoΫEO}tQṛK,۰PKqu%J0 @0 [=h]Zh!~0g_| ,x0 $g?Y~>xwܑv}w.Dܮy˽\nXms)ڶ @l\Պ`qkUW]^.2^9q[<?Ϋ9.W/I溨` ` z TB34<{4Yt+z׻05jo~s9zWpVEBTx.ԩm.O6y/ n d DچnVrJ6dz*~x•_W W~P_fpؖr1` `w>jT],|W\qtw?]_j淾-~a0:[Q: C10Ǖ;qB!s<*>ywޙZ7ygxiKįn^>ygap{s!ƍeaapM7wX#s g>7W҂ޱp% w,N;4*V9ċv0 @0  c[m&M&ȃ 91Ov)_e.@f q?-]u vթox)x+>cp3 lsQGq<XȔo= nV[R _­Kͥ_0\0>#L{􈍇XdA4-e/,R,FnUv؁ 8<dz!X JyX}scnTf.1 @0 :/fB^}M¤!]3MQ:F=or`__;< >Z:3n`ÍB /BG~(]K//&nm |km%)8i*Tp=MH&` Q~|Ӗ|4g~+ ϿƀF2H6 |sKLtuW^%G/#V` ` ` yćw>κ|,` ` ` b`Yh_ s {/r` `;ܺs` ` ` fb2̄\0 @0 @0 tg  ݹ M0 @0 @0 3fB.` ` 3 ܄&` ` X 3 @0 @0 HwnB @0 @0 @,@Ѐ ` `  L3 &?OGz8=c陧Ƨ^|)M4FHsgVZ)-(o[n\KoAH` ` 00M%^|1=tǝe].ji'4LIp]w? @0 1 L@sN' .D}t{믧.:6}ni[4qĴ[wm݆7k6<wޙN?_2]xig*l@0 @0 Cb`ނۮy]XsNE[<8|-&i?=VboK+ K/t3fL?zL /kK裏 >+ ů&,b/Ok&m;v,W_}5eXD,nc?yx㍙2,{|P6?i6Js9\Ta` `  LȋϿiM뭿aL`떛oj9昃ͫEC9${/Ngyf:Yg;ěƘ&UXQ fʗ//]TCi4h`G)nW_}+A=۵k'cF)Z<Ň2ay7sRjUС}' ߍ [7~iڴau/pF%[3 C ѳLP̹C fIB#d?f7,xnIHHH ?:kgekSFT9?Vݱjrw0f~7{z@ s5o+saaj"B3 PP#b:O>gΜ95/B:k0{g.ʇf#~a fP&NKq#Zk`Z9`ǎ>fg0a3 t}4Ȃ VPHHHH2F [;W;5zr7ɓOMP&X͹P`3`UV-m#:uJn훀Unڵ2l02  \&qPߺuSAʇ_ f8ٳG\|ź*neX}+wI蜉6qdX> 0]z?lU@ *(+W}{H:um4pPOO8?A( 175kh3@OS3Ys[p1B lL˅9f =*p6O,Xfj20#,NjV>f0ju2f%2L^5 ^$ ejɶ< d'`%'{L|&@cp1[j`ݢEKYo -+e97@^]`aڼ f/*]Wx"#,}^F |$+- deX20h)fB6l x]8`V+ȅ? $مAÀ„ E~߾}<0dB(2538p;T[jcy    W)VT+ }Z~Y0_Uw9rD0P0T%K.]Ș1cyp_0rb xZfo<"R *U~kfцLDY%7bv    Zp}*JҽI]DrߛKNNQc    LaV@|^xDGWG||̜9SƌG{1rɥ[͆gԪP7e+-3ZY븞5C IDATӗ6KK9T?G,IeI`mOi[A \9E Az{%pHݶRpr$`_tԪXLͰ(Ahv J8Z-ԙJL۾V#$׿<&    &fw梌r8_m\̮f̘!-X}qcNjI+Z}'`0ѬV)='ԬFbbRR2⥚"@3#~'iǔuriˊd!=GĒM@j(-ke[|V墦eU9gdӞ ha6Mm}x{4..ԵQZ!KT^-;$@$@$@$@$«5H= ժ똱cʁ|R͞=[DW&{wpI`xNy)V$J̈ ^qL̀&ReJB"ڎ>"$BlD(eR>>2j6E% 8{hrxWV&S5<|B0X)1rL='m!pԫR\f_Ɉ\HHHH@X_?̍ y$#Z_uLپ̰J""e:'?KPK`Bq )NH<s ?x4QT?YeS aŸ)t|i1Z\ڢR~tک}˾㒬3"HHHH (YzZ(PXr#o3H>GêgnӰq)SۻGjש+zcveԨUW/g/Ǥ5$EUf@f%͕yVŊ=g9^h5S_ÔsmSO0u1wbTYiQ_LmG9' f`6)gԗdD60 @'͌st%U9xJbƲp"   .mvғu@@a~ay;ILY 3{bN)2o№Eb6UI._j^f8S^s*( A+1S~?BmPVqT~M:7OjJ2!߿jF碦Ziko{%\fHHHH Iiޢ,THRn4eK$˔4aV@|GV/ΐjKjWY>"9W,إ;R&Oe^(gTWTZ BT)UU+ IͿl!R\Uq+k)oh5RP(]?Rܖ&)+kR i\AgD- dؘC*"ERH˚dOS\ҵkWQN{Nr ApIP6J#'HHHHH swݷsw*+0 v<V9zZdˁ$|@ٻeZjwߧZj5iҬ4oN~QٚHHHHH Կ=x^MCRTa)iS $@$@$@$@$@y@X՜&RHHHHH 0+ $@$@$@$@$@%¬uBpX7    mytzMCʻV ]o{"SR!zGoO [3êak "    N`e|<[I8}?.,:Er)HHHHH O d* YErIHHHH L>]>S#Gٳ}΅ H8i,    #QzUB>"\#/c-|1 HRRU@ٹK+1'o3hʕRZ59yP: (HHHH07|SZh!tGG={Jf϶Vu`H6mڤHHHHB%!O)[RR _B* N I9}t *Tg2NOgzIЪU+f`P@YF)g֭[!Ch7*%1ꫯ.HkN}Q3gHHHHMzDz%!߰~ _B* I r`]c{JUەxfW/ru9hԨ7 >>>{κ3*ʗ/w)?-[ ʠAѣhpK$@$@$@$@"C_Nn8x<~پ} _BDlAO8 9p2HHHHH _ݷO{wءWHll:XjFjת,Y5@     \G [Mr-VHHHHH Cd3 B H(HHHHH Cd3 B H(HHHHH Cd3 B H(HHHHH Cd3 B H(HHHHH Cd3 B H(HHHHH Cd3 B H(HHHHH Cd3 B H(HHHHH Cd3 B H(HHHHH Cd3 B H(HHHHH CrJ ɓjTNۗ͜QO\\\@QxWܦ X`'YVU <+뛕6&dvkW'|&NFߟ_x!GT8'-= e@y* % С{0 6hϴr-[ Xbf8a 0=vy2dlrq(BI|3);ٰ~u^@uM3Vff+;+@L i?u˽#3Qܒ+ J*IDDmzldAdbb$%%ed" -S@سg$''K޽rRx ʊrFRlmYuojXjlQ@*V'm۶F?W]Mh)/0)>|\ܩS 6\?nO?綒JHsĉoy$':lyN{<]/UFKq2]UR`<_SΚ'dعS{פKK|D8qBר)ys`W`ohum!{-&ś`ӡo 2TjԬ% 6gO&m0S|`90R} u >`͘1Sڴiy vmB`}vbve9ֶ͚5;9];8ztS~xk$۔;ᆛeYfI6mL`}.!!AUVcvr[(.]QS/;&L:ֽޭV8ﲑ]=#o:c"PBj:}f*Xɮ#>XpL?Ik`yE-\$'x^yUyܳʊ?ޔ_|!ǿM)cyFc|٧qFc:_c٧Hzuy&V;-MG~Wq&0vjM_jUYR`yߗe_~au5 $ +(e}s|!ٻocǍU厷fxkb|!ٸi0g|0}ۓ$$rjP_}Yd/_^DhGSe ^vmr^!jǎ]FoʙzP vuE|FlGpp-Ev\ ;wW'^t+WN.[׬Yg7oU;Nn9083 ξTz:T's^¿mDkNqzgWUuD`> Gѱ7ޔ ڵ&ֺǫk2ҢE -OyRz>wPZ5y!CuOaҳGQnf<7)oN_MBWmlݺZe˔0G2gX|O>zҞQUVUO/iӾTS<(\ ʮ<<99s s2nvy'SٺO)R)2|0#J1@6y`us#~^qj]56C2L~k:dNvROVWShFlSw-7#i[A) 4KU+%v YhΊw(r[wW8ƒlvM? ؿnlrFgE-\kvڍ87}ܿn/uD`coEi$eyiiժ34=w8̔9sF`n{L߳vZ<(&aÆ{C)!)_K+;n[ Ϩ<,7# tqǎ֬޷ce6i (AqJ,\2^;k>hٷo,^Xƿ7]y0Q eVgB˖)&MPwHSfkfXgMnbiuLN۷o׳NmF֩ 6s[7̌zZL5=%`p-.T P<.Abbce^]q&vlW(`O37שΦ;$?T&(/m5X_c7}}d#ks5kAn$3g|/ ~Eϟ/?2!3IȷLR t P.K&Wu[SӜ} uy`ȉ=m->`s xkl 9v炕aXfa릝sU:NfNFfRRZST^7dR6?<}ϫS\J-_sWqBY1/É]v˳;vsv4e:7l3_XۖY\571p7st+lQ@j׮HuݻY@#G(тihy$ҭkW餜odmq#GPAfsS~hѢۢ+CD k7ī~ŴiJY! Ls*NT䯿Ν;<+)ޛ0u?bv\zVH66tnnϩnݺz&MY#l1tSh붝hPʷss CmpVT)]XIv .w%sC^|ߟdܴӮą!XZ'up$X?q?qzW~0(/+Efq5\mw?X V齎V'L 0ܯi_~)wm۶7~+/<^פZIOj&M$v?xy wޕ[R]U,omfsS> 6T9R;|ݻWh'*Iu{f L2W(8 'й믿N+١̙ N(QBM6l(K.+)ޛ0u ȼo_]-i-7/.Sf9pdD &7NmFcTl릝k:na}'A k2au[f ӃNE,ܴS' `iĮg:΁d31FY/2k N8g ڝ>&_2Q{M~lvLH ȱ .m5A9bc)N[o-UTש|rA>W?[j5#']uW 2Ll{d*x iպ\Ík.o*V T6j䍳8ZjIƙn{Q p-#FzoMK/(]&ztMeCiSA"d曔5K469Ykڕalߩe5Xp5 UwŽtŊjrZyёvqP8ĸuV),+IY?ܴөP8إc_'&Nĩ8:Tȷc:de,an+ӿ鹎Vg{kz@^"s0?/m2p?Y3XOϐk5w5)=TNJIH;lskazoFBEnmME߉"I9$@$@t3FKʕW_k "r5~'rcIHM <%    H G; 6 @^&@$/_]HHHHr* 9산:$@$@$@$@$ PWm#    F H  eT@eHHHHH {@fN65!    0zgvt6e,m N`wCϔ4J'8f#    Й1 @: PI'8f#    Й1 @: ݿ?8G~aQQQҵ[֣gvrʕҧOٲel޼ٻ_xtW*3#r]f$    Vd?ɸ^… ;6̙3cR@2sndm۶U="A2[h!VbŊzSYdI9䩧uܒ @ d VRRȑ#2x`H"9(P@*U$YaZt9C (HHHH Vsll\y2{lOU&-nݺIڵ9Ν;O:U?|YjJyǫ090m4ڵٸqc{&:)_2M[N;vmV^}Uo)p? IDATw֬YҾ}{_<#-ήD!   ȓrAAd֭2rHy3  /ȼy$G2/?~'~ԩS[-[g`eBdd3F裏dӦM:+*Ge~ZiO޳&`IԩS_K&MuFxm}gdɒ%kɗ_~[@C]Ж~A~moz{sHHHH OVCrÆ {nѣ>5eY|vmrwdB:T>|Xvavz#R)SFUX1W_M-Xy/{qgWw 1cO>;$ӊVv{9sY`2d„ W_IUc=&F#FssKӦM1@lz{qHHHH Ov9{ĉ瞓Zjyg)2xFb`b'|M6һwomս{w˼O^ZϪ_^N> ڭF]>y 0!C9F@(V3, B !:`Jezxz D}aʿzaǎL˩fŧ FY\ TӊGRSX|,\P~.<nЊ Lʖ-+k׮aÆ:;sYҭ&>XM|-|a/7oXô̈́@u1qZ4'   {rLu~+lQ%\"O?+2sLr`fm*ـGjuo$&&DݺLPHPzLXfv7lPm߾]+gӊ޽{iEǪHXn: W3f%   :9BAx衇:}V2~9s9`^au!+4iYA VUd%j^cǎիT-]Txdއѹsgk{za8ٳG+'ӧOճ༏٤kFGֺpHHHH v,+ (!0*Utc@ &_cU92>p`&3ʕ+L7N?Gk&_2u+<ar뭷v_|<iذ|>-]uU^$ W}*    A "6`QWgo喁}Jy䩱 D8r0Q܋TN!=&[lZ9^ @pS&+ cukZpZ5 텹3 ^٪tSa     UW+"|dHHHHH  V @"@$o]OHHHHr4* 9r$@$@$@$@$dg=HHHHalCX', #>E$@$@$@$@$ 0+ TiIHHHH0+ k!    PW* \%    F qp+R$$W1[6wHHHH VēJE*R + u( $w{E( 3 C ȶvY2]~^iǓ,vVgLBңu[crO5`A)4d?6\Ee1rud2m.)X R.u KJ wKȞSRhAfm+EqZQ*+v2HHH0+ Gfo?( i>oRA7'T[bejRb䚎5P7~IS$=Q ^o>$?WT/{7n׃Je _nԲ.:T*]X+Ew앸Pm>ylQ3K7bW#'d2g=ʎiasT,#ex8qvy癛[-`oӠ^R }L5cC:efb6K5٢W'h/|mu;s`6۲n=2s>iXus[ӑ @^&f$-d7OM)f,.iYYZ++ӗ&G0ùC =P?]+S[z>@)#)JG]XMFMUtIm5 ٣%JNR f*Sgs*Jcζ#ceJ "`$6QjZlhNM{]ynyczk=z2^_7\IQz;䤚 2{xޮQYfßd灓Wl=;cqX9G=smrA7e 4k]F딹֔ۼ[DyM4y۽y8qГq) > pR|@apQMժ]) yK)f:"Y)Sp)S"϶%-$+Q IJ}8aPnio4"BbJ)qJ{Œ)mV k\<_r(uիEst9%{?|Zb:-n'.F)L?)1(,xP('uk}"pGZ$*{Pjһ;г"ٹ}MYwVt L]@@ϯ.w㓝9Acj`jQQio9}5 W)؏\Ԭ/*>=P{em麙ٍ wHaCS/ni XXfh;7e}   ȯ¬d3NIQ|STRT@y&2&[yԃWg~R "y\ qXox7KW?5/ާ/= P4(-)g ʙmbAf٩IkkY eô %S}ڡ+6Cg4ZN[DqHHH-ؘ.3sE@bm3/t*oBbruNIO$@$@$@$@$% !GyO)B+)DFFBs4OSFƓ aV@|}dS|B ?BŴ!xuASx{y8F '^oDpe2~kC @xO21[88r:Ű    ¬kl< {aV@hƒ{ kaU@!_fIHHHH '2yCتǂHHHHH3* $@$@$@$@$fT@ ő @~&@$?_}HHHHL Nm9sO}d۶mRp,I *\j6HH|d2ds/ԟ9sF|QW Tҳgz9~eӦMyf9qℏsq;t|ll,YR.by'jժ)RDZj%cǎƍ4rbl2ݖuI]v3Hڵ՟3g?h^h{׮]v;ntMv-[lŋۉVm޽{m"^?ο-|˳c8   V$))ɕaŋKѢEYʔ)NbbDDDfpB ȇY|ƌz%>TXQ0}n'mرcO "k<r\yӧu $sm@ m>soiۼFkč\4VFCJVBC$@$@$@@PTT1>@:v쨟mV^}UINN^#Gl:uG)7R`{]wI Yfz)-Zϛ7O.R[N6M?eǓx4s=ZUu2x`iӦ/QhB?G~``\ⴲEZfIKСCZ|gLSO=%_}=zԠ̲5†=zhz14n{C5jherWN}Ʈej;HHH bczw<w=v~Ŋtۣ{?jꉏ4l_ 2`ޣ{~o]S~(5&~„ 5ӛ-Zhg&M9glf.>co§` @>$z8t (:ّ3>p:C(T9jPEvڥ͛7fNs%a!5ǫW^xA֯_}b uP&f?0cfaְuV롞}ǎ)9ۯZWj{k<ډ8wc0[G|@:uJ 0RT)ҲeKCY?L;}뭷, p܆P/M_|[;w].2.={o9}Pn}50HHH@V@`n]hÆ !0VVGq8zku1@eˊz.Æ @ִ&V| ̓ЎV 0H{}7:ZVcBP`U0UO͵v9 L&Axu ~5MLl,6[~(m_P􈚙J Ռ8c-5}0H軀&OO12”- @ i2W(c"P|@AҶp6!P< 0Pb` <‚ 63)a`J@1;Nmkm}q} 9& k̾9(mx2;LPOp켑au{З^`o>P;t @|{Ϙr[f6;$@$@$@YN _) x 8̟ NO6AVx7[8`uxk'zmM:Ca \̄` ՛xx|9I5Xܷo_OLLv3,A*yn8A,څ?̧A4ơg]t+ya&˜1c52p"i3D f\Pf؀Ҕ]^3b>̠p&>[7):u} `/"[R;3S?(Px =dMX 3-PxWnLf kO$@$@$lNNjQ/󨧲I8g2 NgyБjyWW)5( 8VFy 󪫮(:}d._ =\psEwV:퀯Le~>_PGEQ z~?sLԬf f&8}f'$@$@$ = H8Z-ȃScu"8Xy|[9CN$+ DDHTT8xʕW&M {PnkG!kHHH{ukÙ(H+H)]4nDj֮-  hA$N܃Y@#6O8 +W.]H:ʨ< "/(;# U DI͚$2^F{P~vaS@`vrI׮RG) $@$0Qac|%&+WŊ{P$ @ ɓ'd5gnIޫժ)2u+U.]F*V$Ԭ6pHHH-lQ@VHHKujhEIʟE%&6FfVZ4o%k ??IHH  =XILLT&mm>L<ʌJ fA ),U*Uzu֭e3%=p^Y!  @r2yzR>Q$>!^< %'#Ȫa$73#g#IV]!@H,eS:ᛮԕ?HB;-hCmO!)M(U|7>?QϹ̾omf2rH og癸9z2^($鑳c3eRzX+B۶meÆ '4N&~GҪU+)V/_^nV9zN1 _@1@A=ӡoY-YZ=@ѱ;w) ۶m٩MiujU :^yoZzA΅^тӶ`mo~^(y~'}.>>^0?] Yfɹ瞫ƾ}t &H&M4ڵkرc,۞^9&_- 4:t`܍l>ؕaX Nӟ.Ye, &~|>{+S勩_a},]XfGɷ}#5F#EZ\u~V[d8 @Eޮ!M(E?/=v^/>o|{;bĈX9}݁H@6zo:`r8OĠ8e\ɢrL9-GXw?/] u&+W3GP(ܴiܸq2i$)WTPA{9=H{WiӦjE2l0-ozOz堜J;_RNyuv윸['ؕadX+zZr?s`pjW`#"EIчH`)[/ -1P@^x݄>{l;{ N} vi#[>-O#$7pRM` ~{-jM/9`QFZoi%jH(_\p6&A@j޼yz 2W{GyǥE(JI 8㮅YTamRW(4r<KJReE]N:̾⋚=ěMVf[l.]z =PUa͇}8<'vv܍lS&nxeF=er?4uAW?S3nBFT>*]| `30||fBZf1裏jI,pB8qm}M6¬r6=|L{% ;aW@׮R&.BMr@ʖ.xwF|RJFqe~UH*(!pzU㌘4[&`+4j`N񑑩9D1\veizԨGNyYz~w)GyNx<ֺXә}kR7 ()8F0y(%]LRQx7?5 !_~jV/( &}Ι.yZၙ]ɒ%ŋ)]wݩ:A6LaΜL)һM;*t0u Uge/윸eʲ2Zk&mdpzzf`uGfLDrͷzُ6ji,z>u6:w*acǎjʲkN]);֩Y㱏`oק/y^4W/_}jժ~kaL}}M6i~{fʊ$@$D ̤pwnD>V y(,Wto-'e?Ȧ JhH꼠e='Mz?ѯj9pivժUr%Ba@@ԩMvozJv=gr~'l\s.O4-ro{6XB;lcp}뺦HB(QQQҽ{wܹܨll}aHyeӦ; f]^0ҁ&8c]vig5u4gMywrR$zi%E09@,3))7}!C ?|oq%B%! W®XoN5=[6YJ+} ;qRV:GT;3 i V0ªLS.x"޷o_yǕ^%ϤIh9€.i>(k„rmڵk_w-ϩ<0E0?( fΜޓYښ28iREW^yU`_K9NmcU^z?h]s,m݂YfZ>V4vݾ/oEsi~yaVlJLHsx ?7mI=}[`?~+ p]'vvTmvӿ/m*ա c(|AF2\)V2M (D-[6}ǩ!>/mݻɫ*&ֺMM6}۔ce} 'vcsgW5DS 7yzpBLA5bkY4Oq`9=z4F^Iاz@7~6ԩ4l@XuRL)'NP> OjS!Oi"Ç-1ʇys,sgYiȝמ/\.G"EjJ|En鶀rZ{HF7ߔ^.mVt,Uc$d S`4S&lԬyzn2ՊLJɈvxQpEE7rOsaS<&l'7lX.@{C.kFU@xw3R)+o5e)R>A, n&-DS|Xuէֺdd ȍ.|2–yIr/lP@R:0nWE|{@1+0-lϔw0G>%cI ΝΚ妲0 w<<yv>ayz%j*'{oˬ%|YSf E#I[.ϐ }aW@3e~52J(㖞&Y(V,QB)? q7 b mC/cUsw@:ꁲycC3T(Ho'%6eys} @ 2?m8d>qJ$ ¯~7zP&̬0Xcau:mOrCgaI O'qqjA?[~aˬ:[Ree" %;Ӓ aW@0M ir`:$@{GLAP3.Efϙf>,7=a8.DRdi-J*=_[Hr+ ʈ`/$@y@Ay XNA2 (Y⃡Pd^ Ȼ®)ۡ2x ~G5'119 aU@q \O$@a"L`ix8 psʈ|%D | /SĪue Lbclr'2XރsY L!xʔR(G~xLXLTeK"Rh15PK,H eҥҬE )]( Ayi$}\߃,rؘg9lemef9v`H2BfWjÆ JRdx 'I2H=(0; )aS@3Ge]Ȑ$Q,$RM*%d*J~Hv%I";Y0{Ν!>zs9}%'Abb|#Y6SJ$9KdUِ#Gΐ߮;(rΌI$@8JLW@..,- /ݚAh'     B$@$@$@$@$HHHHH :D# @$!    * H)$@$@$@$@$@.PqAHHHHHC Ht8R T@\@b     B$@$@$@$@$HHHHH :D# @$!    * H)$@$@$@$@$@.PqAHHHHHC Ht8R T@\@b     B$@$@$@$@$HHHHH :D#$$Jj(P^~(IY|{ɨʽKf2m:6uil3#vχ:̓=\VFuJӍ_f7yb 2M(U v闋ŋ M7ǐ!dž#ʾBOLL()3WV-lܰ^zia)-Fķm/#s<m7uhN2wzrsVÒ ȚjX[۶m0uT4v'vVʥ?cԺ6 )5.7jʧCŋ M o۷cŊhF3n [`^-WO<; gٝʣaS_VW'NTF`U7Ϛ5 WթAt… 3gPTi\ܻypy;_3P᝞Mώ_`s+N[ZN'㔖`u+өhpڮ%שn :TGNmӮh^C*Akgbʘ={7{;4*H.e:ƉS{ᴕp'nV ֝bӍ.*TCg |ӣi IDAT>cǎQ񗍘;gƽ>0R7Fg~+&N@2ebb. ??(Gظq#W_믿.0`}$BjfُÍ*oK~@(G<{)s˜71id)_F)MSnB {o><>?{8_!_%eS':t}=a/ao]f=qozei֯[뛟-?+^ʣѨ/&P2ݬ/lTۻwÒK?~,] ]qs>Գ`@/ThP#ku ^uM┖%-wrxnVU?7uBK;ڦS^C7};{vmee7m,Mptʿ ~nBê 2T{ ̫ tJςnm*k~iHb!iK,oӦN]wuC}B |tLcԨQӧ7!zz"o9FՔ(QW]uWFǎv{g1jHAQ'eXyϽݽ~3N'66;ws o?@o( g]tiQFbQfMxxv`8{4bq7|ȑ#HNNFQT) cW'Nju6 ͟7˰wmw9/]lnW_YsS+L4˒ `샹izET~XnU䥸G|+3PjꫯFׇ֬ɷE۩sͳ`@JMhP+n>Tz֭oPiY}rj?8sSnJ;TpՎSԸvyUPe0LbP?>^ޡ{2O9ZjD7Mp;.ԅI'n[s}pmS+ \ 2]Q}53 =,ёd2Wծ rwsݲe+o\רmp]:ЗvZV;ͺE-SZUˊ ytнôXʂhvy*e֗s})rJ ;n*Wl:(!-[@֭p%mM'sX7́3f̐tK+XF{kDCf_͔C?0EȲ7HE%lԫwyNʕ+^e?蝝t p i' 9W@rʅڙhSSFGeZ |(&k\uCX_c$։xx'̋jC;k׮CNw~;sX/Eӄg+%Kl>{W@~e~Gѯ?J؅**Q'4ir=ʒ%=exbL]B,Flҵ+J =+2־HٕǒmwF)K2ݴ?GnMQt={%W|56ҥj\9e_fW( U8fJ],|D<;TÕ&ӳ8e˔ /eׯ?6sÇ&'~yC$@$@$@$a2C:bٳgB||=Sᮻ:a2^6w.;;h,=[jfT,׫wuuԼBJШQ#؛QG㣏>ƲK2X @^7 0ի,](ٱrJ8%]7q)9sZ^{0R-WF oR-[ĉh}sZΞ=&kkr早7n8֔e%~72&uoŵOr:Ky1Oڵaht'!   N K.I+ k㯿mwD6m?~^ϯcшYϑ/_4t2M˕^*#㖣L8Pm"͗dt*G`8ޓ d@ƥ-[ѣ)ԭ[˗] l2$6l\f^bEa׮(W\_N7%Zr5jtFɄ`]feᠼ};S,+V@Μ9̽|)cer/\ *TLБHHHH S H 9I;عs1 ;wnj%d#.]ǍȗtWcB7g¶m0u40ZrK, Uf P8I{ Xt)FN\C-O<=A՘8#Mܔ1W\h߮ y%K0zhݹs`l׭_ ̒1@    H7Z)P ?t-9i qkM-T 5k'|{?h:z=c̛cQoݨ^hQ.r *gyZ~dCuTR%hZn8hĞrmΝp,{kղ%z?P~Sn ^%oj_U]عku/e>UT|w:uBϞRPSWEgdB&LG    :x E;Oo1zb|O%g&`xޓ ]v!.pw7w>\.'aGoK !p+ z ~Qv9q!ja$@$@$@$@$pa ^Y*    8/ כKb @DIHHHH%@$\b O$@$@$@$@$1* cD     p P Ó DL HHHHHH \T@%$@$@$@$@$@1:F$    p1< @DIHHHH%pNΞũOc8z('Dbb"pr_|9 ,'OfH2Z~d:JB悃Dp"t%  (Y3Jp(Oc/8t蠉R@!XW\^ 9/͉e?a_ByFנOQnP -Zb2|zԪU 7ǥ^1QeZb %|ks9 }K PBhwK/QҤ]vBL:[GbE옃ݻwJ'$Aҥqa̘9/} ӦNqyf˖ >߲$%%!kovlsw!9ӗHHH d,]s ,\WnlȞ=+_]uG@lc%KG.O<9jGMDkAɒ%QS8 r%_j>cԺ6 )5.e-Uty,sqO*]*WϿRN5V/F75o߶oNJ+дٍ(^mǎ~q%XVzW8w}룘Ⱥf-3d7\0'LuzAdkT*̸͕4\9,Z_oښ;vxs4k,\U7><,\и9s%Kʕ+ah!  8? dPt~lݺENox0c CM6xq7Qz 9}:('N`6mjP|utܷoyQ <m%>YeI>wVf V~񗍘;g9n܋ WxqeI:zҜ9򰗌[߾ht9eT>\Gx~V"|4Գ_/<<*Tv'SRF46m]ƈnm.-T2^yUkț7/ 'w^+V K.At24iW6W\qEj!h#  8/ dĦ_7][ U>T i֬&KG>0/"4sg͐+mA%ZUTM#G9-7GRWe). ӧc'F&J>1A EQ䮻:a2[sow$vXϿ"vɒ_}iO 7DQt3룎ŋdzC]) ;vUD <3q^ĮSe&I6,ۜNF{C}x|稠(*UKíb钥G|+3jꫯ>'|:ƎYfeVhmktԩSХ)+vZ B&tuIܹ2m)lstUK(m#},*6l2Cy=0r(]iHHH:4T>C&m+n8/~1?,k}$ɞ}Ve̜~ k,kYz wwK c8iR҈o6m.TApQ6ջڴrWbُ?8f$  tl1Yػw#UViR4L#l Vܹq,0+ѣ6OHHHd*R p޵kWi[7n],]^$YFd?]Zpݼ/wvuܹKf9b̘U4_ UzNż'pZڙ-]qa7W\h߮ yo0鏖Qڻ;wN0)%w^߿SEF]|۶m:m^{IStvw1\s7&! +{z(lsNbz?%f/K.3Bj\~_YU@Ays 4-ɩZ*v2cԨxLi c-Tmk6,MT*RSyTᘩG^UDeYg?YHHgY|A:Lr1w,r䮞fXp.]1u#5 \z1. D9Q@4:#5V ֭ž{LW5e֣|DsMKIJ#,@&ZmΗ /sh&tOEVMKD!sd%ߘ6fvHc\   H?s?@$@$@$@$@$o"`0$@$@$@$@$@%@$<)HHHHH8"    .* Ii$@$@$@$@$@8 IDAT @t P.OJ#    p @HHHHHK HtyR * pE$@$@$@$@$]T@˓HHHHHPqC/     ]F$@$@$@$@$@ z D4     T@ЋHHHHH D' 8^$@$@$@$@$@%@$<)HHHHH8"    .* Ii$@$@$@$@$@8 @t P.OJ#    p @HHHHHK HtyR * pE$@$@$@$@$]T@˓HHHHHPqC/     ]F$@$@$@$@$@ z D4     T@ЋHHHHH D' 8^$@$@$@$@$@%@$<)HHHHH8"    .* Ii$@$@$@$@$@8 @t P.OJ#    p @HHHHHK HtyR * pE$@$@$@$@$]T@˓HHHHHPqC/     ]F$@$@$@$@$@ z D4     T@ЋHHHHH D' 8^$@$@$@$@$@%@$<)HHHHH8"    .* Ii$@$@$@$@$@8 @t d8J#   MNF?n dɂK1U֍ۊ.u15$t"   3gXn-9r1=eK7O^TV ˖El-WƗFxh 34 $?@&MP\ɏ <TAV|hbƠt2$JX7keѨ* &   4t՚UpCf('Mxtƣb媢|dÒC"EҸ؄f؀q&tHHH\=0`Z%K?̙n"%/=uC%oHHHH :Ξ=eWDgetJκ]zK"!8$@$@$@$?<%ƺ|"sÝ @N<b?PH1ԨQ9s [#DSuص{'+*U!wO%X@%$@$@$@>ǏE Pj xC s4u/KJn*Xt@1w,ٿr_&HHHH lDX׸f%gP^Nڶe1BN(Q N< V-n93p(H H ޓ @<'~59s^'Kbg*Q2ӛ`.]j6?~|(ғK* .A1 d6cqCsU}X'Ԩ~EYZlfΝM6Öj֬~XlF í܎O5JHj6^?O]DdpF$Z K$@$@$@D@76m.鞙K~bl~Yiv6o,#O?!o޼;"xB Onl,%=Fط_V|˛/e= PB UT>UH V~Ǐڵk@ҥ O~KcĈrSɉ%K駟kN:޽ uU9eB^[E eZVavDI~2r*!CQw߼3ժU3uSlY ޺MjYq^u*U(@ְaCie͆Yaù!G$hB$@$@$@E@7\4%d(7lkE Pq͟ #1{L"ʜ>}Q.$kÇ_~1֭c=s_6M6aԩ(_߲۷,񊏏رc-Nb?ʞ8)jhd]zѤwHdE`_b׮f/KOgLCxGuV|A 6 ox (&LK/d/^0 o0-[Hw_21ePK$@$@$@$Ws֢|*{ez;w~Z#J*{އeaɲL?(з#Xۄu"_|fg}f :u 7`FίZ⋘>} tT];v sW[n"M4Af͠Yd7ݬ߸E-nC%zJUVtR߮r-/eG[:_b(!Y#KrK8X]vz!FW^y~!n&3|U)ywA3urwUV^K)Ry=3B$ 3    pC@G˕+o];vԜv'^r]s.CͶm[P|E_(\06qߴT\ո+Z 6o,_x1VXse;Y|鴖(QB:ԗoǑ#Gp믿ravm޼9z7E(<(wx@֣˖-o I]lݺK;7 ӦOElXdݿD. V*>m틝;wbڴi~atvҡʣe^S7V7|ZkYŕ_B?/    $%ARRmy_A7m0DIXs63aΞMg5M=j9 Zi%RV-$@$@$@$]&MsSnbf?E\ܥx8)c{Ue4}>$fzt_##;"9)^$}(Q:7HѣG1x Ҫ &B fEW4^~y7[ ݈ +h_íjU.7ϙ?g%_isd28|ujדUѵK7{Q?ɬYeV7(?UBOK}QbEi qfv|r5܉'p㩧ZѳC,^C,pVýr$\b O$@$@$@ x:K@q-1s 4Y]2Q>0N܆f7h~l8ɓ[l~shU1d9@a&ƌI@׮]vZ5DtraNz~2~~A H$G{mڴg>Z«= (zcv_w!<ӭxm:!ܹsѭ=(XQ,9ѷC|?qXfNA+WYm0` OJ}eW_]O6#_WyYzcד2p$H3   OV5ohղ5Mߍ؜ؾ73ݹS9Q82uȑol`s# "u7,++K4ùFZ-YtGL0Jï[6Һs3$@$@$@5k49LꑻފOLFFQL6oڼ+UE۶`˭|=zMuM`[f$iFgTܘpdw>FkÆ֎ ʇ.۹s9̈ #5V/T@R6   2 $bz.ө\y5f񫍯kd>6z*Y_ 0߃/pӄC }ucdՑŷ^"_27] '[fC-j= @ >8U&DZcqFPl,a4E Uk͛70:n,V/SK`8ԨRuYG1 H* HHHH װH&/g.\N%^R=ә5f鑪ò@>OoXiQJL鬈*# ?ޑ @Fh(dD# ;{:HR ͈!HHHH "Q&)(MP,H$S03   ?qbJdJ{LLLdbnJOPq HHHH5ٓWi"#pX,~eeK8Md+=uCHHHH =䄥Ksď˖E$gKWܳgǥKqy͚r—a-J欛t5hMCD~6\$@$@$@$paMgmؼi9,mKˮ Rʕ̷NrDX7C:`l   %,Уs4葖%*klrpNspsaD/uC$rI$@$@$@$@$&( 3e'    P誜&    sG ȹcϔIHHHH#@䢫rHHHH* =S&    Y`    8w;LHHHH.:T@.*gIHHHHr3e    P誜&    sG ȹcϔIHHHH#޿  Y6nϹI \lbqHHHH!0m&M$@$@$@N`߾}عs'݋#G.CbPti-Zu~V\ K.%Kݻq@oT^O!3hBxidϞ=G&~w*?믿U t ʕ+3д8x)HHH|"uVXt7n]@ڹSwwk)W7d`6lٸeLĢĉ[eogϞhѢ]/DzKCF0N\~=~ڵC&>e骫2ʡ5TyF9qV㡇 ;mz4Z/ʕ t{*  O:3܇n@atMП["VϛڭPpkpXGLı'$!O'fbvķ + , +gߏM6aǎ(S T…  R,߲&''/@-1g\}zMFLow ƍCVǻヒ8UL&OluݵC}Rޥq7ic~F qJ7,~IkuG0eԨQ~nzm KNbZj6l!mZ8yU˟'_sucoLoQ~#V`VOb%aH9Q7LhjwO芵- ke{G7l#x\!}==+&k+߰!/&`eR 8yoY_eV (U§VgBoYM܌is=Y+1"21ɽ29k`d_(jOnߌ /Mߎ1TXquיى-[eDSU 39s43);v}II4*-3]r%K2{l!ԩSC*TQ8n͍7ވ*y{tM'c|hUy~c]1˪lڈ¥Qh<( q 0~#&5Gi!(>{0k)$>BYXƄdJx0d $ O;7 Ǡm&^yʹ}$>Q\FןMqwB6J!Q0k#"Z%!Fn8ץVjtSj_Åk*Tn :ʎbdHO9U/OuLsWگ,| ~j7|}8.ԻjO}4exSnÆ ~Vx8)G*q):ۧJWFFك( @ڢ)ዥ;&ncQm! ̺KK#!1aa ־=[sM{cd7#LEoL0Ach/)3)T&SŋGQ&Y% Gaq+^أ~$_SFJ:cXgUgP$̇d5IƆ T`7'c!ɝ1i=Aca=b&-s: KxFO,UIWkɛӎ8S[;eWƴ&]OƞMކl;D,ʭ95uØ9]`ޒ y/unq1EQI}sa`imʹv!@X6IDATE=u~ 2aWٵǶ#0[|;09aHi68 3: ~IJ6SaY~E&=`;Swr2ywԄ>RgDLl";gl.m8^fG`鶔1BY\^`m)ja䥮gLjGslVSD,6u5K99읛 y<'oCMъ(,Q/NYӆyym8|wl8f1-9v8?A2u9rqQS"^-%?];Ɨ5k"o޼S{?t rLݴMXY$ɣ>1P& e to<'.(S F˱S, iG|l94C{ġ,S{ GI`ʫX:N|eד3=NFY)#I:BK#k!"(si!q+FSwG ߿)bN Wz2b 0i]xОeƦ?OI'~_jXͻ Aա eƣ[M0Lw\bdv* Я |6"zv!26_ڌ:6e/L 6D߱0E8y\{ ;~Jh|'؎?T$68WƸquLrJLRRIlڞ ?mǍڄcf]I[0?m t޹9p~^drҁ={<oժVE%Yz˥j_Åkonh'OBMXG;~_%Z2qs6=vU>O̺uLOD%F :Ԯn˥ҰfV4Cŷ- q~&b)*_vʇ1R%->>`k֬… q=Xb]W _f t׮j=4?hF׎YaF&IX!'Ō*qcbRY2 !/o)C<6|+Cj/3.ۢ0nw4.#EP, NET!S7NXPFQ2K)+vwrT:Γ^2UhF[t97UYʍDQ>uiH'߻V@:=BdƜW= hcֺ'ШV}h'\( XmX #ԑsq)`l\lqԪ.aQjUG<:Uu|ͨV N5ʉ|Rk^ZZNt@*h*չtہ):(]:7I]_jl$=$6G ]D2-;0s_SGi(SL 6m7ҡ9eZzRFR]ye]a:zYY bbs0Q`̐4{9Lp!\dHd[~IBrRIbtY,ʤ*<2rK|-KuЋnS'&+mċ-|O+v9Ju̞Z@N)o]X V24tjOFҽ6MȪ5$mCS=z5~V9}d_G0C:mڮHl k'FV) e<3mK0/6a%lbYsꕹ̌[ؽCL6Ef nN,ʍSXUrʍ-F~қ\0 OxzZJj$b`[2˙d W^{&m.SpgsՎB_J В5n4ݑ=ZOz((2lI6sXۿC߲ȳ&uj<gz5;=oG״rUUf:{訹4z{uW %Wz2vrȲZj%KR<2#KxJˁl_p~ce̘1Fн#{5'Wk5 %SdI CŊMY ,K]~U/R^Ceh7|cqxFm0V LVCerMa`7QPȆȺOSL#Xz=7@nBqRz;b^$nnCPY979dUr ]dV}pGj7[.#S%-D1)=V #ojR{te|^ظ'hpn)ֲg7Ã}yꖷk,.,؏{KV5FOaU/"~ mkH%e~[ \ۙax_T;zCj]`꿸|%aƎ{ GPkVSk7%IZL\9xt9rr ZGx&2PmSIO66*tR,*7Mh㲞0&;l?ӪyAY&g 6l*;\myhYGg*уD|1N-<oM=A Q#AT; #]+:oW[NA0F:5j dgG ouc~tPGͿ:k} nݺCfmT~`P1kUq;oY~ѐ{@59tH0K=:o|XFGY3Av^wdh\Fkd_r$F4u΂X˸t6ήa֬K$ik2 7mtr(S|ys"~ ׍Y~WErÉH>M a(N܃ŋ7pR*ոeNbv Tzr)@[7l f#-ǰ*\LUv!7쐓w-}&Q}~ kN)Uk4{VĻ2K5(UqϏdž=ya %MƐg1zU3N!]ch<`6?Dmٹ%2)wl#۴ ܄NMc'qi gH|iߡX)$ |˒M]vxyڶuvF{#kJBl*om닂z{xx~`<X-˝쌧G} Y?^:nm|7|Φ͙0~m3٠N/5 kLv\L幖9 Ǡ:{LhhN /a=geN;O;/X87=Petn2S*L<}I>[橅ez ~ǯMp甯iFc==0e^r4GM6*ޯzAzL.:hS% ڑȧd~/Lrlƥ )(*4$K޺C3iz rYҰV%{m~ek!ݚcx,R wfxQeQ KTNn70nK, JԷS [{B҉֗-%Ē3!Cg!;_]dmy /sh[FG5uY>Y`{97nFvͳuڵl'aiN"az|"^>V.f>vX3k oe¨o\l۶(6T}ҳ>OLtZ,JEH tf_5/L=b]}ωLFtJ/\?һ(Jފ#nܹe&ιIXbb8L-݇c, cYU]*˅nZ2e(å'Mޡxz =GQqB,MgXؖ,I%f&[$  H@az^TOխI$SlV;]ce@p " oϱk?vq`C䌜\{ =G [2±s lg?quݥ<*@̎u%  H@X(aܲ>[̺ǸZ>r(UA ?Ԧn9"Ǿwv? "ZWz-Qʯqlgl~$  H@!b{AHd8g/z#"0u|[_}[(;#3lY$  H@FV^IENDB`pacemaker-master/doc/Clusters_from_Scratch/en-US/images/f-13.9-installing.png000066400000000000000000005427421217637305600272530ustar00rootroot00000000000000PNG  IHDR i1 iCCPICC ProfilexXgPMX`w9%眓sFrPQHV""HT  |﫺nW3==sByOtt8n{o& |~hw^ydOEƲ~ѱ`ƣagƃ8<}89Dc K}`(!`{6F:""j_1? =}|~QH\tO߇[DxliH?YiEyXڮc!ngX -Ͱ0{L _|l?v;4 ~8a4 *zX[>AD2AT4K= QLY@* 6!B$ qB($)Bd YA; AP<eAPTBU&tAF  /B !PG#,N/D"FD!{aK,b D$R)TG"m{Xd2YC!Y2 P2(-凊Ae*PMsjMBКhs:A/o/tO ÆǨa0PL*8sӋyǬaXNVk`˱wcX:vGq&Ha\)׃-6xQ&OƟ7Ot&L'hLBO"|'BD =1xXFB$1P$ <N2422L0|'Hb$=^IR3>iHee4ggڵڳ:::tfuu}tt ][ԗտ@ aa(hĘbl\a=HkcNlΫZGC 96['?Q|~iqN((;s2)S5ȂB¦"rQJiy?J *=C8f̪\|"eA*ܪjg>ruimGX]i=>~a \/l7F6694=hVknni9Պhop%K]m2m._W|}u嵾E۫nPou@]]nZqKVmەwX!dMݻ|/|n_<0o?ڃ4n>R9:X'*Ontw,+!vw'VNn` )Ei2%R3\e r%sZv_PXDy M -J*.i3l~5!7";b:cbntG |ǧU=> %Ň ?|"8my9 Wү&hMONθ72 7Kbb>Y&~Ҽ v|8ٲm? r qtEQ ht3F3݇N $hf-2*JZ{ZktJtO08aX`tƸʤٴŲf5gpӠ+uWپYo!o BVPdpUpF8-5XTGb,ρD$䒔}ά<ܙ5rSű/8~ĭN-"aP+v( ->S]v^HD\5~vtx.nnm^jt Uk%ڥnvwv޴v!NaOݾ{=Pwx3P8xihc ƺ}:kfZqm썹y ߖt?nYs j7u~15g@ ! (MQxF!QZ ]!b0o.8g#Db!y"S(6sY|bCyOMaN%3_BrUr+s? EO%)#T+l$ +*#L,^]-")E%!#$J@J'?pTLAiTX]_uAM=^CCQsUk|O]'=i}Aa1;63SsVyk\ulmv+o`\RZV^G~oyр `carVtvL]쭸 'RRoO?w0Pdfa,l#9zG5)K?!~RJ~]Q%JY)gЪʯ^VΥ>yz#oKܗn\A^uvxÿAͬ=^˾'=&?5;O}b9k1 @)\py S%Cv$xL@ _+@dC"HGd9r%:E3mq4bNK8<.ׇ kD^b.q!ɘ(XDecS˔`"5%;k2`gfoPtĕMny B5BZBEEzD}b-4@k('% d؛˦ʽTpVdVQ*TvRTyڢ1٢BS{BL]OoI1ɢٸ )E_6,vŎ.ܮnWNYhY◈O_YXH5ud{l@ː h!鎬AQD}4탾g{1Wx.[TBaEc`#n13v1i2Y0ّ% `вp(BC,D\P|V*+V򐔀Ԁt 9[rEK*e_ߪj!ښ̚Z={JuTuzmG Md9LP&V̿XYnYclm-<]nθ#JxX{yU{1 ಐa#Q)+qf ]IeLiYF?Wc'NvΟN*VwUU:\Xl( lbb׶k;:oR=ۓK7|?G O`610B« 7w?M;^޻ht/.+W}qwۺІݯg7_f#퓡eD\I@C9w0ژ{XK. Wt KǘdLb 7SҨ, p'^psvp>s7/[QBHWX]DETYLI\f(-)!&(ɑU+ijkQOD ^ÏT S_\V'Q6vfnNG\\Ϲ;1}n?o_0|ʫ'1E F)D7݈7Mx䑼(;$ٝe=v5bœO. <<Quxt-|E#wSmPk%Ͷ+.WG\va\?7x>(2T4xd l3/S_|4mlJmZt2+Ec ŧKe>}TlՕV_'=ڏkkQks?>\W]`Hݠ2wMͩ-խ[sǶ'ߵ\n\~.ͺz8ـJo?fRvQnbޥ|^ pHYs   IDATx ]E7~^$} .j@YqQgdt ~.ç7:fe#NTdW!J}#$;Nz_wgUVֽV{KJEO-JCb92@F #d2p PCCkѣ-aqZ\booGFF #d2@F #`"MMMF \ӓd2@F #dNt`B=^WڱcDzcl+#dtzC~aܹs@F #NnjQ<Cɖ-[z 3fq'&Lf Z>lJ ԩSog',Tjg??3WBps5׸$8ns#X8+Vwܡ1;we˖i4 8(6N9zSN4A]sͻKmr@4eojl@gzF #8XfuQ:o"1^criɘ1czL8`N-#df4 UnyGuӧ,,` l޼YgE8#QF h6WZ3˴iM&&NP;P{7oQh?>N Yem%?@fd2~%TDt5LRgΜ%K4x&K r"-ݻdIO(Gk)GVmIrɅ=ɩ@F #q2*pXzɇ} mmmK{[[[f`MD v-6k,wwɓ'RY@69pڴi*(X"P_'N}ڥ f,ˮ _$'MѣFi(?*+3utʶe,7Hh:G9Ms @awɽrm3JƎjv鐻?% VrY5TTJR)ʜɗ.?A9b{X9@F #__}ɶm䤓N>2W91_/pVK|9q?.z!g@֯_r(< bƋ u @aڵ:hMV:}xV[U&-IlnذA&MyOΚNcR@gzF #x* оG߾K.~2_=(w]Z&Oh1d f 1t+k&{.>Yb/w 6Lof+_FYc[:d2#ooڴI9]}s9`vB"7:,t2φ;!Apv,z1`trRSɖ mr`aϞ='}G|0 L!Ciyd'vHS+ҷn%].MuhƗa VJOp쾅?V;;;;q s%2{hu(CF # 3\m4g#w✭}h}t4M5$5BC#(,,_K|W>bB'n*~zCtF #x!+[lo5r؂cg6,:gP2@F``+^^;R>mMگ=l*vwIK/0ej,.|kYߐQSQ^}Ld2aG&[Q$pcol q s>Pν;=; ]&z6sPCY fsر*J > CTd2O1\s2ͣqoډ:4e筇uxk › !Mϯa֣l2Lȗ)Ie5,9µ\Cީgu`w s6|i,6 `} Kkǁ߃s:#<hK?UZ͕'0+Lֵѱq";wI 2א2^zL>d6#w,1sCF #`i.g ,M.c˖-jXӳggyq~,.㢟\۶~Vd2 *G~Vu }xm:m`>ޞCF #<p7 5uu77yɝq㵅2]-b^]3-#pd_3 j)g2@F`pj& u<~tsd2@F #?C.JMF3Tbszd~F #d2@F #04?1~d2@F #d2{kKY0#d2@F # @d2@F #d<>,@F #d2@F`%XGN/s_O7A}QYlcc6fʉ'7|f3Ø{.,3d2@F``}Fߜ M~{$7ϭu_HwF̊p;&.@v@~<Ox`+ghpg@F #3kNo{ vM>Z{{ U}3&)=utTCPF)um-֛.7X~`rʛ0a?OAF{κ1 "vz'>$T%n\rv<#md2@F #C7m^,ԑ֎2wޡҍA_; C ]|BƍEy(9y\`A]K[w=g'h0O4 rg{E֮*K=o#_ ɩG>t'M$۶o7?Rm>@+-W]т@ &Ph>XwuE/_G{08| ORK(CF #d2OOM nҷGF6 IiEy)ЉKeH{{qqc\ =,{( :8Rʵrh=LI=Ҙ^Zm/s0JL0/X@^L1"֜%"8MZe9٧@F #dt<**hXx46i_LӁ(Œm,*J*y7k ;x>2x:˦n[>w6ˣҕ}#W^K:\@ 37v84aG4R)@6xٍi{?.(-O mGtc.%y_m۷U8Ƹč1% ͕ KF #d2&ɮsiIz: oE`:D?3!}wI9ga2a℺ z^n[ eV-{ڔ}I,8U>ݟ4c6waaǍ].ir-[ BFРw0Na`|B|=#lO^+޼0w6r$ވ6g.-֌O4Yxt!qgG`$2O<9uϦo9ӵ2@F #x#˼/ )A뵇bک9iVKJGG'_uDxn ;e⎮<yIX%}h9jWwkh_|}"fQ*2sJY>f 6`WN;oxp?Laʨ߲}|up"ߋn4-A֑obcg9% ,&My6ɆeQ{ڤytz&ڷ^z'Ikى;vi8pG0)g@71R+>cz,Ȭ\ [._L02뮓 /p9ĝ;ȎZ96wG͗-1QZ5#BGdҷ˶ PeG)Hb2\Zř%Ė-[bɁ[N1">G+{d2p#U0a߉g?*xIڥҗ#M3\āH#^NGkc[g~8i3]].͓6af@qȰ˰ET[ ۮR+h#rXڮq@\pn@|bxWeg86^QnRY+=rͿN&b)ViixO5CGOl/3φ6>c֟3 cz27!<RR笛d2XRž(L6aT閦N @U)>^+olZ~BޏN#Xo?1e04'RF6;;˫jXOBnLQБ#g?Xy~.b#buCi^ocҴ oTL`ҊNuc#.<< :){ bj~V|?;D<8 9s㉂XXB )eZl CZ@F #<G {"@hi fG;WyQ译U:r+~\#[^Xr6oޕ掝?bҔC ?8t[k~ъri)Ϗub;pq 7ȫ_;OoX|FǤo)/ XbM;p`&6@D0"˻K_^pT%2a1apcmm|6I1AVie۰x"`'@ڕrd2ģ·Ai@TLWp#vLO@ y>|q]oⴑ"?OyCǒ|C=6twd -\8Tc(ti6Gb`|~ks8H%ArԑRei(fz)k0,2m+əCo"ݸ/}PlF t4$ q4 s`@挈'ΞCF #d2O?Ы >}O$Zwߪc?˯x1ʱ);'+4Wȧ,vwZSd庲LY ^Evu4AWϟ7·!7=$wf@Xaf?n<ģ# s \x025 c<82k,Y%WzH&<2ai!jG|#uWEuqPq34Xvc>%WB_^àЧPnR]%~$$IN#s8Hx^G'6fϔUJkf@pYv<;ct_z9|VIƀ{;\LEN?`% ;-QôUz0Y;p3l}skեX|(z @ IDAT o,}l#=X4Z0C"yQ y}Bl绻9`ˮynu~]d2@F``|ޱeĻH5 ]  }=X-DWO?eY,waL>+o>d6}(߻Me0:z(^j~eʔ)qըQ'@o(@{"=4Ap޼y#Vi ҙg)~g;8S͙"fy{dTa:J'=FWCukN+4:2{lޔ:~$E:uB#OPv8{©.x&@o6[SN9E^vYsоwF2|  )/:L?6|;Хl3gΌ3 Hp39Yc Q^(Nb{2BwO~l8kcn1=b'z姏ڍhx#2ȐnlܸQ;|qcQ9{lC17xכN4u07e@&N?t}0oZPukʾY4Xhd%yiJ`im۶I #ѣF7qՍ;B5?GY.}Ny:/Ǐu쮻իW\gjI5CfζnwRlYpst?k#|*b_9)Mi(t?x9d3@F #g ؇Ӷ\Ě鬒 0v8RrY L{w.4צwɫ}j&N/qsC9@,_8lGa!khm#&ϒygǻ6}@կ"> fLG ē/@F #d2Crc3r~Ǚͦ:U'ry axƬD9bǎrm ݱ#jLr@F #d) \gF #d2@F # d2@F #<اwlq}>Nr.zi-Z4(wl7sYĺ _;./$au@F #dF'V/^Y>Y>@_ }&C/Xbg@:ˢo|Unh8= tˮF[{˿,KT|T3˾ϑ6"W~Q>s?7M˒Eߒ#·>kDH>B'ʕo@?{ݷ˷:EՉC?d2@F #Gw|ŗAfc]rnC_{?|SɅ f`k| {\_D>rzo%VV(4N{Juf Wr6}w@{nɎj ws&ܵ[ayxgi-oM,]no\ʨ2^%dmhzz>_$_ޱZ~t\?"ӛ%mҰ61_E_mê 9/+|y:R?5|Ku7dϗ[e~L}T}[N:_oA۲oIYXZ;I_gsY'#d2MRiǰA ߳*xh`W} M͏_- >as or\rD|>4⭨=9\9MićDk[|\nVI/|t ]MZ/VڰI6n);mQxիHEX5lLco.\( ^m"ޢ嚯}ևIETم߼U"_|,v+H: *_چ/4OfOWz\|]-ҋtgw'?{rL6#bY;fv& wrX*x{UC Yq;^ujum[,w ]]n-\=Yb ߓ_(6\͆5vh[Xmo_~ ؋>a{]"[*m2} z/Qtr4~_4ɕrїʽ(_q./wʯb.ȴˍ -_ɻƻkK+7#>፺$n!#d2"yoBfVƞ^Y?kX(X.[xMg% <*Sik/R FV^P.0`藢$Xoh>]{O/R30޵L|B_x7oByۍW_(_6p?ptnsT4S_.goIo+HQ.|_6ݲ :i\sgP~qa9/>%G_TdoXt՗=R~xϺB!].-?xHϝ.}\/kPPu/X `}Ee鯓*/k~ FrTv|{E2__.6[+oWO7ROȢW42]*5C.O]Wˆ.\n%_B:xo|r$o~(?Qk=+cղiw*r+CC_3N{\!|Hߑ_x.y⾟/V#}軮S5 eK̎w/gߖ6]/]ܵn,(_tMWM7|U8 HOe\[ϟ(szW9x*˔fz_ܾRzˆ%.z7AZ9Y^(ʍ(wR6-ȿ[m)5&̙l|^9%'HKni>W='dy_ͿOJǎخZx^!s2X#Q/[1(7j9zܳ;r5&]H^4J*fb4Na~n;+ɱhwL{~-O}.JsքgT޾j4=-{'Y+ln|qHKSWmzϮ["$-ʥ?\"(|N<#c"=V&rwEƎ$'y2 a}K VE.[/r*t99SһYx_uT#O?GA(!9ߍmHAVgm@F #CQ]eʱϓ"ٴ˟W=}sj}կc0xc7lw%u9Klkm7zDF7B@Z uس+/{w?xpxf@^t+׼]-9'Js9D cڀC]>ipe ÉL c,dF^pdenu~3@F #x gu5eb>QZ+vY`dF;MfZ"nѯ[mAk&yݛ&=д(M~ԁ =ɷN/7M!qn>]Ί;;kEy׼},2؀*s/Fk{Bn?ʍA;o]=پK:{qy9~yd#^c +e"Tm7ʄg?x:Шl wwGQS&ȑg$+&cϔӦɘfo C%>g̔_!0d%@).н{k>_yC!X-G\~;}E/У9(zdCdڴ)СBtܾ]ϘDK37Q*ji~k&' (=J: seV4omYLwȭA.y䎕2sh)7)k?2r<1MtpLX(0[K?2x{uI}&Yf\+q q7-v~܁d2@FIB=ʕj=dѻk J.h}pr8$zKe٫'7&}=;HpF,IxptU>dRLnG,]xNynZkiX9sE\$ʽ.joN;NN:9qRi=V_urqv t0 70vZ$_n=,#2K./_g*'Oŀ@o2#7}N>-@o[LRab \ڰj[A7bxgk&uzW˳g4Pr!e2r? )zvє,`k~@$F9cE rͽsO;_ |K_YLNdǿ$ג3v|:Z?^۾S*2f(bO<}عxbO ʥ7 ;ƌ+z|Da[__un=Oz|KSYvlw_cAuȣ-x^}ʨxoj@S#ٻس-^i8Q1r߃ɘQ2$}ha;cǷHniĒ7ŧ|DxN`^14˨^{3WƷT䡫Z^o\FC+ 2@bnR@F #(MmcdLCt`IBJK~^ꮴx:wD_j_KDj}Wx|E3|n >],i= 7-{Џ>Mҕ68=xtR޳mC۱@dVtrGg&EoۍnlѾkl6 =;a!-[x]MXsd@$-uz |"E'M v͌ZzِŃ@0·RNFniMܸn'|b<m} x}ڽM%Iw}~C:"T_L%`Zlv)/FŪ6AH |#O!*$dd.d%4T缴Z)k̒,b*^-b#\/†*YcQ)P+|XPhᨃ)@idex"|W-ITBu&/kT,!|n[~DQ*Kʫk>AikMh,ƅԆo^|\(Cb|UHXAW3XCL]>0:.A5ne 2?Z@UH X5Dz슊u ?0Ynjc$:f+K}%ߖxM|oy$QΏ4*h7fkB@?PA!S c w&IwAx7CEM(D\8Gyix/R8)Pu Ffa(TǠ(q&YYNw6Zl@^Y;"͊RITiǒ:B:ndV1uT2Q?1hqSƌ" 'zޖI6wlU|*ڱm)Q(Z4m4~Z3 8ިbfF5T o_f[Q ]jT+Lx$%ZM B?aF#biڠ< IWQ]嬘s3A.3&dŤث#Hu{:羃Hܝ SU& ZYKUIz,bA< Kƭ]F! H7m9l=$xW~EYP܎hZ8~ЋkT$WpI*jtoQ?r A4b֭UkKrum t٘O@$_NJt dK!Qe@FUDQ~Ruu У7hTilK! <:YLPH02Jٔ4SdDbV"ZT6mDD]!+JF̘,IG6m6Y)Hi{%Ap2(4R+@]"i`[i>" DU;T]|u.-O"2SuB=NBʹC%9vG3@KiνI^QGA*JpA؅&t/mwdžJ݄ 3N:eaK'y z TiC6hL h<˹^2JWE&Bm$zz%LBG)siYI:3z xJQb,7q]!C Z\~UCCg@ȏ]EPѢLSz.Pm_7ٙ jN7j)r]ANY]Y\>mQX)GT :!R5FgY73)D5IbY!qD1UQm3,qU2HM!JB t>MH\:5 Z 6J2)Z54s&<&zl&x `ƃ]9aPa5A6gTEj~+.QRJSY3tyR!MMD UX`;֪I6ft -gm%,rj.$3S:Ɠt0x olPZ/K'P"(B:%U#ÙVKRU@"H|fJ.!$aA.7M\aϜR@!:^?1rgfd.#0y-rC3҃L^+ P[ 5T!`64Ta $b]?fbQr0t5"_LYk(e)BVh$ ڜ6tds/\1M*im1&=r̾k-ҺS4 9OYehA8!E$jBRAu} v&TO7Q?v)vnHMg܏ =_)tYu't;{t*i0* }K<StNM>D[S6i ["Mr)j"ŏ8Kڋ2Ev"b'HV1uG P29ľUWh"IPe>u6Y i'<G*_Lَu^2{<Ӷ+C*Ѹ".u?>Sҭ7sUT{2 s 'kZˢ %9PP%PFhmk9=6=֍IūNLMOLW ZF)D"fH0Fʥ ni>a$H0[M3H0]'SdmP{̳ܸy`e>FT2E̤QHL/*c"ëS7=QN1;uTD9"@ipY}nj; hv1Rs)Ɣë4T6+sT$g)#0L۩$v4L;Jiw>whQEnT fA&zE2-SZ!EueU \g`yZ@2oWb3 6B$mDnNˏ;Dw2BkcBbVQaL (f T=+Uu"f#LJT, 3;&E:"QG+1\LPyup 6'VFPjRb̈́MCY*Դ,5]%`Cs9("5MuhG;Gw(׀zs th4isDp濄65<2 }Êʁb ,VVn6P0׎T1!*m>l7Z2+MrS7p~h4hՃymcEMYmHbE0fPOIm2Q4`ЙTc ?jɲ͞<Kr}*Q̫BP+qgq/_1ۡvHJ1mltt :R( r9خ !J ҧNIP,$Mt}'x8uFT@!c'P- 2S5惛f!TdYi!L\tӌJeص@.}}/T&%A11C&Zb< J僘E`$2..P n<-NnT! LՉ YۚRQ^ZtIHΠzE DŽSڪ|%)f Q-&+tʫs 1pL V{(j lXrfAFrJd,h !0+y*YMS OUޡ|6]iD/SyGRTc.:BJǔaZ1SLX!C^mHi_s%3YI$zB$]U7j/t]RB=ِK \y;gOw -pvJjQ^d&BAႈc-_OC;Tt,왕͝)UUHBW :1t504 /҂BCBwaDqU |'&0 VqzqI# [m5UM$4+زNd1 'аAIt@Aܵ<EmJv~E1/CʨrdyPʑb>h nȱDȘ $O)o "* ( "f.:q 81SI~F9Sui竬T"O!^0 Kh6^!kۇ%!W,`݃D؝vzNjUU:3c<ֽZƋbi Ro~]QkHs@/Jw(_j߂=tr&9 ߯45ψ_) ` yD '@A-A=} pTcJ' ABg@ۗ [ =hN\'@\9Bt&S(Ҫ2$ P #u:*m[XaԎ!8nL&\c` (fCp5f&!v`, tX֜6gU?vQ). t@U|ǫ*}h=ƱL Xp6Yy.f=~?Z0&%\ڳ#O U$S;^˫ x%$n29y,)m\\9I%o Ɉ]IOA[RR.mPiCDJIAPb~,=RۮF4RJgݥ d&$seSX =_$[̀VE P $Vq=V-PkSEJĉAa\7?P3񪂯g'r;tV * v+<X+Tyr7.g@K@rQtC%]Lc˘ ;A=% 3Ap^hœf˶VoyzC] 4S[<ۯwbf3L;_K¨u ';M& 3S"E(^Wz}Ge%'- IDAT+u6B #q\a-jhq4Hlr#{I~U"P0.y++`BC۵2lʥLcCxʮv|Kp=8&x.c@+<LF2~6JQ,IpUŠf{i>Qȭ :| Q,t5Ȩ?-TFrjBp#5y<]c)4ruq1$1c3c΃D<IOtA7?D:*&/p3fQˡY;lf t EiFn֘^ 2&j8uZ ES.7s) XR9&fDbV- \Q yT 6$EE?M9 = -#F]@`* sL;Rp0s'Q>CuPA 1#' vJV€w| ji&eY4C)E)Jw&bWMHlD! 'rVRBdzćX;S:f= ciݭr*#P`ݍ- 0fܘklW[i׋[޾i|cf3C":bbŶ1PVƤ"8IJTJ.*O0 ʒh6 :8KzW(lB̈́r!Ì`-EIBM&c>LbTp^S i~dPXR5w}M)lu<(6&jLj(lQKoLR0 m*Vs_o17|0UJJUbO 5#< FJŽ}f I XRDP{*iNl _NwqƵΧҾkܬƩ3\!Ҙ7uUPq:n9#dlXKI>H*SE^%>z2LG:6i:̘]m ⒡E%c͆X c) Q vMϺkwYk>:vi Hi#2B@wlh;$ `4@tM A)mSӯYfZ]8:?8y[6130ض\/ʮaI/ᒟq9xO"B>]q,dvG}t_s,URgܱ*dq9H)aG4~ZXtacm!' G!D断qOPvb~47>3bvCl6ң^Ğ/!8g=.գC<>KN~kvJӿsνvqX { ^f?T?po}Sp+zw*㮪 ɹdCJX^,ZkAUq%!ob3@Rͭt_|&QTH }e8vq\k N90&Пn L|AsIkI.nW4hΕ` Y38W3⮫P'k^MZrq54KӪylp| ]>ό+气r"NmIq)el@0`:u#Q\Hwq(s<&/;O_^P`D'3q&[ =uda T)"R<`Ƒ8v"$jVt ctp9MLTsaciLl4EHPCId|Պ*\b0Wlޕ™yj#.H=ޔC{KcWύVka+ÛĉpRs`0%~)p;up}b|{ ޴!8Ľԥ7bbC%Aڳ@S1Hj6Bl/ac [c[8 0W ˸hQv8 nPiP~(mY6'[Dz$6WLRL@%*+ꀱ eC#Y($' 4FMRCߝx!;k͆۾Ofj)zbu* (RYN/1 pu$;mÁ?r7pyegJqeI S>`Xm8:!^:~pMWu3b[`c*WĄʛg>5hD_\AX5Uw,%NKp\>0gL7~1>\0;uxR@ɺ趍@b: U#}kЏ^YǝC&/dr~^'K͎^wBWnL j؆J`"ZެG+B8ĕȶ] y(@q3M-56֝ @ɞl8ǽTS2&2s#^x]\T p}!ξ)X:191ӎqQq-D~7Zr&l4n U,l0 ?V{=I{ } цpI5 iZ|ű+~x8]KAQ%«s^\Qk'%g=Js tT;վ^Et>iG)@01DŽX+ڀy͇_͐sWYץυƋhCEޠ WE]xZV[]|E.^Oo 8̗Y垫e%Uן~M}O^|WtC'@4y,g=3D XسybԧzNTEF~%j^t ɋ(Xǹjb&d2CGgؼ{ݣ ʤEs;1#C6| 7KҩvxJ)A_ уαsqk[J&pԐl筽ga;DGՐ} vlh?옮Wv${up):gO*9:78d_V!r<=%HoY&PGkwGY1uBO{g8WcG\9*o̭hP۶qk+WÙw!]1&O3GBnL 29ƒɛ%7GVLZ"0u6*~4n%Ad hMu%d ށ'zn p{3Gd2{B{e0rsY|tHKJ-Ӏx,ewa!(h`^P(+{X ∕H,a9e3-\Ds-~v%sn 00x@-zmoJ\9=X5Soœ @Sl=&W7?$Waa8f9ӆQYm pET蜌G'rZc̸quI8~Y .40dsS8l0;,tڠg;³&B:汙x_3&&k $v);cp8cTl)TWA`CSɆE 8W`<}A/>&7|և Cl))hWKS{l v߸{T + `:і|nZ f^F٘jk\'FqΐhI#1mM '!Ǜ#=Oym―{ !Orqa Q^tv$1!F:;gdRei-.f9eI6! 3䕤e9%cVr[89;UښH }[}O9A"_HAɼ]`rrvWm6tA=O@EB-t1J sR|-uf%D.tµ[}60o IP0#swnT 55W5l!녈`ãW;[9P&zH.5;·KS/ĻMKs `Csj!JxYO]靚qć^dh@ dޢܓ׵dom+ςIXr1!#MlX ,3'L0dZ'=xYmN臇b |2 X9 wāio5:;sp%:cvo&q^dEj .Gs|j'9g{SLVy&~70>k$H>2 %m] :S]3_X d!cZ&o ޳WX _*'vgCwDoߖ\IݪQ𳆌1_zex~/@L8il|1jb<7^x(. dV9%&9h#xË0/Jc+Ћn3!8a *uRsm!B u#Q8obagSwW͚c^'cg[ydv:}|c馷l^嶽4GZ/ZtR>WD;"U|JgnAEep4ls5vJpS;ڙq2KXd $ZU@k{=HۤPso2!6C}(;΁wl Z$'ގۀ=FBA c[%Nם:°-LAX?2 jZG9ДY&$?ئ p>y%k].k' 5xq,% v|^_3y*Tpzd*ӋRј6yK?>?l6Iψ.G_'ml];'>Cuavn.odZ1{||v?wİͺ024ol Ne toFW^6bYBjPӏ5\Yڽ#c8k@۸`۬& qy%d x:T8NID< DfSCdcXat]Țs"lN sA1\W"vO\K_9570inFJaŋ=ռ>?P~5owNFe'"]Q+T%zmG`%!'\muڈ9x̴P݆_Lvu=d,n\vkve{~o.xJbvv9K1yaQ  Mq,Si'r=5q0|W7hkę!c_C9HSE7YL'TOA.Q8L#nt:ܡqq v>j t;u 2[’T(ޖs3m.K<{*R mS!!!4(9 hj[).73jǜ?Hʕ l·7O v hHOnCKc} vLۣ+ۚk1Fe/7մښ?sS/>:WI\b\+.I<)(څZ`o$& uYWd/W7w:]TKHAjaß$PiE b֧a)#a0eÙdd*8qW4J܄ߨy{[7L"ne 07e};ء/u Ix30COה(Yt°gr$1't<~@3!O+=S\[2fG]F9AfauP^0aKgɄ`<Lfĕ|'[C8ںyVŖ;5N&?ˇ&gck3hGVeπ0{ & X}7cc睅˾byb$ݸtbi->[>ŬwNTh+,3 _xQ+f"> Yu|12UN$u P"};mfэ|$/ %k:qnl`=ȐW_Qr$^4Y0I^w䟅.eTf,eؽGxђPt'QK͸eBe0W4\#ރ M;,` .^ Hv5&xf1cB" +FXJ cH1s_<' IDATK&QLWܼfn ME+tbI̩[v_=\V-]AGK [}F;}OqoD߃ rW\}gy#6N64*b޳:@Y3!nZńY!?1֘>yȊmhSJq^VXG8|#y .R17^_o~{{{?p{˚vadOzs2OyȁSZ 3gSؠw;;evg鉠 Xֻc.4Vs5Bny#z&?71y!#2h`rhxud^s x$ o^ָǓzkM bM<"H^ٿA:unh%;0P6$O !J(Y4oܲc5{?;v ߔ y~k'mActi^LڪǹKyTZ-CiC}faЉޱ/%ar5Sl bA>/J1V?nYgt,ݟZF E7|*,u>P{ 6ϣRC46QҚlTM%Ѿ2vNv ۟+6?aS֧Qܦ4|H;5-پZHs<}\t)zjŇ0c9ˢ}# J'Vpf3<6CrXsI carWTF ff#0r ҃ގ+.2,<ϰgх_ڵ$V5.ٷ ~3`FՑ[G stݲ58:Ρi7_pCrg71&.vP[\<6сqYrLh:KikWQy z;Koe L~#Ĩ1*4x<^wBuٳstUˆfj͵wWGYo5D昊nH3!"ˮ$HP'y6l,\* 5Xj.\[!:Q2UG\}gjɆs?5iί֕0 T8'1;#Ys*2~3+!XlU֚\vtx(òbP0Of` f4]IƩqjy9R:R:%^FF8hqS]|C:6XmnjHqv mJ@8l]ih,Gcߎ^BۤeȮ,e+z%=uShGqa?uL2uGY:g柉9T )隴ngѠ2LaQzk3ܩK?ܾ_ʛ|/ß|SC=coZP0>3O u:Jx*`Rvt 5i+z'cYFp}wh}8x֬0^lS9raKCu b KS{{9&h.@G; {5|f BTs{9{3Ek 1L'N>Z{[iض 00Gy )3| \"m~Cgk 0rB [Wo&Dyf-l$169V#!%{f "wFRy<%n|al&8? M|UPn(x3uFkz<(J8ɕsɦ~ ANo,rٽ1ڳk5O،pܒFAM5pxO{Kyd3ul:l3x:O{Jbo&g|+_o=u9g6EExuɗ{C6^t\`9w}>QsyѸ~G_^m+"Iy/? ^[`80{H|[!CI'ڐ_WuGW.t?nw~÷/~/﷿WW^9C$XkN`ș-%UuL;  %>֐Wц hy “t]:a On;LȣZƹQ[LJ,GtnW?5ūATna,)xHˉH KI/%.~eHZ[S6Ǻ '1bX aq'=^2,.!RI.Mf0!c8SE`vO2fG޾9/mIel|ȚS|JEϧa!Ͽ[!t^#zmfXFqc7tu?5\rLs+qȵ7}g:6S 㜼38IBS9dO!́JаN#.b346 ҟ :|E3^(a%C|΋k5Y5Q8o꓏S?۟C#?KWo}wdЁ)G5g؜O%rZ^bwteRa_FԘlw26W'~YGbLÐAk\Dk8(33,]`UgH Kkd8AO kB*7Ch6Hb ?`|p,&Uϯs@m7M*.O6S1y᫉f8O'یI_'vv7O>}~T4|L!fyeȧ,yYRP-7ssD9oH?cJ3 ފ}"t{+6-*>VPyR1R'WMF$N$gs/puQ^\o?hjm%xqYGmfJȬ {.8=/ `gT/pvD 59rs.8+݄(s>S|0k.gM{Qq+$cS);[/r<ꏭ n}^x+_{Mgpz~&=1tDK.|*b| 1Qp f!G\ :w3"edD.~RMҸƖwܸGWUFŲEAw44o^9aϐ\Z jl{ ++)Z)Xɞ}X%Ajܢ k'Jh>w濻g>{{o|o|_|ʷy?z{)ԡc˝#`ٕޤs[=.cvliљb(/@R@0};Iw,/4FO~A#UI $h.wGe3s5"}as”(' *:`c U=ӿhg+,M/u9Ƿ"fiv^"ʻ\6ਸ/CGeRU9ָV0T*, +uEIp`;bq=9Ń($t HLX%O7Bbʎ5 ,~I8<ְ'8R}׾tү|1e%8?s{Ӌ'^O'Ft^rRs1U *hTj,1LjO@pNp5)&biUr}e1u:J[lg,øpK:/+ r>4́^K:h=E6Y#1Gj(r L'IY9q5w_P&"ٳC3d­zEO"~zS*i\/F (Dž\!Zmak uX=1f;un_ s;Qg,d؋'pABaK/'6)g6xQhh^>'=O'5rxZƼMtZm.@6F/q,FFX!lMsDn',W^>(FPs˅,3sZRa<EF쫠N ~!c6$}Pg]U,jӛQkSf0=ڡ9ř@9.YOp 9Ԋ>̖y¹&m ag]U(|dIZfX91wa=-=|$Yu lWձeىy Bh!+rKQ&# OvZg&.wMN'屩ޕ"e4+3F-W X3 rr;cUK9nMNya?㬥Wn<*}_\g Sag>{?uf_K!}xkrժޫ?׸eryXC. 5]Ϟ▰e@֣]zspEXEzdrͫ-K~mfI:R΁$~bL/< m%NMe1RBIFH: k"E ۳z9ʃwLzN#C +z[ؑ'-a+yq[PXSAzRb G27ȐY=H8i[.. `tn#qo|y}iu`χsZ1ų;}APLơ;"#ʜEi( <<6Ӳ\>'dGl'Sڣld 1r:GHSՀO uLw 9+ƹ&Jŵ1ҷexݍL{<σ[Y͆f=4*0yA<[Kfr{z6,w{I>ww~o|ۺ^~k_n} KnT-s;'QdSOOmið=XY`ݎPQZOڪMoS0n[r60I]rh|lbSƖ(?!,8p1yVj|h CSck$nJ=1prЖUzrO%˘Х]%8_R8/1gp#&Cg٫+]'x67gy|tw67v:Lqhf22ZͮgQ|ZَFl4r&N;{u&F"3+ybbؤ) 9/=q&^gYLKҸ-Zd|OBtSaXz=dTPSYـѝ`G R\U~ˎG^El@lٕrPQ˃V v56)/,a30s ka·l25dMBTh\wXvn%# e O1WHT^:I6ӵD~—y ?6.$6og{o(%y/!3>b i-|#c]b>πl1upZ⺀ DZvԙ`63# @=qq,`΅u&J@A"Q#6؋ڦ;JģQ;n8oA]w]h2I`r657^%pgC"GE7NdλZI׸Z5c`ّTq刷B1uO߼{>p{W_~ C?[C?_ODzḱ-yt&gן2 4SKPg@#$ړ:AUB~Q1Ǚ R퇊nLQG@bG3w]%͋bClLlwNe PM' ΣǡX)kxc^^>PA[N){P7r2)'k\$ =mS!0?z@X^ji"ւ<+n%ͧ<3Byރ8-fW[2C_ZyNdU .\>LFB0YvÊ2CƁf`ԤbM/B fF@(D2>9Aϗ+y+|Bi SK<#c,x1O-3@O? >iVwgy#xד2$wʈxZ׬ =ĄA^IFT6sかΧn5;Lb\|b'Mc3gT ldd"F']؝ʻWOz 2{nxh1YN`yM\+<A6:_Rzn zQǘA`o?>^ޙI4soWh+,q${55SaVt&5?Yx Ε F Ȳ:Jw67J`/rv>/'w2GYK_~r{AK_}Cs3FRHV[eQ}/y(Ӳ+YΩ5- ty߻_}5_qʗr)})6cq{Pe7CƨabS[Ÿ虭9\IoMaK~^o}#;=2G䗼V?3~|{w@[OGThU]OHK|r\L %$L DEaYҶ 똢0 M‹䯄Lf<X3h\= c/BYgxӭv׉Y0ZVClkrܛV+hj2Źj;`؟SE ;v򤀅_Ʋ*vsTStѾ$SdĄ.nWfa@vfd(Kl{τ2'ѩ9!WG cY]t|KHƠ5/5 WEB(` ~EQ%sH͝@ a["l{g6*뎰:an6b{V_ɢ0A_c'bkZ֝-?_F?x1 +s 7Z/==H'۟c?tr? ?g% DN3&5rV/N\믯؃ط3ُP׃[zN[>`/|_?{Q;ͷnWbOSϐ|C}}ut+2CAe _/Jɼ~ V.@]7\a#'cBcC 1|D8hyBⲞd=ú>ژx7KeX&%( fg[Z3^DSLN8LUP52"9(ڈmmsW +\ 0X4.PYgi9D4biϞ Wn<~Wp<٤D{U^^|^埽Yޏ~^K$ʷɝ,=^s)% O@ϮXj%Ee* G${H͌\ ~DǞ* Z'+̄J-$rat K=Q(m`nGM'&,|z˥Xޡ%CYWgX&1K' 3iE:C;Ps4E<60]9 ދ2/Ob9p DOşn>RY  ={u|ӌ?ᑨ\} REzxva xA()yR9I]g yp3t k OP%+wsH1y|[: +jrNxjݪџ8ZX5!麯Ak)dC ?<-8cQ!?' bt[pq]P"> ݘHm{oX{qTi@0.?*߱Q{X5k/B>aon8*NBw3*U޸$= g1#P_! ԊߡRȍc_7,uIPMu̻uS<Ϯ8 k"'Ïn_mfxO>|bSyA L~ccFvzL9-aaRP2Fkq>sml5B[|A޾[('!z|2~#yQwJ9^$2Cࡲg&VN/k530㙤V' <}~ }2u7\#;_x /KWf&R˸6hz}qmPYߩ/Z1,S?VI)Yt;v{a ч<)iΏ&szƬꁽ; \aPDlz(18׺+EɅ Po$}{^]gX#ۙ,xXޔ+B^~_Wh92q}DDZYQpV~z&xa{|m_pgGӻQ8?jxh:l-}rԿe!z {ut49oK)Z>o{;$9WG5A -slNOk)ܯbw#/KZ Hu>y_}4v_0zV/|5-CR5I>H^{G&E>tIEn;cLwF"G\2xfp ` oHmW05_ss*wr0{7b 2, =`nr@q];"u3 1 ǃi;`}I^?]2&׳%lq?FL٨50J].ິ/ PgìZNkkqmv3yu%eԦ҃gbB}^X*}G8<[\㺱OȒk΅'"cc[-'PchDul=.\]e*LGlzp6p @;],[+~[ 9?Ӂ̈́O"mMJnryAޗkv4dLe#!}mOPk}tyƨ osAfDyIS|]?;?T>!_K/>ߧܪԐ7$U/g]򈪨?0mv\3+4Am8cԫDBCsk'zT*=73a\0B{M<|y>hc>0eX֤b ]<c$ D=dʳITg=#ɹ$ӄρ !LmP6dt %>QŸ&'m4o49R*bDj9r9`.R\L?PB&mpy=<䚸egG]@<ιu_.I|+́x*:V6$ M*H\uPK7QB>رYQ8xcSd1ScLeURf+ᨣ!1}zCV빲ӬdHmnY{:e"A)xhWapHS>~o'_;9T|A+~@M;<ٟ95FǦ0 cSf_#7$"f$]}Y. ]T^N?8j7@|#L681*A[ xkvWؓڲ RŴWƦT@Ƀ:Z`:+pω y~~I~勯?7~9ymPQqqb : -sBNc-}Lc˳f´a.6ģggX:^7SWbG])sbo~ޞ|~֕륗nMI?_7>#/D`}Sh|dݿ+Le־%< a=4pq-@ܖdc:}l_B@N-zf!2%#ުyh" Ǧw>y>R[搭'CRbܬ)=W=~<ޮ2gMc.n {nȣd:[^HP.'w}xɹrT^\;. SeN};2&obQ?ބ!Eی["e&znjܬp^UJXBLe6<ͅү}y=ڙd-sjJ&ie=%f&n=Gxr}ƴ4LxO},^$$}pLRifcc,CP ĸ[b&w+ׁ?,ly2BJ9nو1#㊳A027V"4dɅ-ӛj**Eh3{)lD#A)߮ln jmfѤfolYd~ބ=;h6wzCM'N}$] {.f] 6zr)8E`( ?Ծ9֜wb ҝ"9T[( r`r%XY\F7eYiGаvexR1a/ʷd=(jwʗktG揝=9 IDATx'FYiP̉%fv;A{7̒s#One$p !0uu9Ɂ@S ak;0j~nDB &ofI쵊Ksh\ؐc22K#獃`{N#V32?hGVs1|w'9~W^JР% %eƸ"]65cC!v3Au_;ѐ F#/t'aua%#@Ķ{Ju]93Znd']'O|{?GCu~(}[/س5] !g:YЙ0!a o)Ԍ3¨$g?`8%P'q|Gĕ~0 |y>n&Z*gRN=Ex2lͰp=gfu[51gDD:B:43KH 0l1P9ӤɎkbe0't3h8itpO~㛇?1nk*.!r;:QLN,"3߉%~c ʳ);!z̳kHPp>`ܖoO^xWoo۫ow_}s__?_t']G>o/?_wys ^)yKX}~d't>~rBzL]T,_L>D\Odط>-5 erRCW[C՚ka*lWanh%l0v~]8sRzhAA.C'|;ӠS_ksJmzh0ujx w+ t]$4&Z1VT~>ܸ ?Vkѯ|Pէ^ CC n&JN?9T(A m0b@]'j$vό;hE [F6kVA8fߡ#忠}-_ {&k k!LT&w2ȯbFpGV tj]?iLAm#> Az1dc8e Ğ2jI:u;:&st7ew9Rc A\.`G݈pG}H g#(J`6\sx  >Os x]tEO iXB 1pnM(Jrw:tQ%'lH.6r~/]f u8p!d&)Yh%C ' r!) 8ossP3d= aSruqPs ݚʻO{G?ڛGe}sN&229B JE8`QպtY媫NX ]U]F[VDEƄBB朜sz}뾞N]}w~~{G>gA™TY/xㅏ~sz[1ks沏~ Q_G^^\~'uy{>?|[x'}}zG&]pm_hҤ[T3dO|#|޹H~ң/}:c'MoՅ=_ *j GOz#;&ZO.ȽB4pV˻c~}?f[vwk~ {/?Ɵ<|.D<<jVL9IiNHtɄ~KN}TX#`n:r9G|>>'ޖW)ř,'Rɺ"7m֓΍h'%4h; :cSءC}o$RVl cia0A :wM^CtJ7`cl 9m";X8z-xuc.q5`S7ଠ}Y(e :|}B,ŬͫÙsK<̑GQmc8ƆIwxfāvnשԟ/VL!|[]2Gƭ7kNw#n>_oDXbCugn+! a,"c2t#YҳKF#=$DWT2)9ր8Tf\1_azQ\ fCJК#mBX2ξWA_.~j,y ܩHw*Q/ XM쏴C؎ OR;NJx @J#'Fz֊Iw`!dUO>Ό)Ꝋ_ LEǮYqԸ{Hr+DsEap: *xfgg=Qm1ZL  ]B!?%Ұ`(A ?nRڡYDxh O)vqҿn  }H{s|s w<2CI;N:Hv[g=mRkΩ 0@1jQwLg^ÙXG%sH{k"Rh@ClV QgGs.=1Dw1x'94Kqn [q6U4&r]T~SF܈7$[n]tôˆhɘ꯱mub (mc:}|`j ֟jftg0ܱ$V| /ZW>K&ϟnk l{j]y \\ǟ=MH7(@}*]~W~,{_Ͽ{N\U|'+O- `|'>~Kױ@F~Sw'zE@/_"gO~?z%)orsG@uktyk֒i{ӏ [z/Aoh?pȽ|ޫƫ!)z+r6c7{6<*=ttQᤌRvNz$; )غrĽ4夺"\Qnڑ{m~G^!g$[p1ܛ}hmqj&鈲b۫W#B)Q͍~|9HwiX퇏ac֋S9J? hK4SR"7 l?F"-?4';al |b0pQ=)Жop\Y1M1 $NЍ1RD:wi\_=I7 ׺p7z=Wy/[7!ꑓ{l''5a6sփ<#"Sy ?&Be`(a4g:m]pٓ[Z B:[-kӹMʃ9`+ /oQSy?u fmy,9472n7yֵ}ڦ ~,zD3K*/ xt<2"NDǒcVǩt\Lpz G햭mݖI&2怋wx8rrhV>:m 9B ujLK:@\Wێ6'F1NvޯD'r^AX&P,RړTFR0 Ǣ"ۼ))G^tcGO|^gJo7]~z+>_M_S?>߰|ޑngW;gzCMPBˍG= En@NVo_|LT\,-|nnkޮbmPs>Q7UЏ[?[nަ}'._^q/}>P~G߼iE>!_m)K,¦r\7#y=Bmi֩@h?I=&ejhp+uZ> )r7#f(.i=ִ&9?q0lF擔A[Lڨģ[VV `훻|&t+zHlḴ Rr58Ģ= ;- UNNֵn3}nk4"kBclLj>N'rCբkߣrDz`eŮ ˹UO>15E*a,kϧQ(+rMނE֍G01}9Tvwq^o|ߏ> ~ͯx+/!z}%O_ŪSnoK?tKzD7_aE_K>UC>|~;^ӗyӻܫ>+_tJ>=u򳗟=뉗eϽş(9W~ׯ}iz%a/߭zy~ݯσ<˯u\xk^vSU>ǝoAߪW;>pYE_g+쮗?q{TUOL|Əϧx_пxʅt&fIKdͼ8OSr3Hj z䫿94X/HI@ڜ9MَG jOڽ)تLV^PEpb!7S[5d#+n<̟5q?.U]:u2#q!4e$kCi}jg+}AGT4K?[}iM>8d^z]P Qp .Lɣ'K'ɲ=D\[nӊjiRnll!տ7xsTZ(##5]XfK{g!Gjo<q|'Q'<WQ؞FG{&3YӠraz[*V8$`;rxo BRS1;7 SPä4ؤl7vr ޚqЛ \69zuΈwd_mǓ 9"<:8*pd8d4i ؂vƀ, q=TD&TNfkLѪWeW6? s.Gs0. DdEc <'h?\\1$6'P#ob8;s"rmϳjgl6sgS7Atu^[zޯoMzK>i#'/_#?ߑ>gk _˗mGߠ3K#}qx?4@>]f=sV9sy'R.^_>u+Ыoܫ|!3;ޟ9s^_9kA*o[?py?|゛^70^{.Wx'= P^Ի.[~=}? Rx} Sv?ψyy/ Q}{~g./\xuOwi zDhc,Yg2&۽Z) `>.x NPpsdZ{˱Aj VmCuNyH/} bxGD pvƪUgs4j.0ʭlLK݋mAvxRRa!*nhHѳ9 fL%]m&2Hd㱤vWڵt:P&16i#EՆ=TC) O(3$37+&6yg5^4&SONd֟C/9Ʃ>kf^aa Eҵ01=d Wb>1~Z{kd88Au ]ȬQH=,@K2z32ޖŇvMK:D;n^oՒKㅴ1pmbNAI: fUukO Ɖ+W#;rp^{:}$&~RBg&`wu e9VCYp~`T'1簓ւߧ4ٝ^ouƽgCsпw߅-c4RekxD0|FNsBotl!؅junq#ޯm6畡jNŨ6.r5;1> j܄4vlR_ʠ6NMŚt&| ø\˜=Nj\&xI%?!oкI)gN+ZZ\`.[\>>M'=Ưh,w_wsXG䕑||.ew,;|_cۺ蕏c&7H:oOOuI݀}+!I y1 _%;۲ҷc D6Fozv-e9fsqRGLi1vzAFX %.~Ĝ㋋ޞ/f 밣Var)&c9*XSOJv3u]w!\h?3oŇjZ u 8@4wc+J g;}]MT7h}*+ Iekjyĩ;.$8fLj:xh IDAT[qdip6X[\奋G_/oJDŎ{lÖ5)aBf=Y\t5'nH)kx{>&Zn1cxKKxz?Ƅ2Т7Z.f˹[ i][2gy25YoσGp<{z[k`nFK@量[xホ~f1youqn{){|! - R)h1ZݸM@} bd\1qH|d9d^L:_.9Y'flʱR`ktR_ږYZ),KϢ&z̥̞o|m d5 !QTQGu˞BFߌu]Qaa1/eZt6Wz6rnyA>^Kiq )[z@o\Z[& Nۻcֿ .Q3b.;0er6XjYTycR̎83o|^ylݼNO{/.2Z}-\r,|ǫV ]@Ozm^M.AxCuܶÏc>_W~w6'Lxʼ]yVz Շ<@Y#Ez^{偏e7vW]̮+~ScQSZնOٺG2Wou7>>Ode{׺prmC7\Yj)LIizx:r)C+C2 <a-s@;/0uB V* cBXĽA+DBDN41-9\c+_QR#6񨵰|@o_kNzUn"DTGndMY=Nr8EfrkvVb'"].Ub% >Hv'kyQ&4KrފcN?IE'fh 66B{qK >QL=l Z+xO`ϗ9re㐸| i,mB\ӗwXMz&;=*v)й0fnEÊ5ƥslcݞ|1Y-a7;0=}$a1OMA{ࡋ mMUǎE95@ 7і-Ys[9JxUPr]OImZgpF޶b}+(_ K $c>6~Ap֣,@XMwd\}Bv-`Z\ku!ad:4]Z(:8e/\sދ.{7'_pL#8)|Dl.6o֙V?zbR&3.>{F] 7*?]zo7Sd^_iǣOՇ[|##c7{?GDU-~*@1Q?Z&wٲnQjomn5h1*ۇУX{J=<0PKzXQup^[bsRb)Bx!ޣ <:|v)]/>^~ϩx'|R>~[ᕏw A/QgUc*#7 J.EVaa}sPn?=c:Mx)C)#7$'ƛ>hpXv}JNqS(m&!KbbK֍$ThM֯>Y!өJǓdo ӟL "ӍTSȶ0hbgރ3`9R9e,^QTiz<`b5YfY̱4y ޜG]kz DMqF5PPK'"n,R5B3}D; c^؃iVrA]hmS+V:)i}1":֪u֩AF #\xs]1&oz0M?mQkHIV"9=dtg>ԓrH}o:s|nivKB=UUUd5.&!RCelrbHFA۹kKn]0XN_:.#W1j[Tiƭc7xG8tU6 0j_I<}ɺ ^:7+x iu3K{C'@NAǶͩ h;n*98<&uvۻlnvנ9 i/7BuYxZ J<f8QnjzH&ʼ"zV|#([Tҏ}uE>1 >Y1OA iiYw }#ysǨ9;"'44,ªfr̒Pil~e@<)eA'M'%e"^2:<-a]kǏt|XL%O,W!D<@L|0ڵTy,O2%r9T^MbzMSk"Cimy' +Jt'+G>ɬ)[kGUAlE=밁2EL]7gRhB4{Hfsu g%:c5Fp<-Y-.Sphw0Rɢ^{k~i^>y>9NRWw/m-k0z/d*bRY[1Yk6H%WV_ҁ#bĆpk6Y}wݵm߲7^ƓAZ!};.}0u"ҾONW?Bh?|Ts & v2(гC{y[;滱$YOۻgh~9ޯ:A9:GL~ru;ty`l@G<715Ccv}0~HqT` fĢQāAIg`*Ii;2Aoϑ`{@!p̹etIԨi2F{j}d:ՕY'?~pNYr Cu'pg;t 99BY*T}̯'@`p4 #VP…(9F6sc!/Fρq3ҵ-8)pP<"/q[ƌ(;sߏ&yxv&I&f@~LC@(~Bq)M=_8֢׾|Mi{ Ƅz¯Xlä~,Xe"`*FA0eTqMX1Usм-Ъ4Ѵ-.vm\ mHidã13Q#YUM52cӵIAo8ml~bAm;m^[ln`N ¼R= &Y,A-%݁U9|LI1@Mxd=_>ń.3>{@ O? ~c~ƃ5<-=۲a5=Y^uSN){/|H_ax~0Oˋ粲'|zg K?闿=oN:92.m[_>e"$봪knmɈ@V.UD+LQcȎ"*I!XU;lUs=U&Xc܏N=ia;{<߹Y;{rH&__`pY6j$㆗sj h/[(gB?t\2$񵰖<vD3xs.|W|7*Q 0"f=D 1BH`jI]vƆ/8wHI Hrƅ[~H³_uQjK/g\~WY+ ش? 8Z$_imN=>K?B5/MiѷH)W-$r~H zr|W>BoZCoW ?#Sk q1J΅i75>"|ΓaL]Qu dZ=^$Z,7Ta!Vޛ,څ:3蛐M)IS;K{x!φ^䦓>C7Mi.7 mKN^VNp&ml B~DO[4t5._@d?ׯ'GHʈqbG5w1yx缲aѮ/S-8gp8scf?ZV8>8VF~-J]]D9\m H35Q[;M%ha1 _أ_>3>E p:O|#/?~^8! HźQ/V'<ǟ}5y{e ˟V>}~xq/MHx/|v++fw|ϿDW0hxR5H?wy_D5\spAv꯵} +%~ YIc}YghWNY(YT57EY~IIPatI٨]jH _ݙN$w1ρ@*{?o7O/tF1<GjF dqؽg 2 lu[8\۠~rMvf\XOkDHW+ܘ0.GaMj7ςiW7UUE$mc"(3hRڎF^#Q0u t!AJgjLʂI1 `ÕNEYe 5w98 Zc&JȔ cw%cDVlƞ*Ζ5kЎͭ@4Wg^Փ󓎩=(e=qi=x! |@_ nm. m{t^WWp[~}uyRjz zǯҷ|/s_DZ5_mVw\ޤ`|~o> ͕e˻ noEU]>%O/RƷ{1FYr]?~Z8|Q[\>/7g/so#_t~/| |~] (ٽz+>rݭ}y?x<Ífߣ1hNNk#x-M8<1J~*zYPlETtwFI2i?эvJfe^Oc,ʭp ^KPH< ܢS`](N5K{ڐv|{шQɞy]% BWiz.k=+ ̃JxυЎ3$4J`wÊ0- Sb]n\8GR5YvR 'n\̻9~@F#᪠['x@kR뎨=$ޱH{Kjøɻ3)v Fsm|n!`a(=Kw?Gj*M )VьNCk7I_O^ 7Jpv#?דXغ  cw[`!ߑd7NrgA0ȷ94v0T`{$` !JXnJz^S  u}FZ.ъHT%1V}UW\7 &musfK0t^8d5<c7 *d%nyB촎p( IDAT%ʷT x6VX:2D?YAɣ[|H巂^W C/ΝX!(QvL"7 Yj._KbLF'*JR /~|NgϾe^~-x~7"?~L~R}W| Ǟt?;^ç@o/}緌x7_=ї]+;?+gc%Z7-t;OIo0z&1Vyw-}IY}.= y`$߷-,cdޕz7Ɔө[Yjy3x3?Hś]ر InY%^bU.=8- IF.jj$ȎjfYiߚVrR[?݄u`P􁍢"4KnπjoeOuL t]W?VenuBELԬ)t#a{lTe?3_GvO%?lZ^h0kf:7v+ю +*橩|N"$˹ӵ@$4s`6%M;FN}5@}r{Nt5Y⺄9! VC;Ip v"3=cJz=:9Mͺo) v(yC@v7 jf尷}sW's8ˆ740ot5.W8cx|, k?s*7N=x }. {Ko>3w/_W/|яo:Ǥ')X_yu]o.3>T֫$^Wos+8/~μjr\AussN!m56º$.`{aZv*쉗_o@RiRIJv1Ă)ڣ~Cq0nqi35@ocF}?k`?l3ʳ(}4UٟŦڷ@[z~Cv;- 9kg &1}|vא$yC|l3uaxK/_jFZkzۚ 벶AVvH7p2Cb|L |\4 aWb]mƇ]ocGT;f)gi;fFR[= kG Cxc(j$[>t d:&N&o\x`\3 8'!TxWU`:6Hʓ:Xt֎B۶mw 3Ix68v7;`Ǧ$wQUVXC6w;~,7rn*_ۘn}w)&Ex4^/*{@\Loy|۫~/~g CN/y~‡)Yz>;k^_WY_:d92CAzcz3v;o|_{t?oѫo;?D6m=zj)Bë׾^[>蛲nVr3.oy.ߡǫ> 95ˏż>xɺi?+@y?j/zS.o׏2M~*:0Ik03#ӽI dF5jj]~@:GyҟQY!dr[3)زaχd3oi_Xˠ&Cf.NM.ĢqlgY-|;|1/ϵ$Z+N`HήV\:XL\!9/\ịrW0E, ?Y%)Igp&#J\` BL>ju*qs$]TX x;@ ͇$|T?3i,ɑA (o݁H`z/prebw=lo2S訚kTO=kⰕW cя)s) Vx+W<&l :4m7/T!/85ҹ:ѯ=[s!&/I\M]5q;"tU`?)>w~՜^qR oŮJp/X zbJ9G%|h`sun-I4fBzN.,MYQWh2{m0 )G #"LJ[iGĞCCq֊}|ꠁѷ_ tgsgLn1t(Z/:+g,: +¬4.;&s; gT(z:GǺ`o߯ ]-(CZ]|vywȽo{|DyXe?JP0{4| 'qA; Z8+x/q*7#lwD_6|e[>znFU emn17~m J}nROv4I]W ?k1y,ւ?>[54cj5Dm㮰ceo1s sY m^8l0|ڝ%nFЃ.R·*FG*Bi~oU,Ne^kLf9zHII@,MΣ2hijn@1~D1o!n+ͫ=֙yO"K`'|W ?0;Cƛv0WG"aU躼c~}h4u7Xw2fF-`h*v?ܼRp327"0) HE!\ɦ5&zwS[gQrq6GupNL07Yo!9wŲ%tskMcODc1j\HzDsqx6dձ䑃3yFY2CMWҹ _ m ^]n02,=ls|,غ ]ǯAs?&藟ui}Z`E ϙ#?D0tȩTM\rbUT*E5/쭼bF9~tJ'5 6)1=慳0Zik!Ru \ʸ͞鰀WCx E&ƩpݒY%Fdk M]mk%hA5cշ~0F*Xf[JV(R{aǂQ-Xyo泽c6$i1=#O9 >H!ggzV,ul9F4VC>relO} 'H\]3kҭ L րŮC{>>%'e+kW p"g0< pC(d!';#؃6fG'4.`w|l7|Ʉ-^p#9b9fNwiaeqvP506g޶5XYwg|J((wvxZ#7:')nR 7N&-6Ԍ"$ȃ+>Whts Pۜ1FCl#ZsA/ >#5|t's?PXܚ>!3nۉ<0 #;e>qG ne2M9{ZU5@mG~Y0Bt'bѐ;Tϭ',rtby F<9w0M<`2 0WM^iIrf"ڍm2|.g܁÷qMRgޖBn* хv7 ߪh!ՍcYvV]hev$h+Nkh}ԉy Z3TΙ 0`6g?Ce0HHkڝ" ltg=8nޢ!ym&X(XmR{*͟,CsJ(3 Qo:ôg.JK)\|4 !e4K܆U]@6F掠<,<$tc&wh(7208YU`6aS€(5Ww:FVgTF /2=kͿ`vp9pYQٮIJ1OkH±jc"sYμZW2 qLL,)1MC[ 6D |xb⣽hQ_z͌+(SdNaș\6- ϡCnl鰏BDL_׌^MrbsNfd1!jz7x~ݖ\!ըrt\qKvylrݞFuNÇNINɞY:oImᕽm<#~x'&?8 (k: 4lD]eyEraNWd;&qq$$;hߖM8di }s56ý}5cdtp]jm|7R|,R˫8!3(Σn{su]Mfd11(Tn.<Q=jXG:b;pNY/9Lduy@ ihNL60 F+4P2rI¥wi i0 yX7%/US 6՘pјc4q]ˁ@N7 yqoZp <#Mj1.bam0< AD&g{0.ǴsxVq=C q~#J^EaL7Q46֑s)2(GX/b@ f5:p876Q+ՍX*Uhi'^rx xqSrV1D^^Q m %(#1GJ.(I87'Xv _XX t^> K pD7i ec[XdqW6<0Hc4gdákT yz}[Ӽ{hWs櫞OK'y۠m&NNSӨ8meu"CIF_ؕ[_GZ=RQ_^k|ܙ.T>+օmW&C^; I(gkH`ajwe)|EVvkᬢFo|U{6\}j+ RYy-. !PWVLDqp 9sv# ݢ_z 7˘0kXdo,Wv5וP_iomHn۝z:BۭŁ\Κ}l;FLjqp#A͘Z"R/OE08Q"ч=ju3\n@HIcM$rvv:M_Id6 H,򰌞 7_ȑGa>|`bB0#$SfL`ᴼqT6]$_IIMf' K쉃RiZ.F>@;Ʋ1|{jzsw썧(S #zY} :䱒؁Ǭ3$GIܶD&EZnZDz'L{8|t{ Lj"f̓<9d-me:ի-T[zT?yQQP;LSвDlmOP,0Bbz3|ߞE3q&ȒҀ#RT[5 |0RJ<9H߄7I!o/4إ1{N@05ߝvf8)&a j>RUN *ѢI\bGj`Q 5`mHxf b7|aR83#9[H yъ+:uw9JtVMŖa9qGi%|҂koO& IDATV뺃nj[iz<biGT8) 3GkT.t+͑O!I.51hL3UEEs:0j6<޷҃|ǦȋV Ҵn-16C[uRأ;!o-Ix@h+uS, ڥ6gmI GXB O]Y<})Fpy?kj .wO jnM: K2ioK2o+k,66Ɩr>}-XZ_פph"H.h|EPsMBܓd(`Z1lVT0l{1+3TJ^>D;N" v$s:hpYBsuV:axţ<7(|kS ^T6v993{3@Tx-s юY랾6!}rǐvѩR'/aUmFd C7cTd< 9uweDV)hX+5u0 k'kr_^]adN:9rffv}n׮ʴ)N2ۖ\.~zu-( _gߔ7lK5SH +n,ug=ɣ&=Y8(&Қm#'m-?*|cY'.${r o[C(܀݈}Er8=y¨棷#r[5Σ.uƆTD;h~mOj:cx\ ilm늺A`Oз,'%eu4Z] I۔y#sf{fͷQvԃcVkDrDRmɂ rԎ'2b3V;(R*QQzҢاz;^9mH5F; 6iH$Z>hIÛ~W&+h9M!SF~RLfa`Hs ?z) b ˃|4(372Wپ TO  `°ŁajRa.jD9xd (`Q]jθ"ZG_XiW|CTbJqFm/Lk cb.%o%)yN!11fW)~ܥqZ~xL3 I?2ExψHZpLox rDH? 7ܴ&nZkM't bDߐI3t{$eBQKA1X: һ?"3:܄DGZ~Xxn} H /&d#S5P'Ki53c]<8-p5b|NLMk.VOW&fpOd}T>h^~[s/SX*_DN軡Sӎ]3s'yx~sV;c چ Fɩ5R5%'ȽT|>:R(t>J_5MSt؁PSVTۺ>!*ahHT9Q5X8X(2D}2}Rj  OIk9Jh[ 'S2SoT]1@>{nזRz(GE!pZG1 ҁA݊c[ MQ94RHK.߉bp2)>TVf+;݂ ԶÇӒcU¯'o=Vr/G* ]SebFv~ؗ]pwSe =`"jl`>mjdow +5.iagM=jvp!u:YWK;qu4!KSm8Σyp_gt#f5.ޥُp{c¨Dc`j֟nGw,2(Cm/IX߰n6tkЉ?A'LR0R*M4}`ȳjq 5bդ9HOFqRNĺkeR[7==s5&姄kgm+tye `~&=0Tb?L9[#l>Q.Ewڛ ڵ52hWY$=Zk(2l)u-%Ex1bfn.kZ4F+EE.YH9{%'z)o5( أnm6 o{brFۃ*m/{$Y\eξwK,HP/LL2_?[&$J"@R@\gf~U]3ѝ7<܏{3oDfV#c 3HԖ{r41v![\v(M*xĸ!DS}@@%NL*|'+q^y^ m;d*֜ ܉X&Tu8vtɚ%,?cYց0Y6q!.%Ö I#΃Dz2#D"W![+輆tOc,zXy(ߌ)ϕCC79/1ș:}pk~BmڐJrWlɞZ_Beȇ2&x3 aeP|KoYT ⚬x"xڇ8| C6V<ة1i\Z8ʼnEf~+^h^ԜY8|4e6.Gȧ # iT) ơJsn\1/x{ZMXX/bX&ݼ} )[aJƑ;%m\gƃD-r~e!s9lRF6j+:}0I7"@`?z[da҄篌bb`rwF4Wn+VJzk>َr1;W $dž!Tcf~*/l86x\>pLI7 3LbRHNX ' YtL6<7N?B6 b>/%ϯ@n 8J:x\nSP>V1׋cXW=a/drNO*݉15Z/eN-E];%rqSTjq840 WJ8Ё1svf ⇚ӳۤ VޘaI&tH&BLKHU-I1Q0+ AN̟gT&Rcxn(^o;YE)Q Klw]XLgflΎt;|/K@9Ϛّ$nNK9*|W1{O ezmE8 :;DY>yDgjavᛸ0p(Q{q[q;&$GBmr( S!m@} fDSre .T$Jp/W-f8_%9tJG!}ɔs ]7%@ 5͡._kn#Xa2|  e |ڞ|2gbz[jzQ_&G0 ?M \d/(K>|#{l*`H~PjͷyK6!1Wf\8!:y Vh #md(\*n͋h'5(0NlxȘW2K+EWţm@7 ͋6 T f, 27dVmѤMR6i~@єqE<`|}F疍8l1E]a:4&l9E0zvV}3Ԝ‡1VqfHa牔 1&KϢFgr4NlScX^RB 6EZ vmjoMJ*06\`qr"` nG}tꕈG~Sqż6& a~bd6䚃&s$ia&38+YQWIůs8Yc hԠ7%w7q1}˹3v/UomSqc&6ѳu',X#]xwzpb2Id9P(}^Grx^9/}G;1xh5ubRoBqȨ!sOܰ*td8T1' 8#GcL2Yݤ I #^ק4aI\2|"ŭ)P(p =C̓-L  i1saCtYq`($]TqKG;LzW5c(9OFO=ƥߓd}A+2H>ő! iNLE)m IϻI z ?eL^RG&5^? Khfk7rpIbk}<! ;9q LtFhH!&SS^71RI"jl5Y4[Z;dya0gs#§A4ե(G55/GT~w`#1v ]:Ǔ: x8xThH WQJ=)Y(+\ bq,s.@EkԩMMlC3$n%L`m8b*xLU@ ZuS _(Js^W]k\qQwa<583c0ws }S,TN+Y9qPGF?Ek4jr)gHZOk/Y[AX8J >-0q0/,WqKK23W&ҝ7X8NnJ /|g.XDTlQ\Ǔ?K"H.as~gѭbTLY&[0D3gO<^h`p`#7mи5rqqOdC % 1XCFYq0.yrIJ6,;߻M#z.&s@ e9f ?#\B 6wNrWssa \C,ȉAγ>-)qVstOޛ[7Z3b8{v2"^b*}@]~_wȸQ:̷ZIqip˛ې1ߌWr>hb&߀|m9c#E!d|r$˥1,!h<#|K(4ʕSOV4펪aq#ox UBʥK}s89\8XBi\q6q 8S I]-IN8a Lu%.qTyep(;Ta,x ֙% Xq3ѶtuMl)rE-|hPBUR$&81y N^-.>rHH+K(Ps*J募es|UGcD\H IDAT j-sX(V%R z'l8|JKwyaR!%G>Ly _dG $gp HxO#MQ u6GN\Oat(}]]Wㅅ6QC}zI/ơ_pmX] <'$K05?<5ccXq䎣6u>:& X^Aw6!u-b5>Fz.;>E zFOB=b #F)%OtY?} 2@eIMQ+u9c%rG c/!AE`y8<-5q,$ll5i|1LITFؖ'$G9q2LJ||nmrhԢ魛U@1͎ o<b߳ѫwR]<|kۻ[bf1c%p9l\ $'nx,;6l p#j<4|8h$"3HPG:yBzW7ox^BdVRJ K!!JK^LÿVwFS PEnCCD8V ྟFHREyZbsT^ԥ?[%;r1C`8/rǜNciCE|P܏QKV]z Khaʼ4.#xd1GsB|2(CjÄS+J92Rsmc9S;lO⡪s̗m/;x `Hs*G$uhA=Rz9d, {2qcs\+ot-x\H%V>Ձt*~-T̕ަeHAĘb@36zLZN$)P]5E*c\8CI響^uMajHB9'!\*&f@ !zthE = *!P)zrqYAB%~ n F>PM!SzfKRu["%P3WЪqGQ9CUPUHD6&m6mH!BM8kI+J2*थ Xe#qv>g.|4Ί_448ФK,\\L>s4Icm\ӭ#Ayݵ3E{0ey#]!G/E Aqw1m"d-l;C?ccL5PsY#7q7&Nנ3p9c3L,%D23O-M>97s-BgWw'lҜI`82#_`h)[\FZRxQѰ!cl@ҽ ]I`y E5'>ks ]յFݴ鋞<еt좳<]ť>'跟)!A(щ;j8±x +ϐo'X3T=9ü~2=0Wcjue'> 4$PTP8LU()+h~a(Ĵ}:X,7dRQqk`NH|eSQ<7F%xB_$@t/&O#|}[ֳxs"iGn,G"LB8 ?,[2d W}vGDh5H#3zk]󧧑`Tr)BnF6GI<?c@£+ztxxW,B(*iwH,>وWC /^IaIGNo^L2Jх2"V b аKO>րʶIqyсb^]NDE 3<=WPlϯĜ%9Uv2dǹuNyb pub@8-/>y2H\0[Bc,ggl&TYXe`LuEM'ST“]_T3LQZ+ReGVpNOwзfxc)h!AaĆa`)"똫q9ga8"#\3HC5# 7R^ &NPZKy?qe[;0f@я k)*3|G!ɓ̾T1 x-K*hf@^M- }pԶblPeQO} dg>(M:߈Fj$+hUdU$m5sϏiHxa0laΤ,duLBTrzzbtDp]~@K6AU/`ЪW%ۄyQ[K2wS)vRqǎv^&ϤIVJڠA(Vӡ O h~<@3Α׸#8h 1%yT`M^~xwc_ƛm R̀gR!UӋnG5-:ѓMn\__D[$Hπ$T+șnj|r>QHO86(ݫxW9z 鵸-Nor$hpYʚ@K SкVBqf f;[ :?.#D8m;1iu%Ub}@D'v-7~Hb@:4rDǜmmX.~& B3jo9Bu:OAͻYbk1y}@LQ24_Ïfa8&_#M"vܒ S#5$3dK; a9睥WI X^~/0g6yP0sפ1 >:pf6=Yyt)j}0 +jn<*=]TONgH<6}7)9LG)dW=2Mzqk^e?G.F¼7uzS1hLHQ +wrWVaHt r5U9f3lP^Cg-زZ 9K )q`=i%Ā>j\Ŝmd89cc`[xŨ|7&#A<©,3e PI=|[&(8@Y29z,7 A˜W@ʎ\Uy_v.|R<5LpcK'J~[V3Vt]ox?URhqh8y3K?tlp : w 0 (}U[ X) Z$5k2p#`.~Vz!YꀒɆPG'E Lao)iеq&~$6>jlmaW(*vA6KdV/nr2 QcT`/l0i!@d4_A6$c*7?V=r{L&$U}C:Gl_KܤGU O8#oN>4yy仓>O%[?ՠCudu &f)'%kЗ/c7жB jzCOq1kJ鷈+SGp,X%]OܰI\L852WD5 0xPcz]xC`'m*pٟ:Kʢs댽؎{bdKQIhmrd{kx}E^*: AQO?wUXYM[*)Le6>5yy)TQk10: nuyuasq h5f[99+dN?Un͒Fp`Ci6KnǙ9ΜN?;;n}^iH{=>Xš.G#d, p%G}'Q5&(xZuT\u3> })Wn:4F~QFFOzNgDX2v/8 cȀ:~\\"oB(WbliӝDpL_sӆߤɫ Ơml l^vt#/]S1G9fD$Sژjd@Y!u<v7pnup4f= 1Ϧ 'A4id+X,7O~J{`mbCVwڵTpͻ8&gO;u|4Jˆ9l^--] Z١R+8i=|B7DlҦPA,rE.p[K(U4*zsrˮ_%BOsބu]a- a7c& 9·ly^2 I5e;ah'8l-j`tTIKF[gwыP70T#Ok #`p:'1}$pH-~-xOs-.0ί8JGl=v=s!ZT<+ϴaɟBGX8-b%[˦ښ_ Iۼ,c[B\8%I`77_o`Ț]nG WG_bƝorI <7,=g=˦7 jLڬAh\嵍\ܼt=}krnZcx}*֯\8V>aݬ_͈h6;g=+ [N{oY)K kƯ+*:lxVU=NN =NF<+hdxg.os捠lîT);w]aEҘv"N <&`3:c nF8'#ǔZ9,ll@~&NmrsC0d C7 ^ uG[iJ^Ǹn3@ %;‡-fQl`1N4 o Tf SŰQdc$}(MoG##s4;3Vg[|˰RF,czյrTʘ*VQ%JB) a$ h~8% 9=)s{kɛc"wd9=%;xR|UN?~uK{2?תy~#/ -ͪ9Ҭ LvfIH [Flr>Qsp@nCLy@-nGd{7I =%;‚AoKcTL1,v׹w+ksְ#g,7ڝ(AԚ;[u/`%ch N^@#{a"4@1_ސxw|1y,T,ƙ)ϭg=Pz6#4Gv?ߧ?[~dL޶sM'ngP }ǖњBD]6'lԏMc`˙7?[|OVVk]ӿO87wX[,6ڮ>nnZyߚXx3/(xH|gMJ9Hės3c7r%/q9i8lh!_Hv q 6ۓK$G :cHQY;7Qkk6;_;~ƅM.}N%څ[28|ƹ7[IӠJ縗@;q럽{=(kSS*·k=sɷbsą94k}wnh<}CL+Yڀ<\ * ts=cx)ju0ΜHG\-ʡoS9IIng'J)iZP;Pu<5ЂhڨA7k<} Bf\-T_SBpz.O8^!t_ʫv4%_?+5T)9?4o@V!|VVk%^ i7˧l3SpbE)_C 68M' XCy"m?u[gAX氟{6u U;P2=Bc< YCP &w\Awo${Diߌڪ[ڀ"oֻίr-Λ/ʗ^$j^nP[Ǽ[|Qw s-mgBߤݗ7߅7SjNO} }ώݎZ0=_PLSwza0QZA#Pi<'YUUw***sA^ߔmՓ׸7 ĿT3/v?wg|'y|l;լn:䣅Sř]G CHב= w?oc*7ih[7q\C5wUz5aqIbUUD' ӴlW;dtOM\B_4P} s:]d"лМSrmnǴ2m^>,jY.QU,s8f;" }ܛAo\cy "J7XÞ ֹ% Xw>ohޔ|%s%7t˻me֞SoPW=ĵA&5b~ soSZ;_KyBAT6C40qίXQ"\omB\VV>XY]sz*lu)畈Ib&zO qЩ)lЃwN13C?93~ʊIG^\+i\,>+S~ ٹ4~O3x\dΗؽo%Jc_=X!wW aU`UX<5w&|'7Cfϱq Ty{>:˕>,1yN<'ڸ;,ժk:k`{Ofar{{<vT#1t%8m31Xqq>@(y?öks {+ Ρ9;m\8Ԇ1}I?m1z^Cl޹;GP]BV؛濏<y^ Y}*=Q ^3qn܊N:?X)tMjp ',wq>u mցC>u]{*yн{ ֏4N<5)`Gn4!}p\bWR]z~v{ ?akqQR=؈E㼋8M|p-ڹ6̼Aep 8;0v#aoA9;{co~KYXxTQe[No^|nV6,dع6F"Á"zb~J@T;>{_= n\ܯ>:C]gzއO<[FN s-@$H]FlBUA'ix) ~AF?7&k(6BQ۝,XY߹qqtn\c k Ā?ܖ**Xb_zI@ж(OCjzo o+t)-N3 ;u!.>x9O^Tt:,%U]2uxUu(s{GNbAx 1YVf=}BҺ;ιOsn fz̐$*3ύy84\W-XyU[0lU) ]_~1 苍K'J.b>=\y?2 Ea^XxCrj ^k6zF2)8!=63cyv,+~`͘}"9oy|!aQ9=W2 aCV7- Q(v Ln&#k~#}>xEx +˴**ڀFO^5s6Q7`rz7MG<&k fh+]Ɛ|&1G:,>ba{.]=D2^.Ȓ67h்?lSRvw?t189㊐XU~[8G'XزO]R_<́q2XڔD9u9TW7Lq !<[Ceixd{9Ԡ]"z$Ѫ[ڀ傯p_ J)&4|ź9-@,ZI6ܥuʛ D3i(EwsWL6CTHzG2b}3l"4 RF*.]>3{"#G@%8Lna@l&=x.ƴ~\ =%Ѥ <9:x380Ǜt VVk\\T N)&:cziű ߘOwa|s)ݻ֒@t)sQYHOݝ~mH.پD+wG SC7%; =m=UhN)c9wif{<zG'sMݬ ?|b㞶˶mW b:PV}?⍼IC'Rgif}K`CGVNzِ>U4kP1ue]X*ѧ*y|3d tֻֻ?5Xn,H#[<`|Zo>_C_̅[>#Y?E:y ]< (?}w<"{ssoA(Pg! Iք`xa,E@!A<L- G)mR``cs%SܜGqζ_A\>[*!=i C\7kFzhP|].0-|Aw7p~<~(¯ <{K|+_E5E[oƚ}/(DauC\X>IӂE6Fv.3=VX; h٘x ԉM>!xDL=?KG";68D.ra}.^ .F,mdO ]et:I|~J29'Ѽ">p-^KH`+I1"1IdS bUSk4qGkoDuk9sg9##"g7!B6q-;5XXxX]W>Cn:lj)~^TОu/ ('ROTo3z0gp㽧+RzWP6#²9๔85yRsw%-6UĩXꪀy v^"mÑۛ3lLק Nl9Z%`z^Fb )_댵 Ɗ|'"aF0l%OGQT`\'_nl5YVu %ޮ?{-{N߀#mWb5Hg~Z,R +6 zѪU`go³sv8:;m|iCqݷ; XY9|De>8B @َg;>ư隱g,[>|0mQ_һ* Ui!oybW&bE6Ө6hFKm P3% ~=xt41Qp}F~<#qXu ؠFqʥHGqRu sب Ez)4B ,Yeƣt0ν |) ؄ةl:d`k]$8>އ`w\1&yA5sfU`Uڀ'g9@SmL]ve#eYv>M}&{&$ =Sϡb[aԉSp7'ӍO.` Ce#^X;j֨ IDAT#1!GqjjI4䲘cj./G,mlBo{sTxdxD$elz؝)^.%{=xڌlƜ%En@"GtވkOCpќRSQ2 S#ݰJ< @]><%߫yd=xN|oVy-U+&ɝzz݅0L T~~suruI0l ~GK:|]Oo>:M~7YOf6(lL5V!'̩鏑6)aӇ@d|oʍ xT>lF ŊQ>#iDBrU!$ ,S&W17_Y䡠E~9Hs5KP2pR / Cء(Pw4d3-gLrDrOSwN8M}:Q2}bGO'uU`U *6 OPE*psΫKξe5w\o?.g~ Y402 3Kٍq'er#\ZRe5<5 oT1-6'ҧU;ի|מ2d,ձ`хA EO!,Ʀ]a?ـ"R ^)< n sPb%OT9}˽ p!AZlx^ul|FK o92EWX3]AGw!MHOG ~|R}hn788~ V[H}XXx țoy _~s];77KK8xGwˏZMA3#c]Q6C#e!5aɵ>cگ=>_ѱ/|7<- e-c ο*s'!l ֧ 8z?C> XD= +R/~N|b+9N l|s |yws͍B$b|BO."P4ȕZ-K{'Ҫ?$CkA42\8FWҝ6X(?8CXA>U+`g#?[ Dr(|S ]rD|llH#*Bnj !pC!jY/C-DܻO(W|ç"DRFaQ6֦F1tWx29GR=BOfRB׬S0m湑 m֧ˉy**ڀ|O;_\βoʅCSFzsjXf1Yaa5n^ S+?6SO,/l>b# >_&cO, <ԴqnR`~1)6.U`6!dZ$ qY#Km 5 q1(OdAucWĈwRr9zU*ؔkJ82 +@I֘ n7:܇0sUG7 <_h t:ƶ :vW`m@pU`o|zw}o078 }ilyzk_\ٟc-?G:R؛/#98X:a>Ezn<6j,@ 8MI׎PrOI^uQi#*ǿǿ:}ᇱ;}N|/+^m%}!+fKx1@HaBx Gf=X>{'/̚=XcnVοsD)pґ2t!!N5<4ϒcn\9u=ss.nξ_XxkXV [nrqg?(m㕃tev5qsrkvə<{B|f>bc} 'heU$pVWXcaFzu2x_zɯO:?=8}fWRl O>8_{Kf_;}+_=}8}=}ۿ|?x?z_ǧ(~|JSߜoeJeWL9P3FĀ3jM6f8%WQF72uhXii* `7Hon%R2ܗK?Cu˽y)nYUUgڀ&,MH?z>H?erIe::q7g?/O?_>N'}p཯X oO[}ON/|gӷo|=hcld+[!RbC!1؈AJL",y#ءg"AB.PpD\!jBXa2Mhf,1/w_ _p)Q/%mg}kgٸ~^ߒ[_8Z˶** k7&w5O*VMyDBc#4&&>|+j iX?:'?:~_ǟN_7OߎMA߉!6P@cÆWߞ7N،|wS߈N|*?,*O(O=:V6)|CC"L>6F0\juKn%$L#EmB8ٛ(.KFs;沾32q_ @dqXoƬ#)H]+~GؙYgc=E wj v́<9ҙ6(787vp|]*7 !8hq:gӠ ;ȻCۑ0I+U|+tB~'?/?=wZ9>Wo}%R y)DDBvoy) 7Z'?ߟO+_}~/y`"~S]|+1ǘ_0`#I/KbI!;&| abd&ݳ4r*nR$v\.jOa\` A9nU`UW`m@zW/ZU nzK?}ôcesfd#m˸ۭ=zvXbǺy^CsFzZ7v9iOԤָB怅tHZj-,Ka}H.g5hz7[ؔO~чƢ_"_bOl 9/ω|ߍO[ONG/ǧOwO񔉟IѮuKm*bGܽgؔsl>glLPQ!ڢG+*Αԅ{F;5z[bM2r! <μiy/%tIoa v㧈8VVk,e][n,7xh¢"Z j&;(?H_cT;~o1=-㓑o|;!ӿW;?;}[߉}_-UF?~M!>Ywq;ӧ!?f?uG4 (D '8͉8cFc. 6QZodwk#.;O:]].M]W+6 W˳OS9&MϏ !S{C @ݺl]CBz np(<9IZ"o}wCZ62l`|5.~}nBؠȅ0d,%k~X ]v"ʛbϻ gsea.g?<'wW?oXXbs/~/4}+~(t(~|0OA^+^iHls!t)F)UX\*[^ZCu6n6̶ǰ|ă-R9}3mrz7~ǿ8ٟW=}bSBE]cL a&$|*Hm:!jB9y Q8gֆDQR/\~BVkiy2wXxu"Mƍ: F8)  K**$X')"Yx hQ ouTo%՝Oj݀'mAnCQBX{̭OY(fw!]lxe;v(X4`#lطpG.sxc',{!% :Fx|@?_ӷWgk|+|?_!~CJ4#u8n?{okYv]?59 ZllMNB%򰫣;baLA&,QWQ55cF c688 2}W)zbؤY%K?KFJ9wcJCyd\ LU羑3׷3A-dQz1dXrcm-t( B~҅[[|zߛO@/e+ܙ]{<}{No{T:r_RGPK _O/~-gO~E0K8!'Mo>"䩧?1'9s۲X5^-a\P0jY?*duQ2Z@Ę{J?!y2uZhlACDW)p7w ;.9u4S# 4 _jkz"0Gt767_hH+f τ;}GЩyZ[g@簟a,8'Ȋ#(Dx?%a(rn^OoN|]21f߻ӏ~S靏>q6ȇMƛ~իiy떭} |?dnu1}++'cEnR~r8(<WmOp,B^Z!wWD`44:OF7b-A^~ۂm޼VoB 2-ᵼxm ̧~ސ8!t~ ~t{ & :Ezi=}i@:bԓs6Rz/la 4U:0hDa|]}8%ZTir?dM`U(JΊ1`+b%]]Ɣ;;{]Kc%Dd7B(ܜH؅r!&iYqOZ\dt<O%v:z2J[Lꕷ*hϞL?Izǽ2Ĝ@M!=~w噕u]ѐRn~aX:yUZ:v2w5`W5B*#nIyDXkݤ[ njQlrm8aQrE7l`!U-a23]?c5+g@dXd*F`1{~$Cl"=.^Ŧ{, Ap/( N C\JF0nZ/vSdԼ {r f2j xDbF'>JHnSLų oZ_OW_z.Z38_0sjYҰ~x"ILGs(@u|8񭹓5#Yuq?Ϥ,P-@ӚB|Ś:A7B#IkS;E\;-UÍĽ+BH'2vuJZƨx*X#P#Ʒj`c=&;Qp}p]Ł_ |Li>S…=vF*<C|և ]їs\<|=HX=L|{h9G:|@~"gy:6qKo8O(6]`(=D^9<|jnǚʱ x%۞@ZZ^F4L]=O,*Db"OS \ʺYXa(L9+BHP6 YڝeJx }KcԹ^ubQ55{@-@*\#sfx:K9(ALNˈ 9{h{DMsPŹ0a<)3Qң# H#Z(%J_ko_U#i!&(rCg?>AoȚ*boZ]^~鉧އgep|]{O}[r ${=  6L}AN;c [%u|;TZc4s{f8"@%.^*.ߘa*$*X#P#dr5cF b/"Rg-}/p3N_ʔp?aVއ,`|^N0>LKg#p^W27w^*Ʊמ<<[/A lmlx!ݸv%xP24e$O|͵@rlq%$7I'f;͡xC [-x)g`LШm'#fp[ⷾx4b,f,۞[XwRJHjtJ?q).!=MzDnI\lTsqB}ns) pVD@#P )@y|1qP V}%;.e %\1$0HyT.:D,@A aRSuf|J^y╔v+w=$j=r`{d(Dq+} \3JĎ8gć@O$~7Q<]Xڸ6ҵS!|Ͱ0)w <6W_o+O_IǕ#6fby<HhD#y}̉-,AF aZ[1RAJƽn|U !s}pRtbL jnY;.V(tGfOKg~s6#@^\(1a{_P|5k;g Ǥ*)<teԩ \-ՎH/|3 OE͵r*ȳ]Lɯ_x[''W/+Kq]d@٬O0U| eaV#5>ГBG>{@ju7 f;"*QA*Hf`f1|e1JпZ>@HFm9jj=Ww}Lkj&@-@& WeE‶W,+Lmi"K֌t`/hSɞB{Po8JBίK&'!<%DgYM|WD_Ƴĺ~=w?N(wQp~.k{WB_Iq;Vq21xoK'ӛ\~#s!q K˂@ѡFe2D ۑЄ0зZW[\a|ŝF,H5SGGK}keva3аz8m+3 ư62LcW"P Uk&2]"}DAAD'H(PFpFݐ8m=3˅Grrs ^*Sjt^#,^~iyᬇ.t3.ceQZX|)F%}tkޔ/yzV.s + s_mX5:^CvnPX1|0.F29 8ā(fD`1o~s0[p\["IPd r>ycy T8nt:+z#+ǘ4Ǻn/~+n1YbmJb_P?M'6ӶS$TF|vÂ5`^_Koy<"BAY_^>kEj h &֢t:*!k][*ļ inٵC.YkW#P#P#0,RA]}X Z)?؉` #W,`%/ T;^U)Vd13f3%,%@f<^KxgF&5 |[x7/y\y" ;sI?|/fVzmk[|K@:T=?-^ǫU"zQb kkI6AHDn@r6m:W\UK6CWX4*\P4FB(Jq>r`Ol0@uFΉ@-@39s_/Zz BA>"|1][uE ce^Ƣb閠"3 ?Z#3%|DFפF|M )¼NFOtg1{Nz$n[D7u;?D=Mdrz|ؑWTz_ AP5z>U\?[CbV=i8 r`s|ov ۔w3GGaWdq+F q"Dt =;N5AFඍ@-@nۥ.<1bb_o ̡Vv~zmu`h8D>BCG!Z%A` =9- F&vn+D+Ϸ_m7/I'9As|>-7ǵ[icsK"Wϰ0dz?^3(`X]۰ oMWњ:meiM+s@+q2F c>~ r!fKLY վ\b^ySIpdp@Zܽk_g~`yylcrRu,wՐaϬ嵐g|Le5 R';wci]44t>4[%|?gAWH_x! q;ѳj"X´8Oϧ^orx؀uFŋ/3ķU=oɂ3;[0LD!.xxx%u$,2y {Gs$_̊=Jd=tLС{R"P n<q@fs><Քp>hNC=ߵ dnu>Η#jI~1,i6@s#q`l<&$alq,ykz߸6 c^9BAvk-~#&l// M 9ew/'n*"Q2ҁ-[{ZwnlmmH6kX7oK]m]ZGTD$ۙ9V#P#P#0Vj2V*S#t=鈜%AnY!*C\)\=PҸrHFa+@j+2O !f~ fU}Év |tvZ ׫iyobF=|8ݒ-UKWD&EF]WX@1.9H]= ]^hp:bLFnڕttfq B!Fq=C3Q|`]|4KܧٸƒAdr|3=d~dž4>=;*zC{ycAZ}F#,{ qʰ{B7ݘV~HLK"Ѽ Z¡ظFnCL& b& S LCxIQI4bE '6 xBNNaofqm e"e.ʏƜ{=-gz69­ b}𶬝+xƵ br]*@*uwC~xdZb[zOAa3…GSgpvqrClru510|fQfo5@V!]:BtX:VjZ:aGgGrlN9(an +qLa͐븁aGH `6 H$&H3-E+Tҥ߂ ȿ »`fkx WIiH8 7`m ^?H9>( c ޽enǢጨꃎ =~K;n޼xW;d JߡUBep*ȖǦ޽,p!L>\Ǒ/yJo1y(cOݥ[j)Q҃X\к)Cs;"P c,3q@+]\?;L$TpKm,2sDIX(n^zÄmK 9iBd|J91xB8SHZ wBMZʜT [8uڴTƭ?* &ww}чDo<"Kiv~.mc걊c}T3jeҏe`nnX ׬߰ƒŇ`\ <,㏊kJCU*ޭkr1緃.*qXœ(hÆ7,Y#0lo"d7J"z qױzO9m Og8(\2n( 9e Ph$Kv$,CP$K;}qpz-@.7ط>|,pϦa3٨$mS->q\c Oc!L96o82Ѣ o[ox}i}c>o2χcCBV6Z2،tiɝz "wu ĖpģĶ@A#RU >OFc+F`z^]u]~i"tGA{ArǁG 5Jqܧ[81fo7bqײXd(lŭ9*){]g|

7^l NRķ|}-z IDATg'X&D q=lQ3lǼlw4Y2VO"T0{ˠŷ*J?@}O*i\ TE4+Áo3Ρ Qjj%ٗV5Efhv/jCQtTTeJ Ͼ齏I?M_}C~&l\YSB(Ks7Kr>ɍϸkVZ:"ZX+8&=y@&g$k19UF$&A!F/&أ̣ Q#BǑK  T> qлV@-@.]8W%=vή^dGr͈P i%>,f,o'8${ d] |o\3U/3gʼn'|ހ(\`º';~|Z_>9K`vܢ?tbyw (B9:K?+2'k\% D Z*j>@>y>X0bB$ĸbCRWj%Lh#`q(eTkv9hZo Zւ7LJE؂=z7b؇Q…ht[O:_#pTTH Gx0#.k`;H>'-@P|'9p]E/ VŅ0}лG فҘ D(qYLb=;}\&&]W>^A'1Rv7kT&oaβ#a ) #g6]R#XEȔ8\~ ~luq MqUdzSl*È) ߥ+P*T#P#p;#:z:{|8(v~v((}3 3 7=L SYuD]B߸rzΗ?cOA.{MřpplՓr nSϛ 9L&_P$+.n*vՃ$@b8EGpyPZ>uy5h*cB!}!}!p o"8FFΊ@-@9P:.qـ8<)Ge6P!hx"yܒ+ #ITMF s~T9ds`)'jz.J&P%9t'b$s5asxZ;;#*%]"ܛϘw Beo]21])ǁ.voyn@8oeljhwy 9K)H.53-1iяM&eҢ <zVZɄ̜18^ڝ%`\x m88%On,eH[CB/{&l>4UX#Ү46fǶaQ Qff-v|1/gfQoR_%6__u䅠v' ^?;A#*vS<Z'~T8ۤn&xx` +,.~hypf* r'^EA׮ԁ bJ(I5A*{7z@fMe mŔajjfTh:[-#㪎!~,a<2_gx0]sO64W= }}WG)~AQ_Ka((upw4ߵ#P+\wg8dxΒ/u.!9冴D{xR| ^5˦-x4YN?^ #x)<(gRj&OOnqO1 ge)R~ntBP4 &*f}>}PRuBԹϾ>3'!{V<^<o*Lq>e0 OV*m WZBvFC3in syK}2bdIMƐfldXZAlh<kة]bY \{pK6p=)"!w60 } 3\hjr#h?DHpOPvCՏ->o?@/5E&9<. bcxqo^lq W&AuA/q|Sa򁱠?Ա&B7!7 3a+FF`"P } mU\#`{UZǻ֠q(֡Lr@GាGdw(9 e5| ;`[EhoBLܓo\MndVh8NE>V Nbvw^YAʜ=Pq|1D?gKf >K0P\[H?\Ј}9؉V:Z=\Er2VviRJ>tqYMOXdҗЃL}@b>8#tr޽~b-On4{C&$Z&Gȑg0jj39WwIѺGL#jQ>7㶐$,(p<*2) cʂ#T'|;# kWuVVN篶y%\(IHBKrγS3PXN,[6n-=Ω9f ߷O1!9 \[hȍӇJz5|[jU#P'Cq_A8@N Siݣpː[ح1ȅat=i1u:.[+Q*)a*xQ$!+^8YqZ+Iu6}dIV0 <ȳxo`6rC0q֬]Ze+J?fg^@8@FgȫZ1m yM( cd{p㬽C8Xi&-$H(;@r8UP{o%En@q&PqlI:IqP&pR$q38U6ݐ`:N{ާlˮRO!LjK];\^$z_ ")LtM0{Ӱ[H  +hw(>O 5p/ e@W1*y@Bgyě$kFYgD15/:Rĕbż.P}K-Bd:pSjءY,RK _jk<nA*c1އJ=EC@P_ L #G(YZqD]YBfUV~Jw%6"M_ +lg{.%wlr`(ΐ8c 7u\a,Z7c$iCpk>6IJbYpհ.TeIv)TEDLFBq5!`*T#P#p'D w*9lel2ܐ =wxR4aHN{#rZ}c0IqEQ7c'BdmA`/]e & MF2'0SҸWm )}BtkE_sW!UcetmޖN16W&|ǔܚ}H!OLG x#٭l~ߊM9UJǯ4)Ew mLRG55Zgt)ENh U3{fΗ~Bi. m"R`i?1\fWw`7`TMlٛg'k=6 $;Yio`LuNQxn,mgE1sBX* 3"D4$Զ4g*flk̚EvHqË"dqXh,B"G]U2N|)Lk`#?zr?\SLZL_#p@`^Sqӫ kpQF' Hb#].$ʃN7w9^;^ D%dFà Bdm|p K6|-r/y$pd6vɓ1o3 .t"s#v|0/<xն]3³kI++|f+ M\7+|.-IsVa*N dz,$N۹5]z`>fS"쌑9?4۱00>H%X#P#/Ⱦ*h"0^sTrӄcBEHāSalnâW+Kj %sHYr{{{ ߤ|7Z8v ~-ςLI۰#L]`Y{ov3-M> >@_/Uʅ0^Ea Hz@J}~~at.6C3Z2b pw_b͊38L>p-[ԁ_o騃)VzF8$.qGzq䉙EvQ2r'M%UŪ3LNr`.X, %&+uq\4^՘E-ŁdU V5݄ryn!MphC>ECXFN~9F%ElOL>6GFa%U`1PL+4>T f9yо3.ȩ$ˍ5<ہ .ZLn`r=tjo.gϞJ_1IZ2hJxP]mx4=Қ 3=->|(${,ZƵE_ %w/`(n3Ao"D>4!nß0QB:Qb8׹VE S eUT#0$6ع1jw3R?˶}); .yfόB6iDZCc74FeB1fR5z88+G̍+)!s=,ttJK魗qWOоOl1m IDAT٠h}E&<ٽbssɧ0@h>a`!X₯ܵ9r~*ٹ*" Z(Z-`"A\Gj~ c1S0' b>B؛zpEmL9q5KztŶkZyT4Ma~2Iʐ|0,H34[1rg٦S"oTRNˇ:/7o%Mr^2 \3ͮūv1]@k9Z(BOKx.r/.Χؿ>[;dOY|1}=0zZ9}<=e\)W ;kkoMlX*^\#:nb5o Jp,Lʋ (BT"@#͒gu6 m{<QͩxyȴJ(V#P#pȡ;"G}mw2#.x\#ThWYg&㵐 i)Y$_jf$ddUU5,RLy4{uRDs$3t}OZbc,#LgCqud%]ՀS`$b2%Rb[RUOÐo1L@@>F ܪF.rS< %_ dIXR31b7co Cj]yOt}d=s/dz_oxXD!3͎l_9"/'ҽ (:x s|Z/*Lf:yz)gvyKg-3ƏƆWDo GQ3dc$ܻLKs$iwL )hTJI 1h_|Cc p"A~ Λ}]WC'B3faȱ`m55G29R"$Iރc9"hA_KnFe-# AŇ'_7IK0=_A5^J>|v֤(nlCіZJZ9agőؒf 4?21m_>ݠݾ"dc5X!S7[x+dk!T9=Sk/t ;Μ;]}0%&$V `@n16jn01ݱq> ` zZ,BKf%ΈQ*FF`(5mU_&-ʆx+ xoBd2e6 S"cXU!$'@bb_)c2'?qfɒ}E, .f>$s) _h o`NE '-L~psC;ގ4s4nO#"LR^,lwơI lVږH%^|(&$"9)yh7&LbNŌ# RLRmLgjѭkqPTVJa[dH&(Pv/PQG1wve'T< ԏYO%gvK< ~n '㕰\U$TI0ilȣCY*r5渜tIR֍+իgӿKݏ.CYC濏ǿO|P|8\>6Ν(=;ʩiao u]oZgaE"tT暛yN>^ @=']* !D9k 'q* goТ?Sf-O1>cnjLF.y\T]K`iFGk @mn_*/+bU{J@-@FEjKqG7?8e <(`G".{uđ6Մ(@ Kـ 9A&b~XI}8c-%h4NGx6HlV,}U5G݊%_&~`I"߂ř"FLfἇzG~ҭ$t?hyp^L|1?'=}'Pvk=]xF/_QrGXDatcNgpEgaa=Ʈz|3G_QJ=>/_؟C{ }4s U[r`T_ nUxe'6+JFǥ:6aTܵ:.Yg$y`KOh!;lfI4 1cBƘ+XYW,'IM{#>?\A.ǐ2Wj_zk"M;Z7(DtdCaACn{'1z:)32m2 kR4(|F͋\8>(D2HSDZSHz4&k^ꕻ9F$ig,[^}=m֬OǏ-G7ol^ έ Z >r"=ӊ]7bXͤ.\Ixk.{Ko^YŷI6ҟᷧ8KЫFo2Zep0e|<zl;G>fAE`)\BxJcDコJ#VGK=]x._&CD(vjnj2xVm5a`6eG8x 1{𓠺ïItuiJJ9cN\a.u;>WpՂ sqeBY}UЧuW2 Hxeog c=._^bq"$WB}c6gf"y{ëuQxv4r*VXYƂA̤W߸޸|3xjtfzPqs3d;> %p= s??!0Pj T[$yF DI_ v[lJ60Bz4`bfn11vtfÑŻH+xX#;xc  Ёkj#P TL>GG=; F< C1LN>2-Ap']ۿ $'>xBm*~#XDrKCIrz<z 4 O r{4X(@OOM tLFgF17pb:wt}x0Zp|ẪrA:7qU=~&6 & ڕ c+Pk݈#3dE7=29s)8&ݷqS dG:xJYƊ@!v>=B5Zh2/$KR6V~")unkj'ٟV5M7ѱ/bjT>~X,؋t0hYrC1>  `U,TD:Q6-{4a=5:G}(t*Debآ#pK :l N7|lZoKh%_?ܕn<F`wkj#?/"D5.!~'k`Ay 6l\,Q :zOnX9*zM'+xiFMd}6޲R93!̎y{\Ga1&v+KWK7o`.6pd|3ۣftobςaU--t̹t 1xDq" ̸@Ad|zĢb2tci-mYsA7Q+-xl FjkመvD\'PƸ[\go˟%cOWFF`?"PGT4)iN$C^ }P&&BNr/\#M(#_PJ<Ӽh7 Ķ>5[B_Fi5o)RL5U$ӈ fD[C95@---soK{kpY:6'/-U KpUcAd@9x aHXT-z9zKVd܈!zݘt98YUؤ4/]2@ͮ` ]m{ =j!4ty\*i]ѓ^d+c3#oQ< Z6jjZL;U_@7#:rC[x HuLq˱(hg`r:kgfkN< BR11#Lx3L%?mWTiӓbKj!x&_)D]:W"Zjdna!-.H'q%1l &Gc*Hmm97~}\W+ؓs DP#@ hPImأIebŇ*jMd\,bh1f˺]۴26%曐(q}0 ^yI3!cj bi!n f\G|P5oX av\5븞NL'h]|䨭H王cf[L ЋM>h6ڿC*-y&Q}b8e4 Fmg5} -5  -@OE=bBg+!L*WҶU0"P P(Tq%Thg/XNGAR =KD:AB $ k/j' (GbnSc mx=dQ E,Y&u$ DLqbS88WV)'ڢlh6xp$vr}2>&ₑ1AS6+FF`ȔZt#)<ُ2cbyh4B͡{mM UxY\N.(a>rbh3Έ'cĵ mV[jT)5X A %ۼκ+U18٭GVF,ߕbI•9eLЉ2u?6Ps_l=(=[{x.N8aEF`I%i*"X8jߡ ^E %Dr]MK^mr$+`)!F73)b1gMC [^ nl:8r~zP6j濯*@'jqfoq8>MBFF`.WjƏ4K`FYlSI19d EqnxxgOEH"IvFdiƤ-+)u=]΁^1Wp<ێdy C|MgLkĴ mdq޲|$l,L5b /ycޒe%$iN,xVT& d#uxKk"`CjI>o"<?͋yu`cLg͛#DH'[0\Q-Qð!.p?v/$v 9d`Mq޽{ IDATBg-3 胿@e'ΟC<&#aT%KqnJjj=W5Hu9?L=ѣjGK[& 3%L-kࡈZDVI rޮ|uq׳>;+B3+}p o, xحE_+*(&uFis'CJ#EBds@e}jM'xBhCML2-]jC4tm^eԧcF1~澏FZN9#5ʤ+Kz^Gt(+X~9,{q@-]9}0}gP cإ Vx ]W3Ƹa̸^cÅ.dCN =1vP}TCn,:3[}^,:zY RR; bjjZL?Uc@;U%kJAjя:ȶ{}qpQ|GDxʡR=р 3G%+iRKf*n/r>ʛ4iCZ!FP\1 2`gu8bNy=#~[ I%i[_;_볻;;_P.lB;{ݻ7wgΜ9sٙ,ڶ\R;n ~Gbzh 'JljJ+r:uC.jhM48>@PZ4Euz)]N @u0WZ%@ߥAE~S_Y]z~p+$9Z=xA8Ft5"3&3j(=LrAn<&F1a|P9&ɺ bDLY &s&˨,͔1U*3`TټR#ndz;W{Q_6hH وMij/F7\.+2@g,>U8@%f&aaGC@Ŷܴ)-&z:;#kBյI)S1Qa}fA$wtEd΂6}^2^# @`Ro(iIw[ʏWv1xMne*d7V<?lծG+Ԙʴ<]u9&{) HE`RLE&3>:х -lfVq[EBj?>69s Yɪq%A6FX5+,jjL=:>4ah.X2gʆhƆ8'H^fQLL~5.j:yuE+*.\Vܟ|zrV؇ B\=d '7%=YmLЯ͸3Zش @gMo`c:. $M5 ]6Cw:ZT,uiS;J5AoQU\ ÖC~zKxQ&.L"3tnc|6Fzф5>_c<0a87uTupnL%}׫OstM+'DTO{r,}HjCHm Ԉj˔1A)bM4|tPt>߰ J h2EyN=Q'l6I0lޘ`mL?}YCW} LQ]tɼE)|3heiQ!u풦;.:m\,E5T,*K{^+ߒ)zO2= |d`k#ӁNUNq [20X0r:NˏQ賁?#1 @0T$<syU Pr]IOM캮:&xPܕ XODM UP$Xh9C&G/R-YDt(37J6pwOGum>Pg}%XlC)vJE鋠(Ҝ5oj' :K~HGt)Y, lUt)d/vAwM7<[<uHmRuE̥š !t߰kX.j/E+L0:r : @ 0,@m𯳬/JT:VmsET\M`B 鼗 R@~8PuB+ꛕAyH9m@[MBM6׎u`Īmҏ{nt&S֖>eG:B& 0%PXp: 2m,*D.>r(2)dw&^d[:C)27SǓH*%*>h.TӘG@hS@'JjA`)h"p]6G&q#jQGhr:j蹎G#c"Í Yy36;@V V lcI5ϯJ>ț\ę"T7, ԑ:ds(K`f|œķm>ԘݨGP_^mjzk{ﯾ`Tj+I/Gg+/#]0TG~@i-ZhinzMZ#i3cKFw>/ YM=&:Q-W\E]R 9D- c1搜KX_}_8Pw@/ mSB$``Ej%~ 7krz_ij?2J\-։lѮоhePOJfuCb?⹒mDQ ba ٔhE$f_#5!{3s  c襩 ]?Fu(pt@8_ԣifBT@Iotࡶ11aH3Z߱w+ƫ +*ꢍ'eόcM|0Q1CI7g VӔe(KV'IjKHmɱ 4v=\Jm i%mbXBruUFmΏ*K*>\ԂuReʔ0Ս!֚A'ֳɺ6ɱԖdQ{.I4֡]v? 4h^%OI[¨)$&6Jexڻ FF{80-TY %z)qx+"Dvc_Yjs:54^T#(NHq6!!АjKmԆlz]" \BF22*S"6`"+Z,STe -T\Z>fysӣNx0Nxi4ȫzwCA{,`&6G}Y6#}FF>No쏊'Dho&*y_8{^y42jLa3oȱd,&(n *j/p.ZQϚSa#ѕ cYM$P?SZ$-s&7?;(xŒB_ Nd0yTWQ&l~Ho+Qopt1cъD4f-<Qp-\f8367{of4@[t9+z(TI5cChX8.؍& jNBG yC gYܣչqcE}4/Y4X?| M- 6V6,'j *-R "( $PVs 3 d& yT&TCZM >K(8S&5Eڹ"Օ}La^h֍*EQ񦎛#^q]l!8WAU#l*{lՆ%3wi'f][lܲU(DA^ȷZ#u!cYŇGb*,c * f `+ItN%6f|Mf}v93KM7lC$P; @jǍHo5l&śahM*R4rYJۥB?PԄVCfVbR@hxT"O[o Ayf(+?Mo/鼶CO f ΄cF%8šR7vco8,Kk_ۻ~Fn~\c塬&}ֶ]>oł"B>HDH, $Yb"d&@<鈦ae-hX!>D6Pb*ܨTf)ն]hBҤt'>BwʦqHN,L u|l$ixg&3P.=G8Gt"?0оA֚gbيyNz~ }JH 7C |W-pNjk./t HS=u!K$@) @R@X$:͒VW,$6 nf3?֗32Ƚ:9B%'qZؚި>x QP[w1*{g OWVc$űG\g6]όF=G?9Z&۶ FIcso#%'\·@RH&XVJ#k!)uA^UMO5ȇVvMGU"CF_؊eO*z$@ ؄f.Ͳʐw{%LdDɻfz"T7 Eh%*Y!Tb#,b`g&jTPV5h6z@ ~ެOvGd}e|eD]-XnV/էk_mV e9>${2@vX'bn(؇ ԷZ-| >d?fӨ'9[-~P.6Z»1mБP;5bʑQ)]:~̱Be2D,o3o||7^:y+q݆xLǜdAi0G$P?GZ!96/`XWZ*[V |:kߡ-gn"wi!!H8n2ج o4I6U3PQ{W0ΰ"G>Ӱt!=UD9yh e9 WjNuZ׍4}&w-Jw=a]& !g_c%OroޥƱgbpf f @f3E?g]6)K- 4KVMsջO]1hoجoxI94`BDWQytB潫 MJu^y+{e82uy 4Xj05uA:ݗ:a+[ h S{AbK)xWq["u~ j\t+,*5+$(B۞OCۨ=!%sdojob^t9TWH.0ht#H`= c2mfuz~0,gobcdrN&SI*mBhEfV]ۙD>(_z\ˑ~t1FukcLd)DdR ^+> IDAT"UjzB ";&VVUy(qkQ/JtJw(Dz3#ڄ2 BL%Z}GMG8%bT%׬1ω6GMs\U?MlDlt9ԙE D$ Wujߌ6 !oϙ7k*KĘD@ Js2 '\-xVIw<^W(/p@PXװ#V3^~ݨox#]G 퐟/gIVB^.75 9r^|\vnnlUٰLhDDQ5XTe= ߞWȣ L59>|ːfD$PW @JIj|t : dz|5Ҧ-.lg>e0#-# &]6j-+h!!aHi!{7izO.aY-`-$SWϩrn"h`oі,DC8[H* rf fd"6jke1/\?N`"Eg)ڒ2[c2C(B-FR{ϵd5*:6kEDŽjaN @;[cJ6+908oU`un0ƒ<3Zȵȍ<'IέmGpW|GRs| |TqVD`qNחr֙4oOC:N@NT1κVH3ઉ@Dc9PNʾ[S, TjPM_fyy72y|ϾH1/~x2Ve_8L'D]HdC;j9x( R.5!6D,M)~I[iO6 zNy()-^ShϨD%(@9э7uyAGr;@V`GGH N&(ݦ= Mդu\`8Nق>`7mAc"O0c*wAlF(;&Km܎! I*wbTJJs?>lѶ!V  A6H[ːɓ/}!S闟oa 2L&`.G'a>TJy]N߿vQ]ca۴$.!C0޸lӣ2R% u L,Q(/$YaEJqB/`:*CvU5=3tmr2Ke9˹:ܖ!irJAbt;.gd.xR`@ K>NaP/$*W$H\sgևiMup F9%')8DT\,e뢣Q,ǫ{C-!;4@$PAu"0\sʆ/%'O7V~o;K+ t_~BA`_59h[}k9:0]nzC$y]"0"6O *ԩ9H?zwd5͹ cKMbqy]̲cY:꺉sucڦǔ^hMDgvIy.wۥs7FI e[$Hv${"Xb}91ܧ E4Seȍ%̻s~8M査ӕj;HO ?=lJQ}#c?Q>'eޘ\Ս0,@d.:SLOIM2]GZEiHZǽ,&3QI2AKUM/aRI6UI/Dr6~Zv\a/GvKe QBGEJΪ dA6DLvP5=qMt`UEmL,τj6qQ_?o qA顫}/*m[͝h3C$P] @˗IHHHHf@, Tj]      @ P@$@$@$@$@$P- @EvIHHHH 0)@B @0Y%    ( #8@J lC`Ͽ&^{+fyw{uiD/?\yrFxr ]ϖ-(Ѓ`-E7?$o>=:\-ɰoH/S7\qr;-cҬi$3[>YODvW˱>LBi $+{[jɿ}rIVK%6{]N.y/Wyco{zM~,p+oBF_3e<[ҵc3Y2ñT-m_Z̙}.B;wqʲ--S}}tnHZ~w:Ӧɽz~O\/t=*{.rLONkPf(Ws׮!FHf0`?,vNϿ71_m2EKuo|tO$[oڲdS{~)7yXGܘ?}Cn8sixDW|qrYB#Waާ^_Ͼ1鷫|Rzqžr8MTN@gE"L` GV$u=2鏿d'_H HM'ґ}g_uڹ:~7r+yedR'~vw#֥z/ϾVT3;~aLd+{v-]Vaڶ_W͛ݯ(= {K[!Vi#9y Ghzw ϼ_1ÑFQ+!߿׳k1zye؟δ0s&WWYD~l6_xcYs^VZMNǼz?g2tr54uehnNG,f!Yg>隃+,qʴ&ԟ~uelWo˚+,W܁_gsƵVk V:FBK-)sA{pڮV+6_xE?km/m%MWUڐN$Ϻni֬l:tyq/*)l#㿝 ^~}wx4;[dti <YYFVCοjU[ Mw_x}9msrH*̗(A;l IoOg{R]WHr̞w?%r]O*^ZBIO' ]:,V~UuSFinZJv|J'd])Ca]9[`yRח.ՕD|{_w9]p>9͇~v88d V1fHfk\O??֔UP`箋 W#m~Us1I_jV#~w殧vyi!VF}\{ھ_Un b9u_ymZΛ8G &תtͮ[׉2Yi&[ vjoT[Z\c?)lk&s­mO/dI :mˢ49zdw>ѕbm9&o61L>WvݲEzO'n n:AG0wmmjWw>`cni!s\4] [^GtCv9}_A?O]vdDm{q;/8L^~&$+j  ]~NR9EѺ6b/7iG_ewxu t.A^Wn#Ͻ)OGZo%屺cNTfr)7>hb|Ju{~&YÊ~: w 6%buX,:o)SSSWڞCvPϿtϹ>Z}ùJ?X2ut\~Ҵi{@vt \y5PԷ̃t,L[hN+K,ڂ j3;,f}}5Y\'LdaW1Hh+&LJ}Mi{B~׀y ѵoN&nd%\t=܇GvWsy7-sb{Br971{lꢼTNV8!r}ҷLac/-<;*O9CaaM $Y *'3jg6>;Utj`5%|A+WO[pOE4ʸ5Ͼj ؏e~fV0*-Ͼ>C2WOm$yU)ݜWݶZv%j0t*qȽzofCWۀj3:/U"EW!5oDV+g}]unhusw>Վ\p yurMXP'^qXPq#r5ĶK~~' ӞkS7y0o\h_ E0 Vr=&  lL-7Բ뤿\bgYb2D'y n-*Z禝 W qzTN1`Zh@OaOb۶ ➰:E OS [{/ys_U򁧖BpKvOvFCCV VWg\Pw0xD=~v>ࡽ}PfuVnӿlM&j'~{Vm& ٛ;{~6'Gb2 cr}R뺅cmp͏h1^NЫNqzbm'cem{+궫Vbniimm1viڃmO֍t;c놯`R+#nnjg|3#[ \yͱ6N'X@0^e St_q{mn[(S\=#vԮ}wHj>[֣CzLa=eا[G9C sno[QJ0=/kkDWDmhhܭc}nu.={Mv:6fzOX?!q`S0QD\/j !q;G@GI: |?'v<_WqлRp` 9 ~Ma8[os:vsUZf"} 48ˁ#'(C+ۄ„'[|bVBp|%v0&gLS.SK+2kz7c!V=*9~-mT @ ۿ؂fK++|@WƱ\}Jn(#9|I#v݄箊 j̤5V࣊iH` cϞIHHHH`#x>L$@$@$@$@$0# 0 8 IDAT HHHHf$ 36"    ٜ $dFf_$@$@$@$@$0`28|    HHHHHfs @fO$@$@$@$@3I} lNlIHHHH`F`2#i/     0?> Hͫ/>F%'Ly$    f͚B >}Ȓ;{/|7ҋ/J;4wiHHHHHJ6m&SN_zIsNYt굧&'0>->D%-[f=ƩOwiHHHHH >H6pڋ=:8qo^sir. ?7lI$@$@$@$@3@ʄ}}z@jԤIi+XHHHHH`#}}'> @Q @a @c"0zYg/?ӰfX?aMG^w`]:|DmL 4jըO/GL0 ,*rG L?ohb8‰'ɇz}$}2ev; s;_<4Y~A2<تOڣg{N>3wyeȐr|W $@$03pdfPg$@% ҷ@jm{-6vG" ߐ5fe͵֑zՇiz]Xn,G%./+I_UW^-|fe̘>d_~um{ Yg߀ArI'KˍW S~_7r+O;diO`|w>{%=ztV\Qr t]P;tv;SۅǺT=dCe^C:P}< ܂53O bNdpUYrn%ر|rgʙ9[N=$z ;8 ^~a|}a _=N9EE8Qnu˯r 'ٽʫc>Z^|rNkONC9XY{-Arc9SmkțoY>0څdvLL^|r5~ղ{&N=tJ ϗ_l.nzur,7^(bk}'{D>gJڟtFU;nX /g4)g;;}䂓>{2#Q9\hPQ_5mk($ GI*%UVgmJO>iq͵r)oY^wsv֫+ Î lO<)zt]zi0l։Gj93dWEYvrmO jvej~F)7#a"ݺv ]w?C鐃@ N;r@XYl$ag[n2pm]tթp2^xaiݺhaU `O$c?n-[Hk=fj!]qjV!MJǜQ\SC!ۥؕkz &T.m Ԋv칬3 ]"{OP7Mn$M[*+}ԑyjlՀҽ{wm-6aӹ;t=YէRI'b|p]"x߃c L$d&g$@SOy/M㱪jE}9C+Ho٦^|d=k R8aE?ۨ|k nnj!z{/iX[o+&⸇]~?7))7a'x"v&Hg iʰӡ~7]o&ƋFdGu9)\WI{<ȣ#:u=v57ao$Y7xr1> j=v{s {]}*;k>aJcX< HM&N!zdA2\-\vŲ 4(~\O#fC#mHHC=(nupؔH`!_糧>y 2h g)  fH7iӦ s}/n8Ǐ i\L$@$@$@5#fM$0ٳݍvqB/# hq =ό=Pr$@$@$@$@$И4ߝ{ҺujiHHHHH,?Cަ^M=?`#~Gs?~tQHHHHH`fh"Ҿk}}z88^qvQ ԩSg#    RPVһO_idz*H{I$@$@$@$@$@@ojT8     `R4J$@$@$@$@$EHHHHHHBHU( @ YT(#      UJ$@$@$@$@$@YdQHHHHH*T+ d`E2     `R4J$@$@$@$@$EHHHHHHBHU( @ YT(#     .iݦuUW%@+% J]`c!6Nƌ#뭿,D;9`7_OJTgζn'~ 퓝 @}JR/JVMa^xP\質N2d ة֡c'YsZr͵זd}&RթSʺ_niM!ꫯIӦMo߾Ld+鳶̲kL '7 {g2>\6bK {.+"Fd^utAȧ}&m.l^o햔m7.~'g}L6-O **h?{ݥ̌>g QモN;Z/}@Wvd;N:e֥gskiqrMHLtQG~.Z2+ {di1Uqȑ2pٟ>}Kg'v-|'lM7,K,|嗉3o=\/I*/WJ+(u> <83C$@$@ d ޯsιzUqoY}cuL6pCid{YterG&ȣNB WUe‹,*:w-JƼT|të.+5tpW2:~/\xaYrL`駟6nbl`>d[/p_aŕHT+?beceqOIZ:矂-}s\r)ڄu+ qcձ?e>Ͽ|:3w^M ty&l\PWNPii;L`t '|JJ-3[S߭wYgˎ;l . U+M4Io|q?>CyG}$~RKI޽嘣. {n U[oUn[۶icK/-{쾛|tѤI zv, B` sϕ^~YZl)?v_X{)/}C0}ᇽi֓헴2-yO孷FI۶meeI-&@ooVc1}=r1wz%~gyV=ZY Ʒ֭[ ^PW.Kccyɧ#pݱci㏷ -P1vŗ\"~t\/7bcSc2:ʐ5֔UW[&r'0L6hbdEogE]TpMS%}d ?|sWIe澖[S5xe.]ds8ض-Z(upĖѣG[r lEf筷J2ln{5w͛ːC519V9@O>.Tݧ+y  eGCFW1}tnSO{[}Ƕ,V]U>}y K:QA$K5Sj G08[)ڵk,[put% 4dKgq?vUw[o&}H/r ~aWp{Q<ouCz16_~Ux ۸=alϺ$č\vY`bFmw3_UQ][SguA+Mꫯo[Vm|Pp?d]u,[~]d]¬Bnf{*pS>RJj7_-gy1& y𡇤z`:Q*a[nZҕo]QGtr饗ʑG)#G.Ġk5   hfM ,0ah֬Y_ݵ/8*e/̻5=6|N?8VNsMʍ :cíl)8p`ˊA%㇝`7 sW[ؾ!kì}5mj!oVc%¨8<\ZM7ʽ+/xrh5V{ﳯPo6Iǎă. AwVZ7g:F! Ro\Ec/Ǧ>A&~eHN'lA:Y93RrO*#=^Am*Ǥw^fLDO=aU |>njT}n#߁qЁmw' ;>BfBMʍ9Wfc_$~+(x5M?>}<Kk[sW/&J?;uGl%bV]P>*XeM؆Ր$ŪLx#W_%;v @!РB=d5*@ -77-8uҥ\j[{pN{ﵗu`/6craX\yǤC-QGeAӧo?c'YUj=vcLʝ*^&J+"=}kvԉZnn/}jyuw_С}NVUZnHd ;E6KU ?Jd̐ D^͍~d`VGxNM4&ד'<+|Q]#ٚ~ +HREi^ЧxA+N&  D7Tj^7`q\%1c޶+(`+ @'GNrW0_!KGmlH~  W@*%UޯH]vcϯ+偲J+Uhj$@$@$@$@$8 0i畣"    IiS$@$@$@$@$8 0i畣"    IH괼ҺM[Ӭj=~E9VChc-5N]|`[   h'qoֿdŗvKsÄ__Ͽ_tI'aǏ=etf }Hc&,͂e    *0 IDAT=ylҮ];y'g]wE&6)Q/ W^=W{y_˟F4E21 !~ovOSLDix$@$@$@: |r)'KݥSNv ~1SnF4h+G~7]_>| 8VNri%zh{ɒ;]ʴiӒ~Iv;[2d y:\uU2hd1]YWousl^-GJ>}eEei~{u]ϲ/ζaR\Ǐrk]d1wyY}~?so.H5SoUW[M0N_,JXgL'   LHVߓO>qҤINRol]m]宻l :K.9_5ءca˸#?,^spre?\+N;/C/V< ?KnS[9Cd=v7;#oI:w4[,?7mn!kgJ[fMSNU#oqɱ&Lg}+L#H< v=kҋÌW8/^15HHH;K,!trʩJ+(m:WߧN*@VsYO+L_K..P6_n^j~r 7>m+<`^?lNc\x߽ҫW/-r҉'G)v*yƉq/ -VĖ-Z$U%qfJD`q{)8<0qV<`QR<}x,w1I_ſ(O9kt񬉿% @'P B']߻wh@1 `Íl qᵇnv͖=vU(k~rTz-b˭[^Wvi'/=M6/ܫSGҨܼI] Jq}~]15mH$@$@$@ @Wwa+m#mt[N3o9JݱvHz#OMau>` <=k[7| c|tY`C;.3_vK ؊Kg^687u{1)ƳRz   hL2fK/%yWZk-KmU;~uWݰ/TkISǎ a̘1QK.IcV1o'K/3<2~5MgdZC._|wɘ1YE 7QGjDZ4`ܹL0!T)/#q)u*aQI?#ǗU߬v @c%Pdr / ^~YRuOF+ǘ=F ,Bl̫ Y J^rQGٖ&G7t#dOKrEJ PFZر̷5zvarwh 2޶ourZEQ\qŕ <ŒZb4&NHbrΗ'Ma/7ef1d؆$*D$@$@$@T_/>={!%%%>Pu]vC.]7>)Th0&6 ـW @3uRY0na4zJˍhhhh XջZN}{۾4B3h2lC-m#   ( 蜏ϣ[؀+2.v]u3=I:'YIDlC0    pYDHkiohp;P~1َIh"I?C    烽!|އi yK$@$@$ Ws$k;vy0_&iUAmmY:C4iÅp6)@|(A$@$@$@I&5$466J)JTt]isIN$$F-=ʊ]@ѽVK%s0 q4zi*:Cxa)&Vn3gEEGt8u (R%v" wiI+B_4a0;?v}S$>X6%/_;cP4HHH" `yz>K_d(î.]BVPWWgϘ㱆F[[r]eÆ߀N;'sǎP{$QNs&87d>ɓ'ѵ[WK5Ҟ>}zi62߾eŭ_)S2K+dKp @mރSUU!!ñ=5/S&M逝;/쮱xٝNK|ǒH~{SUXj+HIi}3pqԋ ܹjTWW:w 8.h%#L #x   oz>D|(hqh#x6XI{jwBj9@3F&a(/ΛI2(w| <(\A׿?syƜP^zl)-E=↑֙;NۄKڤ CVjoV,S6}0ӧa,U _{OC{ܜ4Wp<ڀY:Su& .vo.m۶öիh뿻NmHKf$@$@$@$N!Wo3FWT ҞzӲ" "RMV~3pgE&y*!סQ߱cK׮JFܻŎࣲ> 7BIT|uh t7 jΟ?nev/evDXC aqz\{-j/$Tt p\z<4G}},,_CGDE+o4-OX5߀=>})+CӬ53$Y;?Bb=+y+ˍ䓏0斱n\#q &=(AIS>}vxNYYE^?K"T UWjaHKjK$@$@$@18#: lVRޏRwwJjKZ }!x. z9Zscb'ewX;ߓJ`:Ϟ9?g#XA_s.He[[uХK.cEŤfi}$tBЦң̵BW!!eC]YЉğQ;v EPЗjH2de"(4,=0jö́gӰ6me{s7|zIBZ&JZtsVTi9|m6>|fwBz 1҅gސ IDATs*VńV[9O9gšC;*bއmtHnV3M2_G{TiWFǏ^FP1NI/W?aL0PzA>>[kn0,+ӒV#%,N uq97GHHHH :ZyVsKz5lg{*>'jyU`UhHHH9eKaW2J{'t"ъ#]Axڞ={u"8~kN*:A+Rr[SޭɦJVX?_f&c`9Fgwߖ(טsG*VLeb{̈́uM#\Q*c9ͧWh@K| LRm*Bt>!| W8VdACȖEjoN(&k #tC9rDI=y-S>9=+:Dt"xHHHH JZa7[s?T\ x_&:t(rQƱ5>: qMfVFOeť{e.fNjܠ!Cd||oט`uW#*X,ks$=-CFʪYnuqTmP\T|SîTD2ahXgCrVi2nArA?z~9&+*8YWkwd{B lČOK~S$]M$@$@$&[caN sBKkɔJŴ􈨿X\'"t)fIV%]+uMs/Y$dx4,z^?\klheؐMiW'Ew]Q4 jo'b fGBz>Jî˰L+`fM{W26/=Smq&=2WZ@}7)+b_}k;2K-:yRM34׬a:WVbF !=eXԱc2KDH4JLh#ñuNsu:K?X྾B?NKp)#8?#MEiR񡶫Uq]4#;d N e;Zb%2L   P-Љ8mE;:ݳ{O#BYBL61߼.;Z/$?ΝQać|T8~s>م&   PCkYH:FaUˋRe,4HaN8 h $яe#}y^k߈F_&P$2(   H&k\ tVrU萞2CPBw X6Y LWarvjڨ6,M,E$@$@$@I% t~tL։GHIHHH &^59,&,=N _%s#` _J,i@kKב @D|t}[8]|zE:"YIDl؀ @퐑5 (7o뮓%6L6NIFP2lCpz%   X:+K\n󫂭IgDӈm;QPƛIHHHH 9 $@$@$@$@$@} $@$xHHHHH 6 o     P$ F$6^M$@$@$@$@$ R     PƋIHHHH @<^J$@$@$@$@$ x7 @(@KIHHHHb#M$@$@$@$@$@qhw+q^HHHHHH &.z&    H@D.$@$@$@$E#p1:tGӧѭ[7 @>}Ύ;`׺ukdffȑ#|ribر͎끖6:X__vڵPۈVE.a°hYΟ?;F/'|4 $'|۷܄ 0wVىVI kϞ=vͱ3ddI>cʕ8~x!ⷿ-~au]zLE.Q#%g U=V &k2/$@$@$@! hǾ}pԹ_׮]k-HKK'l[n1[{Y.]%3DDqaL:{@/kXv-jkkN~Џ>}:f͚e^Q7j1CcmʍYfīo}>?埊1駟B. >|)@@P8qnG: FM0[v FcSC=VڈM{cƤ:TWՠAoi+7c2,&ϳ0(F,yiHnHe"a},7^prQi1'9ѲZʗJ߿DVVrrrnΫXb統/2>e ^}5~%L4Mᮟ7o-[1qTbƍ7dժUfC=QXѸ.dl9Cq^;:'O Hk_ZXN7 +#<TR1`#0l&2kaU8QÆ Ì'6ϓssaO,g\FMgόN uǶcq8SkBRl1'=+cw֠& -[b ly߉`AeCfU;lƍ84J"쑌)[*;aPTr*[%|cU(e"(uexܿ+-[󄹯WrY]E_jUOZ<To81 ͼdP\ܪU+yW<0^NKŇ*ThcȀf^NVЏczI.4xϧ|6*6?ӦM3DIO@tF!9_o݊7秮XjB\2I`(~4yk7of9VR<MqlmLb +qJRI[7?cbEln?}uz^ o|+W,3޴N9D .ܜykgnf>zPYϟsmfrNȘp"]>aԶ2n(+ߊb|gkj:X!!3bWX,1mו#RوJBmT<556EX!1!=回 o+ՒUl+ةӑ-=m@Kt9P o \ǿBUMyZYeQFHRm\#l,gآP= u*9i9O"ͷ5&p_GZms67Ubm}/K"\#TJں1lV5o)>uUS֏`]X'VnrruXt#Vm+XʚkE߱v",_["Bo4~xp< %5cıwđ*SkT2 !T.ecVMF(Vlk# -N#ߍ5uwO\ϩ b XNT$Օ{` bVwh#Xr8˄,!zjJYB?Cz/j]\e Fܥ k'I/SV}.f#uvj_Rc.<{ ÒUۢQ5)ެOmsu$exwۥ=!6 2wgH߆~2LzKg~Cc;`|>C=뙿i3O=UURd=žj(=oc~I8sɑV->ҶVI7pt"]Cм+cuS'm'&ۡC~En0,==7;#2^G٦~h˿!z^j49UXs=Ojws'կ~Q!xؕ9!TUH'u` y_SVM]o{KEoHv],0B P~%= /m ggJXᣞ Rz~ٯKwҿyk>$=#RZ n@,~ _eҩu(?g4VN@tO]s^x%m{zR/3%=#[$(ڮ9nĶ`)9/f %[Ko{Z|{vjq{/,ãyp6c]-,&+•]ar7S!LC}F|Ms` gv`.ACXY,C}^,mB-a:'/wmD$-BuKR@u`=K(n+./b s÷`_Ԟ> -DNJ=6 ?RA2": B,̟}ӊfk1}/~f<;iCZ2]N5Y%wX\Ԣ*ᒖx|h,[76s o#Szj_h{z,d8J9F|eB69I+)^ZI# }R l.Kx}Ji,%A . uoixpV,RyS%DjO ?{!oV^Evea`BlVX^{2P4h׵oWA-u2*^E /-A~2:Mtr.ƷȷU~l'"< q,X+_(}bY2tt?fÓ,+\Hrv4;Vߋvܮs:K|Dzds'Ưۡć>c"-///}lڴ w`̶sW 8ؿ93*ôLvǍw}Cbtj~ r}%2d@|"[}{ޔ&SuKחJ`0 +-qm 4NT~jI;_.4ém=1A|~_'[T_?"[Zr'3~%5gmFM~=r%{_l/2NV6HC.&m\2b..0duExt'C/e66ȻGJxfVp 4 12(6{| -e,EiD  e8)[U疋(:J6PwR~`@5!Y`/B'Խw 8;)CCB"l++`Py՚]+Kiwߛ( @]p]RVqʑ soagKeK:FyN]¦9{Yl'  Yyy Fc|Z!}A nGFy;h~m:ƭ={={2]mQ qbu XBaXY^] k S[ƒDkbqkGaXb7 s~~>o>h=?斃EԵJ/z\Uv1=ӲćGݶ%B_4sw9훻ʿap:Py}GʪOE( ԅ H=ój&;Ft71խ۰gP>zz>N2M*O^&7e0Qn¿$O ^*y!֠R?f PlO]'/k{ r˓yS܁2R;0[MlD.~^(J$X" ϗIV1fO!R)'($%9۫&$VlSuhTGR=61|v^)g}Kئda#0 P(l׌ZPɅ-||WⷺJs~vIK/D\Q Iٟ/'`wo59g韤6 7B|GjdNk<ԇ\Jxʄ|w;^ ۷l%i]|Uzcx?tby7Xxp~UEnj:?C,{Lj%`x~|ؕPeN. .Kf8 1jRV<)趢*G:ȗݧ.߲4H; f}N9Mpgh7d7opGsv41~m~MGtӱuVh4_ }=_h/puǐ5\XzIDAT} ]IJ+ڮ óA셱Rw꜎huHSyzCljy•] qɽ<) wFJ辧KIZ]"ߑq[VJm|e)TdCli<9oZpc8Ո2ϖeS[~cAVr.i1eFBWܮ5?Bl{/\2΅"%A/}R~Gͣ0*>,\$(cpk$ hgPvb?Õ:[_:k n22 ;Ft ^ ',ds@bu\s>a^ź u-NFz:i=?㐉֌qU֡bz<+ ]UG^Ʈi}0>Gr쩨D٦"L/@3MP }m2GRLXe5ޖCbI+ 2r6$O1׫p5Ւ2ag(gl$exqa!6U|V8B>m$1qsTIm_ L.W/# =*+-a yK;rlxoY!D|@ ؽILC^2g%O:i 'mr\)>Dn"(u}-}#S>bٗgV-1ga3 oqoʀjl\2W?d\ B{8*z<^0%y,={TP:%Qh'뼏:EIJ 2yE&{g?~6zLiEު_\G":L:Տ '>[Kҩx̍VoG?َ柖%eaXrΖvCxH*⏗=qޞOK0kW.CC\yURX˚^{9Z)UȺVn5H=s2b]ΣTvǻO2Ty:L_8˷N~Zv0O~zoW7;I?5yK==VE<|oS1}\d|f^8TyT,? ESyF~ޏvrѿ,#9xaPWPڵ"UC f?H dX/!fːy5a9} F7KXM̚ 3yHJ/Wy4fT",^ژ!BV:CeiҐ3qLnޜ ) f}׋- Yn2!Q@RFLi{63 #3u4T kHi/g@c~'>$v!ިĞA3[ʞ8roGZU8-G*tێ4|.KEe['$>:uj6X²&5l %u5C{>rk x ,{Emǎ&ɓ&Os쭷Š+SԷS [sBBc =h["D{BiOF|u%Btey=w;q?EVUAu֬Ym۶oįsIfS{vH蘾]j|hO·i%݄w`Bq]>#>l Qz?jduB`C6푦9MK$yߜtڻ+'kjş6F5^%_4k8VÊw>x ݻwK2$euL.4s֬Xm+:#,O V"w(o~3*BȖ VO!X0    Pt8L.Rmw!V2w@'S۹.:?+8TG߁"Ńzn kq,p1~ /UV~iXgkVs͏Bx},t9kKlŇ)@%  ЊrktV\KiOK&'Rm-s( 42ɞ^X_2 image/svg+xml D'base Web Site Web Site Web Site Web Site GFS2 Host Host Host Host Shared Storage CoroSync Pacemaker Active / Active ServicesClusterSoftwareHardware GFS2 GFS2 GFS2 URL Mail D'base URL Mail D'base URL Mail D'base URL Mail pacemaker-master/doc/Clusters_from_Scratch/en-US/images/pcmk-active-passive.svg000066400000000000000000001166061217637305600301560ustar00rootroot00000000000000 image/svg+xml URL Web Site Files Storage Host Host CoroSync Pacemaker Active / Passive ServicesClusterSoftwareHardware URL D/base Storage D/base Synch Synch pacemaker-master/doc/Clusters_from_Scratch/en-US/images/pcmk-internals.svg000066400000000000000000001271041217637305600272250ustar00rootroot00000000000000 image/svg+xml Pacemaker Internals crmd stonithd cib pengine lrmd cluster abstraction layer corosync ccm or heartbeat linux-ha project pacemaker project pacemaker-master/doc/Clusters_from_Scratch/en-US/images/pcmk-overview.svg000066400000000000000000000703061217637305600270750ustar00rootroot00000000000000 image/svg+xml Pacemaker 10,000ft Cluster Resource Manager Local Resource Manager Resource Agents Messaging & Membership pacemaker-master/doc/Clusters_from_Scratch/en-US/images/pcmk-shared-failover.svg000066400000000000000000001514071217637305600303040ustar00rootroot00000000000000 image/svg+xml URL Mail Files Storage Host Host Host Host CoroSync Pacemaker Shared Failover Hardware ClusterSoftware Services Storage D'base Storage Storage D'base URL URL Web Site Files Synch Synch Synch pacemaker-master/doc/Clusters_from_Scratch/en-US/images/pcmk-stack.svg000066400000000000000000001021201217637305600263220ustar00rootroot00000000000000 image/svg+xml cLVM2 GFS2 OCFS2 Distributed Lock Manager CoroSync Pacemaker Pacemaker Stack Build Dependancy Resource Agents Cluster Glue pacemaker-master/doc/Clusters_from_Scratch/it-IT/000077500000000000000000000000001217637305600223025ustar00rootroot00000000000000pacemaker-master/doc/Clusters_from_Scratch/it-IT/Ap-Configuration.po000066400000000000000000000525531217637305600260210ustar00rootroot00000000000000# # AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: 0\n" "POT-Creation-Date: 2012-10-17T05:19:03\n" "PO-Revision-Date: 2010-07-14 16:33+0100\n" "Last-Translator: RaSca \n" "Language-Team: None\n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. Tag: title #, no-c-format msgid "Configuration Recap" msgstr "Riepilogo delle configurazioni" #. Tag: title #, no-c-format msgid "Final Cluster Configuration" msgstr "Configurazione finale del cluster" #. Tag: programlisting #, no-c-format msgid "" "# pcs resource\n" " Master/Slave Set: WebDataClone [WebData]\n" " Masters: [ pcmk-2 pcmk-1 ]\n" " Clone Set: dlm-clone [dlm]\n" " Started: [ pcmk-2 pcmk-1 ]\n" " Clone Set: ClusterIP-clone [ClusterIP] (unique)\n" " ClusterIP:0 (ocf::heartbeat:IPaddr2) Started\n" " ClusterIP:1 (ocf::heartbeat:IPaddr2) Started\n" " Clone Set: WebFS-clone [WebFS]\n" " Started: [ pcmk-1 pcmk-2 ]\n" " Clone Set: WebSite-clone [WebSite]\n" " Started: [ pcmk-1 pcmk-2 ]\n" "# pcs resource rsc defaults\n" "resource-stickiness: 100\n" "# pcs resource op defaults\n" "timeout: 240s\n" "# pcs stonith\n" " impi-fencing (stonith:fence_ipmilan) Started\n" "# pcs property\n" "dc-version: 1.1.8-1.el7-60a19ed12fdb4d5c6a6b6767f52e5391e447fec0\n" "cluster-infrastructure: corosync\n" "no-quorum-policy: ignore\n" "stonith-enabled: true\n" "# pcs constraint\n" "Location Constraints:\n" "Ordering Constraints:\n" " ClusterIP-clone then WebSite-clone\n" " WebDataClone then WebSite-clone\n" " WebFS-clone then WebSite-clone\n" "Colocation Constraints:\n" " WebSite-clone with ClusterIP-clone\n" " WebFS-clone with WebDataClone (with-rsc-role:Master)\n" " WebSite-clone with WebFS-clone\n" "#\n" "# pcs status\n" "\n" "Last updated: Fri Sep 14 13:45:34 2012\n" "Last change: Fri Sep 14 13:43:13 2012 via cibadmin on pcmk-1\n" "Stack: corosync\n" "Current DC: pcmk-1 (1) - partition with quorum\n" "Version: 1.1.8-1.el7-60a19ed12fdb4d5c6a6b6767f52e5391e447fec0\n" "2 Nodes configured, unknown expected votes\n" "11 Resources configured.\n" "\n" "Online: [ pcmk-1 pcmk-2 ]\n" "\n" "Full list of resources:\n" "\n" " Master/Slave Set: WebDataClone [WebData]\n" " Masters: [ pcmk-2 pcmk-1 ]\n" " Clone Set: dlm-clone [dlm]\n" " Started: [ pcmk-1 pcmk-2 ]\n" " Clone Set: ClusterIP-clone [ClusterIP] (unique)\n" " ClusterIP:0 (ocf::heartbeat:IPaddr2): Started pcmk-1\n" " ClusterIP:1 (ocf::heartbeat:IPaddr2): Started pcmk-2\n" " Clone Set: WebFS-clone [WebFS]\n" " Started: [ pcmk-1 pcmk-2 ]\n" " Clone Set: WebSite-clone [WebSite]\n" " Started: [ pcmk-1 pcmk-2 ]\n" " impi-fencing (stonith:fence_ipmilan): Started" msgstr "" #. Tag: para #, no-c-format msgid "In xml it should look similar to this." msgstr "" #. Tag: programlisting #, no-c-format msgid "" "<cib admin_epoch=\"0\" cib-last-written=\"Fri Sep 14 13:43:13 2012\" crm_feature_set=\"3.0.6\" dc-uuid=\"1\" epoch=\"47\" have-quorum=\"1\" num_updates=\"50\" update-client=\"cibadmin\" update-origin=\"pcmk-1\" validate-with=\"pacemaker-1.2\">\n" " <configuration>\n" " <crm_config>\n" " <cluster_property_set id=\"cib-bootstrap-options\">\n" " <nvpair id=\"cib-bootstrap-options-dc-version\" name=\"dc-version\" value=\"1.1.8-1.el7-60a19ed12fdb4d5c6a6b6767f52e5391e447fec0\"/>\n" " <nvpair id=\"cib-bootstrap-options-cluster-infrastructure\" name=\"cluster-infrastructure\" value=\"corosync\"/>\n" " <nvpair id=\"cib-bootstrap-options-no-quorum-policy\" name=\"no-quorum-policy\" value=\"ignore\"/>\n" " <nvpair id=\"cib-bootstrap-options-stonith-enabled\" name=\"stonith-enabled\" value=\"true\"/>\n" " </cluster_property_set>\n" " </crm_config>\n" " <nodes>\n" " <node id=\"1\" type=\"normal\" uname=\"pcmk-1\"/>\n" " <node id=\"2\" type=\"normal\" uname=\"pcmk-2\"/>\n" " </nodes>\n" " <resources>\n" " <master id=\"WebDataClone\">\n" " <primitive class=\"ocf\" id=\"WebData\" provider=\"linbit\" type=\"drbd\">\n" " <instance_attributes id=\"WebData-instance_attributes\">\n" " <nvpair id=\"WebData-instance_attributes-drbd_resource\" name=\"drbd_resource\" value=\"wwwdata\"/>\n" " </instance_attributes>\n" " <operations>\n" " <op id=\"WebData-interval-60s\" interval=\"60s\" name=\"monitor\"/>\n" " </operations>\n" " </primitive>\n" " <meta_attributes id=\"WebDataClone-meta_attributes\">\n" " <nvpair id=\"WebDataClone-meta_attributes-master-node-max\" name=\"master-node-max\" value=\"1\"/>\n" " <nvpair id=\"WebDataClone-meta_attributes-clone-max\" name=\"clone-max\" value=\"2\"/>\n" " <nvpair id=\"WebDataClone-meta_attributes-clone-node-max\" name=\"clone-node-max\" value=\"1\"/>\n" " <nvpair id=\"WebDataClone-meta_attributes-notify\" name=\"notify\" value=\"true\"/>\n" " <nvpair id=\"WebDataClone-meta_attributes-master-max\" name=\"master-max\" value=\"2\"/>\n" " </meta_attributes>\n" " </master>\n" " <clone id=\"dlm-clone\">\n" " <primitive class=\"ocf\" id=\"dlm\" provider=\"pacemaker\" type=\"controld\">\n" " <instance_attributes id=\"dlm-instance_attributes\"/>\n" " <operations>\n" " <op id=\"dlm-interval-60s\" interval=\"60s\" name=\"monitor\"/>\n" " </operations>\n" " </primitive>\n" " <meta_attributes id=\"dlm-clone-meta\">\n" " <nvpair id=\"dlm-clone-max\" name=\"clone-max\" value=\"2\"/>\n" " <nvpair id=\"dlm-clone-node-max\" name=\"clone-node-max\" value=\"1\"/>\n" " </meta_attributes>\n" " </clone>\n" " <clone id=\"ClusterIP-clone\">\n" " <primitive class=\"ocf\" id=\"ClusterIP\" provider=\"heartbeat\" type=\"IPaddr2\">\n" " <instance_attributes id=\"ClusterIP-instance_attributes\">\n" " <nvpair id=\"ClusterIP-instance_attributes-ip\" name=\"ip\" value=\"192.168.0.120\"/>\n" " <nvpair id=\"ClusterIP-instance_attributes-cidr_netmask\" name=\"cidr_netmask\" value=\"32\"/>\n" " <nvpair id=\"ClusterIP-instance_attributes-clusterip_hash\" name=\"clusterip_hash\" value=\"sourceip\"/>\n" " </instance_attributes>\n" " <operations>\n" " <op id=\"ClusterIP-interval-30s\" interval=\"30s\" name=\"monitor\"/>\n" " </operations>\n" " </primitive>\n" " <meta_attributes id=\"ClusterIP-clone-meta\">\n" " <nvpair id=\"ClusterIP-globally-unique\" name=\"globally-unique\" value=\"true\"/>\n" " <nvpair id=\"ClusterIP-clone-max\" name=\"clone-max\" value=\"2\"/>\n" " <nvpair id=\"ClusterIP-clone-node-max\" name=\"clone-node-max\" value=\"2\"/>\n" " </meta_attributes>\n" " </clone>\n" " <clone id=\"WebFS-clone\">\n" " <primitive class=\"ocf\" id=\"WebFS\" provider=\"heartbeat\" type=\"Filesystem\">\n" " <instance_attributes id=\"WebFS-instance_attributes\">\n" " <nvpair id=\"WebFS-instance_attributes-device\" name=\"device\" value=\"/dev/drbd/by-res/wwwdata\"/>\n" " <nvpair id=\"WebFS-instance_attributes-directory\" name=\"directory\" value=\"/var/www/html\"/>\n" " <nvpair id=\"WebFS-instance_attributes-fstype\" name=\"fstype\" value=\"gfs2\"/>\n" " </instance_attributes>\n" " <meta_attributes id=\"WebFS-meta_attributes\"/>\n" " </primitive>\n" " <meta_attributes id=\"WebFS-clone-meta\"/>\n" " </clone>\n" " <clone id=\"WebSite-clone\">\n" " <primitive class=\"ocf\" id=\"WebSite\" provider=\"heartbeat\" type=\"apache\">\n" " <instance_attributes id=\"WebSite-instance_attributes\">\n" " <nvpair id=\"WebSite-instance_attributes-configfile\" name=\"configfile\" value=\"/etc/httpd/conf/httpd.conf\"/>\n" " <nvpair id=\"WebSite-instance_attributes-statusurl\" name=\"statusurl\" value=\"http://localhost/server-status\"/>\n" " </instance_attributes>\n" " <operations>\n" " <op id=\"WebSite-interval-1min\" interval=\"1min\" name=\"monitor\"/>\n" " </operations>\n" " </primitive>\n" " <meta_attributes id=\"WebSite-clone-meta\"/>\n" " </clone>\n" " <primitive class=\"stonith\" id=\"impi-fencing\" type=\"fence_ipmilan\">\n" " <instance_attributes id=\"impi-fencing-instance_attributes\">\n" " <nvpair id=\"impi-fencing-instance_attributes-pcmk_host_list\" name=\"pcmk_host_list\" value=\"pcmk-1 pcmk-2\"/>\n" " <nvpair id=\"impi-fencing-instance_attributes-ipaddr\" name=\"ipaddr\" value=\"10.0.0.1\"/>\n" " <nvpair id=\"impi-fencing-instance_attributes-login\" name=\"login\" value=\"testuser\"/>\n" " <nvpair id=\"impi-fencing-instance_attributes-passwd\" name=\"passwd\" value=\"acd123\"/>\n" " </instance_attributes>\n" " <operations>\n" " <op id=\"impi-fencing-interval-60s\" interval=\"60s\" name=\"monitor\"/>\n" " </operations>\n" " </primitive>\n" " </resources>\n" " <constraints>\n" " <rsc_colocation id=\"colocation-WebSite-ClusterIP-INFINITY\" rsc=\"WebSite-clone\" score=\"INFINITY\" with-rsc=\"ClusterIP-clone\"/>\n" " <rsc_order first=\"ClusterIP-clone\" first-action=\"start\" id=\"order-ClusterIP-WebSite-mandatory\" then=\"WebSite-clone\" then-action=\"start\"/>\n" " <rsc_colocation id=\"colocation-WebFS-WebDataClone-INFINITY\" rsc=\"WebFS-clone\" score=\"INFINITY\" with-rsc=\"WebDataClone\" with-rsc-role=\"Master\"/>\n" " <rsc_colocation id=\"colocation-WebSite-WebFS-INFINITY\" rsc=\"WebSite-clone\" score=\"INFINITY\" with-rsc=\"WebFS-clone\"/>\n" " <rsc_order first=\"WebFS-clone\" id=\"order-WebFS-WebSite-mandatory\" then=\"WebSite-clone\"/>\n" " <rsc_order first=\"WebDataClone\" first-action=\"promote\" id=\"order-WebDataClone-WebFS-mandatory\" then=\"WebFS-clone\" then-action=\"start\"/>\n" " </constraints>\n" " <rsc_defaults>\n" " <meta_attributes id=\"rsc_defaults-options\">\n" " <nvpair id=\"rsc_defaults-options-resource-stickiness\" name=\"resource-stickiness\" value=\"100\"/>\n" " </meta_attributes>\n" " </rsc_defaults>\n" " <op_defaults>\n" " <meta_attributes id=\"op_defaults-options\">\n" " <nvpair id=\"op_defaults-options-timeout\" name=\"timeout\" value=\"240s\"/>\n" " </meta_attributes>\n" " </op_defaults>\n" " </configuration>\n" "</cib>" msgstr "" #. Tag: title #, no-c-format msgid "Node List" msgstr "Lista nodi" #. Tag: para #, no-c-format msgid "The list of cluster nodes is automatically populated by the cluster." msgstr "La lista dei nodi è popolata automaticamente dal cluster." #. Tag: literallayout #, no-c-format msgid "" "Pacemaker Nodes:\n" " Online: [ pcmk-1 pcmk-2 ]" msgstr "" #. Tag: title #, no-c-format msgid "Cluster Options" msgstr "Opzioni del cluster" #. Tag: para #, no-c-format msgid "This is where the cluster automatically stores some information about the cluster" msgstr "Qui è dove il cluster registra automaticamente alcune informazioni in merito al cluster" #. Tag: para #, no-c-format msgid "dc-version - the version (including upstream source-code hash) of Pacemaker used on the DC" msgstr "dc-version - la versione (incluso l'hash del codice sorgente originale) di Pacemaker usata nel DC" #. Tag: para #, no-c-format msgid "cluster-infrastructure - the cluster infrastructure being used (heartbeat or openais)" msgstr "cluster-infrastructure - l'infrastruttura cluster utilizzata (heartbeat or openais)" #. Tag: para #, no-c-format msgid "expected-quorum-votes - the maximum number of nodes expected to be part of the cluster" msgstr "expected-quorum-votes - il numero massimo di nodi che ci si aspetta facciano parte del cluster" #. Tag: para #, no-c-format msgid "and where the admin can set options that control the way the cluster operates" msgstr "e dove l'amministratore può assegnare valori alle opzioni che controllano il modo in cui il cluster opera" #. Tag: para #, no-c-format msgid "stonith-enabled=true - Make use of STONITH" msgstr "stonith-enabled=true - Fai uso di STONITH" #. Tag: para #, no-c-format msgid "no-quorum-policy=ignore - Ignore loss of quorum and continue to host resources." msgstr "no-quorum-policy=ignore - Ignora la perdita di quorum e continua ad ospitare le risorse." #. Tag: programlisting #, no-c-format msgid "" "# pcs property\n" "dc-version: 1.1.8-1.el7-60a19ed12fdb4d5c6a6b6767f52e5391e447fec0\n" "cluster-infrastructure: corosync\n" "no-quorum-policy: ignore\n" "stonith-enabled: true" msgstr "" #. Tag: title #, no-c-format msgid "Resources" msgstr "Risorse" #. Tag: title #, no-c-format msgid "Default Options" msgstr "Opzioni di default" #. Tag: para #, no-c-format msgid "Here we configure cluster options that apply to every resource." msgstr "Qui vengono configurate le opzioni del cluster che vanno applicati a tutte le risorse" #. Tag: para #, no-c-format msgid "resource-stickiness - Specify the aversion to moving resources to other machines" msgstr "resource-stickiness - Specifica l'impossibilità o meno di muovere risorse ad altre macchine" #. Tag: programlisting #, no-c-format msgid "" "# pcs resource rsc defaults\n" "resource-stickiness: 100" msgstr "" #. Tag: title #, no-c-format msgid "Fencing" msgstr "Fencing" #. Tag: programlisting #, no-c-format msgid "" "# pcs stonith show\n" " impi-fencing (stonith:fence_ipmilan) Started\n" "# pcs stonith show impi-fencing\n" "Resource: impi-fencing\n" " pcmk_host_list: pcmk-1 pcmk-2\n" " ipaddr: 10.0.0.1\n" " login: testuser\n" " passwd: acd123" msgstr "" #. Tag: title #, no-c-format msgid "Service Address" msgstr "Servizio Address" #. Tag: para #, fuzzy, no-c-format msgid "Users of the services provided by the cluster require an unchanging address with which to access it. Additionally, we cloned the address so it will be active on both nodes. An iptables rule (created as part of the resource agent) is used to ensure that each request only gets processed by one of the two clone instances. The additional meta options tell the cluster that we want two instances of the clone (one \"request bucket\" for each node) and that if one node fails, then the remaining node should hold both." msgstr "Gli utenti dei servizi forniti dal cluster richiedono un indirizzo invariato con cui accedervi. Inoltre, l'indirizzo viene clonato così da essere attivo su entrambi i nodi. Una regola iptables (creata come parte del resource agent) viene utilizzata per assicurarsi che ogni richiesta venga processata unicamente da una delle due istanze clone. Le opzioni meta aggiuntive indicano al cluste che si necessità di due istanze del clone (una \"request bucket\" per ogni nodo) e che se un nodo muote, allora il nodo rimanente deve erogarle entrambe." #. Tag: programlisting #, no-c-format msgid "" "# pcs resource show ClusterIP-clone\n" "Resource: ClusterIP-clone\n" " ip: 192.168.0.120\n" " cidr_netmask: 32\n" " clusterip_hash: sourceip\n" " globally-unique: true\n" " clone-max: 2\n" " clone-node-max: 2\n" " op monitor interval=30s" msgstr "" #. Tag: para #, no-c-format msgid "TODO: The RA should check for globally-unique=true when cloned" msgstr "TODO: Il RA quando clonato dovrebbe controllare l'opzione globally-unique=true" #. Tag: title #, no-c-format msgid "DRBD - Shared Storage" msgstr "DRBD - Storage condiviso" #. Tag: para #, no-c-format msgid "Here we define the DRBD service and specify which DRBD resource (from drbd.conf) it should manage. We make it a master/slave resource and, in order to have an active/active setup, allow both instances to be promoted by specifying master-max=2. We also set the notify option so that the cluster will tell DRBD agent when it’s peer changes state." msgstr "Qui viene definito il servizio DRBD e specificata quale risorsa DRBD (da drbd.conf) questi debba controllare. La risorsa viene definita come master/slave e, per rispettare il setup active/active, entrambe le istanze vengono abilitate ad essere promosse specificando master-max=2. Viene valorizzata inoltre l'opzione notify, così che il cluster comunicherà all'agent DRBD quando il suo nodo cambierà stato." #. Tag: programlisting #, no-c-format msgid "" "# pcs resource show WebDataClone\n" "Resource: WebDataClone\n" " drbd_resource: wwwdata\n" " master-node-max: 1\n" " clone-max: 2\n" " clone-node-max: 1\n" " notify: true\n" " master-max: 2\n" " op monitor interval=60s\n" "# pcs constraint ref WebDataClone\n" "Resource: WebDataClone\n" " colocation-WebFS-WebDataClone-INFINITY\n" " order-WebDataClone-WebFS-mandatory" msgstr "" #. Tag: title #, no-c-format msgid "Cluster Filesystem" msgstr "Cluster Filesystem" #. Tag: para #, no-c-format msgid "The cluster filesystem ensures that files are read and written correctly. We need to specify the block device (provided by DRBD), where we want it mounted and that we are using GFS2. Again it is a clone because it is intended to be active on both nodes. The additional constraints ensure that it can only be started on nodes with active gfs-control and drbd instances." msgstr "Il Cluster Filesystem si assicura che i file vengano letti e scritti nella maniera corretta. E' necessario specificare il block device (fornito da DRBD), dove si vuole effettuare l'operazione di mount e che viene utilizzato GFS2. Di nuovo questo è un clone, perché è inteso essere attivo su entrambi i nodi. La constraint aggiuntiva assicura che la risorsa possa essere avviata su nodi con gfs-control attivo e istanze drbd." #. Tag: programlisting #, no-c-format msgid "" "# pcs resource show WebFS-clone\n" "Resource: WebFS-clone\n" " device: /dev/drbd/by-res/wwwdata\n" " directory: /var/www/html\n" " fstype: gfs2\n" "# pcs constraint ref WebFS-clone\n" "Resource: WebFS-clone\n" " colocation-WebFS-WebDataClone-INFINITY\n" " colocation-WebSite-WebFS-INFINITY\n" " order-WebFS-WebSite-mandatory\n" " order-WebDataClone-WebFS-mandatory" msgstr "" #. Tag: title #, no-c-format msgid "Apache" msgstr "Apache" #. Tag: para #, no-c-format msgid "Lastly we have the actual service, Apache. We need only tell the cluster where to find it’s main configuration file and restrict it to running on nodes that have the required filesystem mounted and the IP address active." msgstr "Infine viene definito il servizio Apache. E' necessario solamente specificare al cluster dove trovare il file di configurazione principale e costringere questo ad essere eseguito su nodi con il filesystem richiesto montato e l'indirizzo IP attivo." #. Tag: programlisting #, no-c-format msgid "" "# pcs resource show WebSite-clone\n" "Resource: WebSite-clone\n" " configfile: /etc/httpd/conf/httpd.conf\n" " statusurl: http://localhost/server-status\n" " master-max: 2\n" " op monitor interval=1min\n" "# pcs constraint ref WebSite-clone\n" "Resource: WebSite-clone\n" " colocation-WebSite-ClusterIP-INFINITY\n" " colocation-WebSite-WebFS-INFINITY\n" " order-ClusterIP-WebSite-mandatory\n" " order-WebFS-WebSite-mandatory" msgstr "" #~ msgid "TODO: Add text here" #~ msgstr "TODO: Aggiungi il testo qui" #~ msgid "Distributed lock manager" #~ msgstr "Distributed lock manager" #~ msgid "Cluster filesystems like GFS2 require a lock manager. This service starts the daemon that provides user-space applications (such as the GFS2 daemon) with access to the in-kernel lock manager. Since we need it to be available on all nodes in the cluster, we have it cloned." #~ msgstr "I filesystem cluster come GFS2 richiedono un lock manager. Questo servizio avvia il demone che fornisce applicazioni user-spacc (come il demone GFS2) con accesso al lock manager interno al kernel. Dato che si necessita di averlo attivo su tutti nodi del cluste, questo viene clonato." #~ msgid "TODO: Confirm interleave is no longer needed" #~ msgstr "TODO: La conferma del parametro interleave non è più necessaria" #~ msgid "GFS control daemon" #~ msgstr "Demone di controllo di GFS" #~ msgid "GFS2 also needs a user-space/kernel bridge that runs on every node. So here we have another clone, however this time we must also specify that it can only run on machines that are also running the DLM (colocation constraint) and that it can only be started after the DLM is running (order constraint). Additionally, the gfs-control clone should only care about the DLM instances it is paired with, so we need to set the interleave option." #~ msgstr "GFS2 inoltre necessita di un ponte user-space/kernel eseguito su ogni nodo. Così qui è presente un altro clone, sebbene questa volta va scpecificato che può girare su macchine che tanno eseguendo anche il DLM (colocation constraint) e che questo può solamente essere avviato dopo che il DLM viene a sua volta avviato (order constraint). Inoltre, il clone gfs-control deve preoccuparsi unicamente dell'istanza DLM a cui è associato, così non è necessario valorizzare l'opzione interleave." pacemaker-master/doc/Clusters_from_Scratch/it-IT/Ap-Corosync-Conf.po000066400000000000000000000020521217637305600256610ustar00rootroot00000000000000# # AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: 0\n" "POT-Creation-Date: 2012-10-17T05:19:03\n" "PO-Revision-Date: 2010-07-14 15:18+0100\n" "Last-Translator: RaSca \n" "Language-Team: None\n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. Tag: title #, fuzzy, no-c-format msgid "Sample Corosync Configuration" msgstr "Listato di Corosync.conf" #. Tag: title #, no-c-format msgid "Sample corosync.conf for two-node cluster using a node list." msgstr "" #. Tag: literallayout #, no-c-format msgid "" "# Please read the corosync.conf.5 manual page\n" "totem {\n" "version: 2\n" "secauth: off\n" "cluster_name: mycluster\n" "transport: udpu\n" "}\n" "\n" "nodelist {\n" " node {\n" " ring0_addr: pcmk-1\n" " nodeid: 1\n" " }\n" " node {\n" " ring0_addr: pcmk-2\n" " nodeid: 2\n" " }\n" "}\n" "\n" "quorum {\n" " provider: corosync_votequorum\n" "}\n" "\n" "logging {\n" " to_syslog: yes\n" "}" msgstr "" pacemaker-master/doc/Clusters_from_Scratch/it-IT/Ap-Reading.po000066400000000000000000000037301217637305600245540ustar00rootroot00000000000000# # AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: 0\n" "POT-Creation-Date: 2012-10-17T05:19:03\n" "PO-Revision-Date: 2010-07-14 15:17+0100\n" "Last-Translator: RaSca \n" "Language-Team: None\n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. Tag: title #, no-c-format msgid "Further Reading" msgstr "Approfondimenti" #. Tag: para #, fuzzy, no-c-format msgid "Project Website http://www.clusterlabs.org" msgstr "http://www.clusterlabs.org" #. Tag: para #, fuzzy, no-c-format msgid "Cluster Commands A comprehensive guide to cluster commands has been written by SuSE and can be found at: http://www.suse.com/documentation/sle_ha/book_sleha/?page=/documentation/sle_ha/book_sleha/data/book_sleha.html" msgstr "http://www.novell.com/documentation/sles11/book_sleha/index.html?page=/documentation/sles11/book_sleha/data/book_sleha.html" #. Tag: para #, fuzzy, no-c-format msgid "Corosync http://www.corosync.org" msgstr "http://www.corosync.org" #~ msgid "Project Website" #~ msgstr "Sito del progetto" #~ msgid "Cluster Commands" #~ msgstr "Comandi cluster" #~ msgid "A comprehensive guide to cluster commands has been written by Novell and can be found at:" #~ msgstr "Una guida generale è stata redatta da Novell e si trova qui:" #~ msgid "Corosync" #~ msgstr "Corosync" pacemaker-master/doc/Clusters_from_Scratch/it-IT/Author_Group.po000066400000000000000000000017221217637305600252620ustar00rootroot00000000000000# # AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: 0\n" "POT-Creation-Date: 2012-10-17T05:19:03\n" "PO-Revision-Date: 2010-07-07T15:51:40\n" "Last-Translator: Automatically generated\n" "Language-Team: None\n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: application/x-publican; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. Tag: firstname #, no-c-format msgid "Andrew" msgstr "" #. Tag: surname #, no-c-format msgid "Beekhof" msgstr "" #. Tag: orgname #, no-c-format msgid "Red Hat" msgstr "" #. Tag: contrib #, no-c-format msgid "Primary author" msgstr "" #. Tag: firstname #, no-c-format msgid "Raoul" msgstr "" #. Tag: surname #, no-c-format msgid "Scarazzini" msgstr "" #. Tag: contrib #, no-c-format msgid "Italian translation" msgstr "" #. Tag: firstname #, no-c-format msgid "Dan" msgstr "" #. Tag: surname #, no-c-format msgid "Frîncu" msgstr "" #. Tag: contrib #, no-c-format msgid "Romanian translation" msgstr "" pacemaker-master/doc/Clusters_from_Scratch/it-IT/Book_Info.po000066400000000000000000000051141217637305600245100ustar00rootroot00000000000000# # AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: 0\n" "POT-Creation-Date: 2012-10-17T05:19:03\n" "PO-Revision-Date: 2010-07-14 14:59+0100\n" "Last-Translator: RaSca \n" "Language-Team: None\n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. Tag: title #, no-c-format msgid "Clusters from Scratch" msgstr "Clusters from Scratch" #. Tag: subtitle #, no-c-format msgid "Creating Active/Passive and Active/Active Clusters on Fedora" msgstr "Creare cluster Active/Passive e Active/Active su Fedora" #. Tag: productname #, no-c-format msgid "Pacemaker" msgstr "" #. Tag: para #, no-c-format msgid "The purpose of this document is to provide a start-to-finish guide to building an example active/passive cluster with Pacemaker and show how it can be converted to an active/active one." msgstr "Lo scopo di questo documento è di fornire una guida completa per costruire un cluster active/passive con Pacemaker e mostrare come può essere convertito in una configurazione active/active. " #. Tag: para #, no-c-format msgid "The example cluster will use:" msgstr "Il cluster userà:" #. Tag: para #, no-c-format msgid "&DISTRO; &DISTRO_VERSION; as the host operating system" msgstr "&DISTRO; &DISTRO_VERSION; come sistema operativo" #. Tag: para #, no-c-format msgid "Corosync to provide messaging and membership services," msgstr "Corosync per fornire i servizi di messaging e membership," #. Tag: para #, no-c-format msgid "Pacemaker to perform resource management," msgstr "Pacemaker per la gestione delle risorse" #. Tag: para #, no-c-format msgid "DRBD as a cost-effective alternative to shared storage," msgstr "DRBD come alternativa prezzo/prestazioni allo storage condiviso," #. Tag: para #, no-c-format msgid "GFS2 as the cluster filesystem (in active/active mode)" msgstr "GFS2 come cluster filesystem (nella modalità active/active)" #. Tag: para #, no-c-format msgid "Given the graphical nature of the Fedora install process, a number of screenshots are included. However the guide is primarily composed of commands, the reasons for executing them and their expected outputs." msgstr "Per via del processo grafico di installazione di Fedora, diversi screenshot sono inclusi. Ad ogni modo questa guida è composta primariamente dai comandi, dalle ragioni per cui questi vengono eseguiti e l'output da loro prodotto." #~ msgid "The crm shell for displaying the configuration and making changes" #~ msgstr "La shell crm per la visualizzazione della configurazione e l'attuazione delle modifiche" pacemaker-master/doc/Clusters_from_Scratch/it-IT/Ch-Active-Active.po000066400000000000000000000547711217637305600256340ustar00rootroot00000000000000# # AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: 0\n" "POT-Creation-Date: 2012-10-17T05:19:03\n" "PO-Revision-Date: 2010-08-04 11:23+0100\n" "Last-Translator: RaSca \n" "Language-Team: None\n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. Tag: title #, no-c-format msgid "Conversion to Active/Active" msgstr "Conversione in Active/Active" #. Tag: title #, no-c-format msgid "Requirements" msgstr "Requisiti" #. Tag: para #, fuzzy, no-c-format msgid "The primary requirement for an Active/Active cluster is that the data required for your services is available, simultaneously, on both machines. Pacemaker makes no requirement on how this is achieved, you could use a SAN if you had one available, however since DRBD supports multiple Primaries, we can also use that." msgstr "Il requisito primario di un cluster Active/Active è che i dati richiesti dai servizi siano disponibili, simultaneamente, su entrambe le macchine. Pacemaker non impone requisiti su come questa funzionalità venga gestita, è possibile utilizzare una SAN (Storage Area Network) se ne si possiede una, ad ogni modo è possibile utilizzare anche DRBD, visto che supporta configurazioni multi-Primary." #. Tag: para #, fuzzy, no-c-format msgid "The only hitch is that we need to use a cluster-aware filesystem. The one we used earlier with DRBD, ext4, is not one of those. Both OCFS2 and GFS2 are supported, however here we will use GFS2 which comes with Fedora 17." msgstr "L'unico inconveniente sta nel fatto di dover utilizzare un filesystem cluster-aware (e quello usato in precedenza, ext4, non è uno di questi). Sia OCFS2 che GFS2 sono supportati, la scelta cadrà su GFS2, disponibile con &DISTRO; &DISTRO_VERSION; ." #. Tag: title #, no-c-format msgid "Installing the required Software" msgstr "" #. Tag: programlisting #, no-c-format msgid "# yum install -y gfs2-utils dlm kernel-modules-extra" msgstr "" #. Tag: literallayout #, no-c-format msgid "" "Loaded plugins: langpacks, presto, refresh-packagekit\n" "Resolving Dependencies\n" "--> Running transaction check\n" "---> Package dlm.x86_64 0:3.99.4-1.fc17 will be installed\n" "---> Package gfs2-utils.x86_64 0:3.1.4-3.fc17 will be installed\n" "---> Package kernel-modules-extra.x86_64 0:3.4.4-3.fc17 will be installed\n" "--> Finished Dependency Resolution\n" "\n" "Dependencies Resolved\n" "\n" "================================================================================\n" " Package Arch Version Repository Size\n" "================================================================================\n" "Installing:\n" " dlm x86_64 3.99.4-1.fc17 updates 83 k\n" " gfs2-utils x86_64 3.1.4-3.fc17 fedora 214 k\n" " kernel-modules-extra x86_64 3.4.4-3.fc17 updates 1.7 M\n" "\n" "Transaction Summary\n" "================================================================================\n" "Install 3 Packages\n" "\n" "Total download size: 1.9 M\n" "Installed size: 7.7 M\n" "Downloading Packages:\n" "(1/3): dlm-3.99.4-1.fc17.x86_64.rpm | 83 kB 00:00\n" "(2/3): gfs2-utils-3.1.4-3.fc17.x86_64.rpm | 214 kB 00:00\n" "(3/3): kernel-modules-extra-3.4.4-3.fc17.x86_64.rpm | 1.7 MB 00:01\n" "--------------------------------------------------------------------------------\n" "Total 615 kB/s | 1.9 MB 00:03\n" "Running Transaction Check\n" "Running Transaction Test\n" "Transaction Test Succeeded\n" "Running Transaction\n" " Installing : kernel-modules-extra-3.4.4-3.fc17.x86_64 1/3\n" " Installing : gfs2-utils-3.1.4-3.fc17.x86_64 2/3\n" " Installing : dlm-3.99.4-1.fc17.x86_64 3/3\n" " Verifying : dlm-3.99.4-1.fc17.x86_64 1/3\n" " Verifying : gfs2-utils-3.1.4-3.fc17.x86_64 2/3\n" " Verifying : kernel-modules-extra-3.4.4-3.fc17.x86_64 3/3\n" "\n" "Installed:\n" " dlm.x86_64 0:3.99.4-1.fc17\n" " gfs2-utils.x86_64 0:3.1.4-3.fc17\n" " kernel-modules-extra.x86_64 0:3.4.4-3.fc17\n" "\n" "Complete!" msgstr "" #. Tag: title #, no-c-format msgid "Create a GFS2 Filesystem" msgstr "Creazione un Filesystem GFS2" #. Tag: title #, no-c-format msgid "Preparation" msgstr "Preparazione" #. Tag: para #, fuzzy, no-c-format msgid "Before we do anything to the existing partition, we need to make sure it is unmounted. We do this by telling the cluster to stop the WebFS resource. This will ensure that other resources (in our case, Apache) using WebFS are not only stopped, but stopped in the correct order." msgstr "Prima di fare qualsiasi operazione sulla partizione esistente bisogna accertarsi che questa sia smontata. Ciò è possibile indicando al cluster di fermare la risorsa WebFS. Questo garantirà che altre risorse (nel nostro caso, Apache) che utilizzano WebFS non sono solamente fermate, ma sono state fermate nell'ordine corretto." #. Tag: programlisting #, no-c-format msgid "" "# pcs resource stop WebFS\n" "# pcs resource\n" " ClusterIP (ocf::heartbeat:IPaddr2) Started\n" " WebSite (ocf::heartbeat:apache) Stopped\n" " Master/Slave Set: WebDataClone [WebData]\n" " Masters: [ pcmk-2 ]\n" " Slaves: [ pcmk-1 ]\n" " WebFS (ocf::heartbeat:Filesystem) Stopped" msgstr "" #. Tag: para #, no-c-format msgid "Note that both Apache and WebFS have been stopped." msgstr "Notare come sia Apache che WebFS sono stati fermati." #. Tag: title #, no-c-format msgid "Create and Populate an GFS2 Partition" msgstr "Creazione e popolamento della partizione GFS2" #. Tag: para #, no-c-format msgid "Now that the cluster stack and integration pieces are running smoothly, we can create an GFS2 partition." msgstr "Ora che il cluster e le sue parti stanno funzionando senza problemi, è possibile creare la partizione GFS2." #. Tag: para #, no-c-format msgid "This will erase all previous content stored on the DRBD device. Ensure you have a copy of any important data." msgstr "Questa operazione cancellerà qualsiasi contenuto sul device DRBD. Assicurarsi quindi di avere una copia di qualsiasi dato cruciale." #. Tag: para #, no-c-format msgid "We need to specify a number of additional parameters when creating a GFS2 partition." msgstr "Nella creazione di una partizione GFS2 è necessario specificare diversi parametri aggiuntivi." #. Tag: para #, no-c-format msgid "First we must use the -p option to specify that we want to use the the Kernel’s DLM. Next we use -j to indicate that it should reserve enough space for two journals (one per node accessing the filesystem)." msgstr "Per cominciare, va utilizzata l'opzione -p per specificare la volontà di utilizzare il DLM del Kernel. Proseguendo, l'opzione -j indica che la risorsa dovrà riservare abbastanza spazio per due journal (uno per ogni nodo che accede al filesystem)." #. Tag: para #, no-c-format msgid "Lastly, we use -t to specify the lock table name. The format for this field is clustername:fsname. For the fsname, we need to use the same value as specified in corosync.conf for cluster_name. If you setup corosync with the same cluster name we used in this tutorial, cluster name will be mycluster. If you are unsure what your cluster name is, open up /etc/corosync/corosync.conf, or execute the command pcs cluster corosync pcmk-1 to view the corosync config. The cluster name will be in the totem block." msgstr "" #. Tag: para #, no-c-format msgid "We must run the next command on whichever node last had /dev/drbd mounted. Otherwise you will receive the message:" msgstr "" #. Tag: screen #, no-c-format msgid "/dev/drbd1: Read-only file system" msgstr "" #. Tag: programlisting #, no-c-format msgid "" "# ssh pcmk-2 -- mkfs.gfs2 -p lock_dlm -j 2 -t mycluster:web /dev/drbd1\n" "This will destroy any data on /dev/drbd1.\n" "It appears to contain: Linux rev 1.0 ext4 filesystem data, UUID=dc45fff3-c47a-4db2-96f7-a8049a323fe4 (extents) (large files) (huge files)\n" "Are you sure you want to proceed? [y/n]y\n" "Device: /dev/drbd1\n" "Blocksize: 4096\n" "Device Size 0.97 GB (253935 blocks)\n" "Filesystem Size: 0.97 GB (253932 blocks)\n" "Journals: 2\n" "Resource Groups: 4\n" "Locking Protocol: \"lock_dlm\"\n" "Lock Table: \"mycluster\"\n" "UUID: ed293a02-9eee-3fa3-ed1c-435ef1fd0116" msgstr "" #. Tag: programlisting #, no-c-format msgid "" "# pcs cluster cib dlm_cfg\n" "# pcs -f dlm_cfg resource create dlm ocf:pacemaker:controld op monitor interval=60s\n" "# pcs -f dlm_cfg resource clone dlm clone-max=2 clone-node-max=1\n" "# pcs -f dlm_cfg resource show\n" " ClusterIP (ocf::heartbeat:IPaddr2) Started\n" " WebSite (ocf::heartbeat:apache) Stopped\n" " Master/Slave Set: WebDataClone [WebData]\n" " Masters: [ pcmk-2 ]\n" " Slaves: [ pcmk-1 ]\n" " WebFS (ocf::heartbeat:Filesystem) Stopped\n" " Clone Set: dlm-clone [dlm]\n" " Stopped: [ dlm:0 dlm:1 ]\n" "# pcs cluster push cib dlm_cfg\n" "CIB updated\n" "# pcs status\n" "\n" "Last updated: Fri Sep 14 12:54:50 2012\n" "Last change: Fri Sep 14 12:54:43 2012 via cibadmin on pcmk-1\n" "Stack: corosync\n" "Current DC: pcmk-1 (1) - partition with quorum\n" "Version: 1.1.8-1.el7-60a19ed12fdb4d5c6a6b6767f52e5391e447fec0\n" "2 Nodes configured, unknown expected votes\n" "7 Resources configured.\n" "\n" "Online: [ pcmk-1 pcmk-2 ]\n" "\n" "Full list of resources:\n" "\n" " ClusterIP (ocf::heartbeat:IPaddr2): Started pcmk-2\n" " WebSite (ocf::heartbeat:apache): Stopped\n" " Master/Slave Set: WebDataClone [WebData]\n" " Masters: [ pcmk-2 ]\n" " Slaves: [ pcmk-1 ]\n" " WebFS (ocf::heartbeat:Filesystem): Stopped\n" " Clone Set: dlm-clone [dlm]\n" " Started: [ pcmk-1 pcmk-2 ]" msgstr "" #. Tag: para #, no-c-format msgid "Then (re)populate the new filesystem with data (web pages). For now we’ll create another variation on our home page." msgstr "A questo punto è possibile ripopolare il nuovo filesystem con i dati (le pagine web). Per ora verrà creata una versione alternativa dell'home page." #. Tag: programlisting #, no-c-format msgid "" "# mount /dev/drbd1 /mnt/\n" "# cat <<-END >/mnt/index.html\n" "<html>\n" "<body>My Test Site - GFS2</body>\n" "</html>\n" "END\n" "# umount /dev/drbd1\n" "# drbdadm verify wwwdata#" msgstr "" #. Tag: title #, no-c-format msgid "Reconfigure the Cluster for GFS2" msgstr "Riconfigurare il cluster per GFS2" #. Tag: para #, no-c-format msgid "With the WebFS resource stopped, lets update the configuration." msgstr "" #. Tag: programlisting #, no-c-format msgid "" "# pcs resource show WebFS\n" "Resource: WebFS\n" " device: /dev/drbd/by-res/wwwdata\n" " directory: /var/www/html\n" " fstype: ext4\n" " target-role: Stopped" msgstr "" #. Tag: para #, no-c-format msgid "The fstype option needs to be updated to gfs2 instead of ext4." msgstr "" #. Tag: programlisting #, no-c-format msgid "" "# pcs resource update WebFS fstype=gfs2\n" "# pcs resource show WebFS\n" "Resource: WebFS\n" " device: /dev/drbd/by-res/wwwdata\n" " directory: /var/www/html\n" " fstype: gfs2\n" " target-role: Stopped\n" "CIB updated" msgstr "" #. Tag: title #, no-c-format msgid "Reconfigure Pacemaker for Active/Active" msgstr "Riconfigurare Pacemaker per l'Active/Active" #. Tag: para #, no-c-format msgid "Almost everything is in place. Recent versions of DRBD are capable of operating in Primary/Primary mode and the filesystem we’re using is cluster aware. All we need to do now is reconfigure the cluster to take advantage of this." msgstr "Quasi tutto è a posto. Le versioni recenti di DRBD supportano l'operare in modalità Primary/Primary ed inoltre il filesystem utilizzato è cluster aware. Tutto ciò che rimane da fare è configurare nuovamente il cluster per sfruttare queste peculiarità." #. Tag: para #, fuzzy, no-c-format msgid "This will involve a number of changes, so we’ll want work with a local cib file." msgstr "Questo richiederà diversi cambiamenti, pertanto verrà utilizzata ancora una volta la modalità interattiva." #. Tag: programlisting #, no-c-format msgid "# pcs cluster cib active_cfg" msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "There’s no point making the services active on both locations if we can’t reach them, so lets first clone the IP address. Cloned IPaddr2 resources use an iptables rule to ensure that each request only gets processed by one of the two clone instances. The additional meta options tell the cluster how many instances of the clone we want (one \"request bucket\" for each node) and that if all other nodes fail, then the remaining node should hold all of them. Otherwise the requests would be simply discarded." msgstr "Non ha senso rendere i servizi attivi in entrambi i posti se questi non possono essere utilizzati, quindi per prima cosa va clonato l'indirizzo IP. Le risorse IPaddr2 clonate utilizzano una regola iptables per assicurarsi che ogni richiesta venga processato da solamente una delle due istanze clonate. Le meta opzioni addizionali indicano al cluster quante istanze del clone sono necessarie (una \"request bucket\" per ciascun nodo) e come queste debbano essere gestite tutte dal nodo rimanente in caso di fallimento di tutti gli altri. In caso contrario le richieste verranno semplicemente scartate." #. Tag: screen #, no-c-format msgid "" "# pcs -f active_cfg resource clone ClusterIP \\\n" " globally-unique=true clone-max=2 clone-node-max=2" msgstr "" #. Tag: para #, no-c-format msgid "Notice when the ClusterIP becomes a clone, the constraints referencing ClusterIP now reference the clone. This is done automatically by pcs." msgstr "" #. Tag: programlisting #, no-c-format msgid "" "# pcs -f active_cfg constraint\n" "Location Constraints:\n" "Ordering Constraints:\n" " start ClusterIP-clone then start WebSite\n" " WebFS then WebSite\n" " promote WebDataClone then start WebFS\n" "Colocation Constraints:\n" " WebSite with ClusterIP-clone\n" " WebFS with WebDataClone (with-rsc-role:Master)\n" " WebSite with WebFS" msgstr "" #. Tag: para #, no-c-format msgid "Now we must tell the ClusterIP how to decide which requests are processed by which hosts. To do this we must specify the clusterip_hash parameter." msgstr "Ora bisogna indicare a ClusterIP come decidere quali richieste sono processate e da quali host. Per fare ciò è necessario definire il parametro clusterip_hash." #. Tag: programlisting #, no-c-format msgid "# pcs -f active_cfg resource update ClusterIP clusterip_hash=sourceip" msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "Next we need to convert the filesystem and Apache resources into clones." msgstr "A questo punto è necessario convertire le risorse filesystem ed Apache in cloni. Di nuovo, la shell aggiornerà automaticamente ogni constraint interessata." #. Tag: para #, no-c-format msgid "Notice how pcs automatically updates the relevant constraints again." msgstr "" #. Tag: programlisting #, no-c-format msgid "" "# pcs -f active_cfg resource clone WebFS\n" "# pcs -f active_cfg resource clone WebSite\n" "# pcs -f active_cfg constraint\n" "Location Constraints:\n" "Ordering Constraints:\n" " start ClusterIP-clone then start WebSite-clone\n" " WebFS-clone then WebSite-clone\n" " promote WebDataClone then start WebFS-clone\n" "Colocation Constraints:\n" " WebSite-clone with ClusterIP-clone\n" " WebFS-clone with WebDataClone (with-rsc-role:Master)\n" " WebSite-clone with WebFS-clone" msgstr "" #. Tag: para #, no-c-format msgid "The last step is to tell the cluster that it is now allowed to promote both instances to be Primary (aka. Master)." msgstr "L'ultimo passo è quello di comunicare al cluster che ora è consentito promuovere entrambe le istanze a PRimary (o Master)." #. Tag: programlisting #, no-c-format msgid "# pcs -f active_cfg resource update WebDataClone master-max=2" msgstr "" #. Tag: para #, no-c-format msgid "Review the configuration before uploading it to the cluster, quitting the shell and watching the cluster’s response" msgstr "Prima di caricare la configurazione nel cluster questa va revisionata, la shell andrà terminata e si dovrà osservare il responso del cluster" #. Tag: programlisting #, no-c-format msgid "" "# pcs cluster push cib active_cfg\n" "# pcs resource start WebFS" msgstr "" #. Tag: para #, no-c-format msgid "After all the processes are started the status should look similar to this." msgstr "" #. Tag: programlisting #, no-c-format msgid "" "# pcs resource\n" " Master/Slave Set: WebDataClone [WebData]\n" " Masters: [ pcmk-2 pcmk-1 ]\n" " Clone Set: dlm-clone [dlm]\n" " Started: [ pcmk-2 pcmk-1 ]\n" " Clone Set: ClusterIP-clone [ClusterIP] (unique)\n" " ClusterIP:0 (ocf::heartbeat:IPaddr2) Started\n" " ClusterIP:1 (ocf::heartbeat:IPaddr2) Started\n" " Clone Set: WebFS-clone [WebFS]\n" " Started: [ pcmk-1 pcmk-2 ]\n" " Clone Set: WebSite-clone [WebSite]\n" " Started: [ pcmk-1 pcmk-2 ]" msgstr "" #. Tag: title #, no-c-format msgid "Testing Recovery" msgstr "Testare il recovery" #. Tag: para #, no-c-format msgid "TODO: Put one node into standby to demonstrate failover" msgstr "TODO: mettere un nodo in standby per dimostrare il failover" #~ msgid "Install a Cluster Filesystem - GFS2" #~ msgstr "Installare un cluster filesystem - GFS2" #~ msgid "The first thing to do is install gfs2-utils on each machine." #~ msgstr "La prima cosa da fare è quella di installare il pacchetto gfs2-utils su ciascuna macchina." #~ msgid "Setup Pacemaker-GFS2 Integration" #~ msgstr "Configurare l'integrazione fra Pacemaker e GFS2" #~ msgid "GFS2 needs two services to be running, the first is the user-space interface to the kernel’s distributed lock manager (DLM). The DLM is used to co-ordinate which node(s) can access a given file (and when) and integrates with Pacemaker to obtain node membership The list of nodes the cluster considers to be available information and fencing capabilities." #~ msgstr "GFS2 necessita di due servizi attivi, il primo è l'interfaccia user-space al distribuited lock manager (DLM) del kernel. DLM è utilizzato per regolare quale/i nodo/i possono accedere a determinati file (e quando) e si integra con Pacemaker per ottenere informazioni sulla membership del nodo L'elenco dei nodi che il cluster ritiene essere disponibili ed il supporto al fencing." #~ msgid "The second service is GFS2’s own control daemon which also integrates with Pacemaker to obtain node membership data." #~ msgstr "Il secondo servizio è il demone di controllo di GFS2, che si integra a sua volta con Pacemaker per ottenere i dati di membership dei nodi." #~ msgid "Add the DLM service" #~ msgstr "Aggiunta del servizio DLM" #~ msgid "The DLM control daemon needs to run on all active cluster nodes, so we will use the shells interactive mode to create a cloned resource." #~ msgstr "Il demone di controllo DLM deve funzionare su tutti i nodi attivi del cluster, quindi verrà utilizzata la modalità interattiva della shell per creare una risorsa clonata." #~ msgid "TODO: Explain the meaning of the interleave option" #~ msgstr "TODO: Spiegare il significato dell'opzione interleave" #~ msgid "Add the GFS2 service" #~ msgstr "Aggiunta del servizio GFS2" #~ msgid "Once the DLM is active, we can add the GFS2 control daemon." #~ msgstr "Una volta che il DLM è attivo, è possibile aggiungere il demone di controllo GFS2." #~ msgid "Use the crm shell to create the gfs-control cluster resource:" #~ msgstr "La risorsa gfs-control viene creata utilizzando la shell crm: " #~ msgid "Now ensure Pacemaker only starts the gfs-control service on nodes that also have a copy of the dlm service (created above) already running" #~ msgstr "A questo punto bisogna assicurarsi che Pacemaker avvii il servizio gfs-control sui nodi che erogano una copia del servizio dlm (creato in precedenza) funzionante." #~ msgid "Lastly, we use -t to specify the lock table name. The format for this field is clustername:fsname. For the fsname, we just need to pick something unique and descriptive and since we haven’t specified a clustername yet, we will use the default (pcmk)." #~ msgstr "Infine verrà utilizzato -t per specificare il nome della lock table. Il formato di questo campo è clustername:fsname. Per fsname è sufficiente scegliere un nome unico e descrittivo e dato che non è stato specificato ancora clustername è possibile usare il default (pcmk)." #~ msgid "To specify an alternate name for the cluster, locate the service section containing “name: pacemaker” in corosync.conf and insert the following line anywhere inside the block:" #~ msgstr "Per specificare un nome alternativo per il cluster è necessario localizzare la sezione del servizio che contiene \"name: pacemaker\" nel file corosync.conf, inserendo la seguente linea in qualsiasi posizione del blocco:" #~ msgid "Do this on each node in the cluster and be sure to restart them before continuing." #~ msgstr "Questa operazione andrà eseguita in ciascun nodo, accertandosi di effettuare un restart dello stesso prima di continuare." #~ msgid "Now that we’ve recreated the resource, we also need to recreate all the constraints that used it. This is because the shell will automatically remove any constraints that referenced WebFS." #~ msgstr "Ora che abbiamo creato nuovamente la risorsa è possibile ricreare tutte le constraint che questa utilizzava. Questo perché la shell rimuoverà automaticamente qualsiasi constraint che riferisca a WebFS." #~ msgid "Open the ClusterIP resource" #~ msgstr "Aprire la risorsa ClusterIP" #~ msgid "And add the following to the params line" #~ msgstr "ed aggiungere il seguente testo alla linea dei parametri" #~ msgid "So that the complete definition looks like:" #~ msgstr "In modo che la definizione completa sia simile alla seguente:" #~ msgid "Here is the full transcript" #~ msgstr "Questa è la trascrizione completa" #~ msgid "Notice how any constraints that referenced ClusterIP have been updated to use WebIP instead. This is an additional benefit of using the crm shell." #~ msgstr "Notare come qualsiasi constraint riferita a ClusterIP sia stata aggiornata per utilizzare invece WebIP. Questo è un vantaggio aggiuntivo nell'utilizzo della shell crm." #~ msgid "Change master-max to 2" #~ msgstr "Cambiare master-max a 2" pacemaker-master/doc/Clusters_from_Scratch/it-IT/Ch-Active-Passive.po000066400000000000000000000545361217637305600260320ustar00rootroot00000000000000# # AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: 0\n" "POT-Creation-Date: 2012-10-17T05:19:03\n" "PO-Revision-Date: 2010-08-02 17:19+0100\n" "Last-Translator: RaSca \n" "Language-Team: None\n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. Tag: title #, no-c-format msgid "Creating an Active/Passive Cluster" msgstr "Creare un cluster Active/Passive" #. Tag: title #, no-c-format msgid "Exploring the Existing Configuration" msgstr "Esplorare la configurazione esistente" #. Tag: para #, no-c-format msgid "When Pacemaker starts up, it automatically records the number and details of the nodes in the cluster as well as which stack is being used and the version of Pacemaker being used." msgstr "Quando Pacemaker viene avviato automatica registra il numero ed i dettagli dei nodi nel cluster, così come lo stack è utilizzato e la versione di Pacemaker utilizzata." #. Tag: para #, no-c-format msgid "This is what the base configuration should look like." msgstr "Ecco come dovrebbe apparire la configurazione base." #. Tag: programlisting #, no-c-format msgid "" "# pcs status\n" "Last updated: Fri Sep 14 10:12:01 2012\n" "Last change: Fri Sep 14 09:51:55 2012 via crmd on pcmk-2\n" "Stack: corosync\n" "Current DC: pcmk-1 (1) - partition with quorum\n" "Version: 1.1.8-1.el7-60a19ed12fdb4d5c6a6b6767f52e5391e447fec0\n" "2 Nodes configured, unknown expected votes\n" "0 Resources configured.\n" "\n" "Online: [ pcmk-1 pcmk-2 ]\n" "\n" "Full list of resources:" msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "For those that are not of afraid of XML, you can see the raw cluster configuration and status by using the pcs cluster cib command." msgstr "Per quanti non sono spaventati da XML è possibile visualizzare la configurazione raw aggiungenfo \"xml\" al comando precedente." #. Tag: title #, no-c-format msgid "The last XML you’ll see in this document" msgstr "Questo è l'ultimo XML ad essere utilizzato nel documento." #. Tag: programlisting #, no-c-format msgid "# pcs cluster cib" msgstr "" #. Tag: programlisting #, no-c-format msgid "" "<cib epoch=\"4\" num_updates=\"19\" admin_epoch=\"0\" validate-with=\"pacemaker-1.2\" crm_feature_set=\"3.0.6\" update-origin=\"pcmk-1\" update-client=\"crmd\" cib-last-written=\"Wed Aug 1 16:08:52 2012\" have-quorum=\"1\" dc-uuid=\"1\">\n" " <configuration>\n" " <crm_config>\n" " <cluster_property_set id=\"cib-bootstrap-options\">\n" " <nvpair id=\"cib-bootstrap-options-dc-version\" name=\"dc-version\" value=\"1.1.8-1.el7-60a19ed12fdb4d5c6a6b6767f52e5391e447fec0\"/>\n" " <nvpair id=\"cib-bootstrap-options-cluster-infrastructure\" name=\"cluster-infrastructure\" value=\"corosync\"/>\n" " </cluster_property_set>\n" " </crm_config>\n" " <nodes>\n" " <node id=\"1\" uname=\"pcmk-1\" type=\"normal\"/>\n" " <node id=\"2\" uname=\"pcmk-2\" type=\"normal\"/>\n" " </nodes>\n" " <resources/>\n" " <constraints/>\n" " </configuration>\n" " <status>\n" " <node_state id=\"2\" uname=\"pcmk-2\" ha=\"active\" in_ccm=\"true\" crmd=\"online\" join=\"member\" expected=\"member\" crm-debug-origin=\"do_state_transition\" shutdown=\"0\">\n" " <lrm id=\"2\">\n" " <lrm_resources/>\n" " </lrm>\n" " <transient_attributes id=\"2\">\n" " <instance_attributes id=\"status-2\">\n" " <nvpair id=\"status-2-probe_complete\" name=\"probe_complete\" value=\"true\"/>\n" " </instance_attributes>\n" " </transient_attributes>\n" " </node_state>\n" " <node_state id=\"1\" uname=\"pcmk-1\" ha=\"active\" in_ccm=\"true\" crmd=\"online\" join=\"member\" expected=\"member\" crm-debug-origin=\"do_state_transition\" shutdown=\"0\">\n" " <lrm id=\"1\">\n" " <lrm_resources/>\n" " </lrm>\n" " <transient_attributes id=\"1\">\n" " <instance_attributes id=\"status-1\">\n" " <nvpair id=\"status-1-probe_complete\" name=\"probe_complete\" value=\"true\"/>\n" " </instance_attributes>\n" " </transient_attributes>\n" " </node_state>\n" " </status>\n" "</cib>" msgstr "" #. Tag: para #, no-c-format msgid "Before we make any changes, its a good idea to check the validity of the configuration." msgstr "Prima di effettuare qualsiasi cambiamento è buona norma controllare la validità della configurazione." #. Tag: programlisting #, no-c-format msgid "" "# crm_verify -L -V\n" " error: unpack_resources: Resource start-up disabled since no STONITH resources have been defined\n" " error: unpack_resources: Either configure some or disable STONITH with the stonith-enabled option\n" " error: unpack_resources: NOTE: Clusters with shared data need STONITH to ensure data integrity\n" "Errors found during check: config not valid\n" " -V may provide more details" msgstr "" #. Tag: para #, no-c-format msgid "As you can see, the tool has found some errors." msgstr "Come si può notare il tool ha trovato qualche errore." #. Tag: para #, fuzzy, no-c-format msgid "In order to guarantee the safety of your data If the data is corrupt, there is little point in continuing to make it available , the default for STONITH A common node fencing mechanism. Used to ensure data integrity by powering off \"bad\" nodes in Pacemaker is enabled. However it also knows when no STONITH configuration has been supplied and reports this as a problem (since the cluster would not be able to make progress if a situation requiring node fencing arose)." msgstr "Al fine di garantire la sicurezza dei propri dati Se il dato è corrotto, ha poco senso renderlo ancora disponibile Pacemaker supporta STONITH un meccanismo comune di fencing del nodo utilizzato per assicurare l'integrità dei dati attraverso lo spegnimento dei nodi \"cattivi\". . In ogni caso Pacemaker è conscio quando nessuna configurazione STONITH è stata implementata e riporta questo come un problema (questo perché il cluster non sarà in grado di fare progressi in situazioni in cui vi è necessità di fencing di nodi)." #. Tag: para #, no-c-format msgid "For now, we will disable this feature and configure it later in the Configuring STONITH section. It is important to note that the use of STONITH is highly encouraged, turning it off tells the cluster to simply pretend that failed nodes are safely powered off. Some vendors will even refuse to support clusters that have it disabled." msgstr "Per adesso la funzionalità verrà disabilitata e configurata in seguito nella sezione Configurare STONITH. E' importante notare che l'uso di STONITH è altamente consigliato, disabilitarlo indica al cluster di dare per scontato che i nodi falliti vengano spenti. Alcuni rivenditori potrebbero rifiutarsi di supportare cluster che hanno STONITH disabilitato." #. Tag: para #, fuzzy, no-c-format msgid "To disable STONITH, we set the stonith-enabled cluster option to false." msgstr "Per disabilitare STONITH è necessario impostare l'opzione stonith-enabled a false." #. Tag: programlisting #, no-c-format msgid "" "# pcs property set stonith-enabled=false\n" "# crm_verify -L" msgstr "" #. Tag: para #, no-c-format msgid "With the new cluster option set, the configuration is now valid." msgstr "Con la nuova opzione impostata la configurazione del cluster è ora valida." #. Tag: para #, no-c-format msgid "The use of stonith-enabled=false is completely inappropriate for a production cluster. We use it here to defer the discussion of its configuration which can differ widely from one installation to the next. See for information on why STONITH is important and details on how to configure it." msgstr "" #. Tag: title #, no-c-format msgid "Adding a Resource" msgstr "Aggiungere una risorsa" #. Tag: para #, fuzzy, no-c-format msgid "The first thing we should do is configure an IP address. Regardless of where the cluster service(s) are running, we need a consistent address to contact them on. Here I will choose and add 192.168.122.120 as the floating address, give it the imaginative name ClusterIP and tell the cluster to check that its running every 30 seconds." msgstr "La prima cosa da fare è configurare un indirizzo IP. Indipendentemente da dove i servizi cluster stanno funzionando è necessario un indirizzo per raggiungerli. Verrà scelto ed aggiunto 192.168.122.101 come indirizzo virtuale, con il nome di ClusterIP e verrà indicato al cluster di controllarlo ogni 30 secondi." #. Tag: para #, no-c-format msgid "The chosen address must not be one already associated with a physical node" msgstr "L'indirizzo scelto non dovrà essere già associato ad un nodo fisico" #. Tag: screen #, no-c-format msgid "" "# pcs resource create ClusterIP ocf:heartbeat:IPaddr2 \\\n" " ip=192.168.0.120 cidr_netmask=32 op monitor interval=30s" msgstr "" #. Tag: para #, no-c-format msgid "The other important piece of information here is ocf:heartbeat:IPaddr2." msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "This tells Pacemaker three things about the resource you want to add. The first field, ocf, is the standard to which the resource script conforms to and where to find it. The second field is specific to OCF resources and tells the cluster which namespace to find the resource script in, in this case heartbeat. The last field indicates the name of the resource script." msgstr "L'altra informazione presentata qui è ocf:heartbeat:IPaddr2. Esso comunica a Pacemaker tre informazioni in merito alla risorsa che viene aggiunta. Il primo campo, ocf, indica lo standard a cui lo script della risorsa si conforma e dove trovarlo. Il secondo campo è specifico delle risorse OCF e indica al cluster in quale namespace trovare lo script, in questo caso heartbeat. L'ultimo campo indica il nome dello script della risorsa." #. Tag: para #, fuzzy, no-c-format msgid "To obtain a list of the available resource standards (the ocf part of ocf:heartbeat:IPaddr2), run" msgstr "Per ottenere una lista delle classi di risorse disponibili, lanciare" #. Tag: programlisting #, no-c-format msgid "" "# pcs resource standards\n" "ocf\n" "lsb\n" "service\n" "systemd\n" "stonith" msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "To obtain a list of the available ocf resource providers (the heartbeat part of ocf:heartbeat:IPaddr2), run" msgstr "Per ottenere una lista delle classi di risorse disponibili, lanciare" #. Tag: programlisting #, no-c-format msgid "" "# pcs resource providers\n" "heartbeat\n" "linbit\n" "pacemaker\n" "redhat" msgstr "" #. Tag: para #, no-c-format msgid "Finally, if you want to see all the resource agents available for a specific ocf provider (the IPaddr2 part of ocf:heartbeat:IPaddr2), run" msgstr "" #. Tag: programlisting #, no-c-format msgid "" "# pcs resource agents ocf:heartbeat\n" "AoEtarget\n" "AudibleAlarm\n" "CTDB\n" "ClusterMon\n" "Delay\n" "Dummy\n" ".\n" ". (skipping lots of resources to save space)\n" ".\n" "IPaddr2\n" ".\n" ".\n" ".\n" "symlink\n" "syslog-ng\n" "tomcat\n" "vmware" msgstr "" #. Tag: para #, no-c-format msgid "Now verify that the IP resource has been added and display the cluster’s status to see that it is now active." msgstr "A questo punto va verificato come la risorsa IP sia stata aggiunta e visualizzato lo stato del cluster per vedere che ora è attiva." #. Tag: programlisting #, no-c-format msgid "" "# pcs status\n" "\n" "Last updated: Fri Sep 14 10:17:00 2012\n" "Last change: Fri Sep 14 10:15:48 2012 via cibadmin on pcmk-1\n" "Stack: corosync\n" "Current DC: pcmk-1 (1) - partition with quorum\n" "Version: 1.1.8-1.el7-60a19ed12fdb4d5c6a6b6767f52e5391e447fec0\n" "2 Nodes configured, unknown expected votes\n" "1 Resources configured.\n" "\n" "Online: [ pcmk-1 pcmk-2 ]\n" "\n" "Full list of resources:\n" "\n" " ClusterIP (ocf::heartbeat:IPaddr2): Started pcmk-1" msgstr "" #. Tag: title #, no-c-format msgid "Perform a Failover" msgstr "Effettuare un Failover" #. Tag: para #, no-c-format msgid "Being a high-availability cluster, we should test failover of our new resource before moving on." msgstr "Trattandosi di un cluster ad alta-affidabilità, è necessario testare il failover della nostra nuova risorsa prima di proseguire." #. Tag: para #, no-c-format msgid "First, find the node on which the IP address is running." msgstr "Per prima cosa va identificato da quale nodo l'indirizzo IP è erogato" #. Tag: para #, fuzzy, no-c-format msgid "Shut down Pacemaker and Corosync on that machine." msgstr "Spegnere Corosync su questa macchina" #. Tag: programlisting #, no-c-format msgid "" "#pcs cluster stop pcmk-1\n" "Stopping Cluster..." msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "Once Corosync is no longer running, go to the other node and check the cluster status." msgstr "Una volta che Corosync non sta più funzionando, è possibile verificare sull'altro nodo lo stato del cluster attraverso crm_mon." #. Tag: programlisting #, no-c-format msgid "" "# pcs status\n" "\n" "Last updated: Fri Sep 14 10:31:01 2012\n" "Last change: Fri Sep 14 10:15:48 2012 via cibadmin on pcmk-1\n" "Stack: corosync\n" "Current DC: pcmk-2 (2) - partition WITHOUT quorum\n" "Version: 1.1.8-1.el7-60a19ed12fdb4d5c6a6b6767f52e5391e447fec0\n" "2 Nodes configured, unknown expected votes\n" "1 Resources configured.\n" "\n" "Online: [ pcmk-2 ]\n" "OFFLINE: [ pcmk-1 ]\n" "\n" "Full list of resources:\n" "\n" " ClusterIP (ocf::heartbeat:IPaddr2): Stopped" msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "There are three things to notice about the cluster’s current state. The first is that, as expected, pcmk-1 is now offline. However we can also see that ClusterIP isn’t running anywhere!" msgstr "Ci sono tre cose da evidenziare in merito all'attuale stato del cluster. La prima è che, come aspettato, pcmk-1 è ora offline. Ad ogni modo è possibile anche notare come ClusterIP non sta funzionando da nessuna parte!" #. Tag: title #, no-c-format msgid "Quorum and Two-Node Clusters" msgstr "Quorum e Cluster a due nodi" #. Tag: para #, fuzzy, no-c-format msgid "This is because the cluster no longer has quorum, as can be seen by the text \"partition WITHOUT quorum\" in the status output. In order to reduce the possibility of data corruption, Pacemaker’s default behavior is to stop all resources if the cluster does not have quorum." msgstr "Questo accade perché il cluster non ha più un quorum, come si può notare dalla scritta \"partition WITHOUT quorum\" (evidenziato in verde) nell'output mostrato. Il comportamento di default di Pacemaker nel caso in cui il cluster non abbia un quorum, al fine di ridurre la possibilità di corruzione di dati, prevede lo stop di tutte le risorse." #. Tag: para #, no-c-format msgid "A cluster is said to have quorum when more than half the known or expected nodes are online, or for the mathematically inclined, whenever the following equation is true:" msgstr "Un cluster viene definito con quorum quando più della metà dei nodi conosciuti o aspettati sono online o, attraverso la matematica, quando la seguente equazione è vera:" #. Tag: literallayout #, no-c-format msgid "total_nodes < 2 * active_nodes" msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "Therefore a two-node cluster only has quorum when both nodes are running, which is no longer the case for our cluster. This would normally make the creation of a two-node cluster pointless Actually some would argue that two-node clusters are always pointless, but that is an argument for another time , however it is possible to control how Pacemaker behaves when quorum is lost. In particular, we can tell the cluster to simply ignore quorum altogether." msgstr "Pertanto, un cluster a due nodi ha quorum solo quando entrambi i nodi sono in esecuzione, e questo non è più il caso del cluster d'esempio. Questo normalmente renderebbe la creazione di cluster a due nodi inutile Attualmente molti potrebbero puntualizzare che i cluster a due nodi sono sempre inutili, ma questo è argomento di future discussioni. , ad ogni modo è possibile controllare come Pacemaker gestisce la perdita di quorum. In particolare è possibile indicare al cluster di ignorare semplicemente l'assenza di quorum. " #. Tag: programlisting #, no-c-format msgid "" "# pcs property set no-quorum-policy=ignore\n" "# pcs property\n" "dc-version: 1.1.8-1.el7-60a19ed12fdb4d5c6a6b6767f52e5391e447fec0\n" "cluster-infrastructure: corosync\n" "stonith-enabled: false\n" "no-quorum-policy: ignore" msgstr "" #. Tag: para #, no-c-format msgid "After a few moments, the cluster will start the IP address on the remaining node. Note that the cluster still does not have quorum." msgstr "Dopo alcuni istanti il cluster avvierà l'indirizzo IP sui nodi rimanenti. E' da notare che il cluster non ha comunque il quorum." #. Tag: programlisting #, no-c-format msgid "" "# pcs status\n" "Last updated: Fri Sep 14 10:38:11 2012\n" "Last change: Fri Sep 14 10:37:53 2012 via cibadmin on pcmk-2\n" "Stack: corosync\n" "Current DC: pcmk-2 (2) - partition WITHOUT quorum\n" "Version: 1.1.8-1.el7-60a19ed12fdb4d5c6a6b6767f52e5391e447fec0\n" "2 Nodes configured, unknown expected votes\n" "1 Resources configured.\n" "\n" "Online: [ pcmk-2 ]\n" "OFFLINE: [ pcmk-1 ]\n" "\n" "Full list of resources:\n" "\n" " ClusterIP (ocf::heartbeat:IPaddr2): Started pcmk-2" msgstr "" #. Tag: para #, no-c-format msgid "Now simulate node recovery by restarting the cluster stack on pcmk-1 and check the cluster’s status. Note, if you get an authentication error with the pcs cluster start pcmk-1 command, you must authenticate on the node using the pcs cluster auth pcmk pcmk-1 pcmk-2 command discussed earlier." msgstr "" #. Tag: programlisting #, no-c-format msgid "" "# pcs cluster start pcmk-1\n" "Starting Cluster...\n" "# pcs status\n" "\n" "Last updated: Fri Sep 14 10:42:56 2012\n" "Last change: Fri Sep 14 10:37:53 2012 via cibadmin on pcmk-2\n" "Stack: corosync\n" "Current DC: pcmk-2 (2) - partition with quorum\n" "Version: 1.1.8-1.el7-60a19ed12fdb4d5c6a6b6767f52e5391e447fec0\n" "2 Nodes configured, unknown expected votes\n" "1 Resources configured.\n" "\n" "Online: [ pcmk-1 pcmk-2 ]\n" "\n" "Full list of resources:\n" "\n" " ClusterIP (ocf::heartbeat:IPaddr2): Started pcmk-2" msgstr "" #. Tag: para #, no-c-format msgid "In the dark days, the cluster may have moved the IP back to its original location (pcmk-1). Usually this is no longer the case." msgstr "" #. Tag: title #, no-c-format msgid "Prevent Resources from Moving after Recovery" msgstr "Evitare che le risorse si muovano dopo il recovery" #. Tag: para #, fuzzy, no-c-format msgid "In most circumstances, it is highly desirable to prevent healthy resources from being moved around the cluster. Moving resources almost always requires a period of downtime. For complex services like Oracle databases, this period can be quite long." msgstr "In alcune circostanze è altamente desiderabile prevenire che risorse sane vengano mosse nel cluster. Lo spostamento delle risorse richiede in genere un periodo di downtime e per servizi complessi, come i database Oracle, tale periodo può essere piuttosto lungo." #. Tag: para #, fuzzy, no-c-format msgid "To address this, Pacemaker has the concept of resource stickiness which controls how much a service prefers to stay running where it is. You may like to think of it as the \"cost\" of any downtime. By default, Pacemaker assumes there is zero cost associated with moving resources and will do so to achieve \"optimal\" It should be noted that Pacemaker’s definition of optimal may not always agree with that of a human’s. The order in which Pacemaker processes lists of resources and nodes creates implicit preferences in situations where the administrator has not explicitly specified them resource placement. We can specify a different stickiness for every resource, but it is often sufficient to change the default." msgstr "Per ovviare a questo Pacemaker possiede il concetto di resource stickiness, che controlla quanto un servizio preferisca rimanere dov'è. E' possibile associare il concetto al \"costo\" di ogni downtime. Pacemaker assume di default che non ci sia costo associato allo spostamento di una risorsa, questo per garantire un piazzamento delle risorse \"ottimale Va sottolineato che la definizione \"ottimale\" di Pacemaker potrebbe non sempre concordare con quella umana. L'ordine con cui Pacemaker processa la lista delle risorse e dei nodi crea preferenze implicite (richieste per creare soluzioni stabili) in situazioni dove l'amministratore non ha esplicitamente specificato qualcosa. ”. E' possibile specificare stickiness differenti per ogni risorsa, ma generalmente è sufficiente modificare il valore di default." #. Tag: programlisting #, no-c-format msgid "" "# pcs resource rsc defaults resource-stickiness=100\n" "# pcs resource rsc defaults\n" "resource-stickiness: 100" msgstr "" #~ msgid "To then find all the OCF resource agents provided by Pacemaker and Heartbeat, run" #~ msgstr "Per poi trovare tutte i resource agent OCF disponibili con Pacemaker ed Heartbeat, lanciare" #~ msgid "Now simulate node recovery by restarting the cluster stack on pcmk-1 and check the cluster’s status." #~ msgstr "Viene quindi simulato il recovery del nodo attraverso il riavvio dello stack cluster su pcmk-1 ed il controllo dello stato del cluster." #~ msgid "Here we see something that some may consider surprising, the IP is back running at its original location!" #~ msgstr "Qui appare qualcosa che potrebbe sembrare sorprendente: l'IP è tornato attivo sul nodo originale!" #~ msgid "If we now retry the failover test, we see that as expected ClusterIP still moves to pcmk-2 when pcmk-1 is taken offline." #~ msgstr "Se ora si effettua nuovamente il test di failover si osserverà che come da pronostico ClusterIP verrà spostata su pcmk-2 quando pcmk-1 viene messo offline." #~ msgid "However when we bring pcmk-1 back online, ClusterIP now remains running on pcmk-2." #~ msgstr "Quando però pcmk-1 torna online ClusterIP rimane su pcmk-2." pacemaker-master/doc/Clusters_from_Scratch/it-IT/Ch-Apache.po000066400000000000000000000574631217637305600243720ustar00rootroot00000000000000# # AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: 0\n" "POT-Creation-Date: 2012-10-17T05:19:03\n" "PO-Revision-Date: 2010-08-03 12:16+0100\n" "Last-Translator: RaSca \n" "Language-Team: None\n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. Tag: title #, no-c-format msgid "Apache - Adding More Services" msgstr "Apache - Aggiungere ulteriori servizi" #. Tag: title #, no-c-format msgid "Forward" msgstr "" #. Tag: para #, no-c-format msgid "Now that we have a basic but functional active/passive two-node cluster, we’re ready to add some real services. We’re going to start with Apache because its a feature of many clusters and relatively simple to configure." msgstr "Ora che è stato realizzato un semplice, ma funzionale cluster a due nodi active/passive, è tempo di aggiungere servizi reali. Si partirà con Apache poiché molti cluster lo includono ed è relativamente semplice da configurare. " #. Tag: title #, no-c-format msgid "Installation" msgstr "Installazione" #. Tag: para #, fuzzy, no-c-format msgid "Before continuing, we need to make sure Apache is installed on both hosts. We also need the wget tool in order for the cluster to be able to check the status of the Apache server." msgstr "Inoltre il cluster necessita del tool wget per assicurarsi la capacità di controllare lo stato del server Apache." #. Tag: programlisting #, no-c-format msgid "# yum install -y httpd wget" msgstr "" #. Tag: literallayout #, no-c-format msgid "" "Loaded plugins: langpacks, presto, refresh-packagekit\n" "fedora/metalink | 2.6 kB 00:00\n" "updates/metalink | 3.2 kB 00:00\n" "updates-testing/metalink | 41 kB 00:00\n" "Resolving Dependencies\n" "--> Running transaction check\n" "---> Package httpd.x86_64 0:2.2.22-3.fc17 will be installed\n" "--> Processing Dependency: httpd-tools = 2.2.22-3.fc17 for package: httpd-2.2.22-3.fc17.x86_64\n" "--> Processing Dependency: apr-util-ldap for package: httpd-2.2.22-3.fc17.x86_64\n" "--> Processing Dependency: libaprutil-1.so.0()(64bit) for package: httpd-2.2.22-3.fc17.x86_64\n" "--> Processing Dependency: libapr-1.so.0()(64bit) for package: httpd-2.2.22-3.fc17.x86_64\n" "--> Running transaction check\n" "---> Package apr.x86_64 0:1.4.6-1.fc17 will be installed\n" "---> Package apr-util.x86_64 0:1.4.1-2.fc17 will be installed\n" "---> Package apr-util-ldap.x86_64 0:1.4.1-2.fc17 will be installed\n" "---> Package httpd-tools.x86_64 0:2.2.22-3.fc17 will be installed\n" "--> Finished Dependency Resolution\n" "\n" "Dependencies Resolved\n" "\n" "=====================================================================================\n" " Package Arch Version Repository Size\n" "=====================================================================================\n" "Installing:\n" " httpd x86_64 2.2.22-3.fc17 updates-testing 823 k\n" " wget x86_64 1.13.4-2.fc17 fedora 495 k\n" "Installing for dependencies:\n" " apr x86_64 1.4.6-1.fc17 fedora 99 k\n" " apr-util x86_64 1.4.1-2.fc17 fedora 78 k\n" " apr-util-ldap x86_64 1.4.1-2.fc17 fedora 17 k\n" " httpd-tools x86_64 2.2.22-3.fc17 updates-testing 74 k\n" "\n" "Transaction Summary\n" "=====================================================================================\n" "Install 1 Package (+4 Dependent packages)\n" "\n" "Total download size: 1.1 M\n" "Installed size: 3.5 M\n" "Downloading Packages:\n" "(1/6): apr-1.4.6-1.fc17.x86_64.rpm | 99 kB 00:00\n" "(2/6): apr-util-1.4.1-2.fc17.x86_64.rpm | 78 kB 00:00\n" "(3/6): apr-util-ldap-1.4.1-2.fc17.x86_64.rpm | 17 kB 00:00\n" "(4/6): httpd-2.2.22-3.fc17.x86_64.rpm | 823 kB 00:01\n" "(5/6): httpd-tools-2.2.22-3.fc17.x86_64.rpm | 74 kB 00:00\n" "(6/6): wget-1.13.4-2.fc17.x86_64.rpm | 495 kB 00:01\n" "-------------------------------------------------------------------------------------\n" "Total 238 kB/s | 1.1 MB 00:04\n" "Running Transaction Check\n" "Running Transaction Test\n" "Transaction Test Succeeded\n" "Running Transaction\n" " Installing : apr-1.4.6-1.fc17.x86_64 1/6\n" " Installing : apr-util-1.4.1-2.fc17.x86_64 2/6\n" " Installing : apr-util-ldap-1.4.1-2.fc17.x86_64 3/6\n" " Installing : httpd-tools-2.2.22-3.fc17.x86_64 4/6\n" " Installing : httpd-2.2.22-3.fc17.x86_64 5/6\n" " Installing : wget-1.13.4-2.fc17.x86_64 6/6\n" " Verifying : apr-util-ldap-1.4.1-2.fc17.x86_64 1/6\n" " Verifying : httpd-tools-2.2.22-3.fc17.x86_64 2/6\n" " Verifying : apr-util-1.4.1-2.fc17.x86_64 3/6\n" " Verifying : apr-1.4.6-1.fc17.x86_64 4/6\n" " Verifying : httpd-2.2.22-3.fc17.x86_64 5/6\n" " Verifying : wget-1.13.4-2.fc17.x86_64 6/6\n" "\n" "Installed:\n" " httpd.x86_64 0:2.2.22-3.fc17 wget.x86_64 0:1.13.4-2.fc17\n" "\n" "Dependency Installed:\n" " apr.x86_64 0:1.4.6-1.fc17 apr-util.x86_64 0:1.4.1-2.fc17\n" " apr-util-ldap.x86_64 0:1.4.1-2.fc17 httpd-tools.x86_64 0:2.2.22-3.fc17\n" "\n" "Complete!" msgstr "" #. Tag: title #, no-c-format msgid "Preparation" msgstr "Preparazione" #. Tag: para #, no-c-format msgid "First we need to create a page for Apache to serve up. On Fedora the default Apache docroot is /var/www/html, so we’ll create an index file there." msgstr "Prima di tutto è necessario creare la pagina che Apache servirà. Su Fedora la docroot di default di Apache è /var/www/html, qui verrà creato il file index." #. Tag: programlisting #, no-c-format msgid "" "# cat <<-END >/var/www/html/index.html\n" " <html>\n" " <body>My Test Site - pcmk-1</body>\n" " </html>\n" "END" msgstr "" #. Tag: para #, no-c-format msgid "For the moment, we will simplify things by serving up only a static site and manually sync the data between the two nodes. So run the command again on pcmk-2." msgstr "Per il momento l'architettura verrà semplificata in modo da servire unicamente un sito statico e sincronizzare manualmente i dati tra i due nodi. Quindi lo stesso comando andrà lanciato su pcmk-2." #. Tag: programlisting #, no-c-format msgid "" "[root@pcmk-2 ~]# cat <<-END >/var/www/html/index.html <html>\n" " <body>My Test Site - pcmk-2</body>\n" " </html>\n" " END" msgstr "" #. Tag: title #, no-c-format msgid "Enable the Apache status URL" msgstr "" #. Tag: para #, no-c-format msgid "In order to monitor the health of your Apache instance, and recover it if it fails, the resource agent used by Pacemaker assumes the server-status URL is available. Look for the following in /etc/httpd/conf/httpd.conf and make sure it is not disabled or commented out:" msgstr "" #. Tag: programlisting #, no-c-format msgid "" "<Location /server-status>\n" " SetHandler server-status\n" " Order deny,allow\n" " Deny from all\n" " Allow from 127.0.0.1\n" "</Location>" msgstr "" #. Tag: title #, no-c-format msgid "Update the Configuration" msgstr "Aggiornare la configurazione" #. Tag: para #, fuzzy, no-c-format msgid "At this point, Apache is ready to go, all that needs to be done is to add it to the cluster. Lets call the resource WebSite. We need to use an OCF script called apache in the heartbeat namespace Compare the key used here ocf:heartbeat:apache with the one we used earlier for the IP address: ocf:heartbeat:IPaddr2 , the only required parameter is the path to the main Apache configuration file and we’ll tell the cluster to check once a minute that apache is still running." msgstr "A questo punto Apache è pronto a funzionare, non rimane che aggiungere il servizio al cluster. La risorsa sarà nominata WebSite. Verrà utilizzato uno script OCF chiamato apache all'interno del namespace heartbeat Confrontare la chiave usata qui ocf:heartbeat:apache con quella usata in precedenza per l'indirizzo IP: ocf:heartbeat:IPaddr2 , l'unico altro parametro richiesto è il path al file di configurazione principale di Apache, inoltre verrà indicato al cluster di controllare una volta al minuto che il servizio apache sia in esecuzione." #. Tag: screen #, no-c-format msgid "" "pcs resource create WebSite ocf:heartbeat:apache \\\n" " configfile=/etc/httpd/conf/httpd.conf \\\n" " statusurl=\"http://localhost/server-status\" op monitor interval=1min" msgstr "" #. Tag: para #, no-c-format msgid "By default, the operation timeout for all resource’s start, stop, and monitor operations is 20 seconds. In many cases this timeout period is less than the advised timeout period. For the purposes of this tutorial, we will adjust the global operation timeout default to 240 seconds." msgstr "" #. Tag: programlisting #, no-c-format msgid "" "# pcs resource op defaults timeout=240s\n" "# pcs resource op defaults\n" "timeout: 240s" msgstr "" #. Tag: para #, no-c-format msgid "After a short delay, we should see the cluster start apache" msgstr "Dopo una breve attesa il cluster dovrbbe avviare apache" #. Tag: programlisting #, no-c-format msgid "" "# pcs status\n" "\n" "Last updated: Fri Sep 14 10:51:27 2012\n" "Last change: Fri Sep 14 10:50:46 2012 via crm_attribute on pcmk-1\n" "Stack: corosync\n" "Current DC: pcmk-2 (2) - partition with quorum\n" "Version: 1.1.8-1.el7-60a19ed12fdb4d5c6a6b6767f52e5391e447fec0\n" "2 Nodes configured, unknown expected votes\n" "2 Resources configured.\n" "\n" "Online: [ pcmk-1 pcmk-2 ]\n" "\n" "Full list of resources:\n" "\n" " ClusterIP (ocf::heartbeat:IPaddr2): Started pcmk-2\n" " WebSite (ocf::heartbeat:apache): Started pcmk-1" msgstr "" #. Tag: para #, no-c-format msgid "Wait a moment, the WebSite resource isn’t running on the same host as our IP address!" msgstr "Attenzione però, la risorsa WebSite non sta girando sullo stesso host dell'indirizzo IP!" #. Tag: para #, no-c-format msgid "If, in the pcs status output, you see the WebSite resource has failed to start, then you’ve likely not enabled the status URL correctly. You can check if this is the problem by running:" msgstr "" #. Tag: literallayout #, no-c-format msgid "wget http://127.0.0.1/server-status" msgstr "" #. Tag: para #, no-c-format msgid "If you see Connection refused in the output, then this is indeed the problem. Check to ensure that Allow from 127.0.0.1 is present for the <Location /server-status> block." msgstr "" #. Tag: title #, no-c-format msgid "Ensuring Resources Run on the Same Host" msgstr "Assicurarsi che le risorse funzionino sullo stesso host" #. Tag: para #, fuzzy, no-c-format msgid "To reduce the load on any one machine, Pacemaker will generally try to spread the configured resources across the cluster nodes. However we can tell the cluster that two resources are related and need to run on the same host (or not at all). Here we instruct the cluster that WebSite can only run on the host that ClusterIP is active on." msgstr "Per ridurre il carico su ogni macchina, Pacemaker generalmente tende a distribuire le risorse configurate sui nodi. E' possibile comunicare al cluster che due risorse sono relazionate e necessitano di funzionare sullo stesso host (oppure no). A questo punto il cluster verrà istruito in merito al fatto che WebSite può solamente funzionare sull'host che eroga ClusterIP. Se ClusterIP non è attiva in nessun nodo, a WebSite non verrà permesso di funzionare ovunque." #. Tag: para #, no-c-format msgid "To achieve this we use a colocation constraint that indicates it is mandatory for WebSite to run on the same node as ClusterIP. The \"mandatory\" part of the colocation constraint is indicated by using a score of INFINITY. The INFINITY score also means that if ClusterIP is not active anywhere, WebSite will not be permitted to run." msgstr "" #. Tag: para #, no-c-format msgid "If ClusterIP is not active anywhere, WebSite will not be permitted to run anywhere." msgstr "" #. Tag: para #, no-c-format msgid "Colocation constraints are \"directional\", in that they imply certain things about the order in which the two resources will have a location chosen. In this case we’re saying WebSite needs to be placed on the same machine as ClusterIP, this implies that we must know the location of ClusterIP before choosing a location for WebSite." msgstr "" #. Tag: programlisting #, no-c-format msgid "" "# pcs constraint colocation add WebSite ClusterIP INFINITY\n" "# pcs constraint\n" "Location Constraints:\n" "Ordering Constraints:\n" "Colocation Constraints:\n" " WebSite with ClusterIP\n" "# pcs status\n" "\n" "Last updated: Fri Sep 14 11:00:44 2012\n" "Last change: Fri Sep 14 11:00:25 2012 via cibadmin on pcmk-1\n" "Stack: corosync\n" "Current DC: pcmk-2 (2) - partition with quorum\n" "Version: 1.1.8-1.el7-60a19ed12fdb4d5c6a6b6767f52e5391e447fec0\n" "2 Nodes configured, unknown expected votes\n" "2 Resources configured.\n" "\n" "Online: [ pcmk-1 pcmk-2 ]\n" "\n" "Full list of resources:\n" "\n" " ClusterIP (ocf::heartbeat:IPaddr2): Started pcmk-2\n" " WebSite (ocf::heartbeat:apache): Started pcmk-2" msgstr "" #. Tag: title #, no-c-format msgid "Controlling Resource Start/Stop Ordering" msgstr "Controllare l'ordinamento di start e stop di una risorsa" #. Tag: para #, fuzzy, no-c-format msgid "When Apache starts, it binds to the available IP addresses. It doesn’t know about any addresses we add afterwards, so not only do they need to run on the same node, but we need to make sure ClusterIP is already active before we start WebSite. We do this by adding an ordering constraint." msgstr "Quando Apache si avvia, effettua l'associazione con gli indirizzi IP disponibili. Questo implica che non sarà a conoscenza di indirizzi aggiunti successivamente, quindi è necessario assicurarsi che ClusterIP sia attiva prima di avviare WebSite. Questo è possibile attraverso una ordering constraint. A questa verrà assegnato un nome (scelto in maniera descrittiva, come apache-after-ip), indicato che è obbligatoria (in modo che qualsiasi recovery per ClusterIP implicherà il recovery di WebSite) ed al suo interno verrà definito che l'ordine per l'avvio dei servizi è quello indicato." #. Tag: para #, no-c-format msgid "By default all order constraints are mandatory constraints unless otherwise configured. This means that the recovery of ClusterIP will also trigger the recovery of WebSite." msgstr "" #. Tag: programlisting #, no-c-format msgid "" "# pcs constraint order ClusterIP then WebSite\n" "Adding ClusterIP WebSite (kind: Mandatory) (Options: first-action=start then-action=start)\n" "# pcs constraint\n" "Location Constraints:\n" "Ordering Constraints:\n" " start ClusterIP then start WebSite\n" "Colocation Constraints:\n" " WebSite with ClusterIP" msgstr "" #. Tag: title #, no-c-format msgid "Specifying a Preferred Location" msgstr "Specificare una Location preferita" #. Tag: para #, fuzzy, no-c-format msgid "Pacemaker does not rely on any sort of hardware symmetry between nodes, so it may well be that one machine is more powerful than the other. In such cases it makes sense to host the resources there if it is available. To do this we create a location constraint." msgstr "Pacemaker non si basa su una sorta di simmetria tra i nodi hardware, quindi si potrebbe prevedere di avere anche una macchina più potente di un'altra. In questi casi ha senso erogare le risorse su questa macchina, se è disponibile. Per fare ciò viene creata una location constraint. Anche in questo caso viene assegnato un nome descrittivo (prefer-pcmk-1), specificata la risorsa che girerà qui (WebSite), quanto peso avrà per girare qui (verrà utilizzato 50, ma in una situazione a due nodi ogni valore superiore allo 0 andrà bene) ed il nome dell'host." #. Tag: para #, no-c-format msgid "In the location constraint below, we are saying the WebSite resource prefers the node pcmk-1 with a score of 50. The score here indicates how badly we’d like the resource to run somewhere." msgstr "" #. Tag: programlisting #, no-c-format msgid "" "# pcs constraint location WebSite prefers pcmk-1=50\n" "# pcs constraint\n" "Location Constraints:\n" " Resource: WebSite\n" " Enabled on: pcmk-1 (score:50)\n" "Ordering Constraints:\n" " start ClusterIP then start WebSite\n" "Colocation Constraints:\n" " WebSite with ClusterIP\n" "# pcs status\n" "Last updated: Fri Sep 14 11:06:37 2012\n" "Last change: Fri Sep 14 11:06:26 2012 via cibadmin on pcmk-1\n" "Stack: corosync\n" "Current DC: pcmk-2 (2) - partition with quorum\n" "Version: 1.1.8-1.el7-60a19ed12fdb4d5c6a6b6767f52e5391e447fec0\n" "2 Nodes configured, unknown expected votes\n" "2 Resources configured.\n" "\n" "Online: [ pcmk-1 pcmk-2 ]\n" "\n" "Full list of resources:\n" "\n" " ClusterIP (ocf::heartbeat:IPaddr2): Started pcmk-2\n" " WebSite (ocf::heartbeat:apache): Started pcmk-2" msgstr "" #. Tag: para #, no-c-format msgid "Wait a minute, the resources are still on pcmk-2!" msgstr "Attenzione però, le risorse sono comunque su pcmk-2!" #. Tag: para #, no-c-format msgid "Even though we now prefer pcmk-1 over pcmk-2, that preference is (intentionally) less than the resource stickiness (how much we preferred not to have unnecessary downtime)." msgstr "Anche se al momento viene preferito pcmk-1 a pcmk-2, questa preferenza è (intenzionalmente) minore dello stickiness della risorsa (quanto è stato preferito non avere un downtime superfluo)." #. Tag: para #, fuzzy, no-c-format msgid "To see the current placement scores, you can use a tool called crm_simulate" msgstr "Per osservare gli attuali punteggi di piazzamento è possibile usare un tool denominato ptest" #. Tag: programlisting #, no-c-format msgid "" "# crm_simulate -sL\n" "Current cluster status:\n" "Online: [ pcmk-1 pcmk-2 ]\n" "\n" " ClusterIP (ocf:heartbeat:IPaddr2): Started pcmk-2\n" " WebSite (ocf:heartbeat:apache): Started pcmk-2\n" "\n" "Allocation scores:\n" "native_color: ClusterIP allocation score on pcmk-1: 50\n" "native_color: ClusterIP allocation score on pcmk-2: 200\n" "native_color: WebSite allocation score on pcmk-1: -INFINITY\n" "native_color: WebSite allocation score on pcmk-2: 100\n" "\n" "Transition Summary:" msgstr "" #. Tag: title #, no-c-format msgid "Manually Moving Resources Around the Cluster" msgstr "Spostamento manuale delle risorse all'interno del cluster" #. Tag: para #, fuzzy, no-c-format msgid "There are always times when an administrator needs to override the cluster and force resources to move to a specific location. By updating our previous location constraint with a score of INFINITY, WebSite will be forced to move to pcmk-1." msgstr "C'è sempre la necessità da parte di un amministratore di soprassedere il cluster e forzare le risorse a spostarsi in una posizione specifica. E' possibile ignorare felicemente le location constraint create sopra, fornendo il nome della risorsa che si vuole spostare e la destinazione della stessa, il comando farà il resto." #. Tag: programlisting #, no-c-format msgid "" "# pcs constraint location WebSite prefers pcmk-1=INFINITY\n" "# pcs constraint all\n" "Location Constraints:\n" " Resource: WebSite\n" " Enabled on: pcmk-1 (score:INFINITY) (id:location-WebSite-pcmk-1-INFINITY)\n" "Ordering Constraints:\n" " start ClusterIP then start WebSite (Mandatory) (id:order-ClusterIP-WebSite-mandatory)\n" "Colocation Constraints:\n" " WebSite with ClusterIP (INFINITY) (id:colocation-WebSite-ClusterIP-INFINITY)\n" "# pcs status\n" "\n" "Last updated: Fri Sep 14 11:16:26 2012\n" "Last change: Fri Sep 14 11:16:18 2012 via cibadmin on pcmk-1\n" "Stack: corosync\n" "Current DC: pcmk-2 (2) - partition with quorum\n" "Version: 1.1.8-1.el7-60a19ed12fdb4d5c6a6b6767f52e5391e447fec0\n" "2 Nodes configured, unknown expected votes\n" "2 Resources configured.\n" "\n" "Online: [ pcmk-1 pcmk-2 ]\n" "\n" "Full list of resources:\n" "\n" " ClusterIP (ocf::heartbeat:IPaddr2): Started pcmk-1\n" " WebSite (ocf::heartbeat:apache): Started pcmk-1" msgstr "" #. Tag: title #, no-c-format msgid "Giving Control Back to the Cluster" msgstr "Restituire il controllo nuovamente al cluster" #. Tag: para #, no-c-format msgid "Once we’ve finished whatever activity that required us to move the resources to pcmk-1, in our case nothing, we can then allow the cluster to resume normal operation with the unmove command. Since we previously configured a default stickiness, the resources will remain on pcmk-1." msgstr "Una volta terminata una qualsiasi attività che richiede lo spostamento della risorsa in pcmk-1, in questo caso nessuna, è possibile consentire al cluster di riprendere le normali operazioni con il comando unmove. Dal momento che in precedenza è stata configurata una default stickiness, la risorsa rimarra in pcmk-1." #. Tag: programlisting #, no-c-format msgid "" "# pcs constraint all\n" "Location Constraints:\n" " Resource: WebSite\n" " Enabled on: pcmk-1 (score:INFINITY) (id:location-WebSite-pcmk-1-INFINITY)\n" "Ordering Constraints:\n" " start ClusterIP then start WebSite (Mandatory) (id:order-ClusterIP-WebSite-mandatory)\n" "Colocation Constraints:\n" " WebSite with ClusterIP (INFINITY) (id:colocation-WebSite-ClusterIP-INFINITY)\n" "# pcs constraint rm location-WebSite-pcmk-1-INFINITY\n" "# pcs constraint\n" "Location Constraints:\n" "Ordering Constraints:\n" " start ClusterIP then start WebSite\n" "Colocation Constraints:\n" " WebSite with ClusterIP" msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "Note that the constraint is now gone. If we check the cluster status, we can also see that as expected the resources are still active on pcmk-1." msgstr "E' da notare come la constraint automatizzata non esiste più. Se viene controllato lo stato del cluster è possibile osservare che, così come aspettato, le risorse sono ancora attiva su pcmk-1." #. Tag: programlisting #, no-c-format msgid "" "# pcs status\n" "\n" "Last updated: Fri Sep 14 11:57:12 2012\n" "Last change: Fri Sep 14 11:57:03 2012 via cibadmin on pcmk-1\n" "Stack: corosync\n" "Current DC: pcmk-2 (2) - partition with quorum\n" "Version: 1.1.8-1.el7-60a19ed12fdb4d5c6a6b6767f52e5391e447fec0\n" "2 Nodes configured, unknown expected votes\n" "2 Resources configured.\n" "\n" "Online: [ pcmk-1 pcmk-2 ]\n" "\n" "Full list of resources:\n" "\n" " ClusterIP (ocf::heartbeat:IPaddr2): Started pcmk-1\n" " WebSite (ocf::heartbeat:apache): Started pcmk-1" msgstr "" #~ msgid "Before continuing, we need to make sure Apache is installed on both hosts." #~ msgstr "Prima di cominciare è necessario assicurarsi che Apache sia installato su entrambi gli host." #~ msgid "Include output" #~ msgstr "Output incluso" #~ msgid "There is a way to force them to move though..." #~ msgstr "Esiste un modo per spostare forzatamente le risorse..." #~ msgid "Highlighted is the automated constraint used to move the resources to pcmk-1" #~ msgstr "Viene evidenziata la constraint automatizzata utilizzata per spostare la risorsa in pcmk-1" pacemaker-master/doc/Clusters_from_Scratch/it-IT/Ch-Installation.po000066400000000000000000002405521217637305600256430ustar00rootroot00000000000000# # AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: 0\n" "POT-Creation-Date: 2012-10-17T05:19:03\n" "PO-Revision-Date: 2010-07-16 17:16+0100\n" "Last-Translator: RaSca \n" "Language-Team: None\n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. Tag: title #, no-c-format msgid "Installation" msgstr "Installazione" #. Tag: title #, no-c-format msgid "OS Installation" msgstr "Installazione del sistema operativo" #. Tag: para #, fuzzy, no-c-format msgid "Detailed instructions for installing Fedora are available at http://docs.fedoraproject.org/en-US/Fedora/17/html/Installation_Guide/ in a number of languages. The abbreviated version is as follows…" msgstr "Informazioni dettagliate su come installare Fedora sono disponibili presso http://docs.fedoraproject.org/install-guide/f&DISTRO_VERSION;/ in numerose lingue. La versione abbreviata è la seguente..." #. Tag: para #, fuzzy, no-c-format msgid "Point your browser to http://fedoraproject.org/en/get-fedora-all, locate the Install Media section and download the install DVD that matches your hardware." msgstr "Puntando il browser al link http://fedoraproject.org/en/get-fedora-all, individuare la sezione Install Media e scaricare il DVD di installazione adatto al proprio hardware." #. Tag: para #, fuzzy, no-c-format msgid "Burn the disk image to a DVD http://docs.fedoraproject.org/en-US/Fedora/16/html/Burning_ISO_images_to_disc/index.html and boot from it, or use the image to boot a virtual machine." msgstr "Assegnare un nome alla macchina. http://docs.fedoraproject.org/install-guide/f&DISTRO_VERSION;/en-US/html/sn-networkconfig-fedora.html Il dominio utilizzato in questo progetto sarà clusterlabs.org." #. Tag: para #, no-c-format msgid "After clicking through the welcome screen, select your language, keyboard layout http://docs.fedoraproject.org/en-US/Fedora/16/html/Installation_Guide/sn-keyboard-x86.html and storage type http://docs.fedoraproject.org/en-US/Fedora/16/html/Installation_Guide/Storage_Devices-x86.html" msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "Assign your machine a host name. http://docs.fedoraproject.org/en-US/Fedora/16/html/Installation_Guide/sn-Netconfig-x86.html I happen to control the clusterlabs.org domain name, so I will use that here." msgstr "Assegnare un nome alla macchina. http://docs.fedoraproject.org/install-guide/f&DISTRO_VERSION;/en-US/html/sn-networkconfig-fedora.html Il dominio utilizzato in questo progetto sarà clusterlabs.org." #. Tag: para #, fuzzy, no-c-format msgid "Do not accept the default network settings. Cluster machines should never obtain an IP address via DHCP." msgstr "Non accettare i settaggi di default della rete. Le macchine cluster non devono MAI ottenere un indirizzo IP via DHCP. In questo caso verrà utilizzato gli indirizzi internal della rete clusterlab.org." #. Tag: para #, no-c-format msgid "When you are presented with the Configure Network advanced option, select that option before continuing with the installation process to specify a fixed IPv4 address for System eth0. Be sure to also enter the Routes section and add an entry for your default gateway." msgstr "" #. Tag: phrase #, no-c-format msgid "Custom network settings" msgstr "" #. Tag: para #, no-c-format msgid "If you miss this step, this can easily be configured after installation. You will have to navigate to system settings and select network. From there you can select what device to configure." msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "You will then be prompted to indicate the machine’s physical location http://docs.fedoraproject.org/en-US/Fedora/16/html/Installation_Guide/s1-timezone-x86.html and to supply a root password. http://docs.fedoraproject.org/en-US/Fedora/16/html/Installation_Guide/sn-account_configuration-x86.html" msgstr "Verrà poi richiesto di indicare la locazione fisica della macchina ed una password di root. http://docs.fedoraproject.org/install-guide/f&DISTRO_VERSION;/en-US/html/sn-account_configuration.html " #. Tag: para #, fuzzy, no-c-format msgid "Now select where you want Fedora installed. http://docs.fedoraproject.org/en-US/Fedora/16/html/Installation_Guide/s1-diskpartsetup-x86.html As I don’t care about any existing data, I will accept the default and allow Fedora to use the complete drive." msgstr "Selezionare dove Fedora verrà installata. http://docs.fedoraproject.org/install-guide/f13/en-US/html/s1-diskpartsetup-x86.html Non viene prestato nessun controllo sui dati esistenti, accettando le ozioni di default che prevedono Fedora utilizzi l'intero disco. Ad ogni modo verrà riservato dello spazio per DRBD, verrà quindi selezionata la casella Review and modify partitioning layout." #. Tag: para #, no-c-format msgid "By default Fedora uses LVM for partitioning which allows us to dynamically change the amount of space allocated to a given partition." msgstr "" #. Tag: para #, no-c-format msgid "However, by default it also allocates all free space to the / (aka. root) partition which cannot be dynamically reduced in size (dynamic increases are fine by-the-way)." msgstr "" #. Tag: para #, no-c-format msgid "So if you plan on following the DRBD or GFS2 portions of this guide, you should reserve at least 1Gb of space on each machine from which to create a shared volume. To do so select the Review and modify partitioning layout checkbox before clicking Next. You will then be given an opportunity to reduce the size of the root partition." msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "Next choose which software should be installed. http://docs.fedoraproject.org/en-US/Fedora/16/html/Installation_Guide/s1-pkgselection-x86.html Change the selection to Minimal so that we see everything that gets installed. Don’t enable updates yet, we’ll do that (and install any extra software we need) later. After you click next, Fedora will begin installing." msgstr "Scegliere quindi quale software si vorrà installare. Cambiare la selezione a Web Server dal momento che si ha in programma di usare Apache. Non abilitare gli aggiornamenti, questo verrà fatto (insieme all'installazione di ulteriore software extra necessario) dopo. Dopo aver cliccato next, Fedora si installerà." #. Tag: para #, fuzzy, no-c-format msgid "Go grab something to drink, this may take a while." msgstr "Installazione di Fedora: Prendere qualcosa da bere, questa parte dura abbastanza" #. Tag: para #, no-c-format msgid "Once the node reboots, you’ll see a (possibly mangled) login prompt on the console. Login using root and the password you created earlier." msgstr "" #. Tag: phrase #, no-c-format msgid "Initial Console" msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "From here on in we’re going to be working exclusively from the terminal." msgstr "Questa era l'ultima schermata, da qui in poi il lavoro verrà effettuato da terminale." #. Tag: title #, fuzzy, no-c-format msgid "Post Installation Tasks" msgstr "Installazione" #. Tag: title #, fuzzy, no-c-format msgid "Networking" msgstr "Definire la rete" #. Tag: para #, no-c-format msgid "Bring up the network and ensure it starts at boot" msgstr "" #. Tag: programlisting #, no-c-format msgid "" "# service network start\n" "# chkconfig network on" msgstr "" #. Tag: para #, no-c-format msgid "Check the machine has the static IP address you configured earlier" msgstr "" #. Tag: programlisting #, no-c-format msgid "" "# ip addr\n" "1: lo: <LOOPBACK,UP,LOWER_UP> mtu 16436 qdisc noqueue state UNKNOWN\n" " link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00\n" " inet 127.0.0.1/8 scope host lo\n" " inet6 ::1/128 scope host\n" " valid_lft forever preferred_lft forever\n" "2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000\n" " link/ether 52:54:00:d7:d6:08 brd ff:ff:ff:ff:ff:ff\n" " inet 192.168.122.101/24 brd 192.168.122.255 scope global eth0\n" " inet6 fe80::5054:ff:fed7:d608/64 scope link\n" " valid_lft forever preferred_lft forever" msgstr "" #. Tag: para #, no-c-format msgid "Now check the default route setting:" msgstr "" #. Tag: programlisting #, no-c-format msgid "" "[root@pcmk-1 ~]# ip route\n" "default via 192.168.122.1 dev eth0\n" "192.168.122.0/24 dev eth0 proto kernel scope link src 192.168.122.101" msgstr "" #. Tag: para #, no-c-format msgid "If there is no line beginning with default via, then you may need to add a line such as" msgstr "" #. Tag: programlisting #, no-c-format msgid "GATEWAY=192.168.122.1" msgstr "" #. Tag: para #, no-c-format msgid "to /etc/sysconfig/network and restart the network." msgstr "" #. Tag: para #, no-c-format msgid "Now check for connectivity to the outside world. Start small by testing if we can read the gateway we configured." msgstr "" #. Tag: programlisting #, no-c-format msgid "" "# ping -c 1 192.168.122.1\n" "PING 192.168.122.1 (192.168.122.1) 56(84) bytes of data.\n" "64 bytes from 192.168.122.1: icmp_req=1 ttl=64 time=0.249 ms\n" "\n" "--- 192.168.122.1 ping statistics ---\n" "1 packets transmitted, 1 received, 0% packet loss, time 0ms\n" "rtt min/avg/max/mdev = 0.249/0.249/0.249/0.000 ms" msgstr "" #. Tag: para #, no-c-format msgid "Now try something external, choose a location you know will be available." msgstr "" #. Tag: programlisting #, no-c-format msgid "" "# ping -c 1 www.google.com\n" "PING www.l.google.com (173.194.72.106) 56(84) bytes of data.\n" "64 bytes from tf-in-f106.1e100.net (173.194.72.106): icmp_req=1 ttl=41 time=167 ms\n" "\n" "--- www.l.google.com ping statistics ---\n" "1 packets transmitted, 1 received, 0% packet loss, time 0ms\n" "rtt min/avg/max/mdev = 167.618/167.618/167.618/0.000 ms" msgstr "" #. Tag: title #, no-c-format msgid "Leaving the Console" msgstr "" #. Tag: para #, no-c-format msgid "The console isn’t a very friendly place to work from, we will now switch to accessing the machine remotely via SSH where we can use copy&paste etc." msgstr "" #. Tag: para #, no-c-format msgid "First we check we can see the newly installed at all:" msgstr "" #. Tag: programlisting #, no-c-format msgid "" "beekhof@f16 ~ # ping -c 1 192.168.122.101\n" "PING 192.168.122.101 (192.168.122.101) 56(84) bytes of data.\n" "64 bytes from 192.168.122.101: icmp_req=1 ttl=64 time=1.01 ms\n" "\n" "--- 192.168.122.101 ping statistics ---\n" "1 packets transmitted, 1 received, 0% packet loss, time 0ms\n" "rtt min/avg/max/mdev = 1.012/1.012/1.012/0.000 ms" msgstr "" #. Tag: para #, no-c-format msgid "Next we login via SSH" msgstr "" #. Tag: programlisting #, no-c-format msgid "" "beekhof@f16 ~ # ssh -l root 192.168.122.11\n" "root@192.168.122.11's password:\n" "Last login: Fri Mar 30 19:41:19 2012 from 192.168.122.1\n" "[root@pcmk-1 ~]#" msgstr "" #. Tag: title #, no-c-format msgid "Security Shortcuts" msgstr "Considerazioni sulla sicurezza" #. Tag: para #, fuzzy, no-c-format msgid "To simplify this guide and focus on the aspects directly connected to clustering, we will now disable the machine’s firewall and SELinux installation." msgstr "Per semplificare questa guida e focalizzare gli aspetti direttamente correlati al custering sarà necessario disabilitare il firewall della macchina e l'installazione di SELinux. Entrambe queste azioni creano limiti nella sicurezza e non dovrebbero essere applicate a macchine esposte al mondo." #. Tag: para #, fuzzy, no-c-format msgid "Both of these actions create significant security issues and should not be performed on machines that will be exposed to the outside world." msgstr "Per semplificare questa guida e focalizzare gli aspetti direttamente correlati al custering sarà necessario disabilitare il firewall della macchina e l'installazione di SELinux. Entrambe queste azioni creano limiti nella sicurezza e non dovrebbero essere applicate a macchine esposte al mondo." #. Tag: literallayout #, no-c-format msgid "TODO: Create an Appendix that deals with (at least) re-enabling the firewall." msgstr "TODO: Creare un Appendice che valuti (almeno) la riabilitazione del firewall." #. Tag: programlisting #, no-c-format msgid "" "# setenforce 0\n" "# sed -i.bak \"s/SELINUX=enforcing/SELINUX=permissive/g\" /etc/selinux/config\n" "# systemctl disable iptables.service\n" "# rm '/etc/systemd/system/basic.target.wants/iptables.service'\n" "# systemctl stop iptables.service" msgstr "" #. Tag: title #, no-c-format msgid "Short Node Names" msgstr "Nomi di nodi abbreviati" #. Tag: para #, fuzzy, no-c-format msgid "During installation, we filled in the machine’s fully qualifier domain name (FQDN) which can be rather long when it appears in cluster logs and status output. See for yourself how the machine identifies itself: Nodesshort name short name " msgstr "Durante l'installazione è stato inserito il fully qualifier domain name (FQDN) della macchina che può essere particolarmente lungo all'interno dei log del cluster e nella visualizzazione del suo stato. Verificare come la macchina si identifica:" #. Tag: programlisting #, no-c-format msgid "" "# uname -n\n" "pcmk-1.clusterlabs.org\n" "# dnsdomainname\n" "clusterlabs.org" msgstr "" #. Tag: para #, no-c-format msgid " NodesDomain name (Query) Domain name (Query) " msgstr "" #. Tag: para #, no-c-format msgid "The output from the second command is fine, but we really don’t need the domain name included in the basic host details. To address this, we need to update /etc/sysconfig/network. This is what it should look like before we start." msgstr "L'output del secondo comando è corretto, ma non è necessario il nome del dominio incluso nei dettagli essenziali dell'host. Per risolvere la situazione è necessario modificare il file /etc/sysconfig/netwirk. Ecco come dovrà apparire." #. Tag: programlisting #, no-c-format msgid "" "# cat /etc/sysconfig/network\n" "NETWORKING=yes\n" "HOSTNAME=pcmk-1.clusterlabs.org\n" "GATEWAY=192.168.122.1" msgstr "" #. Tag: para #, no-c-format msgid "All we need to do now is strip off the domain name portion, which is stored elsewhere anyway." msgstr "L'unica cosa da fare sarà di rimuovere la parte relativa al nome del dominio, che rimarrà comunque registrata altrove." #. Tag: programlisting #, no-c-format msgid " # sed -i.sed 's/\\.[a-z].*//g' /etc/sysconfig/network" msgstr "" #. Tag: para #, no-c-format msgid "Now confirm the change was successful. The revised file contents should look something like this." msgstr "Per verificare l'efficacia dei cambiamenti apportati il contenuto del file dovrà essere simile a quanto riportato." #. Tag: programlisting #, no-c-format msgid "" "# cat /etc/sysconfig/network\n" "NETWORKING=yes\n" "HOSTNAME=pcmk-1\n" "GATEWAY=192.168.122.1" msgstr "" #. Tag: para #, no-c-format msgid "However we’re not finished. The machine wont normally see the shortened host name until about it reboots, but we can force it to update." msgstr "Ma non è ancora finita. La macchina non sarà allineata con i nomi abbreviati finché non verrà riavviata, ma è possibile forzare l'aggiornamento." #. Tag: programlisting #, no-c-format msgid "" "# source /etc/sysconfig/network\n" "# hostname $HOSTNAME" msgstr "" #. Tag: para #, no-c-format msgid " NodesDomain name (Remove from host name) Domain name (Remove from host name) " msgstr "" #. Tag: para #, no-c-format msgid "Now check the machine is using the correct names" msgstr "E' possibile quindi verificare che la macchina utilizzi il nome corretto" #. Tag: programlisting #, no-c-format msgid "" "# uname -n\n" "pcmk-1\n" "# dnsdomainname\n" "clusterlabs.org" msgstr "" #. Tag: title #, no-c-format msgid "NTP" msgstr "" #. Tag: para #, no-c-format msgid "It is highly recommended to enable NTP on your cluster nodes. Doing so ensures all nodes agree on the current time and makes reading log files significantly easier. http://docs.fedoraproject.org/en-US/Fedora/17/html-single/System_Administrators_Guide/index.html#ch-Configuring_the_Date_and_Time" msgstr "" #. Tag: title #, no-c-format msgid "Before You Continue" msgstr "Prima di continuare" #. Tag: para #, fuzzy, no-c-format msgid "Repeat the Installation steps so far, so that you have two Fedora nodes ready to have the cluster software installed." msgstr "Ripetere i passi dell'installazione così da avere due nodi Fedora con il software cluster installato." #. Tag: para #, fuzzy, no-c-format msgid "For the purposes of this document, the additional node is called pcmk-2 with address 192.168.122.102." msgstr "Per rispettae gli obiettivi di questa documentazione il nodo aggiuntivo verrà chiamato pcmk-2 con indirizzo 192.168.122.42." #. Tag: title #, no-c-format msgid "Finalize Networking" msgstr "Definire la rete" #. Tag: para #, fuzzy, no-c-format msgid "Confirm that you can communicate between the two new nodes:" msgstr "Verificare la reciproca comunicazione dei due nodi:" #. Tag: programlisting #, no-c-format msgid "" "# ping -c 3 192.168.122.102\n" "PING 192.168.122.102 (192.168.122.102) 56(84) bytes of data.\n" "64 bytes from 192.168.122.102: icmp_seq=1 ttl=64 time=0.343 ms\n" "64 bytes from 192.168.122.102: icmp_seq=2 ttl=64 time=0.402 ms\n" "64 bytes from 192.168.122.102: icmp_seq=3 ttl=64 time=0.558 ms\n" "\n" "--- 192.168.122.102 ping statistics ---\n" "3 packets transmitted, 3 received, 0% packet loss, time 2000ms\n" "rtt min/avg/max/mdev = 0.343/0.434/0.558/0.092 ms" msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "Now we need to make sure we can communicate with the machines by their name. If you have a DNS server, add additional entries for the two machines. Otherwise, you’ll need to add the machines to /etc/hosts . Below are the entries for my cluster nodes:" msgstr "Ora è necessario avere la certezza che i nodi possano comunicare fra loro attraverso il nome. Se si possiede un server DNS andranno aggiunti i nomi delle tre macchine. In alternativa i nomi andranno aggiunti in /etc/hosts. Ecco riportate le impostazioni sui nodi cluster del progetto:" #. Tag: programlisting #, no-c-format msgid "" "# grep pcmk /etc/hosts\n" "192.168.122.101 pcmk-1.clusterlabs.org pcmk-1\n" "192.168.122.102 pcmk-2.clusterlabs.org pcmk-2" msgstr "" #. Tag: para #, no-c-format msgid "We can now verify the setup by again using ping:" msgstr "Ora è possibile verificare il setup usando nuovamente ping:" #. Tag: programlisting #, no-c-format msgid "" "# ping -c 3 pcmk-2\n" "PING pcmk-2.clusterlabs.org (192.168.122.101) 56(84) bytes of data.\n" "64 bytes from pcmk-1.clusterlabs.org (192.168.122.101): icmp_seq=1 ttl=64 time=0.164 ms\n" "64 bytes from pcmk-1.clusterlabs.org (192.168.122.101): icmp_seq=2 ttl=64 time=0.475 ms\n" "64 bytes from pcmk-1.clusterlabs.org (192.168.122.101): icmp_seq=3 ttl=64 time=0.186 ms\n" "\n" "--- pcmk-2.clusterlabs.org ping statistics ---\n" "3 packets transmitted, 3 received, 0% packet loss, time 2001ms\n" "rtt min/avg/max/mdev = 0.164/0.275/0.475/0.141 ms" msgstr "" #. Tag: title #, no-c-format msgid "Configure SSH" msgstr "Configuarazione di SSH" #. Tag: para #, fuzzy, no-c-format msgid "SSH is a convenient and secure way to copy files and perform commands remotely. For the purposes of this guide, we will create a key without a password (using the -N option) so that we can perform remote actions without being prompted." msgstr "SSH rappresenta una via conveniente e sicura per copiare file e lanciare comandi remotamente. Per raggiungere l'obiettivo di questa guida, verrà creata una chiave senza password (utilizzando l'opzione -N) in modo da poter eseguire comandi remoti senza che venga mostrato il prompt." #. Tag: para #, no-c-format msgid " SSH " msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "Unprotected SSH keys, those without a password, are not recommended for servers exposed to the outside world. We use them here only to simplify the demo." msgstr "Chiavi SSH non protette, senza una password, non sono raccomandate per server esposti al mondo." #. Tag: para #, no-c-format msgid "Create a new key and allow anyone with that key to log in:" msgstr "Creazione di una nuova chiave ed abilitazione al proprietario della chiave di effettuare login:" #. Tag: title #, no-c-format msgid "Creating and Activating a new SSH Key" msgstr "Creazione ed attivazione di una nuova chiave SSH" #. Tag: programlisting #, no-c-format msgid "" "# ssh-keygen -t dsa -f ~/.ssh/id_dsa -N \"\"\n" "Generating public/private dsa key pair.\n" "Your identification has been saved in /root/.ssh/id_dsa.\n" "Your public key has been saved in /root/.ssh/id_dsa.pub.\n" "The key fingerprint is:\n" "91:09:5c:82:5a:6a:50:08:4e:b2:0c:62:de:cc:74:44 root@pcmk-1.clusterlabs.org\n" "\n" "The key's randomart image is:\n" "+--[ DSA 1024]----+\n" "|==.ooEo.. |\n" "|X O + .o o |\n" "| * A + |\n" "| + . |\n" "| . S |\n" "| |\n" "| |\n" "| |\n" "| |\n" "+-----------------+\n" "\n" "# cp .ssh/id_dsa.pub .ssh/authorized_keys" msgstr "" #. Tag: para #, fuzzy, no-c-format msgid " Creating and Activating a new SSH Key " msgstr "Creazione ed attivazione di una nuova chiave SSH" #. Tag: para #, no-c-format msgid "Install the key on the other nodes and test that you can now run commands remotely, without being prompted" msgstr "Installare la chiave sull'altro nodo e verificare come sia possibile lanciare comandi remotamente, senza ricevere prompt" #. Tag: title #, no-c-format msgid "Installing the SSH Key on Another Host" msgstr "Installare la chiave SSH su un altro host" #. Tag: programlisting #, no-c-format msgid "" "# scp -r .ssh pcmk-2:\n" "The authenticity of host 'pcmk-2 (192.168.122.102)' can't be established.\n" "RSA key fingerprint is b1:2b:55:93:f1:d9:52:2b:0f:f2:8a:4e:ae:c6:7c:9a.\n" "Are you sure you want to continue connecting (yes/no)? yes\n" "Warning: Permanently added 'pcmk-2,192.168.122.102' (RSA) to the list of known hosts.root@pcmk-2's password:\n" "id_dsa.pub 100% 616 0.6KB/s 00:00\n" "id_dsa 100% 672 0.7KB/s 00:00\n" "known_hosts 100% 400 0.4KB/s 00:00\n" "authorized_keys 100% 616 0.6KB/s 00:00\n" "# ssh pcmk-2 -- uname -n\n" "pcmk-2\n" "#" msgstr "" #. Tag: title #, no-c-format msgid "Cluster Software Installation" msgstr "Installazione del software cluster" #. Tag: title #, no-c-format msgid "Install the Cluster Software" msgstr "Installazione del software cluster" #. Tag: para #, no-c-format msgid "Since version 12, Fedora comes with recent versions of everything you need, so simply fire up the shell and run:" msgstr "Dalla versione 12, Fedora fornisce versioni recenti di tutto quanto si necessita, quindi avviando la shell lanciare:" #. Tag: programlisting #, no-c-format msgid "# yum install -y pacemaker corosync" msgstr "" #. Tag: literallayout #, no-c-format msgid "" "fedora/metalink | 38 kB 00:00\n" "fedora | 4.2 kB 00:00\n" "fedora/primary_db | 14 MB 00:21\n" "updates/metalink | 2.7 kB 00:00\n" "updates | 2.6 kB 00:00\n" "updates/primary_db | 1.2 kB 00:00\n" "updates-testing/metalink | 28 kB 00:00\n" "updates-testing | 4.5 kB 00:00\n" "updates-testing/primary_db | 4.5 MB 00:12\n" "Setting up Install Process\n" "Resolving Dependencies\n" "--> Running transaction check\n" "---> Package corosync.x86_64 0:1.99.9-1.fc17 will be installed\n" "--> Processing Dependency: corosynclib = 1.99.9-1.fc17 for package: corosync-1.99.9-1.fc17.x86_64\n" "--> Processing Dependency: libxslt for package: corosync-1.99.9-1.fc17.x86_64\n" "--> Processing Dependency: libvotequorum.so.5(COROSYNC_VOTEQUORUM_1.0)(64bit) for package: corosync-1.99.9-1.fc17.x86_64\n" "--> Processing Dependency: libquorum.so.5(COROSYNC_QUORUM_1.0)(64bit) for package: corosync-1.99.9-1.fc17.x86_64\n" "--> Processing Dependency: libcpg.so.4(COROSYNC_CPG_1.0)(64bit) for package: corosync-1.99.9-1.fc17.x86_64\n" "--> Processing Dependency: libcmap.so.4(COROSYNC_CMAP_1.0)(64bit) for package: corosync-1.99.9-1.fc17.x86_64\n" "--> Processing Dependency: libcfg.so.6(COROSYNC_CFG_0.82)(64bit) for package: corosync-1.99.9-1.fc17.x86_64\n" "--> Processing Dependency: libvotequorum.so.5()(64bit) for package: corosync-1.99.9-1.fc17.x86_64\n" "--> Processing Dependency: libtotem_pg.so.5()(64bit) for package: corosync-1.99.9-1.fc17.x86_64\n" "--> Processing Dependency: libquorum.so.5()(64bit) for package: corosync-1.99.9-1.fc17.x86_64\n" "--> Processing Dependency: libqb.so.0()(64bit) for package: corosync-1.99.9-1.fc17.x86_64\n" "--> Processing Dependency: libnetsnmp.so.30()(64bit) for package: corosync-1.99.9-1.fc17.x86_64\n" "--> Processing Dependency: libcpg.so.4()(64bit) for package: corosync-1.99.9-1.fc17.x86_64\n" "--> Processing Dependency: libcorosync_common.so.4()(64bit) for package: corosync-1.99.9-1.fc17.x86_64\n" "--> Processing Dependency: libcmap.so.4()(64bit) for package: corosync-1.99.9-1.fc17.x86_64\n" "--> Processing Dependency: libcfg.so.6()(64bit) for package: corosync-1.99.9-1.fc17.x86_64\n" "---> Package pacemaker.x86_64 0:1.1.7-2.fc17 will be installed\n" "--> Processing Dependency: pacemaker-libs = 1.1.7-2.fc17 for package: pacemaker-1.1.7-2.fc17.x86_64\n" "--> Processing Dependency: pacemaker-cluster-libs = 1.1.7-2.fc17 for package: pacemaker-1.1.7-2.fc17.x86_64\n" "--> Processing Dependency: pacemaker-cli = 1.1.7-2.fc17 for package: pacemaker-1.1.7-2.fc17.x86_64\n" "--> Processing Dependency: resource-agents for package: pacemaker-1.1.7-2.fc17.x86_64\n" "--> Processing Dependency: perl(Getopt::Long) for package: pacemaker-1.1.7-2.fc17.x86_64\n" "--> Processing Dependency: libgnutls.so.26(GNUTLS_1_4)(64bit) for package: pacemaker-1.1.7-2.fc17.x86_64\n" "--> Processing Dependency: cluster-glue for package: pacemaker-1.1.7-2.fc17.x86_64\n" "--> Processing Dependency: /usr/bin/perl for package: pacemaker-1.1.7-2.fc17.x86_64\n" "--> Processing Dependency: libtransitioner.so.1()(64bit) for package: pacemaker-1.1.7-2.fc17.x86_64\n" "--> Processing Dependency: libstonithd.so.1()(64bit) for package: pacemaker-1.1.7-2.fc17.x86_64\n" "--> Processing Dependency: libstonith.so.1()(64bit) for package: pacemaker-1.1.7-2.fc17.x86_64\n" "--> Processing Dependency: libplumb.so.2()(64bit) for package: pacemaker-1.1.7-2.fc17.x86_64\n" "--> Processing Dependency: libpils.so.2()(64bit) for package: pacemaker-1.1.7-2.fc17.x86_64\n" "--> Processing Dependency: libpengine.so.3()(64bit) for package: pacemaker-1.1.7-2.fc17.x86_64\n" "--> Processing Dependency: libpe_status.so.3()(64bit) for package: pacemaker-1.1.7-2.fc17.x86_64\n" "--> Processing Dependency: libpe_rules.so.2()(64bit) for package: pacemaker-1.1.7-2.fc17.x86_64\n" "--> Processing Dependency: libltdl.so.7()(64bit) for package: pacemaker-1.1.7-2.fc17.x86_64\n" "--> Processing Dependency: liblrm.so.2()(64bit) for package: pacemaker-1.1.7-2.fc17.x86_64\n" "--> Processing Dependency: libgnutls.so.26()(64bit) for package: pacemaker-1.1.7-2.fc17.x86_64\n" "--> Processing Dependency: libcrmcommon.so.2()(64bit) for package: pacemaker-1.1.7-2.fc17.x86_64\n" "--> Processing Dependency: libcrmcluster.so.1()(64bit) for package: pacemaker-1.1.7-2.fc17.x86_64\n" "--> Processing Dependency: libcib.so.1()(64bit) for package: pacemaker-1.1.7-2.fc17.x86_64\n" "--> Running transaction check\n" "---> Package cluster-glue.x86_64 0:1.0.6-9.fc17.1 will be installed\n" "--> Processing Dependency: perl-TimeDate for package: cluster-glue-1.0.6-9.fc17.1.x86_64\n" "--> Processing Dependency: libOpenIPMIutils.so.0()(64bit) for package: cluster-glue-1.0.6-9.fc17.1.x86_64\n" "--> Processing Dependency: libOpenIPMIposix.so.0()(64bit) for package: cluster-glue-1.0.6-9.fc17.1.x86_64\n" "--> Processing Dependency: libOpenIPMI.so.0()(64bit) for package: cluster-glue-1.0.6-9.fc17.1.x86_64\n" "---> Package cluster-glue-libs.x86_64 0:1.0.6-9.fc17.1 will be installed\n" "---> Package corosynclib.x86_64 0:1.99.9-1.fc17 will be installed\n" "--> Processing Dependency: librdmacm.so.1(RDMACM_1.0)(64bit) for package: corosynclib-1.99.9-1.fc17.x86_64\n" "--> Processing Dependency: libibverbs.so.1(IBVERBS_1.1)(64bit) for package: corosynclib-1.99.9-1.fc17.x86_64\n" "--> Processing Dependency: libibverbs.so.1(IBVERBS_1.0)(64bit) for package: corosynclib-1.99.9-1.fc17.x86_64\n" "--> Processing Dependency: librdmacm.so.1()(64bit) for package: corosynclib-1.99.9-1.fc17.x86_64\n" "--> Processing Dependency: libibverbs.so.1()(64bit) for package: corosynclib-1.99.9-1.fc17.x86_64\n" "---> Package gnutls.x86_64 0:2.12.17-1.fc17 will be installed\n" "--> Processing Dependency: libtasn1.so.3(LIBTASN1_0_3)(64bit) for package: gnutls-2.12.17-1.fc17.x86_64\n" "--> Processing Dependency: libtasn1.so.3()(64bit) for package: gnutls-2.12.17-1.fc17.x86_64\n" "--> Processing Dependency: libp11-kit.so.0()(64bit) for package: gnutls-2.12.17-1.fc17.x86_64\n" "---> Package libqb.x86_64 0:0.11.1-1.fc17 will be installed\n" "---> Package libtool-ltdl.x86_64 0:2.4.2-3.fc17 will be installed\n" "---> Package libxslt.x86_64 0:1.1.26-9.fc17 will be installed\n" "---> Package net-snmp-libs.x86_64 1:5.7.1-4.fc17 will be installed\n" "---> Package pacemaker-cli.x86_64 0:1.1.7-2.fc17 will be installed\n" "---> Package pacemaker-cluster-libs.x86_64 0:1.1.7-2.fc17 will be installed\n" "---> Package pacemaker-libs.x86_64 0:1.1.7-2.fc17 will be installed\n" "---> Package perl.x86_64 4:5.14.2-211.fc17 will be installed\n" "--> Processing Dependency: perl-libs = 4:5.14.2-211.fc17 for package: 4:perl-5.14.2-211.fc17.x86_64\n" "--> Processing Dependency: perl(threads::shared) >= 1.21 for package: 4:perl-5.14.2-211.fc17.x86_64\n" "--> Processing Dependency: perl(Socket) >= 1.3 for package: 4:perl-5.14.2-211.fc17.x86_64\n" "--> Processing Dependency: perl(Scalar::Util) >= 1.10 for package: 4:perl-5.14.2-211.fc17.x86_64\n" "--> Processing Dependency: perl(File::Spec) >= 0.8 for package: 4:perl-5.14.2-211.fc17.x86_64\n" "--> Processing Dependency: perl-macros for package: 4:perl-5.14.2-211.fc17.x86_64\n" "--> Processing Dependency: perl-libs for package: 4:perl-5.14.2-211.fc17.x86_64\n" "--> Processing Dependency: perl(threads::shared) for package: 4:perl-5.14.2-211.fc17.x86_64\n" "--> Processing Dependency: perl(threads) for package: 4:perl-5.14.2-211.fc17.x86_64\n" "--> Processing Dependency: perl(Socket) for package: 4:perl-5.14.2-211.fc17.x86_64\n" "--> Processing Dependency: perl(Scalar::Util) for package: 4:perl-5.14.2-211.fc17.x86_64\n" "--> Processing Dependency: perl(Pod::Simple) for package: 4:perl-5.14.2-211.fc17.x86_64\n" "--> Processing Dependency: perl(Module::Pluggable) for package: 4:perl-5.14.2-211.fc17.x86_64\n" "--> Processing Dependency: perl(List::Util) for package: 4:perl-5.14.2-211.fc17.x86_64\n" "--> Processing Dependency: perl(File::Spec::Unix) for package: 4:perl-5.14.2-211.fc17.x86_64\n" "--> Processing Dependency: perl(File::Spec::Functions) for package: 4:perl-5.14.2-211.fc17.x86_64\n" "--> Processing Dependency: perl(File::Spec) for package: 4:perl-5.14.2-211.fc17.x86_64\n" "--> Processing Dependency: perl(Cwd) for package: 4:perl-5.14.2-211.fc17.x86_64\n" "--> Processing Dependency: perl(Carp) for package: 4:perl-5.14.2-211.fc17.x86_64\n" "--> Processing Dependency: libperl.so()(64bit) for package: 4:perl-5.14.2-211.fc17.x86_64\n" "---> Package resource-agents.x86_64 0:3.9.2-2.fc17.1 will be installed\n" "--> Processing Dependency: /usr/sbin/rpc.nfsd for package: resource-agents-3.9.2-2.fc17.1.x86_64\n" "--> Processing Dependency: /usr/sbin/rpc.mountd for package: resource-agents-3.9.2-2.fc17.1.x86_64\n" "--> Processing Dependency: /usr/sbin/ethtool for package: resource-agents-3.9.2-2.fc17.1.x86_64\n" "--> Processing Dependency: /sbin/rpc.statd for package: resource-agents-3.9.2-2.fc17.1.x86_64\n" "--> Processing Dependency: /sbin/quotaon for package: resource-agents-3.9.2-2.fc17.1.x86_64\n" "--> Processing Dependency: /sbin/quotacheck for package: resource-agents-3.9.2-2.fc17.1.x86_64\n" "--> Processing Dependency: /sbin/mount.nfs4 for package: resource-agents-3.9.2-2.fc17.1.x86_64\n" "--> Processing Dependency: /sbin/mount.nfs for package: resource-agents-3.9.2-2.fc17.1.x86_64\n" "--> Processing Dependency: /sbin/mount.cifs for package: resource-agents-3.9.2-2.fc17.1.x86_64\n" "--> Processing Dependency: /sbin/fsck.xfs for package: resource-agents-3.9.2-2.fc17.1.x86_64\n" "--> Processing Dependency: libnet.so.1()(64bit) for package: resource-agents-3.9.2-2.fc17.1.x86_64\n" "--> Running transaction check\n" "---> Package OpenIPMI-libs.x86_64 0:2.0.18-13.fc17 will be installed\n" "---> Package cifs-utils.x86_64 0:5.3-2.fc17 will be installed\n" "--> Processing Dependency: libtalloc.so.2(TALLOC_2.0.2)(64bit) for package: cifs-utils-5.3-2.fc17.x86_64\n" "--> Processing Dependency: keyutils for package: cifs-utils-5.3-2.fc17.x86_64\n" "--> Processing Dependency: libwbclient.so.0()(64bit) for package: cifs-utils-5.3-2.fc17.x86_64\n" "--> Processing Dependency: libtalloc.so.2()(64bit) for package: cifs-utils-5.3-2.fc17.x86_64\n" "---> Package ethtool.x86_64 2:3.2-2.fc17 will be installed\n" "---> Package libibverbs.x86_64 0:1.1.6-2.fc17 will be installed\n" "---> Package libnet.x86_64 0:1.1.5-3.fc17 will be installed\n" "---> Package librdmacm.x86_64 0:1.0.15-1.fc17 will be installed\n" "---> Package libtasn1.x86_64 0:2.12-1.fc17 will be installed\n" "---> Package nfs-utils.x86_64 1:1.2.5-12.fc17 will be installed\n" "--> Processing Dependency: rpcbind for package: 1:nfs-utils-1.2.5-12.fc17.x86_64\n" "--> Processing Dependency: libtirpc for package: 1:nfs-utils-1.2.5-12.fc17.x86_64\n" "--> Processing Dependency: libnfsidmap for package: 1:nfs-utils-1.2.5-12.fc17.x86_64\n" "--> Processing Dependency: libgssglue.so.1(libgssapi_CITI_2)(64bit) for package: 1:nfs-utils-1.2.5-12.fc17.x86_64\n" "--> Processing Dependency: libgssglue for package: 1:nfs-utils-1.2.5-12.fc17.x86_64\n" "--> Processing Dependency: libevent for package: 1:nfs-utils-1.2.5-12.fc17.x86_64\n" "--> Processing Dependency: libtirpc.so.1()(64bit) for package: 1:nfs-utils-1.2.5-12.fc17.x86_64\n" "--> Processing Dependency: libnfsidmap.so.0()(64bit) for package: 1:nfs-utils-1.2.5-12.fc17.x86_64\n" "--> Processing Dependency: libgssglue.so.1()(64bit) for package: 1:nfs-utils-1.2.5-12.fc17.x86_64\n" "--> Processing Dependency: libevent-2.0.so.5()(64bit) for package: 1:nfs-utils-1.2.5-12.fc17.x86_64\n" "---> Package p11-kit.x86_64 0:0.12-1.fc17 will be installed\n" "---> Package perl-Carp.noarch 0:1.22-2.fc17 will be installed\n" "---> Package perl-Module-Pluggable.noarch 1:3.90-211.fc17 will be installed\n" "---> Package perl-PathTools.x86_64 0:3.33-211.fc17 will be installed\n" "---> Package perl-Pod-Simple.noarch 1:3.16-211.fc17 will be installed\n" "--> Processing Dependency: perl(Pod::Escapes) >= 1.04 for package: 1:perl-Pod-Simple-3.16-211.fc17.noarch\n" "---> Package perl-Scalar-List-Utils.x86_64 0:1.25-1.fc17 will be installed\n" "---> Package perl-Socket.x86_64 0:2.001-1.fc17 will be installed\n" "---> Package perl-TimeDate.noarch 1:1.20-6.fc17 will be installed\n" "---> Package perl-libs.x86_64 4:5.14.2-211.fc17 will be installed\n" "---> Package perl-macros.x86_64 4:5.14.2-211.fc17 will be installed\n" "---> Package perl-threads.x86_64 0:1.86-2.fc17 will be installed\n" "---> Package perl-threads-shared.x86_64 0:1.40-2.fc17 will be installed\n" "---> Package quota.x86_64 1:4.00-3.fc17 will be installed\n" "--> Processing Dependency: quota-nls = 1:4.00-3.fc17 for package: 1:quota-4.00-3.fc17.x86_64\n" "--> Processing Dependency: tcp_wrappers for package: 1:quota-4.00-3.fc17.x86_64\n" "---> Package xfsprogs.x86_64 0:3.1.8-1.fc17 will be installed\n" "--> Running transaction check\n" "---> Package keyutils.x86_64 0:1.5.5-2.fc17 will be installed\n" "---> Package libevent.x86_64 0:2.0.14-2.fc17 will be installed\n" "---> Package libgssglue.x86_64 0:0.3-1.fc17 will be installed\n" "---> Package libnfsidmap.x86_64 0:0.25-1.fc17 will be installed\n" "---> Package libtalloc.x86_64 0:2.0.7-4.fc17 will be installed\n" "---> Package libtirpc.x86_64 0:0.2.2-2.1.fc17 will be installed\n" "---> Package libwbclient.x86_64 1:3.6.3-81.fc17.1 will be installed\n" "---> Package perl-Pod-Escapes.noarch 1:1.04-211.fc17 will be installed\n" "---> Package quota-nls.noarch 1:4.00-3.fc17 will be installed\n" "---> Package rpcbind.x86_64 0:0.2.0-16.fc17 will be installed\n" "---> Package tcp_wrappers.x86_64 0:7.6-69.fc17 will be installed\n" "--> Finished Dependency Resolution\n" "\n" "Dependencies Resolved\n" "\n" "=====================================================================================\n" " Package Arch Version Repository Size\n" "=====================================================================================\n" "Installing:\n" " corosync x86_64 1.99.9-1.fc17 updates-testing 159 k\n" " pacemaker x86_64 1.1.7-2.fc17 updates-testing 362 k\n" "Installing for dependencies:\n" " OpenIPMI-libs x86_64 2.0.18-13.fc17 fedora 466 k\n" " cifs-utils x86_64 5.3-2.fc17 updates-testing 66 k\n" " cluster-glue x86_64 1.0.6-9.fc17.1 fedora 229 k\n" " cluster-glue-libs x86_64 1.0.6-9.fc17.1 fedora 121 k\n" " corosynclib x86_64 1.99.9-1.fc17 updates-testing 96 k\n" " ethtool x86_64 2:3.2-2.fc17 fedora 94 k\n" " gnutls x86_64 2.12.17-1.fc17 fedora 385 k\n" " keyutils x86_64 1.5.5-2.fc17 fedora 49 k\n" " libevent x86_64 2.0.14-2.fc17 fedora 160 k\n" " libgssglue x86_64 0.3-1.fc17 fedora 24 k\n" " libibverbs x86_64 1.1.6-2.fc17 fedora 44 k\n" " libnet x86_64 1.1.5-3.fc17 fedora 54 k\n" " libnfsidmap x86_64 0.25-1.fc17 fedora 34 k\n" " libqb x86_64 0.11.1-1.fc17 updates-testing 68 k\n" " librdmacm x86_64 1.0.15-1.fc17 fedora 27 k\n" " libtalloc x86_64 2.0.7-4.fc17 fedora 22 k\n" " libtasn1 x86_64 2.12-1.fc17 updates-testing 319 k\n" " libtirpc x86_64 0.2.2-2.1.fc17 fedora 78 k\n" " libtool-ltdl x86_64 2.4.2-3.fc17 fedora 45 k\n" " libwbclient x86_64 1:3.6.3-81.fc17.1 updates-testing 68 k\n" " libxslt x86_64 1.1.26-9.fc17 fedora 416 k\n" " net-snmp-libs x86_64 1:5.7.1-4.fc17 fedora 713 k\n" " nfs-utils x86_64 1:1.2.5-12.fc17 fedora 311 k\n" " p11-kit x86_64 0.12-1.fc17 updates-testing 36 k\n" " pacemaker-cli x86_64 1.1.7-2.fc17 updates-testing 368 k\n" " pacemaker-cluster-libs x86_64 1.1.7-2.fc17 updates-testing 77 k\n" " pacemaker-libs x86_64 1.1.7-2.fc17 updates-testing 322 k\n" " perl x86_64 4:5.14.2-211.fc17 fedora 10 M\n" " perl-Carp noarch 1.22-2.fc17 fedora 17 k\n" " perl-Module-Pluggable noarch 1:3.90-211.fc17 fedora 47 k\n" " perl-PathTools x86_64 3.33-211.fc17 fedora 105 k\n" " perl-Pod-Escapes noarch 1:1.04-211.fc17 fedora 40 k\n" " perl-Pod-Simple noarch 1:3.16-211.fc17 fedora 223 k\n" " perl-Scalar-List-Utils x86_64 1.25-1.fc17 updates-testing 33 k\n" " perl-Socket x86_64 2.001-1.fc17 updates-testing 44 k\n" " perl-TimeDate noarch 1:1.20-6.fc17 fedora 43 k\n" " perl-libs x86_64 4:5.14.2-211.fc17 fedora 628 k\n" " perl-macros x86_64 4:5.14.2-211.fc17 fedora 32 k\n" " perl-threads x86_64 1.86-2.fc17 fedora 47 k\n" " perl-threads-shared x86_64 1.40-2.fc17 fedora 36 k\n" " quota x86_64 1:4.00-3.fc17 fedora 160 k\n" " quota-nls noarch 1:4.00-3.fc17 fedora 74 k\n" " resource-agents x86_64 3.9.2-2.fc17.1 fedora 466 k\n" " rpcbind x86_64 0.2.0-16.fc17 fedora 52 k\n" " tcp_wrappers x86_64 7.6-69.fc17 fedora 72 k\n" " xfsprogs x86_64 3.1.8-1.fc17 updates-testing 715 k\n" "\n" "Transaction Summary\n" "=====================================================================================\n" "Install 2 Packages (+46 Dependent packages)\n" "\n" "Total download size: 18 M\n" "Installed size: 59 M\n" "Downloading Packages:\n" "(1/48): OpenIPMI-libs-2.0.18-13.fc17.x86_64.rpm | 466 kB 00:00\n" "warning: rpmts_HdrFromFdno: Header V3 RSA/SHA256 Signature, key ID 1aca3465: NOKEY\n" "Public key for OpenIPMI-libs-2.0.18-13.fc17.x86_64.rpm is not installed\n" "(2/48): cifs-utils-5.3-2.fc17.x86_64.rpm | 66 kB 00:01\n" "Public key for cifs-utils-5.3-2.fc17.x86_64.rpm is not installed\n" "(3/48): cluster-glue-1.0.6-9.fc17.1.x86_64.rpm | 229 kB 00:00\n" "(4/48): cluster-glue-libs-1.0.6-9.fc17.1.x86_64.rpm | 121 kB 00:00\n" "(5/48): corosync-1.99.9-1.fc17.x86_64.rpm | 159 kB 00:01\n" "(6/48): corosynclib-1.99.9-1.fc17.x86_64.rpm | 96 kB 00:00\n" "(7/48): ethtool-3.2-2.fc17.x86_64.rpm | 94 kB 00:00\n" "(8/48): gnutls-2.12.17-1.fc17.x86_64.rpm | 385 kB 00:00\n" "(9/48): keyutils-1.5.5-2.fc17.x86_64.rpm | 49 kB 00:00\n" "(10/48): libevent-2.0.14-2.fc17.x86_64.rpm | 160 kB 00:00\n" "(11/48): libgssglue-0.3-1.fc17.x86_64.rpm | 24 kB 00:00\n" "(12/48): libibverbs-1.1.6-2.fc17.x86_64.rpm | 44 kB 00:00\n" "(13/48): libnet-1.1.5-3.fc17.x86_64.rpm | 54 kB 00:00\n" "(14/48): libnfsidmap-0.25-1.fc17.x86_64.rpm | 34 kB 00:00\n" "(15/48): libqb-0.11.1-1.fc17.x86_64.rpm | 68 kB 00:01\n" "(16/48): librdmacm-1.0.15-1.fc17.x86_64.rpm | 27 kB 00:00\n" "(17/48): libtalloc-2.0.7-4.fc17.x86_64.rpm | 22 kB 00:00\n" "(18/48): libtasn1-2.12-1.fc17.x86_64.rpm | 319 kB 00:02\n" "(19/48): libtirpc-0.2.2-2.1.fc17.x86_64.rpm | 78 kB 00:00\n" "(20/48): libtool-ltdl-2.4.2-3.fc17.x86_64.rpm | 45 kB 00:00\n" "(21/48): libwbclient-3.6.3-81.fc17.1.x86_64.rpm | 68 kB 00:00\n" "(22/48): libxslt-1.1.26-9.fc17.x86_64.rpm | 416 kB 00:00\n" "(23/48): net-snmp-libs-5.7.1-4.fc17.x86_64.rpm | 713 kB 00:01\n" "(24/48): nfs-utils-1.2.5-12.fc17.x86_64.rpm | 311 kB 00:00\n" "(25/48): p11-kit-0.12-1.fc17.x86_64.rpm | 36 kB 00:01\n" "(26/48): pacemaker-1.1.7-2.fc17.x86_64.rpm | 362 kB 00:02\n" "(27/48): pacemaker-cli-1.1.7-2.fc17.x86_64.rpm | 368 kB 00:02\n" "(28/48): pacemaker-cluster-libs-1.1.7-2.fc17.x86_64.rpm | 77 kB 00:00\n" "(29/48): pacemaker-libs-1.1.7-2.fc17.x86_64.rpm | 322 kB 00:01\n" "(30/48): perl-5.14.2-211.fc17.x86_64.rpm | 10 MB 00:15\n" "(31/48): perl-Carp-1.22-2.fc17.noarch.rpm | 17 kB 00:00\n" "(32/48): perl-Module-Pluggable-3.90-211.fc17.noarch.rpm | 47 kB 00:00\n" "(33/48): perl-PathTools-3.33-211.fc17.x86_64.rpm | 105 kB 00:00\n" "(34/48): perl-Pod-Escapes-1.04-211.fc17.noarch.rpm | 40 kB 00:00\n" "(35/48): perl-Pod-Simple-3.16-211.fc17.noarch.rpm | 223 kB 00:00\n" "(36/48): perl-Scalar-List-Utils-1.25-1.fc17.x86_64.rpm | 33 kB 00:01\n" "(37/48): perl-Socket-2.001-1.fc17.x86_64.rpm | 44 kB 00:00\n" "(38/48): perl-TimeDate-1.20-6.fc17.noarch.rpm | 43 kB 00:00\n" "(39/48): perl-libs-5.14.2-211.fc17.x86_64.rpm | 628 kB 00:00\n" "(40/48): perl-macros-5.14.2-211.fc17.x86_64.rpm | 32 kB 00:00\n" "(41/48): perl-threads-1.86-2.fc17.x86_64.rpm | 47 kB 00:00\n" "(42/48): perl-threads-shared-1.40-2.fc17.x86_64.rpm | 36 kB 00:00\n" "(43/48): quota-4.00-3.fc17.x86_64.rpm | 160 kB 00:00\n" "(44/48): quota-nls-4.00-3.fc17.noarch.rpm | 74 kB 00:00\n" "(45/48): resource-agents-3.9.2-2.fc17.1.x86_64.rpm | 466 kB 00:00\n" "(46/48): rpcbind-0.2.0-16.fc17.x86_64.rpm | 52 kB 00:00\n" "(47/48): tcp_wrappers-7.6-69.fc17.x86_64.rpm | 72 kB 00:00\n" "(48/48): xfsprogs-3.1.8-1.fc17.x86_64.rpm | 715 kB 00:03\n" "----------------------------------------------------------------------------------------\n" "Total 333 kB/s | 18 MB 00:55\n" "Retrieving key from file:///etc/pki/rpm-gpg/RPM-GPG-KEY-fedora-x86_64\n" "Importing GPG key 0x1ACA3465:\n" " Userid : \"Fedora (17) <fedora@fedoraproject.org>\"\n" " Fingerprint: cac4 3fb7 74a4 a673 d81c 5de7 50e9 4c99 1aca 3465\n" " Package : fedora-release-17-0.8.noarch (@anaconda-0)\n" " From : /etc/pki/rpm-gpg/RPM-GPG-KEY-fedora-x86_64\n" "Running Transaction Check\n" "Running Transaction Test\n" "Transaction Test Succeeded\n" "Running Transaction\n" " Installing : libqb-0.11.1-1.fc17.x86_64 1/48\n" " Installing : libtool-ltdl-2.4.2-3.fc17.x86_64 2/48\n" " Installing : cluster-glue-libs-1.0.6-9.fc17.1.x86_64 3/48\n" " Installing : libxslt-1.1.26-9.fc17.x86_64 4/48\n" " Installing : 1:perl-Pod-Escapes-1.04-211.fc17.noarch 5/48\n" " Installing : perl-threads-1.86-2.fc17.x86_64 6/48\n" " Installing : 4:perl-macros-5.14.2-211.fc17.x86_64 7/48\n" " Installing : 1:perl-Pod-Simple-3.16-211.fc17.noarch 8/48\n" " Installing : perl-Socket-2.001-1.fc17.x86_64 9/48\n" " Installing : perl-Carp-1.22-2.fc17.noarch 10/48\n" " Installing : 4:perl-libs-5.14.2-211.fc17.x86_64 11/48\n" " Installing : perl-threads-shared-1.40-2.fc17.x86_64 12/48\n" " Installing : perl-Scalar-List-Utils-1.25-1.fc17.x86_64 13/48\n" " Installing : 1:perl-Module-Pluggable-3.90-211.fc17.noarch 14/48\n" " Installing : perl-PathTools-3.33-211.fc17.x86_64 15/48\n" " Installing : 4:perl-5.14.2-211.fc17.x86_64 16/48\n" " Installing : libibverbs-1.1.6-2.fc17.x86_64 17/48\n" " Installing : keyutils-1.5.5-2.fc17.x86_64 18/48\n" " Installing : libgssglue-0.3-1.fc17.x86_64 19/48\n" " Installing : libtirpc-0.2.2-2.1.fc17.x86_64 20/48\n" " Installing : 1:net-snmp-libs-5.7.1-4.fc17.x86_64 21/48\n" " Installing : rpcbind-0.2.0-16.fc17.x86_64 22/48\n" " Installing : librdmacm-1.0.15-1.fc17.x86_64 23/48\n" " Installing : corosynclib-1.99.9-1.fc17.x86_64 24/48\n" " Installing : corosync-1.99.9-1.fc17.x86_64 25/48\n" "error reading information on service corosync: No such file or directory\n" " Installing : 1:perl-TimeDate-1.20-6.fc17.noarch 26/48\n" " Installing : 1:quota-nls-4.00-3.fc17.noarch 27/48\n" " Installing : tcp_wrappers-7.6-69.fc17.x86_64 28/48\n" " Installing : 1:quota-4.00-3.fc17.x86_64 29/48\n" " Installing : libnfsidmap-0.25-1.fc17.x86_64 30/48\n" " Installing : 1:libwbclient-3.6.3-81.fc17.1.x86_64 31/48\n" " Installing : libnet-1.1.5-3.fc17.x86_64 32/48\n" " Installing : 2:ethtool-3.2-2.fc17.x86_64 33/48\n" " Installing : libevent-2.0.14-2.fc17.x86_64 34/48\n" " Installing : 1:nfs-utils-1.2.5-12.fc17.x86_64 35/48\n" " Installing : libtalloc-2.0.7-4.fc17.x86_64 36/48\n" " Installing : cifs-utils-5.3-2.fc17.x86_64 37/48\n" " Installing : libtasn1-2.12-1.fc17.x86_64 38/48\n" " Installing : OpenIPMI-libs-2.0.18-13.fc17.x86_64 39/48\n" " Installing : cluster-glue-1.0.6-9.fc17.1.x86_64 40/48\n" " Installing : p11-kit-0.12-1.fc17.x86_64 41/48\n" " Installing : gnutls-2.12.17-1.fc17.x86_64 42/48\n" " Installing : pacemaker-libs-1.1.7-2.fc17.x86_64 43/48\n" " Installing : pacemaker-cluster-libs-1.1.7-2.fc17.x86_64 44/48\n" " Installing : pacemaker-cli-1.1.7-2.fc17.x86_64 45/48\n" " Installing : xfsprogs-3.1.8-1.fc17.x86_64 46/48\n" " Installing : resource-agents-3.9.2-2.fc17.1.x86_64 47/48\n" " Installing : pacemaker-1.1.7-2.fc17.x86_64 48/48\n" " Verifying : xfsprogs-3.1.8-1.fc17.x86_64 1/48\n" " Verifying : 1:net-snmp-libs-5.7.1-4.fc17.x86_64 2/48\n" " Verifying : corosync-1.99.9-1.fc17.x86_64 3/48\n" " Verifying : cluster-glue-1.0.6-9.fc17.1.x86_64 4/48\n" " Verifying : perl-PathTools-3.33-211.fc17.x86_64 5/48\n" " Verifying : p11-kit-0.12-1.fc17.x86_64 6/48\n" " Verifying : 1:perl-Pod-Simple-3.16-211.fc17.noarch 7/48\n" " Verifying : OpenIPMI-libs-2.0.18-13.fc17.x86_64 8/48\n" " Verifying : libtasn1-2.12-1.fc17.x86_64 9/48\n" " Verifying : perl-threads-1.86-2.fc17.x86_64 10/48\n" " Verifying : 1:perl-Pod-Escapes-1.04-211.fc17.noarch 11/48\n" " Verifying : pacemaker-1.1.7-2.fc17.x86_64 12/48\n" " Verifying : 4:perl-5.14.2-211.fc17.x86_64 13/48\n" " Verifying : gnutls-2.12.17-1.fc17.x86_64 14/48\n" " Verifying : perl-threads-shared-1.40-2.fc17.x86_64 15/48\n" " Verifying : 4:perl-macros-5.14.2-211.fc17.x86_64 16/48\n" " Verifying : 1:perl-Module-Pluggable-3.90-211.fc17.noarch 17/48\n" " Verifying : 1:nfs-utils-1.2.5-12.fc17.x86_64 18/48\n" " Verifying : cluster-glue-libs-1.0.6-9.fc17.1.x86_64 19/48\n" " Verifying : pacemaker-libs-1.1.7-2.fc17.x86_64 20/48\n" " Verifying : libtalloc-2.0.7-4.fc17.x86_64 21/48\n" " Verifying : libevent-2.0.14-2.fc17.x86_64 22/48\n" " Verifying : perl-Socket-2.001-1.fc17.x86_64 23/48\n" " Verifying : libgssglue-0.3-1.fc17.x86_64 24/48\n" " Verifying : perl-Carp-1.22-2.fc17.noarch 25/48\n" " Verifying : libtirpc-0.2.2-2.1.fc17.x86_64 26/48\n" " Verifying : 2:ethtool-3.2-2.fc17.x86_64 27/48\n" " Verifying : 4:perl-libs-5.14.2-211.fc17.x86_64 28/48\n" " Verifying : libxslt-1.1.26-9.fc17.x86_64 29/48\n" " Verifying : rpcbind-0.2.0-16.fc17.x86_64 30/48\n" " Verifying : librdmacm-1.0.15-1.fc17.x86_64 31/48\n" " Verifying : resource-agents-3.9.2-2.fc17.1.x86_64 32/48\n" " Verifying : 1:quota-4.00-3.fc17.x86_64 33/48\n" " Verifying : 1:perl-TimeDate-1.20-6.fc17.noarch 34/48\n" " Verifying : perl-Scalar-List-Utils-1.25-1.fc17.x86_64 35/48\n" " Verifying : libtool-ltdl-2.4.2-3.fc17.x86_64 36/48\n" " Verifying : pacemaker-cluster-libs-1.1.7-2.fc17.x86_64 37/48\n" " Verifying : cifs-utils-5.3-2.fc17.x86_64 38/48\n" " Verifying : libnet-1.1.5-3.fc17.x86_64 39/48\n" " Verifying : corosynclib-1.99.9-1.fc17.x86_64 40/48\n" " Verifying : libqb-0.11.1-1.fc17.x86_64 41/48\n" " Verifying : 1:libwbclient-3.6.3-81.fc17.1.x86_64 42/48\n" " Verifying : libnfsidmap-0.25-1.fc17.x86_64 43/48\n" " Verifying : tcp_wrappers-7.6-69.fc17.x86_64 44/48\n" " Verifying : keyutils-1.5.5-2.fc17.x86_64 45/48\n" " Verifying : libibverbs-1.1.6-2.fc17.x86_64 46/48\n" " Verifying : 1:quota-nls-4.00-3.fc17.noarch 47/48\n" " Verifying : pacemaker-cli-1.1.7-2.fc17.x86_64 48/48\n" "\n" "Installed:\n" " corosync.x86_64 0:1.99.9-1.fc17 pacemaker.x86_64 0:1.1.7-2.fc17\n" "\n" "Dependency Installed:\n" " OpenIPMI-libs.x86_64 0:2.0.18-13.fc17 cifs-utils.x86_64 0:5.3-2.fc17\n" " cluster-glue.x86_64 0:1.0.6-9.fc17.1 cluster-glue-libs.x86_64 0:1.0.6-9.fc17.1\n" " corosynclib.x86_64 0:1.99.9-1.fc17 ethtool.x86_64 2:3.2-2.fc17\n" " gnutls.x86_64 0:2.12.17-1.fc17 keyutils.x86_64 0:1.5.5-2.fc17\n" " libevent.x86_64 0:2.0.14-2.fc17 libgssglue.x86_64 0:0.3-1.fc17\n" " libibverbs.x86_64 0:1.1.6-2.fc17 libnet.x86_64 0:1.1.5-3.fc17\n" " libnfsidmap.x86_64 0:0.25-1.fc17 libqb.x86_64 0:0.11.1-1.fc17\n" " librdmacm.x86_64 0:1.0.15-1.fc17 libtalloc.x86_64 0:2.0.7-4.fc17\n" " libtasn1.x86_64 0:2.12-1.fc17 libtirpc.x86_64 0:0.2.2-2.1.fc17\n" " libtool-ltdl.x86_64 0:2.4.2-3.fc17 libwbclient.x86_64 1:3.6.3-81.fc17.1\n" " libxslt.x86_64 0:1.1.26-9.fc17 net-snmp-libs.x86_64 1:5.7.1-4.fc17\n" " nfs-utils.x86_64 1:1.2.5-12.fc17 p11-kit.x86_64 0:0.12-1.fc17\n" " pacemaker-cli.x86_64 0:1.1.7-2.fc17 pacemaker-cluster-libs.x86_64 0:1.1.7-2.fc17\n" " pacemaker-libs.x86_64 0:1.1.7-2.fc17 perl.x86_64 4:5.14.2-211.fc17\n" " perl-Carp.noarch 0:1.22-2.fc17 perl-Module-Pluggable.noarch 1:3.90-211.fc17\n" " perl-PathTools.x86_64 0:3.33-211.fc17 perl-Pod-Escapes.noarch 1:1.04-211.fc17\n" " perl-Pod-Simple.noarch 1:3.16-211.fc17 perl-Scalar-List-Utils.x86_64 0:1.25-1.fc17\n" " perl-Socket.x86_64 0:2.001-1.fc17 perl-TimeDate.noarch 1:1.20-6.fc17\n" " perl-libs.x86_64 4:5.14.2-211.fc17 perl-macros.x86_64 4:5.14.2-211.fc17\n" " perl-threads.x86_64 0:1.86-2.fc17 perl-threads-shared.x86_64 0:1.40-2.fc17\n" " quota.x86_64 1:4.00-3.fc17 quota-nls.noarch 1:4.00-3.fc17\n" " resource-agents.x86_64 0:3.9.2-2.fc17.1 rpcbind.x86_64 0:0.2.0-16.fc17\n" " tcp_wrappers.x86_64 0:7.6-69.fc17 xfsprogs.x86_64 0:3.1.8-1.fc17\n" "\n" "Complete!\n" "[root@pcmk-1 ~]#" msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "Now install the cluster software on the second node." msgstr "Installazione del software cluster" #. Tag: title #, fuzzy, no-c-format msgid "Install the Cluster Management Software" msgstr "Installazione del software cluster" #. Tag: para #, no-c-format msgid "The pcs cli command coupled with the pcs daemon creates a cluster management system capable of managing all aspects of the cluster stack across all nodes from a single location." msgstr "" #. Tag: programlisting #, no-c-format msgid "# yum install -y pcs" msgstr "" #. Tag: para #, no-c-format msgid "Make sure to install the pcs packages on both nodes." msgstr "" #. Tag: title #, no-c-format msgid "Setup" msgstr "Setup" #. Tag: title #, no-c-format msgid "Enable pcs Daemon" msgstr "" #. Tag: para #, no-c-format msgid "Before the cluster can be configured, the pcs daemon must be started and enabled to boot on startup on each node. This daemon works with the pcs cli command to manage syncing the corosync configuration across all the nodes in the cluster." msgstr "" #. Tag: para #, no-c-format msgid "Start and enable the daemon by issuing the following commands on each node." msgstr "" #. Tag: programlisting #, no-c-format msgid "" "# systemctl start pcsd.service\n" "# systemctl enable pcsd.service" msgstr "" #. Tag: para #, no-c-format msgid "Now we need a way for pcs to talk to itself on other nodes in the cluster. This is necessary in order to perform tasks such as syncing the corosync config, or starting/stopping the cluster on remote nodes" msgstr "" #. Tag: para #, no-c-format msgid "While pcs can be used locally without setting up these user accounts, this tutorial will make use of these remote access commands, so we will set a password for the hacluster user. Its probably best if password is consistent across all the nodes." msgstr "" #. Tag: para #, no-c-format msgid "As root, run:" msgstr "" #. Tag: programlisting #, no-c-format msgid "" "# passwd hacluster\n" "password:" msgstr "" #. Tag: para #, no-c-format msgid "Alternatively, to script this process or set the password on a different machine to the one you’re logged into, you can use the --stdin option for passwd:" msgstr "" #. Tag: programlisting #, no-c-format msgid "# ssh pcmk-2 -- 'echo redhat1 | passwd --stdin hacluster'" msgstr "" #. Tag: title #, no-c-format msgid "Notes on Multicast Address Assignment" msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "There are several subtle points that often deserve consideration when choosing/assigning multicast addresses. This information is borrowed from, the now defunct, http://web.archive.org/web/20101211210054/http://29west.com/docs/THPM/multicast-address-assignment.html" msgstr "Assicurarsi che i valori scelti non vadano in conflitto con qualsiasi altra configurazione cluster presente nella rete. Per consigli sulla scelta dell'indirizzo vedere http://www.29west.com/docs/THPM/multicast-address-assignment.html " #. Tag: para #, no-c-format msgid "Avoid 224.0.0.x" msgstr "" #. Tag: para #, no-c-format msgid "Traffic to addresses of the form 224.0.0.x is often flooded to all switch ports. This address range is reserved for link-local uses. Many routing protocols assume that all traffic within this range will be received by all routers on the network. Hence (at least all Cisco) switches flood traffic within this range. The flooding behavior overrides the normal selective forwarding behavior of a multicast-aware switch (e.g. IGMP snooping, CGMP, etc.)." msgstr "" #. Tag: para #, no-c-format msgid "Watch for 32:1 overlap" msgstr "" #. Tag: para #, no-c-format msgid "32 non-contiguous IP multicast addresses are mapped onto each Ethernet multicast address. A receiver that joins a single IP multicast group implicitly joins 31 others due to this overlap. Of course, filtering in the operating system discards undesired multicast traffic from applications, but NIC bandwidth and CPU resources are nonetheless consumed discarding it. The overlap occurs in the 5 high-order bits, so it’s best to use the 23 low-order bits to make distinct multicast streams unique. For example, IP multicast addresses in the range 239.0.0.0 to 239.127.255.255 all map to unique Ethernet multicast addresses. However, IP multicast address 239.128.0.0 maps to the same Ethernet multicast address as 239.0.0.0, 239.128.0.1 maps to the same Ethernet multicast address as 239.0.0.1, etc." msgstr "" #. Tag: para #, no-c-format msgid "Avoid x.0.0.y and x.128.0.y" msgstr "" #. Tag: para #, no-c-format msgid "Combining the above two considerations, it’s best to avoid using IP multicast addresses of the form x.0.0.y and x.128.0.y since they all map onto the range of Ethernet multicast addresses that are flooded to all switch ports." msgstr "" #. Tag: para #, no-c-format msgid "Watch for address assignment conflicts" msgstr "" #. Tag: para #, no-c-format msgid "IANA administers Internet multicast addresses. Potential conflicts with Internet multicast address assignments can be avoided by using GLOP addressing (AS required) or administratively scoped addresses. Such addresses can be safely used on a network connected to the Internet without fear of conflict with multicast sources originating on the Internet. Administratively scoped addresses are roughly analogous to the unicast address space for private internets. Site-local multicast addresses are of the form 239.255.x.y, but can grow down to 239.252.x.y if needed. Organization-local multicast addresses are of the form 239.192-251.x.y, but can grow down to 239.x.y.z if needed." msgstr "" #. Tag: para #, no-c-format msgid "For a more detailed treatment (57 pages!), see Cisco’s Guidelines for Enterprise IP Multicast Address Allocation paper." msgstr "" #. Tag: title #, no-c-format msgid "Configuring Corosync" msgstr "Configurare Corosync" #. Tag: para #, no-c-format msgid "In the past, at this point in the tutorial an explanation of how to configure and propagate corosync’s /etc/corosync.conf file would be necessary. Using pcs with the pcs daemon greatly simplifies this process by generating corosync.conf across all the nodes in the cluster with a single command. The only thing required to achieve this is to authenticate as the pcs user hacluster on one of the nodes in the cluster, and then issue the pcs cluster setup command with a list of all the node names in the cluster." msgstr "" #. Tag: programlisting #, no-c-format msgid "" "# pcs cluster auth pcmk-1 pcmk-2\n" "Username: hacluster\n" "Password:\n" "pcmk-1: Authorized\n" "pcmk-2: Authorized\n" "\n" "# pcs cluster setup mycluster pcmk-1 pcmk-2\n" "pcmk-1: Succeeded\n" "pcmk-2: Succeeded" msgstr "" #. Tag: para #, no-c-format msgid "That’s it. Corosync is configured across the cluster. If you received an authorization error for either of those commands, make sure you setup the hacluster user account and password on every node in the cluster with the same password." msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "The final /etc/corosync.conf configuration on each node should look something like the sample in Appendix B, Sample Corosync Configuration." msgstr "La configurazione finale dovrà assomigliare a quanto illustrato negli appendici." #. Tag: para #, no-c-format msgid "Pacemaker used to obtain membership and quorum from a custom Corosync plugin. This plugin also had the capability to start Pacemaker automatically when Corosync was started." msgstr "" #. Tag: para #, no-c-format msgid "Neither behavior is possible with Corosync 2.0 and beyond as support for plugins was removed." msgstr "" #. Tag: para #, no-c-format msgid "Instead, Pacemaker must be started as a separate job/initscript. Also, since Pacemaker made use of the plugin for message routing, a node using the plugin (Corosync prior to 2.0) cannot talk to one that isn’t (Corosync 2.0+)." msgstr "" #. Tag: para #, no-c-format msgid "Rolling upgrades between these versions are therefor not possible and an alternate strategy http://www.clusterlabs.org/doc/en-US/Pacemaker/1.1/html/Pacemaker_Explained/ap-upgrade.html must be used." msgstr "" #~ msgid "Burn the disk image to a DVD http://docs.fedoraproject.org/readme-burning-isos/en-US.html and boot from it. Or use the image to boot a virtual machine as I have done here. After clicking through the welcome screen, select your language and keyboard layout http://docs.fedoraproject.org/install-guide/f&DISTRO_VERSION;/en-US/html/s1-langselection-x86.html " #~ msgstr "Masterizzare l'immagine in un DVD http://docs.fedoraproject.org/readme-burning-isos/en-US.html ed avviare da questo media. Oppure utilizzare l'immagine per avviare una virtual machine come illustrato qui. Dopo aver cliccato sulla schermata di benvenuto, selezionare la propria lingua ed il layout della tastiera http://docs.fedoraproject.org/install-guide/f&DISTRO_VERSION;/en-US/html/s1-langselection-x86.html " #~ msgid "Fedora Installation - Welcome" #~ msgstr "Installazione di Fedora - Benvenuto" #~ msgid "Fedora Installation: Good choice" #~ msgstr "Installazione di Fedora: Buona scelta" #~ msgid "Fedora Installation - Storage Devices" #~ msgstr "Installazione di Fedora - Storage Devices" #~ msgid "Fedora Installation: Storage Devices" #~ msgstr "Installazione di Fedora: Storage Devices" #~ msgid "Fedora Installation - Hostname" #~ msgstr "Installazione di Fedora - Hostname" #~ msgid "Fedora Installation: Choose a hostname" #~ msgstr "Installazione di Fedora: Selezionare un hostname" #~ msgid "Fedora Installation - Installation Type" #~ msgstr "Installazione di Fedora - Tipo di installazione" #~ msgid "Fedora Installation: Choose an installation type" #~ msgstr "Installazione di Fedora: Selezionare un tipo di installazione" #~ msgid "By default, Fedora will give all the space to the / (aka. root) partition. Wel'll take some back so we can use DRBD." #~ msgstr "Di default, Fedora dedicherà tutto lo spazio alla partizione di root /.Questa verrà ridotta al fine di poter usare DRBD." #~ msgid "Fedora Installation - Default Partitioning" #~ msgstr "Installazione di Fedora - Partizionamento di default" #~ msgid "The finalized partition layout should look something like the diagram below." #~ msgstr "Lo schema di partizionamento finale dovrà somigliare a quanto illustrato nel diagramma sotto." #~ msgid "If you plan on following the DRBD or GFS2 portions of this guide, you should reserve at least 1Gb of space on each machine from which to create a shared volume." #~ msgstr "Se è nelle intenzioni di chi legge segure le parti di questa guida che trattano DRBD o GFS2 andrà riservato almeno 1Gb di spazio in ciascuna macchina da cui verrà tratto il volume condiviso." #~ msgid "Fedora Installation - Customize Partitioning" #~ msgstr "Installazione di Fedora - Personalizzazione delle partizioni" #~ msgid "Fedora Installation: Create a partition to use (later) for website data" #~ msgstr "Installazione di Fedora: Creare una partizione da usare (dopo) per i dati del sito web" #~ msgid "Fedora Installation - Bootloader" #~ msgstr "Installazione di Fedora - Bootloader" #~ msgid "Fedora Installation: Unless you have a strong reason not to, accept the default bootloader location" #~ msgstr "Installazione di Fedora: A meno che non si abbiano sensate ragioni per non farlo è bene accettare le impostazioni di default del bootloader" #~ msgid "Fedora Installation - Software" #~ msgstr "Installazione di Fedora - Software" #~ msgid "Fedora Installation: Software selection" #~ msgstr "Installazione di Fedora: Selezione del software" #~ msgid "Fedora Installation - Installing" #~ msgstr "Installazione di Fedora - Installazione" #~ msgid "Fedora Installation - Installation Complete" #~ msgstr "Installazione di Fedora - Installazione completata" #~ msgid "Fedora Installation: Stage 1, completed" #~ msgstr "Installazione di Fedora: Stage 1, completato" #~ msgid "Once the node reboots, follow the on screen instructions http://docs.fedoraproject.org/install-guide/f&DISTRO_VERSION;/en-US/html/ch-firstboot.html to create a system user and configure the time." #~ msgstr "Quano il nodo si riavvia seguire le istruzioni sullo schermo http://docs.fedoraproject.org/install-guide/f&DISTRO_VERSION;/en-US/html/ch-firstboot.html per creare un utenza di sistema e sistemare l`ora." #~ msgid "Fedora Installation - First Boot" #~ msgstr "Installazione di Fedora - Primo avvio" #~ msgid "Fedora Installation - Create Non-privileged User" #~ msgstr "Installazione di Fedora - Creazione utente non privilegiato" #~ msgid "Fedora Installation: Creating a non-privileged user, take note of the password, you'll need it soon" #~ msgstr "Installazione di Fedora: Nella creazione di un utente non privilegiato si prenda nota della password, presto servirà" #~ msgid "It is highly recommended to enable NTP on your cluster nodes. Doing so ensures all nodes agree on the current time and makes reading log files significantly easier." #~ msgstr "E' caldamente consigliato di abilitare NTP sui nodi del cluster, ci si assicurerà così che tutti i nodi siano settati sull'ora attuale e la lettura dei log sarà molto più semplice." #~ msgid "Fedora Installation - Date and Time" #~ msgstr "Installazione di Fedora - Data ed ora" #~ msgid "Fedora Installation: Enable NTP to keep the times on all your nodes consistent" #~ msgstr "Installazione di Fedora: Abilitare NTP per mantenere consistente l'ora su tutti i nodi" #~ msgid "Click through the next screens until you reach the login window. Click on the user you created and supply the password you indicated earlier." #~ msgstr "Cliccare su next fino alla comparsa della schermata di login. Cliccare sull'utente creato e fornire la password stabilita." #~ msgid "Fedora Installation - Customize Networking" #~ msgstr "Installazione di Fedora - Personalizzare la rete" #~ msgid "Fedora Installation: Click here to configure networking" #~ msgstr "Installazione di Fedora: Cliccare qui per configurare la rete" #~ msgid "Fedora Installation - Specify Network Preferences" #~ msgstr "Installazione di Fedora - Specificare le preferenze di rete" #~ msgid "Fedora Installation: Specify network settings for your machine, never choose DHCP" #~ msgstr "Installazione di Fedora: Specificare le preferenze di rete per la propria macchina, non selezionare mai DHCP" #~ msgid "Fedora Installation - Activate Networking" #~ msgstr "Installazione di Fedora - Attivare la rete" #~ msgid "Fedora Installation: Click the big green button to activate your changes" #~ msgstr "Installazione di Fedora: cliccare il grosso bottone verde per attivare le modifiche" #~ msgid "Fedora Installation - Bring up the Terminal" #~ msgstr "Installazione di Fedora - Aprire il terminale" #~ msgid "Fedora Installation: Down to business, fire up the command line" #~ msgstr "Installazione di Fedora: al lavoro, avviando la linea di comando" #~ msgid "Go to the terminal window you just opened and switch to the super user (aka. \"root\") account with the su command. You will need to supply the password you entered earlier during the installation process." #~ msgstr "Attraverso la finestra terminale appena aperta diventare super utente (\"root\") attraverso il comando su. Verrà richiesta la password richiesta in fase di installazione." #~ msgid "Note that the username (the text before the @ symbol) now indicates we’re running as the super user “root”." #~ msgstr "Notare che lo username (il testo che precede il simbolo @) ora indica che l'utente utilizzato è \"root\"." #~ msgid "You will need to reboot for the SELinux changes to take effect. Otherwise you will see something like this when you start corosync:" #~ msgstr "Sarà necessario riavviare per rendere effettive le modifiche a SELinux. In alterniva qualcosa di simile a questo apparirà all'avvio di corosync:" #~ msgid "Verify Connectivity by IP address" #~ msgstr "Verifica della connettività dall'indirizzo IP" #~ msgid "Set up /etc/hosts entries" #~ msgstr "Settaggio /etc/hosts" #~ msgid "Verify Connectivity by Hostname" #~ msgstr "Verifica della connettività attraverso l'hostname" #~ msgid "Now repeat on pcmk-2." #~ msgstr "Le stesse operazioni andranno ripetute su pcmk-2" #~ msgid "Choose a port number and multi-cast http://en.wikipedia.org/wiki/Multicast address. http://en.wikipedia.org/wiki/Multicast_address " #~ msgstr "Scegliere un numero di porta ed un indirizzo http://en.wikipedia.org/wiki/Multicast multi-cast. http://en.wikipedia.org/wiki/Multicast_address " #~ msgid "For this document, I have chosen port 4000 and used 226.94.1.1 as the multi-cast address." #~ msgstr "Per questo progetto è stata scelta la porta 4000 e l'indirizzo multi-cast 226.94.1.1." #~ msgid "Next we automatically determine the hosts address. By not using the full address, we make the configuration suitable to be copied to other nodes." #~ msgstr "A questo punto è possibile determinare automaticamente l'indirizzo degli host. Non utilizzando l'indirizzo completo la configurazione è copiabile sugli altri nodi." #~ msgid "Display and verify the configuration options" #~ msgstr "Visualizzazione e verifica delle opzioni di configurazione" #~ msgid "Once you’re happy with the chosen values, update the Corosync configuration" #~ msgstr "Una volta soddisfatti dei valori scelti si potrà aggiornare la configurazione di Corosync" #~ msgid "Finally, tell Corosync to start Pacemaker" #~ msgstr "Infine comunicare a Corosync di avviare Pacemaker" #~ msgid "Propagate the Configuration" #~ msgstr "Distribuire la configurazione" #~ msgid "Now we need to copy the changes so far to the other node:" #~ msgstr "Ora è necessario copiare le modifiche effettuate sinora all'altro nodo:" pacemaker-master/doc/Clusters_from_Scratch/it-IT/Ch-Intro.po000066400000000000000000000447231217637305600242770ustar00rootroot00000000000000# # AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: 0\n" "POT-Creation-Date: 2012-10-17T05:19:03\n" "PO-Revision-Date: 2010-07-14 14:42+0100\n" "Last-Translator: RaSca \n" "Language-Team: None\n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. Tag: title #, no-c-format msgid "Read-Me-First" msgstr "Leggimi-Prima" #. Tag: title #, no-c-format msgid "The Scope of this Document" msgstr "Scopo di questo documento" #. Tag: para #, no-c-format msgid "Computer clusters can be used to provide highly available services or resources. The redundancy of multiple machines is used to guard against failures of many types." msgstr "" #. Tag: para #, no-c-format msgid "This document will walk through the installation and setup of simple clusters using the Fedora distribution, version 17." msgstr "" #. Tag: para #, no-c-format msgid "The clusters described here will use Pacemaker and Corosync to provide resource management and messaging. Required packages and modifications to their configuration files are described along with the use of the Pacemaker command line tool for generating the XML used for cluster control." msgstr "" #. Tag: para #, no-c-format msgid "Pacemaker is a central component and provides the resource management required in these systems. This management includes detecting and recovering from the failure of various nodes, resources and services under its control." msgstr "" #. Tag: para #, no-c-format msgid "When more in depth information is required and for real world usage, please refer to the Pacemaker Explained manual." msgstr "" #. Tag: title #, no-c-format msgid "What Is Pacemaker?" msgstr "Cos'è Pacemaker?" #. Tag: para #, fuzzy, no-c-format msgid "Pacemaker is a cluster resource manager. It achieves maximum availability for your cluster services (aka. resources) by detecting and recovering from node and resource-level failures by making use of the messaging and membership capabilities provided by your preferred cluster infrastructure (either Corosync or Heartbeat)." msgstr "Pacemaker è un cluster resource manager. Ottiene la massima affidabilità per i servizi cluster (conosciuti come risorse) rilevando e ripristinando malfunziomenti di nodi e di risorse facendo uso delle capacità di messaging e membership fornite dalla tua infrastruttura cluster preferita (sia questa Corosync o Heartbeat)." #. Tag: para #, fuzzy, no-c-format msgid "Pacemaker’s key features include:" msgstr "Le caratteristiche di Pacemaker includono:" #. Tag: para #, no-c-format msgid "Detection and recovery of node and service-level failures" msgstr "Rilevazione e ripristino di malfunzionamenti di nodi e servizi" #. Tag: para #, no-c-format msgid "Storage agnostic, no requirement for shared storage" msgstr "Storage agnostic, non richiede uno storage condiviso" #. Tag: para #, no-c-format msgid "Resource agnostic, anything that can be scripted can be clustered" msgstr "Resource agnostic, tutto quello che può essere scriptato può essere clusterizzato" #. Tag: para #, fuzzy, no-c-format msgid "Supports STONITH for ensuring data integrity" msgstr "Supporto STONITH per garantire l'integrità dei dati" #. Tag: para #, no-c-format msgid "Supports large and small clusters" msgstr "Supporto a cluster grandi e piccoli" #. Tag: para #, fuzzy, no-c-format msgid "Supports both quorate and resource driven clusters" msgstr "Supporto a cluster grandi e piccoli" #. Tag: para #, no-c-format msgid "Supports practically any redundancy configuration" msgstr "" #. Tag: para #, no-c-format msgid "Automatically replicated configuration that can be updated from any node" msgstr "Configurazione replicata automaticamente che può essere aggiornata da qualsiasi nodo" #. Tag: para #, no-c-format msgid "Ability to specify cluster-wide service ordering, colocation and anti-colocation" msgstr "Capacità di specificare ordine, collocazione e anti-collocazione per i servizi lato cluster" #. Tag: para #, fuzzy, no-c-format msgid "Support for advanced service types" msgstr "Supporto per servizi di tipo avanzato" #. Tag: para #, no-c-format msgid "Clones: for services which need to be active on multiple nodes" msgstr "Cloni: per servizi che necessitano di essere attivi su nodi multipli" #. Tag: para #, no-c-format msgid "Multi-state: for services with multiple modes (eg. master/slave, primary/secondary)" msgstr "Muliti-state: per servizi con modi multipli (ad esempio master/slave, primary/secondary/" #. Tag: para #, fuzzy, no-c-format msgid "Unified, scriptable, cluster management tools." msgstr "cluster shell unificata e scriptabile" #. Tag: title #, no-c-format msgid "Pacemaker Architecture" msgstr "Architettura di Pacemaker" #. Tag: para #, no-c-format msgid "At the highest level, the cluster is made up of three pieces:" msgstr "Al livello più elevato il cluster è composto da tre componenti:" #. Tag: para #, fuzzy, no-c-format msgid "Non-cluster aware components (illustrated in green). These pieces include the resources themselves, scripts that start, stop and monitor them, and also a local daemon that masks the differences between the different standards these scripts implement." msgstr "Componenti non inerenti al cluster (illustrate in blu). In un cluster Pacemaker queste componenti includono non solo gli script che sanno come avviare, stoppare e monitorare le risorse, ma anche " #. Tag: para #, fuzzy, no-c-format msgid "Resource management Pacemaker provides the brain (illustrated in blue) that processes and reacts to events regarding the cluster. These events include nodes joining or leaving the cluster; resource events caused by failures, maintenance, scheduled activities; and other administrative actions. Pacemaker will compute the ideal state of the cluster and plot a path to achieve it after any of these events. This may include moving resources, stopping nodes and even forcing them offline with remote power switches." msgstr "Un cervello (illustrato in verde) che reagisce e processa gli eventi del cluster (nodi scomparsi o apparsi) e delle risorse (ad esempio il controllo delle anomalie) così come le modifiche effettuate dall'amministratore. In risposta a tutti questi eventi, Pacemaker elaborerà l'ideale stato del cluster ed il piano per renderlo effettivo. Questo potrebbe includere lo spostamento delle risorse, lo stop di nodi fino alla forzatura offline di questi attraverso la rimozione dell'alimentazione remota." #. Tag: para #, fuzzy, no-c-format msgid "Low level infrastructure Corosync provides reliable messaging, membership and quorum information about the cluster (illustrated in red)." msgstr "Infrastruttura core del cluster che rende disponibili le funzionalità di messaging e membership (illustrate in rosso)" #. Tag: title #, no-c-format msgid "Conceptual Stack Overview" msgstr "Panoramica concettuale dello Stack" #. Tag: phrase #, no-c-format msgid "Conceptual overview of the cluster stack" msgstr "Panoramica concettuale dello stack del cluster" #. Tag: para #, fuzzy, no-c-format msgid "When combined with Corosync, Pacemaker also supports popular open source cluster filesystems. Even though Pacemaker also supports Heartbeat, the filesystems need to use the stack for messaging and membership and Corosync seems to be what they’re standardizing on. Technically it would be possible for them to support Heartbeat as well, however there seems little interest in this." msgstr "Quando viene combianato con Corosync, Pacemaker supporta anche i popolari cluster filesystem opensource Sebbene Pacemaker supporti anche Heartbeat, i filesystem necessitano di usare uno stack di messaging e membership e Corosync sembra essere quello su cui questi si stanno standardizzando. Tecnicamente potrebbe essere possibile per questi supportare anche Heartbeat, ma sembra esserci poco interesse in merito alla questione. . Le recenti standardizzazioni all'interno della comunità del cluster filesystem hanno portato all'uso di un lock manager distribuito che utilizza Corosync per il supporto al messaging e Pacemaker per il membership (quali nodi sono vivi o morti) ed il fencing dei servizi." #. Tag: para #, no-c-format msgid "Due to recent standardization within the cluster filesystem community, they make use of a common distributed lock manager which makes use of Corosync for its messaging capabilities and Pacemaker for its membership (which nodes are up/down) and fencing services." msgstr "" #. Tag: title #, no-c-format msgid "The Pacemaker Stack" msgstr "Lo stack Pacemaker" #. Tag: phrase #, fuzzy, no-c-format msgid "The Pacemaker StackThe Pacemaker stack when running on Corosync" msgstr "Lo stack Pacemaker nell'esecuzione su Corosync" #. Tag: title #, no-c-format msgid "Internal Components" msgstr "Componenti interni" #. Tag: para #, no-c-format msgid "Pacemaker itself is composed of four key components (illustrated below in the same color scheme as the previous diagram):" msgstr "Pacemaker stesso è composto da quatto componenti chiave (illustrati sotto nello stesso schema di colori del diagramma precedente):" #. Tag: para #, no-c-format msgid "CIB (aka. Cluster Information Base)" msgstr "CIB (acronimo di come Cluster Information Base)" #. Tag: para #, no-c-format msgid "CRMd (aka. Cluster Resource Management daemon)" msgstr "CRMd (acronimo di Cluster Resource Management daemon)" #. Tag: para #, no-c-format msgid "PEngine (aka. PE or Policy Engine)" msgstr "PEngine (acronimo di Policy Engine)" #. Tag: para #, no-c-format msgid "STONITHd" msgstr "STONITHd" #. Tag: phrase #, no-c-format msgid "Subsystems of a Pacemaker cluster running on Corosync" msgstr "Sottosistemi di un cluster Pacemaker in esecuzione su Corosync" #. Tag: para #, fuzzy, no-c-format msgid "The CIB uses XML to represent both the cluster’s configuration and current state of all resources in the cluster. The contents of the CIB are automatically kept in sync across the entire cluster and are used by the PEngine to compute the ideal state of the cluster and how it should be achieved." msgstr "Il CIB utilizza XML per rappresentare sia l'attuale configurazione del cluster sia lo stato di tutte le risorse all'interno dello stesso. I contenuti del CIB sono automaticamente tenuti in sincronia in tutto il cluster e vengono utilizzati dal PEngine per elaborare lo stato ideale del cluster e come questo debba essere raggiunto." #. Tag: para #, fuzzy, no-c-format msgid "This list of instructions is then fed to the DC (Designated Co-ordinator). Pacemaker centralizes all cluster decision making by electing one of the CRMd instances to act as a master. Should the elected CRMd process, or the node it is on, fail… a new one is quickly established." msgstr "Questa lista di istruzioni viene inviata al DC (Designated Co-ordinator). Pacemaker centralizza tutte le decisioni in merito al cluster eleggendo una delle istanze di CRMd ad agire come master. Qualora il processo eletto CRMd o il nodo su cui questo è in esecuzione dovessero fallire, un nuovo DC viene rapidamente stabilito." #. Tag: para #, fuzzy, no-c-format msgid "The DC carries out the PEngine’s instructions in the required order by passing them to either the LRMd (Local Resource Management daemon) or CRMd peers on other nodes via the cluster messaging infrastructure (which in turn passes them on to their LRMd process)." msgstr "Il DC esegue le istruzioni inviategli dal PEngine nell'ordine richiesto passandole o al LRMd (Local Resource Management daemon) o ai CRMd in ascolto sugli altri nodi attraverso l'infrastruttura di messaging del cluster (che a loro volta passeranno le istruzioni ai proprio LRMd)." #. Tag: para #, no-c-format msgid "The peer nodes all report the results of their operations back to the DC and based on the expected and actual results, will either execute any actions that needed to wait for the previous one to complete, or abort processing and ask the PEngine to recalculate the ideal cluster state based on the unexpected results." msgstr "Gli altri nodi riferiscono i risultati delle loro operazioni al DC. Attraverso l'analisi dei risultati aspettati e di quelli attuali, i nodi eseguiranno qualsiasi azione necessaria per attendere il completamento della precedente oppure interromperanno il processo, richiedendo al PEngine di calcolare nuovamente lo stato ideale del cluster basandosi sui risulati inaspettati." #. Tag: para #, no-c-format msgid "In some cases, it may be necessary to power off nodes in order to protect shared data or complete resource recovery. For this Pacemaker comes with STONITHd. STONITH is an acronym for Shoot-The-Other-Node-In-The-Head and is usually implemented with a remote power switch. In Pacemaker, STONITH devices are modeled as resources (and configured in the CIB) to enable them to be easily monitored for failure, however STONITHd takes care of understanding the STONITH topology such that its clients simply request a node be fenced and it does the rest." msgstr "In alcuni casi, potrebbe essere necessario spegnere i nodi per preservare dati condifivi o completare il ripristino di una risorsa. Per questo in Pacemaker esiste STONITHd. STONITH è un acronimo per Shoot-The-Other-Node-In-The-Head e viene implementato tipicamente con un switch di potenza remoto. In Pacemaker i dispositivi STONITH sono modellati come risorse (e configurati all'interno del CIB) per facilitare il monitoraggio delle anomalie. STONITHd si prende cura di capire la topologia STONITH così che i suoi client debbano unicamente richiedere unicamente la morte di un nodo ed esso si preoccupi del resto." #. Tag: title #, no-c-format msgid "Types of Pacemaker Clusters" msgstr "Tipologia dei cluster Pacemaker" #. Tag: para #, no-c-format msgid "Pacemaker makes no assumptions about your environment, this allows it to support practically any redundancy configuration including Active/Active, Active/Passive, N+1, N+M, N-to-1 and N-to-N." msgstr "Pacemaker non fa alcuna ipotesi in merito all'ambiente operativo, questo consente di supportare praticamente qualsiasi configurazione ridondata come Active/Active, Active/Passive, N+1, N+M, N-to-1 e N-to-N." #. Tag: para #, no-c-format msgid "In this document we will focus on the setup of a highly available Apache web server with an Active/Passive cluster using DRBD and Ext4 to store data. Then, we will upgrade this cluster to Active/Active using GFS2." msgstr "" #. Tag: title #, no-c-format msgid "Active/Passive Redundancy" msgstr "Ridondanza Active/Passive" #. Tag: phrase #, fuzzy, no-c-format msgid "Two-node Active/Passive clusters using Pacemaker and DRBD are a cost-effective solution for many High Availability situations" msgstr "I cluster a due nodi Active/Passive che utilizzano Pacemaker e DRBD sono soluzioni con rapporto qualità-prezzo ottimale in molti ambiti di alta affidabilità." #. Tag: title #, no-c-format msgid "N to N Redundancy" msgstr "Ridondanza N a N" #. Tag: phrase #, fuzzy, no-c-format msgid "When shared storage is available, every node can potentially be used for failover. Pacemaker can even run multiple copies of services to spread out the workload" msgstr "Quando è disponibile uno storage condiviso ogni nodo può essere utilizzato per il failover. Pacemaker può anche eseguire copie multiple dei servizi per distribuire il carico di lavoro." #~ msgid "The purpose of this document is to definitively explain the concepts used to configure Pacemaker. To achieve this best, it will focus exclusively on the XML syntax used to configure the CIB." #~ msgstr "Lo scopo di questo documento è quello di spiegare in maniera definitiva i concetti utilizzati per configurare Pacemaker. Per ottenere il meglio, si focalizzera' esclusivamente sulla sintassi XML per configurare il CIB." #~ msgid "For those that are allergic to XML, Pacemaker comes with a cluster shell and a Python based GUI exists, however these tools will not be covered at all in this document It is hoped however, that having understood the concepts explained here, that the functionality of these tools will also be more readily understood. , precisely because they hide the XML." #~ msgstr "Per gli allergici ad XML, Pacemaker ha una cluster shell ed una GUI Python, ma questi tools non sono trattati nel presente documento Si spera comunque che una volta compresi i concetti qui esposti sarà più semplice comprendere anche questi tools. , proprio perché questi nascondono l'XML." #~ msgid "Additionally, this document is NOT a step-by-step how-to guide for configuring a specific clustering scenario. Although such guides exist, the purpose of this document is to provide an understanding of the building blocks that can be used to construct any type of Pacemaker cluster." #~ msgstr "Inoltre, questo documento NON E' un how-to passo-passo per configurare uno specifico scenario cluster. Sebbene questo tipo di guide esista, lo scopo di questo documento è quello di fornire la comprensione delle componenti che possono essere utilizzate per costruire qualsiasi cluster Pacemaker." #~ msgid "Supports both quorate and resource driven clusters" #~ msgstr "Supporto a cluster quorati e resource driven" #~ msgid "Supports practically any redundancy configuration" #~ msgstr "Supporto a praticamente qualsiasi configurazione ridondata" #~ msgid "Shared Failover" #~ msgstr "Failover condiviso" #~ msgid "By supporting many nodes, Pacemaker can dramatically reduce hardware costs by allowing several active/passive clusters to be combined and share a common backup node" #~ msgstr "Supportando più nodi, Pacemaker può ridurre drammaticamente i costi hardware consentendo a diversi cluster active/passive di combinare e condividere nodi di backup comuni" pacemaker-master/doc/Clusters_from_Scratch/it-IT/Ch-Shared-Storage.po000066400000000000000000000634101217637305600260060ustar00rootroot00000000000000# # AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: 0\n" "POT-Creation-Date: 2012-10-17T05:19:03\n" "PO-Revision-Date: 2010-08-03 16:41+0100\n" "Last-Translator: RaSca \n" "Language-Team: None\n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. Tag: title #, no-c-format msgid "Replicated Storage with DRBD" msgstr "Storage replicato con DRBD" #. Tag: title #, no-c-format msgid "Background" msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "Even if you’re serving up static websites, having to manually synchronize the contents of that website to all the machines in the cluster is not ideal. For dynamic websites, such as a wiki, it’s not even an option. Not everyone care afford network-attached storage but somehow the data needs to be kept in sync. Enter DRBD which can be thought of as network based RAID-1. See http://www.drbd.org/ for more details." msgstr "Anche se si sta servendo un sito con pagine statiche, dover sincronizzare manualmente i contenuti del sito su tutte le macchine nel cluster non è conveniente. Per i siti dinamici, come ad esempio un wiki, non è neanche possibile. Pur non disponendo di un NAS (Network Attached Storage) potrebbe essere necessario che in qualche modo i dati siano mantenuti in sincronia. E' qui che entra in gioco DRBD che può essere descritto come un Network RAID-1. Per ulteriori dettagli vedere http://www.drbd.org." #. Tag: title #, no-c-format msgid "Install the DRBD Packages" msgstr "Installare i pacchetti DRBD" #. Tag: para #, fuzzy, no-c-format msgid "Since its inclusion in the upstream 2.6.33 kernel, everything needed to use DRBD has shiped with Fedora since version 13. All you need to do is install it:" msgstr "Dalla sua inclusione dalla versione 2.6.33 del kernel, quanto necessario per utilizzare DRBD è fornito da &DISTRO; &DISTRO_VERSION;. Tutto ciò che va fatto è installare i pacchetti:" #. Tag: programlisting #, no-c-format msgid "# yum install -y drbd-pacemaker drbd-udev" msgstr "" #. Tag: literallayout #, no-c-format msgid "" "Loaded plugins: langpacks, presto, refresh-packagekit\n" "Resolving Dependencies\n" "--> Running transaction check\n" "---> Package drbd-pacemaker.x86_64 0:8.3.11-5.fc17 will be installed\n" "--> Processing Dependency: drbd-utils = 8.3.11-5.fc17 for package: drbd-pacemaker-8.3.11-5.fc17.x86_64\n" "---> Package drbd-udev.x86_64 0:8.3.11-5.fc17 will be installed\n" "--> Running transaction check\n" "---> Package drbd-utils.x86_64 0:8.3.11-5.fc17 will be installed\n" "--> Finished Dependency Resolution\n" "\n" "Dependencies Resolved\n" "\n" "======================================================================================\n" " Package Arch Version Repository Size\n" "======================================================================================\n" "Installing:\n" " drbd-pacemaker x86_64 8.3.11-5.fc17 updates-testing 22 k\n" " drbd-udev x86_64 8.3.11-5.fc17 updates-testing 6.4 k\n" "Installing for dependencies:\n" " drbd-utils x86_64 8.3.11-5.fc17 updates-testing 183 k\n" "\n" "Transaction Summary\n" "======================================================================================\n" "Install 2 Packages (+1 Dependent package)\n" "\n" "Total download size: 212 k\n" "Installed size: 473 k\n" "Downloading Packages:\n" "(1/3): drbd-pacemaker-8.3.11-5.fc17.x86_64.rpm | 22 kB 00:00\n" "(2/3): drbd-udev-8.3.11-5.fc17.x86_64.rpm | 6.4 kB 00:00\n" "(3/3): drbd-utils-8.3.11-5.fc17.x86_64.rpm | 183 kB 00:00\n" "--------------------------------------------------------------------------------------\n" "Total 293 kB/s | 212 kB 00:00\n" "Running Transaction Check\n" "Running Transaction Test\n" "Transaction Test Succeeded\n" "Running Transaction\n" " Installing : drbd-utils-8.3.11-5.fc17.x86_64 1/3\n" " Installing : drbd-pacemaker-8.3.11-5.fc17.x86_64 2/3\n" " Installing : drbd-udev-8.3.11-5.fc17.x86_64 3/3\n" " Verifying : drbd-pacemaker-8.3.11-5.fc17.x86_64 1/3\n" " Verifying : drbd-udev-8.3.11-5.fc17.x86_64 2/3\n" " Verifying : drbd-utils-8.3.11-5.fc17.x86_64 3/3\n" "\n" "Installed:\n" " drbd-pacemaker.x86_64 0:8.3.11-5.fc17 drbd-udev.x86_64 0:8.3.11-5.fc17\n" "\n" "Dependency Installed:\n" " drbd-utils.x86_64 0:8.3.11-5.fc17\n" "\n" "Complete!" msgstr "" #. Tag: title #, no-c-format msgid "Configure DRBD" msgstr "Configurare DRBD" #. Tag: para #, no-c-format msgid "Before we configure DRBD, we need to set aside some disk for it to use." msgstr "Prima di configurare DRBD è necessario definire a parte lo spazio che questo dovrà utilizzare." #. Tag: title #, no-c-format msgid "Create A Partition for DRBD" msgstr "Creare una partizione per DRBD" #. Tag: para #, no-c-format msgid "If you have more than 1Gb free, feel free to use it. For this guide however, 1Gb is plenty of space for a single html file and sufficient for later holding the GFS2 metadata." msgstr "Se si dispone di più di 1Gb liberi è bene servirsene. Negli scopi di questa guida 1Gb è fin troppo spazio per un file html e sufficiente per ospitare più avanti i metadata di GFS2." #. Tag: programlisting #, no-c-format msgid "" "# vgdisplay | grep -e Name - e Free\n" " VG Name vg_pcmk1\n" " Free PE / Size 31 / 992.00 MiB\n" "# lvs\n" " LV VG Attr LSize Pool Origin Data% Move Log Copy% Convert\n" " lv_root vg_pcmk1 -wi-ao-- 8.56g\n" " lv_swap vg_pcmk1 -wi-ao-- 960.00m\n" "# lvcreate -n drbd-demo -L 1G vg_pcmk1\n" "Logical volume \"drbd-demo\" created\n" "# lvs\n" " LV VG Attr LSize Pool Origin Data% Move Log Copy% Convert\n" " drbd-demo vg_pcmk1 -wi-a--- 1.00G\n" " lv_root vg_pcmk1 -wi-ao-- 8.56g\n" " lv_swap vg_pcmk1 -wi-ao-- 960.00m" msgstr "" #. Tag: para #, no-c-format msgid "Repeat this on the second node, be sure to use the same size partition." msgstr "La medesima operazione va ripetuta sul secondo nodo, avendo cura di utilizzare la stessa grandezza per la partizione." #. Tag: programlisting #, no-c-format msgid "" "# ssh pcmk-2 -- lvs\n" "LV VG Attr LSize Origin Snap% Move Log Copy% Convert\n" " lv_root vg_pcmk1 -wi-ao-- 8.56g\n" " lv_swap vg_pcmk1 -wi-ao-- 960.00m\n" "# ssh pcmk-2 -- lvcreate -n drbd-demo -L 1G vg_pcmk1\n" "Logical volume \"drbd-demo\" created\n" "# ssh pcmk-2 -- lvs\n" "LV VG Attr LSize Origin Snap% Move Log Copy% Convert\n" " drbd-demo vg_pcmk1 -wi-a--- 1.00G\n" " lv_root vg_pcmk1 -wi-ao-- 8.56g\n" " lv_swap vg_pcmk1 -wi-ao-- 960.00m" msgstr "" #. Tag: title #, no-c-format msgid "Write the DRBD Config" msgstr "Scrivere la configurazione DRBD" #. Tag: para #, fuzzy, no-c-format msgid "There is no series of commands for building a DRBD configuration, so simply copy the configuration below to /etc/drbd.conf" msgstr "Non esiste una serie di comandi per costruire una configurazione per DRBD, quindi è sufficiente la configurazione sottostante in /etc/drbd.conf" #. Tag: para #, no-c-format msgid "Detailed information on the directives used in this configuration (and other alternatives) is available from http://www.drbd.org/users-guide/ch-configure.html" msgstr "Informazioni dettagliate sulle direttive utilizzate in questa configurazione (e le alternative disponibili) è disponibile presso http://www.drbd.org/users-guide/ch-configure.html" #. Tag: para #, fuzzy, no-c-format msgid "Be sure to use the names and addresses of your nodes if they differ from the ones used in this guide." msgstr "Accertarsi di usare i nomi e gli indirizzi dei propri nodi se questi differiscono da quelli utilizzati in questa guida." #. Tag: literallayout #, no-c-format msgid "" "global {\n" " usage-count yes;\n" "}\n" "common {\n" " protocol C;\n" "}\n" "resource wwwdata {\n" " meta-disk internal;\n" " device /dev/drbd1;\n" " syncer {\n" " verify-alg sha1;\n" " }\n" " net {\n" " allow-two-primaries;\n" " }\n" " on pcmk-1 {\n" " disk /dev/vg_pcmk1/drbd-demo;\n" " address 192.168.122.101:7789;\n" " }\n" " on pcmk-2 {\n" " disk /dev/vg_pcmk1/drbd-demo;\n" " address 192.168.122.102:7789;\n" " }\n" "}" msgstr "" #. Tag: para #, no-c-format msgid "TODO: Explain the reason for the allow-two-primaries option" msgstr "TODO: Spiegare la ragione dell'opzione allow-two-primaries" #. Tag: title #, no-c-format msgid "Initialize and Load DRBD" msgstr "Inizializzare e caricare DRBD" #. Tag: para #, no-c-format msgid "With the configuration in place, we can now perform the DRBD initialization" msgstr "Sistemata la configurazione, è possibile inizializzare DRBD" #. Tag: programlisting #, no-c-format msgid "" "# drbdadm create-md wwwdata\n" "Writing meta data...\n" "initializing activity log\n" "NOT initialized bitmap\n" "New drbd meta data block successfully created.\n" "success" msgstr "" #. Tag: para #, no-c-format msgid "Now load the DRBD kernel module and confirm that everything is sane" msgstr "Caricando il modulo DRBD del kernel e verificando che tutto sia a posto" #. Tag: programlisting #, no-c-format msgid "" "# modprobe drbd\n" "# drbdadm up wwwdata\n" "# cat /proc/drbd\n" "version: 8.3.11 (api:88/proto:86-96)\n" "srcversion: 0D2B62DEDB020A425130935\n" "\n" " 1: cs:Connected ro:Secondary/Secondary ds:Inconsistent/Inconsistent C r-----\n" " ns:0 nr:0 dw:0 dr:0 al:0 bm:0 lo:0 pe:0 ua:0 ap:0 ep:1 wo:f oos:1015740" msgstr "" #. Tag: para #, no-c-format msgid "Repeat on the second node" msgstr "" #. Tag: programlisting #, no-c-format msgid "" "# ssh pcmk-2 -- drbdadm --force create-md wwwdata\n" "Writing meta data...\n" "initializing activity log\n" "NOT initialized bitmap\n" "New drbd meta data block successfully created.\n" "success\n" "# ssh pcmk-2 -- modprobe drbd\n" "WARNING: Deprecated config file /etc/modprobe.conf, all config files belong into /etc/modprobe.d/.\n" "# ssh pcmk-2 -- drbdadm up wwwdata\n" "# ssh pcmk-2 -- cat /proc/drbd\n" "version: 8.3.11 (api:88/proto:86-96)\n" "srcversion: 0D2B62DEDB020A425130935\n" "\n" " 1: cs:Connected ro:Secondary/Secondary ds:Inconsistent/Inconsistent C r-----\n" " ns:0 nr:0 dw:0 dr:0 al:0 bm:0 lo:0 pe:0 ua:0 ap:0 ep:1 wo:f oos:1015740" msgstr "" #. Tag: para #, no-c-format msgid "Now we need to tell DRBD which set of data to use. Since both sides contain garbage, we can run the following on pcmk-1:" msgstr "Ora va indicato a DRBD quale set di dati utilizzare. Dal momento che entrambe le parti contengono dati non necessari è possibile lanciare il seguente comando su pcmk-1:" #. Tag: programlisting #, no-c-format msgid "" "# drbdadm -- --overwrite-data-of-peer primary wwwdata\n" "# cat /proc/drbd\n" "version: 8.3.11 (api:88/proto:86-96)\n" "srcversion: 0D2B62DEDB020A425130935\n" "\n" " 1: cs:SyncSource ro:Primary/Secondary ds:UpToDate/Inconsistent C r-----\n" " ns:8064 nr:0 dw:0 dr:8728 al:0 bm:0 lo:0 pe:1 ua:0 ap:0 ep:1 wo:f oos:1007804\n" " [>....................] sync'ed: 0.9% (1007804/1015740)K\n" " finish: 0:12:35 speed: 1,320 (1,320) K/sec" msgstr "" #. Tag: para #, no-c-format msgid "After a while, the sync should finish and you’ll see:" msgstr "" #. Tag: programlisting #, no-c-format msgid "" "# cat /proc/drbd\n" "version: 8.3.11 (api:88/proto:86-96)\n" "srcversion: 0D2B62DEDB020A425130935\n" "\n" " 1: cs:Connected ro:Primary/Secondary ds:UpToDate/UpToDate C r-----\n" " ns:1015740 nr:0 dw:0 dr:1016404 al:0 bm:62 lo:0 pe:0 ua:0 ap:0 ep:1 wo:f oos:0" msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "pcmk-1 is now in the Primary state which allows it to be written to. Which means it’s a good point at which to create a filesystem and populate it with some data to serve up via our WebSite resource." msgstr "pcmk-1 è quindi in stato Primary, cioè scrivibile. Questo significa che è possibile crearvi un filesystem e popolarlo con dati da servire via la risorsa WebSite." #. Tag: title #, no-c-format msgid "Populate DRBD with Data" msgstr "Popolare DRBD con i dati" #. Tag: programlisting #, no-c-format msgid "" "# mkfs.ext4 /dev/drbd1\n" "mke2fs 1.42 (29-Nov-2011)\n" "Filesystem label=\n" "OS type: Linux\n" "Block size=4096 (log=2)\n" "Fragment size=4096 (log=2)\n" "Stride=0 blocks, Stripe width=0 blocks\n" "63488 inodes, 253935 blocks\n" "12696 blocks (5.00%) reserved for the super user\n" "First data block=0\n" "Maximum filesystem blocks=260046848\n" "8 block groups\n" "32768 blocks per group, 32768 fragments per group\n" "7936 inodes per group\n" "Superblock backups stored on blocks:\n" " 32768, 98304, 163840, 229376\n" "\n" "Allocating group tables: done\n" "Writing inode tables: done\n" "Creating journal (4096 blocks): done\n" "Writing superblocks and filesystem accounting information: done" msgstr "" #. Tag: para #, no-c-format msgid "Now mount the newly created filesystem so we can create our index file" msgstr "" #. Tag: programlisting #, no-c-format msgid "" "# mount /dev/drbd1 /mnt/\n" "# cat <<-END >/mnt/index.html\n" " <html>\n" " <body>My Test Site - drbd</body>\n" " </html>\n" "END\n" "# umount /dev/drbd1" msgstr "" #. Tag: title #, no-c-format msgid "Configure the Cluster for DRBD" msgstr "Configurare il cluster per DRBD" #. Tag: para #, no-c-format msgid "One handy feature pcs has is the ability to queue up several changes into a file and commit those changes atomically. To do this, start by populating the file with the current raw xml config from the cib. This can be done using the following command." msgstr "" #. Tag: programlisting #, no-c-format msgid "# pcs cluster cib drbd_cfg" msgstr "" #. Tag: para #, no-c-format msgid "Now using the pcs -f option, make changes to the configuration saved in the drbd_cfg file. These changes will not be seen by the cluster until the drbd_cfg file is pushed into the live cluster’s cib later on." msgstr "" #. Tag: screen #, no-c-format msgid "" "# pcs -f drbd_cfg resource create WebData ocf:linbit:drbd \\\n" " drbd_resource=wwwdata op monitor interval=60s\n" "# pcs -f drbd_cfg resource master WebDataClone WebData \\\n" " master-max=1 master-node-max=1 clone-max=2 clone-node-max=1 \\\n" " notify=true" msgstr "" #. Tag: programlisting #, no-c-format msgid "" "# pcs -f drbd_cfg resource show\n" " ClusterIP (ocf::heartbeat:IPaddr2) Started\n" " WebSite (ocf::heartbeat:apache) Started\n" " Master/Slave Set: WebDataClone [WebData]\n" " Stopped: [ WebData:0 WebData:1 ]" msgstr "" #. Tag: para #, no-c-format msgid "After you are satisfied with all the changes, you can commit all the changes at once by pushing the drbd_cfg file into the live cib." msgstr "" #. Tag: programlisting #, no-c-format msgid "" "# pcs cluster push cib drbd_cfg\n" "CIB updated\n" "\n" "# pcs status\n" "\n" "Last updated: Fri Sep 14 12:19:49 2012\n" "Last change: Fri Sep 14 12:19:13 2012 via cibadmin on pcmk-1\n" "Stack: corosync\n" "Current DC: pcmk-2 (2) - partition with quorum\n" "Version: 1.1.8-1.el7-60a19ed12fdb4d5c6a6b6767f52e5391e447fec0\n" "2 Nodes configured, unknown expected votes\n" "4 Resources configured.\n" "\n" "Online: [ pcmk-1 pcmk-2 ]\n" "\n" "Full list of resources:\n" "\n" " ClusterIP (ocf::heartbeat:IPaddr2): Started pcmk-1\n" " WebSite (ocf::heartbeat:apache): Started pcmk-1\n" " Master/Slave Set: WebDataClone [WebData]\n" " Masters: [ pcmk-1 ]\n" " Slaves: [ pcmk-2 ]" msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "TODO: Include details on adding a second DRBD resource" msgstr "Dettagli su come aggiungere una seconda risorsa DRBD" #. Tag: para #, no-c-format msgid "Now that DRBD is functioning we can configure a Filesystem resource to use it. In addition to the filesystem’s definition, we also need to tell the cluster where it can be located (only on the DRBD Primary) and when it is allowed to start (after the Primary was promoted)." msgstr "Ora che DRBD sta funzionando è possibile configurare una risorsa filesystem per utilizzarlo. In aggiunta alla definizione del filesystem si necessita inoltre di indicare al cluster dove questa sia localizzata (cioè solo sul nodo Primary di DRBD) e quando ad essa è consentito avviarsi (solo dopo che il nodo Primary è stato attivato)." #. Tag: para #, no-c-format msgid "We are going to take a shortcut when creating the resource this time though. Instead of explicitly saying we want the ocf:heartbeat:Filesystem script, we are only going to ask for Filesystem. We can do this because we know there is only one resource script named Filesystem available to pacemaker, and that pcs is smart enough to fill in the ocf:heartbeat portion for us correctly in the configuration. If there were multiple Filesystem scripts from different ocf providers, we would need to specify the exact one we wanted to use." msgstr "" #. Tag: para #, no-c-format msgid "Once again we will queue up our changes to a file and then push the new configuration to the cluster as the final step." msgstr "" #. Tag: screen #, no-c-format msgid "" "# pcs cluster cib fs_cfg\n" "# pcs -f fs_cfg resource create WebFS Filesystem \\\n" " device=\"/dev/drbd/by-res/wwwdata\" directory=\"/var/www/html\" \\\n" " fstype=\"ext4\"" msgstr "" #. Tag: programlisting #, no-c-format msgid "" "# pcs -f fs_cfg constraint colocation add WebFS WebDataClone INFINITY with-rsc-role=Master\n" "# pcs -f fs_cfg constraint order promote WebDataClone then start WebFS\n" "Adding WebDataClone WebFS (kind: Mandatory) (Options: first-action=promote then-action=start)" msgstr "" #. Tag: para #, no-c-format msgid "We also need to tell the cluster that Apache needs to run on the same machine as the filesystem and that it must be active before Apache can start." msgstr "Vi è inoltre la necessità di indicare al cluster che Apache necessità di funzionare sullo stessa macchina del filesystem e che questo debba essere attivato prima che Apache venga avviato." #. Tag: programlisting #, no-c-format msgid "" "# pcs -f fs_cfg constraint colocation add WebSite WebFS INFINITY\n" "# pcs -f fs_cfg constraint order WebFS then WebSite" msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "Now review the updated configuration." msgstr "E' tempo di revisionare la configurazione aggiornata:" #. Tag: programlisting #, no-c-format msgid "" "# pcs -f fs_cfg constraint\n" "Location Constraints:\n" "Ordering Constraints:\n" " start ClusterIP then start WebSite\n" " WebFS then WebSite\n" " promote WebDataClone then start WebFS\n" "Colocation Constraints:\n" " WebSite with ClusterIP\n" " WebFS with WebDataClone (with-rsc-role:Master)\n" " WebSite with WebFS\n" "\n" "# pcs -f fs_cfg resource show\n" " ClusterIP (ocf::heartbeat:IPaddr2) Started\n" " WebSite (ocf::heartbeat:apache) Started\n" " Master/Slave Set: WebDataClone [WebData]\n" " Masters: [ pcmk-1 ]\n" " Slaves: [ pcmk-2 ]\n" " WebFS (ocf::heartbeat:Filesystem) Stopped" msgstr "" #. Tag: para #, no-c-format msgid "After reviewing the new configuration, we again upload it and watch the cluster put it into effect." msgstr "Dopo la revisione della nuova configurazione questa va caricata e si potrà osservarla in azione all'interno del cluster." #. Tag: programlisting #, no-c-format msgid "" "# pcs cluster push cib fs_cfg\n" "CIB updated\n" "# pcs status\n" " Last updated: Fri Aug 10 12:47:01 2012\n" "\n" " Last change: Fri Aug 10 12:46:55 2012 via cibadmin on pcmk-1\n" " Stack: corosync\n" " Current DC: pcmk-1 (1) - partition with quorum\n" " Version: 1.1.8-1.el7-60a19ed12fdb4d5c6a6b6767f52e5391e447fec0\n" " 2 Nodes configured, unknown expected votes\n" " 5 Resources configured.\n" "\n" "Online: [ pcmk-1 pcmk-2 ]\n" "\n" "Full list of resources:\n" "\n" " ClusterIP (ocf::heartbeat:IPaddr2): Started pcmk-1\n" " WebSite (ocf::heartbeat:apache): Started pcmk-1\n" " Master/Slave Set: WebDataClone [WebData]\n" " Masters: [ pcmk-1 ]\n" " Slaves: [ pcmk-2 ]\n" " WebFS (ocf::heartbeat:Filesystem): Started pcmk-1" msgstr "" #. Tag: title #, no-c-format msgid "Testing Migration" msgstr "Testare la migrazione" #. Tag: para #, fuzzy, no-c-format msgid "We could shut down the active node again, but another way to safely simulate recovery is to put the node into what is called \"standby mode\". Nodes in this state tell the cluster that they are not allowed to run resources. Any resources found active there will be moved elsewhere. This feature can be particularly useful when updating the resources' packages." msgstr "E' possibile spegnere ancora il nodo attivo, ma un altro metodo per smulare il recovery in maniera salutare è quello di porre il nodo nel così detto \"standby mode\". I nodi in questo stato indicano al cluster che non sono in grado di ospitare risorse. Qualsiasi risorsa attiva verrà spostata altrove. Questa funzionalità può essere particolarmente utile durante gli aggiornamenti dei pacchetti delle risorse." #. Tag: para #, no-c-format msgid "Put the local node into standby mode and observe the cluster move all the resources to the other node. Note also that the node’s status will change to indicate that it can no longer host resources." msgstr "Mettendo il nodo locale in standby consentirà di osservare il cluster spostare tutte le risorse sull'altro nodo. Da notare inoltre come lo stato del nodo cambierà, indicando che non può più ospitare risorse." #. Tag: programlisting #, no-c-format msgid "" "# pcs cluster standby pcmk-1\n" "# pcs status\n" "\n" "Last updated: Fri Sep 14 12:41:12 2012\n" "Last change: Fri Sep 14 12:41:08 2012 via crm_attribute on pcmk-1\n" "Stack: corosync\n" "Current DC: pcmk-1 (1) - partition with quorum\n" "Version: 1.1.8-1.el7-60a19ed12fdb4d5c6a6b6767f52e5391e447fec0\n" "2 Nodes configured, unknown expected votes\n" "5 Resources configured.\n" "\n" "Node pcmk-1 (1): standby\n" "Online: [ pcmk-2 ]\n" "\n" "Full list of resources:\n" "\n" "ClusterIP (ocf::heartbeat:IPaddr2): Started pcmk-2\n" "WebSite (ocf::heartbeat:apache): Started pcmk-2\n" " Master/Slave Set: WebDataClone [WebData]\n" " Masters: [ pcmk-2 ]\n" " Stopped: [ WebData:1 ]\n" "WebFS (ocf::heartbeat:Filesystem): Started pcmk-2" msgstr "" #. Tag: para #, no-c-format msgid "Once we’ve done everything we needed to on pcmk-1 (in this case nothing, we just wanted to see the resources move), we can allow the node to be a full cluster member again." msgstr "Fatto quanto necessario su pcmk-1 (in questo caso nulla, si è solo osservato le risorse spostarsi), è possibile consentire il nodo ad essere nuovamente parte integrante del cluster." #. Tag: programlisting #, no-c-format msgid "" "# pcs cluster unstandby pcmk-1\n" "# pcs status\n" "\n" "Last updated: Fri Sep 14 12:43:02 2012\n" "Last change: Fri Sep 14 12:42:57 2012 via crm_attribute on pcmk-1\n" "Stack: corosync\n" "Current DC: pcmk-1 (1) - partition with quorum\n" "Version: 1.1.8-1.el7-60a19ed12fdb4d5c6a6b6767f52e5391e447fec0\n" "2 Nodes configured, unknown expected votes\n" "5 Resources configured.\n" "\n" "Online: [ pcmk-1 pcmk-2 ]\n" "\n" "Full list of resources:\n" "\n" " ClusterIP (ocf::heartbeat:IPaddr2): Started pcmk-2\n" " WebSite (ocf::heartbeat:apache): Started pcmk-2\n" " Master/Slave Set: WebDataClone [WebData]\n" " Masters: [ pcmk-2 ]\n" " Slaves: [ pcmk-1 ]\n" " WebFS (ocf::heartbeat:Filesystem): Started pcmk-2" msgstr "" #. Tag: para #, no-c-format msgid "Notice that our resource stickiness settings prevent the services from migrating back to pcmk-1." msgstr "Notare come ora l'impostazione di stickiness delle risorse prevenga la migrazione dei servizi nuovamente verso pcmk-1." #~ msgid "One handy feature of the crm shell is that you can use it in interactive mode to make several changes atomically." #~ msgstr "Un comoda funzione della shell crm è quella di rendere interattivi comandi per effettuare diversi cambiamenti automatici." #~ msgid "First we launch the shell. The prompt will change to indicate you’re in interactive mode." #~ msgstr "Inizialmente va lanciata la shell. Il prompt cambierà, indicando l'accesso alla modalità interattiva." #~ msgid "Next we must create a working copy or the current configuration. This is where all our changes will go. The cluster will not see any of them until we say its ok. Notice again how the prompt changes, this time to indicate that we’re no longer looking at the live cluster." #~ msgstr "Successivamente è necessario creare una copia funzionante della configurazione attuale. Sarà qui che i cambiamenti verranno effettuati. Il cluster non vedrà nessun cambiamento finché non verrà data conferma da parte dell'utente. Da notare ancora una volta come il prompt cambia, in questo caso indicando che non si sta più osservando il cluster attivo." #~ msgid "Now we can create our DRBD clone and display the revised configuration." #~ msgstr "Ora è possibile creare il clone DRBD e visualizzare la configurazione revisionata." #~ msgid "Once we’re happy with the changes, we can tell the cluster to start using them and use crm_mon to check everything is functioning." #~ msgstr "Quando i cambiamenti saranno giudicati sufficienti sarà possibile indicare al cluster di iniziare ad usarli, ed utilizzare crm_mon per verificare che tutto stia funzionando." #~ msgid "Once again we’ll use the shell’s interactive mode" #~ msgstr "Ancora una volta verrà utilizzata la shell in modalità interattiva" pacemaker-master/doc/Clusters_from_Scratch/it-IT/Ch-Stonith.po000066400000000000000000000242631217637305600246310ustar00rootroot00000000000000# # AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: 0\n" "POT-Creation-Date: 2012-10-17T05:19:03\n" "PO-Revision-Date: 2010-08-04 11:42+0100\n" "Last-Translator: RaSca \n" "Language-Team: None\n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. Tag: title #, no-c-format msgid "Configure STONITH" msgstr "Configurare STONITH" #. Tag: title #, fuzzy, no-c-format msgid "What Is STONITH" msgstr "Perché STONITH è necessario" #. Tag: para #, fuzzy, no-c-format msgid "STONITH is an acronym for Shoot-The-Other-Node-In-The-Head and it protects your data from being corrupted by rogue nodes or concurrent access." msgstr "STONITH è l'acronimo di Shoot-The-Other-Node-In-The-Head e protegge i dati dalla corruzione derivante da accessi concorrenti incontrollati." #. Tag: para #, no-c-format msgid "Just because a node is unresponsive, this doesn’t mean it isn’t accessing your data. The only way to be 100% sure that your data is safe, is to use STONITH so we can be certain that the node is truly offline, before allowing the data to be accessed from another node." msgstr "Solo perché un nodo non è responsivo non significa che non stia accedendo ai dati. L'unica via per essere sicuri al 100% che i dati sono al sicuro è quella di utilizzare STONITH in modo da essere certi che il nodo sia effettivamente offline, prima di consentire ad altri nodi di accedere ai dati." #. Tag: para #, no-c-format msgid "STONITH also has a role to play in the event that a clustered service cannot be stopped. In this case, the cluster uses STONITH to force the whole node offline, thereby making it safe to start the service elsewhere." msgstr "STONITH gioca un ruolo importante anche nel caso in cui un servizio clusterizzato non può essere stoppato. In questo caso il cluster utilizza STONITH per forzare l'intero nodo offline, rendendo di fatto sicuro l'avvio del servizio altrove." #. Tag: title #, no-c-format msgid "What STONITH Device Should You Use" msgstr "Quale device STONITH andrebbe utilizzato" #. Tag: para #, no-c-format msgid "It is crucial that the STONITH device can allow the cluster to differentiate between a node failure and a network one." msgstr "E' cruciale che il device STONITH sia in grado di differenziare un guasto del nodo da un guasto di rete." #. Tag: para #, fuzzy, no-c-format msgid "The biggest mistake people make in choosing a STONITH device is to use remote power switch (such as many on-board IMPI controllers) that shares power with the node it controls. In such cases, the cluster cannot be sure if the node is really offline, or active and suffering from a network fault." msgstr "L'errore più grande commesso nello scegliere un device STONITH è di utilizzare un \"remote power switch\" (come molti IMPI onboard controller) che condivide l'alimentazione con il nodo che controlla. In questi casi, il cluster non può essere sicuro che il nodo sia realmente offline o attivo ma staccato dalla rete." #. Tag: para #, fuzzy, no-c-format msgid "Likewise, any device that relies on the machine being active (such as SSH-based \"devices\" used during testing) are inappropriate." msgstr "Allo stesso modo, ogni device che risiede su una macchina attiva (come il device basato su SSH utilizzato durante i test) risulta inappropriato." #. Tag: title #, no-c-format msgid "Configuring STONITH" msgstr "Configurare STONITH" #. Tag: para #, fuzzy, no-c-format msgid "Find the correct driver: pcs stonith list" msgstr "Individuare il driver corretto: stonith -L" #. Tag: para #, no-c-format msgid "Find the parameters associated with the device: pcs stonith describe <agent name>" msgstr "" #. Tag: para #, no-c-format msgid "Create a local config to make changes to pcs cluster cib stonith_cfg" msgstr "" #. Tag: para #, no-c-format msgid "Create the fencing resource using pcs -f stonith_cfg stonith create <stonith_id> <stonith device type> [stonith device options]" msgstr "" #. Tag: para #, no-c-format msgid "Set stonith-enable to true. pcs -f stonith_cfg property set stonith-enabled=true" msgstr "" #. Tag: para #, no-c-format msgid "If the device does not know how to fence nodes based on their uname, you may also need to set the special pcmk_host_map parameter. See man stonithd for details." msgstr "" #. Tag: para #, no-c-format msgid "If the device does not support the list command, you may also need to set the special pcmk_host_list and/or pcmk_host_check parameters. See man stonithd for details." msgstr "" #. Tag: para #, no-c-format msgid "If the device does not expect the victim to be specified with the port parameter, you may also need to set the special pcmk_host_argument parameter. See man stonithd for details." msgstr "" #. Tag: para #, no-c-format msgid "Commit the new configuration. pcs cluster push cib stonith_cfg" msgstr "" #. Tag: para #, no-c-format msgid "Once the stonith resource is running, you can test it by executing: stonith_admin --reboot nodename. Although you might want to stop the cluster on that machine first." msgstr "" #. Tag: title #, no-c-format msgid "Example" msgstr "Esempio" #. Tag: para #, fuzzy, no-c-format msgid "Assuming we have an chassis containing four nodes and an IPMI device active on 10.0.0.1, then we would chose the fence_ipmilan driver in step 2 and obtain the following list of parameters" msgstr "Assumendo di possedere un IBM BladeCenter contenente i due nodi e che l'interfaccia di gestione sia attiva su 192.168.122.31, verrà quindi scelto il driver external/ibmrsa, ottenendo la seguente lista di parametri" #. Tag: title #, no-c-format msgid "Obtaining a list of STONITH Parameters" msgstr "" #. Tag: programlisting #, no-c-format msgid "" "# pcs stonith describe fence_ipmilan\n" "Stonith options for: fence_ipmilan\n" " auth: IPMI Lan Auth type (md5, password, or none)\n" " ipaddr: IPMI Lan IP to talk to\n" " passwd: Password (if required) to control power on IPMI device\n" " passwd_script: Script to retrieve password (if required)\n" " lanplus: Use Lanplus\n" " login: Username/Login (if required) to control power on IPMI device\n" " action: Operation to perform. Valid operations: on, off, reboot, status, list, diag, monitor or metadata\n" " timeout: Timeout (sec) for IPMI operation\n" " cipher: Ciphersuite to use (same as ipmitool -C parameter)\n" " method: Method to fence (onoff or cycle)\n" " power_wait: Wait X seconds after on/off operation\n" " delay: Wait X seconds before fencing is started\n" " privlvl: Privilege level on IPMI device\n" " verbose: Verbose mode" msgstr "" #. Tag: para #, no-c-format msgid "from which we would create a STONITH resource fragment that might look like this" msgstr "" #. Tag: title #, no-c-format msgid "Sample STONITH Resource" msgstr "" #. Tag: screen #, no-c-format msgid "" "# pcs cluster cib stonith_cfg\n" "# pcs -f stonith_cfg stonith create impi-fencing fence_ipmilan \\\n" " pcmk_host_list=\"pcmk-1 pcmk-2\" ipaddr=10.0.0.1 login=testuser \\\n" " passwd=acd123 op monitor interval=60s" msgstr "" #. Tag: programlisting #, no-c-format msgid "" "# pcs -f stonith_cfg stonith\n" " impi-fencing (stonith:fence_ipmilan) Stopped" msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "And finally, since we disabled it earlier, we need to re-enable STONITH. At this point we should have the following configuration." msgstr "Ed infine, visto che era stato disabilitato in precedenza, è necessario riabilitare STONITH" #. Tag: programlisting #, no-c-format msgid "" "# pcs -f stonith_cfg property set stonith-enabled=true\n" "# pcs -f stonith_cfg property\n" "dc-version: 1.1.8-1.el7-60a19ed12fdb4d5c6a6b6767f52e5391e447fec0\n" "cluster-infrastructure: corosync\n" "no-quorum-policy: ignore\n" "stonith-enabled: true" msgstr "" #. Tag: para #, no-c-format msgid "Now push the configuration into the cluster." msgstr "" #. Tag: programlisting #, no-c-format msgid "# pcs cluster push cib stonith_cfg" msgstr "" #~ msgid "Since every device is different, the parameters needed to configure it will vary. To find out the parameters required by the device: stonith -t {type} -n" #~ msgstr "Dal momento che ogni device è diverso dagli altri, i parametri necessari a configurarlo saranno vari. Per individuare i parametri richiesti dal device: stonith -t {type} -n" #~ msgid "Hopefully the developers chose names that make sense, if not you can query for some additional information by finding an active cluster node and running:" #~ msgstr "Fortunatamente gli sviluppatori hanno scelto nomi che hanno senso, altrimenti è possibile ricavare informazioni aggiuntive recandosi su un nodo attivo del cluster e lanciando:" #~ msgid "The output should be XML formatted text containing additional parameter descriptions" #~ msgstr "L'output dovrebbe essere testo formattato in XML contenente parametri descrittori aggiuntivi" #~ msgid "Create a file called stonith.xml containing a primitive resource with a class of stonith, a type of {type} and a parameter for each of the values returned in step 2" #~ msgstr "Creare un file chiamato stonith.xml contenente una risorsa primitiva di classe stonith, un tipo {type} ed un parametro per ciascuno dei valori ricavati nello step 2" #~ msgid "Create a clone from the primitive resource if the device can shoot more than one node and supports multiple simultaneous connections." #~ msgstr "Creare un clone dalla risorsa primitiva se il device può sparare a più di un singolo nodo e supporta connessioni simultanee multiple." #~ msgid "Upload it into the CIB using cibadmin: cibadmin -C -o resources --xml-file stonith.xml" #~ msgstr "Caricare il file nel CIB utilizzando cibadmin: cibadmin -C -o resources --xml-file stonith.xml" #~ msgid "Assuming we know the username and password for the management interface, we would create a STONITH resource with the shell" #~ msgstr "Assumendo di conoscere lo username e la password per l'interfaccia di gestione, verrà creata una risorsa STONITH con la shell" pacemaker-master/doc/Clusters_from_Scratch/it-IT/Ch-Tools.po000066400000000000000000000164731217637305600243050ustar00rootroot00000000000000# # AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: 0\n" "POT-Creation-Date: 2012-10-17T05:19:03\n" "PO-Revision-Date: 2010-08-02 16:21+0100\n" "Last-Translator: RaSca \n" "Language-Team: None\n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. Tag: title #, fuzzy, no-c-format msgid "Pacemaker Tools" msgstr "Utilizzare i tool di Pacemaker" #. Tag: title #, no-c-format msgid "Using Pacemaker Tools" msgstr "Utilizzare i tool di Pacemaker" #. Tag: para #, no-c-format msgid "In the dark past, configuring Pacemaker required the administrator to read and write XML. In true UNIX style, there were also a number of different commands that specialized in different aspects of querying and updating the cluster." msgstr "Nell'oscuro passato configurare Pacemaer richiedeva all'amministratore di leggere e scrivere XML. In vero stile UNIX c'erano inoltre parecchi comandi differendi, specializzati in aspetti differenti di interrogazione ed aggiornamento del cluster." #. Tag: para #, no-c-format msgid "All of that has been greatly simplified with the creation of unified command-line shells (and GUIs) that hide all the messy XML scaffolding." msgstr "" #. Tag: para #, no-c-format msgid "These shells take all the individual aspects required for managing and configuring a cluster, and packs them into one simple to use command line tool." msgstr "" #. Tag: para #, no-c-format msgid "They even allow you to queue up several changes at once and commit them atomically." msgstr "" #. Tag: para #, no-c-format msgid "There are currently two command-line shells that people use, pcs and crmsh. This edition of Clusters from Scratch is based on pcs. Start by taking some time to familiarize yourself with what it can do." msgstr "" #. Tag: para #, no-c-format msgid "The two shells share many concepts but the scope, layout and syntax does differ, so make sure you read the version of this guide that corresponds to the software installed on your system." msgstr "" #. Tag: para #, no-c-format msgid "Since pcs has the ability to manage all aspects of the cluster (both corosync and pacemaker), it requires a specific cluster stack to be in use, (corosync 2.0 with votequorum + Pacemaker version >= 1.8)." msgstr "" #. Tag: programlisting #, no-c-format msgid "# pcs" msgstr "" #. Tag: literallayout #, no-c-format msgid "" "Control and configure pacemaker and corosync.\n" "\n" "Options:\n" " -h Display usage and exit\n" " -f file Perform actions on file instead of active CIB\n" "\n" "Commands:\n" " resource Manage cluster resources\n" " cluster Configure cluster options and nodes\n" " stonith Configure fence devices\n" " property Set pacemaker properties\n" " constraint Set resource constraints\n" " status View cluster status" msgstr "" #. Tag: para #, no-c-format msgid "As you can see, the different aspects of cluster management are broken up into categories: resource, cluster, stonith, property, constraint, and status. To discover the functionality available in each of these categories, one can issue the command pcs <category> help. Below is an example of all the options available under the status category." msgstr "" #. Tag: programlisting #, no-c-format msgid "# pcs status help" msgstr "" #. Tag: literallayout #, no-c-format msgid "" "Usage: pcs status [commands]...\n" "View current cluster and resource status\n" "Commands:\n" " status\n" " View all information about the cluster and resources\n" "\n" " status resources\n" " View current status of cluster resources\n" "\n" " status groups\n" " View currently configured groups and their resources\n" "\n" " status cluster\n" " View current cluster status\n" "\n" " status corosync\n" " View current corosync status\n" "\n" " status nodes [corosync]\n" " View current status of nodes from pacemaker, or if corosync is\n" " specified, print nodes currently configured in corosync\n" "\n" " status actions\n" " View failed actions\n" "\n" " status pcsd <node> ...\n" " Show the current status of pcsd on the specified nodes\n" "\n" " status xml\n" " View xml version of status (output from crm_mon -r -1 -X)" msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "Additionally, if you are interested in the Pacemaker version and supported cluster stack(s) available with your current Pacemaker installation, the pacemakerd --features option is available to you." msgstr "La versione ed il cluster stack supportati di Pacemaker sono inoltre disponibili attraverso l'opzione --version." #. Tag: programlisting #, no-c-format msgid "# pacemakerd --features" msgstr "" #. Tag: screen #, no-c-format msgid "" "Pacemaker 1.1.8 (Build: 434edfa)\n" " Supporting: generated-manpages agent-manpages ascii-docs publican-docs ncurses gcov libqb-logging libqb-ipc lha-fencing upstart systemd heartbeat corosync-native snmp" msgstr "" #. Tag: para #, no-c-format msgid "If the SNMP and/or email options are not listed, then Pacemaker was not built to support them. This may be by the choice of your distribution or the required libraries may not have been available. Please contact whoever supplied you with the packages for more details." msgstr "Se SNMP e/o le opzioni mail non sono listate allora Pacemaker non è stato compilato per supportare queste funzionalità. Potrebbe essere dovuto ad una scelta della distribuzione che si sta utilizzando oppure al fatto che le librerie necessarie non sono disponibili. In questo caso è bene contattare il fornitore dei pacchetti per avere maggiori dettagli." #~ msgid "Since Pacemaker 1.0, this has all changed and we have an integrated, scriptable, cluster shell that hides all the messy XML scaffolding. It even allows you to queue up several changes at once and commit them atomically." #~ msgstr "Con Pacemaker 1.0 tutto questo è cambiato ed ora esiste una cluster shell integrata e scriptabile che nasconde tutta la confusionaria impalcatura XML. Essa permette di accodare i diversi cambiamente in una sola volta ed applicarli automaticamente." #~ msgid "Take some time to familiarize yourself with what it can do." #~ msgstr "Va dedicato del tempo a familiarizzare con le peculiarità della shell." #~ msgid "The primary tool for monitoring the status of the cluster is crm_mon (also available as crm status). It can be run in a variety of modes and has a number of output options. To find out about any of the tools that come with Pacemaker, simply invoke them with the --help option or consult the included man pages. Both sets of output are created from the tool, and so will always be in sync with each other and the tool itself." #~ msgstr "Il principale tool per il monitoraggio dello stato è crm_mon (disponibile anche come crm status). Può essere lanciato in diverse modalità e con svariate tipologie di output. Per scoprire le funzionalità dei tool disponibili con Pacemaker è sufficiente invocarli con l'opzione --help oppure consultare le man page incluse. Entrambe i tipi di output sono creati dal tool e quindi saranno sempre sincronizzate l'una con l'altra, oltre che con il tool stesso." pacemaker-master/doc/Clusters_from_Scratch/it-IT/Ch-Verification.po000066400000000000000000000142751217637305600256250ustar00rootroot00000000000000# # AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: 0\n" "POT-Creation-Date: 2012-10-17T05:19:03\n" "PO-Revision-Date: 2010-08-02 16:00+0100\n" "Last-Translator: RaSca \n" "Language-Team: None\n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. Tag: title #, no-c-format msgid "Verify Cluster Installation" msgstr "Verifica dell'installazione del cluster" #. Tag: title #, no-c-format msgid "Start the Cluster" msgstr "" #. Tag: para #, no-c-format msgid "Now that corosync is configured, it is time to start the cluster. The command below will start corosync and pacemaker on both nodes in the cluster. If you are issuing the start command from a different node than the one you ran the pcs cluster auth command on earlier, you must authenticate on current node you are logged into before you will be allowed to start the cluster." msgstr "" #. Tag: programlisting #, no-c-format msgid "" "# pcs cluster start --all\n" "pcmk-1: Starting Cluster...\n" "pcmk-2: Starting Cluster..." msgstr "" #. Tag: para #, no-c-format msgid "An alternative to using the pcs cluster startall command is to issue either of the below commands on each node in the cluster by hand." msgstr "" #. Tag: programlisting #, no-c-format msgid "" "# pcs cluster start\n" "Starting Cluster..." msgstr "" #. Tag: para #, no-c-format msgid "or" msgstr "" #. Tag: programlisting #, no-c-format msgid "" "# systemctl start corosync.service\n" "# systemctl start pacemaker.service" msgstr "" #. Tag: title #, no-c-format msgid "Verify Corosync Installation" msgstr "Verifica dell'installazione di Corosync" #. Tag: para #, no-c-format msgid "The first thing to check is if cluster communication is happy, for that we use corosync-cfgtool." msgstr "" #. Tag: programlisting #, no-c-format msgid "" "# corosync-cfgtool -s\n" "Printing ring status.\n" "Local node ID 1\n" "RING ID 0\n" " id = 192.168.122.101\n" " status = ring 0 active with no faults" msgstr "" #. Tag: para #, no-c-format msgid "We can see here that everything appears normal with our fixed IP address, not a 127.0.0.x loopback address, listed as the id and no faults for the status." msgstr "" #. Tag: para #, no-c-format msgid "If you see something different, you might want to start by checking the node’s network, firewall and selinux configurations." msgstr "" #. Tag: para #, no-c-format msgid "Next we check the membership and quorum APIs:" msgstr "" #. Tag: programlisting #, no-c-format msgid "" "# corosync-cmapctl | grep members\n" "runtime.totem.pg.mrp.srp.members.1.ip (str) = r(0) ip(192.168.122.101)\n" "runtime.totem.pg.mrp.srp.members.1.join_count (u32) = 1\n" "runtime.totem.pg.mrp.srp.members.1.status (str) = joined\n" "runtime.totem.pg.mrp.srp.members.2.ip (str) = r(0) ip(192.168.122.102)\n" "runtime.totem.pg.mrp.srp.members.2.join_count (u32) = 1\n" "runtime.totem.pg.mrp.srp.members.2.status (str) = joined\n" "\n" "# pcs status corosync\n" "Membership information\n" " --------------------------\n" " Nodeid Votes Name\n" " 1 1 pcmk-1\n" " 2 1 pcmk-2" msgstr "" #. Tag: para #, no-c-format msgid "You should see both nodes have joined the cluster." msgstr "" #. Tag: para #, no-c-format msgid "All good!" msgstr "" #. Tag: title #, no-c-format msgid "Verify Pacemaker Installation" msgstr "Verifica dell'installazione di Pacemaker" #. Tag: para #, fuzzy, no-c-format msgid "Now that we have confirmed that Corosync is functional we can check the rest of the stack. Pacemaker has already been started, so verify the necessary processes are running." msgstr "Ora che è stato verificato come Corosync sia funzionante è quindi possibile controllare il resto dello stack." #. Tag: programlisting #, no-c-format msgid "" "# ps axf\n" " PID TTY STAT TIME COMMAND\n" " 2 ? S 0:00 [kthreadd]\n" "...lots of processes...\n" "28019 ? Ssl 0:03 /usr/sbin/corosync\n" "28047 ? Ss 0:00 /usr/sbin/pacemakerd -f\n" "28048 ? Ss 0:00 \\_ /usr/libexec/pacemaker/cib\n" "28049 ? Ss 0:00 \\_ /usr/libexec/pacemaker/stonithd\n" "28050 ? Ss 0:00 \\_ /usr/lib64/heartbeat/lrmd\n" "28051 ? Ss 0:00 \\_ /usr/libexec/pacemaker/attrd\n" "28052 ? Ss 0:00 \\_ /usr/libexec/pacemaker/pengine\n" "28053 ? Ss 0:00 \\_ /usr/libexec/pacemaker/crmd" msgstr "" #. Tag: para #, no-c-format msgid "If that looks ok, check the pcs status output." msgstr "" #. Tag: programlisting #, no-c-format msgid "" "# pcs status\n" "Last updated: Fri Sep 14 09:52:25 2012\n" "Last change: Fri Sep 14 09:51:55 2012 via crmd on pcmk-2\n" "Stack: corosync\n" "Current DC: pcmk-2 (2) - partition with quorum\n" "Version: 1.1.8-1.el7-60a19ed12fdb4d5c6a6b6767f52e5391e447fec0\n" "2 Nodes configured, unknown expected votes\n" "0 Resources configured.\n" "\n" "Online: [ pcmk-1 pcmk-2 ]\n" "\n" "Full list of resources:" msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "Next, check for any ERRORs during startup - there shouldn’t be any." msgstr "Ed infine controllo di errori di qualsiasi tipo durante l'avvio (non se ne dovrebbero rilevare) e visualizzare lo stato del cluster." #. Tag: programlisting #, no-c-format msgid "# grep -i error /var/log/messages" msgstr "" #. Tag: para #, no-c-format msgid "Repeat these checks on the other node. The results should be the same." msgstr "" #~ msgid "Start Corosync on the first node" #~ msgstr "Avvio di Corosync sul primo nodo" #~ msgid "Check the cluster started correctly and that an initial membership was able to form" #~ msgstr "Controllo del corretto avvio del cluster e che è stata formata la membership iniziale" #~ msgid "With one node functional, its now safe to start Corosync on the second node as well." #~ msgstr "Con un nodo funzionante è ora sicuro avviare Corosync anche sul secondo nodo." #~ msgid "Check the cluster formed correctly" #~ msgstr "Controllo della corretta formazione del cluster" #~ msgid "Now verify the Pacemaker processes have been started" #~ msgstr "Verifica che i processi Pacemaker sono stati avviati" pacemaker-master/doc/Clusters_from_Scratch/it-IT/Clusters_from_Scratch.po000066400000000000000000000005541217637305600271440ustar00rootroot00000000000000# # AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: 0\n" "POT-Creation-Date: 2012-10-17T05:19:03\n" "PO-Revision-Date: 2010-07-07T15:51:41\n" "Last-Translator: Automatically generated\n" "Language-Team: None\n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: application/x-publican; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" pacemaker-master/doc/Clusters_from_Scratch/it-IT/Preface.po000066400000000000000000000006571217637305600242170ustar00rootroot00000000000000# # AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: 0\n" "POT-Creation-Date: 2012-10-17T05:19:03\n" "PO-Revision-Date: 2010-07-14 14:49+0100\n" "Last-Translator: RaSca \n" "Language-Team: None\n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. Tag: title #, no-c-format msgid "Preface" msgstr "Prefazione" pacemaker-master/doc/Clusters_from_Scratch/it-IT/Revision_History.po000066400000000000000000000024341217637305600261640ustar00rootroot00000000000000# # AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: 0\n" "POT-Creation-Date: 2012-10-17T05:19:03\n" "PO-Revision-Date: 2010-07-07T15:51:41\n" "Last-Translator: Automatically generated\n" "Language-Team: None\n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: application/x-publican; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. Tag: title #, no-c-format msgid "Revision History" msgstr "" #. Tag: firstname #, no-c-format msgid "Andrew" msgstr "" #. Tag: surname #, no-c-format msgid "Beekhof" msgstr "" #. Tag: member #, no-c-format msgid "Import from Pages.app" msgstr "" #. Tag: firstname #, no-c-format msgid "Raoul" msgstr "" #. Tag: surname #, no-c-format msgid "Scarazzini" msgstr "" #. Tag: member #, no-c-format msgid "Italian translation" msgstr "" #. Tag: member #, no-c-format msgid "Updated for Fedora 13" msgstr "" #. Tag: member #, no-c-format msgid "Update the GFS2 section to use CMAN" msgstr "" #. Tag: member #, no-c-format msgid "Generate docbook content from asciidoc sources" msgstr "" #. Tag: member #, no-c-format msgid "Updated for Fedora 17" msgstr "" #. Tag: firstname #, no-c-format msgid "David" msgstr "" #. Tag: surname #, no-c-format msgid "Vossel" msgstr "" #. Tag: member #, no-c-format msgid "Updated for pcs" msgstr "" pacemaker-master/doc/Clusters_from_Scratch/pot/000077500000000000000000000000001217637305600221565ustar00rootroot00000000000000pacemaker-master/doc/Clusters_from_Scratch/pot/Ap-Configuration.pot000066400000000000000000000414131217637305600260520ustar00rootroot00000000000000# # AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: 0\n" "POT-Creation-Date: 2012-10-17T05:19:03\n" "PO-Revision-Date: 2012-10-17T05:19:03\n" "Last-Translator: Automatically generated\n" "Language-Team: None\n" "MIME-Version: 1.0\n" "Content-Type: application/x-publican; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. Tag: title #, no-c-format msgid "Configuration Recap" msgstr "" #. Tag: title #, no-c-format msgid "Final Cluster Configuration" msgstr "" #. Tag: programlisting #, no-c-format msgid "# pcs resource\n" " Master/Slave Set: WebDataClone [WebData]\n" " Masters: [ pcmk-2 pcmk-1 ]\n" " Clone Set: dlm-clone [dlm]\n" " Started: [ pcmk-2 pcmk-1 ]\n" " Clone Set: ClusterIP-clone [ClusterIP] (unique)\n" " ClusterIP:0 (ocf::heartbeat:IPaddr2) Started\n" " ClusterIP:1 (ocf::heartbeat:IPaddr2) Started\n" " Clone Set: WebFS-clone [WebFS]\n" " Started: [ pcmk-1 pcmk-2 ]\n" " Clone Set: WebSite-clone [WebSite]\n" " Started: [ pcmk-1 pcmk-2 ]\n" "# pcs resource rsc defaults\n" "resource-stickiness: 100\n" "# pcs resource op defaults\n" "timeout: 240s\n" "# pcs stonith\n" " impi-fencing (stonith:fence_ipmilan) Started\n" "# pcs property\n" "dc-version: 1.1.8-1.el7-60a19ed12fdb4d5c6a6b6767f52e5391e447fec0\n" "cluster-infrastructure: corosync\n" "no-quorum-policy: ignore\n" "stonith-enabled: true\n" "# pcs constraint\n" "Location Constraints:\n" "Ordering Constraints:\n" " ClusterIP-clone then WebSite-clone\n" " WebDataClone then WebSite-clone\n" " WebFS-clone then WebSite-clone\n" "Colocation Constraints:\n" " WebSite-clone with ClusterIP-clone\n" " WebFS-clone with WebDataClone (with-rsc-role:Master)\n" " WebSite-clone with WebFS-clone\n" "#\n" "# pcs status\n" "\n" "Last updated: Fri Sep 14 13:45:34 2012\n" "Last change: Fri Sep 14 13:43:13 2012 via cibadmin on pcmk-1\n" "Stack: corosync\n" "Current DC: pcmk-1 (1) - partition with quorum\n" "Version: 1.1.8-1.el7-60a19ed12fdb4d5c6a6b6767f52e5391e447fec0\n" "2 Nodes configured, unknown expected votes\n" "11 Resources configured.\n" "\n" "Online: [ pcmk-1 pcmk-2 ]\n" "\n" "Full list of resources:\n" "\n" " Master/Slave Set: WebDataClone [WebData]\n" " Masters: [ pcmk-2 pcmk-1 ]\n" " Clone Set: dlm-clone [dlm]\n" " Started: [ pcmk-1 pcmk-2 ]\n" " Clone Set: ClusterIP-clone [ClusterIP] (unique)\n" " ClusterIP:0 (ocf::heartbeat:IPaddr2): Started pcmk-1\n" " ClusterIP:1 (ocf::heartbeat:IPaddr2): Started pcmk-2\n" " Clone Set: WebFS-clone [WebFS]\n" " Started: [ pcmk-1 pcmk-2 ]\n" " Clone Set: WebSite-clone [WebSite]\n" " Started: [ pcmk-1 pcmk-2 ]\n" " impi-fencing (stonith:fence_ipmilan): Started" msgstr "" #. Tag: para #, no-c-format msgid "In xml it should look similar to this." msgstr "" #. Tag: programlisting #, no-c-format msgid "<cib admin_epoch=\"0\" cib-last-written=\"Fri Sep 14 13:43:13 2012\" crm_feature_set=\"3.0.6\" dc-uuid=\"1\" epoch=\"47\" have-quorum=\"1\" num_updates=\"50\" update-client=\"cibadmin\" update-origin=\"pcmk-1\" validate-with=\"pacemaker-1.2\">\n" " <configuration>\n" " <crm_config>\n" " <cluster_property_set id=\"cib-bootstrap-options\">\n" " <nvpair id=\"cib-bootstrap-options-dc-version\" name=\"dc-version\" value=\"1.1.8-1.el7-60a19ed12fdb4d5c6a6b6767f52e5391e447fec0\"/>\n" " <nvpair id=\"cib-bootstrap-options-cluster-infrastructure\" name=\"cluster-infrastructure\" value=\"corosync\"/>\n" " <nvpair id=\"cib-bootstrap-options-no-quorum-policy\" name=\"no-quorum-policy\" value=\"ignore\"/>\n" " <nvpair id=\"cib-bootstrap-options-stonith-enabled\" name=\"stonith-enabled\" value=\"true\"/>\n" " </cluster_property_set>\n" " </crm_config>\n" " <nodes>\n" " <node id=\"1\" type=\"normal\" uname=\"pcmk-1\"/>\n" " <node id=\"2\" type=\"normal\" uname=\"pcmk-2\"/>\n" " </nodes>\n" " <resources>\n" " <master id=\"WebDataClone\">\n" " <primitive class=\"ocf\" id=\"WebData\" provider=\"linbit\" type=\"drbd\">\n" " <instance_attributes id=\"WebData-instance_attributes\">\n" " <nvpair id=\"WebData-instance_attributes-drbd_resource\" name=\"drbd_resource\" value=\"wwwdata\"/>\n" " </instance_attributes>\n" " <operations>\n" " <op id=\"WebData-interval-60s\" interval=\"60s\" name=\"monitor\"/>\n" " </operations>\n" " </primitive>\n" " <meta_attributes id=\"WebDataClone-meta_attributes\">\n" " <nvpair id=\"WebDataClone-meta_attributes-master-node-max\" name=\"master-node-max\" value=\"1\"/>\n" " <nvpair id=\"WebDataClone-meta_attributes-clone-max\" name=\"clone-max\" value=\"2\"/>\n" " <nvpair id=\"WebDataClone-meta_attributes-clone-node-max\" name=\"clone-node-max\" value=\"1\"/>\n" " <nvpair id=\"WebDataClone-meta_attributes-notify\" name=\"notify\" value=\"true\"/>\n" " <nvpair id=\"WebDataClone-meta_attributes-master-max\" name=\"master-max\" value=\"2\"/>\n" " </meta_attributes>\n" " </master>\n" " <clone id=\"dlm-clone\">\n" " <primitive class=\"ocf\" id=\"dlm\" provider=\"pacemaker\" type=\"controld\">\n" " <instance_attributes id=\"dlm-instance_attributes\"/>\n" " <operations>\n" " <op id=\"dlm-interval-60s\" interval=\"60s\" name=\"monitor\"/>\n" " </operations>\n" " </primitive>\n" " <meta_attributes id=\"dlm-clone-meta\">\n" " <nvpair id=\"dlm-clone-max\" name=\"clone-max\" value=\"2\"/>\n" " <nvpair id=\"dlm-clone-node-max\" name=\"clone-node-max\" value=\"1\"/>\n" " </meta_attributes>\n" " </clone>\n" " <clone id=\"ClusterIP-clone\">\n" " <primitive class=\"ocf\" id=\"ClusterIP\" provider=\"heartbeat\" type=\"IPaddr2\">\n" " <instance_attributes id=\"ClusterIP-instance_attributes\">\n" " <nvpair id=\"ClusterIP-instance_attributes-ip\" name=\"ip\" value=\"192.168.0.120\"/>\n" " <nvpair id=\"ClusterIP-instance_attributes-cidr_netmask\" name=\"cidr_netmask\" value=\"32\"/>\n" " <nvpair id=\"ClusterIP-instance_attributes-clusterip_hash\" name=\"clusterip_hash\" value=\"sourceip\"/>\n" " </instance_attributes>\n" " <operations>\n" " <op id=\"ClusterIP-interval-30s\" interval=\"30s\" name=\"monitor\"/>\n" " </operations>\n" " </primitive>\n" " <meta_attributes id=\"ClusterIP-clone-meta\">\n" " <nvpair id=\"ClusterIP-globally-unique\" name=\"globally-unique\" value=\"true\"/>\n" " <nvpair id=\"ClusterIP-clone-max\" name=\"clone-max\" value=\"2\"/>\n" " <nvpair id=\"ClusterIP-clone-node-max\" name=\"clone-node-max\" value=\"2\"/>\n" " </meta_attributes>\n" " </clone>\n" " <clone id=\"WebFS-clone\">\n" " <primitive class=\"ocf\" id=\"WebFS\" provider=\"heartbeat\" type=\"Filesystem\">\n" " <instance_attributes id=\"WebFS-instance_attributes\">\n" " <nvpair id=\"WebFS-instance_attributes-device\" name=\"device\" value=\"/dev/drbd/by-res/wwwdata\"/>\n" " <nvpair id=\"WebFS-instance_attributes-directory\" name=\"directory\" value=\"/var/www/html\"/>\n" " <nvpair id=\"WebFS-instance_attributes-fstype\" name=\"fstype\" value=\"gfs2\"/>\n" " </instance_attributes>\n" " <meta_attributes id=\"WebFS-meta_attributes\"/>\n" " </primitive>\n" " <meta_attributes id=\"WebFS-clone-meta\"/>\n" " </clone>\n" " <clone id=\"WebSite-clone\">\n" " <primitive class=\"ocf\" id=\"WebSite\" provider=\"heartbeat\" type=\"apache\">\n" " <instance_attributes id=\"WebSite-instance_attributes\">\n" " <nvpair id=\"WebSite-instance_attributes-configfile\" name=\"configfile\" value=\"/etc/httpd/conf/httpd.conf\"/>\n" " <nvpair id=\"WebSite-instance_attributes-statusurl\" name=\"statusurl\" value=\"http://localhost/server-status\"/>\n" " </instance_attributes>\n" " <operations>\n" " <op id=\"WebSite-interval-1min\" interval=\"1min\" name=\"monitor\"/>\n" " </operations>\n" " </primitive>\n" " <meta_attributes id=\"WebSite-clone-meta\"/>\n" " </clone>\n" " <primitive class=\"stonith\" id=\"impi-fencing\" type=\"fence_ipmilan\">\n" " <instance_attributes id=\"impi-fencing-instance_attributes\">\n" " <nvpair id=\"impi-fencing-instance_attributes-pcmk_host_list\" name=\"pcmk_host_list\" value=\"pcmk-1 pcmk-2\"/>\n" " <nvpair id=\"impi-fencing-instance_attributes-ipaddr\" name=\"ipaddr\" value=\"10.0.0.1\"/>\n" " <nvpair id=\"impi-fencing-instance_attributes-login\" name=\"login\" value=\"testuser\"/>\n" " <nvpair id=\"impi-fencing-instance_attributes-passwd\" name=\"passwd\" value=\"acd123\"/>\n" " </instance_attributes>\n" " <operations>\n" " <op id=\"impi-fencing-interval-60s\" interval=\"60s\" name=\"monitor\"/>\n" " </operations>\n" " </primitive>\n" " </resources>\n" " <constraints>\n" " <rsc_colocation id=\"colocation-WebSite-ClusterIP-INFINITY\" rsc=\"WebSite-clone\" score=\"INFINITY\" with-rsc=\"ClusterIP-clone\"/>\n" " <rsc_order first=\"ClusterIP-clone\" first-action=\"start\" id=\"order-ClusterIP-WebSite-mandatory\" then=\"WebSite-clone\" then-action=\"start\"/>\n" " <rsc_colocation id=\"colocation-WebFS-WebDataClone-INFINITY\" rsc=\"WebFS-clone\" score=\"INFINITY\" with-rsc=\"WebDataClone\" with-rsc-role=\"Master\"/>\n" " <rsc_colocation id=\"colocation-WebSite-WebFS-INFINITY\" rsc=\"WebSite-clone\" score=\"INFINITY\" with-rsc=\"WebFS-clone\"/>\n" " <rsc_order first=\"WebFS-clone\" id=\"order-WebFS-WebSite-mandatory\" then=\"WebSite-clone\"/>\n" " <rsc_order first=\"WebDataClone\" first-action=\"promote\" id=\"order-WebDataClone-WebFS-mandatory\" then=\"WebFS-clone\" then-action=\"start\"/>\n" " </constraints>\n" " <rsc_defaults>\n" " <meta_attributes id=\"rsc_defaults-options\">\n" " <nvpair id=\"rsc_defaults-options-resource-stickiness\" name=\"resource-stickiness\" value=\"100\"/>\n" " </meta_attributes>\n" " </rsc_defaults>\n" " <op_defaults>\n" " <meta_attributes id=\"op_defaults-options\">\n" " <nvpair id=\"op_defaults-options-timeout\" name=\"timeout\" value=\"240s\"/>\n" " </meta_attributes>\n" " </op_defaults>\n" " </configuration>\n" "</cib>" msgstr "" #. Tag: title #, no-c-format msgid "Node List" msgstr "" #. Tag: para #, no-c-format msgid "The list of cluster nodes is automatically populated by the cluster." msgstr "" #. Tag: literallayout #, no-c-format msgid "Pacemaker Nodes:\n" " Online: [ pcmk-1 pcmk-2 ]" msgstr "" #. Tag: title #, no-c-format msgid "Cluster Options" msgstr "" #. Tag: para #, no-c-format msgid "This is where the cluster automatically stores some information about the cluster" msgstr "" #. Tag: para #, no-c-format msgid "dc-version - the version (including upstream source-code hash) of Pacemaker used on the DC" msgstr "" #. Tag: para #, no-c-format msgid "cluster-infrastructure - the cluster infrastructure being used (heartbeat or openais)" msgstr "" #. Tag: para #, no-c-format msgid "expected-quorum-votes - the maximum number of nodes expected to be part of the cluster" msgstr "" #. Tag: para #, no-c-format msgid "and where the admin can set options that control the way the cluster operates" msgstr "" #. Tag: para #, no-c-format msgid "stonith-enabled=true - Make use of STONITH" msgstr "" #. Tag: para #, no-c-format msgid "no-quorum-policy=ignore - Ignore loss of quorum and continue to host resources." msgstr "" #. Tag: programlisting #, no-c-format msgid "# pcs property\n" "dc-version: 1.1.8-1.el7-60a19ed12fdb4d5c6a6b6767f52e5391e447fec0\n" "cluster-infrastructure: corosync\n" "no-quorum-policy: ignore\n" "stonith-enabled: true" msgstr "" #. Tag: title #, no-c-format msgid "Resources" msgstr "" #. Tag: title #, no-c-format msgid "Default Options" msgstr "" #. Tag: para #, no-c-format msgid "Here we configure cluster options that apply to every resource." msgstr "" #. Tag: para #, no-c-format msgid "resource-stickiness - Specify the aversion to moving resources to other machines" msgstr "" #. Tag: programlisting #, no-c-format msgid "# pcs resource rsc defaults\n" "resource-stickiness: 100" msgstr "" #. Tag: title #, no-c-format msgid "Fencing" msgstr "" #. Tag: programlisting #, no-c-format msgid "# pcs stonith show\n" " impi-fencing (stonith:fence_ipmilan) Started\n" "# pcs stonith show impi-fencing\n" "Resource: impi-fencing\n" " pcmk_host_list: pcmk-1 pcmk-2\n" " ipaddr: 10.0.0.1\n" " login: testuser\n" " passwd: acd123" msgstr "" #. Tag: title #, no-c-format msgid "Service Address" msgstr "" #. Tag: para #, no-c-format msgid "Users of the services provided by the cluster require an unchanging address with which to access it. Additionally, we cloned the address so it will be active on both nodes. An iptables rule (created as part of the resource agent) is used to ensure that each request only gets processed by one of the two clone instances. The additional meta options tell the cluster that we want two instances of the clone (one \"request bucket\" for each node) and that if one node fails, then the remaining node should hold both." msgstr "" #. Tag: programlisting #, no-c-format msgid "# pcs resource show ClusterIP-clone\n" "Resource: ClusterIP-clone\n" " ip: 192.168.0.120\n" " cidr_netmask: 32\n" " clusterip_hash: sourceip\n" " globally-unique: true\n" " clone-max: 2\n" " clone-node-max: 2\n" " op monitor interval=30s" msgstr "" #. Tag: para #, no-c-format msgid "TODO: The RA should check for globally-unique=true when cloned" msgstr "" #. Tag: title #, no-c-format msgid "DRBD - Shared Storage" msgstr "" #. Tag: para #, no-c-format msgid "Here we define the DRBD service and specify which DRBD resource (from drbd.conf) it should manage. We make it a master/slave resource and, in order to have an active/active setup, allow both instances to be promoted by specifying master-max=2. We also set the notify option so that the cluster will tell DRBD agent when it’s peer changes state." msgstr "" #. Tag: programlisting #, no-c-format msgid "# pcs resource show WebDataClone\n" "Resource: WebDataClone\n" " drbd_resource: wwwdata\n" " master-node-max: 1\n" " clone-max: 2\n" " clone-node-max: 1\n" " notify: true\n" " master-max: 2\n" " op monitor interval=60s\n" "# pcs constraint ref WebDataClone\n" "Resource: WebDataClone\n" " colocation-WebFS-WebDataClone-INFINITY\n" " order-WebDataClone-WebFS-mandatory" msgstr "" #. Tag: title #, no-c-format msgid "Cluster Filesystem" msgstr "" #. Tag: para #, no-c-format msgid "The cluster filesystem ensures that files are read and written correctly. We need to specify the block device (provided by DRBD), where we want it mounted and that we are using GFS2. Again it is a clone because it is intended to be active on both nodes. The additional constraints ensure that it can only be started on nodes with active gfs-control and drbd instances." msgstr "" #. Tag: programlisting #, no-c-format msgid "# pcs resource show WebFS-clone\n" "Resource: WebFS-clone\n" " device: /dev/drbd/by-res/wwwdata\n" " directory: /var/www/html\n" " fstype: gfs2\n" "# pcs constraint ref WebFS-clone\n" "Resource: WebFS-clone\n" " colocation-WebFS-WebDataClone-INFINITY\n" " colocation-WebSite-WebFS-INFINITY\n" " order-WebFS-WebSite-mandatory\n" " order-WebDataClone-WebFS-mandatory" msgstr "" #. Tag: title #, no-c-format msgid "Apache" msgstr "" #. Tag: para #, no-c-format msgid "Lastly we have the actual service, Apache. We need only tell the cluster where to find it’s main configuration file and restrict it to running on nodes that have the required filesystem mounted and the IP address active." msgstr "" #. Tag: programlisting #, no-c-format msgid "# pcs resource show WebSite-clone\n" "Resource: WebSite-clone\n" " configfile: /etc/httpd/conf/httpd.conf\n" " statusurl: http://localhost/server-status\n" " master-max: 2\n" " op monitor interval=1min\n" "# pcs constraint ref WebSite-clone\n" "Resource: WebSite-clone\n" " colocation-WebSite-ClusterIP-INFINITY\n" " colocation-WebSite-WebFS-INFINITY\n" " order-ClusterIP-WebSite-mandatory\n" " order-WebFS-WebSite-mandatory" msgstr "" pacemaker-master/doc/Clusters_from_Scratch/pot/Ap-Corosync-Conf.pot000066400000000000000000000017721217637305600257310ustar00rootroot00000000000000# # AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: 0\n" "POT-Creation-Date: 2012-10-17T05:19:03\n" "PO-Revision-Date: 2012-10-17T05:19:03\n" "Last-Translator: Automatically generated\n" "Language-Team: None\n" "MIME-Version: 1.0\n" "Content-Type: application/x-publican; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. Tag: title #, no-c-format msgid "Sample Corosync Configuration" msgstr "" #. Tag: title #, no-c-format msgid "Sample corosync.conf for two-node cluster using a node list." msgstr "" #. Tag: literallayout #, no-c-format msgid "# Please read the corosync.conf.5 manual page\n" "totem {\n" "version: 2\n" "secauth: off\n" "cluster_name: mycluster\n" "transport: udpu\n" "}\n" "\n" "nodelist {\n" " node {\n" " ring0_addr: pcmk-1\n" " nodeid: 1\n" " }\n" " node {\n" " ring0_addr: pcmk-2\n" " nodeid: 2\n" " }\n" "}\n" "\n" "quorum {\n" " provider: corosync_votequorum\n" "}\n" "\n" "logging {\n" " to_syslog: yes\n" "}" msgstr "" pacemaker-master/doc/Clusters_from_Scratch/pot/Ap-Reading.pot000066400000000000000000000020711217637305600246110ustar00rootroot00000000000000# # AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: 0\n" "POT-Creation-Date: 2012-10-17T05:19:03\n" "PO-Revision-Date: 2012-10-17T05:19:03\n" "Last-Translator: Automatically generated\n" "Language-Team: None\n" "MIME-Version: 1.0\n" "Content-Type: application/x-publican; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. Tag: title #, no-c-format msgid "Further Reading" msgstr "" #. Tag: para #, no-c-format msgid "Project Website http://www.clusterlabs.org" msgstr "" #. Tag: para #, no-c-format msgid "Cluster Commands A comprehensive guide to cluster commands has been written by SuSE and can be found at: http://www.suse.com/documentation/sle_ha/book_sleha/?page=/documentation/sle_ha/book_sleha/data/book_sleha.html" msgstr "" #. Tag: para #, no-c-format msgid "Corosync http://www.corosync.org" msgstr "" pacemaker-master/doc/Clusters_from_Scratch/pot/Author_Group.pot000066400000000000000000000017051217637305600253230ustar00rootroot00000000000000# # AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: 0\n" "POT-Creation-Date: 2012-10-17T05:19:03\n" "PO-Revision-Date: 2012-10-17T05:19:03\n" "Last-Translator: Automatically generated\n" "Language-Team: None\n" "MIME-Version: 1.0\n" "Content-Type: application/x-publican; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. Tag: firstname #, no-c-format msgid "Andrew" msgstr "" #. Tag: surname #, no-c-format msgid "Beekhof" msgstr "" #. Tag: orgname #, no-c-format msgid "Red Hat" msgstr "" #. Tag: contrib #, no-c-format msgid "Primary author" msgstr "" #. Tag: firstname #, no-c-format msgid "Raoul" msgstr "" #. Tag: surname #, no-c-format msgid "Scarazzini" msgstr "" #. Tag: contrib #, no-c-format msgid "Italian translation" msgstr "" #. Tag: firstname #, no-c-format msgid "Dan" msgstr "" #. Tag: surname #, no-c-format msgid "Frîncu" msgstr "" #. Tag: contrib #, no-c-format msgid "Romanian translation" msgstr "" pacemaker-master/doc/Clusters_from_Scratch/pot/Book_Info.pot000066400000000000000000000031741217637305600245540ustar00rootroot00000000000000# # AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: 0\n" "POT-Creation-Date: 2012-10-17T05:19:03\n" "PO-Revision-Date: 2012-10-17T05:19:03\n" "Last-Translator: Automatically generated\n" "Language-Team: None\n" "MIME-Version: 1.0\n" "Content-Type: application/x-publican; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. Tag: title #, no-c-format msgid "Clusters from Scratch" msgstr "" #. Tag: subtitle #, no-c-format msgid "Creating Active/Passive and Active/Active Clusters on Fedora" msgstr "" #. Tag: productname #, no-c-format msgid "Pacemaker" msgstr "" #. Tag: para #, no-c-format msgid "The purpose of this document is to provide a start-to-finish guide to building an example active/passive cluster with Pacemaker and show how it can be converted to an active/active one." msgstr "" #. Tag: para #, no-c-format msgid "The example cluster will use:" msgstr "" #. Tag: para #, no-c-format msgid "&DISTRO; &DISTRO_VERSION; as the host operating system" msgstr "" #. Tag: para #, no-c-format msgid "Corosync to provide messaging and membership services," msgstr "" #. Tag: para #, no-c-format msgid "Pacemaker to perform resource management," msgstr "" #. Tag: para #, no-c-format msgid "DRBD as a cost-effective alternative to shared storage," msgstr "" #. Tag: para #, no-c-format msgid "GFS2 as the cluster filesystem (in active/active mode)" msgstr "" #. Tag: para #, no-c-format msgid "Given the graphical nature of the Fedora install process, a number of screenshots are included. However the guide is primarily composed of commands, the reasons for executing them and their expected outputs." msgstr "" pacemaker-master/doc/Clusters_from_Scratch/pot/Ch-Active-Active.pot000066400000000000000000000335031217637305600256620ustar00rootroot00000000000000# # AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: 0\n" "POT-Creation-Date: 2012-10-17T05:19:03\n" "PO-Revision-Date: 2012-10-17T05:19:03\n" "Last-Translator: Automatically generated\n" "Language-Team: None\n" "MIME-Version: 1.0\n" "Content-Type: application/x-publican; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. Tag: title #, no-c-format msgid "Conversion to Active/Active" msgstr "" #. Tag: title #, no-c-format msgid "Requirements" msgstr "" #. Tag: para #, no-c-format msgid "The primary requirement for an Active/Active cluster is that the data required for your services is available, simultaneously, on both machines. Pacemaker makes no requirement on how this is achieved, you could use a SAN if you had one available, however since DRBD supports multiple Primaries, we can also use that." msgstr "" #. Tag: para #, no-c-format msgid "The only hitch is that we need to use a cluster-aware filesystem. The one we used earlier with DRBD, ext4, is not one of those. Both OCFS2 and GFS2 are supported, however here we will use GFS2 which comes with Fedora 17." msgstr "" #. Tag: title #, no-c-format msgid "Installing the required Software" msgstr "" #. Tag: programlisting #, no-c-format msgid "# yum install -y gfs2-utils dlm kernel-modules-extra" msgstr "" #. Tag: literallayout #, no-c-format msgid "Loaded plugins: langpacks, presto, refresh-packagekit\n" "Resolving Dependencies\n" "--> Running transaction check\n" "---> Package dlm.x86_64 0:3.99.4-1.fc17 will be installed\n" "---> Package gfs2-utils.x86_64 0:3.1.4-3.fc17 will be installed\n" "---> Package kernel-modules-extra.x86_64 0:3.4.4-3.fc17 will be installed\n" "--> Finished Dependency Resolution\n" "\n" "Dependencies Resolved\n" "\n" "================================================================================\n" " Package Arch Version Repository Size\n" "================================================================================\n" "Installing:\n" " dlm x86_64 3.99.4-1.fc17 updates 83 k\n" " gfs2-utils x86_64 3.1.4-3.fc17 fedora 214 k\n" " kernel-modules-extra x86_64 3.4.4-3.fc17 updates 1.7 M\n" "\n" "Transaction Summary\n" "================================================================================\n" "Install 3 Packages\n" "\n" "Total download size: 1.9 M\n" "Installed size: 7.7 M\n" "Downloading Packages:\n" "(1/3): dlm-3.99.4-1.fc17.x86_64.rpm | 83 kB 00:00\n" "(2/3): gfs2-utils-3.1.4-3.fc17.x86_64.rpm | 214 kB 00:00\n" "(3/3): kernel-modules-extra-3.4.4-3.fc17.x86_64.rpm | 1.7 MB 00:01\n" "--------------------------------------------------------------------------------\n" "Total 615 kB/s | 1.9 MB 00:03\n" "Running Transaction Check\n" "Running Transaction Test\n" "Transaction Test Succeeded\n" "Running Transaction\n" " Installing : kernel-modules-extra-3.4.4-3.fc17.x86_64 1/3\n" " Installing : gfs2-utils-3.1.4-3.fc17.x86_64 2/3\n" " Installing : dlm-3.99.4-1.fc17.x86_64 3/3\n" " Verifying : dlm-3.99.4-1.fc17.x86_64 1/3\n" " Verifying : gfs2-utils-3.1.4-3.fc17.x86_64 2/3\n" " Verifying : kernel-modules-extra-3.4.4-3.fc17.x86_64 3/3\n" "\n" "Installed:\n" " dlm.x86_64 0:3.99.4-1.fc17\n" " gfs2-utils.x86_64 0:3.1.4-3.fc17\n" " kernel-modules-extra.x86_64 0:3.4.4-3.fc17\n" "\n" "Complete!" msgstr "" #. Tag: title #, no-c-format msgid "Create a GFS2 Filesystem" msgstr "" #. Tag: title #, no-c-format msgid "Preparation" msgstr "" #. Tag: para #, no-c-format msgid "Before we do anything to the existing partition, we need to make sure it is unmounted. We do this by telling the cluster to stop the WebFS resource. This will ensure that other resources (in our case, Apache) using WebFS are not only stopped, but stopped in the correct order." msgstr "" #. Tag: programlisting #, no-c-format msgid "# pcs resource stop WebFS\n" "# pcs resource\n" " ClusterIP (ocf::heartbeat:IPaddr2) Started\n" " WebSite (ocf::heartbeat:apache) Stopped\n" " Master/Slave Set: WebDataClone [WebData]\n" " Masters: [ pcmk-2 ]\n" " Slaves: [ pcmk-1 ]\n" " WebFS (ocf::heartbeat:Filesystem) Stopped" msgstr "" #. Tag: para #, no-c-format msgid "Note that both Apache and WebFS have been stopped." msgstr "" #. Tag: title #, no-c-format msgid "Create and Populate an GFS2 Partition" msgstr "" #. Tag: para #, no-c-format msgid "Now that the cluster stack and integration pieces are running smoothly, we can create an GFS2 partition." msgstr "" #. Tag: para #, no-c-format msgid "This will erase all previous content stored on the DRBD device. Ensure you have a copy of any important data." msgstr "" #. Tag: para #, no-c-format msgid "We need to specify a number of additional parameters when creating a GFS2 partition." msgstr "" #. Tag: para #, no-c-format msgid "First we must use the -p option to specify that we want to use the the Kernel’s DLM. Next we use -j to indicate that it should reserve enough space for two journals (one per node accessing the filesystem)." msgstr "" #. Tag: para #, no-c-format msgid "Lastly, we use -t to specify the lock table name. The format for this field is clustername:fsname. For the fsname, we need to use the same value as specified in corosync.conf for cluster_name. If you setup corosync with the same cluster name we used in this tutorial, cluster name will be mycluster. If you are unsure what your cluster name is, open up /etc/corosync/corosync.conf, or execute the command pcs cluster corosync pcmk-1 to view the corosync config. The cluster name will be in the totem block." msgstr "" #. Tag: para #, no-c-format msgid "We must run the next command on whichever node last had /dev/drbd mounted. Otherwise you will receive the message:" msgstr "" #. Tag: screen #, no-c-format msgid "/dev/drbd1: Read-only file system" msgstr "" #. Tag: programlisting #, no-c-format msgid "# ssh pcmk-2 -- mkfs.gfs2 -p lock_dlm -j 2 -t mycluster:web /dev/drbd1\n" "This will destroy any data on /dev/drbd1.\n" "It appears to contain: Linux rev 1.0 ext4 filesystem data, UUID=dc45fff3-c47a-4db2-96f7-a8049a323fe4 (extents) (large files) (huge files)\n" "Are you sure you want to proceed? [y/n]y\n" "Device: /dev/drbd1\n" "Blocksize: 4096\n" "Device Size 0.97 GB (253935 blocks)\n" "Filesystem Size: 0.97 GB (253932 blocks)\n" "Journals: 2\n" "Resource Groups: 4\n" "Locking Protocol: \"lock_dlm\"\n" "Lock Table: \"mycluster\"\n" "UUID: ed293a02-9eee-3fa3-ed1c-435ef1fd0116" msgstr "" #. Tag: programlisting #, no-c-format msgid "# pcs cluster cib dlm_cfg\n" "# pcs -f dlm_cfg resource create dlm ocf:pacemaker:controld op monitor interval=60s\n" "# pcs -f dlm_cfg resource clone dlm clone-max=2 clone-node-max=1\n" "# pcs -f dlm_cfg resource show\n" " ClusterIP (ocf::heartbeat:IPaddr2) Started\n" " WebSite (ocf::heartbeat:apache) Stopped\n" " Master/Slave Set: WebDataClone [WebData]\n" " Masters: [ pcmk-2 ]\n" " Slaves: [ pcmk-1 ]\n" " WebFS (ocf::heartbeat:Filesystem) Stopped\n" " Clone Set: dlm-clone [dlm]\n" " Stopped: [ dlm:0 dlm:1 ]\n" "# pcs cluster push cib dlm_cfg\n" "CIB updated\n" "# pcs status\n" "\n" "Last updated: Fri Sep 14 12:54:50 2012\n" "Last change: Fri Sep 14 12:54:43 2012 via cibadmin on pcmk-1\n" "Stack: corosync\n" "Current DC: pcmk-1 (1) - partition with quorum\n" "Version: 1.1.8-1.el7-60a19ed12fdb4d5c6a6b6767f52e5391e447fec0\n" "2 Nodes configured, unknown expected votes\n" "7 Resources configured.\n" "\n" "Online: [ pcmk-1 pcmk-2 ]\n" "\n" "Full list of resources:\n" "\n" " ClusterIP (ocf::heartbeat:IPaddr2): Started pcmk-2\n" " WebSite (ocf::heartbeat:apache): Stopped\n" " Master/Slave Set: WebDataClone [WebData]\n" " Masters: [ pcmk-2 ]\n" " Slaves: [ pcmk-1 ]\n" " WebFS (ocf::heartbeat:Filesystem): Stopped\n" " Clone Set: dlm-clone [dlm]\n" " Started: [ pcmk-1 pcmk-2 ]" msgstr "" #. Tag: para #, no-c-format msgid "Then (re)populate the new filesystem with data (web pages). For now we’ll create another variation on our home page." msgstr "" #. Tag: programlisting #, no-c-format msgid "# mount /dev/drbd1 /mnt/\n" "# cat <<-END >/mnt/index.html\n" "<html>\n" "<body>My Test Site - GFS2</body>\n" "</html>\n" "END\n" "# umount /dev/drbd1\n" "# drbdadm verify wwwdata#" msgstr "" #. Tag: title #, no-c-format msgid "Reconfigure the Cluster for GFS2" msgstr "" #. Tag: para #, no-c-format msgid "With the WebFS resource stopped, lets update the configuration." msgstr "" #. Tag: programlisting #, no-c-format msgid "# pcs resource show WebFS\n" "Resource: WebFS\n" " device: /dev/drbd/by-res/wwwdata\n" " directory: /var/www/html\n" " fstype: ext4\n" " target-role: Stopped" msgstr "" #. Tag: para #, no-c-format msgid "The fstype option needs to be updated to gfs2 instead of ext4." msgstr "" #. Tag: programlisting #, no-c-format msgid "# pcs resource update WebFS fstype=gfs2\n" "# pcs resource show WebFS\n" "Resource: WebFS\n" " device: /dev/drbd/by-res/wwwdata\n" " directory: /var/www/html\n" " fstype: gfs2\n" " target-role: Stopped\n" "CIB updated" msgstr "" #. Tag: title #, no-c-format msgid "Reconfigure Pacemaker for Active/Active" msgstr "" #. Tag: para #, no-c-format msgid "Almost everything is in place. Recent versions of DRBD are capable of operating in Primary/Primary mode and the filesystem we’re using is cluster aware. All we need to do now is reconfigure the cluster to take advantage of this." msgstr "" #. Tag: para #, no-c-format msgid "This will involve a number of changes, so we’ll want work with a local cib file." msgstr "" #. Tag: programlisting #, no-c-format msgid "# pcs cluster cib active_cfg" msgstr "" #. Tag: para #, no-c-format msgid "There’s no point making the services active on both locations if we can’t reach them, so lets first clone the IP address. Cloned IPaddr2 resources use an iptables rule to ensure that each request only gets processed by one of the two clone instances. The additional meta options tell the cluster how many instances of the clone we want (one \"request bucket\" for each node) and that if all other nodes fail, then the remaining node should hold all of them. Otherwise the requests would be simply discarded." msgstr "" #. Tag: screen #, no-c-format msgid "# pcs -f active_cfg resource clone ClusterIP \\\n" " globally-unique=true clone-max=2 clone-node-max=2" msgstr "" #. Tag: para #, no-c-format msgid "Notice when the ClusterIP becomes a clone, the constraints referencing ClusterIP now reference the clone. This is done automatically by pcs." msgstr "" #. Tag: programlisting #, no-c-format msgid "# pcs -f active_cfg constraint\n" "Location Constraints:\n" "Ordering Constraints:\n" " start ClusterIP-clone then start WebSite\n" " WebFS then WebSite\n" " promote WebDataClone then start WebFS\n" "Colocation Constraints:\n" " WebSite with ClusterIP-clone\n" " WebFS with WebDataClone (with-rsc-role:Master)\n" " WebSite with WebFS" msgstr "" #. Tag: para #, no-c-format msgid "Now we must tell the ClusterIP how to decide which requests are processed by which hosts. To do this we must specify the clusterip_hash parameter." msgstr "" #. Tag: programlisting #, no-c-format msgid "# pcs -f active_cfg resource update ClusterIP clusterip_hash=sourceip" msgstr "" #. Tag: para #, no-c-format msgid "Next we need to convert the filesystem and Apache resources into clones." msgstr "" #. Tag: para #, no-c-format msgid "Notice how pcs automatically updates the relevant constraints again." msgstr "" #. Tag: programlisting #, no-c-format msgid "# pcs -f active_cfg resource clone WebFS\n" "# pcs -f active_cfg resource clone WebSite\n" "# pcs -f active_cfg constraint\n" "Location Constraints:\n" "Ordering Constraints:\n" " start ClusterIP-clone then start WebSite-clone\n" " WebFS-clone then WebSite-clone\n" " promote WebDataClone then start WebFS-clone\n" "Colocation Constraints:\n" " WebSite-clone with ClusterIP-clone\n" " WebFS-clone with WebDataClone (with-rsc-role:Master)\n" " WebSite-clone with WebFS-clone" msgstr "" #. Tag: para #, no-c-format msgid "The last step is to tell the cluster that it is now allowed to promote both instances to be Primary (aka. Master)." msgstr "" #. Tag: programlisting #, no-c-format msgid "# pcs -f active_cfg resource update WebDataClone master-max=2" msgstr "" #. Tag: para #, no-c-format msgid "Review the configuration before uploading it to the cluster, quitting the shell and watching the cluster’s response" msgstr "" #. Tag: programlisting #, no-c-format msgid "# pcs cluster push cib active_cfg\n" "# pcs resource start WebFS" msgstr "" #. Tag: para #, no-c-format msgid "After all the processes are started the status should look similar to this." msgstr "" #. Tag: programlisting #, no-c-format msgid "# pcs resource\n" " Master/Slave Set: WebDataClone [WebData]\n" " Masters: [ pcmk-2 pcmk-1 ]\n" " Clone Set: dlm-clone [dlm]\n" " Started: [ pcmk-2 pcmk-1 ]\n" " Clone Set: ClusterIP-clone [ClusterIP] (unique)\n" " ClusterIP:0 (ocf::heartbeat:IPaddr2) Started\n" " ClusterIP:1 (ocf::heartbeat:IPaddr2) Started\n" " Clone Set: WebFS-clone [WebFS]\n" " Started: [ pcmk-1 pcmk-2 ]\n" " Clone Set: WebSite-clone [WebSite]\n" " Started: [ pcmk-1 pcmk-2 ]" msgstr "" #. Tag: title #, no-c-format msgid "Testing Recovery" msgstr "" #. Tag: para #, no-c-format msgid "TODO: Put one node into standby to demonstrate failover" msgstr "" pacemaker-master/doc/Clusters_from_Scratch/pot/Ch-Active-Passive.pot000066400000000000000000000365011217637305600260620ustar00rootroot00000000000000# # AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: 0\n" "POT-Creation-Date: 2012-10-17T05:19:03\n" "PO-Revision-Date: 2012-10-17T05:19:03\n" "Last-Translator: Automatically generated\n" "Language-Team: None\n" "MIME-Version: 1.0\n" "Content-Type: application/x-publican; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. Tag: title #, no-c-format msgid "Creating an Active/Passive Cluster" msgstr "" #. Tag: title #, no-c-format msgid "Exploring the Existing Configuration" msgstr "" #. Tag: para #, no-c-format msgid "When Pacemaker starts up, it automatically records the number and details of the nodes in the cluster as well as which stack is being used and the version of Pacemaker being used." msgstr "" #. Tag: para #, no-c-format msgid "This is what the base configuration should look like." msgstr "" #. Tag: programlisting #, no-c-format msgid "# pcs status\n" "Last updated: Fri Sep 14 10:12:01 2012\n" "Last change: Fri Sep 14 09:51:55 2012 via crmd on pcmk-2\n" "Stack: corosync\n" "Current DC: pcmk-1 (1) - partition with quorum\n" "Version: 1.1.8-1.el7-60a19ed12fdb4d5c6a6b6767f52e5391e447fec0\n" "2 Nodes configured, unknown expected votes\n" "0 Resources configured.\n" "\n" "Online: [ pcmk-1 pcmk-2 ]\n" "\n" "Full list of resources:" msgstr "" #. Tag: para #, no-c-format msgid "For those that are not of afraid of XML, you can see the raw cluster configuration and status by using the pcs cluster cib command." msgstr "" #. Tag: title #, no-c-format msgid "The last XML you’ll see in this document" msgstr "" #. Tag: programlisting #, no-c-format msgid "# pcs cluster cib" msgstr "" #. Tag: programlisting #, no-c-format msgid "<cib epoch=\"4\" num_updates=\"19\" admin_epoch=\"0\" validate-with=\"pacemaker-1.2\" crm_feature_set=\"3.0.6\" update-origin=\"pcmk-1\" update-client=\"crmd\" cib-last-written=\"Wed Aug 1 16:08:52 2012\" have-quorum=\"1\" dc-uuid=\"1\">\n" " <configuration>\n" " <crm_config>\n" " <cluster_property_set id=\"cib-bootstrap-options\">\n" " <nvpair id=\"cib-bootstrap-options-dc-version\" name=\"dc-version\" value=\"1.1.8-1.el7-60a19ed12fdb4d5c6a6b6767f52e5391e447fec0\"/>\n" " <nvpair id=\"cib-bootstrap-options-cluster-infrastructure\" name=\"cluster-infrastructure\" value=\"corosync\"/>\n" " </cluster_property_set>\n" " </crm_config>\n" " <nodes>\n" " <node id=\"1\" uname=\"pcmk-1\" type=\"normal\"/>\n" " <node id=\"2\" uname=\"pcmk-2\" type=\"normal\"/>\n" " </nodes>\n" " <resources/>\n" " <constraints/>\n" " </configuration>\n" " <status>\n" " <node_state id=\"2\" uname=\"pcmk-2\" ha=\"active\" in_ccm=\"true\" crmd=\"online\" join=\"member\" expected=\"member\" crm-debug-origin=\"do_state_transition\" shutdown=\"0\">\n" " <lrm id=\"2\">\n" " <lrm_resources/>\n" " </lrm>\n" " <transient_attributes id=\"2\">\n" " <instance_attributes id=\"status-2\">\n" " <nvpair id=\"status-2-probe_complete\" name=\"probe_complete\" value=\"true\"/>\n" " </instance_attributes>\n" " </transient_attributes>\n" " </node_state>\n" " <node_state id=\"1\" uname=\"pcmk-1\" ha=\"active\" in_ccm=\"true\" crmd=\"online\" join=\"member\" expected=\"member\" crm-debug-origin=\"do_state_transition\" shutdown=\"0\">\n" " <lrm id=\"1\">\n" " <lrm_resources/>\n" " </lrm>\n" " <transient_attributes id=\"1\">\n" " <instance_attributes id=\"status-1\">\n" " <nvpair id=\"status-1-probe_complete\" name=\"probe_complete\" value=\"true\"/>\n" " </instance_attributes>\n" " </transient_attributes>\n" " </node_state>\n" " </status>\n" "</cib>" msgstr "" #. Tag: para #, no-c-format msgid "Before we make any changes, its a good idea to check the validity of the configuration." msgstr "" #. Tag: programlisting #, no-c-format msgid "# crm_verify -L -V\n" " error: unpack_resources: Resource start-up disabled since no STONITH resources have been defined\n" " error: unpack_resources: Either configure some or disable STONITH with the stonith-enabled option\n" " error: unpack_resources: NOTE: Clusters with shared data need STONITH to ensure data integrity\n" "Errors found during check: config not valid\n" " -V may provide more details" msgstr "" #. Tag: para #, no-c-format msgid "As you can see, the tool has found some errors." msgstr "" #. Tag: para #, no-c-format msgid "In order to guarantee the safety of your data If the data is corrupt, there is little point in continuing to make it available , the default for STONITH A common node fencing mechanism. Used to ensure data integrity by powering off \"bad\" nodes in Pacemaker is enabled. However it also knows when no STONITH configuration has been supplied and reports this as a problem (since the cluster would not be able to make progress if a situation requiring node fencing arose)." msgstr "" #. Tag: para #, no-c-format msgid "For now, we will disable this feature and configure it later in the Configuring STONITH section. It is important to note that the use of STONITH is highly encouraged, turning it off tells the cluster to simply pretend that failed nodes are safely powered off. Some vendors will even refuse to support clusters that have it disabled." msgstr "" #. Tag: para #, no-c-format msgid "To disable STONITH, we set the stonith-enabled cluster option to false." msgstr "" #. Tag: programlisting #, no-c-format msgid "# pcs property set stonith-enabled=false\n" "# crm_verify -L" msgstr "" #. Tag: para #, no-c-format msgid "With the new cluster option set, the configuration is now valid." msgstr "" #. Tag: para #, no-c-format msgid "The use of stonith-enabled=false is completely inappropriate for a production cluster. We use it here to defer the discussion of its configuration which can differ widely from one installation to the next. See for information on why STONITH is important and details on how to configure it." msgstr "" #. Tag: title #, no-c-format msgid "Adding a Resource" msgstr "" #. Tag: para #, no-c-format msgid "The first thing we should do is configure an IP address. Regardless of where the cluster service(s) are running, we need a consistent address to contact them on. Here I will choose and add 192.168.122.120 as the floating address, give it the imaginative name ClusterIP and tell the cluster to check that its running every 30 seconds." msgstr "" #. Tag: para #, no-c-format msgid "The chosen address must not be one already associated with a physical node" msgstr "" #. Tag: screen #, no-c-format msgid "# pcs resource create ClusterIP ocf:heartbeat:IPaddr2 \\\n" " ip=192.168.0.120 cidr_netmask=32 op monitor interval=30s" msgstr "" #. Tag: para #, no-c-format msgid "The other important piece of information here is ocf:heartbeat:IPaddr2." msgstr "" #. Tag: para #, no-c-format msgid "This tells Pacemaker three things about the resource you want to add. The first field, ocf, is the standard to which the resource script conforms to and where to find it. The second field is specific to OCF resources and tells the cluster which namespace to find the resource script in, in this case heartbeat. The last field indicates the name of the resource script." msgstr "" #. Tag: para #, no-c-format msgid "To obtain a list of the available resource standards (the ocf part of ocf:heartbeat:IPaddr2), run" msgstr "" #. Tag: programlisting #, no-c-format msgid "# pcs resource standards\n" "ocf\n" "lsb\n" "service\n" "systemd\n" "stonith" msgstr "" #. Tag: para #, no-c-format msgid "To obtain a list of the available ocf resource providers (the heartbeat part of ocf:heartbeat:IPaddr2), run" msgstr "" #. Tag: programlisting #, no-c-format msgid "# pcs resource providers\n" "heartbeat\n" "linbit\n" "pacemaker\n" "redhat" msgstr "" #. Tag: para #, no-c-format msgid "Finally, if you want to see all the resource agents available for a specific ocf provider (the IPaddr2 part of ocf:heartbeat:IPaddr2), run" msgstr "" #. Tag: programlisting #, no-c-format msgid "# pcs resource agents ocf:heartbeat\n" "AoEtarget\n" "AudibleAlarm\n" "CTDB\n" "ClusterMon\n" "Delay\n" "Dummy\n" ".\n" ". (skipping lots of resources to save space)\n" ".\n" "IPaddr2\n" ".\n" ".\n" ".\n" "symlink\n" "syslog-ng\n" "tomcat\n" "vmware" msgstr "" #. Tag: para #, no-c-format msgid "Now verify that the IP resource has been added and display the cluster’s status to see that it is now active." msgstr "" #. Tag: programlisting #, no-c-format msgid "# pcs status\n" "\n" "Last updated: Fri Sep 14 10:17:00 2012\n" "Last change: Fri Sep 14 10:15:48 2012 via cibadmin on pcmk-1\n" "Stack: corosync\n" "Current DC: pcmk-1 (1) - partition with quorum\n" "Version: 1.1.8-1.el7-60a19ed12fdb4d5c6a6b6767f52e5391e447fec0\n" "2 Nodes configured, unknown expected votes\n" "1 Resources configured.\n" "\n" "Online: [ pcmk-1 pcmk-2 ]\n" "\n" "Full list of resources:\n" "\n" " ClusterIP (ocf::heartbeat:IPaddr2): Started pcmk-1" msgstr "" #. Tag: title #, no-c-format msgid "Perform a Failover" msgstr "" #. Tag: para #, no-c-format msgid "Being a high-availability cluster, we should test failover of our new resource before moving on." msgstr "" #. Tag: para #, no-c-format msgid "First, find the node on which the IP address is running." msgstr "" #. Tag: para #, no-c-format msgid "Shut down Pacemaker and Corosync on that machine." msgstr "" #. Tag: programlisting #, no-c-format msgid "#pcs cluster stop pcmk-1\n" "Stopping Cluster..." msgstr "" #. Tag: para #, no-c-format msgid "Once Corosync is no longer running, go to the other node and check the cluster status." msgstr "" #. Tag: programlisting #, no-c-format msgid "# pcs status\n" "\n" "Last updated: Fri Sep 14 10:31:01 2012\n" "Last change: Fri Sep 14 10:15:48 2012 via cibadmin on pcmk-1\n" "Stack: corosync\n" "Current DC: pcmk-2 (2) - partition WITHOUT quorum\n" "Version: 1.1.8-1.el7-60a19ed12fdb4d5c6a6b6767f52e5391e447fec0\n" "2 Nodes configured, unknown expected votes\n" "1 Resources configured.\n" "\n" "Online: [ pcmk-2 ]\n" "OFFLINE: [ pcmk-1 ]\n" "\n" "Full list of resources:\n" "\n" " ClusterIP (ocf::heartbeat:IPaddr2): Stopped" msgstr "" #. Tag: para #, no-c-format msgid "There are three things to notice about the cluster’s current state. The first is that, as expected, pcmk-1 is now offline. However we can also see that ClusterIP isn’t running anywhere!" msgstr "" #. Tag: title #, no-c-format msgid "Quorum and Two-Node Clusters" msgstr "" #. Tag: para #, no-c-format msgid "This is because the cluster no longer has quorum, as can be seen by the text \"partition WITHOUT quorum\" in the status output. In order to reduce the possibility of data corruption, Pacemaker’s default behavior is to stop all resources if the cluster does not have quorum." msgstr "" #. Tag: para #, no-c-format msgid "A cluster is said to have quorum when more than half the known or expected nodes are online, or for the mathematically inclined, whenever the following equation is true:" msgstr "" #. Tag: literallayout #, no-c-format msgid "total_nodes < 2 * active_nodes" msgstr "" #. Tag: para #, no-c-format msgid "Therefore a two-node cluster only has quorum when both nodes are running, which is no longer the case for our cluster. This would normally make the creation of a two-node cluster pointless Actually some would argue that two-node clusters are always pointless, but that is an argument for another time , however it is possible to control how Pacemaker behaves when quorum is lost. In particular, we can tell the cluster to simply ignore quorum altogether." msgstr "" #. Tag: programlisting #, no-c-format msgid "# pcs property set no-quorum-policy=ignore\n" "# pcs property\n" "dc-version: 1.1.8-1.el7-60a19ed12fdb4d5c6a6b6767f52e5391e447fec0\n" "cluster-infrastructure: corosync\n" "stonith-enabled: false\n" "no-quorum-policy: ignore" msgstr "" #. Tag: para #, no-c-format msgid "After a few moments, the cluster will start the IP address on the remaining node. Note that the cluster still does not have quorum." msgstr "" #. Tag: programlisting #, no-c-format msgid "# pcs status\n" "Last updated: Fri Sep 14 10:38:11 2012\n" "Last change: Fri Sep 14 10:37:53 2012 via cibadmin on pcmk-2\n" "Stack: corosync\n" "Current DC: pcmk-2 (2) - partition WITHOUT quorum\n" "Version: 1.1.8-1.el7-60a19ed12fdb4d5c6a6b6767f52e5391e447fec0\n" "2 Nodes configured, unknown expected votes\n" "1 Resources configured.\n" "\n" "Online: [ pcmk-2 ]\n" "OFFLINE: [ pcmk-1 ]\n" "\n" "Full list of resources:\n" "\n" " ClusterIP (ocf::heartbeat:IPaddr2): Started pcmk-2" msgstr "" #. Tag: para #, no-c-format msgid "Now simulate node recovery by restarting the cluster stack on pcmk-1 and check the cluster’s status. Note, if you get an authentication error with the pcs cluster start pcmk-1 command, you must authenticate on the node using the pcs cluster auth pcmk pcmk-1 pcmk-2 command discussed earlier." msgstr "" #. Tag: programlisting #, no-c-format msgid "# pcs cluster start pcmk-1\n" "Starting Cluster...\n" "# pcs status\n" "\n" "Last updated: Fri Sep 14 10:42:56 2012\n" "Last change: Fri Sep 14 10:37:53 2012 via cibadmin on pcmk-2\n" "Stack: corosync\n" "Current DC: pcmk-2 (2) - partition with quorum\n" "Version: 1.1.8-1.el7-60a19ed12fdb4d5c6a6b6767f52e5391e447fec0\n" "2 Nodes configured, unknown expected votes\n" "1 Resources configured.\n" "\n" "Online: [ pcmk-1 pcmk-2 ]\n" "\n" "Full list of resources:\n" "\n" " ClusterIP (ocf::heartbeat:IPaddr2): Started pcmk-2" msgstr "" #. Tag: para #, no-c-format msgid "In the dark days, the cluster may have moved the IP back to its original location (pcmk-1). Usually this is no longer the case." msgstr "" #. Tag: title #, no-c-format msgid "Prevent Resources from Moving after Recovery" msgstr "" #. Tag: para #, no-c-format msgid "In most circumstances, it is highly desirable to prevent healthy resources from being moved around the cluster. Moving resources almost always requires a period of downtime. For complex services like Oracle databases, this period can be quite long." msgstr "" #. Tag: para #, no-c-format msgid "To address this, Pacemaker has the concept of resource stickiness which controls how much a service prefers to stay running where it is. You may like to think of it as the \"cost\" of any downtime. By default, Pacemaker assumes there is zero cost associated with moving resources and will do so to achieve \"optimal\" It should be noted that Pacemaker’s definition of optimal may not always agree with that of a human’s. The order in which Pacemaker processes lists of resources and nodes creates implicit preferences in situations where the administrator has not explicitly specified them resource placement. We can specify a different stickiness for every resource, but it is often sufficient to change the default." msgstr "" #. Tag: programlisting #, no-c-format msgid "# pcs resource rsc defaults resource-stickiness=100\n" "# pcs resource rsc defaults\n" "resource-stickiness: 100" msgstr "" pacemaker-master/doc/Clusters_from_Scratch/pot/Ch-Apache.pot000066400000000000000000000452141217637305600244210ustar00rootroot00000000000000# # AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: 0\n" "POT-Creation-Date: 2012-10-17T05:19:03\n" "PO-Revision-Date: 2012-10-17T05:19:03\n" "Last-Translator: Automatically generated\n" "Language-Team: None\n" "MIME-Version: 1.0\n" "Content-Type: application/x-publican; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. Tag: title #, no-c-format msgid "Apache - Adding More Services" msgstr "" #. Tag: title #, no-c-format msgid "Forward" msgstr "" #. Tag: para #, no-c-format msgid "Now that we have a basic but functional active/passive two-node cluster, we’re ready to add some real services. We’re going to start with Apache because its a feature of many clusters and relatively simple to configure." msgstr "" #. Tag: title #, no-c-format msgid "Installation" msgstr "" #. Tag: para #, no-c-format msgid "Before continuing, we need to make sure Apache is installed on both hosts. We also need the wget tool in order for the cluster to be able to check the status of the Apache server." msgstr "" #. Tag: programlisting #, no-c-format msgid "# yum install -y httpd wget" msgstr "" #. Tag: literallayout #, no-c-format msgid "Loaded plugins: langpacks, presto, refresh-packagekit\n" "fedora/metalink | 2.6 kB 00:00\n" "updates/metalink | 3.2 kB 00:00\n" "updates-testing/metalink | 41 kB 00:00\n" "Resolving Dependencies\n" "--> Running transaction check\n" "---> Package httpd.x86_64 0:2.2.22-3.fc17 will be installed\n" "--> Processing Dependency: httpd-tools = 2.2.22-3.fc17 for package: httpd-2.2.22-3.fc17.x86_64\n" "--> Processing Dependency: apr-util-ldap for package: httpd-2.2.22-3.fc17.x86_64\n" "--> Processing Dependency: libaprutil-1.so.0()(64bit) for package: httpd-2.2.22-3.fc17.x86_64\n" "--> Processing Dependency: libapr-1.so.0()(64bit) for package: httpd-2.2.22-3.fc17.x86_64\n" "--> Running transaction check\n" "---> Package apr.x86_64 0:1.4.6-1.fc17 will be installed\n" "---> Package apr-util.x86_64 0:1.4.1-2.fc17 will be installed\n" "---> Package apr-util-ldap.x86_64 0:1.4.1-2.fc17 will be installed\n" "---> Package httpd-tools.x86_64 0:2.2.22-3.fc17 will be installed\n" "--> Finished Dependency Resolution\n" "\n" "Dependencies Resolved\n" "\n" "=====================================================================================\n" " Package Arch Version Repository Size\n" "=====================================================================================\n" "Installing:\n" " httpd x86_64 2.2.22-3.fc17 updates-testing 823 k\n" " wget x86_64 1.13.4-2.fc17 fedora 495 k\n" "Installing for dependencies:\n" " apr x86_64 1.4.6-1.fc17 fedora 99 k\n" " apr-util x86_64 1.4.1-2.fc17 fedora 78 k\n" " apr-util-ldap x86_64 1.4.1-2.fc17 fedora 17 k\n" " httpd-tools x86_64 2.2.22-3.fc17 updates-testing 74 k\n" "\n" "Transaction Summary\n" "=====================================================================================\n" "Install 1 Package (+4 Dependent packages)\n" "\n" "Total download size: 1.1 M\n" "Installed size: 3.5 M\n" "Downloading Packages:\n" "(1/6): apr-1.4.6-1.fc17.x86_64.rpm | 99 kB 00:00\n" "(2/6): apr-util-1.4.1-2.fc17.x86_64.rpm | 78 kB 00:00\n" "(3/6): apr-util-ldap-1.4.1-2.fc17.x86_64.rpm | 17 kB 00:00\n" "(4/6): httpd-2.2.22-3.fc17.x86_64.rpm | 823 kB 00:01\n" "(5/6): httpd-tools-2.2.22-3.fc17.x86_64.rpm | 74 kB 00:00\n" "(6/6): wget-1.13.4-2.fc17.x86_64.rpm | 495 kB 00:01\n" "-------------------------------------------------------------------------------------\n" "Total 238 kB/s | 1.1 MB 00:04\n" "Running Transaction Check\n" "Running Transaction Test\n" "Transaction Test Succeeded\n" "Running Transaction\n" " Installing : apr-1.4.6-1.fc17.x86_64 1/6\n" " Installing : apr-util-1.4.1-2.fc17.x86_64 2/6\n" " Installing : apr-util-ldap-1.4.1-2.fc17.x86_64 3/6\n" " Installing : httpd-tools-2.2.22-3.fc17.x86_64 4/6\n" " Installing : httpd-2.2.22-3.fc17.x86_64 5/6\n" " Installing : wget-1.13.4-2.fc17.x86_64 6/6\n" " Verifying : apr-util-ldap-1.4.1-2.fc17.x86_64 1/6\n" " Verifying : httpd-tools-2.2.22-3.fc17.x86_64 2/6\n" " Verifying : apr-util-1.4.1-2.fc17.x86_64 3/6\n" " Verifying : apr-1.4.6-1.fc17.x86_64 4/6\n" " Verifying : httpd-2.2.22-3.fc17.x86_64 5/6\n" " Verifying : wget-1.13.4-2.fc17.x86_64 6/6\n" "\n" "Installed:\n" " httpd.x86_64 0:2.2.22-3.fc17 wget.x86_64 0:1.13.4-2.fc17\n" "\n" "Dependency Installed:\n" " apr.x86_64 0:1.4.6-1.fc17 apr-util.x86_64 0:1.4.1-2.fc17\n" " apr-util-ldap.x86_64 0:1.4.1-2.fc17 httpd-tools.x86_64 0:2.2.22-3.fc17\n" "\n" "Complete!" msgstr "" #. Tag: title #, no-c-format msgid "Preparation" msgstr "" #. Tag: para #, no-c-format msgid "First we need to create a page for Apache to serve up. On Fedora the default Apache docroot is /var/www/html, so we’ll create an index file there." msgstr "" #. Tag: programlisting #, no-c-format msgid "# cat <<-END >/var/www/html/index.html\n" " <html>\n" " <body>My Test Site - pcmk-1</body>\n" " </html>\n" "END" msgstr "" #. Tag: para #, no-c-format msgid "For the moment, we will simplify things by serving up only a static site and manually sync the data between the two nodes. So run the command again on pcmk-2." msgstr "" #. Tag: programlisting #, no-c-format msgid "[root@pcmk-2 ~]# cat <<-END >/var/www/html/index.html <html>\n" " <body>My Test Site - pcmk-2</body>\n" " </html>\n" " END" msgstr "" #. Tag: title #, no-c-format msgid "Enable the Apache status URL" msgstr "" #. Tag: para #, no-c-format msgid "In order to monitor the health of your Apache instance, and recover it if it fails, the resource agent used by Pacemaker assumes the server-status URL is available. Look for the following in /etc/httpd/conf/httpd.conf and make sure it is not disabled or commented out:" msgstr "" #. Tag: programlisting #, no-c-format msgid "<Location /server-status>\n" " SetHandler server-status\n" " Order deny,allow\n" " Deny from all\n" " Allow from 127.0.0.1\n" "</Location>" msgstr "" #. Tag: title #, no-c-format msgid "Update the Configuration" msgstr "" #. Tag: para #, no-c-format msgid "At this point, Apache is ready to go, all that needs to be done is to add it to the cluster. Lets call the resource WebSite. We need to use an OCF script called apache in the heartbeat namespace Compare the key used here ocf:heartbeat:apache with the one we used earlier for the IP address: ocf:heartbeat:IPaddr2 , the only required parameter is the path to the main Apache configuration file and we’ll tell the cluster to check once a minute that apache is still running." msgstr "" #. Tag: screen #, no-c-format msgid "pcs resource create WebSite ocf:heartbeat:apache \\\n" " configfile=/etc/httpd/conf/httpd.conf \\\n" " statusurl=\"http://localhost/server-status\" op monitor interval=1min" msgstr "" #. Tag: para #, no-c-format msgid "By default, the operation timeout for all resource’s start, stop, and monitor operations is 20 seconds. In many cases this timeout period is less than the advised timeout period. For the purposes of this tutorial, we will adjust the global operation timeout default to 240 seconds." msgstr "" #. Tag: programlisting #, no-c-format msgid "# pcs resource op defaults timeout=240s\n" "# pcs resource op defaults\n" "timeout: 240s" msgstr "" #. Tag: para #, no-c-format msgid "After a short delay, we should see the cluster start apache" msgstr "" #. Tag: programlisting #, no-c-format msgid "# pcs status\n" "\n" "Last updated: Fri Sep 14 10:51:27 2012\n" "Last change: Fri Sep 14 10:50:46 2012 via crm_attribute on pcmk-1\n" "Stack: corosync\n" "Current DC: pcmk-2 (2) - partition with quorum\n" "Version: 1.1.8-1.el7-60a19ed12fdb4d5c6a6b6767f52e5391e447fec0\n" "2 Nodes configured, unknown expected votes\n" "2 Resources configured.\n" "\n" "Online: [ pcmk-1 pcmk-2 ]\n" "\n" "Full list of resources:\n" "\n" " ClusterIP (ocf::heartbeat:IPaddr2): Started pcmk-2\n" " WebSite (ocf::heartbeat:apache): Started pcmk-1" msgstr "" #. Tag: para #, no-c-format msgid "Wait a moment, the WebSite resource isn’t running on the same host as our IP address!" msgstr "" #. Tag: para #, no-c-format msgid "If, in the pcs status output, you see the WebSite resource has failed to start, then you’ve likely not enabled the status URL correctly. You can check if this is the problem by running:" msgstr "" #. Tag: literallayout #, no-c-format msgid "wget http://127.0.0.1/server-status" msgstr "" #. Tag: para #, no-c-format msgid "If you see Connection refused in the output, then this is indeed the problem. Check to ensure that Allow from 127.0.0.1 is present for the <Location /server-status> block." msgstr "" #. Tag: title #, no-c-format msgid "Ensuring Resources Run on the Same Host" msgstr "" #. Tag: para #, no-c-format msgid "To reduce the load on any one machine, Pacemaker will generally try to spread the configured resources across the cluster nodes. However we can tell the cluster that two resources are related and need to run on the same host (or not at all). Here we instruct the cluster that WebSite can only run on the host that ClusterIP is active on." msgstr "" #. Tag: para #, no-c-format msgid "To achieve this we use a colocation constraint that indicates it is mandatory for WebSite to run on the same node as ClusterIP. The \"mandatory\" part of the colocation constraint is indicated by using a score of INFINITY. The INFINITY score also means that if ClusterIP is not active anywhere, WebSite will not be permitted to run." msgstr "" #. Tag: para #, no-c-format msgid "If ClusterIP is not active anywhere, WebSite will not be permitted to run anywhere." msgstr "" #. Tag: para #, no-c-format msgid "Colocation constraints are \"directional\", in that they imply certain things about the order in which the two resources will have a location chosen. In this case we’re saying WebSite needs to be placed on the same machine as ClusterIP, this implies that we must know the location of ClusterIP before choosing a location for WebSite." msgstr "" #. Tag: programlisting #, no-c-format msgid "# pcs constraint colocation add WebSite ClusterIP INFINITY\n" "# pcs constraint\n" "Location Constraints:\n" "Ordering Constraints:\n" "Colocation Constraints:\n" " WebSite with ClusterIP\n" "# pcs status\n" "\n" "Last updated: Fri Sep 14 11:00:44 2012\n" "Last change: Fri Sep 14 11:00:25 2012 via cibadmin on pcmk-1\n" "Stack: corosync\n" "Current DC: pcmk-2 (2) - partition with quorum\n" "Version: 1.1.8-1.el7-60a19ed12fdb4d5c6a6b6767f52e5391e447fec0\n" "2 Nodes configured, unknown expected votes\n" "2 Resources configured.\n" "\n" "Online: [ pcmk-1 pcmk-2 ]\n" "\n" "Full list of resources:\n" "\n" " ClusterIP (ocf::heartbeat:IPaddr2): Started pcmk-2\n" " WebSite (ocf::heartbeat:apache): Started pcmk-2" msgstr "" #. Tag: title #, no-c-format msgid "Controlling Resource Start/Stop Ordering" msgstr "" #. Tag: para #, no-c-format msgid "When Apache starts, it binds to the available IP addresses. It doesn’t know about any addresses we add afterwards, so not only do they need to run on the same node, but we need to make sure ClusterIP is already active before we start WebSite. We do this by adding an ordering constraint." msgstr "" #. Tag: para #, no-c-format msgid "By default all order constraints are mandatory constraints unless otherwise configured. This means that the recovery of ClusterIP will also trigger the recovery of WebSite." msgstr "" #. Tag: programlisting #, no-c-format msgid "# pcs constraint order ClusterIP then WebSite\n" "Adding ClusterIP WebSite (kind: Mandatory) (Options: first-action=start then-action=start)\n" "# pcs constraint\n" "Location Constraints:\n" "Ordering Constraints:\n" " start ClusterIP then start WebSite\n" "Colocation Constraints:\n" " WebSite with ClusterIP" msgstr "" #. Tag: title #, no-c-format msgid "Specifying a Preferred Location" msgstr "" #. Tag: para #, no-c-format msgid "Pacemaker does not rely on any sort of hardware symmetry between nodes, so it may well be that one machine is more powerful than the other. In such cases it makes sense to host the resources there if it is available. To do this we create a location constraint." msgstr "" #. Tag: para #, no-c-format msgid "In the location constraint below, we are saying the WebSite resource prefers the node pcmk-1 with a score of 50. The score here indicates how badly we’d like the resource to run somewhere." msgstr "" #. Tag: programlisting #, no-c-format msgid "# pcs constraint location WebSite prefers pcmk-1=50\n" "# pcs constraint\n" "Location Constraints:\n" " Resource: WebSite\n" " Enabled on: pcmk-1 (score:50)\n" "Ordering Constraints:\n" " start ClusterIP then start WebSite\n" "Colocation Constraints:\n" " WebSite with ClusterIP\n" "# pcs status\n" "Last updated: Fri Sep 14 11:06:37 2012\n" "Last change: Fri Sep 14 11:06:26 2012 via cibadmin on pcmk-1\n" "Stack: corosync\n" "Current DC: pcmk-2 (2) - partition with quorum\n" "Version: 1.1.8-1.el7-60a19ed12fdb4d5c6a6b6767f52e5391e447fec0\n" "2 Nodes configured, unknown expected votes\n" "2 Resources configured.\n" "\n" "Online: [ pcmk-1 pcmk-2 ]\n" "\n" "Full list of resources:\n" "\n" " ClusterIP (ocf::heartbeat:IPaddr2): Started pcmk-2\n" " WebSite (ocf::heartbeat:apache): Started pcmk-2" msgstr "" #. Tag: para #, no-c-format msgid "Wait a minute, the resources are still on pcmk-2!" msgstr "" #. Tag: para #, no-c-format msgid "Even though we now prefer pcmk-1 over pcmk-2, that preference is (intentionally) less than the resource stickiness (how much we preferred not to have unnecessary downtime)." msgstr "" #. Tag: para #, no-c-format msgid "To see the current placement scores, you can use a tool called crm_simulate" msgstr "" #. Tag: programlisting #, no-c-format msgid "# crm_simulate -sL\n" "Current cluster status:\n" "Online: [ pcmk-1 pcmk-2 ]\n" "\n" " ClusterIP (ocf:heartbeat:IPaddr2): Started pcmk-2\n" " WebSite (ocf:heartbeat:apache): Started pcmk-2\n" "\n" "Allocation scores:\n" "native_color: ClusterIP allocation score on pcmk-1: 50\n" "native_color: ClusterIP allocation score on pcmk-2: 200\n" "native_color: WebSite allocation score on pcmk-1: -INFINITY\n" "native_color: WebSite allocation score on pcmk-2: 100\n" "\n" "Transition Summary:" msgstr "" #. Tag: title #, no-c-format msgid "Manually Moving Resources Around the Cluster" msgstr "" #. Tag: para #, no-c-format msgid "There are always times when an administrator needs to override the cluster and force resources to move to a specific location. By updating our previous location constraint with a score of INFINITY, WebSite will be forced to move to pcmk-1." msgstr "" #. Tag: programlisting #, no-c-format msgid "# pcs constraint location WebSite prefers pcmk-1=INFINITY\n" "# pcs constraint all\n" "Location Constraints:\n" " Resource: WebSite\n" " Enabled on: pcmk-1 (score:INFINITY) (id:location-WebSite-pcmk-1-INFINITY)\n" "Ordering Constraints:\n" " start ClusterIP then start WebSite (Mandatory) (id:order-ClusterIP-WebSite-mandatory)\n" "Colocation Constraints:\n" " WebSite with ClusterIP (INFINITY) (id:colocation-WebSite-ClusterIP-INFINITY)\n" "# pcs status\n" "\n" "Last updated: Fri Sep 14 11:16:26 2012\n" "Last change: Fri Sep 14 11:16:18 2012 via cibadmin on pcmk-1\n" "Stack: corosync\n" "Current DC: pcmk-2 (2) - partition with quorum\n" "Version: 1.1.8-1.el7-60a19ed12fdb4d5c6a6b6767f52e5391e447fec0\n" "2 Nodes configured, unknown expected votes\n" "2 Resources configured.\n" "\n" "Online: [ pcmk-1 pcmk-2 ]\n" "\n" "Full list of resources:\n" "\n" " ClusterIP (ocf::heartbeat:IPaddr2): Started pcmk-1\n" " WebSite (ocf::heartbeat:apache): Started pcmk-1" msgstr "" #. Tag: title #, no-c-format msgid "Giving Control Back to the Cluster" msgstr "" #. Tag: para #, no-c-format msgid "Once we’ve finished whatever activity that required us to move the resources to pcmk-1, in our case nothing, we can then allow the cluster to resume normal operation with the unmove command. Since we previously configured a default stickiness, the resources will remain on pcmk-1." msgstr "" #. Tag: programlisting #, no-c-format msgid "# pcs constraint all\n" "Location Constraints:\n" " Resource: WebSite\n" " Enabled on: pcmk-1 (score:INFINITY) (id:location-WebSite-pcmk-1-INFINITY)\n" "Ordering Constraints:\n" " start ClusterIP then start WebSite (Mandatory) (id:order-ClusterIP-WebSite-mandatory)\n" "Colocation Constraints:\n" " WebSite with ClusterIP (INFINITY) (id:colocation-WebSite-ClusterIP-INFINITY)\n" "# pcs constraint rm location-WebSite-pcmk-1-INFINITY\n" "# pcs constraint\n" "Location Constraints:\n" "Ordering Constraints:\n" " start ClusterIP then start WebSite\n" "Colocation Constraints:\n" " WebSite with ClusterIP" msgstr "" #. Tag: para #, no-c-format msgid "Note that the constraint is now gone. If we check the cluster status, we can also see that as expected the resources are still active on pcmk-1." msgstr "" #. Tag: programlisting #, no-c-format msgid "# pcs status\n" "\n" "Last updated: Fri Sep 14 11:57:12 2012\n" "Last change: Fri Sep 14 11:57:03 2012 via cibadmin on pcmk-1\n" "Stack: corosync\n" "Current DC: pcmk-2 (2) - partition with quorum\n" "Version: 1.1.8-1.el7-60a19ed12fdb4d5c6a6b6767f52e5391e447fec0\n" "2 Nodes configured, unknown expected votes\n" "2 Resources configured.\n" "\n" "Online: [ pcmk-1 pcmk-2 ]\n" "\n" "Full list of resources:\n" "\n" " ClusterIP (ocf::heartbeat:IPaddr2): Started pcmk-1\n" " WebSite (ocf::heartbeat:apache): Started pcmk-1" msgstr "" pacemaker-master/doc/Clusters_from_Scratch/pot/Ch-Installation.pot000066400000000000000000001755201217637305600257050ustar00rootroot00000000000000# # AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: 0\n" "POT-Creation-Date: 2012-10-17T05:19:03\n" "PO-Revision-Date: 2012-10-17T05:19:03\n" "Last-Translator: Automatically generated\n" "Language-Team: None\n" "MIME-Version: 1.0\n" "Content-Type: application/x-publican; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. Tag: title #, no-c-format msgid "Installation" msgstr "" #. Tag: title #, no-c-format msgid "OS Installation" msgstr "" #. Tag: para #, no-c-format msgid "Detailed instructions for installing Fedora are available at http://docs.fedoraproject.org/en-US/Fedora/17/html/Installation_Guide/ in a number of languages. The abbreviated version is as follows…" msgstr "" #. Tag: para #, no-c-format msgid "Point your browser to http://fedoraproject.org/en/get-fedora-all, locate the Install Media section and download the install DVD that matches your hardware." msgstr "" #. Tag: para #, no-c-format msgid "Burn the disk image to a DVD http://docs.fedoraproject.org/en-US/Fedora/16/html/Burning_ISO_images_to_disc/index.html and boot from it, or use the image to boot a virtual machine." msgstr "" #. Tag: para #, no-c-format msgid "After clicking through the welcome screen, select your language, keyboard layout http://docs.fedoraproject.org/en-US/Fedora/16/html/Installation_Guide/sn-keyboard-x86.html and storage type http://docs.fedoraproject.org/en-US/Fedora/16/html/Installation_Guide/Storage_Devices-x86.html" msgstr "" #. Tag: para #, no-c-format msgid "Assign your machine a host name. http://docs.fedoraproject.org/en-US/Fedora/16/html/Installation_Guide/sn-Netconfig-x86.html I happen to control the clusterlabs.org domain name, so I will use that here." msgstr "" #. Tag: para #, no-c-format msgid "Do not accept the default network settings. Cluster machines should never obtain an IP address via DHCP." msgstr "" #. Tag: para #, no-c-format msgid "When you are presented with the Configure Network advanced option, select that option before continuing with the installation process to specify a fixed IPv4 address for System eth0. Be sure to also enter the Routes section and add an entry for your default gateway." msgstr "" #. Tag: phrase #, no-c-format msgid "Custom network settings" msgstr "" #. Tag: para #, no-c-format msgid "If you miss this step, this can easily be configured after installation. You will have to navigate to system settings and select network. From there you can select what device to configure." msgstr "" #. Tag: para #, no-c-format msgid "You will then be prompted to indicate the machine’s physical location http://docs.fedoraproject.org/en-US/Fedora/16/html/Installation_Guide/s1-timezone-x86.html and to supply a root password. http://docs.fedoraproject.org/en-US/Fedora/16/html/Installation_Guide/sn-account_configuration-x86.html" msgstr "" #. Tag: para #, no-c-format msgid "Now select where you want Fedora installed. http://docs.fedoraproject.org/en-US/Fedora/16/html/Installation_Guide/s1-diskpartsetup-x86.html As I don’t care about any existing data, I will accept the default and allow Fedora to use the complete drive." msgstr "" #. Tag: para #, no-c-format msgid "By default Fedora uses LVM for partitioning which allows us to dynamically change the amount of space allocated to a given partition." msgstr "" #. Tag: para #, no-c-format msgid "However, by default it also allocates all free space to the / (aka. root) partition which cannot be dynamically reduced in size (dynamic increases are fine by-the-way)." msgstr "" #. Tag: para #, no-c-format msgid "So if you plan on following the DRBD or GFS2 portions of this guide, you should reserve at least 1Gb of space on each machine from which to create a shared volume. To do so select the Review and modify partitioning layout checkbox before clicking Next. You will then be given an opportunity to reduce the size of the root partition." msgstr "" #. Tag: para #, no-c-format msgid "Next choose which software should be installed. http://docs.fedoraproject.org/en-US/Fedora/16/html/Installation_Guide/s1-pkgselection-x86.html Change the selection to Minimal so that we see everything that gets installed. Don’t enable updates yet, we’ll do that (and install any extra software we need) later. After you click next, Fedora will begin installing." msgstr "" #. Tag: para #, no-c-format msgid "Go grab something to drink, this may take a while." msgstr "" #. Tag: para #, no-c-format msgid "Once the node reboots, you’ll see a (possibly mangled) login prompt on the console. Login using root and the password you created earlier." msgstr "" #. Tag: phrase #, no-c-format msgid "Initial Console" msgstr "" #. Tag: para #, no-c-format msgid "From here on in we’re going to be working exclusively from the terminal." msgstr "" #. Tag: title #, no-c-format msgid "Post Installation Tasks" msgstr "" #. Tag: title #, no-c-format msgid "Networking" msgstr "" #. Tag: para #, no-c-format msgid "Bring up the network and ensure it starts at boot" msgstr "" #. Tag: programlisting #, no-c-format msgid "# service network start\n" "# chkconfig network on" msgstr "" #. Tag: para #, no-c-format msgid "Check the machine has the static IP address you configured earlier" msgstr "" #. Tag: programlisting #, no-c-format msgid "# ip addr\n" "1: lo: <LOOPBACK,UP,LOWER_UP> mtu 16436 qdisc noqueue state UNKNOWN\n" " link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00\n" " inet 127.0.0.1/8 scope host lo\n" " inet6 ::1/128 scope host\n" " valid_lft forever preferred_lft forever\n" "2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000\n" " link/ether 52:54:00:d7:d6:08 brd ff:ff:ff:ff:ff:ff\n" " inet 192.168.122.101/24 brd 192.168.122.255 scope global eth0\n" " inet6 fe80::5054:ff:fed7:d608/64 scope link\n" " valid_lft forever preferred_lft forever" msgstr "" #. Tag: para #, no-c-format msgid "Now check the default route setting:" msgstr "" #. Tag: programlisting #, no-c-format msgid "[root@pcmk-1 ~]# ip route\n" "default via 192.168.122.1 dev eth0\n" "192.168.122.0/24 dev eth0 proto kernel scope link src 192.168.122.101" msgstr "" #. Tag: para #, no-c-format msgid "If there is no line beginning with default via, then you may need to add a line such as" msgstr "" #. Tag: programlisting #, no-c-format msgid "GATEWAY=192.168.122.1" msgstr "" #. Tag: para #, no-c-format msgid "to /etc/sysconfig/network and restart the network." msgstr "" #. Tag: para #, no-c-format msgid "Now check for connectivity to the outside world. Start small by testing if we can read the gateway we configured." msgstr "" #. Tag: programlisting #, no-c-format msgid "# ping -c 1 192.168.122.1\n" "PING 192.168.122.1 (192.168.122.1) 56(84) bytes of data.\n" "64 bytes from 192.168.122.1: icmp_req=1 ttl=64 time=0.249 ms\n" "\n" "--- 192.168.122.1 ping statistics ---\n" "1 packets transmitted, 1 received, 0% packet loss, time 0ms\n" "rtt min/avg/max/mdev = 0.249/0.249/0.249/0.000 ms" msgstr "" #. Tag: para #, no-c-format msgid "Now try something external, choose a location you know will be available." msgstr "" #. Tag: programlisting #, no-c-format msgid "# ping -c 1 www.google.com\n" "PING www.l.google.com (173.194.72.106) 56(84) bytes of data.\n" "64 bytes from tf-in-f106.1e100.net (173.194.72.106): icmp_req=1 ttl=41 time=167 ms\n" "\n" "--- www.l.google.com ping statistics ---\n" "1 packets transmitted, 1 received, 0% packet loss, time 0ms\n" "rtt min/avg/max/mdev = 167.618/167.618/167.618/0.000 ms" msgstr "" #. Tag: title #, no-c-format msgid "Leaving the Console" msgstr "" #. Tag: para #, no-c-format msgid "The console isn’t a very friendly place to work from, we will now switch to accessing the machine remotely via SSH where we can use copy&paste etc." msgstr "" #. Tag: para #, no-c-format msgid "First we check we can see the newly installed at all:" msgstr "" #. Tag: programlisting #, no-c-format msgid "beekhof@f16 ~ # ping -c 1 192.168.122.101\n" "PING 192.168.122.101 (192.168.122.101) 56(84) bytes of data.\n" "64 bytes from 192.168.122.101: icmp_req=1 ttl=64 time=1.01 ms\n" "\n" "--- 192.168.122.101 ping statistics ---\n" "1 packets transmitted, 1 received, 0% packet loss, time 0ms\n" "rtt min/avg/max/mdev = 1.012/1.012/1.012/0.000 ms" msgstr "" #. Tag: para #, no-c-format msgid "Next we login via SSH" msgstr "" #. Tag: programlisting #, no-c-format msgid "beekhof@f16 ~ # ssh -l root 192.168.122.11\n" "root@192.168.122.11's password:\n" "Last login: Fri Mar 30 19:41:19 2012 from 192.168.122.1\n" "[root@pcmk-1 ~]#" msgstr "" #. Tag: title #, no-c-format msgid "Security Shortcuts" msgstr "" #. Tag: para #, no-c-format msgid "To simplify this guide and focus on the aspects directly connected to clustering, we will now disable the machine’s firewall and SELinux installation." msgstr "" #. Tag: para #, no-c-format msgid "Both of these actions create significant security issues and should not be performed on machines that will be exposed to the outside world." msgstr "" #. Tag: literallayout #, no-c-format msgid "TODO: Create an Appendix that deals with (at least) re-enabling the firewall." msgstr "" #. Tag: programlisting #, no-c-format msgid "# setenforce 0\n" "# sed -i.bak \"s/SELINUX=enforcing/SELINUX=permissive/g\" /etc/selinux/config\n" "# systemctl disable iptables.service\n" "# rm '/etc/systemd/system/basic.target.wants/iptables.service'\n" "# systemctl stop iptables.service" msgstr "" #. Tag: title #, no-c-format msgid "Short Node Names" msgstr "" #. Tag: para #, no-c-format msgid "During installation, we filled in the machine’s fully qualifier domain name (FQDN) which can be rather long when it appears in cluster logs and status output. See for yourself how the machine identifies itself: Nodesshort name short name " msgstr "" #. Tag: programlisting #, no-c-format msgid "# uname -n\n" "pcmk-1.clusterlabs.org\n" "# dnsdomainname\n" "clusterlabs.org" msgstr "" #. Tag: para #, no-c-format msgid " NodesDomain name (Query) Domain name (Query) " msgstr "" #. Tag: para #, no-c-format msgid "The output from the second command is fine, but we really don’t need the domain name included in the basic host details. To address this, we need to update /etc/sysconfig/network. This is what it should look like before we start." msgstr "" #. Tag: programlisting #, no-c-format msgid "# cat /etc/sysconfig/network\n" "NETWORKING=yes\n" "HOSTNAME=pcmk-1.clusterlabs.org\n" "GATEWAY=192.168.122.1" msgstr "" #. Tag: para #, no-c-format msgid "All we need to do now is strip off the domain name portion, which is stored elsewhere anyway." msgstr "" #. Tag: programlisting #, no-c-format msgid " # sed -i.sed 's/\\.[a-z].*//g' /etc/sysconfig/network" msgstr "" #. Tag: para #, no-c-format msgid "Now confirm the change was successful. The revised file contents should look something like this." msgstr "" #. Tag: programlisting #, no-c-format msgid "# cat /etc/sysconfig/network\n" "NETWORKING=yes\n" "HOSTNAME=pcmk-1\n" "GATEWAY=192.168.122.1" msgstr "" #. Tag: para #, no-c-format msgid "However we’re not finished. The machine wont normally see the shortened host name until about it reboots, but we can force it to update." msgstr "" #. Tag: programlisting #, no-c-format msgid "# source /etc/sysconfig/network\n" "# hostname $HOSTNAME" msgstr "" #. Tag: para #, no-c-format msgid " NodesDomain name (Remove from host name) Domain name (Remove from host name) " msgstr "" #. Tag: para #, no-c-format msgid "Now check the machine is using the correct names" msgstr "" #. Tag: programlisting #, no-c-format msgid "# uname -n\n" "pcmk-1\n" "# dnsdomainname\n" "clusterlabs.org" msgstr "" #. Tag: title #, no-c-format msgid "NTP" msgstr "" #. Tag: para #, no-c-format msgid "It is highly recommended to enable NTP on your cluster nodes. Doing so ensures all nodes agree on the current time and makes reading log files significantly easier. http://docs.fedoraproject.org/en-US/Fedora/17/html-single/System_Administrators_Guide/index.html#ch-Configuring_the_Date_and_Time" msgstr "" #. Tag: title #, no-c-format msgid "Before You Continue" msgstr "" #. Tag: para #, no-c-format msgid "Repeat the Installation steps so far, so that you have two Fedora nodes ready to have the cluster software installed." msgstr "" #. Tag: para #, no-c-format msgid "For the purposes of this document, the additional node is called pcmk-2 with address 192.168.122.102." msgstr "" #. Tag: title #, no-c-format msgid "Finalize Networking" msgstr "" #. Tag: para #, no-c-format msgid "Confirm that you can communicate between the two new nodes:" msgstr "" #. Tag: programlisting #, no-c-format msgid "# ping -c 3 192.168.122.102\n" "PING 192.168.122.102 (192.168.122.102) 56(84) bytes of data.\n" "64 bytes from 192.168.122.102: icmp_seq=1 ttl=64 time=0.343 ms\n" "64 bytes from 192.168.122.102: icmp_seq=2 ttl=64 time=0.402 ms\n" "64 bytes from 192.168.122.102: icmp_seq=3 ttl=64 time=0.558 ms\n" "\n" "--- 192.168.122.102 ping statistics ---\n" "3 packets transmitted, 3 received, 0% packet loss, time 2000ms\n" "rtt min/avg/max/mdev = 0.343/0.434/0.558/0.092 ms" msgstr "" #. Tag: para #, no-c-format msgid "Now we need to make sure we can communicate with the machines by their name. If you have a DNS server, add additional entries for the two machines. Otherwise, you’ll need to add the machines to /etc/hosts . Below are the entries for my cluster nodes:" msgstr "" #. Tag: programlisting #, no-c-format msgid "# grep pcmk /etc/hosts\n" "192.168.122.101 pcmk-1.clusterlabs.org pcmk-1\n" "192.168.122.102 pcmk-2.clusterlabs.org pcmk-2" msgstr "" #. Tag: para #, no-c-format msgid "We can now verify the setup by again using ping:" msgstr "" #. Tag: programlisting #, no-c-format msgid "# ping -c 3 pcmk-2\n" "PING pcmk-2.clusterlabs.org (192.168.122.101) 56(84) bytes of data.\n" "64 bytes from pcmk-1.clusterlabs.org (192.168.122.101): icmp_seq=1 ttl=64 time=0.164 ms\n" "64 bytes from pcmk-1.clusterlabs.org (192.168.122.101): icmp_seq=2 ttl=64 time=0.475 ms\n" "64 bytes from pcmk-1.clusterlabs.org (192.168.122.101): icmp_seq=3 ttl=64 time=0.186 ms\n" "\n" "--- pcmk-2.clusterlabs.org ping statistics ---\n" "3 packets transmitted, 3 received, 0% packet loss, time 2001ms\n" "rtt min/avg/max/mdev = 0.164/0.275/0.475/0.141 ms" msgstr "" #. Tag: title #, no-c-format msgid "Configure SSH" msgstr "" #. Tag: para #, no-c-format msgid "SSH is a convenient and secure way to copy files and perform commands remotely. For the purposes of this guide, we will create a key without a password (using the -N option) so that we can perform remote actions without being prompted." msgstr "" #. Tag: para #, no-c-format msgid " SSH " msgstr "" #. Tag: para #, no-c-format msgid "Unprotected SSH keys, those without a password, are not recommended for servers exposed to the outside world. We use them here only to simplify the demo." msgstr "" #. Tag: para #, no-c-format msgid "Create a new key and allow anyone with that key to log in:" msgstr "" #. Tag: title #, no-c-format msgid "Creating and Activating a new SSH Key" msgstr "" #. Tag: programlisting #, no-c-format msgid "# ssh-keygen -t dsa -f ~/.ssh/id_dsa -N \"\"\n" "Generating public/private dsa key pair.\n" "Your identification has been saved in /root/.ssh/id_dsa.\n" "Your public key has been saved in /root/.ssh/id_dsa.pub.\n" "The key fingerprint is:\n" "91:09:5c:82:5a:6a:50:08:4e:b2:0c:62:de:cc:74:44 root@pcmk-1.clusterlabs.org\n" "\n" "The key's randomart image is:\n" "+--[ DSA 1024]----+\n" "|==.ooEo.. |\n" "|X O + .o o |\n" "| * A + |\n" "| + . |\n" "| . S |\n" "| |\n" "| |\n" "| |\n" "| |\n" "+-----------------+\n" "\n" "# cp .ssh/id_dsa.pub .ssh/authorized_keys" msgstr "" #. Tag: para #, no-c-format msgid " Creating and Activating a new SSH Key " msgstr "" #. Tag: para #, no-c-format msgid "Install the key on the other nodes and test that you can now run commands remotely, without being prompted" msgstr "" #. Tag: title #, no-c-format msgid "Installing the SSH Key on Another Host" msgstr "" #. Tag: programlisting #, no-c-format msgid "# scp -r .ssh pcmk-2:\n" "The authenticity of host 'pcmk-2 (192.168.122.102)' can't be established.\n" "RSA key fingerprint is b1:2b:55:93:f1:d9:52:2b:0f:f2:8a:4e:ae:c6:7c:9a.\n" "Are you sure you want to continue connecting (yes/no)? yes\n" "Warning: Permanently added 'pcmk-2,192.168.122.102' (RSA) to the list of known hosts.root@pcmk-2's password:\n" "id_dsa.pub 100% 616 0.6KB/s 00:00\n" "id_dsa 100% 672 0.7KB/s 00:00\n" "known_hosts 100% 400 0.4KB/s 00:00\n" "authorized_keys 100% 616 0.6KB/s 00:00\n" "# ssh pcmk-2 -- uname -n\n" "pcmk-2\n" "#" msgstr "" #. Tag: title #, no-c-format msgid "Cluster Software Installation" msgstr "" #. Tag: title #, no-c-format msgid "Install the Cluster Software" msgstr "" #. Tag: para #, no-c-format msgid "Since version 12, Fedora comes with recent versions of everything you need, so simply fire up the shell and run:" msgstr "" #. Tag: programlisting #, no-c-format msgid "# yum install -y pacemaker corosync" msgstr "" #. Tag: literallayout #, no-c-format msgid "fedora/metalink | 38 kB 00:00\n" "fedora | 4.2 kB 00:00\n" "fedora/primary_db | 14 MB 00:21\n" "updates/metalink | 2.7 kB 00:00\n" "updates | 2.6 kB 00:00\n" "updates/primary_db | 1.2 kB 00:00\n" "updates-testing/metalink | 28 kB 00:00\n" "updates-testing | 4.5 kB 00:00\n" "updates-testing/primary_db | 4.5 MB 00:12\n" "Setting up Install Process\n" "Resolving Dependencies\n" "--> Running transaction check\n" "---> Package corosync.x86_64 0:1.99.9-1.fc17 will be installed\n" "--> Processing Dependency: corosynclib = 1.99.9-1.fc17 for package: corosync-1.99.9-1.fc17.x86_64\n" "--> Processing Dependency: libxslt for package: corosync-1.99.9-1.fc17.x86_64\n" "--> Processing Dependency: libvotequorum.so.5(COROSYNC_VOTEQUORUM_1.0)(64bit) for package: corosync-1.99.9-1.fc17.x86_64\n" "--> Processing Dependency: libquorum.so.5(COROSYNC_QUORUM_1.0)(64bit) for package: corosync-1.99.9-1.fc17.x86_64\n" "--> Processing Dependency: libcpg.so.4(COROSYNC_CPG_1.0)(64bit) for package: corosync-1.99.9-1.fc17.x86_64\n" "--> Processing Dependency: libcmap.so.4(COROSYNC_CMAP_1.0)(64bit) for package: corosync-1.99.9-1.fc17.x86_64\n" "--> Processing Dependency: libcfg.so.6(COROSYNC_CFG_0.82)(64bit) for package: corosync-1.99.9-1.fc17.x86_64\n" "--> Processing Dependency: libvotequorum.so.5()(64bit) for package: corosync-1.99.9-1.fc17.x86_64\n" "--> Processing Dependency: libtotem_pg.so.5()(64bit) for package: corosync-1.99.9-1.fc17.x86_64\n" "--> Processing Dependency: libquorum.so.5()(64bit) for package: corosync-1.99.9-1.fc17.x86_64\n" "--> Processing Dependency: libqb.so.0()(64bit) for package: corosync-1.99.9-1.fc17.x86_64\n" "--> Processing Dependency: libnetsnmp.so.30()(64bit) for package: corosync-1.99.9-1.fc17.x86_64\n" "--> Processing Dependency: libcpg.so.4()(64bit) for package: corosync-1.99.9-1.fc17.x86_64\n" "--> Processing Dependency: libcorosync_common.so.4()(64bit) for package: corosync-1.99.9-1.fc17.x86_64\n" "--> Processing Dependency: libcmap.so.4()(64bit) for package: corosync-1.99.9-1.fc17.x86_64\n" "--> Processing Dependency: libcfg.so.6()(64bit) for package: corosync-1.99.9-1.fc17.x86_64\n" "---> Package pacemaker.x86_64 0:1.1.7-2.fc17 will be installed\n" "--> Processing Dependency: pacemaker-libs = 1.1.7-2.fc17 for package: pacemaker-1.1.7-2.fc17.x86_64\n" "--> Processing Dependency: pacemaker-cluster-libs = 1.1.7-2.fc17 for package: pacemaker-1.1.7-2.fc17.x86_64\n" "--> Processing Dependency: pacemaker-cli = 1.1.7-2.fc17 for package: pacemaker-1.1.7-2.fc17.x86_64\n" "--> Processing Dependency: resource-agents for package: pacemaker-1.1.7-2.fc17.x86_64\n" "--> Processing Dependency: perl(Getopt::Long) for package: pacemaker-1.1.7-2.fc17.x86_64\n" "--> Processing Dependency: libgnutls.so.26(GNUTLS_1_4)(64bit) for package: pacemaker-1.1.7-2.fc17.x86_64\n" "--> Processing Dependency: cluster-glue for package: pacemaker-1.1.7-2.fc17.x86_64\n" "--> Processing Dependency: /usr/bin/perl for package: pacemaker-1.1.7-2.fc17.x86_64\n" "--> Processing Dependency: libtransitioner.so.1()(64bit) for package: pacemaker-1.1.7-2.fc17.x86_64\n" "--> Processing Dependency: libstonithd.so.1()(64bit) for package: pacemaker-1.1.7-2.fc17.x86_64\n" "--> Processing Dependency: libstonith.so.1()(64bit) for package: pacemaker-1.1.7-2.fc17.x86_64\n" "--> Processing Dependency: libplumb.so.2()(64bit) for package: pacemaker-1.1.7-2.fc17.x86_64\n" "--> Processing Dependency: libpils.so.2()(64bit) for package: pacemaker-1.1.7-2.fc17.x86_64\n" "--> Processing Dependency: libpengine.so.3()(64bit) for package: pacemaker-1.1.7-2.fc17.x86_64\n" "--> Processing Dependency: libpe_status.so.3()(64bit) for package: pacemaker-1.1.7-2.fc17.x86_64\n" "--> Processing Dependency: libpe_rules.so.2()(64bit) for package: pacemaker-1.1.7-2.fc17.x86_64\n" "--> Processing Dependency: libltdl.so.7()(64bit) for package: pacemaker-1.1.7-2.fc17.x86_64\n" "--> Processing Dependency: liblrm.so.2()(64bit) for package: pacemaker-1.1.7-2.fc17.x86_64\n" "--> Processing Dependency: libgnutls.so.26()(64bit) for package: pacemaker-1.1.7-2.fc17.x86_64\n" "--> Processing Dependency: libcrmcommon.so.2()(64bit) for package: pacemaker-1.1.7-2.fc17.x86_64\n" "--> Processing Dependency: libcrmcluster.so.1()(64bit) for package: pacemaker-1.1.7-2.fc17.x86_64\n" "--> Processing Dependency: libcib.so.1()(64bit) for package: pacemaker-1.1.7-2.fc17.x86_64\n" "--> Running transaction check\n" "---> Package cluster-glue.x86_64 0:1.0.6-9.fc17.1 will be installed\n" "--> Processing Dependency: perl-TimeDate for package: cluster-glue-1.0.6-9.fc17.1.x86_64\n" "--> Processing Dependency: libOpenIPMIutils.so.0()(64bit) for package: cluster-glue-1.0.6-9.fc17.1.x86_64\n" "--> Processing Dependency: libOpenIPMIposix.so.0()(64bit) for package: cluster-glue-1.0.6-9.fc17.1.x86_64\n" "--> Processing Dependency: libOpenIPMI.so.0()(64bit) for package: cluster-glue-1.0.6-9.fc17.1.x86_64\n" "---> Package cluster-glue-libs.x86_64 0:1.0.6-9.fc17.1 will be installed\n" "---> Package corosynclib.x86_64 0:1.99.9-1.fc17 will be installed\n" "--> Processing Dependency: librdmacm.so.1(RDMACM_1.0)(64bit) for package: corosynclib-1.99.9-1.fc17.x86_64\n" "--> Processing Dependency: libibverbs.so.1(IBVERBS_1.1)(64bit) for package: corosynclib-1.99.9-1.fc17.x86_64\n" "--> Processing Dependency: libibverbs.so.1(IBVERBS_1.0)(64bit) for package: corosynclib-1.99.9-1.fc17.x86_64\n" "--> Processing Dependency: librdmacm.so.1()(64bit) for package: corosynclib-1.99.9-1.fc17.x86_64\n" "--> Processing Dependency: libibverbs.so.1()(64bit) for package: corosynclib-1.99.9-1.fc17.x86_64\n" "---> Package gnutls.x86_64 0:2.12.17-1.fc17 will be installed\n" "--> Processing Dependency: libtasn1.so.3(LIBTASN1_0_3)(64bit) for package: gnutls-2.12.17-1.fc17.x86_64\n" "--> Processing Dependency: libtasn1.so.3()(64bit) for package: gnutls-2.12.17-1.fc17.x86_64\n" "--> Processing Dependency: libp11-kit.so.0()(64bit) for package: gnutls-2.12.17-1.fc17.x86_64\n" "---> Package libqb.x86_64 0:0.11.1-1.fc17 will be installed\n" "---> Package libtool-ltdl.x86_64 0:2.4.2-3.fc17 will be installed\n" "---> Package libxslt.x86_64 0:1.1.26-9.fc17 will be installed\n" "---> Package net-snmp-libs.x86_64 1:5.7.1-4.fc17 will be installed\n" "---> Package pacemaker-cli.x86_64 0:1.1.7-2.fc17 will be installed\n" "---> Package pacemaker-cluster-libs.x86_64 0:1.1.7-2.fc17 will be installed\n" "---> Package pacemaker-libs.x86_64 0:1.1.7-2.fc17 will be installed\n" "---> Package perl.x86_64 4:5.14.2-211.fc17 will be installed\n" "--> Processing Dependency: perl-libs = 4:5.14.2-211.fc17 for package: 4:perl-5.14.2-211.fc17.x86_64\n" "--> Processing Dependency: perl(threads::shared) >= 1.21 for package: 4:perl-5.14.2-211.fc17.x86_64\n" "--> Processing Dependency: perl(Socket) >= 1.3 for package: 4:perl-5.14.2-211.fc17.x86_64\n" "--> Processing Dependency: perl(Scalar::Util) >= 1.10 for package: 4:perl-5.14.2-211.fc17.x86_64\n" "--> Processing Dependency: perl(File::Spec) >= 0.8 for package: 4:perl-5.14.2-211.fc17.x86_64\n" "--> Processing Dependency: perl-macros for package: 4:perl-5.14.2-211.fc17.x86_64\n" "--> Processing Dependency: perl-libs for package: 4:perl-5.14.2-211.fc17.x86_64\n" "--> Processing Dependency: perl(threads::shared) for package: 4:perl-5.14.2-211.fc17.x86_64\n" "--> Processing Dependency: perl(threads) for package: 4:perl-5.14.2-211.fc17.x86_64\n" "--> Processing Dependency: perl(Socket) for package: 4:perl-5.14.2-211.fc17.x86_64\n" "--> Processing Dependency: perl(Scalar::Util) for package: 4:perl-5.14.2-211.fc17.x86_64\n" "--> Processing Dependency: perl(Pod::Simple) for package: 4:perl-5.14.2-211.fc17.x86_64\n" "--> Processing Dependency: perl(Module::Pluggable) for package: 4:perl-5.14.2-211.fc17.x86_64\n" "--> Processing Dependency: perl(List::Util) for package: 4:perl-5.14.2-211.fc17.x86_64\n" "--> Processing Dependency: perl(File::Spec::Unix) for package: 4:perl-5.14.2-211.fc17.x86_64\n" "--> Processing Dependency: perl(File::Spec::Functions) for package: 4:perl-5.14.2-211.fc17.x86_64\n" "--> Processing Dependency: perl(File::Spec) for package: 4:perl-5.14.2-211.fc17.x86_64\n" "--> Processing Dependency: perl(Cwd) for package: 4:perl-5.14.2-211.fc17.x86_64\n" "--> Processing Dependency: perl(Carp) for package: 4:perl-5.14.2-211.fc17.x86_64\n" "--> Processing Dependency: libperl.so()(64bit) for package: 4:perl-5.14.2-211.fc17.x86_64\n" "---> Package resource-agents.x86_64 0:3.9.2-2.fc17.1 will be installed\n" "--> Processing Dependency: /usr/sbin/rpc.nfsd for package: resource-agents-3.9.2-2.fc17.1.x86_64\n" "--> Processing Dependency: /usr/sbin/rpc.mountd for package: resource-agents-3.9.2-2.fc17.1.x86_64\n" "--> Processing Dependency: /usr/sbin/ethtool for package: resource-agents-3.9.2-2.fc17.1.x86_64\n" "--> Processing Dependency: /sbin/rpc.statd for package: resource-agents-3.9.2-2.fc17.1.x86_64\n" "--> Processing Dependency: /sbin/quotaon for package: resource-agents-3.9.2-2.fc17.1.x86_64\n" "--> Processing Dependency: /sbin/quotacheck for package: resource-agents-3.9.2-2.fc17.1.x86_64\n" "--> Processing Dependency: /sbin/mount.nfs4 for package: resource-agents-3.9.2-2.fc17.1.x86_64\n" "--> Processing Dependency: /sbin/mount.nfs for package: resource-agents-3.9.2-2.fc17.1.x86_64\n" "--> Processing Dependency: /sbin/mount.cifs for package: resource-agents-3.9.2-2.fc17.1.x86_64\n" "--> Processing Dependency: /sbin/fsck.xfs for package: resource-agents-3.9.2-2.fc17.1.x86_64\n" "--> Processing Dependency: libnet.so.1()(64bit) for package: resource-agents-3.9.2-2.fc17.1.x86_64\n" "--> Running transaction check\n" "---> Package OpenIPMI-libs.x86_64 0:2.0.18-13.fc17 will be installed\n" "---> Package cifs-utils.x86_64 0:5.3-2.fc17 will be installed\n" "--> Processing Dependency: libtalloc.so.2(TALLOC_2.0.2)(64bit) for package: cifs-utils-5.3-2.fc17.x86_64\n" "--> Processing Dependency: keyutils for package: cifs-utils-5.3-2.fc17.x86_64\n" "--> Processing Dependency: libwbclient.so.0()(64bit) for package: cifs-utils-5.3-2.fc17.x86_64\n" "--> Processing Dependency: libtalloc.so.2()(64bit) for package: cifs-utils-5.3-2.fc17.x86_64\n" "---> Package ethtool.x86_64 2:3.2-2.fc17 will be installed\n" "---> Package libibverbs.x86_64 0:1.1.6-2.fc17 will be installed\n" "---> Package libnet.x86_64 0:1.1.5-3.fc17 will be installed\n" "---> Package librdmacm.x86_64 0:1.0.15-1.fc17 will be installed\n" "---> Package libtasn1.x86_64 0:2.12-1.fc17 will be installed\n" "---> Package nfs-utils.x86_64 1:1.2.5-12.fc17 will be installed\n" "--> Processing Dependency: rpcbind for package: 1:nfs-utils-1.2.5-12.fc17.x86_64\n" "--> Processing Dependency: libtirpc for package: 1:nfs-utils-1.2.5-12.fc17.x86_64\n" "--> Processing Dependency: libnfsidmap for package: 1:nfs-utils-1.2.5-12.fc17.x86_64\n" "--> Processing Dependency: libgssglue.so.1(libgssapi_CITI_2)(64bit) for package: 1:nfs-utils-1.2.5-12.fc17.x86_64\n" "--> Processing Dependency: libgssglue for package: 1:nfs-utils-1.2.5-12.fc17.x86_64\n" "--> Processing Dependency: libevent for package: 1:nfs-utils-1.2.5-12.fc17.x86_64\n" "--> Processing Dependency: libtirpc.so.1()(64bit) for package: 1:nfs-utils-1.2.5-12.fc17.x86_64\n" "--> Processing Dependency: libnfsidmap.so.0()(64bit) for package: 1:nfs-utils-1.2.5-12.fc17.x86_64\n" "--> Processing Dependency: libgssglue.so.1()(64bit) for package: 1:nfs-utils-1.2.5-12.fc17.x86_64\n" "--> Processing Dependency: libevent-2.0.so.5()(64bit) for package: 1:nfs-utils-1.2.5-12.fc17.x86_64\n" "---> Package p11-kit.x86_64 0:0.12-1.fc17 will be installed\n" "---> Package perl-Carp.noarch 0:1.22-2.fc17 will be installed\n" "---> Package perl-Module-Pluggable.noarch 1:3.90-211.fc17 will be installed\n" "---> Package perl-PathTools.x86_64 0:3.33-211.fc17 will be installed\n" "---> Package perl-Pod-Simple.noarch 1:3.16-211.fc17 will be installed\n" "--> Processing Dependency: perl(Pod::Escapes) >= 1.04 for package: 1:perl-Pod-Simple-3.16-211.fc17.noarch\n" "---> Package perl-Scalar-List-Utils.x86_64 0:1.25-1.fc17 will be installed\n" "---> Package perl-Socket.x86_64 0:2.001-1.fc17 will be installed\n" "---> Package perl-TimeDate.noarch 1:1.20-6.fc17 will be installed\n" "---> Package perl-libs.x86_64 4:5.14.2-211.fc17 will be installed\n" "---> Package perl-macros.x86_64 4:5.14.2-211.fc17 will be installed\n" "---> Package perl-threads.x86_64 0:1.86-2.fc17 will be installed\n" "---> Package perl-threads-shared.x86_64 0:1.40-2.fc17 will be installed\n" "---> Package quota.x86_64 1:4.00-3.fc17 will be installed\n" "--> Processing Dependency: quota-nls = 1:4.00-3.fc17 for package: 1:quota-4.00-3.fc17.x86_64\n" "--> Processing Dependency: tcp_wrappers for package: 1:quota-4.00-3.fc17.x86_64\n" "---> Package xfsprogs.x86_64 0:3.1.8-1.fc17 will be installed\n" "--> Running transaction check\n" "---> Package keyutils.x86_64 0:1.5.5-2.fc17 will be installed\n" "---> Package libevent.x86_64 0:2.0.14-2.fc17 will be installed\n" "---> Package libgssglue.x86_64 0:0.3-1.fc17 will be installed\n" "---> Package libnfsidmap.x86_64 0:0.25-1.fc17 will be installed\n" "---> Package libtalloc.x86_64 0:2.0.7-4.fc17 will be installed\n" "---> Package libtirpc.x86_64 0:0.2.2-2.1.fc17 will be installed\n" "---> Package libwbclient.x86_64 1:3.6.3-81.fc17.1 will be installed\n" "---> Package perl-Pod-Escapes.noarch 1:1.04-211.fc17 will be installed\n" "---> Package quota-nls.noarch 1:4.00-3.fc17 will be installed\n" "---> Package rpcbind.x86_64 0:0.2.0-16.fc17 will be installed\n" "---> Package tcp_wrappers.x86_64 0:7.6-69.fc17 will be installed\n" "--> Finished Dependency Resolution\n" "\n" "Dependencies Resolved\n" "\n" "=====================================================================================\n" " Package Arch Version Repository Size\n" "=====================================================================================\n" "Installing:\n" " corosync x86_64 1.99.9-1.fc17 updates-testing 159 k\n" " pacemaker x86_64 1.1.7-2.fc17 updates-testing 362 k\n" "Installing for dependencies:\n" " OpenIPMI-libs x86_64 2.0.18-13.fc17 fedora 466 k\n" " cifs-utils x86_64 5.3-2.fc17 updates-testing 66 k\n" " cluster-glue x86_64 1.0.6-9.fc17.1 fedora 229 k\n" " cluster-glue-libs x86_64 1.0.6-9.fc17.1 fedora 121 k\n" " corosynclib x86_64 1.99.9-1.fc17 updates-testing 96 k\n" " ethtool x86_64 2:3.2-2.fc17 fedora 94 k\n" " gnutls x86_64 2.12.17-1.fc17 fedora 385 k\n" " keyutils x86_64 1.5.5-2.fc17 fedora 49 k\n" " libevent x86_64 2.0.14-2.fc17 fedora 160 k\n" " libgssglue x86_64 0.3-1.fc17 fedora 24 k\n" " libibverbs x86_64 1.1.6-2.fc17 fedora 44 k\n" " libnet x86_64 1.1.5-3.fc17 fedora 54 k\n" " libnfsidmap x86_64 0.25-1.fc17 fedora 34 k\n" " libqb x86_64 0.11.1-1.fc17 updates-testing 68 k\n" " librdmacm x86_64 1.0.15-1.fc17 fedora 27 k\n" " libtalloc x86_64 2.0.7-4.fc17 fedora 22 k\n" " libtasn1 x86_64 2.12-1.fc17 updates-testing 319 k\n" " libtirpc x86_64 0.2.2-2.1.fc17 fedora 78 k\n" " libtool-ltdl x86_64 2.4.2-3.fc17 fedora 45 k\n" " libwbclient x86_64 1:3.6.3-81.fc17.1 updates-testing 68 k\n" " libxslt x86_64 1.1.26-9.fc17 fedora 416 k\n" " net-snmp-libs x86_64 1:5.7.1-4.fc17 fedora 713 k\n" " nfs-utils x86_64 1:1.2.5-12.fc17 fedora 311 k\n" " p11-kit x86_64 0.12-1.fc17 updates-testing 36 k\n" " pacemaker-cli x86_64 1.1.7-2.fc17 updates-testing 368 k\n" " pacemaker-cluster-libs x86_64 1.1.7-2.fc17 updates-testing 77 k\n" " pacemaker-libs x86_64 1.1.7-2.fc17 updates-testing 322 k\n" " perl x86_64 4:5.14.2-211.fc17 fedora 10 M\n" " perl-Carp noarch 1.22-2.fc17 fedora 17 k\n" " perl-Module-Pluggable noarch 1:3.90-211.fc17 fedora 47 k\n" " perl-PathTools x86_64 3.33-211.fc17 fedora 105 k\n" " perl-Pod-Escapes noarch 1:1.04-211.fc17 fedora 40 k\n" " perl-Pod-Simple noarch 1:3.16-211.fc17 fedora 223 k\n" " perl-Scalar-List-Utils x86_64 1.25-1.fc17 updates-testing 33 k\n" " perl-Socket x86_64 2.001-1.fc17 updates-testing 44 k\n" " perl-TimeDate noarch 1:1.20-6.fc17 fedora 43 k\n" " perl-libs x86_64 4:5.14.2-211.fc17 fedora 628 k\n" " perl-macros x86_64 4:5.14.2-211.fc17 fedora 32 k\n" " perl-threads x86_64 1.86-2.fc17 fedora 47 k\n" " perl-threads-shared x86_64 1.40-2.fc17 fedora 36 k\n" " quota x86_64 1:4.00-3.fc17 fedora 160 k\n" " quota-nls noarch 1:4.00-3.fc17 fedora 74 k\n" " resource-agents x86_64 3.9.2-2.fc17.1 fedora 466 k\n" " rpcbind x86_64 0.2.0-16.fc17 fedora 52 k\n" " tcp_wrappers x86_64 7.6-69.fc17 fedora 72 k\n" " xfsprogs x86_64 3.1.8-1.fc17 updates-testing 715 k\n" "\n" "Transaction Summary\n" "=====================================================================================\n" "Install 2 Packages (+46 Dependent packages)\n" "\n" "Total download size: 18 M\n" "Installed size: 59 M\n" "Downloading Packages:\n" "(1/48): OpenIPMI-libs-2.0.18-13.fc17.x86_64.rpm | 466 kB 00:00\n" "warning: rpmts_HdrFromFdno: Header V3 RSA/SHA256 Signature, key ID 1aca3465: NOKEY\n" "Public key for OpenIPMI-libs-2.0.18-13.fc17.x86_64.rpm is not installed\n" "(2/48): cifs-utils-5.3-2.fc17.x86_64.rpm | 66 kB 00:01\n" "Public key for cifs-utils-5.3-2.fc17.x86_64.rpm is not installed\n" "(3/48): cluster-glue-1.0.6-9.fc17.1.x86_64.rpm | 229 kB 00:00\n" "(4/48): cluster-glue-libs-1.0.6-9.fc17.1.x86_64.rpm | 121 kB 00:00\n" "(5/48): corosync-1.99.9-1.fc17.x86_64.rpm | 159 kB 00:01\n" "(6/48): corosynclib-1.99.9-1.fc17.x86_64.rpm | 96 kB 00:00\n" "(7/48): ethtool-3.2-2.fc17.x86_64.rpm | 94 kB 00:00\n" "(8/48): gnutls-2.12.17-1.fc17.x86_64.rpm | 385 kB 00:00\n" "(9/48): keyutils-1.5.5-2.fc17.x86_64.rpm | 49 kB 00:00\n" "(10/48): libevent-2.0.14-2.fc17.x86_64.rpm | 160 kB 00:00\n" "(11/48): libgssglue-0.3-1.fc17.x86_64.rpm | 24 kB 00:00\n" "(12/48): libibverbs-1.1.6-2.fc17.x86_64.rpm | 44 kB 00:00\n" "(13/48): libnet-1.1.5-3.fc17.x86_64.rpm | 54 kB 00:00\n" "(14/48): libnfsidmap-0.25-1.fc17.x86_64.rpm | 34 kB 00:00\n" "(15/48): libqb-0.11.1-1.fc17.x86_64.rpm | 68 kB 00:01\n" "(16/48): librdmacm-1.0.15-1.fc17.x86_64.rpm | 27 kB 00:00\n" "(17/48): libtalloc-2.0.7-4.fc17.x86_64.rpm | 22 kB 00:00\n" "(18/48): libtasn1-2.12-1.fc17.x86_64.rpm | 319 kB 00:02\n" "(19/48): libtirpc-0.2.2-2.1.fc17.x86_64.rpm | 78 kB 00:00\n" "(20/48): libtool-ltdl-2.4.2-3.fc17.x86_64.rpm | 45 kB 00:00\n" "(21/48): libwbclient-3.6.3-81.fc17.1.x86_64.rpm | 68 kB 00:00\n" "(22/48): libxslt-1.1.26-9.fc17.x86_64.rpm | 416 kB 00:00\n" "(23/48): net-snmp-libs-5.7.1-4.fc17.x86_64.rpm | 713 kB 00:01\n" "(24/48): nfs-utils-1.2.5-12.fc17.x86_64.rpm | 311 kB 00:00\n" "(25/48): p11-kit-0.12-1.fc17.x86_64.rpm | 36 kB 00:01\n" "(26/48): pacemaker-1.1.7-2.fc17.x86_64.rpm | 362 kB 00:02\n" "(27/48): pacemaker-cli-1.1.7-2.fc17.x86_64.rpm | 368 kB 00:02\n" "(28/48): pacemaker-cluster-libs-1.1.7-2.fc17.x86_64.rpm | 77 kB 00:00\n" "(29/48): pacemaker-libs-1.1.7-2.fc17.x86_64.rpm | 322 kB 00:01\n" "(30/48): perl-5.14.2-211.fc17.x86_64.rpm | 10 MB 00:15\n" "(31/48): perl-Carp-1.22-2.fc17.noarch.rpm | 17 kB 00:00\n" "(32/48): perl-Module-Pluggable-3.90-211.fc17.noarch.rpm | 47 kB 00:00\n" "(33/48): perl-PathTools-3.33-211.fc17.x86_64.rpm | 105 kB 00:00\n" "(34/48): perl-Pod-Escapes-1.04-211.fc17.noarch.rpm | 40 kB 00:00\n" "(35/48): perl-Pod-Simple-3.16-211.fc17.noarch.rpm | 223 kB 00:00\n" "(36/48): perl-Scalar-List-Utils-1.25-1.fc17.x86_64.rpm | 33 kB 00:01\n" "(37/48): perl-Socket-2.001-1.fc17.x86_64.rpm | 44 kB 00:00\n" "(38/48): perl-TimeDate-1.20-6.fc17.noarch.rpm | 43 kB 00:00\n" "(39/48): perl-libs-5.14.2-211.fc17.x86_64.rpm | 628 kB 00:00\n" "(40/48): perl-macros-5.14.2-211.fc17.x86_64.rpm | 32 kB 00:00\n" "(41/48): perl-threads-1.86-2.fc17.x86_64.rpm | 47 kB 00:00\n" "(42/48): perl-threads-shared-1.40-2.fc17.x86_64.rpm | 36 kB 00:00\n" "(43/48): quota-4.00-3.fc17.x86_64.rpm | 160 kB 00:00\n" "(44/48): quota-nls-4.00-3.fc17.noarch.rpm | 74 kB 00:00\n" "(45/48): resource-agents-3.9.2-2.fc17.1.x86_64.rpm | 466 kB 00:00\n" "(46/48): rpcbind-0.2.0-16.fc17.x86_64.rpm | 52 kB 00:00\n" "(47/48): tcp_wrappers-7.6-69.fc17.x86_64.rpm | 72 kB 00:00\n" "(48/48): xfsprogs-3.1.8-1.fc17.x86_64.rpm | 715 kB 00:03\n" "----------------------------------------------------------------------------------------\n" "Total 333 kB/s | 18 MB 00:55\n" "Retrieving key from file:///etc/pki/rpm-gpg/RPM-GPG-KEY-fedora-x86_64\n" "Importing GPG key 0x1ACA3465:\n" " Userid : \"Fedora (17) <fedora@fedoraproject.org>\"\n" " Fingerprint: cac4 3fb7 74a4 a673 d81c 5de7 50e9 4c99 1aca 3465\n" " Package : fedora-release-17-0.8.noarch (@anaconda-0)\n" " From : /etc/pki/rpm-gpg/RPM-GPG-KEY-fedora-x86_64\n" "Running Transaction Check\n" "Running Transaction Test\n" "Transaction Test Succeeded\n" "Running Transaction\n" " Installing : libqb-0.11.1-1.fc17.x86_64 1/48\n" " Installing : libtool-ltdl-2.4.2-3.fc17.x86_64 2/48\n" " Installing : cluster-glue-libs-1.0.6-9.fc17.1.x86_64 3/48\n" " Installing : libxslt-1.1.26-9.fc17.x86_64 4/48\n" " Installing : 1:perl-Pod-Escapes-1.04-211.fc17.noarch 5/48\n" " Installing : perl-threads-1.86-2.fc17.x86_64 6/48\n" " Installing : 4:perl-macros-5.14.2-211.fc17.x86_64 7/48\n" " Installing : 1:perl-Pod-Simple-3.16-211.fc17.noarch 8/48\n" " Installing : perl-Socket-2.001-1.fc17.x86_64 9/48\n" " Installing : perl-Carp-1.22-2.fc17.noarch 10/48\n" " Installing : 4:perl-libs-5.14.2-211.fc17.x86_64 11/48\n" " Installing : perl-threads-shared-1.40-2.fc17.x86_64 12/48\n" " Installing : perl-Scalar-List-Utils-1.25-1.fc17.x86_64 13/48\n" " Installing : 1:perl-Module-Pluggable-3.90-211.fc17.noarch 14/48\n" " Installing : perl-PathTools-3.33-211.fc17.x86_64 15/48\n" " Installing : 4:perl-5.14.2-211.fc17.x86_64 16/48\n" " Installing : libibverbs-1.1.6-2.fc17.x86_64 17/48\n" " Installing : keyutils-1.5.5-2.fc17.x86_64 18/48\n" " Installing : libgssglue-0.3-1.fc17.x86_64 19/48\n" " Installing : libtirpc-0.2.2-2.1.fc17.x86_64 20/48\n" " Installing : 1:net-snmp-libs-5.7.1-4.fc17.x86_64 21/48\n" " Installing : rpcbind-0.2.0-16.fc17.x86_64 22/48\n" " Installing : librdmacm-1.0.15-1.fc17.x86_64 23/48\n" " Installing : corosynclib-1.99.9-1.fc17.x86_64 24/48\n" " Installing : corosync-1.99.9-1.fc17.x86_64 25/48\n" "error reading information on service corosync: No such file or directory\n" " Installing : 1:perl-TimeDate-1.20-6.fc17.noarch 26/48\n" " Installing : 1:quota-nls-4.00-3.fc17.noarch 27/48\n" " Installing : tcp_wrappers-7.6-69.fc17.x86_64 28/48\n" " Installing : 1:quota-4.00-3.fc17.x86_64 29/48\n" " Installing : libnfsidmap-0.25-1.fc17.x86_64 30/48\n" " Installing : 1:libwbclient-3.6.3-81.fc17.1.x86_64 31/48\n" " Installing : libnet-1.1.5-3.fc17.x86_64 32/48\n" " Installing : 2:ethtool-3.2-2.fc17.x86_64 33/48\n" " Installing : libevent-2.0.14-2.fc17.x86_64 34/48\n" " Installing : 1:nfs-utils-1.2.5-12.fc17.x86_64 35/48\n" " Installing : libtalloc-2.0.7-4.fc17.x86_64 36/48\n" " Installing : cifs-utils-5.3-2.fc17.x86_64 37/48\n" " Installing : libtasn1-2.12-1.fc17.x86_64 38/48\n" " Installing : OpenIPMI-libs-2.0.18-13.fc17.x86_64 39/48\n" " Installing : cluster-glue-1.0.6-9.fc17.1.x86_64 40/48\n" " Installing : p11-kit-0.12-1.fc17.x86_64 41/48\n" " Installing : gnutls-2.12.17-1.fc17.x86_64 42/48\n" " Installing : pacemaker-libs-1.1.7-2.fc17.x86_64 43/48\n" " Installing : pacemaker-cluster-libs-1.1.7-2.fc17.x86_64 44/48\n" " Installing : pacemaker-cli-1.1.7-2.fc17.x86_64 45/48\n" " Installing : xfsprogs-3.1.8-1.fc17.x86_64 46/48\n" " Installing : resource-agents-3.9.2-2.fc17.1.x86_64 47/48\n" " Installing : pacemaker-1.1.7-2.fc17.x86_64 48/48\n" " Verifying : xfsprogs-3.1.8-1.fc17.x86_64 1/48\n" " Verifying : 1:net-snmp-libs-5.7.1-4.fc17.x86_64 2/48\n" " Verifying : corosync-1.99.9-1.fc17.x86_64 3/48\n" " Verifying : cluster-glue-1.0.6-9.fc17.1.x86_64 4/48\n" " Verifying : perl-PathTools-3.33-211.fc17.x86_64 5/48\n" " Verifying : p11-kit-0.12-1.fc17.x86_64 6/48\n" " Verifying : 1:perl-Pod-Simple-3.16-211.fc17.noarch 7/48\n" " Verifying : OpenIPMI-libs-2.0.18-13.fc17.x86_64 8/48\n" " Verifying : libtasn1-2.12-1.fc17.x86_64 9/48\n" " Verifying : perl-threads-1.86-2.fc17.x86_64 10/48\n" " Verifying : 1:perl-Pod-Escapes-1.04-211.fc17.noarch 11/48\n" " Verifying : pacemaker-1.1.7-2.fc17.x86_64 12/48\n" " Verifying : 4:perl-5.14.2-211.fc17.x86_64 13/48\n" " Verifying : gnutls-2.12.17-1.fc17.x86_64 14/48\n" " Verifying : perl-threads-shared-1.40-2.fc17.x86_64 15/48\n" " Verifying : 4:perl-macros-5.14.2-211.fc17.x86_64 16/48\n" " Verifying : 1:perl-Module-Pluggable-3.90-211.fc17.noarch 17/48\n" " Verifying : 1:nfs-utils-1.2.5-12.fc17.x86_64 18/48\n" " Verifying : cluster-glue-libs-1.0.6-9.fc17.1.x86_64 19/48\n" " Verifying : pacemaker-libs-1.1.7-2.fc17.x86_64 20/48\n" " Verifying : libtalloc-2.0.7-4.fc17.x86_64 21/48\n" " Verifying : libevent-2.0.14-2.fc17.x86_64 22/48\n" " Verifying : perl-Socket-2.001-1.fc17.x86_64 23/48\n" " Verifying : libgssglue-0.3-1.fc17.x86_64 24/48\n" " Verifying : perl-Carp-1.22-2.fc17.noarch 25/48\n" " Verifying : libtirpc-0.2.2-2.1.fc17.x86_64 26/48\n" " Verifying : 2:ethtool-3.2-2.fc17.x86_64 27/48\n" " Verifying : 4:perl-libs-5.14.2-211.fc17.x86_64 28/48\n" " Verifying : libxslt-1.1.26-9.fc17.x86_64 29/48\n" " Verifying : rpcbind-0.2.0-16.fc17.x86_64 30/48\n" " Verifying : librdmacm-1.0.15-1.fc17.x86_64 31/48\n" " Verifying : resource-agents-3.9.2-2.fc17.1.x86_64 32/48\n" " Verifying : 1:quota-4.00-3.fc17.x86_64 33/48\n" " Verifying : 1:perl-TimeDate-1.20-6.fc17.noarch 34/48\n" " Verifying : perl-Scalar-List-Utils-1.25-1.fc17.x86_64 35/48\n" " Verifying : libtool-ltdl-2.4.2-3.fc17.x86_64 36/48\n" " Verifying : pacemaker-cluster-libs-1.1.7-2.fc17.x86_64 37/48\n" " Verifying : cifs-utils-5.3-2.fc17.x86_64 38/48\n" " Verifying : libnet-1.1.5-3.fc17.x86_64 39/48\n" " Verifying : corosynclib-1.99.9-1.fc17.x86_64 40/48\n" " Verifying : libqb-0.11.1-1.fc17.x86_64 41/48\n" " Verifying : 1:libwbclient-3.6.3-81.fc17.1.x86_64 42/48\n" " Verifying : libnfsidmap-0.25-1.fc17.x86_64 43/48\n" " Verifying : tcp_wrappers-7.6-69.fc17.x86_64 44/48\n" " Verifying : keyutils-1.5.5-2.fc17.x86_64 45/48\n" " Verifying : libibverbs-1.1.6-2.fc17.x86_64 46/48\n" " Verifying : 1:quota-nls-4.00-3.fc17.noarch 47/48\n" " Verifying : pacemaker-cli-1.1.7-2.fc17.x86_64 48/48\n" "\n" "Installed:\n" " corosync.x86_64 0:1.99.9-1.fc17 pacemaker.x86_64 0:1.1.7-2.fc17\n" "\n" "Dependency Installed:\n" " OpenIPMI-libs.x86_64 0:2.0.18-13.fc17 cifs-utils.x86_64 0:5.3-2.fc17\n" " cluster-glue.x86_64 0:1.0.6-9.fc17.1 cluster-glue-libs.x86_64 0:1.0.6-9.fc17.1\n" " corosynclib.x86_64 0:1.99.9-1.fc17 ethtool.x86_64 2:3.2-2.fc17\n" " gnutls.x86_64 0:2.12.17-1.fc17 keyutils.x86_64 0:1.5.5-2.fc17\n" " libevent.x86_64 0:2.0.14-2.fc17 libgssglue.x86_64 0:0.3-1.fc17\n" " libibverbs.x86_64 0:1.1.6-2.fc17 libnet.x86_64 0:1.1.5-3.fc17\n" " libnfsidmap.x86_64 0:0.25-1.fc17 libqb.x86_64 0:0.11.1-1.fc17\n" " librdmacm.x86_64 0:1.0.15-1.fc17 libtalloc.x86_64 0:2.0.7-4.fc17\n" " libtasn1.x86_64 0:2.12-1.fc17 libtirpc.x86_64 0:0.2.2-2.1.fc17\n" " libtool-ltdl.x86_64 0:2.4.2-3.fc17 libwbclient.x86_64 1:3.6.3-81.fc17.1\n" " libxslt.x86_64 0:1.1.26-9.fc17 net-snmp-libs.x86_64 1:5.7.1-4.fc17\n" " nfs-utils.x86_64 1:1.2.5-12.fc17 p11-kit.x86_64 0:0.12-1.fc17\n" " pacemaker-cli.x86_64 0:1.1.7-2.fc17 pacemaker-cluster-libs.x86_64 0:1.1.7-2.fc17\n" " pacemaker-libs.x86_64 0:1.1.7-2.fc17 perl.x86_64 4:5.14.2-211.fc17\n" " perl-Carp.noarch 0:1.22-2.fc17 perl-Module-Pluggable.noarch 1:3.90-211.fc17\n" " perl-PathTools.x86_64 0:3.33-211.fc17 perl-Pod-Escapes.noarch 1:1.04-211.fc17\n" " perl-Pod-Simple.noarch 1:3.16-211.fc17 perl-Scalar-List-Utils.x86_64 0:1.25-1.fc17\n" " perl-Socket.x86_64 0:2.001-1.fc17 perl-TimeDate.noarch 1:1.20-6.fc17\n" " perl-libs.x86_64 4:5.14.2-211.fc17 perl-macros.x86_64 4:5.14.2-211.fc17\n" " perl-threads.x86_64 0:1.86-2.fc17 perl-threads-shared.x86_64 0:1.40-2.fc17\n" " quota.x86_64 1:4.00-3.fc17 quota-nls.noarch 1:4.00-3.fc17\n" " resource-agents.x86_64 0:3.9.2-2.fc17.1 rpcbind.x86_64 0:0.2.0-16.fc17\n" " tcp_wrappers.x86_64 0:7.6-69.fc17 xfsprogs.x86_64 0:3.1.8-1.fc17\n" "\n" "Complete!\n" "[root@pcmk-1 ~]#" msgstr "" #. Tag: para #, no-c-format msgid "Now install the cluster software on the second node." msgstr "" #. Tag: title #, no-c-format msgid "Install the Cluster Management Software" msgstr "" #. Tag: para #, no-c-format msgid "The pcs cli command coupled with the pcs daemon creates a cluster management system capable of managing all aspects of the cluster stack across all nodes from a single location." msgstr "" #. Tag: programlisting #, no-c-format msgid "# yum install -y pcs" msgstr "" #. Tag: para #, no-c-format msgid "Make sure to install the pcs packages on both nodes." msgstr "" #. Tag: title #, no-c-format msgid "Setup" msgstr "" #. Tag: title #, no-c-format msgid "Enable pcs Daemon" msgstr "" #. Tag: para #, no-c-format msgid "Before the cluster can be configured, the pcs daemon must be started and enabled to boot on startup on each node. This daemon works with the pcs cli command to manage syncing the corosync configuration across all the nodes in the cluster." msgstr "" #. Tag: para #, no-c-format msgid "Start and enable the daemon by issuing the following commands on each node." msgstr "" #. Tag: programlisting #, no-c-format msgid "# systemctl start pcsd.service\n" "# systemctl enable pcsd.service" msgstr "" #. Tag: para #, no-c-format msgid "Now we need a way for pcs to talk to itself on other nodes in the cluster. This is necessary in order to perform tasks such as syncing the corosync config, or starting/stopping the cluster on remote nodes" msgstr "" #. Tag: para #, no-c-format msgid "While pcs can be used locally without setting up these user accounts, this tutorial will make use of these remote access commands, so we will set a password for the hacluster user. Its probably best if password is consistent across all the nodes." msgstr "" #. Tag: para #, no-c-format msgid "As root, run:" msgstr "" #. Tag: programlisting #, no-c-format msgid "# passwd hacluster\n" "password:" msgstr "" #. Tag: para #, no-c-format msgid "Alternatively, to script this process or set the password on a different machine to the one you’re logged into, you can use the --stdin option for passwd:" msgstr "" #. Tag: programlisting #, no-c-format msgid "# ssh pcmk-2 -- 'echo redhat1 | passwd --stdin hacluster'" msgstr "" #. Tag: title #, no-c-format msgid "Notes on Multicast Address Assignment" msgstr "" #. Tag: para #, no-c-format msgid "There are several subtle points that often deserve consideration when choosing/assigning multicast addresses. This information is borrowed from, the now defunct, http://web.archive.org/web/20101211210054/http://29west.com/docs/THPM/multicast-address-assignment.html" msgstr "" #. Tag: para #, no-c-format msgid "Avoid 224.0.0.x" msgstr "" #. Tag: para #, no-c-format msgid "Traffic to addresses of the form 224.0.0.x is often flooded to all switch ports. This address range is reserved for link-local uses. Many routing protocols assume that all traffic within this range will be received by all routers on the network. Hence (at least all Cisco) switches flood traffic within this range. The flooding behavior overrides the normal selective forwarding behavior of a multicast-aware switch (e.g. IGMP snooping, CGMP, etc.)." msgstr "" #. Tag: para #, no-c-format msgid "Watch for 32:1 overlap" msgstr "" #. Tag: para #, no-c-format msgid "32 non-contiguous IP multicast addresses are mapped onto each Ethernet multicast address. A receiver that joins a single IP multicast group implicitly joins 31 others due to this overlap. Of course, filtering in the operating system discards undesired multicast traffic from applications, but NIC bandwidth and CPU resources are nonetheless consumed discarding it. The overlap occurs in the 5 high-order bits, so it’s best to use the 23 low-order bits to make distinct multicast streams unique. For example, IP multicast addresses in the range 239.0.0.0 to 239.127.255.255 all map to unique Ethernet multicast addresses. However, IP multicast address 239.128.0.0 maps to the same Ethernet multicast address as 239.0.0.0, 239.128.0.1 maps to the same Ethernet multicast address as 239.0.0.1, etc." msgstr "" #. Tag: para #, no-c-format msgid "Avoid x.0.0.y and x.128.0.y" msgstr "" #. Tag: para #, no-c-format msgid "Combining the above two considerations, it’s best to avoid using IP multicast addresses of the form x.0.0.y and x.128.0.y since they all map onto the range of Ethernet multicast addresses that are flooded to all switch ports." msgstr "" #. Tag: para #, no-c-format msgid "Watch for address assignment conflicts" msgstr "" #. Tag: para #, no-c-format msgid "IANA administers Internet multicast addresses. Potential conflicts with Internet multicast address assignments can be avoided by using GLOP addressing (AS required) or administratively scoped addresses. Such addresses can be safely used on a network connected to the Internet without fear of conflict with multicast sources originating on the Internet. Administratively scoped addresses are roughly analogous to the unicast address space for private internets. Site-local multicast addresses are of the form 239.255.x.y, but can grow down to 239.252.x.y if needed. Organization-local multicast addresses are of the form 239.192-251.x.y, but can grow down to 239.x.y.z if needed." msgstr "" #. Tag: para #, no-c-format msgid "For a more detailed treatment (57 pages!), see Cisco’s Guidelines for Enterprise IP Multicast Address Allocation paper." msgstr "" #. Tag: title #, no-c-format msgid "Configuring Corosync" msgstr "" #. Tag: para #, no-c-format msgid "In the past, at this point in the tutorial an explanation of how to configure and propagate corosync’s /etc/corosync.conf file would be necessary. Using pcs with the pcs daemon greatly simplifies this process by generating corosync.conf across all the nodes in the cluster with a single command. The only thing required to achieve this is to authenticate as the pcs user hacluster on one of the nodes in the cluster, and then issue the pcs cluster setup command with a list of all the node names in the cluster." msgstr "" #. Tag: programlisting #, no-c-format msgid "# pcs cluster auth pcmk-1 pcmk-2\n" "Username: hacluster\n" "Password:\n" "pcmk-1: Authorized\n" "pcmk-2: Authorized\n" "\n" "# pcs cluster setup mycluster pcmk-1 pcmk-2\n" "pcmk-1: Succeeded\n" "pcmk-2: Succeeded" msgstr "" #. Tag: para #, no-c-format msgid "That’s it. Corosync is configured across the cluster. If you received an authorization error for either of those commands, make sure you setup the hacluster user account and password on every node in the cluster with the same password." msgstr "" #. Tag: para #, no-c-format msgid "The final /etc/corosync.conf configuration on each node should look something like the sample in Appendix B, Sample Corosync Configuration." msgstr "" #. Tag: para #, no-c-format msgid "Pacemaker used to obtain membership and quorum from a custom Corosync plugin. This plugin also had the capability to start Pacemaker automatically when Corosync was started." msgstr "" #. Tag: para #, no-c-format msgid "Neither behavior is possible with Corosync 2.0 and beyond as support for plugins was removed." msgstr "" #. Tag: para #, no-c-format msgid "Instead, Pacemaker must be started as a separate job/initscript. Also, since Pacemaker made use of the plugin for message routing, a node using the plugin (Corosync prior to 2.0) cannot talk to one that isn’t (Corosync 2.0+)." msgstr "" #. Tag: para #, no-c-format msgid "Rolling upgrades between these versions are therefor not possible and an alternate strategy http://www.clusterlabs.org/doc/en-US/Pacemaker/1.1/html/Pacemaker_Explained/ap-upgrade.html must be used." msgstr "" pacemaker-master/doc/Clusters_from_Scratch/pot/Ch-Intro.pot000066400000000000000000000227441217637305600243360ustar00rootroot00000000000000# # AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: 0\n" "POT-Creation-Date: 2012-10-17T05:19:03\n" "PO-Revision-Date: 2012-10-17T05:19:03\n" "Last-Translator: Automatically generated\n" "Language-Team: None\n" "MIME-Version: 1.0\n" "Content-Type: application/x-publican; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. Tag: title #, no-c-format msgid "Read-Me-First" msgstr "" #. Tag: title #, no-c-format msgid "The Scope of this Document" msgstr "" #. Tag: para #, no-c-format msgid "Computer clusters can be used to provide highly available services or resources. The redundancy of multiple machines is used to guard against failures of many types." msgstr "" #. Tag: para #, no-c-format msgid "This document will walk through the installation and setup of simple clusters using the Fedora distribution, version 17." msgstr "" #. Tag: para #, no-c-format msgid "The clusters described here will use Pacemaker and Corosync to provide resource management and messaging. Required packages and modifications to their configuration files are described along with the use of the Pacemaker command line tool for generating the XML used for cluster control." msgstr "" #. Tag: para #, no-c-format msgid "Pacemaker is a central component and provides the resource management required in these systems. This management includes detecting and recovering from the failure of various nodes, resources and services under its control." msgstr "" #. Tag: para #, no-c-format msgid "When more in depth information is required and for real world usage, please refer to the Pacemaker Explained manual." msgstr "" #. Tag: title #, no-c-format msgid "What Is Pacemaker?" msgstr "" #. Tag: para #, no-c-format msgid "Pacemaker is a cluster resource manager. It achieves maximum availability for your cluster services (aka. resources) by detecting and recovering from node and resource-level failures by making use of the messaging and membership capabilities provided by your preferred cluster infrastructure (either Corosync or Heartbeat)." msgstr "" #. Tag: para #, no-c-format msgid "Pacemaker’s key features include:" msgstr "" #. Tag: para #, no-c-format msgid "Detection and recovery of node and service-level failures" msgstr "" #. Tag: para #, no-c-format msgid "Storage agnostic, no requirement for shared storage" msgstr "" #. Tag: para #, no-c-format msgid "Resource agnostic, anything that can be scripted can be clustered" msgstr "" #. Tag: para #, no-c-format msgid "Supports STONITH for ensuring data integrity" msgstr "" #. Tag: para #, no-c-format msgid "Supports large and small clusters" msgstr "" #. Tag: para #, no-c-format msgid "Supports both quorate and resource driven clusters" msgstr "" #. Tag: para #, no-c-format msgid "Supports practically any redundancy configuration" msgstr "" #. Tag: para #, no-c-format msgid "Automatically replicated configuration that can be updated from any node" msgstr "" #. Tag: para #, no-c-format msgid "Ability to specify cluster-wide service ordering, colocation and anti-colocation" msgstr "" #. Tag: para #, no-c-format msgid "Support for advanced service types" msgstr "" #. Tag: para #, no-c-format msgid "Clones: for services which need to be active on multiple nodes" msgstr "" #. Tag: para #, no-c-format msgid "Multi-state: for services with multiple modes (eg. master/slave, primary/secondary)" msgstr "" #. Tag: para #, no-c-format msgid "Unified, scriptable, cluster management tools." msgstr "" #. Tag: title #, no-c-format msgid "Pacemaker Architecture" msgstr "" #. Tag: para #, no-c-format msgid "At the highest level, the cluster is made up of three pieces:" msgstr "" #. Tag: para #, no-c-format msgid "Non-cluster aware components (illustrated in green). These pieces include the resources themselves, scripts that start, stop and monitor them, and also a local daemon that masks the differences between the different standards these scripts implement." msgstr "" #. Tag: para #, no-c-format msgid "Resource management Pacemaker provides the brain (illustrated in blue) that processes and reacts to events regarding the cluster. These events include nodes joining or leaving the cluster; resource events caused by failures, maintenance, scheduled activities; and other administrative actions. Pacemaker will compute the ideal state of the cluster and plot a path to achieve it after any of these events. This may include moving resources, stopping nodes and even forcing them offline with remote power switches." msgstr "" #. Tag: para #, no-c-format msgid "Low level infrastructure Corosync provides reliable messaging, membership and quorum information about the cluster (illustrated in red)." msgstr "" #. Tag: title #, no-c-format msgid "Conceptual Stack Overview" msgstr "" #. Tag: phrase #, no-c-format msgid "Conceptual overview of the cluster stack" msgstr "" #. Tag: para #, no-c-format msgid "When combined with Corosync, Pacemaker also supports popular open source cluster filesystems. Even though Pacemaker also supports Heartbeat, the filesystems need to use the stack for messaging and membership and Corosync seems to be what they’re standardizing on. Technically it would be possible for them to support Heartbeat as well, however there seems little interest in this." msgstr "" #. Tag: para #, no-c-format msgid "Due to recent standardization within the cluster filesystem community, they make use of a common distributed lock manager which makes use of Corosync for its messaging capabilities and Pacemaker for its membership (which nodes are up/down) and fencing services." msgstr "" #. Tag: title #, no-c-format msgid "The Pacemaker Stack" msgstr "" #. Tag: phrase #, no-c-format msgid "The Pacemaker StackThe Pacemaker stack when running on Corosync" msgstr "" #. Tag: title #, no-c-format msgid "Internal Components" msgstr "" #. Tag: para #, no-c-format msgid "Pacemaker itself is composed of four key components (illustrated below in the same color scheme as the previous diagram):" msgstr "" #. Tag: para #, no-c-format msgid "CIB (aka. Cluster Information Base)" msgstr "" #. Tag: para #, no-c-format msgid "CRMd (aka. Cluster Resource Management daemon)" msgstr "" #. Tag: para #, no-c-format msgid "PEngine (aka. PE or Policy Engine)" msgstr "" #. Tag: para #, no-c-format msgid "STONITHd" msgstr "" #. Tag: phrase #, no-c-format msgid "Subsystems of a Pacemaker cluster running on Corosync" msgstr "" #. Tag: para #, no-c-format msgid "The CIB uses XML to represent both the cluster’s configuration and current state of all resources in the cluster. The contents of the CIB are automatically kept in sync across the entire cluster and are used by the PEngine to compute the ideal state of the cluster and how it should be achieved." msgstr "" #. Tag: para #, no-c-format msgid "This list of instructions is then fed to the DC (Designated Co-ordinator). Pacemaker centralizes all cluster decision making by electing one of the CRMd instances to act as a master. Should the elected CRMd process, or the node it is on, fail… a new one is quickly established." msgstr "" #. Tag: para #, no-c-format msgid "The DC carries out the PEngine’s instructions in the required order by passing them to either the LRMd (Local Resource Management daemon) or CRMd peers on other nodes via the cluster messaging infrastructure (which in turn passes them on to their LRMd process)." msgstr "" #. Tag: para #, no-c-format msgid "The peer nodes all report the results of their operations back to the DC and based on the expected and actual results, will either execute any actions that needed to wait for the previous one to complete, or abort processing and ask the PEngine to recalculate the ideal cluster state based on the unexpected results." msgstr "" #. Tag: para #, no-c-format msgid "In some cases, it may be necessary to power off nodes in order to protect shared data or complete resource recovery. For this Pacemaker comes with STONITHd. STONITH is an acronym for Shoot-The-Other-Node-In-The-Head and is usually implemented with a remote power switch. In Pacemaker, STONITH devices are modeled as resources (and configured in the CIB) to enable them to be easily monitored for failure, however STONITHd takes care of understanding the STONITH topology such that its clients simply request a node be fenced and it does the rest." msgstr "" #. Tag: title #, no-c-format msgid "Types of Pacemaker Clusters" msgstr "" #. Tag: para #, no-c-format msgid "Pacemaker makes no assumptions about your environment, this allows it to support practically any redundancy configuration including Active/Active, Active/Passive, N+1, N+M, N-to-1 and N-to-N." msgstr "" #. Tag: para #, no-c-format msgid "In this document we will focus on the setup of a highly available Apache web server with an Active/Passive cluster using DRBD and Ext4 to store data. Then, we will upgrade this cluster to Active/Active using GFS2." msgstr "" #. Tag: title #, no-c-format msgid "Active/Passive Redundancy" msgstr "" #. Tag: phrase #, no-c-format msgid "Two-node Active/Passive clusters using Pacemaker and DRBD are a cost-effective solution for many High Availability situations" msgstr "" #. Tag: title #, no-c-format msgid "N to N Redundancy" msgstr "" #. Tag: phrase #, no-c-format msgid "When shared storage is available, every node can potentially be used for failover. Pacemaker can even run multiple copies of services to spread out the workload" msgstr "" pacemaker-master/doc/Clusters_from_Scratch/pot/Ch-Shared-Storage.pot000066400000000000000000000475721217637305600260610ustar00rootroot00000000000000# # AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: 0\n" "POT-Creation-Date: 2012-10-17T05:19:03\n" "PO-Revision-Date: 2012-10-17T05:19:03\n" "Last-Translator: Automatically generated\n" "Language-Team: None\n" "MIME-Version: 1.0\n" "Content-Type: application/x-publican; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. Tag: title #, no-c-format msgid "Replicated Storage with DRBD" msgstr "" #. Tag: title #, no-c-format msgid "Background" msgstr "" #. Tag: para #, no-c-format msgid "Even if you’re serving up static websites, having to manually synchronize the contents of that website to all the machines in the cluster is not ideal. For dynamic websites, such as a wiki, it’s not even an option. Not everyone care afford network-attached storage but somehow the data needs to be kept in sync. Enter DRBD which can be thought of as network based RAID-1. See http://www.drbd.org/ for more details." msgstr "" #. Tag: title #, no-c-format msgid "Install the DRBD Packages" msgstr "" #. Tag: para #, no-c-format msgid "Since its inclusion in the upstream 2.6.33 kernel, everything needed to use DRBD has shiped with Fedora since version 13. All you need to do is install it:" msgstr "" #. Tag: programlisting #, no-c-format msgid "# yum install -y drbd-pacemaker drbd-udev" msgstr "" #. Tag: literallayout #, no-c-format msgid "Loaded plugins: langpacks, presto, refresh-packagekit\n" "Resolving Dependencies\n" "--> Running transaction check\n" "---> Package drbd-pacemaker.x86_64 0:8.3.11-5.fc17 will be installed\n" "--> Processing Dependency: drbd-utils = 8.3.11-5.fc17 for package: drbd-pacemaker-8.3.11-5.fc17.x86_64\n" "---> Package drbd-udev.x86_64 0:8.3.11-5.fc17 will be installed\n" "--> Running transaction check\n" "---> Package drbd-utils.x86_64 0:8.3.11-5.fc17 will be installed\n" "--> Finished Dependency Resolution\n" "\n" "Dependencies Resolved\n" "\n" "======================================================================================\n" " Package Arch Version Repository Size\n" "======================================================================================\n" "Installing:\n" " drbd-pacemaker x86_64 8.3.11-5.fc17 updates-testing 22 k\n" " drbd-udev x86_64 8.3.11-5.fc17 updates-testing 6.4 k\n" "Installing for dependencies:\n" " drbd-utils x86_64 8.3.11-5.fc17 updates-testing 183 k\n" "\n" "Transaction Summary\n" "======================================================================================\n" "Install 2 Packages (+1 Dependent package)\n" "\n" "Total download size: 212 k\n" "Installed size: 473 k\n" "Downloading Packages:\n" "(1/3): drbd-pacemaker-8.3.11-5.fc17.x86_64.rpm | 22 kB 00:00\n" "(2/3): drbd-udev-8.3.11-5.fc17.x86_64.rpm | 6.4 kB 00:00\n" "(3/3): drbd-utils-8.3.11-5.fc17.x86_64.rpm | 183 kB 00:00\n" "--------------------------------------------------------------------------------------\n" "Total 293 kB/s | 212 kB 00:00\n" "Running Transaction Check\n" "Running Transaction Test\n" "Transaction Test Succeeded\n" "Running Transaction\n" " Installing : drbd-utils-8.3.11-5.fc17.x86_64 1/3\n" " Installing : drbd-pacemaker-8.3.11-5.fc17.x86_64 2/3\n" " Installing : drbd-udev-8.3.11-5.fc17.x86_64 3/3\n" " Verifying : drbd-pacemaker-8.3.11-5.fc17.x86_64 1/3\n" " Verifying : drbd-udev-8.3.11-5.fc17.x86_64 2/3\n" " Verifying : drbd-utils-8.3.11-5.fc17.x86_64 3/3\n" "\n" "Installed:\n" " drbd-pacemaker.x86_64 0:8.3.11-5.fc17 drbd-udev.x86_64 0:8.3.11-5.fc17\n" "\n" "Dependency Installed:\n" " drbd-utils.x86_64 0:8.3.11-5.fc17\n" "\n" "Complete!" msgstr "" #. Tag: title #, no-c-format msgid "Configure DRBD" msgstr "" #. Tag: para #, no-c-format msgid "Before we configure DRBD, we need to set aside some disk for it to use." msgstr "" #. Tag: title #, no-c-format msgid "Create A Partition for DRBD" msgstr "" #. Tag: para #, no-c-format msgid "If you have more than 1Gb free, feel free to use it. For this guide however, 1Gb is plenty of space for a single html file and sufficient for later holding the GFS2 metadata." msgstr "" #. Tag: programlisting #, no-c-format msgid "# vgdisplay | grep -e Name - e Free\n" " VG Name vg_pcmk1\n" " Free PE / Size 31 / 992.00 MiB\n" "# lvs\n" " LV VG Attr LSize Pool Origin Data% Move Log Copy% Convert\n" " lv_root vg_pcmk1 -wi-ao-- 8.56g\n" " lv_swap vg_pcmk1 -wi-ao-- 960.00m\n" "# lvcreate -n drbd-demo -L 1G vg_pcmk1\n" "Logical volume \"drbd-demo\" created\n" "# lvs\n" " LV VG Attr LSize Pool Origin Data% Move Log Copy% Convert\n" " drbd-demo vg_pcmk1 -wi-a--- 1.00G\n" " lv_root vg_pcmk1 -wi-ao-- 8.56g\n" " lv_swap vg_pcmk1 -wi-ao-- 960.00m" msgstr "" #. Tag: para #, no-c-format msgid "Repeat this on the second node, be sure to use the same size partition." msgstr "" #. Tag: programlisting #, no-c-format msgid "# ssh pcmk-2 -- lvs\n" "LV VG Attr LSize Origin Snap% Move Log Copy% Convert\n" " lv_root vg_pcmk1 -wi-ao-- 8.56g\n" " lv_swap vg_pcmk1 -wi-ao-- 960.00m\n" "# ssh pcmk-2 -- lvcreate -n drbd-demo -L 1G vg_pcmk1\n" "Logical volume \"drbd-demo\" created\n" "# ssh pcmk-2 -- lvs\n" "LV VG Attr LSize Origin Snap% Move Log Copy% Convert\n" " drbd-demo vg_pcmk1 -wi-a--- 1.00G\n" " lv_root vg_pcmk1 -wi-ao-- 8.56g\n" " lv_swap vg_pcmk1 -wi-ao-- 960.00m" msgstr "" #. Tag: title #, no-c-format msgid "Write the DRBD Config" msgstr "" #. Tag: para #, no-c-format msgid "There is no series of commands for building a DRBD configuration, so simply copy the configuration below to /etc/drbd.conf" msgstr "" #. Tag: para #, no-c-format msgid "Detailed information on the directives used in this configuration (and other alternatives) is available from http://www.drbd.org/users-guide/ch-configure.html" msgstr "" #. Tag: para #, no-c-format msgid "Be sure to use the names and addresses of your nodes if they differ from the ones used in this guide." msgstr "" #. Tag: literallayout #, no-c-format msgid "global {\n" " usage-count yes;\n" "}\n" "common {\n" " protocol C;\n" "}\n" "resource wwwdata {\n" " meta-disk internal;\n" " device /dev/drbd1;\n" " syncer {\n" " verify-alg sha1;\n" " }\n" " net {\n" " allow-two-primaries;\n" " }\n" " on pcmk-1 {\n" " disk /dev/vg_pcmk1/drbd-demo;\n" " address 192.168.122.101:7789;\n" " }\n" " on pcmk-2 {\n" " disk /dev/vg_pcmk1/drbd-demo;\n" " address 192.168.122.102:7789;\n" " }\n" "}" msgstr "" #. Tag: para #, no-c-format msgid "TODO: Explain the reason for the allow-two-primaries option" msgstr "" #. Tag: title #, no-c-format msgid "Initialize and Load DRBD" msgstr "" #. Tag: para #, no-c-format msgid "With the configuration in place, we can now perform the DRBD initialization" msgstr "" #. Tag: programlisting #, no-c-format msgid "# drbdadm create-md wwwdata\n" "Writing meta data...\n" "initializing activity log\n" "NOT initialized bitmap\n" "New drbd meta data block successfully created.\n" "success" msgstr "" #. Tag: para #, no-c-format msgid "Now load the DRBD kernel module and confirm that everything is sane" msgstr "" #. Tag: programlisting #, no-c-format msgid "# modprobe drbd\n" "# drbdadm up wwwdata\n" "# cat /proc/drbd\n" "version: 8.3.11 (api:88/proto:86-96)\n" "srcversion: 0D2B62DEDB020A425130935\n" "\n" " 1: cs:Connected ro:Secondary/Secondary ds:Inconsistent/Inconsistent C r-----\n" " ns:0 nr:0 dw:0 dr:0 al:0 bm:0 lo:0 pe:0 ua:0 ap:0 ep:1 wo:f oos:1015740" msgstr "" #. Tag: para #, no-c-format msgid "Repeat on the second node" msgstr "" #. Tag: programlisting #, no-c-format msgid "# ssh pcmk-2 -- drbdadm --force create-md wwwdata\n" "Writing meta data...\n" "initializing activity log\n" "NOT initialized bitmap\n" "New drbd meta data block successfully created.\n" "success\n" "# ssh pcmk-2 -- modprobe drbd\n" "WARNING: Deprecated config file /etc/modprobe.conf, all config files belong into /etc/modprobe.d/.\n" "# ssh pcmk-2 -- drbdadm up wwwdata\n" "# ssh pcmk-2 -- cat /proc/drbd\n" "version: 8.3.11 (api:88/proto:86-96)\n" "srcversion: 0D2B62DEDB020A425130935\n" "\n" " 1: cs:Connected ro:Secondary/Secondary ds:Inconsistent/Inconsistent C r-----\n" " ns:0 nr:0 dw:0 dr:0 al:0 bm:0 lo:0 pe:0 ua:0 ap:0 ep:1 wo:f oos:1015740" msgstr "" #. Tag: para #, no-c-format msgid "Now we need to tell DRBD which set of data to use. Since both sides contain garbage, we can run the following on pcmk-1:" msgstr "" #. Tag: programlisting #, no-c-format msgid "# drbdadm -- --overwrite-data-of-peer primary wwwdata\n" "# cat /proc/drbd\n" "version: 8.3.11 (api:88/proto:86-96)\n" "srcversion: 0D2B62DEDB020A425130935\n" "\n" " 1: cs:SyncSource ro:Primary/Secondary ds:UpToDate/Inconsistent C r-----\n" " ns:8064 nr:0 dw:0 dr:8728 al:0 bm:0 lo:0 pe:1 ua:0 ap:0 ep:1 wo:f oos:1007804\n" " [>....................] sync'ed: 0.9% (1007804/1015740)K\n" " finish: 0:12:35 speed: 1,320 (1,320) K/sec" msgstr "" #. Tag: para #, no-c-format msgid "After a while, the sync should finish and you’ll see:" msgstr "" #. Tag: programlisting #, no-c-format msgid "# cat /proc/drbd\n" "version: 8.3.11 (api:88/proto:86-96)\n" "srcversion: 0D2B62DEDB020A425130935\n" "\n" " 1: cs:Connected ro:Primary/Secondary ds:UpToDate/UpToDate C r-----\n" " ns:1015740 nr:0 dw:0 dr:1016404 al:0 bm:62 lo:0 pe:0 ua:0 ap:0 ep:1 wo:f oos:0" msgstr "" #. Tag: para #, no-c-format msgid "pcmk-1 is now in the Primary state which allows it to be written to. Which means it’s a good point at which to create a filesystem and populate it with some data to serve up via our WebSite resource." msgstr "" #. Tag: title #, no-c-format msgid "Populate DRBD with Data" msgstr "" #. Tag: programlisting #, no-c-format msgid "# mkfs.ext4 /dev/drbd1\n" "mke2fs 1.42 (29-Nov-2011)\n" "Filesystem label=\n" "OS type: Linux\n" "Block size=4096 (log=2)\n" "Fragment size=4096 (log=2)\n" "Stride=0 blocks, Stripe width=0 blocks\n" "63488 inodes, 253935 blocks\n" "12696 blocks (5.00%) reserved for the super user\n" "First data block=0\n" "Maximum filesystem blocks=260046848\n" "8 block groups\n" "32768 blocks per group, 32768 fragments per group\n" "7936 inodes per group\n" "Superblock backups stored on blocks:\n" " 32768, 98304, 163840, 229376\n" "\n" "Allocating group tables: done\n" "Writing inode tables: done\n" "Creating journal (4096 blocks): done\n" "Writing superblocks and filesystem accounting information: done" msgstr "" #. Tag: para #, no-c-format msgid "Now mount the newly created filesystem so we can create our index file" msgstr "" #. Tag: programlisting #, no-c-format msgid "# mount /dev/drbd1 /mnt/\n" "# cat <<-END >/mnt/index.html\n" " <html>\n" " <body>My Test Site - drbd</body>\n" " </html>\n" "END\n" "# umount /dev/drbd1" msgstr "" #. Tag: title #, no-c-format msgid "Configure the Cluster for DRBD" msgstr "" #. Tag: para #, no-c-format msgid "One handy feature pcs has is the ability to queue up several changes into a file and commit those changes atomically. To do this, start by populating the file with the current raw xml config from the cib. This can be done using the following command." msgstr "" #. Tag: programlisting #, no-c-format msgid "# pcs cluster cib drbd_cfg" msgstr "" #. Tag: para #, no-c-format msgid "Now using the pcs -f option, make changes to the configuration saved in the drbd_cfg file. These changes will not be seen by the cluster until the drbd_cfg file is pushed into the live cluster’s cib later on." msgstr "" #. Tag: screen #, no-c-format msgid "# pcs -f drbd_cfg resource create WebData ocf:linbit:drbd \\\n" " drbd_resource=wwwdata op monitor interval=60s\n" "# pcs -f drbd_cfg resource master WebDataClone WebData \\\n" " master-max=1 master-node-max=1 clone-max=2 clone-node-max=1 \\\n" " notify=true" msgstr "" #. Tag: programlisting #, no-c-format msgid "# pcs -f drbd_cfg resource show\n" " ClusterIP (ocf::heartbeat:IPaddr2) Started\n" " WebSite (ocf::heartbeat:apache) Started\n" " Master/Slave Set: WebDataClone [WebData]\n" " Stopped: [ WebData:0 WebData:1 ]" msgstr "" #. Tag: para #, no-c-format msgid "After you are satisfied with all the changes, you can commit all the changes at once by pushing the drbd_cfg file into the live cib." msgstr "" #. Tag: programlisting #, no-c-format msgid "# pcs cluster push cib drbd_cfg\n" "CIB updated\n" "\n" "# pcs status\n" "\n" "Last updated: Fri Sep 14 12:19:49 2012\n" "Last change: Fri Sep 14 12:19:13 2012 via cibadmin on pcmk-1\n" "Stack: corosync\n" "Current DC: pcmk-2 (2) - partition with quorum\n" "Version: 1.1.8-1.el7-60a19ed12fdb4d5c6a6b6767f52e5391e447fec0\n" "2 Nodes configured, unknown expected votes\n" "4 Resources configured.\n" "\n" "Online: [ pcmk-1 pcmk-2 ]\n" "\n" "Full list of resources:\n" "\n" " ClusterIP (ocf::heartbeat:IPaddr2): Started pcmk-1\n" " WebSite (ocf::heartbeat:apache): Started pcmk-1\n" " Master/Slave Set: WebDataClone [WebData]\n" " Masters: [ pcmk-1 ]\n" " Slaves: [ pcmk-2 ]" msgstr "" #. Tag: para #, no-c-format msgid "TODO: Include details on adding a second DRBD resource" msgstr "" #. Tag: para #, no-c-format msgid "Now that DRBD is functioning we can configure a Filesystem resource to use it. In addition to the filesystem’s definition, we also need to tell the cluster where it can be located (only on the DRBD Primary) and when it is allowed to start (after the Primary was promoted)." msgstr "" #. Tag: para #, no-c-format msgid "We are going to take a shortcut when creating the resource this time though. Instead of explicitly saying we want the ocf:heartbeat:Filesystem script, we are only going to ask for Filesystem. We can do this because we know there is only one resource script named Filesystem available to pacemaker, and that pcs is smart enough to fill in the ocf:heartbeat portion for us correctly in the configuration. If there were multiple Filesystem scripts from different ocf providers, we would need to specify the exact one we wanted to use." msgstr "" #. Tag: para #, no-c-format msgid "Once again we will queue up our changes to a file and then push the new configuration to the cluster as the final step." msgstr "" #. Tag: screen #, no-c-format msgid "# pcs cluster cib fs_cfg\n" "# pcs -f fs_cfg resource create WebFS Filesystem \\\n" " device=\"/dev/drbd/by-res/wwwdata\" directory=\"/var/www/html\" \\\n" " fstype=\"ext4\"" msgstr "" #. Tag: programlisting #, no-c-format msgid "# pcs -f fs_cfg constraint colocation add WebFS WebDataClone INFINITY with-rsc-role=Master\n" "# pcs -f fs_cfg constraint order promote WebDataClone then start WebFS\n" "Adding WebDataClone WebFS (kind: Mandatory) (Options: first-action=promote then-action=start)" msgstr "" #. Tag: para #, no-c-format msgid "We also need to tell the cluster that Apache needs to run on the same machine as the filesystem and that it must be active before Apache can start." msgstr "" #. Tag: programlisting #, no-c-format msgid "# pcs -f fs_cfg constraint colocation add WebSite WebFS INFINITY\n" "# pcs -f fs_cfg constraint order WebFS then WebSite" msgstr "" #. Tag: para #, no-c-format msgid "Now review the updated configuration." msgstr "" #. Tag: programlisting #, no-c-format msgid "# pcs -f fs_cfg constraint\n" "Location Constraints:\n" "Ordering Constraints:\n" " start ClusterIP then start WebSite\n" " WebFS then WebSite\n" " promote WebDataClone then start WebFS\n" "Colocation Constraints:\n" " WebSite with ClusterIP\n" " WebFS with WebDataClone (with-rsc-role:Master)\n" " WebSite with WebFS\n" "\n" "# pcs -f fs_cfg resource show\n" " ClusterIP (ocf::heartbeat:IPaddr2) Started\n" " WebSite (ocf::heartbeat:apache) Started\n" " Master/Slave Set: WebDataClone [WebData]\n" " Masters: [ pcmk-1 ]\n" " Slaves: [ pcmk-2 ]\n" " WebFS (ocf::heartbeat:Filesystem) Stopped" msgstr "" #. Tag: para #, no-c-format msgid "After reviewing the new configuration, we again upload it and watch the cluster put it into effect." msgstr "" #. Tag: programlisting #, no-c-format msgid "# pcs cluster push cib fs_cfg\n" "CIB updated\n" "# pcs status\n" " Last updated: Fri Aug 10 12:47:01 2012\n" "\n" " Last change: Fri Aug 10 12:46:55 2012 via cibadmin on pcmk-1\n" " Stack: corosync\n" " Current DC: pcmk-1 (1) - partition with quorum\n" " Version: 1.1.8-1.el7-60a19ed12fdb4d5c6a6b6767f52e5391e447fec0\n" " 2 Nodes configured, unknown expected votes\n" " 5 Resources configured.\n" "\n" "Online: [ pcmk-1 pcmk-2 ]\n" "\n" "Full list of resources:\n" "\n" " ClusterIP (ocf::heartbeat:IPaddr2): Started pcmk-1\n" " WebSite (ocf::heartbeat:apache): Started pcmk-1\n" " Master/Slave Set: WebDataClone [WebData]\n" " Masters: [ pcmk-1 ]\n" " Slaves: [ pcmk-2 ]\n" " WebFS (ocf::heartbeat:Filesystem): Started pcmk-1" msgstr "" #. Tag: title #, no-c-format msgid "Testing Migration" msgstr "" #. Tag: para #, no-c-format msgid "We could shut down the active node again, but another way to safely simulate recovery is to put the node into what is called \"standby mode\". Nodes in this state tell the cluster that they are not allowed to run resources. Any resources found active there will be moved elsewhere. This feature can be particularly useful when updating the resources' packages." msgstr "" #. Tag: para #, no-c-format msgid "Put the local node into standby mode and observe the cluster move all the resources to the other node. Note also that the node’s status will change to indicate that it can no longer host resources." msgstr "" #. Tag: programlisting #, no-c-format msgid "# pcs cluster standby pcmk-1\n" "# pcs status\n" "\n" "Last updated: Fri Sep 14 12:41:12 2012\n" "Last change: Fri Sep 14 12:41:08 2012 via crm_attribute on pcmk-1\n" "Stack: corosync\n" "Current DC: pcmk-1 (1) - partition with quorum\n" "Version: 1.1.8-1.el7-60a19ed12fdb4d5c6a6b6767f52e5391e447fec0\n" "2 Nodes configured, unknown expected votes\n" "5 Resources configured.\n" "\n" "Node pcmk-1 (1): standby\n" "Online: [ pcmk-2 ]\n" "\n" "Full list of resources:\n" "\n" "ClusterIP (ocf::heartbeat:IPaddr2): Started pcmk-2\n" "WebSite (ocf::heartbeat:apache): Started pcmk-2\n" " Master/Slave Set: WebDataClone [WebData]\n" " Masters: [ pcmk-2 ]\n" " Stopped: [ WebData:1 ]\n" "WebFS (ocf::heartbeat:Filesystem): Started pcmk-2" msgstr "" #. Tag: para #, no-c-format msgid "Once we’ve done everything we needed to on pcmk-1 (in this case nothing, we just wanted to see the resources move), we can allow the node to be a full cluster member again." msgstr "" #. Tag: programlisting #, no-c-format msgid "# pcs cluster unstandby pcmk-1\n" "# pcs status\n" "\n" "Last updated: Fri Sep 14 12:43:02 2012\n" "Last change: Fri Sep 14 12:42:57 2012 via crm_attribute on pcmk-1\n" "Stack: corosync\n" "Current DC: pcmk-1 (1) - partition with quorum\n" "Version: 1.1.8-1.el7-60a19ed12fdb4d5c6a6b6767f52e5391e447fec0\n" "2 Nodes configured, unknown expected votes\n" "5 Resources configured.\n" "\n" "Online: [ pcmk-1 pcmk-2 ]\n" "\n" "Full list of resources:\n" "\n" " ClusterIP (ocf::heartbeat:IPaddr2): Started pcmk-2\n" " WebSite (ocf::heartbeat:apache): Started pcmk-2\n" " Master/Slave Set: WebDataClone [WebData]\n" " Masters: [ pcmk-2 ]\n" " Slaves: [ pcmk-1 ]\n" " WebFS (ocf::heartbeat:Filesystem): Started pcmk-2" msgstr "" #. Tag: para #, no-c-format msgid "Notice that our resource stickiness settings prevent the services from migrating back to pcmk-1." msgstr "" pacemaker-master/doc/Clusters_from_Scratch/pot/Ch-Stonith.pot000066400000000000000000000146361217637305600246740ustar00rootroot00000000000000# # AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: 0\n" "POT-Creation-Date: 2012-10-17T05:19:03\n" "PO-Revision-Date: 2012-10-17T05:19:03\n" "Last-Translator: Automatically generated\n" "Language-Team: None\n" "MIME-Version: 1.0\n" "Content-Type: application/x-publican; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. Tag: title #, no-c-format msgid "Configure STONITH" msgstr "" #. Tag: title #, no-c-format msgid "What Is STONITH" msgstr "" #. Tag: para #, no-c-format msgid "STONITH is an acronym for Shoot-The-Other-Node-In-The-Head and it protects your data from being corrupted by rogue nodes or concurrent access." msgstr "" #. Tag: para #, no-c-format msgid "Just because a node is unresponsive, this doesn’t mean it isn’t accessing your data. The only way to be 100% sure that your data is safe, is to use STONITH so we can be certain that the node is truly offline, before allowing the data to be accessed from another node." msgstr "" #. Tag: para #, no-c-format msgid "STONITH also has a role to play in the event that a clustered service cannot be stopped. In this case, the cluster uses STONITH to force the whole node offline, thereby making it safe to start the service elsewhere." msgstr "" #. Tag: title #, no-c-format msgid "What STONITH Device Should You Use" msgstr "" #. Tag: para #, no-c-format msgid "It is crucial that the STONITH device can allow the cluster to differentiate between a node failure and a network one." msgstr "" #. Tag: para #, no-c-format msgid "The biggest mistake people make in choosing a STONITH device is to use remote power switch (such as many on-board IMPI controllers) that shares power with the node it controls. In such cases, the cluster cannot be sure if the node is really offline, or active and suffering from a network fault." msgstr "" #. Tag: para #, no-c-format msgid "Likewise, any device that relies on the machine being active (such as SSH-based \"devices\" used during testing) are inappropriate." msgstr "" #. Tag: title #, no-c-format msgid "Configuring STONITH" msgstr "" #. Tag: para #, no-c-format msgid "Find the correct driver: pcs stonith list" msgstr "" #. Tag: para #, no-c-format msgid "Find the parameters associated with the device: pcs stonith describe <agent name>" msgstr "" #. Tag: para #, no-c-format msgid "Create a local config to make changes to pcs cluster cib stonith_cfg" msgstr "" #. Tag: para #, no-c-format msgid "Create the fencing resource using pcs -f stonith_cfg stonith create <stonith_id> <stonith device type> [stonith device options]" msgstr "" #. Tag: para #, no-c-format msgid "Set stonith-enable to true. pcs -f stonith_cfg property set stonith-enabled=true" msgstr "" #. Tag: para #, no-c-format msgid "If the device does not know how to fence nodes based on their uname, you may also need to set the special pcmk_host_map parameter. See man stonithd for details." msgstr "" #. Tag: para #, no-c-format msgid "If the device does not support the list command, you may also need to set the special pcmk_host_list and/or pcmk_host_check parameters. See man stonithd for details." msgstr "" #. Tag: para #, no-c-format msgid "If the device does not expect the victim to be specified with the port parameter, you may also need to set the special pcmk_host_argument parameter. See man stonithd for details." msgstr "" #. Tag: para #, no-c-format msgid "Commit the new configuration. pcs cluster push cib stonith_cfg" msgstr "" #. Tag: para #, no-c-format msgid "Once the stonith resource is running, you can test it by executing: stonith_admin --reboot nodename. Although you might want to stop the cluster on that machine first." msgstr "" #. Tag: title #, no-c-format msgid "Example" msgstr "" #. Tag: para #, no-c-format msgid "Assuming we have an chassis containing four nodes and an IPMI device active on 10.0.0.1, then we would chose the fence_ipmilan driver in step 2 and obtain the following list of parameters" msgstr "" #. Tag: title #, no-c-format msgid "Obtaining a list of STONITH Parameters" msgstr "" #. Tag: programlisting #, no-c-format msgid "# pcs stonith describe fence_ipmilan\n" "Stonith options for: fence_ipmilan\n" " auth: IPMI Lan Auth type (md5, password, or none)\n" " ipaddr: IPMI Lan IP to talk to\n" " passwd: Password (if required) to control power on IPMI device\n" " passwd_script: Script to retrieve password (if required)\n" " lanplus: Use Lanplus\n" " login: Username/Login (if required) to control power on IPMI device\n" " action: Operation to perform. Valid operations: on, off, reboot, status, list, diag, monitor or metadata\n" " timeout: Timeout (sec) for IPMI operation\n" " cipher: Ciphersuite to use (same as ipmitool -C parameter)\n" " method: Method to fence (onoff or cycle)\n" " power_wait: Wait X seconds after on/off operation\n" " delay: Wait X seconds before fencing is started\n" " privlvl: Privilege level on IPMI device\n" " verbose: Verbose mode" msgstr "" #. Tag: para #, no-c-format msgid "from which we would create a STONITH resource fragment that might look like this" msgstr "" #. Tag: title #, no-c-format msgid "Sample STONITH Resource" msgstr "" #. Tag: screen #, no-c-format msgid "# pcs cluster cib stonith_cfg\n" "# pcs -f stonith_cfg stonith create impi-fencing fence_ipmilan \\\n" " pcmk_host_list=\"pcmk-1 pcmk-2\" ipaddr=10.0.0.1 login=testuser \\\n" " passwd=acd123 op monitor interval=60s" msgstr "" #. Tag: programlisting #, no-c-format msgid "# pcs -f stonith_cfg stonith\n" " impi-fencing (stonith:fence_ipmilan) Stopped" msgstr "" #. Tag: para #, no-c-format msgid "And finally, since we disabled it earlier, we need to re-enable STONITH. At this point we should have the following configuration." msgstr "" #. Tag: programlisting #, no-c-format msgid "# pcs -f stonith_cfg property set stonith-enabled=true\n" "# pcs -f stonith_cfg property\n" "dc-version: 1.1.8-1.el7-60a19ed12fdb4d5c6a6b6767f52e5391e447fec0\n" "cluster-infrastructure: corosync\n" "no-quorum-policy: ignore\n" "stonith-enabled: true" msgstr "" #. Tag: para #, no-c-format msgid "Now push the configuration into the cluster." msgstr "" #. Tag: programlisting #, no-c-format msgid "# pcs cluster push cib stonith_cfg" msgstr "" pacemaker-master/doc/Clusters_from_Scratch/pot/Ch-Tools.pot000066400000000000000000000117011217637305600243320ustar00rootroot00000000000000# # AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: 0\n" "POT-Creation-Date: 2012-10-17T05:19:03\n" "PO-Revision-Date: 2012-10-17T05:19:03\n" "Last-Translator: Automatically generated\n" "Language-Team: None\n" "MIME-Version: 1.0\n" "Content-Type: application/x-publican; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. Tag: title #, no-c-format msgid "Pacemaker Tools" msgstr "" #. Tag: title #, no-c-format msgid "Using Pacemaker Tools" msgstr "" #. Tag: para #, no-c-format msgid "In the dark past, configuring Pacemaker required the administrator to read and write XML. In true UNIX style, there were also a number of different commands that specialized in different aspects of querying and updating the cluster." msgstr "" #. Tag: para #, no-c-format msgid "All of that has been greatly simplified with the creation of unified command-line shells (and GUIs) that hide all the messy XML scaffolding." msgstr "" #. Tag: para #, no-c-format msgid "These shells take all the individual aspects required for managing and configuring a cluster, and packs them into one simple to use command line tool." msgstr "" #. Tag: para #, no-c-format msgid "They even allow you to queue up several changes at once and commit them atomically." msgstr "" #. Tag: para #, no-c-format msgid "There are currently two command-line shells that people use, pcs and crmsh. This edition of Clusters from Scratch is based on pcs. Start by taking some time to familiarize yourself with what it can do." msgstr "" #. Tag: para #, no-c-format msgid "The two shells share many concepts but the scope, layout and syntax does differ, so make sure you read the version of this guide that corresponds to the software installed on your system." msgstr "" #. Tag: para #, no-c-format msgid "Since pcs has the ability to manage all aspects of the cluster (both corosync and pacemaker), it requires a specific cluster stack to be in use, (corosync 2.0 with votequorum + Pacemaker version >= 1.8)." msgstr "" #. Tag: programlisting #, no-c-format msgid "# pcs" msgstr "" #. Tag: literallayout #, no-c-format msgid "Control and configure pacemaker and corosync.\n" "\n" "Options:\n" " -h Display usage and exit\n" " -f file Perform actions on file instead of active CIB\n" "\n" "Commands:\n" " resource Manage cluster resources\n" " cluster Configure cluster options and nodes\n" " stonith Configure fence devices\n" " property Set pacemaker properties\n" " constraint Set resource constraints\n" " status View cluster status" msgstr "" #. Tag: para #, no-c-format msgid "As you can see, the different aspects of cluster management are broken up into categories: resource, cluster, stonith, property, constraint, and status. To discover the functionality available in each of these categories, one can issue the command pcs <category> help. Below is an example of all the options available under the status category." msgstr "" #. Tag: programlisting #, no-c-format msgid "# pcs status help" msgstr "" #. Tag: literallayout #, no-c-format msgid "Usage: pcs status [commands]...\n" "View current cluster and resource status\n" "Commands:\n" " status\n" " View all information about the cluster and resources\n" "\n" " status resources\n" " View current status of cluster resources\n" "\n" " status groups\n" " View currently configured groups and their resources\n" "\n" " status cluster\n" " View current cluster status\n" "\n" " status corosync\n" " View current corosync status\n" "\n" " status nodes [corosync]\n" " View current status of nodes from pacemaker, or if corosync is\n" " specified, print nodes currently configured in corosync\n" "\n" " status actions\n" " View failed actions\n" "\n" " status pcsd <node> ...\n" " Show the current status of pcsd on the specified nodes\n" "\n" " status xml\n" " View xml version of status (output from crm_mon -r -1 -X)" msgstr "" #. Tag: para #, no-c-format msgid "Additionally, if you are interested in the Pacemaker version and supported cluster stack(s) available with your current Pacemaker installation, the pacemakerd --features option is available to you." msgstr "" #. Tag: programlisting #, no-c-format msgid "# pacemakerd --features" msgstr "" #. Tag: screen #, no-c-format msgid "Pacemaker 1.1.8 (Build: 434edfa)\n" " Supporting: generated-manpages agent-manpages ascii-docs publican-docs ncurses gcov libqb-logging libqb-ipc lha-fencing upstart systemd heartbeat corosync-native snmp" msgstr "" #. Tag: para #, no-c-format msgid "If the SNMP and/or email options are not listed, then Pacemaker was not built to support them. This may be by the choice of your distribution or the required libraries may not have been available. Please contact whoever supplied you with the packages for more details." msgstr "" pacemaker-master/doc/Clusters_from_Scratch/pot/Ch-Verification.pot000066400000000000000000000121351217637305600256560ustar00rootroot00000000000000# # AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: 0\n" "POT-Creation-Date: 2012-10-17T05:19:03\n" "PO-Revision-Date: 2012-10-17T05:19:03\n" "Last-Translator: Automatically generated\n" "Language-Team: None\n" "MIME-Version: 1.0\n" "Content-Type: application/x-publican; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. Tag: title #, no-c-format msgid "Verify Cluster Installation" msgstr "" #. Tag: title #, no-c-format msgid "Start the Cluster" msgstr "" #. Tag: para #, no-c-format msgid "Now that corosync is configured, it is time to start the cluster. The command below will start corosync and pacemaker on both nodes in the cluster. If you are issuing the start command from a different node than the one you ran the pcs cluster auth command on earlier, you must authenticate on current node you are logged into before you will be allowed to start the cluster." msgstr "" #. Tag: programlisting #, no-c-format msgid "# pcs cluster start --all\n" "pcmk-1: Starting Cluster...\n" "pcmk-2: Starting Cluster..." msgstr "" #. Tag: para #, no-c-format msgid "An alternative to using the pcs cluster startall command is to issue either of the below commands on each node in the cluster by hand." msgstr "" #. Tag: programlisting #, no-c-format msgid "# pcs cluster start\n" "Starting Cluster..." msgstr "" #. Tag: para #, no-c-format msgid "or" msgstr "" #. Tag: programlisting #, no-c-format msgid "# systemctl start corosync.service\n" "# systemctl start pacemaker.service" msgstr "" #. Tag: title #, no-c-format msgid "Verify Corosync Installation" msgstr "" #. Tag: para #, no-c-format msgid "The first thing to check is if cluster communication is happy, for that we use corosync-cfgtool." msgstr "" #. Tag: programlisting #, no-c-format msgid "# corosync-cfgtool -s\n" "Printing ring status.\n" "Local node ID 1\n" "RING ID 0\n" " id = 192.168.122.101\n" " status = ring 0 active with no faults" msgstr "" #. Tag: para #, no-c-format msgid "We can see here that everything appears normal with our fixed IP address, not a 127.0.0.x loopback address, listed as the id and no faults for the status." msgstr "" #. Tag: para #, no-c-format msgid "If you see something different, you might want to start by checking the node’s network, firewall and selinux configurations." msgstr "" #. Tag: para #, no-c-format msgid "Next we check the membership and quorum APIs:" msgstr "" #. Tag: programlisting #, no-c-format msgid "# corosync-cmapctl | grep members\n" "runtime.totem.pg.mrp.srp.members.1.ip (str) = r(0) ip(192.168.122.101)\n" "runtime.totem.pg.mrp.srp.members.1.join_count (u32) = 1\n" "runtime.totem.pg.mrp.srp.members.1.status (str) = joined\n" "runtime.totem.pg.mrp.srp.members.2.ip (str) = r(0) ip(192.168.122.102)\n" "runtime.totem.pg.mrp.srp.members.2.join_count (u32) = 1\n" "runtime.totem.pg.mrp.srp.members.2.status (str) = joined\n" "\n" "# pcs status corosync\n" "Membership information\n" " --------------------------\n" " Nodeid Votes Name\n" " 1 1 pcmk-1\n" " 2 1 pcmk-2" msgstr "" #. Tag: para #, no-c-format msgid "You should see both nodes have joined the cluster." msgstr "" #. Tag: para #, no-c-format msgid "All good!" msgstr "" #. Tag: title #, no-c-format msgid "Verify Pacemaker Installation" msgstr "" #. Tag: para #, no-c-format msgid "Now that we have confirmed that Corosync is functional we can check the rest of the stack. Pacemaker has already been started, so verify the necessary processes are running." msgstr "" #. Tag: programlisting #, no-c-format msgid "# ps axf\n" " PID TTY STAT TIME COMMAND\n" " 2 ? S 0:00 [kthreadd]\n" "...lots of processes...\n" "28019 ? Ssl 0:03 /usr/sbin/corosync\n" "28047 ? Ss 0:00 /usr/sbin/pacemakerd -f\n" "28048 ? Ss 0:00 \\_ /usr/libexec/pacemaker/cib\n" "28049 ? Ss 0:00 \\_ /usr/libexec/pacemaker/stonithd\n" "28050 ? Ss 0:00 \\_ /usr/lib64/heartbeat/lrmd\n" "28051 ? Ss 0:00 \\_ /usr/libexec/pacemaker/attrd\n" "28052 ? Ss 0:00 \\_ /usr/libexec/pacemaker/pengine\n" "28053 ? Ss 0:00 \\_ /usr/libexec/pacemaker/crmd" msgstr "" #. Tag: para #, no-c-format msgid "If that looks ok, check the pcs status output." msgstr "" #. Tag: programlisting #, no-c-format msgid "# pcs status\n" "Last updated: Fri Sep 14 09:52:25 2012\n" "Last change: Fri Sep 14 09:51:55 2012 via crmd on pcmk-2\n" "Stack: corosync\n" "Current DC: pcmk-2 (2) - partition with quorum\n" "Version: 1.1.8-1.el7-60a19ed12fdb4d5c6a6b6767f52e5391e447fec0\n" "2 Nodes configured, unknown expected votes\n" "0 Resources configured.\n" "\n" "Online: [ pcmk-1 pcmk-2 ]\n" "\n" "Full list of resources:" msgstr "" #. Tag: para #, no-c-format msgid "Next, check for any ERRORs during startup - there shouldn’t be any." msgstr "" #. Tag: programlisting #, no-c-format msgid "# grep -i error /var/log/messages" msgstr "" #. Tag: para #, no-c-format msgid "Repeat these checks on the other node. The results should be the same." msgstr "" pacemaker-master/doc/Clusters_from_Scratch/pot/Clusters_from_Scratch.pot000066400000000000000000000005371217637305600272050ustar00rootroot00000000000000# # AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: 0\n" "POT-Creation-Date: 2012-10-17T05:19:03\n" "PO-Revision-Date: 2012-10-17T05:19:03\n" "Last-Translator: Automatically generated\n" "Language-Team: None\n" "MIME-Version: 1.0\n" "Content-Type: application/x-publican; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" pacemaker-master/doc/Clusters_from_Scratch/pot/Preface.pot000066400000000000000000000006271217637305600242540ustar00rootroot00000000000000# # AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: 0\n" "POT-Creation-Date: 2012-10-17T05:19:03\n" "PO-Revision-Date: 2012-10-17T05:19:03\n" "Last-Translator: Automatically generated\n" "Language-Team: None\n" "MIME-Version: 1.0\n" "Content-Type: application/x-publican; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. Tag: title #, no-c-format msgid "Preface" msgstr "" pacemaker-master/doc/Clusters_from_Scratch/pot/Revision_History.pot000066400000000000000000000024171217637305600262250ustar00rootroot00000000000000# # AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: 0\n" "POT-Creation-Date: 2012-10-17T05:19:03\n" "PO-Revision-Date: 2012-10-17T05:19:03\n" "Last-Translator: Automatically generated\n" "Language-Team: None\n" "MIME-Version: 1.0\n" "Content-Type: application/x-publican; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. Tag: title #, no-c-format msgid "Revision History" msgstr "" #. Tag: firstname #, no-c-format msgid "Andrew" msgstr "" #. Tag: surname #, no-c-format msgid "Beekhof" msgstr "" #. Tag: member #, no-c-format msgid "Import from Pages.app" msgstr "" #. Tag: firstname #, no-c-format msgid "Raoul" msgstr "" #. Tag: surname #, no-c-format msgid "Scarazzini" msgstr "" #. Tag: member #, no-c-format msgid "Italian translation" msgstr "" #. Tag: member #, no-c-format msgid "Updated for Fedora 13" msgstr "" #. Tag: member #, no-c-format msgid "Update the GFS2 section to use CMAN" msgstr "" #. Tag: member #, no-c-format msgid "Generate docbook content from asciidoc sources" msgstr "" #. Tag: member #, no-c-format msgid "Updated for Fedora 17" msgstr "" #. Tag: firstname #, no-c-format msgid "David" msgstr "" #. Tag: surname #, no-c-format msgid "Vossel" msgstr "" #. Tag: member #, no-c-format msgid "Updated for pcs" msgstr "" pacemaker-master/doc/Clusters_from_Scratch/publican.cfg.in000066400000000000000000000004021217637305600242330ustar00rootroot00000000000000# Config::Simple 4.59 # Fri Apr 23 15:33:52 2010 docname: Clusters_from_Scratch xml_lang: en-US #edition: 1 type: Book version: @PACKAGE_SERIES@ brand: @PUBLICAN_BRAND@ product: Pacemaker chunk_first: 0 chunk_section_depth: 3 generate_section_toc_level: 4 pacemaker-master/doc/Clusters_from_Scratch/ro-RO/000077500000000000000000000000001217637305600223125ustar00rootroot00000000000000pacemaker-master/doc/Clusters_from_Scratch/ro-RO/Ap-Cman.po000066400000000000000000000253161217637305600240750ustar00rootroot00000000000000# # AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: Clusters from Scratch 1.1\n" "POT-Creation-Date: 2012-02-09T05:01:55\n" "PO-Revision-Date: 2011-11-20 10:41+0200\n" "Last-Translator: Dan Frîncu \n" "Language-Team: None\n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: application/x-publican; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. Tag: title #, no-c-format msgid "Using CMAN for Cluster Membership and Quorum" msgstr "Folosirea CMAN pentru Apartenenţa la Cluster şi Quorum" #. Tag: title #, no-c-format msgid "Background" msgstr "Informaţii de fond" #. Tag: para #, no-c-format msgid "CMAN v3 is a Corosync plugin that monitors the names and number of active cluster nodes in order to deliver membership and quorum information to clients (such as the Pacemaker daemons)." msgstr "CMAN v3 este un plugin al Corosync care monitorizează numele și numărul de noduri active din cluster pentru a livra informații de apartenență și quorum clienților (cum ar fi daemonii Pacemaker-ului)." #. Tag: para #, fuzzy, no-c-format msgid "In a traditional Corosync-Pacemaker cluster, a Pacemaker plugin is loaded to provide membership and quorum information. The motivation for wanting to use CMAN for this instead, is to ensure all elements of the cluster stack are making decisions based on the same membership and quorum data. A failure to do this can lead to what is called internal split-brain - a situation where different parts of the stack disagree about whether some nodes are alive or dead - which quickly leads to unnecssary down-time and/or data corruption. " msgstr "Într-un cluster tradițional Corosync-Pacemaker, un plugin Pacemaker este încărcat pentru a furniza informații de apartenență și quorum. Motivația pentru dorința de a folosi CMAN în schimb, este de a asigura că toate elementele stivei de cluster realizează decizii pe baza acelorași date de apartenență și quorum. Un eșec de a realiza acest lucru poate conduce la ceea ce este numit a fi un split-brain intern - o situație în care părți diferite ale stivei nu sunt de acord dacă unele noduri sunt funcționale sau nu - fapt care conduce rapid către un downtime inutil și/sau către coruperea datelor. " #. Tag: para #, no-c-format msgid "CMAN has been around longer than Pacemaker and is part of the Red Hat cluster stack, so it is available and supported by many distributions and other pieces of software (such as OCFS2 and GFS2). For this reason it makes sense to support it." msgstr "CMAN a fost prin preajmă mai mult timp decât Pacemaker și este parte din stiva de cluster a Red Hat, așa că este disponibil și suportat de către multe distribuții și de alte componente software (cum ar fi OCFS2 și GFS2). Din acest motiv are logică să îl suportăm." #. Tag: title #, no-c-format msgid "Adding CMAN Support" msgstr "Adăugarea de Suport pentru CMAN" #. Tag: para #, no-c-format msgid "Be sure to disable the Pacemaker plugin before continuing with this section. In most cases, this can be achieved by removing /etc/corosync/service.d/pcmk and stopping Corosync." msgstr "Asigurați-vă că dezactivați pluginul de Pacemaker înainte de a continua cu această secțiune. În majoritatea cazurilor, acest lucru poate fi realizat prin înlăturarea /etc/corosync/service.d/pcmk și prin oprirea Corosync." #. Tag: title #, no-c-format msgid "Adding CMAN Support - cluster.conf" msgstr "Adăugarea de Suport pentru CMAN - cluster.conf" #. Tag: para #, fuzzy, no-c-format msgid "The preferred approach for enabling CMAN is to configure cluster.conf and use the /etc/init.d/cman script to start Corosync. Its far easier to maintain and start automatically starts the necessary pieces for using GFS2." msgstr "Abordarea preferată pentru activarea CMAN este să configurați cluster.conf și să folosiți scriptul /etc/init.d/cman pentru a porni Corosync. Este mult mai ușor de menținut și pornirea acestuia pornește automat piesele necesare pentru folosirea GFS2." #. Tag: para #, no-c-format msgid "You can find some documentation on Installing CMAN and Creating a Basic Cluster Configuration File at the Red Hat website. However please ignore the parts about Fencing, Failover Domains, or HA Services and anything to do with rgmanager and fenced. All these continue to be handled by Pacemaker in the normal manner." msgstr "Puteți găsi documentație despre Instalarea CMAN și Crearea unui Fișier de Bază pentru Configurarea Clusterului pe site-ul Red Hat. Totuși vă rugăm să ignorați părțile despre Evacuare forțată, Domenii de Failover sau Servicii HA și orice are de-a face cu rgmanager și fenced. Toate acestea continuă să fie gestionate de către Pacemaker într-o manieră normală." #. Tag: title #, no-c-format msgid "Sample cluster.conf for a two-node cluster" msgstr "Exemplu de cluster.conf pentru un cluster format din două noduri" #. Tag: programlisting #, no-c-format msgid "" "\n" "\t\n" "<?xml version=\"1.0\"?>\n" "<cluster config_version=\"1\" name=\"east8\">\n" " <logging debug=\"off\"/>\n" " <clusternodes>\n" " <clusternode name=\"pcmk-1\" nodeid=\"1\">\n" " <fence>\n" " <method name=\"pcmk-redirect\">\n" " <device name=\"pcmk\" port=\"pcmk-1\"/>\n" " </method>\n" " </fence>\n" " </clusternode>\n" " <clusternode name=\"pcmk-3\" nodeid=\"2\">\n" " <fence>\n" " <method name=\"pcmk-redirect\">\n" " <device name=\"pcmk\" port=\"pcmk-3\"/>\n" " </method>\n" " </fence>\n" " </clusternode>\n" " </clusternodes>\n" " <fencedevices>\n" " <fencedevice name=\"pcmk\" agent=\"fence_pcmk\"/>\n" " </fencedevices>\n" "</cluster>\n" "\t\n" "\t" msgstr "" "\n" "\t\n" "<?xml version=\"1.0\"?>\n" "<cluster config_version=\"1\" name=\"east8\">\n" " <logging debug=\"off\"/>\n" " <clusternodes>\n" " <clusternode name=\"pcmk-1\" nodeid=\"1\">\n" " <fence>\n" " <method name=\"pcmk-redirect\">\n" " <device name=\"pcmk\" port=\"pcmk-1\"/>\n" " </method>\n" " </fence>\n" " </clusternode>\n" " <clusternode name=\"pcmk-3\" nodeid=\"2\">\n" " <fence>\n" " <method name=\"pcmk-redirect\">\n" " <device name=\"pcmk\" port=\"pcmk-3\"/>\n" " </method>\n" " </fence>\n" " </clusternode>\n" " </clusternodes>\n" " <fencedevices>\n" " <fencedevice name=\"pcmk\" agent=\"fence_pcmk\"/>\n" " </fencedevices>\n" "</cluster>\n" "\t\n" "\t" #. Tag: title #, no-c-format msgid "Adding CMAN Support - corosync.conf" msgstr "Adăugarea de Suport pentru CMAN - corosync.conf" #. Tag: para #, no-c-format msgid "The alternative is to add the necessary cman configuration elements to corosync.conf. We recommend you place these directives in /etc/corosync/service.d/cman as they will differ between machines." msgstr "Alternativa este să adăugați elementele necesare pentru configurarea cman în corosync.conf. Vă recomandăm să plasați aceste directive în /etc/corosync/service.d/cman din moment ce acestea vor fi diferite între mașini." #. Tag: para #, fuzzy, no-c-format msgid "If you choose this approach, you would continue to start and stop Corosync with it's init script as previously described in this document." msgstr "Dacă alegeți această abordare, veți continua să porniți și să opriți Corosync cu scriptul său de init după cum am descris în prealabil în acest document." #. Tag: title #, no-c-format msgid "Sample corosync.conf extensions for a two-node cluster" msgstr "Exemplu de extensii ale corosync.conf pentru un cluster format din două noduri" #. Tag: programlisting #, no-c-format msgid "" "\n" "[root@pcmk-1 ~]# cat <<-END >>/etc/corosync/service.d/cman\n" "cluster {\n" " name: beekhof\n" "\n" " clusternodes {\n" " clusternode {\n" " votes: 1\n" " nodeid: 1\n" " name: pcmk-1\n" " }\n" " clusternode {\n" " votes: 1\n" " nodeid: 2\n" " name: pcmk-2\n" " }\n" " }\n" " cman {\n" " expected_votes: 2\n" " cluster_id: 123\n" " nodename: `uname -n`\n" " two_node: 1\n" " max_queued: 10\n" " }\n" "}\n" "\n" "service {\n" " name: corosync_cman\n" " ver: 0\n" "}\n" "\n" "quorum {\n" " provider: quorum_cman\n" "}\n" "END\n" "\t" msgstr "" "\n" "[root@pcmk-1 ~]# cat <<-END >>/etc/corosync/service.d/cman\n" "cluster {\n" " name: beekhof\n" "\n" " clusternodes {\n" " clusternode {\n" " votes: 1\n" " nodeid: 1\n" " name: pcmk-1\n" " }\n" " clusternode {\n" " votes: 1\n" " nodeid: 2\n" " name: pcmk-2\n" " }\n" " }\n" " cman {\n" " expected_votes: 2\n" " cluster_id: 123\n" " nodename: `uname -n`\n" " two_node: 1\n" " max_queued: 10\n" " }\n" "}\n" "\n" "service {\n" " name: corosync_cman\n" " ver: 0\n" "}\n" "\n" "quorum {\n" " provider: quorum_cman\n" "}\n" "END\n" "\t" #. Tag: para #, no-c-format msgid "Verify that nodename was set appropriately on each host." msgstr "Verificați că nodename a fost setat corespunzător pe fiecare gazdă." pacemaker-master/doc/Clusters_from_Scratch/ro-RO/Ap-Configuration.po000066400000000000000000000710011217637305600260160ustar00rootroot00000000000000# # AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: Clusters from Scratch 1.1\n" "POT-Creation-Date: 2012-10-17T05:19:03\n" "PO-Revision-Date: 2011-12-31T16:43:02\n" "Last-Translator: Dan Frîncu \n" "Language-Team: None\n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: application/x-publican; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. Tag: title #, no-c-format msgid "Configuration Recap" msgstr "Recapitularea Configurației" #. Tag: title #, no-c-format msgid "Final Cluster Configuration" msgstr "Configurația Finală a Clusterului" #. Tag: programlisting #, no-c-format msgid "" "# pcs resource\n" " Master/Slave Set: WebDataClone [WebData]\n" " Masters: [ pcmk-2 pcmk-1 ]\n" " Clone Set: dlm-clone [dlm]\n" " Started: [ pcmk-2 pcmk-1 ]\n" " Clone Set: ClusterIP-clone [ClusterIP] (unique)\n" " ClusterIP:0 (ocf::heartbeat:IPaddr2) Started\n" " ClusterIP:1 (ocf::heartbeat:IPaddr2) Started\n" " Clone Set: WebFS-clone [WebFS]\n" " Started: [ pcmk-1 pcmk-2 ]\n" " Clone Set: WebSite-clone [WebSite]\n" " Started: [ pcmk-1 pcmk-2 ]\n" "# pcs resource rsc defaults\n" "resource-stickiness: 100\n" "# pcs resource op defaults\n" "timeout: 240s\n" "# pcs stonith\n" " impi-fencing (stonith:fence_ipmilan) Started\n" "# pcs property\n" "dc-version: 1.1.8-1.el7-60a19ed12fdb4d5c6a6b6767f52e5391e447fec0\n" "cluster-infrastructure: corosync\n" "no-quorum-policy: ignore\n" "stonith-enabled: true\n" "# pcs constraint\n" "Location Constraints:\n" "Ordering Constraints:\n" " ClusterIP-clone then WebSite-clone\n" " WebDataClone then WebSite-clone\n" " WebFS-clone then WebSite-clone\n" "Colocation Constraints:\n" " WebSite-clone with ClusterIP-clone\n" " WebFS-clone with WebDataClone (with-rsc-role:Master)\n" " WebSite-clone with WebFS-clone\n" "#\n" "# pcs status\n" "\n" "Last updated: Fri Sep 14 13:45:34 2012\n" "Last change: Fri Sep 14 13:43:13 2012 via cibadmin on pcmk-1\n" "Stack: corosync\n" "Current DC: pcmk-1 (1) - partition with quorum\n" "Version: 1.1.8-1.el7-60a19ed12fdb4d5c6a6b6767f52e5391e447fec0\n" "2 Nodes configured, unknown expected votes\n" "11 Resources configured.\n" "\n" "Online: [ pcmk-1 pcmk-2 ]\n" "\n" "Full list of resources:\n" "\n" " Master/Slave Set: WebDataClone [WebData]\n" " Masters: [ pcmk-2 pcmk-1 ]\n" " Clone Set: dlm-clone [dlm]\n" " Started: [ pcmk-1 pcmk-2 ]\n" " Clone Set: ClusterIP-clone [ClusterIP] (unique)\n" " ClusterIP:0 (ocf::heartbeat:IPaddr2): Started pcmk-1\n" " ClusterIP:1 (ocf::heartbeat:IPaddr2): Started pcmk-2\n" " Clone Set: WebFS-clone [WebFS]\n" " Started: [ pcmk-1 pcmk-2 ]\n" " Clone Set: WebSite-clone [WebSite]\n" " Started: [ pcmk-1 pcmk-2 ]\n" " impi-fencing (stonith:fence_ipmilan): Started" msgstr "" #. Tag: para #, no-c-format msgid "In xml it should look similar to this." msgstr "" #. Tag: programlisting #, no-c-format msgid "" "<cib admin_epoch=\"0\" cib-last-written=\"Fri Sep 14 13:43:13 2012\" crm_feature_set=\"3.0.6\" dc-uuid=\"1\" epoch=\"47\" have-quorum=\"1\" num_updates=\"50\" update-client=\"cibadmin\" update-origin=\"pcmk-1\" validate-with=\"pacemaker-1.2\">\n" " <configuration>\n" " <crm_config>\n" " <cluster_property_set id=\"cib-bootstrap-options\">\n" " <nvpair id=\"cib-bootstrap-options-dc-version\" name=\"dc-version\" value=\"1.1.8-1.el7-60a19ed12fdb4d5c6a6b6767f52e5391e447fec0\"/>\n" " <nvpair id=\"cib-bootstrap-options-cluster-infrastructure\" name=\"cluster-infrastructure\" value=\"corosync\"/>\n" " <nvpair id=\"cib-bootstrap-options-no-quorum-policy\" name=\"no-quorum-policy\" value=\"ignore\"/>\n" " <nvpair id=\"cib-bootstrap-options-stonith-enabled\" name=\"stonith-enabled\" value=\"true\"/>\n" " </cluster_property_set>\n" " </crm_config>\n" " <nodes>\n" " <node id=\"1\" type=\"normal\" uname=\"pcmk-1\"/>\n" " <node id=\"2\" type=\"normal\" uname=\"pcmk-2\"/>\n" " </nodes>\n" " <resources>\n" " <master id=\"WebDataClone\">\n" " <primitive class=\"ocf\" id=\"WebData\" provider=\"linbit\" type=\"drbd\">\n" " <instance_attributes id=\"WebData-instance_attributes\">\n" " <nvpair id=\"WebData-instance_attributes-drbd_resource\" name=\"drbd_resource\" value=\"wwwdata\"/>\n" " </instance_attributes>\n" " <operations>\n" " <op id=\"WebData-interval-60s\" interval=\"60s\" name=\"monitor\"/>\n" " </operations>\n" " </primitive>\n" " <meta_attributes id=\"WebDataClone-meta_attributes\">\n" " <nvpair id=\"WebDataClone-meta_attributes-master-node-max\" name=\"master-node-max\" value=\"1\"/>\n" " <nvpair id=\"WebDataClone-meta_attributes-clone-max\" name=\"clone-max\" value=\"2\"/>\n" " <nvpair id=\"WebDataClone-meta_attributes-clone-node-max\" name=\"clone-node-max\" value=\"1\"/>\n" " <nvpair id=\"WebDataClone-meta_attributes-notify\" name=\"notify\" value=\"true\"/>\n" " <nvpair id=\"WebDataClone-meta_attributes-master-max\" name=\"master-max\" value=\"2\"/>\n" " </meta_attributes>\n" " </master>\n" " <clone id=\"dlm-clone\">\n" " <primitive class=\"ocf\" id=\"dlm\" provider=\"pacemaker\" type=\"controld\">\n" " <instance_attributes id=\"dlm-instance_attributes\"/>\n" " <operations>\n" " <op id=\"dlm-interval-60s\" interval=\"60s\" name=\"monitor\"/>\n" " </operations>\n" " </primitive>\n" " <meta_attributes id=\"dlm-clone-meta\">\n" " <nvpair id=\"dlm-clone-max\" name=\"clone-max\" value=\"2\"/>\n" " <nvpair id=\"dlm-clone-node-max\" name=\"clone-node-max\" value=\"1\"/>\n" " </meta_attributes>\n" " </clone>\n" " <clone id=\"ClusterIP-clone\">\n" " <primitive class=\"ocf\" id=\"ClusterIP\" provider=\"heartbeat\" type=\"IPaddr2\">\n" " <instance_attributes id=\"ClusterIP-instance_attributes\">\n" " <nvpair id=\"ClusterIP-instance_attributes-ip\" name=\"ip\" value=\"192.168.0.120\"/>\n" " <nvpair id=\"ClusterIP-instance_attributes-cidr_netmask\" name=\"cidr_netmask\" value=\"32\"/>\n" " <nvpair id=\"ClusterIP-instance_attributes-clusterip_hash\" name=\"clusterip_hash\" value=\"sourceip\"/>\n" " </instance_attributes>\n" " <operations>\n" " <op id=\"ClusterIP-interval-30s\" interval=\"30s\" name=\"monitor\"/>\n" " </operations>\n" " </primitive>\n" " <meta_attributes id=\"ClusterIP-clone-meta\">\n" " <nvpair id=\"ClusterIP-globally-unique\" name=\"globally-unique\" value=\"true\"/>\n" " <nvpair id=\"ClusterIP-clone-max\" name=\"clone-max\" value=\"2\"/>\n" " <nvpair id=\"ClusterIP-clone-node-max\" name=\"clone-node-max\" value=\"2\"/>\n" " </meta_attributes>\n" " </clone>\n" " <clone id=\"WebFS-clone\">\n" " <primitive class=\"ocf\" id=\"WebFS\" provider=\"heartbeat\" type=\"Filesystem\">\n" " <instance_attributes id=\"WebFS-instance_attributes\">\n" " <nvpair id=\"WebFS-instance_attributes-device\" name=\"device\" value=\"/dev/drbd/by-res/wwwdata\"/>\n" " <nvpair id=\"WebFS-instance_attributes-directory\" name=\"directory\" value=\"/var/www/html\"/>\n" " <nvpair id=\"WebFS-instance_attributes-fstype\" name=\"fstype\" value=\"gfs2\"/>\n" " </instance_attributes>\n" " <meta_attributes id=\"WebFS-meta_attributes\"/>\n" " </primitive>\n" " <meta_attributes id=\"WebFS-clone-meta\"/>\n" " </clone>\n" " <clone id=\"WebSite-clone\">\n" " <primitive class=\"ocf\" id=\"WebSite\" provider=\"heartbeat\" type=\"apache\">\n" " <instance_attributes id=\"WebSite-instance_attributes\">\n" " <nvpair id=\"WebSite-instance_attributes-configfile\" name=\"configfile\" value=\"/etc/httpd/conf/httpd.conf\"/>\n" " <nvpair id=\"WebSite-instance_attributes-statusurl\" name=\"statusurl\" value=\"http://localhost/server-status\"/>\n" " </instance_attributes>\n" " <operations>\n" " <op id=\"WebSite-interval-1min\" interval=\"1min\" name=\"monitor\"/>\n" " </operations>\n" " </primitive>\n" " <meta_attributes id=\"WebSite-clone-meta\"/>\n" " </clone>\n" " <primitive class=\"stonith\" id=\"impi-fencing\" type=\"fence_ipmilan\">\n" " <instance_attributes id=\"impi-fencing-instance_attributes\">\n" " <nvpair id=\"impi-fencing-instance_attributes-pcmk_host_list\" name=\"pcmk_host_list\" value=\"pcmk-1 pcmk-2\"/>\n" " <nvpair id=\"impi-fencing-instance_attributes-ipaddr\" name=\"ipaddr\" value=\"10.0.0.1\"/>\n" " <nvpair id=\"impi-fencing-instance_attributes-login\" name=\"login\" value=\"testuser\"/>\n" " <nvpair id=\"impi-fencing-instance_attributes-passwd\" name=\"passwd\" value=\"acd123\"/>\n" " </instance_attributes>\n" " <operations>\n" " <op id=\"impi-fencing-interval-60s\" interval=\"60s\" name=\"monitor\"/>\n" " </operations>\n" " </primitive>\n" " </resources>\n" " <constraints>\n" " <rsc_colocation id=\"colocation-WebSite-ClusterIP-INFINITY\" rsc=\"WebSite-clone\" score=\"INFINITY\" with-rsc=\"ClusterIP-clone\"/>\n" " <rsc_order first=\"ClusterIP-clone\" first-action=\"start\" id=\"order-ClusterIP-WebSite-mandatory\" then=\"WebSite-clone\" then-action=\"start\"/>\n" " <rsc_colocation id=\"colocation-WebFS-WebDataClone-INFINITY\" rsc=\"WebFS-clone\" score=\"INFINITY\" with-rsc=\"WebDataClone\" with-rsc-role=\"Master\"/>\n" " <rsc_colocation id=\"colocation-WebSite-WebFS-INFINITY\" rsc=\"WebSite-clone\" score=\"INFINITY\" with-rsc=\"WebFS-clone\"/>\n" " <rsc_order first=\"WebFS-clone\" id=\"order-WebFS-WebSite-mandatory\" then=\"WebSite-clone\"/>\n" " <rsc_order first=\"WebDataClone\" first-action=\"promote\" id=\"order-WebDataClone-WebFS-mandatory\" then=\"WebFS-clone\" then-action=\"start\"/>\n" " </constraints>\n" " <rsc_defaults>\n" " <meta_attributes id=\"rsc_defaults-options\">\n" " <nvpair id=\"rsc_defaults-options-resource-stickiness\" name=\"resource-stickiness\" value=\"100\"/>\n" " </meta_attributes>\n" " </rsc_defaults>\n" " <op_defaults>\n" " <meta_attributes id=\"op_defaults-options\">\n" " <nvpair id=\"op_defaults-options-timeout\" name=\"timeout\" value=\"240s\"/>\n" " </meta_attributes>\n" " </op_defaults>\n" " </configuration>\n" "</cib>" msgstr "" #. Tag: title #, no-c-format msgid "Node List" msgstr "Lista Nodurilor" #. Tag: para #, no-c-format msgid "The list of cluster nodes is automatically populated by the cluster." msgstr "Lista nodurilor din cluster este populată în mod automat de către cluster." #. Tag: literallayout #, no-c-format msgid "" "Pacemaker Nodes:\n" " Online: [ pcmk-1 pcmk-2 ]" msgstr "" #. Tag: title #, no-c-format msgid "Cluster Options" msgstr "Opțiunile Clusterului" #. Tag: para #, no-c-format msgid "This is where the cluster automatically stores some information about the cluster" msgstr "Aici este locul unde clusterul stochează automat anumite informații despre cluster" #. Tag: para #, no-c-format msgid "dc-version - the version (including upstream source-code hash) of Pacemaker used on the DC" msgstr "dc-version - versiunea (incluzând hash-ul codului sursă din upstream) Pacemaker-ului folosit pe DC" #. Tag: para #, no-c-format msgid "cluster-infrastructure - the cluster infrastructure being used (heartbeat or openais)" msgstr "cluster-infrastructure - infrastructura de cluster folosită (heartbeat sau openais)" #. Tag: para #, no-c-format msgid "expected-quorum-votes - the maximum number of nodes expected to be part of the cluster" msgstr "expected-quorum-votes - numărul maxim de noduri care se așteaptă să facă parte din cluster" #. Tag: para #, no-c-format msgid "and where the admin can set options that control the way the cluster operates" msgstr "și locul unde administratorul poate seta opțiuni care controlează modul în care operează clusterul" #. Tag: para #, no-c-format msgid "stonith-enabled=true - Make use of STONITH" msgstr "stonith-enabled=true - Pune STONITH în folosință" #. Tag: para #, no-c-format msgid "no-quorum-policy=ignore - Ignore loss of quorum and continue to host resources." msgstr "no-quorum-policy=ignore - Ignoră pierderea quorumului și continuă să găzduiască resurse." #. Tag: programlisting #, no-c-format msgid "" "# pcs property\n" "dc-version: 1.1.8-1.el7-60a19ed12fdb4d5c6a6b6767f52e5391e447fec0\n" "cluster-infrastructure: corosync\n" "no-quorum-policy: ignore\n" "stonith-enabled: true" msgstr "" #. Tag: title #, no-c-format msgid "Resources" msgstr "Resurse" #. Tag: title #, no-c-format msgid "Default Options" msgstr "Opțiuni Implicite" #. Tag: para #, no-c-format msgid "Here we configure cluster options that apply to every resource." msgstr "Aici configurăm opțiuni ale clusterului care se aplică fiecărei resurse." #. Tag: para #, no-c-format msgid "resource-stickiness - Specify the aversion to moving resources to other machines" msgstr "resource-stickiness - Specifică aversiunea față de mutarea resurselor către alte mașini" #. Tag: programlisting #, no-c-format msgid "" "# pcs resource rsc defaults\n" "resource-stickiness: 100" msgstr "" #. Tag: title #, no-c-format msgid "Fencing" msgstr "Evacuarea Forțată" #. Tag: programlisting #, no-c-format msgid "" "# pcs stonith show\n" " impi-fencing (stonith:fence_ipmilan) Started\n" "# pcs stonith show impi-fencing\n" "Resource: impi-fencing\n" " pcmk_host_list: pcmk-1 pcmk-2\n" " ipaddr: 10.0.0.1\n" " login: testuser\n" " passwd: acd123" msgstr "" #. Tag: title #, no-c-format msgid "Service Address" msgstr "Adresa Serviciului" #. Tag: para #, no-c-format msgid "Users of the services provided by the cluster require an unchanging address with which to access it. Additionally, we cloned the address so it will be active on both nodes. An iptables rule (created as part of the resource agent) is used to ensure that each request only gets processed by one of the two clone instances. The additional meta options tell the cluster that we want two instances of the clone (one \"request bucket\" for each node) and that if one node fails, then the remaining node should hold both." msgstr "Utilizatorii serviciilor furnizate de către cluster necesită o adresă neschimbabilă prin care să le acceseze. În mod adițional, am clonat adresa astfel încât va fi activă pe ambele noduri. O regulă de iptables (creată ca parte din agentul de resursă) este folosită pentru a asigura faptul că fiecare cerere va fi procesată doar de către una din cele două instanțe ale clonei. Meta opțiunile adiționale spun clusterului că dorim două instanțe ale clonei (câte o \"găleată de cereri\" pentru fiecare nod) și că dacă un nod eșuează, atunci nodul care rămâne ar trebui să le țină pe amândouă." #. Tag: programlisting #, no-c-format msgid "" "# pcs resource show ClusterIP-clone\n" "Resource: ClusterIP-clone\n" " ip: 192.168.0.120\n" " cidr_netmask: 32\n" " clusterip_hash: sourceip\n" " globally-unique: true\n" " clone-max: 2\n" " clone-node-max: 2\n" " op monitor interval=30s" msgstr "" #. Tag: para #, no-c-format msgid "TODO: The RA should check for globally-unique=true when cloned" msgstr "TODO: RA-ul ar trebui să verifice globally-unique=true când este clonat" #. Tag: title #, no-c-format msgid "DRBD - Shared Storage" msgstr "DRBD - Stocare Partajată" #. Tag: para #, no-c-format msgid "Here we define the DRBD service and specify which DRBD resource (from drbd.conf) it should manage. We make it a master/slave resource and, in order to have an active/active setup, allow both instances to be promoted by specifying master-max=2. We also set the notify option so that the cluster will tell DRBD agent when it’s peer changes state." msgstr "Aici definim serviciul DRBD și specificăm care resursă DRBD (din drbd.conf) ar trebui să gestioneze. O creem ca resursă master/slave și pentru a avea un setup activ/activ, permitem ambelor instanțe să fie promovate specificând master-max=2. De asemenea setăm opțiunea notify astfel încât clusterul va spune agentului DRBD când vecinul acestuia își schimbă starea." #. Tag: programlisting #, no-c-format msgid "" "# pcs resource show WebDataClone\n" "Resource: WebDataClone\n" " drbd_resource: wwwdata\n" " master-node-max: 1\n" " clone-max: 2\n" " clone-node-max: 1\n" " notify: true\n" " master-max: 2\n" " op monitor interval=60s\n" "# pcs constraint ref WebDataClone\n" "Resource: WebDataClone\n" " colocation-WebFS-WebDataClone-INFINITY\n" " order-WebDataClone-WebFS-mandatory" msgstr "" #. Tag: title #, no-c-format msgid "Cluster Filesystem" msgstr "Sistem de Fișiere de Cluster" #. Tag: para #, no-c-format msgid "The cluster filesystem ensures that files are read and written correctly. We need to specify the block device (provided by DRBD), where we want it mounted and that we are using GFS2. Again it is a clone because it is intended to be active on both nodes. The additional constraints ensure that it can only be started on nodes with active gfs-control and drbd instances." msgstr "Sistemul de fișiere de cluster se asigură că fișierele sunt citite și scrise corect. Trebuie să specificâm dispozitivul de tip bloc (furnizat de DRBD), unde îl vrem montat și că folosim GFS2. Din nou este o clonă deoarece este intenționat să fie activă pe ambele noduri. Restricțiile adiționale asigură faptul că poate fi pornită numai pe noduri cu gfs-control activ și instanțe DRBD." #. Tag: programlisting #, no-c-format msgid "" "# pcs resource show WebFS-clone\n" "Resource: WebFS-clone\n" " device: /dev/drbd/by-res/wwwdata\n" " directory: /var/www/html\n" " fstype: gfs2\n" "# pcs constraint ref WebFS-clone\n" "Resource: WebFS-clone\n" " colocation-WebFS-WebDataClone-INFINITY\n" " colocation-WebSite-WebFS-INFINITY\n" " order-WebFS-WebSite-mandatory\n" " order-WebDataClone-WebFS-mandatory" msgstr "" #. Tag: title #, no-c-format msgid "Apache" msgstr "Apache" #. Tag: para #, fuzzy, no-c-format msgid "Lastly we have the actual service, Apache. We need only tell the cluster where to find it’s main configuration file and restrict it to running on nodes that have the required filesystem mounted and the IP address active." msgstr "În cele din urmă avem serviciul în sine, Apache. Nu trebuie decât să specificăm clusterului unde să găsească fișierul principal de configurare al acestuia și să-l restricționăm în a rula numai pe nodurile care au montat sistemul de fișiere cerut și adresa IP activă." #. Tag: programlisting #, no-c-format msgid "" "# pcs resource show WebSite-clone\n" "Resource: WebSite-clone\n" " configfile: /etc/httpd/conf/httpd.conf\n" " statusurl: http://localhost/server-status\n" " master-max: 2\n" " op monitor interval=1min\n" "# pcs constraint ref WebSite-clone\n" "Resource: WebSite-clone\n" " colocation-WebSite-ClusterIP-INFINITY\n" " colocation-WebSite-WebFS-INFINITY\n" " order-ClusterIP-WebSite-mandatory\n" " order-WebFS-WebSite-mandatory" msgstr "" #~ msgid "" #~ "\n" #~ "[root@pcmk-1 ~]# crm configure show\n" #~ "node pcmk-1\n" #~ "node pcmk-2\n" #~ "primitive WebData ocf:linbit:drbd \\\n" #~ "        params drbd_resource=\"wwwdata\" \\\n" #~ "        op monitor interval=\"60s\"\n" #~ "primitive WebFS ocf:heartbeat:Filesystem \\\n" #~ "        params device=\"/dev/drbd/by-res/wwwdata\" directory=\"/var/www/html\" fstype=\"gfs2\"\n" #~ "primitive WebSite ocf:heartbeat:apache \\\n" #~ "        params configfile=\"/etc/httpd/conf/httpd.conf\" \\\n" #~ "        op monitor interval=\"1min\"\n" #~ "primitive ClusterIP ocf:heartbeat:IPaddr2 \\\n" #~ "        params ip=\"192.168.122.101\" cidr_netmask=\"32\" clusterip_hash=\"sourceip\" \\\n" #~ "        op monitor interval=\"30s\"\n" #~ "primitive ipmi-fencing stonith::fence_ipmilan \\\n" #~ "        params pcmk_host_list=\"pcmk-1 pcmk-2\" ipaddr=10.0.0.1 login=testuser passwd=abc123 \\\n" #~ "        op monitor interval=\"60s\"\n" #~ "ms WebDataClone WebData \\\n" #~ "        meta master-max=\"2\" master-node-max=\"1\" clone-max=\"2\" clone-node-max=\"1\" notify=\"true\"\n" #~ "clone WebFSClone WebFS\n" #~ "clone WebIP ClusterIP  \\\n" #~ "        meta globally-unique=\"true\" clone-max=\"2\" clone-node-max=\"2\"\n" #~ "clone WebSiteClone WebSite\n" #~ "colocation WebSite-with-WebFS inf: WebSiteClone WebFSClone\n" #~ "colocation fs_on_drbd inf: WebFSClone WebDataClone:Master\n" #~ "colocation website-with-ip inf: WebSiteClone WebIP\n" #~ "order WebFS-after-WebData inf: WebDataClone:promote WebFSClone:start\n" #~ "order WebSite-after-WebFS inf: WebFSClone WebSiteClone\n" #~ "order apache-after-ip inf: WebIP WebSiteClone\n" #~ "property $id=\"cib-bootstrap-options\" \\\n" #~ "        dc-version=\"1.1.5-bdd89e69ba545404d02445be1f3d72e6a203ba2f\" \\\n" #~ "        cluster-infrastructure=\"openais\" \\\n" #~ "        expected-quorum-votes=\"2\" \\\n" #~ "        stonith-enabled=\"true\" \\\n" #~ "        no-quorum-policy=\"ignore\"\n" #~ "rsc_defaults $id=\"rsc-options\" \\\n" #~ "        resource-stickiness=\"100\"\n" #~ msgstr "" #~ "\n" #~ "[root@pcmk-1 ~]# crm configure show\n" #~ "node pcmk-1\n" #~ "node pcmk-2\n" #~ "primitive WebData ocf:linbit:drbd \\\n" #~ "        params drbd_resource=\"wwwdata\" \\\n" #~ "        op monitor interval=\"60s\"\n" #~ "primitive WebFS ocf:heartbeat:Filesystem \\\n" #~ "        params device=\"/dev/drbd/by-res/wwwdata\" directory=\"/var/www/html\" fstype=\"gfs2\"\n" #~ "primitive WebSite ocf:heartbeat:apache \\\n" #~ "        params configfile=\"/etc/httpd/conf/httpd.conf\" \\\n" #~ "        op monitor interval=\"1min\"\n" #~ "primitive ClusterIP ocf:heartbeat:IPaddr2 \\\n" #~ "        params ip=\"192.168.122.101\" cidr_netmask=\"32\" clusterip_hash=\"sourceip\" \\\n" #~ "        op monitor interval=\"30s\"\n" #~ "primitive ipmi-fencing stonith::fence_ipmilan \\\n" #~ "        params pcmk_host_list=\"pcmk-1 pcmk-2\" ipaddr=10.0.0.1 login=testuser passwd=abc123 \\\n" #~ "        op monitor interval=\"60s\"\n" #~ "ms WebDataClone WebData \\\n" #~ "        meta master-max=\"2\" master-node-max=\"1\" clone-max=\"2\" clone-node-max=\"1\" notify=\"true\"\n" #~ "clone WebFSClone WebFS\n" #~ "clone WebIP ClusterIP  \\\n" #~ "        meta globally-unique=\"true\" clone-max=\"2\" clone-node-max=\"2\"\n" #~ "clone WebSiteClone WebSite\n" #~ "colocation WebSite-with-WebFS inf: WebSiteClone WebFSClone\n" #~ "colocation fs_on_drbd inf: WebFSClone WebDataClone:Master\n" #~ "colocation website-with-ip inf: WebSiteClone WebIP\n" #~ "order WebFS-after-WebData inf: WebDataClone:promote WebFSClone:start\n" #~ "order WebSite-after-WebFS inf: WebFSClone WebSiteClone\n" #~ "order apache-after-ip inf: WebIP WebSiteClone\n" #~ "property $id=\"cib-bootstrap-options\" \\\n" #~ "        dc-version=\"1.1.5-bdd89e69ba545404d02445be1f3d72e6a203ba2f\" \\\n" #~ "        cluster-infrastructure=\"openais\" \\\n" #~ "        expected-quorum-votes=\"2\" \\\n" #~ "        stonith-enabled=\"true\" \\\n" #~ "        no-quorum-policy=\"ignore\"\n" #~ "rsc_defaults $id=\"rsc-options\" \\\n" #~ "        resource-stickiness=\"100\"\n" #~ msgid "" #~ "\n" #~ "node pcmk-1\n" #~ "node pcmk-2\n" #~ msgstr "" #~ "\n" #~ "node pcmk-1\n" #~ "node pcmk-2\n" #~ msgid "" #~ "\n" #~ "property $id=\"cib-bootstrap-options\" \\\n" #~ "        dc-version=\"1.1.5-bdd89e69ba545404d02445be1f3d72e6a203ba2f\" \\\n" #~ "        cluster-infrastructure=\"openais\" \\\n" #~ "        expected-quorum-votes=\"2\" \\\n" #~ "        stonith-enabled=\"true\" \\\n" #~ "        no-quorum-policy=\"ignore\"\n" #~ msgstr "" #~ "\n" #~ "property $id=\"cib-bootstrap-options\" \\\n" #~ "        dc-version=\"1.1.5-bdd89e69ba545404d02445be1f3d72e6a203ba2f\" \\\n" #~ "        cluster-infrastructure=\"openais\" \\\n" #~ "        expected-quorum-votes=\"2\" \\\n" #~ "        stonith-enabled=\"true\" \\\n" #~ "        no-quorum-policy=\"ignore\"\n" #~ msgid "" #~ "\n" #~ "rsc_defaults $id=\"rsc-options\" \\\n" #~ "        resource-stickiness=\"100\"\n" #~ msgstr "" #~ "\n" #~ "rsc_defaults $id=\"rsc-options\" \\\n" #~ "        resource-stickiness=\"100\"\n" #~ msgid "TODO: Add text here" #~ msgstr "TODO: Adaugă text aici" #~ msgid "" #~ "\n" #~ "primitive ipmi-fencing stonith::fence_ipmilan \\\n" #~ "        params pcmk_host_list=\"pcmk-1 pcmk-2\" ipaddr=10.0.0.1 login=testuser passwd=abc123 \\\n" #~ "        op monitor interval=\"60s\"\n" #~ "clone Fencing rsa-fencing\n" #~ msgstr "" #~ "\n" #~ "primitive ipmi-fencing stonith::fence_ipmilan \\\n" #~ "        params pcmk_host_list=\"pcmk-1 pcmk-2\" ipaddr=10.0.0.1 login=testuser passwd=abc123 \\\n" #~ "        op monitor interval=\"60s\"\n" #~ "clone Fencing rsa-fencing\n" #~ msgid "" #~ "\n" #~ "primitive ClusterIP ocf:heartbeat:IPaddr2 \\\n" #~ "        params ip=\"192.168.122.101\" cidr_netmask=\"32\" clusterip_hash=\"sourceip\" \\\n" #~ "        op monitor interval=\"30s\"\n" #~ "clone WebIP ClusterIP  \n" #~ "        meta globally-unique=\"true\" clone-max=\"2\" clone-node-max=\"2\"\n" #~ msgstr "" #~ "\n" #~ "primitive ClusterIP ocf:heartbeat:IPaddr2 \\\n" #~ "        params ip=\"192.168.122.101\" cidr_netmask=\"32\" clusterip_hash=\"sourceip\" \\\n" #~ "        op monitor interval=\"30s\"\n" #~ "clone WebIP ClusterIP  \n" #~ "        meta globally-unique=\"true\" clone-max=\"2\" clone-node-max=\"2\"\n" #~ msgid "" #~ "\n" #~ "primitive WebData ocf:linbit:drbd \\\n" #~ "        params drbd_resource=\"wwwdata\" \\\n" #~ "        op monitor interval=\"60s\"\n" #~ "ms WebDataClone WebData \\\n" #~ "        meta master-max=\"2\" master-node-max=\"1\" clone-max=\"2\" clone-node-max=\"1\" notify=\"true\"\n" #~ msgstr "" #~ "\n" #~ "primitive WebData ocf:linbit:drbd \\\n" #~ "        params drbd_resource=\"wwwdata\" \\\n" #~ "        op monitor interval=\"60s\"\n" #~ "ms WebDataClone WebData \\\n" #~ "        meta master-max=\"2\" master-node-max=\"1\" clone-max=\"2\" clone-node-max=\"1\" notify=\"true\"\n" #~ msgid "" #~ "\n" #~ "primitive WebFS ocf:heartbeat:Filesystem \\\n" #~ "        params device=\"/dev/drbd/by-res/wwwdata\" directory=\"/var/www/html\" fstype=\"gfs2\"\n" #~ "clone WebFSClone WebFS\n" #~ "colocation WebFS-with-gfs-control inf: WebFSClone gfs-clone\n" #~ "colocation fs_on_drbd inf: WebFSClone WebDataClone:Master\n" #~ "order WebFS-after-WebData inf: WebDataClone:promote WebFSClone:start\n" #~ "order start-WebFS-after-gfs-control inf: gfs-clone WebFSClone\n" #~ msgstr "" #~ "\n" #~ "primitive WebFS ocf:heartbeat:Filesystem \\\n" #~ "        params device=\"/dev/drbd/by-res/wwwdata\" directory=\"/var/www/html\" fstype=\"gfs2\"\n" #~ "clone WebFSClone WebFS\n" #~ "colocation WebFS-with-gfs-control inf: WebFSClone gfs-clone\n" #~ "colocation fs_on_drbd inf: WebFSClone WebDataClone:Master\n" #~ "order WebFS-after-WebData inf: WebDataClone:promote WebFSClone:start\n" #~ "order start-WebFS-after-gfs-control inf: gfs-clone WebFSClone\n" #~ msgid "" #~ "\n" #~ "primitive WebSite ocf:heartbeat:apache \\\n" #~ "        params configfile=\"/etc/httpd/conf/httpd.conf\" \\\n" #~ "        op monitor interval=\"1min\"\n" #~ "clone WebSiteClone WebSite\n" #~ "colocation WebSite-with-WebFS inf: WebSiteClone WebFSClone\n" #~ "colocation website-with-ip inf: WebSiteClone WebIP\n" #~ "order apache-after-ip inf: WebIP WebSiteClone\n" #~ "order WebSite-after-WebFS inf: WebFSClone WebSiteClone\n" #~ msgstr "" #~ "\n" #~ "primitive WebSite ocf:heartbeat:apache \\\n" #~ "        params configfile=\"/etc/httpd/conf/httpd.conf\" \\\n" #~ "        op monitor interval=\"1min\"\n" #~ "clone WebSiteClone WebSite\n" #~ "colocation WebSite-with-WebFS inf: WebSiteClone WebFSClone\n" #~ "colocation website-with-ip inf: WebSiteClone WebIP\n" #~ "order apache-after-ip inf: WebIP WebSiteClone\n" #~ "order WebSite-after-WebFS inf: WebFSClone WebSiteClone\n" pacemaker-master/doc/Clusters_from_Scratch/ro-RO/Ap-Corosync-Conf.po000066400000000000000000000132761217637305600257030ustar00rootroot00000000000000# # AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: Clusters from Scratch 1.1\n" "POT-Creation-Date: 2012-10-17T05:19:03\n" "PO-Revision-Date: 2011-11-20 00:27+0200\n" "Last-Translator: Dan Frîncu \n" "Language-Team: None\n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: application/x-publican; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. Tag: title #, no-c-format msgid "Sample Corosync Configuration" msgstr "Exemplu de Configurație al Corosync" #. Tag: title #, fuzzy, no-c-format msgid "Sample corosync.conf for two-node cluster using a node list." msgstr "Exemplu de corosync.conf pentru un cluster cu două noduri" #. Tag: literallayout #, no-c-format msgid "" "# Please read the corosync.conf.5 manual page\n" "totem {\n" "version: 2\n" "secauth: off\n" "cluster_name: mycluster\n" "transport: udpu\n" "}\n" "\n" "nodelist {\n" " node {\n" " ring0_addr: pcmk-1\n" " nodeid: 1\n" " }\n" " node {\n" " ring0_addr: pcmk-2\n" " nodeid: 2\n" " }\n" "}\n" "\n" "quorum {\n" " provider: corosync_votequorum\n" "}\n" "\n" "logging {\n" " to_syslog: yes\n" "}" msgstr "" #~ msgid "" #~ "\n" #~ "\t\n" #~ "# Please read the Corosync.conf.5 manual page\n" #~ "compatibility: whitetank\n" #~ "\n" #~ "totem {\n" #~ "        version: 2\n" #~ "\n" #~ "        # How long before declaring a token lost (ms)\n" #~ "        token:          5000\n" #~ "\n" #~ "        # How many token retransmits before forming a new configuration\n" #~ "        token_retransmits_before_loss_const: 10\n" #~ "\n" #~ "        # How long to wait for join messages in the membership protocol (ms)\n" #~ "        join:           1000\n" #~ "\n" #~ "        # How long to wait for consensus to be achieved before starting a new\n" #~ "        # round of membership configuration (ms)\n" #~ "        consensus:      6000\n" #~ "\n" #~ "        # Turn off the virtual synchrony filter\n" #~ "        vsftype:        none\n" #~ "\n" #~ "        # Number of messages that may be sent by one processor on receipt of the token\n" #~ "        max_messages:   20\n" #~ "\n" #~ "        # Stagger sending the node join messages by 1..send_join ms\n" #~ "        send_join: 45\n" #~ "\n" #~ "        # Limit generated nodeids to 31-bits (positive signed integers)\n" #~ "        clear_node_high_bit: yes\n" #~ "\n" #~ "        # Disable encryption\n" #~ "        secauth:        off\n" #~ "\n" #~ "        # How many threads to use for encryption/decryption\n" #~ "        threads:           0\n" #~ "\n" #~ "        # Optionally assign a fixed node id (integer)\n" #~ "        # nodeid:         1234\n" #~ "\n" #~ "        interface {\n" #~ "                ringnumber: 0\n" #~ "\n" #~ "                # The following values need to be set based on your environment\n" #~ "                bindnetaddr: 192.168.122.0\n" #~ "                mcastaddr: 226.94.1.1\n" #~ "                mcastport: 4000\n" #~ "        }\n" #~ "}\n" #~ "\n" #~ "logging {\n" #~ "        debug: off\n" #~ "        fileline: off\n" #~ "        to_syslog: yes\n" #~ "        to_stderr: off\n" #~ "        syslog_facility: daemon\n" #~ "        timestamp: on\n" #~ "}\n" #~ "\n" #~ "amf {\n" #~ "        mode: disabled\n" #~ "}\n" #~ "\t\n" #~ " " #~ msgstr "" #~ "\n" #~ "\t\n" #~ "# Please read the Corosync.conf.5 manual page\n" #~ "compatibility: whitetank\n" #~ "\n" #~ "totem {\n" #~ "        version: 2\n" #~ "\n" #~ "        # How long before declaring a token lost (ms)\n" #~ "        token:          5000\n" #~ "\n" #~ "        # How many token retransmits before forming a new configuration\n" #~ "        token_retransmits_before_loss_const: 10\n" #~ "\n" #~ "        # How long to wait for join messages in the membership protocol (ms)\n" #~ "        join:           1000\n" #~ "\n" #~ "        # How long to wait for consensus to be achieved before starting a new\n" #~ "        # round of membership configuration (ms)\n" #~ "        consensus:      6000\n" #~ "\n" #~ "        # Turn off the virtual synchrony filter\n" #~ "        vsftype:        none\n" #~ "\n" #~ "        # Number of messages that may be sent by one processor on receipt of the token\n" #~ "        max_messages:   20\n" #~ "\n" #~ "        # Stagger sending the node join messages by 1..send_join ms\n" #~ "        send_join: 45\n" #~ "\n" #~ "        # Limit generated nodeids to 31-bits (positive signed integers)\n" #~ "        clear_node_high_bit: yes\n" #~ "\n" #~ "        # Disable encryption\n" #~ "        secauth:        off\n" #~ "\n" #~ "        # How many threads to use for encryption/decryption\n" #~ "        threads:           0\n" #~ "\n" #~ "        # Optionally assign a fixed node id (integer)\n" #~ "        # nodeid:         1234\n" #~ "\n" #~ "        interface {\n" #~ "                ringnumber: 0\n" #~ "\n" #~ "                # The following values need to be set based on your environment\n" #~ "                bindnetaddr: 192.168.122.0\n" #~ "                mcastaddr: 226.94.1.1\n" #~ "                mcastport: 4000\n" #~ "        }\n" #~ "}\n" #~ "\n" #~ "logging {\n" #~ "        debug: off\n" #~ "        fileline: off\n" #~ "        to_syslog: yes\n" #~ "        to_stderr: off\n" #~ "        syslog_facility: daemon\n" #~ "        timestamp: on\n" #~ "}\n" #~ "\n" #~ "amf {\n" #~ "        mode: disabled\n" #~ "}\n" #~ "\t\n" #~ " " pacemaker-master/doc/Clusters_from_Scratch/ro-RO/Ap-Reading.po000066400000000000000000000040721217637305600245640ustar00rootroot00000000000000# # AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: Clusters from Scratch 1.1\n" "POT-Creation-Date: 2012-10-17T05:19:03\n" "PO-Revision-Date: 2011-11-20 10:41+0200\n" "Last-Translator: Dan Frîncu \n" "Language-Team: None\n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: application/x-publican; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. Tag: title #, no-c-format msgid "Further Reading" msgstr "Documentație Suplimentară" #. Tag: para #, fuzzy, no-c-format msgid "Project Website http://www.clusterlabs.org" msgstr "http://www.clusterlabs.org" #. Tag: para #, fuzzy, no-c-format msgid "Cluster Commands A comprehensive guide to cluster commands has been written by SuSE and can be found at: http://www.suse.com/documentation/sle_ha/book_sleha/?page=/documentation/sle_ha/book_sleha/data/book_sleha.html" msgstr "http://www.novell.com/documentation/sles11/book_sleha/index.html?page=/documentation/sles11/book_sleha/data/book_sleha.html" #. Tag: para #, fuzzy, no-c-format msgid "Corosync http://www.corosync.org" msgstr "http://www.corosync.org" #~ msgid "Project Website" #~ msgstr "Site-ul Proiectului" #~ msgid "Cluster Commands" #~ msgstr "Comenzile Clusterului" #~ msgid "A comprehensive guide to cluster commands has been written by Novell and can be found at:" #~ msgstr "Un ghid comprehensiv pentru comenzile clusterului a fost scris de către Novell și poate fi găsit la:" #~ msgid "Corosync" #~ msgstr "Corosync" pacemaker-master/doc/Clusters_from_Scratch/ro-RO/Author_Group.po000066400000000000000000000021561217637305600252740ustar00rootroot00000000000000# # AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: Clusters from Scratch 1.1\n" "POT-Creation-Date: 2012-10-17T05:19:03\n" "PO-Revision-Date: 2011-11-20 10:53+0200\n" "Last-Translator: Dan Frîncu \n" "Language-Team: None\n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: application/x-publican; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. Tag: firstname #, no-c-format msgid "Andrew" msgstr "Andrew" #. Tag: surname #, no-c-format msgid "Beekhof" msgstr "Beekhof" #. Tag: orgname #, no-c-format msgid "Red Hat" msgstr "Red Hat" #. Tag: contrib #, no-c-format msgid "Primary author" msgstr "Autor principal" #. Tag: firstname #, no-c-format msgid "Raoul" msgstr "Raoul" #. Tag: surname #, no-c-format msgid "Scarazzini" msgstr "Scarazzini" #. Tag: contrib #, no-c-format msgid "Italian translation" msgstr "Traducerea în limba italiană" #. Tag: firstname #, no-c-format msgid "Dan" msgstr "Dan" #. Tag: surname #, no-c-format msgid "Frîncu" msgstr "Frîncu" #. Tag: contrib #, no-c-format msgid "Romanian translation" msgstr "Traducerea în limba română" pacemaker-master/doc/Clusters_from_Scratch/ro-RO/Book_Info.po000066400000000000000000000053441217637305600245250ustar00rootroot00000000000000# # AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: Clusters from Scratch 1.1\n" "POT-Creation-Date: 2012-10-17T05:19:03\n" "PO-Revision-Date: 2011-11-21 23:38+0200\n" "Last-Translator: Dan Frîncu \n" "Language-Team: None\n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: application/x-publican; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. Tag: title #, no-c-format msgid "Clusters from Scratch" msgstr "Clusters from Scratch" #. Tag: subtitle #, no-c-format msgid "Creating Active/Passive and Active/Active Clusters on Fedora" msgstr "Crearea de Clustere Active/Pasive și Active/Active pe Fedora" #. Tag: productname #, no-c-format msgid "Pacemaker" msgstr "Pacemaker" #. Tag: para #, no-c-format msgid "The purpose of this document is to provide a start-to-finish guide to building an example active/passive cluster with Pacemaker and show how it can be converted to an active/active one." msgstr "Scopul acestui document este de a furniza un ghid de la început-la-sfârșit despre cum să construiți un exemplu de cluster activ/pasiv cu Pacemaker și de a arăta cum poate fi convertit la unul de tip activ/activ." #. Tag: para #, no-c-format msgid "The example cluster will use:" msgstr "Clusterul din exemplu va folosi: " #. Tag: para #, no-c-format msgid "&DISTRO; &DISTRO_VERSION; as the host operating system" msgstr "&DISTRO; &DISTRO_VERSION; ca sistem de operare gazdă" #. Tag: para #, no-c-format msgid "Corosync to provide messaging and membership services," msgstr "Corosync pentru a furniza servicii de mesagerie și apartenență," #. Tag: para #, no-c-format msgid "Pacemaker to perform resource management," msgstr "Pacemaker pentru a efectua gestiunea resurselor," #. Tag: para #, no-c-format msgid "DRBD as a cost-effective alternative to shared storage," msgstr "DRBD ca o alternativă eficientă ca și cost pentru spațiu de stocare partajat," #. Tag: para #, no-c-format msgid "GFS2 as the cluster filesystem (in active/active mode)" msgstr "GFS2 ca și sistem de fișiere de cluster (în mod activ/activ)" #. Tag: para #, no-c-format msgid "Given the graphical nature of the Fedora install process, a number of screenshots are included. However the guide is primarily composed of commands, the reasons for executing them and their expected outputs." msgstr "Dată fiind natura grafică a procesului de instalare al Fedora, un număr de capturi de ecran sunt incluse. Însă ghidul este compus în mod primar din comenzi, motivele pentru care sunt executate și rezultatele de ieșire așteptate ale acestora." #~ msgid "The crm shell for displaying the configuration and making changes" #~ msgstr "Shell-ul crm pentru vizualizarea configurației și pentru realizarea de modificări" pacemaker-master/doc/Clusters_from_Scratch/ro-RO/Ch-Active-Active.po000066400000000000000000003017751217637305600256430ustar00rootroot00000000000000# # AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: Clusters from Scratch 1.1\n" "POT-Creation-Date: 2012-10-17T05:19:03\n" "PO-Revision-Date: 2011-11-22 10:42+0200\n" "Last-Translator: Dan Frîncu \n" "Language-Team: None\n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: application/x-publican; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. Tag: title #, no-c-format msgid "Conversion to Active/Active" msgstr "Conversia la Activ/Activ" #. Tag: title #, no-c-format msgid "Requirements" msgstr "Cerințe" #. Tag: para #, no-c-format msgid "The primary requirement for an Active/Active cluster is that the data required for your services is available, simultaneously, on both machines. Pacemaker makes no requirement on how this is achieved, you could use a SAN if you had one available, however since DRBD supports multiple Primaries, we can also use that." msgstr "Cerința primară pentru un cluster Activ/Activ este ca datele necesare pentru serviciile voastre să fie disponibile, în mod simultan, pe ambele mașini. Pacemaker nu face nici o cerință asupra modului în care este atins acest scop, ați putea folosi un SAN dacă ați fi avut unul disponibil, însă din moment ce DRBD suportă noduri multiple Primare, putem să le folosim pe acestea de asemenea." #. Tag: para #, fuzzy, no-c-format msgid "The only hitch is that we need to use a cluster-aware filesystem. The one we used earlier with DRBD, ext4, is not one of those. Both OCFS2 and GFS2 are supported, however here we will use GFS2 which comes with Fedora 17." msgstr "Singura piedică este că avem nevoie de un sistem de fișiere conștient de cluster. Cel folosit anterior cu DRBD, ext4, nu este unul dintre acelea. Atât OCFS2 cât și GFS2 sunt suportate, însă aici vom folosi GFS2 care vine împreună cu &DISTRO; &DISTRO_VERSION;." #. Tag: title #, no-c-format msgid "Installing the required Software" msgstr "Instalarea Soft-ului necesar" #. Tag: programlisting #, no-c-format msgid "# yum install -y gfs2-utils dlm kernel-modules-extra" msgstr "" #. Tag: literallayout #, no-c-format msgid "" "Loaded plugins: langpacks, presto, refresh-packagekit\n" "Resolving Dependencies\n" "--> Running transaction check\n" "---> Package dlm.x86_64 0:3.99.4-1.fc17 will be installed\n" "---> Package gfs2-utils.x86_64 0:3.1.4-3.fc17 will be installed\n" "---> Package kernel-modules-extra.x86_64 0:3.4.4-3.fc17 will be installed\n" "--> Finished Dependency Resolution\n" "\n" "Dependencies Resolved\n" "\n" "================================================================================\n" " Package Arch Version Repository Size\n" "================================================================================\n" "Installing:\n" " dlm x86_64 3.99.4-1.fc17 updates 83 k\n" " gfs2-utils x86_64 3.1.4-3.fc17 fedora 214 k\n" " kernel-modules-extra x86_64 3.4.4-3.fc17 updates 1.7 M\n" "\n" "Transaction Summary\n" "================================================================================\n" "Install 3 Packages\n" "\n" "Total download size: 1.9 M\n" "Installed size: 7.7 M\n" "Downloading Packages:\n" "(1/3): dlm-3.99.4-1.fc17.x86_64.rpm | 83 kB 00:00\n" "(2/3): gfs2-utils-3.1.4-3.fc17.x86_64.rpm | 214 kB 00:00\n" "(3/3): kernel-modules-extra-3.4.4-3.fc17.x86_64.rpm | 1.7 MB 00:01\n" "--------------------------------------------------------------------------------\n" "Total 615 kB/s | 1.9 MB 00:03\n" "Running Transaction Check\n" "Running Transaction Test\n" "Transaction Test Succeeded\n" "Running Transaction\n" " Installing : kernel-modules-extra-3.4.4-3.fc17.x86_64 1/3\n" " Installing : gfs2-utils-3.1.4-3.fc17.x86_64 2/3\n" " Installing : dlm-3.99.4-1.fc17.x86_64 3/3\n" " Verifying : dlm-3.99.4-1.fc17.x86_64 1/3\n" " Verifying : gfs2-utils-3.1.4-3.fc17.x86_64 2/3\n" " Verifying : kernel-modules-extra-3.4.4-3.fc17.x86_64 3/3\n" "\n" "Installed:\n" " dlm.x86_64 0:3.99.4-1.fc17\n" " gfs2-utils.x86_64 0:3.1.4-3.fc17\n" " kernel-modules-extra.x86_64 0:3.4.4-3.fc17\n" "\n" "Complete!" msgstr "" #. Tag: title #, no-c-format msgid "Create a GFS2 Filesystem" msgstr "Creați un Sistem de Fișiere GFS2" #. Tag: title #, no-c-format msgid "Preparation" msgstr "Pregătire" #. Tag: para #, no-c-format msgid "Before we do anything to the existing partition, we need to make sure it is unmounted. We do this by telling the cluster to stop the WebFS resource. This will ensure that other resources (in our case, Apache) using WebFS are not only stopped, but stopped in the correct order." msgstr "Înainte de a face orice partiției existente, trebuie să ne asigurăm că este nemontată. Realizăm acest lucru spunând clusterului să oprească resursa WebFS. Acest lucru va asigura că alte resurse (în cazul nostru, Apache) care folosesc WebFS nu sunt doar oprite, ci sunt oprite în ordinea corectă." #. Tag: programlisting #, no-c-format msgid "" "# pcs resource stop WebFS\n" "# pcs resource\n" " ClusterIP (ocf::heartbeat:IPaddr2) Started\n" " WebSite (ocf::heartbeat:apache) Stopped\n" " Master/Slave Set: WebDataClone [WebData]\n" " Masters: [ pcmk-2 ]\n" " Slaves: [ pcmk-1 ]\n" " WebFS (ocf::heartbeat:Filesystem) Stopped" msgstr "" #. Tag: para #, no-c-format msgid "Note that both Apache and WebFS have been stopped." msgstr "Luați aminte că atât Apache cât și WebFS au fost oprite." #. Tag: title #, no-c-format msgid "Create and Populate an GFS2 Partition" msgstr "Crearea și Popularea unei Partiții GFS2" #. Tag: para #, no-c-format msgid "Now that the cluster stack and integration pieces are running smoothly, we can create an GFS2 partition." msgstr "Acum că stiva de cluster și componentele de integrare rulează fără piedici, putem crea o partiție GFS2." #. Tag: para #, no-c-format msgid "This will erase all previous content stored on the DRBD device. Ensure you have a copy of any important data." msgstr "Această acțiune va șterge tot conținutul stocat anterior pe dispozitivul DRBD. Asigurați-vă că aveți o copie a oricăror date importante." #. Tag: para #, no-c-format msgid "We need to specify a number of additional parameters when creating a GFS2 partition." msgstr "Trebuie să specificăm un număr de parametri adiționali când creem o partiție GFS2." #. Tag: para #, no-c-format msgid "First we must use the -p option to specify that we want to use the the Kernel’s DLM. Next we use -j to indicate that it should reserve enough space for two journals (one per node accessing the filesystem)." msgstr "Întâi trebuie să folosim opțiunea -p pentru a specifica faptul că vrem să folosim DLM-ul Kernel-ului. În continuare folosim -j pentru a indica faptul că trebuie să rezerve destul spațiu pentru două jurnale (unul pentru fiecare nod care accesează sistemul de fișiere)." #. Tag: para #, no-c-format msgid "Lastly, we use -t to specify the lock table name. The format for this field is clustername:fsname. For the fsname, we need to use the same value as specified in corosync.conf for cluster_name. If you setup corosync with the same cluster name we used in this tutorial, cluster name will be mycluster. If you are unsure what your cluster name is, open up /etc/corosync/corosync.conf, or execute the command pcs cluster corosync pcmk-1 to view the corosync config. The cluster name will be in the totem block." msgstr "" #. Tag: para #, no-c-format msgid "We must run the next command on whichever node last had /dev/drbd mounted. Otherwise you will receive the message:" msgstr "" #. Tag: screen #, no-c-format msgid "/dev/drbd1: Read-only file system" msgstr "" #. Tag: programlisting #, fuzzy, no-c-format msgid "" "# ssh pcmk-2 -- mkfs.gfs2 -p lock_dlm -j 2 -t mycluster:web /dev/drbd1\n" "This will destroy any data on /dev/drbd1.\n" "It appears to contain: Linux rev 1.0 ext4 filesystem data, UUID=dc45fff3-c47a-4db2-96f7-a8049a323fe4 (extents) (large files) (huge files)\n" "Are you sure you want to proceed? [y/n]y\n" "Device: /dev/drbd1\n" "Blocksize: 4096\n" "Device Size 0.97 GB (253935 blocks)\n" "Filesystem Size: 0.97 GB (253932 blocks)\n" "Journals: 2\n" "Resource Groups: 4\n" "Locking Protocol: \"lock_dlm\"\n" "Lock Table: \"mycluster\"\n" "UUID: ed293a02-9eee-3fa3-ed1c-435ef1fd0116" msgstr "" "\n" "[root@pcmk-1 ~]# mkfs.gfs2 -p lock_dlm -j 2 -t pcmk:web /dev/drbd1\n" "This will destroy any data on /dev/drbd1.\n" "It appears to contain: data\n" "\n" "Are you sure you want to proceed? [y/n] y\n" "\n" "Device:                    /dev/drbd1\n" "Blocksize:                 4096\n" "Device Size                1.00 GB (131072 blocks)\n" "Filesystem Size:           1.00 GB (131070 blocks)\n" "Journals:                  2\n" "Resource Groups:           2\n" "Locking Protocol:          \"lock_dlm\"\n" "Lock Table:                \"pcmk:web\"\n" "UUID:                      6B776F46-177B-BAF8-2C2B-292C0E078613\n" "\n" "[root@pcmk-1 ~]#\n" #. Tag: programlisting #, no-c-format msgid "" "# pcs cluster cib dlm_cfg\n" "# pcs -f dlm_cfg resource create dlm ocf:pacemaker:controld op monitor interval=60s\n" "# pcs -f dlm_cfg resource clone dlm clone-max=2 clone-node-max=1\n" "# pcs -f dlm_cfg resource show\n" " ClusterIP (ocf::heartbeat:IPaddr2) Started\n" " WebSite (ocf::heartbeat:apache) Stopped\n" " Master/Slave Set: WebDataClone [WebData]\n" " Masters: [ pcmk-2 ]\n" " Slaves: [ pcmk-1 ]\n" " WebFS (ocf::heartbeat:Filesystem) Stopped\n" " Clone Set: dlm-clone [dlm]\n" " Stopped: [ dlm:0 dlm:1 ]\n" "# pcs cluster push cib dlm_cfg\n" "CIB updated\n" "# pcs status\n" "\n" "Last updated: Fri Sep 14 12:54:50 2012\n" "Last change: Fri Sep 14 12:54:43 2012 via cibadmin on pcmk-1\n" "Stack: corosync\n" "Current DC: pcmk-1 (1) - partition with quorum\n" "Version: 1.1.8-1.el7-60a19ed12fdb4d5c6a6b6767f52e5391e447fec0\n" "2 Nodes configured, unknown expected votes\n" "7 Resources configured.\n" "\n" "Online: [ pcmk-1 pcmk-2 ]\n" "\n" "Full list of resources:\n" "\n" " ClusterIP (ocf::heartbeat:IPaddr2): Started pcmk-2\n" " WebSite (ocf::heartbeat:apache): Stopped\n" " Master/Slave Set: WebDataClone [WebData]\n" " Masters: [ pcmk-2 ]\n" " Slaves: [ pcmk-1 ]\n" " WebFS (ocf::heartbeat:Filesystem): Stopped\n" " Clone Set: dlm-clone [dlm]\n" " Started: [ pcmk-1 pcmk-2 ]" msgstr "" #. Tag: para #, no-c-format msgid "Then (re)populate the new filesystem with data (web pages). For now we’ll create another variation on our home page." msgstr "Apoi (re)populați noul sistem de fișiere cu date (pagini web). Momentan vom crea o nouă variație pe pagina noastră principală." #. Tag: programlisting #, fuzzy, no-c-format msgid "" "# mount /dev/drbd1 /mnt/\n" "# cat <<-END >/mnt/index.html\n" "<html>\n" "<body>My Test Site - GFS2</body>\n" "</html>\n" "END\n" "# umount /dev/drbd1\n" "# drbdadm verify wwwdata#" msgstr "" "\n" "[root@pcmk-1 ~]# mount /dev/drbd1 /mnt/\n" "[root@pcmk-1 ~]# cat <<-END >/mnt/index.html\n" "<html>\n" "<body>My Test Site - GFS2</body>\n" "</html>\n" "END\n" "[root@pcmk-1 ~]# umount /dev/drbd1\n" "[root@pcmk-1 ~]# drbdadm verify wwwdata\n" "[root@pcmk-1 ~]#\n" #. Tag: title #, no-c-format msgid "Reconfigure the Cluster for GFS2" msgstr "Reconfigurarea Clusterului pentru GFS2" #. Tag: para #, no-c-format msgid "With the WebFS resource stopped, lets update the configuration." msgstr "" #. Tag: programlisting #, no-c-format msgid "" "# pcs resource show WebFS\n" "Resource: WebFS\n" " device: /dev/drbd/by-res/wwwdata\n" " directory: /var/www/html\n" " fstype: ext4\n" " target-role: Stopped" msgstr "" #. Tag: para #, no-c-format msgid "The fstype option needs to be updated to gfs2 instead of ext4." msgstr "" #. Tag: programlisting #, no-c-format msgid "" "# pcs resource update WebFS fstype=gfs2\n" "# pcs resource show WebFS\n" "Resource: WebFS\n" " device: /dev/drbd/by-res/wwwdata\n" " directory: /var/www/html\n" " fstype: gfs2\n" " target-role: Stopped\n" "CIB updated" msgstr "" #. Tag: title #, no-c-format msgid "Reconfigure Pacemaker for Active/Active" msgstr "Reconfigurarea Pacemaker pentru Activ/Activ" #. Tag: para #, no-c-format msgid "Almost everything is in place. Recent versions of DRBD are capable of operating in Primary/Primary mode and the filesystem we’re using is cluster aware. All we need to do now is reconfigure the cluster to take advantage of this." msgstr "Aproape totul este la locul său. Versiunile recente de DRBD sunt capabile să opereze în mod Primar/Primar și sistemul de fișiere pe care îl folosim este conștient de cluster. Tot ce trebuie să facem aum este să reconfigurăm clusterul pentru a profita de acest lucru." #. Tag: para #, fuzzy, no-c-format msgid "This will involve a number of changes, so we’ll want work with a local cib file." msgstr "Acest lucru va implica un număr de modificări, așa că vom folosi din nou modul interactiv." #. Tag: programlisting #, no-c-format msgid "# pcs cluster cib active_cfg" msgstr "" #. Tag: para #, no-c-format msgid "There’s no point making the services active on both locations if we can’t reach them, so lets first clone the IP address. Cloned IPaddr2 resources use an iptables rule to ensure that each request only gets processed by one of the two clone instances. The additional meta options tell the cluster how many instances of the clone we want (one \"request bucket\" for each node) and that if all other nodes fail, then the remaining node should hold all of them. Otherwise the requests would be simply discarded." msgstr "Nu are nici un sens să facem serviciile active în ambele locații dacă nu putem ajunge la acestea, așa că hai să clonăm adresa IP. Resursele clonate IPaddr2 folosesc o regulă de iptables pentru a se asigura că fiecare cerere nu este procesată decât de una din cele două instanțe ale clonei. Meta opțiunile adiționale spun clusterului câte instanțe ale clonei dorim (câte o \"găleată de cereri\" pentru fiecare nod) și că dacă toate celelalte noduri eșuează, atunci nodul care rămâne ar trebui să le țină pe toate. Altfel cererile ar fi pur și simplu aruncate." #. Tag: screen #, fuzzy, no-c-format msgid "" "# pcs -f active_cfg resource clone ClusterIP \\\n" " globally-unique=true clone-max=2 clone-node-max=2" msgstr "" "\n" "[root@pcmk-1 ~]# configure clone WebIP ClusterIP  \\\n" "        meta globally-unique=\"true\" clone-max=\"2\" clone-node-max=\"2\"\n" " " #. Tag: para #, no-c-format msgid "Notice when the ClusterIP becomes a clone, the constraints referencing ClusterIP now reference the clone. This is done automatically by pcs." msgstr "" #. Tag: programlisting #, no-c-format msgid "" "# pcs -f active_cfg constraint\n" "Location Constraints:\n" "Ordering Constraints:\n" " start ClusterIP-clone then start WebSite\n" " WebFS then WebSite\n" " promote WebDataClone then start WebFS\n" "Colocation Constraints:\n" " WebSite with ClusterIP-clone\n" " WebFS with WebDataClone (with-rsc-role:Master)\n" " WebSite with WebFS" msgstr "" #. Tag: para #, no-c-format msgid "Now we must tell the ClusterIP how to decide which requests are processed by which hosts. To do this we must specify the clusterip_hash parameter." msgstr "Acum trebuie să spunem ClusterIP-ului cum să decidă care cereri sunt procesate de care gazde. Pentru a realiza acest lucru trebuie să specificăm parametrul clusterip_hash." #. Tag: programlisting #, no-c-format msgid "# pcs -f active_cfg resource update ClusterIP clusterip_hash=sourceip" msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "Next we need to convert the filesystem and Apache resources into clones." msgstr "În continuare trebuie să convertim resursele de sistem de fișiere și Apache în clone. Din nou, shell-ul va actualiza în mod automat orice restricții relevante." #. Tag: para #, no-c-format msgid "Notice how pcs automatically updates the relevant constraints again." msgstr "" #. Tag: programlisting #, no-c-format msgid "" "# pcs -f active_cfg resource clone WebFS\n" "# pcs -f active_cfg resource clone WebSite\n" "# pcs -f active_cfg constraint\n" "Location Constraints:\n" "Ordering Constraints:\n" " start ClusterIP-clone then start WebSite-clone\n" " WebFS-clone then WebSite-clone\n" " promote WebDataClone then start WebFS-clone\n" "Colocation Constraints:\n" " WebSite-clone with ClusterIP-clone\n" " WebFS-clone with WebDataClone (with-rsc-role:Master)\n" " WebSite-clone with WebFS-clone" msgstr "" #. Tag: para #, no-c-format msgid "The last step is to tell the cluster that it is now allowed to promote both instances to be Primary (aka. Master)." msgstr "Ultimul pas este acela de a spune clusterului că acum îi este permis să promoveze ambele instanțe să fie Primare (Master)." #. Tag: programlisting #, no-c-format msgid "# pcs -f active_cfg resource update WebDataClone master-max=2" msgstr "" #. Tag: para #, no-c-format msgid "Review the configuration before uploading it to the cluster, quitting the shell and watching the cluster’s response" msgstr "Revizuiți configurația înainte de a o încărca pe cluster, părăsind shell-ul și urmărind răspunsul clusterului" #. Tag: programlisting #, no-c-format msgid "" "# pcs cluster push cib active_cfg\n" "# pcs resource start WebFS" msgstr "" #. Tag: para #, no-c-format msgid "After all the processes are started the status should look similar to this." msgstr "" #. Tag: programlisting #, no-c-format msgid "" "# pcs resource\n" " Master/Slave Set: WebDataClone [WebData]\n" " Masters: [ pcmk-2 pcmk-1 ]\n" " Clone Set: dlm-clone [dlm]\n" " Started: [ pcmk-2 pcmk-1 ]\n" " Clone Set: ClusterIP-clone [ClusterIP] (unique)\n" " ClusterIP:0 (ocf::heartbeat:IPaddr2) Started\n" " ClusterIP:1 (ocf::heartbeat:IPaddr2) Started\n" " Clone Set: WebFS-clone [WebFS]\n" " Started: [ pcmk-1 pcmk-2 ]\n" " Clone Set: WebSite-clone [WebSite]\n" " Started: [ pcmk-1 pcmk-2 ]" msgstr "" #. Tag: title #, no-c-format msgid "Testing Recovery" msgstr "Testarea Recuperării" #. Tag: para #, no-c-format msgid "TODO: Put one node into standby to demonstrate failover" msgstr "TODO: Plasarea unui nod în standby pentru a demonstra failover-ul" #~ msgid "We'll also need to use CMAN for Cluster Membership and Quorum instead of our Corosync plugin." #~ msgstr "Va trebui de asemenea să folosim CMAN pentru Apartenența la Cluster și Quorum în locul plugin-ului nostru de Corosync." #~ msgid "Adding CMAN Support" #~ msgstr "Adăugarea de Suport pentru CMAN" #~ msgid "CMAN v3 is a Corosync plugin that monitors the names and number of active cluster nodes in order to deliver membership and quorum information to clients (such as the Pacemaker daemons)." #~ msgstr "CMAN v3 este un plugin al Corosync care monitorizează numele și numărul de noduri active din cluster pentru a livra informații de apartenență și quorum clienților (cum ar fi daemonii Pacemaker)." #~ msgid "In a traditional Corosync-Pacemaker cluster, a Pacemaker plugin is loaded to provide membership and quorum information. The motivation for wanting to use CMAN for this instead, is to ensure all elements of the cluster stack are making decisions based on the same membership and quorum data. A failure to do this can lead to what is called internal split-brain - a situation where different parts of the stack disagree about whether some nodes are alive or dead - which quickly leads to unnecssary down-time and/or data corruption. " #~ msgstr "Într-un cluster tradițional Corosync-Pacemaker, un plugin Pacemaker este încărcat pentru a furniza informații de apartenență și quorum. Motivația pentru a dori folosirea CMAN în schimb pentru acest lucru, este de a asigura că toate elementele stivei de cluster realizează decizii bazate pe aceleași date de apartenență și quorum. Un eșec de a realiza acest lucru poate duce la ceea ce este numit a fi un split-brain intern - o situație în care părți diferite ale stivei nu sunt de acord dacă unele noduri sunt funcționale sau nu - fapt care conduce rapid către o nefuncționare inutilă și/sau către coruperea datelor. " #~ msgid "In the case of GFS2, the key pieces are the dlm_controld and gfs_controld helpers which act as the glue between the filesystem and the cluster software. Supporting CMAN enables us to use the versions already being shipped by most distributions (since CMAN has been around longer than Pacemaker and is part of the Red Hat cluster stack)." #~ msgstr "În cazul GFS2, componentele cheie sunt ajutoarele dlm_controld și gfs_controld care se comportă ca o îmbinare între sistemul de fișiere și soft-ul de cluster. Suportarea CMAN ne permite să folosim versiunile deja expediate de către majoritatea distribuțiilor (din moment ce CMAN a fost prin preajmă mai mult timp decât Pacemaker și este totodată parte din stiva de cluster a Red Hat)." #~ msgid "Ensure Corosync and Pacemaker are stopped on all nodes before continuing" #~ msgstr "Asigurați-vă că Pacemaker și Corosync sunt oprite pe toate nodurile înainte de a continua" #~ msgid "Be sure to disable the Pacemaker plugin before continuing with this section. In most cases, this can be achieved by removing /etc/corosync/service.d/pcmk and stopping Corosync." #~ msgstr "Să vă asigurați că dezactivați plugin-ul de Pacemaker înainte de a continua cu această secțiune. În majoritatea cazurilor, acest lucru poate fi realizat prin înlăturarea /etc/corosync/service.d/pcmk și prin oprirea Corosync." #~ msgid "" #~ "\n" #~ "[root@pcmk-1 ~]# yum install -y cman gfs2-utils gfs2-cluster\n" #~ "Loaded plugins: auto-update-debuginfo\n" #~ "Setting up Install Process\n" #~ "Resolving Dependencies\n" #~ "--> Running transaction check\n" #~ "---> Package cman.x86_64 0:3.1.7-1.fc15 will be installed\n" #~ "--> Processing Dependency: modcluster >= 0.18.1-1 for package: cman-3.1.7-1.fc15.x86_64\n" #~ "--> Processing Dependency: fence-agents >= 3.1.5-1 for package: cman-3.1.7-1.fc15.x86_64\n" #~ "--> Processing Dependency: openais >= 1.1.4-1 for package: cman-3.1.7-1.fc15.x86_64\n" #~ "--> Processing Dependency: ricci >= 0.18.1-1 for package: cman-3.1.7-1.fc15.x86_64\n" #~ "--> Processing Dependency: libSaCkpt.so.3(OPENAIS_CKPT_B.01.01)(64bit) for package: cman-3.1.7-1.fc15.x86_64\n" #~ "--> Processing Dependency: libSaCkpt.so.3()(64bit) for package: cman-3.1.7-1.fc15.x86_64\n" #~ "---> Package gfs2-cluster.x86_64 0:3.1.1-2.fc15 will be installed\n" #~ "---> Package gfs2-utils.x86_64 0:3.1.1-2.fc15 will be installed\n" #~ "--> Running transaction check\n" #~ "---> Package fence-agents.x86_64 0:3.1.5-1.fc15 will be installed\n" #~ "--> Processing Dependency: /usr/bin/virsh for package: fence-agents-3.1.5-1.fc15.x86_64\n" #~ "--> Processing Dependency: net-snmp-utils for package: fence-agents-3.1.5-1.fc15.x86_64\n" #~ "--> Processing Dependency: sg3_utils for package: fence-agents-3.1.5-1.fc15.x86_64\n" #~ "--> Processing Dependency: perl(Net::Telnet) for package: fence-agents-3.1.5-1.fc15.x86_64\n" #~ "--> Processing Dependency: /usr/bin/ipmitool for package: fence-agents-3.1.5-1.fc15.x86_64\n" #~ "--> Processing Dependency: perl-Net-Telnet for package: fence-agents-3.1.5-1.fc15.x86_64\n" #~ "--> Processing Dependency: pexpect for package: fence-agents-3.1.5-1.fc15.x86_64\n" #~ "--> Processing Dependency: pyOpenSSL for package: fence-agents-3.1.5-1.fc15.x86_64\n" #~ "--> Processing Dependency: python-suds for package: fence-agents-3.1.5-1.fc15.x86_64\n" #~ "---> Package modcluster.x86_64 0:0.18.7-1.fc15 will be installed\n" #~ "--> Processing Dependency: oddjob for package: modcluster-0.18.7-1.fc15.x86_64\n" #~ "---> Package openais.x86_64 0:1.1.4-2.fc15 will be installed\n" #~ "---> Package openaislib.x86_64 0:1.1.4-2.fc15 will be installed\n" #~ "---> Package ricci.x86_64 0:0.18.7-1.fc15 will be installed\n" #~ "--> Processing Dependency: parted for package: ricci-0.18.7-1.fc15.x86_64\n" #~ "--> Processing Dependency: nss-tools for package: ricci-0.18.7-1.fc15.x86_64\n" #~ "--> Running transaction check\n" #~ "---> Package ipmitool.x86_64 0:1.8.11-6.fc15 will be installed\n" #~ "---> Package libvirt-client.x86_64 0:0.8.8-7.fc15 will be installed\n" #~ "--> Processing Dependency: libnetcf.so.1(NETCF_1.3.0)(64bit) for package: libvirt-client-0.8.8-7.fc15.x86_64\n" #~ "--> Processing Dependency: cyrus-sasl-md5 for package: libvirt-client-0.8.8-7.fc15.x86_64\n" #~ "--> Processing Dependency: gettext for package: libvirt-client-0.8.8-7.fc15.x86_64\n" #~ "--> Processing Dependency: nc for package: libvirt-client-0.8.8-7.fc15.x86_64\n" #~ "--> Processing Dependency: libnuma.so.1(libnuma_1.1)(64bit) for package: libvirt-client-0.8.8-7.fc15.x86_64\n" #~ "--> Processing Dependency: libnuma.so.1(libnuma_1.2)(64bit) for package: libvirt-client-0.8.8-7.fc15.x86_64\n" #~ "--> Processing Dependency: libnetcf.so.1(NETCF_1.2.0)(64bit) for package: libvirt-client-0.8.8-7.fc15.x86_64\n" #~ "--> Processing Dependency: gnutls-utils for package: libvirt-client-0.8.8-7.fc15.x86_64\n" #~ "--> Processing Dependency: libnetcf.so.1(NETCF_1.0.0)(64bit) for package: libvirt-client-0.8.8-7.fc15.x86_64\n" #~ "--> Processing Dependency: libxenstore.so.3.0()(64bit) for package: libvirt-client-0.8.8-7.fc15.x86_64\n" #~ "--> Processing Dependency: libyajl.so.1()(64bit) for package: libvirt-client-0.8.8-7.fc15.x86_64\n" #~ "--> Processing Dependency: libnl.so.1()(64bit) for package: libvirt-client-0.8.8-7.fc15.x86_64\n" #~ "--> Processing Dependency: libnuma.so.1()(64bit) for package: libvirt-client-0.8.8-7.fc15.x86_64\n" #~ "--> Processing Dependency: libaugeas.so.0()(64bit) for package: libvirt-client-0.8.8-7.fc15.x86_64\n" #~ "--> Processing Dependency: libnetcf.so.1()(64bit) for package: libvirt-client-0.8.8-7.fc15.x86_64\n" #~ "---> Package net-snmp-utils.x86_64 1:5.6.1-7.fc15 will be installed\n" #~ "---> Package nss-tools.x86_64 0:3.12.10-6.fc15 will be installed\n" #~ "---> Package oddjob.x86_64 0:0.31-2.fc15 will be installed\n" #~ "---> Package parted.x86_64 0:2.3-10.fc15 will be installed\n" #~ "---> Package perl-Net-Telnet.noarch 0:3.03-12.fc15 will be installed\n" #~ "---> Package pexpect.noarch 0:2.3-6.fc15 will be installed\n" #~ "---> Package pyOpenSSL.x86_64 0:0.10-3.fc15 will be installed\n" #~ "---> Package python-suds.noarch 0:0.3.9-3.fc15 will be installed\n" #~ "---> Package sg3_utils.x86_64 0:1.29-3.fc15 will be installed\n" #~ "--> Processing Dependency: sg3_utils-libs = 1.29-3.fc15 for package: sg3_utils-1.29-3.fc15.x86_64\n" #~ "--> Processing Dependency: libsgutils2.so.2()(64bit) for package: sg3_utils-1.29-3.fc15.x86_64\n" #~ "--> Running transaction check\n" #~ "---> Package augeas-libs.x86_64 0:0.9.0-1.fc15 will be installed\n" #~ "---> Package cyrus-sasl-md5.x86_64 0:2.1.23-18.fc15 will be installed\n" #~ "---> Package gettext.x86_64 0:0.18.1.1-7.fc15 will be installed\n" #~ "--> Processing Dependency: libgomp.so.1(GOMP_1.0)(64bit) for package: gettext-0.18.1.1-7.fc15.x86_64\n" #~ "--> Processing Dependency: libgettextlib-0.18.1.so()(64bit) for package: gettext-0.18.1.1-7.fc15.x86_64\n" #~ "--> Processing Dependency: libgettextsrc-0.18.1.so()(64bit) for package: gettext-0.18.1.1-7.fc15.x86_64\n" #~ "--> Processing Dependency: libgomp.so.1()(64bit) for package: gettext-0.18.1.1-7.fc15.x86_64\n" #~ "---> Package gnutls-utils.x86_64 0:2.10.5-1.fc15 will be installed\n" #~ "---> Package libnl.x86_64 0:1.1-14.fc15 will be installed\n" #~ "---> Package nc.x86_64 0:1.100-3.fc15 will be installed\n" #~ "--> Processing Dependency: libbsd.so.0(LIBBSD_0.0)(64bit) for package: nc-1.100-3.fc15.x86_64\n" #~ "--> Processing Dependency: libbsd.so.0(LIBBSD_0.2)(64bit) for package: nc-1.100-3.fc15.x86_64\n" #~ "--> Processing Dependency: libbsd.so.0()(64bit) for package: nc-1.100-3.fc15.x86_64\n" #~ "---> Package netcf-libs.x86_64 0:0.1.9-1.fc15 will be installed\n" #~ "---> Package numactl.x86_64 0:2.0.7-1.fc15 will be installed\n" #~ "---> Package sg3_utils-libs.x86_64 0:1.29-3.fc15 will be installed\n" #~ "---> Package xen-libs.x86_64 0:4.1.1-3.fc15 will be installed\n" #~ "--> Processing Dependency: xen-licenses for package: xen-libs-4.1.1-3.fc15.x86_64\n" #~ "---> Package yajl.x86_64 0:1.0.11-1.fc15 will be installed\n" #~ "--> Running transaction check\n" #~ "---> Package gettext-libs.x86_64 0:0.18.1.1-7.fc15 will be installed\n" #~ "---> Package libbsd.x86_64 0:0.2.0-4.fc15 will be installed\n" #~ "---> Package libgomp.x86_64 0:4.6.1-9.fc15 will be installed\n" #~ "---> Package xen-licenses.x86_64 0:4.1.1-3.fc15 will be installed\n" #~ "--> Finished Dependency Resolution\n" #~ "\n" #~ "Dependencies Resolved\n" #~ "\n" #~ "=============================================================================\n" #~ " Package Arch Version Repository Size\n" #~ "=============================================================================\n" #~ "Installing:\n" #~ " cman x86_64 3.1.7-1.fc15 updates 366 k\n" #~ " gfs2-cluster x86_64 3.1.1-2.fc15 fedora 69 k\n" #~ " gfs2-utils x86_64 3.1.1-2.fc15 fedora 222 k\n" #~ "Installing for dependencies:\n" #~ " augeas-libs x86_64 0.9.0-1.fc15 updates 311 k\n" #~ " cyrus-sasl-md5 x86_64 2.1.23-18.fc15 updates 46 k\n" #~ " fence-agents x86_64 3.1.5-1.fc15 updates 186 k\n" #~ " gettext x86_64 0.18.1.1-7.fc15 fedora 1.0 M\n" #~ " gettext-libs x86_64 0.18.1.1-7.fc15 fedora 610 k\n" #~ " gnutls-utils x86_64 2.10.5-1.fc15 fedora 101 k\n" #~ " ipmitool x86_64 1.8.11-6.fc15 fedora 273 k\n" #~ " libbsd x86_64 0.2.0-4.fc15 fedora 37 k\n" #~ " libgomp x86_64 4.6.1-9.fc15 updates 95 k\n" #~ " libnl x86_64 1.1-14.fc15 fedora 118 k\n" #~ " libvirt-client x86_64 0.8.8-7.fc15 updates 2.4 M\n" #~ " modcluster x86_64 0.18.7-1.fc15 fedora 187 k\n" #~ " nc x86_64 1.100-3.fc15 updates 24 k\n" #~ " net-snmp-utils x86_64 1:5.6.1-7.fc15 fedora 180 k\n" #~ " netcf-libs x86_64 0.1.9-1.fc15 updates 50 k\n" #~ " nss-tools x86_64 3.12.10-6.fc15 updates 723 k\n" #~ " numactl x86_64 2.0.7-1.fc15 updates 54 k\n" #~ " oddjob x86_64 0.31-2.fc15 fedora 61 k\n" #~ " openais x86_64 1.1.4-2.fc15 fedora 190 k\n" #~ " openaislib x86_64 1.1.4-2.fc15 fedora 88 k\n" #~ " parted x86_64 2.3-10.fc15 updates 618 k\n" #~ " perl-Net-Telnet noarch 3.03-12.fc15 fedora 55 k\n" #~ " pexpect noarch 2.3-6.fc15 fedora 141 k\n" #~ " pyOpenSSL x86_64 0.10-3.fc15 fedora 198 k\n" #~ " python-suds noarch 0.3.9-3.fc15 fedora 195 k\n" #~ " ricci x86_64 0.18.7-1.fc15 fedora 584 k\n" #~ " sg3_utils x86_64 1.29-3.fc15 fedora 465 k\n" #~ " sg3_utils-libs x86_64 1.29-3.fc15 fedora 54 k\n" #~ " xen-libs x86_64 4.1.1-3.fc15 updates 310 k\n" #~ " xen-licenses x86_64 4.1.1-3.fc15 updates 64 k\n" #~ " yajl x86_64 1.0.11-1.fc15 fedora 27 k\n" #~ "\n" #~ "Transaction Summary\n" #~ "=============================================================================\n" #~ "Install 34 Package(s)\n" #~ "\n" #~ "Total download size: 10 M\n" #~ "Installed size: 38 M\n" #~ "Downloading Packages:\n" #~ "(1/34): augeas-libs-0.9.0-1.fc15.x86_64.rpm | 311 kB 00:00 \n" #~ "(2/34): cman-3.1.7-1.fc15.x86_64.rpm | 366 kB 00:00 \n" #~ "(3/34): cyrus-sasl-md5-2.1.23-18.fc15.x86_64.rpm | 46 kB 00:00 \n" #~ "(4/34): fence-agents-3.1.5-1.fc15.x86_64.rpm | 186 kB 00:00 \n" #~ "(5/34): gettext-0.18.1.1-7.fc15.x86_64.rpm | 1.0 MB 00:01 \n" #~ "(6/34): gettext-libs-0.18.1.1-7.fc15.x86_64.rpm | 610 kB 00:00 \n" #~ "(7/34): gfs2-cluster-3.1.1-2.fc15.x86_64.rpm | 69 kB 00:00 \n" #~ "(8/34): gfs2-utils-3.1.1-2.fc15.x86_64.rpm | 222 kB 00:00 \n" #~ "(9/34): gnutls-utils-2.10.5-1.fc15.x86_64.rpm | 101 kB 00:00 \n" #~ "(10/34): ipmitool-1.8.11-6.fc15.x86_64.rpm | 273 kB 00:00 \n" #~ "(11/34): libbsd-0.2.0-4.fc15.x86_64.rpm | 37 kB 00:00 \n" #~ "(12/34): libgomp-4.6.1-9.fc15.x86_64.rpm | 95 kB 00:00 \n" #~ "(13/34): libnl-1.1-14.fc15.x86_64.rpm | 118 kB 00:00 \n" #~ "(14/34): libvirt-client-0.8.8-7.fc15.x86_64.rpm | 2.4 MB 00:01 \n" #~ "(15/34): modcluster-0.18.7-1.fc15.x86_64.rpm | 187 kB 00:00 \n" #~ "(16/34): nc-1.100-3.fc15.x86_64.rpm | 24 kB 00:00 \n" #~ "(17/34): net-snmp-utils-5.6.1-7.fc15.x86_64.rpm | 180 kB 00:00 \n" #~ "(18/34): netcf-libs-0.1.9-1.fc15.x86_64.rpm | 50 kB 00:00 \n" #~ "(19/34): nss-tools-3.12.10-6.fc15.x86_64.rpm | 723 kB 00:00 \n" #~ "(20/34): numactl-2.0.7-1.fc15.x86_64.rpm | 54 kB 00:00 \n" #~ "(21/34): oddjob-0.31-2.fc15.x86_64.rpm | 61 kB 00:00 \n" #~ "(22/34): openais-1.1.4-2.fc15.x86_64.rpm | 190 kB 00:00 \n" #~ "(23/34): openaislib-1.1.4-2.fc15.x86_64.rpm | 88 kB 00:00 \n" #~ "(24/34): parted-2.3-10.fc15.x86_64.rpm | 618 kB 00:00 \n" #~ "(25/34): perl-Net-Telnet-3.03-12.fc15.noarch.rpm | 55 kB 00:00 \n" #~ "(26/34): pexpect-2.3-6.fc15.noarch.rpm | 141 kB 00:00 \n" #~ "(27/34): pyOpenSSL-0.10-3.fc15.x86_64.rpm | 198 kB 00:00 \n" #~ "(28/34): python-suds-0.3.9-3.fc15.noarch.rpm | 195 kB 00:00 \n" #~ "(29/34): ricci-0.18.7-1.fc15.x86_64.rpm | 584 kB 00:00 \n" #~ "(30/34): sg3_utils-1.29-3.fc15.x86_64.rpm | 465 kB 00:00 \n" #~ "(31/34): sg3_utils-libs-1.29-3.fc15.x86_64.rpm | 54 kB 00:00 \n" #~ "(32/34): xen-libs-4.1.1-3.fc15.x86_64.rpm | 310 kB 00:00 \n" #~ "(33/34): xen-licenses-4.1.1-3.fc15.x86_64.rpm | 64 kB 00:00 \n" #~ "(34/34): yajl-1.0.11-1.fc15.x86_64.rpm | 27 kB 00:00 \n" #~ "-----------------------------------------------------------------------------\n" #~ "Total 803 kB/s | 10 MB 00:12 \n" #~ "Running rpm_check_debug\n" #~ "Running Transaction Test\n" #~ "Transaction Test Succeeded\n" #~ "Running Transaction\n" #~ " Installing : openais-1.1.4-2.fc15.x86_64 1/34 \n" #~ " Installing : openaislib-1.1.4-2.fc15.x86_64 2/34 \n" #~ " Installing : libnl-1.1-14.fc15.x86_64 3/34 \n" #~ " Installing : augeas-libs-0.9.0-1.fc15.x86_64 4/34 \n" #~ " Installing : oddjob-0.31-2.fc15.x86_64 5/34 \n" #~ " Installing : modcluster-0.18.7-1.fc15.x86_64 6/34 \n" #~ " Installing : netcf-libs-0.1.9-1.fc15.x86_64 7/34 \n" #~ " Installing : 1:net-snmp-utils-5.6.1-7.fc15.x86_64 8/34 \n" #~ " Installing : sg3_utils-libs-1.29-3.fc15.x86_64 9/34 \n" #~ " Installing : sg3_utils-1.29-3.fc15.x86_64 10/34 \n" #~ " Installing : libgomp-4.6.1-9.fc15.x86_64 11/34 \n" #~ " Installing : gnutls-utils-2.10.5-1.fc15.x86_64 12/34 \n" #~ " Installing : pyOpenSSL-0.10-3.fc15.x86_64 13/34 \n" #~ " Installing : parted-2.3-10.fc15.x86_64 14/34 \n" #~ " Installing : cyrus-sasl-md5-2.1.23-18.fc15.x86_64 15/34 \n" #~ " Installing : python-suds-0.3.9-3.fc15.noarch 16/34 \n" #~ " Installing : ipmitool-1.8.11-6.fc15.x86_64 17/34 \n" #~ " Installing : perl-Net-Telnet-3.03-12.fc15.noarch 18/34 \n" #~ " Installing : numactl-2.0.7-1.fc15.x86_64 19/34 \n" #~ " Installing : yajl-1.0.11-1.fc15.x86_64 20/34 \n" #~ " Installing : gettext-libs-0.18.1.1-7.fc15.x86_64 21/34 \n" #~ " Installing : gettext-0.18.1.1-7.fc15.x86_64 22/34 \n" #~ " Installing : libbsd-0.2.0-4.fc15.x86_64 23/34 \n" #~ " Installing : nc-1.100-3.fc15.x86_64 24/34 \n" #~ " Installing : xen-licenses-4.1.1-3.fc15.x86_64 25/34 \n" #~ " Installing : xen-libs-4.1.1-3.fc15.x86_64 26/34 \n" #~ " Installing : libvirt-client-0.8.8-7.fc15.x86_64 27/34 \n" #~ "\n" #~ "Note: This output shows SysV services only and does not include native\n" #~ " systemd services. SysV configuration data might be overridden by native\n" #~ " systemd configuration.\n" #~ "\n" #~ " Installing : nss-tools-3.12.10-6.fc15.x86_64 28/34 \n" #~ " Installing : ricci-0.18.7-1.fc15.x86_64 29/34 \n" #~ " Installing : pexpect-2.3-6.fc15.noarch 30/34 \n" #~ " Installing : fence-agents-3.1.5-1.fc15.x86_64 31/34 \n" #~ " Installing : cman-3.1.7-1.fc15.x86_64 32/34 \n" #~ " Installing : gfs2-cluster-3.1.1-2.fc15.x86_64 33/34 \n" #~ " Installing : gfs2-utils-3.1.1-2.fc15.x86_64 34/34 \n" #~ "\n" #~ "Installed:\n" #~ " cman.x86_64 0:3.1.7-1.fc15 gfs2-cluster.x86_64 0:3.1.1-2.fc15 \n" #~ " gfs2-utils.x86_64 0:3.1.1-2.fc15 \n" #~ "\n" #~ "Dependency Installed:\n" #~ " augeas-libs.x86_64 0:0.9.0-1.fc15 \n" #~ " cyrus-sasl-md5.x86_64 0:2.1.23-18.fc15 \n" #~ " fence-agents.x86_64 0:3.1.5-1.fc15 \n" #~ " gettext.x86_64 0:0.18.1.1-7.fc15 \n" #~ " gettext-libs.x86_64 0:0.18.1.1-7.fc15 \n" #~ " gnutls-utils.x86_64 0:2.10.5-1.fc15 \n" #~ " ipmitool.x86_64 0:1.8.11-6.fc15 \n" #~ " libbsd.x86_64 0:0.2.0-4.fc15 \n" #~ " libgomp.x86_64 0:4.6.1-9.fc15 \n" #~ " libnl.x86_64 0:1.1-14.fc15 \n" #~ " libvirt-client.x86_64 0:0.8.8-7.fc15 \n" #~ " modcluster.x86_64 0:0.18.7-1.fc15 \n" #~ " nc.x86_64 0:1.100-3.fc15 \n" #~ " net-snmp-utils.x86_64 1:5.6.1-7.fc15 \n" #~ " netcf-libs.x86_64 0:0.1.9-1.fc15 \n" #~ " nss-tools.x86_64 0:3.12.10-6.fc15 \n" #~ " numactl.x86_64 0:2.0.7-1.fc15 \n" #~ " oddjob.x86_64 0:0.31-2.fc15 \n" #~ " openais.x86_64 0:1.1.4-2.fc15 \n" #~ " openaislib.x86_64 0:1.1.4-2.fc15 \n" #~ " parted.x86_64 0:2.3-10.fc15 \n" #~ " perl-Net-Telnet.noarch 0:3.03-12.fc15 \n" #~ " pexpect.noarch 0:2.3-6.fc15 \n" #~ " pyOpenSSL.x86_64 0:0.10-3.fc15 \n" #~ " python-suds.noarch 0:0.3.9-3.fc15 \n" #~ " ricci.x86_64 0:0.18.7-1.fc15 \n" #~ " sg3_utils.x86_64 0:1.29-3.fc15 \n" #~ " sg3_utils-libs.x86_64 0:1.29-3.fc15 \n" #~ " xen-libs.x86_64 0:4.1.1-3.fc15 \n" #~ " xen-licenses.x86_64 0:4.1.1-3.fc15 \n" #~ " yajl.x86_64 0:1.0.11-1.fc15 \n" #~ "\n" #~ "Complete!\n" #~ "[root@pcmk-1 ~]# \n" #~ " " #~ msgstr "" #~ "\n" #~ "[root@pcmk-1 ~]# yum install -y cman gfs2-utils gfs2-cluster\n" #~ "Loaded plugins: auto-update-debuginfo\n" #~ "Setting up Install Process\n" #~ "Resolving Dependencies\n" #~ "--> Running transaction check\n" #~ "---> Package cman.x86_64 0:3.1.7-1.fc15 will be installed\n" #~ "--> Processing Dependency: modcluster >= 0.18.1-1 for package: cman-3.1.7-1.fc15.x86_64\n" #~ "--> Processing Dependency: fence-agents >= 3.1.5-1 for package: cman-3.1.7-1.fc15.x86_64\n" #~ "--> Processing Dependency: openais >= 1.1.4-1 for package: cman-3.1.7-1.fc15.x86_64\n" #~ "--> Processing Dependency: ricci >= 0.18.1-1 for package: cman-3.1.7-1.fc15.x86_64\n" #~ "--> Processing Dependency: libSaCkpt.so.3(OPENAIS_CKPT_B.01.01)(64bit) for package: cman-3.1.7-1.fc15.x86_64\n" #~ "--> Processing Dependency: libSaCkpt.so.3()(64bit) for package: cman-3.1.7-1.fc15.x86_64\n" #~ "---> Package gfs2-cluster.x86_64 0:3.1.1-2.fc15 will be installed\n" #~ "---> Package gfs2-utils.x86_64 0:3.1.1-2.fc15 will be installed\n" #~ "--> Running transaction check\n" #~ "---> Package fence-agents.x86_64 0:3.1.5-1.fc15 will be installed\n" #~ "--> Processing Dependency: /usr/bin/virsh for package: fence-agents-3.1.5-1.fc15.x86_64\n" #~ "--> Processing Dependency: net-snmp-utils for package: fence-agents-3.1.5-1.fc15.x86_64\n" #~ "--> Processing Dependency: sg3_utils for package: fence-agents-3.1.5-1.fc15.x86_64\n" #~ "--> Processing Dependency: perl(Net::Telnet) for package: fence-agents-3.1.5-1.fc15.x86_64\n" #~ "--> Processing Dependency: /usr/bin/ipmitool for package: fence-agents-3.1.5-1.fc15.x86_64\n" #~ "--> Processing Dependency: perl-Net-Telnet for package: fence-agents-3.1.5-1.fc15.x86_64\n" #~ "--> Processing Dependency: pexpect for package: fence-agents-3.1.5-1.fc15.x86_64\n" #~ "--> Processing Dependency: pyOpenSSL for package: fence-agents-3.1.5-1.fc15.x86_64\n" #~ "--> Processing Dependency: python-suds for package: fence-agents-3.1.5-1.fc15.x86_64\n" #~ "---> Package modcluster.x86_64 0:0.18.7-1.fc15 will be installed\n" #~ "--> Processing Dependency: oddjob for package: modcluster-0.18.7-1.fc15.x86_64\n" #~ "---> Package openais.x86_64 0:1.1.4-2.fc15 will be installed\n" #~ "---> Package openaislib.x86_64 0:1.1.4-2.fc15 will be installed\n" #~ "---> Package ricci.x86_64 0:0.18.7-1.fc15 will be installed\n" #~ "--> Processing Dependency: parted for package: ricci-0.18.7-1.fc15.x86_64\n" #~ "--> Processing Dependency: nss-tools for package: ricci-0.18.7-1.fc15.x86_64\n" #~ "--> Running transaction check\n" #~ "---> Package ipmitool.x86_64 0:1.8.11-6.fc15 will be installed\n" #~ "---> Package libvirt-client.x86_64 0:0.8.8-7.fc15 will be installed\n" #~ "--> Processing Dependency: libnetcf.so.1(NETCF_1.3.0)(64bit) for package: libvirt-client-0.8.8-7.fc15.x86_64\n" #~ "--> Processing Dependency: cyrus-sasl-md5 for package: libvirt-client-0.8.8-7.fc15.x86_64\n" #~ "--> Processing Dependency: gettext for package: libvirt-client-0.8.8-7.fc15.x86_64\n" #~ "--> Processing Dependency: nc for package: libvirt-client-0.8.8-7.fc15.x86_64\n" #~ "--> Processing Dependency: libnuma.so.1(libnuma_1.1)(64bit) for package: libvirt-client-0.8.8-7.fc15.x86_64\n" #~ "--> Processing Dependency: libnuma.so.1(libnuma_1.2)(64bit) for package: libvirt-client-0.8.8-7.fc15.x86_64\n" #~ "--> Processing Dependency: libnetcf.so.1(NETCF_1.2.0)(64bit) for package: libvirt-client-0.8.8-7.fc15.x86_64\n" #~ "--> Processing Dependency: gnutls-utils for package: libvirt-client-0.8.8-7.fc15.x86_64\n" #~ "--> Processing Dependency: libnetcf.so.1(NETCF_1.0.0)(64bit) for package: libvirt-client-0.8.8-7.fc15.x86_64\n" #~ "--> Processing Dependency: libxenstore.so.3.0()(64bit) for package: libvirt-client-0.8.8-7.fc15.x86_64\n" #~ "--> Processing Dependency: libyajl.so.1()(64bit) for package: libvirt-client-0.8.8-7.fc15.x86_64\n" #~ "--> Processing Dependency: libnl.so.1()(64bit) for package: libvirt-client-0.8.8-7.fc15.x86_64\n" #~ "--> Processing Dependency: libnuma.so.1()(64bit) for package: libvirt-client-0.8.8-7.fc15.x86_64\n" #~ "--> Processing Dependency: libaugeas.so.0()(64bit) for package: libvirt-client-0.8.8-7.fc15.x86_64\n" #~ "--> Processing Dependency: libnetcf.so.1()(64bit) for package: libvirt-client-0.8.8-7.fc15.x86_64\n" #~ "---> Package net-snmp-utils.x86_64 1:5.6.1-7.fc15 will be installed\n" #~ "---> Package nss-tools.x86_64 0:3.12.10-6.fc15 will be installed\n" #~ "---> Package oddjob.x86_64 0:0.31-2.fc15 will be installed\n" #~ "---> Package parted.x86_64 0:2.3-10.fc15 will be installed\n" #~ "---> Package perl-Net-Telnet.noarch 0:3.03-12.fc15 will be installed\n" #~ "---> Package pexpect.noarch 0:2.3-6.fc15 will be installed\n" #~ "---> Package pyOpenSSL.x86_64 0:0.10-3.fc15 will be installed\n" #~ "---> Package python-suds.noarch 0:0.3.9-3.fc15 will be installed\n" #~ "---> Package sg3_utils.x86_64 0:1.29-3.fc15 will be installed\n" #~ "--> Processing Dependency: sg3_utils-libs = 1.29-3.fc15 for package: sg3_utils-1.29-3.fc15.x86_64\n" #~ "--> Processing Dependency: libsgutils2.so.2()(64bit) for package: sg3_utils-1.29-3.fc15.x86_64\n" #~ "--> Running transaction check\n" #~ "---> Package augeas-libs.x86_64 0:0.9.0-1.fc15 will be installed\n" #~ "---> Package cyrus-sasl-md5.x86_64 0:2.1.23-18.fc15 will be installed\n" #~ "---> Package gettext.x86_64 0:0.18.1.1-7.fc15 will be installed\n" #~ "--> Processing Dependency: libgomp.so.1(GOMP_1.0)(64bit) for package: gettext-0.18.1.1-7.fc15.x86_64\n" #~ "--> Processing Dependency: libgettextlib-0.18.1.so()(64bit) for package: gettext-0.18.1.1-7.fc15.x86_64\n" #~ "--> Processing Dependency: libgettextsrc-0.18.1.so()(64bit) for package: gettext-0.18.1.1-7.fc15.x86_64\n" #~ "--> Processing Dependency: libgomp.so.1()(64bit) for package: gettext-0.18.1.1-7.fc15.x86_64\n" #~ "---> Package gnutls-utils.x86_64 0:2.10.5-1.fc15 will be installed\n" #~ "---> Package libnl.x86_64 0:1.1-14.fc15 will be installed\n" #~ "---> Package nc.x86_64 0:1.100-3.fc15 will be installed\n" #~ "--> Processing Dependency: libbsd.so.0(LIBBSD_0.0)(64bit) for package: nc-1.100-3.fc15.x86_64\n" #~ "--> Processing Dependency: libbsd.so.0(LIBBSD_0.2)(64bit) for package: nc-1.100-3.fc15.x86_64\n" #~ "--> Processing Dependency: libbsd.so.0()(64bit) for package: nc-1.100-3.fc15.x86_64\n" #~ "---> Package netcf-libs.x86_64 0:0.1.9-1.fc15 will be installed\n" #~ "---> Package numactl.x86_64 0:2.0.7-1.fc15 will be installed\n" #~ "---> Package sg3_utils-libs.x86_64 0:1.29-3.fc15 will be installed\n" #~ "---> Package xen-libs.x86_64 0:4.1.1-3.fc15 will be installed\n" #~ "--> Processing Dependency: xen-licenses for package: xen-libs-4.1.1-3.fc15.x86_64\n" #~ "---> Package yajl.x86_64 0:1.0.11-1.fc15 will be installed\n" #~ "--> Running transaction check\n" #~ "---> Package gettext-libs.x86_64 0:0.18.1.1-7.fc15 will be installed\n" #~ "---> Package libbsd.x86_64 0:0.2.0-4.fc15 will be installed\n" #~ "---> Package libgomp.x86_64 0:4.6.1-9.fc15 will be installed\n" #~ "---> Package xen-licenses.x86_64 0:4.1.1-3.fc15 will be installed\n" #~ "--> Finished Dependency Resolution\n" #~ "\n" #~ "Dependencies Resolved\n" #~ "\n" #~ "=============================================================================\n" #~ " Package Arch Version Repository Size\n" #~ "=============================================================================\n" #~ "Installing:\n" #~ " cman x86_64 3.1.7-1.fc15 updates 366 k\n" #~ " gfs2-cluster x86_64 3.1.1-2.fc15 fedora 69 k\n" #~ " gfs2-utils x86_64 3.1.1-2.fc15 fedora 222 k\n" #~ "Installing for dependencies:\n" #~ " augeas-libs x86_64 0.9.0-1.fc15 updates 311 k\n" #~ " cyrus-sasl-md5 x86_64 2.1.23-18.fc15 updates 46 k\n" #~ " fence-agents x86_64 3.1.5-1.fc15 updates 186 k\n" #~ " gettext x86_64 0.18.1.1-7.fc15 fedora 1.0 M\n" #~ " gettext-libs x86_64 0.18.1.1-7.fc15 fedora 610 k\n" #~ " gnutls-utils x86_64 2.10.5-1.fc15 fedora 101 k\n" #~ " ipmitool x86_64 1.8.11-6.fc15 fedora 273 k\n" #~ " libbsd x86_64 0.2.0-4.fc15 fedora 37 k\n" #~ " libgomp x86_64 4.6.1-9.fc15 updates 95 k\n" #~ " libnl x86_64 1.1-14.fc15 fedora 118 k\n" #~ " libvirt-client x86_64 0.8.8-7.fc15 updates 2.4 M\n" #~ " modcluster x86_64 0.18.7-1.fc15 fedora 187 k\n" #~ " nc x86_64 1.100-3.fc15 updates 24 k\n" #~ " net-snmp-utils x86_64 1:5.6.1-7.fc15 fedora 180 k\n" #~ " netcf-libs x86_64 0.1.9-1.fc15 updates 50 k\n" #~ " nss-tools x86_64 3.12.10-6.fc15 updates 723 k\n" #~ " numactl x86_64 2.0.7-1.fc15 updates 54 k\n" #~ " oddjob x86_64 0.31-2.fc15 fedora 61 k\n" #~ " openais x86_64 1.1.4-2.fc15 fedora 190 k\n" #~ " openaislib x86_64 1.1.4-2.fc15 fedora 88 k\n" #~ " parted x86_64 2.3-10.fc15 updates 618 k\n" #~ " perl-Net-Telnet noarch 3.03-12.fc15 fedora 55 k\n" #~ " pexpect noarch 2.3-6.fc15 fedora 141 k\n" #~ " pyOpenSSL x86_64 0.10-3.fc15 fedora 198 k\n" #~ " python-suds noarch 0.3.9-3.fc15 fedora 195 k\n" #~ " ricci x86_64 0.18.7-1.fc15 fedora 584 k\n" #~ " sg3_utils x86_64 1.29-3.fc15 fedora 465 k\n" #~ " sg3_utils-libs x86_64 1.29-3.fc15 fedora 54 k\n" #~ " xen-libs x86_64 4.1.1-3.fc15 updates 310 k\n" #~ " xen-licenses x86_64 4.1.1-3.fc15 updates 64 k\n" #~ " yajl x86_64 1.0.11-1.fc15 fedora 27 k\n" #~ "\n" #~ "Transaction Summary\n" #~ "=============================================================================\n" #~ "Install 34 Package(s)\n" #~ "\n" #~ "Total download size: 10 M\n" #~ "Installed size: 38 M\n" #~ "Downloading Packages:\n" #~ "(1/34): augeas-libs-0.9.0-1.fc15.x86_64.rpm | 311 kB 00:00 \n" #~ "(2/34): cman-3.1.7-1.fc15.x86_64.rpm | 366 kB 00:00 \n" #~ "(3/34): cyrus-sasl-md5-2.1.23-18.fc15.x86_64.rpm | 46 kB 00:00 \n" #~ "(4/34): fence-agents-3.1.5-1.fc15.x86_64.rpm | 186 kB 00:00 \n" #~ "(5/34): gettext-0.18.1.1-7.fc15.x86_64.rpm | 1.0 MB 00:01 \n" #~ "(6/34): gettext-libs-0.18.1.1-7.fc15.x86_64.rpm | 610 kB 00:00 \n" #~ "(7/34): gfs2-cluster-3.1.1-2.fc15.x86_64.rpm | 69 kB 00:00 \n" #~ "(8/34): gfs2-utils-3.1.1-2.fc15.x86_64.rpm | 222 kB 00:00 \n" #~ "(9/34): gnutls-utils-2.10.5-1.fc15.x86_64.rpm | 101 kB 00:00 \n" #~ "(10/34): ipmitool-1.8.11-6.fc15.x86_64.rpm | 273 kB 00:00 \n" #~ "(11/34): libbsd-0.2.0-4.fc15.x86_64.rpm | 37 kB 00:00 \n" #~ "(12/34): libgomp-4.6.1-9.fc15.x86_64.rpm | 95 kB 00:00 \n" #~ "(13/34): libnl-1.1-14.fc15.x86_64.rpm | 118 kB 00:00 \n" #~ "(14/34): libvirt-client-0.8.8-7.fc15.x86_64.rpm | 2.4 MB 00:01 \n" #~ "(15/34): modcluster-0.18.7-1.fc15.x86_64.rpm | 187 kB 00:00 \n" #~ "(16/34): nc-1.100-3.fc15.x86_64.rpm | 24 kB 00:00 \n" #~ "(17/34): net-snmp-utils-5.6.1-7.fc15.x86_64.rpm | 180 kB 00:00 \n" #~ "(18/34): netcf-libs-0.1.9-1.fc15.x86_64.rpm | 50 kB 00:00 \n" #~ "(19/34): nss-tools-3.12.10-6.fc15.x86_64.rpm | 723 kB 00:00 \n" #~ "(20/34): numactl-2.0.7-1.fc15.x86_64.rpm | 54 kB 00:00 \n" #~ "(21/34): oddjob-0.31-2.fc15.x86_64.rpm | 61 kB 00:00 \n" #~ "(22/34): openais-1.1.4-2.fc15.x86_64.rpm | 190 kB 00:00 \n" #~ "(23/34): openaislib-1.1.4-2.fc15.x86_64.rpm | 88 kB 00:00 \n" #~ "(24/34): parted-2.3-10.fc15.x86_64.rpm | 618 kB 00:00 \n" #~ "(25/34): perl-Net-Telnet-3.03-12.fc15.noarch.rpm | 55 kB 00:00 \n" #~ "(26/34): pexpect-2.3-6.fc15.noarch.rpm | 141 kB 00:00 \n" #~ "(27/34): pyOpenSSL-0.10-3.fc15.x86_64.rpm | 198 kB 00:00 \n" #~ "(28/34): python-suds-0.3.9-3.fc15.noarch.rpm | 195 kB 00:00 \n" #~ "(29/34): ricci-0.18.7-1.fc15.x86_64.rpm | 584 kB 00:00 \n" #~ "(30/34): sg3_utils-1.29-3.fc15.x86_64.rpm | 465 kB 00:00 \n" #~ "(31/34): sg3_utils-libs-1.29-3.fc15.x86_64.rpm | 54 kB 00:00 \n" #~ "(32/34): xen-libs-4.1.1-3.fc15.x86_64.rpm | 310 kB 00:00 \n" #~ "(33/34): xen-licenses-4.1.1-3.fc15.x86_64.rpm | 64 kB 00:00 \n" #~ "(34/34): yajl-1.0.11-1.fc15.x86_64.rpm | 27 kB 00:00 \n" #~ "-----------------------------------------------------------------------------\n" #~ "Total 803 kB/s | 10 MB 00:12 \n" #~ "Running rpm_check_debug\n" #~ "Running Transaction Test\n" #~ "Transaction Test Succeeded\n" #~ "Running Transaction\n" #~ " Installing : openais-1.1.4-2.fc15.x86_64 1/34 \n" #~ " Installing : openaislib-1.1.4-2.fc15.x86_64 2/34 \n" #~ " Installing : libnl-1.1-14.fc15.x86_64 3/34 \n" #~ " Installing : augeas-libs-0.9.0-1.fc15.x86_64 4/34 \n" #~ " Installing : oddjob-0.31-2.fc15.x86_64 5/34 \n" #~ " Installing : modcluster-0.18.7-1.fc15.x86_64 6/34 \n" #~ " Installing : netcf-libs-0.1.9-1.fc15.x86_64 7/34 \n" #~ " Installing : 1:net-snmp-utils-5.6.1-7.fc15.x86_64 8/34 \n" #~ " Installing : sg3_utils-libs-1.29-3.fc15.x86_64 9/34 \n" #~ " Installing : sg3_utils-1.29-3.fc15.x86_64 10/34 \n" #~ " Installing : libgomp-4.6.1-9.fc15.x86_64 11/34 \n" #~ " Installing : gnutls-utils-2.10.5-1.fc15.x86_64 12/34 \n" #~ " Installing : pyOpenSSL-0.10-3.fc15.x86_64 13/34 \n" #~ " Installing : parted-2.3-10.fc15.x86_64 14/34 \n" #~ " Installing : cyrus-sasl-md5-2.1.23-18.fc15.x86_64 15/34 \n" #~ " Installing : python-suds-0.3.9-3.fc15.noarch 16/34 \n" #~ " Installing : ipmitool-1.8.11-6.fc15.x86_64 17/34 \n" #~ " Installing : perl-Net-Telnet-3.03-12.fc15.noarch 18/34 \n" #~ " Installing : numactl-2.0.7-1.fc15.x86_64 19/34 \n" #~ " Installing : yajl-1.0.11-1.fc15.x86_64 20/34 \n" #~ " Installing : gettext-libs-0.18.1.1-7.fc15.x86_64 21/34 \n" #~ " Installing : gettext-0.18.1.1-7.fc15.x86_64 22/34 \n" #~ " Installing : libbsd-0.2.0-4.fc15.x86_64 23/34 \n" #~ " Installing : nc-1.100-3.fc15.x86_64 24/34 \n" #~ " Installing : xen-licenses-4.1.1-3.fc15.x86_64 25/34 \n" #~ " Installing : xen-libs-4.1.1-3.fc15.x86_64 26/34 \n" #~ " Installing : libvirt-client-0.8.8-7.fc15.x86_64 27/34 \n" #~ "\n" #~ "Note: This output shows SysV services only and does not include native\n" #~ " systemd services. SysV configuration data might be overridden by native\n" #~ " systemd configuration.\n" #~ "\n" #~ " Installing : nss-tools-3.12.10-6.fc15.x86_64 28/34 \n" #~ " Installing : ricci-0.18.7-1.fc15.x86_64 29/34 \n" #~ " Installing : pexpect-2.3-6.fc15.noarch 30/34 \n" #~ " Installing : fence-agents-3.1.5-1.fc15.x86_64 31/34 \n" #~ " Installing : cman-3.1.7-1.fc15.x86_64 32/34 \n" #~ " Installing : gfs2-cluster-3.1.1-2.fc15.x86_64 33/34 \n" #~ " Installing : gfs2-utils-3.1.1-2.fc15.x86_64 34/34 \n" #~ "\n" #~ "Installed:\n" #~ " cman.x86_64 0:3.1.7-1.fc15 gfs2-cluster.x86_64 0:3.1.1-2.fc15 \n" #~ " gfs2-utils.x86_64 0:3.1.1-2.fc15 \n" #~ "\n" #~ "Dependency Installed:\n" #~ " augeas-libs.x86_64 0:0.9.0-1.fc15 \n" #~ " cyrus-sasl-md5.x86_64 0:2.1.23-18.fc15 \n" #~ " fence-agents.x86_64 0:3.1.5-1.fc15 \n" #~ " gettext.x86_64 0:0.18.1.1-7.fc15 \n" #~ " gettext-libs.x86_64 0:0.18.1.1-7.fc15 \n" #~ " gnutls-utils.x86_64 0:2.10.5-1.fc15 \n" #~ " ipmitool.x86_64 0:1.8.11-6.fc15 \n" #~ " libbsd.x86_64 0:0.2.0-4.fc15 \n" #~ " libgomp.x86_64 0:4.6.1-9.fc15 \n" #~ " libnl.x86_64 0:1.1-14.fc15 \n" #~ " libvirt-client.x86_64 0:0.8.8-7.fc15 \n" #~ " modcluster.x86_64 0:0.18.7-1.fc15 \n" #~ " nc.x86_64 0:1.100-3.fc15 \n" #~ " net-snmp-utils.x86_64 1:5.6.1-7.fc15 \n" #~ " netcf-libs.x86_64 0:0.1.9-1.fc15 \n" #~ " nss-tools.x86_64 0:3.12.10-6.fc15 \n" #~ " numactl.x86_64 0:2.0.7-1.fc15 \n" #~ " oddjob.x86_64 0:0.31-2.fc15 \n" #~ " openais.x86_64 0:1.1.4-2.fc15 \n" #~ " openaislib.x86_64 0:1.1.4-2.fc15 \n" #~ " parted.x86_64 0:2.3-10.fc15 \n" #~ " perl-Net-Telnet.noarch 0:3.03-12.fc15 \n" #~ " pexpect.noarch 0:2.3-6.fc15 \n" #~ " pyOpenSSL.x86_64 0:0.10-3.fc15 \n" #~ " python-suds.noarch 0:0.3.9-3.fc15 \n" #~ " ricci.x86_64 0:0.18.7-1.fc15 \n" #~ " sg3_utils.x86_64 0:1.29-3.fc15 \n" #~ " sg3_utils-libs.x86_64 0:1.29-3.fc15 \n" #~ " xen-libs.x86_64 0:4.1.1-3.fc15 \n" #~ " xen-licenses.x86_64 0:4.1.1-3.fc15 \n" #~ " yajl.x86_64 0:1.0.11-1.fc15 \n" #~ "\n" #~ "Complete!\n" #~ "[root@pcmk-1 ~]# \n" #~ " " #~ msgid "Configuring CMAN" #~ msgstr "Configurarea CMAN" #~ msgid "The first thing we need to do, is tell CMAN complete starting up even without quorum. We can do this by changing the quorum timeout setting:" #~ msgstr "Primul lucru pe care trebuie să îl facem este să îi spunem lui CMAN să încheie cu succes procedura de pornire chiar și fără quorum. Putem realiza acest lucru prin schimbarea setării de expirare a temporizatorului pentru quorum:" #~ msgid "" #~ "\n" #~ "[root@pcmk-1 ~]# sed -i.sed \"s/.*CMAN_QUORUM_TIMEOUT=.*/CMAN_QUORUM_TIMEOUT=0/g\" /etc/sysconfig/cman\n" #~ " " #~ msgstr "" #~ "\n" #~ "[root@pcmk-1 ~]# sed -i.sed \"s/.*CMAN_QUORUM_TIMEOUT=.*/CMAN_QUORUM_TIMEOUT=0/g\" /etc/sysconfig/cman\n" #~ " " #~ msgid "Next we create a basic configuration file and place it in /etc/cluster/cluster.conf. The name used for each clusternode should correspond to that node's uname -n, just as Pacemaker expects. The nodeid can be any positive number but must be unique." #~ msgstr "În continuare creem un fișier de configurare de bază și îl punem în /etc/cluster/cluster.conf. Numele folosit pentru fiecare clusternode ar trebui să corespundă cu uname -n de pe nodul respectiv, exact așa cum se așteaptă și Pacemaker. nodeid poate fi orice număr pozitiv dar trebuie să fie unic." #~ msgid "Basic cluster.conf for a two-node cluster" #~ msgstr "Un cluster.conf de bază pentru un cluster format din două noduri" #~ msgid "" #~ "\n" #~ "\t\n" #~ "<?xml version=\"1.0\"?>\n" #~ "<cluster config_version=\"1\" name=\"my_cluster_name\">\n" #~ " <logging debug=\"off\"/>\n" #~ " <clusternodes>\n" #~ " <clusternode name=\"pcmk-1\" nodeid=\"1\"/>\n" #~ " <clusternode name=\"pcmk-2\" nodeid=\"2\"/>\n" #~ " </clusternodes>\n" #~ "</cluster>\n" #~ "\t\n" #~ "\t " #~ msgstr "" #~ "\n" #~ "\t\n" #~ "<?xml version=\"1.0\"?>\n" #~ "<cluster config_version=\"1\" name=\"my_cluster_name\">\n" #~ " <logging debug=\"off\"/>\n" #~ " <clusternodes>\n" #~ " <clusternode name=\"pcmk-1\" nodeid=\"1\"/>\n" #~ " <clusternode name=\"pcmk-2\" nodeid=\"2\"/>\n" #~ " </clusternodes>\n" #~ "</cluster>\n" #~ "\t\n" #~ "\t " #~ msgid "Configuring CMAN Fencing" #~ msgstr "Configurarea Evacuării Forțate în CMAN" #~ msgid "We configure the fence_pcmk agent (supplied with Pacemaker) to redirect any fencing requests from CMAN components (such as dlm_controld) to Pacemaker. Pacemaker's fencing subsystem lets other parts of the stack know that a node has been successfully fenced, thus avoiding the need for it to be fenced again when other subsystems notice the node is gone." #~ msgstr "Configurăm agentul fence_pcmk (furnizat împreună cu Pacemaker) pentru a redirecta orice cereri de evacuare forțată de la componentele CMAN (cum ar fi dlm_controld) către Pacemaker. Subsistemul de evacuare forțată al Pacemaker lasă alte părți ale stivei să știe că un nod a fost evacuat forțat cu succes, prin urmare evitând nevoia ca acesta să fie evacuat forțat din nou când alte subsisteme detectează că nodul a dispărut. " #~ msgid "Configuring real fencing devices in CMAN will result in nodes being fenced multiple times as different parts of the stack notice the node is missing or failed." #~ msgstr "Configurarea de dispozitive reale de evacuare forțată în CMAN va rezulta în evacuarea forțată de mai multe ori a nodurilor pe măsură ce părți diferite ale stivei detectează că un nod lipsește sau a eșuat." #~ msgid "The definition should be placed in the fencedevices section and contain:" #~ msgstr "Definiția ar trebui plasată în secțiunea fencedevices și ar trebui să conțină:" #~ msgid "" #~ "\n" #~ "\t\n" #~ " <fencedevice name=\"pcmk\" agent=\"fence_pcmk\"/>\n" #~ "\t\n" #~ "\t" #~ msgstr "" #~ "\n" #~ "\t\n" #~ " <fencedevice name=\"pcmk\" agent=\"fence_pcmk\"/>\n" #~ "\t\n" #~ "\t" #~ msgid "Each clusternode must be configured to use this device by adding a fence method block that lists the node's name as the port." #~ msgstr "Fiecare clusternode trebuie să fie configurat să folosească acest dispozitiv prin adăugarea unui bloc cu metoda de evacuare forțată care listează numele acelui nod ca și port." #~ msgid "" #~ "\n" #~ "\t\n" #~ " <fence>\n" #~ " <method name=\"pcmk-redirect\">\n" #~ " <device name=\"pcmk\" port=\"node_name_here\"/>\n" #~ " </method>\n" #~ " </fence>\n" #~ "\t\n" #~ "\t" #~ msgstr "" #~ "\n" #~ "\t\n" #~ " <fence>\n" #~ " <method name=\"pcmk-redirect\">\n" #~ " <device name=\"pcmk\" port=\"node_name_here\"/>\n" #~ " </method>\n" #~ " </fence>\n" #~ "\t\n" #~ "\t" #~ msgid "Putting everything together, we have:" #~ msgstr "Punând totul la un loc, avem:" #~ msgid "cluster.conf for a two-node cluster with fencing" #~ msgstr "cluster.conf pentru un cluster format din două noduri cu evacuare forțată" #~ msgid "" #~ "\n" #~ "\t\n" #~ "<?xml version=\"1.0\"?>\n" #~ "<cluster config_version=\"1\" name=\"mycluster\">\n" #~ " <logging debug=\"off\"/>\n" #~ " <clusternodes>\n" #~ " <clusternode name=\"pcmk-1\" nodeid=\"1\">\n" #~ " <fence>\n" #~ " <method name=\"pcmk-redirect\">\n" #~ " <device name=\"pcmk\" port=\"pcmk-1\"/>\n" #~ " </method>\n" #~ " </fence>\n" #~ " </clusternode>\n" #~ " <clusternode name=\"pcmk-2\" nodeid=\"2\">\n" #~ " <fence>\n" #~ " <method name=\"pcmk-redirect\">\n" #~ " <device name=\"pcmk\" port=\"pcmk-2\"/>\n" #~ " </method>\n" #~ " </fence>\n" #~ " </clusternode>\n" #~ " </clusternodes>\n" #~ " <fencedevices>\n" #~ " <fencedevice name=\"pcmk\" agent=\"fence_pcmk\"/>\n" #~ " </fencedevices>\n" #~ "</cluster>\n" #~ "\t\n" #~ "\t " #~ msgstr "" #~ "\n" #~ "\t\n" #~ "<?xml version=\"1.0\"?>\n" #~ "<cluster config_version=\"1\" name=\"mycluster\">\n" #~ " <logging debug=\"off\"/>\n" #~ " <clusternodes>\n" #~ " <clusternode name=\"pcmk-1\" nodeid=\"1\">\n" #~ " <fence>\n" #~ " <method name=\"pcmk-redirect\">\n" #~ " <device name=\"pcmk\" port=\"pcmk-1\"/>\n" #~ " </method>\n" #~ " </fence>\n" #~ " </clusternode>\n" #~ " <clusternode name=\"pcmk-2\" nodeid=\"2\">\n" #~ " <fence>\n" #~ " <method name=\"pcmk-redirect\">\n" #~ " <device name=\"pcmk\" port=\"pcmk-2\"/>\n" #~ " </method>\n" #~ " </fence>\n" #~ " </clusternode>\n" #~ " </clusternodes>\n" #~ " <fencedevices>\n" #~ " <fencedevice name=\"pcmk\" agent=\"fence_pcmk\"/>\n" #~ " </fencedevices>\n" #~ "</cluster>\n" #~ "\t\n" #~ "\t " #~ msgid "Bringing the Cluster Online with CMAN" #~ msgstr "Aducerea Clusterului Online cu CMAN" #~ msgid "The first thing to do is check that the configuration is valid" #~ msgstr "Primul lucru care trebuie făcut este de a verifica dacă este validă configurația" #~ msgid "" #~ "\n" #~ "[root@pcmk-1 ~]# ccs_config_validate\n" #~ "Configuration validates\n" #~ "\t" #~ msgstr "" #~ "\n" #~ "[root@pcmk-1 ~]# ccs_config_validate\n" #~ "Configuration validates\n" #~ "\t" #~ msgid "Now start CMAN" #~ msgstr "Acum porniți CMAN" #~ msgid "" #~ "\n" #~ "[root@pcmk-1 ~]# service cman start\n" #~ "Starting cluster: \n" #~ " Checking Network Manager... [ OK ]\n" #~ " Global setup... [ OK ]\n" #~ " Loading kernel modules... [ OK ]\n" #~ " Mounting configfs... [ OK ]\n" #~ " Starting cman... [ OK ]\n" #~ " Waiting for quorum... [ OK ]\n" #~ " Starting fenced... [ OK ]\n" #~ " Starting dlm_controld... [ OK ]\n" #~ " Starting gfs_controld... [ OK ]\n" #~ " Unfencing self... [ OK ]\n" #~ " Joining fence domain... [ OK ]\n" #~ "[root@pcmk-1 ~]# crm_mon -1\n" #~ "\t" #~ msgstr "" #~ "\n" #~ "[root@pcmk-1 ~]# service cman start\n" #~ "Starting cluster: \n" #~ " Checking Network Manager... [ OK ]\n" #~ " Global setup... [ OK ]\n" #~ " Loading kernel modules... [ OK ]\n" #~ " Mounting configfs... [ OK ]\n" #~ " Starting cman... [ OK ]\n" #~ " Waiting for quorum... [ OK ]\n" #~ " Starting fenced... [ OK ]\n" #~ " Starting dlm_controld... [ OK ]\n" #~ " Starting gfs_controld... [ OK ]\n" #~ " Unfencing self... [ OK ]\n" #~ " Joining fence domain... [ OK ]\n" #~ "[root@pcmk-1 ~]# crm_mon -1\n" #~ "\t" #~ msgid "Once you have confirmed that the first node is happily online, start the second node." #~ msgstr "Odată ce ați confirmat că primul nod este fericit online, porniți al doilea nod." #~ msgid "" #~ "\n" #~ "[root@pcmk-2 ~]# service cman start\n" #~ "Starting cluster: \n" #~ " Checking Network Manager... [ OK ]\n" #~ " Global setup... [ OK ]\n" #~ " Loading kernel modules... [ OK ]\n" #~ " Mounting configfs... [ OK ]\n" #~ " Starting cman... [ OK ]\n" #~ " Waiting for quorum... [ OK ]\n" #~ " Starting fenced... [ OK ]\n" #~ " Starting dlm_controld... [ OK ]\n" #~ " Starting gfs_controld... [ OK ]\n" #~ " Unfencing self... [ OK ]\n" #~ " Joining fence domain... [ OK ]\n" #~ "[root@pcmk-1 ~]# cman_tool nodes\n" #~ "Node Sts Inc Joined Name\n" #~ " 1 M 548 2011-09-28 10:52:21 pcmk-1\n" #~ " 2 M 548 2011-09-28 10:52:21 pcmk-2\n" #~ "[root@pcmk-1 ~]# crm_mon -1\n" #~ "\t" #~ msgstr "" #~ "\n" #~ "[root@pcmk-2 ~]# service cman start\n" #~ "Starting cluster: \n" #~ " Checking Network Manager... [ OK ]\n" #~ " Global setup... [ OK ]\n" #~ " Loading kernel modules... [ OK ]\n" #~ " Mounting configfs... [ OK ]\n" #~ " Starting cman... [ OK ]\n" #~ " Waiting for quorum... [ OK ]\n" #~ " Starting fenced... [ OK ]\n" #~ " Starting dlm_controld... [ OK ]\n" #~ " Starting gfs_controld... [ OK ]\n" #~ " Unfencing self... [ OK ]\n" #~ " Joining fence domain... [ OK ]\n" #~ "[root@pcmk-1 ~]# cman_tool nodes\n" #~ "Node Sts Inc Joined Name\n" #~ " 1 M 548 2011-09-28 10:52:21 pcmk-1\n" #~ " 2 M 548 2011-09-28 10:52:21 pcmk-2\n" #~ "[root@pcmk-1 ~]# crm_mon -1\n" #~ "\t" #~ msgid "You should now see both nodes online and services started." #~ msgstr "Ar trebui să vedeți acum ambele noduri online și serviciile pornite." #~ msgid "" #~ "\n" #~ "[root@pcmk-1 ~]# crm_resource --resource WebFS --set-parameter target-role --meta --parameter-value Stopped\n" #~ "[root@pcmk-1 ~]# crm_mon\n" #~ "============\n" #~ "Last updated: Thu Sep  3 15:18:06 2009\n" #~ "Stack: openais\n" #~ "Current DC: pcmk-1 - partition with quorum\n" #~ "Version: 1.1.5-bdd89e69ba545404d02445be1f3d72e6a203ba2f\n" #~ "2 Nodes configured, 2 expected votes\n" #~ "6 Resources configured.\n" #~ "============\n" #~ "\n" #~ "Online: [ pcmk-1 pcmk-2 ]\n" #~ "\n" #~ "Master/Slave Set: WebDataClone\n" #~ "        Masters: [ pcmk-1 ]\n" #~ "        Slaves: [ pcmk-2 ]\n" #~ "ClusterIP        (ocf::heartbeat:IPaddr):        Started pcmk-1\n" #~ msgstr "" #~ "\n" #~ "[root@pcmk-1 ~]# crm_resource --resource WebFS --set-parameter target-role --meta --parameter-value Stopped\n" #~ "[root@pcmk-1 ~]# crm_mon\n" #~ "============\n" #~ "Last updated: Thu Sep  3 15:18:06 2009\n" #~ "Stack: openais\n" #~ "Current DC: pcmk-1 - partition with quorum\n" #~ "Version: 1.1.5-bdd89e69ba545404d02445be1f3d72e6a203ba2f\n" #~ "2 Nodes configured, 2 expected votes\n" #~ "6 Resources configured.\n" #~ "============\n" #~ "\n" #~ "Online: [ pcmk-1 pcmk-2 ]\n" #~ "\n" #~ "Master/Slave Set: WebDataClone\n" #~ "        Masters: [ pcmk-1 ]\n" #~ "        Slaves: [ pcmk-2 ]\n" #~ "ClusterIP        (ocf::heartbeat:IPaddr):        Started pcmk-1\n" #~ msgid "Lastly, we use -t to specify the lock table name. The format for this field is clustername:fsname. For the fsname, we just need to pick something unique and descriptive and since we haven’t specified a clustername yet, we will use the default (pcmk)." #~ msgstr "În cele din urmă, folosim -t pentru a specifica numele tabelei de blocare. Formatul acestui câmp este clustername:fsname. Pentru fsname, nu trebuie decât să alegem ceva unic și descriptiv și din moment ce nu am specificat un clustername încă, vom folosi valoarea implicită (pcmk)." #~ msgid "To specify an alternate name for the cluster, locate the service section containing \"name: pacemaker\" in corosync.conf and insert the following line anywhere inside the block:" #~ msgstr "Pentru a specifica un nume alternativ pentru cluster, localizați secțiunea service din corosync.conf care conține \"name: pacemaker\" și inserați următoarea linie oriunde înăuntrul acelui bloc." #~ msgid "clustername: myname" #~ msgstr "clustername: myname" #~ msgid "Do this on each node in the cluster and be sure to restart them before continuing." #~ msgstr "Realizați acest lucru pe fiecare nod din cluster și asigurați-vă că le-ați repornit înainte de a continua." #~ msgid "" #~ "\n" #~ "[root@pcmk-1 ~]# crm\n" #~ "crm(live)# cib new GFS2\n" #~ "INFO: GFS2 shadow CIB created\n" #~ "crm(GFS2)# configure delete WebFS\n" #~ "crm(GFS2)# configure primitive WebFS ocf:heartbeat:Filesystem params device=\"/dev/drbd/by-res/wwwdata\" directory=\"/var/www/html\" fstype=\"gfs2\"\n" #~ msgstr "" #~ "\n" #~ "[root@pcmk-1 ~]# crm\n" #~ "crm(live)# cib new GFS2\n" #~ "INFO: GFS2 shadow CIB created\n" #~ "crm(GFS2)# configure delete WebFS\n" #~ "crm(GFS2)# configure primitive WebFS ocf:heartbeat:Filesystem params device=\"/dev/drbd/by-res/wwwdata\" directory=\"/var/www/html\" fstype=\"gfs2\"\n" #~ msgid "Now that we’ve recreated the resource, we also need to recreate all the constraints that used it. This is because the shell will automatically remove any constraints that referenced WebFS." #~ msgstr "Acum că am creat resursa, trebuie să recreem și toate restricțiile care o foloseau. Acest lucru este datorită faptului că shell-ul va înlătura în mod automat orice restricție care referențiază WebFS.." #~ msgid "" #~ "\n" #~ "crm(GFS2)# configure colocation WebSite-with-WebFS inf: WebSite WebFS\n" #~ "crm(GFS2)# configure colocation fs_on_drbd inf: WebFS WebDataClone:Master\n" #~ "crm(GFS2)# configure order WebFS-after-WebData inf: WebDataClone:promote WebFS:start\n" #~ "crm(GFS2)# configure order WebSite-after-WebFS inf: WebFS WebSite\n" #~ "crm(GFS2)# configure show\n" #~ "node pcmk-1\n" #~ "node pcmk-2\n" #~ "primitive WebData ocf:linbit:drbd \\\n" #~ "        params drbd_resource=\"wwwdata\" \\\n" #~ "        op monitor interval=\"60s\"\n" #~ "primitive WebFS ocf:heartbeat:Filesystem \\\n" #~ " params device=\"/dev/drbd/by-res/wwwdata\" directory=\"/var/www/html\" fstype=\"gfs2\"\n" #~ "primitive WebSite ocf:heartbeat:apache \\\n" #~ "        params configfile=\"/etc/httpd/conf/httpd.conf\" \\\n" #~ "        op monitor interval=\"1min\"\n" #~ "primitive ClusterIP ocf:heartbeat:IPaddr2 \\\n" #~ "        params ip=\"192.168.122.101\" cidr_netmask=\"32\" \\\n" #~ "        op monitor interval=\"30s\"\n" #~ "ms WebDataClone WebData \\\n" #~ "        meta master-max=\"1\" master-node-max=\"1\" clone-max=\"2\" clone-node-max=\"1\" notify=\"true\"\n" #~ "colocation WebSite-with-WebFS inf: WebSite WebFS\n" #~ "colocation fs_on_drbd inf: WebFS WebDataClone:Master\n" #~ "colocation website-with-ip inf: WebSite ClusterIP\n" #~ "order WebFS-after-WebData inf: WebDataClone:promote WebFS:start\n" #~ "order WebSite-after-WebFS inf: WebFS WebSite\n" #~ "order apache-after-ip inf: ClusterIP WebSite\n" #~ "property $id=\"cib-bootstrap-options\" \\\n" #~ "        dc-version=\"1.1.5-bdd89e69ba545404d02445be1f3d72e6a203ba2f\" \\\n" #~ "        cluster-infrastructure=\"openais\" \\\n" #~ "        expected-quorum-votes=\"2\" \\\n" #~ "        stonith-enabled=\"false\" \\\n" #~ "        no-quorum-policy=\"ignore\"\n" #~ "rsc_defaults $id=\"rsc-options\" \\\n" #~ "        resource-stickiness=\"100\"\n" #~ msgstr "" #~ "\n" #~ "crm(GFS2)# configure colocation WebSite-with-WebFS inf: WebSite WebFS\n" #~ "crm(GFS2)# configure colocation fs_on_drbd inf: WebFS WebDataClone:Master\n" #~ "crm(GFS2)# configure order WebFS-after-WebData inf: WebDataClone:promote WebFS:start\n" #~ "crm(GFS2)# configure order WebSite-after-WebFS inf: WebFS WebSite\n" #~ "crm(GFS2)# configure show\n" #~ "node pcmk-1\n" #~ "node pcmk-2\n" #~ "primitive WebData ocf:linbit:drbd \\\n" #~ "        params drbd_resource=\"wwwdata\" \\\n" #~ "        op monitor interval=\"60s\"\n" #~ "primitive WebFS ocf:heartbeat:Filesystem \\\n" #~ " params device=\"/dev/drbd/by-res/wwwdata\" directory=\"/var/www/html\" fstype=\"gfs2\"\n" #~ "primitive WebSite ocf:heartbeat:apache \\\n" #~ "        params configfile=\"/etc/httpd/conf/httpd.conf\" \\\n" #~ "        op monitor interval=\"1min\"\n" #~ "primitive ClusterIP ocf:heartbeat:IPaddr2 \\\n" #~ "        params ip=\"192.168.122.101\" cidr_netmask=\"32\" \\\n" #~ "        op monitor interval=\"30s\"\n" #~ "ms WebDataClone WebData \\\n" #~ "        meta master-max=\"1\" master-node-max=\"1\" clone-max=\"2\" clone-node-max=\"1\" notify=\"true\"\n" #~ "colocation WebSite-with-WebFS inf: WebSite WebFS\n" #~ "colocation fs_on_drbd inf: WebFS WebDataClone:Master\n" #~ "colocation website-with-ip inf: WebSite ClusterIP\n" #~ "order WebFS-after-WebData inf: WebDataClone:promote WebFS:start\n" #~ "order WebSite-after-WebFS inf: WebFS WebSite\n" #~ "order apache-after-ip inf: ClusterIP WebSite\n" #~ "property $id=\"cib-bootstrap-options\" \\\n" #~ "        dc-version=\"1.1.5-bdd89e69ba545404d02445be1f3d72e6a203ba2f\" \\\n" #~ "        cluster-infrastructure=\"openais\" \\\n" #~ "        expected-quorum-votes=\"2\" \\\n" #~ "        stonith-enabled=\"false\" \\\n" #~ "        no-quorum-policy=\"ignore\"\n" #~ "rsc_defaults $id=\"rsc-options\" \\\n" #~ "        resource-stickiness=\"100\"\n" #~ msgid "" #~ "\n" #~ "crm(GFS2)# cib commit GFS2\n" #~ "INFO: commited 'GFS2' shadow CIB to the cluster\n" #~ "crm(GFS2)# quit\n" #~ "bye\n" #~ "[root@pcmk-1 ~]# crm_mon\n" #~ "============\n" #~ "Last updated: Thu Sep  3 20:49:54 2009\n" #~ "Stack: openais\n" #~ "Current DC: pcmk-2 - partition with quorum\n" #~ "Version: 1.1.5-bdd89e69ba545404d02445be1f3d72e6a203ba2f\n" #~ "2 Nodes configured, 2 expected votes\n" #~ "6 Resources configured.\n" #~ "============\n" #~ "\n" #~ "Online: [ pcmk-1 pcmk-2 ]\n" #~ "\n" #~ "WebSite (ocf::heartbeat:apache):        Started pcmk-2\n" #~ "Master/Slave Set: WebDataClone\n" #~ "        Masters: [ pcmk-1 ]\n" #~ "        Slaves: [ pcmk-2 ]\n" #~ "ClusterIP        (ocf::heartbeat:IPaddr):        Started pcmk-2\n" #~ "WebFS (ocf::heartbeat:Filesystem): Started pcmk-1\n" #~ msgstr "" #~ "\n" #~ "crm(GFS2)# cib commit GFS2\n" #~ "INFO: commited 'GFS2' shadow CIB to the cluster\n" #~ "crm(GFS2)# quit\n" #~ "bye\n" #~ "[root@pcmk-1 ~]# crm_mon\n" #~ "============\n" #~ "Last updated: Thu Sep  3 20:49:54 2009\n" #~ "Stack: openais\n" #~ "Current DC: pcmk-2 - partition with quorum\n" #~ "Version: 1.1.5-bdd89e69ba545404d02445be1f3d72e6a203ba2f\n" #~ "2 Nodes configured, 2 expected votes\n" #~ "6 Resources configured.\n" #~ "============\n" #~ "\n" #~ "Online: [ pcmk-1 pcmk-2 ]\n" #~ "\n" #~ "WebSite (ocf::heartbeat:apache):        Started pcmk-2\n" #~ "Master/Slave Set: WebDataClone\n" #~ "        Masters: [ pcmk-1 ]\n" #~ "        Slaves: [ pcmk-2 ]\n" #~ "ClusterIP        (ocf::heartbeat:IPaddr):        Started pcmk-2\n" #~ "WebFS (ocf::heartbeat:Filesystem): Started pcmk-1\n" #~ msgid "" #~ "\n" #~ "[root@pcmk-1 ~]# crm\n" #~ "[root@pcmk-1 ~]# cib new active\n" #~ " " #~ msgstr "" #~ "\n" #~ "[root@pcmk-1 ~]# crm\n" #~ "[root@pcmk-1 ~]# cib new active\n" #~ " " #~ msgid "Open the ClusterIP resource" #~ msgstr "Deschideți resursa ClusterIP" #~ msgid "[root@pcmk-1 ~]# configure edit  ClusterIP" #~ msgstr "[root@pcmk-1 ~]# configure edit  ClusterIP" #~ msgid "And add the following to the params line" #~ msgstr "Adăugați următoarele pe linia params" #~ msgid "clusterip_hash=\"sourceip\"" #~ msgstr "clusterip_hash=\"sourceip\"" #~ msgid "So that the complete definition looks like:" #~ msgstr "Astfel încât definiția completă să arate precum:" #~ msgid "" #~ "\n" #~ "primitive ClusterIP ocf:heartbeat:IPaddr2 \\ \n" #~ "        params ip=\"192.168.122.101\" cidr_netmask=\"32\" clusterip_hash=\"sourceip\" \\\n" #~ "        op monitor interval=\"30s\"\n" #~ " " #~ msgstr "" #~ "\n" #~ "primitive ClusterIP ocf:heartbeat:IPaddr2 \\ \n" #~ "        params ip=\"192.168.122.101\" cidr_netmask=\"32\" clusterip_hash=\"sourceip\" \\\n" #~ "        op monitor interval=\"30s\"\n" #~ " " #~ msgid "Here is the full transcript" #~ msgstr "Aici este transcrierea completă" #~ msgid "" #~ "\n" #~ "[root@pcmk-1 ~]# crm \n" #~ "crm(live)# cib new active\n" #~ "INFO: active shadow CIB created\n" #~ "crm(active)# configure clone WebIP ClusterIP  \\\n" #~ "        meta globally-unique=\"true\" clone-max=\"2\" clone-node-max=\"2\"\n" #~ "crm(active)# configure show\n" #~ "node pcmk-1\n" #~ "node pcmk-2\n" #~ "primitive WebData ocf:linbit:drbd \\\n" #~ "        params drbd_resource=\"wwwdata\" \\\n" #~ "        op monitor interval=\"60s\"\n" #~ "primitive WebFS ocf:heartbeat:Filesystem \\\n" #~ "        params device=\"/dev/drbd/by-res/wwwdata\" directory=\"/var/www/html\" fstype=\"gfs2\"\n" #~ "primitive WebSite ocf:heartbeat:apache \\\n" #~ "        params configfile=\"/etc/httpd/conf/httpd.conf\" \\\n" #~ "        op monitor interval=\"1min\"\n" #~ "primitive ClusterIP ocf:heartbeat:IPaddr2 \\\n" #~ "        params ip=\"192.168.122.101\" cidr_netmask=\"32\" clusterip_hash=\"sourceip\" \\\n" #~ "        op monitor interval=\"30s\"\n" #~ "ms WebDataClone WebData \\\n" #~ "        meta master-max=\"1\" master-node-max=\"1\" clone-max=\"2\" clone-node-max=\"1\" notify=\"true\"\n" #~ "clone WebIP ClusterIP \\\n" #~ " meta globally-unique=\"true\" clone-max=\"2\" clone-node-max=\"2\"\n" #~ "colocation WebSite-with-WebFS inf: WebSite WebFS\n" #~ "colocation fs_on_drbd inf: WebFS WebDataClone:Master\n" #~ "colocation website-with-ip inf: WebSite WebIP\n" #~ "order WebFS-after-WebData inf: WebDataClone:promote WebFS:start\n" #~ "order WebSite-after-WebFS inf: WebFS WebSite\n" #~ "order apache-after-ip inf: WebIP WebSite\n" #~ "property $id=\"cib-bootstrap-options\" \\\n" #~ "        dc-version=\"1.1.5-bdd89e69ba545404d02445be1f3d72e6a203ba2f\" \\\n" #~ "        cluster-infrastructure=\"openais\" \\\n" #~ "        expected-quorum-votes=\"2\" \\\n" #~ "        stonith-enabled=\"false\" \\\n" #~ "        no-quorum-policy=\"ignore\"\n" #~ "rsc_defaults $id=\"rsc-options\" \\\n" #~ "        resource-stickiness=\"100\"\n" #~ " " #~ msgstr "" #~ "\n" #~ "[root@pcmk-1 ~]# crm \n" #~ "crm(live)# cib new active\n" #~ "INFO: active shadow CIB created\n" #~ "crm(active)# configure clone WebIP ClusterIP  \\\n" #~ "        meta globally-unique=\"true\" clone-max=\"2\" clone-node-max=\"2\"\n" #~ "crm(active)# configure show\n" #~ "node pcmk-1\n" #~ "node pcmk-2\n" #~ "primitive WebData ocf:linbit:drbd \\\n" #~ "        params drbd_resource=\"wwwdata\" \\\n" #~ "        op monitor interval=\"60s\"\n" #~ "primitive WebFS ocf:heartbeat:Filesystem \\\n" #~ "        params device=\"/dev/drbd/by-res/wwwdata\" directory=\"/var/www/html\" fstype=\"gfs2\"\n" #~ "primitive WebSite ocf:heartbeat:apache \\\n" #~ "        params configfile=\"/etc/httpd/conf/httpd.conf\" \\\n" #~ "        op monitor interval=\"1min\"\n" #~ "primitive ClusterIP ocf:heartbeat:IPaddr2 \\\n" #~ "        params ip=\"192.168.122.101\" cidr_netmask=\"32\" clusterip_hash=\"sourceip\" \\\n" #~ "        op monitor interval=\"30s\"\n" #~ "ms WebDataClone WebData \\\n" #~ "        meta master-max=\"1\" master-node-max=\"1\" clone-max=\"2\" clone-node-max=\"1\" notify=\"true\"\n" #~ "clone WebIP ClusterIP \\\n" #~ " meta globally-unique=\"true\" clone-max=\"2\" clone-node-max=\"2\"\n" #~ "colocation WebSite-with-WebFS inf: WebSite WebFS\n" #~ "colocation fs_on_drbd inf: WebFS WebDataClone:Master\n" #~ "colocation website-with-ip inf: WebSite WebIP\n" #~ "order WebFS-after-WebData inf: WebDataClone:promote WebFS:start\n" #~ "order WebSite-after-WebFS inf: WebFS WebSite\n" #~ "order apache-after-ip inf: WebIP WebSite\n" #~ "property $id=\"cib-bootstrap-options\" \\\n" #~ "        dc-version=\"1.1.5-bdd89e69ba545404d02445be1f3d72e6a203ba2f\" \\\n" #~ "        cluster-infrastructure=\"openais\" \\\n" #~ "        expected-quorum-votes=\"2\" \\\n" #~ "        stonith-enabled=\"false\" \\\n" #~ "        no-quorum-policy=\"ignore\"\n" #~ "rsc_defaults $id=\"rsc-options\" \\\n" #~ "        resource-stickiness=\"100\"\n" #~ " " #~ msgid "Notice how any constraints that referenced ClusterIP have been updated to use WebIP instead. This is an additional benefit of using the crm shell." #~ msgstr "Vedeți câte restricții care referențiau ClusterIP au fost actualizate pentru a folosi WebIP în schimb. Acesta este un beneficiu adițional al folosirii shell-ului crm." #~ msgid "" #~ "\n" #~ "crm(active)# configure clone WebFSClone WebFS\n" #~ "crm(active)# configure clone WebSiteClone WebSite\n" #~ " " #~ msgstr "" #~ "\n" #~ "crm(active)# configure clone WebFSClone WebFS\n" #~ "crm(active)# configure clone WebSiteClone WebSite\n" #~ " " #~ msgid "" #~ "\n" #~ "crm(active)# configure edit WebDataClone\n" #~ " " #~ msgstr "" #~ "\n" #~ "crm(active)# configure edit WebDataClone\n" #~ " " #~ msgid "Change master-max to 2" #~ msgstr "Schimbați master-max la 2" #~ msgid "" #~ "\n" #~ "crm(active)# configure show\n" #~ "node pcmk-1\n" #~ "node pcmk-2\n" #~ "primitive WebData ocf:linbit:drbd \\\n" #~ "        params drbd_resource=\"wwwdata\" \\\n" #~ "        op monitor interval=\"60s\"\n" #~ "primitive WebFS ocf:heartbeat:Filesystem \\\n" #~ "        params device=\"/dev/drbd/by-res/wwwdata\" directory=\"/var/www/html\" fstype=\"gfs2\"\n" #~ "primitive WebSite ocf:heartbeat:apache \\\n" #~ "        params configfile=\"/etc/httpd/conf/httpd.conf\" \\\n" #~ "        op monitor interval=\"1min\"\n" #~ "primitive ClusterIP ocf:heartbeat:IPaddr2 \\\n" #~ "        params ip=\"192.168.122.101\" cidr_netmask=\"32\" clusterip_hash=\"sourceip\" \\\n" #~ "        op monitor interval=\"30s\"\n" #~ "ms WebDataClone WebData \\\n" #~ "        meta master-max=\"2\" master-node-max=\"1\" clone-max=\"2\" clone-node-max=\"1\" notify=\"true\"\n" #~ "clone WebFSClone WebFS\n" #~ "clone WebIP ClusterIP  \\\n" #~ "        meta globally-unique=\"true\" clone-max=\"2\" clone-node-max=\"2\"\n" #~ "clone WebSiteClone WebSite\n" #~ "colocation WebSite-with-WebFS inf: WebSiteClone WebFSClone\n" #~ "colocation fs_on_drbd inf: WebFSClone WebDataClone:Master\n" #~ "colocation website-with-ip inf: WebSiteClone WebIP\n" #~ "order WebFS-after-WebData inf: WebDataClone:promote WebFSClone:start\n" #~ "order WebSite-after-WebFS inf: WebFSClone WebSiteClone\n" #~ "order apache-after-ip inf: WebIP WebSiteClone\n" #~ "property $id=\"cib-bootstrap-options\" \\\n" #~ "        dc-version=\"1.1.5-bdd89e69ba545404d02445be1f3d72e6a203ba2f\" \\\n" #~ "        cluster-infrastructure=\"openais\" \\\n" #~ "        expected-quorum-votes=\"2\" \\\n" #~ "        stonith-enabled=\"false\" \\\n" #~ "        no-quorum-policy=\"ignore\"\n" #~ "rsc_defaults $id=\"rsc-options\" \\\n" #~ "        resource-stickiness=\"100\"\n" #~ " " #~ msgstr "" #~ "\n" #~ "crm(active)# configure show\n" #~ "node pcmk-1\n" #~ "node pcmk-2\n" #~ "primitive WebData ocf:linbit:drbd \\\n" #~ "        params drbd_resource=\"wwwdata\" \\\n" #~ "        op monitor interval=\"60s\"\n" #~ "primitive WebFS ocf:heartbeat:Filesystem \\\n" #~ "        params device=\"/dev/drbd/by-res/wwwdata\" directory=\"/var/www/html\" fstype=\"gfs2\"\n" #~ "primitive WebSite ocf:heartbeat:apache \\\n" #~ "        params configfile=\"/etc/httpd/conf/httpd.conf\" \\\n" #~ "        op monitor interval=\"1min\"\n" #~ "primitive ClusterIP ocf:heartbeat:IPaddr2 \\\n" #~ "        params ip=\"192.168.122.101\" cidr_netmask=\"32\" clusterip_hash=\"sourceip\" \\\n" #~ "        op monitor interval=\"30s\"\n" #~ "ms WebDataClone WebData \\\n" #~ "        meta master-max=\"2\" master-node-max=\"1\" clone-max=\"2\" clone-node-max=\"1\" notify=\"true\"\n" #~ "clone WebFSClone WebFS\n" #~ "clone WebIP ClusterIP  \\\n" #~ "        meta globally-unique=\"true\" clone-max=\"2\" clone-node-max=\"2\"\n" #~ "clone WebSiteClone WebSite\n" #~ "colocation WebSite-with-WebFS inf: WebSiteClone WebFSClone\n" #~ "colocation fs_on_drbd inf: WebFSClone WebDataClone:Master\n" #~ "colocation website-with-ip inf: WebSiteClone WebIP\n" #~ "order WebFS-after-WebData inf: WebDataClone:promote WebFSClone:start\n" #~ "order WebSite-after-WebFS inf: WebFSClone WebSiteClone\n" #~ "order apache-after-ip inf: WebIP WebSiteClone\n" #~ "property $id=\"cib-bootstrap-options\" \\\n" #~ "        dc-version=\"1.1.5-bdd89e69ba545404d02445be1f3d72e6a203ba2f\" \\\n" #~ "        cluster-infrastructure=\"openais\" \\\n" #~ "        expected-quorum-votes=\"2\" \\\n" #~ "        stonith-enabled=\"false\" \\\n" #~ "        no-quorum-policy=\"ignore\"\n" #~ "rsc_defaults $id=\"rsc-options\" \\\n" #~ "        resource-stickiness=\"100\"\n" #~ " " #~ msgid "" #~ "\n" #~ "crm(active)# cib commit active\n" #~ "INFO: commited 'active' shadow CIB to the cluster\n" #~ "crm(active)# quit\n" #~ "bye\n" #~ "[root@pcmk-1 ~]# crm_mon\n" #~ "============\n" #~ "Last updated: Thu Sep  3 21:37:27 2009\n" #~ "Stack: openais\n" #~ "Current DC: pcmk-2 - partition with quorum\n" #~ "Version: 1.1.5-bdd89e69ba545404d02445be1f3d72e6a203ba2f\n" #~ "2 Nodes configured, 2 expected votes\n" #~ "6 Resources configured.\n" #~ "============\n" #~ "\n" #~ "Online: [ pcmk-1 pcmk-2 ]\n" #~ "\n" #~ "Master/Slave Set: WebDataClone\n" #~ "        Masters: [ pcmk-1 pcmk-2 ]\n" #~ "Clone Set: WebIP\n" #~ " Started: [ pcmk-1 pcmk-2 ]\n" #~ "Clone Set: WebFSClone\n" #~ " Started: [ pcmk-1 pcmk-2 ]\n" #~ "Clone Set: WebSiteClone\n" #~ " Started: [ pcmk-1 pcmk-2 ]\n" #~ " " #~ msgstr "" #~ "\n" #~ "crm(active)# cib commit active\n" #~ "INFO: commited 'active' shadow CIB to the cluster\n" #~ "crm(active)# quit\n" #~ "bye\n" #~ "[root@pcmk-1 ~]# crm_mon\n" #~ "============\n" #~ "Last updated: Thu Sep  3 21:37:27 2009\n" #~ "Stack: openais\n" #~ "Current DC: pcmk-2 - partition with quorum\n" #~ "Version: 1.1.5-bdd89e69ba545404d02445be1f3d72e6a203ba2f\n" #~ "2 Nodes configured, 2 expected votes\n" #~ "6 Resources configured.\n" #~ "============\n" #~ "\n" #~ "Online: [ pcmk-1 pcmk-2 ]\n" #~ "\n" #~ "Master/Slave Set: WebDataClone\n" #~ "        Masters: [ pcmk-1 pcmk-2 ]\n" #~ "Clone Set: WebIP\n" #~ " Started: [ pcmk-1 pcmk-2 ]\n" #~ "Clone Set: WebFSClone\n" #~ " Started: [ pcmk-1 pcmk-2 ]\n" #~ "Clone Set: WebSiteClone\n" #~ " Started: [ pcmk-1 pcmk-2 ]\n" #~ " " pacemaker-master/doc/Clusters_from_Scratch/ro-RO/Ch-Active-Passive.po000066400000000000000000001335121217637305600260320ustar00rootroot00000000000000# # AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: Clusters from Scratch 1.1\n" "POT-Creation-Date: 2012-10-17T05:19:03\n" "PO-Revision-Date: 2011-11-22 23:24+0200\n" "Last-Translator: Dan Frîncu \n" "Language-Team: None\n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: application/x-publican; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. Tag: title #, no-c-format msgid "Creating an Active/Passive Cluster" msgstr "Crearea unui Cluster Activ/Pasiv" #. Tag: title #, no-c-format msgid "Exploring the Existing Configuration" msgstr "Explorarea Configurației Existente" #. Tag: para #, no-c-format msgid "When Pacemaker starts up, it automatically records the number and details of the nodes in the cluster as well as which stack is being used and the version of Pacemaker being used." msgstr "Când Pacemaker pornește, înregistrează în mod automat numărul și detaliile nodurilor din cluster la fel ca și care stivă este folosită și care versiune de Pacemaker este folosită." #. Tag: para #, no-c-format msgid "This is what the base configuration should look like." msgstr "Așa ar trebui să arate configurația de bază." #. Tag: programlisting #, no-c-format msgid "" "# pcs status\n" "Last updated: Fri Sep 14 10:12:01 2012\n" "Last change: Fri Sep 14 09:51:55 2012 via crmd on pcmk-2\n" "Stack: corosync\n" "Current DC: pcmk-1 (1) - partition with quorum\n" "Version: 1.1.8-1.el7-60a19ed12fdb4d5c6a6b6767f52e5391e447fec0\n" "2 Nodes configured, unknown expected votes\n" "0 Resources configured.\n" "\n" "Online: [ pcmk-1 pcmk-2 ]\n" "\n" "Full list of resources:" msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "For those that are not of afraid of XML, you can see the raw cluster configuration and status by using the pcs cluster cib command." msgstr "Pentru cei care nu se tem de XML, puteți vedea configurația în stare brută adăugând \"xml\" la comanda anterioară." #. Tag: title #, no-c-format msgid "The last XML you’ll see in this document" msgstr "Ultimul XML pe care îl veți vedea în acest document." #. Tag: programlisting #, no-c-format msgid "# pcs cluster cib" msgstr "" #. Tag: programlisting #, no-c-format msgid "" "<cib epoch=\"4\" num_updates=\"19\" admin_epoch=\"0\" validate-with=\"pacemaker-1.2\" crm_feature_set=\"3.0.6\" update-origin=\"pcmk-1\" update-client=\"crmd\" cib-last-written=\"Wed Aug 1 16:08:52 2012\" have-quorum=\"1\" dc-uuid=\"1\">\n" " <configuration>\n" " <crm_config>\n" " <cluster_property_set id=\"cib-bootstrap-options\">\n" " <nvpair id=\"cib-bootstrap-options-dc-version\" name=\"dc-version\" value=\"1.1.8-1.el7-60a19ed12fdb4d5c6a6b6767f52e5391e447fec0\"/>\n" " <nvpair id=\"cib-bootstrap-options-cluster-infrastructure\" name=\"cluster-infrastructure\" value=\"corosync\"/>\n" " </cluster_property_set>\n" " </crm_config>\n" " <nodes>\n" " <node id=\"1\" uname=\"pcmk-1\" type=\"normal\"/>\n" " <node id=\"2\" uname=\"pcmk-2\" type=\"normal\"/>\n" " </nodes>\n" " <resources/>\n" " <constraints/>\n" " </configuration>\n" " <status>\n" " <node_state id=\"2\" uname=\"pcmk-2\" ha=\"active\" in_ccm=\"true\" crmd=\"online\" join=\"member\" expected=\"member\" crm-debug-origin=\"do_state_transition\" shutdown=\"0\">\n" " <lrm id=\"2\">\n" " <lrm_resources/>\n" " </lrm>\n" " <transient_attributes id=\"2\">\n" " <instance_attributes id=\"status-2\">\n" " <nvpair id=\"status-2-probe_complete\" name=\"probe_complete\" value=\"true\"/>\n" " </instance_attributes>\n" " </transient_attributes>\n" " </node_state>\n" " <node_state id=\"1\" uname=\"pcmk-1\" ha=\"active\" in_ccm=\"true\" crmd=\"online\" join=\"member\" expected=\"member\" crm-debug-origin=\"do_state_transition\" shutdown=\"0\">\n" " <lrm id=\"1\">\n" " <lrm_resources/>\n" " </lrm>\n" " <transient_attributes id=\"1\">\n" " <instance_attributes id=\"status-1\">\n" " <nvpair id=\"status-1-probe_complete\" name=\"probe_complete\" value=\"true\"/>\n" " </instance_attributes>\n" " </transient_attributes>\n" " </node_state>\n" " </status>\n" "</cib>" msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "Before we make any changes, its a good idea to check the validity of the configuration." msgstr "Înainte de a realiza orice modificări, este o idee bună să verificați validitatea configurației." #. Tag: programlisting #, fuzzy, no-c-format msgid "" "# crm_verify -L -V\n" " error: unpack_resources: Resource start-up disabled since no STONITH resources have been defined\n" " error: unpack_resources: Either configure some or disable STONITH with the stonith-enabled option\n" " error: unpack_resources: NOTE: Clusters with shared data need STONITH to ensure data integrity\n" "Errors found during check: config not valid\n" " -V may provide more details" msgstr "" "\n" "[root@pcmk-1 ~]# crm_verify -L\n" "crm_verify[2195]: 2009/08/27_16:57:12 ERROR: unpack_resources: Resource start-up disabled since no STONITH resources have been defined\n" "crm_verify[2195]: 2009/08/27_16:57:12 ERROR: unpack_resources: Either configure some or disable STONITH with the stonith-enabled option\n" "crm_verify[2195]: 2009/08/27_16:57:12 ERROR: unpack_resources: NOTE: Clusters with shared data need STONITH to ensure data integrity\n" "Errors found during check: config not valid\n" "  -V may provide more details\n" "[root@pcmk-1 ~]#\n" #. Tag: para #, no-c-format msgid "As you can see, the tool has found some errors." msgstr "După cum puteți vedea, utilitarul a găsit câteva erori." #. Tag: para #, fuzzy, no-c-format msgid "In order to guarantee the safety of your data If the data is corrupt, there is little point in continuing to make it available , the default for STONITH A common node fencing mechanism. Used to ensure data integrity by powering off \"bad\" nodes in Pacemaker is enabled. However it also knows when no STONITH configuration has been supplied and reports this as a problem (since the cluster would not be able to make progress if a situation requiring node fencing arose)." msgstr "Pentru a garanta siguranța datelor voastre Dacă datele sunt corupte, nu are sens să continuăm să le facem disponibile , Pacemaker este livrat cu STONITH Un mecanism comun de evacuare forțată a nodului. Folosit pentru a asigura integritatea datelor prin închiderea nodurilor \"rele\". activat. Oricum acesta știe de asemenea când nici o configurație STONITH nu a fost furnizată și raportează acest lucru ca pe o problemă (din moment ce clusterul nu ar fi capabil să realizeze progrese dacă ar fi apărut o situație care ar fi necesitat evacuarea forțată a nodului)." #. Tag: para #, no-c-format msgid "For now, we will disable this feature and configure it later in the Configuring STONITH section. It is important to note that the use of STONITH is highly encouraged, turning it off tells the cluster to simply pretend that failed nodes are safely powered off. Some vendors will even refuse to support clusters that have it disabled." msgstr "Momentan, vom dezactiva această funcționalitate și o vom configura mai târziu în secțiunea Configurarea STONITH. Este important de reținut că utilizarea STONITH este puternic încurajată, oprirea acestuia îi spune clusterului să se prefacă pur și simplu că nodurile care au eșuat sunt oprite în siguranță. Unii comercianți vor refuza chiar să ofere suport pentru clustere care îl au dezactivat." #. Tag: para #, fuzzy, no-c-format msgid "To disable STONITH, we set the stonith-enabled cluster option to false." msgstr "Pentru a dezactiva STONITH, setăm opțiunea clusterului stonith-enabled pe false." #. Tag: programlisting #, no-c-format msgid "" "# pcs property set stonith-enabled=false\n" "# crm_verify -L" msgstr "" #. Tag: para #, no-c-format msgid "With the new cluster option set, the configuration is now valid." msgstr "Cu noua opțiune a clusterului setată, configurația este acum validă." #. Tag: para #, fuzzy, no-c-format msgid "The use of stonith-enabled=false is completely inappropriate for a production cluster. We use it here to defer the discussion of its configuration which can differ widely from one installation to the next. See for information on why STONITH is important and details on how to configure it." msgstr "Utilizarea stonith-enabled=false este complet nepotrivită pentru un cluster de producție. O folosim aici pentru a face referință la configurarea acestuia care poate fi foarte diferită de la o instalare la alta. Vedeți pentru informații despre de ce este important STONITH și detalii despre cum să îl configurați." #. Tag: title #, no-c-format msgid "Adding a Resource" msgstr "Adăugarea unei Resurse" #. Tag: para #, fuzzy, no-c-format msgid "The first thing we should do is configure an IP address. Regardless of where the cluster service(s) are running, we need a consistent address to contact them on. Here I will choose and add 192.168.122.120 as the floating address, give it the imaginative name ClusterIP and tell the cluster to check that its running every 30 seconds." msgstr "Primul lucru pe care ar trebui să îl facem este să configurăm o adresă IP. Indiferent de unde rulează serviciul/serviciile de cluster, avem nevoie de o adresa consistentă pe care să le contactăm. Aici voi alege și adăuga 192.168.122.101 ca adresa virtuală, îi vom da numele plin de imaginație ClusterIP și vom spune clusterului să verifice că aceasta rulează la fiecare 30 de secunde." #. Tag: para #, no-c-format msgid "The chosen address must not be one already associated with a physical node" msgstr "Adresa aleasă nu trebuie să fie una deja asociată cu un nod fizic" #. Tag: screen #, fuzzy, no-c-format msgid "" "# pcs resource create ClusterIP ocf:heartbeat:IPaddr2 \\\n" " ip=192.168.0.120 cidr_netmask=32 op monitor interval=30s" msgstr "" "\n" "crm configure primitive ClusterIP ocf:heartbeat:IPaddr2 \\ \n" "        params ip=192.168.122.101 cidr_netmask=32 \\ \n" "        op monitor interval=30s\n" #. Tag: para #, no-c-format msgid "The other important piece of information here is ocf:heartbeat:IPaddr2." msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "This tells Pacemaker three things about the resource you want to add. The first field, ocf, is the standard to which the resource script conforms to and where to find it. The second field is specific to OCF resources and tells the cluster which namespace to find the resource script in, in this case heartbeat. The last field indicates the name of the resource script." msgstr "Cealaltă parte importantă de informație de aici este ocf:heartbeat:IPaddr2. Aceasta îi spune Pacemaker-ului trei lucruri despre resursa pe care doriți să o adăugați. Primul câmp, ocf, este standardul la care aderă scriptul resursei și unde să-l găsiți. Al doilea câmp este specific resurselor OCF și spune clusterului în care namespace să găsească scriptul de resursă, în acest caz heartbeat. Ultimul câmp indică numele scriptului de resursă." #. Tag: para #, fuzzy, no-c-format msgid "To obtain a list of the available resource standards (the ocf part of ocf:heartbeat:IPaddr2), run" msgstr "Pentru a obține o listă a claselor de resurse disponibile, rulați" #. Tag: programlisting #, no-c-format msgid "" "# pcs resource standards\n" "ocf\n" "lsb\n" "service\n" "systemd\n" "stonith" msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "To obtain a list of the available ocf resource providers (the heartbeat part of ocf:heartbeat:IPaddr2), run" msgstr "Pentru a obține o listă a claselor de resurse disponibile, rulați" #. Tag: programlisting #, no-c-format msgid "" "# pcs resource providers\n" "heartbeat\n" "linbit\n" "pacemaker\n" "redhat" msgstr "" #. Tag: para #, no-c-format msgid "Finally, if you want to see all the resource agents available for a specific ocf provider (the IPaddr2 part of ocf:heartbeat:IPaddr2), run" msgstr "" #. Tag: programlisting #, no-c-format msgid "" "# pcs resource agents ocf:heartbeat\n" "AoEtarget\n" "AudibleAlarm\n" "CTDB\n" "ClusterMon\n" "Delay\n" "Dummy\n" ".\n" ". (skipping lots of resources to save space)\n" ".\n" "IPaddr2\n" ".\n" ".\n" ".\n" "symlink\n" "syslog-ng\n" "tomcat\n" "vmware" msgstr "" #. Tag: para #, no-c-format msgid "Now verify that the IP resource has been added and display the cluster’s status to see that it is now active." msgstr "Acum verificați că resursa IP a fost adăugată și listați status-ul clusterului pentru a vedea că acum este activă." #. Tag: programlisting #, no-c-format msgid "" "# pcs status\n" "\n" "Last updated: Fri Sep 14 10:17:00 2012\n" "Last change: Fri Sep 14 10:15:48 2012 via cibadmin on pcmk-1\n" "Stack: corosync\n" "Current DC: pcmk-1 (1) - partition with quorum\n" "Version: 1.1.8-1.el7-60a19ed12fdb4d5c6a6b6767f52e5391e447fec0\n" "2 Nodes configured, unknown expected votes\n" "1 Resources configured.\n" "\n" "Online: [ pcmk-1 pcmk-2 ]\n" "\n" "Full list of resources:\n" "\n" " ClusterIP (ocf::heartbeat:IPaddr2): Started pcmk-1" msgstr "" #. Tag: title #, no-c-format msgid "Perform a Failover" msgstr "Efectuați un Failover" #. Tag: para #, no-c-format msgid "Being a high-availability cluster, we should test failover of our new resource before moving on." msgstr "Fiind un cluster de tip high-availability, ar trebui să testăm failover-ul noii noastre resurse înainte de a merge mai departe." #. Tag: para #, no-c-format msgid "First, find the node on which the IP address is running." msgstr "Întâi, găsiți nodul pe care rulează adresa IP." #. Tag: para #, no-c-format msgid "Shut down Pacemaker and Corosync on that machine." msgstr "Opriți Pacemaker și Corosync pe acea mașină." #. Tag: programlisting #, no-c-format msgid "" "#pcs cluster stop pcmk-1\n" "Stopping Cluster..." msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "Once Corosync is no longer running, go to the other node and check the cluster status." msgstr "Odată ce Corosync nu mai rulează, mergeți pe celălalt nod și verificați status-ul clusterului cu crm_mon." #. Tag: programlisting #, fuzzy, no-c-format msgid "" "# pcs status\n" "\n" "Last updated: Fri Sep 14 10:31:01 2012\n" "Last change: Fri Sep 14 10:15:48 2012 via cibadmin on pcmk-1\n" "Stack: corosync\n" "Current DC: pcmk-2 (2) - partition WITHOUT quorum\n" "Version: 1.1.8-1.el7-60a19ed12fdb4d5c6a6b6767f52e5391e447fec0\n" "2 Nodes configured, unknown expected votes\n" "1 Resources configured.\n" "\n" "Online: [ pcmk-2 ]\n" "OFFLINE: [ pcmk-1 ]\n" "\n" "Full list of resources:\n" "\n" " ClusterIP (ocf::heartbeat:IPaddr2): Stopped" msgstr "" "\n" "[root@pcmk-2 ~]# crm_mon\n" "============\n" "Last updated: Fri Aug 28 15:30:18 2009\n" "Stack: openais\n" "Current DC: pcmk-2 - partition WITHOUT quorum\n" "Version: 1.1.5-bdd89e69ba545404d02445be1f3d72e6a203ba2f\n" "2 Nodes configured, 2 expected votes\n" "1 Resources configured.\n" "============\n" "Online: [ pcmk-2 ]\n" "OFFLINE: [ pcmk-1 ]\n" "\n" "ClusterIP (ocf::heartbeat:IPaddr): Started pcmk-2\n" #. Tag: para #, fuzzy, no-c-format msgid "There are three things to notice about the cluster’s current state. The first is that, as expected, pcmk-1 is now offline. However we can also see that ClusterIP isn’t running anywhere!" msgstr "Sunt trei aspecte de ținut cont în legătură cu starea curentă a clusterului. Primul este acela că, așa cum ne așteptam, pcmk-1 este acum offline. Totodată putem vedea că, ClusterIP nu rulează nicăieri!" #. Tag: title #, no-c-format msgid "Quorum and Two-Node Clusters" msgstr "Quorum și Clusterele Formate din Două Noduri" #. Tag: para #, fuzzy, no-c-format msgid "This is because the cluster no longer has quorum, as can be seen by the text \"partition WITHOUT quorum\" in the status output. In order to reduce the possibility of data corruption, Pacemaker’s default behavior is to stop all resources if the cluster does not have quorum." msgstr "Acest lucru este datorită faptului că, clusterul nu mai are quorum, după cum poate fi observat din textul \"partition WITHOUT quorum\" (ieșind în evidență în verde) în rezultatul de ieșire de mai sus. Pentru a reduce posibilitatea coruperii datelor, comportamentul implicit al Pacemaker-ului este să oprească toate resursele dacă clusterul nu are quorum." #. Tag: para #, no-c-format msgid "A cluster is said to have quorum when more than half the known or expected nodes are online, or for the mathematically inclined, whenever the following equation is true:" msgstr "Un cluster este considerat că are quorum când mai mult de jumătate din nodurile cunoscute sau așteptate sunt online, sau pentru cei cu înclinație către matematică, în orice moment în care ecuația următoare este adevărată:" #. Tag: literallayout #, no-c-format msgid "total_nodes < 2 * active_nodes" msgstr "numărul_total_de_noduri < 2 * numărul_de_noduri_active" #. Tag: para #, fuzzy, no-c-format msgid "Therefore a two-node cluster only has quorum when both nodes are running, which is no longer the case for our cluster. This would normally make the creation of a two-node cluster pointless Actually some would argue that two-node clusters are always pointless, but that is an argument for another time , however it is possible to control how Pacemaker behaves when quorum is lost. In particular, we can tell the cluster to simply ignore quorum altogether." msgstr "Prin urmare un cluster format din două noduri are quorum numai când ambele noduri rulează, ceea ce nu mai este cazul pentru clusterul nostru. Acest lucru ar face în mod normal crearea de clustere formate din două noduri lipsită de sens De altfel, unii ar argumenta că clusterele formate din două noduri sunt întotdeauna lipsite de sens, dar acela este un argument pentru o dată ulterioară. , totuși este posibil să controlăm cum se comportă Pacemaker când quorum-ul este pierdut. În mod particular, putem spune clusterului să ignore pur și simplu quorum-ul în întregime." #. Tag: programlisting #, no-c-format msgid "" "# pcs property set no-quorum-policy=ignore\n" "# pcs property\n" "dc-version: 1.1.8-1.el7-60a19ed12fdb4d5c6a6b6767f52e5391e447fec0\n" "cluster-infrastructure: corosync\n" "stonith-enabled: false\n" "no-quorum-policy: ignore" msgstr "" #. Tag: para #, no-c-format msgid "After a few moments, the cluster will start the IP address on the remaining node. Note that the cluster still does not have quorum." msgstr "După câteva momente, clusterul va porni adresa IP pe nodul rămas. Luați aminte, clusterul încă nu are quorum." #. Tag: programlisting #, fuzzy, no-c-format msgid "" "# pcs status\n" "Last updated: Fri Sep 14 10:38:11 2012\n" "Last change: Fri Sep 14 10:37:53 2012 via cibadmin on pcmk-2\n" "Stack: corosync\n" "Current DC: pcmk-2 (2) - partition WITHOUT quorum\n" "Version: 1.1.8-1.el7-60a19ed12fdb4d5c6a6b6767f52e5391e447fec0\n" "2 Nodes configured, unknown expected votes\n" "1 Resources configured.\n" "\n" "Online: [ pcmk-2 ]\n" "OFFLINE: [ pcmk-1 ]\n" "\n" "Full list of resources:\n" "\n" " ClusterIP (ocf::heartbeat:IPaddr2): Started pcmk-2" msgstr "" "\n" "[root@pcmk-2 ~]# crm_mon\n" "============\n" "Last updated: Fri Aug 28 15:30:18 2009\n" "Stack: openais\n" "Current DC: pcmk-2 - partition WITHOUT quorum\n" "Version: 1.1.5-bdd89e69ba545404d02445be1f3d72e6a203ba2f\n" "2 Nodes configured, 2 expected votes\n" "1 Resources configured.\n" "============\n" "Online: [ pcmk-2 ]\n" "OFFLINE: [ pcmk-1 ]\n" "\n" "ClusterIP (ocf::heartbeat:IPaddr): Started pcmk-2\n" #. Tag: para #, no-c-format msgid "Now simulate node recovery by restarting the cluster stack on pcmk-1 and check the cluster’s status. Note, if you get an authentication error with the pcs cluster start pcmk-1 command, you must authenticate on the node using the pcs cluster auth pcmk pcmk-1 pcmk-2 command discussed earlier." msgstr "" #. Tag: programlisting #, no-c-format msgid "" "# pcs cluster start pcmk-1\n" "Starting Cluster...\n" "# pcs status\n" "\n" "Last updated: Fri Sep 14 10:42:56 2012\n" "Last change: Fri Sep 14 10:37:53 2012 via cibadmin on pcmk-2\n" "Stack: corosync\n" "Current DC: pcmk-2 (2) - partition with quorum\n" "Version: 1.1.8-1.el7-60a19ed12fdb4d5c6a6b6767f52e5391e447fec0\n" "2 Nodes configured, unknown expected votes\n" "1 Resources configured.\n" "\n" "Online: [ pcmk-1 pcmk-2 ]\n" "\n" "Full list of resources:\n" "\n" " ClusterIP (ocf::heartbeat:IPaddr2): Started pcmk-2" msgstr "" #. Tag: para #, no-c-format msgid "In the dark days, the cluster may have moved the IP back to its original location (pcmk-1). Usually this is no longer the case." msgstr "" #. Tag: title #, no-c-format msgid "Prevent Resources from Moving after Recovery" msgstr "Prevenirea Mutării Resurselor după Recuperare" #. Tag: para #, fuzzy, no-c-format msgid "In most circumstances, it is highly desirable to prevent healthy resources from being moved around the cluster. Moving resources almost always requires a period of downtime. For complex services like Oracle databases, this period can be quite long." msgstr "În anumite circumstanțe, este foarte de dorit să se prevină ca resursele sănătoase din a fi mutate prin cluster. Mutarea resurselor necesită aproape întotdeauna o perioadă de nefuncționare. Pentru servicii complexe precum bazele de date Oracle, această perioadă poate fi destul de lungă." #. Tag: para #, fuzzy, no-c-format msgid "To address this, Pacemaker has the concept of resource stickiness which controls how much a service prefers to stay running where it is. You may like to think of it as the \"cost\" of any downtime. By default, Pacemaker assumes there is zero cost associated with moving resources and will do so to achieve \"optimal\" It should be noted that Pacemaker’s definition of optimal may not always agree with that of a human’s. The order in which Pacemaker processes lists of resources and nodes creates implicit preferences in situations where the administrator has not explicitly specified them resource placement. We can specify a different stickiness for every resource, but it is often sufficient to change the default." msgstr "Pentru a adresa acest aspect, Pacemaker are conceptul de adezivitate a resursei care controleaza cât de mult preferă un serviciu să rămână funcțional acolo unde este. Vă puteți gândi la acest aspect ca fiind \"costul\" nefuncționării. În mod implicit, Pacemaker presupune că este un cost zero asociat cu mutarea resurselor și va face acest lucru pentru a atinge plasamentul \"optim Ar trebui să fie notat faptul că definiția Pacemaker-ului pentru optim ar putea să nu fie de acord întotdeauna cu cea a unui om. Ordinea în care Pacemaker procesează listele de resurse și noduri creează preferințe implicite în situații unde administratorul nu le-a specificat în mod explicit. \" al resurselor. Putem specifica o adezivitate diferită pentru fiecare resursă, dar este adeseori suficient să schimbați valoarea implicită." #. Tag: programlisting #, no-c-format msgid "" "# pcs resource rsc defaults resource-stickiness=100\n" "# pcs resource rsc defaults\n" "resource-stickiness: 100" msgstr "" #~ msgid "" #~ "\n" #~ "[root@pcmk-2 ~]# crm configure show\n" #~ "node pcmk-1\n" #~ "node pcmk-2\n" #~ "property $id=\"cib-bootstrap-options\" \\\n" #~ "        dc-version=\"1.1.5-bdd89e69ba545404d02445be1f3d72e6a203ba2f\" \\\n" #~ "        cluster-infrastructure=\"openais\" \\\n" #~ "        expected-quorum-votes=\"2\"\n" #~ msgstr "" #~ "\n" #~ "[root@pcmk-2 ~]# crm configure show\n" #~ "node pcmk-1\n" #~ "node pcmk-2\n" #~ "property $id=\"cib-bootstrap-options\" \\\n" #~ "        dc-version=\"1.1.5-bdd89e69ba545404d02445be1f3d72e6a203ba2f\" \\\n" #~ "        cluster-infrastructure=\"openais\" \\\n" #~ "        expected-quorum-votes=\"2\"\n" #~ msgid "" #~ "\n" #~ "[root@pcmk-2 ~]# crm configure show xml\n" #~ "<?xml version=\"1.0\" ?>\n" #~ "<cib admin_epoch=\"0\" crm_feature_set=\"3.0.1\" dc-uuid=\"pcmk-1\" epoch=\"13\" have-quorum=\"1\" num_updates=\"7\" validate-with=\"pacemaker-1.0\">\n" #~ "  <configuration>\n" #~ "    <crm_config>\n" #~ "      <cluster_property_set id=\"cib-bootstrap-options\">\n" #~ "        <nvpair id=\"cib-bootstrap-options-dc-version\" name=\"dc-version\" value=\"1.1.5-bdd89e69ba545404d02445be1f3d72e6a203ba2f\"/>\n" #~ "        <nvpair id=\"cib-bootstrap-options-cluster-infrastructure\" name=\"cluster-infrastructure\" value=\"openais\"/>\n" #~ "        <nvpair id=\"cib-bootstrap-options-expected-quorum-votes\" name=\"expected-quorum-votes\" value=\"2\"/>\n" #~ "      </cluster_property_set>\n" #~ "    </crm_config>\n" #~ "    <rsc_defaults/>\n" #~ "    <op_defaults/>\n" #~ "    <nodes>\n" #~ "      <node id=\"pcmk-1\" type=\"normal\" uname=\"pcmk-1\"/>\n" #~ "      <node id=\"pcmk-2\" type=\"normal\" uname=\"pcmk-2\"/>\n" #~ "    </nodes>\n" #~ "    <resources/>\n" #~ "    <constraints/>\n" #~ "  </configuration>\n" #~ "</cib>\n" #~ msgstr "" #~ "\n" #~ "[root@pcmk-2 ~]# crm configure show xml\n" #~ "<?xml version=\"1.0\" ?>\n" #~ "<cib admin_epoch=\"0\" crm_feature_set=\"3.0.1\" dc-uuid=\"pcmk-1\" epoch=\"13\" have-quorum=\"1\" num_updates=\"7\" validate-with=\"pacemaker-1.0\">\n" #~ "  <configuration>\n" #~ "    <crm_config>\n" #~ "      <cluster_property_set id=\"cib-bootstrap-options\">\n" #~ "        <nvpair id=\"cib-bootstrap-options-dc-version\" name=\"dc-version\" value=\"1.1.5-bdd89e69ba545404d02445be1f3d72e6a203ba2f\"/>\n" #~ "        <nvpair id=\"cib-bootstrap-options-cluster-infrastructure\" name=\"cluster-infrastructure\" value=\"openais\"/>\n" #~ "        <nvpair id=\"cib-bootstrap-options-expected-quorum-votes\" name=\"expected-quorum-votes\" value=\"2\"/>\n" #~ "      </cluster_property_set>\n" #~ "    </crm_config>\n" #~ "    <rsc_defaults/>\n" #~ "    <op_defaults/>\n" #~ "    <nodes>\n" #~ "      <node id=\"pcmk-1\" type=\"normal\" uname=\"pcmk-1\"/>\n" #~ "      <node id=\"pcmk-2\" type=\"normal\" uname=\"pcmk-2\"/>\n" #~ "    </nodes>\n" #~ "    <resources/>\n" #~ "    <constraints/>\n" #~ "  </configuration>\n" #~ "</cib>\n" #~ msgid "crm configure property stonith-enabled=false" #~ msgstr "crm configure property stonith-enabled=false" #~ msgid "crm_verify -L" #~ msgstr "crm_verify -L" #~ msgid "" #~ "\n" #~ "[root@pcmk-1 ~]# crm ra classes\n" #~ "heartbeat\n" #~ "lsb\n" #~ "ocf / heartbeat pacemaker\n" #~ "stonith\n" #~ msgstr "" #~ "\n" #~ "[root@pcmk-1 ~]# crm ra classes\n" #~ "heartbeat\n" #~ "lsb\n" #~ "ocf / heartbeat pacemaker\n" #~ "stonith\n" #~ msgid "To then find all the OCF resource agents provided by Pacemaker and Heartbeat, run" #~ msgstr "Pentru a găsi mai apoi toți agenții de resursă OCF furnizați de Pacemaker și Heartbeat, rulați" #~ msgid "" #~ "\n" #~ "[root@pcmk-1 ~]# crm ra list ocf pacemaker\n" #~ "ClusterMon     Dummy          Stateful       SysInfo        SystemHealth   controld\n" #~ "ping           pingd          \n" #~ "[root@pcmk-1 ~]# crm ra list ocf heartbeat\n" #~ "AoEtarget              AudibleAlarm           ClusterMon             Delay\n" #~ "Dummy                  EvmsSCC                Evmsd                  Filesystem\n" #~ "ICP                    IPaddr                 IPaddr2                IPsrcaddr\n" #~ "LVM                    LinuxSCSI              MailTo                 ManageRAID\n" #~ "ManageVE               Pure-FTPd              Raid1                  Route\n" #~ "SAPDatabase            SAPInstance            SendArp                ServeRAID\n" #~ "SphinxSearchDaemon     Squid                  Stateful               SysInfo\n" #~ "VIPArip                VirtualDomain          WAS                    WAS6\n" #~ "WinPopup               Xen                    Xinetd                 anything\n" #~ "apache                 db2                    drbd                   eDir88\n" #~ "iSCSILogicalUnit       iSCSITarget            ids                    iscsi\n" #~ "ldirectord             mysql                  mysql-proxy            nfsserver\n" #~ "oracle                 oralsnr                pgsql                  pingd\n" #~ "portblock              rsyncd                 scsi2reservation       sfex\n" #~ "tomcat                 vmware                 \n" #~ "[root@pcmk-1 ~]#\n" #~ msgstr "" #~ "\n" #~ "[root@pcmk-1 ~]# crm ra list ocf pacemaker\n" #~ "ClusterMon     Dummy          Stateful       SysInfo        SystemHealth   controld\n" #~ "ping           pingd          \n" #~ "[root@pcmk-1 ~]# crm ra list ocf heartbeat\n" #~ "AoEtarget              AudibleAlarm           ClusterMon             Delay\n" #~ "Dummy                  EvmsSCC                Evmsd                  Filesystem\n" #~ "ICP                    IPaddr                 IPaddr2                IPsrcaddr\n" #~ "LVM                    LinuxSCSI              MailTo                 ManageRAID\n" #~ "ManageVE               Pure-FTPd              Raid1                  Route\n" #~ "SAPDatabase            SAPInstance            SendArp                ServeRAID\n" #~ "SphinxSearchDaemon     Squid                  Stateful               SysInfo\n" #~ "VIPArip                VirtualDomain          WAS                    WAS6\n" #~ "WinPopup               Xen                    Xinetd                 anything\n" #~ "apache                 db2                    drbd                   eDir88\n" #~ "iSCSILogicalUnit       iSCSITarget            ids                    iscsi\n" #~ "ldirectord             mysql                  mysql-proxy            nfsserver\n" #~ "oracle                 oralsnr                pgsql                  pingd\n" #~ "portblock              rsyncd                 scsi2reservation       sfex\n" #~ "tomcat                 vmware                 \n" #~ "[root@pcmk-1 ~]#\n" #~ msgid "" #~ "\n" #~ "[root@pcmk-1 ~]# crm configure show\n" #~ "node pcmk-1\n" #~ "node pcmk-2\n" #~ "primitive ClusterIP ocf:heartbeat:IPaddr2 \\\n" #~ " params ip=\"192.168.122.101\" cidr_netmask=\"32\" \\\n" #~ " op monitor interval=\"30s\"\n" #~ "property $id=\"cib-bootstrap-options\" \\\n" #~ "        dc-version=\"1.1.5-bdd89e69ba545404d02445be1f3d72e6a203ba2f\" \\\n" #~ "        cluster-infrastructure=\"openais\" \\\n" #~ "        expected-quorum-votes=\"2\" \\\n" #~ "        stonith-enabled=\"false\" \\\n" #~ "[root@pcmk-1 ~]# crm_mon\n" #~ "============\n" #~ "Last updated: Fri Aug 28 15:23:48 2009\n" #~ "Stack: openais\n" #~ "Current DC: pcmk-1 - partition with quorum\n" #~ "Version: 1.1.5-bdd89e69ba545404d02445be1f3d72e6a203ba2f\n" #~ "2 Nodes configured, 2 expected votes\n" #~ "1 Resources configured.\n" #~ "============\n" #~ "\n" #~ "Online: [ pcmk-1 pcmk-2 ]\n" #~ "ClusterIP (ocf::heartbeat:IPaddr): Started pcmk-1\n" #~ msgstr "" #~ "\n" #~ "[root@pcmk-1 ~]# crm configure show\n" #~ "node pcmk-1\n" #~ "node pcmk-2\n" #~ "primitive ClusterIP ocf:heartbeat:IPaddr2 \\\n" #~ " params ip=\"192.168.122.101\" cidr_netmask=\"32\" \\\n" #~ " op monitor interval=\"30s\"\n" #~ "property $id=\"cib-bootstrap-options\" \\\n" #~ "        dc-version=\"1.1.5-bdd89e69ba545404d02445be1f3d72e6a203ba2f\" \\\n" #~ "        cluster-infrastructure=\"openais\" \\\n" #~ "        expected-quorum-votes=\"2\" \\\n" #~ "        stonith-enabled=\"false\" \\\n" #~ "[root@pcmk-1 ~]# crm_mon\n" #~ "============\n" #~ "Last updated: Fri Aug 28 15:23:48 2009\n" #~ "Stack: openais\n" #~ "Current DC: pcmk-1 - partition with quorum\n" #~ "Version: 1.1.5-bdd89e69ba545404d02445be1f3d72e6a203ba2f\n" #~ "2 Nodes configured, 2 expected votes\n" #~ "1 Resources configured.\n" #~ "============\n" #~ "\n" #~ "Online: [ pcmk-1 pcmk-2 ]\n" #~ "ClusterIP (ocf::heartbeat:IPaddr): Started pcmk-1\n" #~ msgid "" #~ "\n" #~ "[root@pcmk-1 ~]# crm resource status ClusterIP\n" #~ "resource ClusterIP is running on: pcmk-1\n" #~ "[root@pcmk-1 ~]#\n" #~ msgstr "" #~ "\n" #~ "[root@pcmk-1 ~]# crm resource status ClusterIP\n" #~ "resource ClusterIP is running on: pcmk-1\n" #~ "[root@pcmk-1 ~]#\n" #~ msgid "" #~ "\n" #~ "[root@pcmk-1 ~]# ssh pcmk-1 -- /etc/init.d/pacemaker stop\n" #~ "Signaling Pacemaker Cluster Manager to terminate: [ OK ]\n" #~ "Waiting for cluster services to unload:. [ OK ]\n" #~ "[root@pcmk-1 ~]# ssh pcmk-1 -- /etc/init.d/corosync stop\n" #~ "Stopping Corosync Cluster Engine (corosync): [ OK ]\n" #~ "Waiting for services to unload: [ OK ]\n" #~ "[root@pcmk-1 ~]#\n" #~ msgstr "" #~ "\n" #~ "[root@pcmk-1 ~]# ssh pcmk-1 -- /etc/init.d/pacemaker stop\n" #~ "Signaling Pacemaker Cluster Manager to terminate: [ OK ]\n" #~ "Waiting for cluster services to unload:. [ OK ]\n" #~ "[root@pcmk-1 ~]# ssh pcmk-1 -- /etc/init.d/corosync stop\n" #~ "Stopping Corosync Cluster Engine (corosync): [ OK ]\n" #~ "Waiting for services to unload: [ OK ]\n" #~ "[root@pcmk-1 ~]#\n" #~ msgid "" #~ "\n" #~ "[root@pcmk-2 ~]# crm_mon\n" #~ "============\n" #~ "Last updated: Fri Aug 28 15:27:35 2009\n" #~ "Stack: openais\n" #~ "Current DC: pcmk-2 - partition WITHOUT quorum\n" #~ "Version: 1.1.5-bdd89e69ba545404d02445be1f3d72e6a203ba2f\n" #~ "2 Nodes configured, 2 expected votes\n" #~ "1 Resources configured.\n" #~ "============\n" #~ "\n" #~ "Online: [ pcmk-2 ]\n" #~ "OFFLINE: [ pcmk-1 ]\n" #~ msgstr "" #~ "\n" #~ "[root@pcmk-2 ~]# crm_mon\n" #~ "============\n" #~ "Last updated: Fri Aug 28 15:27:35 2009\n" #~ "Stack: openais\n" #~ "Current DC: pcmk-2 - partition WITHOUT quorum\n" #~ "Version: 1.1.5-bdd89e69ba545404d02445be1f3d72e6a203ba2f\n" #~ "2 Nodes configured, 2 expected votes\n" #~ "1 Resources configured.\n" #~ "============\n" #~ "\n" #~ "Online: [ pcmk-2 ]\n" #~ "OFFLINE: [ pcmk-1 ]\n" #~ msgid "" #~ "\n" #~ "[root@pcmk-1 ~]# crm configure property no-quorum-policy=ignore\n" #~ "[root@pcmk-1 ~]# crm configure show \n" #~ "node pcmk-1\n" #~ "node pcmk-2\n" #~ "primitive ClusterIP ocf:heartbeat:IPaddr2 \\\n" #~ "        params ip=\"192.168.122.101\" cidr_netmask=\"32\" \\\n" #~ "        op monitor interval=\"30s\"\n" #~ "property $id=\"cib-bootstrap-options\" \\\n" #~ "        dc-version=\"1.1.5-bdd89e69ba545404d02445be1f3d72e6a203ba2f\" \\\n" #~ "        cluster-infrastructure=\"openais\" \\\n" #~ "        expected-quorum-votes=\"2\" \\\n" #~ "        stonith-enabled=\"false\" \\\n" #~ "        no-quorum-policy=\"ignore\"\n" #~ msgstr "" #~ "\n" #~ "[root@pcmk-1 ~]# crm configure property no-quorum-policy=ignore\n" #~ "[root@pcmk-1 ~]# crm configure show \n" #~ "node pcmk-1\n" #~ "node pcmk-2\n" #~ "primitive ClusterIP ocf:heartbeat:IPaddr2 \\\n" #~ "        params ip=\"192.168.122.101\" cidr_netmask=\"32\" \\\n" #~ "        op monitor interval=\"30s\"\n" #~ "property $id=\"cib-bootstrap-options\" \\\n" #~ "        dc-version=\"1.1.5-bdd89e69ba545404d02445be1f3d72e6a203ba2f\" \\\n" #~ "        cluster-infrastructure=\"openais\" \\\n" #~ "        expected-quorum-votes=\"2\" \\\n" #~ "        stonith-enabled=\"false\" \\\n" #~ "        no-quorum-policy=\"ignore\"\n" #~ msgid "Now simulate node recovery by restarting the cluster stack on pcmk-1 and check the cluster’s status." #~ msgstr "Acum simulați recuperarea nodului restartând stiva de cluster pe pcmk-1 și verificați status-ul clusterului." #~ msgid "" #~ "\n" #~ "[root@pcmk-1 ~]# /etc/init.d/corosync start\n" #~ "Starting Corosync Cluster Engine (corosync): [ OK ] \n" #~ "[root@pcmk-1 ~]# /etc/init.d/pacemaker start\n" #~ "Starting Pacemaker Cluster Manager: [ OK ]\n" #~ "[root@pcmk-1 ~]# crm_mon\n" #~ "============\n" #~ "Last updated: Fri Aug 28 15:32:13 2009\n" #~ "Stack: openais\n" #~ "Current DC: pcmk-2 - partition with quorum\n" #~ "Version: 1.1.5-bdd89e69ba545404d02445be1f3d72e6a203ba2f\n" #~ "2 Nodes configured, 2 expected votes\n" #~ "1 Resources configured.\n" #~ "============\n" #~ "Online: [ pcmk-1 pcmk-2 ]\n" #~ "\n" #~ "ClusterIP        (ocf::heartbeat:IPaddr):        Started pcmk-1\n" #~ msgstr "" #~ "\n" #~ "[root@pcmk-1 ~]# /etc/init.d/corosync start\n" #~ "Starting Corosync Cluster Engine (corosync): [ OK ] \n" #~ "[root@pcmk-1 ~]# /etc/init.d/pacemaker start\n" #~ "Starting Pacemaker Cluster Manager: [ OK ]\n" #~ "[root@pcmk-1 ~]# crm_mon\n" #~ "============\n" #~ "Last updated: Fri Aug 28 15:32:13 2009\n" #~ "Stack: openais\n" #~ "Current DC: pcmk-2 - partition with quorum\n" #~ "Version: 1.1.5-bdd89e69ba545404d02445be1f3d72e6a203ba2f\n" #~ "2 Nodes configured, 2 expected votes\n" #~ "1 Resources configured.\n" #~ "============\n" #~ "Online: [ pcmk-1 pcmk-2 ]\n" #~ "\n" #~ "ClusterIP        (ocf::heartbeat:IPaddr):        Started pcmk-1\n" #~ msgid "Here we see something that some may consider surprising, the IP is back running at its original location!" #~ msgstr "Aici putem vedea ceva ce unii ar putea considera surprinzător, IP-ul rulează înapoi pe locația sa originală!" #~ msgid "" #~ "\n" #~ "[root@pcmk-2 ~]# crm configure rsc_defaults resource-stickiness=100\n" #~ "[root@pcmk-2 ~]# crm configure show\n" #~ "node pcmk-1\n" #~ "node pcmk-2\n" #~ "primitive ClusterIP ocf:heartbeat:IPaddr2 \\\n" #~ "        params ip=\"192.168.122.101\" cidr_netmask=\"32\" \\\n" #~ "        op monitor interval=\"30s\"\n" #~ "property $id=\"cib-bootstrap-options\" \\\n" #~ "        dc-version=\"1.1.5-bdd89e69ba545404d02445be1f3d72e6a203ba2f\" \\\n" #~ "        cluster-infrastructure=\"openais\" \\\n" #~ "        expected-quorum-votes=\"2\" \\\n" #~ "        stonith-enabled=\"false\" \\\n" #~ "        no-quorum-policy=\"ignore\"\n" #~ "rsc_defaults $id=\"rsc-options\" \\\n" #~ " resource-stickiness=\"100\"\n" #~ msgstr "" #~ "\n" #~ "[root@pcmk-2 ~]# crm configure rsc_defaults resource-stickiness=100\n" #~ "[root@pcmk-2 ~]# crm configure show\n" #~ "node pcmk-1\n" #~ "node pcmk-2\n" #~ "primitive ClusterIP ocf:heartbeat:IPaddr2 \\\n" #~ "        params ip=\"192.168.122.101\" cidr_netmask=\"32\" \\\n" #~ "        op monitor interval=\"30s\"\n" #~ "property $id=\"cib-bootstrap-options\" \\\n" #~ "        dc-version=\"1.1.5-bdd89e69ba545404d02445be1f3d72e6a203ba2f\" \\\n" #~ "        cluster-infrastructure=\"openais\" \\\n" #~ "        expected-quorum-votes=\"2\" \\\n" #~ "        stonith-enabled=\"false\" \\\n" #~ "        no-quorum-policy=\"ignore\"\n" #~ "rsc_defaults $id=\"rsc-options\" \\\n" #~ " resource-stickiness=\"100\"\n" #~ msgid "If we now retry the failover test, we see that as expected ClusterIP still moves to pcmk-2 when pcmk-1 is taken offline." #~ msgstr "Dacă încercăm din nou acum testul de failover, vedem că așa cum este de așteptat ClusterIP se mută în continuare pe pcmk-2 când pcmk-1 este trecut offline." #~ msgid "" #~ "\n" #~ "[root@pcmk-1 ~]# ssh pcmk-1 -- /etc/init.d/pacemaker stop\n" #~ "Signaling Pacemaker Cluster Manager to terminate: [ OK ]\n" #~ "Waiting for cluster services to unload:. [ OK ]\n" #~ "[root@pcmk-1 ~]# ssh pcmk-1 -- /etc/init.d/corosync stop\n" #~ "Stopping Corosync Cluster Engine (corosync):               [  OK  ]\n" #~ "Waiting for services to unload:                            [  OK  ]\n" #~ "[root@pcmk-1 ~]# ssh pcmk-2 -- crm_mon -1\n" #~ "============\n" #~ "Last updated: Fri Aug 28 15:39:38 2009\n" #~ "Stack: openais\n" #~ "Current DC: pcmk-2 - partition WITHOUT quorum\n" #~ "Version: 1.1.5-bdd89e69ba545404d02445be1f3d72e6a203ba2f\n" #~ "2 Nodes configured, 2 expected votes\n" #~ "1 Resources configured.\n" #~ "============\n" #~ "\n" #~ "Online: [ pcmk-2 ]\n" #~ "OFFLINE: [ pcmk-1 ]\n" #~ "\n" #~ "ClusterIP        (ocf::heartbeat:IPaddr):        Started pcmk-2\n" #~ msgstr "" #~ "\n" #~ "[root@pcmk-1 ~]# ssh pcmk-1 -- /etc/init.d/pacemaker stop\n" #~ "Signaling Pacemaker Cluster Manager to terminate: [ OK ]\n" #~ "Waiting for cluster services to unload:. [ OK ]\n" #~ "[root@pcmk-1 ~]# ssh pcmk-1 -- /etc/init.d/corosync stop\n" #~ "Stopping Corosync Cluster Engine (corosync):               [  OK  ]\n" #~ "Waiting for services to unload:                            [  OK  ]\n" #~ "[root@pcmk-1 ~]# ssh pcmk-2 -- crm_mon -1\n" #~ "============\n" #~ "Last updated: Fri Aug 28 15:39:38 2009\n" #~ "Stack: openais\n" #~ "Current DC: pcmk-2 - partition WITHOUT quorum\n" #~ "Version: 1.1.5-bdd89e69ba545404d02445be1f3d72e6a203ba2f\n" #~ "2 Nodes configured, 2 expected votes\n" #~ "1 Resources configured.\n" #~ "============\n" #~ "\n" #~ "Online: [ pcmk-2 ]\n" #~ "OFFLINE: [ pcmk-1 ]\n" #~ "\n" #~ "ClusterIP        (ocf::heartbeat:IPaddr):        Started pcmk-2\n" #~ msgid "However when we bring pcmk-1 back online, ClusterIP now remains running on pcmk-2." #~ msgstr "Însă când aducem pcmk-1 înapoi online, ClusterIP acum rămâne în funcționare pe pcmk-2." #~ msgid "" #~ "\n" #~ "[root@pcmk-1 ~]# /etc/init.d/corosync start\n" #~ "Starting Corosync Cluster Engine (corosync): [ OK ]\n" #~ "[root@pcmk-1 ~]# /etc/init.d/pacemaker start\n" #~ "Starting Pacemaker Cluster Manager: [ OK ]\n" #~ "[root@pcmk-1 ~]# crm_mon\n" #~ "============\n" #~ "Last updated: Fri Aug 28 15:41:23 2009\n" #~ "Stack: openais\n" #~ "Current DC: pcmk-2 - partition with quorum\n" #~ "Version: 1.1.5-bdd89e69ba545404d02445be1f3d72e6a203ba2f\n" #~ "2 Nodes configured, 2 expected votes\n" #~ "1 Resources configured.\n" #~ "============\n" #~ "\n" #~ "Online: [ pcmk-1 pcmk-2 ]\n" #~ "\n" #~ "ClusterIP        (ocf::heartbeat:IPaddr):        Started pcmk-2\n" #~ msgstr "" #~ "\n" #~ "[root@pcmk-1 ~]# /etc/init.d/corosync start\n" #~ "Starting Corosync Cluster Engine (corosync): [ OK ]\n" #~ "[root@pcmk-1 ~]# /etc/init.d/pacemaker start\n" #~ "Starting Pacemaker Cluster Manager: [ OK ]\n" #~ "[root@pcmk-1 ~]# crm_mon\n" #~ "============\n" #~ "Last updated: Fri Aug 28 15:41:23 2009\n" #~ "Stack: openais\n" #~ "Current DC: pcmk-2 - partition with quorum\n" #~ "Version: 1.1.5-bdd89e69ba545404d02445be1f3d72e6a203ba2f\n" #~ "2 Nodes configured, 2 expected votes\n" #~ "1 Resources configured.\n" #~ "============\n" #~ "\n" #~ "Online: [ pcmk-1 pcmk-2 ]\n" #~ "\n" #~ "ClusterIP        (ocf::heartbeat:IPaddr):        Started pcmk-2\n" pacemaker-master/doc/Clusters_from_Scratch/ro-RO/Ch-Apache.po000066400000000000000000001636111217637305600243730ustar00rootroot00000000000000# # AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: Clusters from Scratch 1.1\n" "POT-Creation-Date: 2012-10-17T05:19:03\n" "PO-Revision-Date: 2011-11-24 00:51+0200\n" "Last-Translator: Dan Frîncu \n" "Language-Team: None\n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: application/x-publican; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. Tag: title #, no-c-format msgid "Apache - Adding More Services" msgstr "Apache - Adăugarea mai Multor Servicii" #. Tag: title #, no-c-format msgid "Forward" msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "Now that we have a basic but functional active/passive two-node cluster, we’re ready to add some real services. We’re going to start with Apache because its a feature of many clusters and relatively simple to configure." msgstr "Acum că avem un cluster de bază, funcțional, activ/pasiv format din două noduri, suntem pregătiți să adăugăm câteva servicii reale. O să începem cu Apache deoarece este o caracteristică a multor clustere și este relativ simplu de configurat." #. Tag: title #, no-c-format msgid "Installation" msgstr "Instalare" #. Tag: para #, fuzzy, no-c-format msgid "Before continuing, we need to make sure Apache is installed on both hosts. We also need the wget tool in order for the cluster to be able to check the status of the Apache server." msgstr "De asemenea, avem nevoie de utilitarul wget pentru ca și clusterul să fie capabil să verifice status-ul serverului Apache." #. Tag: programlisting #, no-c-format msgid "# yum install -y httpd wget" msgstr "" #. Tag: literallayout #, no-c-format msgid "" "Loaded plugins: langpacks, presto, refresh-packagekit\n" "fedora/metalink | 2.6 kB 00:00\n" "updates/metalink | 3.2 kB 00:00\n" "updates-testing/metalink | 41 kB 00:00\n" "Resolving Dependencies\n" "--> Running transaction check\n" "---> Package httpd.x86_64 0:2.2.22-3.fc17 will be installed\n" "--> Processing Dependency: httpd-tools = 2.2.22-3.fc17 for package: httpd-2.2.22-3.fc17.x86_64\n" "--> Processing Dependency: apr-util-ldap for package: httpd-2.2.22-3.fc17.x86_64\n" "--> Processing Dependency: libaprutil-1.so.0()(64bit) for package: httpd-2.2.22-3.fc17.x86_64\n" "--> Processing Dependency: libapr-1.so.0()(64bit) for package: httpd-2.2.22-3.fc17.x86_64\n" "--> Running transaction check\n" "---> Package apr.x86_64 0:1.4.6-1.fc17 will be installed\n" "---> Package apr-util.x86_64 0:1.4.1-2.fc17 will be installed\n" "---> Package apr-util-ldap.x86_64 0:1.4.1-2.fc17 will be installed\n" "---> Package httpd-tools.x86_64 0:2.2.22-3.fc17 will be installed\n" "--> Finished Dependency Resolution\n" "\n" "Dependencies Resolved\n" "\n" "=====================================================================================\n" " Package Arch Version Repository Size\n" "=====================================================================================\n" "Installing:\n" " httpd x86_64 2.2.22-3.fc17 updates-testing 823 k\n" " wget x86_64 1.13.4-2.fc17 fedora 495 k\n" "Installing for dependencies:\n" " apr x86_64 1.4.6-1.fc17 fedora 99 k\n" " apr-util x86_64 1.4.1-2.fc17 fedora 78 k\n" " apr-util-ldap x86_64 1.4.1-2.fc17 fedora 17 k\n" " httpd-tools x86_64 2.2.22-3.fc17 updates-testing 74 k\n" "\n" "Transaction Summary\n" "=====================================================================================\n" "Install 1 Package (+4 Dependent packages)\n" "\n" "Total download size: 1.1 M\n" "Installed size: 3.5 M\n" "Downloading Packages:\n" "(1/6): apr-1.4.6-1.fc17.x86_64.rpm | 99 kB 00:00\n" "(2/6): apr-util-1.4.1-2.fc17.x86_64.rpm | 78 kB 00:00\n" "(3/6): apr-util-ldap-1.4.1-2.fc17.x86_64.rpm | 17 kB 00:00\n" "(4/6): httpd-2.2.22-3.fc17.x86_64.rpm | 823 kB 00:01\n" "(5/6): httpd-tools-2.2.22-3.fc17.x86_64.rpm | 74 kB 00:00\n" "(6/6): wget-1.13.4-2.fc17.x86_64.rpm | 495 kB 00:01\n" "-------------------------------------------------------------------------------------\n" "Total 238 kB/s | 1.1 MB 00:04\n" "Running Transaction Check\n" "Running Transaction Test\n" "Transaction Test Succeeded\n" "Running Transaction\n" " Installing : apr-1.4.6-1.fc17.x86_64 1/6\n" " Installing : apr-util-1.4.1-2.fc17.x86_64 2/6\n" " Installing : apr-util-ldap-1.4.1-2.fc17.x86_64 3/6\n" " Installing : httpd-tools-2.2.22-3.fc17.x86_64 4/6\n" " Installing : httpd-2.2.22-3.fc17.x86_64 5/6\n" " Installing : wget-1.13.4-2.fc17.x86_64 6/6\n" " Verifying : apr-util-ldap-1.4.1-2.fc17.x86_64 1/6\n" " Verifying : httpd-tools-2.2.22-3.fc17.x86_64 2/6\n" " Verifying : apr-util-1.4.1-2.fc17.x86_64 3/6\n" " Verifying : apr-1.4.6-1.fc17.x86_64 4/6\n" " Verifying : httpd-2.2.22-3.fc17.x86_64 5/6\n" " Verifying : wget-1.13.4-2.fc17.x86_64 6/6\n" "\n" "Installed:\n" " httpd.x86_64 0:2.2.22-3.fc17 wget.x86_64 0:1.13.4-2.fc17\n" "\n" "Dependency Installed:\n" " apr.x86_64 0:1.4.6-1.fc17 apr-util.x86_64 0:1.4.1-2.fc17\n" " apr-util-ldap.x86_64 0:1.4.1-2.fc17 httpd-tools.x86_64 0:2.2.22-3.fc17\n" "\n" "Complete!" msgstr "" #. Tag: title #, no-c-format msgid "Preparation" msgstr "Pregătire" #. Tag: para #, no-c-format msgid "First we need to create a page for Apache to serve up. On Fedora the default Apache docroot is /var/www/html, so we’ll create an index file there." msgstr "Mai întâi trebuie să creem o pagină pe care Apache să o servească. Pe Fedora docroot-ul implicit al Apache-ului este în /var/www/html, așa că vom crea un fișier index acolo." #. Tag: programlisting #, fuzzy, no-c-format msgid "" "# cat <<-END >/var/www/html/index.html\n" " <html>\n" " <body>My Test Site - pcmk-1</body>\n" " </html>\n" "END" msgstr "" "\n" "[root@pcmk-1 ~]# cat <<-END >/var/www/html/index.html\n" " <html>\n" " <body>My Test Site - pcmk-1</body>\n" " </html>\n" " END\n" "[root@pcmk-1 ~]#\n" #. Tag: para #, no-c-format msgid "For the moment, we will simplify things by serving up only a static site and manually sync the data between the two nodes. So run the command again on pcmk-2." msgstr "Pentru moment, vom simplifica lucrurile servind doar un site static și vom sincroniza manual datele între cele două noduri. Așa că rulați comanda din nou pe pcmk-2." #. Tag: programlisting #, fuzzy, no-c-format msgid "" "[root@pcmk-2 ~]# cat <<-END >/var/www/html/index.html <html>\n" " <body>My Test Site - pcmk-2</body>\n" " </html>\n" " END" msgstr "" "\n" "[root@pcmk-2 ~]# cat <<-END >/var/www/html/index.html\n" " <html>\n" " <body>My Test Site - pcmk-2</body>\n" " </html>\n" " END\n" "[root@pcmk-2 ~]#\n" #. Tag: title #, no-c-format msgid "Enable the Apache status URL" msgstr "Activați status URL-ul Apache-ului" #. Tag: para #, fuzzy, no-c-format msgid "In order to monitor the health of your Apache instance, and recover it if it fails, the resource agent used by Pacemaker assumes the server-status URL is available. Look for the following in /etc/httpd/conf/httpd.conf and make sure it is not disabled or commented out:" msgstr "Pentru a monitoriza sănătatea instanței voastre de Apache și pentru a o recupera dacă eșuează, agentul de resursă folosit de Pacemaker presupune că URL-ul server-status este disponibil. Uitați-vă după următoarele în /etc/httpd/conf/httpd.conf și asigurați-vă că nu este dezactivat sau comentat." #. Tag: programlisting #, fuzzy, no-c-format msgid "" "<Location /server-status>\n" " SetHandler server-status\n" " Order deny,allow\n" " Deny from all\n" " Allow from 127.0.0.1\n" "</Location>" msgstr "" "\n" "<Location /server-status>\n" " SetHandler server-status\n" " Order deny,allow\n" " Deny from all\n" " Allow from 127.0.0.1\n" "</Location>\n" "\t " #. Tag: title #, no-c-format msgid "Update the Configuration" msgstr "Actualizarea Configurației" #. Tag: para #, fuzzy, no-c-format msgid "At this point, Apache is ready to go, all that needs to be done is to add it to the cluster. Lets call the resource WebSite. We need to use an OCF script called apache in the heartbeat namespace Compare the key used here ocf:heartbeat:apache with the one we used earlier for the IP address: ocf:heartbeat:IPaddr2 , the only required parameter is the path to the main Apache configuration file and we’ll tell the cluster to check once a minute that apache is still running." msgstr "La acest punct, Apache este gata de pornire, tot ce trebuie făcut este să îl adăugăm la cluster. Să denumim resursa WebSite. Avem nevoie să folosim un script OCF numit apache din namespace-ul Comparați cheia folosită aici, ocf:heartbeart:apache, cu cea folosită anterior pentru adresa IP: ocf:heartbeat:IPaddr2 heartbeat, singurul parametru necesar este calea către fișierul principal de configurare al Apache și vom spune clusterului să verifice o dată pe minut că apache încă funcționează." #. Tag: screen #, no-c-format msgid "" "pcs resource create WebSite ocf:heartbeat:apache \\\n" " configfile=/etc/httpd/conf/httpd.conf \\\n" " statusurl=\"http://localhost/server-status\" op monitor interval=1min" msgstr "" #. Tag: para #, no-c-format msgid "By default, the operation timeout for all resource’s start, stop, and monitor operations is 20 seconds. In many cases this timeout period is less than the advised timeout period. For the purposes of this tutorial, we will adjust the global operation timeout default to 240 seconds." msgstr "" #. Tag: programlisting #, no-c-format msgid "" "# pcs resource op defaults timeout=240s\n" "# pcs resource op defaults\n" "timeout: 240s" msgstr "" #. Tag: para #, no-c-format msgid "After a short delay, we should see the cluster start apache" msgstr "După o scurtă întârziere, ar trebui să vedem clusterul pornind apache-ul" #. Tag: programlisting #, fuzzy, no-c-format msgid "" "# pcs status\n" "\n" "Last updated: Fri Sep 14 10:51:27 2012\n" "Last change: Fri Sep 14 10:50:46 2012 via crm_attribute on pcmk-1\n" "Stack: corosync\n" "Current DC: pcmk-2 (2) - partition with quorum\n" "Version: 1.1.8-1.el7-60a19ed12fdb4d5c6a6b6767f52e5391e447fec0\n" "2 Nodes configured, unknown expected votes\n" "2 Resources configured.\n" "\n" "Online: [ pcmk-1 pcmk-2 ]\n" "\n" "Full list of resources:\n" "\n" " ClusterIP (ocf::heartbeat:IPaddr2): Started pcmk-2\n" " WebSite (ocf::heartbeat:apache): Started pcmk-1" msgstr "" "\n" "[root@pcmk-1 ~]# crm_mon\n" "============\n" "Last updated: Fri Aug 28 16:12:49 2009\n" "Stack: openais\n" "Current DC: pcmk-2 - partition with quorum\n" "Version: 1.1.5-bdd89e69ba545404d02445be1f3d72e6a203ba2f\n" "2 Nodes configured, 2 expected votes\n" "2 Resources configured.\n" "============\n" "\n" "Online: [ pcmk-1 pcmk-2 ]\n" "\n" "ClusterIP        (ocf::heartbeat:IPaddr):        Started pcmk-2\n" "WebSite        (ocf::heartbeat:apache):        Started pcmk-1\n" #. Tag: para #, no-c-format msgid "Wait a moment, the WebSite resource isn’t running on the same host as our IP address!" msgstr "Așteptați un moment, resursa WebSite nu rulează pe aceeași gazdă ca și adresa noastră IP!" #. Tag: para #, no-c-format msgid "If, in the pcs status output, you see the WebSite resource has failed to start, then you’ve likely not enabled the status URL correctly. You can check if this is the problem by running:" msgstr "" #. Tag: literallayout #, no-c-format msgid "wget http://127.0.0.1/server-status" msgstr "" #. Tag: para #, no-c-format msgid "If you see Connection refused in the output, then this is indeed the problem. Check to ensure that Allow from 127.0.0.1 is present for the <Location /server-status> block." msgstr "" #. Tag: title #, no-c-format msgid "Ensuring Resources Run on the Same Host" msgstr "Asigurarea că Resursele Rulează pe Aceeași Gazdă" #. Tag: para #, no-c-format msgid "To reduce the load on any one machine, Pacemaker will generally try to spread the configured resources across the cluster nodes. However we can tell the cluster that two resources are related and need to run on the same host (or not at all). Here we instruct the cluster that WebSite can only run on the host that ClusterIP is active on." msgstr "Pentru a reduce nivelul de încărcare pe oricare din mașini, Pacemaker va încerca în mod general să împrăștie resursele configurate de-a lungul nodurilor din cluster. Totuși putem spune clusterului că două resurse au legătura una cu cealaltă și trebuie să ruleze pe aceeași gazdă (sau să nu ruleze deloc). Aici instruim clusterul că WebSite poate rula numar pe o gazdă pe care este activ ClusterIP." #. Tag: para #, no-c-format msgid "To achieve this we use a colocation constraint that indicates it is mandatory for WebSite to run on the same node as ClusterIP. The \"mandatory\" part of the colocation constraint is indicated by using a score of INFINITY. The INFINITY score also means that if ClusterIP is not active anywhere, WebSite will not be permitted to run." msgstr "" #. Tag: para #, no-c-format msgid "If ClusterIP is not active anywhere, WebSite will not be permitted to run anywhere." msgstr "Dacă ClusterIP nu este activ nicăieri, lui WebSite nu i se va permite să ruleze nicăieri." #. Tag: para #, fuzzy, no-c-format msgid "Colocation constraints are \"directional\", in that they imply certain things about the order in which the two resources will have a location chosen. In this case we’re saying WebSite needs to be placed on the same machine as ClusterIP, this implies that we must know the location of ClusterIP before choosing a location for WebSite." msgstr "Restricțiile de colocare sunt \"direcționale\", în sensul că implică anumite lucruri despre ordinea în care celor două resurse li se va alege o locație. În acest caz spunem că WebSite are nevoie să fie plasat pe aceeași mașină ca și ClusterIP, acest lucru implică faptul că noi trebuie să știm locația lui ClusterIP înainte de a alege o locație pentru WebSite." #. Tag: programlisting #, no-c-format msgid "" "# pcs constraint colocation add WebSite ClusterIP INFINITY\n" "# pcs constraint\n" "Location Constraints:\n" "Ordering Constraints:\n" "Colocation Constraints:\n" " WebSite with ClusterIP\n" "# pcs status\n" "\n" "Last updated: Fri Sep 14 11:00:44 2012\n" "Last change: Fri Sep 14 11:00:25 2012 via cibadmin on pcmk-1\n" "Stack: corosync\n" "Current DC: pcmk-2 (2) - partition with quorum\n" "Version: 1.1.8-1.el7-60a19ed12fdb4d5c6a6b6767f52e5391e447fec0\n" "2 Nodes configured, unknown expected votes\n" "2 Resources configured.\n" "\n" "Online: [ pcmk-1 pcmk-2 ]\n" "\n" "Full list of resources:\n" "\n" " ClusterIP (ocf::heartbeat:IPaddr2): Started pcmk-2\n" " WebSite (ocf::heartbeat:apache): Started pcmk-2" msgstr "" #. Tag: title #, no-c-format msgid "Controlling Resource Start/Stop Ordering" msgstr "Controlarea Ordinii de Pornire/Oprire a Resursei" #. Tag: para #, fuzzy, no-c-format msgid "When Apache starts, it binds to the available IP addresses. It doesn’t know about any addresses we add afterwards, so not only do they need to run on the same node, but we need to make sure ClusterIP is already active before we start WebSite. We do this by adding an ordering constraint." msgstr "Când pornește Apache, se atașează de adresa IP disponibilă. Nu știe de alte adrese pe care le adăugăm ulterior, așa nu trebuie doar să ruleze pe același nod, dar trebuie să ne asigurăm că ClusterIP este activ deja înainte să pornim WebSite. Realizăm acest lucru prin adăugarea unei restricții de ordonare. Trebuie să îi dăm un nume (alegeți ceva descriptiv precum apache-after-ip), să indicăm faptul că este obligatorie (astfel încât orice recuperare a ClusterIP va declanșa recuperarea WebSite-ului) și să listăm cele două resurse în ordinea în care avem nevoie să le pornim." #. Tag: para #, no-c-format msgid "By default all order constraints are mandatory constraints unless otherwise configured. This means that the recovery of ClusterIP will also trigger the recovery of WebSite." msgstr "" #. Tag: programlisting #, no-c-format msgid "" "# pcs constraint order ClusterIP then WebSite\n" "Adding ClusterIP WebSite (kind: Mandatory) (Options: first-action=start then-action=start)\n" "# pcs constraint\n" "Location Constraints:\n" "Ordering Constraints:\n" " start ClusterIP then start WebSite\n" "Colocation Constraints:\n" " WebSite with ClusterIP" msgstr "" #. Tag: title #, no-c-format msgid "Specifying a Preferred Location" msgstr "Specificarea unei Locații Preferate" #. Tag: para #, fuzzy, no-c-format msgid "Pacemaker does not rely on any sort of hardware symmetry between nodes, so it may well be that one machine is more powerful than the other. In such cases it makes sense to host the resources there if it is available. To do this we create a location constraint." msgstr "Pacemaker nu se bazează pe nici un fel de simetrie hardware între noduri, așa că ar putea foarte bine ca o mașină să fie mai puternică decât cealaltă. În astfel de cazuri are logică să găzduim resursele acolo dacă este disponibilă. Pentru a face acest lucru creăm o restricție de locație. Din nou îi dăm un nume descriptiv (prefer-pcmk-1), specificăm resursa pe care vrem să o rulăm acolo (WebSite), cât de mult am dori ca aceasta să ruleze acolo (vom folosi 50 momentan, dar într-o situație cu două noduri aproape orice valoare mai mare ca 0 este suficientă) și numele gazdei." #. Tag: para #, no-c-format msgid "In the location constraint below, we are saying the WebSite resource prefers the node pcmk-1 with a score of 50. The score here indicates how badly we’d like the resource to run somewhere." msgstr "" #. Tag: programlisting #, no-c-format msgid "" "# pcs constraint location WebSite prefers pcmk-1=50\n" "# pcs constraint\n" "Location Constraints:\n" " Resource: WebSite\n" " Enabled on: pcmk-1 (score:50)\n" "Ordering Constraints:\n" " start ClusterIP then start WebSite\n" "Colocation Constraints:\n" " WebSite with ClusterIP\n" "# pcs status\n" "Last updated: Fri Sep 14 11:06:37 2012\n" "Last change: Fri Sep 14 11:06:26 2012 via cibadmin on pcmk-1\n" "Stack: corosync\n" "Current DC: pcmk-2 (2) - partition with quorum\n" "Version: 1.1.8-1.el7-60a19ed12fdb4d5c6a6b6767f52e5391e447fec0\n" "2 Nodes configured, unknown expected votes\n" "2 Resources configured.\n" "\n" "Online: [ pcmk-1 pcmk-2 ]\n" "\n" "Full list of resources:\n" "\n" " ClusterIP (ocf::heartbeat:IPaddr2): Started pcmk-2\n" " WebSite (ocf::heartbeat:apache): Started pcmk-2" msgstr "" #. Tag: para #, no-c-format msgid "Wait a minute, the resources are still on pcmk-2!" msgstr "Așteptați o clipă, resursele sunt încă pe pcmk-2!" #. Tag: para #, no-c-format msgid "Even though we now prefer pcmk-1 over pcmk-2, that preference is (intentionally) less than the resource stickiness (how much we preferred not to have unnecessary downtime)." msgstr "Chiar dacă acum preferăm pcmk-1 în favoarea pcmk-2, această preferință este (în mod intenționat) mai mică decât adezivitatea resursei (cât de mult am preferat să nu avem nefuncționare inutilă)." #. Tag: para #, fuzzy, no-c-format msgid "To see the current placement scores, you can use a tool called crm_simulate" msgstr "Pentru a vedea scorurile curente de plasament, puteți folosi un utilitar numit ptest" #. Tag: programlisting #, no-c-format msgid "" "# crm_simulate -sL\n" "Current cluster status:\n" "Online: [ pcmk-1 pcmk-2 ]\n" "\n" " ClusterIP (ocf:heartbeat:IPaddr2): Started pcmk-2\n" " WebSite (ocf:heartbeat:apache): Started pcmk-2\n" "\n" "Allocation scores:\n" "native_color: ClusterIP allocation score on pcmk-1: 50\n" "native_color: ClusterIP allocation score on pcmk-2: 200\n" "native_color: WebSite allocation score on pcmk-1: -INFINITY\n" "native_color: WebSite allocation score on pcmk-2: 100\n" "\n" "Transition Summary:" msgstr "" #. Tag: title #, no-c-format msgid "Manually Moving Resources Around the Cluster" msgstr "Mutarea Manuală a Resurselor Prin Jurul Clusterului" #. Tag: para #, fuzzy, no-c-format msgid "There are always times when an administrator needs to override the cluster and force resources to move to a specific location. By updating our previous location constraint with a score of INFINITY, WebSite will be forced to move to pcmk-1." msgstr "Sunt întotdeauna momente când un administrator are nevoie să preia controlul clusterului și să forțeze resursele să se mute într-o locație specifică. Dedesupt folosim restricții de locație precum cea pe care am creat-o mai sus, dar în mod fericit nu trebuie să vă pese. Doar furnizați numele resursei și locația dorită, iar noi vom face restul." #. Tag: programlisting #, no-c-format msgid "" "# pcs constraint location WebSite prefers pcmk-1=INFINITY\n" "# pcs constraint all\n" "Location Constraints:\n" " Resource: WebSite\n" " Enabled on: pcmk-1 (score:INFINITY) (id:location-WebSite-pcmk-1-INFINITY)\n" "Ordering Constraints:\n" " start ClusterIP then start WebSite (Mandatory) (id:order-ClusterIP-WebSite-mandatory)\n" "Colocation Constraints:\n" " WebSite with ClusterIP (INFINITY) (id:colocation-WebSite-ClusterIP-INFINITY)\n" "# pcs status\n" "\n" "Last updated: Fri Sep 14 11:16:26 2012\n" "Last change: Fri Sep 14 11:16:18 2012 via cibadmin on pcmk-1\n" "Stack: corosync\n" "Current DC: pcmk-2 (2) - partition with quorum\n" "Version: 1.1.8-1.el7-60a19ed12fdb4d5c6a6b6767f52e5391e447fec0\n" "2 Nodes configured, unknown expected votes\n" "2 Resources configured.\n" "\n" "Online: [ pcmk-1 pcmk-2 ]\n" "\n" "Full list of resources:\n" "\n" " ClusterIP (ocf::heartbeat:IPaddr2): Started pcmk-1\n" " WebSite (ocf::heartbeat:apache): Started pcmk-1" msgstr "" #. Tag: title #, no-c-format msgid "Giving Control Back to the Cluster" msgstr "Returnarea Controlului Înapoi Clusterului" #. Tag: para #, no-c-format msgid "Once we’ve finished whatever activity that required us to move the resources to pcmk-1, in our case nothing, we can then allow the cluster to resume normal operation with the unmove command. Since we previously configured a default stickiness, the resources will remain on pcmk-1." msgstr "Odată ce am terminat oricare activitate ce ne-a cerut să mutăm resursele pe pcmk-1, în cazul nostru nimic, putem mai apoi să permitem clusterului să reia operațiunile normale prin comanda unmove. Din moment ce am configurat anterior o adezivitate implicită, resursele vor rămâne pe pcmk-1." #. Tag: programlisting #, no-c-format msgid "" "# pcs constraint all\n" "Location Constraints:\n" " Resource: WebSite\n" " Enabled on: pcmk-1 (score:INFINITY) (id:location-WebSite-pcmk-1-INFINITY)\n" "Ordering Constraints:\n" " start ClusterIP then start WebSite (Mandatory) (id:order-ClusterIP-WebSite-mandatory)\n" "Colocation Constraints:\n" " WebSite with ClusterIP (INFINITY) (id:colocation-WebSite-ClusterIP-INFINITY)\n" "# pcs constraint rm location-WebSite-pcmk-1-INFINITY\n" "# pcs constraint\n" "Location Constraints:\n" "Ordering Constraints:\n" " start ClusterIP then start WebSite\n" "Colocation Constraints:\n" " WebSite with ClusterIP" msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "Note that the constraint is now gone. If we check the cluster status, we can also see that as expected the resources are still active on pcmk-1." msgstr "Observați că restricția automată acum nu mai există. Dacă verificăm status-ul clusterului, putem vedea că așa cum ne așteptam resursele sunt în continuare active pe pcmk-1." #. Tag: programlisting #, fuzzy, no-c-format msgid "" "# pcs status\n" "\n" "Last updated: Fri Sep 14 11:57:12 2012\n" "Last change: Fri Sep 14 11:57:03 2012 via cibadmin on pcmk-1\n" "Stack: corosync\n" "Current DC: pcmk-2 (2) - partition with quorum\n" "Version: 1.1.8-1.el7-60a19ed12fdb4d5c6a6b6767f52e5391e447fec0\n" "2 Nodes configured, unknown expected votes\n" "2 Resources configured.\n" "\n" "Online: [ pcmk-1 pcmk-2 ]\n" "\n" "Full list of resources:\n" "\n" " ClusterIP (ocf::heartbeat:IPaddr2): Started pcmk-1\n" " WebSite (ocf::heartbeat:apache): Started pcmk-1" msgstr "" "\n" "[root@pcmk-1 ~]# crm_mon\n" "============\n" "Last updated: Fri Aug 28 16:12:49 2009\n" "Stack: openais\n" "Current DC: pcmk-2 - partition with quorum\n" "Version: 1.1.5-bdd89e69ba545404d02445be1f3d72e6a203ba2f\n" "2 Nodes configured, 2 expected votes\n" "2 Resources configured.\n" "============\n" "\n" "Online: [ pcmk-1 pcmk-2 ]\n" "\n" "ClusterIP        (ocf::heartbeat:IPaddr):        Started pcmk-2\n" "WebSite        (ocf::heartbeat:apache):        Started pcmk-1\n" #~ msgid "Before continuing, we need to make sure Apache is installed on both hosts." #~ msgstr "Înainte de a continua, trebuie să ne asigurăm că Apache este înstalat pe ambele gazde." #~ msgid "" #~ "\n" #~ "[root@ppcmk-1 ~]# yum install -y httpd\n" #~ "Setting up Install Process\n" #~ "Resolving Dependencies\n" #~ "--> Running transaction check\n" #~ "---> Package httpd.x86_64 0:2.2.13-2.fc12 set to be updated\n" #~ "--> Processing Dependency: httpd-tools = 2.2.13-2.fc12 for package: httpd-2.2.13-2.fc12.x86_64\n" #~ "--> Processing Dependency: apr-util-ldap for package: httpd-2.2.13-2.fc12.x86_64\n" #~ "--> Processing Dependency: /etc/mime.types for package: httpd-2.2.13-2.fc12.x86_64\n" #~ "--> Processing Dependency: libaprutil-1.so.0()(64bit) for package: httpd-2.2.13-2.fc12.x86_64\n" #~ "--> Processing Dependency: libapr-1.so.0()(64bit) for package: httpd-2.2.13-2.fc12.x86_64\n" #~ "--> Running transaction check\n" #~ "---> Package apr.x86_64 0:1.3.9-2.fc12 set to be updated\n" #~ "---> Package apr-util.x86_64 0:1.3.9-2.fc12 set to be updated\n" #~ "---> Package apr-util-ldap.x86_64 0:1.3.9-2.fc12 set to be updated\n" #~ "---> Package httpd-tools.x86_64 0:2.2.13-2.fc12 set to be updated\n" #~ "---> Package mailcap.noarch 0:2.1.30-1.fc12 set to be updated\n" #~ "--> Finished Dependency Resolution\n" #~ "\n" #~ "Dependencies Resolved\n" #~ "\n" #~ "=======================================================================================\n" #~ " Package               Arch             Version                Repository         Size\n" #~ "=======================================================================================\n" #~ "Installing:\n" #~ " httpd               x86_64           2.2.13-2.fc12            rawhide           735 k\n" #~ "Installing for dependencies:\n" #~ " apr                 x86_64           1.3.9-2.fc12             rawhide           117 k\n" #~ " apr-util            x86_64           1.3.9-2.fc12             rawhide            84 k\n" #~ " apr-util-ldap       x86_64           1.3.9-2.fc12             rawhide            15 k\n" #~ " httpd-tools         x86_64           2.2.13-2.fc12            rawhide            63 k\n" #~ " mailcap             noarch           2.1.30-1.fc12            rawhide            25 k\n" #~ "\n" #~ "Transaction Summary\n" #~ "=======================================================================================\n" #~ "Install       6 Package(s)\n" #~ "Upgrade       0 Package(s)\n" #~ "\n" #~ "Total download size: 1.0 M\n" #~ "Downloading Packages:\n" #~ "(1/6): apr-1.3.9-2.fc12.x86_64.rpm                                   | 117 kB     00:00     \n" #~ "(2/6): apr-util-1.3.9-2.fc12.x86_64.rpm                             |  84 kB     00:00     \n" #~ "(3/6): apr-util-ldap-1.3.9-2.fc12.x86_64.rpm                         |  15 kB     00:00     \n" #~ "(4/6): httpd-2.2.13-2.fc12.x86_64.rpm                               | 735 kB     00:00     \n" #~ "(5/6): httpd-tools-2.2.13-2.fc12.x86_64.rpm                         |  63 kB     00:00     \n" #~ "(6/6): mailcap-2.1.30-1.fc12.noarch.rpm                             |  25 kB     00:00     \n" #~ "----------------------------------------------------------------------------------------\n" #~ "Total                                                       875 kB/s | 1.0 MB     00:01     \n" #~ "Running rpm_check_debug\n" #~ "Running Transaction Test\n" #~ "Finished Transaction Test\n" #~ "Transaction Test Succeeded\n" #~ "Running Transaction\n" #~ "  Installing     : apr-1.3.9-2.fc12.x86_64                                         1/6 \n" #~ "  Installing     : apr-util-1.3.9-2.fc12.x86_64                                     2/6 \n" #~ "  Installing     : apr-util-ldap-1.3.9-2.fc12.x86_64                               3/6 \n" #~ "  Installing     : httpd-tools-2.2.13-2.fc12.x86_64                                 4/6 \n" #~ "  Installing     : mailcap-2.1.30-1.fc12.noarch                                     5/6 \n" #~ "  Installing     : httpd-2.2.13-2.fc12.x86_64                                       6/6 \n" #~ "\n" #~ "Installed:\n" #~ "  httpd.x86_64 0:2.2.13-2.fc12                                                         \n" #~ "\n" #~ "Dependency Installed:\n" #~ "  apr.x86_64 0:1.3.9-2.fc12            apr-util.x86_64 0:1.3.9-2.fc12\n" #~ "  apr-util-ldap.x86_64 0:1.3.9-2.fc12  httpd-tools.x86_64 0:2.2.13-2.fc12\n" #~ "  mailcap.noarch 0:2.1.30-1.fc12  \n" #~ "\n" #~ "Complete!\n" #~ "[root@pcmk-1 ~]#\n" #~ msgstr "" #~ "\n" #~ "[root@ppcmk-1 ~]# yum install -y httpd\n" #~ "Setting up Install Process\n" #~ "Resolving Dependencies\n" #~ "--> Running transaction check\n" #~ "---> Package httpd.x86_64 0:2.2.13-2.fc12 set to be updated\n" #~ "--> Processing Dependency: httpd-tools = 2.2.13-2.fc12 for package: httpd-2.2.13-2.fc12.x86_64\n" #~ "--> Processing Dependency: apr-util-ldap for package: httpd-2.2.13-2.fc12.x86_64\n" #~ "--> Processing Dependency: /etc/mime.types for package: httpd-2.2.13-2.fc12.x86_64\n" #~ "--> Processing Dependency: libaprutil-1.so.0()(64bit) for package: httpd-2.2.13-2.fc12.x86_64\n" #~ "--> Processing Dependency: libapr-1.so.0()(64bit) for package: httpd-2.2.13-2.fc12.x86_64\n" #~ "--> Running transaction check\n" #~ "---> Package apr.x86_64 0:1.3.9-2.fc12 set to be updated\n" #~ "---> Package apr-util.x86_64 0:1.3.9-2.fc12 set to be updated\n" #~ "---> Package apr-util-ldap.x86_64 0:1.3.9-2.fc12 set to be updated\n" #~ "---> Package httpd-tools.x86_64 0:2.2.13-2.fc12 set to be updated\n" #~ "---> Package mailcap.noarch 0:2.1.30-1.fc12 set to be updated\n" #~ "--> Finished Dependency Resolution\n" #~ "\n" #~ "Dependencies Resolved\n" #~ "\n" #~ "=======================================================================================\n" #~ " Package               Arch             Version                Repository         Size\n" #~ "=======================================================================================\n" #~ "Installing:\n" #~ " httpd               x86_64           2.2.13-2.fc12            rawhide           735 k\n" #~ "Installing for dependencies:\n" #~ " apr                 x86_64           1.3.9-2.fc12             rawhide           117 k\n" #~ " apr-util            x86_64           1.3.9-2.fc12             rawhide            84 k\n" #~ " apr-util-ldap       x86_64           1.3.9-2.fc12             rawhide            15 k\n" #~ " httpd-tools         x86_64           2.2.13-2.fc12            rawhide            63 k\n" #~ " mailcap             noarch           2.1.30-1.fc12            rawhide            25 k\n" #~ "\n" #~ "Transaction Summary\n" #~ "=======================================================================================\n" #~ "Install       6 Package(s)\n" #~ "Upgrade       0 Package(s)\n" #~ "\n" #~ "Total download size: 1.0 M\n" #~ "Downloading Packages:\n" #~ "(1/6): apr-1.3.9-2.fc12.x86_64.rpm                                   | 117 kB     00:00     \n" #~ "(2/6): apr-util-1.3.9-2.fc12.x86_64.rpm                             |  84 kB     00:00     \n" #~ "(3/6): apr-util-ldap-1.3.9-2.fc12.x86_64.rpm                         |  15 kB     00:00     \n" #~ "(4/6): httpd-2.2.13-2.fc12.x86_64.rpm                               | 735 kB     00:00     \n" #~ "(5/6): httpd-tools-2.2.13-2.fc12.x86_64.rpm                         |  63 kB     00:00     \n" #~ "(6/6): mailcap-2.1.30-1.fc12.noarch.rpm                             |  25 kB     00:00     \n" #~ "----------------------------------------------------------------------------------------\n" #~ "Total                                                       875 kB/s | 1.0 MB     00:01     \n" #~ "Running rpm_check_debug\n" #~ "Running Transaction Test\n" #~ "Finished Transaction Test\n" #~ "Transaction Test Succeeded\n" #~ "Running Transaction\n" #~ "  Installing     : apr-1.3.9-2.fc12.x86_64                                         1/6 \n" #~ "  Installing     : apr-util-1.3.9-2.fc12.x86_64                                     2/6 \n" #~ "  Installing     : apr-util-ldap-1.3.9-2.fc12.x86_64                               3/6 \n" #~ "  Installing     : httpd-tools-2.2.13-2.fc12.x86_64                                 4/6 \n" #~ "  Installing     : mailcap-2.1.30-1.fc12.noarch                                     5/6 \n" #~ "  Installing     : httpd-2.2.13-2.fc12.x86_64                                       6/6 \n" #~ "\n" #~ "Installed:\n" #~ "  httpd.x86_64 0:2.2.13-2.fc12                                                         \n" #~ "\n" #~ "Dependency Installed:\n" #~ "  apr.x86_64 0:1.3.9-2.fc12            apr-util.x86_64 0:1.3.9-2.fc12\n" #~ "  apr-util-ldap.x86_64 0:1.3.9-2.fc12  httpd-tools.x86_64 0:2.2.13-2.fc12\n" #~ "  mailcap.noarch 0:2.1.30-1.fc12  \n" #~ "\n" #~ "Complete!\n" #~ "[root@pcmk-1 ~]#\n" #~ msgid "" #~ "\n" #~ "[root@pcmk-1 ~]# yum install -y wget\n" #~ "Setting up Install Process\n" #~ "Resolving Dependencies\n" #~ "--> Running transaction check\n" #~ "---> Package wget.x86_64 0:1.11.4-5.fc12 set to be updated\n" #~ "--> Finished Dependency Resolution\n" #~ "\n" #~ "Dependencies Resolved\n" #~ "\n" #~ "===========================================================================================\n" #~ " Package        Arch             Version                      Repository               Size\n" #~ "===========================================================================================\n" #~ "Installing:\n" #~ " wget         x86_64          1.11.4-5.fc12                   rawhide                393 k\n" #~ "\n" #~ "Transaction Summary\n" #~ "===========================================================================================\n" #~ "Install       1 Package(s)\n" #~ "Upgrade       0 Package(s)\n" #~ "\n" #~ "Total download size: 393 k\n" #~ "Downloading Packages:\n" #~ "wget-1.11.4-5.fc12.x86_64.rpm                                            | 393 kB     00:00     \n" #~ "Running rpm_check_debug\n" #~ "Running Transaction Test\n" #~ "Finished Transaction Test\n" #~ "Transaction Test Succeeded\n" #~ "Running Transaction\n" #~ "  Installing     : wget-1.11.4-5.fc12.x86_64                                            1/1 \n" #~ "\n" #~ "Installed:\n" #~ "  wget.x86_64 0:1.11.4-5.fc12\n" #~ "\n" #~ "Complete!\n" #~ "[root@pcmk-1 ~]#\n" #~ msgstr "" #~ "\n" #~ "[root@pcmk-1 ~]# yum install -y wget\n" #~ "Setting up Install Process\n" #~ "Resolving Dependencies\n" #~ "--> Running transaction check\n" #~ "---> Package wget.x86_64 0:1.11.4-5.fc12 set to be updated\n" #~ "--> Finished Dependency Resolution\n" #~ "\n" #~ "Dependencies Resolved\n" #~ "\n" #~ "===========================================================================================\n" #~ " Package        Arch             Version                      Repository               Size\n" #~ "===========================================================================================\n" #~ "Installing:\n" #~ " wget         x86_64          1.11.4-5.fc12                   rawhide                393 k\n" #~ "\n" #~ "Transaction Summary\n" #~ "===========================================================================================\n" #~ "Install       1 Package(s)\n" #~ "Upgrade       0 Package(s)\n" #~ "\n" #~ "Total download size: 393 k\n" #~ "Downloading Packages:\n" #~ "wget-1.11.4-5.fc12.x86_64.rpm                                            | 393 kB     00:00     \n" #~ "Running rpm_check_debug\n" #~ "Running Transaction Test\n" #~ "Finished Transaction Test\n" #~ "Transaction Test Succeeded\n" #~ "Running Transaction\n" #~ "  Installing     : wget-1.11.4-5.fc12.x86_64                                            1/1 \n" #~ "\n" #~ "Installed:\n" #~ "  wget.x86_64 0:1.11.4-5.fc12\n" #~ "\n" #~ "Complete!\n" #~ "[root@pcmk-1 ~]#\n" #~ msgid "" #~ "\n" #~ "[root@pcmk-1 ~]# crm configure primitive WebSite ocf:heartbeat:apache params configfile=/etc/httpd/conf/httpd.conf op monitor interval=1min\n" #~ "[root@pcmk-1 ~]# crm configure show\n" #~ "node pcmk-1\n" #~ "node pcmk-2\n" #~ "primitive WebSite ocf:heartbeat:apache \\\n" #~ " params configfile=\"/etc/httpd/conf/httpd.conf\" \\\n" #~ " op monitor interval=\"1min\"\n" #~ "primitive ClusterIP ocf:heartbeat:IPaddr2 \\\n" #~ "        params ip=\"192.168.122.101\" cidr_netmask=\"32\" \\\n" #~ "        op monitor interval=\"30s\"\n" #~ "property $id=\"cib-bootstrap-options\" \\\n" #~ "        dc-version=\"1.1.5-bdd89e69ba545404d02445be1f3d72e6a203ba2f\" \\\n" #~ "        cluster-infrastructure=\"openais\" \\\n" #~ "        expected-quorum-votes=\"2\" \\\n" #~ "        stonith-enabled=\"false\" \\\n" #~ "        no-quorum-policy=\"ignore\"\n" #~ "rsc_defaults $id=\"rsc-options\" \\\n" #~ "        resource-stickiness=\"100\"\n" #~ msgstr "" #~ "\n" #~ "[root@pcmk-1 ~]# crm configure primitive WebSite ocf:heartbeat:apache params configfile=/etc/httpd/conf/httpd.conf op monitor interval=1min\n" #~ "[root@pcmk-1 ~]# crm configure show\n" #~ "node pcmk-1\n" #~ "node pcmk-2\n" #~ "primitive WebSite ocf:heartbeat:apache \\\n" #~ " params configfile=\"/etc/httpd/conf/httpd.conf\" \\\n" #~ " op monitor interval=\"1min\"\n" #~ "primitive ClusterIP ocf:heartbeat:IPaddr2 \\\n" #~ "        params ip=\"192.168.122.101\" cidr_netmask=\"32\" \\\n" #~ "        op monitor interval=\"30s\"\n" #~ "property $id=\"cib-bootstrap-options\" \\\n" #~ "        dc-version=\"1.1.5-bdd89e69ba545404d02445be1f3d72e6a203ba2f\" \\\n" #~ "        cluster-infrastructure=\"openais\" \\\n" #~ "        expected-quorum-votes=\"2\" \\\n" #~ "        stonith-enabled=\"false\" \\\n" #~ "        no-quorum-policy=\"ignore\"\n" #~ "rsc_defaults $id=\"rsc-options\" \\\n" #~ "        resource-stickiness=\"100\"\n" #~ msgid "For the constraint, we need a name (choose something descriptive like website-with-ip), indicate that it's mandatory (so that if ClusterIP is not active anywhere, WebSite will not be permitted to run anywhere either) by specifying a score of INFINITY and finally list the two resources." #~ msgstr "Pentru restricție, ne trebuie un nume (alegeți ceva descriptiv precum website-with-ip), să indicăm că este obligatorie (astfel încât dacă ClusterIP nu este activ nicăieri, nici lui WebSite nu i se va permite să ruleze nicăieri) specificând un scor cu valoarea INFINITY și la sfârșit vom lista cele două resurse." #~ msgid "" #~ "\n" #~ "[root@pcmk-1 ~]# crm configure colocation website-with-ip INFINITY: WebSite ClusterIP\n" #~ "[root@pcmk-1 ~]# crm configure show\n" #~ "node pcmk-1\n" #~ "node pcmk-2\n" #~ "primitive WebSite ocf:heartbeat:apache \\\n" #~ "        params configfile=\"/etc/httpd/conf/httpd.conf\" \\\n" #~ "        op monitor interval=\"1min\"\n" #~ "primitive ClusterIP ocf:heartbeat:IPaddr2 \\\n" #~ "        params ip=\"192.168.122.101\" cidr_netmask=\"32\" \\\n" #~ "        op monitor interval=\"30s\"\n" #~ "colocation website-with-ip inf: WebSite ClusterIP\n" #~ "property $id=\"cib-bootstrap-options\" \\\n" #~ "        dc-version=\"1.1.5-bdd89e69ba545404d02445be1f3d72e6a203ba2f\" \\\n" #~ "        cluster-infrastructure=\"openais\" \\\n" #~ "        expected-quorum-votes=\"2\" \\\n" #~ "        stonith-enabled=\"false\" \\\n" #~ "        no-quorum-policy=\"ignore\"\n" #~ "rsc_defaults $id=\"rsc-options\" \\\n" #~ "        resource-stickiness=\"100\"\n" #~ "[root@pcmk-1 ~]# crm_mon\n" #~ "============\n" #~ "Last updated: Fri Aug 28 16:14:34 2009\n" #~ "Stack: openais\n" #~ "Current DC: pcmk-2 - partition with quorum\n" #~ "Version: 1.1.5-bdd89e69ba545404d02445be1f3d72e6a203ba2f\n" #~ "2 Nodes configured, 2 expected votes\n" #~ "2 Resources configured.\n" #~ "============\n" #~ "\n" #~ "Online: [ pcmk-1 pcmk-2 ]\n" #~ "\n" #~ "ClusterIP        (ocf::heartbeat:IPaddr):        Started pcmk-2\n" #~ "WebSite        (ocf::heartbeat:apache):        Started pcmk-2\n" #~ msgstr "" #~ "\n" #~ "[root@pcmk-1 ~]# crm configure colocation website-with-ip INFINITY: WebSite ClusterIP\n" #~ "[root@pcmk-1 ~]# crm configure show\n" #~ "node pcmk-1\n" #~ "node pcmk-2\n" #~ "primitive WebSite ocf:heartbeat:apache \\\n" #~ "        params configfile=\"/etc/httpd/conf/httpd.conf\" \\\n" #~ "        op monitor interval=\"1min\"\n" #~ "primitive ClusterIP ocf:heartbeat:IPaddr2 \\\n" #~ "        params ip=\"192.168.122.101\" cidr_netmask=\"32\" \\\n" #~ "        op monitor interval=\"30s\"\n" #~ "colocation website-with-ip inf: WebSite ClusterIP\n" #~ "property $id=\"cib-bootstrap-options\" \\\n" #~ "        dc-version=\"1.1.5-bdd89e69ba545404d02445be1f3d72e6a203ba2f\" \\\n" #~ "        cluster-infrastructure=\"openais\" \\\n" #~ "        expected-quorum-votes=\"2\" \\\n" #~ "        stonith-enabled=\"false\" \\\n" #~ "        no-quorum-policy=\"ignore\"\n" #~ "rsc_defaults $id=\"rsc-options\" \\\n" #~ "        resource-stickiness=\"100\"\n" #~ "[root@pcmk-1 ~]# crm_mon\n" #~ "============\n" #~ "Last updated: Fri Aug 28 16:14:34 2009\n" #~ "Stack: openais\n" #~ "Current DC: pcmk-2 - partition with quorum\n" #~ "Version: 1.1.5-bdd89e69ba545404d02445be1f3d72e6a203ba2f\n" #~ "2 Nodes configured, 2 expected votes\n" #~ "2 Resources configured.\n" #~ "============\n" #~ "\n" #~ "Online: [ pcmk-1 pcmk-2 ]\n" #~ "\n" #~ "ClusterIP        (ocf::heartbeat:IPaddr):        Started pcmk-2\n" #~ "WebSite        (ocf::heartbeat:apache):        Started pcmk-2\n" #~ msgid "" #~ "\n" #~ "[root@pcmk-1 ~]# crm configure order apache-after-ip mandatory: ClusterIP WebSite\n" #~ "[root@pcmk-1 ~]# crm configure show\n" #~ "node pcmk-1\n" #~ "node pcmk-2\n" #~ "primitive WebSite ocf:heartbeat:apache \\\n" #~ "        params configfile=\"/etc/httpd/conf/httpd.conf\" \\\n" #~ "        op monitor interval=\"1min\"\n" #~ "primitive ClusterIP ocf:heartbeat:IPaddr2 \\\n" #~ "        params ip=\"192.168.122.101\" cidr_netmask=\"32\" \\\n" #~ "        op monitor interval=\"30s\"\n" #~ "colocation website-with-ip inf: WebSite ClusterIP\n" #~ "order apache-after-ip inf: ClusterIP WebSite\n" #~ "property $id=\"cib-bootstrap-options\" \\\n" #~ "        dc-version=\"1.1.5-bdd89e69ba545404d02445be1f3d72e6a203ba2f\" \\\n" #~ "        cluster-infrastructure=\"openais\" \\\n" #~ "        expected-quorum-votes=\"2\" \\\n" #~ "        stonith-enabled=\"false\" \\\n" #~ "        no-quorum-policy=\"ignore\"\n" #~ "rsc_defaults $id=\"rsc-options\" \\\n" #~ "        resource-stickiness=\"100\"\n" #~ msgstr "" #~ "\n" #~ "[root@pcmk-1 ~]# crm configure order apache-after-ip mandatory: ClusterIP WebSite\n" #~ "[root@pcmk-1 ~]# crm configure show\n" #~ "node pcmk-1\n" #~ "node pcmk-2\n" #~ "primitive WebSite ocf:heartbeat:apache \\\n" #~ "        params configfile=\"/etc/httpd/conf/httpd.conf\" \\\n" #~ "        op monitor interval=\"1min\"\n" #~ "primitive ClusterIP ocf:heartbeat:IPaddr2 \\\n" #~ "        params ip=\"192.168.122.101\" cidr_netmask=\"32\" \\\n" #~ "        op monitor interval=\"30s\"\n" #~ "colocation website-with-ip inf: WebSite ClusterIP\n" #~ "order apache-after-ip inf: ClusterIP WebSite\n" #~ "property $id=\"cib-bootstrap-options\" \\\n" #~ "        dc-version=\"1.1.5-bdd89e69ba545404d02445be1f3d72e6a203ba2f\" \\\n" #~ "        cluster-infrastructure=\"openais\" \\\n" #~ "        expected-quorum-votes=\"2\" \\\n" #~ "        stonith-enabled=\"false\" \\\n" #~ "        no-quorum-policy=\"ignore\"\n" #~ "rsc_defaults $id=\"rsc-options\" \\\n" #~ "        resource-stickiness=\"100\"\n" #~ msgid "" #~ "\n" #~ "[root@pcmk-1 ~]# crm configure location prefer-pcmk-1 WebSite 50: pcmk-1\n" #~ "[root@pcmk-1 ~]# crm configure show\n" #~ "node pcmk-1\n" #~ "node pcmk-2\n" #~ "primitive WebSite ocf:heartbeat:apache \\\n" #~ "        params configfile=\"/etc/httpd/conf/httpd.conf\" \\\n" #~ "        op monitor interval=\"1min\"\n" #~ "primitive ClusterIP ocf:heartbeat:IPaddr2 \\\n" #~ "        params ip=\"192.168.122.101\" cidr_netmask=\"32\" \\\n" #~ "        op monitor interval=\"30s\"\n" #~ "location prefer-pcmk-1 WebSite 50: pcmk-1\n" #~ "colocation website-with-ip inf: WebSite ClusterIP\n" #~ "property $id=\"cib-bootstrap-options\" \\\n" #~ "        dc-version=\"1.1.5-bdd89e69ba545404d02445be1f3d72e6a203ba2f\" \\\n" #~ "        cluster-infrastructure=\"openais\" \\\n" #~ "        expected-quorum-votes=\"2\" \\\n" #~ "        stonith-enabled=\"false\" \\\n" #~ "        no-quorum-policy=\"ignore\"\n" #~ "rsc_defaults $id=\"rsc-options\" \\\n" #~ "        resource-stickiness=\"100\"\n" #~ "[root@pcmk-1 ~]# crm_mon\n" #~ "============\n" #~ "Last updated: Fri Aug 28 16:17:35 2009\n" #~ "Stack: openais\n" #~ "Current DC: pcmk-2 - partition with quorum\n" #~ "Version: 1.1.5-bdd89e69ba545404d02445be1f3d72e6a203ba2f\n" #~ "2 Nodes configured, 2 expected votes\n" #~ "2 Resources configured.\n" #~ "============\n" #~ "\n" #~ "Online: [ pcmk-1 pcmk-2 ]\n" #~ "\n" #~ "ClusterIP        (ocf::heartbeat:IPaddr):        Started pcmk-2\n" #~ "WebSite        (ocf::heartbeat:apache):        Started pcmk-2\n" #~ msgstr "" #~ "\n" #~ "[root@pcmk-1 ~]# crm configure location prefer-pcmk-1 WebSite 50: pcmk-1\n" #~ "[root@pcmk-1 ~]# crm configure show\n" #~ "node pcmk-1\n" #~ "node pcmk-2\n" #~ "primitive WebSite ocf:heartbeat:apache \\\n" #~ "        params configfile=\"/etc/httpd/conf/httpd.conf\" \\\n" #~ "        op monitor interval=\"1min\"\n" #~ "primitive ClusterIP ocf:heartbeat:IPaddr2 \\\n" #~ "        params ip=\"192.168.122.101\" cidr_netmask=\"32\" \\\n" #~ "        op monitor interval=\"30s\"\n" #~ "location prefer-pcmk-1 WebSite 50: pcmk-1\n" #~ "colocation website-with-ip inf: WebSite ClusterIP\n" #~ "property $id=\"cib-bootstrap-options\" \\\n" #~ "        dc-version=\"1.1.5-bdd89e69ba545404d02445be1f3d72e6a203ba2f\" \\\n" #~ "        cluster-infrastructure=\"openais\" \\\n" #~ "        expected-quorum-votes=\"2\" \\\n" #~ "        stonith-enabled=\"false\" \\\n" #~ "        no-quorum-policy=\"ignore\"\n" #~ "rsc_defaults $id=\"rsc-options\" \\\n" #~ "        resource-stickiness=\"100\"\n" #~ "[root@pcmk-1 ~]# crm_mon\n" #~ "============\n" #~ "Last updated: Fri Aug 28 16:17:35 2009\n" #~ "Stack: openais\n" #~ "Current DC: pcmk-2 - partition with quorum\n" #~ "Version: 1.1.5-bdd89e69ba545404d02445be1f3d72e6a203ba2f\n" #~ "2 Nodes configured, 2 expected votes\n" #~ "2 Resources configured.\n" #~ "============\n" #~ "\n" #~ "Online: [ pcmk-1 pcmk-2 ]\n" #~ "\n" #~ "ClusterIP        (ocf::heartbeat:IPaddr):        Started pcmk-2\n" #~ "WebSite        (ocf::heartbeat:apache):        Started pcmk-2\n" #~ msgid "ptest -sL" #~ msgstr "ptest -sL" #~ msgid "Include output" #~ msgstr "Include rezultatul de ieșire" #~ msgid "There is a way to force them to move though..." #~ msgstr "Există o cale să le forțăm să se mute totuși ..." #~ msgid "" #~ "\n" #~ "[root@pcmk-1 ~]# crm resource move WebSite pcmk-1\n" #~ "[root@pcmk-1 ~]# crm_mon\n" #~ "============\n" #~ "Last updated: Fri Aug 28 16:19:24 2009\n" #~ "Stack: openais\n" #~ "Current DC: pcmk-2 - partition with quorum\n" #~ "Version: 1.1.5-bdd89e69ba545404d02445be1f3d72e6a203ba2f\n" #~ "2 Nodes configured, 2 expected votes\n" #~ "2 Resources configured.\n" #~ "============\n" #~ "\n" #~ "Online: [ pcmk-1 pcmk-2 ]\n" #~ "\n" #~ "ClusterIP        (ocf::heartbeat:IPaddr):        Started pcmk-1\n" #~ "WebSite        (ocf::heartbeat:apache):        Started pcmk-1\n" #~ "Notice how the colocation rule we created has ensured that ClusterIP was also moved to pcmk-1.\n" #~ "For the curious, we can see the effect of this command by examining the configuration\n" #~ "crm configure show\n" #~ "[root@pcmk-1 ~]# crm configure show\n" #~ "node pcmk-1\n" #~ "node pcmk-2\n" #~ "primitive WebSite ocf:heartbeat:apache \\\n" #~ "        params configfile=\"/etc/httpd/conf/httpd.conf\" \\\n" #~ "        op monitor interval=\"1min\"\n" #~ "primitive ClusterIP ocf:heartbeat:IPaddr2 \\\n" #~ "        params ip=\"192.168.122.101\" cidr_netmask=\"32\" \\\n" #~ "        op monitor interval=\"30s\"\n" #~ "location cli-prefer-WebSite WebSite \\\n" #~ " rule $id=\"cli-prefer-rule-WebSite\" inf: #uname eq pcmk-1\n" #~ "location prefer-pcmk-1 WebSite 50: pcmk-1\n" #~ "colocation website-with-ip inf: WebSite ClusterIP\n" #~ "property $id=\"cib-bootstrap-options\" \\\n" #~ "        dc-version=\"1.1.5-bdd89e69ba545404d02445be1f3d72e6a203ba2f\" \\\n" #~ "        cluster-infrastructure=\"openais\" \\\n" #~ "        expected-quorum-votes=\"2\" \\\n" #~ "        stonith-enabled=\"false\" \\\n" #~ "        no-quorum-policy=\"ignore\"\n" #~ "rsc_defaults $id=\"rsc-options\" \\\n" #~ "        resource-stickiness=\"100\"\n" #~ msgstr "" #~ "\n" #~ "[root@pcmk-1 ~]# crm resource move WebSite pcmk-1\n" #~ "[root@pcmk-1 ~]# crm_mon\n" #~ "============\n" #~ "Last updated: Fri Aug 28 16:19:24 2009\n" #~ "Stack: openais\n" #~ "Current DC: pcmk-2 - partition with quorum\n" #~ "Version: 1.1.5-bdd89e69ba545404d02445be1f3d72e6a203ba2f\n" #~ "2 Nodes configured, 2 expected votes\n" #~ "2 Resources configured.\n" #~ "============\n" #~ "\n" #~ "Online: [ pcmk-1 pcmk-2 ]\n" #~ "\n" #~ "ClusterIP        (ocf::heartbeat:IPaddr):        Started pcmk-1\n" #~ "WebSite        (ocf::heartbeat:apache):        Started pcmk-1\n" #~ "Notice how the colocation rule we created has ensured that ClusterIP was also moved to pcmk-1.\n" #~ "For the curious, we can see the effect of this command by examining the configuration\n" #~ "crm configure show\n" #~ "[root@pcmk-1 ~]# crm configure show\n" #~ "node pcmk-1\n" #~ "node pcmk-2\n" #~ "primitive WebSite ocf:heartbeat:apache \\\n" #~ "        params configfile=\"/etc/httpd/conf/httpd.conf\" \\\n" #~ "        op monitor interval=\"1min\"\n" #~ "primitive ClusterIP ocf:heartbeat:IPaddr2 \\\n" #~ "        params ip=\"192.168.122.101\" cidr_netmask=\"32\" \\\n" #~ "        op monitor interval=\"30s\"\n" #~ "location cli-prefer-WebSite WebSite \\\n" #~ " rule $id=\"cli-prefer-rule-WebSite\" inf: #uname eq pcmk-1\n" #~ "location prefer-pcmk-1 WebSite 50: pcmk-1\n" #~ "colocation website-with-ip inf: WebSite ClusterIP\n" #~ "property $id=\"cib-bootstrap-options\" \\\n" #~ "        dc-version=\"1.1.5-bdd89e69ba545404d02445be1f3d72e6a203ba2f\" \\\n" #~ "        cluster-infrastructure=\"openais\" \\\n" #~ "        expected-quorum-votes=\"2\" \\\n" #~ "        stonith-enabled=\"false\" \\\n" #~ "        no-quorum-policy=\"ignore\"\n" #~ "rsc_defaults $id=\"rsc-options\" \\\n" #~ "        resource-stickiness=\"100\"\n" #~ msgid "Highlighted is the automated constraint used to move the resources to pcmk-1" #~ msgstr "Subliniată este restricția automată folosită pentru a muta resursele pe pcmk-1" #~ msgid "" #~ "\n" #~ "[root@pcmk-1 ~]# crm resource unmove WebSite\n" #~ "[root@pcmk-1 ~]# crm configure show\n" #~ "node pcmk-1\n" #~ "node pcmk-2\n" #~ "primitive WebSite ocf:heartbeat:apache \\\n" #~ "        params configfile=\"/etc/httpd/conf/httpd.conf\" \\\n" #~ "        op monitor interval=\"1min\"\n" #~ "primitive ClusterIP ocf:heartbeat:IPaddr2 \\\n" #~ "        params ip=\"192.168.122.101\" cidr_netmask=\"32\" \\\n" #~ "        op monitor interval=\"30s\"\n" #~ "location prefer-pcmk-1 WebSite 50: pcmk-1\n" #~ "colocation website-with-ip inf: WebSite ClusterIP\n" #~ "property $id=\"cib-bootstrap-options\" \\\n" #~ "        dc-version=\"1.1.5-bdd89e69ba545404d02445be1f3d72e6a203ba2f\" \\\n" #~ "        cluster-infrastructure=\"openais\" \\\n" #~ "        expected-quorum-votes=\"2\" \\\n" #~ "        stonith-enabled=\"false\" \\\n" #~ "        no-quorum-policy=\"ignore\"\n" #~ "rsc_defaults $id=\"rsc-options\" \\\n" #~ "        resource-stickiness=\"100\"\n" #~ msgstr "" #~ "\n" #~ "[root@pcmk-1 ~]# crm resource unmove WebSite\n" #~ "[root@pcmk-1 ~]# crm configure show\n" #~ "node pcmk-1\n" #~ "node pcmk-2\n" #~ "primitive WebSite ocf:heartbeat:apache \\\n" #~ "        params configfile=\"/etc/httpd/conf/httpd.conf\" \\\n" #~ "        op monitor interval=\"1min\"\n" #~ "primitive ClusterIP ocf:heartbeat:IPaddr2 \\\n" #~ "        params ip=\"192.168.122.101\" cidr_netmask=\"32\" \\\n" #~ "        op monitor interval=\"30s\"\n" #~ "location prefer-pcmk-1 WebSite 50: pcmk-1\n" #~ "colocation website-with-ip inf: WebSite ClusterIP\n" #~ "property $id=\"cib-bootstrap-options\" \\\n" #~ "        dc-version=\"1.1.5-bdd89e69ba545404d02445be1f3d72e6a203ba2f\" \\\n" #~ "        cluster-infrastructure=\"openais\" \\\n" #~ "        expected-quorum-votes=\"2\" \\\n" #~ "        stonith-enabled=\"false\" \\\n" #~ "        no-quorum-policy=\"ignore\"\n" #~ "rsc_defaults $id=\"rsc-options\" \\\n" #~ "        resource-stickiness=\"100\"\n" #~ msgid "" #~ "\n" #~ "[root@pcmk-1 ~]# crm_mon\n" #~ "============\n" #~ "Last updated: Fri Aug 28 16:20:53 2009\n" #~ "Stack: openais\n" #~ "Current DC: pcmk-2 - partition with quorum\n" #~ "Version: 1.1.5-bdd89e69ba545404d02445be1f3d72e6a203ba2f\n" #~ "2 Nodes configured, 2 expected votes\n" #~ "2 Resources configured.\n" #~ "============\n" #~ "\n" #~ "Online: [ pcmk-1 pcmk-2 ]\n" #~ "\n" #~ " ClusterIP        (ocf::heartbeat:IPaddr):        Started pcmk-1\n" #~ " WebSite        (ocf::heartbeat:apache):        Started pcmk-1\n" #~ msgstr "" #~ "\n" #~ "[root@pcmk-1 ~]# crm_mon\n" #~ "============\n" #~ "Last updated: Fri Aug 28 16:20:53 2009\n" #~ "Stack: openais\n" #~ "Current DC: pcmk-2 - partition with quorum\n" #~ "Version: 1.1.5-bdd89e69ba545404d02445be1f3d72e6a203ba2f\n" #~ "2 Nodes configured, 2 expected votes\n" #~ "2 Resources configured.\n" #~ "============\n" #~ "\n" #~ "Online: [ pcmk-1 pcmk-2 ]\n" #~ "\n" #~ " ClusterIP        (ocf::heartbeat:IPaddr):        Started pcmk-1\n" #~ " WebSite        (ocf::heartbeat:apache):        Started pcmk-1\n" pacemaker-master/doc/Clusters_from_Scratch/ro-RO/Ch-Installation.po000066400000000000000000004132671217637305600256600ustar00rootroot00000000000000# # AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: Clusters from Scratch 1.1\n" "POT-Creation-Date: 2012-10-17T05:19:03\n" "PO-Revision-Date: 2011-11-24 08:21+0200\n" "Last-Translator: Dan Frîncu \n" "Language-Team: None\n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: application/x-publican; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. Tag: title #, no-c-format msgid "Installation" msgstr "Instalare" #. Tag: title #, no-c-format msgid "OS Installation" msgstr "Instalarea Sistemului de Operare" #. Tag: para #, fuzzy, no-c-format msgid "Detailed instructions for installing Fedora are available at http://docs.fedoraproject.org/en-US/Fedora/17/html/Installation_Guide/ in a number of languages. The abbreviated version is as follows…" msgstr "Instrucțiuni detaliate pentru instalarea Fedora sunt disponibile la http://docs.fedoraproject.org/install-guide/f&DISTRO_VERSION;/ într-un număr de limbi. Versiunea abreviată este după cum urmează ..." #. Tag: para #, fuzzy, no-c-format msgid "Point your browser to http://fedoraproject.org/en/get-fedora-all, locate the Install Media section and download the install DVD that matches your hardware." msgstr "Îndreptați browserul vostru către http://fedoraproject.org/en/get-fedora-all, localizați secțiunea Install Media și descărcați DVD-ul de instalare care se potrivește cu hardware-ul vostru." #. Tag: para #, fuzzy, no-c-format msgid "Burn the disk image to a DVD http://docs.fedoraproject.org/en-US/Fedora/16/html/Burning_ISO_images_to_disc/index.html and boot from it, or use the image to boot a virtual machine." msgstr "Asignați mașinii un nume de gazdă. http://docs.fedoraproject.org/install-guide/f&DISTRO_VERSION;/en-US/html/sn-networkconfig-fedora.html Eu se întâmplă să controlez numele de domeniu clusterlabs.org, așa că îl voi folosi pe acesta aici." #. Tag: para #, no-c-format msgid "After clicking through the welcome screen, select your language, keyboard layout http://docs.fedoraproject.org/en-US/Fedora/16/html/Installation_Guide/sn-keyboard-x86.html and storage type http://docs.fedoraproject.org/en-US/Fedora/16/html/Installation_Guide/Storage_Devices-x86.html" msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "Assign your machine a host name. http://docs.fedoraproject.org/en-US/Fedora/16/html/Installation_Guide/sn-Netconfig-x86.html I happen to control the clusterlabs.org domain name, so I will use that here." msgstr "Asignați mașinii un nume de gazdă. http://docs.fedoraproject.org/install-guide/f&DISTRO_VERSION;/en-US/html/sn-networkconfig-fedora.html Eu se întâmplă să controlez numele de domeniu clusterlabs.org, așa că îl voi folosi pe acesta aici." #. Tag: para #, fuzzy, no-c-format msgid "Do not accept the default network settings. Cluster machines should never obtain an IP address via DHCP." msgstr "Nu acceptați setările implicite de rețea. Mașinile din cluster nu ar trebui niciodată să obțină o adresă IP via DHCP. Aici voi folosi adresele interne pentru rețeaua clusterlab.org." #. Tag: para #, no-c-format msgid "When you are presented with the Configure Network advanced option, select that option before continuing with the installation process to specify a fixed IPv4 address for System eth0. Be sure to also enter the Routes section and add an entry for your default gateway." msgstr "" #. Tag: phrase #, no-c-format msgid "Custom network settings" msgstr "" #. Tag: para #, no-c-format msgid "If you miss this step, this can easily be configured after installation. You will have to navigate to system settings and select network. From there you can select what device to configure." msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "You will then be prompted to indicate the machine’s physical location http://docs.fedoraproject.org/en-US/Fedora/16/html/Installation_Guide/s1-timezone-x86.html and to supply a root password. http://docs.fedoraproject.org/en-US/Fedora/16/html/Installation_Guide/sn-account_configuration-x86.html" msgstr "Vi se va cere ulterior să indicați locația fizică a mașinii și să furnizați o parolă de root. http://docs.fedoraproject.org/install-guide/f&DISTRO_VERSION;/en-US/html/sn-account_configuration.html " #. Tag: para #, fuzzy, no-c-format msgid "Now select where you want Fedora installed. http://docs.fedoraproject.org/en-US/Fedora/16/html/Installation_Guide/s1-diskpartsetup-x86.html As I don’t care about any existing data, I will accept the default and allow Fedora to use the complete drive." msgstr "Acum selectați unde vreți Fedora să fie instalată. http://docs.fedoraproject.org/install-guide/f13/en-US/html/s1-diskpartsetup-x86.html Deoarece nu îmi pasă de orice date existente, voi accepta valorile implicite și voi permite Fedorei să folosească întregul disc. Totuși vreau să rezerv ceva spațiu pentru DRBD, așa că voi bifa caseta Review and modify partitioning layout." #. Tag: para #, no-c-format msgid "By default Fedora uses LVM for partitioning which allows us to dynamically change the amount of space allocated to a given partition." msgstr "" #. Tag: para #, no-c-format msgid "However, by default it also allocates all free space to the / (aka. root) partition which cannot be dynamically reduced in size (dynamic increases are fine by-the-way)." msgstr "" #. Tag: para #, no-c-format msgid "So if you plan on following the DRBD or GFS2 portions of this guide, you should reserve at least 1Gb of space on each machine from which to create a shared volume. To do so select the Review and modify partitioning layout checkbox before clicking Next. You will then be given an opportunity to reduce the size of the root partition." msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "Next choose which software should be installed. http://docs.fedoraproject.org/en-US/Fedora/16/html/Installation_Guide/s1-pkgselection-x86.html Change the selection to Minimal so that we see everything that gets installed. Don’t enable updates yet, we’ll do that (and install any extra software we need) later. After you click next, Fedora will begin installing." msgstr "În continuare alegeți ce software ar trebui să fie instalat. Schimbați selecția pe Web Server din moment ce plănuim să instalăm Apache. Nu activați încă actualizările, o să facem asta (și vom instala orice software adițional de care avem nevoie) mai târziu. După ce faceți click pe Next, Fedora va începe să se instaleze. " #. Tag: para #, fuzzy, no-c-format msgid "Go grab something to drink, this may take a while." msgstr "Instalarea Fedora: Mergeți să vă luați ceva de băut, asta ar putea dura o vreme" #. Tag: para #, no-c-format msgid "Once the node reboots, you’ll see a (possibly mangled) login prompt on the console. Login using root and the password you created earlier." msgstr "" #. Tag: phrase #, no-c-format msgid "Initial Console" msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "From here on in we’re going to be working exclusively from the terminal." msgstr "Aceea a fost ultima captură de ecran, de aici înainte vom lucra de la terminal." #. Tag: title #, fuzzy, no-c-format msgid "Post Installation Tasks" msgstr "Instalare" #. Tag: title #, fuzzy, no-c-format msgid "Networking" msgstr "Finalizați Rețelistica" #. Tag: para #, no-c-format msgid "Bring up the network and ensure it starts at boot" msgstr "" #. Tag: programlisting #, no-c-format msgid "" "# service network start\n" "# chkconfig network on" msgstr "" #. Tag: para #, no-c-format msgid "Check the machine has the static IP address you configured earlier" msgstr "" #. Tag: programlisting #, no-c-format msgid "" "# ip addr\n" "1: lo: <LOOPBACK,UP,LOWER_UP> mtu 16436 qdisc noqueue state UNKNOWN\n" " link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00\n" " inet 127.0.0.1/8 scope host lo\n" " inet6 ::1/128 scope host\n" " valid_lft forever preferred_lft forever\n" "2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000\n" " link/ether 52:54:00:d7:d6:08 brd ff:ff:ff:ff:ff:ff\n" " inet 192.168.122.101/24 brd 192.168.122.255 scope global eth0\n" " inet6 fe80::5054:ff:fed7:d608/64 scope link\n" " valid_lft forever preferred_lft forever" msgstr "" #. Tag: para #, no-c-format msgid "Now check the default route setting:" msgstr "" #. Tag: programlisting #, no-c-format msgid "" "[root@pcmk-1 ~]# ip route\n" "default via 192.168.122.1 dev eth0\n" "192.168.122.0/24 dev eth0 proto kernel scope link src 192.168.122.101" msgstr "" #. Tag: para #, no-c-format msgid "If there is no line beginning with default via, then you may need to add a line such as" msgstr "" #. Tag: programlisting #, no-c-format msgid "GATEWAY=192.168.122.1" msgstr "" #. Tag: para #, no-c-format msgid "to /etc/sysconfig/network and restart the network." msgstr "" #. Tag: para #, no-c-format msgid "Now check for connectivity to the outside world. Start small by testing if we can read the gateway we configured." msgstr "" #. Tag: programlisting #, fuzzy, no-c-format msgid "" "# ping -c 1 192.168.122.1\n" "PING 192.168.122.1 (192.168.122.1) 56(84) bytes of data.\n" "64 bytes from 192.168.122.1: icmp_req=1 ttl=64 time=0.249 ms\n" "\n" "--- 192.168.122.1 ping statistics ---\n" "1 packets transmitted, 1 received, 0% packet loss, time 0ms\n" "rtt min/avg/max/mdev = 0.249/0.249/0.249/0.000 ms" msgstr "" "\n" "[root@pcmk-1 ~]# ping -c 3 192.168.122.102\n" "PING 192.168.122.102 (192.168.122.102) 56(84) bytes of data.\n" "64 bytes from 192.168.122.102: icmp_seq=1 ttl=64 time=0.343 ms\n" "64 bytes from 192.168.122.102: icmp_seq=2 ttl=64 time=0.402 ms\n" "64 bytes from 192.168.122.102: icmp_seq=3 ttl=64 time=0.558 ms\n" "\n" "--- 192.168.122.102 ping statistics ---\n" "3 packets transmitted, 3 received, 0% packet loss, time 2000ms\n" "rtt min/avg/max/mdev = 0.343/0.434/0.558/0.092 ms\n" "\t" #. Tag: para #, no-c-format msgid "Now try something external, choose a location you know will be available." msgstr "" #. Tag: programlisting #, no-c-format msgid "" "# ping -c 1 www.google.com\n" "PING www.l.google.com (173.194.72.106) 56(84) bytes of data.\n" "64 bytes from tf-in-f106.1e100.net (173.194.72.106): icmp_req=1 ttl=41 time=167 ms\n" "\n" "--- www.l.google.com ping statistics ---\n" "1 packets transmitted, 1 received, 0% packet loss, time 0ms\n" "rtt min/avg/max/mdev = 167.618/167.618/167.618/0.000 ms" msgstr "" #. Tag: title #, no-c-format msgid "Leaving the Console" msgstr "" #. Tag: para #, no-c-format msgid "The console isn’t a very friendly place to work from, we will now switch to accessing the machine remotely via SSH where we can use copy&paste etc." msgstr "" #. Tag: para #, no-c-format msgid "First we check we can see the newly installed at all:" msgstr "" #. Tag: programlisting #, fuzzy, no-c-format msgid "" "beekhof@f16 ~ # ping -c 1 192.168.122.101\n" "PING 192.168.122.101 (192.168.122.101) 56(84) bytes of data.\n" "64 bytes from 192.168.122.101: icmp_req=1 ttl=64 time=1.01 ms\n" "\n" "--- 192.168.122.101 ping statistics ---\n" "1 packets transmitted, 1 received, 0% packet loss, time 0ms\n" "rtt min/avg/max/mdev = 1.012/1.012/1.012/0.000 ms" msgstr "" "\n" "[root@pcmk-1 ~]# ping -c 3 192.168.122.102\n" "PING 192.168.122.102 (192.168.122.102) 56(84) bytes of data.\n" "64 bytes from 192.168.122.102: icmp_seq=1 ttl=64 time=0.343 ms\n" "64 bytes from 192.168.122.102: icmp_seq=2 ttl=64 time=0.402 ms\n" "64 bytes from 192.168.122.102: icmp_seq=3 ttl=64 time=0.558 ms\n" "\n" "--- 192.168.122.102 ping statistics ---\n" "3 packets transmitted, 3 received, 0% packet loss, time 2000ms\n" "rtt min/avg/max/mdev = 0.343/0.434/0.558/0.092 ms\n" "\t" #. Tag: para #, no-c-format msgid "Next we login via SSH" msgstr "" #. Tag: programlisting #, no-c-format msgid "" "beekhof@f16 ~ # ssh -l root 192.168.122.11\n" "root@192.168.122.11's password:\n" "Last login: Fri Mar 30 19:41:19 2012 from 192.168.122.1\n" "[root@pcmk-1 ~]#" msgstr "" #. Tag: title #, no-c-format msgid "Security Shortcuts" msgstr "Scurtături de Securitate" #. Tag: para #, fuzzy, no-c-format msgid "To simplify this guide and focus on the aspects directly connected to clustering, we will now disable the machine’s firewall and SELinux installation." msgstr "Pentru a simplifica acest ghid și pentru a ne concentra pe aspecte care sunt legate în mod direct de clustering, o să dezactivăm acum firewall-ul mașinii și instalarea de SELinux. Ambele aceste acțiuni creează probleme semnificative de securitate și nu ar trebui să fie efectuate pe mașini care vor fi expuse în mod direct către lumea exterioara. " #. Tag: para #, fuzzy, no-c-format msgid "Both of these actions create significant security issues and should not be performed on machines that will be exposed to the outside world." msgstr "Pentru a simplifica acest ghid și pentru a ne concentra pe aspecte care sunt legate în mod direct de clustering, o să dezactivăm acum firewall-ul mașinii și instalarea de SELinux. Ambele aceste acțiuni creează probleme semnificative de securitate și nu ar trebui să fie efectuate pe mașini care vor fi expuse în mod direct către lumea exterioara. " #. Tag: literallayout #, no-c-format msgid "TODO: Create an Appendix that deals with (at least) re-enabling the firewall." msgstr "TODO: Crearea unui Apendix care să se ocupe cu (cel puțin) reactivarea firewall-ului." #. Tag: programlisting #, no-c-format msgid "" "# setenforce 0\n" "# sed -i.bak \"s/SELINUX=enforcing/SELINUX=permissive/g\" /etc/selinux/config\n" "# systemctl disable iptables.service\n" "# rm '/etc/systemd/system/basic.target.wants/iptables.service'\n" "# systemctl stop iptables.service" msgstr "" #. Tag: title #, no-c-format msgid "Short Node Names" msgstr "Numele Scurte ale Nodurilor" #. Tag: para #, fuzzy, no-c-format msgid "During installation, we filled in the machine’s fully qualifier domain name (FQDN) which can be rather long when it appears in cluster logs and status output. See for yourself how the machine identifies itself: Nodesshort name short name " msgstr "În timpul instalării, am completat numele complet calificat de domeniu (FQDN) al mașinii care poate fi destul de lung când apare în logurile clusterului sau în rezultatul de ieșire al status-ului. Vedeți pentru voi înșivă cum se identifică singură mașina:" #. Tag: programlisting #, no-c-format msgid "" "# uname -n\n" "pcmk-1.clusterlabs.org\n" "# dnsdomainname\n" "clusterlabs.org" msgstr "" #. Tag: para #, no-c-format msgid " NodesDomain name (Query) Domain name (Query) " msgstr "" #. Tag: para #, no-c-format msgid "The output from the second command is fine, but we really don’t need the domain name included in the basic host details. To address this, we need to update /etc/sysconfig/network. This is what it should look like before we start." msgstr "Rezultatul de ieșire de la a doua comandă este în regulă, dar nu avem nevoie cu adevărat ca numele de domeniu să fie inclus în detaliile de bază ale gazdei. Pentru a adresa acest lucru, trebuie să actualizăm /etc/sysconfig/network. Așa ar trebui să arate înainte să începem." #. Tag: programlisting #, fuzzy, no-c-format msgid "" "# cat /etc/sysconfig/network\n" "NETWORKING=yes\n" "HOSTNAME=pcmk-1.clusterlabs.org\n" "GATEWAY=192.168.122.1" msgstr "" "\n" "[root@pcmk-1 ~]# cat /etc/sysconfig/network\n" "NETWORKING=yes\n" "HOSTNAME=pcmk-1.clusterlabs.org\n" "GATEWAY=192.168.122.1\n" " " #. Tag: para #, no-c-format msgid "All we need to do now is strip off the domain name portion, which is stored elsewhere anyway." msgstr "Tot ceea ce trebuie să facem acum este să scoatem porțiunea de nume de domeniu, care este stocată oricum în altă parte." #. Tag: programlisting #, fuzzy, no-c-format msgid " # sed -i.sed 's/\\.[a-z].*//g' /etc/sysconfig/network" msgstr "[root@pcmk-1 ~]# sed -i.bak 's/\\.[a-z].*//g' /etc/sysconfig/network" #. Tag: para #, no-c-format msgid "Now confirm the change was successful. The revised file contents should look something like this." msgstr "Acum confirmați că modificarea a fost realizată cu succes. Conținutul fișierului revizuit ar trebui să arate ceva de genul acesta." #. Tag: programlisting #, fuzzy, no-c-format msgid "" "# cat /etc/sysconfig/network\n" "NETWORKING=yes\n" "HOSTNAME=pcmk-1\n" "GATEWAY=192.168.122.1" msgstr "" "\n" "[root@pcmk-1 ~]# cat /etc/sysconfig/network\n" "NETWORKING=yes\n" "HOSTNAME=pcmk-1\n" "GATEWAY=192.168.122.1\n" " " #. Tag: para #, fuzzy, no-c-format msgid "However we’re not finished. The machine wont normally see the shortened host name until about it reboots, but we can force it to update." msgstr "Însă nu am terminat. Mașina nu ar vedea în mod normal lista de nume de gazde scurtate până ce nu repornește, dar putem să o forțăm să se actualizeze." #. Tag: programlisting #, no-c-format msgid "" "# source /etc/sysconfig/network\n" "# hostname $HOSTNAME" msgstr "" #. Tag: para #, no-c-format msgid " NodesDomain name (Remove from host name) Domain name (Remove from host name) " msgstr "" #. Tag: para #, no-c-format msgid "Now check the machine is using the correct names" msgstr "Acum verificați că mașina folosește numele corecte" #. Tag: programlisting #, no-c-format msgid "" "# uname -n\n" "pcmk-1\n" "# dnsdomainname\n" "clusterlabs.org" msgstr "" #. Tag: title #, no-c-format msgid "NTP" msgstr "" #. Tag: para #, no-c-format msgid "It is highly recommended to enable NTP on your cluster nodes. Doing so ensures all nodes agree on the current time and makes reading log files significantly easier. http://docs.fedoraproject.org/en-US/Fedora/17/html-single/System_Administrators_Guide/index.html#ch-Configuring_the_Date_and_Time" msgstr "" #. Tag: title #, no-c-format msgid "Before You Continue" msgstr "Înainte de a Continua" #. Tag: para #, fuzzy, no-c-format msgid "Repeat the Installation steps so far, so that you have two Fedora nodes ready to have the cluster software installed." msgstr "Repetați pașii de Instalare astfel încât să aveți 2 noduri cu Fedora cu software-ul de cluster instalat." #. Tag: para #, fuzzy, no-c-format msgid "For the purposes of this document, the additional node is called pcmk-2 with address 192.168.122.102." msgstr "Pentru scopurile acestui document, nodul adițional este numit pcmk-2 cu adresa 192.168.122.42." #. Tag: title #, no-c-format msgid "Finalize Networking" msgstr "Finalizați Rețelistica" #. Tag: para #, fuzzy, no-c-format msgid "Confirm that you can communicate between the two new nodes:" msgstr "Confirmați că puteți comunica cu cele două noi noduri:" #. Tag: programlisting #, fuzzy, no-c-format msgid "" "# ping -c 3 192.168.122.102\n" "PING 192.168.122.102 (192.168.122.102) 56(84) bytes of data.\n" "64 bytes from 192.168.122.102: icmp_seq=1 ttl=64 time=0.343 ms\n" "64 bytes from 192.168.122.102: icmp_seq=2 ttl=64 time=0.402 ms\n" "64 bytes from 192.168.122.102: icmp_seq=3 ttl=64 time=0.558 ms\n" "\n" "--- 192.168.122.102 ping statistics ---\n" "3 packets transmitted, 3 received, 0% packet loss, time 2000ms\n" "rtt min/avg/max/mdev = 0.343/0.434/0.558/0.092 ms" msgstr "" "\n" "[root@pcmk-1 ~]# ping -c 3 192.168.122.102\n" "PING 192.168.122.102 (192.168.122.102) 56(84) bytes of data.\n" "64 bytes from 192.168.122.102: icmp_seq=1 ttl=64 time=0.343 ms\n" "64 bytes from 192.168.122.102: icmp_seq=2 ttl=64 time=0.402 ms\n" "64 bytes from 192.168.122.102: icmp_seq=3 ttl=64 time=0.558 ms\n" "\n" "--- 192.168.122.102 ping statistics ---\n" "3 packets transmitted, 3 received, 0% packet loss, time 2000ms\n" "rtt min/avg/max/mdev = 0.343/0.434/0.558/0.092 ms\n" "\t" #. Tag: para #, fuzzy, no-c-format msgid "Now we need to make sure we can communicate with the machines by their name. If you have a DNS server, add additional entries for the two machines. Otherwise, you’ll need to add the machines to /etc/hosts . Below are the entries for my cluster nodes:" msgstr "Acum trebuie să ne asigurăm că putem comunica cu mașinile după numele acestora. Dacă aveți un server DNS, adăugați intrări adiționale pentru cele două mașini. În caz contrar, va trebui să adăugați mașinile în /etc/hosts. Mai jos sunt intrările pentru nodurile mele de cluster:" #. Tag: programlisting #, fuzzy, no-c-format msgid "" "# grep pcmk /etc/hosts\n" "192.168.122.101 pcmk-1.clusterlabs.org pcmk-1\n" "192.168.122.102 pcmk-2.clusterlabs.org pcmk-2" msgstr "" "\n" "[root@pcmk-1 ~]# grep pcmk /etc/hosts\n" "192.168.122.101 pcmk-1.clusterlabs.org pcmk-1\n" "192.168.122.102 pcmk-2.clusterlabs.org pcmk-2\n" "\t" #. Tag: para #, no-c-format msgid "We can now verify the setup by again using ping:" msgstr "Putem verifica setup-ul folosind ping din nou:" #. Tag: programlisting #, fuzzy, no-c-format msgid "" "# ping -c 3 pcmk-2\n" "PING pcmk-2.clusterlabs.org (192.168.122.101) 56(84) bytes of data.\n" "64 bytes from pcmk-1.clusterlabs.org (192.168.122.101): icmp_seq=1 ttl=64 time=0.164 ms\n" "64 bytes from pcmk-1.clusterlabs.org (192.168.122.101): icmp_seq=2 ttl=64 time=0.475 ms\n" "64 bytes from pcmk-1.clusterlabs.org (192.168.122.101): icmp_seq=3 ttl=64 time=0.186 ms\n" "\n" "--- pcmk-2.clusterlabs.org ping statistics ---\n" "3 packets transmitted, 3 received, 0% packet loss, time 2001ms\n" "rtt min/avg/max/mdev = 0.164/0.275/0.475/0.141 ms" msgstr "" "\n" "[root@pcmk-1 ~]# ping -c 3 pcmk-2\n" "PING pcmk-2.clusterlabs.org (192.168.122.101) 56(84) bytes of data.\n" "64 bytes from pcmk-1.clusterlabs.org (192.168.122.101): icmp_seq=1 ttl=64 time=0.164 ms\n" "64 bytes from pcmk-1.clusterlabs.org (192.168.122.101): icmp_seq=2 ttl=64 time=0.475 ms\n" "64 bytes from pcmk-1.clusterlabs.org (192.168.122.101): icmp_seq=3 ttl=64 time=0.186 ms\n" "\n" "--- pcmk-2.clusterlabs.org ping statistics ---\n" "3 packets transmitted, 3 received, 0% packet loss, time 2001ms\n" "rtt min/avg/max/mdev = 0.164/0.275/0.475/0.141 ms\n" "\t" #. Tag: title #, no-c-format msgid "Configure SSH" msgstr "Configurați SSH" #. Tag: para #, fuzzy, no-c-format msgid "SSH is a convenient and secure way to copy files and perform commands remotely. For the purposes of this guide, we will create a key without a password (using the -N option) so that we can perform remote actions without being prompted." msgstr "SSH este un mod convenabil și sigur de a copia fișierele și de a efectua comenzi pe sisteme la distanță. Pentru scopurile acestui ghid, vom crea o cheie fără parolă (folosind opțiunea -N \"\") astfel încât să putem efectua acțiuni la distanță fără a mai fi întrebați." #. Tag: para #, no-c-format msgid " SSH " msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "Unprotected SSH keys, those without a password, are not recommended for servers exposed to the outside world. We use them here only to simplify the demo." msgstr "Chei neprotejate de SSH, precum cele fără parolă, nu sunt recomandate pentru servere expuse la lumea externă." #. Tag: para #, no-c-format msgid "Create a new key and allow anyone with that key to log in:" msgstr "Creați o cheie nouă și permiteți oricui cu acea cheie să se logheze:" #. Tag: title #, no-c-format msgid "Creating and Activating a new SSH Key" msgstr "Crearea și Activarea unei Chei noi SSH" #. Tag: programlisting #, fuzzy, no-c-format msgid "" "# ssh-keygen -t dsa -f ~/.ssh/id_dsa -N \"\"\n" "Generating public/private dsa key pair.\n" "Your identification has been saved in /root/.ssh/id_dsa.\n" "Your public key has been saved in /root/.ssh/id_dsa.pub.\n" "The key fingerprint is:\n" "91:09:5c:82:5a:6a:50:08:4e:b2:0c:62:de:cc:74:44 root@pcmk-1.clusterlabs.org\n" "\n" "The key's randomart image is:\n" "+--[ DSA 1024]----+\n" "|==.ooEo.. |\n" "|X O + .o o |\n" "| * A + |\n" "| + . |\n" "| . S |\n" "| |\n" "| |\n" "| |\n" "| |\n" "+-----------------+\n" "\n" "# cp .ssh/id_dsa.pub .ssh/authorized_keys" msgstr "" "\n" "[root@pcmk-1 ~]# ssh-keygen -t dsa -f ~/.ssh/id_dsa -N \"\"\n" "Generating public/private dsa key pair.\n" "Your identification has been saved in /root/.ssh/id_dsa.\n" "Your public key has been saved in /root/.ssh/id_dsa.pub.\n" "The key fingerprint is:\n" "91:09:5c:82:5a:6a:50:08:4e:b2:0c:62:de:cc:74:44 root@pcmk-1.clusterlabs.org\n" "\n" "The key's randomart image is:\n" "+--[ DSA 1024]----+\n" "|==.ooEo.. |\n" "|X O + .o o |\n" "| * A + |\n" "| + . |\n" "| . S |\n" "| |\n" "| |\n" "| |\n" "| |\n" "+-----------------+\n" "[root@pcmk-1 ~]# cp .ssh/id_dsa.pub .ssh/authorized_keys\n" "[root@pcmk-1 ~]#\n" "\t" #. Tag: para #, fuzzy, no-c-format msgid " Creating and Activating a new SSH Key " msgstr "Crearea și Activarea unei Chei noi SSH" #. Tag: para #, no-c-format msgid "Install the key on the other nodes and test that you can now run commands remotely, without being prompted" msgstr "Instalați cheia pe celelalte noduri și testați că acum puteți rula comenzi de la distanță, fără să mai fiți întrebați" #. Tag: title #, no-c-format msgid "Installing the SSH Key on Another Host" msgstr "Instalarea Cheii SSH pe o Altă Gazdă" #. Tag: programlisting #, fuzzy, no-c-format msgid "" "# scp -r .ssh pcmk-2:\n" "The authenticity of host 'pcmk-2 (192.168.122.102)' can't be established.\n" "RSA key fingerprint is b1:2b:55:93:f1:d9:52:2b:0f:f2:8a:4e:ae:c6:7c:9a.\n" "Are you sure you want to continue connecting (yes/no)? yes\n" "Warning: Permanently added 'pcmk-2,192.168.122.102' (RSA) to the list of known hosts.root@pcmk-2's password:\n" "id_dsa.pub 100% 616 0.6KB/s 00:00\n" "id_dsa 100% 672 0.7KB/s 00:00\n" "known_hosts 100% 400 0.4KB/s 00:00\n" "authorized_keys 100% 616 0.6KB/s 00:00\n" "# ssh pcmk-2 -- uname -n\n" "pcmk-2\n" "#" msgstr "" "\n" "[root@pcmk-1 ~]# scp -r .ssh pcmk-2:\n" "The authenticity of host 'pcmk-2 (192.168.122.102)' can't be established.\n" "RSA key fingerprint is b1:2b:55:93:f1:d9:52:2b:0f:f2:8a:4e:ae:c6:7c:9a.\n" "Are you sure you want to continue connecting (yes/no)? yes\n" "Warning: Permanently added 'pcmk-2,192.168.122.102' (RSA) to the list of known hosts.\n" "root@pcmk-2's password: \n" "id_dsa.pub 100% 616 0.6KB/s 00:00 \n" "id_dsa 100% 672 0.7KB/s 00:00 \n" "known_hosts 100% 400 0.4KB/s 00:00 \n" "authorized_keys 100% 616 0.6KB/s 00:00 \n" "[root@pcmk-1 ~]# ssh pcmk-2 -- uname -n\n" "pcmk-2\n" "[root@pcmk-1 ~]#\n" "\t" #. Tag: title #, no-c-format msgid "Cluster Software Installation" msgstr "Instalarea Software-ului de Cluster" #. Tag: title #, no-c-format msgid "Install the Cluster Software" msgstr "Instalați Software-ul de Cluster" #. Tag: para #, no-c-format msgid "Since version 12, Fedora comes with recent versions of everything you need, so simply fire up the shell and run:" msgstr "Începând cu versiunea 12, Fedora vine cu versiuni recente ale tuturor lucrurilor de care aveți nevoie, așa că pur și simplu porniți shell-ul și rulați:" #. Tag: programlisting #, no-c-format msgid "# yum install -y pacemaker corosync" msgstr "" #. Tag: literallayout #, no-c-format msgid "" "fedora/metalink | 38 kB 00:00\n" "fedora | 4.2 kB 00:00\n" "fedora/primary_db | 14 MB 00:21\n" "updates/metalink | 2.7 kB 00:00\n" "updates | 2.6 kB 00:00\n" "updates/primary_db | 1.2 kB 00:00\n" "updates-testing/metalink | 28 kB 00:00\n" "updates-testing | 4.5 kB 00:00\n" "updates-testing/primary_db | 4.5 MB 00:12\n" "Setting up Install Process\n" "Resolving Dependencies\n" "--> Running transaction check\n" "---> Package corosync.x86_64 0:1.99.9-1.fc17 will be installed\n" "--> Processing Dependency: corosynclib = 1.99.9-1.fc17 for package: corosync-1.99.9-1.fc17.x86_64\n" "--> Processing Dependency: libxslt for package: corosync-1.99.9-1.fc17.x86_64\n" "--> Processing Dependency: libvotequorum.so.5(COROSYNC_VOTEQUORUM_1.0)(64bit) for package: corosync-1.99.9-1.fc17.x86_64\n" "--> Processing Dependency: libquorum.so.5(COROSYNC_QUORUM_1.0)(64bit) for package: corosync-1.99.9-1.fc17.x86_64\n" "--> Processing Dependency: libcpg.so.4(COROSYNC_CPG_1.0)(64bit) for package: corosync-1.99.9-1.fc17.x86_64\n" "--> Processing Dependency: libcmap.so.4(COROSYNC_CMAP_1.0)(64bit) for package: corosync-1.99.9-1.fc17.x86_64\n" "--> Processing Dependency: libcfg.so.6(COROSYNC_CFG_0.82)(64bit) for package: corosync-1.99.9-1.fc17.x86_64\n" "--> Processing Dependency: libvotequorum.so.5()(64bit) for package: corosync-1.99.9-1.fc17.x86_64\n" "--> Processing Dependency: libtotem_pg.so.5()(64bit) for package: corosync-1.99.9-1.fc17.x86_64\n" "--> Processing Dependency: libquorum.so.5()(64bit) for package: corosync-1.99.9-1.fc17.x86_64\n" "--> Processing Dependency: libqb.so.0()(64bit) for package: corosync-1.99.9-1.fc17.x86_64\n" "--> Processing Dependency: libnetsnmp.so.30()(64bit) for package: corosync-1.99.9-1.fc17.x86_64\n" "--> Processing Dependency: libcpg.so.4()(64bit) for package: corosync-1.99.9-1.fc17.x86_64\n" "--> Processing Dependency: libcorosync_common.so.4()(64bit) for package: corosync-1.99.9-1.fc17.x86_64\n" "--> Processing Dependency: libcmap.so.4()(64bit) for package: corosync-1.99.9-1.fc17.x86_64\n" "--> Processing Dependency: libcfg.so.6()(64bit) for package: corosync-1.99.9-1.fc17.x86_64\n" "---> Package pacemaker.x86_64 0:1.1.7-2.fc17 will be installed\n" "--> Processing Dependency: pacemaker-libs = 1.1.7-2.fc17 for package: pacemaker-1.1.7-2.fc17.x86_64\n" "--> Processing Dependency: pacemaker-cluster-libs = 1.1.7-2.fc17 for package: pacemaker-1.1.7-2.fc17.x86_64\n" "--> Processing Dependency: pacemaker-cli = 1.1.7-2.fc17 for package: pacemaker-1.1.7-2.fc17.x86_64\n" "--> Processing Dependency: resource-agents for package: pacemaker-1.1.7-2.fc17.x86_64\n" "--> Processing Dependency: perl(Getopt::Long) for package: pacemaker-1.1.7-2.fc17.x86_64\n" "--> Processing Dependency: libgnutls.so.26(GNUTLS_1_4)(64bit) for package: pacemaker-1.1.7-2.fc17.x86_64\n" "--> Processing Dependency: cluster-glue for package: pacemaker-1.1.7-2.fc17.x86_64\n" "--> Processing Dependency: /usr/bin/perl for package: pacemaker-1.1.7-2.fc17.x86_64\n" "--> Processing Dependency: libtransitioner.so.1()(64bit) for package: pacemaker-1.1.7-2.fc17.x86_64\n" "--> Processing Dependency: libstonithd.so.1()(64bit) for package: pacemaker-1.1.7-2.fc17.x86_64\n" "--> Processing Dependency: libstonith.so.1()(64bit) for package: pacemaker-1.1.7-2.fc17.x86_64\n" "--> Processing Dependency: libplumb.so.2()(64bit) for package: pacemaker-1.1.7-2.fc17.x86_64\n" "--> Processing Dependency: libpils.so.2()(64bit) for package: pacemaker-1.1.7-2.fc17.x86_64\n" "--> Processing Dependency: libpengine.so.3()(64bit) for package: pacemaker-1.1.7-2.fc17.x86_64\n" "--> Processing Dependency: libpe_status.so.3()(64bit) for package: pacemaker-1.1.7-2.fc17.x86_64\n" "--> Processing Dependency: libpe_rules.so.2()(64bit) for package: pacemaker-1.1.7-2.fc17.x86_64\n" "--> Processing Dependency: libltdl.so.7()(64bit) for package: pacemaker-1.1.7-2.fc17.x86_64\n" "--> Processing Dependency: liblrm.so.2()(64bit) for package: pacemaker-1.1.7-2.fc17.x86_64\n" "--> Processing Dependency: libgnutls.so.26()(64bit) for package: pacemaker-1.1.7-2.fc17.x86_64\n" "--> Processing Dependency: libcrmcommon.so.2()(64bit) for package: pacemaker-1.1.7-2.fc17.x86_64\n" "--> Processing Dependency: libcrmcluster.so.1()(64bit) for package: pacemaker-1.1.7-2.fc17.x86_64\n" "--> Processing Dependency: libcib.so.1()(64bit) for package: pacemaker-1.1.7-2.fc17.x86_64\n" "--> Running transaction check\n" "---> Package cluster-glue.x86_64 0:1.0.6-9.fc17.1 will be installed\n" "--> Processing Dependency: perl-TimeDate for package: cluster-glue-1.0.6-9.fc17.1.x86_64\n" "--> Processing Dependency: libOpenIPMIutils.so.0()(64bit) for package: cluster-glue-1.0.6-9.fc17.1.x86_64\n" "--> Processing Dependency: libOpenIPMIposix.so.0()(64bit) for package: cluster-glue-1.0.6-9.fc17.1.x86_64\n" "--> Processing Dependency: libOpenIPMI.so.0()(64bit) for package: cluster-glue-1.0.6-9.fc17.1.x86_64\n" "---> Package cluster-glue-libs.x86_64 0:1.0.6-9.fc17.1 will be installed\n" "---> Package corosynclib.x86_64 0:1.99.9-1.fc17 will be installed\n" "--> Processing Dependency: librdmacm.so.1(RDMACM_1.0)(64bit) for package: corosynclib-1.99.9-1.fc17.x86_64\n" "--> Processing Dependency: libibverbs.so.1(IBVERBS_1.1)(64bit) for package: corosynclib-1.99.9-1.fc17.x86_64\n" "--> Processing Dependency: libibverbs.so.1(IBVERBS_1.0)(64bit) for package: corosynclib-1.99.9-1.fc17.x86_64\n" "--> Processing Dependency: librdmacm.so.1()(64bit) for package: corosynclib-1.99.9-1.fc17.x86_64\n" "--> Processing Dependency: libibverbs.so.1()(64bit) for package: corosynclib-1.99.9-1.fc17.x86_64\n" "---> Package gnutls.x86_64 0:2.12.17-1.fc17 will be installed\n" "--> Processing Dependency: libtasn1.so.3(LIBTASN1_0_3)(64bit) for package: gnutls-2.12.17-1.fc17.x86_64\n" "--> Processing Dependency: libtasn1.so.3()(64bit) for package: gnutls-2.12.17-1.fc17.x86_64\n" "--> Processing Dependency: libp11-kit.so.0()(64bit) for package: gnutls-2.12.17-1.fc17.x86_64\n" "---> Package libqb.x86_64 0:0.11.1-1.fc17 will be installed\n" "---> Package libtool-ltdl.x86_64 0:2.4.2-3.fc17 will be installed\n" "---> Package libxslt.x86_64 0:1.1.26-9.fc17 will be installed\n" "---> Package net-snmp-libs.x86_64 1:5.7.1-4.fc17 will be installed\n" "---> Package pacemaker-cli.x86_64 0:1.1.7-2.fc17 will be installed\n" "---> Package pacemaker-cluster-libs.x86_64 0:1.1.7-2.fc17 will be installed\n" "---> Package pacemaker-libs.x86_64 0:1.1.7-2.fc17 will be installed\n" "---> Package perl.x86_64 4:5.14.2-211.fc17 will be installed\n" "--> Processing Dependency: perl-libs = 4:5.14.2-211.fc17 for package: 4:perl-5.14.2-211.fc17.x86_64\n" "--> Processing Dependency: perl(threads::shared) >= 1.21 for package: 4:perl-5.14.2-211.fc17.x86_64\n" "--> Processing Dependency: perl(Socket) >= 1.3 for package: 4:perl-5.14.2-211.fc17.x86_64\n" "--> Processing Dependency: perl(Scalar::Util) >= 1.10 for package: 4:perl-5.14.2-211.fc17.x86_64\n" "--> Processing Dependency: perl(File::Spec) >= 0.8 for package: 4:perl-5.14.2-211.fc17.x86_64\n" "--> Processing Dependency: perl-macros for package: 4:perl-5.14.2-211.fc17.x86_64\n" "--> Processing Dependency: perl-libs for package: 4:perl-5.14.2-211.fc17.x86_64\n" "--> Processing Dependency: perl(threads::shared) for package: 4:perl-5.14.2-211.fc17.x86_64\n" "--> Processing Dependency: perl(threads) for package: 4:perl-5.14.2-211.fc17.x86_64\n" "--> Processing Dependency: perl(Socket) for package: 4:perl-5.14.2-211.fc17.x86_64\n" "--> Processing Dependency: perl(Scalar::Util) for package: 4:perl-5.14.2-211.fc17.x86_64\n" "--> Processing Dependency: perl(Pod::Simple) for package: 4:perl-5.14.2-211.fc17.x86_64\n" "--> Processing Dependency: perl(Module::Pluggable) for package: 4:perl-5.14.2-211.fc17.x86_64\n" "--> Processing Dependency: perl(List::Util) for package: 4:perl-5.14.2-211.fc17.x86_64\n" "--> Processing Dependency: perl(File::Spec::Unix) for package: 4:perl-5.14.2-211.fc17.x86_64\n" "--> Processing Dependency: perl(File::Spec::Functions) for package: 4:perl-5.14.2-211.fc17.x86_64\n" "--> Processing Dependency: perl(File::Spec) for package: 4:perl-5.14.2-211.fc17.x86_64\n" "--> Processing Dependency: perl(Cwd) for package: 4:perl-5.14.2-211.fc17.x86_64\n" "--> Processing Dependency: perl(Carp) for package: 4:perl-5.14.2-211.fc17.x86_64\n" "--> Processing Dependency: libperl.so()(64bit) for package: 4:perl-5.14.2-211.fc17.x86_64\n" "---> Package resource-agents.x86_64 0:3.9.2-2.fc17.1 will be installed\n" "--> Processing Dependency: /usr/sbin/rpc.nfsd for package: resource-agents-3.9.2-2.fc17.1.x86_64\n" "--> Processing Dependency: /usr/sbin/rpc.mountd for package: resource-agents-3.9.2-2.fc17.1.x86_64\n" "--> Processing Dependency: /usr/sbin/ethtool for package: resource-agents-3.9.2-2.fc17.1.x86_64\n" "--> Processing Dependency: /sbin/rpc.statd for package: resource-agents-3.9.2-2.fc17.1.x86_64\n" "--> Processing Dependency: /sbin/quotaon for package: resource-agents-3.9.2-2.fc17.1.x86_64\n" "--> Processing Dependency: /sbin/quotacheck for package: resource-agents-3.9.2-2.fc17.1.x86_64\n" "--> Processing Dependency: /sbin/mount.nfs4 for package: resource-agents-3.9.2-2.fc17.1.x86_64\n" "--> Processing Dependency: /sbin/mount.nfs for package: resource-agents-3.9.2-2.fc17.1.x86_64\n" "--> Processing Dependency: /sbin/mount.cifs for package: resource-agents-3.9.2-2.fc17.1.x86_64\n" "--> Processing Dependency: /sbin/fsck.xfs for package: resource-agents-3.9.2-2.fc17.1.x86_64\n" "--> Processing Dependency: libnet.so.1()(64bit) for package: resource-agents-3.9.2-2.fc17.1.x86_64\n" "--> Running transaction check\n" "---> Package OpenIPMI-libs.x86_64 0:2.0.18-13.fc17 will be installed\n" "---> Package cifs-utils.x86_64 0:5.3-2.fc17 will be installed\n" "--> Processing Dependency: libtalloc.so.2(TALLOC_2.0.2)(64bit) for package: cifs-utils-5.3-2.fc17.x86_64\n" "--> Processing Dependency: keyutils for package: cifs-utils-5.3-2.fc17.x86_64\n" "--> Processing Dependency: libwbclient.so.0()(64bit) for package: cifs-utils-5.3-2.fc17.x86_64\n" "--> Processing Dependency: libtalloc.so.2()(64bit) for package: cifs-utils-5.3-2.fc17.x86_64\n" "---> Package ethtool.x86_64 2:3.2-2.fc17 will be installed\n" "---> Package libibverbs.x86_64 0:1.1.6-2.fc17 will be installed\n" "---> Package libnet.x86_64 0:1.1.5-3.fc17 will be installed\n" "---> Package librdmacm.x86_64 0:1.0.15-1.fc17 will be installed\n" "---> Package libtasn1.x86_64 0:2.12-1.fc17 will be installed\n" "---> Package nfs-utils.x86_64 1:1.2.5-12.fc17 will be installed\n" "--> Processing Dependency: rpcbind for package: 1:nfs-utils-1.2.5-12.fc17.x86_64\n" "--> Processing Dependency: libtirpc for package: 1:nfs-utils-1.2.5-12.fc17.x86_64\n" "--> Processing Dependency: libnfsidmap for package: 1:nfs-utils-1.2.5-12.fc17.x86_64\n" "--> Processing Dependency: libgssglue.so.1(libgssapi_CITI_2)(64bit) for package: 1:nfs-utils-1.2.5-12.fc17.x86_64\n" "--> Processing Dependency: libgssglue for package: 1:nfs-utils-1.2.5-12.fc17.x86_64\n" "--> Processing Dependency: libevent for package: 1:nfs-utils-1.2.5-12.fc17.x86_64\n" "--> Processing Dependency: libtirpc.so.1()(64bit) for package: 1:nfs-utils-1.2.5-12.fc17.x86_64\n" "--> Processing Dependency: libnfsidmap.so.0()(64bit) for package: 1:nfs-utils-1.2.5-12.fc17.x86_64\n" "--> Processing Dependency: libgssglue.so.1()(64bit) for package: 1:nfs-utils-1.2.5-12.fc17.x86_64\n" "--> Processing Dependency: libevent-2.0.so.5()(64bit) for package: 1:nfs-utils-1.2.5-12.fc17.x86_64\n" "---> Package p11-kit.x86_64 0:0.12-1.fc17 will be installed\n" "---> Package perl-Carp.noarch 0:1.22-2.fc17 will be installed\n" "---> Package perl-Module-Pluggable.noarch 1:3.90-211.fc17 will be installed\n" "---> Package perl-PathTools.x86_64 0:3.33-211.fc17 will be installed\n" "---> Package perl-Pod-Simple.noarch 1:3.16-211.fc17 will be installed\n" "--> Processing Dependency: perl(Pod::Escapes) >= 1.04 for package: 1:perl-Pod-Simple-3.16-211.fc17.noarch\n" "---> Package perl-Scalar-List-Utils.x86_64 0:1.25-1.fc17 will be installed\n" "---> Package perl-Socket.x86_64 0:2.001-1.fc17 will be installed\n" "---> Package perl-TimeDate.noarch 1:1.20-6.fc17 will be installed\n" "---> Package perl-libs.x86_64 4:5.14.2-211.fc17 will be installed\n" "---> Package perl-macros.x86_64 4:5.14.2-211.fc17 will be installed\n" "---> Package perl-threads.x86_64 0:1.86-2.fc17 will be installed\n" "---> Package perl-threads-shared.x86_64 0:1.40-2.fc17 will be installed\n" "---> Package quota.x86_64 1:4.00-3.fc17 will be installed\n" "--> Processing Dependency: quota-nls = 1:4.00-3.fc17 for package: 1:quota-4.00-3.fc17.x86_64\n" "--> Processing Dependency: tcp_wrappers for package: 1:quota-4.00-3.fc17.x86_64\n" "---> Package xfsprogs.x86_64 0:3.1.8-1.fc17 will be installed\n" "--> Running transaction check\n" "---> Package keyutils.x86_64 0:1.5.5-2.fc17 will be installed\n" "---> Package libevent.x86_64 0:2.0.14-2.fc17 will be installed\n" "---> Package libgssglue.x86_64 0:0.3-1.fc17 will be installed\n" "---> Package libnfsidmap.x86_64 0:0.25-1.fc17 will be installed\n" "---> Package libtalloc.x86_64 0:2.0.7-4.fc17 will be installed\n" "---> Package libtirpc.x86_64 0:0.2.2-2.1.fc17 will be installed\n" "---> Package libwbclient.x86_64 1:3.6.3-81.fc17.1 will be installed\n" "---> Package perl-Pod-Escapes.noarch 1:1.04-211.fc17 will be installed\n" "---> Package quota-nls.noarch 1:4.00-3.fc17 will be installed\n" "---> Package rpcbind.x86_64 0:0.2.0-16.fc17 will be installed\n" "---> Package tcp_wrappers.x86_64 0:7.6-69.fc17 will be installed\n" "--> Finished Dependency Resolution\n" "\n" "Dependencies Resolved\n" "\n" "=====================================================================================\n" " Package Arch Version Repository Size\n" "=====================================================================================\n" "Installing:\n" " corosync x86_64 1.99.9-1.fc17 updates-testing 159 k\n" " pacemaker x86_64 1.1.7-2.fc17 updates-testing 362 k\n" "Installing for dependencies:\n" " OpenIPMI-libs x86_64 2.0.18-13.fc17 fedora 466 k\n" " cifs-utils x86_64 5.3-2.fc17 updates-testing 66 k\n" " cluster-glue x86_64 1.0.6-9.fc17.1 fedora 229 k\n" " cluster-glue-libs x86_64 1.0.6-9.fc17.1 fedora 121 k\n" " corosynclib x86_64 1.99.9-1.fc17 updates-testing 96 k\n" " ethtool x86_64 2:3.2-2.fc17 fedora 94 k\n" " gnutls x86_64 2.12.17-1.fc17 fedora 385 k\n" " keyutils x86_64 1.5.5-2.fc17 fedora 49 k\n" " libevent x86_64 2.0.14-2.fc17 fedora 160 k\n" " libgssglue x86_64 0.3-1.fc17 fedora 24 k\n" " libibverbs x86_64 1.1.6-2.fc17 fedora 44 k\n" " libnet x86_64 1.1.5-3.fc17 fedora 54 k\n" " libnfsidmap x86_64 0.25-1.fc17 fedora 34 k\n" " libqb x86_64 0.11.1-1.fc17 updates-testing 68 k\n" " librdmacm x86_64 1.0.15-1.fc17 fedora 27 k\n" " libtalloc x86_64 2.0.7-4.fc17 fedora 22 k\n" " libtasn1 x86_64 2.12-1.fc17 updates-testing 319 k\n" " libtirpc x86_64 0.2.2-2.1.fc17 fedora 78 k\n" " libtool-ltdl x86_64 2.4.2-3.fc17 fedora 45 k\n" " libwbclient x86_64 1:3.6.3-81.fc17.1 updates-testing 68 k\n" " libxslt x86_64 1.1.26-9.fc17 fedora 416 k\n" " net-snmp-libs x86_64 1:5.7.1-4.fc17 fedora 713 k\n" " nfs-utils x86_64 1:1.2.5-12.fc17 fedora 311 k\n" " p11-kit x86_64 0.12-1.fc17 updates-testing 36 k\n" " pacemaker-cli x86_64 1.1.7-2.fc17 updates-testing 368 k\n" " pacemaker-cluster-libs x86_64 1.1.7-2.fc17 updates-testing 77 k\n" " pacemaker-libs x86_64 1.1.7-2.fc17 updates-testing 322 k\n" " perl x86_64 4:5.14.2-211.fc17 fedora 10 M\n" " perl-Carp noarch 1.22-2.fc17 fedora 17 k\n" " perl-Module-Pluggable noarch 1:3.90-211.fc17 fedora 47 k\n" " perl-PathTools x86_64 3.33-211.fc17 fedora 105 k\n" " perl-Pod-Escapes noarch 1:1.04-211.fc17 fedora 40 k\n" " perl-Pod-Simple noarch 1:3.16-211.fc17 fedora 223 k\n" " perl-Scalar-List-Utils x86_64 1.25-1.fc17 updates-testing 33 k\n" " perl-Socket x86_64 2.001-1.fc17 updates-testing 44 k\n" " perl-TimeDate noarch 1:1.20-6.fc17 fedora 43 k\n" " perl-libs x86_64 4:5.14.2-211.fc17 fedora 628 k\n" " perl-macros x86_64 4:5.14.2-211.fc17 fedora 32 k\n" " perl-threads x86_64 1.86-2.fc17 fedora 47 k\n" " perl-threads-shared x86_64 1.40-2.fc17 fedora 36 k\n" " quota x86_64 1:4.00-3.fc17 fedora 160 k\n" " quota-nls noarch 1:4.00-3.fc17 fedora 74 k\n" " resource-agents x86_64 3.9.2-2.fc17.1 fedora 466 k\n" " rpcbind x86_64 0.2.0-16.fc17 fedora 52 k\n" " tcp_wrappers x86_64 7.6-69.fc17 fedora 72 k\n" " xfsprogs x86_64 3.1.8-1.fc17 updates-testing 715 k\n" "\n" "Transaction Summary\n" "=====================================================================================\n" "Install 2 Packages (+46 Dependent packages)\n" "\n" "Total download size: 18 M\n" "Installed size: 59 M\n" "Downloading Packages:\n" "(1/48): OpenIPMI-libs-2.0.18-13.fc17.x86_64.rpm | 466 kB 00:00\n" "warning: rpmts_HdrFromFdno: Header V3 RSA/SHA256 Signature, key ID 1aca3465: NOKEY\n" "Public key for OpenIPMI-libs-2.0.18-13.fc17.x86_64.rpm is not installed\n" "(2/48): cifs-utils-5.3-2.fc17.x86_64.rpm | 66 kB 00:01\n" "Public key for cifs-utils-5.3-2.fc17.x86_64.rpm is not installed\n" "(3/48): cluster-glue-1.0.6-9.fc17.1.x86_64.rpm | 229 kB 00:00\n" "(4/48): cluster-glue-libs-1.0.6-9.fc17.1.x86_64.rpm | 121 kB 00:00\n" "(5/48): corosync-1.99.9-1.fc17.x86_64.rpm | 159 kB 00:01\n" "(6/48): corosynclib-1.99.9-1.fc17.x86_64.rpm | 96 kB 00:00\n" "(7/48): ethtool-3.2-2.fc17.x86_64.rpm | 94 kB 00:00\n" "(8/48): gnutls-2.12.17-1.fc17.x86_64.rpm | 385 kB 00:00\n" "(9/48): keyutils-1.5.5-2.fc17.x86_64.rpm | 49 kB 00:00\n" "(10/48): libevent-2.0.14-2.fc17.x86_64.rpm | 160 kB 00:00\n" "(11/48): libgssglue-0.3-1.fc17.x86_64.rpm | 24 kB 00:00\n" "(12/48): libibverbs-1.1.6-2.fc17.x86_64.rpm | 44 kB 00:00\n" "(13/48): libnet-1.1.5-3.fc17.x86_64.rpm | 54 kB 00:00\n" "(14/48): libnfsidmap-0.25-1.fc17.x86_64.rpm | 34 kB 00:00\n" "(15/48): libqb-0.11.1-1.fc17.x86_64.rpm | 68 kB 00:01\n" "(16/48): librdmacm-1.0.15-1.fc17.x86_64.rpm | 27 kB 00:00\n" "(17/48): libtalloc-2.0.7-4.fc17.x86_64.rpm | 22 kB 00:00\n" "(18/48): libtasn1-2.12-1.fc17.x86_64.rpm | 319 kB 00:02\n" "(19/48): libtirpc-0.2.2-2.1.fc17.x86_64.rpm | 78 kB 00:00\n" "(20/48): libtool-ltdl-2.4.2-3.fc17.x86_64.rpm | 45 kB 00:00\n" "(21/48): libwbclient-3.6.3-81.fc17.1.x86_64.rpm | 68 kB 00:00\n" "(22/48): libxslt-1.1.26-9.fc17.x86_64.rpm | 416 kB 00:00\n" "(23/48): net-snmp-libs-5.7.1-4.fc17.x86_64.rpm | 713 kB 00:01\n" "(24/48): nfs-utils-1.2.5-12.fc17.x86_64.rpm | 311 kB 00:00\n" "(25/48): p11-kit-0.12-1.fc17.x86_64.rpm | 36 kB 00:01\n" "(26/48): pacemaker-1.1.7-2.fc17.x86_64.rpm | 362 kB 00:02\n" "(27/48): pacemaker-cli-1.1.7-2.fc17.x86_64.rpm | 368 kB 00:02\n" "(28/48): pacemaker-cluster-libs-1.1.7-2.fc17.x86_64.rpm | 77 kB 00:00\n" "(29/48): pacemaker-libs-1.1.7-2.fc17.x86_64.rpm | 322 kB 00:01\n" "(30/48): perl-5.14.2-211.fc17.x86_64.rpm | 10 MB 00:15\n" "(31/48): perl-Carp-1.22-2.fc17.noarch.rpm | 17 kB 00:00\n" "(32/48): perl-Module-Pluggable-3.90-211.fc17.noarch.rpm | 47 kB 00:00\n" "(33/48): perl-PathTools-3.33-211.fc17.x86_64.rpm | 105 kB 00:00\n" "(34/48): perl-Pod-Escapes-1.04-211.fc17.noarch.rpm | 40 kB 00:00\n" "(35/48): perl-Pod-Simple-3.16-211.fc17.noarch.rpm | 223 kB 00:00\n" "(36/48): perl-Scalar-List-Utils-1.25-1.fc17.x86_64.rpm | 33 kB 00:01\n" "(37/48): perl-Socket-2.001-1.fc17.x86_64.rpm | 44 kB 00:00\n" "(38/48): perl-TimeDate-1.20-6.fc17.noarch.rpm | 43 kB 00:00\n" "(39/48): perl-libs-5.14.2-211.fc17.x86_64.rpm | 628 kB 00:00\n" "(40/48): perl-macros-5.14.2-211.fc17.x86_64.rpm | 32 kB 00:00\n" "(41/48): perl-threads-1.86-2.fc17.x86_64.rpm | 47 kB 00:00\n" "(42/48): perl-threads-shared-1.40-2.fc17.x86_64.rpm | 36 kB 00:00\n" "(43/48): quota-4.00-3.fc17.x86_64.rpm | 160 kB 00:00\n" "(44/48): quota-nls-4.00-3.fc17.noarch.rpm | 74 kB 00:00\n" "(45/48): resource-agents-3.9.2-2.fc17.1.x86_64.rpm | 466 kB 00:00\n" "(46/48): rpcbind-0.2.0-16.fc17.x86_64.rpm | 52 kB 00:00\n" "(47/48): tcp_wrappers-7.6-69.fc17.x86_64.rpm | 72 kB 00:00\n" "(48/48): xfsprogs-3.1.8-1.fc17.x86_64.rpm | 715 kB 00:03\n" "----------------------------------------------------------------------------------------\n" "Total 333 kB/s | 18 MB 00:55\n" "Retrieving key from file:///etc/pki/rpm-gpg/RPM-GPG-KEY-fedora-x86_64\n" "Importing GPG key 0x1ACA3465:\n" " Userid : \"Fedora (17) <fedora@fedoraproject.org>\"\n" " Fingerprint: cac4 3fb7 74a4 a673 d81c 5de7 50e9 4c99 1aca 3465\n" " Package : fedora-release-17-0.8.noarch (@anaconda-0)\n" " From : /etc/pki/rpm-gpg/RPM-GPG-KEY-fedora-x86_64\n" "Running Transaction Check\n" "Running Transaction Test\n" "Transaction Test Succeeded\n" "Running Transaction\n" " Installing : libqb-0.11.1-1.fc17.x86_64 1/48\n" " Installing : libtool-ltdl-2.4.2-3.fc17.x86_64 2/48\n" " Installing : cluster-glue-libs-1.0.6-9.fc17.1.x86_64 3/48\n" " Installing : libxslt-1.1.26-9.fc17.x86_64 4/48\n" " Installing : 1:perl-Pod-Escapes-1.04-211.fc17.noarch 5/48\n" " Installing : perl-threads-1.86-2.fc17.x86_64 6/48\n" " Installing : 4:perl-macros-5.14.2-211.fc17.x86_64 7/48\n" " Installing : 1:perl-Pod-Simple-3.16-211.fc17.noarch 8/48\n" " Installing : perl-Socket-2.001-1.fc17.x86_64 9/48\n" " Installing : perl-Carp-1.22-2.fc17.noarch 10/48\n" " Installing : 4:perl-libs-5.14.2-211.fc17.x86_64 11/48\n" " Installing : perl-threads-shared-1.40-2.fc17.x86_64 12/48\n" " Installing : perl-Scalar-List-Utils-1.25-1.fc17.x86_64 13/48\n" " Installing : 1:perl-Module-Pluggable-3.90-211.fc17.noarch 14/48\n" " Installing : perl-PathTools-3.33-211.fc17.x86_64 15/48\n" " Installing : 4:perl-5.14.2-211.fc17.x86_64 16/48\n" " Installing : libibverbs-1.1.6-2.fc17.x86_64 17/48\n" " Installing : keyutils-1.5.5-2.fc17.x86_64 18/48\n" " Installing : libgssglue-0.3-1.fc17.x86_64 19/48\n" " Installing : libtirpc-0.2.2-2.1.fc17.x86_64 20/48\n" " Installing : 1:net-snmp-libs-5.7.1-4.fc17.x86_64 21/48\n" " Installing : rpcbind-0.2.0-16.fc17.x86_64 22/48\n" " Installing : librdmacm-1.0.15-1.fc17.x86_64 23/48\n" " Installing : corosynclib-1.99.9-1.fc17.x86_64 24/48\n" " Installing : corosync-1.99.9-1.fc17.x86_64 25/48\n" "error reading information on service corosync: No such file or directory\n" " Installing : 1:perl-TimeDate-1.20-6.fc17.noarch 26/48\n" " Installing : 1:quota-nls-4.00-3.fc17.noarch 27/48\n" " Installing : tcp_wrappers-7.6-69.fc17.x86_64 28/48\n" " Installing : 1:quota-4.00-3.fc17.x86_64 29/48\n" " Installing : libnfsidmap-0.25-1.fc17.x86_64 30/48\n" " Installing : 1:libwbclient-3.6.3-81.fc17.1.x86_64 31/48\n" " Installing : libnet-1.1.5-3.fc17.x86_64 32/48\n" " Installing : 2:ethtool-3.2-2.fc17.x86_64 33/48\n" " Installing : libevent-2.0.14-2.fc17.x86_64 34/48\n" " Installing : 1:nfs-utils-1.2.5-12.fc17.x86_64 35/48\n" " Installing : libtalloc-2.0.7-4.fc17.x86_64 36/48\n" " Installing : cifs-utils-5.3-2.fc17.x86_64 37/48\n" " Installing : libtasn1-2.12-1.fc17.x86_64 38/48\n" " Installing : OpenIPMI-libs-2.0.18-13.fc17.x86_64 39/48\n" " Installing : cluster-glue-1.0.6-9.fc17.1.x86_64 40/48\n" " Installing : p11-kit-0.12-1.fc17.x86_64 41/48\n" " Installing : gnutls-2.12.17-1.fc17.x86_64 42/48\n" " Installing : pacemaker-libs-1.1.7-2.fc17.x86_64 43/48\n" " Installing : pacemaker-cluster-libs-1.1.7-2.fc17.x86_64 44/48\n" " Installing : pacemaker-cli-1.1.7-2.fc17.x86_64 45/48\n" " Installing : xfsprogs-3.1.8-1.fc17.x86_64 46/48\n" " Installing : resource-agents-3.9.2-2.fc17.1.x86_64 47/48\n" " Installing : pacemaker-1.1.7-2.fc17.x86_64 48/48\n" " Verifying : xfsprogs-3.1.8-1.fc17.x86_64 1/48\n" " Verifying : 1:net-snmp-libs-5.7.1-4.fc17.x86_64 2/48\n" " Verifying : corosync-1.99.9-1.fc17.x86_64 3/48\n" " Verifying : cluster-glue-1.0.6-9.fc17.1.x86_64 4/48\n" " Verifying : perl-PathTools-3.33-211.fc17.x86_64 5/48\n" " Verifying : p11-kit-0.12-1.fc17.x86_64 6/48\n" " Verifying : 1:perl-Pod-Simple-3.16-211.fc17.noarch 7/48\n" " Verifying : OpenIPMI-libs-2.0.18-13.fc17.x86_64 8/48\n" " Verifying : libtasn1-2.12-1.fc17.x86_64 9/48\n" " Verifying : perl-threads-1.86-2.fc17.x86_64 10/48\n" " Verifying : 1:perl-Pod-Escapes-1.04-211.fc17.noarch 11/48\n" " Verifying : pacemaker-1.1.7-2.fc17.x86_64 12/48\n" " Verifying : 4:perl-5.14.2-211.fc17.x86_64 13/48\n" " Verifying : gnutls-2.12.17-1.fc17.x86_64 14/48\n" " Verifying : perl-threads-shared-1.40-2.fc17.x86_64 15/48\n" " Verifying : 4:perl-macros-5.14.2-211.fc17.x86_64 16/48\n" " Verifying : 1:perl-Module-Pluggable-3.90-211.fc17.noarch 17/48\n" " Verifying : 1:nfs-utils-1.2.5-12.fc17.x86_64 18/48\n" " Verifying : cluster-glue-libs-1.0.6-9.fc17.1.x86_64 19/48\n" " Verifying : pacemaker-libs-1.1.7-2.fc17.x86_64 20/48\n" " Verifying : libtalloc-2.0.7-4.fc17.x86_64 21/48\n" " Verifying : libevent-2.0.14-2.fc17.x86_64 22/48\n" " Verifying : perl-Socket-2.001-1.fc17.x86_64 23/48\n" " Verifying : libgssglue-0.3-1.fc17.x86_64 24/48\n" " Verifying : perl-Carp-1.22-2.fc17.noarch 25/48\n" " Verifying : libtirpc-0.2.2-2.1.fc17.x86_64 26/48\n" " Verifying : 2:ethtool-3.2-2.fc17.x86_64 27/48\n" " Verifying : 4:perl-libs-5.14.2-211.fc17.x86_64 28/48\n" " Verifying : libxslt-1.1.26-9.fc17.x86_64 29/48\n" " Verifying : rpcbind-0.2.0-16.fc17.x86_64 30/48\n" " Verifying : librdmacm-1.0.15-1.fc17.x86_64 31/48\n" " Verifying : resource-agents-3.9.2-2.fc17.1.x86_64 32/48\n" " Verifying : 1:quota-4.00-3.fc17.x86_64 33/48\n" " Verifying : 1:perl-TimeDate-1.20-6.fc17.noarch 34/48\n" " Verifying : perl-Scalar-List-Utils-1.25-1.fc17.x86_64 35/48\n" " Verifying : libtool-ltdl-2.4.2-3.fc17.x86_64 36/48\n" " Verifying : pacemaker-cluster-libs-1.1.7-2.fc17.x86_64 37/48\n" " Verifying : cifs-utils-5.3-2.fc17.x86_64 38/48\n" " Verifying : libnet-1.1.5-3.fc17.x86_64 39/48\n" " Verifying : corosynclib-1.99.9-1.fc17.x86_64 40/48\n" " Verifying : libqb-0.11.1-1.fc17.x86_64 41/48\n" " Verifying : 1:libwbclient-3.6.3-81.fc17.1.x86_64 42/48\n" " Verifying : libnfsidmap-0.25-1.fc17.x86_64 43/48\n" " Verifying : tcp_wrappers-7.6-69.fc17.x86_64 44/48\n" " Verifying : keyutils-1.5.5-2.fc17.x86_64 45/48\n" " Verifying : libibverbs-1.1.6-2.fc17.x86_64 46/48\n" " Verifying : 1:quota-nls-4.00-3.fc17.noarch 47/48\n" " Verifying : pacemaker-cli-1.1.7-2.fc17.x86_64 48/48\n" "\n" "Installed:\n" " corosync.x86_64 0:1.99.9-1.fc17 pacemaker.x86_64 0:1.1.7-2.fc17\n" "\n" "Dependency Installed:\n" " OpenIPMI-libs.x86_64 0:2.0.18-13.fc17 cifs-utils.x86_64 0:5.3-2.fc17\n" " cluster-glue.x86_64 0:1.0.6-9.fc17.1 cluster-glue-libs.x86_64 0:1.0.6-9.fc17.1\n" " corosynclib.x86_64 0:1.99.9-1.fc17 ethtool.x86_64 2:3.2-2.fc17\n" " gnutls.x86_64 0:2.12.17-1.fc17 keyutils.x86_64 0:1.5.5-2.fc17\n" " libevent.x86_64 0:2.0.14-2.fc17 libgssglue.x86_64 0:0.3-1.fc17\n" " libibverbs.x86_64 0:1.1.6-2.fc17 libnet.x86_64 0:1.1.5-3.fc17\n" " libnfsidmap.x86_64 0:0.25-1.fc17 libqb.x86_64 0:0.11.1-1.fc17\n" " librdmacm.x86_64 0:1.0.15-1.fc17 libtalloc.x86_64 0:2.0.7-4.fc17\n" " libtasn1.x86_64 0:2.12-1.fc17 libtirpc.x86_64 0:0.2.2-2.1.fc17\n" " libtool-ltdl.x86_64 0:2.4.2-3.fc17 libwbclient.x86_64 1:3.6.3-81.fc17.1\n" " libxslt.x86_64 0:1.1.26-9.fc17 net-snmp-libs.x86_64 1:5.7.1-4.fc17\n" " nfs-utils.x86_64 1:1.2.5-12.fc17 p11-kit.x86_64 0:0.12-1.fc17\n" " pacemaker-cli.x86_64 0:1.1.7-2.fc17 pacemaker-cluster-libs.x86_64 0:1.1.7-2.fc17\n" " pacemaker-libs.x86_64 0:1.1.7-2.fc17 perl.x86_64 4:5.14.2-211.fc17\n" " perl-Carp.noarch 0:1.22-2.fc17 perl-Module-Pluggable.noarch 1:3.90-211.fc17\n" " perl-PathTools.x86_64 0:3.33-211.fc17 perl-Pod-Escapes.noarch 1:1.04-211.fc17\n" " perl-Pod-Simple.noarch 1:3.16-211.fc17 perl-Scalar-List-Utils.x86_64 0:1.25-1.fc17\n" " perl-Socket.x86_64 0:2.001-1.fc17 perl-TimeDate.noarch 1:1.20-6.fc17\n" " perl-libs.x86_64 4:5.14.2-211.fc17 perl-macros.x86_64 4:5.14.2-211.fc17\n" " perl-threads.x86_64 0:1.86-2.fc17 perl-threads-shared.x86_64 0:1.40-2.fc17\n" " quota.x86_64 1:4.00-3.fc17 quota-nls.noarch 1:4.00-3.fc17\n" " resource-agents.x86_64 0:3.9.2-2.fc17.1 rpcbind.x86_64 0:0.2.0-16.fc17\n" " tcp_wrappers.x86_64 0:7.6-69.fc17 xfsprogs.x86_64 0:3.1.8-1.fc17\n" "\n" "Complete!\n" "[root@pcmk-1 ~]#" msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "Now install the cluster software on the second node." msgstr "Instalați Software-ul de Cluster" #. Tag: title #, fuzzy, no-c-format msgid "Install the Cluster Management Software" msgstr "Instalați Software-ul de Cluster" #. Tag: para #, no-c-format msgid "The pcs cli command coupled with the pcs daemon creates a cluster management system capable of managing all aspects of the cluster stack across all nodes from a single location." msgstr "" #. Tag: programlisting #, no-c-format msgid "# yum install -y pcs" msgstr "" #. Tag: para #, no-c-format msgid "Make sure to install the pcs packages on both nodes." msgstr "" #. Tag: title #, no-c-format msgid "Setup" msgstr "Setup" #. Tag: title #, no-c-format msgid "Enable pcs Daemon" msgstr "" #. Tag: para #, no-c-format msgid "Before the cluster can be configured, the pcs daemon must be started and enabled to boot on startup on each node. This daemon works with the pcs cli command to manage syncing the corosync configuration across all the nodes in the cluster." msgstr "" #. Tag: para #, no-c-format msgid "Start and enable the daemon by issuing the following commands on each node." msgstr "" #. Tag: programlisting #, no-c-format msgid "" "# systemctl start pcsd.service\n" "# systemctl enable pcsd.service" msgstr "" #. Tag: para #, no-c-format msgid "Now we need a way for pcs to talk to itself on other nodes in the cluster. This is necessary in order to perform tasks such as syncing the corosync config, or starting/stopping the cluster on remote nodes" msgstr "" #. Tag: para #, no-c-format msgid "While pcs can be used locally without setting up these user accounts, this tutorial will make use of these remote access commands, so we will set a password for the hacluster user. Its probably best if password is consistent across all the nodes." msgstr "" #. Tag: para #, no-c-format msgid "As root, run:" msgstr "" #. Tag: programlisting #, no-c-format msgid "" "# passwd hacluster\n" "password:" msgstr "" #. Tag: para #, no-c-format msgid "Alternatively, to script this process or set the password on a different machine to the one you’re logged into, you can use the --stdin option for passwd:" msgstr "" #. Tag: programlisting #, no-c-format msgid "# ssh pcmk-2 -- 'echo redhat1 | passwd --stdin hacluster'" msgstr "" #. Tag: title #, no-c-format msgid "Notes on Multicast Address Assignment" msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "There are several subtle points that often deserve consideration when choosing/assigning multicast addresses. This information is borrowed from, the now defunct, http://web.archive.org/web/20101211210054/http://29west.com/docs/THPM/multicast-address-assignment.html" msgstr "Asigurați-vă că valorile pe care le alegeți nu dau conflicte cu alte clustere existente pe care le-ați putea avea. Pentru sfaturi în privința alegerii unei adrese multicast, vedeți http://www.29west.com/docs/THPM/multicast-address-assignment.html " #. Tag: para #, no-c-format msgid "Avoid 224.0.0.x" msgstr "" #. Tag: para #, no-c-format msgid "Traffic to addresses of the form 224.0.0.x is often flooded to all switch ports. This address range is reserved for link-local uses. Many routing protocols assume that all traffic within this range will be received by all routers on the network. Hence (at least all Cisco) switches flood traffic within this range. The flooding behavior overrides the normal selective forwarding behavior of a multicast-aware switch (e.g. IGMP snooping, CGMP, etc.)." msgstr "" #. Tag: para #, no-c-format msgid "Watch for 32:1 overlap" msgstr "" #. Tag: para #, no-c-format msgid "32 non-contiguous IP multicast addresses are mapped onto each Ethernet multicast address. A receiver that joins a single IP multicast group implicitly joins 31 others due to this overlap. Of course, filtering in the operating system discards undesired multicast traffic from applications, but NIC bandwidth and CPU resources are nonetheless consumed discarding it. The overlap occurs in the 5 high-order bits, so it’s best to use the 23 low-order bits to make distinct multicast streams unique. For example, IP multicast addresses in the range 239.0.0.0 to 239.127.255.255 all map to unique Ethernet multicast addresses. However, IP multicast address 239.128.0.0 maps to the same Ethernet multicast address as 239.0.0.0, 239.128.0.1 maps to the same Ethernet multicast address as 239.0.0.1, etc." msgstr "" #. Tag: para #, no-c-format msgid "Avoid x.0.0.y and x.128.0.y" msgstr "" #. Tag: para #, no-c-format msgid "Combining the above two considerations, it’s best to avoid using IP multicast addresses of the form x.0.0.y and x.128.0.y since they all map onto the range of Ethernet multicast addresses that are flooded to all switch ports." msgstr "" #. Tag: para #, no-c-format msgid "Watch for address assignment conflicts" msgstr "" #. Tag: para #, no-c-format msgid "IANA administers Internet multicast addresses. Potential conflicts with Internet multicast address assignments can be avoided by using GLOP addressing (AS required) or administratively scoped addresses. Such addresses can be safely used on a network connected to the Internet without fear of conflict with multicast sources originating on the Internet. Administratively scoped addresses are roughly analogous to the unicast address space for private internets. Site-local multicast addresses are of the form 239.255.x.y, but can grow down to 239.252.x.y if needed. Organization-local multicast addresses are of the form 239.192-251.x.y, but can grow down to 239.x.y.z if needed." msgstr "" #. Tag: para #, no-c-format msgid "For a more detailed treatment (57 pages!), see Cisco’s Guidelines for Enterprise IP Multicast Address Allocation paper." msgstr "" #. Tag: title #, no-c-format msgid "Configuring Corosync" msgstr "Configurarea Corosync" #. Tag: para #, no-c-format msgid "In the past, at this point in the tutorial an explanation of how to configure and propagate corosync’s /etc/corosync.conf file would be necessary. Using pcs with the pcs daemon greatly simplifies this process by generating corosync.conf across all the nodes in the cluster with a single command. The only thing required to achieve this is to authenticate as the pcs user hacluster on one of the nodes in the cluster, and then issue the pcs cluster setup command with a list of all the node names in the cluster." msgstr "" #. Tag: programlisting #, no-c-format msgid "" "# pcs cluster auth pcmk-1 pcmk-2\n" "Username: hacluster\n" "Password:\n" "pcmk-1: Authorized\n" "pcmk-2: Authorized\n" "\n" "# pcs cluster setup mycluster pcmk-1 pcmk-2\n" "pcmk-1: Succeeded\n" "pcmk-2: Succeeded" msgstr "" #. Tag: para #, no-c-format msgid "That’s it. Corosync is configured across the cluster. If you received an authorization error for either of those commands, make sure you setup the hacluster user account and password on every node in the cluster with the same password." msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "The final /etc/corosync.conf configuration on each node should look something like the sample in Appendix B, Sample Corosync Configuration." msgstr "Configurația finală ar trebui să arate ceva similar cu exemplul din ." #. Tag: para #, no-c-format msgid "Pacemaker used to obtain membership and quorum from a custom Corosync plugin. This plugin also had the capability to start Pacemaker automatically when Corosync was started." msgstr "" #. Tag: para #, no-c-format msgid "Neither behavior is possible with Corosync 2.0 and beyond as support for plugins was removed." msgstr "" #. Tag: para #, no-c-format msgid "Instead, Pacemaker must be started as a separate job/initscript. Also, since Pacemaker made use of the plugin for message routing, a node using the plugin (Corosync prior to 2.0) cannot talk to one that isn’t (Corosync 2.0+)." msgstr "" #. Tag: para #, no-c-format msgid "Rolling upgrades between these versions are therefor not possible and an alternate strategy http://www.clusterlabs.org/doc/en-US/Pacemaker/1.1/html/Pacemaker_Explained/ap-upgrade.html must be used." msgstr "" #~ msgid "Burn the disk image to a DVD http://docs.fedoraproject.org/readme-burning-isos/en-US.html and boot from it. Or use the image to boot a virtual machine as I have done here. After clicking through the welcome screen, select your language and keyboard layout http://docs.fedoraproject.org/install-guide/f&DISTRO_VERSION;/en-US/html/s1-langselection-x86.html " #~ msgstr "Scrieți imaginea pe un DVD http://docs.fedoraproject.org/readme-burning-isos/en-US.html și bootați de pe acesta. Sau folosiți imaginea pentru a boota o mașină virtuală așa cum am făcut aici. După ce ați selectat prin ecranul de început, selectați limba voastră și așezarea tastaturii http://docs.fedoraproject.org/install-guide/f&DISTRO_VERSION;/en-US/html/s1-langselection-x86.html " #~ msgid "Fedora Installation - Welcome" #~ msgstr "Instalarea Fedora - Bine ați venit" #~ msgid "Fedora Installation: Good choice" #~ msgstr "Instalarea Fedora: O alegere bună" #~ msgid "Fedora Installation - Storage Devices" #~ msgstr "Instalarea Fedora - Dispozitive de Stocare" #~ msgid "Fedora Installation: Storage Devices" #~ msgstr "Instalarea Fedora: Dispozitive de Stocare" #~ msgid "Fedora Installation - Hostname" #~ msgstr "Instalarea Fedora - Nume de gazdă" #~ msgid "Fedora Installation: Choose a hostname" #~ msgstr "Instalarea Fedora: Alegeți un nume pentru gazdă" #~ msgid "Fedora Installation - Installation Type" #~ msgstr "Instalarea Fedora - Tipul de Instalare" #~ msgid "Fedora Installation: Choose an installation type" #~ msgstr "Instalarea Fedora: Alegeți tipul de instalare" #~ msgid "By default, Fedora will give all the space to the / (aka. root) partition. Wel'll take some back so we can use DRBD." #~ msgstr "În mod implicit, Fedora va da tot spațiul către partiția / (root). Vom lua ceva din acesta înapoi pentru a putea folosi DRBD. " #~ msgid "Fedora Installation - Default Partitioning" #~ msgstr "Instalarea Fedora - Partiționarea Implicită" #~ msgid "The finalized partition layout should look something like the diagram below." #~ msgstr "Așezarea finalizată a partițiilor ar trebui să arate asemănător cu diagrama de mai jos. " #~ msgid "If you plan on following the DRBD or GFS2 portions of this guide, you should reserve at least 1Gb of space on each machine from which to create a shared volume." #~ msgstr "Dacă plănuiți să urmați porțiunile referitoare la DRBD sau GFS2 ale acestui ghid, ar trebui să rezervați cel puțin 1Gb de spațiu pe fieare mașină din care să creați un volum partajat." #~ msgid "Fedora Installation - Customize Partitioning" #~ msgstr "Instalarea Fedora - Customizarea Partiționării" #~ msgid "Fedora Installation: Create a partition to use (later) for website data" #~ msgstr "Instalarea Fedora: Creați o partiție pentru a o folosi (mai târziu) pentru datele website-ului" #~ msgid "Fedora Installation - Bootloader" #~ msgstr "Instalarea Fedora - Bootloader" #~ msgid "Fedora Installation: Unless you have a strong reason not to, accept the default bootloader location" #~ msgstr "Instalarea Fedora: Decât dacă aveți un motiv puternic împotriva acestui lucru, acceptați locația implicită pentru bootloader" #~ msgid "Fedora Installation - Software" #~ msgstr "Instalarea Fedora - Software" #~ msgid "Fedora Installation: Software selection" #~ msgstr "Instalarea Fedora: Selecția software-ului" #~ msgid "Fedora Installation - Installing" #~ msgstr "Instalarea Fedora - Instalează" #~ msgid "Fedora Installation - Installation Complete" #~ msgstr "Instalarea Fedora - Instalarea a Terminat" #~ msgid "Fedora Installation: Stage 1, completed" #~ msgstr "Instalarea Fedora: Stadiul 1, terminat" #~ msgid "Once the node reboots, follow the on screen instructions http://docs.fedoraproject.org/install-guide/f&DISTRO_VERSION;/en-US/html/ch-firstboot.html to create a system user and configure the time." #~ msgstr "Odată ce nodul repornește, urmați instrucțiunile de pe ecran http://docs.fedoraproject.org/install-guide/f&DISTRO_VERSION;/en-US/html/ch-firstboot.html pentru a crea un utilizator de system și pentru a configura ora." #~ msgid "Fedora Installation - First Boot" #~ msgstr "Instalarea Fedora - Primul Boot" #~ msgid "Fedora Installation - Create Non-privileged User" #~ msgstr "Instalarea Fedora - Creați un Utilizator Neprivilegiat" #~ msgid "Fedora Installation: Creating a non-privileged user, take note of the password, you'll need it soon" #~ msgstr "Instalarea Fedora: Creând un utilizator neprivilegiat, rețineți parola, o să aveți nevoie de ea în curând" #~ msgid "It is highly recommended to enable NTP on your cluster nodes. Doing so ensures all nodes agree on the current time and makes reading log files significantly easier." #~ msgstr "Este foarte recomandat să activați NTP-ul pe nodurile din cluster. Realizând acest lucru asigură câ toate nodurile sunt de acord asupra datei curente și acest lucru face citirea fișierelor de log semnificativ mai ușoară." #~ msgid "Fedora Installation - Date and Time" #~ msgstr "Instalarea Fedora - Data și Ora" #~ msgid "Fedora Installation: Enable NTP to keep the times on all your nodes consistent" #~ msgstr "Instalarea Fedora: Activați NTP pentru a menține data consistentă pe noate nodurile" #~ msgid "Click through the next screens until you reach the login window. Click on the user you created and supply the password you indicated earlier." #~ msgstr "Selectați cu mouse-ul prin următorul ecran până ajungeți la fereastra de login. Selectați utilizatorul pe care l-ați creat și furnizați parola pe care ați ales-o mai devreme." #~ msgid "Fedora Installation - Customize Networking" #~ msgstr "Instalarea Fedora - Personalizați Rețeaua" #~ msgid "Fedora Installation: Click here to configure networking" #~ msgstr "Instalarea Fedora: Selectați aici pentru a configura rețeaua" #~ msgid "Fedora Installation - Specify Network Preferences" #~ msgstr "Instalarea Fedora - Specificați Preferințele de Rețea" #~ msgid "Fedora Installation: Specify network settings for your machine, never choose DHCP" #~ msgstr "Instalarea Fedora: Specificați setările de rețea pentru mașina voastră, să nu alegeți niciodată DHCP" #~ msgid "Fedora Installation - Activate Networking" #~ msgstr "Instalarea Fedora - Activați Rețeaua" #~ msgid "Fedora Installation: Click the big green button to activate your changes" #~ msgstr "Instalarea Fedora: Selectați butonul mare verde pentru a activa modificările voastre" #~ msgid "Fedora Installation - Bring up the Terminal" #~ msgstr "Instalarea Fedora - Porniți Terminalul" #~ msgid "Fedora Installation: Down to business, fire up the command line" #~ msgstr "Instalarea Fedora: Să trecem la afaceri, porniți linia de comandă" #~ msgid "Go to the terminal window you just opened and switch to the super user (aka. \"root\") account with the su command. You will need to supply the password you entered earlier during the installation process." #~ msgstr "Mergeți la fereastra de terminal pe care tocmai ați deschis-o și schimbați la contul de super utilizator (adică la \"root\") cu comanda su. Va trebui să furnizați parola pe care ați introdus-o mai devreme în timpul procesului de instalare." #~ msgid "" #~ "\n" #~ "[beekhof@pcmk-1 ~]$ su -\n" #~ "Password:\n" #~ "[root@pcmk-1 ~]#\n" #~ " " #~ msgstr "" #~ "\n" #~ "[beekhof@pcmk-1 ~]$ su -\n" #~ "Password:\n" #~ "[root@pcmk-1 ~]#\n" #~ " " #~ msgid "Note that the username (the text before the @ symbol) now indicates we’re running as the super user “root”." #~ msgstr "Luați aminte că numele de utilizator (textul dinaintea simbolului @) acum indică faptul că rulăm ca super utilizatorul \"root\"." #~ msgid "" #~ "\n" #~ "[root@pcmk-1 ~]# ip addr\n" #~ "1: lo: <LOOPBACK,UP,LOWER_UP> mtu 16436 qdisc noqueue state UNKNOWN \n" #~ " link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00\n" #~ " inet 127.0.0.1/8 scope host lo\n" #~ " inet6 ::1/128 scope host \n" #~ " valid_lft forever preferred_lft forever\n" #~ "2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UNKNOWN qlen 1000\n" #~ " link/ether 00:0c:29:6f:e1:58 brd ff:ff:ff:ff:ff:ff\n" #~ " inet 192.168.9.41/24 brd 192.168.9.255 scope global eth0\n" #~ " inet6 ::20c:29ff:fe6f:e158/64 scope global dynamic \n" #~ " valid_lft 2591667sec preferred_lft 604467sec\n" #~ " inet6 2002:57ae:43fc:0:20c:29ff:fe6f:e158/64 scope global dynamic \n" #~ " valid_lft 2591990sec preferred_lft 604790sec\n" #~ " inet6 fe80::20c:29ff:fe6f:e158/64 scope link \n" #~ " valid_lft forever preferred_lft forever\n" #~ "[root@pcmk-1 ~]# ping -c 1 www.google.com\n" #~ "PING www.l.google.com (74.125.39.99) 56(84) bytes of data.\n" #~ "64 bytes from fx-in-f99.1e100.net (74.125.39.99): icmp_seq=1 ttl=56 time=16.7 ms\n" #~ "\n" #~ "--- www.l.google.com ping statistics ---\n" #~ "1 packets transmitted, 1 received, 0% packet loss, time 20ms\n" #~ "rtt min/avg/max/mdev = 16.713/16.713/16.713/0.000 ms\n" #~ "[root@pcmk-1 ~]# /sbin/chkconfig network on\n" #~ "[root@pcmk-1 ~]# \n" #~ " " #~ msgstr "" #~ "\n" #~ "[root@pcmk-1 ~]# ip addr\n" #~ "1: lo: <LOOPBACK,UP,LOWER_UP> mtu 16436 qdisc noqueue state UNKNOWN \n" #~ " link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00\n" #~ " inet 127.0.0.1/8 scope host lo\n" #~ " inet6 ::1/128 scope host \n" #~ " valid_lft forever preferred_lft forever\n" #~ "2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UNKNOWN qlen 1000\n" #~ " link/ether 00:0c:29:6f:e1:58 brd ff:ff:ff:ff:ff:ff\n" #~ " inet 192.168.9.41/24 brd 192.168.9.255 scope global eth0\n" #~ " inet6 ::20c:29ff:fe6f:e158/64 scope global dynamic \n" #~ " valid_lft 2591667sec preferred_lft 604467sec\n" #~ " inet6 2002:57ae:43fc:0:20c:29ff:fe6f:e158/64 scope global dynamic \n" #~ " valid_lft 2591990sec preferred_lft 604790sec\n" #~ " inet6 fe80::20c:29ff:fe6f:e158/64 scope link \n" #~ " valid_lft forever preferred_lft forever\n" #~ "[root@pcmk-1 ~]# ping -c 1 www.google.com\n" #~ "PING www.l.google.com (74.125.39.99) 56(84) bytes of data.\n" #~ "64 bytes from fx-in-f99.1e100.net (74.125.39.99): icmp_seq=1 ttl=56 time=16.7 ms\n" #~ "\n" #~ "--- www.l.google.com ping statistics ---\n" #~ "1 packets transmitted, 1 received, 0% packet loss, time 20ms\n" #~ "rtt min/avg/max/mdev = 16.713/16.713/16.713/0.000 ms\n" #~ "[root@pcmk-1 ~]# /sbin/chkconfig network on\n" #~ "[root@pcmk-1 ~]# \n" #~ " " #~ msgid "" #~ "\n" #~ "[root@pcmk-1 ~]# sed -i.bak \"s/SELINUX=enforcing/SELINUX=permissive/g\" /etc/selinux/config\n" #~ "[root@pcmk-1 ~]# /sbin/chkconfig --del iptables\n" #~ "[root@pcmk-1 ~]# service iptables stop\n" #~ "iptables: Flushing firewall rules: [ OK ]\n" #~ "iptables: Setting chains to policy ACCEPT: filter [ OK ]\n" #~ "iptables: Unloading modules: [ OK ]\n" #~ " " #~ msgstr "" #~ "\n" #~ "[root@pcmk-1 ~]# sed -i.bak \"s/SELINUX=enforcing/SELINUX=permissive/g\" /etc/selinux/config\n" #~ "[root@pcmk-1 ~]# /sbin/chkconfig --del iptables\n" #~ "[root@pcmk-1 ~]# service iptables stop\n" #~ "iptables: Flushing firewall rules: [ OK ]\n" #~ "iptables: Setting chains to policy ACCEPT: filter [ OK ]\n" #~ "iptables: Unloading modules: [ OK ]\n" #~ " " #~ msgid "You will need to reboot for the SELinux changes to take effect. Otherwise you will see something like this when you start corosync:" #~ msgstr "Va trebui să reporniți pentru ca modificările de SELinux să ia effect. Altfel ați vedea ceva similar cu acesta când veți porni corosync:" #~ msgid "" #~ "\n" #~ "May 4 19:30:54 pcmk-1 setroubleshoot: SELinux is preventing /usr/sbin/corosync \"getattr\" access on /. For complete SELinux messages. run sealert -l 6e0d4384-638e-4d55-9aaf-7dac011f29c1\n" #~ "May 4 19:30:54 pcmk-1 setroubleshoot: SELinux is preventing /usr/sbin/corosync \"getattr\" access on /. For complete SELinux messages. run sealert -l 6e0d4384-638e-4d55-9aaf-7dac011f29c1\n" #~ "\t" #~ msgstr "" #~ "\n" #~ "May 4 19:30:54 pcmk-1 setroubleshoot: SELinux is preventing /usr/sbin/corosync \"getattr\" access on /. For complete SELinux messages. run sealert -l 6e0d4384-638e-4d55-9aaf-7dac011f29c1\n" #~ "May 4 19:30:54 pcmk-1 setroubleshoot: SELinux is preventing /usr/sbin/corosync \"getattr\" access on /. For complete SELinux messages. run sealert -l 6e0d4384-638e-4d55-9aaf-7dac011f29c1\n" #~ "\t" #~ msgid "" #~ "\n" #~ "[root@pcmk-1 ~]# sed -i.bak \"s/enabled=0/enabled=1/g\" /etc/yum.repos.d/fedora.repo\n" #~ "[root@pcmk-1 ~]# sed -i.bak \"s/enabled=0/enabled=1/g\" /etc/yum.repos.d/fedora-updates.repo\n" #~ "[root@pcmk-1 ~]# yum install -y pacemaker corosync\n" #~ "Loaded plugins: presto, refresh-packagekit\n" #~ "fedora/metalink \t | 22 kB 00:00 \n" #~ "fedora-debuginfo/metalink \t | 16 kB 00:00 \n" #~ "fedora-debuginfo \t | 3.2 kB 00:00 \n" #~ "fedora-debuginfo/primary_db \t | 1.4 MB 00:04 \n" #~ "fedora-source/metalink \t | 22 kB 00:00 \n" #~ "fedora-source \t | 3.2 kB 00:00 \n" #~ "fedora-source/primary_db \t | 3.0 MB 00:05 \n" #~ "updates/metalink \t | 26 kB 00:00 \n" #~ "updates \t | 2.6 kB 00:00 \n" #~ "updates/primary_db \t | 1.1 kB 00:00 \n" #~ "updates-debuginfo/metalink \t | 18 kB 00:00 \n" #~ "updates-debuginfo \t | 2.6 kB 00:00 \n" #~ "updates-debuginfo/primary_db \t | 1.1 kB 00:00 \n" #~ "updates-source/metalink \t | 25 kB 00:00 \n" #~ "updates-source \t | 2.6 kB 00:00 \n" #~ "updates-source/primary_db \t | 1.1 kB 00:00 \n" #~ "Setting up Install Process\n" #~ "Resolving Dependencies\n" #~ "--> Running transaction check\n" #~ "---> Package corosync.x86_64 0:1.2.1-1.fc13 set to be updated\n" #~ "--> Processing Dependency: corosynclib = 1.2.1-1.fc13 for package: corosync-1.2.1-1.fc13.x86_64\n" #~ "--> Processing Dependency: libquorum.so.4(COROSYNC_QUORUM_1.0)(64bit) for package: corosync-1.2.1-1.fc13.x86_64\n" #~ "--> Processing Dependency: libvotequorum.so.4(COROSYNC_VOTEQUORUM_1.0)(64bit) for package: corosync-1.2.1-1.fc13.x86_64\n" #~ "--> Processing Dependency: libcpg.so.4(COROSYNC_CPG_1.0)(64bit) for package: corosync-1.2.1-1.fc13.x86_64\n" #~ "--> Processing Dependency: libconfdb.so.4(COROSYNC_CONFDB_1.0)(64bit) for package: corosync-1.2.1-1.fc13.x86_64\n" #~ "--> Processing Dependency: libcfg.so.4(COROSYNC_CFG_0.82)(64bit) for package: corosync-1.2.1-1.fc13.x86_64\n" #~ "--> Processing Dependency: libpload.so.4(COROSYNC_PLOAD_1.0)(64bit) for package: corosync-1.2.1-1.fc13.x86_64\n" #~ "--> Processing Dependency: liblogsys.so.4()(64bit) for package: corosync-1.2.1-1.fc13.x86_64\n" #~ "--> Processing Dependency: libconfdb.so.4()(64bit) for package: corosync-1.2.1-1.fc13.x86_64\n" #~ "--> Processing Dependency: libcoroipcc.so.4()(64bit) for package: corosync-1.2.1-1.fc13.x86_64\n" #~ "--> Processing Dependency: libcpg.so.4()(64bit) for package: corosync-1.2.1-1.fc13.x86_64\n" #~ "--> Processing Dependency: libquorum.so.4()(64bit) for package: corosync-1.2.1-1.fc13.x86_64\n" #~ "--> Processing Dependency: libcoroipcs.so.4()(64bit) for package: corosync-1.2.1-1.fc13.x86_64\n" #~ "--> Processing Dependency: libvotequorum.so.4()(64bit) for package: corosync-1.2.1-1.fc13.x86_64\n" #~ "--> Processing Dependency: libcfg.so.4()(64bit) for package: corosync-1.2.1-1.fc13.x86_64\n" #~ "--> Processing Dependency: libtotem_pg.so.4()(64bit) for package: corosync-1.2.1-1.fc13.x86_64\n" #~ "--> Processing Dependency: libpload.so.4()(64bit) for package: corosync-1.2.1-1.fc13.x86_64\n" #~ "---> Package pacemaker.x86_64 0:1.1.5-1.fc13 set to be updated\n" #~ "--> Processing Dependency: heartbeat >= 3.0.0 for package: pacemaker-1.1.5-1.fc13.x86_64\n" #~ "--> Processing Dependency: net-snmp >= 5.4 for package: pacemaker-1.1.5-1.fc13.x86_64\n" #~ "--> Processing Dependency: resource-agents for package: pacemaker-1.1.5-1.fc13.x86_64\n" #~ "--> Processing Dependency: cluster-glue for package: pacemaker-1.1.5-1.fc13.x86_64\n" #~ "--> Processing Dependency: libnetsnmp.so.20()(64bit) for package: pacemaker-1.1.5-1.fc13.x86_64\n" #~ "--> Processing Dependency: libcrmcluster.so.1()(64bit) for package: pacemaker-1.1.5-1.fc13.x86_64\n" #~ "--> Processing Dependency: libpengine.so.3()(64bit) for package: pacemaker-1.1.5-1.fc13.x86_64\n" #~ "--> Processing Dependency: libnetsnmpagent.so.20()(64bit) for package: pacemaker-1.1.5-1.fc13.x86_64\n" #~ "--> Processing Dependency: libesmtp.so.5()(64bit) for package: pacemaker-1.1.5-1.fc13.x86_64\n" #~ "--> Processing Dependency: libstonithd.so.1()(64bit) for package: pacemaker-1.1.5-1.fc13.x86_64\n" #~ "--> Processing Dependency: libhbclient.so.1()(64bit) for package: pacemaker-1.1.5-1.fc13.x86_64\n" #~ "--> Processing Dependency: libpils.so.2()(64bit) for package: pacemaker-1.1.5-1.fc13.x86_64\n" #~ "--> Processing Dependency: libpe_status.so.2()(64bit) for package: pacemaker-1.1.5-1.fc13.x86_64\n" #~ "--> Processing Dependency: libnetsnmpmibs.so.20()(64bit) for package: pacemaker-1.1.5-1.fc13.x86_64\n" #~ "--> Processing Dependency: libnetsnmphelpers.so.20()(64bit) for package: pacemaker-1.1.5-1.fc13.x86_64\n" #~ "--> Processing Dependency: libcib.so.1()(64bit) for package: pacemaker-1.1.5-1.fc13.x86_64\n" #~ "--> Processing Dependency: libccmclient.so.1()(64bit) for package: pacemaker-1.1.5-1.fc13.x86_64\n" #~ "--> Processing Dependency: libstonith.so.1()(64bit) for package: pacemaker-1.1.5-1.fc13.x86_64\n" #~ "--> Processing Dependency: liblrm.so.2()(64bit) for package: pacemaker-1.1.5-1.fc13.x86_64\n" #~ "--> Processing Dependency: libtransitioner.so.1()(64bit) for package: pacemaker-1.1.5-1.fc13.x86_64\n" #~ "--> Processing Dependency: libpe_rules.so.2()(64bit) for package: pacemaker-1.1.5-1.fc13.x86_64\n" #~ "--> Processing Dependency: libcrmcommon.so.2()(64bit) for package: pacemaker-1.1.5-1.fc13.x86_64\n" #~ "--> Processing Dependency: libplumb.so.2()(64bit) for package: pacemaker-1.1.5-1.fc13.x86_64\n" #~ "--> Running transaction check\n" #~ "---> Package cluster-glue.x86_64 0:1.0.2-1.fc13 set to be updated\n" #~ "--> Processing Dependency: perl-TimeDate for package: cluster-glue-1.0.2-1.fc13.x86_64\n" #~ "--> Processing Dependency: libOpenIPMIutils.so.0()(64bit) for package: cluster-glue-1.0.2-1.fc13.x86_64\n" #~ "--> Processing Dependency: libOpenIPMIposix.so.0()(64bit) for package: cluster-glue-1.0.2-1.fc13.x86_64\n" #~ "--> Processing Dependency: libopenhpi.so.2()(64bit) for package: cluster-glue-1.0.2-1.fc13.x86_64\n" #~ "--> Processing Dependency: libOpenIPMI.so.0()(64bit) for package: cluster-glue-1.0.2-1.fc13.x86_64\n" #~ "---> Package cluster-glue-libs.x86_64 0:1.0.2-1.fc13 set to be updated\n" #~ "---> Package corosynclib.x86_64 0:1.2.1-1.fc13 set to be updated\n" #~ "--> Processing Dependency: librdmacm.so.1(RDMACM_1.0)(64bit) for package: corosynclib-1.2.1-1.fc13.x86_64\n" #~ "--> Processing Dependency: libibverbs.so.1(IBVERBS_1.0)(64bit) for package: corosynclib-1.2.1-1.fc13.x86_64\n" #~ "--> Processing Dependency: libibverbs.so.1(IBVERBS_1.1)(64bit) for package: corosynclib-1.2.1-1.fc13.x86_64\n" #~ "--> Processing Dependency: libibverbs.so.1()(64bit) for package: corosynclib-1.2.1-1.fc13.x86_64\n" #~ "--> Processing Dependency: librdmacm.so.1()(64bit) for package: corosynclib-1.2.1-1.fc13.x86_64\n" #~ "---> Package heartbeat.x86_64 0:3.0.0-0.7.0daab7da36a8.hg.fc13 set to be updated\n" #~ "--> Processing Dependency: PyXML for package: heartbeat-3.0.0-0.7.0daab7da36a8.hg.fc13.x86_64\n" #~ "---> Package heartbeat-libs.x86_64 0:3.0.0-0.7.0daab7da36a8.hg.fc13 set to be updated\n" #~ "---> Package libesmtp.x86_64 0:1.0.4-12.fc12 set to be updated\n" #~ "---> Package net-snmp.x86_64 1:5.5-12.fc13 set to be updated\n" #~ "--> Processing Dependency: libsensors.so.4()(64bit) for package: 1:net-snmp-5.5-12.fc13.x86_64\n" #~ "---> Package net-snmp-libs.x86_64 1:5.5-12.fc13 set to be updated\n" #~ "---> Package pacemaker-libs.x86_64 0:1.1.5-1.fc13 set to be updated\n" #~ "---> Package resource-agents.x86_64 0:3.0.10-1.fc13 set to be updated\n" #~ "--> Processing Dependency: libnet.so.1()(64bit) for package: resource-agents-3.0.10-1.fc13.x86_64\n" #~ "--> Running transaction check\n" #~ "---> Package OpenIPMI-libs.x86_64 0:2.0.16-8.fc13 set to be updated\n" #~ "---> Package PyXML.x86_64 0:0.8.4-17.fc13 set to be updated\n" #~ "---> Package libibverbs.x86_64 0:1.1.3-4.fc13 set to be updated\n" #~ "--> Processing Dependency: libibverbs-driver for package: libibverbs-1.1.3-4.fc13.x86_64\n" #~ "---> Package libnet.x86_64 0:1.1.4-3.fc12 set to be updated\n" #~ "---> Package librdmacm.x86_64 0:1.0.10-2.fc13 set to be updated\n" #~ "---> Package lm_sensors-libs.x86_64 0:3.1.2-2.fc13 set to be updated\n" #~ "---> Package openhpi-libs.x86_64 0:2.14.1-3.fc13 set to be updated\n" #~ "---> Package perl-TimeDate.noarch 1:1.20-1.fc13 set to be updated\n" #~ "--> Running transaction check\n" #~ "---> Package libmlx4.x86_64 0:1.0.1-5.fc13 set to be updated\n" #~ "--> Finished Dependency Resolution\n" #~ "\n" #~ "Dependencies Resolved\n" #~ "\n" #~ " " #~ msgstr "" #~ "\n" #~ "[root@pcmk-1 ~]# sed -i.bak \"s/enabled=0/enabled=1/g\" /etc/yum.repos.d/fedora.repo\n" #~ "[root@pcmk-1 ~]# sed -i.bak \"s/enabled=0/enabled=1/g\" /etc/yum.repos.d/fedora-updates.repo\n" #~ "[root@pcmk-1 ~]# yum install -y pacemaker corosync\n" #~ "Loaded plugins: presto, refresh-packagekit\n" #~ "fedora/metalink \t | 22 kB 00:00 \n" #~ "fedora-debuginfo/metalink \t | 16 kB 00:00 \n" #~ "fedora-debuginfo \t | 3.2 kB 00:00 \n" #~ "fedora-debuginfo/primary_db \t | 1.4 MB 00:04 \n" #~ "fedora-source/metalink \t | 22 kB 00:00 \n" #~ "fedora-source \t | 3.2 kB 00:00 \n" #~ "fedora-source/primary_db \t | 3.0 MB 00:05 \n" #~ "updates/metalink \t | 26 kB 00:00 \n" #~ "updates \t | 2.6 kB 00:00 \n" #~ "updates/primary_db \t | 1.1 kB 00:00 \n" #~ "updates-debuginfo/metalink \t | 18 kB 00:00 \n" #~ "updates-debuginfo \t | 2.6 kB 00:00 \n" #~ "updates-debuginfo/primary_db \t | 1.1 kB 00:00 \n" #~ "updates-source/metalink \t | 25 kB 00:00 \n" #~ "updates-source \t | 2.6 kB 00:00 \n" #~ "updates-source/primary_db \t | 1.1 kB 00:00 \n" #~ "Setting up Install Process\n" #~ "Resolving Dependencies\n" #~ "--> Running transaction check\n" #~ "---> Package corosync.x86_64 0:1.2.1-1.fc13 set to be updated\n" #~ "--> Processing Dependency: corosynclib = 1.2.1-1.fc13 for package: corosync-1.2.1-1.fc13.x86_64\n" #~ "--> Processing Dependency: libquorum.so.4(COROSYNC_QUORUM_1.0)(64bit) for package: corosync-1.2.1-1.fc13.x86_64\n" #~ "--> Processing Dependency: libvotequorum.so.4(COROSYNC_VOTEQUORUM_1.0)(64bit) for package: corosync-1.2.1-1.fc13.x86_64\n" #~ "--> Processing Dependency: libcpg.so.4(COROSYNC_CPG_1.0)(64bit) for package: corosync-1.2.1-1.fc13.x86_64\n" #~ "--> Processing Dependency: libconfdb.so.4(COROSYNC_CONFDB_1.0)(64bit) for package: corosync-1.2.1-1.fc13.x86_64\n" #~ "--> Processing Dependency: libcfg.so.4(COROSYNC_CFG_0.82)(64bit) for package: corosync-1.2.1-1.fc13.x86_64\n" #~ "--> Processing Dependency: libpload.so.4(COROSYNC_PLOAD_1.0)(64bit) for package: corosync-1.2.1-1.fc13.x86_64\n" #~ "--> Processing Dependency: liblogsys.so.4()(64bit) for package: corosync-1.2.1-1.fc13.x86_64\n" #~ "--> Processing Dependency: libconfdb.so.4()(64bit) for package: corosync-1.2.1-1.fc13.x86_64\n" #~ "--> Processing Dependency: libcoroipcc.so.4()(64bit) for package: corosync-1.2.1-1.fc13.x86_64\n" #~ "--> Processing Dependency: libcpg.so.4()(64bit) for package: corosync-1.2.1-1.fc13.x86_64\n" #~ "--> Processing Dependency: libquorum.so.4()(64bit) for package: corosync-1.2.1-1.fc13.x86_64\n" #~ "--> Processing Dependency: libcoroipcs.so.4()(64bit) for package: corosync-1.2.1-1.fc13.x86_64\n" #~ "--> Processing Dependency: libvotequorum.so.4()(64bit) for package: corosync-1.2.1-1.fc13.x86_64\n" #~ "--> Processing Dependency: libcfg.so.4()(64bit) for package: corosync-1.2.1-1.fc13.x86_64\n" #~ "--> Processing Dependency: libtotem_pg.so.4()(64bit) for package: corosync-1.2.1-1.fc13.x86_64\n" #~ "--> Processing Dependency: libpload.so.4()(64bit) for package: corosync-1.2.1-1.fc13.x86_64\n" #~ "---> Package pacemaker.x86_64 0:1.1.5-1.fc13 set to be updated\n" #~ "--> Processing Dependency: heartbeat >= 3.0.0 for package: pacemaker-1.1.5-1.fc13.x86_64\n" #~ "--> Processing Dependency: net-snmp >= 5.4 for package: pacemaker-1.1.5-1.fc13.x86_64\n" #~ "--> Processing Dependency: resource-agents for package: pacemaker-1.1.5-1.fc13.x86_64\n" #~ "--> Processing Dependency: cluster-glue for package: pacemaker-1.1.5-1.fc13.x86_64\n" #~ "--> Processing Dependency: libnetsnmp.so.20()(64bit) for package: pacemaker-1.1.5-1.fc13.x86_64\n" #~ "--> Processing Dependency: libcrmcluster.so.1()(64bit) for package: pacemaker-1.1.5-1.fc13.x86_64\n" #~ "--> Processing Dependency: libpengine.so.3()(64bit) for package: pacemaker-1.1.5-1.fc13.x86_64\n" #~ "--> Processing Dependency: libnetsnmpagent.so.20()(64bit) for package: pacemaker-1.1.5-1.fc13.x86_64\n" #~ "--> Processing Dependency: libesmtp.so.5()(64bit) for package: pacemaker-1.1.5-1.fc13.x86_64\n" #~ "--> Processing Dependency: libstonithd.so.1()(64bit) for package: pacemaker-1.1.5-1.fc13.x86_64\n" #~ "--> Processing Dependency: libhbclient.so.1()(64bit) for package: pacemaker-1.1.5-1.fc13.x86_64\n" #~ "--> Processing Dependency: libpils.so.2()(64bit) for package: pacemaker-1.1.5-1.fc13.x86_64\n" #~ "--> Processing Dependency: libpe_status.so.2()(64bit) for package: pacemaker-1.1.5-1.fc13.x86_64\n" #~ "--> Processing Dependency: libnetsnmpmibs.so.20()(64bit) for package: pacemaker-1.1.5-1.fc13.x86_64\n" #~ "--> Processing Dependency: libnetsnmphelpers.so.20()(64bit) for package: pacemaker-1.1.5-1.fc13.x86_64\n" #~ "--> Processing Dependency: libcib.so.1()(64bit) for package: pacemaker-1.1.5-1.fc13.x86_64\n" #~ "--> Processing Dependency: libccmclient.so.1()(64bit) for package: pacemaker-1.1.5-1.fc13.x86_64\n" #~ "--> Processing Dependency: libstonith.so.1()(64bit) for package: pacemaker-1.1.5-1.fc13.x86_64\n" #~ "--> Processing Dependency: liblrm.so.2()(64bit) for package: pacemaker-1.1.5-1.fc13.x86_64\n" #~ "--> Processing Dependency: libtransitioner.so.1()(64bit) for package: pacemaker-1.1.5-1.fc13.x86_64\n" #~ "--> Processing Dependency: libpe_rules.so.2()(64bit) for package: pacemaker-1.1.5-1.fc13.x86_64\n" #~ "--> Processing Dependency: libcrmcommon.so.2()(64bit) for package: pacemaker-1.1.5-1.fc13.x86_64\n" #~ "--> Processing Dependency: libplumb.so.2()(64bit) for package: pacemaker-1.1.5-1.fc13.x86_64\n" #~ "--> Running transaction check\n" #~ "---> Package cluster-glue.x86_64 0:1.0.2-1.fc13 set to be updated\n" #~ "--> Processing Dependency: perl-TimeDate for package: cluster-glue-1.0.2-1.fc13.x86_64\n" #~ "--> Processing Dependency: libOpenIPMIutils.so.0()(64bit) for package: cluster-glue-1.0.2-1.fc13.x86_64\n" #~ "--> Processing Dependency: libOpenIPMIposix.so.0()(64bit) for package: cluster-glue-1.0.2-1.fc13.x86_64\n" #~ "--> Processing Dependency: libopenhpi.so.2()(64bit) for package: cluster-glue-1.0.2-1.fc13.x86_64\n" #~ "--> Processing Dependency: libOpenIPMI.so.0()(64bit) for package: cluster-glue-1.0.2-1.fc13.x86_64\n" #~ "---> Package cluster-glue-libs.x86_64 0:1.0.2-1.fc13 set to be updated\n" #~ "---> Package corosynclib.x86_64 0:1.2.1-1.fc13 set to be updated\n" #~ "--> Processing Dependency: librdmacm.so.1(RDMACM_1.0)(64bit) for package: corosynclib-1.2.1-1.fc13.x86_64\n" #~ "--> Processing Dependency: libibverbs.so.1(IBVERBS_1.0)(64bit) for package: corosynclib-1.2.1-1.fc13.x86_64\n" #~ "--> Processing Dependency: libibverbs.so.1(IBVERBS_1.1)(64bit) for package: corosynclib-1.2.1-1.fc13.x86_64\n" #~ "--> Processing Dependency: libibverbs.so.1()(64bit) for package: corosynclib-1.2.1-1.fc13.x86_64\n" #~ "--> Processing Dependency: librdmacm.so.1()(64bit) for package: corosynclib-1.2.1-1.fc13.x86_64\n" #~ "---> Package heartbeat.x86_64 0:3.0.0-0.7.0daab7da36a8.hg.fc13 set to be updated\n" #~ "--> Processing Dependency: PyXML for package: heartbeat-3.0.0-0.7.0daab7da36a8.hg.fc13.x86_64\n" #~ "---> Package heartbeat-libs.x86_64 0:3.0.0-0.7.0daab7da36a8.hg.fc13 set to be updated\n" #~ "---> Package libesmtp.x86_64 0:1.0.4-12.fc12 set to be updated\n" #~ "---> Package net-snmp.x86_64 1:5.5-12.fc13 set to be updated\n" #~ "--> Processing Dependency: libsensors.so.4()(64bit) for package: 1:net-snmp-5.5-12.fc13.x86_64\n" #~ "---> Package net-snmp-libs.x86_64 1:5.5-12.fc13 set to be updated\n" #~ "---> Package pacemaker-libs.x86_64 0:1.1.5-1.fc13 set to be updated\n" #~ "---> Package resource-agents.x86_64 0:3.0.10-1.fc13 set to be updated\n" #~ "--> Processing Dependency: libnet.so.1()(64bit) for package: resource-agents-3.0.10-1.fc13.x86_64\n" #~ "--> Running transaction check\n" #~ "---> Package OpenIPMI-libs.x86_64 0:2.0.16-8.fc13 set to be updated\n" #~ "---> Package PyXML.x86_64 0:0.8.4-17.fc13 set to be updated\n" #~ "---> Package libibverbs.x86_64 0:1.1.3-4.fc13 set to be updated\n" #~ "--> Processing Dependency: libibverbs-driver for package: libibverbs-1.1.3-4.fc13.x86_64\n" #~ "---> Package libnet.x86_64 0:1.1.4-3.fc12 set to be updated\n" #~ "---> Package librdmacm.x86_64 0:1.0.10-2.fc13 set to be updated\n" #~ "---> Package lm_sensors-libs.x86_64 0:3.1.2-2.fc13 set to be updated\n" #~ "---> Package openhpi-libs.x86_64 0:2.14.1-3.fc13 set to be updated\n" #~ "---> Package perl-TimeDate.noarch 1:1.20-1.fc13 set to be updated\n" #~ "--> Running transaction check\n" #~ "---> Package libmlx4.x86_64 0:1.0.1-5.fc13 set to be updated\n" #~ "--> Finished Dependency Resolution\n" #~ "\n" #~ "Dependencies Resolved\n" #~ "\n" #~ " " #~ msgid "" #~ "\n" #~ "==========================================================================================\n" #~ " Package Arch Version Repository Size\n" #~ "==========================================================================================\n" #~ "Installing:\n" #~ " corosync x86_64 1.2.1-1.fc13 fedora 136 k\n" #~ " pacemaker x86_64 1.1.5-1.fc13 fedora 543 k\n" #~ "Installing for dependencies:\n" #~ " OpenIPMI-libs x86_64 2.0.16-8.fc13 fedora 474 k\n" #~ " PyXML x86_64 0.8.4-17.fc13 fedora 906 k\n" #~ " cluster-glue x86_64 1.0.2-1.fc13 fedora 230 k\n" #~ " cluster-glue-libs x86_64 1.0.2-1.fc13 fedora 116 k\n" #~ " corosynclib x86_64 1.2.1-1.fc13 fedora 145 k\n" #~ " heartbeat x86_64 3.0.0-0.7.0daab7da36a8.hg.fc13 updates 172 k\n" #~ " heartbeat-libs x86_64 3.0.0-0.7.0daab7da36a8.hg.fc13 updates 265 k\n" #~ " libesmtp x86_64 1.0.4-12.fc12 fedora 54 k\n" #~ " libibverbs x86_64 1.1.3-4.fc13 fedora 42 k\n" #~ " libmlx4 x86_64 1.0.1-5.fc13 fedora 27 k\n" #~ " libnet x86_64 1.1.4-3.fc12 fedora 49 k\n" #~ " librdmacm x86_64 1.0.10-2.fc13 fedora 22 k\n" #~ " lm_sensors-libs x86_64 3.1.2-2.fc13 fedora 37 k\n" #~ " net-snmp x86_64 1:5.5-12.fc13 fedora 295 k\n" #~ " net-snmp-libs x86_64 1:5.5-12.fc13 fedora 1.5 M\n" #~ " openhpi-libs x86_64 2.14.1-3.fc13 fedora 135 k\n" #~ " pacemaker-libs x86_64 1.1.5-1.fc13 fedora 264 k\n" #~ " perl-TimeDate noarch 1:1.20-1.fc13 fedora 42 k\n" #~ " resource-agents x86_64 3.0.10-1.fc13 fedora 357 k\n" #~ "\n" #~ "Transaction Summary\n" #~ "=========================================================================================\n" #~ "Install 21 Package(s)\n" #~ "Upgrade 0 Package(s)\n" #~ "\n" #~ "Total download size: 5.7 M\n" #~ "Installed size: 20 M\n" #~ "Downloading Packages:\n" #~ "Setting up and reading Presto delta metadata\n" #~ "updates-testing/prestodelta | 164 kB 00:00 \n" #~ "fedora/prestodelta | 150 B 00:00 \n" #~ "Processing delta metadata\n" #~ "Package(s) data still to download: 5.7 M\n" #~ "(1/21): OpenIPMI-libs-2.0.16-8.fc13.x86_64.rpm | 474 kB 00:00 \n" #~ "(2/21): PyXML-0.8.4-17.fc13.x86_64.rpm | 906 kB 00:01 \n" #~ "(3/21): cluster-glue-1.0.2-1.fc13.x86_64.rpm | 230 kB 00:00 \n" #~ "(4/21): cluster-glue-libs-1.0.2-1.fc13.x86_64.rpm | 116 kB 00:00 \n" #~ "(5/21): corosync-1.2.1-1.fc13.x86_64.rpm | 136 kB 00:00 \n" #~ "(6/21): corosynclib-1.2.1-1.fc13.x86_64.rpm | 145 kB 00:00 \n" #~ "(7/21): heartbeat-3.0.0-0.7.0daab7da36a8.hg.fc13.x86_64.rpm | 172 kB 00:00 \n" #~ "(8/21): heartbeat-libs-3.0.0-0.7.0daab7da36a8.hg.fc13.x86_64.rpm | 265 kB 00:00 \n" #~ "(9/21): libesmtp-1.0.4-12.fc12.x86_64.rpm | 54 kB 00:00 \n" #~ "(10/21): libibverbs-1.1.3-4.fc13.x86_64.rpm | 42 kB 00:00 \n" #~ "(11/21): libmlx4-1.0.1-5.fc13.x86_64.rpm | 27 kB 00:00 \n" #~ "(12/21): libnet-1.1.4-3.fc12.x86_64.rpm | 49 kB 00:00 \n" #~ "(13/21): librdmacm-1.0.10-2.fc13.x86_64.rpm | 22 kB 00:00 \n" #~ "(14/21): lm_sensors-libs-3.1.2-2.fc13.x86_64.rpm | 37 kB 00:00 \n" #~ "(15/21): net-snmp-5.5-12.fc13.x86_64.rpm | 295 kB 00:00 \n" #~ "(16/21): net-snmp-libs-5.5-12.fc13.x86_64.rpm | 1.5 MB 00:01 \n" #~ "(17/21): openhpi-libs-2.14.1-3.fc13.x86_64.rpm | 135 kB 00:00 \n" #~ "(18/21): pacemaker-1.1.5-1.fc13.x86_64.rpm | 543 kB 00:00 \n" #~ "(19/21): pacemaker-libs-1.1.5-1.fc13.x86_64.rpm | 264 kB 00:00 \n" #~ "(20/21): perl-TimeDate-1.20-1.fc13.noarch.rpm | 42 kB 00:00 \n" #~ "(21/21): resource-agents-3.0.10-1.fc13.x86_64.rpm | 357 kB 00:00 \n" #~ "----------------------------------------------------------------------------------------\n" #~ "Total 539 kB/s | 5.7 MB 00:10 \n" #~ "warning: rpmts_HdrFromFdno: Header V3 RSA/SHA256 Signature, key ID e8e40fde: NOKEY\n" #~ "fedora/gpgkey | 3.2 kB 00:00 ... \n" #~ "Importing GPG key 0xE8E40FDE \"Fedora (13) <fedora@fedoraproject.org%gt;\" from /etc/pki/rpm-gpg/RPM-GPG-KEY-fedora-x86_64\n" #~ " " #~ msgstr "" #~ "\n" #~ "==========================================================================================\n" #~ " Package Arch Version Repository Size\n" #~ "==========================================================================================\n" #~ "Installing:\n" #~ " corosync x86_64 1.2.1-1.fc13 fedora 136 k\n" #~ " pacemaker x86_64 1.1.5-1.fc13 fedora 543 k\n" #~ "Installing for dependencies:\n" #~ " OpenIPMI-libs x86_64 2.0.16-8.fc13 fedora 474 k\n" #~ " PyXML x86_64 0.8.4-17.fc13 fedora 906 k\n" #~ " cluster-glue x86_64 1.0.2-1.fc13 fedora 230 k\n" #~ " cluster-glue-libs x86_64 1.0.2-1.fc13 fedora 116 k\n" #~ " corosynclib x86_64 1.2.1-1.fc13 fedora 145 k\n" #~ " heartbeat x86_64 3.0.0-0.7.0daab7da36a8.hg.fc13 updates 172 k\n" #~ " heartbeat-libs x86_64 3.0.0-0.7.0daab7da36a8.hg.fc13 updates 265 k\n" #~ " libesmtp x86_64 1.0.4-12.fc12 fedora 54 k\n" #~ " libibverbs x86_64 1.1.3-4.fc13 fedora 42 k\n" #~ " libmlx4 x86_64 1.0.1-5.fc13 fedora 27 k\n" #~ " libnet x86_64 1.1.4-3.fc12 fedora 49 k\n" #~ " librdmacm x86_64 1.0.10-2.fc13 fedora 22 k\n" #~ " lm_sensors-libs x86_64 3.1.2-2.fc13 fedora 37 k\n" #~ " net-snmp x86_64 1:5.5-12.fc13 fedora 295 k\n" #~ " net-snmp-libs x86_64 1:5.5-12.fc13 fedora 1.5 M\n" #~ " openhpi-libs x86_64 2.14.1-3.fc13 fedora 135 k\n" #~ " pacemaker-libs x86_64 1.1.5-1.fc13 fedora 264 k\n" #~ " perl-TimeDate noarch 1:1.20-1.fc13 fedora 42 k\n" #~ " resource-agents x86_64 3.0.10-1.fc13 fedora 357 k\n" #~ "\n" #~ "Transaction Summary\n" #~ "=========================================================================================\n" #~ "Install 21 Package(s)\n" #~ "Upgrade 0 Package(s)\n" #~ "\n" #~ "Total download size: 5.7 M\n" #~ "Installed size: 20 M\n" #~ "Downloading Packages:\n" #~ "Setting up and reading Presto delta metadata\n" #~ "updates-testing/prestodelta | 164 kB 00:00 \n" #~ "fedora/prestodelta | 150 B 00:00 \n" #~ "Processing delta metadata\n" #~ "Package(s) data still to download: 5.7 M\n" #~ "(1/21): OpenIPMI-libs-2.0.16-8.fc13.x86_64.rpm | 474 kB 00:00 \n" #~ "(2/21): PyXML-0.8.4-17.fc13.x86_64.rpm | 906 kB 00:01 \n" #~ "(3/21): cluster-glue-1.0.2-1.fc13.x86_64.rpm | 230 kB 00:00 \n" #~ "(4/21): cluster-glue-libs-1.0.2-1.fc13.x86_64.rpm | 116 kB 00:00 \n" #~ "(5/21): corosync-1.2.1-1.fc13.x86_64.rpm | 136 kB 00:00 \n" #~ "(6/21): corosynclib-1.2.1-1.fc13.x86_64.rpm | 145 kB 00:00 \n" #~ "(7/21): heartbeat-3.0.0-0.7.0daab7da36a8.hg.fc13.x86_64.rpm | 172 kB 00:00 \n" #~ "(8/21): heartbeat-libs-3.0.0-0.7.0daab7da36a8.hg.fc13.x86_64.rpm | 265 kB 00:00 \n" #~ "(9/21): libesmtp-1.0.4-12.fc12.x86_64.rpm | 54 kB 00:00 \n" #~ "(10/21): libibverbs-1.1.3-4.fc13.x86_64.rpm | 42 kB 00:00 \n" #~ "(11/21): libmlx4-1.0.1-5.fc13.x86_64.rpm | 27 kB 00:00 \n" #~ "(12/21): libnet-1.1.4-3.fc12.x86_64.rpm | 49 kB 00:00 \n" #~ "(13/21): librdmacm-1.0.10-2.fc13.x86_64.rpm | 22 kB 00:00 \n" #~ "(14/21): lm_sensors-libs-3.1.2-2.fc13.x86_64.rpm | 37 kB 00:00 \n" #~ "(15/21): net-snmp-5.5-12.fc13.x86_64.rpm | 295 kB 00:00 \n" #~ "(16/21): net-snmp-libs-5.5-12.fc13.x86_64.rpm | 1.5 MB 00:01 \n" #~ "(17/21): openhpi-libs-2.14.1-3.fc13.x86_64.rpm | 135 kB 00:00 \n" #~ "(18/21): pacemaker-1.1.5-1.fc13.x86_64.rpm | 543 kB 00:00 \n" #~ "(19/21): pacemaker-libs-1.1.5-1.fc13.x86_64.rpm | 264 kB 00:00 \n" #~ "(20/21): perl-TimeDate-1.20-1.fc13.noarch.rpm | 42 kB 00:00 \n" #~ "(21/21): resource-agents-3.0.10-1.fc13.x86_64.rpm | 357 kB 00:00 \n" #~ "----------------------------------------------------------------------------------------\n" #~ "Total 539 kB/s | 5.7 MB 00:10 \n" #~ "warning: rpmts_HdrFromFdno: Header V3 RSA/SHA256 Signature, key ID e8e40fde: NOKEY\n" #~ "fedora/gpgkey | 3.2 kB 00:00 ... \n" #~ "Importing GPG key 0xE8E40FDE \"Fedora (13) <fedora@fedoraproject.org%gt;\" from /etc/pki/rpm-gpg/RPM-GPG-KEY-fedora-x86_64\n" #~ " " #~ msgid "" #~ "\n" #~ "Running rpm_check_debug\n" #~ "Running Transaction Test\n" #~ "Transaction Test Succeeded\n" #~ "Running Transaction\n" #~ " Installing : lm_sensors-libs-3.1.2-2.fc13.x86_64 1/21 \n" #~ " Installing : 1:net-snmp-libs-5.5-12.fc13.x86_64 2/21 \n" #~ " Installing : 1:net-snmp-5.5-12.fc13.x86_64 3/21 \n" #~ " Installing : openhpi-libs-2.14.1-3.fc13.x86_64 4/21 \n" #~ " Installing : libibverbs-1.1.3-4.fc13.x86_64 5/21 \n" #~ " Installing : libmlx4-1.0.1-5.fc13.x86_64 6/21 \n" #~ " Installing : librdmacm-1.0.10-2.fc13.x86_64 7/21 \n" #~ " Installing : corosync-1.2.1-1.fc13.x86_64 8/21 \n" #~ " Installing : corosynclib-1.2.1-1.fc13.x86_64 9/21 \n" #~ " Installing : libesmtp-1.0.4-12.fc12.x86_64 10/21 \n" #~ " Installing : OpenIPMI-libs-2.0.16-8.fc13.x86_64 11/21 \n" #~ " Installing : PyXML-0.8.4-17.fc13.x86_64 12/21 \n" #~ " Installing : libnet-1.1.4-3.fc12.x86_64 13/21 \n" #~ " Installing : 1:perl-TimeDate-1.20-1.fc13.noarch 14/21 \n" #~ " Installing : cluster-glue-1.0.2-1.fc13.x86_64 15/21 \n" #~ " Installing : cluster-glue-libs-1.0.2-1.fc13.x86_64 16/21 \n" #~ " Installing : resource-agents-3.0.10-1.fc13.x86_64 17/21 \n" #~ " Installing : heartbeat-libs-3.0.0-0.7.0daab7da36a8.hg.fc13.x86_64 18/21 \n" #~ " Installing : heartbeat-3.0.0-0.7.0daab7da36a8.hg.fc13.x86_64 19/21 \n" #~ " Installing : pacemaker-1.1.5-1.fc13.x86_64 20/21 \n" #~ " Installing : pacemaker-libs-1.1.5-1.fc13.x86_64 21/21 \n" #~ "\n" #~ "Installed:\n" #~ " corosync.x86_64 0:1.2.1-1.fc13 pacemaker.x86_64 0:1.1.5-1.fc13 \n" #~ "\n" #~ "Dependency Installed:\n" #~ " OpenIPMI-libs.x86_64 0:2.0.16-8.fc13 \n" #~ " PyXML.x86_64 0:0.8.4-17.fc13 \n" #~ " cluster-glue.x86_64 0:1.0.2-1.fc13 \n" #~ " cluster-glue-libs.x86_64 0:1.0.2-1.fc13 \n" #~ " corosynclib.x86_64 0:1.2.1-1.fc13 \n" #~ " heartbeat.x86_64 0:3.0.0-0.7.0daab7da36a8.hg.fc13 \n" #~ " heartbeat-libs.x86_64 0:3.0.0-0.7.0daab7da36a8.hg.fc13 \n" #~ " libesmtp.x86_64 0:1.0.4-12.fc12 \n" #~ " libibverbs.x86_64 0:1.1.3-4.fc13 \n" #~ " libmlx4.x86_64 0:1.0.1-5.fc13 \n" #~ " libnet.x86_64 0:1.1.4-3.fc12 \n" #~ " librdmacm.x86_64 0:1.0.10-2.fc13 \n" #~ " lm_sensors-libs.x86_64 0:3.1.2-2.fc13 \n" #~ " net-snmp.x86_64 1:5.5-12.fc13 \n" #~ " net-snmp-libs.x86_64 1:5.5-12.fc13 \n" #~ " openhpi-libs.x86_64 0:2.14.1-3.fc13 \n" #~ " pacemaker-libs.x86_64 0:1.1.5-1.fc13 \n" #~ " perl-TimeDate.noarch 1:1.20-1.fc13 \n" #~ " resource-agents.x86_64 0:3.0.10-1.fc13 \n" #~ "\n" #~ "Complete!\n" #~ "[root@pcmk-1 ~]# \n" #~ " " #~ msgstr "" #~ "\n" #~ "Running rpm_check_debug\n" #~ "Running Transaction Test\n" #~ "Transaction Test Succeeded\n" #~ "Running Transaction\n" #~ " Installing : lm_sensors-libs-3.1.2-2.fc13.x86_64 1/21 \n" #~ " Installing : 1:net-snmp-libs-5.5-12.fc13.x86_64 2/21 \n" #~ " Installing : 1:net-snmp-5.5-12.fc13.x86_64 3/21 \n" #~ " Installing : openhpi-libs-2.14.1-3.fc13.x86_64 4/21 \n" #~ " Installing : libibverbs-1.1.3-4.fc13.x86_64 5/21 \n" #~ " Installing : libmlx4-1.0.1-5.fc13.x86_64 6/21 \n" #~ " Installing : librdmacm-1.0.10-2.fc13.x86_64 7/21 \n" #~ " Installing : corosync-1.2.1-1.fc13.x86_64 8/21 \n" #~ " Installing : corosynclib-1.2.1-1.fc13.x86_64 9/21 \n" #~ " Installing : libesmtp-1.0.4-12.fc12.x86_64 10/21 \n" #~ " Installing : OpenIPMI-libs-2.0.16-8.fc13.x86_64 11/21 \n" #~ " Installing : PyXML-0.8.4-17.fc13.x86_64 12/21 \n" #~ " Installing : libnet-1.1.4-3.fc12.x86_64 13/21 \n" #~ " Installing : 1:perl-TimeDate-1.20-1.fc13.noarch 14/21 \n" #~ " Installing : cluster-glue-1.0.2-1.fc13.x86_64 15/21 \n" #~ " Installing : cluster-glue-libs-1.0.2-1.fc13.x86_64 16/21 \n" #~ " Installing : resource-agents-3.0.10-1.fc13.x86_64 17/21 \n" #~ " Installing : heartbeat-libs-3.0.0-0.7.0daab7da36a8.hg.fc13.x86_64 18/21 \n" #~ " Installing : heartbeat-3.0.0-0.7.0daab7da36a8.hg.fc13.x86_64 19/21 \n" #~ " Installing : pacemaker-1.1.5-1.fc13.x86_64 20/21 \n" #~ " Installing : pacemaker-libs-1.1.5-1.fc13.x86_64 21/21 \n" #~ "\n" #~ "Installed:\n" #~ " corosync.x86_64 0:1.2.1-1.fc13 pacemaker.x86_64 0:1.1.5-1.fc13 \n" #~ "\n" #~ "Dependency Installed:\n" #~ " OpenIPMI-libs.x86_64 0:2.0.16-8.fc13 \n" #~ " PyXML.x86_64 0:0.8.4-17.fc13 \n" #~ " cluster-glue.x86_64 0:1.0.2-1.fc13 \n" #~ " cluster-glue-libs.x86_64 0:1.0.2-1.fc13 \n" #~ " corosynclib.x86_64 0:1.2.1-1.fc13 \n" #~ " heartbeat.x86_64 0:3.0.0-0.7.0daab7da36a8.hg.fc13 \n" #~ " heartbeat-libs.x86_64 0:3.0.0-0.7.0daab7da36a8.hg.fc13 \n" #~ " libesmtp.x86_64 0:1.0.4-12.fc12 \n" #~ " libibverbs.x86_64 0:1.1.3-4.fc13 \n" #~ " libmlx4.x86_64 0:1.0.1-5.fc13 \n" #~ " libnet.x86_64 0:1.1.4-3.fc12 \n" #~ " librdmacm.x86_64 0:1.0.10-2.fc13 \n" #~ " lm_sensors-libs.x86_64 0:3.1.2-2.fc13 \n" #~ " net-snmp.x86_64 1:5.5-12.fc13 \n" #~ " net-snmp-libs.x86_64 1:5.5-12.fc13 \n" #~ " openhpi-libs.x86_64 0:2.14.1-3.fc13 \n" #~ " pacemaker-libs.x86_64 0:1.1.5-1.fc13 \n" #~ " perl-TimeDate.noarch 1:1.20-1.fc13 \n" #~ " resource-agents.x86_64 0:3.0.10-1.fc13 \n" #~ "\n" #~ "Complete!\n" #~ "[root@pcmk-1 ~]# \n" #~ " " #~ msgid "Verify Connectivity by IP address" #~ msgstr "Verificați Conectivitatea după Adresa IP" #~ msgid "Set up /etc/hosts entries" #~ msgstr "Setați intrările din /etc/hosts" #~ msgid "Verify Connectivity by Hostname" #~ msgstr "Verificați Conectivitatea după Numele Gazdei" #~ msgid "" #~ "\n" #~ "[root@pcmk-1 ~]# uname -n\n" #~ "pcmk-1.clusterlabs.org\n" #~ "[root@pcmk-1 ~]# dnsdomainname \n" #~ "clusterlabs.org\n" #~ " " #~ msgstr "" #~ "\n" #~ "[root@pcmk-1 ~]# uname -n\n" #~ "pcmk-1.clusterlabs.org\n" #~ "[root@pcmk-1 ~]# dnsdomainname \n" #~ "clusterlabs.org\n" #~ " " #~ msgid "" #~ "\n" #~ "[root@pcmk-1 ~]# source /etc/sysconfig/network\n" #~ "[root@pcmk-1 ~]# hostname $HOSTNAME\n" #~ " " #~ msgstr "" #~ "\n" #~ "[root@pcmk-1 ~]# source /etc/sysconfig/network\n" #~ "[root@pcmk-1 ~]# hostname $HOSTNAME\n" #~ " " #~ msgid "" #~ "\n" #~ "[root@pcmk-1 ~]# uname -n\n" #~ "pcmk-1\n" #~ "[root@pcmk-1 ~]# dnsdomainname \n" #~ "clusterlabs.org\n" #~ " " #~ msgstr "" #~ "\n" #~ "[root@pcmk-1 ~]# uname -n\n" #~ "pcmk-1\n" #~ "[root@pcmk-1 ~]# dnsdomainname \n" #~ "clusterlabs.org\n" #~ " " #~ msgid "Now repeat on pcmk-2." #~ msgstr "Acum repetați pe pcmk-2." #~ msgid "Choose a port number and multicast http://en.wikipedia.org/wiki/Multicast address. http://en.wikipedia.org/wiki/Multicast_address " #~ msgstr "Alegeți un număr de port și o http://en.wikipedia.org/wiki/Multicast adresă multicast. http://en.wikipedia.org/wiki/Multicast_address " #~ msgid "For this document, I have chosen port 4000 and used 226.94.1.1 as the multicast address." #~ msgstr "Pentru acest document, am ales portul 4000 și am folosit 226.94.1.1 ca adresă multicast" #~ msgid "The instructions below only apply for a machine with a single NIC. If you have a more complicated setup, you should edit the configuration manually." #~ msgstr "Instrucțiunile de mai jos se aplică numai pentru o mașină cu o singură placă de rețea. Dacă aveți un setup mai complicat, ar trebui să editați configurația manual." #~ msgid "" #~ "\n" #~ "[root@pcmk-1 ~]# export ais_port=4000\n" #~ "[root@pcmk-1 ~]# export ais_mcast=226.94.1.1\n" #~ " " #~ msgstr "" #~ "\n" #~ "[root@pcmk-1 ~]# export ais_port=4000\n" #~ "[root@pcmk-1 ~]# export ais_mcast=226.94.1.1\n" #~ " " #~ msgid "Next we automatically determine the hosts address. By not using the full address, we make the configuration suitable to be copied to other nodes." #~ msgstr "În continuare determinăm în mod automat adresa gazdelor. Nefolosind adresa completă, facem configurația fezabilă pentru a fi copiată pe alte noduri." #~ msgid "[root@pcmk-1 ~]# export ais_addr=`ip addr | grep \"inet \" | tail -n 1 | awk '{print $4}' | sed s/255/0/`" #~ msgstr "[root@pcmk-1 ~]# export ais_addr=`ip addr | grep \"inet \" | tail -n 1 | awk '{print $4}' | sed s/255/0/`" #~ msgid "Display and verify the configuration options" #~ msgstr "Listați și verificați opțiunile de configurare" #~ msgid "" #~ "\n" #~ "[root@pcmk-1 ~]# env | grep ais_\n" #~ "ais_mcast=226.94.1.1\n" #~ "ais_port=4000\n" #~ "ais_addr=192.168.122.0\n" #~ " " #~ msgstr "" #~ "\n" #~ "[root@pcmk-1 ~]# env | grep ais_\n" #~ "ais_mcast=226.94.1.1\n" #~ "ais_port=4000\n" #~ "ais_addr=192.168.122.0\n" #~ " " #~ msgid "Once you're happy with the chosen values, update the Corosync configuration" #~ msgstr "Odată ce sunteți mulțumiți cu valorile alese, actualizați configurația Corosync" #~ msgid "" #~ "\n" #~ "[root@pcmk-1 ~]# cp /etc/corosync/corosync.conf.example /etc/corosync/corosync.conf\n" #~ "[root@pcmk-1 ~]# sed -i.bak \"s/.*mcastaddr:.*/mcastaddr:\\ $ais_mcast/g\" /etc/corosync/corosync.conf\n" #~ "[root@pcmk-1 ~]# sed -i.bak \"s/.*mcastport:.*/mcastport:\\ $ais_port/g\" /etc/corosync/corosync.conf\n" #~ "[root@pcmk-1 ~]# sed -i.bak \"s/.*bindnetaddr:.*/bindnetaddr:\\ $ais_addr/g\" /etc/corosync/corosync.conf\n" #~ " " #~ msgstr "" #~ "\n" #~ "[root@pcmk-1 ~]# cp /etc/corosync/corosync.conf.example /etc/corosync/corosync.conf\n" #~ "[root@pcmk-1 ~]# sed -i.bak \"s/.*mcastaddr:.*/mcastaddr:\\ $ais_mcast/g\" /etc/corosync/corosync.conf\n" #~ "[root@pcmk-1 ~]# sed -i.bak \"s/.*mcastport:.*/mcastport:\\ $ais_port/g\" /etc/corosync/corosync.conf\n" #~ "[root@pcmk-1 ~]# sed -i.bak \"s/.*bindnetaddr:.*/bindnetaddr:\\ $ais_addr/g\" /etc/corosync/corosync.conf\n" #~ " " #~ msgid "Finally, tell Corosync to load the Pacemaker plugin." #~ msgstr "În sfârșit, spuneți Corosync-ului să încarce plugin-ul de Pacemaker." #~ msgid "" #~ "\n" #~ "[root@pcmk-1 ~]# cat <<-END >>/etc/corosync/service.d/pcmk\n" #~ "service {\n" #~ " # Load the Pacemaker Cluster Resource Manager\n" #~ " name: pacemaker\n" #~ " ver: 1\n" #~ "}\n" #~ "END\n" #~ " " #~ msgstr "" #~ "\n" #~ "[root@pcmk-1 ~]# cat <<-END >>/etc/corosync/service.d/pcmk\n" #~ "service {\n" #~ " # Load the Pacemaker Cluster Resource Manager\n" #~ " name: pacemaker\n" #~ " ver: 1\n" #~ "}\n" #~ "END\n" #~ " " #~ msgid "When run in version 1 mode, the plugin does not start the Pacemaker daemons. Instead it just sets up the quorum and messaging interfaces needed by the rest of the stack." #~ msgstr "Când rulează în modul versiunea 1, plugin-ul nu pornește daemonii Pacemaker-ului. În schimb doar setează quorum-ul și interfețele de mesagerie necesitate de către restul stivei." #~ msgid "Starting the dameons occurs when the Pacemaker init script is invoked. This resolves two long standing issues:" #~ msgstr "Pornirea daemonilor se întâmplă când scriptul de init al Pacemaker este invocat. Acest lucru rezolvă două probleme existente de mult timp: " #~ msgid "Forking inside a multi-threaded process like Corosync causes all sorts of pain. This has been problematic for Pacemaker as it needs a number of daemons to be spawned." #~ msgstr "Forking-ul înăuntrul unui proces multi-threaded precum Corosync cauzează tot felul de probleme. Acest lucru a fost problematic pentru Pacemaker din moment ce acesta are nevoie de un număr de daemoni să fie lansați în execuție." #~ msgid "Corosync was never designed for staggered shutdown - something previously needed in order to prevent the cluster from leaving before Pacemaker could stop all active resources." #~ msgstr "Corosync nu a fost niciodată conceput pentru închiderea în pași - un aspect necesar anterior pentru a preveni clusterul din a ieși înainte ca Pacemaker să poată opri toate resursele active." #~ msgid "Propagate the Configuration" #~ msgstr "Propagarea Configurației" #~ msgid "Now we need to copy the changes so far to the other node:" #~ msgstr "Acum trebuie să copiem modificările făcute până acum pe celălalt nod:" #~ msgid "" #~ "\n" #~ "[root@pcmk-1 ~]# for f in /etc/corosync/corosync.conf /etc/corosync/service.d/pcmk /etc/hosts; do scp $f pcmk-2:$f ; done\n" #~ "corosync.conf 100% 1528 1.5KB/s 00:00\n" #~ "hosts 100% 281 0.3KB/s 00:00\n" #~ "[root@pcmk-1 ~]#\n" #~ " " #~ msgstr "" #~ "\n" #~ "[root@pcmk-1 ~]# for f in /etc/corosync/corosync.conf /etc/corosync/service.d/pcmk /etc/hosts; do scp $f pcmk-2:$f ; done\n" #~ "corosync.conf 100% 1528 1.5KB/s 00:00\n" #~ "hosts 100% 281 0.3KB/s 00:00\n" #~ "[root@pcmk-1 ~]#\n" #~ " " pacemaker-master/doc/Clusters_from_Scratch/ro-RO/Ch-Intro.po000066400000000000000000000447501217637305600243070ustar00rootroot00000000000000# # AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: Clusters from Scratch 1.1\n" "POT-Creation-Date: 2012-10-17T05:19:03\n" "PO-Revision-Date: 2011-11-25 09:08+0200\n" "Last-Translator: Dan Frîncu \n" "Language-Team: None\n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: application/x-publican; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. Tag: title #, no-c-format msgid "Read-Me-First" msgstr "Citeşte-mă-Întâi-pe-Mine" #. Tag: title #, no-c-format msgid "The Scope of this Document" msgstr "Domeniul de Aplicare al acestui Document" #. Tag: para #, no-c-format msgid "Computer clusters can be used to provide highly available services or resources. The redundancy of multiple machines is used to guard against failures of many types." msgstr "Clusterele de calculatoare pot fi folosite pentru a furniza servicii sau resurse cu disponibilitate crescută. Redundanța mai multor mașini este folosită pentru a proteja împotriva eșecurilor de multe feluri." #. Tag: para #, no-c-format msgid "This document will walk through the installation and setup of simple clusters using the Fedora distribution, version 17." msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "The clusters described here will use Pacemaker and Corosync to provide resource management and messaging. Required packages and modifications to their configuration files are described along with the use of the Pacemaker command line tool for generating the XML used for cluster control." msgstr "Acest document va merge prin instalarea și setarea de clustere simple folosind distribuția Fedora, versiunea 14. Clusterele descrise aici vor folosi Pacemaker și Corosync pentru a furniza gestiunea și mesageria resurselor. Pachetele necesare și modificările realizate fișierelor de configurare ale acestora sunt descrise împreună cu folosirea utilitarului din linie de comandă al Pacemaker-ului pentru generarea XML-ului folosit pentru controlul clusterului." #. Tag: para #, no-c-format msgid "Pacemaker is a central component and provides the resource management required in these systems. This management includes detecting and recovering from the failure of various nodes, resources and services under its control." msgstr "Pacemaker este o componentă centrală și furnizează gestiunea resurselor necesară în aceste sisteme. Această gestiune include detectarea și recuperarea de la eșecul diverselor noduri, resurselor și serviciilor care sunt sub controlul acestuia." #. Tag: para #, no-c-format msgid "When more in depth information is required and for real world usage, please refer to the Pacemaker Explained manual." msgstr "Când sunt necesare informații mai aprofundate și pentru utilizarea în lumea reală, vă rugăm să faceți referință la manualul Pacemaker Explained." #. Tag: title #, no-c-format msgid "What Is Pacemaker?" msgstr "Ce Este Pacemaker?" #. Tag: para #, fuzzy, no-c-format msgid "Pacemaker is a cluster resource manager. It achieves maximum availability for your cluster services (aka. resources) by detecting and recovering from node and resource-level failures by making use of the messaging and membership capabilities provided by your preferred cluster infrastructure (either Corosync or Heartbeat)." msgstr "Pacemaker este un gestionar de resurse în cluster. Atinge disponibilitatea maximă pentru serviciile voastre din cluster (cunoscute drept resurse/le) prin detectarea şi recuperarea din eşecuri la nivel de nod sau de resursă prin folosirea capabilităţilor de mesagerie şi apartenenţă furnizate de infrastructura voastră preferată de cluster (fie Corosync sau Heartbeat)." #. Tag: para #, fuzzy, no-c-format msgid "Pacemaker’s key features include:" msgstr "Caracteristicile cheie ale Pacemaker includ:" #. Tag: para #, no-c-format msgid "Detection and recovery of node and service-level failures" msgstr "Detectarea şi recuperarea eşecurilor la nivel de nod şi serviciu" #. Tag: para #, no-c-format msgid "Storage agnostic, no requirement for shared storage" msgstr "Agnostic d.p.d.v. al stocării, nu sunt cerinţe pentru spaţiu de stocare partajat" #. Tag: para #, no-c-format msgid "Resource agnostic, anything that can be scripted can be clustered" msgstr "Agnostic d.p.d.v. al resurselor, orice poate fi scriptat poate fi folosit într-un cluster" #. Tag: para #, fuzzy, no-c-format msgid "Supports STONITH for ensuring data integrity" msgstr "Suportă STONITH pentru asigurarea integrităţii datelor" #. Tag: para #, no-c-format msgid "Supports large and small clusters" msgstr "Suportă clustere mici şi mari" #. Tag: para #, fuzzy, no-c-format msgid "Supports both quorate and resource driven clusters" msgstr "Suportă clustere mici şi mari" #. Tag: para #, no-c-format msgid "Supports practically any redundancy configuration" msgstr "" #. Tag: para #, no-c-format msgid "Automatically replicated configuration that can be updated from any node" msgstr "Configuraţie replicată în mod automat care poate fi actualizată de pe orice nod" #. Tag: para #, no-c-format msgid "Ability to specify cluster-wide service ordering, colocation and anti-colocation" msgstr "Abilitatea de a specifica ordonare, colocare şi anti-colocare la nivelul întregului cluster" #. Tag: para #, no-c-format msgid "Support for advanced service types" msgstr "Suport pentru tipuri de servicii avansate" #. Tag: para #, no-c-format msgid "Clones: for services which need to be active on multiple nodes" msgstr "Clone: pentru servicii care trebuie să fie active pe mai multe noduri" #. Tag: para #, no-c-format msgid "Multi-state: for services with multiple modes (eg. master/slave, primary/secondary)" msgstr "Stări-multiple: pentru servicii cu mai multe moduri de operare (ex. master/slave, primar/secundar)" #. Tag: para #, fuzzy, no-c-format msgid "Unified, scriptable, cluster management tools." msgstr "Shell de cluster unificat, scriptabil" #. Tag: title #, no-c-format msgid "Pacemaker Architecture" msgstr "Arhitectura Pacemaker" #. Tag: para #, no-c-format msgid "At the highest level, the cluster is made up of three pieces:" msgstr "La cel mai înalt nivel, clusterul este compus din trei părţi:" #. Tag: para #, fuzzy, no-c-format msgid "Non-cluster aware components (illustrated in green). These pieces include the resources themselves, scripts that start, stop and monitor them, and also a local daemon that masks the differences between the different standards these scripts implement." msgstr "Aceste părți includ resursele în sine, scripturi care le pornesc, le opresc și le monitorizează și de asemenea un daemon local care maschează diferenţele între diferitele standarde pe care le implementează aceste scripturi." #. Tag: para #, fuzzy, no-c-format msgid "Resource management Pacemaker provides the brain (illustrated in blue) that processes and reacts to events regarding the cluster. These events include nodes joining or leaving the cluster; resource events caused by failures, maintenance, scheduled activities; and other administrative actions. Pacemaker will compute the ideal state of the cluster and plot a path to achieve it after any of these events. This may include moving resources, stopping nodes and even forcing them offline with remote power switches." msgstr "Pacemaker furnizează creierul (ilustrat în albastru) care procesează și reacționează la evenimente care privesc clusterul. Aceste evenimente includ noduri care se alătură sau pleacă din cluster; evenimente ale resurselor cauzate de eșecuri, mentenanță, activități programate; și alte acțiuni administrative. Pacemaker va calcula starea ideală a clusterului și va cartografia o cale de a atinge țelul după oricare din aceste evenimente. Acest lucru poate include mutarea resurselor, oprirea nodurilor sau chiar oprirea forțată a acestora cu switch-uri de curent cu acces de la distanță." #. Tag: para #, fuzzy, no-c-format msgid "Low level infrastructure Corosync provides reliable messaging, membership and quorum information about the cluster (illustrated in red)." msgstr "Corosync furnizează informații de mesagerie, apartenență și quorum de încredere despre cluster (ilustrate cu roșu)." #. Tag: title #, no-c-format msgid "Conceptual Stack Overview" msgstr "Vederea Conceptuală a Stivei" #. Tag: phrase #, no-c-format msgid "Conceptual overview of the cluster stack" msgstr "Vederea conceptuală a stivei de cluster" #. Tag: para #, fuzzy, no-c-format msgid "When combined with Corosync, Pacemaker also supports popular open source cluster filesystems. Even though Pacemaker also supports Heartbeat, the filesystems need to use the stack for messaging and membership and Corosync seems to be what they’re standardizing on. Technically it would be possible for them to support Heartbeat as well, however there seems little interest in this." msgstr "În combinaţie cu Corosync, Pacemaker suportă de asemenea sistemele de fişiere de cluster open source populare Deși Pacemaker suportă de asemenea și Heartbeat, sistemele de fișiere au nevoie să folosească stiva pentru mesagerie și apartenență și Corosync pare să fie ținta standardizării. Tehnic ar fi posibil ca acestea să suporte Heartbeat de asemenea, însă există puţin interes pentru acest aspect. Datorită standardizării recente dinăuntrul comunităţii de sisteme de fişiere de cluster, acestea folosesc un manager de blocare distribuit care foloseşte la rândul său Corosync pentru capabilităţile acestuia de mesagerie şi Pacemaker pentru apartenenţă (care noduri sunt funcţionale şi care nu) şi pentru servicii de evacuare forțată." #. Tag: para #, no-c-format msgid "Due to recent standardization within the cluster filesystem community, they make use of a common distributed lock manager which makes use of Corosync for its messaging capabilities and Pacemaker for its membership (which nodes are up/down) and fencing services." msgstr "" #. Tag: title #, no-c-format msgid "The Pacemaker Stack" msgstr "Stiva Pacemaker" #. Tag: phrase #, fuzzy, no-c-format msgid "The Pacemaker StackThe Pacemaker stack when running on Corosync" msgstr "Stiva Pacemaker atunci când rulează pe Corosync" #. Tag: title #, no-c-format msgid "Internal Components" msgstr "Componente Interne" #. Tag: para #, no-c-format msgid "Pacemaker itself is composed of four key components (illustrated below in the same color scheme as the previous diagram):" msgstr "Pacemaker însuşi este compus din patru componente cheie (ilustrate mai jos cu aceeaşi schemă de culori ca şi în diagrama anterioară):" #. Tag: para #, no-c-format msgid "CIB (aka. Cluster Information Base)" msgstr "CIB (aka. Cluster Information Base)" #. Tag: para #, no-c-format msgid "CRMd (aka. Cluster Resource Management daemon)" msgstr "CRMd (aka. Cluster Resource Management daemon)" #. Tag: para #, no-c-format msgid "PEngine (aka. PE or Policy Engine)" msgstr "PEngine (aka. PE sau Policy Engine)" #. Tag: para #, no-c-format msgid "STONITHd" msgstr "STONITHd" #. Tag: phrase #, no-c-format msgid "Subsystems of a Pacemaker cluster running on Corosync" msgstr "Subsisteme ale unui cluster Pacemaker rulând pe Corosync" #. Tag: para #, fuzzy, no-c-format msgid "The CIB uses XML to represent both the cluster’s configuration and current state of all resources in the cluster. The contents of the CIB are automatically kept in sync across the entire cluster and are used by the PEngine to compute the ideal state of the cluster and how it should be achieved." msgstr "CIB-ul foloseşte XML pentru a reprezenta atât configuraţia clusterului cât şi starea curentă a tuturor resurselor din cluster. Conţinutul CIB-ului este ţinut sincronizat în mod automat pe tot clusterul şi este folosit de către PEngine pentru a calcula starea ideală a clusterului şi de a arăta cum poate fi atinsă." #. Tag: para #, fuzzy, no-c-format msgid "This list of instructions is then fed to the DC (Designated Co-ordinator). Pacemaker centralizes all cluster decision making by electing one of the CRMd instances to act as a master. Should the elected CRMd process, or the node it is on, fail… a new one is quickly established." msgstr "Lista de instrucţiuni este apoi furnizată către DC (Designated Co-ordinator). Pacemaker centralizează toate deciziile clusterului prin alegerea uneia dintre instanţele de CRMd pentru a se comporta ca master. Dacă procesul ales de CRMd sau nodul pe care acesta există eşuează ... unul nou este stabilit repede." #. Tag: para #, fuzzy, no-c-format msgid "The DC carries out the PEngine’s instructions in the required order by passing them to either the LRMd (Local Resource Management daemon) or CRMd peers on other nodes via the cluster messaging infrastructure (which in turn passes them on to their LRMd process)." msgstr "DC-ul îndeplineşte instrucţiunile PEngine-ului în ordinea necesară prin pasarea acestora fie către LRMd (Local Resource Managemen daemon) fie altor noduri pe care rulează CRMd prin infrastructura de mesagerie a clusterului (care la rândul ei le pasează către procesul lor LRMd)." #. Tag: para #, no-c-format msgid "The peer nodes all report the results of their operations back to the DC and based on the expected and actual results, will either execute any actions that needed to wait for the previous one to complete, or abort processing and ask the PEngine to recalculate the ideal cluster state based on the unexpected results." msgstr "Nodurile vecine raportează toate rezultatele operaţiunilor înapoi către DC şi pe baza rezultatelor aşteptate şi a rezultatelor actuale, fie va executa orice acţiuni care necesitau să aştepte ca şi cele anterioare să termine sau va anula procesarea şi va ruga PEngine-ul să recalculeze starea ideală a clusterului pe baza rezultatelor neaşteptate." #. Tag: para #, no-c-format msgid "In some cases, it may be necessary to power off nodes in order to protect shared data or complete resource recovery. For this Pacemaker comes with STONITHd. STONITH is an acronym for Shoot-The-Other-Node-In-The-Head and is usually implemented with a remote power switch. In Pacemaker, STONITH devices are modeled as resources (and configured in the CIB) to enable them to be easily monitored for failure, however STONITHd takes care of understanding the STONITH topology such that its clients simply request a node be fenced and it does the rest." msgstr "În anumite cazuri, ar putea fi necesar să oprească alimentarea nodurilor pentru a proteja datele partajate sau pentru a termina recuperarea resurselor. Pentru acest lucru Pacemaker vine cu STONITHd. STONITH este un acronim pentru Shoot-The-Other-Node-In-The-Head (împuşcă celălalt nod în cap) şi este implementat de obicei cu un switch de alimentare cu curent controlat de la distanţă. În Pacemaker, dispozitivele STONITH sunt modelate precum resursele (şi configurate în CIB) pentru a permite monitorizarea facilă a acestora în caz de eşec, totuşi STONITHd se ocupă de înţelegerea topologiei STONITH astfel încât clienţii acestuia să solicite pur şi simplu ca un nod să fie evacuat forțat şi acesta se va ocupa de rest." #. Tag: title #, no-c-format msgid "Types of Pacemaker Clusters" msgstr "Tipuri de Clustere Pacemaker" #. Tag: para #, no-c-format msgid "Pacemaker makes no assumptions about your environment, this allows it to support practically any redundancy configuration including Active/Active, Active/Passive, N+1, N+M, N-to-1 and N-to-N." msgstr "Pacemaker nu face nici un fel de presupuneri despre mediul vostru, acest aspect îi permite să suporte practic orice configuraţie redundantă incluzând Activ/Activ, Activ/Pasiv, N+1, N+M, N-la-1 şi N-la-N." #. Tag: para #, no-c-format msgid "In this document we will focus on the setup of a highly available Apache web server with an Active/Passive cluster using DRBD and Ext4 to store data. Then, we will upgrade this cluster to Active/Active using GFS2." msgstr "În acest document ne vom concentra pe setarea unui server web Apache cu disponibilitate crescută cu un cluster Activ/Pasiv folosind DRBD și Ext4 pentru a stoca datele. Apoi, vom actualiza clusterul la Activ/Activ folosind GFS2." #. Tag: title #, no-c-format msgid "Active/Passive Redundancy" msgstr "Redundanţă Activă/Pasivă" #. Tag: phrase #, fuzzy, no-c-format msgid "Two-node Active/Passive clusters using Pacemaker and DRBD are a cost-effective solution for many High Availability situations" msgstr "Clusterele Active/Pasive formate din două noduri care folosesc Pacemaker şi DRBD sunt o soluţie eficientă d.p.d.v. al costului pentru multe situaţii de Disponibilitate Crescută." #. Tag: title #, no-c-format msgid "N to N Redundancy" msgstr "Redundanţă N la N" #. Tag: phrase #, fuzzy, no-c-format msgid "When shared storage is available, every node can potentially be used for failover. Pacemaker can even run multiple copies of services to spread out the workload" msgstr "Când un mediu de stocare partajat este disponibil, fiecare nod poate fi folosit în mod potenţial pentru failover. Pacemaker poate chiar rula mai multe copii ale serviciilor pentru a distribui sarcina de lucru." #~ msgid "Supports both quorate and resource driven clusters" #~ msgstr "Suportă atât clustere quorate cât şi conduse de resurse" #~ msgid "Supports practically any redundancy configuration" #~ msgstr "Suportă practic orice configuraţie redundantă" #~ msgid "Non-cluster aware components (illustrated in green)." #~ msgstr "Componente fără cunoștințe despre cluster (ilustrate în verde)." #~ msgid "Resource management" #~ msgstr "Gestiunea resurselor" #~ msgid "Low level infrastructure" #~ msgstr "Infrastructura la nivel inferior" pacemaker-master/doc/Clusters_from_Scratch/ro-RO/Ch-Shared-Storage.po000066400000000000000000001656141217637305600260270ustar00rootroot00000000000000# # AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: Clusters from Scratch 1.1\n" "POT-Creation-Date: 2012-10-17T05:19:03\n" "PO-Revision-Date: 2011-11-25 23:39+0200\n" "Last-Translator: Dan Frîncu \n" "Language-Team: None\n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: application/x-publican; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. Tag: title #, no-c-format msgid "Replicated Storage with DRBD" msgstr "Stocare Replicată cu DRBD" #. Tag: title #, no-c-format msgid "Background" msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "Even if you’re serving up static websites, having to manually synchronize the contents of that website to all the machines in the cluster is not ideal. For dynamic websites, such as a wiki, it’s not even an option. Not everyone care afford network-attached storage but somehow the data needs to be kept in sync. Enter DRBD which can be thought of as network based RAID-1. See http://www.drbd.org/ for more details." msgstr "Chiar și atunci când serviți site-uri statice, să trebuiască să sincronizați manual conținutul site-ului pe toate mașinile din cluster nu este ideal. Pentru site-uri dinamice, cu ar fi wiki-urile, nici măcar nu este o opțiune acest lucru. Nu toată lumea își poate permite stocare atașată la rețea dar cumva datele trebuie ținute sincronizate. Intră în scenă DRBD care poate fi considerat ca un RAID-1 la nivel de rețea. Vedeți http://www.drbd.org/ pentru mai multe detalii." #. Tag: title #, no-c-format msgid "Install the DRBD Packages" msgstr "Instalarea Pachetelor DRBD" #. Tag: para #, fuzzy, no-c-format msgid "Since its inclusion in the upstream 2.6.33 kernel, everything needed to use DRBD has shiped with Fedora since version 13. All you need to do is install it:" msgstr "De la includerea acestuia în kernelul 2.6.33, tot ce este necesar pentru a rula DRBD este livrat cu &DISTRO; &DISTRO_VERSION;. Tot ceea ce trebuie să faceți este să îl instalați:" #. Tag: programlisting #, no-c-format msgid "# yum install -y drbd-pacemaker drbd-udev" msgstr "" #. Tag: literallayout #, fuzzy, no-c-format msgid "" "Loaded plugins: langpacks, presto, refresh-packagekit\n" "Resolving Dependencies\n" "--> Running transaction check\n" "---> Package drbd-pacemaker.x86_64 0:8.3.11-5.fc17 will be installed\n" "--> Processing Dependency: drbd-utils = 8.3.11-5.fc17 for package: drbd-pacemaker-8.3.11-5.fc17.x86_64\n" "---> Package drbd-udev.x86_64 0:8.3.11-5.fc17 will be installed\n" "--> Running transaction check\n" "---> Package drbd-utils.x86_64 0:8.3.11-5.fc17 will be installed\n" "--> Finished Dependency Resolution\n" "\n" "Dependencies Resolved\n" "\n" "======================================================================================\n" " Package Arch Version Repository Size\n" "======================================================================================\n" "Installing:\n" " drbd-pacemaker x86_64 8.3.11-5.fc17 updates-testing 22 k\n" " drbd-udev x86_64 8.3.11-5.fc17 updates-testing 6.4 k\n" "Installing for dependencies:\n" " drbd-utils x86_64 8.3.11-5.fc17 updates-testing 183 k\n" "\n" "Transaction Summary\n" "======================================================================================\n" "Install 2 Packages (+1 Dependent package)\n" "\n" "Total download size: 212 k\n" "Installed size: 473 k\n" "Downloading Packages:\n" "(1/3): drbd-pacemaker-8.3.11-5.fc17.x86_64.rpm | 22 kB 00:00\n" "(2/3): drbd-udev-8.3.11-5.fc17.x86_64.rpm | 6.4 kB 00:00\n" "(3/3): drbd-utils-8.3.11-5.fc17.x86_64.rpm | 183 kB 00:00\n" "--------------------------------------------------------------------------------------\n" "Total 293 kB/s | 212 kB 00:00\n" "Running Transaction Check\n" "Running Transaction Test\n" "Transaction Test Succeeded\n" "Running Transaction\n" " Installing : drbd-utils-8.3.11-5.fc17.x86_64 1/3\n" " Installing : drbd-pacemaker-8.3.11-5.fc17.x86_64 2/3\n" " Installing : drbd-udev-8.3.11-5.fc17.x86_64 3/3\n" " Verifying : drbd-pacemaker-8.3.11-5.fc17.x86_64 1/3\n" " Verifying : drbd-udev-8.3.11-5.fc17.x86_64 2/3\n" " Verifying : drbd-utils-8.3.11-5.fc17.x86_64 3/3\n" "\n" "Installed:\n" " drbd-pacemaker.x86_64 0:8.3.11-5.fc17 drbd-udev.x86_64 0:8.3.11-5.fc17\n" "\n" "Dependency Installed:\n" " drbd-utils.x86_64 0:8.3.11-5.fc17\n" "\n" "Complete!" msgstr "" "\n" "[root@pcmk-1 ~]# yum install -y drbd-pacemaker drbd-udev\n" "Loaded plugins: presto, refresh-packagekit\n" "Setting up Install Process\n" "Resolving Dependencies\n" "--> Running transaction check\n" "---> Package drbd-pacemaker.x86_64 0:8.3.7-2.fc13 set to be updated\n" "--> Processing Dependency: drbd-utils = 8.3.7-2.fc13 for package: drbd-pacemaker-8.3.7-2.fc13.x86_64\n" "--> Running transaction check\n" "---> Package drbd-utils.x86_64 0:8.3.7-2.fc13 set to be updated\n" "--> Finished Dependency Resolution\n" "\n" "Dependencies Resolved\n" "\n" "=================================================================================\n" " Package Arch Version Repository Size\n" "=================================================================================\n" "Installing:\n" " drbd-pacemaker x86_64 8.3.7-2.fc13 fedora 19 k\n" "Installing for dependencies:\n" " drbd-utils x86_64 8.3.7-2.fc13 fedora 165 k\n" "\n" "Transaction Summary\n" "=================================================================================\n" "Install 2 Package(s)\n" "Upgrade 0 Package(s)\n" "\n" "Total download size: 184 k\n" "Installed size: 427 k\n" "Downloading Packages:\n" "Setting up and reading Presto delta metadata\n" "fedora/prestodelta | 1.7 kB 00:00 \n" "Processing delta metadata\n" "Package(s) data still to download: 184 k\n" "(1/2): drbd-pacemaker-8.3.7-2.fc13.x86_64.rpm | 19 kB 00:01 \n" "(2/2): drbd-utils-8.3.7-2.fc13.x86_64.rpm | 165 kB 00:02 \n" "---------------------------------------------------------------------------------\n" "Total 45 kB/s | 184 kB 00:04 \n" "Running rpm_check_debug\n" "Running Transaction Test\n" "Transaction Test Succeeded\n" "Running Transaction\n" " Installing : drbd-utils-8.3.7-2.fc13.x86_64 1/2 \n" " Installing : drbd-pacemaker-8.3.7-2.fc13.x86_64 2/2 \n" "\n" "Installed:\n" " drbd-pacemaker.x86_64 0:8.3.7-2.fc13 \n" "\n" "Dependency Installed:\n" " drbd-utils.x86_64 0:8.3.7-2.fc13 \n" "\n" "Complete!\n" "[root@pcmk-1 ~]#\n" " " #. Tag: title #, no-c-format msgid "Configure DRBD" msgstr "Configurarea DRBD" #. Tag: para #, no-c-format msgid "Before we configure DRBD, we need to set aside some disk for it to use." msgstr "Înainte să configurăm DRBD-ul, trebuie să punem deoparte spațiu pe disc pentru ca acesta să îl folosească." #. Tag: title #, no-c-format msgid "Create A Partition for DRBD" msgstr "Crearea Unei Partiții Pentru DRBD" #. Tag: para #, no-c-format msgid "If you have more than 1Gb free, feel free to use it. For this guide however, 1Gb is plenty of space for a single html file and sufficient for later holding the GFS2 metadata." msgstr "Dacă aveți mai mult de 1Gb liber, simțiți-vă liberi să-l folosiți. Pentru acest ghid însă, 1Gb este suficient spațiu pentru un singur fișier html și suficient pentru a stoca ulterior metadata din GFS2." #. Tag: programlisting #, no-c-format msgid "" "# vgdisplay | grep -e Name - e Free\n" " VG Name vg_pcmk1\n" " Free PE / Size 31 / 992.00 MiB\n" "# lvs\n" " LV VG Attr LSize Pool Origin Data% Move Log Copy% Convert\n" " lv_root vg_pcmk1 -wi-ao-- 8.56g\n" " lv_swap vg_pcmk1 -wi-ao-- 960.00m\n" "# lvcreate -n drbd-demo -L 1G vg_pcmk1\n" "Logical volume \"drbd-demo\" created\n" "# lvs\n" " LV VG Attr LSize Pool Origin Data% Move Log Copy% Convert\n" " drbd-demo vg_pcmk1 -wi-a--- 1.00G\n" " lv_root vg_pcmk1 -wi-ao-- 8.56g\n" " lv_swap vg_pcmk1 -wi-ao-- 960.00m" msgstr "" #. Tag: para #, no-c-format msgid "Repeat this on the second node, be sure to use the same size partition." msgstr "Repetați acest lucru pe al doilea nod, asigurați-vă că folosiți o partiție de aceeași dimensiune." #. Tag: programlisting #, no-c-format msgid "" "# ssh pcmk-2 -- lvs\n" "LV VG Attr LSize Origin Snap% Move Log Copy% Convert\n" " lv_root vg_pcmk1 -wi-ao-- 8.56g\n" " lv_swap vg_pcmk1 -wi-ao-- 960.00m\n" "# ssh pcmk-2 -- lvcreate -n drbd-demo -L 1G vg_pcmk1\n" "Logical volume \"drbd-demo\" created\n" "# ssh pcmk-2 -- lvs\n" "LV VG Attr LSize Origin Snap% Move Log Copy% Convert\n" " drbd-demo vg_pcmk1 -wi-a--- 1.00G\n" " lv_root vg_pcmk1 -wi-ao-- 8.56g\n" " lv_swap vg_pcmk1 -wi-ao-- 960.00m" msgstr "" #. Tag: title #, no-c-format msgid "Write the DRBD Config" msgstr "Scrierea Config-ului DRBD" #. Tag: para #, no-c-format msgid "There is no series of commands for building a DRBD configuration, so simply copy the configuration below to /etc/drbd.conf" msgstr " Nu există nici o serie de comenzi pentru a construi configurația DRBD, așa că pur și simplu copiați configurația de mai jos în /etc/drbd.conf." #. Tag: para #, no-c-format msgid "Detailed information on the directives used in this configuration (and other alternatives) is available from http://www.drbd.org/users-guide/ch-configure.html" msgstr "Informații detaliate despre directivele folosite în această configurație (precum și alte alternative) sunt disponibile de pe http://www.drbd.org/users-guide/ch-configure.html" #. Tag: para #, fuzzy, no-c-format msgid "Be sure to use the names and addresses of your nodes if they differ from the ones used in this guide." msgstr "Asigurați-vă că folosiți numele și adresele nodurilor voastre, dacă diferă de cele folosite în acest ghid." #. Tag: literallayout #, fuzzy, no-c-format msgid "" "global {\n" " usage-count yes;\n" "}\n" "common {\n" " protocol C;\n" "}\n" "resource wwwdata {\n" " meta-disk internal;\n" " device /dev/drbd1;\n" " syncer {\n" " verify-alg sha1;\n" " }\n" " net {\n" " allow-two-primaries;\n" " }\n" " on pcmk-1 {\n" " disk /dev/vg_pcmk1/drbd-demo;\n" " address 192.168.122.101:7789;\n" " }\n" " on pcmk-2 {\n" " disk /dev/vg_pcmk1/drbd-demo;\n" " address 192.168.122.102:7789;\n" " }\n" "}" msgstr "" "\n" "global { \n" "  usage-count yes; \n" "}\n" "common {\n" "  protocol C;\n" "}\n" "resource wwwdata {\n" "  meta-disk internal;\n" "  device    /dev/drbd1;\n" "  syncer {\n" "    verify-alg sha1;\n" "  }\n" "  net { \n" "    allow-two-primaries; \n" "  }\n" "  on pcmk-1 {\n" "    disk      /dev/mapper/VolGroup-drbd--demo;\n" "    address   192.168.122.101:7789; \n" "  }\n" "  on \n" "pcmk-2 {\n" "    disk      /dev/mapper/VolGroup-drbd--demo;\n" "    address   192.168.122.102:7789; \n" "  }\n" "}\n" " " #. Tag: para #, no-c-format msgid "TODO: Explain the reason for the allow-two-primaries option" msgstr "TODO: De explicat motivul pentru opțiunea allow-two primaries" #. Tag: title #, no-c-format msgid "Initialize and Load DRBD" msgstr "Inițializarea și Încărcarea DRBD-ului" #. Tag: para #, no-c-format msgid "With the configuration in place, we can now perform the DRBD initialization" msgstr "Cu configurația pusă la locul ei, acum putem executa inițializarea DRBD-ului." #. Tag: programlisting #, no-c-format msgid "" "# drbdadm create-md wwwdata\n" "Writing meta data...\n" "initializing activity log\n" "NOT initialized bitmap\n" "New drbd meta data block successfully created.\n" "success" msgstr "" #. Tag: para #, no-c-format msgid "Now load the DRBD kernel module and confirm that everything is sane" msgstr "Acum încărcați modulul de kernel al DRBD și confirmați că totul este în regulă" #. Tag: programlisting #, no-c-format msgid "" "# modprobe drbd\n" "# drbdadm up wwwdata\n" "# cat /proc/drbd\n" "version: 8.3.11 (api:88/proto:86-96)\n" "srcversion: 0D2B62DEDB020A425130935\n" "\n" " 1: cs:Connected ro:Secondary/Secondary ds:Inconsistent/Inconsistent C r-----\n" " ns:0 nr:0 dw:0 dr:0 al:0 bm:0 lo:0 pe:0 ua:0 ap:0 ep:1 wo:f oos:1015740" msgstr "" #. Tag: para #, no-c-format msgid "Repeat on the second node" msgstr "" #. Tag: programlisting #, no-c-format msgid "" "# ssh pcmk-2 -- drbdadm --force create-md wwwdata\n" "Writing meta data...\n" "initializing activity log\n" "NOT initialized bitmap\n" "New drbd meta data block successfully created.\n" "success\n" "# ssh pcmk-2 -- modprobe drbd\n" "WARNING: Deprecated config file /etc/modprobe.conf, all config files belong into /etc/modprobe.d/.\n" "# ssh pcmk-2 -- drbdadm up wwwdata\n" "# ssh pcmk-2 -- cat /proc/drbd\n" "version: 8.3.11 (api:88/proto:86-96)\n" "srcversion: 0D2B62DEDB020A425130935\n" "\n" " 1: cs:Connected ro:Secondary/Secondary ds:Inconsistent/Inconsistent C r-----\n" " ns:0 nr:0 dw:0 dr:0 al:0 bm:0 lo:0 pe:0 ua:0 ap:0 ep:1 wo:f oos:1015740" msgstr "" #. Tag: para #, no-c-format msgid "Now we need to tell DRBD which set of data to use. Since both sides contain garbage, we can run the following on pcmk-1:" msgstr "Acum trebuie să spunem DRBD-ului care set de date să îl folosească. Din moment ce ambele părți conțin date nefolositoare, putem rula următoarea comandă pe pcmk-1:" #. Tag: programlisting #, no-c-format msgid "" "# drbdadm -- --overwrite-data-of-peer primary wwwdata\n" "# cat /proc/drbd\n" "version: 8.3.11 (api:88/proto:86-96)\n" "srcversion: 0D2B62DEDB020A425130935\n" "\n" " 1: cs:SyncSource ro:Primary/Secondary ds:UpToDate/Inconsistent C r-----\n" " ns:8064 nr:0 dw:0 dr:8728 al:0 bm:0 lo:0 pe:1 ua:0 ap:0 ep:1 wo:f oos:1007804\n" " [>....................] sync'ed: 0.9% (1007804/1015740)K\n" " finish: 0:12:35 speed: 1,320 (1,320) K/sec" msgstr "" #. Tag: para #, no-c-format msgid "After a while, the sync should finish and you’ll see:" msgstr "" #. Tag: programlisting #, no-c-format msgid "" "# cat /proc/drbd\n" "version: 8.3.11 (api:88/proto:86-96)\n" "srcversion: 0D2B62DEDB020A425130935\n" "\n" " 1: cs:Connected ro:Primary/Secondary ds:UpToDate/UpToDate C r-----\n" " ns:1015740 nr:0 dw:0 dr:1016404 al:0 bm:62 lo:0 pe:0 ua:0 ap:0 ep:1 wo:f oos:0" msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "pcmk-1 is now in the Primary state which allows it to be written to. Which means it’s a good point at which to create a filesystem and populate it with some data to serve up via our WebSite resource." msgstr "pcmk-1 este acum în starea Primară care îi permite să scrie pe acesta. Lucru care înseamnă că este un punct bun în care să creăm un sistem de fișiere și să îl populăm cu ceva date pe care să le servim prin resursa noastră WebSite." #. Tag: title #, no-c-format msgid "Populate DRBD with Data" msgstr "Popularea DRBD-ului cu Date" #. Tag: programlisting #, no-c-format msgid "" "# mkfs.ext4 /dev/drbd1\n" "mke2fs 1.42 (29-Nov-2011)\n" "Filesystem label=\n" "OS type: Linux\n" "Block size=4096 (log=2)\n" "Fragment size=4096 (log=2)\n" "Stride=0 blocks, Stripe width=0 blocks\n" "63488 inodes, 253935 blocks\n" "12696 blocks (5.00%) reserved for the super user\n" "First data block=0\n" "Maximum filesystem blocks=260046848\n" "8 block groups\n" "32768 blocks per group, 32768 fragments per group\n" "7936 inodes per group\n" "Superblock backups stored on blocks:\n" " 32768, 98304, 163840, 229376\n" "\n" "Allocating group tables: done\n" "Writing inode tables: done\n" "Creating journal (4096 blocks): done\n" "Writing superblocks and filesystem accounting information: done" msgstr "" #. Tag: para #, no-c-format msgid "Now mount the newly created filesystem so we can create our index file" msgstr "" #. Tag: programlisting #, no-c-format msgid "" "# mount /dev/drbd1 /mnt/\n" "# cat <<-END >/mnt/index.html\n" " <html>\n" " <body>My Test Site - drbd</body>\n" " </html>\n" "END\n" "# umount /dev/drbd1" msgstr "" #. Tag: title #, no-c-format msgid "Configure the Cluster for DRBD" msgstr "Configurarea Clusterului pentru DRBD" #. Tag: para #, no-c-format msgid "One handy feature pcs has is the ability to queue up several changes into a file and commit those changes atomically. To do this, start by populating the file with the current raw xml config from the cib. This can be done using the following command." msgstr "" #. Tag: programlisting #, no-c-format msgid "# pcs cluster cib drbd_cfg" msgstr "" #. Tag: para #, no-c-format msgid "Now using the pcs -f option, make changes to the configuration saved in the drbd_cfg file. These changes will not be seen by the cluster until the drbd_cfg file is pushed into the live cluster’s cib later on." msgstr "" #. Tag: screen #, no-c-format msgid "" "# pcs -f drbd_cfg resource create WebData ocf:linbit:drbd \\\n" " drbd_resource=wwwdata op monitor interval=60s\n" "# pcs -f drbd_cfg resource master WebDataClone WebData \\\n" " master-max=1 master-node-max=1 clone-max=2 clone-node-max=1 \\\n" " notify=true" msgstr "" #. Tag: programlisting #, no-c-format msgid "" "# pcs -f drbd_cfg resource show\n" " ClusterIP (ocf::heartbeat:IPaddr2) Started\n" " WebSite (ocf::heartbeat:apache) Started\n" " Master/Slave Set: WebDataClone [WebData]\n" " Stopped: [ WebData:0 WebData:1 ]" msgstr "" #. Tag: para #, no-c-format msgid "After you are satisfied with all the changes, you can commit all the changes at once by pushing the drbd_cfg file into the live cib." msgstr "" #. Tag: programlisting #, fuzzy, no-c-format msgid "" "# pcs cluster push cib drbd_cfg\n" "CIB updated\n" "\n" "# pcs status\n" "\n" "Last updated: Fri Sep 14 12:19:49 2012\n" "Last change: Fri Sep 14 12:19:13 2012 via cibadmin on pcmk-1\n" "Stack: corosync\n" "Current DC: pcmk-2 (2) - partition with quorum\n" "Version: 1.1.8-1.el7-60a19ed12fdb4d5c6a6b6767f52e5391e447fec0\n" "2 Nodes configured, unknown expected votes\n" "4 Resources configured.\n" "\n" "Online: [ pcmk-1 pcmk-2 ]\n" "\n" "Full list of resources:\n" "\n" " ClusterIP (ocf::heartbeat:IPaddr2): Started pcmk-1\n" " WebSite (ocf::heartbeat:apache): Started pcmk-1\n" " Master/Slave Set: WebDataClone [WebData]\n" " Masters: [ pcmk-1 ]\n" " Slaves: [ pcmk-2 ]" msgstr "" "\n" "[root@pcmk-1 ~]# crm node online\n" "[root@pcmk-1 ~]# crm_mon\n" "============\n" "Last updated: Tue Sep  1 10:13:25 2009\n" "Stack: openais\n" "Current DC: pcmk-1 - partition with quorum\n" "Version: 1.1.5-bdd89e69ba545404d02445be1f3d72e6a203ba2f\n" "2 Nodes configured, 2 expected votes\n" "4 Resources configured.\n" "============\n" "\n" "Online: [ pcmk-1 pcmk-2 ]\n" "\n" "ClusterIP        (ocf::heartbeat:IPaddr):        Started pcmk-2\n" "WebSite (ocf::heartbeat:apache):        Started pcmk-2\n" "Master/Slave Set: WebDataClone\n" "        Masters: [ pcmk-2 ]\n" "        Slaves: [ pcmk-1 ]\n" "WebFS   (ocf::heartbeat:Filesystem):    Started pcmk-2\n" " " #. Tag: para #, fuzzy, no-c-format msgid "TODO: Include details on adding a second DRBD resource" msgstr "Include detalii despre adăugarea unei resurse secundare DRBD" #. Tag: para #, no-c-format msgid "Now that DRBD is functioning we can configure a Filesystem resource to use it. In addition to the filesystem’s definition, we also need to tell the cluster where it can be located (only on the DRBD Primary) and when it is allowed to start (after the Primary was promoted)." msgstr "Acum că DRBD funcționează putem configura o resursă Filesystem pentru a îl folosi. Suplimentar față de definiția sistemului de fișiere, trebuie să spunem clusterului de asemenea unde poate fi plasată (doar pe DRBD-ul Primar) și când îi este permis să pornească (după ce nodul a fost promovat la acest rol - Primar)." #. Tag: para #, no-c-format msgid "We are going to take a shortcut when creating the resource this time though. Instead of explicitly saying we want the ocf:heartbeat:Filesystem script, we are only going to ask for Filesystem. We can do this because we know there is only one resource script named Filesystem available to pacemaker, and that pcs is smart enough to fill in the ocf:heartbeat portion for us correctly in the configuration. If there were multiple Filesystem scripts from different ocf providers, we would need to specify the exact one we wanted to use." msgstr "" #. Tag: para #, no-c-format msgid "Once again we will queue up our changes to a file and then push the new configuration to the cluster as the final step." msgstr "" #. Tag: screen #, no-c-format msgid "" "# pcs cluster cib fs_cfg\n" "# pcs -f fs_cfg resource create WebFS Filesystem \\\n" " device=\"/dev/drbd/by-res/wwwdata\" directory=\"/var/www/html\" \\\n" " fstype=\"ext4\"" msgstr "" #. Tag: programlisting #, no-c-format msgid "" "# pcs -f fs_cfg constraint colocation add WebFS WebDataClone INFINITY with-rsc-role=Master\n" "# pcs -f fs_cfg constraint order promote WebDataClone then start WebFS\n" "Adding WebDataClone WebFS (kind: Mandatory) (Options: first-action=promote then-action=start)" msgstr "" #. Tag: para #, no-c-format msgid "We also need to tell the cluster that Apache needs to run on the same machine as the filesystem and that it must be active before Apache can start." msgstr "Trebuie să spunem clusterului de asemenea că Apache are nevoie să ruleze pe aceeași mașină ca și sistemul de fișiere și că trebuie să fie activ înainte ca Apache să pornească." #. Tag: programlisting #, no-c-format msgid "" "# pcs -f fs_cfg constraint colocation add WebSite WebFS INFINITY\n" "# pcs -f fs_cfg constraint order WebFS then WebSite" msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "Now review the updated configuration." msgstr "E timpul să revizuim configurația actualizată:" #. Tag: programlisting #, no-c-format msgid "" "# pcs -f fs_cfg constraint\n" "Location Constraints:\n" "Ordering Constraints:\n" " start ClusterIP then start WebSite\n" " WebFS then WebSite\n" " promote WebDataClone then start WebFS\n" "Colocation Constraints:\n" " WebSite with ClusterIP\n" " WebFS with WebDataClone (with-rsc-role:Master)\n" " WebSite with WebFS\n" "\n" "# pcs -f fs_cfg resource show\n" " ClusterIP (ocf::heartbeat:IPaddr2) Started\n" " WebSite (ocf::heartbeat:apache) Started\n" " Master/Slave Set: WebDataClone [WebData]\n" " Masters: [ pcmk-1 ]\n" " Slaves: [ pcmk-2 ]\n" " WebFS (ocf::heartbeat:Filesystem) Stopped" msgstr "" #. Tag: para #, no-c-format msgid "After reviewing the new configuration, we again upload it and watch the cluster put it into effect." msgstr "După ce am revizuit configurația nouă, o încărcăm din nou și urmărim clusterul cum o pune în folosință." #. Tag: programlisting #, fuzzy, no-c-format msgid "" "# pcs cluster push cib fs_cfg\n" "CIB updated\n" "# pcs status\n" " Last updated: Fri Aug 10 12:47:01 2012\n" "\n" " Last change: Fri Aug 10 12:46:55 2012 via cibadmin on pcmk-1\n" " Stack: corosync\n" " Current DC: pcmk-1 (1) - partition with quorum\n" " Version: 1.1.8-1.el7-60a19ed12fdb4d5c6a6b6767f52e5391e447fec0\n" " 2 Nodes configured, unknown expected votes\n" " 5 Resources configured.\n" "\n" "Online: [ pcmk-1 pcmk-2 ]\n" "\n" "Full list of resources:\n" "\n" " ClusterIP (ocf::heartbeat:IPaddr2): Started pcmk-1\n" " WebSite (ocf::heartbeat:apache): Started pcmk-1\n" " Master/Slave Set: WebDataClone [WebData]\n" " Masters: [ pcmk-1 ]\n" " Slaves: [ pcmk-2 ]\n" " WebFS (ocf::heartbeat:Filesystem): Started pcmk-1" msgstr "" "\n" "[root@pcmk-1 ~]# crm node online\n" "[root@pcmk-1 ~]# crm_mon\n" "============\n" "Last updated: Tue Sep  1 10:13:25 2009\n" "Stack: openais\n" "Current DC: pcmk-1 - partition with quorum\n" "Version: 1.1.5-bdd89e69ba545404d02445be1f3d72e6a203ba2f\n" "2 Nodes configured, 2 expected votes\n" "4 Resources configured.\n" "============\n" "\n" "Online: [ pcmk-1 pcmk-2 ]\n" "\n" "ClusterIP        (ocf::heartbeat:IPaddr):        Started pcmk-2\n" "WebSite (ocf::heartbeat:apache):        Started pcmk-2\n" "Master/Slave Set: WebDataClone\n" "        Masters: [ pcmk-2 ]\n" "        Slaves: [ pcmk-1 ]\n" "WebFS   (ocf::heartbeat:Filesystem):    Started pcmk-2\n" " " #. Tag: title #, no-c-format msgid "Testing Migration" msgstr "Testarea Migrării" #. Tag: para #, fuzzy, no-c-format msgid "We could shut down the active node again, but another way to safely simulate recovery is to put the node into what is called \"standby mode\". Nodes in this state tell the cluster that they are not allowed to run resources. Any resources found active there will be moved elsewhere. This feature can be particularly useful when updating the resources' packages." msgstr "Am putea opri nodul activ din nou, dar o altă cale sigură de a simula recuperarea este de a pune nodul în ceea ce este numit \"mod standby\". Nodurile în această stare spun clusterului că nu li se permite să ruleze resurse. Orice resursă gasită ca fiind activă acolo va fi mutată în altă parte Această funcționalitate poate fi deosebit de utilă atunci când actualizați pachetele resurselor." #. Tag: para #, no-c-format msgid "Put the local node into standby mode and observe the cluster move all the resources to the other node. Note also that the node’s status will change to indicate that it can no longer host resources." msgstr "Puneți nodul local în mod standby și observați cum clusterul mută toate resursele pe nodul celălalt. Observați de asemenea că status-ul nodului se va schimba pentru a indica faptul că nu mai poate găzdui resurse." #. Tag: programlisting #, fuzzy, no-c-format msgid "" "# pcs cluster standby pcmk-1\n" "# pcs status\n" "\n" "Last updated: Fri Sep 14 12:41:12 2012\n" "Last change: Fri Sep 14 12:41:08 2012 via crm_attribute on pcmk-1\n" "Stack: corosync\n" "Current DC: pcmk-1 (1) - partition with quorum\n" "Version: 1.1.8-1.el7-60a19ed12fdb4d5c6a6b6767f52e5391e447fec0\n" "2 Nodes configured, unknown expected votes\n" "5 Resources configured.\n" "\n" "Node pcmk-1 (1): standby\n" "Online: [ pcmk-2 ]\n" "\n" "Full list of resources:\n" "\n" "ClusterIP (ocf::heartbeat:IPaddr2): Started pcmk-2\n" "WebSite (ocf::heartbeat:apache): Started pcmk-2\n" " Master/Slave Set: WebDataClone [WebData]\n" " Masters: [ pcmk-2 ]\n" " Stopped: [ WebData:1 ]\n" "WebFS (ocf::heartbeat:Filesystem): Started pcmk-2" msgstr "" "\n" "[root@pcmk-1 ~]# crm node online\n" "[root@pcmk-1 ~]# crm_mon\n" "============\n" "Last updated: Tue Sep  1 10:13:25 2009\n" "Stack: openais\n" "Current DC: pcmk-1 - partition with quorum\n" "Version: 1.1.5-bdd89e69ba545404d02445be1f3d72e6a203ba2f\n" "2 Nodes configured, 2 expected votes\n" "4 Resources configured.\n" "============\n" "\n" "Online: [ pcmk-1 pcmk-2 ]\n" "\n" "ClusterIP        (ocf::heartbeat:IPaddr):        Started pcmk-2\n" "WebSite (ocf::heartbeat:apache):        Started pcmk-2\n" "Master/Slave Set: WebDataClone\n" "        Masters: [ pcmk-2 ]\n" "        Slaves: [ pcmk-1 ]\n" "WebFS   (ocf::heartbeat:Filesystem):    Started pcmk-2\n" " " #. Tag: para #, no-c-format msgid "Once we’ve done everything we needed to on pcmk-1 (in this case nothing, we just wanted to see the resources move), we can allow the node to be a full cluster member again." msgstr "Odată ce am făcut tot ceea ce era nevoie să facem pe pcmk-1 (în acest caz nimic, vroiam doar să vedem resursele mutându-se), putem permite nodului să fie din nou un membru întreg al clusterului." #. Tag: programlisting #, fuzzy, no-c-format msgid "" "# pcs cluster unstandby pcmk-1\n" "# pcs status\n" "\n" "Last updated: Fri Sep 14 12:43:02 2012\n" "Last change: Fri Sep 14 12:42:57 2012 via crm_attribute on pcmk-1\n" "Stack: corosync\n" "Current DC: pcmk-1 (1) - partition with quorum\n" "Version: 1.1.8-1.el7-60a19ed12fdb4d5c6a6b6767f52e5391e447fec0\n" "2 Nodes configured, unknown expected votes\n" "5 Resources configured.\n" "\n" "Online: [ pcmk-1 pcmk-2 ]\n" "\n" "Full list of resources:\n" "\n" " ClusterIP (ocf::heartbeat:IPaddr2): Started pcmk-2\n" " WebSite (ocf::heartbeat:apache): Started pcmk-2\n" " Master/Slave Set: WebDataClone [WebData]\n" " Masters: [ pcmk-2 ]\n" " Slaves: [ pcmk-1 ]\n" " WebFS (ocf::heartbeat:Filesystem): Started pcmk-2" msgstr "" "\n" "[root@pcmk-1 ~]# crm node online\n" "[root@pcmk-1 ~]# crm_mon\n" "============\n" "Last updated: Tue Sep  1 10:13:25 2009\n" "Stack: openais\n" "Current DC: pcmk-1 - partition with quorum\n" "Version: 1.1.5-bdd89e69ba545404d02445be1f3d72e6a203ba2f\n" "2 Nodes configured, 2 expected votes\n" "4 Resources configured.\n" "============\n" "\n" "Online: [ pcmk-1 pcmk-2 ]\n" "\n" "ClusterIP        (ocf::heartbeat:IPaddr):        Started pcmk-2\n" "WebSite (ocf::heartbeat:apache):        Started pcmk-2\n" "Master/Slave Set: WebDataClone\n" "        Masters: [ pcmk-2 ]\n" "        Slaves: [ pcmk-1 ]\n" "WebFS   (ocf::heartbeat:Filesystem):    Started pcmk-2\n" " " #. Tag: para #, no-c-format msgid "Notice that our resource stickiness settings prevent the services from migrating back to pcmk-1." msgstr "Observați că setările noastre de adezivitate a resurselor previn serviciile din a migra înapoi pe pcmk-1." #~ msgid "" #~ "\n" #~ "[root@pcmk-1 ~]# lvcreate -n drbd-demo -L 1G VolGroup\n" #~ "  Logical volume \"drbd-demo\" created\n" #~ "[root@pcmk-1 ~]# lvs\n" #~ "  LV        VG       Attr   LSize   Origin Snap%  Move Log Copy%  Convert\n" #~ "  drbd-demo VolGroup -wi-a- 1.00G                                      \n" #~ "  lv_root   VolGroup -wi-ao   7.30G                                      \n" #~ "  lv_swap   VolGroup -wi-ao 500.00M\n" #~ " " #~ msgstr "" #~ "\n" #~ "[root@pcmk-1 ~]# lvcreate -n drbd-demo -L 1G VolGroup\n" #~ "  Logical volume \"drbd-demo\" created\n" #~ "[root@pcmk-1 ~]# lvs\n" #~ "  LV        VG       Attr   LSize   Origin Snap%  Move Log Copy%  Convert\n" #~ "  drbd-demo VolGroup -wi-a- 1.00G                                      \n" #~ "  lv_root   VolGroup -wi-ao   7.30G                                      \n" #~ "  lv_swap   VolGroup -wi-ao 500.00M\n" #~ " " #~ msgid "" #~ "\n" #~ "[root@pcmk-2 ~]# lvs\n" #~ "  LV      VG       Attr   LSize   Origin Snap%  Move Log Copy%  Convert\n" #~ "  lv_root VolGroup -wi-ao   7.30G                                      \n" #~ "  lv_swap VolGroup -wi-ao 500.00M                                      \n" #~ "[root@pcmk-2 ~]# lvcreate -n drbd-demo -L 1G VolGroup\n" #~ "  Logical volume \"drbd-demo\" created\n" #~ "[root@pcmk-2 ~]# lvs\n" #~ "  LV        VG       Attr   LSize   Origin Snap%  Move Log Copy%  Convert\n" #~ "  drbd-demo VolGroup -wi-a- 1.00G                                      \n" #~ "  lv_root   VolGroup -wi-ao   7.30G                                      \n" #~ "  lv_swap   VolGroup -wi-ao 500.00M\n" #~ " " #~ msgstr "" #~ "\n" #~ "[root@pcmk-2 ~]# lvs\n" #~ "  LV      VG       Attr   LSize   Origin Snap%  Move Log Copy%  Convert\n" #~ "  lv_root VolGroup -wi-ao   7.30G                                      \n" #~ "  lv_swap VolGroup -wi-ao 500.00M                                      \n" #~ "[root@pcmk-2 ~]# lvcreate -n drbd-demo -L 1G VolGroup\n" #~ "  Logical volume \"drbd-demo\" created\n" #~ "[root@pcmk-2 ~]# lvs\n" #~ "  LV        VG       Attr   LSize   Origin Snap%  Move Log Copy%  Convert\n" #~ "  drbd-demo VolGroup -wi-a- 1.00G                                      \n" #~ "  lv_root   VolGroup -wi-ao   7.30G                                      \n" #~ "  lv_swap   VolGroup -wi-ao 500.00M\n" #~ " " #~ msgid "" #~ "\n" #~ "[root@pcmk-1 ~]# drbdadm create-md wwwdata\n" #~ "md_offset 12578816\n" #~ "al_offset 12546048\n" #~ "bm_offset 12541952\n" #~ "\n" #~ "Found some data \n" #~ " ==> This might destroy existing data! <==\n" #~ "\n" #~ "Do you want to proceed?\n" #~ "[need to type 'yes' to confirm] yes\n" #~ "\n" #~ "Writing meta data...\n" #~ "initializing activity log\n" #~ "NOT initialized bitmap\n" #~ "New drbd meta data block successfully created.\n" #~ "success\n" #~ " " #~ msgstr "" #~ "\n" #~ "[root@pcmk-1 ~]# drbdadm create-md wwwdata\n" #~ "md_offset 12578816\n" #~ "al_offset 12546048\n" #~ "bm_offset 12541952\n" #~ "\n" #~ "Found some data \n" #~ " ==> This might destroy existing data! <==\n" #~ "\n" #~ "Do you want to proceed?\n" #~ "[need to type 'yes' to confirm] yes\n" #~ "\n" #~ "Writing meta data...\n" #~ "initializing activity log\n" #~ "NOT initialized bitmap\n" #~ "New drbd meta data block successfully created.\n" #~ "success\n" #~ " " #~ msgid "" #~ "\n" #~ "[root@pcmk-1 ~]# modprobe drbd\n" #~ "[root@pcmk-1 ~]# drbdadm up wwwdata\n" #~ "[root@pcmk-1 ~]# cat /proc/drbd\n" #~ "version: 8.3.6 (api:88/proto:86-90)\n" #~ "GIT-hash: f3606c47cc6fcf6b3f086e425cb34af8b7a81bbf build by root@pcmk-1, 2009-12-08 11:22:57\n" #~ "\n" #~ " 1: cs:WFConnection ro:Secondary/Unknown ds:Inconsistent/DUnknown C r----\n" #~ "    ns:0 nr:0 dw:0 dr:0 al:0 bm:0 lo:0 pe:0 ua:0 ap:0 ep:1 wo:b oos:12248\n" #~ "[root@pcmk-1 ~]# \n" #~ "\n" #~ "Repeat on the second node\n" #~ "drbdadm --force create-md wwwdata \n" #~ "modprobe drbd\n" #~ "drbdadm up wwwdata\n" #~ "cat /proc/drbd\n" #~ "[root@pcmk-2 ~]# drbdadm --force create-md wwwdata\n" #~ "Writing meta data...\n" #~ "initializing activity log\n" #~ "NOT initialized bitmap\n" #~ "New drbd meta data block successfully created.\n" #~ "success\n" #~ "[root@pcmk-2 ~]# modprobe drbd\n" #~ "WARNING: Deprecated config file /etc/modprobe.conf, all config files belong into /etc/modprobe.d/.\n" #~ "[root@pcmk-2 ~]# drbdadm up wwwdata\n" #~ "[root@pcmk-2 ~]# cat /proc/drbd\n" #~ "version: 8.3.6 (api:88/proto:86-90)\n" #~ "GIT-hash: f3606c47cc6fcf6b3f086e425cb34af8b7a81bbf build by root@pcmk-1, 2009-12-08 11:22:57\n" #~ "\n" #~ " 1: cs:Connected ro:Secondary/Secondary ds:Inconsistent/Inconsistent C r----\n" #~ "    ns:0 nr:0 dw:0 dr:0 al:0 bm:0 lo:0 pe:0 ua:0 ap:0 ep:1 wo:b oos:12248\n" #~ " " #~ msgstr "" #~ "\n" #~ "[root@pcmk-1 ~]# modprobe drbd\n" #~ "[root@pcmk-1 ~]# drbdadm up wwwdata\n" #~ "[root@pcmk-1 ~]# cat /proc/drbd\n" #~ "version: 8.3.6 (api:88/proto:86-90)\n" #~ "GIT-hash: f3606c47cc6fcf6b3f086e425cb34af8b7a81bbf build by root@pcmk-1, 2009-12-08 11:22:57\n" #~ "\n" #~ " 1: cs:WFConnection ro:Secondary/Unknown ds:Inconsistent/DUnknown C r----\n" #~ "    ns:0 nr:0 dw:0 dr:0 al:0 bm:0 lo:0 pe:0 ua:0 ap:0 ep:1 wo:b oos:12248\n" #~ "[root@pcmk-1 ~]# \n" #~ "\n" #~ "Repeat on the second node\n" #~ "drbdadm --force create-md wwwdata \n" #~ "modprobe drbd\n" #~ "drbdadm up wwwdata\n" #~ "cat /proc/drbd\n" #~ "[root@pcmk-2 ~]# drbdadm --force create-md wwwdata\n" #~ "Writing meta data...\n" #~ "initializing activity log\n" #~ "NOT initialized bitmap\n" #~ "New drbd meta data block successfully created.\n" #~ "success\n" #~ "[root@pcmk-2 ~]# modprobe drbd\n" #~ "WARNING: Deprecated config file /etc/modprobe.conf, all config files belong into /etc/modprobe.d/.\n" #~ "[root@pcmk-2 ~]# drbdadm up wwwdata\n" #~ "[root@pcmk-2 ~]# cat /proc/drbd\n" #~ "version: 8.3.6 (api:88/proto:86-90)\n" #~ "GIT-hash: f3606c47cc6fcf6b3f086e425cb34af8b7a81bbf build by root@pcmk-1, 2009-12-08 11:22:57\n" #~ "\n" #~ " 1: cs:Connected ro:Secondary/Secondary ds:Inconsistent/Inconsistent C r----\n" #~ "    ns:0 nr:0 dw:0 dr:0 al:0 bm:0 lo:0 pe:0 ua:0 ap:0 ep:1 wo:b oos:12248\n" #~ " " #~ msgid "" #~ "\n" #~ "[root@pcmk-1 ~]# drbdadm -- --overwrite-data-of-peer primary wwwdata\n" #~ "[root@pcmk-1 ~]# cat /proc/drbd\n" #~ "version: 8.3.6 (api:88/proto:86-90)\n" #~ "GIT-hash: f3606c47cc6fcf6b3f086e425cb34af8b7a81bbf build by root@pcmk-1, 2009-12-08 11:22:57\n" #~ " 1: cs:SyncSource ro:Primary/Secondary ds:UpToDate/Inconsistent C r----\n" #~ "    ns:2184 nr:0 dw:0 dr:2472 al:0 bm:0 lo:0 pe:0 ua:0 ap:0 ep:1 wo:b oos:10064\n" #~ "        [=====>..............] sync'ed: 33.4% (10064/12248)K\n" #~ "        finish: 0:00:37 speed: 240 (240) K/sec\n" #~ "[root@pcmk-1 ~]# cat /proc/drbd\n" #~ "version: 8.3.6 (api:88/proto:86-90)\n" #~ "GIT-hash: f3606c47cc6fcf6b3f086e425cb34af8b7a81bbf build by root@pcmk-1, 2009-12-08 11:22:57\n" #~ " 1: cs:Connected ro:Primary/Secondary ds:UpToDate/UpToDate C r----\n" #~ "    ns:12248 nr:0 dw:0 dr:12536 al:0 bm:1 lo:0 pe:0 ua:0 ap:0 ep:1 wo:b oos:0\n" #~ " " #~ msgstr "" #~ "\n" #~ "[root@pcmk-1 ~]# drbdadm -- --overwrite-data-of-peer primary wwwdata\n" #~ "[root@pcmk-1 ~]# cat /proc/drbd\n" #~ "version: 8.3.6 (api:88/proto:86-90)\n" #~ "GIT-hash: f3606c47cc6fcf6b3f086e425cb34af8b7a81bbf build by root@pcmk-1, 2009-12-08 11:22:57\n" #~ " 1: cs:SyncSource ro:Primary/Secondary ds:UpToDate/Inconsistent C r----\n" #~ "    ns:2184 nr:0 dw:0 dr:2472 al:0 bm:0 lo:0 pe:0 ua:0 ap:0 ep:1 wo:b oos:10064\n" #~ "        [=====>..............] sync'ed: 33.4% (10064/12248)K\n" #~ "        finish: 0:00:37 speed: 240 (240) K/sec\n" #~ "[root@pcmk-1 ~]# cat /proc/drbd\n" #~ "version: 8.3.6 (api:88/proto:86-90)\n" #~ "GIT-hash: f3606c47cc6fcf6b3f086e425cb34af8b7a81bbf build by root@pcmk-1, 2009-12-08 11:22:57\n" #~ " 1: cs:Connected ro:Primary/Secondary ds:UpToDate/UpToDate C r----\n" #~ "    ns:12248 nr:0 dw:0 dr:12536 al:0 bm:1 lo:0 pe:0 ua:0 ap:0 ep:1 wo:b oos:0\n" #~ " " #~ msgid "" #~ "\n" #~ "[root@pcmk-1 ~]# mkfs.ext4 /dev/drbd1\n" #~ "mke2fs 1.41.4 (27-Jan-2009)\n" #~ "Filesystem label=\n" #~ "OS type: Linux\n" #~ "Block size=1024 (log=0)\n" #~ "Fragment size=1024 (log=0)\n" #~ "3072 inodes, 12248 blocks\n" #~ "612 blocks (5.00%) reserved for the super user\n" #~ "First data block=1\n" #~ "Maximum filesystem blocks=12582912\n" #~ "2 block groups\n" #~ "8192 blocks per group, 8192 fragments per group\n" #~ "1536 inodes per group\n" #~ "Superblock backups stored on blocks: \n" #~ "        8193\n" #~ "\n" #~ "Writing inode tables: done                            \n" #~ "Creating journal (1024 blocks): done\n" #~ "Writing superblocks and filesystem accounting information: done\n" #~ "\n" #~ "This filesystem will be automatically checked every 26 mounts or\n" #~ "180 days, whichever comes first.  Use tune2fs -c or -i to override.\n" #~ "\n" #~ "Now mount the newly created filesystem so we can create our index file\n" #~ "mount /dev/drbd1 /mnt/\n" #~ "cat <<-END >/mnt/index.html\n" #~ "<html>\n" #~ "<body>My Test Site - drbd</body>\n" #~ "</html>\n" #~ "END\n" #~ "umount /dev/drbd1\n" #~ "[root@pcmk-1 ~]# mount /dev/drbd1 /mnt/\n" #~ "[root@pcmk-1 ~]# cat <<-END >/mnt/index.html\n" #~ "> <html>\n" #~ "> <body>My Test Site - drbd</body>\n" #~ "> </html>\n" #~ "> END\n" #~ "[root@pcmk-1 ~]# umount /dev/drbd1\n" #~ " " #~ msgstr "" #~ "\n" #~ "[root@pcmk-1 ~]# mkfs.ext4 /dev/drbd1\n" #~ "mke2fs 1.41.4 (27-Jan-2009)\n" #~ "Filesystem label=\n" #~ "OS type: Linux\n" #~ "Block size=1024 (log=0)\n" #~ "Fragment size=1024 (log=0)\n" #~ "3072 inodes, 12248 blocks\n" #~ "612 blocks (5.00%) reserved for the super user\n" #~ "First data block=1\n" #~ "Maximum filesystem blocks=12582912\n" #~ "2 block groups\n" #~ "8192 blocks per group, 8192 fragments per group\n" #~ "1536 inodes per group\n" #~ "Superblock backups stored on blocks: \n" #~ "        8193\n" #~ "\n" #~ "Writing inode tables: done                            \n" #~ "Creating journal (1024 blocks): done\n" #~ "Writing superblocks and filesystem accounting information: done\n" #~ "\n" #~ "This filesystem will be automatically checked every 26 mounts or\n" #~ "180 days, whichever comes first.  Use tune2fs -c or -i to override.\n" #~ "\n" #~ "Now mount the newly created filesystem so we can create our index file\n" #~ "mount /dev/drbd1 /mnt/\n" #~ "cat <<-END >/mnt/index.html\n" #~ "<html>\n" #~ "<body>My Test Site - drbd</body>\n" #~ "</html>\n" #~ "END\n" #~ "umount /dev/drbd1\n" #~ "[root@pcmk-1 ~]# mount /dev/drbd1 /mnt/\n" #~ "[root@pcmk-1 ~]# cat <<-END >/mnt/index.html\n" #~ "> <html>\n" #~ "> <body>My Test Site - drbd</body>\n" #~ "> </html>\n" #~ "> END\n" #~ "[root@pcmk-1 ~]# umount /dev/drbd1\n" #~ " " #~ msgid "One handy feature of the crm shell is that you can use it in interactive mode to make several changes atomically." #~ msgstr "O funcționalitate utilă a shell-ului crm este aceea că îl puteți folosi în mod interactiv pentru a realiza mai multe modificări în mod atomic." #~ msgid "First we launch the shell. The prompt will change to indicate you’re in interactive mode." #~ msgstr "Întâi lansăm shell-ul. Promptul se va schimba pentru a indica faptul că sunteți în mod interactiv." #~ msgid "" #~ "\n" #~ "[root@pcmk-1 ~]# crm\n" #~ "cib crm(live)#\n" #~ " " #~ msgstr "" #~ "\n" #~ "[root@pcmk-1 ~]# crm\n" #~ "cib crm(live)#\n" #~ " " #~ msgid "Next we must create a working copy of the current configuration. This is where all our changes will go. The cluster will not see any of them until we say it's ok. Notice again how the prompt changes, this time to indicate that we’re no longer looking at the live cluster." #~ msgstr "În continuare trebuie să creăm o copie funcțională a configurației curente. Acesta este locul în care vor merge toate modificările noastre. Clusterul nu va vedea nici una dintre ele până nu spunem noi că este ok. Observați cum promptul se schimbă din nou, de această dată pentru a indica faptul că nu ne mai uităm la clusterul live." #~ msgid "" #~ "\n" #~ "cib crm(live)# cib new drbd\n" #~ "INFO: drbd shadow CIB created\n" #~ "crm(drbd)#\n" #~ " " #~ msgstr "" #~ "\n" #~ "cib crm(live)# cib new drbd\n" #~ "INFO: drbd shadow CIB created\n" #~ "crm(drbd)#\n" #~ " " #~ msgid "Now we can create our DRBD clone and display the revised configuration." #~ msgstr "Acum putem crea clona noastră de DRBD și să listăm configurația revizuită." #~ msgid "" #~ "\n" #~ "crm(drbd)# configure primitive WebData ocf:linbit:drbd params drbd_resource=wwwdata \\\n" #~ "        op monitor interval=60s\n" #~ "crm(drbd)# configure ms WebDataClone WebData meta master-max=1 master-node-max=1 \\\n" #~ "        clone-max=2 clone-node-max=1 notify=true\n" #~ "crm(drbd)# configure show\n" #~ "node pcmk-1\n" #~ "node pcmk-2\n" #~ "primitive WebData ocf:linbit:drbd \\\n" #~ " params drbd_resource=\"wwwdata\" \\\n" #~ " op monitor interval=\"60s\"\n" #~ "primitive WebSite ocf:heartbeat:apache \\\n" #~ "        params configfile=\"/etc/httpd/conf/httpd.conf\" \\\n" #~ "        op monitor interval=\"1min\"\n" #~ "primitive ClusterIP ocf:heartbeat:IPaddr2 \\\n" #~ "        params ip=\"192.168.122.101\" cidr_netmask=\"32\" \\\n" #~ "        op monitor interval=\"30s\"\n" #~ "ms WebDataClone WebData \\\n" #~ " meta master-max=\"1\" master-node-max=\"1\" clone-max=\"2\" clone-node-max=\"1\" notify=\"true\"\n" #~ "location prefer-pcmk-1 WebSite 50: pcmk-1\n" #~ "colocation website-with-ip inf: WebSite ClusterIP\n" #~ "order apache-after-ip inf: ClusterIP WebSite\n" #~ "property $id=\"cib-bootstrap-options\" \\\n" #~ "        dc-version=\"1.1.5-bdd89e69ba545404d02445be1f3d72e6a203ba2f\" \\\n" #~ "        cluster-infrastructure=\"openais\" \\\n" #~ "        expected-quorum-votes=\"2\" \\\n" #~ "        stonith-enabled=\"false\" \\\n" #~ "        no-quorum-policy=\"ignore\"\n" #~ "rsc_defaults $id=\"rsc-options\" \\\n" #~ "        resource-stickiness=\"100\"\n" #~ " " #~ msgstr "" #~ "\n" #~ "crm(drbd)# configure primitive WebData ocf:linbit:drbd params drbd_resource=wwwdata \\\n" #~ "        op monitor interval=60s\n" #~ "crm(drbd)# configure ms WebDataClone WebData meta master-max=1 master-node-max=1 \\\n" #~ "        clone-max=2 clone-node-max=1 notify=true\n" #~ "crm(drbd)# configure show\n" #~ "node pcmk-1\n" #~ "node pcmk-2\n" #~ "primitive WebData ocf:linbit:drbd \\\n" #~ " params drbd_resource=\"wwwdata\" \\\n" #~ " op monitor interval=\"60s\"\n" #~ "primitive WebSite ocf:heartbeat:apache \\\n" #~ "        params configfile=\"/etc/httpd/conf/httpd.conf\" \\\n" #~ "        op monitor interval=\"1min\"\n" #~ "primitive ClusterIP ocf:heartbeat:IPaddr2 \\\n" #~ "        params ip=\"192.168.122.101\" cidr_netmask=\"32\" \\\n" #~ "        op monitor interval=\"30s\"\n" #~ "ms WebDataClone WebData \\\n" #~ " meta master-max=\"1\" master-node-max=\"1\" clone-max=\"2\" clone-node-max=\"1\" notify=\"true\"\n" #~ "location prefer-pcmk-1 WebSite 50: pcmk-1\n" #~ "colocation website-with-ip inf: WebSite ClusterIP\n" #~ "order apache-after-ip inf: ClusterIP WebSite\n" #~ "property $id=\"cib-bootstrap-options\" \\\n" #~ "        dc-version=\"1.1.5-bdd89e69ba545404d02445be1f3d72e6a203ba2f\" \\\n" #~ "        cluster-infrastructure=\"openais\" \\\n" #~ "        expected-quorum-votes=\"2\" \\\n" #~ "        stonith-enabled=\"false\" \\\n" #~ "        no-quorum-policy=\"ignore\"\n" #~ "rsc_defaults $id=\"rsc-options\" \\\n" #~ "        resource-stickiness=\"100\"\n" #~ " " #~ msgid "Once we’re happy with the changes, we can tell the cluster to start using them and use crm_mon to check everything is functioning." #~ msgstr "Odată ce suntem multumiți cu modificările realizate, putem spune clusterului să înceapă să le folosească și vom folosi crm_mon pentru a verifica faptul că totul funcționează." #~ msgid "" #~ "\n" #~ "crm(drbd)# cib commit drbd\n" #~ "INFO: commited 'drbd' shadow CIB to the cluster\n" #~ "crm(drbd)# quit\n" #~ "bye\n" #~ "[root@pcmk-1 ~]# crm_mon\n" #~ "============\n" #~ "Last updated: Tue Sep  1 09:37:13 2009\n" #~ "Stack: openais\n" #~ "Current DC: pcmk-1 - partition with quorum\n" #~ "Version: 1.1.5-bdd89e69ba545404d02445be1f3d72e6a203ba2f\n" #~ "2 Nodes configured, 2 expected votes\n" #~ "3 Resources configured.\n" #~ "============\n" #~ "\n" #~ "Online: [ pcmk-1 pcmk-2 ]\n" #~ "\n" #~ "ClusterIP        (ocf::heartbeat:IPaddr):        Started pcmk-1\n" #~ "WebSite (ocf::heartbeat:apache):        Started pcmk-1\n" #~ "Master/Slave Set: WebDataClone\n" #~ " Masters: [ pcmk-2 ]\n" #~ " Slaves: [ pcmk-1 ]\n" #~ " " #~ msgstr "" #~ "\n" #~ "crm(drbd)# cib commit drbd\n" #~ "INFO: commited 'drbd' shadow CIB to the cluster\n" #~ "crm(drbd)# quit\n" #~ "bye\n" #~ "[root@pcmk-1 ~]# crm_mon\n" #~ "============\n" #~ "Last updated: Tue Sep  1 09:37:13 2009\n" #~ "Stack: openais\n" #~ "Current DC: pcmk-1 - partition with quorum\n" #~ "Version: 1.1.5-bdd89e69ba545404d02445be1f3d72e6a203ba2f\n" #~ "2 Nodes configured, 2 expected votes\n" #~ "3 Resources configured.\n" #~ "============\n" #~ "\n" #~ "Online: [ pcmk-1 pcmk-2 ]\n" #~ "\n" #~ "ClusterIP        (ocf::heartbeat:IPaddr):        Started pcmk-1\n" #~ "WebSite (ocf::heartbeat:apache):        Started pcmk-1\n" #~ "Master/Slave Set: WebDataClone\n" #~ " Masters: [ pcmk-2 ]\n" #~ " Slaves: [ pcmk-1 ]\n" #~ " " #~ msgid "Once again we’ll use the shell’s interactive mode" #~ msgstr "Încă o dată vom folosi modul interactiv al shell-ului" #~ msgid "" #~ "\n" #~ "[root@pcmk-1 ~]# crm\n" #~ "crm(live)# cib new fs\n" #~ "INFO: fs shadow CIB created\n" #~ "crm(fs)# configure primitive WebFS ocf:heartbeat:Filesystem \\\n" #~ "        params device=\"/dev/drbd/by-res/wwwdata\" directory=\"/var/www/html\" fstype=\"ext4\"\n" #~ "crm(fs)# configure colocation fs_on_drbd inf: WebFS WebDataClone:Master\n" #~ "crm(fs)# configure order WebFS-after-WebData inf: WebDataClone:promote WebFS:start\n" #~ " " #~ msgstr "" #~ "\n" #~ "[root@pcmk-1 ~]# crm\n" #~ "crm(live)# cib new fs\n" #~ "INFO: fs shadow CIB created\n" #~ "crm(fs)# configure primitive WebFS ocf:heartbeat:Filesystem \\\n" #~ "        params device=\"/dev/drbd/by-res/wwwdata\" directory=\"/var/www/html\" fstype=\"ext4\"\n" #~ "crm(fs)# configure colocation fs_on_drbd inf: WebFS WebDataClone:Master\n" #~ "crm(fs)# configure order WebFS-after-WebData inf: WebDataClone:promote WebFS:start\n" #~ " " #~ msgid "" #~ "\n" #~ "crm(fs)# configure colocation WebSite-with-WebFS inf: WebSite WebFS\n" #~ "crm(fs)# configure order WebSite-after-WebFS inf: WebFS WebSite\n" #~ " " #~ msgstr "" #~ "\n" #~ "crm(fs)# configure colocation WebSite-with-WebFS inf: WebSite WebFS\n" #~ "crm(fs)# configure order WebSite-after-WebFS inf: WebFS WebSite\n" #~ " " #~ msgid "" #~ "\n" #~ "[root@pcmk-1 ~]# crm configure show\n" #~ "node pcmk-1\n" #~ "node pcmk-2\n" #~ "primitive WebData ocf:linbit:drbd \\\n" #~ "        params drbd_resource=\"wwwdata\" \\\n" #~ "        op monitor interval=\"60s\"\n" #~ "primitive WebFS ocf:heartbeat:Filesystem \\\n" #~ "        params device=\"/dev/drbd/by-res/wwwdata\" directory=\"/var/www/html\" fstype=\"ext4\"\n" #~ "primitive WebSite ocf:heartbeat:apache \\\n" #~ "        params configfile=\"/etc/httpd/conf/httpd.conf\" \\\n" #~ "        op monitor interval=\"1min\"\n" #~ "primitive ClusterIP ocf:heartbeat:IPaddr2 \\\n" #~ "        params ip=\"192.168.122.101\" cidr_netmask=\"32\" \\\n" #~ "        op monitor interval=\"30s\"\n" #~ "ms WebDataClone WebData \\\n" #~ "        meta master-max=\"1\" master-node-max=\"1\" clone-max=\"2\" clone-node-max=\"1\" notify=\"true\"\n" #~ "location prefer-pcmk-1 WebSite 50: pcmk-1\n" #~ "colocation WebSite-with-WebFS inf: WebSite WebFS\n" #~ "colocation fs_on_drbd inf: WebFS WebDataClone:Master\n" #~ "colocation website-with-ip inf: WebSite ClusterIP\n" #~ "order WebFS-after-WebData inf: WebDataClone:promote WebFS:start\n" #~ "order WebSite-after-WebFS inf: WebFS WebSite\n" #~ "order apache-after-ip inf: ClusterIP WebSite\n" #~ "property $id=\"cib-bootstrap-options\" \\\n" #~ "        dc-version=\"1.1.5-bdd89e69ba545404d02445be1f3d72e6a203ba2f\" \\\n" #~ "        cluster-infrastructure=\"openais\" \\\n" #~ "        expected-quorum-votes=\"2\" \\\n" #~ "        stonith-enabled=\"false\" \\\n" #~ "        no-quorum-policy=\"ignore\"\n" #~ "rsc_defaults $id=\"rsc-options\" \\\n" #~ "        resource-stickiness=\"100\"\n" #~ " " #~ msgstr "" #~ "\n" #~ "[root@pcmk-1 ~]# crm configure show\n" #~ "node pcmk-1\n" #~ "node pcmk-2\n" #~ "primitive WebData ocf:linbit:drbd \\\n" #~ "        params drbd_resource=\"wwwdata\" \\\n" #~ "        op monitor interval=\"60s\"\n" #~ "primitive WebFS ocf:heartbeat:Filesystem \\\n" #~ "        params device=\"/dev/drbd/by-res/wwwdata\" directory=\"/var/www/html\" fstype=\"ext4\"\n" #~ "primitive WebSite ocf:heartbeat:apache \\\n" #~ "        params configfile=\"/etc/httpd/conf/httpd.conf\" \\\n" #~ "        op monitor interval=\"1min\"\n" #~ "primitive ClusterIP ocf:heartbeat:IPaddr2 \\\n" #~ "        params ip=\"192.168.122.101\" cidr_netmask=\"32\" \\\n" #~ "        op monitor interval=\"30s\"\n" #~ "ms WebDataClone WebData \\\n" #~ "        meta master-max=\"1\" master-node-max=\"1\" clone-max=\"2\" clone-node-max=\"1\" notify=\"true\"\n" #~ "location prefer-pcmk-1 WebSite 50: pcmk-1\n" #~ "colocation WebSite-with-WebFS inf: WebSite WebFS\n" #~ "colocation fs_on_drbd inf: WebFS WebDataClone:Master\n" #~ "colocation website-with-ip inf: WebSite ClusterIP\n" #~ "order WebFS-after-WebData inf: WebDataClone:promote WebFS:start\n" #~ "order WebSite-after-WebFS inf: WebFS WebSite\n" #~ "order apache-after-ip inf: ClusterIP WebSite\n" #~ "property $id=\"cib-bootstrap-options\" \\\n" #~ "        dc-version=\"1.1.5-bdd89e69ba545404d02445be1f3d72e6a203ba2f\" \\\n" #~ "        cluster-infrastructure=\"openais\" \\\n" #~ "        expected-quorum-votes=\"2\" \\\n" #~ "        stonith-enabled=\"false\" \\\n" #~ "        no-quorum-policy=\"ignore\"\n" #~ "rsc_defaults $id=\"rsc-options\" \\\n" #~ "        resource-stickiness=\"100\"\n" #~ " " #~ msgid "" #~ "\n" #~ "crm(fs)# cib commit fs\n" #~ "INFO: commited 'fs' shadow CIB to the cluster\n" #~ "crm(fs)# quit\n" #~ "bye\n" #~ "[root@pcmk-1 ~]# crm_mon\n" #~ "============\n" #~ "Last updated: Tue Sep  1 10:08:44 2009\n" #~ "Stack: openais\n" #~ "Current DC: pcmk-1 - partition with quorum\n" #~ "Version: 1.1.5-bdd89e69ba545404d02445be1f3d72e6a203ba2f\n" #~ "2 Nodes configured, 2 expected votes\n" #~ "4 Resources configured.\n" #~ "============\n" #~ "\n" #~ "Online: [ pcmk-1 pcmk-2 ]\n" #~ "\n" #~ "ClusterIP        (ocf::heartbeat:IPaddr):        Started pcmk-1\n" #~ "WebSite (ocf::heartbeat:apache): Started pcmk-1\n" #~ "Master/Slave Set: WebDataClone\n" #~ "        Masters: [ pcmk-1 ]\n" #~ "        Slaves: [ pcmk-2 ]\n" #~ "WebFS (ocf::heartbeat:Filesystem): Started pcmk-1\n" #~ " " #~ msgstr "" #~ "\n" #~ "crm(fs)# cib commit fs\n" #~ "INFO: commited 'fs' shadow CIB to the cluster\n" #~ "crm(fs)# quit\n" #~ "bye\n" #~ "[root@pcmk-1 ~]# crm_mon\n" #~ "============\n" #~ "Last updated: Tue Sep  1 10:08:44 2009\n" #~ "Stack: openais\n" #~ "Current DC: pcmk-1 - partition with quorum\n" #~ "Version: 1.1.5-bdd89e69ba545404d02445be1f3d72e6a203ba2f\n" #~ "2 Nodes configured, 2 expected votes\n" #~ "4 Resources configured.\n" #~ "============\n" #~ "\n" #~ "Online: [ pcmk-1 pcmk-2 ]\n" #~ "\n" #~ "ClusterIP        (ocf::heartbeat:IPaddr):        Started pcmk-1\n" #~ "WebSite (ocf::heartbeat:apache): Started pcmk-1\n" #~ "Master/Slave Set: WebDataClone\n" #~ "        Masters: [ pcmk-1 ]\n" #~ "        Slaves: [ pcmk-2 ]\n" #~ "WebFS (ocf::heartbeat:Filesystem): Started pcmk-1\n" #~ " " #~ msgid "" #~ "\n" #~ "[root@pcmk-1 ~]# crm node standby\n" #~ "[root@pcmk-1 ~]# crm_mon\n" #~ "============\n" #~ "Last updated: Tue Sep  1 10:09:57 2009\n" #~ "Stack: openais\n" #~ "Current DC: pcmk-1 - partition with quorum\n" #~ "Version: 1.1.5-bdd89e69ba545404d02445be1f3d72e6a203ba2f\n" #~ "2 Nodes configured, 2 expected votes\n" #~ "4 Resources configured.\n" #~ "============\n" #~ "\n" #~ "Node pcmk-1: standby\n" #~ "Online: [ pcmk-2 ]\n" #~ "\n" #~ "ClusterIP        (ocf::heartbeat:IPaddr):        Started pcmk-2\n" #~ "WebSite (ocf::heartbeat:apache):        Started pcmk-2\n" #~ "Master/Slave Set: WebDataClone\n" #~ "        Masters: [ pcmk-2 ]\n" #~ "        Stopped: [ WebData:1 ]\n" #~ "WebFS   (ocf::heartbeat:Filesystem):    Started pcmk-2\n" #~ " " #~ msgstr "" #~ "\n" #~ "[root@pcmk-1 ~]# crm node standby\n" #~ "[root@pcmk-1 ~]# crm_mon\n" #~ "============\n" #~ "Last updated: Tue Sep  1 10:09:57 2009\n" #~ "Stack: openais\n" #~ "Current DC: pcmk-1 - partition with quorum\n" #~ "Version: 1.1.5-bdd89e69ba545404d02445be1f3d72e6a203ba2f\n" #~ "2 Nodes configured, 2 expected votes\n" #~ "4 Resources configured.\n" #~ "============\n" #~ "\n" #~ "Node pcmk-1: standby\n" #~ "Online: [ pcmk-2 ]\n" #~ "\n" #~ "ClusterIP        (ocf::heartbeat:IPaddr):        Started pcmk-2\n" #~ "WebSite (ocf::heartbeat:apache):        Started pcmk-2\n" #~ "Master/Slave Set: WebDataClone\n" #~ "        Masters: [ pcmk-2 ]\n" #~ "        Stopped: [ WebData:1 ]\n" #~ "WebFS   (ocf::heartbeat:Filesystem):    Started pcmk-2\n" #~ " " pacemaker-master/doc/Clusters_from_Scratch/ro-RO/Ch-Stonith.po000066400000000000000000000644301217637305600246410ustar00rootroot00000000000000# # AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: Clusters from Scratch 1.1\n" "POT-Creation-Date: 2012-10-17T05:19:03\n" "PO-Revision-Date: 2011-11-26 11:16+0200\n" "Last-Translator: Dan Frîncu \n" "Language-Team: None\n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: application/x-publican; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. Tag: title #, no-c-format msgid "Configure STONITH" msgstr "Configurarea STONITH" #. Tag: title #, fuzzy, no-c-format msgid "What Is STONITH" msgstr "De Ce Aveți Nevoie de STONITH" #. Tag: para #, fuzzy, no-c-format msgid "STONITH is an acronym for Shoot-The-Other-Node-In-The-Head and it protects your data from being corrupted by rogue nodes or concurrent access." msgstr "STONITH este un acronim pentru Shoot-The-Other-Node-In-The-Head (împușcă-celălalt-nod-în-cap) şi protejează datele voastre de la a fi corupte de către noduri pribege sau de la acces simultan." #. Tag: para #, fuzzy, no-c-format msgid "Just because a node is unresponsive, this doesn’t mean it isn’t accessing your data. The only way to be 100% sure that your data is safe, is to use STONITH so we can be certain that the node is truly offline, before allowing the data to be accessed from another node." msgstr "Doar pentru că un nod nu mai răspunde, acest lucru nu înseamnă că acesta nu mai accesează datele voastre. Singura metodă de a fi 100% siguri că datele voastre sunt în siguranţă, este să folosiţi STONITH pentru a putea fi siguri că nodul este cu adevărat offline, înainte de a permite datelor să fie accesate de pe alt nod." #. Tag: para #, no-c-format msgid "STONITH also has a role to play in the event that a clustered service cannot be stopped. In this case, the cluster uses STONITH to force the whole node offline, thereby making it safe to start the service elsewhere." msgstr "STONITH mai are un rol pe care îl joacă în cazul în care un serviciu clusterizat nu poate fi oprit. În acest caz, clusterul foloseşte STONITH pentru a forţa întregul nod offline, astfel făcând să fie sigurâ pornirea serviciului în altă parte." #. Tag: title #, no-c-format msgid "What STONITH Device Should You Use" msgstr "Ce Dispozitiv STONITH Ar Trebui Să Folosiţi" #. Tag: para #, no-c-format msgid "It is crucial that the STONITH device can allow the cluster to differentiate between a node failure and a network one." msgstr "Este imperativ ca dispozitivul STONITH să permită clusterului să facă diferenţa între o defecţiune a nodului şi una a reţelei." #. Tag: para #, no-c-format msgid "The biggest mistake people make in choosing a STONITH device is to use remote power switch (such as many on-board IMPI controllers) that shares power with the node it controls. In such cases, the cluster cannot be sure if the node is really offline, or active and suffering from a network fault." msgstr "Cea mai mare greşeală pe care o fac oamenii în alegerea unui dispozitiv STONITH este să folosească un switch de curent cu acces la distanţă (cum ar fi multe controlere IPMI integrate) care partajează curentul cu nodul pe care îl controlează. În astfel de cazuri, clusterul nu poate fi sigur dacă nodul este cu adevărat offline sau inactiv şi suferă din cauza unei probleme de reţea." #. Tag: para #, no-c-format msgid "Likewise, any device that relies on the machine being active (such as SSH-based \"devices\" used during testing) are inappropriate." msgstr "În mod similar, orice dispozitiv care se bazează pe maşină să fie activă (cum ar fi \"dispozitivele\" bazate pe SSH folosite în timpul testării) sunt nepotrivite." #. Tag: title #, no-c-format msgid "Configuring STONITH" msgstr "Configurarea STONITH" #. Tag: para #, fuzzy, no-c-format msgid "Find the correct driver: pcs stonith list" msgstr "Găsiţi driverul corect: stonith_admin --list-installed" #. Tag: para #, no-c-format msgid "Find the parameters associated with the device: pcs stonith describe <agent name>" msgstr "" #. Tag: para #, no-c-format msgid "Create a local config to make changes to pcs cluster cib stonith_cfg" msgstr "" #. Tag: para #, no-c-format msgid "Create the fencing resource using pcs -f stonith_cfg stonith create <stonith_id> <stonith device type> [stonith device options]" msgstr "" #. Tag: para #, no-c-format msgid "Set stonith-enable to true. pcs -f stonith_cfg property set stonith-enabled=true" msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "If the device does not know how to fence nodes based on their uname, you may also need to set the special pcmk_host_map parameter. See man stonithd for details." msgstr "Dacă dispozitivul nu știe cum să evacueze forțat nodurile pe baza uname-ului acestora, ar putea fi nevoie să setați parametrul special pcmk_host_map. Vedeți man stonithd pentru detalii." #. Tag: para #, fuzzy, no-c-format msgid "If the device does not support the list command, you may also need to set the special pcmk_host_list and/or pcmk_host_check parameters. See man stonithd for details." msgstr "Dacă dispozitivul nu suportă comanda list ar putea fi nevoie să setați parametrii speciali pcmk_host_list și/sau pcmk_host_check. Vedeți man stonithd pentru detalii." #. Tag: para #, fuzzy, no-c-format msgid "If the device does not expect the victim to be specified with the port parameter, you may also need to set the special pcmk_host_argument parameter. See man stonithd for details." msgstr "Dacă dispozitivul nu se așteaptă ca victima să fie specificată cu parametrul port, ar putea fi necesar să setați parametrul special pcmk_host_argument. Vedeți man stonithd pentru detalii." #. Tag: para #, no-c-format msgid "Commit the new configuration. pcs cluster push cib stonith_cfg" msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "Once the stonith resource is running, you can test it by executing: stonith_admin --reboot nodename. Although you might want to stop the cluster on that machine first." msgstr "Odată ce resursa stonith rulează, o puteți testa executând: stonith_admin --reboot nodename. Deși ați putea dori să opriți clusterul pe acea mașină mai întâi." #. Tag: title #, no-c-format msgid "Example" msgstr "Exemplu" #. Tag: para #, fuzzy, no-c-format msgid "Assuming we have an chassis containing four nodes and an IPMI device active on 10.0.0.1, then we would chose the fence_ipmilan driver in step 2 and obtain the following list of parameters" msgstr "Presupunând că avem un şasiu conţinând patru noduri şi un dispozitiv IPMI activ pe 10.0.0.1, atunci am alege driverul fence_ipmilan la pasul 2 şi am obţine următoarea listă de parametri" #. Tag: title #, no-c-format msgid "Obtaining a list of STONITH Parameters" msgstr "Obţinerea unei liste de Parametri STONITH" #. Tag: programlisting #, no-c-format msgid "" "# pcs stonith describe fence_ipmilan\n" "Stonith options for: fence_ipmilan\n" " auth: IPMI Lan Auth type (md5, password, or none)\n" " ipaddr: IPMI Lan IP to talk to\n" " passwd: Password (if required) to control power on IPMI device\n" " passwd_script: Script to retrieve password (if required)\n" " lanplus: Use Lanplus\n" " login: Username/Login (if required) to control power on IPMI device\n" " action: Operation to perform. Valid operations: on, off, reboot, status, list, diag, monitor or metadata\n" " timeout: Timeout (sec) for IPMI operation\n" " cipher: Ciphersuite to use (same as ipmitool -C parameter)\n" " method: Method to fence (onoff or cycle)\n" " power_wait: Wait X seconds after on/off operation\n" " delay: Wait X seconds before fencing is started\n" " privlvl: Privilege level on IPMI device\n" " verbose: Verbose mode" msgstr "" #. Tag: para #, no-c-format msgid "from which we would create a STONITH resource fragment that might look like this" msgstr "din care am crea un fragment de resursă STONITH care ar putea arăta aşa" #. Tag: title #, no-c-format msgid "Sample STONITH Resource" msgstr "Exemplu de Resursă STONITH" #. Tag: screen #, no-c-format msgid "" "# pcs cluster cib stonith_cfg\n" "# pcs -f stonith_cfg stonith create impi-fencing fence_ipmilan \\\n" " pcmk_host_list=\"pcmk-1 pcmk-2\" ipaddr=10.0.0.1 login=testuser \\\n" " passwd=acd123 op monitor interval=60s" msgstr "" #. Tag: programlisting #, no-c-format msgid "" "# pcs -f stonith_cfg stonith\n" " impi-fencing (stonith:fence_ipmilan) Stopped" msgstr "" #. Tag: para #, no-c-format msgid "And finally, since we disabled it earlier, we need to re-enable STONITH. At this point we should have the following configuration." msgstr "Și în sfârșit, din moment ce l-am dezactivat mai devreme, trebuie să reactivăm STONITH. În acest punct ar trebui să avem următoarea configurație." #. Tag: programlisting #, no-c-format msgid "" "# pcs -f stonith_cfg property set stonith-enabled=true\n" "# pcs -f stonith_cfg property\n" "dc-version: 1.1.8-1.el7-60a19ed12fdb4d5c6a6b6767f52e5391e447fec0\n" "cluster-infrastructure: corosync\n" "no-quorum-policy: ignore\n" "stonith-enabled: true" msgstr "" #. Tag: para #, no-c-format msgid "Now push the configuration into the cluster." msgstr "" #. Tag: programlisting #, no-c-format msgid "# pcs cluster push cib stonith_cfg" msgstr "" #~ msgid "Since every device is different, the parameters needed to configure it will vary. To find out the parameters associated with the device, run:" #~ msgstr "Din moment ce fiecare dispozitiv este diferit, parametrii necesari să îl configurați vor varia. Pentru a afla parametrii asociaţi dispozitivului, rulaţi:" #~ msgid "stonith_admin --metadata --agent type" #~ msgstr "stonith_admin --metadata --agent type" #~ msgid "The output should be XML formatted text containing additional parameter descriptions. We will endevor to make the output more friendly in a later version." #~ msgstr "Rezultatul de ieşire ar trebui să fie un text formatat XML conţinând descrierile parametrilor adiţionali. Ne vom aventura să facem rezultatul de ieşire mai prietenos într-o versiune ulterioară." #~ msgid "Enter the shell crm" #~ msgstr "Intrați în shell-ul crm" #~ msgid "Create an editable copy of the existing configuration cib new stonith" #~ msgstr "CreațI o copie editabilă a configurației existente cib new stonith" #~ msgid "Create a fencing resource containing a primitive resource with a class of stonith, a type of type and a parameter for each of the values returned in step 2: configure primitive ..." #~ msgstr "Creați o resursă de evacuare forțată conținând o resursă primitivă cu o clasă stonith, de tipul type și un parametru pentru fiecare din valorile returnate la pasul 2: configure primitive ..." #~ msgid "Upload it into the CIB from the shell: cib commit stonith" #~ msgstr "Încărcați în CIB din shell: cib commit stonith" #~ msgid "" #~ "\n" #~ "# stonith_admin --metadata -a fence_ipmilan\n" #~ "\n" #~ "<?xml version=\"1.0\" ?>\n" #~ "<resource-agent name=\"fence_ipmilan\" shortdesc=\"Fence agent for IPMI over LAN\">\n" #~ "<longdesc>\n" #~ "fence_ipmilan is an I/O Fencing agent which can be used with machines controlled by IPMI. This agent calls support software using ipmitool (http://ipmitool.sf.net/).\n" #~ "\n" #~ "To use fence_ipmilan with HP iLO 3 you have to enable lanplus option (lanplus / -P) and increase wait after operation to 4 seconds (power_wait=4 / -T 4)</longdesc>\n" #~ "<parameters>\n" #~ "\t<parameter name=\"auth\" unique=\"1\">\n" #~ "\t\t<getopt mixed=\"-A\" />\n" #~ "\t\t<content type=\"string\" />\n" #~ "\t\t<shortdesc lang=\"en\">IPMI Lan Auth type (md5, password, or none)</shortdesc>\n" #~ "\t</parameter>\n" #~ "\t<parameter name=\"ipaddr\" unique=\"1\">\n" #~ "\t\t<getopt mixed=\"-a\" />\n" #~ "\t\t<content type=\"string\" />\n" #~ "\t\t<shortdesc lang=\"en\">IPMI Lan IP to talk to</shortdesc>\n" #~ "\t</parameter>\n" #~ "\t<parameter name=\"passwd\" unique=\"1\">\n" #~ "\t\t<getopt mixed=\"-p\" />\n" #~ "\t\t<content type=\"string\" />\n" #~ "\t\t<shortdesc lang=\"en\">Password (if required) to control power on IPMI device</shortdesc>\n" #~ "\t</parameter>\n" #~ "\t<parameter name=\"passwd_script\" unique=\"1\">\n" #~ "\t\t<getopt mixed=\"-S\" />\n" #~ "\t\t<content type=\"string\" />\n" #~ "\t\t<shortdesc lang=\"en\">Script to retrieve password (if required)</shortdesc>\n" #~ "\t</parameter>\n" #~ "\t<parameter name=\"lanplus\" unique=\"1\">\n" #~ "\t\t<getopt mixed=\"-P\" />\n" #~ "\t\t<content type=\"boolean\" />\n" #~ "\t\t<shortdesc lang=\"en\">Use Lanplus</shortdesc>\n" #~ "\t</parameter>\n" #~ "\t<parameter name=\"login\" unique=\"1\">\n" #~ "\t\t<getopt mixed=\"-l\" />\n" #~ "\t\t<content type=\"string\" />\n" #~ "\t\t<shortdesc lang=\"en\">Username/Login (if required) to control power on IPMI device</shortdesc>\n" #~ "\t</parameter>\n" #~ "\t<parameter name=\"action\" unique=\"1\">\n" #~ "\t\t<getopt mixed=\"-o\" />\n" #~ "\t\t<content type=\"string\" default=\"reboot\"/>\n" #~ "\t\t<shortdesc lang=\"en\">Operation to perform. Valid operations: on, off, reboot, status, list, diag, monitor or metadata</shortdesc>\n" #~ "\t</parameter>\n" #~ "\t<parameter name=\"timeout\" unique=\"1\">\n" #~ "\t\t<getopt mixed=\"-t\" />\n" #~ "\t\t<content type=\"string\" />\n" #~ "\t\t<shortdesc lang=\"en\">Timeout (sec) for IPMI operation</shortdesc>\n" #~ "\t</parameter>\n" #~ "\t<parameter name=\"cipher\" unique=\"1\">\n" #~ "\t\t<getopt mixed=\"-C\" />\n" #~ "\t\t<content type=\"string\" />\n" #~ "\t\t<shortdesc lang=\"en\">Ciphersuite to use (same as ipmitool -C parameter)</shortdesc>\n" #~ "\t</parameter>\n" #~ "\t<parameter name=\"method\" unique=\"1\">\n" #~ "\t\t<getopt mixed=\"-M\" />\n" #~ "\t\t<content type=\"string\" default=\"onoff\"/>\n" #~ "\t\t<shortdesc lang=\"en\">Method to fence (onoff or cycle)</shortdesc>\n" #~ "\t</parameter>\n" #~ "\t<parameter name=\"power_wait\" unique=\"1\">\n" #~ "\t\t<getopt mixed=\"-T\" />\n" #~ "\t\t<content type=\"string\" default=\"2\"/>\n" #~ "\t\t<shortdesc lang=\"en\">Wait X seconds after on/off operation</shortdesc>\n" #~ "\t</parameter>\n" #~ "\t<parameter name=\"delay\" unique=\"1\">\n" #~ "\t\t<getopt mixed=\"-f\" />\n" #~ "\t\t<content type=\"string\" />\n" #~ "\t\t<shortdesc lang=\"en\">Wait X seconds before fencing is started</shortdesc>\n" #~ "\t</parameter>\n" #~ "\t<parameter name=\"verbose\" unique=\"1\">\n" #~ "\t\t<getopt mixed=\"-v\" />\n" #~ "\t\t<content type=\"boolean\" />\n" #~ "\t\t<shortdesc lang=\"en\">Verbose mode</shortdesc>\n" #~ "\t</parameter>\n" #~ "</parameters>\n" #~ "<actions>\n" #~ "\t<action name=\"on\" />\n" #~ "\t<action name=\"off\" />\n" #~ "\t<action name=\"reboot\" />\n" #~ "\t<action name=\"status\" />\n" #~ "\t<action name=\"diag\" />\n" #~ "\t<action name=\"list\" />\n" #~ "\t<action name=\"monitor\" />\n" #~ "\t<action name=\"metadata\" />\n" #~ "</actions>\n" #~ "</resource-agent>\n" #~ "\t" #~ msgstr "" #~ "\n" #~ "# stonith_admin --metadata -a fence_ipmilan\n" #~ "\n" #~ "<?xml version=\"1.0\" ?>\n" #~ "<resource-agent name=\"fence_ipmilan\" shortdesc=\"Fence agent for IPMI over LAN\">\n" #~ "<longdesc>\n" #~ "fence_ipmilan is an I/O Fencing agent which can be used with machines controlled by IPMI. This agent calls support software using ipmitool (http://ipmitool.sf.net/).\n" #~ "\n" #~ "To use fence_ipmilan with HP iLO 3 you have to enable lanplus option (lanplus / -P) and increase wait after operation to 4 seconds (power_wait=4 / -T 4)</longdesc>\n" #~ "<parameters>\n" #~ "\t<parameter name=\"auth\" unique=\"1\">\n" #~ "\t\t<getopt mixed=\"-A\" />\n" #~ "\t\t<content type=\"string\" />\n" #~ "\t\t<shortdesc lang=\"en\">IPMI Lan Auth type (md5, password, or none)</shortdesc>\n" #~ "\t</parameter>\n" #~ "\t<parameter name=\"ipaddr\" unique=\"1\">\n" #~ "\t\t<getopt mixed=\"-a\" />\n" #~ "\t\t<content type=\"string\" />\n" #~ "\t\t<shortdesc lang=\"en\">IPMI Lan IP to talk to</shortdesc>\n" #~ "\t</parameter>\n" #~ "\t<parameter name=\"passwd\" unique=\"1\">\n" #~ "\t\t<getopt mixed=\"-p\" />\n" #~ "\t\t<content type=\"string\" />\n" #~ "\t\t<shortdesc lang=\"en\">Password (if required) to control power on IPMI device</shortdesc>\n" #~ "\t</parameter>\n" #~ "\t<parameter name=\"passwd_script\" unique=\"1\">\n" #~ "\t\t<getopt mixed=\"-S\" />\n" #~ "\t\t<content type=\"string\" />\n" #~ "\t\t<shortdesc lang=\"en\">Script to retrieve password (if required)</shortdesc>\n" #~ "\t</parameter>\n" #~ "\t<parameter name=\"lanplus\" unique=\"1\">\n" #~ "\t\t<getopt mixed=\"-P\" />\n" #~ "\t\t<content type=\"boolean\" />\n" #~ "\t\t<shortdesc lang=\"en\">Use Lanplus</shortdesc>\n" #~ "\t</parameter>\n" #~ "\t<parameter name=\"login\" unique=\"1\">\n" #~ "\t\t<getopt mixed=\"-l\" />\n" #~ "\t\t<content type=\"string\" />\n" #~ "\t\t<shortdesc lang=\"en\">Username/Login (if required) to control power on IPMI device</shortdesc>\n" #~ "\t</parameter>\n" #~ "\t<parameter name=\"action\" unique=\"1\">\n" #~ "\t\t<getopt mixed=\"-o\" />\n" #~ "\t\t<content type=\"string\" default=\"reboot\"/>\n" #~ "\t\t<shortdesc lang=\"en\">Operation to perform. Valid operations: on, off, reboot, status, list, diag, monitor or metadata</shortdesc>\n" #~ "\t</parameter>\n" #~ "\t<parameter name=\"timeout\" unique=\"1\">\n" #~ "\t\t<getopt mixed=\"-t\" />\n" #~ "\t\t<content type=\"string\" />\n" #~ "\t\t<shortdesc lang=\"en\">Timeout (sec) for IPMI operation</shortdesc>\n" #~ "\t</parameter>\n" #~ "\t<parameter name=\"cipher\" unique=\"1\">\n" #~ "\t\t<getopt mixed=\"-C\" />\n" #~ "\t\t<content type=\"string\" />\n" #~ "\t\t<shortdesc lang=\"en\">Ciphersuite to use (same as ipmitool -C parameter)</shortdesc>\n" #~ "\t</parameter>\n" #~ "\t<parameter name=\"method\" unique=\"1\">\n" #~ "\t\t<getopt mixed=\"-M\" />\n" #~ "\t\t<content type=\"string\" default=\"onoff\"/>\n" #~ "\t\t<shortdesc lang=\"en\">Method to fence (onoff or cycle)</shortdesc>\n" #~ "\t</parameter>\n" #~ "\t<parameter name=\"power_wait\" unique=\"1\">\n" #~ "\t\t<getopt mixed=\"-T\" />\n" #~ "\t\t<content type=\"string\" default=\"2\"/>\n" #~ "\t\t<shortdesc lang=\"en\">Wait X seconds after on/off operation</shortdesc>\n" #~ "\t</parameter>\n" #~ "\t<parameter name=\"delay\" unique=\"1\">\n" #~ "\t\t<getopt mixed=\"-f\" />\n" #~ "\t\t<content type=\"string\" />\n" #~ "\t\t<shortdesc lang=\"en\">Wait X seconds before fencing is started</shortdesc>\n" #~ "\t</parameter>\n" #~ "\t<parameter name=\"verbose\" unique=\"1\">\n" #~ "\t\t<getopt mixed=\"-v\" />\n" #~ "\t\t<content type=\"boolean\" />\n" #~ "\t\t<shortdesc lang=\"en\">Verbose mode</shortdesc>\n" #~ "\t</parameter>\n" #~ "</parameters>\n" #~ "<actions>\n" #~ "\t<action name=\"on\" />\n" #~ "\t<action name=\"off\" />\n" #~ "\t<action name=\"reboot\" />\n" #~ "\t<action name=\"status\" />\n" #~ "\t<action name=\"diag\" />\n" #~ "\t<action name=\"list\" />\n" #~ "\t<action name=\"monitor\" />\n" #~ "\t<action name=\"metadata\" />\n" #~ "</actions>\n" #~ "</resource-agent>\n" #~ "\t" #~ msgid "" #~ "\n" #~ "[root@pcmk-1 ~]# crm \n" #~ "crm(live)# cib new stonith\n" #~ "INFO: stonith shadow CIB created\n" #~ "crm(stonith)# configure primitive impi-fencing stonith::fence_ipmilan \\\n" #~ " params pcmk_host_list=\"pcmk-1 pcmk-2\" ipaddr=10.0.0.1 login=testuser passwd=abc123 \\\n" #~ " op monitor interval=\"60s\"\n" #~ "\t" #~ msgstr "" #~ "\n" #~ "[root@pcmk-1 ~]# crm \n" #~ "crm(live)# cib new stonith\n" #~ "INFO: stonith shadow CIB created\n" #~ "crm(stonith)# configure primitive impi-fencing stonith::fence_ipmilan \\\n" #~ " params pcmk_host_list=\"pcmk-1 pcmk-2\" ipaddr=10.0.0.1 login=testuser passwd=abc123 \\\n" #~ " op monitor interval=\"60s\"\n" #~ "\t" #~ msgid "" #~ "\n" #~ "crm(stonith)# configure property stonith-enabled=\"true\"\n" #~ "crm(stonith)# configure show\n" #~ "node pcmk-1\n" #~ "node pcmk-2\n" #~ "primitive WebData ocf:linbit:drbd \\\n" #~ "        params drbd_resource=\"wwwdata\" \\\n" #~ "        op monitor interval=\"60s\"\n" #~ "primitive WebFS ocf:heartbeat:Filesystem \\\n" #~ "        params device=\"/dev/drbd/by-res/wwwdata\" directory=\"/var/www/html\" fstype=\"gfs2\"\n" #~ "primitive WebSite ocf:heartbeat:apache \\\n" #~ "        params configfile=\"/etc/httpd/conf/httpd.conf\" \\\n" #~ "        op monitor interval=\"1min\"\n" #~ "primitive ClusterIP ocf:heartbeat:IPaddr2 \\\n" #~ "        params ip=\"192.168.122.101\" cidr_netmask=\"32\" clusterip_hash=\"sourceip\" \\\n" #~ "        op monitor interval=\"30s\"\n" #~ "primitive ipmi-fencing stonith::fence_ipmilan \\\n" #~ " params pcmk_host_list=\"pcmk-1 pcmk-2\" ipaddr=10.0.0.1 login=testuser passwd=abc123 \\\n" #~ " op monitor interval=\"60s\"\n" #~ "ms WebDataClone WebData \\\n" #~ "        meta master-max=\"2\" master-node-max=\"1\" clone-max=\"2\" clone-node-max=\"1\" notify=\"true\"\n" #~ "clone WebFSClone WebFS\n" #~ "clone WebIP ClusterIP  \\\n" #~ "        meta globally-unique=\"true\" clone-max=\"2\" clone-node-max=\"2\"\n" #~ "clone WebSiteClone WebSite\n" #~ "colocation WebSite-with-WebFS inf: WebSiteClone WebFSClone\n" #~ "colocation fs_on_drbd inf: WebFSClone WebDataClone:Master\n" #~ "colocation website-with-ip inf: WebSiteClone WebIP\n" #~ "order WebFS-after-WebData inf: WebDataClone:promote WebFSClone:start\n" #~ "order WebSite-after-WebFS inf: WebFSClone WebSiteClone\n" #~ "order apache-after-ip inf: WebIP WebSiteClone\n" #~ "property $id=\"cib-bootstrap-options\" \\\n" #~ "        dc-version=\"1.1.5-bdd89e69ba545404d02445be1f3d72e6a203ba2f\" \\\n" #~ "        cluster-infrastructure=\"openais\" \\\n" #~ "        expected-quorum-votes=\"2\" \\\n" #~ "        stonith-enabled=\"true\" \\\n" #~ "        no-quorum-policy=\"ignore\"\n" #~ "rsc_defaults $id=\"rsc-options\" \\\n" #~ "        resource-stickiness=\"100\"\n" #~ "crm(stonith)# cib commit stonith\n" #~ "INFO: commited 'stonith' shadow CIB to the cluster\n" #~ "crm(stonith)# quit\n" #~ "bye\n" #~ " " #~ msgstr "" #~ "\n" #~ "crm(stonith)# configure property stonith-enabled=\"true\"\n" #~ "crm(stonith)# configure show\n" #~ "node pcmk-1\n" #~ "node pcmk-2\n" #~ "primitive WebData ocf:linbit:drbd \\\n" #~ "        params drbd_resource=\"wwwdata\" \\\n" #~ "        op monitor interval=\"60s\"\n" #~ "primitive WebFS ocf:heartbeat:Filesystem \\\n" #~ "        params device=\"/dev/drbd/by-res/wwwdata\" directory=\"/var/www/html\" fstype=\"gfs2\"\n" #~ "primitive WebSite ocf:heartbeat:apache \\\n" #~ "        params configfile=\"/etc/httpd/conf/httpd.conf\" \\\n" #~ "        op monitor interval=\"1min\"\n" #~ "primitive ClusterIP ocf:heartbeat:IPaddr2 \\\n" #~ "        params ip=\"192.168.122.101\" cidr_netmask=\"32\" clusterip_hash=\"sourceip\" \\\n" #~ "        op monitor interval=\"30s\"\n" #~ "primitive ipmi-fencing stonith::fence_ipmilan \\\n" #~ " params pcmk_host_list=\"pcmk-1 pcmk-2\" ipaddr=10.0.0.1 login=testuser passwd=abc123 \\\n" #~ " op monitor interval=\"60s\"\n" #~ "ms WebDataClone WebData \\\n" #~ "        meta master-max=\"2\" master-node-max=\"1\" clone-max=\"2\" clone-node-max=\"1\" notify=\"true\"\n" #~ "clone WebFSClone WebFS\n" #~ "clone WebIP ClusterIP  \\\n" #~ "        meta globally-unique=\"true\" clone-max=\"2\" clone-node-max=\"2\"\n" #~ "clone WebSiteClone WebSite\n" #~ "colocation WebSite-with-WebFS inf: WebSiteClone WebFSClone\n" #~ "colocation fs_on_drbd inf: WebFSClone WebDataClone:Master\n" #~ "colocation website-with-ip inf: WebSiteClone WebIP\n" #~ "order WebFS-after-WebData inf: WebDataClone:promote WebFSClone:start\n" #~ "order WebSite-after-WebFS inf: WebFSClone WebSiteClone\n" #~ "order apache-after-ip inf: WebIP WebSiteClone\n" #~ "property $id=\"cib-bootstrap-options\" \\\n" #~ "        dc-version=\"1.1.5-bdd89e69ba545404d02445be1f3d72e6a203ba2f\" \\\n" #~ "        cluster-infrastructure=\"openais\" \\\n" #~ "        expected-quorum-votes=\"2\" \\\n" #~ "        stonith-enabled=\"true\" \\\n" #~ "        no-quorum-policy=\"ignore\"\n" #~ "rsc_defaults $id=\"rsc-options\" \\\n" #~ "        resource-stickiness=\"100\"\n" #~ "crm(stonith)# cib commit stonith\n" #~ "INFO: commited 'stonith' shadow CIB to the cluster\n" #~ "crm(stonith)# quit\n" #~ "bye\n" #~ " " pacemaker-master/doc/Clusters_from_Scratch/ro-RO/Ch-Tools.po000066400000000000000000000403271217637305600243100ustar00rootroot00000000000000# # AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: Clusters from Scratch 1.1\n" "POT-Creation-Date: 2012-10-17T05:19:03\n" "PO-Revision-Date: 2011-11-26 11:30+0200\n" "Last-Translator: Dan Frîncu \n" "Language-Team: None\n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: application/x-publican; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. Tag: title #, fuzzy, no-c-format msgid "Pacemaker Tools" msgstr "Folosirea Utilitarelor Pacemaker" #. Tag: title #, no-c-format msgid "Using Pacemaker Tools" msgstr "Folosirea Utilitarelor Pacemaker" #. Tag: para #, no-c-format msgid "In the dark past, configuring Pacemaker required the administrator to read and write XML. In true UNIX style, there were also a number of different commands that specialized in different aspects of querying and updating the cluster." msgstr "În trecutul întunecat, configurarea Pacemaker necesita ca administratorul să citească și să scrie XML. În stilul adevărat UNIX, existau și un număr de comenzi diferite care se specializau în diferitele aspecte ale interogării și actualizării clusterului." #. Tag: para #, no-c-format msgid "All of that has been greatly simplified with the creation of unified command-line shells (and GUIs) that hide all the messy XML scaffolding." msgstr "" #. Tag: para #, no-c-format msgid "These shells take all the individual aspects required for managing and configuring a cluster, and packs them into one simple to use command line tool." msgstr "" #. Tag: para #, no-c-format msgid "They even allow you to queue up several changes at once and commit them atomically." msgstr "" #. Tag: para #, no-c-format msgid "There are currently two command-line shells that people use, pcs and crmsh. This edition of Clusters from Scratch is based on pcs. Start by taking some time to familiarize yourself with what it can do." msgstr "" #. Tag: para #, no-c-format msgid "The two shells share many concepts but the scope, layout and syntax does differ, so make sure you read the version of this guide that corresponds to the software installed on your system." msgstr "" #. Tag: para #, no-c-format msgid "Since pcs has the ability to manage all aspects of the cluster (both corosync and pacemaker), it requires a specific cluster stack to be in use, (corosync 2.0 with votequorum + Pacemaker version >= 1.8)." msgstr "" #. Tag: programlisting #, no-c-format msgid "# pcs" msgstr "" #. Tag: literallayout #, no-c-format msgid "" "Control and configure pacemaker and corosync.\n" "\n" "Options:\n" " -h Display usage and exit\n" " -f file Perform actions on file instead of active CIB\n" "\n" "Commands:\n" " resource Manage cluster resources\n" " cluster Configure cluster options and nodes\n" " stonith Configure fence devices\n" " property Set pacemaker properties\n" " constraint Set resource constraints\n" " status View cluster status" msgstr "" #. Tag: para #, no-c-format msgid "As you can see, the different aspects of cluster management are broken up into categories: resource, cluster, stonith, property, constraint, and status. To discover the functionality available in each of these categories, one can issue the command pcs <category> help. Below is an example of all the options available under the status category." msgstr "" #. Tag: programlisting #, no-c-format msgid "# pcs status help" msgstr "" #. Tag: literallayout #, no-c-format msgid "" "Usage: pcs status [commands]...\n" "View current cluster and resource status\n" "Commands:\n" " status\n" " View all information about the cluster and resources\n" "\n" " status resources\n" " View current status of cluster resources\n" "\n" " status groups\n" " View currently configured groups and their resources\n" "\n" " status cluster\n" " View current cluster status\n" "\n" " status corosync\n" " View current corosync status\n" "\n" " status nodes [corosync]\n" " View current status of nodes from pacemaker, or if corosync is\n" " specified, print nodes currently configured in corosync\n" "\n" " status actions\n" " View failed actions\n" "\n" " status pcsd <node> ...\n" " Show the current status of pcsd on the specified nodes\n" "\n" " status xml\n" " View xml version of status (output from crm_mon -r -1 -X)" msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "Additionally, if you are interested in the Pacemaker version and supported cluster stack(s) available with your current Pacemaker installation, the pacemakerd --features option is available to you." msgstr "Suplimentar, versiunea de Pacemaker și stiva(ele) suportate de cluster sunt disponibile prin opțiunea --version." #. Tag: programlisting #, no-c-format msgid "# pacemakerd --features" msgstr "" #. Tag: screen #, no-c-format msgid "" "Pacemaker 1.1.8 (Build: 434edfa)\n" " Supporting: generated-manpages agent-manpages ascii-docs publican-docs ncurses gcov libqb-logging libqb-ipc lha-fencing upstart systemd heartbeat corosync-native snmp" msgstr "" #. Tag: para #, no-c-format msgid "If the SNMP and/or email options are not listed, then Pacemaker was not built to support them. This may be by the choice of your distribution or the required libraries may not have been available. Please contact whoever supplied you with the packages for more details." msgstr "Dacă opțiunile de SNMP și/sau email nu sunt listate, atunci Pacemaker nu a fost construit pentru a le suporta. Acest lucru s-ar putea întâmpla din alegerea făcută de distribuția folosită sau librăriile necesare ar putea să nu fie disponibile. Vă rugăm să contactați pe oricine v-a furnizat pachetele pentru mai multe detalii." #~ msgid "Since Pacemaker 1.0, this has all changed and we have an integrated, scriptable, cluster shell that hides all the messy XML scaffolding. It even allows you to queue up several changes at once and commit them atomically." #~ msgstr "Începând cu Pacemaker 1.0, acest lucru s-a schimbat și avem un shell de cluster integrat, scriptabil, care ascunde toată schela neordonată de XML. Chiar vă permite să adăugați într-o coadă de așteptare mai multe schimbări și să le aplicați în mod atomic." #~ msgid "Take some time to familiarize yourself with what it can do." #~ msgstr "Luați-vă ceva timp pentru a vă familiariza cu ceea ce poate să facă." #~ msgid "" #~ "\n" #~ "[root@pcmk-1 ~]# crm --help\n" #~ "\n" #~ "usage:\n" #~ "    crm [-D display_type]\n" #~ "    crm [-D display_type] args\n" #~ "    crm [-D display_type] [-f file]\n" #~ "\n" #~ "    Use crm without arguments for an interactive session.\n" #~ "    Supply one or more arguments for a \"single-shot\" use.\n" #~ "    Specify with -f a file which contains a script. Use '-' for\n" #~ "    standard input or use pipe/redirection.\n" #~ "\n" #~ "    crm displays cli format configurations using a color scheme\n" #~ "    and/or in uppercase. Pick one of \"color\" or \"uppercase\", or\n" #~ "    use \"-D color,uppercase\" if you want colorful uppercase.\n" #~ "    Get plain output by \"-D plain\". The default may be set in\n" #~ "    user preferences (options).\n" #~ "\n" #~ "Examples:\n" #~ "\n" #~ "    # crm -f stopapp2.cli\n" #~ "    # crm < stopapp2.cli\n" #~ "    # crm resource stop global_www\n" #~ "    # crm status\n" #~ msgstr "" #~ "\n" #~ "[root@pcmk-1 ~]# crm --help\n" #~ "\n" #~ "usage:\n" #~ "    crm [-D display_type]\n" #~ "    crm [-D display_type] args\n" #~ "    crm [-D display_type] [-f file]\n" #~ "\n" #~ "    Use crm without arguments for an interactive session.\n" #~ "    Supply one or more arguments for a \"single-shot\" use.\n" #~ "    Specify with -f a file which contains a script. Use '-' for\n" #~ "    standard input or use pipe/redirection.\n" #~ "\n" #~ "    crm displays cli format configurations using a color scheme\n" #~ "    and/or in uppercase. Pick one of \"color\" or \"uppercase\", or\n" #~ "    use \"-D color,uppercase\" if you want colorful uppercase.\n" #~ "    Get plain output by \"-D plain\". The default may be set in\n" #~ "    user preferences (options).\n" #~ "\n" #~ "Examples:\n" #~ "\n" #~ "    # crm -f stopapp2.cli\n" #~ "    # crm < stopapp2.cli\n" #~ "    # crm resource stop global_www\n" #~ "    # crm status\n" #~ msgid "The primary tool for monitoring the status of the cluster is crm_mon (also available as crm status). It can be run in a variety of modes and has a number of output options. To find out about any of the tools that come with Pacemaker, simply invoke them with the --help option or consult the included man pages. Both sets of output are created from the tool, and so will always be in sync with each other and the tool itself." #~ msgstr "Utilitarul principal pentru monitorizarea status-ului clusterului este crm_mon (de asemenea disponibil ca și crm status). Poate fi rulat într-o varietate de moduri și are un număr de opțiuni ale rezultatelor de ieșire. Pentru a afla despre oricare dintre utilitarele care vin cu Pacemaker, pur și simplu invocați-le cu opțiunea --help sau consultați paginile de manual incluse. Ambele seturi de rezultate de ieșire sunt create de către utilitar și așa va fi întotdeauna sincronizate una cu cealaltă și cu utilitarul însuși." #~ msgid "" #~ "\n" #~ "[root@pcmk-1 ~]# crm_mon --version\n" #~ "Pacemaker 1.1.5\n" #~ "Written by Andrew Beekhof\n" #~ "[root@pcmk-1 ~]# crm_mon --help\n" #~ "crm_mon - Provides a summary of cluster's current state.\n" #~ "\n" #~ "Outputs varying levels of detail in a number of different formats.\n" #~ "\n" #~ "Usage: crm_mon mode [options]\n" #~ "Options:\n" #~ " -?, --help                 This text\n" #~ " -$, --version             Version information\n" #~ " -V, --verbose             Increase debug output\n" #~ "\n" #~ "Modes:\n" #~ " -h, --as-html=value        Write cluster status to the named file\n" #~ " -w, --web-cgi             Web mode with output suitable for cgi\n" #~ " -s, --simple-status       Display the cluster status once as a simple one line output (suitable for nagios)\n" #~ " -S, --snmp-traps=value    Send SNMP traps to this station\n" #~ " -T, --mail-to=value        Send Mail alerts to this user.  See also --mail-from, --mail-host, --mail-prefix\n" #~ "\n" #~ "Display Options:\n" #~ " -n, --group-by-node       Group resources by node\n" #~ " -r, --inactive             Display inactive resources\n" #~ " -f, --failcounts           Display resource fail counts\n" #~ " -o, --operations           Display resource operation history\n" #~ " -t, --timing-details       Display resource operation history with timing details\n" #~ "\n" #~ "\n" #~ "Additional Options:\n" #~ " -i, --interval=value           Update frequency in seconds\n" #~ " -1, --one-shot                 Display the cluster status once on the console and exit\n" #~ " -N, --disable-ncurses          Disable the use of ncurses\n" #~ " -d, --daemonize                Run in the background as a daemon\n" #~ " -p, --pid-file=value           (Advanced) Daemon pid file location\n" #~ " -F, --mail-from=value          Mail alerts should come from the named user\n" #~ " -H, --mail-host=value          Mail alerts should be sent via the named host\n" #~ " -P, --mail-prefix=value        Subjects for mail alerts should start with this string\n" #~ " -E, --external-agent=value     A program to run when resource operations take place.\n" #~ " -e, --external-recipient=value A recipient for your program (assuming you want the program to send something to someone).\n" #~ "\n" #~ "Examples:\n" #~ "\n" #~ "Display the cluster´s status on the console with updates as they occur:\n" #~ "        # crm_mon\n" #~ "\n" #~ "Display the cluster´s status on the console just once then exit:\n" #~ "        # crm_mon -1\n" #~ "\n" #~ "Display your cluster´s status, group resources by node, and include inactive resources in the list:\n" #~ "        # crm_mon --group-by-node --inactive\n" #~ "\n" #~ "Start crm_mon as a background daemon and have it write the cluster´s status to an HTML file:\n" #~ "        # crm_mon --daemonize --as-html /path/to/docroot/filename.html\n" #~ "\n" #~ "Start crm_mon as a background daemon and have it send email alerts:\n" #~ "        # crm_mon --daemonize --mail-to user@example.com --mail-host mail.example.com\n" #~ "\n" #~ "Start crm_mon as a background daemon and have it send SNMP alerts:\n" #~ "        # crm_mon --daemonize --snmp-traps snmptrapd.example.com\n" #~ "\n" #~ "Report bugs to pacemaker@oss.clusterlabs.org\n" #~ msgstr "" #~ "\n" #~ "[root@pcmk-1 ~]# crm_mon --version\n" #~ "Pacemaker 1.1.5\n" #~ "Written by Andrew Beekhof\n" #~ "[root@pcmk-1 ~]# crm_mon --help\n" #~ "crm_mon - Provides a summary of cluster's current state.\n" #~ "\n" #~ "Outputs varying levels of detail in a number of different formats.\n" #~ "\n" #~ "Usage: crm_mon mode [options]\n" #~ "Options:\n" #~ " -?, --help                 This text\n" #~ " -$, --version             Version information\n" #~ " -V, --verbose             Increase debug output\n" #~ "\n" #~ "Modes:\n" #~ " -h, --as-html=value        Write cluster status to the named file\n" #~ " -w, --web-cgi             Web mode with output suitable for cgi\n" #~ " -s, --simple-status       Display the cluster status once as a simple one line output (suitable for nagios)\n" #~ " -S, --snmp-traps=value    Send SNMP traps to this station\n" #~ " -T, --mail-to=value        Send Mail alerts to this user.  See also --mail-from, --mail-host, --mail-prefix\n" #~ "\n" #~ "Display Options:\n" #~ " -n, --group-by-node       Group resources by node\n" #~ " -r, --inactive             Display inactive resources\n" #~ " -f, --failcounts           Display resource fail counts\n" #~ " -o, --operations           Display resource operation history\n" #~ " -t, --timing-details       Display resource operation history with timing details\n" #~ "\n" #~ "\n" #~ "Additional Options:\n" #~ " -i, --interval=value           Update frequency in seconds\n" #~ " -1, --one-shot                 Display the cluster status once on the console and exit\n" #~ " -N, --disable-ncurses          Disable the use of ncurses\n" #~ " -d, --daemonize                Run in the background as a daemon\n" #~ " -p, --pid-file=value           (Advanced) Daemon pid file location\n" #~ " -F, --mail-from=value          Mail alerts should come from the named user\n" #~ " -H, --mail-host=value          Mail alerts should be sent via the named host\n" #~ " -P, --mail-prefix=value        Subjects for mail alerts should start with this string\n" #~ " -E, --external-agent=value     A program to run when resource operations take place.\n" #~ " -e, --external-recipient=value A recipient for your program (assuming you want the program to send something to someone).\n" #~ "\n" #~ "Examples:\n" #~ "\n" #~ "Display the cluster´s status on the console with updates as they occur:\n" #~ "        # crm_mon\n" #~ "\n" #~ "Display the cluster´s status on the console just once then exit:\n" #~ "        # crm_mon -1\n" #~ "\n" #~ "Display your cluster´s status, group resources by node, and include inactive resources in the list:\n" #~ "        # crm_mon --group-by-node --inactive\n" #~ "\n" #~ "Start crm_mon as a background daemon and have it write the cluster´s status to an HTML file:\n" #~ "        # crm_mon --daemonize --as-html /path/to/docroot/filename.html\n" #~ "\n" #~ "Start crm_mon as a background daemon and have it send email alerts:\n" #~ "        # crm_mon --daemonize --mail-to user@example.com --mail-host mail.example.com\n" #~ "\n" #~ "Start crm_mon as a background daemon and have it send SNMP alerts:\n" #~ "        # crm_mon --daemonize --snmp-traps snmptrapd.example.com\n" #~ "\n" #~ "Report bugs to pacemaker@oss.clusterlabs.org\n" pacemaker-master/doc/Clusters_from_Scratch/ro-RO/Ch-Verification.po000066400000000000000000000506601217637305600256330ustar00rootroot00000000000000# # AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: Clusters from Scratch 1.1\n" "POT-Creation-Date: 2012-10-17T05:19:03\n" "PO-Revision-Date: 2011-11-26 13:57+0200\n" "Last-Translator: Dan Frîncu \n" "Language-Team: None\n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: application/x-publican; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. Tag: title #, no-c-format msgid "Verify Cluster Installation" msgstr "Verificați Instalarea Clusterului" #. Tag: title #, no-c-format msgid "Start the Cluster" msgstr "" #. Tag: para #, no-c-format msgid "Now that corosync is configured, it is time to start the cluster. The command below will start corosync and pacemaker on both nodes in the cluster. If you are issuing the start command from a different node than the one you ran the pcs cluster auth command on earlier, you must authenticate on current node you are logged into before you will be allowed to start the cluster." msgstr "" #. Tag: programlisting #, no-c-format msgid "" "# pcs cluster start --all\n" "pcmk-1: Starting Cluster...\n" "pcmk-2: Starting Cluster..." msgstr "" #. Tag: para #, no-c-format msgid "An alternative to using the pcs cluster startall command is to issue either of the below commands on each node in the cluster by hand." msgstr "" #. Tag: programlisting #, no-c-format msgid "" "# pcs cluster start\n" "Starting Cluster..." msgstr "" #. Tag: para #, no-c-format msgid "or" msgstr "" #. Tag: programlisting #, no-c-format msgid "" "# systemctl start corosync.service\n" "# systemctl start pacemaker.service" msgstr "" #. Tag: title #, no-c-format msgid "Verify Corosync Installation" msgstr "Verificați Instalarea Corosync" #. Tag: para #, no-c-format msgid "The first thing to check is if cluster communication is happy, for that we use corosync-cfgtool." msgstr "" #. Tag: programlisting #, no-c-format msgid "" "# corosync-cfgtool -s\n" "Printing ring status.\n" "Local node ID 1\n" "RING ID 0\n" " id = 192.168.122.101\n" " status = ring 0 active with no faults" msgstr "" #. Tag: para #, no-c-format msgid "We can see here that everything appears normal with our fixed IP address, not a 127.0.0.x loopback address, listed as the id and no faults for the status." msgstr "" #. Tag: para #, no-c-format msgid "If you see something different, you might want to start by checking the node’s network, firewall and selinux configurations." msgstr "" #. Tag: para #, no-c-format msgid "Next we check the membership and quorum APIs:" msgstr "" #. Tag: programlisting #, no-c-format msgid "" "# corosync-cmapctl | grep members\n" "runtime.totem.pg.mrp.srp.members.1.ip (str) = r(0) ip(192.168.122.101)\n" "runtime.totem.pg.mrp.srp.members.1.join_count (u32) = 1\n" "runtime.totem.pg.mrp.srp.members.1.status (str) = joined\n" "runtime.totem.pg.mrp.srp.members.2.ip (str) = r(0) ip(192.168.122.102)\n" "runtime.totem.pg.mrp.srp.members.2.join_count (u32) = 1\n" "runtime.totem.pg.mrp.srp.members.2.status (str) = joined\n" "\n" "# pcs status corosync\n" "Membership information\n" " --------------------------\n" " Nodeid Votes Name\n" " 1 1 pcmk-1\n" " 2 1 pcmk-2" msgstr "" #. Tag: para #, no-c-format msgid "You should see both nodes have joined the cluster." msgstr "" #. Tag: para #, no-c-format msgid "All good!" msgstr "" #. Tag: title #, no-c-format msgid "Verify Pacemaker Installation" msgstr "Verificați Instalarea Pacemaker" #. Tag: para #, fuzzy, no-c-format msgid "Now that we have confirmed that Corosync is functional we can check the rest of the stack. Pacemaker has already been started, so verify the necessary processes are running." msgstr "Acum că am confirmat că este funcțional Corosync putem verifica și restul stivei." #. Tag: programlisting #, no-c-format msgid "" "# ps axf\n" " PID TTY STAT TIME COMMAND\n" " 2 ? S 0:00 [kthreadd]\n" "...lots of processes...\n" "28019 ? Ssl 0:03 /usr/sbin/corosync\n" "28047 ? Ss 0:00 /usr/sbin/pacemakerd -f\n" "28048 ? Ss 0:00 \\_ /usr/libexec/pacemaker/cib\n" "28049 ? Ss 0:00 \\_ /usr/libexec/pacemaker/stonithd\n" "28050 ? Ss 0:00 \\_ /usr/lib64/heartbeat/lrmd\n" "28051 ? Ss 0:00 \\_ /usr/libexec/pacemaker/attrd\n" "28052 ? Ss 0:00 \\_ /usr/libexec/pacemaker/pengine\n" "28053 ? Ss 0:00 \\_ /usr/libexec/pacemaker/crmd" msgstr "" #. Tag: para #, no-c-format msgid "If that looks ok, check the pcs status output." msgstr "" #. Tag: programlisting #, no-c-format msgid "" "# pcs status\n" "Last updated: Fri Sep 14 09:52:25 2012\n" "Last change: Fri Sep 14 09:51:55 2012 via crmd on pcmk-2\n" "Stack: corosync\n" "Current DC: pcmk-2 (2) - partition with quorum\n" "Version: 1.1.8-1.el7-60a19ed12fdb4d5c6a6b6767f52e5391e447fec0\n" "2 Nodes configured, unknown expected votes\n" "0 Resources configured.\n" "\n" "Online: [ pcmk-1 pcmk-2 ]\n" "\n" "Full list of resources:" msgstr "" #. Tag: para #, no-c-format msgid "Next, check for any ERRORs during startup - there shouldn’t be any." msgstr "În continuare, verificați pentru orice mesaje de tip ERROR din timpul pornirii - nu ar trebui să existe nici unul." #. Tag: programlisting #, no-c-format msgid "# grep -i error /var/log/messages" msgstr "" #. Tag: para #, no-c-format msgid "Repeat these checks on the other node. The results should be the same." msgstr "" #~ msgid "Start Corosync on the first node" #~ msgstr "Porniți Corosync pe primul nod" #~ msgid "" #~ "\n" #~ "[root@pcmk-1 ~]# /etc/init.d/corosync start\n" #~ "Starting Corosync Cluster Engine (corosync): [ OK ]\n" #~ msgstr "" #~ "\n" #~ "[root@pcmk-1 ~]# /etc/init.d/corosync start\n" #~ "Starting Corosync Cluster Engine (corosync): [ OK ]\n" #~ msgid "Check the cluster started correctly and that an initial membership was able to form" #~ msgstr "Verificați dacă a pornit corect clusterul și că o apartenență inițială s-a putut forma" #~ msgid "" #~ "\n" #~ "[root@pcmk-1 ~]# grep -e \"corosync.*network interface\" -e \"Corosync Cluster Engine\" \\\n" #~ "-e \"Successfully read main configuration file\" /var/log/messages\n" #~ "Aug 27 09:05:34 pcmk-1 corosync[1540]: [MAIN  ] Corosync Cluster Engine ('1.1.0'): started and ready to provide service.\n" #~ "Aug 27 09:05:34 pcmk-1 corosync[1540]: [MAIN  ] Successfully read main configuration file '/etc/corosync/corosync.conf'.\n" #~ "[root@pcmk-1 ~]# grep TOTEM /var/log/messages\n" #~ "Aug 27 09:05:34 pcmk-1 corosync[1540]: [TOTEM ] Initializing transport (UDP/IP).\n" #~ "Aug 27 09:05:34 pcmk-1 corosync[1540]: [TOTEM ] Initializing transmit/receive security: libtomcrypt SOBER128/SHA1HMAC (mode 0).\n" #~ "Aug 27 09:05:35 pcmk-1 corosync[1540]: [TOTEM ] The network interface [192.168.122.101] is now up.\n" #~ "Aug 27 09:05:35 pcmk-1 corosync[1540]: [TOTEM ] A processor joined or left the membership and a new membership was formed.\n" #~ msgstr "" #~ "\n" #~ "[root@pcmk-1 ~]# grep -e \"corosync.*network interface\" -e \"Corosync Cluster Engine\" \\\n" #~ "-e \"Successfully read main configuration file\" /var/log/messages\n" #~ "Aug 27 09:05:34 pcmk-1 corosync[1540]: [MAIN  ] Corosync Cluster Engine ('1.1.0'): started and ready to provide service.\n" #~ "Aug 27 09:05:34 pcmk-1 corosync[1540]: [MAIN  ] Successfully read main configuration file '/etc/corosync/corosync.conf'.\n" #~ "[root@pcmk-1 ~]# grep TOTEM /var/log/messages\n" #~ "Aug 27 09:05:34 pcmk-1 corosync[1540]: [TOTEM ] Initializing transport (UDP/IP).\n" #~ "Aug 27 09:05:34 pcmk-1 corosync[1540]: [TOTEM ] Initializing transmit/receive security: libtomcrypt SOBER128/SHA1HMAC (mode 0).\n" #~ "Aug 27 09:05:35 pcmk-1 corosync[1540]: [TOTEM ] The network interface [192.168.122.101] is now up.\n" #~ "Aug 27 09:05:35 pcmk-1 corosync[1540]: [TOTEM ] A processor joined or left the membership and a new membership was formed.\n" #~ msgid "With one node functional, it's now safe to start Corosync on the second node as well." #~ msgstr "Cu un nod funcțional, este acum în siguranță să pornim Corosync de asemenea pe al doilea nod." #~ msgid "" #~ "\n" #~ "[root@pcmk-1 ~]# ssh pcmk-2 -- /etc/init.d/corosync start\n" #~ "Starting Corosync Cluster Engine (corosync): [ OK ]\n" #~ "[root@pcmk-1 ~]#\n" #~ msgstr "" #~ "\n" #~ "[root@pcmk-1 ~]# ssh pcmk-2 -- /etc/init.d/corosync start\n" #~ "Starting Corosync Cluster Engine (corosync): [ OK ]\n" #~ "[root@pcmk-1 ~]#\n" #~ msgid "Check the cluster formed correctly" #~ msgstr "Verificați dacă s-a format corect clusterul" #~ msgid "" #~ "\n" #~ "[root@pcmk-1 ~]# grep TOTEM /var/log/messages\n" #~ "Aug 27 09:05:34 pcmk-1 corosync[1540]: [TOTEM ] Initializing transport (UDP/IP).\n" #~ "Aug 27 09:05:34 pcmk-1 corosync[1540]: [TOTEM ] Initializing transmit/receive security: libtomcrypt SOBER128/SHA1HMAC (mode 0).\n" #~ "Aug 27 09:05:35 pcmk-1 corosync[1540]: [TOTEM ] The network interface [192.168.122.101] is now up.\n" #~ "Aug 27 09:05:35 pcmk-1 corosync[1540]: [TOTEM ] A processor joined or left the membership and a new membership was formed.\n" #~ "Aug 27 09:12:11 pcmk-1 corosync[1540]: [TOTEM ] A processor joined or left the membership and a new membership was formed.\n" #~ msgstr "" #~ "\n" #~ "[root@pcmk-1 ~]# grep TOTEM /var/log/messages\n" #~ "Aug 27 09:05:34 pcmk-1 corosync[1540]: [TOTEM ] Initializing transport (UDP/IP).\n" #~ "Aug 27 09:05:34 pcmk-1 corosync[1540]: [TOTEM ] Initializing transmit/receive security: libtomcrypt SOBER128/SHA1HMAC (mode 0).\n" #~ "Aug 27 09:05:35 pcmk-1 corosync[1540]: [TOTEM ] The network interface [192.168.122.101] is now up.\n" #~ "Aug 27 09:05:35 pcmk-1 corosync[1540]: [TOTEM ] A processor joined or left the membership and a new membership was formed.\n" #~ "Aug 27 09:12:11 pcmk-1 corosync[1540]: [TOTEM ] A processor joined or left the membership and a new membership was formed.\n" #~ msgid "" #~ "\n" #~ "[root@pcmk-1 ~]# grep pcmk_startup /var/log/messages\n" #~ "Aug 27 09:05:35 pcmk-1 corosync[1540]:   [pcmk  ] info: pcmk_startup: CRM: Initialized\n" #~ "Aug 27 09:05:35 pcmk-1 corosync[1540]:   [pcmk  ] Logging: Initialized pcmk_startup\n" #~ "Aug 27 09:05:35 pcmk-1 corosync[1540]:   [pcmk  ] info: pcmk_startup: Maximum core file size is: 18446744073709551615\n" #~ "Aug 27 09:05:35 pcmk-1 corosync[1540]:   [pcmk  ] info: pcmk_startup: Service: 9\n" #~ "Aug 27 09:05:35 pcmk-1 corosync[1540]:   [pcmk  ] info: pcmk_startup: Local hostname: pcmk-1\n" #~ msgstr "" #~ "\n" #~ "[root@pcmk-1 ~]# grep pcmk_startup /var/log/messages\n" #~ "Aug 27 09:05:35 pcmk-1 corosync[1540]:   [pcmk  ] info: pcmk_startup: CRM: Initialized\n" #~ "Aug 27 09:05:35 pcmk-1 corosync[1540]:   [pcmk  ] Logging: Initialized pcmk_startup\n" #~ "Aug 27 09:05:35 pcmk-1 corosync[1540]:   [pcmk  ] info: pcmk_startup: Maximum core file size is: 18446744073709551615\n" #~ "Aug 27 09:05:35 pcmk-1 corosync[1540]:   [pcmk  ] info: pcmk_startup: Service: 9\n" #~ "Aug 27 09:05:35 pcmk-1 corosync[1540]:   [pcmk  ] info: pcmk_startup: Local hostname: pcmk-1\n" #~ msgid "Now try starting Pacemaker and check the necessary processes have been started" #~ msgstr "Acum încercați să porniți Pacemaker și verificați că procesele necesare au fost pornite" #~ msgid "" #~ "\n" #~ "[root@pcmk-1 ~]# /etc/init.d/pacemaker start\n" #~ "Starting Pacemaker Cluster Manager: [ OK ]\n" #~ "\t\t" #~ msgstr "" #~ "\n" #~ "[root@pcmk-1 ~]# /etc/init.d/pacemaker start\n" #~ "Starting Pacemaker Cluster Manager: [ OK ]\n" #~ "\t\t" #~ msgid "" #~ "\n" #~ "[root@pcmk-1 ~]# grep -e pacemakerd.*get_config_opt -e pacemakerd.*start_child \\\n" #~ "-e \"Starting Pacemaker\" /var/log/messages\n" #~ "Feb 8 13:31:24 pcmk-1 pacemakerd: [13155]: info: get_config_opt: Found 'pacemaker' for option: name\n" #~ "Feb 8 13:31:24 pcmk-1 pacemakerd: [13155]: info: get_config_opt: Found '1' for option: ver\n" #~ "Feb 8 13:31:24 pcmk-1 pacemakerd: [13155]: info: get_config_opt: Defaulting to 'no' for option: use_logd\n" #~ "Feb 8 13:31:24 pcmk-1 pacemakerd: [13155]: info: get_config_opt: Defaulting to 'no' for option: use_mgmtd\n" #~ "Feb 8 13:31:24 pcmk-1 pacemakerd: [13155]: info: get_config_opt: Found 'on' for option: debug\n" #~ "Feb 8 13:31:24 pcmk-1 pacemakerd: [13155]: info: get_config_opt: Found 'yes' for option: to_logfile\n" #~ "Feb 8 13:31:24 pcmk-1 pacemakerd: [13155]: info: get_config_opt: Found '/var/log/corosync.log' for option: logfile\n" #~ "Feb 8 13:31:24 pcmk-1 pacemakerd: [13155]: info: get_config_opt: Found 'yes' for option: to_syslog\n" #~ "Feb 8 13:31:24 pcmk-1 pacemakerd: [13155]: info: get_config_opt: Found 'daemon' for option: syslog_facility\n" #~ "Feb 8 16:50:38 pcmk-1 pacemakerd: [13990]: info: main: Starting Pacemaker 1.1.5 (Build: 31f088949239+): docbook-manpages publican ncurses trace-logging cman cs-quorum heartbeat corosync snmp libesmtp\n" #~ "Feb 8 16:50:38 pcmk-1 pacemakerd: [13990]: info: start_child: Forked child 14022 for process stonith-ng\n" #~ "Feb 8 16:50:38 pcmk-1 pacemakerd: [13990]: info: start_child: Forked child 14023 for process cib\n" #~ "Feb 8 16:50:38 pcmk-1 pacemakerd: [13990]: info: start_child: Forked child 14024 for process lrmd\n" #~ "Feb 8 16:50:38 pcmk-1 pacemakerd: [13990]: info: start_child: Forked child 14025 for process attrd\n" #~ "Feb 8 16:50:38 pcmk-1 pacemakerd: [13990]: info: start_child: Forked child 14026 for process pengine\n" #~ "Feb 8 16:50:38 pcmk-1 pacemakerd: [13990]: info: start_child: Forked child 14027 for process crmd\n" #~ msgstr "" #~ "\n" #~ "[root@pcmk-1 ~]# grep -e pacemakerd.*get_config_opt -e pacemakerd.*start_child \\\n" #~ "-e \"Starting Pacemaker\" /var/log/messages\n" #~ "Feb 8 13:31:24 pcmk-1 pacemakerd: [13155]: info: get_config_opt: Found 'pacemaker' for option: name\n" #~ "Feb 8 13:31:24 pcmk-1 pacemakerd: [13155]: info: get_config_opt: Found '1' for option: ver\n" #~ "Feb 8 13:31:24 pcmk-1 pacemakerd: [13155]: info: get_config_opt: Defaulting to 'no' for option: use_logd\n" #~ "Feb 8 13:31:24 pcmk-1 pacemakerd: [13155]: info: get_config_opt: Defaulting to 'no' for option: use_mgmtd\n" #~ "Feb 8 13:31:24 pcmk-1 pacemakerd: [13155]: info: get_config_opt: Found 'on' for option: debug\n" #~ "Feb 8 13:31:24 pcmk-1 pacemakerd: [13155]: info: get_config_opt: Found 'yes' for option: to_logfile\n" #~ "Feb 8 13:31:24 pcmk-1 pacemakerd: [13155]: info: get_config_opt: Found '/var/log/corosync.log' for option: logfile\n" #~ "Feb 8 13:31:24 pcmk-1 pacemakerd: [13155]: info: get_config_opt: Found 'yes' for option: to_syslog\n" #~ "Feb 8 13:31:24 pcmk-1 pacemakerd: [13155]: info: get_config_opt: Found 'daemon' for option: syslog_facility\n" #~ "Feb 8 16:50:38 pcmk-1 pacemakerd: [13990]: info: main: Starting Pacemaker 1.1.5 (Build: 31f088949239+): docbook-manpages publican ncurses trace-logging cman cs-quorum heartbeat corosync snmp libesmtp\n" #~ "Feb 8 16:50:38 pcmk-1 pacemakerd: [13990]: info: start_child: Forked child 14022 for process stonith-ng\n" #~ "Feb 8 16:50:38 pcmk-1 pacemakerd: [13990]: info: start_child: Forked child 14023 for process cib\n" #~ "Feb 8 16:50:38 pcmk-1 pacemakerd: [13990]: info: start_child: Forked child 14024 for process lrmd\n" #~ "Feb 8 16:50:38 pcmk-1 pacemakerd: [13990]: info: start_child: Forked child 14025 for process attrd\n" #~ "Feb 8 16:50:38 pcmk-1 pacemakerd: [13990]: info: start_child: Forked child 14026 for process pengine\n" #~ "Feb 8 16:50:38 pcmk-1 pacemakerd: [13990]: info: start_child: Forked child 14027 for process crmd\n" #~ msgid "" #~ "\n" #~ "[root@pcmk-1 ~]# ps axf\n" #~ "  PID TTY      STAT   TIME COMMAND\n" #~ "    2 ?        S<     0:00 [kthreadd]\n" #~ "    3 ?        S<     0:00  \\_ [migration/0]\n" #~ "... lots of processes ...\n" #~ " 13990 ?    S      0:01 pacemakerd\n" #~ " 14022 ?    Sa      0:00  \\_ /usr/lib64/heartbeat/stonithd\n" #~ " 14023 ?    Sa      0:00  \\_ /usr/lib64/heartbeat/cib\n" #~ " 14024 ?    Sa      0:00  \\_ /usr/lib64/heartbeat/lrmd\n" #~ " 14025 ?    Sa      0:00  \\_ /usr/lib64/heartbeat/attrd\n" #~ " 14026 ?    Sa      0:00  \\_ /usr/lib64/heartbeat/pengine\n" #~ " 14027 ?    Sa      0:00  \\_ /usr/lib64/heartbeat/crmd\n" #~ msgstr "" #~ "\n" #~ "[root@pcmk-1 ~]# ps axf\n" #~ "  PID TTY      STAT   TIME COMMAND\n" #~ "    2 ?        S<     0:00 [kthreadd]\n" #~ "    3 ?        S<     0:00  \\_ [migration/0]\n" #~ "... lots of processes ...\n" #~ " 13990 ?    S      0:01 pacemakerd\n" #~ " 14022 ?    Sa      0:00  \\_ /usr/lib64/heartbeat/stonithd\n" #~ " 14023 ?    Sa      0:00  \\_ /usr/lib64/heartbeat/cib\n" #~ " 14024 ?    Sa      0:00  \\_ /usr/lib64/heartbeat/lrmd\n" #~ " 14025 ?    Sa      0:00  \\_ /usr/lib64/heartbeat/attrd\n" #~ " 14026 ?    Sa      0:00  \\_ /usr/lib64/heartbeat/pengine\n" #~ " 14027 ?    Sa      0:00  \\_ /usr/lib64/heartbeat/crmd\n" #~ msgid "" #~ "\n" #~ "[root@pcmk-1 ~]# grep ERROR: /var/log/messages | grep -v unpack_resources\n" #~ "[root@pcmk-1 ~]# \n" #~ msgstr "" #~ "\n" #~ "[root@pcmk-1 ~]# grep ERROR: /var/log/messages | grep -v unpack_resources\n" #~ "[root@pcmk-1 ~]# \n" #~ msgid "Repeat on the other node and display the cluster's status." #~ msgstr "Repetați pe nodul celălalt și listați status-ul clusterului." #~ msgid "" #~ "\n" #~ "[root@pcmk-1 ~]# ssh pcmk-2 -- /etc/init.d/pacemaker start\n" #~ "Starting Pacemaker Cluster Manager: [ OK ]\n" #~ "[root@pcmk-1 ~]# crm_mon\n" #~ "============\n" #~ "Last updated: Thu Aug 27 16:54:55 2009\n" #~ "Stack: openais\n" #~ "Current DC: pcmk-1 - partition with quorum\n" #~ "Version: 1.1.5-bdd89e69ba545404d02445be1f3d72e6a203ba2f\n" #~ "2 Nodes configured, 2 expected votes\n" #~ "0 Resources configured.\n" #~ "============\n" #~ "\n" #~ "Online: [ pcmk-1 pcmk-2 ]\n" #~ msgstr "" #~ "\n" #~ "[root@pcmk-1 ~]# ssh pcmk-2 -- /etc/init.d/pacemaker start\n" #~ "Starting Pacemaker Cluster Manager: [ OK ]\n" #~ "[root@pcmk-1 ~]# crm_mon\n" #~ "============\n" #~ "Last updated: Thu Aug 27 16:54:55 2009\n" #~ "Stack: openais\n" #~ "Current DC: pcmk-1 - partition with quorum\n" #~ "Version: 1.1.5-bdd89e69ba545404d02445be1f3d72e6a203ba2f\n" #~ "2 Nodes configured, 2 expected votes\n" #~ "0 Resources configured.\n" #~ "============\n" #~ "\n" #~ "Online: [ pcmk-1 pcmk-2 ]\n" pacemaker-master/doc/Clusters_from_Scratch/ro-RO/Clusters_from_Scratch.po000066400000000000000000000006211217637305600271470ustar00rootroot00000000000000# # AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: Clusters from Scratch 1.1\n" "POT-Creation-Date: 2012-10-17T05:19:03\n" "PO-Revision-Date: 2011-11-24 08:23+0200\n" "Last-Translator: Dan Frîncu \n" "Language-Team: None\n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: application/x-publican; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" pacemaker-master/doc/Clusters_from_Scratch/ro-RO/Preface.po000066400000000000000000000007221217637305600242200ustar00rootroot00000000000000# # AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: Clusters from Scratch 1.1\n" "POT-Creation-Date: 2012-10-17T05:19:03\n" "PO-Revision-Date: 2011-11-26 13:57+0200\n" "Last-Translator: Dan Frîncu \n" "Language-Team: None\n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: application/x-publican; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. Tag: title #, no-c-format msgid "Preface" msgstr "Prefață" pacemaker-master/doc/Clusters_from_Scratch/ro-RO/Revision_History.po000066400000000000000000000025661217637305600262020ustar00rootroot00000000000000# # AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: Clusters from Scratch 1.1\n" "POT-Creation-Date: 2012-10-17T05:19:03\n" "PO-Revision-Date: 2011-11-26 13:59+0200\n" "Last-Translator: Dan Frîncu \n" "Language-Team: None\n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: application/x-publican; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. Tag: title #, no-c-format msgid "Revision History" msgstr "Istoricul Reviziilor" #. Tag: firstname #, no-c-format msgid "Andrew" msgstr "Andrew" #. Tag: surname #, no-c-format msgid "Beekhof" msgstr "Beekhof" #. Tag: member #, no-c-format msgid "Import from Pages.app" msgstr "Import din Pages.app" #. Tag: firstname #, no-c-format msgid "Raoul" msgstr "" #. Tag: surname #, no-c-format msgid "Scarazzini" msgstr "" #. Tag: member #, no-c-format msgid "Italian translation" msgstr "" #. Tag: member #, no-c-format msgid "Updated for Fedora 13" msgstr "" #. Tag: member #, no-c-format msgid "Update the GFS2 section to use CMAN" msgstr "" #. Tag: member #, no-c-format msgid "Generate docbook content from asciidoc sources" msgstr "" #. Tag: member #, no-c-format msgid "Updated for Fedora 17" msgstr "" #. Tag: firstname #, no-c-format msgid "David" msgstr "" #. Tag: surname #, no-c-format msgid "Vossel" msgstr "" #. Tag: member #, no-c-format msgid "Updated for pcs" msgstr "" pacemaker-master/doc/Clusters_from_Scratch/zh-CN/000077500000000000000000000000001217637305600222735ustar00rootroot00000000000000pacemaker-master/doc/Clusters_from_Scratch/zh-CN/Ap-Configuration.mo000066400000000000000000000410671217637305600260050ustar00rootroot00000000000000,|;k 5 #O si|9 F"L?">Q?ZH  ?>p9DQAMA!U!Z!V@"O"P"*8#c#k u$-#-/0|1039345L687?7 R7_7c8v8 88888r83Z:[:; << <<?<>=X=9x>->>0@K@BA6aASA%A$B"+ ' !,* %& $( #)  [root@pcmk-1 ~]# crm configure show node pcmk-1 node pcmk-2 primitive WebData ocf:linbit:drbd \         params drbd_resource="wwwdata" \         op monitor interval="60s" primitive WebFS ocf:heartbeat:Filesystem \         params device="/dev/drbd/by-res/wwwdata" directory="/var/www/html" fstype=”gfs2” primitive WebSite ocf:heartbeat:apache \         params configfile="/etc/httpd/conf/httpd.conf" \         op monitor interval="1min" primitive ClusterIP ocf:heartbeat:IPaddr2 \         params ip=”192.168.122.101” cidr_netmask=”32” clusterip_hash=”sourceip” \         op monitor interval="30s" primitive dlm ocf:pacemaker:controld \         op monitor interval="120s" primitive gfs-control ocf:pacemaker:controld \    params daemon=”gfs_controld.pcmk” args=”-g 0” \         op monitor interval="120s" primitive rsa-fencing stonith::external/ibmrsa \         params hostname=”pcmk-1 pcmk-2" ipaddr=192.168.122.31 userid=mgmt passwd=abc123 type=ibm \         op monitor interval="60s" ms WebDataClone WebData \         meta master-max="2" master-node-max="1" clone-max="2" clone-node-max="1" notify="true" clone Fencing rsa-fencing clone WebFSClone WebFS clone WebIP ClusterIP  \         meta globally-unique=”true” clone-max=”2” clone-node-max=”2” clone WebSiteClone WebSite clone dlm-clone dlm \         meta interleave="true" clone gfs-clone gfs-control \         meta interleave="true" colocation WebFS-with-gfs-control inf: WebFSClone gfs-clone colocation WebSite-with-WebFS inf: WebSiteClone WebFSClone colocation fs_on_drbd inf: WebFSClone WebDataClone:Master colocation gfs-with-dlm inf: gfs-clone dlm-clone colocation website-with-ip inf: WebSiteClone WebIP order WebFS-after-WebData inf: WebDataClone:promote WebFSClone:start order WebSite-after-WebFS inf: WebFSClone WebSiteClone order apache-after-ip inf: WebIP WebSiteClone order start-WebFS-after-gfs-control inf: gfs-clone WebFSClone order start-gfs-after-dlm inf: dlm-clone gfs-clone property $id="cib-bootstrap-options" \         dc-version="1.0.5-462f1569a43740667daf7b0f6b521742e9eb8fa7" \         cluster-infrastructure="openais" \         expected-quorum-votes=”2” \         stonith-enabled=”true” \         no-quorum-policy="ignore" rsc_defaults $id="rsc-options" \         resource-stickiness=”100” node pcmk-1 node pcmk-2 primitive ClusterIP ocf:heartbeat:IPaddr2 \         params ip=”192.168.122.101” cidr_netmask=”32” clusterip_hash=”sourceip” \         op monitor interval="30s" clone WebIP ClusterIP           meta globally-unique=”true” clone-max=”2” clone-node-max=”2” primitive WebData ocf:linbit:drbd \         params drbd_resource="wwwdata" \         op monitor interval="60s" ms WebDataClone WebData \         meta master-max="2" master-node-max="1" clone-max="2" clone-node-max="1" notify="true" primitive WebFS ocf:heartbeat:Filesystem \         params device="/dev/drbd/by-res/wwwdata" directory="/var/www/html" fstype=”gfs2” clone WebFSClone WebFS colocation WebFS-with-gfs-control inf: WebFSClone gfs-clone colocation fs_on_drbd inf: WebFSClone WebDataClone:Master order WebFS-after-WebData inf: WebDataClone:promote WebFSClone:start order start-WebFS-after-gfs-control inf: gfs-clone WebFSClone primitive WebSite ocf:heartbeat:apache \         params configfile="/etc/httpd/conf/httpd.conf" \         op monitor interval="1min" clone WebSiteClone WebSite colocation WebSite-with-WebFS inf: WebSiteClone WebFSClone colocation website-with-ip inf: WebSiteClone WebIP order apache-after-ip inf: WebIP WebSiteClone order WebSite-after-WebFS inf: WebFSClone WebSiteClone primitive dlm ocf:pacemaker:controld \         op monitor interval="120s" clone dlm-clone dlm \         meta interleave="true primitive gfs-control ocf:pacemaker:controld \    params daemon=”gfs_controld.pcmk” args=”-g 0” \         op monitor interval="120s" clone gfs-clone gfs-control \         meta interleave="true" colocation gfs-with-dlm inf: gfs-clone dlm-clone order start-gfs-after-dlm inf: dlm-clone gfs-clone primitive rsa-fencing stonith::external/ibmrsa \         params hostname=”pcmk-1 pcmk-2" ipaddr=192.168.122.31 userid=mgmt passwd=abc123 type=ibm \         op monitor interval="60s" clone Fencing rsa-fencing property $id="cib-bootstrap-options" \         dc-version="1.0.5-462f1569a43740667daf7b0f6b521742e9eb8fa7" \         cluster-infrastructure="openais" \         expected-quorum-votes=”2” \         stonith-enabled=”true” \         no-quorum-policy="ignore" rsc_defaults $id="rsc-options" \         resource-stickiness=”100” ApacheCluster FilesystemCluster OptionsCluster filesystems like GFS2 require a lock manager. This service starts the daemon that provides user-space applications (such as the GFS2 daemon) with access to the in-kernel lock manager. Since we need it to be available on all nodes in the cluster, we have it cloned.Configuration RecapDRBD - Shared StorageDefault OptionsDistributed lock managerFencingFinal Cluster ConfigurationGFS control daemonGFS2 also needs a user-space/kernel bridge that runs on every node. So here we have another clone, however this time we must also specify that it can only run on machines that are also running the DLM (colocation constraint) and that it can only be started after the DLM is running (order constraint). Additionally, the gfs-control clone should only care about the DLM instances it is paired with, so we need to set the interleave option.Here we configure cluster options that apply to every resource.Here we define the DRBD service and specify which DRBD resource (from drbd.conf) it should manage. We make it a master/slave resource and, in order to have an active/active setup, allow both instances to be promoted by specifying master-max=2. We also set the notify option so that the cluster will tell DRBD agent when it’s peer changes state.Lastly we have the actual service, Apache. We need only tell the cluster where to find it’s main configuration file and restrict it to running on nodes that have the required filesystem mounted and the IP address active.Node ListResourcesService AddressTODO: Add text hereTODO: Confirm interleave is no longer neededTODO: The RA should check for globally-unique=true when clonedThe cluster filesystem ensures that files are read and written correctly. We need to specify the block device (provided by DRBD), where we want it mounted and that we are using GFS2. Again it is a clone because it is intended to be active on both nodes. The additional constraints ensure that it can only be started on nodes with active gfs-control and drbd instances.The list of cluster nodes is automatically populated by the cluster.This is where the cluster automatically stores some information about the clusterUsers of the services provided by the cluster require an unchanging address with which to access it. Additionally, we cloned the address so it will be active on both nodes. An iptables rule (created as part of the resource agent) is used to ensure that each request only processed by one of the two clone instances. The additional meta options tell the cluster that we want two instances of the clone (one “request bucket” for each node) and that if one node fails, then the remaining node should hold both.and where the admin can set options that control the way the cluster operatescluster-infrastructure - the cluster infrastructure being used (heartbeat or openais)dc-version - the version (including upstream source-code hash) of Pacemaker used on the DCexpected-quorum-votes - the maximum number of nodes expected to be part of the clusterno-quorum-policy=ignore - Ignore loss of quorum and continue to host resources.resource-stickiness - Specify the aversion to moving resources to other machinesstonith-enabled=true - Make use of STONITHProject-Id-Version: 0 POT-Creation-Date: 2010-12-15T23:32:36 PO-Revision-Date: 2010-12-15 23:34+0800 Last-Translator: Charlie Chen Language-Team: None Language: MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [root@pcmk-1 ~]# crm configure show node pcmk-1 node pcmk-2 primitive WebData ocf:linbit:drbd \         params drbd_resource="wwwdata" \         op monitor interval="60s" primitive WebFS ocf:heartbeat:Filesystem \         params device="/dev/drbd/by-res/wwwdata" directory="/var/www/html" fstype=”gfs2” primitive WebSite ocf:heartbeat:apache \         params configfile="/etc/httpd/conf/httpd.conf" \         op monitor interval="1min" primitive ClusterIP ocf:heartbeat:IPaddr2 \         params ip=”192.168.122.101” cidr_netmask=”32” clusterip_hash=”sourceip” \         op monitor interval="30s" primitive dlm ocf:pacemaker:controld \         op monitor interval="120s" primitive gfs-control ocf:pacemaker:controld \    params daemon=”gfs_controld.pcmk” args=”-g 0” \         op monitor interval="120s" primitive rsa-fencing stonith::external/ibmrsa \         params hostname=”pcmk-1 pcmk-2" ipaddr=192.168.122.31 userid=mgmt passwd=abc123 type=ibm \         op monitor interval="60s" ms WebDataClone WebData \         meta master-max="2" master-node-max="1" clone-max="2" clone-node-max="1" notify="true" clone Fencing rsa-fencing clone WebFSClone WebFS clone WebIP ClusterIP  \         meta globally-unique=”true” clone-max=”2” clone-node-max=”2” clone WebSiteClone WebSite clone dlm-clone dlm \         meta interleave="true" clone gfs-clone gfs-control \         meta interleave="true" colocation WebFS-with-gfs-control inf: WebFSClone gfs-clone colocation WebSite-with-WebFS inf: WebSiteClone WebFSClone colocation fs_on_drbd inf: WebFSClone WebDataClone:Master colocation gfs-with-dlm inf: gfs-clone dlm-clone colocation website-with-ip inf: WebSiteClone WebIP order WebFS-after-WebData inf: WebDataClone:promote WebFSClone:start order WebSite-after-WebFS inf: WebFSClone WebSiteClone order apache-after-ip inf: WebIP WebSiteClone order start-WebFS-after-gfs-control inf: gfs-clone WebFSClone order start-gfs-after-dlm inf: dlm-clone gfs-clone property $id="cib-bootstrap-options" \         dc-version="1.0.5-462f1569a43740667daf7b0f6b521742e9eb8fa7" \         cluster-infrastructure="openais" \         expected-quorum-votes=”2” \         stonith-enabled=”true” \         no-quorum-policy="ignore" rsc_defaults $id="rsc-options" \         resource-stickiness=”100” node pcmk-1 node pcmk-2 primitive ClusterIP ocf:heartbeat:IPaddr2 \         params ip=”192.168.122.101” cidr_netmask=”32” clusterip_hash=”sourceip” \         op monitor interval="30s" clone WebIP ClusterIP           meta globally-unique=”true” clone-max=”2” clone-node-max=”2” primitive WebData ocf:linbit:drbd \         params drbd_resource="wwwdata" \         op monitor interval="60s" ms WebDataClone WebData \         meta master-max="2" master-node-max="1" clone-max="2" clone-node-max="1" notify="true" primitive WebFS ocf:heartbeat:Filesystem \         params device="/dev/drbd/by-res/wwwdata" directory="/var/www/html" fstype=”gfs2” clone WebFSClone WebFS colocation WebFS-with-gfs-control inf: WebFSClone gfs-clone colocation fs_on_drbd inf: WebFSClone WebDataClone:Master order WebFS-after-WebData inf: WebDataClone:promote WebFSClone:start order start-WebFS-after-gfs-control inf: gfs-clone WebFSClone primitive WebSite ocf:heartbeat:apache \         params configfile="/etc/httpd/conf/httpd.conf" \         op monitor interval="1min" clone WebSiteClone WebSite colocation WebSite-with-WebFS inf: WebSiteClone WebFSClone colocation website-with-ip inf: WebSiteClone WebIP order apache-after-ip inf: WebIP WebSiteClone order WebSite-after-WebFS inf: WebFSClone WebSiteClone primitive dlm ocf:pacemaker:controld \         op monitor interval="120s" clone dlm-clone dlm \         meta interleave="true primitive gfs-control ocf:pacemaker:controld \    params daemon=”gfs_controld.pcmk” args=”-g 0” \         op monitor interval="120s" clone gfs-clone gfs-control \         meta interleave="true" colocation gfs-with-dlm inf: gfs-clone dlm-clone order start-gfs-after-dlm inf: dlm-clone gfs-clone primitive rsa-fencing stonith::external/ibmrsa \         params hostname=”pcmk-1 pcmk-2" ipaddr=192.168.122.31 userid=mgmt passwd=abc123 type=ibm \         op monitor interval="60s" clone Fencing rsa-fencing property $id="cib-bootstrap-options" \         dc-version="1.0.5-462f1569a43740667daf7b0f6b521742e9eb8fa7" \         cluster-infrastructure="openais" \         expected-quorum-votes=”2” \         stonith-enabled=”true” \         no-quorum-policy="ignore" rsc_defaults $id="rsc-options" \         resource-stickiness=”100” Apache集群文件系统集群选项像GFS2集群文件系统需要一个锁管理。该服务启动守护进程,提供了访问内核中的锁管理器的用户空间应用程序(如GFS2守护进程)。因为我们需要它在集群中的所有可用节点中运行,我们把它clone。配置扼要重述DRBD - 共享存储默认选项分布式锁控制器隔离最终的集群配置文件GFS 控制守护进程GFS2还需要一个user-space到kernel的桥梁,每个节点上要运行。所以在这里我们还有一个clone,但是这一次我们还必须指定它只能运行在有DLM的机器上(colocation 约束),它只能在DLM后启动 (order约束)。此外,gfs-control clone应该只关系与其配对的DLM实例,所以我们还要设置interleave 选项这里我们设置所有资源共用的集群选项在这里,我们定义了DRBD技术服务,并指定DRBD应该管理的资源(从drbd.conf)。我们让它作为主/从资源,并且为了active/active,用设置master-max=2来允许两者都晋升为master。我们还可以设置通知选项,这样,当时集群的节点的状态发生改变时,该集群将告诉DRBD的agent。 最后我们有了真正的服务,Apache,我们只需要告诉集群在哪里可以找到它的主配置文件,并限制其只在挂载了文件系统和有可用IP节点上运行节点列表资源服务地址TODO: Add text hereTODO: Confirm interleave is no longer neededTODO: The RA should check for globally-unique=true when cloned群集文件系统可确保文件读写正确。我们需要指定我们想挂载并使用GFS2的块设备(由DRBD提供)。这又是一个clone,因为它的目的是在两个节点上都可用。这些额外的限制确保它只在有gfs-control和drbd 实例的节点上运行。这个列表中的集群节点是集群自动添加的。这是集群自动存储集群信息的地方用户需要一个不变的地址来访问集群所提供的服务。此外,我们clone了地址,以便在两个节点上都使用这个IP。一个iptables规则(resource agent的一部分)是用来确保每个请求只能由两个节点中的某一个处理。这些额外的集群选项告诉我们想要两个clone(每个节点一个“请求桶”)实例,如果一个节点失效,那么剩下的节点处理这两个请求桶。以及管理员设置集群操作的方法选项集群-基层 - 集群使用的基层软件 (heartbeat or openais/corosync)dc-version - DC使用的Pacemaker的版本(包括源代码的hash)expected-quorum-votes - 预期的集群最大成员数no-quorum-policy=ignore - 忽略达不到法定人数的情况,继续运行资源resource-stickiness - 资源粘稠值stonith-enabled=true - 使用STONITHpacemaker-master/doc/Clusters_from_Scratch/zh-CN/Ap-Configuration.po000066400000000000000000000776601217637305600260200ustar00rootroot00000000000000# # AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: 0\n" "POT-Creation-Date: 2012-10-17T05:19:03\n" "PO-Revision-Date: 2010-12-15 23:34+0800\n" "Last-Translator: Charlie Chen \n" "Language-Team: None\n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. Tag: title #, no-c-format msgid "Configuration Recap" msgstr "配置扼要重述" #. Tag: title #, no-c-format msgid "Final Cluster Configuration" msgstr "最终的集群配置文件" #. Tag: programlisting #, no-c-format msgid "" "# pcs resource\n" " Master/Slave Set: WebDataClone [WebData]\n" " Masters: [ pcmk-2 pcmk-1 ]\n" " Clone Set: dlm-clone [dlm]\n" " Started: [ pcmk-2 pcmk-1 ]\n" " Clone Set: ClusterIP-clone [ClusterIP] (unique)\n" " ClusterIP:0 (ocf::heartbeat:IPaddr2) Started\n" " ClusterIP:1 (ocf::heartbeat:IPaddr2) Started\n" " Clone Set: WebFS-clone [WebFS]\n" " Started: [ pcmk-1 pcmk-2 ]\n" " Clone Set: WebSite-clone [WebSite]\n" " Started: [ pcmk-1 pcmk-2 ]\n" "# pcs resource rsc defaults\n" "resource-stickiness: 100\n" "# pcs resource op defaults\n" "timeout: 240s\n" "# pcs stonith\n" " impi-fencing (stonith:fence_ipmilan) Started\n" "# pcs property\n" "dc-version: 1.1.8-1.el7-60a19ed12fdb4d5c6a6b6767f52e5391e447fec0\n" "cluster-infrastructure: corosync\n" "no-quorum-policy: ignore\n" "stonith-enabled: true\n" "# pcs constraint\n" "Location Constraints:\n" "Ordering Constraints:\n" " ClusterIP-clone then WebSite-clone\n" " WebDataClone then WebSite-clone\n" " WebFS-clone then WebSite-clone\n" "Colocation Constraints:\n" " WebSite-clone with ClusterIP-clone\n" " WebFS-clone with WebDataClone (with-rsc-role:Master)\n" " WebSite-clone with WebFS-clone\n" "#\n" "# pcs status\n" "\n" "Last updated: Fri Sep 14 13:45:34 2012\n" "Last change: Fri Sep 14 13:43:13 2012 via cibadmin on pcmk-1\n" "Stack: corosync\n" "Current DC: pcmk-1 (1) - partition with quorum\n" "Version: 1.1.8-1.el7-60a19ed12fdb4d5c6a6b6767f52e5391e447fec0\n" "2 Nodes configured, unknown expected votes\n" "11 Resources configured.\n" "\n" "Online: [ pcmk-1 pcmk-2 ]\n" "\n" "Full list of resources:\n" "\n" " Master/Slave Set: WebDataClone [WebData]\n" " Masters: [ pcmk-2 pcmk-1 ]\n" " Clone Set: dlm-clone [dlm]\n" " Started: [ pcmk-1 pcmk-2 ]\n" " Clone Set: ClusterIP-clone [ClusterIP] (unique)\n" " ClusterIP:0 (ocf::heartbeat:IPaddr2): Started pcmk-1\n" " ClusterIP:1 (ocf::heartbeat:IPaddr2): Started pcmk-2\n" " Clone Set: WebFS-clone [WebFS]\n" " Started: [ pcmk-1 pcmk-2 ]\n" " Clone Set: WebSite-clone [WebSite]\n" " Started: [ pcmk-1 pcmk-2 ]\n" " impi-fencing (stonith:fence_ipmilan): Started" msgstr "" #. Tag: para #, no-c-format msgid "In xml it should look similar to this." msgstr "" #. Tag: programlisting #, no-c-format msgid "" "<cib admin_epoch=\"0\" cib-last-written=\"Fri Sep 14 13:43:13 2012\" crm_feature_set=\"3.0.6\" dc-uuid=\"1\" epoch=\"47\" have-quorum=\"1\" num_updates=\"50\" update-client=\"cibadmin\" update-origin=\"pcmk-1\" validate-with=\"pacemaker-1.2\">\n" " <configuration>\n" " <crm_config>\n" " <cluster_property_set id=\"cib-bootstrap-options\">\n" " <nvpair id=\"cib-bootstrap-options-dc-version\" name=\"dc-version\" value=\"1.1.8-1.el7-60a19ed12fdb4d5c6a6b6767f52e5391e447fec0\"/>\n" " <nvpair id=\"cib-bootstrap-options-cluster-infrastructure\" name=\"cluster-infrastructure\" value=\"corosync\"/>\n" " <nvpair id=\"cib-bootstrap-options-no-quorum-policy\" name=\"no-quorum-policy\" value=\"ignore\"/>\n" " <nvpair id=\"cib-bootstrap-options-stonith-enabled\" name=\"stonith-enabled\" value=\"true\"/>\n" " </cluster_property_set>\n" " </crm_config>\n" " <nodes>\n" " <node id=\"1\" type=\"normal\" uname=\"pcmk-1\"/>\n" " <node id=\"2\" type=\"normal\" uname=\"pcmk-2\"/>\n" " </nodes>\n" " <resources>\n" " <master id=\"WebDataClone\">\n" " <primitive class=\"ocf\" id=\"WebData\" provider=\"linbit\" type=\"drbd\">\n" " <instance_attributes id=\"WebData-instance_attributes\">\n" " <nvpair id=\"WebData-instance_attributes-drbd_resource\" name=\"drbd_resource\" value=\"wwwdata\"/>\n" " </instance_attributes>\n" " <operations>\n" " <op id=\"WebData-interval-60s\" interval=\"60s\" name=\"monitor\"/>\n" " </operations>\n" " </primitive>\n" " <meta_attributes id=\"WebDataClone-meta_attributes\">\n" " <nvpair id=\"WebDataClone-meta_attributes-master-node-max\" name=\"master-node-max\" value=\"1\"/>\n" " <nvpair id=\"WebDataClone-meta_attributes-clone-max\" name=\"clone-max\" value=\"2\"/>\n" " <nvpair id=\"WebDataClone-meta_attributes-clone-node-max\" name=\"clone-node-max\" value=\"1\"/>\n" " <nvpair id=\"WebDataClone-meta_attributes-notify\" name=\"notify\" value=\"true\"/>\n" " <nvpair id=\"WebDataClone-meta_attributes-master-max\" name=\"master-max\" value=\"2\"/>\n" " </meta_attributes>\n" " </master>\n" " <clone id=\"dlm-clone\">\n" " <primitive class=\"ocf\" id=\"dlm\" provider=\"pacemaker\" type=\"controld\">\n" " <instance_attributes id=\"dlm-instance_attributes\"/>\n" " <operations>\n" " <op id=\"dlm-interval-60s\" interval=\"60s\" name=\"monitor\"/>\n" " </operations>\n" " </primitive>\n" " <meta_attributes id=\"dlm-clone-meta\">\n" " <nvpair id=\"dlm-clone-max\" name=\"clone-max\" value=\"2\"/>\n" " <nvpair id=\"dlm-clone-node-max\" name=\"clone-node-max\" value=\"1\"/>\n" " </meta_attributes>\n" " </clone>\n" " <clone id=\"ClusterIP-clone\">\n" " <primitive class=\"ocf\" id=\"ClusterIP\" provider=\"heartbeat\" type=\"IPaddr2\">\n" " <instance_attributes id=\"ClusterIP-instance_attributes\">\n" " <nvpair id=\"ClusterIP-instance_attributes-ip\" name=\"ip\" value=\"192.168.0.120\"/>\n" " <nvpair id=\"ClusterIP-instance_attributes-cidr_netmask\" name=\"cidr_netmask\" value=\"32\"/>\n" " <nvpair id=\"ClusterIP-instance_attributes-clusterip_hash\" name=\"clusterip_hash\" value=\"sourceip\"/>\n" " </instance_attributes>\n" " <operations>\n" " <op id=\"ClusterIP-interval-30s\" interval=\"30s\" name=\"monitor\"/>\n" " </operations>\n" " </primitive>\n" " <meta_attributes id=\"ClusterIP-clone-meta\">\n" " <nvpair id=\"ClusterIP-globally-unique\" name=\"globally-unique\" value=\"true\"/>\n" " <nvpair id=\"ClusterIP-clone-max\" name=\"clone-max\" value=\"2\"/>\n" " <nvpair id=\"ClusterIP-clone-node-max\" name=\"clone-node-max\" value=\"2\"/>\n" " </meta_attributes>\n" " </clone>\n" " <clone id=\"WebFS-clone\">\n" " <primitive class=\"ocf\" id=\"WebFS\" provider=\"heartbeat\" type=\"Filesystem\">\n" " <instance_attributes id=\"WebFS-instance_attributes\">\n" " <nvpair id=\"WebFS-instance_attributes-device\" name=\"device\" value=\"/dev/drbd/by-res/wwwdata\"/>\n" " <nvpair id=\"WebFS-instance_attributes-directory\" name=\"directory\" value=\"/var/www/html\"/>\n" " <nvpair id=\"WebFS-instance_attributes-fstype\" name=\"fstype\" value=\"gfs2\"/>\n" " </instance_attributes>\n" " <meta_attributes id=\"WebFS-meta_attributes\"/>\n" " </primitive>\n" " <meta_attributes id=\"WebFS-clone-meta\"/>\n" " </clone>\n" " <clone id=\"WebSite-clone\">\n" " <primitive class=\"ocf\" id=\"WebSite\" provider=\"heartbeat\" type=\"apache\">\n" " <instance_attributes id=\"WebSite-instance_attributes\">\n" " <nvpair id=\"WebSite-instance_attributes-configfile\" name=\"configfile\" value=\"/etc/httpd/conf/httpd.conf\"/>\n" " <nvpair id=\"WebSite-instance_attributes-statusurl\" name=\"statusurl\" value=\"http://localhost/server-status\"/>\n" " </instance_attributes>\n" " <operations>\n" " <op id=\"WebSite-interval-1min\" interval=\"1min\" name=\"monitor\"/>\n" " </operations>\n" " </primitive>\n" " <meta_attributes id=\"WebSite-clone-meta\"/>\n" " </clone>\n" " <primitive class=\"stonith\" id=\"impi-fencing\" type=\"fence_ipmilan\">\n" " <instance_attributes id=\"impi-fencing-instance_attributes\">\n" " <nvpair id=\"impi-fencing-instance_attributes-pcmk_host_list\" name=\"pcmk_host_list\" value=\"pcmk-1 pcmk-2\"/>\n" " <nvpair id=\"impi-fencing-instance_attributes-ipaddr\" name=\"ipaddr\" value=\"10.0.0.1\"/>\n" " <nvpair id=\"impi-fencing-instance_attributes-login\" name=\"login\" value=\"testuser\"/>\n" " <nvpair id=\"impi-fencing-instance_attributes-passwd\" name=\"passwd\" value=\"acd123\"/>\n" " </instance_attributes>\n" " <operations>\n" " <op id=\"impi-fencing-interval-60s\" interval=\"60s\" name=\"monitor\"/>\n" " </operations>\n" " </primitive>\n" " </resources>\n" " <constraints>\n" " <rsc_colocation id=\"colocation-WebSite-ClusterIP-INFINITY\" rsc=\"WebSite-clone\" score=\"INFINITY\" with-rsc=\"ClusterIP-clone\"/>\n" " <rsc_order first=\"ClusterIP-clone\" first-action=\"start\" id=\"order-ClusterIP-WebSite-mandatory\" then=\"WebSite-clone\" then-action=\"start\"/>\n" " <rsc_colocation id=\"colocation-WebFS-WebDataClone-INFINITY\" rsc=\"WebFS-clone\" score=\"INFINITY\" with-rsc=\"WebDataClone\" with-rsc-role=\"Master\"/>\n" " <rsc_colocation id=\"colocation-WebSite-WebFS-INFINITY\" rsc=\"WebSite-clone\" score=\"INFINITY\" with-rsc=\"WebFS-clone\"/>\n" " <rsc_order first=\"WebFS-clone\" id=\"order-WebFS-WebSite-mandatory\" then=\"WebSite-clone\"/>\n" " <rsc_order first=\"WebDataClone\" first-action=\"promote\" id=\"order-WebDataClone-WebFS-mandatory\" then=\"WebFS-clone\" then-action=\"start\"/>\n" " </constraints>\n" " <rsc_defaults>\n" " <meta_attributes id=\"rsc_defaults-options\">\n" " <nvpair id=\"rsc_defaults-options-resource-stickiness\" name=\"resource-stickiness\" value=\"100\"/>\n" " </meta_attributes>\n" " </rsc_defaults>\n" " <op_defaults>\n" " <meta_attributes id=\"op_defaults-options\">\n" " <nvpair id=\"op_defaults-options-timeout\" name=\"timeout\" value=\"240s\"/>\n" " </meta_attributes>\n" " </op_defaults>\n" " </configuration>\n" "</cib>" msgstr "" #. Tag: title #, no-c-format msgid "Node List" msgstr "节点列表" #. Tag: para #, no-c-format msgid "The list of cluster nodes is automatically populated by the cluster." msgstr "这个列表中的集群节点是集群自动添加的。" #. Tag: literallayout #, no-c-format msgid "" "Pacemaker Nodes:\n" " Online: [ pcmk-1 pcmk-2 ]" msgstr "" #. Tag: title #, no-c-format msgid "Cluster Options" msgstr "集群选项" #. Tag: para #, no-c-format msgid "This is where the cluster automatically stores some information about the cluster" msgstr "这是集群自动存储集群信息的地方" #. Tag: para #, no-c-format msgid "dc-version - the version (including upstream source-code hash) of Pacemaker used on the DC" msgstr "dc-version - DC使用的Pacemaker的版本(包括源代码的hash)" #. Tag: para #, no-c-format msgid "cluster-infrastructure - the cluster infrastructure being used (heartbeat or openais)" msgstr "集群-基层 - 集群使用的基层软件 (heartbeat or openais/corosync)" #. Tag: para #, no-c-format msgid "expected-quorum-votes - the maximum number of nodes expected to be part of the cluster" msgstr "expected-quorum-votes - 预期的集群最大成员数" #. Tag: para #, no-c-format msgid "and where the admin can set options that control the way the cluster operates" msgstr "以及管理员设置集群操作的方法选项" #. Tag: para #, no-c-format msgid "stonith-enabled=true - Make use of STONITH" msgstr "stonith-enabled=true - 使用STONITH" #. Tag: para #, no-c-format msgid "no-quorum-policy=ignore - Ignore loss of quorum and continue to host resources." msgstr "no-quorum-policy=ignore - 忽略达不到法定人数的情况,继续运行资源" #. Tag: programlisting #, no-c-format msgid "" "# pcs property\n" "dc-version: 1.1.8-1.el7-60a19ed12fdb4d5c6a6b6767f52e5391e447fec0\n" "cluster-infrastructure: corosync\n" "no-quorum-policy: ignore\n" "stonith-enabled: true" msgstr "" #. Tag: title #, no-c-format msgid "Resources" msgstr "资源" #. Tag: title #, no-c-format msgid "Default Options" msgstr "默认选项" #. Tag: para #, no-c-format msgid "Here we configure cluster options that apply to every resource." msgstr "这里我们设置所有资源共用的集群选项" #. Tag: para #, no-c-format msgid "resource-stickiness - Specify the aversion to moving resources to other machines" msgstr "resource-stickiness - 资源粘稠值" #. Tag: programlisting #, no-c-format msgid "" "# pcs resource rsc defaults\n" "resource-stickiness: 100" msgstr "" #. Tag: title #, no-c-format msgid "Fencing" msgstr "隔离" #. Tag: programlisting #, no-c-format msgid "" "# pcs stonith show\n" " impi-fencing (stonith:fence_ipmilan) Started\n" "# pcs stonith show impi-fencing\n" "Resource: impi-fencing\n" " pcmk_host_list: pcmk-1 pcmk-2\n" " ipaddr: 10.0.0.1\n" " login: testuser\n" " passwd: acd123" msgstr "" #. Tag: title #, no-c-format msgid "Service Address" msgstr "服务地址" #. Tag: para #, fuzzy, no-c-format msgid "Users of the services provided by the cluster require an unchanging address with which to access it. Additionally, we cloned the address so it will be active on both nodes. An iptables rule (created as part of the resource agent) is used to ensure that each request only gets processed by one of the two clone instances. The additional meta options tell the cluster that we want two instances of the clone (one \"request bucket\" for each node) and that if one node fails, then the remaining node should hold both." msgstr "用户需要一个不变的地址来访问集群所提供的服务。此外,我们clone了地址,以便在两个节点上都使用这个IP。一个iptables规则(resource agent的一部分)是用来确保每个请求只能由两个节点中的某一个处理。这些额外的集群选项告诉我们想要两个clone(每个节点一个“请求桶”)实例,如果一个节点失效,那么剩下的节点处理这两个请求桶。" #. Tag: programlisting #, no-c-format msgid "" "# pcs resource show ClusterIP-clone\n" "Resource: ClusterIP-clone\n" " ip: 192.168.0.120\n" " cidr_netmask: 32\n" " clusterip_hash: sourceip\n" " globally-unique: true\n" " clone-max: 2\n" " clone-node-max: 2\n" " op monitor interval=30s" msgstr "" #. Tag: para #, no-c-format msgid "TODO: The RA should check for globally-unique=true when cloned" msgstr "TODO: The RA should check for globally-unique=true when cloned" #. Tag: title #, no-c-format msgid "DRBD - Shared Storage" msgstr "DRBD - 共享存储" #. Tag: para #, no-c-format msgid "Here we define the DRBD service and specify which DRBD resource (from drbd.conf) it should manage. We make it a master/slave resource and, in order to have an active/active setup, allow both instances to be promoted by specifying master-max=2. We also set the notify option so that the cluster will tell DRBD agent when it’s peer changes state." msgstr "在这里,我们定义了DRBD技术服务,并指定DRBD应该管理的资源(从drbd.conf)。我们让它作为主/从资源,并且为了active/active,用设置master-max=2来允许两者都晋升为master。我们还可以设置通知选项,这样,当时集群的节点的状态发生改变时,该集群将告诉DRBD的agent。 " #. Tag: programlisting #, no-c-format msgid "" "# pcs resource show WebDataClone\n" "Resource: WebDataClone\n" " drbd_resource: wwwdata\n" " master-node-max: 1\n" " clone-max: 2\n" " clone-node-max: 1\n" " notify: true\n" " master-max: 2\n" " op monitor interval=60s\n" "# pcs constraint ref WebDataClone\n" "Resource: WebDataClone\n" " colocation-WebFS-WebDataClone-INFINITY\n" " order-WebDataClone-WebFS-mandatory" msgstr "" #. Tag: title #, no-c-format msgid "Cluster Filesystem" msgstr "集群文件系统" #. Tag: para #, no-c-format msgid "The cluster filesystem ensures that files are read and written correctly. We need to specify the block device (provided by DRBD), where we want it mounted and that we are using GFS2. Again it is a clone because it is intended to be active on both nodes. The additional constraints ensure that it can only be started on nodes with active gfs-control and drbd instances." msgstr "群集文件系统可确保文件读写正确。我们需要指定我们想挂载并使用GFS2的块设备(由DRBD提供)。这又是一个clone,因为它的目的是在两个节点上都可用。这些额外的限制确保它只在有gfs-control和drbd 实例的节点上运行。" #. Tag: programlisting #, no-c-format msgid "" "# pcs resource show WebFS-clone\n" "Resource: WebFS-clone\n" " device: /dev/drbd/by-res/wwwdata\n" " directory: /var/www/html\n" " fstype: gfs2\n" "# pcs constraint ref WebFS-clone\n" "Resource: WebFS-clone\n" " colocation-WebFS-WebDataClone-INFINITY\n" " colocation-WebSite-WebFS-INFINITY\n" " order-WebFS-WebSite-mandatory\n" " order-WebDataClone-WebFS-mandatory" msgstr "" #. Tag: title #, no-c-format msgid "Apache" msgstr "Apache" #. Tag: para #, no-c-format msgid "Lastly we have the actual service, Apache. We need only tell the cluster where to find it’s main configuration file and restrict it to running on nodes that have the required filesystem mounted and the IP address active." msgstr "最后我们有了真正的服务,Apache,我们只需要告诉集群在哪里可以找到它的主配置文件,并限制其只在挂载了文件系统和有可用IP节点上运行" #. Tag: programlisting #, no-c-format msgid "" "# pcs resource show WebSite-clone\n" "Resource: WebSite-clone\n" " configfile: /etc/httpd/conf/httpd.conf\n" " statusurl: http://localhost/server-status\n" " master-max: 2\n" " op monitor interval=1min\n" "# pcs constraint ref WebSite-clone\n" "Resource: WebSite-clone\n" " colocation-WebSite-ClusterIP-INFINITY\n" " colocation-WebSite-WebFS-INFINITY\n" " order-ClusterIP-WebSite-mandatory\n" " order-WebFS-WebSite-mandatory" msgstr "" #~ msgid "" #~ "\n" #~ "[root@pcmk-1 ~]# crm configure show\n" #~ "node pcmk-1\n" #~ "node pcmk-2\n" #~ "primitive WebData ocf:linbit:drbd \\\n" #~ "        params drbd_resource=\"wwwdata\" \\\n" #~ "        op monitor interval=\"60s\"\n" #~ "primitive WebFS ocf:heartbeat:Filesystem \\\n" #~ "        params device=\"/dev/drbd/by-res/wwwdata\" directory=\"/var/www/html\" fstype=”gfs2”\n" #~ "primitive WebSite ocf:heartbeat:apache \\\n" #~ "        params configfile=\"/etc/httpd/conf/httpd.conf\" \\\n" #~ "        op monitor interval=\"1min\"\n" #~ "primitive ClusterIP ocf:heartbeat:IPaddr2 \\\n" #~ "        params ip=”192.168.122.101” cidr_netmask=”32” clusterip_hash=”sourceip” \\\n" #~ "        op monitor interval=\"30s\"\n" #~ "primitive dlm ocf:pacemaker:controld \\\n" #~ "        op monitor interval=\"120s\"\n" #~ "primitive gfs-control ocf:pacemaker:controld \\\n" #~ "   params daemon=”gfs_controld.pcmk” args=”-g 0” \\\n" #~ "        op monitor interval=\"120s\"\n" #~ "primitive rsa-fencing stonith::external/ibmrsa \\\n" #~ "        params hostname=”pcmk-1 pcmk-2\" ipaddr=192.168.122.31 userid=mgmt passwd=abc123 type=ibm \\\n" #~ "        op monitor interval=\"60s\"\n" #~ "ms WebDataClone WebData \\\n" #~ "        meta master-max=\"2\" master-node-max=\"1\" clone-max=\"2\" clone-node-max=\"1\" notify=\"true\"\n" #~ "clone Fencing rsa-fencing \n" #~ "clone WebFSClone WebFS\n" #~ "clone WebIP ClusterIP  \\\n" #~ "        meta globally-unique=”true” clone-max=”2” clone-node-max=”2”\n" #~ "clone WebSiteClone WebSite\n" #~ "clone dlm-clone dlm \\\n" #~ "        meta interleave=\"true\"\n" #~ "clone gfs-clone gfs-control \\\n" #~ "        meta interleave=\"true\"\n" #~ "colocation WebFS-with-gfs-control inf: WebFSClone gfs-clone\n" #~ "colocation WebSite-with-WebFS inf: WebSiteClone WebFSClone\n" #~ "colocation fs_on_drbd inf: WebFSClone WebDataClone:Master\n" #~ "colocation gfs-with-dlm inf: gfs-clone dlm-clone\n" #~ "colocation website-with-ip inf: WebSiteClone WebIP\n" #~ "order WebFS-after-WebData inf: WebDataClone:promote WebFSClone:start\n" #~ "order WebSite-after-WebFS inf: WebFSClone WebSiteClone\n" #~ "order apache-after-ip inf: WebIP WebSiteClone\n" #~ "order start-WebFS-after-gfs-control inf: gfs-clone WebFSClone\n" #~ "order start-gfs-after-dlm inf: dlm-clone gfs-clone\n" #~ "property $id=\"cib-bootstrap-options\" \\\n" #~ "        dc-version=\"1.0.5-462f1569a43740667daf7b0f6b521742e9eb8fa7\" \\\n" #~ "        cluster-infrastructure=\"openais\" \\\n" #~ "        expected-quorum-votes=”2” \\\n" #~ "        stonith-enabled=”true” \\\n" #~ "        no-quorum-policy=\"ignore\"\n" #~ "rsc_defaults $id=\"rsc-options\" \\\n" #~ "        resource-stickiness=”100”\n" #~ msgstr "" #~ "\n" #~ "[root@pcmk-1 ~]# crm configure show\n" #~ "node pcmk-1\n" #~ "node pcmk-2\n" #~ "primitive WebData ocf:linbit:drbd \\\n" #~ "        params drbd_resource=\"wwwdata\" \\\n" #~ "        op monitor interval=\"60s\"\n" #~ "primitive WebFS ocf:heartbeat:Filesystem \\\n" #~ "        params device=\"/dev/drbd/by-res/wwwdata\" directory=\"/var/www/html\" fstype=”gfs2”\n" #~ "primitive WebSite ocf:heartbeat:apache \\\n" #~ "        params configfile=\"/etc/httpd/conf/httpd.conf\" \\\n" #~ "        op monitor interval=\"1min\"\n" #~ "primitive ClusterIP ocf:heartbeat:IPaddr2 \\\n" #~ "        params ip=”192.168.122.101” cidr_netmask=”32” clusterip_hash=”sourceip” \\\n" #~ "        op monitor interval=\"30s\"\n" #~ "primitive dlm ocf:pacemaker:controld \\\n" #~ "        op monitor interval=\"120s\"\n" #~ "primitive gfs-control ocf:pacemaker:controld \\\n" #~ "   params daemon=”gfs_controld.pcmk” args=”-g 0” \\\n" #~ "        op monitor interval=\"120s\"\n" #~ "primitive rsa-fencing stonith::external/ibmrsa \\\n" #~ "        params hostname=”pcmk-1 pcmk-2\" ipaddr=192.168.122.31 userid=mgmt passwd=abc123 type=ibm \\\n" #~ "        op monitor interval=\"60s\"\n" #~ "ms WebDataClone WebData \\\n" #~ "        meta master-max=\"2\" master-node-max=\"1\" clone-max=\"2\" clone-node-max=\"1\" notify=\"true\"\n" #~ "clone Fencing rsa-fencing \n" #~ "clone WebFSClone WebFS\n" #~ "clone WebIP ClusterIP  \\\n" #~ "        meta globally-unique=”true” clone-max=”2” clone-node-max=”2”\n" #~ "clone WebSiteClone WebSite\n" #~ "clone dlm-clone dlm \\\n" #~ "        meta interleave=\"true\"\n" #~ "clone gfs-clone gfs-control \\\n" #~ "        meta interleave=\"true\"\n" #~ "colocation WebFS-with-gfs-control inf: WebFSClone gfs-clone\n" #~ "colocation WebSite-with-WebFS inf: WebSiteClone WebFSClone\n" #~ "colocation fs_on_drbd inf: WebFSClone WebDataClone:Master\n" #~ "colocation gfs-with-dlm inf: gfs-clone dlm-clone\n" #~ "colocation website-with-ip inf: WebSiteClone WebIP\n" #~ "order WebFS-after-WebData inf: WebDataClone:promote WebFSClone:start\n" #~ "order WebSite-after-WebFS inf: WebFSClone WebSiteClone\n" #~ "order apache-after-ip inf: WebIP WebSiteClone\n" #~ "order start-WebFS-after-gfs-control inf: gfs-clone WebFSClone\n" #~ "order start-gfs-after-dlm inf: dlm-clone gfs-clone\n" #~ "property $id=\"cib-bootstrap-options\" \\\n" #~ "        dc-version=\"1.0.5-462f1569a43740667daf7b0f6b521742e9eb8fa7\" \\\n" #~ "        cluster-infrastructure=\"openais\" \\\n" #~ "        expected-quorum-votes=”2” \\\n" #~ "        stonith-enabled=”true” \\\n" #~ "        no-quorum-policy=\"ignore\"\n" #~ "rsc_defaults $id=\"rsc-options\" \\\n" #~ "        resource-stickiness=”100”\n" #~ msgid "" #~ "\n" #~ "node pcmk-1\n" #~ "node pcmk-2\n" #~ msgstr "" #~ "\n" #~ "node pcmk-1\n" #~ "node pcmk-2\n" #~ msgid "" #~ "\n" #~ "property $id=\"cib-bootstrap-options\" \\\n" #~ "        dc-version=\"1.0.5-462f1569a43740667daf7b0f6b521742e9eb8fa7\" \\\n" #~ "        cluster-infrastructure=\"openais\" \\\n" #~ "        expected-quorum-votes=”2” \\\n" #~ "        stonith-enabled=”true” \\\n" #~ "        no-quorum-policy=\"ignore\"\n" #~ msgstr "" #~ "\n" #~ "property $id=\"cib-bootstrap-options\" \\\n" #~ "        dc-version=\"1.0.5-462f1569a43740667daf7b0f6b521742e9eb8fa7\" \\\n" #~ "        cluster-infrastructure=\"openais\" \\\n" #~ "        expected-quorum-votes=”2” \\\n" #~ "        stonith-enabled=”true” \\\n" #~ "        no-quorum-policy=\"ignore\"\n" #~ msgid "" #~ "\n" #~ "rsc_defaults $id=\"rsc-options\" \\\n" #~ "        resource-stickiness=”100”\n" #~ msgstr "" #~ "\n" #~ "rsc_defaults $id=\"rsc-options\" \\\n" #~ "        resource-stickiness=”100”\n" #~ msgid "TODO: Add text here" #~ msgstr "TODO: Add text here" #~ msgid "" #~ "\n" #~ "primitive rsa-fencing stonith::external/ibmrsa \\\n" #~ "        params hostname=”pcmk-1 pcmk-2\" ipaddr=192.168.122.31 userid=mgmt passwd=abc123 type=ibm \\\n" #~ "        op monitor interval=\"60s\"\n" #~ "clone Fencing rsa-fencing\n" #~ msgstr "" #~ "\n" #~ "primitive rsa-fencing stonith::external/ibmrsa \\\n" #~ "        params hostname=”pcmk-1 pcmk-2\" ipaddr=192.168.122.31 userid=mgmt passwd=abc123 type=ibm \\\n" #~ "        op monitor interval=\"60s\"\n" #~ "clone Fencing rsa-fencing\n" #~ msgid "" #~ "\n" #~ "primitive ClusterIP ocf:heartbeat:IPaddr2 \\\n" #~ "        params ip=”192.168.122.101” cidr_netmask=”32” clusterip_hash=”sourceip” \\\n" #~ "        op monitor interval=\"30s\"\n" #~ "clone WebIP ClusterIP  \n" #~ "        meta globally-unique=”true” clone-max=”2” clone-node-max=”2”\n" #~ msgstr "" #~ "\n" #~ "primitive ClusterIP ocf:heartbeat:IPaddr2 \\\n" #~ "        params ip=”192.168.122.101” cidr_netmask=”32” clusterip_hash=”sourceip” \\\n" #~ "        op monitor interval=\"30s\"\n" #~ "clone WebIP ClusterIP  \n" #~ "        meta globally-unique=”true” clone-max=”2” clone-node-max=”2”\n" #~ msgid "Distributed lock manager" #~ msgstr "分布式锁控制器" #~ msgid "Cluster filesystems like GFS2 require a lock manager. This service starts the daemon that provides user-space applications (such as the GFS2 daemon) with access to the in-kernel lock manager. Since we need it to be available on all nodes in the cluster, we have it cloned." #~ msgstr "像GFS2集群文件系统需要一个锁管理。该服务启动守护进程,提供了访问内核中的锁管理器的用户空间应用程序(如GFS2守护进程)。因为我们需要它在集群中的所有可用节点中运行,我们把它clone。" #~ msgid "" #~ "\n" #~ "primitive dlm ocf:pacemaker:controld \\\n" #~ "        op monitor interval=\"120s\"\n" #~ "clone dlm-clone dlm \\\n" #~ "        meta interleave=\"true\n" #~ msgstr "" #~ "\n" #~ "primitive dlm ocf:pacemaker:controld \\\n" #~ "        op monitor interval=\"120s\"\n" #~ "clone dlm-clone dlm \\\n" #~ "        meta interleave=\"true\n" #~ msgid "TODO: Confirm interleave is no longer needed" #~ msgstr "TODO: Confirm interleave is no longer needed" #~ msgid "GFS control daemon" #~ msgstr "GFS 控制守护进程" #~ msgid "GFS2 also needs a user-space/kernel bridge that runs on every node. So here we have another clone, however this time we must also specify that it can only run on machines that are also running the DLM (colocation constraint) and that it can only be started after the DLM is running (order constraint). Additionally, the gfs-control clone should only care about the DLM instances it is paired with, so we need to set the interleave option." #~ msgstr "GFS2还需要一个user-space到kernel的桥梁,每个节点上要运行。所以在这里我们还有一个clone,但是这一次我们还必须指定它只能运行在有DLM的机器上(colocation 约束),它只能在DLM后启动 (order约束)。此外,gfs-control clone应该只关系与其配对的DLM实例,所以我们还要设置interleave 选项" #~ msgid "" #~ "\n" #~ "primitive gfs-control ocf:pacemaker:controld \\\n" #~ "   params daemon=”gfs_controld.pcmk” args=”-g 0” \\\n" #~ "        op monitor interval=\"120s\"\n" #~ "clone gfs-clone gfs-control \\\n" #~ "        meta interleave=\"true\"\n" #~ "colocation gfs-with-dlm inf: gfs-clone dlm-clone\n" #~ "order start-gfs-after-dlm inf: dlm-clone gfs-clone\n" #~ msgstr "" #~ "\n" #~ "primitive gfs-control ocf:pacemaker:controld \\\n" #~ "   params daemon=”gfs_controld.pcmk” args=”-g 0” \\\n" #~ "        op monitor interval=\"120s\"\n" #~ "clone gfs-clone gfs-control \\\n" #~ "        meta interleave=\"true\"\n" #~ "colocation gfs-with-dlm inf: gfs-clone dlm-clone\n" #~ "order start-gfs-after-dlm inf: dlm-clone gfs-clone\n" #~ msgid "" #~ "\n" #~ "primitive WebData ocf:linbit:drbd \\\n" #~ "        params drbd_resource=\"wwwdata\" \\\n" #~ "        op monitor interval=\"60s\"\n" #~ "ms WebDataClone WebData \\\n" #~ "        meta master-max=\"2\" master-node-max=\"1\" clone-max=\"2\" clone-node-max=\"1\" notify=\"true\"\n" #~ msgstr "" #~ "\n" #~ "primitive WebData ocf:linbit:drbd \\\n" #~ "        params drbd_resource=\"wwwdata\" \\\n" #~ "        op monitor interval=\"60s\"\n" #~ "ms WebDataClone WebData \\\n" #~ "        meta master-max=\"2\" master-node-max=\"1\" clone-max=\"2\" clone-node-max=\"1\" notify=\"true\"\n" #~ msgid "" #~ "\n" #~ "primitive WebFS ocf:heartbeat:Filesystem \\\n" #~ "        params device=\"/dev/drbd/by-res/wwwdata\" directory=\"/var/www/html\" fstype=”gfs2”\n" #~ "clone WebFSClone WebFS\n" #~ "colocation WebFS-with-gfs-control inf: WebFSClone gfs-clone\n" #~ "colocation fs_on_drbd inf: WebFSClone WebDataClone:Master\n" #~ "order WebFS-after-WebData inf: WebDataClone:promote WebFSClone:start\n" #~ "order start-WebFS-after-gfs-control inf: gfs-clone WebFSClone\n" #~ msgstr "" #~ "\n" #~ "primitive WebFS ocf:heartbeat:Filesystem \\\n" #~ "        params device=\"/dev/drbd/by-res/wwwdata\" directory=\"/var/www/html\" fstype=”gfs2”\n" #~ "clone WebFSClone WebFS\n" #~ "colocation WebFS-with-gfs-control inf: WebFSClone gfs-clone\n" #~ "colocation fs_on_drbd inf: WebFSClone WebDataClone:Master\n" #~ "order WebFS-after-WebData inf: WebDataClone:promote WebFSClone:start\n" #~ "order start-WebFS-after-gfs-control inf: gfs-clone WebFSClone\n" #~ msgid "" #~ "\n" #~ "primitive WebSite ocf:heartbeat:apache \\\n" #~ "        params configfile=\"/etc/httpd/conf/httpd.conf\" \\\n" #~ "        op monitor interval=\"1min\"\n" #~ "clone WebSiteClone WebSite\n" #~ "colocation WebSite-with-WebFS inf: WebSiteClone WebFSClone\n" #~ "colocation website-with-ip inf: WebSiteClone WebIP\n" #~ "order apache-after-ip inf: WebIP WebSiteClone\n" #~ "order WebSite-after-WebFS inf: WebFSClone WebSiteClone\n" #~ msgstr "" #~ "\n" #~ "primitive WebSite ocf:heartbeat:apache \\\n" #~ "        params configfile=\"/etc/httpd/conf/httpd.conf\" \\\n" #~ "        op monitor interval=\"1min\"\n" #~ "clone WebSiteClone WebSite\n" #~ "colocation WebSite-with-WebFS inf: WebSiteClone WebFSClone\n" #~ "colocation website-with-ip inf: WebSiteClone WebIP\n" #~ "order apache-after-ip inf: WebIP WebSiteClone\n" #~ "order WebSite-after-WebFS inf: WebFSClone WebSiteClone\n" pacemaker-master/doc/Clusters_from_Scratch/zh-CN/Ap-Corosync-Conf.mo000066400000000000000000000113211217637305600256460ustar00rootroot000000000000004L`a "  # Please read the Corosync.conf.5 manual page compatibility: whitetank aisexec {         # Run as root - this is necessary to be able to manage resources with Pacemaker         user:        root         group:        root } service {         # Load the Pacemaker Cluster Resource Manager         ver:       0         name:      pacemaker         use_mgmtd: no         use_logd:  no } totem {         version: 2         # How long before declaring a token lost (ms)         token:          5000         # How many token retransmits before forming a new configuration         token_retransmits_before_loss_const: 10         # How long to wait for join messages in the membership protocol (ms)         join:           1000         # How long to wait for consensus to be achieved before starting a new         # round of membership configuration (ms)         consensus:      6000         # Turn off the virtual synchrony filter         vsftype:        none         # Number of messages that may be sent by one processor on receipt of the token         max_messages:   20         # Stagger sending the node join messages by 1..send_join ms         send_join: 45         # Limit generated nodeids to 31-bits (positive signed integers)         clear_node_high_bit: yes         # Disable encryption         secauth:        off         # How many threads to use for encryption/decryption         threads:           0         # Optionally assign a fixed node id (integer)         # nodeid:         1234         interface {                 ringnumber: 0                 # The following values need to be set based on your environment                 bindnetaddr: 192.168.122.0                 mcastaddr: 226.94.1.1                 mcastport: 4000         } } logging {         debug: off         fileline: off         to_syslog: yes         to_stderr: off         syslog_facility: daemon         timestamp: on } amf {         mode: disabled } Sample Corosync.confProject-Id-Version: 0 POT-Creation-Date: 2010-12-15T23:32:36 PO-Revision-Date: 2010-12-15 23:35+0800 Last-Translator: Charlie Chen Language-Team: None Language: MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit # Please read the Corosync.conf.5 manual page compatibility: whitetank aisexec {         # Run as root - this is necessary to be able to manage resources with Pacemaker         user:        root         group:        root } service {         # Load the Pacemaker Cluster Resource Manager         ver:       0         name:      pacemaker         use_mgmtd: no         use_logd:  no } totem {         version: 2         # How long before declaring a token lost (ms)         token:          5000         # How many token retransmits before forming a new configuration         token_retransmits_before_loss_const: 10         # How long to wait for join messages in the membership protocol (ms)         join:           1000         # How long to wait for consensus to be achieved before starting a new         # round of membership configuration (ms)         consensus:      6000         # Turn off the virtual synchrony filter         vsftype:        none         # Number of messages that may be sent by one processor on receipt of the token         max_messages:   20         # Stagger sending the node join messages by 1..send_join ms         send_join: 45         # Limit generated nodeids to 31-bits (positive signed integers)         clear_node_high_bit: yes         # Disable encryption         secauth:        off         # How many threads to use for encryption/decryption         threads:           0         # Optionally assign a fixed node id (integer)         # nodeid:         1234         interface {                 ringnumber: 0                 # The following values need to be set based on your environment                 bindnetaddr: 192.168.122.0                 mcastaddr: 226.94.1.1                 mcastport: 4000         } } logging {         debug: off         fileline: off         to_syslog: yes         to_stderr: off         syslog_facility: daemon         timestamp: on } amf {         mode: disabled } Corosync.conf 样例pacemaker-master/doc/Clusters_from_Scratch/zh-CN/Ap-Corosync-Conf.po000066400000000000000000000146471217637305600256670ustar00rootroot00000000000000# # AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: 0\n" "POT-Creation-Date: 2012-10-17T05:19:03\n" "PO-Revision-Date: 2010-12-15 23:35+0800\n" "Last-Translator: Charlie Chen \n" "Language-Team: None\n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. Tag: title #, fuzzy, no-c-format msgid "Sample Corosync Configuration" msgstr "Corosync.conf 样例" #. Tag: title #, no-c-format msgid "Sample corosync.conf for two-node cluster using a node list." msgstr "" #. Tag: literallayout #, no-c-format msgid "" "# Please read the corosync.conf.5 manual page\n" "totem {\n" "version: 2\n" "secauth: off\n" "cluster_name: mycluster\n" "transport: udpu\n" "}\n" "\n" "nodelist {\n" " node {\n" " ring0_addr: pcmk-1\n" " nodeid: 1\n" " }\n" " node {\n" " ring0_addr: pcmk-2\n" " nodeid: 2\n" " }\n" "}\n" "\n" "quorum {\n" " provider: corosync_votequorum\n" "}\n" "\n" "logging {\n" " to_syslog: yes\n" "}" msgstr "" #~ msgid "" #~ "\n" #~ "# Please read the Corosync.conf.5 manual page\n" #~ "compatibility: whitetank\n" #~ "\n" #~ "aisexec {\n" #~ "        # Run as root - this is necessary to be able to manage resources with Pacemaker\n" #~ "        user:        root\n" #~ "        group:        root\n" #~ "}\n" #~ "\n" #~ "service {\n" #~ "        # Load the Pacemaker Cluster Resource Manager\n" #~ "        ver:       0\n" #~ "        name:      pacemaker\n" #~ "        use_mgmtd: no\n" #~ "        use_logd:  no\n" #~ "}\n" #~ "\n" #~ "totem {\n" #~ "        version: 2\n" #~ "\n" #~ "        # How long before declaring a token lost (ms)\n" #~ "        token:          5000\n" #~ "\n" #~ "        # How many token retransmits before forming a new configuration\n" #~ "        token_retransmits_before_loss_const: 10\n" #~ "\n" #~ "        # How long to wait for join messages in the membership protocol (ms)\n" #~ "        join:           1000\n" #~ "\n" #~ "        # How long to wait for consensus to be achieved before starting a new\n" #~ "        # round of membership configuration (ms)\n" #~ "        consensus:      6000\n" #~ "\n" #~ "        # Turn off the virtual synchrony filter\n" #~ "        vsftype:        none\n" #~ "\n" #~ "        # Number of messages that may be sent by one processor on receipt of the token\n" #~ "        max_messages:   20\n" #~ "\n" #~ "        # Stagger sending the node join messages by 1..send_join ms\n" #~ "        send_join: 45\n" #~ "\n" #~ "        # Limit generated nodeids to 31-bits (positive signed integers)\n" #~ "        clear_node_high_bit: yes\n" #~ "\n" #~ "        # Disable encryption\n" #~ "        secauth:        off\n" #~ "\n" #~ "        # How many threads to use for encryption/decryption\n" #~ "        threads:           0\n" #~ "\n" #~ "        # Optionally assign a fixed node id (integer)\n" #~ "        # nodeid:         1234\n" #~ "\n" #~ "        interface {\n" #~ "                ringnumber: 0\n" #~ "\n" #~ "                # The following values need to be set based on your environment\n" #~ "                bindnetaddr: 192.168.122.0\n" #~ "                mcastaddr: 226.94.1.1\n" #~ "                mcastport: 4000\n" #~ "        }\n" #~ "}\n" #~ "\n" #~ "logging {\n" #~ "        debug: off\n" #~ "        fileline: off\n" #~ "        to_syslog: yes\n" #~ "        to_stderr: off\n" #~ "        syslog_facility: daemon\n" #~ "        timestamp: on\n" #~ "}\n" #~ "\n" #~ "amf {\n" #~ "        mode: disabled\n" #~ "}\n" #~ msgstr "" #~ "\n" #~ "# Please read the Corosync.conf.5 manual page\n" #~ "compatibility: whitetank\n" #~ "\n" #~ "aisexec {\n" #~ "        # Run as root - this is necessary to be able to manage resources with Pacemaker\n" #~ "        user:        root\n" #~ "        group:        root\n" #~ "}\n" #~ "\n" #~ "service {\n" #~ "        # Load the Pacemaker Cluster Resource Manager\n" #~ "        ver:       0\n" #~ "        name:      pacemaker\n" #~ "        use_mgmtd: no\n" #~ "        use_logd:  no\n" #~ "}\n" #~ "\n" #~ "totem {\n" #~ "        version: 2\n" #~ "\n" #~ "        # How long before declaring a token lost (ms)\n" #~ "        token:          5000\n" #~ "\n" #~ "        # How many token retransmits before forming a new configuration\n" #~ "        token_retransmits_before_loss_const: 10\n" #~ "\n" #~ "        # How long to wait for join messages in the membership protocol (ms)\n" #~ "        join:           1000\n" #~ "\n" #~ "        # How long to wait for consensus to be achieved before starting a new\n" #~ "        # round of membership configuration (ms)\n" #~ "        consensus:      6000\n" #~ "\n" #~ "        # Turn off the virtual synchrony filter\n" #~ "        vsftype:        none\n" #~ "\n" #~ "        # Number of messages that may be sent by one processor on receipt of the token\n" #~ "        max_messages:   20\n" #~ "\n" #~ "        # Stagger sending the node join messages by 1..send_join ms\n" #~ "        send_join: 45\n" #~ "\n" #~ "        # Limit generated nodeids to 31-bits (positive signed integers)\n" #~ "        clear_node_high_bit: yes\n" #~ "\n" #~ "        # Disable encryption\n" #~ "        secauth:        off\n" #~ "\n" #~ "        # How many threads to use for encryption/decryption\n" #~ "        threads:           0\n" #~ "\n" #~ "        # Optionally assign a fixed node id (integer)\n" #~ "        # nodeid:         1234\n" #~ "\n" #~ "        interface {\n" #~ "                ringnumber: 0\n" #~ "\n" #~ "                # The following values need to be set based on your environment\n" #~ "                bindnetaddr: 192.168.122.0\n" #~ "                mcastaddr: 226.94.1.1\n" #~ "                mcastport: 4000\n" #~ "        }\n" #~ "}\n" #~ "\n" #~ "logging {\n" #~ "        debug: off\n" #~ "        fileline: off\n" #~ "        to_syslog: yes\n" #~ "        to_stderr: off\n" #~ "        syslog_facility: daemon\n" #~ "        timestamp: on\n" #~ "}\n" #~ "\n" #~ "amf {\n" #~ "        mode: disabled\n" #~ "}\n" pacemaker-master/doc/Clusters_from_Scratch/zh-CN/Ap-Reading.mo000066400000000000000000000033041217637305600245370ustar00rootroot00000000000000 d %$%KJE YCS%Z$KE UTb  Cluster CommandsCorosyncProject Websitehttp://www.clusterlabs.orghttp://www.corosync.orghttp://www.novell.com/documentation/sles11/book_sleha/index.html?page=/documentation/sles11/book_sleha/data/book_sleha.htmlA comprehensive guide to cluster commands has been written by Novell and can be found at:Further ReadingProject-Id-Version: 0 POT-Creation-Date: 2010-09-22T10:48:14 PO-Revision-Date: 2010-12-15 20:03+0800 Last-Translator: Charlie Chen Language-Team: None MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cluster CommandsCorosyncProject Websitehttp://www.clusterlabs.orghttp://www.corosync.orghttp://www.novell.com/documentation/sles11/book_sleha/index.html?page=/documentation/sles11/book_sleha/data/book_sleha.html一个综合的指南,包含了Novell所写的集群命令,可以在这里被找到:延伸阅读pacemaker-master/doc/Clusters_from_Scratch/zh-CN/Ap-Reading.po000066400000000000000000000037521217637305600245510ustar00rootroot00000000000000# # AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: 0\n" "POT-Creation-Date: 2012-10-17T05:19:03\n" "PO-Revision-Date: 2010-12-15 20:03+0800\n" "Last-Translator: Charlie Chen \n" "Language-Team: None\n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. Tag: title #, no-c-format msgid "Further Reading" msgstr "延伸阅读" #. Tag: para #, fuzzy, no-c-format msgid "Project Website http://www.clusterlabs.org" msgstr "http://www.clusterlabs.org" #. Tag: para #, fuzzy, no-c-format msgid "Cluster Commands A comprehensive guide to cluster commands has been written by SuSE and can be found at: http://www.suse.com/documentation/sle_ha/book_sleha/?page=/documentation/sle_ha/book_sleha/data/book_sleha.html" msgstr "http://www.novell.com/documentation/sles11/book_sleha/index.html?page=/documentation/sles11/book_sleha/data/book_sleha.html" #. Tag: para #, fuzzy, no-c-format msgid "Corosync http://www.corosync.org" msgstr "http://www.corosync.org" #~ msgid "Project Website" #~ msgstr "Project Website" #~ msgid "Cluster Commands" #~ msgstr "Cluster Commands" #~ msgid "A comprehensive guide to cluster commands has been written by Novell and can be found at:" #~ msgstr "一个综合的指南,包含了Novell所写的集群命令,可以在这里被找到:" #~ msgid "Corosync" #~ msgstr "Corosync" pacemaker-master/doc/Clusters_from_Scratch/zh-CN/Author_Group.mo000066400000000000000000000011501217637305600252430ustar00rootroot00000000000000\  &-5HOU ]AndrewBeekhofItalian translationPrimary authorRaoulRed HatScarazziniProject-Id-Version: 0 POT-Creation-Date: 2010-12-15T23:32:36 PO-Revision-Date: 2010-12-15 23:35+0800 Last-Translator: Charlie Chen Language-Team: None Language: MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit AndrewBeekhof意大利语翻译作者RaoulRed HatScarazzinipacemaker-master/doc/Clusters_from_Scratch/zh-CN/Author_Group.po000066400000000000000000000020461217637305600252530ustar00rootroot00000000000000# # AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: 0\n" "POT-Creation-Date: 2012-10-17T05:19:03\n" "PO-Revision-Date: 2010-12-15 23:35+0800\n" "Last-Translator: Charlie Chen \n" "Language-Team: None\n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. Tag: firstname #, no-c-format msgid "Andrew" msgstr "Andrew" #. Tag: surname #, no-c-format msgid "Beekhof" msgstr "Beekhof" #. Tag: orgname #, no-c-format msgid "Red Hat" msgstr "Red Hat" #. Tag: contrib #, no-c-format msgid "Primary author" msgstr "作者" #. Tag: firstname #, no-c-format msgid "Raoul" msgstr "Raoul" #. Tag: surname #, no-c-format msgid "Scarazzini" msgstr "Scarazzini" #. Tag: contrib #, no-c-format msgid "Italian translation" msgstr "意大利语翻译" #. Tag: firstname #, no-c-format msgid "Dan" msgstr "" #. Tag: surname #, no-c-format msgid "Frîncu" msgstr "" #. Tag: contrib #, fuzzy, no-c-format msgid "Romanian translation" msgstr "意大利语翻译" pacemaker-master/doc/Clusters_from_Scratch/zh-CN/Book_Info.mo000066400000000000000000000043051217637305600244770ustar00rootroot00000000000000 0:1l6<76.e 5)?Ai62+,D3q ("2   &DISTRO; &DISTRO_VERSION; as the host operating systemClusters from ScratchCorosync to provide messaging and membership services,Creating Active/Passive and Active/Active Clusters on FedoraDRBD as a cost-effective alternative to shared storage,GFS2 as the cluster filesystem (in active/active mode)Given the graphical nature of the Fedora install process, a number of screenshots are included. However the guide is primarily composed of commands, the reasons for executing them and their expected outputs.PacemakerPacemaker to perform resource management,The crm shell for displaying the configuration and making changesThe example cluster will use:The purpose of this document is to provide a start-to-finish guide to building an example active/passive cluster with Pacemaker and show how it can be converted to an active/active one.Project-Id-Version: 0 POT-Creation-Date: 2010-12-15T23:32:36 PO-Revision-Date: 2010-12-15 23:35+0800 Last-Translator: Charlie Chen Language-Team: None Language: MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit &DISTRO; &DISTRO_VERSION; 作为基本操作系统从头开始搭建集群Corosync作为通信层和提供关系管理服务在Fedora上面创建主/主和主备集群DRBD 作为一个经济的共享存储方案GFS2 作为集群文件系统(主/主模式中)虽然给出了图形化安装Fedora的过程,并且有很多截图,但是本文的主要是靠命令来操作,包括为什么要运行这个命令和这些操作产生的结果。(译者注:本文中基本是crm shell来操作的,这里应该是老版本文档的遗留)PacemakerPacemaker来实现资源管理crm shell 来显示并修改配置文件示例集群会使用以下软件:本文档的主要目的是提供一站式指南,教您如何使用Pacemaker创建一个主/备模式的集群并把它转换到主/主模式。pacemaker-master/doc/Clusters_from_Scratch/zh-CN/Book_Info.po000066400000000000000000000050171217637305600245030ustar00rootroot00000000000000# # AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: 0\n" "POT-Creation-Date: 2012-10-17T05:19:03\n" "PO-Revision-Date: 2010-12-15 23:35+0800\n" "Last-Translator: Charlie Chen \n" "Language-Team: None\n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. Tag: title #, no-c-format msgid "Clusters from Scratch" msgstr "从头开始搭建集群" #. Tag: subtitle #, no-c-format msgid "Creating Active/Passive and Active/Active Clusters on Fedora" msgstr "在Fedora上面创建主/主和主备集群" #. Tag: productname #, no-c-format msgid "Pacemaker" msgstr "Pacemaker" #. Tag: para #, no-c-format msgid "The purpose of this document is to provide a start-to-finish guide to building an example active/passive cluster with Pacemaker and show how it can be converted to an active/active one." msgstr "本文档的主要目的是提供一站式指南,教您如何使用Pacemaker创建一个主/备模式的集群并把它转换到主/主模式。" #. Tag: para #, no-c-format msgid "The example cluster will use:" msgstr "示例集群会使用以下软件:" #. Tag: para #, fuzzy, no-c-format msgid "&DISTRO; &DISTRO_VERSION; as the host operating system" msgstr "&DISTRO; &DISTRO_VERSION; 作为基本操作系统" #. Tag: para #, no-c-format msgid "Corosync to provide messaging and membership services," msgstr "Corosync作为通信层和提供关系管理服务" #. Tag: para #, no-c-format msgid "Pacemaker to perform resource management," msgstr "Pacemaker来实现资源管理" #. Tag: para #, no-c-format msgid "DRBD as a cost-effective alternative to shared storage," msgstr "DRBD 作为一个经济的共享存储方案" #. Tag: para #, no-c-format msgid "GFS2 as the cluster filesystem (in active/active mode)" msgstr "GFS2 作为集群文件系统(主/主模式中)" #. Tag: para #, no-c-format msgid "Given the graphical nature of the Fedora install process, a number of screenshots are included. However the guide is primarily composed of commands, the reasons for executing them and their expected outputs." msgstr "虽然给出了图形化安装Fedora的过程,并且有很多截图,但是本文的主要是靠命令来操作,包括为什么要运行这个命令和这些操作产生的结果。(译者注:本文中基本是crm shell来操作的,这里应该是老版本文档的遗留)" #~ msgid "The crm shell for displaying the configuration and making changes" #~ msgstr "crm shell 来显示并修改配置文件" pacemaker-master/doc/Clusters_from_Scratch/zh-CN/Ch-Active-Active.mo000066400000000000000000001574161217637305600256220ustar00rootroot00000000000000GTa hn]5e k/ U3t=AEA] ASKh $LYWZ]Z^n^^(j__```%`Raja:bc#cde2eeVfhfJg h;hh h'i (i IiuVi i+i2j7Ljjj<kr[kk=lvnvznnmpM\qq=^rTrBr4sNsbbst uh"]wneNk (ϯEc] h غYA_ 34T7Of$'N%m3zU2X~}@= V(cM"297l .;ZjjijREm}317eB51;&/ *<B2D87#>0F6"C(G+?E ,$!34 A-.:9 =) '@% [root@pcmk-1 ~]# configure clone WebIP ClusterIP  \         meta globally-unique=”true” clone-max=”2” clone-node-max=”2” [root@pcmk-1 ~]# crm crm(live)# cib new active INFO: active shadow CIB created crm(active)# configure clone WebIP ClusterIP  \         meta globally-unique=”true” clone-max=”2” clone-node-max=”2” crm(active)# configure show node pcmk-1 node pcmk-2 primitive WebData ocf:linbit:drbd \         params drbd_resource="wwwdata" \         op monitor interval="60s" primitive WebFS ocf:heartbeat:Filesystem \         params device="/dev/drbd/by-res/wwwdata" directory="/var/www/html" fstype=”gfs2” primitive WebSite ocf:heartbeat:apache \         params configfile="/etc/httpd/conf/httpd.conf" \         op monitor interval="1min" primitive ClusterIP ocf:heartbeat:IPaddr2 \         params ip=”192.168.122.101” cidr_netmask=”32” clusterip_hash=”sourceip” \         op monitor interval="30s" primitive dlm ocf:pacemaker:controld \         op monitor interval="120s" primitive gfs-control ocf:pacemaker:controld \    params daemon=”gfs_controld.pcmk” args=”-g 0” \         op monitor interval="120s" ms WebDataClone WebData \         meta master-max="1" master-node-max="1" clone-max="2" clone-node-max="1" notify="true" clone WebIP ClusterIP \ meta globally-unique=”true” clone-max=”2” clone-node-max=”2” clone dlm-clone dlm \         meta interleave="true" clone gfs-clone gfs-control \         meta interleave="true" colocation WebFS-with-gfs-control inf: WebFS gfs-clone colocation WebSite-with-WebFS inf: WebSite WebFS colocation fs_on_drbd inf: WebFS WebDataClone:Master colocation gfs-with-dlm inf: gfs-clone dlm-clone colocation website-with-ip inf: WebSite WebIP order WebFS-after-WebData inf: WebDataClone:promote WebFS:start order WebSite-after-WebFS inf: WebFS WebSite order apache-after-ip inf: WebIP WebSite order start-WebFS-after-gfs-control inf: gfs-clone WebFS order start-gfs-after-dlm inf: dlm-clone gfs-clone property $id="cib-bootstrap-options" \         dc-version="1.0.5-462f1569a43740667daf7b0f6b521742e9eb8fa7" \         cluster-infrastructure="openais" \         expected-quorum-votes=”2” \         stonith-enabled="false" \         no-quorum-policy="ignore" rsc_defaults $id="rsc-options" \         resource-stickiness=”100” [root@pcmk-1 ~]# crm [root@pcmk-1 ~]# cib new active [root@pcmk-1 ~]# crm crm(live)# cib new GFS2 INFO: GFS2 shadow CIB created crm(GFS2)# configure delete WebFS crm(GFS2)# configure primitive WebFS ocf:heartbeat:Filesystem params device="/dev/drbd/by-res/wwwdata" directory="/var/www/html" fstype=”gfs2” [root@pcmk-1 ~]# crm crm(live)# cib new gfs-glue --force INFO: gfs-glue shadow CIB created crm(gfs-glue)# configure primitive gfs-control ocf:pacemaker:controld params daemon=gfs_controld.pcmk args="-g 0" op monitor interval=120s crm(gfs-glue)# configure clone gfs-clone gfs-control meta interleave=true [root@pcmk-1 ~]# crm crm(live)# cib new stack-glue INFO: stack-glue shadow CIB created crm(stack-glue)# configure primitive dlm ocf:pacemaker:controld op monitor interval=120s crm(stack-glue)# configure clone dlm-clone dlm meta interleave=true crm(stack-glue)# configure show xml crm(stack-glue)# configure show node pcmk-1 node pcmk-2 primitive WebData ocf:linbit:drbd \         params drbd_resource="wwwdata" \         op monitor interval="60s" primitive WebFS ocf:heartbeat:Filesystem \         params device="/dev/drbd/by-res/wwwdata" directory="/var/www/html" fstype="ext4" primitive WebSite ocf:heartbeat:apache \         params configfile="/etc/httpd/conf/httpd.conf" \         op monitor interval="1min" primitive ClusterIP ocf:heartbeat:IPaddr2 \         params ip="192.168.122.101" cidr_netmask="32" \         op monitor interval="30s" primitive dlm ocf:pacemaker:controld \ op monitor interval="120s" ms WebDataClone WebData \         meta master-max="1" master-node-max="1" clone-max="2" clone-node-max="1" notify="true" clone dlm-clone dlm \ meta interleave="true" location prefer-pcmk-1 WebSite 50: pcmk-1 colocation WebSite-with-WebFS inf: WebSite WebFS colocation fs_on_drbd inf: WebFS WebDataClone:Master colocation website-with-ip inf: WebSite ClusterIP order WebFS-after-WebData inf: WebDataClone:promote WebFS:start order WebSite-after-WebFS inf: WebFS WebSite order apache-after-ip inf: ClusterIP WebSite property $id="cib-bootstrap-options" \         dc-version="1.0.5-462f1569a43740667daf7b0f6b521742e9eb8fa7" \         cluster-infrastructure="openais" \         expected-quorum-votes=”2” \         stonith-enabled="false" \         no-quorum-policy="ignore" rsc_defaults $id="rsc-options" \         resource-stickiness=”100” [root@pcmk-1 ~]# crm_resource --resource WebFS --set-parameter target-role --meta --parameter-value Stopped [root@pcmk-1 ~]# crm_mon ============ Last updated: Thu Sep  3 15:18:06 2009 Stack: openais Current DC: pcmk-1 - partition with quorum Version: 1.0.5-462f1569a43740667daf7b0f6b521742e9eb8fa7 2 Nodes configured, 2 expected votes 6 Resources configured. ============ Online: [ pcmk-1 pcmk-2 ] Master/Slave Set: WebDataClone         Masters: [ pcmk-1 ]         Slaves: [ pcmk-2 ] ClusterIP        (ocf::heartbeat:IPaddr):        Started pcmk-1 Clone Set: dlm-clone         Started: [ pcmk-2 pcmk-1 ] Clone Set: gfs-clone         Started: [ pcmk-2 pcmk-1 ] [root@pcmk-1 ~]# mount /dev/drbd1 /mnt/ [root@pcmk-1 ~]# cat <<-END >/mnt/index.html <html> <body>My Test Site - GFS2</body> </html> END [root@pcmk-1 ~]# umount /dev/drbd1 [root@pcmk-1 ~]# drbdadm verify wwwdata [root@pcmk-1 ~]# [root@pcmk-1 ~]# yum install -y gfs2-utils gfs-pcmk Setting up Install Process Resolving Dependencies --> Running transaction check ---> Package gfs-pcmk.x86_64 0:3.0.5-2.fc12 set to be updated --> Processing Dependency: libSaCkpt.so.3(OPENAIS_CKPT_B.01.01)(64bit) for package: gfs-pcmk-3.0.5-2.fc12.x86_64 --> Processing Dependency: dlm-pcmk for package: gfs-pcmk-3.0.5-2.fc12.x86_64 --> Processing Dependency: libccs.so.3()(64bit) for package: gfs-pcmk-3.0.5-2.fc12.x86_64 --> Processing Dependency: libdlmcontrol.so.3()(64bit) for package: gfs-pcmk-3.0.5-2.fc12.x86_64 --> Processing Dependency: liblogthread.so.3()(64bit) for package: gfs-pcmk-3.0.5-2.fc12.x86_64 --> Processing Dependency: libSaCkpt.so.3()(64bit) for package: gfs-pcmk-3.0.5-2.fc12.x86_64 ---> Package gfs2-utils.x86_64 0:3.0.5-2.fc12 set to be updated --> Running transaction check ---> Package clusterlib.x86_64 0:3.0.5-2.fc12 set to be updated ---> Package dlm-pcmk.x86_64 0:3.0.5-2.fc12 set to be updated ---> Package openaislib.x86_64 0:1.1.0-1.fc12 set to be updated --> Finished Dependency Resolution Dependencies Resolved ===========================================================================================  Package                Arch               Version                   Repository        Size =========================================================================================== Installing:  gfs-pcmk               x86_64             3.0.5-2.fc12              custom           101 k  gfs2-utils             x86_64             3.0.5-2.fc12              custom           208 k Installing for dependencies:  clusterlib             x86_64             3.0.5-2.fc12              custom            65 k  dlm-pcmk               x86_64             3.0.5-2.fc12              custom            93 k  openaislib             x86_64             1.1.0-1.fc12              fedora            76 k Transaction Summary =========================================================================================== Install       5 Package(s) Upgrade       0 Package(s) Total download size: 541 k Downloading Packages: (1/5): clusterlib-3.0.5-2.fc12.x86_64.rpm                                |  65 kB     00:00 (2/5): dlm-pcmk-3.0.5-2.fc12.x86_64.rpm                                  |  93 kB     00:00 (3/5): gfs-pcmk-3.0.5-2.fc12.x86_64.rpm                                  | 101 kB     00:00 (4/5): gfs2-utils-3.0.5-2.fc12.x86_64.rpm                                | 208 kB     00:00 (5/5): openaislib-1.1.0-1.fc12.x86_64.rpm                                |  76 kB     00:00 ------------------------------------------------------------------------------------------- Total                                                           992 kB/s | 541 kB     00:00 Running rpm_check_debug Running Transaction Test Finished Transaction Test Transaction Test Succeeded Running Transaction   Installing     : clusterlib-3.0.5-2.fc12.x86_64                                       1/5   Installing     : openaislib-1.1.0-1.fc12.x86_64                                       2/5   Installing     : dlm-pcmk-3.0.5-2.fc12.x86_64                                         3/5   Installing     : gfs-pcmk-3.0.5-2.fc12.x86_64                                         4/5   Installing     : gfs2-utils-3.0.5-2.fc12.x86_64                                       5/5 Installed:   gfs-pcmk.x86_64 0:3.0.5-2.fc12                    gfs2-utils.x86_64 0:3.0.5-2.fc12 Dependency Installed:   clusterlib.x86_64 0:3.0.5-2.fc12   dlm-pcmk.x86_64 0:3.0.5-2.fc12   openaislib.x86_64 0:1.1.0-1.fc12   Complete! [root@pcmk-1 x86_64]# crm(GFS2)# cib commit GFS2 INFO: commited 'GFS2' shadow CIB to the cluster crm(GFS2)# quit bye [root@pcmk-1 ~]# crm_mon ============ Last updated: Thu Sep  3 20:49:54 2009 Stack: openais Current DC: pcmk-2 - partition with quorum Version: 1.0.5-462f1569a43740667daf7b0f6b521742e9eb8fa7 2 Nodes configured, 2 expected votes 6 Resources configured. ============ Online: [ pcmk-1 pcmk-2 ] WebSite (ocf::heartbeat:apache):        Started pcmk-2 Master/Slave Set: WebDataClone         Masters: [ pcmk-1 ]         Slaves: [ pcmk-2 ] ClusterIP        (ocf::heartbeat:IPaddr):        Started pcmk-2 Clone Set: dlm-clone         Started: [ pcmk-2 pcmk-1 ] Clone Set: gfs-clone         Started: [ pcmk-2 pcmk-1 ] WebFS (ocf::heartbeat:Filesystem): Started pcmk-1 crm(GFS2)# configure colocation WebSite-with-WebFS inf: WebSite WebFS crm(GFS2)# configure colocation fs_on_drbd inf: WebFS WebDataClone:Master crm(GFS2)# configure order WebFS-after-WebData inf: WebDataClone:promote WebFS:start crm(GFS2)# configure order WebSite-after-WebFS inf: WebFS WebSite crm(GFS2)# configure colocation WebFS-with-gfs-control INFINITY: WebFS gfs-clone crm(GFS2)# configure order start-WebFS-after-gfs-control mandatory: gfs-clone WebFS crm(GFS2)# configure show node pcmk-1 node pcmk-2 primitive WebData ocf:linbit:drbd \         params drbd_resource="wwwdata" \         op monitor interval="60s" primitive WebFS ocf:heartbeat:Filesystem \ params device="/dev/drbd/by-res/wwwdata" directory="/var/www/html" fstype=”gfs2” primitive WebSite ocf:heartbeat:apache \         params configfile="/etc/httpd/conf/httpd.conf" \         op monitor interval="1min" primitive ClusterIP ocf:heartbeat:IPaddr2 \         params ip="192.168.122.101" cidr_netmask="32" \         op monitor interval="30s" primitive dlm ocf:pacemaker:controld \         op monitor interval="120s" primitive gfs-control ocf:pacemaker:controld \    params daemon=”gfs_controld.pcmk” args=”-g 0” \         op monitor interval="120s" ms WebDataClone WebData \         meta master-max="1" master-node-max="1" clone-max="2" clone-node-max="1" notify="true" clone dlm-clone dlm \         meta interleave="true" clone gfs-clone gfs-control \         meta interleave="true" colocation WebFS-with-gfs-control inf: WebFS gfs-clone colocation WebSite-with-WebFS inf: WebSite WebFS colocation fs_on_drbd inf: WebFS WebDataClone:Master colocation gfs-with-dlm inf: gfs-clone dlm-clone colocation website-with-ip inf: WebSite ClusterIP order WebFS-after-WebData inf: WebDataClone:promote WebFS:start order WebSite-after-WebFS inf: WebFS WebSite order apache-after-ip inf: ClusterIP WebSite order start-WebFS-after-gfs-control inf: gfs-clone WebFS order start-gfs-after-dlm inf: dlm-clone gfs-clone property $id="cib-bootstrap-options" \         dc-version="1.0.5-462f1569a43740667daf7b0f6b521742e9eb8fa7" \         cluster-infrastructure="openais" \         expected-quorum-votes=”2” \         stonith-enabled="false" \         no-quorum-policy="ignore" rsc_defaults $id="rsc-options" \         resource-stickiness=”100” crm(active)# cib commit active INFO: commited 'active' shadow CIB to the cluster crm(active)# quit bye [root@pcmk-1 ~]# crm_mon ============ Last updated: Thu Sep  3 21:37:27 2009 Stack: openais Current DC: pcmk-2 - partition with quorum Version: 1.0.5-462f1569a43740667daf7b0f6b521742e9eb8fa7 2 Nodes configured, 2 expected votes 6 Resources configured. ============ Online: [ pcmk-1 pcmk-2 ] Master/Slave Set: WebDataClone         Masters: [ pcmk-1 pcmk-2 ] Clone Set: dlm-clone         Started: [ pcmk-2 pcmk-1 ] Clone Set: gfs-clone         Started: [ pcmk-2 pcmk-1 ] Clone Set: WebIP Started: [ pcmk-1 pcmk-2 ] Clone Set: WebFSClone Started: [ pcmk-1 pcmk-2 ] Clone Set: WebSiteClone Started: [ pcmk-1 pcmk-2 ] crm(active)# configure clone WebFSClone WebFS crm(active)# configure clone WebSiteClone WebSite crm(active)# configure edit WebDataClone crm(active)# configure show node pcmk-1 node pcmk-2 primitive WebData ocf:linbit:drbd \         params drbd_resource="wwwdata" \         op monitor interval="60s" primitive WebFS ocf:heartbeat:Filesystem \         params device="/dev/drbd/by-res/wwwdata" directory="/var/www/html" fstype=”gfs2” primitive WebSite ocf:heartbeat:apache \         params configfile="/etc/httpd/conf/httpd.conf" \         op monitor interval="1min" primitive ClusterIP ocf:heartbeat:IPaddr2 \         params ip=”192.168.122.101” cidr_netmask=”32” clusterip_hash=”sourceip” \         op monitor interval="30s" primitive dlm ocf:pacemaker:controld \         op monitor interval="120s" primitive gfs-control ocf:pacemaker:controld \    params daemon=”gfs_controld.pcmk” args=”-g 0” \         op monitor interval="120s" ms WebDataClone WebData \         meta master-max="2" master-node-max="1" clone-max="2" clone-node-max="1" notify="true" clone WebFSClone WebFS clone WebIP ClusterIP  \         meta globally-unique=”true” clone-max=”2” clone-node-max=”2” clone WebSiteClone WebSite clone dlm-clone dlm \         meta interleave="true" clone gfs-clone gfs-control \         meta interleave="true" colocation WebFS-with-gfs-control inf: WebFSClone gfs-clone colocation WebSite-with-WebFS inf: WebSiteClone WebFSClone colocation fs_on_drbd inf: WebFSClone WebDataClone:Master colocation gfs-with-dlm inf: gfs-clone dlm-clone colocation website-with-ip inf: WebSiteClone WebIP order WebFS-after-WebData inf: WebDataClone:promote WebFSClone:start order WebSite-after-WebFS inf: WebFSClone WebSiteClone order apache-after-ip inf: WebIP WebSiteClone order start-WebFS-after-gfs-control inf: gfs-clone WebFSClone order start-gfs-after-dlm inf: dlm-clone gfs-clone property $id="cib-bootstrap-options" \         dc-version="1.0.5-462f1569a43740667daf7b0f6b521742e9eb8fa7" \         cluster-infrastructure="openais" \         expected-quorum-votes=”2” \         stonith-enabled="false" \         no-quorum-policy="ignore" rsc_defaults $id="rsc-options" \         resource-stickiness=”100” crm(gfs-glue)# configure colocation gfs-with-dlm INFINITY: gfs-clone dlm-clone crm(gfs-glue)# configure order start-gfs-after-dlm mandatory: dlm-clone gfs-clone crm(gfs-glue)# configure show node pcmk-1 node pcmk-2 primitive WebData ocf:linbit:drbd \         params drbd_resource="wwwdata" \         op monitor interval="60s" primitive WebFS ocf:heartbeat:Filesystem \         params device="/dev/drbd/by-res/wwwdata" directory="/var/www/html" fstype="ext4" primitive WebSite ocf:heartbeat:apache \         params configfile="/etc/httpd/conf/httpd.conf" \         op monitor interval="1min" primitive ClusterIP ocf:heartbeat:IPaddr2 \         params ip="192.168.122.101" cidr_netmask="32" \         op monitor interval="30s" primitive dlm ocf:pacemaker:controld \         op monitor interval="120s" primitive gfs-control ocf:pacemaker:controld \ params daemon=”gfs_controld.pcmk” args=”-g 0” \ op monitor interval="120s" ms WebDataClone WebData \         meta master-max="1" master-node-max="1" clone-max="2" clone-node-max="1" notify="true" clone dlm-clone dlm \         meta interleave="true" clone gfs-clone gfs-control \ meta interleave="true" location prefer-pcmk-1 WebSite 50: pcmk-1 colocation WebSite-with-WebFS inf: WebSite WebFS colocation fs_on_drbd inf: WebFS WebDataClone:Master colocation gfs-with-dlm inf: gfs-clone dlm-clone colocation website-with-ip inf: WebSite ClusterIP order WebFS-after-WebData inf: WebDataClone:promote WebFS:start order WebSite-after-WebFS inf: WebFS WebSite order apache-after-ip inf: ClusterIP WebSite order start-gfs-after-dlm inf: dlm-clone gfs-clone property $id="cib-bootstrap-options" \         dc-version="1.0.5-462f1569a43740667daf7b0f6b521742e9eb8fa7" \         cluster-infrastructure="openais" \         expected-quorum-votes=”2” \         stonith-enabled="false" \         no-quorum-policy="ignore" rsc_defaults $id="rsc-options" \         resource-stickiness=”100” crm(gfs-glue)# cib commit gfs-glue INFO: commited 'gfs-glue' shadow CIB to the cluster crm(gfs-glue)# quit bye [root@pcmk-1 ~]# crm_mon ============ Last updated: Thu Sep  3 20:49:54 2009 Stack: openais Current DC: pcmk-2 - partition with quorum Version: 1.0.5-462f1569a43740667daf7b0f6b521742e9eb8fa7 2 Nodes configured, 2 expected votes 6 Resources configured. ============ Online: [ pcmk-1 pcmk-2 ] WebSite (ocf::heartbeat:apache):        Started pcmk-2 Master/Slave Set: WebDataClone         Masters: [ pcmk-1 ]         Slaves: [ pcmk-2 ] ClusterIP        (ocf::heartbeat:IPaddr):        Started pcmk-2 Clone Set: dlm-clone         Started: [ pcmk-2 pcmk-1 ] Clone Set: gfs-clone Started: [ pcmk-2 pcmk-1 ] WebFS   (ocf::heartbeat:Filesystem):    Started pcmk-1 crm(stack-glue)# cib commit stack-glue INFO: commited 'stack-glue' shadow CIB to the cluster crm(stack-glue)# quit bye [root@pcmk-1 ~]# crm_mon ============ Last updated: Thu Sep  3 20:49:54 2009 Stack: openais Current DC: pcmk-2 - partition with quorum Version: 1.0.5-462f1569a43740667daf7b0f6b521742e9eb8fa7 2 Nodes configured, 2 expected votes 5 Resources configured. ============ Online: [ pcmk-1 pcmk-2 ] WebSite (ocf::heartbeat:apache):        Started pcmk-2 Master/Slave Set: WebDataClone         Masters: [ pcmk-1 ]         Slaves: [ pcmk-2 ] ClusterIP        (ocf::heartbeat:IPaddr):        Started pcmk-2 Clone Set: dlm-clone Started: [ pcmk-2 pcmk-1 ] WebFS   (ocf::heartbeat:Filesystem):    Started pcmk-2 mkfs.gfs2 -p lock_dlm -j 2 -t pcmk:web /dev/drbd1 [root@pcmk-1 ~]# mkfs.gfs2 -t pcmk:web -p lock_dlm -j 2 /dev/vdb This will destroy any data on /dev/vdb. It appears to contain: data Are you sure you want to proceed? [y/n] y Device:                    /dev/vdb Blocksize:                 4096 Device Size                1.00 GB (131072 blocks) Filesystem Size:           1.00 GB (131070 blocks) Journals:                  2 Resource Groups:           2 Locking Protocol:          "lock_dlm" Lock Table:                "pcmk:web" UUID:                      6B776F46-177B-BAF8-2C2B-292C0E078613 [root@pcmk-1 ~]# primitive ClusterIP ocf:heartbeat:IPaddr2 \         params ip="192.168.122.101" cidr_netmask="32" clusterip_hash="sourceip" \         op monitor interval="30s" Add the DLM serviceAdd the GFS2 serviceAlmost everything is in place. Recent versions of DRBD are capable of operating in Primary/Primary mode and the filesystem we’re using is cluster aware. All we need to do now is reconfigure the cluster to take advantage of this.And add the following to the params lineBefore we do anything to the existing partition, we need to make sure it is unmounted. We do this by tell the cluster to stop the WebFS resource. This will ensure that other resources (in our case, Apache) using WebFS are not only stopped, but stopped in the correct order.Change master-max to 2Conversion to Active/ActiveCreate a GFS2 FilesystemCreate and Populate an GFS2 PartitionDo this on each node in the cluster and be sure to restart them before continuing.First we must use the -p option to specify that we want to use the the Kernel’s DLM. Next we use -j to indicate that it should reserve enough space for two journals (one per node accessing the filesystem).GFS2 needs two services to be running, the first is the user-space interface to the kernel’s distributed lock manager (DLM). The DLM is used to co-ordinate which node(s) can access a given file (and when) and integrates with Pacemaker to obtain node membership The list of nodes the cluster considers to be available information and fencing capabilities.Here is the full transcriptInstall a Cluster Filesystem - GFS2Lastly, we use -t to specify the lock table name. The format for this field is clustername:fsname. For the fsname, we just need to pick something unique and descriptive and since we haven’t specified a clustername yet, we will use the default (pcmk).Next we need to convert the filesystem and Apache resources into clones. Again, the shell will automatically update any relevant constraints.Note that both Apache and WebFS have been stopped.Notice how any constraints that referenced ClusterIP have been updated to use WebIP instead. This is an additional benefit of using the crm shell.Now ensure Pacemaker only starts the gfs-control service on nodes that also have a copy of the dlm service (created above) already runningNow that the cluster stack and integration pieces are running smoothly, we can create an GFS2 partition.Now that we’ve recreated the resource, we also need to recreate all the constraints that used it. This is because the shell will automatically remove any constraints that referenced WebFS.Now we must tell the ClusterIP how to decide which requests are processed by which hosts. To do this we must specify the clusterip_hash parameter.Once the DLM is active, we can add the GFS2 control daemon.Open the ClusterIP resourcePreparationReconfigure Pacemaker for Active/ActiveReconfigure the Cluster for GFS2RequirementsReview the configuration before uploading it to the cluster, quitting the shell and watching the cluster’s responseSetup Pacemaker-GFS2 IntegrationSo that the complete definition looks like:TODO: Explain the meaning of the interleave optionTODO: Put one node into standby to demonstrate failoverTesting RecoveryThe DLM control daemon needs to run on all active cluster nodes, so we will use the shells interactive mode to create a cloned resource.The first thing to do is install gfs2-utils on each machine.The last step is to tell the cluster that it is now allowed to promote both instances to be Primary (aka. Master).The only hitch is that we need to use a cluster-aware filesystem (and the one we used earlier with DRBD, ext4, is not one of those). Both OCFS2 and GFS2 are supported, however here we will use GFS2 which comes with &DISTRO; &DISTRO_VERSION; .The primary requirement for an Active/Active cluster is that the data required for your services are available, simultaneously, on both machines. Pacemaker makes no requirement on how this is achieved, you could use a SAN if you had one available, however since DRBD supports multiple Primaries, we can also use that.The second service is GFS2’s own control daemon which also integrates with Pacemaker to obtain node membership data.Then (re)populate the new filesystem with data (web pages). For now we’ll create another variation on our home page.There’s no point making the services active on both locations if we can’t reach them, so lets first clone the IP address. Cloned IPaddr2 resources use an iptables rule to ensure that each request only processed by one of the two clone instances. The additional meta options tell the cluster how many instances of the clone we want (one “request bucket” for each node) and that if all other nodes fail, then the remaining node should hold all of them. Otherwise the requests would be simply discarded.This will erase all previous content stored on the DRBD device. Ensure you have a copy of any important data.This will involve a number of changes, so we’ll again use interactive mode.To specify an alternate name for the cluster, locate the service section containing “name: pacemaker” in corosync.conf and insert the following line anywhere inside the block:Use the crm shell to create the gfs-control cluster resource:We need to specify a number of additional parameters when creating a GFS2 partition.[root@pcmk-1 ~]# configure edit  ClusterIPclusterip_hash="sourceip"clustername: mynameProject-Id-Version: 0 POT-Creation-Date: 2010-12-15T23:32:36 PO-Revision-Date: 2010-12-16 00:37+0800 Last-Translator: Charlie Chen Language-Team: None Language: MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-Poedit-Language: Chinese X-Poedit-Country: CHINA X-Poedit-SourceCharset: utf-8 [root@pcmk-1 ~]# configure clone WebIP ClusterIP  \         meta globally-unique=”true” clone-max=”2” clone-node-max=”2” [root@pcmk-1 ~]# crm crm(live)# cib new active INFO: active shadow CIB created crm(active)# configure clone WebIP ClusterIP  \         meta globally-unique=”true” clone-max=”2” clone-node-max=”2” crm(active)# configure show node pcmk-1 node pcmk-2 primitive WebData ocf:linbit:drbd \         params drbd_resource="wwwdata" \         op monitor interval="60s" primitive WebFS ocf:heartbeat:Filesystem \         params device="/dev/drbd/by-res/wwwdata" directory="/var/www/html" fstype=”gfs2” primitive WebSite ocf:heartbeat:apache \         params configfile="/etc/httpd/conf/httpd.conf" \         op monitor interval="1min" primitive ClusterIP ocf:heartbeat:IPaddr2 \         params ip=”192.168.122.101” cidr_netmask=”32” clusterip_hash=”sourceip” \         op monitor interval="30s" primitive dlm ocf:pacemaker:controld \         op monitor interval="120s" primitive gfs-control ocf:pacemaker:controld \    params daemon=”gfs_controld.pcmk” args=”-g 0” \         op monitor interval="120s" ms WebDataClone WebData \         meta master-max="1" master-node-max="1" clone-max="2" clone-node-max="1" notify="true" clone WebIP ClusterIP \ meta globally-unique=”true” clone-max=”2” clone-node-max=”2” clone dlm-clone dlm \         meta interleave="true" clone gfs-clone gfs-control \         meta interleave="true" colocation WebFS-with-gfs-control inf: WebFS gfs-clone colocation WebSite-with-WebFS inf: WebSite WebFS colocation fs_on_drbd inf: WebFS WebDataClone:Master colocation gfs-with-dlm inf: gfs-clone dlm-clone colocation website-with-ip inf: WebSite WebIP order WebFS-after-WebData inf: WebDataClone:promote WebFS:start order WebSite-after-WebFS inf: WebFS WebSite order apache-after-ip inf: WebIP WebSite order start-WebFS-after-gfs-control inf: gfs-clone WebFS order start-gfs-after-dlm inf: dlm-clone gfs-clone property $id="cib-bootstrap-options" \         dc-version="1.0.5-462f1569a43740667daf7b0f6b521742e9eb8fa7" \         cluster-infrastructure="openais" \         expected-quorum-votes=”2” \         stonith-enabled="false" \         no-quorum-policy="ignore" rsc_defaults $id="rsc-options" \         resource-stickiness=”100” [root@pcmk-1 ~]# crm [root@pcmk-1 ~]# cib new active [root@pcmk-1 ~]# crm crm(live)# cib new GFS2 INFO: GFS2 shadow CIB created crm(GFS2)# configure delete WebFS crm(GFS2)# configure primitive WebFS ocf:heartbeat:Filesystem params device="/dev/drbd/by-res/wwwdata" directory="/var/www/html" fstype=”gfs2” [root@pcmk-1 ~]# crm crm(live)# cib new gfs-glue --force INFO: gfs-glue shadow CIB created crm(gfs-glue)# configure primitive gfs-control ocf:pacemaker:controld params daemon=gfs_controld.pcmk args="-g 0" op monitor interval=120s crm(gfs-glue)# configure clone gfs-clone gfs-control meta interleave=true [root@pcmk-1 ~]# crm crm(live)# cib new stack-glue INFO: stack-glue shadow CIB created crm(stack-glue)# configure primitive dlm ocf:pacemaker:controld op monitor interval=120s crm(stack-glue)# configure clone dlm-clone dlm meta interleave=true crm(stack-glue)# configure show xml crm(stack-glue)# configure show node pcmk-1 node pcmk-2 primitive WebData ocf:linbit:drbd \         params drbd_resource="wwwdata" \         op monitor interval="60s" primitive WebFS ocf:heartbeat:Filesystem \         params device="/dev/drbd/by-res/wwwdata" directory="/var/www/html" fstype="ext4" primitive WebSite ocf:heartbeat:apache \         params configfile="/etc/httpd/conf/httpd.conf" \         op monitor interval="1min" primitive ClusterIP ocf:heartbeat:IPaddr2 \         params ip="192.168.122.101" cidr_netmask="32" \         op monitor interval="30s" primitive dlm ocf:pacemaker:controld \ op monitor interval="120s" ms WebDataClone WebData \         meta master-max="1" master-node-max="1" clone-max="2" clone-node-max="1" notify="true" clone dlm-clone dlm \ meta interleave="true" location prefer-pcmk-1 WebSite 50: pcmk-1 colocation WebSite-with-WebFS inf: WebSite WebFS colocation fs_on_drbd inf: WebFS WebDataClone:Master colocation website-with-ip inf: WebSite ClusterIP order WebFS-after-WebData inf: WebDataClone:promote WebFS:start order WebSite-after-WebFS inf: WebFS WebSite order apache-after-ip inf: ClusterIP WebSite property $id="cib-bootstrap-options" \         dc-version="1.0.5-462f1569a43740667daf7b0f6b521742e9eb8fa7" \         cluster-infrastructure="openais" \         expected-quorum-votes=”2” \         stonith-enabled="false" \         no-quorum-policy="ignore" rsc_defaults $id="rsc-options" \         resource-stickiness=”100” [root@pcmk-1 ~]# crm_resource --resource WebFS --set-parameter target-role --meta --parameter-value Stopped [root@pcmk-1 ~]# crm_mon ============ Last updated: Thu Sep  3 15:18:06 2009 Stack: openais Current DC: pcmk-1 - partition with quorum Version: 1.0.5-462f1569a43740667daf7b0f6b521742e9eb8fa7 2 Nodes configured, 2 expected votes 6 Resources configured. ============ Online: [ pcmk-1 pcmk-2 ] Master/Slave Set: WebDataClone         Masters: [ pcmk-1 ]         Slaves: [ pcmk-2 ] ClusterIP        (ocf::heartbeat:IPaddr):        Started pcmk-1 Clone Set: dlm-clone         Started: [ pcmk-2 pcmk-1 ] Clone Set: gfs-clone         Started: [ pcmk-2 pcmk-1 ] [root@pcmk-1 ~]# mount /dev/drbd1 /mnt/ [root@pcmk-1 ~]# cat <<-END >/mnt/index.html <html> <body>My Test Site - GFS2</body> </html> END [root@pcmk-1 ~]# umount /dev/drbd1 [root@pcmk-1 ~]# drbdadm verify wwwdata [root@pcmk-1 ~]# [root@pcmk-1 ~]# yum install -y gfs2-utils gfs-pcmk Setting up Install Process Resolving Dependencies --> Running transaction check ---> Package gfs-pcmk.x86_64 0:3.0.5-2.fc12 set to be updated --> Processing Dependency: libSaCkpt.so.3(OPENAIS_CKPT_B.01.01)(64bit) for package: gfs-pcmk-3.0.5-2.fc12.x86_64 --> Processing Dependency: dlm-pcmk for package: gfs-pcmk-3.0.5-2.fc12.x86_64 --> Processing Dependency: libccs.so.3()(64bit) for package: gfs-pcmk-3.0.5-2.fc12.x86_64 --> Processing Dependency: libdlmcontrol.so.3()(64bit) for package: gfs-pcmk-3.0.5-2.fc12.x86_64 --> Processing Dependency: liblogthread.so.3()(64bit) for package: gfs-pcmk-3.0.5-2.fc12.x86_64 --> Processing Dependency: libSaCkpt.so.3()(64bit) for package: gfs-pcmk-3.0.5-2.fc12.x86_64 ---> Package gfs2-utils.x86_64 0:3.0.5-2.fc12 set to be updated --> Running transaction check ---> Package clusterlib.x86_64 0:3.0.5-2.fc12 set to be updated ---> Package dlm-pcmk.x86_64 0:3.0.5-2.fc12 set to be updated ---> Package openaislib.x86_64 0:1.1.0-1.fc12 set to be updated --> Finished Dependency Resolution Dependencies Resolved ===========================================================================================  Package                Arch               Version                   Repository        Size =========================================================================================== Installing:  gfs-pcmk               x86_64             3.0.5-2.fc12              custom           101 k  gfs2-utils             x86_64             3.0.5-2.fc12              custom           208 k Installing for dependencies:  clusterlib             x86_64             3.0.5-2.fc12              custom            65 k  dlm-pcmk               x86_64             3.0.5-2.fc12              custom            93 k  openaislib             x86_64             1.1.0-1.fc12              fedora            76 k Transaction Summary =========================================================================================== Install       5 Package(s) Upgrade       0 Package(s) Total download size: 541 k Downloading Packages: (1/5): clusterlib-3.0.5-2.fc12.x86_64.rpm                                |  65 kB     00:00 (2/5): dlm-pcmk-3.0.5-2.fc12.x86_64.rpm                                  |  93 kB     00:00 (3/5): gfs-pcmk-3.0.5-2.fc12.x86_64.rpm                                  | 101 kB     00:00 (4/5): gfs2-utils-3.0.5-2.fc12.x86_64.rpm                                | 208 kB     00:00 (5/5): openaislib-1.1.0-1.fc12.x86_64.rpm                                |  76 kB     00:00 ------------------------------------------------------------------------------------------- Total                                                           992 kB/s | 541 kB     00:00 Running rpm_check_debug Running Transaction Test Finished Transaction Test Transaction Test Succeeded Running Transaction   Installing     : clusterlib-3.0.5-2.fc12.x86_64                                       1/5   Installing     : openaislib-1.1.0-1.fc12.x86_64                                       2/5   Installing     : dlm-pcmk-3.0.5-2.fc12.x86_64                                         3/5   Installing     : gfs-pcmk-3.0.5-2.fc12.x86_64                                         4/5   Installing     : gfs2-utils-3.0.5-2.fc12.x86_64                                       5/5 Installed:   gfs-pcmk.x86_64 0:3.0.5-2.fc12                    gfs2-utils.x86_64 0:3.0.5-2.fc12 Dependency Installed:   clusterlib.x86_64 0:3.0.5-2.fc12   dlm-pcmk.x86_64 0:3.0.5-2.fc12   openaislib.x86_64 0:1.1.0-1.fc12   Complete! [root@pcmk-1 x86_64]# crm(GFS2)# cib commit GFS2 INFO: commited 'GFS2' shadow CIB to the cluster crm(GFS2)# quit bye [root@pcmk-1 ~]# crm_mon ============ Last updated: Thu Sep  3 20:49:54 2009 Stack: openais Current DC: pcmk-2 - partition with quorum Version: 1.0.5-462f1569a43740667daf7b0f6b521742e9eb8fa7 2 Nodes configured, 2 expected votes 6 Resources configured. ============ Online: [ pcmk-1 pcmk-2 ] WebSite (ocf::heartbeat:apache):        Started pcmk-2 Master/Slave Set: WebDataClone         Masters: [ pcmk-1 ]         Slaves: [ pcmk-2 ] ClusterIP        (ocf::heartbeat:IPaddr):        Started pcmk-2 Clone Set: dlm-clone         Started: [ pcmk-2 pcmk-1 ] Clone Set: gfs-clone         Started: [ pcmk-2 pcmk-1 ] WebFS (ocf::heartbeat:Filesystem): Started pcmk-1 crm(GFS2)# configure colocation WebSite-with-WebFS inf: WebSite WebFS crm(GFS2)# configure colocation fs_on_drbd inf: WebFS WebDataClone:Master crm(GFS2)# configure order WebFS-after-WebData inf: WebDataClone:promote WebFS:start crm(GFS2)# configure order WebSite-after-WebFS inf: WebFS WebSite crm(GFS2)# configure colocation WebFS-with-gfs-control INFINITY: WebFS gfs-clone crm(GFS2)# configure order start-WebFS-after-gfs-control mandatory: gfs-clone WebFS crm(GFS2)# configure show node pcmk-1 node pcmk-2 primitive WebData ocf:linbit:drbd \         params drbd_resource="wwwdata" \         op monitor interval="60s" primitive WebFS ocf:heartbeat:Filesystem \ params device="/dev/drbd/by-res/wwwdata" directory="/var/www/html" fstype=”gfs2” primitive WebSite ocf:heartbeat:apache \         params configfile="/etc/httpd/conf/httpd.conf" \         op monitor interval="1min" primitive ClusterIP ocf:heartbeat:IPaddr2 \         params ip="192.168.122.101" cidr_netmask="32" \         op monitor interval="30s" primitive dlm ocf:pacemaker:controld \         op monitor interval="120s" primitive gfs-control ocf:pacemaker:controld \    params daemon=”gfs_controld.pcmk” args=”-g 0” \         op monitor interval="120s" ms WebDataClone WebData \         meta master-max="1" master-node-max="1" clone-max="2" clone-node-max="1" notify="true" clone dlm-clone dlm \         meta interleave="true" clone gfs-clone gfs-control \         meta interleave="true" colocation WebFS-with-gfs-control inf: WebFS gfs-clone colocation WebSite-with-WebFS inf: WebSite WebFS colocation fs_on_drbd inf: WebFS WebDataClone:Master colocation gfs-with-dlm inf: gfs-clone dlm-clone colocation website-with-ip inf: WebSite ClusterIP order WebFS-after-WebData inf: WebDataClone:promote WebFS:start order WebSite-after-WebFS inf: WebFS WebSite order apache-after-ip inf: ClusterIP WebSite order start-WebFS-after-gfs-control inf: gfs-clone WebFS order start-gfs-after-dlm inf: dlm-clone gfs-clone property $id="cib-bootstrap-options" \         dc-version="1.0.5-462f1569a43740667daf7b0f6b521742e9eb8fa7" \         cluster-infrastructure="openais" \         expected-quorum-votes=”2” \         stonith-enabled="false" \         no-quorum-policy="ignore" rsc_defaults $id="rsc-options" \         resource-stickiness=”100” crm(active)# cib commit active INFO: commited 'active' shadow CIB to the cluster crm(active)# quit bye [root@pcmk-1 ~]# crm_mon ============ Last updated: Thu Sep  3 21:37:27 2009 Stack: openais Current DC: pcmk-2 - partition with quorum Version: 1.0.5-462f1569a43740667daf7b0f6b521742e9eb8fa7 2 Nodes configured, 2 expected votes 6 Resources configured. ============ Online: [ pcmk-1 pcmk-2 ] Master/Slave Set: WebDataClone         Masters: [ pcmk-1 pcmk-2 ] Clone Set: dlm-clone         Started: [ pcmk-2 pcmk-1 ] Clone Set: gfs-clone         Started: [ pcmk-2 pcmk-1 ] Clone Set: WebIP Started: [ pcmk-1 pcmk-2 ] Clone Set: WebFSClone Started: [ pcmk-1 pcmk-2 ] Clone Set: WebSiteClone Started: [ pcmk-1 pcmk-2 ] crm(active)# configure clone WebFSClone WebFS crm(active)# configure clone WebSiteClone WebSite crm(active)# configure edit WebDataClone crm(active)# configure show node pcmk-1 node pcmk-2 primitive WebData ocf:linbit:drbd \         params drbd_resource="wwwdata" \         op monitor interval="60s" primitive WebFS ocf:heartbeat:Filesystem \         params device="/dev/drbd/by-res/wwwdata" directory="/var/www/html" fstype=”gfs2” primitive WebSite ocf:heartbeat:apache \         params configfile="/etc/httpd/conf/httpd.conf" \         op monitor interval="1min" primitive ClusterIP ocf:heartbeat:IPaddr2 \         params ip=”192.168.122.101” cidr_netmask=”32” clusterip_hash=”sourceip” \         op monitor interval="30s" primitive dlm ocf:pacemaker:controld \         op monitor interval="120s" primitive gfs-control ocf:pacemaker:controld \    params daemon=”gfs_controld.pcmk” args=”-g 0” \         op monitor interval="120s" ms WebDataClone WebData \         meta master-max="2" master-node-max="1" clone-max="2" clone-node-max="1" notify="true" clone WebFSClone WebFS clone WebIP ClusterIP  \         meta globally-unique=”true” clone-max=”2” clone-node-max=”2” clone WebSiteClone WebSite clone dlm-clone dlm \         meta interleave="true" clone gfs-clone gfs-control \         meta interleave="true" colocation WebFS-with-gfs-control inf: WebFSClone gfs-clone colocation WebSite-with-WebFS inf: WebSiteClone WebFSClone colocation fs_on_drbd inf: WebFSClone WebDataClone:Master colocation gfs-with-dlm inf: gfs-clone dlm-clone colocation website-with-ip inf: WebSiteClone WebIP order WebFS-after-WebData inf: WebDataClone:promote WebFSClone:start order WebSite-after-WebFS inf: WebFSClone WebSiteClone order apache-after-ip inf: WebIP WebSiteClone order start-WebFS-after-gfs-control inf: gfs-clone WebFSClone order start-gfs-after-dlm inf: dlm-clone gfs-clone property $id="cib-bootstrap-options" \         dc-version="1.0.5-462f1569a43740667daf7b0f6b521742e9eb8fa7" \         cluster-infrastructure="openais" \         expected-quorum-votes=”2” \         stonith-enabled="false" \         no-quorum-policy="ignore" rsc_defaults $id="rsc-options" \         resource-stickiness=”100” crm(gfs-glue)# configure colocation gfs-with-dlm INFINITY: gfs-clone dlm-clone crm(gfs-glue)# configure order start-gfs-after-dlm mandatory: dlm-clone gfs-clone crm(gfs-glue)# configure show node pcmk-1 node pcmk-2 primitive WebData ocf:linbit:drbd \         params drbd_resource="wwwdata" \         op monitor interval="60s" primitive WebFS ocf:heartbeat:Filesystem \         params device="/dev/drbd/by-res/wwwdata" directory="/var/www/html" fstype="ext4" primitive WebSite ocf:heartbeat:apache \         params configfile="/etc/httpd/conf/httpd.conf" \         op monitor interval="1min" primitive ClusterIP ocf:heartbeat:IPaddr2 \         params ip="192.168.122.101" cidr_netmask="32" \         op monitor interval="30s" primitive dlm ocf:pacemaker:controld \         op monitor interval="120s" primitive gfs-control ocf:pacemaker:controld \ params daemon=”gfs_controld.pcmk” args=”-g 0” \ op monitor interval="120s" ms WebDataClone WebData \         meta master-max="1" master-node-max="1" clone-max="2" clone-node-max="1" notify="true" clone dlm-clone dlm \         meta interleave="true" clone gfs-clone gfs-control \ meta interleave="true" location prefer-pcmk-1 WebSite 50: pcmk-1 colocation WebSite-with-WebFS inf: WebSite WebFS colocation fs_on_drbd inf: WebFS WebDataClone:Master colocation gfs-with-dlm inf: gfs-clone dlm-clone colocation website-with-ip inf: WebSite ClusterIP order WebFS-after-WebData inf: WebDataClone:promote WebFS:start order WebSite-after-WebFS inf: WebFS WebSite order apache-after-ip inf: ClusterIP WebSite order start-gfs-after-dlm inf: dlm-clone gfs-clone property $id="cib-bootstrap-options" \         dc-version="1.0.5-462f1569a43740667daf7b0f6b521742e9eb8fa7" \         cluster-infrastructure="openais" \         expected-quorum-votes=”2” \         stonith-enabled="false" \         no-quorum-policy="ignore" rsc_defaults $id="rsc-options" \         resource-stickiness=”100” crm(gfs-glue)# cib commit gfs-glue INFO: commited 'gfs-glue' shadow CIB to the cluster crm(gfs-glue)# quit bye [root@pcmk-1 ~]# crm_mon ============ Last updated: Thu Sep  3 20:49:54 2009 Stack: openais Current DC: pcmk-2 - partition with quorum Version: 1.0.5-462f1569a43740667daf7b0f6b521742e9eb8fa7 2 Nodes configured, 2 expected votes 6 Resources configured. ============ Online: [ pcmk-1 pcmk-2 ] WebSite (ocf::heartbeat:apache):        Started pcmk-2 Master/Slave Set: WebDataClone         Masters: [ pcmk-1 ]         Slaves: [ pcmk-2 ] ClusterIP        (ocf::heartbeat:IPaddr):        Started pcmk-2 Clone Set: dlm-clone         Started: [ pcmk-2 pcmk-1 ] Clone Set: gfs-clone Started: [ pcmk-2 pcmk-1 ] WebFS   (ocf::heartbeat:Filesystem):    Started pcmk-1 crm(stack-glue)# cib commit stack-glue INFO: commited 'stack-glue' shadow CIB to the cluster crm(stack-glue)# quit bye [root@pcmk-1 ~]# crm_mon ============ Last updated: Thu Sep  3 20:49:54 2009 Stack: openais Current DC: pcmk-2 - partition with quorum Version: 1.0.5-462f1569a43740667daf7b0f6b521742e9eb8fa7 2 Nodes configured, 2 expected votes 5 Resources configured. ============ Online: [ pcmk-1 pcmk-2 ] WebSite (ocf::heartbeat:apache):        Started pcmk-2 Master/Slave Set: WebDataClone         Masters: [ pcmk-1 ]         Slaves: [ pcmk-2 ] ClusterIP        (ocf::heartbeat:IPaddr):        Started pcmk-2 Clone Set: dlm-clone Started: [ pcmk-2 pcmk-1 ] WebFS   (ocf::heartbeat:Filesystem):    Started pcmk-2 mkfs.gfs2 -p lock_dlm -j 2 -t pcmk:web /dev/drbd1 [root@pcmk-1 ~]# mkfs.gfs2 -t pcmk:web -p lock_dlm -j 2 /dev/vdb This will destroy any data on /dev/vdb. It appears to contain: data Are you sure you want to proceed? [y/n] y Device:                    /dev/vdb Blocksize:                 4096 Device Size                1.00 GB (131072 blocks) Filesystem Size:           1.00 GB (131070 blocks) Journals:                  2 Resource Groups:           2 Locking Protocol:          "lock_dlm" Lock Table:                "pcmk:web" UUID:                      6B776F46-177B-BAF8-2C2B-292C0E078613 [root@pcmk-1 ~]# primitive ClusterIP ocf:heartbeat:IPaddr2 \         params ip="192.168.122.101" cidr_netmask="32" clusterip_hash="sourceip" \         op monitor interval="30s" 添加 DLM 服务添加 GFS2 服务基本上所有的事情都已经准备就绪了。最新的DRBD是支持 Primary/Primary(主/主)模式的,并且我们的文件系统的是针对集群的。所有我们要做的事情就是重新配置我们的集群来使用它们(的先进功能)。在参数行添加以下内容:在我们对一个已存在的分区做任何操作之前,我们要确保它没有被挂载。我们告诉集群停止WebFS这个资源来确保这一点。这可以确保其他使用WebFS的资源会正确的依次关闭。把 master-max 改为 2转变为Active/Active创建一个 GFS2 文件系统创建并迁移数据到 GFS2 分区在每个节点都执行以下命令。首先我们要用 -p选项来指定我们用的是内核的DLM,然后我们用-j来表示我们为两个日志保留足够的空间(每个操作文件系统的节点各一个)。GFS2要求运行两个服务,首先是用户空间访问内核的分布式锁管理(DLM)的接口。 DLM是用来统筹哪个节点可以处理某个特定的文件,并且与Pacemaker集成来得到节点之间的关系 The list of nodes the cluster considers to be available 和隔离能力。以下是完整的配置安装一个集群文件系统 - GFS2最后,我们用-t来指定lock table的名称。这个字段的格式是 clustername:fsname(集群名称:文件系统名称)。fsname的话,我们只要用一个唯一的并且能描述我们这个集群的名称就好了,我们用默认的pcmk。然后我们要把文件系统和apache资源变成clones。同样的 crm shell会自动更新相关约束。注意 Apache and WebFS 两者都已经停止了。请注意所有跟ClusterIP相关的限制都已经被更新到与WebIP相关,这是使用crm shell的另一个好处。现在确保Pacemaker只在有dlm服务运行的节点上面启动 gfs-control 服务现在集群的基层和集成部分都正常运行,我们现在创建一个GFS2分区现在我们重新创建这个资源, 我们也要重建跟这个资源相关的约束条件,因为shell会自动删除跟WebFS相关的约束条件。现在我们要告诉集群如何决定请求怎样分配给节点。我们要设置 clusterip_hash这个参数来实现它。一旦DLM启动了,我们可以加上GFS2的控制进程了。打开ClusterIP的配置准备工作重新配置 Pacemaker 为 Active/Active8.5. 重新为集群配置GFS2需求看看配置文件有没有错误,然后退出shell看看集群的反应。整合 Pacemaker-GFS2完整的定义就像下面一样:TODO: Explain the meaning of the interleave optionTODO: Put one node into standby to demonstrate failover恢复测试DLM控制进程需要在所有可用的集群节点上面运行,所以我们用shell交互模式来添加一个cloned类型的资源。首先我们在各个节点上面安装GFS2。最后要告诉集群现在允许把两个节点都提升为 Primary(换句话说 Master).唯一的限制是我们要用一个针对集群的文件系统(我们之前用的ext4,它并不是这样一个文件系统)。 OCFS2或者GFS2都是可以的,但是在&DISTRO; &DISTRO_VERSION;上面,我们用GFS2。Active/Active集群一个主要的需求就是数据在两台机器上面都是可用并且是同步的。Pacemaker没有要求你怎么实现,你可以用SAN,但是自从DRBD支持多主模式,我们也可以用这个来实现。另外一个服务是GFS2自身的控制进程,也是与Pacemaker集成来得到节点之间的关系。然后再迁移数据到这个新的文件系统。现在我们创建一个跟上次不一样的主页。如果我们不能访问这些服务,那做成 Active/Active是没有必要的,所以我们要先clone这个IP地址,克隆的IPaddr2资源用的是iptables规则来保证每个请求都只由一个节点来处理。附件的meta选项告诉集群我们要克隆多少个实例(每个节点一个"请求桶")。并且如果其他节点挂了,剩下的节点可以处理所有的请求。否则这些请求都会被丢弃。这个操作会清除DRBD分区上面的所有数据,请备份重要的数据。这次操作会改很多东西,所以我们再次使用交互模式如果要更改集群的名称,找到包含name:pacemaker的配置文件区域,然后添加如下所示的选项即可。用crm shell来创建gfs-control这个集群资源:我们要为GFS2分区指定一系列附加的参数。[root@pcmk-1 ~]# configure edit  ClusterIPclusterip_hash="sourceip"clustername: mynamepacemaker-master/doc/Clusters_from_Scratch/zh-CN/Ch-Active-Active.po000066400000000000000000002221141217637305600256110ustar00rootroot00000000000000# # AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: 0\n" "POT-Creation-Date: 2012-10-17T05:19:03\n" "PO-Revision-Date: 2010-12-16 00:37+0800\n" "Last-Translator: Charlie Chen \n" "Language-Team: None\n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Poedit-Language: Chinese\n" "X-Poedit-Country: CHINA\n" "X-Poedit-SourceCharset: utf-8\n" #. Tag: title #, no-c-format msgid "Conversion to Active/Active" msgstr "转变为Active/Active" #. Tag: title #, no-c-format msgid "Requirements" msgstr "需求" #. Tag: para #, fuzzy, no-c-format msgid "The primary requirement for an Active/Active cluster is that the data required for your services is available, simultaneously, on both machines. Pacemaker makes no requirement on how this is achieved, you could use a SAN if you had one available, however since DRBD supports multiple Primaries, we can also use that." msgstr "Active/Active集群一个主要的需求就是数据在两台机器上面都是可用并且是同步的。Pacemaker没有要求你怎么实现,你可以用SAN,但是自从DRBD支持多主模式,我们也可以用这个来实现。" #. Tag: para #, fuzzy, no-c-format msgid "The only hitch is that we need to use a cluster-aware filesystem. The one we used earlier with DRBD, ext4, is not one of those. Both OCFS2 and GFS2 are supported, however here we will use GFS2 which comes with Fedora 17." msgstr "唯一的限制是我们要用一个针对集群的文件系统(我们之前用的ext4,它并不是这样一个文件系统)。 OCFS2或者GFS2都是可以的,但是在&DISTRO; &DISTRO_VERSION;上面,我们用GFS2。" #. Tag: title #, no-c-format msgid "Installing the required Software" msgstr "" #. Tag: programlisting #, no-c-format msgid "# yum install -y gfs2-utils dlm kernel-modules-extra" msgstr "" #. Tag: literallayout #, no-c-format msgid "" "Loaded plugins: langpacks, presto, refresh-packagekit\n" "Resolving Dependencies\n" "--> Running transaction check\n" "---> Package dlm.x86_64 0:3.99.4-1.fc17 will be installed\n" "---> Package gfs2-utils.x86_64 0:3.1.4-3.fc17 will be installed\n" "---> Package kernel-modules-extra.x86_64 0:3.4.4-3.fc17 will be installed\n" "--> Finished Dependency Resolution\n" "\n" "Dependencies Resolved\n" "\n" "================================================================================\n" " Package Arch Version Repository Size\n" "================================================================================\n" "Installing:\n" " dlm x86_64 3.99.4-1.fc17 updates 83 k\n" " gfs2-utils x86_64 3.1.4-3.fc17 fedora 214 k\n" " kernel-modules-extra x86_64 3.4.4-3.fc17 updates 1.7 M\n" "\n" "Transaction Summary\n" "================================================================================\n" "Install 3 Packages\n" "\n" "Total download size: 1.9 M\n" "Installed size: 7.7 M\n" "Downloading Packages:\n" "(1/3): dlm-3.99.4-1.fc17.x86_64.rpm | 83 kB 00:00\n" "(2/3): gfs2-utils-3.1.4-3.fc17.x86_64.rpm | 214 kB 00:00\n" "(3/3): kernel-modules-extra-3.4.4-3.fc17.x86_64.rpm | 1.7 MB 00:01\n" "--------------------------------------------------------------------------------\n" "Total 615 kB/s | 1.9 MB 00:03\n" "Running Transaction Check\n" "Running Transaction Test\n" "Transaction Test Succeeded\n" "Running Transaction\n" " Installing : kernel-modules-extra-3.4.4-3.fc17.x86_64 1/3\n" " Installing : gfs2-utils-3.1.4-3.fc17.x86_64 2/3\n" " Installing : dlm-3.99.4-1.fc17.x86_64 3/3\n" " Verifying : dlm-3.99.4-1.fc17.x86_64 1/3\n" " Verifying : gfs2-utils-3.1.4-3.fc17.x86_64 2/3\n" " Verifying : kernel-modules-extra-3.4.4-3.fc17.x86_64 3/3\n" "\n" "Installed:\n" " dlm.x86_64 0:3.99.4-1.fc17\n" " gfs2-utils.x86_64 0:3.1.4-3.fc17\n" " kernel-modules-extra.x86_64 0:3.4.4-3.fc17\n" "\n" "Complete!" msgstr "" #. Tag: title #, no-c-format msgid "Create a GFS2 Filesystem" msgstr "创建一个 GFS2 文件系统" #. Tag: title #, no-c-format msgid "Preparation" msgstr "准备工作" #. Tag: para #, fuzzy, no-c-format msgid "Before we do anything to the existing partition, we need to make sure it is unmounted. We do this by telling the cluster to stop the WebFS resource. This will ensure that other resources (in our case, Apache) using WebFS are not only stopped, but stopped in the correct order." msgstr "在我们对一个已存在的分区做任何操作之前,我们要确保它没有被挂载。我们告诉集群停止WebFS这个资源来确保这一点。这可以确保其他使用WebFS的资源会正确的依次关闭。" #. Tag: programlisting #, no-c-format msgid "" "# pcs resource stop WebFS\n" "# pcs resource\n" " ClusterIP (ocf::heartbeat:IPaddr2) Started\n" " WebSite (ocf::heartbeat:apache) Stopped\n" " Master/Slave Set: WebDataClone [WebData]\n" " Masters: [ pcmk-2 ]\n" " Slaves: [ pcmk-1 ]\n" " WebFS (ocf::heartbeat:Filesystem) Stopped" msgstr "" #. Tag: para #, no-c-format msgid "Note that both Apache and WebFS have been stopped." msgstr "注意 Apache and WebFS 两者都已经停止了。" #. Tag: title #, no-c-format msgid "Create and Populate an GFS2 Partition" msgstr "创建并迁移数据到 GFS2 分区" #. Tag: para #, no-c-format msgid "Now that the cluster stack and integration pieces are running smoothly, we can create an GFS2 partition." msgstr "现在集群的基层和集成部分都正常运行,我们现在创建一个GFS2分区" #. Tag: para #, no-c-format msgid "This will erase all previous content stored on the DRBD device. Ensure you have a copy of any important data." msgstr "这个操作会清除DRBD分区上面的所有数据,请备份重要的数据。" #. Tag: para #, no-c-format msgid "We need to specify a number of additional parameters when creating a GFS2 partition." msgstr "我们要为GFS2分区指定一系列附加的参数。" #. Tag: para #, no-c-format msgid "First we must use the -p option to specify that we want to use the the Kernel’s DLM. Next we use -j to indicate that it should reserve enough space for two journals (one per node accessing the filesystem)." msgstr "首先我们要用 -p选项来指定我们用的是内核的DLM,然后我们用-j来表示我们为两个日志保留足够的空间(每个操作文件系统的节点各一个)。" #. Tag: para #, no-c-format msgid "Lastly, we use -t to specify the lock table name. The format for this field is clustername:fsname. For the fsname, we need to use the same value as specified in corosync.conf for cluster_name. If you setup corosync with the same cluster name we used in this tutorial, cluster name will be mycluster. If you are unsure what your cluster name is, open up /etc/corosync/corosync.conf, or execute the command pcs cluster corosync pcmk-1 to view the corosync config. The cluster name will be in the totem block." msgstr "" #. Tag: para #, no-c-format msgid "We must run the next command on whichever node last had /dev/drbd mounted. Otherwise you will receive the message:" msgstr "" #. Tag: screen #, no-c-format msgid "/dev/drbd1: Read-only file system" msgstr "" #. Tag: programlisting #, no-c-format msgid "" "# ssh pcmk-2 -- mkfs.gfs2 -p lock_dlm -j 2 -t mycluster:web /dev/drbd1\n" "This will destroy any data on /dev/drbd1.\n" "It appears to contain: Linux rev 1.0 ext4 filesystem data, UUID=dc45fff3-c47a-4db2-96f7-a8049a323fe4 (extents) (large files) (huge files)\n" "Are you sure you want to proceed? [y/n]y\n" "Device: /dev/drbd1\n" "Blocksize: 4096\n" "Device Size 0.97 GB (253935 blocks)\n" "Filesystem Size: 0.97 GB (253932 blocks)\n" "Journals: 2\n" "Resource Groups: 4\n" "Locking Protocol: \"lock_dlm\"\n" "Lock Table: \"mycluster\"\n" "UUID: ed293a02-9eee-3fa3-ed1c-435ef1fd0116" msgstr "" #. Tag: programlisting #, no-c-format msgid "" "# pcs cluster cib dlm_cfg\n" "# pcs -f dlm_cfg resource create dlm ocf:pacemaker:controld op monitor interval=60s\n" "# pcs -f dlm_cfg resource clone dlm clone-max=2 clone-node-max=1\n" "# pcs -f dlm_cfg resource show\n" " ClusterIP (ocf::heartbeat:IPaddr2) Started\n" " WebSite (ocf::heartbeat:apache) Stopped\n" " Master/Slave Set: WebDataClone [WebData]\n" " Masters: [ pcmk-2 ]\n" " Slaves: [ pcmk-1 ]\n" " WebFS (ocf::heartbeat:Filesystem) Stopped\n" " Clone Set: dlm-clone [dlm]\n" " Stopped: [ dlm:0 dlm:1 ]\n" "# pcs cluster push cib dlm_cfg\n" "CIB updated\n" "# pcs status\n" "\n" "Last updated: Fri Sep 14 12:54:50 2012\n" "Last change: Fri Sep 14 12:54:43 2012 via cibadmin on pcmk-1\n" "Stack: corosync\n" "Current DC: pcmk-1 (1) - partition with quorum\n" "Version: 1.1.8-1.el7-60a19ed12fdb4d5c6a6b6767f52e5391e447fec0\n" "2 Nodes configured, unknown expected votes\n" "7 Resources configured.\n" "\n" "Online: [ pcmk-1 pcmk-2 ]\n" "\n" "Full list of resources:\n" "\n" " ClusterIP (ocf::heartbeat:IPaddr2): Started pcmk-2\n" " WebSite (ocf::heartbeat:apache): Stopped\n" " Master/Slave Set: WebDataClone [WebData]\n" " Masters: [ pcmk-2 ]\n" " Slaves: [ pcmk-1 ]\n" " WebFS (ocf::heartbeat:Filesystem): Stopped\n" " Clone Set: dlm-clone [dlm]\n" " Started: [ pcmk-1 pcmk-2 ]" msgstr "" #. Tag: para #, no-c-format msgid "Then (re)populate the new filesystem with data (web pages). For now we’ll create another variation on our home page." msgstr "然后再迁移数据到这个新的文件系统。现在我们创建一个跟上次不一样的主页。" #. Tag: programlisting #, fuzzy, no-c-format msgid "" "# mount /dev/drbd1 /mnt/\n" "# cat <<-END >/mnt/index.html\n" "<html>\n" "<body>My Test Site - GFS2</body>\n" "</html>\n" "END\n" "# umount /dev/drbd1\n" "# drbdadm verify wwwdata#" msgstr "" "\n" "[root@pcmk-1 ~]# mount /dev/drbd1 /mnt/\n" "[root@pcmk-1 ~]# cat <<-END >/mnt/index.html\n" "<html>\n" "<body>My Test Site - GFS2</body>\n" "</html>\n" "END\n" "[root@pcmk-1 ~]# umount /dev/drbd1\n" "[root@pcmk-1 ~]# drbdadm verify wwwdata\n" "[root@pcmk-1 ~]#\n" #. Tag: title #, no-c-format msgid "Reconfigure the Cluster for GFS2" msgstr "8.5. 重新为集群配置GFS2" #. Tag: para #, no-c-format msgid "With the WebFS resource stopped, lets update the configuration." msgstr "" #. Tag: programlisting #, no-c-format msgid "" "# pcs resource show WebFS\n" "Resource: WebFS\n" " device: /dev/drbd/by-res/wwwdata\n" " directory: /var/www/html\n" " fstype: ext4\n" " target-role: Stopped" msgstr "" #. Tag: para #, no-c-format msgid "The fstype option needs to be updated to gfs2 instead of ext4." msgstr "" #. Tag: programlisting #, no-c-format msgid "" "# pcs resource update WebFS fstype=gfs2\n" "# pcs resource show WebFS\n" "Resource: WebFS\n" " device: /dev/drbd/by-res/wwwdata\n" " directory: /var/www/html\n" " fstype: gfs2\n" " target-role: Stopped\n" "CIB updated" msgstr "" #. Tag: title #, no-c-format msgid "Reconfigure Pacemaker for Active/Active" msgstr "重新配置 Pacemaker 为 Active/Active" #. Tag: para #, no-c-format msgid "Almost everything is in place. Recent versions of DRBD are capable of operating in Primary/Primary mode and the filesystem we’re using is cluster aware. All we need to do now is reconfigure the cluster to take advantage of this." msgstr "基本上所有的事情都已经准备就绪了。最新的DRBD是支持 Primary/Primary(主/主)模式的,并且我们的文件系统的是针对集群的。所有我们要做的事情就是重新配置我们的集群来使用它们(的先进功能)。" #. Tag: para #, fuzzy, no-c-format msgid "This will involve a number of changes, so we’ll want work with a local cib file." msgstr "这次操作会改很多东西,所以我们再次使用交互模式" #. Tag: programlisting #, no-c-format msgid "# pcs cluster cib active_cfg" msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "There’s no point making the services active on both locations if we can’t reach them, so lets first clone the IP address. Cloned IPaddr2 resources use an iptables rule to ensure that each request only gets processed by one of the two clone instances. The additional meta options tell the cluster how many instances of the clone we want (one \"request bucket\" for each node) and that if all other nodes fail, then the remaining node should hold all of them. Otherwise the requests would be simply discarded." msgstr "如果我们不能访问这些服务,那做成 Active/Active是没有必要的,所以我们要先clone这个IP地址,克隆的IPaddr2资源用的是iptables规则来保证每个请求都只由一个节点来处理。附件的meta选项告诉集群我们要克隆多少个实例(每个节点一个\"请求桶\")。并且如果其他节点挂了,剩下的节点可以处理所有的请求。否则这些请求都会被丢弃。" #. Tag: screen #, no-c-format msgid "" "# pcs -f active_cfg resource clone ClusterIP \\\n" " globally-unique=true clone-max=2 clone-node-max=2" msgstr "" #. Tag: para #, no-c-format msgid "Notice when the ClusterIP becomes a clone, the constraints referencing ClusterIP now reference the clone. This is done automatically by pcs." msgstr "" #. Tag: programlisting #, no-c-format msgid "" "# pcs -f active_cfg constraint\n" "Location Constraints:\n" "Ordering Constraints:\n" " start ClusterIP-clone then start WebSite\n" " WebFS then WebSite\n" " promote WebDataClone then start WebFS\n" "Colocation Constraints:\n" " WebSite with ClusterIP-clone\n" " WebFS with WebDataClone (with-rsc-role:Master)\n" " WebSite with WebFS" msgstr "" #. Tag: para #, no-c-format msgid "Now we must tell the ClusterIP how to decide which requests are processed by which hosts. To do this we must specify the clusterip_hash parameter." msgstr "现在我们要告诉集群如何决定请求怎样分配给节点。我们要设置 clusterip_hash这个参数来实现它。" #. Tag: programlisting #, no-c-format msgid "# pcs -f active_cfg resource update ClusterIP clusterip_hash=sourceip" msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "Next we need to convert the filesystem and Apache resources into clones." msgstr "然后我们要把文件系统和apache资源变成clones。同样的 crm shell会自动更新相关约束。" #. Tag: para #, no-c-format msgid "Notice how pcs automatically updates the relevant constraints again." msgstr "" #. Tag: programlisting #, no-c-format msgid "" "# pcs -f active_cfg resource clone WebFS\n" "# pcs -f active_cfg resource clone WebSite\n" "# pcs -f active_cfg constraint\n" "Location Constraints:\n" "Ordering Constraints:\n" " start ClusterIP-clone then start WebSite-clone\n" " WebFS-clone then WebSite-clone\n" " promote WebDataClone then start WebFS-clone\n" "Colocation Constraints:\n" " WebSite-clone with ClusterIP-clone\n" " WebFS-clone with WebDataClone (with-rsc-role:Master)\n" " WebSite-clone with WebFS-clone" msgstr "" #. Tag: para #, no-c-format msgid "The last step is to tell the cluster that it is now allowed to promote both instances to be Primary (aka. Master)." msgstr "最后要告诉集群现在允许把两个节点都提升为 Primary(换句话说 Master)." #. Tag: programlisting #, no-c-format msgid "# pcs -f active_cfg resource update WebDataClone master-max=2" msgstr "" #. Tag: para #, no-c-format msgid "Review the configuration before uploading it to the cluster, quitting the shell and watching the cluster’s response" msgstr "看看配置文件有没有错误,然后退出shell看看集群的反应。" #. Tag: programlisting #, no-c-format msgid "" "# pcs cluster push cib active_cfg\n" "# pcs resource start WebFS" msgstr "" #. Tag: para #, no-c-format msgid "After all the processes are started the status should look similar to this." msgstr "" #. Tag: programlisting #, no-c-format msgid "" "# pcs resource\n" " Master/Slave Set: WebDataClone [WebData]\n" " Masters: [ pcmk-2 pcmk-1 ]\n" " Clone Set: dlm-clone [dlm]\n" " Started: [ pcmk-2 pcmk-1 ]\n" " Clone Set: ClusterIP-clone [ClusterIP] (unique)\n" " ClusterIP:0 (ocf::heartbeat:IPaddr2) Started\n" " ClusterIP:1 (ocf::heartbeat:IPaddr2) Started\n" " Clone Set: WebFS-clone [WebFS]\n" " Started: [ pcmk-1 pcmk-2 ]\n" " Clone Set: WebSite-clone [WebSite]\n" " Started: [ pcmk-1 pcmk-2 ]" msgstr "" #. Tag: title #, no-c-format msgid "Testing Recovery" msgstr "恢复测试" #. Tag: para #, no-c-format msgid "TODO: Put one node into standby to demonstrate failover" msgstr "TODO: Put one node into standby to demonstrate failover" #~ msgid "Install a Cluster Filesystem - GFS2" #~ msgstr "安装一个集群文件系统 - GFS2" #~ msgid "The first thing to do is install gfs2-utils on each machine." #~ msgstr "首先我们在各个节点上面安装GFS2。" #~ msgid "" #~ "\n" #~ "[root@pcmk-1 ~]# yum install -y gfs2-utils gfs-pcmk\n" #~ "Setting up Install Process\n" #~ "Resolving Dependencies\n" #~ "--> Running transaction check\n" #~ "---> Package gfs-pcmk.x86_64 0:3.0.5-2.fc12 set to be updated\n" #~ "--> Processing Dependency: libSaCkpt.so.3(OPENAIS_CKPT_B.01.01)(64bit) for package: gfs-pcmk-3.0.5-2.fc12.x86_64\n" #~ "--> Processing Dependency: dlm-pcmk for package: gfs-pcmk-3.0.5-2.fc12.x86_64\n" #~ "--> Processing Dependency: libccs.so.3()(64bit) for package: gfs-pcmk-3.0.5-2.fc12.x86_64\n" #~ "--> Processing Dependency: libdlmcontrol.so.3()(64bit) for package: gfs-pcmk-3.0.5-2.fc12.x86_64\n" #~ "--> Processing Dependency: liblogthread.so.3()(64bit) for package: gfs-pcmk-3.0.5-2.fc12.x86_64\n" #~ "--> Processing Dependency: libSaCkpt.so.3()(64bit) for package: gfs-pcmk-3.0.5-2.fc12.x86_64\n" #~ "---> Package gfs2-utils.x86_64 0:3.0.5-2.fc12 set to be updated\n" #~ "--> Running transaction check\n" #~ "---> Package clusterlib.x86_64 0:3.0.5-2.fc12 set to be updated\n" #~ "---> Package dlm-pcmk.x86_64 0:3.0.5-2.fc12 set to be updated\n" #~ "---> Package openaislib.x86_64 0:1.1.0-1.fc12 set to be updated\n" #~ "--> Finished Dependency Resolution\n" #~ "\n" #~ "Dependencies Resolved\n" #~ "\n" #~ "===========================================================================================\n" #~ " Package                Arch               Version                   Repository        Size\n" #~ "===========================================================================================\n" #~ "Installing:\n" #~ " gfs-pcmk               x86_64             3.0.5-2.fc12              custom           101 k\n" #~ " gfs2-utils             x86_64             3.0.5-2.fc12              custom           208 k\n" #~ "Installing for dependencies:\n" #~ " clusterlib             x86_64             3.0.5-2.fc12              custom            65 k\n" #~ " dlm-pcmk               x86_64             3.0.5-2.fc12              custom            93 k\n" #~ " openaislib             x86_64             1.1.0-1.fc12              fedora            76 k\n" #~ "\n" #~ "Transaction Summary\n" #~ "===========================================================================================\n" #~ "Install       5 Package(s)\n" #~ "Upgrade       0 Package(s)\n" #~ "\n" #~ "Total download size: 541 k\n" #~ "Downloading Packages:\n" #~ "(1/5): clusterlib-3.0.5-2.fc12.x86_64.rpm                                |  65 kB     00:00\n" #~ "(2/5): dlm-pcmk-3.0.5-2.fc12.x86_64.rpm                                  |  93 kB     00:00\n" #~ "(3/5): gfs-pcmk-3.0.5-2.fc12.x86_64.rpm                                  | 101 kB     00:00\n" #~ "(4/5): gfs2-utils-3.0.5-2.fc12.x86_64.rpm                                | 208 kB     00:00\n" #~ "(5/5): openaislib-1.1.0-1.fc12.x86_64.rpm                                |  76 kB     00:00\n" #~ "-------------------------------------------------------------------------------------------\n" #~ "Total                                                           992 kB/s | 541 kB     00:00\n" #~ "Running rpm_check_debug\n" #~ "Running Transaction Test\n" #~ "Finished Transaction Test\n" #~ "Transaction Test Succeeded\n" #~ "Running Transaction\n" #~ "  Installing     : clusterlib-3.0.5-2.fc12.x86_64                                       1/5 \n" #~ "  Installing     : openaislib-1.1.0-1.fc12.x86_64                                       2/5 \n" #~ "  Installing     : dlm-pcmk-3.0.5-2.fc12.x86_64                                         3/5 \n" #~ "  Installing     : gfs-pcmk-3.0.5-2.fc12.x86_64                                         4/5 \n" #~ "  Installing     : gfs2-utils-3.0.5-2.fc12.x86_64                                       5/5 \n" #~ "\n" #~ "Installed:\n" #~ "  gfs-pcmk.x86_64 0:3.0.5-2.fc12                    gfs2-utils.x86_64 0:3.0.5-2.fc12\n" #~ "\n" #~ "Dependency Installed:\n" #~ "  clusterlib.x86_64 0:3.0.5-2.fc12   dlm-pcmk.x86_64 0:3.0.5-2.fc12 \n" #~ "  openaislib.x86_64 0:1.1.0-1.fc12  \n" #~ "\n" #~ "Complete!\n" #~ "[root@pcmk-1 x86_64]#\n" #~ msgstr "" #~ "\n" #~ "[root@pcmk-1 ~]# yum install -y gfs2-utils gfs-pcmk\n" #~ "Setting up Install Process\n" #~ "Resolving Dependencies\n" #~ "--> Running transaction check\n" #~ "---> Package gfs-pcmk.x86_64 0:3.0.5-2.fc12 set to be updated\n" #~ "--> Processing Dependency: libSaCkpt.so.3(OPENAIS_CKPT_B.01.01)(64bit) for package: gfs-pcmk-3.0.5-2.fc12.x86_64\n" #~ "--> Processing Dependency: dlm-pcmk for package: gfs-pcmk-3.0.5-2.fc12.x86_64\n" #~ "--> Processing Dependency: libccs.so.3()(64bit) for package: gfs-pcmk-3.0.5-2.fc12.x86_64\n" #~ "--> Processing Dependency: libdlmcontrol.so.3()(64bit) for package: gfs-pcmk-3.0.5-2.fc12.x86_64\n" #~ "--> Processing Dependency: liblogthread.so.3()(64bit) for package: gfs-pcmk-3.0.5-2.fc12.x86_64\n" #~ "--> Processing Dependency: libSaCkpt.so.3()(64bit) for package: gfs-pcmk-3.0.5-2.fc12.x86_64\n" #~ "---> Package gfs2-utils.x86_64 0:3.0.5-2.fc12 set to be updated\n" #~ "--> Running transaction check\n" #~ "---> Package clusterlib.x86_64 0:3.0.5-2.fc12 set to be updated\n" #~ "---> Package dlm-pcmk.x86_64 0:3.0.5-2.fc12 set to be updated\n" #~ "---> Package openaislib.x86_64 0:1.1.0-1.fc12 set to be updated\n" #~ "--> Finished Dependency Resolution\n" #~ "\n" #~ "Dependencies Resolved\n" #~ "\n" #~ "===========================================================================================\n" #~ " Package                Arch               Version                   Repository        Size\n" #~ "===========================================================================================\n" #~ "Installing:\n" #~ " gfs-pcmk               x86_64             3.0.5-2.fc12              custom           101 k\n" #~ " gfs2-utils             x86_64             3.0.5-2.fc12              custom           208 k\n" #~ "Installing for dependencies:\n" #~ " clusterlib             x86_64             3.0.5-2.fc12              custom            65 k\n" #~ " dlm-pcmk               x86_64             3.0.5-2.fc12              custom            93 k\n" #~ " openaislib             x86_64             1.1.0-1.fc12              fedora            76 k\n" #~ "\n" #~ "Transaction Summary\n" #~ "===========================================================================================\n" #~ "Install       5 Package(s)\n" #~ "Upgrade       0 Package(s)\n" #~ "\n" #~ "Total download size: 541 k\n" #~ "Downloading Packages:\n" #~ "(1/5): clusterlib-3.0.5-2.fc12.x86_64.rpm                                |  65 kB     00:00\n" #~ "(2/5): dlm-pcmk-3.0.5-2.fc12.x86_64.rpm                                  |  93 kB     00:00\n" #~ "(3/5): gfs-pcmk-3.0.5-2.fc12.x86_64.rpm                                  | 101 kB     00:00\n" #~ "(4/5): gfs2-utils-3.0.5-2.fc12.x86_64.rpm                                | 208 kB     00:00\n" #~ "(5/5): openaislib-1.1.0-1.fc12.x86_64.rpm                                |  76 kB     00:00\n" #~ "-------------------------------------------------------------------------------------------\n" #~ "Total                                                           992 kB/s | 541 kB     00:00\n" #~ "Running rpm_check_debug\n" #~ "Running Transaction Test\n" #~ "Finished Transaction Test\n" #~ "Transaction Test Succeeded\n" #~ "Running Transaction\n" #~ "  Installing     : clusterlib-3.0.5-2.fc12.x86_64                                       1/5 \n" #~ "  Installing     : openaislib-1.1.0-1.fc12.x86_64                                       2/5 \n" #~ "  Installing     : dlm-pcmk-3.0.5-2.fc12.x86_64                                         3/5 \n" #~ "  Installing     : gfs-pcmk-3.0.5-2.fc12.x86_64                                         4/5 \n" #~ "  Installing     : gfs2-utils-3.0.5-2.fc12.x86_64                                       5/5 \n" #~ "\n" #~ "Installed:\n" #~ "  gfs-pcmk.x86_64 0:3.0.5-2.fc12                    gfs2-utils.x86_64 0:3.0.5-2.fc12\n" #~ "\n" #~ "Dependency Installed:\n" #~ "  clusterlib.x86_64 0:3.0.5-2.fc12   dlm-pcmk.x86_64 0:3.0.5-2.fc12 \n" #~ "  openaislib.x86_64 0:1.1.0-1.fc12  \n" #~ "\n" #~ "Complete!\n" #~ "[root@pcmk-1 x86_64]#\n" #~ msgid "Setup Pacemaker-GFS2 Integration" #~ msgstr "整合 Pacemaker-GFS2" #~ msgid "GFS2 needs two services to be running, the first is the user-space interface to the kernel’s distributed lock manager (DLM). The DLM is used to co-ordinate which node(s) can access a given file (and when) and integrates with Pacemaker to obtain node membership The list of nodes the cluster considers to be available information and fencing capabilities." #~ msgstr "GFS2要求运行两个服务,首先是用户空间访问内核的分布式锁管理(DLM)的接口。 DLM是用来统筹哪个节点可以处理某个特定的文件,并且与Pacemaker集成来得到节点之间的关系 The list of nodes the cluster considers to be available 和隔离能力。" #~ msgid "The second service is GFS2’s own control daemon which also integrates with Pacemaker to obtain node membership data." #~ msgstr "另外一个服务是GFS2自身的控制进程,也是与Pacemaker集成来得到节点之间的关系。" #~ msgid "Add the DLM service" #~ msgstr "添加 DLM 服务" #~ msgid "The DLM control daemon needs to run on all active cluster nodes, so we will use the shells interactive mode to create a cloned resource." #~ msgstr "DLM控制进程需要在所有可用的集群节点上面运行,所以我们用shell交互模式来添加一个cloned类型的资源。" #~ msgid "" #~ "\n" #~ "[root@pcmk-1 ~]# crm\n" #~ "crm(live)# cib new stack-glue\n" #~ "INFO: stack-glue shadow CIB created\n" #~ "crm(stack-glue)# configure primitive dlm ocf:pacemaker:controld op monitor interval=120s\n" #~ "crm(stack-glue)# configure clone dlm-clone dlm meta interleave=true\n" #~ "crm(stack-glue)# configure show xml\n" #~ "crm(stack-glue)# configure show\n" #~ "node pcmk-1\n" #~ "node pcmk-2\n" #~ "primitive WebData ocf:linbit:drbd \\\n" #~ "        params drbd_resource=\"wwwdata\" \\\n" #~ "        op monitor interval=\"60s\"\n" #~ "primitive WebFS ocf:heartbeat:Filesystem \\\n" #~ "        params device=\"/dev/drbd/by-res/wwwdata\" directory=\"/var/www/html\" fstype=\"ext4\"\n" #~ "primitive WebSite ocf:heartbeat:apache \\\n" #~ "        params configfile=\"/etc/httpd/conf/httpd.conf\" \\\n" #~ "        op monitor interval=\"1min\"\n" #~ "primitive ClusterIP ocf:heartbeat:IPaddr2 \\\n" #~ "        params ip=\"192.168.122.101\" cidr_netmask=\"32\" \\\n" #~ "        op monitor interval=\"30s\"\n" #~ "primitive dlm ocf:pacemaker:controld \\\n" #~ " op monitor interval=\"120s\"\n" #~ "ms WebDataClone WebData \\\n" #~ "        meta master-max=\"1\" master-node-max=\"1\" clone-max=\"2\" clone-node-max=\"1\" notify=\"true\"\n" #~ "clone dlm-clone dlm \\\n" #~ " meta interleave=\"true\"\n" #~ "location prefer-pcmk-1 WebSite 50: pcmk-1\n" #~ "colocation WebSite-with-WebFS inf: WebSite WebFS\n" #~ "colocation fs_on_drbd inf: WebFS WebDataClone:Master\n" #~ "colocation website-with-ip inf: WebSite ClusterIP\n" #~ "order WebFS-after-WebData inf: WebDataClone:promote WebFS:start\n" #~ "order WebSite-after-WebFS inf: WebFS WebSite\n" #~ "order apache-after-ip inf: ClusterIP WebSite\n" #~ "property $id=\"cib-bootstrap-options\" \\\n" #~ "        dc-version=\"1.0.5-462f1569a43740667daf7b0f6b521742e9eb8fa7\" \\\n" #~ "        cluster-infrastructure=\"openais\" \\\n" #~ "        expected-quorum-votes=”2” \\\n" #~ "        stonith-enabled=\"false\" \\\n" #~ "        no-quorum-policy=\"ignore\"\n" #~ "rsc_defaults $id=\"rsc-options\" \\\n" #~ "        resource-stickiness=”100”\n" #~ msgstr "" #~ "\n" #~ "[root@pcmk-1 ~]# crm\n" #~ "crm(live)# cib new stack-glue\n" #~ "INFO: stack-glue shadow CIB created\n" #~ "crm(stack-glue)# configure primitive dlm ocf:pacemaker:controld op monitor interval=120s\n" #~ "crm(stack-glue)# configure clone dlm-clone dlm meta interleave=true\n" #~ "crm(stack-glue)# configure show xml\n" #~ "crm(stack-glue)# configure show\n" #~ "node pcmk-1\n" #~ "node pcmk-2\n" #~ "primitive WebData ocf:linbit:drbd \\\n" #~ "        params drbd_resource=\"wwwdata\" \\\n" #~ "        op monitor interval=\"60s\"\n" #~ "primitive WebFS ocf:heartbeat:Filesystem \\\n" #~ "        params device=\"/dev/drbd/by-res/wwwdata\" directory=\"/var/www/html\" fstype=\"ext4\"\n" #~ "primitive WebSite ocf:heartbeat:apache \\\n" #~ "        params configfile=\"/etc/httpd/conf/httpd.conf\" \\\n" #~ "        op monitor interval=\"1min\"\n" #~ "primitive ClusterIP ocf:heartbeat:IPaddr2 \\\n" #~ "        params ip=\"192.168.122.101\" cidr_netmask=\"32\" \\\n" #~ "        op monitor interval=\"30s\"\n" #~ "primitive dlm ocf:pacemaker:controld \\\n" #~ " op monitor interval=\"120s\"\n" #~ "ms WebDataClone WebData \\\n" #~ "        meta master-max=\"1\" master-node-max=\"1\" clone-max=\"2\" clone-node-max=\"1\" notify=\"true\"\n" #~ "clone dlm-clone dlm \\\n" #~ " meta interleave=\"true\"\n" #~ "location prefer-pcmk-1 WebSite 50: pcmk-1\n" #~ "colocation WebSite-with-WebFS inf: WebSite WebFS\n" #~ "colocation fs_on_drbd inf: WebFS WebDataClone:Master\n" #~ "colocation website-with-ip inf: WebSite ClusterIP\n" #~ "order WebFS-after-WebData inf: WebDataClone:promote WebFS:start\n" #~ "order WebSite-after-WebFS inf: WebFS WebSite\n" #~ "order apache-after-ip inf: ClusterIP WebSite\n" #~ "property $id=\"cib-bootstrap-options\" \\\n" #~ "        dc-version=\"1.0.5-462f1569a43740667daf7b0f6b521742e9eb8fa7\" \\\n" #~ "        cluster-infrastructure=\"openais\" \\\n" #~ "        expected-quorum-votes=”2” \\\n" #~ "        stonith-enabled=\"false\" \\\n" #~ "        no-quorum-policy=\"ignore\"\n" #~ "rsc_defaults $id=\"rsc-options\" \\\n" #~ "        resource-stickiness=”100”\n" #~ msgid "TODO: Explain the meaning of the interleave option" #~ msgstr "TODO: Explain the meaning of the interleave option" #~ msgid "" #~ "\n" #~ "crm(stack-glue)# cib commit stack-glue\n" #~ "INFO: commited 'stack-glue' shadow CIB to the cluster\n" #~ "crm(stack-glue)# quit\n" #~ "bye\n" #~ "[root@pcmk-1 ~]# crm_mon\n" #~ "============\n" #~ "Last updated: Thu Sep  3 20:49:54 2009\n" #~ "Stack: openais\n" #~ "Current DC: pcmk-2 - partition with quorum\n" #~ "Version: 1.0.5-462f1569a43740667daf7b0f6b521742e9eb8fa7\n" #~ "2 Nodes configured, 2 expected votes\n" #~ "5 Resources configured.\n" #~ "============\n" #~ "\n" #~ "Online: [ pcmk-1 pcmk-2 ]\n" #~ "\n" #~ "WebSite (ocf::heartbeat:apache):        Started pcmk-2\n" #~ "Master/Slave Set: WebDataClone\n" #~ "        Masters: [ pcmk-1 ]\n" #~ "        Slaves: [ pcmk-2 ]\n" #~ "ClusterIP        (ocf::heartbeat:IPaddr):        Started pcmk-2\n" #~ "Clone Set: dlm-clone\n" #~ " Started: [ pcmk-2 pcmk-1 ]\n" #~ "WebFS   (ocf::heartbeat:Filesystem):    Started pcmk-2\n" #~ msgstr "" #~ "\n" #~ "crm(stack-glue)# cib commit stack-glue\n" #~ "INFO: commited 'stack-glue' shadow CIB to the cluster\n" #~ "crm(stack-glue)# quit\n" #~ "bye\n" #~ "[root@pcmk-1 ~]# crm_mon\n" #~ "============\n" #~ "Last updated: Thu Sep  3 20:49:54 2009\n" #~ "Stack: openais\n" #~ "Current DC: pcmk-2 - partition with quorum\n" #~ "Version: 1.0.5-462f1569a43740667daf7b0f6b521742e9eb8fa7\n" #~ "2 Nodes configured, 2 expected votes\n" #~ "5 Resources configured.\n" #~ "============\n" #~ "\n" #~ "Online: [ pcmk-1 pcmk-2 ]\n" #~ "\n" #~ "WebSite (ocf::heartbeat:apache):        Started pcmk-2\n" #~ "Master/Slave Set: WebDataClone\n" #~ "        Masters: [ pcmk-1 ]\n" #~ "        Slaves: [ pcmk-2 ]\n" #~ "ClusterIP        (ocf::heartbeat:IPaddr):        Started pcmk-2\n" #~ "Clone Set: dlm-clone\n" #~ " Started: [ pcmk-2 pcmk-1 ]\n" #~ "WebFS   (ocf::heartbeat:Filesystem):    Started pcmk-2\n" #~ msgid "Add the GFS2 service" #~ msgstr "添加 GFS2 服务" #~ msgid "Once the DLM is active, we can add the GFS2 control daemon." #~ msgstr "一旦DLM启动了,我们可以加上GFS2的控制进程了。" #~ msgid "Use the crm shell to create the gfs-control cluster resource:" #~ msgstr "用crm shell来创建gfs-control这个集群资源:" #~ msgid "" #~ "\n" #~ "[root@pcmk-1 ~]# crm\n" #~ "crm(live)# cib new gfs-glue --force\n" #~ "INFO: gfs-glue shadow CIB created\n" #~ "crm(gfs-glue)# configure primitive gfs-control ocf:pacemaker:controld params daemon=gfs_controld.pcmk args=\"-g 0\" op monitor interval=120s\n" #~ "crm(gfs-glue)# configure clone gfs-clone gfs-control meta interleave=true\n" #~ msgstr "" #~ "\n" #~ "[root@pcmk-1 ~]# crm\n" #~ "crm(live)# cib new gfs-glue --force\n" #~ "INFO: gfs-glue shadow CIB created\n" #~ "crm(gfs-glue)# configure primitive gfs-control ocf:pacemaker:controld params daemon=gfs_controld.pcmk args=\"-g 0\" op monitor interval=120s\n" #~ "crm(gfs-glue)# configure clone gfs-clone gfs-control meta interleave=true\n" #~ msgid "Now ensure Pacemaker only starts the gfs-control service on nodes that also have a copy of the dlm service (created above) already running" #~ msgstr "现在确保Pacemaker只在有dlm服务运行的节点上面启动 gfs-control 服务" #~ msgid "" #~ "\n" #~ "crm(gfs-glue)# configure colocation gfs-with-dlm INFINITY: gfs-clone dlm-clone\n" #~ "crm(gfs-glue)# configure order start-gfs-after-dlm mandatory: dlm-clone gfs-clone\n" #~ msgstr "" #~ "\n" #~ "crm(gfs-glue)# configure colocation gfs-with-dlm INFINITY: gfs-clone dlm-clone\n" #~ "crm(gfs-glue)# configure order start-gfs-after-dlm mandatory: dlm-clone gfs-clone\n" #~ msgid "" #~ "\n" #~ "crm(gfs-glue)# configure show\n" #~ "node pcmk-1\n" #~ "node pcmk-2\n" #~ "primitive WebData ocf:linbit:drbd \\\n" #~ "        params drbd_resource=\"wwwdata\" \\\n" #~ "        op monitor interval=\"60s\"\n" #~ "primitive WebFS ocf:heartbeat:Filesystem \\\n" #~ "        params device=\"/dev/drbd/by-res/wwwdata\" directory=\"/var/www/html\" fstype=\"ext4\"\n" #~ "primitive WebSite ocf:heartbeat:apache \\\n" #~ "        params configfile=\"/etc/httpd/conf/httpd.conf\" \\\n" #~ "        op monitor interval=\"1min\"\n" #~ "primitive ClusterIP ocf:heartbeat:IPaddr2 \\\n" #~ "        params ip=\"192.168.122.101\" cidr_netmask=\"32\" \\\n" #~ "        op monitor interval=\"30s\"\n" #~ "primitive dlm ocf:pacemaker:controld \\\n" #~ "        op monitor interval=\"120s\"\n" #~ "primitive gfs-control ocf:pacemaker:controld \\\n" #~ " params daemon=”gfs_controld.pcmk” args=”-g 0” \\\n" #~ " op monitor interval=\"120s\"\n" #~ "ms WebDataClone WebData \\\n" #~ "        meta master-max=\"1\" master-node-max=\"1\" clone-max=\"2\" clone-node-max=\"1\" notify=\"true\"\n" #~ "clone dlm-clone dlm \\\n" #~ "        meta interleave=\"true\"\n" #~ "clone gfs-clone gfs-control \\\n" #~ " meta interleave=\"true\"\n" #~ "location prefer-pcmk-1 WebSite 50: pcmk-1\n" #~ "colocation WebSite-with-WebFS inf: WebSite WebFS\n" #~ "colocation fs_on_drbd inf: WebFS WebDataClone:Master\n" #~ "colocation gfs-with-dlm inf: gfs-clone dlm-clone\n" #~ "colocation website-with-ip inf: WebSite ClusterIP\n" #~ "order WebFS-after-WebData inf: WebDataClone:promote WebFS:start\n" #~ "order WebSite-after-WebFS inf: WebFS WebSite\n" #~ "order apache-after-ip inf: ClusterIP WebSite\n" #~ "order start-gfs-after-dlm inf: dlm-clone gfs-clone\n" #~ "property $id=\"cib-bootstrap-options\" \\\n" #~ "        dc-version=\"1.0.5-462f1569a43740667daf7b0f6b521742e9eb8fa7\" \\\n" #~ "        cluster-infrastructure=\"openais\" \\\n" #~ "        expected-quorum-votes=”2” \\\n" #~ "        stonith-enabled=\"false\" \\\n" #~ "        no-quorum-policy=\"ignore\"\n" #~ "rsc_defaults $id=\"rsc-options\" \\\n" #~ "        resource-stickiness=”100”\n" #~ "crm(gfs-glue)# cib commit gfs-glue\n" #~ "INFO: commited 'gfs-glue' shadow CIB to the cluster\n" #~ "crm(gfs-glue)# quit\n" #~ "bye\n" #~ "[root@pcmk-1 ~]# crm_mon\n" #~ "============\n" #~ "Last updated: Thu Sep  3 20:49:54 2009\n" #~ "Stack: openais\n" #~ "Current DC: pcmk-2 - partition with quorum\n" #~ "Version: 1.0.5-462f1569a43740667daf7b0f6b521742e9eb8fa7\n" #~ "2 Nodes configured, 2 expected votes\n" #~ "6 Resources configured.\n" #~ "============\n" #~ "\n" #~ "Online: [ pcmk-1 pcmk-2 ]\n" #~ "\n" #~ "WebSite (ocf::heartbeat:apache):        Started pcmk-2\n" #~ "Master/Slave Set: WebDataClone\n" #~ "        Masters: [ pcmk-1 ]\n" #~ "        Slaves: [ pcmk-2 ]\n" #~ "ClusterIP        (ocf::heartbeat:IPaddr):        Started pcmk-2\n" #~ "Clone Set: dlm-clone\n" #~ "        Started: [ pcmk-2 pcmk-1 ]\n" #~ "Clone Set: gfs-clone\n" #~ " Started: [ pcmk-2 pcmk-1 ]\n" #~ "WebFS   (ocf::heartbeat:Filesystem):    Started pcmk-1\n" #~ msgstr "" #~ "\n" #~ "crm(gfs-glue)# configure show\n" #~ "node pcmk-1\n" #~ "node pcmk-2\n" #~ "primitive WebData ocf:linbit:drbd \\\n" #~ "        params drbd_resource=\"wwwdata\" \\\n" #~ "        op monitor interval=\"60s\"\n" #~ "primitive WebFS ocf:heartbeat:Filesystem \\\n" #~ "        params device=\"/dev/drbd/by-res/wwwdata\" directory=\"/var/www/html\" fstype=\"ext4\"\n" #~ "primitive WebSite ocf:heartbeat:apache \\\n" #~ "        params configfile=\"/etc/httpd/conf/httpd.conf\" \\\n" #~ "        op monitor interval=\"1min\"\n" #~ "primitive ClusterIP ocf:heartbeat:IPaddr2 \\\n" #~ "        params ip=\"192.168.122.101\" cidr_netmask=\"32\" \\\n" #~ "        op monitor interval=\"30s\"\n" #~ "primitive dlm ocf:pacemaker:controld \\\n" #~ "        op monitor interval=\"120s\"\n" #~ "primitive gfs-control ocf:pacemaker:controld \\\n" #~ " params daemon=”gfs_controld.pcmk” args=”-g 0” \\\n" #~ " op monitor interval=\"120s\"\n" #~ "ms WebDataClone WebData \\\n" #~ "        meta master-max=\"1\" master-node-max=\"1\" clone-max=\"2\" clone-node-max=\"1\" notify=\"true\"\n" #~ "clone dlm-clone dlm \\\n" #~ "        meta interleave=\"true\"\n" #~ "clone gfs-clone gfs-control \\\n" #~ " meta interleave=\"true\"\n" #~ "location prefer-pcmk-1 WebSite 50: pcmk-1\n" #~ "colocation WebSite-with-WebFS inf: WebSite WebFS\n" #~ "colocation fs_on_drbd inf: WebFS WebDataClone:Master\n" #~ "colocation gfs-with-dlm inf: gfs-clone dlm-clone\n" #~ "colocation website-with-ip inf: WebSite ClusterIP\n" #~ "order WebFS-after-WebData inf: WebDataClone:promote WebFS:start\n" #~ "order WebSite-after-WebFS inf: WebFS WebSite\n" #~ "order apache-after-ip inf: ClusterIP WebSite\n" #~ "order start-gfs-after-dlm inf: dlm-clone gfs-clone\n" #~ "property $id=\"cib-bootstrap-options\" \\\n" #~ "        dc-version=\"1.0.5-462f1569a43740667daf7b0f6b521742e9eb8fa7\" \\\n" #~ "        cluster-infrastructure=\"openais\" \\\n" #~ "        expected-quorum-votes=”2” \\\n" #~ "        stonith-enabled=\"false\" \\\n" #~ "        no-quorum-policy=\"ignore\"\n" #~ "rsc_defaults $id=\"rsc-options\" \\\n" #~ "        resource-stickiness=”100”\n" #~ "crm(gfs-glue)# cib commit gfs-glue\n" #~ "INFO: commited 'gfs-glue' shadow CIB to the cluster\n" #~ "crm(gfs-glue)# quit\n" #~ "bye\n" #~ "[root@pcmk-1 ~]# crm_mon\n" #~ "============\n" #~ "Last updated: Thu Sep  3 20:49:54 2009\n" #~ "Stack: openais\n" #~ "Current DC: pcmk-2 - partition with quorum\n" #~ "Version: 1.0.5-462f1569a43740667daf7b0f6b521742e9eb8fa7\n" #~ "2 Nodes configured, 2 expected votes\n" #~ "6 Resources configured.\n" #~ "============\n" #~ "\n" #~ "Online: [ pcmk-1 pcmk-2 ]\n" #~ "\n" #~ "WebSite (ocf::heartbeat:apache):        Started pcmk-2\n" #~ "Master/Slave Set: WebDataClone\n" #~ "        Masters: [ pcmk-1 ]\n" #~ "        Slaves: [ pcmk-2 ]\n" #~ "ClusterIP        (ocf::heartbeat:IPaddr):        Started pcmk-2\n" #~ "Clone Set: dlm-clone\n" #~ "        Started: [ pcmk-2 pcmk-1 ]\n" #~ "Clone Set: gfs-clone\n" #~ " Started: [ pcmk-2 pcmk-1 ]\n" #~ "WebFS   (ocf::heartbeat:Filesystem):    Started pcmk-1\n" #~ msgid "" #~ "\n" #~ "[root@pcmk-1 ~]# crm_resource --resource WebFS --set-parameter target-role --meta --parameter-value Stopped\n" #~ "[root@pcmk-1 ~]# crm_mon\n" #~ "============\n" #~ "Last updated: Thu Sep  3 15:18:06 2009\n" #~ "Stack: openais\n" #~ "Current DC: pcmk-1 - partition with quorum\n" #~ "Version: 1.0.5-462f1569a43740667daf7b0f6b521742e9eb8fa7\n" #~ "2 Nodes configured, 2 expected votes\n" #~ "6 Resources configured.\n" #~ "============\n" #~ "\n" #~ "Online: [ pcmk-1 pcmk-2 ]\n" #~ "\n" #~ "Master/Slave Set: WebDataClone\n" #~ "        Masters: [ pcmk-1 ]\n" #~ "        Slaves: [ pcmk-2 ]\n" #~ "ClusterIP        (ocf::heartbeat:IPaddr):        Started pcmk-1\n" #~ "Clone Set: dlm-clone\n" #~ "        Started: [ pcmk-2 pcmk-1 ]\n" #~ "Clone Set: gfs-clone\n" #~ "        Started: [ pcmk-2 pcmk-1 ]\n" #~ msgstr "" #~ "\n" #~ "[root@pcmk-1 ~]# crm_resource --resource WebFS --set-parameter target-role --meta --parameter-value Stopped\n" #~ "[root@pcmk-1 ~]# crm_mon\n" #~ "============\n" #~ "Last updated: Thu Sep  3 15:18:06 2009\n" #~ "Stack: openais\n" #~ "Current DC: pcmk-1 - partition with quorum\n" #~ "Version: 1.0.5-462f1569a43740667daf7b0f6b521742e9eb8fa7\n" #~ "2 Nodes configured, 2 expected votes\n" #~ "6 Resources configured.\n" #~ "============\n" #~ "\n" #~ "Online: [ pcmk-1 pcmk-2 ]\n" #~ "\n" #~ "Master/Slave Set: WebDataClone\n" #~ "        Masters: [ pcmk-1 ]\n" #~ "        Slaves: [ pcmk-2 ]\n" #~ "ClusterIP        (ocf::heartbeat:IPaddr):        Started pcmk-1\n" #~ "Clone Set: dlm-clone\n" #~ "        Started: [ pcmk-2 pcmk-1 ]\n" #~ "Clone Set: gfs-clone\n" #~ "        Started: [ pcmk-2 pcmk-1 ]\n" #~ msgid "Lastly, we use -t to specify the lock table name. The format for this field is clustername:fsname. For the fsname, we just need to pick something unique and descriptive and since we haven’t specified a clustername yet, we will use the default (pcmk)." #~ msgstr "最后,我们用-t来指定lock table的名称。这个字段的格式是 clustername:fsname(集群名称:文件系统名称)。fsname的话,我们只要用一个唯一的并且能描述我们这个集群的名称就好了,我们用默认的pcmk。" #~ msgid "To specify an alternate name for the cluster, locate the service section containing “name: pacemaker” in corosync.conf and insert the following line anywhere inside the block:" #~ msgstr "如果要更改集群的名称,找到包含name:pacemaker的配置文件区域,然后添加如下所示的选项即可。" #~ msgid "clustername: myname" #~ msgstr "clustername: myname" #~ msgid "Do this on each node in the cluster and be sure to restart them before continuing." #~ msgstr "在每个节点都执行以下命令。" #~ msgid "" #~ "\n" #~ "mkfs.gfs2 -p lock_dlm -j 2 -t pcmk:web /dev/drbd1\n" #~ "[root@pcmk-1 ~]# mkfs.gfs2 -t pcmk:web -p lock_dlm -j 2 /dev/vdb \n" #~ "This will destroy any data on /dev/vdb.\n" #~ "It appears to contain: data\n" #~ "\n" #~ "Are you sure you want to proceed? [y/n] y\n" #~ "\n" #~ "Device:                    /dev/vdb\n" #~ "Blocksize:                 4096\n" #~ "Device Size                1.00 GB (131072 blocks)\n" #~ "Filesystem Size:           1.00 GB (131070 blocks)\n" #~ "Journals:                  2\n" #~ "Resource Groups:           2\n" #~ "Locking Protocol:          \"lock_dlm\"\n" #~ "Lock Table:                \"pcmk:web\"\n" #~ "UUID:                      6B776F46-177B-BAF8-2C2B-292C0E078613\n" #~ "\n" #~ "[root@pcmk-1 ~]#\n" #~ msgstr "" #~ "\n" #~ "mkfs.gfs2 -p lock_dlm -j 2 -t pcmk:web /dev/drbd1\n" #~ "[root@pcmk-1 ~]# mkfs.gfs2 -t pcmk:web -p lock_dlm -j 2 /dev/vdb \n" #~ "This will destroy any data on /dev/vdb.\n" #~ "It appears to contain: data\n" #~ "\n" #~ "Are you sure you want to proceed? [y/n] y\n" #~ "\n" #~ "Device:                    /dev/vdb\n" #~ "Blocksize:                 4096\n" #~ "Device Size                1.00 GB (131072 blocks)\n" #~ "Filesystem Size:           1.00 GB (131070 blocks)\n" #~ "Journals:                  2\n" #~ "Resource Groups:           2\n" #~ "Locking Protocol:          \"lock_dlm\"\n" #~ "Lock Table:                \"pcmk:web\"\n" #~ "UUID:                      6B776F46-177B-BAF8-2C2B-292C0E078613\n" #~ "\n" #~ "[root@pcmk-1 ~]#\n" #~ msgid "" #~ "\n" #~ "[root@pcmk-1 ~]# crm\n" #~ "crm(live)# cib new GFS2\n" #~ "INFO: GFS2 shadow CIB created\n" #~ "crm(GFS2)# configure delete WebFS\n" #~ "crm(GFS2)# configure primitive WebFS ocf:heartbeat:Filesystem params device=\"/dev/drbd/by-res/wwwdata\" directory=\"/var/www/html\" fstype=”gfs2”\n" #~ msgstr "" #~ "\n" #~ "[root@pcmk-1 ~]# crm\n" #~ "crm(live)# cib new GFS2\n" #~ "INFO: GFS2 shadow CIB created\n" #~ "crm(GFS2)# configure delete WebFS\n" #~ "crm(GFS2)# configure primitive WebFS ocf:heartbeat:Filesystem params device=\"/dev/drbd/by-res/wwwdata\" directory=\"/var/www/html\" fstype=”gfs2”\n" #~ msgid "Now that we’ve recreated the resource, we also need to recreate all the constraints that used it. This is because the shell will automatically remove any constraints that referenced WebFS." #~ msgstr "现在我们重新创建这个资源, 我们也要重建跟这个资源相关的约束条件,因为shell会自动删除跟WebFS相关的约束条件。" #~ msgid "" #~ "\n" #~ "crm(GFS2)# configure colocation WebSite-with-WebFS inf: WebSite WebFS\n" #~ "crm(GFS2)# configure colocation fs_on_drbd inf: WebFS WebDataClone:Master\n" #~ "crm(GFS2)# configure order WebFS-after-WebData inf: WebDataClone:promote WebFS:start\n" #~ "crm(GFS2)# configure order WebSite-after-WebFS inf: WebFS WebSite\n" #~ "crm(GFS2)# configure colocation WebFS-with-gfs-control INFINITY: WebFS gfs-clone\n" #~ "crm(GFS2)# configure order start-WebFS-after-gfs-control mandatory: gfs-clone WebFS\n" #~ "crm(GFS2)# configure show\n" #~ "node pcmk-1\n" #~ "node pcmk-2\n" #~ "primitive WebData ocf:linbit:drbd \\\n" #~ "        params drbd_resource=\"wwwdata\" \\\n" #~ "        op monitor interval=\"60s\"\n" #~ "primitive WebFS ocf:heartbeat:Filesystem \\\n" #~ " params device=\"/dev/drbd/by-res/wwwdata\" directory=\"/var/www/html\" fstype=”gfs2”\n" #~ "primitive WebSite ocf:heartbeat:apache \\\n" #~ "        params configfile=\"/etc/httpd/conf/httpd.conf\" \\\n" #~ "        op monitor interval=\"1min\"\n" #~ "primitive ClusterIP ocf:heartbeat:IPaddr2 \\\n" #~ "        params ip=\"192.168.122.101\" cidr_netmask=\"32\" \\\n" #~ "        op monitor interval=\"30s\"\n" #~ "primitive dlm ocf:pacemaker:controld \\\n" #~ "        op monitor interval=\"120s\"\n" #~ "primitive gfs-control ocf:pacemaker:controld \\\n" #~ "   params daemon=”gfs_controld.pcmk” args=”-g 0” \\\n" #~ "        op monitor interval=\"120s\"\n" #~ "ms WebDataClone WebData \\\n" #~ "        meta master-max=\"1\" master-node-max=\"1\" clone-max=\"2\" clone-node-max=\"1\" notify=\"true\"\n" #~ "clone dlm-clone dlm \\\n" #~ "        meta interleave=\"true\"\n" #~ "clone gfs-clone gfs-control \\\n" #~ "        meta interleave=\"true\"\n" #~ "colocation WebFS-with-gfs-control inf: WebFS gfs-clone\n" #~ "colocation WebSite-with-WebFS inf: WebSite WebFS\n" #~ "colocation fs_on_drbd inf: WebFS WebDataClone:Master\n" #~ "colocation gfs-with-dlm inf: gfs-clone dlm-clone\n" #~ "colocation website-with-ip inf: WebSite ClusterIP\n" #~ "order WebFS-after-WebData inf: WebDataClone:promote WebFS:start\n" #~ "order WebSite-after-WebFS inf: WebFS WebSite\n" #~ "order apache-after-ip inf: ClusterIP WebSite\n" #~ "order start-WebFS-after-gfs-control inf: gfs-clone WebFS\n" #~ "order start-gfs-after-dlm inf: dlm-clone gfs-clone\n" #~ "property $id=\"cib-bootstrap-options\" \\\n" #~ "        dc-version=\"1.0.5-462f1569a43740667daf7b0f6b521742e9eb8fa7\" \\\n" #~ "        cluster-infrastructure=\"openais\" \\\n" #~ "        expected-quorum-votes=”2” \\\n" #~ "        stonith-enabled=\"false\" \\\n" #~ "        no-quorum-policy=\"ignore\"\n" #~ "rsc_defaults $id=\"rsc-options\" \\\n" #~ "        resource-stickiness=”100”\n" #~ msgstr "" #~ "\n" #~ "crm(GFS2)# configure colocation WebSite-with-WebFS inf: WebSite WebFS\n" #~ "crm(GFS2)# configure colocation fs_on_drbd inf: WebFS WebDataClone:Master\n" #~ "crm(GFS2)# configure order WebFS-after-WebData inf: WebDataClone:promote WebFS:start\n" #~ "crm(GFS2)# configure order WebSite-after-WebFS inf: WebFS WebSite\n" #~ "crm(GFS2)# configure colocation WebFS-with-gfs-control INFINITY: WebFS gfs-clone\n" #~ "crm(GFS2)# configure order start-WebFS-after-gfs-control mandatory: gfs-clone WebFS\n" #~ "crm(GFS2)# configure show\n" #~ "node pcmk-1\n" #~ "node pcmk-2\n" #~ "primitive WebData ocf:linbit:drbd \\\n" #~ "        params drbd_resource=\"wwwdata\" \\\n" #~ "        op monitor interval=\"60s\"\n" #~ "primitive WebFS ocf:heartbeat:Filesystem \\\n" #~ " params device=\"/dev/drbd/by-res/wwwdata\" directory=\"/var/www/html\" fstype=”gfs2”\n" #~ "primitive WebSite ocf:heartbeat:apache \\\n" #~ "        params configfile=\"/etc/httpd/conf/httpd.conf\" \\\n" #~ "        op monitor interval=\"1min\"\n" #~ "primitive ClusterIP ocf:heartbeat:IPaddr2 \\\n" #~ "        params ip=\"192.168.122.101\" cidr_netmask=\"32\" \\\n" #~ "        op monitor interval=\"30s\"\n" #~ "primitive dlm ocf:pacemaker:controld \\\n" #~ "        op monitor interval=\"120s\"\n" #~ "primitive gfs-control ocf:pacemaker:controld \\\n" #~ "   params daemon=”gfs_controld.pcmk” args=”-g 0” \\\n" #~ "        op monitor interval=\"120s\"\n" #~ "ms WebDataClone WebData \\\n" #~ "        meta master-max=\"1\" master-node-max=\"1\" clone-max=\"2\" clone-node-max=\"1\" notify=\"true\"\n" #~ "clone dlm-clone dlm \\\n" #~ "        meta interleave=\"true\"\n" #~ "clone gfs-clone gfs-control \\\n" #~ "        meta interleave=\"true\"\n" #~ "colocation WebFS-with-gfs-control inf: WebFS gfs-clone\n" #~ "colocation WebSite-with-WebFS inf: WebSite WebFS\n" #~ "colocation fs_on_drbd inf: WebFS WebDataClone:Master\n" #~ "colocation gfs-with-dlm inf: gfs-clone dlm-clone\n" #~ "colocation website-with-ip inf: WebSite ClusterIP\n" #~ "order WebFS-after-WebData inf: WebDataClone:promote WebFS:start\n" #~ "order WebSite-after-WebFS inf: WebFS WebSite\n" #~ "order apache-after-ip inf: ClusterIP WebSite\n" #~ "order start-WebFS-after-gfs-control inf: gfs-clone WebFS\n" #~ "order start-gfs-after-dlm inf: dlm-clone gfs-clone\n" #~ "property $id=\"cib-bootstrap-options\" \\\n" #~ "        dc-version=\"1.0.5-462f1569a43740667daf7b0f6b521742e9eb8fa7\" \\\n" #~ "        cluster-infrastructure=\"openais\" \\\n" #~ "        expected-quorum-votes=”2” \\\n" #~ "        stonith-enabled=\"false\" \\\n" #~ "        no-quorum-policy=\"ignore\"\n" #~ "rsc_defaults $id=\"rsc-options\" \\\n" #~ "        resource-stickiness=”100”\n" #~ msgid "" #~ "\n" #~ "crm(GFS2)# cib commit GFS2\n" #~ "INFO: commited 'GFS2' shadow CIB to the cluster\n" #~ "crm(GFS2)# quit\n" #~ "bye\n" #~ "[root@pcmk-1 ~]# crm_mon\n" #~ "============\n" #~ "Last updated: Thu Sep  3 20:49:54 2009\n" #~ "Stack: openais\n" #~ "Current DC: pcmk-2 - partition with quorum\n" #~ "Version: 1.0.5-462f1569a43740667daf7b0f6b521742e9eb8fa7\n" #~ "2 Nodes configured, 2 expected votes\n" #~ "6 Resources configured.\n" #~ "============\n" #~ "\n" #~ "Online: [ pcmk-1 pcmk-2 ]\n" #~ "\n" #~ "WebSite (ocf::heartbeat:apache):        Started pcmk-2\n" #~ "Master/Slave Set: WebDataClone\n" #~ "        Masters: [ pcmk-1 ]\n" #~ "        Slaves: [ pcmk-2 ]\n" #~ "ClusterIP        (ocf::heartbeat:IPaddr):        Started pcmk-2\n" #~ "Clone Set: dlm-clone\n" #~ "        Started: [ pcmk-2 pcmk-1 ]\n" #~ "Clone Set: gfs-clone\n" #~ "        Started: [ pcmk-2 pcmk-1 ]\n" #~ "WebFS (ocf::heartbeat:Filesystem): Started pcmk-1\n" #~ msgstr "" #~ "\n" #~ "crm(GFS2)# cib commit GFS2\n" #~ "INFO: commited 'GFS2' shadow CIB to the cluster\n" #~ "crm(GFS2)# quit\n" #~ "bye\n" #~ "[root@pcmk-1 ~]# crm_mon\n" #~ "============\n" #~ "Last updated: Thu Sep  3 20:49:54 2009\n" #~ "Stack: openais\n" #~ "Current DC: pcmk-2 - partition with quorum\n" #~ "Version: 1.0.5-462f1569a43740667daf7b0f6b521742e9eb8fa7\n" #~ "2 Nodes configured, 2 expected votes\n" #~ "6 Resources configured.\n" #~ "============\n" #~ "\n" #~ "Online: [ pcmk-1 pcmk-2 ]\n" #~ "\n" #~ "WebSite (ocf::heartbeat:apache):        Started pcmk-2\n" #~ "Master/Slave Set: WebDataClone\n" #~ "        Masters: [ pcmk-1 ]\n" #~ "        Slaves: [ pcmk-2 ]\n" #~ "ClusterIP        (ocf::heartbeat:IPaddr):        Started pcmk-2\n" #~ "Clone Set: dlm-clone\n" #~ "        Started: [ pcmk-2 pcmk-1 ]\n" #~ "Clone Set: gfs-clone\n" #~ "        Started: [ pcmk-2 pcmk-1 ]\n" #~ "WebFS (ocf::heartbeat:Filesystem): Started pcmk-1\n" #~ msgid "" #~ "\n" #~ "[root@pcmk-1 ~]# crm\n" #~ "[root@pcmk-1 ~]# cib new active\n" #~ " " #~ msgstr "" #~ "\n" #~ "[root@pcmk-1 ~]# crm\n" #~ "[root@pcmk-1 ~]# cib new active\n" #~ " " #~ msgid "" #~ "\n" #~ "[root@pcmk-1 ~]# configure clone WebIP ClusterIP  \\\n" #~ "        meta globally-unique=”true” clone-max=”2” clone-node-max=”2”\n" #~ " " #~ msgstr "" #~ "\n" #~ "[root@pcmk-1 ~]# configure clone WebIP ClusterIP  \\\n" #~ "        meta globally-unique=”true” clone-max=”2” clone-node-max=”2”\n" #~ " " #~ msgid "Open the ClusterIP resource" #~ msgstr "打开ClusterIP的配置" #~ msgid "[root@pcmk-1 ~]# configure edit  ClusterIP" #~ msgstr "[root@pcmk-1 ~]# configure edit  ClusterIP" #~ msgid "And add the following to the params line" #~ msgstr "在参数行添加以下内容:" #~ msgid "clusterip_hash=\"sourceip\"" #~ msgstr "clusterip_hash=\"sourceip\"" #~ msgid "So that the complete definition looks like:" #~ msgstr "完整的定义就像下面一样:" #~ msgid "" #~ "\n" #~ "primitive ClusterIP ocf:heartbeat:IPaddr2 \\ \n" #~ "        params ip=\"192.168.122.101\" cidr_netmask=\"32\" clusterip_hash=\"sourceip\" \\\n" #~ "        op monitor interval=\"30s\"\n" #~ " " #~ msgstr "" #~ "\n" #~ "primitive ClusterIP ocf:heartbeat:IPaddr2 \\ \n" #~ "        params ip=\"192.168.122.101\" cidr_netmask=\"32\" clusterip_hash=\"sourceip\" \\\n" #~ "        op monitor interval=\"30s\"\n" #~ " " #~ msgid "Here is the full transcript" #~ msgstr "以下是完整的配置" #~ msgid "" #~ "\n" #~ "[root@pcmk-1 ~]# crm \n" #~ "crm(live)# cib new active\n" #~ "INFO: active shadow CIB created\n" #~ "crm(active)# configure clone WebIP ClusterIP  \\\n" #~ "        meta globally-unique=”true” clone-max=”2” clone-node-max=”2”\n" #~ "crm(active)# configure show\n" #~ "node pcmk-1\n" #~ "node pcmk-2\n" #~ "primitive WebData ocf:linbit:drbd \\\n" #~ "        params drbd_resource=\"wwwdata\" \\\n" #~ "        op monitor interval=\"60s\"\n" #~ "primitive WebFS ocf:heartbeat:Filesystem \\\n" #~ "        params device=\"/dev/drbd/by-res/wwwdata\" directory=\"/var/www/html\" fstype=”gfs2”\n" #~ "primitive WebSite ocf:heartbeat:apache \\\n" #~ "        params configfile=\"/etc/httpd/conf/httpd.conf\" \\\n" #~ "        op monitor interval=\"1min\"\n" #~ "primitive ClusterIP ocf:heartbeat:IPaddr2 \\\n" #~ "        params ip=”192.168.122.101” cidr_netmask=”32” clusterip_hash=”sourceip” \\\n" #~ "        op monitor interval=\"30s\"\n" #~ "primitive dlm ocf:pacemaker:controld \\\n" #~ "        op monitor interval=\"120s\"\n" #~ "primitive gfs-control ocf:pacemaker:controld \\\n" #~ "   params daemon=”gfs_controld.pcmk” args=”-g 0” \\\n" #~ "        op monitor interval=\"120s\"\n" #~ "ms WebDataClone WebData \\\n" #~ "        meta master-max=\"1\" master-node-max=\"1\" clone-max=\"2\" clone-node-max=\"1\" notify=\"true\"\n" #~ "clone WebIP ClusterIP \\\n" #~ " meta globally-unique=”true” clone-max=”2” clone-node-max=”2”\n" #~ "clone dlm-clone dlm \\\n" #~ "        meta interleave=\"true\"\n" #~ "clone gfs-clone gfs-control \\\n" #~ "        meta interleave=\"true\"\n" #~ "colocation WebFS-with-gfs-control inf: WebFS gfs-clone\n" #~ "colocation WebSite-with-WebFS inf: WebSite WebFS\n" #~ "colocation fs_on_drbd inf: WebFS WebDataClone:Master\n" #~ "colocation gfs-with-dlm inf: gfs-clone dlm-clone\n" #~ "colocation website-with-ip inf: WebSite WebIP\n" #~ "order WebFS-after-WebData inf: WebDataClone:promote WebFS:start\n" #~ "order WebSite-after-WebFS inf: WebFS WebSite\n" #~ "order apache-after-ip inf: WebIP WebSite\n" #~ "order start-WebFS-after-gfs-control inf: gfs-clone WebFS\n" #~ "order start-gfs-after-dlm inf: dlm-clone gfs-clone\n" #~ "property $id=\"cib-bootstrap-options\" \\\n" #~ "        dc-version=\"1.0.5-462f1569a43740667daf7b0f6b521742e9eb8fa7\" \\\n" #~ "        cluster-infrastructure=\"openais\" \\\n" #~ "        expected-quorum-votes=”2” \\\n" #~ "        stonith-enabled=\"false\" \\\n" #~ "        no-quorum-policy=\"ignore\"\n" #~ "rsc_defaults $id=\"rsc-options\" \\\n" #~ "        resource-stickiness=”100”\n" #~ " " #~ msgstr "" #~ "\n" #~ "[root@pcmk-1 ~]# crm \n" #~ "crm(live)# cib new active\n" #~ "INFO: active shadow CIB created\n" #~ "crm(active)# configure clone WebIP ClusterIP  \\\n" #~ "        meta globally-unique=”true” clone-max=”2” clone-node-max=”2”\n" #~ "crm(active)# configure show\n" #~ "node pcmk-1\n" #~ "node pcmk-2\n" #~ "primitive WebData ocf:linbit:drbd \\\n" #~ "        params drbd_resource=\"wwwdata\" \\\n" #~ "        op monitor interval=\"60s\"\n" #~ "primitive WebFS ocf:heartbeat:Filesystem \\\n" #~ "        params device=\"/dev/drbd/by-res/wwwdata\" directory=\"/var/www/html\" fstype=”gfs2”\n" #~ "primitive WebSite ocf:heartbeat:apache \\\n" #~ "        params configfile=\"/etc/httpd/conf/httpd.conf\" \\\n" #~ "        op monitor interval=\"1min\"\n" #~ "primitive ClusterIP ocf:heartbeat:IPaddr2 \\\n" #~ "        params ip=”192.168.122.101” cidr_netmask=”32” clusterip_hash=”sourceip” \\\n" #~ "        op monitor interval=\"30s\"\n" #~ "primitive dlm ocf:pacemaker:controld \\\n" #~ "        op monitor interval=\"120s\"\n" #~ "primitive gfs-control ocf:pacemaker:controld \\\n" #~ "   params daemon=”gfs_controld.pcmk” args=”-g 0” \\\n" #~ "        op monitor interval=\"120s\"\n" #~ "ms WebDataClone WebData \\\n" #~ "        meta master-max=\"1\" master-node-max=\"1\" clone-max=\"2\" clone-node-max=\"1\" notify=\"true\"\n" #~ "clone WebIP ClusterIP \\\n" #~ " meta globally-unique=”true” clone-max=”2” clone-node-max=”2”\n" #~ "clone dlm-clone dlm \\\n" #~ "        meta interleave=\"true\"\n" #~ "clone gfs-clone gfs-control \\\n" #~ "        meta interleave=\"true\"\n" #~ "colocation WebFS-with-gfs-control inf: WebFS gfs-clone\n" #~ "colocation WebSite-with-WebFS inf: WebSite WebFS\n" #~ "colocation fs_on_drbd inf: WebFS WebDataClone:Master\n" #~ "colocation gfs-with-dlm inf: gfs-clone dlm-clone\n" #~ "colocation website-with-ip inf: WebSite WebIP\n" #~ "order WebFS-after-WebData inf: WebDataClone:promote WebFS:start\n" #~ "order WebSite-after-WebFS inf: WebFS WebSite\n" #~ "order apache-after-ip inf: WebIP WebSite\n" #~ "order start-WebFS-after-gfs-control inf: gfs-clone WebFS\n" #~ "order start-gfs-after-dlm inf: dlm-clone gfs-clone\n" #~ "property $id=\"cib-bootstrap-options\" \\\n" #~ "        dc-version=\"1.0.5-462f1569a43740667daf7b0f6b521742e9eb8fa7\" \\\n" #~ "        cluster-infrastructure=\"openais\" \\\n" #~ "        expected-quorum-votes=”2” \\\n" #~ "        stonith-enabled=\"false\" \\\n" #~ "        no-quorum-policy=\"ignore\"\n" #~ "rsc_defaults $id=\"rsc-options\" \\\n" #~ "        resource-stickiness=”100”\n" #~ " " #~ msgid "Notice how any constraints that referenced ClusterIP have been updated to use WebIP instead. This is an additional benefit of using the crm shell." #~ msgstr "请注意所有跟ClusterIP相关的限制都已经被更新到与WebIP相关,这是使用crm shell的另一个好处。" #~ msgid "" #~ "\n" #~ "crm(active)# configure clone WebFSClone WebFS\n" #~ "crm(active)# configure clone WebSiteClone WebSite\n" #~ " " #~ msgstr "" #~ "\n" #~ "crm(active)# configure clone WebFSClone WebFS\n" #~ "crm(active)# configure clone WebSiteClone WebSite\n" #~ " " #~ msgid "" #~ "\n" #~ "crm(active)# configure edit WebDataClone\n" #~ " " #~ msgstr "" #~ "\n" #~ "crm(active)# configure edit WebDataClone\n" #~ " " #~ msgid "Change master-max to 2" #~ msgstr "把 master-max 改为 2" #~ msgid "" #~ "\n" #~ "crm(active)# configure show\n" #~ "node pcmk-1\n" #~ "node pcmk-2\n" #~ "primitive WebData ocf:linbit:drbd \\\n" #~ "        params drbd_resource=\"wwwdata\" \\\n" #~ "        op monitor interval=\"60s\"\n" #~ "primitive WebFS ocf:heartbeat:Filesystem \\\n" #~ "        params device=\"/dev/drbd/by-res/wwwdata\" directory=\"/var/www/html\" fstype=”gfs2”\n" #~ "primitive WebSite ocf:heartbeat:apache \\\n" #~ "        params configfile=\"/etc/httpd/conf/httpd.conf\" \\\n" #~ "        op monitor interval=\"1min\"\n" #~ "primitive ClusterIP ocf:heartbeat:IPaddr2 \\\n" #~ "        params ip=”192.168.122.101” cidr_netmask=”32” clusterip_hash=”sourceip” \\\n" #~ "        op monitor interval=\"30s\"\n" #~ "primitive dlm ocf:pacemaker:controld \\\n" #~ "        op monitor interval=\"120s\"\n" #~ "primitive gfs-control ocf:pacemaker:controld \\\n" #~ "   params daemon=”gfs_controld.pcmk” args=”-g 0” \\\n" #~ "        op monitor interval=\"120s\"\n" #~ "ms WebDataClone WebData \\\n" #~ "        meta master-max=\"2\" master-node-max=\"1\" clone-max=\"2\" clone-node-max=\"1\" notify=\"true\"\n" #~ "clone WebFSClone WebFS\n" #~ "clone WebIP ClusterIP  \\\n" #~ "        meta globally-unique=”true” clone-max=”2” clone-node-max=”2”\n" #~ "clone WebSiteClone WebSite\n" #~ "clone dlm-clone dlm \\\n" #~ "        meta interleave=\"true\"\n" #~ "clone gfs-clone gfs-control \\\n" #~ "        meta interleave=\"true\"\n" #~ "colocation WebFS-with-gfs-control inf: WebFSClone gfs-clone\n" #~ "colocation WebSite-with-WebFS inf: WebSiteClone WebFSClone\n" #~ "colocation fs_on_drbd inf: WebFSClone WebDataClone:Master\n" #~ "colocation gfs-with-dlm inf: gfs-clone dlm-clone\n" #~ "colocation website-with-ip inf: WebSiteClone WebIP\n" #~ "order WebFS-after-WebData inf: WebDataClone:promote WebFSClone:start\n" #~ "order WebSite-after-WebFS inf: WebFSClone WebSiteClone\n" #~ "order apache-after-ip inf: WebIP WebSiteClone\n" #~ "order start-WebFS-after-gfs-control inf: gfs-clone WebFSClone\n" #~ "order start-gfs-after-dlm inf: dlm-clone gfs-clone\n" #~ "property $id=\"cib-bootstrap-options\" \\\n" #~ "        dc-version=\"1.0.5-462f1569a43740667daf7b0f6b521742e9eb8fa7\" \\\n" #~ "        cluster-infrastructure=\"openais\" \\\n" #~ "        expected-quorum-votes=”2” \\\n" #~ "        stonith-enabled=\"false\" \\\n" #~ "        no-quorum-policy=\"ignore\"\n" #~ "rsc_defaults $id=\"rsc-options\" \\\n" #~ "        resource-stickiness=”100”\n" #~ " " #~ msgstr "" #~ "\n" #~ "crm(active)# configure show\n" #~ "node pcmk-1\n" #~ "node pcmk-2\n" #~ "primitive WebData ocf:linbit:drbd \\\n" #~ "        params drbd_resource=\"wwwdata\" \\\n" #~ "        op monitor interval=\"60s\"\n" #~ "primitive WebFS ocf:heartbeat:Filesystem \\\n" #~ "        params device=\"/dev/drbd/by-res/wwwdata\" directory=\"/var/www/html\" fstype=”gfs2”\n" #~ "primitive WebSite ocf:heartbeat:apache \\\n" #~ "        params configfile=\"/etc/httpd/conf/httpd.conf\" \\\n" #~ "        op monitor interval=\"1min\"\n" #~ "primitive ClusterIP ocf:heartbeat:IPaddr2 \\\n" #~ "        params ip=”192.168.122.101” cidr_netmask=”32” clusterip_hash=”sourceip” \\\n" #~ "        op monitor interval=\"30s\"\n" #~ "primitive dlm ocf:pacemaker:controld \\\n" #~ "        op monitor interval=\"120s\"\n" #~ "primitive gfs-control ocf:pacemaker:controld \\\n" #~ "   params daemon=”gfs_controld.pcmk” args=”-g 0” \\\n" #~ "        op monitor interval=\"120s\"\n" #~ "ms WebDataClone WebData \\\n" #~ "        meta master-max=\"2\" master-node-max=\"1\" clone-max=\"2\" clone-node-max=\"1\" notify=\"true\"\n" #~ "clone WebFSClone WebFS\n" #~ "clone WebIP ClusterIP  \\\n" #~ "        meta globally-unique=”true” clone-max=”2” clone-node-max=”2”\n" #~ "clone WebSiteClone WebSite\n" #~ "clone dlm-clone dlm \\\n" #~ "        meta interleave=\"true\"\n" #~ "clone gfs-clone gfs-control \\\n" #~ "        meta interleave=\"true\"\n" #~ "colocation WebFS-with-gfs-control inf: WebFSClone gfs-clone\n" #~ "colocation WebSite-with-WebFS inf: WebSiteClone WebFSClone\n" #~ "colocation fs_on_drbd inf: WebFSClone WebDataClone:Master\n" #~ "colocation gfs-with-dlm inf: gfs-clone dlm-clone\n" #~ "colocation website-with-ip inf: WebSiteClone WebIP\n" #~ "order WebFS-after-WebData inf: WebDataClone:promote WebFSClone:start\n" #~ "order WebSite-after-WebFS inf: WebFSClone WebSiteClone\n" #~ "order apache-after-ip inf: WebIP WebSiteClone\n" #~ "order start-WebFS-after-gfs-control inf: gfs-clone WebFSClone\n" #~ "order start-gfs-after-dlm inf: dlm-clone gfs-clone\n" #~ "property $id=\"cib-bootstrap-options\" \\\n" #~ "        dc-version=\"1.0.5-462f1569a43740667daf7b0f6b521742e9eb8fa7\" \\\n" #~ "        cluster-infrastructure=\"openais\" \\\n" #~ "        expected-quorum-votes=”2” \\\n" #~ "        stonith-enabled=\"false\" \\\n" #~ "        no-quorum-policy=\"ignore\"\n" #~ "rsc_defaults $id=\"rsc-options\" \\\n" #~ "        resource-stickiness=”100”\n" #~ " " #~ msgid "" #~ "\n" #~ "crm(active)# cib commit active\n" #~ "INFO: commited 'active' shadow CIB to the cluster\n" #~ "crm(active)# quit\n" #~ "bye\n" #~ "[root@pcmk-1 ~]# crm_mon\n" #~ "============\n" #~ "Last updated: Thu Sep  3 21:37:27 2009\n" #~ "Stack: openais\n" #~ "Current DC: pcmk-2 - partition with quorum\n" #~ "Version: 1.0.5-462f1569a43740667daf7b0f6b521742e9eb8fa7\n" #~ "2 Nodes configured, 2 expected votes\n" #~ "6 Resources configured.\n" #~ "============\n" #~ "\n" #~ "Online: [ pcmk-1 pcmk-2 ]\n" #~ "\n" #~ "Master/Slave Set: WebDataClone\n" #~ "        Masters: [ pcmk-1 pcmk-2 ]\n" #~ "Clone Set: dlm-clone\n" #~ "        Started: [ pcmk-2 pcmk-1 ]\n" #~ "Clone Set: gfs-clone\n" #~ "        Started: [ pcmk-2 pcmk-1 ]\n" #~ "Clone Set: WebIP\n" #~ " Started: [ pcmk-1 pcmk-2 ]\n" #~ "Clone Set: WebFSClone\n" #~ " Started: [ pcmk-1 pcmk-2 ]\n" #~ "Clone Set: WebSiteClone\n" #~ " Started: [ pcmk-1 pcmk-2 ]\n" #~ " " #~ msgstr "" #~ "\n" #~ "crm(active)# cib commit active\n" #~ "INFO: commited 'active' shadow CIB to the cluster\n" #~ "crm(active)# quit\n" #~ "bye\n" #~ "[root@pcmk-1 ~]# crm_mon\n" #~ "============\n" #~ "Last updated: Thu Sep  3 21:37:27 2009\n" #~ "Stack: openais\n" #~ "Current DC: pcmk-2 - partition with quorum\n" #~ "Version: 1.0.5-462f1569a43740667daf7b0f6b521742e9eb8fa7\n" #~ "2 Nodes configured, 2 expected votes\n" #~ "6 Resources configured.\n" #~ "============\n" #~ "\n" #~ "Online: [ pcmk-1 pcmk-2 ]\n" #~ "\n" #~ "Master/Slave Set: WebDataClone\n" #~ "        Masters: [ pcmk-1 pcmk-2 ]\n" #~ "Clone Set: dlm-clone\n" #~ "        Started: [ pcmk-2 pcmk-1 ]\n" #~ "Clone Set: gfs-clone\n" #~ "        Started: [ pcmk-2 pcmk-1 ]\n" #~ "Clone Set: WebIP\n" #~ " Started: [ pcmk-1 pcmk-2 ]\n" #~ "Clone Set: WebFSClone\n" #~ " Started: [ pcmk-1 pcmk-2 ]\n" #~ "Clone Set: WebSiteClone\n" #~ " Started: [ pcmk-1 pcmk-2 ]\n" #~ " " #~ msgid "The list of nodes the cluster considers to be available" #~ msgstr "集群认为列表中的节点都是可用的" #~ msgid "information and fencing capabilities." #~ msgstr "信息和隔离功能。" pacemaker-master/doc/Clusters_from_Scratch/zh-CN/Ch-Active-Passive.mo000066400000000000000000000746541217637305600260230ustar00rootroot000000000000009O;@cE { }%sQG/UG"vb#$&C')$k)):*L*/*W+`X+"+$+8,L:,z-i.Rl.x.8/S1fL2o2c#33,33#3J4MS4*557C8'/:5W;+;G>7?Q9??@?@%@@A;B@DcG{xI}LrMBTQTWWUZ_v1`afcCe$:f_ffzg9gHgghjhh8hhZij?jTjjkSmd#nZn[n?o$Vo{o*o)oo>pP.qrs&t"u@u9w6)xN`xx?Ay*y!23*$7)  &/#'1, 9  (5+0"6%-48.  crm configure primitive ClusterIP ocf:heartbeat:IPaddr2 \         params ip=192.168.122.101 cidr_netmask=32 \         op monitor interval=30s [root@pcmk-1 ~]# /etc/init.d/corosync start Starting Corosync Cluster Engine (corosync): [ OK ] [root@pcmk-1 ~]# crm_mon ============ Last updated: Fri Aug 28 15:41:23 2009 Stack: openais Current DC: pcmk-2 - partition with quorum Version: 1.0.5-462f1569a43740667daf7b0f6b521742e9eb8fa7 2 Nodes configured, 2 expected votes 1 Resources configured. ============ Online: [ pcmk-1 pcmk-2 ] ClusterIP        (ocf::heartbeat:IPaddr):        Started pcmk-2 [root@pcmk-1 ~]# /etc/init.d/corosync start Starting Corosync Cluster Engine (corosync): [ OK ] [root@pcmk-1 ~]# crm_mon ============ Last updated: Fri Aug 28 15:32:13 2009 Stack: openais Current DC: pcmk-2 - partition with quorum Version: 1.0.5-462f1569a43740667daf7b0f6b521742e9eb8fa7 2 Nodes configured, 2 expected votes 1 Resources configured. ============ Online: [ pcmk-1 pcmk-2 ] ClusterIP        (ocf::heartbeat:IPaddr):        Started pcmk-1 [root@pcmk-1 ~]# crm configure property no-quorum-policy=ignore [root@pcmk-1 ~]# crm configure show node pcmk-1 node pcmk-2 primitive ClusterIP ocf:heartbeat:IPaddr2 \         params ip="192.168.122.101" cidr_netmask="32" \         op monitor interval="30s" property $id="cib-bootstrap-options" \         dc-version="1.0.5-462f1569a43740667daf7b0f6b521742e9eb8fa7" \         cluster-infrastructure="openais" \         expected-quorum-votes="2" \         stonith-enabled="false" \         no-quorum-policy="ignore" [root@pcmk-1 ~]# crm configure show node pcmk-1 node pcmk-2 primitive ClusterIP ocf:heartbeat:IPaddr2 \ params ip="192.168.122.101" cidr_netmask="32" \ op monitor interval="30s" property $id="cib-bootstrap-options" \         dc-version="1.0.5-462f1569a43740667daf7b0f6b521742e9eb8fa7" \         cluster-infrastructure="openais" \         expected-quorum-votes="2" \         stonith-enabled="false" \ [root@pcmk-1 ~]# crm_mon ============ Last updated: Fri Aug 28 15:23:48 2009 Stack: openais Current DC: pcmk-1 - partition with quorum Version: 1.0.5-462f1569a43740667daf7b0f6b521742e9eb8fa7 2 Nodes configured, 2 expected votes 1 Resources configured. ============ Online: [ pcmk-1 pcmk-2 ] ClusterIP (ocf::heartbeat:IPaddr): Started pcmk-1 [root@pcmk-1 ~]# crm ra classes heartbeat lsb ocf / heartbeat pacemaker stonith [root@pcmk-1 ~]# crm ra list ocf pacemaker ClusterMon     Dummy          Stateful       SysInfo        SystemHealth   controld ping           pingd           [root@pcmk-1 ~]# crm ra list ocf heartbeat AoEtarget              AudibleAlarm           ClusterMon             Delay Dummy                  EvmsSCC                Evmsd                  Filesystem ICP                    IPaddr                 IPaddr2                IPsrcaddr LVM                    LinuxSCSI              MailTo                 ManageRAID ManageVE               Pure-FTPd              Raid1                  Route SAPDatabase            SAPInstance            SendArp                ServeRAID SphinxSearchDaemon     Squid                  Stateful               SysInfo VIPArip                VirtualDomain          WAS                    WAS6 WinPopup               Xen                    Xinetd                 anything apache                 db2                    drbd                   eDir88 iSCSILogicalUnit       iSCSITarget            ids                    iscsi ldirectord             mysql                  mysql-proxy            nfsserver oracle                 oralsnr                pgsql                  pingd portblock              rsyncd                 scsi2reservation       sfex tomcat                 vmware                 [root@pcmk-1 ~]# [root@pcmk-1 ~]# crm resource status ClusterIP resource ClusterIP is running on: pcmk-1 [root@pcmk-1 ~]# [root@pcmk-1 ~]# crm_verify -L crm_verify[2195]: 2009/08/27_16:57:12 ERROR: unpack_resources: Resource start-up disabled since no STONITH resources have been defined crm_verify[2195]: 2009/08/27_16:57:12 ERROR: unpack_resources: Either configure some or disable STONITH with the stonith-enabled option crm_verify[2195]: 2009/08/27_16:57:12 ERROR: unpack_resources: NOTE: Clusters with shared data need STONITH to ensure data integrity Errors found during check: config not valid   -V may provide more details [root@pcmk-1 ~]# [root@pcmk-1 ~]# ssh pcmk-1 -- /etc/init.d/corosync stop Stopping Corosync Cluster Engine (corosync): [ OK ] Waiting for services to unload: [ OK ] [root@pcmk-1 ~]# [root@pcmk-1 ~]# ssh pcmk-1 -- /etc/init.d/corosync stop Stopping Corosync Cluster Engine (corosync):               [  OK  ] Waiting for services to unload:                            [  OK  ] [root@pcmk-1 ~]# ssh pcmk-2 -- crm_mon -1 ============ Last updated: Fri Aug 28 15:39:38 2009 Stack: openais Current DC: pcmk-2 - partition WITHOUT quorum Version: 1.0.5-462f1569a43740667daf7b0f6b521742e9eb8fa7 2 Nodes configured, 2 expected votes 1 Resources configured. ============ Online: [ pcmk-2 ] OFFLINE: [ pcmk-1 ] ClusterIP        (ocf::heartbeat:IPaddr):        Started pcmk-2 [root@pcmk-2 ~]# crm configure show xml <?xml version="1.0" ?> <cib admin_epoch="0" crm_feature_set="3.0.1" dc-uuid="pcmk-1" epoch="13" have-quorum="1" num_updates="7" validate-with="pacemaker-1.0">   <configuration>     <crm_config>       <cluster_property_set id="cib-bootstrap-options">         <nvpair id="cib-bootstrap-options-dc-version" name="dc-version" value="1.0.5-462f1569a43740667daf7b0f6b521742e9eb8fa7"/>         <nvpair id="cib-bootstrap-options-cluster-infrastructure" name="cluster-infrastructure" value="openais"/>         <nvpair id="cib-bootstrap-options-expected-quorum-votes" name="expected-quorum-votes" value="2"/>       </cluster_property_set>     </crm_config>     <rsc_defaults/>     <op_defaults/>     <nodes>       <node id="pcmk-1" type="normal" uname="pcmk-1"/>       <node id="pcmk-2" type="normal" uname="pcmk-2"/>     </nodes>     <resources/>     <constraints/>   </configuration> </cib> [root@pcmk-2 ~]# crm configure show node pcmk-1 node pcmk-2 property $id="cib-bootstrap-options" \         dc-version="1.0.5-462f1569a43740667daf7b0f6b521742e9eb8fa7" \         cluster-infrastructure="openais" \         expected-quorum-votes="2" [root@pcmk-2 ~]# crm_mon ============ Last updated: Fri Aug 28 15:27:35 2009 Stack: openais Current DC: pcmk-2 - partition WITHOUT quorum Version: 1.0.5-462f1569a43740667daf7b0f6b521742e9eb8fa7 2 Nodes configured, 2 expected votes 1 Resources configured. ============ Online: [ pcmk-2 ] OFFLINE: [ pcmk-1 ] [root@pcmk-2 ~]# crm_mon ============ Last updated: Fri Aug 28 15:30:18 2009 Stack: openais Current DC: pcmk-2 - partition WITHOUT quorum Version: 1.0.5-462f1569a43740667daf7b0f6b521742e9eb8fa7 2 Nodes configured, 2 expected votes 1 Resources configured. ============ Online: [ pcmk-2 ] OFFLINE: [ pcmk-1 ] ClusterIP (ocf::heartbeat:IPaddr): Started pcmk-2 crm configure rsc_defaults resource-stickiness=100 [root@pcmk-2 ~]# crm configure show node pcmk-1 node pcmk-2 primitive ClusterIP ocf:heartbeat:IPaddr2 \         params ip="192.168.122.101" cidr_netmask="32" \         op monitor interval="30s" property $id="cib-bootstrap-options" \         dc-version="1.0.5-462f1569a43740667daf7b0f6b521742e9eb8fa7" \         cluster-infrastructure="openais" \         expected-quorum-votes="2" \         stonith-enabled="false" \         no-quorum-policy="ignore" rsc_defaults $id="rsc-options" \ resource-stickiness="100" crm configure property stonith-enabled=falsecrm_verify -LA cluster is said to have quorum when more than half the known or expected nodes are online, or for the mathematically inclined, whenever the following equation is true:Adding a ResourceAfter a few moments, the cluster will start the IP address on the remaining node. Note that the cluster still does not have quorum.As you can see, the tool has found some errors.Before we make any changes, its a good idea to check the validity of the configuration.Being a high-availability cluster, we should test failover of our new resource before moving on.Creating an Active/Passive ClusterExploring the Existing ConfigurationFirst, find the node on which the IP address is running.For now, we will disable this feature and configure it later in the Configuring STONITH section. It is important to note that the use of STONITH is highly encouraged, turning it off tells the cluster to simply pretend that failed nodes are safely powered off. Some vendors will even refuse to support clusters that have it disabled.For those that are not of afraid of XML, you can see the raw configuration by appending “xml” to the previous command.Here we see something that some may consider surprising, the IP is back running at its original location!However when we bring pcmk-1 back online, ClusterIP now remains running on pcmk-2.If we now retry the failover test, we see that as expected ClusterIP still moves to pcmk-2 when pcmk-1 is taken offline.In order to guarantee the safety of your data If the data is corrupt, there is little point in continuing to make it available , Pacemaker ships with STONITH A common node fencing mechanism. Used to ensure data integrity by powering off “bad” nodes. enabled. However it also knows when no STONITH configuration has been supplied and reports this as a problem (since the cluster would not be able to make progress if a situation requiring node fencing arose).In some circumstances it is highly desirable to prevent healthy resources from being moved around the cluster. Move resources almost always requires a period of downtime and for complex services like Oracle databases, this period can be quite long.Now simulate node recovery by restarting the cluster stack on pcmk-1 and check the cluster’s status.Now verify that the IP resource has been added and display the cluster’s status to see that it is now active.Once Corosync is no longer running, go to the other node and check the cluster status with crm_mon.Perform a FailoverPrevent Resources from Moving after RecoveryQuorum and Two-Node ClustersShut down Corosync on that machine.The chosen address must not be one already associated with a physical nodeThe first thing we should do is configure an IP address. Regardless of where the cluster service(s) are running, we need a consistent address to contact them on. Here I will choose and add 192.168.122.101 as the floating address, give it the imaginative name ClusterIP and tell the cluster to check that its running every 30 seconds.The last XML you’ll see in this documentThe other important piece of information here is ocf:heartbeat:IPaddr2. This tells Pacemaker three things about the resource you want to add. The first field, ocf, is the standard to which the resource script conforms to and where to find it. The second field is specific to OCF resources and tells the cluster which namespace to find the resource script in, in this case heartbeat. The last field indicates the name of the resource script.There are three things to notice about the cluster’s current state. The first is that, as expected, pcmk-1 is now offline. However we can also see that ClusterIP isn’t running anywhere!Therefore a two-node cluster only has quorum when both nodes are running, which is no longer the case for our cluster. This would normally make the creation of a two-node cluster pointless Actually some would argue that two-node clusters are always pointless, but that is an argument for another time. , however it is possible to control how Pacemaker behaves when quorum is lost. In particular, we can tell the cluster to simply ignore quorum altogether.This is because the cluster no longer has quorum, as can be seen by the text “partition WITHOUT quorum” (emphasised green) in the output above. In order to reduce the possibility of data corruption, Pacemaker’s default behavior is to stop all resources if the cluster does not have quorum.This is what the base configuration should look like.To address this, Pacemaker has the concept of resource stickiness which controls how much a service prefers to stay running where it is. You may like to think of it as the “cost” of any downtime. By default, Pacemaker assumes there is zero cost associated with moving resources and will do so to achieve “optimal It should be noted that Pacemaker’s definition of optimal may not always agree with that of a human’s. The order in which Pacemaker processes lists of resources and nodes create implicit preferences (required in order to create a stabile solution) in situations where the administrator had not explicitly specified some. ” resource placement. We can specify a different stickiness for every resource, but it is often sufficient to change the default.To disable STONITH, we set the stonith-enabled cluster option to false.To obtain a list of the available resource classes, runTo then find all the OCF resource agents provided by Pacemaker and Heartbeat, runWhen Pacemaker starts up, it automatically records the number and details of the nodes in the cluster as well as which stack is being used and the version of Pacemaker being used.With the new cluster option set, the configuration is now valid.total_nodes - 1 < 2 * active_nodesProject-Id-Version: 0 POT-Creation-Date: 2010-12-15T23:32:36 PO-Revision-Date: 2010-12-16 00:24+0800 Last-Translator: Charlie Chen Language-Team: None Language: MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit crm configure primitive ClusterIP ocf:heartbeat:IPaddr2 \         params ip=192.168.122.101 cidr_netmask=32 \         op monitor interval=30s [root@pcmk-1 ~]# /etc/init.d/corosync start Starting Corosync Cluster Engine (corosync): [ OK ] [root@pcmk-1 ~]# crm_mon ============ Last updated: Fri Aug 28 15:41:23 2009 Stack: openais Current DC: pcmk-2 - partition with quorum Version: 1.0.5-462f1569a43740667daf7b0f6b521742e9eb8fa7 2 Nodes configured, 2 expected votes 1 Resources configured. ============ Online: [ pcmk-1 pcmk-2 ] ClusterIP        (ocf::heartbeat:IPaddr):        Started pcmk-2 [root@pcmk-1 ~]# /etc/init.d/corosync start Starting Corosync Cluster Engine (corosync): [ OK ] [root@pcmk-1 ~]# crm_mon ============ Last updated: Fri Aug 28 15:32:13 2009 Stack: openais Current DC: pcmk-2 - partition with quorum Version: 1.0.5-462f1569a43740667daf7b0f6b521742e9eb8fa7 2 Nodes configured, 2 expected votes 1 Resources configured. ============ Online: [ pcmk-1 pcmk-2 ] ClusterIP        (ocf::heartbeat:IPaddr):        Started pcmk-1 [root@pcmk-1 ~]# crm configure property no-quorum-policy=ignore [root@pcmk-1 ~]# crm configure show node pcmk-1 node pcmk-2 primitive ClusterIP ocf:heartbeat:IPaddr2 \         params ip="192.168.122.101" cidr_netmask="32" \         op monitor interval="30s" property $id="cib-bootstrap-options" \         dc-version="1.0.5-462f1569a43740667daf7b0f6b521742e9eb8fa7" \         cluster-infrastructure="openais" \         expected-quorum-votes="2" \         stonith-enabled="false" \         no-quorum-policy="ignore" [root@pcmk-1 ~]# crm configure show node pcmk-1 node pcmk-2 primitive ClusterIP ocf:heartbeat:IPaddr2 \ params ip="192.168.122.101" cidr_netmask="32" \ op monitor interval="30s" property $id="cib-bootstrap-options" \         dc-version="1.0.5-462f1569a43740667daf7b0f6b521742e9eb8fa7" \         cluster-infrastructure="openais" \         expected-quorum-votes="2" \         stonith-enabled="false" \ [root@pcmk-1 ~]# crm_mon ============ Last updated: Fri Aug 28 15:23:48 2009 Stack: openais Current DC: pcmk-1 - partition with quorum Version: 1.0.5-462f1569a43740667daf7b0f6b521742e9eb8fa7 2 Nodes configured, 2 expected votes 1 Resources configured. ============ Online: [ pcmk-1 pcmk-2 ] ClusterIP (ocf::heartbeat:IPaddr): Started pcmk-1 [root@pcmk-1 ~]# crm ra classes heartbeat lsb ocf / heartbeat pacemaker stonith [root@pcmk-1 ~]# crm ra list ocf pacemaker ClusterMon     Dummy          Stateful       SysInfo        SystemHealth   controld ping           pingd           [root@pcmk-1 ~]# crm ra list ocf heartbeat AoEtarget              AudibleAlarm           ClusterMon             Delay Dummy                  EvmsSCC                Evmsd                  Filesystem ICP                    IPaddr                 IPaddr2                IPsrcaddr LVM                    LinuxSCSI              MailTo                 ManageRAID ManageVE               Pure-FTPd              Raid1                  Route SAPDatabase            SAPInstance            SendArp                ServeRAID SphinxSearchDaemon     Squid                  Stateful               SysInfo VIPArip                VirtualDomain          WAS                    WAS6 WinPopup               Xen                    Xinetd                 anything apache                 db2                    drbd                   eDir88 iSCSILogicalUnit       iSCSITarget            ids                    iscsi ldirectord             mysql                  mysql-proxy            nfsserver oracle                 oralsnr                pgsql                  pingd portblock              rsyncd                 scsi2reservation       sfex tomcat                 vmware                 [root@pcmk-1 ~]# [root@pcmk-1 ~]# crm resource status ClusterIP resource ClusterIP is running on: pcmk-1 [root@pcmk-1 ~]# [root@pcmk-1 ~]# crm_verify -L crm_verify[2195]: 2009/08/27_16:57:12 ERROR: unpack_resources: Resource start-up disabled since no STONITH resources have been defined crm_verify[2195]: 2009/08/27_16:57:12 ERROR: unpack_resources: Either configure some or disable STONITH with the stonith-enabled option crm_verify[2195]: 2009/08/27_16:57:12 ERROR: unpack_resources: NOTE: Clusters with shared data need STONITH to ensure data integrity Errors found during check: config not valid   -V may provide more details [root@pcmk-1 ~]# [root@pcmk-1 ~]# ssh pcmk-1 -- /etc/init.d/corosync stop Stopping Corosync Cluster Engine (corosync): [ OK ] Waiting for services to unload: [ OK ] [root@pcmk-1 ~]# [root@pcmk-1 ~]# ssh pcmk-1 -- /etc/init.d/corosync stop Stopping Corosync Cluster Engine (corosync):               [  OK  ] Waiting for services to unload:                            [  OK  ] [root@pcmk-1 ~]# ssh pcmk-2 -- crm_mon -1 ============ Last updated: Fri Aug 28 15:39:38 2009 Stack: openais Current DC: pcmk-2 - partition WITHOUT quorum Version: 1.0.5-462f1569a43740667daf7b0f6b521742e9eb8fa7 2 Nodes configured, 2 expected votes 1 Resources configured. ============ Online: [ pcmk-2 ] OFFLINE: [ pcmk-1 ] ClusterIP        (ocf::heartbeat:IPaddr):        Started pcmk-2 [root@pcmk-2 ~]# crm configure show xml <?xml version="1.0" ?> <cib admin_epoch="0" crm_feature_set="3.0.1" dc-uuid="pcmk-1" epoch="13" have-quorum="1" num_updates="7" validate-with="pacemaker-1.0">   <configuration>     <crm_config>       <cluster_property_set id="cib-bootstrap-options">         <nvpair id="cib-bootstrap-options-dc-version" name="dc-version" value="1.0.5-462f1569a43740667daf7b0f6b521742e9eb8fa7"/>         <nvpair id="cib-bootstrap-options-cluster-infrastructure" name="cluster-infrastructure" value="openais"/>         <nvpair id="cib-bootstrap-options-expected-quorum-votes" name="expected-quorum-votes" value="2"/>       </cluster_property_set>     </crm_config>     <rsc_defaults/>     <op_defaults/>     <nodes>       <node id="pcmk-1" type="normal" uname="pcmk-1"/>       <node id="pcmk-2" type="normal" uname="pcmk-2"/>     </nodes>     <resources/>     <constraints/>   </configuration> </cib> [root@pcmk-2 ~]# crm configure show node pcmk-1 node pcmk-2 property $id="cib-bootstrap-options" \         dc-version="1.0.5-462f1569a43740667daf7b0f6b521742e9eb8fa7" \         cluster-infrastructure="openais" \         expected-quorum-votes="2" [root@pcmk-2 ~]# crm_mon ============ Last updated: Fri Aug 28 15:27:35 2009 Stack: openais Current DC: pcmk-2 - partition WITHOUT quorum Version: 1.0.5-462f1569a43740667daf7b0f6b521742e9eb8fa7 2 Nodes configured, 2 expected votes 1 Resources configured. ============ Online: [ pcmk-2 ] OFFLINE: [ pcmk-1 ] [root@pcmk-2 ~]# crm_mon ============ Last updated: Fri Aug 28 15:30:18 2009 Stack: openais Current DC: pcmk-2 - partition WITHOUT quorum Version: 1.0.5-462f1569a43740667daf7b0f6b521742e9eb8fa7 2 Nodes configured, 2 expected votes 1 Resources configured. ============ Online: [ pcmk-2 ] OFFLINE: [ pcmk-1 ] ClusterIP (ocf::heartbeat:IPaddr): Started pcmk-2 crm configure rsc_defaults resource-stickiness=100 [root@pcmk-2 ~]# crm configure show node pcmk-1 node pcmk-2 primitive ClusterIP ocf:heartbeat:IPaddr2 \         params ip="192.168.122.101" cidr_netmask="32" \         op monitor interval="30s" property $id="cib-bootstrap-options" \         dc-version="1.0.5-462f1569a43740667daf7b0f6b521742e9eb8fa7" \         cluster-infrastructure="openais" \         expected-quorum-votes="2" \         stonith-enabled="false" \         no-quorum-policy="ignore" rsc_defaults $id="rsc-options" \ resource-stickiness="100" crm configure property stonith-enabled=falsecrm_verify -L当有半数以上的节点在线时,这个集群就认为自己拥有法定人数了,是“合法”的,换而言之就是下面的公式:添加一个资源过了一会,集群会在剩下的那个节点上启动这个IP。请注意集群现在依然没有达到法定人数。就像你看到的,这个工具发现了一些错误。在我们做出任何改变之前,我们最好检查下配置文件。作为一个高可用的集群,我们在继续本文档之前,我们要需要测试失效备援 。创建一个主/备集群浏览现有配置首先,找到IP资源现在在哪个节点上运行。目前,我们禁用这个特性,然后在 配置STONISH 章节来配置它。这里要指出,使用STONITH是非常有必要的。关闭这个特性就是告诉集群:假装故障的节点已经安全的关机了。一些供应商甚至不允许这个特性被关闭。如果有谁想看看XML格式的,你可以添加xml选项来看到原始的配置文件现在我们可以看到让某些人惊奇的事情,IP资源回到原来那个节点(pcmk-1)上去了。但是当我们把pcmk-1恢复在线后,ClusterIP现在还是跑在pcmk-2上面。现在我们重新尝试失效援备测试,我们可以看到,正如我们所料,当pcmk-1不在线的时候ClusterIP还是移动到了pcmk-2为了确保您数据的安全性 如果数据是损坏的,那保证它的可用性是没有意义的 ,请使用配备STONITH 一个常见的隔离手段。用关掉坏节点电源的办法来保证数据完整 的Pacemaker。但是当没有配置STONITH的时候也会报这个错误(因为当集群中某个节点需要被隔离的时候,集群就无法工作了)。一些环境中会要求尽量避免资源在节点之间移动。移动资源通常意味着一段时间内无法提供服务,某些复杂的服务,比如Oracle数据库,这个时间可能会很长。现在模拟节点恢复,我们启动 pcmk-1 上面的Corosync服务,然后检查集群状态。现在检查下IP 资源是不是已经添加了,并且看看是否处在可用状态。当Corosync停止运行以后,我们到另外一个节点用crm_mon来检查集群状态. 做一次失效备援防止资源在节点恢复后移动法定人数和双节点集群关闭那个节点上面的Corosync服务:选择的IP地址不能被节点所占用首先要做的是配置一个IP地址,不管集群服务在哪运行,我们要一个固定的地址来提供服务。在这里我选择192.168.122.101作为浮动IP,给它取一个好记的名字 ClusterIP 并且告诉集群 每30秒检查它一次这是本文档最后一次显示XML。(作者怨念很深啊)另外一个重要的信息是 ocf:heartbeat:IPaddr2。这告诉Pacemaker三件事情,第一个部分,ocf,指明了这个资源采用的标准(类型)以及在哪能找到它。第二个部分标明这个资源脚本的在OCF中的名字空间,在这个例子中是heartbeat。最后一个部分指明了资源脚本的名称。关于集群状态,我们有三个地方需要注意,首先,如我们所料pcmk-1已经下线了,然而我们发现ClusterIP不在任何地方运行!因此在双节点的集群中,只有当两者都在线时才是合法的。 这个规则会让 双节点的集群 毫无意义,但是我们可以控制Pacemaker发现集群达不到法定人数时候的行为。简单来说,我们告诉集群忽略它 。这是因为集群已经达不到“法定人数”了,就像我们看到的“partition WITHOUT quorum” (用绿色强调的)。为了避免数据遭到破坏,当Pacemaker发现集群达不到法定人数时,就会停止所有的资源。这是初始配置文件的模样:为了达到这个效果,Pacemaker 有一个叫做 资源黏性值 的概念,它能够控制一个服务(资源)有多想呆在它正在运行的节点上。你可以把它认为是无法提供服务的“代价” 这里要注意的是Pacemaker定义的代价跟人们所想的不一样。如果管理员没有明确的指定参数(创建稳定环境所必须的),那么资源个节点在Pacemaker处理列表中的顺序会隐式地创建参数 ”。 Pacemaker为了达到最优分布各个资源的目的,默认设置这个值为0。我们可以为每个资源定义不同的黏性值,但一般来说,更改默认黏性值就够了。我们将 stonith-enabled设置为 false 来关闭STONITH可以运行下面的命令来获得可用的资源类找到OCF中Pacemaker和Heartbeat提供的资源脚本,运行下面的命令当Pacemaker启动的时候,它会自动记录节点的数量和详细信息,以及基层软件(本文中是corosync)和Pacemaker的版本。设置完这个选项以后,校验配置文件就正常了。总节点数 - 1 < 2 * 可用的节点pacemaker-master/doc/Clusters_from_Scratch/zh-CN/Ch-Active-Passive.po000066400000000000000000001317751217637305600260240ustar00rootroot00000000000000# # AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: 0\n" "POT-Creation-Date: 2012-10-17T05:19:03\n" "PO-Revision-Date: 2010-12-16 00:24+0800\n" "Last-Translator: Charlie Chen \n" "Language-Team: None\n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. Tag: title #, no-c-format msgid "Creating an Active/Passive Cluster" msgstr "创建一个主/备集群" #. Tag: title #, no-c-format msgid "Exploring the Existing Configuration" msgstr "浏览现有配置" #. Tag: para #, no-c-format msgid "When Pacemaker starts up, it automatically records the number and details of the nodes in the cluster as well as which stack is being used and the version of Pacemaker being used." msgstr "当Pacemaker启动的时候,它会自动记录节点的数量和详细信息,以及基层软件(本文中是corosync)和Pacemaker的版本。" #. Tag: para #, no-c-format msgid "This is what the base configuration should look like." msgstr "这是初始配置文件的模样:" #. Tag: programlisting #, no-c-format msgid "" "# pcs status\n" "Last updated: Fri Sep 14 10:12:01 2012\n" "Last change: Fri Sep 14 09:51:55 2012 via crmd on pcmk-2\n" "Stack: corosync\n" "Current DC: pcmk-1 (1) - partition with quorum\n" "Version: 1.1.8-1.el7-60a19ed12fdb4d5c6a6b6767f52e5391e447fec0\n" "2 Nodes configured, unknown expected votes\n" "0 Resources configured.\n" "\n" "Online: [ pcmk-1 pcmk-2 ]\n" "\n" "Full list of resources:" msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "For those that are not of afraid of XML, you can see the raw cluster configuration and status by using the pcs cluster cib command." msgstr "如果有谁想看看XML格式的,你可以添加xml选项来看到原始的配置文件" #. Tag: title #, no-c-format msgid "The last XML you’ll see in this document" msgstr "这是本文档最后一次显示XML。(作者怨念很深啊)" #. Tag: programlisting #, no-c-format msgid "# pcs cluster cib" msgstr "" #. Tag: programlisting #, no-c-format msgid "" "<cib epoch=\"4\" num_updates=\"19\" admin_epoch=\"0\" validate-with=\"pacemaker-1.2\" crm_feature_set=\"3.0.6\" update-origin=\"pcmk-1\" update-client=\"crmd\" cib-last-written=\"Wed Aug 1 16:08:52 2012\" have-quorum=\"1\" dc-uuid=\"1\">\n" " <configuration>\n" " <crm_config>\n" " <cluster_property_set id=\"cib-bootstrap-options\">\n" " <nvpair id=\"cib-bootstrap-options-dc-version\" name=\"dc-version\" value=\"1.1.8-1.el7-60a19ed12fdb4d5c6a6b6767f52e5391e447fec0\"/>\n" " <nvpair id=\"cib-bootstrap-options-cluster-infrastructure\" name=\"cluster-infrastructure\" value=\"corosync\"/>\n" " </cluster_property_set>\n" " </crm_config>\n" " <nodes>\n" " <node id=\"1\" uname=\"pcmk-1\" type=\"normal\"/>\n" " <node id=\"2\" uname=\"pcmk-2\" type=\"normal\"/>\n" " </nodes>\n" " <resources/>\n" " <constraints/>\n" " </configuration>\n" " <status>\n" " <node_state id=\"2\" uname=\"pcmk-2\" ha=\"active\" in_ccm=\"true\" crmd=\"online\" join=\"member\" expected=\"member\" crm-debug-origin=\"do_state_transition\" shutdown=\"0\">\n" " <lrm id=\"2\">\n" " <lrm_resources/>\n" " </lrm>\n" " <transient_attributes id=\"2\">\n" " <instance_attributes id=\"status-2\">\n" " <nvpair id=\"status-2-probe_complete\" name=\"probe_complete\" value=\"true\"/>\n" " </instance_attributes>\n" " </transient_attributes>\n" " </node_state>\n" " <node_state id=\"1\" uname=\"pcmk-1\" ha=\"active\" in_ccm=\"true\" crmd=\"online\" join=\"member\" expected=\"member\" crm-debug-origin=\"do_state_transition\" shutdown=\"0\">\n" " <lrm id=\"1\">\n" " <lrm_resources/>\n" " </lrm>\n" " <transient_attributes id=\"1\">\n" " <instance_attributes id=\"status-1\">\n" " <nvpair id=\"status-1-probe_complete\" name=\"probe_complete\" value=\"true\"/>\n" " </instance_attributes>\n" " </transient_attributes>\n" " </node_state>\n" " </status>\n" "</cib>" msgstr "" #. Tag: para #, no-c-format msgid "Before we make any changes, its a good idea to check the validity of the configuration." msgstr "在我们做出任何改变之前,我们最好检查下配置文件。" #. Tag: programlisting #, fuzzy, no-c-format msgid "" "# crm_verify -L -V\n" " error: unpack_resources: Resource start-up disabled since no STONITH resources have been defined\n" " error: unpack_resources: Either configure some or disable STONITH with the stonith-enabled option\n" " error: unpack_resources: NOTE: Clusters with shared data need STONITH to ensure data integrity\n" "Errors found during check: config not valid\n" " -V may provide more details" msgstr "" "\n" "[root@pcmk-1 ~]# crm_verify -L\n" "crm_verify[2195]: 2009/08/27_16:57:12 ERROR: unpack_resources: Resource start-up disabled since no STONITH resources have been defined\n" "crm_verify[2195]: 2009/08/27_16:57:12 ERROR: unpack_resources: Either configure some or disable STONITH with the stonith-enabled option\n" "crm_verify[2195]: 2009/08/27_16:57:12 ERROR: unpack_resources: NOTE: Clusters with shared data need STONITH to ensure data integrity\n" "Errors found during check: config not valid\n" "  -V may provide more details\n" "[root@pcmk-1 ~]#\n" #. Tag: para #, no-c-format msgid "As you can see, the tool has found some errors." msgstr "就像你看到的,这个工具发现了一些错误。" #. Tag: para #, fuzzy, no-c-format msgid "In order to guarantee the safety of your data If the data is corrupt, there is little point in continuing to make it available , the default for STONITH A common node fencing mechanism. Used to ensure data integrity by powering off \"bad\" nodes in Pacemaker is enabled. However it also knows when no STONITH configuration has been supplied and reports this as a problem (since the cluster would not be able to make progress if a situation requiring node fencing arose)." msgstr "为了确保您数据的安全性 如果数据是损坏的,那保证它的可用性是没有意义的 ,请使用配备STONITH 一个常见的隔离手段。用关掉坏节点电源的办法来保证数据完整 的Pacemaker。但是当没有配置STONITH的时候也会报这个错误(因为当集群中某个节点需要被隔离的时候,集群就无法工作了)。" #. Tag: para #, no-c-format msgid "For now, we will disable this feature and configure it later in the Configuring STONITH section. It is important to note that the use of STONITH is highly encouraged, turning it off tells the cluster to simply pretend that failed nodes are safely powered off. Some vendors will even refuse to support clusters that have it disabled." msgstr "目前,我们禁用这个特性,然后在 配置STONISH 章节来配置它。这里要指出,使用STONITH是非常有必要的。关闭这个特性就是告诉集群:假装故障的节点已经安全的关机了。一些供应商甚至不允许这个特性被关闭。" #. Tag: para #, fuzzy, no-c-format msgid "To disable STONITH, we set the stonith-enabled cluster option to false." msgstr "我们将 stonith-enabled设置为 false 来关闭STONITH" #. Tag: programlisting #, no-c-format msgid "" "# pcs property set stonith-enabled=false\n" "# crm_verify -L" msgstr "" #. Tag: para #, no-c-format msgid "With the new cluster option set, the configuration is now valid." msgstr "设置完这个选项以后,校验配置文件就正常了。" #. Tag: para #, no-c-format msgid "The use of stonith-enabled=false is completely inappropriate for a production cluster. We use it here to defer the discussion of its configuration which can differ widely from one installation to the next. See for information on why STONITH is important and details on how to configure it." msgstr "" #. Tag: title #, no-c-format msgid "Adding a Resource" msgstr "添加一个资源" #. Tag: para #, fuzzy, no-c-format msgid "The first thing we should do is configure an IP address. Regardless of where the cluster service(s) are running, we need a consistent address to contact them on. Here I will choose and add 192.168.122.120 as the floating address, give it the imaginative name ClusterIP and tell the cluster to check that its running every 30 seconds." msgstr "首先要做的是配置一个IP地址,不管集群服务在哪运行,我们要一个固定的地址来提供服务。在这里我选择192.168.122.101作为浮动IP,给它取一个好记的名字 ClusterIP 并且告诉集群 每30秒检查它一次" #. Tag: para #, no-c-format msgid "The chosen address must not be one already associated with a physical node" msgstr "选择的IP地址不能被节点所占用" #. Tag: screen #, fuzzy, no-c-format msgid "" "# pcs resource create ClusterIP ocf:heartbeat:IPaddr2 \\\n" " ip=192.168.0.120 cidr_netmask=32 op monitor interval=30s" msgstr "" "\n" "crm configure primitive ClusterIP ocf:heartbeat:IPaddr2 \\ \n" "        params ip=192.168.122.101 cidr_netmask=32 \\ \n" "        op monitor interval=30s\n" #. Tag: para #, no-c-format msgid "The other important piece of information here is ocf:heartbeat:IPaddr2." msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "This tells Pacemaker three things about the resource you want to add. The first field, ocf, is the standard to which the resource script conforms to and where to find it. The second field is specific to OCF resources and tells the cluster which namespace to find the resource script in, in this case heartbeat. The last field indicates the name of the resource script." msgstr "另外一个重要的信息是 ocf:heartbeat:IPaddr2。这告诉Pacemaker三件事情,第一个部分,ocf,指明了这个资源采用的标准(类型)以及在哪能找到它。第二个部分标明这个资源脚本的在OCF中的名字空间,在这个例子中是heartbeat。最后一个部分指明了资源脚本的名称。" #. Tag: para #, fuzzy, no-c-format msgid "To obtain a list of the available resource standards (the ocf part of ocf:heartbeat:IPaddr2), run" msgstr "可以运行下面的命令来获得可用的资源类" #. Tag: programlisting #, no-c-format msgid "" "# pcs resource standards\n" "ocf\n" "lsb\n" "service\n" "systemd\n" "stonith" msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "To obtain a list of the available ocf resource providers (the heartbeat part of ocf:heartbeat:IPaddr2), run" msgstr "可以运行下面的命令来获得可用的资源类" #. Tag: programlisting #, no-c-format msgid "" "# pcs resource providers\n" "heartbeat\n" "linbit\n" "pacemaker\n" "redhat" msgstr "" #. Tag: para #, no-c-format msgid "Finally, if you want to see all the resource agents available for a specific ocf provider (the IPaddr2 part of ocf:heartbeat:IPaddr2), run" msgstr "" #. Tag: programlisting #, no-c-format msgid "" "# pcs resource agents ocf:heartbeat\n" "AoEtarget\n" "AudibleAlarm\n" "CTDB\n" "ClusterMon\n" "Delay\n" "Dummy\n" ".\n" ". (skipping lots of resources to save space)\n" ".\n" "IPaddr2\n" ".\n" ".\n" ".\n" "symlink\n" "syslog-ng\n" "tomcat\n" "vmware" msgstr "" #. Tag: para #, no-c-format msgid "Now verify that the IP resource has been added and display the cluster’s status to see that it is now active." msgstr "现在检查下IP 资源是不是已经添加了,并且看看是否处在可用状态。" #. Tag: programlisting #, no-c-format msgid "" "# pcs status\n" "\n" "Last updated: Fri Sep 14 10:17:00 2012\n" "Last change: Fri Sep 14 10:15:48 2012 via cibadmin on pcmk-1\n" "Stack: corosync\n" "Current DC: pcmk-1 (1) - partition with quorum\n" "Version: 1.1.8-1.el7-60a19ed12fdb4d5c6a6b6767f52e5391e447fec0\n" "2 Nodes configured, unknown expected votes\n" "1 Resources configured.\n" "\n" "Online: [ pcmk-1 pcmk-2 ]\n" "\n" "Full list of resources:\n" "\n" " ClusterIP (ocf::heartbeat:IPaddr2): Started pcmk-1" msgstr "" #. Tag: title #, no-c-format msgid "Perform a Failover" msgstr " 做一次失效备援" #. Tag: para #, no-c-format msgid "Being a high-availability cluster, we should test failover of our new resource before moving on." msgstr "作为一个高可用的集群,我们在继续本文档之前,我们要需要测试失效备援 。" #. Tag: para #, no-c-format msgid "First, find the node on which the IP address is running." msgstr "首先,找到IP资源现在在哪个节点上运行。" #. Tag: para #, fuzzy, no-c-format msgid "Shut down Pacemaker and Corosync on that machine." msgstr "关闭那个节点上面的Corosync服务:" #. Tag: programlisting #, no-c-format msgid "" "#pcs cluster stop pcmk-1\n" "Stopping Cluster..." msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "Once Corosync is no longer running, go to the other node and check the cluster status." msgstr "当Corosync停止运行以后,我们到另外一个节点用crm_mon来检查集群状态." #. Tag: programlisting #, fuzzy, no-c-format msgid "" "# pcs status\n" "\n" "Last updated: Fri Sep 14 10:31:01 2012\n" "Last change: Fri Sep 14 10:15:48 2012 via cibadmin on pcmk-1\n" "Stack: corosync\n" "Current DC: pcmk-2 (2) - partition WITHOUT quorum\n" "Version: 1.1.8-1.el7-60a19ed12fdb4d5c6a6b6767f52e5391e447fec0\n" "2 Nodes configured, unknown expected votes\n" "1 Resources configured.\n" "\n" "Online: [ pcmk-2 ]\n" "OFFLINE: [ pcmk-1 ]\n" "\n" "Full list of resources:\n" "\n" " ClusterIP (ocf::heartbeat:IPaddr2): Stopped" msgstr "" "\n" "[root@pcmk-2 ~]# crm_mon\n" "============\n" "Last updated: Fri Aug 28 15:30:18 2009\n" "Stack: openais\n" "Current DC: pcmk-2 - partition WITHOUT quorum\n" "Version: 1.0.5-462f1569a43740667daf7b0f6b521742e9eb8fa7\n" "2 Nodes configured, 2 expected votes\n" "1 Resources configured.\n" "============\n" "Online: [ pcmk-2 ]\n" "OFFLINE: [ pcmk-1 ]\n" "\n" "ClusterIP (ocf::heartbeat:IPaddr): Started pcmk-2\n" #. Tag: para #, fuzzy, no-c-format msgid "There are three things to notice about the cluster’s current state. The first is that, as expected, pcmk-1 is now offline. However we can also see that ClusterIP isn’t running anywhere!" msgstr "关于集群状态,我们有三个地方需要注意,首先,如我们所料pcmk-1已经下线了,然而我们发现ClusterIP不在任何地方运行!" #. Tag: title #, no-c-format msgid "Quorum and Two-Node Clusters" msgstr "法定人数和双节点集群" #. Tag: para #, fuzzy, no-c-format msgid "This is because the cluster no longer has quorum, as can be seen by the text \"partition WITHOUT quorum\" in the status output. In order to reduce the possibility of data corruption, Pacemaker’s default behavior is to stop all resources if the cluster does not have quorum." msgstr "这是因为集群已经达不到“法定人数”了,就像我们看到的“partition WITHOUT quorum” (用绿色强调的)。为了避免数据遭到破坏,当Pacemaker发现集群达不到法定人数时,就会停止所有的资源。" #. Tag: para #, no-c-format msgid "A cluster is said to have quorum when more than half the known or expected nodes are online, or for the mathematically inclined, whenever the following equation is true:" msgstr "当有半数以上的节点在线时,这个集群就认为自己拥有法定人数了,是“合法”的,换而言之就是下面的公式:" #. Tag: literallayout #, fuzzy, no-c-format msgid "total_nodes < 2 * active_nodes" msgstr "总节点数 - 1 < 2 * 可用的节点" #. Tag: para #, fuzzy, no-c-format msgid "Therefore a two-node cluster only has quorum when both nodes are running, which is no longer the case for our cluster. This would normally make the creation of a two-node cluster pointless Actually some would argue that two-node clusters are always pointless, but that is an argument for another time , however it is possible to control how Pacemaker behaves when quorum is lost. In particular, we can tell the cluster to simply ignore quorum altogether." msgstr "因此在双节点的集群中,只有当两者都在线时才是合法的。 这个规则会让 双节点的集群 毫无意义,但是我们可以控制Pacemaker发现集群达不到法定人数时候的行为。简单来说,我们告诉集群忽略它 。" #. Tag: programlisting #, no-c-format msgid "" "# pcs property set no-quorum-policy=ignore\n" "# pcs property\n" "dc-version: 1.1.8-1.el7-60a19ed12fdb4d5c6a6b6767f52e5391e447fec0\n" "cluster-infrastructure: corosync\n" "stonith-enabled: false\n" "no-quorum-policy: ignore" msgstr "" #. Tag: para #, no-c-format msgid "After a few moments, the cluster will start the IP address on the remaining node. Note that the cluster still does not have quorum." msgstr "过了一会,集群会在剩下的那个节点上启动这个IP。请注意集群现在依然没有达到法定人数。" #. Tag: programlisting #, fuzzy, no-c-format msgid "" "# pcs status\n" "Last updated: Fri Sep 14 10:38:11 2012\n" "Last change: Fri Sep 14 10:37:53 2012 via cibadmin on pcmk-2\n" "Stack: corosync\n" "Current DC: pcmk-2 (2) - partition WITHOUT quorum\n" "Version: 1.1.8-1.el7-60a19ed12fdb4d5c6a6b6767f52e5391e447fec0\n" "2 Nodes configured, unknown expected votes\n" "1 Resources configured.\n" "\n" "Online: [ pcmk-2 ]\n" "OFFLINE: [ pcmk-1 ]\n" "\n" "Full list of resources:\n" "\n" " ClusterIP (ocf::heartbeat:IPaddr2): Started pcmk-2" msgstr "" "\n" "[root@pcmk-2 ~]# crm_mon\n" "============\n" "Last updated: Fri Aug 28 15:30:18 2009\n" "Stack: openais\n" "Current DC: pcmk-2 - partition WITHOUT quorum\n" "Version: 1.0.5-462f1569a43740667daf7b0f6b521742e9eb8fa7\n" "2 Nodes configured, 2 expected votes\n" "1 Resources configured.\n" "============\n" "Online: [ pcmk-2 ]\n" "OFFLINE: [ pcmk-1 ]\n" "\n" "ClusterIP (ocf::heartbeat:IPaddr): Started pcmk-2\n" #. Tag: para #, no-c-format msgid "Now simulate node recovery by restarting the cluster stack on pcmk-1 and check the cluster’s status. Note, if you get an authentication error with the pcs cluster start pcmk-1 command, you must authenticate on the node using the pcs cluster auth pcmk pcmk-1 pcmk-2 command discussed earlier." msgstr "" #. Tag: programlisting #, no-c-format msgid "" "# pcs cluster start pcmk-1\n" "Starting Cluster...\n" "# pcs status\n" "\n" "Last updated: Fri Sep 14 10:42:56 2012\n" "Last change: Fri Sep 14 10:37:53 2012 via cibadmin on pcmk-2\n" "Stack: corosync\n" "Current DC: pcmk-2 (2) - partition with quorum\n" "Version: 1.1.8-1.el7-60a19ed12fdb4d5c6a6b6767f52e5391e447fec0\n" "2 Nodes configured, unknown expected votes\n" "1 Resources configured.\n" "\n" "Online: [ pcmk-1 pcmk-2 ]\n" "\n" "Full list of resources:\n" "\n" " ClusterIP (ocf::heartbeat:IPaddr2): Started pcmk-2" msgstr "" #. Tag: para #, no-c-format msgid "In the dark days, the cluster may have moved the IP back to its original location (pcmk-1). Usually this is no longer the case." msgstr "" #. Tag: title #, no-c-format msgid "Prevent Resources from Moving after Recovery" msgstr "防止资源在节点恢复后移动" #. Tag: para #, fuzzy, no-c-format msgid "In most circumstances, it is highly desirable to prevent healthy resources from being moved around the cluster. Moving resources almost always requires a period of downtime. For complex services like Oracle databases, this period can be quite long." msgstr "一些环境中会要求尽量避免资源在节点之间移动。移动资源通常意味着一段时间内无法提供服务,某些复杂的服务,比如Oracle数据库,这个时间可能会很长。" #. Tag: para #, fuzzy, no-c-format msgid "To address this, Pacemaker has the concept of resource stickiness which controls how much a service prefers to stay running where it is. You may like to think of it as the \"cost\" of any downtime. By default, Pacemaker assumes there is zero cost associated with moving resources and will do so to achieve \"optimal\" It should be noted that Pacemaker’s definition of optimal may not always agree with that of a human’s. The order in which Pacemaker processes lists of resources and nodes creates implicit preferences in situations where the administrator has not explicitly specified them resource placement. We can specify a different stickiness for every resource, but it is often sufficient to change the default." msgstr "为了达到这个效果,Pacemaker 有一个叫做 资源黏性值 的概念,它能够控制一个服务(资源)有多想呆在它正在运行的节点上。你可以把它认为是无法提供服务的“代价” 这里要注意的是Pacemaker定义的代价跟人们所想的不一样。如果管理员没有明确的指定参数(创建稳定环境所必须的),那么资源个节点在Pacemaker处理列表中的顺序会隐式地创建参数 ”。 Pacemaker为了达到最优分布各个资源的目的,默认设置这个值为0。我们可以为每个资源定义不同的黏性值,但一般来说,更改默认黏性值就够了。" #. Tag: programlisting #, no-c-format msgid "" "# pcs resource rsc defaults resource-stickiness=100\n" "# pcs resource rsc defaults\n" "resource-stickiness: 100" msgstr "" #~ msgid "" #~ "\n" #~ "[root@pcmk-2 ~]# crm configure show\n" #~ "node pcmk-1\n" #~ "node pcmk-2\n" #~ "property $id=\"cib-bootstrap-options\" \\\n" #~ "        dc-version=\"1.0.5-462f1569a43740667daf7b0f6b521742e9eb8fa7\" \\\n" #~ "        cluster-infrastructure=\"openais\" \\\n" #~ "        expected-quorum-votes=\"2\"\n" #~ msgstr "" #~ "\n" #~ "[root@pcmk-2 ~]# crm configure show\n" #~ "node pcmk-1\n" #~ "node pcmk-2\n" #~ "property $id=\"cib-bootstrap-options\" \\\n" #~ "        dc-version=\"1.0.5-462f1569a43740667daf7b0f6b521742e9eb8fa7\" \\\n" #~ "        cluster-infrastructure=\"openais\" \\\n" #~ "        expected-quorum-votes=\"2\"\n" #~ msgid "" #~ "\n" #~ "[root@pcmk-2 ~]# crm configure show xml\n" #~ "<?xml version=\"1.0\" ?>\n" #~ "<cib admin_epoch=\"0\" crm_feature_set=\"3.0.1\" dc-uuid=\"pcmk-1\" epoch=\"13\" have-quorum=\"1\" num_updates=\"7\" validate-with=\"pacemaker-1.0\">\n" #~ "  <configuration>\n" #~ "    <crm_config>\n" #~ "      <cluster_property_set id=\"cib-bootstrap-options\">\n" #~ "        <nvpair id=\"cib-bootstrap-options-dc-version\" name=\"dc-version\" value=\"1.0.5-462f1569a43740667daf7b0f6b521742e9eb8fa7\"/>\n" #~ "        <nvpair id=\"cib-bootstrap-options-cluster-infrastructure\" name=\"cluster-infrastructure\" value=\"openais\"/>\n" #~ "        <nvpair id=\"cib-bootstrap-options-expected-quorum-votes\" name=\"expected-quorum-votes\" value=\"2\"/>\n" #~ "      </cluster_property_set>\n" #~ "    </crm_config>\n" #~ "    <rsc_defaults/>\n" #~ "    <op_defaults/>\n" #~ "    <nodes>\n" #~ "      <node id=\"pcmk-1\" type=\"normal\" uname=\"pcmk-1\"/>\n" #~ "      <node id=\"pcmk-2\" type=\"normal\" uname=\"pcmk-2\"/>\n" #~ "    </nodes>\n" #~ "    <resources/>\n" #~ "    <constraints/>\n" #~ "  </configuration>\n" #~ "</cib>\n" #~ msgstr "" #~ "\n" #~ "[root@pcmk-2 ~]# crm configure show xml\n" #~ "<?xml version=\"1.0\" ?>\n" #~ "<cib admin_epoch=\"0\" crm_feature_set=\"3.0.1\" dc-uuid=\"pcmk-1\" epoch=\"13\" have-quorum=\"1\" num_updates=\"7\" validate-with=\"pacemaker-1.0\">\n" #~ "  <configuration>\n" #~ "    <crm_config>\n" #~ "      <cluster_property_set id=\"cib-bootstrap-options\">\n" #~ "        <nvpair id=\"cib-bootstrap-options-dc-version\" name=\"dc-version\" value=\"1.0.5-462f1569a43740667daf7b0f6b521742e9eb8fa7\"/>\n" #~ "        <nvpair id=\"cib-bootstrap-options-cluster-infrastructure\" name=\"cluster-infrastructure\" value=\"openais\"/>\n" #~ "        <nvpair id=\"cib-bootstrap-options-expected-quorum-votes\" name=\"expected-quorum-votes\" value=\"2\"/>\n" #~ "      </cluster_property_set>\n" #~ "    </crm_config>\n" #~ "    <rsc_defaults/>\n" #~ "    <op_defaults/>\n" #~ "    <nodes>\n" #~ "      <node id=\"pcmk-1\" type=\"normal\" uname=\"pcmk-1\"/>\n" #~ "      <node id=\"pcmk-2\" type=\"normal\" uname=\"pcmk-2\"/>\n" #~ "    </nodes>\n" #~ "    <resources/>\n" #~ "    <constraints/>\n" #~ "  </configuration>\n" #~ "</cib>\n" #~ msgid "crm configure property stonith-enabled=false" #~ msgstr "crm configure property stonith-enabled=false" #~ msgid "crm_verify -L" #~ msgstr "crm_verify -L" #~ msgid "" #~ "\n" #~ "[root@pcmk-1 ~]# crm ra classes\n" #~ "heartbeat\n" #~ "lsb\n" #~ "ocf / heartbeat pacemaker\n" #~ "stonith\n" #~ msgstr "" #~ "\n" #~ "[root@pcmk-1 ~]# crm ra classes\n" #~ "heartbeat\n" #~ "lsb\n" #~ "ocf / heartbeat pacemaker\n" #~ "stonith\n" #~ msgid "To then find all the OCF resource agents provided by Pacemaker and Heartbeat, run" #~ msgstr "找到OCF中Pacemaker和Heartbeat提供的资源脚本,运行下面的命令" #~ msgid "" #~ "\n" #~ "[root@pcmk-1 ~]# crm ra list ocf pacemaker\n" #~ "ClusterMon     Dummy          Stateful       SysInfo        SystemHealth   controld\n" #~ "ping           pingd          \n" #~ "[root@pcmk-1 ~]# crm ra list ocf heartbeat\n" #~ "AoEtarget              AudibleAlarm           ClusterMon             Delay\n" #~ "Dummy                  EvmsSCC                Evmsd                  Filesystem\n" #~ "ICP                    IPaddr                 IPaddr2                IPsrcaddr\n" #~ "LVM                    LinuxSCSI              MailTo                 ManageRAID\n" #~ "ManageVE               Pure-FTPd              Raid1                  Route\n" #~ "SAPDatabase            SAPInstance            SendArp                ServeRAID\n" #~ "SphinxSearchDaemon     Squid                  Stateful               SysInfo\n" #~ "VIPArip                VirtualDomain          WAS                    WAS6\n" #~ "WinPopup               Xen                    Xinetd                 anything\n" #~ "apache                 db2                    drbd                   eDir88\n" #~ "iSCSILogicalUnit       iSCSITarget            ids                    iscsi\n" #~ "ldirectord             mysql                  mysql-proxy            nfsserver\n" #~ "oracle                 oralsnr                pgsql                  pingd\n" #~ "portblock              rsyncd                 scsi2reservation       sfex\n" #~ "tomcat                 vmware                 \n" #~ "[root@pcmk-1 ~]#\n" #~ msgstr "" #~ "\n" #~ "[root@pcmk-1 ~]# crm ra list ocf pacemaker\n" #~ "ClusterMon     Dummy          Stateful       SysInfo        SystemHealth   controld\n" #~ "ping           pingd          \n" #~ "[root@pcmk-1 ~]# crm ra list ocf heartbeat\n" #~ "AoEtarget              AudibleAlarm           ClusterMon             Delay\n" #~ "Dummy                  EvmsSCC                Evmsd                  Filesystem\n" #~ "ICP                    IPaddr                 IPaddr2                IPsrcaddr\n" #~ "LVM                    LinuxSCSI              MailTo                 ManageRAID\n" #~ "ManageVE               Pure-FTPd              Raid1                  Route\n" #~ "SAPDatabase            SAPInstance            SendArp                ServeRAID\n" #~ "SphinxSearchDaemon     Squid                  Stateful               SysInfo\n" #~ "VIPArip                VirtualDomain          WAS                    WAS6\n" #~ "WinPopup               Xen                    Xinetd                 anything\n" #~ "apache                 db2                    drbd                   eDir88\n" #~ "iSCSILogicalUnit       iSCSITarget            ids                    iscsi\n" #~ "ldirectord             mysql                  mysql-proxy            nfsserver\n" #~ "oracle                 oralsnr                pgsql                  pingd\n" #~ "portblock              rsyncd                 scsi2reservation       sfex\n" #~ "tomcat                 vmware                 \n" #~ "[root@pcmk-1 ~]#\n" #~ msgid "" #~ "\n" #~ "[root@pcmk-1 ~]# crm configure show\n" #~ "node pcmk-1\n" #~ "node pcmk-2\n" #~ "primitive ClusterIP ocf:heartbeat:IPaddr2 \\\n" #~ " params ip=\"192.168.122.101\" cidr_netmask=\"32\" \\\n" #~ " op monitor interval=\"30s\"\n" #~ "property $id=\"cib-bootstrap-options\" \\\n" #~ "        dc-version=\"1.0.5-462f1569a43740667daf7b0f6b521742e9eb8fa7\" \\\n" #~ "        cluster-infrastructure=\"openais\" \\\n" #~ "        expected-quorum-votes=\"2\" \\\n" #~ "        stonith-enabled=\"false\" \\\n" #~ "[root@pcmk-1 ~]# crm_mon\n" #~ "============\n" #~ "Last updated: Fri Aug 28 15:23:48 2009\n" #~ "Stack: openais\n" #~ "Current DC: pcmk-1 - partition with quorum\n" #~ "Version: 1.0.5-462f1569a43740667daf7b0f6b521742e9eb8fa7\n" #~ "2 Nodes configured, 2 expected votes\n" #~ "1 Resources configured.\n" #~ "============\n" #~ "\n" #~ "Online: [ pcmk-1 pcmk-2 ]\n" #~ "ClusterIP (ocf::heartbeat:IPaddr): Started pcmk-1\n" #~ msgstr "" #~ "\n" #~ "[root@pcmk-1 ~]# crm configure show\n" #~ "node pcmk-1\n" #~ "node pcmk-2\n" #~ "primitive ClusterIP ocf:heartbeat:IPaddr2 \\\n" #~ " params ip=\"192.168.122.101\" cidr_netmask=\"32\" \\\n" #~ " op monitor interval=\"30s\"\n" #~ "property $id=\"cib-bootstrap-options\" \\\n" #~ "        dc-version=\"1.0.5-462f1569a43740667daf7b0f6b521742e9eb8fa7\" \\\n" #~ "        cluster-infrastructure=\"openais\" \\\n" #~ "        expected-quorum-votes=\"2\" \\\n" #~ "        stonith-enabled=\"false\" \\\n" #~ "[root@pcmk-1 ~]# crm_mon\n" #~ "============\n" #~ "Last updated: Fri Aug 28 15:23:48 2009\n" #~ "Stack: openais\n" #~ "Current DC: pcmk-1 - partition with quorum\n" #~ "Version: 1.0.5-462f1569a43740667daf7b0f6b521742e9eb8fa7\n" #~ "2 Nodes configured, 2 expected votes\n" #~ "1 Resources configured.\n" #~ "============\n" #~ "\n" #~ "Online: [ pcmk-1 pcmk-2 ]\n" #~ "ClusterIP (ocf::heartbeat:IPaddr): Started pcmk-1\n" #~ msgid "" #~ "\n" #~ "[root@pcmk-1 ~]# crm resource status ClusterIP\n" #~ "resource ClusterIP is running on: pcmk-1\n" #~ "[root@pcmk-1 ~]#\n" #~ msgstr "" #~ "\n" #~ "[root@pcmk-1 ~]# crm resource status ClusterIP\n" #~ "resource ClusterIP is running on: pcmk-1\n" #~ "[root@pcmk-1 ~]#\n" #~ msgid "" #~ "\n" #~ "[root@pcmk-1 ~]# ssh pcmk-1 -- /etc/init.d/corosync stop\n" #~ "Stopping Corosync Cluster Engine (corosync): [ OK ]\n" #~ "Waiting for services to unload: [ OK ]\n" #~ "[root@pcmk-1 ~]#\n" #~ msgstr "" #~ "\n" #~ "[root@pcmk-1 ~]# ssh pcmk-1 -- /etc/init.d/corosync stop\n" #~ "Stopping Corosync Cluster Engine (corosync): [ OK ]\n" #~ "Waiting for services to unload: [ OK ]\n" #~ "[root@pcmk-1 ~]#\n" #~ msgid "" #~ "\n" #~ "[root@pcmk-2 ~]# crm_mon\n" #~ "============\n" #~ "Last updated: Fri Aug 28 15:27:35 2009\n" #~ "Stack: openais\n" #~ "Current DC: pcmk-2 - partition WITHOUT quorum\n" #~ "Version: 1.0.5-462f1569a43740667daf7b0f6b521742e9eb8fa7\n" #~ "2 Nodes configured, 2 expected votes\n" #~ "1 Resources configured.\n" #~ "============\n" #~ "\n" #~ "Online: [ pcmk-2 ]\n" #~ "OFFLINE: [ pcmk-1 ]\n" #~ msgstr "" #~ "\n" #~ "[root@pcmk-2 ~]# crm_mon\n" #~ "============\n" #~ "Last updated: Fri Aug 28 15:27:35 2009\n" #~ "Stack: openais\n" #~ "Current DC: pcmk-2 - partition WITHOUT quorum\n" #~ "Version: 1.0.5-462f1569a43740667daf7b0f6b521742e9eb8fa7\n" #~ "2 Nodes configured, 2 expected votes\n" #~ "1 Resources configured.\n" #~ "============\n" #~ "\n" #~ "Online: [ pcmk-2 ]\n" #~ "OFFLINE: [ pcmk-1 ]\n" #~ msgid "" #~ "\n" #~ "[root@pcmk-1 ~]# crm configure property no-quorum-policy=ignore\n" #~ "[root@pcmk-1 ~]# crm configure show \n" #~ "node pcmk-1\n" #~ "node pcmk-2\n" #~ "primitive ClusterIP ocf:heartbeat:IPaddr2 \\\n" #~ "        params ip=\"192.168.122.101\" cidr_netmask=\"32\" \\\n" #~ "        op monitor interval=\"30s\"\n" #~ "property $id=\"cib-bootstrap-options\" \\\n" #~ "        dc-version=\"1.0.5-462f1569a43740667daf7b0f6b521742e9eb8fa7\" \\\n" #~ "        cluster-infrastructure=\"openais\" \\\n" #~ "        expected-quorum-votes=\"2\" \\\n" #~ "        stonith-enabled=\"false\" \\\n" #~ "        no-quorum-policy=\"ignore\"\n" #~ msgstr "" #~ "\n" #~ "[root@pcmk-1 ~]# crm configure property no-quorum-policy=ignore\n" #~ "[root@pcmk-1 ~]# crm configure show \n" #~ "node pcmk-1\n" #~ "node pcmk-2\n" #~ "primitive ClusterIP ocf:heartbeat:IPaddr2 \\\n" #~ "        params ip=\"192.168.122.101\" cidr_netmask=\"32\" \\\n" #~ "        op monitor interval=\"30s\"\n" #~ "property $id=\"cib-bootstrap-options\" \\\n" #~ "        dc-version=\"1.0.5-462f1569a43740667daf7b0f6b521742e9eb8fa7\" \\\n" #~ "        cluster-infrastructure=\"openais\" \\\n" #~ "        expected-quorum-votes=\"2\" \\\n" #~ "        stonith-enabled=\"false\" \\\n" #~ "        no-quorum-policy=\"ignore\"\n" #~ msgid "Now simulate node recovery by restarting the cluster stack on pcmk-1 and check the cluster’s status." #~ msgstr "现在模拟节点恢复,我们启动 pcmk-1 上面的Corosync服务,然后检查集群状态。" #~ msgid "" #~ "\n" #~ "[root@pcmk-1 ~]# /etc/init.d/corosync start\n" #~ "Starting Corosync Cluster Engine (corosync): [ OK ] \n" #~ "[root@pcmk-1 ~]# crm_mon\n" #~ "============\n" #~ "Last updated: Fri Aug 28 15:32:13 2009\n" #~ "Stack: openais\n" #~ "Current DC: pcmk-2 - partition with quorum\n" #~ "Version: 1.0.5-462f1569a43740667daf7b0f6b521742e9eb8fa7\n" #~ "2 Nodes configured, 2 expected votes\n" #~ "1 Resources configured.\n" #~ "============\n" #~ "Online: [ pcmk-1 pcmk-2 ]\n" #~ "\n" #~ "ClusterIP        (ocf::heartbeat:IPaddr):        Started pcmk-1\n" #~ msgstr "" #~ "\n" #~ "[root@pcmk-1 ~]# /etc/init.d/corosync start\n" #~ "Starting Corosync Cluster Engine (corosync): [ OK ] \n" #~ "[root@pcmk-1 ~]# crm_mon\n" #~ "============\n" #~ "Last updated: Fri Aug 28 15:32:13 2009\n" #~ "Stack: openais\n" #~ "Current DC: pcmk-2 - partition with quorum\n" #~ "Version: 1.0.5-462f1569a43740667daf7b0f6b521742e9eb8fa7\n" #~ "2 Nodes configured, 2 expected votes\n" #~ "1 Resources configured.\n" #~ "============\n" #~ "Online: [ pcmk-1 pcmk-2 ]\n" #~ "\n" #~ "ClusterIP        (ocf::heartbeat:IPaddr):        Started pcmk-1\n" #~ msgid "Here we see something that some may consider surprising, the IP is back running at its original location!" #~ msgstr "现在我们可以看到让某些人惊奇的事情,IP资源回到原来那个节点(pcmk-1)上去了。" #~ msgid "" #~ "\n" #~ "crm configure rsc_defaults resource-stickiness=100\n" #~ "[root@pcmk-2 ~]# crm configure show\n" #~ "node pcmk-1\n" #~ "node pcmk-2\n" #~ "primitive ClusterIP ocf:heartbeat:IPaddr2 \\\n" #~ "        params ip=\"192.168.122.101\" cidr_netmask=\"32\" \\\n" #~ "        op monitor interval=\"30s\"\n" #~ "property $id=\"cib-bootstrap-options\" \\\n" #~ "        dc-version=\"1.0.5-462f1569a43740667daf7b0f6b521742e9eb8fa7\" \\\n" #~ "        cluster-infrastructure=\"openais\" \\\n" #~ "        expected-quorum-votes=\"2\" \\\n" #~ "        stonith-enabled=\"false\" \\\n" #~ "        no-quorum-policy=\"ignore\"\n" #~ "rsc_defaults $id=\"rsc-options\" \\\n" #~ " resource-stickiness=\"100\"\n" #~ msgstr "" #~ "\n" #~ "crm configure rsc_defaults resource-stickiness=100\n" #~ "[root@pcmk-2 ~]# crm configure show\n" #~ "node pcmk-1\n" #~ "node pcmk-2\n" #~ "primitive ClusterIP ocf:heartbeat:IPaddr2 \\\n" #~ "        params ip=\"192.168.122.101\" cidr_netmask=\"32\" \\\n" #~ "        op monitor interval=\"30s\"\n" #~ "property $id=\"cib-bootstrap-options\" \\\n" #~ "        dc-version=\"1.0.5-462f1569a43740667daf7b0f6b521742e9eb8fa7\" \\\n" #~ "        cluster-infrastructure=\"openais\" \\\n" #~ "        expected-quorum-votes=\"2\" \\\n" #~ "        stonith-enabled=\"false\" \\\n" #~ "        no-quorum-policy=\"ignore\"\n" #~ "rsc_defaults $id=\"rsc-options\" \\\n" #~ " resource-stickiness=\"100\"\n" #~ msgid "If we now retry the failover test, we see that as expected ClusterIP still moves to pcmk-2 when pcmk-1 is taken offline." #~ msgstr "现在我们重新尝试失效援备测试,我们可以看到,正如我们所料,当pcmk-1不在线的时候ClusterIP还是移动到了pcmk-2" #~ msgid "" #~ "\n" #~ "[root@pcmk-1 ~]# ssh pcmk-1 -- /etc/init.d/corosync stop\n" #~ "Stopping Corosync Cluster Engine (corosync):               [  OK  ]\n" #~ "Waiting for services to unload:                            [  OK  ]\n" #~ "[root@pcmk-1 ~]# ssh pcmk-2 -- crm_mon -1\n" #~ "============\n" #~ "Last updated: Fri Aug 28 15:39:38 2009\n" #~ "Stack: openais\n" #~ "Current DC: pcmk-2 - partition WITHOUT quorum\n" #~ "Version: 1.0.5-462f1569a43740667daf7b0f6b521742e9eb8fa7\n" #~ "2 Nodes configured, 2 expected votes\n" #~ "1 Resources configured.\n" #~ "============\n" #~ "\n" #~ "Online: [ pcmk-2 ]\n" #~ "OFFLINE: [ pcmk-1 ]\n" #~ "\n" #~ "ClusterIP        (ocf::heartbeat:IPaddr):        Started pcmk-2\n" #~ msgstr "" #~ "\n" #~ "[root@pcmk-1 ~]# ssh pcmk-1 -- /etc/init.d/corosync stop\n" #~ "Stopping Corosync Cluster Engine (corosync):               [  OK  ]\n" #~ "Waiting for services to unload:                            [  OK  ]\n" #~ "[root@pcmk-1 ~]# ssh pcmk-2 -- crm_mon -1\n" #~ "============\n" #~ "Last updated: Fri Aug 28 15:39:38 2009\n" #~ "Stack: openais\n" #~ "Current DC: pcmk-2 - partition WITHOUT quorum\n" #~ "Version: 1.0.5-462f1569a43740667daf7b0f6b521742e9eb8fa7\n" #~ "2 Nodes configured, 2 expected votes\n" #~ "1 Resources configured.\n" #~ "============\n" #~ "\n" #~ "Online: [ pcmk-2 ]\n" #~ "OFFLINE: [ pcmk-1 ]\n" #~ "\n" #~ "ClusterIP        (ocf::heartbeat:IPaddr):        Started pcmk-2\n" #~ msgid "However when we bring pcmk-1 back online, ClusterIP now remains running on pcmk-2." #~ msgstr "但是当我们把pcmk-1恢复在线后,ClusterIP现在还是跑在pcmk-2上面。" #~ msgid "" #~ "\n" #~ "[root@pcmk-1 ~]# /etc/init.d/corosync start\n" #~ "Starting Corosync Cluster Engine (corosync): [ OK ]\n" #~ "[root@pcmk-1 ~]# crm_mon\n" #~ "============\n" #~ "Last updated: Fri Aug 28 15:41:23 2009\n" #~ "Stack: openais\n" #~ "Current DC: pcmk-2 - partition with quorum\n" #~ "Version: 1.0.5-462f1569a43740667daf7b0f6b521742e9eb8fa7\n" #~ "2 Nodes configured, 2 expected votes\n" #~ "1 Resources configured.\n" #~ "============\n" #~ "\n" #~ "Online: [ pcmk-1 pcmk-2 ]\n" #~ "\n" #~ "ClusterIP        (ocf::heartbeat:IPaddr):        Started pcmk-2\n" #~ msgstr "" #~ "\n" #~ "[root@pcmk-1 ~]# /etc/init.d/corosync start\n" #~ "Starting Corosync Cluster Engine (corosync): [ OK ]\n" #~ "[root@pcmk-1 ~]# crm_mon\n" #~ "============\n" #~ "Last updated: Fri Aug 28 15:41:23 2009\n" #~ "Stack: openais\n" #~ "Current DC: pcmk-2 - partition with quorum\n" #~ "Version: 1.0.5-462f1569a43740667daf7b0f6b521742e9eb8fa7\n" #~ "2 Nodes configured, 2 expected votes\n" #~ "1 Resources configured.\n" #~ "============\n" #~ "\n" #~ "Online: [ pcmk-1 pcmk-2 ]\n" #~ "\n" #~ "ClusterIP        (ocf::heartbeat:IPaddr):        Started pcmk-2\n" #~ msgid "In order to guarantee the safety of your data" #~ msgstr "为了保持你的数据的安全性" #~ msgid "If the data is corrupt, there is little point in continuing to make it available" #~ msgstr "如果数据是异常的, 那保证它的可用性是没有意义的。" #~ msgid ", Pacemaker ships with STONITH" #~ msgstr ",Pacemaker与STONITH一起工作" #~ msgid "A common node fencing mechanism. Used to ensure data integrity by powering off “bad” nodes." #~ msgstr "一个常见的隔离途径。用关闭“坏”节点的电源的方法来保证数据完整。" #~ msgid "enabled. However it also knows when no STONITH configuration has been supplied and reports this as a problem (since the cluster would not be able to make progress if a situation requiring node fencing arose)." #~ msgstr "但是当没有配置STONITH的时候也会报这个错误,(因为 当集群需要隔离的时候,集群就无法工作了。)" #~ msgid "Therefore a two-node cluster only has quorum when both nodes are running, which is no longer the case for our cluster. This would normally make the creation of a two-node cluster pointless" #~ msgstr "因此 两个节点的集群 只有在两者都在线时才是合法的。 这个规则会让 两个节点的集群 毫无意义," #~ msgid "Actually some would argue that two-node clusters are always pointless, but that is an argument for another time." #~ msgstr "事实上某些人会说双节点集群本身就是没有意义的,但这不是现在我们要讨论的问题。" #~ msgid ", however it is possible to control how Pacemaker behaves when quorum is lost. In particular, we can tell the cluster to simply ignore quorum altogether." #~ msgstr "但是我们可以控制Pacemaker达不到法定人数时候的行为。简单来说,我们告诉集群忽略它 。" #~ msgid "To address this, Pacemaker has the concept of resource stickiness which controls how much a service prefers to stay running where it is. You may like to think of it as the “cost” of any downtime. By default, Pacemaker assumes there is zero cost associated with moving resources and will do so to achieve “optimal" #~ msgstr "为了达到这个效果,Pacemaker 有一个叫做 资源黏性值 的概念,它能够控制一个服务(资源)有多想呆在它正在运行的节点上。你可以把它认为是无法提供服务的“代价" #~ msgid "It should be noted that Pacemaker’s definition of optimal may not always agree with that of a human’s. The order in which Pacemaker processes lists of resources and nodes create implicit preferences (required in order to create a stabile solution) in situations where the administrator had not explicitly specified some." #~ msgstr "这里要注意的是Pacemaker定义的代价通常跟常人认为的不一样。如果管理员没有明确的指定顺序,Pacemaker处理列表中的资源和节点顺序隐式地定义了参数(创建稳定的方案所需要的)。" #~ msgid "” resource placement. We can specify a different stickiness for every resource, but it is often sufficient to change the default." #~ msgstr "”。 Pacemaker默认这个值为0,以达到最优分布各个资源的目的。我们可以为每个资源定义不同的黏性值,但一般来说,更改默认黏性值就够了。" pacemaker-master/doc/Clusters_from_Scratch/zh-CN/Ch-Apache.mo000066400000000000000000001135641217637305600243530ustar00rootroot00000000000000.=H< TjK!,#R$%w*2+;*<if<<<_>(O?x?'??j@@"ALA BC *C,7CdCCDE G H<)H.fIID;KK1KWK#L 9NCNUOOHPUy[!_bjDilnRpuvBLчC=U!׉$j7<K݋) !&Hڎ0 '4M'/sW8˔-EE j )$ -'( % + *!,.&"# <Location /server-status> SetHandler server-status Order deny,allow Deny from all Allow from 127.0.0.1 </Location> [root@pcmk-1 ~]# cat <<-END >/var/www/html/index.html <html> <body>My Test Site - pcmk-1</body> </html> END [root@pcmk-1 ~]# [root@pcmk-1 ~]# crm configure colocation website-with-ip INFINITY: WebSite ClusterIP [root@pcmk-1 ~]# crm configure show node pcmk-1 node pcmk-2 primitive WebSite ocf:heartbeat:apache \         params configfile="/etc/httpd/conf/httpd.conf" \         op monitor interval="1min" primitive ClusterIP ocf:heartbeat:IPaddr2 \         params ip="192.168.122.101" cidr_netmask="32" \         op monitor interval="30s" colocation website-with-ip inf: WebSite ClusterIP property $id="cib-bootstrap-options" \         dc-version="1.0.5-462f1569a43740667daf7b0f6b521742e9eb8fa7" \         cluster-infrastructure="openais" \         expected-quorum-votes="2" \         stonith-enabled="false" \         no-quorum-policy="ignore" rsc_defaults $id="rsc-options" \         resource-stickiness="100" [root@pcmk-1 ~]# crm_mon ============ Last updated: Fri Aug 28 16:14:34 2009 Stack: openais Current DC: pcmk-2 - partition with quorum Version: 1.0.5-462f1569a43740667daf7b0f6b521742e9eb8fa7 2 Nodes configured, 2 expected votes 2 Resources configured. ============ Online: [ pcmk-1 pcmk-2 ] ClusterIP        (ocf::heartbeat:IPaddr):        Started pcmk-2 WebSite        (ocf::heartbeat:apache):        Started pcmk-2 [root@pcmk-1 ~]# crm configure location prefer-pcmk-1 WebSite 50: pcmk-1 [root@pcmk-1 ~]# crm configure show node pcmk-1 node pcmk-2 primitive WebSite ocf:heartbeat:apache \         params configfile="/etc/httpd/conf/httpd.conf" \         op monitor interval="1min" primitive ClusterIP ocf:heartbeat:IPaddr2 \         params ip="192.168.122.101" cidr_netmask="32" \         op monitor interval="30s" location prefer-pcmk-1 WebSite 50: pcmk-1 colocation website-with-ip inf: WebSite ClusterIP property $id="cib-bootstrap-options" \         dc-version="1.0.5-462f1569a43740667daf7b0f6b521742e9eb8fa7" \         cluster-infrastructure="openais" \         expected-quorum-votes="2" \         stonith-enabled="false" \         no-quorum-policy="ignore" rsc_defaults $id="rsc-options" \         resource-stickiness="100" [root@pcmk-1 ~]# crm_mon ============ Last updated: Fri Aug 28 16:17:35 2009 Stack: openais Current DC: pcmk-2 - partition with quorum Version: 1.0.5-462f1569a43740667daf7b0f6b521742e9eb8fa7 2 Nodes configured, 2 expected votes 2 Resources configured. ============ Online: [ pcmk-1 pcmk-2 ] ClusterIP        (ocf::heartbeat:IPaddr):        Started pcmk-2 WebSite        (ocf::heartbeat:apache):        Started pcmk-2 [root@pcmk-1 ~]# crm configure order apache-after-ip mandatory: ClusterIP WebSite [root@pcmk-1 ~]# crm configure show node pcmk-1 node pcmk-2 primitive WebSite ocf:heartbeat:apache \         params configfile="/etc/httpd/conf/httpd.conf" \         op monitor interval="1min" primitive ClusterIP ocf:heartbeat:IPaddr2 \         params ip="192.168.122.101" cidr_netmask="32" \         op monitor interval="30s" colocation website-with-ip inf: WebSite ClusterIP order apache-after-ip inf: ClusterIP WebSite property $id="cib-bootstrap-options" \         dc-version="1.0.5-462f1569a43740667daf7b0f6b521742e9eb8fa7" \         cluster-infrastructure="openais" \         expected-quorum-votes="2" \         stonith-enabled="false" \         no-quorum-policy="ignore" rsc_defaults $id="rsc-options" \         resource-stickiness="100" [root@pcmk-1 ~]# crm configure primitive WebSite ocf:heartbeat:apache params configfile=/etc/httpd/conf/httpd.conf op monitor interval=1min [root@pcmk-1 ~]# crm configure show node pcmk-1 node pcmk-2 primitive WebSite ocf:heartbeat:apache \ params configfile="/etc/httpd/conf/httpd.conf" \ op monitor interval="1min" primitive ClusterIP ocf:heartbeat:IPaddr2 \         params ip="192.168.122.101" cidr_netmask="32" \         op monitor interval="30s" property $id="cib-bootstrap-options" \         dc-version="1.0.5-462f1569a43740667daf7b0f6b521742e9eb8fa7" \         cluster-infrastructure="openais" \         expected-quorum-votes="2" \         stonith-enabled="false" \         no-quorum-policy="ignore" rsc_defaults $id="rsc-options" \         resource-stickiness="100" [root@pcmk-1 ~]# crm resource move WebSite pcmk-1 [root@pcmk-1 ~]# crm_mon ============ Last updated: Fri Aug 28 16:19:24 2009 Stack: openais Current DC: pcmk-2 - partition with quorum Version: 1.0.5-462f1569a43740667daf7b0f6b521742e9eb8fa7 2 Nodes configured, 2 expected votes 2 Resources configured. ============ Online: [ pcmk-1 pcmk-2 ] ClusterIP        (ocf::heartbeat:IPaddr):        Started pcmk-1 WebSite        (ocf::heartbeat:apache):        Started pcmk-1 Notice how the colocation rule we created has ensured that ClusterIP was also moved to pcmk-1. For the curious, we can see the effect of this command by examining the configuration crm configure show [root@pcmk-1 ~]# crm configure show node pcmk-1 node pcmk-2 primitive WebSite ocf:heartbeat:apache \         params configfile="/etc/httpd/conf/httpd.conf" \         op monitor interval="1min" primitive ClusterIP ocf:heartbeat:IPaddr2 \         params ip="192.168.122.101" cidr_netmask="32" \         op monitor interval="30s" location cli-prefer-WebSite WebSite \ rule $id="cli-prefer-rule-WebSite" inf: #uname eq pcmk-1 location prefer-pcmk-1 WebSite 50: pcmk-1 colocation website-with-ip inf: WebSite ClusterIP property $id="cib-bootstrap-options" \         dc-version="1.0.5-462f1569a43740667daf7b0f6b521742e9eb8fa7" \         cluster-infrastructure="openais" \         expected-quorum-votes="2" \         stonith-enabled="false" \         no-quorum-policy="ignore" rsc_defaults $id="rsc-options" \         resource-stickiness="100" [root@pcmk-1 ~]# crm resource unmove WebSite [root@pcmk-1 ~]# crm configure show node pcmk-1 node pcmk-2 primitive WebSite ocf:heartbeat:apache \         params configfile="/etc/httpd/conf/httpd.conf" \         op monitor interval="1min" primitive ClusterIP ocf:heartbeat:IPaddr2 \         params ip="192.168.122.101" cidr_netmask="32" \         op monitor interval="30s" location prefer-pcmk-1 WebSite 50: pcmk-1 colocation website-with-ip inf: WebSite ClusterIP property $id="cib-bootstrap-options" \         dc-version="1.0.5-462f1569a43740667daf7b0f6b521742e9eb8fa7" \         cluster-infrastructure="openais" \         expected-quorum-votes="2" \         stonith-enabled="false" \         no-quorum-policy="ignore" rsc_defaults $id="rsc-options" \         resource-stickiness="100" [root@pcmk-1 ~]# crm_mon ============ Last updated: Fri Aug 28 16:12:49 2009 Stack: openais Current DC: pcmk-2 - partition with quorum Version: 1.0.5-462f1569a43740667daf7b0f6b521742e9eb8fa7 2 Nodes configured, 2 expected votes 2 Resources configured. ============ Online: [ pcmk-1 pcmk-2 ] ClusterIP        (ocf::heartbeat:IPaddr):        Started pcmk-2 WebSite        (ocf::heartbeat:apache):        Started pcmk-1 [root@pcmk-1 ~]# crm_mon ============ Last updated: Fri Aug 28 16:20:53 2009 Stack: openais Current DC: pcmk-2 - partition with quorum Version: 1.0.5-462f1569a43740667daf7b0f6b521742e9eb8fa7 2 Nodes configured, 2 expected votes 2 Resources configured. ============ Online: [ pcmk-1 pcmk-2 ] ClusterIP        (ocf::heartbeat:IPaddr):        Started pcmk-1 WebSite        (ocf::heartbeat:apache):        Started pcmk-1 [root@pcmk-1 ~]# yum install -y wget Setting up Install Process Resolving Dependencies --> Running transaction check ---> Package wget.x86_64 0:1.11.4-5.fc12 set to be updated --> Finished Dependency Resolution Dependencies Resolved ===========================================================================================  Package        Arch             Version                      Repository               Size =========================================================================================== Installing:  wget         x86_64          1.11.4-5.fc12                   rawhide                393 k Transaction Summary =========================================================================================== Install       1 Package(s) Upgrade       0 Package(s) Total download size: 393 k Downloading Packages: wget-1.11.4-5.fc12.x86_64.rpm                                            | 393 kB     00:00     Running rpm_check_debug Running Transaction Test Finished Transaction Test Transaction Test Succeeded Running Transaction   Installing     : wget-1.11.4-5.fc12.x86_64                                            1/1 Installed:   wget.x86_64 0:1.11.4-5.fc12 Complete! [root@pcmk-1 ~]# [root@pcmk-2 ~]# cat <<-END >/var/www/html/index.html <html> <body>My Test Site - pcmk-2</body> </html> END [root@pcmk-2 ~]# [root@ppcmk-1 ~]# yum install -y httpd Setting up Install Process Resolving Dependencies --> Running transaction check ---> Package httpd.x86_64 0:2.2.13-2.fc12 set to be updated --> Processing Dependency: httpd-tools = 2.2.13-2.fc12 for package: httpd-2.2.13-2.fc12.x86_64 --> Processing Dependency: apr-util-ldap for package: httpd-2.2.13-2.fc12.x86_64 --> Processing Dependency: /etc/mime.types for package: httpd-2.2.13-2.fc12.x86_64 --> Processing Dependency: libaprutil-1.so.0()(64bit) for package: httpd-2.2.13-2.fc12.x86_64 --> Processing Dependency: libapr-1.so.0()(64bit) for package: httpd-2.2.13-2.fc12.x86_64 --> Running transaction check ---> Package apr.x86_64 0:1.3.9-2.fc12 set to be updated ---> Package apr-util.x86_64 0:1.3.9-2.fc12 set to be updated ---> Package apr-util-ldap.x86_64 0:1.3.9-2.fc12 set to be updated ---> Package httpd-tools.x86_64 0:2.2.13-2.fc12 set to be updated ---> Package mailcap.noarch 0:2.1.30-1.fc12 set to be updated --> Finished Dependency Resolution Dependencies Resolved =======================================================================================  Package               Arch             Version                Repository         Size ======================================================================================= Installing:  httpd               x86_64           2.2.13-2.fc12            rawhide           735 k Installing for dependencies:  apr                 x86_64           1.3.9-2.fc12             rawhide           117 k  apr-util            x86_64           1.3.9-2.fc12             rawhide            84 k  apr-util-ldap       x86_64           1.3.9-2.fc12             rawhide            15 k  httpd-tools         x86_64           2.2.13-2.fc12            rawhide            63 k  mailcap             noarch           2.1.30-1.fc12            rawhide            25 k Transaction Summary ======================================================================================= Install       6 Package(s) Upgrade       0 Package(s) Total download size: 1.0 M Downloading Packages: (1/6): apr-1.3.9-2.fc12.x86_64.rpm                                   | 117 kB     00:00     (2/6): apr-util-1.3.9-2.fc12.x86_64.rpm                             |  84 kB     00:00     (3/6): apr-util-ldap-1.3.9-2.fc12.x86_64.rpm                         |  15 kB     00:00     (4/6): httpd-2.2.13-2.fc12.x86_64.rpm                               | 735 kB     00:00     (5/6): httpd-tools-2.2.13-2.fc12.x86_64.rpm                         |  63 kB     00:00     (6/6): mailcap-2.1.30-1.fc12.noarch.rpm                             |  25 kB     00:00     ---------------------------------------------------------------------------------------- Total                                                       875 kB/s | 1.0 MB     00:01     Running rpm_check_debug Running Transaction Test Finished Transaction Test Transaction Test Succeeded Running Transaction   Installing     : apr-1.3.9-2.fc12.x86_64                                         1/6   Installing     : apr-util-1.3.9-2.fc12.x86_64                                     2/6   Installing     : apr-util-ldap-1.3.9-2.fc12.x86_64                               3/6   Installing     : httpd-tools-2.2.13-2.fc12.x86_64                                 4/6   Installing     : mailcap-2.1.30-1.fc12.noarch                                     5/6   Installing     : httpd-2.2.13-2.fc12.x86_64                                       6/6 Installed:   httpd.x86_64 0:2.2.13-2.fc12                                                         Dependency Installed:   apr.x86_64 0:1.3.9-2.fc12            apr-util.x86_64 0:1.3.9-2.fc12   apr-util-ldap.x86_64 0:1.3.9-2.fc12  httpd-tools.x86_64 0:2.2.13-2.fc12   mailcap.noarch 0:2.1.30-1.fc12   Complete! [root@pcmk-1 ~]# After a short delay, we should see the cluster start apacheAlso, we need the wget tool in order for the cluster to be able to check the status of the Apache server.Apache - Adding More ServicesAt this point, Apache is ready to go, all that needs to be done is to add it to the cluster. Lets call the resource WebSite. We need to use an OCF script called apache in the heartbeat namespace Compare the key used here ocf:heartbeat:apache with the one we used earlier for the IP address: ocf:heartbeat:IPaddr2 , the only required parameter is the path to the main Apache configuration file and we’ll tell the cluster to check once a minute that apache is still running.Before continuing, we need to make sure Apache is installed on both hosts.Controlling Resource Start/Stop OrderingEnable the Apache status URLEnsuring Resources Run on the Same HostEven though we now prefer pcmk-1 over pcmk-2, that preference is (intentionally) less than the resource stickiness (how much we preferred not to have unnecessary downtime).First we need to create a page for Apache to serve up. On Fedora the default Apache docroot is /var/www/html, so we’ll create an index file there.For the moment, we will simplify things by serving up only a static site and manually sync the data between the two nodes. So run the command again on pcmk-2.Giving Control Back to the ClusterHighlighted is the automated constraint used to move the resources to pcmk-1In order to monitor the health of your Apache instance, and recover it if it fails, the resource agent used by Pacemaker assumes the server-status URL is available. Look for the following in /etc/httpd/conf/httpd.conf and make sure it is not disabled or commented out:Include outputInstallationManually Moving Resources Around the ClusterNote that the automated constraint is now gone. If we check the cluster status, we can also see that as expected the resources are still active on pcmk-1.Now that we have a basic but functional active/passive two-node cluster, we’re ready to add some real services. We’re going to start with Apache because its a feature of many clusters and relatively simple to configure.Once we’ve finished whatever activity that required us to move the resources to pcmk-1, in our case nothing, we can then allow the cluster to resume normal operation with the unmove command. Since we previously configured a default stickiness, the resources will remain on pcmk-1.Pacemaker does not rely on any sort of hardware symmetry between nodes, so it may well be that one machine is more powerful than the other. In such cases it makes sense to host the resources there if it is available. To do this we create a location constraint. Again we give it a descriptive name (prefer-pcmk-1), specify the resource we want to run there (WebSite), how badly we’d like it to run there (we’ll use 50 for now, but in a two-node situation almost any value above 0 will do) and the host’s name.PreparationSpecifying a Preferred LocationThere are always times when an administrator needs to override the cluster and force resources to move to a specific location. Underneath we use location constraints like the one we created above, happily you don’t need to care. Just provide the name of the resource and the intended location, we’ll do the rest.There is a way to force them to move though...To reduce the load on any one machine, Pacemaker will generally try to spread the configured resources across the cluster nodes. However we can tell the cluster that two resources are related and need to run on the same host (or not at all). Here we instruct the cluster that WebSite can only run on the host that ClusterIP is active on. If ClusterIP is not active anywhere, WebSite will not be permitted to run anywhere.To see the current placement scores, you can use a tool called ptestUpdate the ConfigurationWait a minute, the resources are still on pcmk-2!Wait a moment, the WebSite resource isn’t running on the same host as our IP address!When Apache starts, it binds to the available IP addresses. It doesn’t know about any addresses we add afterwards, so not only do they need to run on the same node, but we need to make sure ClusterIP is already active before we start WebSite. We do this by adding an ordering constraint. We need to give it a name (chose something descriptive like apache-after-ip), indicate that its mandatory (so that any recovery for ClusterIP will also trigger recovery of WebSite) and list the two resources in the order we need them to start.ptest -sLProject-Id-Version: 0 POT-Creation-Date: 2010-12-15T23:32:36 PO-Revision-Date: 2010-12-15 23:37+0800 Last-Translator: Charlie Chen Language-Team: None Language: MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit <Location /server-status> SetHandler server-status Order deny,allow Deny from all Allow from 127.0.0.1 </Location> [root@pcmk-1 ~]# cat <<-END >/var/www/html/index.html <html> <body>My Test Site - pcmk-1</body> </html> END [root@pcmk-1 ~]# [root@pcmk-1 ~]# crm configure colocation website-with-ip INFINITY: WebSite ClusterIP [root@pcmk-1 ~]# crm configure show node pcmk-1 node pcmk-2 primitive WebSite ocf:heartbeat:apache \         params configfile="/etc/httpd/conf/httpd.conf" \         op monitor interval="1min" primitive ClusterIP ocf:heartbeat:IPaddr2 \         params ip="192.168.122.101" cidr_netmask="32" \         op monitor interval="30s" colocation website-with-ip inf: WebSite ClusterIP property $id="cib-bootstrap-options" \         dc-version="1.0.5-462f1569a43740667daf7b0f6b521742e9eb8fa7" \         cluster-infrastructure="openais" \         expected-quorum-votes="2" \         stonith-enabled="false" \         no-quorum-policy="ignore" rsc_defaults $id="rsc-options" \         resource-stickiness="100" [root@pcmk-1 ~]# crm_mon ============ Last updated: Fri Aug 28 16:14:34 2009 Stack: openais Current DC: pcmk-2 - partition with quorum Version: 1.0.5-462f1569a43740667daf7b0f6b521742e9eb8fa7 2 Nodes configured, 2 expected votes 2 Resources configured. ============ Online: [ pcmk-1 pcmk-2 ] ClusterIP        (ocf::heartbeat:IPaddr):        Started pcmk-2 WebSite        (ocf::heartbeat:apache):        Started pcmk-2 [root@pcmk-1 ~]# crm configure location prefer-pcmk-1 WebSite 50: pcmk-1 [root@pcmk-1 ~]# crm configure show node pcmk-1 node pcmk-2 primitive WebSite ocf:heartbeat:apache \         params configfile="/etc/httpd/conf/httpd.conf" \         op monitor interval="1min" primitive ClusterIP ocf:heartbeat:IPaddr2 \         params ip="192.168.122.101" cidr_netmask="32" \         op monitor interval="30s" location prefer-pcmk-1 WebSite 50: pcmk-1 colocation website-with-ip inf: WebSite ClusterIP property $id="cib-bootstrap-options" \         dc-version="1.0.5-462f1569a43740667daf7b0f6b521742e9eb8fa7" \         cluster-infrastructure="openais" \         expected-quorum-votes="2" \         stonith-enabled="false" \         no-quorum-policy="ignore" rsc_defaults $id="rsc-options" \         resource-stickiness="100" [root@pcmk-1 ~]# crm_mon ============ Last updated: Fri Aug 28 16:17:35 2009 Stack: openais Current DC: pcmk-2 - partition with quorum Version: 1.0.5-462f1569a43740667daf7b0f6b521742e9eb8fa7 2 Nodes configured, 2 expected votes 2 Resources configured. ============ Online: [ pcmk-1 pcmk-2 ] ClusterIP        (ocf::heartbeat:IPaddr):        Started pcmk-2 WebSite        (ocf::heartbeat:apache):        Started pcmk-2 [root@pcmk-1 ~]# crm configure order apache-after-ip mandatory: ClusterIP WebSite [root@pcmk-1 ~]# crm configure show node pcmk-1 node pcmk-2 primitive WebSite ocf:heartbeat:apache \         params configfile="/etc/httpd/conf/httpd.conf" \         op monitor interval="1min" primitive ClusterIP ocf:heartbeat:IPaddr2 \         params ip="192.168.122.101" cidr_netmask="32" \         op monitor interval="30s" colocation website-with-ip inf: WebSite ClusterIP order apache-after-ip inf: ClusterIP WebSite property $id="cib-bootstrap-options" \         dc-version="1.0.5-462f1569a43740667daf7b0f6b521742e9eb8fa7" \         cluster-infrastructure="openais" \         expected-quorum-votes="2" \         stonith-enabled="false" \         no-quorum-policy="ignore" rsc_defaults $id="rsc-options" \         resource-stickiness="100" [root@pcmk-1 ~]# crm configure primitive WebSite ocf:heartbeat:apache params configfile=/etc/httpd/conf/httpd.conf op monitor interval=1min [root@pcmk-1 ~]# crm configure show node pcmk-1 node pcmk-2 primitive WebSite ocf:heartbeat:apache \ params configfile="/etc/httpd/conf/httpd.conf" \ op monitor interval="1min" primitive ClusterIP ocf:heartbeat:IPaddr2 \         params ip="192.168.122.101" cidr_netmask="32" \         op monitor interval="30s" property $id="cib-bootstrap-options" \         dc-version="1.0.5-462f1569a43740667daf7b0f6b521742e9eb8fa7" \         cluster-infrastructure="openais" \         expected-quorum-votes="2" \         stonith-enabled="false" \         no-quorum-policy="ignore" rsc_defaults $id="rsc-options" \         resource-stickiness="100" [root@pcmk-1 ~]# crm resource move WebSite pcmk-1 [root@pcmk-1 ~]# crm_mon ============ Last updated: Fri Aug 28 16:19:24 2009 Stack: openais Current DC: pcmk-2 - partition with quorum Version: 1.0.5-462f1569a43740667daf7b0f6b521742e9eb8fa7 2 Nodes configured, 2 expected votes 2 Resources configured. ============ Online: [ pcmk-1 pcmk-2 ] ClusterIP        (ocf::heartbeat:IPaddr):        Started pcmk-1 WebSite        (ocf::heartbeat:apache):        Started pcmk-1 Notice how the colocation rule we created has ensured that ClusterIP was also moved to pcmk-1. For the curious, we can see the effect of this command by examining the configuration crm configure show [root@pcmk-1 ~]# crm configure show node pcmk-1 node pcmk-2 primitive WebSite ocf:heartbeat:apache \         params configfile="/etc/httpd/conf/httpd.conf" \         op monitor interval="1min" primitive ClusterIP ocf:heartbeat:IPaddr2 \         params ip="192.168.122.101" cidr_netmask="32" \         op monitor interval="30s" location cli-prefer-WebSite WebSite \ rule $id="cli-prefer-rule-WebSite" inf: #uname eq pcmk-1 location prefer-pcmk-1 WebSite 50: pcmk-1 colocation website-with-ip inf: WebSite ClusterIP property $id="cib-bootstrap-options" \         dc-version="1.0.5-462f1569a43740667daf7b0f6b521742e9eb8fa7" \         cluster-infrastructure="openais" \         expected-quorum-votes="2" \         stonith-enabled="false" \         no-quorum-policy="ignore" rsc_defaults $id="rsc-options" \         resource-stickiness="100" [root@pcmk-1 ~]# crm resource unmove WebSite [root@pcmk-1 ~]# crm configure show node pcmk-1 node pcmk-2 primitive WebSite ocf:heartbeat:apache \         params configfile="/etc/httpd/conf/httpd.conf" \         op monitor interval="1min" primitive ClusterIP ocf:heartbeat:IPaddr2 \         params ip="192.168.122.101" cidr_netmask="32" \         op monitor interval="30s" location prefer-pcmk-1 WebSite 50: pcmk-1 colocation website-with-ip inf: WebSite ClusterIP property $id="cib-bootstrap-options" \         dc-version="1.0.5-462f1569a43740667daf7b0f6b521742e9eb8fa7" \         cluster-infrastructure="openais" \         expected-quorum-votes="2" \         stonith-enabled="false" \         no-quorum-policy="ignore" rsc_defaults $id="rsc-options" \         resource-stickiness="100" [root@pcmk-1 ~]# crm_mon ============ Last updated: Fri Aug 28 16:12:49 2009 Stack: openais Current DC: pcmk-2 - partition with quorum Version: 1.0.5-462f1569a43740667daf7b0f6b521742e9eb8fa7 2 Nodes configured, 2 expected votes 2 Resources configured. ============ Online: [ pcmk-1 pcmk-2 ] ClusterIP        (ocf::heartbeat:IPaddr):        Started pcmk-2 WebSite        (ocf::heartbeat:apache):        Started pcmk-1 [root@pcmk-1 ~]# crm_mon ============ Last updated: Fri Aug 28 16:20:53 2009 Stack: openais Current DC: pcmk-2 - partition with quorum Version: 1.0.5-462f1569a43740667daf7b0f6b521742e9eb8fa7 2 Nodes configured, 2 expected votes 2 Resources configured. ============ Online: [ pcmk-1 pcmk-2 ] ClusterIP        (ocf::heartbeat:IPaddr):        Started pcmk-1 WebSite        (ocf::heartbeat:apache):        Started pcmk-1 [root@pcmk-1 ~]# yum install -y wget Setting up Install Process Resolving Dependencies --> Running transaction check ---> Package wget.x86_64 0:1.11.4-5.fc12 set to be updated --> Finished Dependency Resolution Dependencies Resolved ===========================================================================================  Package        Arch             Version                      Repository               Size =========================================================================================== Installing:  wget         x86_64          1.11.4-5.fc12                   rawhide                393 k Transaction Summary =========================================================================================== Install       1 Package(s) Upgrade       0 Package(s) Total download size: 393 k Downloading Packages: wget-1.11.4-5.fc12.x86_64.rpm                                            | 393 kB     00:00     Running rpm_check_debug Running Transaction Test Finished Transaction Test Transaction Test Succeeded Running Transaction   Installing     : wget-1.11.4-5.fc12.x86_64                                            1/1 Installed:   wget.x86_64 0:1.11.4-5.fc12 Complete! [root@pcmk-1 ~]# [root@pcmk-2 ~]# cat <<-END >/var/www/html/index.html <html> <body>My Test Site - pcmk-2</body> </html> END [root@pcmk-2 ~]# [root@ppcmk-1 ~]# yum install -y httpd Setting up Install Process Resolving Dependencies --> Running transaction check ---> Package httpd.x86_64 0:2.2.13-2.fc12 set to be updated --> Processing Dependency: httpd-tools = 2.2.13-2.fc12 for package: httpd-2.2.13-2.fc12.x86_64 --> Processing Dependency: apr-util-ldap for package: httpd-2.2.13-2.fc12.x86_64 --> Processing Dependency: /etc/mime.types for package: httpd-2.2.13-2.fc12.x86_64 --> Processing Dependency: libaprutil-1.so.0()(64bit) for package: httpd-2.2.13-2.fc12.x86_64 --> Processing Dependency: libapr-1.so.0()(64bit) for package: httpd-2.2.13-2.fc12.x86_64 --> Running transaction check ---> Package apr.x86_64 0:1.3.9-2.fc12 set to be updated ---> Package apr-util.x86_64 0:1.3.9-2.fc12 set to be updated ---> Package apr-util-ldap.x86_64 0:1.3.9-2.fc12 set to be updated ---> Package httpd-tools.x86_64 0:2.2.13-2.fc12 set to be updated ---> Package mailcap.noarch 0:2.1.30-1.fc12 set to be updated --> Finished Dependency Resolution Dependencies Resolved =======================================================================================  Package               Arch             Version                Repository         Size ======================================================================================= Installing:  httpd               x86_64           2.2.13-2.fc12            rawhide           735 k Installing for dependencies:  apr                 x86_64           1.3.9-2.fc12             rawhide           117 k  apr-util            x86_64           1.3.9-2.fc12             rawhide            84 k  apr-util-ldap       x86_64           1.3.9-2.fc12             rawhide            15 k  httpd-tools         x86_64           2.2.13-2.fc12            rawhide            63 k  mailcap             noarch           2.1.30-1.fc12            rawhide            25 k Transaction Summary ======================================================================================= Install       6 Package(s) Upgrade       0 Package(s) Total download size: 1.0 M Downloading Packages: (1/6): apr-1.3.9-2.fc12.x86_64.rpm                                   | 117 kB     00:00     (2/6): apr-util-1.3.9-2.fc12.x86_64.rpm                             |  84 kB     00:00     (3/6): apr-util-ldap-1.3.9-2.fc12.x86_64.rpm                         |  15 kB     00:00     (4/6): httpd-2.2.13-2.fc12.x86_64.rpm                               | 735 kB     00:00     (5/6): httpd-tools-2.2.13-2.fc12.x86_64.rpm                         |  63 kB     00:00     (6/6): mailcap-2.1.30-1.fc12.noarch.rpm                             |  25 kB     00:00     ---------------------------------------------------------------------------------------- Total                                                       875 kB/s | 1.0 MB     00:01     Running rpm_check_debug Running Transaction Test Finished Transaction Test Transaction Test Succeeded Running Transaction   Installing     : apr-1.3.9-2.fc12.x86_64                                         1/6   Installing     : apr-util-1.3.9-2.fc12.x86_64                                     2/6   Installing     : apr-util-ldap-1.3.9-2.fc12.x86_64                               3/6   Installing     : httpd-tools-2.2.13-2.fc12.x86_64                                 4/6   Installing     : mailcap-2.1.30-1.fc12.noarch                                     5/6   Installing     : httpd-2.2.13-2.fc12.x86_64                                       6/6 Installed:   httpd.x86_64 0:2.2.13-2.fc12                                                         Dependency Installed:   apr.x86_64 0:1.3.9-2.fc12            apr-util.x86_64 0:1.3.9-2.fc12   apr-util-ldap.x86_64 0:1.3.9-2.fc12  httpd-tools.x86_64 0:2.2.13-2.fc12   mailcap.noarch 0:2.1.30-1.fc12   Complete! [root@pcmk-1 ~]# 过了一会,我们可以看到集群把apache启动起来了。同样的,为了检测Apache服务器,我们要安装wget这个工具。Apache - 添加更多的服务现在 ,Apache已经可以添加到集群中了。我们管这个资源叫WebSite。我们需要用一个叫做apache的OCF脚本,这个脚本在heartbeat这个名字空间里,唯一一个需要设定的参数就是Apache的主配置文件路径,并且我们告诉集群每一分钟检测一次Apache是否运行。在继续之前,我们先确保两个节点安装了Apache.控制资源的启动停止顺序开启 Apache status URL确保资源在同一个节点运行即使我们更希望资源在pcmk-1上面运行,但是 这个优先值还是比资源黏性值要小。首先我们为Apache创建一个主页。在Fedora上面默认的Apache docroot是/var/www/html,所以我们在这个目录下面建立一个主页。为了方便,我们简化所用的页面并人工地在两个节点直接同步数据。所以在pcmk-2上面运行这个命令。把控制权交还给集群斜体部分是用来移动资源到pcmk-1约束,它是自动生成的。为了监控Apache实例的健康状态,并在它挂掉的时候恢复Apache服务,资源agent会假设 server-status URL是可用的。查看/etc/httpd/conf/httpd.conf并确保下面的选项没有被禁用或注释掉。Include output安装Apache在集群中手工地移动资源可以看到自动生成的约束已经没有了。如果我们查看集群的状态,我们也可以看到就如我们所预期的,资源还是在pcmk-1上面跑现在我们有了一个基本的但是功能齐全的双节点集群,我们已经可以往里面加些真的服务了。我们准备启动一个Apache服务,因为它是许多集群的主角,并且相对来说比较容易配置。当我们完成那些要求要资源移动到pcmk-1的操作--在我们的例子里面啥都没干 --我们可以用unmove命令把集群恢复到强制移动前的状态。因为我们之前配置了默认的资源黏性值,恢复了以后资源还是会在pcmk-1上面。Pacemaker 并不要求你机器的硬件配置是相同的,可能某些机器比另外的机器配置要好。这种状况下我们会希望设置:当某个节点可用时,资源就要跑在上面之类的规则。为了达到这个效果我们创建location约束。同样的,我们给他取一个描述性的名字(prefer-pcmk-1),指明我们想在上面跑WebSite这个服务,多想在上面跑(我们现在指定分值为50,但是在双节点的集群状态下,任何大于0的值都可以达到想要的效果),以及目标节点的名字:准备工作指定优先的 Location经常性的会有管理员想要无视集群然后强制把资源移动到指定的地方。 底层的操作就像我们上面创建的location约束一样。只要提供资源和目标地址,我们会补全剩余部分。这里有个办法强制地移动资源为了减少每个机器的负载,Pacemaker会智能地尝试将资源分散到各个节点上面。 然而我们可以告诉集群某两个资源是有联系并且要在同一个节点运行(或不同的节点运行)。这里我们告诉集群WebSite只能在有ClusterIP的节点上运行。如果ClusterIP在哪个节点都不存在,那么WebSite也不能运行。如果要看现在的分值,可以用ptest这个命令更新配置文件等等,资源还是在pcmk-2上面跑的!等等!WebSite这个资源跟IP没有跑在同一个节点上面!当Apache启动了,它跟可用的IP绑在了一起。它不会知道我们后来添加的IP,所以我们不仅需要控制他们在相同的节点运行,也要确保ClusterIP在WebSite之前就启动了。我们用添加ordering约束来达到这个效果。我们需要给这个order取个名字(apache-after-ip之类 描述性的),并指出他是托管的(这样当ClusterIP恢复了,同时会触发WebSite的恢复) 并且写明了这两个资源的启动顺序。ptest -sLpacemaker-master/doc/Clusters_from_Scratch/zh-CN/Ch-Apache.po000066400000000000000000001607451217637305600243610ustar00rootroot00000000000000# # AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: 0\n" "POT-Creation-Date: 2012-10-17T05:19:03\n" "PO-Revision-Date: 2010-12-15 23:37+0800\n" "Last-Translator: Charlie Chen \n" "Language-Team: None\n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. Tag: title #, no-c-format msgid "Apache - Adding More Services" msgstr "Apache - 添加更多的服务" #. Tag: title #, no-c-format msgid "Forward" msgstr "" #. Tag: para #, no-c-format msgid "Now that we have a basic but functional active/passive two-node cluster, we’re ready to add some real services. We’re going to start with Apache because its a feature of many clusters and relatively simple to configure." msgstr "现在我们有了一个基本的但是功能齐全的双节点集群,我们已经可以往里面加些真的服务了。我们准备启动一个Apache服务,因为它是许多集群的主角,并且相对来说比较容易配置。" #. Tag: title #, no-c-format msgid "Installation" msgstr "安装Apache" #. Tag: para #, fuzzy, no-c-format msgid "Before continuing, we need to make sure Apache is installed on both hosts. We also need the wget tool in order for the cluster to be able to check the status of the Apache server." msgstr "同样的,为了检测Apache服务器,我们要安装wget这个工具。" #. Tag: programlisting #, no-c-format msgid "# yum install -y httpd wget" msgstr "" #. Tag: literallayout #, no-c-format msgid "" "Loaded plugins: langpacks, presto, refresh-packagekit\n" "fedora/metalink | 2.6 kB 00:00\n" "updates/metalink | 3.2 kB 00:00\n" "updates-testing/metalink | 41 kB 00:00\n" "Resolving Dependencies\n" "--> Running transaction check\n" "---> Package httpd.x86_64 0:2.2.22-3.fc17 will be installed\n" "--> Processing Dependency: httpd-tools = 2.2.22-3.fc17 for package: httpd-2.2.22-3.fc17.x86_64\n" "--> Processing Dependency: apr-util-ldap for package: httpd-2.2.22-3.fc17.x86_64\n" "--> Processing Dependency: libaprutil-1.so.0()(64bit) for package: httpd-2.2.22-3.fc17.x86_64\n" "--> Processing Dependency: libapr-1.so.0()(64bit) for package: httpd-2.2.22-3.fc17.x86_64\n" "--> Running transaction check\n" "---> Package apr.x86_64 0:1.4.6-1.fc17 will be installed\n" "---> Package apr-util.x86_64 0:1.4.1-2.fc17 will be installed\n" "---> Package apr-util-ldap.x86_64 0:1.4.1-2.fc17 will be installed\n" "---> Package httpd-tools.x86_64 0:2.2.22-3.fc17 will be installed\n" "--> Finished Dependency Resolution\n" "\n" "Dependencies Resolved\n" "\n" "=====================================================================================\n" " Package Arch Version Repository Size\n" "=====================================================================================\n" "Installing:\n" " httpd x86_64 2.2.22-3.fc17 updates-testing 823 k\n" " wget x86_64 1.13.4-2.fc17 fedora 495 k\n" "Installing for dependencies:\n" " apr x86_64 1.4.6-1.fc17 fedora 99 k\n" " apr-util x86_64 1.4.1-2.fc17 fedora 78 k\n" " apr-util-ldap x86_64 1.4.1-2.fc17 fedora 17 k\n" " httpd-tools x86_64 2.2.22-3.fc17 updates-testing 74 k\n" "\n" "Transaction Summary\n" "=====================================================================================\n" "Install 1 Package (+4 Dependent packages)\n" "\n" "Total download size: 1.1 M\n" "Installed size: 3.5 M\n" "Downloading Packages:\n" "(1/6): apr-1.4.6-1.fc17.x86_64.rpm | 99 kB 00:00\n" "(2/6): apr-util-1.4.1-2.fc17.x86_64.rpm | 78 kB 00:00\n" "(3/6): apr-util-ldap-1.4.1-2.fc17.x86_64.rpm | 17 kB 00:00\n" "(4/6): httpd-2.2.22-3.fc17.x86_64.rpm | 823 kB 00:01\n" "(5/6): httpd-tools-2.2.22-3.fc17.x86_64.rpm | 74 kB 00:00\n" "(6/6): wget-1.13.4-2.fc17.x86_64.rpm | 495 kB 00:01\n" "-------------------------------------------------------------------------------------\n" "Total 238 kB/s | 1.1 MB 00:04\n" "Running Transaction Check\n" "Running Transaction Test\n" "Transaction Test Succeeded\n" "Running Transaction\n" " Installing : apr-1.4.6-1.fc17.x86_64 1/6\n" " Installing : apr-util-1.4.1-2.fc17.x86_64 2/6\n" " Installing : apr-util-ldap-1.4.1-2.fc17.x86_64 3/6\n" " Installing : httpd-tools-2.2.22-3.fc17.x86_64 4/6\n" " Installing : httpd-2.2.22-3.fc17.x86_64 5/6\n" " Installing : wget-1.13.4-2.fc17.x86_64 6/6\n" " Verifying : apr-util-ldap-1.4.1-2.fc17.x86_64 1/6\n" " Verifying : httpd-tools-2.2.22-3.fc17.x86_64 2/6\n" " Verifying : apr-util-1.4.1-2.fc17.x86_64 3/6\n" " Verifying : apr-1.4.6-1.fc17.x86_64 4/6\n" " Verifying : httpd-2.2.22-3.fc17.x86_64 5/6\n" " Verifying : wget-1.13.4-2.fc17.x86_64 6/6\n" "\n" "Installed:\n" " httpd.x86_64 0:2.2.22-3.fc17 wget.x86_64 0:1.13.4-2.fc17\n" "\n" "Dependency Installed:\n" " apr.x86_64 0:1.4.6-1.fc17 apr-util.x86_64 0:1.4.1-2.fc17\n" " apr-util-ldap.x86_64 0:1.4.1-2.fc17 httpd-tools.x86_64 0:2.2.22-3.fc17\n" "\n" "Complete!" msgstr "" #. Tag: title #, no-c-format msgid "Preparation" msgstr "准备工作" #. Tag: para #, no-c-format msgid "First we need to create a page for Apache to serve up. On Fedora the default Apache docroot is /var/www/html, so we’ll create an index file there." msgstr "首先我们为Apache创建一个主页。在Fedora上面默认的Apache docroot是/var/www/html,所以我们在这个目录下面建立一个主页。" #. Tag: programlisting #, fuzzy, no-c-format msgid "" "# cat <<-END >/var/www/html/index.html\n" " <html>\n" " <body>My Test Site - pcmk-1</body>\n" " </html>\n" "END" msgstr "" "\n" "[root@pcmk-1 ~]# cat <<-END >/var/www/html/index.html\n" " <html>\n" " <body>My Test Site - pcmk-1</body>\n" " </html>\n" " END\n" "[root@pcmk-1 ~]#\n" #. Tag: para #, no-c-format msgid "For the moment, we will simplify things by serving up only a static site and manually sync the data between the two nodes. So run the command again on pcmk-2." msgstr "为了方便,我们简化所用的页面并人工地在两个节点直接同步数据。所以在pcmk-2上面运行这个命令。" #. Tag: programlisting #, fuzzy, no-c-format msgid "" "[root@pcmk-2 ~]# cat <<-END >/var/www/html/index.html <html>\n" " <body>My Test Site - pcmk-2</body>\n" " </html>\n" " END" msgstr "" "\n" "[root@pcmk-2 ~]# cat <<-END >/var/www/html/index.html\n" " <html>\n" " <body>My Test Site - pcmk-2</body>\n" " </html>\n" " END\n" "[root@pcmk-2 ~]#\n" #. Tag: title #, no-c-format msgid "Enable the Apache status URL" msgstr "开启 Apache status URL" #. Tag: para #, fuzzy, no-c-format msgid "In order to monitor the health of your Apache instance, and recover it if it fails, the resource agent used by Pacemaker assumes the server-status URL is available. Look for the following in /etc/httpd/conf/httpd.conf and make sure it is not disabled or commented out:" msgstr "为了监控Apache实例的健康状态,并在它挂掉的时候恢复Apache服务,资源agent会假设 server-status URL是可用的。查看/etc/httpd/conf/httpd.conf并确保下面的选项没有被禁用或注释掉。" #. Tag: programlisting #, fuzzy, no-c-format msgid "" "<Location /server-status>\n" " SetHandler server-status\n" " Order deny,allow\n" " Deny from all\n" " Allow from 127.0.0.1\n" "</Location>" msgstr "" "\n" "<Location /server-status>\n" " SetHandler server-status\n" " Order deny,allow\n" " Deny from all\n" " Allow from 127.0.0.1\n" "</Location>\n" "\t " #. Tag: title #, no-c-format msgid "Update the Configuration" msgstr "更新配置文件" #. Tag: para #, fuzzy, no-c-format msgid "At this point, Apache is ready to go, all that needs to be done is to add it to the cluster. Lets call the resource WebSite. We need to use an OCF script called apache in the heartbeat namespace Compare the key used here ocf:heartbeat:apache with the one we used earlier for the IP address: ocf:heartbeat:IPaddr2 , the only required parameter is the path to the main Apache configuration file and we’ll tell the cluster to check once a minute that apache is still running." msgstr "现在 ,Apache已经可以添加到集群中了。我们管这个资源叫WebSite。我们需要用一个叫做apache的OCF脚本,这个脚本在heartbeat这个名字空间里,唯一一个需要设定的参数就是Apache的主配置文件路径,并且我们告诉集群每一分钟检测一次Apache是否运行。" #. Tag: screen #, no-c-format msgid "" "pcs resource create WebSite ocf:heartbeat:apache \\\n" " configfile=/etc/httpd/conf/httpd.conf \\\n" " statusurl=\"http://localhost/server-status\" op monitor interval=1min" msgstr "" #. Tag: para #, no-c-format msgid "By default, the operation timeout for all resource’s start, stop, and monitor operations is 20 seconds. In many cases this timeout period is less than the advised timeout period. For the purposes of this tutorial, we will adjust the global operation timeout default to 240 seconds." msgstr "" #. Tag: programlisting #, no-c-format msgid "" "# pcs resource op defaults timeout=240s\n" "# pcs resource op defaults\n" "timeout: 240s" msgstr "" #. Tag: para #, no-c-format msgid "After a short delay, we should see the cluster start apache" msgstr "过了一会,我们可以看到集群把apache启动起来了。" #. Tag: programlisting #, fuzzy, no-c-format msgid "" "# pcs status\n" "\n" "Last updated: Fri Sep 14 10:51:27 2012\n" "Last change: Fri Sep 14 10:50:46 2012 via crm_attribute on pcmk-1\n" "Stack: corosync\n" "Current DC: pcmk-2 (2) - partition with quorum\n" "Version: 1.1.8-1.el7-60a19ed12fdb4d5c6a6b6767f52e5391e447fec0\n" "2 Nodes configured, unknown expected votes\n" "2 Resources configured.\n" "\n" "Online: [ pcmk-1 pcmk-2 ]\n" "\n" "Full list of resources:\n" "\n" " ClusterIP (ocf::heartbeat:IPaddr2): Started pcmk-2\n" " WebSite (ocf::heartbeat:apache): Started pcmk-1" msgstr "" "\n" "[root@pcmk-1 ~]# crm_mon\n" "============\n" "Last updated: Fri Aug 28 16:12:49 2009\n" "Stack: openais\n" "Current DC: pcmk-2 - partition with quorum\n" "Version: 1.0.5-462f1569a43740667daf7b0f6b521742e9eb8fa7\n" "2 Nodes configured, 2 expected votes\n" "2 Resources configured.\n" "============\n" "\n" "Online: [ pcmk-1 pcmk-2 ]\n" "\n" "ClusterIP        (ocf::heartbeat:IPaddr):        Started pcmk-2\n" "WebSite        (ocf::heartbeat:apache):        Started pcmk-1\n" #. Tag: para #, no-c-format msgid "Wait a moment, the WebSite resource isn’t running on the same host as our IP address!" msgstr "等等!WebSite这个资源跟IP没有跑在同一个节点上面!" #. Tag: para #, no-c-format msgid "If, in the pcs status output, you see the WebSite resource has failed to start, then you’ve likely not enabled the status URL correctly. You can check if this is the problem by running:" msgstr "" #. Tag: literallayout #, no-c-format msgid "wget http://127.0.0.1/server-status" msgstr "" #. Tag: para #, no-c-format msgid "If you see Connection refused in the output, then this is indeed the problem. Check to ensure that Allow from 127.0.0.1 is present for the <Location /server-status> block." msgstr "" #. Tag: title #, no-c-format msgid "Ensuring Resources Run on the Same Host" msgstr "确保资源在同一个节点运行" #. Tag: para #, fuzzy, no-c-format msgid "To reduce the load on any one machine, Pacemaker will generally try to spread the configured resources across the cluster nodes. However we can tell the cluster that two resources are related and need to run on the same host (or not at all). Here we instruct the cluster that WebSite can only run on the host that ClusterIP is active on." msgstr "为了减少每个机器的负载,Pacemaker会智能地尝试将资源分散到各个节点上面。 然而我们可以告诉集群某两个资源是有联系并且要在同一个节点运行(或不同的节点运行)。这里我们告诉集群WebSite只能在有ClusterIP的节点上运行。如果ClusterIP在哪个节点都不存在,那么WebSite也不能运行。" #. Tag: para #, no-c-format msgid "To achieve this we use a colocation constraint that indicates it is mandatory for WebSite to run on the same node as ClusterIP. The \"mandatory\" part of the colocation constraint is indicated by using a score of INFINITY. The INFINITY score also means that if ClusterIP is not active anywhere, WebSite will not be permitted to run." msgstr "" #. Tag: para #, no-c-format msgid "If ClusterIP is not active anywhere, WebSite will not be permitted to run anywhere." msgstr "" #. Tag: para #, no-c-format msgid "Colocation constraints are \"directional\", in that they imply certain things about the order in which the two resources will have a location chosen. In this case we’re saying WebSite needs to be placed on the same machine as ClusterIP, this implies that we must know the location of ClusterIP before choosing a location for WebSite." msgstr "" #. Tag: programlisting #, no-c-format msgid "" "# pcs constraint colocation add WebSite ClusterIP INFINITY\n" "# pcs constraint\n" "Location Constraints:\n" "Ordering Constraints:\n" "Colocation Constraints:\n" " WebSite with ClusterIP\n" "# pcs status\n" "\n" "Last updated: Fri Sep 14 11:00:44 2012\n" "Last change: Fri Sep 14 11:00:25 2012 via cibadmin on pcmk-1\n" "Stack: corosync\n" "Current DC: pcmk-2 (2) - partition with quorum\n" "Version: 1.1.8-1.el7-60a19ed12fdb4d5c6a6b6767f52e5391e447fec0\n" "2 Nodes configured, unknown expected votes\n" "2 Resources configured.\n" "\n" "Online: [ pcmk-1 pcmk-2 ]\n" "\n" "Full list of resources:\n" "\n" " ClusterIP (ocf::heartbeat:IPaddr2): Started pcmk-2\n" " WebSite (ocf::heartbeat:apache): Started pcmk-2" msgstr "" #. Tag: title #, no-c-format msgid "Controlling Resource Start/Stop Ordering" msgstr "控制资源的启动停止顺序" #. Tag: para #, fuzzy, no-c-format msgid "When Apache starts, it binds to the available IP addresses. It doesn’t know about any addresses we add afterwards, so not only do they need to run on the same node, but we need to make sure ClusterIP is already active before we start WebSite. We do this by adding an ordering constraint." msgstr "当Apache启动了,它跟可用的IP绑在了一起。它不会知道我们后来添加的IP,所以我们不仅需要控制他们在相同的节点运行,也要确保ClusterIP在WebSite之前就启动了。我们用添加ordering约束来达到这个效果。我们需要给这个order取个名字(apache-after-ip之类 描述性的),并指出他是托管的(这样当ClusterIP恢复了,同时会触发WebSite的恢复) 并且写明了这两个资源的启动顺序。" #. Tag: para #, no-c-format msgid "By default all order constraints are mandatory constraints unless otherwise configured. This means that the recovery of ClusterIP will also trigger the recovery of WebSite." msgstr "" #. Tag: programlisting #, no-c-format msgid "" "# pcs constraint order ClusterIP then WebSite\n" "Adding ClusterIP WebSite (kind: Mandatory) (Options: first-action=start then-action=start)\n" "# pcs constraint\n" "Location Constraints:\n" "Ordering Constraints:\n" " start ClusterIP then start WebSite\n" "Colocation Constraints:\n" " WebSite with ClusterIP" msgstr "" #. Tag: title #, no-c-format msgid "Specifying a Preferred Location" msgstr "指定优先的 Location" #. Tag: para #, fuzzy, no-c-format msgid "Pacemaker does not rely on any sort of hardware symmetry between nodes, so it may well be that one machine is more powerful than the other. In such cases it makes sense to host the resources there if it is available. To do this we create a location constraint." msgstr "Pacemaker 并不要求你机器的硬件配置是相同的,可能某些机器比另外的机器配置要好。这种状况下我们会希望设置:当某个节点可用时,资源就要跑在上面之类的规则。为了达到这个效果我们创建location约束。同样的,我们给他取一个描述性的名字(prefer-pcmk-1),指明我们想在上面跑WebSite这个服务,多想在上面跑(我们现在指定分值为50,但是在双节点的集群状态下,任何大于0的值都可以达到想要的效果),以及目标节点的名字:" #. Tag: para #, no-c-format msgid "In the location constraint below, we are saying the WebSite resource prefers the node pcmk-1 with a score of 50. The score here indicates how badly we’d like the resource to run somewhere." msgstr "" #. Tag: programlisting #, no-c-format msgid "" "# pcs constraint location WebSite prefers pcmk-1=50\n" "# pcs constraint\n" "Location Constraints:\n" " Resource: WebSite\n" " Enabled on: pcmk-1 (score:50)\n" "Ordering Constraints:\n" " start ClusterIP then start WebSite\n" "Colocation Constraints:\n" " WebSite with ClusterIP\n" "# pcs status\n" "Last updated: Fri Sep 14 11:06:37 2012\n" "Last change: Fri Sep 14 11:06:26 2012 via cibadmin on pcmk-1\n" "Stack: corosync\n" "Current DC: pcmk-2 (2) - partition with quorum\n" "Version: 1.1.8-1.el7-60a19ed12fdb4d5c6a6b6767f52e5391e447fec0\n" "2 Nodes configured, unknown expected votes\n" "2 Resources configured.\n" "\n" "Online: [ pcmk-1 pcmk-2 ]\n" "\n" "Full list of resources:\n" "\n" " ClusterIP (ocf::heartbeat:IPaddr2): Started pcmk-2\n" " WebSite (ocf::heartbeat:apache): Started pcmk-2" msgstr "" #. Tag: para #, no-c-format msgid "Wait a minute, the resources are still on pcmk-2!" msgstr "等等,资源还是在pcmk-2上面跑的!" #. Tag: para #, no-c-format msgid "Even though we now prefer pcmk-1 over pcmk-2, that preference is (intentionally) less than the resource stickiness (how much we preferred not to have unnecessary downtime)." msgstr "即使我们更希望资源在pcmk-1上面运行,但是 这个优先值还是比资源黏性值要小。" #. Tag: para #, fuzzy, no-c-format msgid "To see the current placement scores, you can use a tool called crm_simulate" msgstr "如果要看现在的分值,可以用ptest这个命令" #. Tag: programlisting #, no-c-format msgid "" "# crm_simulate -sL\n" "Current cluster status:\n" "Online: [ pcmk-1 pcmk-2 ]\n" "\n" " ClusterIP (ocf:heartbeat:IPaddr2): Started pcmk-2\n" " WebSite (ocf:heartbeat:apache): Started pcmk-2\n" "\n" "Allocation scores:\n" "native_color: ClusterIP allocation score on pcmk-1: 50\n" "native_color: ClusterIP allocation score on pcmk-2: 200\n" "native_color: WebSite allocation score on pcmk-1: -INFINITY\n" "native_color: WebSite allocation score on pcmk-2: 100\n" "\n" "Transition Summary:" msgstr "" #. Tag: title #, no-c-format msgid "Manually Moving Resources Around the Cluster" msgstr "在集群中手工地移动资源" #. Tag: para #, fuzzy, no-c-format msgid "There are always times when an administrator needs to override the cluster and force resources to move to a specific location. By updating our previous location constraint with a score of INFINITY, WebSite will be forced to move to pcmk-1." msgstr "经常性的会有管理员想要无视集群然后强制把资源移动到指定的地方。 底层的操作就像我们上面创建的location约束一样。只要提供资源和目标地址,我们会补全剩余部分。" #. Tag: programlisting #, no-c-format msgid "" "# pcs constraint location WebSite prefers pcmk-1=INFINITY\n" "# pcs constraint all\n" "Location Constraints:\n" " Resource: WebSite\n" " Enabled on: pcmk-1 (score:INFINITY) (id:location-WebSite-pcmk-1-INFINITY)\n" "Ordering Constraints:\n" " start ClusterIP then start WebSite (Mandatory) (id:order-ClusterIP-WebSite-mandatory)\n" "Colocation Constraints:\n" " WebSite with ClusterIP (INFINITY) (id:colocation-WebSite-ClusterIP-INFINITY)\n" "# pcs status\n" "\n" "Last updated: Fri Sep 14 11:16:26 2012\n" "Last change: Fri Sep 14 11:16:18 2012 via cibadmin on pcmk-1\n" "Stack: corosync\n" "Current DC: pcmk-2 (2) - partition with quorum\n" "Version: 1.1.8-1.el7-60a19ed12fdb4d5c6a6b6767f52e5391e447fec0\n" "2 Nodes configured, unknown expected votes\n" "2 Resources configured.\n" "\n" "Online: [ pcmk-1 pcmk-2 ]\n" "\n" "Full list of resources:\n" "\n" " ClusterIP (ocf::heartbeat:IPaddr2): Started pcmk-1\n" " WebSite (ocf::heartbeat:apache): Started pcmk-1" msgstr "" #. Tag: title #, no-c-format msgid "Giving Control Back to the Cluster" msgstr "把控制权交还给集群" #. Tag: para #, no-c-format msgid "Once we’ve finished whatever activity that required us to move the resources to pcmk-1, in our case nothing, we can then allow the cluster to resume normal operation with the unmove command. Since we previously configured a default stickiness, the resources will remain on pcmk-1." msgstr "当我们完成那些要求要资源移动到pcmk-1的操作--在我们的例子里面啥都没干 --我们可以用unmove命令把集群恢复到强制移动前的状态。因为我们之前配置了默认的资源黏性值,恢复了以后资源还是会在pcmk-1上面。" #. Tag: programlisting #, no-c-format msgid "" "# pcs constraint all\n" "Location Constraints:\n" " Resource: WebSite\n" " Enabled on: pcmk-1 (score:INFINITY) (id:location-WebSite-pcmk-1-INFINITY)\n" "Ordering Constraints:\n" " start ClusterIP then start WebSite (Mandatory) (id:order-ClusterIP-WebSite-mandatory)\n" "Colocation Constraints:\n" " WebSite with ClusterIP (INFINITY) (id:colocation-WebSite-ClusterIP-INFINITY)\n" "# pcs constraint rm location-WebSite-pcmk-1-INFINITY\n" "# pcs constraint\n" "Location Constraints:\n" "Ordering Constraints:\n" " start ClusterIP then start WebSite\n" "Colocation Constraints:\n" " WebSite with ClusterIP" msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "Note that the constraint is now gone. If we check the cluster status, we can also see that as expected the resources are still active on pcmk-1." msgstr "可以看到自动生成的约束已经没有了。如果我们查看集群的状态,我们也可以看到就如我们所预期的,资源还是在pcmk-1上面跑" #. Tag: programlisting #, fuzzy, no-c-format msgid "" "# pcs status\n" "\n" "Last updated: Fri Sep 14 11:57:12 2012\n" "Last change: Fri Sep 14 11:57:03 2012 via cibadmin on pcmk-1\n" "Stack: corosync\n" "Current DC: pcmk-2 (2) - partition with quorum\n" "Version: 1.1.8-1.el7-60a19ed12fdb4d5c6a6b6767f52e5391e447fec0\n" "2 Nodes configured, unknown expected votes\n" "2 Resources configured.\n" "\n" "Online: [ pcmk-1 pcmk-2 ]\n" "\n" "Full list of resources:\n" "\n" " ClusterIP (ocf::heartbeat:IPaddr2): Started pcmk-1\n" " WebSite (ocf::heartbeat:apache): Started pcmk-1" msgstr "" "\n" "[root@pcmk-1 ~]# crm_mon\n" "============\n" "Last updated: Fri Aug 28 16:12:49 2009\n" "Stack: openais\n" "Current DC: pcmk-2 - partition with quorum\n" "Version: 1.0.5-462f1569a43740667daf7b0f6b521742e9eb8fa7\n" "2 Nodes configured, 2 expected votes\n" "2 Resources configured.\n" "============\n" "\n" "Online: [ pcmk-1 pcmk-2 ]\n" "\n" "ClusterIP        (ocf::heartbeat:IPaddr):        Started pcmk-2\n" "WebSite        (ocf::heartbeat:apache):        Started pcmk-1\n" #~ msgid "Before continuing, we need to make sure Apache is installed on both hosts." #~ msgstr "在继续之前,我们先确保两个节点安装了Apache." #~ msgid "" #~ "\n" #~ "[root@ppcmk-1 ~]# yum install -y httpd\n" #~ "Setting up Install Process\n" #~ "Resolving Dependencies\n" #~ "--> Running transaction check\n" #~ "---> Package httpd.x86_64 0:2.2.13-2.fc12 set to be updated\n" #~ "--> Processing Dependency: httpd-tools = 2.2.13-2.fc12 for package: httpd-2.2.13-2.fc12.x86_64\n" #~ "--> Processing Dependency: apr-util-ldap for package: httpd-2.2.13-2.fc12.x86_64\n" #~ "--> Processing Dependency: /etc/mime.types for package: httpd-2.2.13-2.fc12.x86_64\n" #~ "--> Processing Dependency: libaprutil-1.so.0()(64bit) for package: httpd-2.2.13-2.fc12.x86_64\n" #~ "--> Processing Dependency: libapr-1.so.0()(64bit) for package: httpd-2.2.13-2.fc12.x86_64\n" #~ "--> Running transaction check\n" #~ "---> Package apr.x86_64 0:1.3.9-2.fc12 set to be updated\n" #~ "---> Package apr-util.x86_64 0:1.3.9-2.fc12 set to be updated\n" #~ "---> Package apr-util-ldap.x86_64 0:1.3.9-2.fc12 set to be updated\n" #~ "---> Package httpd-tools.x86_64 0:2.2.13-2.fc12 set to be updated\n" #~ "---> Package mailcap.noarch 0:2.1.30-1.fc12 set to be updated\n" #~ "--> Finished Dependency Resolution\n" #~ "\n" #~ "Dependencies Resolved\n" #~ "\n" #~ "=======================================================================================\n" #~ " Package               Arch             Version                Repository         Size\n" #~ "=======================================================================================\n" #~ "Installing:\n" #~ " httpd               x86_64           2.2.13-2.fc12            rawhide           735 k\n" #~ "Installing for dependencies:\n" #~ " apr                 x86_64           1.3.9-2.fc12             rawhide           117 k\n" #~ " apr-util            x86_64           1.3.9-2.fc12             rawhide            84 k\n" #~ " apr-util-ldap       x86_64           1.3.9-2.fc12             rawhide            15 k\n" #~ " httpd-tools         x86_64           2.2.13-2.fc12            rawhide            63 k\n" #~ " mailcap             noarch           2.1.30-1.fc12            rawhide            25 k\n" #~ "\n" #~ "Transaction Summary\n" #~ "=======================================================================================\n" #~ "Install       6 Package(s)\n" #~ "Upgrade       0 Package(s)\n" #~ "\n" #~ "Total download size: 1.0 M\n" #~ "Downloading Packages:\n" #~ "(1/6): apr-1.3.9-2.fc12.x86_64.rpm                                   | 117 kB     00:00     \n" #~ "(2/6): apr-util-1.3.9-2.fc12.x86_64.rpm                             |  84 kB     00:00     \n" #~ "(3/6): apr-util-ldap-1.3.9-2.fc12.x86_64.rpm                         |  15 kB     00:00     \n" #~ "(4/6): httpd-2.2.13-2.fc12.x86_64.rpm                               | 735 kB     00:00     \n" #~ "(5/6): httpd-tools-2.2.13-2.fc12.x86_64.rpm                         |  63 kB     00:00     \n" #~ "(6/6): mailcap-2.1.30-1.fc12.noarch.rpm                             |  25 kB     00:00     \n" #~ "----------------------------------------------------------------------------------------\n" #~ "Total                                                       875 kB/s | 1.0 MB     00:01     \n" #~ "Running rpm_check_debug\n" #~ "Running Transaction Test\n" #~ "Finished Transaction Test\n" #~ "Transaction Test Succeeded\n" #~ "Running Transaction\n" #~ "  Installing     : apr-1.3.9-2.fc12.x86_64                                         1/6 \n" #~ "  Installing     : apr-util-1.3.9-2.fc12.x86_64                                     2/6 \n" #~ "  Installing     : apr-util-ldap-1.3.9-2.fc12.x86_64                               3/6 \n" #~ "  Installing     : httpd-tools-2.2.13-2.fc12.x86_64                                 4/6 \n" #~ "  Installing     : mailcap-2.1.30-1.fc12.noarch                                     5/6 \n" #~ "  Installing     : httpd-2.2.13-2.fc12.x86_64                                       6/6 \n" #~ "\n" #~ "Installed:\n" #~ "  httpd.x86_64 0:2.2.13-2.fc12                                                         \n" #~ "\n" #~ "Dependency Installed:\n" #~ "  apr.x86_64 0:1.3.9-2.fc12            apr-util.x86_64 0:1.3.9-2.fc12\n" #~ "  apr-util-ldap.x86_64 0:1.3.9-2.fc12  httpd-tools.x86_64 0:2.2.13-2.fc12\n" #~ "  mailcap.noarch 0:2.1.30-1.fc12  \n" #~ "\n" #~ "Complete!\n" #~ "[root@pcmk-1 ~]#\n" #~ msgstr "" #~ "\n" #~ "[root@ppcmk-1 ~]# yum install -y httpd\n" #~ "Setting up Install Process\n" #~ "Resolving Dependencies\n" #~ "--> Running transaction check\n" #~ "---> Package httpd.x86_64 0:2.2.13-2.fc12 set to be updated\n" #~ "--> Processing Dependency: httpd-tools = 2.2.13-2.fc12 for package: httpd-2.2.13-2.fc12.x86_64\n" #~ "--> Processing Dependency: apr-util-ldap for package: httpd-2.2.13-2.fc12.x86_64\n" #~ "--> Processing Dependency: /etc/mime.types for package: httpd-2.2.13-2.fc12.x86_64\n" #~ "--> Processing Dependency: libaprutil-1.so.0()(64bit) for package: httpd-2.2.13-2.fc12.x86_64\n" #~ "--> Processing Dependency: libapr-1.so.0()(64bit) for package: httpd-2.2.13-2.fc12.x86_64\n" #~ "--> Running transaction check\n" #~ "---> Package apr.x86_64 0:1.3.9-2.fc12 set to be updated\n" #~ "---> Package apr-util.x86_64 0:1.3.9-2.fc12 set to be updated\n" #~ "---> Package apr-util-ldap.x86_64 0:1.3.9-2.fc12 set to be updated\n" #~ "---> Package httpd-tools.x86_64 0:2.2.13-2.fc12 set to be updated\n" #~ "---> Package mailcap.noarch 0:2.1.30-1.fc12 set to be updated\n" #~ "--> Finished Dependency Resolution\n" #~ "\n" #~ "Dependencies Resolved\n" #~ "\n" #~ "=======================================================================================\n" #~ " Package               Arch             Version                Repository         Size\n" #~ "=======================================================================================\n" #~ "Installing:\n" #~ " httpd               x86_64           2.2.13-2.fc12            rawhide           735 k\n" #~ "Installing for dependencies:\n" #~ " apr                 x86_64           1.3.9-2.fc12             rawhide           117 k\n" #~ " apr-util            x86_64           1.3.9-2.fc12             rawhide            84 k\n" #~ " apr-util-ldap       x86_64           1.3.9-2.fc12             rawhide            15 k\n" #~ " httpd-tools         x86_64           2.2.13-2.fc12            rawhide            63 k\n" #~ " mailcap             noarch           2.1.30-1.fc12            rawhide            25 k\n" #~ "\n" #~ "Transaction Summary\n" #~ "=======================================================================================\n" #~ "Install       6 Package(s)\n" #~ "Upgrade       0 Package(s)\n" #~ "\n" #~ "Total download size: 1.0 M\n" #~ "Downloading Packages:\n" #~ "(1/6): apr-1.3.9-2.fc12.x86_64.rpm                                   | 117 kB     00:00     \n" #~ "(2/6): apr-util-1.3.9-2.fc12.x86_64.rpm                             |  84 kB     00:00     \n" #~ "(3/6): apr-util-ldap-1.3.9-2.fc12.x86_64.rpm                         |  15 kB     00:00     \n" #~ "(4/6): httpd-2.2.13-2.fc12.x86_64.rpm                               | 735 kB     00:00     \n" #~ "(5/6): httpd-tools-2.2.13-2.fc12.x86_64.rpm                         |  63 kB     00:00     \n" #~ "(6/6): mailcap-2.1.30-1.fc12.noarch.rpm                             |  25 kB     00:00     \n" #~ "----------------------------------------------------------------------------------------\n" #~ "Total                                                       875 kB/s | 1.0 MB     00:01     \n" #~ "Running rpm_check_debug\n" #~ "Running Transaction Test\n" #~ "Finished Transaction Test\n" #~ "Transaction Test Succeeded\n" #~ "Running Transaction\n" #~ "  Installing     : apr-1.3.9-2.fc12.x86_64                                         1/6 \n" #~ "  Installing     : apr-util-1.3.9-2.fc12.x86_64                                     2/6 \n" #~ "  Installing     : apr-util-ldap-1.3.9-2.fc12.x86_64                               3/6 \n" #~ "  Installing     : httpd-tools-2.2.13-2.fc12.x86_64                                 4/6 \n" #~ "  Installing     : mailcap-2.1.30-1.fc12.noarch                                     5/6 \n" #~ "  Installing     : httpd-2.2.13-2.fc12.x86_64                                       6/6 \n" #~ "\n" #~ "Installed:\n" #~ "  httpd.x86_64 0:2.2.13-2.fc12                                                         \n" #~ "\n" #~ "Dependency Installed:\n" #~ "  apr.x86_64 0:1.3.9-2.fc12            apr-util.x86_64 0:1.3.9-2.fc12\n" #~ "  apr-util-ldap.x86_64 0:1.3.9-2.fc12  httpd-tools.x86_64 0:2.2.13-2.fc12\n" #~ "  mailcap.noarch 0:2.1.30-1.fc12  \n" #~ "\n" #~ "Complete!\n" #~ "[root@pcmk-1 ~]#\n" #~ msgid "" #~ "\n" #~ "[root@pcmk-1 ~]# yum install -y wget\n" #~ "Setting up Install Process\n" #~ "Resolving Dependencies\n" #~ "--> Running transaction check\n" #~ "---> Package wget.x86_64 0:1.11.4-5.fc12 set to be updated\n" #~ "--> Finished Dependency Resolution\n" #~ "\n" #~ "Dependencies Resolved\n" #~ "\n" #~ "===========================================================================================\n" #~ " Package        Arch             Version                      Repository               Size\n" #~ "===========================================================================================\n" #~ "Installing:\n" #~ " wget         x86_64          1.11.4-5.fc12                   rawhide                393 k\n" #~ "\n" #~ "Transaction Summary\n" #~ "===========================================================================================\n" #~ "Install       1 Package(s)\n" #~ "Upgrade       0 Package(s)\n" #~ "\n" #~ "Total download size: 393 k\n" #~ "Downloading Packages:\n" #~ "wget-1.11.4-5.fc12.x86_64.rpm                                            | 393 kB     00:00     \n" #~ "Running rpm_check_debug\n" #~ "Running Transaction Test\n" #~ "Finished Transaction Test\n" #~ "Transaction Test Succeeded\n" #~ "Running Transaction\n" #~ "  Installing     : wget-1.11.4-5.fc12.x86_64                                            1/1 \n" #~ "\n" #~ "Installed:\n" #~ "  wget.x86_64 0:1.11.4-5.fc12\n" #~ "\n" #~ "Complete!\n" #~ "[root@pcmk-1 ~]#\n" #~ msgstr "" #~ "\n" #~ "[root@pcmk-1 ~]# yum install -y wget\n" #~ "Setting up Install Process\n" #~ "Resolving Dependencies\n" #~ "--> Running transaction check\n" #~ "---> Package wget.x86_64 0:1.11.4-5.fc12 set to be updated\n" #~ "--> Finished Dependency Resolution\n" #~ "\n" #~ "Dependencies Resolved\n" #~ "\n" #~ "===========================================================================================\n" #~ " Package        Arch             Version                      Repository               Size\n" #~ "===========================================================================================\n" #~ "Installing:\n" #~ " wget         x86_64          1.11.4-5.fc12                   rawhide                393 k\n" #~ "\n" #~ "Transaction Summary\n" #~ "===========================================================================================\n" #~ "Install       1 Package(s)\n" #~ "Upgrade       0 Package(s)\n" #~ "\n" #~ "Total download size: 393 k\n" #~ "Downloading Packages:\n" #~ "wget-1.11.4-5.fc12.x86_64.rpm                                            | 393 kB     00:00     \n" #~ "Running rpm_check_debug\n" #~ "Running Transaction Test\n" #~ "Finished Transaction Test\n" #~ "Transaction Test Succeeded\n" #~ "Running Transaction\n" #~ "  Installing     : wget-1.11.4-5.fc12.x86_64                                            1/1 \n" #~ "\n" #~ "Installed:\n" #~ "  wget.x86_64 0:1.11.4-5.fc12\n" #~ "\n" #~ "Complete!\n" #~ "[root@pcmk-1 ~]#\n" #~ msgid "" #~ "\n" #~ "[root@pcmk-1 ~]# crm configure primitive WebSite ocf:heartbeat:apache params configfile=/etc/httpd/conf/httpd.conf op monitor interval=1min\n" #~ "[root@pcmk-1 ~]# crm configure show\n" #~ "node pcmk-1\n" #~ "node pcmk-2\n" #~ "primitive WebSite ocf:heartbeat:apache \\\n" #~ " params configfile=\"/etc/httpd/conf/httpd.conf\" \\\n" #~ " op monitor interval=\"1min\"\n" #~ "primitive ClusterIP ocf:heartbeat:IPaddr2 \\\n" #~ "        params ip=\"192.168.122.101\" cidr_netmask=\"32\" \\\n" #~ "        op monitor interval=\"30s\"\n" #~ "property $id=\"cib-bootstrap-options\" \\\n" #~ "        dc-version=\"1.0.5-462f1569a43740667daf7b0f6b521742e9eb8fa7\" \\\n" #~ "        cluster-infrastructure=\"openais\" \\\n" #~ "        expected-quorum-votes=\"2\" \\\n" #~ "        stonith-enabled=\"false\" \\\n" #~ "        no-quorum-policy=\"ignore\"\n" #~ "rsc_defaults $id=\"rsc-options\" \\\n" #~ "        resource-stickiness=\"100\"\n" #~ msgstr "" #~ "\n" #~ "[root@pcmk-1 ~]# crm configure primitive WebSite ocf:heartbeat:apache params configfile=/etc/httpd/conf/httpd.conf op monitor interval=1min\n" #~ "[root@pcmk-1 ~]# crm configure show\n" #~ "node pcmk-1\n" #~ "node pcmk-2\n" #~ "primitive WebSite ocf:heartbeat:apache \\\n" #~ " params configfile=\"/etc/httpd/conf/httpd.conf\" \\\n" #~ " op monitor interval=\"1min\"\n" #~ "primitive ClusterIP ocf:heartbeat:IPaddr2 \\\n" #~ "        params ip=\"192.168.122.101\" cidr_netmask=\"32\" \\\n" #~ "        op monitor interval=\"30s\"\n" #~ "property $id=\"cib-bootstrap-options\" \\\n" #~ "        dc-version=\"1.0.5-462f1569a43740667daf7b0f6b521742e9eb8fa7\" \\\n" #~ "        cluster-infrastructure=\"openais\" \\\n" #~ "        expected-quorum-votes=\"2\" \\\n" #~ "        stonith-enabled=\"false\" \\\n" #~ "        no-quorum-policy=\"ignore\"\n" #~ "rsc_defaults $id=\"rsc-options\" \\\n" #~ "        resource-stickiness=\"100\"\n" #~ msgid "" #~ "\n" #~ "[root@pcmk-1 ~]# crm configure colocation website-with-ip INFINITY: WebSite ClusterIP\n" #~ "[root@pcmk-1 ~]# crm configure show\n" #~ "node pcmk-1\n" #~ "node pcmk-2\n" #~ "primitive WebSite ocf:heartbeat:apache \\\n" #~ "        params configfile=\"/etc/httpd/conf/httpd.conf\" \\\n" #~ "        op monitor interval=\"1min\"\n" #~ "primitive ClusterIP ocf:heartbeat:IPaddr2 \\\n" #~ "        params ip=\"192.168.122.101\" cidr_netmask=\"32\" \\\n" #~ "        op monitor interval=\"30s\"\n" #~ "colocation website-with-ip inf: WebSite ClusterIP\n" #~ "property $id=\"cib-bootstrap-options\" \\\n" #~ "        dc-version=\"1.0.5-462f1569a43740667daf7b0f6b521742e9eb8fa7\" \\\n" #~ "        cluster-infrastructure=\"openais\" \\\n" #~ "        expected-quorum-votes=\"2\" \\\n" #~ "        stonith-enabled=\"false\" \\\n" #~ "        no-quorum-policy=\"ignore\"\n" #~ "rsc_defaults $id=\"rsc-options\" \\\n" #~ "        resource-stickiness=\"100\"\n" #~ "[root@pcmk-1 ~]# crm_mon\n" #~ "============\n" #~ "Last updated: Fri Aug 28 16:14:34 2009\n" #~ "Stack: openais\n" #~ "Current DC: pcmk-2 - partition with quorum\n" #~ "Version: 1.0.5-462f1569a43740667daf7b0f6b521742e9eb8fa7\n" #~ "2 Nodes configured, 2 expected votes\n" #~ "2 Resources configured.\n" #~ "============\n" #~ "\n" #~ "Online: [ pcmk-1 pcmk-2 ]\n" #~ "\n" #~ "ClusterIP        (ocf::heartbeat:IPaddr):        Started pcmk-2\n" #~ "WebSite        (ocf::heartbeat:apache):        Started pcmk-2\n" #~ msgstr "" #~ "\n" #~ "[root@pcmk-1 ~]# crm configure colocation website-with-ip INFINITY: WebSite ClusterIP\n" #~ "[root@pcmk-1 ~]# crm configure show\n" #~ "node pcmk-1\n" #~ "node pcmk-2\n" #~ "primitive WebSite ocf:heartbeat:apache \\\n" #~ "        params configfile=\"/etc/httpd/conf/httpd.conf\" \\\n" #~ "        op monitor interval=\"1min\"\n" #~ "primitive ClusterIP ocf:heartbeat:IPaddr2 \\\n" #~ "        params ip=\"192.168.122.101\" cidr_netmask=\"32\" \\\n" #~ "        op monitor interval=\"30s\"\n" #~ "colocation website-with-ip inf: WebSite ClusterIP\n" #~ "property $id=\"cib-bootstrap-options\" \\\n" #~ "        dc-version=\"1.0.5-462f1569a43740667daf7b0f6b521742e9eb8fa7\" \\\n" #~ "        cluster-infrastructure=\"openais\" \\\n" #~ "        expected-quorum-votes=\"2\" \\\n" #~ "        stonith-enabled=\"false\" \\\n" #~ "        no-quorum-policy=\"ignore\"\n" #~ "rsc_defaults $id=\"rsc-options\" \\\n" #~ "        resource-stickiness=\"100\"\n" #~ "[root@pcmk-1 ~]# crm_mon\n" #~ "============\n" #~ "Last updated: Fri Aug 28 16:14:34 2009\n" #~ "Stack: openais\n" #~ "Current DC: pcmk-2 - partition with quorum\n" #~ "Version: 1.0.5-462f1569a43740667daf7b0f6b521742e9eb8fa7\n" #~ "2 Nodes configured, 2 expected votes\n" #~ "2 Resources configured.\n" #~ "============\n" #~ "\n" #~ "Online: [ pcmk-1 pcmk-2 ]\n" #~ "\n" #~ "ClusterIP        (ocf::heartbeat:IPaddr):        Started pcmk-2\n" #~ "WebSite        (ocf::heartbeat:apache):        Started pcmk-2\n" #~ msgid "" #~ "\n" #~ "[root@pcmk-1 ~]# crm configure order apache-after-ip mandatory: ClusterIP WebSite\n" #~ "[root@pcmk-1 ~]# crm configure show\n" #~ "node pcmk-1\n" #~ "node pcmk-2\n" #~ "primitive WebSite ocf:heartbeat:apache \\\n" #~ "        params configfile=\"/etc/httpd/conf/httpd.conf\" \\\n" #~ "        op monitor interval=\"1min\"\n" #~ "primitive ClusterIP ocf:heartbeat:IPaddr2 \\\n" #~ "        params ip=\"192.168.122.101\" cidr_netmask=\"32\" \\\n" #~ "        op monitor interval=\"30s\"\n" #~ "colocation website-with-ip inf: WebSite ClusterIP\n" #~ "order apache-after-ip inf: ClusterIP WebSite\n" #~ "property $id=\"cib-bootstrap-options\" \\\n" #~ "        dc-version=\"1.0.5-462f1569a43740667daf7b0f6b521742e9eb8fa7\" \\\n" #~ "        cluster-infrastructure=\"openais\" \\\n" #~ "        expected-quorum-votes=\"2\" \\\n" #~ "        stonith-enabled=\"false\" \\\n" #~ "        no-quorum-policy=\"ignore\"\n" #~ "rsc_defaults $id=\"rsc-options\" \\\n" #~ "        resource-stickiness=\"100\"\n" #~ msgstr "" #~ "\n" #~ "[root@pcmk-1 ~]# crm configure order apache-after-ip mandatory: ClusterIP WebSite\n" #~ "[root@pcmk-1 ~]# crm configure show\n" #~ "node pcmk-1\n" #~ "node pcmk-2\n" #~ "primitive WebSite ocf:heartbeat:apache \\\n" #~ "        params configfile=\"/etc/httpd/conf/httpd.conf\" \\\n" #~ "        op monitor interval=\"1min\"\n" #~ "primitive ClusterIP ocf:heartbeat:IPaddr2 \\\n" #~ "        params ip=\"192.168.122.101\" cidr_netmask=\"32\" \\\n" #~ "        op monitor interval=\"30s\"\n" #~ "colocation website-with-ip inf: WebSite ClusterIP\n" #~ "order apache-after-ip inf: ClusterIP WebSite\n" #~ "property $id=\"cib-bootstrap-options\" \\\n" #~ "        dc-version=\"1.0.5-462f1569a43740667daf7b0f6b521742e9eb8fa7\" \\\n" #~ "        cluster-infrastructure=\"openais\" \\\n" #~ "        expected-quorum-votes=\"2\" \\\n" #~ "        stonith-enabled=\"false\" \\\n" #~ "        no-quorum-policy=\"ignore\"\n" #~ "rsc_defaults $id=\"rsc-options\" \\\n" #~ "        resource-stickiness=\"100\"\n" #~ msgid "" #~ "\n" #~ "[root@pcmk-1 ~]# crm configure location prefer-pcmk-1 WebSite 50: pcmk-1\n" #~ "[root@pcmk-1 ~]# crm configure show\n" #~ "node pcmk-1\n" #~ "node pcmk-2\n" #~ "primitive WebSite ocf:heartbeat:apache \\\n" #~ "        params configfile=\"/etc/httpd/conf/httpd.conf\" \\\n" #~ "        op monitor interval=\"1min\"\n" #~ "primitive ClusterIP ocf:heartbeat:IPaddr2 \\\n" #~ "        params ip=\"192.168.122.101\" cidr_netmask=\"32\" \\\n" #~ "        op monitor interval=\"30s\"\n" #~ "location prefer-pcmk-1 WebSite 50: pcmk-1\n" #~ "colocation website-with-ip inf: WebSite ClusterIP\n" #~ "property $id=\"cib-bootstrap-options\" \\\n" #~ "        dc-version=\"1.0.5-462f1569a43740667daf7b0f6b521742e9eb8fa7\" \\\n" #~ "        cluster-infrastructure=\"openais\" \\\n" #~ "        expected-quorum-votes=\"2\" \\\n" #~ "        stonith-enabled=\"false\" \\\n" #~ "        no-quorum-policy=\"ignore\"\n" #~ "rsc_defaults $id=\"rsc-options\" \\\n" #~ "        resource-stickiness=\"100\"\n" #~ "[root@pcmk-1 ~]# crm_mon\n" #~ "============\n" #~ "Last updated: Fri Aug 28 16:17:35 2009\n" #~ "Stack: openais\n" #~ "Current DC: pcmk-2 - partition with quorum\n" #~ "Version: 1.0.5-462f1569a43740667daf7b0f6b521742e9eb8fa7\n" #~ "2 Nodes configured, 2 expected votes\n" #~ "2 Resources configured.\n" #~ "============\n" #~ "\n" #~ "Online: [ pcmk-1 pcmk-2 ]\n" #~ "\n" #~ "ClusterIP        (ocf::heartbeat:IPaddr):        Started pcmk-2\n" #~ "WebSite        (ocf::heartbeat:apache):        Started pcmk-2\n" #~ msgstr "" #~ "\n" #~ "[root@pcmk-1 ~]# crm configure location prefer-pcmk-1 WebSite 50: pcmk-1\n" #~ "[root@pcmk-1 ~]# crm configure show\n" #~ "node pcmk-1\n" #~ "node pcmk-2\n" #~ "primitive WebSite ocf:heartbeat:apache \\\n" #~ "        params configfile=\"/etc/httpd/conf/httpd.conf\" \\\n" #~ "        op monitor interval=\"1min\"\n" #~ "primitive ClusterIP ocf:heartbeat:IPaddr2 \\\n" #~ "        params ip=\"192.168.122.101\" cidr_netmask=\"32\" \\\n" #~ "        op monitor interval=\"30s\"\n" #~ "location prefer-pcmk-1 WebSite 50: pcmk-1\n" #~ "colocation website-with-ip inf: WebSite ClusterIP\n" #~ "property $id=\"cib-bootstrap-options\" \\\n" #~ "        dc-version=\"1.0.5-462f1569a43740667daf7b0f6b521742e9eb8fa7\" \\\n" #~ "        cluster-infrastructure=\"openais\" \\\n" #~ "        expected-quorum-votes=\"2\" \\\n" #~ "        stonith-enabled=\"false\" \\\n" #~ "        no-quorum-policy=\"ignore\"\n" #~ "rsc_defaults $id=\"rsc-options\" \\\n" #~ "        resource-stickiness=\"100\"\n" #~ "[root@pcmk-1 ~]# crm_mon\n" #~ "============\n" #~ "Last updated: Fri Aug 28 16:17:35 2009\n" #~ "Stack: openais\n" #~ "Current DC: pcmk-2 - partition with quorum\n" #~ "Version: 1.0.5-462f1569a43740667daf7b0f6b521742e9eb8fa7\n" #~ "2 Nodes configured, 2 expected votes\n" #~ "2 Resources configured.\n" #~ "============\n" #~ "\n" #~ "Online: [ pcmk-1 pcmk-2 ]\n" #~ "\n" #~ "ClusterIP        (ocf::heartbeat:IPaddr):        Started pcmk-2\n" #~ "WebSite        (ocf::heartbeat:apache):        Started pcmk-2\n" #~ msgid "ptest -sL" #~ msgstr "ptest -sL" #~ msgid "Include output" #~ msgstr "Include output" #~ msgid "There is a way to force them to move though..." #~ msgstr "这里有个办法强制地移动资源" #~ msgid "" #~ "\n" #~ "[root@pcmk-1 ~]# crm resource move WebSite pcmk-1\n" #~ "[root@pcmk-1 ~]# crm_mon\n" #~ "============\n" #~ "Last updated: Fri Aug 28 16:19:24 2009\n" #~ "Stack: openais\n" #~ "Current DC: pcmk-2 - partition with quorum\n" #~ "Version: 1.0.5-462f1569a43740667daf7b0f6b521742e9eb8fa7\n" #~ "2 Nodes configured, 2 expected votes\n" #~ "2 Resources configured.\n" #~ "============\n" #~ "\n" #~ "Online: [ pcmk-1 pcmk-2 ]\n" #~ "\n" #~ "ClusterIP        (ocf::heartbeat:IPaddr):        Started pcmk-1\n" #~ "WebSite        (ocf::heartbeat:apache):        Started pcmk-1\n" #~ "Notice how the colocation rule we created has ensured that ClusterIP was also moved to pcmk-1.\n" #~ "For the curious, we can see the effect of this command by examining the configuration\n" #~ "crm configure show\n" #~ "[root@pcmk-1 ~]# crm configure show\n" #~ "node pcmk-1\n" #~ "node pcmk-2\n" #~ "primitive WebSite ocf:heartbeat:apache \\\n" #~ "        params configfile=\"/etc/httpd/conf/httpd.conf\" \\\n" #~ "        op monitor interval=\"1min\"\n" #~ "primitive ClusterIP ocf:heartbeat:IPaddr2 \\\n" #~ "        params ip=\"192.168.122.101\" cidr_netmask=\"32\" \\\n" #~ "        op monitor interval=\"30s\"\n" #~ "location cli-prefer-WebSite WebSite \\\n" #~ " rule $id=\"cli-prefer-rule-WebSite\" inf: #uname eq pcmk-1\n" #~ "location prefer-pcmk-1 WebSite 50: pcmk-1\n" #~ "colocation website-with-ip inf: WebSite ClusterIP\n" #~ "property $id=\"cib-bootstrap-options\" \\\n" #~ "        dc-version=\"1.0.5-462f1569a43740667daf7b0f6b521742e9eb8fa7\" \\\n" #~ "        cluster-infrastructure=\"openais\" \\\n" #~ "        expected-quorum-votes=\"2\" \\\n" #~ "        stonith-enabled=\"false\" \\\n" #~ "        no-quorum-policy=\"ignore\"\n" #~ "rsc_defaults $id=\"rsc-options\" \\\n" #~ "        resource-stickiness=\"100\"\n" #~ msgstr "" #~ "\n" #~ "[root@pcmk-1 ~]# crm resource move WebSite pcmk-1\n" #~ "[root@pcmk-1 ~]# crm_mon\n" #~ "============\n" #~ "Last updated: Fri Aug 28 16:19:24 2009\n" #~ "Stack: openais\n" #~ "Current DC: pcmk-2 - partition with quorum\n" #~ "Version: 1.0.5-462f1569a43740667daf7b0f6b521742e9eb8fa7\n" #~ "2 Nodes configured, 2 expected votes\n" #~ "2 Resources configured.\n" #~ "============\n" #~ "\n" #~ "Online: [ pcmk-1 pcmk-2 ]\n" #~ "\n" #~ "ClusterIP        (ocf::heartbeat:IPaddr):        Started pcmk-1\n" #~ "WebSite        (ocf::heartbeat:apache):        Started pcmk-1\n" #~ "Notice how the colocation rule we created has ensured that ClusterIP was also moved to pcmk-1.\n" #~ "For the curious, we can see the effect of this command by examining the configuration\n" #~ "crm configure show\n" #~ "[root@pcmk-1 ~]# crm configure show\n" #~ "node pcmk-1\n" #~ "node pcmk-2\n" #~ "primitive WebSite ocf:heartbeat:apache \\\n" #~ "        params configfile=\"/etc/httpd/conf/httpd.conf\" \\\n" #~ "        op monitor interval=\"1min\"\n" #~ "primitive ClusterIP ocf:heartbeat:IPaddr2 \\\n" #~ "        params ip=\"192.168.122.101\" cidr_netmask=\"32\" \\\n" #~ "        op monitor interval=\"30s\"\n" #~ "location cli-prefer-WebSite WebSite \\\n" #~ " rule $id=\"cli-prefer-rule-WebSite\" inf: #uname eq pcmk-1\n" #~ "location prefer-pcmk-1 WebSite 50: pcmk-1\n" #~ "colocation website-with-ip inf: WebSite ClusterIP\n" #~ "property $id=\"cib-bootstrap-options\" \\\n" #~ "        dc-version=\"1.0.5-462f1569a43740667daf7b0f6b521742e9eb8fa7\" \\\n" #~ "        cluster-infrastructure=\"openais\" \\\n" #~ "        expected-quorum-votes=\"2\" \\\n" #~ "        stonith-enabled=\"false\" \\\n" #~ "        no-quorum-policy=\"ignore\"\n" #~ "rsc_defaults $id=\"rsc-options\" \\\n" #~ "        resource-stickiness=\"100\"\n" #~ msgid "Highlighted is the automated constraint used to move the resources to pcmk-1" #~ msgstr "斜体部分是用来移动资源到pcmk-1约束,它是自动生成的。" #~ msgid "" #~ "\n" #~ "[root@pcmk-1 ~]# crm resource unmove WebSite\n" #~ "[root@pcmk-1 ~]# crm configure show\n" #~ "node pcmk-1\n" #~ "node pcmk-2\n" #~ "primitive WebSite ocf:heartbeat:apache \\\n" #~ "        params configfile=\"/etc/httpd/conf/httpd.conf\" \\\n" #~ "        op monitor interval=\"1min\"\n" #~ "primitive ClusterIP ocf:heartbeat:IPaddr2 \\\n" #~ "        params ip=\"192.168.122.101\" cidr_netmask=\"32\" \\\n" #~ "        op monitor interval=\"30s\"\n" #~ "location prefer-pcmk-1 WebSite 50: pcmk-1\n" #~ "colocation website-with-ip inf: WebSite ClusterIP\n" #~ "property $id=\"cib-bootstrap-options\" \\\n" #~ "        dc-version=\"1.0.5-462f1569a43740667daf7b0f6b521742e9eb8fa7\" \\\n" #~ "        cluster-infrastructure=\"openais\" \\\n" #~ "        expected-quorum-votes=\"2\" \\\n" #~ "        stonith-enabled=\"false\" \\\n" #~ "        no-quorum-policy=\"ignore\"\n" #~ "rsc_defaults $id=\"rsc-options\" \\\n" #~ "        resource-stickiness=\"100\"\n" #~ msgstr "" #~ "\n" #~ "[root@pcmk-1 ~]# crm resource unmove WebSite\n" #~ "[root@pcmk-1 ~]# crm configure show\n" #~ "node pcmk-1\n" #~ "node pcmk-2\n" #~ "primitive WebSite ocf:heartbeat:apache \\\n" #~ "        params configfile=\"/etc/httpd/conf/httpd.conf\" \\\n" #~ "        op monitor interval=\"1min\"\n" #~ "primitive ClusterIP ocf:heartbeat:IPaddr2 \\\n" #~ "        params ip=\"192.168.122.101\" cidr_netmask=\"32\" \\\n" #~ "        op monitor interval=\"30s\"\n" #~ "location prefer-pcmk-1 WebSite 50: pcmk-1\n" #~ "colocation website-with-ip inf: WebSite ClusterIP\n" #~ "property $id=\"cib-bootstrap-options\" \\\n" #~ "        dc-version=\"1.0.5-462f1569a43740667daf7b0f6b521742e9eb8fa7\" \\\n" #~ "        cluster-infrastructure=\"openais\" \\\n" #~ "        expected-quorum-votes=\"2\" \\\n" #~ "        stonith-enabled=\"false\" \\\n" #~ "        no-quorum-policy=\"ignore\"\n" #~ "rsc_defaults $id=\"rsc-options\" \\\n" #~ "        resource-stickiness=\"100\"\n" #~ msgid "" #~ "\n" #~ "[root@pcmk-1 ~]# crm_mon\n" #~ "============\n" #~ "Last updated: Fri Aug 28 16:20:53 2009\n" #~ "Stack: openais\n" #~ "Current DC: pcmk-2 - partition with quorum\n" #~ "Version: 1.0.5-462f1569a43740667daf7b0f6b521742e9eb8fa7\n" #~ "2 Nodes configured, 2 expected votes\n" #~ "2 Resources configured.\n" #~ "============\n" #~ "\n" #~ "Online: [ pcmk-1 pcmk-2 ]\n" #~ "\n" #~ " ClusterIP        (ocf::heartbeat:IPaddr):        Started pcmk-1\n" #~ " WebSite        (ocf::heartbeat:apache):        Started pcmk-1\n" #~ msgstr "" #~ "\n" #~ "[root@pcmk-1 ~]# crm_mon\n" #~ "============\n" #~ "Last updated: Fri Aug 28 16:20:53 2009\n" #~ "Stack: openais\n" #~ "Current DC: pcmk-2 - partition with quorum\n" #~ "Version: 1.0.5-462f1569a43740667daf7b0f6b521742e9eb8fa7\n" #~ "2 Nodes configured, 2 expected votes\n" #~ "2 Resources configured.\n" #~ "============\n" #~ "\n" #~ "Online: [ pcmk-1 pcmk-2 ]\n" #~ "\n" #~ " ClusterIP        (ocf::heartbeat:IPaddr):        Started pcmk-1\n" #~ " WebSite        (ocf::heartbeat:apache):        Started pcmk-1\n" #~ msgid "At this point, Apache is ready to go, all that needs to be done is to add it to the cluster. Lets call the resource WebSite. We need to use an OCF script called apache in the heartbeat namespace" #~ msgstr "现在 ,Apache已经可以添加到集群中了。我们管这个资源叫WebSite。我们需要用一个叫做apache的OCF脚本" #~ msgid "Compare the key used here ocf:heartbeat:apache with the one we used earlier for the IP address: ocf:heartbeat:IPaddr2" #~ msgstr "把我现在所用的关键字ocf:heartbeat:apache 跟之前IP地址所用的比较一下: ocf:heartbeat:IPaddr2" #~ msgid ", the only required parameter is the path to the main Apache configuration file and we’ll tell the cluster to check once a minute that apache is still running." #~ msgstr ",这个脚本在heartbeat这个名字空间里,唯一一个需要设定的参数就是Apache的主配置文件路径,并且我们告诉集群每一分钟检测一次apache是否运行。" pacemaker-master/doc/Clusters_from_Scratch/zh-CN/Ch-Installation.mo000066400000000000000000002115301217637305600256230ustar00rootroot00000000000000x( )  Q T:v# %N 2o2C33}4yd667g78="@"ccfgg]Qimi(kFlrZlnNUop2q Pq^q8sq:q%q r,sCst)t u+=u0iu*u,u#u*v Avbv+v'v vv1w%Gwmw&w0w7wHxGdxcx?yNPyFy y'zQ/z'z$zcz2{)F{dp{Y{/|}}:~jW~ ~&~~q>0aCY9ZQMC4bPӉىpM[\NLU$m!=0_g~|ZVh Q'TyvΫ EN_'y7"a^ 9n 9GSZ}D,[q %? $`0J{$<[{!5Wt# )480Si(93 Tr9Z [)hTN6]nZ'!OuU7-S(1F DY M   s W   >! ` g jz M H36|'y@Bd@=~~ZAW&6YnPI4GN( OwhS\1)$`j9/KeRUt;s M v,DB3>LaX o:.5E7qp^Zki2!? H'-u+#lr8cm=x%fg<[CJ*F _0]Vb"@dTQ grep pcmk /etc/hosts [root@pcmk-1 ~]# grep pcmk /etc/hosts 192.168.122.101 pcmk-1.clusterlabs.org pcmk-1 192.168.122.102 pcmk-2.clusterlabs.org pcmk-2 ping -c 3 192.168.122.102 [root@pcmk-1 ~]# ping -c 3 192.168.122.102 PING 192.168.122.102 (192.168.122.102) 56(84) bytes of data. 64 bytes from 192.168.122.102: icmp_seq=1 ttl=64 time=0.343 ms 64 bytes from 192.168.122.102: icmp_seq=2 ttl=64 time=0.402 ms 64 bytes from 192.168.122.102: icmp_seq=3 ttl=64 time=0.558 ms --- 192.168.122.102 ping statistics --- 3 packets transmitted, 3 received, 0% packet loss, time 2000ms rtt min/avg/max/mdev = 0.343/0.434/0.558/0.092 ms ping -c 3 pcmk-2 [root@pcmk-1 ~]# ping -c 3 pcmk-2 PING pcmk-2.clusterlabs.org (192.168.122.101) 56(84) bytes of data. 64 bytes from pcmk-1.clusterlabs.org (192.168.122.101): icmp_seq=1 ttl=64 time=0.164 ms 64 bytes from pcmk-1.clusterlabs.org (192.168.122.101): icmp_seq=2 ttl=64 time=0.475 ms 64 bytes from pcmk-1.clusterlabs.org (192.168.122.101): icmp_seq=3 ttl=64 time=0.186 ms --- pcmk-2.clusterlabs.org ping statistics --- 3 packets transmitted, 3 received, 0% packet loss, time 2001ms rtt min/avg/max/mdev = 0.164/0.275/0.475/0.141 ms ========================================================================================== Package Arch Version Repository Size ========================================================================================== Installing: corosync x86_64 1.2.1-1.fc13 fedora 136 k pacemaker x86_64 1.1.1-1.fc13 fedora 543 k Installing for dependencies: OpenIPMI-libs x86_64 2.0.16-8.fc13 fedora 474 k PyXML x86_64 0.8.4-17.fc13 fedora 906 k cluster-glue x86_64 1.0.2-1.fc13 fedora 230 k cluster-glue-libs x86_64 1.0.2-1.fc13 fedora 116 k corosynclib x86_64 1.2.1-1.fc13 fedora 145 k heartbeat x86_64 3.0.0-0.7.0daab7da36a8.hg.fc13 updates 172 k heartbeat-libs x86_64 3.0.0-0.7.0daab7da36a8.hg.fc13 updates 265 k libesmtp x86_64 1.0.4-12.fc12 fedora 54 k libibverbs x86_64 1.1.3-4.fc13 fedora 42 k libmlx4 x86_64 1.0.1-5.fc13 fedora 27 k libnet x86_64 1.1.4-3.fc12 fedora 49 k librdmacm x86_64 1.0.10-2.fc13 fedora 22 k lm_sensors-libs x86_64 3.1.2-2.fc13 fedora 37 k net-snmp x86_64 1:5.5-12.fc13 fedora 295 k net-snmp-libs x86_64 1:5.5-12.fc13 fedora 1.5 M openhpi-libs x86_64 2.14.1-3.fc13 fedora 135 k pacemaker-libs x86_64 1.1.1-1.fc13 fedora 264 k perl-TimeDate noarch 1:1.20-1.fc13 fedora 42 k resource-agents x86_64 3.0.10-1.fc13 fedora 357 k Transaction Summary ========================================================================================= Install 21 Package(s) Upgrade 0 Package(s) Total download size: 5.7 M Installed size: 20 M Downloading Packages: Setting up and reading Presto delta metadata updates-testing/prestodelta | 164 kB 00:00 fedora/prestodelta | 150 B 00:00 Processing delta metadata Package(s) data still to download: 5.7 M (1/21): OpenIPMI-libs-2.0.16-8.fc13.x86_64.rpm | 474 kB 00:00 (2/21): PyXML-0.8.4-17.fc13.x86_64.rpm | 906 kB 00:01 (3/21): cluster-glue-1.0.2-1.fc13.x86_64.rpm | 230 kB 00:00 (4/21): cluster-glue-libs-1.0.2-1.fc13.x86_64.rpm | 116 kB 00:00 (5/21): corosync-1.2.1-1.fc13.x86_64.rpm | 136 kB 00:00 (6/21): corosynclib-1.2.1-1.fc13.x86_64.rpm | 145 kB 00:00 (7/21): heartbeat-3.0.0-0.7.0daab7da36a8.hg.fc13.x86_64.rpm | 172 kB 00:00 (8/21): heartbeat-libs-3.0.0-0.7.0daab7da36a8.hg.fc13.x86_64.rpm | 265 kB 00:00 (9/21): libesmtp-1.0.4-12.fc12.x86_64.rpm | 54 kB 00:00 (10/21): libibverbs-1.1.3-4.fc13.x86_64.rpm | 42 kB 00:00 (11/21): libmlx4-1.0.1-5.fc13.x86_64.rpm | 27 kB 00:00 (12/21): libnet-1.1.4-3.fc12.x86_64.rpm | 49 kB 00:00 (13/21): librdmacm-1.0.10-2.fc13.x86_64.rpm | 22 kB 00:00 (14/21): lm_sensors-libs-3.1.2-2.fc13.x86_64.rpm | 37 kB 00:00 (15/21): net-snmp-5.5-12.fc13.x86_64.rpm | 295 kB 00:00 (16/21): net-snmp-libs-5.5-12.fc13.x86_64.rpm | 1.5 MB 00:01 (17/21): openhpi-libs-2.14.1-3.fc13.x86_64.rpm | 135 kB 00:00 (18/21): pacemaker-1.1.1-1.fc13.x86_64.rpm | 543 kB 00:00 (19/21): pacemaker-libs-1.1.1-1.fc13.x86_64.rpm | 264 kB 00:00 (20/21): perl-TimeDate-1.20-1.fc13.noarch.rpm | 42 kB 00:00 (21/21): resource-agents-3.0.10-1.fc13.x86_64.rpm | 357 kB 00:00 ---------------------------------------------------------------------------------------- Total 539 kB/s | 5.7 MB 00:10 warning: rpmts_HdrFromFdno: Header V3 RSA/SHA256 Signature, key ID e8e40fde: NOKEY fedora/gpgkey | 3.2 kB 00:00 ... Importing GPG key 0xE8E40FDE "Fedora (13) <fedora@fedoraproject.org%gt;" from /etc/pki/rpm-gpg/RPM-GPG-KEY-fedora-x86_64 May 4 19:30:54 pcmk-1 setroubleshoot: SELinux is preventing /usr/sbin/corosync "getattr" access on /. For complete SELinux messages. run sealert -l 6e0d4384-638e-4d55-9aaf-7dac011f29c1 May 4 19:30:54 pcmk-1 setroubleshoot: SELinux is preventing /usr/sbin/corosync "getattr" access on /. For complete SELinux messages. run sealert -l 6e0d4384-638e-4d55-9aaf-7dac011f29c1 Running rpm_check_debug Running Transaction Test Transaction Test Succeeded Running Transaction Installing : lm_sensors-libs-3.1.2-2.fc13.x86_64 1/21 Installing : 1:net-snmp-libs-5.5-12.fc13.x86_64 2/21 Installing : 1:net-snmp-5.5-12.fc13.x86_64 3/21 Installing : openhpi-libs-2.14.1-3.fc13.x86_64 4/21 Installing : libibverbs-1.1.3-4.fc13.x86_64 5/21 Installing : libmlx4-1.0.1-5.fc13.x86_64 6/21 Installing : librdmacm-1.0.10-2.fc13.x86_64 7/21 Installing : corosync-1.2.1-1.fc13.x86_64 8/21 Installing : corosynclib-1.2.1-1.fc13.x86_64 9/21 Installing : libesmtp-1.0.4-12.fc12.x86_64 10/21 Installing : OpenIPMI-libs-2.0.16-8.fc13.x86_64 11/21 Installing : PyXML-0.8.4-17.fc13.x86_64 12/21 Installing : libnet-1.1.4-3.fc12.x86_64 13/21 Installing : 1:perl-TimeDate-1.20-1.fc13.noarch 14/21 Installing : cluster-glue-1.0.2-1.fc13.x86_64 15/21 Installing : cluster-glue-libs-1.0.2-1.fc13.x86_64 16/21 Installing : resource-agents-3.0.10-1.fc13.x86_64 17/21 Installing : heartbeat-libs-3.0.0-0.7.0daab7da36a8.hg.fc13.x86_64 18/21 Installing : heartbeat-3.0.0-0.7.0daab7da36a8.hg.fc13.x86_64 19/21 Installing : pacemaker-1.1.1-1.fc13.x86_64 20/21 Installing : pacemaker-libs-1.1.1-1.fc13.x86_64 21/21 Installed: corosync.x86_64 0:1.2.1-1.fc13 pacemaker.x86_64 0:1.1.1-1.fc13 Dependency Installed: OpenIPMI-libs.x86_64 0:2.0.16-8.fc13 PyXML.x86_64 0:0.8.4-17.fc13 cluster-glue.x86_64 0:1.0.2-1.fc13 cluster-glue-libs.x86_64 0:1.0.2-1.fc13 corosynclib.x86_64 0:1.2.1-1.fc13 heartbeat.x86_64 0:3.0.0-0.7.0daab7da36a8.hg.fc13 heartbeat-libs.x86_64 0:3.0.0-0.7.0daab7da36a8.hg.fc13 libesmtp.x86_64 0:1.0.4-12.fc12 libibverbs.x86_64 0:1.1.3-4.fc13 libmlx4.x86_64 0:1.0.1-5.fc13 libnet.x86_64 0:1.1.4-3.fc12 librdmacm.x86_64 0:1.0.10-2.fc13 lm_sensors-libs.x86_64 0:3.1.2-2.fc13 net-snmp.x86_64 1:5.5-12.fc13 net-snmp-libs.x86_64 1:5.5-12.fc13 openhpi-libs.x86_64 0:2.14.1-3.fc13 pacemaker-libs.x86_64 0:1.1.1-1.fc13 perl-TimeDate.noarch 1:1.20-1.fc13 resource-agents.x86_64 0:3.0.10-1.fc13 Complete! [root@pcmk-1 ~]# [beekhof@pcmk-1 ~]$ su - Password: [root@pcmk-1 ~]# [root@pcmk-1 ~]# cat <<-END >>/etc/corosync/service.d/pcmk service { # Load the Pacemaker Cluster Resource Manager name: pacemaker ver: 0 } END [root@pcmk-1 ~]# cat /etc/sysconfig/network NETWORKING=yes HOSTNAME=pcmk-1.clusterlabs.org GATEWAY=192.168.122.1 [root@pcmk-1 ~]# cat /etc/sysconfig/network NETWORKING=yes HOSTNAME=pcmk-1 GATEWAY=192.168.122.1 [root@pcmk-1 ~]# cp /etc/corosync/corosync.conf.example /etc/corosync/corosync.conf [root@pcmk-1 ~]# sed -i.bak "s/.*mcastaddr:.*/mcastaddr:\ $ais_mcast/g" /etc/corosync/corosync.conf [root@pcmk-1 ~]# sed -i.bak "s/.*mcastport:.*/mcastport:\ $ais_port/g" /etc/corosync/corosync.conf [root@pcmk-1 ~]# sed -i.bak "s/.*bindnetaddr:.*/bindnetaddr:\ $ais_addr/g" /etc/corosync/corosync.conf [root@pcmk-1 ~]# env | grep ais_ ais_mcast=226.94.1.1 ais_port=4000 ais_addr=192.168.122.0 [root@pcmk-1 ~]# export ais_port=4000 [root@pcmk-1 ~]# export ais_mcast=226.94.1.1 [root@pcmk-1 ~]# for f in /etc/corosync/corosync.conf /etc/corosync/service.d/pcmk /etc/hosts; do scp $f pcmk-2:$f ; done corosync.conf 100% 1528 1.5KB/s 00:00 hosts 100% 281 0.3KB/s 00:00 [root@pcmk-1 ~]# [root@pcmk-1 ~]# ip addr 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 16436 qdisc noqueue state UNKNOWN link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo inet6 ::1/128 scope host valid_lft forever preferred_lft forever 2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UNKNOWN qlen 1000 link/ether 00:0c:29:6f:e1:58 brd ff:ff:ff:ff:ff:ff inet 192.168.9.41/24 brd 192.168.9.255 scope global eth0 inet6 ::20c:29ff:fe6f:e158/64 scope global dynamic valid_lft 2591667sec preferred_lft 604467sec inet6 2002:57ae:43fc:0:20c:29ff:fe6f:e158/64 scope global dynamic valid_lft 2591990sec preferred_lft 604790sec inet6 fe80::20c:29ff:fe6f:e158/64 scope link valid_lft forever preferred_lft forever [root@pcmk-1 ~]# ping -c 1 www.google.com PING www.l.google.com (74.125.39.99) 56(84) bytes of data. 64 bytes from fx-in-f99.1e100.net (74.125.39.99): icmp_seq=1 ttl=56 time=16.7 ms --- www.l.google.com ping statistics --- 1 packets transmitted, 1 received, 0% packet loss, time 20ms rtt min/avg/max/mdev = 16.713/16.713/16.713/0.000 ms [root@pcmk-1 ~]# /sbin/chkconfig network on [root@pcmk-1 ~]# [root@pcmk-1 ~]# scp -r .ssh pcmk-2: The authenticity of host 'pcmk-2 (192.168.122.102)' can't be established. RSA key fingerprint is b1:2b:55:93:f1:d9:52:2b:0f:f2:8a:4e:ae:c6:7c:9a. Are you sure you want to continue connecting (yes/no)? yes Warning: Permanently added 'pcmk-2,192.168.122.102' (RSA) to the list of known hosts. root@pcmk-2's password: id_dsa.pub 100% 616 0.6KB/s 00:00 id_dsa 100% 672 0.7KB/s 00:00 known_hosts 100% 400 0.4KB/s 00:00 authorized_keys 100% 616 0.6KB/s 00:00 [root@pcmk-1 ~]# ssh pcmk-2 -- uname -n pcmk-2 [root@pcmk-1 ~]# [root@pcmk-1 ~]# sed -i.bak "s/enabled=0/enabled=1/g" /etc/yum.repos.d/fedora.repo [root@pcmk-1 ~]# sed -i.bak "s/enabled=0/enabled=1/g" /etc/yum.repos.d/fedora-updates.repo [root@pcmk-1 ~]# yum install -y pacemaker corosync Loaded plugins: presto, refresh-packagekit fedora/metalink | 22 kB 00:00 fedora-debuginfo/metalink | 16 kB 00:00 fedora-debuginfo | 3.2 kB 00:00 fedora-debuginfo/primary_db | 1.4 MB 00:04 fedora-source/metalink | 22 kB 00:00 fedora-source | 3.2 kB 00:00 fedora-source/primary_db | 3.0 MB 00:05 updates/metalink | 26 kB 00:00 updates | 2.6 kB 00:00 updates/primary_db | 1.1 kB 00:00 updates-debuginfo/metalink | 18 kB 00:00 updates-debuginfo | 2.6 kB 00:00 updates-debuginfo/primary_db | 1.1 kB 00:00 updates-source/metalink | 25 kB 00:00 updates-source | 2.6 kB 00:00 updates-source/primary_db | 1.1 kB 00:00 Setting up Install Process Resolving Dependencies --> Running transaction check ---> Package corosync.x86_64 0:1.2.1-1.fc13 set to be updated --> Processing Dependency: corosynclib = 1.2.1-1.fc13 for package: corosync-1.2.1-1.fc13.x86_64 --> Processing Dependency: libquorum.so.4(COROSYNC_QUORUM_1.0)(64bit) for package: corosync-1.2.1-1.fc13.x86_64 --> Processing Dependency: libvotequorum.so.4(COROSYNC_VOTEQUORUM_1.0)(64bit) for package: corosync-1.2.1-1.fc13.x86_64 --> Processing Dependency: libcpg.so.4(COROSYNC_CPG_1.0)(64bit) for package: corosync-1.2.1-1.fc13.x86_64 --> Processing Dependency: libconfdb.so.4(COROSYNC_CONFDB_1.0)(64bit) for package: corosync-1.2.1-1.fc13.x86_64 --> Processing Dependency: libcfg.so.4(COROSYNC_CFG_0.82)(64bit) for package: corosync-1.2.1-1.fc13.x86_64 --> Processing Dependency: libpload.so.4(COROSYNC_PLOAD_1.0)(64bit) for package: corosync-1.2.1-1.fc13.x86_64 --> Processing Dependency: liblogsys.so.4()(64bit) for package: corosync-1.2.1-1.fc13.x86_64 --> Processing Dependency: libconfdb.so.4()(64bit) for package: corosync-1.2.1-1.fc13.x86_64 --> Processing Dependency: libcoroipcc.so.4()(64bit) for package: corosync-1.2.1-1.fc13.x86_64 --> Processing Dependency: libcpg.so.4()(64bit) for package: corosync-1.2.1-1.fc13.x86_64 --> Processing Dependency: libquorum.so.4()(64bit) for package: corosync-1.2.1-1.fc13.x86_64 --> Processing Dependency: libcoroipcs.so.4()(64bit) for package: corosync-1.2.1-1.fc13.x86_64 --> Processing Dependency: libvotequorum.so.4()(64bit) for package: corosync-1.2.1-1.fc13.x86_64 --> Processing Dependency: libcfg.so.4()(64bit) for package: corosync-1.2.1-1.fc13.x86_64 --> Processing Dependency: libtotem_pg.so.4()(64bit) for package: corosync-1.2.1-1.fc13.x86_64 --> Processing Dependency: libpload.so.4()(64bit) for package: corosync-1.2.1-1.fc13.x86_64 ---> Package pacemaker.x86_64 0:1.1.1-1.fc13 set to be updated --> Processing Dependency: heartbeat >= 3.0.0 for package: pacemaker-1.1.1-1.fc13.x86_64 --> Processing Dependency: net-snmp >= 5.4 for package: pacemaker-1.1.1-1.fc13.x86_64 --> Processing Dependency: resource-agents for package: pacemaker-1.1.1-1.fc13.x86_64 --> Processing Dependency: cluster-glue for package: pacemaker-1.1.1-1.fc13.x86_64 --> Processing Dependency: libnetsnmp.so.20()(64bit) for package: pacemaker-1.1.1-1.fc13.x86_64 --> Processing Dependency: libcrmcluster.so.1()(64bit) for package: pacemaker-1.1.1-1.fc13.x86_64 --> Processing Dependency: libpengine.so.3()(64bit) for package: pacemaker-1.1.1-1.fc13.x86_64 --> Processing Dependency: libnetsnmpagent.so.20()(64bit) for package: pacemaker-1.1.1-1.fc13.x86_64 --> Processing Dependency: libesmtp.so.5()(64bit) for package: pacemaker-1.1.1-1.fc13.x86_64 --> Processing Dependency: libstonithd.so.1()(64bit) for package: pacemaker-1.1.1-1.fc13.x86_64 --> Processing Dependency: libhbclient.so.1()(64bit) for package: pacemaker-1.1.1-1.fc13.x86_64 --> Processing Dependency: libpils.so.2()(64bit) for package: pacemaker-1.1.1-1.fc13.x86_64 --> Processing Dependency: libpe_status.so.2()(64bit) for package: pacemaker-1.1.1-1.fc13.x86_64 --> Processing Dependency: libnetsnmpmibs.so.20()(64bit) for package: pacemaker-1.1.1-1.fc13.x86_64 --> Processing Dependency: libnetsnmphelpers.so.20()(64bit) for package: pacemaker-1.1.1-1.fc13.x86_64 --> Processing Dependency: libcib.so.1()(64bit) for package: pacemaker-1.1.1-1.fc13.x86_64 --> Processing Dependency: libccmclient.so.1()(64bit) for package: pacemaker-1.1.1-1.fc13.x86_64 --> Processing Dependency: libstonith.so.1()(64bit) for package: pacemaker-1.1.1-1.fc13.x86_64 --> Processing Dependency: liblrm.so.2()(64bit) for package: pacemaker-1.1.1-1.fc13.x86_64 --> Processing Dependency: libtransitioner.so.1()(64bit) for package: pacemaker-1.1.1-1.fc13.x86_64 --> Processing Dependency: libpe_rules.so.2()(64bit) for package: pacemaker-1.1.1-1.fc13.x86_64 --> Processing Dependency: libcrmcommon.so.2()(64bit) for package: pacemaker-1.1.1-1.fc13.x86_64 --> Processing Dependency: libplumb.so.2()(64bit) for package: pacemaker-1.1.1-1.fc13.x86_64 --> Running transaction check ---> Package cluster-glue.x86_64 0:1.0.2-1.fc13 set to be updated --> Processing Dependency: perl-TimeDate for package: cluster-glue-1.0.2-1.fc13.x86_64 --> Processing Dependency: libOpenIPMIutils.so.0()(64bit) for package: cluster-glue-1.0.2-1.fc13.x86_64 --> Processing Dependency: libOpenIPMIposix.so.0()(64bit) for package: cluster-glue-1.0.2-1.fc13.x86_64 --> Processing Dependency: libopenhpi.so.2()(64bit) for package: cluster-glue-1.0.2-1.fc13.x86_64 --> Processing Dependency: libOpenIPMI.so.0()(64bit) for package: cluster-glue-1.0.2-1.fc13.x86_64 ---> Package cluster-glue-libs.x86_64 0:1.0.2-1.fc13 set to be updated ---> Package corosynclib.x86_64 0:1.2.1-1.fc13 set to be updated --> Processing Dependency: librdmacm.so.1(RDMACM_1.0)(64bit) for package: corosynclib-1.2.1-1.fc13.x86_64 --> Processing Dependency: libibverbs.so.1(IBVERBS_1.0)(64bit) for package: corosynclib-1.2.1-1.fc13.x86_64 --> Processing Dependency: libibverbs.so.1(IBVERBS_1.1)(64bit) for package: corosynclib-1.2.1-1.fc13.x86_64 --> Processing Dependency: libibverbs.so.1()(64bit) for package: corosynclib-1.2.1-1.fc13.x86_64 --> Processing Dependency: librdmacm.so.1()(64bit) for package: corosynclib-1.2.1-1.fc13.x86_64 ---> Package heartbeat.x86_64 0:3.0.0-0.7.0daab7da36a8.hg.fc13 set to be updated --> Processing Dependency: PyXML for package: heartbeat-3.0.0-0.7.0daab7da36a8.hg.fc13.x86_64 ---> Package heartbeat-libs.x86_64 0:3.0.0-0.7.0daab7da36a8.hg.fc13 set to be updated ---> Package libesmtp.x86_64 0:1.0.4-12.fc12 set to be updated ---> Package net-snmp.x86_64 1:5.5-12.fc13 set to be updated --> Processing Dependency: libsensors.so.4()(64bit) for package: 1:net-snmp-5.5-12.fc13.x86_64 ---> Package net-snmp-libs.x86_64 1:5.5-12.fc13 set to be updated ---> Package pacemaker-libs.x86_64 0:1.1.1-1.fc13 set to be updated ---> Package resource-agents.x86_64 0:3.0.10-1.fc13 set to be updated --> Processing Dependency: libnet.so.1()(64bit) for package: resource-agents-3.0.10-1.fc13.x86_64 --> Running transaction check ---> Package OpenIPMI-libs.x86_64 0:2.0.16-8.fc13 set to be updated ---> Package PyXML.x86_64 0:0.8.4-17.fc13 set to be updated ---> Package libibverbs.x86_64 0:1.1.3-4.fc13 set to be updated --> Processing Dependency: libibverbs-driver for package: libibverbs-1.1.3-4.fc13.x86_64 ---> Package libnet.x86_64 0:1.1.4-3.fc12 set to be updated ---> Package librdmacm.x86_64 0:1.0.10-2.fc13 set to be updated ---> Package lm_sensors-libs.x86_64 0:3.1.2-2.fc13 set to be updated ---> Package openhpi-libs.x86_64 0:2.14.1-3.fc13 set to be updated ---> Package perl-TimeDate.noarch 1:1.20-1.fc13 set to be updated --> Running transaction check ---> Package libmlx4.x86_64 0:1.0.1-5.fc13 set to be updated --> Finished Dependency Resolution Dependencies Resolved [root@pcmk-1 ~]# source /etc/sysconfig/network [root@pcmk-1 ~]# hostname $HOSTNAME [root@pcmk-1 ~]# ssh-keygen -t dsa -f ~/.ssh/id_dsa -N "" Generating public/private dsa key pair. Your identification has been saved in /root/.ssh/id_dsa. Your public key has been saved in /root/.ssh/id_dsa.pub. The key fingerprint is: 91:09:5c:82:5a:6a:50:08:4e:b2:0c:62:de:cc:74:44 root@pcmk-1.clusterlabs.org The key's randomart image is: +--[ DSA 1024]----+ |==.ooEo.. | |X O + .o o | | * A + | | + . | | . S | | | | | | | | | +-----------------+ [root@pcmk-1 ~]# cp .ssh/id_dsa.pub .ssh/authorized_keys [root@pcmk-1 ~]# [root@pcmk-1 ~]# uname -n pcmk-1 [root@pcmk-1 ~]# dnsdomainname clusterlabs.org [root@pcmk-1 ~]# uname -n pcmk-1.clusterlabs.org [root@pcmk-1 ~]# dnsdomainname clusterlabs.org [root@pcmk-1 ~]# sed -i.bak "s/SELINUX=enforcing/SELINUX=permissive/g" /etc/selinux/config [root@pcmk-1 ~]# /sbin/chkconfig --del iptables [root@pcmk-1 ~]# service iptables stop iptables: Flushing firewall rules: [ OK ] iptables: Setting chains to policy ACCEPT: filter [ OK ] iptables: Unloading modules: [ OK ] All we need to do now is strip off the domain name portion, which is stored elsewhere anyway.Assign your machine a host name. http://docs.fedoraproject.org/install-guide/f&DISTRO_VERSION;/en-US/html/sn-networkconfig-fedora.html I happen to control the clusterlabs.org domain name, so I will use that here.Be sure that the values you chose do not conflict with any existing clusters you might have. For advice on choosing a multi-cast address, see http://www.29west.com/docs/THPM/multicast-address-assignment.html Before You ContinueBurn the disk image to a DVD http://docs.fedoraproject.org/readme-burning-isos/en-US.html and boot from it. Or use the image to boot a virtual machine as I have done here. After clicking through the welcome screen, select your language and keyboard layout http://docs.fedoraproject.org/install-guide/f&DISTRO_VERSION;/en-US/html/s1-langselection-x86.html By default, Fedora will give all the space to the / (aka. root) partition. Wel'll take some back so we can use DRBD.Choose a port number and multi-cast http://en.wikipedia.org/wiki/Multicast address. http://en.wikipedia.org/wiki/Multicast_address Click through the next screens until you reach the login window. Click on the user you created and supply the password you indicated earlier.Cluster Software InstallationConfigure SSHConfiguring CorosyncConfirm that you can communicate with the two new nodes:Create a new key and allow anyone with that key to log in:Creating and Activating a new SSH KeyDetailed instructions for installing Fedora are available at http://docs.fedoraproject.org/install-guide/f&DISTRO_VERSION;/ in a number of languages. The abbreviated version is as follows...Display and verify the configuration optionsDo not accept the default network settings. Cluster machines should never obtain an ip address via DHCP. Here I will use the internal addresses for the clusterlab.org network.During installation, we filled in the machine’s fully qualifier domain name (FQDN) which can be rather long when it appears in cluster logs and status output. See for yourself how the machine identifies itself:Fedora Installation - Activate NetworkingFedora Installation - BootloaderFedora Installation - Bring up the TerminalFedora Installation - Create Non-privileged UserFedora Installation - Customize NetworkingFedora Installation - Customize PartitioningFedora Installation - Date and TimeFedora Installation - Default PartitioningFedora Installation - First BootFedora Installation - HostnameFedora Installation - Installation CompleteFedora Installation - Installation TypeFedora Installation - InstallingFedora Installation - SoftwareFedora Installation - Specify Network PreferencesFedora Installation - Storage DevicesFedora Installation - WelcomeFedora Installation: Choose a hostnameFedora Installation: Choose an installation typeFedora Installation: Click here to configure networkingFedora Installation: Click the big green button to activate your changesFedora Installation: Create a partition to use (later) for website dataFedora Installation: Creating a non-privileged user, take note of the password, you'll need it soonFedora Installation: Down to business, fire up the command lineFedora Installation: Enable NTP to keep the times on all your nodes consistentFedora Installation: Go grab something to drink, this may take a whileFedora Installation: Good choiceFedora Installation: Software selectionFedora Installation: Specify network settings for your machine, never choose DHCPFedora Installation: Stage 1, completedFedora Installation: Storage DevicesFedora Installation: Unless you have a strong reason not to, accept the default bootloader locationFinalize NetworkingFinally, tell Corosync to start PacemakerFor the purposes of this document, the additional node is called pcmk-2 with address 192.168.122.42.For this document, I have chosen port 4000 and used 226.94.1.1 as the multi-cast address.Go to the terminal window you just opened and switch to the super user (aka. "root") account with the su command. You will need to supply the password you entered earlier during the installation process.However we’re not finished. The machine wont normally see the shortened host name until about it reboots, but we can force it to update.If you plan on following the DRBD or GFS2 portions of this guide, you should reserve at least 1Gb of space on each machine from which to create a shared volume.Install the Cluster SoftwareInstall the key on the other nodes and test that you can now run commands remotely, without being promptedInstallationInstalling the SSH Key on Another HostIt is highly recommended to enable NTP on your cluster nodes. Doing so ensures all nodes agree on the current time and makes reading log files significantly easier.Next choose which software should be installed. Change the selection to Web Server since we plan on using Apache. Don't enable updates yet, we'll do that (and install any extra software we need) later. After you click next, Fedora will begin installing.Next we automatically determine the hosts address. By not using the full address, we make the configuration suitable to be copied to other nodes.Note that the username (the text before the @ symbol) now indicates we’re running as the super user “root”.Now check the machine is using the correct namesNow confirm the change was successful. The revised file contents should look something like this.Now repeat on pcmk-2.Now select where you want Fedora installed. http://docs.fedoraproject.org/install-guide/f13/en-US/html/s1-diskpartsetup-x86.html As I don’t care about any existing data, I will accept the default and allow Fedora to use the complete drive. However I want to reserve some space for DRBD, so I'll check the Review and modify partitioning layout box.Now we need to copy the changes so far to the other node:Now we need to make sure we can communicate with the machines by their name. If you have a DNS server, add additional entries for the three machines. Otherwise, you’ll need to add the machines to /etc/hosts . Below are the entries for my cluster nodes:OS InstallationOnce the node reboots, follow the on screen instructions http://docs.fedoraproject.org/install-guide/f&DISTRO_VERSION;/en-US/html/ch-firstboot.html to create a system user and configure the time.Once you’re happy with the chosen values, update the Corosync configurationPoint your browser to http://fedoraproject.org/en/get-fedora-all, locate the Install Media section and download the install DVD that matches your hardware.Propagate the ConfigurationRepeat the Installation steps so that you have 2 Fedora nodes with the cluster software installed.SSH is a convenient and secure way to copy files and perform commands remotely. For the purposes of this guide, we will create a key without a password (using the -N “” option) so that we can perform remote actions without being prompted.Security ShortcutsSet up /etc/hosts entriesSetupShort Node NamesSince version 12, Fedora comes with recent versions of everything you need, so simply fire up the shell and run:TODO: Create an Appendix that deals with (at least) re-enabling the firewall.That was the last screenshot, from here on in we’re going to be working from the terminal.The final configuration should look something like the sample in the appendix.The finalized partition layout should look something like the diagram below.The output from the second command is fine, but we really don’t need the domain name included in the basic host details. To address this, we need to update /etc/sysconfig/network. This is what it should look like before we start.To simplify this guide and focus on the aspects directly connected to clustering, we will now disable the machine’s firewall and SELinux installation. Both of these actions create significant security issues and should not be performed on machines that will be exposed to the outside world.Unprotected SSH keys, those without a password, are not recommended for servers exposed to the outside world.Verify Connectivity by HostnameVerify Connectivity by IP addressWe can now verify the setup by again using ping:You will need to reboot for the SELinux changes to take effect. Otherwise you will see something like this when you start corosync:You will then be prompted to indicate the machine’s physical location and to supply a root password. http://docs.fedoraproject.org/install-guide/f&DISTRO_VERSION;/en-US/html/sn-account_configuration.html [root@pcmk-1 ~]# export ais_addr=`ip addr | grep "inet " | tail -n 1 | awk '{print $4}' | sed s/255/0/`[root@pcmk-1 ~]# sed -i.bak 's/\.[a-z].*//g' /etc/sysconfig/networkProject-Id-Version: 0 POT-Creation-Date: 2010-12-15T23:32:37 PO-Revision-Date: 2010-12-16 00:16+0800 Last-Translator: Charlie Chen Language-Team: None Language: MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit grep pcmk /etc/hosts [root@pcmk-1 ~]# grep pcmk /etc/hosts 192.168.122.101 pcmk-1.clusterlabs.org pcmk-1 192.168.122.102 pcmk-2.clusterlabs.org pcmk-2 ping -c 3 192.168.122.102 [root@pcmk-1 ~]# ping -c 3 192.168.122.102 PING 192.168.122.102 (192.168.122.102) 56(84) bytes of data. 64 bytes from 192.168.122.102: icmp_seq=1 ttl=64 time=0.343 ms 64 bytes from 192.168.122.102: icmp_seq=2 ttl=64 time=0.402 ms 64 bytes from 192.168.122.102: icmp_seq=3 ttl=64 time=0.558 ms --- 192.168.122.102 ping statistics --- 3 packets transmitted, 3 received, 0% packet loss, time 2000ms rtt min/avg/max/mdev = 0.343/0.434/0.558/0.092 ms ping -c 3 pcmk-2 [root@pcmk-1 ~]# ping -c 3 pcmk-2 PING pcmk-2.clusterlabs.org (192.168.122.101) 56(84) bytes of data. 64 bytes from pcmk-1.clusterlabs.org (192.168.122.101): icmp_seq=1 ttl=64 time=0.164 ms 64 bytes from pcmk-1.clusterlabs.org (192.168.122.101): icmp_seq=2 ttl=64 time=0.475 ms 64 bytes from pcmk-1.clusterlabs.org (192.168.122.101): icmp_seq=3 ttl=64 time=0.186 ms --- pcmk-2.clusterlabs.org ping statistics --- 3 packets transmitted, 3 received, 0% packet loss, time 2001ms rtt min/avg/max/mdev = 0.164/0.275/0.475/0.141 ms ========================================================================================== Package Arch Version Repository Size ========================================================================================== Installing: corosync x86_64 1.2.1-1.fc13 fedora 136 k pacemaker x86_64 1.1.1-1.fc13 fedora 543 k Installing for dependencies: OpenIPMI-libs x86_64 2.0.16-8.fc13 fedora 474 k PyXML x86_64 0.8.4-17.fc13 fedora 906 k cluster-glue x86_64 1.0.2-1.fc13 fedora 230 k cluster-glue-libs x86_64 1.0.2-1.fc13 fedora 116 k corosynclib x86_64 1.2.1-1.fc13 fedora 145 k heartbeat x86_64 3.0.0-0.7.0daab7da36a8.hg.fc13 updates 172 k heartbeat-libs x86_64 3.0.0-0.7.0daab7da36a8.hg.fc13 updates 265 k libesmtp x86_64 1.0.4-12.fc12 fedora 54 k libibverbs x86_64 1.1.3-4.fc13 fedora 42 k libmlx4 x86_64 1.0.1-5.fc13 fedora 27 k libnet x86_64 1.1.4-3.fc12 fedora 49 k librdmacm x86_64 1.0.10-2.fc13 fedora 22 k lm_sensors-libs x86_64 3.1.2-2.fc13 fedora 37 k net-snmp x86_64 1:5.5-12.fc13 fedora 295 k net-snmp-libs x86_64 1:5.5-12.fc13 fedora 1.5 M openhpi-libs x86_64 2.14.1-3.fc13 fedora 135 k pacemaker-libs x86_64 1.1.1-1.fc13 fedora 264 k perl-TimeDate noarch 1:1.20-1.fc13 fedora 42 k resource-agents x86_64 3.0.10-1.fc13 fedora 357 k Transaction Summary ========================================================================================= Install 21 Package(s) Upgrade 0 Package(s) Total download size: 5.7 M Installed size: 20 M Downloading Packages: Setting up and reading Presto delta metadata updates-testing/prestodelta | 164 kB 00:00 fedora/prestodelta | 150 B 00:00 Processing delta metadata Package(s) data still to download: 5.7 M (1/21): OpenIPMI-libs-2.0.16-8.fc13.x86_64.rpm | 474 kB 00:00 (2/21): PyXML-0.8.4-17.fc13.x86_64.rpm | 906 kB 00:01 (3/21): cluster-glue-1.0.2-1.fc13.x86_64.rpm | 230 kB 00:00 (4/21): cluster-glue-libs-1.0.2-1.fc13.x86_64.rpm | 116 kB 00:00 (5/21): corosync-1.2.1-1.fc13.x86_64.rpm | 136 kB 00:00 (6/21): corosynclib-1.2.1-1.fc13.x86_64.rpm | 145 kB 00:00 (7/21): heartbeat-3.0.0-0.7.0daab7da36a8.hg.fc13.x86_64.rpm | 172 kB 00:00 (8/21): heartbeat-libs-3.0.0-0.7.0daab7da36a8.hg.fc13.x86_64.rpm | 265 kB 00:00 (9/21): libesmtp-1.0.4-12.fc12.x86_64.rpm | 54 kB 00:00 (10/21): libibverbs-1.1.3-4.fc13.x86_64.rpm | 42 kB 00:00 (11/21): libmlx4-1.0.1-5.fc13.x86_64.rpm | 27 kB 00:00 (12/21): libnet-1.1.4-3.fc12.x86_64.rpm | 49 kB 00:00 (13/21): librdmacm-1.0.10-2.fc13.x86_64.rpm | 22 kB 00:00 (14/21): lm_sensors-libs-3.1.2-2.fc13.x86_64.rpm | 37 kB 00:00 (15/21): net-snmp-5.5-12.fc13.x86_64.rpm | 295 kB 00:00 (16/21): net-snmp-libs-5.5-12.fc13.x86_64.rpm | 1.5 MB 00:01 (17/21): openhpi-libs-2.14.1-3.fc13.x86_64.rpm | 135 kB 00:00 (18/21): pacemaker-1.1.1-1.fc13.x86_64.rpm | 543 kB 00:00 (19/21): pacemaker-libs-1.1.1-1.fc13.x86_64.rpm | 264 kB 00:00 (20/21): perl-TimeDate-1.20-1.fc13.noarch.rpm | 42 kB 00:00 (21/21): resource-agents-3.0.10-1.fc13.x86_64.rpm | 357 kB 00:00 ---------------------------------------------------------------------------------------- Total 539 kB/s | 5.7 MB 00:10 warning: rpmts_HdrFromFdno: Header V3 RSA/SHA256 Signature, key ID e8e40fde: NOKEY fedora/gpgkey | 3.2 kB 00:00 ... Importing GPG key 0xE8E40FDE "Fedora (13) <fedora@fedoraproject.org%gt;" from /etc/pki/rpm-gpg/RPM-GPG-KEY-fedora-x86_64 May 4 19:30:54 pcmk-1 setroubleshoot: SELinux is preventing /usr/sbin/corosync "getattr" access on /. For complete SELinux messages. run sealert -l 6e0d4384-638e-4d55-9aaf-7dac011f29c1 May 4 19:30:54 pcmk-1 setroubleshoot: SELinux is preventing /usr/sbin/corosync "getattr" access on /. For complete SELinux messages. run sealert -l 6e0d4384-638e-4d55-9aaf-7dac011f29c1 Running rpm_check_debug Running Transaction Test Transaction Test Succeeded Running Transaction Installing : lm_sensors-libs-3.1.2-2.fc13.x86_64 1/21 Installing : 1:net-snmp-libs-5.5-12.fc13.x86_64 2/21 Installing : 1:net-snmp-5.5-12.fc13.x86_64 3/21 Installing : openhpi-libs-2.14.1-3.fc13.x86_64 4/21 Installing : libibverbs-1.1.3-4.fc13.x86_64 5/21 Installing : libmlx4-1.0.1-5.fc13.x86_64 6/21 Installing : librdmacm-1.0.10-2.fc13.x86_64 7/21 Installing : corosync-1.2.1-1.fc13.x86_64 8/21 Installing : corosynclib-1.2.1-1.fc13.x86_64 9/21 Installing : libesmtp-1.0.4-12.fc12.x86_64 10/21 Installing : OpenIPMI-libs-2.0.16-8.fc13.x86_64 11/21 Installing : PyXML-0.8.4-17.fc13.x86_64 12/21 Installing : libnet-1.1.4-3.fc12.x86_64 13/21 Installing : 1:perl-TimeDate-1.20-1.fc13.noarch 14/21 Installing : cluster-glue-1.0.2-1.fc13.x86_64 15/21 Installing : cluster-glue-libs-1.0.2-1.fc13.x86_64 16/21 Installing : resource-agents-3.0.10-1.fc13.x86_64 17/21 Installing : heartbeat-libs-3.0.0-0.7.0daab7da36a8.hg.fc13.x86_64 18/21 Installing : heartbeat-3.0.0-0.7.0daab7da36a8.hg.fc13.x86_64 19/21 Installing : pacemaker-1.1.1-1.fc13.x86_64 20/21 Installing : pacemaker-libs-1.1.1-1.fc13.x86_64 21/21 Installed: corosync.x86_64 0:1.2.1-1.fc13 pacemaker.x86_64 0:1.1.1-1.fc13 Dependency Installed: OpenIPMI-libs.x86_64 0:2.0.16-8.fc13 PyXML.x86_64 0:0.8.4-17.fc13 cluster-glue.x86_64 0:1.0.2-1.fc13 cluster-glue-libs.x86_64 0:1.0.2-1.fc13 corosynclib.x86_64 0:1.2.1-1.fc13 heartbeat.x86_64 0:3.0.0-0.7.0daab7da36a8.hg.fc13 heartbeat-libs.x86_64 0:3.0.0-0.7.0daab7da36a8.hg.fc13 libesmtp.x86_64 0:1.0.4-12.fc12 libibverbs.x86_64 0:1.1.3-4.fc13 libmlx4.x86_64 0:1.0.1-5.fc13 libnet.x86_64 0:1.1.4-3.fc12 librdmacm.x86_64 0:1.0.10-2.fc13 lm_sensors-libs.x86_64 0:3.1.2-2.fc13 net-snmp.x86_64 1:5.5-12.fc13 net-snmp-libs.x86_64 1:5.5-12.fc13 openhpi-libs.x86_64 0:2.14.1-3.fc13 pacemaker-libs.x86_64 0:1.1.1-1.fc13 perl-TimeDate.noarch 1:1.20-1.fc13 resource-agents.x86_64 0:3.0.10-1.fc13 Complete! [root@pcmk-1 ~]# [beekhof@pcmk-1 ~]$ su - Password: [root@pcmk-1 ~]# [root@pcmk-1 ~]# cat <<-END >>/etc/corosync/service.d/pcmk service { # Load the Pacemaker Cluster Resource Manager name: pacemaker ver: 0 } END [root@pcmk-1 ~]# cat /etc/sysconfig/network NETWORKING=yes HOSTNAME=pcmk-1.clusterlabs.org GATEWAY=192.168.122.1 [root@pcmk-1 ~]# cat /etc/sysconfig/network NETWORKING=yes HOSTNAME=pcmk-1 GATEWAY=192.168.122.1 [root@pcmk-1 ~]# cp /etc/corosync/corosync.conf.example /etc/corosync/corosync.conf [root@pcmk-1 ~]# sed -i.bak "s/.*mcastaddr:.*/mcastaddr:\ $ais_mcast/g" /etc/corosync/corosync.conf [root@pcmk-1 ~]# sed -i.bak "s/.*mcastport:.*/mcastport:\ $ais_port/g" /etc/corosync/corosync.conf [root@pcmk-1 ~]# sed -i.bak "s/.*bindnetaddr:.*/bindnetaddr:\ $ais_addr/g" /etc/corosync/corosync.conf [root@pcmk-1 ~]# env | grep ais_ ais_mcast=226.94.1.1 ais_port=4000 ais_addr=192.168.122.0 [root@pcmk-1 ~]# export ais_port=4000 [root@pcmk-1 ~]# export ais_mcast=226.94.1.1 [root@pcmk-1 ~]# for f in /etc/corosync/corosync.conf /etc/corosync/service.d/pcmk /etc/hosts; do scp $f pcmk-2:$f ; done corosync.conf 100% 1528 1.5KB/s 00:00 hosts 100% 281 0.3KB/s 00:00 [root@pcmk-1 ~]# [root@pcmk-1 ~]# ip addr 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 16436 qdisc noqueue state UNKNOWN link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo inet6 ::1/128 scope host valid_lft forever preferred_lft forever 2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UNKNOWN qlen 1000 link/ether 00:0c:29:6f:e1:58 brd ff:ff:ff:ff:ff:ff inet 192.168.9.41/24 brd 192.168.9.255 scope global eth0 inet6 ::20c:29ff:fe6f:e158/64 scope global dynamic valid_lft 2591667sec preferred_lft 604467sec inet6 2002:57ae:43fc:0:20c:29ff:fe6f:e158/64 scope global dynamic valid_lft 2591990sec preferred_lft 604790sec inet6 fe80::20c:29ff:fe6f:e158/64 scope link valid_lft forever preferred_lft forever [root@pcmk-1 ~]# ping -c 1 www.google.com PING www.l.google.com (74.125.39.99) 56(84) bytes of data. 64 bytes from fx-in-f99.1e100.net (74.125.39.99): icmp_seq=1 ttl=56 time=16.7 ms --- www.l.google.com ping statistics --- 1 packets transmitted, 1 received, 0% packet loss, time 20ms rtt min/avg/max/mdev = 16.713/16.713/16.713/0.000 ms [root@pcmk-1 ~]# /sbin/chkconfig network on [root@pcmk-1 ~]# [root@pcmk-1 ~]# scp -r .ssh pcmk-2: The authenticity of host 'pcmk-2 (192.168.122.102)' can't be established. RSA key fingerprint is b1:2b:55:93:f1:d9:52:2b:0f:f2:8a:4e:ae:c6:7c:9a. Are you sure you want to continue connecting (yes/no)? yes Warning: Permanently added 'pcmk-2,192.168.122.102' (RSA) to the list of known hosts. root@pcmk-2's password: id_dsa.pub 100% 616 0.6KB/s 00:00 id_dsa 100% 672 0.7KB/s 00:00 known_hosts 100% 400 0.4KB/s 00:00 authorized_keys 100% 616 0.6KB/s 00:00 [root@pcmk-1 ~]# ssh pcmk-2 -- uname -n pcmk-2 [root@pcmk-1 ~]# [root@pcmk-1 ~]# sed -i.bak "s/enabled=0/enabled=1/g" /etc/yum.repos.d/fedora.repo [root@pcmk-1 ~]# sed -i.bak "s/enabled=0/enabled=1/g" /etc/yum.repos.d/fedora-updates.repo [root@pcmk-1 ~]# yum install -y pacemaker corosync Loaded plugins: presto, refresh-packagekit fedora/metalink | 22 kB 00:00 fedora-debuginfo/metalink | 16 kB 00:00 fedora-debuginfo | 3.2 kB 00:00 fedora-debuginfo/primary_db | 1.4 MB 00:04 fedora-source/metalink | 22 kB 00:00 fedora-source | 3.2 kB 00:00 fedora-source/primary_db | 3.0 MB 00:05 updates/metalink | 26 kB 00:00 updates | 2.6 kB 00:00 updates/primary_db | 1.1 kB 00:00 updates-debuginfo/metalink | 18 kB 00:00 updates-debuginfo | 2.6 kB 00:00 updates-debuginfo/primary_db | 1.1 kB 00:00 updates-source/metalink | 25 kB 00:00 updates-source | 2.6 kB 00:00 updates-source/primary_db | 1.1 kB 00:00 Setting up Install Process Resolving Dependencies --> Running transaction check ---> Package corosync.x86_64 0:1.2.1-1.fc13 set to be updated --> Processing Dependency: corosynclib = 1.2.1-1.fc13 for package: corosync-1.2.1-1.fc13.x86_64 --> Processing Dependency: libquorum.so.4(COROSYNC_QUORUM_1.0)(64bit) for package: corosync-1.2.1-1.fc13.x86_64 --> Processing Dependency: libvotequorum.so.4(COROSYNC_VOTEQUORUM_1.0)(64bit) for package: corosync-1.2.1-1.fc13.x86_64 --> Processing Dependency: libcpg.so.4(COROSYNC_CPG_1.0)(64bit) for package: corosync-1.2.1-1.fc13.x86_64 --> Processing Dependency: libconfdb.so.4(COROSYNC_CONFDB_1.0)(64bit) for package: corosync-1.2.1-1.fc13.x86_64 --> Processing Dependency: libcfg.so.4(COROSYNC_CFG_0.82)(64bit) for package: corosync-1.2.1-1.fc13.x86_64 --> Processing Dependency: libpload.so.4(COROSYNC_PLOAD_1.0)(64bit) for package: corosync-1.2.1-1.fc13.x86_64 --> Processing Dependency: liblogsys.so.4()(64bit) for package: corosync-1.2.1-1.fc13.x86_64 --> Processing Dependency: libconfdb.so.4()(64bit) for package: corosync-1.2.1-1.fc13.x86_64 --> Processing Dependency: libcoroipcc.so.4()(64bit) for package: corosync-1.2.1-1.fc13.x86_64 --> Processing Dependency: libcpg.so.4()(64bit) for package: corosync-1.2.1-1.fc13.x86_64 --> Processing Dependency: libquorum.so.4()(64bit) for package: corosync-1.2.1-1.fc13.x86_64 --> Processing Dependency: libcoroipcs.so.4()(64bit) for package: corosync-1.2.1-1.fc13.x86_64 --> Processing Dependency: libvotequorum.so.4()(64bit) for package: corosync-1.2.1-1.fc13.x86_64 --> Processing Dependency: libcfg.so.4()(64bit) for package: corosync-1.2.1-1.fc13.x86_64 --> Processing Dependency: libtotem_pg.so.4()(64bit) for package: corosync-1.2.1-1.fc13.x86_64 --> Processing Dependency: libpload.so.4()(64bit) for package: corosync-1.2.1-1.fc13.x86_64 ---> Package pacemaker.x86_64 0:1.1.1-1.fc13 set to be updated --> Processing Dependency: heartbeat >= 3.0.0 for package: pacemaker-1.1.1-1.fc13.x86_64 --> Processing Dependency: net-snmp >= 5.4 for package: pacemaker-1.1.1-1.fc13.x86_64 --> Processing Dependency: resource-agents for package: pacemaker-1.1.1-1.fc13.x86_64 --> Processing Dependency: cluster-glue for package: pacemaker-1.1.1-1.fc13.x86_64 --> Processing Dependency: libnetsnmp.so.20()(64bit) for package: pacemaker-1.1.1-1.fc13.x86_64 --> Processing Dependency: libcrmcluster.so.1()(64bit) for package: pacemaker-1.1.1-1.fc13.x86_64 --> Processing Dependency: libpengine.so.3()(64bit) for package: pacemaker-1.1.1-1.fc13.x86_64 --> Processing Dependency: libnetsnmpagent.so.20()(64bit) for package: pacemaker-1.1.1-1.fc13.x86_64 --> Processing Dependency: libesmtp.so.5()(64bit) for package: pacemaker-1.1.1-1.fc13.x86_64 --> Processing Dependency: libstonithd.so.1()(64bit) for package: pacemaker-1.1.1-1.fc13.x86_64 --> Processing Dependency: libhbclient.so.1()(64bit) for package: pacemaker-1.1.1-1.fc13.x86_64 --> Processing Dependency: libpils.so.2()(64bit) for package: pacemaker-1.1.1-1.fc13.x86_64 --> Processing Dependency: libpe_status.so.2()(64bit) for package: pacemaker-1.1.1-1.fc13.x86_64 --> Processing Dependency: libnetsnmpmibs.so.20()(64bit) for package: pacemaker-1.1.1-1.fc13.x86_64 --> Processing Dependency: libnetsnmphelpers.so.20()(64bit) for package: pacemaker-1.1.1-1.fc13.x86_64 --> Processing Dependency: libcib.so.1()(64bit) for package: pacemaker-1.1.1-1.fc13.x86_64 --> Processing Dependency: libccmclient.so.1()(64bit) for package: pacemaker-1.1.1-1.fc13.x86_64 --> Processing Dependency: libstonith.so.1()(64bit) for package: pacemaker-1.1.1-1.fc13.x86_64 --> Processing Dependency: liblrm.so.2()(64bit) for package: pacemaker-1.1.1-1.fc13.x86_64 --> Processing Dependency: libtransitioner.so.1()(64bit) for package: pacemaker-1.1.1-1.fc13.x86_64 --> Processing Dependency: libpe_rules.so.2()(64bit) for package: pacemaker-1.1.1-1.fc13.x86_64 --> Processing Dependency: libcrmcommon.so.2()(64bit) for package: pacemaker-1.1.1-1.fc13.x86_64 --> Processing Dependency: libplumb.so.2()(64bit) for package: pacemaker-1.1.1-1.fc13.x86_64 --> Running transaction check ---> Package cluster-glue.x86_64 0:1.0.2-1.fc13 set to be updated --> Processing Dependency: perl-TimeDate for package: cluster-glue-1.0.2-1.fc13.x86_64 --> Processing Dependency: libOpenIPMIutils.so.0()(64bit) for package: cluster-glue-1.0.2-1.fc13.x86_64 --> Processing Dependency: libOpenIPMIposix.so.0()(64bit) for package: cluster-glue-1.0.2-1.fc13.x86_64 --> Processing Dependency: libopenhpi.so.2()(64bit) for package: cluster-glue-1.0.2-1.fc13.x86_64 --> Processing Dependency: libOpenIPMI.so.0()(64bit) for package: cluster-glue-1.0.2-1.fc13.x86_64 ---> Package cluster-glue-libs.x86_64 0:1.0.2-1.fc13 set to be updated ---> Package corosynclib.x86_64 0:1.2.1-1.fc13 set to be updated --> Processing Dependency: librdmacm.so.1(RDMACM_1.0)(64bit) for package: corosynclib-1.2.1-1.fc13.x86_64 --> Processing Dependency: libibverbs.so.1(IBVERBS_1.0)(64bit) for package: corosynclib-1.2.1-1.fc13.x86_64 --> Processing Dependency: libibverbs.so.1(IBVERBS_1.1)(64bit) for package: corosynclib-1.2.1-1.fc13.x86_64 --> Processing Dependency: libibverbs.so.1()(64bit) for package: corosynclib-1.2.1-1.fc13.x86_64 --> Processing Dependency: librdmacm.so.1()(64bit) for package: corosynclib-1.2.1-1.fc13.x86_64 ---> Package heartbeat.x86_64 0:3.0.0-0.7.0daab7da36a8.hg.fc13 set to be updated --> Processing Dependency: PyXML for package: heartbeat-3.0.0-0.7.0daab7da36a8.hg.fc13.x86_64 ---> Package heartbeat-libs.x86_64 0:3.0.0-0.7.0daab7da36a8.hg.fc13 set to be updated ---> Package libesmtp.x86_64 0:1.0.4-12.fc12 set to be updated ---> Package net-snmp.x86_64 1:5.5-12.fc13 set to be updated --> Processing Dependency: libsensors.so.4()(64bit) for package: 1:net-snmp-5.5-12.fc13.x86_64 ---> Package net-snmp-libs.x86_64 1:5.5-12.fc13 set to be updated ---> Package pacemaker-libs.x86_64 0:1.1.1-1.fc13 set to be updated ---> Package resource-agents.x86_64 0:3.0.10-1.fc13 set to be updated --> Processing Dependency: libnet.so.1()(64bit) for package: resource-agents-3.0.10-1.fc13.x86_64 --> Running transaction check ---> Package OpenIPMI-libs.x86_64 0:2.0.16-8.fc13 set to be updated ---> Package PyXML.x86_64 0:0.8.4-17.fc13 set to be updated ---> Package libibverbs.x86_64 0:1.1.3-4.fc13 set to be updated --> Processing Dependency: libibverbs-driver for package: libibverbs-1.1.3-4.fc13.x86_64 ---> Package libnet.x86_64 0:1.1.4-3.fc12 set to be updated ---> Package librdmacm.x86_64 0:1.0.10-2.fc13 set to be updated ---> Package lm_sensors-libs.x86_64 0:3.1.2-2.fc13 set to be updated ---> Package openhpi-libs.x86_64 0:2.14.1-3.fc13 set to be updated ---> Package perl-TimeDate.noarch 1:1.20-1.fc13 set to be updated --> Running transaction check ---> Package libmlx4.x86_64 0:1.0.1-5.fc13 set to be updated --> Finished Dependency Resolution Dependencies Resolved [root@pcmk-1 ~]# source /etc/sysconfig/network [root@pcmk-1 ~]# hostname $HOSTNAME [root@pcmk-1 ~]# ssh-keygen -t dsa -f ~/.ssh/id_dsa -N "" Generating public/private dsa key pair. Your identification has been saved in /root/.ssh/id_dsa. Your public key has been saved in /root/.ssh/id_dsa.pub. The key fingerprint is: 91:09:5c:82:5a:6a:50:08:4e:b2:0c:62:de:cc:74:44 root@pcmk-1.clusterlabs.org The key's randomart image is: +--[ DSA 1024]----+ |==.ooEo.. | |X O + .o o | | * A + | | + . | | . S | | | | | | | | | +-----------------+ [root@pcmk-1 ~]# cp .ssh/id_dsa.pub .ssh/authorized_keys [root@pcmk-1 ~]# [root@pcmk-1 ~]# uname -n pcmk-1 [root@pcmk-1 ~]# dnsdomainname clusterlabs.org [root@pcmk-1 ~]# uname -n pcmk-1.clusterlabs.org [root@pcmk-1 ~]# dnsdomainname clusterlabs.org [root@pcmk-1 ~]# sed -i.bak "s/SELINUX=enforcing/SELINUX=permissive/g" /etc/selinux/config [root@pcmk-1 ~]# /sbin/chkconfig --del iptables [root@pcmk-1 ~]# service iptables stop iptables: Flushing firewall rules: [ OK ] iptables: Setting chains to policy ACCEPT: filter [ OK ] iptables: Unloading modules: [ OK ] 我们要做的只是要把域名后面的部分去掉。给你的机器取个名字。 http://docs.fedoraproject.org/install-guide/f&DISTRO_VERSION;/en-US/html/sn-networkconfig-fedora.html 我可以使用clusterlabs.org这个域名,所以在这里我用这个域名。请注意你选择的端口和地址不能跟已存在的集群冲突,关于组播地址的选择,可以参考 http://www.29west.com/docs/THPM/multicast-address-assignment.html 写在开始之前烧录一个DVD光盘 http://docs.fedoraproject.org/readme-burning-isos/en-US.html 并从它启动。或者就像我一样启动一个虚拟机。 在点击欢迎界面的NETX后 ,我们要开始选择语言和键盘类型 http://docs.fedoraproject.org/install-guide/f&DISTRO_VERSION;/en-US/html/s1-langselection-x86.html 默认的话,Fedora会将所有的空间都分配给/ (aka. 根)分区。我们要保留一点给DRBD。选择一个组播 http://en.wikipedia.org/wiki/Multicast 端口和地址。 http://en.wikipedia.org/wiki/Multicast_address 点击next会进入登入界面,点击你创建的用户并输入之前设定的密码。集群软件安装配置SSH配置 Corosync确认这两个新节点能够通讯:创建一个密钥并允许所有有这个密钥的用户登入创建并激活一个新的SSH密钥详细的安装手册在http://docs.fedoraproject.org/install-guide/f&DISTRO_VERSION;/。下文是一个简短的版本...显示并检查配置的环境变量是否正确不要使用默认的网络设置,集群永远不会靠DHCP来管理IP,这里我使用clusterslab的内部IP。在安装过程中,我们发现FQDN域名太长了,不利于在日志或状态界面中查看,我们用以下操作来简化机器名:安装Fedora - 激活网络安装Fedora - Bootloader安装Fedora - 打开终端安装Fedora - 创建非特权用户安装Fedora -自定义网络安装Fedora - 自定义分区安装Fedora - 日期和时间安装Fedora - 默认分区安装Fedora - 第一次启动安装Fedora -机器名安装Fedora - 安装完成安装Fedora - 安装类型安装Fedora - 安装中安装Fedora - 软件安装Fedora - 指定网络参数安装Fedora - 存储设备安装Fedora - 欢迎 安装Fedora: 选择一个机器名安装Fedora: 选择安装类型安装Fedora: 点击这里来配置网络安装Fedora:点击绿色按钮来应用你的更改安装Fedora: 创建一个网站存放数据用的分区安装Fedora: 创建非特权用户,请注意密码,一会你要用到它的。安装Fedora:开始干活,打开终端安装Fedora : 启用NTP来保证所有节点时间同步安装Fedora: 去搞点东西喝喝 这要一会儿安装Fedora: 好的选择!安装Fedora: 软件选择安装Fedora: 设定你的网络,永远不要选择DHCP安装Fedora: Stage 1, 完成安装Fedora: 存储设备安装Fedora: 除非有非常强力的理由,不然选择默认的bootloader安装位置设定网络最后,告诉corosync要启动pacemaker在这篇文档中, 另外一个节点叫 pcmk-2 并且IP地址为 192.168.122.42。在这个文档中,我选择端口4000并且用226.94.1.1作为组播地址:打开一个终端,然后使用su命令切换到超级用户(root)。输入之前安装时候设定的密码:然而到这里还没结束,机器还没接受新的配置文件,我们强制它生效。如果你想试验本文档中关于DRBD或者GFS2的部分,你要为每个节点保留至少1Gb的空间。安装集群软件在其他节点安装这个密钥并测试你是否可以执行命令而不用输入密码安装在另一个机器上面安装SSH密钥强烈建议开启NTP时间同步,这样可以使集群更好的同步配置文件以及使日志文件有更好的可读性。然后我们选择应该安装什么软件。因为我们想用Apache,所以选择Web Server。现在不要开启Update源,我们一会操作它。点击下一步,开始安装Fedora。然后我们用下面的命令自动获得机器的地址。为了让配置文件能够在机器上面的各个机器通用,我们不使用完整的IP地址而使用网络地址。(译者注:corosync配置文件中的监听地址一项可以填写网络地址,corosync会自动匹配应该监听在哪个地址而不是0.0.0.0)注意用户名 (@符号左边的字符串) 显示我们现在使用的是root用户.现在我们看看是否按达到我们预期的效果:现在cat一下看看更改是否成功了。现在在pcmk-2上面重复以上操作.如然后你选择想在哪安装Fedora http://docs.fedoraproject.org/install-guide/f13/en-US/html/s1-diskpartsetup-x86.html 。 如果你像我一样不在意已存在的数据,就选择默认让Fedora来使用完整的驱动器。然而我想为DRBD保留一些空间,所以我勾选了Review and modify partitioning layout。然后我们把配置文件拷贝到其他节点:现在我们需要确认我们能通过机器名访问这两台机器,如果你有一个DNS服务器,为这两台节点做域名解析。安装操作系统一旦系统重启完毕你可以看到以下界面 http://docs.fedoraproject.org/install-guide/f&DISTRO_VERSION;/en-US/html/ch-firstboot.html ,然后配置用户和设定时间。确认以上输出没有错误以后,我们用以下命令来配置corosync在你的浏览器中打开 http://fedoraproject.org/en/get-fedora-all,找到Install Media部分并下载适合你硬件的安装DVD文件。 传送配置文件在另一台Fedora 12机器上面重复以上操作步骤,这样你就有2台安装了集群软件的节点了。SSH 是一个方便又安全来的用来远程传输文件或运行命令 的工具. 在这个文档中, 我们创建ssh key(用 -N “” 选项)来免去登入要输入密码的麻烦。安全提示否则,我们修改/etc/hosts文件来达到相同的效果:安装简化节点名称从Fedora 12开始,你需要的东西都已经准备好了,只需在终端命令行运行以下命令:TODO: Create an Appendix that deals with (at least) re-enabling the firewall.这是最后一个截屏了,剩下的我们都用命令行来操作。最后配置文件应该看起来像下面的样子。完整的分区应该像下面一样。第二个命令的输出是正常的,但是我们真的不需要这么详细的输出,我们更改/etc/sysconfig/network文件来达到简化的目的。为了简化本文档并更好的关注集群方面的问题,我们现在在先禁用防火墙和SELinux。这些操作都会导致重大的安全问题,并不推荐对公网上的集群这样做。不推荐在公网的机器上采用未用密码保护的ssh-key通过机器名检查连接通过IP地址来检查连接现在让我们ping一下:你需要重启来保证SELinux正确关闭。不然你启动corosync的时候将看到以下提示:然后你会被提示选择机器所在地并设定root密码。 http://docs.fedoraproject.org/install-guide/f&DISTRO_VERSION;/en-US/html/sn-account_configuration.html [root@pcmk-1 ~]# export ais_addr=`ip addr | grep "inet " | tail -n 1 | awk '{print $4}' | sed s/255/0/`[root@pcmk-1 ~]# sed -i.bak 's/\.[a-z].*//g' /etc/sysconfig/networkpacemaker-master/doc/Clusters_from_Scratch/zh-CN/Ch-Installation.po000066400000000000000000004073771217637305600256460ustar00rootroot00000000000000# # AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: 0\n" "POT-Creation-Date: 2012-10-17T05:19:03\n" "PO-Revision-Date: 2010-12-16 00:16+0800\n" "Last-Translator: Charlie Chen \n" "Language-Team: None\n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. Tag: title #, no-c-format msgid "Installation" msgstr "安装" #. Tag: title #, no-c-format msgid "OS Installation" msgstr "安装操作系统" #. Tag: para #, fuzzy, no-c-format msgid "Detailed instructions for installing Fedora are available at http://docs.fedoraproject.org/en-US/Fedora/17/html/Installation_Guide/ in a number of languages. The abbreviated version is as follows…" msgstr "详细的安装手册在http://docs.fedoraproject.org/install-guide/f&DISTRO_VERSION;/。下文是一个简短的版本..." #. Tag: para #, fuzzy, no-c-format msgid "Point your browser to http://fedoraproject.org/en/get-fedora-all, locate the Install Media section and download the install DVD that matches your hardware." msgstr "在你的浏览器中打开 http://fedoraproject.org/en/get-fedora-all,找到Install Media部分并下载适合你硬件的安装DVD文件。" #. Tag: para #, fuzzy, no-c-format msgid "Burn the disk image to a DVD http://docs.fedoraproject.org/en-US/Fedora/16/html/Burning_ISO_images_to_disc/index.html and boot from it, or use the image to boot a virtual machine." msgstr "给你的机器取个名字。 http://docs.fedoraproject.org/install-guide/f&DISTRO_VERSION;/en-US/html/sn-networkconfig-fedora.html 我可以使用clusterlabs.org这个域名,所以在这里我用这个域名。" #. Tag: para #, no-c-format msgid "After clicking through the welcome screen, select your language, keyboard layout http://docs.fedoraproject.org/en-US/Fedora/16/html/Installation_Guide/sn-keyboard-x86.html and storage type http://docs.fedoraproject.org/en-US/Fedora/16/html/Installation_Guide/Storage_Devices-x86.html" msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "Assign your machine a host name. http://docs.fedoraproject.org/en-US/Fedora/16/html/Installation_Guide/sn-Netconfig-x86.html I happen to control the clusterlabs.org domain name, so I will use that here." msgstr "给你的机器取个名字。 http://docs.fedoraproject.org/install-guide/f&DISTRO_VERSION;/en-US/html/sn-networkconfig-fedora.html 我可以使用clusterlabs.org这个域名,所以在这里我用这个域名。" #. Tag: para #, fuzzy, no-c-format msgid "Do not accept the default network settings. Cluster machines should never obtain an IP address via DHCP." msgstr "不要使用默认的网络设置,集群永远不会靠DHCP来管理IP,这里我使用clusterslab的内部IP。" #. Tag: para #, no-c-format msgid "When you are presented with the Configure Network advanced option, select that option before continuing with the installation process to specify a fixed IPv4 address for System eth0. Be sure to also enter the Routes section and add an entry for your default gateway." msgstr "" #. Tag: phrase #, no-c-format msgid "Custom network settings" msgstr "" #. Tag: para #, no-c-format msgid "If you miss this step, this can easily be configured after installation. You will have to navigate to system settings and select network. From there you can select what device to configure." msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "You will then be prompted to indicate the machine’s physical location http://docs.fedoraproject.org/en-US/Fedora/16/html/Installation_Guide/s1-timezone-x86.html and to supply a root password. http://docs.fedoraproject.org/en-US/Fedora/16/html/Installation_Guide/sn-account_configuration-x86.html" msgstr "然后你会被提示选择机器所在地并设定root密码。 http://docs.fedoraproject.org/install-guide/f&DISTRO_VERSION;/en-US/html/sn-account_configuration.html " #. Tag: para #, fuzzy, no-c-format msgid "Now select where you want Fedora installed. http://docs.fedoraproject.org/en-US/Fedora/16/html/Installation_Guide/s1-diskpartsetup-x86.html As I don’t care about any existing data, I will accept the default and allow Fedora to use the complete drive." msgstr "如然后你选择想在哪安装Fedora http://docs.fedoraproject.org/install-guide/f13/en-US/html/s1-diskpartsetup-x86.html 。 如果你像我一样不在意已存在的数据,就选择默认让Fedora来使用完整的驱动器。然而我想为DRBD保留一些空间,所以我勾选了Review and modify partitioning layout。" #. Tag: para #, no-c-format msgid "By default Fedora uses LVM for partitioning which allows us to dynamically change the amount of space allocated to a given partition." msgstr "" #. Tag: para #, no-c-format msgid "However, by default it also allocates all free space to the / (aka. root) partition which cannot be dynamically reduced in size (dynamic increases are fine by-the-way)." msgstr "" #. Tag: para #, no-c-format msgid "So if you plan on following the DRBD or GFS2 portions of this guide, you should reserve at least 1Gb of space on each machine from which to create a shared volume. To do so select the Review and modify partitioning layout checkbox before clicking Next. You will then be given an opportunity to reduce the size of the root partition." msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "Next choose which software should be installed. http://docs.fedoraproject.org/en-US/Fedora/16/html/Installation_Guide/s1-pkgselection-x86.html Change the selection to Minimal so that we see everything that gets installed. Don’t enable updates yet, we’ll do that (and install any extra software we need) later. After you click next, Fedora will begin installing." msgstr "然后我们选择应该安装什么软件。因为我们想用Apache,所以选择Web Server。现在不要开启Update源,我们一会操作它。点击下一步,开始安装Fedora。" #. Tag: para #, fuzzy, no-c-format msgid "Go grab something to drink, this may take a while." msgstr "安装Fedora: 去搞点东西喝喝 这要一会儿" #. Tag: para #, no-c-format msgid "Once the node reboots, you’ll see a (possibly mangled) login prompt on the console. Login using root and the password you created earlier." msgstr "" #. Tag: phrase #, no-c-format msgid "Initial Console" msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "From here on in we’re going to be working exclusively from the terminal." msgstr "这是最后一个截屏了,剩下的我们都用命令行来操作。" #. Tag: title #, fuzzy, no-c-format msgid "Post Installation Tasks" msgstr "安装" #. Tag: title #, fuzzy, no-c-format msgid "Networking" msgstr "设定网络" #. Tag: para #, no-c-format msgid "Bring up the network and ensure it starts at boot" msgstr "" #. Tag: programlisting #, no-c-format msgid "" "# service network start\n" "# chkconfig network on" msgstr "" #. Tag: para #, no-c-format msgid "Check the machine has the static IP address you configured earlier" msgstr "" #. Tag: programlisting #, no-c-format msgid "" "# ip addr\n" "1: lo: <LOOPBACK,UP,LOWER_UP> mtu 16436 qdisc noqueue state UNKNOWN\n" " link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00\n" " inet 127.0.0.1/8 scope host lo\n" " inet6 ::1/128 scope host\n" " valid_lft forever preferred_lft forever\n" "2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000\n" " link/ether 52:54:00:d7:d6:08 brd ff:ff:ff:ff:ff:ff\n" " inet 192.168.122.101/24 brd 192.168.122.255 scope global eth0\n" " inet6 fe80::5054:ff:fed7:d608/64 scope link\n" " valid_lft forever preferred_lft forever" msgstr "" #. Tag: para #, no-c-format msgid "Now check the default route setting:" msgstr "" #. Tag: programlisting #, no-c-format msgid "" "[root@pcmk-1 ~]# ip route\n" "default via 192.168.122.1 dev eth0\n" "192.168.122.0/24 dev eth0 proto kernel scope link src 192.168.122.101" msgstr "" #. Tag: para #, no-c-format msgid "If there is no line beginning with default via, then you may need to add a line such as" msgstr "" #. Tag: programlisting #, no-c-format msgid "GATEWAY=192.168.122.1" msgstr "" #. Tag: para #, no-c-format msgid "to /etc/sysconfig/network and restart the network." msgstr "" #. Tag: para #, no-c-format msgid "Now check for connectivity to the outside world. Start small by testing if we can read the gateway we configured." msgstr "" #. Tag: programlisting #, fuzzy, no-c-format msgid "" "# ping -c 1 192.168.122.1\n" "PING 192.168.122.1 (192.168.122.1) 56(84) bytes of data.\n" "64 bytes from 192.168.122.1: icmp_req=1 ttl=64 time=0.249 ms\n" "\n" "--- 192.168.122.1 ping statistics ---\n" "1 packets transmitted, 1 received, 0% packet loss, time 0ms\n" "rtt min/avg/max/mdev = 0.249/0.249/0.249/0.000 ms" msgstr "" "\n" "\t ping -c 3 192.168.122.102\n" "[root@pcmk-1 ~]# ping -c 3 192.168.122.102\n" "PING 192.168.122.102 (192.168.122.102) 56(84) bytes of data.\n" "64 bytes from 192.168.122.102: icmp_seq=1 ttl=64 time=0.343 ms\n" "64 bytes from 192.168.122.102: icmp_seq=2 ttl=64 time=0.402 ms\n" "64 bytes from 192.168.122.102: icmp_seq=3 ttl=64 time=0.558 ms\n" "\n" "--- 192.168.122.102 ping statistics ---\n" "3 packets transmitted, 3 received, 0% packet loss, time 2000ms\n" "rtt min/avg/max/mdev = 0.343/0.434/0.558/0.092 ms\n" "\t" #. Tag: para #, no-c-format msgid "Now try something external, choose a location you know will be available." msgstr "" #. Tag: programlisting #, no-c-format msgid "" "# ping -c 1 www.google.com\n" "PING www.l.google.com (173.194.72.106) 56(84) bytes of data.\n" "64 bytes from tf-in-f106.1e100.net (173.194.72.106): icmp_req=1 ttl=41 time=167 ms\n" "\n" "--- www.l.google.com ping statistics ---\n" "1 packets transmitted, 1 received, 0% packet loss, time 0ms\n" "rtt min/avg/max/mdev = 167.618/167.618/167.618/0.000 ms" msgstr "" #. Tag: title #, no-c-format msgid "Leaving the Console" msgstr "" #. Tag: para #, no-c-format msgid "The console isn’t a very friendly place to work from, we will now switch to accessing the machine remotely via SSH where we can use copy&paste etc." msgstr "" #. Tag: para #, no-c-format msgid "First we check we can see the newly installed at all:" msgstr "" #. Tag: programlisting #, fuzzy, no-c-format msgid "" "beekhof@f16 ~ # ping -c 1 192.168.122.101\n" "PING 192.168.122.101 (192.168.122.101) 56(84) bytes of data.\n" "64 bytes from 192.168.122.101: icmp_req=1 ttl=64 time=1.01 ms\n" "\n" "--- 192.168.122.101 ping statistics ---\n" "1 packets transmitted, 1 received, 0% packet loss, time 0ms\n" "rtt min/avg/max/mdev = 1.012/1.012/1.012/0.000 ms" msgstr "" "\n" "\t ping -c 3 192.168.122.102\n" "[root@pcmk-1 ~]# ping -c 3 192.168.122.102\n" "PING 192.168.122.102 (192.168.122.102) 56(84) bytes of data.\n" "64 bytes from 192.168.122.102: icmp_seq=1 ttl=64 time=0.343 ms\n" "64 bytes from 192.168.122.102: icmp_seq=2 ttl=64 time=0.402 ms\n" "64 bytes from 192.168.122.102: icmp_seq=3 ttl=64 time=0.558 ms\n" "\n" "--- 192.168.122.102 ping statistics ---\n" "3 packets transmitted, 3 received, 0% packet loss, time 2000ms\n" "rtt min/avg/max/mdev = 0.343/0.434/0.558/0.092 ms\n" "\t" #. Tag: para #, no-c-format msgid "Next we login via SSH" msgstr "" #. Tag: programlisting #, no-c-format msgid "" "beekhof@f16 ~ # ssh -l root 192.168.122.11\n" "root@192.168.122.11's password:\n" "Last login: Fri Mar 30 19:41:19 2012 from 192.168.122.1\n" "[root@pcmk-1 ~]#" msgstr "" #. Tag: title #, no-c-format msgid "Security Shortcuts" msgstr "安全提示" #. Tag: para #, fuzzy, no-c-format msgid "To simplify this guide and focus on the aspects directly connected to clustering, we will now disable the machine’s firewall and SELinux installation." msgstr "为了简化本文档并更好的关注集群方面的问题,我们现在在先禁用防火墙和SELinux。这些操作都会导致重大的安全问题,并不推荐对公网上的集群这样做。" #. Tag: para #, fuzzy, no-c-format msgid "Both of these actions create significant security issues and should not be performed on machines that will be exposed to the outside world." msgstr "为了简化本文档并更好的关注集群方面的问题,我们现在在先禁用防火墙和SELinux。这些操作都会导致重大的安全问题,并不推荐对公网上的集群这样做。" #. Tag: literallayout #, no-c-format msgid "TODO: Create an Appendix that deals with (at least) re-enabling the firewall." msgstr "TODO: Create an Appendix that deals with (at least) re-enabling the firewall." #. Tag: programlisting #, no-c-format msgid "" "# setenforce 0\n" "# sed -i.bak \"s/SELINUX=enforcing/SELINUX=permissive/g\" /etc/selinux/config\n" "# systemctl disable iptables.service\n" "# rm '/etc/systemd/system/basic.target.wants/iptables.service'\n" "# systemctl stop iptables.service" msgstr "" #. Tag: title #, no-c-format msgid "Short Node Names" msgstr "简化节点名称" #. Tag: para #, fuzzy, no-c-format msgid "During installation, we filled in the machine’s fully qualifier domain name (FQDN) which can be rather long when it appears in cluster logs and status output. See for yourself how the machine identifies itself: Nodesshort name short name " msgstr "在安装过程中,我们发现FQDN域名太长了,不利于在日志或状态界面中查看,我们用以下操作来简化机器名:" #. Tag: programlisting #, no-c-format msgid "" "# uname -n\n" "pcmk-1.clusterlabs.org\n" "# dnsdomainname\n" "clusterlabs.org" msgstr "" #. Tag: para #, no-c-format msgid " NodesDomain name (Query) Domain name (Query) " msgstr "" #. Tag: para #, no-c-format msgid "The output from the second command is fine, but we really don’t need the domain name included in the basic host details. To address this, we need to update /etc/sysconfig/network. This is what it should look like before we start." msgstr "第二个命令的输出是正常的,但是我们真的不需要这么详细的输出,我们更改/etc/sysconfig/network文件来达到简化的目的。" #. Tag: programlisting #, fuzzy, no-c-format msgid "" "# cat /etc/sysconfig/network\n" "NETWORKING=yes\n" "HOSTNAME=pcmk-1.clusterlabs.org\n" "GATEWAY=192.168.122.1" msgstr "" "\n" "[root@pcmk-1 ~]# cat /etc/sysconfig/network\n" "NETWORKING=yes\n" "HOSTNAME=pcmk-1.clusterlabs.org\n" "GATEWAY=192.168.122.1\n" " " #. Tag: para #, no-c-format msgid "All we need to do now is strip off the domain name portion, which is stored elsewhere anyway." msgstr "我们要做的只是要把域名后面的部分去掉。" #. Tag: programlisting #, fuzzy, no-c-format msgid " # sed -i.sed 's/\\.[a-z].*//g' /etc/sysconfig/network" msgstr "[root@pcmk-1 ~]# sed -i.bak 's/\\.[a-z].*//g' /etc/sysconfig/network" #. Tag: para #, no-c-format msgid "Now confirm the change was successful. The revised file contents should look something like this." msgstr "现在cat一下看看更改是否成功了。" #. Tag: programlisting #, fuzzy, no-c-format msgid "" "# cat /etc/sysconfig/network\n" "NETWORKING=yes\n" "HOSTNAME=pcmk-1\n" "GATEWAY=192.168.122.1" msgstr "" "\n" "[root@pcmk-1 ~]# cat /etc/sysconfig/network\n" "NETWORKING=yes\n" "HOSTNAME=pcmk-1\n" "GATEWAY=192.168.122.1\n" " " #. Tag: para #, no-c-format msgid "However we’re not finished. The machine wont normally see the shortened host name until about it reboots, but we can force it to update." msgstr "然而到这里还没结束,机器还没接受新的配置文件,我们强制它生效。" #. Tag: programlisting #, no-c-format msgid "" "# source /etc/sysconfig/network\n" "# hostname $HOSTNAME" msgstr "" #. Tag: para #, no-c-format msgid " NodesDomain name (Remove from host name) Domain name (Remove from host name) " msgstr "" #. Tag: para #, no-c-format msgid "Now check the machine is using the correct names" msgstr "现在我们看看是否按达到我们预期的效果:" #. Tag: programlisting #, no-c-format msgid "" "# uname -n\n" "pcmk-1\n" "# dnsdomainname\n" "clusterlabs.org" msgstr "" #. Tag: title #, no-c-format msgid "NTP" msgstr "" #. Tag: para #, no-c-format msgid "It is highly recommended to enable NTP on your cluster nodes. Doing so ensures all nodes agree on the current time and makes reading log files significantly easier. http://docs.fedoraproject.org/en-US/Fedora/17/html-single/System_Administrators_Guide/index.html#ch-Configuring_the_Date_and_Time" msgstr "" #. Tag: title #, no-c-format msgid "Before You Continue" msgstr "写在开始之前" #. Tag: para #, fuzzy, no-c-format msgid "Repeat the Installation steps so far, so that you have two Fedora nodes ready to have the cluster software installed." msgstr "在另一台Fedora 12机器上面重复以上操作步骤,这样你就有2台安装了集群软件的节点了。" #. Tag: para #, fuzzy, no-c-format msgid "For the purposes of this document, the additional node is called pcmk-2 with address 192.168.122.102." msgstr "在这篇文档中, 另外一个节点叫 pcmk-2 并且IP地址为 192.168.122.42。" #. Tag: title #, no-c-format msgid "Finalize Networking" msgstr "设定网络" #. Tag: para #, fuzzy, no-c-format msgid "Confirm that you can communicate between the two new nodes:" msgstr "确认这两个新节点能够通讯:" #. Tag: programlisting #, fuzzy, no-c-format msgid "" "# ping -c 3 192.168.122.102\n" "PING 192.168.122.102 (192.168.122.102) 56(84) bytes of data.\n" "64 bytes from 192.168.122.102: icmp_seq=1 ttl=64 time=0.343 ms\n" "64 bytes from 192.168.122.102: icmp_seq=2 ttl=64 time=0.402 ms\n" "64 bytes from 192.168.122.102: icmp_seq=3 ttl=64 time=0.558 ms\n" "\n" "--- 192.168.122.102 ping statistics ---\n" "3 packets transmitted, 3 received, 0% packet loss, time 2000ms\n" "rtt min/avg/max/mdev = 0.343/0.434/0.558/0.092 ms" msgstr "" "\n" "\t ping -c 3 192.168.122.102\n" "[root@pcmk-1 ~]# ping -c 3 192.168.122.102\n" "PING 192.168.122.102 (192.168.122.102) 56(84) bytes of data.\n" "64 bytes from 192.168.122.102: icmp_seq=1 ttl=64 time=0.343 ms\n" "64 bytes from 192.168.122.102: icmp_seq=2 ttl=64 time=0.402 ms\n" "64 bytes from 192.168.122.102: icmp_seq=3 ttl=64 time=0.558 ms\n" "\n" "--- 192.168.122.102 ping statistics ---\n" "3 packets transmitted, 3 received, 0% packet loss, time 2000ms\n" "rtt min/avg/max/mdev = 0.343/0.434/0.558/0.092 ms\n" "\t" #. Tag: para #, fuzzy, no-c-format msgid "Now we need to make sure we can communicate with the machines by their name. If you have a DNS server, add additional entries for the two machines. Otherwise, you’ll need to add the machines to /etc/hosts . Below are the entries for my cluster nodes:" msgstr "现在我们需要确认我们能通过机器名访问这两台机器,如果你有一个DNS服务器,为这两台节点做域名解析。" #. Tag: programlisting #, fuzzy, no-c-format msgid "" "# grep pcmk /etc/hosts\n" "192.168.122.101 pcmk-1.clusterlabs.org pcmk-1\n" "192.168.122.102 pcmk-2.clusterlabs.org pcmk-2" msgstr "" "\n" "\t grep pcmk /etc/hosts\n" "[root@pcmk-1 ~]# grep pcmk /etc/hosts\n" "192.168.122.101 pcmk-1.clusterlabs.org pcmk-1\n" "192.168.122.102 pcmk-2.clusterlabs.org pcmk-2\n" "\t" #. Tag: para #, no-c-format msgid "We can now verify the setup by again using ping:" msgstr "现在让我们ping一下:" #. Tag: programlisting #, fuzzy, no-c-format msgid "" "# ping -c 3 pcmk-2\n" "PING pcmk-2.clusterlabs.org (192.168.122.101) 56(84) bytes of data.\n" "64 bytes from pcmk-1.clusterlabs.org (192.168.122.101): icmp_seq=1 ttl=64 time=0.164 ms\n" "64 bytes from pcmk-1.clusterlabs.org (192.168.122.101): icmp_seq=2 ttl=64 time=0.475 ms\n" "64 bytes from pcmk-1.clusterlabs.org (192.168.122.101): icmp_seq=3 ttl=64 time=0.186 ms\n" "\n" "--- pcmk-2.clusterlabs.org ping statistics ---\n" "3 packets transmitted, 3 received, 0% packet loss, time 2001ms\n" "rtt min/avg/max/mdev = 0.164/0.275/0.475/0.141 ms" msgstr "" "\n" "\t ping -c 3 pcmk-2\n" "[root@pcmk-1 ~]# ping -c 3 pcmk-2\n" "PING pcmk-2.clusterlabs.org (192.168.122.101) 56(84) bytes of data.\n" "64 bytes from pcmk-1.clusterlabs.org (192.168.122.101): icmp_seq=1 ttl=64 time=0.164 ms\n" "64 bytes from pcmk-1.clusterlabs.org (192.168.122.101): icmp_seq=2 ttl=64 time=0.475 ms\n" "64 bytes from pcmk-1.clusterlabs.org (192.168.122.101): icmp_seq=3 ttl=64 time=0.186 ms\n" "\n" "--- pcmk-2.clusterlabs.org ping statistics ---\n" "3 packets transmitted, 3 received, 0% packet loss, time 2001ms\n" "rtt min/avg/max/mdev = 0.164/0.275/0.475/0.141 ms\n" "\t" #. Tag: title #, no-c-format msgid "Configure SSH" msgstr "配置SSH" #. Tag: para #, fuzzy, no-c-format msgid "SSH is a convenient and secure way to copy files and perform commands remotely. For the purposes of this guide, we will create a key without a password (using the -N option) so that we can perform remote actions without being prompted." msgstr "SSH 是一个方便又安全来的用来远程传输文件或运行命令 的工具. 在这个文档中, 我们创建ssh key(用 -N “” 选项)来免去登入要输入密码的麻烦。" #. Tag: para #, no-c-format msgid " SSH " msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "Unprotected SSH keys, those without a password, are not recommended for servers exposed to the outside world. We use them here only to simplify the demo." msgstr "不推荐在公网的机器上采用未用密码保护的ssh-key" #. Tag: para #, no-c-format msgid "Create a new key and allow anyone with that key to log in:" msgstr "创建一个密钥并允许所有有这个密钥的用户登入" #. Tag: title #, no-c-format msgid "Creating and Activating a new SSH Key" msgstr "创建并激活一个新的SSH密钥" #. Tag: programlisting #, fuzzy, no-c-format msgid "" "# ssh-keygen -t dsa -f ~/.ssh/id_dsa -N \"\"\n" "Generating public/private dsa key pair.\n" "Your identification has been saved in /root/.ssh/id_dsa.\n" "Your public key has been saved in /root/.ssh/id_dsa.pub.\n" "The key fingerprint is:\n" "91:09:5c:82:5a:6a:50:08:4e:b2:0c:62:de:cc:74:44 root@pcmk-1.clusterlabs.org\n" "\n" "The key's randomart image is:\n" "+--[ DSA 1024]----+\n" "|==.ooEo.. |\n" "|X O + .o o |\n" "| * A + |\n" "| + . |\n" "| . S |\n" "| |\n" "| |\n" "| |\n" "| |\n" "+-----------------+\n" "\n" "# cp .ssh/id_dsa.pub .ssh/authorized_keys" msgstr "" "\n" "[root@pcmk-1 ~]# ssh-keygen -t dsa -f ~/.ssh/id_dsa -N \"\"\n" "Generating public/private dsa key pair.\n" "Your identification has been saved in /root/.ssh/id_dsa.\n" "Your public key has been saved in /root/.ssh/id_dsa.pub.\n" "The key fingerprint is:\n" "91:09:5c:82:5a:6a:50:08:4e:b2:0c:62:de:cc:74:44 root@pcmk-1.clusterlabs.org\n" "\n" "The key's randomart image is:\n" "+--[ DSA 1024]----+\n" "|==.ooEo.. |\n" "|X O + .o o |\n" "| * A + |\n" "| + . |\n" "| . S |\n" "| |\n" "| |\n" "| |\n" "| |\n" "+-----------------+\n" "[root@pcmk-1 ~]# cp .ssh/id_dsa.pub .ssh/authorized_keys\n" "[root@pcmk-1 ~]#\n" "\t" #. Tag: para #, fuzzy, no-c-format msgid " Creating and Activating a new SSH Key " msgstr "创建并激活一个新的SSH密钥" #. Tag: para #, no-c-format msgid "Install the key on the other nodes and test that you can now run commands remotely, without being prompted" msgstr "在其他节点安装这个密钥并测试你是否可以执行命令而不用输入密码" #. Tag: title #, no-c-format msgid "Installing the SSH Key on Another Host" msgstr "在另一个机器上面安装SSH密钥" #. Tag: programlisting #, fuzzy, no-c-format msgid "" "# scp -r .ssh pcmk-2:\n" "The authenticity of host 'pcmk-2 (192.168.122.102)' can't be established.\n" "RSA key fingerprint is b1:2b:55:93:f1:d9:52:2b:0f:f2:8a:4e:ae:c6:7c:9a.\n" "Are you sure you want to continue connecting (yes/no)? yes\n" "Warning: Permanently added 'pcmk-2,192.168.122.102' (RSA) to the list of known hosts.root@pcmk-2's password:\n" "id_dsa.pub 100% 616 0.6KB/s 00:00\n" "id_dsa 100% 672 0.7KB/s 00:00\n" "known_hosts 100% 400 0.4KB/s 00:00\n" "authorized_keys 100% 616 0.6KB/s 00:00\n" "# ssh pcmk-2 -- uname -n\n" "pcmk-2\n" "#" msgstr "" "\n" "[root@pcmk-1 ~]# scp -r .ssh pcmk-2:\n" "The authenticity of host 'pcmk-2 (192.168.122.102)' can't be established.\n" "RSA key fingerprint is b1:2b:55:93:f1:d9:52:2b:0f:f2:8a:4e:ae:c6:7c:9a.\n" "Are you sure you want to continue connecting (yes/no)? yes\n" "Warning: Permanently added 'pcmk-2,192.168.122.102' (RSA) to the list of known hosts.\n" "root@pcmk-2's password: \n" "id_dsa.pub 100% 616 0.6KB/s 00:00 \n" "id_dsa 100% 672 0.7KB/s 00:00 \n" "known_hosts 100% 400 0.4KB/s 00:00 \n" "authorized_keys 100% 616 0.6KB/s 00:00 \n" "[root@pcmk-1 ~]# ssh pcmk-2 -- uname -n\n" "pcmk-2\n" "[root@pcmk-1 ~]#\n" "\t" #. Tag: title #, no-c-format msgid "Cluster Software Installation" msgstr "集群软件安装" #. Tag: title #, no-c-format msgid "Install the Cluster Software" msgstr "安装集群软件" #. Tag: para #, no-c-format msgid "Since version 12, Fedora comes with recent versions of everything you need, so simply fire up the shell and run:" msgstr "从Fedora 12开始,你需要的东西都已经准备好了,只需在终端命令行运行以下命令:" #. Tag: programlisting #, no-c-format msgid "# yum install -y pacemaker corosync" msgstr "" #. Tag: literallayout #, no-c-format msgid "" "fedora/metalink | 38 kB 00:00\n" "fedora | 4.2 kB 00:00\n" "fedora/primary_db | 14 MB 00:21\n" "updates/metalink | 2.7 kB 00:00\n" "updates | 2.6 kB 00:00\n" "updates/primary_db | 1.2 kB 00:00\n" "updates-testing/metalink | 28 kB 00:00\n" "updates-testing | 4.5 kB 00:00\n" "updates-testing/primary_db | 4.5 MB 00:12\n" "Setting up Install Process\n" "Resolving Dependencies\n" "--> Running transaction check\n" "---> Package corosync.x86_64 0:1.99.9-1.fc17 will be installed\n" "--> Processing Dependency: corosynclib = 1.99.9-1.fc17 for package: corosync-1.99.9-1.fc17.x86_64\n" "--> Processing Dependency: libxslt for package: corosync-1.99.9-1.fc17.x86_64\n" "--> Processing Dependency: libvotequorum.so.5(COROSYNC_VOTEQUORUM_1.0)(64bit) for package: corosync-1.99.9-1.fc17.x86_64\n" "--> Processing Dependency: libquorum.so.5(COROSYNC_QUORUM_1.0)(64bit) for package: corosync-1.99.9-1.fc17.x86_64\n" "--> Processing Dependency: libcpg.so.4(COROSYNC_CPG_1.0)(64bit) for package: corosync-1.99.9-1.fc17.x86_64\n" "--> Processing Dependency: libcmap.so.4(COROSYNC_CMAP_1.0)(64bit) for package: corosync-1.99.9-1.fc17.x86_64\n" "--> Processing Dependency: libcfg.so.6(COROSYNC_CFG_0.82)(64bit) for package: corosync-1.99.9-1.fc17.x86_64\n" "--> Processing Dependency: libvotequorum.so.5()(64bit) for package: corosync-1.99.9-1.fc17.x86_64\n" "--> Processing Dependency: libtotem_pg.so.5()(64bit) for package: corosync-1.99.9-1.fc17.x86_64\n" "--> Processing Dependency: libquorum.so.5()(64bit) for package: corosync-1.99.9-1.fc17.x86_64\n" "--> Processing Dependency: libqb.so.0()(64bit) for package: corosync-1.99.9-1.fc17.x86_64\n" "--> Processing Dependency: libnetsnmp.so.30()(64bit) for package: corosync-1.99.9-1.fc17.x86_64\n" "--> Processing Dependency: libcpg.so.4()(64bit) for package: corosync-1.99.9-1.fc17.x86_64\n" "--> Processing Dependency: libcorosync_common.so.4()(64bit) for package: corosync-1.99.9-1.fc17.x86_64\n" "--> Processing Dependency: libcmap.so.4()(64bit) for package: corosync-1.99.9-1.fc17.x86_64\n" "--> Processing Dependency: libcfg.so.6()(64bit) for package: corosync-1.99.9-1.fc17.x86_64\n" "---> Package pacemaker.x86_64 0:1.1.7-2.fc17 will be installed\n" "--> Processing Dependency: pacemaker-libs = 1.1.7-2.fc17 for package: pacemaker-1.1.7-2.fc17.x86_64\n" "--> Processing Dependency: pacemaker-cluster-libs = 1.1.7-2.fc17 for package: pacemaker-1.1.7-2.fc17.x86_64\n" "--> Processing Dependency: pacemaker-cli = 1.1.7-2.fc17 for package: pacemaker-1.1.7-2.fc17.x86_64\n" "--> Processing Dependency: resource-agents for package: pacemaker-1.1.7-2.fc17.x86_64\n" "--> Processing Dependency: perl(Getopt::Long) for package: pacemaker-1.1.7-2.fc17.x86_64\n" "--> Processing Dependency: libgnutls.so.26(GNUTLS_1_4)(64bit) for package: pacemaker-1.1.7-2.fc17.x86_64\n" "--> Processing Dependency: cluster-glue for package: pacemaker-1.1.7-2.fc17.x86_64\n" "--> Processing Dependency: /usr/bin/perl for package: pacemaker-1.1.7-2.fc17.x86_64\n" "--> Processing Dependency: libtransitioner.so.1()(64bit) for package: pacemaker-1.1.7-2.fc17.x86_64\n" "--> Processing Dependency: libstonithd.so.1()(64bit) for package: pacemaker-1.1.7-2.fc17.x86_64\n" "--> Processing Dependency: libstonith.so.1()(64bit) for package: pacemaker-1.1.7-2.fc17.x86_64\n" "--> Processing Dependency: libplumb.so.2()(64bit) for package: pacemaker-1.1.7-2.fc17.x86_64\n" "--> Processing Dependency: libpils.so.2()(64bit) for package: pacemaker-1.1.7-2.fc17.x86_64\n" "--> Processing Dependency: libpengine.so.3()(64bit) for package: pacemaker-1.1.7-2.fc17.x86_64\n" "--> Processing Dependency: libpe_status.so.3()(64bit) for package: pacemaker-1.1.7-2.fc17.x86_64\n" "--> Processing Dependency: libpe_rules.so.2()(64bit) for package: pacemaker-1.1.7-2.fc17.x86_64\n" "--> Processing Dependency: libltdl.so.7()(64bit) for package: pacemaker-1.1.7-2.fc17.x86_64\n" "--> Processing Dependency: liblrm.so.2()(64bit) for package: pacemaker-1.1.7-2.fc17.x86_64\n" "--> Processing Dependency: libgnutls.so.26()(64bit) for package: pacemaker-1.1.7-2.fc17.x86_64\n" "--> Processing Dependency: libcrmcommon.so.2()(64bit) for package: pacemaker-1.1.7-2.fc17.x86_64\n" "--> Processing Dependency: libcrmcluster.so.1()(64bit) for package: pacemaker-1.1.7-2.fc17.x86_64\n" "--> Processing Dependency: libcib.so.1()(64bit) for package: pacemaker-1.1.7-2.fc17.x86_64\n" "--> Running transaction check\n" "---> Package cluster-glue.x86_64 0:1.0.6-9.fc17.1 will be installed\n" "--> Processing Dependency: perl-TimeDate for package: cluster-glue-1.0.6-9.fc17.1.x86_64\n" "--> Processing Dependency: libOpenIPMIutils.so.0()(64bit) for package: cluster-glue-1.0.6-9.fc17.1.x86_64\n" "--> Processing Dependency: libOpenIPMIposix.so.0()(64bit) for package: cluster-glue-1.0.6-9.fc17.1.x86_64\n" "--> Processing Dependency: libOpenIPMI.so.0()(64bit) for package: cluster-glue-1.0.6-9.fc17.1.x86_64\n" "---> Package cluster-glue-libs.x86_64 0:1.0.6-9.fc17.1 will be installed\n" "---> Package corosynclib.x86_64 0:1.99.9-1.fc17 will be installed\n" "--> Processing Dependency: librdmacm.so.1(RDMACM_1.0)(64bit) for package: corosynclib-1.99.9-1.fc17.x86_64\n" "--> Processing Dependency: libibverbs.so.1(IBVERBS_1.1)(64bit) for package: corosynclib-1.99.9-1.fc17.x86_64\n" "--> Processing Dependency: libibverbs.so.1(IBVERBS_1.0)(64bit) for package: corosynclib-1.99.9-1.fc17.x86_64\n" "--> Processing Dependency: librdmacm.so.1()(64bit) for package: corosynclib-1.99.9-1.fc17.x86_64\n" "--> Processing Dependency: libibverbs.so.1()(64bit) for package: corosynclib-1.99.9-1.fc17.x86_64\n" "---> Package gnutls.x86_64 0:2.12.17-1.fc17 will be installed\n" "--> Processing Dependency: libtasn1.so.3(LIBTASN1_0_3)(64bit) for package: gnutls-2.12.17-1.fc17.x86_64\n" "--> Processing Dependency: libtasn1.so.3()(64bit) for package: gnutls-2.12.17-1.fc17.x86_64\n" "--> Processing Dependency: libp11-kit.so.0()(64bit) for package: gnutls-2.12.17-1.fc17.x86_64\n" "---> Package libqb.x86_64 0:0.11.1-1.fc17 will be installed\n" "---> Package libtool-ltdl.x86_64 0:2.4.2-3.fc17 will be installed\n" "---> Package libxslt.x86_64 0:1.1.26-9.fc17 will be installed\n" "---> Package net-snmp-libs.x86_64 1:5.7.1-4.fc17 will be installed\n" "---> Package pacemaker-cli.x86_64 0:1.1.7-2.fc17 will be installed\n" "---> Package pacemaker-cluster-libs.x86_64 0:1.1.7-2.fc17 will be installed\n" "---> Package pacemaker-libs.x86_64 0:1.1.7-2.fc17 will be installed\n" "---> Package perl.x86_64 4:5.14.2-211.fc17 will be installed\n" "--> Processing Dependency: perl-libs = 4:5.14.2-211.fc17 for package: 4:perl-5.14.2-211.fc17.x86_64\n" "--> Processing Dependency: perl(threads::shared) >= 1.21 for package: 4:perl-5.14.2-211.fc17.x86_64\n" "--> Processing Dependency: perl(Socket) >= 1.3 for package: 4:perl-5.14.2-211.fc17.x86_64\n" "--> Processing Dependency: perl(Scalar::Util) >= 1.10 for package: 4:perl-5.14.2-211.fc17.x86_64\n" "--> Processing Dependency: perl(File::Spec) >= 0.8 for package: 4:perl-5.14.2-211.fc17.x86_64\n" "--> Processing Dependency: perl-macros for package: 4:perl-5.14.2-211.fc17.x86_64\n" "--> Processing Dependency: perl-libs for package: 4:perl-5.14.2-211.fc17.x86_64\n" "--> Processing Dependency: perl(threads::shared) for package: 4:perl-5.14.2-211.fc17.x86_64\n" "--> Processing Dependency: perl(threads) for package: 4:perl-5.14.2-211.fc17.x86_64\n" "--> Processing Dependency: perl(Socket) for package: 4:perl-5.14.2-211.fc17.x86_64\n" "--> Processing Dependency: perl(Scalar::Util) for package: 4:perl-5.14.2-211.fc17.x86_64\n" "--> Processing Dependency: perl(Pod::Simple) for package: 4:perl-5.14.2-211.fc17.x86_64\n" "--> Processing Dependency: perl(Module::Pluggable) for package: 4:perl-5.14.2-211.fc17.x86_64\n" "--> Processing Dependency: perl(List::Util) for package: 4:perl-5.14.2-211.fc17.x86_64\n" "--> Processing Dependency: perl(File::Spec::Unix) for package: 4:perl-5.14.2-211.fc17.x86_64\n" "--> Processing Dependency: perl(File::Spec::Functions) for package: 4:perl-5.14.2-211.fc17.x86_64\n" "--> Processing Dependency: perl(File::Spec) for package: 4:perl-5.14.2-211.fc17.x86_64\n" "--> Processing Dependency: perl(Cwd) for package: 4:perl-5.14.2-211.fc17.x86_64\n" "--> Processing Dependency: perl(Carp) for package: 4:perl-5.14.2-211.fc17.x86_64\n" "--> Processing Dependency: libperl.so()(64bit) for package: 4:perl-5.14.2-211.fc17.x86_64\n" "---> Package resource-agents.x86_64 0:3.9.2-2.fc17.1 will be installed\n" "--> Processing Dependency: /usr/sbin/rpc.nfsd for package: resource-agents-3.9.2-2.fc17.1.x86_64\n" "--> Processing Dependency: /usr/sbin/rpc.mountd for package: resource-agents-3.9.2-2.fc17.1.x86_64\n" "--> Processing Dependency: /usr/sbin/ethtool for package: resource-agents-3.9.2-2.fc17.1.x86_64\n" "--> Processing Dependency: /sbin/rpc.statd for package: resource-agents-3.9.2-2.fc17.1.x86_64\n" "--> Processing Dependency: /sbin/quotaon for package: resource-agents-3.9.2-2.fc17.1.x86_64\n" "--> Processing Dependency: /sbin/quotacheck for package: resource-agents-3.9.2-2.fc17.1.x86_64\n" "--> Processing Dependency: /sbin/mount.nfs4 for package: resource-agents-3.9.2-2.fc17.1.x86_64\n" "--> Processing Dependency: /sbin/mount.nfs for package: resource-agents-3.9.2-2.fc17.1.x86_64\n" "--> Processing Dependency: /sbin/mount.cifs for package: resource-agents-3.9.2-2.fc17.1.x86_64\n" "--> Processing Dependency: /sbin/fsck.xfs for package: resource-agents-3.9.2-2.fc17.1.x86_64\n" "--> Processing Dependency: libnet.so.1()(64bit) for package: resource-agents-3.9.2-2.fc17.1.x86_64\n" "--> Running transaction check\n" "---> Package OpenIPMI-libs.x86_64 0:2.0.18-13.fc17 will be installed\n" "---> Package cifs-utils.x86_64 0:5.3-2.fc17 will be installed\n" "--> Processing Dependency: libtalloc.so.2(TALLOC_2.0.2)(64bit) for package: cifs-utils-5.3-2.fc17.x86_64\n" "--> Processing Dependency: keyutils for package: cifs-utils-5.3-2.fc17.x86_64\n" "--> Processing Dependency: libwbclient.so.0()(64bit) for package: cifs-utils-5.3-2.fc17.x86_64\n" "--> Processing Dependency: libtalloc.so.2()(64bit) for package: cifs-utils-5.3-2.fc17.x86_64\n" "---> Package ethtool.x86_64 2:3.2-2.fc17 will be installed\n" "---> Package libibverbs.x86_64 0:1.1.6-2.fc17 will be installed\n" "---> Package libnet.x86_64 0:1.1.5-3.fc17 will be installed\n" "---> Package librdmacm.x86_64 0:1.0.15-1.fc17 will be installed\n" "---> Package libtasn1.x86_64 0:2.12-1.fc17 will be installed\n" "---> Package nfs-utils.x86_64 1:1.2.5-12.fc17 will be installed\n" "--> Processing Dependency: rpcbind for package: 1:nfs-utils-1.2.5-12.fc17.x86_64\n" "--> Processing Dependency: libtirpc for package: 1:nfs-utils-1.2.5-12.fc17.x86_64\n" "--> Processing Dependency: libnfsidmap for package: 1:nfs-utils-1.2.5-12.fc17.x86_64\n" "--> Processing Dependency: libgssglue.so.1(libgssapi_CITI_2)(64bit) for package: 1:nfs-utils-1.2.5-12.fc17.x86_64\n" "--> Processing Dependency: libgssglue for package: 1:nfs-utils-1.2.5-12.fc17.x86_64\n" "--> Processing Dependency: libevent for package: 1:nfs-utils-1.2.5-12.fc17.x86_64\n" "--> Processing Dependency: libtirpc.so.1()(64bit) for package: 1:nfs-utils-1.2.5-12.fc17.x86_64\n" "--> Processing Dependency: libnfsidmap.so.0()(64bit) for package: 1:nfs-utils-1.2.5-12.fc17.x86_64\n" "--> Processing Dependency: libgssglue.so.1()(64bit) for package: 1:nfs-utils-1.2.5-12.fc17.x86_64\n" "--> Processing Dependency: libevent-2.0.so.5()(64bit) for package: 1:nfs-utils-1.2.5-12.fc17.x86_64\n" "---> Package p11-kit.x86_64 0:0.12-1.fc17 will be installed\n" "---> Package perl-Carp.noarch 0:1.22-2.fc17 will be installed\n" "---> Package perl-Module-Pluggable.noarch 1:3.90-211.fc17 will be installed\n" "---> Package perl-PathTools.x86_64 0:3.33-211.fc17 will be installed\n" "---> Package perl-Pod-Simple.noarch 1:3.16-211.fc17 will be installed\n" "--> Processing Dependency: perl(Pod::Escapes) >= 1.04 for package: 1:perl-Pod-Simple-3.16-211.fc17.noarch\n" "---> Package perl-Scalar-List-Utils.x86_64 0:1.25-1.fc17 will be installed\n" "---> Package perl-Socket.x86_64 0:2.001-1.fc17 will be installed\n" "---> Package perl-TimeDate.noarch 1:1.20-6.fc17 will be installed\n" "---> Package perl-libs.x86_64 4:5.14.2-211.fc17 will be installed\n" "---> Package perl-macros.x86_64 4:5.14.2-211.fc17 will be installed\n" "---> Package perl-threads.x86_64 0:1.86-2.fc17 will be installed\n" "---> Package perl-threads-shared.x86_64 0:1.40-2.fc17 will be installed\n" "---> Package quota.x86_64 1:4.00-3.fc17 will be installed\n" "--> Processing Dependency: quota-nls = 1:4.00-3.fc17 for package: 1:quota-4.00-3.fc17.x86_64\n" "--> Processing Dependency: tcp_wrappers for package: 1:quota-4.00-3.fc17.x86_64\n" "---> Package xfsprogs.x86_64 0:3.1.8-1.fc17 will be installed\n" "--> Running transaction check\n" "---> Package keyutils.x86_64 0:1.5.5-2.fc17 will be installed\n" "---> Package libevent.x86_64 0:2.0.14-2.fc17 will be installed\n" "---> Package libgssglue.x86_64 0:0.3-1.fc17 will be installed\n" "---> Package libnfsidmap.x86_64 0:0.25-1.fc17 will be installed\n" "---> Package libtalloc.x86_64 0:2.0.7-4.fc17 will be installed\n" "---> Package libtirpc.x86_64 0:0.2.2-2.1.fc17 will be installed\n" "---> Package libwbclient.x86_64 1:3.6.3-81.fc17.1 will be installed\n" "---> Package perl-Pod-Escapes.noarch 1:1.04-211.fc17 will be installed\n" "---> Package quota-nls.noarch 1:4.00-3.fc17 will be installed\n" "---> Package rpcbind.x86_64 0:0.2.0-16.fc17 will be installed\n" "---> Package tcp_wrappers.x86_64 0:7.6-69.fc17 will be installed\n" "--> Finished Dependency Resolution\n" "\n" "Dependencies Resolved\n" "\n" "=====================================================================================\n" " Package Arch Version Repository Size\n" "=====================================================================================\n" "Installing:\n" " corosync x86_64 1.99.9-1.fc17 updates-testing 159 k\n" " pacemaker x86_64 1.1.7-2.fc17 updates-testing 362 k\n" "Installing for dependencies:\n" " OpenIPMI-libs x86_64 2.0.18-13.fc17 fedora 466 k\n" " cifs-utils x86_64 5.3-2.fc17 updates-testing 66 k\n" " cluster-glue x86_64 1.0.6-9.fc17.1 fedora 229 k\n" " cluster-glue-libs x86_64 1.0.6-9.fc17.1 fedora 121 k\n" " corosynclib x86_64 1.99.9-1.fc17 updates-testing 96 k\n" " ethtool x86_64 2:3.2-2.fc17 fedora 94 k\n" " gnutls x86_64 2.12.17-1.fc17 fedora 385 k\n" " keyutils x86_64 1.5.5-2.fc17 fedora 49 k\n" " libevent x86_64 2.0.14-2.fc17 fedora 160 k\n" " libgssglue x86_64 0.3-1.fc17 fedora 24 k\n" " libibverbs x86_64 1.1.6-2.fc17 fedora 44 k\n" " libnet x86_64 1.1.5-3.fc17 fedora 54 k\n" " libnfsidmap x86_64 0.25-1.fc17 fedora 34 k\n" " libqb x86_64 0.11.1-1.fc17 updates-testing 68 k\n" " librdmacm x86_64 1.0.15-1.fc17 fedora 27 k\n" " libtalloc x86_64 2.0.7-4.fc17 fedora 22 k\n" " libtasn1 x86_64 2.12-1.fc17 updates-testing 319 k\n" " libtirpc x86_64 0.2.2-2.1.fc17 fedora 78 k\n" " libtool-ltdl x86_64 2.4.2-3.fc17 fedora 45 k\n" " libwbclient x86_64 1:3.6.3-81.fc17.1 updates-testing 68 k\n" " libxslt x86_64 1.1.26-9.fc17 fedora 416 k\n" " net-snmp-libs x86_64 1:5.7.1-4.fc17 fedora 713 k\n" " nfs-utils x86_64 1:1.2.5-12.fc17 fedora 311 k\n" " p11-kit x86_64 0.12-1.fc17 updates-testing 36 k\n" " pacemaker-cli x86_64 1.1.7-2.fc17 updates-testing 368 k\n" " pacemaker-cluster-libs x86_64 1.1.7-2.fc17 updates-testing 77 k\n" " pacemaker-libs x86_64 1.1.7-2.fc17 updates-testing 322 k\n" " perl x86_64 4:5.14.2-211.fc17 fedora 10 M\n" " perl-Carp noarch 1.22-2.fc17 fedora 17 k\n" " perl-Module-Pluggable noarch 1:3.90-211.fc17 fedora 47 k\n" " perl-PathTools x86_64 3.33-211.fc17 fedora 105 k\n" " perl-Pod-Escapes noarch 1:1.04-211.fc17 fedora 40 k\n" " perl-Pod-Simple noarch 1:3.16-211.fc17 fedora 223 k\n" " perl-Scalar-List-Utils x86_64 1.25-1.fc17 updates-testing 33 k\n" " perl-Socket x86_64 2.001-1.fc17 updates-testing 44 k\n" " perl-TimeDate noarch 1:1.20-6.fc17 fedora 43 k\n" " perl-libs x86_64 4:5.14.2-211.fc17 fedora 628 k\n" " perl-macros x86_64 4:5.14.2-211.fc17 fedora 32 k\n" " perl-threads x86_64 1.86-2.fc17 fedora 47 k\n" " perl-threads-shared x86_64 1.40-2.fc17 fedora 36 k\n" " quota x86_64 1:4.00-3.fc17 fedora 160 k\n" " quota-nls noarch 1:4.00-3.fc17 fedora 74 k\n" " resource-agents x86_64 3.9.2-2.fc17.1 fedora 466 k\n" " rpcbind x86_64 0.2.0-16.fc17 fedora 52 k\n" " tcp_wrappers x86_64 7.6-69.fc17 fedora 72 k\n" " xfsprogs x86_64 3.1.8-1.fc17 updates-testing 715 k\n" "\n" "Transaction Summary\n" "=====================================================================================\n" "Install 2 Packages (+46 Dependent packages)\n" "\n" "Total download size: 18 M\n" "Installed size: 59 M\n" "Downloading Packages:\n" "(1/48): OpenIPMI-libs-2.0.18-13.fc17.x86_64.rpm | 466 kB 00:00\n" "warning: rpmts_HdrFromFdno: Header V3 RSA/SHA256 Signature, key ID 1aca3465: NOKEY\n" "Public key for OpenIPMI-libs-2.0.18-13.fc17.x86_64.rpm is not installed\n" "(2/48): cifs-utils-5.3-2.fc17.x86_64.rpm | 66 kB 00:01\n" "Public key for cifs-utils-5.3-2.fc17.x86_64.rpm is not installed\n" "(3/48): cluster-glue-1.0.6-9.fc17.1.x86_64.rpm | 229 kB 00:00\n" "(4/48): cluster-glue-libs-1.0.6-9.fc17.1.x86_64.rpm | 121 kB 00:00\n" "(5/48): corosync-1.99.9-1.fc17.x86_64.rpm | 159 kB 00:01\n" "(6/48): corosynclib-1.99.9-1.fc17.x86_64.rpm | 96 kB 00:00\n" "(7/48): ethtool-3.2-2.fc17.x86_64.rpm | 94 kB 00:00\n" "(8/48): gnutls-2.12.17-1.fc17.x86_64.rpm | 385 kB 00:00\n" "(9/48): keyutils-1.5.5-2.fc17.x86_64.rpm | 49 kB 00:00\n" "(10/48): libevent-2.0.14-2.fc17.x86_64.rpm | 160 kB 00:00\n" "(11/48): libgssglue-0.3-1.fc17.x86_64.rpm | 24 kB 00:00\n" "(12/48): libibverbs-1.1.6-2.fc17.x86_64.rpm | 44 kB 00:00\n" "(13/48): libnet-1.1.5-3.fc17.x86_64.rpm | 54 kB 00:00\n" "(14/48): libnfsidmap-0.25-1.fc17.x86_64.rpm | 34 kB 00:00\n" "(15/48): libqb-0.11.1-1.fc17.x86_64.rpm | 68 kB 00:01\n" "(16/48): librdmacm-1.0.15-1.fc17.x86_64.rpm | 27 kB 00:00\n" "(17/48): libtalloc-2.0.7-4.fc17.x86_64.rpm | 22 kB 00:00\n" "(18/48): libtasn1-2.12-1.fc17.x86_64.rpm | 319 kB 00:02\n" "(19/48): libtirpc-0.2.2-2.1.fc17.x86_64.rpm | 78 kB 00:00\n" "(20/48): libtool-ltdl-2.4.2-3.fc17.x86_64.rpm | 45 kB 00:00\n" "(21/48): libwbclient-3.6.3-81.fc17.1.x86_64.rpm | 68 kB 00:00\n" "(22/48): libxslt-1.1.26-9.fc17.x86_64.rpm | 416 kB 00:00\n" "(23/48): net-snmp-libs-5.7.1-4.fc17.x86_64.rpm | 713 kB 00:01\n" "(24/48): nfs-utils-1.2.5-12.fc17.x86_64.rpm | 311 kB 00:00\n" "(25/48): p11-kit-0.12-1.fc17.x86_64.rpm | 36 kB 00:01\n" "(26/48): pacemaker-1.1.7-2.fc17.x86_64.rpm | 362 kB 00:02\n" "(27/48): pacemaker-cli-1.1.7-2.fc17.x86_64.rpm | 368 kB 00:02\n" "(28/48): pacemaker-cluster-libs-1.1.7-2.fc17.x86_64.rpm | 77 kB 00:00\n" "(29/48): pacemaker-libs-1.1.7-2.fc17.x86_64.rpm | 322 kB 00:01\n" "(30/48): perl-5.14.2-211.fc17.x86_64.rpm | 10 MB 00:15\n" "(31/48): perl-Carp-1.22-2.fc17.noarch.rpm | 17 kB 00:00\n" "(32/48): perl-Module-Pluggable-3.90-211.fc17.noarch.rpm | 47 kB 00:00\n" "(33/48): perl-PathTools-3.33-211.fc17.x86_64.rpm | 105 kB 00:00\n" "(34/48): perl-Pod-Escapes-1.04-211.fc17.noarch.rpm | 40 kB 00:00\n" "(35/48): perl-Pod-Simple-3.16-211.fc17.noarch.rpm | 223 kB 00:00\n" "(36/48): perl-Scalar-List-Utils-1.25-1.fc17.x86_64.rpm | 33 kB 00:01\n" "(37/48): perl-Socket-2.001-1.fc17.x86_64.rpm | 44 kB 00:00\n" "(38/48): perl-TimeDate-1.20-6.fc17.noarch.rpm | 43 kB 00:00\n" "(39/48): perl-libs-5.14.2-211.fc17.x86_64.rpm | 628 kB 00:00\n" "(40/48): perl-macros-5.14.2-211.fc17.x86_64.rpm | 32 kB 00:00\n" "(41/48): perl-threads-1.86-2.fc17.x86_64.rpm | 47 kB 00:00\n" "(42/48): perl-threads-shared-1.40-2.fc17.x86_64.rpm | 36 kB 00:00\n" "(43/48): quota-4.00-3.fc17.x86_64.rpm | 160 kB 00:00\n" "(44/48): quota-nls-4.00-3.fc17.noarch.rpm | 74 kB 00:00\n" "(45/48): resource-agents-3.9.2-2.fc17.1.x86_64.rpm | 466 kB 00:00\n" "(46/48): rpcbind-0.2.0-16.fc17.x86_64.rpm | 52 kB 00:00\n" "(47/48): tcp_wrappers-7.6-69.fc17.x86_64.rpm | 72 kB 00:00\n" "(48/48): xfsprogs-3.1.8-1.fc17.x86_64.rpm | 715 kB 00:03\n" "----------------------------------------------------------------------------------------\n" "Total 333 kB/s | 18 MB 00:55\n" "Retrieving key from file:///etc/pki/rpm-gpg/RPM-GPG-KEY-fedora-x86_64\n" "Importing GPG key 0x1ACA3465:\n" " Userid : \"Fedora (17) <fedora@fedoraproject.org>\"\n" " Fingerprint: cac4 3fb7 74a4 a673 d81c 5de7 50e9 4c99 1aca 3465\n" " Package : fedora-release-17-0.8.noarch (@anaconda-0)\n" " From : /etc/pki/rpm-gpg/RPM-GPG-KEY-fedora-x86_64\n" "Running Transaction Check\n" "Running Transaction Test\n" "Transaction Test Succeeded\n" "Running Transaction\n" " Installing : libqb-0.11.1-1.fc17.x86_64 1/48\n" " Installing : libtool-ltdl-2.4.2-3.fc17.x86_64 2/48\n" " Installing : cluster-glue-libs-1.0.6-9.fc17.1.x86_64 3/48\n" " Installing : libxslt-1.1.26-9.fc17.x86_64 4/48\n" " Installing : 1:perl-Pod-Escapes-1.04-211.fc17.noarch 5/48\n" " Installing : perl-threads-1.86-2.fc17.x86_64 6/48\n" " Installing : 4:perl-macros-5.14.2-211.fc17.x86_64 7/48\n" " Installing : 1:perl-Pod-Simple-3.16-211.fc17.noarch 8/48\n" " Installing : perl-Socket-2.001-1.fc17.x86_64 9/48\n" " Installing : perl-Carp-1.22-2.fc17.noarch 10/48\n" " Installing : 4:perl-libs-5.14.2-211.fc17.x86_64 11/48\n" " Installing : perl-threads-shared-1.40-2.fc17.x86_64 12/48\n" " Installing : perl-Scalar-List-Utils-1.25-1.fc17.x86_64 13/48\n" " Installing : 1:perl-Module-Pluggable-3.90-211.fc17.noarch 14/48\n" " Installing : perl-PathTools-3.33-211.fc17.x86_64 15/48\n" " Installing : 4:perl-5.14.2-211.fc17.x86_64 16/48\n" " Installing : libibverbs-1.1.6-2.fc17.x86_64 17/48\n" " Installing : keyutils-1.5.5-2.fc17.x86_64 18/48\n" " Installing : libgssglue-0.3-1.fc17.x86_64 19/48\n" " Installing : libtirpc-0.2.2-2.1.fc17.x86_64 20/48\n" " Installing : 1:net-snmp-libs-5.7.1-4.fc17.x86_64 21/48\n" " Installing : rpcbind-0.2.0-16.fc17.x86_64 22/48\n" " Installing : librdmacm-1.0.15-1.fc17.x86_64 23/48\n" " Installing : corosynclib-1.99.9-1.fc17.x86_64 24/48\n" " Installing : corosync-1.99.9-1.fc17.x86_64 25/48\n" "error reading information on service corosync: No such file or directory\n" " Installing : 1:perl-TimeDate-1.20-6.fc17.noarch 26/48\n" " Installing : 1:quota-nls-4.00-3.fc17.noarch 27/48\n" " Installing : tcp_wrappers-7.6-69.fc17.x86_64 28/48\n" " Installing : 1:quota-4.00-3.fc17.x86_64 29/48\n" " Installing : libnfsidmap-0.25-1.fc17.x86_64 30/48\n" " Installing : 1:libwbclient-3.6.3-81.fc17.1.x86_64 31/48\n" " Installing : libnet-1.1.5-3.fc17.x86_64 32/48\n" " Installing : 2:ethtool-3.2-2.fc17.x86_64 33/48\n" " Installing : libevent-2.0.14-2.fc17.x86_64 34/48\n" " Installing : 1:nfs-utils-1.2.5-12.fc17.x86_64 35/48\n" " Installing : libtalloc-2.0.7-4.fc17.x86_64 36/48\n" " Installing : cifs-utils-5.3-2.fc17.x86_64 37/48\n" " Installing : libtasn1-2.12-1.fc17.x86_64 38/48\n" " Installing : OpenIPMI-libs-2.0.18-13.fc17.x86_64 39/48\n" " Installing : cluster-glue-1.0.6-9.fc17.1.x86_64 40/48\n" " Installing : p11-kit-0.12-1.fc17.x86_64 41/48\n" " Installing : gnutls-2.12.17-1.fc17.x86_64 42/48\n" " Installing : pacemaker-libs-1.1.7-2.fc17.x86_64 43/48\n" " Installing : pacemaker-cluster-libs-1.1.7-2.fc17.x86_64 44/48\n" " Installing : pacemaker-cli-1.1.7-2.fc17.x86_64 45/48\n" " Installing : xfsprogs-3.1.8-1.fc17.x86_64 46/48\n" " Installing : resource-agents-3.9.2-2.fc17.1.x86_64 47/48\n" " Installing : pacemaker-1.1.7-2.fc17.x86_64 48/48\n" " Verifying : xfsprogs-3.1.8-1.fc17.x86_64 1/48\n" " Verifying : 1:net-snmp-libs-5.7.1-4.fc17.x86_64 2/48\n" " Verifying : corosync-1.99.9-1.fc17.x86_64 3/48\n" " Verifying : cluster-glue-1.0.6-9.fc17.1.x86_64 4/48\n" " Verifying : perl-PathTools-3.33-211.fc17.x86_64 5/48\n" " Verifying : p11-kit-0.12-1.fc17.x86_64 6/48\n" " Verifying : 1:perl-Pod-Simple-3.16-211.fc17.noarch 7/48\n" " Verifying : OpenIPMI-libs-2.0.18-13.fc17.x86_64 8/48\n" " Verifying : libtasn1-2.12-1.fc17.x86_64 9/48\n" " Verifying : perl-threads-1.86-2.fc17.x86_64 10/48\n" " Verifying : 1:perl-Pod-Escapes-1.04-211.fc17.noarch 11/48\n" " Verifying : pacemaker-1.1.7-2.fc17.x86_64 12/48\n" " Verifying : 4:perl-5.14.2-211.fc17.x86_64 13/48\n" " Verifying : gnutls-2.12.17-1.fc17.x86_64 14/48\n" " Verifying : perl-threads-shared-1.40-2.fc17.x86_64 15/48\n" " Verifying : 4:perl-macros-5.14.2-211.fc17.x86_64 16/48\n" " Verifying : 1:perl-Module-Pluggable-3.90-211.fc17.noarch 17/48\n" " Verifying : 1:nfs-utils-1.2.5-12.fc17.x86_64 18/48\n" " Verifying : cluster-glue-libs-1.0.6-9.fc17.1.x86_64 19/48\n" " Verifying : pacemaker-libs-1.1.7-2.fc17.x86_64 20/48\n" " Verifying : libtalloc-2.0.7-4.fc17.x86_64 21/48\n" " Verifying : libevent-2.0.14-2.fc17.x86_64 22/48\n" " Verifying : perl-Socket-2.001-1.fc17.x86_64 23/48\n" " Verifying : libgssglue-0.3-1.fc17.x86_64 24/48\n" " Verifying : perl-Carp-1.22-2.fc17.noarch 25/48\n" " Verifying : libtirpc-0.2.2-2.1.fc17.x86_64 26/48\n" " Verifying : 2:ethtool-3.2-2.fc17.x86_64 27/48\n" " Verifying : 4:perl-libs-5.14.2-211.fc17.x86_64 28/48\n" " Verifying : libxslt-1.1.26-9.fc17.x86_64 29/48\n" " Verifying : rpcbind-0.2.0-16.fc17.x86_64 30/48\n" " Verifying : librdmacm-1.0.15-1.fc17.x86_64 31/48\n" " Verifying : resource-agents-3.9.2-2.fc17.1.x86_64 32/48\n" " Verifying : 1:quota-4.00-3.fc17.x86_64 33/48\n" " Verifying : 1:perl-TimeDate-1.20-6.fc17.noarch 34/48\n" " Verifying : perl-Scalar-List-Utils-1.25-1.fc17.x86_64 35/48\n" " Verifying : libtool-ltdl-2.4.2-3.fc17.x86_64 36/48\n" " Verifying : pacemaker-cluster-libs-1.1.7-2.fc17.x86_64 37/48\n" " Verifying : cifs-utils-5.3-2.fc17.x86_64 38/48\n" " Verifying : libnet-1.1.5-3.fc17.x86_64 39/48\n" " Verifying : corosynclib-1.99.9-1.fc17.x86_64 40/48\n" " Verifying : libqb-0.11.1-1.fc17.x86_64 41/48\n" " Verifying : 1:libwbclient-3.6.3-81.fc17.1.x86_64 42/48\n" " Verifying : libnfsidmap-0.25-1.fc17.x86_64 43/48\n" " Verifying : tcp_wrappers-7.6-69.fc17.x86_64 44/48\n" " Verifying : keyutils-1.5.5-2.fc17.x86_64 45/48\n" " Verifying : libibverbs-1.1.6-2.fc17.x86_64 46/48\n" " Verifying : 1:quota-nls-4.00-3.fc17.noarch 47/48\n" " Verifying : pacemaker-cli-1.1.7-2.fc17.x86_64 48/48\n" "\n" "Installed:\n" " corosync.x86_64 0:1.99.9-1.fc17 pacemaker.x86_64 0:1.1.7-2.fc17\n" "\n" "Dependency Installed:\n" " OpenIPMI-libs.x86_64 0:2.0.18-13.fc17 cifs-utils.x86_64 0:5.3-2.fc17\n" " cluster-glue.x86_64 0:1.0.6-9.fc17.1 cluster-glue-libs.x86_64 0:1.0.6-9.fc17.1\n" " corosynclib.x86_64 0:1.99.9-1.fc17 ethtool.x86_64 2:3.2-2.fc17\n" " gnutls.x86_64 0:2.12.17-1.fc17 keyutils.x86_64 0:1.5.5-2.fc17\n" " libevent.x86_64 0:2.0.14-2.fc17 libgssglue.x86_64 0:0.3-1.fc17\n" " libibverbs.x86_64 0:1.1.6-2.fc17 libnet.x86_64 0:1.1.5-3.fc17\n" " libnfsidmap.x86_64 0:0.25-1.fc17 libqb.x86_64 0:0.11.1-1.fc17\n" " librdmacm.x86_64 0:1.0.15-1.fc17 libtalloc.x86_64 0:2.0.7-4.fc17\n" " libtasn1.x86_64 0:2.12-1.fc17 libtirpc.x86_64 0:0.2.2-2.1.fc17\n" " libtool-ltdl.x86_64 0:2.4.2-3.fc17 libwbclient.x86_64 1:3.6.3-81.fc17.1\n" " libxslt.x86_64 0:1.1.26-9.fc17 net-snmp-libs.x86_64 1:5.7.1-4.fc17\n" " nfs-utils.x86_64 1:1.2.5-12.fc17 p11-kit.x86_64 0:0.12-1.fc17\n" " pacemaker-cli.x86_64 0:1.1.7-2.fc17 pacemaker-cluster-libs.x86_64 0:1.1.7-2.fc17\n" " pacemaker-libs.x86_64 0:1.1.7-2.fc17 perl.x86_64 4:5.14.2-211.fc17\n" " perl-Carp.noarch 0:1.22-2.fc17 perl-Module-Pluggable.noarch 1:3.90-211.fc17\n" " perl-PathTools.x86_64 0:3.33-211.fc17 perl-Pod-Escapes.noarch 1:1.04-211.fc17\n" " perl-Pod-Simple.noarch 1:3.16-211.fc17 perl-Scalar-List-Utils.x86_64 0:1.25-1.fc17\n" " perl-Socket.x86_64 0:2.001-1.fc17 perl-TimeDate.noarch 1:1.20-6.fc17\n" " perl-libs.x86_64 4:5.14.2-211.fc17 perl-macros.x86_64 4:5.14.2-211.fc17\n" " perl-threads.x86_64 0:1.86-2.fc17 perl-threads-shared.x86_64 0:1.40-2.fc17\n" " quota.x86_64 1:4.00-3.fc17 quota-nls.noarch 1:4.00-3.fc17\n" " resource-agents.x86_64 0:3.9.2-2.fc17.1 rpcbind.x86_64 0:0.2.0-16.fc17\n" " tcp_wrappers.x86_64 0:7.6-69.fc17 xfsprogs.x86_64 0:3.1.8-1.fc17\n" "\n" "Complete!\n" "[root@pcmk-1 ~]#" msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "Now install the cluster software on the second node." msgstr "安装集群软件" #. Tag: title #, fuzzy, no-c-format msgid "Install the Cluster Management Software" msgstr "安装集群软件" #. Tag: para #, no-c-format msgid "The pcs cli command coupled with the pcs daemon creates a cluster management system capable of managing all aspects of the cluster stack across all nodes from a single location." msgstr "" #. Tag: programlisting #, no-c-format msgid "# yum install -y pcs" msgstr "" #. Tag: para #, no-c-format msgid "Make sure to install the pcs packages on both nodes." msgstr "" #. Tag: title #, no-c-format msgid "Setup" msgstr "安装" #. Tag: title #, no-c-format msgid "Enable pcs Daemon" msgstr "" #. Tag: para #, no-c-format msgid "Before the cluster can be configured, the pcs daemon must be started and enabled to boot on startup on each node. This daemon works with the pcs cli command to manage syncing the corosync configuration across all the nodes in the cluster." msgstr "" #. Tag: para #, no-c-format msgid "Start and enable the daemon by issuing the following commands on each node." msgstr "" #. Tag: programlisting #, no-c-format msgid "" "# systemctl start pcsd.service\n" "# systemctl enable pcsd.service" msgstr "" #. Tag: para #, no-c-format msgid "Now we need a way for pcs to talk to itself on other nodes in the cluster. This is necessary in order to perform tasks such as syncing the corosync config, or starting/stopping the cluster on remote nodes" msgstr "" #. Tag: para #, no-c-format msgid "While pcs can be used locally without setting up these user accounts, this tutorial will make use of these remote access commands, so we will set a password for the hacluster user. Its probably best if password is consistent across all the nodes." msgstr "" #. Tag: para #, no-c-format msgid "As root, run:" msgstr "" #. Tag: programlisting #, no-c-format msgid "" "# passwd hacluster\n" "password:" msgstr "" #. Tag: para #, no-c-format msgid "Alternatively, to script this process or set the password on a different machine to the one you’re logged into, you can use the --stdin option for passwd:" msgstr "" #. Tag: programlisting #, no-c-format msgid "# ssh pcmk-2 -- 'echo redhat1 | passwd --stdin hacluster'" msgstr "" #. Tag: title #, no-c-format msgid "Notes on Multicast Address Assignment" msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "There are several subtle points that often deserve consideration when choosing/assigning multicast addresses. This information is borrowed from, the now defunct, http://web.archive.org/web/20101211210054/http://29west.com/docs/THPM/multicast-address-assignment.html" msgstr "请注意你选择的端口和地址不能跟已存在的集群冲突,关于组播地址的选择,可以参考 http://www.29west.com/docs/THPM/multicast-address-assignment.html " #. Tag: para #, no-c-format msgid "Avoid 224.0.0.x" msgstr "" #. Tag: para #, no-c-format msgid "Traffic to addresses of the form 224.0.0.x is often flooded to all switch ports. This address range is reserved for link-local uses. Many routing protocols assume that all traffic within this range will be received by all routers on the network. Hence (at least all Cisco) switches flood traffic within this range. The flooding behavior overrides the normal selective forwarding behavior of a multicast-aware switch (e.g. IGMP snooping, CGMP, etc.)." msgstr "" #. Tag: para #, no-c-format msgid "Watch for 32:1 overlap" msgstr "" #. Tag: para #, no-c-format msgid "32 non-contiguous IP multicast addresses are mapped onto each Ethernet multicast address. A receiver that joins a single IP multicast group implicitly joins 31 others due to this overlap. Of course, filtering in the operating system discards undesired multicast traffic from applications, but NIC bandwidth and CPU resources are nonetheless consumed discarding it. The overlap occurs in the 5 high-order bits, so it’s best to use the 23 low-order bits to make distinct multicast streams unique. For example, IP multicast addresses in the range 239.0.0.0 to 239.127.255.255 all map to unique Ethernet multicast addresses. However, IP multicast address 239.128.0.0 maps to the same Ethernet multicast address as 239.0.0.0, 239.128.0.1 maps to the same Ethernet multicast address as 239.0.0.1, etc." msgstr "" #. Tag: para #, no-c-format msgid "Avoid x.0.0.y and x.128.0.y" msgstr "" #. Tag: para #, no-c-format msgid "Combining the above two considerations, it’s best to avoid using IP multicast addresses of the form x.0.0.y and x.128.0.y since they all map onto the range of Ethernet multicast addresses that are flooded to all switch ports." msgstr "" #. Tag: para #, no-c-format msgid "Watch for address assignment conflicts" msgstr "" #. Tag: para #, no-c-format msgid "IANA administers Internet multicast addresses. Potential conflicts with Internet multicast address assignments can be avoided by using GLOP addressing (AS required) or administratively scoped addresses. Such addresses can be safely used on a network connected to the Internet without fear of conflict with multicast sources originating on the Internet. Administratively scoped addresses are roughly analogous to the unicast address space for private internets. Site-local multicast addresses are of the form 239.255.x.y, but can grow down to 239.252.x.y if needed. Organization-local multicast addresses are of the form 239.192-251.x.y, but can grow down to 239.x.y.z if needed." msgstr "" #. Tag: para #, no-c-format msgid "For a more detailed treatment (57 pages!), see Cisco’s Guidelines for Enterprise IP Multicast Address Allocation paper." msgstr "" #. Tag: title #, no-c-format msgid "Configuring Corosync" msgstr "配置 Corosync" #. Tag: para #, no-c-format msgid "In the past, at this point in the tutorial an explanation of how to configure and propagate corosync’s /etc/corosync.conf file would be necessary. Using pcs with the pcs daemon greatly simplifies this process by generating corosync.conf across all the nodes in the cluster with a single command. The only thing required to achieve this is to authenticate as the pcs user hacluster on one of the nodes in the cluster, and then issue the pcs cluster setup command with a list of all the node names in the cluster." msgstr "" #. Tag: programlisting #, no-c-format msgid "" "# pcs cluster auth pcmk-1 pcmk-2\n" "Username: hacluster\n" "Password:\n" "pcmk-1: Authorized\n" "pcmk-2: Authorized\n" "\n" "# pcs cluster setup mycluster pcmk-1 pcmk-2\n" "pcmk-1: Succeeded\n" "pcmk-2: Succeeded" msgstr "" #. Tag: para #, no-c-format msgid "That’s it. Corosync is configured across the cluster. If you received an authorization error for either of those commands, make sure you setup the hacluster user account and password on every node in the cluster with the same password." msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "The final /etc/corosync.conf configuration on each node should look something like the sample in Appendix B, Sample Corosync Configuration." msgstr "最后配置文件应该看起来像下面的样子。" #. Tag: para #, no-c-format msgid "Pacemaker used to obtain membership and quorum from a custom Corosync plugin. This plugin also had the capability to start Pacemaker automatically when Corosync was started." msgstr "" #. Tag: para #, no-c-format msgid "Neither behavior is possible with Corosync 2.0 and beyond as support for plugins was removed." msgstr "" #. Tag: para #, no-c-format msgid "Instead, Pacemaker must be started as a separate job/initscript. Also, since Pacemaker made use of the plugin for message routing, a node using the plugin (Corosync prior to 2.0) cannot talk to one that isn’t (Corosync 2.0+)." msgstr "" #. Tag: para #, no-c-format msgid "Rolling upgrades between these versions are therefor not possible and an alternate strategy http://www.clusterlabs.org/doc/en-US/Pacemaker/1.1/html/Pacemaker_Explained/ap-upgrade.html must be used." msgstr "" #~ msgid "Burn the disk image to a DVD http://docs.fedoraproject.org/readme-burning-isos/en-US.html and boot from it. Or use the image to boot a virtual machine as I have done here. After clicking through the welcome screen, select your language and keyboard layout http://docs.fedoraproject.org/install-guide/f&DISTRO_VERSION;/en-US/html/s1-langselection-x86.html " #~ msgstr "烧录一个DVD光盘 http://docs.fedoraproject.org/readme-burning-isos/en-US.html 并从它启动。或者就像我一样启动一个虚拟机。 在点击欢迎界面的NETX后 ,我们要开始选择语言和键盘类型 http://docs.fedoraproject.org/install-guide/f&DISTRO_VERSION;/en-US/html/s1-langselection-x86.html " #~ msgid "Fedora Installation - Welcome" #~ msgstr "安装Fedora - 欢迎 " #~ msgid "Fedora Installation: Good choice" #~ msgstr "安装Fedora: 好的选择!" #~ msgid "Fedora Installation - Storage Devices" #~ msgstr "安装Fedora - 存储设备" #~ msgid "Fedora Installation: Storage Devices" #~ msgstr "安装Fedora: 存储设备" #~ msgid "Fedora Installation - Hostname" #~ msgstr "安装Fedora -机器名" #~ msgid "Fedora Installation: Choose a hostname" #~ msgstr "安装Fedora: 选择一个机器名" #~ msgid "Fedora Installation - Installation Type" #~ msgstr "安装Fedora - 安装类型" #~ msgid "Fedora Installation: Choose an installation type" #~ msgstr "安装Fedora: 选择安装类型" #~ msgid "By default, Fedora will give all the space to the / (aka. root) partition. Wel'll take some back so we can use DRBD." #~ msgstr "默认的话,Fedora会将所有的空间都分配给/ (aka. 根)分区。我们要保留一点给DRBD。" #~ msgid "Fedora Installation - Default Partitioning" #~ msgstr "安装Fedora - 默认分区" #~ msgid "The finalized partition layout should look something like the diagram below." #~ msgstr "完整的分区应该像下面一样。" #~ msgid "If you plan on following the DRBD or GFS2 portions of this guide, you should reserve at least 1Gb of space on each machine from which to create a shared volume." #~ msgstr "如果你想试验本文档中关于DRBD或者GFS2的部分,你要为每个节点保留至少1Gb的空间。" #~ msgid "Fedora Installation - Customize Partitioning" #~ msgstr "安装Fedora - 自定义分区" #~ msgid "Fedora Installation: Create a partition to use (later) for website data" #~ msgstr "安装Fedora: 创建一个网站存放数据用的分区" #~ msgid "Fedora Installation - Bootloader" #~ msgstr "安装Fedora - Bootloader" #~ msgid "Fedora Installation: Unless you have a strong reason not to, accept the default bootloader location" #~ msgstr "安装Fedora: 除非有非常强力的理由,不然选择默认的bootloader安装位置" #~ msgid "Fedora Installation - Software" #~ msgstr "安装Fedora - 软件" #~ msgid "Fedora Installation: Software selection" #~ msgstr "安装Fedora: 软件选择" #~ msgid "Fedora Installation - Installing" #~ msgstr "安装Fedora - 安装中" #~ msgid "Fedora Installation - Installation Complete" #~ msgstr "安装Fedora - 安装完成" #~ msgid "Fedora Installation: Stage 1, completed" #~ msgstr "安装Fedora: Stage 1, 完成" #~ msgid "Once the node reboots, follow the on screen instructions http://docs.fedoraproject.org/install-guide/f&DISTRO_VERSION;/en-US/html/ch-firstboot.html to create a system user and configure the time." #~ msgstr "一旦系统重启完毕你可以看到以下界面 http://docs.fedoraproject.org/install-guide/f&DISTRO_VERSION;/en-US/html/ch-firstboot.html ,然后配置用户和设定时间。" #~ msgid "Fedora Installation - First Boot" #~ msgstr "安装Fedora - 第一次启动" #~ msgid "Fedora Installation - Create Non-privileged User" #~ msgstr "安装Fedora - 创建非特权用户" #~ msgid "Fedora Installation: Creating a non-privileged user, take note of the password, you'll need it soon" #~ msgstr "安装Fedora: 创建非特权用户,请注意密码,一会你要用到它的。" #~ msgid "It is highly recommended to enable NTP on your cluster nodes. Doing so ensures all nodes agree on the current time and makes reading log files significantly easier." #~ msgstr "强烈建议开启NTP时间同步,这样可以使集群更好的同步配置文件以及使日志文件有更好的可读性。" #~ msgid "Fedora Installation - Date and Time" #~ msgstr "安装Fedora - 日期和时间" #~ msgid "Fedora Installation: Enable NTP to keep the times on all your nodes consistent" #~ msgstr "安装Fedora : 启用NTP来保证所有节点时间同步" #~ msgid "Click through the next screens until you reach the login window. Click on the user you created and supply the password you indicated earlier." #~ msgstr "点击next会进入登入界面,点击你创建的用户并输入之前设定的密码。" #~ msgid "Fedora Installation - Customize Networking" #~ msgstr "安装Fedora -自定义网络" #~ msgid "Fedora Installation: Click here to configure networking" #~ msgstr "安装Fedora: 点击这里来配置网络" #~ msgid "Fedora Installation - Specify Network Preferences" #~ msgstr "安装Fedora - 指定网络参数" #~ msgid "Fedora Installation: Specify network settings for your machine, never choose DHCP" #~ msgstr "安装Fedora: 设定你的网络,永远不要选择DHCP" #~ msgid "Fedora Installation - Activate Networking" #~ msgstr "安装Fedora - 激活网络" #~ msgid "Fedora Installation: Click the big green button to activate your changes" #~ msgstr "安装Fedora:点击绿色按钮来应用你的更改" #~ msgid "Fedora Installation - Bring up the Terminal" #~ msgstr "安装Fedora - 打开终端" #~ msgid "Fedora Installation: Down to business, fire up the command line" #~ msgstr "安装Fedora:开始干活,打开终端" #~ msgid "Go to the terminal window you just opened and switch to the super user (aka. \"root\") account with the su command. You will need to supply the password you entered earlier during the installation process." #~ msgstr "打开一个终端,然后使用su命令切换到超级用户(root)。输入之前安装时候设定的密码:" #~ msgid "" #~ "\n" #~ "[beekhof@pcmk-1 ~]$ su -\n" #~ "Password:\n" #~ "[root@pcmk-1 ~]#\n" #~ " " #~ msgstr "" #~ "\n" #~ "[beekhof@pcmk-1 ~]$ su -\n" #~ "Password:\n" #~ "[root@pcmk-1 ~]#\n" #~ " " #~ msgid "Note that the username (the text before the @ symbol) now indicates we’re running as the super user “root”." #~ msgstr "注意用户名 (@符号左边的字符串) 显示我们现在使用的是root用户." #~ msgid "" #~ "\n" #~ "[root@pcmk-1 ~]# ip addr\n" #~ "1: lo: <LOOPBACK,UP,LOWER_UP> mtu 16436 qdisc noqueue state UNKNOWN \n" #~ " link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00\n" #~ " inet 127.0.0.1/8 scope host lo\n" #~ " inet6 ::1/128 scope host \n" #~ " valid_lft forever preferred_lft forever\n" #~ "2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UNKNOWN qlen 1000\n" #~ " link/ether 00:0c:29:6f:e1:58 brd ff:ff:ff:ff:ff:ff\n" #~ " inet 192.168.9.41/24 brd 192.168.9.255 scope global eth0\n" #~ " inet6 ::20c:29ff:fe6f:e158/64 scope global dynamic \n" #~ " valid_lft 2591667sec preferred_lft 604467sec\n" #~ " inet6 2002:57ae:43fc:0:20c:29ff:fe6f:e158/64 scope global dynamic \n" #~ " valid_lft 2591990sec preferred_lft 604790sec\n" #~ " inet6 fe80::20c:29ff:fe6f:e158/64 scope link \n" #~ " valid_lft forever preferred_lft forever\n" #~ "[root@pcmk-1 ~]# ping -c 1 www.google.com\n" #~ "PING www.l.google.com (74.125.39.99) 56(84) bytes of data.\n" #~ "64 bytes from fx-in-f99.1e100.net (74.125.39.99): icmp_seq=1 ttl=56 time=16.7 ms\n" #~ "\n" #~ "--- www.l.google.com ping statistics ---\n" #~ "1 packets transmitted, 1 received, 0% packet loss, time 20ms\n" #~ "rtt min/avg/max/mdev = 16.713/16.713/16.713/0.000 ms\n" #~ "[root@pcmk-1 ~]# /sbin/chkconfig network on\n" #~ "[root@pcmk-1 ~]# \n" #~ " " #~ msgstr "" #~ "\n" #~ "[root@pcmk-1 ~]# ip addr\n" #~ "1: lo: <LOOPBACK,UP,LOWER_UP> mtu 16436 qdisc noqueue state UNKNOWN \n" #~ " link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00\n" #~ " inet 127.0.0.1/8 scope host lo\n" #~ " inet6 ::1/128 scope host \n" #~ " valid_lft forever preferred_lft forever\n" #~ "2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UNKNOWN qlen 1000\n" #~ " link/ether 00:0c:29:6f:e1:58 brd ff:ff:ff:ff:ff:ff\n" #~ " inet 192.168.9.41/24 brd 192.168.9.255 scope global eth0\n" #~ " inet6 ::20c:29ff:fe6f:e158/64 scope global dynamic \n" #~ " valid_lft 2591667sec preferred_lft 604467sec\n" #~ " inet6 2002:57ae:43fc:0:20c:29ff:fe6f:e158/64 scope global dynamic \n" #~ " valid_lft 2591990sec preferred_lft 604790sec\n" #~ " inet6 fe80::20c:29ff:fe6f:e158/64 scope link \n" #~ " valid_lft forever preferred_lft forever\n" #~ "[root@pcmk-1 ~]# ping -c 1 www.google.com\n" #~ "PING www.l.google.com (74.125.39.99) 56(84) bytes of data.\n" #~ "64 bytes from fx-in-f99.1e100.net (74.125.39.99): icmp_seq=1 ttl=56 time=16.7 ms\n" #~ "\n" #~ "--- www.l.google.com ping statistics ---\n" #~ "1 packets transmitted, 1 received, 0% packet loss, time 20ms\n" #~ "rtt min/avg/max/mdev = 16.713/16.713/16.713/0.000 ms\n" #~ "[root@pcmk-1 ~]# /sbin/chkconfig network on\n" #~ "[root@pcmk-1 ~]# \n" #~ " " #~ msgid "" #~ "\n" #~ "[root@pcmk-1 ~]# sed -i.bak \"s/SELINUX=enforcing/SELINUX=permissive/g\" /etc/selinux/config\n" #~ "[root@pcmk-1 ~]# /sbin/chkconfig --del iptables\n" #~ "[root@pcmk-1 ~]# service iptables stop\n" #~ "iptables: Flushing firewall rules: [ OK ]\n" #~ "iptables: Setting chains to policy ACCEPT: filter [ OK ]\n" #~ "iptables: Unloading modules: [ OK ]\n" #~ " " #~ msgstr "" #~ "\n" #~ "[root@pcmk-1 ~]# sed -i.bak \"s/SELINUX=enforcing/SELINUX=permissive/g\" /etc/selinux/config\n" #~ "[root@pcmk-1 ~]# /sbin/chkconfig --del iptables\n" #~ "[root@pcmk-1 ~]# service iptables stop\n" #~ "iptables: Flushing firewall rules: [ OK ]\n" #~ "iptables: Setting chains to policy ACCEPT: filter [ OK ]\n" #~ "iptables: Unloading modules: [ OK ]\n" #~ " " #~ msgid "You will need to reboot for the SELinux changes to take effect. Otherwise you will see something like this when you start corosync:" #~ msgstr "你需要重启来保证SELinux正确关闭。不然你启动corosync的时候将看到以下提示:" #~ msgid "" #~ "\n" #~ "May 4 19:30:54 pcmk-1 setroubleshoot: SELinux is preventing /usr/sbin/corosync \"getattr\" access on /. For complete SELinux messages. run sealert -l 6e0d4384-638e-4d55-9aaf-7dac011f29c1\n" #~ "May 4 19:30:54 pcmk-1 setroubleshoot: SELinux is preventing /usr/sbin/corosync \"getattr\" access on /. For complete SELinux messages. run sealert -l 6e0d4384-638e-4d55-9aaf-7dac011f29c1\n" #~ "\t" #~ msgstr "" #~ "\n" #~ "May 4 19:30:54 pcmk-1 setroubleshoot: SELinux is preventing /usr/sbin/corosync \"getattr\" access on /. For complete SELinux messages. run sealert -l 6e0d4384-638e-4d55-9aaf-7dac011f29c1\n" #~ "May 4 19:30:54 pcmk-1 setroubleshoot: SELinux is preventing /usr/sbin/corosync \"getattr\" access on /. For complete SELinux messages. run sealert -l 6e0d4384-638e-4d55-9aaf-7dac011f29c1\n" #~ "\t" #~ msgid "" #~ "\n" #~ "[root@pcmk-1 ~]# sed -i.bak \"s/enabled=0/enabled=1/g\" /etc/yum.repos.d/fedora.repo\n" #~ "[root@pcmk-1 ~]# sed -i.bak \"s/enabled=0/enabled=1/g\" /etc/yum.repos.d/fedora-updates.repo\n" #~ "[root@pcmk-1 ~]# yum install -y pacemaker corosync\n" #~ "Loaded plugins: presto, refresh-packagekit\n" #~ "fedora/metalink \t | 22 kB 00:00 \n" #~ "fedora-debuginfo/metalink \t | 16 kB 00:00 \n" #~ "fedora-debuginfo \t | 3.2 kB 00:00 \n" #~ "fedora-debuginfo/primary_db \t | 1.4 MB 00:04 \n" #~ "fedora-source/metalink \t | 22 kB 00:00 \n" #~ "fedora-source \t | 3.2 kB 00:00 \n" #~ "fedora-source/primary_db \t | 3.0 MB 00:05 \n" #~ "updates/metalink \t | 26 kB 00:00 \n" #~ "updates \t | 2.6 kB 00:00 \n" #~ "updates/primary_db \t | 1.1 kB 00:00 \n" #~ "updates-debuginfo/metalink \t | 18 kB 00:00 \n" #~ "updates-debuginfo \t | 2.6 kB 00:00 \n" #~ "updates-debuginfo/primary_db \t | 1.1 kB 00:00 \n" #~ "updates-source/metalink \t | 25 kB 00:00 \n" #~ "updates-source \t | 2.6 kB 00:00 \n" #~ "updates-source/primary_db \t | 1.1 kB 00:00 \n" #~ "Setting up Install Process\n" #~ "Resolving Dependencies\n" #~ "--> Running transaction check\n" #~ "---> Package corosync.x86_64 0:1.2.1-1.fc13 set to be updated\n" #~ "--> Processing Dependency: corosynclib = 1.2.1-1.fc13 for package: corosync-1.2.1-1.fc13.x86_64\n" #~ "--> Processing Dependency: libquorum.so.4(COROSYNC_QUORUM_1.0)(64bit) for package: corosync-1.2.1-1.fc13.x86_64\n" #~ "--> Processing Dependency: libvotequorum.so.4(COROSYNC_VOTEQUORUM_1.0)(64bit) for package: corosync-1.2.1-1.fc13.x86_64\n" #~ "--> Processing Dependency: libcpg.so.4(COROSYNC_CPG_1.0)(64bit) for package: corosync-1.2.1-1.fc13.x86_64\n" #~ "--> Processing Dependency: libconfdb.so.4(COROSYNC_CONFDB_1.0)(64bit) for package: corosync-1.2.1-1.fc13.x86_64\n" #~ "--> Processing Dependency: libcfg.so.4(COROSYNC_CFG_0.82)(64bit) for package: corosync-1.2.1-1.fc13.x86_64\n" #~ "--> Processing Dependency: libpload.so.4(COROSYNC_PLOAD_1.0)(64bit) for package: corosync-1.2.1-1.fc13.x86_64\n" #~ "--> Processing Dependency: liblogsys.so.4()(64bit) for package: corosync-1.2.1-1.fc13.x86_64\n" #~ "--> Processing Dependency: libconfdb.so.4()(64bit) for package: corosync-1.2.1-1.fc13.x86_64\n" #~ "--> Processing Dependency: libcoroipcc.so.4()(64bit) for package: corosync-1.2.1-1.fc13.x86_64\n" #~ "--> Processing Dependency: libcpg.so.4()(64bit) for package: corosync-1.2.1-1.fc13.x86_64\n" #~ "--> Processing Dependency: libquorum.so.4()(64bit) for package: corosync-1.2.1-1.fc13.x86_64\n" #~ "--> Processing Dependency: libcoroipcs.so.4()(64bit) for package: corosync-1.2.1-1.fc13.x86_64\n" #~ "--> Processing Dependency: libvotequorum.so.4()(64bit) for package: corosync-1.2.1-1.fc13.x86_64\n" #~ "--> Processing Dependency: libcfg.so.4()(64bit) for package: corosync-1.2.1-1.fc13.x86_64\n" #~ "--> Processing Dependency: libtotem_pg.so.4()(64bit) for package: corosync-1.2.1-1.fc13.x86_64\n" #~ "--> Processing Dependency: libpload.so.4()(64bit) for package: corosync-1.2.1-1.fc13.x86_64\n" #~ "---> Package pacemaker.x86_64 0:1.1.1-1.fc13 set to be updated\n" #~ "--> Processing Dependency: heartbeat >= 3.0.0 for package: pacemaker-1.1.1-1.fc13.x86_64\n" #~ "--> Processing Dependency: net-snmp >= 5.4 for package: pacemaker-1.1.1-1.fc13.x86_64\n" #~ "--> Processing Dependency: resource-agents for package: pacemaker-1.1.1-1.fc13.x86_64\n" #~ "--> Processing Dependency: cluster-glue for package: pacemaker-1.1.1-1.fc13.x86_64\n" #~ "--> Processing Dependency: libnetsnmp.so.20()(64bit) for package: pacemaker-1.1.1-1.fc13.x86_64\n" #~ "--> Processing Dependency: libcrmcluster.so.1()(64bit) for package: pacemaker-1.1.1-1.fc13.x86_64\n" #~ "--> Processing Dependency: libpengine.so.3()(64bit) for package: pacemaker-1.1.1-1.fc13.x86_64\n" #~ "--> Processing Dependency: libnetsnmpagent.so.20()(64bit) for package: pacemaker-1.1.1-1.fc13.x86_64\n" #~ "--> Processing Dependency: libesmtp.so.5()(64bit) for package: pacemaker-1.1.1-1.fc13.x86_64\n" #~ "--> Processing Dependency: libstonithd.so.1()(64bit) for package: pacemaker-1.1.1-1.fc13.x86_64\n" #~ "--> Processing Dependency: libhbclient.so.1()(64bit) for package: pacemaker-1.1.1-1.fc13.x86_64\n" #~ "--> Processing Dependency: libpils.so.2()(64bit) for package: pacemaker-1.1.1-1.fc13.x86_64\n" #~ "--> Processing Dependency: libpe_status.so.2()(64bit) for package: pacemaker-1.1.1-1.fc13.x86_64\n" #~ "--> Processing Dependency: libnetsnmpmibs.so.20()(64bit) for package: pacemaker-1.1.1-1.fc13.x86_64\n" #~ "--> Processing Dependency: libnetsnmphelpers.so.20()(64bit) for package: pacemaker-1.1.1-1.fc13.x86_64\n" #~ "--> Processing Dependency: libcib.so.1()(64bit) for package: pacemaker-1.1.1-1.fc13.x86_64\n" #~ "--> Processing Dependency: libccmclient.so.1()(64bit) for package: pacemaker-1.1.1-1.fc13.x86_64\n" #~ "--> Processing Dependency: libstonith.so.1()(64bit) for package: pacemaker-1.1.1-1.fc13.x86_64\n" #~ "--> Processing Dependency: liblrm.so.2()(64bit) for package: pacemaker-1.1.1-1.fc13.x86_64\n" #~ "--> Processing Dependency: libtransitioner.so.1()(64bit) for package: pacemaker-1.1.1-1.fc13.x86_64\n" #~ "--> Processing Dependency: libpe_rules.so.2()(64bit) for package: pacemaker-1.1.1-1.fc13.x86_64\n" #~ "--> Processing Dependency: libcrmcommon.so.2()(64bit) for package: pacemaker-1.1.1-1.fc13.x86_64\n" #~ "--> Processing Dependency: libplumb.so.2()(64bit) for package: pacemaker-1.1.1-1.fc13.x86_64\n" #~ "--> Running transaction check\n" #~ "---> Package cluster-glue.x86_64 0:1.0.2-1.fc13 set to be updated\n" #~ "--> Processing Dependency: perl-TimeDate for package: cluster-glue-1.0.2-1.fc13.x86_64\n" #~ "--> Processing Dependency: libOpenIPMIutils.so.0()(64bit) for package: cluster-glue-1.0.2-1.fc13.x86_64\n" #~ "--> Processing Dependency: libOpenIPMIposix.so.0()(64bit) for package: cluster-glue-1.0.2-1.fc13.x86_64\n" #~ "--> Processing Dependency: libopenhpi.so.2()(64bit) for package: cluster-glue-1.0.2-1.fc13.x86_64\n" #~ "--> Processing Dependency: libOpenIPMI.so.0()(64bit) for package: cluster-glue-1.0.2-1.fc13.x86_64\n" #~ "---> Package cluster-glue-libs.x86_64 0:1.0.2-1.fc13 set to be updated\n" #~ "---> Package corosynclib.x86_64 0:1.2.1-1.fc13 set to be updated\n" #~ "--> Processing Dependency: librdmacm.so.1(RDMACM_1.0)(64bit) for package: corosynclib-1.2.1-1.fc13.x86_64\n" #~ "--> Processing Dependency: libibverbs.so.1(IBVERBS_1.0)(64bit) for package: corosynclib-1.2.1-1.fc13.x86_64\n" #~ "--> Processing Dependency: libibverbs.so.1(IBVERBS_1.1)(64bit) for package: corosynclib-1.2.1-1.fc13.x86_64\n" #~ "--> Processing Dependency: libibverbs.so.1()(64bit) for package: corosynclib-1.2.1-1.fc13.x86_64\n" #~ "--> Processing Dependency: librdmacm.so.1()(64bit) for package: corosynclib-1.2.1-1.fc13.x86_64\n" #~ "---> Package heartbeat.x86_64 0:3.0.0-0.7.0daab7da36a8.hg.fc13 set to be updated\n" #~ "--> Processing Dependency: PyXML for package: heartbeat-3.0.0-0.7.0daab7da36a8.hg.fc13.x86_64\n" #~ "---> Package heartbeat-libs.x86_64 0:3.0.0-0.7.0daab7da36a8.hg.fc13 set to be updated\n" #~ "---> Package libesmtp.x86_64 0:1.0.4-12.fc12 set to be updated\n" #~ "---> Package net-snmp.x86_64 1:5.5-12.fc13 set to be updated\n" #~ "--> Processing Dependency: libsensors.so.4()(64bit) for package: 1:net-snmp-5.5-12.fc13.x86_64\n" #~ "---> Package net-snmp-libs.x86_64 1:5.5-12.fc13 set to be updated\n" #~ "---> Package pacemaker-libs.x86_64 0:1.1.1-1.fc13 set to be updated\n" #~ "---> Package resource-agents.x86_64 0:3.0.10-1.fc13 set to be updated\n" #~ "--> Processing Dependency: libnet.so.1()(64bit) for package: resource-agents-3.0.10-1.fc13.x86_64\n" #~ "--> Running transaction check\n" #~ "---> Package OpenIPMI-libs.x86_64 0:2.0.16-8.fc13 set to be updated\n" #~ "---> Package PyXML.x86_64 0:0.8.4-17.fc13 set to be updated\n" #~ "---> Package libibverbs.x86_64 0:1.1.3-4.fc13 set to be updated\n" #~ "--> Processing Dependency: libibverbs-driver for package: libibverbs-1.1.3-4.fc13.x86_64\n" #~ "---> Package libnet.x86_64 0:1.1.4-3.fc12 set to be updated\n" #~ "---> Package librdmacm.x86_64 0:1.0.10-2.fc13 set to be updated\n" #~ "---> Package lm_sensors-libs.x86_64 0:3.1.2-2.fc13 set to be updated\n" #~ "---> Package openhpi-libs.x86_64 0:2.14.1-3.fc13 set to be updated\n" #~ "---> Package perl-TimeDate.noarch 1:1.20-1.fc13 set to be updated\n" #~ "--> Running transaction check\n" #~ "---> Package libmlx4.x86_64 0:1.0.1-5.fc13 set to be updated\n" #~ "--> Finished Dependency Resolution\n" #~ "\n" #~ "Dependencies Resolved\n" #~ "\n" #~ " " #~ msgstr "" #~ "\n" #~ "[root@pcmk-1 ~]# sed -i.bak \"s/enabled=0/enabled=1/g\" /etc/yum.repos.d/fedora.repo\n" #~ "[root@pcmk-1 ~]# sed -i.bak \"s/enabled=0/enabled=1/g\" /etc/yum.repos.d/fedora-updates.repo\n" #~ "[root@pcmk-1 ~]# yum install -y pacemaker corosync\n" #~ "Loaded plugins: presto, refresh-packagekit\n" #~ "fedora/metalink \t | 22 kB 00:00 \n" #~ "fedora-debuginfo/metalink \t | 16 kB 00:00 \n" #~ "fedora-debuginfo \t | 3.2 kB 00:00 \n" #~ "fedora-debuginfo/primary_db \t | 1.4 MB 00:04 \n" #~ "fedora-source/metalink \t | 22 kB 00:00 \n" #~ "fedora-source \t | 3.2 kB 00:00 \n" #~ "fedora-source/primary_db \t | 3.0 MB 00:05 \n" #~ "updates/metalink \t | 26 kB 00:00 \n" #~ "updates \t | 2.6 kB 00:00 \n" #~ "updates/primary_db \t | 1.1 kB 00:00 \n" #~ "updates-debuginfo/metalink \t | 18 kB 00:00 \n" #~ "updates-debuginfo \t | 2.6 kB 00:00 \n" #~ "updates-debuginfo/primary_db \t | 1.1 kB 00:00 \n" #~ "updates-source/metalink \t | 25 kB 00:00 \n" #~ "updates-source \t | 2.6 kB 00:00 \n" #~ "updates-source/primary_db \t | 1.1 kB 00:00 \n" #~ "Setting up Install Process\n" #~ "Resolving Dependencies\n" #~ "--> Running transaction check\n" #~ "---> Package corosync.x86_64 0:1.2.1-1.fc13 set to be updated\n" #~ "--> Processing Dependency: corosynclib = 1.2.1-1.fc13 for package: corosync-1.2.1-1.fc13.x86_64\n" #~ "--> Processing Dependency: libquorum.so.4(COROSYNC_QUORUM_1.0)(64bit) for package: corosync-1.2.1-1.fc13.x86_64\n" #~ "--> Processing Dependency: libvotequorum.so.4(COROSYNC_VOTEQUORUM_1.0)(64bit) for package: corosync-1.2.1-1.fc13.x86_64\n" #~ "--> Processing Dependency: libcpg.so.4(COROSYNC_CPG_1.0)(64bit) for package: corosync-1.2.1-1.fc13.x86_64\n" #~ "--> Processing Dependency: libconfdb.so.4(COROSYNC_CONFDB_1.0)(64bit) for package: corosync-1.2.1-1.fc13.x86_64\n" #~ "--> Processing Dependency: libcfg.so.4(COROSYNC_CFG_0.82)(64bit) for package: corosync-1.2.1-1.fc13.x86_64\n" #~ "--> Processing Dependency: libpload.so.4(COROSYNC_PLOAD_1.0)(64bit) for package: corosync-1.2.1-1.fc13.x86_64\n" #~ "--> Processing Dependency: liblogsys.so.4()(64bit) for package: corosync-1.2.1-1.fc13.x86_64\n" #~ "--> Processing Dependency: libconfdb.so.4()(64bit) for package: corosync-1.2.1-1.fc13.x86_64\n" #~ "--> Processing Dependency: libcoroipcc.so.4()(64bit) for package: corosync-1.2.1-1.fc13.x86_64\n" #~ "--> Processing Dependency: libcpg.so.4()(64bit) for package: corosync-1.2.1-1.fc13.x86_64\n" #~ "--> Processing Dependency: libquorum.so.4()(64bit) for package: corosync-1.2.1-1.fc13.x86_64\n" #~ "--> Processing Dependency: libcoroipcs.so.4()(64bit) for package: corosync-1.2.1-1.fc13.x86_64\n" #~ "--> Processing Dependency: libvotequorum.so.4()(64bit) for package: corosync-1.2.1-1.fc13.x86_64\n" #~ "--> Processing Dependency: libcfg.so.4()(64bit) for package: corosync-1.2.1-1.fc13.x86_64\n" #~ "--> Processing Dependency: libtotem_pg.so.4()(64bit) for package: corosync-1.2.1-1.fc13.x86_64\n" #~ "--> Processing Dependency: libpload.so.4()(64bit) for package: corosync-1.2.1-1.fc13.x86_64\n" #~ "---> Package pacemaker.x86_64 0:1.1.1-1.fc13 set to be updated\n" #~ "--> Processing Dependency: heartbeat >= 3.0.0 for package: pacemaker-1.1.1-1.fc13.x86_64\n" #~ "--> Processing Dependency: net-snmp >= 5.4 for package: pacemaker-1.1.1-1.fc13.x86_64\n" #~ "--> Processing Dependency: resource-agents for package: pacemaker-1.1.1-1.fc13.x86_64\n" #~ "--> Processing Dependency: cluster-glue for package: pacemaker-1.1.1-1.fc13.x86_64\n" #~ "--> Processing Dependency: libnetsnmp.so.20()(64bit) for package: pacemaker-1.1.1-1.fc13.x86_64\n" #~ "--> Processing Dependency: libcrmcluster.so.1()(64bit) for package: pacemaker-1.1.1-1.fc13.x86_64\n" #~ "--> Processing Dependency: libpengine.so.3()(64bit) for package: pacemaker-1.1.1-1.fc13.x86_64\n" #~ "--> Processing Dependency: libnetsnmpagent.so.20()(64bit) for package: pacemaker-1.1.1-1.fc13.x86_64\n" #~ "--> Processing Dependency: libesmtp.so.5()(64bit) for package: pacemaker-1.1.1-1.fc13.x86_64\n" #~ "--> Processing Dependency: libstonithd.so.1()(64bit) for package: pacemaker-1.1.1-1.fc13.x86_64\n" #~ "--> Processing Dependency: libhbclient.so.1()(64bit) for package: pacemaker-1.1.1-1.fc13.x86_64\n" #~ "--> Processing Dependency: libpils.so.2()(64bit) for package: pacemaker-1.1.1-1.fc13.x86_64\n" #~ "--> Processing Dependency: libpe_status.so.2()(64bit) for package: pacemaker-1.1.1-1.fc13.x86_64\n" #~ "--> Processing Dependency: libnetsnmpmibs.so.20()(64bit) for package: pacemaker-1.1.1-1.fc13.x86_64\n" #~ "--> Processing Dependency: libnetsnmphelpers.so.20()(64bit) for package: pacemaker-1.1.1-1.fc13.x86_64\n" #~ "--> Processing Dependency: libcib.so.1()(64bit) for package: pacemaker-1.1.1-1.fc13.x86_64\n" #~ "--> Processing Dependency: libccmclient.so.1()(64bit) for package: pacemaker-1.1.1-1.fc13.x86_64\n" #~ "--> Processing Dependency: libstonith.so.1()(64bit) for package: pacemaker-1.1.1-1.fc13.x86_64\n" #~ "--> Processing Dependency: liblrm.so.2()(64bit) for package: pacemaker-1.1.1-1.fc13.x86_64\n" #~ "--> Processing Dependency: libtransitioner.so.1()(64bit) for package: pacemaker-1.1.1-1.fc13.x86_64\n" #~ "--> Processing Dependency: libpe_rules.so.2()(64bit) for package: pacemaker-1.1.1-1.fc13.x86_64\n" #~ "--> Processing Dependency: libcrmcommon.so.2()(64bit) for package: pacemaker-1.1.1-1.fc13.x86_64\n" #~ "--> Processing Dependency: libplumb.so.2()(64bit) for package: pacemaker-1.1.1-1.fc13.x86_64\n" #~ "--> Running transaction check\n" #~ "---> Package cluster-glue.x86_64 0:1.0.2-1.fc13 set to be updated\n" #~ "--> Processing Dependency: perl-TimeDate for package: cluster-glue-1.0.2-1.fc13.x86_64\n" #~ "--> Processing Dependency: libOpenIPMIutils.so.0()(64bit) for package: cluster-glue-1.0.2-1.fc13.x86_64\n" #~ "--> Processing Dependency: libOpenIPMIposix.so.0()(64bit) for package: cluster-glue-1.0.2-1.fc13.x86_64\n" #~ "--> Processing Dependency: libopenhpi.so.2()(64bit) for package: cluster-glue-1.0.2-1.fc13.x86_64\n" #~ "--> Processing Dependency: libOpenIPMI.so.0()(64bit) for package: cluster-glue-1.0.2-1.fc13.x86_64\n" #~ "---> Package cluster-glue-libs.x86_64 0:1.0.2-1.fc13 set to be updated\n" #~ "---> Package corosynclib.x86_64 0:1.2.1-1.fc13 set to be updated\n" #~ "--> Processing Dependency: librdmacm.so.1(RDMACM_1.0)(64bit) for package: corosynclib-1.2.1-1.fc13.x86_64\n" #~ "--> Processing Dependency: libibverbs.so.1(IBVERBS_1.0)(64bit) for package: corosynclib-1.2.1-1.fc13.x86_64\n" #~ "--> Processing Dependency: libibverbs.so.1(IBVERBS_1.1)(64bit) for package: corosynclib-1.2.1-1.fc13.x86_64\n" #~ "--> Processing Dependency: libibverbs.so.1()(64bit) for package: corosynclib-1.2.1-1.fc13.x86_64\n" #~ "--> Processing Dependency: librdmacm.so.1()(64bit) for package: corosynclib-1.2.1-1.fc13.x86_64\n" #~ "---> Package heartbeat.x86_64 0:3.0.0-0.7.0daab7da36a8.hg.fc13 set to be updated\n" #~ "--> Processing Dependency: PyXML for package: heartbeat-3.0.0-0.7.0daab7da36a8.hg.fc13.x86_64\n" #~ "---> Package heartbeat-libs.x86_64 0:3.0.0-0.7.0daab7da36a8.hg.fc13 set to be updated\n" #~ "---> Package libesmtp.x86_64 0:1.0.4-12.fc12 set to be updated\n" #~ "---> Package net-snmp.x86_64 1:5.5-12.fc13 set to be updated\n" #~ "--> Processing Dependency: libsensors.so.4()(64bit) for package: 1:net-snmp-5.5-12.fc13.x86_64\n" #~ "---> Package net-snmp-libs.x86_64 1:5.5-12.fc13 set to be updated\n" #~ "---> Package pacemaker-libs.x86_64 0:1.1.1-1.fc13 set to be updated\n" #~ "---> Package resource-agents.x86_64 0:3.0.10-1.fc13 set to be updated\n" #~ "--> Processing Dependency: libnet.so.1()(64bit) for package: resource-agents-3.0.10-1.fc13.x86_64\n" #~ "--> Running transaction check\n" #~ "---> Package OpenIPMI-libs.x86_64 0:2.0.16-8.fc13 set to be updated\n" #~ "---> Package PyXML.x86_64 0:0.8.4-17.fc13 set to be updated\n" #~ "---> Package libibverbs.x86_64 0:1.1.3-4.fc13 set to be updated\n" #~ "--> Processing Dependency: libibverbs-driver for package: libibverbs-1.1.3-4.fc13.x86_64\n" #~ "---> Package libnet.x86_64 0:1.1.4-3.fc12 set to be updated\n" #~ "---> Package librdmacm.x86_64 0:1.0.10-2.fc13 set to be updated\n" #~ "---> Package lm_sensors-libs.x86_64 0:3.1.2-2.fc13 set to be updated\n" #~ "---> Package openhpi-libs.x86_64 0:2.14.1-3.fc13 set to be updated\n" #~ "---> Package perl-TimeDate.noarch 1:1.20-1.fc13 set to be updated\n" #~ "--> Running transaction check\n" #~ "---> Package libmlx4.x86_64 0:1.0.1-5.fc13 set to be updated\n" #~ "--> Finished Dependency Resolution\n" #~ "\n" #~ "Dependencies Resolved\n" #~ "\n" #~ " " #~ msgid "" #~ "\n" #~ "==========================================================================================\n" #~ " Package Arch Version Repository Size\n" #~ "==========================================================================================\n" #~ "Installing:\n" #~ " corosync x86_64 1.2.1-1.fc13 fedora 136 k\n" #~ " pacemaker x86_64 1.1.1-1.fc13 fedora 543 k\n" #~ "Installing for dependencies:\n" #~ " OpenIPMI-libs x86_64 2.0.16-8.fc13 fedora 474 k\n" #~ " PyXML x86_64 0.8.4-17.fc13 fedora 906 k\n" #~ " cluster-glue x86_64 1.0.2-1.fc13 fedora 230 k\n" #~ " cluster-glue-libs x86_64 1.0.2-1.fc13 fedora 116 k\n" #~ " corosynclib x86_64 1.2.1-1.fc13 fedora 145 k\n" #~ " heartbeat x86_64 3.0.0-0.7.0daab7da36a8.hg.fc13 updates 172 k\n" #~ " heartbeat-libs x86_64 3.0.0-0.7.0daab7da36a8.hg.fc13 updates 265 k\n" #~ " libesmtp x86_64 1.0.4-12.fc12 fedora 54 k\n" #~ " libibverbs x86_64 1.1.3-4.fc13 fedora 42 k\n" #~ " libmlx4 x86_64 1.0.1-5.fc13 fedora 27 k\n" #~ " libnet x86_64 1.1.4-3.fc12 fedora 49 k\n" #~ " librdmacm x86_64 1.0.10-2.fc13 fedora 22 k\n" #~ " lm_sensors-libs x86_64 3.1.2-2.fc13 fedora 37 k\n" #~ " net-snmp x86_64 1:5.5-12.fc13 fedora 295 k\n" #~ " net-snmp-libs x86_64 1:5.5-12.fc13 fedora 1.5 M\n" #~ " openhpi-libs x86_64 2.14.1-3.fc13 fedora 135 k\n" #~ " pacemaker-libs x86_64 1.1.1-1.fc13 fedora 264 k\n" #~ " perl-TimeDate noarch 1:1.20-1.fc13 fedora 42 k\n" #~ " resource-agents x86_64 3.0.10-1.fc13 fedora 357 k\n" #~ "\n" #~ "Transaction Summary\n" #~ "=========================================================================================\n" #~ "Install 21 Package(s)\n" #~ "Upgrade 0 Package(s)\n" #~ "\n" #~ "Total download size: 5.7 M\n" #~ "Installed size: 20 M\n" #~ "Downloading Packages:\n" #~ "Setting up and reading Presto delta metadata\n" #~ "updates-testing/prestodelta | 164 kB 00:00 \n" #~ "fedora/prestodelta | 150 B 00:00 \n" #~ "Processing delta metadata\n" #~ "Package(s) data still to download: 5.7 M\n" #~ "(1/21): OpenIPMI-libs-2.0.16-8.fc13.x86_64.rpm | 474 kB 00:00 \n" #~ "(2/21): PyXML-0.8.4-17.fc13.x86_64.rpm | 906 kB 00:01 \n" #~ "(3/21): cluster-glue-1.0.2-1.fc13.x86_64.rpm | 230 kB 00:00 \n" #~ "(4/21): cluster-glue-libs-1.0.2-1.fc13.x86_64.rpm | 116 kB 00:00 \n" #~ "(5/21): corosync-1.2.1-1.fc13.x86_64.rpm | 136 kB 00:00 \n" #~ "(6/21): corosynclib-1.2.1-1.fc13.x86_64.rpm | 145 kB 00:00 \n" #~ "(7/21): heartbeat-3.0.0-0.7.0daab7da36a8.hg.fc13.x86_64.rpm | 172 kB 00:00 \n" #~ "(8/21): heartbeat-libs-3.0.0-0.7.0daab7da36a8.hg.fc13.x86_64.rpm | 265 kB 00:00 \n" #~ "(9/21): libesmtp-1.0.4-12.fc12.x86_64.rpm | 54 kB 00:00 \n" #~ "(10/21): libibverbs-1.1.3-4.fc13.x86_64.rpm | 42 kB 00:00 \n" #~ "(11/21): libmlx4-1.0.1-5.fc13.x86_64.rpm | 27 kB 00:00 \n" #~ "(12/21): libnet-1.1.4-3.fc12.x86_64.rpm | 49 kB 00:00 \n" #~ "(13/21): librdmacm-1.0.10-2.fc13.x86_64.rpm | 22 kB 00:00 \n" #~ "(14/21): lm_sensors-libs-3.1.2-2.fc13.x86_64.rpm | 37 kB 00:00 \n" #~ "(15/21): net-snmp-5.5-12.fc13.x86_64.rpm | 295 kB 00:00 \n" #~ "(16/21): net-snmp-libs-5.5-12.fc13.x86_64.rpm | 1.5 MB 00:01 \n" #~ "(17/21): openhpi-libs-2.14.1-3.fc13.x86_64.rpm | 135 kB 00:00 \n" #~ "(18/21): pacemaker-1.1.1-1.fc13.x86_64.rpm | 543 kB 00:00 \n" #~ "(19/21): pacemaker-libs-1.1.1-1.fc13.x86_64.rpm | 264 kB 00:00 \n" #~ "(20/21): perl-TimeDate-1.20-1.fc13.noarch.rpm | 42 kB 00:00 \n" #~ "(21/21): resource-agents-3.0.10-1.fc13.x86_64.rpm | 357 kB 00:00 \n" #~ "----------------------------------------------------------------------------------------\n" #~ "Total 539 kB/s | 5.7 MB 00:10 \n" #~ "warning: rpmts_HdrFromFdno: Header V3 RSA/SHA256 Signature, key ID e8e40fde: NOKEY\n" #~ "fedora/gpgkey | 3.2 kB 00:00 ... \n" #~ "Importing GPG key 0xE8E40FDE \"Fedora (13) <fedora@fedoraproject.org%gt;\" from /etc/pki/rpm-gpg/RPM-GPG-KEY-fedora-x86_64\n" #~ " " #~ msgstr "" #~ "\n" #~ "==========================================================================================\n" #~ " Package Arch Version Repository Size\n" #~ "==========================================================================================\n" #~ "Installing:\n" #~ " corosync x86_64 1.2.1-1.fc13 fedora 136 k\n" #~ " pacemaker x86_64 1.1.1-1.fc13 fedora 543 k\n" #~ "Installing for dependencies:\n" #~ " OpenIPMI-libs x86_64 2.0.16-8.fc13 fedora 474 k\n" #~ " PyXML x86_64 0.8.4-17.fc13 fedora 906 k\n" #~ " cluster-glue x86_64 1.0.2-1.fc13 fedora 230 k\n" #~ " cluster-glue-libs x86_64 1.0.2-1.fc13 fedora 116 k\n" #~ " corosynclib x86_64 1.2.1-1.fc13 fedora 145 k\n" #~ " heartbeat x86_64 3.0.0-0.7.0daab7da36a8.hg.fc13 updates 172 k\n" #~ " heartbeat-libs x86_64 3.0.0-0.7.0daab7da36a8.hg.fc13 updates 265 k\n" #~ " libesmtp x86_64 1.0.4-12.fc12 fedora 54 k\n" #~ " libibverbs x86_64 1.1.3-4.fc13 fedora 42 k\n" #~ " libmlx4 x86_64 1.0.1-5.fc13 fedora 27 k\n" #~ " libnet x86_64 1.1.4-3.fc12 fedora 49 k\n" #~ " librdmacm x86_64 1.0.10-2.fc13 fedora 22 k\n" #~ " lm_sensors-libs x86_64 3.1.2-2.fc13 fedora 37 k\n" #~ " net-snmp x86_64 1:5.5-12.fc13 fedora 295 k\n" #~ " net-snmp-libs x86_64 1:5.5-12.fc13 fedora 1.5 M\n" #~ " openhpi-libs x86_64 2.14.1-3.fc13 fedora 135 k\n" #~ " pacemaker-libs x86_64 1.1.1-1.fc13 fedora 264 k\n" #~ " perl-TimeDate noarch 1:1.20-1.fc13 fedora 42 k\n" #~ " resource-agents x86_64 3.0.10-1.fc13 fedora 357 k\n" #~ "\n" #~ "Transaction Summary\n" #~ "=========================================================================================\n" #~ "Install 21 Package(s)\n" #~ "Upgrade 0 Package(s)\n" #~ "\n" #~ "Total download size: 5.7 M\n" #~ "Installed size: 20 M\n" #~ "Downloading Packages:\n" #~ "Setting up and reading Presto delta metadata\n" #~ "updates-testing/prestodelta | 164 kB 00:00 \n" #~ "fedora/prestodelta | 150 B 00:00 \n" #~ "Processing delta metadata\n" #~ "Package(s) data still to download: 5.7 M\n" #~ "(1/21): OpenIPMI-libs-2.0.16-8.fc13.x86_64.rpm | 474 kB 00:00 \n" #~ "(2/21): PyXML-0.8.4-17.fc13.x86_64.rpm | 906 kB 00:01 \n" #~ "(3/21): cluster-glue-1.0.2-1.fc13.x86_64.rpm | 230 kB 00:00 \n" #~ "(4/21): cluster-glue-libs-1.0.2-1.fc13.x86_64.rpm | 116 kB 00:00 \n" #~ "(5/21): corosync-1.2.1-1.fc13.x86_64.rpm | 136 kB 00:00 \n" #~ "(6/21): corosynclib-1.2.1-1.fc13.x86_64.rpm | 145 kB 00:00 \n" #~ "(7/21): heartbeat-3.0.0-0.7.0daab7da36a8.hg.fc13.x86_64.rpm | 172 kB 00:00 \n" #~ "(8/21): heartbeat-libs-3.0.0-0.7.0daab7da36a8.hg.fc13.x86_64.rpm | 265 kB 00:00 \n" #~ "(9/21): libesmtp-1.0.4-12.fc12.x86_64.rpm | 54 kB 00:00 \n" #~ "(10/21): libibverbs-1.1.3-4.fc13.x86_64.rpm | 42 kB 00:00 \n" #~ "(11/21): libmlx4-1.0.1-5.fc13.x86_64.rpm | 27 kB 00:00 \n" #~ "(12/21): libnet-1.1.4-3.fc12.x86_64.rpm | 49 kB 00:00 \n" #~ "(13/21): librdmacm-1.0.10-2.fc13.x86_64.rpm | 22 kB 00:00 \n" #~ "(14/21): lm_sensors-libs-3.1.2-2.fc13.x86_64.rpm | 37 kB 00:00 \n" #~ "(15/21): net-snmp-5.5-12.fc13.x86_64.rpm | 295 kB 00:00 \n" #~ "(16/21): net-snmp-libs-5.5-12.fc13.x86_64.rpm | 1.5 MB 00:01 \n" #~ "(17/21): openhpi-libs-2.14.1-3.fc13.x86_64.rpm | 135 kB 00:00 \n" #~ "(18/21): pacemaker-1.1.1-1.fc13.x86_64.rpm | 543 kB 00:00 \n" #~ "(19/21): pacemaker-libs-1.1.1-1.fc13.x86_64.rpm | 264 kB 00:00 \n" #~ "(20/21): perl-TimeDate-1.20-1.fc13.noarch.rpm | 42 kB 00:00 \n" #~ "(21/21): resource-agents-3.0.10-1.fc13.x86_64.rpm | 357 kB 00:00 \n" #~ "----------------------------------------------------------------------------------------\n" #~ "Total 539 kB/s | 5.7 MB 00:10 \n" #~ "warning: rpmts_HdrFromFdno: Header V3 RSA/SHA256 Signature, key ID e8e40fde: NOKEY\n" #~ "fedora/gpgkey | 3.2 kB 00:00 ... \n" #~ "Importing GPG key 0xE8E40FDE \"Fedora (13) <fedora@fedoraproject.org%gt;\" from /etc/pki/rpm-gpg/RPM-GPG-KEY-fedora-x86_64\n" #~ " " #~ msgid "" #~ "\n" #~ "Running rpm_check_debug\n" #~ "Running Transaction Test\n" #~ "Transaction Test Succeeded\n" #~ "Running Transaction\n" #~ " Installing : lm_sensors-libs-3.1.2-2.fc13.x86_64 1/21 \n" #~ " Installing : 1:net-snmp-libs-5.5-12.fc13.x86_64 2/21 \n" #~ " Installing : 1:net-snmp-5.5-12.fc13.x86_64 3/21 \n" #~ " Installing : openhpi-libs-2.14.1-3.fc13.x86_64 4/21 \n" #~ " Installing : libibverbs-1.1.3-4.fc13.x86_64 5/21 \n" #~ " Installing : libmlx4-1.0.1-5.fc13.x86_64 6/21 \n" #~ " Installing : librdmacm-1.0.10-2.fc13.x86_64 7/21 \n" #~ " Installing : corosync-1.2.1-1.fc13.x86_64 8/21 \n" #~ " Installing : corosynclib-1.2.1-1.fc13.x86_64 9/21 \n" #~ " Installing : libesmtp-1.0.4-12.fc12.x86_64 10/21 \n" #~ " Installing : OpenIPMI-libs-2.0.16-8.fc13.x86_64 11/21 \n" #~ " Installing : PyXML-0.8.4-17.fc13.x86_64 12/21 \n" #~ " Installing : libnet-1.1.4-3.fc12.x86_64 13/21 \n" #~ " Installing : 1:perl-TimeDate-1.20-1.fc13.noarch 14/21 \n" #~ " Installing : cluster-glue-1.0.2-1.fc13.x86_64 15/21 \n" #~ " Installing : cluster-glue-libs-1.0.2-1.fc13.x86_64 16/21 \n" #~ " Installing : resource-agents-3.0.10-1.fc13.x86_64 17/21 \n" #~ " Installing : heartbeat-libs-3.0.0-0.7.0daab7da36a8.hg.fc13.x86_64 18/21 \n" #~ " Installing : heartbeat-3.0.0-0.7.0daab7da36a8.hg.fc13.x86_64 19/21 \n" #~ " Installing : pacemaker-1.1.1-1.fc13.x86_64 20/21 \n" #~ " Installing : pacemaker-libs-1.1.1-1.fc13.x86_64 21/21 \n" #~ "\n" #~ "Installed:\n" #~ " corosync.x86_64 0:1.2.1-1.fc13 pacemaker.x86_64 0:1.1.1-1.fc13 \n" #~ "\n" #~ "Dependency Installed:\n" #~ " OpenIPMI-libs.x86_64 0:2.0.16-8.fc13 \n" #~ " PyXML.x86_64 0:0.8.4-17.fc13 \n" #~ " cluster-glue.x86_64 0:1.0.2-1.fc13 \n" #~ " cluster-glue-libs.x86_64 0:1.0.2-1.fc13 \n" #~ " corosynclib.x86_64 0:1.2.1-1.fc13 \n" #~ " heartbeat.x86_64 0:3.0.0-0.7.0daab7da36a8.hg.fc13 \n" #~ " heartbeat-libs.x86_64 0:3.0.0-0.7.0daab7da36a8.hg.fc13 \n" #~ " libesmtp.x86_64 0:1.0.4-12.fc12 \n" #~ " libibverbs.x86_64 0:1.1.3-4.fc13 \n" #~ " libmlx4.x86_64 0:1.0.1-5.fc13 \n" #~ " libnet.x86_64 0:1.1.4-3.fc12 \n" #~ " librdmacm.x86_64 0:1.0.10-2.fc13 \n" #~ " lm_sensors-libs.x86_64 0:3.1.2-2.fc13 \n" #~ " net-snmp.x86_64 1:5.5-12.fc13 \n" #~ " net-snmp-libs.x86_64 1:5.5-12.fc13 \n" #~ " openhpi-libs.x86_64 0:2.14.1-3.fc13 \n" #~ " pacemaker-libs.x86_64 0:1.1.1-1.fc13 \n" #~ " perl-TimeDate.noarch 1:1.20-1.fc13 \n" #~ " resource-agents.x86_64 0:3.0.10-1.fc13 \n" #~ "\n" #~ "Complete!\n" #~ "[root@pcmk-1 ~]# \n" #~ " " #~ msgstr "" #~ "\n" #~ "Running rpm_check_debug\n" #~ "Running Transaction Test\n" #~ "Transaction Test Succeeded\n" #~ "Running Transaction\n" #~ " Installing : lm_sensors-libs-3.1.2-2.fc13.x86_64 1/21 \n" #~ " Installing : 1:net-snmp-libs-5.5-12.fc13.x86_64 2/21 \n" #~ " Installing : 1:net-snmp-5.5-12.fc13.x86_64 3/21 \n" #~ " Installing : openhpi-libs-2.14.1-3.fc13.x86_64 4/21 \n" #~ " Installing : libibverbs-1.1.3-4.fc13.x86_64 5/21 \n" #~ " Installing : libmlx4-1.0.1-5.fc13.x86_64 6/21 \n" #~ " Installing : librdmacm-1.0.10-2.fc13.x86_64 7/21 \n" #~ " Installing : corosync-1.2.1-1.fc13.x86_64 8/21 \n" #~ " Installing : corosynclib-1.2.1-1.fc13.x86_64 9/21 \n" #~ " Installing : libesmtp-1.0.4-12.fc12.x86_64 10/21 \n" #~ " Installing : OpenIPMI-libs-2.0.16-8.fc13.x86_64 11/21 \n" #~ " Installing : PyXML-0.8.4-17.fc13.x86_64 12/21 \n" #~ " Installing : libnet-1.1.4-3.fc12.x86_64 13/21 \n" #~ " Installing : 1:perl-TimeDate-1.20-1.fc13.noarch 14/21 \n" #~ " Installing : cluster-glue-1.0.2-1.fc13.x86_64 15/21 \n" #~ " Installing : cluster-glue-libs-1.0.2-1.fc13.x86_64 16/21 \n" #~ " Installing : resource-agents-3.0.10-1.fc13.x86_64 17/21 \n" #~ " Installing : heartbeat-libs-3.0.0-0.7.0daab7da36a8.hg.fc13.x86_64 18/21 \n" #~ " Installing : heartbeat-3.0.0-0.7.0daab7da36a8.hg.fc13.x86_64 19/21 \n" #~ " Installing : pacemaker-1.1.1-1.fc13.x86_64 20/21 \n" #~ " Installing : pacemaker-libs-1.1.1-1.fc13.x86_64 21/21 \n" #~ "\n" #~ "Installed:\n" #~ " corosync.x86_64 0:1.2.1-1.fc13 pacemaker.x86_64 0:1.1.1-1.fc13 \n" #~ "\n" #~ "Dependency Installed:\n" #~ " OpenIPMI-libs.x86_64 0:2.0.16-8.fc13 \n" #~ " PyXML.x86_64 0:0.8.4-17.fc13 \n" #~ " cluster-glue.x86_64 0:1.0.2-1.fc13 \n" #~ " cluster-glue-libs.x86_64 0:1.0.2-1.fc13 \n" #~ " corosynclib.x86_64 0:1.2.1-1.fc13 \n" #~ " heartbeat.x86_64 0:3.0.0-0.7.0daab7da36a8.hg.fc13 \n" #~ " heartbeat-libs.x86_64 0:3.0.0-0.7.0daab7da36a8.hg.fc13 \n" #~ " libesmtp.x86_64 0:1.0.4-12.fc12 \n" #~ " libibverbs.x86_64 0:1.1.3-4.fc13 \n" #~ " libmlx4.x86_64 0:1.0.1-5.fc13 \n" #~ " libnet.x86_64 0:1.1.4-3.fc12 \n" #~ " librdmacm.x86_64 0:1.0.10-2.fc13 \n" #~ " lm_sensors-libs.x86_64 0:3.1.2-2.fc13 \n" #~ " net-snmp.x86_64 1:5.5-12.fc13 \n" #~ " net-snmp-libs.x86_64 1:5.5-12.fc13 \n" #~ " openhpi-libs.x86_64 0:2.14.1-3.fc13 \n" #~ " pacemaker-libs.x86_64 0:1.1.1-1.fc13 \n" #~ " perl-TimeDate.noarch 1:1.20-1.fc13 \n" #~ " resource-agents.x86_64 0:3.0.10-1.fc13 \n" #~ "\n" #~ "Complete!\n" #~ "[root@pcmk-1 ~]# \n" #~ " " #~ msgid "Verify Connectivity by IP address" #~ msgstr "通过IP地址来检查连接" #~ msgid "Set up /etc/hosts entries" #~ msgstr "否则,我们修改/etc/hosts文件来达到相同的效果:" #~ msgid "Verify Connectivity by Hostname" #~ msgstr "通过机器名检查连接" #~ msgid "" #~ "\n" #~ "[root@pcmk-1 ~]# uname -n\n" #~ "pcmk-1.clusterlabs.org\n" #~ "[root@pcmk-1 ~]# dnsdomainname \n" #~ "clusterlabs.org\n" #~ " " #~ msgstr "" #~ "\n" #~ "[root@pcmk-1 ~]# uname -n\n" #~ "pcmk-1.clusterlabs.org\n" #~ "[root@pcmk-1 ~]# dnsdomainname \n" #~ "clusterlabs.org\n" #~ " " #~ msgid "" #~ "\n" #~ "[root@pcmk-1 ~]# source /etc/sysconfig/network\n" #~ "[root@pcmk-1 ~]# hostname $HOSTNAME\n" #~ " " #~ msgstr "" #~ "\n" #~ "[root@pcmk-1 ~]# source /etc/sysconfig/network\n" #~ "[root@pcmk-1 ~]# hostname $HOSTNAME\n" #~ " " #~ msgid "" #~ "\n" #~ "[root@pcmk-1 ~]# uname -n\n" #~ "pcmk-1\n" #~ "[root@pcmk-1 ~]# dnsdomainname \n" #~ "clusterlabs.org\n" #~ " " #~ msgstr "" #~ "\n" #~ "[root@pcmk-1 ~]# uname -n\n" #~ "pcmk-1\n" #~ "[root@pcmk-1 ~]# dnsdomainname \n" #~ "clusterlabs.org\n" #~ " " #~ msgid "Now repeat on pcmk-2." #~ msgstr "现在在pcmk-2上面重复以上操作." #~ msgid "Choose a port number and multi-cast http://en.wikipedia.org/wiki/Multicast address. http://en.wikipedia.org/wiki/Multicast_address " #~ msgstr "选择一个组播 http://en.wikipedia.org/wiki/Multicast 端口和地址。 http://en.wikipedia.org/wiki/Multicast_address " #~ msgid "For this document, I have chosen port 4000 and used 226.94.1.1 as the multi-cast address." #~ msgstr "在这个文档中,我选择端口4000并且用226.94.1.1作为组播地址:" #~ msgid "" #~ "\n" #~ "[root@pcmk-1 ~]# export ais_port=4000\n" #~ "[root@pcmk-1 ~]# export ais_mcast=226.94.1.1\n" #~ " " #~ msgstr "" #~ "\n" #~ "[root@pcmk-1 ~]# export ais_port=4000\n" #~ "[root@pcmk-1 ~]# export ais_mcast=226.94.1.1\n" #~ " " #~ msgid "Next we automatically determine the hosts address. By not using the full address, we make the configuration suitable to be copied to other nodes." #~ msgstr "然后我们用下面的命令自动获得机器的地址。为了让配置文件能够在机器上面的各个机器通用,我们不使用完整的IP地址而使用网络地址。(译者注:corosync配置文件中的监听地址一项可以填写网络地址,corosync会自动匹配应该监听在哪个地址而不是0.0.0.0)" #~ msgid "[root@pcmk-1 ~]# export ais_addr=`ip addr | grep \"inet \" | tail -n 1 | awk '{print $4}' | sed s/255/0/`" #~ msgstr "[root@pcmk-1 ~]# export ais_addr=`ip addr | grep \"inet \" | tail -n 1 | awk '{print $4}' | sed s/255/0/`" #~ msgid "Display and verify the configuration options" #~ msgstr "显示并检查配置的环境变量是否正确" #~ msgid "" #~ "\n" #~ "[root@pcmk-1 ~]# env | grep ais_\n" #~ "ais_mcast=226.94.1.1\n" #~ "ais_port=4000\n" #~ "ais_addr=192.168.122.0\n" #~ " " #~ msgstr "" #~ "\n" #~ "[root@pcmk-1 ~]# env | grep ais_\n" #~ "ais_mcast=226.94.1.1\n" #~ "ais_port=4000\n" #~ "ais_addr=192.168.122.0\n" #~ " " #~ msgid "Once you’re happy with the chosen values, update the Corosync configuration" #~ msgstr "确认以上输出没有错误以后,我们用以下命令来配置corosync" #~ msgid "" #~ "\n" #~ "[root@pcmk-1 ~]# cp /etc/corosync/corosync.conf.example /etc/corosync/corosync.conf\n" #~ "[root@pcmk-1 ~]# sed -i.bak \"s/.*mcastaddr:.*/mcastaddr:\\ $ais_mcast/g\" /etc/corosync/corosync.conf\n" #~ "[root@pcmk-1 ~]# sed -i.bak \"s/.*mcastport:.*/mcastport:\\ $ais_port/g\" /etc/corosync/corosync.conf\n" #~ "[root@pcmk-1 ~]# sed -i.bak \"s/.*bindnetaddr:.*/bindnetaddr:\\ $ais_addr/g\" /etc/corosync/corosync.conf\n" #~ " " #~ msgstr "" #~ "\n" #~ "[root@pcmk-1 ~]# cp /etc/corosync/corosync.conf.example /etc/corosync/corosync.conf\n" #~ "[root@pcmk-1 ~]# sed -i.bak \"s/.*mcastaddr:.*/mcastaddr:\\ $ais_mcast/g\" /etc/corosync/corosync.conf\n" #~ "[root@pcmk-1 ~]# sed -i.bak \"s/.*mcastport:.*/mcastport:\\ $ais_port/g\" /etc/corosync/corosync.conf\n" #~ "[root@pcmk-1 ~]# sed -i.bak \"s/.*bindnetaddr:.*/bindnetaddr:\\ $ais_addr/g\" /etc/corosync/corosync.conf\n" #~ " " #~ msgid "Finally, tell Corosync to start Pacemaker" #~ msgstr "最后,告诉corosync要启动pacemaker" #~ msgid "" #~ "\n" #~ "[root@pcmk-1 ~]# cat <<-END >>/etc/corosync/service.d/pcmk\n" #~ "service {\n" #~ " # Load the Pacemaker Cluster Resource Manager\n" #~ " name: pacemaker\n" #~ " ver: 0\n" #~ "}\n" #~ "END\n" #~ " " #~ msgstr "" #~ "\n" #~ "[root@pcmk-1 ~]# cat <<-END >>/etc/corosync/service.d/pcmk\n" #~ "service {\n" #~ " # Load the Pacemaker Cluster Resource Manager\n" #~ " name: pacemaker\n" #~ " ver: 0\n" #~ "}\n" #~ "END\n" #~ " " #~ msgid "Propagate the Configuration" #~ msgstr " 传送配置文件" #~ msgid "Now we need to copy the changes so far to the other node:" #~ msgstr "然后我们把配置文件拷贝到其他节点:" #~ msgid "" #~ "\n" #~ "[root@pcmk-1 ~]# for f in /etc/corosync/corosync.conf /etc/corosync/service.d/pcmk /etc/hosts; do scp $f pcmk-2:$f ; done\n" #~ "corosync.conf 100% 1528 1.5KB/s 00:00\n" #~ "hosts 100% 281 0.3KB/s 00:00\n" #~ "[root@pcmk-1 ~]#\n" #~ " " #~ msgstr "" #~ "\n" #~ "[root@pcmk-1 ~]# for f in /etc/corosync/corosync.conf /etc/corosync/service.d/pcmk /etc/hosts; do scp $f pcmk-2:$f ; done\n" #~ "corosync.conf 100% 1528 1.5KB/s 00:00\n" #~ "hosts 100% 281 0.3KB/s 00:00\n" #~ "[root@pcmk-1 ~]#\n" #~ " " #~ msgid "Burn the disk image to a DVD" #~ msgstr "把整个镜像刻录成一个DVD光盘" #~ msgid " http://docs.fedoraproject.org/readme-burning-isos/en-US.html " #~ msgstr " http://docs.fedoraproject.org/readme-burning-isos/en-US.html " #~ msgid "and boot from it. Or use the image to boot a virtual machine as I have done here. After clicking through the welcome screen, select your language and keyboard layout" #~ msgstr "并从它启动。或者就像我一样启动一个虚拟机. 在点击欢迎界面的NETX后 ,我们要开始选择语言和键盘类型" #~ msgid " http://docs.fedoraproject.org/install-guide/f&DISTRO_VERSION;/en-US/html/s1-langselection-x86.html " #~ msgstr " http://docs.fedoraproject.org/install-guide/f&DISTRO_VERSION;/en-US/html/s1-langselection-x86.html " #~ msgid "Assign your machine a host name." #~ msgstr "给你的机器取个名字。" #~ msgid "I happen to control the clusterlabs.org domain name, so I will use that here." #~ msgstr "我正好能控制clusterlabs.org 这个域名,所以我用这个名字。" #~ msgid "You will then be prompted to indicate the machine’s physical location and to supply a root password." #~ msgstr "然后你会被提示选择机器所在地并设定root密码" #~ msgid "Now select where you want Fedora installed." #~ msgstr "然后你选择想在把Fedora安装在哪" #~ msgid "http://docs.fedoraproject.org/install-guide/f13/en-US/html/s1-diskpartsetup-x86.html" #~ msgstr "http://docs.fedoraproject.org/install-guide/f13/en-US/html/s1-diskpartsetup-x86.html" #~ msgid "Once the node reboots, follow the on screen instructions" #~ msgstr "一旦系统重启完毕你可以看到以下界面" #~ msgid "to create a system user and configure the time." #~ msgstr ",然后配置用户和设定时间。" #~ msgid "Choose a port number and multi-cast" #~ msgstr "选择一个组播" #~ msgid "http://en.wikipedia.org/wiki/Multicast" #~ msgstr "http://en.wikipedia.org/wiki/Multicast" #~ msgid "address." #~ msgstr "端口和地址。" #~ msgid "http://en.wikipedia.org/wiki/Multicast_address" #~ msgstr "http://en.wikipedia.org/wiki/Multicast_address" pacemaker-master/doc/Clusters_from_Scratch/zh-CN/Ch-Intro.mo000066400000000000000000000337651217637305600242710ustar00rootroot000000000000004G\xyP+|=H8#. >0 o ( a 9 N "  S as"qy6! ABK3[5"fO!<^',2_<zv~ ")L_ FD"""4w#'##q$*$=$$ %M$%-r%%r8' )P) **!+1+B++,,X,%, -E+-q-z-'-&--h-a.!h/|/001#1 112]3sS44+4 59!5[7/% 2$ ) *,'4(0." -3 1!&#+A brain (illustrated in green) that processes and reacts to events from the cluster (nodes leaving or joining) and resources (eg. monitor failures) as well as configuration changes from the administrator. In response to all of these events, Pacemaker will compute the ideal state of the cluster and plot a path to achieve it. This may include moving resources, stopping nodes and even forcing them offline with remote power switches.Ability to specify cluster-wide service ordering, colocation and anti-colocationActive/Passive RedundancyAdditionally, this document is NOT a step-by-step how-to guide for configuring a specific clustering scenario. Although such guides exist, the purpose of this document is to provide an understanding of the building blocks that can be used to construct any type of Pacemaker cluster.At the highest level, the cluster is made up of three pieces:Automatically replicated configuration that can be updated from any nodeBy supporting many nodes, Pacemaker can dramatically reduce hardware costs by allowing several active/passive clusters to be combined and share a common backup nodeCIB (aka. Cluster Information Base)CRMd (aka. Cluster Resource Management daemon)Clones: for services which need to be active on multiple nodesConceptual Stack OverviewConceptual overview of the cluster stackCore cluster infrastructure providing messaging and membership functionality (illustrated in red)Detection and recovery of node and service-level failuresFor those that are allergic to XML, Pacemaker comes with a cluster shell and a Python based GUI exists, however these tools will not be covered at all in this document It is hoped however, that having understood the concepts explained here, that the functionality of these tools will also be more readily understood. , precisely because they hide the XML.In some cases, it may be necessary to power off nodes in order to protect shared data or complete resource recovery. For this Pacemaker comes with STONITHd. STONITH is an acronym for Shoot-The-Other-Node-In-The-Head and is usually implemented with a remote power switch. In Pacemaker, STONITH devices are modeled as resources (and configured in the CIB) to enable them to be easily monitored for failure, however STONITHd takes care of understanding the STONITH topology such that its clients simply request a node be fenced and it does the rest.Internal ComponentsMulti-state: for services with multiple modes (eg. master/slave, primary/secondary)N to N RedundancyNon-cluster aware components (illustrated in blue). In a Pacemaker cluster, these pieces include not only the scripts that knows how to start, stop and monitor resources, but also a local daemon that masks the differences between the different standards these scripts implement.PEngine (aka. PE or Policy Engine)Pacemaker ArchitecturePacemaker is a cluster resource manager. It achieves maximum availability for your cluster services (aka. resources) by detecting and recovering from node and resource-level failures by making use of the messaging and membership capabilities provided by your preferred cluster infrastructure (either Corosync or Heartbeat).Pacemaker itself is composed of four key components (illustrated below in the same color scheme as the previous diagram):Pacemaker makes no assumptions about your environment, this allows it to support practically any redundancy configuration including Active/Active, Active/Passive, N+1, N+M, N-to-1 and N-to-N.Pacemaker's key features include:Read-Me-FirstResource agnostic, anything that can be scripted can be clusteredSTONITHdShared FailoverStorage agnostic, no requirement for shared storageSubsystems of a Pacemaker cluster running on CorosyncSupport for advanced services typeSupports STONITH for ensuring data integritySupports both quorate and resource driven clustersSupports large and small clustersSupports practically any redundancy configurationThe CIB uses XML to represent both the cluster's configuration and current state of all resources in the cluster. The contents of the CIB are automatically kept in sync across the entire cluster and are used by the PEngine to compute the ideal state of the cluster and how it should be achieved.The DC carries out the PEngine's instructions in the required order by passing them to either the LRMd (Local Resource Management daemon) or CRMd peers on other nodes via the cluster messaging infrastructure (which in turn passes them on to their LRMd process).The Pacemaker StackThe Pacemaker stack when running on CorosyncThe Scope of this DocumentThe peer nodes all report the results of their operations back to the DC and based on the expected and actual results, will either execute any actions that needed to wait for the previous one to complete, or abort processing and ask the PEngine to recalculate the ideal cluster state based on the unexpected results.The purpose of this document is to definitively explain the concepts used to configure Pacemaker. To achieve this best, it will focus exclusively on the XML syntax used to configure the CIB.This list of instructions is then fed to the DC (Designated Co-ordinator). Pacemaker centralizes all cluster decision making by electing one of the CRMd instances to act as a master. Should the elected CRMd process, or the node it is on, fail... a new one is quickly established.Two-node Active/Passive clusters using Pacemaker and DRBD are a cost-effective solution for many High Availability situations.Types of Pacemaker ClustersUnified, scriptable, cluster shellWhat Is Pacemaker?When combined with Corosync, Pacemaker also supports popular open source cluster filesystems Even though Pacemaker also supports Heartbeat, the filesystems need to use the stack for messaging and membership and Corosync seems to be what they're standardizing on. Technically it would be possible for them to support Heartbeat as well, however there seems little interest in this. Due to recent standardization within the cluster filesystem community, they make use of a common distributed lock manager which makes use of Corosync for its messaging capabilities and Pacemaker for its membership (which nodes are up/down) and fencing services.When shared storage is available, every node can potentially be used for failover. Pacemaker can even run multiple copies of services to spread out the workload.Project-Id-Version: 0 POT-Creation-Date: 2010-12-15T23:32:37 PO-Revision-Date: 2010-12-16 00:15+0800 Last-Translator: Charlie Chen Language-Team: None Language: MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 大脑(绿色部分)处理并响应来自集群和资源的事件(比如节点的离开和加入,资源的失效) ,以及管理员对配置文件的修改。在对所有这些事件的响应中,Pacemaker会计算集群理想的状态,并规划一个途径来实现它。这个操作可能会包含移动资源,停止节点,甚至使用远程电源管理来强制使他们下线。可以设定集群范围内的ordering, colocation and anti-colocationActive/Passive 冗余此外,本文不是一个手把手地教你配置特定集群方案的how-to guide。尽管有很多这样的内容,但是本文的主要目的是让大家理解配置Pacemaker所需要用到的各种组件。在最高一个层次,集群由三个部分组成:自动同步各个节点的配置文件正是因为支持很多节点,Pacemaker可以让多个主备模式的集群集成起来并共享一个备用节点,从而大幅度的减少硬件成本CIB (aka. 集群信息基础)CRMd (aka. 集群资源管理守护进程)Clones:为那些要在多个节点运行的服务所准备的概念层次总览集群概念层次总览提供消息和集群关系功能的集群核心基础组件(标红的部分)监测并恢复节点和服务级别的故障对于那些特别讨厌XML的人,Pacemaker有一个集群shell和基于Python的GUI,但是本文没有包含这些工具的使用 明白了本文的内容以后,会更容易理解那些工具的功能,当然这只是希望。 , 正是因为它们隐藏了XML细节。(译者注:本文中基本是crm shell来操作的,这里应该是老版本文档的遗留)在某些情况下,可能会需要关闭节点的电源来保证共享数据的完整性或是完全地恢复资源。为此Pacemaker引入了STONITHd。STONITH是 Shoot-The-Other-Node-In-The-Head(爆其他节点的头)的缩写,并且通常是靠远程电源开关来实现的。在Pacemaker中,STONITH设备被当成资源(并且是在CIB中配置)从而轻松地监控,然而STONITHd会注意理解STONITH拓扑,比如它的客户端请求隔离一个节点,它会重启那个机器。(译者注:就是说不同的爆头设备驱动会对相同的请求有不同的理解,这些都是在驱动中定义的。)内部组件Multi-state:为那些有多种模式的服务准备的。(比如.主从, 主备)N to N 冗余集群无关的组件(蓝色的部分)。在Pacemaker架构中,这部分不仅包含有怎么样启动,关闭,监控资源的脚本,而且还有一个本地的守护进程来消除这些脚本实现的(采用的)不同标准之间的差异PEngine (aka. PE or 策略引擎)Pacemaker 架构Pacemaker是一个集群资源管理者。他用资源级别的监测和恢复来保证集群服务(aka. 资源)的最大可用性。它可以用你所擅长的基础组件(Corosync或者是Heartbeat)来实现通信和关系管理。Pacemaker本身由四个关键组件组成:Pacemaker对你的环境没有特定的要求,这使得它支持任何的冗余配置,包括 Active/Active, Active/Passive, N+1, N+M, N-to-1 and N-to-N。Pacemaker包含以下的关键特性:Read-Me-First资源无关,任何能用脚本控制的资源都可以作为服务STONITHd共享失效备援存储无关,并不需要共享存储基于Corosync的Pacemaker的子系统支持高级的服务模式支持使用STONITH来保证数据一致性。clusters 支持 quorate(法定人数)resource(资源) 驱动的集群支持大型或者小型的集群支持任何的 冗余配置CIB用XML来展示集群的配置和资源的当前状态。 CIB的内容会自动地在集群之间同步,并被PEngine用来来计算集群的理想状态和如何达到这个理想状态。DC会按顺序处理PEngine的指令,然后把他们发送给LRMd(本地资源管理守护进程) 或者通过集群消息层发送给其他CRMd成员(就是把这些指令依次传给LRMd)。Pacemaker 层次Pacemaker采用Corosync时的层次本文范围节点会把他们所有操作的日志发给DC,然后根据预期的结果和实际的结果(之间的差异), 执行下一个等待中的命令,或者取消操作,并让PEngine根据非预期的结果重新计算集群的理想状态。本文的目的是透彻地解释用于配置Pacemaker的概念。为了达到最好的效果,本文会主要关注于用于配置CIB的XML格式。这个指令列表然后会被交给DC(指定协调者)。 Pacemaker会推举一个CRMd实例作为master来集中做出所有决策。如果推举的CRMd繁忙中,或者这个节点不够稳定... 一个新的master会马上被推举出来。使用Pacemaker和DRBD的双节点主备方案作为一种经济的解决方案被很多高可用环境所采用。Pacemaker 集群的种类统一的,可脚本控制的cluster shell什么是Pacemaker?当与Corosync集成时,Pacemaker也支持常见的开源集群文件系统 尽管Pacemaker也支持Heartbeat,但是文件系统也要用基层软件来通信和维护节点关系,Corosync看来是他们的标准,技术上来说,让它们支持Heartbeat也是可能的,但是看起来他们没多大兴趣 ,根据来着集群文件系统社区的最新标准,他们用一个通用的分布式锁控制器,它靠Corosync通信并且用Pacemaker管理成员关系(哪些节点是开启或关闭的)和隔离服务。当有共享存储设备是,每个节点都成为潜在的备援节点。Pacemaker甚至可以在不同的节点上跑相同的服务来负载均衡。pacemaker-master/doc/Clusters_from_Scratch/zh-CN/Ch-Intro.po000066400000000000000000000457341217637305600242730ustar00rootroot00000000000000# # AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: 0\n" "POT-Creation-Date: 2012-10-17T05:19:03\n" "PO-Revision-Date: 2010-12-16 00:15+0800\n" "Last-Translator: Charlie Chen \n" "Language-Team: None\n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. Tag: title #, no-c-format msgid "Read-Me-First" msgstr "Read-Me-First" #. Tag: title #, no-c-format msgid "The Scope of this Document" msgstr "本文范围" #. Tag: para #, no-c-format msgid "Computer clusters can be used to provide highly available services or resources. The redundancy of multiple machines is used to guard against failures of many types." msgstr "" #. Tag: para #, no-c-format msgid "This document will walk through the installation and setup of simple clusters using the Fedora distribution, version 17." msgstr "" #. Tag: para #, no-c-format msgid "The clusters described here will use Pacemaker and Corosync to provide resource management and messaging. Required packages and modifications to their configuration files are described along with the use of the Pacemaker command line tool for generating the XML used for cluster control." msgstr "" #. Tag: para #, no-c-format msgid "Pacemaker is a central component and provides the resource management required in these systems. This management includes detecting and recovering from the failure of various nodes, resources and services under its control." msgstr "" #. Tag: para #, no-c-format msgid "When more in depth information is required and for real world usage, please refer to the Pacemaker Explained manual." msgstr "" #. Tag: title #, no-c-format msgid "What Is Pacemaker?" msgstr "什么是Pacemaker?" #. Tag: para #, fuzzy, no-c-format msgid "Pacemaker is a cluster resource manager. It achieves maximum availability for your cluster services (aka. resources) by detecting and recovering from node and resource-level failures by making use of the messaging and membership capabilities provided by your preferred cluster infrastructure (either Corosync or Heartbeat)." msgstr "Pacemaker是一个集群资源管理者。他用资源级别的监测和恢复来保证集群服务(aka. 资源)的最大可用性。它可以用你所擅长的基础组件(Corosync或者是Heartbeat)来实现通信和关系管理。" #. Tag: para #, fuzzy, no-c-format msgid "Pacemaker’s key features include:" msgstr "Pacemaker包含以下的关键特性:" #. Tag: para #, no-c-format msgid "Detection and recovery of node and service-level failures" msgstr "监测并恢复节点和服务级别的故障" #. Tag: para #, no-c-format msgid "Storage agnostic, no requirement for shared storage" msgstr "存储无关,并不需要共享存储" #. Tag: para #, no-c-format msgid "Resource agnostic, anything that can be scripted can be clustered" msgstr "资源无关,任何能用脚本控制的资源都可以作为服务" #. Tag: para #, fuzzy, no-c-format msgid "Supports STONITH for ensuring data integrity" msgstr "支持使用STONITH来保证数据一致性。" #. Tag: para #, no-c-format msgid "Supports large and small clusters" msgstr "支持大型或者小型的集群" #. Tag: para #, fuzzy, no-c-format msgid "Supports both quorate and resource driven clusters" msgstr "支持大型或者小型的集群" #. Tag: para #, no-c-format msgid "Supports practically any redundancy configuration" msgstr "" #. Tag: para #, no-c-format msgid "Automatically replicated configuration that can be updated from any node" msgstr "自动同步各个节点的配置文件" #. Tag: para #, no-c-format msgid "Ability to specify cluster-wide service ordering, colocation and anti-colocation" msgstr "可以设定集群范围内的ordering, colocation and anti-colocation" #. Tag: para #, fuzzy, no-c-format msgid "Support for advanced service types" msgstr "支持高级的服务模式" #. Tag: para #, no-c-format msgid "Clones: for services which need to be active on multiple nodes" msgstr "Clones:为那些要在多个节点运行的服务所准备的" #. Tag: para #, no-c-format msgid "Multi-state: for services with multiple modes (eg. master/slave, primary/secondary)" msgstr "Multi-state:为那些有多种模式的服务准备的。(比如.主从, 主备)" #. Tag: para #, fuzzy, no-c-format msgid "Unified, scriptable, cluster management tools." msgstr "统一的,可脚本控制的cluster shell" #. Tag: title #, no-c-format msgid "Pacemaker Architecture" msgstr "Pacemaker 架构" #. Tag: para #, no-c-format msgid "At the highest level, the cluster is made up of three pieces:" msgstr "在最高一个层次,集群由三个部分组成:" #. Tag: para #, fuzzy, no-c-format msgid "Non-cluster aware components (illustrated in green). These pieces include the resources themselves, scripts that start, stop and monitor them, and also a local daemon that masks the differences between the different standards these scripts implement." msgstr "集群无关的组件(蓝色的部分)。在Pacemaker架构中,这部分不仅包含有怎么样启动,关闭,监控资源的脚本,而且还有一个本地的守护进程来消除这些脚本实现的(采用的)不同标准之间的差异" #. Tag: para #, fuzzy, no-c-format msgid "Resource management Pacemaker provides the brain (illustrated in blue) that processes and reacts to events regarding the cluster. These events include nodes joining or leaving the cluster; resource events caused by failures, maintenance, scheduled activities; and other administrative actions. Pacemaker will compute the ideal state of the cluster and plot a path to achieve it after any of these events. This may include moving resources, stopping nodes and even forcing them offline with remote power switches." msgstr "大脑(绿色部分)处理并响应来自集群和资源的事件(比如节点的离开和加入,资源的失效) ,以及管理员对配置文件的修改。在对所有这些事件的响应中,Pacemaker会计算集群理想的状态,并规划一个途径来实现它。这个操作可能会包含移动资源,停止节点,甚至使用远程电源管理来强制使他们下线。" #. Tag: para #, fuzzy, no-c-format msgid "Low level infrastructure Corosync provides reliable messaging, membership and quorum information about the cluster (illustrated in red)." msgstr "提供消息和集群关系功能的集群核心基础组件(标红的部分)" #. Tag: title #, no-c-format msgid "Conceptual Stack Overview" msgstr "概念层次总览" #. Tag: phrase #, no-c-format msgid "Conceptual overview of the cluster stack" msgstr "集群概念层次总览" #. Tag: para #, fuzzy, no-c-format msgid "When combined with Corosync, Pacemaker also supports popular open source cluster filesystems. Even though Pacemaker also supports Heartbeat, the filesystems need to use the stack for messaging and membership and Corosync seems to be what they’re standardizing on. Technically it would be possible for them to support Heartbeat as well, however there seems little interest in this." msgstr "虽然Pacemaker也支持Heartbeat,文件系统也需要一个基层软件来通信和保持关系,Corosync看起来是他们的标准。技术上来说,他们支持Heartbeat也是可能的,但是看起来他们没什么兴趣。" #. Tag: para #, no-c-format msgid "Due to recent standardization within the cluster filesystem community, they make use of a common distributed lock manager which makes use of Corosync for its messaging capabilities and Pacemaker for its membership (which nodes are up/down) and fencing services." msgstr ",根据来着集群文件系统社区的最新标准,他们用一个通用的分布式锁控制器,它用Corosync来通信并且用Pacemaker来管理关系(那些节点是开启或关闭的)和隔离服务。" #. Tag: title #, no-c-format msgid "The Pacemaker Stack" msgstr "Pacemaker 层次" #. Tag: phrase #, fuzzy, no-c-format msgid "The Pacemaker StackThe Pacemaker stack when running on Corosync" msgstr "Pacemaker采用Corosync时的层次" #. Tag: title #, no-c-format msgid "Internal Components" msgstr "内部组件" #. Tag: para #, no-c-format msgid "Pacemaker itself is composed of four key components (illustrated below in the same color scheme as the previous diagram):" msgstr "Pacemaker本身由四个关键组件组成:" #. Tag: para #, no-c-format msgid "CIB (aka. Cluster Information Base)" msgstr "CIB (aka. 集群信息基础)" #. Tag: para #, no-c-format msgid "CRMd (aka. Cluster Resource Management daemon)" msgstr "CRMd (aka. 集群资源管理守护进程)" #. Tag: para #, no-c-format msgid "PEngine (aka. PE or Policy Engine)" msgstr "PEngine (aka. PE or 策略引擎)" #. Tag: para #, no-c-format msgid "STONITHd" msgstr "STONITHd" #. Tag: phrase #, no-c-format msgid "Subsystems of a Pacemaker cluster running on Corosync" msgstr "基于Corosync的Pacemaker的子系统" #. Tag: para #, fuzzy, no-c-format msgid "The CIB uses XML to represent both the cluster’s configuration and current state of all resources in the cluster. The contents of the CIB are automatically kept in sync across the entire cluster and are used by the PEngine to compute the ideal state of the cluster and how it should be achieved." msgstr "CIB用XML来展示集群的配置和资源的当前状态。 CIB的内容会自动地在集群之间同步,并被PEngine用来来计算集群的理想状态和如何达到这个理想状态。" #. Tag: para #, fuzzy, no-c-format msgid "This list of instructions is then fed to the DC (Designated Co-ordinator). Pacemaker centralizes all cluster decision making by electing one of the CRMd instances to act as a master. Should the elected CRMd process, or the node it is on, fail… a new one is quickly established." msgstr "这个指令列表然后会被交给DC(指定协调者)。 Pacemaker会推举一个CRMd实例作为master来集中做出所有决策。如果推举的CRMd繁忙中,或者这个节点不够稳定... 一个新的master会马上被推举出来。" #. Tag: para #, fuzzy, no-c-format msgid "The DC carries out the PEngine’s instructions in the required order by passing them to either the LRMd (Local Resource Management daemon) or CRMd peers on other nodes via the cluster messaging infrastructure (which in turn passes them on to their LRMd process)." msgstr "DC会按顺序处理PEngine的指令,然后把他们发送给LRMd(本地资源管理守护进程) 或者通过集群消息层发送给其他CRMd成员(就是把这些指令依次传给LRMd)。" #. Tag: para #, no-c-format msgid "The peer nodes all report the results of their operations back to the DC and based on the expected and actual results, will either execute any actions that needed to wait for the previous one to complete, or abort processing and ask the PEngine to recalculate the ideal cluster state based on the unexpected results." msgstr "节点会把他们所有操作的日志发给DC,然后根据预期的结果和实际的结果(之间的差异), 执行下一个等待中的命令,或者取消操作,并让PEngine根据非预期的结果重新计算集群的理想状态。" #. Tag: para #, no-c-format msgid "In some cases, it may be necessary to power off nodes in order to protect shared data or complete resource recovery. For this Pacemaker comes with STONITHd. STONITH is an acronym for Shoot-The-Other-Node-In-The-Head and is usually implemented with a remote power switch. In Pacemaker, STONITH devices are modeled as resources (and configured in the CIB) to enable them to be easily monitored for failure, however STONITHd takes care of understanding the STONITH topology such that its clients simply request a node be fenced and it does the rest." msgstr "在某些情况下,可能会需要关闭节点的电源来保证共享数据的完整性或是完全地恢复资源。为此Pacemaker引入了STONITHd。STONITH是 Shoot-The-Other-Node-In-The-Head(爆其他节点的头)的缩写,并且通常是靠远程电源开关来实现的。在Pacemaker中,STONITH设备被当成资源(并且是在CIB中配置)从而轻松地监控,然而STONITHd会注意理解STONITH拓扑,比如它的客户端请求隔离一个节点,它会重启那个机器。(译者注:就是说不同的爆头设备驱动会对相同的请求有不同的理解,这些都是在驱动中定义的。)" #. Tag: title #, no-c-format msgid "Types of Pacemaker Clusters" msgstr "Pacemaker 集群的种类" #. Tag: para #, no-c-format msgid "Pacemaker makes no assumptions about your environment, this allows it to support practically any redundancy configuration including Active/Active, Active/Passive, N+1, N+M, N-to-1 and N-to-N." msgstr "Pacemaker对你的环境没有特定的要求,这使得它支持任何的冗余配置,包括 Active/Active, Active/Passive, N+1, N+M, N-to-1 and N-to-N。" #. Tag: para #, no-c-format msgid "In this document we will focus on the setup of a highly available Apache web server with an Active/Passive cluster using DRBD and Ext4 to store data. Then, we will upgrade this cluster to Active/Active using GFS2." msgstr "" #. Tag: title #, no-c-format msgid "Active/Passive Redundancy" msgstr "Active/Passive 冗余" #. Tag: phrase #, fuzzy, no-c-format msgid "Two-node Active/Passive clusters using Pacemaker and DRBD are a cost-effective solution for many High Availability situations" msgstr "使用Pacemaker和DRBD的双节点主备方案作为一种经济的解决方案被很多高可用环境所采用。" #. Tag: title #, no-c-format msgid "N to N Redundancy" msgstr "N to N 冗余" #. Tag: phrase #, fuzzy, no-c-format msgid "When shared storage is available, every node can potentially be used for failover. Pacemaker can even run multiple copies of services to spread out the workload" msgstr "当有共享存储设备是,每个节点都成为潜在的备援节点。Pacemaker甚至可以在不同的节点上跑相同的服务来负载均衡。" #~ msgid "The purpose of this document is to definitively explain the concepts used to configure Pacemaker. To achieve this best, it will focus exclusively on the XML syntax used to configure the CIB." #~ msgstr "本文的目的是透彻地解释用于配置Pacemaker的概念。为了达到最好的效果,本文会主要关注于用于配置CIB的XML格式。" #~ msgid "For those that are allergic to XML, Pacemaker comes with a cluster shell and a Python based GUI exists, however these tools will not be covered at all in this document It is hoped however, that having understood the concepts explained here, that the functionality of these tools will also be more readily understood. , precisely because they hide the XML." #~ msgstr "对于那些特别讨厌XML的人,Pacemaker有一个集群shell和基于Python的GUI,但是本文没有包含这些工具的使用 明白了本文的内容以后,会更容易理解那些工具的功能,当然这只是希望。 , 正是因为它们隐藏了XML细节。(译者注:本文中基本是crm shell来操作的,这里应该是老版本文档的遗留)" #~ msgid "Additionally, this document is NOT a step-by-step how-to guide for configuring a specific clustering scenario. Although such guides exist, the purpose of this document is to provide an understanding of the building blocks that can be used to construct any type of Pacemaker cluster." #~ msgstr "此外,本文不是一个手把手地教你配置特定集群方案的how-to guide。尽管有很多这样的内容,但是本文的主要目的是让大家理解配置Pacemaker所需要用到的各种组件。" #~ msgid "Supports both quorate and resource driven clusters" #~ msgstr "clusters 支持 quorate(法定人数)resource(资源) 驱动的集群" #~ msgid "Supports practically any redundancy configuration" #~ msgstr "支持任何的 冗余配置" #~ msgid "Shared Failover" #~ msgstr "共享失效备援" #~ msgid "By supporting many nodes, Pacemaker can dramatically reduce hardware costs by allowing several active/passive clusters to be combined and share a common backup node" #~ msgstr "正是因为支持很多节点,Pacemaker可以让多个主备模式的集群集成起来并共享一个备用节点,从而大幅度的减少硬件成本" #~ msgid "When combined with Corosync, Pacemaker also supports popular open source cluster filesystems Even though Pacemaker also supports Heartbeat, the filesystems need to use the stack for messaging and membership and Corosync seems to be what they're standardizing on. Technically it would be possible for them to support Heartbeat as well, however there seems little interest in this. Due to recent standardization within the cluster filesystem community, they make use of a common distributed lock manager which makes use of Corosync for its messaging capabilities and Pacemaker for its membership (which nodes are up/down) and fencing services." #~ msgstr "当与Corosync集成时,Pacemaker也支持常见的开源集群文件系统 尽管Pacemaker也支持Heartbeat,但是文件系统也要用基层软件来通信和维护节点关系,Corosync看来是他们的标准,技术上来说,让它们支持Heartbeat也是可能的,但是看起来他们没多大兴趣 ,根据来着集群文件系统社区的最新标准,他们用一个通用的分布式锁控制器,它靠Corosync通信并且用Pacemaker管理成员关系(哪些节点是开启或关闭的)和隔离服务。" #~ msgid "For those that are allergic to XML, Pacemaker comes with a cluster shell and a Python based GUI exists, however these tools will not be covered at all in this document" #~ msgstr "对于那些特别讨厌XML的人,Pacemaker有一个集群shell和基于Python的GUI,但是本文没有包含这些工具的使用" #~ msgid "It is hoped however, that having understood the concepts explained here, that the functionality of these tools will also be more readily understood." #~ msgstr "这只是希望,如果理解了这里的内容,那些工具的功能可以更好理解。" #~ msgid ", precisely because they hide the XML." #~ msgstr ", 正是因为它们隐藏了XML细节" #~ msgid "When combined with Corosync, Pacemaker also supports popular open source cluster filesystems" #~ msgstr "当与Corosync集成时,Pacemaker也支持常见的开源集群文件系统" pacemaker-master/doc/Clusters_from_Scratch/zh-CN/Ch-Shared-Storage.mo000066400000000000000000001152401217637305600257730ustar00rootroot000000000000008O 5 @I ;^!$U,a(00d3T9N<U=c\?z?G;@@@@@A[}CC0DDDD`EC^FFGGxG5vHH1IqIRJjJG2KzKK;4LpLwL)L$MlMK%OqOONP`QWY@\ ]_b[dOf^IkpUYya|}ۅՈU9GHe ЌlJjL0B"=eM0vȓ?lOf]q; G{TЗoMZ6 ߙ )+$ '75(0%/4&6!*. - 2 ,"831# [root@pcmk-1 ~]# crm configure show node pcmk-1 node pcmk-2 primitive WebData ocf:linbit:drbd \         params drbd_resource="wwwdata" \         op monitor interval="60s" primitive WebFS ocf:heartbeat:Filesystem \         params device="/dev/drbd/by-res/wwwdata" directory="/var/www/html" fstype="ext4" primitive WebSite ocf:heartbeat:apache \         params configfile="/etc/httpd/conf/httpd.conf" \         op monitor interval="1min" primitive ClusterIP ocf:heartbeat:IPaddr2 \         params ip="192.168.122.101" cidr_netmask="32" \         op monitor interval="30s" ms WebDataClone WebData \         meta master-max="1" master-node-max="1" clone-max="2" clone-node-max="1" notify="true" location prefer-pcmk-1 WebSite 50: pcmk-1 colocation WebSite-with-WebFS inf: WebSite WebFS colocation fs_on_drbd inf: WebFS WebDataClone:Master colocation website-with-ip inf: WebSite ClusterIP order WebFS-after-WebData inf: WebDataClone:promote WebFS:start order WebSite-after-WebFS inf: WebFS WebSite order apache-after-ip inf: ClusterIP WebSite property $id="cib-bootstrap-options" \         dc-version="1.0.5-462f1569a43740667daf7b0f6b521742e9eb8fa7" \         cluster-infrastructure="openais" \         expected-quorum-votes=”2” \         stonith-enabled="false" \         no-quorum-policy="ignore" rsc_defaults $id="rsc-options" \         resource-stickiness=”100” [root@pcmk-1 ~]# crm node online [root@pcmk-1 ~]# crm_mon ============ Last updated: Tue Sep  1 10:13:25 2009 Stack: openais Current DC: pcmk-1 - partition with quorum Version: 1.0.5-462f1569a43740667daf7b0f6b521742e9eb8fa7 2 Nodes configured, 2 expected votes 4 Resources configured. ============ Online: [ pcmk-1 pcmk-2 ] ClusterIP        (ocf::heartbeat:IPaddr):        Started pcmk-2 WebSite (ocf::heartbeat:apache):        Started pcmk-2 Master/Slave Set: WebDataClone         Masters: [ pcmk-2 ]         Slaves: [ pcmk-1 ] WebFS   (ocf::heartbeat:Filesystem):    Started pcmk-2 [root@pcmk-1 ~]# crm node standby [root@pcmk-1 ~]# crm_mon ============ Last updated: Tue Sep  1 10:09:57 2009 Stack: openais Current DC: pcmk-1 - partition with quorum Version: 1.0.5-462f1569a43740667daf7b0f6b521742e9eb8fa7 2 Nodes configured, 2 expected votes 4 Resources configured. ============ Node pcmk-1: standby Online: [ pcmk-2 ] ClusterIP        (ocf::heartbeat:IPaddr):        Started pcmk-2 WebSite (ocf::heartbeat:apache):        Started pcmk-2 Master/Slave Set: WebDataClone         Masters: [ pcmk-2 ]         Stopped: [ WebData:1 ] WebFS   (ocf::heartbeat:Filesystem):    Started pcmk-2 [root@pcmk-1 ~]# crm cib crm(live)# [root@pcmk-1 ~]# crm crm(live)# cib new fs INFO: fs shadow CIB created crm(fs)# configure primitive WebFS ocf:heartbeat:Filesystem \         params device="/dev/drbd/by-res/wwwdata" directory="/var/www/html" fstype="ext4" crm(fs)# configure colocation fs_on_drbd inf: WebFS WebDataClone:Master crm(fs)# configure order WebFS-after-WebData inf: WebDataClone:promote WebFS:start [root@pcmk-1 ~]# drbdadm -- --overwrite-data-of-peer primary wwwdata [root@pcmk-1 ~]# cat /proc/drbd version: 8.3.6 (api:88/proto:86-90) GIT-hash: f3606c47cc6fcf6b3f086e425cb34af8b7a81bbf build by root@pcmk-1, 2009-12-08 11:22:57  1: cs:SyncSource ro:Primary/Secondary ds:UpToDate/Inconsistent C r----     ns:2184 nr:0 dw:0 dr:2472 al:0 bm:0 lo:0 pe:0 ua:0 ap:0 ep:1 wo:b oos:10064         [=====>..............] sync'ed: 33.4% (10064/12248)K         finish: 0:00:37 speed: 240 (240) K/sec [root@pcmk-1 ~]# cat /proc/drbd version: 8.3.6 (api:88/proto:86-90) GIT-hash: f3606c47cc6fcf6b3f086e425cb34af8b7a81bbf build by root@pcmk-1, 2009-12-08 11:22:57  1: cs:Connected ro:Primary/Secondary ds:UpToDate/UpToDate C r----     ns:12248 nr:0 dw:0 dr:12536 al:0 bm:1 lo:0 pe:0 ua:0 ap:0 ep:1 wo:b oos:0 [root@pcmk-1 ~]# drbdadm create-md wwwdata md_offset 12578816 al_offset 12546048 bm_offset 12541952 Found some data  ==> This might destroy existing data! <== Do you want to proceed? [need to type 'yes' to confirm] yes Writing meta data... initializing activity log NOT initialized bitmap New drbd meta data block successfully created. success [root@pcmk-1 ~]# lvcreate -n drbd-demo -L 1G VolGroup   Logical volume "drbd-demo" created [root@pcmk-1 ~]# lvs   LV        VG       Attr   LSize   Origin Snap%  Move Log Copy%  Convert   drbd-demo VolGroup -wi-a- 1.00G                                         lv_root   VolGroup -wi-ao   7.30G                                         lv_swap   VolGroup -wi-ao 500.00M [root@pcmk-1 ~]# mkfs.ext4 /dev/drbd1 mke2fs 1.41.4 (27-Jan-2009) Filesystem label= OS type: Linux Block size=1024 (log=0) Fragment size=1024 (log=0) 3072 inodes, 12248 blocks 612 blocks (5.00%) reserved for the super user First data block=1 Maximum filesystem blocks=12582912 2 block groups 8192 blocks per group, 8192 fragments per group 1536 inodes per group Superblock backups stored on blocks:         8193 Writing inode tables: done                             Creating journal (1024 blocks): done Writing superblocks and filesystem accounting information: done This filesystem will be automatically checked every 26 mounts or 180 days, whichever comes first.  Use tune2fs -c or -i to override. Now mount the newly created filesystem so we can create our index file mount /dev/drbd1 /mnt/ cat <<-END >/mnt/index.html <html> <body>My Test Site - drbd</body> </html> END umount /dev/drbd1 [root@pcmk-1 ~]# mount /dev/drbd1 /mnt/ [root@pcmk-1 ~]# cat <<-END >/mnt/index.html > <html> > <body>My Test Site - drbd</body> > </html> > END [root@pcmk-1 ~]# umount /dev/drbd1 [root@pcmk-1 ~]# modprobe drbd [root@pcmk-1 ~]# drbdadm up wwwdata [root@pcmk-1 ~]# cat /proc/drbd version: 8.3.6 (api:88/proto:86-90) GIT-hash: f3606c47cc6fcf6b3f086e425cb34af8b7a81bbf build by root@pcmk-1, 2009-12-08 11:22:57 1: cs:WFConnection ro:Secondary/Unknown ds:Inconsistent/DUnknown C r----     ns:0 nr:0 dw:0 dr:0 al:0 bm:0 lo:0 pe:0 ua:0 ap:0 ep:1 wo:b oos:12248 [root@pcmk-1 ~]# Repeat on the second node drbdadm --force create-md wwwdata modprobe drbd drbdadm up wwwdata cat /proc/drbd [root@pcmk-2 ~]# drbdadm --force create-md wwwdata Writing meta data... initializing activity log NOT initialized bitmap New drbd meta data block successfully created. success [root@pcmk-2 ~]# modprobe drbd WARNING: Deprecated config file /etc/modprobe.conf, all config files belong into /etc/modprobe.d/. [root@pcmk-2 ~]# drbdadm up wwwdata [root@pcmk-2 ~]# cat /proc/drbd version: 8.3.6 (api:88/proto:86-90) GIT-hash: f3606c47cc6fcf6b3f086e425cb34af8b7a81bbf build by root@pcmk-1, 2009-12-08 11:22:57 1: cs:Connected ro:Secondary/Secondary ds:Inconsistent/Inconsistent C r----     ns:0 nr:0 dw:0 dr:0 al:0 bm:0 lo:0 pe:0 ua:0 ap:0 ep:1 wo:b oos:12248 [root@pcmk-1 ~]# yum install -y drbd-pacemaker Loaded plugins: presto, refresh-packagekit Setting up Install Process Resolving Dependencies --> Running transaction check ---> Package drbd-pacemaker.x86_64 0:8.3.7-2.fc13 set to be updated --> Processing Dependency: drbd-utils = 8.3.7-2.fc13 for package: drbd-pacemaker-8.3.7-2.fc13.x86_64 --> Running transaction check ---> Package drbd-utils.x86_64 0:8.3.7-2.fc13 set to be updated --> Finished Dependency Resolution Dependencies Resolved ================================================================================= Package Arch Version Repository Size ================================================================================= Installing: drbd-pacemaker x86_64 8.3.7-2.fc13 fedora 19 k Installing for dependencies: drbd-utils x86_64 8.3.7-2.fc13 fedora 165 k Transaction Summary ================================================================================= Install 2 Package(s) Upgrade 0 Package(s) Total download size: 184 k Installed size: 427 k Downloading Packages: Setting up and reading Presto delta metadata fedora/prestodelta | 1.7 kB 00:00 Processing delta metadata Package(s) data still to download: 184 k (1/2): drbd-pacemaker-8.3.7-2.fc13.x86_64.rpm | 19 kB 00:01 (2/2): drbd-utils-8.3.7-2.fc13.x86_64.rpm | 165 kB 00:02 --------------------------------------------------------------------------------- Total 45 kB/s | 184 kB 00:04 Running rpm_check_debug Running Transaction Test Transaction Test Succeeded Running Transaction Installing : drbd-utils-8.3.7-2.fc13.x86_64 1/2 Installing : drbd-pacemaker-8.3.7-2.fc13.x86_64 2/2 Installed: drbd-pacemaker.x86_64 0:8.3.7-2.fc13 Dependency Installed: drbd-utils.x86_64 0:8.3.7-2.fc13 Complete! [root@pcmk-1 ~]# [root@pcmk-2 ~]# lvs   LV      VG       Attr   LSize   Origin Snap%  Move Log Copy%  Convert   lv_root VolGroup -wi-ao   7.30G                                         lv_swap VolGroup -wi-ao 500.00M                                       [root@pcmk-2 ~]# lvcreate -n drbd-demo -L 1G VolGroup   Logical volume "drbd-demo" created [root@pcmk-2 ~]# lvs   LV        VG       Attr   LSize   Origin Snap%  Move Log Copy%  Convert   drbd-demo VolGroup -wi-a- 1.00G                                         lv_root   VolGroup -wi-ao   7.30G                                         lv_swap   VolGroup -wi-ao 500.00M cib crm(live)# cib new drbd INFO: drbd shadow CIB created crm(drbd)# crm(drbd)# cib commit drbd INFO: commited 'drbd' shadow CIB to the cluster crm(drbd)# quit bye [root@pcmk-1 ~]# crm_mon ============ Last updated: Tue Sep  1 09:37:13 2009 Stack: openais Current DC: pcmk-1 - partition with quorum Version: 1.0.5-462f1569a43740667daf7b0f6b521742e9eb8fa7 2 Nodes configured, 2 expected votes 3 Resources configured. ============ Online: [ pcmk-1 pcmk-2 ] ClusterIP        (ocf::heartbeat:IPaddr):        Started pcmk-1 WebSite (ocf::heartbeat:apache):        Started pcmk-1 Master/Slave Set: WebDataClone Masters: [ pcmk-2 ] Slaves: [ pcmk-1 ] crm(drbd)# configure primitive WebData ocf:linbit:drbd params drbd_resource=wwwdata \         op monitor interval=60s crm(drbd)# configure ms WebDataClone WebData meta master-max=1 master-node-max=1 \         clone-max=2 clone-node-max=1 notify=true crm(drbd)# configure show node pcmk-1 node pcmk-2 primitive WebData ocf:linbit:drbd \ params drbd_resource="wwwdata" \ op monitor interval="60s" primitive WebSite ocf:heartbeat:apache \         params configfile="/etc/httpd/conf/httpd.conf" \         op monitor interval="1min" primitive ClusterIP ocf:heartbeat:IPaddr2 \         params ip="192.168.122.101" cidr_netmask="32" \         op monitor interval="30s" ms WebDataClone WebData \ meta master-max="1" master-node-max="1" clone-max="2" clone-node-max="1" notify="true" location prefer-pcmk-1 WebSite 50: pcmk-1 colocation website-with-ip inf: WebSite ClusterIP order apache-after-ip inf: ClusterIP WebSite property $id="cib-bootstrap-options" \         dc-version="1.0.5-462f1569a43740667daf7b0f6b521742e9eb8fa7" \         cluster-infrastructure="openais" \         expected-quorum-votes=”2” \         stonith-enabled="false" \         no-quorum-policy="ignore" rsc_defaults $id="rsc-options" \         resource-stickiness=”100” crm(fs)# cib commit fs INFO: commited 'fs' shadow CIB to the cluster crm(fs)# quit bye [root@pcmk-1 ~]# crm_mon ============ Last updated: Tue Sep  1 10:08:44 2009 Stack: openais Current DC: pcmk-1 - partition with quorum Version: 1.0.5-462f1569a43740667daf7b0f6b521742e9eb8fa7 2 Nodes configured, 2 expected votes 4 Resources configured. ============ Online: [ pcmk-1 pcmk-2 ] ClusterIP        (ocf::heartbeat:IPaddr):        Started pcmk-1 WebSite (ocf::heartbeat:apache): Started pcmk-1 Master/Slave Set: WebDataClone         Masters: [ pcmk-1 ]         Slaves: [ pcmk-2 ] WebFS (ocf::heartbeat:Filesystem): Started pcmk-1 crm(fs)# configure colocation WebSite-with-WebFS inf: WebSite WebFS crm(fs)# configure order WebSite-after-WebFS inf: WebFS WebSite global {   usage-count yes; } common {   protocol C; } resource wwwdata {   meta-disk internal;   device    /dev/drbd1;   syncer {     verify-alg sha1;   }   net {     allow-two-primaries;   }   on pcmk-1 {     disk      /dev/mapper/VolGroup-drbd--demo;     address   192.168.122.101:7789;   }   on pcmk-2 {     disk      /dev/mapper/VolGroup-drbd--demo;     address   192.168.122.102:7789;   } } After reviewing the new configuration, we again upload it and watch the cluster put it into effect.Be sure to use the names and addresses of your nodes if they differ from the ones used in this guide.Before we configure DRBD, we need to set aside some disk for it to use.Configure DRBDConfigure the Cluster for DRBDCreate A Partition for DRBDDetailed information on the directives used in this configuration (and other alternatives) is available from http://www.drbd.org/users-guide/ch-configure.htmlEven if you’re serving up static websites, having to manually synchronize the contents of that website to all the machines in the cluster is not ideal. For dynamic websites, such as a wiki, its not even an option. Not everyone care afford network-attached storage but somehow the data needs to be kept in sync. Enter DRBD which can be thought of as network based RAID-1. See http://www.drbd.org/ for more details.First we launch the shell. The prompt will change to indicate you’re in interactive mode.If you have more than 1Gb free, feel free to use it. For this guide however, 1Gb is plenty of space for a single html file and sufficient for later holding the GFS2 metadata.Include details on adding a second DRBD resourceInitialize and Load DRBDInstall the DRBD PackagesNext we must create a working copy or the current configuration. This is where all our changes will go. The cluster will not see any of them until we say its ok. Notice again how the prompt changes, this time to indicate that we’re no longer looking at the live cluster.Notice that our resource stickiness settings prevent the services from migrating back to pcmk-1.Now load the DRBD kernel module and confirm that everything is saneNow that DRBD is functioning we can configure a Filesystem resource to use it. In addition to the filesystem’s definition, we also need to tell the cluster where it can be located (only on the DRBD Primary) and when it is allowed to start (after the Primary was promoted).Now we can create our DRBD clone and display the revised configuration.Now we need to tell DRBD which set of data to use. Since both sides contain garbage, we can run the following on pcmk-1:Once again we’ll use the shell’s interactive modeOnce we’re happy with the changes, we can tell the cluster to start using them and use crm_mon to check everything is functioning.Once we’ve done everything we needed to on pcmk-1 (in this case nothing, we just wanted to see the resources move), we can allow the node to be a full cluster member again.One handy feature of the crm shell is that you can use it in interactive mode to make several changes atomically.Populate DRBD with DataPut the local node into standby mode and observe the cluster move all the resources to the other node. Note also that the node’s status will change to indicate that it can no longer host resources.Repeat this on the second node, be sure to use the same size partition.Replicated Storage with DRBDSince its inclusion in the upstream 2.6.33 kernel, everything needed to use DRBD ships with &DISTRO; &DISTRO_VERSION;. All you need to do is install it:TODO: Explain the reason for the allow-two-primaries optionTesting MigrationThere is no series of commands for build a DRBD configuration, so simply copy the configuration below to /etc/drbd.confTime to review the updated configuration:We also need to tell the cluster that Apache needs to run on the same machine as the filesystem and that it must be active before Apache can start.We could shut down the active node again, but another way to safely simulate recovery is to put the node into what is called “standby mode”. Nodes in this state tell the cluster that they are not allowed to run resources. Any resources found active there will be moved elsewhere. This feature can be particularly useful when updating the resources’ packages.With the configuration in place, we can now perform the DRBD initializationWrite the DRBD Configpcmk-1 is now in the Primary state which allows it to be written to. Which means its a good point at which to create a filesystem and populate it with some data to serve up via our WebSite resource.Project-Id-Version: 0 POT-Creation-Date: 2010-12-15T23:32:37 PO-Revision-Date: 2010-12-16 00:32+0800 Last-Translator: Charlie Chen Language-Team: None Language: MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [root@pcmk-1 ~]# crm configure show node pcmk-1 node pcmk-2 primitive WebData ocf:linbit:drbd \         params drbd_resource="wwwdata" \         op monitor interval="60s" primitive WebFS ocf:heartbeat:Filesystem \         params device="/dev/drbd/by-res/wwwdata" directory="/var/www/html" fstype="ext4" primitive WebSite ocf:heartbeat:apache \         params configfile="/etc/httpd/conf/httpd.conf" \         op monitor interval="1min" primitive ClusterIP ocf:heartbeat:IPaddr2 \         params ip="192.168.122.101" cidr_netmask="32" \         op monitor interval="30s" ms WebDataClone WebData \         meta master-max="1" master-node-max="1" clone-max="2" clone-node-max="1" notify="true" location prefer-pcmk-1 WebSite 50: pcmk-1 colocation WebSite-with-WebFS inf: WebSite WebFS colocation fs_on_drbd inf: WebFS WebDataClone:Master colocation website-with-ip inf: WebSite ClusterIP order WebFS-after-WebData inf: WebDataClone:promote WebFS:start order WebSite-after-WebFS inf: WebFS WebSite order apache-after-ip inf: ClusterIP WebSite property $id="cib-bootstrap-options" \         dc-version="1.0.5-462f1569a43740667daf7b0f6b521742e9eb8fa7" \         cluster-infrastructure="openais" \         expected-quorum-votes=”2” \         stonith-enabled="false" \         no-quorum-policy="ignore" rsc_defaults $id="rsc-options" \         resource-stickiness=”100” [root@pcmk-1 ~]# crm node online [root@pcmk-1 ~]# crm_mon ============ Last updated: Tue Sep  1 10:13:25 2009 Stack: openais Current DC: pcmk-1 - partition with quorum Version: 1.0.5-462f1569a43740667daf7b0f6b521742e9eb8fa7 2 Nodes configured, 2 expected votes 4 Resources configured. ============ Online: [ pcmk-1 pcmk-2 ] ClusterIP        (ocf::heartbeat:IPaddr):        Started pcmk-2 WebSite (ocf::heartbeat:apache):        Started pcmk-2 Master/Slave Set: WebDataClone         Masters: [ pcmk-2 ]         Slaves: [ pcmk-1 ] WebFS   (ocf::heartbeat:Filesystem):    Started pcmk-2 [root@pcmk-1 ~]# crm node standby [root@pcmk-1 ~]# crm_mon ============ Last updated: Tue Sep  1 10:09:57 2009 Stack: openais Current DC: pcmk-1 - partition with quorum Version: 1.0.5-462f1569a43740667daf7b0f6b521742e9eb8fa7 2 Nodes configured, 2 expected votes 4 Resources configured. ============ Node pcmk-1: standby Online: [ pcmk-2 ] ClusterIP        (ocf::heartbeat:IPaddr):        Started pcmk-2 WebSite (ocf::heartbeat:apache):        Started pcmk-2 Master/Slave Set: WebDataClone         Masters: [ pcmk-2 ]         Stopped: [ WebData:1 ] WebFS   (ocf::heartbeat:Filesystem):    Started pcmk-2 [root@pcmk-1 ~]# crm cib crm(live)# [root@pcmk-1 ~]# crm crm(live)# cib new fs INFO: fs shadow CIB created crm(fs)# configure primitive WebFS ocf:heartbeat:Filesystem \         params device="/dev/drbd/by-res/wwwdata" directory="/var/www/html" fstype="ext4" crm(fs)# configure colocation fs_on_drbd inf: WebFS WebDataClone:Master crm(fs)# configure order WebFS-after-WebData inf: WebDataClone:promote WebFS:start [root@pcmk-1 ~]# drbdadm -- --overwrite-data-of-peer primary wwwdata [root@pcmk-1 ~]# cat /proc/drbd version: 8.3.6 (api:88/proto:86-90) GIT-hash: f3606c47cc6fcf6b3f086e425cb34af8b7a81bbf build by root@pcmk-1, 2009-12-08 11:22:57  1: cs:SyncSource ro:Primary/Secondary ds:UpToDate/Inconsistent C r----     ns:2184 nr:0 dw:0 dr:2472 al:0 bm:0 lo:0 pe:0 ua:0 ap:0 ep:1 wo:b oos:10064         [=====>..............] sync'ed: 33.4% (10064/12248)K         finish: 0:00:37 speed: 240 (240) K/sec [root@pcmk-1 ~]# cat /proc/drbd version: 8.3.6 (api:88/proto:86-90) GIT-hash: f3606c47cc6fcf6b3f086e425cb34af8b7a81bbf build by root@pcmk-1, 2009-12-08 11:22:57  1: cs:Connected ro:Primary/Secondary ds:UpToDate/UpToDate C r----     ns:12248 nr:0 dw:0 dr:12536 al:0 bm:1 lo:0 pe:0 ua:0 ap:0 ep:1 wo:b oos:0 [root@pcmk-1 ~]# drbdadm create-md wwwdata md_offset 12578816 al_offset 12546048 bm_offset 12541952 Found some data  ==> This might destroy existing data! <== Do you want to proceed? [need to type 'yes' to confirm] yes Writing meta data... initializing activity log NOT initialized bitmap New drbd meta data block successfully created. success [root@pcmk-1 ~]# lvcreate -n drbd-demo -L 1G VolGroup   Logical volume "drbd-demo" created [root@pcmk-1 ~]# lvs   LV        VG       Attr   LSize   Origin Snap%  Move Log Copy%  Convert   drbd-demo VolGroup -wi-a- 1.00G                                         lv_root   VolGroup -wi-ao   7.30G                                         lv_swap   VolGroup -wi-ao 500.00M [root@pcmk-1 ~]# mkfs.ext4 /dev/drbd1 mke2fs 1.41.4 (27-Jan-2009) Filesystem label= OS type: Linux Block size=1024 (log=0) Fragment size=1024 (log=0) 3072 inodes, 12248 blocks 612 blocks (5.00%) reserved for the super user First data block=1 Maximum filesystem blocks=12582912 2 block groups 8192 blocks per group, 8192 fragments per group 1536 inodes per group Superblock backups stored on blocks:         8193 Writing inode tables: done                             Creating journal (1024 blocks): done Writing superblocks and filesystem accounting information: done This filesystem will be automatically checked every 26 mounts or 180 days, whichever comes first.  Use tune2fs -c or -i to override. Now mount the newly created filesystem so we can create our index file mount /dev/drbd1 /mnt/ cat <<-END >/mnt/index.html <html> <body>My Test Site - drbd</body> </html> END umount /dev/drbd1 [root@pcmk-1 ~]# mount /dev/drbd1 /mnt/ [root@pcmk-1 ~]# cat <<-END >/mnt/index.html > <html> > <body>My Test Site - drbd</body> > </html> > END [root@pcmk-1 ~]# umount /dev/drbd1 [root@pcmk-1 ~]# modprobe drbd [root@pcmk-1 ~]# drbdadm up wwwdata [root@pcmk-1 ~]# cat /proc/drbd version: 8.3.6 (api:88/proto:86-90) GIT-hash: f3606c47cc6fcf6b3f086e425cb34af8b7a81bbf build by root@pcmk-1, 2009-12-08 11:22:57 1: cs:WFConnection ro:Secondary/Unknown ds:Inconsistent/DUnknown C r----     ns:0 nr:0 dw:0 dr:0 al:0 bm:0 lo:0 pe:0 ua:0 ap:0 ep:1 wo:b oos:12248 [root@pcmk-1 ~]# Repeat on the second node drbdadm --force create-md wwwdata modprobe drbd drbdadm up wwwdata cat /proc/drbd [root@pcmk-2 ~]# drbdadm --force create-md wwwdata Writing meta data... initializing activity log NOT initialized bitmap New drbd meta data block successfully created. success [root@pcmk-2 ~]# modprobe drbd WARNING: Deprecated config file /etc/modprobe.conf, all config files belong into /etc/modprobe.d/. [root@pcmk-2 ~]# drbdadm up wwwdata [root@pcmk-2 ~]# cat /proc/drbd version: 8.3.6 (api:88/proto:86-90) GIT-hash: f3606c47cc6fcf6b3f086e425cb34af8b7a81bbf build by root@pcmk-1, 2009-12-08 11:22:57 1: cs:Connected ro:Secondary/Secondary ds:Inconsistent/Inconsistent C r----     ns:0 nr:0 dw:0 dr:0 al:0 bm:0 lo:0 pe:0 ua:0 ap:0 ep:1 wo:b oos:12248 [root@pcmk-1 ~]# yum install -y drbd-pacemaker Loaded plugins: presto, refresh-packagekit Setting up Install Process Resolving Dependencies --> Running transaction check ---> Package drbd-pacemaker.x86_64 0:8.3.7-2.fc13 set to be updated --> Processing Dependency: drbd-utils = 8.3.7-2.fc13 for package: drbd-pacemaker-8.3.7-2.fc13.x86_64 --> Running transaction check ---> Package drbd-utils.x86_64 0:8.3.7-2.fc13 set to be updated --> Finished Dependency Resolution Dependencies Resolved ================================================================================= Package Arch Version Repository Size ================================================================================= Installing: drbd-pacemaker x86_64 8.3.7-2.fc13 fedora 19 k Installing for dependencies: drbd-utils x86_64 8.3.7-2.fc13 fedora 165 k Transaction Summary ================================================================================= Install 2 Package(s) Upgrade 0 Package(s) Total download size: 184 k Installed size: 427 k Downloading Packages: Setting up and reading Presto delta metadata fedora/prestodelta | 1.7 kB 00:00 Processing delta metadata Package(s) data still to download: 184 k (1/2): drbd-pacemaker-8.3.7-2.fc13.x86_64.rpm | 19 kB 00:01 (2/2): drbd-utils-8.3.7-2.fc13.x86_64.rpm | 165 kB 00:02 --------------------------------------------------------------------------------- Total 45 kB/s | 184 kB 00:04 Running rpm_check_debug Running Transaction Test Transaction Test Succeeded Running Transaction Installing : drbd-utils-8.3.7-2.fc13.x86_64 1/2 Installing : drbd-pacemaker-8.3.7-2.fc13.x86_64 2/2 Installed: drbd-pacemaker.x86_64 0:8.3.7-2.fc13 Dependency Installed: drbd-utils.x86_64 0:8.3.7-2.fc13 Complete! [root@pcmk-1 ~]# [root@pcmk-2 ~]# lvs   LV      VG       Attr   LSize   Origin Snap%  Move Log Copy%  Convert   lv_root VolGroup -wi-ao   7.30G                                         lv_swap VolGroup -wi-ao 500.00M                                       [root@pcmk-2 ~]# lvcreate -n drbd-demo -L 1G VolGroup   Logical volume "drbd-demo" created [root@pcmk-2 ~]# lvs   LV        VG       Attr   LSize   Origin Snap%  Move Log Copy%  Convert   drbd-demo VolGroup -wi-a- 1.00G                                         lv_root   VolGroup -wi-ao   7.30G                                         lv_swap   VolGroup -wi-ao 500.00M cib crm(live)# cib new drbd INFO: drbd shadow CIB created crm(drbd)# crm(drbd)# cib commit drbd INFO: commited 'drbd' shadow CIB to the cluster crm(drbd)# quit bye [root@pcmk-1 ~]# crm_mon ============ Last updated: Tue Sep  1 09:37:13 2009 Stack: openais Current DC: pcmk-1 - partition with quorum Version: 1.0.5-462f1569a43740667daf7b0f6b521742e9eb8fa7 2 Nodes configured, 2 expected votes 3 Resources configured. ============ Online: [ pcmk-1 pcmk-2 ] ClusterIP        (ocf::heartbeat:IPaddr):        Started pcmk-1 WebSite (ocf::heartbeat:apache):        Started pcmk-1 Master/Slave Set: WebDataClone Masters: [ pcmk-2 ] Slaves: [ pcmk-1 ] crm(drbd)# configure primitive WebData ocf:linbit:drbd params drbd_resource=wwwdata \         op monitor interval=60s crm(drbd)# configure ms WebDataClone WebData meta master-max=1 master-node-max=1 \         clone-max=2 clone-node-max=1 notify=true crm(drbd)# configure show node pcmk-1 node pcmk-2 primitive WebData ocf:linbit:drbd \ params drbd_resource="wwwdata" \ op monitor interval="60s" primitive WebSite ocf:heartbeat:apache \         params configfile="/etc/httpd/conf/httpd.conf" \         op monitor interval="1min" primitive ClusterIP ocf:heartbeat:IPaddr2 \         params ip="192.168.122.101" cidr_netmask="32" \         op monitor interval="30s" ms WebDataClone WebData \ meta master-max="1" master-node-max="1" clone-max="2" clone-node-max="1" notify="true" location prefer-pcmk-1 WebSite 50: pcmk-1 colocation website-with-ip inf: WebSite ClusterIP order apache-after-ip inf: ClusterIP WebSite property $id="cib-bootstrap-options" \         dc-version="1.0.5-462f1569a43740667daf7b0f6b521742e9eb8fa7" \         cluster-infrastructure="openais" \         expected-quorum-votes=”2” \         stonith-enabled="false" \         no-quorum-policy="ignore" rsc_defaults $id="rsc-options" \         resource-stickiness=”100” crm(fs)# cib commit fs INFO: commited 'fs' shadow CIB to the cluster crm(fs)# quit bye [root@pcmk-1 ~]# crm_mon ============ Last updated: Tue Sep  1 10:08:44 2009 Stack: openais Current DC: pcmk-1 - partition with quorum Version: 1.0.5-462f1569a43740667daf7b0f6b521742e9eb8fa7 2 Nodes configured, 2 expected votes 4 Resources configured. ============ Online: [ pcmk-1 pcmk-2 ] ClusterIP        (ocf::heartbeat:IPaddr):        Started pcmk-1 WebSite (ocf::heartbeat:apache): Started pcmk-1 Master/Slave Set: WebDataClone         Masters: [ pcmk-1 ]         Slaves: [ pcmk-2 ] WebFS (ocf::heartbeat:Filesystem): Started pcmk-1 crm(fs)# configure colocation WebSite-with-WebFS inf: WebSite WebFS crm(fs)# configure order WebSite-after-WebFS inf: WebFS WebSite global {   usage-count yes; } common {   protocol C; } resource wwwdata {   meta-disk internal;   device    /dev/drbd1;   syncer {     verify-alg sha1;   }   net {     allow-two-primaries;   }   on pcmk-1 {     disk      /dev/mapper/VolGroup-drbd--demo;     address   192.168.122.101:7789;   }   on pcmk-2 {     disk      /dev/mapper/VolGroup-drbd--demo;     address   192.168.122.102:7789;   } } 看完以后,我们提交它并看看有没有生效。请注意要替换掉name和address选项以符合您的试验环境。在我们设置之前,我们要创建一些空的磁盘分区给它。配置DRBD在集群中配置DRBD为DRBD创建一个分区想知道配置文件的详细信息,请访问 http://www.drbd.org/users-guide/ch-configure.html就算你用的是静态站点,手工在各个节点之间同步文件也不是个好主意。如果是动态站点,那根本不会考虑这个。用NAS不是所有人都能负担得起,但是有些数据还是要同步。用用DRBD: 它被认为是网络RAID-1。访问 See http://www.drbd.org/获得更详细介绍首先我们打开shell。提示会指出你现在是在交互模式下。如果你有1Gb以上的空间,就用那么多吧, 在这个指南中根本用不到这么多空间。Include details on adding a second DRBD resource初始化并载入DRBD安装DRBD软件包然后我们创建一个当前配置文件的副本。我们在这个副本里更改配置。直到我们提交这个副本之前集群不会应用这些更改。请注意提示符的变更,现在它指出我们看到的已经不是当前(live)集群的配置文件。注意我们设置的资源黏性值阻止了资源迁移回pcmk-1现在讲DRBD的模块载入内核并检测是不是都正常现在DRBD已经工作了,我们可以配置一个Filesystem资源来使用它。 此外,对于这个文件系统的定义,同样的我们告诉集群这个文件系统能在哪运行(主DRBD运行的节点)以及什么时候可以启动(在主DRBD启动以后)。现在我们可以创建DRBD clone,然后看看修改过后的配置文件。现在我们要告诉DRBD要用那个数据(那个节点作为主)。因为两边都有一些废数据,我们要在pcmk-1上面执行一下命令。我们再一次的使用交互模式的crm shell一旦你确认这些修改没问题,我们就提交这个副本,然后用crm_mon来看看修改是否生效了。当我在pcmk-1上面操作完了--本例中没有任何操作,我们只是想让资源移动移动--我们可以让节点变回正常的集群成员。crm shell一个便捷的特性是可以工作在交互模式下并自动的变更配置中的相关部分。向DRBD中添加数据把一个本地节点设置为standby模式并观察集群把所有资源移动到另外一个节点了。并且注意节点的状态改变为不能运行任何的资源。在另外一个节点上面执行相同的操作,请确保使用了相同大小的分区。用DRBD同步存储在2.6.33以上的内核中,所以DRBD要的东西都在 &DISTRO; &DISTRO_VERSION;中存在了,你只要安装它就好了。TODO: Explain the reason for the allow-two-primaries option迁移测试没有命令来自动生成DRBD配置文件,所以我们要简单的拷贝下面的配置文件并粘贴到/etc/drbd.conf审视一下你的配置:我们也要告诉集群Apache也要运行在同样的节点上,而且文件系统要在Apache之前启动。我们可以再次关掉在运行的那个节点,但是安全的方法是把节点设置为standby模式。节点在这个状态下面等于告诉集群它不能运行任何资源,任何在这个节点上面运行的资源都会被移动到其他地方。这个特性在更新资源安装包的时候特别的方便。(确实!)配置完成以后,我们可以来执行初始化了配置DRBDpcmk-1现在是处于Primary(主)状态了,它允许写入了。这意味着可以在上面创建文件系统并把一些数据放进去,并且用WebSite这个资源来展现。pacemaker-master/doc/Clusters_from_Scratch/zh-CN/Ch-Shared-Storage.po000066400000000000000000001626771217637305600260160ustar00rootroot00000000000000# # AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: 0\n" "POT-Creation-Date: 2012-10-17T05:19:03\n" "PO-Revision-Date: 2010-12-16 00:32+0800\n" "Last-Translator: Charlie Chen \n" "Language-Team: None\n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. Tag: title #, no-c-format msgid "Replicated Storage with DRBD" msgstr "用DRBD同步存储" #. Tag: title #, no-c-format msgid "Background" msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "Even if you’re serving up static websites, having to manually synchronize the contents of that website to all the machines in the cluster is not ideal. For dynamic websites, such as a wiki, it’s not even an option. Not everyone care afford network-attached storage but somehow the data needs to be kept in sync. Enter DRBD which can be thought of as network based RAID-1. See http://www.drbd.org/ for more details." msgstr "就算你用的是静态站点,手工在各个节点之间同步文件也不是个好主意。如果是动态站点,那根本不会考虑这个。用NAS不是所有人都能负担得起,但是有些数据还是要同步。用用DRBD: 它被认为是网络RAID-1。访问 See http://www.drbd.org/获得更详细介绍" #. Tag: title #, no-c-format msgid "Install the DRBD Packages" msgstr "安装DRBD软件包" #. Tag: para #, fuzzy, no-c-format msgid "Since its inclusion in the upstream 2.6.33 kernel, everything needed to use DRBD has shiped with Fedora since version 13. All you need to do is install it:" msgstr "在2.6.33以上的内核中,所以DRBD要的东西都在 &DISTRO; &DISTRO_VERSION;中存在了,你只要安装它就好了。" #. Tag: programlisting #, no-c-format msgid "# yum install -y drbd-pacemaker drbd-udev" msgstr "" #. Tag: literallayout #, fuzzy, no-c-format msgid "" "Loaded plugins: langpacks, presto, refresh-packagekit\n" "Resolving Dependencies\n" "--> Running transaction check\n" "---> Package drbd-pacemaker.x86_64 0:8.3.11-5.fc17 will be installed\n" "--> Processing Dependency: drbd-utils = 8.3.11-5.fc17 for package: drbd-pacemaker-8.3.11-5.fc17.x86_64\n" "---> Package drbd-udev.x86_64 0:8.3.11-5.fc17 will be installed\n" "--> Running transaction check\n" "---> Package drbd-utils.x86_64 0:8.3.11-5.fc17 will be installed\n" "--> Finished Dependency Resolution\n" "\n" "Dependencies Resolved\n" "\n" "======================================================================================\n" " Package Arch Version Repository Size\n" "======================================================================================\n" "Installing:\n" " drbd-pacemaker x86_64 8.3.11-5.fc17 updates-testing 22 k\n" " drbd-udev x86_64 8.3.11-5.fc17 updates-testing 6.4 k\n" "Installing for dependencies:\n" " drbd-utils x86_64 8.3.11-5.fc17 updates-testing 183 k\n" "\n" "Transaction Summary\n" "======================================================================================\n" "Install 2 Packages (+1 Dependent package)\n" "\n" "Total download size: 212 k\n" "Installed size: 473 k\n" "Downloading Packages:\n" "(1/3): drbd-pacemaker-8.3.11-5.fc17.x86_64.rpm | 22 kB 00:00\n" "(2/3): drbd-udev-8.3.11-5.fc17.x86_64.rpm | 6.4 kB 00:00\n" "(3/3): drbd-utils-8.3.11-5.fc17.x86_64.rpm | 183 kB 00:00\n" "--------------------------------------------------------------------------------------\n" "Total 293 kB/s | 212 kB 00:00\n" "Running Transaction Check\n" "Running Transaction Test\n" "Transaction Test Succeeded\n" "Running Transaction\n" " Installing : drbd-utils-8.3.11-5.fc17.x86_64 1/3\n" " Installing : drbd-pacemaker-8.3.11-5.fc17.x86_64 2/3\n" " Installing : drbd-udev-8.3.11-5.fc17.x86_64 3/3\n" " Verifying : drbd-pacemaker-8.3.11-5.fc17.x86_64 1/3\n" " Verifying : drbd-udev-8.3.11-5.fc17.x86_64 2/3\n" " Verifying : drbd-utils-8.3.11-5.fc17.x86_64 3/3\n" "\n" "Installed:\n" " drbd-pacemaker.x86_64 0:8.3.11-5.fc17 drbd-udev.x86_64 0:8.3.11-5.fc17\n" "\n" "Dependency Installed:\n" " drbd-utils.x86_64 0:8.3.11-5.fc17\n" "\n" "Complete!" msgstr "" "\n" "[root@pcmk-1 ~]# yum install -y drbd-pacemaker\n" "Loaded plugins: presto, refresh-packagekit\n" "Setting up Install Process\n" "Resolving Dependencies\n" "--> Running transaction check\n" "---> Package drbd-pacemaker.x86_64 0:8.3.7-2.fc13 set to be updated\n" "--> Processing Dependency: drbd-utils = 8.3.7-2.fc13 for package: drbd-pacemaker-8.3.7-2.fc13.x86_64\n" "--> Running transaction check\n" "---> Package drbd-utils.x86_64 0:8.3.7-2.fc13 set to be updated\n" "--> Finished Dependency Resolution\n" "\n" "Dependencies Resolved\n" "\n" "=================================================================================\n" " Package Arch Version Repository Size\n" "=================================================================================\n" "Installing:\n" " drbd-pacemaker x86_64 8.3.7-2.fc13 fedora 19 k\n" "Installing for dependencies:\n" " drbd-utils x86_64 8.3.7-2.fc13 fedora 165 k\n" "\n" "Transaction Summary\n" "=================================================================================\n" "Install 2 Package(s)\n" "Upgrade 0 Package(s)\n" "\n" "Total download size: 184 k\n" "Installed size: 427 k\n" "Downloading Packages:\n" "Setting up and reading Presto delta metadata\n" "fedora/prestodelta | 1.7 kB 00:00 \n" "Processing delta metadata\n" "Package(s) data still to download: 184 k\n" "(1/2): drbd-pacemaker-8.3.7-2.fc13.x86_64.rpm | 19 kB 00:01 \n" "(2/2): drbd-utils-8.3.7-2.fc13.x86_64.rpm | 165 kB 00:02 \n" "---------------------------------------------------------------------------------\n" "Total 45 kB/s | 184 kB 00:04 \n" "Running rpm_check_debug\n" "Running Transaction Test\n" "Transaction Test Succeeded\n" "Running Transaction\n" " Installing : drbd-utils-8.3.7-2.fc13.x86_64 1/2 \n" " Installing : drbd-pacemaker-8.3.7-2.fc13.x86_64 2/2 \n" "\n" "Installed:\n" " drbd-pacemaker.x86_64 0:8.3.7-2.fc13 \n" "\n" "Dependency Installed:\n" " drbd-utils.x86_64 0:8.3.7-2.fc13 \n" "\n" "Complete!\n" "[root@pcmk-1 ~]#\n" " " #. Tag: title #, no-c-format msgid "Configure DRBD" msgstr "配置DRBD" #. Tag: para #, no-c-format msgid "Before we configure DRBD, we need to set aside some disk for it to use." msgstr "在我们设置之前,我们要创建一些空的磁盘分区给它。" #. Tag: title #, no-c-format msgid "Create A Partition for DRBD" msgstr "为DRBD创建一个分区" #. Tag: para #, no-c-format msgid "If you have more than 1Gb free, feel free to use it. For this guide however, 1Gb is plenty of space for a single html file and sufficient for later holding the GFS2 metadata." msgstr "如果你有1Gb以上的空间,就用那么多吧, 在这个指南中根本用不到这么多空间。" #. Tag: programlisting #, no-c-format msgid "" "# vgdisplay | grep -e Name - e Free\n" " VG Name vg_pcmk1\n" " Free PE / Size 31 / 992.00 MiB\n" "# lvs\n" " LV VG Attr LSize Pool Origin Data% Move Log Copy% Convert\n" " lv_root vg_pcmk1 -wi-ao-- 8.56g\n" " lv_swap vg_pcmk1 -wi-ao-- 960.00m\n" "# lvcreate -n drbd-demo -L 1G vg_pcmk1\n" "Logical volume \"drbd-demo\" created\n" "# lvs\n" " LV VG Attr LSize Pool Origin Data% Move Log Copy% Convert\n" " drbd-demo vg_pcmk1 -wi-a--- 1.00G\n" " lv_root vg_pcmk1 -wi-ao-- 8.56g\n" " lv_swap vg_pcmk1 -wi-ao-- 960.00m" msgstr "" #. Tag: para #, no-c-format msgid "Repeat this on the second node, be sure to use the same size partition." msgstr "在另外一个节点上面执行相同的操作,请确保使用了相同大小的分区。" #. Tag: programlisting #, no-c-format msgid "" "# ssh pcmk-2 -- lvs\n" "LV VG Attr LSize Origin Snap% Move Log Copy% Convert\n" " lv_root vg_pcmk1 -wi-ao-- 8.56g\n" " lv_swap vg_pcmk1 -wi-ao-- 960.00m\n" "# ssh pcmk-2 -- lvcreate -n drbd-demo -L 1G vg_pcmk1\n" "Logical volume \"drbd-demo\" created\n" "# ssh pcmk-2 -- lvs\n" "LV VG Attr LSize Origin Snap% Move Log Copy% Convert\n" " drbd-demo vg_pcmk1 -wi-a--- 1.00G\n" " lv_root vg_pcmk1 -wi-ao-- 8.56g\n" " lv_swap vg_pcmk1 -wi-ao-- 960.00m" msgstr "" #. Tag: title #, no-c-format msgid "Write the DRBD Config" msgstr "配置DRBD" #. Tag: para #, fuzzy, no-c-format msgid "There is no series of commands for building a DRBD configuration, so simply copy the configuration below to /etc/drbd.conf" msgstr "没有命令来自动生成DRBD配置文件,所以我们要简单的拷贝下面的配置文件并粘贴到/etc/drbd.conf" #. Tag: para #, no-c-format msgid "Detailed information on the directives used in this configuration (and other alternatives) is available from http://www.drbd.org/users-guide/ch-configure.html" msgstr "想知道配置文件的详细信息,请访问 http://www.drbd.org/users-guide/ch-configure.html" #. Tag: para #, fuzzy, no-c-format msgid "Be sure to use the names and addresses of your nodes if they differ from the ones used in this guide." msgstr "请注意要替换掉name和address选项以符合您的试验环境。" #. Tag: literallayout #, fuzzy, no-c-format msgid "" "global {\n" " usage-count yes;\n" "}\n" "common {\n" " protocol C;\n" "}\n" "resource wwwdata {\n" " meta-disk internal;\n" " device /dev/drbd1;\n" " syncer {\n" " verify-alg sha1;\n" " }\n" " net {\n" " allow-two-primaries;\n" " }\n" " on pcmk-1 {\n" " disk /dev/vg_pcmk1/drbd-demo;\n" " address 192.168.122.101:7789;\n" " }\n" " on pcmk-2 {\n" " disk /dev/vg_pcmk1/drbd-demo;\n" " address 192.168.122.102:7789;\n" " }\n" "}" msgstr "" "\n" "global { \n" "  usage-count yes; \n" "}\n" "common {\n" "  protocol C;\n" "}\n" "resource wwwdata {\n" "  meta-disk internal;\n" "  device    /dev/drbd1;\n" "  syncer {\n" "    verify-alg sha1;\n" "  }\n" "  net { \n" "    allow-two-primaries; \n" "  }\n" "  on pcmk-1 {\n" "    disk      /dev/mapper/VolGroup-drbd--demo;\n" "    address   192.168.122.101:7789; \n" "  }\n" "  on \n" "pcmk-2 {\n" "    disk      /dev/mapper/VolGroup-drbd--demo;\n" "    address   192.168.122.102:7789; \n" "  }\n" "}\n" " " #. Tag: para #, no-c-format msgid "TODO: Explain the reason for the allow-two-primaries option" msgstr "TODO: Explain the reason for the allow-two-primaries option" #. Tag: title #, no-c-format msgid "Initialize and Load DRBD" msgstr "初始化并载入DRBD" #. Tag: para #, no-c-format msgid "With the configuration in place, we can now perform the DRBD initialization" msgstr "配置完成以后,我们可以来执行初始化了" #. Tag: programlisting #, no-c-format msgid "" "# drbdadm create-md wwwdata\n" "Writing meta data...\n" "initializing activity log\n" "NOT initialized bitmap\n" "New drbd meta data block successfully created.\n" "success" msgstr "" #. Tag: para #, no-c-format msgid "Now load the DRBD kernel module and confirm that everything is sane" msgstr "现在讲DRBD的模块载入内核并检测是不是都正常" #. Tag: programlisting #, no-c-format msgid "" "# modprobe drbd\n" "# drbdadm up wwwdata\n" "# cat /proc/drbd\n" "version: 8.3.11 (api:88/proto:86-96)\n" "srcversion: 0D2B62DEDB020A425130935\n" "\n" " 1: cs:Connected ro:Secondary/Secondary ds:Inconsistent/Inconsistent C r-----\n" " ns:0 nr:0 dw:0 dr:0 al:0 bm:0 lo:0 pe:0 ua:0 ap:0 ep:1 wo:f oos:1015740" msgstr "" #. Tag: para #, no-c-format msgid "Repeat on the second node" msgstr "" #. Tag: programlisting #, no-c-format msgid "" "# ssh pcmk-2 -- drbdadm --force create-md wwwdata\n" "Writing meta data...\n" "initializing activity log\n" "NOT initialized bitmap\n" "New drbd meta data block successfully created.\n" "success\n" "# ssh pcmk-2 -- modprobe drbd\n" "WARNING: Deprecated config file /etc/modprobe.conf, all config files belong into /etc/modprobe.d/.\n" "# ssh pcmk-2 -- drbdadm up wwwdata\n" "# ssh pcmk-2 -- cat /proc/drbd\n" "version: 8.3.11 (api:88/proto:86-96)\n" "srcversion: 0D2B62DEDB020A425130935\n" "\n" " 1: cs:Connected ro:Secondary/Secondary ds:Inconsistent/Inconsistent C r-----\n" " ns:0 nr:0 dw:0 dr:0 al:0 bm:0 lo:0 pe:0 ua:0 ap:0 ep:1 wo:f oos:1015740" msgstr "" #. Tag: para #, no-c-format msgid "Now we need to tell DRBD which set of data to use. Since both sides contain garbage, we can run the following on pcmk-1:" msgstr "现在我们要告诉DRBD要用那个数据(那个节点作为主)。因为两边都有一些废数据,我们要在pcmk-1上面执行一下命令。" #. Tag: programlisting #, no-c-format msgid "" "# drbdadm -- --overwrite-data-of-peer primary wwwdata\n" "# cat /proc/drbd\n" "version: 8.3.11 (api:88/proto:86-96)\n" "srcversion: 0D2B62DEDB020A425130935\n" "\n" " 1: cs:SyncSource ro:Primary/Secondary ds:UpToDate/Inconsistent C r-----\n" " ns:8064 nr:0 dw:0 dr:8728 al:0 bm:0 lo:0 pe:1 ua:0 ap:0 ep:1 wo:f oos:1007804\n" " [>....................] sync'ed: 0.9% (1007804/1015740)K\n" " finish: 0:12:35 speed: 1,320 (1,320) K/sec" msgstr "" #. Tag: para #, no-c-format msgid "After a while, the sync should finish and you’ll see:" msgstr "" #. Tag: programlisting #, no-c-format msgid "" "# cat /proc/drbd\n" "version: 8.3.11 (api:88/proto:86-96)\n" "srcversion: 0D2B62DEDB020A425130935\n" "\n" " 1: cs:Connected ro:Primary/Secondary ds:UpToDate/UpToDate C r-----\n" " ns:1015740 nr:0 dw:0 dr:1016404 al:0 bm:62 lo:0 pe:0 ua:0 ap:0 ep:1 wo:f oos:0" msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "pcmk-1 is now in the Primary state which allows it to be written to. Which means it’s a good point at which to create a filesystem and populate it with some data to serve up via our WebSite resource." msgstr "pcmk-1现在是处于Primary(主)状态了,它允许写入了。这意味着可以在上面创建文件系统并把一些数据放进去,并且用WebSite这个资源来展现。" #. Tag: title #, no-c-format msgid "Populate DRBD with Data" msgstr "向DRBD中添加数据" #. Tag: programlisting #, no-c-format msgid "" "# mkfs.ext4 /dev/drbd1\n" "mke2fs 1.42 (29-Nov-2011)\n" "Filesystem label=\n" "OS type: Linux\n" "Block size=4096 (log=2)\n" "Fragment size=4096 (log=2)\n" "Stride=0 blocks, Stripe width=0 blocks\n" "63488 inodes, 253935 blocks\n" "12696 blocks (5.00%) reserved for the super user\n" "First data block=0\n" "Maximum filesystem blocks=260046848\n" "8 block groups\n" "32768 blocks per group, 32768 fragments per group\n" "7936 inodes per group\n" "Superblock backups stored on blocks:\n" " 32768, 98304, 163840, 229376\n" "\n" "Allocating group tables: done\n" "Writing inode tables: done\n" "Creating journal (4096 blocks): done\n" "Writing superblocks and filesystem accounting information: done" msgstr "" #. Tag: para #, no-c-format msgid "Now mount the newly created filesystem so we can create our index file" msgstr "" #. Tag: programlisting #, no-c-format msgid "" "# mount /dev/drbd1 /mnt/\n" "# cat <<-END >/mnt/index.html\n" " <html>\n" " <body>My Test Site - drbd</body>\n" " </html>\n" "END\n" "# umount /dev/drbd1" msgstr "" #. Tag: title #, no-c-format msgid "Configure the Cluster for DRBD" msgstr "在集群中配置DRBD" #. Tag: para #, no-c-format msgid "One handy feature pcs has is the ability to queue up several changes into a file and commit those changes atomically. To do this, start by populating the file with the current raw xml config from the cib. This can be done using the following command." msgstr "" #. Tag: programlisting #, no-c-format msgid "# pcs cluster cib drbd_cfg" msgstr "" #. Tag: para #, no-c-format msgid "Now using the pcs -f option, make changes to the configuration saved in the drbd_cfg file. These changes will not be seen by the cluster until the drbd_cfg file is pushed into the live cluster’s cib later on." msgstr "" #. Tag: screen #, no-c-format msgid "" "# pcs -f drbd_cfg resource create WebData ocf:linbit:drbd \\\n" " drbd_resource=wwwdata op monitor interval=60s\n" "# pcs -f drbd_cfg resource master WebDataClone WebData \\\n" " master-max=1 master-node-max=1 clone-max=2 clone-node-max=1 \\\n" " notify=true" msgstr "" #. Tag: programlisting #, no-c-format msgid "" "# pcs -f drbd_cfg resource show\n" " ClusterIP (ocf::heartbeat:IPaddr2) Started\n" " WebSite (ocf::heartbeat:apache) Started\n" " Master/Slave Set: WebDataClone [WebData]\n" " Stopped: [ WebData:0 WebData:1 ]" msgstr "" #. Tag: para #, no-c-format msgid "After you are satisfied with all the changes, you can commit all the changes at once by pushing the drbd_cfg file into the live cib." msgstr "" #. Tag: programlisting #, fuzzy, no-c-format msgid "" "# pcs cluster push cib drbd_cfg\n" "CIB updated\n" "\n" "# pcs status\n" "\n" "Last updated: Fri Sep 14 12:19:49 2012\n" "Last change: Fri Sep 14 12:19:13 2012 via cibadmin on pcmk-1\n" "Stack: corosync\n" "Current DC: pcmk-2 (2) - partition with quorum\n" "Version: 1.1.8-1.el7-60a19ed12fdb4d5c6a6b6767f52e5391e447fec0\n" "2 Nodes configured, unknown expected votes\n" "4 Resources configured.\n" "\n" "Online: [ pcmk-1 pcmk-2 ]\n" "\n" "Full list of resources:\n" "\n" " ClusterIP (ocf::heartbeat:IPaddr2): Started pcmk-1\n" " WebSite (ocf::heartbeat:apache): Started pcmk-1\n" " Master/Slave Set: WebDataClone [WebData]\n" " Masters: [ pcmk-1 ]\n" " Slaves: [ pcmk-2 ]" msgstr "" "\n" "[root@pcmk-1 ~]# crm node online\n" "[root@pcmk-1 ~]# crm_mon\n" "============\n" "Last updated: Tue Sep  1 10:13:25 2009\n" "Stack: openais\n" "Current DC: pcmk-1 - partition with quorum\n" "Version: 1.0.5-462f1569a43740667daf7b0f6b521742e9eb8fa7\n" "2 Nodes configured, 2 expected votes\n" "4 Resources configured.\n" "============\n" "\n" "Online: [ pcmk-1 pcmk-2 ]\n" "\n" "ClusterIP        (ocf::heartbeat:IPaddr):        Started pcmk-2\n" "WebSite (ocf::heartbeat:apache):        Started pcmk-2\n" "Master/Slave Set: WebDataClone\n" "        Masters: [ pcmk-2 ]\n" "        Slaves: [ pcmk-1 ]\n" "WebFS   (ocf::heartbeat:Filesystem):    Started pcmk-2\n" " " #. Tag: para #, fuzzy, no-c-format msgid "TODO: Include details on adding a second DRBD resource" msgstr "Include details on adding a second DRBD resource" #. Tag: para #, no-c-format msgid "Now that DRBD is functioning we can configure a Filesystem resource to use it. In addition to the filesystem’s definition, we also need to tell the cluster where it can be located (only on the DRBD Primary) and when it is allowed to start (after the Primary was promoted)." msgstr "现在DRBD已经工作了,我们可以配置一个Filesystem资源来使用它。 此外,对于这个文件系统的定义,同样的我们告诉集群这个文件系统能在哪运行(主DRBD运行的节点)以及什么时候可以启动(在主DRBD启动以后)。" #. Tag: para #, no-c-format msgid "We are going to take a shortcut when creating the resource this time though. Instead of explicitly saying we want the ocf:heartbeat:Filesystem script, we are only going to ask for Filesystem. We can do this because we know there is only one resource script named Filesystem available to pacemaker, and that pcs is smart enough to fill in the ocf:heartbeat portion for us correctly in the configuration. If there were multiple Filesystem scripts from different ocf providers, we would need to specify the exact one we wanted to use." msgstr "" #. Tag: para #, no-c-format msgid "Once again we will queue up our changes to a file and then push the new configuration to the cluster as the final step." msgstr "" #. Tag: screen #, no-c-format msgid "" "# pcs cluster cib fs_cfg\n" "# pcs -f fs_cfg resource create WebFS Filesystem \\\n" " device=\"/dev/drbd/by-res/wwwdata\" directory=\"/var/www/html\" \\\n" " fstype=\"ext4\"" msgstr "" #. Tag: programlisting #, no-c-format msgid "" "# pcs -f fs_cfg constraint colocation add WebFS WebDataClone INFINITY with-rsc-role=Master\n" "# pcs -f fs_cfg constraint order promote WebDataClone then start WebFS\n" "Adding WebDataClone WebFS (kind: Mandatory) (Options: first-action=promote then-action=start)" msgstr "" #. Tag: para #, no-c-format msgid "We also need to tell the cluster that Apache needs to run on the same machine as the filesystem and that it must be active before Apache can start." msgstr "我们也要告诉集群Apache也要运行在同样的节点上,而且文件系统要在Apache之前启动。" #. Tag: programlisting #, no-c-format msgid "" "# pcs -f fs_cfg constraint colocation add WebSite WebFS INFINITY\n" "# pcs -f fs_cfg constraint order WebFS then WebSite" msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "Now review the updated configuration." msgstr "审视一下你的配置:" #. Tag: programlisting #, no-c-format msgid "" "# pcs -f fs_cfg constraint\n" "Location Constraints:\n" "Ordering Constraints:\n" " start ClusterIP then start WebSite\n" " WebFS then WebSite\n" " promote WebDataClone then start WebFS\n" "Colocation Constraints:\n" " WebSite with ClusterIP\n" " WebFS with WebDataClone (with-rsc-role:Master)\n" " WebSite with WebFS\n" "\n" "# pcs -f fs_cfg resource show\n" " ClusterIP (ocf::heartbeat:IPaddr2) Started\n" " WebSite (ocf::heartbeat:apache) Started\n" " Master/Slave Set: WebDataClone [WebData]\n" " Masters: [ pcmk-1 ]\n" " Slaves: [ pcmk-2 ]\n" " WebFS (ocf::heartbeat:Filesystem) Stopped" msgstr "" #. Tag: para #, no-c-format msgid "After reviewing the new configuration, we again upload it and watch the cluster put it into effect." msgstr "看完以后,我们提交它并看看有没有生效。" #. Tag: programlisting #, fuzzy, no-c-format msgid "" "# pcs cluster push cib fs_cfg\n" "CIB updated\n" "# pcs status\n" " Last updated: Fri Aug 10 12:47:01 2012\n" "\n" " Last change: Fri Aug 10 12:46:55 2012 via cibadmin on pcmk-1\n" " Stack: corosync\n" " Current DC: pcmk-1 (1) - partition with quorum\n" " Version: 1.1.8-1.el7-60a19ed12fdb4d5c6a6b6767f52e5391e447fec0\n" " 2 Nodes configured, unknown expected votes\n" " 5 Resources configured.\n" "\n" "Online: [ pcmk-1 pcmk-2 ]\n" "\n" "Full list of resources:\n" "\n" " ClusterIP (ocf::heartbeat:IPaddr2): Started pcmk-1\n" " WebSite (ocf::heartbeat:apache): Started pcmk-1\n" " Master/Slave Set: WebDataClone [WebData]\n" " Masters: [ pcmk-1 ]\n" " Slaves: [ pcmk-2 ]\n" " WebFS (ocf::heartbeat:Filesystem): Started pcmk-1" msgstr "" "\n" "[root@pcmk-1 ~]# crm node online\n" "[root@pcmk-1 ~]# crm_mon\n" "============\n" "Last updated: Tue Sep  1 10:13:25 2009\n" "Stack: openais\n" "Current DC: pcmk-1 - partition with quorum\n" "Version: 1.0.5-462f1569a43740667daf7b0f6b521742e9eb8fa7\n" "2 Nodes configured, 2 expected votes\n" "4 Resources configured.\n" "============\n" "\n" "Online: [ pcmk-1 pcmk-2 ]\n" "\n" "ClusterIP        (ocf::heartbeat:IPaddr):        Started pcmk-2\n" "WebSite (ocf::heartbeat:apache):        Started pcmk-2\n" "Master/Slave Set: WebDataClone\n" "        Masters: [ pcmk-2 ]\n" "        Slaves: [ pcmk-1 ]\n" "WebFS   (ocf::heartbeat:Filesystem):    Started pcmk-2\n" " " #. Tag: title #, no-c-format msgid "Testing Migration" msgstr "迁移测试" #. Tag: para #, fuzzy, no-c-format msgid "We could shut down the active node again, but another way to safely simulate recovery is to put the node into what is called \"standby mode\". Nodes in this state tell the cluster that they are not allowed to run resources. Any resources found active there will be moved elsewhere. This feature can be particularly useful when updating the resources' packages." msgstr "我们可以再次关掉在运行的那个节点,但是安全的方法是把节点设置为standby模式。节点在这个状态下面等于告诉集群它不能运行任何资源,任何在这个节点上面运行的资源都会被移动到其他地方。这个特性在更新资源安装包的时候特别的方便。(确实!)" #. Tag: para #, no-c-format msgid "Put the local node into standby mode and observe the cluster move all the resources to the other node. Note also that the node’s status will change to indicate that it can no longer host resources." msgstr "把一个本地节点设置为standby模式并观察集群把所有资源移动到另外一个节点了。并且注意节点的状态改变为不能运行任何的资源。" #. Tag: programlisting #, fuzzy, no-c-format msgid "" "# pcs cluster standby pcmk-1\n" "# pcs status\n" "\n" "Last updated: Fri Sep 14 12:41:12 2012\n" "Last change: Fri Sep 14 12:41:08 2012 via crm_attribute on pcmk-1\n" "Stack: corosync\n" "Current DC: pcmk-1 (1) - partition with quorum\n" "Version: 1.1.8-1.el7-60a19ed12fdb4d5c6a6b6767f52e5391e447fec0\n" "2 Nodes configured, unknown expected votes\n" "5 Resources configured.\n" "\n" "Node pcmk-1 (1): standby\n" "Online: [ pcmk-2 ]\n" "\n" "Full list of resources:\n" "\n" "ClusterIP (ocf::heartbeat:IPaddr2): Started pcmk-2\n" "WebSite (ocf::heartbeat:apache): Started pcmk-2\n" " Master/Slave Set: WebDataClone [WebData]\n" " Masters: [ pcmk-2 ]\n" " Stopped: [ WebData:1 ]\n" "WebFS (ocf::heartbeat:Filesystem): Started pcmk-2" msgstr "" "\n" "[root@pcmk-1 ~]# crm node online\n" "[root@pcmk-1 ~]# crm_mon\n" "============\n" "Last updated: Tue Sep  1 10:13:25 2009\n" "Stack: openais\n" "Current DC: pcmk-1 - partition with quorum\n" "Version: 1.0.5-462f1569a43740667daf7b0f6b521742e9eb8fa7\n" "2 Nodes configured, 2 expected votes\n" "4 Resources configured.\n" "============\n" "\n" "Online: [ pcmk-1 pcmk-2 ]\n" "\n" "ClusterIP        (ocf::heartbeat:IPaddr):        Started pcmk-2\n" "WebSite (ocf::heartbeat:apache):        Started pcmk-2\n" "Master/Slave Set: WebDataClone\n" "        Masters: [ pcmk-2 ]\n" "        Slaves: [ pcmk-1 ]\n" "WebFS   (ocf::heartbeat:Filesystem):    Started pcmk-2\n" " " #. Tag: para #, no-c-format msgid "Once we’ve done everything we needed to on pcmk-1 (in this case nothing, we just wanted to see the resources move), we can allow the node to be a full cluster member again." msgstr "当我在pcmk-1上面操作完了--本例中没有任何操作,我们只是想让资源移动移动--我们可以让节点变回正常的集群成员。" #. Tag: programlisting #, fuzzy, no-c-format msgid "" "# pcs cluster unstandby pcmk-1\n" "# pcs status\n" "\n" "Last updated: Fri Sep 14 12:43:02 2012\n" "Last change: Fri Sep 14 12:42:57 2012 via crm_attribute on pcmk-1\n" "Stack: corosync\n" "Current DC: pcmk-1 (1) - partition with quorum\n" "Version: 1.1.8-1.el7-60a19ed12fdb4d5c6a6b6767f52e5391e447fec0\n" "2 Nodes configured, unknown expected votes\n" "5 Resources configured.\n" "\n" "Online: [ pcmk-1 pcmk-2 ]\n" "\n" "Full list of resources:\n" "\n" " ClusterIP (ocf::heartbeat:IPaddr2): Started pcmk-2\n" " WebSite (ocf::heartbeat:apache): Started pcmk-2\n" " Master/Slave Set: WebDataClone [WebData]\n" " Masters: [ pcmk-2 ]\n" " Slaves: [ pcmk-1 ]\n" " WebFS (ocf::heartbeat:Filesystem): Started pcmk-2" msgstr "" "\n" "[root@pcmk-1 ~]# crm node online\n" "[root@pcmk-1 ~]# crm_mon\n" "============\n" "Last updated: Tue Sep  1 10:13:25 2009\n" "Stack: openais\n" "Current DC: pcmk-1 - partition with quorum\n" "Version: 1.0.5-462f1569a43740667daf7b0f6b521742e9eb8fa7\n" "2 Nodes configured, 2 expected votes\n" "4 Resources configured.\n" "============\n" "\n" "Online: [ pcmk-1 pcmk-2 ]\n" "\n" "ClusterIP        (ocf::heartbeat:IPaddr):        Started pcmk-2\n" "WebSite (ocf::heartbeat:apache):        Started pcmk-2\n" "Master/Slave Set: WebDataClone\n" "        Masters: [ pcmk-2 ]\n" "        Slaves: [ pcmk-1 ]\n" "WebFS   (ocf::heartbeat:Filesystem):    Started pcmk-2\n" " " #. Tag: para #, no-c-format msgid "Notice that our resource stickiness settings prevent the services from migrating back to pcmk-1." msgstr "注意我们设置的资源黏性值阻止了资源迁移回pcmk-1" #~ msgid "" #~ "\n" #~ "[root@pcmk-1 ~]# lvcreate -n drbd-demo -L 1G VolGroup\n" #~ "  Logical volume \"drbd-demo\" created\n" #~ "[root@pcmk-1 ~]# lvs\n" #~ "  LV        VG       Attr   LSize   Origin Snap%  Move Log Copy%  Convert\n" #~ "  drbd-demo VolGroup -wi-a- 1.00G                                      \n" #~ "  lv_root   VolGroup -wi-ao   7.30G                                      \n" #~ "  lv_swap   VolGroup -wi-ao 500.00M\n" #~ " " #~ msgstr "" #~ "\n" #~ "[root@pcmk-1 ~]# lvcreate -n drbd-demo -L 1G VolGroup\n" #~ "  Logical volume \"drbd-demo\" created\n" #~ "[root@pcmk-1 ~]# lvs\n" #~ "  LV        VG       Attr   LSize   Origin Snap%  Move Log Copy%  Convert\n" #~ "  drbd-demo VolGroup -wi-a- 1.00G                                      \n" #~ "  lv_root   VolGroup -wi-ao   7.30G                                      \n" #~ "  lv_swap   VolGroup -wi-ao 500.00M\n" #~ " " #~ msgid "" #~ "\n" #~ "[root@pcmk-2 ~]# lvs\n" #~ "  LV      VG       Attr   LSize   Origin Snap%  Move Log Copy%  Convert\n" #~ "  lv_root VolGroup -wi-ao   7.30G                                      \n" #~ "  lv_swap VolGroup -wi-ao 500.00M                                      \n" #~ "[root@pcmk-2 ~]# lvcreate -n drbd-demo -L 1G VolGroup\n" #~ "  Logical volume \"drbd-demo\" created\n" #~ "[root@pcmk-2 ~]# lvs\n" #~ "  LV        VG       Attr   LSize   Origin Snap%  Move Log Copy%  Convert\n" #~ "  drbd-demo VolGroup -wi-a- 1.00G                                      \n" #~ "  lv_root   VolGroup -wi-ao   7.30G                                      \n" #~ "  lv_swap   VolGroup -wi-ao 500.00M\n" #~ " " #~ msgstr "" #~ "\n" #~ "[root@pcmk-2 ~]# lvs\n" #~ "  LV      VG       Attr   LSize   Origin Snap%  Move Log Copy%  Convert\n" #~ "  lv_root VolGroup -wi-ao   7.30G                                      \n" #~ "  lv_swap VolGroup -wi-ao 500.00M                                      \n" #~ "[root@pcmk-2 ~]# lvcreate -n drbd-demo -L 1G VolGroup\n" #~ "  Logical volume \"drbd-demo\" created\n" #~ "[root@pcmk-2 ~]# lvs\n" #~ "  LV        VG       Attr   LSize   Origin Snap%  Move Log Copy%  Convert\n" #~ "  drbd-demo VolGroup -wi-a- 1.00G                                      \n" #~ "  lv_root   VolGroup -wi-ao   7.30G                                      \n" #~ "  lv_swap   VolGroup -wi-ao 500.00M\n" #~ " " #~ msgid "" #~ "\n" #~ "[root@pcmk-1 ~]# drbdadm create-md wwwdata\n" #~ "md_offset 12578816\n" #~ "al_offset 12546048\n" #~ "bm_offset 12541952\n" #~ "\n" #~ "Found some data \n" #~ " ==> This might destroy existing data! <==\n" #~ "\n" #~ "Do you want to proceed?\n" #~ "[need to type 'yes' to confirm] yes\n" #~ "\n" #~ "Writing meta data...\n" #~ "initializing activity log\n" #~ "NOT initialized bitmap\n" #~ "New drbd meta data block successfully created.\n" #~ "success\n" #~ " " #~ msgstr "" #~ "\n" #~ "[root@pcmk-1 ~]# drbdadm create-md wwwdata\n" #~ "md_offset 12578816\n" #~ "al_offset 12546048\n" #~ "bm_offset 12541952\n" #~ "\n" #~ "Found some data \n" #~ " ==> This might destroy existing data! <==\n" #~ "\n" #~ "Do you want to proceed?\n" #~ "[need to type 'yes' to confirm] yes\n" #~ "\n" #~ "Writing meta data...\n" #~ "initializing activity log\n" #~ "NOT initialized bitmap\n" #~ "New drbd meta data block successfully created.\n" #~ "success\n" #~ " " #~ msgid "" #~ "\n" #~ "[root@pcmk-1 ~]# modprobe drbd\n" #~ "[root@pcmk-1 ~]# drbdadm up wwwdata\n" #~ "[root@pcmk-1 ~]# cat /proc/drbd\n" #~ "version: 8.3.6 (api:88/proto:86-90)\n" #~ "GIT-hash: f3606c47cc6fcf6b3f086e425cb34af8b7a81bbf build by root@pcmk-1, 2009-12-08 11:22:57\n" #~ "\n" #~ " 1: cs:WFConnection ro:Secondary/Unknown ds:Inconsistent/DUnknown C r----\n" #~ "    ns:0 nr:0 dw:0 dr:0 al:0 bm:0 lo:0 pe:0 ua:0 ap:0 ep:1 wo:b oos:12248\n" #~ "[root@pcmk-1 ~]# \n" #~ "\n" #~ "Repeat on the second node\n" #~ "drbdadm --force create-md wwwdata \n" #~ "modprobe drbd\n" #~ "drbdadm up wwwdata\n" #~ "cat /proc/drbd\n" #~ "[root@pcmk-2 ~]# drbdadm --force create-md wwwdata\n" #~ "Writing meta data...\n" #~ "initializing activity log\n" #~ "NOT initialized bitmap\n" #~ "New drbd meta data block successfully created.\n" #~ "success\n" #~ "[root@pcmk-2 ~]# modprobe drbd\n" #~ "WARNING: Deprecated config file /etc/modprobe.conf, all config files belong into /etc/modprobe.d/.\n" #~ "[root@pcmk-2 ~]# drbdadm up wwwdata\n" #~ "[root@pcmk-2 ~]# cat /proc/drbd\n" #~ "version: 8.3.6 (api:88/proto:86-90)\n" #~ "GIT-hash: f3606c47cc6fcf6b3f086e425cb34af8b7a81bbf build by root@pcmk-1, 2009-12-08 11:22:57\n" #~ "\n" #~ " 1: cs:Connected ro:Secondary/Secondary ds:Inconsistent/Inconsistent C r----\n" #~ "    ns:0 nr:0 dw:0 dr:0 al:0 bm:0 lo:0 pe:0 ua:0 ap:0 ep:1 wo:b oos:12248\n" #~ " " #~ msgstr "" #~ "\n" #~ "[root@pcmk-1 ~]# modprobe drbd\n" #~ "[root@pcmk-1 ~]# drbdadm up wwwdata\n" #~ "[root@pcmk-1 ~]# cat /proc/drbd\n" #~ "version: 8.3.6 (api:88/proto:86-90)\n" #~ "GIT-hash: f3606c47cc6fcf6b3f086e425cb34af8b7a81bbf build by root@pcmk-1, 2009-12-08 11:22:57\n" #~ "\n" #~ " 1: cs:WFConnection ro:Secondary/Unknown ds:Inconsistent/DUnknown C r----\n" #~ "    ns:0 nr:0 dw:0 dr:0 al:0 bm:0 lo:0 pe:0 ua:0 ap:0 ep:1 wo:b oos:12248\n" #~ "[root@pcmk-1 ~]# \n" #~ "\n" #~ "Repeat on the second node\n" #~ "drbdadm --force create-md wwwdata \n" #~ "modprobe drbd\n" #~ "drbdadm up wwwdata\n" #~ "cat /proc/drbd\n" #~ "[root@pcmk-2 ~]# drbdadm --force create-md wwwdata\n" #~ "Writing meta data...\n" #~ "initializing activity log\n" #~ "NOT initialized bitmap\n" #~ "New drbd meta data block successfully created.\n" #~ "success\n" #~ "[root@pcmk-2 ~]# modprobe drbd\n" #~ "WARNING: Deprecated config file /etc/modprobe.conf, all config files belong into /etc/modprobe.d/.\n" #~ "[root@pcmk-2 ~]# drbdadm up wwwdata\n" #~ "[root@pcmk-2 ~]# cat /proc/drbd\n" #~ "version: 8.3.6 (api:88/proto:86-90)\n" #~ "GIT-hash: f3606c47cc6fcf6b3f086e425cb34af8b7a81bbf build by root@pcmk-1, 2009-12-08 11:22:57\n" #~ "\n" #~ " 1: cs:Connected ro:Secondary/Secondary ds:Inconsistent/Inconsistent C r----\n" #~ "    ns:0 nr:0 dw:0 dr:0 al:0 bm:0 lo:0 pe:0 ua:0 ap:0 ep:1 wo:b oos:12248\n" #~ " " #~ msgid "" #~ "\n" #~ "[root@pcmk-1 ~]# drbdadm -- --overwrite-data-of-peer primary wwwdata\n" #~ "[root@pcmk-1 ~]# cat /proc/drbd\n" #~ "version: 8.3.6 (api:88/proto:86-90)\n" #~ "GIT-hash: f3606c47cc6fcf6b3f086e425cb34af8b7a81bbf build by root@pcmk-1, 2009-12-08 11:22:57\n" #~ " 1: cs:SyncSource ro:Primary/Secondary ds:UpToDate/Inconsistent C r----\n" #~ "    ns:2184 nr:0 dw:0 dr:2472 al:0 bm:0 lo:0 pe:0 ua:0 ap:0 ep:1 wo:b oos:10064\n" #~ "        [=====>..............] sync'ed: 33.4% (10064/12248)K\n" #~ "        finish: 0:00:37 speed: 240 (240) K/sec\n" #~ "[root@pcmk-1 ~]# cat /proc/drbd\n" #~ "version: 8.3.6 (api:88/proto:86-90)\n" #~ "GIT-hash: f3606c47cc6fcf6b3f086e425cb34af8b7a81bbf build by root@pcmk-1, 2009-12-08 11:22:57\n" #~ " 1: cs:Connected ro:Primary/Secondary ds:UpToDate/UpToDate C r----\n" #~ "    ns:12248 nr:0 dw:0 dr:12536 al:0 bm:1 lo:0 pe:0 ua:0 ap:0 ep:1 wo:b oos:0\n" #~ " " #~ msgstr "" #~ "\n" #~ "[root@pcmk-1 ~]# drbdadm -- --overwrite-data-of-peer primary wwwdata\n" #~ "[root@pcmk-1 ~]# cat /proc/drbd\n" #~ "version: 8.3.6 (api:88/proto:86-90)\n" #~ "GIT-hash: f3606c47cc6fcf6b3f086e425cb34af8b7a81bbf build by root@pcmk-1, 2009-12-08 11:22:57\n" #~ " 1: cs:SyncSource ro:Primary/Secondary ds:UpToDate/Inconsistent C r----\n" #~ "    ns:2184 nr:0 dw:0 dr:2472 al:0 bm:0 lo:0 pe:0 ua:0 ap:0 ep:1 wo:b oos:10064\n" #~ "        [=====>..............] sync'ed: 33.4% (10064/12248)K\n" #~ "        finish: 0:00:37 speed: 240 (240) K/sec\n" #~ "[root@pcmk-1 ~]# cat /proc/drbd\n" #~ "version: 8.3.6 (api:88/proto:86-90)\n" #~ "GIT-hash: f3606c47cc6fcf6b3f086e425cb34af8b7a81bbf build by root@pcmk-1, 2009-12-08 11:22:57\n" #~ " 1: cs:Connected ro:Primary/Secondary ds:UpToDate/UpToDate C r----\n" #~ "    ns:12248 nr:0 dw:0 dr:12536 al:0 bm:1 lo:0 pe:0 ua:0 ap:0 ep:1 wo:b oos:0\n" #~ " " #~ msgid "" #~ "\n" #~ "[root@pcmk-1 ~]# mkfs.ext4 /dev/drbd1\n" #~ "mke2fs 1.41.4 (27-Jan-2009)\n" #~ "Filesystem label=\n" #~ "OS type: Linux\n" #~ "Block size=1024 (log=0)\n" #~ "Fragment size=1024 (log=0)\n" #~ "3072 inodes, 12248 blocks\n" #~ "612 blocks (5.00%) reserved for the super user\n" #~ "First data block=1\n" #~ "Maximum filesystem blocks=12582912\n" #~ "2 block groups\n" #~ "8192 blocks per group, 8192 fragments per group\n" #~ "1536 inodes per group\n" #~ "Superblock backups stored on blocks: \n" #~ "        8193\n" #~ "\n" #~ "Writing inode tables: done                            \n" #~ "Creating journal (1024 blocks): done\n" #~ "Writing superblocks and filesystem accounting information: done\n" #~ "\n" #~ "This filesystem will be automatically checked every 26 mounts or\n" #~ "180 days, whichever comes first.  Use tune2fs -c or -i to override.\n" #~ "\n" #~ "Now mount the newly created filesystem so we can create our index file\n" #~ "mount /dev/drbd1 /mnt/\n" #~ "cat <<-END >/mnt/index.html\n" #~ "<html>\n" #~ "<body>My Test Site - drbd</body>\n" #~ "</html>\n" #~ "END\n" #~ "umount /dev/drbd1\n" #~ "[root@pcmk-1 ~]# mount /dev/drbd1 /mnt/\n" #~ "[root@pcmk-1 ~]# cat <<-END >/mnt/index.html\n" #~ "> <html>\n" #~ "> <body>My Test Site - drbd</body>\n" #~ "> </html>\n" #~ "> END\n" #~ "[root@pcmk-1 ~]# umount /dev/drbd1\n" #~ " " #~ msgstr "" #~ "\n" #~ "[root@pcmk-1 ~]# mkfs.ext4 /dev/drbd1\n" #~ "mke2fs 1.41.4 (27-Jan-2009)\n" #~ "Filesystem label=\n" #~ "OS type: Linux\n" #~ "Block size=1024 (log=0)\n" #~ "Fragment size=1024 (log=0)\n" #~ "3072 inodes, 12248 blocks\n" #~ "612 blocks (5.00%) reserved for the super user\n" #~ "First data block=1\n" #~ "Maximum filesystem blocks=12582912\n" #~ "2 block groups\n" #~ "8192 blocks per group, 8192 fragments per group\n" #~ "1536 inodes per group\n" #~ "Superblock backups stored on blocks: \n" #~ "        8193\n" #~ "\n" #~ "Writing inode tables: done                            \n" #~ "Creating journal (1024 blocks): done\n" #~ "Writing superblocks and filesystem accounting information: done\n" #~ "\n" #~ "This filesystem will be automatically checked every 26 mounts or\n" #~ "180 days, whichever comes first.  Use tune2fs -c or -i to override.\n" #~ "\n" #~ "Now mount the newly created filesystem so we can create our index file\n" #~ "mount /dev/drbd1 /mnt/\n" #~ "cat <<-END >/mnt/index.html\n" #~ "<html>\n" #~ "<body>My Test Site - drbd</body>\n" #~ "</html>\n" #~ "END\n" #~ "umount /dev/drbd1\n" #~ "[root@pcmk-1 ~]# mount /dev/drbd1 /mnt/\n" #~ "[root@pcmk-1 ~]# cat <<-END >/mnt/index.html\n" #~ "> <html>\n" #~ "> <body>My Test Site - drbd</body>\n" #~ "> </html>\n" #~ "> END\n" #~ "[root@pcmk-1 ~]# umount /dev/drbd1\n" #~ " " #~ msgid "One handy feature of the crm shell is that you can use it in interactive mode to make several changes atomically." #~ msgstr "crm shell一个便捷的特性是可以工作在交互模式下并自动的变更配置中的相关部分。" #~ msgid "First we launch the shell. The prompt will change to indicate you’re in interactive mode." #~ msgstr "首先我们打开shell。提示会指出你现在是在交互模式下。" #~ msgid "" #~ "\n" #~ "[root@pcmk-1 ~]# crm\n" #~ "cib crm(live)#\n" #~ " " #~ msgstr "" #~ "\n" #~ "[root@pcmk-1 ~]# crm\n" #~ "cib crm(live)#\n" #~ " " #~ msgid "Next we must create a working copy or the current configuration. This is where all our changes will go. The cluster will not see any of them until we say its ok. Notice again how the prompt changes, this time to indicate that we’re no longer looking at the live cluster." #~ msgstr "然后我们创建一个当前配置文件的副本。我们在这个副本里更改配置。直到我们提交这个副本之前集群不会应用这些更改。请注意提示符的变更,现在它指出我们看到的已经不是当前(live)集群的配置文件。" #~ msgid "" #~ "\n" #~ "cib crm(live)# cib new drbd\n" #~ "INFO: drbd shadow CIB created\n" #~ "crm(drbd)#\n" #~ " " #~ msgstr "" #~ "\n" #~ "cib crm(live)# cib new drbd\n" #~ "INFO: drbd shadow CIB created\n" #~ "crm(drbd)#\n" #~ " " #~ msgid "Now we can create our DRBD clone and display the revised configuration." #~ msgstr "现在我们可以创建DRBD clone,然后看看修改过后的配置文件。" #~ msgid "" #~ "\n" #~ "crm(drbd)# configure primitive WebData ocf:linbit:drbd params drbd_resource=wwwdata \\\n" #~ "        op monitor interval=60s\n" #~ "crm(drbd)# configure ms WebDataClone WebData meta master-max=1 master-node-max=1 \\\n" #~ "        clone-max=2 clone-node-max=1 notify=true\n" #~ "crm(drbd)# configure show\n" #~ "node pcmk-1\n" #~ "node pcmk-2\n" #~ "primitive WebData ocf:linbit:drbd \\\n" #~ " params drbd_resource=\"wwwdata\" \\\n" #~ " op monitor interval=\"60s\"\n" #~ "primitive WebSite ocf:heartbeat:apache \\\n" #~ "        params configfile=\"/etc/httpd/conf/httpd.conf\" \\\n" #~ "        op monitor interval=\"1min\"\n" #~ "primitive ClusterIP ocf:heartbeat:IPaddr2 \\\n" #~ "        params ip=\"192.168.122.101\" cidr_netmask=\"32\" \\\n" #~ "        op monitor interval=\"30s\"\n" #~ "ms WebDataClone WebData \\\n" #~ " meta master-max=\"1\" master-node-max=\"1\" clone-max=\"2\" clone-node-max=\"1\" notify=\"true\"\n" #~ "location prefer-pcmk-1 WebSite 50: pcmk-1\n" #~ "colocation website-with-ip inf: WebSite ClusterIP\n" #~ "order apache-after-ip inf: ClusterIP WebSite\n" #~ "property $id=\"cib-bootstrap-options\" \\\n" #~ "        dc-version=\"1.0.5-462f1569a43740667daf7b0f6b521742e9eb8fa7\" \\\n" #~ "        cluster-infrastructure=\"openais\" \\\n" #~ "        expected-quorum-votes=”2” \\\n" #~ "        stonith-enabled=\"false\" \\\n" #~ "        no-quorum-policy=\"ignore\"\n" #~ "rsc_defaults $id=\"rsc-options\" \\\n" #~ "        resource-stickiness=”100”\n" #~ " " #~ msgstr "" #~ "\n" #~ "crm(drbd)# configure primitive WebData ocf:linbit:drbd params drbd_resource=wwwdata \\\n" #~ "        op monitor interval=60s\n" #~ "crm(drbd)# configure ms WebDataClone WebData meta master-max=1 master-node-max=1 \\\n" #~ "        clone-max=2 clone-node-max=1 notify=true\n" #~ "crm(drbd)# configure show\n" #~ "node pcmk-1\n" #~ "node pcmk-2\n" #~ "primitive WebData ocf:linbit:drbd \\\n" #~ " params drbd_resource=\"wwwdata\" \\\n" #~ " op monitor interval=\"60s\"\n" #~ "primitive WebSite ocf:heartbeat:apache \\\n" #~ "        params configfile=\"/etc/httpd/conf/httpd.conf\" \\\n" #~ "        op monitor interval=\"1min\"\n" #~ "primitive ClusterIP ocf:heartbeat:IPaddr2 \\\n" #~ "        params ip=\"192.168.122.101\" cidr_netmask=\"32\" \\\n" #~ "        op monitor interval=\"30s\"\n" #~ "ms WebDataClone WebData \\\n" #~ " meta master-max=\"1\" master-node-max=\"1\" clone-max=\"2\" clone-node-max=\"1\" notify=\"true\"\n" #~ "location prefer-pcmk-1 WebSite 50: pcmk-1\n" #~ "colocation website-with-ip inf: WebSite ClusterIP\n" #~ "order apache-after-ip inf: ClusterIP WebSite\n" #~ "property $id=\"cib-bootstrap-options\" \\\n" #~ "        dc-version=\"1.0.5-462f1569a43740667daf7b0f6b521742e9eb8fa7\" \\\n" #~ "        cluster-infrastructure=\"openais\" \\\n" #~ "        expected-quorum-votes=”2” \\\n" #~ "        stonith-enabled=\"false\" \\\n" #~ "        no-quorum-policy=\"ignore\"\n" #~ "rsc_defaults $id=\"rsc-options\" \\\n" #~ "        resource-stickiness=”100”\n" #~ " " #~ msgid "Once we’re happy with the changes, we can tell the cluster to start using them and use crm_mon to check everything is functioning." #~ msgstr "一旦你确认这些修改没问题,我们就提交这个副本,然后用crm_mon来看看修改是否生效了。" #~ msgid "" #~ "\n" #~ "crm(drbd)# cib commit drbd\n" #~ "INFO: commited 'drbd' shadow CIB to the cluster\n" #~ "crm(drbd)# quit\n" #~ "bye\n" #~ "[root@pcmk-1 ~]# crm_mon\n" #~ "============\n" #~ "Last updated: Tue Sep  1 09:37:13 2009\n" #~ "Stack: openais\n" #~ "Current DC: pcmk-1 - partition with quorum\n" #~ "Version: 1.0.5-462f1569a43740667daf7b0f6b521742e9eb8fa7\n" #~ "2 Nodes configured, 2 expected votes\n" #~ "3 Resources configured.\n" #~ "============\n" #~ "\n" #~ "Online: [ pcmk-1 pcmk-2 ]\n" #~ "\n" #~ "ClusterIP        (ocf::heartbeat:IPaddr):        Started pcmk-1\n" #~ "WebSite (ocf::heartbeat:apache):        Started pcmk-1\n" #~ "Master/Slave Set: WebDataClone\n" #~ " Masters: [ pcmk-2 ]\n" #~ " Slaves: [ pcmk-1 ]\n" #~ " " #~ msgstr "" #~ "\n" #~ "crm(drbd)# cib commit drbd\n" #~ "INFO: commited 'drbd' shadow CIB to the cluster\n" #~ "crm(drbd)# quit\n" #~ "bye\n" #~ "[root@pcmk-1 ~]# crm_mon\n" #~ "============\n" #~ "Last updated: Tue Sep  1 09:37:13 2009\n" #~ "Stack: openais\n" #~ "Current DC: pcmk-1 - partition with quorum\n" #~ "Version: 1.0.5-462f1569a43740667daf7b0f6b521742e9eb8fa7\n" #~ "2 Nodes configured, 2 expected votes\n" #~ "3 Resources configured.\n" #~ "============\n" #~ "\n" #~ "Online: [ pcmk-1 pcmk-2 ]\n" #~ "\n" #~ "ClusterIP        (ocf::heartbeat:IPaddr):        Started pcmk-1\n" #~ "WebSite (ocf::heartbeat:apache):        Started pcmk-1\n" #~ "Master/Slave Set: WebDataClone\n" #~ " Masters: [ pcmk-2 ]\n" #~ " Slaves: [ pcmk-1 ]\n" #~ " " #~ msgid "Once again we’ll use the shell’s interactive mode" #~ msgstr "我们再一次的使用交互模式的crm shell" #~ msgid "" #~ "\n" #~ "[root@pcmk-1 ~]# crm\n" #~ "crm(live)# cib new fs\n" #~ "INFO: fs shadow CIB created\n" #~ "crm(fs)# configure primitive WebFS ocf:heartbeat:Filesystem \\\n" #~ "        params device=\"/dev/drbd/by-res/wwwdata\" directory=\"/var/www/html\" fstype=\"ext4\"\n" #~ "crm(fs)# configure colocation fs_on_drbd inf: WebFS WebDataClone:Master\n" #~ "crm(fs)# configure order WebFS-after-WebData inf: WebDataClone:promote WebFS:start\n" #~ " " #~ msgstr "" #~ "\n" #~ "[root@pcmk-1 ~]# crm\n" #~ "crm(live)# cib new fs\n" #~ "INFO: fs shadow CIB created\n" #~ "crm(fs)# configure primitive WebFS ocf:heartbeat:Filesystem \\\n" #~ "        params device=\"/dev/drbd/by-res/wwwdata\" directory=\"/var/www/html\" fstype=\"ext4\"\n" #~ "crm(fs)# configure colocation fs_on_drbd inf: WebFS WebDataClone:Master\n" #~ "crm(fs)# configure order WebFS-after-WebData inf: WebDataClone:promote WebFS:start\n" #~ " " #~ msgid "" #~ "\n" #~ "crm(fs)# configure colocation WebSite-with-WebFS inf: WebSite WebFS\n" #~ "crm(fs)# configure order WebSite-after-WebFS inf: WebFS WebSite\n" #~ " " #~ msgstr "" #~ "\n" #~ "crm(fs)# configure colocation WebSite-with-WebFS inf: WebSite WebFS\n" #~ "crm(fs)# configure order WebSite-after-WebFS inf: WebFS WebSite\n" #~ " " #~ msgid "" #~ "\n" #~ "[root@pcmk-1 ~]# crm configure show\n" #~ "node pcmk-1\n" #~ "node pcmk-2\n" #~ "primitive WebData ocf:linbit:drbd \\\n" #~ "        params drbd_resource=\"wwwdata\" \\\n" #~ "        op monitor interval=\"60s\"\n" #~ "primitive WebFS ocf:heartbeat:Filesystem \\\n" #~ "        params device=\"/dev/drbd/by-res/wwwdata\" directory=\"/var/www/html\" fstype=\"ext4\"\n" #~ "primitive WebSite ocf:heartbeat:apache \\\n" #~ "        params configfile=\"/etc/httpd/conf/httpd.conf\" \\\n" #~ "        op monitor interval=\"1min\"\n" #~ "primitive ClusterIP ocf:heartbeat:IPaddr2 \\\n" #~ "        params ip=\"192.168.122.101\" cidr_netmask=\"32\" \\\n" #~ "        op monitor interval=\"30s\"\n" #~ "ms WebDataClone WebData \\\n" #~ "        meta master-max=\"1\" master-node-max=\"1\" clone-max=\"2\" clone-node-max=\"1\" notify=\"true\"\n" #~ "location prefer-pcmk-1 WebSite 50: pcmk-1\n" #~ "colocation WebSite-with-WebFS inf: WebSite WebFS\n" #~ "colocation fs_on_drbd inf: WebFS WebDataClone:Master\n" #~ "colocation website-with-ip inf: WebSite ClusterIP\n" #~ "order WebFS-after-WebData inf: WebDataClone:promote WebFS:start\n" #~ "order WebSite-after-WebFS inf: WebFS WebSite\n" #~ "order apache-after-ip inf: ClusterIP WebSite\n" #~ "property $id=\"cib-bootstrap-options\" \\\n" #~ "        dc-version=\"1.0.5-462f1569a43740667daf7b0f6b521742e9eb8fa7\" \\\n" #~ "        cluster-infrastructure=\"openais\" \\\n" #~ "        expected-quorum-votes=”2” \\\n" #~ "        stonith-enabled=\"false\" \\\n" #~ "        no-quorum-policy=\"ignore\"\n" #~ "rsc_defaults $id=\"rsc-options\" \\\n" #~ "        resource-stickiness=”100”\n" #~ " " #~ msgstr "" #~ "\n" #~ "[root@pcmk-1 ~]# crm configure show\n" #~ "node pcmk-1\n" #~ "node pcmk-2\n" #~ "primitive WebData ocf:linbit:drbd \\\n" #~ "        params drbd_resource=\"wwwdata\" \\\n" #~ "        op monitor interval=\"60s\"\n" #~ "primitive WebFS ocf:heartbeat:Filesystem \\\n" #~ "        params device=\"/dev/drbd/by-res/wwwdata\" directory=\"/var/www/html\" fstype=\"ext4\"\n" #~ "primitive WebSite ocf:heartbeat:apache \\\n" #~ "        params configfile=\"/etc/httpd/conf/httpd.conf\" \\\n" #~ "        op monitor interval=\"1min\"\n" #~ "primitive ClusterIP ocf:heartbeat:IPaddr2 \\\n" #~ "        params ip=\"192.168.122.101\" cidr_netmask=\"32\" \\\n" #~ "        op monitor interval=\"30s\"\n" #~ "ms WebDataClone WebData \\\n" #~ "        meta master-max=\"1\" master-node-max=\"1\" clone-max=\"2\" clone-node-max=\"1\" notify=\"true\"\n" #~ "location prefer-pcmk-1 WebSite 50: pcmk-1\n" #~ "colocation WebSite-with-WebFS inf: WebSite WebFS\n" #~ "colocation fs_on_drbd inf: WebFS WebDataClone:Master\n" #~ "colocation website-with-ip inf: WebSite ClusterIP\n" #~ "order WebFS-after-WebData inf: WebDataClone:promote WebFS:start\n" #~ "order WebSite-after-WebFS inf: WebFS WebSite\n" #~ "order apache-after-ip inf: ClusterIP WebSite\n" #~ "property $id=\"cib-bootstrap-options\" \\\n" #~ "        dc-version=\"1.0.5-462f1569a43740667daf7b0f6b521742e9eb8fa7\" \\\n" #~ "        cluster-infrastructure=\"openais\" \\\n" #~ "        expected-quorum-votes=”2” \\\n" #~ "        stonith-enabled=\"false\" \\\n" #~ "        no-quorum-policy=\"ignore\"\n" #~ "rsc_defaults $id=\"rsc-options\" \\\n" #~ "        resource-stickiness=”100”\n" #~ " " #~ msgid "" #~ "\n" #~ "crm(fs)# cib commit fs\n" #~ "INFO: commited 'fs' shadow CIB to the cluster\n" #~ "crm(fs)# quit\n" #~ "bye\n" #~ "[root@pcmk-1 ~]# crm_mon\n" #~ "============\n" #~ "Last updated: Tue Sep  1 10:08:44 2009\n" #~ "Stack: openais\n" #~ "Current DC: pcmk-1 - partition with quorum\n" #~ "Version: 1.0.5-462f1569a43740667daf7b0f6b521742e9eb8fa7\n" #~ "2 Nodes configured, 2 expected votes\n" #~ "4 Resources configured.\n" #~ "============\n" #~ "\n" #~ "Online: [ pcmk-1 pcmk-2 ]\n" #~ "\n" #~ "ClusterIP        (ocf::heartbeat:IPaddr):        Started pcmk-1\n" #~ "WebSite (ocf::heartbeat:apache): Started pcmk-1\n" #~ "Master/Slave Set: WebDataClone\n" #~ "        Masters: [ pcmk-1 ]\n" #~ "        Slaves: [ pcmk-2 ]\n" #~ "WebFS (ocf::heartbeat:Filesystem): Started pcmk-1\n" #~ " " #~ msgstr "" #~ "\n" #~ "crm(fs)# cib commit fs\n" #~ "INFO: commited 'fs' shadow CIB to the cluster\n" #~ "crm(fs)# quit\n" #~ "bye\n" #~ "[root@pcmk-1 ~]# crm_mon\n" #~ "============\n" #~ "Last updated: Tue Sep  1 10:08:44 2009\n" #~ "Stack: openais\n" #~ "Current DC: pcmk-1 - partition with quorum\n" #~ "Version: 1.0.5-462f1569a43740667daf7b0f6b521742e9eb8fa7\n" #~ "2 Nodes configured, 2 expected votes\n" #~ "4 Resources configured.\n" #~ "============\n" #~ "\n" #~ "Online: [ pcmk-1 pcmk-2 ]\n" #~ "\n" #~ "ClusterIP        (ocf::heartbeat:IPaddr):        Started pcmk-1\n" #~ "WebSite (ocf::heartbeat:apache): Started pcmk-1\n" #~ "Master/Slave Set: WebDataClone\n" #~ "        Masters: [ pcmk-1 ]\n" #~ "        Slaves: [ pcmk-2 ]\n" #~ "WebFS (ocf::heartbeat:Filesystem): Started pcmk-1\n" #~ " " #~ msgid "" #~ "\n" #~ "[root@pcmk-1 ~]# crm node standby\n" #~ "[root@pcmk-1 ~]# crm_mon\n" #~ "============\n" #~ "Last updated: Tue Sep  1 10:09:57 2009\n" #~ "Stack: openais\n" #~ "Current DC: pcmk-1 - partition with quorum\n" #~ "Version: 1.0.5-462f1569a43740667daf7b0f6b521742e9eb8fa7\n" #~ "2 Nodes configured, 2 expected votes\n" #~ "4 Resources configured.\n" #~ "============\n" #~ "\n" #~ "Node pcmk-1: standby\n" #~ "Online: [ pcmk-2 ]\n" #~ "\n" #~ "ClusterIP        (ocf::heartbeat:IPaddr):        Started pcmk-2\n" #~ "WebSite (ocf::heartbeat:apache):        Started pcmk-2\n" #~ "Master/Slave Set: WebDataClone\n" #~ "        Masters: [ pcmk-2 ]\n" #~ "        Stopped: [ WebData:1 ]\n" #~ "WebFS   (ocf::heartbeat:Filesystem):    Started pcmk-2\n" #~ " " #~ msgstr "" #~ "\n" #~ "[root@pcmk-1 ~]# crm node standby\n" #~ "[root@pcmk-1 ~]# crm_mon\n" #~ "============\n" #~ "Last updated: Tue Sep  1 10:09:57 2009\n" #~ "Stack: openais\n" #~ "Current DC: pcmk-1 - partition with quorum\n" #~ "Version: 1.0.5-462f1569a43740667daf7b0f6b521742e9eb8fa7\n" #~ "2 Nodes configured, 2 expected votes\n" #~ "4 Resources configured.\n" #~ "============\n" #~ "\n" #~ "Node pcmk-1: standby\n" #~ "Online: [ pcmk-2 ]\n" #~ "\n" #~ "ClusterIP        (ocf::heartbeat:IPaddr):        Started pcmk-2\n" #~ "WebSite (ocf::heartbeat:apache):        Started pcmk-2\n" #~ "Master/Slave Set: WebDataClone\n" #~ "        Masters: [ pcmk-2 ]\n" #~ "        Stopped: [ WebData:1 ]\n" #~ "WebFS   (ocf::heartbeat:Filesystem):    Started pcmk-2\n" #~ " " pacemaker-master/doc/Clusters_from_Scratch/zh-CN/Ch-Stonith.mo000066400000000000000000000274411217637305600246200ustar00rootroot00000000000000%PQ 9SG,zD#v&6#&TV9"% &5&&\'' ''( )()9)R)*s*f+#,y,<-H.Vf.%..%.     [root@pcmk-1 ~]# crm crm(live)# cib new stonith INFO: stonith shadow CIB created crm(stonith)# configure primitive rsa-fencing stonith::external/ibmrsa \         params hostname=”pcmk-1 pcmk-2" ipaddr=192.168.122.31 userid=mgmt passwd=abc123 type=ibm \         op monitor interval="60s" crm(stonith)# configure clone Fencing rsa-fencing crm(stonith)# configure property stonith-enabled="true" crm(stonith)# configure show node pcmk-1 node pcmk-2 primitive WebData ocf:linbit:drbd \         params drbd_resource="wwwdata" \         op monitor interval="60s" primitive WebFS ocf:heartbeat:Filesystem \         params device="/dev/drbd/by-res/wwwdata" directory="/var/www/html" fstype=”gfs2” primitive WebSite ocf:heartbeat:apache \         params configfile="/etc/httpd/conf/httpd.conf" \         op monitor interval="1min" primitive ClusterIP ocf:heartbeat:IPaddr2 \         params ip=”192.168.122.101” cidr_netmask=”32” clusterip_hash=”sourceip” \         op monitor interval="30s" primitive dlm ocf:pacemaker:controld \         op monitor interval="120s" primitive gfs-control ocf:pacemaker:controld \    params daemon=”gfs_controld.pcmk” args=”-g 0” \         op monitor interval="120s" primitive rsa-fencing stonith::external/ibmrsa \ params hostname=”pcmk-1 pcmk-2" ipaddr=192.168.122.31 userid=mgmt passwd=abc123 type=ibm \ op monitor interval="60s" ms WebDataClone WebData \         meta master-max="2" master-node-max="1" clone-max="2" clone-node-max="1" notify="true" clone Fencing rsa-fencing clone WebFSClone WebFS clone WebIP ClusterIP  \         meta globally-unique=”true” clone-max=”2” clone-node-max=”2” clone WebSiteClone WebSite clone dlm-clone dlm \         meta interleave="true" clone gfs-clone gfs-control \         meta interleave="true" colocation WebFS-with-gfs-control inf: WebFSClone gfs-clone colocation WebSite-with-WebFS inf: WebSiteClone WebFSClone colocation fs_on_drbd inf: WebFSClone WebDataClone:Master colocation gfs-with-dlm inf: gfs-clone dlm-clone colocation website-with-ip inf: WebSiteClone WebIP order WebFS-after-WebData inf: WebDataClone:promote WebFSClone:start order WebSite-after-WebFS inf: WebFSClone WebSiteClone order apache-after-ip inf: WebIP WebSiteClone order start-WebFS-after-gfs-control inf: gfs-clone WebFSClone order start-gfs-after-dlm inf: dlm-clone gfs-clone property $id="cib-bootstrap-options" \         dc-version="1.0.5-462f1569a43740667daf7b0f6b521742e9eb8fa7" \         cluster-infrastructure="openais" \         expected-quorum-votes=”2” \         stonith-enabled="true" \         no-quorum-policy="ignore" rsc_defaults $id="rsc-options" \         resource-stickiness=”100” stonith -t external/ibmrsa -n [root@pcmk-1 ~]# stonith -t external/ibmrsa -n hostname  ipaddr  userid  passwd  type And finally, since we disabled it earlier, we need to re-enable STONITHAssuming we have an IBM BladeCenter containing our two nodes and the management interface is active on 192.168.122.31, then we would chose the external/ibmrsa driver in step 2 and obtain the following list of parametersAssuming we know the username and password for the management interface, we would create a STONITH resource with the shellConfigure STONITHConfiguring STONITHCreate a clone from the primitive resource if the device can shoot more than one node and supports multiple simultaneous connections.Create a file called stonith.xml containing a primitive resource with a class of stonith, a type of {type} and a parameter for each of the values returned in step 2ExampleFind the correct driver: stonith -LHopefully the developers chose names that make sense, if not you can query for some additional information by finding an active cluster node and running:It is crucial that the STONITH device can allow the cluster to differentiate between a node failure and a network one.Just because a node is unresponsive, this doesn’t mean it isn’t accessing your data. The only way to be 100% sure that your data is safe, is to use STONITH so we can be certain that the node is truly offline, before allowing the data to be accessed from another node.Likewise, any device that relies on the machine being active (such as SSH-based “devices” used during testing) are inappropriate.STONITH also has a role to play in the event that a clustered service cannot be stopped. In this case, the cluster uses STONITH to force the whole node offline, thereby making it safe to start the service elsewhere.STONITH is an acronym for Shoot-The-Other-Node-In-The-Head and it protects your data from being corrupted by rouge nodes or concurrent access.Since every device is different, the parameters needed to configure it will vary. To find out the parameters required by the device: stonith -t {type} -nThe biggest mistake people make in choosing a STONITH device is to use remote power switch (such as many onboard IMPI controllers) that shares power with the node it controls. In such cases, the cluster cannot be sure if the node is really offline, or active and suffering from a network fault.The output should be XML formatted text containing additional parameter descriptionsUpload it into the CIB using cibadmin: cibadmin -C -o resources --xml-file stonith.xmlWhat STONITH Device Should You UseWhy You Need STONITHlrmadmin -M stonith {type} pacemaker Project-Id-Version: 0 POT-Creation-Date: 2010-12-15T23:32:37 PO-Revision-Date: 2010-12-16 00:38+0800 Last-Translator: Charlie Chen Language-Team: None Language: MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [root@pcmk-1 ~]# crm crm(live)# cib new stonith INFO: stonith shadow CIB created crm(stonith)# configure primitive rsa-fencing stonith::external/ibmrsa \         params hostname=”pcmk-1 pcmk-2" ipaddr=192.168.122.31 userid=mgmt passwd=abc123 type=ibm \         op monitor interval="60s" crm(stonith)# configure clone Fencing rsa-fencing crm(stonith)# configure property stonith-enabled="true" crm(stonith)# configure show node pcmk-1 node pcmk-2 primitive WebData ocf:linbit:drbd \         params drbd_resource="wwwdata" \         op monitor interval="60s" primitive WebFS ocf:heartbeat:Filesystem \         params device="/dev/drbd/by-res/wwwdata" directory="/var/www/html" fstype=”gfs2” primitive WebSite ocf:heartbeat:apache \         params configfile="/etc/httpd/conf/httpd.conf" \         op monitor interval="1min" primitive ClusterIP ocf:heartbeat:IPaddr2 \         params ip=”192.168.122.101” cidr_netmask=”32” clusterip_hash=”sourceip” \         op monitor interval="30s" primitive dlm ocf:pacemaker:controld \         op monitor interval="120s" primitive gfs-control ocf:pacemaker:controld \    params daemon=”gfs_controld.pcmk” args=”-g 0” \         op monitor interval="120s" primitive rsa-fencing stonith::external/ibmrsa \ params hostname=”pcmk-1 pcmk-2" ipaddr=192.168.122.31 userid=mgmt passwd=abc123 type=ibm \ op monitor interval="60s" ms WebDataClone WebData \         meta master-max="2" master-node-max="1" clone-max="2" clone-node-max="1" notify="true" clone Fencing rsa-fencing clone WebFSClone WebFS clone WebIP ClusterIP  \         meta globally-unique=”true” clone-max=”2” clone-node-max=”2” clone WebSiteClone WebSite clone dlm-clone dlm \         meta interleave="true" clone gfs-clone gfs-control \         meta interleave="true" colocation WebFS-with-gfs-control inf: WebFSClone gfs-clone colocation WebSite-with-WebFS inf: WebSiteClone WebFSClone colocation fs_on_drbd inf: WebFSClone WebDataClone:Master colocation gfs-with-dlm inf: gfs-clone dlm-clone colocation website-with-ip inf: WebSiteClone WebIP order WebFS-after-WebData inf: WebDataClone:promote WebFSClone:start order WebSite-after-WebFS inf: WebFSClone WebSiteClone order apache-after-ip inf: WebIP WebSiteClone order start-WebFS-after-gfs-control inf: gfs-clone WebFSClone order start-gfs-after-dlm inf: dlm-clone gfs-clone property $id="cib-bootstrap-options" \         dc-version="1.0.5-462f1569a43740667daf7b0f6b521742e9eb8fa7" \         cluster-infrastructure="openais" \         expected-quorum-votes=”2” \         stonith-enabled="true" \         no-quorum-policy="ignore" rsc_defaults $id="rsc-options" \         resource-stickiness=”100” stonith -t external/ibmrsa -n [root@pcmk-1 ~]# stonith -t external/ibmrsa -n hostname  ipaddr  userid  passwd  type 最后,我们要重新打开之前禁用的STONITH:假设我们有一个 包含两个节点的IBM BladeCenter,控制界面的IP是192.168.122.31,然后我们选择 external/ibmrsa作为驱动,然后配置下面列表当中的参数。假设我们知道管理界面的用户名和密码,我们要创建一个STONITH的资源:配置 STONITH配置STONITH如果这个设备可以击杀多个设备并且支持从多个节点连接过来,那我们从这个原始资源创建一个克隆。创建stonith.xml文件 包含了一个原始的源,它定义了资stonith类下面的某个type和这个type所需的参数。例子找到正确的STONITH驱动: stonith -L希望开发者选择了合适的名称,如果不是这样,你可以在活动的机器上面执行以下命令来获得更多信息。重要的一点是STONITH设备可以让集群区分节点故障和网络故障。因为如果一个节点没有相应,但并不代表它没有在操作你的数据,100%保证数据安全的做法就是在允许另外一个节点操作数据之前,使用STONITH来保证节点真的下线了。同样地, 任何依靠可用节点的设备(比如测试用的基于SSH的“设备”)都是不适当的。STONITH另外一个用场是在当集群服务无法停止的时候。这个时候,集群可以用STONITH来强制使节点下线,从而可以安全的得在其他地方启动服务。STONITH 是爆其他节点的头( Shoot-The-Other-Node-In-The-Head)的缩写,它能保护你的数据不被不正常的节点破坏或是并发写入。因为设备的不同, 配置的参数也不一样。 想看设备所需设置的参数,可以用: stonith -t {type} -n人们常常犯得一个错误就是选择远程电源开关作为STONITH设备(比如许多主板自带的IPMI控制器) 。在那种情况下,集群不能分辨节点是真正的下线了,还是网络无法连通了。输出应该是XML格式的文本文件,它包含了更详细的描述使用cibadmin来更新CIB配置文件:cibadmin -C -o resources --xml-file stonith.xml你该用什么样的STONITH设备。为什么需要 STONITHlrmadmin -M stonith {type} pacemaker pacemaker-master/doc/Clusters_from_Scratch/zh-CN/Ch-Stonith.po000066400000000000000000000421771217637305600246260ustar00rootroot00000000000000# # AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: 0\n" "POT-Creation-Date: 2012-10-17T05:19:03\n" "PO-Revision-Date: 2010-12-16 00:38+0800\n" "Last-Translator: Charlie Chen \n" "Language-Team: None\n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. Tag: title #, no-c-format msgid "Configure STONITH" msgstr "配置 STONITH" #. Tag: title #, fuzzy, no-c-format msgid "What Is STONITH" msgstr "为什么需要 STONITH" #. Tag: para #, fuzzy, no-c-format msgid "STONITH is an acronym for Shoot-The-Other-Node-In-The-Head and it protects your data from being corrupted by rogue nodes or concurrent access." msgstr "STONITH 是爆其他节点的头( Shoot-The-Other-Node-In-The-Head)的缩写,它能保护你的数据不被不正常的节点破坏或是并发写入。" #. Tag: para #, no-c-format msgid "Just because a node is unresponsive, this doesn’t mean it isn’t accessing your data. The only way to be 100% sure that your data is safe, is to use STONITH so we can be certain that the node is truly offline, before allowing the data to be accessed from another node." msgstr "因为如果一个节点没有相应,但并不代表它没有在操作你的数据,100%保证数据安全的做法就是在允许另外一个节点操作数据之前,使用STONITH来保证节点真的下线了。" #. Tag: para #, no-c-format msgid "STONITH also has a role to play in the event that a clustered service cannot be stopped. In this case, the cluster uses STONITH to force the whole node offline, thereby making it safe to start the service elsewhere." msgstr "STONITH另外一个用场是在当集群服务无法停止的时候。这个时候,集群可以用STONITH来强制使节点下线,从而可以安全的得在其他地方启动服务。" #. Tag: title #, no-c-format msgid "What STONITH Device Should You Use" msgstr "你该用什么样的STONITH设备。" #. Tag: para #, no-c-format msgid "It is crucial that the STONITH device can allow the cluster to differentiate between a node failure and a network one." msgstr "重要的一点是STONITH设备可以让集群区分节点故障和网络故障。" #. Tag: para #, fuzzy, no-c-format msgid "The biggest mistake people make in choosing a STONITH device is to use remote power switch (such as many on-board IMPI controllers) that shares power with the node it controls. In such cases, the cluster cannot be sure if the node is really offline, or active and suffering from a network fault." msgstr "人们常常犯得一个错误就是选择远程电源开关作为STONITH设备(比如许多主板自带的IPMI控制器) 。在那种情况下,集群不能分辨节点是真正的下线了,还是网络无法连通了。" #. Tag: para #, fuzzy, no-c-format msgid "Likewise, any device that relies on the machine being active (such as SSH-based \"devices\" used during testing) are inappropriate." msgstr "同样地, 任何依靠可用节点的设备(比如测试用的基于SSH的“设备”)都是不适当的。" #. Tag: title #, no-c-format msgid "Configuring STONITH" msgstr "配置STONITH" #. Tag: para #, fuzzy, no-c-format msgid "Find the correct driver: pcs stonith list" msgstr "找到正确的STONITH驱动: stonith -L" #. Tag: para #, no-c-format msgid "Find the parameters associated with the device: pcs stonith describe <agent name>" msgstr "" #. Tag: para #, no-c-format msgid "Create a local config to make changes to pcs cluster cib stonith_cfg" msgstr "" #. Tag: para #, no-c-format msgid "Create the fencing resource using pcs -f stonith_cfg stonith create <stonith_id> <stonith device type> [stonith device options]" msgstr "" #. Tag: para #, no-c-format msgid "Set stonith-enable to true. pcs -f stonith_cfg property set stonith-enabled=true" msgstr "" #. Tag: para #, no-c-format msgid "If the device does not know how to fence nodes based on their uname, you may also need to set the special pcmk_host_map parameter. See man stonithd for details." msgstr "" #. Tag: para #, no-c-format msgid "If the device does not support the list command, you may also need to set the special pcmk_host_list and/or pcmk_host_check parameters. See man stonithd for details." msgstr "" #. Tag: para #, no-c-format msgid "If the device does not expect the victim to be specified with the port parameter, you may also need to set the special pcmk_host_argument parameter. See man stonithd for details." msgstr "" #. Tag: para #, no-c-format msgid "Commit the new configuration. pcs cluster push cib stonith_cfg" msgstr "" #. Tag: para #, no-c-format msgid "Once the stonith resource is running, you can test it by executing: stonith_admin --reboot nodename. Although you might want to stop the cluster on that machine first." msgstr "" #. Tag: title #, no-c-format msgid "Example" msgstr "例子" #. Tag: para #, fuzzy, no-c-format msgid "Assuming we have an chassis containing four nodes and an IPMI device active on 10.0.0.1, then we would chose the fence_ipmilan driver in step 2 and obtain the following list of parameters" msgstr "假设我们有一个 包含两个节点的IBM BladeCenter,控制界面的IP是192.168.122.31,然后我们选择 external/ibmrsa作为驱动,然后配置下面列表当中的参数。" #. Tag: title #, no-c-format msgid "Obtaining a list of STONITH Parameters" msgstr "" #. Tag: programlisting #, no-c-format msgid "" "# pcs stonith describe fence_ipmilan\n" "Stonith options for: fence_ipmilan\n" " auth: IPMI Lan Auth type (md5, password, or none)\n" " ipaddr: IPMI Lan IP to talk to\n" " passwd: Password (if required) to control power on IPMI device\n" " passwd_script: Script to retrieve password (if required)\n" " lanplus: Use Lanplus\n" " login: Username/Login (if required) to control power on IPMI device\n" " action: Operation to perform. Valid operations: on, off, reboot, status, list, diag, monitor or metadata\n" " timeout: Timeout (sec) for IPMI operation\n" " cipher: Ciphersuite to use (same as ipmitool -C parameter)\n" " method: Method to fence (onoff or cycle)\n" " power_wait: Wait X seconds after on/off operation\n" " delay: Wait X seconds before fencing is started\n" " privlvl: Privilege level on IPMI device\n" " verbose: Verbose mode" msgstr "" #. Tag: para #, no-c-format msgid "from which we would create a STONITH resource fragment that might look like this" msgstr "" #. Tag: title #, no-c-format msgid "Sample STONITH Resource" msgstr "" #. Tag: screen #, no-c-format msgid "" "# pcs cluster cib stonith_cfg\n" "# pcs -f stonith_cfg stonith create impi-fencing fence_ipmilan \\\n" " pcmk_host_list=\"pcmk-1 pcmk-2\" ipaddr=10.0.0.1 login=testuser \\\n" " passwd=acd123 op monitor interval=60s" msgstr "" #. Tag: programlisting #, no-c-format msgid "" "# pcs -f stonith_cfg stonith\n" " impi-fencing (stonith:fence_ipmilan) Stopped" msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "And finally, since we disabled it earlier, we need to re-enable STONITH. At this point we should have the following configuration." msgstr "最后,我们要重新打开之前禁用的STONITH:" #. Tag: programlisting #, no-c-format msgid "" "# pcs -f stonith_cfg property set stonith-enabled=true\n" "# pcs -f stonith_cfg property\n" "dc-version: 1.1.8-1.el7-60a19ed12fdb4d5c6a6b6767f52e5391e447fec0\n" "cluster-infrastructure: corosync\n" "no-quorum-policy: ignore\n" "stonith-enabled: true" msgstr "" #. Tag: para #, no-c-format msgid "Now push the configuration into the cluster." msgstr "" #. Tag: programlisting #, no-c-format msgid "# pcs cluster push cib stonith_cfg" msgstr "" #~ msgid "Since every device is different, the parameters needed to configure it will vary. To find out the parameters required by the device: stonith -t {type} -n" #~ msgstr "因为设备的不同, 配置的参数也不一样。 想看设备所需设置的参数,可以用: stonith -t {type} -n" #~ msgid "Hopefully the developers chose names that make sense, if not you can query for some additional information by finding an active cluster node and running:" #~ msgstr "希望开发者选择了合适的名称,如果不是这样,你可以在活动的机器上面执行以下命令来获得更多信息。" #~ msgid "lrmadmin -M stonith {type} pacemaker\n" #~ msgstr "lrmadmin -M stonith {type} pacemaker\n" #~ msgid "The output should be XML formatted text containing additional parameter descriptions" #~ msgstr "输出应该是XML格式的文本文件,它包含了更详细的描述" #~ msgid "Create a file called stonith.xml containing a primitive resource with a class of stonith, a type of {type} and a parameter for each of the values returned in step 2" #~ msgstr "创建stonith.xml文件 包含了一个原始的源,它定义了资stonith类下面的某个type和这个type所需的参数。" #~ msgid "Create a clone from the primitive resource if the device can shoot more than one node and supports multiple simultaneous connections." #~ msgstr "如果这个设备可以击杀多个设备并且支持从多个节点连接过来,那我们从这个原始资源创建一个克隆。" #~ msgid "Upload it into the CIB using cibadmin: cibadmin -C -o resources --xml-file stonith.xml" #~ msgstr "使用cibadmin来更新CIB配置文件:cibadmin -C -o resources --xml-file stonith.xml" #~ msgid "" #~ "\n" #~ "stonith -t external/ibmrsa -n\n" #~ "[root@pcmk-1 ~]# stonith -t external/ibmrsa -n\n" #~ "hostname  ipaddr  userid  passwd  type\n" #~ msgstr "" #~ "\n" #~ "stonith -t external/ibmrsa -n\n" #~ "[root@pcmk-1 ~]# stonith -t external/ibmrsa -n\n" #~ "hostname  ipaddr  userid  passwd  type\n" #~ msgid "Assuming we know the username and password for the management interface, we would create a STONITH resource with the shell" #~ msgstr "假设我们知道管理界面的用户名和密码,我们要创建一个STONITH的资源:" #~ msgid "" #~ "\n" #~ "[root@pcmk-1 ~]# crm \n" #~ "crm(live)# cib new stonith\n" #~ "INFO: stonith shadow CIB created\n" #~ "crm(stonith)# configure primitive rsa-fencing stonith::external/ibmrsa \\\n" #~ "        params hostname=”pcmk-1 pcmk-2\" ipaddr=192.168.122.31 userid=mgmt passwd=abc123 type=ibm \\\n" #~ "        op monitor interval=\"60s\"\n" #~ "crm(stonith)# configure clone Fencing rsa-fencing\n" #~ msgstr "" #~ "\n" #~ "[root@pcmk-1 ~]# crm \n" #~ "crm(live)# cib new stonith\n" #~ "INFO: stonith shadow CIB created\n" #~ "crm(stonith)# configure primitive rsa-fencing stonith::external/ibmrsa \\\n" #~ "        params hostname=”pcmk-1 pcmk-2\" ipaddr=192.168.122.31 userid=mgmt passwd=abc123 type=ibm \\\n" #~ "        op monitor interval=\"60s\"\n" #~ "crm(stonith)# configure clone Fencing rsa-fencing\n" #~ msgid "" #~ "\n" #~ "crm(stonith)# configure property stonith-enabled=\"true\"\n" #~ "crm(stonith)# configure show\n" #~ "node pcmk-1\n" #~ "node pcmk-2\n" #~ "primitive WebData ocf:linbit:drbd \\\n" #~ "        params drbd_resource=\"wwwdata\" \\\n" #~ "        op monitor interval=\"60s\"\n" #~ "primitive WebFS ocf:heartbeat:Filesystem \\\n" #~ "        params device=\"/dev/drbd/by-res/wwwdata\" directory=\"/var/www/html\" fstype=”gfs2”\n" #~ "primitive WebSite ocf:heartbeat:apache \\\n" #~ "        params configfile=\"/etc/httpd/conf/httpd.conf\" \\\n" #~ "        op monitor interval=\"1min\"\n" #~ "primitive ClusterIP ocf:heartbeat:IPaddr2 \\\n" #~ "        params ip=”192.168.122.101” cidr_netmask=”32” clusterip_hash=”sourceip” \\\n" #~ "        op monitor interval=\"30s\"\n" #~ "primitive dlm ocf:pacemaker:controld \\\n" #~ "        op monitor interval=\"120s\"\n" #~ "primitive gfs-control ocf:pacemaker:controld \\\n" #~ "   params daemon=”gfs_controld.pcmk” args=”-g 0” \\\n" #~ "        op monitor interval=\"120s\"\n" #~ "primitive rsa-fencing stonith::external/ibmrsa \\\n" #~ " params hostname=”pcmk-1 pcmk-2\" ipaddr=192.168.122.31 userid=mgmt passwd=abc123 type=ibm \\\n" #~ " op monitor interval=\"60s\"\n" #~ "ms WebDataClone WebData \\\n" #~ "        meta master-max=\"2\" master-node-max=\"1\" clone-max=\"2\" clone-node-max=\"1\" notify=\"true\"\n" #~ "clone Fencing rsa-fencing \n" #~ "clone WebFSClone WebFS\n" #~ "clone WebIP ClusterIP  \\\n" #~ "        meta globally-unique=”true” clone-max=”2” clone-node-max=”2”\n" #~ "clone WebSiteClone WebSite\n" #~ "clone dlm-clone dlm \\\n" #~ "        meta interleave=\"true\"\n" #~ "clone gfs-clone gfs-control \\\n" #~ "        meta interleave=\"true\"\n" #~ "colocation WebFS-with-gfs-control inf: WebFSClone gfs-clone\n" #~ "colocation WebSite-with-WebFS inf: WebSiteClone WebFSClone\n" #~ "colocation fs_on_drbd inf: WebFSClone WebDataClone:Master\n" #~ "colocation gfs-with-dlm inf: gfs-clone dlm-clone\n" #~ "colocation website-with-ip inf: WebSiteClone WebIP\n" #~ "order WebFS-after-WebData inf: WebDataClone:promote WebFSClone:start\n" #~ "order WebSite-after-WebFS inf: WebFSClone WebSiteClone\n" #~ "order apache-after-ip inf: WebIP WebSiteClone\n" #~ "order start-WebFS-after-gfs-control inf: gfs-clone WebFSClone\n" #~ "order start-gfs-after-dlm inf: dlm-clone gfs-clone\n" #~ "property $id=\"cib-bootstrap-options\" \\\n" #~ "        dc-version=\"1.0.5-462f1569a43740667daf7b0f6b521742e9eb8fa7\" \\\n" #~ "        cluster-infrastructure=\"openais\" \\\n" #~ "        expected-quorum-votes=”2” \\\n" #~ "        stonith-enabled=\"true\" \\\n" #~ "        no-quorum-policy=\"ignore\"\n" #~ "rsc_defaults $id=\"rsc-options\" \\\n" #~ "        resource-stickiness=”100”\n" #~ msgstr "" #~ "\n" #~ "crm(stonith)# configure property stonith-enabled=\"true\"\n" #~ "crm(stonith)# configure show\n" #~ "node pcmk-1\n" #~ "node pcmk-2\n" #~ "primitive WebData ocf:linbit:drbd \\\n" #~ "        params drbd_resource=\"wwwdata\" \\\n" #~ "        op monitor interval=\"60s\"\n" #~ "primitive WebFS ocf:heartbeat:Filesystem \\\n" #~ "        params device=\"/dev/drbd/by-res/wwwdata\" directory=\"/var/www/html\" fstype=”gfs2”\n" #~ "primitive WebSite ocf:heartbeat:apache \\\n" #~ "        params configfile=\"/etc/httpd/conf/httpd.conf\" \\\n" #~ "        op monitor interval=\"1min\"\n" #~ "primitive ClusterIP ocf:heartbeat:IPaddr2 \\\n" #~ "        params ip=”192.168.122.101” cidr_netmask=”32” clusterip_hash=”sourceip” \\\n" #~ "        op monitor interval=\"30s\"\n" #~ "primitive dlm ocf:pacemaker:controld \\\n" #~ "        op monitor interval=\"120s\"\n" #~ "primitive gfs-control ocf:pacemaker:controld \\\n" #~ "   params daemon=”gfs_controld.pcmk” args=”-g 0” \\\n" #~ "        op monitor interval=\"120s\"\n" #~ "primitive rsa-fencing stonith::external/ibmrsa \\\n" #~ " params hostname=”pcmk-1 pcmk-2\" ipaddr=192.168.122.31 userid=mgmt passwd=abc123 type=ibm \\\n" #~ " op monitor interval=\"60s\"\n" #~ "ms WebDataClone WebData \\\n" #~ "        meta master-max=\"2\" master-node-max=\"1\" clone-max=\"2\" clone-node-max=\"1\" notify=\"true\"\n" #~ "clone Fencing rsa-fencing \n" #~ "clone WebFSClone WebFS\n" #~ "clone WebIP ClusterIP  \\\n" #~ "        meta globally-unique=”true” clone-max=”2” clone-node-max=”2”\n" #~ "clone WebSiteClone WebSite\n" #~ "clone dlm-clone dlm \\\n" #~ "        meta interleave=\"true\"\n" #~ "clone gfs-clone gfs-control \\\n" #~ "        meta interleave=\"true\"\n" #~ "colocation WebFS-with-gfs-control inf: WebFSClone gfs-clone\n" #~ "colocation WebSite-with-WebFS inf: WebSiteClone WebFSClone\n" #~ "colocation fs_on_drbd inf: WebFSClone WebDataClone:Master\n" #~ "colocation gfs-with-dlm inf: gfs-clone dlm-clone\n" #~ "colocation website-with-ip inf: WebSiteClone WebIP\n" #~ "order WebFS-after-WebData inf: WebDataClone:promote WebFSClone:start\n" #~ "order WebSite-after-WebFS inf: WebFSClone WebSiteClone\n" #~ "order apache-after-ip inf: WebIP WebSiteClone\n" #~ "order start-WebFS-after-gfs-control inf: gfs-clone WebFSClone\n" #~ "order start-gfs-after-dlm inf: dlm-clone gfs-clone\n" #~ "property $id=\"cib-bootstrap-options\" \\\n" #~ "        dc-version=\"1.0.5-462f1569a43740667daf7b0f6b521742e9eb8fa7\" \\\n" #~ "        cluster-infrastructure=\"openais\" \\\n" #~ "        expected-quorum-votes=”2” \\\n" #~ "        stonith-enabled=\"true\" \\\n" #~ "        no-quorum-policy=\"ignore\"\n" #~ "rsc_defaults $id=\"rsc-options\" \\\n" #~ "        resource-stickiness=”100”\n" pacemaker-master/doc/Clusters_from_Scratch/zh-CN/Ch-Tools.mo000066400000000000000000000250211217637305600242600ustar00rootroot00000000000000 l , |/ ;~v, d%A&&'3}(I()   [root@pcmk-1 ~]# crm --help usage:     crm [-D display_type]     crm [-D display_type] args     crm [-D display_type] [-f file]     Use crm without arguments for an interactive session.     Supply one or more arguments for a "single-shot" use.     Specify with -f a file which contains a script. Use '-' for     standard input or use pipe/redirection.     crm displays cli format configurations using a color scheme     and/or in uppercase. Pick one of "color" or "uppercase", or     use "-D color,uppercase" if you want colorful uppercase.     Get plain output by "-D plain". The default may be set in     user preferences (options). Examples:     # crm -f stopapp2.cli     # crm < stopapp2.cli     # crm resource stop global_www     # crm status [root@pcmk-1 ~]# crm_mon --version crm_mon 1.0.5 for OpenAIS and Heartbeat (Build: 462f1569a43740667daf7b0f6b521742e9eb8fa7) Written by Andrew Beekhof [root@pcmk-1 ~]# crm_mon --help crm_mon - Provides a summary of cluster's current state. Outputs varying levels of detail in a number of different formats. Usage: crm_mon mode [options] Options:  -?, --help                 This text  -$, --version             Version information  -V, --verbose             Increase debug output Modes:  -h, --as-html=value        Write cluster status to the named file  -w, --web-cgi             Web mode with output suitable for cgi  -s, --simple-status       Display the cluster status once as a simple one line output (suitable for nagios)  -S, --snmp-traps=value    Send SNMP traps to this station  -T, --mail-to=value        Send Mail alerts to this user.  See also --mail-from, --mail-host, --mail-prefix Display Options:  -n, --group-by-node       Group resources by node  -r, --inactive             Display inactive resources  -f, --failcounts           Display resource fail counts  -o, --operations           Display resource operation history  -t, --timing-details       Display resource operation history with timing details Additional Options:  -i, --interval=value           Update frequency in seconds  -1, --one-shot                 Display the cluster status once on the console and exit  -N, --disable-ncurses          Disable the use of ncurses  -d, --daemonize                Run in the background as a daemon  -p, --pid-file=value           (Advanced) Daemon pid file location  -F, --mail-from=value          Mail alerts should come from the named user  -H, --mail-host=value          Mail alerts should be sent via the named host  -P, --mail-prefix=value        Subjects for mail alerts should start with this string  -E, --external-agent=value     A program to run when resource operations take place.  -e, --external-recipient=value A recipient for your program (assuming you want the program to send something to someone). Examples: Display the cluster´s status on the console with updates as they occur:         # crm_mon Display the cluster´s status on the console just once then exit:         # crm_mon Display your cluster´s status, group resources by node, and include inactive resources in the list:         # crm_mon --group-by-node --inactive Start crm_mon as a background daemon and have it write the cluster´s status to an HTML file:         # crm_mon --daemonize --as-html /path/to/docroot/filename.html Start crm_mon as a background daemon and have it send email alerts:         # crm_mon --daemonize --mail-to user@example.com --mail-host mail.example.com Start crm_mon as a background daemon and have it send SNMP alerts:         # crm_mon --daemonize --snmp-traps snmptrapd.example.com Report bugs to pacemaker@oss.clusterlabs.org Additionally, the Pacemaker version and supported cluster stack(s) is available via the --version option.If the SNMP and/or email options are not listed, then Pacemaker was not built to support them. This may be by the choice of your distribution or the required libraries may not have been available. Please contact whoever supplied you with the packages for more details.In the dark past, configuring Pacemaker required the administrator to read and write XML. In true UNIX style, there were also a number of different commands that specialized in different aspects of querying and updating the cluster.Since Pacemaker 1.0, this has all changed and we have an integrated, scriptable, cluster shell that hides all the messy XML scaffolding. It even allows you to queue up several changes at once and commit them atomically.Take some time to familiarize yourself with what it can do.The primary tool for monitoring the status of the cluster is crm_mon (also available as crm status). It can be run in a variety of modes and has a number of output options. To find out about any of the tools that come with Pacemaker, simply invoke them with the --help option or consult the included man pages. Both sets of output are created from the tool, and so will always be in sync with each other and the tool itself.Using Pacemaker ToolsProject-Id-Version: 0 POT-Creation-Date: 2010-12-15T23:32:37 PO-Revision-Date: 2010-12-15 23:43+0800 Last-Translator: Charlie Chen Language-Team: None Language: MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [root@pcmk-1 ~]# crm --help usage:     crm [-D display_type]     crm [-D display_type] args     crm [-D display_type] [-f file]     Use crm without arguments for an interactive session.     Supply one or more arguments for a "single-shot" use.     Specify with -f a file which contains a script. Use '-' for     standard input or use pipe/redirection.     crm displays cli format configurations using a color scheme     and/or in uppercase. Pick one of "color" or "uppercase", or     use "-D color,uppercase" if you want colorful uppercase.     Get plain output by "-D plain". The default may be set in     user preferences (options). Examples:     # crm -f stopapp2.cli     # crm < stopapp2.cli     # crm resource stop global_www     # crm status [root@pcmk-1 ~]# crm_mon --version crm_mon 1.0.5 for OpenAIS and Heartbeat (Build: 462f1569a43740667daf7b0f6b521742e9eb8fa7) Written by Andrew Beekhof [root@pcmk-1 ~]# crm_mon --help crm_mon - Provides a summary of cluster's current state. Outputs varying levels of detail in a number of different formats. Usage: crm_mon mode [options] Options:  -?, --help                 This text  -$, --version             Version information  -V, --verbose             Increase debug output Modes:  -h, --as-html=value        Write cluster status to the named file  -w, --web-cgi             Web mode with output suitable for cgi  -s, --simple-status       Display the cluster status once as a simple one line output (suitable for nagios)  -S, --snmp-traps=value    Send SNMP traps to this station  -T, --mail-to=value        Send Mail alerts to this user.  See also --mail-from, --mail-host, --mail-prefix Display Options:  -n, --group-by-node       Group resources by node  -r, --inactive             Display inactive resources  -f, --failcounts           Display resource fail counts  -o, --operations           Display resource operation history  -t, --timing-details       Display resource operation history with timing details Additional Options:  -i, --interval=value           Update frequency in seconds  -1, --one-shot                 Display the cluster status once on the console and exit  -N, --disable-ncurses          Disable the use of ncurses  -d, --daemonize                Run in the background as a daemon  -p, --pid-file=value           (Advanced) Daemon pid file location  -F, --mail-from=value          Mail alerts should come from the named user  -H, --mail-host=value          Mail alerts should be sent via the named host  -P, --mail-prefix=value        Subjects for mail alerts should start with this string  -E, --external-agent=value     A program to run when resource operations take place.  -e, --external-recipient=value A recipient for your program (assuming you want the program to send something to someone). Examples: Display the cluster´s status on the console with updates as they occur:         # crm_mon Display the cluster´s status on the console just once then exit:         # crm_mon Display your cluster´s status, group resources by node, and include inactive resources in the list:         # crm_mon --group-by-node --inactive Start crm_mon as a background daemon and have it write the cluster´s status to an HTML file:         # crm_mon --daemonize --as-html /path/to/docroot/filename.html Start crm_mon as a background daemon and have it send email alerts:         # crm_mon --daemonize --mail-to user@example.com --mail-host mail.example.com Start crm_mon as a background daemon and have it send SNMP alerts:         # crm_mon --daemonize --snmp-traps snmptrapd.example.com Report bugs to pacemaker@oss.clusterlabs.org 此外,Pacemaker的版本和支持的stack(本文中是corosync)可以通过 --version选项看到如果SNMP或者email选项没有出现在选项中,说明pacemaker编译的时候没有打开对他们的支持,你需要联系提供这个发行版本的人,或者自己编译。在万恶的旧社会,配置Pacemaker需要管理员具备读写XML的能力。 根据UNIX精神,也有许多不同的查询和配置集群的命令。自从Pacemaker 1.0,这一切都改变了,我们有了一个集成的脚本化的集群控制shell,它把麻烦的XML配置隐藏了起来。它甚至允许你一次做出许多修改并自动提交(并检测是否合法)。让我们花点时间熟悉一下它能做什么。监控集群状态的主要命令是 crm_mon(跟crm status是一样的效果)。它可以运行在很多模式下并且有许多输出选项。如果要查看Pacemaker相应的工具,可以通过--help或者man pages来查看。这些输出都是靠命令来生成的,所以它总是会在各个节点和工具之间同步。使用Pacemaker工具pacemaker-master/doc/Clusters_from_Scratch/zh-CN/Ch-Tools.po000066400000000000000000000373451217637305600242770ustar00rootroot00000000000000# # AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: 0\n" "POT-Creation-Date: 2012-10-17T05:19:03\n" "PO-Revision-Date: 2010-12-15 23:43+0800\n" "Last-Translator: Charlie Chen \n" "Language-Team: None\n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. Tag: title #, fuzzy, no-c-format msgid "Pacemaker Tools" msgstr "使用Pacemaker工具" #. Tag: title #, no-c-format msgid "Using Pacemaker Tools" msgstr "使用Pacemaker工具" #. Tag: para #, no-c-format msgid "In the dark past, configuring Pacemaker required the administrator to read and write XML. In true UNIX style, there were also a number of different commands that specialized in different aspects of querying and updating the cluster." msgstr "在万恶的旧社会,配置Pacemaker需要管理员具备读写XML的能力。 根据UNIX精神,也有许多不同的查询和配置集群的命令。" #. Tag: para #, no-c-format msgid "All of that has been greatly simplified with the creation of unified command-line shells (and GUIs) that hide all the messy XML scaffolding." msgstr "" #. Tag: para #, no-c-format msgid "These shells take all the individual aspects required for managing and configuring a cluster, and packs them into one simple to use command line tool." msgstr "" #. Tag: para #, no-c-format msgid "They even allow you to queue up several changes at once and commit them atomically." msgstr "" #. Tag: para #, no-c-format msgid "There are currently two command-line shells that people use, pcs and crmsh. This edition of Clusters from Scratch is based on pcs. Start by taking some time to familiarize yourself with what it can do." msgstr "" #. Tag: para #, no-c-format msgid "The two shells share many concepts but the scope, layout and syntax does differ, so make sure you read the version of this guide that corresponds to the software installed on your system." msgstr "" #. Tag: para #, no-c-format msgid "Since pcs has the ability to manage all aspects of the cluster (both corosync and pacemaker), it requires a specific cluster stack to be in use, (corosync 2.0 with votequorum + Pacemaker version >= 1.8)." msgstr "" #. Tag: programlisting #, no-c-format msgid "# pcs" msgstr "" #. Tag: literallayout #, no-c-format msgid "" "Control and configure pacemaker and corosync.\n" "\n" "Options:\n" " -h Display usage and exit\n" " -f file Perform actions on file instead of active CIB\n" "\n" "Commands:\n" " resource Manage cluster resources\n" " cluster Configure cluster options and nodes\n" " stonith Configure fence devices\n" " property Set pacemaker properties\n" " constraint Set resource constraints\n" " status View cluster status" msgstr "" #. Tag: para #, no-c-format msgid "As you can see, the different aspects of cluster management are broken up into categories: resource, cluster, stonith, property, constraint, and status. To discover the functionality available in each of these categories, one can issue the command pcs <category> help. Below is an example of all the options available under the status category." msgstr "" #. Tag: programlisting #, no-c-format msgid "# pcs status help" msgstr "" #. Tag: literallayout #, no-c-format msgid "" "Usage: pcs status [commands]...\n" "View current cluster and resource status\n" "Commands:\n" " status\n" " View all information about the cluster and resources\n" "\n" " status resources\n" " View current status of cluster resources\n" "\n" " status groups\n" " View currently configured groups and their resources\n" "\n" " status cluster\n" " View current cluster status\n" "\n" " status corosync\n" " View current corosync status\n" "\n" " status nodes [corosync]\n" " View current status of nodes from pacemaker, or if corosync is\n" " specified, print nodes currently configured in corosync\n" "\n" " status actions\n" " View failed actions\n" "\n" " status pcsd <node> ...\n" " Show the current status of pcsd on the specified nodes\n" "\n" " status xml\n" " View xml version of status (output from crm_mon -r -1 -X)" msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "Additionally, if you are interested in the Pacemaker version and supported cluster stack(s) available with your current Pacemaker installation, the pacemakerd --features option is available to you." msgstr "此外,Pacemaker的版本和支持的stack(本文中是corosync)可以通过 --version选项看到" #. Tag: programlisting #, no-c-format msgid "# pacemakerd --features" msgstr "" #. Tag: screen #, no-c-format msgid "" "Pacemaker 1.1.8 (Build: 434edfa)\n" " Supporting: generated-manpages agent-manpages ascii-docs publican-docs ncurses gcov libqb-logging libqb-ipc lha-fencing upstart systemd heartbeat corosync-native snmp" msgstr "" #. Tag: para #, no-c-format msgid "If the SNMP and/or email options are not listed, then Pacemaker was not built to support them. This may be by the choice of your distribution or the required libraries may not have been available. Please contact whoever supplied you with the packages for more details." msgstr "如果SNMP或者email选项没有出现在选项中,说明pacemaker编译的时候没有打开对他们的支持,你需要联系提供这个发行版本的人,或者自己编译。" #~ msgid "Since Pacemaker 1.0, this has all changed and we have an integrated, scriptable, cluster shell that hides all the messy XML scaffolding. It even allows you to queue up several changes at once and commit them atomically." #~ msgstr "自从Pacemaker 1.0,这一切都改变了,我们有了一个集成的脚本化的集群控制shell,它把麻烦的XML配置隐藏了起来。它甚至允许你一次做出许多修改并自动提交(并检测是否合法)。" #~ msgid "Take some time to familiarize yourself with what it can do." #~ msgstr "让我们花点时间熟悉一下它能做什么。" #~ msgid "" #~ "\n" #~ "[root@pcmk-1 ~]# crm --help\n" #~ "\n" #~ "usage:\n" #~ "    crm [-D display_type]\n" #~ "    crm [-D display_type] args\n" #~ "    crm [-D display_type] [-f file]\n" #~ "\n" #~ "    Use crm without arguments for an interactive session.\n" #~ "    Supply one or more arguments for a \"single-shot\" use.\n" #~ "    Specify with -f a file which contains a script. Use '-' for\n" #~ "    standard input or use pipe/redirection.\n" #~ "\n" #~ "    crm displays cli format configurations using a color scheme\n" #~ "    and/or in uppercase. Pick one of \"color\" or \"uppercase\", or\n" #~ "    use \"-D color,uppercase\" if you want colorful uppercase.\n" #~ "    Get plain output by \"-D plain\". The default may be set in\n" #~ "    user preferences (options).\n" #~ "\n" #~ "Examples:\n" #~ "\n" #~ "    # crm -f stopapp2.cli\n" #~ "    # crm < stopapp2.cli\n" #~ "    # crm resource stop global_www\n" #~ "    # crm status\n" #~ msgstr "" #~ "\n" #~ "[root@pcmk-1 ~]# crm --help\n" #~ "\n" #~ "usage:\n" #~ "    crm [-D display_type]\n" #~ "    crm [-D display_type] args\n" #~ "    crm [-D display_type] [-f file]\n" #~ "\n" #~ "    Use crm without arguments for an interactive session.\n" #~ "    Supply one or more arguments for a \"single-shot\" use.\n" #~ "    Specify with -f a file which contains a script. Use '-' for\n" #~ "    standard input or use pipe/redirection.\n" #~ "\n" #~ "    crm displays cli format configurations using a color scheme\n" #~ "    and/or in uppercase. Pick one of \"color\" or \"uppercase\", or\n" #~ "    use \"-D color,uppercase\" if you want colorful uppercase.\n" #~ "    Get plain output by \"-D plain\". The default may be set in\n" #~ "    user preferences (options).\n" #~ "\n" #~ "Examples:\n" #~ "\n" #~ "    # crm -f stopapp2.cli\n" #~ "    # crm < stopapp2.cli\n" #~ "    # crm resource stop global_www\n" #~ "    # crm status\n" #~ msgid "The primary tool for monitoring the status of the cluster is crm_mon (also available as crm status). It can be run in a variety of modes and has a number of output options. To find out about any of the tools that come with Pacemaker, simply invoke them with the --help option or consult the included man pages. Both sets of output are created from the tool, and so will always be in sync with each other and the tool itself." #~ msgstr "监控集群状态的主要命令是 crm_mon(跟crm status是一样的效果)。它可以运行在很多模式下并且有许多输出选项。如果要查看Pacemaker相应的工具,可以通过--help或者man pages来查看。这些输出都是靠命令来生成的,所以它总是会在各个节点和工具之间同步。" #~ msgid "" #~ "\n" #~ "[root@pcmk-1 ~]# crm_mon --version\n" #~ "crm_mon 1.0.5 for OpenAIS and Heartbeat (Build: 462f1569a43740667daf7b0f6b521742e9eb8fa7)\n" #~ "\n" #~ "Written by Andrew Beekhof\n" #~ "[root@pcmk-1 ~]# crm_mon --help\n" #~ "crm_mon - Provides a summary of cluster's current state.\n" #~ "\n" #~ "Outputs varying levels of detail in a number of different formats.\n" #~ "\n" #~ "Usage: crm_mon mode [options]\n" #~ "Options:\n" #~ " -?, --help                 This text\n" #~ " -$, --version             Version information\n" #~ " -V, --verbose             Increase debug output\n" #~ "\n" #~ "Modes:\n" #~ " -h, --as-html=value        Write cluster status to the named file\n" #~ " -w, --web-cgi             Web mode with output suitable for cgi\n" #~ " -s, --simple-status       Display the cluster status once as a simple one line output (suitable for nagios)\n" #~ " -S, --snmp-traps=value    Send SNMP traps to this station\n" #~ " -T, --mail-to=value        Send Mail alerts to this user.  See also --mail-from, --mail-host, --mail-prefix\n" #~ "\n" #~ "Display Options:\n" #~ " -n, --group-by-node       Group resources by node\n" #~ " -r, --inactive             Display inactive resources\n" #~ " -f, --failcounts           Display resource fail counts\n" #~ " -o, --operations           Display resource operation history\n" #~ " -t, --timing-details       Display resource operation history with timing details\n" #~ "\n" #~ "\n" #~ "Additional Options:\n" #~ " -i, --interval=value           Update frequency in seconds\n" #~ " -1, --one-shot                 Display the cluster status once on the console and exit\n" #~ " -N, --disable-ncurses          Disable the use of ncurses\n" #~ " -d, --daemonize                Run in the background as a daemon\n" #~ " -p, --pid-file=value           (Advanced) Daemon pid file location\n" #~ " -F, --mail-from=value          Mail alerts should come from the named user\n" #~ " -H, --mail-host=value          Mail alerts should be sent via the named host\n" #~ " -P, --mail-prefix=value        Subjects for mail alerts should start with this string\n" #~ " -E, --external-agent=value     A program to run when resource operations take place.\n" #~ " -e, --external-recipient=value A recipient for your program (assuming you want the program to send something to someone).\n" #~ "\n" #~ "Examples:\n" #~ "\n" #~ "Display the cluster´s status on the console with updates as they occur:\n" #~ "        # crm_mon\n" #~ "\n" #~ "Display the cluster´s status on the console just once then exit:\n" #~ "        # crm_mon\n" #~ "\n" #~ "Display your cluster´s status, group resources by node, and include inactive resources in the list:\n" #~ "        # crm_mon --group-by-node --inactive\n" #~ "\n" #~ "Start crm_mon as a background daemon and have it write the cluster´s status to an HTML file:\n" #~ "        # crm_mon --daemonize --as-html /path/to/docroot/filename.html\n" #~ "\n" #~ "Start crm_mon as a background daemon and have it send email alerts:\n" #~ "        # crm_mon --daemonize --mail-to user@example.com --mail-host mail.example.com\n" #~ "\n" #~ "Start crm_mon as a background daemon and have it send SNMP alerts:\n" #~ "        # crm_mon --daemonize --snmp-traps snmptrapd.example.com\n" #~ "\n" #~ "Report bugs to pacemaker@oss.clusterlabs.org\n" #~ msgstr "" #~ "\n" #~ "[root@pcmk-1 ~]# crm_mon --version\n" #~ "crm_mon 1.0.5 for OpenAIS and Heartbeat (Build: 462f1569a43740667daf7b0f6b521742e9eb8fa7)\n" #~ "\n" #~ "Written by Andrew Beekhof\n" #~ "[root@pcmk-1 ~]# crm_mon --help\n" #~ "crm_mon - Provides a summary of cluster's current state.\n" #~ "\n" #~ "Outputs varying levels of detail in a number of different formats.\n" #~ "\n" #~ "Usage: crm_mon mode [options]\n" #~ "Options:\n" #~ " -?, --help                 This text\n" #~ " -$, --version             Version information\n" #~ " -V, --verbose             Increase debug output\n" #~ "\n" #~ "Modes:\n" #~ " -h, --as-html=value        Write cluster status to the named file\n" #~ " -w, --web-cgi             Web mode with output suitable for cgi\n" #~ " -s, --simple-status       Display the cluster status once as a simple one line output (suitable for nagios)\n" #~ " -S, --snmp-traps=value    Send SNMP traps to this station\n" #~ " -T, --mail-to=value        Send Mail alerts to this user.  See also --mail-from, --mail-host, --mail-prefix\n" #~ "\n" #~ "Display Options:\n" #~ " -n, --group-by-node       Group resources by node\n" #~ " -r, --inactive             Display inactive resources\n" #~ " -f, --failcounts           Display resource fail counts\n" #~ " -o, --operations           Display resource operation history\n" #~ " -t, --timing-details       Display resource operation history with timing details\n" #~ "\n" #~ "\n" #~ "Additional Options:\n" #~ " -i, --interval=value           Update frequency in seconds\n" #~ " -1, --one-shot                 Display the cluster status once on the console and exit\n" #~ " -N, --disable-ncurses          Disable the use of ncurses\n" #~ " -d, --daemonize                Run in the background as a daemon\n" #~ " -p, --pid-file=value           (Advanced) Daemon pid file location\n" #~ " -F, --mail-from=value          Mail alerts should come from the named user\n" #~ " -H, --mail-host=value          Mail alerts should be sent via the named host\n" #~ " -P, --mail-prefix=value        Subjects for mail alerts should start with this string\n" #~ " -E, --external-agent=value     A program to run when resource operations take place.\n" #~ " -e, --external-recipient=value A recipient for your program (assuming you want the program to send something to someone).\n" #~ "\n" #~ "Examples:\n" #~ "\n" #~ "Display the cluster´s status on the console with updates as they occur:\n" #~ "        # crm_mon\n" #~ "\n" #~ "Display the cluster´s status on the console just once then exit:\n" #~ "        # crm_mon\n" #~ "\n" #~ "Display your cluster´s status, group resources by node, and include inactive resources in the list:\n" #~ "        # crm_mon --group-by-node --inactive\n" #~ "\n" #~ "Start crm_mon as a background daemon and have it write the cluster´s status to an HTML file:\n" #~ "        # crm_mon --daemonize --as-html /path/to/docroot/filename.html\n" #~ "\n" #~ "Start crm_mon as a background daemon and have it send email alerts:\n" #~ "        # crm_mon --daemonize --mail-to user@example.com --mail-host mail.example.com\n" #~ "\n" #~ "Start crm_mon as a background daemon and have it send SNMP alerts:\n" #~ "        # crm_mon --daemonize --snmp-traps snmptrapd.example.com\n" #~ "\n" #~ "Report bugs to pacemaker@oss.clusterlabs.org\n" pacemaker-master/doc/Clusters_from_Scratch/zh-CN/Ch-Verification.mo000066400000000000000000000233021217637305600256020ustar00rootroot00000000000000<?e  or"SZY4  &CTaVe3 #{$(%Q.%Z%1%! &/&E&]&Kv&    [root@pcmk-1 ~]# /etc/init.d/corosync start Starting Corosync Cluster Engine (corosync): [ OK ] [root@pcmk-1 ~]# grep -e "corosync.*network interface" -e "Corosync Cluster Engine" -e "Successfully read main configuration file" /var/log/messages Aug 27 09:05:34 pcmk-1 corosync[1540]: [MAIN  ] Corosync Cluster Engine ('1.1.0'): started and ready to provide service. Aug 27 09:05:34 pcmk-1 corosync[1540]: [MAIN  ] Successfully read main configuration file '/etc/corosync/corosync.conf'. [root@pcmk-1 ~]# grep TOTEM /var/log/messages Aug 27 09:05:34 pcmk-1 corosync[1540]: [TOTEM ] Initializing transport (UDP/IP). Aug 27 09:05:34 pcmk-1 corosync[1540]: [TOTEM ] Initializing transmit/receive security: libtomcrypt SOBER128/SHA1HMAC (mode 0). Aug 27 09:05:35 pcmk-1 corosync[1540]: [TOTEM ] The network interface [192.168.122.101] is now up. Aug 27 09:05:35 pcmk-1 corosync[1540]: [TOTEM ] A processor joined or left the membership and a new membership was formed. [root@pcmk-1 ~]# grep ERROR: /var/log/messages | grep -v unpack_resources [root@pcmk-1 ~]# crm_mon ============ Last updated: Thu Aug 27 16:54:55 2009 Stack: openais Current DC: pcmk-1 - partition with quorum Version: 1.0.5-462f1569a43740667daf7b0f6b521742e9eb8fa7 2 Nodes configured, 2 expected votes 0 Resources configured. ============ Online: [ pcmk-1 pcmk-2 ] [root@pcmk-1 ~]# grep TOTEM /var/log/messages Aug 27 09:05:34 pcmk-1 corosync[1540]: [TOTEM ] Initializing transport (UDP/IP). Aug 27 09:05:34 pcmk-1 corosync[1540]: [TOTEM ] Initializing transmit/receive security: libtomcrypt SOBER128/SHA1HMAC (mode 0). Aug 27 09:05:35 pcmk-1 corosync[1540]: [TOTEM ] The network interface [192.168.122.101] is now up. Aug 27 09:05:35 pcmk-1 corosync[1540]: [TOTEM ] A processor joined or left the membership and a new membership was formed. Aug 27 09:12:11 pcmk-1 corosync[1540]: [TOTEM ] A processor joined or left the membership and a new membership was formed. [root@pcmk-1 ~]# grep pcmk_startup /var/log/messages Aug 27 09:05:35 pcmk-1 corosync[1540]:   [pcmk  ] info: pcmk_startup: CRM: Initialized Aug 27 09:05:35 pcmk-1 corosync[1540]:   [pcmk  ] Logging: Initialized pcmk_startup Aug 27 09:05:35 pcmk-1 corosync[1540]:   [pcmk  ] info: pcmk_startup: Maximum core file size is: 18446744073709551615 Aug 27 09:05:35 pcmk-1 corosync[1540]:   [pcmk  ] info: pcmk_startup: Service: 9 Aug 27 09:05:35 pcmk-1 corosync[1540]:   [pcmk  ] info: pcmk_startup: Local hostname: pcmk-1 [root@pcmk-1 ~]# ps axf   PID TTY      STAT   TIME COMMAND     2 ?        S<     0:00 [kthreadd]     3 ?        S<     0:00  \_ [migration/0] ... lots of processes ...  2166 pts/0    SLl    0:01 /usr/sbin/corosync  2172 ?        SLs    0:00  \_ /usr/lib64/heartbeat/stonithd  2173 pts/0    S      0:00  \_ /usr/lib64/heartbeat/cib  2174 pts/0    S      0:00  \_ /usr/lib64/heartbeat/lrmd  2175 pts/0    S      0:00  \_ /usr/lib64/heartbeat/attrd  2176 pts/0    S      0:00  \_ /usr/lib64/heartbeat/pengine  2177 pts/0    S      0:00  \_ /usr/lib64/heartbeat/crmd [root@pcmk-1 ~]# ssh pcmk-2 -- /etc/init.d/corosync start Starting Corosync Cluster Engine (corosync): [ OK ] [root@pcmk-1 ~]# And finally, check for any ERRORs during startup, there shouldn’t be any, and display the cluster’s status.Check the cluster formed correctlyCheck the cluster started correctly and that an initial membership was able to formNow that we have confirmed that Corosync is functional we can check the rest of the stack.Now verify the Pacemaker processes have been startedStart Corosync on the first nodeVerify Cluster InstallationVerify Corosync InstallationVerify Pacemaker InstallationWith one node functional, its now safe to start Corosync on the second node as well.Project-Id-Version: 0 POT-Creation-Date: 2010-12-15T23:32:37 PO-Revision-Date: 2010-12-16 00:39+0800 Last-Translator: Charlie Chen Language-Team: None Language: MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [root@pcmk-1 ~]# /etc/init.d/corosync start Starting Corosync Cluster Engine (corosync): [ OK ] [root@pcmk-1 ~]# grep -e "corosync.*network interface" -e "Corosync Cluster Engine" -e "Successfully read main configuration file" /var/log/messages Aug 27 09:05:34 pcmk-1 corosync[1540]: [MAIN  ] Corosync Cluster Engine ('1.1.0'): started and ready to provide service. Aug 27 09:05:34 pcmk-1 corosync[1540]: [MAIN  ] Successfully read main configuration file '/etc/corosync/corosync.conf'. [root@pcmk-1 ~]# grep TOTEM /var/log/messages Aug 27 09:05:34 pcmk-1 corosync[1540]: [TOTEM ] Initializing transport (UDP/IP). Aug 27 09:05:34 pcmk-1 corosync[1540]: [TOTEM ] Initializing transmit/receive security: libtomcrypt SOBER128/SHA1HMAC (mode 0). Aug 27 09:05:35 pcmk-1 corosync[1540]: [TOTEM ] The network interface [192.168.122.101] is now up. Aug 27 09:05:35 pcmk-1 corosync[1540]: [TOTEM ] A processor joined or left the membership and a new membership was formed. [root@pcmk-1 ~]# grep ERROR: /var/log/messages | grep -v unpack_resources [root@pcmk-1 ~]# crm_mon ============ Last updated: Thu Aug 27 16:54:55 2009 Stack: openais Current DC: pcmk-1 - partition with quorum Version: 1.0.5-462f1569a43740667daf7b0f6b521742e9eb8fa7 2 Nodes configured, 2 expected votes 0 Resources configured. ============ Online: [ pcmk-1 pcmk-2 ] [root@pcmk-1 ~]# grep TOTEM /var/log/messages Aug 27 09:05:34 pcmk-1 corosync[1540]: [TOTEM ] Initializing transport (UDP/IP). Aug 27 09:05:34 pcmk-1 corosync[1540]: [TOTEM ] Initializing transmit/receive security: libtomcrypt SOBER128/SHA1HMAC (mode 0). Aug 27 09:05:35 pcmk-1 corosync[1540]: [TOTEM ] The network interface [192.168.122.101] is now up. Aug 27 09:05:35 pcmk-1 corosync[1540]: [TOTEM ] A processor joined or left the membership and a new membership was formed. Aug 27 09:12:11 pcmk-1 corosync[1540]: [TOTEM ] A processor joined or left the membership and a new membership was formed. [root@pcmk-1 ~]# grep pcmk_startup /var/log/messages Aug 27 09:05:35 pcmk-1 corosync[1540]:   [pcmk  ] info: pcmk_startup: CRM: Initialized Aug 27 09:05:35 pcmk-1 corosync[1540]:   [pcmk  ] Logging: Initialized pcmk_startup Aug 27 09:05:35 pcmk-1 corosync[1540]:   [pcmk  ] info: pcmk_startup: Maximum core file size is: 18446744073709551615 Aug 27 09:05:35 pcmk-1 corosync[1540]:   [pcmk  ] info: pcmk_startup: Service: 9 Aug 27 09:05:35 pcmk-1 corosync[1540]:   [pcmk  ] info: pcmk_startup: Local hostname: pcmk-1 [root@pcmk-1 ~]# ps axf   PID TTY      STAT   TIME COMMAND     2 ?        S<     0:00 [kthreadd]     3 ?        S<     0:00  \_ [migration/0] ... lots of processes ...  2166 pts/0    SLl    0:01 /usr/sbin/corosync  2172 ?        SLs    0:00  \_ /usr/lib64/heartbeat/stonithd  2173 pts/0    S      0:00  \_ /usr/lib64/heartbeat/cib  2174 pts/0    S      0:00  \_ /usr/lib64/heartbeat/lrmd  2175 pts/0    S      0:00  \_ /usr/lib64/heartbeat/attrd  2176 pts/0    S      0:00  \_ /usr/lib64/heartbeat/pengine  2177 pts/0    S      0:00  \_ /usr/lib64/heartbeat/crmd [root@pcmk-1 ~]# ssh pcmk-2 -- /etc/init.d/corosync start Starting Corosync Cluster Engine (corosync): [ OK ] [root@pcmk-1 ~]# 最后我们检查启动的过程中有没有错误,按照常理应该没有任何错误并显示集群当前的状态。检查集群关系有没有正确建立:查看集群是否正确启动并且已经可以与其他节点建立集群关系现在我们已经确认Corosync正常,我们可以开始检查其他部分是否正常.现在确认pacemaker进程是否正常启动了:在第一个节点启动Corosync:检验集群的安装检验Corosync的安装检查Pacemaker的安装第一个节点正常以后,我们可以安全地启动第二个节点。pacemaker-master/doc/Clusters_from_Scratch/zh-CN/Ch-Verification.po000066400000000000000000000356571217637305600256250ustar00rootroot00000000000000# # AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: 0\n" "POT-Creation-Date: 2012-10-17T05:19:03\n" "PO-Revision-Date: 2010-12-16 00:39+0800\n" "Last-Translator: Charlie Chen \n" "Language-Team: None\n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. Tag: title #, no-c-format msgid "Verify Cluster Installation" msgstr "检验集群的安装" #. Tag: title #, no-c-format msgid "Start the Cluster" msgstr "" #. Tag: para #, no-c-format msgid "Now that corosync is configured, it is time to start the cluster. The command below will start corosync and pacemaker on both nodes in the cluster. If you are issuing the start command from a different node than the one you ran the pcs cluster auth command on earlier, you must authenticate on current node you are logged into before you will be allowed to start the cluster." msgstr "" #. Tag: programlisting #, no-c-format msgid "" "# pcs cluster start --all\n" "pcmk-1: Starting Cluster...\n" "pcmk-2: Starting Cluster..." msgstr "" #. Tag: para #, no-c-format msgid "An alternative to using the pcs cluster startall command is to issue either of the below commands on each node in the cluster by hand." msgstr "" #. Tag: programlisting #, no-c-format msgid "" "# pcs cluster start\n" "Starting Cluster..." msgstr "" #. Tag: para #, no-c-format msgid "or" msgstr "" #. Tag: programlisting #, no-c-format msgid "" "# systemctl start corosync.service\n" "# systemctl start pacemaker.service" msgstr "" #. Tag: title #, no-c-format msgid "Verify Corosync Installation" msgstr "检验Corosync的安装" #. Tag: para #, no-c-format msgid "The first thing to check is if cluster communication is happy, for that we use corosync-cfgtool." msgstr "" #. Tag: programlisting #, no-c-format msgid "" "# corosync-cfgtool -s\n" "Printing ring status.\n" "Local node ID 1\n" "RING ID 0\n" " id = 192.168.122.101\n" " status = ring 0 active with no faults" msgstr "" #. Tag: para #, no-c-format msgid "We can see here that everything appears normal with our fixed IP address, not a 127.0.0.x loopback address, listed as the id and no faults for the status." msgstr "" #. Tag: para #, no-c-format msgid "If you see something different, you might want to start by checking the node’s network, firewall and selinux configurations." msgstr "" #. Tag: para #, no-c-format msgid "Next we check the membership and quorum APIs:" msgstr "" #. Tag: programlisting #, no-c-format msgid "" "# corosync-cmapctl | grep members\n" "runtime.totem.pg.mrp.srp.members.1.ip (str) = r(0) ip(192.168.122.101)\n" "runtime.totem.pg.mrp.srp.members.1.join_count (u32) = 1\n" "runtime.totem.pg.mrp.srp.members.1.status (str) = joined\n" "runtime.totem.pg.mrp.srp.members.2.ip (str) = r(0) ip(192.168.122.102)\n" "runtime.totem.pg.mrp.srp.members.2.join_count (u32) = 1\n" "runtime.totem.pg.mrp.srp.members.2.status (str) = joined\n" "\n" "# pcs status corosync\n" "Membership information\n" " --------------------------\n" " Nodeid Votes Name\n" " 1 1 pcmk-1\n" " 2 1 pcmk-2" msgstr "" #. Tag: para #, no-c-format msgid "You should see both nodes have joined the cluster." msgstr "" #. Tag: para #, no-c-format msgid "All good!" msgstr "" #. Tag: title #, no-c-format msgid "Verify Pacemaker Installation" msgstr "检查Pacemaker的安装" #. Tag: para #, fuzzy, no-c-format msgid "Now that we have confirmed that Corosync is functional we can check the rest of the stack. Pacemaker has already been started, so verify the necessary processes are running." msgstr "现在我们已经确认Corosync正常,我们可以开始检查其他部分是否正常." #. Tag: programlisting #, no-c-format msgid "" "# ps axf\n" " PID TTY STAT TIME COMMAND\n" " 2 ? S 0:00 [kthreadd]\n" "...lots of processes...\n" "28019 ? Ssl 0:03 /usr/sbin/corosync\n" "28047 ? Ss 0:00 /usr/sbin/pacemakerd -f\n" "28048 ? Ss 0:00 \\_ /usr/libexec/pacemaker/cib\n" "28049 ? Ss 0:00 \\_ /usr/libexec/pacemaker/stonithd\n" "28050 ? Ss 0:00 \\_ /usr/lib64/heartbeat/lrmd\n" "28051 ? Ss 0:00 \\_ /usr/libexec/pacemaker/attrd\n" "28052 ? Ss 0:00 \\_ /usr/libexec/pacemaker/pengine\n" "28053 ? Ss 0:00 \\_ /usr/libexec/pacemaker/crmd" msgstr "" #. Tag: para #, no-c-format msgid "If that looks ok, check the pcs status output." msgstr "" #. Tag: programlisting #, no-c-format msgid "" "# pcs status\n" "Last updated: Fri Sep 14 09:52:25 2012\n" "Last change: Fri Sep 14 09:51:55 2012 via crmd on pcmk-2\n" "Stack: corosync\n" "Current DC: pcmk-2 (2) - partition with quorum\n" "Version: 1.1.8-1.el7-60a19ed12fdb4d5c6a6b6767f52e5391e447fec0\n" "2 Nodes configured, unknown expected votes\n" "0 Resources configured.\n" "\n" "Online: [ pcmk-1 pcmk-2 ]\n" "\n" "Full list of resources:" msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "Next, check for any ERRORs during startup - there shouldn’t be any." msgstr "最后我们检查启动的过程中有没有错误,按照常理应该没有任何错误并显示集群当前的状态。" #. Tag: programlisting #, no-c-format msgid "# grep -i error /var/log/messages" msgstr "" #. Tag: para #, no-c-format msgid "Repeat these checks on the other node. The results should be the same." msgstr "" #~ msgid "Start Corosync on the first node" #~ msgstr "在第一个节点启动Corosync:" #~ msgid "" #~ "\n" #~ "[root@pcmk-1 ~]# /etc/init.d/corosync start\n" #~ "Starting Corosync Cluster Engine (corosync): [ OK ]\n" #~ msgstr "" #~ "\n" #~ "[root@pcmk-1 ~]# /etc/init.d/corosync start\n" #~ "Starting Corosync Cluster Engine (corosync): [ OK ]\n" #~ msgid "Check the cluster started correctly and that an initial membership was able to form" #~ msgstr "查看集群是否正确启动并且已经可以与其他节点建立集群关系" #~ msgid "" #~ "\n" #~ "[root@pcmk-1 ~]# grep -e \"corosync.*network interface\" -e \"Corosync Cluster Engine\" -e \"Successfully read main configuration file\" /var/log/messages\n" #~ "Aug 27 09:05:34 pcmk-1 corosync[1540]: [MAIN  ] Corosync Cluster Engine ('1.1.0'): started and ready to provide service.\n" #~ "Aug 27 09:05:34 pcmk-1 corosync[1540]: [MAIN  ] Successfully read main configuration file '/etc/corosync/corosync.conf'.\n" #~ "[root@pcmk-1 ~]# grep TOTEM /var/log/messages\n" #~ "Aug 27 09:05:34 pcmk-1 corosync[1540]: [TOTEM ] Initializing transport (UDP/IP).\n" #~ "Aug 27 09:05:34 pcmk-1 corosync[1540]: [TOTEM ] Initializing transmit/receive security: libtomcrypt SOBER128/SHA1HMAC (mode 0).\n" #~ "Aug 27 09:05:35 pcmk-1 corosync[1540]: [TOTEM ] The network interface [192.168.122.101] is now up.\n" #~ "Aug 27 09:05:35 pcmk-1 corosync[1540]: [TOTEM ] A processor joined or left the membership and a new membership was formed.\n" #~ msgstr "" #~ "\n" #~ "[root@pcmk-1 ~]# grep -e \"corosync.*network interface\" -e \"Corosync Cluster Engine\" -e \"Successfully read main configuration file\" /var/log/messages\n" #~ "Aug 27 09:05:34 pcmk-1 corosync[1540]: [MAIN  ] Corosync Cluster Engine ('1.1.0'): started and ready to provide service.\n" #~ "Aug 27 09:05:34 pcmk-1 corosync[1540]: [MAIN  ] Successfully read main configuration file '/etc/corosync/corosync.conf'.\n" #~ "[root@pcmk-1 ~]# grep TOTEM /var/log/messages\n" #~ "Aug 27 09:05:34 pcmk-1 corosync[1540]: [TOTEM ] Initializing transport (UDP/IP).\n" #~ "Aug 27 09:05:34 pcmk-1 corosync[1540]: [TOTEM ] Initializing transmit/receive security: libtomcrypt SOBER128/SHA1HMAC (mode 0).\n" #~ "Aug 27 09:05:35 pcmk-1 corosync[1540]: [TOTEM ] The network interface [192.168.122.101] is now up.\n" #~ "Aug 27 09:05:35 pcmk-1 corosync[1540]: [TOTEM ] A processor joined or left the membership and a new membership was formed.\n" #~ msgid "With one node functional, its now safe to start Corosync on the second node as well." #~ msgstr "第一个节点正常以后,我们可以安全地启动第二个节点。" #~ msgid "" #~ "\n" #~ "[root@pcmk-1 ~]# ssh pcmk-2 -- /etc/init.d/corosync start\n" #~ "Starting Corosync Cluster Engine (corosync): [ OK ]\n" #~ "[root@pcmk-1 ~]#\n" #~ msgstr "" #~ "\n" #~ "[root@pcmk-1 ~]# ssh pcmk-2 -- /etc/init.d/corosync start\n" #~ "Starting Corosync Cluster Engine (corosync): [ OK ]\n" #~ "[root@pcmk-1 ~]#\n" #~ msgid "Check the cluster formed correctly" #~ msgstr "检查集群关系有没有正确建立:" #~ msgid "" #~ "\n" #~ "[root@pcmk-1 ~]# grep TOTEM /var/log/messages\n" #~ "Aug 27 09:05:34 pcmk-1 corosync[1540]: [TOTEM ] Initializing transport (UDP/IP).\n" #~ "Aug 27 09:05:34 pcmk-1 corosync[1540]: [TOTEM ] Initializing transmit/receive security: libtomcrypt SOBER128/SHA1HMAC (mode 0).\n" #~ "Aug 27 09:05:35 pcmk-1 corosync[1540]: [TOTEM ] The network interface [192.168.122.101] is now up.\n" #~ "Aug 27 09:05:35 pcmk-1 corosync[1540]: [TOTEM ] A processor joined or left the membership and a new membership was formed.\n" #~ "Aug 27 09:12:11 pcmk-1 corosync[1540]: [TOTEM ] A processor joined or left the membership and a new membership was formed.\n" #~ msgstr "" #~ "\n" #~ "[root@pcmk-1 ~]# grep TOTEM /var/log/messages\n" #~ "Aug 27 09:05:34 pcmk-1 corosync[1540]: [TOTEM ] Initializing transport (UDP/IP).\n" #~ "Aug 27 09:05:34 pcmk-1 corosync[1540]: [TOTEM ] Initializing transmit/receive security: libtomcrypt SOBER128/SHA1HMAC (mode 0).\n" #~ "Aug 27 09:05:35 pcmk-1 corosync[1540]: [TOTEM ] The network interface [192.168.122.101] is now up.\n" #~ "Aug 27 09:05:35 pcmk-1 corosync[1540]: [TOTEM ] A processor joined or left the membership and a new membership was formed.\n" #~ "Aug 27 09:12:11 pcmk-1 corosync[1540]: [TOTEM ] A processor joined or left the membership and a new membership was formed.\n" #~ msgid "" #~ "\n" #~ "[root@pcmk-1 ~]# grep pcmk_startup /var/log/messages\n" #~ "Aug 27 09:05:35 pcmk-1 corosync[1540]:   [pcmk  ] info: pcmk_startup: CRM: Initialized\n" #~ "Aug 27 09:05:35 pcmk-1 corosync[1540]:   [pcmk  ] Logging: Initialized pcmk_startup\n" #~ "Aug 27 09:05:35 pcmk-1 corosync[1540]:   [pcmk  ] info: pcmk_startup: Maximum core file size is: 18446744073709551615\n" #~ "Aug 27 09:05:35 pcmk-1 corosync[1540]:   [pcmk  ] info: pcmk_startup: Service: 9\n" #~ "Aug 27 09:05:35 pcmk-1 corosync[1540]:   [pcmk  ] info: pcmk_startup: Local hostname: pcmk-1\n" #~ msgstr "" #~ "\n" #~ "[root@pcmk-1 ~]# grep pcmk_startup /var/log/messages\n" #~ "Aug 27 09:05:35 pcmk-1 corosync[1540]:   [pcmk  ] info: pcmk_startup: CRM: Initialized\n" #~ "Aug 27 09:05:35 pcmk-1 corosync[1540]:   [pcmk  ] Logging: Initialized pcmk_startup\n" #~ "Aug 27 09:05:35 pcmk-1 corosync[1540]:   [pcmk  ] info: pcmk_startup: Maximum core file size is: 18446744073709551615\n" #~ "Aug 27 09:05:35 pcmk-1 corosync[1540]:   [pcmk  ] info: pcmk_startup: Service: 9\n" #~ "Aug 27 09:05:35 pcmk-1 corosync[1540]:   [pcmk  ] info: pcmk_startup: Local hostname: pcmk-1\n" #~ msgid "Now verify the Pacemaker processes have been started" #~ msgstr "现在确认pacemaker进程是否正常启动了:" #~ msgid "" #~ "\n" #~ "[root@pcmk-1 ~]# ps axf\n" #~ "  PID TTY      STAT   TIME COMMAND\n" #~ "    2 ?        S<     0:00 [kthreadd]\n" #~ "    3 ?        S<     0:00  \\_ [migration/0]\n" #~ "... lots of processes ...\n" #~ " 2166 pts/0    SLl    0:01 /usr/sbin/corosync\n" #~ " 2172 ?        SLs    0:00  \\_ /usr/lib64/heartbeat/stonithd\n" #~ " 2173 pts/0    S      0:00  \\_ /usr/lib64/heartbeat/cib\n" #~ " 2174 pts/0    S      0:00  \\_ /usr/lib64/heartbeat/lrmd\n" #~ " 2175 pts/0    S      0:00  \\_ /usr/lib64/heartbeat/attrd\n" #~ " 2176 pts/0    S      0:00  \\_ /usr/lib64/heartbeat/pengine\n" #~ " 2177 pts/0    S      0:00  \\_ /usr/lib64/heartbeat/crmd\n" #~ msgstr "" #~ "\n" #~ "[root@pcmk-1 ~]# ps axf\n" #~ "  PID TTY      STAT   TIME COMMAND\n" #~ "    2 ?        S<     0:00 [kthreadd]\n" #~ "    3 ?        S<     0:00  \\_ [migration/0]\n" #~ "... lots of processes ...\n" #~ " 2166 pts/0    SLl    0:01 /usr/sbin/corosync\n" #~ " 2172 ?        SLs    0:00  \\_ /usr/lib64/heartbeat/stonithd\n" #~ " 2173 pts/0    S      0:00  \\_ /usr/lib64/heartbeat/cib\n" #~ " 2174 pts/0    S      0:00  \\_ /usr/lib64/heartbeat/lrmd\n" #~ " 2175 pts/0    S      0:00  \\_ /usr/lib64/heartbeat/attrd\n" #~ " 2176 pts/0    S      0:00  \\_ /usr/lib64/heartbeat/pengine\n" #~ " 2177 pts/0    S      0:00  \\_ /usr/lib64/heartbeat/crmd\n" #~ msgid "" #~ "\n" #~ "[root@pcmk-1 ~]# grep ERROR: /var/log/messages | grep -v unpack_resources\n" #~ "[root@pcmk-1 ~]# crm_mon\n" #~ "============\n" #~ "Last updated: Thu Aug 27 16:54:55 2009\n" #~ "Stack: openais\n" #~ "Current DC: pcmk-1 - partition with quorum\n" #~ "Version: 1.0.5-462f1569a43740667daf7b0f6b521742e9eb8fa7\n" #~ "2 Nodes configured, 2 expected votes\n" #~ "0 Resources configured.\n" #~ "============\n" #~ "\n" #~ "Online: [ pcmk-1 pcmk-2 ]\n" #~ msgstr "" #~ "\n" #~ "[root@pcmk-1 ~]# grep ERROR: /var/log/messages | grep -v unpack_resources\n" #~ "[root@pcmk-1 ~]# crm_mon\n" #~ "============\n" #~ "Last updated: Thu Aug 27 16:54:55 2009\n" #~ "Stack: openais\n" #~ "Current DC: pcmk-1 - partition with quorum\n" #~ "Version: 1.0.5-462f1569a43740667daf7b0f6b521742e9eb8fa7\n" #~ "2 Nodes configured, 2 expected votes\n" #~ "0 Resources configured.\n" #~ "============\n" #~ "\n" #~ "Online: [ pcmk-1 pcmk-2 ]\n" pacemaker-master/doc/Clusters_from_Scratch/zh-CN/Clusters_from_Scratch.mo000066400000000000000000000005001217637305600271210ustar00rootroot00000000000000$,89Project-Id-Version: 0 POT-Creation-Date: 2010-09-22T10:48:14 PO-Revision-Date: 2010-12-15 19:18+0800 Last-Translator: Charlie Chen Language-Team: None MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit pacemaker-master/doc/Clusters_from_Scratch/zh-CN/Clusters_from_Scratch.po000066400000000000000000000005541217637305600271350ustar00rootroot00000000000000# # AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: 0\n" "POT-Creation-Date: 2010-12-15T12:27:01\n" "PO-Revision-Date: 2010-12-15 19:18+0800\n" "Last-Translator: Charlie Chen \n" "Language-Team: None\n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" pacemaker-master/doc/Clusters_from_Scratch/zh-CN/Preface.mo000066400000000000000000000005471217637305600242030ustar00rootroot00000000000000,<PQY`PrefaceProject-Id-Version: 0 POT-Creation-Date: 2010-09-22T10:48:14 PO-Revision-Date: 2010-12-15 19:18+0800 Last-Translator: Charlie Chen Language-Team: None MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 前言pacemaker-master/doc/Clusters_from_Scratch/zh-CN/Preface.po000066400000000000000000000006521217637305600242030ustar00rootroot00000000000000# # AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: 0\n" "POT-Creation-Date: 2010-12-15T23:32:37\n" "PO-Revision-Date: 2010-12-15 19:18+0800\n" "Last-Translator: Charlie Chen \n" "Language-Team: None\n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. Tag: title #, no-c-format msgid "Preface" msgstr "前言" pacemaker-master/doc/Clusters_from_Scratch/zh-CN/Revision_History.mo000066400000000000000000000010031217637305600261410ustar00rootroot00000000000000Dl AndrewBeekhofImport from Pages.appRevision HistoryProject-Id-Version: 0 POT-Creation-Date: 2010-12-15T23:32:37 PO-Revision-Date: 2010-12-15 23:43+0800 Last-Translator: Charlie Chen Language-Team: None Language: MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit AndrewBeekhofImport from Pages.app修订历史pacemaker-master/doc/Clusters_from_Scratch/zh-CN/Revision_History.po000066400000000000000000000025121217637305600261520ustar00rootroot00000000000000# # AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: 0\n" "POT-Creation-Date: 2012-10-17T05:19:03\n" "PO-Revision-Date: 2010-12-15 23:43+0800\n" "Last-Translator: Charlie Chen \n" "Language-Team: None\n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. Tag: title #, no-c-format msgid "Revision History" msgstr "修订历史" #. Tag: firstname #, no-c-format msgid "Andrew" msgstr "Andrew" #. Tag: surname #, no-c-format msgid "Beekhof" msgstr "Beekhof" #. Tag: member #, no-c-format msgid "Import from Pages.app" msgstr "Import from Pages.app" #. Tag: firstname #, no-c-format msgid "Raoul" msgstr "" #. Tag: surname #, no-c-format msgid "Scarazzini" msgstr "" #. Tag: member #, no-c-format msgid "Italian translation" msgstr "" #. Tag: member #, no-c-format msgid "Updated for Fedora 13" msgstr "" #. Tag: member #, no-c-format msgid "Update the GFS2 section to use CMAN" msgstr "" #. Tag: member #, no-c-format msgid "Generate docbook content from asciidoc sources" msgstr "" #. Tag: member #, no-c-format msgid "Updated for Fedora 17" msgstr "" #. Tag: firstname #, no-c-format msgid "David" msgstr "" #. Tag: surname #, no-c-format msgid "Vossel" msgstr "" #. Tag: member #, no-c-format msgid "Updated for pcs" msgstr "" pacemaker-master/doc/Makefile.am000066400000000000000000000200271217637305600171130ustar00rootroot00000000000000# # doc: Pacemaker code # # Copyright (C) 2008 Andrew Beekhof # # 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 2 # of the License, 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. # MAINTAINERCLEANFILES = Makefile.in helpdir = $(datadir)/$(PACKAGE) ascii = crm_fencing.txt acls.txt docbook = Pacemaker_Explained Clusters_from_Scratch Pacemaker_Remote doc_DATA = README.hb2openais $(ascii) $(generated_docs) publican_docs = generated_docs = generated_mans = DOCBOOK_FORMATS := html-desktop DOCBOOK_LANGS := en-US DOTs = $(wildcard */en-US/images/*.dot) SVG = $(wildcard */en-US/images/pcmk-*.svg) $(DOTs:%.dot=%.svg) PNGS = $(SVG:%.svg=%-small.png) $(SVG:%.svg=%.png) $(SVG:%.svg=%-large.png) \ Pacemaker_Explained/en-US/images/Policy-Engine-big.png \ Pacemaker_Explained/en-US/images/Policy-Engine-small.png \ Pacemaker_Remote/en-US/images/pcmk-ha-cluster-stack.png \ Pacemaker_Remote/en-US/images/pcmk-ha-remote-stack.png BRAND_PNGS = publican-clusterlabs/en-US/images/title_logo.png \ publican-clusterlabs/en-US/images/image_left.png \ publican-clusterlabs/en-US/images/image_right.png \ publican-clusterlabs/en-US/images/h1-bg.png graphics: $(PNGS) %.png: %.svg $(INKSCAPE) --file=$< --export-dpi=90 -C --export-png=$@ %-small.png: %.svg $(INKSCAPE) --file=$< --export-dpi=45 -C --export-png=$@ %-large.png: %.svg $(INKSCAPE) --file=$< --export-dpi=180 -C --export-png=$@ if BUILD_ASCIIDOC generated_docs += $(ascii:%.txt=%.html) if BUILD_DOCBOOK publican_docs += $(docbook) endif endif EXTRA_DIST = $(docbook:%=%.xml) %.html: %.txt $(ASCIIDOC) --unsafe --backend=xhtml11 $< %.8: %.8.txt a2x -L -f manpage $< # Build docbook from asciidoc because XML is a PITA to edit # # Build each chapter as a book (since the numbering isn't right for # articles and only books can have appendicies) and then strip out the # bits we don't want/need # %.xml: %.txt asciidoc -b docbook -a cli_name=$(ASCIIDOC_CLI_TYPE) -a $(ASCIIDOC_CLI_TYPE)=true -d book -o $@ $< sed -i.sed 's///' $@ sed -i.sed 's/ //' $@ # Fix line endings sed -i.sed 's/\ lang="en"//' $@ # Never specify a language in the chapters sed -i.sed 's/simpara/para/g' $@ # publican doesn't correctly render footnotes with simpara sed -i.sed 's/.*.*//g' $@ # Remove dangling tag sed -i.sed 's/.*preface>//g' $@ # Remove preface elements sed -i.sed 's:::g' $@ # Remove empty title sed -i.sed 's/chapter/section/g' $@ # Chapters become sections, so that books can become chapters sed -i.sed 's/<.*bookinfo.*>//g' $@ # Strip out bookinfo, we don't need it -grep -qis "//' $@ # We just want the appendix tag -grep -vqis "/chapter>/g' $@ # Rename to chapter echo Rebuilt $@ from $< CFS_TXT=$(wildcard Clusters_from_Scratch/en-US/*.txt) CFS_XML=$(CFS_TXT:%.txt=%.xml) # We have to hardcode the book name # With '%' the test for 'newness' fails Clusters_from_Scratch.build: $(PNGS) $(wildcard Clusters_from_Scratch/en-US/*.xml) $(CFS_XML) @echo Building $(@:%.build=%) because of $? rm -rf $(@:%.build=%)/publish/* cd $(@:%.build=%) && RPM_BUILD_DIR="" $(PUBLICAN) build --publish --langs=$(DOCBOOK_LANGS) --formats=$(DOCBOOK_FORMATS) rm -rf $(@:%.build=%)/tmp touch $@ PE_TXT=$(wildcard Pacemaker_Explained/en-US/*.txt) PE_XML=$(PE_TXT:%.txt=%.xml) # We have to hardcode the book name # With '%' the test for 'newness' fails Pacemaker_Explained.build: $(PNGS) $(wildcard Pacemaker_Explained/en-US/*.xml) $(PE_XML) @echo Building $(@:%.build=%) because of $? rm -rf $(@:%.build=%)/publish/* cd $(@:%.build=%) && RPM_BUILD_DIR="" $(PUBLICAN) build --publish --langs=$(DOCBOOK_LANGS) --formats=$(DOCBOOK_FORMATS) rm -rf $(@:%.build=%)/tmp touch $@ PR_TXT=$(wildcard Pacemaker_Remote/en-US/*.txt) PR_XML=$(PR_TXT:%.txt=%.xml) # We have to hardcode the book name # With '%' the test for 'newness' fails Pacemaker_Remote.build: $(PNGS) $(wildcard Pacemaker_Remote/en-US/*.xml) $(PR_XML) @echo Building $(@:%.build=%) because of $? rm -rf $(@:%.build=%)/publish/* cd $(@:%.build=%) && RPM_BUILD_DIR="" $(PUBLICAN) build --publish --langs=$(DOCBOOK_LANGS) --formats=$(DOCBOOK_FORMATS) rm -rf $(@:%.build=%)/tmp touch $@ # Update the translation template pot: for book in $(docbook); do \ echo "Updating translation templates in: $$book"; \ ( cd $$book && RPM_BUILD_DIR="" $(PUBLICAN) update_pot ); \ done # Update the actual translations po: pot for book in $(docbook); do \ echo "Updating translations in: $$book"; \ ( cd $$book && RPM_BUILD_DIR="" $(PUBLICAN) update_po --langs=all );\ done if BUILD_DOCBOOK docbook_build = $(docbook:%=%.build) all-local: $(docbook_build) */publican.cfg #install-data-local: all-local install-data-local: all-local for book in $(docbook); do \ filelist=`find $$book/publish/* -print`; \ for f in $$filelist; do \ p=`echo $$f | sed s:publish/:: | sed s:Pacemaker/::`; \ if [ -d $$f ]; then \ $(INSTALL) -d 775 $(DESTDIR)$(docdir)/$$p; \ else \ $(INSTALL) -m 644 $$f $(DESTDIR)$(docdir)/$$p; \ fi \ done; \ done endif brand: $(BRAND_PNGS) $(wildcard publican-clusterlabs/en-US/*.xml) cd publican-clusterlabs && publican build --formats=xml --langs=all --publish echo "Installing..." cd publican-clusterlabs && sudo publican install_brand --path=$(datadir)/publican/Common_Content # find publican-clusterlabs -name "*.noarch.rpm" -exec rm -f \{\} \; # cd publican-clusterlabs && $(PUBLICAN) package --binary # find publican-clusterlabs -name "*.noarch.rpm" -exec sudo rpm -Uvh --force \{\} \; pdf: make DOCBOOK_FORMATS="pdf" ASCIIDOC_CLI_TYPE=$(ASCIIDOC_CLI_TYPE) all-local # Make sure www-(pcs|crmsh) happen in serial www: make www-pcs make www-crmsh make $(generated_docs) $(ascii) rsync -rtz --progress $(generated_docs) $(ascii) $(asciiman) root@www.clusterlabs.org:/var/www/html/doc/ www-crmsh: make ASCIIDOC_CLI_TYPE=crmsh clean-local www-cli www-pcs: make ASCIIDOC_CLI_TYPE=pcs clean-local www-cli www-cli: for book in $(docbook); do \ sed -i.sed 's@brand:.*@brand: clusterlabs@' $$book/publican.cfg; \ sed -i.sed 's@version:.*@version: $(PACKAGE_SERIES)-$(ASCIIDOC_CLI_TYPE)@' $$book/publican.cfg; \ done make DOCBOOK_FORMATS="pdf,html,html-single,epub" DOCBOOK_LANGS="all" ASCIIDOC_CLI_TYPE=$(ASCIIDOC_CLI_TYPE) all-local echo Uploading current $(PACKAGE_SERIES)-$(ASCIIDOC_CLI_TYPE) documentation set to clusterlabs.org if BUILD_DOCBOOK for book in $(docbook); do \ echo Uploading $$book...; \ echo "Generated on `date` from version: $(shell git log --pretty="format:%h %d" -n 1)" >> $$book/publish/build-$(PACKAGE_SERIES)-$(ASCIIDOC_CLI_TYPE).txt; \ for lang in `ls -1 $$book/publish | grep [a-z][a-z]-[A-Z][A-Z]`; do \ mv $$book/publish/$$lang/Pacemaker/$(PACKAGE_SERIES)-$(ASCIIDOC_CLI_TYPE)/epub/$$book/Pacemaker-1.1{-$(ASCIIDOC_CLI_TYPE),}-$$book-$$lang.epub; \ mv $$book/publish/$$lang/Pacemaker/$(PACKAGE_SERIES)-$(ASCIIDOC_CLI_TYPE)/pdf/$$book/Pacemaker-1.1{-$(ASCIIDOC_CLI_TYPE),}-$$book-$$lang.pdf; \ done; \ rsync -rtz --progress $$book/publish/* root@www.clusterlabs.org:/var/www/html/doc/; \ sed -i.sed 's@version:.*@version: $(PACKAGE_SERIES)@' $$book/publican.cfg; \ done endif clean-local: -rm -rf $(generated_docs) $(generated_mans) $(docbook_build) $(CFS_XML) $(PE_XML) $(PR_XML) for book in $(docbook); do rm -rf $$book/tmp $$book/publish; done foo: rm -f $(CFS_XML) pacemaker-master/doc/Pacemaker_Explained/000077500000000000000000000000001217637305600207375ustar00rootroot00000000000000pacemaker-master/doc/Pacemaker_Explained/en-US/000077500000000000000000000000001217637305600216665ustar00rootroot00000000000000pacemaker-master/doc/Pacemaker_Explained/en-US/Ap-Changes.txt000066400000000000000000000060131217637305600243350ustar00rootroot00000000000000[appendix] == What Changed in 1.0 == === New === * Failure timeouts. See <> * New section for resource and operation defaults. See <> and <> * Tool for making offline configuration changes. See <> * +Rules, instance_attributes, meta_attributes+ and sets of operations can be defined once and referenced in multiple places. See <> * The CIB now accepts XPath-based create/modify/delete operations. See the pass:[cibadmin] help text. * Multi-dimensional colocation and ordering constraints. See <> and <> * The ability to connect to the CIB from non-cluster machines. See <> * Allow recurring actions to be triggered at known times. See <> === Changed === * Syntax ** All resource and cluster options now use dashes (-) instead of underscores (_) ** +master_slave+ was renamed to +master+ ** The +attributes+ container tag was removed ** The operation field +pre-req+ has been renamed +requires+ ** All operations must have an +interval+, +start+/+stop+ must have it set to zero * The +stonith-enabled+ option now defaults to true. * The cluster will refuse to start resources if +stonith-enabled+ is true (or unset) and no STONITH resources have been defined * The attributes of colocation and ordering constraints were renamed for clarity. See <> and <> * +resource-failure-stickiness+ has been replaced by +migration-threshold+. See <> * The parameters for command-line tools have been made consistent * Switched to 'RelaxNG' schema validation and 'libxml2' parser ** id fields are now XML IDs which have the following limitations: *** id's cannot contain colons (:) *** id's cannot begin with a number *** id's must be globally unique (not just unique for that tag) ** Some fields (such as those in constraints that refer to resources) are IDREFs. + This means that they must reference existing resources or objects in order for the configuration to be valid. Removing an object which is referenced elsewhere will therefore fail. + ** The CIB representation, from which a MD5 digest is calculated to verify CIBs on the nodes, has changed. + This means that every CIB update will require a full refresh on any upgraded nodes until the cluster is fully upgraded to 1.0. This will result in significant performance degradation and it is therefore highly inadvisable to run a mixed 1.0/0.6 cluster for any longer than absolutely necessary. + * Ping node information no longer needs to be added to _ha.cf_. + Simply include the lists of hosts in your ping resource(s). === Removed === * Syntax ** It is no longer possible to set resource meta options as top-level attributes. Use meta attributes instead. ** Resource and operation defaults are no longer read from +crm_config+. See <> and <> instead. pacemaker-master/doc/Pacemaker_Explained/en-US/Ap-Debug.xml000066400000000000000000000115541217637305600240020ustar00rootroot00000000000000 Debugging Cluster Startup

Corosync
Prerequisites Minimum logging configuration # /etc/init.d/openais start logging { to_syslog: yes syslog_facility: daemon } Whatever other logging you have, these two lines are required for Pacemaker clusters
Confirm Corosync Started
Expected output when starting openais # /etc/init.d/openais start Starting Corosync daemon (aisexec): starting... rc=0: OK
Expected log messages - startup # grep -e "openais.*network interface" -e "AIS Executive Service" /var/log/messages Aug 27 16:23:37 test1 openais[26337]: [MAIN ] AIS Executive Service RELEASE 'subrev 1152 version 0.80' Aug 27 16:23:38 test1 openais[26337]: [MAIN ] AIS Executive Service: started and ready to provide service. Aug 27 16:23:38 test1 openais[26337]: [TOTEM] The network interface [192.168.9.41] is now up. The versions may differ, but you should see Corosync indicate it started and sucessfully attached to the machine's network interface
Expected log messages - membership # grep CLM /var/log/messages Aug 27 16:53:15 test1 openais[2166]: [CLM ] CLM CONFIGURATION CHANGE Aug 27 16:53:15 test1 openais[2166]: [CLM ] New Configuration: Aug 27 16:53:15 test1 openais[2166]: [CLM ] Members Left: Aug 27 16:53:15 test1 openais[2166]: [CLM ] Members Joined: Aug 27 16:53:15 test1 openais[2166]: [CLM ] CLM CONFIGURATION CHANGE Aug 27 16:53:15 test1 openais[2166]: [CLM ] New Configuration: Aug 27 16:53:15 test1 openais[2166]: [CLM ] r(0) ip(192.168.9.41) Aug 27 16:53:15 test1 openais[2166]: [CLM ] Members Left: Aug 27 16:53:15 test1 openais[2166]: [CLM ] Members Joined: Aug 27 16:53:15 test1 openais[2166]: [CLM ] r(0) ip(192.168.9.41) Aug 27 16:53:15 test1 openais[2166]: [CLM ] got nodejoin message 192.168.9.41 The exact messages will differ, but you should see a new membership formed with the real IP address of your node
Checking Pacemaker Now that we have confirmed that Corosync is functional we can check the rest of the stack.
Expected Pacemaker startup logging for Corosync # grep pcmk_plugin_init /var/log/messages Aug 27 16:53:15 test1 openais[2166]: [pcmk ] info: pcmk_plugin_init: CRM: Initialized Aug 27 16:53:15 test1 openais[2166]: [pcmk ] Logging: Initialized pcmk_plugin_init Aug 27 16:53:15 test1 openais[2166]: [pcmk ] info: pcmk_plugin_init: Service: 9 Aug 27 16:53:15 test1 openais[2166]: [pcmk ] info: pcmk_plugin_init: Local hostname: test1 If you don't see these messages, or some like them, there is likely a problem finding or loading the pacemaker plugin.
Expected process listing on a 64-bit machine # ps axf 3718 ? Ssl 0:05 /usr/sbin/aisexec 3723 ? SLs 0:00 \_ /usr/lib64/heartbeat/stonithd 3724 ? S 0:05 \_ /usr/lib64/heartbeat/cib 3725 ? S 0:21 \_ /usr/lib64/heartbeat/lrmd 3726 ? S 0:01 \_ /usr/lib64/heartbeat/attrd 3727 ? S 0:00 \_ /usr/lib64/heartbeat/pengine 3728 ? S 0:01 \_ /usr/lib64/heartbeat/crmd On 32-bit systems the exact path may differ, but all the above processes should be listed.
pacemaker-master/doc/Pacemaker_Explained/en-US/Ap-FAQ.xml000066400000000000000000000116211217637305600233560ustar00rootroot00000000000000 FAQ History Why is the Project Called PacemakernamingPacemaker? First of all, the reason its not called the CRM is because of the abundance of terms that are commonly abbreviated to those three letters. The Pacemaker name came from Kham, a good friend of mine, and was originally used by a Java GUI that I was prototyping in early 2007. Alas other commitments have prevented the GUI from progressing much and, when it came time to choose a name for this project, Lars suggested it was an even better fit for an independent CRM. The idea stems from the analogy between the role of this software and that of the little device that keeps the human heart pumping. Pacemaker monitors the cluster and intervenes when necessary to ensure the smooth operation of the services it provides. There were a number of other names (and acronyms) tossed around, but suffice to say "Pacemaker" was the best Why was the Pacemaker Project Created? The decision was made to spin-off the CRM into its own project after the 2.1.3 Heartbeat release in order to support both the Corosync and Heartbeat cluster stacks equally decouple the release cycles of two projects at very different stages of their life-cycles foster the clearer package boundaries, thus leading to better and more stable interfaces Setup What Messaging Layers Messaging Layers are Supported? Corosync () Heartbeat () Can I Choose which Messaging Layer to use at Run Time? Yes. The CRM will automatically detect which started it and behave accordingly. Can I Have a Mixed Heartbeat-Corosync Cluster? No. Which Messaging Layer Should I Choose? This is discussed in . Where Can I Get Pre-built Packages? Official packages for most major .rpm and based distributions are available from the ClusterLabs Website. For Debian packages, building from source and details on using the above repositories, see our installation page. What Versions of Pacemaker Are Supported? Please refer to the Releases page for an up-to-date list of versions supported directly by the project. When seeking assistance, please try to ensure you have one of these versions. pacemaker-master/doc/Pacemaker_Explained/en-US/Ap-Install.txt000066400000000000000000000067551217637305600244100ustar00rootroot00000000000000[appendix] [[ap-install]] == Installation == [WARNING] The following text may no longer be accurate in some places. === Choosing a Cluster Stack === indexterm:[Cluster,Choosing Between Heartbeat and Corosync] indexterm:[Cluster Stack,Corosync] indexterm:[Corosync] indexterm:[Cluster Stack,Heartbeat] indexterm:[Heartbeat] Ultimately the choice of cluster stack is a personal decision that must be made in the context of you or your company's needs and strategic direction. Pacemaker currently functions equally well with both stacks. Here are some factors that may influence the decision: * SUSE/Novell, Red Hat and Oracle are all putting their collective weight behind the Corosync cluster stack. * Using Corosync gives your applications access to the following additional cluster services ** distributed locking service ** extended virtual synchronization service ** cluster closed process group service * It is likely that Pacemaker, at some point in the future, will make use of some of these additional services not provided by Heartbeat === Enabling Pacemaker === ==== For Corosync ==== The Corosync configuration is normally located in '/etc/corosync/corosync.conf' and an example for a machine with an address of +1.2.3.4+ in a cluster communicating on port 1234 (without peer authentication and message encryption) is shown below. .An example Corosync configuration file [source,XML] ------- totem { version: 2 secauth: off threads: 0 interface { ringnumber: 0 bindnetaddr: 1.2.3.4 mcastaddr: 239.255.1.1 mcastport: 1234 } } logging { fileline: off to_syslog: yes syslog_facility: daemon } amf { mode: disabled } ------- The logging should be mostly obvious and the amf section refers to the Availability Management Framework and is not covered in this document. The interesting part of the configuration is the totem section. This is where we define how the node can communicate with the rest of the cluster and what protocol version and options (including encryption footnote:[ Please consult the Corosync website (http://www.corosync.org/) and documentation for details on enabling encryption and peer authentication for the cluster. ] ) it should use. Beginners are encouraged to use the values shown and modify the interface section based on their network. It is also possible to configure Corosync for an IPv6 based environment. Simply configure +bindnetaddr+ and +mcastaddr+ with their IPv6 equivalents, eg. .Example options for an IPv6 environment [source,Bash] ------- bindnetaddr: fec0::1:a800:4ff:fe00:20 mcastaddr: ff05::1 ------- To tell Corosync to use the Pacemaker cluster manager, add the following fragment to a functional Corosync configuration and restart the cluster. .Configuration fragment for enabling Pacemaker under Corosync [source,XML] ------- aisexec { user: root group: root } service { name: pacemaker ver: 0 } ------- The cluster needs to be run as root so that its child processes (the +lrmd+ in particular) have sufficient privileges to perform the actions requested of it. After all, a cluster manager that can't add an IP address or start apache is of little use. The second directive is the one that actually instructs the cluster to run Pacemaker. ==== For Heartbeat ==== Add the following to a functional _ha.cf_ configuration file and restart Heartbeat: .Configuration fragment for enabling Pacemaker under Heartbeat [source,Bash] crm respawn pacemaker-master/doc/Pacemaker_Explained/en-US/Ap-LSB.txt000066400000000000000000000042641217637305600234130ustar00rootroot00000000000000[appendix] [[ap-lsb]] == init-Script LSB Compliance == The relevant part of http://refspecs.freestandards.org/LSB_3.1.0/LSB-Core-generic/LSB-Core-generic/iniscrptact.html[LSB spec] includes a description of all the return codes listed here. Assuming +some_service+ is configured correctly and currently not active, the following sequence will help you determine if it is LSB compatible: . Start (stopped): + [source,C] # /etc/init.d/some_service start ; echo "result: $?" + .. Did the service start? .. Did the command print result: 0 (in addition to the regular output)? + . Status (running): + [source,C] # /etc/init.d/some_service status ; echo "result: $?" + .. Did the script accept the command? .. Did the script indicate the service was running? .. Did the command print result: 0 (in addition to the regular output)? + . Start (running): + [source,C] # /etc/init.d/some_service start ; echo "result: $?" + .. Is the service still running? .. Did the command print result: 0 (in addition to the regular output)? + . Stop (running): + [source,C] # /etc/init.d/some_service stop ; echo "result: $?" + .. Was the service stopped? .. Did the command print result: 0 (in addition to the regular output)? + . Status (stopped): + [source,C] # /etc/init.d/some_service status ; echo "result: $?" + .. Did the script accept the command? .. Did the script indicate the service was not running? .. Did the command print result: 3 (in addition to the regular output)? + . Stop (stopped): + [source,C] # /etc/init.d/some_service stop ; echo "result: $?" + .. Is the service still stopped? .. Did the command print result: 0 (in addition to the regular output)? + . Status (failed): + This step is not readily testable and relies on manual inspection of the script. + The script can use one of the error codes (other than 3) listed in the LSB spec to indicate that it is active but failed. This tells the cluster that before moving the resource to another node, it needs to stop it on the existing one first. If the answer to any of the above questions is no, then the script is not LSB compliant. Your options are then to either fix the script or write an OCF agent based on the existing script. pacemaker-master/doc/Pacemaker_Explained/en-US/Ap-OCF.txt000066400000000000000000000170471217637305600234050ustar00rootroot00000000000000[appendix] [[ap-ocf]] == More About OCF Resource Agents == === Location of Custom Scripts === indexterm:[OCF Resource Agents] OCF Resource Agents are found in '/usr/lib/ocf/resource.d/+provider+'. When creating your own agents, you are encouraged to create a new directory under _/usr/lib/ocf/resource.d/_ so that they are not confused with (or overwritten by) the agents shipped with Heartbeat. So, for example, if you chose the provider name of bigCorp and wanted a new resource named bigApp, you would create a script called _/usr/lib/ocf/resource.d/bigCorp/bigApp_ and define a resource: [source,XML] === Actions === All OCF Resource Agents are required to implement the following actions .Required Actions for OCF Agents [width="95%",cols="3m,3,7",options="header",align="center"] |========================================================= |Action |Description |Instructions |start |Start the resource |Return 0 on success and an appropriate error code otherwise. Must not report success until the resource is fully active. indexterm:[start,OCF Action] indexterm:[OCF,Action,start] |stop |Stop the resource |Return 0 on success and an appropriate error code otherwise. Must not report success until the resource is fully stopped. indexterm:[stop,OCF Action] indexterm:[OCF,Action,stop] |monitor |Check the resource's state |Exit 0 if the resource is running, 7 if it is stopped, and anything else if it is failed. indexterm:[monitor,OCF Action] indexterm:[OCF,Action,monitor] NOTE: The monitor script should test the state of the resource on the local machine only. |meta-data |Describe the resource |Provide information about this resource as an XML snippet. Exit with 0. indexterm:[meta-data,OCF Action] indexterm:[OCF,Action,meta-data] NOTE: This is *not* performed as root. |validate-all |Verify the supplied parameters |Exit with 0 if parameters are valid, 2 if not valid, 6 if resource is not configured. indexterm:[validate-all,OCF Action] indexterm:[OCF,Action,validate-all] |========================================================= Additional requirements (not part of the OCF specs) are placed on agents that will be used for advanced concepts like <> and <> resources. .Optional Actions for OCF Agents [width="95%",cols="2m,6,3",options="header",align="center"] |========================================================= |Action |Description |Instructions |promote |Promote the local instance of a multi-state resource to the master/primary state. |Return 0 on success indexterm:[promote,OCF Action] indexterm:[OCF,Action,promote] |demote |Demote the local instance of a multi-state resource to the slave/secondary state. |Return 0 on success indexterm:[demote,OCF Action] indexterm:[OCF,Action,demote] |notify |Used by the cluster to send the agent pre and post notification events telling the resource what has happened and will happen. |Must not fail. Must exit with 0 indexterm:[notify,OCF Action] indexterm:[OCF,Action,notify] |========================================================= One action specified in the OCF specs is not currently used by the cluster: * +recover+ - a variant of the +start+ action, this should try to recover a resource locally. Remember to use indexterm:[ocf-tester]`ocf-tester` to verify that your new agent complies with the OCF standard properly. === How are OCF Return Codes Interpreted? === The first thing the cluster does is to check the return code against the expected result. If the result does not match the expected value, then the operation is considered to have failed and recovery action is initiated. There are three types of failure recovery: .Types of recovery performed by the cluster [width="95%",cols="1m,4,4",options="header",align="center"] |========================================================= |Type |Description |Action Taken by the Cluster |soft |A transient error occurred |Restart the resource or move it to a new location indexterm:[soft,OCF error] indexterm:[OCF,error,soft] |hard |A non-transient error that may be specific to the current node occurred |Move the resource elsewhere and prevent it from being retried on the current node indexterm:[hard,OCF error] indexterm:[OCF,error,hard] |fatal |A non-transient error that will be common to all cluster nodes (eg. a bad configuration was specified) |Stop the resource and prevent it from being started on any cluster node indexterm:[fatal,OCF error] indexterm:[OCF,error,fatal] |========================================================= Assuming an action is considered to have failed, the following table outlines the different OCF return codes and the type of recovery the cluster will initiate when it is received. [[s-ocf-return-codes]] === OCF Return Codes === .OCF Return Codes and their Recovery Types [width="95%",cols="2m,5^m,6<,1m",options="header",align="center"] |========================================================= |RC |OCF Alias |Description |RT |0 |OCF_SUCCESS |Success. The command completed successfully. This is the expected result for all start, stop, promote and demote commands. indexterm:[Return Code,OCF_SUCCESS] indexterm:[Return Code,0,OCF_SUCCESS] |soft |1 |OCF_ERR_GENERIC |Generic "there was a problem" error code. indexterm:[Return Code,OCF_ERR_GENERIC] indexterm:[Return Code,1,OCF_ERR_GENERIC] |soft |2 |OCF_ERR_ARGS |The resource's configuration is not valid on this machine. Eg. refers to a location/tool not found on the node. indexterm:[Return Code,OCF_ERR_ARGS] indexterm:[Return Code,2,OCF_ERR_ARGS] |hard |3 |OCF_ERR_UNIMPLEMENTED |The requested action is not implemented. indexterm:[Return Code,OCF_ERR_UNIMPLEMENTED] indexterm:[Return Code,3,OCF_ERR_UNIMPLEMENTED] |hard |4 |OCF_ERR_PERM |The resource agent does not have sufficient privileges to complete the task. indexterm:[Return Code,OCF_ERR_PERM] indexterm:[Return Code,4,OCF_ERR_PERM] |hard |5 |OCF_ERR_INSTALLED |The tools required by the resource are not installed on this machine. indexterm:[Return Code,OCF_ERR_INSTALLED] indexterm:[Return Code,5,OCF_ERR_INSTALLED] |hard |6 |OCF_ERR_CONFIGURED |The resource's configuration is invalid. Eg. required parameters are missing. indexterm:[Return Code,OCF_ERR_CONFIGURED] indexterm:[Return Code,6,OCF_ERR_CONFIGURED] |fatal |7 |OCF_NOT_RUNNING |The resource is safely stopped. The cluster will not attempt to stop a resource that returns this for any action. indexterm:[Return Code,OCF_NOT_RUNNING] indexterm:[Return Code,7,OCF_NOT_RUNNING] |N/A |8 |OCF_RUNNING_MASTER |The resource is running in +Master+ mode. indexterm:[Return Code,OCF_RUNNING_MASTER] indexterm:[Return Code,8,OCF_RUNNING_MASTER] |soft |9 |OCF_FAILED_MASTER |The resource is in +Master+ mode but has failed. The resource will be demoted, stopped and then started (and possibly promoted) again. indexterm:[Return Code,OCF_FAILED_MASTER] indexterm:[Return Code,9,OCF_FAILED_MASTER] |soft |other |NA |Custom error code. indexterm:[Return Code,other] |soft |========================================================= Although counterintuitive, even actions that return 0 (aka. +OCF_SUCCESS+) can be considered to have failed. === Exceptions === * Non-recurring monitor actions (probes) that find a resource active (or in Master mode) will not result in recovery action unless it is also found active elsewhere * The recovery action taken when a resource is found active more than once is determined by the _multiple-active_ property of the resource * Recurring actions that return +OCF_ERR_UNIMPLEMENTED+ do not cause any type of recovery pacemaker-master/doc/Pacemaker_Explained/en-US/Ap-Samples.txt000066400000000000000000000105261217637305600243750ustar00rootroot00000000000000[appendix] == Sample Configurations == === Empty === .An Empty Configuration ======= [source,XML] ------- ------- ======= === Simple === .Simple Configuration - 2 nodes, some cluster options and a resource ======= [source,XML] ------- ------- ======= In this example, we have one resource (an IP address) that we check every five minutes and will run on host +c001n01+ until either the resource fails 10 times or the host shuts down. === Advanced Configuration === .Advanced configuration - groups and clones with stonith ======= [source,XML] ------- ------- ======= pacemaker-master/doc/Pacemaker_Explained/en-US/Ap-Upgrade-Config.txt000066400000000000000000000110031217637305600255520ustar00rootroot00000000000000[appendix] == Upgrading the Configuration from 0.6 == === Preparation === indexterm:[Upgrading the Configuration] indexterm:[Configuration,Upgrading] indexterm:[Download,DTD] indexterm:[DTD,Download] Download the latest http://hg.clusterlabs.org/pacemaker/stable-1.0/file-raw/tip/xml/crm.dtd[DTD] and ensure your configuration validates. === Perform the upgrade === ==== Upgrade the software ==== Refer to the appendix: <> ==== Upgrade the Configuration ==== As XML is not the friendliest of languages, it is common for cluster administrators to have scripted some of their activities. In such cases, it is likely that those scripts will not work with the new 1.0 syntax. In order to support such environments, it is actually possible to continue using the old 0.6 syntax. The downside is, however, that not all the new features will be available and there is a performance impact since the cluster must do a non-persistent configuration upgrade before each transition. So while using the old syntax is possible, it is not advisable to continue using it indefinitely. Even if you wish to continue using the old syntax, it is advisable to follow the upgrade procedure to ensure that the cluster is able to use your existing configuration (since it will perform much the same task internally). . Create a shadow copy to work with + [source,C] ----- # crm_shadow --create upgrade06 ----- . Verify the configuration is valid indexterm:[Configuration,Verify]indexterm:[Verify,Configuration] + [source,C] ----- # crm_verify --live-check ----- . Fix any errors or warnings . Perform the upgrade: + [source,C] ----- # cibadmin --upgrade ----- . If this step fails, there are three main possibilities: .. The configuration was not valid to start with - go back to step 2 .. The transformation failed - report a bug or mailto:pacemaker@oss.clusterlabs.org?subject=Transformation%20failed%20during%20upgrade[email the project] .. The transformation was successful but produced an invalid result footnote:[ The most common reason is ID values being repeated or invalid. Pacemaker 1.0 is much stricter regarding this type of validation. ] + If the result of the transformation is invalid, you may see a number of errors from the validation library. If these are not helpful, visit http://clusterlabs.org/wiki/Validation_FAQ and/or try the procedure described below under <> + . Check the changes + [source,C] ----- # crm_shadow --diff ----- + If at this point there is anything about the upgrade that you wish to fine-tune (for example, to change some of the automatic IDs) now is the time to do so. Since the shadow configuration is not in use by the cluster, it is safe to edit the file manually: + [source,C] ----- # crm_shadow --edit ----- + This will open the configuration in your favorite editor (whichever is specified by the standard +$EDITOR+ environment variable) + . Preview how the cluster will react + Test what the cluster will do when you upload the new configuration + [source,C] ------ # crm_simulate --live-check --save-dotfile upgrade06.dot -S # graphviz upgrade06.dot ------ + Verify that either no resource actions will occur or that you are happy with any that are scheduled. If the output contains actions you do not expect (possibly due to changes to the score calculations), you may need to make further manual changes. See <> for further details on how to interpret the output of `crm_simulate` + . Upload the changes + [source,C] ----- # crm_shadow --commit upgrade06 --force ----- If this step fails, something really strange has occurred. You should report a bug. [[s-upgrade-config-manual]] ==== Manually Upgrading the Configuration ==== indexterm:[Configuration,Upgrade manually] It is also possible to perform the configuration upgrade steps manually. To do this Locate the 'upgrade06.xsl' conversion script or download the latest version from https://github.com/ClusterLabs/pacemaker/tree/master/xml/upgrade06.xsl[Git] . Convert the XML blob: indexterm:[XML,Convert] + [source,C] ----- # xsltproc /path/to/upgrade06.xsl config06.xml > config10.xml ----- + . Locate the 'pacemaker.rng' script. . Check the XML validity: indexterm:[Validate Configuration]indexterm:[Configuration,Validate XML] + [source,C] # xmllint --relaxng /path/to/pacemaker.rng config10.xml The advantage of this method is that it can be performed without the cluster running and any validation errors should be more informative (despite being generated by the same library!) since they include line numbers. pacemaker-master/doc/Pacemaker_Explained/en-US/Ap-Upgrade.txt000066400000000000000000000140331217637305600243550ustar00rootroot00000000000000[appendix] [[ap-upgrade]] == Upgrading Cluster Software === Version Compatibility === When releasing newer versions we take care to make sure we are backwards compatible with older versions. While you will always be able to upgrade from version x to x+1, in order to continue to produce high quality software it may occasionally be necessary to drop compatibility with older versions. There will always be an upgrade path from any series-2 release to any other series-2 release. There are three approaches to upgrading your cluster software: * Complete Cluster Shutdown * Rolling (node by node) * Disconnect and Reattach Each method has advantages and disadvantages, some of which are listed in the table below, and you should chose the one most appropriate to your needs. .Summary of Upgrade Methodologies [width="95%",cols="6*",options="header",align="center"] |========================================================= |Type |Available between all software versions |Service Outage During Upgrade |Service Recovery During Upgrade |Exercises Failover Logic/Configuration |Allows change of cluster stack type indexterm:[Cluster,Switching between Stacks] indexterm:[Changing Cluster Stack] footnote:[ For example, switching from Heartbeat to Corosync. Consult the Heartbeat or Corosync documentation to see if upgrading them to a newer version is also supported. ] |Shutdown indexterm:[Upgrade,Shutdown] indexterm:[Shutdown Upgrade] |yes |always |N/A |no |yes |Rolling indexterm:[Upgrade,Rolling] indexterm:[Rolling Upgrade] |no |always |yes |yes |no |Reattach indexterm:[Upgrade,Reattach] indexterm:[Reattach Upgrade] |yes |only due to failure |no |no |yes |========================================================= === Complete Cluster Shutdown === In this scenario one shuts down all cluster nodes and resources and upgrades all the nodes before restarting the cluster. ==== Procedure ==== . On each node: .. Shutdown the cluster stack (Heartbeat or Corosync) .. Upgrade the Pacemaker software. This may also include upgrading the cluster stack and/or the underlying operating system. .. Check the configuration manually or with the `crm_verify` tool if available. . On each node: .. Start the cluster stack. This can be either Corosync or Heartbeat and does not need to be the same as the previous cluster stack. === Rolling (node by node) === In this scenario each node is removed from the cluster, upgraded and then brought back online until all nodes are running the newest version. [IMPORTANT] =========== This method is currently broken between Pacemaker 0.6.x and 1.0.x. Measures have been put into place to ensure rolling upgrades always work for versions after 1.0.0. Please try one of the other upgrade strategies. Detach/Reattach is a particularly good option for most people. =========== ==== Procedure ==== On each node: . Shutdown the cluster stack (Heartbeat or Corosync) . Upgrade the Pacemaker software. This may also include upgrading the cluster stack and/or the underlying operating system. .. On the first node, check the configuration manually or with the `crm_verify` tool if available. .. Start the cluster stack. + This must be the same type of cluster stack (Corosync or Heartbeat) that the rest of the cluster is using. Upgrading Corosync/Heartbeat may also be possible, please consult the documentation for those projects to see if the two versions will be compatible. + .. Repeat for each node in the cluster. ==== Version Compatibility ==== .Version Compatibility Table [width="95%",cols="2*",options="header",align="center"] |========================================================= |Version being Installed |Oldest Compatible Version |Pacemaker 1.0.x |Pacemaker 1.0.0 |Pacemaker 0.7.x |Pacemaker 0.6 or Heartbeat 2.1.3 |Pacemaker 0.6.x |Heartbeat 2.0.8 |Heartbeat 2.1.3 (or less) |Heartbeat 2.0.4 |Heartbeat 2.0.4 (or less) |Heartbeat 2.0.0 |Heartbeat 2.0.0 |None. Use an alternate upgrade strategy. |========================================================= ==== Crossing Compatibility Boundaries ==== Rolling upgrades that cross compatibility boundaries must be preformed in multiple steps. For example, to perform a rolling update from Heartbeat 2.0.1 to Pacemaker 0.6.6 one must: . Perform a rolling upgrade from Heartbeat 2.0.1 to Heartbeat 2.0.4 . Perform a rolling upgrade from Heartbeat 2.0.4 to Heartbeat 2.1.3 . Perform a rolling upgrade from Heartbeat 2.1.3 to Pacemaker 0.6.6 === Disconnect and Reattach === A variant of a complete cluster shutdown, but the resources are left active and get re-detected when the cluster is restarted. ==== Procedure ==== . Tell the cluster to stop managing services. + This is required to allow the services to remain active after the cluster shuts down. + [source,C] # crm_attribute -t crm_config -n is-managed-default -v false + . For any resource that has a value for +is-managed+, make sure it is set to +false+ (so that the cluster will not stop it) + [source,C] # crm_resource -t primitive -r $rsc_id -p is-managed -v false + . On each node: .. Shutdown the cluster stack (Heartbeat or Corosync) .. Upgrade the cluster stack program - This may also include upgrading the underlying operating system. . Check the configuration manually or with the `crm_verify` tool if available. . On each node: .. Start the cluster stack. + This can be either Corosync or Heartbeat and does not need to be the same as the previous cluster stack. + . Verify that the cluster re-detected all resources correctly. . Allow the cluster to resume managing resources again: + [source,C] # crm_attribute -t crm_config -n is-managed-default -v true + . For any resource that has a value for +is-managed+ reset it to +true+ (so the cluster can recover the service if it fails) if desired: + [source,C] # crm_resource -t primitive -r $rsc_id -p is-managed -v true ==== Notes ==== [IMPORTANT] =========== Always check your existing configuration is still compatible with the version you are installing before starting the cluster. =========== [NOTE] The oldest version of the CRM to support this upgrade type was in Heartbeat 2.0.4 pacemaker-master/doc/Pacemaker_Explained/en-US/Author_Group.xml000066400000000000000000000044041217637305600250300ustar00rootroot00000000000000 AndrewBeekhof Red Hat Primary author andrew@beekhof.net DanFrîncu Romanian translation df.cluster@gmail.com PhilippMarek LINBit Style and formatting updates. Indexing. philipp.marek@linbit.com TanjaRoth SUSE Utilization chapter Resource Templates chapter Multi-Site Clusters chapter taroth@suse.com LarsMarowsky-Bree SUSE Multi-Site Clusters chapter lmb@suse.com YanGao SUSE Utilization chapter Resource Templates chapter Multi-Site Clusters chapter ygao@suse.com ThomasSchraitle SUSE Utilization chapter Resource Templates chapter Multi-Site Clusters chapter toms@suse.com DejanMuhamedagic SUSE Resource Templates chapter dmuhamedagic@suse.com pacemaker-master/doc/Pacemaker_Explained/en-US/Book_Info.xml000066400000000000000000000035721217637305600242640ustar00rootroot00000000000000 Configuration Explained An A-Z guide to Pacemaker's Configuration Options Pacemaker 1.1 1 0 The purpose of this document is to definitively explain the concepts used to configure Pacemaker. To achieve this, it will focus exclusively on the XML syntax used to configure the CIB. For those that are allergic to XML, there exist several unified shells and GUIs for Pacemaker. However these tools will not be covered at all in this document I hope, however, that the concepts explained here make the functionality of these tools more easily understood. , precisely because they hide the XML. Additionally, this document is NOT a step-by-step how-to guide for configuring a specific clustering scenario. Although such guides exist, the purpose of this document is to provide an understanding of the building blocks that can be used to construct any type of Pacemaker cluster. Try the Clusters from Scratch document instead. pacemaker-master/doc/Pacemaker_Explained/en-US/Ch-Advanced-Options.txt000066400000000000000000000554121217637305600261240ustar00rootroot00000000000000= Advanced Configuration = [[s-remote-connection]] == Connecting from a Remote Machine == indexterm:[Cluster,Remote connection] indexterm:[Cluster,Remote administration] Provided Pacemaker is installed on a machine, it is possible to connect to the cluster even if the machine itself is not in the same cluster. To do this, one simply sets up a number of environment variables and runs the same commands as when working on a cluster node. .Environment Variables Used to Connect to Remote Instances of the CIB [width="95%",cols="1m,2<",options="header",align="center"] |========================================================= |Environment Variable |Description |CIB_user |The user to connect as. Needs to be part of the +hacluster+ group on the target host. Defaults to _$USER_. indexterm:[Environment Variable,CIB_user] |CIB_passwd |The user's password. Read from the command line if unset. indexterm:[Environment Variable,CIB_passwd] |CIB_server |The host to contact. Defaults to _localhost_. indexterm:[Environment Variable,CIB_server] |CIB_port |The port on which to contact the server; required. indexterm:[Environment Variable,CIB_port] |CIB_encrypted |Encrypt network traffic; defaults to _true_. indexterm:[Environment Variable,CIB_encrypted] |========================================================= So, if +c001n01+ is an active cluster node and is listening on +1234+ for connections, and +someguy+ is a member of the +hacluster+ group, then the following would prompt for +someguy+'s password and return the cluster's current configuration: [source,C] # export CIB_port=1234; export CIB_server=c001n01; export CIB_user=someguy; # cibadmin -Q For security reasons, the cluster does not listen for remote connections by default. If you wish to allow remote access, you need to set the +remote-tls-port+ (encrypted) or +remote-clear-port+ (unencrypted) top-level options (ie., those kept in the cib tag, like +num_updates+ and +epoch+). .Extra top-level CIB options for remote access [width="95%",cols="1m,2<",options="header",align="center"] |========================================================= |Field |Description |remote-tls-port |Listen for encrypted remote connections on this port. Default: _none_ indexterm:[remote-tls-port,Remote Connection Option] indexterm:[Remote Connection,Option,remote-tls-port] |remote-clear-port |Listen for plaintext remote connections on this port. Default: _none_ indexterm:[remote-clear-port,Remote Connection Option] indexterm:[Remote Connection,Option,remote-clear-port] |========================================================= [[s-recurring-start]] == Specifying When Recurring Actions are Performed == By default, recurring actions are scheduled relative to when the resource started. So if your resource was last started at 14:32 and you have a backup set to be performed every 24 hours, then the backup will always run at in the middle of the business day - hardly desirable. To specify a date/time that the operation should be relative to, set the operation's +interval-origin+. The cluster uses this point to calculate the correct +start-delay+ such that the operation will occur at _origin + (interval * N)_. So, if the operation's interval is 24h, it's interval-origin is set to +02:00+ and it is currently +14:32+, then the cluster would initiate the operation with a start delay of 11 hours and 28 minutes. If the resource is moved to another node before 2am, then the operation is of course cancelled. The value specified for interval and +interval-origin+ can be any date/time conforming to the http://en.wikipedia.org/wiki/ISO_8601[ISO8601 standard]. By way of example, to specify an operation that would run on the first Monday of 2009 and every Monday after that you would add: .Specifying a Base for Recurring Action Intervals ===== [source,XML] ===== == Moving Resources == indexterm:[Moving,Resources] indexterm:[Resource,Moving] === Manual Intervention === There are primarily two occasions when you would want to move a resource from it's current location: when the whole node is under maintenance, and when a single resource needs to be moved. Since everything eventually comes down to a score, you could create constraints for every resource to prevent them from running on one node. While the configuration can seem convoluted at times, not even we would require this of administrators. Instead one can set a special node attribute which tells the cluster "don't let anything run here". There is even a helpful tool to help query and set it, called `crm_standby`. To check the standby status of the current machine, simply run: [source,C] # crm_standby --get-value A value of +true+ indicates that the node is _NOT_ able to host any resources, while a value of +false+ says that it _CAN_. You can also check the status of other nodes in the cluster by specifying the `--node-uname` option: [source,C] # crm_standby --get-value --node-uname sles-2 To change the current node's standby status, use `--attr-value` instead of `--get-value`. [source,C] # crm_standby --attr-value Again, you can change another host's value by supplying a host name with `--node-uname`. When only one resource is required to move, we do this by creating location constraints. However, once again we provide a user friendly shortcut as part of the `crm_resource` command, which creates and modifies the extra constraints for you. If +Email+ was running on +sles-1+ and you wanted it moved to a specific location, the command would look something like: [source,C] # crm_resource -M -r Email -H sles-2 Behind the scenes, the tool will create the following location constraint: [source,XML] It is important to note that subsequent invocations of `crm_resource -M` are not cumulative. So, if you ran these commands [source,C] # crm_resource -M -r Email -H sles-2 # crm_resource -M -r Email -H sles-3 then it is as if you had never performed the first command. To allow the resource to move back again, use: [source,C] # crm_resource -U -r Email Note the use of the word _allow_. The resource can move back to its original location but, depending on +resource-stickiness+, it might stay where it is. To be absolutely certain that it moves back to +sles-1+, move it there before issuing the call to `crm_resource -U`: [source,C] # crm_resource -M -r Email -H sles-1 # crm_resource -U -r Email Alternatively, if you only care that the resource should be moved from its current location, try [source,C] # crm_resource -M -r Email` Which will instead create a negative constraint, like [source,XML] This will achieve the desired effect, but will also have long-term consequences. As the tool will warn you, the creation of a +-INFINITY+ constraint will prevent the resource from running on that node until `crm_resource -U` is used. This includes the situation where every other cluster node is no longer available! In some cases, such as when +resource-stickiness+ is set to +INFINITY+, it is possible that you will end up with the problem described in <>. The tool can detect some of these cases and deals with them by also creating both a positive and negative constraint. Eg. +Email+ prefers +sles-1+ with a score of +-INFINITY+ +Email+ prefers +sles-2+ with a score of +INFINITY+ which has the same long-term consequences as discussed earlier. [[s-failure-migration]] === Moving Resources Due to Failure === New in 1.0 is the concept of a migration threshold. footnote:[ The naming of this option was perhaps unfortunate as it is easily confused with true migration, the process of moving a resource from one node to another without stopping it. Xen virtual guests are the most common example of resources that can be migrated in this manner. ] Simply define +migration-threshold=N+ for a resource and it will migrate to a new node after N failures. There is no threshold defined by default. To determine the resource's current failure status and limits, use `crm_mon --failcounts`. By default, once the threshold has been reached, this node will no longer be allowed to run the failed resource until the administrator manually resets the resource's failcount using `crm_failcount` (after hopefully first fixing the failure's cause). However it is possible to expire them by setting the resource's +failure-timeout+ option. So a setting of +migration-threshold=2+ and +failure-timeout=60s+ would cause the resource to move to a new node after 2 failures, and allow it to move back (depending on the stickiness and constraint scores) after one minute. There are two exceptions to the migration threshold concept; they occur when a resource either fails to start or fails to stop. Start failures cause the failcount to be set to +INFINITY+ and thus always cause the resource to move immediately. Stop failures are slightly different and crucial. If a resource fails to stop and STONITH is enabled, then the cluster will fence the node in order to be able to start the resource elsewhere. If STONITH is not enabled, then the cluster has no way to continue and will not try to start the resource elsewhere, but will try to stop it again after the failure timeout. [IMPORTANT] Please read <> before enabling this option. === Moving Resources Due to Connectivity Changes === Setting up the cluster to move resources when external connectivity is lost is a two-step process. ==== Tell Pacemaker to monitor connectivity ==== To do this, you need to add a +ping+ resource to the cluster. The +ping+ resource uses the system utility of the same name to a test if list of machines (specified by DNS hostname or IPv4/IPv6 address) are reachable and uses the results to maintain a node attribute normally called +pingd+. footnote:[ The attribute name is customizable; that allows multiple ping groups to be defined. ] [NOTE] Older versions of Heartbeat required users to add ping nodes to _ha.cf_ - this is no longer required. [IMPORTANT] =========== Older versions of Pacemaker used a custom binary called 'pingd' for this functionality; this is now deprecated in favor of 'ping'. If your version of Pacemaker does not contain the ping agent, you can download the latest version from https://github.com/ClusterLabs/pacemaker/tree/master/extra/resources/ping =========== Normally the resource will run on all cluster nodes, which means that you'll need to create a clone. A template for this can be found below along with a description of the most interesting parameters. .Common Options for a 'ping' Resource [width="95%",cols="1m,4<",options="header",align="center"] |========================================================= |Field |Description |dampen |The time to wait (dampening) for further changes to occur. Use this to prevent a resource from bouncing around the cluster when cluster nodes notice the loss of connectivity at slightly different times. indexterm:[dampen,Ping Resource Option] indexterm:[Ping Resource,Option,dampen] |multiplier |The number of connected ping nodes gets multiplied by this value to get a score. Useful when there are multiple ping nodes configured. indexterm:[multiplier,Ping Resource Option] indexterm:[Ping Resource,Option,multiplier] |host_list |The machines to contact in order to determine the current connectivity status. Allowed values include resolvable DNS host names, IPv4 and IPv6 addresses. indexterm:[host_list,Ping Resource Option] indexterm:[Ping Resource,Option,host_list] |========================================================= .An example ping cluster resource that checks node connectivity once every minute ===== [source,XML] ------------ ------------ ===== [IMPORTANT] =========== You're only half done. The next section deals with telling Pacemaker how to deal with the connectivity status that +ocf:pacemaker:ping+ is recording. =========== ==== Tell Pacemaker how to interpret the connectivity data ==== [NOTE] ====== Before reading the following, please make sure you have read and understood <> above. ====== There are a number of ways to use the connectivity data provided by Heartbeat. The most common setup is for people to have a single ping node, to prevent the cluster from running a resource on any unconnected node. //// TODO: is the idea that only nodes that can reach eg. the router should have active resources? //// .Don't run on unconnected nodes ===== [source,XML] ------- ------- ===== A more complex setup is to have a number of ping nodes configured. You can require the cluster to only run resources on nodes that can connect to all (or a minimum subset) of them. .Run only on nodes connected to three or more ping nodes; this assumes +multiplier+ is set to 1000: ===== [source,XML] ------- ------- ===== Instead you can tell the cluster only to _prefer_ nodes with the best connectivity. Just be sure to set +multiplier+ to a value higher than that of +resource-stickiness+ (and don't set either of them to +INFINITY+). .Prefer the node with the most connected ping nodes ===== [source,XML] ------- ------- ===== It is perhaps easier to think of this in terms of the simple constraints that the cluster translates it into. For example, if +sles-1+ is connected to all 5 ping nodes but +sles-2+ is only connected to 2, then it would be as if you instead had the following constraints in your configuration: .How the cluster translates the pingd constraint ===== [source,XML] ------- ------- ===== The advantage is that you don't have to manually update any constraints whenever your network connectivity changes. You can also combine the concepts above into something even more complex. The example below shows how you can prefer the node with the most connected ping nodes provided they have connectivity to at least three (again assuming that +multiplier+ is set to 1000). .A more complex example of choosing a location based on connectivity ===== [source,XML] ------- ------- ===== === Resource Migration === Some resources, such as Xen virtual guests, are able to move to another location without loss of state. We call this resource migration; this is different from the normal practice of stopping the resource on the first machine and starting it elsewhere. Not all resources are able to migrate, see the Migration Checklist below, and those that can, won't do so in all situations. Conceptually there are two requirements from which the other prerequisites follow: * the resource must be active and healthy at the old location * everything required for the resource to run must be available on both the old and new locations The cluster is able to accommodate both push and pull migration models by requiring the resource agent to support two new actions: +migrate_to+ (performed on the current location) and +migrate_from+ (performed on the destination). In push migration, the process on the current location transfers the resource to the new location where is it later activated. In this scenario, most of the work would be done in the +migrate_to+ action and, if anything, the activation would occur during +migrate_from+. Conversely for pull, the +migrate_to+ action is practically empty and +migrate_from+ does most of the work, extracting the relevant resource state from the old location and activating it. There is no wrong or right way to implement migration for your service, as long as it works. ==== Migration Checklist ==== * The resource may not be a clone. * The resource must use an OCF style agent. * The resource must not be in a failed or degraded state. * The resource must not, directly or indirectly, depend on any primitive or group resources. * The resource must support two new actions: +migrate_to+ and +migrate_from+, and advertise them in its metadata. * The resource must have the +allow-migrate+ meta-attribute set to +true+ (which is not the default). //// TODO: how can a KVM with DRBD migrate? //// If the resource depends on a clone, and at the time the resource needs to be move, the clone has instances that are stopping and instances that are starting, then the resource will be moved in the traditional manner. The Policy Engine is not yet able to model this situation correctly and so takes the safe (yet less optimal) path. [[s-reusing-config-elements]] == Reusing Rules, Options and Sets of Operations == Sometimes a number of constraints need to use the same set of rules, and resources need to set the same options and parameters. To simplify this situation, you can refer to an existing object using an +id-ref+ instead of an id. So if for one resource you have [source,XML] ------ ------ Then instead of duplicating the rule for all your other resources, you can instead specify: .Referencing rules from other constraints ===== [source,XML] ------- ------- ===== [IMPORTANT] =========== The cluster will insist that the +rule+ exists somewhere. Attempting to add a reference to a non-existing rule will cause a validation failure, as will attempting to remove a +rule+ that is referenced elsewhere. =========== The same principle applies for +meta_attributes+ and +instance_attributes+ as illustrated in the example below: .Referencing attributes, options, and operations from other resources ===== [source,XML] ------- ------- ===== == Reloading Services After a Definition Change == The cluster automatically detects changes to the definition of services it manages. However, the normal response is to stop the service (using the old definition) and start it again (with the new definition). This works well, but some services are smarter and can be told to use a new set of options without restarting. To take advantage of this capability, your resource agent must: . Accept the +reload+ operation and perform any required actions. _The steps required here depend completely on your application!_ + .The DRBD Agent's Control logic for Supporting the +reload+ Operation ===== [source,Bash] ------- case $1 in start) drbd_start ;; stop) drbd_stop ;; reload) drbd_reload ;; monitor) drbd_monitor ;; *) drbd_usage exit $OCF_ERR_UNIMPLEMENTED ;; esac exit $? ------- ===== . Advertise the +reload+ operation in the +actions+ section of its metadata + .The DRBD Agent Advertising Support for the +reload+ Operation ===== [source,XML] ------- 1.1 Master/Slave OCF Resource Agent for DRBD ... ------- ===== . Advertise one or more parameters that can take effect using +reload+. + Any parameter with the +unique+ set to 0 is eligible to be used in this way. + .Parameter that can be changed using reload ===== [source,XML] ------- Full path to the drbd.conf file. Path to drbd.conf ------- ===== Once these requirements are satisfied, the cluster will automatically know to reload the resource (instead of restarting) when a non-unique fields changes. [NOTE] ====== The metadata is re-read when the resource is started. This may mean that the resource will be restarted the first time, even though you changed a parameter with +unique=0+ ====== [NOTE] ====== If both a unique and non-unique field are changed simultaneously, the resource will still be restarted. ====== pacemaker-master/doc/Pacemaker_Explained/en-US/Ch-Advanced-Resources.txt000066400000000000000000001050741217637305600264430ustar00rootroot00000000000000= Advanced Resource Types = [[group-resources]] == Groups - A Syntactic Shortcut == indexterm:[Group Resources] indexterm:[Resources,Groups] One of the most common elements of a cluster is a set of resources that need to be located together, start sequentially, and stop in the reverse order. To simplify this configuration we support the concept of groups. .An example group ====== [source,XML] ------- ------- ====== Although the example above contains only two resources, there is no limit to the number of resources a group can contain. The example is also sufficient to explain the fundamental properties of a group: * Resources are started in the order they appear in (+Public-IP+ first, then +Email+) * Resources are stopped in the reverse order to which they appear in (+Email+ first, then +Public-IP+) If a resource in the group can't run anywhere, then nothing after that is allowed to run, too. * If +Public-IP+ can't run anywhere, neither can +Email+; * but if +Email+ can't run anywhere, this does not affect +Public-IP+ in any way The group above is logically equivalent to writing: .How the cluster sees a group resource ====== [source,XML] ------- ------- ====== Obviously as the group grows bigger, the reduced configuration effort can become significant. Another (typical) example of a group is a DRBD volume, the filesystem mount, an IP address, and an application that uses them. === Group Properties === .Properties of a Group Resource [width="95%",cols="3m,5<",options="header",align="center"] |========================================================= |Field |Description |id |Your name for the group indexterm:[id,Group Resource Property] indexterm:[Resource,Group Property,id] |========================================================= === Group Options === Options inherited from <> resources: +priority, target-role, is-managed+ === Group Instance Attributes === Groups have no instance attributes, however any that are set here will be inherited by the group's children. === Group Contents === Groups may only contain a collection of <> cluster resources. To refer to the child of a group resource, just use the child's id instead of the group's. === Group Constraints === Although it is possible to reference the group's children in constraints, it is usually preferable to use the group's name instead. .Example constraints involving groups ====== [source,XML] ------- ------- ====== === Group Stickiness === indexterm:[resource-stickiness,Groups] Stickiness, the measure of how much a resource wants to stay where it is, is additive in groups. Every active resource of the group will contribute its stickiness value to the group's total. So if the default +resource-stickiness+ is 100, and a group has seven members, five of which are active, then the group as a whole will prefer its current location with a score of 500. [[s-resource-clone]] == Clones - Resources That Get Active on Multiple Hosts == indexterm:[Clone Resources] indexterm:[Resources,Clones] Clones were initially conceived as a convenient way to start N instances of an IP resource and have them distributed throughout the cluster for load balancing. They have turned out to quite useful for a number of purposes including integrating with Red Hat's DLM, the fencing subsystem, and OCFS2. You can clone any resource, provided the resource agent supports it. Three types of cloned resources exist: * Anonymous * Globally Unique * Stateful Anonymous clones are the simplest type. These resources behave completely identically everywhere they are running. Because of this, there can only be one copy of an anonymous clone active per machine. Globally unique clones are distinct entities. A copy of the clone running on one machine is not equivalent to another instance on another node. Nor would any two copies on the same node be equivalent. Stateful clones are covered later in <>. .An example clone ====== [source,XML] ------- ------- ====== === Clone Properties === .Properties of a Clone Resource [width="95%",cols="3m,5<",options="header",align="center"] |========================================================= |Field |Description |id |Your name for the clone indexterm:[id,Clone Property] indexterm:[Clone,Property,id] |========================================================= === Clone Options === Options inherited from <> resources: +priority, target-role, is-managed+ .Clone specific configuration options [width="95%",cols="3m,5<",options="header",align="center"] |========================================================= |Field |Description |clone-max |How many copies of the resource to start. Defaults to the number of nodes in the cluster. indexterm:[clone-max,Clone Option] indexterm:[Clone,Option,clone-max] |clone-node-max |How many copies of the resource can be started on a single node; default _1_. indexterm:[clone-node-max,Clone Option] indexterm:[Clone,Option,clone-node-max] |notify |When stopping or starting a copy of the clone, tell all the other copies beforehand and when the action was successful. Allowed values: _false_, +true+ indexterm:[notify,Clone Option] indexterm:[Clone,Option,notify] |globally-unique |Does each copy of the clone perform a different function? Allowed values: _false_, +true+ indexterm:[globally-unique,Clone Option] indexterm:[Clone,Option,globally-unique] |ordered |Should the copies be started in series (instead of in parallel). Allowed values: _false_, +true+ indexterm:[ordered,Clone Option] indexterm:[Clone,Option,ordered] |interleave |Changes the behavior of ordering constraints (between clones/masters) so that instances can start/stop as soon as their peer instance has (rather than waiting for every instance of the other clone has). Allowed values: _false_, +true+ indexterm:[interleave,Clone Option] indexterm:[Clone,Option,interleave] |========================================================= === Clone Instance Attributes === Clones have no instance attributes; however, any that are set here will be inherited by the clone's children. === Clone Contents === Clones must contain exactly one group or one regular resource. [WARNING] You should never reference the name of a clone's child. If you think you need to do this, you probably need to re-evaluate your design. === Clone Constraints === In most cases, a clone will have a single copy on each active cluster node. If this is not the case, you can indicate which nodes the cluster should preferentially assign copies to with resource location constraints. These constraints are written no differently to those for regular resources except that the clone's id is used. Ordering constraints behave slightly differently for clones. In the example below, +apache-stats+ will wait until all copies of the clone that need to be started have done so before being started itself. Only if _no_ copies can be started +apache-stats+ will be prevented from being active. Additionally, the clone will wait for +apache-stats+ to be stopped before stopping the clone. Colocation of a regular (or group) resource with a clone means that the resource can run on any machine with an active copy of the clone. The cluster will choose a copy based on where the clone is running and the resource's own location preferences. Colocation between clones is also possible. In such cases, the set of allowed locations for the clone is limited to nodes on which the clone is (or will be) active. Allocation is then performed as normally. .Example constraints involving clones ====== [source,XML] ------- ------- ====== === Clone Stickiness === indexterm:[resource-stickiness,Clones] To achieve a stable allocation pattern, clones are slightly sticky by default. If no value for +resource-stickiness+ is provided, the clone will use a value of 1. Being a small value, it causes minimal disturbance to the score calculations of other resources but is enough to prevent Pacemaker from needlessly moving copies around the cluster. === Clone Resource Agent Requirements === Any resource can be used as an anonymous clone, as it requires no additional support from the resource agent. Whether it makes sense to do so depends on your resource and its resource agent. Globally unique clones do require some additional support in the resource agent. In particular, it must only respond with +${OCF_SUCCESS}+ if the node has that exact instance active. All other probes for instances of the clone should result in +${OCF_NOT_RUNNING}+. Unless of course they are failed, in which case they should return one of the other OCF error codes. Copies of a clone are identified by appending a colon and a numerical offset, eg. +apache:2+. Resource agents can find out how many copies there are by examining the +OCF_RESKEY_CRM_meta_clone_max+ environment variable and which copy it is by examining +OCF_RESKEY_CRM_meta_clone+. You should not make any assumptions (based on +OCF_RESKEY_CRM_meta_clone+) about which copies are active. In particular, the list of active copies will not always be an unbroken sequence, nor always start at 0. ==== Clone Notifications ==== Supporting notifications requires the +notify+ action to be implemented. Once supported, the notify action will be passed a number of extra variables which, when combined with additional context, can be used to calculate the current state of the cluster and what is about to happen to it. .Environment variables supplied with Clone notify actions [width="95%",cols="5,3<",options="header",align="center"] |========================================================= |Variable |Description |OCF_RESKEY_CRM_meta_notify_type |Allowed values: +pre+, +post+ indexterm:[Environment Variable,OCF_RESKEY_CRM_meta_notify_,type] indexterm:[type,Notification Environment Variable] |OCF_RESKEY_CRM_meta_notify_operation |Allowed values: +start+, +stop+ indexterm:[Environment Variable,OCF_RESKEY_CRM_meta_notify_,operation] indexterm:[operation,Notification Environment Variable] |OCF_RESKEY_CRM_meta_notify_start_resource |Resources to be started indexterm:[Environment Variable,OCF_RESKEY_CRM_meta_notify_,start_resource] indexterm:[start_resource,Notification Environment Variable] |OCF_RESKEY_CRM_meta_notify_stop_resource |Resources to be stopped indexterm:[Environment Variable,OCF_RESKEY_CRM_meta_notify_,stop_resource] indexterm:[stop_resource,Notification Environment Variable] |OCF_RESKEY_CRM_meta_notify_active_resource |Resources that are running indexterm:[Environment Variable,OCF_RESKEY_CRM_meta_notify_,active_resource] indexterm:[active_resource,Notification Environment Variable] |OCF_RESKEY_CRM_meta_notify_inactive_resource |Resources that are not running indexterm:[Environment Variable,OCF_RESKEY_CRM_meta_notify_,inactive_resource] indexterm:[inactive_resource,Notification Environment Variable] |OCF_RESKEY_CRM_meta_notify_start_uname |Nodes on which resources will be started indexterm:[Environment Variable,OCF_RESKEY_CRM_meta_notify_,start_uname] indexterm:[start_uname,Notification Environment Variable] |OCF_RESKEY_CRM_meta_notify_stop_uname |Nodes on which resources will be stopped indexterm:[Environment Variable,OCF_RESKEY_CRM_meta_notify_,stop_uname] indexterm:[stop_uname,Notification Environment Variable] |OCF_RESKEY_CRM_meta_notify_active_uname |Nodes on which resources are running indexterm:[Environment Variable,OCF_RESKEY_CRM_meta_notify_,active_uname] indexterm:[active_uname,Notification Environment Variable] |OCF_RESKEY_CRM_meta_notify_inactive_uname |Nodes on which resources are not running indexterm:[Environment Variable,OCF_RESKEY_CRM_meta_notify_,inactive_uname] indexterm:[inactive_uname,Notification Environment Variable] |========================================================= The variables come in pairs, such as +OCF_RESKEY_CRM_meta_notify_start_resource+ and +OCF_RESKEY_CRM_meta_notify_start_uname+ and should be treated as an array of whitespace separated elements. Thus in order to indicate that +clone:0+ will be started on +sles-1+, +clone:2+ will be started on +sles-3+, and +clone:3+ will be started on +sles-2+, the cluster would set .Example notification variables ====== [source,Bash] ------- OCF_RESKEY_CRM_meta_notify_start_resource="clone:0 clone:2 clone:3" OCF_RESKEY_CRM_meta_notify_start_uname="sles-1 sles-3 sles-2" ------- ====== ==== Proper Interpretation of Notification Environment Variables ==== .Pre-notification (stop): * Active resources: +$OCF_RESKEY_CRM_meta_notify_active_resource+ * Inactive resources: +$OCF_RESKEY_CRM_meta_notify_inactive_resource+ * Resources to be started: +$OCF_RESKEY_CRM_meta_notify_start_resource+ * Resources to be stopped: +$OCF_RESKEY_CRM_meta_notify_stop_resource+ .Post-notification (stop) / Pre-notification (start): * Active resources ** +$OCF_RESKEY_CRM_meta_notify_active_resource+ ** minus +$OCF_RESKEY_CRM_meta_notify_stop_resource+ * Inactive resources ** +$OCF_RESKEY_CRM_meta_notify_inactive_resource+ ** plus +$OCF_RESKEY_CRM_meta_notify_stop_resource+ * Resources that were started: +$OCF_RESKEY_CRM_meta_notify_start_resource+ * Resources that were stopped: +$OCF_RESKEY_CRM_meta_notify_stop_resource+ .Post-notification (start): * Active resources: ** +$OCF_RESKEY_CRM_meta_notify_active_resource+ ** minus +$OCF_RESKEY_CRM_meta_notify_stop_resource+ ** plus +$OCF_RESKEY_CRM_meta_notify_start_resource+ * Inactive resources: ** +$OCF_RESKEY_CRM_meta_notify_inactive_resource+ ** plus +$OCF_RESKEY_CRM_meta_notify_stop_resource+ ** minus +$OCF_RESKEY_CRM_meta_notify_start_resource+ * Resources that were started: +$OCF_RESKEY_CRM_meta_notify_start_resource+ * Resources that were stopped: +$OCF_RESKEY_CRM_meta_notify_stop_resource+ [[s-resource-multistate]] == Multi-state - Resources That Have Multiple Modes == indexterm:[Multi-state Resources] indexterm:[Resources,Multi-state] Multi-state resources are a specialization of Clone resources; please ensure you understand the section on clones before continuing! They allow the instances to be in one of two operating modes; these are called +Master+ and +Slave+, but can mean whatever you wish them to mean. The only limitation is that when an instance is started, it must come up in the +Slave+ state. === Multi-state Properties === .Properties of a Multi-State Resource [width="95%",cols="3m,5<",options="header",align="center"] |========================================================= |Field |Description |id |Your name for the multi-state resource indexterm:[id,Multi-State Property] indexterm:[Multi-State,Property,id] |========================================================= === Multi-state Options === Options inherited from <> resources: +priority+, +target-role+, +is-managed+ Options inherited from <> resources: +clone-max+, +clone-node-max+, +notify+, +globally-unique+, +ordered+, +interleave+ .Multi-state specific resource configuration options [width="95%",cols="3m,5<",options="header",align="center"] |========================================================= |Field |Description |master-max |How many copies of the resource can be promoted to +master+ status; default 1. indexterm:[master-max,Multi-State Option] indexterm:[Multi-State,Option,master-max] |master-node-max |How many copies of the resource can be promoted to +master+ status on a single node; default 1. indexterm:[master-node-max,Multi-State Option] indexterm:[Multi-State,Option,master-node-max] |========================================================= === Multi-state Instance Attributes === Multi-state resources have no instance attributes; however, any that are set here will be inherited by master's children. === Multi-state Contents === Masters must contain exactly one group or one regular resource. [WARNING] You should never reference the name of a master's child. If you think you need to do this, you probably need to re-evaluate your design. === Monitoring Multi-State Resources === The normal type of monitor actions are not sufficient to monitor a multi-state resource in the +Master+ state. To detect failures of the +Master+ instance, you need to define an additional monitor action with +role="Master"+. [IMPORTANT] =========== It is crucial that _every_ monitor operation has a different interval! This is because Pacemaker currently differentiates between operations only by resource and interval; so if eg. a master/slave resource has the same monitor interval for both roles, Pacemaker would ignore the role when checking the status - which would cause unexpected return codes, and therefore unnecessary complications. =========== .Monitoring both states of a multi-state resource ====== [source,XML] ------- ------- ====== === Multi-state Constraints === In most cases, a multi-state resources will have a single copy on each active cluster node. If this is not the case, you can indicate which nodes the cluster should preferentially assign copies to with resource location constraints. These constraints are written no differently to those for regular resources except that the master's id is used. When considering multi-state resources in constraints, for most purposes it is sufficient to treat them as clones. The exception is when the +rsc-role+ and/or +with-rsc-role+ fields (for colocation constraints) and +first-action+ and/or +then-action+ fields (for ordering constraints) are used. .Additional constraint options relevant to multi-state resources [width="95%",cols="3m,5<",options="header",align="center"] |========================================================= |Field |Description |rsc-role |An additional attribute of colocation constraints that specifies the role that +rsc+ must be in. Allowed values: _Started_, +Master+, +Slave+. indexterm:[rsc-role,Ordering Constraints] indexterm:[Constraints,Ordering,rsc-role] |with-rsc-role |An additional attribute of colocation constraints that specifies the role that +with-rsc+ must be in. Allowed values: _Started_, +Master+, +Slave+. indexterm:[with-rsc-role,Ordering Constraints] indexterm:[Constraints,Ordering,with-rsc-role] |first-action |An additional attribute of ordering constraints that specifies the action that the +first+ resource must complete before executing the specified action for the +then+ resource. Allowed values: _start_, +stop+, +promote+, +demote+. indexterm:[first-action,Ordering Constraints] indexterm:[Constraints,Ordering,first-action] |then-action |An additional attribute of ordering constraints that specifies the action that the +then+ resource can only execute after the +first-action+ on the +first+ resource has completed. Allowed values: +start+, +stop+, +promote+, +demote+. Defaults to the value (specified or implied) of +first-action+. indexterm:[then-action,Ordering Constraints] indexterm:[Constraints,Ordering,then-action] |========================================================= In the example below, +myApp+ will wait until one of the database copies has been started and promoted to master before being started itself. Only if no copies can be promoted will +apache-stats+ be prevented from being active. Additionally, the database will wait for +myApp+ to be stopped before it is demoted. .Example constraints involving multi-state resources ====== [source,XML] ------- ------- ====== Colocation of a regular (or group) resource with a multi-state resource means that it can run on any machine with an active copy of the multi-state resource that is in the specified state (+Master+ or +Slave+). In the example, the cluster will choose a location based on where database is running as a +Master+, and if there are multiple +Master+ instances it will also factor in +myApp+'s own location preferences when deciding which location to choose. Colocation with regular clones and other multi-state resources is also possible. In such cases, the set of allowed locations for the +rsc+ clone is (after role filtering) limited to nodes on which the +with-rsc+ multi-state resource is (or will be) in the specified role. Allocation is then performed as-per-normal. === Multi-state Stickiness === indexterm:[resource-stickiness,Multi-State] To achieve a stable allocation pattern, multi-state resources are slightly sticky by default. If no value for +resource-stickiness+ is provided, the multi-state resource will use a value of 1. Being a small value, it causes minimal disturbance to the score calculations of other resources but is enough to prevent Pacemaker from needlessly moving copies around the cluster. === Which Resource Instance is Promoted === During the start operation, most Resource Agent scripts should call the `crm_master` utility. This tool automatically detects both the resource and host and should be used to set a preference for being promoted. Based on this, +master-max+, and +master-node-max+, the instance(s) with the highest preference will be promoted. The other alternative is to create a location constraint that indicates which nodes are most preferred as masters. .Manually specifying which node should be promoted ====== [source,XML] ------- ------- ====== === Multi-state Resource Agent Requirements === Since multi-state resources are an extension of cloned resources, all the requirements of Clones are also requirements of multi-state resources. Additionally, multi-state resources require two extra actions: +demote+ and +promote+; these actions are responsible for changing the state of the resource. Like +start+ and +stop+, they should return +OCF_SUCCESS+ if they completed successfully or a relevant error code if they did not. The states can mean whatever you wish, but when the resource is started, it must come up in the mode called +Slave+. From there the cluster will then decide which instances to promote to +Master+. In addition to the Clone requirements for monitor actions, agents must also _accurately_ report which state they are in. The cluster relies on the agent to report its status (including role) accurately and does not indicate to the agent what role it currently believes it to be in. .Role implications of OCF return codes [width="95%",cols="5,3<",options="header",align="center"] |========================================================= |Monitor Return Code |Description |OCF_NOT_RUNNING |Stopped indexterm:[Return Code,OCF_NOT_RUNNING] |OCF_SUCCESS |Running (Slave) indexterm:[Return Code,OCF_SUCCESS] |OCF_RUNNING_MASTER |Running (Master) indexterm:[Return Code,OCF_RUNNING_MASTER] |OCF_FAILED_MASTER |Failed (Master) indexterm:[Return Code,OCF_FAILED_MASTER] |Other |Failed (Slave) |========================================================= === Multi-state Notifications === Like clones, supporting notifications requires the +notify+ action to be implemented. Once supported the notify action will be passed a number of extra variables which, when combined with additional context, can be used to calculate the current state of the cluster and what is about to happen to it. .Environment variables supplied with Master notify actions footnote:[Emphasized variables are specific to +Master+ resources and all behave in the same manner as described for Clone resources.] [width="95%",cols="5,3<",options="header",align="center"] |========================================================= |Variable |Description |OCF_RESKEY_CRM_meta_notify_type |Allowed values: +pre+, +post+ indexterm:[Environment Variable,OCF_RESKEY_CRM_meta_notify_,type] indexterm:[type,Notification Environment Variable] |OCF_RESKEY_CRM_meta_notify_operation |Allowed values: +start+, +stop+ indexterm:[Environment Variable,OCF_RESKEY_CRM_meta_notify_,operation] indexterm:[operation,Notification Environment Variable] |OCF_RESKEY_CRM_meta_notify_active_resource |Resources the that are running indexterm:[Environment Variable,OCF_RESKEY_CRM_meta_notify_,active_resource] indexterm:[active_resource,Notification Environment Variable] |OCF_RESKEY_CRM_meta_notify_inactive_resource |Resources the that are not running indexterm:[Environment Variable,OCF_RESKEY_CRM_meta_notify_,inactive_resource] indexterm:[inactive_resource,Notification Environment Variable] |_OCF_RESKEY_CRM_meta_notify_master_resource_ |Resources that are running in +Master+ mode indexterm:[Environment Variable,OCF_RESKEY_CRM_meta_notify_,master_resource] indexterm:[master_resource,Notification Environment Variable] |_OCF_RESKEY_CRM_meta_notify_slave_resource_ |Resources that are running in +Slave+ mode indexterm:[Environment Variable,OCF_RESKEY_CRM_meta_notify_,slave_resource] indexterm:[slave_resource,Notification Environment Variable] |OCF_RESKEY_CRM_meta_notify_start_resource |Resources to be started indexterm:[Environment Variable,OCF_RESKEY_CRM_meta_notify_,start_resource] indexterm:[start_resource,Notification Environment Variable] |indexterm:[Environment Variable,OCF_RESKEY_CRM_meta_notify_,stop_resource] indexterm:[stop_resource,Notification Environment Variable] OCF_RESKEY_CRM_meta_notify_stop_resource |Resources to be stopped |_OCF_RESKEY_CRM_meta_notify_promote_resource_ |Resources to be promoted indexterm:[Environment Variable,OCF_RESKEY_CRM_meta_notify_,promote_resource] indexterm:[promote_resource,Notification Environment Variable] |_OCF_RESKEY_CRM_meta_notify_demote_resource_ |Resources to be demoted indexterm:[Environment Variable,OCF_RESKEY_CRM_meta_notify_,demote_resource] indexterm:[demote_resource,Notification Environment Variable] |OCF_RESKEY_CRM_meta_notify_start_uname |Nodes on which resources will be started indexterm:[Environment Variable,OCF_RESKEY_CRM_meta_notify_,start_uname] indexterm:[start_uname,Notification Environment Variable] |OCF_RESKEY_CRM_meta_notify_stop_uname |Nodes on which resources will be stopped indexterm:[Environment Variable,OCF_RESKEY_CRM_meta_notify_,stop_uname] indexterm:[stop_uname,Notification Environment Variable] |_OCF_RESKEY_CRM_meta_notify_promote_uname_ |Nodes on which resources will be promote indexterm:[Environment Variable,OCF_RESKEY_CRM_meta_notify_,promote_uname] indexterm:[promote_uname,Notification Environment Variable] |_OCF_RESKEY_CRM_meta_notify_demote_uname_ |Nodes on which resources will be demoted indexterm:[Environment Variable,OCF_RESKEY_CRM_meta_notify_,demote_uname] indexterm:[demote_uname,Notification Environment Variable] |OCF_RESKEY_CRM_meta_notify_active_uname |Nodes on which resources are running indexterm:[Environment Variable,OCF_RESKEY_CRM_meta_notify_,active_uname] indexterm:[active_uname,Notification Environment Variable] |OCF_RESKEY_CRM_meta_notify_inactive_uname |Nodes on which resources are not running indexterm:[Environment Variable,OCF_RESKEY_CRM_meta_notify_,inactive_uname] indexterm:[inactive_uname,Notification Environment Variable] |_OCF_RESKEY_CRM_meta_notify_master_uname_ |Nodes on which resources are running in +Master+ mode indexterm:[Environment Variable,OCF_RESKEY_CRM_meta_notify_,master_uname] indexterm:[master_uname,Notification Environment Variable] |_OCF_RESKEY_CRM_meta_notify_slave_uname_ |Nodes on which resources are running in +Slave+ mode indexterm:[Environment Variable,OCF_RESKEY_CRM_meta_notify_,slave_uname] indexterm:[slave_uname,Notification Environment Variable] |========================================================= === Multi-state - Proper Interpretation of Notification Environment Variables === .Pre-notification (demote): * +Active+ resources: +$OCF_RESKEY_CRM_meta_notify_active_resource+ * +Master+ resources: +$OCF_RESKEY_CRM_meta_notify_master_resource+ * +Slave+ resources: +$OCF_RESKEY_CRM_meta_notify_slave_resource+ * Inactive resources: +$OCF_RESKEY_CRM_meta_notify_inactive_resource+ * Resources to be started: +$OCF_RESKEY_CRM_meta_notify_start_resource+ * Resources to be promoted: +$OCF_RESKEY_CRM_meta_notify_promote_resource+ * Resources to be demoted: +$OCF_RESKEY_CRM_meta_notify_demote_resource+ * Resources to be stopped: +$OCF_RESKEY_CRM_meta_notify_stop_resource+ .Post-notification (demote) / Pre-notification (stop): * +Active+ resources: +$OCF_RESKEY_CRM_meta_notify_active_resource+ * +Master+ resources: ** +$OCF_RESKEY_CRM_meta_notify_master_resource+ ** minus +$OCF_RESKEY_CRM_meta_notify_demote_resource+ * +Slave+ resources: +$OCF_RESKEY_CRM_meta_notify_slave_resource+ * Inactive resources: +$OCF_RESKEY_CRM_meta_notify_inactive_resource+ * Resources to be started: +$OCF_RESKEY_CRM_meta_notify_start_resource+ * Resources to be promoted: +$OCF_RESKEY_CRM_meta_notify_promote_resource+ * Resources to be demoted: +$OCF_RESKEY_CRM_meta_notify_demote_resource+ * Resources to be stopped: +$OCF_RESKEY_CRM_meta_notify_stop_resource+ * Resources that were demoted: +$OCF_RESKEY_CRM_meta_notify_demote_resource+ .Post-notification (stop) / Pre-notification (start) * +Active+ resources: ** +$OCF_RESKEY_CRM_meta_notify_active_resource+ ** minus +$OCF_RESKEY_CRM_meta_notify_stop_resource+ * +Master+ resources: ** +$OCF_RESKEY_CRM_meta_notify_master_resource+ ** minus +$OCF_RESKEY_CRM_meta_notify_demote_resource+ * +Slave+ resources: ** +$OCF_RESKEY_CRM_meta_notify_slave_resource+ ** minus +$OCF_RESKEY_CRM_meta_notify_stop_resource+ * Inactive resources: ** +$OCF_RESKEY_CRM_meta_notify_inactive_resource+ ** plus +$OCF_RESKEY_CRM_meta_notify_stop_resource+ * Resources to be started: +$OCF_RESKEY_CRM_meta_notify_start_resource+ * Resources to be promoted: +$OCF_RESKEY_CRM_meta_notify_promote_resource+ * Resources to be demoted: +$OCF_RESKEY_CRM_meta_notify_demote_resource+ * Resources to be stopped: +$OCF_RESKEY_CRM_meta_notify_stop_resource+ * Resources that were demoted: +$OCF_RESKEY_CRM_meta_notify_demote_resource+ * Resources that were stopped: +$OCF_RESKEY_CRM_meta_notify_stop_resource+ .Post-notification (start) / Pre-notification (promote) * +Active+ resources: ** +$OCF_RESKEY_CRM_meta_notify_active_resource+ ** minus +$OCF_RESKEY_CRM_meta_notify_stop_resource+ ** plus +$OCF_RESKEY_CRM_meta_notify_start_resource+ * +Master+ resources: ** +$OCF_RESKEY_CRM_meta_notify_master_resource+ ** minus +$OCF_RESKEY_CRM_meta_notify_demote_resource+ * +Slave+ resources: ** +$OCF_RESKEY_CRM_meta_notify_slave_resource+ ** minus +$OCF_RESKEY_CRM_meta_notify_stop_resource+ ** plus +$OCF_RESKEY_CRM_meta_notify_start_resource+ * Inactive resources: ** +$OCF_RESKEY_CRM_meta_notify_inactive_resource+ ** plus +$OCF_RESKEY_CRM_meta_notify_stop_resource+ ** minus +$OCF_RESKEY_CRM_meta_notify_start_resource+ * Resources to be started: +$OCF_RESKEY_CRM_meta_notify_start_resource+ * Resources to be promoted: +$OCF_RESKEY_CRM_meta_notify_promote_resource+ * Resources to be demoted: +$OCF_RESKEY_CRM_meta_notify_demote_resource+ * Resources to be stopped: +$OCF_RESKEY_CRM_meta_notify_stop_resource+ * Resources that were started: +$OCF_RESKEY_CRM_meta_notify_start_resource+ * Resources that were demoted: +$OCF_RESKEY_CRM_meta_notify_demote_resource+ * Resources that were stopped: +$OCF_RESKEY_CRM_meta_notify_stop_resource+ .Post-notification (promote) * +Active+ resources: ** +$OCF_RESKEY_CRM_meta_notify_active_resource+ ** minus +$OCF_RESKEY_CRM_meta_notify_stop_resource+ ** plus +$OCF_RESKEY_CRM_meta_notify_start_resource+ * +Master+ resources: ** +$OCF_RESKEY_CRM_meta_notify_master_resource+ ** minus +$OCF_RESKEY_CRM_meta_notify_demote_resource+ ** plus +$OCF_RESKEY_CRM_meta_notify_promote_resource+ * +Slave+ resources: ** +$OCF_RESKEY_CRM_meta_notify_slave_resource+ ** minus +$OCF_RESKEY_CRM_meta_notify_stop_resource+ ** plus +$OCF_RESKEY_CRM_meta_notify_start_resource+ ** minus +$OCF_RESKEY_CRM_meta_notify_promote_resource+ * Inactive resources: ** +$OCF_RESKEY_CRM_meta_notify_inactive_resource+ ** plus +$OCF_RESKEY_CRM_meta_notify_stop_resource+ ** minus +$OCF_RESKEY_CRM_meta_notify_start_resource+ * Resources to be started: +$OCF_RESKEY_CRM_meta_notify_start_resource+ * Resources to be promoted: +$OCF_RESKEY_CRM_meta_notify_promote_resource+ * Resources to be demoted: +$OCF_RESKEY_CRM_meta_notify_demote_resource+ * Resources to be stopped: +$OCF_RESKEY_CRM_meta_notify_stop_resource+ * Resources that were started: +$OCF_RESKEY_CRM_meta_notify_start_resource+ * Resources that were promoted: +$OCF_RESKEY_CRM_meta_notify_promote_resource+ * Resources that were demoted: +$OCF_RESKEY_CRM_meta_notify_demote_resource+ * Resources that were stopped: +$OCF_RESKEY_CRM_meta_notify_stop_resource+ pacemaker-master/doc/Pacemaker_Explained/en-US/Ch-Basics.txt000066400000000000000000000335531217637305600241740ustar00rootroot00000000000000= Configuration Basics = == Configuration Layout == The cluster is written using XML notation and divided into two main sections: configuration and status. The status section contains the history of each resource on each node and based on this data, the cluster can construct the complete current state of the cluster. The authoritative source for the status section is the local resource manager (lrmd) process on each cluster node and the cluster will occasionally repopulate the entire section. For this reason it is never written to disk and administrators are advised against modifying it in any way. The configuration section contains the more traditional information like cluster options, lists of resources and indications of where they should be placed. The configuration section is the primary focus of this document. The configuration section itself is divided into four parts: * Configuration options (called +crm_config+) * Nodes * Resources * Resource relationships (called +constraints+) .An empty configuration ====== [source,XML] ------- ------- ====== == The Current State of the Cluster == Before one starts to configure a cluster, it is worth explaining how to view the finished product. For this purpose we have created the `crm_mon` utility that will display the current state of an active cluster. It can show the cluster status by node or by resource and can be used in either single-shot or dynamically-updating mode. There are also modes for displaying a list of the operations performed (grouped by node and resource) as well as information about failures. Using this tool, you can examine the state of the cluster for irregularities and see how it responds when you cause or simulate failures. Details on all the available options can be obtained using the `crm_mon --help` command. .Sample output from crm_mon ====== ------- ============ Last updated: Fri Nov 23 15:26:13 2007 Current DC: sles-3 (2298606a-6a8c-499a-9d25-76242f7006ec) 3 Nodes configured. 5 Resources configured. ============ Node: sles-1 (1186dc9a-324d-425a-966e-d757e693dc86): online 192.168.100.181 (heartbeat::ocf:IPaddr): Started sles-1 192.168.100.182 (heartbeat:IPaddr): Started sles-1 192.168.100.183 (heartbeat::ocf:IPaddr): Started sles-1 rsc_sles-1 (heartbeat::ocf:IPaddr): Started sles-1 child_DoFencing:2 (stonith:external/vmware): Started sles-1 Node: sles-2 (02fb99a8-e30e-482f-b3ad-0fb3ce27d088): standby Node: sles-3 (2298606a-6a8c-499a-9d25-76242f7006ec): online rsc_sles-2 (heartbeat::ocf:IPaddr): Started sles-3 rsc_sles-3 (heartbeat::ocf:IPaddr): Started sles-3 child_DoFencing:0 (stonith:external/vmware): Started sles-3 ------- ====== .Sample output from crm_mon -n ====== ------- ============ Last updated: Fri Nov 23 15:26:13 2007 Current DC: sles-3 (2298606a-6a8c-499a-9d25-76242f7006ec) 3 Nodes configured. 5 Resources configured. ============ Node: sles-1 (1186dc9a-324d-425a-966e-d757e693dc86): online Node: sles-2 (02fb99a8-e30e-482f-b3ad-0fb3ce27d088): standby Node: sles-3 (2298606a-6a8c-499a-9d25-76242f7006ec): online Resource Group: group-1 192.168.100.181 (heartbeat::ocf:IPaddr): Started sles-1 192.168.100.182 (heartbeat:IPaddr): Started sles-1 192.168.100.183 (heartbeat::ocf:IPaddr): Started sles-1 rsc_sles-1 (heartbeat::ocf:IPaddr): Started sles-1 rsc_sles-2 (heartbeat::ocf:IPaddr): Started sles-3 rsc_sles-3 (heartbeat::ocf:IPaddr): Started sles-3 Clone Set: DoFencing child_DoFencing:0 (stonith:external/vmware): Started sles-3 child_DoFencing:1 (stonith:external/vmware): Stopped child_DoFencing:2 (stonith:external/vmware): Started sles-1 ------- ====== The DC (Designated Controller) node is where all the decisions are made and if the current DC fails a new one is elected from the remaining cluster nodes. The choice of DC is of no significance to an administrator beyond the fact that its logs will generally be more interesting. == How Should the Configuration be Updated? == There are three basic rules for updating the cluster configuration: * Rule 1 - Never edit the cib.xml file manually. Ever. I'm not making this up. * Rule 2 - Read Rule 1 again. * Rule 3 - The cluster will notice if you ignored rules 1 & 2 and refuse to use the configuration. Now that it is clear how NOT to update the configuration, we can begin to explain how you should. The most powerful tool for modifying the configuration is the +cibadmin+ command which talks to a running cluster. With +cibadmin+, the user can query, add, remove, update or replace any part of the configuration; all changes take effect immediately, so there is no need to perform a reload-like operation. The simplest way of using cibadmin is to use it to save the current configuration to a temporary file, edit that file with your favorite text or XML editor and then upload the revised configuration. .Safely using an editor to modify the cluster configuration ====== [source,C] -------- # cibadmin --query > tmp.xml # vi tmp.xml # cibadmin --replace --xml-file tmp.xml -------- ====== Some of the better XML editors can make use of a Relax NG schema to help make sure any changes you make are valid. The schema describing the configuration can normally be found in '/usr/lib/heartbeat/pacemaker.rng' on most systems. If you only wanted to modify the resources section, you could instead do .Safely using an editor to modify a subsection of the cluster configuration ====== [source,C] -------- # cibadmin --query --obj_type resources > tmp.xml # vi tmp.xml # cibadmin --replace --obj_type resources --xml-file tmp.xml -------- ====== to avoid modifying any other part of the configuration. == Quickly Deleting Part of the Configuration == Identify the object you wish to delete. Eg. run .Searching for STONITH related configuration items ====== [source,C] # cibadmin -Q | grep stonith [source,XML] -------- -------- ====== Next identify the resource's tag name and id (in this case we'll choose +primitive+ and +child_DoFencing+). Then simply execute: [source,C] # cibadmin --delete --crm_xml '' == Updating the Configuration Without Using XML == Some common tasks can also be performed with one of the higher level tools that avoid the need to read or edit XML. To enable stonith for example, one could run: [source,C] # crm_attribute --attr-name stonith-enabled --attr-value true Or, to see if +somenode+ is allowed to run resources, there is: [source,C] # crm_standby --get-value --node-uname somenode Or, to find the current location of +my-test-rsc+, one can use: [source,C] # crm_resource --locate --resource my-test-rsc [[s-config-sandboxes]] == Making Configuration Changes in a Sandbox == Often it is desirable to preview the effects of a series of changes before updating the configuration atomically. For this purpose we have created `crm_shadow` which creates a "shadow" copy of the configuration and arranges for all the command line tools to use it. To begin, simply invoke `crm_shadow` and give it the name of a configuration to create footnote:[Shadow copies are identified with a name, making it possible to have more than one.] ; be sure to follow the simple on-screen instructions. WARNING: Read the above carefully, failure to do so could result in you destroying the cluster's active configuration! .Creating and displaying the active sandbox ====== [source,Bash] -------- # crm_shadow --create test Setting up shadow instance Type Ctrl-D to exit the crm_shadow shell shadow[test]: shadow[test] # crm_shadow --which test -------- ====== From this point on, all cluster commands will automatically use the shadow copy instead of talking to the cluster's active configuration. Once you have finished experimenting, you can either commit the changes, or discard them as shown below. Again, be sure to follow the on-screen instructions carefully. For a full list of `crm_shadow` options and commands, invoke it with the --help option. .Using a sandbox to make multiple changes atomically ====== [source,Bash] -------- shadow[test] # crm_failcount -G -r rsc_c001n01 name=fail-count-rsc_c001n01 value=0 shadow[test] # crm_standby -v on -n c001n02 shadow[test] # crm_standby -G -n c001n02 name=c001n02 scope=nodes value=on shadow[test] # cibadmin --erase --force shadow[test] # cibadmin --query shadow[test] # crm_shadow --delete test --force Now type Ctrl-D to exit the crm_shadow shell shadow[test] # exit # crm_shadow --which No shadow instance provided # cibadmin -Q -------- ====== Making changes in a sandbox and verifying the real configuration is untouched [[s-config-testing-changes]] == Testing Your Configuration Changes == We saw previously how to make a series of changes to a "shadow" copy of the configuration. Before loading the changes back into the cluster (eg. `crm_shadow --commit mytest --force`), it is often advisable to simulate the effect of the changes with +crm_simulate+, eg. [source,C] # crm_simulate --live-check -VVVVV --save-graph tmp.graph --save-dotfile tmp.dot The tool uses the same library as the live cluster to show what it would have done given the supplied input. It's output, in addition to a significant amount of logging, is stored in two files +tmp.graph+ and +tmp.dot+, both are representations of the same thing -- the cluster's response to your changes. In the graph file is stored the complete transition, containing a list of all the actions, their parameters and their pre-requisites. Because the transition graph is not terribly easy to read, the tool also generates a Graphviz dot-file representing the same information. == Interpreting the Graphviz output == * Arrows indicate ordering dependencies * Dashed-arrows indicate dependencies that are not present in the transition graph * Actions with a dashed border of any color do not form part of the transition graph * Actions with a green border form part of the transition graph * Actions with a red border are ones the cluster would like to execute but cannot run * Actions with a blue border are ones the cluster does not feel need to be executed * Actions with orange text are pseudo/pretend actions that the cluster uses to simplify the graph * Actions with black text are sent to the LRM * Resource actions have text of the form pass:[rsc]_pass:[action]_pass:[interval] pass:[node] * Any action depending on an action with a red border will not be able to execute. * Loops are _really_ bad. Please report them to the development team. === Small Cluster Transition === image::images/Policy-Engine-small.png["An example transition graph as represented by Graphviz",width="16cm",height="6cm",align="center"] In the above example, it appears that a new node, +node2+, has come online and that the cluster is checking to make sure +rsc1+, +rsc2+ and +rsc3+ are not already running there (Indicated by the +*_monitor_0+ entries). Once it did that, and assuming the resources were not active there, it would have liked to stop +rsc1+ and +rsc2+ on +node1+ and move them to +node2+. However, there appears to be some problem and the cluster cannot or is not permitted to perform the stop actions which implies it also cannot perform the start actions. For some reason the cluster does not want to start +rsc3+ anywhere. For information on the options supported by `crm_simulate`, use the `--help` option. === Complex Cluster Transition === image::images/Policy-Engine-big.png["Another, slightly more complex, transition graph that you're not expected to be able to read",width="16cm",height="20cm",align="center"] == Do I Need to Update the Configuration on all Cluster Nodes? == No. Any changes are immediately synchronized to the other active members of the cluster. To reduce bandwidth, the cluster only broadcasts the incremental updates that result from your changes and uses MD5 checksums to ensure that each copy is completely consistent. pacemaker-master/doc/Pacemaker_Explained/en-US/Ch-Constraints.txt000066400000000000000000000524561217637305600253020ustar00rootroot00000000000000= Resource Constraints = indexterm:[Resource,Constraints] == Scores == Scores of all kinds are integral to how the cluster works. Practically everything from moving a resource to deciding which resource to stop in a degraded cluster is achieved by manipulating scores in some way. Scores are calculated on a per-resource basis and any node with a negative score for a resource can't run that resource. After calculating the scores for a resource, the cluster then chooses the node with the highest one. === Infinity Math === +INFINITY+ is currently defined as 1,000,000 and addition/subtraction with it follows these three basic rules: * Any value + +INFINITY+ = +INFINITY+ * Any value - +INFINITY+ = -+INFINITY+ * +INFINITY+ - +INFINITY+ = -+INFINITY+ == Deciding Which Nodes a Resource Can Run On == indexterm:[Location Constraints] indexterm:[Resource,Constraints,Location] There are two alternative strategies for specifying which nodes a resources can run on. One way is to say that by default they can run anywhere and then create location constraints for nodes that are not allowed. The other option is to have nodes "opt-in"... to start with nothing able to run anywhere and selectively enable allowed nodes. === Options === .Options for Simple Location Constraints [width="95%",cols="2m,5<",options="header",align="center"] |========================================================= |Field |Description |id |A unique name for the constraint indexterm:[id,Location Constraints] indexterm:[Constraints,Location,id] |rsc |A resource name indexterm:[rsc,Location Constraints] indexterm:[Constraints,Location,rsc] |node |A node's name indexterm:[node,Location Constraints] indexterm:[Constraints,Location,node] |score |Positive values indicate the resource should run on this node. Negative values indicate the resource should not run on this node. Values of \+/- +INFINITY+ change "should"/"should not" to "must"/"must not". indexterm:[score,Location Constraints] indexterm:[Constraints,Location,score] |========================================================= === Asymmetrical "Opt-In" Clusters === indexterm:[Asymmetrical Opt-In Clusters] indexterm:[Cluster Type,Asymmetrical Opt-In] To create an opt-in cluster, start by preventing resources from running anywhere by default: [source,C] # crm_attribute --attr-name symmetric-cluster --attr-value false Then start enabling nodes. The following fragment says that the web server prefers +sles-1+, the database prefers +sles-2+ and both can fail over to +sles-3+ if their most preferred node fails. .Example set of opt-in location constraints ====== [source,XML] ------- ------- ====== === Symmetrical "Opt-Out" Clusters === indexterm:[Symmetrical Opt-Out Clusters] indexterm:[Cluster Type,Symmetrical Opt-Out] To create an opt-out cluster, start by allowing resources to run anywhere by default: [source,C] # crm_attribute --attr-name symmetric-cluster --attr-value true Then start disabling nodes. The following fragment is the equivalent of the above opt-in configuration. .Example set of opt-out location constraints ====== [source,XML] ------- ------- ====== Whether you should choose opt-in or opt-out depends both on your personal preference and the make-up of your cluster. If most of your resources can run on most of the nodes, then an opt-out arrangement is likely to result in a simpler configuration. On the other-hand, if most resources can only run on a small subset of nodes an opt-in configuration might be simpler. [[node-score-equal]] === What if Two Nodes Have the Same Score === If two nodes have the same score, then the cluster will choose one. This choice may seem random and may not be what was intended, however the cluster was not given enough information to know any better. .Example of two resources that prefer two nodes equally ====== [source,XML] ------- ------- ====== In the example above, assuming no other constraints and an inactive cluster, Webserver would probably be placed on sles-1 and Database on sles-2. It would likely have placed Webserver based on the node's uname and Database based on the desire to spread the resource load evenly across the cluster. However other factors can also be involved in more complex configurations. [[s-resource-ordering]] == Specifying in which Order Resources Should Start/Stop == indexterm:[Resource,Constraints,Ordering] indexterm:[Resource,Start Order] indexterm:[Ordering Constraints] The way to specify the order in which resources should start is by creating +rsc_order+ constraints. .Properties of an Ordering Constraint [width="95%",cols="2m,5<",options="header",align="center"] |========================================================= |Field |Description |id |A unique name for the constraint indexterm:[id,Ordering Constraints] indexterm:[Constraints,Ordering,id] |first |The name of a resource that must be started before the +then+ resource is allowed to. indexterm:[first,Ordering Constraints] indexterm:[Constraints,Ordering,first] |then |The name of a resource. This resource will start after the +first+ resource. indexterm:[then,Ordering Constraints] indexterm:[Constraints,Ordering,then] |kind |How to enforce the constraint. ('Since 1.1.2') * Optional - Just a suggestion. Only applies if both resources are starting/stopping. * Mandatory - Always. If 'first' is stopping or cannot be started, 'then' must be stopped. * Serialize - Ensure that no two stop/start actions occur concurrently for a set of resources. indexterm:[kind,Ordering Constraints] indexterm:[Constraints,Ordering,kind] |symmetrical |If true, which is the default, stop the resources in the reverse order. Default value: _true_ indexterm:[symmetrical,Ordering Constraints] indexterm:[Ordering Constraints,symmetrical] |========================================================= === Mandatory Ordering === When the +then+ resource cannot run without the +first+ resource being active, one should use mandatory constraints. To specify a constraint is mandatory, use scores greater than zero. This will ensure that the then resource will react when the first resource changes state. * If the +first+ resource was running and is stopped, the +then+ resource will also be stopped (if it is running). * If the +first+ resource was not running and cannot be started, the +then+ resource will be stopped (if it is running). * If the +first+ resource is (re)started while the +then+ resource is running, the +then+ resource will be stopped and restarted. === Advisory Ordering === On the other hand, when +score="0"+ is specified for a constraint, the constraint is considered optional and only has an effect when both resources are stopping and/or starting. Any change in state by the +first+ resource will have no effect on the +then+ resource. .Example of an optional and mandatory ordering constraint ====== [source,XML] ------- ------- ====== Some additional information on ordering constraints can be found in the document http://www.clusterlabs.org/mediawiki/images/d/d6/Ordering_Explained.pdf[Ordering Explained]. [[s-resource-colocation]] == Placing Resources Relative to other Resources == indexterm:[Resource,Constraints,Colocation] indexterm:[Resource,Location Relative to other Resources] When the location of one resource depends on the location of another one, we call this colocation. There is an important side-effect of creating a colocation constraint between two resources: it affects the order in which resources are assigned to a node. If you think about it, it's somewhat obvious. You can't place A relative to B unless you know where B is. footnote:[ While the human brain is sophisticated enough to read the constraint in any order and choose the correct one depending on the situation, the cluster is not quite so smart. Yet. ] So when you are creating colocation constraints, it is important to consider whether you should colocate A with B or B with A. Another thing to keep in mind is that, assuming A is collocated with B, the cluster will also take into account A's preferences when deciding which node to choose for B. For a detailed look at exactly how this occurs, see the http://www.clusterlabs.org/mediawiki/images/6/61/Colocation_Explained.pdf[Colocation Explained] document. === Options === .Properties of a Collocation Constraint [width="95%",cols="2m,5<",options="header",align="center"] |========================================================= |Field |Description |id |A unique name for the constraint. indexterm:[id,Colocation Constraints] indexterm:[Constraints,Colocation,id] |rsc |The colocation source. If the constraint cannot be satisfied, the cluster may decide not to allow the resource to run at all. indexterm:[rsc,Colocation Constraints] indexterm:[Constraints,Colocation,rsc] |with-rsc |The colocation target. The cluster will decide where to put this resource first and then decide where to put the resource in the +rsc+ field. indexterm:[with-rsc,Colocation Constraints] indexterm:[Constraints,Colocation,with-rsc] |score |Positive values indicate the resource should run on the same node. Negative values indicate the resources should not run on the same node. Values of \+/- +INFINITY+ change "should" to "must". indexterm:[score,Colocation Constraints] indexterm:[Constraints,Colocation,score] |========================================================= === Mandatory Placement === Mandatory placement occurs any time the constraint's score is ++INFINITY+ or +-INFINITY+. In such cases, if the constraint can't be satisfied, then the +rsc+ resource is not permitted to run. For +score=INFINITY+, this includes cases where the +with-rsc+ resource is not active. If you need +resource1+ to always run on the same machine as +resource2+, you would add the following constraint: .An example colocation constraint [source,XML] Remember, because +INFINITY+ was used, if +resource2+ can't run on any of the cluster nodes (for whatever reason) then +resource1+ will not be allowed to run. Alternatively, you may want the opposite... that +resource1+ cannot run on the same machine as +resource2+. In this case use +score="-INFINITY"+ .An example anti-colocation constraint [source,XML] Again, by specifying +-INFINTY+, the constraint is binding. So if the only place left to run is where +resource2+ already is, then +resource1+ may not run anywhere. === Advisory Placement === If mandatory placement is about "must" and "must not", then advisory placement is the "I'd prefer if" alternative. For constraints with scores greater than +-INFINITY+ and less than +INFINITY+, the cluster will try and accommodate your wishes but may ignore them if the alternative is to stop some of the cluster resources. Like in life, where if enough people prefer something it effectively becomes mandatory, advisory colocation constraints can combine with other elements of the configuration to behave as if they were mandatory. .An example advisory-only colocation constraint [source,XML] [[s-resource-sets-ordering]] == Ordering Sets of Resources == A common situation is for an administrator to create a chain of ordered resources, such as: .A chain of ordered resources ====== [source,XML] ------- ------- ====== == Ordered Set == .Visual representation of the four resources' start order for the above constraints image::images/resource-set.png["Ordered set",width="16cm",height="2.5cm",align="center"] To simplify this situation, there is an alternate format for ordering constraints: .A chain of ordered resources expressed as a set ====== [source,XML] ------- ------- ====== [NOTE] Resource sets have the same ordering semantics as groups. .A group resource with the equivalent ordering rules ====== [source,XML] ------- ------- ====== While the set-based format is not less verbose, it is significantly easier to get right and maintain. It can also be expanded to allow ordered sets of (un)ordered resources. In the example below, +rscA+ and +rscB+ can both start in parallel, as can +rscC+ and +rscD+, however +rscC+ and +rscD+ can only start once _both_ +rscA+ _and_ +rscB+ are active. .Ordered sets of unordered resources ====== [source,XML] ------- ------- ====== == Two Sets of Unordered Resources == .Visual representation of the start order for two ordered sets of unordered resources image::images/two-sets.png["Two ordered sets",width="13cm",height="7.5cm",align="center"] Of course either set -- or both sets -- of resources can also be internally ordered (by setting +sequential="true"+) and there is no limit to the number of sets that can be specified. .Advanced use of set ordering - Three ordered sets, two of which are internally unordered ====== [source,XML] ------- ------- ====== == Three Resources Sets == .Visual representation of the start order for the three sets defined above image::images/three-sets.png["Three ordered sets",width="16cm",height="7.5cm",align="center"] == Resource Set OR Logic == The unordered set logic discussed so far has all been "AND" logic. To illustrate this take the 3 resource set figure in the previous section. Those sets can be expressed, +(A and B) then (C) then (D) then (E and F)+ Say for example we want change the first set, (A and B), to use "OR" logic so the sets look like this, +(A or B) then (C) then (D) then (E and F)+. This functionality can be achieved through the use of the +require-all+ option. By default this option is 'require-all=true' which is why the "AND" logic is used by default. Changing +require-all=false+ means only one resource in the set needs to be started before continuing on to the next set. Note that the 'require-all=false' option only makes sense to use in conjunction with unordered sets, 'sequential=false'. Think of it like this, 'sequential=false' modifies the set to be an unordered set that uses "AND" logic by default, by adding 'require-all=false' the unordered set's "AND" logic is flipped to "OR" logic. .Resource Set "OR" logic. Three ordered sets, where the first set is internally unordered with "OR" logic. ====== [source,XML] ------- ------- ====== [[s-resource-sets-collocation]] == Collocating Sets of Resources == Another common situation is for an administrator to create a set of collocated resources. Previously this was possible either by defining a resource group (See <>) which could not always accurately express the design; or by defining each relationship as an individual constraint, causing a constraint explosion as the number of resources and combinations grew. .A chain of collocated resources ====== [source,XML] ------- ------- ====== To make things easier, we allow an alternate form of colocation constraints using +resource_sets+. Just like the expanded version, a resource that can't be active also prevents any resource that must be collocated with it from being active. For example, if +B was+ not able to run, then both +C (+and by inference +D)+ must also remain stopped. .The equivalent colocation chain expressed using +resource_sets+ ====== [source,XML] ------- ------- ====== [NOTE] Resource sets have the same colocation semantics as groups. .A group resource with the equivalent colocation rules [source,XML] ------- ------- This notation can also be used in this context to tell the cluster that a set of resources must all be located with a common peer, but have no dependencies on each other. In this scenario, unlike the previous, +B would+ be allowed to remain active even if +A or+ +C+ (or both) were inactive. .Using colocation sets to specify a common peer. ====== [source,XML] ------- ------- ====== Of course there is no limit to the number and size of the sets used. The only thing that matters is that in order for any member of set N to be active, all the members of set N+1 must also be active (and naturally on the same node); and if a set has +sequential="true"+, then in order for member M to be active, member M+1 must also be active. You can even specify the role in which the members of a set must be in using the set's role attribute. .A colocation chain where the members of the middle set have no inter-dependencies and the last has master status. ====== [source,XML] ------- ------- ====== == Another Three Resources Sets == .Visual representation of a colocation chain where the members of the middle set have no inter-dependencies image::images/three-sets-complex.png["Colocation chain",width="16cm",height="9cm",align="center"] pacemaker-master/doc/Pacemaker_Explained/en-US/Ch-Intro.txt000066400000000000000000000166611217637305600240640ustar00rootroot00000000000000= Read-Me-First = == The Scope of this Document == The purpose of this document is to definitively explain the concepts used to configure Pacemaker. To achieve this, it will focus exclusively on the XML syntax used to configure the CIB. For those that are allergic to XML, there exist several unified shells and GUIs for Pacemaker. However these tools will not be covered at all in this document footnote:[I hope, however, that the concepts explained here make the functionality of these tools more easily understood.] , precisely because they hide the XML. Additionally, this document is NOT a step-by-step how-to guide for configuring a specific clustering scenario. Although such guides exist, the purpose of this document is to provide an understanding of the building blocks that can be used to construct any type of Pacemaker cluster. == What Is Pacemaker? == Pacemaker is a cluster resource manager. It achieves maximum availability for your cluster services (aka. resources) by detecting and recovering from node and resource-level failures by making use of the messaging and membership capabilities provided by your preferred cluster infrastructure (either http://www.corosync.org/[Corosync] or http://linux-ha.org/wiki/Heartbeat[Heartbeat]. Pacemaker's key features include: * Detection and recovery of node and service-level failures * Storage agnostic, no requirement for shared storage * Resource agnostic, anything that can be scripted can be clustered * Supports http://en.wikipedia.org/wiki/STONITH[STONITH] for ensuring data integrity * Supports large and small clusters * Supports both http://en.wikipedia.org/wiki/Quorum_(Distributed_Systems)[quorate] and http://devresources.linux-foundation.org/dev/clusters/docs/ResourceDrivenClusters.pdf[resource driven] clusters * Supports practically any http://en.wikipedia.org/wiki/High-availability_cluster#Node_configurations[redundancy configuration] * Automatically replicated configuration that can be updated from any node * Ability to specify cluster-wide service ordering, colocation and anti-colocation * Support for advanced services type ** Clones: for services which need to be active on multiple nodes ** Multi-state: for services with multiple modes (eg. master/slave, primary/secondary) == Types of Pacemaker Clusters == Pacemaker makes no assumptions about your environment, this allows it to support practically any http://en.wikipedia.org/wiki/High-availability_cluster#Node_configurations[redundancy configuration] including Active/Active, Active/Passive, N+1, N+M, N-to-1 and N-to-N. .Active/Passive Redundancy image::images/pcmk-active-passive.png["Active/Passive Redundancy",width="10cm",height="7.5cm",align="center"] Two-node Active/Passive clusters using Pacemaker and DRBD are a cost-effective solution for many High Availability situations. .Shared Failover image::images/pcmk-shared-failover.png["Shared Failover",width="10cm",height="7.5cm",align="center"] By supporting many nodes, Pacemaker can dramatically reduce hardware costs by allowing several active/passive clusters to be combined and share a common backup node .N to N Redundancy image::images/pcmk-active-active.png["N to N Redundancy",width="10cm",height="7.5cm",align="center"] When shared storage is available, every node can potentially be used for failover. Pacemaker can even run multiple copies of services to spread out the workload. == Pacemaker Architecture == At the highest level, the cluster is made up of three pieces: * Core cluster infrastructure providing messaging and membership functionality (illustrated in red) * Non-cluster aware components (illustrated in green). + In a Pacemaker cluster, these pieces include not only the scripts that knows how to start, stop and monitor resources, but also a local daemon that masks the differences between the different standards these scripts implement. + * A brain (illustrated in blue) + This component processes and reacts to events from the cluster (nodes leaving or joining) and resources (eg. monitor failures) as well as configuration changes from the administrator. In response to all of these events, Pacemaker will compute the ideal state of the cluster and plot a path to achieve it. This may include moving resources, stopping nodes and even forcing nodes offline with remote power switches. + //// Hack to force end list //// === Conceptual Stack Overview === .Conceptual overview of the cluster stack image::images/pcmk-overview.png["Conceptual overview of the cluster stack",width="10cm",height="7.5cm",align="center"] When combined with Corosync, Pacemaker also supports popular open source cluster filesystems. footnote:[ Even though Pacemaker also supports Heartbeat, the filesystems need to use the stack for messaging and membership and Corosync seems to be what they're standardizing on. Technically it would be possible for them to support Heartbeat as well, however there seems little interest in this. ] Due to recent standardization within the cluster filesystem community, they make use of a common distributed lock manager which makes use of Corosync for its messaging capabilities and Pacemaker for its membership (which nodes are up/down) and fencing services. .The Pacemaker stack when running on Corosync image::images/pcmk-stack.png["The Pacemaker stack when running on Corosync",width="10cm",height="7.5cm",align="center"] === Internal Components === Pacemaker itself is composed of four key components (illustrated below in the same color scheme as the previous diagram): * CIB (aka. Cluster Information Base) * CRMd (aka. Cluster Resource Management daemon) * PEngine (aka. PE or Policy Engine) * STONITHd .Subsystems of a Pacemaker cluster image::images/pcmk-internals.png["Subsystems of a Pacemaker cluster",width="10cm",height="7.5cm",align="center"] The CIB uses XML to represent both the cluster's configuration and current state of all resources in the cluster. The contents of the CIB are automatically kept in sync across the entire cluster and are used by the PEngine to compute the ideal state of the cluster and how it should be achieved. This list of instructions is then fed to the DC (Designated Controller). Pacemaker centralizes all cluster decision making by electing one of the CRMd instances to act as a master. Should the elected CRMd process (or the node it is on) fail... a new one is quickly established. The DC carries out PEngine's instructions in the required order by passing them to either the LRMd (Local Resource Management daemon) or CRMd peers on other nodes via the cluster messaging infrastructure (which in turn passes them on to their LRMd process). The peer nodes all report the results of their operations back to the DC and, based on the expected and actual results, will either execute any actions that needed to wait for the previous one to complete, or abort processing and ask the PEngine to recalculate the ideal cluster state based on the unexpected results. In some cases, it may be necessary to power off nodes in order to protect shared data or complete resource recovery. For this Pacemaker comes with STONITHd. STONITH is an acronym for Shoot-The-Other-Node-In-The-Head and is usually implemented with a remote power switch. In Pacemaker, STONITH devices are modeled as resources (and configured in the CIB) to enable them to be easily monitored for failure, however STONITHd takes care of understanding the STONITH topology such that its clients simply request a node be fenced and it does the rest. pacemaker-master/doc/Pacemaker_Explained/en-US/Ch-Multi-site-Clusters.txt000066400000000000000000000320271217637305600266210ustar00rootroot00000000000000= Multi-Site Clusters and Tickets = [[Multisite]] == Abstract == Apart from local clusters, Pacemaker also supports multi-site clusters. That means you can have multiple, geographically dispersed sites with a local cluster each. Failover between these clusters can be coordinated by a higher level entity, the so-called `CTR (Cluster Ticket Registry)`. == Challenges for Multi-Site Clusters == Typically, multi-site environments are too far apart to support synchronous communication between the sites and synchronous data replication. That leads to the following challenges: - How to make sure that a cluster site is up and running? - How to make sure that resources are only started once? - How to make sure that quorum can be reached between the different sites and a split brain scenario can be avoided? - How to manage failover between the sites? - How to deal with high latency in case of resources that need to be stopped? In the following sections, learn how to meet these challenges. == Conceptual Overview == Multi-site clusters can be considered as “overlay” clusters where each cluster site corresponds to a cluster node in a traditional cluster. The overlay cluster can be managed by a `CTR (Cluster Ticket Registry)` mechanism. It guarantees that the cluster resources will be highly available across different cluster sites. This is achieved by using so-called `tickets` that are treated as failover domain between cluster sites, in case a site should be down. The following list explains the individual components and mechanisms that were introduced for multi-site clusters in more detail. === Components and Concepts === ==== Ticket ==== "Tickets" are, essentially, cluster-wide attributes. A ticket grants the right to run certain resources on a specific cluster site. Resources can be bound to a certain ticket by `rsc_ticket` dependencies. Only if the ticket is available at a site, the respective resources are started. Vice versa, if the ticket is revoked, the resources depending on that ticket need to be stopped. The ticket thus is similar to a 'site quorum'; i.e., the permission to manage/own resources associated with that site. (One can also think of the current `have-quorum` flag as a special, cluster-wide ticket that is granted in case of node majority.) These tickets can be granted/revoked either manually by administrators (which could be the default for the classic enterprise clusters), or via an automated `CTR` mechanism described further below. A ticket can only be owned by one site at a time. Initially, none of the sites has a ticket. Each ticket must be granted once by the cluster administrator. The presence or absence of tickets for a site is stored in the CIB as a cluster status. With regards to a certain ticket, there are only two states for a site: `true` (the site has the ticket) or `false` (the site does not have the ticket). The absence of a certain ticket (during the initial state of the multi-site cluster) is also reflected by the value `false`. ==== Dead Man Dependency ==== A site can only activate the resources safely if it can be sure that the other site has deactivated them. However after a ticket is revoked, it can take a long time until all resources depending on that ticket are stopped "cleanly", especially in case of cascaded resources. To cut that process short, the concept of a `Dead Man Dependency` was introduced: - If the ticket is revoked from a site, the nodes that are hosting dependent resources are fenced. This considerably speeds up the recovery process of the cluster and makes sure that resources can be migrated more quickly. This can be configured by specifying a `loss-policy="fence"` in `rsc_ticket` constraints. ==== CTR (Cluster Ticket Registry) ==== This is for those scenarios where the tickets management is supposed to be automatic (instead of the administrator revoking the ticket somewhere, waiting for everything to stop, and then granting it on the desired site). A `CTR` is a network daemon that handles granting, revoking, and timing out "tickets". The participating clusters would run the daemons that would connect to each other, exchange information on their connectivity details, and vote on which site gets which ticket(s). A ticket would only be granted to a site once they can be sure that it has been relinquished by the previous owner, which would need to be implemented via a timer in most scenarios. If a site loses connection to its peers, its tickets time out and recovery occurs. After the connection timeout plus the recovery timeout has passed, the other sites are allowed to re-acquire the ticket and start the resources again. This can also be thought of as a "quorum server", except that it is not a single quorum ticket, but several. ==== Configuration Replication ==== As usual, the CIB is synchronized within each cluster, but it is not synchronized across cluster sites of a multi-site cluster. You have to configure the resources that will be highly available across the multi-site cluster for every site accordingly. == Configuring Ticket Dependencies == The `rsc_ticket` constraint lets you specify the resources depending on a certain ticket. Together with the constraint, you can set a `loss-policy` that defines what should happen to the respective resources if the ticket is revoked. The attribute `loss-policy` can have the following values: fence:: Fence the nodes that are running the relevant resources. stop:: Stop the relevant resources. freeze:: Do nothing to the relevant resources. demote:: Demote relevant resources that are running in master mode to slave mode. An example to configure a `rsc_ticket` constraint: [source,XML] ------- ------- This creates a constraint with the ID `rsc1-req-ticketA`. It defines that the resource `rsc1` depends on `ticketA` and that the node running the resource should be fenced in case `ticketA` is revoked. If resource `rsc1` was a multi-state resource that can run in master or slave mode, you may want to configure that only `rsc1's` master mode depends on `ticketA`. With the following configuration, `rsc1` will be demoted to slave mode if `ticketA` is revoked: [source,XML] ------- ------- You can create more `rsc_ticket` constraints to let multiple resources depend on the same ticket. `rsc_ticket` also supports resource sets. So one can easily list all the resources in one `rsc_ticket` constraint. For example: [source,XML] ------- ------- In the example, there are two resource sets for listing the resources with different `roles` in one `rsc_ticket` constraint. There's no dependency between the two resource sets. And there's no dependency among the resources within a resource set. Each of the resources just depends on `ticketA`. Referencing resource templates in `rsc_ticket` constraints, and even referencing them within resource sets, is also supported. If you want other resources to depend on further tickets, create as many constraints as necessary with `rsc_ticket`. == Managing Multi-Site Clusters == === Granting and Revoking Tickets Manually === You can grant tickets to sites or revoke them from sites manually. Though if you want to re-distribute a ticket, you should wait for the dependent resources to cleanly stop at the previous site before you grant the ticket to another desired site. Use the `crm_ticket` command line tool to grant and revoke tickets. To grant a ticket to this site: [source,C] ------- # crm_ticket --ticket ticketA --grant ------- To revoke a ticket from this site: [source,C] ------- # crm_ticket --ticket ticketA --revoke ------- [IMPORTANT] ==== If you are managing tickets manually. Use the `crm_ticket` command with great care as they cannot help verify if the same ticket is already granted elsewhere. ==== === Granting and Revoking Tickets via a Cluster Ticket Registry === ==== Booth ==== Booth is an implementation of `Cluster Ticket Registry` or so-called `Cluster Ticket Manager`. Booth is the instance managing the ticket distribution and thus, the failover process between the sites of a multi-site cluster. Each of the participating clusters and arbitrators runs a service, the boothd. It connects to the booth daemons running at the other sites and exchanges connectivity details. Once a ticket is granted to a site, the booth mechanism will manage the ticket automatically: If the site which holds the ticket is out of service, the booth daemons will vote which of the other sites will get the ticket. To protect against brief connection failures, sites that lose the vote (either explicitly or implicitly by being disconnected from the voting body) need to relinquish the ticket after a time-out. Thus, it is made sure that a ticket will only be re-distributed after it has been relinquished by the previous site. The resources that depend on that ticket will fail over to the new site holding the ticket. The nodes that have run the resources before will be treated according to the `loss-policy` you set within the `rsc_ticket` constraint. Before the booth can manage a certain ticket within the multi-site cluster, you initially need to grant it to a site manually via `booth client` command. After you have initially granted a ticket to a site, the booth mechanism will take over and manage the ticket automatically. [IMPORTANT] ==== The `booth client` command line tool can be used to grant, list, or revoke tickets. The `booth client` commands work on any machine where the booth daemon is running. If you are managing tickets via `Booth`, only use `booth client` for manual intervention instead of `crm_ticket`. That can make sure the same ticket will only be owned by one cluster site at a time. ==== Booth includes an implementation of http://en.wikipedia.org/wiki/Paxos_algorithm['Paxos'] and 'Paxos Lease' algorithm, which guarantees the distributed consensus among different cluster sites. [NOTE] ==== `Arbitrator` Each site runs one booth instance that is responsible for communicating with the other sites. If you have a setup with an even number of sites, you need an additional instance to reach consensus about decisions such as failover of resources across sites. In this case, add one or more arbitrators running at additional sites. Arbitrators are single machines that run a booth instance in a special mode. As all booth instances communicate with each other, arbitrators help to make more reliable decisions about granting or revoking tickets. An arbitrator is especially important for a two-site scenario: For example, if site `A` can no longer communicate with site `B`, there are two possible causes for that: - `A` network failure between `A` and `B`. - Site `B` is down. However, if site `C` (the arbitrator) can still communicate with site `B`, site `B` must still be up and running. ==== ===== Requirements ===== - All clusters that will be part of the multi-site cluster must be based on Pacemaker. - Booth must be installed on all cluster nodes and on all arbitrators that will be part of the multi-site cluster. The most common scenario is probably a multi-site cluster with two sites and a single arbitrator on a third site. However, technically, there are no limitations with regards to the number of sites and the number of arbitrators involved. Nodes belonging to the same cluster site should be synchronized via NTP. However, time synchronization is not required between the individual cluster sites. === General Management of Tickets === Display the information of tickets: [source,C] ------- # crm_ticket --info ------- Or you can monitor them with: [source,C] ------- # crm_mon --tickets ------- Display the rsc_ticket constraints that apply to a ticket: [source,C] ------- # crm_ticket --ticket ticketA --constraints ------- When you want to do maintenance or manual switch-over of a ticket, the ticket could be revoked from the site for any reason, which would trigger the loss-policies. If `loss-policy="fence"`, the dependent resources could not be gracefully stopped/demoted, and even, other unrelated resources could be impacted. The proper way is making the ticket `standby` first with: [source,C] ------- # crm_ticket --ticket ticketA --standby ------- Then the dependent resources will be stopped or demoted gracefully without triggering the loss-policies. If you have finished the maintenance and want to activate the ticket again, you can run: [source,C] ------- # crm_ticket --ticket ticketA --activate ------- == For more information == `Multi-site Clusters` http://doc.opensuse.org/products/draft/SLE-HA/SLE-ha-guide_sd_draft/cha.ha.geo.html `Booth` https://github.com/ClusterLabs/booth pacemaker-master/doc/Pacemaker_Explained/en-US/Ch-Nodes.txt000066400000000000000000000156261217637305600240410ustar00rootroot00000000000000= Cluster Nodes = == Defining a Cluster Node == Each node in the cluster will have an entry in the nodes section containing its UUID, uname, and type. .Example Heartbeat cluster node entry ====== [source,XML] ====== .Example Corosync cluster node entry ====== [source,XML] ====== In normal circumstances, the admin should let the cluster populate this information automatically from the communications and membership data. However for Heartbeat, one can use the `crm_uuid` tool to read an existing UUID or define a value before the cluster starts. [[s-node-name]] == Where Pacemaker Gets the Node Name == Traditionally, Pacemaker required nodes to be referred to by the value returned by `uname -n`. This can be problematic for services that require the `uname -n` to be a specific value (ie. for a licence file). Since version 2.0.0 of Pacemaker, this requirement has been relaxed for clusters using Corosync 2.0 or later. The name Pacemaker uses is: . The value stored in 'corosync.conf' under +ring0_addr+ in the +nodelist+, if it does not contain an IP address; otherwise . The value stored in 'corosync.conf' under +name+ in the +nodelist+; otherwise . The value of `uname -n` Pacemaker provides the `crm_node -n` command which displays the name used by a running cluster. If a Corosync nodelist is used, `crm_node --name-for-id $number` is also available to display the name used by the node with the corosync +nodeid+ of '$number', for example: `crm_node --name-for-id 2`. [[s-node-attributes]] == Describing a Cluster Node == indexterm:[Node,attribute] Beyond the basic definition of a node the administrator can also describe the node's attributes, such as how much RAM, disk, what OS or kernel version it has, perhaps even its physical location. This information can then be used by the cluster when deciding where to place resources. For more information on the use of node attributes, see <>. Node attributes can be specified ahead of time or populated later, when the cluster is running, using `crm_attribute`. Below is what the node's definition would look like if the admin ran the command: .The result of using crm_attribute to specify which kernel pcmk-1 is running ====== [source,C] ------- # crm_attribute --type nodes --node-uname pcmk-1 --attr-name kernel --attr-value `uname -r` ------- [source,XML] ------- ------- ====== A simpler way to determine the current value of an attribute is to use `crm_attribute` command again: [source,C] # crm_attribute --type nodes --node-uname pcmk-1 --attr-name kernel --get-value By specifying `--type nodes` the admin tells the cluster that this attribute is persistent. There are also transient attributes which are kept in the status section which are "forgotten" whenever the node rejoins the cluster. The cluster uses this area to store a record of how many times a resource has failed on that node but administrators can also read and write to this section by specifying `--type status`. == Corosync == === Adding a New Corosync Node === indexterm:[Corosync,Add Cluster Node] indexterm:[Add Cluster Node,Corosync] Adding a new node is as simple as installing Corosync and Pacemaker, and copying '/etc/corosync/corosync.conf' and '/etc/corosync/authkey' (if it exists) from an existing node. You may need to modify the +mcastaddr+ option to match the new node's IP address. If a log message containing "Invalid digest" appears from Corosync, the keys are not consistent between the machines. === Removing a Corosync Node === indexterm:[Corosync,Remove Cluster Node] indexterm:[Remove Cluster Node,Corosync] Because the messaging and membership layers are the authoritative source for cluster nodes, deleting them from the CIB is not a reliable solution. First one must arrange for corosync to forget about the node (_pcmk-1_ in the example below). On the host to be removed: . Stop the cluster: `/etc/init.d/corosync stop` Next, from one of the remaining active cluster nodes: . Tell Pacemaker to forget about the removed host: + [source,C] # crm_node -R pcmk-1 + This includes deleting the node from the CIB [NOTE] ====== This proceedure only works for versions after 1.1.8 ====== === Replacing a Corosync Node === indexterm:[Corosync,Replace Cluster Node] indexterm:[Replace Cluster Node,Corosync] The five-step guide to replacing an existing cluster node: . Make sure the old node is completely stopped . Give the new machine the same hostname and IP address as the old one . Install the cluster software :-) . Copy '/etc/corosync/corosync.conf' and '/etc/corosync/authkey' (if it exists) to the new node . Start the new cluster node If a log message containing "Invalid digest" appears from Corosync, the keys are not consistent between the machines. == CMAN == === Adding a New CMAN Node === indexterm:[CMAN,Add Cluster Node] indexterm:[Add Cluster Node,CMAN] === Removing a CMAN Node === indexterm:[CMAN,Remove Cluster Node] indexterm:[Remove Cluster Node,CMAN] == Heartbeat == === Adding a New Heartbeat Node === indexterm:[Heartbeat,Add Cluster Node] indexterm:[Add Cluster Node,Heartbeat] Provided you specified +autojoin any+ in 'ha.cf', adding a new node is as simple as installing heartbeat and copying 'ha.cf' and 'authkeys' from an existing node. If you don't want to use +autojoin+, then after setting up 'ha.cf' and 'authkeys', you must use `hb_addnode` before starting the new node. === Removing a Heartbeat Node === indexterm:[Heartbeat,Remove Cluster Node] indexterm:[Remove Cluster Node,Heartbeat] Because the messaging and membership layers are the authoritative source for cluster nodes, deleting them from the CIB is not a reliable solution. First one must arrange for Heartbeat to forget about the node (pcmk-1 in the example below). On the host to be removed: . Stop the cluster: `/etc/init.d/corosync stop` Next, from one of the remaining active cluster nodes: . Tell Heartbeat the node should be removed [source,C] # hb_delnode pcmk-1 . Tell Pacemaker to forget about the removed host: [source,C] # crm_node -R pcmk-1 [NOTE] ====== This proceedure only works for versions after 1.1.8 ====== === Replacing a Heartbeat Node === indexterm:[Heartbeat,Replace Cluster Node] indexterm:[Replace Cluster Node,Heartbeat] The seven-step guide to replacing an existing cluster node: . Make sure the old node is completely stopped . Give the new machine the same hostname as the old one . Go to an active cluster node and look up the UUID for the old node in '/var/lib/heartbeat/hostcache' . Install the cluster software . Copy 'ha.cf' and 'authkeys' to the new node . On the new node, populate it's UUID using `crm_uuid -w` and the UUID from step 2 . Start the new cluster node pacemaker-master/doc/Pacemaker_Explained/en-US/Ch-Notifications.txt000066400000000000000000000120661217637305600255750ustar00rootroot00000000000000= Receiving Notification for Cluster Events = //// We prefer [[ch-notifications]], but older versions of asciidoc dont deal well with that construct for chapter headings //// anchor:ch-notifications[Chapter 7, Receiving Notification for Cluster Events] indexterm:[Resource,Notification] A Pacemaker cluster is an event driven system. In this context, an event is a resource failure or configuration change (not exhaustive). The +ocf:pacemaker:ClusterMon+ resource can monitor the cluster status and triggers alerts on each cluster event. This resource runs +crm_mon+ in the background at regular intervals (configurable) and uses +crm_mon+ capabilities to send emails (SMTP), SNMP traps or to execute an external program via the +extra_options+ parameter. [NOTE] ===== Depending on your system settings and compilation settings, SNMP or email alerts might be unavailable. Check +crm_mon --help+ output to see if these options are available to you. In any case, executing an external agent will always be available, and you can have this agent to send emails, SNMP traps, or whatever action you develop. ===== [[s-notification-snmp]] == Configuring SNMP Notifications == indexterm:[Resource,Notification,SNMP] Requires an IP to send SNMP traps to, and a SNMP community. Pacemaker MIB is found in _/usr/share/snmp/mibs/PCMK-MIB.txt_ .Configuring ClusterMon to send SNMP traps ===== [source,XML] ----- ----- ===== [[s-notification-email]] == Configuring Email Notifications == indexterm:[Resource,Notification,SMTP,Email] Requires a user to send mail alerts to. "Mail-From", SMTP relay and Subject prefix can also be configured. .Configuring ClusterMon to send email alerts ===== [source,XML] ----- ----- ===== [[s-notification-external]] == Configuring Notifications via External-Agent == Requires a program (external-agent) to run when resource operations take place, and an external-recipient (IP address, Email address, URI). When triggered, the external-agent is fed with dynamically filled environnement variables describing precisely the cluster event that occurred. By making smart usage of these variables in your external-agent code, you can trigger any action. .Configuring ClusterMon to execute an external-agent ===== [source,XML] ----- ----- ===== .Environment Variables Passed to the External Agent [width="95%",cols="1m,2<",options="header",align="center"] |========================================================= |Environment Variable |Description |CRM_notify_recipient | The static external-recipient from the resource definition. indexterm:[Environment Variable,CRM_notify_recipient] |CRM_notify_node | The node on which the status change happened. indexterm:[Environment Variable,CRM_notify_node] |CRM_notify_rsc | The name of the resource that changed the status. indexterm:[Environment Variable,CRM_notify_rsc] |CRM_notify_task | The operation that caused the status change. indexterm:[Environment Variable,CRM_notify_task] |CRM_notify_desc | The textual output relevant error code of the operation (if any) that caused the status change. indexterm:[Environment Variable,CRM_notify_desc] |CRM_notify_rc | The return code of the operation. indexterm:[Environment Variable,CRM_notify_rc] |CRM_notify_target_rc | The expected return code of the operation. indexterm:[Environment Variable,CRM_notify_target_rc] |CRM_notify_status | The numerical representation of the status of the operation. indexterm:[Environment Variable,CRM_notify_target_rc] |========================================================= pacemaker-master/doc/Pacemaker_Explained/en-US/Ch-Options.txt000066400000000000000000000333021217637305600244130ustar00rootroot00000000000000= Cluster Options = == Special Options == The reason for these fields to be placed at the top level instead of with the rest of cluster options is simply a matter of parsing. These options are used by the configuration database which is, by design, mostly ignorant of the content it holds. So the decision was made to place them in an easy to find location. == Configuration Version == indexterm:[Configuration Version,Cluster] indexterm:[Cluster,Option,Configuration Version] When a node joins the cluster, the cluster will perform a check to see who has the best configuration based on the fields below. It then asks the node with the highest (+admin_epoch+, +epoch+, +num_updates+) tuple to replace the configuration on all the nodes - which makes setting them, and setting them correctly, very important. .Configuration Version Properties [width="95%",cols="2m,5<",options="header",align="center"] |========================================================= |Field |Description | admin_epoch | indexterm:[admin_epoch,Cluster Option] indexterm:[Cluster,Option,admin_epoch] Never modified by the cluster. Use this to make the configurations on any inactive nodes obsolete. _Never set this value to zero_, in such cases the cluster cannot tell the difference between your configuration and the "empty" one used when nothing is found on disk. | epoch | indexterm:[epoch,Cluster Option] indexterm:[Cluster,Option,epoch] Incremented every time the configuration is updated (usually by the admin) | num_updates | indexterm:[num_updates,Cluster Option] indexterm:[Cluster,Option,num_updates] Incremented every time the configuration or status is updated (usually by the cluster) |========================================================= == Other Fields == .Properties Controlling Validation [width="95%",cols="2m,5<",options="header",align="center"] |========================================================= |Field |Description | validate-with | indexterm:[validate-with,Cluster Option] indexterm:[Cluster,Option,validate-with] Determines the type of validation being done on the configuration. If set to "none", the cluster will not verify that updates conform to the DTD (nor reject ones that don't). This option can be useful when operating a mixed version cluster during an upgrade. |========================================================= == Fields Maintained by the Cluster == .Properties Maintained by the Cluster [width="95%",cols="2m,5<",options="header",align="center"] |========================================================= |Field |Description |cib-last-written | indexterm:[cib-last-written,Cluster Property] indexterm:[Cluster,Property,cib-last-written] Indicates when the configuration was last written to disk. Informational purposes only. |dc-uuid | indexterm:[dc-uuid,Cluster Property] indexterm:[Cluster,Property,dc-uuid] Indicates which cluster node is the current leader. Used by the cluster when placing resources and determining the order of some events. |have-quorum | indexterm:[have-quorum,Cluster Property] indexterm:[Cluster,Property,have-quorum] Indicates if the cluster has quorum. If false, this may mean that the cluster cannot start resources or fence other nodes. See +no-quorum-policy+ below. | dc-version | indexterm:[dc-version,Cluster Peroperty] indexterm:[Cluster,Peroperty,dc-version] Version of Pacemaker on the cluster's DC. Often includes the hash which identifies the exact Git changeset it was built from. Used for diagnostic purposes. | cluster-infrastructure | indexterm:[cluster-infrastructure,Cluster Peroperty] indexterm:[Cluster,Peroperty,cluster-infrastructure] The messaging stack on which Pacemaker is currently running. Used for informational and diagnostic purposes. | expected-quorum-votes | indexterm:[expected-quorum-votes,Cluster Peroperty] indexterm:[Cluster,Peroperty,expected-quorum-votes] The number of nodes expected to be in the cluster Used to calculate quorum in Corosync 1.x (not CMAN) based clusters. |========================================================= Note that although these fields can be written to by the admin, in most cases the cluster will overwrite any values specified by the admin with the "correct" ones. To change the +admin_epoch+, for example, one would use: [source,C] # cibadmin --modify --crm_xml '' A complete set of fields will look something like this: .An example of the fields set for a cib object ====== [source,XML] ------- ------- ====== == Cluster Options == Cluster options, as you might expect, control how the cluster behaves when confronted with certain situations. They are grouped into sets and, in advanced configurations, there may be more than one. footnote:[This will be described later in the section on <> where we will show how to have the cluster use different sets of options during working hours (when downtime is usually to be avoided at all costs) than it does during the weekends (when resources can be moved to the their preferred hosts without bothering end users)] For now we will describe the simple case where each option is present at most once. == Available Cluster Options == .Cluster Options [width="95%",cols="5m,2,11<",options="header",align="center"] |========================================================= |Option |Default |Description | batch-limit | 30 | indexterm:[batch-limit,Cluster Option] indexterm:[Cluster,Option,batch-limit] The number of jobs that the TE is allowed to execute in parallel. The "correct" value will depend on the speed and load of your network and cluster nodes. | migration-limit | -1 (unlimited) | indexterm:[migration-limit,Cluster Option] indexterm:[Cluster,Option,migration-limit] The number of migration jobs that the TE is allowed to execute in parallel on a node. | no-quorum-policy | stop | indexterm:[no-quorum-policy,Cluster Option] indexterm:[Cluster,Option,no-quorum-policy] What to do when the cluster does not have quorum. Allowed values: * ignore - continue all resource management * freeze - continue resource management, but don't recover resources from nodes not in the affected partition * stop - stop all resources in the affected cluster partition * suicide - fence all nodes in the affected cluster partition | symmetric-cluster | TRUE | indexterm:[symmetric-cluster,Cluster Option] indexterm:[Cluster,Option,symmetric-cluster] Can all resources run on any node by default? | stonith-enabled | TRUE | indexterm:[stonith-enabled,Cluster Option] indexterm:[Cluster,Option,stonith-enabled] Should failed nodes and nodes with resources that can't be stopped be shot? If you value your data, set up a STONITH device and enable this. If true, or unset, the cluster will refuse to start resources unless one or more STONITH resources have been configured also. | stonith-action | reboot | indexterm:[stonith-action,Cluster Option] indexterm:[Cluster,Option,stonith-action] Action to send to STONITH device. Allowed values: reboot, off. The value 'poweroff' is also allowed, but is only used for legacy devices. | cluster-delay | 60s | indexterm:[cluster-delay,Cluster Option] indexterm:[Cluster,Option,cluster-delay] Round trip delay over the network (excluding action execution). The "correct" value will depend on the speed and load of your network and cluster nodes. | stop-all-resources | FALSE | indexterm:[stop-all-resources,Cluster Option] indexterm:[Cluster,Option,stop-all-resources] Should the cluster stop all stop | resources-orphan-resources | TRUE | indexterm:[stop-orphan-resources,Cluster Option] indexterm:[Cluster,Option,stop-orphan-resources] Should deleted resources be stopped? | stop-orphan-actions | TRUE | indexterm:[stop-orphan-actions,Cluster Option] indexterm:[Cluster,Option,stop-orphan-actions] Should deleted actions be cancelled? | start-failure-is-fatal | TRUE | indexterm:[start-failure-is-fatal,Cluster Option] indexterm:[Cluster,Option,start-failure-is-fatal] When set to FALSE, the cluster will instead use the resource's +failcount+ and value for +resource-failure-stickiness+. | pe-error-series-max | -1 (all) | indexterm:[pe-error-series-max,Cluster Option] indexterm:[Cluster,Option,pe-error-series-max] The number of PE inputs resulting in ERRORs to save. Used when reporting problems. | pe-warn-series-max | -1 (all) | indexterm:[pe-warn-series-max,Cluster Option] indexterm:[Cluster,Option,pe-warn-series-max] The number of PE inputs resulting in WARNINGs to save. Used when reporting problems. | pe-input-series-max | -1 (all) | indexterm:[pe-input-series-max,Cluster Option] indexterm:[Cluster,Option,pe-input-series-max] The number of "normal" PE inputs to save. Used when reporting problems. |default-resource-stickiness | 0 | indexterm:[default-resource-stickiness,Cluster Option] indexterm:[Cluster,Option,default-resource-stickiness] +Deprecated:+ See <> instead | is-managed-default | TRUE | indexterm:[is-managed-default,Cluster Option] indexterm:[Cluster,Option,is-managed-default] +Deprecated:+ See <> instead | maintenance-mode | FALSE | indexterm:[maintenance-mode,Cluster Option] indexterm:[Cluster,Option,maintenance-mode] Should the cluster monitor resources and start/stop them as required | stonith-timeout | 60s | indexterm:[stonith-timeout,Cluster Option] indexterm:[Cluster,Option,stonith-timeout] How long to wait for the STONITH action to complete | default-action-timeout | 20s | indexterm:[default-action-timeout,Cluster Option] indexterm:[Cluster,Option,default-action-timeout] +Deprecated:+ See <> instead | dc-deadtime | 20s | indexterm:[dc-deadtime,Cluster Option] indexterm:[Cluster,Option,dc-deadtime] How long to wait for a response from other nodes during startup. The "correct" value will depend on the speed/load of your network and the type of switches used. | cluster-recheck-interval | 15min | indexterm:[cluster-recheck-interval,Cluster Option] indexterm:[Cluster,Option,cluster-recheck-interval] Polling interval for time based changes to options, resource parameters and constraints. The Cluster is primarily event driven, however the configuration can have elements that change based on time. To ensure these changes take effect, we can optionally poll the cluster's status for changes. Allowed values: Zero disables polling. Positive values are an interval in seconds (unless other SI units are specified. eg. 5min) | election-timeout | 2min | indexterm:[election-timeout,Cluster Option] indexterm:[Cluster,Option,election-timeout] +Advanced Use Only+ If need to adjust this value, it probably indicates the presence of a bug. | shutdown-escalation | 20min | indexterm:[shutdown-escalation,Cluster Option] indexterm:[Cluster,Option,shutdown-escalation] +Advanced Use Only+ If need to adjust this value, it probably indicates the presence of a bug. | crmd-integration-timeout | 3min | indexterm:[crmd-integration-timeout,Cluster Option] indexterm:[Cluster,Option,crmd-integration-timeout] +Advanced Use Only+ If need to adjust this value, it probably indicates the presence of a bug. | crmd-finalization-timeout | 30min | indexterm:[crmd-finalization-timeout,Cluster Option] indexterm:[Cluster,Option,crmd-finalization-timeout] +Advanced Use Only+ If need to adjust this value, it probably indicates the presence of a bug. | crmd-transition-delay | | indexterm:[crmd-transition-delay,Cluster Option] indexterm:[Cluster,Option,crmd-transition-delay] +Advanced Use Only+ Enabling this option will slow down cluster recovery under all conditions. Delay cluster recovery for the configured interval to allow for additional/related events to occur. Useful if your configuration is sensitive to the order in which ping updates arrive. |========================================================= You can always obtain an up-to-date list of cluster options, including their default values, by running the `man pengine` and `man crmd` commands. == Querying and Setting Cluster Options == indexterm:[Querying,Cluster Option] indexterm:[Setting,Cluster Option] indexterm:[Cluster,Querying Options] indexterm:[Cluster,Setting Options] Cluster options can be queried and modified using the `crm_attribute` tool. To get the current value of +cluster-delay+, simply use: [source,C] # crm_attribute --attr-name cluster-delay --get-value which is more simply written as [source,C] # crm_attribute --get-value -n cluster-delay If a value is found, you'll see a result like this: [source,C] # crm_attribute --get-value -n cluster-delay name=cluster-delay value=60s However, if no value is found, the tool will display an error: [source,C] # crm_attribute --get-value -n clusta-deway` name=clusta-deway value=(null) Error performing operation: The object/attribute does not exist To use a different value, eg. +30+, simply run: [source,C] # crm_attribute --attr-name cluster-delay --attr-value 30s To go back to the cluster's default value you can delete the value, for example with this command: [source,C] # crm_attribute --attr-name cluster-delay --delete-attr == When Options are Listed More Than Once == If you ever see something like the following, it means that the option you're modifying is present more than once. .Deleting an option that is listed twice ======= [source,C] ------ # crm_attribute --attr-name batch-limit --delete-attr Multiple attributes match name=batch-limit in crm_config: Value: 50 (set=cib-bootstrap-options, id=cib-bootstrap-options-batch-limit) Value: 100 (set=custom, id=custom-batch-limit) Please choose from one of the matches above and supply the 'id' with --attr-id ------- ======= In such cases follow the on-screen instructions to perform the requested action. To determine which value is currently being used by the cluster, please refer to <>. pacemaker-master/doc/Pacemaker_Explained/en-US/Ch-Resource-Templates.txt000066400000000000000000000157011217637305600265060ustar00rootroot00000000000000= Resource Templates = == Abstract == If you want to create lots of resources with similar configurations, defining a resource template simplifies the task. Once defined, it can be referenced in primitives or in certain types of constraints. == Configuring Resources with Templates == The primitives referencing the template will inherit all meta attributes, instance attributes, utilization attributes and operations defined in the template. And you can define specific attributes and operations for any of the primitives. If any of these are defined in both the template and the primitive, the values defined in the primitive will take precedence over the ones defined in the template. Hence, resource templates help to reduce the amount of configuration work. If any changes are needed, they can be done to the template definition and will take effect globally in all resource definitions referencing that template. Resource templates have a similar syntax like primitives. For example: [source,XML] ---- ---- Once you defined the new resource template, you can use it in primitives: [source,XML] ---- ---- The new primitive `vm1` is going to inherit everything from the `vm-template`. For example, the equivalent of the above two would be: [source,XML] ---- ---- If you want to overwrite some attributes or operations, add them to the particular primitive's definition. For instance, the following new primitive `vm2` has special attribute values. Its `monitor` operation has a longer `timeout` and `interval`, and the primitive has an additional `stop` operation. [source,XML] ---- ---- The following command shows the resulting definition of a resource: [source,C] # crm_resource --query-xml --resource vm2 The following command shows its raw definition in cib: [source,C] # crm_resource --query-xml-raw --resource vm2 == Referencing Templates in Constraints == A resource template can be referenced in the following types of constraints: - `order` constraints - `colocation` constraints, - `rsc_ticket` constraints (for multi-site clusters). Resource templates referenced in constraints stand for all primitives which are derived from that template. This means, the constraint applies to all primitive resources referencing the resource template. Referencing resource templates in constraints is an alternative to resource sets and can simplify the cluster configuration considerably. For example: [source,XML] is the equivalent of the following constraint configuration: [source,XML] ---- ---- [NOTE] ====== In a colocation constraint, only one template may be referenced from either `rsc` or `with-rsc`, and the other reference must be a regular resource. ====== Resource templates can also be referenced in resource sets. For example: [source,XML] ---- ---- is the equivalent of the following constraint configuration: [source,XML] ---- ---- If the resources referencing the template can run in parallel: [source,XML] ---- ---- is the equivalent of the following constraint configuration: [source,XML] ---- ---- pacemaker-master/doc/Pacemaker_Explained/en-US/Ch-Resources.txt000066400000000000000000000553571217637305600247500ustar00rootroot00000000000000= Cluster Resources = == What is a Cluster Resource == indexterm:[Resource] The role of a resource agent is to abstract the service it provides and present a consistent view to the cluster, which allows the cluster to be agnostic about the resources it manages. The cluster doesn't need to understand how the resource works because it relies on the resource agent to do the right thing when given a +start+, +stop+ or +monitor+ command. For this reason it is crucial that resource agents are well tested. Typically resource agents come in the form of shell scripts, however they can be written using any technology (such as C, Python or Perl) that the author is comfortable with. [[s-resource-supported]] == Supported Resource Classes == indexterm:[Resource,class] There are six classes of agents supported by Pacemaker: * OCF * LSB * Upstart * Systemd * Fencing * Service * Nagios indexterm:[Resource,Heartbeat] indexterm:[Heartbeat,Resources] Version 1 of Heartbeat came with its own style of resource agents and it is highly likely that many people have written their own agents based on its conventions. footnote:[ See http://wiki.linux-ha.org/HeartbeatResourceAgent for more information ] Although deprecated with the release of Heartbeat v2, they were supported by Pacemaker up until the release of 1.1.8 to enable administrators to continue to use these agents. === Open Cluster Framework === indexterm:[Resource,OCF] indexterm:[OCF,Resources] indexterm:[Open Cluster Framework,Resources] The OCF standard footnote:[ http://www.opencf.org/cgi-bin/viewcvs.cgi/specs/ra/resource-agent-api.txt?rev=HEAD - at least as it relates to resource agents. ] footnote:[ The Pacemaker implementation has been somewhat extended from the OCF Specs, but none of those changes are incompatible with the original OCF specification. ] is basically an extension of the Linux Standard Base conventions for init scripts to: * support parameters, * make them self describing and * extensible OCF specs have strict definitions of the exit codes that actions must return. footnote:[ Included with the cluster is the ocf-tester script, which can be useful in this regard. ] The cluster follows these specifications exactly, and giving the wrong exit code will cause the cluster to behave in ways you will likely find puzzling and annoying. In particular, the cluster needs to distinguish a completely stopped resource from one which is in some erroneous and indeterminate state. Parameters are passed to the script as environment variables, with the special prefix +OCF_RESKEY_+. So, a parameter which the user thinks of as ip it will be passed to the script as +OCF_RESKEY_ip+. The number and purpose of the parameters is completely arbitrary, however your script should advertise any that it supports using the +meta-data+ command. The OCF class is the most preferred one as it is an industry standard, highly flexible (allowing parameters to be passed to agents in a non-positional manner) and self-describing. For more information, see the http://www.linux-ha.org/wiki/OCF_Resource_Agents[reference] and <>. === Linux Standard Base === indexterm:[Resource,LSB] indexterm:[LSB,Resources] indexterm:[Linux Standard Base,Resources] LSB resource agents are those found in '/etc/init.d'. Generally they are provided by the OS/distribution and, in order to be used with the cluster, they must conform to the LSB Spec. footnote:[ See http://refspecs.linux-foundation.org/LSB_3.0.0/LSB-Core-generic/LSB-Core-generic/iniscrptact.html for the LSB Spec (as it relates to init scripts). ] Many distributions claim LSB compliance but ship with broken init scripts. For details on how to check if your init script is LSB-compatible, see <>. The most common problems are: * Not implementing the status operation at all * Not observing the correct exit status codes for start/stop/status actions * Starting a started resource returns an error (this violates the LSB spec) * Stopping a stopped resource returns an error (this violates the LSB spec) === Systemd === indexterm:[Resource,Systemd] indexterm:[Systemd,Resources] Some newer distributions have replaced the old http://en.wikipedia.org/wiki/Init#SysV-style[SYS-V] style of initialization daemons (and scripts) with an alternative called http://www.freedesktop.org/wiki/Software/systemd[Systemd]. Pacemaker is able to manage these services _if they are present_. Instead of +init scripts+, systemd has +unit files+. Generally the services (or unit files) are provided by the OS/distribution but there are some instructions for converting from init scripts at: http://0pointer.de/blog/projects/systemd-for-admins-3.html [NOTE] ====== Remember to make sure the computer is +not+ configured to start any services at boot time that should be controlled by the cluster. ====== === Upstart === indexterm:[Resource,Upstart] indexterm:[Upstart,Resources] Some newer distributions have replaced the old http://en.wikipedia.org/wiki/Init#SysV-style[SYS-V] style of initialization daemons (and scripts) with an alternative called http://upstart.ubuntu.com[Upstart]. Pacemaker is able to manage these services _if they are present_. Instead of +init scripts+, upstart has +jobs+. Generally the services (or jobs) are provided by the OS/distribution. [NOTE] ====== Remember to make sure the computer is +not+ configured to start any services at boot time that should be controlled by the cluster. ====== === System Services === indexterm:[Resource,System Services] indexterm:[System Service,Resources] Since there are now many "common" types of system services (+systemd+, +upstart+, and +lsb+), Pacemaker supports a special alias which intelligently figures out which one applies to a given cluster node. This is particularly useful when the cluster contains a mix of +systemd+, +upstart+, and +lsb+. In order, Pacemaker will try to find the named service as: . an LSB (SYS-V) init script . a Systemd unit file . an Upstart job === STONITH === indexterm:[Resource,STONITH] indexterm:[STONITH,Resources] There is also an additional class, STONITH, which is used exclusively for fencing related resources. This is discussed later in <>. === Nagios Plugins === indexterm:[Resource,Nagios Plugins] indexterm:[Nagios Plugins,Resources] Nagios plugins allow us to monitor services on the remote hosts. http://nagiosplugins.org[Nagios Plugins]. Pacemaker is able to do remote monitoring with the plugins _if they are present_. An use case is to configure them as resources belonging to a resource container, which usually is a VM, and the container will be restarted if any of them has failed. While they can also be configured as ordinary resources to be just used for monitoring hosts or services via network. The supported parameters are same as the long options of a nagios plugin. [[primitive-resource]] == Resource Properties == These values tell the cluster which script to use for the resource, where to find that script and what standards it conforms to. .Properties of a Primitive Resource [width="95%",cols="1m,6<",options="header",align="center"] |========================================================= |Field |Description |id |Your name for the resource indexterm:[id,Resource] indexterm:[Resource,Property,id] |class |The standard the script conforms to. Allowed values: +ocf+, +service+, +upstart+, +systemd+, +lsb+, +stonith+ indexterm:[class,Resource] indexterm:[Resource,Property,class] |type |The name of the Resource Agent you wish to use. Eg. _IPaddr_ or _Filesystem_ indexterm:[type,Resource] indexterm:[Resource,Property,type] |provider |The OCF spec allows multiple vendors to supply the same ResourceAgent. To use the OCF resource agents supplied with Heartbeat, you should specify +heartbeat+ here. indexterm:[provider,Resource] indexterm:[Resource,Property,provider] |========================================================= Resource definitions can be queried with the `crm_resource` tool. For example [source,C] # crm_resource --resource Email --query-xml might produce: .An example system resource ===== [source,XML] ===== [NOTE] ===== One of the main drawbacks to system services (such as LSB, Systemd and Upstart) resources is that they do not allow any parameters! ===== .An example OCF resource ===== [source,XML] ------- ------- ===== [[s-resource-options]] == Resource Options == Options are used by the cluster to decide how your resource should behave and can be easily set using the `--meta` option of the `crm_resource` command. .Options for a Primitive Resource [width="95%",cols="1m,1,4<",options="header",align="center"] |========================================================= |Field |Default |Description |priority |+0+ |If not all resources can be active, the cluster will stop lower priority resources in order to keep higher priority ones active. indexterm:[priority,Resource Option] indexterm:[Resource,Option,priority] |target-role |+Started+ |What state should the cluster attempt to keep this resource in? Allowed values: * 'Stopped' - Force the resource to be stopped * 'Started' - Allow the resource to be started (In the case of <> resources, they will not promoted to master) * 'Master' - Allow the resource to be started and, if appropriate, promoted indexterm:[target-role,Resource Option] indexterm:[Resource,Option,target-role] |is-managed |+TRUE+ |Is the cluster allowed to start and stop the resource? Allowed values: +true+, +false+ indexterm:[is-managed,Resource Option] indexterm:[Resource,Option,is-managed] |resource-stickiness |Calculated |How much does the resource prefer to stay where it is? Defaults to the value of +resource-stickiness+ in the +rsc_defaults+ section indexterm:[resource-stickiness,Resource Option] indexterm:[Resource,Option,resource-stickiness] |requires |Calculated |Under what conditions can the resource be started. ('Since 1.1.8') Defaults to +fencing+ unless +stonith-enabled+ is 'false' or +class+ is 'stonith' - under those conditions the default is +quorum+. Possible values: * 'nothing' - can always be started * 'quorum' - The cluster can only start this resource if a majority of the configured nodes are active * 'fencing' - The cluster can only start this resource if a majority of the configured nodes are active _and_ any failed or unknown nodes have been powered off. * 'unfencing' - The cluster can only start this resource if a majority of the configured nodes are active _and_ any failed or unknown nodes have been powered off _and_ only on nodes that have been 'unfenced' indexterm: Option[requires,Resource] indexterm:[Resource,Option,requires] |migration-threshold |+INFINITY+ (disabled) |How many failures may occur for this resource on a node, before this node is marked ineligible to host this resource. indexterm:[migration-threshold,Resource Option] indexterm:[Resource,Option,migration-threshold] |failure-timeout |+0+ (disabled) |How many seconds to wait before acting as if the failure had not occurred, and potentially allowing the resource back to the node on which it failed. indexterm:[failure-timeout,Resource Option] indexterm:[Resource,Option,failure-timeout] |multiple-active |+stop_start+ |What should the cluster do if it ever finds the resource active on more than one node. Allowed values: * 'block' - mark the resource as unmanaged * 'stop_only' - stop all active instances and leave them that way * 'stop_start' - stop all active instances and start the resource in one location only indexterm:[multiple-active,Resource Option] indexterm:[Resource,Option,multiple-active] |remote-node |++ (disabled) |The name of the remote-node this resource defines. This both enables the resource as a remote-node and defines the unique name used to identify the remote-node. If no other parameters are set, this value will also be assumed as the hostname to connect to at port 3121. +WARNING+ This value cannot overlap with any resource or node IDs. |remote-port |+3121+ |Configure a custom port to use for the guest connection to pacemaker_remote. |remote-addr |+remote-node+ value used as hostname |The ip address or hostname to connect to if remote-node's name is not the hostname of the guest. |+remote-connect-timeout+ |+60s+ |How long before a pending guest connection will time out. |========================================================= If you performed the following commands on the previous LSB Email resource [source,C] ------- # crm_resource --meta --resource Email --set-parameter priority --property-value 100 # crm_resource --meta --resource Email --set-parameter multiple-active --property-value block ------- the resulting resource definition would be .An LSB resource with cluster options ===== [source,XML] ------- ------- ===== [[s-resource-defaults]] == Setting Global Defaults for Resource Options == To set a default value for a resource option, simply add it to the +rsc_defaults+ section with `crm_attribute`. Thus, [source,C] # crm_attribute --type rsc_defaults --attr-name is-managed --attr-value false would prevent the cluster from starting or stopping any of the resources in the configuration (unless of course the individual resources were specifically enabled and had +is-managed+ set to +true+). == Instance Attributes == The scripts of some resource classes (LSB not being one of them) can be given parameters which determine how they behave and which instance of a service they control. If your resource agent supports parameters, you can add them with the `crm_resource` command. For instance [source,C] # crm_resource --resource Public-IP --set-parameter ip --property-value 1.2.3.4 would create an entry in the resource like this: .An example OCF resource with instance attributes ===== [source,XML] ------- ------- ===== For an OCF resource, the result would be an environment variable called +OCF_RESKEY_ip+ with a value of +1.2.3.4+. The list of instance attributes supported by an OCF script can be found by calling the resource script with the `meta-data` command. The output contains an XML description of all the supported attributes, their purpose and default values. .Displaying the metadata for the Dummy resource agent template ===== [source,C] ------- # export OCF_ROOT=/usr/lib/ocf # $OCF_ROOT/resource.d/pacemaker/Dummy meta-data ------- [source,XML] ------- 1.0 This is a Dummy Resource Agent. It does absolutely nothing except keep track of whether its running or not. Its purpose in life is for testing and to serve as a template for RA writers. Dummy resource agent Location to store the resource state in. State file Dummy attribute that can be changed to cause a reload Dummy attribute that can be changed to cause a reload ------- ===== == Resource Operations == indexterm:[Resource,Action] === Monitoring Resources for Failure === By default, the cluster will not ensure your resources are still healthy. To instruct the cluster to do this, you need to add a +monitor+ operation to the resource's definition. .An OCF resource with a recurring health check ===== [source,XML] ------- ------- ===== .Properties of an Operation [width="95%",cols="1m,6<",options="header",align="center"] |========================================================= |Field |Description |id |Your name for the action. Must be unique. indexterm:[id,Action Property] indexterm:[Action,Property,id] |name |The action to perform. Common values: +monitor+, +start+, +stop+ indexterm:[name,Action Property] indexterm:[Action,Property,name] |interval |How frequently (in seconds) to perform the operation. Default value: +0+, meaning never. indexterm:[interval,Action Property] indexterm:[Action,Property,interval] |timeout |How long to wait before declaring the action has failed. indexterm:[timeout,Action Property] indexterm:[Action,Property,timeout] |on-fail |The action to take if this action ever fails. Allowed values: * 'ignore' - Pretend the resource did not fail * 'block' - Don't perform any further operations on the resource * 'stop' - Stop the resource and do not start it elsewhere * 'restart' - Stop the resource and start it again (possibly on a different node) * 'fence' - STONITH the node on which the resource failed * 'standby' - Move _all_ resources away from the node on which the resource failed The default for the +stop+ operation is +fence+ when STONITH is enabled and +block+ otherwise. All other operations default to +restart+. indexterm:[on-fail,Action Property] indexterm:[Action,Property,on-fail] |enabled |If +false+, the operation is treated as if it does not exist. Allowed values: +true+, +false+ indexterm:[enabled,Action Property] indexterm:[Action,Property,enabled] |========================================================= [[s-operation-defaults]] === Setting Global Defaults for Operations === To set a default value for a operation option, simply add it to the +op_defaults+ section with `crm_attribute`. Thus, [source,C] # crm_attribute --type op_defaults --attr-name timeout --attr-value 20s would default each operation's +timeout+ to 20 seconds. If an operation's definition also includes a value for +timeout+, then that value would be used instead (for that operation only). ==== When Resources Take a Long Time to Start/Stop ==== There are a number of implicit operations that the cluster will always perform - +start+, +stop+ and a non-recurring +monitor+ operation (used at startup to check the resource isn't already active). If one of these is taking too long, then you can create an entry for them and simply specify a new value. .An OCF resource with custom timeouts for its implicit actions ===== [source,XML] ------- ------- ===== ==== Multiple Monitor Operations ==== Provided no two operations (for a single resource) have the same name and interval you can have as many monitor operations as you like. In this way you can do a superficial health check every minute and progressively more intense ones at higher intervals. To tell the resource agent what kind of check to perform, you need to provide each monitor with a different value for a common parameter. The OCF standard creates a special parameter called +OCF_CHECK_LEVEL+ for this purpose and dictates that it is _"made available to the resource agent without the normal +OCF_RESKEY+ prefix"_. Whatever name you choose, you can specify it by adding an +instance_attributes+ block to the op tag. Note that it is up to each resource agent to look for the parameter and decide how to use it. .An OCF resource with two recurring health checks, performing different levels of checks - specified via +OCF_CHECK_LEVEL+. ===== [source,XML] ------- ------- ===== ==== Disabling a Monitor Operation ==== The easiest way to stop a recurring monitor is to just delete it. However, there can be times when you only want to disable it temporarily. In such cases, simply add +enabled="false"+ to the operation's definition. .Example of an OCF resource with a disabled health check ===== [source,XML] ------- ------- ===== This can be achieved from the command-line by executing [source,C] # cibadmin -M -X '' Once you've done whatever you needed to do, you can then re-enable it with pacemaker-master/doc/Pacemaker_Explained/en-US/Ch-Rules.txt000066400000000000000000000434461217637305600240640ustar00rootroot00000000000000= Rules = //// We prefer [[ch-rules]], but older versions of asciidoc dont deal well with that construct for chapter headings //// anchor:ch-rules[Chapter 8, Rules] indexterm:[Resource,Constraint,Rule] Rules can be used to make your configuration more dynamic. One common example is to set one value for +resource-stickiness+ during working hours, to prevent resources from being moved back to their most preferred location, and another on weekends when no-one is around to notice an outage. Another use of rules might be to assign machines to different processing groups (using a node attribute) based on time and to then use that attribute when creating location constraints. Each rule can contain a number of expressions, date-expressions and even other rules. The results of the expressions are combined based on the rule's +boolean-op+ field to determine if the rule ultimately evaluates to +true+ or +false+. What happens next depends on the context in which the rule is being used. .Properties of a Rule [width="95%",cols="2m,5<",options="header",align="center"] |========================================================= |Field |Description |role |Limits the rule to apply only when the resource is in that role. Allowed values: _Started_, +Slave,+ and +Master+. NOTE: A rule with +role="Master"+ can not determine the initial location of a clone instance. It will only affect which of the active instances will be promoted. indexterm:[role,Constraint Rule] indexterm:[Constraint,Rule,role] |score |The score to apply if the rule evaluates to +true+. Limited to use in rules that are part of location constraints. indexterm:[score,Constraint Rule] indexterm:[Constraint,Rule,score] |score-attribute |The node attribute to look up and use as a score if the rule evaluates to +true+. Limited to use in rules that are part of location constraints. indexterm:[score-attribute,Constraint Rule] indexterm:[Constraint,Rule,score-attribute] |boolean-op |How to combine the result of multiple expression objects. Allowed values: _and_ and +or+. indexterm:[boolean-op,Constraint Rule] indexterm:[Constraint,Rule,boolean-op] |========================================================= == Node Attribute Expressions == indexterm:[Resource,Constraint,Attribute Expression] Expression objects are used to control a resource based on the attributes defined by a node or nodes. In addition to any attributes added by the administrator, each node has a built-in node attribute called +#uname+ that can also be used. .Properties of an Expression [width="95%",cols="2m,5<",options="header",align="center"] |========================================================= |Field |Description |value |User supplied value for comparison indexterm:[value,Constraint Expression] indexterm:[Constraint,Attribute Expression,value] |attribute |The node attribute to test indexterm:[attribute,Constraint Expression] indexterm:[Constraint,Attribute Expression,attribute] |type |Determines how the value(s) should be tested. Allowed values: _string_, +integer+, +version+ indexterm:[type,Constraint Expression] indexterm:[Constraint,Attribute Expression,type] |operation |The comparison to perform. Allowed values: * 'lt' - True if the node attribute's value is less than +value+ * 'gt' - True if the node attribute's value is greater than +value+ * 'lte' - True if the node attribute's value is less than or equal to +value+ * 'gte' - True if the node attribute's value is greater than or equal to +value+ * 'eq' - True if the node attribute's value is equal to +value+ * 'ne' - True if the node attribute's value is not equal to +value+ * 'defined' - True if the node has the named attribute * 'not_defined' - True if the node does not have the named attribute indexterm:[operation,Constraint Expression] indexterm:[Constraint,Attribute Expression,operation] |========================================================= == Time/Date Based Expressions == indexterm:[Time Based Expressions] indexterm:[Resource,Constraint,Date/Time Expression] As the name suggests, +date_expressions+ are used to control a resource or cluster option based on the current date/time. They can contain an optional +date_spec+ and/or +duration+ object depending on the context. .Properties of a Date Expression [width="95%",cols="2m,5<",options="header",align="center"] |========================================================= |Field |Description |start |A date/time conforming to the ISO8601 specification. indexterm:[start,Constraint Expression] indexterm:[Constraint,Date/Time Expression,start] |end |A date/time conforming to the ISO8601 specification. Can be inferred by supplying a value for +start+ and a +duration+. indexterm:[end,Constraint Expression] indexterm:[Constraint,Date/Time Expression,end] |operation |Compares the current date/time with the start and/or end date, depending on the context. Allowed values: * 'gt' - True if the current date/time is after +start+ * 'lt' - True if the current date/time is before +end+ * 'in-range' - True if the current date/time is after +start+ and before +end+ * 'date-spec' - performs a cron-like comparison to the current date/time indexterm:[operation,Constraint Expression] indexterm:[Constraint,Date/Time Expression,operation] |========================================================= [NOTE] ====== As these comparisons (except for +date_spec+) include the time, the +eq+, +neq+, +gte+ and +lte+ operators have not been implemented since they would only be valid for a single second. ====== === Date Specifications === indexterm:[Date Specification] indexterm:[Resource,Constraint,Date Specification] +date_spec+ objects are used to create cron-like expressions relating to time. Each field can contain a single number or a single range. Instead of defaulting to zero, any field not supplied is ignored. For example, +monthdays="1"+ matches the first day of every month and +hours="09-17"+ matches the hours between 9am and 5pm (inclusive). However, at this time one cannot specify +weekdays="1,2"+ or +weekdays="1-2,5-6"+ since they contain multiple ranges. Depending on demand, this may be implemented in a future release. .Properties of a Date Spec [width="95%",cols="2m,5<",options="header",align="center"] |========================================================= |Field |Description |id |A unique name for the date indexterm:[id,Date Specification] indexterm:[Constraint,Date Specification,id] |hours |Allowed values: 0-23 indexterm:[hours,Date Specification] indexterm:[Constraint,Date Specification,hours] |monthdays |Allowed values: 0-31 (depending on month and year) indexterm:[monthdays,Date Specification] indexterm:[Constraint,Date Specification,monthdays] |weekdays |Allowed values: 1-7 (1=Monday, 7=Sunday) indexterm:[weekdays,Date Specification] indexterm:[Constraint,Date Specification,weekdays] |yeardays |Allowed values: 1-366 (depending on the year) indexterm:[yeardays,Date Specification] indexterm:[Constraint,Date Specification,yeardays] |months |Allowed values: 1-12 indexterm:[months,Date Specification] indexterm:[Constraint,Date Specification,months] |weeks |Allowed values: 1-53 (depending on weekyear) indexterm:[weeks,Date Specification] indexterm:[Constraint,Date Specification,weeks] |years |Year according the Gregorian calendar indexterm:[years,Date Specification] indexterm:[Constraint,Date Specification,years] |weekyears |May differ from Gregorian years; Eg. +2005-001 Ordinal+ is also +2005-01-01 Gregorian+ is also +2004-W53-6 Weekly+ indexterm:[weekyears,Date Specification] indexterm:[Constraint,Date Specification,weekyears] |moon |Allowed values: 0-7 (0 is new, 4 is full moon). Seriously, you can use this. This was implemented to demonstrate the ease with which new comparisons could be added. indexterm:[moon,Date Specification] indexterm:[Constraint,Date Specification,moon] |========================================================= === Durations === indexterm:[Duration] indexterm:[Resource,Constraint,Duration] Durations are used to calculate a value for +end+ when one is not supplied to in_range operations. They contain the same fields as +date_spec+ objects but without the limitations (ie. you can have a duration of 19 months). Like +date_specs+, any field not supplied is ignored. == Sample Time Based Expressions == A small sample of how time based expressions can be used. //// On older versions of asciidoc, the [source] directive makes the title dissappear //// .True if now is any time in the year 2005 ==== [source,XML] ---- ---- ==== .Equivalent expression ==== [source,XML] ---- ---- ==== .9am-5pm, Mon-Friday ==== [source,XML] ------- ------- ==== Please note that the +16+ matches up to +16:59:59+, as the numeric value (hour) still matches! .9am-6pm, Mon-Friday, or all day saturday ==== [source,XML] ------- ------- ==== .9am-5pm or 9pm-12pm, Mon-Friday ==== [source,XML] ------- ------- ==== .Mondays in March 2005 ==== [source,XML] ------- ------- ==== [NOTE] ====== Because no time is specified, 00:00:00 is implied. This means that the range includes all of 2005-03-01 but none of 2005-04-01. You may wish to write +end="2005-03-31T23:59:59"+ to avoid confusion. ====== .A full moon on Friday the 13th ===== [source,XML] ------- ------- ===== == Using Rules to Determine Resource Location == indexterm:[Rule,Determine Resource Location] indexterm:[Resource,Location,Determine by Rules] If the constraint's outer-most rule evaluates to +false+, the cluster treats the constraint as if it was not there. When the rule evaluates to +true+, the node's preference for running the resource is updated with the score associated with the rule. If this sounds familiar, its because you have been using a simplified syntax for location constraint rules already. Consider the following location constraint: .Prevent myApacheRsc from running on c001n03 ===== [source,XML] ------- ------- ===== This constraint can be more verbosely written as: .Prevent myApacheRsc from running on c001n03 - expanded version ===== [source,XML] ------- ------- ===== The advantage of using the expanded form is that one can then add extra clauses to the rule, such as limiting the rule such that it only applies during certain times of the day or days of the week (this is discussed in subsequent sections). It also allows us to match on node properties other than its name. If we rated each machine's CPU power such that the cluster had the following nodes section: .A sample nodes section for use with score-attribute ===== [source,XML] ------- ------- ===== then we could prevent resources from running on underpowered machines with the rule [source,XML] ------- ------- === Using +score-attribute+ Instead of +score+ === When using +score-attribute+ instead of +score+, each node matched by the rule has its score adjusted differently, according to its value for the named node attribute. Thus, in the previous example, if a rule used +score-attribute="cpu_mips"+, +c001n01+ would have its preference to run the resource increased by +1234+ whereas +c001n02+ would have its preference increased by +5678+. == Using Rules to Control Resource Options == Often some cluster nodes will be different from their peers; sometimes these differences (the location of a binary or the names of network interfaces) require resources to be configured differently depending on the machine they're hosted on. By defining multiple +instance_attributes+ objects for the resource and adding a rule to each, we can easily handle these special cases. In the example below, +mySpecialRsc+ will use eth1 and port 9999 when run on +node1+, eth2 and port 8888 on +node2+ and default to eth0 and port 9999 for all other nodes. .Defining different resource options based on the node name ===== [source,XML] ------- ------- ===== The order in which +instance_attributes+ objects are evaluated is determined by their score (highest to lowest). If not supplied, score defaults to zero and objects with an equal score are processed in listed order. If the +instance_attributes+ object does not have a +rule+ or has a +rule+ that evaluates to +true+, then for any parameter the resource does not yet have a value for, the resource will use the parameter values defined by the +instance_attributes+ object. == Using Rules to Control Cluster Options == indexterm:[Rule,Controlling Cluster Options] indexterm:[Cluster,Setting Options with Rules] Controlling cluster options is achieved in much the same manner as specifying different resource options on different nodes. The difference is that because they are cluster options, one cannot (or should not, because they won't work) use attribute based expressions. The following example illustrates how to set a different +resource-stickiness+ value during and outside of work hours. This allows resources to automatically move back to their most preferred hosts, but at a time that (in theory) does not interfere with business activities. .Change +resource-stickiness+ during working hours ===== [source,XML] ------- ------- ===== [[s-rules-recheck]] == Ensuring Time Based Rules Take Effect == A Pacemaker cluster is an event driven system. As such, it won't recalculate the best place for resources to run in unless something (like a resource failure or configuration change) happens. This can mean that a location constraint that only allows resource X to run between 9am and 5pm is not enforced. If you rely on time based rules, it is essential that you set the +cluster-recheck-interval+ option. This tells the cluster to periodically recalculate the ideal state of the cluster. For example, if you set +cluster-recheck-interval=5m+, then sometime between 9:00 and 9:05 the cluster would notice that it needs to start resource X, and between 17:00 and 17:05 it would realize that X needed to be stopped. Note that the timing of the actual start and stop actions depends on what else needs to be performed first . pacemaker-master/doc/Pacemaker_Explained/en-US/Ch-Status.txt000066400000000000000000000316321217637305600242470ustar00rootroot00000000000000= Status - Here be dragons = Most users never need to understand the contents of the status section and can be happy with the output from `crm_mon`. However for those with a curious inclination, this section attempts to provide an overview of its contents. == Node Status == indexterm:[Node,Status] indexterm:[Status of a Node] In addition to the cluster's configuration, the CIB holds an up-to-date representation of each cluster node in the status section. .A bare-bones status entry for a healthy node called +cl-virt-1+ ====== [source,XML] ----- ----- ====== Users are highly recommended _not to modify_ any part of a node's state _directly_. The cluster will periodically regenerate the entire section from authoritative sources. So any changes should be done with the tools for those subsystems. .Authoritative Sources for State Information [width="95%",cols="5m,5<",options="header",align="center"] |========================================================= |Dataset |Authoritative Source |node_state fields |crmd |transient_attributes tag |attrd |lrm tag |lrmd |========================================================= The fields used in the +node_state+ objects are named as they are largely for historical reasons and are rooted in Pacemaker's origins as the Heartbeat resource manager. They have remained unchanged to preserve compatibility with older versions. .Node Status Fields [width="95%",cols="2m,5<",options="header",align="center"] |========================================================= |Field |Description | id | indexterm:[id,Node Status] indexterm:[Node,Status,id] Unique identifier for the node. Corosync based clusters use the uname of the machine, Heartbeat clusters use a human-readable (but annoying) UUID. | uname | indexterm:[uname,Node Status] indexterm:[Node,Status,uname] The node's machine name (output from `uname -n`). | ha | indexterm:[ha,Node Status] indexterm:[Node,Status,ha] Flag specifying whether the cluster software is active on the node. Allowed values: +active+, +dead+. | in_ccm | indexterm:[in_ccm,Node Status] indexterm:[Node,Status,in_ccm] Flag for cluster membership; allowed values: +true+, +false+. | crmd | indexterm:[crmd,Node Status] indexterm:[Node,Status,crmd] Flag: is the crmd process active on the node? One of +online+, +offline+. | join | indexterm:[join,Node Status] indexterm:[Node,Status,join] Flag saying whether the node participates in hosting resources. Possible values: +down+, +pending+, +member+, +banned+. | expected | indexterm:[expected,Node Status] indexterm:[Node,Status,expected] Expected value for +join+. | crm-debug-origin | indexterm:[crm-debug-origin,Node Status] indexterm:[Node,Status,crm-debug-origin] Diagnostic indicator: the origin of the most recent change(s). |========================================================= The cluster uses these fields to determine if, at the node level, the node is healthy or is in a failed state and needs to be fenced. == Transient Node Attributes == Like regular <>, the name/value pairs listed here also help to describe the node. However they are forgotten by the cluster when the node goes offline. This can be useful, for instance, when you want a node to be in standby mode (not able to run resources) until the next reboot. In addition to any values the administrator sets, the cluster will also store information about failed resources here. .Example set of transient node attributes for node "cl-virt-1" ====== [source,XML] ----- ----- ====== In the above example, we can see that the +pingd:0+ resource has failed once, at +Mon Apr 6 11:22:22 2009+. footnote:[ You can use the standard +date+ command to print a human readable of any seconds-since-epoch value: # `date -d @number` ] We also see that the node is connected to three "pingd" peers and that all known resources have been checked for on this machine (+probe_complete+). == Operation History == indexterm:[Operation History] A node's resource history is held in the +lrm_resources+ tag (a child of the +lrm+ tag). The information stored here includes enough information for the cluster to stop the resource safely if it is removed from the +configuration+ section. Specifically the resource's +id+, +class+, +type+ and +provider+ are stored. .A record of the apcstonith resource ====== [source,XML] ====== Additionally, we store the last job for every combination of +resource, action+ and +interval+. The concatenation of the values in this tuple are used to create the id of the +lrm_rsc_op+ object. .Contents of an +lrm_rsc_op+ job [width="95%",cols="2m,5<",options="header",align="center"] |========================================================= |Field |Description | id | indexterm:[id,Action Status] indexterm:[Action,Status,id] Identifier for the job constructed from the resource's +id+, +operation+ and +interval+. | call-id | indexterm:[call-id,Action Status] indexterm:[Action,Status,call-id] The job's ticket number. Used as a sort key to determine the order in which the jobs were executed. | operation | indexterm:[operation,Action Status] indexterm:[Action,Status,operation] The action the resource agent was invoked with. | interval | indexterm:[interval,Action Status] indexterm:[Action,Status,interval] The frequency, in milliseconds, at which the operation will be repeated. A one-off job is indicated by 0. | op-status | indexterm:[op-status,Action Status] indexterm:[Action,Status,op-status] The job's status. Generally this will be either 0 (done) or -1 (pending). Rarely used in favor of +rc-code+. | rc-code | indexterm:[rc-code,Action Status] indexterm:[Action,Status,rc-code] The job's result. Refer to <> for details on what the values here mean and how they are interpreted. | last-run | indexterm:[last-run,Action Status] indexterm:[Action,Status,last-run] Diagnostic indicator. Machine local date/time, in seconds since epoch, at which the job was executed. | last-rc-change | indexterm:[last-rc-change,Action Status] indexterm:[Action,Status,last-rc-change] Diagnostic indicator. Machine local date/time, in seconds since epoch, at which the job first returned the current value of +rc-code+. | exec-time | indexterm:[exec-time,Action Status] indexterm:[Action,Status,exec-time] Diagnostic indicator. Time, in milliseconds, that the job was running for. | queue-time | indexterm:[queue-time,Action Status] indexterm:[Action,Status,queue-time] Diagnostic indicator. Time, in seconds, that the job was queued for in the LRMd. | crm_feature_set | indexterm:[crm_feature_set,Action Status] indexterm:[Action,Status,crm_feature_set] The version which this job description conforms to. Used when processing +op-digest+. | transition-key | indexterm:[transition-key,Action Status] indexterm:[Action,Status,transition-key] A concatenation of the job's graph action number, the graph number, the expected result and the UUID of the crmd instance that scheduled it. This is used to construct +transition-magic+ (below). | transition-magic | indexterm:[transition-magic,Action Status] indexterm:[Action,Status,transition-magic] A concatenation of the job's +op-status+, +rc-code+ and +transition-key+. Guaranteed to be unique for the life of the cluster (which ensures it is part of CIB update notifications) and contains all the information needed for the crmd to correctly analyze and process the completed job. Most importantly, the decomposed elements tell the crmd if the job entry was expected and whether it failed. | op-digest | indexterm:[op-digest,Action Status] indexterm:[Action,Status,op-digest] An MD5 sum representing the parameters passed to the job. Used to detect changes to the configuration, to restart resources if necessary. | crm-debug-origin | indexterm:[crm-debug-origin,Action Status] indexterm:[Action,Status,crm-debug-origin] Diagnostic indicator. The origin of the current values. |========================================================= === Simple Example === .A monitor operation (determines current state of the apcstonith resource) ====== [source,XML] ----- ----- ====== In the above example, the job is a non-recurring monitor operation often referred to as a "probe" for the +apcstonith+ resource. The cluster schedules probes for every configured resource on when a new node starts, in order to determine the resource's current state before it takes any further action. From the +transition-key+, we can see that this was the 22nd action of the 2nd graph produced by this instance of the crmd (2668bbeb-06d5-40f9-936d-24cb7f87006a). The third field of the +transition-key+ contains a 7, this indicates that the job expects to find the resource inactive. By looking at the +rc-code+ property, we see that this was the case. As that is the only job recorded for this node we can conclude that the cluster started the resource elsewhere. === Complex Resource History Example === .Resource history of a pingd clone with multiple jobs ====== [source,XML] ----- ----- ====== When more than one job record exists, it is important to first sort them by +call-id+ before interpreting them. Once sorted, the above example can be summarized as: . A non-recurring monitor operation returning 7 (not running), with a +call-id+ of 3 . A stop operation returning 0 (success), with a +call-id+ of 32 . A start operation returning 0 (success), with a +call-id+ of 33 . A recurring monitor returning 0 (success), with a +call-id+ of 34 The cluster processes each job record to build up a picture of the resource's state. After the first and second entries, it is considered stopped and after the third it considered active. Based on the last operation, we can tell that the resource is currently active. Additionally, from the presence of a +stop+ operation with a lower +call-id+ than that of the +start+ operation, we can conclude that the resource has been restarted. Specifically this occurred as part of actions 11 and 31 of transition 11 from the crmd instance with the key +2668bbeb...+. This information can be helpful for locating the relevant section of the logs when looking for the source of a failure. pacemaker-master/doc/Pacemaker_Explained/en-US/Ch-Stonith.txt000066400000000000000000001110041217637305600244040ustar00rootroot00000000000000= Configure STONITH = //// We prefer [[ch-stonith]], but older versions of asciidoc dont deal well with that construct for chapter headings //// anchor:ch-stonith[Chapter 13, STONITH] indexterm:[STONITH, Configuration] == What Is STONITH == STONITH is an acronym for Shoot-The-Other-Node-In-The-Head and it protects your data from being corrupted by rogue nodes or concurrent access. Just because a node is unresponsive, this doesn't mean it isn't accessing your data. The only way to be 100% sure that your data is safe, is to use STONITH so we can be certain that the node is truly offline, before allowing the data to be accessed from another node. STONITH also has a role to play in the event that a clustered service cannot be stopped. In this case, the cluster uses STONITH to force the whole node offline, thereby making it safe to start the service elsewhere. == What STONITH Device Should You Use == It is crucial that the STONITH device can allow the cluster to differentiate between a node failure and a network one. The biggest mistake people make in choosing a STONITH device is to use remote power switch (such as many on-board IMPI controllers) that shares power with the node it controls. In such cases, the cluster cannot be sure if the node is really offline, or active and suffering from a network fault. Likewise, any device that relies on the machine being active (such as SSH-based "devices" used during testing) are inappropriate. == Differences of STONITH Resources == Stonith resources are somewhat special in Pacemaker. In previous versions, only "running" resources could be used by Pacemaker for fencing. This requirement has been relaxed to allow other parts of the cluster (such as resources like DRBD) to reliably initiate fencing. footnote:[Fencing a node while Pacemaker was moving stonith resources around would otherwise fail] Now all nodes have access to their definitions and instantiate them on-the-fly when needed, however preference is given to 'verified' instances which are the ones the cluster has explicitly started. In the case of a cluster split, the partition with a verified instance will have a slight advantage as stonith-ng in the other partition will have to hear from all its current peers before choosing a node to perform the fencing. [NOTE] =========== To disable a fencing device/resource, 'target-role' can be set as you would for a normal resource. =========== [NOTE] =========== To prevent a specific node from using a fencing device, location constraints will work as expected. =========== [IMPORTANT] =========== Currently there is a limitation that fencing resources may only have a one set of meta-attributes and one set of instance-attributes. This can be revisited if it becomes a significant limitation for people. =========== .Properties of Fencing Devices [width="95%",cols="1m,1m,1m,5<",options="header",align="center"] |========================================================= |Field |Type |Default |Description |stonith-timeout |time |60s |How long to wait for the STONITH action to complete per a stonith device. Overrides the stonith-timeout cluster property indexterm:[stonith-timeout,Fencing] indexterm:[Fencing,Property,stonith-timeout] |priority |integer |0 |The priority of the stonith resource. Devices are tried in order of highest priority to lowest. indexterm:[priority,Fencing] indexterm:[Fencing,Property,priority] |pcmk_host_argument |string |port |Advanced use only: An alternate parameter to supply instead of 'port' Some devices do not support the standard 'port' parameter or may provide additional ones. Use this to specify an alternate, device-specific, parameter that should indicate the machine to be fenced. A value of 'none' can be used to tell the cluster not to supply any additional parameters. indexterm:[pcmk_host_argument,Fencing] indexterm:[Fencing,Property,pcmk_host_argument] |pcmk_host_map |string | |A mapping of host names to ports numbers for devices that do not support host names. Eg. node1:1;node2:2,3 would tell the cluster to use port 1 for node1 and ports 2 and 3 for node2 indexterm:[pcmk_host_map,Fencing] indexterm:[Fencing,Property,pcmk_host_map] |pcmk_host_list |string | |A list of machines controlled by this device (Optional unless pcmk_host_check=static-list). indexterm:[pcmk_host_list,Fencing] indexterm:[Fencing,Property,pcmk_host_list] |pcmk_host_check |string |dynamic-list |How to determin which machines are controlled by the device. Allowed values: dynamic-list (query the device), static-list (check the pcmk_host_list attribute), none (assume every device can fence every machine) indexterm:[pcmk_host_check,Fencing] indexterm:[Fencing,Property,pcmk_host_check] |pcmk_reboot_action |string |reboot |Advanced use only: An alternate command to run instead of 'reboot' Some devices do not support the standard commands or may provide additional ones. Use this to specify an alternate, device-specific, command that implements the 'reboot' action. indexterm:[pcmk_reboot_action,Fencing] indexterm:[Fencing,Property,pcmk_reboot_action] |pcmk_reboot_timeout |time |60s |Advanced use only: Specify an alternate timeout to use for reboot actions instead of stonith-timeout Some devices need much more/less time to complete than normal. Use this to specify an alternate, device-specific, timeout for 'reboot' actions. indexterm:[pcmk_reboot_timeout,Fencing] indexterm:[Fencing,Property,pcmk_reboot_timeout] |pcmk_reboot_retries |integer |2 |Advanced use only: The maximum number of times to retry the 'reboot' command within the timeout period Some devices do not support multiple connections. Operations may 'fail' if the device is busy with another task so Pacemaker will automatically retry the operation, if there is time remaining. Use this option to alter the number of times Pacemaker retries 'reboot' actions before giving up. indexterm:[pcmk_reboot_retries,Fencing] indexterm:[Fencing,Property,pcmk_reboot_retries] |pcmk_off_action |string |off |Advanced use only: An alternate command to run instead of 'off' Some devices do not support the standard commands or may provide additional ones. Use this to specify an alternate, device-specific, command that implements the 'off' action. indexterm:[pcmk_off_action,Fencing] indexterm:[Fencing,Property,pcmk_off_action] |pcmk_off_timeout |time |60s |Advanced use only: Specify an alternate timeout to use for off actions instead of stonith-timeout Some devices need much more/less time to complete than normal. Use this to specify an alternate, device-specific, timeout for 'off' actions. indexterm:[pcmk_off_timeout,Fencing] indexterm:[Fencing,Property,pcmk_off_timeout] |pcmk_off_retries |integer |2 |Advanced use only: The maximum number of times to retry the 'off' command within the timeout period Some devices do not support multiple connections. Operations may 'fail' if the device is busy with another task so Pacemaker will automatically retry the operation, if there is time remaining. Use this option to alter the number of times Pacemaker retries 'off' actions before giving up. indexterm:[pcmk_off_retries,Fencing] indexterm:[Fencing,Property,pcmk_off_retries] |pcmk_list_action |string |list |Advanced use only: An alternate command to run instead of 'list' Some devices do not support the standard commands or may provide additional ones. Use this to specify an alternate, device-specific, command that implements the 'list' action. indexterm:[pcmk_list_action,Fencing] indexterm:[Fencing,Property,pcmk_list_action] |pcmk_list_timeout |time |60s |Advanced use only: Specify an alternate timeout to use for list actions instead of stonith-timeout Some devices need much more/less time to complete than normal. Use this to specify an alternate, device-specific, timeout for 'list' actions. indexterm:[pcmk_list_timeout,Fencing] indexterm:[Fencing,Property,pcmk_list_timeout] |pcmk_list_retries |integer |2 |Advanced use only: The maximum number of times to retry the 'list' command within the timeout period Some devices do not support multiple connections. Operations may 'fail' if the device is busy with another task so Pacemaker will automatically retry the operation, if there is time remaining. Use this option to alter the number of times Pacemaker retries 'list' actions before giving up. indexterm:[pcmk_list_retries,Fencing] indexterm:[Fencing,Property,pcmk_list_retries] |pcmk_monitor_action |string |monitor |Advanced use only: An alternate command to run instead of 'monitor' Some devices do not support the standard commands or may provide additional ones. Use this to specify an alternate, device-specific, command that implements the 'monitor' action. indexterm:[pcmk_monitor_action,Fencing] indexterm:[Fencing,Property,pcmk_monitor_action] |pcmk_monitor_timeout |time |60s |Advanced use only: Specify an alternate timeout to use for monitor actions instead of stonith-timeout Some devices need much more/less time to complete than normal. Use this to specify an alternate, device-specific, timeout for 'monitor' actions. indexterm:[pcmk_monitor_timeout,Fencing] indexterm:[Fencing,Property,pcmk_monitor_timeout] |pcmk_monitor_retries |integer |2 |Advanced use only: The maximum number of times to retry the 'monitor' command within the timeout period Some devices do not support multiple connections. Operations may 'fail' if the device is busy with another task so Pacemaker will automatically retry the operation, if there is time remaining. Use this option to alter the number of times Pacemaker retries 'monitor' actions before giving up. indexterm:[pcmk_monitor_retries,Fencing] indexterm:[Fencing,Property,pcmk_monitor_retries] |pcmk_status_action |string |status |Advanced use only: An alternate command to run instead of 'status' Some devices do not support the standard commands or may provide additional ones. Use this to specify an alternate, device-specific, command that implements the 'status' action. indexterm:[pcmk_status_action,Fencing] indexterm:[Fencing,Property,pcmk_status_action] |pcmk_status_timeout |time |60s |Advanced use only: Specify an alternate timeout to use for status actions instead of stonith-timeout Some devices need much more/less time to complete than normal. Use this to specify an alternate, device-specific, timeout for 'status' actions. indexterm:[pcmk_status_timeout,Fencing] indexterm:[Fencing,Property,pcmk_status_timeout] |pcmk_status_retries |integer |2 |Advanced use only: The maximum number of times to retry the 'status' command within the timeout period Some devices do not support multiple connections. Operations may 'fail' if the device is busy with another task so Pacemaker will automatically retry the operation, if there is time remaining. Use this option to alter the number of times Pacemaker retries 'status' actions before giving up. indexterm:[pcmk_status_retries,Fencing] indexterm:[Fencing,Property,pcmk_status_retries] |========================================================= == Configuring STONITH == [NOTE] =========== Both configuration shells include functionality to simplify the process below, particularly the step for deciding which parameters are required. However since this document deals only with core components, you should refer to the Stonith chapter of +Clusters from Scratch+ for those details. =========== . Find the correct driver: +stonith_admin --list-installed+ . Find the required parameters associated with the device: +stonith_admin --metadata --agent + . Create a file called +stonith.xml+ containing a primitive resource with a class of 'stonith', a type of and a parameter for each of the values returned in step 2. . If the device does not know how to fence nodes based on their uname, you may also need to set the special +pcmk_host_map+ parameter. See +man stonithd+ for details. . If the device does not support the list command, you may also need to set the special +pcmk_host_list+ and/or +pcmk_host_check+ parameters. See +man stonithd+ for details. . If the device does not expect the victim to be specified with the port parameter, you may also need to set the special +pcmk_host_argument+ parameter. See +man stonithd+ for details. . Upload it into the CIB using cibadmin: +cibadmin -C -o resources --xml-file stonith.xml+ . Set stonith-enabled to true. +crm_attribute -t crm_config -n stonith-enabled -v true+ . Once the stonith resource is running, you can test it by executing: +stonith_admin --reboot nodename+. Although you might want to stop the cluster on that machine first. === Example === Assuming we have an chassis containing four nodes and an IPMI device active on 10.0.0.1, then we would chose the fence_ipmilan driver in step 2 and obtain the following list of parameters .Obtaining a list of STONITH Parameters [source,C] ---- # stonith_admin --metadata -a fence_ipmilan ---- [source,XML] ---- fence_ipmilan is an I/O Fencing agent which can be used with machines controlled by IPMI. This agent calls support software using ipmitool (http://ipmitool.sf.net/). To use fence_ipmilan with HP iLO 3 you have to enable lanplus option (lanplus / -P) and increase wait after operation to 4 seconds (power_wait=4 / -T 4) IPMI Lan Auth type (md5, password, or none) IPMI Lan IP to talk to Password (if required) to control power on IPMI device Script to retrieve password (if required) Use Lanplus Username/Login (if required) to control power on IPMI device Operation to perform. Valid operations: on, off, reboot, status, list, diag, monitor or metadata Timeout (sec) for IPMI operation Ciphersuite to use (same as ipmitool -C parameter) Method to fence (onoff or cycle) Wait X seconds after on/off operation Wait X seconds before fencing is started Verbose mode ---- from which we would create a STONITH resource fragment that might look like this: .Sample STONITH Resource [source,XML] ---- ---- And finally, since we disabled it earlier, we need to re-enable STONITH. [source,Bash] ---- # crm_attribute -t crm_config -n stonith-enabled -v true ---- == Advanced Fencing Configurations == Some people consider that having one fencing device is a single point of failure footnote:[Not true, since a node or resource must fail before fencing even has a chance to], others prefer removing the node from the storage and network instead of turning it off. Whatever the reason, Pacemaker supports fencing nodes with multiple devices through a feature called fencing topologies. Simply create the individual devices as you normally would and then define one or more fencing levels in the fencing-topology section in the configuration. * Each level is attempted in +ascending index+ order * If a device fails, +processing terminates+ for the current level. No further devices in that level are exercised and the next level is attempted instead. * If the operation succeeds for all the listed devices in a level, the level is deemed to have passed * The operation is finished +when a level has passed+ (success), or all levels have been attempted (failed) * If the operation failed, the next step is determined by the Policy Engine and/or crmd. Some possible uses of topologies include: * try poison-pill and fail back to power * try disk and network, and fall back to power if either fails * initiate a kdump and then poweroff the node .Properties of Fencing Levels [width="95%",cols="1m,6<",options="header",align="center"] |========================================================= |Field |Description |id |Your name for the level indexterm:[id,fencing-level] indexterm:[Fencing,fencing-level,id] |target |The node to which this level applies indexterm:[target,fencing-level] indexterm:[Fencing,fencing-level,target] |index |The order in which to attempt the levels. Levels are attempted in +ascending index+ order +until one succeeds+. indexterm:[index,fencing-level] indexterm:[Fencing,fencing-level,index] |devices |A comma separated list of devices for which the indexterm:[devices,fencing-level] indexterm:[Fencing,fencing-level,devices] |========================================================= === Example use of Fencing Topologies === [source,XML] ---- ... ... ---- === Example use of advanced Fencing Topologies: dual layer and dual devices === The following example illustrates an advanced use of +fencing_topology+ in a cluster with the following properties: * 3 nodes (2 active prod-mysql nodes, 1 prod_mysql-rep in standby for quorum purposes) * the active nodes have an IPMI-controlled power board reached at 10.10.10.1 and 10.10.10.2 * the active nodes also have two independant PSUs (Power Supplu Units) connected to two independant PDUs (Power Distribution Unit) reached at 10.20.1.1 (port 10 and port 11) and 10.20.2.1 (port 10 and port 11) * the first fencing method uses the +fence_ipmi+ agent * the second fencing method uses the +fence_apc_snmp+ agent targetting 2 fencing devices (one per PSU, either port 10 or 11) * fencing is only implemented for the active nodes and has location constraints * fencing topology is set to try IPMI fencing first then default to a "sure-kill" dual PDU fencing In a normal failure scenario, STONITH will first select +fence_ipmi+ to try and kill the faulty node. Using a +fencing_topology+, if that first method fails, STONITH will then move on to selecting +fence_apc_snmp+ twice: * once for the first PDU * again for the second PDU The fence action is considered successful only if both PDUs report the required status. If any of them fails, STONITH loops back to the first fencing method, +fence_ipmi+, and so on until the node is fenced or fencing action is cancelled. .First fencing method: single IPMI device Each cluster node has it own dedicated IPMI channel that can be called for fencing using the following primitives: [source,XML] ---- ---- .Second fencing method: dual PDU devices Each cluster node also has two distinct power channels controlled by two distinct PDUs. That means a total of 4 fencing devices configured as follows: - Node 1, PDU 1, PSU 1 @ port 10 - Node 1, PDU 2, PSU 2 @ port 10 - Node 2, PDU 1, PSU 1 @ port 11 - Node 2, PDU 2, PSU 2 @ port 11 The matching fencing agents are configured as follows: [source,XML] ---- ---- .Location Constraints To prevent STONITH from running a fencing agent on the very same node it is supposed to fence, constraints are placed on all the fencing primitives: [source,XML] ---- ---- .Fencing topology Now that all the fencing resources are defined, it's time to create the right topology. We want to first fence using IPMI and if that does not work, fence both PDUs to effectively and surely kill the node. [source,XML] ---- ---- Please note, in +fencing_topology+, the lower index value determines the priority of the first fencing method. .Final configuration Put together, the configuration looks like this: [source,XML] ---- ... ... ---- pacemaker-master/doc/Pacemaker_Explained/en-US/Ch-Utilization.txt000066400000000000000000000210671217637305600253000ustar00rootroot00000000000000= Utilization and Placement Strategy = == Background == Pacemaker decides where to place a resource according to the resource allocation scores on every node. The resource will be allocated to the node where the resource has the highest score. If the resource allocation scores on all the nodes are equal, by the `default` placement strategy, Pacemaker will choose a node with the least number of allocated resources for balancing the load. If the number of resources on each node is equal, the first eligible node listed in cib will be chosen to run the resource. Though resources are different. They may consume different amounts of the capacities of the nodes. Actually, we cannot ideally balance the load just according to the number of resources allocated to a node. Besides, if resources are placed such that their combined requirements exceed the provided capacity, they may fail to start completely or run with degraded performance. To take these into account, Pacemaker allows you to specify the following configurations: . The `capacity` a certain `node provides`. . The `capacity` a certain `resource requires`. . An overall `strategy` for placement of resources. == Utilization attributes == To configure the capacity a node provides and the resource's requirements, use `utilization` attributes. You can name the `utilization` attributes according to your preferences and define as many `name/value` pairs as your configuration needs. However, the attribute's values must be `integers`. First, specify the capacities the nodes provide: [source,XML] ---- ---- Then, specify the capacities the resources require: [source,XML] ---- ---- A node is considered eligible for a resource if it has sufficient free capacity to satisfy the resource's requirements. The nature of the required or provided capacities is completely irrelevant for Pacemaker, it just makes sure that all capacity requirements of a resource are satisfied before placing a resource to a node. == Placement Strategy == After you have configured the capacities your nodes provide and the capacities your resources require, you need to set the `placement-strategy` in the global cluster options, otherwise the capacity configurations have `no effect`. Four values are available for the `placement-strategy`: `default`:: Utilization values are not taken into account at all, per default. Resources are allocated according to allocation scores. If scores are equal, resources are evenly distributed across nodes. `utilization`:: Utilization values are taken into account when deciding whether a node is considered eligible if it has sufficient free capacity to satisfy the resource's requirements. However, load-balancing is still done based on the number of resources allocated to a node. `balanced`:: Utilization values are taken into account when deciding whether a node is eligible to serve a resource; an attempt is made to spread the resources evenly, optimizing resource performance. `minimal`:: Utilization values are taken into account when deciding whether a node is eligible to serve a resource; an attempt is made to concentrate the resources on as few nodes as possible, thereby enabling possible power savings on the remaining nodes. Set `placement-strategy` with `crm_attribute`: [source,C] # crm_attribute --attr-name placement-strategy --attr-value balanced Now Pacemaker will ensure the load from your resources will be distributed evenly throughout the cluster - without the need for convoluted sets of colocation constraints. == Allocation Details == === Which node is preferred to be chosen to get consumed first on allocating resources? === - The node that is most healthy (which has the highest node weight) gets consumed first. - If their weights are equal: * If `placement-strategy="default|utilization"`, the node that has the least number of allocated resources gets consumed first. ** If their numbers of allocated resources are equal, the first eligible node listed in cib gets consumed first. * If `placement-strategy="balanced"`, the node that has more free capacity gets consumed first. ** If the free capacities of the nodes are equal, the node that has the least number of allocated resources gets consumed first. *** If their numbers of allocated resources are equal, the first eligible node listed in cib gets consumed first. * If `placement-strategy="minimal"`, the first eligible node listed in cib gets consumed first. ==== Which node has more free capacity? ==== This will be quite clear if we only define one type of `capacity`. While if we define multiple types of `capacity`, for example: - If `nodeA` has more free `cpus`, `nodeB` has more free `memory`, their free capacities are equal. - If `nodeA` has more free `cpus`, while `nodeB` has more free `memory` and `storage`, `nodeB` has more free capacity. === Which resource is preferred to be chosen to get assigned first? === - The resource that has the highest priority gets allocated first. - If their priorities are equal, check if they are already running. The resource that has the highest score on the node where it's running gets allocated first (to prevent resource shuffling). - If the scores above are equal or they are not running, the resource has the highest score on the preferred node gets allocated first. - If the scores above are equal, the first runnable resource listed in cib gets allocated first. == Limitations == This type of problem Pacemaker is dealing with here is known as the http://en.wikipedia.org/wiki/Knapsack_problem[knapsack problem] and falls into the http://en.wikipedia.org/wiki/NP-complete[NP-complete] category of computer science problems - which is fancy way of saying "it takes a really long time to solve". Clearly in a HA cluster, it's not acceptable to spend minutes, let alone hours or days, finding an optional solution while services remain unavailable. So instead of trying to solve the problem completely, Pacemaker uses a 'best effort' algorithm for determining which node should host a particular service. This means it arrives at a solution much faster than traditional linear programming algorithms, but by doing so at the price of leaving some services stopped. In the contrived example above: - `rsc-small` would be allocated to `node1` - `rsc-medium` would be allocated to `node2` - `rsc-large` would remain inactive Which is not ideal. == Strategies for Dealing with the Limitations == - Ensure you have sufficient physical capacity. It might sounds obvious, but if the physical capacity of your nodes is (close to) maxed out by the cluster under normal conditions, then failover isn't going to go well. Even without the Utilization feature, you'll start hitting timeouts and getting secondary failures'. - Build some buffer into the capabilities advertised by the nodes. Advertise slightly more resources than we physically have on the (usually valid) assumption that a resource will not use 100% of the configured number of cpu/memory/etc `all` the time. This practice is also known as 'over commit'. - Specify resource priorities. If the cluster is going to sacrifice services, it should be the ones you care (comparatively) about the least. Ensure that resource priorities are properly set so that your most important resources are scheduled first. pacemaker-master/doc/Pacemaker_Explained/en-US/NOTES000066400000000000000000000032421217637305600225020ustar00rootroot00000000000000 That's a "+", not a hyphen: Key combinations can be distinguished from keycaps by the hyphen connecting each part of a key combination. For example: Press Enter to execute the command. Press Ctrl+Alt+F2 to switch to the first virtual terminal. Press Ctrl+Alt+F1 to return to your X-Windows session. doesn't apply here: If source code is discussed, class names, methods, functions, v including application names; dialog box text; labeled buttons; check-box and radio button labels; menu titles and sub-menu titles. 1.2 terminal output has page-break 2.3 editing via VI isn't that racy? Are concurrent changes detected? why sometimes and sometimes
? example 2.2 has title at top, different to the figures 2.8 header slightly too long, line broken some are in , some in ... I'd like the latter more, or perhaps in a . Indentation makes whitespace at start of lines ... remove? Chapter 3 ========= - table 3.3 "Properties maintained by the Cluster" incomplete (crm-feature-set, ...) 4.4.2 structure different from 4.4.1 ... numbered lists 5.3 Notes have next content overlaid ex 5.6: 1.0 ???? perhaps use 10.20.30.40 instead of the 1.2.3.4 example IP address? 6.5 images/resource-set.png missing, "images/two-sets.png" too; images/three-sets; "images/three-sets-complex.png" Ch 7 missing? Remove Ex9.9? collocate or colocate? Eg. in C.1: Multi-dimensional colocation and ordering constraints. See Section 6.5, “Ordering Sets of Resources” and Section 6.6, “Collocating Sets of Resources” Ap-Debug.xml not used? alias for primary? pacemaker-master/doc/Pacemaker_Explained/en-US/Pacemaker_Explained.ent000066400000000000000000000001751217637305600262620ustar00rootroot00000000000000 pacemaker-master/doc/Pacemaker_Explained/en-US/Pacemaker_Explained.xml000066400000000000000000000062071217637305600262760ustar00rootroot00000000000000 Further Reading Project Website Project Documentation A comprehensive guide to cluster commands has been written by Novell Heartbeat configuration: Corosync Configuration: pacemaker-master/doc/Pacemaker_Explained/en-US/Preface.xml000066400000000000000000000011251217637305600237540ustar00rootroot00000000000000 Preface pacemaker-master/doc/Pacemaker_Explained/en-US/Revision_History.xml000066400000000000000000000037611217637305600257360ustar00rootroot00000000000000 Revision History 1-0 19 Oct 2009 AndrewBeekhofandrew@beekhof.net Import from Pages.app 2-0 26 Oct 2009 AndrewBeekhofandrew@beekhof.net Cleanup and reformatting of docbook xml complete 3-0 Tue Nov 12 2009 AndrewBeekhofandrew@beekhof.net Split book into chapters and pass validation Re-organize book for use with Publican 4-0 Mon Oct 8 2012 AndrewBeekhofandrew@beekhof.net Converted to asciidoc (which is converted to docbook for use with Publican) pacemaker-master/doc/Pacemaker_Explained/en-US/images/000077500000000000000000000000001217637305600231335ustar00rootroot00000000000000pacemaker-master/doc/Pacemaker_Explained/en-US/images/Policy-Engine-big.dot000066400000000000000000000145311217637305600270500ustar00rootroot00000000000000digraph "g" { "Cancel drbd0:0_monitor_10000 frigg" -> "drbd0:0_demote_0 frigg" [ style = bold] "Cancel drbd0:0_monitor_10000 frigg" [ style=bold color="green" fontcolor="black" ] "Cancel drbd0:1_monitor_12000 odin" -> "drbd0:1_promote_0 odin" [ style = bold] "Cancel drbd0:1_monitor_12000 odin" [ style=bold color="green" fontcolor="black" ] "IPaddr0_monitor_5000 odin" [ style=bold color="green" fontcolor="black" ] "IPaddr0_start_0 odin" -> "IPaddr0_monitor_5000 odin" [ style = bold] "IPaddr0_start_0 odin" -> "MailTo_start_0 odin" [ style = bold] "IPaddr0_start_0 odin" -> "group_running_0" [ style = bold] "IPaddr0_start_0 odin" [ style=bold color="green" fontcolor="black" ] "MailTo_start_0 odin" -> "group_running_0" [ style = bold] "MailTo_start_0 odin" [ style=bold color="green" fontcolor="black" ] "drbd0:0_demote_0 frigg" -> "drbd0:0_monitor_12000 frigg" [ style = bold] "drbd0:0_demote_0 frigg" -> "ms_drbd_demoted_0" [ style = bold] "drbd0:0_demote_0 frigg" [ style=bold color="green" fontcolor="black" ] "drbd0:0_monitor_12000 frigg" [ style=bold color="green" fontcolor="black" ] "drbd0:0_post_notify_demote_0 frigg" -> "ms_drbd_confirmed-post_notify_demoted_0" [ style = bold] "drbd0:0_post_notify_demote_0 frigg" [ style=bold color="green" fontcolor="black" ] "drbd0:0_post_notify_promote_0 frigg" -> "ms_drbd_confirmed-post_notify_promoted_0" [ style = bold] "drbd0:0_post_notify_promote_0 frigg" [ style=bold color="green" fontcolor="black" ] "drbd0:0_pre_notify_demote_0 frigg" -> "ms_drbd_confirmed-pre_notify_demote_0" [ style = bold] "drbd0:0_pre_notify_demote_0 frigg" [ style=bold color="green" fontcolor="black" ] "drbd0:0_pre_notify_promote_0 frigg" -> "ms_drbd_confirmed-pre_notify_promote_0" [ style = bold] "drbd0:0_pre_notify_promote_0 frigg" [ style=bold color="green" fontcolor="black" ] "drbd0:1_monitor_10000 odin" [ style=bold color="green" fontcolor="black" ] "drbd0:1_post_notify_demote_0 odin" -> "ms_drbd_confirmed-post_notify_demoted_0" [ style = bold] "drbd0:1_post_notify_demote_0 odin" [ style=bold color="green" fontcolor="black" ] "drbd0:1_post_notify_promote_0 odin" -> "ms_drbd_confirmed-post_notify_promoted_0" [ style = bold] "drbd0:1_post_notify_promote_0 odin" [ style=bold color="green" fontcolor="black" ] "drbd0:1_pre_notify_demote_0 odin" -> "ms_drbd_confirmed-pre_notify_demote_0" [ style = bold] "drbd0:1_pre_notify_demote_0 odin" [ style=bold color="green" fontcolor="black" ] "drbd0:1_pre_notify_promote_0 odin" -> "ms_drbd_confirmed-pre_notify_promote_0" [ style = bold] "drbd0:1_pre_notify_promote_0 odin" [ style=bold color="green" fontcolor="black" ] "drbd0:1_promote_0 odin" -> "drbd0:1_monitor_10000 odin" [ style = bold] "drbd0:1_promote_0 odin" -> "ms_drbd_promoted_0" [ style = bold] "drbd0:1_promote_0 odin" [ style=bold color="green" fontcolor="black" ] "group_running_0" [ style=bold color="green" fontcolor="orange" ] "group_start_0" -> "IPaddr0_start_0 odin" [ style = bold] "group_start_0" -> "MailTo_start_0 odin" [ style = bold] "group_start_0" -> "group_running_0" [ style = bold] "group_start_0" [ style=bold color="green" fontcolor="orange" ] "ms_drbd_confirmed-post_notify_demoted_0" -> "drbd0:0_monitor_12000 frigg" [ style = bold] "ms_drbd_confirmed-post_notify_demoted_0" -> "drbd0:1_monitor_10000 odin" [ style = bold] "ms_drbd_confirmed-post_notify_demoted_0" -> "ms_drbd_pre_notify_promote_0" [ style = bold] "ms_drbd_confirmed-post_notify_demoted_0" [ style=bold color="green" fontcolor="orange" ] "ms_drbd_confirmed-post_notify_promoted_0" -> "drbd0:0_monitor_12000 frigg" [ style = bold] "ms_drbd_confirmed-post_notify_promoted_0" -> "drbd0:1_monitor_10000 odin" [ style = bold] "ms_drbd_confirmed-post_notify_promoted_0" -> "group_start_0" [ style = bold] "ms_drbd_confirmed-post_notify_promoted_0" [ style=bold color="green" fontcolor="orange" ] "ms_drbd_confirmed-pre_notify_demote_0" -> "ms_drbd_demote_0" [ style = bold] "ms_drbd_confirmed-pre_notify_demote_0" -> "ms_drbd_post_notify_demoted_0" [ style = bold] "ms_drbd_confirmed-pre_notify_demote_0" [ style=bold color="green" fontcolor="orange" ] "ms_drbd_confirmed-pre_notify_promote_0" -> "ms_drbd_post_notify_promoted_0" [ style = bold] "ms_drbd_confirmed-pre_notify_promote_0" -> "ms_drbd_promote_0" [ style = bold] "ms_drbd_confirmed-pre_notify_promote_0" [ style=bold color="green" fontcolor="orange" ] "ms_drbd_demote_0" -> "drbd0:0_demote_0 frigg" [ style = bold] "ms_drbd_demote_0" -> "ms_drbd_demoted_0" [ style = bold] "ms_drbd_demote_0" [ style=bold color="green" fontcolor="orange" ] "ms_drbd_demoted_0" -> "ms_drbd_post_notify_demoted_0" [ style = bold] "ms_drbd_demoted_0" -> "ms_drbd_promote_0" [ style = bold] "ms_drbd_demoted_0" [ style=bold color="green" fontcolor="orange" ] "ms_drbd_post_notify_demoted_0" -> "drbd0:0_post_notify_demote_0 frigg" [ style = bold] "ms_drbd_post_notify_demoted_0" -> "drbd0:1_post_notify_demote_0 odin" [ style = bold] "ms_drbd_post_notify_demoted_0" -> "ms_drbd_confirmed-post_notify_demoted_0" [ style = bold] "ms_drbd_post_notify_demoted_0" [ style=bold color="green" fontcolor="orange" ] "ms_drbd_post_notify_promoted_0" -> "drbd0:0_post_notify_promote_0 frigg" [ style = bold] "ms_drbd_post_notify_promoted_0" -> "drbd0:1_post_notify_promote_0 odin" [ style = bold] "ms_drbd_post_notify_promoted_0" -> "ms_drbd_confirmed-post_notify_promoted_0" [ style = bold] "ms_drbd_post_notify_promoted_0" [ style=bold color="green" fontcolor="orange" ] "ms_drbd_pre_notify_demote_0" -> "drbd0:0_pre_notify_demote_0 frigg" [ style = bold] "ms_drbd_pre_notify_demote_0" -> "drbd0:1_pre_notify_demote_0 odin" [ style = bold] "ms_drbd_pre_notify_demote_0" -> "ms_drbd_confirmed-pre_notify_demote_0" [ style = bold] "ms_drbd_pre_notify_demote_0" [ style=bold color="green" fontcolor="orange" ] "ms_drbd_pre_notify_promote_0" -> "drbd0:0_pre_notify_promote_0 frigg" [ style = bold] "ms_drbd_pre_notify_promote_0" -> "drbd0:1_pre_notify_promote_0 odin" [ style = bold] "ms_drbd_pre_notify_promote_0" -> "ms_drbd_confirmed-pre_notify_promote_0" [ style = bold] "ms_drbd_pre_notify_promote_0" [ style=bold color="green" fontcolor="orange" ] "ms_drbd_promote_0" -> "drbd0:1_promote_0 odin" [ style = bold] "ms_drbd_promote_0" [ style=bold color="green" fontcolor="orange" ] "ms_drbd_promoted_0" -> "group_start_0" [ style = bold] "ms_drbd_promoted_0" -> "ms_drbd_post_notify_promoted_0" [ style = bold] "ms_drbd_promoted_0" [ style=bold color="green" fontcolor="orange" ] } pacemaker-master/doc/Pacemaker_Explained/en-US/images/Policy-Engine-big.svg000066400000000000000000001011371217637305600270600ustar00rootroot00000000000000 g Cancel drbd0:0_monitor_10000 frigg Cancel drbd0:0_monitor_10000 frigg drbd0:0_demote_0 frigg drbd0:0_demote_0 frigg Cancel drbd0:0_monitor_10000 frigg->drbd0:0_demote_0 frigg drbd0:0_monitor_12000 frigg drbd0:0_monitor_12000 frigg drbd0:0_demote_0 frigg->drbd0:0_monitor_12000 frigg ms_drbd_demoted_0 ms_drbd_demoted_0 drbd0:0_demote_0 frigg->ms_drbd_demoted_0 Cancel drbd0:1_monitor_12000 odin Cancel drbd0:1_monitor_12000 odin drbd0:1_promote_0 odin drbd0:1_promote_0 odin Cancel drbd0:1_monitor_12000 odin->drbd0:1_promote_0 odin drbd0:1_monitor_10000 odin drbd0:1_monitor_10000 odin drbd0:1_promote_0 odin->drbd0:1_monitor_10000 odin ms_drbd_promoted_0 ms_drbd_promoted_0 drbd0:1_promote_0 odin->ms_drbd_promoted_0 IPaddr0_monitor_5000 odin IPaddr0_monitor_5000 odin IPaddr0_start_0 odin IPaddr0_start_0 odin IPaddr0_start_0 odin->IPaddr0_monitor_5000 odin MailTo_start_0 odin MailTo_start_0 odin IPaddr0_start_0 odin->MailTo_start_0 odin group_running_0 group_running_0 IPaddr0_start_0 odin->group_running_0 MailTo_start_0 odin->group_running_0 ms_drbd_post_notify_demoted_0 ms_drbd_post_notify_demoted_0 ms_drbd_demoted_0->ms_drbd_post_notify_demoted_0 ms_drbd_promote_0 ms_drbd_promote_0 ms_drbd_demoted_0->ms_drbd_promote_0 drbd0:0_post_notify_demote_0 frigg drbd0:0_post_notify_demote_0 frigg ms_drbd_confirmed-post_notify_demoted_0 ms_drbd_confirmed-post_notify_demoted_0 drbd0:0_post_notify_demote_0 frigg->ms_drbd_confirmed-post_notify_demoted_0 ms_drbd_confirmed-post_notify_demoted_0->drbd0:0_monitor_12000 frigg ms_drbd_confirmed-post_notify_demoted_0->drbd0:1_monitor_10000 odin ms_drbd_pre_notify_promote_0 ms_drbd_pre_notify_promote_0 ms_drbd_confirmed-post_notify_demoted_0->ms_drbd_pre_notify_promote_0 drbd0:0_post_notify_promote_0 frigg drbd0:0_post_notify_promote_0 frigg ms_drbd_confirmed-post_notify_promoted_0 ms_drbd_confirmed-post_notify_promoted_0 drbd0:0_post_notify_promote_0 frigg->ms_drbd_confirmed-post_notify_promoted_0 ms_drbd_confirmed-post_notify_promoted_0->drbd0:0_monitor_12000 frigg ms_drbd_confirmed-post_notify_promoted_0->drbd0:1_monitor_10000 odin group_start_0 group_start_0 ms_drbd_confirmed-post_notify_promoted_0->group_start_0 drbd0:0_pre_notify_demote_0 frigg drbd0:0_pre_notify_demote_0 frigg ms_drbd_confirmed-pre_notify_demote_0 ms_drbd_confirmed-pre_notify_demote_0 drbd0:0_pre_notify_demote_0 frigg->ms_drbd_confirmed-pre_notify_demote_0 ms_drbd_demote_0 ms_drbd_demote_0 ms_drbd_confirmed-pre_notify_demote_0->ms_drbd_demote_0 ms_drbd_confirmed-pre_notify_demote_0->ms_drbd_post_notify_demoted_0 drbd0:0_pre_notify_promote_0 frigg drbd0:0_pre_notify_promote_0 frigg ms_drbd_confirmed-pre_notify_promote_0 ms_drbd_confirmed-pre_notify_promote_0 drbd0:0_pre_notify_promote_0 frigg->ms_drbd_confirmed-pre_notify_promote_0 ms_drbd_post_notify_promoted_0 ms_drbd_post_notify_promoted_0 ms_drbd_confirmed-pre_notify_promote_0->ms_drbd_post_notify_promoted_0 ms_drbd_confirmed-pre_notify_promote_0->ms_drbd_promote_0 drbd0:1_post_notify_demote_0 odin drbd0:1_post_notify_demote_0 odin drbd0:1_post_notify_demote_0 odin->ms_drbd_confirmed-post_notify_demoted_0 drbd0:1_post_notify_promote_0 odin drbd0:1_post_notify_promote_0 odin drbd0:1_post_notify_promote_0 odin->ms_drbd_confirmed-post_notify_promoted_0 drbd0:1_pre_notify_demote_0 odin drbd0:1_pre_notify_demote_0 odin drbd0:1_pre_notify_demote_0 odin->ms_drbd_confirmed-pre_notify_demote_0 drbd0:1_pre_notify_promote_0 odin drbd0:1_pre_notify_promote_0 odin drbd0:1_pre_notify_promote_0 odin->ms_drbd_confirmed-pre_notify_promote_0 ms_drbd_promoted_0->group_start_0 ms_drbd_promoted_0->ms_drbd_post_notify_promoted_0 group_start_0->IPaddr0_start_0 odin group_start_0->MailTo_start_0 odin group_start_0->group_running_0 ms_drbd_pre_notify_promote_0->drbd0:0_pre_notify_promote_0 frigg ms_drbd_pre_notify_promote_0->ms_drbd_confirmed-pre_notify_promote_0 ms_drbd_pre_notify_promote_0->drbd0:1_pre_notify_promote_0 odin ms_drbd_demote_0->drbd0:0_demote_0 frigg ms_drbd_demote_0->ms_drbd_demoted_0 ms_drbd_post_notify_demoted_0->drbd0:0_post_notify_demote_0 frigg ms_drbd_post_notify_demoted_0->ms_drbd_confirmed-post_notify_demoted_0 ms_drbd_post_notify_demoted_0->drbd0:1_post_notify_demote_0 odin ms_drbd_post_notify_promoted_0->drbd0:0_post_notify_promote_0 frigg ms_drbd_post_notify_promoted_0->ms_drbd_confirmed-post_notify_promoted_0 ms_drbd_post_notify_promoted_0->drbd0:1_post_notify_promote_0 odin ms_drbd_promote_0->drbd0:1_promote_0 odin ms_drbd_pre_notify_demote_0 ms_drbd_pre_notify_demote_0 ms_drbd_pre_notify_demote_0->drbd0:0_pre_notify_demote_0 frigg ms_drbd_pre_notify_demote_0->ms_drbd_confirmed-pre_notify_demote_0 ms_drbd_pre_notify_demote_0->drbd0:1_pre_notify_demote_0 odin pacemaker-master/doc/Pacemaker_Explained/en-US/images/Policy-Engine-small.dot000066400000000000000000000030701217637305600274130ustar00rootroot00000000000000 digraph "g" { "rsc1_monitor_0 pcmk-2" -> "probe_complete pcmk-2" [ style = bold] "rsc1_monitor_0 pcmk-2" [ style=bold color="green" fontcolor="black" ] "rsc1_stop_0 pcmk-1" [ style=dashed color="red" fontcolor="black" ] "rsc1_start_0 pcmk-2" [ style=dashed color="red" fontcolor="black" ] "rsc1_stop_0 pcmk-1" -> "rsc1_start_0 pcmk-2" [ style = dashed ] "rsc1_stop_0 pcmk-1" -> "all_stopped" [ style = dashed ] "probe_complete" -> "rsc1_start_0 pcmk-2" [ style = dashed ] "rsc2_monitor_0 pcmk-2" -> "probe_complete pcmk-2" [ style = bold] "rsc2_monitor_0 pcmk-2" [ style=bold color="green" fontcolor="black" ] "rsc2_stop_0 pcmk-1" [ style=dashed color="red" fontcolor="black" ] "rsc2_start_0 pcmk-2" [ style=dashed color="red" fontcolor="black" ] "rsc2_stop_0 pcmk-1" -> "rsc2_start_0 pcmk-2" [ style = dashed ] "rsc2_stop_0 pcmk-1" -> "all_stopped" [ style = dashed ] "probe_complete" -> "rsc2_start_0 pcmk-2" [ style = dashed ] "rsc3_monitor_0 pcmk-2" -> "probe_complete pcmk-2" [ style = bold] "rsc3_monitor_0 pcmk-2" [ style=bold color="green" fontcolor="black" ] "rsc3_stop_0 pcmk-1" [ style=dashed color="blue" fontcolor="orange" ] "rsc3_start_0 pcmk-2" [ style=dashed color="blue" fontcolor="black" ] "rsc3_stop_0 pcmk-1" -> "all_stopped" [ style = dashed ] "probe_complete" -> "rsc3_start_0 pcmk-2" [ style = dashed ] "probe_complete pcmk-2" -> "probe_complete" [ style = bold] "probe_complete pcmk-2" [ style=bold color="green" fontcolor="black" ] "probe_complete" [ style=bold color="green" fontcolor="orange" ] "all_stopped" [ style=dashed color="red" fontcolor="orange" ] } pacemaker-master/doc/Pacemaker_Explained/en-US/images/Policy-Engine-small.svg000066400000000000000000000220421217637305600274240ustar00rootroot00000000000000 g rsc1_monitor_0 pcmk-2 rsc1_monitor_0 pcmk-2 probe_complete pcmk-2 probe_complete pcmk-2 rsc1_monitor_0 pcmk-2->probe_complete pcmk-2 probe_complete probe_complete probe_complete pcmk-2->probe_complete rsc1_stop_0 pcmk-1 rsc1_stop_0 pcmk-1 rsc1_start_0 pcmk-2 rsc1_start_0 pcmk-2 rsc1_stop_0 pcmk-1->rsc1_start_0 pcmk-2 all_stopped all_stopped rsc1_stop_0 pcmk-1->all_stopped probe_complete->rsc1_start_0 pcmk-2 rsc2_start_0 pcmk-2 rsc2_start_0 pcmk-2 probe_complete->rsc2_start_0 pcmk-2 rsc3_start_0 pcmk-2 rsc3_start_0 pcmk-2 probe_complete->rsc3_start_0 pcmk-2 rsc2_monitor_0 pcmk-2 rsc2_monitor_0 pcmk-2 rsc2_monitor_0 pcmk-2->probe_complete pcmk-2 rsc2_stop_0 pcmk-1 rsc2_stop_0 pcmk-1 rsc2_stop_0 pcmk-1->all_stopped rsc2_stop_0 pcmk-1->rsc2_start_0 pcmk-2 rsc3_monitor_0 pcmk-2 rsc3_monitor_0 pcmk-2 rsc3_monitor_0 pcmk-2->probe_complete pcmk-2 rsc3_stop_0 pcmk-1 rsc3_stop_0 pcmk-1 rsc3_stop_0 pcmk-1->all_stopped pacemaker-master/doc/Pacemaker_Explained/en-US/images/pcmk-active-active.svg000066400000000000000000001636711217637305600273460ustar00rootroot00000000000000 image/svg+xml D'base Web Site Web Site Web Site Web Site GFS2 Host Host Host Host Shared Storage CoroSync Pacemaker Active / Active Hardware ClusterSoftware Services GFS2 GFS2 GFS2 URL Mail D'base URL Mail D'base URL Mail D'base URL Mail pacemaker-master/doc/Pacemaker_Explained/en-US/images/pcmk-active-passive.svg000066400000000000000000001210521217637305600275300ustar00rootroot00000000000000 image/svg+xml URL Web Site Files DRBD Host Host Host Host CoroSync Pacemaker Active / Passive Hardware ClusterSoftware Services URL D/base DRBD D/base Synch Synch pacemaker-master/doc/Pacemaker_Explained/en-US/images/pcmk-internals.svg000066400000000000000000001271041217637305600266100ustar00rootroot00000000000000 image/svg+xml Pacemaker Internals CRMd STONITHd CIB PEngine LRMd Cluster Abstraction Layer Corosync CCM or Heartbeat Linux-HA Project Pacemaker Project pacemaker-master/doc/Pacemaker_Explained/en-US/images/pcmk-overview.svg000066400000000000000000000703061217637305600264600ustar00rootroot00000000000000 image/svg+xml Pacemaker 10,000ft Cluster Resource Manager Local Resource Manager Resource Agents Messaging & Membership pacemaker-master/doc/Pacemaker_Explained/en-US/images/pcmk-shared-failover.svg000066400000000000000000001514071217637305600276670ustar00rootroot00000000000000 image/svg+xml URL Mail Files DRBD Host Host Host Host CoroSync Pacemaker Shared Failover Hardware ClusterSoftware Services DRBD D'base DRBD DRBD D'base URL URL Web Site Files Synch Synch Synch pacemaker-master/doc/Pacemaker_Explained/en-US/images/pcmk-stack.svg000066400000000000000000001021201217637305600257050ustar00rootroot00000000000000 image/svg+xml cLVM2 GFS2 OCFS2 Distributed Lock Manager CoroSync Pacemaker Pacemaker Stack Build Dependancy Resource Agents Cluster Glue pacemaker-master/doc/Pacemaker_Explained/en-US/images/resource-set.png000066400000000000000000000651461217637305600262750ustar00rootroot00000000000000PNG  IHDRre pHYs   IDATximWu&3oo4Kh !#FS%0m*] W=7pT=veMa`0ۀfM{zcN7߹;;7fv{^Y{9c0)LP ( A@P ( ƇР@P ( A@P (0 " A@P (  ـEsA@P ( A@(rA@P ( A@P`(ܐ X47( A@P ( "< A@P ( CޡnnӗVMa$@P@ª &55d@ޚV#TޚV+#۝Mk [NMk [0Xn\%YK73 Q+,'AFot4kV=p JnVҪ S_rn(VI[XI&lJ. )i"g ܊͂Jd~6*l5w.2HRZn&AJw00׋ ;J Vlt7Ѣ [ |ʏPZn& JwM00׋[qrmuMQ2x-i]Yp߭2fXSZeuQ@8bnK_Sx7tÚp-ƒF/mKOh ka).ºS #Ɩ̈́t/w/6ݥs6ݽ\,G2W P`P)PbNm藻[KK eyr+^BఌTs)Xn_(rt @>IlUX7w=ʹbhm8>>^)u[6eq *:2ѮBvS 8#g֠@drӮ_RJV/CMa8,ɖF.L/Vٴi&(0.6_*m2m4%.hݥy/TOP`@( <9rױC52ьM~GbWDȭBL@$d/--0YTG٤rWN4tZp*O6$ /iJďTL deX)Pb}(Gw`pXG6=l,ۈmm{Cko/ $Q&Kw=rzX:%ʙvzO-kv411a].R'aU0A@A#,{V@)<*Hyq X ,tȁB(XrıT'vS3OONڄS_ )tT,Zq4F]vn! e$ -Z8醝K5W,=SQEeN R$d{SgOP`( ܱxe 6Ԅr!He]`BeN2^ "G  ,*l&maa9ǦE|UY0aHmkeZPVamZn^j"77*{ne!u&z3 ]WK*o 9)uHY՜;LPv`1ފ2z@=hKyRFHEp(7bnڝw" (TV.7ڏj<>>}oxA MZf?QJE~8Wy8aHSbjxaD1(H:ۮORGH#xБJ]w֊@o,{HU Q X\`^:\RJ%F }LIK=F dv_rLcz-E>"i ]O}6Wł4cP6>>Z;3L鸥:/WmOP` OӔv`ra%F,])Pb 2LDl17sm;E ݺJNQq+}r,ɣ^`ESP)lB gJٰhnDE.ˇxSii#mRNW^=0 i-m*r, Jq })}gW-2ǝ9]sDB&(^ z&`)ō϶R|vM{b1kF:8keC1q)iD]39㫰MIw['ec7[MWyt._,9Vy\?A(X ,&d ) n!{E@`1v i\:M@Y8Q{w'ώO)Un*nPԨ?~h*78S;YyMQz~o鐔YYٖ}gO&5r˶-[aQ X~q( ^NZ֢@`1-^"6<0葝inѕ7*nG[rsoØߕ20/+]=oǦKd3_8M͎*^Js>tzvn5; ~m&h 2#(PP b Ŧ@`00xy.k@`1 yE ( 3q:F)Jܱ3 ޑ7Re~#%4F=Ⱦg ffqa+*o4=gR}o%~xX_no[''KOL.x_K0AER#XD/.w`r]D"Xl"gBUgͥO-k;cgƫg\ȱ,ϮYBx:\$ʕE^-ӆOOK;Z8]n['(@ ,H}#?9/ IIe`_嬃E+iL:Ҋ@žK;q@֕YNܮt< Moڪ xިvS" +h٥t'v$o1˽عCb/‹08"AL`00(^S ?<\IFVPJU*qz&N;qw[J]ԜQӇUע%\uhNY`4 I,Ni!?Sp(o6l6ηgv̥eIіɶ,bEpl!-( zҌ"Pq'ٙ.pwXF߇LHi:Z _J2ᖳH.zR*Ǧ)]\K_|f*ݶ{.4 ҭe0ۓE;SἼEA50(J}i(XD?THW?Nس y0}# ¯J^}9xL1xKþ7ZemV/KP^|9n#OK%(^/JX$/Ey`wUy8Fg#eF8)/69%7>g稄)/'\if)`3,6؄Maf{AoM>UܦвK;#icT O'S@9S`1[B!^p/pG4Hqs,>X*9EҤ6'*1&#pGRPC 5ì/NC(v9H3Ҏ4=i̊)1;@9rqX^X^8 wC``p+y.nXfnYH)r>B?)T@>w8=5SazNLGm2e[R\,4S-wI=a'IZ?nt!m{ vH;Ұ֢̑ѴCpmS 9)`ہU `5"G/)rܑubw`nn\;緰kg~!>Ut[*)7\6a\#4$-EWzq?@/,nAdFq`ߜ ,GJ# i7Jv~tz!N]tT).SYYCzRXt['-h}v+?Oxj~9}]E]9fP@M;Kj"J<6`^T^J\I^y`pLٌVCa$(tJEcҽ'',n| ix*\Vܝ_VaLPNJw6\F+ؙ۽'&'OFc*v,?#KH|B;hG^|{I`qd% "q%[ª#_h`1x1|$9MKEs OG)y :+'`& h`qYTi:pwKFڑL?}xG"m0kgcm58k ckQ 0(\T`No-ŭ0/}&h(傻ET:1犅}FY)&<ѹE6d0㩴nq9ji78\ /5ҝH[ȕrev&V`1'^X&@D7MOd#>ӪE"GhWH;rj>1e D@v!b9m(.^,)F',ւG.?e7%tU^zӉ4'3.'hHQx=Ҙ/s/ ,dޙd`v$ ,/c"GBiH%C&T.>$&t~4'V)]*nr%.X9d:_AB e~Z?}[\ZNxxrJmR@c]`1k8}G?Y`pq`:eˇZ#Hhڜ@jJܑ3ӸO/7A:`1,ݠ]/v۴3RmcSFrWTʱ*(@9t ,nŽ$8"c7Iȼ#VT`1x1Yz$9>q2ǸGōtPQ0ݢ2'N0~~ϿztRE)sraF\W`qQCty~q`p<;%Z#]T 'MOγЈ94[&/4HRjP>Ԕ\rOys~2(Ycc=cⰣek?*kBxܶͅ~+ Tb~`bA8VR %nЧhEa :7,$APF&Si,_i")~[qD1Чz m @+hi.cq2aF6Ƹw¥f’{I`qd`׎ ׃7E?ĐQeX uGaff K!Cȕ/'8Ay`ila^+scc 8W1 -3t=M8i5yT=nᗍs$[-zg6lAJ=ʣKIƧf8FrARb^/|p+m#CѱAà(,Oe3t0a(}R~{o:+?a엛NcZ\Ygmш橭l?r?yE$9Œ45R.%X"ߊ(汰ձ<GЁJ73p1O5(@~T,+mϵC$2[aYoeҭkyΟ~YͅC~˸l֯͟;2e7rL7G#~r|q27HX1kskq k²GFS?HAں/ ĺ߀!˃Vy0C+Kb!#B2r3_t[tʃ-9"aIv4/p|{aVVBG,Ub<*ZRd`9zv9>FB.`)SdʍҽB=X\MV-ecab!1[Q@|ryJwHv"Mj1mן瓶6oscs,Rn-lf>9q3BL,;~kXyU+Gi5MIUDmwiM{럃(1hGr*[Lu[7^p26Mo&/hط0cIO:krp'z|}|H:= Қo.Sv`p9g C_93J ,: "kXx>I#S!q͜Atq bbqF }ɑz=\YD+צ}eK ~͋=mqt>u8=zOmWC?i~~ aĄE `3;ҷ|o9^G~t 2LL>\nŰ8gE(BEFP.4g5CV| ;/~iD[h}7_| lKsgRZ.C3=oJw8[^^~KwSr7AOΠxl b n_烎ÙVjL2,\ϬN]#?ǟ;~c3ǎ:,b 橔< X'u:ENmOSgH NW<]f<bx7|\^Jae5Roe~L_կUaFOKEO.p5Kxj6Sf0q|2{bzWǮ8nm,6En sx0v٭Stۅlzan+S?}3t|r,~fVW G#O>JY(b 簐Gw6Py M: l]~!=;ӷ=o)rKNa<`>Qs%s/?fG0[AŢcB,zxABr||r:MpY@>汉ӿ)+ϭ[k򐋢}1;yZҦۮb10ݝCw+8>vaWad&3.XOprx5aLΌȯZ13x<p|1vޝ[5MwwdzpĎ䂶꾁?Hmm!̍caw4f)}Xa< $ ? ~jgZ\كY;׹xWp?> AP&+Kx1˳%#,WjCEŊ1Uѿ|i[aێvv-BĎxGʟyk)e>ˊR0gӃO؝ʛ'(cj27vyE'`/(;M7 4<"KBNH 9`^3X7O\{(N\rt X9+u_3<r@^|kgi_-sܑi$3=g9lrlX4.l|[olM̤ v޸SԖB3vS9瑮xVNujl^X,FEϗҟߗE_zW?5P| -.`.N^e,:䡓k_*Co8ؚ$-,ڭn ]d2sG7x3]WaK$߭[.I/vxފ,Ã&e7C{0iX8rbΞPuڿVq$ЙrIENP $z Jc(X'yLK4d}ǻ)^zB Am{ H3HuQT?l,3P`ӑ#G{lEgw6tKxXR~J?+P:7}GL?䤑/au^{I`16  E09,`_N;WZ0ڙV;yxeNh *Gp`pabK}u~5aqĦa2s.Z3~.q j`QT޼=tȕ]֪:m) syGhd6H0NՍ6W`ُܖAy0m 7ݶ7i~ǿ^@cұ^nrozN_(5x,~@֪/Ve6~Qo$ "Ǿ?4]3Gyqc>(Xtpo"ƣ"r /s"5^đKH_(@xMw%&c0)*c)',S gΜhJ8GAh, c汳x% _qd J\l1yX%\ AN_x ›sFc> ^Tm3X4@~b@sSf XM='/,5vǏ x`߸n̢YQ4iCȉbD 2bfD(c, (,,X vY#/|&"vO:8L?='LJKyNy  ~[zL02Ͷ[~/۪I_7BAcϱlX"~=p2_<~w*XX}DQ?37r/ H< Vbpo(f{Jg.'k3Ȼi _[M!Hݸqs 1P"yHXEE"Vss6Te/DKX&f!2?͆csCaQvnPZCi8!5ZN 1 yw|2 )of!S,nbO&%3U{Af04^rb/I~~BN.ӇVӛ_qC7'x0Glc XV@nl)I&WkXXh\LT60E8-ѹqs|7@`ѰIpF_}0a a<>rٞi\SLzs㭲'kHP8ji+,2 ^/,o|((h3?A dw0x>S7 óAy(cʅ<租F%b .\G|uۂI~ y`ĬAb5upv4uyhE g b9+D-c 43SrBȋ+E?eϹUCe "DqdY-󆱝@3S1NYRc Utɏ|=7bT"Y>{_S'N$_a@TkJ*r3S~n(~x"MBqڏ\cY_slЖ)I <3G`Ϟ=H,f,W {:}:u͢a>=q q]~Sٗg'{>y8eX0t"^ +$Yǽ⯹>/+h h}= NUfgN嘽\lg|m0)h9E1dP :ⷿx,f,dv฀[0d?eN;N;9}//ܖs9Ä0 XԹk_gV>~ͲBY&uh8,?ҠQr@5e|M׊,a06eige!S.Vn-xu,ZJfS]fNwMGXz m0mU1Bl{O`T4U?Bbblc?CE>&ݹk5\cn|(lBEt[!lxdg/ϟ#s8: ǰ'OxONfҿoxO  ܁EQÎGvy{IB6l._}Î?~c1"0*SUxQtqiCrv,5b+x‚Hg>.tʜ:`qy(29M ILgI0y,c`2&@rPY{9 7s]tbn}{śil v{r6^SK\iENthYpRoځcoq$,utIJ |$11 /d@Ǘұ o,EWO݋]G+1fF^Dh[g?HJm3,g vO/}/އ{$]npl/NC%6-aN]==>Qe{ x.ZV8Ba#"04)0X\M${d[]wY%|6 |21RUXȵC5JrHwyoCݜM7<),>c~'ײ}7wjP]s=k#QPX|_ѦGqcRQ}6r)c?UMc%=W[TS;krǁ4y"lrwJ_yl.e 0^9X`GYpcE'ѬKkX,a#u<Ǿ)z-i4?U{*sXrټ<Xoie}cmtgE niBÈEѮĂ|sk4ܒ J8}Sh8|6KNL2&kͦd"jvn>jp$v퀲fhI|&b*?,}Ok~L+gҭWKNo~5-V"NI wZӻx% ?Yzkނ~w?4^zLa[;}X_qU烵ts,h46扟{`/;;㼪s:T<"<6kߠƋɿ5,q7p- =nzOz{m<g\%i K^ KY_/cFm3-_ؓݓN\܅WM5xD٤_1H {rtЌKg:fq>̺yoOAR#L)0XH`"6<~HEe^ gf<= |)_6wCfrFMp|uq2ɣ2=L b ٌ++W۽7Al/;ДKp7>]5^~\{qvؖax] ΞLvL֛s\}s=~NH^zϊTʭӯzVXv\IPz =F2y ƎU_VOL¼Z٦1Aٝ:2Km2xޞkCs: bToeVU/w ,^ ɷtߓ8͏~KNYbRU|ċ$X,?jiIV`-W[3xx&R XL `X$ iV#&оlgiWiBgynN_I0ŭ#JVp8-3K|{@c]Xo٫aa0}`8/~hzx;03pHe FXLWizoC̲+DZ`3>hQ@c[axبLjs*w >N $9:ܓv.0eDc_Y>`o~ZzNϻ-OE@;KFq2?DŽFc$"g()1-;3hXtv2 +@ޙ3Fsq3˪"/.9,ǓbEplÀAa 6 IDAT =q~#ߴ޿Eצ?+M]mqIjOJɻN#lGN~*¢Z :=w,:5,]<V AoeNmاD(<`/bp,^8 "Wv̘J.w5f1ÙBuAF1$ː_6Y!4:yV'/:r_'ӓGI~eqi ^!M:>đxmҏgr/^ qU@k{IW;#?8mvc#5>~FŸƘ cN|bCFBKv;w\VGt8=rflw~d ,:Mwk)0$ $[l|=~Μ_HϽf~sz̘>CEe:K3qӿΫ$c1c'G)A9JiկEay>إ*M\'+xpE%躝_ˇ]6E-)pl,"rE=XUcaqh_v‰ :lnڏ׃Ĉ7p":^Rvv8͌|]S0d~T6_prUFV\EY8 ^r/&f~ګ%4׽>?xˎko#g=Յ6ߴqŘ5vt~ hn݉S-V.N/Nx&-;oW¬ȔBS8}wk( >wY0XsñIJdڽg2]oeߕ&ӷ>ow:ϧo/Q=y#.7)ZSheEbE:Vc $F(râ8)V2M Zٝ4Ji|j!d3[_2G?'\e7&xj-QjR)Vk>c57|!<'p^ae-DlvH+΋2] <+'+(~F=(X$뛁m/GGgg/#'Z}_>~ON#|MA8$ $KEрb)K ,s#)yݾ{#iVx=~r>/|< 7zƫ=O'?{Lտ|0}ci;q܍&|9Ubd%( ?q)FHy2Dz\:lK3rѶY %'4w4i_pU ;JP}e7>/Υ9?up7ߘ3HaEZ31_w1G߸MYǶC|ƅ%SQ@ɖk5惈 V\VOͧ:9C2=}ҏr-p'Ϻw'pه GԽp/ ,9`1؁YUb%c[nԮt;ӍWHؓǾK>u&=v |a5){ޜ[x }(c`P6XlR|g7Z򑞇KoIhR03f27wh"t3-B4,<.#nfH$0 86]a1 DǑf+5nm6)Y/ҫMxhdT ?:|A>K.u)H{h|`[d Z-Aش|e VSb%oef^c$1)$0[^b YVcXt*m? &<,4'\W8^ڏ}ءLY~=G(qsJe E7i"ᓏU:8( e~k&8%@Pa.]3( }Y@t?Llƍo1E;Y(4 30>$ 㬱 aQ6b W0y  ӱ?E;W y<Ǻ+71?>fl[ɹt&,V ( ɾz Onl$ƀ9!e_ŗS!O %T DiL`PbR@}X+yFܹq7y~@dc.븱ʿape=b!37m "G&1f8rxt͞vzo0SgKVtC8 i, <3^-?cI,k6cG?c\VG*?5_B^@XL^Ke,k! 8֊_g)]׏G+5N٤0A)vHH9_q`h&-NU{)-yc1$8ɣX$v!М"U6öVb+kZ(ءvv *<`8q &U՚<\fki*i ʚ+l\L(_9$pm!ŐF֧qK@\X3vAŢ?P/f~WcyCȩ7dN^<ҦG?ɕǷ񀴥M|a>3^7t oqτ;g^3H& WJed(^`꧚LAHDrWN1ĭ~dw,j,8ѽP@cj@S#; 8ܝ[^gR+ /2QO~2#=Ae <-뷬?k :CAf!߶ @qXjcX ,vUV܈mrʚگ|S8ކ綐nnмL>qY&vv1D~ h){LG꣢U(^!EAN 6m EDCV?*m+IC{8eSv휯 B74f~3~GÆEbX$X08\J2뻗G2}Рc<܄& 6ahtߥ~츭 t,K6# r5yZb95jE$Qn)N랷EtLhn nI_CLg [U\6[i簪L W~Ҫ_Sxe/2E?u7/V;/pDeؗ0K<ƷPiWR`,,k&%Vtʯ򅱍K0P`1 H^36פbOt:R`Xa,5 3􊜨)Д+kn7cJ9+$Bk.21f 7ϓY~<'v7jua{?f-im74 }(0XJǀc#KW<]/F ,J 2Wg%TC0XaLk9^oM{;Bj^IA"[*e0[ܴ ŕc|CIIXhʜv^Rڋo|{. _G.3@*9\rgNPSMP y~ICFD)I? \ߍӸt] h|5洇G3٨`"gi`ߜ: ג.4%aWH:`tKJ]x'`sp3bq|\ţn W {~Ҩ0itVq9t4#H*4AĢ F2H81ܼ9 aV0`pi`p5ÀȳC̓I%w=2\9qlL/>;g|exމ3% 'iv~ARKSUM on)0aߡ@g*zOiI厜_*sSѧU1'Xb %%0U^o^PrLbIm <$Ì:g~΍K~ yءH(rId}ͧSA~Csd AP 'NSJLkGCB)]qB_l4*q@`qsM?{ S X8t92RwppDzǷ̹'eeJIN0[eaJۉseP~Ð(/?m}9{ACRqs}NcBrИv`1^ NbX8L/K n"( v`11nj52\=`#]Rn:W߰`q|΋90N|;'Q JoByZwey}촟}SF^i5T.^3V)q+9[ga7 L{EXCR$e7`0#ŭ@H)rɣv{^6z)_ v?|Vc, pJY4 U6Jg87F+)}'h':&}9A mCr읏Qf bX6)/[Κۮb`q+~9Ji@jWnvf*n=3;xkL &\ ?#FVL]o[֤y6kߍ#] yW%Ҏq5Ƒa| ~Qy  Kh{ 7D lDn H鹗ͧH K|nY:!x/rdO"Ǖ>+'ǛrEyuL^3|aTZ,ug<((Pbs)&˼[pQ|W ]c#ȑupIdIOGHw>8aiA)kS3PY6ŹR 9IaNؽ'@*r#(rOXL<T=0X$Y]`0 Řn"GB2L(9y;r IDATvPJd:u9,MF!RLu | gMBư:gi-UGsǍJx]ݳ)s}NG?qɲV6X+z8+J{C`0aGacn~vI 0 1^Rhיs _dzsL%sr|vږ,|vUNiejd\̬1Oʛʹqm&&+nOw`))q_Tl[عaMᠴY+2H{B`RBD/,t#-9`$#@WӋHw?> X BSPG J+8r޲XOw,=*"+T9JOG+?3x횅/+lſI.vB#lŭ(7 qJj mȑPqRb|`2}-|H3eWFwV6m5Lt#ۦ)u$Mgns%6Oӫ`Iy*Vi38)oWSњ?AMQ XEMS 04E}@`1F֊ 4.]:)tO]L_};t'LAѢY t36R$N{-ͭ:Wk^^rbڽÏLJqR"J`>iyˤ00A@`14/ˢ( w(X ,me*u éɦF_*xGOנd:?jP.*kR48eŭ pWܥ3]n,m.J5RXV9iF8扟Ru[zQt@`0aa0(X ,ʼn`cnD2LJ]cVz 9+mITKX(Kc`]w`)]wh)]rڿk^VBL[-7RhK7a[Mbg_17퍀}`17"@@S*sLG8;}~9?5dJ3өi~!y]8iӨuG]w+Lҗe*NaN8Z:}֌sfKt7).Mrvf[XYGN:؟zMaeں~a~Kt70Aa@[O=,08 q60k1is:H)\aLS$qM2LSo*;‚DaJ&lws+O]b]1ʌ(Q@/dXjra/2#,(0dfx74%e/Nu,kU8GP`-ﵰW_o>(0cl-z[ZBW_o^=~G )܅4ٲn^oH7t P (膹nuu\z;a[x^ݰ-?AS溅 sÿ9 "9E@P ( A@P (p)0~k A@P ( A@P`SEnSA@P ( A@PS O1( A@P ( lm|9( A@P ( \| L\*Ơ@P ( ۓMol [:Mol [ AP`h<4VA)l2".( "if_na%]_r R8IENDB`pacemaker-master/doc/Pacemaker_Explained/en-US/images/three-sets-complex.png000066400000000000000000002401751217637305600274020ustar00rootroot00000000000000PNG  IHDRpp pHYs   IDATxym]sz<d!!1KR #21ؤ HC*E*N\? 0`* W("'BhzzB;sN~}V{}Ogg{~{,3-7WN}H. e@8H@ʀxV'A@ʀp%" " " " " " O" " " " " " "Ѓ=(JD@D@D@D@D@D@#)YUD@D@D@D@D@D@D)zQGRdz>@=%" " " Zz)DYPKNaO%R%O?1ڦa" " " 96Iெܝ## e;'jE 7r36*ݝ*̅{61S x~LW" " "i_uӟp~TXwkN6:oTVx,)vj-$W}7рN $Sr?/Wx5" " " K@ʀE@D@D`: yX.7͝@ Z?⻹7/eqrsUE: zPm~cX 60@O?;#=KeÆÀD@D@D' 幝 )v?eב79waw:zpg^G;`ˈ)vjyUhPana؃]_u[Ґ_RsȖ5[n r#5m2u?>:ڴ3c~L4؊hّ$?ݰs7 )HBl/ujxHsN." " "Pos/B^/xrs!+ҧPDdҴ^G.) p3-nGHW(\Jr !W0V +vh|R ,jGe2)NE@D@D?a`G"3n o\) ()l/zw+v\%#݂)a2 ,"uT @rW??2fC=g[ ^ H! #" " !riA2" " " "[+R ʀkO|"> !ageA8!7Vu{::3!3?7iЬ^h~{!-g@* @ˈH%l$" "  *,?u>zs"m* ]T?Kޝ{m=Rh 0C8Damҽ(CDz ,{ U}J)mcAAm-" " " tR 3Ob&;OV_= \_!#<x+J$G2Ù~<<ҡ w 'ug$dj4C= ΍מ҂~BQ܍ A~K!@"E@D@DYھ_Rdp;-<#rivm~˓vsHe5}yQnx^`d# 6ϸ<-#`al`A `&@,~_؅?s aۥ;Eydr 8?ڟ{#?- qO8?rl G" " "7 a Ҁ|/"`K0­ !O^_^ 75}/1!vd|`"eA@ʀ> )"a)2, _+.3ϼb|H^:b>=">ugBȀ)%??i{x==} ̸Ăh3KE\" " " URT/" " [ @vvaxl Xb/@o=,6+f L!ܣm=p0Ĕi<|CqIqɻ"\|2} `vU9E" " "  HЛbE@D@D' HD7T#cWx| ȗ^& @z%@P \I!PdN(sgCׇBZ fzKyq^iZf`_KPG? DX(I}C$Wξg#KD@D@D):@QCoa4g@P̀}׼|M5f@ 7) qEaT 'wGnݔ,R?UKB/W_iه2Qr%krRS_n)" " " 0-` QO\/?4!亀Ke@(ǛB ),5.ocJ cpa5 PtbzR!E&U*reUO7dG%pò“o{@<XiS\)D`>,h:R )l''$Ɯ ߿x}J͞h2B.L8 R@oG2$6^|CЍVZORXp@x!)O`;bl93  @H!ŋ@@U?Nsf}(dP4񒂀~JjH* tdDI @8ĦcT?"eD@D@D@& eL"" " Yՙ~mIxizOv.UG$GH!"Vβ|Iz 8/pcѲ>n@~.x~RnT HP%" !&l*8+֓}˲z:/ݢ, IvHmRd~ߍ?{g:sAưah'X)4D@D@D`r\s `Zd@? R)v0v"a0Ο@3/+hP!ݎI)@l)4D@D@D` ~԰O̍!kHHzD.5`"y9_( [e}.َi A3d۹`<4BFD@D@D # 9E@D@D 4)xRzݖk$0yB|x CK~E/g?ƛw/lQcY`~=`69v$ۜs Rh PH?}gҀ$Bl.-?p!hG 1eh?M䇂!ϏA3CEQŴm#44E3Q!mLӷ,Q8'{kt"nC@ʀsQg%@v в mjv4TOs{pd&yrw%?G{iΩxd~fŽOx\"_2? =wmAоn-֓,2 o?YL eD@D@D@6 p଀WCP$7ֺB@mon!xg5"}T-'/~!;1=[e~oeFc2Y ϲh)L @+f\$mANz7ΘXayD@D@D2tuYD@D`(dI^xB*Eۃ)m!:)>PQd??V77E!Շ = \`Oy R|[G?h[^W؇}+m~aZkV]<6a)Of;yhw]|i_}ٖ[u\GZ!jxo~K.yR*~]1}㹁 [~D@D@D H " "  &>?Znm_nF[!((M9B.2 [E1a\Q[qAg;<1l˫Mz箛-e۾f+6߷?gv;x}˥#_/{:ȸ RIvh`? q{n8cc <\q!#" " "&;c\" " "Б0'~;q<<V6oL"2B1dʹ3_55Vb\?G?g_tsQ=?h{t|&9J x|_S*dGa܃C-p3O|7?uyŽN j~+sք`+Y Ma_ d Ocnw1??Zqhr򛎆28ʀ%_{{J_m?U_ԕiAh82" " " m3B.Mw|<ӐOCD BZ!B0)B& Se|F:Z"r?T_-Zˏ0:aPB>2{D{oFYwoyyo6Wl?-X^+"}}2WD  y/[D@D@DM@ʀ6 D@D@D+ _i$!ܻʩ8Mpxȱ" =]2ݞ=60Wn==B|,pe/ uo1{.av)O N—|6>ۇc${G!ۿgRIvU7fcȈIQ " " [ @aY 7.Pک< ^Dj?*^<)nB jZ2B!,G? wCZ=>PdyʏO) vz@zJ*dXG@ʀu8j IDATf6bfrB(8t7 r|!0#"sG"-4(y],녣Ipg~\Xo!Y >ԞBW 6,t%{u+gaOf0O(f ",GD@D@D H " " [ @E@0k M[*_HXW+܍0Gi7ȟr67_Y^m ˪[Z= o5"(ۈPmO>+nIŰ oQ8 C;52Gx~nx@{.q  xB'V!E;ӧZˡ$@x9 ěˏuQ*G廾,͙#V7W|>pk1TeFS"O W* }a`i-Q*F{AQh*@F~'\Hu##" " " @g$0Z/ åPPnr8)LtQ(+@ } J7gX~by@},lgQLe\X~_U,@G@fY%" "  PMC7SS-x"SCH΅=Q9 |"!w4Ϋ(~C5c@<:n}geٿWfxPu/lC0$+&KD@D@4)WE@D@6K L.HP:C8m 'NZ/qNYX.)? w|Ξ,>M'l|_Xc0d'~EϿڂW|F<jVȨm=ȢUlOo+"JeX5z'snJFD@D@DM O;P. p6L#MOطʚ|ݝo͞7D?>4`Q WL$E@#TʉDm?azGlyxo8f K8 8Ч_,A x?Wff?]o]:{ľǢgya_}wlg`V@kgM M “Vnַ~PD"qcVLX7"̈́B*#" " "P2D!t'^(r?Bj MGm߬qم.#Al?Ɏ5삚0<>m㇭6K#B߂(={4-\0|φfN )GD@D@JR( L[| ȅN8b}< 8i~Ȳ!F~Hp{;mқr$D)?PO EG|ȅQ*Y (x!?<FWf -/c?@=S#ZxN H~ԇ鍿,R8؈C9t6H G}Ph`/#C>3#}ސ " ډɈb  PЄ %D-WBHNtZQ8ڰC "l_Q~t=0Gξh7[XAEG~~D@D@D@2`yD@D@D74: 6 n BtLهGL/* . "=ȟ_&O2Y7pGtўgm?8y/VSCT &?g -" " @NyI" " " )tRaB隽+7xSe.<˷~aar a'?h{V?’5#8borOmHmj3Pkw:_:Fm߿_*&ҁ)#" " "p#" " 0 eE{k6\@B6$*BP {2ON/7뇝ԃx]ԟvA5F}{=zTDH7;WD@D@D 8-P`Çv{v%ך+(B.nnXH腍$2 f/HY!i};SP˾^:3mgϞ %/,,(G" " "Б&E@D@D;IX{ݻw|{?χ# u P@MBNS 9:*HP &A <^I08 h EfZQ{)?:E:ÿM` / oܸQP%" " "Љ(LD@D@$p֭B,S,JeaoX8La˧|PSoo0iʂ=O?l~VJ $PTPFD@D@D3):sQlH|lPM8B[ϙkv5b;xiZ&ނx[&R?AlNO TnΟn?~'FEV5z|ɕ qÒ۷oR <XG@ʀu83Ћ/?~<}(ۚ]8_7I{@¡(f @SG2Y:)Ÿs~9o?gf؅f6g^@@e2l*suò XC>ؐ@&匀o!R!Z-( և(!1P -9>PC&R~$<+-u.x8.8>ղ}粁`I"p@1s2|a`uuQE@D@D@" " " *IAGcǎB(ӳg&!PpJ;Y8:3bw,ۡ<wSBC`G ߕAy!.'@{@Emw $zCQʈ^D@D@D@6&Cp !jB@ @ᆍT`7ُ{f|:<HGZ6 Իߢj$`'q~BSS.WDS9 .YOjEj'wGRƇB!'( sjfP70ݒ*\D@D@ )̩VGE@D@J߬{ndgƺEj2B#eَO@B0.C.ʄ&=iC/@ӒeF;l7}Cw͎  02 E樷̍7ɓ'ݒ*\D@D@ujtcÁ:)" " ^G6 voGшa3B?Ԩ]Wt k-w~50' ,#wz#s D~qц~gC7D>/m{ŎL?Ř6ڱ2(vPtR(6ʣx؏@3HOl^{-vgfbxK BJ[Z^°}kÑ M(tCI8&v;=5o񷒟9Rk h/Ïwa;k6>fP T2ҤFA=Ǡ_`l%4" " " ~\;Ў0_xBL¦ ҁJ_ڲ'cxɅ}37|lÍ:NYODy @o2ZYHOE UQ0 AP쬍t%" " @>֪U" " "M l!>|Ν;-5VpBJ~W붊w;%[>nvy BRDGLz*j6RoR󍫱/96P+(Wh~_n>]t)mFE!`;(/_lXC>1$pk IDAT1a/b%N6hKR *`//L+urϏy,2>U@3>XS84 Si.4/dOKr%IP,3wJ Pt@ @dD@D@D`3@oˈ"/@Hɷ¼68 ~*ϕ6틮(ID>yqrT^;=cic6{ܱx5;y8Mɦys%@YO,ww ;MU!" " A@ My7twR 䊁N-!rnW(de(xH);CvԅvD^ë6-aO< EX !#" " ," " }ثߓ` C;wW{s陟6aPpn ?8a夐}<ƂSSSvŲ/{jt& e@g. ؇޽kn aoy=h(F)Mwn(#ݝt C^3૯v(#" " {{팩" " }!;Q8@&P P6`SA(dD@D@D`2`)SD@D`CFî\kgff'7;FQ>;e2" " "HΒ(" "!ܰ>7>aaJ  p1;ra B1(#" "  }" " }yf|9^kʨD"0gΜIg X!" " F@ʀmCE@D@v{1;E^f}+0S@FD@D@v+)vQD@D@"ìg}QS Y)/ZlG]*SD@D@JPE@D@' 8~>|E`ffpJx#" " 섨9" " fOOOɓ'˨T"wffȈn# en;#jڵkr )N0[_>2" " "HΆ"" "\]v8%Q233cf3>9,2" " "[i CD@D/j֗¦Dρ0p9՘!/ <*E@D@:2#F mÚl͖LV67nm" " d" " _8vaMf <|ܹ6sR~ /ƗN:> d]}ޫ" " M" " %~z|9plaFСC" _XZZk]P{E@D@)TWD@D`?u=~r #{>7xaʕ+^-" " HϟZ/" ޽{fȈ^'/l`mm-0OʈN2`>;9sƦʧD" ` ?XO# e;y&;:/=ztI>5xEç 6$ eNV]" " iƗ0@_Qccc1CͿ{aY)vؐJcbS=L /,qay)vJ:)r@_ؔh2,zj|FswI 'IM@Ç1U}jrA8# `9t,2 evPU" " "SI_:%'bJ,U7D@D`2`5KD@ |9oB!`pPμY%/yU/" " # eP ȿ099iOlJ/H엁2 #" " A@ʀ2E@D@6$ׯ_/@>rؔsEOoݺjn" " ;L@ʀD@D@;w!:tN81RT 2`SD@D`=zdPpӴ-l"o |x Nl)J(M&hŋ o:eD@6Gk` (6WR@F@ʀ " " '/ J<ѣGc ,>2" " "RlEFN:/EMD7FaW\ wŊ xBD@D@@BP>lǏ@*BDm`ߍQ[^^k׮ߙȈfHZJ+" "F:.#"08z=߀y WI" " 4" "O;_ p… K@ʀ~I)@_3l2%-sE%”QD@D@{:[;5SX~tz[)WN:Na2XEy7p7333ϻI_[nݻw󝳳666v N:QgNaP@)NcSX2wܞQ''w`-,DUrˑ[@ GZ4 iUrfE` Z=r7hTrrW5,޵ʀlf<͞Drˍ8EX0 ;4Fqw*_a"0hrj:;1ڒג_c^ elsظ_\wعF lf|h‖ JIxݠP駻ystr?/Wx5@>R=f܆;7O8d Cny}f܆;7N6(Xf^do|3M%wu}N͝aٹ_;x]Q.yX^ܻ@1y9zϱ1UyX6 2-zm@^ݰOPn]#êear< ͓CND~4긂c.r0?tW;#2X6l_Ǐʕ+AF6K7ayz“PП_gŲܝeU9 `lCw:?9 w՟v!&>Zۼs?П燻S=]Ic:O*Ɠn4qbm伬j]~_xQ塾./{x˜CX>ܽU-1 rz^x=ڼ.1~aW0wѝ=JU 懟eF~z,fggK+]%g&v~ȯ-s~ϧo8D ˎ(9yxEv?Xn!\Ś- պ-5lQ֐-7ZpphΌ1Ѵc ;7Ѳ#cA'醝n=9vkh|>`]U ɰ?\{"m/m恝 v~T=~(,av˗maal82"Ѝ 7B7=znFU[%CqHc05ꉃ??at˾дW8حucnڨ.iWefՏ5{ɏӓPPOn'_!1yAadn|>RPz,b0ymy#q큛 RR0>O(𦧧… s^=xd^wkJnsA)cO%By{ca۔< 7^q >yg>}o_hA :~x0\Dm@JP5fi1Wjė>7l7b/ĉgZ Z?V?|%E nQ y"Ԕ=4N5W=}jh-+ R WPbjYn뵐;{Tn%p=y_bF6#{3kLnWGzv*!xIٳvY(x"=Ǟc{cLʍ!G^eO)yKsn|]U`6__ORF[B$u> HHf wC )qf9b? ۱NJ(t"-h̶%*L+m{}9` L7m="KpK^x|ڣ́$ Ln s{H.͝!ǥˑPee6\X Wkcɻ> 7([n/ `XDt(R8)eM|(B1َ?",<<ǻ_3R!PU p Au@P0%J_3-yxo%ӋO8_o}tpK[?ҿjօ>K.~Յ@됞f|] k<>?9ٶ%e6/&(vSt5Hznhx|rd'vY`G~1E5wc~ʄ=XMƃQ4CnoiaNzdG)IOP+ A%?!F*PHW?h d.,{ζB!!ʂ@5/0P +Na7 1ʧ!dtÅ7,OE;3rrTfy(X?[&sc nO-늱תK.r!Xw]xJs8{y-036Ħ2@됞\rk"68;P8S7⎉{hع]އ<,ǽw@<-*:Տ́6QOy|e^FFF@чY>xn0NCfolznO(=x,q~r䖔@>ƃe_M?m62#ύGI1are_{p>(qT\U\M?,,,R @|uرcр|,o]E~?Cs;f1}0R4jw=oZ]PZ\MiͯI/)PͦHQE,ёG[SO`&`f7l_7Mw~!Ph| K4>B" 1S3Yk3C">#`.O"mw^XRPf c-  яj5όxɗ qMt3Lo` i|gW|ձv ۪AñX7'@Ihk6lzww# E[g555by+2,FY܃GeguruHzniDԫȾ arَ-σ"olyg:=XC8NE\+ǜ+@帩$g ?k?3߲֐}ufَ&4LuHN'am|k|n9پOwfaLWLur̅ dj9 ;lxx#d{+ oߎkNjP)&7] y`^ܮ碝x$ޗ2]6nr%]}j?E!, /JLs~@r{@2Buʟ)d'zRn>@xdɦ| nrݎ"wO8.ik|O~<__P#&㸮Kxڕ:h7n܈ӧOw5 ^K;.28װ%W% #4 )y"2_QL?x2!Tiѹq\~ @EnTN&bqSwn-r1EYlY20WKo'xvo=uv%8+'\+0D@s;'qaӍ G>b?3?cmKdo{ ^~myEZ??ߏQLT:Xg7#mnwK{PxH8l=.y۠{={SQgv=cA9ĥ#|z.*h xS'c8a=^pނ f Ey??<N7Y4yB<ߋ6?`SW|CA~L5yXcdd$6쁆\@v |l­Y>j0/Aq^$֯> (<Wu3v0]{@awSz.J^52.-/w\9qݍ<빽d!m;.Ƀ<)pч<> YQa0 wjRl!]FT^?X"4}+%W&Hp2l?{oQVwϾfBbXm "p,6`@ qOLq^ ;%!&6vxNBEeJоhfοgz}nUS:unݺEV;<1}rK]}+_kDŽbc}Pq_28pys;Վ8:츥½KJ_>&o gq@AKO29f,ƩF!p8RM 1ʯD;.h-MW|xdp&m + 53yEcw_ pgN;yyeߑ9G\ HkqջFwT@د Hn0\e#˗^uyb{e}2Z7~.MoJ{n$-OK__Nox^i/%Gqx#hBڌ!y#/%<\J>4iN" on-$]rl.:c R2! PX}j޶<;})qcaJ\&yrZ![&^†F!9h QGo[vR0eV2|?:4w_-;>>YJƧ ?h_Otqki΋W*]wu._׎7<8_̾jZ[Yw 1҇(DHb4}g_eѴv0@PgYX칬kr]ԣlB?]:O]J;^uD;ƺ]q`]i,vu97ɲZf%K_JW]uU"' quO$/ypW\qEA w>ݹ\#{33ҋ,q/i)uaW0dL`A_/[8kY6댖Sp{j*-̰mwvQhuBD ɩ \Y3O}ttf<Ӱ qOݺ\|y{\Mr;a婺\t*R N&|J85Q>ux|2}} Լ0$_ӤϹ|[B6qOYY?_ty5d|p.~<̨oNzk4.dڎ3 ;'( ĕÝHqO='S66muvQg͗vxsi-M\_Z iuvsX;/>wDzfkw6`p)lzu[;3u]}w5kG?/ySlɴnۊ_¹eR>A'3]+gb4M-5 m:SSo8mzvcg6Wf9hHtv{?f' 05ط>H]W]q ƈ%D9c2e=''6.:^xmD91Ez!b#`ZXٮ]R23y5 csRe#r$45,\'3F!߿?30۟~OO\=?U.i>x7[6Em$ =\!_0)b<   Zc,UJtϱq!@zh>vhVFsUnf ǭw4xz92Z&!`;y6vvk3$jy6nmo: |j+ Zg$ʗŢ#9}+: V}|3-8|+ꫯN]w1h~NGUfP~h#kA = @%鷌1/N0 's:Sy1@ET7*d?^4N?ίxf|ll,xc9KY&nN,N׼&NgMvηm|gIsvY'uTa/w:n^>-cщ>G@| *L#^?~sY<O9}pǫ^5e~\S߆Wࠂr։Ԗ¹d̗6z-yfݲN);n"li қ~#7.@/U&<#O|=y<y Gy[ ۋ?.tW6̮Fmǟ*켋ɧ!<Z765Li~!nKn7?} <6,!<J~^]0%֤ 7zu˾ڛhydD:9;;D)q?,Rz cs2}X:kc>2#.hE`mG |6|EHq ?/4OJ&s9gN>@Cc٬}B>j}_*DS?m0nO8ӛ=C IDAT'=)`t~:Q_ ͜㥂?޹&0 #Q`UV \'`<Y4h%ӵ?abgۊ],2ghKw\$ ?},}~£c|oDqkZ5vzw=aoNCE[2m34nρ4- ^1.8RS_U8:F cc \:3pEKl&\!V[~&1rx'iߵo<&5KCJ_|BcwUJy׎f8}=qwwHr{|,pM¾Cö08~\m,Q(RLW(9*#sA;~22XxТc$WV1v Nm}Fj)v}o~]d=V)F?++uQdzptt׮K?x$M/Uj7@DvQXq]NvyDZpgL2mIStDO!|~Fa=,WIב#Y]GܴsZ3FDh1\Af꥙`%~,BLҿsX]nOW{ڽo_<|(Ԅ֦'1Ǟ!])Mwe+ȘH;`sگvFnڹL8 aE5LYV 7=sXzc3vtϧo\p!'}mzӟիWu4ZLtwL7دtP>.Y2xdbq2t]p^yyDZ6$@J'`rKx}{A|Yg|I紓=uO ."ݙ-tx ߻tw뱳05ȊЌ uV𪳳ϵ,&y<<;5Gҋ/\^xAv2j7QB^ |KYzi9o?vzb 3m<|`2;iRqbj8Ρȟ;^&%5n!RyNOفA!>wMoKW/KMGϿ}w8Oמ4q8{8w=D_>_xS+]+iddHst=1꣍,EAs];%xre/7Y%򝟼94.cB<@k2-J+t.sT?}UΰN>{:ZzyY8>tg2|>Ҏ ܟuYUW]' _K#OCp&=|\cۗL߸]#y@~ ^r6gϵr&ݍ :Kxѿ3}?IGZ^~KZ{L]4n7:([H󋰅jšLFWOY{tꆕ駞5=u>ݷG<ē&FDkt"Z8<3-]vy4󃴌3:2!c,,v_ytH%[|ʦoުil@':`_1l LxAXo1B<ؿwAJs)ѷ!>>/@~q_|$O兀Nϟޘ}4-B~-h?GZx3qS3ץo|Ezi_]FVcuբG`?g~b~4r7sq=Ϛ2@:D/Wߒ~8'{p*p+UMWgRc+:&)/p,\eps?HUՒOӼ-> 6/eu:{E OvσZ$x5@BASzyZЫpzLJ:x1[S\g( +q nKvv7֔qO͟LY"noK jvڱ2g6bU1HQ^hH9 MeR@*8A|'ǷL}xG$7zd3܎N//ſh9=1(~>6p_l.<3.NOض)YgK1!]>MWIP>ZSO3Iz*Y(Ww6|ֻ)&C}ʑue8B|am@l 풽tf#c꤆rOoW<5=u[SΝilvciԕS&L\s+KnFyg ~9%GVlX^Uv|;?|Yiڕ镗k#3 Lh|L_Ӿ Jp2[y:&ct@B}y@H^ Cg4@y)_ ۫{%6S{ݥ?#qCibV0(֦e7ڪ딸lNoIApǃQGV ,e宽t%4qM!/P}󟟾/-Zzh*?<&:}a*JgpvcCqc1Rc^;دNM1>j;ΏO?iM҆]wd ]QA{ҧp^h-q=p|>ozx&:bl8-[gt}2`e\}a7?_Yn籝 odC‰b;‹ŹMnl#_ !'\6<^1Xoܓۓ>Ͽ0͉v]Ratog@R?f 4Rh-~"/@NO:h9Ȝ e OR8{FNm[ 12L\FWoHcDn5g(7Y6gulOO|)e~lzն#3&'pJHμ0J]VPk:H%J,oh|LrLr:\[u(`ۅ!2&_Zy gHyGt(N>'$tMsI_n[m1vj< >[`egөKU>(+zid—2e${T8 )_%p *89ӃK.;_v~goRZ%-t\=k@< q-ܲC~:)u|!wg?o &b"-J5Ȃ>E:l;؛΀ga H]]'&y,֯d/*Lx[%+K!mYt:҈?y٧nL>Q/@J~P7\\̃s/ѮB0zW|4r@_L$e0iA,5^7rx9oHOڵkMtkN~zo1dv16Tm+ pqWoL#:)t b-%Ţ夞q}{ww'~GH;S+J pxBeq͚5}+t)8zϷ]y nBP6LOeVtHBt&#&_Hqk8()Vu@mY?SUsARAZ*X"mٲeNA>ߐ2^}'o,bo](rw 9?yjWi;?lY&[rrKZ|yڸqNco'n?v|m/㵣bS zv(=[Y <s8U?vnX;cc y]D\h*QR6ԲYA62>Y* Chnu'˟{Bm~Fs"p3>M? үױVz[]u7;Wngv߽Cg|PO\N!Y!]@eQxe%PoҝW(2*x⛋&ݾq?Ţ< N[-/ݥ&=8}nIoyt%I[7N;P'u<ӕ0% n꧶xYTAcb@L@㥳d,F`P~(TN&# NW#es7Iqwlߥ|5FIh'2-m?*7I k|e)db]_k:|'F\۷/qacO{:~.w:mГ% Am]h/;zI}l.&f{X P6eXmfE88młƕ~ߊ,ykRzO|m CHc'i?Fc%ODKB٩[7<(ѧ7mڔ|P_P:݃0->W/F~! :nX좰Tvu8P?vv񹧦>{kwp($9]B Uu3_vBGx*y@dO>iS_'89:/o?]viU/0}Kʧc18QT<͗<-؀÷b9PvMt!`<‘#l3G$1NWA#/*e=8d I4ar48,E9l-<s,gr m x8Ä=Xm|++!<[O{N&=E-$6zE@g[hmF4ɠsp],ٺLf/p֓럋:] ={KacOj^Btu{hG}ўw]iݺu+\;fy/}JrMZg=BT8<6Nj:&ed3^޲/f8Dv5>c0-/5]Ă90Idђ3얂y[᣿sx( hF~y /L]t~ɨ9TG0zHM+ٺvڴV|߾o>qsv)f ١&JT-s9N]EBG=BOܘ֭KNqݽy[lTjݧ;cczgo޴C8^_.9,` Ѯ;qOy[ 1 Oc0ѽ:`,DP쾭Uq>'qp0g-r{wbׄv0g{,"M3_G?,v:X. OyJXs\f:;,b}b1ty)wBXwFmÇӭڧhikyGC IDATA-Pn( K/{J4G=]b%M]JMNS|Ep'b.22'-хx7"mJs|Z{t{ki_.~_:!}6M>!g []qi9uJ]+ӟb3}9h <͋5z'>:9v{U <2w`Jxy7ǯq(/dK7'Fg%>g<:oYڣ }"iK|G.vR~Y\O<2^HbТo1 0kegrcyum&JXzЄwf)sL_} Va>[7Log=X` #L \b_3hw (4WR+F*Zͥ9~7UG/̫|N#,`V72Sȃ%{_36]^"z.9q.:r^8*5|T Qϱό ,]E B08⬀s8 ?=5~0hg6p )k_\~?LLh"rdGEܳ(ǐVW"Vâ_/yrFkzȯApP0eP{j<{;<.26Nqp 1+{w]cG0P)& ́(\'ёX>י#u5-yEdc욟y! ˟w\#馻wj?? NyNX#Y*bO҇xtF+>SϜ4rU []# s\Gz)"YUZ.S6=GC#:Y42ʂ.7CP z{9mC.A"Wg Jamq*ӁGv<~0u)@|xG:[Ddit*𣵿?O2- 7ɡ`8<ֶmmNaXs᣹b?x2E6U|GSi&?k.qOhx/ y_PF_VDտKA>--kjFjS8:8Jv \Oub|pgƖs^8tH'˹6sNV珴Q g(aϳl8@6 9BL\U?#:x:g|RGǂlxi=F/v=~NIstZha/Fc(Xi'nw?ph=0'~퓿%;;"G!1::}(tSeO:=]}^̇Ob#Y:x Q#p56+΋Lْ.:wK|ݎ Wr}{U(U!K+bD{Q&;uV( B bqN;^[^ǥ5+EtVedkBš:eDzt| ƴ3(mΫ;<-NPk満I M<%>*xRpU݂ b0n0gX豂-Ӷe7,.CnN+מ ZYQ6j'as1T\}N>M-.FkYxSZB |_uawp57xcHnw16 7{cpl>"f`pbSYY(Ye?{0PSy)حq|"m߹/4c4$:<#4S/74b~9lbݪNXj,=܆𺾆.]p-|DИ$lrsJs-_=3)~tݝ|yegvwhB55ՏtOv\~n_ X_~I~EbW^x<c!󌱥'#UT8pgy?uJƤph E1kC1cf^BiWy_'= iU^>uleӥ\زSp;M'&txG[gBA4^ǸH#ŅxUo6r;#s0hєm?e7 ¨cJg1 B>'?3ܐZ&B~ 0`gipmLm-2PJ {h*v]$F׶~;5ÈVȲ: R`CzJ vI!sxwBH&^g|kl%JH.+baUT2oveԉcAx1 Nş<Ƿǝ*=O?7+m~H s1=@O_+pM/I/Kun:Z(]/| <"}N {>D8-"} }wZ'ܳ/Ľ' :A/bIb;V Mڒ^ܳ~dwmYtb4ҫko\CiG Ɋvkq;n0g͟&lz. VC9 W U5k&|9d_%2VriOvtwWO~GT#G8 aШIT-F8`\jp6 1!r"&zyzRr8pa%nӪc3zsN] M'xE*y:SyhKf:ݓes&Zy{} ]Գ-`gnB#OŎIoGyUә'7wXX]mBA{,jG8tɸ)|m^|.)E.COx?S`uoW7ܣɼҜrB\ ^{vuH!}|;nϹ ν3/8U Ȝ~+T:m?Syd m > Եƀ^&Ɂ GP "#u 00>d:c˺{KyEh#.KlKv_✴L+ ߹=v rluTTmbG\ӛ/2WEZ,cw!? 3œ| 7uH H7,ƥ ܉w$k؅}>ˆ-LF O9'F:u׹[V?#?=]ӵ7и H\mouczO/f^l4QwGe:_ 2,ׅa4R_8&@j=zi_ 9_vX *<|sN-%&=ݡ<qfXhHg7䛓BZɛt^1QWߑhy N@YWlՙ:+*Ks[ےշ/m[cWx̠2Ƨ]B-ypo1F ux>u:RV딞֓#ۧs\y5G,ymd~ oBE'G*C_/??{s_yIz%[gJtOB,OQ)Mܷ/?JvˍJΈ.\Or<+TU(!z*؊7K2v|-;GI2G6f{~:s0CC;E֭[0L' qw}OƥԧwݠYӃHo2.@uۆWhAN Nbpgn\Sg'e'o頞0'Pc=9MuY8T-tO>#KVp uAl[`sW"7v xӥ~Ɩ(t򚀇%PUE;Գ˦7n_hSOϋ߸yWg'Ly-W?MV{-\5}:>pK%^5u,ƻf\Rfy<A&̬l72 O,1UrDa!.#=N:4e%o)yWEXxm.!Tz)):XWǷ] ?6w;_u%Y븅]{arlrV&rwn?1)k;ZZ>OS8=/?5]}3I1m$ *'j-m>ImXE=!dthh^nGWޙpϮW%%] XB_w pӚt=Qؔh{|{ wgA9S Љ?Yr+6+?8-|ͥ]4"Cwf>S_[sxׄQ\9sUh' V:W/ox ]S˞waz&u^[yv3';̘JR9Ooܵ!?=KX7T4Y>~#M-y0I9 _|Gȥ]Y "'s ?¾wַ.|Dv[_Hr}K V}Ʀ9]nȆOo~O-i65]M 3_- vܜ_4ap&&_ߚc~d.he6E>3 o'WO:} it,kZN>;>™6Р|5m}o?ۗ^ZsT~hk}Y-6|\[_ޓ>b'Se bJOOHtG/Acqsm߷q wAKYt"e=4v'^ѻ p3x`]hg7I=I߭]I<]W[@QvYލe.g(#֣@.jgq|Q98ޟȖ',ph^œ(/xkJ_㜊o޺/tUg.{b57aX`ТVt #s-}f}9N<8>QǞ@h(y#B3i+1PRY4iUT=3s81vi%ݿ7sጋ0TX) z߃ )އ,-( -'xS탂[LE':8BQ'<3 J_H.%_FGȨқԱcik鞚' װEMǯ-|?'GMN/`L|tIޙWG9B.͙`ZX!]ħ{h̥]Ej۲c;N+~XL:$Yk&%l]⚋9xpdsv/]Xyr1ƍ/ :']4w虼T|3$y#FC2B<.11_:o F M c, :JC` &v[`p&ɮQJ$ N0"lBGX\MHwtd} klCq5G !QN2eP"]0d1 ib|!ȫR@5&b?n) oLYHtLk*N>͐~rׯO^կ~5wy}j:L&_Mux/:~*OCCgK$ڀ ~gf7S1y,`bDQCܨW:xF3E>8'IΡmЬtOEE8|a2^YK 2M˴8JOee9wٛH!{\~I[N cr_:<-IB~st72}g=~]ao*߃M^9_]ӊ:N /6|yA`!Y1j jcR\Sѝ~_r1t)6Ϲ>(Y#yIIޡgي,pxSb>v΃<C9'"cwѿ:*<2y+;J{=ɘ$d YdYC~Я<4K|ڵR#E\3dF7DgXv9m[5~N\T<ƇBЩj`C<M"q`ĖI|.~ࣣ?p 0;4'όQLAۄʌWR[:ajmxB/ں4*F3}ü9@&c%yp;(|ɎA0:'?ɱ lbwT}{+;] 69|v:?,Lӑ0?z|c}3ŒAQ>xދ 2]O\y5n>:~ =#lOt-I 2.8ڴ8cDW¹ռsb~~{k>N_š-}8PySۥcƴK]IY9]; ;Ru_\D*Ņx\S+-bΩ T#XSA|AY\\$G Fr'=;?5W0cbѨ2.[&B3k >9F3Wge1ڪ?wZ^)r;w|pm^yf6Ty^gӏOI_5WH_,~ݾEC\ôp>zDLI~-X8At)6GdNy+c=4n݃[ Y{e]pVQC CId%@=MåtUݾ7.LiA.8ARs[5 |y"666s?BFxIOҍk'^a9.x??GTݦ-xmI/yH`Y̅it(_Y+ %7Cx4|^zrm@缹g63aR\ֱ>>,@z鞚ӄSGm?=fքҝG[WC ˷v(vr\.GxXd٘Ngy4 m )R;<Uf: imy# JQp^Ml䜱q,أTWW2i˥,d5 㓼'qGp;:ksaQte Wg#k Oqo՟D(=G(qhF d,KtyrZvoӾ}%\>O4YwT>eMVǓ8;wLOzғbAWmq;x3h7aiZ8bt*%FzzjƸ#G:@_/wxPr0*[btxqF׾A\ӹLӧEGm!unyE:yae=r"iO|gNbc!2h9LyH2qiF~P}/_" -/(a >ĂS M_$ښ(r/5RruMz3:}~4"*%[VpիWߏ~w}y>@u>k>ankmpRMZ-&\RcΜuwp"SL#`0墬:#Na 4~p^H4WKg().o{͛<}mȱK״0k}Pl]ռI7tvQl<q1p ^0N@8j/1ҁBZ8F. ?YA5+A9O*-~ 7%6=aSvEJ?sts= =; ݃smN;ZI=B7dGJֱtx|-y/hDž@r;'ҟ~}eWX(XP9HP:W<{i54c,cIk?=QcalM.*\GY* ϒvMZ'uߙt9?ysx*cotM7x +2yi)>z0X #O~9hT_Zs]e|DO$cѓql95g`h0) i >? ԍ+K+|6bGo8H?Ѻ:񮎫\1G]E/,<汸\ys({2qD#g3@dtX:C-qAYq\IX9,Gi%DJ=m E `su6׈p(]tHLm`8Om@ >|μt9PNJ$9\u|d*?1PXG?q9/~6YgnXe&8,e43 /p=t:O= Z5ϯIz7p1x]|F<rӦX8KޅOmjOXP?uh/KS*s2ȫ,.^+!shcv: g tvdg.:q2ˆPS#0JF^mVT77aBw"H4a'IlP^vOkLC=USmN'DW#"OMLN>{I>rTJ,fvy2nZIu=QOy W0>G=Qٳ'p9Wk Դ^G? ;h,EOxH Cfq_ g(KßݙFhpq߿?CnOv,}uÆ:s^AA4\nU:9<2h~jY=IvzoϨrxPF/8P񞱴M &(,QStOș F^6nX(NˤQ[Nz{6QV~ tyg#F'=`7HxI~]Odq߾}1s{|?U%!ǫtP82bsg "< F^FDRx,P(7u픔|je/3-ug8`׮]A'Hm' WǵNNsLheǮ,[ug[=Cd]Flb%9H` _$b#·qP,Hb[F2-idHI3򌦯&lI6ɺkYsUź<ϻgowvQMwMhߧj Nq\[-p{mԧUgV7nR/ߟYOKZ`eID.O&qO]e!~>p&/.ϔgVW6m ƯsIfbH-YKt8i>8uR~9|=y$7}qOk~q7 x^kݎIִЂz\˗מ b86ߨJt; ˯x܋؉c?"^۹1q<.nkiֆ[wbњzbQ̀)u@dR2TbTee~s\#e~6;Sg\UCgh1@q˃KϨ ~OϱKqcwMSםgR: 7 IDATp(~Xkhqp;̉ÿ1*޽뗿|Rк9ǯ۰ʵݖ#kkí"|l9ӆ[?)fueze@wz.bR|̟ju㰥Nwx cr_S . 5 Հ_g# ~5 ƅe.n43K6Os|r|8ǭcv-RrpB*0wǕ9m}ц[?7<yAO-5?@BQ=^UkpIe[~Kq_}aȉYq;ILp﻾V}w<󢂺(ybQ\oj|ЃДϊ%W$,Z(JcyUF| @UenfjcR+2 \0S?R޼RWmg2-n4IL9>uj- #c/~QqR!g4Xa\ F@rp%5GȽis[:5Gqk_*?N<# h$"t8T>pǩ;;񥚯Z޻'?V jE>N^_6)5*wb\)UN.gYQqWʺ8}~83fjIe=(K3/J[qRo"U^u~KOJLK@ ݿ?σ7oOM[Iߞ4uNkdV͗o|麺kk\뺨5Kӵ#м5WHޖk^^25|ꔡ\I癴a.U{cC׾^3KpfL6,!#18}I=ٯ=ޝvAI9_+%lO.˧7?'e;aQ؝hK{Cw5C176]t7Y*~|C5F&6MoU򏭖tQܦq{'c=8>9>~DQr;ɚ!נn޼';X;l4[{GA֭[)ZNGܷs~G:#iƱSO|>Zcs>I>̨ ;3 u/}KiԞ/o:HϤp^ߗp> }5޽{y Joqز=ն{1Ǧ$w&)wS}WsaԘ}0ar18}YT+{xˌ:{#;Eꑝj\wtVmjh+צov5|(P[SjXJ|B9OW=/U)ҟUu?CCmӉAn> kg\T i%Kh78q3<)P(y~z|)}CG䡧Oɹ֜G#ܷ ǗGnS{cGX⭔ߛ 8iBΕ5-=Ry _3LUW04vWY.=59+JrR^یW6׾g-@'$mMT|k_v8h8>/c]ڞI]|lFb8o9->tt\t)p0 t>RGܷo_hcm/GvU -i:7?io|tbs9Pȣ: Q Bz =;Y@x.E~i)_u[G^.OK1FVG_ hK0'7@ǝ|.d{"C Ν+z=%"0Կgoܷs"%R3K5Z)6L,}㓊í6Qo/bF@ju*i(GiΓNo2> f=`\>_ _}k\{N?J;M~M}G(sx=Dǝ? Z֭[i0=;q^\/w?t zE`ii)?!{%0|x/xzuqz/Yi~ߌN~urQ lw?)ߟ+ߛ+>1 [R#1R2B`tᑒWLۗ7W7ʗmExf𾿕)a+QޑꉜkߗEǣ19>_֞ݓB@~ _W}jGA>b8~GÇyOr֭icxC?Ꜥ8Fo߿sjxjA둵 uy?ZlO,d"7>[>yU?% ̖gZ)zc410}oR7Vl\UΟ)&\X;K;蝷4Q wc_0i>{K@_f -:?p>dx}/w{ }Bpy9o>9HUynV6a*8?ɇb 19JxmїxK¯xGI|6 sd X%}L*~}[@^{\r尻p,k>g7D>q~,;d7n/N\II>Y~£6K}g@ts_R>~$Q;Qi6n*i.ӗJ$`B_1N*\uWw 8%}ǞeF6?:|\>Iq˻V pP=zk~3QP3_q6q£6J9CRg%UZ%O5]v\zu|fR tސ%}NwnR,]/6yCj>nj\g+~qGQT{?NL_mdG(98tʴNםtP= l7Tf[)NwhG9l6i k$V([:FIg$t :Ӟk'rukkþN4QD~Fh_yWʛo928sKySTsFsK\TmmxT]:vFIW$pTc߉ۦکO nef\[O$ߗmrǒqf?-Oq8 :/ ܼy󬸝 <1J*nTK‚iǝEbQ3&9޻/;R~InjFad8KonǙíTyשᶵ>ԙ.X*lq򷮅m+[6LN)<*+lMa[Gx^6)4|a`o{^Q-m\߯p9=q>(ld8Kot㑻O<)fq|Tߺa+[6 L)<*+lKa[G᎜1QN8i.3Jzg)mkGM'#vR.3J([8Tg0=sjT6Nֵ[U׶2w)~ivq+>!(G@|w~%}Q(ǏGǕG谥]flQ6NUˈ;ƀH[-;cv OR'yNݎ~dv;O~6v40b}~tm[*~eF2ƩÖ$nr<(q'Ϟ=;yarB%h5ni?~,iGOl qu1 C`'q C -N"7|CIь  1@4-oVь-,Gf!Lǿo_8H:  !@`2zE@gOV\8A֔L^9A;@80B F9%Zc{n#p90I5i" $I!@`*/^,׮]2o.ZQNӧc_^Ο?҇ @pv] !Wq8VWW g^|hAƀàL 07x#I󅁩Hfklt3yw@'@_8;K_'53`iih- Ev @`*_  }BPk8 @8L\y6mAToeT| ܻw/?)C>Ok @Mca=@@?<|dQ"ѣ'dd'5q AcˠN 0a@Y󅁩Бd @xY0, @SUk Dž@eW^y\rt~B %1X@kzZ |҆xN(<ٳE- @eC0p8jֺXYY)iGy7@ƀӳ) A@_7ǏOĸ$pΝɓ277W~'s m_@(.\؄/ p@U<(f @Gƀ' LE@ i5v0062 AGio@_ Ќ9}S_AGm@@ }e O_{K"c p ` 8{>A/ !+8@Q&1(@SX_ _Ç7n '1 " ~.v)#+_rSFBq%19 @# hz+VFf&/@`uu|Y˗˥K^6BƀMk p z/ SFIxN! @Ǚƀ; %/ nrZ܍/ EE”&fhf:|BpJd NcKt_8(^z4E_x`+uo@@ kkk#Fw^r&צ8@Q'1!@/L€wonnpTpUr"WOF @'ƀ+ #Ƒ!~RϞ=+oZ,P @Ǚƀ; LL}};qd<j_}բWOp Ncq߃&&U@~󅁉ѝڌ'Ϟ=[^S˂C"1dOF@h iߚ( X` E8@80ǽF!@h{{|apw)yOJ @'ƀ' LE@ӽ5{}}Н̟~iy $Nd, 01MsxAɓ'EYJp FcIۣ&&~aǹąx" 0u^Z^y9N@1@_8ջʈ>!Y.^X]- @$p&c =_eB2 rp @; @|2_8={HV@zE@kH"mDNt'n2 @+0Wrǻ'|Rf ovZ8@I'1a@T/ Lg|a~C^kH @ƀӰ# LL`nn.)1dG}ӬsΝ́2*@F@! N7 zjgn 'p>ȑiK.Q2$@xƳ!N1 zzٳSLd }cc{ A^{d @& 1`Hd I€>;v:AQ} Z+@8m0=x!@`*€& /xi~1@_w_s@x1^!@h0ߣe#p޽\AT}5@80=ϸ!@`b|a`bTG6G_qF9s̑+ A6 @_8^S?޾};;/\p@o!@@`ۊ91y*!@O˝;wK_*gϞ=҃ui F-7*n:^V w[ëZx㍗څ )3 pf C IDAT|Eܺuȼ{*_Lqq-Q ? w-ZܹsNQbC  ) Hw*^yKYUw;RCn}r??,..>@@%1# z;r\OUPDEZwa5k%7.9] kdA 0$1` @`*2}rʕʍRûIqT}m߭RI6|q%ۺŁz!@; @4t2 oW^ye'R۸VAq~['rnžUkmܨ>%>Ȣ?@*Gu/@86Kݏ/ V[i*㸶v ͊d߆U~jSqvq{ϟ?5֫Wk׮@N87ûS1| @;^ R~oV%19K^Y9+V%GmZoTqٶNٶaZz!yrƍi ? @Tpv7 " ګ V[)7+/qWg3\lLy6WoΔeeklT2K[EۙB^Z,/ŶY/m7ʫKUo%[;(ƫOjfrP8@0 ) H VՐYo䝧囏˷=Y(w=w1?`p򩼟__Xm@lΦq҆VlI4?hr2??[1!@@w₺}@t/ \|\~}[R,JdTxm6R~BO(}ske @*NxOPE*U~6^xfڥWˍs%qQJy+[#AkltT;ݻw54+@j>tq: A 0 oFyW]f?oiC@o#<_~ӅӅ4 [ j ٫[ts2SMk@vedgf6O]Y+?{}\\MZˮyaTnH}'V I@ʿP~?~^/ACV@+M YQOUw6]ʽӥܻnwz-)qk +N_A@g ?~%1@i}BPF[n!+ `  @;;F9-z'EWFv&߸Uwϗ'aGH-kCtt# ȗ^9NO~Pt壒jPX\9U[6S3d hg ܧ~Zݻ 68$~ @ƀp 0|Y?^e}IqW^)KKKC?_- ,L\ 0lB^UWv;PS07Y*z%=L@' ^ s۱_VΝYQ@VIF~rŁ!`Vq Jt!Z  #˩7xaj ܠ}V~g?͵0`-_€+T|zBv;J˺.9-ߗ//ϬnT󾗯zmGA#Cia _QxZ[Hg ׯ_/׮]!2A 0!mwqS;  >KjW>tRxg˝ga،tUκd SWSo 0Hkʯ2m٨ƀ^Mr[@ \_,WX eʕ+!   0L̍ lWA@ʽ6 1@k艷 ~Q7ϕ+uʩ)w فqMqYvcy)o$UO8+V%/iKsނb+7ouT@0Έ XI&%^B6޽u<]jq,7xEq?뿭C+'lw9<6Mk۴1o"qHϬa_^(?_5._  bH|@L!@C;l A@1#j@U)aTЦ]8[w_T(\YFxɵrIX=\2t&)~<]J6b<0xvxТZ ` ؙ X1 b5PTnCɕ\@`>ݕxΞ:ҚY8–̇WWū b󷂑X6^aeW9 ` Y @;2jgԆ "M_ ~lyJp7`3R]V ROm9j!'5}HAByK}?-#*%>uJ2oŐ>@0 쁀R|lJ_.w͕ P?2㻂. y թw8)pS O(20Ty4v[9C"8#}aAĮo0疽 @`gvC* @`GVD~)~mV,w! |uufF 9!G_q ⴕί -2>@F0 q ) H j)ZCo)>>3ȓʫXK#k28z8\Re~%wki*1 þA@=j8@v%1`WDd &PV+UJ1Skvz}*sf@:w;-/ԙz_r7]\sF\2.$1Xg_}A@ 0ƀP LBO%tڳzfV)֜ 7jLB\w /t8m֟iv7Ry^u~"~խwhyլFQcm 1 V%Ib>3[gTr@ʄtR$3T`OZibUo=/_$c[1@v @M+6ƀGw{-@kHA2QD8ו?k.f[iuAmgZ˲2]aHTl"Pw3<3<-=2$ @C,A&"`%SRPX8OUh4ܪ!3tW%\ _ʻ\UAoS$7A`խp$[ hg` ` ؍ 1@a?̀o|{14XtkV+^>m/ITG[^2j).Rc_y QQa @@Cc@/ @`RV8=+?3WYAUF3j*,[I[ ӕ@qZVNA̶ ǰ| &47ʯUv_xt ` !@؉L9+6xV7o_ ]6``Y[Uw+!|q>SP~?ֽ"v$*sJp@ 8 @SHE7x?@b)^Ɓ3PUYf{e+_˜C-#1?1z~+6xqH@i'1&>yt F JiM ooL&Ą@ -->'|]&7?xgx G~ @_$1L $ SΊOI gz,q%cŸOC~tթ;Pǔwެz_B9 EgZ;A-A[Y/EͿ'OTA 0 1` @`rV4[C߼ՀJͼ)rᙙlZAl[>S͟e`ϊS3ڟYP?UO.A XA)^l'?* @0| 1 `ZO~hd>ʆZ,BMj5OO%&vV⽥ uA7&ROmǮW9W}?wє{kLtۏW{ʇw~~u @` 8 LI@ʥ>K [,rE*UJIM ;dsEB6LFW{5ߊߦ +IT}jw:$\AJ[UZm}Ty.$\ !C @c X *iSRomp\=|9m'|.)=[vdd;~yt >?7~?N~j_o]ܶ?lp*@80!@`*V,-[c'OʝeU BCl\F?2mL+~ΘGt2Bh˴H':+ d)w͖giY? @p@hTY|Kj5l]]w)wSW߇TOLSut峎 _ǿت}XrJ_23~kj~/[[}ռ/ @*G8@&$`% lUҿ)86YN%9QXJ~Tҧ v< ?cC;|$W[?s?Yw2Íf.;H>1*ձijK2;#V}unT@:8 @e+R kYMU() @8)0=8 @PHϏV'zv=";zN-#i50I)*[7;euu5#܈fu4PUĝj23Pfϔ_P=(*W^Pk5q.|_l<+KK@fgT p ` 8 @`7V*Ta?<M)Q7=:ŵSށJm+ ךUO/c˿q(k+f%z }uk{f2T"U;{gjD Yu u,u H@i$14u @{&W.5;Qr:]lh%gTe;P|vi*敿|.~WȀy-7Sћϟ4LNGR|UfAny ?]4 !yDa틯FcgI~ @H8 @RiEPUҮ4p4'*&z蠜*QxQ"|t}Un#ޫ! .zKACDl?~ff\䟙_ſΊPg@V?45AKu^~ @C,A&&`ES*rVhM‚UOUr A|kTt]NG FZF>Iy'zΕ1l(1տ늳JdH?!X/ #O) &vQv8P_Pq @_$1L l#t*?xw x2l!B ]i~_ oMP> H֑E/],Ģzsf笀j8{J~}N 3TyƐN㓑B}ȇ+>0{0 pZ ` 8{qC h̵NVT#J UGk֩lGAzg"bգ:[cܓPgcڿ˯ZP.44t ʦQcZ@m?5'w:Z2Vgq @ƀ! | XJگntf-T!l..= tkcٖjHELR{Yle*ʾƯdٮ1G}`C7 @pZ< " %Nƀ@RL샴~XѠޥȗ.~Z$zcy`8.o[Au{B PU#!!@0p$@ 0PCi P5RLnJnwH^y:) ms]ܿOug#4^(sgb@+м"jf7?~V>z_ F(偬i8NL]^fBAEyye@@XNS奬XB]4?1(u:K |{2-*ήpVU޹|ET>rWDRoƟw*7P Veٿ@9m'*q52;n> 4040Bv#`S 3s[em=X/0 z$8.3EdwIDATԡKQT|2ߵV@WE-?엪|R6jd(Ġ텕3\W'>, .Ģ%)j۟S? ,e5[F%Q @Ic @ ,zRU~e)'ZFpLKͨay矤 '=\uget蹿K<7ena.+s˩Dڧ(O::733_\ɘϺܼ4("0~UMWE]n03@ƀ! SfɾL\M5E]j}ٔ襙?UiͺIK9|@ nn͵ 1A Ou/=3e3>G8?vOى}yl_kDkh_Rb>!E: JcG @`lP3u|"E^ڮɡָm~H+GB*c5vJ.J ]SR@φb.O*GM vW 3e:[{4uD}\u z @.TqfKXB j{tNo?sSQW*ѓ3 e~"#moTd +|]3`~5n E ~OTfR1l[h{eq#eW-@B'1 )wl<9Ŵ~үS eT7H篞x_RJuoզfk_ɦXRP9'/Or\2:tn>t p ` 8{1C x6K/)WCÖOc}*C^ J5m7=jx(՝Vk~nЖ|#ק˷u)|QQ([T=3._۬ƊEU~[-WRjFѾhC Pbc @b)gSo_Q}^/U7JWTpeU#VS|dtaY|Y#dm_Wx.慲XW=_/O|Ն\[W ŵ0hz]&Kso{C=Xf>T r&p@R6coiR=}]SFf.{j۞|w2OW>t,| W;=-.s/+K2Tfu1Qw#+G Gi$k_{\QUh94)^};T xM`;B ~*UY1@m]X+7.nV%y3o+}sc#ٮ:?3jЀ#-T KAd7.n_hݾ֛ p ` 8 @`ZV2tR4]Ç1m^ Pd^qj*ҡ;M\Oڕw]mPc:|cOףfC+e땚NUx[fYXǹ3nd[*ů ̣A @_@B @`4ViC叿o/竳e}3cet#5ji֛D; RڟH_eS+WSufA^nqjGs&.?U %bitzŸ}+:ӵR5FHIi/|ipМhZFL7bB)5A `L @MI?̕?}cwb}(Ki+lKYy*ҺtR3|)@W>b%ǗW̘j _M]mXÑIӢiPn|ѧk\X&? l#m1 @K@JOd ilPs./GR «ig+Giݕq~sxQmWM'ۋU:^^&m_52~E~~f]ܪ_w&}ʵ @@XJZ+6\>?[~^ f4DR­KJ[ȟnMo58(fPO?뉧ʻڍrz' nӠƕIeF6<~q#X[Cd>1oCu @Fc6 @riS RNJf %[Sӟ*tJx`W)m\~E8PeiKdw[I?>!̀(N}A EȄ@DRlxS7WSy JtӁHUzeTTǥ_?2ۦ6ֶ2M>Ko/T桿-O7E3'; @Mch.Bic?}3Re ["][+)eȖcw~ٟSUe"q*oqަJڸ}sԫ'V!ƀvVK? @"_dB  @`WR8xp>Vs " w\J)76&(VͭؐPRߡ|;*E˿HgS )sß"!o иA ƀ<A&"`#g ' O[7PPPSѭ*&Jg:>6(>Gn@GbyOڃ!4ZlHIb*lCC2x;m!@0p$@O+ eUJ_rvQ+{:ݿSN.Nʱ@:oIѿrn3F / @0'rA*M^X.]X(+r4^JofcfA5U>]˟jnm @0(sDkrg><7ᎅ8^\//O4 lJR׫"^ w wd zGO3iPZ^~&f5ۯq_ RfY2 #b G?R^{u>gfY)? LLcĨ@@N=|Vo,? F@9;@zb@*7\>oU]b65}_5t]kg%SWFw\X0 '*N.mSO1q3Mա;~ @@vYfULTL #Kz%W{ v{*JA 0/_7$gkߌ3 ljjFsA+UY]3Pڻ"݁_V}2ʛSVF9\!@rkCzY;/ @{%]kc +IAv!l+&g Hjk z4_Å0 gzշKe~]^?y o/#?2ՄN)jÊ{]$P ͖X+?0 h< }#0Gq]5@E  RJ 6 X*N |; w;Wִ`\U^e1@a;C@Tz\uoo2 N2z @n_"_ s*f6hgH 6Xnocv@^+kʏ @ J@+mAFO˿z/f ?Wn? QW7Q~:ʿ_h6TCBAT846]@+l܄r @J`)_an|Y~?x{TTNuF-6 (yR 6.@jEݗWWZ/^Y%mP0;? + @R;l(@kdLy\y\yBнJxV_BfʥP߾Q޾Q|m+3{+}V-Kگ[8@ƀIm =@m5(Mavړ[㙘1P0ly|k=ZŹR|e)+R\*'RMqa)6Xj|D@8|9-BQ`roCV58˶RQu~*oE/+Q.7M2@ p08b LO (ieU']/3^ b?N*\Vʾ? @ $@ @GQRxKx}xPp_+K3J*@pi 01)֣{[9*_/ٶid8KmQqNCB paM?@.|Tv[Giow?*ϸ8 @x0}@ @{&W]Ѩx)OwQJF۸6O?~TA ` xyi  ni+ ǚ @Nop;ݲt$ @Gƀ @ @` {T@ @&1H:@ @)5B @4Gz9@ @L @ p ` 8һA @ƀgJ @ #Mc=t @ oQ!IENDB`pacemaker-master/doc/Pacemaker_Explained/en-US/images/three-sets.png000066400000000000000000002105211217637305600257250ustar00rootroot00000000000000PNG  IHDR>'< pHYs   IDATxymU޹3o/^ &ITR! IB$lD  A6hƴ pt b҈&P 4UKTI*WzƜo{_/o潙kguϹ3b. @ @ @ D`|$[@ @ @ G }B @ @ @ 0@ @ @ A@ @ @ F`bM@ @ @ rz+z&W5HXH2^qjvczYF@ @ @ mjTU;/Fj_{UY;O@zR;vY@ @ @`Z~Kү߫5_-S-q{n)~m8k.ɠ^Fˠ'I^eG\ @ @ ;@͉~kv_ďzIzůUVQ^F@ o_zWZ@ @ @  IR7~_n-N|sP27J]MkӠ˿_;N-ctu2@ @ "^Us)Sگ|;?:NuҩXznfx[KsK+c_Ǧmv,鎙tt:D^~d'E(򬑞 [rÓe #@ @ ZW"<}e9=tq"=qi2OwV]F-_zq}0C v,{8ɼH}?)_K\^gU,GVF俞)- o4@ @ @@Þuӣ,7ߴvb!w/_{zyC1R^FKeD4-@ @ py^_XXprϊ?j2}t]l _*D#Ϡ|i=/aEo:אpHv|R}dO˥i 67^]06a"D{@ @ @ͩoͫDYz<'mx2{/gZzoC!VWېO84PgAWqcvSN7ͧw9^ph!me|p$n0ix%@ @ {^J+kRߞ_]H|*}d۟;ogh^ZOjSD3C7#7׍aWndm 1/M]nj+n||,u,'f{^8.G P{W0khɈmp E3@ @ @`9~53cIlC<#4Vβs6~mFW3Sߕ 'ZA]R74qmpcI 'z[tJ?qוW3s~^c|0lh`[ @ @ G@J~ =3Z~,=-Ёt~.s1ЗߥxIL7ݤ>ě8BR9s9#?}cU^AWQſn(}a  @ @ @k=^sK7>  } ?m6k!f/+ZSu:O;NCN\^3sjD8D?3?rzג~U;Nʈ ӢwmGu@ @ GzܪLן]L+ҕf3wRoKj~sj&4Ʋ4aqM=K~neiՏ/3gX]N/;>KYWP{B[\[EQbo+rHzWdu}ղPXyy }0M6`/6@qjՋ@ @ @ 0;>_k QBY~u/>#hsBT=^)vXs"AmR3|k60+q,i0%tUHJwp@ @ @ 5ܪ&Sv_?w7Fh!҅ę,[yRRmpNc!ѧ_Wz 1vbq۾`f`W{pɽ^-wםԇVimޠ ;@ @ UHUls72\%/Q3 9/SZvHi=ӤiPN;.go 3k{Lt^m{#Hԇ 7y@ @ ^ī+-e9<2dҙ@=A.[.'gj.I$5Uj1{N3F`v`(<]B@Hlb_wT0 7vw@ @ %V*H'H(sS}M1AaMÏBE/\ï+6l;i=؁a܃pwL34#^= n0<@@ @ @ <p!bʹ/-~ֳM&yƝg!O{.1}Ǥl[f^O3e}{Wm;06vT@ @ zD5l=S3=#nI(dչL!ywK;m6_~O+jìQp])\_IWa-\=oxv:qGF`Qd @ @ qDcA2OK??yC9^*"/>}|ehrݦy݈p+c nH<cn Ɍ>ثSug^֦8jx3(9@ @ UM/\]H{l,gY:JDSYsy +*<|C )Ly4{[s ϐ8P""۟V7PMQ^k-(xޘᎢ!@ @ @`0"9VW"&cSdrZ/_30' ~9.ʟ%$6}g-Ȳ|?o[׳mWg0.ߊ/Ψޠ ;@ @ v3m~EXƚrSS,]ޛ\hRhs~>#42^}c䙔Wo8hx~"Ÿ<:({:mg oP@ @ {GM"ŭ xt™Xz2Xv5W<%}):"^i߄H(vϹy)~ر>Xh|`? ul`:J@ @ v/*R^g؟6˳|ܡ% wC q FWQ~Tz֞Hdk?ثu`Gޔ@ @ @`o ~Eo b'Lx& K7sH "Pq{E?~>mEp̅=Ra5WPh{7xzS@ @ J$R䞙g'OM6>gGY)p*_߻͌ saz:5k^C uBB)u;axQ/(G(@ @ փ '~%n%bS4hOo?s}ݸ&IXi#L|}-oڳCDu9f Y;k21׌}=&' {gPIu< ⌒ Ȟ@ @ @` Ps,q+gl//<FF4JU -42~GO[9%w䍑$ԿnK]F^>(Ϛ<ژ ϞчޫAenľ:VMpdMNcpn6.@ @ C@J=q +>:_4)~C94$s$u8;Y\8Og8]2Onc 2TzUrZ{nmOI'/vq8I沷s^TE2 xW[_inK?8F/Gy!]~ko|;!\ax*݇>N2ځk՟#Huj|R3SC^n^VGlx H F O:^ʢzkSyZ7m٤~ӖIë@ @ @ X-/YWV+ob%8<[ڿԅ:߮_m'e+:>GiȔ\wkM]W? nĞ5a1 pۆ ^SKwR5E:M[D@ @ u%~p,CA2_v2]#GW$i A#^@8N~, =snW>^ō?78Km]I4WӽޏOvUkw@[3O8RgqyM.W X61{iT.cw J} #Z.՗V8{ixY@ @ ;~ד&Aeȑ9%8K& [_4R,sN³!}/2O]}ρ߾8٩0ڡJIv8IZ|lYrd2샢(cKS7OƗd~%u:+>o[λk|4^} ث:&9tg0,쌁of+u,r~q9=,= 3 w ۘ9˕#mV0@ @ Cnǒc}ts*|z]"/_7-imTk.MDʍ|lZY+ON(=QSnwGkqFX jt~ =p qBz+}Y }Βm:i7m_8 @ @ @`@kBOJ:kx.E* C|tgVWy J2XȊz9+H7d}Ѧd9!TFU/~|Z::ilb_J&&Vd;FOz͛F5qjbzzhh|A" Q1z÷ YxQ4O?Q3ԙvlva名"STF٘&)k @ @ @ .DE0S?\JrΗEQ _$ėgfuvUեշҕF,ϲJҒK\ILLڗƧ,Ì=7:vto&lrJ? HM7*-~h0~@蚮IS|^ Ae9VY^v˾wHKF/Rzˎ['ٝ,axsLDg'߯~Ƣ=>#.@ @ v~{ӗ=p~Í8q%Ҳ)l@[Ig/F<9a3şRZ"8ֲ/q,Z:&mfߦVK`ge>zf3v<tN .&2[f?sb,Oŋ iŌr;O ZyK/FjpQx @ @ Khs+q3W`*{lJs*^w}HʒM3Y_1;ϤC6A9>ߎ&eve{Ͷ_m]xS_yE~k 3j:$6<;3 Qnxfq&% oP 1U-\m79~#߿~:]o{M?W?ߟlvTt IDATN=j+pPNy0 s#@ @ 6ܬ-G79O;&b=s'-ȫsƐZ֩*}mLOڦwi#37dWU(#SQe4R߱mgVp*f.k+[9'˃'u1^{S][{8HO4fσ_ub-G^釟Ii^0? ƭ6!3 @ @ 5pb\rWYȻL2zϓ6[RCKV>g_2y0Co$݈@ @ @`$ּ eK2Ify.;nG/q 2Vr(:ѿ~>al I`5ulV<^+^9},ueB%[~_qݣ`cYY$ľo(# 2Mę >[o;ݥ?h3+}9#F=8` K/Ψ@ @ G@|W5qad!M\ 7%/u7oe!]>KWߔhwoik]?me.\z /,%JqΠWq+*߄>3c-{;z+e!^MKoyE?rYDd$ SFv6 Tkݕ Ȇ)fW2@ @ 8se_eQq1uTS*q W@ќ6)mS^a.4{l< mgK`5E4SWNijY7msrMk/Дm2'7ĞcU"ם i>UG}/rb2LLə'_ŷI+H>+x& ԇAc91FI3V|g@ @ @ <.N )`bn: 8l:[qdO˛s ϻoՠmCM"%owCWXz{=/g;*%T;6YOޯJz#]MbԝƖ;/O4Ox*])jm`~,} 7̟g#qq6w/\U{?{~E@ @ @ n4 SZ+>$/S4; "aKh&{\m>$k> `&@yUlybZde󛜳*|,4Rfpez6W3zW(lv \#M=p3SM>tdj)7JǏLcMK[g.{W}n/N=_dK 5L G @ @ l- -א<dXI5Mak藶T%} ߡ41m@ۻxo}0Y&Ǣ;Q?oJM;Kns&z0c,z[%Fi^6i67 O/چ[^b홑Ej w@ @ @`sSܲ8ьmDu@8_&3IFIkӉlHAK7IG63>a{M&܏uXKϤ9[jow_:msFmކ1{_%94-N Ȋ7%[>bz@ @ O!u0;|e'Kg@y}CbKxHSCazt4CvߤCyW11}|=lL\Ily?kurӎ _mOޖ&/#=n{\V:,*K#udu |vp&\╖@VؔNKFm<{/_r!-^>ǂɅ+ϧ?O|{ Y{DOB[oTN֫x~Or v @ @ # ^@g#x^"¹p[y 5H#^m[mc37FF?K;WNǧ XGcy@'[;7lא^cv!9mW-3ܙ1#w콉y,l~6=y{x펟Vɽ6 r l8Mu 0^J@ @ @ XMy<?!rCE=,[n uLtDzP^U8nNxSIwlVܺ!|hw`Lp#z-Wbxn@5 ĽG~4wfy~>&OSn&{E4cxq׽һn;RgpՎ~~Z> 98@ @ F c L4䓊2ʼRX#VϜ™Jn[~P\M,+&W=k_J}ה蓮X56}j7e鳶ʹ{cb我i̞ ]KQ 4ON>S۬$[[JSي;^fR0} @ @ C s̉Yqϱtrxêa8#!eS)[RNf,8aSibǪ.E7&ca?γ=gƷuoG=a 16{V\VÃ83(rx6{XJx){m Bvw^p0oW{R%{_}&շW>e=_c(Y~SC@ @ {ԇTɴ2n籋dI9l2j 'i"SHVk} }f/~=}S?vڴd`ٛ::D۷7롟W#=VK񹹒i8yRՆ0 @8K>WP^ |< @I Y,GQK_YHӶݬس[cǞ{ޞevs1[9/}b#q6v fQ>w䍏@ @ @  .Vȗ ?_>Kg W^gLP\Ǜ]lM3V{e}ʻ%{c}CISn\8ǢRzU?5g6h}-\Kn;k\4No= 9{wl:㐇܇'?A|ISup֣"-K6e2V:/۾esWw-Ki|q"-:T?v~1I:`[JFI3OэW_2Us,U'8Il@uzĘCa>}.[R6Su<&מx%f}Ͳ} z: ML0r7#^c;n7K}=|{纽Ȧz}nd?o;ix4+\ @ @ l8V&]r]SD"̳ 19O,n0I&My$sX,η g*u}k:~51mo9Tu#^1> o4J7(ue"z%~˚]X<>^S g`Ǿ B82rld n,U4$/(!_wȔ y hò;Hc`F G =nȹl{Ov7# ״C|X|ɏh߳^_~6:)PG@ @ @ >[][nq롅tLx {yi:SFtI %K>`ugևÃ:fm2cGi ĩEz߽lθMz&24nAHF}aێwtۑqI2׼'nnuDiã=nk͍6f Xfvpٽ޾$Smplyd *w2`==ndcflYֵf wf9ys#@ @ 6@_9t'ϳw&.o\еyHQ8UM4r/fC!G6i^ v1YUW6K'>:~́1d:7>fx]j3&N ثꐈ0^ywzpIͲ3?rv6b~^ylm7n6<!\ @ @ lU|aq+xl7xZ:gɉ6e}&#~t 2(1\8t,ThNɖN=΋, ێ~ynmcٽʯJĘҼMhyi}Eų w`V"[G26r_q[%Ni:Vw;;oxN xc8 } ׇM3`jGwbc/u4\ @ @ lq+$J ~up_'Gyx6|e@v↫xE`"KW(,_r Yyv'}2?j/Z.(H?-{u#Gɟko4eCZ㮅th^y^VLh<1ܧ|\ݒN O=o q,ieUŹs;7%~U+Kyy=UO_* \[~AKrE1T@ @ @`^nL-ux=Ki҈39;6͟8$t>kazLr_e})e)e=^}Ǥ|JIXok?1vYU*m0F/λ;ڋ,lu'0( ̷pf@ @ @  WH)up>_ȦUFޚOƐ|0 ٥љj3룣o|ⲷ6ç^{9ޒLH|#W?U?u85 1&e]ĞstV3;ix kk8~}XYd88W?l@ @ @`s[X<}Kq+=p vfBNŇx%+!g\|N{}qV&"Q|owL(vUir^E ?$/[l&oY^9eƞN 9 FEwɯ6׆UStD*~Y~ |qLѿDVWyo(KE>I@ @ #owێtқw":n$T~Pǔ8lH;Ytχ>8ge6&)Uib3wnή OqUiV]i8͒&ŭ:4.16bjNmdal28I206ߴӔ_G~UiJO/_N˶Q`1> Ň @ @ F8G귽={_DD$ڙ(\'")ݞ Rz[`xo\\fW_qBŋ.y~ڟ1)($L8!Y `}-דo6bO)ur F w+7bxk9MNʽٳ… N}U1L@ @ C@?J"mwb6'oה3͒b IDAT_DZ"JsBn~䗣ֿõ7E:*w;&mbO4FStnX FI o2̤cǎ}ϧ'xg oQW@ @ @ <UV"׿p%4i[ۋ󬴓. keAWl/i~Z~vUyK>-yuH7܂g'_||)E'M{M\#뱩ﱯN,$sEK O,GEr2e:-^ow-}orh}w26t}YꩧҁmݖH@ @ R:uogs?߱}l9xٚ}:l "HB4RI^DosWg[s_0㯛3R?jsBvmow΁*sǃ}|o  Y5aL3"NA')[ Q鍒~"Óau oÃȿ/Lrcs0Ro,ΥeZ/Çc!?0nvb҉^bX1М^\?jbIaz _8苧0rǏOsO:r3<@ @ h ǂS1q$^/Oƽ9q%spSȮ?5+[8iR=3zM/7,p3wƈIf]}w]/mǶ긓wJ'hUw0< #z;#}=qcz@ @ Cx5?soЪ#tQ>Ü,eY"lљ<,I.3''o!էu7I:߹)IhE6}6jPm}<sߐJ^677\KtxZ\ZLKˮl$i:P]TE:KK.QH*awRgIy°:?xl?3Kr놉(|28I/>M5q17{@ @ @ 0BYβ|KlM<빋 ?5]Zq>-//<6se B *rBP$­[!҇* V0p+MVϿu>;4V53QbOt R$w IrIaz뭾d @ @ @ BϣsnJOC!L o y}q`|^.@ @ C<[_q;wW-U '-33iv>l =*i#YDzY|f2Imr|Stge_C:gYQK?;AKkR/BznfQ$}jY=c>wpGKP@ @ `w8d"yfy*=3__3Ns6ʒ|;^x\/R.n=9oIppPY@ʫ ? AN7Φ{N\~ߞyEz`?ߚ˶.|N(8Pqgرc~##@ @  8!"y=$ 6gj_h{fgb}Tu5⑍dȞd[ТQS|L@fRo~ mlOkHÃ\wݎ{z,Cre;fcӧ6وN,nQa @ @ `ɼfř<~b=zΜ_L'reR.-Ȱ%| y.U^IpU/&gy}f8&%3هFygBOC)ҭGL=7Hz\N9P{@Ox3gyþϝ @ @ #a7U'AY)~Wqҫe T8i!_MώdȷogdgDnΉ<"|Ik|X&ty>m}/dV6ISH|&:;ʷ-J7ϧ׬EnA7<00<Ɖ!ͨ9&_p@ wvypFZ'v ˖{]-lWʈ@ ؽt^^jnB@[DԯsRܸn.17=RKՄ^KҮtCEBFA#fx{.㭷OxD|H"3_˯tɶN/ mU~CW$^[I#.Fxܑ#G=7JUR("5ًK>?=k.7 N/ZNEU۸#,񊢗>y2U{|j_vn{z^$ѯLWsj]vftUۉS:Ixr^Ii=q-zߜ/Їsu/γ,,=~{jw[R0(Z፞q׏t/ Ë@}U+^K_멼Z/{Pvy@/{+]ᵤ({]S2Yx733z~'ڵ:t#ՅɇG&lYKm|w#wiD3Uoι46(V`rѓ_il|Way''[Xϧr)ɛ#{-W4˭: rh=hk_F b68w\sw{7![h'u\qup]˯tIDvjFOq23qHʯ HA@Fo%al-uv9Bx\mkZfmFGZz<2>@`(`rGS/_{{1 )T-s=z"&<# ճSec_HK һOS8˜[,uσs\>_dgٖ/7dkm& {Ҁ0Ѻr{9q|\eH@`{ϫԬdQ{'>~#:^v/sq"2ضkQ0؄p-"eZ}uзǥ>?sd}>_#,/?n3OtS\(fs1q7ޖWt⍱௬+w<7 sW]Nݵ^th^b/"o@yk! b/GS${>733nwtzFzt]й+[IO]K:tjv,=Icivi<ͭ9_c_g%3t۴3Rcf%pޫ8JX_G|ъ"=:?D;/gb: }2kqs&w~7>/ۧ&3}o&zE;Iu_?ZLɿ;dl;Agm)bO@XG^R=gx_'q2q[G0=":v;9}~WC'&әY{%N)zl/#$8>)_.'Ђ^;N_b-⯋en(# [a;eX`@`<^V\w \:fK{,۠K+鱳cg:se%&=w<_K8N (# F_p|)[lrX3 "8~%u#G}xEm94#I< T"v- 6¬5wOD&gy#]q8] ._K"azɐ}}ܱ]7/;y8gh.H.:tֹ-'!P5m#eaߣ7@``w{=@晨?jNRڭCuNy}_]I\$K_HiͿheʠIۆ`jb%|W}21]}ݯ\WKGXFIb/2 QԩfY2p@ ygfȼHS鯞L]t홠3ϷoوKY=Ps|N3ەs9/~msN,SN!:D_}]%t'A8 {Ke}Jv.F}xGKFfkBϦz5#Zc\ۖ4e]Wl8Ve}MDxO=9b#M5%hI{±3@GyQSΏIo5YXX Kܞ4k_ɺL?9be2%g.nzI#w-;E K>;5wo+x}P/]wuЮpC@m4V]K}_v8 [4CW8s =חzgc|0\ʬU-~O]A9%e<22i˺>jѴ$ҤKk{.`\X s'TnG-Csnqh?qq9}t XfeYNMv+N?Csӊ_6g;yO}:+n,߄y|zr&{mq%>p!P5-#w~.[֌>[twwB =:]s.}ֹzR\Sʏl;u}VY_%=r?vX !9<_N'NHõ@'΃"5gC OޗD!N)wgނ̞<\3M4Bq.}.ʛsz7{~S\EcSlz }% С2ڲ4>Đ j}*~[7( Fs ]jBYzO>1/؆xFܡO.¼dbo&Q҄Eߕ9ǩ J& h?/Z^υSz3NtJ?qוWslf6Et>" 7}}1F+v-g w'=oui1 sԫeN@[r^7:x鞯|xr8f*yU?|t嗤گqq4֒{F1S䅅LϕQoMd>/-Î3k_7UD`K]K}~}oh!xa8}'uo/Kː^/džxЫ3C~'F$No'Q׎" |ѣ[oٸm\uA"+k'-W~ES~*q4^H'&kR{=Ź?}6ʛ\4Xe;㵲=Z_lŠqWaם #38[?l/^s%z(oSf a%Ǎ"P`_a7ju;/[گqR~yNaZyѩji),|;!AY=ɜp^@텎F.~6 'FJ%I^Q\/o}W-pé򗿜|A6x)½dG~I^q7f*8\sI'Lx$HtYDʱ|ޙ_/2~QìOxzNzMih/(# F}o}%`8IYk*܋ywz!+_JWQ~ON뿞Q}k[ Τ?׺ 9Ri!ԷG&ӣ:nޟ/|>t"7I|g,KTHJ",/nXsfs'bV3,9q_Ysg_1ߐ6rsIdӨ+{jظ:L^γ"M3B3-Hc@zRi{ .8ew_۝p]_T?xGz;ߙĒ42_~Hrg>>O;+ꪥjYɫp#8ȋh%}z9oZ;O7tBL2Ʌ洆;v T~8/l)۳D~(﹇sֱ 6mdwNo_amGYhuW/W\ OkЏ^~ղ.O;7~M/Wr};$6!g뙹gԓF.%AGX.W5|M{շ7헿YP68~k3g k*lq60D}K6baA疽S^i{:^HO>Qʗ%;R  A /Y9fAq~NvWq<?s?^yrMp"I61 u.]1ܮܲq_q{:zxf9vXzK_n 2@@ Bѹ&,`.*JMk'7W;ٟ__UځNqԸׄ~势N''}y Y2!VM yzj%W+ۘ㥣tOCY:yop ]^Fz9{p.ߝ~?¾ SY*Ez E֝gc{~#ҽ޾W}z];}r[8ΛyΩ@`tF 7= RE#P]H*JGr!$^ZY痮$wOCK= 77^K 7s -yo~?-a;\~{.1,jXHYrrΑ3{O{?NN72LwI?ĿmPXۅ} #}Ln3[FʾUگtn_t)=S.zc? ae$C o<׬\ԩS>czI{n?9/˨u.g=~tiʐ_]ߟ{M,)]RqHՁ?ܵ~z%H}mU ;cϴ`a"8͓5 SC]pe4>DKࣅ+|H]c]d(`{9rnFt]S9rKy }o"H=co?[kA!!#~FH-O {oގijþXyMۗY{$eJKLk.=97!/rC90;dF@3{'K36ž̮#c*S[aÍkHcZQu,?EWUǖ^*9u>zd 䘃}IUXtD@ no5kMYQ 7%w}s/ :V3"+YwYzqæt@b]CΌ6aY>3 T9f+rݬn"ђ4_^2 >z@<:Fb69+LE'3yp(=yvr7Ĉ֋cou4LWΪ/ZӃ6iڕpuR$*z |a:_ش,ڛ)'̥}är͗182$}}F :noTs+դnC;zHSv$h(4% ::?u.I,RiQ$Sq8qs+\ƙ0,ud?~n|ZJz"*9KJ\**JK^iTUnNC,rhd*3'k#^ۏy>=֗Nͧ gOHLtoFy>YS1Q}z&o(bg?n. n!ٶR)N3g1z<}ZO p݊OK!,c|nH޽{|J?? ˃p fm!)_~]mUe}՞2]-D$0oü*QQ!̜f>"Y,X4McP>ڽnQSΗexHm&sQ^Pyf鎲^杓U\k* '=p?v`;V,,0\!@v~K}m[ѣ|k]t Gy2R~t~H6+SLd܃ܿ=^):J߰z دG Svw&ve*瞓WUxGbI$"dW4Av+nրPx!ټi^d!*x{FiB!@]gvb ~(d/VHӼA㇑8eٷ=Z&xGI|]Ogl֙WO;ink̛.`jsgˌ"2#{U UTiG^3ʫNF֡P~.*t\up}_?8+ݪߜ.0uZi:`4y)Ņ~;~TG qNZbV#}  Tϝ;矴!nHyr{2h]ډنi4ݪ{7կ4O`/Ľ[Mv_74QCH7<8HjpI"{4vJOy02}o|/ߟT+ɾ'OO<2>ggӕIfuٰq6PYQ%ˊI-ߩ/[l#=DRs[8 nowӒuO(釷+\:%J~HwE:]J;UCQK{<6ҟi4ݪCD@`kb5Gfy׌]!c"˃oGE7Rb/uZFu]~ү/h‘v0@oKAs;tϲr3\,grRps/ϟ$l4>n7Fҫo#\ϥ}|jkw%ޡ@}p\kƞQy#gIWػEtrݯ˛zPr;W<'9fғ/N/J0T6A\?9$2l%ݵ?qUL~{|#oO緸@`_X5X) VM޺7w˲iW]h ~w}z{;#a,ϣlT^FUxvU6+-_azKr*?~` wܖǏ~bϥ95ԗfmG[^qcߕN~mkNK{8M懌Tjvz?cҡ/96_~# mPlJUy^-y_k/m?ܹuY;xfq{@3AWa(numtZY*~îcu=S\K.jWVPd؇&[7(nZ»IRWQ7+XO~1l6tS]Y`j^O4?" [ܐ-hǡ*DUa9i>7o5Os|"x643y5II>+җ|&6#/;ӽagm }'χzԿ])SN>Y8΍%bhhr|)vM7}9}@AR=,¬({]4<ؗn>8n='V W޼'ew:~cU[zۃ+`eMWP,)?aٖ?\9dd/ucJm>l A(u"yaޑ!{MfVuT{ǿAMCYt:BW8fsH2Xe+XsΠ,t7·fRL_:&)f' 1kIY6 oĦHLzy3^}SRhޗz[FjJ꿜8 +ő} kt7Mw.&Vm~0YuЇ<]r)C*cm!fƣ72}٭wt]?gEiX2Yk :G:T绌s9UѢ V,V줍>YMHG9 ,S??gNqJwiWxȥF[^e,Uu3!<p o,I`'*)?$iq0is}(c>}C{lUGOsF/9fm^#3FG=S?Ǿ?>駩]o><5ħj3{=/[ښۗ 93uVa8ªj4{ci~ʖOɟY3SiHD֟ y+?]Ӱ*xyJg~.u;Ur}bXb-V0@ Ʀz^%Uүwkk?񶄾˛%S#5n3 IDAThy*n&"ʫ)gr;4җyssgRq_7IԿp=l:ߺI|5/=~v|vlev??~`gʾ)?(*1jz^-oW y##+Oz77Cށk$=wۗO$-/'ǝW=\-7utE:nꕨK sbs6ZeO>oOߐI9VGQ%ya37e0.b3OXAgIӴ{>UukCz=Y[nL{=Ol:vXj{n>)uF FM+0 )syAsrl˿Hz//ͯ9~9ʾ,|d}bػnO/)=IgR穤?̄S~n&aY]i$k^#8ɌHsn43xݻn~ݬ߬Ґ:`3;oz>=y\4gYa2ox>H}__jrGgQ|HV47 iAu~~7Q^ߺIKD@ Hx&6'0ʜ>}:?~ɂrv,4p/k˸><<>3i||nr}Џ&`#Lg$hfL6!ٟ(uY?ʇ|sgUc9 ¬ #Cy~+γ^MŦzչ4a96w[u\[AuXŔ }f!3׸z*]M7lq~ը?Bg\O]^l>3}C2f|$7Eeg VdUS)d>5~CeZyajxϸ^%X7b~ݠ!7~^$Xru9vO*损vJ[ upt9'CCC>)nj6{ƍ|['N-0+9 -*%ӓo%?qx_7Ϝ%,%3k2|fYLEDRgunzci,}V. bb#Hc gRҸ ;ΔGEYI=8s`vnHgϞMO?tڳg!D/JW҈(n vD3sx=_kk^kNE\0bo"?9B.)bJ+]+T7!2 fwu,bο]쓓ٔNizcty<~6_MЗ >y .2e ktlD3~]W;n(mf}3z#,|֎~g@;Òx;*;nĵ=k[ j?)[ݔ$$uaL!(Wx[jE 9ѷ[߮S|~ S_Q6 mY+Ĺ=9j}q~#û<-Ժ[Jy ,~Sp|XSxK+O)@`5MmՔ-ihؘnvs(oLg񐚝dENNV`Fl7|̤}>Co Ͷ{iW>Ee9w{C/8x-Uԟ,:?Uu Qi0kB@z^& ,cVK^Θl6饟W& Ğa=Z>W&lI,VUNl x{;hQd۽WOA>zq{`|8cTzfM'dgLf5=%׳6ܴ㷛 yo=qn'L/ݪ/-Snp~-ƮM;{tR ];WnJ\uK['d /~Y,#@ h"Al7@t7}.n[,e'N*zW0}長ѡtd;ReK/7'#U#ź&%NOu0%vݤ>H~Z\5Y鮇Tz]9;Iv^}rvv.8^P@ٗ:?Ck(7IJ\4u\ؐL]sviۣف! Ӯ@nn}kӧ?_G4WueYf8lOIЏCysPKs/gOx6ggηݕ @wyPNaOd"_6R?n槮)޷o2mvTj4,3u~C~s~f4z{\/V\Ki 쟳1{9e~{~~'Mߝ{O> A "PdE|ސxvAoA .߶mV\8c Bv9^njے`|y%/(7a/0wϪݨߥ~qYQ;J@/+~;8ܛ_=u1~vLpuS%>RX)^@ X7#MMCТX(/pU7[u#_JnBuM%V9ф08 DE2$ +kw寰,WeϧGH IJ7_.12|Rԟq7b~4;1fƍیɳU,DJqJ?aJ8HXEc{lVQ5nF]Y*!!^eWD߱ȃya[fhVooo4yig跃~>g6빨n }b}*j9kʷ-GIgϞ]%Q^4v"TS7{ uE%GVyT8MnBC>#===VH'DeQiD?]-0.~am2MZ؃9'ajaw} y <1?f{L!7/F?oՃTLٌ߸L @`w"~w{z ˁ9`Ӵ&)[Yr r]e]z8=uZ[rKKC"}pO:2blpui?%^|aR~[*)AϿ3tzC74>/?vbaOJޑ߸9 3'?_+qK{A'A=pɾ㿚]9iwȬ-^7'@,tZ!AE~]oL?s_#k$n[p~ c?rWzm{MӿO>zƉ=K{8LëD~_]`/>)q^!@`Y{fC GXM ;(ҭOUğA}iJ,JjH*;ͦKxkЏ"feoI݇d/,ʉ~5bbˊ?/|<!C73Ӌcs\:qHP7z:~?})]xޫ|/iZbVKC;WSB." m!O[Vw)Ap1HfHcMc }A'?/?)7C.3}j#Z~Pt=κc׉N;t+];cw/m|wMjw!~wwKh7qtcV7G]Oz׻QArҭ +IF*}NΖBƙzѮLFr8vʯ t AV^)I!;?}i*_~ݝt2`zK;^X39=9}f2OҴ3[_x_2"k"TRhڟgKJ`F% OH>bQJ̰w~>oļ/~ߞK/k}AQ;_ج}^O Jnv^ܲn譨nG n׀h"NtclVFevfv^S۹?򑏤--^-p9Dz/=?x=>N+"B^đʰ^絼9ϸNhw>Ϥ;M'o9ޟg^O?5zq<'>OF{s>uܓʶ@wr3˫0n~Ä%;[}KU'=`#셛pjv!Qu}j#OO=wŏǟ>ty{~nzu{~~6 }~= ?u5Z)ۦl=-:},]2tV(s}~{#@5#Y7Gݨ.3G??vJtfڛիWӽޛ~Ii=>f;D9gGyۚ::/a 8  <3N]|xN'deY99^#9N=gp@ehݦTyNK+lU~ߑ=sEIH* kJdv>oمK33iySUu>#y)Cv̳<m&/V#FXO_;"M췃=};Fq/{  _p]\#@ hne$_򒗤z(xM]G@'*V xGKrv)<:J |)_p"%yd)[᷌J"ۗHIO>FVx/~`d_{8 9dNj(ٿGo3Nv)Clv~p@R|-z_8emU`7HҢy!\8aRXo~s׸\gǞ}$1?;id>hfbv)M_2]q{he{EXƽ,=8l=MC+͊ ^gt$>_@ X/z(/L l"v:d/˗^/o]0YڛWX5J_vV\zwriv}n>39k3~LNN&/7asCȉ-ɪxIV_ϺLR{6yjg)͈s@~4c ,_ס"uix\DϑQbZvk84t$t~"~P\xfg}֖3#oJ->C=!XngOx`eXgodu^ʸo. ]@,. TF#ۗ~73}}_ɓ'(Ӗv" ФN!?5H_~SJ pqB@3hB9n7K.BqQ g*MUw-ғ[}l}/%CXF3 {m9?Db1ʭȃLMC[ ޸/w޽~-+un]@효nC`{ϤoosrA f]MYn5>+ƮCu-e3m[7'gI줝m@jPY s~JN}k˹^nz,,LϫyQwmc=v'ofA1A IDAT&/ JRO"nja柗Qk mҡ} j#n"0K#{YX[Cy%.1o`G/<sG: 9?f/ gaz~Rn3%w}D/\Ο %M9nt9G)E F[BGy׼&T kf\ē[Ni寲qvs3guAiD)aoЬ&$ct/g2ls3p\xf4ezE%lɏԕzz{CyBUCrV[H7h?9 CZ=o$xyyU5 n=no7kv >{o7| s_\P+Puz`r'i Dĉ 4'HW\!=X0z411lf<;p@ <n .wMϧ;;=e\KwK ၌_{Tzܝhͷfg!yfg3!'9f^]N. `7Qɬ?*_}%ӓ{^.+G|󬪸0=i,*~${eZ<\ (-' 6[d^x%gQJ~ܞ(o og Ώ !l2 k_,wy)N'<?X_]v)nWe=_#@`'ޝAvR/ |ufJ)K髿ӏȏ&67#MCFHȏ=ã57OfM80w >c賎լG&.)M*fۥr-^Y>vjARf~t{~=OSϜZ9*\9^kuIρ<, pøΙ]xj~kLZRkRe/Ϗe϶TyRQ>gϞtĉt1?y6={P!@`b~XFNF '͟j|5%c?c}'?fvqJp{tz}~'aLLf֗Nیr&Z:vȷÉMפ),*czex"f^ţF*Wu\cW)O+b哦 ܡ*3M!ؾe3=&}nչZ9C,M]2ӛF:얟vIKR ;>Ϲ;/yK|!{0@ __<#@`}466VY~ό=F~~wo\@މӎ#.S?/uĨGU# LKht/ĔQ-5Ѱ%ϧֻC$v< fro.7Lyf"eEu8X~uEFdZ'>~' <+_Y<?d(e`$:HW^N~g!<hCtG;5vɿte2?I%s9mٯ" 33"ĥ{i'x,=?F=\B*{I?t`t>W#C0+G {ϯF(Siytt9@2C F -R+F"622ntwSl"*[w]CD^,\alz*֥I.\8fu;a.Yjn_Tj$=㞮(:/n,3){2u l;;5f|L`za(ìa'}.}wE wS62+ }ʚ/MOKv0ԚCAN|- [ "Rew#m^ցRAówz{'`7GԷo;wTOIos3X*}D>D; S 7>]]uѪnf܋I]LbBy3N +C ,ICYv/B.,7ۻwu0ύlttøcJ(菦J7x/&ʷf'~oܠlWH y3 d/'BϚK]J~H:a-͜=\ri=Ω3IJ*˺ qU*>qvzYM :HG ^$㵆R6oq WpS[vNRsMӵt=,:˸Yt X &@e#M]_!B!Nfzzge$F?P7w)=L:эOn5e HʊCթg% ч3<"ÏylMeXtizQ ^[vV_5^s[RC.&aֆt[+{m٩u7*{'٬[3N&9pܳd#~q|"4X6*;~Kʔ]RS7Үʲڴ+d3Ϧ[BS} $?{7=ĀQ\'z_LߊV.JN39g:n'gs5gsKf8Dꉋ!vyrn_:nBNCYu7%6=s?V< fb}nh gBSf}n1P+o& ҍj7݊/Yc[x[y\;Z}]bF7o|d:}/H#V<͍g~y,1e.>Uwkq:nV]@b=: K|^dx )Fv7dk-Y ͰtiJ(ݲKe}P?! %ː{33]{OgyHG$~ّW ۊS&XKlpGŪ{[~'Nc̋kƞ%H%Y7Ii/xίo9FlQ_n2>~kS.ӔQe,l;3vϿrرcÛ](/FwcD_|߁|&u,MCey7orK.+oGg^IOGT~/ =vam`>-!Ж=MOܭK3!zz~d'}'mGfyy6 ϺQnc^x~~oug2 _l^\MbL`X)W aݎ@ݮ%D虡b7{¸AK.6|io567o,3SCibfyƋ}H>v8 ^fWp"$CIc}Eyqo>Ӟ߯=6S?2ԗcm7g]oB?B[˶_~:/yi>J{7!Eج{ԓrT@`"~|{I&&&166qq0Cg&[Mr꺜r,~ rʙ;O :oVxiv ȁ٢t [RMpI]6Ytp& 373~-ᅫԗ30O瀤rcF'j~om\u^Mr9׭iUn糹VR26cy>a݈@EwB&-֙/2ht0u{E2*"Zk=gS=.hmo~,dH7yi/7ˣ/q΀LTq<^%\iz_]߳w^'[dl4A7 e]W^:s#kf}ogtgogv.a8pbY~v<%缢ezBVۥe_EVײ[ͧwy*mKσHM[l^S(oM(p…tܹ|*4Uz5Եle;2io_3nqo픬_W;%kW'˖!~ˠ]$!>ؑPty[Qռ^&qM"j<&24daz`eumU9;6#j{7aos&}kfP}ԓ*C<גߡߛ}QvBŋ^mlǫa6])sw_ݽWK rRJ;tw+"5Jwi/ #<3{ xf6jo}<[Kw~sTB7[ mU{>322n4<q|_7HP^*Sa-B@:VawcptoǽѣGc}1Y5r{.ɿStn'+|]AKei.%Mg7ݝ@N_)wiWx#zv@!\ЯH}4Wdpr^3~2}n I)-ë7سC˝ʛ?FtzL.tuJG W*mGxa7۾l2}GǮͤ?ӗh;,_3\=;U\щ:W~d]vOߟߣw~[gkI<7u]7x]*66A ;?*nۤ[#$Rfhh(;v,ݻw:]O7OixB~|zv'KϏ'z҅41ד&f{|Oy?Ӱ ΥKdžf-#}^Ie]8rSۚ؇œwtBSWv*=KbӭV 5/ X7hݜEq4>g/wi9e@40s"[~oydΤ ]7vRd9u˰0Q@`Mk,~_Ϙr]Ci<1B'ks cW N?GP쒄cpW_3}v̤Wqlc $,˗1mIdJ/^tB  k6Rl]?i~i_2:דy/=B_pbfenxpcx9.|NžtȈmgmGfGhOt^DsiɵQRI^qٞ~1Aߨ"Lq-a$p~ Yj_야^J6nyWa6qpѩ7OR}<k| $XBl b.%vP v;)rB = sU_ Wbz۴55ejI$I0AKٴ{`xCL;)㖽T,AfSJw;I+Li{)v@ X5Zs.L)F:4A*2|fl.}PE XfyYNMO<.Cs]*$uݯv\,]sz6fOV˗t,^oa*}t۾ޚ7I>^侼z]rn2]OK8ܡxyxK\L4C$Ї A5t]Lqʴ#$(M߬9k'ɻ̣t7 B {ww6X/ gϞ ɓ^fy tvAԷ#'<=py;?@ޛ|;8yi=qz==L+n-xU|'c˭&y,|wODۧE >ʣ)wjbObJw͊GHrZ[vd.?I/5TC P)v鲤(5AّM$Iߴ7Tk /hϞ==nS^t=C8z|f$] \9o$ߥ t'/70S9]*گzH,hq=bOFIs.{ǭ=7;g^Gxǒ^M/[w%xz;X2,=Ko6q w cΏoڕ$(0bH?%+{)K{8,)$fX@`ZFΝ_=|Y!jkvy{-g\2~K#:9q#|" @Px\o"#~kRX1ENf߉cF Q>^6n͓%.bT~Wg?]I RYœދCG&d@ .tJvrKɮ4n~e/X 鬤-'Ҵ~[][| O .BnboMWRyfn~k[lu|#h.?cWzzW8{D޾4:8ɫ7"r\O^%t :bBφxЫϙg>=0@#sW5]ʭx˕R >7×gg)}ni݃=||++|͞Z${Չ;O q?$yg҄Y7 8]Տ$^N:jEzߗn޿t;܁@ Нp t39x` nUumBu,=m!/\N=˽<ߡimfܿO77brr;&çW*5KbR|eVO@7W\KG8󆚹}w BJ=Oil /˕8sB-O4S@ @ @`5[)^^/o<*)_[MNNc3ޓΌ'{Z,I< 5{M3ʸIS9fWeOF摽;ld.W^K'6FlG[= Uo*baB񲢁沲o7ɟf!"]vUC@ @ K!Ify>c<3_7_q0C-gN}0dbŐ^v"UGZO~%긫L -έcwID{?eK- P=(_t؇-ub+=˒d'3AH@ @ ˗xí|y>p#M'nMRfӯ|q4]1y&+OYov0G _s2R'sVho32N3 ^f>wBo~I#)+wZV orb/%$#'vR<=Kpг%L @ @ [hy>|ȸOmbܪLϤtm]VgXSo6\p?wAbM@ɴ-Nޯys-:Y yOd}@Oz׫w.vﴡvmRbEؘp AkD@ @ `3gҕ+WLx=K+|YrN_#86Kn9I4SRnV<>{z B < @ @ =߳Sǎ[q3| #^,ebvl2aMFyy4m1/v"ly?rki(^!)LPoL4f뱳 k}y3=ܗ<4O^f-#rqwA虡SG7fQF @ vFci쌣<_r5#/+vǮM4˒{Fy޹s_w66r{L;ykaъg.J_U?^Oܛgo_o:9:iߞz\!@NKz`͖PD=]zի:tgyb&@ @ Fg{SAgFtMRJho}/}!{}@yL!U$Flr٧]J^s'>{g=4n3sx^䞲O0RadGQS؀=Ms'Ix(u4ɡ'M&%3Kղ Ul]1]x=!imOWLs=}˧%!I`')_ g @ @ ,d!ߧNy~5O3/}[=t&^@z'Vs8p*S&ȌkxT/Uʶ/'E{{Y7/Ui<I+^Moyy$M¾fKJDŃП;w.B9x*&@ @ Vx[/+g%')i> anuY1 ~;GĞq̥^s0?6ՓH_1] `*bO_ L7,gJqdsO)iIϿ(~\br]< ~@ @ @``f,g+`B 8-:婈&zj0]!~@#ϕ$|gdMs _;rveE`a~]5?gM) 36cO0R}z: 4bO05ICN_/G`c<u.@ @ #dlE|6ؓU[٫s@315w YLk],*^m;C/ :=|K_I[n W#Ɖԋ؇ѵvqɢSO6:'2N(3{a+OM @ @ +C;||-SWѬDR4P&tTsf"kp1lflE}':ıZpƙM%4+IWLpl8@ @  .jf^TDW! O˷H{yQc.}ti"DW+<7)ĞzAH)rϒ@VOg|U\{iI\ w @ @ ,`:u~oJm:vnFfN*CzAX9|!-('Jhdm(cA3gLJ|ol8/q<% lm6ثj(b @ɟqxw8w;)z+r@ @ ?S͞YysZOIi'v422CXcм9h/g*Ծez|Wr=c/<ۜᆣ!1UIߪ'JO寴!9fSz>\_|8Wd~7;4$4Q)W ab-xځ-;!;ٕ"&iA+jWWfsZq@ Ϟ:xtbV>.œ @ @ C1xӳ+>=si6UnD+"'EO L87'ȊEmE,Il̺bR驳s˛b=e.ʯ*KAƣWTu鱾tzl>^XHLe=Ǿ)3ec@SWxP2 a=_Պf*p2*OXC7ՊS{<|,v)4_kU'IOQ_JꗲZmF!@ @ @`^q=zQUXAEmZWp`Q (j&}O&Vnԯ8<ޫbIWtA8Zg`?p6oWr+Q+m8Wi&ţο^hm(V2:gB=u9q6+_սn+j2@ @ HHq$+Xx^MbĠZJ쩘wJUݪxtH(V٣fc$(L(@ @ +DFF ǂL~.9'ٞ_52bq!H]k _v^X>H]ܣ.\VshK/@ju-\Z2}~/ՓeZL畕.œ"Jr.^. |c-m)SHBۗ52_Q<޷ʷ)zob#9N+M+ZJ)WPo;ey:b Cy @ @ -E@r.;qa5_ ;c9|xppo%)#9[N~! 3fB o/(Ul'yXUE!yH]|bw.@mCy{~Wn(W5L[bW8-w5e;[vTDOΤΦӗ&K&g]дT,ltH.W59D @ @ FK!9""4F>x;->"ѕY"=muy__k/̹݇4;uaþchL׳omu,-F5uxb3z^fÉwU\ &cޛZ&g}BW<8v;O_cz+?@ @ @ bR%}yr>wӼM2 |ʝ%vB#).q1妯ɒ뺨̬ 93$g(P\"DZ-iB"C0%À/  ` AÆ! ʒ)$4%R9)p.ٺ*|νq^F%k˪nč7>/ūL~^Ebˆʇɽ|  d~ޠAڿ"?FCs\\,.n9N+LYwOoT6V`{.Ubamb/;Xgp&.GհW/C 9mkrj>(C#4Gx+]i IDATZBpMgg9[ǘ2tx}?^^yiy|W?Sec~Ae U/Æc27qX#`0F#;YıMA"+vȬf?7Hp%, t[qy~ROK^\~vR&o^-+z栨hmCЇT ҃Usy}G(nI1Gocc@w?1>s4O#Lط΢mPݦpIgV6A9sчÑY'(me䟔K?+cKWK +llSZOc9s0F#`0F`ws+\_%ǬMƁ$822/"D UDIvOE#VҖ.]t _(EǶxcy^2N,b~ò $sd\wIԉ׀$؜XW9~b>LgۄÖm!u4:N?dO>QO+o{|DgG>V뜞VǛC]#`0F#pZ|nȁ-"I;X޽w=8LX$ d]@FXa~l3]ws װYil,_z7:[@x~ |@~>Vqs}ˈ# Xf#Lط(:G`wLT7Acޑg[-AXGKdQ+oz}e#Nm@pK}7E2?|򗬷&!Su啵F:h4 R۵ XW\l'9V[#bOyѲl(2G%T`~3ȏ?.]_\(Y-F'Ai`xQG:NBgÓ#:{) aK͗r=#xdnIWx`#`0F##]Z^EEWc09r .Rrq ނ3T>Z(ڡ Mh#A&ma|ʜs_}R=Fx1c:mz>B{)I9@@T=Dp<Cᩑx3sJj@^sGPUQ!O -o 9NX~q@?xc;i0F#`Њo[uŞq r r1C3f:Uqۋ8J߶o{ܾuo>X>c>+y0o]8(/@NƯ>?hlu㯅3yPNά8^NF>Í~ eX; gJo3 ]/Uʃb<̭/?d>E%Qv"Ĩ|= w}=6keϋj?aלr/3d/T_m p>8f.R솜Mګs.4/@U,J8bA Nj9o&'oFY[] @qpXɿraByRS>K<}_7nG2[d aD#7t'kF0F#`0D`3/mP,0=kd2@b)jEOTr';.k\{x谎EPp%|,*j|K(Dq&_Yf<'ɞƟp D[CáIc rB3&ѿry9V;> 'ʉ*_ꗟ}ߣ?],¿Doj}[{=<@11SՌeyLv^fb(#`0F#cS**fG:LKecKDYܒSP?6|b[h&da|J"/}6y8>/ͭepl;c'>BV?GJ5r Az43!\\h^7gAA7|$´/@4O: k#&X@1VRm։ۭ~~&-i:>Woҿ8K}z]vۏ3/(?b=]mO㧣k-~Gx#`0F#'z1v??ԨF˱@@2bKapfR~7yi,`(Q#`0F#`ĕ3X}#0+"cOb6z*!Yve+iAk={nIZŊ}*Sl"퉅Z=s.47mj~;5q<N|H'Hg0Y+c=p}|ٛP^}l_;.aVFNx@?cx0F#`)J]+Wl;""TT ]eaim_"3 T~իݥzqi8@m%Ye0ġ4fggmNDlq뎯Gv:L' | %Nj9ք :Ls v>>]xzG R?L$3QeS+[>~Ls?ӹ8ɲw/#`0F" ^E)ylSxTGDЌHENc;vw~}[5wklKR9ی8o]ғܹ!=:ڿBp՞s+ƶӲivqzZ}vG0b=CfeZ/ń'.,N -LcOu.s<k߻uq#װZ=Bl? 'V2'9hn4WQ7#`0F#`RAqWinU;Wy}[.@ -86$K{oÉ/}nb<"r&Oǹ0h9JpͳxI0[w~@zs|oJ>,rNVWDa~hϖZYtF#`0FXp$ĥry| &!Yc%S tb˺/=?D'EԏgzkT [\i%!>fn Nط4 Yp<_Nv;Y+Q/OסW9wC/?SUr+IL'owO%#`0F#ȥĭȵt=z *gZH|$Qڅeɑe_-X͈{?mh>$1ձi){ L~fɛCr%ʲVI?Z(KRYFσNa؎Ϻ͋gs^.||Ͼso~'8ܦ-[{ASt蘷ۏJo,.t#q<`0F#` h/G}kll`)c*̫֨LuϞw\hwc)w+QUؖʞjяh? /-"$|}d4ԉ=n8^3Ε.xί|x׸G{_xRq*$o=|@7L=BhLkһwYuoF#`0Frngo%V?p&ADuW٥b<n篯g_uvWO~;k7Яݺ^6}|ap8 +#`0F#}($.b|'?s=&2}4'~ԠA!X|EFJm|^,[l+-nHyc[{&awDc/㓃΅=e;WT} Yq<:gK}܋NY_yLYBxן?S=?eGbN ]#,\[g%_XO}>p ?wv#`0F#pwbqR%$o|^ f`+Iʃt! mNX>8a(>Y?{c}vP;r0΄EOh#s<!CߑL[*ta^k$9ƧJ,9'!6A䓕>&f ¾Ow'_៨Q:Da{s2Xhk$:0ub/P4Yq:nL ҷ#VY;nv|:>'2kF%,߯>' Gܵ됫0H(h$*XxZ Ev b;31g_ƙ]oÚf@m g@ Cs>!)s#y[ӭ>N?{N|o5{xoч]zlrlya E}Eh:6rHaCV9mQ#y>לĸ8fΔwP};xC1~3Cu'C:Iu471{P}L' ktbQ;޸h8t@L(ǻ$M +v97EvF#`0F# nŁ@g5('_q$&JރT>$8uM(>{2rR2/rg?,gGHSM] szɳ*$V8voN5vzDPM\yDIDATDc"qNDNrN 3CnOiun懓=eZ7F#`0F`gs}j9P)yYp,ZvrZ=g]s2Rvy(?N9^[Vßy{tHC%c ΤJvt? ^(c?<r:޸/8m0F#`h=O;?(~$\$@w"AʙO}.H*/Vk*?f3tD0$Z'Ƽy;N5Vv|vÑg; vF#`0F4! E~Kĵ3W׮*|\zxy8.9H#VX]I Q21~ڗy@!廁ݛH=qoxЉ};8;^>J;9Iq7F#`0F`WE쵚e]?ō 6VתtZf=jF'ϕIb%Jkh{1}_O G0Ke`')/ɽC;q#!@v|ӂeh~8݅0F#`8UgMXZ_^Z(yjfc+9YhrR\mLm.R:3zB<[;Y>ۅؑj~j=:p$^U=8qw<0F#`0G@rciUY~aa\:?_.mAPI5*U&yQ`XqG~[ ̴M,E-Dx;2bZGPxIjO+#`0F#p*`[E%2*B++eiyzh>.( P(,ڹM?uV?< v$ŀb.jԫpqc(‘{@vtxG#`0Fĭ$xTT?|yu6WZMR Or8۠E>H;#p2 "Qy,C$.j0pB!Yp(A cƯ] BV'ml/Z~T>%#@S9z\kkkeuu5(bYYkc:~9.ֵO_H8"jE eLQ*c~`4!~dcc\Y^Vʣ|z@"ǣO0F#`0'߈cgcgϭ}f\_% ~: .D8KTmBF'b%?.U.r; C{AX1"A7H1FۛQe%yfTO@y:TG Êd~q}r.r;?_A|=+.F곝|8m&=n˧F'ݭ0F#`8f+VIy]Vgʷ^0vA/Vv]`4AVڙpqHwwO!Ŀ2n~fFv}R} ]e$6Ğ8NK#`0F#p'$Y|+|Aͭ| l$_JU$}3io`Y:r&W/-}3O(3Ͳw>^қ>ЊƔags #i;w؎0F#`iDXg$g7'Xn`{|h2V&-'Sgی⪟(B.,YJyy֏E̥'y'}0 : Y+gŹW]{hny\Zgl[K2(L{!'ǨjxIOӻo#`0F#pj 8|מz\pAk8 IGDVZ"d\1Wl}{~ZR/BhUmGvqd=|;bwF#`0FT!r, \g+VR>rVBRd_%C5򕐫q1yY'~uf }1[^axl%匟_.?t= >YVAQ6̕wYW #ʙU\(ozhXr VEIEE[y} b/cx$$8#`0FC`;|{I-+gm/w0E!zUKo"CK2C=Y$~.ja\F ߎ'.;gl0F#`038MjxD'_Y\ś$jJg{{m zYie&I8s×5W6ޏ'aoJK$^qƙp=љZgkQ7#`0F#`j=1-Bnla%F\_յRV:0Tg_ ߏ >,I7*.lsKNr^$ۥɗD% [.wݑW;^xCK#`0F#`f IDy|KymǡtLIRjcгO2vLr6).|']mhANJ9$U.ݓx-v#`0F#0{LIXL+θș!IR\i;II_mr8WOkQi'MN0΍OmYW;${[ ''p ,H2N'CICF#`0FFYVD|+O-Su8x\ylcP ǔwK?䯗TW64ِ"rׅqez931L]XKAJa@# WڥTYY׹eܔ,MwEsȈzx2lFtoe օT+a.~z 5BO% ;RmcqKbnSرthj$<=JN3sCpJScӈfKWL19.8O;'EI.."[c㺑]u@ V [íHCiXKM81N.͟[6bWw_r#/6mLzov!(m\^gQ0dCI+v{ B7%}  ZҽҳҧgffG?p* #y5:91' -V;P$I,ȩD 6pŦ]S {f[Q'u$!%vdvΩ;~ " K#-[ "?;<8ة1|E2t@4<~?ڡc"XDpq`|&"_ʟ۷e6tiHHnpd(:6x!d-;>_xM7…} t+K} lf/D.p0c?K;:ʅ̈U",` @?CBqtG֌Uӑ+kvҳ;<,F-˥i򫙃h,ِv} ^ѧ@ V̀d``?>>r`"bئNHLbʇ`@*L 9q s2bIG黯>6!u%L8h&l@AXO@[hҹ9.F}Oڔfm}):qV e8W2"ٟ pc f²U$l4Jp{Ȇ†҈qM7$"*n{e3pdvS|ׅ֓]N 2ŭ$ړ(>5~od:6m>Lݶr\[m7Ynd/>ޙl  !.!0@ pXέgΦXI F. sv>wFZl aSZ~&wAbl' ,جȈr|M-!lhɊTd#>>L  M:r6CO0qt^ ޓA!8 6語+tA j(_%ϟITǗY] _ή$m'_r*2C3phcg8lH"4!M@`5,kazΝJϤ߿9hoƜ-@4,ȆчE=@XsT_ĕiq nV9V ~'fW{2q}t*]m4MLLtf9J¡=L9}dańg!zPz Ǹh$Jg4^d2+XS e2M=#O=2M=_{DXBOjC7 Kx=nK** ӟ$!/ +1^:iF㯞I-43T8ѰH3+P,Ta>/i(8afaGzsVVmqYrŒplJ{ݣ²i{BdG?yn1l>hx>Lu5B~6'Ϊ+C-*!q$_ŽS}ԳU=lH`eXy%B!@ pzЌfЯC4X:y\ j)hh5xzpU Sў1oBKFsU`+XI2fi9Թ|tf/;T.zzVsK`S'k1{ AP^t᮱|4ұ-u|6p9_Wz lkc&ž},`f`W p- ^ WdZ+B;uv=_hg Zoѹһ^6IsI3Ǥ? Yfʄ0TK9iFL'ڿ,G y[pO p:}Wd:NFhWX\t!}zFuD@&ȍtHCcF4,L&r>gg6,ĉdd!wI*/o~?ch G 4Dz"^@H7dY_t!t9F[v"Er0rh`dPJ>'lůwOpcD5 _/ ڟg)l;o:gfhoȆ _t!@`)kȆ6cփM-^⿚ sBUM{5aϗNF(;&U&?C7`%"ฒL_&CхѕM  hغ֬f6> s`OWFP9ngaw ^|^)Weks~WnurGoNvpVŎ!`!^]c4-h̰u{;JxnӸnahSTQь'O.`9r+c n86>w 9Ɛ9P:";֓ ZB~F_@`}]ܒl<z:&eCwmo=fT{f^>U\(<ӡLRҋUNWӔq渋Yā96KO~ lEN8ȼN[;B/Yf#  ;E@6:WzW wظ}DiY.ȭ 4nH&ʿU\5h;?oׅȀf6 ΃ \ni57~`EQe/XOz5'm;$23Ыs֛ZXY\[=RPLn7&Og\7՚SOM$0 sTzF*_$*:#AM7x" ytyf#/T Pct#"Bxr28ѹ2}13;>آ\wdj t}f F~0z HbhH>9}zK'ypV>)UY/j$ BΓь ~{t=-#nӶll Vk 4L8⸅rijUGC M\Ymзz~oQTc!:G eJ!J@E4$jky#A.0fC-zl,NY(p`3V (lؤ{a kzx/A:LV6XF<}~%a7U~/jKUYN«\+WN=jsﴥh?m𸓋;mudC D`XvsJB$4. rc袑Si-vwVWܢ̓ %l@pzȩtT5\X߉[6`h:Cq[ҽHyJw-?zT}(269^qdd >]g.iQma/M?Vt/iwnhsʦm6,+r_}dΗlOoygո`N㻏>s&wp:a"f˵٫~%[*GS}&c 86WR:oB/a1o|Y&(˼_j"*-Y# Q+5dV(\U(w`fGr2#KEZTD#)w\]蘓S3mi릑nݓ]O߹H:=ɰ@͛N{VO_ tsispM^yh#ªopp4y&GG/4bgg~x!n>0`XW-R?ush?~pQ{0B a@`1ѓ͠ vbJ! ϭ 7 $uk\Eq9M'|i-zXI/?Iw}H:~TNƊt/,7KoJ?mפ7^-?M͏ mh35*(U}kE<6jcsnr+F ` j]um/F;>g-3m>©. DhiL1BOw˸9=i~vp@褳NZaT͖9yK͟zݾ-_co19/|/?43u2)qI6g_=?y_zEo9{}r~mmedqUm\7,ܝZ8s11x)s4lĨ--v8JX:aIICiΉDS=IklEwSϥY;Ou|OpԶnca .RF"@!SqgSϦϤϥ)f6m#&Գ3WK43}˯H?WϦ3'R2\__k\~~h{Fъ+"^B'A@_tnIF:Ǐ9o|t4`>n9;,("j]*s)Wz,%L z# !@'qw'tm-8ţ:n+ȟC9^'2LϦM8 kmpK[4ygؖ~#O}qz}iq;o%ҋPhRύ} Ny#Nup GmrUڻY~Xo)J4shbcN8,UnNŅD@ X :W)B^.&[I* |(}V|=ps;vMnHzg28e:fY^bl4ewۺKֱ;2oHo|.'vfجni}goG͊[N|E2u^dp;DKZI6o g7C^OSi{q{b#}n![+Dsy&t%Sإ[*[SOY~@ 芀t.3oaSGpp ˳y{9Urk>d$gl?~Ҽ-̝>K&<1:%߲+mڞl&ct|[3cvqꓳCF.̼5ק9KSrLor{ ~<[,hl~1 ZM g`D̲1aDžY`✵N p]J!V*+{.bmazoMK;>Ci6*ޟΛ_tGkm8{xMIjw͏czYEp@?!P^36\.C~C.<Ju| S#Q9oη"#nj$:Ì8̈-d2ik4]f>ɣk16~߯}5̜0Rxp8LPݴxWgjpt-33 q1h;ZcɏQz s 0ePŹ s IDATwYJ0J򫼦zU~~w*#O07fg-& r/r{6~Y]h!9'!L #~'G١trn=B IӞhO+_D4HU 3v = 4pXgg3'eg9-Mrpݘ [i<יn+Rjm>+3#㓾Œ0̰:FF%% -Nn36¾\ں{?{ zve,a?ݖud0%A蛄AlhYm ö3{{ȘǾ|Ҩ]&)#6iJkߗY!pq5B< H뺤qCH4TK qaȘàD0C1{(ʯ[ՌȘ%1ohW#U[Kh `N%m^B396pSB]&&ϜN um(C9ϾYԮӅݫ~]PJ[ zdoGDA-;Ulxa.Ca܌LBl\wŎ_叾d{7z oF@@:5T ήg f5k@Vt ~_A~o围P0S~ f3`a^aü#+`"x-ۖˢ@ bo)ұ>tW`I0K.u @WʽOy(/QC,,Iou<-b&{L6 ZT2(ܪg7t8#|J?Ow?{wDTz\:ā9sOZK6@^O/E/H/z?6vYo1þgG0-6{D`vdJm5}MxsY63bDʝx%Λ9+`q`;uAm6s^%dCxMzʛm]S_MkF)HJ }q.t^N1_iᏟ6K5RF13ei!{wxڽckڽm?.:Kјy/5/U`)ea)wa՟d/ rC>;lhQs/7! =L5“v@(/SV~ן|Kui{4P.(?iwfijǙ[oܖnja<;Gl/K?322rqNlcs lhz;[YZz, SΉ1qpIHI oQE?5e;ӖE3?RK^pIzٵǸxÄ́ mPi+b}_J~> wqbֲPڰ@? ƯelV]'GH',xSY7pӲ`1[v3}G׽pGo1ݛΜ9]E|mhԘ({+iy}%{UD3džS{I !fV [ωHc4՗sTtR1-*] B_ k4l B4Wvj]wܒPTrެ=o hP({BsYFdkc@8In3xWi /UYvfi{չkDBw23̗ZYfF^27:=lv^klД4crOEnfӌHZ r!W)kSp.0:7铟lBp6^w20L wfa],7^)䪼1'~/g4}cv6xn{xù -!mt솥L8g5ڿEsN/?@  `:ɻt f:sY͆H/ulZ)JzhmqF O`-?Im^3Ӷ\/M?]7oطClP,tʧl;3oOI|`=s7мeXl{p)` 7Su]t<o  e0g6:r@`[l# ] .i;'?۸?wUⲽz,;=O:6x1nf'8ɒ9cTNLƚgNcSϥ_>q]{Q~/Gzm?o9\}E+Zi{o>]yҖ1#bVocjx#]߲;+y8=qӳFy^ }e5ۯ]v9Ҁ<<9UznZI6RLmBn7 !9{#(F#+~n+%2_#ѧ-uGߜC 99w'.Rת40˶ΣUtp jڷCt3)BN_iSr[;<6~x׿|o_|{|蝪6xiiItU[/I+<&}OhU6MٯvJIQ>Fzës$ΣGUdC`I"v[> Y!xδ6B>3mږƶN[qsx|.[8Kȫm/ܻgEf`Yt_Y?@ p,6{nϤnnA_zZu\OՀlfNede@η]uWLܐos/S恓}M6/TČ^GmFztL~oe5om^xfLcĊsR#`ZI6f[A;|t䯻>wj:էlO;vj]7|Y&~1 b;>@ fX{s_q2Qtio3Eh!9"rYK˟;]'ۙG4cz7>t[uWNޞoLNYWcC.B1߳a-cs8"*Fw &/ٹyMM3#Wf5ژp&&y`2#s?Ogس'zܾv8Sz!v ,,zHnl {GiM '}fY]/̀l%neZ%Ӑ<ݜ t@Z׭; >y'R8xY to5]놼 =18%/XN.e~ueUyڕ3Fypcd?# }%|r(2  ٤45o b3E$;BAR ͈4 ҉K4Ћ\j!qC6n;>p5Ye>Z9w4ZLN*g`r_} ˱6p@2 ?6lK*3S160KnC,^S_3 ԗBoMnc N~&n(T~1#%px5U$S]Li 5x 7I msaMFWç*!2Q ˆl$sYBP]8 ~U&~{KO:`[=]/z\ =0 pc6t.eۦS9+<\Tʨ3P$dНJcZm\#[ȸݸ@̎3;l3ܰaN*l7KгC,R4cZ뺳!{(VXIϦ+vdyX$۲ڴllQஷql7!C]d5R ! &4Rw.t&iiԖ`#k>d@}+8/~1ppAzÉ>䋇zAs7]*tc!ӛnB]MJYfk&ɱ [.3jf7rMml9^efD30m+?HH̢ ZSnsՎՇJI4軧m}bZI6X"%SkR('Lأ fg6%-H#[@*1oi= A@I^+h] 0@ PC`0A[9>฽b؞}fIJϖwMO UVAnl׃ne @GTU/۵KkhsBvPgĹ?L*eeJg-Ku *vP4·\3kn6s) km*%YgD Dv4?e<͖!p+ │(OVyTq02Lj3% UIB~0blPɓ-Hgu"YY_ yO Hǒ)ϝA@4v&o릑Uġ{MK0Ycdz@J,o/w kLKOyᠭoqmW"=Oޕ?^p o}2&m\ft>A[ -5Ӂf7z> ,&&&..4bP؟s|.0]ry\bJw]}kE<  t/zwt^eǛMc#YkpȖﳶ6L0*Z| FeψX+Kz`@ZNɼ]8˭_WNz:~y̰t 7x)B[ֺ~ZNE}2lw}ㆧvǠ{pzŕ6Z@J A:LDR&'@nn<,r ʯ Jwr`J;Yvj&cvȿqa %7}`ZO6Rf6S/Dh^BҋgT'*h{_T2ҹ4{ѻp+}FC !pk +\yl_nP37+R~Z-y g:I)JG*_h3qu;Qۭ%PE8S;bm|B+Pt}B2? W~8Eޔh|1@ 艀owWIwa5HM~@yH3YEnCV̬4q%wp7_ԟ:suu^ԟ~[M6 q)B+Q}3uu:< MBΤMٳɓ2ia uk^dg{z$/3Ғ;Ϩ~/H)'} /;!m2WN$~a "^ ad?&[G}u]E^X,ȑ#_~_Ѽ@`^nD8SoyLDLnfcuы< y&7?w%>p~^b*{_5eDþR,h}w3u<$U'G|-gf;a}qNpd*c+m%^,_?ON0K\v x ^.Rǘ}=P:|>av 7i޽~ѭWNOa"%k !`6ÉG7pU(=i&ֲc Bwr*]-eioc? %r;N'v|dH _tЃݻ_vO;`?G@ ,Х |dpdqf4 = ڗh;p IDATɳ"" -]騅=E'(& 9_'iK~{] qC VtzC]O4h( tMWt8'#!>y̯ꪴo>1cWH=X:sLy}-K>lz;{_44aq `!uX@5)_3}.,>φXlet-Oɫ҉V])پסY{s|~3~4-],0(8qqпNt[ӳk]κjEO5׭((WY.RZT|=eBdrslOΦ]|:lu] ;Y`@C$w`Y G!A8PP..̗["O `y€T\r%i͉p#7=t,yfo66Έ7o8'0<nsP!lS~nhYiox%f6̶wmJ?tb+=}ӷdK;>_gζ=ʋΝ/ c'K" $"Q7Jk٫f8˟nJmx& ߔ-bw^`- ;ʁ-uX=E{K݅tL4m~$k:{-|=hhXjbt}kl#>`Cuv&ַWT4<XLt)/doS闢{wMm?,g6rms3a6j@dr=?gV^*H&o6T$%ROvwihhr2aBo/ބ#>36=%`})a@!5LOIB2iWv=8vb:?OC{Иo5X^17ؐ CL0 y<^G/#?7WX3_EFVʷ-5Ϧ[oEߝhxݔ5f` <8\cg;o@ X=XP۶m󙌥 .~g_ퟫ835>qhQOg96B4סMbAKdBjCD%X e~ROЎGs6gwb&mȏdԉ.̌O߾&@B|sS+zf/kk$'Gب-L"%,c^)u=m^OD:qȄYvb C`aWx2@2OD'D 4f{7d`k|%Pi ' eEmC3lᮋs@>`$|=J2ʖҽ`r@2J/GNDmfIJJc򰯺 wcr"hC%}\:/ rai)طvohdlX yOK[#?Ʀ5$ ȡ ?3Z H3Kߖ!!,WM_K C+80X1ei1W@',NBɃ_U)R!D:5Bo~Tzus" rVu;jp~bfCCBWΫ6 =wAl ]*K+v s%zǏ{$3 mJK]9п:D8l/CbyΧ%_9SG!x}İ0P oYa4 MZOO\v`qC[;n{l2q,GӲʠY^nadHJ;> E̺.򯧰:uspHjNg@B yy(_\@$>37Gƌt,pX1r` $HxS.a90e*FʣQ{MWOo}l|W(I?uPv -_ $7^8KPX)wl=0~ DqI5/`[/K'Q+9yh,##i?d0tAE4L,F0[Clq"#V0$;}_feGDCCz7`lp$l[G}k| ŭy@:%NzP?4ӌN>~j&6ӱ$=i_B:^t>5$_nϜc}T9^w6|Lڶ9/3u!Jֹ@fªl蜅gf=(Bϴ1Oo퐷]# 3 33f=g2zMᐭ? Kr乹5#_r,=|KAݔ] B (Z"8{޽5ΤKwHEC%~lp낈_Gs7KPaAA k/G?Ⱥt/C:t7_D<ϞOJˎgOB6l3C6b<-m!Ǚr2rqY~lkPgt/r!$rS{ƿ̆ V] z7G!ž V_vO@2xlC0 ոҿ% ~ ;qf>=}|f<gO ۇ߆YY1768nбb̶Χ퓐9mO[7 Cy{7?FC6R~; C6T}FbUx YRai|Ltf2JOHX&@8"u[i|u+tv!BAMUipce;6{Ñ ` `-A'Nn uVo:Ҕ)-m 8ar7يWލ*bx3m].e!f272 A3҅M6aҽ[au[y6V$FɖfGqʯ2KƿQ͆%:&[+/w7[y6V#am%l(NUfip^~M 6|mA #zM?$ ޕNl uHiK~0.Lz+ݔ؉Y<nP`CMX#}BfiE!E` t  kI2xw $Czq]/ne:Aaʍ]w+L6z*Ca/ g6. lBƮ&[tr/S0__zćI>= @KVq.t$ #r`/,#tgWYakKtPC٨#R{ oW^aE㑻KwSna0qnt 2 OGѐ Qoҥh WX߻KR-[/[a SHe+ V&&wF~e7anY}JZٺ՞y 2\H%%ɀ2/*9_^ :UW@(( EFqC s\OpUs /̦dgu^oHs-?KG ұ꙲pw Myp^LkslV|6)RK)ӈd07HvЏ.|q1Zw{4G`{MPr-ݫU~ʁXh&N2LeJ&} IQs͍7oL)/n sI,/`vY oLz/ڄ@6h˺"ˆ>;TяߣhP즼K k"MaK-m `0!9EN=.m;[ў d-g" ,@<0 -fk| D闻n7Y]{SzJ[/\md@4HoS+7S<*˦6 jcOx[~[%IXJ:MY[e~[/Of2of0^g%7l) .-JiBƥ TZ&wi˭ҒW4n=l`K}HF|Qx=Hm_3 B4>oӷ,4 8t_aM>K_R/N$$O{4J'̥Wz<2 εѨJ mZ+@`.7C6"ڷ`iWZgi-" #ea:fwޙ>O|3pBs?sGM|+?i߾}N.H/QU+2~ܼM3ħǰ@ f6c cK+c=&[at ?/ſHoy[wܑ^2:qP^/~ _Bt|wWڥV $2޳LF !v paٸ0"F-0Q(]A^>v77˸z!N%)KU:{٤>Ur~0WÆdp 2Fa^A6V(e#]='NpXZYw.0k[6R~ׄr/+,đ hz/C:+l{*b$C,xU} A6 d}l0İ94 ؛ cyߏ/}iI[Eү:M\< /uK۴k׮dKn*{960\"AY"-6DSѧ@`=n721=C~͝jP׾ Wdae88~ߝկkr=z_}ؐ'6 KA1@l\~;hD ͡ hr\臹M'>~0N۽%(eg_Q[(OO/C`&wiexbٜ'Oz2ʂd\^y{7AF ۺ#@~6#bJvٹ]iyt㨘_(|W)Bmr橧r,TUI[OCX7 `nnEx pqqq}|M)]ԃS9x~~fYʥ QhV,5 dHmkIp-mH` ?S w \|l\|@RV>@TK]/Opˁ[ae(dҭ♁oחVN1jo=le&#Hȅ ډ@vh#S+<^|ɔܥ-7q~[$ܥ6V7M~[N[&٤͞ ,LH ڃ@hBoo01Hj즁e^8%re҉CinAjlʨWqw#/yT6՞ /O +is @_vG @!HyTK!` $ ̄h&7 ]4n4m)g*6MOy|0`R V#3>=ѸX`Xu]$ :7ɟLy{<=ytGekih+. b/ؘ|a@=:њ@O\Ja擟^Dí^~[m]v٢7V ;ڋ@lD68,!<䓾\qt .[i. AXV:)W@]FG&GD٧#4 "^_-!+I50/݊_K[YMf//d4@{s-۠Q(0{{7)0^ 1M6ֶo_D0Gv XFi9@9ʭU~2x/ ҖMSF;yƫ_j偀zU~lԿhK dbf#$!3kmXoUW]o?V_؇hS tG Fwl"&h"M~?}S광x ֝ʡvm{D*q2FX A6)XH2+m/MegFߞ/z37z/@IZޯ@Cal"ec=vˮ4ce^-7K}M2epw+}؁@ bf="Z@9^vUfV2@=@ X@  ZےtH^[F٨M$d}  xVO@}Ы3a Mqm kjgѪzXߦE[@> @!p뭷[nYvfqG\0 J_<|"DFm]lX.v6ҟ=55}޴iSMҍ?L XFiϹ]A)%g쟥~=^3aD#dc! #A׀+n5'}?~xںu7$#8Zul  B4ta՚q)Wl*W\S C a5@9n0o}aϗ>@ >Xܣ@4 q<e4;o}E/Z'YW@"dc Oktj55sz缫uQٳidd$۷ϻQ'Ivm 6*A66ꙏ~^07ߜtHXtퟘHd%/0@ *ltDctU܄wϩ+?O<+Cx;ډ@vhU p"lH2~m1e[m,Ky)  5Wr&Luݭke*Ԯ~o7O$c"dcuUEd{z(zmejVPX" _EMz/ˏRFar7QqljF"}3xi%\vGβp@; YD6pˁL2LM~. "L[i^L|?)W7`XN9~5_~yb(L m8O@l8p 9s;ҕW^5]XDh/M镶n5y`p2wakĄ)})`^{]~Hd~^>ѽr˃W=>|8=s<::K+۷o/;Z@<ڒ$ >bdN6mڴ(= )?!#" Aypի0i=ܓJ4!|m_-/=c%2}@`}?jlғ1^d seF2;LS'([n&w{%()u`d+|)YU/mҊVFFFʤuB :KA@$駟QwO h.F˪nUlcXNqMyd:uqX@0.,YVeu@ pQ.2Q| 8Yn`V췐ag5\v95Ⱦ'O{]x)e|+?O}鮻J׾Rqv("x{ِ fva-_`/L 1>G@#=`0@dl޼g2J32ˁ_MnJ?}fep!JKox|voa`DB2LK6L1~0@ X[@DJ !;lt3J:it+nˬCv~aߌJ8k_I(ҭ&?vV4Ku,c׮]Yjy.V@UA R@2V:rhܲn~r/*KaSں[id+]7Wj"0^+1qai[i]/E ƹDH pd0SS1=z!PUVOx&l/ y݈Fz~VK+l"-gV(/6[ 4@#GD2T`&c5H./]閮L/wIJrxepe!NXZqYq-u lG_ Hꍗ4jHS4꫇/layp(r.Xk7Ɨy1M^ rpgԕuӂ[Olºm2tńst|9CI.."-lП;[D/dp1w;#XZ_VQ|ui(m^Ss'3É e u-z1+ȯr#/6mLzov!(m\^gQ0dCI+v{ B|b&H(%A2\Kk'ǠE4K_N!=-}*kut,̸\VF] 08A60p_&9ȩa;_WlK5ްg&]mS,B8vIBJ!]gCR9|EIUQh KJns?絟@ .~u f28@Bl",p00)u-}(t-ch?>>r`"޹yv\3VZYe?cRTap@&! T%U! @QEHR@Āc6`KVcݝ|vgvGҽ鞹Ogv-W+aΟ&,V5ܼ߭B1ot$,Rq18 ~i|rz  hmW:hlolTߝBJFdQM@8C2⩘Uf\WM=6 ,9 @?Gu!/D!c{ 0+ax Vb'c+f&''Ҕ5]7/s3ʣm{acv;`J[]>7iYOv )O\Gч6:^Qsk{lR2FU*?}r"c4vYw]n!~ÀfY08;@4ŀp;n隰uҢW-l 8rLzu8X /e~q3c6Л"Gy0X@Q2v7 MI801cr-U3J `rVS ?7ﯮH  _&c wZu.IN|V(z8MƊܸx|t8QO66` z +Zx`_ 1l5ڟSZ[7`eArlx+!ZnV30.œ?9^a]Gh5,^aшqoxBɩv#БMWO`r\] / pبB?B'+sV0x X͸p-Z9{7vUY:wh d`Jo=4>vl>raZc l>7'@60 <|J0oVm lHUo{d%훛=t&`% !w_ݽ. *&c$(+@O{o*d_ yV:g )e4oeSGf` xJ/M0g1NFŗD0^IWD;=0?`'C gyr68"n;ɝgUfpV81+بBsz_Ԓ2ʃJ]y£NT@(=ҷԅ;t.sMwK<ӭ/vә s? ,d#PcW} nl=i}+Lt0Azz(j[GrP *j =OBZd`rB_vNq^0Zy)o8JhP[K?}Rcm牶s+C֤Hzm)'qWI8thU -بBAQN ~$MoQA8R΁^x_e>l0Qfdhۤ_xz-3qg2-X:a %,jĤ mSiǗqе +Ӵ˸7[(_`؄Ϥ#wN\1jKŋlT7D( Q2(P@Ƹ|YvNp9I/St]MҙV0TǺ}07~'0%̿iTtFN>fa#=I^4m C\ʁ`ˑ-,,x" [+;nyv +|az.o0b!ZF,6dKL9fvjAqm)_n<8ln+ ݛyO/F . =D&`WS9P9=6863N|c'Ӏ@2㧖O >W=%r͸/v ay{8)hy(Lv腖 zW,,Cݙt80pV8<sϭW`L*h. = =1*菲56ЏxnƗV4]L KzWƩ3f>=0r 0| (olP'ym>+ѫSucmwQ7l'oXd:-gӁs GĀIBolT7%"I SϗG9=1 Cv ʁʁos cҷԮ 4>ъ[ScOtlFqV̇tV'b+&aiQ03,a K{nX JW981ڥZWJaHߕ7(Y鍦/UnoPf ]OŲڅ7a5Wbbfν:2GE΂Nk庝$9oO8jYq2 @^#/@*ŵ^9pi`|Ր~Q?y9x/F[~X21giMX A9 W:(鋬3 9n>9ЯQjZOdIz_cmSp61鼻-~ޕ KqlU/rнBe ^M@9r?xd\> |]۾y ُcWXә2\Wk<<`xi{7w 6R҆c t끅t}mxZ=h rz [9JF]޵LH|W ߰\~m4I hlƯ~y>-عTK]m5<! l_aO,:mv8l0ܵ>&_O?%r>_eGnݿwlغ_ڠ 8T%C@˴dt_.Ån0>9OŃ2ɔzUlpv%}6;&x`AyEޡ˸F\2M,ppޘ;xdot 8`f6 ꬣ(b(6hߟ;,\ rرfn囻שzBO5'Xa^HL)x"a{z}`'ʁʁajY{/xX #'L ȬrL(%kQ@hNq> ]QXMdoϞF4N8o+EJ#n;Bk46-txs&R DIb: N #SK@ݞYl'*2D<Ҝ?睵eum##3JzPyttl>1ULШB *|· =|G:?7TT!a[C2l:^Oyf mw]`n) Y=4@0)iT4~ӳk9<XzWXU`C ,+!QڙAgE!W 5QᮦrrrӀ?:ʪ@XhtRp(,m>A]v[?|>lo/Y[|%ӫ灼v7 }GbV@'8EǢsۆUW;y;鑰!+BlPp?7zS82>Ps͐΂ %fb`耏?53HNaxfRn\TW@8 =p^gy ~=vE$(J~hfG:W6vA|Up8K$؀l lt:`i5^%tU2()֠ߍBlUS9P9p.xG*;g𳅊9vf"-(}+-`a);-`Wл^*#Mt6=ə wjoOu)}V?1Z֏{/!Q2S퀒]ea7~X'.&q}4v"ۿ]N}@DjH#% GZ/@ۦ*NjQA3kEpFpn]j$j**Ʋ~e] V78k_|v2[)P,MKV]g:!'&t|aClŷg)qh1sFY7zz.ϥ'ڑ."H)ӛ{"ȅK˯Q~naԑ=5?n-W6&9e=+İ 8zzt; fbjt0pDd:uDXGӏz o $ݔlaG~{I--'G{~^U>4NIv^B/Ч~)j6誩se39w5LC^1Wo6TF4ɲ" 3=:)n9$ΒZm7?S)ʿt@U8(Z\܃v`Cb( }p$LU%ծAH`&qF,'_Q+b}%S]"}^S]^\u$&]A9 7/rZ._MݚO~ޞ&9:601Bx[ZBBK\}Le!Uo7[W>smEuTT4`|WwOٰy ]>%D]m{ -vIS=nPU&1J:4OK їu.*?r)K=>r>I`i؀Ix}Gohh18yY܅s,iJ裎(x**:.t/ܗc {݁FcѠ'۱P'rM-Ao ׉ uQG86ъ$mpҼ.HWn~vyVD w; f InISeCm@oԖv QKJyqp FNQ>=y}=lf@sn]/詩kK诿,^EV뇕V9P9g-)Ѭ7PL'4 n.M<$I/xz?[92y Bw=>~)WN\oz$>F1wvfUrr`-лcj(QPRQL<`HkE|S.r-vEzvEot݁wn?sfhgr:LZN/VyGCot^Z-2m >c Wp]$؀qb=nBZ{Kc鱓Nh4[ZKwIx>B/Wrr`3бҹ^?ag҆=ezB &:fo<2* "ALi_!2'oP٩ts+O7OWؓno#g_tzrWm%D:WR1;U hG:qvbϞͫQ~q`7jmL\6g¿7}Ww7K_HNpMڻ=}DghU葎j**vؘҏ6YG!.$-ROptq83w\I郟|0Yx>,Y%4M.{N=o6㕗{:klژɕi_{=sa۩vگO_\u`1T7Ⱥd:6J!I =ldz;H?uJV45c6 **^$'/˜}9@̕L4БI+CLGvj`4`l:`T}oJt/l;{ŎJ̧Ж,+gޭ_{"F]p͍n㠩ܪ>l+̗,&hr3, g~Si} knoϞII4zxddX\46pPІ Vso*Elio}ղ TS9P9Ku&r ?$g8OC/t+^z˜h1kvƆlAOI3s{4gm9t:Οݗo|KWEgo,/^y65_S+ub2O -z[/o_d7N 1N̔GGf݄ޯnO`҄?~:BNpҗΚЯB1TU90v~zqWU',fO ϓ*{>5rW {ʏ2 oC157_J3HLr> <ɽϤOwߔ޳yг VHxS ({qֳS)+ޓ[Qdl)3fy6 8l?xfz$ yNߤG9dj =g.@s䞽BÐea⪭t}LV6^siVG@v o)[dI)ț'O7nөdט6}.GnV\ɤ:**ārYC57 |j!.+s%<<^VVkP{PdfcLNO/h@ :w8svsqy->E;+jΝ2ҵG(ёIsKzumxMO.6V>Rm/>I(;v)(wW¥-j_ \#Sh"Ϳa?iz9ž>։ 峾Vm>Ơ1J_dvAۤa7a(ʁʁ%Ŋ&>K'~uz-)>o8[͝L. (oxX4*?#vlC'r"}W7y}gڢCޤ%?h~\6{BFv0fuQɃn7__]m }d@ N{6_|uCA 2NtY"* _rr`N+-_^ Lڀ *gf$m,sO0[@vPR2Ksj]f0Ia F#zʁʁ&z7tQ--Z簁~RA\z ٤&η}Iy>ǘRE[>x¾odfLe鉧퐨}ے7[Lkk, mI~^)vCY><5Z#uԼ,Bo`F q/shD_Y)ީrm7_.l@_S6 Jzb5UOEnsG9Z=䀞5҄[Wc"EG`7p+LeVSI)nno.Mu O^0L!s=Lڊ_gn !}{ܟlp¶Oh7d!@kuwABERzSfRo#9 L0=*sH,`{[.L:nQ5NoV&&`?!ؠ-9Dj(?(! 9vԁl1][9SeD~; 6ľ. afػsKgx>z0iBY_Y:ix'{_QSQ~K<**-`Aל sp]gdtۡKP'0lVLF,U*B [S"G(77V.)?'X4OYnUϡVS.,_V:}~i]ΫWGܒ}?i˜[lIꔭxgusk_qY;}#C K?@3=o`ccrp[BU^v@s`~}y1ύnc7~,Ml;L {!w?r!*jԏI܀|f`/qJZu}Kz;x潻ul dׄ>D"$/#jөg2L:^g!<Jym}tgz}wṁӽOU)~q⼠*äUTlzJr,xu~)xQ8̶t^msP}b>בn[=!<Ԓ=,s _ B9AIb/^%3V3\g$ li6}~V~]o]ô_BdEIND",PgvKhKeR.?J}R>é3Mb5'ӯ~~꿧c._=+:'Ԡ!q)?8Cg%,zƺL1tiAпG?|aKПKwT*K6QS{W;oq||=?i?>C~5%߳}V*Pby@u\ݭ@c_u`+;k >ckwO/yW _u0pPT7l 3qzEUT8I wy{dK\5a~54{Jm'=Q:!șL{}ؙdCA$q/u/UKqs?yVºb80{ njkqg *&Sܥo*b, h(rJx[҆vLѥfgҝ7J'ſgoHMN oԖ2(4,eTw@pHk+\?09r[9~SLqkܡʶDoy8}΃B˧e_5!vQ Bh>7:zpn2=sÖi`omC!f(r'گ ިM_`7ɭS`cؾBj蓟ҙUٽٻ..!DTXGyt ݰ7R&xuv-&zlkК_X%䬆WfHbBkp=jbol11+&Nƍ"0{\X31M&GoːcQV 7C︦9O?Bl¾yɃ_" }G_k?T#34c.K6ettlq%C&.ef&m){տaHƂ&Drmf+3lpÿaĊe!N`ʰ=~ޙQops  & SDYC:3v5D;._L[oN/˲6P zOtud}H-WΦ|8ӗ_Ho{H`|㈕JV\lGK՟4䯭lʧ/0A.;ibl[4v J1p&0%=6oq..|!VpʾV9P9 a_WxW9y7MkЭ}}YnWu䇽A:.N?#jcuqofBa~̭)yH[?u(@y sɭ~:!fIDЯ:dZirnIG_9Ah.Dϯ*hJzc1Y],Bt^5V~/9Av3Ѯ{iSyur6)  Bʁʁ6rHWͯ Bqɔ2@M`'gt'BDJVme\|mLluodo?l4;Kk''Ykܪf*4M=i.ُM̤sOϤg5ﱏ'E샊ǞYLwQY=#GQL[CiVOʋi?E4xۡզ?/eQNM'F@1Uv՝5;m{$FaNr+Ϥi>}W@@P{tyՈ]c. &vTO@q}S^һGl3iÔ:'EjT*Q^\v@Nplg0:{U̓Gyzf&<7<5·BDe;}rdޔvx ~=Bg ` }|NJ43w0]LZ<™۵x[lQT-_qUl]k.NQHW#[΁ 7wa:T̩t_JdgL>gIDATr(v|uAB5NT[&fb2=Kr?v*:}: rtNDW} ',c(1<>gRO>V_H/K+mS*1e`7X 4xpVh+fbdo71߀}tC^xl[i'I?#]evWV*(wpBX`ƒ})tͫW6@m|M̸jUTгz`vs51ɽ;@ZbLbjl-~0yĩLOC~4^&zEĤkҶ#BRNs7?`V6 ac3%VU蝍V9P90ҹwƕ&]<,9tnbJgH'{7N4ØC72G8$6l;j=m_kްՊ5`´=DX/l3tEup=idr޻MDz Vi.a<:6J9ÍEiOlHL-̤fҟO340\2ЗRݕ 5utt$*^}%nO$<}3p^2|f 'K}Kڰ9WFݙSkYg䟅`X^+zVkb;FQ?tIhn^"ÁAʅپanNZDvʁʁ&/ 2`9襘 Wme|*v5r\'RsǃVLnՃ,=i;nfU#V6qw |Msf$b&2l&6MrcZђ^(1tt0a 6sX%}?> = Nm d~L4pvI۲$n.}۞Bh,l7hqzhseNom-LwE-}A W2)HG+@詶mܪ-j;(Nqyy uR=][%# |p̃i6e)]qz˅Y `N..6W!I׭T<~6^aO6JoxXCzϳy^3|'Rn NQ?t79ymNrx KPx` IQ!1pBh`*VҹT[OL|\p=yҲ? @+?\p1$ 7>p%z,KŒ0jfC9CyBwjB?l~ m%SU`ygggvQy8O|\f.vЊ~7 }p+*RJ^{Tz>9NĨIUə)/ n.2!]m7 0i{&&ɎAw!Q_Jōs[xԪ 4G`C|wgIۂ,78he yWoC9LzZWbVXQ.ho'0OdGD <9H|RYiH36[']^P@/`CsQ]hH }_cg@78ֽ]MzZooI|C'K73 &ڰY 4<8O 8<]%v=FkjI?O©A)p5}[\JV;}|t}2%C(堩BߧUZ9OHbOWO333knI|¾iM'uh<,aq~ ݖA:Y39oBoQ\h-Бylmފ!(`C-.tM#@1@*]bn:X{i};N7)}BUMp@bnؚLB0K'&a{i$I=uly ë(ΠBߖMlpw/^6-C%l wF`ۿ]~8_IaJ$S>Sײc_⹾x/!>䆝}2bniWʠk˿Oֵr Ճ|);LRa2m mCtP>/M.pyE$b^c:@m/O"U x*Po1޽憉hW-}{6JƊ*tUK ʁʁr@wSt>ZRfZ=!9I e)ݤD5Qz\_η~㡔x'>bkHSQ29: ʎBo4i,mZʁp@wlzӕ{7fnvzDlKg3|e"I4GIw:Z\o#MK 1iEcت DB/)v@V9I{-1;;IuK|&mAaJMnMFw28pRW@x<^Ю=u3=,k^`9y:NB }_ew@8 K/+qp,8_ŴIRNorCTn6SKw0vFA vWų{&GK ^҈ϴSA+f:CS> }am@_8 +'ppha嶺}2I5V5x ڏ7,phxVqq3m\0]LrMNҫwCگx}urUS`,1ԱyߍmC226׺}{mm-zzOIKvo@c擏]L?i [ 9HȍL' agNjHO6L/ۮtGI m>Ϡ{/**vhzO-ucO˹tjT`d{iaeۨ&A8D'[VxVlئ/:Q# #4t6^,:Cߖ:W@C etn/}ZB,TS9P9q`;qjoܓY+gŴt:)l w(b&tB&Q?&zρH  {@kG# Gz3Rz[՗Ƿ4.4",io }h?>|JyZF޷.^* /:Rv؀ =_Vrho¶UV}a:}iOu@>ZF+L 0D6=屽%3[/K Kq0v2^ VFT=l*ňAS磱VrG(u`C=G7҇?'-,0Wqpkeq`! wcrGHS!GoON}Coz#}@6Z 4a2{jr pTBSծ<oKAbnV6Ut|>řtl4uf5}Q[xl*=q&|7yuոc¼I<.{7r7۔adܸ^wj:w*ET6g5ޥq7c 6qUc $ڕ/F^'! BNL@Mq6C576Dbn\M/\ҵU&o ]p{A*OwM{tn ~na#=rb"=Tzi6s9`#oLn7qfytMW[o9o!`( \K7`vؠ#t){7|mc@Kρp@[XHϜ㹅IɴҲXY5TTJ6F:8XՋ RF?+\G0deK[_^xyK5`ClBB/Yv@Ka6p.(ڶ(\tmV>aqr< 2+mۮg 0[N궭4 ?\KS %=VhЗ\ʁʁq@p-)݋_Qh6&4I0[:t D, YEAR. # msgid "" msgstr "" "Project-Id-Version: 0\n" "POT-Creation-Date: 2012-10-17T05:19:01\n" "PO-Revision-Date: 2011-05-04 10:28+0100\n" "Last-Translator: RaSca \n" "Language-Team: None\n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. Tag: title #, no-c-format msgid "What Changed in 1.0" msgstr "Cosa è cambiato nella versione 1.0" #. Tag: title #, no-c-format msgid "New" msgstr "Nuovo" #. Tag: para #, no-c-format msgid "Failure timeouts. See " msgstr "Failure timeouts. Vedere " #. Tag: para #, no-c-format msgid "New section for resource and operation defaults. See and " msgstr "Nuova sezione per le risorse e le operazioni di default. Vedere e " #. Tag: para #, no-c-format msgid "Tool for making offline configuration changes. See " msgstr "Strumento per effettuare modifiche alla configurazione offline. Vedere " #. Tag: para #, no-c-format msgid "Rules, instance_attributes, meta_attributes and sets of operations can be defined once and referenced in multiple places. See " msgstr "Rules, instance_attributes, meta_attributes ed i set di operazioni possono essere definiti inizialmente e referenziati in diversi posti. Vedere " #. Tag: para #, no-c-format msgid "The CIB now accepts XPath-based create/modify/delete operations. See the cibadmin help text." msgstr "Il CIB ora accetta le operazioni create/modify/delete basate su XPath. Vedere il testo di aiuto di cibadmin" #. Tag: para #, no-c-format msgid "Multi-dimensional colocation and ordering constraints. See and " msgstr "Vincoli multi dimensionali di colocation e ordering. Vedere e " #. Tag: para #, no-c-format msgid "The ability to connect to the CIB from non-cluster machines. See " msgstr "Possibilità di connessione al CIB da macchine non appartenenti al cluster. Vedere " #. Tag: para #, no-c-format msgid "Allow recurring actions to be triggered at known times. See " msgstr "Possibilità di innescare azioni ricorrenti in determinate tempistiche. Vedere " #. Tag: title #, no-c-format msgid "Changed" msgstr "Modifiche" #. Tag: para #, no-c-format msgid "Syntax" msgstr "Sintassi" #. Tag: para #, no-c-format msgid "All resource and cluster options now use dashes (-) instead of underscores (_)" msgstr "Tutte le risorse e le opzioni del cluster ora utilizzano trattini (-) invece di underscore (_)" #. Tag: para #, no-c-format msgid "master_slave was renamed to master" msgstr "master_slave è stato rinominato in master" #. Tag: para #, no-c-format msgid "The attributes container tag was removed" msgstr "Il tag contenitore attributes è stato rimosso" #. Tag: para #, no-c-format msgid "The operation field pre-req has been renamed requires" msgstr "Il campo operazione pre-req è stato rinominato in requires" #. Tag: para #, fuzzy, no-c-format msgid "All operations must have an interval, start/stop must have it set to zero" msgstr "Tutte le operazioni devono avere un intervallo interval e le operazioni start/stop devono averlo valorizzato a zero" #. Tag: para #, no-c-format msgid "The stonith-enabled option now defaults to true." msgstr "L'opzione stonith-enabled ora per default è true" #. Tag: para #, no-c-format msgid "The cluster will refuse to start resources if stonith-enabled is true (or unset) and no STONITH resources have been defined" msgstr "Il cluster rifiuterà di avviare risorse se stonith-enabled è true (o non valorizzato) e non è stata definita nessuna risorsa STONITH" #. Tag: para #, no-c-format msgid "The attributes of colocation and ordering constraints were renamed for clarity. See and " msgstr "Gli attributi dei vincoli colocation e ordering sono stati rinominati per chiarezza. Vedere e " #. Tag: para #, no-c-format msgid "resource-failure-stickiness has been replaced by migration-threshold. See " msgstr "resource-failure-stickiness è stata rimpiazzata da migration-threshold. Vedere " #. Tag: para #, fuzzy, no-c-format msgid "The parameters for command-line tools have been made consistent" msgstr "Gli argomenti degli strumenti a linea di comando sono stati resi consistenti" #. Tag: para #, fuzzy, no-c-format msgid "Switched to RelaxNG schema validation and libxml2 parser" msgstr "Passaggio allo schema di validazione RelaxNG ed al parser libxml2." #. Tag: para #, fuzzy, no-c-format msgid "id fields are now XML IDs which have the following limitations:" msgstr "I campi id ora sono XML ID con le seguenti limitazioni" #. Tag: para #, fuzzy, no-c-format msgid "id’s cannot contain colons (:)" msgstr "gli id non possonoo contenere due punti (:)" #. Tag: para #, fuzzy, no-c-format msgid "id’s cannot begin with a number" msgstr "gli id non possono iniziare con numeri" #. Tag: para #, fuzzy, no-c-format msgid "id’s must be globally unique (not just unique for that tag)" msgstr "gli id devono essere globalmente univoci (non solamente univoci per il tag relativo)" #. Tag: para #, no-c-format msgid "Some fields (such as those in constraints that refer to resources) are IDREFs." msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "This means that they must reference existing resources or objects in order for the configuration to be valid. Removing an object which is referenced elsewhere will therefore fail." msgstr "Alcuni campi (come quelli presenti nei vincoli riferiti alle risorse) sono IDREF. Questo significa che essi devono riferirsi a risorse esistenti o oggetti affinché la configurazione venga ritenuta valida. Rimuovere un oggetto che è referenziato alltrove quindi fallirà." #. Tag: para #, no-c-format msgid "The CIB representation, from which a MD5 digest is calculated to verify CIBs on the nodes, has changed." msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "This means that every CIB update will require a full refresh on any upgraded nodes until the cluster is fully upgraded to 1.0. This will result in significant performance degradation and it is therefore highly inadvisable to run a mixed 1.0/0.6 cluster for any longer than absolutely necessary." msgstr "La rappresentazione del CIB da cui è ricavato l'hash MD5 utilizzato per verificare il CIB è stata modificata. Questo significa che ogni variazione del CIB richiederà un completo refresh su ogni nodo aggiornato finché il cluster non verrà totalmente passato alla versione 1.0. Questo provocherà significative perdite di performance ed è assolutamente sconsigliato utilizzare versioni mixate del cluster 1.0/0.6 a meno che non sia strettamente necessario." #. Tag: para #, fuzzy, no-c-format msgid "Ping node information no longer needs to be added to ha.cf." msgstr "Le informazioni sui ping node non necessitano più di essere aggiunte al file ha.cf. Sarà sufficiente includere gli host nella lista delle risorse ping definite." #. Tag: para #, no-c-format msgid "Simply include the lists of hosts in your ping resource(s)." msgstr "" #. Tag: title #, no-c-format msgid "Removed" msgstr "Rimozioni" #. Tag: para #, no-c-format msgid "It is no longer possible to set resource meta options as top-level attributes. Use meta attributes instead." msgstr "Non è più possibile valorizzare un'opzione meta della risorsa come attributo di livello superiore. Sarà necessario utilizzare invece gli attributi meta." #. Tag: para #, no-c-format msgid "Resource and operation defaults are no longer read from crm_config. See and instead." msgstr "I valori di default per le risorse e le operazioni non sono più letti da crm_config. Vedere invece e ." pacemaker-master/doc/Pacemaker_Explained/it-IT/Ap-Debug.po000066400000000000000000000225751217637305600236240ustar00rootroot00000000000000# # AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: 0\n" "POT-Creation-Date: 2012-10-17T05:19:01\n" "PO-Revision-Date: 2011-05-03 15:53+0100\n" "Last-Translator: RaSca \n" "Language-Team: None\n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. Tag: title #, no-c-format msgid "Debugging Cluster Startup" msgstr "" #. Tag: title #, no-c-format msgid "Corosync" msgstr "Corosync" #. Tag: title #, no-c-format msgid "Prerequisites" msgstr "Prerequisiti" #. Tag: title #, no-c-format msgid "Minimum logging configuration" msgstr "Configurazione per il log minima" #. Tag: programlisting #, fuzzy, no-c-format msgid "" "\n" " # /etc/init.d/openais start\n" " \n" " \n" " logging {\n" " to_syslog: yes\n" " syslog_facility: daemon\n" " }\n" " \n" " " msgstr "" "\n" "\t \n" " # /etc/init.d/openais start\n" "\t \n" "\t \n" " logging {\n" " to_syslog: yes\n" " syslog_facility: daemon\n" " }\n" "\t \n" "\t " #. Tag: caption #, no-c-format msgid "Whatever other logging you have, these two lines are required for Pacemaker clusters" msgstr "Qualsiasi tipo di log si sia impostato, queste due linee sono necessarie per i cluster Pacemaker" #. Tag: title #, no-c-format msgid "Confirm Corosync Started" msgstr "Conferma avvio Corosync" #. Tag: title #, no-c-format msgid "Expected output when starting openais" msgstr "Output previsto all'avvio di openais" #. Tag: screen #, fuzzy, no-c-format msgid "" "\n" " # /etc/init.d/openais start\n" " \n" " \n" " Starting Corosync daemon (aisexec): starting... rc=0: OK\n" " \n" " " msgstr "" "\n" "\t \n" " # /etc/init.d/openais start\n" "\t \n" "\t \n" " Starting Corosync daemon (aisexec): starting... rc=0: OK\n" "\t \n" "\t " #. Tag: title #, no-c-format msgid "Expected log messages - startup" msgstr "Messaggi di log previsti - startup" #. Tag: screen #, fuzzy, no-c-format msgid "" "\n" " # grep -e \"openais.*network interface\" -e \"AIS Executive Service\" /var/log/messages\n" " \n" " \n" " Aug 27 16:23:37 test1 openais[26337]: [MAIN ] AIS Executive Service RELEASE 'subrev 1152 version 0.80'\n" " Aug 27 16:23:38 test1 openais[26337]: [MAIN ] AIS Executive Service: started and ready to provide service.\n" " Aug 27 16:23:38 test1 openais[26337]: [TOTEM] The network interface [192.168.9.41] is now up.\n" " \n" " " msgstr "" "\n" "\t \n" " # grep -e "openais.*network interface" -e "AIS Executive Service" /var/log/messages\n" "\t \n" "\t \n" " Aug 27 16:23:37 test1 openais[26337]: [MAIN ] AIS Executive Service RELEASE 'subrev 1152 version 0.80'\n" " Aug 27 16:23:38 test1 openais[26337]: [MAIN ] AIS Executive Service: started and ready to provide service.\n" " Aug 27 16:23:38 test1 openais[26337]: [TOTEM] The network interface [192.168.9.41] is now up.\n" "\t \n" "\t " #. Tag: caption #, fuzzy, no-c-format msgid "The versions may differ, but you should see Corosync indicate it started and sucessfully attached to the machine's network interface" msgstr "Le versioni potrebbero differire, ma si dovrebbe vedere Corosync indicare l'avvio e l'aggancio all'interfaccia di rete della macchina" #. Tag: title #, no-c-format msgid "Expected log messages - membership" msgstr "Messaggi di log attesi - membership" #. Tag: screen #, fuzzy, no-c-format msgid "" "\n" " # grep CLM /var/log/messages\n" " \n" " \n" " Aug 27 16:53:15 test1 openais[2166]: [CLM ] CLM CONFIGURATION CHANGE\n" " Aug 27 16:53:15 test1 openais[2166]: [CLM ] New Configuration:\n" " Aug 27 16:53:15 test1 openais[2166]: [CLM ] Members Left:\n" " Aug 27 16:53:15 test1 openais[2166]: [CLM ] Members Joined:\n" " Aug 27 16:53:15 test1 openais[2166]: [CLM ] CLM CONFIGURATION CHANGE\n" " Aug 27 16:53:15 test1 openais[2166]: [CLM ] New Configuration:\n" " Aug 27 16:53:15 test1 openais[2166]: [CLM ] r(0) ip(192.168.9.41)\n" " Aug 27 16:53:15 test1 openais[2166]: [CLM ] Members Left:\n" " Aug 27 16:53:15 test1 openais[2166]: [CLM ] Members Joined:\n" " Aug 27 16:53:15 test1 openais[2166]: [CLM ] r(0) ip(192.168.9.41)\n" " Aug 27 16:53:15 test1 openais[2166]: [CLM ] got nodejoin message 192.168.9.41\n" " \n" " " msgstr "" "\n" "\t \n" " # grep CLM /var/log/messages\n" "\t \n" "\t \n" " Aug 27 16:53:15 test1 openais[2166]: [CLM ] CLM CONFIGURATION CHANGE\n" " Aug 27 16:53:15 test1 openais[2166]: [CLM ] New Configuration:\n" " Aug 27 16:53:15 test1 openais[2166]: [CLM ] Members Left:\n" " Aug 27 16:53:15 test1 openais[2166]: [CLM ] Members Joined:\n" " Aug 27 16:53:15 test1 openais[2166]: [CLM ] CLM CONFIGURATION CHANGE\n" " Aug 27 16:53:15 test1 openais[2166]: [CLM ] New Configuration:\n" " Aug 27 16:53:15 test1 openais[2166]: [CLM ] r(0) ip(192.168.9.41) \n" " Aug 27 16:53:15 test1 openais[2166]: [CLM ] Members Left:\n" " Aug 27 16:53:15 test1 openais[2166]: [CLM ] Members Joined:\n" " Aug 27 16:53:15 test1 openais[2166]: [CLM ] r(0) ip(192.168.9.41) \n" " Aug 27 16:53:15 test1 openais[2166]: [CLM ] got nodejoin message 192.168.9.41\n" "\t \n" "\t " #. Tag: caption #, no-c-format msgid "The exact messages will differ, but you should see a new membership formed with the real IP address of your node" msgstr "Il messaggio preciso potrebbe differire, ma si dovrebbero osservare nuove membership formate con l'indirizzo IP reale del proprio nodo" #. Tag: title #, no-c-format msgid "Checking Pacemaker" msgstr "Controllare Pacemaker" #. Tag: para #, no-c-format msgid "Now that we have confirmed that Corosync is functional we can check the rest of the stack." msgstr "Dopo aver verificato la funzionalità di Corosync è possibile controllare il resto dello stack." #. Tag: title #, no-c-format msgid "Expected Pacemaker startup logging for Corosync" msgstr "Log di avvio previsti per Pacemaker con Corosync" #. Tag: screen #, fuzzy, no-c-format msgid "" "\n" " # grep pcmk_plugin_init /var/log/messages\n" " \n" " \n" " Aug 27 16:53:15 test1 openais[2166]: [pcmk ] info: pcmk_plugin_init: CRM: Initialized\n" " Aug 27 16:53:15 test1 openais[2166]: [pcmk ] Logging: Initialized pcmk_plugin_init\n" " Aug 27 16:53:15 test1 openais[2166]: [pcmk ] info: pcmk_plugin_init: Service: 9\n" " Aug 27 16:53:15 test1 openais[2166]: [pcmk ] info: pcmk_plugin_init: Local hostname: test1\n" " \n" " " msgstr "" "\n" "\t \n" " # grep pcmk_plugin_init /var/log/messages\n" "\t \n" "\t \n" " Aug 27 16:53:15 test1 openais[2166]: [pcmk ] info: pcmk_plugin_init: CRM: Initialized\n" " Aug 27 16:53:15 test1 openais[2166]: [pcmk ] Logging: Initialized pcmk_plugin_init\n" " Aug 27 16:53:15 test1 openais[2166]: [pcmk ] info: pcmk_plugin_init: Service: 9\n" " Aug 27 16:53:15 test1 openais[2166]: [pcmk ] info: pcmk_plugin_init: Local hostname: test1\n" "\t \n" "\t " #. Tag: caption #, fuzzy, no-c-format msgid "If you don't see these messages, or some like them, there is likely a problem finding or loading the pacemaker plugin." msgstr "Se non si osservano questi messaggi o qualcosa di simile, esiste verosimilmente un problema nel trovare o caricare il plugin pacemaker." #. Tag: title #, no-c-format msgid "Expected process listing on a 64-bit machine" msgstr "Lista dei processi prevista su una macchina a 64 bit" #. Tag: screen #, fuzzy, no-c-format msgid "" "\n" " # ps axf\n" " \n" " \n" " 3718 ? Ssl 0:05 /usr/sbin/aisexec\n" " 3723 ? SLs 0:00 \\_ /usr/lib64/heartbeat/stonithd\n" " 3724 ? S 0:05 \\_ /usr/lib64/heartbeat/cib\n" " 3725 ? S 0:21 \\_ /usr/lib64/heartbeat/lrmd\n" " 3726 ? S 0:01 \\_ /usr/lib64/heartbeat/attrd\n" " 3727 ? S 0:00 \\_ /usr/lib64/heartbeat/pengine\n" " 3728 ? S 0:01 \\_ /usr/lib64/heartbeat/crmd\n" " \n" " " msgstr "" "\n" "\t \n" " # ps axf\n" "\t \n" "\t \n" " 3718 ? Ssl 0:05 /usr/sbin/aisexec\n" " 3723 ? SLs 0:00 \\_ /usr/lib64/heartbeat/stonithd\n" " 3724 ? S 0:05 \\_ /usr/lib64/heartbeat/cib\n" " 3725 ? S 0:21 \\_ /usr/lib64/heartbeat/lrmd\n" " 3726 ? S 0:01 \\_ /usr/lib64/heartbeat/attrd\n" " 3727 ? S 0:00 \\_ /usr/lib64/heartbeat/pengine\n" " 3728 ? S 0:01 \\_ /usr/lib64/heartbeat/crmd\n" "\t \n" "\t " #. Tag: caption #, no-c-format msgid "On 32-bit systems the exact path may differ, but all the above processes should be listed." msgstr "Su sistemi 32 bit il path esatto potrebbe differire, ma dovrebbero apparire tutti i processi listati sopra." pacemaker-master/doc/Pacemaker_Explained/it-IT/Ap-FAQ.po000066400000000000000000000161461217637305600232020ustar00rootroot00000000000000# # AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: 0\n" "POT-Creation-Date: 2012-10-17T05:19:01\n" "PO-Revision-Date: 2011-10-12 10:18+0100\n" "Last-Translator: RaSca \n" "Language-Team: None\n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. Tag: title #, no-c-format msgid "FAQ" msgstr "FAQ" #. Tag: title #, no-c-format msgid "History" msgstr "Storia" #. Tag: para #, no-c-format msgid "Why is the Project Called PacemakernamingPacemaker?" msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "First of all, the reason its not called the CRM is because of the abundance of terms that are commonly abbreviated to those three letters." msgstr "Prima di tutto non è chiamato CRM per via dell'abbondanza di termini a cui l'acronimo corrisponde." #. Tag: para #, fuzzy, no-c-format msgid "The Pacemaker name came from Kham, a good friend of mine, and was originally used by a Java GUI that I was prototyping in early 2007. Alas other commitments have prevented the GUI from progressing much and, when it came time to choose a name for this project, Lars suggested it was an even better fit for an independent CRM." msgstr "Il nome Pacemaker deriva da Kham, un caro amico, e venne originariamente usato per una GUI Java che stavo costruendo all'inizio del 2007. Purtroppo altri impegni hanno portato la GUI a non progredire a sufficienza e quando venne il momento di scegliere un nome per questo progetto, Lars suggerì che calzava ancora meglio su un CRM indipendente." #. Tag: para #, no-c-format msgid "The idea stems from the analogy between the role of this software and that of the little device that keeps the human heart pumping. Pacemaker monitors the cluster and intervenes when necessary to ensure the smooth operation of the services it provides." msgstr "L'idea su basa sull'analogia del ruolo di questo software con il piccolo dispositivo che mantiene il cuore umano in grado di pompare. Pacemaker controlla il cluster ed interviene quando necessario per assicurare il buon funzionamento dei servizi che fornisce." #. Tag: para #, fuzzy, no-c-format msgid "There were a number of other names (and acronyms) tossed around, but suffice to say \"Pacemaker\" was the best" msgstr "Ci furono diversi altri nomi (ed acronimi) proposti, ma è sufficiente affermare che "Pacemaker" era il migliore" #. Tag: para #, no-c-format msgid "Why was the Pacemaker Project Created?" msgstr "Perché è stato creato il progetto Pacemaker?" #. Tag: para #, no-c-format msgid "The decision was made to spin-off the CRM into its own project after the 2.1.3 Heartbeat release in order to" msgstr "La decisione venne presa per slacciare il CRM in un progetto a se stante dopo la versione 2.1.3 di Heartbeat in modo da" #. Tag: para #, no-c-format msgid "support both the Corosync and Heartbeat cluster stacks equally" msgstr "supportare gli stack Corosync ed Heartbeat equamente" #. Tag: para #, no-c-format msgid "decouple the release cycles of two projects at very different stages of their life-cycles" msgstr "disaccoppiare i cicli di rilascio di due progetti in fasi molto diverse della loro crescita" #. Tag: para #, no-c-format msgid "foster the clearer package boundaries, thus leading to" msgstr "definire meglio gli ambiti del progetto, in modo da avere" #. Tag: para #, no-c-format msgid "better and more stable interfaces" msgstr "interfacci più stabili e migliori" #. Tag: title #, no-c-format msgid "Setup" msgstr "Setup" #. Tag: para #, no-c-format msgid "What Messaging Layers Messaging Layers are Supported?" msgstr "" #. Tag: para #, no-c-format msgid "Corosync ()" msgstr "Corosync ()" #. Tag: para #, no-c-format msgid "Heartbeat ()" msgstr "Heartbeat ()" #. Tag: para #, no-c-format msgid "Can I Choose which Messaging Layer to use at Run Time?" msgstr "E' possibile scegliere a runtime il Message Layer da usare?" #. Tag: para #, fuzzy, no-c-format msgid "Yes. The CRM will automatically detect which started it and behave accordingly." msgstr "Sì. Il CRM identificherà da chi è stato avviato, comportandosi di conseguenza." #. Tag: para #, no-c-format msgid "Can I Have a Mixed Heartbeat-Corosync Cluster?" msgstr "E' possibile avere un cluster mixato Heartbeat-Corosync?" #. Tag: para #, no-c-format msgid "No." msgstr "No." #. Tag: para #, no-c-format msgid "Which Messaging Layer Should I Choose?" msgstr "Quale Message Layer si dovrebbe scegliere?" #. Tag: para #, no-c-format msgid "This is discussed in ." msgstr "Questo viene discusso qui ." #. Tag: para #, no-c-format msgid "Where Can I Get Pre-built Packages?" msgstr "Dove si possono reperire pacchetti pre compilati?" #. Tag: para #, fuzzy, no-c-format msgid "Official packages for most major .rpm and based distributions are available from the ClusterLabs Website." msgstr "I pacchetti ufficiali per le distribuzioni basate su rpm sono disponibili presso:" #. Tag: para #, fuzzy, no-c-format msgid "For Debian packages, building from source and details on using the above repositories, see our installation page." msgstr "Per i pacchetti Debian, compilare dai sorgenti e dettagli sull'utilizzo dei repository indicati sopra, vedere la nostra Pagina di installazione." #. Tag: para #, no-c-format msgid "What Versions of Pacemaker Are Supported?" msgstr "Quali versioni di Pacemaker sono supportate?" #. Tag: para #, fuzzy, no-c-format msgid "Please refer to the Releases page for an up-to-date list of versions supported directly by the project." msgstr "Riferirsi alla pagina Releases per una lista aggiornata delle versioni supportate direttamente dal progetto." #. Tag: para #, no-c-format msgid "When seeking assistance, please try to ensure you have one of these versions." msgstr "Quando si necessita di assistenza è ideale utilizzare una di queste versioni." #~ msgid "Why is the Project Called Pacemaker?" #~ msgstr "Perché il progetto è chiamato Pacemaker?" #~ msgid "What Messaging Layers are Supported?" #~ msgstr "Quali Messaging Layers sono supportati?" #~ msgid "" #~ msgstr "" pacemaker-master/doc/Pacemaker_Explained/it-IT/Ap-Install.po000066400000000000000000000235531217637305600242010ustar00rootroot00000000000000# # AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: 0\n" "POT-Creation-Date: 2012-10-17T05:19:01\n" "PO-Revision-Date: 2011-05-03 16:30+0100\n" "Last-Translator: RaSca \n" "Language-Team: None\n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. Tag: title #, no-c-format msgid "Installation" msgstr "Installazione" #. Tag: para #, no-c-format msgid "The following text may no longer be accurate in some places." msgstr "" #. Tag: title #, no-c-format msgid "Choosing a Cluster Stack" msgstr "Scegliere lo stack del cluster" #. Tag: para #, no-c-format msgid " ClusterChoosing Between Heartbeat and Corosync Choosing Between Heartbeat and Corosync Cluster StackCorosync Corosync Corosync Cluster StackHeartbeat Heartbeat Heartbeat " msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "Ultimately the choice of cluster stack is a personal decision that must be made in the context of you or your company’s needs and strategic direction. Pacemaker currently functions equally well with both stacks." msgstr "Ultimamente la scelta dello stack del cluster da utilizzare è una decisione personale che va presa nel contesto delle proprie (e della propria azienda) esigenze e strategie direzionali. Pacemaker attualmente funziona in maniera identica con entrambi gli stack." #. Tag: para #, fuzzy, no-c-format msgid "Here are some factors that may influence the decision:" msgstr "Alcuni fattori che potrebbero influenzare la decisione" #. Tag: para #, no-c-format msgid "SUSE/Novell, Red Hat and Oracle are all putting their collective weight behind the Corosync cluster stack." msgstr "SUSE/Novell, Red Hat ed Oracle stanno ponendo il proprio peso sulle spalle dello stack Corosync." #. Tag: para #, no-c-format msgid "Using Corosync gives your applications access to the following additional cluster services" msgstr "Utilizzare Corosync da accesso alle proprie applicazioni a questi servizi aggiuntivi" #. Tag: para #, no-c-format msgid "distributed locking service" msgstr "distributed locking service" #. Tag: para #, fuzzy, no-c-format msgid "extended virtual synchronization service" msgstr "servizio extended virtual synchrony" #. Tag: para #, no-c-format msgid "cluster closed process group service" msgstr "servizio cluster closed process group" #. Tag: para #, no-c-format msgid "It is likely that Pacemaker, at some point in the future, will make use of some of these additional services not provided by Heartbeat" msgstr "E' verosimile pensare che Pacemaker, in futuro, possa utilizzare qualcuno di questi servizi aggiuntivi non forniti da Heartbeat" #. Tag: title #, no-c-format msgid "Enabling Pacemaker" msgstr "Abilitare Pacemaker" #. Tag: title #, no-c-format msgid "For Corosync" msgstr "Per Corosync" #. Tag: para #, fuzzy, no-c-format msgid "The Corosync configuration is normally located in /etc/corosync/corosync.conf and an example for a machine with an address of 1.2.3.4 in a cluster communicating on port 1234 (without peer authentication and message encryption) is shown below." msgstr "La configurazione di Corosync è normalmente posizionata in /etc/corosync/corosync.conf. Viene mostrato sotto un esempio per una macchina con indirizzo 1.2.3.4 comunicante in un cluster alla porta 1234 (senza autenticazione e crittazione dei messaggi)." #. Tag: title #, no-c-format msgid "An example Corosync configuration file" msgstr "Un esempio di un file di configurazione di Corosync" #. Tag: programlisting #, fuzzy, no-c-format msgid "" " totem {\n" " version: 2\n" " secauth: off\n" " threads: 0\n" " interface {\n" " ringnumber: 0\n" " bindnetaddr: 1.2.3.4\n" " mcastaddr: 239.255.1.1\n" " mcastport: 1234\n" " }\n" " }\n" " logging {\n" " fileline: off\n" " to_syslog: yes\n" " syslog_facility: daemon\n" " }\n" " amf {\n" " mode: disabled\n" " }" msgstr "" "\n" " totem {\n" " version: 2\n" " secauth: off\n" " threads: 0\n" " interface {\n" " ringnumber: 0\n" " bindnetaddr: 1.2.3.4\n" " mcastaddr: 226.94.1.1\n" " mcastport: 1234\n" " }\n" " }\n" " logging {\n" " fileline: off\n" " to_syslog: yes\n" " syslog_facility: daemon\n" " }\n" " amf {\n" " mode: disabled\n" " }\n" "\t" #. Tag: para #, no-c-format msgid "The logging should be mostly obvious and the amf section refers to the Availability Management Framework and is not covered in this document." msgstr "La sezione logging risulta piuttosto ovvia e la sezione amf si riferisce all'Availability Management Framework e non è affrontata in questo documento." #. Tag: para #, fuzzy, no-c-format msgid "The interesting part of the configuration is the totem section. This is where we define how the node can communicate with the rest of the cluster and what protocol version and options (including encryption Please consult the Corosync website (http://www.corosync.org/) and documentation for details on enabling encryption and peer authentication for the cluster. ) it should use. Beginners are encouraged to use the values shown and modify the interface section based on their network." msgstr "La parte interessante è la sezione totem. Qui è dove viene definito come un nodo comunica con il resto del cluster e quale versione di protocollo ed opzioni (inclusa la crittazione Consultare il sito di Corosync e la documentazione per dettagli su come abilitare la crittazione e l'autenticazione dei componenti nel cluster. ) esso debba utilizzare. I principianti sono incoraggiati ad utilizzare quanto indicato e modificare la sezione dell'interfaccia in base alla propria rete." #. Tag: para #, fuzzy, no-c-format msgid "It is also possible to configure Corosync for an IPv6 based environment. Simply configure bindnetaddr and mcastaddr with their IPv6 equivalents, eg." msgstr "E' inoltre possibile configurare Corosync per un ambiente basato su IPv6. E' sufficiente configurare i parametri bindnetaddr e mcastaddr con l'equivalente IPV6. Ad esempio" #. Tag: title #, no-c-format msgid "Example options for an IPv6 environment" msgstr "Esempio di opzioni per un ambiente IPV6" #. Tag: programlisting #, fuzzy, no-c-format msgid "" " bindnetaddr: fec0::1:a800:4ff:fe00:20\n" " mcastaddr: ff05::1" msgstr "" "\n" " bindnetaddr: fec0::1:a800:4ff:fe00:20 \n" " mcastaddr: ff05::1\n" "\t " #. Tag: para #, no-c-format msgid "To tell Corosync to use the Pacemaker cluster manager, add the following fragment to a functional Corosync configuration and restart the cluster." msgstr "Per indicare a Corosync di utilizzare il cluster manager Pacemaker è necessario aggiungere il seguente frammento ad una configurazione Corosync funzionante e riavviare il cluster." #. Tag: title #, no-c-format msgid "Configuration fragment for enabling Pacemaker under Corosync" msgstr "Frammento di configurazione per abilitare Pacemaker in Corosync" #. Tag: programlisting #, fuzzy, no-c-format msgid "" "aisexec {\n" " user: root\n" " group: root\n" "}\n" "service {\n" " name: pacemaker\n" " ver: 0\n" "}" msgstr "" "\n" " aisexec {\n" " user: root\n" " group: root\n" " }\n" " service {\n" " name: pacemaker\n" " ver: 0\n" " }\n" "\t " #. Tag: para #, fuzzy, no-c-format msgid "The cluster needs to be run as root so that its child processes (the lrmd in particular) have sufficient privileges to perform the actions requested of it. After all, a cluster manager that can’t add an IP address or start apache is of little use." msgstr "Il cluster necessità di funzionare come root in modo che i processi figlio (lrmd in particolare) abbiano sufficienti privilegi per effettuare le azioni richieste da esso. Dopo tutto, un cluster manager che non potesse aggiungere un indirizzo IP o avviare apache risulterebbe piuttosto inutile." #. Tag: para #, no-c-format msgid "The second directive is the one that actually instructs the cluster to run Pacemaker." msgstr "La seconda direttiva istruisce il cluster nell'utilizzare Pacemaker." #. Tag: title #, no-c-format msgid "For Heartbeat" msgstr "Per Heartbeat" #. Tag: para #, fuzzy, no-c-format msgid "Add the following to a functional ha.cf configuration file and restart Heartbeat:" msgstr "Aggiungere quanto segue al file ha.cf in una configurazione funzionante e riavviando Heartbeat" #. Tag: title #, no-c-format msgid "Configuration fragment for enabling Pacemaker under Heartbeat" msgstr "Frammento di configurazione per abilitare Pacemaker in Heartbeat" #. Tag: programlisting #, fuzzy, no-c-format msgid "crm respawn" msgstr "" "\n" " crm respawn\n" "\t " #~ msgid "Corosync is an OSI Certified implementation of an industry standard (the Service Availability Forum Application Interface Specification)." #~ msgstr "Corosync è un'implementazione di uno standard industriale (il Service Availability Forum Application Interface Specification) certificato OSI." #~ msgid "checkpoint service" #~ msgstr "servizio checkpoint" #~ msgid "To date, Pacemaker has received less real-world testing on Corosync than it has on Heartbeat." #~ msgstr "Fino ad oggi, Pacemaker ha ricevuto minori test su soluzioni in produzione con Corosync rispetto ad Heartbeat" pacemaker-master/doc/Pacemaker_Explained/it-IT/Ap-LSB.po000066400000000000000000000133151217637305600232060ustar00rootroot00000000000000# # AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: 0\n" "POT-Creation-Date: 2012-10-17T05:19:01\n" "PO-Revision-Date: 2011-05-03 17:51+0100\n" "Last-Translator: RaSca \n" "Language-Team: None\n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. Tag: title #, fuzzy, no-c-format msgid "init-Script LSB Compliance" msgstr "Questo script è compatibile con LSB?" #. Tag: para #, fuzzy, no-c-format msgid "The relevant part of LSB spec includes a description of all the return codes listed here." msgstr "La parte rilevante delle specifiche LSB si trova qui: http://refspecs.freestandards.org/LSB_3.1.0/LSB-Core-generic/LSB-Core-generic/iniscrptact.html. Essa include una descrizione di tutti i codici di ritorno riportati qui." #. Tag: para #, fuzzy, no-c-format msgid "Assuming some_service is configured correctly and currently not active, the following sequence will help you determine if it is LSB compatible:" msgstr "Assumendo che some_service sia configurato correttamente ed attualmente inattivo, la seguente sequenza aiuterà a valutare la compatibilità con LSB:" #. Tag: para #, no-c-format msgid "Start (stopped):" msgstr "Start (a servizio fermo):" #. Tag: programlisting #, fuzzy, no-c-format msgid "# /etc/init.d/some_service start ; echo \"result: $?\"" msgstr " /etc/init.d/some_service start ; echo "result: $?" " #. Tag: para #, no-c-format msgid "Did the service start?" msgstr "Il servizio si è avviato?" #. Tag: para #, no-c-format msgid "Did the command print result: 0 (in addition to the regular output)?" msgstr "Il comando ha stampato il risultato: 0 (in aggiunta all'output classico)?" #. Tag: para #, no-c-format msgid "Status (running):" msgstr "Status (a servizio attivo):" #. Tag: programlisting #, fuzzy, no-c-format msgid "# /etc/init.d/some_service status ; echo \"result: $?\"" msgstr "/etc/init.d/some_service status ; echo "result: $?" " #. Tag: para #, no-c-format msgid "Did the script accept the command?" msgstr "Lo script ha accettato il comando?" #. Tag: para #, no-c-format msgid "Did the script indicate the service was running?" msgstr "Lo script ha indicato che il servizio stava funzionando?" #. Tag: para #, no-c-format msgid "Start (running):" msgstr "Start (a servizio attivo):" #. Tag: para #, no-c-format msgid "Is the service still running?" msgstr "Il servizio è ancora attivo?" #. Tag: para #, no-c-format msgid "Stop (running):" msgstr "Stop (a servizio attivo):" #. Tag: programlisting #, fuzzy, no-c-format msgid "# /etc/init.d/some_service stop ; echo \"result: $?\"" msgstr "/etc/init.d/some_service stop ; echo "result: $?" " #. Tag: para #, no-c-format msgid "Was the service stopped?" msgstr "Il servizio è stato stoppato?" #. Tag: para #, no-c-format msgid "Status (stopped):" msgstr "Status (a servizio fermo):" #. Tag: para #, no-c-format msgid "Did the script indicate the service was not running?" msgstr "Lo script ha indicato che il servizio non stava funzionando?" #. Tag: para #, no-c-format msgid "Did the command print result: 3 (in addition to the regular output)?" msgstr "Il comando ha restituito il risultato: 3 (in aggiunta all'ouput classico)?" #. Tag: para #, no-c-format msgid "Stop (stopped):" msgstr "Stop (a servizio fermo):" #. Tag: para #, no-c-format msgid "Is the service still stopped?" msgstr "Il servizio è ancora stoppato?" #. Tag: para #, no-c-format msgid "Status (failed):" msgstr "Status (a servizio fallito):" #. Tag: para #, no-c-format msgid "This step is not readily testable and relies on manual inspection of the script." msgstr "Questo passaggio non è facilmente verificabile e si basa sul controllo manuale dello script." #. Tag: para #, no-c-format msgid "The script can use one of the error codes (other than 3) listed in the LSB spec to indicate that it is active but failed. This tells the cluster that before moving the resource to another node, it needs to stop it on the existing one first." msgstr "Lo script può utilizzare un codice di errore (diverso da 3) elencato nelle specifiche LSB per indicare che è attivo ma fallito. Questo indica al cluster che prima di spostare una risorsa ad un altro nodo essa necessita di essere stoppata prima sul nodo attuale." #. Tag: para #, no-c-format msgid "If the answer to any of the above questions is no, then the script is not LSB compliant. Your options are then to either fix the script or write an OCF agent based on the existing script." msgstr "Se la risposta a qualsiasi delle domande elencate è no, allora lo script non è LSB compatibile. Le opzioni a questo punto sono di sistemare lo script o scrivere un agent OCF basato sullo script esistente." #~ msgid "/etc/init.d/some_service start ; echo "result: $?"" #~ msgstr "/etc/init.d/some_service start ; echo "result: $?"" #~ msgid "The script can use one of the error codes (other than 3) listed in the LSB spec to indicate that it is active but failed." #~ msgstr "Lo script può utilizzare un codice di errore (diverso da 3) elencato nelle specifiche LSB per indicare che è attivo ma fallito." #~ msgid "This tells the cluster that before moving the resource to another node, it needs to stop it on the existing one first." #~ msgstr "Questo indica al cluster che prima di spostare la risorsa su un altro nodo, essa necessita di essere fermata prima sul nodo attuale." pacemaker-master/doc/Pacemaker_Explained/it-IT/Ap-OCF.po000066400000000000000000000717121217637305600232020ustar00rootroot00000000000000# # AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: 0\n" "POT-Creation-Date: 2012-10-17T05:19:01\n" "PO-Revision-Date: 2011-05-04 09:58+0100\n" "Last-Translator: RaSca \n" "Language-Team: None\n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. Tag: title #, no-c-format msgid "More About OCF Resource Agents" msgstr "Maggiori informazioni sui Resource Agent OCF" #. Tag: title #, no-c-format msgid "Location of Custom Scripts" msgstr "Dove si trovano gli script personalizzati" #. Tag: para #, fuzzy, no-c-format msgid " OCF Resource Agents OCF Resource Agents are found in /usr/lib/ocf/resource.d/provider." msgstr "Gli OCF Resource Agent si troviano nel path /usr/lib/ocf/resource.d/provider." #. Tag: para #, fuzzy, no-c-format msgid "When creating your own agents, you are encouraged to create a new directory under /usr/lib/ocf/resource.d/ so that they are not confused with (or overwritten by) the agents shipped with Heartbeat." msgstr "In fase di creazione dei propri Agent l'utente è incoraggiato a creare una nuova cartella sotto /usr/lib/ocf/resource.d/ in modo che questi non vengano confusi (o sovrascritti) con gli agenti forniti con Heartbeat. Quindi, ad esempio, se viene scelto come nome provider bigCorp ed il nome della nuova risorsa sarà bigApp, andrà creato uno script chiamato /usr/lib/ocf/resource.d/bigCorp/bigApp e definita una risorsa:" #. Tag: para #, fuzzy, no-c-format msgid "So, for example, if you chose the provider name of bigCorp and wanted a new resource named bigApp, you would create a script called /usr/lib/ocf/resource.d/bigCorp/bigApp and define a resource:" msgstr "In fase di creazione dei propri Agent l'utente è incoraggiato a creare una nuova cartella sotto /usr/lib/ocf/resource.d/ in modo che questi non vengano confusi (o sovrascritti) con gli agenti forniti con Heartbeat. Quindi, ad esempio, se viene scelto come nome provider bigCorp ed il nome della nuova risorsa sarà bigApp, andrà creato uno script chiamato /usr/lib/ocf/resource.d/bigCorp/bigApp e definita una risorsa:" #. Tag: programlisting #, fuzzy, no-c-format msgid "<primitive id=\"custom-app\" class=\"ocf\" provider=\"bigCorp\" type=\"bigApp\"/>" msgstr "<primitive id="custom-app" class="ocf" provider="bigCorp" type="bigApp"/>" #. Tag: title #, no-c-format msgid "Actions" msgstr "Azioni" #. Tag: para #, no-c-format msgid "All OCF Resource Agents are required to implement the following actions" msgstr "Tutti i Resource Agent OCF devono implementare le seguenti azioni" #. Tag: title #, no-c-format msgid "Required Actions for OCF Agents" msgstr "Azioni richieste per gli agenti OCF" #. Tag: entry #, no-c-format msgid "Action" msgstr "Azione" #. Tag: entry #, no-c-format msgid "Description" msgstr "Descrizione" #. Tag: entry #, no-c-format msgid "Instructions" msgstr "Istruzioni" #. Tag: para #, no-c-format msgid "start" msgstr "" #. Tag: para #, no-c-format msgid "Start the resource" msgstr "Avvia la risorsa" #. Tag: para #, no-c-format msgid "Return 0 on success and an appropriate error code otherwise. Must not report success until the resource is fully active. startOCF Action OCF Action OCFActionstart Actionstart start " msgstr "" #. Tag: para #, no-c-format msgid "stop" msgstr "" #. Tag: para #, no-c-format msgid "Stop the resource" msgstr "Ferma la risorsa" #. Tag: para #, no-c-format msgid "Return 0 on success and an appropriate error code otherwise. Must not report success until the resource is fully stopped. stopOCF Action OCF Action OCFActionstop Actionstop stop " msgstr "" #. Tag: para #, no-c-format msgid "monitor" msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "Check the resource’s state" msgstr "Controlla lo stato della risorsa" #. Tag: para #, no-c-format msgid "Exit 0 if the resource is running, 7 if it is stopped, and anything else if it is failed. monitorOCF Action OCF Action OCFActionmonitor Actionmonitor monitor " msgstr "" #. Tag: para #, no-c-format msgid "NOTE: The monitor script should test the state of the resource on the local machine only." msgstr "NOTA: Lo script di monitor dovrebbe controllare lo stato della risorsa solo sulla macchina locale." #. Tag: para #, no-c-format msgid "meta-data" msgstr "" #. Tag: para #, no-c-format msgid "Describe the resource" msgstr "Descrive la risorsa" #. Tag: para #, no-c-format msgid "Provide information about this resource as an XML snippet. Exit with 0. meta-dataOCF Action OCF Action OCFActionmeta-data Actionmeta-data meta-data " msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "NOTE: This is not performed as root." msgstr "NOTA: non viene eseguito come root." #. Tag: para #, no-c-format msgid "validate-all" msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "Verify the supplied parameters" msgstr "Verifica che i parametri passati siano corretti" #. Tag: para #, no-c-format msgid "Exit with 0 if parameters are valid, 2 if not valid, 6 if resource is not configured. validate-allOCF Action OCF Action OCFActionvalidate-all Actionvalidate-all validate-all " msgstr "" #. Tag: para #, no-c-format msgid "Additional requirements (not part of the OCF specs) are placed on agents that will be used for advanced concepts like clones and multi-state resources." msgstr "Requisiti aggiuntivi (che non fanno parte delle specifiche OCF) sono associati ad agenti che vengono utilizzati nell'ambito delle risorse clone e multi-state." #. Tag: title #, no-c-format msgid "Optional Actions for OCF Agents" msgstr "Azioni facoltative per gli agent OCF" #. Tag: para #, no-c-format msgid "promote" msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "Promote the local instance of a multi-state resource to the master/primary state." msgstr "Promuove l'istanza locale di una risorsa multi-state allo stato master/primary" #. Tag: para #, no-c-format msgid "Return 0 on success promoteOCF Action OCF Action OCFActionpromote Actionpromote promote " msgstr "" #. Tag: para #, no-c-format msgid "demote" msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "Demote the local instance of a multi-state resource to the slave/secondary state." msgstr "Degrada l'istanza locale di una risorsa multi-state allo stato slave/secondary" #. Tag: para #, no-c-format msgid "Return 0 on success demoteOCF Action OCF Action OCFActiondemote Actiondemote demote " msgstr "" #. Tag: para #, no-c-format msgid "notify" msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "Used by the cluster to send the agent pre and post notification events telling the resource what has happened and will happen." msgstr "Utilizzato dal cluster per inviare pre e post notifiche di eventi all'agente indicando cosa sta accadendo o cosa è accaduto alla risorsa" #. Tag: para #, no-c-format msgid "Must not fail. Must exit with 0 notifyOCF Action OCF Action OCFActionnotify Actionnotify notify " msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "One action specified in the OCF specs is not currently used by the cluster:" msgstr "Un'azione definita nelle specifiche OCF non è attalmente utilizzata dal cluster" #. Tag: para #, fuzzy, no-c-format msgid "recover - a variant of the start action, this should try to recover a resource locally." msgstr "rescover - una variante dell'azione start, dovrebbe cercare di ripristinare localmente una risorsa." #. Tag: para #, fuzzy, no-c-format msgid "Remember to use ocf-tester ocf-tester to verify that your new agent complies with the OCF standard properly." msgstr "E' necessario ricordare l'utilizzo di ocf-tester per verificare che i nuovi agenti creati siano propriamente compatibili con lo standard OCF." #. Tag: title #, no-c-format msgid "How are OCF Return Codes Interpreted?" msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "The first thing the cluster does is to check the return code against the expected result. If the result does not match the expected value, then the operation is considered to have failed and recovery action is initiated." msgstr "La prima cosa che il cluster fa è controllare il codice di ritorno rispetto ai risultati attesi. Se il risultato non combacia con i valori attesi, allora l'operazione viene considerata fallita e viene avviata un'azione di ripristino." #. Tag: para #, no-c-format msgid "There are three types of failure recovery:" msgstr "Esistono tre tipi di ripristino da fallimenti:" #. Tag: title #, no-c-format msgid "Types of recovery performed by the cluster" msgstr "Tipi di ripristino effettuati dal cluster" #. Tag: entry #, no-c-format msgid "Type" msgstr "" #. Tag: entry #, no-c-format msgid "Action Taken by the Cluster" msgstr "Azione intrapresa dal cluster" #. Tag: para #, no-c-format msgid "soft" msgstr "" #. Tag: para #, no-c-format msgid "A transient error occurred" msgstr "Si è verificato un errore transitorio" #. Tag: para #, no-c-format msgid "Restart the resource or move it to a new location softOCF error OCF error OCFerrorsoft errorsoft soft " msgstr "" #. Tag: para #, no-c-format msgid "hard" msgstr "" #. Tag: para #, no-c-format msgid "A non-transient error that may be specific to the current node occurred" msgstr "Si è verificato un errore non transitorio che potrebbe essere specificamente correlato al nodo attuale" #. Tag: para #, no-c-format msgid "Move the resource elsewhere and prevent it from being retried on the current node hardOCF error OCF error OCFerrorhard errorhard hard " msgstr "" #. Tag: para #, no-c-format msgid "fatal" msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "A non-transient error that will be common to all cluster nodes (eg. a bad configuration was specified)" msgstr "Si è verificato un errore non transitorio che sarà associato a tutti i nodi del cluster (ad esempio una configurazione sbagliata)" #. Tag: para #, no-c-format msgid "Stop the resource and prevent it from being started on any cluster node fatalOCF error OCF error OCFerrorfatal errorfatal fatal " msgstr "" #. Tag: para #, no-c-format msgid "Assuming an action is considered to have failed, the following table outlines the different OCF return codes and the type of recovery the cluster will initiate when it is received." msgstr "Assumendo che l'azione sia considerata fallita, la seguente tabella evidenzia i diversi codici di ritorno OCF ed i tipi di ripristino che il cluster avvierà di conseguenza." #. Tag: title #, fuzzy, no-c-format msgid "OCF Return Codes" msgstr "OCF Return Code" #. Tag: title #, fuzzy, no-c-format msgid "OCF Return Codes and their Recovery Types" msgstr "Codici di ritorno OCF e come sono gestiti" #. Tag: entry #, no-c-format msgid "RC" msgstr "" #. Tag: entry #, no-c-format msgid "OCF Alias" msgstr "OCF Alias" #. Tag: entry #, no-c-format msgid "RT" msgstr "" #. Tag: para #, no-c-format msgid "0" msgstr "" #. Tag: para #, no-c-format msgid "OCF_SUCCESS" msgstr "" #. Tag: para #, no-c-format msgid "Success. The command completed successfully. This is the expected result for all start, stop, promote and demote commands. Return CodeOCF_SUCCESS OCF_SUCCESS Return Code0OCF_SUCCESS 0OCF_SUCCESS OCF_SUCCESS " msgstr "" #. Tag: para #, no-c-format msgid "1" msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "OCF_ERR_GENERIC" msgstr "OCF_ERR_GENERIC" #. Tag: para #, no-c-format msgid "Generic \"there was a problem\" error code. Return CodeOCF_ERR_GENERIC OCF_ERR_GENERIC Return Code1OCF_ERR_GENERIC 1OCF_ERR_GENERIC OCF_ERR_GENERIC " msgstr "" #. Tag: para #, no-c-format msgid "2" msgstr "" #. Tag: para #, no-c-format msgid "OCF_ERR_ARGS" msgstr "" #. Tag: para #, no-c-format msgid "The resource’s configuration is not valid on this machine. Eg. refers to a location/tool not found on the node. Return CodeOCF_ERR_ARGS OCF_ERR_ARGS Return Code2OCF_ERR_ARGS 2OCF_ERR_ARGS OCF_ERR_ARGS " msgstr "" #. Tag: para #, no-c-format msgid "3" msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "OCF_ERR_UNIMPLEMENTED" msgstr "OCF_ERR_UNIMPLEMENTED" #. Tag: para #, no-c-format msgid "The requested action is not implemented. Return CodeOCF_ERR_UNIMPLEMENTED OCF_ERR_UNIMPLEMENTED Return Code3OCF_ERR_UNIMPLEMENTED 3OCF_ERR_UNIMPLEMENTED OCF_ERR_UNIMPLEMENTED " msgstr "" #. Tag: para #, no-c-format msgid "4" msgstr "" #. Tag: para #, no-c-format msgid "OCF_ERR_PERM" msgstr "" #. Tag: para #, no-c-format msgid "The resource agent does not have sufficient privileges to complete the task. Return CodeOCF_ERR_PERM OCF_ERR_PERM Return Code4OCF_ERR_PERM 4OCF_ERR_PERM OCF_ERR_PERM " msgstr "" #. Tag: para #, no-c-format msgid "5" msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "OCF_ERR_INSTALLED" msgstr "OCF_ERR_INSTALLED" #. Tag: para #, no-c-format msgid "The tools required by the resource are not installed on this machine. Return CodeOCF_ERR_INSTALLED OCF_ERR_INSTALLED Return Code5OCF_ERR_INSTALLED 5OCF_ERR_INSTALLED OCF_ERR_INSTALLED " msgstr "" #. Tag: para #, no-c-format msgid "6" msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "OCF_ERR_CONFIGURED" msgstr "OCF_ERR_CONFIGURED" #. Tag: para #, no-c-format msgid "The resource’s configuration is invalid. Eg. required parameters are missing. Return CodeOCF_ERR_CONFIGURED OCF_ERR_CONFIGURED Return Code6OCF_ERR_CONFIGURED 6OCF_ERR_CONFIGURED OCF_ERR_CONFIGURED " msgstr "" #. Tag: para #, no-c-format msgid "7" msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "OCF_NOT_RUNNING" msgstr "OCF_NOT_RUNNING" #. Tag: para #, no-c-format msgid "The resource is safely stopped. The cluster will not attempt to stop a resource that returns this for any action. Return CodeOCF_NOT_RUNNING OCF_NOT_RUNNING Return Code7OCF_NOT_RUNNING 7OCF_NOT_RUNNING OCF_NOT_RUNNING " msgstr "" #. Tag: para #, no-c-format msgid "N/A" msgstr "" #. Tag: para #, no-c-format msgid "8" msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "OCF_RUNNING_MASTER" msgstr "OCF_RUNNING_MASTER" #. Tag: para #, no-c-format msgid "The resource is running in Master mode. Return CodeOCF_RUNNING_MASTER OCF_RUNNING_MASTER Return Code8OCF_RUNNING_MASTER 8OCF_RUNNING_MASTER OCF_RUNNING_MASTER " msgstr "" #. Tag: para #, no-c-format msgid "9" msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "OCF_FAILED_MASTER" msgstr "OCF_FAILED_MASTER" #. Tag: para #, no-c-format msgid "The resource is in Master mode but has failed. The resource will be demoted, stopped and then started (and possibly promoted) again. Return CodeOCF_FAILED_MASTER OCF_FAILED_MASTER Return Code9OCF_FAILED_MASTER 9OCF_FAILED_MASTER OCF_FAILED_MASTER " msgstr "" #. Tag: para #, no-c-format msgid "other" msgstr "" #. Tag: para #, no-c-format msgid "NA" msgstr "" #. Tag: para #, no-c-format msgid "Custom error code. Return Codeother other " msgstr "" #. Tag: para #, no-c-format msgid "Although counterintuitive, even actions that return 0 (aka. OCF_SUCCESS) can be considered to have failed." msgstr "" #. Tag: title #, no-c-format msgid "Exceptions" msgstr "Eccezioni" #. Tag: para #, no-c-format msgid "Non-recurring monitor actions (probes) that find a resource active (or in Master mode) will not result in recovery action unless it is also found active elsewhere" msgstr "Azioni di monitor non ricorrenti (probes) che trovano una risorsa attiva (o in modalità Master) non forzeranno un ripristino a meno che non trovino la risorsa attiva altrove" #. Tag: para #, fuzzy, no-c-format msgid "The recovery action taken when a resource is found active more than once is determined by the multiple-active property of the resource" msgstr "L'azione di ripristino intrapresa quando una risorsa viene trovata attiva più di una volta è determinata dalla proprietà multiple-active" #. Tag: para #, fuzzy, no-c-format msgid "Recurring actions that return OCF_ERR_UNIMPLEMENTED do not cause any type of recovery" msgstr "Azioni ricorrenti che restituiscono OCF_ERR_UNIMPLEMENTED non forzano alcun tipo di ripristino" #~ msgid "start" #~ msgstr "start" #~ msgid "Return 0 on success and an appropriate error code otherwise. Must not report success until the resource is fully active." #~ msgstr "Restituisce 0 in caso di successo oppure un appropriato codice di errore. Non deve riportare successo finché la risorsa non è totalmente attiva." #~ msgid "stop" #~ msgstr "stop" #~ msgid "Return 0 on success and an appropriate error code otherwise. Must not report success until the resource is fully stopped." #~ msgstr "Restituisce 0 in caso di successo oppure un appropriato codice di errore. Non deve riportare successo finché la risorsa non è completamente stoppata." #~ msgid "monitor" #~ msgstr "monitor" #~ msgid "Exit 0 if the resource is running, 7 if it is stopped and anything else if it is failed." #~ msgstr "Restituisce 0 se la risorsa sta funzionando, 7 se è stoppata e qualsiasi altro valore se è fallita." #~ msgid "meta-data" #~ msgstr "meta-data" #~ msgid "Provide information about this resource as an XML snippet. Exit with 0." #~ msgstr "Fornisce informazioni in merito a questa risorsa in forma di estr atto di XML. Restituisce 0." #~ msgid "validate-all" #~ msgstr "validate-all" #~ msgid "Exit with 0 if parameters are valid, 2 if not valid, 6 if resource is not configured." #~ msgstr "Restituisce 0 se i parametri sono validi, 2 se non sono validi, 6 se la risorsa non è configurata." #~ msgid "promote" #~ msgstr "promote" #~ msgid "Return 0 on success" #~ msgstr "Restituisce 0 in caso di successo" #~ msgid "demote" #~ msgstr "demote" #~ msgid "notify" #~ msgstr "notify" #~ msgid "Must not fail. Must exit 0" #~ msgstr "Non può fallire. Deve restituire 0" #~ msgid "How Does the Cluster Interpret the OCF Return Codes?" #~ msgstr "Il cluster come interpreta i codici di ritorno OCF?" #~ msgid "Recovery Type" #~ msgstr "Tipo di ripristino" #~ msgid "soft" #~ msgstr "soft" #~ msgid "Restart the resource or move it to a new location" #~ msgstr "Riavvia la risora o la sposta in una nuova posizione" #~ msgid "hard" #~ msgstr "hard" #~ msgid "Move the resource elsewhere and prevent it from being retried on the current node" #~ msgstr "Sposta altrove la risorsa e previene che questa venga riavviata sul nodo attuale" #~ msgid "fatal" #~ msgstr "fatal" #~ msgid "Stop the resource and prevent it from being started on any cluster node" #~ msgstr "Ferma la risorsa ed evita che venga avviata da qualsiasi nodo del cluster" #~ msgid "0" #~ msgstr "0" #~ msgid "OCF_SUCCESS" #~ msgstr "OCF_SUCCESS" #~ msgid "Success. The command complete successfully. This is the expected result for all start, stop, promote and demote commands." #~ msgstr "Successo. Il comando è stato completato con successo. E' il risultato atteso per tutte le operazioni di start, stop, promote e demote." #~ msgid "1" #~ msgstr "1" #~ msgid "Generic "there was a problem" error code." #~ msgstr "Codice di errore generico "c'è stato un problema"" #~ msgid "2" #~ msgstr "2" #~ msgid "OCF_ERR_ARGS" #~ msgstr "OCF_ERR_ARGS" #~ msgid "The resource's configuration is not valid on this machine. Eg. Refers to a location/tool not found on the node." #~ msgstr "La configurazione della risorsa su questa macchina è invalida. Ad esempio riferisce ad uno strumento/posizione non trovato all'interno del nodo." #~ msgid "3" #~ msgstr "3" #~ msgid "The requested action is not implemented." #~ msgstr "L'azione richiesta non è implementata." #~ msgid "4" #~ msgstr "4" #~ msgid "OCF_ERR_PERM" #~ msgstr "OCF_ERR_PERM" #~ msgid "The resource agent does not have sufficient privileges to complete the task." #~ msgstr "L'agente della risorsa non ha privilegi sufficienti per completare l'operazione." #~ msgid "5" #~ msgstr "5" #~ msgid "The tools required by the resource are not installed on this machine." #~ msgstr "I tool richiesti dalla risorsa non sono installati su questa macchina." #~ msgid "6" #~ msgstr "6" #~ msgid "The resource's configuration is invalid. Eg. A required parameters are missing." #~ msgstr "La configurazione della risorsa è invalida. Ad esempio manca un parametro richiesto." #~ msgid "7" #~ msgstr "7" #~ msgid "The resource is safely stopped. The cluster will not attempt to stop a resource that returns this for any action." #~ msgstr "La risosra è ferma in sicurezza. Il cluster non cercherà di fermare una risorsa con questo codice di ritorno per qualsiasi azione." #~ msgid "N/A" #~ msgstr "N/A" #~ msgid "8" #~ msgstr "8" #~ msgid "The resource is running in Master mode." #~ msgstr "La risorsa sta funzionando in modalità Master." #~ msgid "9" #~ msgstr "9" #~ msgid "The resource is in Master mode but has failed. The resource will be demoted, stopped and then started (and possibly promoted) again." #~ msgstr "La risorsa è in modalità Master, ma ha fallito. La risorsa verrà degradata, fermata e quindi avviata (e possibilmente promossa) di nuovo." #~ msgid "other" #~ msgstr "other" #~ msgid "NA" #~ msgstr "NA" #~ msgid "Custom error code." #~ msgstr "Codice di errore personalizzato." #~ msgid "Although counter intuitive, even actions that return 0 (aka. OCF_SUCCESS) can be considered to have failed. This can happen when a resource that is expected to be in the Master state is found running as a Slave, or when a resource is found active on multiple machines.." #~ msgstr "E' facilmente intuibile come anche le azioni che restituiscono 0 (quindi OCF_SUCCESS) possono essere considerate fallite. Questo può succedere quando una risorsa attesa in stato Master venga trovata in realtà attiva ma in stato Slave, oppure quando una risorsa viene trovata attiva su più macchine." pacemaker-master/doc/Pacemaker_Explained/it-IT/Ap-Samples.po000066400000000000000000000305571217637305600242010ustar00rootroot00000000000000# # AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: 0\n" "POT-Creation-Date: 2012-10-17T05:19:01\n" "PO-Revision-Date: 2011-06-07 11:04+0100\n" "Last-Translator: RaSca \n" "Language-Team: None\n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. Tag: title #, no-c-format msgid "Sample Configurations" msgstr "Configurazioni di esempio" #. Tag: title #, no-c-format msgid "Empty" msgstr "" #. Tag: title #, no-c-format msgid "An Empty Configuration" msgstr "Una configurazione vuota" #. Tag: programlisting #, fuzzy, no-c-format msgid "" "<cib admin_epoch=\"0\" epoch=\"0\" num_updates=\"0\" have-quorum=\"false\">\n" " <configuration>\n" " <crm_config/>\n" " <nodes/>\n" " <resources/>\n" " <constraints/>\n" " </configuration>\n" " <status/>\n" "</cib>" msgstr "" "\n" "\n" " <cib admin_epoch="0" epoch="0" num_updates="0" have-quorum="false">\n" " <configuration>\n" " <crm_config/>\n" " <nodes/>\n" " <resources/>\n" " <constraints/>\n" " </configuration>\n" " <status/>\n" " </cib>\n" "\n" "\t" #. Tag: title #, no-c-format msgid "Simple" msgstr "" #. Tag: title #, fuzzy, no-c-format msgid "Simple Configuration - 2 nodes, some cluster options and a resource" msgstr "2 nodi, alcune opzioni del cluster ed una risorsa" #. Tag: programlisting #, fuzzy, no-c-format msgid "" "<cib admin_epoch=\"0\" epoch=\"1\" num_updates=\"0\" have-quorum=\"false\"\n" " validate-with=\"pacemaker-1.0\">\n" " <configuration>\n" " <crm_config>\n" " <nvpair id=\"option-1\" name=\"symmetric-cluster\" value=\"true\"/>\n" " <nvpair id=\"option-2\" name=\"no-quorum-policy\" value=\"stop\"/>\n" " </crm_config>\n" " <op_defaults>\n" " <nvpair id=\"op-default-1\" name=\"timeout\" value=\"30s\"/>\n" " </op_defaults>\n" " <rsc_defaults>\n" " <nvpair id=\"rsc-default-1\" name=\"resource-stickiness\" value=\"100\"/>\n" " <nvpair id=\"rsc-default-2\" name=\"migration-threshold\" value=\"10\"/>\n" " </rsc_defaults>\n" " <nodes>\n" " <node id=\"xxx\" uname=\"c001n01\" type=\"normal\"/>\n" " <node id=\"yyy\" uname=\"c001n02\" type=\"normal\"/>\n" " </nodes>\n" " <resources>\n" " <primitive id=\"myAddr\" class=\"ocf\" provider=\"heartbeat\" type=\"IPaddr\">\n" " <operations>\n" " <op id=\"myAddr-monitor\" name=\"monitor\" interval=\"300s\"/>\n" " </operations>\n" " <instance_attributes>\n" " <nvpair name=\"ip\" value=\"10.0.200.30\"/>\n" " </instance_attributes>\n" " </primitive>\n" " </resources>\n" " <constraints>\n" " <rsc_location id=\"myAddr-prefer\" rsc=\"myAddr\" node=\"c001n01\" score=\"INFINITY\"/>\n" " </constraints>\n" " </configuration>\n" " <status/>\n" "</cib>" msgstr "" " <rsc_defaults>\n" " <nvpair id="rsc-default-1" name="resource-stickiness" value="100"/>\n" " <nvpair id="rsc-default-2" name="migration-threshold" value="10"/>\n" " </rsc_defaults>\n" " <nodes>\n" " <node id="xxx" uname="c001n01" type="normal"/>\n" " <node id="yyy" uname="c001n02" type="normal"/>\n" " </nodes>\n" " <resources>\n" " <primitive id="myAddr" class="ocf" provider="heartbeat" type="IPaddr">\n" " <operations>\n" " <op id="myAddr-monitor" name="monitor" interval="300s"/>\n" " </operations>\n" " <instance_attributes>\n" " <nvpair name="ip" value="10.0.200.30"/>\n" " </instance_attributes>\n" " </primitive>\n" " </resources>\n" " <constraints>\n" " <rsc_location id="myAddr-prefer" rsc="myAddr" node="c001n01" score="INFINITY"/>\n" " </constraints>\n" " </configuration>\n" " <status/>\n" " </cib>\n" "\n" "\t" #. Tag: para #, fuzzy, no-c-format msgid "In this example, we have one resource (an IP address) that we check every five minutes and will run on host c001n01 until either the resource fails 10 times or the host shuts down." msgstr "In questo esempio esiste una risorsa (un indirizzo IP) che viene controllato ogni cinque minuti. Verrà lanciata sull'host c001n01 finché o la risorsa fallirà 10 volte o l'host si spegnerà." #. Tag: title #, fuzzy, no-c-format msgid "Advanced Configuration" msgstr "Una configurazione avanzata" #. Tag: title #, fuzzy, no-c-format msgid "Advanced configuration - groups and clones with stonith" msgstr "Gruppi e cloni con STONITH" #. Tag: programlisting #, fuzzy, no-c-format msgid "" "<cib admin_epoch=\"0\" epoch=\"1\" num_updates=\"0\" have-quorum=\"false\"\n" " validate-with=\"pacemaker-1.0\">\n" " <configuration>\n" " <crm_config>\n" " <nvpair id=\"option-1\" name=\"symmetric-cluster\" value=\"true\"/>\n" " <nvpair id=\"option-2\" name=\"no-quorum-policy\" value=\"stop\"/>\n" " <nvpair id=\"option-3\" name=\"stonith-enabled\" value=\"true\"/>\n" " </crm_config>\n" " <op_defaults>\n" " <nvpair id=\"op-default-1\" name=\"timeout\" value=\"30s\"/>\n" " </op_defaults>\n" " <rsc_defaults>\n" " <nvpair id=\"rsc-default-1\" name=\"resource-stickiness\" value=\"100\"/>\n" " <nvpair id=\"rsc-default-2\" name=\"migration-threshold\" value=\"10\"/>\n" " </rsc_defaults>\n" " <nodes>\n" " <node id=\"xxx\" uname=\"c001n01\" type=\"normal\"/>\n" " <node id=\"yyy\" uname=\"c001n02\" type=\"normal\"/>\n" " <node id=\"zzz\" uname=\"c001n03\" type=\"normal\"/>\n" " </nodes>\n" " <resources>\n" " <primitive id=\"myAddr\" class=\"ocf\" provider=\"heartbeat\" type=\"IPaddr\">\n" " <operations>\n" " <op id=\"myAddr-monitor\" name=\"monitor\" interval=\"300s\"/>\n" " </operations>\n" " <instance_attributes>\n" " <nvpair name=\"ip\" value=\"10.0.200.30\"/>\n" " </instance_attributes>\n" " </primitive>\n" " <group id=\"myGroup\">\n" " <primitive id=\"database\" class=\"lsb\" type=\"oracle\">\n" " <operations>\n" " <op id=\"database-monitor\" name=\"monitor\" interval=\"300s\"/>\n" " </operations>\n" " </primitive>\n" " <primitive id=\"webserver\" class=\"lsb\" type=\"apache\">\n" " <operations>\n" " <op id=\"webserver-monitor\" name=\"monitor\" interval=\"300s\"/>\n" " </operations>\n" " </primitive>\n" " </group>\n" " <clone id=\"STONITH\">\n" " <meta_attributes id=\"stonith-options\">\n" " <nvpair id=\"stonith-option-1\" name=\"globally-unique\" value=\"false\"/>\n" " </meta_attributes>\n" " <primitive id=\"stonithclone\" class=\"stonith\" type=\"external/ssh\">\n" " <operations>\n" " <op id=\"stonith-op-mon\" name=\"monitor\" interval=\"5s\"/>\n" " </operations>\n" " <instance_attributes id=\"stonith-attrs\">\n" " <nvpair id=\"stonith-attr-1\" name=\"hostlist\" value=\"c001n01,c001n02\"/>\n" " </instance_attributes>\n" " </primitive>\n" " </clone>\n" " </resources>\n" " <constraints>\n" " <rsc_location id=\"myAddr-prefer\" rsc=\"myAddr\" node=\"c001n01\"\n" " score=\"INFINITY\"/>\n" " <rsc_colocation id=\"group-with-ip\" rsc=\"myGroup\" with-rsc=\"myAddr\"\n" " score=\"INFINITY\"/>\n" " </constraints>\n" " </configuration>\n" " <status/>\n" "</cib>" msgstr "" "\n" "\n" " <cib admin_epoch="0" epoch="1" num_updates="0" have-quorum="false" validate-with="pacemaker-1.0">\n" " <configuration>\n" " <crm_config>\n" " <nvpair id="option-1" name="symmetric-cluster" value="true"/>\n" " <nvpair id="option-2" name="no-quorum-policy" value="stop"/>\n" " <nvpair id="option-3" name="stonith-enabled" value="true"/>\n" " </crm_config>\n" " <op_defaults>\n" " <nvpair id="op-default-1" name="timeout" value="30s"/>\n" " </op_defaults>\n" " <rsc_defaults>\n" " <nvpair id="rsc-default-1" name="resource-stickiness" value="100"/>\n" " <nvpair id="rsc-default-2" name="migration-threshold" value="10"/>\n" " </rsc_defaults>\n" " <nodes>\n" " <node id="xxx" uname="c001n01" type="normal"/>\n" " <node id="yyy" uname="c001n02" type="normal"/>\n" " <node id="zzz" uname="c001n03" type="normal"/>\n" " </nodes>\n" " <resources>\n" " <primitive id="myAddr" class="ocf" provider="heartbeat" type="IPaddr">\n" " <operations>\n" " <op id="myAddr-monitor" name="monitor" interval="300s"/>\n" " </operations>\n" " <instance_attributes>\n" " <nvpair name="ip" value="10.0.200.30"/>\n" " </instance_attributes>\n" " </primitive>\n" " <group id="myGroup">\n" " <primitive id="database" class="lsb" type="oracle">\n" " <operations>\n" " <op id="database-monitor" name="monitor" interval="300s"/>\n" " </operations>\n" " </primitive>\n" " <primitive id="webserver" class="lsb" type="apache">\n" " <operations>\n" " <op id="webserver-monitor" name="monitor" interval="300s"/>\n" " </operations>\n" " </primitive>\n" " </group>\n" " <clone id="STONITH">\n" " <meta_attributes id="stonith-options">\n" " <nvpair id="stonith-option-1" name="globally-unique" value="false"/>\n" " </meta_attributes>\n" " <primitive id="stonithclone" class="stonith" type="external/ssh">\n" " <operations>\n" " <op id="stonith-op-mon" name="monitor" interval="5s"/>\n" " </operations>\n" " <instance_attributes id="stonith-attrs">\n" " <nvpair id="stonith-attr-1" name="hostlist" value="c001n01,c001n02"/>\n" " </instance_attributes>\n" " </primitive>\n" " </clone>\n" " </resources>\n" " <constraints>\n" " <rsc_location id="myAddr-prefer" rsc="myAddr" node="c001n01" score="INFINITY"/>\n" " <rsc_colocation id="group-with-ip" rsc="myGroup" with-rsc="myAddr" score="INFINITY"/>\n" " </constraints>\n" " </configuration>\n" " <status/>\n" " </cib>\n" "\n" "\t" #~ msgid "An empty configuration" #~ msgstr "Una configurazione vuota" #~ msgid "A Simple Configuration" #~ msgstr "Una semplice configurazione" pacemaker-master/doc/Pacemaker_Explained/it-IT/Ap-Upgrade-Config.po000066400000000000000000000322271217637305600253630ustar00rootroot00000000000000# # AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: 0\n" "POT-Creation-Date: 2012-10-17T05:19:01\n" "PO-Revision-Date: 2011-05-05 15:32+0100\n" "Last-Translator: RaSca \n" "Language-Team: None\n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. Tag: title #, no-c-format msgid "Upgrading the Configuration from 0.6" msgstr "Aggiornare la configurazione dalla versione 0.6" #. Tag: title #, no-c-format msgid "Preparation" msgstr "Preparazione" #. Tag: para #, no-c-format msgid " Upgrading the Configuration ConfigurationUpgrading Upgrading " msgstr "" #. Tag: para #, no-c-format msgid " DownloadDTD DTD DTDDownload Download " msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "Download the latest DTD and ensure your configuration validates." msgstr "Scaricare l'ultimo DTD da ed assicurarsi che la propria configurazione venga validata." #. Tag: title #, no-c-format msgid "Perform the upgrade" msgstr "Effettuale l'aggiornamento" #. Tag: title #, no-c-format msgid "Upgrade the software" msgstr "Aggiornamento del software" #. Tag: para #, no-c-format msgid "Refer to the appendix: " msgstr "Riferirsi all'appendice " #. Tag: title #, no-c-format msgid "Upgrade the Configuration" msgstr "Aggiornare la configurazione" #. Tag: para #, no-c-format msgid "As XML is not the friendliest of languages, it is common for cluster administrators to have scripted some of their activities. In such cases, it is likely that those scripts will not work with the new 1.0 syntax." msgstr "Dato che XM non è il più amichevole dei linguaggi è pratica comune per gli amministratori del cluster creare script per le proprie attività. In questi casi c'è da aspettarsi che tali script non funzionino con la sintassi della versione 1.0." #. Tag: para #, no-c-format msgid "In order to support such environments, it is actually possible to continue using the old 0.6 syntax." msgstr "Al fine di supportare tali ambienti, è possibile continuare ad utilizzare la vecchia sintassi 0.6." #. Tag: para #, fuzzy, no-c-format msgid "The downside is, however, that not all the new features will be available and there is a performance impact since the cluster must do a non-persistent configuration upgrade before each transition. So while using the old syntax is possible, it is not advisable to continue using it indefinitely." msgstr "Gli aspetti negativi sono che non tutte le nuove funzionalità saranno disponibili e si verificherà un impatto sulle performance, visto che il cluster deve effettuare una aggiornamento di configurazione non persistente prima di ogni transizione. Quindi sebbene l'utilizzo della vecchia sintassi è consentito, non è consigliabile utilizzarlo continuativamente." #. Tag: para #, no-c-format msgid "Even if you wish to continue using the old syntax, it is advisable to follow the upgrade procedure to ensure that the cluster is able to use your existing configuration (since it will perform much the same task internally)." msgstr "Anche se il proprio desiderio è quello di utilizzare la vecchia sintassi, è consigliabile seguire la procedura di upgrade per assicurarsi che il cluster sia capace di utilizzare la configurazione attuale (visto che internamente effettuerà praticamente la stessa operazione)." #. Tag: para #, no-c-format msgid "Create a shadow copy to work with" msgstr "Creare di una copia shadow del proprio lavoro con" #. Tag: programlisting #, fuzzy, no-c-format msgid "# crm_shadow --create upgrade06" msgstr "crm_shadow --create upgrade06" #. Tag: para #, no-c-format msgid "Verify the configuration is valid ConfigurationVerify Verify VerifyConfiguration Configuration " msgstr "" #. Tag: programlisting #, fuzzy, no-c-format msgid "# crm_verify --live-check" msgstr "crm_verify --live-check" #. Tag: para #, no-c-format msgid "Fix any errors or warnings" msgstr "Correggere eventuali errori o allerta" #. Tag: para #, fuzzy, no-c-format msgid "Perform the upgrade:" msgstr "Effettuale l'aggiornamento" #. Tag: programlisting #, fuzzy, no-c-format msgid "# cibadmin --upgrade" msgstr "cibadmin --upgrade" #. Tag: para #, fuzzy, no-c-format msgid "If this step fails, there are three main possibilities:" msgstr "Se questo passo fallisce il motivo potrebbe essere uno fra questi" #. Tag: para #, no-c-format msgid "The configuration was not valid to start with - go back to step 2" msgstr "La configurazione non è valida per l'avvio - tornare al passo 2" #. Tag: para #, fuzzy, no-c-format msgid "The transformation failed - report a bug or email the project" msgstr "La trasformazione è fallita - segnalare un bug o scrivere un'email al progetto presso pacemaker@oss.clusterlabs.org" #. Tag: para #, fuzzy, no-c-format msgid "The transformation was successful but produced an invalid result The most common reason is ID values being repeated or invalid. Pacemaker 1.0 is much stricter regarding this type of validation. " msgstr "La trasformazione ha avuto successo, ma ha prodotto risultati invalidi La ragione più comune è che i valori di ID siano ripetuti o invalidi. Pacemaker 1.0 è molto più rigido riguardo a questi tipi di validazione " #. Tag: para #, fuzzy, no-c-format msgid "If the result of the transformation is invalid, you may see a number of errors from the validation library. If these are not helpful, visit http://clusterlabs.org/wiki/Validation_FAQ and/or try the procedure described below under " msgstr "Se il risultato della trasformazione è invalido, si potrebbero notare diversi errori dalla libreria di validazione. Se questi non risultano essere d'aiuto vedere e/o provare la procedura descritta più avanti sotto ." #. Tag: para #, no-c-format msgid "Check the changes" msgstr "Verificare le modifiche" #. Tag: programlisting #, fuzzy, no-c-format msgid "# crm_shadow --diff" msgstr "crm_shadow --diff" #. Tag: para #, no-c-format msgid "If at this point there is anything about the upgrade that you wish to fine-tune (for example, to change some of the automatic IDs) now is the time to do so. Since the shadow configuration is not in use by the cluster, it is safe to edit the file manually:" msgstr "Se a questo punto si necessita di approfondire altro in merio all'aggioramento (ad esempio cambiare qualcuno degli ID automatici) questo è il momento. Dal momento che la configurazione shadow non è utilizzata dal cluster è possibile modificare il file manualmenee." #. Tag: programlisting #, fuzzy, no-c-format msgid "# crm_shadow --edit" msgstr "crm_shadow --edit" #. Tag: para #, fuzzy, no-c-format msgid "This will open the configuration in your favorite editor (whichever is specified by the standard $EDITOR environment variable)" msgstr "Aprirà la configurazione nel proprio editor preferito (o in quello specificato alla variabile d'abiente) EDITOR" #. Tag: para #, no-c-format msgid "Preview how the cluster will react" msgstr "Presenterà un'anteprima delle azioni del cluster" #. Tag: para #, no-c-format msgid "Test what the cluster will do when you upload the new configuration" msgstr "Controlla quello che fa il cluster quando viene caricata la nuova configurazione" #. Tag: programlisting #, no-c-format msgid "" "# crm_simulate --live-check --save-dotfile upgrade06.dot -S\n" "# graphviz upgrade06.dot" msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "Verify that either no resource actions will occur or that you are happy with any that are scheduled. If the output contains actions you do not expect (possibly due to changes to the score calculations), you may need to make further manual changes. See for further details on how to interpret the output of crm_simulate" msgstr "Verifica che non avvenga nessuna delle azioni relative alle risorse o e che quelle schedulate rispettino le proprioe intenzioni. Se l'output contiene azioni inattese (verosimilmente sui punteggi calcolati) potrebbero essere necessari ulteriori modifiche manuali. Vedere per altri ettagli su come interpretare più ptest." #. Tag: para #, no-c-format msgid "Upload the changes" msgstr "Applicare le modifiche" #. Tag: programlisting #, fuzzy, no-c-format msgid "# crm_shadow --commit upgrade06 --force" msgstr "crm_shadow --commit upgrade06 --force" #. Tag: para #, no-c-format msgid "If this step fails, something really strange has occurred. You should report a bug." msgstr "Se il passo fallisce, p accaduto qualcosa di veramente strano. Biosgnerebbe quindi riportare un Bug" #. Tag: title #, no-c-format msgid "Manually Upgrading the Configuration" msgstr "Aggiornamento manuale della configurazione" #. Tag: para #, no-c-format msgid " ConfigurationUpgrade manually Upgrade manually It is also possible to perform the configuration upgrade steps manually. To do this" msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "Locate the upgrade06.xsl conversion script or download the latest version from Git" msgstr "Recuperare lo script di conversione upgrade06.xsl oppure scaricare l'ultima versione da version control" #. Tag: para #, no-c-format msgid "Convert the XML blob: XMLConvert Convert " msgstr "" #. Tag: programlisting #, no-c-format msgid "# xsltproc /path/to/upgrade06.xsl config06.xml > config10.xml" msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "Locate the pacemaker.rng script." msgstr "Individuare lo script pacemaker.rng." #. Tag: para #, no-c-format msgid "Check the XML validity: Validate Configuration ConfigurationValidate XML Validate XML " msgstr "" #. Tag: programlisting #, fuzzy, no-c-format msgid "# xmllint --relaxng /path/to/pacemaker.rng config10.xml" msgstr "xmllint --relaxng /path/tp/pacemaker.rng config10.xml" #. Tag: para #, no-c-format msgid "The advantage of this method is that it can be performed without the cluster running and any validation errors should be more informative (despite being generated by the same library!) since they include line numbers." msgstr "Il vantaggio di questo metodo è che può essere eseguito senza che il cluster sia attivo e qualsiasi errore di validazione dovrebbe risultare esplicativo (sebbene generato dalla stessa libreria!) dato che ciascuna riga è numerata." #~ msgid "Verify the configuration is valid" #~ msgstr "Verificare la validità della configurazione" #~ msgid "ptest -VVVVV --live-check --save-dotfile upgrade06.dot" #~ msgstr "ptest -VVVVV --live-check --save-dotfile upgrade06.dot" #~ msgid "graphviz upgrade06.dot" #~ msgstr "graphviz upgrade06.dot" #~ msgid "It is also possible to perform the configuration upgrade steps manually. To do this" #~ msgstr "E' inoltre possibile eseguire la procedura di aggiornamento manualmente. Per farlo" #~ msgid "xsltproc /path/tp/upgrade06.xsl config06.xml > config10.xml" #~ msgstr "xsltproc /path/tp/upgrade06.xsl config06.xml > config10.xml" pacemaker-master/doc/Pacemaker_Explained/it-IT/Ap-Upgrade.po000066400000000000000000000367061217637305600241660ustar00rootroot00000000000000# # AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: 0\n" "POT-Creation-Date: 2012-10-17T05:19:01\n" "PO-Revision-Date: 2011-05-04 11:11+0100\n" "Last-Translator: RaSca \n" "Language-Team: None\n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. Tag: title #, no-c-format msgid "Upgrading Cluster Software" msgstr "Aggiornare il software del cluster" #. Tag: title #, no-c-format msgid "Version Compatibility" msgstr "Compatibilità delle versioni" #. Tag: para #, fuzzy, no-c-format msgid "When releasing newer versions we take care to make sure we are backwards compatible with older versions. While you will always be able to upgrade from version x to x+1, in order to continue to produce high quality software it may occasionally be necessary to drop compatibility with older versions." msgstr "Quando viene rilasciata una nuova versione viene posta estrema attenzione alla compatibilità con le versioni passate. Mentre sarà sempre possibile aggiornare dalla versione X alla X+1, la compatibilità con le versioni più vecchie, per garantire sempre software di alta qualità, potrebbe occasionalmente essere rimossa." #. Tag: para #, no-c-format msgid "There will always be an upgrade path from any series-2 release to any other series-2 release." msgstr "Ci sarà sempre percorso di aggiornamento da qualsiasi versione serie-2 a qualsiasi altra versione serie-2." #. Tag: para #, fuzzy, no-c-format msgid "There are three approaches to upgrading your cluster software:" msgstr "Esistono tre approcci per aggiornare il proprio software cluster" #. Tag: para #, no-c-format msgid "Complete Cluster Shutdown" msgstr "Completo spegnimento del cluster" #. Tag: para #, no-c-format msgid "Rolling (node by node)" msgstr "Rolling (nodo dopo nodo)" #. Tag: para #, no-c-format msgid "Disconnect and Reattach" msgstr "Disconnessione e riaggancio" #. Tag: para #, no-c-format msgid "Each method has advantages and disadvantages, some of which are listed in the table below, and you should chose the one most appropriate to your needs." msgstr "Ogni metodo ha vantaggi e svantaggi, alcuni dei quali sono elencati nella tabella sotto, ed è necessario scegliere l'approccio più adatto alle proprie esigenze." #. Tag: title #, no-c-format msgid "Summary of Upgrade Methodologies" msgstr "Riepilogo delle metodologie di aggiornamento" #. Tag: entry #, no-c-format msgid "Type" msgstr "Tipo" #. Tag: entry #, no-c-format msgid "Available between all software versions" msgstr "Disponibile fra tutte le versioni del software" #. Tag: entry #, no-c-format msgid "Service Outage During Upgrade" msgstr "Interruzione del servizio in fase di aggiornamento" #. Tag: entry #, no-c-format msgid "Service Recovery During Upgrade" msgstr "Ripristino del servizio in fase di aggiornamento" #. Tag: entry #, no-c-format msgid "Exercises Failover Logic/Configuration" msgstr "Esercizi di Logica Di Failover/Configurazione" #. Tag: entry #, fuzzy, no-c-format msgid "Allows change of cluster stack type ClusterSwitching between Stacks Switching between Stacks Changing Cluster Stack For example, switching from Heartbeat to Corosync. Consult the Heartbeat or Corosync documentation to see if upgrading them to a newer version is also supported. " msgstr "Consente cambiamenti nel tipo di cluster stack Ad esempio, lo switch da Heartbeat a Corosync. Consultate la documentazione di Heartbeat e Corosync per vedere se l'aggiornamento ad una nuova versione è supportato " #. Tag: para #, no-c-format msgid "Shutdown UpgradeShutdown Shutdown Shutdown Upgrade " msgstr "" #. Tag: para #, no-c-format msgid "yes" msgstr "sì" #. Tag: para #, no-c-format msgid "always" msgstr "sempre" #. Tag: para #, no-c-format msgid "N/A" msgstr "N/A" #. Tag: para #, no-c-format msgid "no" msgstr "no" #. Tag: para #, no-c-format msgid "Rolling UpgradeRolling Rolling Rolling Upgrade " msgstr "" #. Tag: para #, no-c-format msgid "Reattach UpgradeReattach Reattach Reattach Upgrade " msgstr "" #. Tag: para #, no-c-format msgid "only due to failure" msgstr "solo in seguito a fallimenti" #. Tag: para #, no-c-format msgid "In this scenario one shuts down all cluster nodes and resources and upgrades all the nodes before restarting the cluster." msgstr "In questo scenario tutti i nodi del cluster e le risorse vengono spenti, vengono aggiornati tutti i nodi prima di riattivare il cluster." #. Tag: title #, no-c-format msgid "Procedure" msgstr "Procedura" #. Tag: para #, no-c-format msgid "On each node:" msgstr "Su ciascun nodo:" #. Tag: para #, no-c-format msgid "Shutdown the cluster stack (Heartbeat or Corosync)" msgstr "Spegnimento dello stack del cluster (Heartbeat o Corosync)" #. Tag: para #, no-c-format msgid "Upgrade the Pacemaker software. This may also include upgrading the cluster stack and/or the underlying operating system." msgstr "Aggiornamento del software Pacemaker. Questo potrebbe includere l'aggiornamento dello stack del cluster e/o del sistema operativo." #. Tag: para #, fuzzy, no-c-format msgid "Check the configuration manually or with the crm_verify tool if available." msgstr "Controllo manuale della configurazione o attraverso crm_verify se disponibile." #. Tag: para #, no-c-format msgid "Start the cluster stack. This can be either Corosync or Heartbeat and does not need to be the same as the previous cluster stack." msgstr "Avvio dello stack del cluster. Questo può essere Corosync o Heartbeat e non necessità di essere lo stesso stack precedentemente utilizzato." #. Tag: para #, no-c-format msgid "In this scenario each node is removed from the cluster, upgraded and then brought back online until all nodes are running the newest version." msgstr "In questo scenario ogni nodo viene rimosso dal cluster, aggiornato e riportato online finché tutti i nodi stanno funzionando con la nuova versione." #. Tag: para #, fuzzy, no-c-format msgid "This method is currently broken between Pacemaker 0.6.x and 1.0.x." msgstr "Questo metodo attualmente non funziona da Pacemaker 0.6.x a 1.0.x" #. Tag: para #, fuzzy, no-c-format msgid "Measures have been put into place to ensure rolling upgrades always work for versions after 1.0.0. Please try one of the other upgrade strategies. Detach/Reattach is a particularly good option for most people." msgstr "Sono state messe in atto misure per assicurarsi che gli aggiornamenti di tipo rolling funzionino sempre per versioni successive alla 1.0.0. Se ci sarà abbastanza richiesta la riparazione della compatibilità da 0.6 a 1.0 verrà affrontata. Altrimenti, sarà necessario utilizzare una delle altre soluzioni di upgrade. L'opzione Detach/Reattach risulta ottimale per diverse persone." #. Tag: para #, no-c-format msgid "On each node: . Shutdown the cluster stack (Heartbeat or Corosync) . Upgrade the Pacemaker software. This may also include upgrading the cluster stack and/or the underlying operating system. .. On the first node, check the configuration manually or with the crm_verify tool if available. .. Start the cluster stack." msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "+ This must be the same type of cluster stack (Corosync or Heartbeat) that the rest of the cluster is using. Upgrading Corosync/Heartbeat may also be possible, please consult the documentation for those projects to see if the two versions will be compatible." msgstr "Avvio dello stack del cluster. Questo deve essere lo stesso tipo di stack (Corosync o Heartbeat) che il resto del cluster sta usando. Potrebbe anche essere possibile aggiornare Corosync/Heartbeat, verificare consultando la documentazione di questi progetti che le due versioni siano compatibili." #. Tag: para #, fuzzy, no-c-format msgid "+ .. Repeat for each node in the cluster." msgstr "Ripetere per ciascun nodo del cluster" #. Tag: title #, no-c-format msgid "Version Compatibility Table" msgstr "Tabella della compatibilità delle versioni" #. Tag: entry #, no-c-format msgid "Version being Installed" msgstr "Versione da installare" #. Tag: entry #, no-c-format msgid "Oldest Compatible Version" msgstr "Ultima versione compatibile" #. Tag: para #, no-c-format msgid "Pacemaker 1.0.x" msgstr "Pacemaker 1.0.x" #. Tag: para #, no-c-format msgid "Pacemaker 1.0.0" msgstr "Pacemaker 1.0.0" #. Tag: para #, no-c-format msgid "Pacemaker 0.7.x" msgstr "Pacemaker 0.7.x" #. Tag: para #, no-c-format msgid "Pacemaker 0.6 or Heartbeat 2.1.3" msgstr "Pacemaker 0.6 o Heartbeat 2.1.3" #. Tag: para #, no-c-format msgid "Pacemaker 0.6.x" msgstr "Pacemaker 0.6.x" #. Tag: para #, no-c-format msgid "Heartbeat 2.0.8" msgstr "Heartbeat 2.0.8" #. Tag: para #, no-c-format msgid "Heartbeat 2.1.3 (or less)" msgstr "Heartbeat 2.1.3 (o precedenti)" #. Tag: para #, no-c-format msgid "Heartbeat 2.0.4" msgstr "Heartbeat 2.0.4" #. Tag: para #, no-c-format msgid "Heartbeat 2.0.4 (or less)" msgstr "Heartbeat 2.0.4 (o precedenti)" #. Tag: para #, no-c-format msgid "Heartbeat 2.0.0" msgstr "Heartbeat 2.0.0" #. Tag: para #, no-c-format msgid "None. Use an alternate upgrade strategy." msgstr "Nessuna. Utilizzare una diversa strategia di aggiornamento." #. Tag: title #, no-c-format msgid "Crossing Compatibility Boundaries" msgstr "Limiti di compatibilità" #. Tag: para #, no-c-format msgid "Rolling upgrades that cross compatibility boundaries must be preformed in multiple steps. For example, to perform a rolling update from Heartbeat 2.0.1 to Pacemaker 0.6.6 one must:" msgstr "Aggiornamenti rolling che attraversano i limiti di compatibilità devono essere effettuati in diversi passi. Ad esempio, per effettuare un aggiornameno rolling da Heartbeat 2.0.1 a Pacemaker 0.6.6 i passi sono:" #. Tag: para #, no-c-format msgid "Perform a rolling upgrade from Heartbeat 2.0.1 to Heartbeat 2.0.4" msgstr "Effettuare un aggiornamento rolling da Heartbeat 2.0.1 a Heartbeat 2.0.4" #. Tag: para #, no-c-format msgid "Perform a rolling upgrade from Heartbeat 2.0.4 to Heartbeat 2.1.3" msgstr "Effettuare un aggiornamento rolling da Heartbeat 2.0.4 a Heartbeat 2.1.3" #. Tag: para #, no-c-format msgid "Perform a rolling upgrade from Heartbeat 2.1.3 to Pacemaker 0.6.6" msgstr "Effettuare un aggiornamento rolling da Heartbeat 2.1.3 a Pacemaker 0.6.6" #. Tag: para #, fuzzy, no-c-format msgid "A variant of a complete cluster shutdown, but the resources are left active and get re-detected when the cluster is restarted." msgstr "Una variante dello spegnimento completo del cluster, le risorse vengono lasciate attive e ri scoperte all'avvio del cluster." #. Tag: para #, fuzzy, no-c-format msgid "Tell the cluster to stop managing services." msgstr "Abilitazione del cluster a gestire nuovamente le risorse" #. Tag: para #, fuzzy, no-c-format msgid "This is required to allow the services to remain active after the cluster shuts down." msgstr "Comunicare al cluster di smettere di gestire i servizi. Ciò è richiesto per abilitare i servizi a rimanere attivi dopo che il cluster è stato spento." #. Tag: programlisting #, fuzzy, no-c-format msgid "# crm_attribute -t crm_config -n is-managed-default -v false" msgstr "crm_attribute -t crm_config -n is-managed-default -v false " #. Tag: para #, fuzzy, no-c-format msgid "For any resource that has a value for is-managed, make sure it is set to false (so that the cluster will not stop it)" msgstr "Per qualsiasi risorsa il cui campo \"is-managed\" è valorizzato , assicurarsi che questo sia impostato a \"false\" (in modo che il cluster non la fermi)" #. Tag: programlisting #, fuzzy, no-c-format msgid "# crm_resource -t primitive -r $rsc_id -p is-managed -v false" msgstr "crm_resource -t primitive -r <rsc_id> -p is-managed -v false" #. Tag: para #, no-c-format msgid "Upgrade the cluster stack program - This may also include upgrading the underlying operating system." msgstr "Programma di aggiornamento dello stack del Cluster - Questo potrebbe includere l'aggiornamento del sistema operativo." #. Tag: para #, no-c-format msgid "Start the cluster stack." msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "This can be either Corosync or Heartbeat and does not need to be the same as the previous cluster stack." msgstr "Avvio dello stack del cluster. Questo può essere Corosync o Heartbeat e non necessità di essere lo stesso stack precedentemente utilizzato." #. Tag: para #, fuzzy, no-c-format msgid "Verify that the cluster re-detected all resources correctly." msgstr "Verifica della corretta individuazione di tutte le risorse" #. Tag: para #, fuzzy, no-c-format msgid "Allow the cluster to resume managing resources again:" msgstr "Abilitazione del cluster a gestire nuovamente le risorse" #. Tag: programlisting #, fuzzy, no-c-format msgid "# crm_attribute -t crm_config -n is-managed-default -v true" msgstr "crm_attribute -t crm_config -n is-managed-default -v true " #. Tag: para #, fuzzy, no-c-format msgid "For any resource that has a value for is-managed reset it to true (so the cluster can recover the service if it fails) if desired:" msgstr "Reset a \"true\" del valore \"is-managed\" per ogni risorsa (in modo che il cluster possa ripristinare il servizio se questo fallisce)" #. Tag: programlisting #, fuzzy, no-c-format msgid "# crm_resource -t primitive -r $rsc_id -p is-managed -v true" msgstr "crm_resource -t primitive -r <rsc_id> -p is-managed -v false" #. Tag: title #, no-c-format msgid "Notes" msgstr "Note" #. Tag: para #, no-c-format msgid "Always check your existing configuration is still compatible with the version you are installing before starting the cluster." msgstr "Controllare sempre che la propria configurazione sia sempre compatibile con la versione che si sta installando prima di avviare il cluster." #. Tag: para #, no-c-format msgid "The oldest version of the CRM to support this upgrade type was in Heartbeat 2.0.4" msgstr "La versione più vecchia del CRM che supporta questo tipo di aggiornamento è presente in Heartbeat 2.0.4" #~ msgid "Shutdown" #~ msgstr "Spegnimento" #~ msgid "Rolling" #~ msgstr "Rolling" #~ msgid "Reattach" #~ msgstr "Riaggancio" #~ msgid "Upgrade the Pacemaker software. This may also include upgrading the cluster stack and/or the underlying operating system.." #~ msgstr "Aggiornamento del software Pacemaker. Questo potrebbe includere l'aggiornamento dello stack del cluster e/o del sistema operativo sottostante." #~ msgid "On the first node, check the configuration manually or with the crm_verify tool if available." #~ msgstr "Sul primo nodo, controllare la configurazione manualmente o via crm_verify, se disponibile." #~ msgid "crm_resource -t primitive -r <rsc_id> -p is-managed -v false " #~ msgstr "crm_resource -t primitive -r <rsc_id> -p is-managed -v false " pacemaker-master/doc/Pacemaker_Explained/it-IT/Author_Group.po000066400000000000000000000036201217637305600246440ustar00rootroot00000000000000# # AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: 0\n" "POT-Creation-Date: 2012-10-17T05:19:01\n" "PO-Revision-Date: 2011-05-04 09:59+0100\n" "Last-Translator: RaSca \n" "Language-Team: None\n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. Tag: firstname #, no-c-format msgid "Andrew" msgstr "Andrew" #. Tag: surname #, no-c-format msgid "Beekhof" msgstr "Beekhof" #. Tag: orgname #, no-c-format msgid "Red Hat" msgstr "Red Hat" #. Tag: contrib #, no-c-format msgid "Primary author" msgstr "" #. Tag: firstname #, no-c-format msgid "Dan" msgstr "" #. Tag: surname #, no-c-format msgid "Frîncu" msgstr "" #. Tag: contrib #, no-c-format msgid "Romanian translation" msgstr "" #. Tag: firstname #, no-c-format msgid "Philipp" msgstr "" #. Tag: surname #, no-c-format msgid "Marek" msgstr "" #. Tag: orgname #, no-c-format msgid "LINBit" msgstr "" #. Tag: contrib #, no-c-format msgid "Style and formatting updates. Indexing." msgstr "" #. Tag: firstname #, no-c-format msgid "Tanja" msgstr "" #. Tag: surname #, no-c-format msgid "Roth" msgstr "" #. Tag: orgname #, no-c-format msgid "SUSE" msgstr "" #. Tag: contrib #, no-c-format msgid "Utilization chapter" msgstr "" #. Tag: contrib #, no-c-format msgid "Resource Templates chapter" msgstr "" #. Tag: contrib #, no-c-format msgid "Multi-Site Clusters chapter" msgstr "" #. Tag: firstname #, no-c-format msgid "Lars" msgstr "" #. Tag: surname #, no-c-format msgid "Marowsky-Bree" msgstr "" #. Tag: firstname #, no-c-format msgid "Yan" msgstr "" #. Tag: surname #, no-c-format msgid "Gao" msgstr "" #. Tag: firstname #, no-c-format msgid "Thomas" msgstr "" #. Tag: surname #, no-c-format msgid "Schraitle" msgstr "" #. Tag: firstname #, no-c-format msgid "Dejan" msgstr "" #. Tag: surname #, no-c-format msgid "Muhamedagic" msgstr "" pacemaker-master/doc/Pacemaker_Explained/it-IT/Book_Info.po000066400000000000000000000052131217637305600240730ustar00rootroot00000000000000# # AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: 0\n" "POT-Creation-Date: 2012-10-17T05:19:01\n" "PO-Revision-Date: 2011-04-07 13:27+0100\n" "Last-Translator: RaSca \n" "Language-Team: None\n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. Tag: title #, no-c-format msgid "Configuration Explained" msgstr "Configuration Explained" #. Tag: subtitle #, fuzzy, no-c-format msgid "An A-Z guide to Pacemaker's Configuration Options" msgstr "Una guida dalla A alla Z alle opzioni di configurazione di Pacemaker" #. Tag: productname #, no-c-format msgid "Pacemaker" msgstr "Pacemaker" #. Tag: para #, fuzzy, no-c-format msgid "The purpose of this document is to definitively explain the concepts used to configure Pacemaker. To achieve this, it will focus exclusively on the XML syntax used to configure the CIB." msgstr "Lo scopo di questo documento e di spiegare definitivamente i concetti utilizzati per configurare Pacemaker. Per ottenere il risultato migliore, si focalizzerà esclusivamente sulla sintassi XML utilizzata per configurare il CIB" #. Tag: para #, fuzzy, no-c-format msgid "For those that are allergic to XML, there exist several unified shells and GUIs for Pacemaker. However these tools will not be covered at all in this document I hope, however, that the concepts explained here make the functionality of these tools more easily understood. , precisely because they hide the XML." msgstr "Per tutti gli allergici ad XML Pacemaker dispone di una cluster shell ed una GUI scritta in Python, ma questi strumenti non verranno assolutamente trattati in questo documento Si spera comunque che attraverso l'apprendimento dei concetti spiegati qui le funzionalità di questi strumenti possano essere compresi ancora meglio. , in particolare perché questi nascondono l'XML." #. Tag: para #, fuzzy, no-c-format msgid "Additionally, this document is NOT a step-by-step how-to guide for configuring a specific clustering scenario. Although such guides exist, the purpose of this document is to provide an understanding of the building blocks that can be used to construct any type of Pacemaker cluster. Try the Clusters from Scratch document instead." msgstr "In aggiunta, questo documento NON E' una guida passo passo per configurare specifici scenari cluster. Sebbene queste guide esistano, lo scopo di questo documento è di far acquisire fondamentea che possano essere utilizzate per costruire qualsiasi tipo di cluster Pacemaker." pacemaker-master/doc/Pacemaker_Explained/it-IT/Ch-Advanced-Options.po000066400000000000000000002037101217637305600257160ustar00rootroot00000000000000# # AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: 0\n" "POT-Creation-Date: 2012-10-17T05:19:01\n" "PO-Revision-Date: 2011-10-12 10:17+0100\n" "Last-Translator: RaSca \n" "Language-Team: None\n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. Tag: title #, no-c-format msgid "Advanced Configuration" msgstr "Configurazione avanzata" #. Tag: title #, fuzzy, no-c-format msgid "Connecting from a Remote Machine" msgstr "Connessione alla configurazione del cluster da una macchina remota" #. Tag: para #, no-c-format msgid " ClusterRemote connection Remote connection ClusterRemote administration Remote administration " msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "Provided Pacemaker is installed on a machine, it is possible to connect to the cluster even if the machine itself is not in the same cluster. To do this, one simply sets up a number of environment variables and runs the same commands as when working on a cluster node." msgstr "Supponendo che Pacemaker sia installato su una macchina, è possibile collegarsi al cluster anche se questa non è parte di esso. Per farlo è sufficiente valorizzare alcune variabili d'ambiente ed eseguire gli stessi comandi che si eseguirebbero su un nodo del cluster." #. Tag: title #, no-c-format msgid "Environment Variables Used to Connect to Remote Instances of the CIB" msgstr "Variabili d'ambiente utilizzate per connettersi ad istanze remote del CIB" #. Tag: entry #, no-c-format msgid "Environment Variable" msgstr "Variabile d'ambiente" #. Tag: entry #, no-c-format msgid "Description" msgstr "Descrizione" #. Tag: para #, no-c-format msgid "CIB_user" msgstr "" #. Tag: para #, no-c-format msgid "The user to connect as. Needs to be part of the hacluster group on the target host. Defaults to $USER. Environment VariableCIB_user CIB_user " msgstr "" #. Tag: para #, no-c-format msgid "CIB_passwd" msgstr "" #. Tag: para #, no-c-format msgid "The user’s password. Read from the command line if unset. Environment VariableCIB_passwd CIB_passwd " msgstr "" #. Tag: para #, no-c-format msgid "CIB_server" msgstr "" #. Tag: para #, no-c-format msgid "The host to contact. Defaults to localhost. Environment VariableCIB_server CIB_server " msgstr "" #. Tag: para #, no-c-format msgid "CIB_port" msgstr "" #. Tag: para #, no-c-format msgid "The port on which to contact the server; required. Environment VariableCIB_port CIB_port " msgstr "" #. Tag: para #, no-c-format msgid "CIB_encrypted" msgstr "" #. Tag: para #, no-c-format msgid "Encrypt network traffic; defaults to true. Environment VariableCIB_encrypted CIB_encrypted " msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "So, if c001n01 is an active cluster node and is listening on 1234 for connections, and someguy is a member of the hacluster group, then the following would prompt for someguy's password and return the cluster’s current configuration:" msgstr "Quindi se c001n01 è un nodo del cluster attivo in ascolto alle connessioni sulla porta 1234 e someguy è un parte del gruppo hacluster, allora di seguito verrà richiesta la password e restituito lo stato della configurazione del cluster:" #. Tag: programlisting #, fuzzy, no-c-format msgid "" "# export CIB_port=1234; export CIB_server=c001n01; export CIB_user=someguy;\n" "# cibadmin -Q" msgstr "" "\n" "\t\n" " export CIB_port=1234; export CIB_server=c001n01; export CIB_user=someguy;\n" " cibadmin -Q\n" "\t\n" " " #. Tag: para #, fuzzy, no-c-format msgid "For security reasons, the cluster does not listen for remote connections by default. If you wish to allow remote access, you need to set the remote-tls-port (encrypted) or remote-clear-port (unencrypted) top-level options (ie., those kept in the cib tag, like num_updates and epoch)." msgstr "Per ragioni di sicurezza il cluster non è per default in ascolto alle connessioni remote. Per abilitare l'accesso remoto è necessario impostare le opzioni top-level (ad esempio quelle dichiarate nel tag cib, come num_updates e epoch) remote-tls-port (criptato) o remote-clear-port (non criptato) ." #. Tag: title #, no-c-format msgid "Extra top-level CIB options for remote access" msgstr "Opzioni top-level extra per l'accesso remoto" #. Tag: entry #, no-c-format msgid "Field" msgstr "Campo" #. Tag: para #, fuzzy, no-c-format msgid "remote-tls-port" msgstr "remote-tls-port" #. Tag: para #, no-c-format msgid "Listen for encrypted remote connections on this port. Default: none remote-tls-portRemote Connection Option Remote Connection Option Remote ConnectionOptionremote-tls-port Optionremote-tls-port remote-tls-port " msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "remote-clear-port" msgstr "remote-clear-port" #. Tag: para #, no-c-format msgid "Listen for plaintext remote connections on this port. Default: none remote-clear-portRemote Connection Option Remote Connection Option Remote ConnectionOptionremote-clear-port Optionremote-clear-port remote-clear-port " msgstr "" #. Tag: title #, no-c-format msgid "Specifying When Recurring Actions are Performed" msgstr "Specificare tempistiche per le azioni ricorrenti" #. Tag: para #, no-c-format msgid "By default, recurring actions are scheduled relative to when the resource started. So if your resource was last started at 14:32 and you have a backup set to be performed every 24 hours, then the backup will always run at in the middle of the business day - hardly desirable." msgstr "Per default, le operazioni ricorrenti vengono schedulate quando le risorse relative sono avviate. Quindi se una risorsa è stata avviata l'ultima volta alle 14:32 ed è stata dichiarata un'operazione di backup che deve essere eseguita ogni 24 ore, allora tale backup verrà eseguito sempre nel mezzo di un giorno lavorativo, il che non è particolarmente desiderabile..." #. Tag: para #, fuzzy, no-c-format msgid "To specify a date/time that the operation should be relative to, set the operation’s interval-origin. The cluster uses this point to calculate the correct start-delay such that the operation will occur at origin + (interval * N)." msgstr "Per dichiarare tempistiche specifiche a cui le operazioni devono riferirsi l'opzione di riferimento è interval-origin. Il cluster utilizza questo punto di partenza per calcolare il corretto start-delay con cui l'operazione dovrà essere eseguita (interval + N)." #. Tag: para #, fuzzy, no-c-format msgid "So, if the operation’s interval is 24h, it’s interval-origin is set to 02:00 and it is currently 14:32, then the cluster would initiate the operation with a start delay of 11 hours and 28 minutes. If the resource is moved to another node before 2am, then the operation is of course cancelled." msgstr "Quindi se l'intervallo dell'operazione è 24 ore, il relativo interval-origin è 02:00 e l'orario attuale è 14:32, allore il cluster avvierà le operazioni con un ritardo di 11 ore e 28 minuti. Se la risorsa viene spostata su un altro nodo prima delle 2, allora l'operazione è ovviamente cancellata." #. Tag: para #, no-c-format msgid "The value specified for interval and interval-origin can be any date/time conforming to the ISO8601 standard. By way of example, to specify an operation that would run on the first Monday of 2009 and every Monday after that you would add:" msgstr "Il valore specificato per interval e interval-origin può essere un qualsiasi date/time conforme allo standard ISO8601. Facendo un esempio, per dichiarare un'operazione che verrà eseguita il primo lunedì del 2009 ed ogni lunedì successivo bisognerà aggiungere:" #. Tag: title #, no-c-format msgid "Specifying a Base for Recurring Action Intervals" msgstr "Specificare una base di partenza per gli intervalli relativi alle azioni ricorrenti" #. Tag: programlisting #, fuzzy, no-c-format msgid "<op id=\"my-weekly-action\" name=\"custom-action\" interval=\"P7D\" interval-origin=\"2009-W01-1\"/>" msgstr "" "\n" " <op id="my-weekly-action" name="custom-action" interval="P7D" interval-origin="2009-W01-1"/>\n" "\t" #. Tag: title #, no-c-format msgid "Moving Resources" msgstr "Spostare le risorse" #. Tag: para #, no-c-format msgid " MovingResources Resources ResourceMoving Moving " msgstr "" #. Tag: title #, no-c-format msgid "Manual Intervention" msgstr "Intervenire manualmente" #. Tag: para #, fuzzy, no-c-format msgid "There are primarily two occasions when you would want to move a resource from it’s current location: when the whole node is under maintenance, and when a single resource needs to be moved." msgstr "Esistono due casi in cui potrebbe essere necessario spostare una risorsa dalla posizione attuale: quando l'intero nodo è in manutenzione e quando una singola risorsa necessita di essere spostata." #. Tag: para #, fuzzy, no-c-format msgid "Since everything eventually comes down to a score, you could create constraints for every resource to prevent them from running on one node. While the configuration can seem convoluted at times, not even we would require this of administrators." msgstr "Nel caso in cui tutto necessita di essere spostato, dato che tutto si riduce ad un punteggio, è possibile creare una constraint per ciascuna riosrsa per prevenire che questa venga eseguita sul nodo. Questo approccio può sembrare contorto, ma difficilmente ci si troverà nella condizione di doverlo utilizzare." #. Tag: para #, fuzzy, no-c-format msgid "Instead one can set a special node attribute which tells the cluster \"don’t let anything run here\". There is even a helpful tool to help query and set it, called crm_standby. To check the standby status of the current machine, simply run:" msgstr "Infatti è possibile valorizzare un attributo del nodo che indica al cluster di non lasciare nessun processo su di esso. Esiste un comando per facilitare l'interrogazione ed il settaggio di questa condizione chiamato crm_standby. Per controllare che un lo stato standby della macchina è sufficiente lanciare:" #. Tag: programlisting #, fuzzy, no-c-format msgid "# crm_standby --get-value" msgstr "crm_standby --get-value" #. Tag: para #, no-c-format msgid "A value of true indicates that the node is NOT able to host any resources, while a value of false says that it CAN." msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "You can also check the status of other nodes in the cluster by specifying the --node-uname option:" msgstr "Il valore true indica che il nodo NON è in grado di erogare alcuna risorsa, mentr eil valore false indica che PUO'. E' possibile inoltre controllare lo stato degli altri nodi specificando l'opzione --node-uname. Ad esempio" #. Tag: programlisting #, fuzzy, no-c-format msgid "# crm_standby --get-value --node-uname sles-2" msgstr "crm_standby --get-value --node-uname sles-2" #. Tag: para #, fuzzy, no-c-format msgid "To change the current node’s standby status, use --attr-value instead of --get-value." msgstr "Per cambiare lo stato standby del nodo attuale è possibile utilizzare --attr-value invece di --get-value ad esempio" #. Tag: programlisting #, fuzzy, no-c-format msgid "# crm_standby --attr-value" msgstr "crm_standby --attr-value" #. Tag: para #, fuzzy, no-c-format msgid "Again, you can change another host’s value by supplying a host name with --node-uname." msgstr "Nuovamente, è possibile cambiare il valore di un altro host fornendo un nome al parametro --node-uname." #. Tag: para #, fuzzy, no-c-format msgid "When only one resource is required to move, we do this by creating location constraints. However, once again we provide a user friendly shortcut as part of the crm_resource command, which creates and modifies the extra constraints for you. If Email was running on sles-1 and you wanted it moved to a specific location, the command would look something like:" msgstr "Quando è necessario spostare una sola risorsa è possibile creare una location constraint. Ad ogni modo esiste un via più rapida mediante il comando crm_resource che crea e modifica extra constraint in autonomia. Se si vuole spostare in una determinata posizione Email operativa su sles-1 il comando sarà:" #. Tag: programlisting #, fuzzy, no-c-format msgid "# crm_resource -M -r Email -H sles-2" msgstr "crm_resource -M -r Email -H sles-2" #. Tag: para #, no-c-format msgid "Behind the scenes, the tool will create the following location constraint:" msgstr "Dietro le quinte il comando creerà la seguente location constraint:" #. Tag: programlisting #, fuzzy, no-c-format msgid "<rsc_location rsc=\"Email\" node=\"sles-2\" score=\"INFINITY\"/>" msgstr "<rsc_location rsc="Email" node="sles-1" score="-INFINITY"/>" #. Tag: para #, fuzzy, no-c-format msgid "It is important to note that subsequent invocations of crm_resource -M are not cumulative. So, if you ran these commands" msgstr "E' importante notare che successive invocazioni di crm_resource -M non saranno cumulative. Quindi se il comando successivo sarà:" #. Tag: programlisting #, fuzzy, no-c-format msgid "" "# crm_resource -M -r Email -H sles-2\n" "# crm_resource -M -r Email -H sles-3" msgstr "crm_resource -M -r Email -H sles-2" #. Tag: para #, no-c-format msgid "then it is as if you had never performed the first command." msgstr "allora risulterà come se il primo comando non fosse mai stato eseguito." #. Tag: para #, no-c-format msgid "To allow the resource to move back again, use:" msgstr "Per permettere ad una risorsa di essere nuovamente spostata è possibile utilizzare:" #. Tag: programlisting #, fuzzy, no-c-format msgid "# crm_resource -U -r Email" msgstr "crm_resource -U -r Email" #. Tag: para #, fuzzy, no-c-format msgid "Note the use of the word allow. The resource can move back to its original location but, depending on resource-stickiness, it might stay where it is. To be absolutely certain that it moves back to sles-1, move it there before issuing the call to crm_resource -U:" msgstr "Da notare l'uso della parola permettere. La risorsa potrà spostarsi nuovamente nella sua posizione originaria ma, dipendentemente dal valore di stickiness, potrebbe rimanere dov'è. Per essere assolutamente certi che essa venga spostata nuovamente su sles-1 bisognerà spostarla prima di invocare la chiamata a crm_resource -U:" #. Tag: programlisting #, fuzzy, no-c-format msgid "" "# crm_resource -M -r Email -H sles-1\n" "# crm_resource -U -r Email" msgstr "crm_resource -M -r Email -H sles-1" #. Tag: para #, no-c-format msgid "Alternatively, if you only care that the resource should be moved from its current location, try" msgstr "Alternativamente, se l'unica esigenza è quella di spostare la risorsa dalla posizione attuale si può provare con" #. Tag: programlisting #, fuzzy, no-c-format msgid "# crm_resource -M -r Email`" msgstr "crm_resource -M -r Email" #. Tag: para #, fuzzy, no-c-format msgid "Which will instead create a negative constraint, like" msgstr "Che creerà invece una constraint negativa. Ad esempio:" #. Tag: programlisting #, fuzzy, no-c-format msgid "<rsc_location rsc=\"Email\" node=\"sles-1\" score=\"-INFINITY\"/>" msgstr "<rsc_location rsc="Email" node="sles-1" score="-INFINITY"/>" #. Tag: para #, fuzzy, no-c-format msgid "This will achieve the desired effect, but will also have long-term consequences. As the tool will warn you, the creation of a -INFINITY constraint will prevent the resource from running on that node until crm_resource -U is used. This includes the situation where every other cluster node is no longer available!" msgstr "Questo comando servirà allo scopo, ma avrà conseguenze a lungo termine. Il comando avviserà come la creazione di una constraint -INFINITY precluderà alla risorsa la possibilità di essere eseguita su quel particolare nodo finché non verrà usato il comando crm_resource -U. Questo include situazioni in cui nessun altro nodo del cluster sia disponibile." #. Tag: para #, fuzzy, no-c-format msgid "In some cases, such as when resource-stickiness is set to INFINITY, it is possible that you will end up with the problem described in . The tool can detect some of these cases and deals with them by also creating both a positive and negative constraint. Eg." msgstr "In alcuni casi, come quando il valore di stickiness è settato a INFINITY, è possibile trovarsi nel problema descritto nel capitolo . Il tool può rilevare alcuni di questi casi ed agire in modo da creare constraint sia positive che negative. Ad esempio:" #. Tag: para #, fuzzy, no-c-format msgid "Email prefers sles-1 with a score of -INFINITY" msgstr "Email preferisce sles-1 con un punteggio di -INFINITY" #. Tag: para #, fuzzy, no-c-format msgid "Email prefers sles-2 with a score of INFINITY" msgstr "Email preferisce sles-2 con un punteggio di INFINITY" #. Tag: para #, no-c-format msgid "which has the same long-term consequences as discussed earlier." msgstr "che ha lo stesso effetto a lungo termine discusso in precedenza." #. Tag: title #, no-c-format msgid "Moving Resources Due to Failure" msgstr "Spostare risorse in seguito ad un fallimento" #. Tag: para #, fuzzy, no-c-format msgid "New in 1.0 is the concept of a migration threshold. The naming of this option was perhaps unfortunate as it is easily confused with true migration, the process of moving a resource from one node to another without stopping it. Xen virtual guests are the most common example of resources that can be migrated in this manner. " msgstr "Dalla release 1.0 è stato introdotto il concetto di migration threshold Il nome di questa opzione sfortunatamente si confonde con la true migration, la migrazione cioè di una risorsa da un nodo all'altro senza che questa venga stoppata. L'esempio più comune riguarda i virtual guest Xen che possono appunto essere migrate in queto modo. . E' sufficiente definire il parametro migration-threshold=N per una risorsa e questa migrerà ad un nuovo nodo dopo N fallimenti. Non esiste un treshold definito per default. Per determinare lo stato ed i limiti attuali dei fallimenti di una risorsa è possibile utilizzare crm_mon --failcounts" #. Tag: para #, no-c-format msgid "Simply define migration-threshold=N for a resource and it will migrate to a new node after N failures. There is no threshold defined by default. To determine the resource’s current failure status and limits, use crm_mon --failcounts." msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "By default, once the threshold has been reached, this node will no longer be allowed to run the failed resource until the administrator manually resets the resource’s failcount using crm_failcount (after hopefully first fixing the failure’s cause). However it is possible to expire them by setting the resource’s failure-timeout option." msgstr "Per default, quando il valore di treshold viene raggiunto, al verrà proibito di eseguire la risorsa finché l'amministratore non effettuerà un reset manuale del valore utilizzando il comando crm_failcount (si spera dopo aver sistemato la causa del problema). Ad ogni modo è possibile forzare la scadenza impostando l'opzione failure-timeout." #. Tag: para #, fuzzy, no-c-format msgid "So a setting of migration-threshold=2 and failure-timeout=60s would cause the resource to move to a new node after 2 failures, and allow it to move back (depending on the stickiness and constraint scores) after one minute." msgstr "Quindi impostare valori di migration-threshold=2 e failure-timeout=60s comporterà la riduzione degli spostamenti ad un nuovo nodo dopo 2 fallimenti e riabiliando il successivo spostamente (dipendentemente dai punteggi di stickiness e constraint) dopo un minuto" #. Tag: para #, fuzzy, no-c-format msgid "There are two exceptions to the migration threshold concept; they occur when a resource either fails to start or fails to stop. Start failures cause the failcount to be set to INFINITY and thus always cause the resource to move immediately." msgstr "Esistono due eccezioni al concetto di migration threshold e capitano quando una risorsa fallisce l'avvio o lo stop. Fallimenti in fase di avvio forzano il valore di failcount a INFINITY e questo provoca sempre uno spostamento immediato della risorsa." #. Tag: para #, no-c-format msgid "Stop failures are slightly different and crucial. If a resource fails to stop and STONITH is enabled, then the cluster will fence the node in order to be able to start the resource elsewhere. If STONITH is not enabled, then the cluster has no way to continue and will not try to start the resource elsewhere, but will try to stop it again after the failure timeout." msgstr "I fallimenti in fase di stop sono leggermente differenti e cruciali. Se una risorsa fallisce lo stop e STONITH è abilitato, allora il cluster effettuerà un fence del nodo in modo da essere in grado di avviare la risorsa altrove. Se STONITH non è abilitato, allora il cluster non ha modo di continuare e non cercherà di avviare la risorsa altrove, ma continuerà a tentare di stopparla superato il failure timeout." #. Tag: para #, no-c-format msgid "Please read before enabling this option." msgstr "Prima di abilitare questa opzione, si prega di leggere ." #. Tag: title #, no-c-format msgid "Moving Resources Due to Connectivity Changes" msgstr "Spostare le risorse in base a variazioni della connettività" #. Tag: para #, fuzzy, no-c-format msgid "Setting up the cluster to move resources when external connectivity is lost is a two-step process." msgstr "Configurare il cluster affinché sposti le risorse se la connettività viene persa è un processo di due fasi." #. Tag: title #, no-c-format msgid "Tell Pacemaker to monitor connectivity" msgstr "Comunicare a Pacemaker di controllare la connettività" #. Tag: para #, fuzzy, no-c-format msgid "To do this, you need to add a ping resource to the cluster. The ping resource uses the system utility of the same name to a test if list of machines (specified by DNS hostname or IPv4/IPv6 address) are reachable and uses the results to maintain a node attribute normally called pingd. The attribute name is customizable; that allows multiple ping groups to be defined. " msgstr "Per fare ciò è necessario disporre di una risorsa ping all'interno del cluster. La risorsa ping utilizza l'omonima utility di sistama per controllare che una lista di macchine (specificate da un hostname nel DNS o da un indirizzo IPv4/IPv6) sia raggiungibile e conserva i risultati nell'attributo pingd. Il nome dell'attributo è personalizzabile in modo da poter dichiarare ping multipli o gruppi di ping " #. Tag: para #, fuzzy, no-c-format msgid "Older versions of Heartbeat required users to add ping nodes to ha.cf - this is no longer required." msgstr "Versioni passate di Heartbeat richiedevano all'utente di aggiungere i ping node all'interno del file ha.cf, oggi non è più richiesto." #. Tag: para #, no-c-format msgid "Older versions of Pacemaker used a custom binary called pingd for this functionality; this is now deprecated in favor of ping." msgstr "" #. Tag: para #, no-c-format msgid "If your version of Pacemaker does not contain the ping agent, you can download the latest version from https://github.com/ClusterLabs/pacemaker/tree/master/extra/resources/ping" msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "Normally the resource will run on all cluster nodes, which means that you’ll need to create a clone. A template for this can be found below along with a description of the most interesting parameters." msgstr "Tipicamente la risorsa verrà eseguita su tutti i nodi del cluster, che significa come sia necessario creare un clone. Il template relativo è disponibile sotto con una descrizione dei parametri più interessanti." #. Tag: title #, fuzzy, no-c-format msgid "Common Options for a ping Resource" msgstr "Opzioni comuni per la risorsa 'ping'" #. Tag: para #, no-c-format msgid "dampen" msgstr "" #. Tag: para #, no-c-format msgid "The time to wait (dampening) for further changes to occur. Use this to prevent a resource from bouncing around the cluster when cluster nodes notice the loss of connectivity at slightly different times. dampenPing Resource Option Ping Resource Option Ping ResourceOptiondampen Optiondampen dampen " msgstr "" #. Tag: para #, no-c-format msgid "multiplier" msgstr "" #. Tag: para #, no-c-format msgid "The number of connected ping nodes gets multiplied by this value to get a score. Useful when there are multiple ping nodes configured. multiplierPing Resource Option Ping Resource Option Ping ResourceOptionmultiplier Optionmultiplier multiplier " msgstr "" #. Tag: para #, no-c-format msgid "host_list" msgstr "" #. Tag: para #, no-c-format msgid "The machines to contact in order to determine the current connectivity status. Allowed values include resolvable DNS host names, IPv4 and IPv6 addresses. host_listPing Resource Option Ping Resource Option Ping ResourceOptionhost_list Optionhost_list host_list " msgstr "" #. Tag: title #, fuzzy, no-c-format msgid "An example ping cluster resource that checks node connectivity once every minute" msgstr "Un esempio di risorsa ping che controlla la connettività ogni minuto" #. Tag: programlisting #, fuzzy, no-c-format msgid "" "<clone id=\"Connected\">\n" " <primitive id=\"ping\" provider=\"pacemaker\" class=\"ocf\" type=\"ping\">\n" " <instance_attributes id=\"ping-attrs\">\n" " <nvpair id=\"pingd-dampen\" name=\"dampen\" value=\"5s\"/>\n" " <nvpair id=\"pingd-multiplier\" name=\"multiplier\" value=\"1000\"/>\n" " <nvpair id=\"pingd-hosts\" name=\"host_list\" value=\"my.gateway.com www.bigcorp.com\"/>\n" " </instance_attributes>\n" " <operations>\n" " <op id=\"ping-monitor-60s\" interval=\"60s\" name=\"monitor\"/>\n" " </operations>\n" " </primitive>\n" "</clone>" msgstr "" "\n" "\n" " <clone id="Connected">\n" " <primitive id="ping" provider="pacemaker" class="ocf" type="ping">\n" " <instance_attributes id="ping-attrs">\n" " <nvpair id="pingd-dampen" name="dampen" value="5s"/>\n" " <nvpair id="pingd-multiplier" name="multiplier" value="1000"/>\n" " <nvpair id="pingd-hosts" name="host_list" value="my.gateway.com www.bigcorp.com"/>\n" " </instance_attributes>\n" " <operations>\n" " <op id="ping-monitor-60s" interval="60s" name="monitor"/>\n" " </operations>\n" " </primitive>\n" " </clone>\n" "\n" "\t " #. Tag: para #, fuzzy, no-c-format msgid "You’re only half done. The next section deals with telling Pacemaker how to deal with the connectivity status that ocf:pacemaker:ping is recording." msgstr "A questo punto metà del lavoro è fatto. La sezione successiva descrive come deve agire Pacemaker sulla base dello stato che ocf:pacemaker:ping sta registrando." #. Tag: title #, no-c-format msgid "Tell Pacemaker how to interpret the connectivity data" msgstr "Specificare a Pacemaker come intepretare i dati di connettività" #. Tag: para #, fuzzy, no-c-format msgid "Before reading the following, please make sure you have read and understood above." msgstr "NOTA: prima di continuare a leggere accertarsi di aver letto e capito la sezione " #. Tag: para #, fuzzy, no-c-format msgid "There are a number of ways to use the connectivity data provided by Heartbeat. The most common setup is for people to have a single ping node, to prevent the cluster from running a resource on any unconnected node." msgstr "Esistono diversi modi per utilizzare i dati di connettività forniti da Heartbeat. Il setup più comune è composto da un singolo nodo ping che preclude ad una risorsa di essere eseguita su un nodo non connesso." #. Tag: title #, fuzzy, no-c-format msgid "Don’t run on unconnected nodes" msgstr "Non operare su nodi non connessi" #. Tag: programlisting #, fuzzy, no-c-format msgid "" "<rsc_location id=\"WebServer-no-connectivity\" rsc=\"Webserver\">\n" " <rule id=\"ping-exclude-rule\" score=\"-INFINITY\" >\n" " <expression id=\"ping-exclude\" attribute=\"pingd\" operation=\"not_defined\"/>\n" " </rule>\n" "</rsc_location>" msgstr "" "\n" "\n" " <rsc_location id="WebServer-no-connectivity" rsc="Webserver">\n" " <rule id="ping-exclude-rule" score="-INFINITY" >\n" " <expression id="ping-exclude" attribute="pingd" operation="not_defined"/>\n" " </rule>\n" " </rsc_location>\n" "\n" "\t " #. Tag: para #, fuzzy, no-c-format msgid "A more complex setup is to have a number of ping nodes configured. You can require the cluster to only run resources on nodes that can connect to all (or a minimum subset) of them." msgstr "Un setup maggiormente complesso consiste nell'avere diversi nodi ping configurati. E' possibile richiedere al cluster di eseguire risorse su nodi che sono connessi a tutti (o ad un set ridotto) di nodi ping." #. Tag: title #, fuzzy, no-c-format msgid "Run only on nodes connected to three or more ping nodes; this assumes multiplier is set to 1000:" msgstr "Opera solo sui nodi connessi a 3 o più nodi ping (assumendo che multiplier sia impostato a 1000)" #. Tag: programlisting #, fuzzy, no-c-format msgid "" "<rsc_location id=\"WebServer-connectivity\" rsc=\"Webserver\">\n" " <rule id=\"ping-prefer-rule\" score=\"-INFINITY\" >\n" " <expression id=\"ping-prefer\" attribute=\"pingd\" operation=\"lt\" value=\"3000\"/>\n" " </rule>\n" "</rsc_location>" msgstr "" "\n" "\n" " <rsc_location id="WebServer-connectivity" rsc="Webserver">\n" " <rule id="ping-prefer-rule" score="-INFINITY" >\n" " <expression id="ping-prefer" attribute="pingd" operation="lt" value="3000"/>\n" " </rule>\n" " </rsc_location> \n" "\n" "\t " #. Tag: para #, fuzzy, no-c-format msgid "Instead you can tell the cluster only to prefer nodes with the best connectivity. Just be sure to set multiplier to a value higher than that of resource-stickiness (and don’t set either of them to INFINITY)." msgstr "o altrimenti è possibile comunicare al cluster di prediligere i nodi con la connettività maggiore. E' sufficiente assicurarsi che il moltiplicatore sia maggiore del valore di resource-stickiness (e che non ci siano impostati valori di INFINITY)" #. Tag: title #, no-c-format msgid "Prefer the node with the most connected ping nodes" msgstr "Prediligi il nodo che il maggior numero di nodi ping" #. Tag: programlisting #, fuzzy, no-c-format msgid "" "<rsc_location id=\"WebServer-connectivity\" rsc=\"Webserver\">\n" " <rule id=\"ping-prefer-rule\" score-attribute=\"pingd\" >\n" " <expression id=\"ping-prefer\" attribute=\"pingd\" operation=\"defined\"/>\n" " </rule>\n" "</rsc_location>" msgstr "" "\n" "\n" " <rsc_location id="WebServer-connectivity" rsc="Webserver">\n" " <rule id="ping-prefer-rule" score-attribute="pingd" >\n" " <expression id="ping-prefer" attribute="pingd" operation="defined"/>\n" " </rule>\n" " </rsc_location> \n" "\n" "\t " #. Tag: para #, fuzzy, no-c-format msgid "It is perhaps easier to think of this in terms of the simple constraints that the cluster translates it into. For example, if sles-1 is connected to all 5 ping nodes but sles-2 is only connected to 2, then it would be as if you instead had the following constraints in your configuration:" msgstr "E' comunque più semplice ragionare in questi termini sulla base delle constraint che il cluster crea. Ad esempio, se sles-1 è connessa a tutti e 5 i nodi ping, ma sles-2 è connessa solo a 2 di questi, allora sarà più semplice operare con questa constraint all'interno della configurazione:" #. Tag: title #, no-c-format msgid "How the cluster translates the pingd constraint" msgstr "Come il cluster traduce le constraint pingd" #. Tag: programlisting #, fuzzy, no-c-format msgid "" "<rsc_location id=\"ping-1\" rsc=\"Webserver\" node=\"sles-1\" score=\"5000\"/>\n" "<rsc_location id=\"ping-2\" rsc=\"Webserver\" node=\"sles-2\" score=\"2000\"/>" msgstr "" "\n" "\n" " <rsc_location id="ping-1" rsc="Webserver" node="sles-1" score="5000"/>\n" " <rsc_location id="ping-2" rsc="Webserver" node="sles-2" score="2000"/>\n" "\n" "\t " #. Tag: para #, fuzzy, no-c-format msgid "The advantage is that you don’t have to manually update any constraints whenever your network connectivity changes." msgstr "Il vantaggio risiede nel fatto che quando la connettività è ripristinata, non è necessario un intervento manuale." #. Tag: para #, fuzzy, no-c-format msgid "You can also combine the concepts above into something even more complex. The example below shows how you can prefer the node with the most connected ping nodes provided they have connectivity to at least three (again assuming that multiplier is set to 1000)." msgstr "E' possibile inoltre combinare i concetti sopra elencati per ottenere qualcosa di ulteriormente complesso. L'esempio riportato mostra come sia possibile preferire il nodo con il maggior numero di nodi ping forniti con un minimo di tre (assumendo che il valore multiplier sia 1000)." #. Tag: title #, no-c-format msgid "A more complex example of choosing a location based on connectivity" msgstr "Un esempio più complesso di location basata sui valori di connettività" #. Tag: programlisting #, fuzzy, no-c-format msgid "" "<rsc_location id=\"WebServer-connectivity\" rsc=\"Webserver\">\n" " <rule id=\"ping-exclude-rule\" score=\"-INFINITY\" >\n" " <expression id=\"ping-exclude\" attribute=\"pingd\" operation=\"lt\" value=\"3000\"/>\n" " </rule>\n" " <rule id=\"ping-prefer-rule\" score-attribute=\"pingd\" >\n" " <expression id=\"ping-prefer\" attribute=\"pingd\" operation=\"defined\"/>\n" " </rule>\n" "</rsc_location>" msgstr "" "\n" "\n" " <rsc_location id="WebServer-connectivity" rsc="Webserver">\n" " <rule id="ping-exclude-rule" score="-INFINITY" >\n" " <expression id="ping-exclude" attribute="pingd" operation="lt" value="3000"/>\n" " </rule>\n" " <rule id="ping-prefer-rule" score-attribute="pingd" >\n" " <expression id="ping-prefer" attribute="pingd" operation="defined"/>\n" " </rule>\n" " </rsc_location> \n" "\n" "\t " #. Tag: title #, no-c-format msgid "Resource Migration" msgstr "Migrazione delle risorse" #. Tag: para #, fuzzy, no-c-format msgid "Some resources, such as Xen virtual guests, are able to move to another location without loss of state. We call this resource migration; this is different from the normal practice of stopping the resource on the first machine and starting it elsewhere." msgstr "Alcune risorse, come i virtual guest Xen, supportano gli spostamenti presso una nuova destinazione senza smettere di funzionare. Questo processo viene chiamato resource migration ed è differente dalla pratica comune di stoppare una risorsa su una macchina ed avviarla altrove." #. Tag: para #, fuzzy, no-c-format msgid "Not all resources are able to migrate, see the Migration Checklist below, and those that can, won’t do so in all situations. Conceptually there are two requirements from which the other prerequisites follow:" msgstr "Non tutte le risorse sono in grado di migrare, come dimostra la lista riportata sotto, e non tutte le risorse migrabili possono farlo in tutte le situazioni. Concettualmente esistono due requisiti da cui derivano altri pre requisiti:" #. Tag: para #, no-c-format msgid "the resource must be active and healthy at the old location" msgstr "la risorsa deve essere attiva e funzionante nella locazione originale" #. Tag: para #, no-c-format msgid "everything required for the resource to run must be available on both the old and new locations" msgstr "quanto necessario alla risorsa per funzionare deve essere disponibile sulla locazione originale e futura." #. Tag: para #, no-c-format msgid "The cluster is able to accommodate both push and pull migration models by requiring the resource agent to support two new actions: migrate_to (performed on the current location) and migrate_from (performed on the destination)." msgstr "Il cluster supporta sia la migrazione \"da\" che quella \"verso\" richiedendo al resource agent di supportare due nuove azioni:migrate_to (eseguita sulla locazione attuale) e migrate_from (eseguita sulla destinazione)." #. Tag: para #, fuzzy, no-c-format msgid "In push migration, the process on the current location transfers the resource to the new location where is it later activated. In this scenario, most of the work would be done in the migrate_to action and, if anything, the activation would occur during migrate_from." msgstr "Nella migrazione \"da\", il processo dalla locazione attuale è trasferito alla nuova dove verrà poi attivato. In questo scenario la maggior parte del lavoro verrà svolto durante l'azione migrate_to e, salvo imprevisti, l'attivazione verrà completata durante il migrate_from." #. Tag: para #, no-c-format msgid "Conversely for pull, the migrate_to action is practically empty and migrate_from does most of the work, extracting the relevant resource state from the old location and activating it." msgstr "Al contrario per l'azione \"a\" l'azione migrate_to è praticamente nulla mentre la maggior parte del lavoro è svoloto durante migrate_from, che estrae lo stato rilevante della risorsa nella vecchia locazione e lo attiva." #. Tag: para #, no-c-format msgid "There is no wrong or right way to implement migration for your service, as long as it works." msgstr "Non esiste una via giusta o sbagliata di implementare la migrazione di un servizio, finché questa funziona." #. Tag: title #, no-c-format msgid "Migration Checklist" msgstr "Lista di controllo della migrazione" #. Tag: para #, no-c-format msgid "The resource may not be a clone." msgstr "La risorsa potrebbe non essere un clone" #. Tag: para #, no-c-format msgid "The resource must use an OCF style agent." msgstr "La risorsa deve usare un agent di tipo OCF" #. Tag: para #, no-c-format msgid "The resource must not be in a failed or degraded state." msgstr "La risorsa non deve essere in stato failed o degraded." #. Tag: para #, no-c-format msgid "The resource must not, directly or indirectly, depend on any primitive or group resources." msgstr "La risorsa non deve, direttamente o indirettamente, dipendere da una primitiva o da un gruppo di risorse." #. Tag: para #, fuzzy, no-c-format msgid "The resource must support two new actions: migrate_to and migrate_from, and advertise them in its metadata." msgstr "La risorsa deve supportare due nuove azioni: migrate_to e migrate_from ed notificare queste nei propri metadata." #. Tag: para #, fuzzy, no-c-format msgid "The resource must have the allow-migrate meta-attribute set to true (which is not the default)." msgstr "La risorsa deve avere il meta-attribute allow-migrate impostato a true (che non è il default)." #. Tag: para #, no-c-format msgid "If the resource depends on a clone, and at the time the resource needs to be move, the clone has instances that are stopping and instances that are starting, then the resource will be moved in the traditional manner. The Policy Engine is not yet able to model this situation correctly and so takes the safe (yet less optimal) path." msgstr "Se la risorsa dipende da un clone e, nel momento in cui questa deve essere spostata, il clone ha istanze che stanno partendo o fermandos, allora la risorsa verrà spostata in maniera tradizionale. Il Policy Engine (motore delle politiche di spostamento) non è ancora in grado di modellare questa situazione correttamente e quindi prende la via più sicura (e meno ottimale)." #. Tag: title #, no-c-format msgid "Reusing Rules, Options and Sets of Operations" msgstr "Riutilizzare regole, opzioni e set di operazioni" #. Tag: para #, fuzzy, no-c-format msgid "Sometimes a number of constraints need to use the same set of rules, and resources need to set the same options and parameters. To simplify this situation, you can refer to an existing object using an id-ref instead of an id." msgstr "A volte alcune constraint necessitano di utilizzare lo stesso set di regole ed alcune risorse necessitano di impostare le stesse opzioni su dei parametri. Per semplificare questa situazione è possibile riferirsi all'oggetto esistente mediante un id-ref anziché un id." #. Tag: para #, no-c-format msgid "So if for one resource you have" msgstr "Quindi data una risorsa" #. Tag: para #, fuzzy, no-c-format msgid "Then instead of duplicating the rule for all your other resources, you can instead specify:" msgstr "anziché duplicare la regola per tutte le altre risorse, è possibile specificare" #. Tag: title #, no-c-format msgid "Referencing rules from other constraints" msgstr "Referenziare regole da altre constraint" #. Tag: programlisting #, fuzzy, no-c-format msgid "" "<rsc_location id=\"WebDB-connectivity\" rsc=\"WebDB\">\n" " <rule id-ref=\"ping-prefer-rule\"/>\n" "</rsc_location>" msgstr "" "\n" "\n" " <rsc_location id="WebDB-connectivity" rsc="WebDB">\n" " <rule id-ref="ping-prefer-rule"/>\n" " </rsc_location> \n" "\n" "\t" #. Tag: para #, no-c-format msgid "The cluster will insist that the rule exists somewhere. Attempting to add a reference to a non-existing rule will cause a validation failure, as will attempting to remove a rule that is referenced elsewhere." msgstr "Il cluster insisterà sul fatto che la rule esiste da qualche parte. Cercare di aggiungere una referenza ad una regola inesistente provocherà problemi nella validazione, in quanto seguirà un tentativo di rimuovere una rule referenziata altrove." #. Tag: para #, fuzzy, no-c-format msgid "The same principle applies for meta_attributes and instance_attributes as illustrated in the example below:" msgstr "Lo stesso principio è applicabile a meta_attributes e instance_attributes come illustrato nell'esempio seguente" #. Tag: title #, fuzzy, no-c-format msgid "Referencing attributes, options, and operations from other resources" msgstr "Referenziare attributi, opzioni ed operazioni da altre risorse" #. Tag: programlisting #, fuzzy, no-c-format msgid "" "<primitive id=\"mySpecialRsc\" class=\"ocf\" type=\"Special\" provider=\"me\">\n" " <instance_attributes id=\"mySpecialRsc-attrs\" score=\"1\" >\n" " <nvpair id=\"default-interface\" name=\"interface\" value=\"eth0\"/>\n" " <nvpair id=\"default-port\" name=\"port\" value=\"9999\"/>\n" " </instance_attributes>\n" " <meta_attributes id=\"mySpecialRsc-options\">\n" " <nvpair id=\"failure-timeout\" name=\"failure-timeout\" value=\"5m\"/>\n" " <nvpair id=\"migration-threshold\" name=\"migration-threshold\" value=\"1\"/>\n" " <nvpair id=\"stickiness\" name=\"resource-stickiness\" value=\"0\"/>\n" " </meta_attributes>\n" " <operations id=\"health-checks\">\n" " <op id=\"health-check\" name=\"monitor\" interval=\"60s\"/>\n" " <op id=\"health-check\" name=\"monitor\" interval=\"30min\"/>\n" " </operations>\n" "</primitive>\n" "<primitive id=\"myOtherlRsc\" class=\"ocf\" type=\"Other\" provider=\"me\">\n" " <instance_attributes id-ref=\"mySpecialRsc-attrs\"/>\n" " <meta_attributes id-ref=\"mySpecialRsc-options\"/>\n" " <operations id-ref=\"health-checks\"/>\n" "</primitive>" msgstr "" "\n" "\n" " <primitive id="mySpecialRsc" class="ocf" type="Special" provider="me">\n" " <instance_attributes id="mySpecialRsc-attrs" score="1" >\n" " <nvpair id="default-interface" name="interface" value="eth0"/>\n" " <nvpair id="default-port" name="port" value="9999"/>\n" " </instance_attributes>\n" " <meta_attributes id="mySpecialRsc-options">\n" " <nvpair id="failure-timeout" name="failure-timeout" value="5m"/>\n" " <nvpair id="migration-threshold" name="migration-threshold" value="1"/>\n" " <nvpair id="stickiness" name="resource-stickiness" value="0"/>\n" " </meta_attributes>\n" " <operations id="health-checks">\n" " <op id="health-check" name="monitor" interval="60s"/>\n" " <op id="health-check" name="monitor" interval="30min"/>\n" " </operations>\n" " </primitive>\n" " <primitive id="myOtherlRsc" class="ocf" type="Other" provider="me">\n" " <instance_attributes id-ref="mySpecialRsc-attrs"/>\n" " <meta_attributes id-ref="mySpecialRsc-options"/>\n" " <operations id-ref="health-checks"/>\n" " </primitive>\n" "\n" "\t" #. Tag: title #, no-c-format msgid "Reloading Services After a Definition Change" msgstr "Effettuare il reload dei servizi dopo una variazione della definizione" #. Tag: para #, fuzzy, no-c-format msgid "The cluster automatically detects changes to the definition of services it manages. However, the normal response is to stop the service (using the old definition) and start it again (with the new definition). This works well, but some services are smarter and can be told to use a new set of options without restarting." msgstr "Il cluster rileva autoamticamente variazioni alle definizioni dei servizi che gestisce. Il comportamento normale prevede lo stop del servizio (utilizzando la vecchia definizione) ed il nuovo avvio (con la nuova definizione). Quanto illustrato funziona egregiamente, ma alcuni servizi sono abbastanza furbu da poter essere guidati ad utilizzare un nuovo set di opzioni senza che venga eseguito un riavvio." #. Tag: para #, no-c-format msgid "To take advantage of this capability, your resource agent must:" msgstr "Per trarre beneficio da questa abilità il proprio resource agent dovrà" #. Tag: para #, fuzzy, no-c-format msgid "Accept the reload operation and perform any required actions. The steps required here depend completely on your application!" msgstr "Accettare l'operazione reload ed eseguire ogni azione richiesta." #. Tag: title #, fuzzy, no-c-format msgid "The DRBD Agent’s Control logic for Supporting the reload Operation" msgstr "L'agent di controllo di DRBD " #. Tag: programlisting #, fuzzy, no-c-format msgid "" "case $1 in\n" " start)\n" " drbd_start\n" " ;;\n" " stop)\n" " drbd_stop\n" " ;;\n" " reload)\n" " drbd_reload\n" " ;;\n" " monitor)\n" " drbd_monitor\n" " ;;\n" " *)\n" " drbd_usage\n" " exit $OCF_ERR_UNIMPLEMENTED\n" " ;;\n" "esac\n" "exit $?" msgstr "" "\n" "\n" " case $1 in\n" " start)\n" "\tdrbd_start\n" "\t;;\n" " stop)\n" "\tdrbd_stop\n" "\t;;\n" " reload)\n" "\tdrbd_reload\n" "\t;;\n" " monitor)\n" "\tdrbd_monitor\n" "\t;;\n" " *)\t\n" "\tdrbd_usage\n" "\texit $OCF_ERR_UNIMPLEMENTED\n" "\t;;\n" " esac\n" " exit $?\n" "\n" "\t\t" #. Tag: para #, no-c-format msgid "Advertise the reload operation in the actions section of its metadata" msgstr "Promuovere l'operazione di reload nella sezione actions dei metadata" #. Tag: title #, no-c-format msgid "The DRBD Agent Advertising Support for the reload Operation" msgstr "La logica di controllo dell'operazione di reload implementata dall'agente DRBD" #. Tag: programlisting #, no-c-format msgid "" "<?xml version=\"1.0\"?>\n" " <!DOCTYPE resource-agent SYSTEM \"ra-api-1.dtd\">\n" " <resource-agent name=\"drbd\">\n" " <version>1.1</version>\n" "\n" " <longdesc>\n" " Master/Slave OCF Resource Agent for DRBD\n" " </longdesc>\n" "\n" " ...\n" "\n" " <actions>\n" " <action name=\"start\" timeout=\"240\" />\n" " <action name=\"reload\" timeout=\"240\" />\n" " <action name=\"promote\" timeout=\"90\" />\n" " <action name=\"demote\" timeout=\"90\" />\n" " <action name=\"notify\" timeout=\"90\" />\n" " <action name=\"stop\" timeout=\"100\" />\n" " <action name=\"meta-data\" timeout=\"5\" />\n" " <action name=\"validate-all\" timeout=\"30\" />\n" " </actions>\n" " </resource-agent>" msgstr "" #. Tag: para #, no-c-format msgid "Advertise one or more parameters that can take effect using reload." msgstr "Promuove uno o più paramtri che vengono attivati utilizzando reload." #. Tag: para #, fuzzy, no-c-format msgid "Any parameter with the unique set to 0 is eligible to be used in this way." msgstr "Qualsiasi parametro con il valore unique impostato a 0 è abile ad essere utilizzato in questo modo." #. Tag: title #, no-c-format msgid "Parameter that can be changed using reload" msgstr "Paramtro modificabile utilizzando reload" #. Tag: programlisting #, fuzzy, no-c-format msgid "" "<parameter name=\"drbdconf\" unique=\"0\">\n" " <longdesc>Full path to the drbd.conf file.</longdesc>\n" " <shortdesc>Path to drbd.conf</shortdesc>\n" " <content type=\"string\" default=\"${OCF_RESKEY_drbdconf_default}\"/>\n" "</parameter>" msgstr "" "\n" "\n" " <parameter name="drbdconf" unique="0">\n" " <longdesc lang="en">Full path to the drbd.conf file.</longdesc>\n" " <shortdesc lang="en">Path to drbd.conf</shortdesc>\n" " <content type="string" default="${OCF_RESKEY_drbdconf_default}"/>\n" " </parameter>\n" "\n" "\t\t" #. Tag: para #, fuzzy, no-c-format msgid "Once these requirements are satisfied, the cluster will automatically know to reload the resource (instead of restarting) when a non-unique fields changes." msgstr "Una volta che questi requisiti sono soddisfatti, il cluster saprà automaticamente di dover effettuare un reload (anziché un restart) della risorsa in seguito alla variazione di un campo non-unique." #. Tag: para #, no-c-format msgid "The metadata is re-read when the resource is started. This may mean that the resource will be restarted the first time, even though you changed a parameter with unique=0" msgstr "I metadata vengono nuovamente letti quando la risorsa viene avviata. Questo potrebbe significare che la risorsa verrà riavviata la prima volta, anche se è stato modificato un parametro con unique=0" #. Tag: para #, fuzzy, no-c-format msgid "If both a unique and non-unique field are changed simultaneously, the resource will still be restarted." msgstr "Se due campi unique e non-unique vengono cambiati simultaneamente, allora la risorsa verrà comunque riavviata." #~ msgid "CIB_user" #~ msgstr "CIB_user" #~ msgid "The user to connect as. Needs to be part of the hacluster group on the target host. Defaults to $USER" #~ msgstr "L'utente mediante il quale connettersi. Deve essere parte del gruppo hacluster sull'host di destinazione. Il valore di default è $USER" #~ msgid "CIB_passwd" #~ msgstr "CIB_passwd" #~ msgid "The user's password. Read from the command line if unset" #~ msgstr "La password dell'utente. Viene letta da linea di comando se non passata" #~ msgid "CIB_server" #~ msgstr "CIB_server" #~ msgid "The host to contact. Defaults to localhost." #~ msgstr "L'host da contattare. Il valore di default è localhost." #~ msgid "CIB_port" #~ msgstr "CIB_port" #~ msgid "The port on which to contact the server. Required." #~ msgstr "La porta alla quale contattare il server. Richiesto." #~ msgid "CIB_encrypted" #~ msgstr "CIB_encrypted" #~ msgid "Encrypt network traffic. Defaults to true." #~ msgstr "Crittare o meno il traffico network. Il valore di default è true." #~ msgid "Listen for encrypted remote connections on this port. Default: none" #~ msgstr "Ascolta per connessioni non criptate su questa porta. Default: none" #~ msgid "Listen for plaintext remote connections on this port. Default: none" #~ msgstr "Ascolta per connessioni in chiaro su questa porta. Default: none" #~ msgid "" #~ "\n" #~ " <rsc_location rsc="Email" node="sles-2" score="INFINITY"/>\n" #~ "\t " #~ msgstr "" #~ "\n" #~ " <rsc_location rsc="Email" node="sles-2" score="INFINITY"/>\n" #~ "\t " #~ msgid "crm_resource -M -r Email -H sles-3" #~ msgstr "crm_resource -M -r Email -H sles-3" #~ msgid "Older versions of Pacemaker used a custom binary called pingd for this functionality, this is now deprecated in favor of ping. If your version of Pacemaker does not contain the ping agent, you can download the latest version from: " #~ msgstr "Versioni passate di Pacemaker utilizzavano un eseguibile chiamato pingd per garantire questa funzionalità, al momento questo approccio è deprecato in virtù di ping. Se la versione di Pacemaker di cui si dispone non contiene l'eseguibile ping, è possibile scaricare l'ultima versione da " #~ msgid "dampen" #~ msgstr "dampen" #~ msgid "The time to wait (dampening) for further changes occur. Use this to prevent a resource from bouncing around the cluster when cluster nodes notice the loss of connectivity at slightly different times." #~ msgstr "Il tempo di attesa (dampening) dopo il quale avverrà un cambiamento. Utilizzare questio parametro per prevenire che una risorsa rimbalzi all'interno dei nodi del cluster quando gli stessi notificano assenza di connettività in tempi diversi." #~ msgid "multiplier" #~ msgstr "multiplier" #~ msgid "The number by which to multiply the number of connected ping nodes by. Useful when there are multiple ping nodes configured." #~ msgstr "Il numero da moltiplicare ai nodi connessi. Utile quando sono configurati nodi multipli." #~ msgid "host_list" #~ msgstr "host_list" #~ msgid "The machines to contact in order to determine the current connectivity status. Allowed values include resolvable DNS hostnames, IPv4 and IPv6 addresses." #~ msgstr "Le macchine da contattare per determinare lo stato della connettività. I valori permessi sono hostname DNS risolvibili, indirizzi IPv4 ed IPv6." #~ msgid "" #~ "\n" #~ "\n" #~ " <rsc_location id="WebServer-connectivity" rsc="Webserver">\n" #~ " <rule id="ping-prefer-rule" score-attribute="pingd" >\n" #~ " <expression id="ping-prefer" attribute="pingd" operation="defined"/>\n" #~ " </rule>\n" #~ " </rsc_location>\n" #~ "\n" #~ " " #~ msgstr "" #~ "\n" #~ "\n" #~ " <rsc_location id="WebServer-connectivity" rsc="Webserver">\n" #~ " <rule id="ping-prefer-rule" score-attribute="pingd" >\n" #~ " <expression id="ping-prefer" attribute="pingd" operation="defined"/>\n" #~ " </rule>\n" #~ " </rsc_location>\n" #~ "\n" #~ " " #~ msgid "The steps required here depend completely on your application" #~ msgstr "Le fasi richieste qui dipendono completamente dall'applicazione utilizzata" #~ msgid "" #~ "\n" #~ "\n" #~ " <?xml version="1.0"?>\n" #~ " <!DOCTYPE resource-agent SYSTEM "ra-api-1.dtd">\n" #~ " <resource-agent name="drbd">\n" #~ " <version>1.1</version>\n" #~ " \n" #~ " <longdesc lang="en">\n" #~ " Master/Slave OCF Resource Agent for DRBD\n" #~ " </longdesc>\n" #~ " \n" #~ " <shortdesc lang="en">\n" #~ " This resource agent manages a DRBD resource as a master/slave\n" #~ " resource. DRBD is a shared-nothing replicated storage device.\n" #~ " </shortdesc>\n" #~ " \n" #~ " <parameters>\n" #~ " <parameter name="drbd_resource" unique="1" required="1">\n" #~ " <longdesc lang="en">The name of the drbd resource from the drbd.conf file.</longdesc>\n" #~ " <shortdesc lang="en">drbd resource name</shortdesc>\n" #~ " <content type="string"/>\n" #~ " </parameter>\n" #~ " \n" #~ " <parameter name="drbdconf" unique="0">\n" #~ " <longdesc lang="en">Full path to the drbd.conf file.</longdesc>\n" #~ " <shortdesc lang="en">Path to drbd.conf</shortdesc>\n" #~ " <content type="string" default="${OCF_RESKEY_drbdconf_default}"/>\n" #~ " </parameter>\n" #~ " \n" #~ " </parameters>\n" #~ " \n" #~ " <actions>\n" #~ " <action name="start" timeout="240" />\n" #~ " <action name="reload" timeout="240" />\n" #~ " <action name="promote" timeout="90" />\n" #~ " <action name="demote" timeout="90" />\n" #~ " <action name="notify" timeout="90" />\n" #~ " <action name="stop" timeout="100" />\n" #~ " <action name="meta-data" timeout="5" />\n" #~ " <action name="validate-all" timeout="30" />\n" #~ " </actions>\n" #~ " </resource-agent>\n" #~ "\n" #~ "\t\t" #~ msgstr "" #~ "\n" #~ "\n" #~ " <?xml version="1.0"?>\n" #~ " <!DOCTYPE resource-agent SYSTEM "ra-api-1.dtd">\n" #~ " <resource-agent name="drbd">\n" #~ " <version>1.1</version>\n" #~ " \n" #~ " <longdesc lang="en">\n" #~ " Master/Slave OCF Resource Agent for DRBD\n" #~ " </longdesc>\n" #~ " \n" #~ " <shortdesc lang="en">\n" #~ " This resource agent manages a DRBD resource as a master/slave\n" #~ " resource. DRBD is a shared-nothing replicated storage device.\n" #~ " </shortdesc>\n" #~ " \n" #~ " <parameters>\n" #~ " <parameter name="drbd_resource" unique="1" required="1">\n" #~ " <longdesc lang="en">The name of the drbd resource from the drbd.conf file.</longdesc>\n" #~ " <shortdesc lang="en">drbd resource name</shortdesc>\n" #~ " <content type="string"/>\n" #~ " </parameter>\n" #~ " \n" #~ " <parameter name="drbdconf" unique="0">\n" #~ " <longdesc lang="en">Full path to the drbd.conf file.</longdesc>\n" #~ " <shortdesc lang="en">Path to drbd.conf</shortdesc>\n" #~ " <content type="string" default="${OCF_RESKEY_drbdconf_default}"/>\n" #~ " </parameter>\n" #~ " \n" #~ " </parameters>\n" #~ " \n" #~ " <actions>\n" #~ " <action name="start" timeout="240" />\n" #~ " <action name="reload" timeout="240" />\n" #~ " <action name="promote" timeout="90" />\n" #~ " <action name="demote" timeout="90" />\n" #~ " <action name="notify" timeout="90" />\n" #~ " <action name="stop" timeout="100" />\n" #~ " <action name="meta-data" timeout="5" />\n" #~ " <action name="validate-all" timeout="30" />\n" #~ " </actions>\n" #~ " </resource-agent>\n" #~ "\n" #~ "\t\t" pacemaker-master/doc/Pacemaker_Explained/it-IT/Ch-Advanced-Resources.po000066400000000000000000002500341217637305600262360ustar00rootroot00000000000000# # AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: 0\n" "POT-Creation-Date: 2012-10-17T05:19:01\n" "PO-Revision-Date: 2012-05-07 11:11+0100\n" "Last-Translator: RaSca \n" "Language-Team: None\n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. Tag: title #, no-c-format msgid "Advanced Resource Types" msgstr "Tipi di risorse avanzati" #. Tag: title #, no-c-format msgid "Groups - A Syntactic Shortcut" msgstr "Gruppi - Una scorciatoia sintattica" #. Tag: para #, no-c-format msgid " Group Resources ResourcesGroups Groups " msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "One of the most common elements of a cluster is a set of resources that need to be located together, start sequentially, and stop in the reverse order. To simplify this configuration we support the concept of groups." msgstr "Fra gli elementi più comuni all'interno dei cluster ci sono i set di risorse che necessitano di essere posizionate insieme, avviarsi sequenzialmente e stopparsi nell'ordine inverso. Per semplificare questa configurazione è stato creato il concetto di gruppi." #. Tag: title #, no-c-format msgid "An example group" msgstr "Un esempio di gruppo" #. Tag: programlisting #, fuzzy, no-c-format msgid "" "<group id=\"shortcut\">\n" " <primitive id=\"Public-IP\" class=\"ocf\" type=\"IPaddr\" provider=\"heartbeat\">\n" " <instance_attributes id=\"params-public-ip\">\n" " <nvpair id=\"public-ip-addr\" name=\"ip\" value=\"1.2.3.4\"/>\n" " </instance_attributes>\n" " </primitive>\n" " <primitive id=\"Email\" class=\"lsb\" type=\"exim\"/>\n" " </group>" msgstr "" "\n" "\n" " <group id="shortcut">\n" " <primitive id="Public-IP" class="ocf" type="IPaddr" provider="heartbeat">\n" " <instance_attributes id="params-public-ip">\n" " <nvpair id="public-ip-addr" name="ip" value="1.2.3.4"/>\n" " </instance_attributes>\n" " </primitive>\n" " <primitive id="Email" class="lsb" type="exim"/>\n" " </group>\n" "\n" "\t" #. Tag: para #, no-c-format msgid "Although the example above contains only two resources, there is no limit to the number of resources a group can contain. The example is also sufficient to explain the fundamental properties of a group:" msgstr "Anche se l'esempio illustrato sopra contiene solo due risorse, non esiste limite al numero di risorse che un gruppo può contenere. L'esempio è comunque sufficiente per illustrare le proprietà fondamentali di un gruppo:" #. Tag: para #, fuzzy, no-c-format msgid "Resources are started in the order they appear in (Public-IP first, then Email)" msgstr "Le risorse vengono avviate nell'ordine in cui appaiono (prima Public-IP, poi Email)" #. Tag: para #, fuzzy, no-c-format msgid "Resources are stopped in the reverse order to which they appear in (Email first, then Public-IP)" msgstr "Le risorse vengono stoppate in ordine inverso rispetto a come appaiono (prima Email, poi Public-IP)" #. Tag: para #, fuzzy, no-c-format msgid "If a resource in the group can’t run anywhere, then nothing after that is allowed to run, too." msgstr "Se una risorsa nel gruppo non può essere avviata ovunque, allora tutto quel che segue non verrà avviato" #. Tag: para #, fuzzy, no-c-format msgid "If Public-IP can’t run anywhere, neither can Email;" msgstr "Se Public-IP non può essere avviata ovunque, anche Email non verrà avviata" #. Tag: para #, fuzzy, no-c-format msgid "but if Email can’t run anywhere, this does not affect Public-IP in any way" msgstr "Il fatto che Email non può essere avviata ovunque non influisce minimamente su Public-IP" #. Tag: para #, no-c-format msgid "The group above is logically equivalent to writing:" msgstr "Il gruppo descritto è locicamente equivalente alla seguente definizione:" #. Tag: title #, no-c-format msgid "How the cluster sees a group resource" msgstr "Come il gruppo di risorse è visto dal cluster" #. Tag: programlisting #, fuzzy, no-c-format msgid "" "<configuration>\n" " <resources>\n" " <primitive id=\"Public-IP\" class=\"ocf\" type=\"IPaddr\" provider=\"heartbeat\">\n" " <instance_attributes id=\"params-public-ip\">\n" " <nvpair id=\"public-ip-addr\" name=\"ip\" value=\"1.2.3.4\"/>\n" " </instance_attributes>\n" " </primitive>\n" " <primitive id=\"Email\" class=\"lsb\" type=\"exim\"/>\n" " </resources>\n" " <constraints>\n" " <rsc_colocation id=\"xxx\" rsc=\"Email\" with-rsc=\"Public-IP\" score=\"INFINITY\"/>\n" " <rsc_order id=\"yyy\" first=\"Public-IP\" then=\"Email\"/>\n" " </constraints>\n" "</configuration>" msgstr "" "\n" "\n" " <configuration>\n" " <resources>\n" " <primitive id="Public-IP" class="ocf" type="IPaddr" provider="heartbeat">\n" " <instance_attributes id="params-public-ip">\n" " <nvpair id="public-ip-addr" name="ip" value="1.2.3.4"/>\n" " </instance_attributes>\n" " </primitive>\n" " <primitive id="Email" class="lsb" type="exim"/>\n" " </resources>\n" " <constraints>\n" " <rsc_colocation id="xxx" rsc="Email" with-rsc="Public-IP" score="INFINITY"/>\n" " <rsc_order id="yyy" first="Public-IP" then="Email"/>\n" " </constraints>\n" " </configuration>\n" "\n" "\t" #. Tag: para #, no-c-format msgid "Obviously as the group grows bigger, the reduced configuration effort can become significant." msgstr "Ovviamente a fronte di gruppi che crescono in grandezza, il risparmio di dichiarazioni in configurazione può diventare considerevole" #. Tag: para #, no-c-format msgid "Another (typical) example of a group is a DRBD volume, the filesystem mount, an IP address, and an application that uses them." msgstr "" #. Tag: title #, fuzzy, no-c-format msgid "Group Properties" msgstr "Proprietà" #. Tag: title #, no-c-format msgid "Properties of a Group Resource" msgstr "Proprietà di un gruppo di risorse" #. Tag: entry #, no-c-format msgid "Field" msgstr "Campo" #. Tag: entry #, no-c-format msgid "Description" msgstr "Descrizione" #. Tag: para #, no-c-format msgid "id" msgstr "" #. Tag: para #, no-c-format msgid "Your name for the group idGroup Resource Property Group Resource Property ResourceGroup Propertyid Group Propertyid id " msgstr "" #. Tag: title #, fuzzy, no-c-format msgid "Group Options" msgstr "Opzioni" #. Tag: para #, fuzzy, no-c-format msgid "Options inherited from primitive resources: priority, target-role, is-managed" msgstr "Opzioni ereditate da simple resources: priority, target-role, is-managed" #. Tag: title #, fuzzy, no-c-format msgid "Group Instance Attributes" msgstr "Attributi dell'istanza" #. Tag: para #, fuzzy, no-c-format msgid "Groups have no instance attributes, however any that are set here will be inherited by the group’s children." msgstr "I gruppi non hanno attributi di istanza, ad ogni modo qualsiasi attributo dichiarato all'interno verrà ereditato dai componenti del gruppo." #. Tag: title #, fuzzy, no-c-format msgid "Group Contents" msgstr "Contenuti" #. Tag: para #, fuzzy, no-c-format msgid "Groups may only contain a collection of cluster resources. To refer to the child of a group resource, just use the child’s id instead of the group’s." msgstr "I gruppi possono contenere unicamente una collezione di risorse di tipo primitive . Per riferirsi ad un membro del gruppo è sufficiente utilizzare l'id del membro anziché quello del gruppo." #. Tag: title #, fuzzy, no-c-format msgid "Group Constraints" msgstr "Constraints" #. Tag: para #, fuzzy, no-c-format msgid "Although it is possible to reference the group’s children in constraints, it is usually preferable to use the group’s name instead." msgstr "Anche se è possibile riferirsi ai membri del gruppo nelle constraint, è preferibile utilizzare direttamente il nome del gruppo." #. Tag: title #, no-c-format msgid "Example constraints involving groups" msgstr "Esempio di constraint che coinvolgono i gruppi" #. Tag: programlisting #, fuzzy, no-c-format msgid "" "<constraints>\n" " <rsc_location id=\"group-prefers-node1\" rsc=\"shortcut\" node=\"node1\" score=\"500\"/>\n" " <rsc_colocation id=\"webserver-with-group\" rsc=\"Webserver\" with-rsc=\"shortcut\"/>\n" " <rsc_order id=\"start-group-then-webserver\" first=\"Webserver\" then=\"shortcut\"/>\n" "</constraints>" msgstr "" "\n" "\n" " <constraints>\n" " <rsc_location id="group-prefers-node1" rsc="shortcut" node="node1" score="500"/>\n" " <rsc_colocation id="webserver-with-group" rsc="Webserver" with-rsc="shortcut"/>\n" " <rsc_order id="start-group-then-webserver" first="Webserver" then="shortcut"/>\n" " </constraints>\n" "\n" "\t " #. Tag: title #, fuzzy, no-c-format msgid "Group Stickiness" msgstr "Stickiness" #. Tag: para #, no-c-format msgid " resource-stickinessGroups Groups " msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "Stickiness, the measure of how much a resource wants to stay where it is, is additive in groups. Every active resource of the group will contribute its stickiness value to the group’s total. So if the default resource-stickiness is 100, and a group has seven members, five of which are active, then the group as a whole will prefer its current location with a score of 500." msgstr "La Stickiness, ossia la misura di quanto una risorsa vuole rimanere dov'è, all'interno dei gruppi è sommata per ciascun membro. Ogni membro attivo contribuirà con il proprio valore di stickiness al totale del gruppo. Quindi se la resource-stickiness di default è 100 ed un gruppo ha sette membri, cinque dei quali attivi, allora il gruppo preferirà la locazione attuale con un punteggio di 500." #. Tag: title #, fuzzy, no-c-format msgid "Clones - Resources That Get Active on Multiple Hosts" msgstr "Cloni - Risorse che devono essere attive su host multipli8" #. Tag: para #, no-c-format msgid " Clone Resources ResourcesClones Clones " msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "Clones were initially conceived as a convenient way to start N instances of an IP resource and have them distributed throughout the cluster for load balancing. They have turned out to quite useful for a number of purposes including integrating with Red Hat’s DLM, the fencing subsystem, and OCFS2." msgstr "Le risorse clone sono stati inizialmente concepiti come una via economica per avere N istanze di una risorsa IP distribuite nel cluster per il bilanciamento del carico. Esse sono tornate poi utili per diversi scopi, compresa l'integrazione con il sistema DLM di Red Hat, il sottosistema di fencing ed OCFS2." #. Tag: para #, fuzzy, no-c-format msgid "You can clone any resource, provided the resource agent supports it." msgstr "E' possibile clonare qualsiasi risorsa se il resource agent lo supporta. " #. Tag: para #, fuzzy, no-c-format msgid "Three types of cloned resources exist:" msgstr "Esistono tre tipi di risorsa clonata." #. Tag: para #, no-c-format msgid "Anonymous" msgstr "Anonymous" #. Tag: para #, no-c-format msgid "Globally Unique" msgstr "Globally Unique" #. Tag: para #, no-c-format msgid "Stateful" msgstr "Stateful" #. Tag: para #, no-c-format msgid "Anonymous clones are the simplest type. These resources behave completely identically everywhere they are running. Because of this, there can only be one copy of an anonymous clone active per machine." msgstr "I cloni di tipo Anonymous sono il tipo più semplice. Queste risorse si comportano in maniera identica ovunque sono avviate. Per questo può esistere solo una copia attiva di un clone di tipo Anonymous per ciascuna macchina." #. Tag: para #, no-c-format msgid "Globally unique clones are distinct entities. A copy of the clone running on one machine is not equivalent to another instance on another node. Nor would any two copies on the same node be equivalent." msgstr "I cloni di tipo Globally unique sono entità distinte. Una copia del clone che funziona su una macchina non è equivalente ad un'altra istanza su un altro nodo. Due copie sullo stesso nodo non sarebbero comunque equivalenti." #. Tag: para #, no-c-format msgid "Stateful clones are covered later in ." msgstr "I cloni di tipo Stateful sono descritti nella sezione ." #. Tag: title #, no-c-format msgid "An example clone" msgstr "Un esempio di risorsa clonata" #. Tag: programlisting #, fuzzy, no-c-format msgid "" "<clone id=\"apache-clone\">\n" " <meta_attributes id=\"apache-clone-meta\">\n" " <nvpair id=\"apache-unique\" name=\"globally-unique\" value=\"false\"/>\n" " </meta_attributes>\n" " <primitive id=\"apache\" class=\"lsb\" type=\"apache\"/>\n" "</clone>" msgstr "" "\n" "\n" " <clone id="apache-clone">\n" " <meta_attributes id="apache-clone-meta">\n" " <nvpair id="apache-unique" name="globally-unique" value="false"/>\n" " </meta_attributes>\n" " <primitive id="apache" class="lsb" type="apache"/>\n" " </clone>\n" "\n" "\t" #. Tag: title #, fuzzy, no-c-format msgid "Clone Properties" msgstr "Proprietà" #. Tag: title #, no-c-format msgid "Properties of a Clone Resource" msgstr "Proprietà di una risorsa di tipo clone" #. Tag: para #, no-c-format msgid "Your name for the clone idClone Property Clone Property ClonePropertyid Propertyid id " msgstr "" #. Tag: title #, fuzzy, no-c-format msgid "Clone Options" msgstr "Opzioni" #. Tag: title #, no-c-format msgid "Clone specific configuration options" msgstr "Opzioni specifiche di configurazione per le risorse Clone" #. Tag: para #, no-c-format msgid "clone-max" msgstr "" #. Tag: para #, no-c-format msgid "How many copies of the resource to start. Defaults to the number of nodes in the cluster. clone-maxClone Option Clone Option CloneOptionclone-max Optionclone-max clone-max " msgstr "" #. Tag: para #, no-c-format msgid "clone-node-max" msgstr "" #. Tag: para #, no-c-format msgid "How many copies of the resource can be started on a single node; default 1. clone-node-maxClone Option Clone Option CloneOptionclone-node-max Optionclone-node-max clone-node-max " msgstr "" #. Tag: para #, no-c-format msgid "notify" msgstr "" #. Tag: para #, no-c-format msgid "When stopping or starting a copy of the clone, tell all the other copies beforehand and when the action was successful. Allowed values: false, true notifyClone Option Clone Option CloneOptionnotify Optionnotify notify " msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "globally-unique" msgstr "globally-unique" #. Tag: para #, no-c-format msgid "Does each copy of the clone perform a different function? Allowed values: false, true globally-uniqueClone Option Clone Option CloneOptionglobally-unique Optionglobally-unique globally-unique " msgstr "" #. Tag: para #, no-c-format msgid "ordered" msgstr "" #. Tag: para #, no-c-format msgid "Should the copies be started in series (instead of in parallel). Allowed values: false, true orderedClone Option Clone Option CloneOptionordered Optionordered ordered " msgstr "" #. Tag: para #, no-c-format msgid "interleave" msgstr "" #. Tag: para #, no-c-format msgid "Changes the behavior of ordering constraints (between clones/masters) so that instances can start/stop as soon as their peer instance has (rather than waiting for every instance of the other clone has). Allowed values: false, true interleaveClone Option Clone Option CloneOptioninterleave Optioninterleave interleave " msgstr "" #. Tag: title #, fuzzy, no-c-format msgid "Clone Instance Attributes" msgstr "Attributi dell'istanza" #. Tag: para #, fuzzy, no-c-format msgid "Clones have no instance attributes; however, any that are set here will be inherited by the clone’s children." msgstr "Le risorse clone non possiedono attributi istanza, ad ogni modo questi se valorizzati vengono ereditati da tutte le risorse clone figlio." #. Tag: title #, fuzzy, no-c-format msgid "Clone Contents" msgstr "Contenuti" #. Tag: para #, no-c-format msgid "Clones must contain exactly one group or one regular resource." msgstr "Le risorse clone devono contenere esattamente un gruppo od una risorsa regolare." #. Tag: para #, fuzzy, no-c-format msgid "You should never reference the name of a clone’s child. If you think you need to do this, you probably need to re-evaluate your design." msgstr "Non bisognerebbe mai riferirsi direttamente alle risorse clone figlio. Se è nelle proprie intenzioni farlo, allora probabilmente sarà necessario rivedere i propri piani." #. Tag: title #, fuzzy, no-c-format msgid "Clone Constraints" msgstr "Constraints" #. Tag: para #, fuzzy, no-c-format msgid "In most cases, a clone will have a single copy on each active cluster node. If this is not the case, you can indicate which nodes the cluster should preferentially assign copies to with resource location constraints. These constraints are written no differently to those for regular resources except that the clone’s id is used." msgstr "In molti casi, un clone avrà una singola copia della risorsa su ogni nodo attivo del cluster. Ad ogni modo è possibile indicare a quali nodi del cluster assegnare le copie delle risorse mediante contraint di tipo location. Queste constraint sono scritte in maniera del tutto simile a quelle delle risorse regolari, eccezione fatta per l'id utilizzato che deve essere quello della risorsa clone." #. Tag: para #, fuzzy, no-c-format msgid "Ordering constraints behave slightly differently for clones. In the example below, apache-stats will wait until all copies of the clone that need to be started have done so before being started itself. Only if no copies can be started apache-stats will be prevented from being active. Additionally, the clone will wait for apache-stats to be stopped before stopping the clone." msgstr "Le constraint di tipo order funzionano in una forma differente per i cloni. Nell'esempio sotto, apache-stats aspetterà finché tutte le copie del clone che necessitano di essere avviate lo siano. Solo se nessuna copia può essere avviata ad apache-stats verrà impedito di avviarsi. In aggiunta, la risorsa clone aspetterà che apache-stats sia stoppata prima di stoppare se stessa." #. Tag: para #, fuzzy, no-c-format msgid "Colocation of a regular (or group) resource with a clone means that the resource can run on any machine with an active copy of the clone. The cluster will choose a copy based on where the clone is running and the resource’s own location preferences." msgstr "Effettuare una colocation di una risorsa (o gruppo) con un clone significa che la risorsa può funzionare su qualsiasi macchine che possiede una copia attiva del clone. Il cluster sceglierà la copia in base a dove il clone sta funzionando ed in base alle preferenze di locazione della risorsa (rsc)." #. Tag: para #, fuzzy, no-c-format msgid "Colocation between clones is also possible. In such cases, the set of allowed locations for the clone is limited to nodes on which the clone is (or will be) active. Allocation is then performed as normally." msgstr "E' possibile utilizzare colocation con le risorse clone. In questi casi il set di locazioni consentite per la risorsa clone viene limitato ai nodi su cui il clone è (o sarà) attivo. A questo punto l'allocazione verrà effettuata normalmente." #. Tag: title #, no-c-format msgid "Example constraints involving clones" msgstr "Esempi di constraint che coinvolgono cloni" #. Tag: programlisting #, fuzzy, no-c-format msgid "" "<constraints>\n" " <rsc_location id=\"clone-prefers-node1\" rsc=\"apache-clone\" node=\"node1\" score=\"500\"/>\n" " <rsc_colocation id=\"stats-with-clone\" rsc=\"apache-stats\" with=\"apache-clone\"/>\n" " <rsc_order id=\"start-clone-then-stats\" first=\"apache-clone\" then=\"apache-stats\"/>\n" "</constraints>" msgstr "" "\n" "\n" " <constraints>\n" " <rsc_location id="clone-prefers-node1" rsc="apache-clone" node="node1" score="500"/>\n" " <rsc_colocation id="stats-with-clone" rsc="apache-stats" with="apache-clone"/>\n" " <rsc_order id="start-clone-then-stats" first="apache-clone" then="apache-stats"/>\n" " </constraints>\n" "\n" "\t " #. Tag: title #, fuzzy, no-c-format msgid "Clone Stickiness" msgstr "Stickiness" #. Tag: para #, no-c-format msgid " resource-stickinessClones Clones " msgstr "" #. Tag: para #, no-c-format msgid "To achieve a stable allocation pattern, clones are slightly sticky by default. If no value for resource-stickiness is provided, the clone will use a value of 1. Being a small value, it causes minimal disturbance to the score calculations of other resources but is enough to prevent Pacemaker from needlessly moving copies around the cluster." msgstr "Per fare in modo che abbiano una locazione stabile le risorse clone sono per default sticky (ossia collose). Se non viene specificato alcun valore relativo a resource-stickiness, la risorsa clone utilizzerà il valore di 1. Essendo un valore ridotto, esso causa il disturbo minimo nel calcolo del punteggio delle altre risorse, ma è sufficiente per prevenire Pacemaker dal muovere inutilmente copie delle risorse nel cluster." #. Tag: title #, fuzzy, no-c-format msgid "Clone Resource Agent Requirements" msgstr "Requisiti del resource agent" #. Tag: para #, fuzzy, no-c-format msgid "Any resource can be used as an anonymous clone, as it requires no additional support from the resource agent. Whether it makes sense to do so depends on your resource and its resource agent." msgstr "Ogni risorsa può essere usata come un clone anonimo dato che non richiede supporto aggiuntivo all'interno del resource agent. Dove abbia senso fare ciò dipende dalla propria risorsa e dal relativo resource agent." #. Tag: para #, fuzzy, no-c-format msgid "Globally unique clones do require some additional support in the resource agent. In particular, it must only respond with other probes for instances of the clone should result in they should return one of the other OCF error codes." msgstr "I cloni di tipo Globally unique richiedono supporto aggiuntivo all'interno del resource agent. In particolare, la risorsa dovrà rispondere solamente con ${OCF_SUCCESS} se il nodo ha l'esatta istanza attiva. Tutti gli altri tipi di interrogazione sul clone dovrebbero risultare in ${OCF_NOT_RUNNING}. A meno che ovviamente esse falliscano, caso in cui dovranno restituire i relativi codici di errore OCF." #. Tag: para #, fuzzy, no-c-format msgid "Copies of a clone are identified by appending a colon and a numerical offset, eg. apache:2." msgstr "Le copie di un clone vengono identificate con l'aggiunta di due punti ed un contatore numerico. Ad esempio apache:2" #. Tag: para #, fuzzy, no-c-format msgid "Resource agents can find out how many copies there are by examining the OCF_RESKEY_CRM_meta_clone_max environment variable and which copy it is by examining OCF_RESKEY_CRM_meta_clone." msgstr "Un resource agent può ricavare quante copie di se stesso sono attive esaminando la variabile d'ambiente OCF_RESKEY_CRM_meta_clone_max e quale copia questa sia analizzando OCF_RESKEY_CRM_meta_clone." #. Tag: para #, fuzzy, no-c-format msgid "You should not make any assumptions (based on OCF_RESKEY_CRM_meta_clone) about which copies are active. In particular, the list of active copies will not always be an unbroken sequence, nor always start at 0." msgstr "E' bene non fare assunzioni (basandosi su OCF_RESKEY_CRM_meta_clone) su quali copie siano attive. In particolare la lista delle copie attive non sarà necessariamente in sequenza e non partirà necessariamente da 0." #. Tag: title #, fuzzy, no-c-format msgid "Clone Notifications" msgstr "Notifiche" #. Tag: para #, no-c-format msgid "Supporting notifications requires the notify action to be implemented. Once supported, the notify action will be passed a number of extra variables which, when combined with additional context, can be used to calculate the current state of the cluster and what is about to happen to it." msgstr "Il supporto alle notifiche comporta che l'azione notify sia implementata. Una volta che questa è supportata all'azione notify verranno passate un numero di variabili extra che, quando combinate con le informazioni aggiuntive, potranno essere utilizzate per calcolare lo stato attuale del cluster e cosa sta per succedere ad esso." #. Tag: title #, no-c-format msgid "Environment variables supplied with Clone notify actions" msgstr "Variabili d'ambiente fornite alle azioni notify delle risorse clone" #. Tag: entry #, no-c-format msgid "Variable" msgstr "Variabile" #. Tag: para #, no-c-format msgid "OCF_RESKEY_CRM_meta_notify_type" msgstr "OCF_RESKEY_CRM_meta_notify_type" #. Tag: para #, no-c-format msgid "Allowed values: pre, post Environment VariableOCF_RESKEY_CRM_meta_notify_type OCF_RESKEY_CRM_meta_notify_type type typeNotification Environment Variable Notification Environment Variable " msgstr "" #. Tag: para #, no-c-format msgid "OCF_RESKEY_CRM_meta_notify_operation" msgstr "OCF_RESKEY_CRM_meta_notify_operation" #. Tag: para #, no-c-format msgid "Allowed values: start, stop Environment VariableOCF_RESKEY_CRM_meta_notify_operation OCF_RESKEY_CRM_meta_notify_operation operation operationNotification Environment Variable Notification Environment Variable " msgstr "" #. Tag: para #, no-c-format msgid "OCF_RESKEY_CRM_meta_notify_start_resource" msgstr "OCF_RESKEY_CRM_meta_notify_start_resource" #. Tag: para #, no-c-format msgid "Resources to be started Environment VariableOCF_RESKEY_CRM_meta_notify_start_resource OCF_RESKEY_CRM_meta_notify_start_resource start_resource start_resourceNotification Environment Variable Notification Environment Variable " msgstr "" #. Tag: para #, no-c-format msgid "OCF_RESKEY_CRM_meta_notify_stop_resource" msgstr "OCF_RESKEY_CRM_meta_notify_stop_resource" #. Tag: para #, no-c-format msgid "Resources to be stopped Environment VariableOCF_RESKEY_CRM_meta_notify_stop_resource OCF_RESKEY_CRM_meta_notify_stop_resource stop_resource stop_resourceNotification Environment Variable Notification Environment Variable " msgstr "" #. Tag: para #, no-c-format msgid "OCF_RESKEY_CRM_meta_notify_active_resource" msgstr "OCF_RESKEY_CRM_meta_notify_active_resource" #. Tag: para #, no-c-format msgid "Resources that are running Environment VariableOCF_RESKEY_CRM_meta_notify_active_resource OCF_RESKEY_CRM_meta_notify_active_resource active_resource active_resourceNotification Environment Variable Notification Environment Variable " msgstr "" #. Tag: para #, no-c-format msgid "OCF_RESKEY_CRM_meta_notify_inactive_resource" msgstr "OCF_RESKEY_CRM_meta_notify_inactive_resource" #. Tag: para #, no-c-format msgid "Resources that are not running Environment VariableOCF_RESKEY_CRM_meta_notify_inactive_resource OCF_RESKEY_CRM_meta_notify_inactive_resource inactive_resource inactive_resourceNotification Environment Variable Notification Environment Variable " msgstr "" #. Tag: para #, no-c-format msgid "OCF_RESKEY_CRM_meta_notify_start_uname" msgstr "OCF_RESKEY_CRM_meta_notify_start_uname" #. Tag: para #, no-c-format msgid "Nodes on which resources will be started Environment VariableOCF_RESKEY_CRM_meta_notify_start_uname OCF_RESKEY_CRM_meta_notify_start_uname start_uname start_unameNotification Environment Variable Notification Environment Variable " msgstr "" #. Tag: para #, no-c-format msgid "OCF_RESKEY_CRM_meta_notify_stop_uname" msgstr "OCF_RESKEY_CRM_meta_notify_stop_uname" #. Tag: para #, no-c-format msgid "Nodes on which resources will be stopped Environment VariableOCF_RESKEY_CRM_meta_notify_stop_uname OCF_RESKEY_CRM_meta_notify_stop_uname stop_uname stop_unameNotification Environment Variable Notification Environment Variable " msgstr "" #. Tag: para #, no-c-format msgid "OCF_RESKEY_CRM_meta_notify_active_uname" msgstr "OCF_RESKEY_CRM_meta_notify_active_uname" #. Tag: para #, no-c-format msgid "Nodes on which resources are running Environment VariableOCF_RESKEY_CRM_meta_notify_active_uname OCF_RESKEY_CRM_meta_notify_active_uname active_uname active_unameNotification Environment Variable Notification Environment Variable " msgstr "" #. Tag: para #, no-c-format msgid "OCF_RESKEY_CRM_meta_notify_inactive_uname" msgstr "OCF_RESKEY_CRM_meta_notify_inactive_uname" #. Tag: para #, no-c-format msgid "Nodes on which resources are not running Environment VariableOCF_RESKEY_CRM_meta_notify_inactive_uname OCF_RESKEY_CRM_meta_notify_inactive_uname inactive_uname inactive_unameNotification Environment Variable Notification Environment Variable " msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "The variables come in pairs, such as OCF_RESKEY_CRM_meta_notify_start_resource and OCF_RESKEY_CRM_meta_notify_start_uname and should be treated as an array of whitespace separated elements." msgstr "Le variabili vengono considerate a coppie, come OCF_RESKEY_CRM_meta_notify_start_resource e OCF_RESKEY_CRM_meta_notify_start_uname e dovrebbero essere tratta come un array di elementi separati da spazi." #. Tag: para #, fuzzy, no-c-format msgid "Thus in order to indicate that clone:0 will be started on sles-1, clone:2 will be started on sles-3, and clone:3 will be started on sles-2, the cluster would set" msgstr "Quindi per indicare che clone:0 verrà avviato su sles-, clone:2 verrà avviato su sles-3 e clone:3 verrà avviato su sles-2, il cluser imposterà" #. Tag: title #, no-c-format msgid "Example notification variables" msgstr "Esempio di variabili notifica" #. Tag: programlisting #, fuzzy, no-c-format msgid "" "OCF_RESKEY_CRM_meta_notify_start_resource=\"clone:0 clone:2 clone:3\"\n" "OCF_RESKEY_CRM_meta_notify_start_uname=\"sles-1 sles-3 sles-2\"" msgstr "OCF_RESKEY_CRM_meta_notify_start_resource="clone:0 clone:2 clone:3"" #. Tag: title #, no-c-format msgid "Proper Interpretation of Notification Environment Variables" msgstr "Corretta interpretazione delle variabili di notifica d'ambiente" #. Tag: title #, fuzzy, no-c-format msgid "Pre-notification (stop):" msgstr "Pre-notification (stop)" #. Tag: para #, fuzzy, no-c-format msgid "Active resources: $OCF_RESKEY_CRM_meta_notify_active_resource" msgstr "Risorse attive: $OCF_RESKEY_CRM_meta_notify_active_resource" #. Tag: para #, fuzzy, no-c-format msgid "Inactive resources: $OCF_RESKEY_CRM_meta_notify_inactive_resource" msgstr "Risorse inattive: $OCF_RESKEY_CRM_meta_notify_inactive_resource" #. Tag: para #, fuzzy, no-c-format msgid "Resources to be started: $OCF_RESKEY_CRM_meta_notify_start_resource" msgstr "Risorse da avviare: $OCF_RESKEY_CRM_meta_notify_start_resource" #. Tag: para #, fuzzy, no-c-format msgid "Resources to be stopped: $OCF_RESKEY_CRM_meta_notify_stop_resource" msgstr "Risorse da stoppare: $OCF_RESKEY_CRM_meta_notify_stop_resource" #. Tag: title #, fuzzy, no-c-format msgid "Post-notification (stop) / Pre-notification (start):" msgstr "Post-notification (stop) / Pre-notification (start)" #. Tag: para #, fuzzy, no-c-format msgid "Active resources" msgstr "Risorse attive:" #. Tag: para #, fuzzy, no-c-format msgid "$OCF_RESKEY_CRM_meta_notify_active_resource" msgstr "$OCF_RESKEY_CRM_meta_notify_active_resource" #. Tag: para #, fuzzy, no-c-format msgid "minus $OCF_RESKEY_CRM_meta_notify_stop_resource" msgstr "meno $OCF_RESKEY_CRM_meta_notify_stop_resource" #. Tag: para #, fuzzy, no-c-format msgid "Inactive resources" msgstr "Risorse inattive:" #. Tag: para #, fuzzy, no-c-format msgid "$OCF_RESKEY_CRM_meta_notify_inactive_resource" msgstr "$OCF_RESKEY_CRM_meta_notify_inactive_resource" #. Tag: para #, fuzzy, no-c-format msgid "plus $OCF_RESKEY_CRM_meta_notify_stop_resource" msgstr "più $OCF_RESKEY_CRM_meta_notify_stop_resource" #. Tag: para #, fuzzy, no-c-format msgid "Resources that were started: $OCF_RESKEY_CRM_meta_notify_start_resource" msgstr "Risorse che sono state avviate: $OCF_RESKEY_CRM_meta_notify_start_resource" #. Tag: para #, fuzzy, no-c-format msgid "Resources that were stopped: $OCF_RESKEY_CRM_meta_notify_stop_resource" msgstr "Risorse che sono state stoppate: $OCF_RESKEY_CRM_meta_notify_stop_resource" #. Tag: title #, fuzzy, no-c-format msgid "Post-notification (start):" msgstr "Post-notification (start)" #. Tag: para #, no-c-format msgid "Active resources:" msgstr "Risorse attive:" #. Tag: para #, fuzzy, no-c-format msgid "plus $OCF_RESKEY_CRM_meta_notify_start_resource" msgstr "più $OCF_RESKEY_CRM_meta_notify_start_resource" #. Tag: para #, no-c-format msgid "Inactive resources:" msgstr "Risorse inattive:" #. Tag: para #, fuzzy, no-c-format msgid "minus $OCF_RESKEY_CRM_meta_notify_start_resource" msgstr "meno $OCF_RESKEY_CRM_meta_notify_start_resource" #. Tag: title #, no-c-format msgid "Multi-state - Resources That Have Multiple Modes" msgstr "Multi-state - Risorse con modalità multipla" #. Tag: para #, no-c-format msgid " Multi-state Resources ResourcesMulti-state Multi-state " msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "Multi-state resources are a specialization of Clone resources; please ensure you understand the section on clones before continuing! They allow the instances to be in one of two operating modes; these are called Master and Slave, but can mean whatever you wish them to mean. The only limitation is that when an instance is started, it must come up in the Slave state." msgstr "Le risorse multi-state sono una specializzazione delle risorse clone (assicurarsi di aver compreso la sezione precedente relativa alle risorse clone prima di continuare) che consentono alle istanze di essere in una delle due modalità operative. Queste modalità sono chiamate Master e Slave ma tali nomi possono avere il significato che gli si vuole attribuire. L'unica limitazione è che quando un'istanza viene avviata, deve esserlo in stato Slave." #. Tag: title #, fuzzy, no-c-format msgid "Multi-state Properties" msgstr "Utilizzare le risorse multi-state" #. Tag: title #, no-c-format msgid "Properties of a Multi-State Resource" msgstr "Proprietà delle risorse multi-state" #. Tag: para #, no-c-format msgid "Your name for the multi-state resource idMulti-State Property Multi-State Property Multi-StatePropertyid Propertyid id " msgstr "" #. Tag: title #, fuzzy, no-c-format msgid "Multi-state Options" msgstr "Utilizzare le risorse multi-state" #. Tag: para #, fuzzy, no-c-format msgid "Options inherited from primitive resources: priority, target-role, is-managed" msgstr "Opzioni ereditate da simple resources: priority, target-role, is-managed" #. Tag: para #, fuzzy, no-c-format msgid "Options inherited from clone resources: clone-max, clone-node-max, notify, globally-unique, ordered, interleave" msgstr "Opzioni ereditate da clone resources: clone-max, clone-node-max, notify, globally-unique, ordered, interleave" #. Tag: title #, no-c-format msgid "Multi-state specific resource configuration options" msgstr "Opzioni di configurazione specifiche alle risorse multi-state" #. Tag: para #, no-c-format msgid "master-max" msgstr "" #. Tag: para #, no-c-format msgid "How many copies of the resource can be promoted to master status; default 1. master-maxMulti-State Option Multi-State Option Multi-StateOptionmaster-max Optionmaster-max master-max " msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "master-node-max" msgstr "master-node-max" #. Tag: para #, no-c-format msgid "How many copies of the resource can be promoted to master status on a single node; default 1. master-node-maxMulti-State Option Multi-State Option Multi-StateOptionmaster-node-max Optionmaster-node-max master-node-max " msgstr "" #. Tag: title #, fuzzy, no-c-format msgid "Multi-state Instance Attributes" msgstr "Attributi dell'istanza" #. Tag: para #, fuzzy, no-c-format msgid "Multi-state resources have no instance attributes; however, any that are set here will be inherited by master’s children." msgstr "Le risorse multi-state non hanno attributi di istanza, ad ogni modo qualsiasi attributo settato viene ereditato dai figli del master." #. Tag: title #, fuzzy, no-c-format msgid "Multi-state Contents" msgstr "Utilizzare le risorse multi-state" #. Tag: para #, no-c-format msgid "Masters must contain exactly one group or one regular resource." msgstr "Le risorse master devono contenere esattamente un gruppo o una singola risorsa regolare." #. Tag: para #, fuzzy, no-c-format msgid "You should never reference the name of a master’s child. If you think you need to do this, you probably need to re-evaluate your design." msgstr "Non ci si dovrebbe mai riferire direttamente alle risorse figlio del master. Se è nelle proprie intenzioni farlo, allora probabilmente sarà necessario rivedere i propri piani." #. Tag: title #, no-c-format msgid "Monitoring Multi-State Resources" msgstr "Monitoraggio delle risorse multi-state" #. Tag: para #, fuzzy, no-c-format msgid "The normal type of monitor actions are not sufficient to monitor a multi-state resource in the Master state. To detect failures of the Master instance, you need to define an additional monitor action with role=\"Master\"." msgstr "L'azione di monitor normale che viene definita non è sufficiente a monitorare una risorsa multi-state che è in stato master. Per rilevare malfunzionamenti sull'istanza master è necessario definire azioni di monitoraggio aggiuntive mediante role="Master"." #. Tag: para #, fuzzy, no-c-format msgid "It is crucial that every monitor operation has a different interval!" msgstr "E' cruciale che ogni operazione di monitora avvenga in intervalli differenti" #. Tag: para #, no-c-format msgid "This is because Pacemaker currently differentiates between operations only by resource and interval; so if eg. a master/slave resource has the same monitor interval for both roles, Pacemaker would ignore the role when checking the status - which would cause unexpected return codes, and therefore unnecessary complications." msgstr "" #. Tag: title #, no-c-format msgid "Monitoring both states of a multi-state resource" msgstr "Monitorare entrambi gli stati di una risorsa multi-state" #. Tag: programlisting #, fuzzy, no-c-format msgid "" "<master id=\"myMasterRsc\">\n" " <primitive id=\"myRsc\" class=\"ocf\" type=\"myApp\" provider=\"myCorp\">\n" " <operations>\n" " <op id=\"public-ip-slave-check\" name=\"monitor\" interval=\"60\"/>\n" " <op id=\"public-ip-master-check\" name=\"monitor\" interval=\"61\" role=\"Master\"/>\n" " </operations>\n" " </primitive>\n" "</master>" msgstr "" "\n" "\n" " <master id="myMasterRsc">\n" " <primitive id="myRsc" class="ocf" type="myApp" provider="myCorp">\n" " <operations>\n" " <op id="public-ip-slave-check" name="monitor" interval="60"/>\n" " <op id="public-ip-master-check" name="monitor" interval="61" role="Master"/>\n" " </operations>\n" " </primitive>\n" " </master>\n" "\n" "\t " #. Tag: title #, fuzzy, no-c-format msgid "Multi-state Constraints" msgstr "Constraints" #. Tag: para #, fuzzy, no-c-format msgid "In most cases, a multi-state resources will have a single copy on each active cluster node. If this is not the case, you can indicate which nodes the cluster should preferentially assign copies to with resource location constraints. These constraints are written no differently to those for regular resources except that the master’s id is used." msgstr "Nella maggioranza dei casi, una risorsa multi-state avrà una singola copia su ogni nodo del cluster attivo. Ad ogni modo è possibile indicare a quali nodi del cluster assegnare le copie delle risorse mediante contraint di tipo location. Queste constraint sono scritte in maniera del tutto simile a quelle delle risorse regolari, eccezione fatta per l'id utilizzato che deve essere quello della risorsa master." #. Tag: para #, fuzzy, no-c-format msgid "When considering multi-state resources in constraints, for most purposes it is sufficient to treat them as clones. The exception is when the rsc-role and/or with-rsc-role fields (for colocation constraints) and first-action and/or then-action fields (for ordering constraints) are used." msgstr "Quando si considerano le risorse multi-state all'interno delle constraint, generalmente è sufficiente trattarle come cloni. L'eccezione avviene quando sono utilizzati i valori rsc-role e/o with-rsc-role (per constraint di tipo colocation) e first-action e/o then-action (per constraint di tipo order)." #. Tag: title #, no-c-format msgid "Additional constraint options relevant to multi-state resources" msgstr "Opzioni aggiuntive per le constraint relative alle risorse multi-state" #. Tag: para #, no-c-format msgid "rsc-role" msgstr "" #. Tag: para #, no-c-format msgid "An additional attribute of colocation constraints that specifies the role that rsc must be in. Allowed values: Started, Master, Slave. rsc-roleOrdering Constraints Ordering Constraints ConstraintsOrderingrsc-role Orderingrsc-role rsc-role " msgstr "" #. Tag: para #, no-c-format msgid "with-rsc-role" msgstr "" #. Tag: para #, no-c-format msgid "An additional attribute of colocation constraints that specifies the role that with-rsc must be in. Allowed values: Started, Master, Slave. with-rsc-roleOrdering Constraints Ordering Constraints ConstraintsOrderingwith-rsc-role Orderingwith-rsc-role with-rsc-role " msgstr "" #. Tag: para #, no-c-format msgid "first-action" msgstr "" #. Tag: para #, no-c-format msgid "An additional attribute of ordering constraints that specifies the action that the first resource must complete before executing the specified action for the then resource. Allowed values: start, stop, promote, demote. first-actionOrdering Constraints Ordering Constraints ConstraintsOrderingfirst-action Orderingfirst-action first-action " msgstr "" #. Tag: para #, no-c-format msgid "then-action" msgstr "" #. Tag: para #, no-c-format msgid "An additional attribute of ordering constraints that specifies the action that the then resource can only execute after the first-action on the first resource has completed. Allowed values: start, stop, promote, demote. Defaults to the value (specified or implied) of first-action. then-actionOrdering Constraints Ordering Constraints ConstraintsOrderingthen-action Orderingthen-action then-action " msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "In the example below, myApp will wait until one of the database copies has been started and promoted to master before being started itself. Only if no copies can be promoted will apache-stats be prevented from being active. Additionally, the database will wait for myApp to be stopped before it is demoted." msgstr "Nell'esempio sottostante, myApp aspetterà finché una delle copie del database verrà avviata e promossa a master prima di avviarsi essa stessa. Solo se nessuna copia può essere promossa allora apache-stats non sarà avviata. In aggiunta il database aspetterà finché myApp verra stoppata prima di essere degradato." #. Tag: title #, no-c-format msgid "Example constraints involving multi-state resources" msgstr "Esempio di constraint che coinvolge risorse multi-state" #. Tag: programlisting #, fuzzy, no-c-format msgid "" "<constraints>\n" " <rsc_location id=\"db-prefers-node1\" rsc=\"database\" node=\"node1\" score=\"500\"/>\n" " <rsc_colocation id=\"backup-with-db-slave\" rsc=\"backup\"\n" " with-rsc=\"database\" with-rsc-role=\"Slave\"/>\n" " <rsc_colocation id=\"myapp-with-db-master\" rsc=\"myApp\"\n" " with-rsc=\"database\" with-rsc-role=\"Master\"/>\n" " <rsc_order id=\"start-db-before-backup\" first=\"database\" then=\"backup\"/>\n" " <rsc_order id=\"promote-db-then-app\" first=\"database\" first-action=\"promote\"\n" " then=\"myApp\" then-action=\"start\"/>\n" "</constraints>" msgstr "" "\n" "\n" " <constraints>\n" " <rsc_location id="db-prefers-node1" rsc="database" node="node1" score="500"/>\n" " <rsc_colocation id="backup-with-db-slave" rsc="backup" with-rsc="database" with-rsc-role="Slave"/>\n" " <rsc_colocation id="myapp-with-db-master" rsc="myApp" with-rsc="database" with-rsc-role="Master"/>\n" " <rsc_order id="start-db-before-backup" first="database" then="backup"/>\n" " <rsc_order id="promote-db-then-app" first="database" first-action="promote" then="myApp" then-action="start"/>\n" " </constraints>\n" "\n" "\t " #. Tag: para #, fuzzy, no-c-format msgid "Colocation of a regular (or group) resource with a multi-state resource means that it can run on any machine with an active copy of the multi-state resource that is in the specified state (Master or Slave). In the example, the cluster will choose a location based on where database is running as a Master, and if there are multiple Master instances it will also factor in myApp's own location preferences when deciding which location to choose." msgstr "Effettuare una colocation di un risorsa regolare (o di un gruppo) con una risorsa multi-state significa che tale risorsa può funzionare solo la copia del clone è attiva nello stato specificato (Master o Slave). Nell'esempio, il cluster sceglierà la location in base a dove il database sta funzionando come Master. Se ci sono istanze Master multiple, ciò diventerà fattore di calcolo nel momento di decidere quale location scegliere per myApp." #. Tag: para #, fuzzy, no-c-format msgid "Colocation with regular clones and other multi-state resources is also possible. In such cases, the set of allowed locations for the rsc clone is (after role filtering) limited to nodes on which the with-rsc multi-state resource is (or will be) in the specified role. Allocation is then performed as-per-normal." msgstr "E' possibile definire colocation con risorse clone regolari ed altre risorse multi-state. In questi casi, il set delle locazioni permesse per la risorsa clone (rsc) è limitata (dopo il filtro sul ruolo) ai nodi in cui la risorsa clone associata (with-rsc) è (o sarà) nel ruolo specifico. A quel punto l'allocazione procede come di consueto." #. Tag: title #, fuzzy, no-c-format msgid "Multi-state Stickiness" msgstr "Stickiness" #. Tag: para #, fuzzy, no-c-format msgid " resource-stickinessMulti-State Multi-State To achieve a stable allocation pattern, multi-state resources are slightly sticky by default. If no value for resource-stickiness is provided, the multi-state resource will use a value of 1. Being a small value, it causes minimal disturbance to the score calculations of other resources but is enough to prevent Pacemaker from needlessly moving copies around the cluster." msgstr "Per fare in modo che abbiano una locazione stabile le risorse clone sono per default sticky (ossia collose). Se non viene specificato alcun valore relativo a resource-stickiness, la risorsa clone utilizzerà il valore di 1. Essendo un valore ridotto, esso causa il disturbo minimo nel calcolo del punteggio delle altre risorse, ma è sufficiente per prevenire Pacemaker dal muovere inutilmente copie delle risorse nel cluster." #. Tag: title #, no-c-format msgid "Which Resource Instance is Promoted" msgstr "Quale istanza della risorsa è promossa" #. Tag: para #, fuzzy, no-c-format msgid "During the start operation, most Resource Agent scripts should call the crm_master utility. This tool automatically detects both the resource and host and should be used to set a preference for being promoted. Based on this, master-max, and master-node-max, the instance(s) with the highest preference will be promoted." msgstr "Durante l'operazione di avvio, molti script dei resource agent invocano l'utility crm_master. Questa utility rileva automaticamente sia la risorsa che l'host e dovrebbe essere usata per impostare la preferenza sull'essere promossa. Basandosi su questo, master-max, e master-node-max l'istanza con la più alta preferenza viene promossa." #. Tag: para #, no-c-format msgid "The other alternative is to create a location constraint that indicates which nodes are most preferred as masters." msgstr "" #. Tag: title #, no-c-format msgid "Manually specifying which node should be promoted" msgstr "Specificare manualmente quale nodo dovrebbe essere promosso" #. Tag: programlisting #, fuzzy, no-c-format msgid "" "<rsc_location id=\"master-location\" rsc=\"myMasterRsc\">\n" " <rule id=\"master-rule\" score=\"100\" role=\"Master\">\n" " <expression id=\"master-exp\" attribute=\"#uname\" operation=\"eq\" value=\"node1\"/>\n" " </rule>\n" "</rsc_location>" msgstr "" "\n" "\n" " <rsc_location id="master-location" rsc="myMasterRsc">\n" " <rule id="master-rule" score="100" role="Master">\n" " <expression id="master-exp" attribute="#uname" operation="eq" value="node1"/>\n" " </rule>\n" " </rsc_location>\n" "\n" "\t " #. Tag: title #, fuzzy, no-c-format msgid "Multi-state Resource Agent Requirements" msgstr "Requisiti del resource agent" #. Tag: para #, fuzzy, no-c-format msgid "Since multi-state resources are an extension of cloned resources, all the requirements of Clones are also requirements of multi-state resources. Additionally, multi-state resources require two extra actions: demote and promote; these actions are responsible for changing the state of the resource. Like start and stop, they should return OCF_SUCCESS if they completed successfully or a relevant error code if they did not." msgstr "Dal momneto che le risorse multi-state sono un'estensione delle risorse clonate, tutti i requisiti dei cloni sono requisiti anche delle risrose multi-state. In aggiunta, le risorse multi-state richiedono due azioni extra che sono demote e promote. Queste azioni sono responsabili del cambio di stato della risorsa. Come start e stop, devono restituire OCF_SUCCESS se tutto viene completato con successo o un codice di errore rilevante se qualcosa è andato storto." #. Tag: para #, fuzzy, no-c-format msgid "The states can mean whatever you wish, but when the resource is started, it must come up in the mode called Slave. From there the cluster will then decide which instances to promote to Master." msgstr "Gli stati possono significare qualsiasi cosa si voglia, ma quando la risorsa viene avviata, essa deve salire nella modalità denominata Slave. Da qui il cluster deciderà quindi quale istanza promuovere a Master." #. Tag: para #, no-c-format msgid "In addition to the Clone requirements for monitor actions, agents must also accurately report which state they are in. The cluster relies on the agent to report its status (including role) accurately and does not indicate to the agent what role it currently believes it to be in." msgstr "In aggiunta ai requisiti per le azioni di monitor relativi alle risorse clone, gli agent devono anche riportare accuratamente in quale stato essi si trovano. Il cluster si affida all'agent per riportare il proprio stato (incluso il ruolo) accuratamente e non indica all'agente in quale ruolo ritiene che la risorsa si trovi." #. Tag: title #, no-c-format msgid "Role implications of OCF return codes" msgstr "Implicazioni dei ruoli nei return code OCF" #. Tag: entry #, no-c-format msgid "Monitor Return Code" msgstr "Return code del monitor" #. Tag: para #, no-c-format msgid "OCF_NOT_RUNNING" msgstr "OCF_NOT_RUNNING" #. Tag: para #, no-c-format msgid "Stopped Return CodeOCF_NOT_RUNNING OCF_NOT_RUNNING " msgstr "" #. Tag: para #, no-c-format msgid "OCF_SUCCESS" msgstr "OCF_SUCCESS" #. Tag: para #, no-c-format msgid "Running (Slave) Return CodeOCF_SUCCESS OCF_SUCCESS " msgstr "" #. Tag: para #, no-c-format msgid "OCF_RUNNING_MASTER" msgstr "OCF_RUNNING_MASTER" #. Tag: para #, no-c-format msgid "Running (Master) Return CodeOCF_RUNNING_MASTER OCF_RUNNING_MASTER " msgstr "" #. Tag: para #, no-c-format msgid "OCF_FAILED_MASTER" msgstr "OCF_FAILED_MASTER" #. Tag: para #, no-c-format msgid "Failed (Master) Return CodeOCF_FAILED_MASTER OCF_FAILED_MASTER " msgstr "" #. Tag: para #, no-c-format msgid "Other" msgstr "Atro" #. Tag: para #, no-c-format msgid "Failed (Slave)" msgstr "Fallito (Slave)" #. Tag: title #, fuzzy, no-c-format msgid "Multi-state Notifications" msgstr "Notifiche" #. Tag: para #, fuzzy, no-c-format msgid "Like clones, supporting notifications requires the notify action to be implemented. Once supported the notify action will be passed a number of extra variables which, when combined with additional context, can be used to calculate the current state of the cluster and what is about to happen to it." msgstr "Come nei cloni, il supporto alle notifiche richiede che l'azione notify venga implementata. Una volta supportate, alle azioni notify verranno passati un numero extra di variabili che, quando combinate con contesti aggiuntivi, possono essere usate per calcolare lo stato attuale del cluster e cosa sta per succedere ad esso." #. Tag: title #, fuzzy, no-c-format msgid "Environment variables supplied with Master notify actions Emphasized variables are specific to Master resources and all behave in the same manner as described for Clone resources." msgstr "Variabili d'ambiente fornite con le azioni notify Master Le variabili in grassetto sono specifiche alle risorse Master e si comportano allo stesso modo di come descritto per le risorse clone." #. Tag: para #, no-c-format msgid "Resources the that are running Environment VariableOCF_RESKEY_CRM_meta_notify_active_resource OCF_RESKEY_CRM_meta_notify_active_resource active_resource active_resourceNotification Environment Variable Notification Environment Variable " msgstr "" #. Tag: para #, no-c-format msgid "Resources the that are not running Environment VariableOCF_RESKEY_CRM_meta_notify_inactive_resource OCF_RESKEY_CRM_meta_notify_inactive_resource inactive_resource inactive_resourceNotification Environment Variable Notification Environment Variable " msgstr "" #. Tag: para #, no-c-format msgid "OCF_RESKEY_CRM_meta_notify_master_resource" msgstr "OCF_RESKEY_CRM_meta_notify_master_resource" #. Tag: para #, no-c-format msgid "Resources that are running in Master mode Environment VariableOCF_RESKEY_CRM_meta_notify_master_resource OCF_RESKEY_CRM_meta_notify_master_resource master_resource master_resourceNotification Environment Variable Notification Environment Variable " msgstr "" #. Tag: para #, no-c-format msgid "OCF_RESKEY_CRM_meta_notify_slave_resource" msgstr "OCF_RESKEY_CRM_meta_notify_slave_resource" #. Tag: para #, no-c-format msgid "Resources that are running in Slave mode Environment VariableOCF_RESKEY_CRM_meta_notify_slave_resource OCF_RESKEY_CRM_meta_notify_slave_resource slave_resource slave_resourceNotification Environment Variable Notification Environment Variable " msgstr "" #. Tag: para #, no-c-format msgid " Environment VariableOCF_RESKEY_CRM_meta_notify_stop_resource OCF_RESKEY_CRM_meta_notify_stop_resource stop_resource stop_resourceNotification Environment Variable Notification Environment Variable OCF_RESKEY_CRM_meta_notify_stop_resource" msgstr "" #. Tag: para #, no-c-format msgid "Resources to be stopped" msgstr "La risorsa da stoppare" #. Tag: para #, no-c-format msgid "OCF_RESKEY_CRM_meta_notify_promote_resource" msgstr "OCF_RESKEY_CRM_meta_notify_promote_resource" #. Tag: para #, no-c-format msgid "Resources to be promoted Environment VariableOCF_RESKEY_CRM_meta_notify_promote_resource OCF_RESKEY_CRM_meta_notify_promote_resource promote_resource promote_resourceNotification Environment Variable Notification Environment Variable " msgstr "" #. Tag: para #, no-c-format msgid "OCF_RESKEY_CRM_meta_notify_demote_resource" msgstr "OCF_RESKEY_CRM_meta_notify_demote_resource" #. Tag: para #, no-c-format msgid "Resources to be demoted Environment VariableOCF_RESKEY_CRM_meta_notify_demote_resource OCF_RESKEY_CRM_meta_notify_demote_resource demote_resource demote_resourceNotification Environment Variable Notification Environment Variable " msgstr "" #. Tag: para #, no-c-format msgid "OCF_RESKEY_CRM_meta_notify_promote_uname" msgstr "OCF_RESKEY_CRM_meta_notify_promote_uname" #. Tag: para #, no-c-format msgid "Nodes on which resources will be promote Environment VariableOCF_RESKEY_CRM_meta_notify_promote_uname OCF_RESKEY_CRM_meta_notify_promote_uname promote_uname promote_unameNotification Environment Variable Notification Environment Variable " msgstr "" #. Tag: para #, no-c-format msgid "OCF_RESKEY_CRM_meta_notify_demote_uname" msgstr "OCF_RESKEY_CRM_meta_notify_demote_uname" #. Tag: para #, no-c-format msgid "Nodes on which resources will be demoted Environment VariableOCF_RESKEY_CRM_meta_notify_demote_uname OCF_RESKEY_CRM_meta_notify_demote_uname demote_uname demote_unameNotification Environment Variable Notification Environment Variable " msgstr "" #. Tag: para #, no-c-format msgid "OCF_RESKEY_CRM_meta_notify_master_uname" msgstr "OCF_RESKEY_CRM_meta_notify_master_uname" #. Tag: para #, no-c-format msgid "Nodes on which resources are running in Master mode Environment VariableOCF_RESKEY_CRM_meta_notify_master_uname OCF_RESKEY_CRM_meta_notify_master_uname master_uname master_unameNotification Environment Variable Notification Environment Variable " msgstr "" #. Tag: para #, no-c-format msgid "OCF_RESKEY_CRM_meta_notify_slave_uname" msgstr "OCF_RESKEY_CRM_meta_notify_slave_uname" #. Tag: para #, no-c-format msgid "Nodes on which resources are running in Slave mode Environment VariableOCF_RESKEY_CRM_meta_notify_slave_uname OCF_RESKEY_CRM_meta_notify_slave_uname slave_uname slave_unameNotification Environment Variable Notification Environment Variable " msgstr "" #. Tag: title #, fuzzy, no-c-format msgid "Multi-state - Proper Interpretation of Notification Environment Variables" msgstr "Corretta interpretazione delle variabili di notifica d'ambiente" #. Tag: title #, fuzzy, no-c-format msgid "Pre-notification (demote):" msgstr "Pre-notification (demote)" #. Tag: para #, fuzzy, no-c-format msgid "Active resources: $OCF_RESKEY_CRM_meta_notify_active_resource" msgstr "Risorse attive: $OCF_RESKEY_CRM_meta_notify_active_resource" #. Tag: para #, fuzzy, no-c-format msgid "Master resources: $OCF_RESKEY_CRM_meta_notify_master_resource" msgstr "Risorse master: $OCF_RESKEY_CRM_meta_notify_master_resource" #. Tag: para #, fuzzy, no-c-format msgid "Slave resources: $OCF_RESKEY_CRM_meta_notify_slave_resource" msgstr "Risorse slave: $OCF_RESKEY_CRM_meta_notify_slave_resource" #. Tag: para #, fuzzy, no-c-format msgid "Resources to be promoted: $OCF_RESKEY_CRM_meta_notify_promote_resource" msgstr "Risorse da promuovere: $OCF_RESKEY_CRM_meta_notify_promote_resource" #. Tag: para #, fuzzy, no-c-format msgid "Resources to be demoted: $OCF_RESKEY_CRM_meta_notify_demote_resource" msgstr "Risorse da degradare: $OCF_RESKEY_CRM_meta_notify_demote_resource" #. Tag: title #, fuzzy, no-c-format msgid "Post-notification (demote) / Pre-notification (stop):" msgstr "Post-notification (demote) / Pre-notification (stop)" #. Tag: para #, fuzzy, no-c-format msgid "Master resources:" msgstr "Risorse master:" #. Tag: para #, fuzzy, no-c-format msgid "$OCF_RESKEY_CRM_meta_notify_master_resource" msgstr "$OCF_RESKEY_CRM_meta_notify_master_resource" #. Tag: para #, fuzzy, no-c-format msgid "minus $OCF_RESKEY_CRM_meta_notify_demote_resource" msgstr "meno $OCF_RESKEY_CRM_meta_notify_demote_resource" #. Tag: para #, fuzzy, no-c-format msgid "Resources that were demoted: $OCF_RESKEY_CRM_meta_notify_demote_resource" msgstr "Risorse che sono state degradate: $OCF_RESKEY_CRM_meta_notify_demote_resource" #. Tag: title #, no-c-format msgid "Post-notification (stop) / Pre-notification (start)" msgstr "Post-notification (stop) / Pre-notification (start)" #. Tag: para #, fuzzy, no-c-format msgid "Active resources:" msgstr "Risorse attive:" #. Tag: para #, fuzzy, no-c-format msgid "Slave resources:" msgstr "Risorse slave:" #. Tag: para #, fuzzy, no-c-format msgid "$OCF_RESKEY_CRM_meta_notify_slave_resource" msgstr "$OCF_RESKEY_CRM_meta_notify_slave_resource" #. Tag: title #, no-c-format msgid "Post-notification (start) / Pre-notification (promote)" msgstr "Post-notification (start) / Pre-notification (promote)" #. Tag: title #, no-c-format msgid "Post-notification (promote)" msgstr "Post-notification (promote)" #. Tag: para #, fuzzy, no-c-format msgid "plus $OCF_RESKEY_CRM_meta_notify_promote_resource" msgstr "più $OCF_RESKEY_CRM_meta_notify_promote_resource" #. Tag: para #, fuzzy, no-c-format msgid "minus $OCF_RESKEY_CRM_meta_notify_promote_resource" msgstr "meno $OCF_RESKEY_CRM_meta_notify_promote_resource" #. Tag: para #, fuzzy, no-c-format msgid "Resources that were promoted: $OCF_RESKEY_CRM_meta_notify_promote_resource" msgstr "Risorse che sono state promosse: $OCF_RESKEY_CRM_meta_notify_promote_resource" #~ msgid "id" #~ msgstr "id" #~ msgid "Your name for the group" #~ msgstr "Nome del gruppo" #~ msgid "Using Groups" #~ msgstr "Utilizzare i gruppi" #~ msgid "Your name for the clone" #~ msgstr "Nome del clone" #~ msgid "Options inherited from simple resources: priority, target-role, is-managed" #~ msgstr "Opzioni ereditate da simple resources: priority, target-role, is-managed" #~ msgid "clone-max" #~ msgstr "clone-max" #~ msgid "How many copies of the resource to start. Defaults to the number of nodes in the cluster." #~ msgstr "Quante copie della risorsa è necessario avviare. Il valore di default è il numero dei nodi del cluster." #~ msgid "clone-node-max" #~ msgstr "clone-node-max" #~ msgid "How many copies of the resource can be started on a single node. Defaults to 1." #~ msgstr "Quante copie della risorsa possono essere avviate sul singolo nodo. Il default è 1." #~ msgid "notify" #~ msgstr "notify" #~ msgid "When stopping or starting a copy of the clone, tell all the other copies beforehand and when the action was successful. Allowed values: true, false" #~ msgstr "Quando una copia del clone viene avviata o stoppata, comunica l'azione in anticipo alle altre copie e comunica quando l'azione ha successo. Valori permessi: true, false" #~ msgid "Does each copy of the clone perform a different function? Allowed values: true, false" #~ msgstr "Ogni copia del clone può eseguire funzioni differenti? Valori permessi: true, false" #~ msgid "ordered" #~ msgstr "ordered" #~ msgid "Should the copies be started in series (instead of in parallel). Allowed values: true, false" #~ msgstr "Le copie devono essere avviate in serie (anziché in parallelo)? Valori permessi: true, false" #~ msgid "interleave" #~ msgstr "interleave" #~ msgid "Changes the behavior of ordering constraints (between clones/masters) so that instances can start/stop as soon as their peer instance has (rather than waiting for every instance of the other clone has). Allowed values: true, false" #~ msgstr "Modifica il comportamento delle constraint di tipo order (fra cloni/master) in modo che le istanze possano essere avviate e stoppate appena le rispettive istanze lo sono (anziché aspettare che ogni istanza degli altri cloni sia stata avviata o stoppata). Valori permessi: true, false" #~ msgid "Using Clones" #~ msgstr "Utilizzare le risorse clone" #~ msgid "Allowed values: pre, post" #~ msgstr "Valori permessi: pre, post" #~ msgid "Allowed values: start, stop" #~ msgstr "Valori permessi: start, stop" #~ msgid "Resources to be started" #~ msgstr "La risorsa da avviare" #~ msgid "Resources the that are running" #~ msgstr "Le risorse che stanno funzionando" #~ msgid "Resources the that are not running" #~ msgstr "Le risorse che non stanno funzionando" #~ msgid "Nodes on which resources will be started" #~ msgstr "I nodi su cui le risorse verranno avviate" #~ msgid "Nodes on which resources will be stopped" #~ msgstr "I nodi su cui le risorse verranno stoppate" #~ msgid "Nodes on which resources are running" #~ msgstr "I nodi su cui le risorse stanno funzionando" #~ msgid "Nodes on which resources are not running" #~ msgstr "I nodi su cui le risorse non stanno funzionando" #~ msgid "OCF_RESKEY_CRM_meta_notify_start_uname="sles-1 sles-3 sles-2"" #~ msgstr "OCF_RESKEY_CRM_meta_notify_start_uname="sles-1 sles-3 sles-2"" #~ msgid "Your name for the multi-state resource" #~ msgstr "Nome della risorsa multi-state" #~ msgid "master-max" #~ msgstr "master-max" #~ msgid "How many copies of the resource can be promoted to master status. Defaults to 1." #~ msgstr "Quante copie della risorsa possono essere promosse allo status master. Valore di default 1." #~ msgid "How many copies of the resource can be promoted to master status on a single node. Defaults to 1." #~ msgstr "Quante copie della risorsa possono essere promosse allo status master su un singolo nodo. Valore di default 1." #~ msgid "rsc-role" #~ msgstr "rsc-role" #~ msgid "An additional attribute of colocation constraints that specifies the role that rsc must be in." #~ msgstr "Un'attributo aggiuntivo di una constraint colocation che specifica il ruolo in cui la risorsa (rsc) dovrà trovarsi." #~ msgid "Allowed values: Started, Master, Slave" #~ msgstr "Valori permessi: Started, Master, Slave" #~ msgid "with-rsc-role" #~ msgstr "with-rsc-role" #~ msgid "An additional attribute of colocation constraints that specifies the role that with-rsc must be in." #~ msgstr "Un'attributo aggiuntivo di una constraint colocation che specifica il ruolo in cui la risorsa associata (with-rsc) dovrà trovarsi." #~ msgid "first-action" #~ msgstr "first-action" #~ msgid "An additional attribute of ordering constraints that specifies the action that the first resource must complete before executing the specified action for the then resource." #~ msgstr "Un'attributo aggiuntivo di una constraint di tipo order che specifica l'azione che la prima risorsa dovrà completare prima di eseguire l'azione specificata per la risorsa successiva." #~ msgid "Allowed values: start, stop, promote, demote" #~ msgstr "Valori permessi: start, stop, promote, demote" #~ msgid "then-action" #~ msgstr "then-action" #~ msgid "An additional attribute of ordering constraints that specifies the action that the then resource can only execute after the first-action on the first resource has completed." #~ msgstr "Un'attributo aggiuntivo di una constraint di tipo order che specifica l'azione che la risorsa successiva potrà eseguire solamente dopo che l'azione first-action sulla prima risorsa sarà completata." #~ msgid "Allowed values: start, stop, promote, demote. Defaults to the value (specified or implied) of first-action" #~ msgstr "Valori permessi: start, stop, promote, demote. Il valore di default (specificato o implicito) è quello relativo a first-action" #~ msgid "Stopped" #~ msgstr "Stoppato" #~ msgid "Running (Slave)" #~ msgstr "Attivo (Slave)" #~ msgid "Running (Master)" #~ msgstr "Attivo (Master)" #~ msgid "Failed (Master)" #~ msgstr "Fallito (Master)" #~ msgid "Resources that are running in Master mode" #~ msgstr "Risorse che stanno funzionando in modalità master" #~ msgid "Resources that are running in Slave mode" #~ msgstr "Risorse che stanno funzionando in modalità slave" #~ msgid "Resources to be promoted" #~ msgstr "Risorse da promuovere" #~ msgid "Resources to be demoted" #~ msgstr "Risorse da degradare" #~ msgid "Nodes on which resources will be promoted" #~ msgstr "Nodi su cui la risorsa verrà promossa" #~ msgid "Nodes on which resources will be demoted" #~ msgstr "Nodi su cui la risorsa verrà degradata" #~ msgid "Nodes on which resources are running in Master mode" #~ msgstr "Nodi su cui le risorse stanno funzionando in modalità master" #~ msgid "Nodes on which resources are running in Slave mode" #~ msgstr "Nodi su cui le risorse stanno funzionando in modalità slave" pacemaker-master/doc/Pacemaker_Explained/it-IT/Ch-Basics.po000066400000000000000000001100221217637305600237550ustar00rootroot00000000000000# # AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: 0\n" "POT-Creation-Date: 2012-10-17T05:19:02\n" "PO-Revision-Date: 2011-04-19 12:07+0100\n" "Last-Translator: RaSca \n" "Language-Team: None\n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. Tag: title #, no-c-format msgid "Configuration Basics" msgstr "Nozioni di base sulla configurazione" #. Tag: title #, no-c-format msgid "Configuration Layout" msgstr "Layout della configurazione" #. Tag: para #, fuzzy, no-c-format msgid "The cluster is written using XML notation and divided into two main sections: configuration and status." msgstr "Il cluster viene scritto utilizzando la notazione XML e diviso in due sezioni principali; configuration e status." #. Tag: para #, fuzzy, no-c-format msgid "The status section contains the history of each resource on each node and based on this data, the cluster can construct the complete current state of the cluster. The authoritative source for the status section is the local resource manager (lrmd) process on each cluster node and the cluster will occasionally repopulate the entire section. For this reason it is never written to disk and administrators are advised against modifying it in any way." msgstr "La sezione status coniente lo storico di ciascuna risorsa in ciascun nodo e, sulla base di questi dati, il cluster può risalire al suo stato attuale. La sorgente autoritativa della sezione status è il processo local resource manager (lrmd) su ciascun nodo del cluster ed il cluster potrà occasionalmente ripopolare l'intera sezione. Per questa ragione essa non è mai scritta sul disco e gli amministratori sono allertati di non modificarla in alcuna maniera." #. Tag: para #, no-c-format msgid "The configuration section contains the more traditional information like cluster options, lists of resources and indications of where they should be placed. The configuration section is the primary focus of this document." msgstr "La sezione configuration contiene le informazioni più tradizionali come le opzioni del cluster, la lista delle risorse ed indicazioni su dove queste dovranno essere poste. La comprensione della sezione configuration è l'obiettivo primario di questo documento." #. Tag: para #, no-c-format msgid "The configuration section itself is divided into four parts:" msgstr "La sezione configuration è a sua volta divisa in quattro parti:" #. Tag: para #, no-c-format msgid "Configuration options (called crm_config)" msgstr "Opzioni di configurazione (chiamata crm_config)" #. Tag: para #, no-c-format msgid "Nodes" msgstr "Nodi" #. Tag: para #, no-c-format msgid "Resources" msgstr "Risorse" #. Tag: para #, no-c-format msgid "Resource relationships (called constraints)" msgstr "Relazioni delle risorse (chiamate constraints)" #. Tag: title #, no-c-format msgid "An empty configuration" msgstr "Una configurazione vuota" #. Tag: programlisting #, fuzzy, no-c-format msgid "" " <cib admin_epoch=\"0\" epoch=\"0\" num_updates=\"0\" have-quorum=\"false\">\n" " <configuration>\n" " <crm_config/>\n" " <nodes/>\n" " <resources/>\n" " <constraints/>\n" " </configuration>\n" " <status/>\n" " </cib>" msgstr "" "\n" "\n" " <cib generated="true" admin_epoch="0" epoch="0" num_updates="0" have-quorum="false">\n" " <configuration>\n" " <crm_config/>\n" " <nodes/>\n" " <resources/>\n" " <constraints/>\n" " </configuration>\n" " <status/>\n" " </cib>\n" "\n" "\t" #. Tag: title #, no-c-format msgid "The Current State of the Cluster" msgstr "Lo stato attuale del Cluster" #. Tag: para #, fuzzy, no-c-format msgid "Before one starts to configure a cluster, it is worth explaining how to view the finished product. For this purpose we have created the crm_mon utility that will display the current state of an active cluster. It can show the cluster status by node or by resource and can be used in either single-shot or dynamically-updating mode. There are also modes for displaying a list of the operations performed (grouped by node and resource) as well as information about failures." msgstr "Prima di iniziare a configurare il cluster, vale la pena spiegare come sia possibile visionare lo stato del prodotto finito. Per questo scopo è stato creato il comando crm_mon, una utility che visualizzerà lo stato attuale di un Cluster attivo. Questo comando può visualizzare lo stato del cluster in base ai nodi o alle risorse e può essere utilizzato in modalità comando singolo o aggiornamento dinamico. Esistono poi modi per visualizzare una lista di operazioni eseguite (raggruppate per nodo o risorsa) così come informazioni in merito ai fallimenti." #. Tag: para #, no-c-format msgid "Using this tool, you can examine the state of the cluster for irregularities and see how it responds when you cause or simulate failures." msgstr "Utilizzando questo strumento è possibile esaminare le irregolarità presenti nello stato del Cluster e vedere come questo risponda una volta che tali problemi si verificano o vengono simulati." #. Tag: para #, fuzzy, no-c-format msgid "Details on all the available options can be obtained using the crm_mon --help command." msgstr "Dettagli su tutte le opzioni disponibili possono essere ottenuti utilizzando il comando crm_mon --help." #. Tag: title #, no-c-format msgid "Sample output from crm_mon" msgstr "Esempio dell'output di crm_mon" #. Tag: screen #, fuzzy, no-c-format msgid "" " ============\n" " Last updated: Fri Nov 23 15:26:13 2007\n" " Current DC: sles-3 (2298606a-6a8c-499a-9d25-76242f7006ec)\n" " 3 Nodes configured.\n" " 5 Resources configured.\n" " ============\n" "\n" " Node: sles-1 (1186dc9a-324d-425a-966e-d757e693dc86): online\n" " 192.168.100.181 (heartbeat::ocf:IPaddr): Started sles-1\n" " 192.168.100.182 (heartbeat:IPaddr): Started sles-1\n" " 192.168.100.183 (heartbeat::ocf:IPaddr): Started sles-1\n" " rsc_sles-1 (heartbeat::ocf:IPaddr): Started sles-1\n" " child_DoFencing:2 (stonith:external/vmware): Started sles-1\n" " Node: sles-2 (02fb99a8-e30e-482f-b3ad-0fb3ce27d088): standby\n" " Node: sles-3 (2298606a-6a8c-499a-9d25-76242f7006ec): online\n" " rsc_sles-2 (heartbeat::ocf:IPaddr): Started sles-3\n" " rsc_sles-3 (heartbeat::ocf:IPaddr): Started sles-3\n" " child_DoFencing:0 (stonith:external/vmware): Started sles-3" msgstr "" "\n" " # crm_mon\n" " ============\n" " Last updated: Fri Nov 23 15:26:13 2007\n" " Current DC: sles-3 (2298606a-6a8c-499a-9d25-76242f7006ec)\n" " 3 Nodes configured.\n" " 5 Resources configured.\n" " ============\n" "\n" " Node: sles-1 (1186dc9a-324d-425a-966e-d757e693dc86): online\n" " 192.168.100.181 (heartbeat::ocf:IPaddr): Started sles-1\n" " 192.168.100.182 (heartbeat:IPaddr): Started sles-1\n" " 192.168.100.183 (heartbeat::ocf:IPaddr): Started sles-1\n" " rsc_sles-1 (heartbeat::ocf:IPaddr): Started sles-1\n" " child_DoFencing:2 (stonith:external/vmware): Started sles-1\n" " Node: sles-2 (02fb99a8-e30e-482f-b3ad-0fb3ce27d088): standby\n" " Node: sles-3 (2298606a-6a8c-499a-9d25-76242f7006ec): online\n" " rsc_sles-2 (heartbeat::ocf:IPaddr): Started sles-3\n" " rsc_sles-3 (heartbeat::ocf:IPaddr): Started sles-3\n" " child_DoFencing:0 (stonith:external/vmware): Started sles-3" #. Tag: title #, no-c-format msgid "Sample output from crm_mon -n" msgstr "Esempio dell'output di crm_mon -n" #. Tag: screen #, fuzzy, no-c-format msgid "" " ============\n" " Last updated: Fri Nov 23 15:26:13 2007\n" " Current DC: sles-3 (2298606a-6a8c-499a-9d25-76242f7006ec)\n" " 3 Nodes configured.\n" " 5 Resources configured.\n" " ============\n" "\n" " Node: sles-1 (1186dc9a-324d-425a-966e-d757e693dc86): online\n" " Node: sles-2 (02fb99a8-e30e-482f-b3ad-0fb3ce27d088): standby\n" " Node: sles-3 (2298606a-6a8c-499a-9d25-76242f7006ec): online\n" "\n" " Resource Group: group-1\n" " 192.168.100.181 (heartbeat::ocf:IPaddr): Started sles-1\n" " 192.168.100.182 (heartbeat:IPaddr): Started sles-1\n" " 192.168.100.183 (heartbeat::ocf:IPaddr): Started sles-1\n" " rsc_sles-1 (heartbeat::ocf:IPaddr): Started sles-1\n" " rsc_sles-2 (heartbeat::ocf:IPaddr): Started sles-3\n" " rsc_sles-3 (heartbeat::ocf:IPaddr): Started sles-3\n" " Clone Set: DoFencing\n" " child_DoFencing:0 (stonith:external/vmware): Started sles-3\n" " child_DoFencing:1 (stonith:external/vmware): Stopped\n" " child_DoFencing:2 (stonith:external/vmware): Started sles-1" msgstr "" "\n" " # crm_mon -n\n" " ============\n" " Last updated: Fri Nov 23 15:26:13 2007\n" " Current DC: sles-3 (2298606a-6a8c-499a-9d25-76242f7006ec)\n" " 3 Nodes configured.\n" " 5 Resources configured.\n" " ============\n" "\n" " Node: sles-1 (1186dc9a-324d-425a-966e-d757e693dc86): online\n" " Node: sles-2 (02fb99a8-e30e-482f-b3ad-0fb3ce27d088): standby\n" " Node: sles-3 (2298606a-6a8c-499a-9d25-76242f7006ec): online\n" "\n" " Resource Group: group-1\n" " 192.168.100.181 (heartbeat::ocf:IPaddr): Started sles-1\n" " 192.168.100.182 (heartbeat:IPaddr): Started sles-1\n" " 192.168.100.183 (heartbeat::ocf:IPaddr): Started sles-1\n" " rsc_sles-1 (heartbeat::ocf:IPaddr): Started sles-1\n" " rsc_sles-2 (heartbeat::ocf:IPaddr): Started sles-3\n" " rsc_sles-3 (heartbeat::ocf:IPaddr): Started sles-3\n" " Clone Set: DoFencing\n" " child_DoFencing:0 (stonith:external/vmware): Started sles-3\n" " child_DoFencing:1 (stonith:external/vmware): Stopped\n" " child_DoFencing:2 (stonith:external/vmware): Started sles-1" #. Tag: para #, no-c-format msgid "The DC (Designated Controller) node is where all the decisions are made and if the current DC fails a new one is elected from the remaining cluster nodes. The choice of DC is of no significance to an administrator beyond the fact that its logs will generally be more interesting." msgstr "Sul nodo DC (Designated Controller) vengono prese tutte le decisioni e se l'attuale DC fallisce, uno nuovo viene eletto partendo dai nodi rimanenti. La scelta del DC non è di competenza dell'amministratore, mentre lo sono i log generati dallo stesso." #. Tag: title #, no-c-format msgid "How Should the Configuration be Updated?" msgstr "Come dovrebbe essere aggiornata la configurazione?" #. Tag: para #, no-c-format msgid "There are three basic rules for updating the cluster configuration:" msgstr "Ci sono tre regole base per aggiornare la configurazione del cluster:" #. Tag: para #, fuzzy, no-c-format msgid "Rule 1 - Never edit the cib.xml file manually. Ever. I’m not making this up." msgstr "Regola 1 - Non modificare MAI il file cib.xml manualmente. Mai. Non è un semplice suggerimento, ma una regola da rispettare." #. Tag: para #, no-c-format msgid "Rule 2 - Read Rule 1 again." msgstr "Regola 2 - Leggere nuovamente la regola 1." #. Tag: para #, no-c-format msgid "Rule 3 - The cluster will notice if you ignored rules 1 & 2 and refuse to use the configuration." msgstr "Regola 3 - Il cluster noterà se sono state ignorate le regole 1 e 2 e si rifiuterà di utilizzare la configurazione." #. Tag: para #, no-c-format msgid "Now that it is clear how NOT to update the configuration, we can begin to explain how you should." msgstr "Ora che è chiaro com NON modificare la configurazione, è possibile spiegare come invece si debba fare." #. Tag: para #, fuzzy, no-c-format msgid "The most powerful tool for modifying the configuration is the cibadmin command which talks to a running cluster. With cibadmin, the user can query, add, remove, update or replace any part of the configuration; all changes take effect immediately, so there is no need to perform a reload-like operation." msgstr "Lo strumento più potente per modificare la configurazione è il comando cibadmin che comunica direttamente con un cluster attivo. Con cibadmin l'utente può interrogare, aggiungere, rimuovere, aggiornare o rimpiazzare qualsiasi parte della configurazione. Tutti i cambiamenti avvengono istantaneamente, quindi non è necessario effettuare operazioni come reload." #. Tag: para #, fuzzy, no-c-format msgid "The simplest way of using cibadmin is to use it to save the current configuration to a temporary file, edit that file with your favorite text or XML editor and then upload the revised configuration." msgstr "La via pià semplice per utilizzare cibadmin è quella di salvare l'attuale configurazione in un file temporaneo, modificare questo file con il proprio editor di testo (o XML) preferito e quindi caricare la nuova configurazione." #. Tag: title #, no-c-format msgid "Safely using an editor to modify the cluster configuration" msgstr "Utilizzare un editor per modificare la configurazione del cluster in sicurezza" #. Tag: programlisting #, fuzzy, no-c-format msgid "" "# cibadmin --query > tmp.xml\n" "# vi tmp.xml\n" "# cibadmin --replace --xml-file tmp.xml" msgstr "" "\n" " cibadmin --query > tmp.xml\n" " vi tmp.xml\n" " cibadmin --replace --xml-file tmp.xml\n" "\t" #. Tag: para #, fuzzy, no-c-format msgid "Some of the better XML editors can make use of a Relax NG schema to help make sure any changes you make are valid. The schema describing the configuration can normally be found in /usr/lib/heartbeat/pacemaker.rng on most systems." msgstr "Alcuni dei migliori editor XML possono utilizzare uno schema Relax NG per avere la certezza che ogni cambiamento effettuato sia valido. Lo schema che descrive la configurazione può essere normalmente trovato nel file /usr/lib/heartbeat/pacemaker.rng presente sulla maggior parte dei sistemi." #. Tag: para #, no-c-format msgid "If you only wanted to modify the resources section, you could instead do" msgstr "Se invece la necessità è quella di modificare unicamente la sezione risores, allora è possibile fare" #. Tag: title #, no-c-format msgid "Safely using an editor to modify a subsection of the cluster configuration" msgstr "Utilizzare in sicurezza un editor per modificare una sotto sezione della configurazione del cluster" #. Tag: programlisting #, fuzzy, no-c-format msgid "" "# cibadmin --query --obj_type resources > tmp.xml\n" "# vi tmp.xml\n" "# cibadmin --replace --obj_type resources --xml-file tmp.xml" msgstr "" "\n" " cibadmin --query --obj_type resources > tmp.xml\n" " vi tmp.xml\n" " cibadmin --replace --obj_type resources --xml-file tmp.xml\n" "\t" #. Tag: para #, no-c-format msgid "to avoid modifying any other part of the configuration." msgstr "per consentire la modifica di qualsiasi altra parte della configurazione." #. Tag: title #, no-c-format msgid "Quickly Deleting Part of the Configuration" msgstr "Eliminare velocemente parte della configurazione" #. Tag: para #, fuzzy, no-c-format msgid "Identify the object you wish to delete. Eg. run" msgstr "Identificare l'oggetto da rimuovere, ad esempio" #. Tag: title #, no-c-format msgid "Searching for STONITH related configuration items" msgstr "Ricerca di oggetti relativi alla configurazione di STONITH" #. Tag: programlisting #, no-c-format msgid "# cibadmin -Q | grep stonith" msgstr "" #. Tag: programlisting #, fuzzy, no-c-format msgid "" " <nvpair id=\"cib-bootstrap-options-stonith-action\" name=\"stonith-action\" value=\"reboot\"/>\n" " <nvpair id=\"cib-bootstrap-options-stonith-enabled\" name=\"stonith-enabled\" value=\"1\"/>\n" " <primitive id=\"child_DoFencing\" class=\"stonith\" type=\"external/vmware\">\n" " <lrm_resource id=\"child_DoFencing:0\" type=\"external/vmware\" class=\"stonith\">\n" " <lrm_resource id=\"child_DoFencing:0\" type=\"external/vmware\" class=\"stonith\">\n" " <lrm_resource id=\"child_DoFencing:1\" type=\"external/vmware\" class=\"stonith\">\n" " <lrm_resource id=\"child_DoFencing:0\" type=\"external/vmware\" class=\"stonith\">\n" " <lrm_resource id=\"child_DoFencing:2\" type=\"external/vmware\" class=\"stonith\">\n" " <lrm_resource id=\"child_DoFencing:0\" type=\"external/vmware\" class=\"stonith\">\n" " <lrm_resource id=\"child_DoFencing:3\" type=\"external/vmware\" class=\"stonith\">" msgstr "" "\n" " # cibadmin -Q | grep stonith\n" "\n" " <nvpair id="cib-bootstrap-options-stonith-action" name="stonith-action" value="reboot"/>\n" " <nvpair id="cib-bootstrap-options-stonith-enabled" name="stonith-enabled" value="1"/>\n" " <primitive id="child_DoFencing" class="stonith" type="external/vmware">\n" " <lrm_resource id="child_DoFencing:0" type="external/vmware" class="stonith">\n" " <lrm_resource id="child_DoFencing:0" type="external/vmware" class="stonith">\n" " <lrm_resource id="child_DoFencing:1" type="external/vmware" class="stonith">\n" " <lrm_resource id="child_DoFencing:0" type="external/vmware" class="stonith">\n" " <lrm_resource id="child_DoFencing:2" type="external/vmware" class="stonith">\n" " <lrm_resource id="child_DoFencing:0" type="external/vmware" class="stonith">\n" " <lrm_resource id="child_DoFencing:3" type="external/vmware" class="stonith">\n" #. Tag: para #, fuzzy, no-c-format msgid "Next identify the resource’s tag name and id (in this case we’ll choose primitive and child_DoFencing). Then simply execute:" msgstr "Quindi identificare il tag delle risorse e l'id (in questo caso verranno selezionati primitive e child_DoFencing). Quindi eseguire semplicemente:" #. Tag: programlisting #, fuzzy, no-c-format msgid "# cibadmin --delete --crm_xml '<primitive id=\"child_DoFencing\"/>'" msgstr "cibadmin --delete --crm_xml ‘<primitive id="child_DoFencing"/>'" #. Tag: title #, no-c-format msgid "Updating the Configuration Without Using XML" msgstr "Aggiornare la configurazione senza utilizzare XML" #. Tag: para #, no-c-format msgid "Some common tasks can also be performed with one of the higher level tools that avoid the need to read or edit XML." msgstr "Alcune operazioni comuni possono essere eseguite con uno dei tanti strumenti ad alto livello, per ovviare alla necessità di leggere o modificare XML." #. Tag: para #, no-c-format msgid "To enable stonith for example, one could run:" msgstr "Per abilitare stonith, ad esempio, è possibile lanciare:" #. Tag: programlisting #, fuzzy, no-c-format msgid "# crm_attribute --attr-name stonith-enabled --attr-value true" msgstr "crm_attribute --attr-name stonith-enabled --attr-value true" #. Tag: para #, fuzzy, no-c-format msgid "Or, to see if somenode is allowed to run resources, there is:" msgstr "O per vedere se qualche nodo è abilitato ad erogare risorse, esiste:" #. Tag: programlisting #, fuzzy, no-c-format msgid "# crm_standby --get-value --node-uname somenode" msgstr "crm_standby --get-value --node-uname somenode" #. Tag: para #, fuzzy, no-c-format msgid "Or, to find the current location of my-test-rsc, one can use:" msgstr "O per trovare la posizione attuale di my-test-rsc è possibile lanciare:" #. Tag: programlisting #, fuzzy, no-c-format msgid "# crm_resource --locate --resource my-test-rsc" msgstr "crm_resource --locate --resource my-test-rsc" #. Tag: title #, no-c-format msgid "Making Configuration Changes in a Sandbox" msgstr "Effettuare modifiche alla configurazione in un ambiente di prova" #. Tag: para #, fuzzy, no-c-format msgid "Often it is desirable to preview the effects of a series of changes before updating the configuration atomically. For this purpose we have created crm_shadow which creates a \"shadow\" copy of the configuration and arranges for all the command line tools to use it." msgstr "A volte esiste la necessità di prevedere gli effetti di una serie di modifiche prima di aggiornare automaticamente la configurazione. A questo scopo è stato creato crm_shadow che crea una copia "shadow" della configurazione e la organizza affinché tutti gli strumenti da linea di comando possano utilizzarla." #. Tag: para #, fuzzy, no-c-format msgid "To begin, simply invoke crm_shadow and give it the name of a configuration to create Shadow copies are identified with a name, making it possible to have more than one. ; be sure to follow the simple on-screen instructions." msgstr "Per iniziare è sufficiente lanciare crm_shadow passando come parametro il nome della configurazione da creare Tutte le copie Shadow sono identificate da un nome, rendendo così possibile l'esistenza di più copie contemporaneamente ed essendo sicuri di segure le semplici istruzioni che appaiono." #. Tag: para #, fuzzy, no-c-format msgid "Read the above carefully, failure to do so could result in you destroying the cluster’s active configuration!" msgstr "Leggere quanto segue attentamente, tale mancanza potrebbe portare alla distruzione della configurazione attiva del cluster" #. Tag: title #, no-c-format msgid "Creating and displaying the active sandbox" msgstr "Creazione e visualizzazione dell'ambiente di test" #. Tag: programlisting #, fuzzy, no-c-format msgid "" " # crm_shadow --create test\n" " Setting up shadow instance\n" " Type Ctrl-D to exit the crm_shadow shell\n" " shadow[test]:\n" " shadow[test] # crm_shadow --which\n" " test" msgstr "" "\n" " # crm_shadow --create test\n" " Setting up shadow instance\n" " Type Ctrl-D to exit the crm_shadow shell\n" " shadow[test]: \n" " shadow[test] # crm_shadow --which\n" " test" #. Tag: para #, fuzzy, no-c-format msgid "From this point on, all cluster commands will automatically use the shadow copy instead of talking to the cluster’s active configuration. Once you have finished experimenting, you can either commit the changes, or discard them as shown below. Again, be sure to follow the on-screen instructions carefully." msgstr "Da questo punto in poi, tutti i comandi cluster utilizzeranno automaticamente la copia shadow anziché la copia attiva della configurazione del cluster. Una volta terminate le sperimentazione, è possibile effettuare la registrazione delle modifiche oppure scartare le stesse come mostrato sotto. Di nuovo, porre estrema attenzione alle istruzioni da seguire che appaiono a schermo." #. Tag: para #, fuzzy, no-c-format msgid "For a full list of crm_shadow options and commands, invoke it with the <parameter>--help</parameter> option." msgstr "Per una lista competa delle opzioni e comandi di crm_shadow è possibile lanciare il comando con il parametro --help." #. Tag: title #, no-c-format msgid "Using a sandbox to make multiple changes atomically" msgstr "Utilizzare un ambiente di test per effettuare più cambiamenti contemporaneamente" #. Tag: programlisting #, fuzzy, no-c-format msgid "" " shadow[test] # crm_failcount -G -r rsc_c001n01\n" " name=fail-count-rsc_c001n01 value=0\n" " shadow[test] # crm_standby -v on -n c001n02\n" " shadow[test] # crm_standby -G -n c001n02\n" " name=c001n02 scope=nodes value=on\n" " shadow[test] # cibadmin --erase --force\n" " shadow[test] # cibadmin --query\n" " <cib cib_feature_revision=\"1\" validate-with=\"pacemaker-1.0\" admin_epoch=\"0\" crm_feature_set=\"3.0\" have-quorum=\"1\" epoch=\"112\"\n" " dc-uuid=\"c001n01\" num_updates=\"1\" cib-last-written=\"Fri Jun 27 12:17:10 2008\">\n" " <configuration>\n" " <crm_config/>\n" " <nodes/>\n" " <resources/>\n" " <constraints/>\n" " </configuration>\n" " <status/>\n" " </cib>\n" " shadow[test] # crm_shadow --delete test --force\n" " Now type Ctrl-D to exit the crm_shadow shell\n" " shadow[test] # exit\n" " # crm_shadow --which\n" " No shadow instance provided\n" " # cibadmin -Q\n" " <cib cib_feature_revision=\"1\" validate-with=\"pacemaker-1.0\" admin_epoch=\"0\" crm_feature_set=\"3.0\" have-quorum=\"1\" epoch=\"110\"\n" " dc-uuid=\"c001n01\" num_updates=\"551\">\n" " <configuration>\n" " <crm_config>\n" " <cluster_property_set id=\"cib-bootstrap-options\">\n" " <nvpair id=\"cib-bootstrap-1\" name=\"stonith-enabled\" value=\"1\"/>\n" " <nvpair id=\"cib-bootstrap-2\" name=\"pe-input-series-max\" value=\"30000\"/>" msgstr "" "\n" " shadow[test] # crm_failcount -G -r rsc_c001n01\n" " name=fail-count-rsc_c001n01 value=0\n" " shadow[test] # crm_standby -v on -n c001n02\n" " shadow[test] # crm_standby -G -n c001n02\n" " name=c001n02 scope=nodes value=on\n" " shadow[test] # cibadmin --erase --force\n" " shadow[test] # cibadmin --query\n" "\n" " <cib cib_feature_revision="1" validate-with="pacemaker-1.0" admin_epoch="0" crm_feature_set="3.0" have-quorum="1" epoch="112"\n" " dc-uuid="c001n01" num_updates="1" cib-last-written="Fri Jun 27 12:17:10 2008">\n" " <configuration>\n" " <crm_config/>\n" " <nodes/>\n" " <resources/>\n" " <constraints/>\n" " </configuration>\n" " <status/>\n" " </cib>\n" "\n" " shadow[test] # crm_shadow --delete test --force\n" " Now type Ctrl-D to exit the crm_shadow shell\n" " shadow[test] # exit\n" " # crm_shadow --which\n" " No shadow instance provided\n" " # cibadmin -Q\n" "\n" " <cib cib_feature_revision="1" validate-with="pacemaker-1.0" admin_epoch="0" crm_feature_set="3.0" have-quorum="1" epoch="110"\n" " dc-uuid="c001n01" num_updates="551">\n" " <configuration>\n" " <crm_config>\n" " <cluster_property_set id="cib-bootstrap-options">\n" " <nvpair id="cib-bootstrap-1" name="stonith-enabled" value="1"/>\n" " <nvpair id="cib-bootstrap-2" name="pe-input-series-max" value="30000"/>\n" "\n" "\t" #. Tag: para #, no-c-format msgid "Making changes in a sandbox and verifying the real configuration is untouched" msgstr "Effettuare i cambiamenti nell'ambiente di test e verificare che la configurazione reale sia intonsa" #. Tag: title #, no-c-format msgid "Testing Your Configuration Changes" msgstr "Testare le proprie modifiche" #. Tag: para #, fuzzy, no-c-format msgid "We saw previously how to make a series of changes to a \"shadow\" copy of the configuration. Before loading the changes back into the cluster (eg. crm_shadow --commit mytest --force), it is often advisable to simulate the effect of the changes with crm_simulate, eg." msgstr "E' stato mostrato in precedenza come effettuare seie di cambiamente alle copie "shadow" della configurazione. Prima di caricare tali modifiche nel cluster (ad esempio con crm_shadow --commit mytest --force), a olte può essere necessario simulare l'effetto dei cambiamenti con ptest. Ad esempio." #. Tag: programlisting #, fuzzy, no-c-format msgid "# crm_simulate --live-check -VVVVV --save-graph tmp.graph --save-dotfile tmp.dot" msgstr "ptest --live-check -VVVVV --save-graph tmp.graph --save-dotfile tmp.dot" #. Tag: para #, fuzzy, no-c-format msgid "The tool uses the same library as the live cluster to show what it would have done given the supplied input. It’s output, in addition to a significant amount of logging, is stored in two files tmp.graph and tmp.dot, both are representations of the same thing — the cluster’s response to your changes." msgstr "Lo strumento utilizza la stessa libreria del cluster attivo per mostrare cosa succederebbe con l'input definito. L'output del programma, insieme a parecchi messaggi di log, è registrato in due files tmp.graph e tmp.dot. Entrambi sono rappresentazioni della stessa cosa: la risposta del cluster ai cambiamenti effettuati. Nel file grafico è registrata la transizione completa, contenente una lista di tutte le azioni, i parametri ed i pre-requisiti. A causa del fatto che il grafico di transizione non è propriamente semplice da leggere, il tool genera anche un dot-file Graphviz, rappresentante le stesse informazioni." #. Tag: para #, fuzzy, no-c-format msgid "In the graph file is stored the complete transition, containing a list of all the actions, their parameters and their pre-requisites. Because the transition graph is not terribly easy to read, the tool also generates a Graphviz dot-file representing the same information." msgstr "Lo strumento utilizza la stessa libreria del cluster attivo per mostrare cosa succederebbe con l'input definito. L'output del programma, insieme a parecchi messaggi di log, è registrato in due files tmp.graph e tmp.dot. Entrambi sono rappresentazioni della stessa cosa: la risposta del cluster ai cambiamenti effettuati. Nel file grafico è registrata la transizione completa, contenente una lista di tutte le azioni, i parametri ed i pre-requisiti. A causa del fatto che il grafico di transizione non è propriamente semplice da leggere, il tool genera anche un dot-file Graphviz, rappresentante le stesse informazioni." #. Tag: title #, no-c-format msgid "Interpreting the Graphviz output" msgstr "Interpretare l'output di Graphviz" #. Tag: para #, no-c-format msgid "Arrows indicate ordering dependencies" msgstr "Le frecce indicano le dipendenze relative all'ordine" #. Tag: para #, no-c-format msgid "Dashed-arrows indicate dependencies that are not present in the transition graph" msgstr "Le frecce tratteggiate indicano dipendenze che non sono presenti nel grafico di transizione" #. Tag: para #, no-c-format msgid "Actions with a dashed border of any color do not form part of the transition graph" msgstr "Azioni con un bordo tratteggiato di qualsiasi colore non fanno parte del grafico di transizione" #. Tag: para #, no-c-format msgid "Actions with a green border form part of the transition graph" msgstr "Azioni con un bordo verde sono parte del grafico di transizione" #. Tag: para #, fuzzy, no-c-format msgid "Actions with a red border are ones the cluster would like to execute but cannot run" msgstr "Azioni con un bordo rosso sono azioni che il cluster vorrebbe eseguire, ma non è possibile farlo" #. Tag: para #, no-c-format msgid "Actions with a blue border are ones the cluster does not feel need to be executed" msgstr "Azioni con un bordo blu sono azioni che il cluster non sente il bisogno di eseguire" #. Tag: para #, no-c-format msgid "Actions with orange text are pseudo/pretend actions that the cluster uses to simplify the graph" msgstr "Azioni con un testo arancione sono pseudo azioni che il cluster utilizza per semplificare il grafico" #. Tag: para #, no-c-format msgid "Actions with black text are sent to the LRM" msgstr "Azioni con un testo nero sono inviate a LRM" #. Tag: para #, no-c-format msgid "Resource actions have text of the form rsc_action_interval node" msgstr "Azioni relative alle risorse hanno un testo nella forma rsc_action_interval node" #. Tag: para #, no-c-format msgid "Any action depending on an action with a red border will not be able to execute." msgstr "Ogni azione dipendente da un'azione con un bordo rosso non avrà la possibilità di essere eseguita" #. Tag: para #, no-c-format msgid "Loops are really bad. Please report them to the development team." msgstr "I loop sono qualcosa di veramente negativo. Essi vanno riportati al team di sviluppo." #. Tag: title #, no-c-format msgid "Small Cluster Transition" msgstr "Una piccola transizione del cluster" #. Tag: phrase #, no-c-format msgid "An example transition graph as represented by Graphviz" msgstr "Un esempio di grafico di transizione come rappresentato da Graphviz" #. Tag: para #, no-c-format msgid "In the above example, it appears that a new node, node2, has come online and that the cluster is checking to make sure rsc1, rsc2 and rsc3 are not already running there (Indicated by the *_monitor_0 entries). Once it did that, and assuming the resources were not active there, it would have liked to stop rsc1 and rsc2 on node1 and move them to node2. However, there appears to be some problem and the cluster cannot or is not permitted to perform the stop actions which implies it also cannot perform the start actions. For some reason the cluster does not want to start rsc3 anywhere." msgstr "Nell'esempio soprastante appare come un nuovo nodo, node2, è giunto online e che il cluster sta controllando che rsc1, rsc2 e rsc3 non stiano già funzionando su di esso (indicato dalle entry *_monitor_0). Una volta completato il controllo ed assunto che le risorse non sono attive qui, il cluster vorrebbe stoppare rsc1 ed rsc2 su node1 e muovere tali risorse su node2. Tuttavia, sembrano esserci problemi ed il cluster non può o non riesce ad effettuare lo azioni di stop, che implicano quindi l'impossibilità di eseguire le azioni di start. Per qualche ragione il cluster non vuole avviare rsc3 da nessuna parte." #. Tag: para #, fuzzy, no-c-format msgid "For information on the options supported by crm_simulate, use the --help option." msgstr "Per informazioni sulle opzioni supportate da ptest, utilizzare ptest --help" #. Tag: title #, no-c-format msgid "Complex Cluster Transition" msgstr "Una complessa transizione del cluster" #. Tag: phrase #, fuzzy, no-c-format msgid "Another, slightly more complex, transition graph that you're not expected to be able to read" msgstr "Un altro grafico di transizione leggermente più complesso, (particolarmente complicato da leggere)" #. Tag: title #, no-c-format msgid "Do I Need to Update the Configuration on all Cluster Nodes?" msgstr "Esiste l'esigenza di aggiornare la configurazione su tutti i nodi del cluster?" #. Tag: para #, no-c-format msgid "No. Any changes are immediately synchronized to the other active members of the cluster." msgstr "No. Ogni modifica è immediatamente sincronizzata con gli altri membri attivi del cluster." #. Tag: para #, fuzzy, no-c-format msgid "To reduce bandwidth, the cluster only broadcasts the incremental updates that result from your changes and uses MD5 checksums to ensure that each copy is completely consistent." msgstr "Per ridurre la banda utilizzata il cluster effettua il broadcast incrementale degli aggiornamenti risultanti i cambiamenti effettuati ed utilizza sum MD5 per assicurare che ciascuna copia sia completamente consistente." pacemaker-master/doc/Pacemaker_Explained/it-IT/Ch-Constraints.po000066400000000000000000001055141217637305600250720ustar00rootroot00000000000000# # AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: 0\n" "POT-Creation-Date: 2012-10-17T05:19:02\n" "PO-Revision-Date: 2011-05-03 15:38+0100\n" "Last-Translator: RaSca \n" "Language-Team: None\n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. Tag: title #, no-c-format msgid "Resource Constraints" msgstr "Vincoli delle risorse" #. Tag: para #, no-c-format msgid " ResourceConstraints Constraints " msgstr "" #. Tag: title #, no-c-format msgid "Scores" msgstr "Punteggi" #. Tag: para #, no-c-format msgid "Scores of all kinds are integral to how the cluster works. Practically everything from moving a resource to deciding which resource to stop in a degraded cluster is achieved by manipulating scores in some way." msgstr "Nel funzionamento del cluster sono integrati punteggi di ogni tipo. Praticamente qualsiasi decisione, dallo spostamento di una risorsa sino a quale risorsa fermare in un cluster degradato, è ottenuta manipolando in qualche forma i punteggi." #. Tag: para #, fuzzy, no-c-format msgid "Scores are calculated on a per-resource basis and any node with a negative score for a resource can’t run that resource. After calculating the scores for a resource, the cluster then chooses the node with the highest one." msgstr "I punteggi sono calcolati sulla base per l'erogazione di ogni risorsa e qualsiasi nodo con un punteggio negativo non può erogare la risorsa associata. Dopo aver calcolato i punteggi per una risorsa il cluster sceglie il nodo con il punteggio più alto." #. Tag: title #, no-c-format msgid "Infinity Math" msgstr "Il valore INFINITY" #. Tag: para #, fuzzy, no-c-format msgid "INFINITY is currently defined as 1,000,000 and addition/subtraction with it follows these three basic rules:" msgstr "INFINITY viene attualmente definito come 1,000,000 ed addizioni/sottrazioni ad esso seguono queste 3 regole base:" #. Tag: para #, no-c-format msgid "Any value + INFINITY = INFINITY" msgstr "Qualsiasi valore + INFINITY = INFINITY" #. Tag: para #, no-c-format msgid "Any value - INFINITY = -INFINITY" msgstr "Qualsiasi valore - INFINITY = -INFINITY" #. Tag: para #, no-c-format msgid "INFINITY - INFINITY = -INFINITY" msgstr "INFINITY - INFINITY = -INFINITY" #. Tag: title #, no-c-format msgid "Deciding Which Nodes a Resource Can Run On" msgstr "Decidere quale nodo può erogare una risorsa" #. Tag: para #, fuzzy, no-c-format msgid " Location Constraints ResourceConstraintsLocation ConstraintsLocation Location There are two alternative strategies for specifying which nodes a resources can run on. One way is to say that by default they can run anywhere and then create location constraints for nodes that are not allowed. The other option is to have nodes \"opt-in\"… to start with nothing able to run anywhere and selectively enable allowed nodes." msgstr "Esistono due strategie alternative per specificare su quali nodi può funzionare una risorsa. Una via è quella di dire che di default la risorsa può funzionare ovunque e poi create dei vincoli posizionali (location constraints) per i nodi da escludere. L'altra via è quella di avere nodi che vengano avviati come inabili ad erogare risorse ed fare in modo che questi vengano abilitati selettivamente." #. Tag: title #, no-c-format msgid "Options" msgstr "Opzioni" #. Tag: title #, no-c-format msgid "Options for Simple Location Constraints" msgstr "Opzioni per semplici vincoli di locazione (location constraints)" #. Tag: entry #, no-c-format msgid "Field" msgstr "Campo" #. Tag: entry #, no-c-format msgid "Description" msgstr "Descrizione" #. Tag: para #, no-c-format msgid "id" msgstr "" #. Tag: para #, no-c-format msgid "A unique name for the constraint idLocation Constraints Location Constraints ConstraintsLocationid Locationid id " msgstr "" #. Tag: para #, no-c-format msgid "rsc" msgstr "" #. Tag: para #, no-c-format msgid "A resource name rscLocation Constraints Location Constraints ConstraintsLocationrsc Locationrsc rsc " msgstr "" #. Tag: para #, no-c-format msgid "node" msgstr "" #. Tag: para #, no-c-format msgid "A node’s name nodeLocation Constraints Location Constraints ConstraintsLocationnode Locationnode node " msgstr "" #. Tag: para #, no-c-format msgid "score" msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "Positive values indicate the resource should run on this node. Negative values indicate the resource should not run on this node." msgstr "Valori positivi indicano che la risorsa può funzionare su questo nodo. Valori negativi indicano che la risorsa non può funzionare su questo nodo. Valori di +/- INFINITY modificano "può" in "deve"." #. Tag: para #, no-c-format msgid "Values of +/- INFINITY change \"should\"/\"should not\" to \"must\"/\"must not\". scoreLocation Constraints Location Constraints ConstraintsLocationscore Locationscore score " msgstr "" #. Tag: title #, fuzzy, no-c-format msgid "Asymmetrical \"Opt-In\" Clusters" msgstr "Cluster "Opt-In" asimmetrici" #. Tag: para #, no-c-format msgid " Asymmetrical Opt-In Clusters Cluster TypeAsymmetrical Opt-In Asymmetrical Opt-In " msgstr "" #. Tag: para #, no-c-format msgid "To create an opt-in cluster, start by preventing resources from running anywhere by default:" msgstr "" #. Tag: programlisting #, no-c-format msgid "# crm_attribute --attr-name symmetric-cluster --attr-value false" msgstr "" #. Tag: para #, no-c-format msgid "Then start enabling nodes. The following fragment says that the web server prefers sles-1, the database prefers sles-2 and both can fail over to sles-3 if their most preferred node fails." msgstr "" #. Tag: title #, no-c-format msgid "Example set of opt-in location constraints" msgstr "" #. Tag: programlisting #, no-c-format msgid "" "<constraints>\n" " <rsc_location id=\"loc-1\" rsc=\"Webserver\" node=\"sles-1\" score=\"200\"/>\n" " <rsc_location id=\"loc-2\" rsc=\"Webserver\" node=\"sles-3\" score=\"0\"/>\n" " <rsc_location id=\"loc-3\" rsc=\"Database\" node=\"sles-2\" score=\"200\"/>\n" " <rsc_location id=\"loc-4\" rsc=\"Database\" node=\"sles-3\" score=\"0\"/>\n" "</constraints>" msgstr "" #. Tag: title #, fuzzy, no-c-format msgid "Symmetrical \"Opt-Out\" Clusters" msgstr "Cluster "Opt-In" asimmetrici" #. Tag: para #, no-c-format msgid " Symmetrical Opt-Out Clusters Cluster TypeSymmetrical Opt-Out Symmetrical Opt-Out " msgstr "" #. Tag: para #, no-c-format msgid "To create an opt-out cluster, start by allowing resources to run anywhere by default:" msgstr "" #. Tag: programlisting #, no-c-format msgid "# crm_attribute --attr-name symmetric-cluster --attr-value true" msgstr "" #. Tag: para #, no-c-format msgid "Then start disabling nodes. The following fragment is the equivalent of the above opt-in configuration." msgstr "" #. Tag: title #, no-c-format msgid "Example set of opt-out location constraints" msgstr "" #. Tag: programlisting #, no-c-format msgid "" "<constraints>\n" " <rsc_location id=\"loc-1\" rsc=\"Webserver\" node=\"sles-1\" score=\"200\"/>\n" " <rsc_location id=\"loc-2-dont-run\" rsc=\"Webserver\" node=\"sles-2\" score=\"-INFINITY\"/>\n" " <rsc_location id=\"loc-3-dont-run\" rsc=\"Database\" node=\"sles-1\" score=\"-INFINITY\"/>\n" " <rsc_location id=\"loc-4\" rsc=\"Database\" node=\"sles-2\" score=\"200\"/>\n" "</constraints>" msgstr "" #. Tag: para #, no-c-format msgid "Whether you should choose opt-in or opt-out depends both on your personal preference and the make-up of your cluster. If most of your resources can run on most of the nodes, then an opt-out arrangement is likely to result in a simpler configuration. On the other-hand, if most resources can only run on a small subset of nodes an opt-in configuration might be simpler." msgstr "" #. Tag: title #, no-c-format msgid "What if Two Nodes Have the Same Score" msgstr "" #. Tag: para #, no-c-format msgid "If two nodes have the same score, then the cluster will choose one. This choice may seem random and may not be what was intended, however the cluster was not given enough information to know any better." msgstr "" #. Tag: title #, no-c-format msgid "Example of two resources that prefer two nodes equally" msgstr "" #. Tag: programlisting #, no-c-format msgid "" "<constraints>\n" " <rsc_location id=\"loc-1\" rsc=\"Webserver\" node=\"sles-1\" score=\"INFINITY\"/>\n" " <rsc_location id=\"loc-2\" rsc=\"Webserver\" node=\"sles-2\" score=\"INFINITY\"/>\n" " <rsc_location id=\"loc-3\" rsc=\"Database\" node=\"sles-1\" score=\"500\"/>\n" " <rsc_location id=\"loc-4\" rsc=\"Database\" node=\"sles-2\" score=\"300\"/>\n" " <rsc_location id=\"loc-5\" rsc=\"Database\" node=\"sles-2\" score=\"200\"/>\n" "</constraints>" msgstr "" #. Tag: para #, no-c-format msgid "In the example above, assuming no other constraints and an inactive cluster, Webserver would probably be placed on sles-1 and Database on sles-2. It would likely have placed Webserver based on the node’s uname and Database based on the desire to spread the resource load evenly across the cluster. However other factors can also be involved in more complex configurations." msgstr "" #. Tag: title #, no-c-format msgid "Specifying in which Order Resources Should Start/Stop" msgstr "" #. Tag: para #, no-c-format msgid " ResourceConstraintsOrdering ConstraintsOrdering Ordering ResourceStart Order Start Order Ordering Constraints The way to specify the order in which resources should start is by creating rsc_order constraints." msgstr "" #. Tag: title #, no-c-format msgid "Properties of an Ordering Constraint" msgstr "" #. Tag: para #, no-c-format msgid "A unique name for the constraint idOrdering Constraints Ordering Constraints ConstraintsOrderingid Orderingid id " msgstr "" #. Tag: para #, no-c-format msgid "first" msgstr "" #. Tag: para #, no-c-format msgid "The name of a resource that must be started before the then resource is allowed to. firstOrdering Constraints Ordering Constraints ConstraintsOrderingfirst Orderingfirst first " msgstr "" #. Tag: para #, no-c-format msgid "then" msgstr "" #. Tag: para #, no-c-format msgid "The name of a resource. This resource will start after the first resource. thenOrdering Constraints Ordering Constraints ConstraintsOrderingthen Orderingthen then " msgstr "" #. Tag: para #, no-c-format msgid "kind" msgstr "" #. Tag: para #, no-c-format msgid "How to enforce the constraint. (Since 1.1.2)" msgstr "" #. Tag: para #, no-c-format msgid "* Optional - Just a suggestion. Only applies if both resources are starting/stopping." msgstr "" #. Tag: para #, no-c-format msgid "* Mandatory - Always. If first is stopping or cannot be started, then must be stopped." msgstr "" #. Tag: para #, no-c-format msgid "* Serialize - Ensure that no two stop/start actions occur concurrently for a set of resources." msgstr "" #. Tag: para #, no-c-format msgid " kindOrdering Constraints Ordering Constraints ConstraintsOrderingkind Orderingkind kind " msgstr "" #. Tag: para #, no-c-format msgid "symmetrical" msgstr "" #. Tag: para #, no-c-format msgid "If true, which is the default, stop the resources in the reverse order. Default value: true symmetricalOrdering Constraints Ordering Constraints Ordering Constraintssymmetrical symmetrical " msgstr "" #. Tag: title #, no-c-format msgid "Mandatory Ordering" msgstr "" #. Tag: para #, no-c-format msgid "When the then resource cannot run without the first resource being active, one should use mandatory constraints. To specify a constraint is mandatory, use scores greater than zero. This will ensure that the then resource will react when the first resource changes state." msgstr "" #. Tag: para #, no-c-format msgid "If the first resource was running and is stopped, the then resource will also be stopped (if it is running)." msgstr "" #. Tag: para #, no-c-format msgid "If the first resource was not running and cannot be started, the then resource will be stopped (if it is running)." msgstr "" #. Tag: para #, no-c-format msgid "If the first resource is (re)started while the then resource is running, the then resource will be stopped and restarted." msgstr "" #. Tag: title #, no-c-format msgid "Advisory Ordering" msgstr "" #. Tag: para #, no-c-format msgid "On the other hand, when score=\"0\" is specified for a constraint, the constraint is considered optional and only has an effect when both resources are stopping and/or starting. Any change in state by the first resource will have no effect on the then resource." msgstr "" #. Tag: title #, no-c-format msgid "Example of an optional and mandatory ordering constraint" msgstr "" #. Tag: programlisting #, no-c-format msgid "" "<constraints>\n" " <rsc_order id=\"order-1\" first=\"Database\" then=\"Webserver\" />\n" " <rsc_order id=\"order-2\" first=\"IP\" then=\"Webserver\" score=\"0\"/>\n" "</constraints>" msgstr "" #. Tag: para #, no-c-format msgid "Some additional information on ordering constraints can be found in the document Ordering Explained." msgstr "" #. Tag: title #, no-c-format msgid "Placing Resources Relative to other Resources" msgstr "" #. Tag: para #, no-c-format msgid " ResourceConstraintsColocation ConstraintsColocation Colocation ResourceLocation Relative to other Resources Location Relative to other Resources When the location of one resource depends on the location of another one, we call this colocation." msgstr "" #. Tag: para #, no-c-format msgid "There is an important side-effect of creating a colocation constraint between two resources: it affects the order in which resources are assigned to a node. If you think about it, it’s somewhat obvious. You can’t place A relative to B unless you know where B is. While the human brain is sophisticated enough to read the constraint in any order and choose the correct one depending on the situation, the cluster is not quite so smart. Yet. " msgstr "" #. Tag: para #, no-c-format msgid "So when you are creating colocation constraints, it is important to consider whether you should colocate A with B or B with A." msgstr "" #. Tag: para #, no-c-format msgid "Another thing to keep in mind is that, assuming A is collocated with B, the cluster will also take into account A’s preferences when deciding which node to choose for B." msgstr "" #. Tag: para #, no-c-format msgid "For a detailed look at exactly how this occurs, see the Colocation Explained document." msgstr "" #. Tag: title #, no-c-format msgid "Properties of a Collocation Constraint" msgstr "" #. Tag: para #, no-c-format msgid "A unique name for the constraint. idColocation Constraints Colocation Constraints ConstraintsColocationid Colocationid id " msgstr "" #. Tag: para #, no-c-format msgid "The colocation source. If the constraint cannot be satisfied, the cluster may decide not to allow the resource to run at all. rscColocation Constraints Colocation Constraints ConstraintsColocationrsc Colocationrsc rsc " msgstr "" #. Tag: para #, no-c-format msgid "with-rsc" msgstr "" #. Tag: para #, no-c-format msgid "The colocation target. The cluster will decide where to put this resource first and then decide where to put the resource in the rsc field. with-rscColocation Constraints Colocation Constraints ConstraintsColocationwith-rsc Colocationwith-rsc with-rsc " msgstr "" #. Tag: para #, no-c-format msgid "Positive values indicate the resource should run on the same node. Negative values indicate the resources should not run on the same node. Values of +/- INFINITY change \"should\" to \"must\". scoreColocation Constraints Colocation Constraints ConstraintsColocationscore Colocationscore score " msgstr "" #. Tag: title #, no-c-format msgid "Mandatory Placement" msgstr "" #. Tag: para #, no-c-format msgid "Mandatory placement occurs any time the constraint’s score is +INFINITY or -INFINITY. In such cases, if the constraint can’t be satisfied, then the rsc resource is not permitted to run. For score=INFINITY, this includes cases where the with-rsc resource is not active." msgstr "" #. Tag: para #, no-c-format msgid "If you need resource1 to always run on the same machine as resource2, you would add the following constraint:" msgstr "" #. Tag: title #, no-c-format msgid "An example colocation constraint" msgstr "" #. Tag: programlisting #, no-c-format msgid "<rsc_colocation id=\"colocate\" rsc=\"resource1\" with-rsc=\"resource2\" score=\"INFINITY\"/>" msgstr "" #. Tag: para #, no-c-format msgid "Remember, because INFINITY was used, if resource2 can’t run on any of the cluster nodes (for whatever reason) then resource1 will not be allowed to run." msgstr "" #. Tag: para #, no-c-format msgid "Alternatively, you may want the opposite… that resource1 cannot run on the same machine as resource2. In this case use score=\"-INFINITY\"" msgstr "" #. Tag: title #, no-c-format msgid "An example anti-colocation constraint" msgstr "" #. Tag: programlisting #, no-c-format msgid "<rsc_colocation id=\"anti-colocate\" rsc=\"resource1\" with-rsc=\"resource2\" score=\"-INFINITY\"/>" msgstr "" #. Tag: para #, no-c-format msgid "Again, by specifying -INFINTY, the constraint is binding. So if the only place left to run is where resource2 already is, then resource1 may not run anywhere." msgstr "" #. Tag: title #, no-c-format msgid "Advisory Placement" msgstr "" #. Tag: para #, no-c-format msgid "If mandatory placement is about \"must\" and \"must not\", then advisory placement is the \"I’d prefer if\" alternative. For constraints with scores greater than -INFINITY and less than INFINITY, the cluster will try and accommodate your wishes but may ignore them if the alternative is to stop some of the cluster resources." msgstr "" #. Tag: para #, no-c-format msgid "Like in life, where if enough people prefer something it effectively becomes mandatory, advisory colocation constraints can combine with other elements of the configuration to behave as if they were mandatory." msgstr "" #. Tag: title #, no-c-format msgid "An example advisory-only colocation constraint" msgstr "" #. Tag: programlisting #, no-c-format msgid "<rsc_colocation id=\"colocate-maybe\" rsc=\"resource1\" with-rsc=\"resource2\" score=\"500\"/>" msgstr "" #. Tag: title #, no-c-format msgid "Ordering Sets of Resources" msgstr "" #. Tag: para #, no-c-format msgid "A common situation is for an administrator to create a chain of ordered resources, such as:" msgstr "" #. Tag: title #, no-c-format msgid "A chain of ordered resources" msgstr "" #. Tag: programlisting #, no-c-format msgid "" "<constraints>\n" " <rsc_order id=\"order-1\" first=\"A\" then=\"B\" />\n" " <rsc_order id=\"order-2\" first=\"B\" then=\"C\" />\n" " <rsc_order id=\"order-3\" first=\"C\" then=\"D\" />\n" "</constraints>" msgstr "" #. Tag: title #, no-c-format msgid "Ordered Set" msgstr "" #. Tag: title #, no-c-format msgid "Visual representation of the four resources' start order for the above constraints" msgstr "" #. Tag: phrase #, no-c-format msgid "Ordered set" msgstr "" #. Tag: para #, no-c-format msgid "To simplify this situation, there is an alternate format for ordering constraints:" msgstr "" #. Tag: title #, no-c-format msgid "A chain of ordered resources expressed as a set" msgstr "" #. Tag: programlisting #, no-c-format msgid "" "<constraints>\n" " <rsc_order id=\"order-1\">\n" " <resource_set id=\"ordered-set-example\" sequential=\"true\">\n" " <resource_ref id=\"A\"/>\n" " <resource_ref id=\"B\"/>\n" " <resource_ref id=\"C\"/>\n" " <resource_ref id=\"D\"/>\n" " </resource_set>\n" " </rsc_order>\n" "</constraints>" msgstr "" #. Tag: para #, no-c-format msgid "Resource sets have the same ordering semantics as groups." msgstr "" #. Tag: title #, no-c-format msgid "A group resource with the equivalent ordering rules" msgstr "" #. Tag: programlisting #, no-c-format msgid "" "<group id=\"dummy\">\n" " <primitive id=\"A\" .../>\n" " <primitive id=\"B\" .../>\n" " <primitive id=\"C\" .../>\n" " <primitive id=\"D\" .../>\n" "</group>" msgstr "" #. Tag: para #, no-c-format msgid "While the set-based format is not less verbose, it is significantly easier to get right and maintain. It can also be expanded to allow ordered sets of (un)ordered resources. In the example below, rscA and rscB can both start in parallel, as can rscC and rscD, however rscC and rscD can only start once both rscA and rscB are active." msgstr "" #. Tag: title #, no-c-format msgid "Ordered sets of unordered resources" msgstr "" #. Tag: programlisting #, no-c-format msgid "" "<constraints>\n" " <rsc_order id=\"order-1\">\n" " <resource_set id=\"ordered-set-1\" sequential=\"false\">\n" " <resource_ref id=\"A\"/>\n" " <resource_ref id=\"B\"/>\n" " </resource_set>\n" " <resource_set id=\"ordered-set-2\" sequential=\"false\">\n" " <resource_ref id=\"C\"/>\n" " <resource_ref id=\"D\"/>\n" " </resource_set>\n" " </rsc_order>\n" " </constraints>" msgstr "" #. Tag: title #, no-c-format msgid "Two Sets of Unordered Resources" msgstr "" #. Tag: title #, no-c-format msgid "Visual representation of the start order for two ordered sets of unordered resources" msgstr "" #. Tag: phrase #, no-c-format msgid "Two ordered sets" msgstr "" #. Tag: para #, no-c-format msgid "Of course either set — or both sets — of resources can also be internally ordered (by setting sequential=\"true\") and there is no limit to the number of sets that can be specified." msgstr "" #. Tag: title #, no-c-format msgid "Advanced use of set ordering - Three ordered sets, two of which are internally unordered" msgstr "" #. Tag: programlisting #, no-c-format msgid "" "<constraints>\n" " <rsc_order id=\"order-1\">\n" " <resource_set id=\"ordered-set-1\" sequential=\"false\">\n" " <resource_ref id=\"A\"/>\n" " <resource_ref id=\"B\"/>\n" " </resource_set>\n" " <resource_set id=\"ordered-set-2\" sequential=\"true\">\n" " <resource_ref id=\"C\"/>\n" " <resource_ref id=\"D\"/>\n" " </resource_set>\n" " <resource_set id=\"ordered-set-3\" sequential=\"false\">\n" " <resource_ref id=\"E\"/>\n" " <resource_ref id=\"F\"/>\n" " </resource_set>\n" " </rsc_order>\n" "</constraints>" msgstr "" #. Tag: title #, no-c-format msgid "Three Resources Sets" msgstr "" #. Tag: title #, no-c-format msgid "Visual representation of the start order for the three sets defined above" msgstr "" #. Tag: phrase #, no-c-format msgid "Three ordered sets" msgstr "" #. Tag: title #, no-c-format msgid "Collocating Sets of Resources" msgstr "" #. Tag: para #, no-c-format msgid "Another common situation is for an administrator to create a set of collocated resources. Previously this was possible either by defining a resource group (See ) which could not always accurately express the design; or by defining each relationship as an individual constraint, causing a constraint explosion as the number of resources and combinations grew." msgstr "" #. Tag: title #, no-c-format msgid "A chain of collocated resources" msgstr "" #. Tag: programlisting #, no-c-format msgid "" "<constraints>\n" " <rsc_colocation id=\"coloc-1\" rsc=\"B\" with-rsc=\"A\" score=\"INFINITY\"/>\n" " <rsc_colocation id=\"coloc-2\" rsc=\"C\" with-rsc=\"B\" score=\"INFINITY\"/>\n" " <rsc_colocation id=\"coloc-3\" rsc=\"D\" with-rsc=\"C\" score=\"INFINITY\"/>\n" "</constraints>" msgstr "" #. Tag: para #, no-c-format msgid "To make things easier, we allow an alternate form of colocation constraints using resource_sets. Just like the expanded version, a resource that can’t be active also prevents any resource that must be collocated with it from being active. For example, if B was not able to run, then both C (+and by inference +D) must also remain stopped." msgstr "" #. Tag: title #, no-c-format msgid "The equivalent colocation chain expressed using resource_sets" msgstr "" #. Tag: programlisting #, no-c-format msgid "" "<constraints>\n" " <rsc_colocation id=\"coloc-1\" score=\"INFINITY\" >\n" " <resource_set id=\"collocated-set-example\" sequential=\"true\">\n" " <resource_ref id=\"A\"/>\n" " <resource_ref id=\"B\"/>\n" " <resource_ref id=\"C\"/>\n" " <resource_ref id=\"D\"/>\n" " </resource_set>\n" " </rsc_colocation>\n" "</constraints>" msgstr "" #. Tag: para #, no-c-format msgid "Resource sets have the same colocation semantics as groups." msgstr "" #. Tag: title #, no-c-format msgid "A group resource with the equivalent colocation rules" msgstr "" #. Tag: para #, no-c-format msgid "This notation can also be used in this context to tell the cluster that a set of resources must all be located with a common peer, but have no dependencies on each other. In this scenario, unlike the previous, B would be allowed to remain active even if A or C (or both) were inactive." msgstr "" #. Tag: title #, no-c-format msgid "Using colocation sets to specify a common peer." msgstr "" #. Tag: programlisting #, no-c-format msgid "" "<constraints>\n" " <rsc_colocation id=\"coloc-1\" score=\"INFINITY\" >\n" " <resource_set id=\"collocated-set-1\" sequential=\"false\">\n" " <resource_ref id=\"A\"/>\n" " <resource_ref id=\"B\"/>\n" " <resource_ref id=\"C\"/>\n" " </resource_set>\n" " <resource_set id=\"collocated-set-2\" sequential=\"true\">\n" " <resource_ref id=\"D\"/>\n" " </resource_set>\n" " </rsc_colocation>\n" "</constraints>" msgstr "" #. Tag: para #, no-c-format msgid "Of course there is no limit to the number and size of the sets used. The only thing that matters is that in order for any member of set N to be active, all the members of set N+1 must also be active (and naturally on the same node); and if a set has sequential=\"true\", then in order for member M to be active, member M+1 must also be active. You can even specify the role in which the members of a set must be in using the set’s role attribute." msgstr "" #. Tag: title #, no-c-format msgid "A colocation chain where the members of the middle set have no inter-dependencies and the last has master status." msgstr "" #. Tag: programlisting #, no-c-format msgid "" "<constraints>\n" " <rsc_colocation id=\"coloc-1\" score=\"INFINITY\" >\n" " <resource_set id=\"collocated-set-1\" sequential=\"true\">\n" " <resource_ref id=\"A\"/>\n" " <resource_ref id=\"B\"/>\n" " </resource_set>\n" " <resource_set id=\"collocated-set-2\" sequential=\"false\">\n" " <resource_ref id=\"C\"/>\n" " <resource_ref id=\"D\"/>\n" " <resource_ref id=\"E\"/>\n" " </resource_set>\n" " <resource_set id=\"collocated-set-2\" sequential=\"true\" role=\"Master\">\n" " <resource_ref id=\"F\"/>\n" " <resource_ref id=\"G\"/>\n" " </resource_set>\n" " </rsc_colocation>\n" "</constraints>" msgstr "" #. Tag: title #, no-c-format msgid "Another Three Resources Sets" msgstr "" #. Tag: title #, no-c-format msgid "Visual representation of a colocation chain where the members of the middle set have no inter-dependencies" msgstr "" #. Tag: phrase #, no-c-format msgid "Colocation chain" msgstr "" #~ msgid "id" #~ msgstr "id" #~ msgid "A unique name for the constraint" #~ msgstr "Nome univoco per il vincolo (constraint)" #~ msgid "rsc" #~ msgstr "rsc" #~ msgid "A resource name" #~ msgstr "Nome della risorsa" #~ msgid "node" #~ msgstr "node" #~ msgid "A node's uname" #~ msgstr "uname del nodo" #~ msgid "score" #~ msgstr "punteggio" pacemaker-master/doc/Pacemaker_Explained/it-IT/Ch-Intro.po000066400000000000000000000435611217637305600236610ustar00rootroot00000000000000# # AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: 0\n" "POT-Creation-Date: 2012-10-17T05:19:02\n" "PO-Revision-Date: 2011-04-19 10:43+0100\n" "Last-Translator: RaSca \n" "Language-Team: None\n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. Tag: title #, no-c-format msgid "Read-Me-First" msgstr "Leggimi-Prima" #. Tag: title #, no-c-format msgid "The Scope of this Document" msgstr "Scopo di questo documento" #. Tag: para #, fuzzy, no-c-format msgid "The purpose of this document is to definitively explain the concepts used to configure Pacemaker. To achieve this, it will focus exclusively on the XML syntax used to configure the CIB." msgstr "Lo scopo di questo documento è quello di spiegare in maniera definitiva i concetti utilizzati per configurare Pacemaker. Per ottenere il meglio, si focalizzera' esclusivamente sulla sintassi XML per configurare il CIB." #. Tag: para #, fuzzy, no-c-format msgid "For those that are allergic to XML, there exist several unified shells and GUIs for Pacemaker. However these tools will not be covered at all in this document I hope, however, that the concepts explained here make the functionality of these tools more easily understood. , precisely because they hide the XML." msgstr "Per gli allergici ad XML, Pacemaker ha una cluster shell ed una GUI Python, ma questi tools non sono trattati nel presente documento Si spera comunque che una volta compresi i concetti qui esposti sarà più semplice comprendere anche questi tools. , proprio perché questi nascondono l'XML." #. Tag: para #, no-c-format msgid "Additionally, this document is NOT a step-by-step how-to guide for configuring a specific clustering scenario." msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "Although such guides exist, the purpose of this document is to provide an understanding of the building blocks that can be used to construct any type of Pacemaker cluster." msgstr "Inoltre, questo documento NON E' un how-to passo-passo per configurare uno specifico scenario cluster. Sebbene questo tipo di guide esista, lo scopo di questo documento è quello di fornire la comprensione delle componenti che possono essere utilizzate per costruire qualsiasi cluster Pacemaker." #. Tag: title #, no-c-format msgid "What Is Pacemaker?" msgstr "Cos'è Pacemaker?" #. Tag: para #, no-c-format msgid "Pacemaker is a cluster resource manager." msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "It achieves maximum availability for your cluster services (aka. resources) by detecting and recovering from node and resource-level failures by making use of the messaging and membership capabilities provided by your preferred cluster infrastructure (either Corosync or Heartbeat." msgstr "Pacemaker è un cluster resource manager. Ottiene la massima affidabilità per i servizi cluster (conosciuti come risorse) rilevando e ripristinando malfunziomenti di nodi e di risorse facendo uso delle capacità di messaging e membership fornite dalla tua infrastruttura cluster preferita (sia questa Corosync o Heartbeat)." #. Tag: para #, fuzzy, no-c-format msgid "Pacemaker’s key features include:" msgstr "Le caratteristiche di Pacemaker includono:" #. Tag: para #, no-c-format msgid "Detection and recovery of node and service-level failures" msgstr "Rilevazione e ripristino di malfunzionamenti di nodi e servizi" #. Tag: para #, no-c-format msgid "Storage agnostic, no requirement for shared storage" msgstr "Storage agnostic, non richiede uno storage condiviso" #. Tag: para #, no-c-format msgid "Resource agnostic, anything that can be scripted can be clustered" msgstr "Resource agnostic, tutto quello che può essere scriptato può essere clusterizzato" #. Tag: para #, no-c-format msgid "Supports STONITH for ensuring data integrity" msgstr "Supporto STONITH per garantire l'integrità dei dati" #. Tag: para #, no-c-format msgid "Supports large and small clusters" msgstr "Supporto a cluster grandi e piccoli" #. Tag: para #, no-c-format msgid "Supports both quorate and resource driven clusters" msgstr "Supporto a cluster quorati e resource driven" #. Tag: para #, no-c-format msgid "Supports practically any redundancy configuration" msgstr "Supporto a praticamente qualsiasi configurazione ridondata" #. Tag: para #, no-c-format msgid "Automatically replicated configuration that can be updated from any node" msgstr "Configurazione replicata automaticamente che può essere aggiornata da qualsiasi nodo" #. Tag: para #, no-c-format msgid "Ability to specify cluster-wide service ordering, colocation and anti-colocation" msgstr "Capacità di specificare ordine, collocazione e anti-collocazione per i servizi lato cluster" #. Tag: para #, no-c-format msgid "Support for advanced services type" msgstr "Supporto per servizi di tipo avanzato" #. Tag: para #, no-c-format msgid "Clones: for services which need to be active on multiple nodes" msgstr "Cloni: per servizi che necessitano di essere attivi su nodi multipli" #. Tag: para #, no-c-format msgid "Multi-state: for services with multiple modes (eg. master/slave, primary/secondary)" msgstr "Muliti-state: per servizi con modi multipli (ad esempio master/slave, primary/secondary/)" #. Tag: title #, no-c-format msgid "Types of Pacemaker Clusters" msgstr "Tipologia dei cluster Pacemaker" #. Tag: para #, no-c-format msgid "Pacemaker makes no assumptions about your environment, this allows it to support practically any redundancy configuration including Active/Active, Active/Passive, N+1, N+M, N-to-1 and N-to-N." msgstr "Pacemaker non fa alcuna ipotesi in merito all'ambiente operativo, questo consente di supportare praticamente qualsiasi configurazione ridondata come Active/Active, Active/Passive, N+1, N+M, N-to-1 e N-to-N." #. Tag: title #, no-c-format msgid "Active/Passive Redundancy" msgstr "Ridondanza Active/Passive" #. Tag: para #, no-c-format msgid "Two-node Active/Passive clusters using Pacemaker and DRBD are a cost-effective solution for many High Availability situations." msgstr "I cluster a due nodi Active/Passive che utilizzano Pacemaker e DRBD sono soluzioni con rapporto qualità-prezzo ottimale in molti ambiti di alta affidabilità." #. Tag: title #, no-c-format msgid "Shared Failover" msgstr "Failover condiviso" #. Tag: para #, no-c-format msgid "By supporting many nodes, Pacemaker can dramatically reduce hardware costs by allowing several active/passive clusters to be combined and share a common backup node" msgstr "Supportando più nodi, Pacemaker può ridurre drammaticamente i costi hardware consentendo a diversi cluster active/passive di combinare e condividere nodi di backup comuni" #. Tag: title #, no-c-format msgid "N to N Redundancy" msgstr "Ridondanza N a N" #. Tag: para #, no-c-format msgid "When shared storage is available, every node can potentially be used for failover. Pacemaker can even run multiple copies of services to spread out the workload." msgstr "Quando è disponibile uno storage condiviso ogni nodo può essere utilizzato per il failover. Pacemaker può anche eseguire copie multiple dei servizi per distribuire il carico di lavoro." #. Tag: title #, no-c-format msgid "Pacemaker Architecture" msgstr "Architettura di Pacemaker" #. Tag: para #, no-c-format msgid "At the highest level, the cluster is made up of three pieces:" msgstr "Al livello più elevato il cluster è composto da tre componenti:" #. Tag: para #, no-c-format msgid "Core cluster infrastructure providing messaging and membership functionality (illustrated in red)" msgstr "Infrastruttura core del cluster che rende disponibili le funzionalità di messaging e membership (illustrate in rosso)" #. Tag: para #, no-c-format msgid "Non-cluster aware components (illustrated in green)." msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "In a Pacemaker cluster, these pieces include not only the scripts that knows how to start, stop and monitor resources, but also a local daemon that masks the differences between the different standards these scripts implement." msgstr "Componenti non inerenti al cluster (illustrate in blu). In un cluster Pacemaker queste componenti includono non solo gli script che sanno come avviare, stoppare e monitorare le risorse, ma anche " #. Tag: para #, no-c-format msgid "A brain (illustrated in blue)" msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "This component processes and reacts to events from the cluster (nodes leaving or joining) and resources (eg. monitor failures) as well as configuration changes from the administrator. In response to all of these events, Pacemaker will compute the ideal state of the cluster and plot a path to achieve it. This may include moving resources, stopping nodes and even forcing nodes offline with remote power switches." msgstr "Un cervello (illustrato in verde) che reagisce e processa gli eventi del cluster (nodi scomparsi o apparsi) e delle risorse (ad esempio il controllo delle anomalie) così come le modifiche effettuate dall'amministratore. In risposta a tutti questi eventi, Pacemaker elaborerà l'ideale stato del cluster ed il piano per renderlo effettivo. Questo potrebbe includere lo spostamento delle risorse, lo stop di nodi fino alla forzatura offline di questi attraverso la rimozione dell'alimentazione remota." #. Tag: title #, no-c-format msgid "Conceptual Stack Overview" msgstr "Panoramica concettuale dello Stack" #. Tag: title #, no-c-format msgid "Conceptual overview of the cluster stack" msgstr "Panoramica concettuale dello stack del cluster" #. Tag: para #, no-c-format msgid "When combined with Corosync, Pacemaker also supports popular open source cluster filesystems. footnote:[ Even though Pacemaker also supports Heartbeat, the filesystems need to use the stack for messaging and membership and Corosync seems to be what they’re standardizing on." msgstr "" #. Tag: para #, no-c-format msgid "Technically it would be possible for them to support Heartbeat as well, however there seems little interest in this. ]" msgstr "" #. Tag: para #, no-c-format msgid "Due to recent standardization within the cluster filesystem community, they make use of a common distributed lock manager which makes use of Corosync for its messaging capabilities and Pacemaker for its membership (which nodes are up/down) and fencing services." msgstr "" #. Tag: title #, no-c-format msgid "The Pacemaker stack when running on Corosync" msgstr "Lo stack Pacemaker nell'esecuzione su Corosync" #. Tag: title #, no-c-format msgid "Internal Components" msgstr "Componenti interni" #. Tag: para #, no-c-format msgid "Pacemaker itself is composed of four key components (illustrated below in the same color scheme as the previous diagram):" msgstr "Pacemaker stesso è composto da quatto componenti chiave (illustrati sotto nello stesso schema di colori del diagramma precedente):" #. Tag: para #, no-c-format msgid "CIB (aka. Cluster Information Base)" msgstr "CIB (acronimo di come Cluster Information Base)" #. Tag: para #, no-c-format msgid "CRMd (aka. Cluster Resource Management daemon)" msgstr "CRMd (acronimo di Cluster Resource Management daemon)" #. Tag: para #, no-c-format msgid "PEngine (aka. PE or Policy Engine)" msgstr "PEngine (acronimo di Policy Engine)" #. Tag: para #, no-c-format msgid "STONITHd" msgstr "STONITHd" #. Tag: title #, fuzzy, no-c-format msgid "Subsystems of a Pacemaker cluster" msgstr "Sottosistemi di un cluster Pacemaker in esecuzione su Corosync" #. Tag: para #, fuzzy, no-c-format msgid "The CIB uses XML to represent both the cluster’s configuration and current state of all resources in the cluster. The contents of the CIB are automatically kept in sync across the entire cluster and are used by the PEngine to compute the ideal state of the cluster and how it should be achieved." msgstr "Il CIB utilizza XML per rappresentare sia l'attuale configurazione del cluster sia lo stato di tutte le risorse all'interno dello stesso. I contenuti del CIB sono automaticamente tenuti in sincronia in tutto il cluster e vengono utilizzati dal PEngine per elaborare lo stato ideale del cluster e come questo debba essere raggiunto." #. Tag: para #, fuzzy, no-c-format msgid "This list of instructions is then fed to the DC (Designated Controller). Pacemaker centralizes all cluster decision making by electing one of the CRMd instances to act as a master. Should the elected CRMd process (or the node it is on) fail… a new one is quickly established." msgstr "Questa lista di istruzioni viene inviata al DC (Designated Co-ordinator). Pacemaker centralizza tutte le decisioni in merito al cluster eleggendo una delle istanze di CRMd ad agire come master. Qualora il processo eletto CRMd o il nodo su cui questo è in esecuzione dovessero fallire, un nuovo DC viene rapidamente stabilito." #. Tag: para #, fuzzy, no-c-format msgid "The DC carries out PEngine’s instructions in the required order by passing them to either the LRMd (Local Resource Management daemon) or CRMd peers on other nodes via the cluster messaging infrastructure (which in turn passes them on to their LRMd process)." msgstr "Il DC esegue le istruzioni inviategli dal PEngine nell'ordine richiesto passandole o al LRMd (Local Resource Management daemon) o ai CRMd in ascolto sugli altri nodi attraverso l'infrastruttura di messaging del cluster (che a loro volta passeranno le istruzioni ai proprio LRMd)." #. Tag: para #, fuzzy, no-c-format msgid "The peer nodes all report the results of their operations back to the DC and, based on the expected and actual results, will either execute any actions that needed to wait for the previous one to complete, or abort processing and ask the PEngine to recalculate the ideal cluster state based on the unexpected results." msgstr "Gli altri nodi riferiscono i risultati delle loro operazioni al DC. Attraverso l'analisi dei risultati aspettati e di quelli attuali, i nodi eseguiranno qualsiasi azione necessaria per attendere il completamento della precedente oppure interromperanno il processo, richiedendo al PEngine di calcolare nuovamente lo stato ideale del cluster basandosi sui risulati inaspettati." #. Tag: para #, no-c-format msgid "In some cases, it may be necessary to power off nodes in order to protect shared data or complete resource recovery. For this Pacemaker comes with STONITHd." msgstr "" #. Tag: para #, no-c-format msgid "STONITH is an acronym for Shoot-The-Other-Node-In-The-Head and is usually implemented with a remote power switch." msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "In Pacemaker, STONITH devices are modeled as resources (and configured in the CIB) to enable them to be easily monitored for failure, however STONITHd takes care of understanding the STONITH topology such that its clients simply request a node be fenced and it does the rest." msgstr "In alcuni casi, potrebbe essere necessario spegnere i nodi per preservare dati condifivi o completare il ripristino di una risorsa. Per questo in Pacemaker esiste STONITHd. STONITH è un acronimo per Shoot-The-Other-Node-In-The-Head e viene implementato tipicamente con un switch di potenza remoto. In Pacemaker i dispositivi STONITH sono modellati come risorse (e configurati all'interno del CIB) per facilitare il monitoraggio delle anomalie. STONITHd si prende cura di capire la topologia STONITH così che i suoi client debbano unicamente richiedere unicamente la morte di un nodo ed esso si preoccupi del resto." #~ msgid "Unified, scriptable, cluster shell" #~ msgstr "cluster shell unificata e scriptabile" #, fuzzy #~ msgid "When combined with Corosync, Pacemaker also supports popular open source cluster filesystems Even though Pacemaker also supports Heartbeat, the filesystems need to use the stack for messaging and membership and Corosync seems to be what they're standardizing on. Technically it would be possible for them to support Heartbeat as well, however there seems little interest in this. Due to recent standardization within the cluster filesystem community, they make use of a common distributed lock manager which makes use of Corosync for its messaging capabilities and Pacemaker for its membership (which nodes are up/down) and fencing services." #~ msgstr "Quando viene combianato con Corosync, Pacemaker supporta anche i popolari cluster filesystem opensource Sebbene Pacemaker supporti anche Heartbeat, i filesystem necessitano di usare uno stack di messaging e membership e Corosync sembra essere quello su cui questi si stanno standardizzando. Tecnicamente potrebbe essere possibile per questi supportare anche Heartbeat, ma sembra esserci poco interesse in merito alla questione. . Le recenti standardizzazioni all'interno della comunità del cluster filesystem hanno portato all'uso di un lock manager distribuito che utilizza Corsync per il supporto al messaging e Pacemaker per il membership (quali nodi sono vivi o morti) ed il fencing dei servizi." #~ msgid "The Pacemaker Stack" #~ msgstr "Lo stack Pacemaker" pacemaker-master/doc/Pacemaker_Explained/it-IT/Ch-Nodes.po000066400000000000000000000437651217637305600236440ustar00rootroot00000000000000# # AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: 0\n" "POT-Creation-Date: 2012-10-17T05:19:02\n" "PO-Revision-Date: 2011-04-26 14:39+0100\n" "Last-Translator: RaSca \n" "Language-Team: None\n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. Tag: title #, no-c-format msgid "Cluster Nodes" msgstr "Nodi del cluster" #. Tag: title #, no-c-format msgid "Defining a Cluster Node" msgstr "Definire un nodo del cluster" #. Tag: para #, fuzzy, no-c-format msgid "Each node in the cluster will have an entry in the nodes section containing its UUID, uname, and type." msgstr "Ad ogni nodo nel cluster corrisponderà una entry nella sezione nodi contenente il relativo UUID, il valore di uname ed il tipo." #. Tag: title #, no-c-format msgid "Example cluster node entry" msgstr "Esempio di una entry relativa ad un nodo cluster" #. Tag: programlisting #, fuzzy, no-c-format msgid "<node id=\"1186dc9a-324d-425a-966e-d757e693dc86\" uname=\"pcmk-1\" type=\"normal\"/>" msgstr "" "\n" " <node id="1186dc9a-324d-425a-966e-d757e693dc86" uname="pcmk-1" type="normal"/>\n" "\t" #. Tag: para #, fuzzy, no-c-format msgid "In normal circumstances, the admin should let the cluster populate this information automatically from the communications and membership data. However one can use the crm_uuid tool to read an existing UUID or define a value before the cluster starts." msgstr "In circostanze normali, l'amministratore dovrebbe lasciar popolare le informazioni automaticamente al cluster in base ai dati di communication e membership. Ad ogni modo è possibile utilizzare lo strumento crm_uuid per leggere un UUID esistente o definire un valore prima che il cluster si avii." #. Tag: title #, no-c-format msgid "Describing a Cluster Node" msgstr "Descrivere un nodo del cluster" #. Tag: para #, fuzzy, no-c-format msgid " Nodeattribute attribute Beyond the basic definition of a node the administrator can also describe the node’s attributes, such as how much RAM, disk, what OS or kernel version it has, perhaps even its physical location. This information can then be used by the cluster when deciding where to place resources. For more information on the use of node attributes, see ." msgstr "Al di la della definizione base di un nodo, l'amministratore può inoltre descriverne gli attributi, come ad esempio quanta RAM, disco, quale sistema operativo o versione di kernel monta, forse anche la locazione fisica. Queste informazioni possono quindi essere utilizzate dal cluster nel momento in cui viene deciso dove porre le risorse. Per ulteriori informazioni sull'uso degli attributi del nodo, vedere la sezione ." #. Tag: para #, fuzzy, no-c-format msgid "Node attributes can be specified ahead of time or populated later, when the cluster is running, using crm_attribute." msgstr "Gli attributi dei nodi possono essere specificati a priori o popolate in seguito, quando il cluster sta funzionando, utilizzando crm_attribute." #. Tag: para #, fuzzy, no-c-format msgid "Below is what the node’s definition would look like if the admin ran the command:" msgstr "Ecco riportato come sarà la definzione del nodo se l'amministratore lancia il comando:" #. Tag: title #, no-c-format msgid "The result of using crm_attribute to specify which kernel pcmk-1 is running" msgstr "Risultato dell'utilizzo di crm_attribute per specificare quale kernel sta funzionando su pcmk-1" #. Tag: programlisting #, fuzzy, no-c-format msgid "# crm_attribute --type nodes --node-uname pcmk-1 --attr-name kernel --attr-value `uname -r`" msgstr " crm_attribute --type nodes --node-uname pcmk-1 --attr-name kernel --get-value" #. Tag: programlisting #, fuzzy, no-c-format msgid "" "<node uname=\"pcmk-1\" type=\"normal\" id=\"1186dc9a-324d-425a-966e-d757e693dc86\">\n" " <instance_attributes id=\"nodes-1186dc9a-324d-425a-966e-d757e693dc86\">\n" " <nvpair id=\"kernel-1186dc9a-324d-425a-966e-d757e693dc86\" name=\"kernel\" value=\"2.6.16.46-0.4-default\"/>\n" " </instance_attributes>\n" "</node>" msgstr "" "\n" " crm_attribute --type nodes --node-uname pcmk-1 --attr-name kernel --attr-value `uname -r` \n" "\n" " <node uname="pcmk-1" type="normal" id="1186dc9a-324d-425a-966e-d757e693dc86">\n" " <instance_attributes id="nodes-1186dc9a-324d-425a-966e-d757e693dc86">\n" " <nvpair id="kernel-1186dc9a-324d-425a-966e-d757e693dc86" name="kernel" value="2.6.16.46-0.4-default"/>\n" " </instance_attributes>\n" " </node>\n" "\n" "\t" #. Tag: para #, fuzzy, no-c-format msgid "A simpler way to determine the current value of an attribute is to use crm_attribute command again:" msgstr "Una via più semplice per determinare il valore corrente di un attributo è di utilizzare nuovamente il comando crm_attribute:" #. Tag: programlisting #, fuzzy, no-c-format msgid "# crm_attribute --type nodes --node-uname pcmk-1 --attr-name kernel --get-value" msgstr " crm_attribute --type nodes --node-uname pcmk-1 --attr-name kernel --get-value" #. Tag: para #, fuzzy, no-c-format msgid "By specifying --type nodes the admin tells the cluster that this attribute is persistent. There are also transient attributes which are kept in the status section which are \"forgotten\" whenever the node rejoins the cluster. The cluster uses this area to store a record of how many times a resource has failed on that node but administrators can also read and write to this section by specifying --type status." msgstr "Specificando --type nodes, l'amministratore comunica al cluster che l'attributo è persistente. Esistono inoltre attributi transitori presenti nella sezione status che sono "dimenticati" ogni volta che il nodo diventa parte nuovamente del cluster. Il cluster utilizza quest'area per registrare il valore relativo a quante volte una risorsa è fallita su quel nodo, ma gli amministratoripossono inoltre leggere e scrivere in questa sezione specificando --type status." #. Tag: title #, no-c-format msgid "Adding a New Cluster Node" msgstr "Aggiungere un nuovo nodo al cluster" #. Tag: title #, no-c-format msgid "Corosync" msgstr "Corosync" #. Tag: para #, no-c-format msgid " CorosyncAdd Cluster Node Add Cluster Node Add Cluster NodeCorosync Corosync Adding a new node is as simple as installing Corosync and Pacemaker, and copying /etc/corosync/corosync.conf and /etc/corosync/authkey (if it exists) from an existing node. You may need to modify the mcastaddr option to match the new node’s IP address." msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "If a log message containing \"Invalid digest\" appears from Corosync, the keys are not consistent between the machines." msgstr "Se appare tra i log di Corosync un messaggio contenente "Invalid digest", le chiavi tra le due macchine non sono consistenti." #. Tag: title #, no-c-format msgid "Heartbeat" msgstr "Heartbeat" #. Tag: para #, no-c-format msgid " HeartbeatAdd Cluster Node Add Cluster Node Add Cluster NodeHeartbeat Heartbeat Provided you specified autojoin any in ha.cf, adding a new node is as simple as installing heartbeat and copying ha.cf and authkeys from an existing node." msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "If you don’t want to use autojoin, then after setting up ha.cf and authkeys, you must use the hb_addnode command before starting the new node." msgstr "Se l'opzione autojoin non è stata specificata, allora dopo aver modificato ha.cf e authkeys, sarà necessario utilizzare il comando bh_addnode prima di avviare il nuovo nodo." #. Tag: title #, no-c-format msgid "Removing a Cluster Node" msgstr "Rimuovere un nodo" #. Tag: para #, fuzzy, no-c-format msgid " CorosyncRemove Cluster Node Remove Cluster Node Remove Cluster NodeCorosync Corosync Because the messaging and membership layers are the authoritative source for cluster nodes, deleting them from the CIB is not a reliable solution. First one must arrange for heartbeat to forget about the node (pcmk-1 in the example below)." msgstr "Poiché il livello di messaging e membership sono sorgenti autoritative per i nodi del cluster, la loro cancellazione dal CIB non è una via percorribile. Prima quindi è necessario fare in modo che heartbeat dimentichi il nodo in questione (pcmk-1 nell'esempio sottostante)." #. Tag: para #, no-c-format msgid "On the host to be removed:" msgstr "Sull'host da rimuovere:" #. Tag: para #, fuzzy, no-c-format msgid "Find and record the node’s Corosync id: crm_node -i" msgstr "Trova e registra l'id Corosync del nodo: crm_node -i" #. Tag: para #, fuzzy, no-c-format msgid "Stop the cluster: /etc/init.d/corosync stop" msgstr "Stop del cluster: /etc/init.d/corosync stop" #. Tag: para #, no-c-format msgid "Next, from one of the remaining active cluster nodes:" msgstr "Quindi, da uno dei nodi rimasti attivi:" #. Tag: para #, no-c-format msgid "Tell the cluster to forget about the removed host:" msgstr "" #. Tag: programlisting #, no-c-format msgid "# crm_node -R $COROSYNC_ID" msgstr "" #. Tag: para #, no-c-format msgid "Only now is it safe to delete the node from the CIB with:" msgstr "Solamente ora è sicuro rimuovere il nodo dal CIB mediante:" #. Tag: programlisting #, no-c-format msgid "" "# cibadmin --delete --obj_type nodes --crm_xml '<node uname=\"_pcmk-1_\"/>'\n" "# cibadmin --delete --obj_type status --crm_xml '<node_state uname=\"_pcmk-1_\"/>'" msgstr "" #. Tag: para #, no-c-format msgid " HeartbeatRemove Cluster Node Remove Cluster Node Remove Cluster NodeHeartbeat Heartbeat Because the messaging and membership layers are the authoritative source for cluster nodes, deleting them from the CIB is not a reliable solution." msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "First one must arrange for heartbeat to forget about the node (pcmk-1 in the example below). To do this, shut down heartbeat on the node and then, from one of the remaining active cluster nodes, run:" msgstr "Poiché i livelli di messaging e membership sono le sorgenti autoritative per i nodi del cluster, cancellarli dal CIB non è una soluzione percorribile. Prima quindi è necessario fare in modo che heartbeat dimentichi il nodo (pcmk-1 in the example below). Per fare questo, è sufficiente fermare heartbeat sul nodo interessato e successivamente, sul nodo rimasto attivo nel cluster, lanciare:" #. Tag: programlisting #, fuzzy, no-c-format msgid "# hb_delnode pcmk-1" msgstr "hb_delnode pcmk-1" #. Tag: para #, no-c-format msgid "Only then is it safe to delete the node from the CIB with:" msgstr "Solo a questo punto è sicuro rimuovere il nodo dal CIB con:" #. Tag: programlisting #, no-c-format msgid "" "# cibadmin --delete --obj_type nodes --crm_xml '<node uname=\"pcmk-1\"/>'\n" "# cibadmin --delete --obj_type status --crm_xml '<node_state uname=\"pcmk-1\"/>'" msgstr "" #. Tag: title #, no-c-format msgid "Replacing a Cluster Node" msgstr "Rimpiazzare un nodo del cluster" #. Tag: para #, no-c-format msgid " CorosyncReplace Cluster Node Replace Cluster Node Replace Cluster NodeCorosync Corosync The five-step guide to replacing an existing cluster node:" msgstr "" #. Tag: para #, no-c-format msgid "Make sure the old node is completely stopped" msgstr "Assicurarsi che il vecchio nodo sia completamente stoppato" #. Tag: para #, no-c-format msgid "Give the new machine the same hostname and IP address as the old one" msgstr "Assegnare alla nuova macchina lo stesso hostname ed indirizzo IP della vecchia macchina" #. Tag: para #, no-c-format msgid "Install the cluster software :-)" msgstr "Installare il software del cluster :-)" #. Tag: para #, fuzzy, no-c-format msgid "Copy /etc/corosync/corosync.conf and /etc/corosync/authkey (if it exists) to the new node" msgstr "Copiare /etc/corosync/corosync.conf e /etc/corosync/authkey (se esiste) nel nuovo nodo" #. Tag: para #, no-c-format msgid "Start the new cluster node" msgstr "Avviare il nuovo nodo del cluster" #. Tag: para #, no-c-format msgid " HeartbeatReplace Cluster Node Replace Cluster Node Replace Cluster NodeHeartbeat Heartbeat The seven-step guide to replacing an existing cluster node:" msgstr "" #. Tag: para #, no-c-format msgid "Give the new machine the same hostname as the old one" msgstr "Dare alla nuova macchina lo stesso hostname della vecchia" #. Tag: para #, fuzzy, no-c-format msgid "Go to an active cluster node and look up the UUID for the old node in /var/lib/heartbeat/hostcache" msgstr "Su un nodo attivo del cluster localizzale l'UUID del vecchio nodo in /var/lib/heartbeat/hostcache" #. Tag: para #, no-c-format msgid "Install the cluster software" msgstr "Installare il software del cluster" #. Tag: para #, fuzzy, no-c-format msgid "Copy ha.cf and authkeys to the new node" msgstr "Copiare ha.cf ed authkeys nel nuovo nodo" #. Tag: para #, fuzzy, no-c-format msgid "On the new node, populate it’s UUID using crm_uuid -w and the UUID from step 2" msgstr "Sul vecchio nodo, popolare il file con il valore UUID utilizzando crm_uuid -w ed il valore UUID ricavato nel passo 2" #~ msgid "Adding a new is as simple as installing Corosync and Pacemaker, and copying /etc/corosync/corosync.conf and /etc/corosync/authkey (if it exists) from an existing node. You may need to modify the mcastaddr option to match the new node's IP address." #~ msgstr "Aggiungere un nuovo nodo è fattibile installando Corosync e Pacemaker, e copiando /etc/corosync/corosync.conf e /etc/corosync/authkey (se esiste) da un nodo esistente. Potrebbe essere necessario modificare l'opzione mcastaddr in modo che corrisponda all'indirizzo IP del nuovo nodo." #~ msgid "Provided you specified autojoin any in ha.cf, adding a new is as simple as installing heartbeat and copying ha.cf and authkeys from an existing node." #~ msgstr "A condizione che si sia specificato autojon any all'interno del file ha.cf, aggiungere un nuovo nodo è possibile semplicemente installando heartbeat e copiando i file ha.cf e authkeys da un nodo esistente." #~ msgid "Tell the cluster to forget about the removed host: crm_node -R COROSYNC_ID" #~ msgstr "Comunica al cluster di dimenticare gli host rimossi: crm_node -R COROSYNC_ID" #~ msgid "cibadmin --delete --obj_type nodes --crm_xml '<node uname="pcmk-1"/>'" #~ msgstr "cibadmin --delete --obj_type nodes --crm_xml '<node uname="pcmk-1"/>'" #~ msgid "cibadmin --delete --obj_type status --crm_xml '<node_state uname="pcmk-1"/>'" #~ msgstr "cibadmin --delete --obj_type status --crm_xml '<node_state uname="pcmk-1"/>'" #~ msgid "cibadmin --delete --obj_type nodes --crm_xml '<node uname="pcmk-1"/>'" #~ msgstr "cibadmin --delete --obj_type nodes --crm_xml '<node uname="pcmk-1"/>'" #~ msgid "cibadmin --delete --obj_type status --crm_xml '<node_state uname="pcmk-1"/>'" #~ msgstr "cibadmin --delete --obj_type status --crm_xml '<node_state uname="pcmk-1"/>'" #~ msgid "The five-step guide to replacing an existing cluster node:" #~ msgstr "Guida in cinque passi per rimpiazzare un nodo esistente del cluster:" #~ msgid "The seven-step guide to replacing an existing cluster node:" #~ msgstr "Guida in sette passi per rimpiazzare un nodo del cluster esistente:" pacemaker-master/doc/Pacemaker_Explained/it-IT/Ch-Options.po000066400000000000000000001007021217637305600242100ustar00rootroot00000000000000# # AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: 0\n" "POT-Creation-Date: 2012-10-17T05:19:02\n" "PO-Revision-Date: 2011-04-23 23:07+0100\n" "Last-Translator: RaSca \n" "Language-Team: None\n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. Tag: title #, no-c-format msgid "Cluster Options" msgstr "Opzioni del cluster" #. Tag: title #, no-c-format msgid "Special Options" msgstr "Opzioni speciali" #. Tag: para #, no-c-format msgid "The reason for these fields to be placed at the top level instead of with the rest of cluster options is simply a matter of parsing. These options are used by the configuration database which is, by design, mostly ignorant of the content it holds. So the decision was made to place them in an easy to find location." msgstr "La ragione per cui questi campi vengono posti in cima anziché con il resto delle opzioni del cluster è meramente una questione di parsing. Queste opzioni sono utilizzate dal database di configurazione che è, per natura, piuttosto ignorante dei contenuti che detetiene. Quindi la decisione è stata presa in modo da porli in una locazione facile da individuare." #. Tag: title #, no-c-format msgid "Configuration Version" msgstr "Versione della configurazione" #. Tag: para #, no-c-format msgid " Configuration VersionCluster Cluster ClusterOptionConfiguration Version OptionConfiguration Version Configuration Version " msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "When a node joins the cluster, the cluster will perform a check to see who has the best configuration based on the fields below. It then asks the node with the highest (admin_epoch, epoch, num_updates) tuple to replace the configuration on all the nodes - which makes setting them, and setting them correctly, very important." msgstr "Quando un nodo aderisce al cluster, questo effettuerà un controllo per vedere chi ha la migliore configurazione in base ai campi riportati sotto. Esso domanda poi al nodo con la più alta (admin_epoch, epoch, num_updates) tupla di rimpiazzare la configurazione su tutti i nodi - il che implica una notevole importanza ai valori, i quali dovranno essere impostati correttamente." #. Tag: title #, no-c-format msgid "Configuration Version Properties" msgstr "Proprietà relative alla versione della configurazione" #. Tag: entry #, no-c-format msgid "Field" msgstr "Campo" #. Tag: entry #, no-c-format msgid "Description" msgstr "Descrizione" #. Tag: para #, no-c-format msgid "admin_epoch" msgstr "" #. Tag: para #, no-c-format msgid " admin_epochCluster Option Cluster Option ClusterOptionadmin_epoch Optionadmin_epoch admin_epoch Never modified by the cluster. Use this to make the configurations on any inactive nodes obsolete." msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "Never set this value to zero, in such cases the cluster cannot tell the difference between your configuration and the \"empty\" one used when nothing is found on disk." msgstr "Non settare mai questo valore a zero, in questi casi il cluster non potrà determinare la differenza tra la configurazione attiva e quella "vuota" utilizzata quando non viene trovato nulla sul disco." #. Tag: para #, no-c-format msgid "epoch" msgstr "" #. Tag: para #, no-c-format msgid " epochCluster Option Cluster Option ClusterOptionepoch Optionepoch epoch Incremented every time the configuration is updated (usually by the admin)" msgstr "" #. Tag: para #, no-c-format msgid "num_updates" msgstr "" #. Tag: para #, no-c-format msgid " num_updatesCluster Option Cluster Option ClusterOptionnum_updates Optionnum_updates num_updates Incremented every time the configuration or status is updated (usually by the cluster)" msgstr "" #. Tag: title #, no-c-format msgid "Other Fields" msgstr "Altri campi" #. Tag: title #, fuzzy, no-c-format msgid "Properties Controlling Validation" msgstr "Proprietà del controllo di validazione" #. Tag: para #, no-c-format msgid "validate-with" msgstr "" #. Tag: para #, no-c-format msgid " validate-withCluster Option Cluster Option ClusterOptionvalidate-with Optionvalidate-with validate-with Determines the type of validation being done on the configuration. If set to \"none\", the cluster will not verify that updates conform to the DTD (nor reject ones that don’t). This option can be useful when operating a mixed version cluster during an upgrade." msgstr "" #. Tag: title #, no-c-format msgid "Fields Maintained by the Cluster" msgstr "Campi gestiti dal cluster" #. Tag: title #, no-c-format msgid "Properties Maintained by the Cluster" msgstr "Proprietà gestite dal cluster" #. Tag: para #, fuzzy, no-c-format msgid "cib-last-written" msgstr "cib-last-written" #. Tag: para #, no-c-format msgid " cib-last-writtenCluster Property Cluster Property ClusterPropertycib-last-written Propertycib-last-written cib-last-written Indicates when the configuration was last written to disk. Informational purposes only." msgstr "" #. Tag: para #, no-c-format msgid "dc-uuid" msgstr "" #. Tag: para #, no-c-format msgid " dc-uuidCluster Property Cluster Property ClusterPropertydc-uuid Propertydc-uuid dc-uuid Indicates which cluster node is the current leader. Used by the cluster when placing resources and determining the order of some events." msgstr "" #. Tag: para #, no-c-format msgid "have-quorum" msgstr "" #. Tag: para #, no-c-format msgid " have-quorumCluster Property Cluster Property ClusterPropertyhave-quorum Propertyhave-quorum have-quorum Indicates if the cluster has quorum. If false, this may mean that the cluster cannot start resources or fence other nodes. See no-quorum-policy below." msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "Note that although these fields can be written to by the admin, in most cases the cluster will overwrite any values specified by the admin with the \"correct\" ones. To change the admin_epoch, for example, one would use:" msgstr "Da notare come sebbene questi campi possono essere impostati dall'admin, in molti casi il cluster li riscriverà qualsiasi valore specificato da admin con quelli "corretti"" #. Tag: programlisting #, fuzzy, no-c-format msgid "# cibadmin --modify --crm_xml '<cib admin_epoch=\"42\"/>'" msgstr "cibadmin --modify --crm_xml ‘<cib admin_epoch="42"/>'" #. Tag: para #, no-c-format msgid "A complete set of fields will look something like this:" msgstr "Un set completo di campi assomiglierà a questo:" #. Tag: title #, no-c-format msgid "An example of the fields set for a cib object" msgstr "Un esempio dei campi settati per un oggetto cib" #. Tag: programlisting #, fuzzy, no-c-format msgid "" "<cib have-quorum=\"true\" validate-with=\"pacemaker-1.0\"\n" " admin_epoch=\"1\" epoch=\"12\" num_updates=\"65\"\n" " dc-uuid=\"ea7d39f4-3b94-4cfa-ba7a-952956daabee\">" msgstr "" "\n" "\n" " <cib have-quorum="true" validate-with="pacemaker-1.0" admin_epoch="1" epoch="12" num_updates="65"\n" " dc-uuid="ea7d39f4-3b94-4cfa-ba7a-952956daabee">\n" "\n" "\t " #. Tag: para #, fuzzy, no-c-format msgid "Cluster options, as you might expect, control how the cluster behaves when confronted with certain situations." msgstr "Le opzioni del cluster, come presumibile, controllano come il cluster si comporta di fronte a determinate situazioni." #. Tag: para #, fuzzy, no-c-format msgid "They are grouped into sets and, in advanced configurations, there may be more than one. This will be described later in the section on where we will show how to have the cluster use different sets of options during working hours (when downtime is usually to be avoided at all costs) than it does during the weekends (when resources can be moved to the their preferred hosts without bothering end users) For now we will describe the simple case where each option is present at most once." msgstr "Esse sono raggruppate in set e, in configurazioni avanzate, ne possono esistere più di uno. Questo verrà descritto più avanti nel dove verrà mostrato come sia possibile fare in modo che il cluster utilizzi diversi set di opzioni durante gli orari lavorativi (dove qualsiasi downtime va evitato ad ogni costo) e durate i weekend (quando le risorse possono essere spostate ai loro host preferiti senza annoiare gli utilizzatori finali) Per ora verrà descritto il semplice caso in cui ogni opzione è presente al massimo una volta." #. Tag: title #, no-c-format msgid "Available Cluster Options" msgstr "Opzioni disponibili nel cluster" #. Tag: entry #, no-c-format msgid "Option" msgstr "Opzione" #. Tag: entry #, no-c-format msgid "Default" msgstr "Default" #. Tag: para #, no-c-format msgid "batch-limit" msgstr "" #. Tag: para #, no-c-format msgid "30" msgstr "30" #. Tag: para #, no-c-format msgid " batch-limitCluster Option Cluster Option ClusterOptionbatch-limit Optionbatch-limit batch-limit The number of jobs that the TE is allowed to execute in parallel. The \"correct\" value will depend on the speed and load of your network and cluster nodes." msgstr "" #. Tag: para #, no-c-format msgid "migration-limit" msgstr "" #. Tag: para #, no-c-format msgid "-1 (unlimited)" msgstr "" #. Tag: para #, no-c-format msgid " migration-limitCluster Option Cluster Option ClusterOptionmigration-limit Optionmigration-limit migration-limit The number of migration jobs that the TE is allowed to execute in parallel on a node." msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "no-quorum-policy" msgstr "no-quorum-policy" #. Tag: para #, no-c-format msgid "stop" msgstr "stop" #. Tag: para #, no-c-format msgid " no-quorum-policyCluster Option Cluster Option ClusterOptionno-quorum-policy Optionno-quorum-policy no-quorum-policy What to do when the cluster does not have quorum. Allowed values:" msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "* ignore - continue all resource management" msgstr "ignore - continua a gestire tutte le risorse" #. Tag: para #, fuzzy, no-c-format msgid "* freeze - continue resource management, but don’t recover resources from nodes not in the affected partition" msgstr "freeze - continua a gestire le risorse, ma non ripara risorse da nodi non presenti nella partizione interessata" #. Tag: para #, fuzzy, no-c-format msgid "* stop - stop all resources in the affected cluster partition" msgstr "stop - ferma tutte le risorse nella partizione del cluster interessata" #. Tag: para #, fuzzy, no-c-format msgid "* suicide - fence all nodes in the affected cluster partition" msgstr "suicide - effettua il fence di tutti i nodi nella partizione del cluster interessata" #. Tag: para #, fuzzy, no-c-format msgid "symmetric-cluster" msgstr "symmetric-cluster" #. Tag: para #, no-c-format msgid "TRUE" msgstr "TRUE" #. Tag: para #, no-c-format msgid " symmetric-clusterCluster Option Cluster Option ClusterOptionsymmetric-cluster Optionsymmetric-cluster symmetric-cluster Can all resources run on any node by default?" msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "stonith-enabled" msgstr "stonith-enabled" #. Tag: para #, no-c-format msgid " stonith-enabledCluster Option Cluster Option ClusterOptionstonith-enabled Optionstonith-enabled stonith-enabled Should failed nodes and nodes with resources that can’t be stopped be shot? If you value your data, set up a STONITH device and enable this." msgstr "" #. Tag: para #, no-c-format msgid "If true, or unset, the cluster will refuse to start resources unless one or more STONITH resources have been configured also." msgstr "Se \"true\" o non valorizzata, il cluster rifiuterà di avviare risorse a meno che uno o più dispositivi STONITH siano stati configurati." #. Tag: para #, no-c-format msgid "stonith-action" msgstr "" #. Tag: para #, no-c-format msgid "reboot" msgstr "reboot" #. Tag: para #, no-c-format msgid " stonith-actionCluster Option Cluster Option ClusterOptionstonith-action Optionstonith-action stonith-action Action to send to STONITH device. Allowed values: reboot, off. The value poweroff is also allowed, but is only used for legacy devices." msgstr "" #. Tag: para #, no-c-format msgid "cluster-delay" msgstr "" #. Tag: para #, no-c-format msgid "60s" msgstr "60s" #. Tag: para #, no-c-format msgid " cluster-delayCluster Option Cluster Option ClusterOptioncluster-delay Optioncluster-delay cluster-delay Round trip delay over the network (excluding action execution). The \"correct\" value will depend on the speed and load of your network and cluster nodes." msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "stop-orphan-resources" msgstr "stop-orphan-resources" #. Tag: para #, no-c-format msgid " stop-orphan-resourcesCluster Option Cluster Option ClusterOptionstop-orphan-resources Optionstop-orphan-resources stop-orphan-resources Should deleted resources be stopped?" msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "stop-orphan-actions" msgstr "stop-orphan-actions" #. Tag: para #, no-c-format msgid " stop-orphan-actionsCluster Option Cluster Option ClusterOptionstop-orphan-actions Optionstop-orphan-actions stop-orphan-actions Should deleted actions be cancelled?" msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "start-failure-is-fatal" msgstr "start-failure-is-fatal" #. Tag: para #, no-c-format msgid " start-failure-is-fatalCluster Option Cluster Option ClusterOptionstart-failure-is-fatal Optionstart-failure-is-fatal start-failure-is-fatal When set to FALSE, the cluster will instead use the resource’s failcount and value for resource-failure-stickiness." msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "pe-error-series-max" msgstr "pe-error-series-max" #. Tag: para #, no-c-format msgid "-1 (all)" msgstr "-1 (tutti)" #. Tag: para #, no-c-format msgid " pe-error-series-maxCluster Option Cluster Option ClusterOptionpe-error-series-max Optionpe-error-series-max pe-error-series-max The number of PE inputs resulting in ERRORs to save. Used when reporting problems." msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "pe-warn-series-max" msgstr "pe-warn-series-max" #. Tag: para #, no-c-format msgid " pe-warn-series-maxCluster Option Cluster Option ClusterOptionpe-warn-series-max Optionpe-warn-series-max pe-warn-series-max The number of PE inputs resulting in WARNINGs to save. Used when reporting problems." msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "pe-input-series-max" msgstr "pe-input-series-max" #. Tag: para #, no-c-format msgid " pe-input-series-maxCluster Option Cluster Option ClusterOptionpe-input-series-max Optionpe-input-series-max pe-input-series-max The number of \"normal\" PE inputs to save. Used when reporting problems." msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "You can always obtain an up-to-date list of cluster options, including their default values, by running the pengine metadata command." msgstr "E' sempre possibile ottenere una lista aggiornata delle opzioni del cluster, inclusi i loro valori di default lanciando il comando pengine metadata." #. Tag: title #, no-c-format msgid "Querying and Setting Cluster Options" msgstr "Interrogare e valorizzare le opzioni del cluster" #. Tag: para #, no-c-format msgid " QueryingCluster Option Cluster Option SettingCluster Option Cluster Option ClusterQuerying Options Querying Options ClusterSetting Options Setting Options " msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "Cluster options can be queried and modified using the crm_attribute tool. To get the current value of cluster-delay, simply use:" msgstr "Le opzioni del cluster possono essere interrogate e modificate mediante l'utilizzo dello strumento crm_attribute. Per ottenere il valore del parametro cluster-delay è sufficiente utilizzare:" #. Tag: programlisting #, fuzzy, no-c-format msgid "# crm_attribute --attr-name cluster-delay --get-value" msgstr "crm_attribute --attr-name cluster-delay --get-value" #. Tag: para #, no-c-format msgid "which is more simply written as" msgstr "più semplicemente scrivibile come" #. Tag: programlisting #, fuzzy, no-c-format msgid "# crm_attribute --get-value -n cluster-delay" msgstr "crm_attribute --get-value -n cluster-delay" #. Tag: para #, fuzzy, no-c-format msgid "If a value is found, you’ll see a result like this:" msgstr "Se viene trovato un valore, allora sarà possibile vederlo come segue" #. Tag: programlisting #, fuzzy, no-c-format msgid "" "# crm_attribute --get-value -n cluster-delay\n" " name=cluster-delay value=60s" msgstr "" "\n" " # crm_attribute --get-value -n cluster-delay\n" " name=cluster-delay value=60s" #. Tag: para #, fuzzy, no-c-format msgid "However, if no value is found, the tool will display an error:" msgstr "Ad ogni modo se nessun valore viene trovato lo strumento restituirà un errore:" #. Tag: programlisting #, fuzzy, no-c-format msgid "" "# crm_attribute --get-value -n clusta-deway`\n" "name=clusta-deway value=(null)\n" "Error performing operation: The object/attribute does not exist" msgstr "" "\n" " # crm_attribute --get-value -n clusta-deway\n" " name=clusta-deway value=(null)\n" " Error performing operation: The object/attribute does not exist" #. Tag: para #, fuzzy, no-c-format msgid "To use a different value, eg. 30, simply run:" msgstr "Per utilizzare un valore differente, ad esempio 30s, è sufficiente lanciare:" #. Tag: programlisting #, fuzzy, no-c-format msgid "# crm_attribute --attr-name cluster-delay --attr-value 30s" msgstr "crm_attribute --attr-name cluster-delay --attr-value 30s" #. Tag: para #, fuzzy, no-c-format msgid "To go back to the cluster’s default value you can delete the value, for example with this command:" msgstr "Per ripristinare il valore di default è possibile cancellare il valore con:" #. Tag: programlisting #, fuzzy, no-c-format msgid "# crm_attribute --attr-name cluster-delay --delete-attr" msgstr "crm_attribute --attr-name cluster-delay --delete-attr" #. Tag: title #, no-c-format msgid "When Options are Listed More Than Once" msgstr "Quando le opzioni vengono elencate più di una volta" #. Tag: para #, fuzzy, no-c-format msgid "If you ever see something like the following, it means that the option you’re modifying is present more than once." msgstr "Se capiterà mai di vedere quanto illustrato, il motivo risiederà nel fatto che sono state dichiarate le stesse opzioni più di una volta." #. Tag: title #, no-c-format msgid "Deleting an option that is listed twice" msgstr "Cancellare un'opzione dichiarata due volte" #. Tag: programlisting #, fuzzy, no-c-format msgid "" "# crm_attribute --attr-name batch-limit --delete-attr\n" "\n" "Multiple attributes match name=batch-limit in crm_config:\n" "Value: 50 (set=cib-bootstrap-options, id=cib-bootstrap-options-batch-limit)\n" "Value: 100 (set=custom, id=custom-batch-limit)\n" "Please choose from one of the matches above and supply the 'id' with --attr-id" msgstr "" "\n" " # crm_attribute --attr-name batch-limit --delete-attr\n" " Multiple attributes match name=batch-limit in crm_config:\n" " Value: 50 (set=cib-bootstrap-options, id=cib-bootstrap-options-batch-limit)\n" " Value: 100 (set=custom, id=custom-batch-limit)\n" " Please choose from one of the matches above and supply the 'id' with --attr-id" #. Tag: para #, fuzzy, no-c-format msgid "In such cases follow the on-screen instructions to perform the requested action. To determine which value is currently being used by the cluster, please refer to ." msgstr "In questi casi seguendo le istruzioni a video sarà possibile eseguire l'azione richiesta. Per determinare quale valore è attualmente utilizzato dal cluster bisognerà fare riferimento al ." #~ msgid "admin_epoch" #~ msgstr "admin_epoch" #~ msgid "Never modified by the cluster. Use this to make the configurations on any inactive nodes obsolete." #~ msgstr "Non viene mai modificata dal cluster. Viene utilizzata per applicare le configurazioni su qualsiasi nodo inattivo obsoleto." #~ msgid "epoch" #~ msgstr "epoch" #~ msgid "Incremented every time the configuration is updated (usually by the admin)" #~ msgstr "Incrementata ogni volta che la configurazione viene aggiornata (generalmente dall'admin)" #~ msgid "num_updates" #~ msgstr "num_updates" #~ msgid "Incremented every time the configuration or status is updated (usually by the cluster)" #~ msgstr "Incrementata ogni volta che la configurazione o lo stato vengono aggiornati (generalmente dal cluster)" #~ msgid "validate-with" #~ msgstr "validate-with" #~ msgid "Determines the type of validation being done on the configuration. If set to "none", the cluster will not verify that updates conform the the DTD (nor reject ones that don't). This option can be useful when operating a mixed version cluster during an upgrade." #~ msgstr "Determina il tipo di validazione effettuata sulla configurazione. Se valorizzata a "none" il cluster non verificherà che gli aggiornamenti siano conformi al DTD (e non scarterà quelli che non lo sono). Questa opzione può essere utile quando si opera con versioni del cluster mixate, durante un aggiornamento." #~ msgid "crm-debug-origin" #~ msgstr "crm-debug-origin" #~ msgid "Indicates where the last update came from. Informational purposes only." #~ msgstr "Indica da dove è provenuto l'ultimo aggiornamento. Ha scopo puramente informativo." #~ msgid "Indicates when the configuration was last written to disk. Informational purposes only." #~ msgstr "Indica quando la configurazione è stata scritta su disco. Ha scopo puramente informativo." #~ msgid "dc-uuid" #~ msgstr "dc-uuid" #~ msgid "Indicates which cluster node is the current leader. Used by the cluster when placing resources and determining the order of some events." #~ msgstr "Indica quale nodo del cluster è l'attuale capo. Viene utilizzato dal cluster durante l'assegnamento delle risorse e determinato l'ordine di alcuni eventi." #~ msgid "have-quorum" #~ msgstr "have-quorum" #~ msgid "Indicates if the cluster has quorum. If false, this may mean that the cluster cannot start resources or fence other nodes. See no-quorum-policy below." #~ msgstr "Indica se il cluster ha quorumi. Se valorizzata a \"false\" potrebbe significare che il cluster non può avviare risorse od effettuare il fence di altri nodi. Vedere no-quorum-policy sotto." #~ msgid "batch-limit" #~ msgstr "batch-limit" #~ msgid "The number of jobs that the TE is allowed to execute in parallel. The "correct" value will depend on the speed and load of your network and cluster nodes." #~ msgstr "Il numero di job che il TE è abilitato ad eseguire in parallelo. Il valore "corretto" dipenderà dalla velocità e dal carico della rete e dei nodi del cluster." #~ msgid "What to do when the cluster does not have quorum. Allowed values:" #~ msgstr "Cosa fare quando il cluster non ha quorum. Valori permessi:" #~ msgid "Can all resources run on any node by default?" #~ msgstr "Possono di default tutte le risorse funzionare su qualsiasi nodo?" #~ msgid "Should failed nodes and nodes with resources that can't be stopped be shot? If you value your data, set up a STONITH device and enable this." #~ msgstr "I nodi falliti ed i nodi con risorse che non possono essere fermate possono essere colpiti? Se si ritengono i propri dati importanti, sarà necessario configurare un dispositivo STONITH ed abilitare questa opzione. " #~ msgid "stonith-action" #~ msgstr "stonith-action" #~ msgid "Action to send to STONITH device. Allowed values: reboot, poweroff." #~ msgstr "Azione da inviare al dispositivo STONITH. Valori permessi: reboot, poweroff." #~ msgid "cluster-delay" #~ msgstr "cluster-delay" #~ msgid "Round trip delay over the network (excluding action execution). The "correct" value will depend on the speed and load of your network and cluster nodes." #~ msgstr "Ritardo guidato sulla rete (con esclusione dell'esecuzione dell'azione). Il valore "corretto" dipenderà dalla velocità e dal carico della propria rete e dai nodi del cluster." #~ msgid "Should deleted resources be stopped" #~ msgstr "Le risorse cancellate devono essere fermate?" #~ msgid "Should deleted actions be cancelled" #~ msgstr "Le azioni cancellate devono essere annullate?" #~ msgid "When set to FALSE, the cluster will instead use the resource's failcount and value for resource-failure-stickiness" #~ msgstr "Quando settata a FALSE il cluster utilizzerà invece il valore di failcount delle risorse ed il valore di resource-failure-stickiness" #~ msgid "The number of PE inputs resulting in ERRORs to save. Used when reporting problems." #~ msgstr "Il numero da salvare di input PE che risultano in stato ERROR. Utilizzato in fase di comunicazione di problemi." #~ msgid "The number of PE inputs resulting in WARNINGs to save. Used when reporting problems." #~ msgstr "Il numero da salvare di input PE che risultano in stato WARNING. Utilizzato in fase di comunicazione di problemi." #~ msgid "The number of "normal" PE inputs to save. Used when reporting problems." #~ msgstr "Il numero da salvare di input PE in stato "normal". Utilizzato in fase di comunicazione di problemi." pacemaker-master/doc/Pacemaker_Explained/it-IT/Ch-Resources.po000066400000000000000000002063021217637305600245320ustar00rootroot00000000000000# # AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: 0\n" "POT-Creation-Date: 2012-10-17T05:19:02\n" "PO-Revision-Date: 2011-05-03 15:46+0100\n" "Last-Translator: RaSca \n" "Language-Team: None\n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. Tag: title #, no-c-format msgid "Cluster Resources" msgstr "Risorse del cluster" #. Tag: title #, no-c-format msgid "What is a Cluster Resource" msgstr "Cos'è una risorsa del cluster" #. Tag: para #, no-c-format msgid " Resource " msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "The role of a resource agent is to abstract the service it provides and present a consistent view to the cluster, which allows the cluster to be agnostic about the resources it manages." msgstr "Il ruolo di un resource agent è quello di astrarre il servizio che eroga e presentarne una vista consistente al cluster, il che abilita il cluster ad essere all'oscuro delle risorse che gestisce. Il cluster non necessità di capire come funziona una risorsa perché si appoggia al resource agent per fare la cosa giusta quando viene eseguito uno start, uno stop o un comando di monitor." #. Tag: para #, no-c-format msgid "The cluster doesn’t need to understand how the resource works because it relies on the resource agent to do the right thing when given a start, stop or monitor command." msgstr "" #. Tag: para #, no-c-format msgid "For this reason it is crucial that resource agents are well tested." msgstr "Per questa ragione è cruciale che i resource agent siano ben testati." #. Tag: para #, no-c-format msgid "Typically resource agents come in the form of shell scripts, however they can be written using any technology (such as C, Python or Perl) that the author is comfortable with." msgstr "Tipicamente i resource agents nascono come script di shell, tuttavia possono essere scritti utilizzando qualsiasi tecnologia (come C, Python o Perl) con la quale l'autore abbia familiarità." #. Tag: title #, no-c-format msgid "Supported Resource Classes" msgstr "Classi di risorse supportate" #. Tag: para #, no-c-format msgid " Resourceclass class " msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "There are five classes of agents supported by Pacemaker:" msgstr "Esistono tre classi base di agenti supportati da Pacemaker. Il cui utilizzo viene caldeggiato:" #. Tag: para #, no-c-format msgid "OCF" msgstr "" #. Tag: para #, no-c-format msgid "LSB" msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "Upstart" msgstr "stop_start" #. Tag: para #, no-c-format msgid "Systemd" msgstr "" #. Tag: para #, no-c-format msgid "Fencing" msgstr "" #. Tag: para #, no-c-format msgid "Service" msgstr "" #. Tag: para #, no-c-format msgid " ResourceHeartbeat Heartbeat HeartbeatResources Resources " msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "Version 1 of Heartbeat came with its own style of resource agents and it is highly likely that many people have written their own agents based on its conventions. See http://wiki.linux-ha.org/HeartbeatResourceAgent for more information " msgstr "La versione 1 di Heartbeat aveva un proprio stile per i resource agent e verosimilmente tutte le persone che hanno sviluppato propri resource agent si sono basati su queste convenzioni. Per fare in modo che gli amministratori continuino ad utilizzare quest agenti questi sono supportati dal nuovo cluster manager." #. Tag: para #, no-c-format msgid "Although deprecated with the release of Heartbeat v2, they were supported by Pacemaker up until the release of 1.1.8 to enable administrators to continue to use these agents." msgstr "" #. Tag: title #, no-c-format msgid "Open Cluster Framework" msgstr "Open Cluster Framework" #. Tag: para #, no-c-format msgid " ResourceOCF OCF OCFResources Resources Open Cluster FrameworkResources Resources " msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "The OCF standard http://www.opencf.org/cgi-bin/viewcvs.cgi/specs/ra/resource-agent-api.txt?rev=HEAD - at least as it relates to resource agents. The Pacemaker implementation has been somewhat extended from the OCF Specs, but none of those changes are incompatible with the original OCF specification. is basically an extension of the Linux Standard Base conventions for init scripts to:" msgstr "Le specifiche OCF (per come si riferiscono ai resource agent, possono essere trovate qui: ) Nota: l'implementazione di Pacemaker è stata in qualche modo estesa dalle specifiche OCF, ma nessuno di questi cambiamenti è incompabile con la specifica originale OCF sono sostanzialmente un'estensione delle convenzioni degli script di init Linux Standard Base per " #. Tag: para #, fuzzy, no-c-format msgid "support parameters," msgstr "supportare parametri" #. Tag: para #, fuzzy, no-c-format msgid "make them self describing and" msgstr "renderli auto esplicativi ed" #. Tag: para #, no-c-format msgid "extensible" msgstr "estensibili" #. Tag: para #, no-c-format msgid "OCF specs have strict definitions of the exit codes that actions must return. Included with the cluster is the ocf-tester script, which can be useful in this regard. " msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "The cluster follows these specifications exactly, and giving the wrong exit code will cause the cluster to behave in ways you will likely find puzzling and annoying. In particular, the cluster needs to distinguish a completely stopped resource from one which is in some erroneous and indeterminate state." msgstr "Le specifiche OCF hanno definizioni rigorose di quali exit code devono restituire Incluso nel cluster vi è lo script ocf-tester che può essere utile in questo senso. Il cluster segue esattamente queste specifiche e restituire un exit code non corretto causerebbe al cluster comportamenti inaspettati e noiosi difficili da interpretare. In particolare il cluster necessita di distinguere una risorsa competamente stoppata da una che si trova in stato errato o indeterminabile." #. Tag: para #, fuzzy, no-c-format msgid "Parameters are passed to the script as environment variables, with the special prefix OCF_RESKEY_. So, a parameter which the user thinks of as ip it will be passed to the script as OCF_RESKEY_ip. The number and purpose of the parameters is completely arbitrary, however your script should advertise any that it supports using the meta-data command." msgstr "I parametri sono passati allo script come variabili d'ambiente, con il prefisso speciale OCF_RESKEY_. Quindi se la propria necessità è quella di utilizzare una variabile chiamata ip, questa verrà passata allo script come OCF_RESKEY_ip. Il numero e lo scopo dei parametri è completamente arbitrario, ad ogni modo lo script dovrebbe allertare su quali parametri supporta mediante il comando meta-data." #. Tag: para #, no-c-format msgid "The OCF class is the most preferred one as it is an industry standard, highly flexible (allowing parameters to be passed to agents in a non-positional manner) and self-describing." msgstr "La classe OCF è la preferita poiché è uno standard industriale, altamente flessibile (permettendo che i parametri vengano passati agli agenti in maniera non posizionale) ed auto esplicativi." #. Tag: para #, fuzzy, no-c-format msgid "For more information, see the reference and ." msgstr "Per ulteriori informazioni, vedere e ." #. Tag: title #, no-c-format msgid "Linux Standard Base" msgstr "Linux Standard Base" #. Tag: para #, no-c-format msgid " ResourceLSB LSB LSBResources Resources Linux Standard BaseResources Resources " msgstr "" #. Tag: para #, no-c-format msgid "LSB resource agents are those found in /etc/init.d." msgstr "" #. Tag: para #, no-c-format msgid "Generally they are provided by the OS/distribution and, in order to be used with the cluster, they must conform to the LSB Spec. See http://refspecs.linux-foundation.org/LSB_3.0.0/LSB-Core-generic/LSB-Core-generic/iniscrptact.html for the LSB Spec (as it relates to init scripts). " msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "Many distributions claim LSB compliance but ship with broken init scripts. For details on how to check if your init script is LSB-compatible, see . The most common problems are:" msgstr "Molte distribuzioni affermano di essere LSB compatibili, ma in realtà hanno script di init non funzionanti. Per vedere se i propri script di init sono LSB-compatibili fare riferimento alla FAQ ." #. Tag: para #, no-c-format msgid "Not implementing the status operation at all" msgstr "Assenza dell'operazione status" #. Tag: para #, no-c-format msgid "Not observing the correct exit status codes for start/stop/status actions" msgstr "Assenza dell'exit status corretto per le azioni start/stop/status" #. Tag: para #, no-c-format msgid "Starting a started resource returns an error (this violates the LSB spec)" msgstr "Lo start di una risorsa avviata restituisce un errore (questo viola le specifiche LSB)" #. Tag: para #, no-c-format msgid "Stopping a stopped resource returns an error (this violates the LSB spec)" msgstr "Lo stop di una risorsa ferma restituisce un errore (questo viola le specifiche LSB)" #. Tag: para #, no-c-format msgid " ResourceSystemd Systemd SystemdResources Resources " msgstr "" #. Tag: para #, no-c-format msgid "Some newer distributions have replaced the old SYS-V style of initialization daemons (and scripts) with an alternative called Systemd." msgstr "" #. Tag: para #, no-c-format msgid "Pacemaker is able to manage these services if they are present." msgstr "" #. Tag: para #, no-c-format msgid "Instead of init scripts, systemd has unit files. Generally the services (or unit files) are provided by the OS/distribution but there are some instructions for converting from init scripts at: http://0pointer.de/blog/projects/systemd-for-admins-3.html" msgstr "" #. Tag: para #, no-c-format msgid "Remember to make sure the computer is not configured to start any services at boot time that should be controlled by the cluster." msgstr "" #. Tag: para #, no-c-format msgid " ResourceUpstart Upstart UpstartResources Resources " msgstr "" #. Tag: para #, no-c-format msgid "Some newer distributions have replaced the old SYS-V style of initialization daemons (and scripts) with an alternative called Upstart." msgstr "" #. Tag: para #, no-c-format msgid "Instead of init scripts, upstart has jobs. Generally the services (or jobs) are provided by the OS/distribution." msgstr "" #. Tag: title #, no-c-format msgid "System Services" msgstr "" #. Tag: para #, no-c-format msgid " ResourceSystem Services System Services System ServiceResources Resources " msgstr "" #. Tag: para #, no-c-format msgid "Since there are now many \"common\" types of system services (systemd, upstart, and lsb), Pacemaker supports a special alias which intelligently figures out which one applies to a given cluster node." msgstr "" #. Tag: para #, no-c-format msgid "This is particularly useful when the cluster contains a mix of systemd, upstart, and lsb." msgstr "" #. Tag: para #, no-c-format msgid "In order, Pacemaker will try to find the named service as:" msgstr "" #. Tag: para #, no-c-format msgid "an LSB (SYS-V) init script" msgstr "" #. Tag: para #, no-c-format msgid "a Systemd unit file" msgstr "" #. Tag: para #, no-c-format msgid "an Upstart job" msgstr "" #. Tag: title #, no-c-format msgid "STONITH" msgstr "" #. Tag: para #, no-c-format msgid " ResourceSTONITH STONITH STONITHResources Resources " msgstr "" #. Tag: para #, no-c-format msgid "There is also an additional class, STONITH, which is used exclusively for fencing related resources. This is discussed later in ." msgstr "Esiste ancheuna classe aggiuntiva, STONITH, che viene usata esclusivamente per effettuare il fence delle risorse relative. L'argomento è trattato più avanti nel ." #. Tag: title #, fuzzy, no-c-format msgid "Resource Properties" msgstr "Operazioni sulle risorse" #. Tag: para #, no-c-format msgid "These values tell the cluster which script to use for the resource, where to find that script and what standards it conforms to." msgstr "Questo valore indica al cluster quale script utilizzare per la risorsa, dove trovarlo ed a quali standard è conforme." #. Tag: title #, no-c-format msgid "Properties of a Primitive Resource" msgstr "Proprietà di una Primitive Resource" #. Tag: entry #, no-c-format msgid "Field" msgstr "Campo" #. Tag: entry #, no-c-format msgid "Description" msgstr "Descrizione" #. Tag: para #, no-c-format msgid "id" msgstr "" #. Tag: para #, no-c-format msgid "Your name for the resource idResource Resource ResourcePropertyid Propertyid id " msgstr "" #. Tag: para #, no-c-format msgid "class" msgstr "" #. Tag: para #, no-c-format msgid "The standard the script conforms to. Allowed values: ocf, service, upstart, systemd, lsb, stonith classResource Resource ResourcePropertyclass Propertyclass class " msgstr "" #. Tag: para #, no-c-format msgid "type" msgstr "" #. Tag: para #, no-c-format msgid "The name of the Resource Agent you wish to use. Eg. IPaddr or Filesystem typeResource Resource ResourcePropertytype Propertytype type " msgstr "" #. Tag: para #, no-c-format msgid "provider" msgstr "" #. Tag: para #, no-c-format msgid "The OCF spec allows multiple vendors to supply the same ResourceAgent. To use the OCF resource agents supplied with Heartbeat, you should specify heartbeat here. providerResource Resource ResourcePropertyprovider Propertyprovider provider " msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "Resource definitions can be queried with the crm_resource tool. For example" msgstr "Le definizioni della risorsa possono essere interrogate con lo strumento crm_resource. Ad esempio" #. Tag: programlisting #, fuzzy, no-c-format msgid "# crm_resource --resource Email --query-xml" msgstr "crm_resource --resource Email --query-xml" #. Tag: para #, fuzzy, no-c-format msgid "might produce:" msgstr "potrebbe restituire" #. Tag: title #, fuzzy, no-c-format msgid "An example system resource" msgstr "Una risorsa LSB di esempio" #. Tag: programlisting #, no-c-format msgid "<primitive id=\"Email\" class=\"service\" type=\"exim\"/>" msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "One of the main drawbacks to system services (such as LSB, Systemd and Upstart) resources is that they do not allow any parameters!" msgstr "Uno dei principali svantaggi delle risorse LSB è che essi non supportano alcun parametro" #. Tag: title #, no-c-format msgid "An example OCF resource" msgstr "Un esempio di risorsa OCF" #. Tag: programlisting #, fuzzy, no-c-format msgid "" "<primitive id=\"Public-IP\" class=\"ocf\" type=\"IPaddr\" provider=\"heartbeat\">\n" " <instance_attributes id=\"params-public-ip\">\n" " <nvpair id=\"public-ip-addr\" name=\"ip\" value=\"1.2.3.4\"/>\n" " </instance_attributes>\n" "</primitive>" msgstr "" "\n" "\n" " <primitive id="Public-IP" class="ocf" type="IPaddr" provider="heartbeat">\n" " <instance_attributes id="params-public-ip">\n" " <nvpair id="public-ip-addr" name="ip" value="1.2.3.4"/>\n" " </instance_attributes>\n" " </primitive>\n" "\n" "\t" #. Tag: title #, no-c-format msgid "Resource Options" msgstr "Opzioni delle risorse" #. Tag: para #, fuzzy, no-c-format msgid "Options are used by the cluster to decide how your resource should behave and can be easily set using the --meta option of the crm_resource command." msgstr "Le opzioni vengono utilizzate dal cluster per decidere come la propria risorsa debba comportarsi. Esse possono facilmente essere impostate utilizzando l'opzione --meta del comando crm_resource." #. Tag: title #, no-c-format msgid "Options for a Primitive Resource" msgstr "Opzioni per una Primitive Resource" #. Tag: entry #, no-c-format msgid "Default" msgstr "Default" #. Tag: para #, no-c-format msgid "priority" msgstr "" #. Tag: para #, no-c-format msgid "0" msgstr "" #. Tag: para #, no-c-format msgid "If not all resources can be active, the cluster will stop lower priority resources in order to keep higher priority ones active. priorityResource Option Resource Option ResourceOptionpriority Optionpriority priority " msgstr "" #. Tag: para #, no-c-format msgid "target-role" msgstr "" #. Tag: para #, no-c-format msgid "Started" msgstr "" #. Tag: para #, no-c-format msgid "What state should the cluster attempt to keep this resource in? Allowed values:" msgstr "In quale stato il cluster deve cercare di tenere questa risorsa? Valori permessi:" #. Tag: para #, fuzzy, no-c-format msgid "* Stopped - Force the resource to be stopped" msgstr "Stopped - Forza lo stop risorsa" #. Tag: para #, fuzzy, no-c-format msgid "* Started - Allow the resource to be started (In the case of multi-state resources, they will not promoted to master)" msgstr "Started - Permetti alla risorsa di essere avviata (nel caso di risorse multi-state esse non verranno promosse a master)" #. Tag: para #, no-c-format msgid "* Master - Allow the resource to be started and, if appropriate, promoted target-roleResource Option Resource Option ResourceOptiontarget-role Optiontarget-role target-role " msgstr "" #. Tag: para #, no-c-format msgid "is-managed" msgstr "" #. Tag: para #, no-c-format msgid "TRUE" msgstr "" #. Tag: para #, no-c-format msgid "Is the cluster allowed to start and stop the resource? Allowed values: true, false is-managedResource Option Resource Option ResourceOptionis-managed Optionis-managed is-managed " msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "resource-stickiness" msgstr "resource-stickiness" #. Tag: para #, no-c-format msgid "Calculated" msgstr "" #. Tag: para #, no-c-format msgid "How much does the resource prefer to stay where it is? Defaults to the value of resource-stickiness in the rsc_defaults section resource-stickinessResource Option Resource Option ResourceOptionresource-stickiness Optionresource-stickiness resource-stickiness " msgstr "" #. Tag: para #, no-c-format msgid "requires" msgstr "" #. Tag: para #, no-c-format msgid "Under what conditions can the resource be started. (Since 1.1.8)" msgstr "" #. Tag: para #, no-c-format msgid "Defaults to fencing unless stonith-enabled is false or class is stonith - under those conditions the default is quorum. Possible values:" msgstr "" #. Tag: para #, no-c-format msgid "* nothing - can always be started" msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "* quorum - The cluster can only start this resource if a majority of the configured nodes are active" msgstr "quorum - Il cluster può avviare questa risorsa solamente se la maggioranza dei nodi configurati è attiva" #. Tag: para #, fuzzy, no-c-format msgid "* fencing - The cluster can only start this resource if a majority of the configured nodes are active and any failed or unknown nodes have been powered off." msgstr "fencing - Il cluster può avviare questa risorsa solo se la maggioranza dei nodi configurati è attiva e qualsiasi nodo fallito o sconosciuto è stato spento." #. Tag: para #, no-c-format msgid "* unfencing - The cluster can only start this resource if a majority of the configured nodes are active and any failed or unknown nodes have been powered off and only on nodes that have been unfenced indexterm: Option[requires,Resource] ResourceOptionrequires Optionrequires requires " msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "migration-threshold" msgstr "migration-threshold" #. Tag: para #, fuzzy, no-c-format msgid "INFINITY (disabled)" msgstr "0 (disabilitata)" #. Tag: para #, no-c-format msgid "How many failures may occur for this resource on a node, before this node is marked ineligible to host this resource. migration-thresholdResource Option Resource Option ResourceOptionmigration-threshold Optionmigration-threshold migration-threshold " msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "failure-timeout" msgstr "failure-timeout" #. Tag: para #, no-c-format msgid "0 (disabled)" msgstr "" #. Tag: para #, no-c-format msgid "How many seconds to wait before acting as if the failure had not occurred, and potentially allowing the resource back to the node on which it failed. failure-timeoutResource Option Resource Option ResourceOptionfailure-timeout Optionfailure-timeout failure-timeout " msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "multiple-active" msgstr "multiple-active" #. Tag: para #, no-c-format msgid "stop_start" msgstr "" #. Tag: para #, no-c-format msgid "What should the cluster do if it ever finds the resource active on more than one node. Allowed values:" msgstr "Cosa dovrebbe fare il cluster se mai trovasse la risorsa attiva su più di un nodo. Valori permessi:" #. Tag: para #, fuzzy, no-c-format msgid "* block - mark the resource as unmanaged" msgstr "block - marchiare la risorse come non gestita (unmanaged)" #. Tag: para #, fuzzy, no-c-format msgid "* stop_only - stop all active instances and leave them that way" msgstr "stop_only - ferma tutte le istanze attive a le lascia in questo stato" #. Tag: para #, fuzzy, no-c-format msgid "* stop_start - stop all active instances and start the resource in one location only" msgstr "stop_start - ferma tutte le istanze attive ed avvia le risorse in una sola posizione" #. Tag: para #, no-c-format msgid " multiple-activeResource Option Resource Option ResourceOptionmultiple-active Optionmultiple-active multiple-active " msgstr "" #. Tag: para #, no-c-format msgid "If you performed the following commands on the previous LSB Email resource" msgstr "Se sono stati eseguiti i seguenti comandi nella precedente risorsa LSB Email" #. Tag: programlisting #, fuzzy, no-c-format msgid "" "# crm_resource --meta --resource Email --set-parameter priority --property-value 100\n" "# crm_resource --meta --resource Email --set-parameter multiple-active --property-value block" msgstr "" "\n" "\tcrm_resource --meta --resource Email --set-parameter priority --property-value 100\n" "\tcrm_resource --meta --resource Email --set-parameter multiple-active --property-value block\n" " " #. Tag: para #, no-c-format msgid "the resulting resource definition would be" msgstr "la definizione della risorsa risultate sarebbe" #. Tag: title #, no-c-format msgid "An LSB resource with cluster options" msgstr "Una risorsa LSB con le opzioni cluster" #. Tag: programlisting #, fuzzy, no-c-format msgid "" "<primitive id=\"Email\" class=\"lsb\" type=\"exim\">\n" " <meta_attributes id=\"meta-email\">\n" " <nvpair id=\"email-priority\" name=\"priority\" value=\"100\"/>\n" " <nvpair id=\"email-active\" name=\"multiple-active\" value=\"block\"/>\n" " </meta_attributes>\n" "</primitive>" msgstr "" "\n" "\n" " <primitive id="Email" class="lsb" type="exim">\n" " <meta_attributes id="meta-email">\n" " <nvpair id="email-priority" name="priority" value="100"/>\n" " <nvpair id="email-active" name="multiple-active" value="block"/>\n" " </meta_attributes>\n" " </primitive>\n" "\n" "\t" #. Tag: title #, no-c-format msgid "Setting Global Defaults for Resource Options" msgstr "Settaggio dei valori di default globali per le opzioni delle risorse" #. Tag: para #, fuzzy, no-c-format msgid "To set a default value for a resource option, simply add it to the rsc_defaults section with crm_attribute. Thus," msgstr "Per assegnare il valore di default dell'opzione di una risorsa è sufficiente aggiungerla alla sezione rsc_defaults mediante crm_attribute. In questo modo," #. Tag: programlisting #, fuzzy, no-c-format msgid "# crm_attribute --type rsc_defaults --attr-name is-managed --attr-value false" msgstr "crm_attribute --type rsc_defaults --attr-name is-managed --attr-value false" #. Tag: para #, fuzzy, no-c-format msgid "would prevent the cluster from starting or stopping any of the resources in the configuration (unless of course the individual resources were specifically enabled and had is-managed set to true)." msgstr "verrà evitato che il cluster avvii o fermi una qualsiasi risorsa nella configurazione (a meno che le risorse siano specificamente abilitate e sia a true il valore is-managed)." #. Tag: title #, no-c-format msgid "Instance Attributes" msgstr "Attributi dell'istanza" #. Tag: para #, no-c-format msgid "The scripts of some resource classes (LSB not being one of them) can be given parameters which determine how they behave and which instance of a service they control." msgstr "Gli script di alcune classi di risorse (ad esclusione di quelli LSB) supportano il passaggio di parametri che determinano come questi si devono comportare e quale istanza del servizio controllano." #. Tag: para #, fuzzy, no-c-format msgid "If your resource agent supports parameters, you can add them with the crm_resource command. For instance" msgstr "Se il resource agent prescelto supporta parametri, è possibile aggiungerli mediante il comando crm_resource. Ad esempio" #. Tag: programlisting #, fuzzy, no-c-format msgid "# crm_resource --resource Public-IP --set-parameter ip --property-value 1.2.3.4" msgstr "crm_resource --resource Public-IP --set-parameter ip --property-value 1.2.3.4" #. Tag: para #, fuzzy, no-c-format msgid "would create an entry in the resource like this:" msgstr "creerà una entry come questa" #. Tag: title #, no-c-format msgid "An example OCF resource with instance attributes" msgstr "Una risorsa OCF di esempio con attributi di istanza" #. Tag: para #, fuzzy, no-c-format msgid "For an OCF resource, the result would be an environment variable called OCF_RESKEY_ip with a value of 1.2.3.4." msgstr "Per una risorsa OCF il risultato sarà una variabile d'ambiente chiamata OCF_RESKEY_ip il cui valore è 1.2.3.4" #. Tag: para #, fuzzy, no-c-format msgid "The list of instance attributes supported by an OCF script can be found by calling the resource script with the meta-data command. The output contains an XML description of all the supported attributes, their purpose and default values." msgstr "La lista degli attriuti di istanza supportati da uno script OCF può essere recuperata richiamando lo script con il comando meta-data. L'output contiene una descrizione XML di tutti gli attributi supportati, la loro funzione ed i valori di default." #. Tag: title #, no-c-format msgid "Displaying the metadata for the Dummy resource agent template" msgstr "Visualizzazione dei metadata per il template del resource agent Dummy" #. Tag: programlisting #, no-c-format msgid "" "# export OCF_ROOT=/usr/lib/ocf\n" "# $OCF_ROOT/resource.d/pacemaker/Dummy meta-data" msgstr "" #. Tag: programlisting #, fuzzy, no-c-format msgid "" "<?xml version=\"1.0\"?>\n" " <!DOCTYPE resource-agent SYSTEM \"ra-api-1.dtd\">\n" " <resource-agent name=\"Dummy\" version=\"0.9\">\n" " <version>1.0</version>\n" "\n" " <longdesc lang=\"en-US\">\n" " This is a Dummy Resource Agent. It does absolutely nothing except\n" " keep track of whether its running or not.\n" " Its purpose in life is for testing and to serve as a template for RA writers.\n" " </longdesc>\n" " <shortdesc lang=\"en-US\">Dummy resource agent</shortdesc>\n" "\n" " <parameters>\n" " <parameter name=\"state\" unique=\"1\">\n" " <longdesc lang=\"en-US\">\n" " Location to store the resource state in.\n" " </longdesc>\n" " <shortdesc lang=\"en-US\">State file</shortdesc>\n" " <content type=\"string\" default=\"/var/run/Dummy-{OCF_RESOURCE_INSTANCE}.state\" />\n" " </parameter>\n" "\n" " <parameter name=\"dummy\" unique=\"0\">\n" " <longdesc lang=\"en-US\">\n" " Dummy attribute that can be changed to cause a reload\n" " </longdesc>\n" " <shortdesc lang=\"en-US\">Dummy attribute that can be changed to cause a reload</shortdesc>\n" " <content type=\"string\" default=\"blah\" />\n" " </parameter>\n" " </parameters>\n" "\n" " <actions>\n" " <action name=\"start\" timeout=\"90\" />\n" " <action name=\"stop\" timeout=\"100\" />\n" " <action name=\"monitor\" timeout=\"20\" interval=\"10\",height=\"0\" start-delay=\"0\" />\n" " <action name=\"reload\" timeout=\"90\" />\n" " <action name=\"migrate_to\" timeout=\"100\" />\n" " <action name=\"migrate_from\" timeout=\"90\" />\n" " <action name=\"meta-data\" timeout=\"5\" />\n" " <action name=\"validate-all\" timeout=\"30\" />\n" " </actions>\n" " </resource-agent>" msgstr "" "\n" " export OCF_ROOT=/usr/lib/ocf; $OCF_ROOT/resource.d/pacemaker/Dummy meta-data\n" "\n" " <?xml version="1.0"?>\n" " <!DOCTYPE resource-agent SYSTEM "ra-api-1.dtd">\n" " <resource-agent name="Dummy" version="0.9">\n" " <version>1.0</version>\n" " \n" " <longdesc lang="en-US">\n" " This is a Dummy Resource Agent. It does absolutely nothing except \n" " keep track of whether its running or not.\n" " Its purpose in life is for testing and to serve as a template for RA writers.\n" " </longdesc>\n" " <shortdesc lang="en-US">Dummy resource agent</shortdesc>\n" " \n" " <parameters>\n" " <parameter name="state" unique="1">\n" " <longdesc lang="en-US">\n" " Location to store the resource state in.\n" " </longdesc>\n" " <shortdesc lang="en-US">State file</shortdesc>\n" " <content type="string" default="/var/run//Dummy-{OCF_RESOURCE_INSTANCE}.state" />\n" " </parameter>\n" " \n" " <parameter name="dummy" unique="0">\n" " <longdesc lang="en-US"> \n" " Dummy attribute that can be changed to cause a reload\n" " </longdesc>\n" " <shortdesc lang="en-US">Dummy attribute that can be changed to cause a reload</shortdesc>\n" " <content type="string" default="blah" />\n" " </parameter>\n" " </parameters>\n" " \n" " <actions>\n" " <action name="start" timeout="90" />\n" " <action name="stop" timeout="100" />\n" " <action name="monitor" timeout="20" interval="10" depth="0" start-delay="0" />\n" " <action name="reload" timeout="90" />\n" " <action name="migrate_to" timeout="100" />\n" " <action name="migrate_from" timeout="90" />\n" " <action name="meta-data" timeout="5" />\n" " <action name="validate-all" timeout="30" />\n" " </actions>\n" " </resource-agent>\n" "\n" " " #. Tag: title #, no-c-format msgid "Resource Operations" msgstr "Operazioni sulle risorse" #. Tag: para #, no-c-format msgid " ResourceAction Action " msgstr "" #. Tag: title #, no-c-format msgid "Monitoring Resources for Failure" msgstr "Monitoraggio di anomalie sulle risorse" #. Tag: para #, fuzzy, no-c-format msgid "By default, the cluster will not ensure your resources are still healthy. To instruct the cluster to do this, you need to add a monitor operation to the resource’s definition." msgstr "Come comportamento di default il cluster non accerterà che le risorse siano in salute. Per istruire il cluster a farlo è necessario aggiungere alla definizione della risorsa un'operazione di monitor." #. Tag: title #, no-c-format msgid "An OCF resource with a recurring health check" msgstr "Una risorsa OCF con un controllo dello stato di salute ciclico" #. Tag: programlisting #, fuzzy, no-c-format msgid "" "<primitive id=\"Public-IP\" class=\"ocf\" type=\"IPaddr\" provider=\"heartbeat\">\n" " <operations>\n" " <op id=\"public-ip-check\" name=\"monitor\" interval=\"60s\"/>\n" " </operations>\n" " <instance_attributes id=\"params-public-ip\">\n" " <nvpair id=\"public-ip-addr\" name=\"ip\" value=\"1.2.3.4\"/>\n" " </instance_attributes>\n" "</primitive>" msgstr "" "\n" "\n" " <primitive id="Public-IP" class="ocf" type="IPaddr" provider="heartbeat">\n" " <operations>\n" " <op id="public-ip-check" name="monitor" interval="60s"/>\n" " </operations>\n" " <instance_attributes id="params-public-ip">\n" " <nvpair id="public-ip-addr" name="ip" value="1.2.3.4"/>\n" " </instance_attributes>\n" " </primitive>\n" "\n" "\t " #. Tag: title #, no-c-format msgid "Properties of an Operation" msgstr "Proprietà di un'operazione" #. Tag: para #, no-c-format msgid "Your name for the action. Must be unique. idAction Property Action Property ActionPropertyid Propertyid id " msgstr "" #. Tag: para #, no-c-format msgid "name" msgstr "" #. Tag: para #, no-c-format msgid "The action to perform. Common values: monitor, start, stop nameAction Property Action Property ActionPropertyname Propertyname name " msgstr "" #. Tag: para #, no-c-format msgid "interval" msgstr "" #. Tag: para #, no-c-format msgid "How frequently (in seconds) to perform the operation. Default value: 0, meaning never. intervalAction Property Action Property ActionPropertyinterval Propertyinterval interval " msgstr "" #. Tag: para #, no-c-format msgid "timeout" msgstr "" #. Tag: para #, no-c-format msgid "How long to wait before declaring the action has failed. timeoutAction Property Action Property ActionPropertytimeout Propertytimeout timeout " msgstr "" #. Tag: para #, no-c-format msgid "on-fail" msgstr "" #. Tag: para #, no-c-format msgid "The action to take if this action ever fails. Allowed values:" msgstr "L'azione da intraprendere se l'azione principale dovesse fallire. Valori permessi:" #. Tag: para #, fuzzy, no-c-format msgid "* ignore - Pretend the resource did not fail" msgstr "ignore - Pretende che la risorsa non fallisca." #. Tag: para #, fuzzy, no-c-format msgid "* block - Don’t perform any further operations on the resource" msgstr "block - Non effettuar alcuna altra operazione sulla risorsa" #. Tag: para #, fuzzy, no-c-format msgid "* stop - Stop the resource and do not start it elsewhere" msgstr "stop - Ferma la risorsa che non verrà avviata da nessuna parte" #. Tag: para #, fuzzy, no-c-format msgid "* restart - Stop the resource and start it again (possibly on a different node)" msgstr "restart - Ferma la risorsa e la avvia di nuovo (possibilmente su di un altro nodo)" #. Tag: para #, fuzzy, no-c-format msgid "* fence - STONITH the node on which the resource failed" msgstr "fence - effettua lo STONITH sul nodo dove è fallita la risorsa" #. Tag: para #, fuzzy, no-c-format msgid "* standby - Move all resources away from the node on which the resource failed" msgstr "standby - Sposta tutte le risorse altrove dal nodo in cui queste sono fallite" #. Tag: para #, no-c-format msgid "The default for the stop operation is fence when STONITH is enabled and block otherwise. All other operations default to stop. on-failAction Property Action Property ActionPropertyon-fail Propertyon-fail on-fail " msgstr "" #. Tag: para #, no-c-format msgid "enabled" msgstr "" #. Tag: para #, no-c-format msgid "If false, the operation is treated as if it does not exist. Allowed values: true, false enabledAction Property Action Property ActionPropertyenabled Propertyenabled enabled " msgstr "" #. Tag: title #, no-c-format msgid "Setting Global Defaults for Operations" msgstr "Settaggio dei valori di default globali per le operazioni" #. Tag: para #, fuzzy, no-c-format msgid "To set a default value for a operation option, simply add it to the op_defaults section with crm_attribute. Thus," msgstr "Per assegnare il valore di default dell'opzione di una risorsa è sufficiente aggiungerla alla sezione rsc_defaults mediante crm_attribute. In questo modo," #. Tag: programlisting #, fuzzy, no-c-format msgid "# crm_attribute --type op_defaults --attr-name timeout --attr-value 20s" msgstr "crm_attribute --type op_defaults --attr-name timeout --attr-value 20s" #. Tag: para #, fuzzy, no-c-format msgid "would default each operation’s timeout to 20 seconds. If an operation’s definition also includes a value for timeout, then that value would be used instead (for that operation only)." msgstr "imposterà 20 secondi come valore di default per ciascuna operazione. Se la definizione dell'operazione include anche un valore per il timeout, allora verrà utilizzato questo valore (solamente per questa operazione)." #. Tag: title #, no-c-format msgid "When Resources Take a Long Time to Start/Stop" msgstr "Quando una risorsa impiega molto tempo per Avviarsi/Fermarsi" #. Tag: para #, fuzzy, no-c-format msgid "There are a number of implicit operations that the cluster will always perform - start, stop and a non-recurring monitor operation (used at startup to check the resource isn’t already active). If one of these is taking too long, then you can create an entry for them and simply specify a new value." msgstr "Esistono diverse operazioni implicite che il cluster effettuerà sempre - start, stop e monitoraggi non ricorrenti (utilizzati in fase di avvio per verificare che la risorsa non sia già attiva). Se una di queste impiega troppo tempo, sarà possibile creare una entry relativa e specificare semplicemente un nuovo valore." #. Tag: title #, no-c-format msgid "An OCF resource with custom timeouts for its implicit actions" msgstr "Una risorsa OCF on timeout personalizzato per le proprie azioni implicite" #. Tag: programlisting #, fuzzy, no-c-format msgid "" "<primitive id=\"Public-IP\" class=\"ocf\" type=\"IPaddr\" provider=\"heartbeat\">\n" " <operations>\n" " <op id=\"public-ip-startup\" name=\"monitor\" interval=\"0\" timeout=\"90s\"/>\n" " <op id=\"public-ip-start\" name=\"start\" interval=\"0\" timeout=\"180s\"/>\n" " <op id=\"public-ip-stop\" name=\"stop\" interval=\"0\" timeout=\"15min\"/>\n" " </operations>\n" " <instance_attributes id=\"params-public-ip\">\n" " <nvpair id=\"public-ip-addr\" name=\"ip\" value=\"1.2.3.4\"/>\n" " </instance_attributes>\n" "</primitive>" msgstr "" "\n" "\n" " <primitive id="Public-IP" class="ocf" type="IPaddr" provider="heartbeat">\n" " <operations>\n" " <op id="public-ip-startup" name="monitor" interval="0" timeout="90s"/>\n" " <op id="public-ip-start" name="start" interval="0" timeout="180s"/>\n" " <op id="public-ip-stop" name="stop" interval="0" timeout="15min"/>\n" " </operations>\n" " <instance_attributes id="params-public-ip">\n" " <nvpair id="public-ip-addr" name="ip" value="1.2.3.4"/>\n" " </instance_attributes>\n" " </primitive>\n" "\n" "\t " #. Tag: title #, no-c-format msgid "Multiple Monitor Operations" msgstr "Operazioni di monitoraggio multiple" #. Tag: para #, no-c-format msgid "Provided no two operations (for a single resource) have the same name and interval you can have as many monitor operations as you like. In this way you can do a superficial health check every minute and progressively more intense ones at higher intervals." msgstr "Purché non ci sono due operazioni (per una singola risorsa) con lo stesso nome ed intervallo è possibile avere un umero arbitrario di operazioni di monitoraggio . In questo modo si può fare un controllo superficiale ogni minuto, che si intensificherà con intervalli più alti." #. Tag: para #, fuzzy, no-c-format msgid "To tell the resource agent what kind of check to perform, you need to provide each monitor with a different value for a common parameter. The OCF standard creates a special parameter called OCF_CHECK_LEVEL for this purpose and dictates that it is \"made available to the resource agent without the normal OCF_RESKEY prefix\"." msgstr "Per comunicare al resource agent che tipo di controllo effettuare è necessario fornire ogni monitor con un valore di parametro comune differente. Lo standard OCF, per questo scopo, crea un parametro speciale denominato OCF_CHECK_LEVEL ed impone che questo sia reso disponibile al resource agent senza il normale prefisso OCF_RESKEY_." #. Tag: para #, fuzzy, no-c-format msgid "Whatever name you choose, you can specify it by adding an instance_attributes block to the op tag. Note that it is up to each resource agent to look for the parameter and decide how to use it." msgstr "Qualsiasi nome venga scelto sarà possibile specificarlo aggiungendo un blocco instance_attributes al tag op. Va sottolineato come è compito di ciascun resource agent controllae il parametro e decidere come utilizzarlo." #. Tag: title #, fuzzy, no-c-format msgid "An OCF resource with two recurring health checks, performing different levels of checks - specified via OCF_CHECK_LEVEL." msgstr "Una risorsa OCF con due controlli di sanità ricorrenti che effettuano differenti livelli di controllo" #. Tag: programlisting #, fuzzy, no-c-format msgid "" "<primitive id=\"Public-IP\" class=\"ocf\" type=\"IPaddr\" provider=\"heartbeat\">\n" " <operations>\n" " <op id=\"public-ip-health-60\" name=\"monitor\" interval=\"60\">\n" " <instance_attributes id=\"params-public-ip-depth-60\">\n" " <nvpair id=\"public-ip-depth-60\" name=\"OCF_CHECK_LEVEL\" value=\"10\"/>\n" " </instance_attributes>\n" " </op>\n" " <op id=\"public-ip-health-300\" name=\"monitor\" interval=\"300\">\n" " <instance_attributes id=\"params-public-ip-depth-300\">\n" " <nvpair id=\"public-ip-depth-300\" name=\"OCF_CHECK_LEVEL\" value=\"20\"/>\n" " </instance_attributes>\n" " </op>\n" " </operations>\n" " <instance_attributes id=\"params-public-ip\">\n" " <nvpair id=\"public-ip-level\" name=\"ip\" value=\"1.2.3.4\"/>\n" " </instance_attributes>\n" "</primitive>" msgstr "" "\n" "\n" " <primitive id="Public-IP" class="ocf" type="IPaddr" provider="heartbeat">\n" " <operations>\n" " <op id="public-ip-health-60" name="monitor" interval="60">\n" " <instance_attributes id="params-public-ip-depth-60">\n" " <nvpair id="public-ip-depth-60" name="OCF_CHECK_LEVEL" value="10"/>\n" " </instance_attributes>\n" " </op>\n" " <op id="public-ip-health-300" name="monitor" interval="300">\n" " <instance_attributes id="params-public-ip-depth-300">\n" " <nvpair id="public-ip-depth-300" name="OCF_CHECK_LEVEL" value="20"/>\n" " </instance_attributes>\n" " </op>\n" " </operations>\n" " <instance_attributes id="params-public-ip">\n" " <nvpair id="public-ip-level" name="ip" value="1.2.3.4"/>\n" " </instance_attributes>\n" " </primitive>\n" "\n" "\t " #. Tag: title #, no-c-format msgid "Disabling a Monitor Operation" msgstr "Disabilitare un'operazione di monitoring" #. Tag: para #, fuzzy, no-c-format msgid "The easiest way to stop a recurring monitor is to just delete it. However, there can be times when you only want to disable it temporarily. In such cases, simply add enabled=\"false\" to the operation’s definition." msgstr "La via più semplice per fermare un monitor ricorrente è semplicemente quella di cancellarlo. Ad ogni modo ci saranno occasioni in cui l'esigenza sia semplicemente quella di disabilitare il controllo temporaneamente. In questi casi, sarà sufficiente aggiungere disabled="true" akka definizione dell'operazione." #. Tag: title #, no-c-format msgid "Example of an OCF resource with a disabled health check" msgstr "Esempio di una risorsa OCF con controllo di sanità disabilitato" #. Tag: programlisting #, fuzzy, no-c-format msgid "" "<primitive id=\"Public-IP\" class=\"ocf\" type=\"IPaddr\" provider=\"heartbeat\">\n" " <operations>\n" " <op id=\"public-ip-check\" name=\"monitor\" interval=\"60s\" enabled=\"false\"/>\n" " </operations>\n" " <instance_attributes id=\"params-public-ip\">\n" " <nvpair id=\"public-ip-addr\" name=\"ip\" value=\"1.2.3.4\"/>\n" " </instance_attributes>\n" "</primitive>" msgstr "" "\n" "\n" " <primitive id="Public-IP" class="ocf" type="IPaddr" provider="heartbeat">\n" " <operations>\n" " <op id="public-ip-check" name="monitor" interval="60s"/>\n" " </operations>\n" " <instance_attributes id="params-public-ip">\n" " <nvpair id="public-ip-addr" name="ip" value="1.2.3.4"/>\n" " </instance_attributes>\n" " </primitive>\n" "\n" "\t " #. Tag: para #, no-c-format msgid "This can be achieved from the command-line by executing" msgstr "L'operazione è effettuabile da linea di comando, eseguendo" #. Tag: programlisting #, fuzzy, no-c-format msgid "# cibadmin -M -X '<op id=\"public-ip-check\" enabled=\"false\"/>'" msgstr "cibadmin -M -X ‘<op id="public-ip-check" disabled="false"/>'" #. Tag: para #, fuzzy, no-c-format msgid "Once you’ve done whatever you needed to do, you can then re-enable it with" msgstr "Una volta ottenuto il proprio scopo, sarà possibile riabilitare nuovamente il controllo con" #~ msgid "LSB resource agents are those found in /etc/init.d. Generally they are provided by the OS/distribution and in order to be used with the cluster, must conform to the LSB Spec." #~ msgstr "I resource agents LSB si trovano in /etc/init.d. Generalmente sono forniti dalla distribuzione e per essere utilizzati con il cluster devono essere conformi alle specifiche LSB." #~ msgid "The LSB Spec (as it relates to init scripts) can be found at: " #~ msgstr "Le specifiche LSB (per come si riferiscono agli script di init) si trovano qui: " #~ msgid "Legacy Heartbeat" #~ msgstr "Legacy Heartbeat" #~ msgid "For more information, see: " #~ msgstr "Per ulteriori informazioni vedere: " #~ msgid "Properties" #~ msgstr "Proprietà" #~ msgid "id" #~ msgstr "id" #~ msgid "Your name for the resource" #~ msgstr "Il nome della risorsa" #~ msgid "class" #~ msgstr "class" #~ msgid "The standard the script conforms to. Allowed values: heartbeat, lsb, ocf, stonith" #~ msgstr "Lo standard a cui lo script è conforme. Valori permessi: heartbeat, lsb, ocf, stonith" #~ msgid "type" #~ msgstr "type" #~ msgid "The name of the Resource Agent you wish to use. eg. IPaddr or Filesystem" #~ msgstr "Il nome del Resource Agent che si vuole utilizzare. Ad esempio IPaddr o Filesystem" #~ msgid "provider" #~ msgstr "provider" #~ msgid "The OCF spec allows multiple vendors to supply the same ResourceAgent. To use the OCF resource agents supplied with Heartbeat, you should specify heartbeat here." #~ msgstr "La specifica OCF consente fornitori multipli per lo stesso Resource Agent. Per utilizzare i resource agent OCF forniti da Heartbeat, andrebbe specificato qui \"heartbeat\"." #~ msgid "" #~ "\n" #~ " <primitive id="Email" class="lsb" type="exim"/>\n" #~ "\t" #~ msgstr "" #~ "\n" #~ " <primitive id="Email" class="lsb" type="exim"/>\n" #~ "\t" #~ msgid "or, for an OCF resource:" #~ msgstr "o, per una risorsa OCF:" #~ msgid "" #~ "\n" #~ "\n" #~ " <primitive id="Public-IP" class="ocf" type="IPaddr" provider="heartbeat">\n" #~ " <instance_attributes id="params-public-ip">\n" #~ " <nvpair id="public-ip-addr" name="ip" value="1.2.3.4"/>\n" #~ " </instance_attributes>\n" #~ " </primitive>\n" #~ "\n" #~ "\t" #~ msgstr "" #~ "\n" #~ "\n" #~ " <primitive id="Public-IP" class="ocf" type="IPaddr" provider="heartbeat">\n" #~ " <instance_attributes id="params-public-ip">\n" #~ " <nvpair id="public-ip-addr" name="ip" value="1.2.3.4"/>\n" #~ " </instance_attributes>\n" #~ " </primitive>\n" #~ "\n" #~ "\t" #~ msgid "or, finally for the equivalent legacy Heartbeat resource:" #~ msgstr "o, infine per la risora legacy Heartbeat equivalente:" #~ msgid "An example Heartbeat resource" #~ msgstr "Una risorsa Heartbeat di esempio" #~ msgid "" #~ "\n" #~ "\n" #~ " <primitive id="Public-IP-legacy" class="heartbeat" type="IPaddr">\n" #~ " <instance_attributes id="params-public-ip-legacy">\n" #~ " <nvpair id="public-ip-addr-legacy" name="1" value="1.2.3.4"/>\n" #~ " </instance_attributes>\n" #~ " </primitive>\n" #~ "\n" #~ "\t" #~ msgstr "" #~ "\n" #~ "\n" #~ " <primitive id="Public-IP-legacy" class="heartbeat" type="IPaddr">\n" #~ " <instance_attributes id="params-public-ip-legacy">\n" #~ " <nvpair id="public-ip-addr-legacy" name="1" value="1.2.3.4"/>\n" #~ " </instance_attributes>\n" #~ " </primitive>\n" #~ "\n" #~ "\t" #~ msgid "Heartbeat resources take only ordered and unnamed parameters. The supplied name therefor indicates the order in which they are passed to the script. Only single digit values are allowed." #~ msgstr "Le risorse heartbeat supportano solo parametri non ordinati e senza nome. Il nome fornito indica quindi l'ordine in cui essi vengono passati allo script. Sono permessi solo valori a singola cifra." #~ msgid "priority" #~ msgstr "priority" #~ msgid "0" #~ msgstr "0" #~ msgid "If not all resources can be active, the cluster will stop lower priority resources in order to keep higher priority ones active." #~ msgstr "Se non possono essere attive tutte le risorse, il cluster fermerà le risorse con la minore priorità in modo da mantenere attive quelle ad alta prorità." #~ msgid "target-role" #~ msgstr "target-role" #~ msgid "Started" #~ msgstr "Started" #~ msgid "Master - Allow the resource to be started and, if appropriate, promoted" #~ msgstr "Master - Consenti alla risorsa di essere avviata e, se è il caso, promossa a master" #~ msgid "is-managed" #~ msgstr "is-managed" #~ msgid "TRUE" #~ msgstr "TRUE" #~ msgid "Is the cluster allowed to start and stop the resource? Allowed values: true, false" #~ msgstr "Il cluster può avviare e stoppare la risorsa? Valori permessi: true, false" #~ msgid "Inherited" #~ msgstr "Inherited" #~ msgid "How much does the resource prefer to stay where it is? Defaults to the value of resource-stickiness in the rsc_defaults section" #~ msgstr "Quanto la risorsa deve preferire rimanere dov'è? Il valore di default corrisponde al valore resource-stickiness nella sezione rsc_defaults" #~ msgid "How many failures should occur for this resource on a node before making the node ineligible to host this resource." #~ msgstr "Quanti fallimenti si devono verificare su un nodo per questa risorsa prima di rendere il nodo ineleggibile all'erogazione di questa risorsa." #~ msgid "0 (disabled)" #~ msgstr "0 (disabilitata)" #~ msgid "How many seconds to wait before acting as if the failure had not occurred (and potentially allowing the resource back to the node on which it failed." #~ msgstr "Quanti secondo aspettare prima di agire come se il fallimento non si fosse verificato (abilitando potenzialmente la risorsa sul nodo in cui è fallita)." #~ msgid "Your name for the action. Must be unique." #~ msgstr "Nome assegnato all'azione. Deve essere univoco." #~ msgid "name" #~ msgstr "name" #~ msgid "The action to perform. Common values: monitor, start, stop" #~ msgstr "L'azione da eseguire. Valori possibili: monitor, start, stop" #~ msgid "interval" #~ msgstr "interval" #~ msgid "How frequently (in seconds) to perform the operation. Default value: 0" #~ msgstr "Quanto frequentemente (in secondi) effettuare l'operazione. Valore di default: 0" #~ msgid "timeout" #~ msgstr "timeout" #~ msgid "How long to wait before declaring the action has failed." #~ msgstr "Quanto aspettare prima di dichiarare che un'azione è fallita." #~ msgid "requires" #~ msgstr "requires" #~ msgid "What conditions need to be satisfied before this action occurs. Allowed values:" #~ msgstr "Quali condizioni devono essere soddisfatte prima che l'azione avvenga. Valori permessi:" #~ msgid "nothing - The cluster may start this resource at any time" #~ msgstr "nothing - Il cluster può avviare la risorsa quando vuole" #~ msgid "STONITH resources default to nothing, and all others default to fencing if STONITH is enabled and quorum otherwise." #~ msgstr "Le risorse STONITH per default non fanno nulla mentre tutte le altre, per default, utilizzano \"fencing\" se STONITH è abilitato nel cluster e \"quorum\" in tutti gli altri casi." #~ msgid "on-fail" #~ msgstr "on-fail" #~ msgid "The default for the stop operation is fence when STONITH is enabled and block otherwise. All other operations default to stop." #~ msgstr "Il valore di default per l'operazione di stop è \"fence\" quando STONITH è abilitato e \"block\" negli altri casi. Tutte le altre operazioni per default utilizzano \"stop\"." #~ msgid "enabled" #~ msgstr "enabled" #~ msgid "If false, the operation is treated as if it does not exist. Allowed values: true, false" #~ msgstr "Se impostato a \"false\" l'operazione viene trattata come se non esiste. Valori permessi: true, false" #~ msgid "To set a default value for a operation option, simply add it to the op_defaults section with crm_attribute. Thus," #~ msgstr "Per impostare il valore di default dell'opzione di un'operazione è sufficiente aggiungerlo alla sezione op_defaults section mediante crm_attribute. Quindi." #~ msgid "" #~ "\n" #~ "\n" #~ " <primitive id="Public-IP" class="ocf" type="IPaddr" provider="heartbeat">\n" #~ " <operations>\n" #~ " <op id="public-ip-check" name="monitor" interval="60s" disabled="true"/>\n" #~ " </operations>\n" #~ " <instance_attributes id="params-public-ip">\n" #~ " <nvpair id="public-ip-addr" name="ip" value="1.2.3.4"/>\n" #~ " </instance_attributes>\n" #~ " </primitive>\n" #~ "\n" #~ "\t " #~ msgstr "" #~ "\n" #~ "\n" #~ " <primitive id="Public-IP" class="ocf" type="IPaddr" provider="heartbeat">\n" #~ " <operations>\n" #~ " <op id="public-ip-check" name="monitor" interval="60s" disabled="true"/>\n" #~ " </operations>\n" #~ " <instance_attributes id="params-public-ip">\n" #~ " <nvpair id="public-ip-addr" name="ip" value="1.2.3.4"/>\n" #~ " </instance_attributes>\n" #~ " </primitive>\n" #~ "\n" #~ "\t " #~ msgid "cibadmin -M -X ‘<op id="public-ip-check" disabled="true"/>'" #~ msgstr "cibadmin -M -X ‘<op id="public-ip-check" disabled="true"/>'" pacemaker-master/doc/Pacemaker_Explained/it-IT/Ch-Rules.po000066400000000000000000001563321217637305600236610ustar00rootroot00000000000000# # AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: 0\n" "POT-Creation-Date: 2012-10-17T05:19:02\n" "PO-Revision-Date: 2012-01-30 17:16+0100\n" "Last-Translator: RaSca \n" "Language-Team: None\n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. Tag: title #, no-c-format msgid "Rules" msgstr "Regole" #. Tag: para #, no-c-format msgid " ResourceConstraintRule ConstraintRule Rule " msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "Rules can be used to make your configuration more dynamic. One common example is to set one value for resource-stickiness during working hours, to prevent resources from being moved back to their most preferred location, and another on weekends when no-one is around to notice an outage." msgstr "Le regole possono essere utilizzate per rendere la propria configurazione più dinamica. Un esempio comune sta nell'impostare un valore di resource-stickiness durante le ore lavorative, per prevenire che le risorse vengano spostate alla loro posizione preferita, ed un altro nei weekend, quando l'impatto dell'operazione di spostamento non verrà notato." #. Tag: para #, no-c-format msgid "Another use of rules might be to assign machines to different processing groups (using a node attribute) based on time and to then use that attribute when creating location constraints." msgstr "Un'altra regola impostabile potrebbe essere quella di assegnare le macchine a differenti gruppi di processo (utilizzando gli attributi del nodo) basati sulle tempistiche ed utilizzare quindi questi attributi nella creazione delle constraint di tipo location." #. Tag: para #, fuzzy, no-c-format msgid "Each rule can contain a number of expressions, date-expressions and even other rules. The results of the expressions are combined based on the rule’s boolean-op field to determine if the rule ultimately evaluates to true or false. What happens next depends on the context in which the rule is being used." msgstr "Ogni regola può contenere diverse espressioni, espressioni di tipo data ed altre regole. L'esito delle espressione è combinato in base al valore del campo boolean-op per determinare se la regola infine risulta vera o falsa. Quello che accade successivamente dipende dal contesto in cui la regola viene utilizzata." #. Tag: title #, no-c-format msgid "Properties of a Rule" msgstr "Proprietà di una regola" #. Tag: entry #, no-c-format msgid "Field" msgstr "Campo" #. Tag: entry #, no-c-format msgid "Description" msgstr "Descrizione" #. Tag: para #, no-c-format msgid "role" msgstr "" #. Tag: para #, no-c-format msgid "Limits the rule to apply only when the resource is in that role. Allowed values: Started, Slave, and Master. NOTE: A rule with role=\"Master\" can not determine the initial location of a clone instance. It will only affect which of the active instances will be promoted. roleConstraint Rule Constraint Rule ConstraintRulerole Rulerole role " msgstr "" #. Tag: para #, no-c-format msgid "score" msgstr "" #. Tag: para #, no-c-format msgid "The score to apply if the rule evaluates to true. Limited to use in rules that are part of location constraints. scoreConstraint Rule Constraint Rule ConstraintRulescore Rulescore score " msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "score-attribute" msgstr "Utilizzo di score-attribute invece di score" #. Tag: para #, no-c-format msgid "The node attribute to look up and use as a score if the rule evaluates to true. Limited to use in rules that are part of location constraints. score-attributeConstraint Rule Constraint Rule ConstraintRulescore-attribute Rulescore-attribute score-attribute " msgstr "" #. Tag: para #, no-c-format msgid "boolean-op" msgstr "" #. Tag: para #, no-c-format msgid "How to combine the result of multiple expression objects. Allowed values: and and or. boolean-opConstraint Rule Constraint Rule ConstraintRuleboolean-op Ruleboolean-op boolean-op " msgstr "" #. Tag: title #, no-c-format msgid "Node Attribute Expressions" msgstr "Espressioni relative agli attributi del nodo" #. Tag: para #, no-c-format msgid " ResourceConstraintAttribute Expression ConstraintAttribute Expression Attribute Expression " msgstr "" #. Tag: para #, no-c-format msgid "Expression objects are used to control a resource based on the attributes defined by a node or nodes. In addition to any attributes added by the administrator, each node has a built-in node attribute called #uname that can also be used." msgstr "Gli oggetti espressione sono utilizzati per controllare una risorsa basata sugli attributi definiti da uno o più nodi. In aggiunta a qualsiasi attributo aggiunto dall'amministratore, ogni nodo possiede un attributo predefinito che può essere utilizzato chiamato #uname." #. Tag: title #, no-c-format msgid "Properties of an Expression" msgstr "Proprietà di un'espressione" #. Tag: para #, no-c-format msgid "value" msgstr "" #. Tag: para #, no-c-format msgid "User supplied value for comparison valueConstraint Expression Constraint Expression ConstraintAttribute Expressionvalue Attribute Expressionvalue value " msgstr "" #. Tag: para #, no-c-format msgid "attribute" msgstr "" #. Tag: para #, no-c-format msgid "The node attribute to test attributeConstraint Expression Constraint Expression ConstraintAttribute Expressionattribute Attribute Expressionattribute attribute " msgstr "" #. Tag: para #, no-c-format msgid "type" msgstr "" #. Tag: para #, no-c-format msgid "Determines how the value(s) should be tested. Allowed values: string, integer, version typeConstraint Expression Constraint Expression ConstraintAttribute Expressiontype Attribute Expressiontype type " msgstr "" #. Tag: para #, no-c-format msgid "operation" msgstr "" #. Tag: para #, no-c-format msgid "The comparison to perform. Allowed values:" msgstr "Il confronto da effettuare. Valori permessi:" #. Tag: para #, fuzzy, no-c-format msgid "* lt - True if the node attribute’s value is less than value" msgstr "lt - Vera se l'attributo del nodo è minore del valore" #. Tag: para #, fuzzy, no-c-format msgid "* gt - True if the node attribute’s value is greater than value" msgstr "gt - Vera se l'attributo del nodo è maggiore del valore" #. Tag: para #, fuzzy, no-c-format msgid "* lte - True if the node attribute’s value is less than or equal to value" msgstr "lte - Vera se l'attributo del nodo è minore o uguale al valore" #. Tag: para #, fuzzy, no-c-format msgid "* gte - True if the node attribute’s value is greater than or equal to value" msgstr "gte - Vera se l'attributo del nodo è maggiore o ugulae del valore" #. Tag: para #, fuzzy, no-c-format msgid "* eq - True if the node attribute’s value is equal to value" msgstr "eq - Vera se l'attributo del nodo è uguale al valore" #. Tag: para #, fuzzy, no-c-format msgid "* ne - True if the node attribute’s value is not equal to value" msgstr "ne - Vera se l'attributo del nodo non è uguale al valore" #. Tag: para #, fuzzy, no-c-format msgid "* defined - True if the node has the named attribute" msgstr "defined - Vera se il nodo possiede l'attributo indicato" #. Tag: para #, no-c-format msgid "* not_defined - True if the node does not have the named attribute operationConstraint Expression Constraint Expression ConstraintAttribute Expressionoperation Attribute Expressionoperation operation " msgstr "" #. Tag: title #, no-c-format msgid "Time/Date Based Expressions" msgstr "Espressioni basate su Ora/Data" #. Tag: para #, no-c-format msgid " Time Based Expressions ResourceConstraintDate/Time Expression ConstraintDate/Time Expression Date/Time Expression " msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "As the name suggests, date_expressions are used to control a resource or cluster option based on the current date/time. They can contain an optional date_spec and/or duration object depending on the context." msgstr "Come suggerisce il nome, le date_expressions sono utilizzate per contollare una risorsa o un'opzione del cluster in base alla data/ora attuale." #. Tag: title #, no-c-format msgid "Properties of a Date Expression" msgstr "Proprietà di un'espressione basata sulla data" #. Tag: para #, no-c-format msgid "start" msgstr "" #. Tag: para #, no-c-format msgid "A date/time conforming to the ISO8601 specification. startConstraint Expression Constraint Expression ConstraintDate/Time Expressionstart Date/Time Expressionstart start " msgstr "" #. Tag: para #, no-c-format msgid "end" msgstr "" #. Tag: para #, no-c-format msgid "A date/time conforming to the ISO8601 specification. Can be inferred by supplying a value for start and a duration. endConstraint Expression Constraint Expression ConstraintDate/Time Expressionend Date/Time Expressionend end " msgstr "" #. Tag: para #, no-c-format msgid "Compares the current date/time with the start and/or end date, depending on the context. Allowed values:" msgstr "Confronta la data/ora attuale con la data/ora indicata nei parametri start ed end, dipendentemente dal contesto. Valori permessi:" #. Tag: para #, fuzzy, no-c-format msgid "* gt - True if the current date/time is after start" msgstr "gt - Vera se la data/ora attuale è successiva al valore start" #. Tag: para #, fuzzy, no-c-format msgid "* lt - True if the current date/time is before end" msgstr "lt - Vera se la data/ora attuale è precedente al valore start" #. Tag: para #, fuzzy, no-c-format msgid "* in-range - True if the current date/time is after start and before end" msgstr "in-range - Vera se la data/ora attuale è successiva al valore start e precedente al valore end" #. Tag: para #, no-c-format msgid "* date-spec - performs a cron-like comparison to the current date/time operationConstraint Expression Constraint Expression ConstraintDate/Time Expressionoperation Date/Time Expressionoperation operation " msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "As these comparisons (except for date_spec) include the time, the eq, neq, gte and lte operators have not been implemented since they would only be valid for a single second." msgstr "Dato che la comparazione (ad eccezione di date_spec) include l'ora, gli operatori eq, neq, gte e lte non sono stati implementati." #. Tag: title #, no-c-format msgid "Date Specifications" msgstr "Dichiarare date" #. Tag: para #, no-c-format msgid " Date Specification ResourceConstraintDate Specification ConstraintDate Specification Date Specification " msgstr "" #. Tag: para #, no-c-format msgid "date_spec objects are used to create cron-like expressions relating to time. Each field can contain a single number or a single range. Instead of defaulting to zero, any field not supplied is ignored." msgstr "gli oggetti di tipo date_spec sono utilizzati per creare espressioni simili a quelle cron. Ogi campo contiene un singolo numero ed un singolo range Anziché impostare per default zero, ogni campo non difinito viene ignorato." #. Tag: para #, fuzzy, no-c-format msgid "For example, monthdays=\"1\" matches the first day of every month and hours=\"09-17\" matches the hours between 9am and 5pm (inclusive). However, at this time one cannot specify weekdays=\"1,2\" or weekdays=\"1-2,5-6\" since they contain multiple ranges. Depending on demand, this may be implemented in a future release." msgstr "Ad esempio, monthdays="1" identificherà il primo giorno di ogni mese e hours="09-17" identificherà le ore tra le 9:00 e le 17:00 incluse. Per via del fatto che sono specificati range multipli è impossibile specificare weekdays="1,2" o weekdays="1-2,5-6". A seconda della richiesta, questa funzionalità potrebbe essere implementata in futuro." #. Tag: title #, no-c-format msgid "Properties of a Date Spec" msgstr "Prorpietà di una specifica data" #. Tag: para #, no-c-format msgid "id" msgstr "" #. Tag: para #, no-c-format msgid "A unique name for the date idDate Specification Date Specification ConstraintDate Specificationid Date Specificationid id " msgstr "" #. Tag: para #, no-c-format msgid "hours" msgstr "" #. Tag: para #, no-c-format msgid "Allowed values: 0-23 hoursDate Specification Date Specification ConstraintDate Specificationhours Date Specificationhours hours " msgstr "" #. Tag: para #, no-c-format msgid "monthdays" msgstr "" #. Tag: para #, no-c-format msgid "Allowed values: 0-31 (depending on month and year) monthdaysDate Specification Date Specification ConstraintDate Specificationmonthdays Date Specificationmonthdays monthdays " msgstr "" #. Tag: para #, no-c-format msgid "weekdays" msgstr "" #. Tag: para #, no-c-format msgid "Allowed values: 1-7 (1=Monday, 7=Sunday) weekdaysDate Specification Date Specification ConstraintDate Specificationweekdays Date Specificationweekdays weekdays " msgstr "" #. Tag: para #, no-c-format msgid "yeardays" msgstr "" #. Tag: para #, no-c-format msgid "Allowed values: 1-366 (depending on the year) yeardaysDate Specification Date Specification ConstraintDate Specificationyeardays Date Specificationyeardays yeardays " msgstr "" #. Tag: para #, no-c-format msgid "months" msgstr "" #. Tag: para #, no-c-format msgid "Allowed values: 1-12 monthsDate Specification Date Specification ConstraintDate Specificationmonths Date Specificationmonths months " msgstr "" #. Tag: para #, no-c-format msgid "weeks" msgstr "" #. Tag: para #, no-c-format msgid "Allowed values: 1-53 (depending on weekyear) weeksDate Specification Date Specification ConstraintDate Specificationweeks Date Specificationweeks weeks " msgstr "" #. Tag: para #, no-c-format msgid "years" msgstr "" #. Tag: para #, no-c-format msgid "Year according the Gregorian calendar yearsDate Specification Date Specification ConstraintDate Specificationyears Date Specificationyears years " msgstr "" #. Tag: para #, no-c-format msgid "weekyears" msgstr "" #. Tag: para #, no-c-format msgid "May differ from Gregorian years; Eg. 2005-001 Ordinal is also 2005-01-01 Gregorian is also 2004-W53-6 Weekly weekyearsDate Specification Date Specification ConstraintDate Specificationweekyears Date Specificationweekyears weekyears " msgstr "" #. Tag: para #, no-c-format msgid "moon" msgstr "" #. Tag: para #, no-c-format msgid "Allowed values: 0-7 (0 is new, 4 is full moon). Seriously, you can use this. This was implemented to demonstrate the ease with which new comparisons could be added. moonDate Specification Date Specification ConstraintDate Specificationmoon Date Specificationmoon moon " msgstr "" #. Tag: title #, no-c-format msgid "Durations" msgstr "Durate" #. Tag: para #, no-c-format msgid " Duration ResourceConstraintDuration ConstraintDuration Duration " msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "Durations are used to calculate a value for end when one is not supplied to in_range operations. They contain the same fields as date_spec objects but without the limitations (ie. you can have a duration of 19 months). Like date_specs, any field not supplied is ignored." msgstr "Le durate vengono utilizzate per calcolare un valore finale nelle operazioni in_range quando non viene fornito. Essi contengono gli stessi campi degli oggetti date_spec ma senza le limitazioni (ad esempio è possibile avere durate da 19 giorni). Come per date_specs qualsiasi campo non fornito viene ignorato." #. Tag: title #, no-c-format msgid "Sample Time Based Expressions" msgstr "Espressioni temporali di esempio" #. Tag: para #, no-c-format msgid "A small sample of how time based expressions can be used." msgstr "" #. Tag: title #, no-c-format msgid "True if now is any time in the year 2005" msgstr "Vero se \"now\" è un qualsiasi momento nell'anno 2005" #. Tag: programlisting #, fuzzy, no-c-format msgid "" "<rule id=\"rule1\">\n" " <date_expression id=\"date_expr1\" start=\"2005-001\" operation=\"in_range\">\n" " <duration years=\"1\"/>\n" " </date_expression>\n" "</rule>" msgstr "" "\n" "\n" " <rule id="rule1">\n" " <date_expression id="date_expr1" start="2005-001" operation="in_range">\n" " <duration years="1"/>\n" " </date_expression>\n" " </rule>\n" "\n" "\t " #. Tag: title #, fuzzy, no-c-format msgid "Equivalent expression" msgstr "Espressione equivalente." #. Tag: programlisting #, fuzzy, no-c-format msgid "" "<rule id=\"rule2\">\n" " <date_expression id=\"date_expr2\" operation=\"date_spec\">\n" " <date_spec years=\"2005\"/>\n" " </date_expression>\n" "</rule>" msgstr "" "\n" "\n" " <rule id="rule2">\n" " <date_expression id="date_expr2" operation="date_spec">\n" " <date_spec years="2005"/>\n" " </date_expression>\n" " </rule>\n" "\n" "\t " #. Tag: title #, no-c-format msgid "9am-5pm, Mon-Friday" msgstr "9:00-17:00, lunedì-venerdì" #. Tag: programlisting #, fuzzy, no-c-format msgid "" "<rule id=\"rule3\">\n" " <date_expression id=\"date_expr3\" operation=\"date_spec\">\n" " <date_spec hours=\"9-16\" days=\"1-5\"/>\n" " </date_expression>\n" "</rule>" msgstr "" "\n" "\n" " <rule id="rule3">\n" " <date_expression id="date_expr3" operation="date_spec">\n" " <date_spec hours="9-16" days="1-5"/>\n" " </date_expression>\n" " </rule>\n" "\n" "\t " #. Tag: para #, no-c-format msgid "Please note that the 16 matches up to 16:59:59, as the numeric value (hour) still matches!" msgstr "" #. Tag: title #, no-c-format msgid "9am-6pm, Mon-Friday, or all day saturday" msgstr "9:00-18:00, lunedì-venerdì, o qualsiasi ora di sabato" #. Tag: programlisting #, fuzzy, no-c-format msgid "" "<rule id=\"rule4\" boolean_op=\"or\">\n" " <date_expression id=\"date_expr4-1\" operation=\"date_spec\">\n" " <date_spec hours=\"9-16\" days=\"1-5\"/>\n" " </date_expression>\n" " <date_expression id=\"date_expr4-2\" operation=\"date_spec\">\n" " <date_spec days=\"6\"/>\n" " </date_expression>\n" "</rule>" msgstr "" "\n" "\n" " <rule id="rule4" boolean_op="or">\n" " <date_expression id="date_expr4-1" operation="date_spec">\n" " <date_spec hours="9-16" days="1-5"/>\n" " </date_expression>\n" " <date_expression id="date_expr4-2" operation="date_spec">\n" " <date_spec days="6"/>\n" " </date_expression>\n" " </rule>\n" "\n" "\t " #. Tag: title #, no-c-format msgid "9am-5pm or 9pm-12pm, Mon-Friday" msgstr "9:00-17:00 o 21:00-24:00, lunedì-venerdì" #. Tag: programlisting #, fuzzy, no-c-format msgid "" "<rule id=\"rule5\" boolean_op=\"and\">\n" " <rule id=\"rule5-nested1\" boolean_op=\"or\">\n" " <date_expression id=\"date_expr5-1\" operation=\"date_spec\">\n" " <date_spec hours=\"9-16\"/>\n" " </date_expression>\n" " <date_expression id=\"date_expr5-2\" operation=\"date_spec\">\n" " <date_spec hours=\"21-23\"/>\n" " </date_expression>\n" " </rule>\n" " <date_expression id=\"date_expr5-3\" operation=\"date_spec\">\n" " <date_spec days=\"1-5\"/>\n" " </date_expression>\n" " </rule>" msgstr "" "\n" "\n" " <rule id="rule5" boolean_op="and">\n" " <rule id="rule5-nested1" boolean_op="or">\n" " <date_expression id="date_expr5-1" operation="date_spec">\n" " <date_spec hours="9-16"/>\n" " </date_expression>\n" " <date_expression id="date_expr5-2" operation="date_spec">\n" " <date_spec hours="21-23"/>\n" " </date_expression>\n" " </rule>\n" " <date_expression id="date_expr5-3" operation="date_spec">\n" " <date_spec days="1-5"/>\n" " </date_expression>\n" " </rule>\n" "\n" "\t " #. Tag: title #, no-c-format msgid "Mondays in March 2005" msgstr "Tutti i lunedì del mese di marzo 2005" #. Tag: programlisting #, fuzzy, no-c-format msgid "" "<rule id=\"rule6\" boolean_op=\"and\">\n" " <date_expression id=\"date_expr6-1\" operation=\"date_spec\">\n" " <date_spec weekdays=\"1\"/>\n" " </date_expression>\n" " <date_expression id=\"date_expr6-2\" operation=\"in_range\"\n" " start=\"2005-03-01\" end=\"2005-04-01\"/>\n" " </rule>" msgstr "" "\n" "\n" " <rule id="rule6" boolean_op="and">\n" " <date_expression id="date_expr6-1" operation="date_spec">\n" " <date_spec weekdays="1"/>\n" " </date_expression>\n" " <date_expression id="date_expr6-2" operation="in_range" start="2005-03-01" end="2005-04-01"/>\n" " </rule>\n" "\n" "\t " #. Tag: para #, fuzzy, no-c-format msgid "Because no time is specified, 00:00:00 is implied." msgstr "NOTA: visto che non è stato specificato un orario, 00:00:00 è implicito." #. Tag: para #, fuzzy, no-c-format msgid "This means that the range includes all of 2005-03-01 but none of 2005-04-01. You may wish to write end=\"2005-03-31T23:59:59\" to avoid confusion." msgstr "Questo significa che il range include tutto il 03/01/2005 ma nulla del 04/01/2005" #. Tag: title #, no-c-format msgid "A full moon on Friday the 13th" msgstr "In luna piena di venerdì 13" #. Tag: programlisting #, fuzzy, no-c-format msgid "" "<rule id=\"rule7\" boolean_op=\"and\">\n" " <date_expression id=\"date_expr7\" operation=\"date_spec\">\n" " <date_spec weekdays=\"5\" monthdays=\"13\" moon=\"4\"/>\n" " </date_expression>\n" "</rule>" msgstr "" "\n" "\n" " <rule id="rule7" boolean_op="and">\n" " <date_expression id="date_expr7" operation="date_spec">\n" " <date_spec weekdays="5" monthdays="13" moon="4"/>\n" " </date_expression>\n" " </rule>\n" "\n" "\t " #. Tag: title #, no-c-format msgid "Using Rules to Determine Resource Location" msgstr "Utilizzare regole per determinare il posizionamento delle risorse" #. Tag: para #, no-c-format msgid " RuleDetermine Resource Location Determine Resource Location ResourceLocationDetermine by Rules LocationDetermine by Rules Determine by Rules " msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "If the constraint’s outer-most rule evaluates to false, the cluster treats the constraint as if it was not there. When the rule evaluates to true, the node’s preference for running the resource is updated with the score associated with the rule." msgstr "Se il valore della regola constraint è falso il cluster tratta la constraint come non ci fosse.Quando la regola viene valorizzata a vero la preferenza per l'erogazione della risorsa da parte del nodo viene aggiornata con il valore associato alla regola." #. Tag: para #, no-c-format msgid "If this sounds familiar, its because you have been using a simplified syntax for location constraint rules already. Consider the following location constraint:" msgstr "Se questo suona familiare è perché sono state già utilizzate sintassi semplificate per le constraint di tipo location. Considerata la seguente location constraint:" #. Tag: title #, no-c-format msgid "Prevent myApacheRsc from running on c001n03" msgstr "Impedisci a myApacheRsc di essere eseguita su c001n03" #. Tag: programlisting #, fuzzy, no-c-format msgid "" "<rsc_location id=\"dont-run-apache-on-c001n03\" rsc=\"myApacheRsc\"\n" " score=\"-INFINITY\" node=\"c001n03\"/>" msgstr "" "\n" " <rsc_location id="dont-run-apache-on-c001n03" rsc="myApacheRsc" score="-INFINITY" node="c001n03"/>\n" "\t" #. Tag: para #, no-c-format msgid "This constraint can be more verbosely written as:" msgstr "Questa constraint potrebbe essere scritta più verbosamente come:" #. Tag: title #, no-c-format msgid "Prevent myApacheRsc from running on c001n03 - expanded version" msgstr "Impedisci a myApacheRsc di essere eseguita su c001n03 - versione estesa" #. Tag: programlisting #, fuzzy, no-c-format msgid "" "<rsc_location id=\"dont-run-apache-on-c001n03\" rsc=\"myApacheRsc\">\n" " <rule id=\"dont-run-apache-rule\" score=\"-INFINITY\">\n" " <expression id=\"dont-run-apache-expr\" attribute=\"#uname\"\n" " operation=\"eq\" value=\"c00n03\"/>\n" " </rule>\n" "</rsc_location>" msgstr "" "\n" "\n" " <rsc_location id="dont-run-apache-on-c001n03" rsc="myApacheRsc">\n" " <rule id="dont-run-apache-rule" score="-INFINITY">\n" " <expression id="dont-run-apache-expr" attribute="#uname" operation="eq" value="c00n03"/>\n" " </rule>\n" " </rsc_location>\n" "\n" "\t" #. Tag: para #, no-c-format msgid "The advantage of using the expanded form is that one can then add extra clauses to the rule, such as limiting the rule such that it only applies during certain times of the day or days of the week (this is discussed in subsequent sections)." msgstr "Il vantaggio di usare la versione estesa risiede nel fatto che è possibile aggiungere clausole extra nella regola, come limitarla affinché venga applicata solo in determinati orari del giorno o giorni sella settimana (il tema viene affrontato nelle sezioni sottostanti)." #. Tag: para #, fuzzy, no-c-format msgid "It also allows us to match on node properties other than its name. If we rated each machine’s CPU power such that the cluster had the following nodes section:" msgstr "Ciò permette di identificare proprietà del nodo diverse dal suo nome. Se per ogni macchina viene quantificata una potenza di CPU così che il cluster abbia la seguente sezione nodi:" #. Tag: title #, no-c-format msgid "A sample nodes section for use with score-attribute" msgstr "Una sezione nodi di esempio da utilizzare con score-attribute" #. Tag: programlisting #, fuzzy, no-c-format msgid "" "<nodes>\n" " <node id=\"uuid1\" uname=\"c001n01\" type=\"normal\">\n" " <instance_attributes id=\"uuid1-custom_attrs\">\n" " <nvpair id=\"uuid1-cpu_mips\" name=\"cpu_mips\" value=\"1234\"/>\n" " </instance_attributes>\n" " </node>\n" " <node id=\"uuid2\" uname=\"c001n02\" type=\"normal\">\n" " <instance_attributes id=\"uuid2-custom_attrs\">\n" " <nvpair id=\"uuid2-cpu_mips\" name=\"cpu_mips\" value=\"5678\"/>\n" " </instance_attributes>\n" " </node>\n" "</nodes>" msgstr "" "\n" "\n" " <nodes>\n" " <node id="uuid1" uname="c001n01" type="normal">\n" " <instance_attributes id="uuid1-custom_attrs">\n" " <nvpair id="uuid1-cpu_mips" name="cpu_mips" value="1234"/>\n" " </instance_attributes>\n" " </node>\n" " <node id="uuid2" uname="c001n02" type="normal">\n" " <instance_attributes id="uuid2-custom_attrs">\n" " <nvpair id="uuid2-cpu_mips" name="cpu_mips" value="5678"/>\n" " </instance_attributes>\n" " </node>\n" " </nodes>\n" "\n" "\t" #. Tag: para #, no-c-format msgid "then we could prevent resources from running on underpowered machines with the rule" msgstr "allora è possibile prevenire le risorse dall'essere eseguite in macchine meno potenti, mediante la regola" #. Tag: programlisting #, fuzzy, no-c-format msgid "" "<rule id=\"need-more-power-rule\" score=\"-INFINITY\">\n" " <expression id=\" need-more-power-expr\" attribute=\"cpu_mips\"\n" " operation=\"lt\" value=\"3000\"/>\n" "</rule>" msgstr "" "\n" "\n" " <rule id="need-more-power-rule" score="-INFINITY">\n" " <expression id=" need-more-power-expr" attribute="cpu_mips" operation="lt" value="3000"/>\n" " </rule>\n" "\n" " " #. Tag: title #, no-c-format msgid "Using score-attribute Instead of score" msgstr "Utilizzo di score-attribute invece di score" #. Tag: para #, fuzzy, no-c-format msgid "When using score-attribute instead of score, each node matched by the rule has its score adjusted differently, according to its value for the named node attribute. Thus, in the previous example, if a rule used score-attribute=\"cpu_mips\", c001n01 would have its preference to run the resource increased by 1234 whereas c001n02 would have its preference increased by 5678." msgstr "Quando viene utilizzato score-attribute anziché score, per ogni nodo identificato dalla regola viene calcolato il punteggio in maniera differente, in base al valore dell'attributo definito nel nodo. Quindi nell'esempio precedente, nella regola score-attribute="cpu_mips", la possibilità di erogare la risorsa per il nodo c001n01 verrà incrementata di 1234 mentre per il nodo c001n02 verrà incrementata di 5678." #. Tag: title #, no-c-format msgid "Using Rules to Control Resource Options" msgstr "Utilizzare regole per controllare le opzioni delle risorse" #. Tag: para #, fuzzy, no-c-format msgid "Often some cluster nodes will be different from their peers; sometimes these differences (the location of a binary or the names of network interfaces) require resources to be configured differently depending on the machine they’re hosted on." msgstr "Può capitare che alcuni nodi del cluster siano differenti fra loro, tali differenze (la posizione di alcuni file o i nomi delle interfacce di rete) a volte impongono configurazioni differenti, dipendenti dalla macchina su cui risiedono." #. Tag: para #, no-c-format msgid "By defining multiple instance_attributes objects for the resource and adding a rule to each, we can easily handle these special cases." msgstr "E' possibile gestire facilmente questi casi speciali definendo oggetti instance_attributes multipli per le risorse ed aggiungendo una regola per ognuno." #. Tag: para #, fuzzy, no-c-format msgid "In the example below, mySpecialRsc will use eth1 and port 9999 when run on node1, eth2 and port 8888 on node2 and default to eth0 and port 9999 for all other nodes." msgstr "Nell'esempio sottostante mySpecialRsc utilizzerà eth1 e la porta 9999 per funzionare su node1, mentre eth2 e la porta 8888 su node2. Per tutti gli altri nodi i valori di default saranno eth0 con porta 9999." #. Tag: title #, no-c-format msgid "Defining different resource options based on the node name" msgstr "Definire opzioni per le risorse differenti in base al nome del nodo" #. Tag: programlisting #, fuzzy, no-c-format msgid "" "<primitive id=\"mySpecialRsc\" class=\"ocf\" type=\"Special\" provider=\"me\">\n" " <instance_attributes id=\"special-node1\" score=\"3\">\n" " <rule id=\"node1-special-case\" score=\"INFINITY\" >\n" " <expression id=\"node1-special-case-expr\" attribute=\"#uname\"\n" " operation=\"eq\" value=\"node1\"/>\n" " </rule>\n" " <nvpair id=\"node1-interface\" name=\"interface\" value=\"eth1\"/>\n" " </instance_attributes>\n" " <instance_attributes id=\"special-node2\" score=\"2\" >\n" " <rule id=\"node2-special-case\" score=\"INFINITY\">\n" " <expression id=\"node2-special-case-expr\" attribute=\"#uname\"\n" " operation=\"eq\" value=\"node2\"/>\n" " </rule>\n" " <nvpair id=\"node2-interface\" name=\"interface\" value=\"eth2\"/>\n" " <nvpair id=\"node2-port\" name=\"port\" value=\"8888\"/>\n" " </instance_attributes>\n" " <instance_attributes id=\"defaults\" score=\"1\" >\n" " <nvpair id=\"default-interface\" name=\"interface\" value=\"eth0\"/>\n" " <nvpair id=\"default-port\" name=\"port\" value=\"9999\"/>\n" " </instance_attributes>\n" "</primitive>" msgstr "" "\n" "\n" " <primitive id="mySpecialRsc" class="ocf" type="Special" provider="me">\n" " <instance_attributes id="special-node1" score="3">\n" " <rule id="node1-special-case" score="INFINITY" >\n" " <expression id="node1-special-case-expr" attribute="#uname" operation="eq" value="node1"/>\n" " </rule>\n" " <nvpair id="node1-interface" name="interface" value="eth1"/>\n" " </instance_attributes>\n" " <instance_attributes id="special-node2" score="2" >\n" " <rule id="node2-special-case" score="INFINITY">\n" " <expression id="node2-special-case-expr" attribute="#uname" operation="eq" value="node2"/>\n" " </rule>\n" " <nvpair id="node2-interface" name="interface" value="eth2"/>\n" " <nvpair id="node2-port" name="port" value="8888"/>\n" " </instance_attributes>\n" " <instance_attributes id="defaults" score="1" >\n" " <nvpair id="default-interface" name="interface" value="eth0"/>\n" " <nvpair id="default-port" name="port" value="9999"/>\n" " </instance_attributes>\n" " </primitive>\n" "\n" "\t" #. Tag: para #, no-c-format msgid "The order in which instance_attributes objects are evaluated is determined by their score (highest to lowest). If not supplied, score defaults to zero and objects with an equal score are processed in listed order. If the instance_attributes object does not have a rule or has a rule that evaluates to true, then for any parameter the resource does not yet have a value for, the resource will use the parameter values defined by the instance_attributes object." msgstr "L'ordine in cui gli oggetti instance_attributes sono valutati è determinato dal loro peso (dal più alto al più basso). Se non è fornito il punteggio di default è zero e gli oggetti con lo stesso punteggio vengono processati nell'ordine della lista. Se l'oggetto instance_attributes non ha una rule o ha una rule che risulta in true, allora la risorsa non avrà ancora un valore per qualsiasi parametro ed utilizzerà quindi il valore fornito dall'oggetto instance_attributes." #. Tag: title #, no-c-format msgid "Using Rules to Control Cluster Options" msgstr "Utilizzare le regole per controllare le opzioni del cluster" #. Tag: para #, no-c-format msgid " RuleControlling Cluster Options Controlling Cluster Options ClusterSetting Options with Rules Setting Options with Rules " msgstr "" #. Tag: para #, no-c-format msgid "Controlling cluster options is achieved in much the same manner as specifying different resource options on different nodes." msgstr "E' possibile controllare le opzioni del cluster mediante le stesse modalità utilizzate per specificare opzioni differenti per le risorse in nodi differenti." #. Tag: para #, fuzzy, no-c-format msgid "The difference is that because they are cluster options, one cannot (or should not, because they won’t work) use attribute based expressions. The following example illustrates how to set a different resource-stickiness value during and outside of work hours. This allows resources to automatically move back to their most preferred hosts, but at a time that (in theory) does not interfere with business activities." msgstr "La differenza è che queste sono opzioni del cluster e non è possibile (o non dovrebbe esserlo, visto che non funzionerebbe) utilizzare espressioni basate sugli attributi. L'esempio seguente illustra come settare un valore differente di resource-stickiness in un periodo di tempo lontano dalle ore lavorative. Ciò permette alle risorse di tornare sugli host preferiti in orari che (in teoria) non interferiscono con le attività produttive." #. Tag: title #, no-c-format msgid "Change resource-stickiness during working hours" msgstr "" #. Tag: programlisting #, fuzzy, no-c-format msgid "" "<rsc_defaults>\n" " <meta_attributes id=\"core-hours\" score=\"2\">\n" " <rule id=\"core-hour-rule\" score=\"0\">\n" " <date_expression id=\"nine-to-five-Mon-to-Fri\" operation=\"date_spec\">\n" " <date_spec id=\"nine-to-five-Mon-to-Fri-spec\" hours=\"9-16\" weekdays=\"1-5\"/>\n" " </date_expression>\n" " </rule>\n" " <nvpair id=\"core-stickiness\" name=\"resource-stickiness\" value=\"INFINITY\"/>\n" " </meta_attributes>\n" " <meta_attributes id=\"after-hours\" score=\"1\" >\n" " <nvpair id=\"after-stickiness\" name=\"resource-stickiness\" value=\"0\"/>\n" " </meta_attributes>\n" "</rsc_defaults>" msgstr "" "\n" "\n" " <rsc_defaults>\n" " <meta_attributes id="core-hours" score="2">\n" " <rule id="core-hour-rule" score="0">\n" " <date_expression id="nine-to-five-Mon-to-Fri" operation="date_spec">\n" " <date_spec id="nine-to-five-Mon-to-Fri-spec" hours="9-17" weekdays="1-5"/>\n" " </date_expression>\n" " </rule>\n" " <nvpair id="core-stickiness" name="resource-stickiness" value="INFINITY"/>\n" " </meta_attributes>\n" " <meta_attributes id="after-hours" score="1" >\n" " <nvpair id="after-stickiness" name="resource-stickiness" value="0"/>\n" " </meta_attributes>\n" " </rsc_defaults>\n" "\n" "\t" #. Tag: title #, no-c-format msgid "Ensuring Time Based Rules Take Effect" msgstr "Assicurarsi che le regole basate sugli orari abbiano effetto" #. Tag: para #, fuzzy, no-c-format msgid "A Pacemaker cluster is an event driven system. As such, it won’t recalculate the best place for resources to run in unless something (like a resource failure or configuration change) happens. This can mean that a location constraint that only allows resource X to run between 9am and 5pm is not enforced." msgstr "Un cluster Pacemaker è un sistema guidato dagli eventi. Per via di questo, non ricalcolerà il posto migliore per una risorsa a meno che non succeda qualcosa (come un problema o una variazione nella configurazione). Questo può significare che una location constraint che permetta il funzionamento tra le 9:00 e le 17:00 della risorsa X possa non essere forzata." #. Tag: para #, fuzzy, no-c-format msgid "If you rely on time based rules, it is essential that you set the cluster-recheck-interval option. This tells the cluster to periodically recalculate the ideal state of the cluster. For example, if you set cluster-recheck-interval=5m, then sometime between 9:00 and 9:05 the cluster would notice that it needs to start resource X, and between 17:00 and 17:05 it would realize that X needed to be stopped." msgstr "Se ci si basa sulle regole orarie, è essenziale impostare l'opzione cluster-recheck-interval. Questo comunica al cluster di ricalcolare periodicamente il suo stato. Ad esempio, se viene impostato cluster-recheck-interval=5m, allora in qualche momento tra le 9:00 e le 9:05 il cluster rileverà la necessità di avviare la risorsa X e tra le 17:00 e le 17:05 rileverà di doverla fermare." #. Tag: para #, fuzzy, no-c-format msgid "Note that the timing of the actual start and stop actions depends on what else needs to be performed first ." msgstr "E' da notare come le tempistiche delle azioni di start e stop dipendono da quanto altro necessita di essere eseguito prima." #~ msgid "role" #~ msgstr "role" #~ msgid "Limits the rule to only apply when the resource is in that role. Allowed values: Started, Slave, Master. NOTE: A rule with role="Master" can not determine the initial location of a clone instance. It will only affect which of the active instances will be promoted." #~ msgstr "Limita l'applicazione della regola a quando la risorsa è nel role indicato. Valori permessi: Started, Slave, Master. NOTA: una regola con role="Master" non può determinare la posizione iniziale di un'istanza clone. Essa agirà unicamente su quale delle istanze attive verrà promossa." #~ msgid "score" #~ msgstr "score" #~ msgid "The score to apply if the rule evaluates to "true". Limited to use in rules that are part of location constraints." #~ msgstr "Il punteggio da applicare se la regola risulta "true". L'utilizzo è limitato nelle regole che sono parte di constraint di tipo location." #~ msgid "score-attribute" #~ msgstr "score-attribute" #~ msgid "The node attribute to look up and use as a score if the rule evaluates to "true". Limited to use in rules that are part of location constraints." #~ msgstr "L'attributo del nodo da controllare ed utilizzare come punteggio de la regola risulta "true". L'utilizzo è limitato nelle regole che sono parte di constraint tipo location." #~ msgid "boolean-op" #~ msgstr "boolean-op" #~ msgid "How to combine the result of multiple expression objects. Allowed values: and, or" #~ msgstr "Come combinare il risultato di oggetti con espressioni multiple. Valori permessi: and, or" #~ msgid "value" #~ msgstr "value" #~ msgid "User supplied value for comparison" #~ msgstr "Valore fornito dall'utente per la comparazione" #~ msgid "attribute" #~ msgstr "attribute" #~ msgid "The node attribute to test" #~ msgstr "L'attributo del nodo da controllare" #~ msgid "type" #~ msgstr "type" #~ msgid "Determines how the value(s) should be tested. Allowed values: integer, string, version" #~ msgstr "Determina come i valori devono essere testati. Valori permessi: integer, string, version" #~ msgid "operation" #~ msgstr "operation" #~ msgid "not_defined- True if the node does not have the named attribute" #~ msgstr "not_defined - Vera se il nodo non possiede l'attributo indicato" #~ msgid "start" #~ msgstr "start" #~ msgid "A date/time conforming to the ISO8601 specification." #~ msgstr "Una data/ora conforme alle specifiche ISO8601." #~ msgid "end" #~ msgstr "end" #~ msgid "A date/time conforming to the ISO8601 specification. Can be inferred by supplying a value for start and a duration." #~ msgstr "Una data/ora conforme alle specifiche ISO8601. Può essere dedotta fornendo un valore per start e duration." #~ msgid "date-spec - performs a cron-like comparison between the contents of date_spec and now" #~ msgstr "date-spec - effettua una comparazione simile a cron tra il contenuto di date_spec e la data/ora attuale." #~ msgid "id" #~ msgstr "id" #~ msgid "A unique name for the date" #~ msgstr "Un nome univoco per la data" #~ msgid "hours" #~ msgstr "hours" #~ msgid "Allowed values: 0-23" #~ msgstr "Valori permessi 0-23" #~ msgid "monthdays" #~ msgstr "monthdays" #~ msgid "Allowed values: 0-31 (depending on current month and year)" #~ msgstr "Valori permessi: 0-31 (dipendentemente dall'attuale mese ed anno)" #~ msgid "weekdays" #~ msgstr "weekdays" #~ msgid "Allowed values: 1-7 (1=Monday, 7=Sunday)" #~ msgstr "Valori permessi: 1-7 (1=lunedì, 7=domenica)" #~ msgid "yeardays" #~ msgstr "yesterdays" #~ msgid "Allowed values: 1-366 (depending on the current year)" #~ msgstr "Valori permessi: 1-366 (dipendente dall'anno attuale)" #~ msgid "months" #~ msgstr "months" #~ msgid "Allowed values: 1-12" #~ msgstr "Valori permessi: 1-12" #~ msgid "weeks" #~ msgstr "weeks" #~ msgid "Allowed values: 1-53 (depending on weekyear)" #~ msgstr "Valori permessi: 1-53 (dipendentemente dalla settimana dell'anno)" #~ msgid "years" #~ msgstr "years" #~ msgid "Year according the Gregorian calendar" #~ msgstr "Anno relativo nel calendario gregoriano" #~ msgid "weekyears" #~ msgstr "weekyears" #~ msgid "May differ from Gregorian years." #~ msgstr "Potrebbe differire dal calendario gregoriano." #~ msgid "Eg. "2005-001 Ordinal" is also "2005-01-01 Gregorian" is also "2004-W53-6 Weekly"" #~ msgstr "Ad esempio "2005-001 Ordinal" è anche "2005-01-01 Gregorian" è anche "2004-W53-6 Weekly"" #~ msgid "moon" #~ msgstr "moon" #~ msgid "Allowed values: 0..7 (0 is new, 4 is full moon). Seriously, you can use this. This was implemented to demonstrate the ease with which new comparisons could be added." #~ msgstr "Valori permessi: 0..7 (0 è luna nuova, 4 è luna piena). L'opzione è realmente utilizzabile. E' stata inclusa per dimostrare la facilità con cui è possibile aggiungere le nuove comparazioni." #~ msgid "You may wish to write end="2005-03-31T23:59:59" to avoid confusion." #~ msgstr "portrebbe essere necessario inserire end="2005-03-31T23:59:59" per non creare confusione." #~ msgid "Set resource-stickiness=INFINITY Mon-Fri between 9am and 6pm, and resource-stickiness=0 all other times" #~ msgstr "Imposta resource-stickiness=INFINITY dal lunedì al venerdì tra le 9:00 e le 18:00 e resource-stickiness=0 per tutti gli altri orari" pacemaker-master/doc/Pacemaker_Explained/it-IT/Ch-Status.po000066400000000000000000001232751217637305600240520ustar00rootroot00000000000000# # AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: 0\n" "POT-Creation-Date: 2012-10-17T05:19:02\n" "PO-Revision-Date: 2012-05-07 13:13+0100\n" "Last-Translator: RaSca \n" "Language-Team: None\n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. Tag: title #, no-c-format msgid "Status - Here be dragons" msgstr "Status - Here be dragons" #. Tag: para #, fuzzy, no-c-format msgid "Most users never need to understand the contents of the status section and can be happy with the output from crm_mon." msgstr "Molti utenti non hanno necessità di capire il contenuto della sezione status e possono ritenersi soddisfatti con l'output di crm_mon. Ad ogni modo, per quanti possiedono una vena curiosa, quanto segue rappresenta una panoramica sull'argomento." #. Tag: para #, no-c-format msgid "However for those with a curious inclination, this section attempts to provide an overview of its contents." msgstr "" #. Tag: title #, no-c-format msgid "Node Status" msgstr "Stato dei nodi" #. Tag: para #, no-c-format msgid " NodeStatus Status Status of a Node " msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "In addition to the cluster’s configuration, the CIB holds an up-to-date representation of each cluster node in the status section." msgstr "Inaggiunta alla configurazione del cluster, il CIB, all'interno della sezione status, contiene una rappresentazione aggiornata di ciascun nodo del cluster." #. Tag: title #, fuzzy, no-c-format msgid "A bare-bones status entry for a healthy node called cl-virt-1" msgstr "Una entry nuda e cruda dello stato del nodo chiamato cl-virt-1" #. Tag: programlisting #, fuzzy, no-c-format msgid "" " <node_state id=\"cl-virt-1\" uname=\"cl-virt-2\" ha=\"active\" in_ccm=\"true\" crmd=\"online\" join=\"member\" expected=\"member\" crm-debug-origin=\"do_update_resource\">\n" " <transient_attributes id=\"cl-virt-1\"/>\n" " <lrm id=\"cl-virt-1\"/>\n" " </node_state>" msgstr "" "\n" "\n" " <node_state id="cl-virt-1" uname="cl-virt-2" ha="active" in_ccm="true" crmd="online" join="member" expected="member" crm-debug-origin="do_update_resource">\n" " <transient_attributes id="cl-virt-1"/>\n" " <lrm id="cl-virt-1"/>\n" " </node_state>\n" "\n" "\t" #. Tag: para #, fuzzy, no-c-format msgid "Users are highly recommended not to modify any part of a node’s state directly. The cluster will periodically regenerate the entire section from authoritative sources. So any changes should be done with the tools for those subsystems." msgstr "E' vivamente consigliato non modificare le parti dello stato di un nodo direttamente. Il cluster periodicamente rigenera l'intera sezione da sorgenti autoritative. Quindi qualsiasi cambiamento dovrà essere effettuato mediante i sotto sistemi disponibili." #. Tag: title #, no-c-format msgid "Authoritative Sources for State Information" msgstr "Sorgenti autoritative per le informazioni di stato" #. Tag: entry #, no-c-format msgid "Dataset" msgstr "Dataset" #. Tag: entry #, no-c-format msgid "Authoritative Source" msgstr "Sorgente autoritativa" #. Tag: para #, fuzzy, no-c-format msgid "node_state fields" msgstr "campi node_state" #. Tag: para #, no-c-format msgid "crmd" msgstr "crmd" #. Tag: para #, fuzzy, no-c-format msgid "transient_attributes tag" msgstr "tag transient_attributes" #. Tag: para #, no-c-format msgid "attrd" msgstr "attrd" #. Tag: para #, no-c-format msgid "lrm tag" msgstr "" #. Tag: para #, no-c-format msgid "lrmd" msgstr "lrmd" #. Tag: para #, fuzzy, no-c-format msgid "The fields used in the node_state objects are named as they are largely for historical reasons and are rooted in Pacemaker’s origins as the Heartbeat resource manager." msgstr "I campi usati negli oggetti node_state sono nominati in questo modo per ragioni storiche ed affondano le proprie radici nelle origini di Pacemaker come resource manager di Heartbeat. Sono rimasti immutati per retro compatibilità." #. Tag: para #, no-c-format msgid "They have remained unchanged to preserve compatibility with older versions." msgstr "" #. Tag: title #, no-c-format msgid "Node Status Fields" msgstr "Campi relativi allo status dei nodi" #. Tag: entry #, no-c-format msgid "Field" msgstr "Campo" #. Tag: entry #, no-c-format msgid "Description" msgstr "Descrizione" #. Tag: para #, no-c-format msgid "id" msgstr "" #. Tag: para #, no-c-format msgid " idNode Status Node Status NodeStatusid Statusid id Unique identifier for the node. Corosync based clusters use the uname of the machine, Heartbeat clusters use a human-readable (but annoying) UUID." msgstr "" #. Tag: para #, no-c-format msgid "uname" msgstr "" #. Tag: para #, no-c-format msgid " unameNode Status Node Status NodeStatusuname Statusuname uname The node’s machine name (output from uname -n)." msgstr "" #. Tag: para #, no-c-format msgid "ha" msgstr "" #. Tag: para #, no-c-format msgid " haNode Status Node Status NodeStatusha Statusha ha Flag specifying whether the cluster software is active on the node. Allowed values: active, dead." msgstr "" #. Tag: para #, no-c-format msgid "in_ccm" msgstr "" #. Tag: para #, no-c-format msgid " in_ccmNode Status Node Status NodeStatusin_ccm Statusin_ccm in_ccm Flag for cluster membership; allowed values: true, false." msgstr "" #. Tag: para #, no-c-format msgid "crmd" msgstr "" #. Tag: para #, no-c-format msgid " crmdNode Status Node Status NodeStatuscrmd Statuscrmd crmd Flag: is the crmd process active on the node? One of online, offline." msgstr "" #. Tag: para #, no-c-format msgid "join" msgstr "" #. Tag: para #, no-c-format msgid " joinNode Status Node Status NodeStatusjoin Statusjoin join Flag saying whether the node participates in hosting resources. Possible values: down, pending, member, banned." msgstr "" #. Tag: para #, no-c-format msgid "expected" msgstr "" #. Tag: para #, no-c-format msgid " expectedNode Status Node Status NodeStatusexpected Statusexpected expected Expected value for join." msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "crm-debug-origin" msgstr "crm-debug-origin" #. Tag: para #, no-c-format msgid " crm-debug-originNode Status Node Status NodeStatuscrm-debug-origin Statuscrm-debug-origin crm-debug-origin Diagnostic indicator: the origin of the most recent change(s)." msgstr "" #. Tag: para #, no-c-format msgid "The cluster uses these fields to determine if, at the node level, the node is healthy or is in a failed state and needs to be fenced." msgstr "Il cluster utilizza questi campi per determinare se, a livello di nodo, il nodo è sano o in uno stato fallito e necessita di essere ucciso (fenced)." #. Tag: title #, no-c-format msgid "Transient Node Attributes" msgstr "Attributi dei nodi transitori" #. Tag: para #, fuzzy, no-c-format msgid "Like regular node attributes, the name/value pairs listed here also help to describe the node. However they are forgotten by the cluster when the node goes offline. This can be useful, for instance, when you want a node to be in standby mode (not able to run resources) until the next reboot." msgstr "Come gli attributi del nodo regolari, la coppia nome/valore listata qui aiuta a descrivere il nodo. Ad ogni modo tali valori vengono dimenticati dal cluster quando il nodo va offline. Questo può essere utile, ad esempio, quando si vuole che un nodo rimanga in standby mode (quindi inabile ad erogare risorse) fino al successivo reboot." #. Tag: para #, no-c-format msgid "In addition to any values the administrator sets, the cluster will also store information about failed resources here." msgstr "In aggiunta a qualsiasi valore impostato dall'amministratore, il cluster registrerà informazioni a proposito di azioni fallite." #. Tag: title #, fuzzy, no-c-format msgid "Example set of transient node attributes for node \"cl-virt-1\"" msgstr "Esempio di set di attributi dei nodi transitori per il nodo "cl-virt-1"" #. Tag: programlisting #, fuzzy, no-c-format msgid "" " <transient_attributes id=\"cl-virt-1\">\n" " <instance_attributes id=\"status-cl-virt-1\">\n" " <nvpair id=\"status-cl-virt-1-pingd\" name=\"pingd\" value=\"3\"/>\n" " <nvpair id=\"status-cl-virt-1-probe_complete\" name=\"probe_complete\" value=\"true\"/>\n" " <nvpair id=\"status-cl-virt-1-fail-count-pingd:0\" name=\"fail-count-pingd:0\" value=\"1\"/>\n" " <nvpair id=\"status-cl-virt-1-last-failure-pingd:0\" name=\"last-failure-pingd:0\" value=\"1239009742\"/>\n" " </instance_attributes>\n" " </transient_attributes>" msgstr "" "\n" "\n" " <transient_attributes id="cl-virt-1">\n" " <instance_attributes id="status-cl-virt-1">\n" " <nvpair id="status-cl-virt-1-pingd" name="pingd" value="3"/>\n" " <nvpair id="status-cl-virt-1-probe_complete" name="probe_complete" value="true"/>\n" " <nvpair id="status-cl-virt-1-fail-count-pingd:0" name="fail-count-pingd:0" value="1"/>\n" " <nvpair id="status-cl-virt-1-last-failure-pingd:0" name="last-failure-pingd:0" value="1239009742"/>\n" " </instance_attributes>\n" " </transient_attributes>\n" "\n" "\t" #. Tag: para #, fuzzy, no-c-format msgid "In the above example, we can see that the pingd:0 resource has failed once, at Mon Apr 6 11:22:22 2009. You can use the standard date command to print a human readable of any seconds-since-epoch value: # date -d @<parameter>number</parameter> We also see that the node is connected to three \"pingd\" peers and that all known resources have been checked for on this machine (probe_complete)." msgstr "Nell'esempio sopra, si può osservare che la risorsa pingd:0 è fallita una volta in data Mon Apr 6 11:22:22 2009. E' possibile utilizzare questo script perl per rendere comprensibie il valore data:perl -e 'print scalar(localtime($seconds))."\\n"' E' possibie inoltre osservare come il nodo sia connesso a tre punti "pingd" a come tutte le risorse conosciute siano state controllate da questa macchina (probe_complete)." #. Tag: title #, no-c-format msgid "Operation History" msgstr "Storico delle operazioni" #. Tag: para #, no-c-format msgid " Operation History " msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "A node’s resource history is held in the lrm_resources tag (a child of the lrm tag). The information stored here includes enough information for the cluster to stop the resource safely if it is removed from the configuration section. Specifically the resource’s id, class, type and provider are stored." msgstr "Lo storico di una risorsa relativo al nodo è contenuto nel tag (che è un tag figlio del tag lrm) lrm_resources. Le informazioni registrate qui includono sufficienti dati per il cluster affinché stoppi la risorsa in sicureza se questa viene rimossa dalla sezione configuration. Specificamente vengono registrati per la risorsa i valori id, class, type e provider." #. Tag: title #, no-c-format msgid "A record of the apcstonith resource" msgstr "Un record della risorsa apcstonith" #. Tag: programlisting #, fuzzy, no-c-format msgid "<lrm_resource id=\"apcstonith\" type=\"apcmastersnmp\" class=\"stonith\"/>" msgstr "" "\n" " <lrm_resource id="apcstonith" type="apcmastersnmp" class="stonith">\n" "\t" #. Tag: para #, no-c-format msgid "Additionally, we store the last job for every combination of resource, action and interval. The concatenation of the values in this tuple are used to create the id of the lrm_rsc_op object." msgstr "In aggiunta, viene registrato l'ultimo job per ciascuna combinazione di resource, action e interval. La concatenazione di valori in questa tupla viene usata per creare l'id dell'oggetto lrm_rsc_op." #. Tag: title #, fuzzy, no-c-format msgid "Contents of an lrm_rsc_op job" msgstr "Contenuti di un job lrm_rsc_op." #. Tag: para #, no-c-format msgid " idAction Status Action Status ActionStatusid Statusid id " msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "Identifier for the job constructed from the resource’s id, operation and interval." msgstr "Identificatore per il job costruito partendo dai valori della risorsa relativi a id, operation ed interval." #. Tag: para #, no-c-format msgid "call-id" msgstr "" #. Tag: para #, no-c-format msgid " call-idAction Status Action Status ActionStatuscall-id Statuscall-id call-id " msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "The job’s ticket number. Used as a sort key to determine the order in which the jobs were executed." msgstr "Il numero di ticket del job. Utilizzato come una sorta di chiave per determirnare l'ordine in cui i job sono stati eseguiti." #. Tag: para #, no-c-format msgid "operation" msgstr "" #. Tag: para #, no-c-format msgid " operationAction Status Action Status ActionStatusoperation Statusoperation operation " msgstr "" #. Tag: para #, no-c-format msgid "The action the resource agent was invoked with." msgstr "L'azione con cui il resource agent è stato invocato." #. Tag: para #, no-c-format msgid "interval" msgstr "" #. Tag: para #, no-c-format msgid " intervalAction Status Action Status ActionStatusinterval Statusinterval interval " msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "The frequency, in milliseconds, at which the operation will be repeated. A one-off job is indicated by 0." msgstr "La frequenza, in millisecondi, in cui l'operazione verrà ripetuta. 0 indica un job una tantum." #. Tag: para #, no-c-format msgid "op-status" msgstr "" #. Tag: para #, no-c-format msgid " op-statusAction Status Action Status ActionStatusop-status Statusop-status op-status " msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "The job’s status. Generally this will be either 0 (done) or -1 (pending). Rarely used in favor of rc-code." msgstr "Lo status del job. Generalmente questo sarà 0 (done) o -1 (pending). Raramente usato al posto di rc-code." #. Tag: para #, no-c-format msgid "rc-code" msgstr "" #. Tag: para #, no-c-format msgid " rc-codeAction Status Action Status ActionStatusrc-code Statusrc-code rc-code " msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "The job’s result. Refer to for details on what the values here mean and how they are interpreted." msgstr "Il risultato del job. Riferirsi a per dettagli su cosa significano questi valori e come vengono interpretati." #. Tag: para #, no-c-format msgid "last-run" msgstr "" #. Tag: para #, no-c-format msgid " last-runAction Status Action Status ActionStatuslast-run Statuslast-run last-run " msgstr "" #. Tag: para #, no-c-format msgid "Diagnostic indicator. Machine local date/time, in seconds since epoch, at which the job was executed." msgstr "Indicatore diagnostico. Data/ora locale della macchina in cui il job è stato eseguito, in secondi da epoch (00:00:00 UTC on 1 January 1970)." #. Tag: para #, no-c-format msgid "last-rc-change" msgstr "" #. Tag: para #, no-c-format msgid " last-rc-changeAction Status Action Status ActionStatuslast-rc-change Statuslast-rc-change last-rc-change " msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "Diagnostic indicator. Machine local date/time, in seconds since epoch, at which the job first returned the current value of rc-code." msgstr "Indicatore diagnostico. Data/ora locale della macchina in cui il job ha restituito la prima volta il valore di rc-code, in secondi da epoch (00:00:00 UTC on 1 January 1970)." #. Tag: para #, no-c-format msgid "exec-time" msgstr "" #. Tag: para #, no-c-format msgid " exec-timeAction Status Action Status ActionStatusexec-time Statusexec-time exec-time " msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "Diagnostic indicator. Time, in milliseconds, that the job was running for." msgstr "Indicatore diagnostico. Da quando il job è attivo, in millisecondi." #. Tag: para #, no-c-format msgid "queue-time" msgstr "" #. Tag: para #, no-c-format msgid " queue-timeAction Status Action Status ActionStatusqueue-time Statusqueue-time queue-time " msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "Diagnostic indicator. Time, in seconds, that the job was queued for in the LRMd." msgstr "Indicatore diagnostico. Tempo in cui il job è stato accodato all'interno di LRMd, in secondi." #. Tag: para #, fuzzy, no-c-format msgid "crm_feature_set" msgstr "crm_feature_set" #. Tag: para #, no-c-format msgid " crm_feature_setAction Status Action Status ActionStatuscrm_feature_set Statuscrm_feature_set crm_feature_set " msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "The version which this job description conforms to. Used when processing op-digest." msgstr "La versione a cui questa descrizione del job è conforme. Utilizzato quando si processa op-digest" #. Tag: para #, no-c-format msgid "transition-key" msgstr "" #. Tag: para #, no-c-format msgid " transition-keyAction Status Action Status ActionStatustransition-key Statustransition-key transition-key " msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "A concatenation of the job’s graph action number, the graph number, the expected result and the UUID of the crmd instance that scheduled it. This is used to construct transition-magic (below)." msgstr "Una concatenazione del numero azione grafica del job, del numero grafico, del risultato atteso e dell'UUID dell'istanza crmd che l'ha schedulato. Viene usato per costruire la transition-magic (sotto)." #. Tag: para #, fuzzy, no-c-format msgid "transition-magic" msgstr "transition-magic" #. Tag: para #, no-c-format msgid " transition-magicAction Status Action Status ActionStatustransition-magic Statustransition-magic transition-magic " msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "A concatenation of the job’s op-status, rc-code and transition-key. Guaranteed to be unique for the life of the cluster (which ensures it is part of CIB update notifications) and contains all the information needed for the crmd to correctly analyze and process the completed job. Most importantly, the decomposed elements tell the crmd if the job entry was expected and whether it failed." msgstr "Una concatenazione del valore di op-status del job, di rc-code e del valore transition-key. L'unicità è garantita per l'intera vita del cluster (ciò assicura che sarà parte delle notifiche di update del CIB) e contiene tutte le informazioni necessarie a crmd per la corretta analisi ed elaborazione del lavoro completato. Più importante, gli elementi decomposti comunicano al crmd se le entry dei job erano attese e se non sono riuscite." #. Tag: para #, no-c-format msgid "op-digest" msgstr "" #. Tag: para #, no-c-format msgid " op-digestAction Status Action Status ActionStatusop-digest Statusop-digest op-digest " msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "An MD5 sum representing the parameters passed to the job. Used to detect changes to the configuration, to restart resources if necessary." msgstr "Un MD5 sum che rappresenta i parametri passati al job. Utilizzato per rilevare cambiamenti alla configurazione ed effettuare restart se necessario." #. Tag: para #, no-c-format msgid " crm-debug-originAction Status Action Status ActionStatuscrm-debug-origin Statuscrm-debug-origin crm-debug-origin " msgstr "" #. Tag: para #, no-c-format msgid "Diagnostic indicator. The origin of the current values." msgstr "Indicatore diagnostico. L'originie degli attuali valori." #. Tag: title #, no-c-format msgid "Simple Example" msgstr "Un semplice esempio" #. Tag: title #, fuzzy, no-c-format msgid "A monitor operation (determines current state of the apcstonith resource)" msgstr "Un'operazione di monitor eseguita dal cluster per determinare lo stato attuale della risorsa apcstonith" #. Tag: programlisting #, fuzzy, no-c-format msgid "" "<lrm_resource id=\"apcstonith\" type=\"apcmastersnmp\" class=\"stonith\">\n" " <lrm_rsc_op id=\"apcstonith_monitor_0\" operation=\"monitor\" call-id=\"2\"\n" " rc-code=\"7\" op-status=\"0\" interval=\"0\"\n" " crm-debug-origin=\"do_update_resource\" crm_feature_set=\"3.0.1\"\n" " op-digest=\"2e3da9274d3550dc6526fb24bfcbcba0\"\n" " transition-key=\"22:2:7:2668bbeb-06d5-40f9-936d-24cb7f87006a\"\n" " transition-magic=\"0:7;22:2:7:2668bbeb-06d5-40f9-936d-24cb7f87006a\"\n" " last-run=\"1239008085\" last-rc-change=\"1239008085\" exec-time=\"10\" queue-time=\"0\"/>\n" "</lrm_resource>" msgstr "" "\n" "\n" " <lrm_resource id="apcstonith" type="apcmastersnmp" class="stonith"> \n" " <lrm_rsc_op id="apcstonith_monitor_0" operation="monitor" call-id="2" rc-code="7" op-status="0" interval="0" \n" "\t\tcrm-debug-origin="do_update_resource" crm_feature_set="3.0.1" \n" "\t\top-digest="2e3da9274d3550dc6526fb24bfcbcba0"\n" "\t\ttransition-key="22:2:7:2668bbeb-06d5-40f9-936d-24cb7f87006a"\n" "\t\ttransition-magic="0:7;22:2:7:2668bbeb-06d5-40f9-936d-24cb7f87006a" \n" "\t\tlast-run="1239008085" last-rc-change="1239008085" exec-time="10" queue-time="0"/>\n" " </lrm_resource>\n" "\n" "\t " #. Tag: para #, no-c-format msgid "In the above example, the job is a non-recurring monitor operation often referred to as a \"probe\" for the apcstonith resource." msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "The cluster schedules probes for every configured resource on when a new node starts, in order to determine the resource’s current state before it takes any further action." msgstr "Nell'esempio sopra il job è un monitor non ricorrente spesso denominato "probe" per la risorsa apcstonith. Il cluster schedula delle interrogazioni per ogni risorsa configurata ogni volta che un nodo si avvia, in modo da determinare lo stato attuale della risora prima che questa compia qualsiasi altra azione." #. Tag: para #, fuzzy, no-c-format msgid "From the transition-key, we can see that this was the 22nd action of the 2nd graph produced by this instance of the crmd (2668bbeb-06d5-40f9-936d-24cb7f87006a)." msgstr "Mediante transition-key è possibile osservare che questa era la ventiduesima azione del secondo grafo prodotto da questa istanza di crmd (2668bbeb-06d5-40f9-936d-24cb7f87006a). Il terzo coampo di transition-key contiene un 7 che indica come il job si aspetti di trovare la risorsa inattiva. Osservando alla proprietà di rc-code, si può concludere che è questo il caso." #. Tag: para #, no-c-format msgid "The third field of the transition-key contains a 7, this indicates that the job expects to find the resource inactive." msgstr "" #. Tag: para #, no-c-format msgid "By looking at the rc-code property, we see that this was the case." msgstr "" #. Tag: para #, no-c-format msgid "As that is the only job recorded for this node we can conclude that the cluster started the resource elsewhere." msgstr "" #. Tag: title #, no-c-format msgid "Complex Resource History Example" msgstr "Un complesso esempio di storico per risorsa" #. Tag: title #, no-c-format msgid "Resource history of a pingd clone with multiple jobs" msgstr "Storico di una risorsa clone pingd con job multipli" #. Tag: programlisting #, fuzzy, no-c-format msgid "" "<lrm_resource id=\"pingd:0\" type=\"pingd\" class=\"ocf\" provider=\"pacemaker\">\n" " <lrm_rsc_op id=\"pingd:0_monitor_30000\" operation=\"monitor\" call-id=\"34\"\n" " rc-code=\"0\" op-status=\"0\" interval=\"30000\"\n" " crm-debug-origin=\"do_update_resource\" crm_feature_set=\"3.0.1\"\n" " transition-key=\"10:11:0:2668bbeb-06d5-40f9-936d-24cb7f87006a\"\n" " ...\n" " last-run=\"1239009741\" last-rc-change=\"1239009741\" exec-time=\"10\" queue-time=\"0\"/>\n" " <lrm_rsc_op id=\"pingd:0_stop_0\" operation=\"stop\"\n" " crm-debug-origin=\"do_update_resource\" crm_feature_set=\"3.0.1\" call-id=\"32\"\n" " rc-code=\"0\" op-status=\"0\" interval=\"0\"\n" " transition-key=\"11:11:0:2668bbeb-06d5-40f9-936d-24cb7f87006a\"\n" " ...\n" " last-run=\"1239009741\" last-rc-change=\"1239009741\" exec-time=\"10\" queue-time=\"0\"/>\n" " <lrm_rsc_op id=\"pingd:0_start_0\" operation=\"start\" call-id=\"33\"\n" " rc-code=\"0\" op-status=\"0\" interval=\"0\"\n" " crm-debug-origin=\"do_update_resource\" crm_feature_set=\"3.0.1\"\n" " transition-key=\"31:11:0:2668bbeb-06d5-40f9-936d-24cb7f87006a\"\n" " ...\n" " last-run=\"1239009741\" last-rc-change=\"1239009741\" exec-time=\"10\" queue-time=\"0\" />\n" " <lrm_rsc_op id=\"pingd:0_monitor_0\" operation=\"monitor\" call-id=\"3\"\n" " rc-code=\"0\" op-status=\"0\" interval=\"0\"\n" " crm-debug-origin=\"do_update_resource\" crm_feature_set=\"3.0.1\"\n" " transition-key=\"23:2:7:2668bbeb-06d5-40f9-936d-24cb7f87006a\"\n" " ...\n" " last-run=\"1239008085\" last-rc-change=\"1239008085\" exec-time=\"20\" queue-time=\"0\"/>\n" " </lrm_resource>" msgstr "" "\n" "\n" " <lrm_resource id="pingd:0" type="pingd" class="ocf" provider="pacemaker">\n" " <lrm_rsc_op id="pingd:0_monitor_30000" operation="monitor" call-id="34" rc-code="0" op-status="0" interval="30000" \n" "\t\tcrm-debug-origin="do_update_resource" crm_feature_set="3.0.1" \n" "\t\top-digest="a0f8398dac7ced82320fe99fd20fbd2f"\n" "\t\ttransition-key="10:11:0:2668bbeb-06d5-40f9-936d-24cb7f87006a" \n" "\t\ttransition-magic="0:0;10:11:0:2668bbeb-06d5-40f9-936d-24cb7f87006a" \n" "\t\tlast-run="1239009741" last-rc-change="1239009741" exec-time="10" queue-time="0"/>\n" " <lrm_rsc_op id="pingd:0_stop_0" operation="stop" \n" "\t\tcrm-debug-origin="do_update_resource" crm_feature_set="3.0.1" call-id="32" rc-code="0" op-status="0" interval="0" \n" "\t\top-digest="313aee7c6aad26e290b9084427bbab60"\n" "\t\ttransition-key="11:11:0:2668bbeb-06d5-40f9-936d-24cb7f87006a" \n" "\t\ttransition-magic="0:0;11:11:0:2668bbeb-06d5-40f9-936d-24cb7f87006a" \n" "\t\tlast-run="1239009741" last-rc-change="1239009741" exec-time="10" queue-time="0"/>\n" " <lrm_rsc_op id="pingd:0_start_0" operation="start" call-id="33" rc-code="0" op-status="0" interval="0" \n" "\t\tcrm-debug-origin="do_update_resource" crm_feature_set="3.0.1" \n" "\t\top-digest="313aee7c6aad26e290b9084427bbab60"\n" "\t\ttransition-key="31:11:0:2668bbeb-06d5-40f9-936d-24cb7f87006a" \n" "\t\ttransition-magic="0:0;31:11:0:2668bbeb-06d5-40f9-936d-24cb7f87006a" \n" "\t\tlast-run="1239009741" last-rc-change="1239009741" exec-time="10" queue-time="0" />\n" " <lrm_rsc_op id="pingd:0_monitor_0" operation="monitor" call-id="3" rc-code="0" op-status="0" interval="0" \n" "\t\tcrm-debug-origin="do_update_resource" crm_feature_set="3.0.1" \n" "\t\top-digest="313aee7c6aad26e290b9084427bbab60"\n" "\t\ttransition-key="23:2:7:2668bbeb-06d5-40f9-936d-24cb7f87006a" \n" "\t\ttransition-magic="0:0;23:2:7:2668bbeb-06d5-40f9-936d-24cb7f87006a" \n" "\t\tlast-run="1239008085" last-rc-change="1239008085" exec-time="20" queue-time="0"/>\n" " </lrm_resource>\n" "\n" "\t " #. Tag: para #, fuzzy, no-c-format msgid "When more than one job record exists, it is important to first sort them by call-id before interpreting them." msgstr "Quando esiste più di una registrazione per il job da interpretare, è importante l'ordinamento mediante call-id. Una volta ordinato, l'esempio sopra può essere riassunto come:" #. Tag: para #, no-c-format msgid "Once sorted, the above example can be summarized as:" msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "A non-recurring monitor operation returning 7 (not running), with a call-id of 3" msgstr "Un'operazione di monitor non ricorrente che restituisce 7 (not running), con un valore call-id di 3" #. Tag: para #, fuzzy, no-c-format msgid "A stop operation returning 0 (success), with a call-id of 32" msgstr "Un'operazione di stop che restituisce 0 (successo), con un call-id del valore di 32" #. Tag: para #, fuzzy, no-c-format msgid "A start operation returning 0 (success), with a call-id of 33" msgstr "Un'operazione di start che restituisce 0 (successo), con un call-id del valore di 33" #. Tag: para #, fuzzy, no-c-format msgid "A recurring monitor returning 0 (success), with a call-id of 34" msgstr "Un'operazione di monitor ricorrente che restituisce 0 (successo), con un call-id del valore di 34" #. Tag: para #, fuzzy, no-c-format msgid "The cluster processes each job record to build up a picture of the resource’s state. After the first and second entries, it is considered stopped and after the third it considered active." msgstr "Il cluster processa ogni registrazione di job per costruire un disegno dello stato delle risorse. Dopo la prima e la seconda entry, è considerato stoppato e dopo la terza è considerato attivo. In base all'ultima operazione è possibile concludere che la risorsa è attualmente attiva." #. Tag: para #, no-c-format msgid "Based on the last operation, we can tell that the resource is currently active." msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "Additionally, from the presence of a stop operation with a lower call-id than that of the start operation, we can conclude that the resource has been restarted. Specifically this occurred as part of actions 11 and 31 of transition 11 from the crmd instance with the key 2668bbeb…. This information can be helpful for locating the relevant section of the logs when looking for the source of a failure." msgstr "In aggiunta, dalla presenza di un'operazione di tipo stop con un numero minore di call-id rispetto al valore per l'operazione di start, è possibile concludere che la risorsa è stata avviata. Specificamente ciò è avvenuto come parte delle azioni 11 e 31 della transazione 11 dall'istanza crmd con chiave 2668bbeb-06d5-40f9-936d-24cb7f87006a. Questa informazione può essere utile per localizzare la sezione del log rilevavnte se si è alla ricerca del motivo di un'anomalia." #~ msgid "lrm tag" #~ msgstr "tag lrm" #~ msgid "id" #~ msgstr "id" #~ msgid "Unique identifier for the node. Corosync based clusters use the same value as uname, Heartbeat cluster use a human-readable (but annoying) UUID." #~ msgstr "Identificatore univoco per il nodo. I cluster basati su Corosync utilizzano lo stesso valore di numae, mentre quelli Heartbeat sono UUID leggibili (ma tediosi)." #~ msgid "uname" #~ msgstr "uname" #~ msgid "The node's machine name (output from uname -n)" #~ msgstr "Il nome macchina del nodo (dall'output di uname -n)" #~ msgid "ha" #~ msgstr "ha" #~ msgid "Is the cluster software active on the node. Allowed values: active, dead" #~ msgstr "Il cluster software attivo nel nodo. Valori permessi: active, dead" #~ msgid "in_ccm" #~ msgstr "in_ccm" #~ msgid "Is the node part of the cluster's membership. Allowed values: true, false" #~ msgstr "E' la parte del nodo relativa ai membri del cluster. Valori permessi: true, false" #~ msgid "Is the crmd process active on the node. Allowed values: online, offline" #~ msgstr "E' lo stato del processo crmd nel nodo. Valori permesse: online, offline" #~ msgid "join" #~ msgstr "join" #~ msgid "Is the node participating in hosting resources. Allowed values: down, pending, member, banned" #~ msgstr "Determina se il nodo sta partecipando all'erogazione delle risorse. Valori permessi: down, pending, member, banned" #~ msgid "expected" #~ msgstr "expected" #~ msgid "Expected value for join" #~ msgstr "Valore atteso per join" #~ msgid "Diagnostic indicator. The origin of the most recent change(s)." #~ msgstr "Indicatore diagnostico. L'origine del cambiamento o dei cambiamenti più recenti." #~ msgid "call-id" #~ msgstr "call-id" #~ msgid "operation" #~ msgstr "operation" #~ msgid "interval" #~ msgstr "interval" #~ msgid "op-status" #~ msgstr "op-status" #~ msgid "rc-code" #~ msgstr "rc-code" #~ msgid "last-run" #~ msgstr "last-run" #~ msgid "last-rc-change" #~ msgstr "last-rc-change" #~ msgid "exec-time" #~ msgstr "exec-time" #~ msgid "queue-time" #~ msgstr "queue-time" #~ msgid "transition-key" #~ msgstr "transition-key" #~ msgid "op-digest" #~ msgstr "op-digest" #~ msgid "Evidently, the cluster started the resource elsewhere as that is the only job recorded for this node." #~ msgstr "Evidentemente, il cluster ha avviato la risorsa altrove visto che quello è l'unico job registrato per questo nodo." pacemaker-master/doc/Pacemaker_Explained/it-IT/Ch-Stonith.po000066400000000000000000000562501217637305600242150ustar00rootroot00000000000000# # AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: 0\n" "POT-Creation-Date: 2012-10-17T05:19:02\n" "PO-Revision-Date: 2012-05-07 11:42+0100\n" "Last-Translator: RaSca \n" "Language-Team: None\n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. Tag: title #, fuzzy, no-c-format msgid "Configure STONITH" msgstr "Configurare STONITH" #. Tag: para #, no-c-format msgid " STONITHConfiguration Configuration " msgstr "" #. Tag: title #, fuzzy, no-c-format msgid "What Is STONITH" msgstr "Perché c'è bisogno di STONITH" #. Tag: para #, fuzzy, no-c-format msgid "STONITH is an acronym for Shoot-The-Other-Node-In-The-Head and it protects your data from being corrupted by rogue nodes or concurrent access." msgstr "STONITH è l'acronimo di Shoot-The-Other-Node-In-The-Head (Spara in testa all'altro nodo) e protegge i propri dati dall'essere corrotti mediante nodi ribelli od accessi concorrenti." #. Tag: para #, fuzzy, no-c-format msgid "Just because a node is unresponsive, this doesn’t mean it isn’t accessing your data. The only way to be 100% sure that your data is safe, is to use STONITH so we can be certain that the node is truly offline, before allowing the data to be accessed from another node." msgstr "Solo perché un nodo non risponde, non significa che non sta accedendo ai dati. L'unica via per essere al 100% certi che i propri dati siano al sicuro è quella di utilizzare STONITH in modo da essere certi che un nodo sia realmente spento, prima di consentire l'accesso ai dati ad un altro nodo." #. Tag: para #, no-c-format msgid "STONITH also has a role to play in the event that a clustered service cannot be stopped. In this case, the cluster uses STONITH to force the whole node offline, thereby making it safe to start the service elsewhere." msgstr "STONITH ha un ruolo da gionare anche nel caso in cui i servizi clusterizzati non possono essere stoppati. In questi casi, il cluster utilizza STONITH per spegnere forzatamente l'intero nodo, ed essere quindi certo che il servizio possa essere avviato altrove in sicurezza." #. Tag: title #, no-c-format msgid "What STONITH Device Should You Use" msgstr "Quale STONITH device si dovrebbe usare" #. Tag: para #, no-c-format msgid "It is crucial that the STONITH device can allow the cluster to differentiate between a node failure and a network one." msgstr "E' cruciale che il device STONITH consenta al cluster di differenziare tra un'anomalia del nodo ed una di rete." #. Tag: para #, no-c-format msgid "The biggest mistake people make in choosing a STONITH device is to use remote power switch (such as many on-board IMPI controllers) that shares power with the node it controls. In such cases, the cluster cannot be sure if the node is really offline, or active and suffering from a network fault." msgstr "Il più grande errore generalmente commesso nella scelta del device STONITH è quello di usare un remote power switch (come molti on-board IMPI controller) che condividono l'alimentazione con il nodo che controllano. In questi casi, il cluster non può essere certo del fatto che il nodo sia realmente offline, oppure attivo, ma con problemi di rete." #. Tag: para #, fuzzy, no-c-format msgid "Likewise, any device that relies on the machine being active (such as SSH-based \"devices\" used during testing) are inappropriate." msgstr "Similarmente ogni device che risiede sulla macchina attiva (come i device SSH utilizzati per i test) risulta inappropriato." #. Tag: title #, no-c-format msgid "Configuring STONITH" msgstr "Configurare STONITH" #. Tag: para #, fuzzy, no-c-format msgid "Find the correct driver: stonith_admin --list-installed" msgstr "Determinare il driver corretto: stonith_admin --list-installed" #. Tag: para #, fuzzy, no-c-format msgid "Since every device is different, the parameters needed to configure it will vary. To find out the parameters associated with the device, run: stonith_admin --metadata --agent type" msgstr "Dato che ogni device è diverso, i parametri necessari per configurarlo possono variare. Per trovare i parametri associati al device è sufficiente lanciare:" #. Tag: literallayout #, fuzzy, no-c-format msgid "" "The output should be XML formatted text containing additional\n" "parameter descriptions. We will endevor to make the output more\n" "friendly in a later version." msgstr "L'output dovrebbe risultare in testo formattato in XML contenente le descrizioni dei parametri. Nelle prossime versioni l'output verrà reso più leggibile." #. Tag: para #, fuzzy, no-c-format msgid "Enter the shell crm Create an editable copy of the existing configuration cib new stonith Create a fencing resource containing a primitive resource with a class of stonith, a type of type and a parameter for each of the values returned in step 2: configure primitive …" msgstr "Creare un file chiamato stonith.xml contenente una risorsa primitiva con una classe di stonith, un tipo di type ed un parametro per ciascuno dei valori restituiti nel passo 2" #. Tag: para #, fuzzy, no-c-format msgid "If the device does not know how to fence nodes based on their uname, you may also need to set the special pcmk_host_map parameter. See man stonithd for details." msgstr "Se il device non conosce come effettuare il fence dei nodi in base al relativo uname, potrebbe essere necessario valorizzare il parametro speciale pcmk_host_map. Vedere man stonithd per i dettagli." #. Tag: para #, fuzzy, no-c-format msgid "If the device does not support the list command, you may also need to set the special pcmk_host_list and/or pcmk_host_check parameters. See man stonithd for details." msgstr "Se il device non supporta il comando list è possibile valorizzare i parametri speciali pcmk_host_list e/o pcmk_host_check. Vedere man stonithd per dettagli." #. Tag: para #, fuzzy, no-c-format msgid "If the device does not expect the victim to be specified with the port parameter, you may also need to set the special pcmk_host_argument parameter. See man stonithd for details." msgstr "Se il device non si aspetta che la vittima venga specificata con il parametro port, potrebbe essere necessario valorizzare il parametro speciale pcmk_host_argument. Vedere man stonithd per dettagli." #. Tag: para #, no-c-format msgid "Upload it into the CIB from the shell: cib commit stonith" msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "Once the stonith resource is running, you can test it by executing: stonith_admin --reboot nodename. Although you might want to stop the cluster on that machine first." msgstr "Una volta che la risorsa stonith sta funzionando, è possibile testarla eseguendo: stonith_admin --reboot nodename. Su questa macchina sarebbe certamente preferibile effettuare prima uno stop del servizio cluster." #. Tag: title #, no-c-format msgid "Example" msgstr "Esempio" #. Tag: para #, fuzzy, no-c-format msgid "Assuming we have an chassis containing four nodes and an IPMI device active on 10.0.0.1, then we would chose the fence_ipmilan driver in step 2 and obtain the following list of parameters" msgstr "Assumendo di possedere uno chassis contenente quattro nodi ed un device IPMI attivo su 10.0.0.1, allora nel passo 2 verrà selezionato il driver fence_ipmilan e si otterrà la seguente lista di parametri" #. Tag: title #, no-c-format msgid "Obtaining a list of STONITH Parameters" msgstr "Ottenere la lista dei parametri STONITH" #. Tag: programlisting #, no-c-format msgid "# stonith_admin --metadata -a fence_ipmilan" msgstr "" #. Tag: programlisting #, fuzzy, no-c-format msgid "" "<?xml version=\"1.0\" ?>\n" "<resource-agent name=\"fence_ipmilan\" shortdesc=\"Fence agent for IPMI over LAN\">\n" "<longdesc>\n" "fence_ipmilan is an I/O Fencing agent which can be used with machines controlled by IPMI. This agent calls support software using ipmitool (http://ipmitool.sf.net/).\n" "\n" "To use fence_ipmilan with HP iLO 3 you have to enable lanplus option (lanplus / -P) and increase wait after operation to 4 seconds (power_wait=4 / -T 4)</longdesc>\n" "<parameters>\n" " <parameter name=\"auth\" unique=\"1\">\n" " <getopt mixed=\"-A\" />\n" " <content type=\"string\" />\n" " <shortdesc>IPMI Lan Auth type (md5, password, or none)</shortdesc>\n" " </parameter>\n" " <parameter name=\"ipaddr\" unique=\"1\">\n" " <getopt mixed=\"-a\" />\n" " <content type=\"string\" />\n" " <shortdesc>IPMI Lan IP to talk to</shortdesc>\n" " </parameter>\n" " <parameter name=\"passwd\" unique=\"1\">\n" " <getopt mixed=\"-p\" />\n" " <content type=\"string\" />\n" " <shortdesc>Password (if required) to control power on IPMI device</shortdesc>\n" " </parameter>\n" " <parameter name=\"passwd_script\" unique=\"1\">\n" " <getopt mixed=\"-S\" />\n" " <content type=\"string\" />\n" " <shortdesc>Script to retrieve password (if required)</shortdesc>\n" " </parameter>\n" " <parameter name=\"lanplus\" unique=\"1\">\n" " <getopt mixed=\"-P\" />\n" " <content type=\"boolean\" />\n" " <shortdesc>Use Lanplus</shortdesc>\n" " </parameter>\n" " <parameter name=\"login\" unique=\"1\">\n" " <getopt mixed=\"-l\" />\n" " <content type=\"string\" />\n" " <shortdesc>Username/Login (if required) to control power on IPMI device</shortdesc>\n" " </parameter>\n" " <parameter name=\"action\" unique=\"1\">\n" " <getopt mixed=\"-o\" />\n" " <content type=\"string\" default=\"reboot\"/>\n" " <shortdesc>Operation to perform. Valid operations: on, off, reboot, status, list, diag, monitor or metadata</shortdesc>\n" " </parameter>\n" " <parameter name=\"timeout\" unique=\"1\">\n" " <getopt mixed=\"-t\" />\n" " <content type=\"string\" />\n" " <shortdesc>Timeout (sec) for IPMI operation</shortdesc>\n" " </parameter>\n" " <parameter name=\"cipher\" unique=\"1\">\n" " <getopt mixed=\"-C\" />\n" " <content type=\"string\" />\n" " <shortdesc>Ciphersuite to use (same as ipmitool -C parameter)</shortdesc>\n" " </parameter>\n" " <parameter name=\"method\" unique=\"1\">\n" " <getopt mixed=\"-M\" />\n" " <content type=\"string\" default=\"onoff\"/>\n" " <shortdesc>Method to fence (onoff or cycle)</shortdesc>\n" " </parameter>\n" " <parameter name=\"power_wait\" unique=\"1\">\n" " <getopt mixed=\"-T\" />\n" " <content type=\"string\" default=\"2\"/>\n" " <shortdesc>Wait X seconds after on/off operation</shortdesc>\n" " </parameter>\n" " <parameter name=\"delay\" unique=\"1\">\n" " <getopt mixed=\"-f\" />\n" " <content type=\"string\" />\n" " <shortdesc>Wait X seconds before fencing is started</shortdesc>\n" " </parameter>\n" " <parameter name=\"verbose\" unique=\"1\">\n" " <getopt mixed=\"-v\" />\n" " <content type=\"boolean\" />\n" " <shortdesc>Verbose mode</shortdesc>\n" " </parameter>\n" "</parameters>\n" "<actions>\n" " <action name=\"on\" />\n" " <action name=\"off\" />\n" " <action name=\"reboot\" />\n" " <action name=\"status\" />\n" " <action name=\"diag\" />\n" " <action name=\"list\" />\n" " <action name=\"monitor\" />\n" " <action name=\"metadata\" />\n" "</actions>\n" "</resource-agent>" msgstr "" "\n" "# stonith_admin --metadata -a fence_ipmilan\n" "\n" "<?xml version="1.0" ?>\n" "<resource-agent name="fence_ipmilan" shortdesc="Fence agent for IPMI over LAN">\n" "<longdesc>\n" "fence_ipmilan is an I/O Fencing agent which can be used with machines controlled by IPMI. This agent calls support software using ipmitool (http://ipmitool.sf.net/).\n" "\n" "To use fence_ipmilan with HP iLO 3 you have to enable lanplus option (lanplus / -P) and increase wait after operation to 4 seconds (power_wait=4 / -T 4)</longdesc>\n" "<parameters>\n" "\t<parameter name="auth" unique="1">\n" "\t\t<getopt mixed="-A" />\n" "\t\t<content type="string" />\n" "\t\t<shortdesc lang="en">IPMI Lan Auth type (md5, password, or none)</shortdesc>\n" "\t</parameter>\n" "\t<parameter name="ipaddr" unique="1">\n" "\t\t<getopt mixed="-a" />\n" "\t\t<content type="string" />\n" "\t\t<shortdesc lang="en">IPMI Lan IP to talk to</shortdesc>\n" "\t</parameter>\n" "\t<parameter name="passwd" unique="1">\n" "\t\t<getopt mixed="-p" />\n" "\t\t<content type="string" />\n" "\t\t<shortdesc lang="en">Password (if required) to control power on IPMI device</shortdesc>\n" "\t</parameter>\n" "\t<parameter name="passwd_script" unique="1">\n" "\t\t<getopt mixed="-S" />\n" "\t\t<content type="string" />\n" "\t\t<shortdesc lang="en">Script to retrieve password (if required)</shortdesc>\n" "\t</parameter>\n" "\t<parameter name="lanplus" unique="1">\n" "\t\t<getopt mixed="-P" />\n" "\t\t<content type="boolean" />\n" "\t\t<shortdesc lang="en">Use Lanplus</shortdesc>\n" "\t</parameter>\n" "\t<parameter name="login" unique="1">\n" "\t\t<getopt mixed="-l" />\n" "\t\t<content type="string" />\n" "\t\t<shortdesc lang="en">Username/Login (if required) to control power on IPMI device</shortdesc>\n" "\t</parameter>\n" "\t<parameter name="action" unique="1">\n" "\t\t<getopt mixed="-o" />\n" "\t\t<content type="string" default="reboot"/>\n" "\t\t<shortdesc lang="en">Operation to perform. Valid operations: on, off, reboot, status, list, diag, monitor or metadata</shortdesc>\n" "\t</parameter>\n" "\t<parameter name="timeout" unique="1">\n" "\t\t<getopt mixed="-t" />\n" "\t\t<content type="string" />\n" "\t\t<shortdesc lang="en">Timeout (sec) for IPMI operation</shortdesc>\n" "\t</parameter>\n" "\t<parameter name="cipher" unique="1">\n" "\t\t<getopt mixed="-C" />\n" "\t\t<content type="string" />\n" "\t\t<shortdesc lang="en">Ciphersuite to use (same as ipmitool -C parameter)</shortdesc>\n" "\t</parameter>\n" "\t<parameter name="method" unique="1">\n" "\t\t<getopt mixed="-M" />\n" "\t\t<content type="string" default="onoff"/>\n" "\t\t<shortdesc lang="en">Method to fence (onoff or cycle)</shortdesc>\n" "\t</parameter>\n" "\t<parameter name="power_wait" unique="1">\n" "\t\t<getopt mixed="-T" />\n" "\t\t<content type="string" default="2"/>\n" "\t\t<shortdesc lang="en">Wait X seconds after on/off operation</shortdesc>\n" "\t</parameter>\n" "\t<parameter name="delay" unique="1">\n" "\t\t<getopt mixed="-f" />\n" "\t\t<content type="string" />\n" "\t\t<shortdesc lang="en">Wait X seconds before fencing is started</shortdesc>\n" "\t</parameter>\n" "\t<parameter name="verbose" unique="1">\n" "\t\t<getopt mixed="-v" />\n" "\t\t<content type="boolean" />\n" "\t\t<shortdesc lang="en">Verbose mode</shortdesc>\n" "\t</parameter>\n" "</parameters>\n" "<actions>\n" "\t<action name="on" />\n" "\t<action name="off" />\n" "\t<action name="reboot" />\n" "\t<action name="status" />\n" "\t<action name="diag" />\n" "\t<action name="list" />\n" "\t<action name="monitor" />\n" "\t<action name="metadata" />\n" "</actions>\n" "</resource-agent>\n" #. Tag: para #, no-c-format msgid "from which we would create a STONITH resource fragment that might look like this" msgstr "da cui sarà possibile creare una risorsa STONITH che assomigli alla seguente" #. Tag: title #, no-c-format msgid "Sample STONITH Resource" msgstr "Esempio di risorsa STONITH" #. Tag: programlisting #, no-c-format msgid "" "# crm crm(live)# cib new stonith\n" "INFO: stonith shadow CIB created\n" "crm(stonith)# configure primitive impi-fencing stonith::fence_ipmilan \\\n" " params pcmk_host_list=\"pcmk-1 pcmk-2\" ipaddr=10.0.0.1 login=testuser passwd=abc123 \\\n" " op monitor interval=\"60s\"" msgstr "" #. Tag: para #, no-c-format msgid "And finally, since we disabled it earlier, we need to re-enable STONITH. At this point we should have the following configuration." msgstr "" #. Tag: para #, no-c-format msgid "Now push the configuration into the cluster." msgstr "" #. Tag: programlisting #, no-c-format msgid "" "crm(stonith)# configure property stonith-enabled=\"true\"\n" "crm(stonith)# configure shownode pcmk-1\n" "node pcmk-2\n" "primitive WebData ocf:linbit:drbd \\\n" " params drbd_resource=\"wwwdata\" \\\n" " op monitor interval=\"60s\"\n" "primitive WebFS ocf:heartbeat:Filesystem \\\n" " params device=\"/dev/drbd/by-res/wwwdata\" directory=\"/var/www/html\" fstype=\"gfs2\"\n" "primitive WebSite ocf:heartbeat:apache \\\n" " params configfile=\"/etc/httpd/conf/httpd.conf\" \\\n" " op monitor interval=\"1min\"\n" "primitive ClusterIP ocf:heartbeat:IPaddr2 \\\n" " params ip=\"192.168.122.101\" cidr_netmask=\"32\" clusterip_hash=\"sourceip\" \\\n" " op monitor interval=\"30s\"primitive ipmi-fencing stonith::fence_ipmilan \\ params pcmk_host_list=\"pcmk-1 pcmk-2\" ipaddr=10.0.0.1 login=testuser passwd=abc123 \\ op monitor interval=\"60s\"ms WebDataClone WebData \\\n" " meta master-max=\"2\" master-node-max=\"1\" clone-max=\"2\" clone-node-max=\"1\" notify=\"true\"\n" "clone WebFSClone WebFS\n" "clone WebIP ClusterIP \\\n" " meta globally-unique=\"true\" clone-max=\"2\" clone-node-max=\"2\"\n" "clone WebSiteClone WebSite\n" "colocation WebSite-with-WebFS inf: WebSiteClone WebFSClone\n" "colocation fs_on_drbd inf: WebFSClone WebDataClone:Master\n" "colocation website-with-ip inf: WebSiteClone WebIP\n" "order WebFS-after-WebData inf: WebDataClone:promote WebFSClone:start\n" "order WebSite-after-WebFS inf: WebFSClone WebSiteClone\n" "order apache-after-ip inf: WebIP WebSiteClone\n" "property $id=\"cib-bootstrap-options\" \\\n" " dc-version=\"1.1.5-bdd89e69ba545404d02445be1f3d72e6a203ba2f\" \\\n" " cluster-infrastructure=\"openais\" \\\n" " expected-quorum-votes=\"2\" \\\n" " stonith-enabled=\"true\" \\\n" " no-quorum-policy=\"ignore\"\n" "rsc_defaults $id=\"rsc-options\" \\\n" " resource-stickiness=\"100\"\n" "crm(stonith)# cib commit stonithINFO: commited 'stonith' shadow CIB to the cluster\n" "crm(stonith)# quit\n" "bye" msgstr "" #~ msgid "Protecting Your Data - STONITH" #~ msgstr "Proteggere i propri dati - STONITH" #~ msgid "stonith_admin --metadata --agent type" #~ msgstr "stonith_admin --metadata --agent type" #~ msgid "Upload it into the CIB using cibadmin: cibadmin -C -o resources --xml-file stonith.xml" #~ msgstr "Effettuare l'upload all'interno del CIB utilizzando cibadmin: cibadmin -C -o resources --xml-file stonith.xml" #~ msgid "" #~ "\n" #~ "\n" #~ " <primitive id="ipmi" class="stonith" type="fence_ipmilan">\n" #~ " <operations>\n" #~ " <op id="ipmi-mon-1" name="monitor" interval="120s"/>\n" #~ " </operations>\n" #~ " <instance_attributes id="ipmi-parameters">\n" #~ " <nvpair id="ipmi-attr-1" name="pcmk_host_list" value="node1 node2 node3 node4"/>\n" #~ " <nvpair id="ipmi-attr-1" name="ipaddr" value="10.0.0.1"/>\n" #~ " <nvpair id="ipmi-attr-1" name="login" value="testuser"/>\n" #~ " <nvpair id="ipmi-attr-1" name="passwd" value="abc123"/>\n" #~ " </instance_attributes>\n" #~ " </primitive>\n" #~ "\n" #~ "\t " #~ msgstr "" #~ "\n" #~ "\n" #~ " <primitive id="ipmi" class="stonith" type="fence_ipmilan">\n" #~ " <operations>\n" #~ " <op id="ipmi-mon-1" name="monitor" interval="120s"/>\n" #~ " </operations>\n" #~ " <instance_attributes id="ipmi-parameters">\n" #~ " <nvpair id="ipmi-attr-1" name="pcmk_host_list" value="node1 node2 node3 node4"/>\n" #~ " <nvpair id="ipmi-attr-1" name="ipaddr" value="10.0.0.1"/>\n" #~ " <nvpair id="ipmi-attr-1" name="login" value="testuser"/>\n" #~ " <nvpair id="ipmi-attr-1" name="passwd" value="abc123"/>\n" #~ " </instance_attributes>\n" #~ " </primitive>\n" #~ "\n" #~ "\t " pacemaker-master/doc/Pacemaker_Explained/it-IT/Pacemaker_Explained.po000066400000000000000000000042141217637305600261070ustar00rootroot00000000000000# # AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: 0\n" "POT-Creation-Date: 2012-10-17T05:19:02\n" "PO-Revision-Date: 2011-04-19 10:27+0100\n" "Last-Translator: RaSca \n" "Language-Team: None\n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. Tag: title #, fuzzy, no-c-format msgid "Receiving Notification for Cluster Events" msgstr "Ricevere notifiche in merito agli eventi del Cluster" #. Tag: title #, no-c-format msgid "Configuring Email Notifications" msgstr "Configurare le notifica Email" #. Tag: title #, no-c-format msgid "Configuring SNMP Notifications" msgstr "Configurare le notifiche SNMP" #. Tag: title #, no-c-format msgid "Further Reading" msgstr "Approfondimenti" #. Tag: para #, fuzzy, no-c-format msgid "Project Website " msgstr "Configurazione di Corosync: " #. Tag: para #, fuzzy, no-c-format msgid "Project Documentation " msgstr "Sito del progetto: e documentazione " #. Tag: para #, fuzzy, no-c-format msgid "A comprehensive guide to cluster commands has been written by Novell" msgstr "Una guida completa ai comandi cluster è stata scritta da Novell ed è disponibile qui: " #. Tag: para #, no-c-format msgid "Heartbeat configuration: " msgstr "Configurazione di Heartbeat: " #. Tag: para #, no-c-format msgid "Corosync Configuration: " msgstr "Configurazione di Corosync: " #~ msgid "Cluster Commands" #~ msgstr "Comandi del Cluster" pacemaker-master/doc/Pacemaker_Explained/it-IT/Preface.po000066400000000000000000000006571217637305600236020ustar00rootroot00000000000000# # AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: 0\n" "POT-Creation-Date: 2011-10-05T10:46:07\n" "PO-Revision-Date: 2011-04-19 10:23+0100\n" "Last-Translator: RaSca \n" "Language-Team: None\n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. Tag: title #, no-c-format msgid "Preface" msgstr "Prefazione" pacemaker-master/doc/Pacemaker_Explained/it-IT/Revision_History.po000066400000000000000000000030551217637305600255470ustar00rootroot00000000000000# # AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: 0\n" "POT-Creation-Date: 2012-10-17T05:19:02\n" "PO-Revision-Date: 2011-04-19 10:30+0100\n" "Last-Translator: RaSca \n" "Language-Team: None\n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. Tag: title #, no-c-format msgid "Revision History" msgstr "Revision History" #. Tag: firstname #, no-c-format msgid "Andrew" msgstr "Andrew" #. Tag: surname #, no-c-format msgid "Beekhof" msgstr "Beekhof" #. Tag: member #, no-c-format msgid "Import from Pages.app" msgstr "Import da Pages.app" #. Tag: member #, no-c-format msgid "Cleanup and reformatting of docbook xml complete" msgstr "Completata la pulizia e riformattazione dell'xml docbook" #. Tag: member #, no-c-format msgid "Split book into chapters and pass validation" msgstr "Divisione del libro in capitoli e conferma validazione" #. Tag: member #, no-c-format msgid "Re-organize book for use with Publican" msgstr "Riorganizzazione del lbro per l'utilizzo di Publican" #. Tag: member #, fuzzy, no-c-format msgid "Converted to asciidoc (which is converted to docbook for use with Publican)" msgstr "Riorganizzazione del lbro per l'utilizzo di Publican" pacemaker-master/doc/Pacemaker_Explained/pot/000077500000000000000000000000001217637305600215415ustar00rootroot00000000000000pacemaker-master/doc/Pacemaker_Explained/pot/Ap-Changes.pot000066400000000000000000000125441217637305600242010ustar00rootroot00000000000000# # AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: 0\n" "POT-Creation-Date: 2012-10-17T05:19:01\n" "PO-Revision-Date: 2012-10-17T05:19:01\n" "Last-Translator: Automatically generated\n" "Language-Team: None\n" "MIME-Version: 1.0\n" "Content-Type: application/x-publican; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. Tag: title #, no-c-format msgid "What Changed in 1.0" msgstr "" #. Tag: title #, no-c-format msgid "New" msgstr "" #. Tag: para #, no-c-format msgid "Failure timeouts. See " msgstr "" #. Tag: para #, no-c-format msgid "New section for resource and operation defaults. See and " msgstr "" #. Tag: para #, no-c-format msgid "Tool for making offline configuration changes. See " msgstr "" #. Tag: para #, no-c-format msgid "Rules, instance_attributes, meta_attributes and sets of operations can be defined once and referenced in multiple places. See " msgstr "" #. Tag: para #, no-c-format msgid "The CIB now accepts XPath-based create/modify/delete operations. See the cibadmin help text." msgstr "" #. Tag: para #, no-c-format msgid "Multi-dimensional colocation and ordering constraints. See and " msgstr "" #. Tag: para #, no-c-format msgid "The ability to connect to the CIB from non-cluster machines. See " msgstr "" #. Tag: para #, no-c-format msgid "Allow recurring actions to be triggered at known times. See " msgstr "" #. Tag: title #, no-c-format msgid "Changed" msgstr "" #. Tag: para #, no-c-format msgid "Syntax" msgstr "" #. Tag: para #, no-c-format msgid "All resource and cluster options now use dashes (-) instead of underscores (_)" msgstr "" #. Tag: para #, no-c-format msgid "master_slave was renamed to master" msgstr "" #. Tag: para #, no-c-format msgid "The attributes container tag was removed" msgstr "" #. Tag: para #, no-c-format msgid "The operation field pre-req has been renamed requires" msgstr "" #. Tag: para #, no-c-format msgid "All operations must have an interval, start/stop must have it set to zero" msgstr "" #. Tag: para #, no-c-format msgid "The stonith-enabled option now defaults to true." msgstr "" #. Tag: para #, no-c-format msgid "The cluster will refuse to start resources if stonith-enabled is true (or unset) and no STONITH resources have been defined" msgstr "" #. Tag: para #, no-c-format msgid "The attributes of colocation and ordering constraints were renamed for clarity. See and " msgstr "" #. Tag: para #, no-c-format msgid "resource-failure-stickiness has been replaced by migration-threshold. See " msgstr "" #. Tag: para #, no-c-format msgid "The parameters for command-line tools have been made consistent" msgstr "" #. Tag: para #, no-c-format msgid "Switched to RelaxNG schema validation and libxml2 parser" msgstr "" #. Tag: para #, no-c-format msgid "id fields are now XML IDs which have the following limitations:" msgstr "" #. Tag: para #, no-c-format msgid "id’s cannot contain colons (:)" msgstr "" #. Tag: para #, no-c-format msgid "id’s cannot begin with a number" msgstr "" #. Tag: para #, no-c-format msgid "id’s must be globally unique (not just unique for that tag)" msgstr "" #. Tag: para #, no-c-format msgid "Some fields (such as those in constraints that refer to resources) are IDREFs." msgstr "" #. Tag: para #, no-c-format msgid "This means that they must reference existing resources or objects in order for the configuration to be valid. Removing an object which is referenced elsewhere will therefore fail." msgstr "" #. Tag: para #, no-c-format msgid "The CIB representation, from which a MD5 digest is calculated to verify CIBs on the nodes, has changed." msgstr "" #. Tag: para #, no-c-format msgid "This means that every CIB update will require a full refresh on any upgraded nodes until the cluster is fully upgraded to 1.0. This will result in significant performance degradation and it is therefore highly inadvisable to run a mixed 1.0/0.6 cluster for any longer than absolutely necessary." msgstr "" #. Tag: para #, no-c-format msgid "Ping node information no longer needs to be added to ha.cf." msgstr "" #. Tag: para #, no-c-format msgid "Simply include the lists of hosts in your ping resource(s)." msgstr "" #. Tag: title #, no-c-format msgid "Removed" msgstr "" #. Tag: para #, no-c-format msgid "It is no longer possible to set resource meta options as top-level attributes. Use meta attributes instead." msgstr "" #. Tag: para #, no-c-format msgid "Resource and operation defaults are no longer read from crm_config. See and instead." msgstr "" pacemaker-master/doc/Pacemaker_Explained/pot/Ap-Debug.pot000066400000000000000000000125631217637305600236600ustar00rootroot00000000000000# # AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: 0\n" "POT-Creation-Date: 2012-10-17T05:19:01\n" "PO-Revision-Date: 2012-10-17T05:19:01\n" "Last-Translator: Automatically generated\n" "Language-Team: None\n" "MIME-Version: 1.0\n" "Content-Type: application/x-publican; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. Tag: title #, no-c-format msgid "Debugging Cluster Startup" msgstr "" #. Tag: title #, no-c-format msgid "Corosync" msgstr "" #. Tag: title #, no-c-format msgid "Prerequisites" msgstr "" #. Tag: title #, no-c-format msgid "Minimum logging configuration" msgstr "" #. Tag: programlisting #, no-c-format msgid "\n" " # /etc/init.d/openais start\n" " \n" " \n" " logging {\n" " to_syslog: yes\n" " syslog_facility: daemon\n" " }\n" " \n" " " msgstr "" #. Tag: caption #, no-c-format msgid "Whatever other logging you have, these two lines are required for Pacemaker clusters" msgstr "" #. Tag: title #, no-c-format msgid "Confirm Corosync Started" msgstr "" #. Tag: title #, no-c-format msgid "Expected output when starting openais" msgstr "" #. Tag: screen #, no-c-format msgid "\n" " # /etc/init.d/openais start\n" " \n" " \n" " Starting Corosync daemon (aisexec): starting... rc=0: OK\n" " \n" " " msgstr "" #. Tag: title #, no-c-format msgid "Expected log messages - startup" msgstr "" #. Tag: screen #, no-c-format msgid "\n" " # grep -e \"openais.*network interface\" -e \"AIS Executive Service\" /var/log/messages\n" " \n" " \n" " Aug 27 16:23:37 test1 openais[26337]: [MAIN ] AIS Executive Service RELEASE 'subrev 1152 version 0.80'\n" " Aug 27 16:23:38 test1 openais[26337]: [MAIN ] AIS Executive Service: started and ready to provide service.\n" " Aug 27 16:23:38 test1 openais[26337]: [TOTEM] The network interface [192.168.9.41] is now up.\n" " \n" " " msgstr "" #. Tag: caption #, no-c-format msgid "The versions may differ, but you should see Corosync indicate it started and sucessfully attached to the machine's network interface" msgstr "" #. Tag: title #, no-c-format msgid "Expected log messages - membership" msgstr "" #. Tag: screen #, no-c-format msgid "\n" " # grep CLM /var/log/messages\n" " \n" " \n" " Aug 27 16:53:15 test1 openais[2166]: [CLM ] CLM CONFIGURATION CHANGE\n" " Aug 27 16:53:15 test1 openais[2166]: [CLM ] New Configuration:\n" " Aug 27 16:53:15 test1 openais[2166]: [CLM ] Members Left:\n" " Aug 27 16:53:15 test1 openais[2166]: [CLM ] Members Joined:\n" " Aug 27 16:53:15 test1 openais[2166]: [CLM ] CLM CONFIGURATION CHANGE\n" " Aug 27 16:53:15 test1 openais[2166]: [CLM ] New Configuration:\n" " Aug 27 16:53:15 test1 openais[2166]: [CLM ] r(0) ip(192.168.9.41)\n" " Aug 27 16:53:15 test1 openais[2166]: [CLM ] Members Left:\n" " Aug 27 16:53:15 test1 openais[2166]: [CLM ] Members Joined:\n" " Aug 27 16:53:15 test1 openais[2166]: [CLM ] r(0) ip(192.168.9.41)\n" " Aug 27 16:53:15 test1 openais[2166]: [CLM ] got nodejoin message 192.168.9.41\n" " \n" " " msgstr "" #. Tag: caption #, no-c-format msgid "The exact messages will differ, but you should see a new membership formed with the real IP address of your node" msgstr "" #. Tag: title #, no-c-format msgid "Checking Pacemaker" msgstr "" #. Tag: para #, no-c-format msgid "Now that we have confirmed that Corosync is functional we can check the rest of the stack." msgstr "" #. Tag: title #, no-c-format msgid "Expected Pacemaker startup logging for Corosync" msgstr "" #. Tag: screen #, no-c-format msgid "\n" " # grep pcmk_plugin_init /var/log/messages\n" " \n" " \n" " Aug 27 16:53:15 test1 openais[2166]: [pcmk ] info: pcmk_plugin_init: CRM: Initialized\n" " Aug 27 16:53:15 test1 openais[2166]: [pcmk ] Logging: Initialized pcmk_plugin_init\n" " Aug 27 16:53:15 test1 openais[2166]: [pcmk ] info: pcmk_plugin_init: Service: 9\n" " Aug 27 16:53:15 test1 openais[2166]: [pcmk ] info: pcmk_plugin_init: Local hostname: test1\n" " \n" " " msgstr "" #. Tag: caption #, no-c-format msgid "If you don't see these messages, or some like them, there is likely a problem finding or loading the pacemaker plugin." msgstr "" #. Tag: title #, no-c-format msgid "Expected process listing on a 64-bit machine" msgstr "" #. Tag: screen #, no-c-format msgid "\n" " # ps axf\n" " \n" " \n" " 3718 ? Ssl 0:05 /usr/sbin/aisexec\n" " 3723 ? SLs 0:00 \\_ /usr/lib64/heartbeat/stonithd\n" " 3724 ? S 0:05 \\_ /usr/lib64/heartbeat/cib\n" " 3725 ? S 0:21 \\_ /usr/lib64/heartbeat/lrmd\n" " 3726 ? S 0:01 \\_ /usr/lib64/heartbeat/attrd\n" " 3727 ? S 0:00 \\_ /usr/lib64/heartbeat/pengine\n" " 3728 ? S 0:01 \\_ /usr/lib64/heartbeat/crmd\n" " \n" " " msgstr "" #. Tag: caption #, no-c-format msgid "On 32-bit systems the exact path may differ, but all the above processes should be listed." msgstr "" pacemaker-master/doc/Pacemaker_Explained/pot/Ap-FAQ.pot000066400000000000000000000106341217637305600232360ustar00rootroot00000000000000# # AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: 0\n" "POT-Creation-Date: 2012-10-17T05:19:01\n" "PO-Revision-Date: 2012-10-17T05:19:01\n" "Last-Translator: Automatically generated\n" "Language-Team: None\n" "MIME-Version: 1.0\n" "Content-Type: application/x-publican; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. Tag: title #, no-c-format msgid "FAQ" msgstr "" #. Tag: title #, no-c-format msgid "History" msgstr "" #. Tag: para #, no-c-format msgid "Why is the Project Called PacemakernamingPacemaker?" msgstr "" #. Tag: para #, no-c-format msgid "First of all, the reason its not called the CRM is because of the abundance of terms that are commonly abbreviated to those three letters." msgstr "" #. Tag: para #, no-c-format msgid "The Pacemaker name came from Kham, a good friend of mine, and was originally used by a Java GUI that I was prototyping in early 2007. Alas other commitments have prevented the GUI from progressing much and, when it came time to choose a name for this project, Lars suggested it was an even better fit for an independent CRM." msgstr "" #. Tag: para #, no-c-format msgid "The idea stems from the analogy between the role of this software and that of the little device that keeps the human heart pumping. Pacemaker monitors the cluster and intervenes when necessary to ensure the smooth operation of the services it provides." msgstr "" #. Tag: para #, no-c-format msgid "There were a number of other names (and acronyms) tossed around, but suffice to say \"Pacemaker\" was the best" msgstr "" #. Tag: para #, no-c-format msgid "Why was the Pacemaker Project Created?" msgstr "" #. Tag: para #, no-c-format msgid "The decision was made to spin-off the CRM into its own project after the 2.1.3 Heartbeat release in order to" msgstr "" #. Tag: para #, no-c-format msgid "support both the Corosync and Heartbeat cluster stacks equally" msgstr "" #. Tag: para #, no-c-format msgid "decouple the release cycles of two projects at very different stages of their life-cycles" msgstr "" #. Tag: para #, no-c-format msgid "foster the clearer package boundaries, thus leading to" msgstr "" #. Tag: para #, no-c-format msgid "better and more stable interfaces" msgstr "" #. Tag: title #, no-c-format msgid "Setup" msgstr "" #. Tag: para #, no-c-format msgid "What Messaging Layers Messaging Layers are Supported?" msgstr "" #. Tag: para #, no-c-format msgid "Corosync ()" msgstr "" #. Tag: para #, no-c-format msgid "Heartbeat ()" msgstr "" #. Tag: para #, no-c-format msgid "Can I Choose which Messaging Layer to use at Run Time?" msgstr "" #. Tag: para #, no-c-format msgid "Yes. The CRM will automatically detect which started it and behave accordingly." msgstr "" #. Tag: para #, no-c-format msgid "Can I Have a Mixed Heartbeat-Corosync Cluster?" msgstr "" #. Tag: para #, no-c-format msgid "No." msgstr "" #. Tag: para #, no-c-format msgid "Which Messaging Layer Should I Choose?" msgstr "" #. Tag: para #, no-c-format msgid "This is discussed in ." msgstr "" #. Tag: para #, no-c-format msgid "Where Can I Get Pre-built Packages?" msgstr "" #. Tag: para #, no-c-format msgid "Official packages for most major .rpm and based distributions are available from the ClusterLabs Website." msgstr "" #. Tag: para #, no-c-format msgid "For Debian packages, building from source and details on using the above repositories, see our installation page." msgstr "" #. Tag: para #, no-c-format msgid "What Versions of Pacemaker Are Supported?" msgstr "" #. Tag: para #, no-c-format msgid "Please refer to the Releases page for an up-to-date list of versions supported directly by the project." msgstr "" #. Tag: para #, no-c-format msgid "When seeking assistance, please try to ensure you have one of these versions." msgstr "" pacemaker-master/doc/Pacemaker_Explained/pot/Ap-Install.pot000066400000000000000000000133701217637305600242350ustar00rootroot00000000000000# # AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: 0\n" "POT-Creation-Date: 2012-10-17T05:19:01\n" "PO-Revision-Date: 2012-10-17T05:19:01\n" "Last-Translator: Automatically generated\n" "Language-Team: None\n" "MIME-Version: 1.0\n" "Content-Type: application/x-publican; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. Tag: title #, no-c-format msgid "Installation" msgstr "" #. Tag: para #, no-c-format msgid "The following text may no longer be accurate in some places." msgstr "" #. Tag: title #, no-c-format msgid "Choosing a Cluster Stack" msgstr "" #. Tag: para #, no-c-format msgid " ClusterChoosing Between Heartbeat and Corosync Choosing Between Heartbeat and Corosync Cluster StackCorosync Corosync Corosync Cluster StackHeartbeat Heartbeat Heartbeat " msgstr "" #. Tag: para #, no-c-format msgid "Ultimately the choice of cluster stack is a personal decision that must be made in the context of you or your company’s needs and strategic direction. Pacemaker currently functions equally well with both stacks." msgstr "" #. Tag: para #, no-c-format msgid "Here are some factors that may influence the decision:" msgstr "" #. Tag: para #, no-c-format msgid "SUSE/Novell, Red Hat and Oracle are all putting their collective weight behind the Corosync cluster stack." msgstr "" #. Tag: para #, no-c-format msgid "Using Corosync gives your applications access to the following additional cluster services" msgstr "" #. Tag: para #, no-c-format msgid "distributed locking service" msgstr "" #. Tag: para #, no-c-format msgid "extended virtual synchronization service" msgstr "" #. Tag: para #, no-c-format msgid "cluster closed process group service" msgstr "" #. Tag: para #, no-c-format msgid "It is likely that Pacemaker, at some point in the future, will make use of some of these additional services not provided by Heartbeat" msgstr "" #. Tag: title #, no-c-format msgid "Enabling Pacemaker" msgstr "" #. Tag: title #, no-c-format msgid "For Corosync" msgstr "" #. Tag: para #, no-c-format msgid "The Corosync configuration is normally located in /etc/corosync/corosync.conf and an example for a machine with an address of 1.2.3.4 in a cluster communicating on port 1234 (without peer authentication and message encryption) is shown below." msgstr "" #. Tag: title #, no-c-format msgid "An example Corosync configuration file" msgstr "" #. Tag: programlisting #, no-c-format msgid " totem {\n" " version: 2\n" " secauth: off\n" " threads: 0\n" " interface {\n" " ringnumber: 0\n" " bindnetaddr: 1.2.3.4\n" " mcastaddr: 239.255.1.1\n" " mcastport: 1234\n" " }\n" " }\n" " logging {\n" " fileline: off\n" " to_syslog: yes\n" " syslog_facility: daemon\n" " }\n" " amf {\n" " mode: disabled\n" " }" msgstr "" #. Tag: para #, no-c-format msgid "The logging should be mostly obvious and the amf section refers to the Availability Management Framework and is not covered in this document." msgstr "" #. Tag: para #, no-c-format msgid "The interesting part of the configuration is the totem section. This is where we define how the node can communicate with the rest of the cluster and what protocol version and options (including encryption Please consult the Corosync website (http://www.corosync.org/) and documentation for details on enabling encryption and peer authentication for the cluster. ) it should use. Beginners are encouraged to use the values shown and modify the interface section based on their network." msgstr "" #. Tag: para #, no-c-format msgid "It is also possible to configure Corosync for an IPv6 based environment. Simply configure bindnetaddr and mcastaddr with their IPv6 equivalents, eg." msgstr "" #. Tag: title #, no-c-format msgid "Example options for an IPv6 environment" msgstr "" #. Tag: programlisting #, no-c-format msgid " bindnetaddr: fec0::1:a800:4ff:fe00:20\n" " mcastaddr: ff05::1" msgstr "" #. Tag: para #, no-c-format msgid "To tell Corosync to use the Pacemaker cluster manager, add the following fragment to a functional Corosync configuration and restart the cluster." msgstr "" #. Tag: title #, no-c-format msgid "Configuration fragment for enabling Pacemaker under Corosync" msgstr "" #. Tag: programlisting #, no-c-format msgid "aisexec {\n" " user: root\n" " group: root\n" "}\n" "service {\n" " name: pacemaker\n" " ver: 0\n" "}" msgstr "" #. Tag: para #, no-c-format msgid "The cluster needs to be run as root so that its child processes (the lrmd in particular) have sufficient privileges to perform the actions requested of it. After all, a cluster manager that can’t add an IP address or start apache is of little use." msgstr "" #. Tag: para #, no-c-format msgid "The second directive is the one that actually instructs the cluster to run Pacemaker." msgstr "" #. Tag: title #, no-c-format msgid "For Heartbeat" msgstr "" #. Tag: para #, no-c-format msgid "Add the following to a functional ha.cf configuration file and restart Heartbeat:" msgstr "" #. Tag: title #, no-c-format msgid "Configuration fragment for enabling Pacemaker under Heartbeat" msgstr "" #. Tag: programlisting #, no-c-format msgid "crm respawn" msgstr "" pacemaker-master/doc/Pacemaker_Explained/pot/Ap-LSB.pot000066400000000000000000000060741217637305600232520ustar00rootroot00000000000000# # AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: 0\n" "POT-Creation-Date: 2012-10-17T05:19:01\n" "PO-Revision-Date: 2012-10-17T05:19:01\n" "Last-Translator: Automatically generated\n" "Language-Team: None\n" "MIME-Version: 1.0\n" "Content-Type: application/x-publican; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. Tag: title #, no-c-format msgid "init-Script LSB Compliance" msgstr "" #. Tag: para #, no-c-format msgid "The relevant part of LSB spec includes a description of all the return codes listed here." msgstr "" #. Tag: para #, no-c-format msgid "Assuming some_service is configured correctly and currently not active, the following sequence will help you determine if it is LSB compatible:" msgstr "" #. Tag: para #, no-c-format msgid "Start (stopped):" msgstr "" #. Tag: programlisting #, no-c-format msgid "# /etc/init.d/some_service start ; echo \"result: $?\"" msgstr "" #. Tag: para #, no-c-format msgid "Did the service start?" msgstr "" #. Tag: para #, no-c-format msgid "Did the command print result: 0 (in addition to the regular output)?" msgstr "" #. Tag: para #, no-c-format msgid "Status (running):" msgstr "" #. Tag: programlisting #, no-c-format msgid "# /etc/init.d/some_service status ; echo \"result: $?\"" msgstr "" #. Tag: para #, no-c-format msgid "Did the script accept the command?" msgstr "" #. Tag: para #, no-c-format msgid "Did the script indicate the service was running?" msgstr "" #. Tag: para #, no-c-format msgid "Start (running):" msgstr "" #. Tag: para #, no-c-format msgid "Is the service still running?" msgstr "" #. Tag: para #, no-c-format msgid "Stop (running):" msgstr "" #. Tag: programlisting #, no-c-format msgid "# /etc/init.d/some_service stop ; echo \"result: $?\"" msgstr "" #. Tag: para #, no-c-format msgid "Was the service stopped?" msgstr "" #. Tag: para #, no-c-format msgid "Status (stopped):" msgstr "" #. Tag: para #, no-c-format msgid "Did the script indicate the service was not running?" msgstr "" #. Tag: para #, no-c-format msgid "Did the command print result: 3 (in addition to the regular output)?" msgstr "" #. Tag: para #, no-c-format msgid "Stop (stopped):" msgstr "" #. Tag: para #, no-c-format msgid "Is the service still stopped?" msgstr "" #. Tag: para #, no-c-format msgid "Status (failed):" msgstr "" #. Tag: para #, no-c-format msgid "This step is not readily testable and relies on manual inspection of the script." msgstr "" #. Tag: para #, no-c-format msgid "The script can use one of the error codes (other than 3) listed in the LSB spec to indicate that it is active but failed. This tells the cluster that before moving the resource to another node, it needs to stop it on the existing one first." msgstr "" #. Tag: para #, no-c-format msgid "If the answer to any of the above questions is no, then the script is not LSB compliant. Your options are then to either fix the script or write an OCF agent based on the existing script." msgstr "" pacemaker-master/doc/Pacemaker_Explained/pot/Ap-OCF.pot000066400000000000000000000464261217637305600232460ustar00rootroot00000000000000# # AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: 0\n" "POT-Creation-Date: 2012-10-17T05:19:01\n" "PO-Revision-Date: 2012-10-17T05:19:01\n" "Last-Translator: Automatically generated\n" "Language-Team: None\n" "MIME-Version: 1.0\n" "Content-Type: application/x-publican; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. Tag: title #, no-c-format msgid "More About OCF Resource Agents" msgstr "" #. Tag: title #, no-c-format msgid "Location of Custom Scripts" msgstr "" #. Tag: para #, no-c-format msgid " OCF Resource Agents OCF Resource Agents are found in /usr/lib/ocf/resource.d/provider." msgstr "" #. Tag: para #, no-c-format msgid "When creating your own agents, you are encouraged to create a new directory under /usr/lib/ocf/resource.d/ so that they are not confused with (or overwritten by) the agents shipped with Heartbeat." msgstr "" #. Tag: para #, no-c-format msgid "So, for example, if you chose the provider name of bigCorp and wanted a new resource named bigApp, you would create a script called /usr/lib/ocf/resource.d/bigCorp/bigApp and define a resource:" msgstr "" #. Tag: programlisting #, no-c-format msgid "<primitive id=\"custom-app\" class=\"ocf\" provider=\"bigCorp\" type=\"bigApp\"/>" msgstr "" #. Tag: title #, no-c-format msgid "Actions" msgstr "" #. Tag: para #, no-c-format msgid "All OCF Resource Agents are required to implement the following actions" msgstr "" #. Tag: title #, no-c-format msgid "Required Actions for OCF Agents" msgstr "" #. Tag: entry #, no-c-format msgid "Action" msgstr "" #. Tag: entry #, no-c-format msgid "Description" msgstr "" #. Tag: entry #, no-c-format msgid "Instructions" msgstr "" #. Tag: para #, no-c-format msgid "start" msgstr "" #. Tag: para #, no-c-format msgid "Start the resource" msgstr "" #. Tag: para #, no-c-format msgid "Return 0 on success and an appropriate error code otherwise. Must not report success until the resource is fully active. startOCF Action OCF Action OCFActionstart Actionstart start " msgstr "" #. Tag: para #, no-c-format msgid "stop" msgstr "" #. Tag: para #, no-c-format msgid "Stop the resource" msgstr "" #. Tag: para #, no-c-format msgid "Return 0 on success and an appropriate error code otherwise. Must not report success until the resource is fully stopped. stopOCF Action OCF Action OCFActionstop Actionstop stop " msgstr "" #. Tag: para #, no-c-format msgid "monitor" msgstr "" #. Tag: para #, no-c-format msgid "Check the resource’s state" msgstr "" #. Tag: para #, no-c-format msgid "Exit 0 if the resource is running, 7 if it is stopped, and anything else if it is failed. monitorOCF Action OCF Action OCFActionmonitor Actionmonitor monitor " msgstr "" #. Tag: para #, no-c-format msgid "NOTE: The monitor script should test the state of the resource on the local machine only." msgstr "" #. Tag: para #, no-c-format msgid "meta-data" msgstr "" #. Tag: para #, no-c-format msgid "Describe the resource" msgstr "" #. Tag: para #, no-c-format msgid "Provide information about this resource as an XML snippet. Exit with 0. meta-dataOCF Action OCF Action OCFActionmeta-data Actionmeta-data meta-data " msgstr "" #. Tag: para #, no-c-format msgid "NOTE: This is not performed as root." msgstr "" #. Tag: para #, no-c-format msgid "validate-all" msgstr "" #. Tag: para #, no-c-format msgid "Verify the supplied parameters" msgstr "" #. Tag: para #, no-c-format msgid "Exit with 0 if parameters are valid, 2 if not valid, 6 if resource is not configured. validate-allOCF Action OCF Action OCFActionvalidate-all Actionvalidate-all validate-all " msgstr "" #. Tag: para #, no-c-format msgid "Additional requirements (not part of the OCF specs) are placed on agents that will be used for advanced concepts like clones and multi-state resources." msgstr "" #. Tag: title #, no-c-format msgid "Optional Actions for OCF Agents" msgstr "" #. Tag: para #, no-c-format msgid "promote" msgstr "" #. Tag: para #, no-c-format msgid "Promote the local instance of a multi-state resource to the master/primary state." msgstr "" #. Tag: para #, no-c-format msgid "Return 0 on success promoteOCF Action OCF Action OCFActionpromote Actionpromote promote " msgstr "" #. Tag: para #, no-c-format msgid "demote" msgstr "" #. Tag: para #, no-c-format msgid "Demote the local instance of a multi-state resource to the slave/secondary state." msgstr "" #. Tag: para #, no-c-format msgid "Return 0 on success demoteOCF Action OCF Action OCFActiondemote Actiondemote demote " msgstr "" #. Tag: para #, no-c-format msgid "notify" msgstr "" #. Tag: para #, no-c-format msgid "Used by the cluster to send the agent pre and post notification events telling the resource what has happened and will happen." msgstr "" #. Tag: para #, no-c-format msgid "Must not fail. Must exit with 0 notifyOCF Action OCF Action OCFActionnotify Actionnotify notify " msgstr "" #. Tag: para #, no-c-format msgid "One action specified in the OCF specs is not currently used by the cluster:" msgstr "" #. Tag: para #, no-c-format msgid "recover - a variant of the start action, this should try to recover a resource locally." msgstr "" #. Tag: para #, no-c-format msgid "Remember to use ocf-tester ocf-tester to verify that your new agent complies with the OCF standard properly." msgstr "" #. Tag: title #, no-c-format msgid "How are OCF Return Codes Interpreted?" msgstr "" #. Tag: para #, no-c-format msgid "The first thing the cluster does is to check the return code against the expected result. If the result does not match the expected value, then the operation is considered to have failed and recovery action is initiated." msgstr "" #. Tag: para #, no-c-format msgid "There are three types of failure recovery:" msgstr "" #. Tag: title #, no-c-format msgid "Types of recovery performed by the cluster" msgstr "" #. Tag: entry #, no-c-format msgid "Type" msgstr "" #. Tag: entry #, no-c-format msgid "Action Taken by the Cluster" msgstr "" #. Tag: para #, no-c-format msgid "soft" msgstr "" #. Tag: para #, no-c-format msgid "A transient error occurred" msgstr "" #. Tag: para #, no-c-format msgid "Restart the resource or move it to a new location softOCF error OCF error OCFerrorsoft errorsoft soft " msgstr "" #. Tag: para #, no-c-format msgid "hard" msgstr "" #. Tag: para #, no-c-format msgid "A non-transient error that may be specific to the current node occurred" msgstr "" #. Tag: para #, no-c-format msgid "Move the resource elsewhere and prevent it from being retried on the current node hardOCF error OCF error OCFerrorhard errorhard hard " msgstr "" #. Tag: para #, no-c-format msgid "fatal" msgstr "" #. Tag: para #, no-c-format msgid "A non-transient error that will be common to all cluster nodes (eg. a bad configuration was specified)" msgstr "" #. Tag: para #, no-c-format msgid "Stop the resource and prevent it from being started on any cluster node fatalOCF error OCF error OCFerrorfatal errorfatal fatal " msgstr "" #. Tag: para #, no-c-format msgid "Assuming an action is considered to have failed, the following table outlines the different OCF return codes and the type of recovery the cluster will initiate when it is received." msgstr "" #. Tag: title #, no-c-format msgid "OCF Return Codes" msgstr "" #. Tag: title #, no-c-format msgid "OCF Return Codes and their Recovery Types" msgstr "" #. Tag: entry #, no-c-format msgid "RC" msgstr "" #. Tag: entry #, no-c-format msgid "OCF Alias" msgstr "" #. Tag: entry #, no-c-format msgid "RT" msgstr "" #. Tag: para #, no-c-format msgid "0" msgstr "" #. Tag: para #, no-c-format msgid "OCF_SUCCESS" msgstr "" #. Tag: para #, no-c-format msgid "Success. The command completed successfully. This is the expected result for all start, stop, promote and demote commands. Return CodeOCF_SUCCESS OCF_SUCCESS Return Code0OCF_SUCCESS 0OCF_SUCCESS OCF_SUCCESS " msgstr "" #. Tag: para #, no-c-format msgid "1" msgstr "" #. Tag: para #, no-c-format msgid "OCF_ERR_GENERIC" msgstr "" #. Tag: para #, no-c-format msgid "Generic \"there was a problem\" error code. Return CodeOCF_ERR_GENERIC OCF_ERR_GENERIC Return Code1OCF_ERR_GENERIC 1OCF_ERR_GENERIC OCF_ERR_GENERIC " msgstr "" #. Tag: para #, no-c-format msgid "2" msgstr "" #. Tag: para #, no-c-format msgid "OCF_ERR_ARGS" msgstr "" #. Tag: para #, no-c-format msgid "The resource’s configuration is not valid on this machine. Eg. refers to a location/tool not found on the node. Return CodeOCF_ERR_ARGS OCF_ERR_ARGS Return Code2OCF_ERR_ARGS 2OCF_ERR_ARGS OCF_ERR_ARGS " msgstr "" #. Tag: para #, no-c-format msgid "3" msgstr "" #. Tag: para #, no-c-format msgid "OCF_ERR_UNIMPLEMENTED" msgstr "" #. Tag: para #, no-c-format msgid "The requested action is not implemented. Return CodeOCF_ERR_UNIMPLEMENTED OCF_ERR_UNIMPLEMENTED Return Code3OCF_ERR_UNIMPLEMENTED 3OCF_ERR_UNIMPLEMENTED OCF_ERR_UNIMPLEMENTED " msgstr "" #. Tag: para #, no-c-format msgid "4" msgstr "" #. Tag: para #, no-c-format msgid "OCF_ERR_PERM" msgstr "" #. Tag: para #, no-c-format msgid "The resource agent does not have sufficient privileges to complete the task. Return CodeOCF_ERR_PERM OCF_ERR_PERM Return Code4OCF_ERR_PERM 4OCF_ERR_PERM OCF_ERR_PERM " msgstr "" #. Tag: para #, no-c-format msgid "5" msgstr "" #. Tag: para #, no-c-format msgid "OCF_ERR_INSTALLED" msgstr "" #. Tag: para #, no-c-format msgid "The tools required by the resource are not installed on this machine. Return CodeOCF_ERR_INSTALLED OCF_ERR_INSTALLED Return Code5OCF_ERR_INSTALLED 5OCF_ERR_INSTALLED OCF_ERR_INSTALLED " msgstr "" #. Tag: para #, no-c-format msgid "6" msgstr "" #. Tag: para #, no-c-format msgid "OCF_ERR_CONFIGURED" msgstr "" #. Tag: para #, no-c-format msgid "The resource’s configuration is invalid. Eg. required parameters are missing. Return CodeOCF_ERR_CONFIGURED OCF_ERR_CONFIGURED Return Code6OCF_ERR_CONFIGURED 6OCF_ERR_CONFIGURED OCF_ERR_CONFIGURED " msgstr "" #. Tag: para #, no-c-format msgid "7" msgstr "" #. Tag: para #, no-c-format msgid "OCF_NOT_RUNNING" msgstr "" #. Tag: para #, no-c-format msgid "The resource is safely stopped. The cluster will not attempt to stop a resource that returns this for any action. Return CodeOCF_NOT_RUNNING OCF_NOT_RUNNING Return Code7OCF_NOT_RUNNING 7OCF_NOT_RUNNING OCF_NOT_RUNNING " msgstr "" #. Tag: para #, no-c-format msgid "N/A" msgstr "" #. Tag: para #, no-c-format msgid "8" msgstr "" #. Tag: para #, no-c-format msgid "OCF_RUNNING_MASTER" msgstr "" #. Tag: para #, no-c-format msgid "The resource is running in Master mode. Return CodeOCF_RUNNING_MASTER OCF_RUNNING_MASTER Return Code8OCF_RUNNING_MASTER 8OCF_RUNNING_MASTER OCF_RUNNING_MASTER " msgstr "" #. Tag: para #, no-c-format msgid "9" msgstr "" #. Tag: para #, no-c-format msgid "OCF_FAILED_MASTER" msgstr "" #. Tag: para #, no-c-format msgid "The resource is in Master mode but has failed. The resource will be demoted, stopped and then started (and possibly promoted) again. Return CodeOCF_FAILED_MASTER OCF_FAILED_MASTER Return Code9OCF_FAILED_MASTER 9OCF_FAILED_MASTER OCF_FAILED_MASTER " msgstr "" #. Tag: para #, no-c-format msgid "other" msgstr "" #. Tag: para #, no-c-format msgid "NA" msgstr "" #. Tag: para #, no-c-format msgid "Custom error code. Return Codeother other " msgstr "" #. Tag: para #, no-c-format msgid "Although counterintuitive, even actions that return 0 (aka. OCF_SUCCESS) can be considered to have failed." msgstr "" #. Tag: title #, no-c-format msgid "Exceptions" msgstr "" #. Tag: para #, no-c-format msgid "Non-recurring monitor actions (probes) that find a resource active (or in Master mode) will not result in recovery action unless it is also found active elsewhere" msgstr "" #. Tag: para #, no-c-format msgid "The recovery action taken when a resource is found active more than once is determined by the multiple-active property of the resource" msgstr "" #. Tag: para #, no-c-format msgid "Recurring actions that return OCF_ERR_UNIMPLEMENTED do not cause any type of recovery" msgstr "" pacemaker-master/doc/Pacemaker_Explained/pot/Ap-Samples.pot000066400000000000000000000144561217637305600242410ustar00rootroot00000000000000# # AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: 0\n" "POT-Creation-Date: 2012-10-17T05:19:01\n" "PO-Revision-Date: 2012-10-17T05:19:01\n" "Last-Translator: Automatically generated\n" "Language-Team: None\n" "MIME-Version: 1.0\n" "Content-Type: application/x-publican; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. Tag: title #, no-c-format msgid "Sample Configurations" msgstr "" #. Tag: title #, no-c-format msgid "Empty" msgstr "" #. Tag: title #, no-c-format msgid "An Empty Configuration" msgstr "" #. Tag: programlisting #, no-c-format msgid "<cib admin_epoch=\"0\" epoch=\"0\" num_updates=\"0\" have-quorum=\"false\">\n" " <configuration>\n" " <crm_config/>\n" " <nodes/>\n" " <resources/>\n" " <constraints/>\n" " </configuration>\n" " <status/>\n" "</cib>" msgstr "" #. Tag: title #, no-c-format msgid "Simple" msgstr "" #. Tag: title #, no-c-format msgid "Simple Configuration - 2 nodes, some cluster options and a resource" msgstr "" #. Tag: programlisting #, no-c-format msgid "<cib admin_epoch=\"0\" epoch=\"1\" num_updates=\"0\" have-quorum=\"false\"\n" " validate-with=\"pacemaker-1.0\">\n" " <configuration>\n" " <crm_config>\n" " <nvpair id=\"option-1\" name=\"symmetric-cluster\" value=\"true\"/>\n" " <nvpair id=\"option-2\" name=\"no-quorum-policy\" value=\"stop\"/>\n" " </crm_config>\n" " <op_defaults>\n" " <nvpair id=\"op-default-1\" name=\"timeout\" value=\"30s\"/>\n" " </op_defaults>\n" " <rsc_defaults>\n" " <nvpair id=\"rsc-default-1\" name=\"resource-stickiness\" value=\"100\"/>\n" " <nvpair id=\"rsc-default-2\" name=\"migration-threshold\" value=\"10\"/>\n" " </rsc_defaults>\n" " <nodes>\n" " <node id=\"xxx\" uname=\"c001n01\" type=\"normal\"/>\n" " <node id=\"yyy\" uname=\"c001n02\" type=\"normal\"/>\n" " </nodes>\n" " <resources>\n" " <primitive id=\"myAddr\" class=\"ocf\" provider=\"heartbeat\" type=\"IPaddr\">\n" " <operations>\n" " <op id=\"myAddr-monitor\" name=\"monitor\" interval=\"300s\"/>\n" " </operations>\n" " <instance_attributes>\n" " <nvpair name=\"ip\" value=\"10.0.200.30\"/>\n" " </instance_attributes>\n" " </primitive>\n" " </resources>\n" " <constraints>\n" " <rsc_location id=\"myAddr-prefer\" rsc=\"myAddr\" node=\"c001n01\" score=\"INFINITY\"/>\n" " </constraints>\n" " </configuration>\n" " <status/>\n" "</cib>" msgstr "" #. Tag: para #, no-c-format msgid "In this example, we have one resource (an IP address) that we check every five minutes and will run on host c001n01 until either the resource fails 10 times or the host shuts down." msgstr "" #. Tag: title #, no-c-format msgid "Advanced Configuration" msgstr "" #. Tag: title #, no-c-format msgid "Advanced configuration - groups and clones with stonith" msgstr "" #. Tag: programlisting #, no-c-format msgid "<cib admin_epoch=\"0\" epoch=\"1\" num_updates=\"0\" have-quorum=\"false\"\n" " validate-with=\"pacemaker-1.0\">\n" " <configuration>\n" " <crm_config>\n" " <nvpair id=\"option-1\" name=\"symmetric-cluster\" value=\"true\"/>\n" " <nvpair id=\"option-2\" name=\"no-quorum-policy\" value=\"stop\"/>\n" " <nvpair id=\"option-3\" name=\"stonith-enabled\" value=\"true\"/>\n" " </crm_config>\n" " <op_defaults>\n" " <nvpair id=\"op-default-1\" name=\"timeout\" value=\"30s\"/>\n" " </op_defaults>\n" " <rsc_defaults>\n" " <nvpair id=\"rsc-default-1\" name=\"resource-stickiness\" value=\"100\"/>\n" " <nvpair id=\"rsc-default-2\" name=\"migration-threshold\" value=\"10\"/>\n" " </rsc_defaults>\n" " <nodes>\n" " <node id=\"xxx\" uname=\"c001n01\" type=\"normal\"/>\n" " <node id=\"yyy\" uname=\"c001n02\" type=\"normal\"/>\n" " <node id=\"zzz\" uname=\"c001n03\" type=\"normal\"/>\n" " </nodes>\n" " <resources>\n" " <primitive id=\"myAddr\" class=\"ocf\" provider=\"heartbeat\" type=\"IPaddr\">\n" " <operations>\n" " <op id=\"myAddr-monitor\" name=\"monitor\" interval=\"300s\"/>\n" " </operations>\n" " <instance_attributes>\n" " <nvpair name=\"ip\" value=\"10.0.200.30\"/>\n" " </instance_attributes>\n" " </primitive>\n" " <group id=\"myGroup\">\n" " <primitive id=\"database\" class=\"lsb\" type=\"oracle\">\n" " <operations>\n" " <op id=\"database-monitor\" name=\"monitor\" interval=\"300s\"/>\n" " </operations>\n" " </primitive>\n" " <primitive id=\"webserver\" class=\"lsb\" type=\"apache\">\n" " <operations>\n" " <op id=\"webserver-monitor\" name=\"monitor\" interval=\"300s\"/>\n" " </operations>\n" " </primitive>\n" " </group>\n" " <clone id=\"STONITH\">\n" " <meta_attributes id=\"stonith-options\">\n" " <nvpair id=\"stonith-option-1\" name=\"globally-unique\" value=\"false\"/>\n" " </meta_attributes>\n" " <primitive id=\"stonithclone\" class=\"stonith\" type=\"external/ssh\">\n" " <operations>\n" " <op id=\"stonith-op-mon\" name=\"monitor\" interval=\"5s\"/>\n" " </operations>\n" " <instance_attributes id=\"stonith-attrs\">\n" " <nvpair id=\"stonith-attr-1\" name=\"hostlist\" value=\"c001n01,c001n02\"/>\n" " </instance_attributes>\n" " </primitive>\n" " </clone>\n" " </resources>\n" " <constraints>\n" " <rsc_location id=\"myAddr-prefer\" rsc=\"myAddr\" node=\"c001n01\"\n" " score=\"INFINITY\"/>\n" " <rsc_colocation id=\"group-with-ip\" rsc=\"myGroup\" with-rsc=\"myAddr\"\n" " score=\"INFINITY\"/>\n" " </constraints>\n" " </configuration>\n" " <status/>\n" "</cib>" msgstr "" pacemaker-master/doc/Pacemaker_Explained/pot/Ap-Upgrade-Config.pot000066400000000000000000000175401217637305600254240ustar00rootroot00000000000000# # AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: 0\n" "POT-Creation-Date: 2012-10-17T05:19:01\n" "PO-Revision-Date: 2012-10-17T05:19:01\n" "Last-Translator: Automatically generated\n" "Language-Team: None\n" "MIME-Version: 1.0\n" "Content-Type: application/x-publican; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. Tag: title #, no-c-format msgid "Upgrading the Configuration from 0.6" msgstr "" #. Tag: title #, no-c-format msgid "Preparation" msgstr "" #. Tag: para #, no-c-format msgid " Upgrading the Configuration ConfigurationUpgrading Upgrading " msgstr "" #. Tag: para #, no-c-format msgid " DownloadDTD DTD DTDDownload Download " msgstr "" #. Tag: para #, no-c-format msgid "Download the latest DTD and ensure your configuration validates." msgstr "" #. Tag: title #, no-c-format msgid "Perform the upgrade" msgstr "" #. Tag: title #, no-c-format msgid "Upgrade the software" msgstr "" #. Tag: para #, no-c-format msgid "Refer to the appendix: " msgstr "" #. Tag: title #, no-c-format msgid "Upgrade the Configuration" msgstr "" #. Tag: para #, no-c-format msgid "As XML is not the friendliest of languages, it is common for cluster administrators to have scripted some of their activities. In such cases, it is likely that those scripts will not work with the new 1.0 syntax." msgstr "" #. Tag: para #, no-c-format msgid "In order to support such environments, it is actually possible to continue using the old 0.6 syntax." msgstr "" #. Tag: para #, no-c-format msgid "The downside is, however, that not all the new features will be available and there is a performance impact since the cluster must do a non-persistent configuration upgrade before each transition. So while using the old syntax is possible, it is not advisable to continue using it indefinitely." msgstr "" #. Tag: para #, no-c-format msgid "Even if you wish to continue using the old syntax, it is advisable to follow the upgrade procedure to ensure that the cluster is able to use your existing configuration (since it will perform much the same task internally)." msgstr "" #. Tag: para #, no-c-format msgid "Create a shadow copy to work with" msgstr "" #. Tag: programlisting #, no-c-format msgid "# crm_shadow --create upgrade06" msgstr "" #. Tag: para #, no-c-format msgid "Verify the configuration is valid ConfigurationVerify Verify VerifyConfiguration Configuration " msgstr "" #. Tag: programlisting #, no-c-format msgid "# crm_verify --live-check" msgstr "" #. Tag: para #, no-c-format msgid "Fix any errors or warnings" msgstr "" #. Tag: para #, no-c-format msgid "Perform the upgrade:" msgstr "" #. Tag: programlisting #, no-c-format msgid "# cibadmin --upgrade" msgstr "" #. Tag: para #, no-c-format msgid "If this step fails, there are three main possibilities:" msgstr "" #. Tag: para #, no-c-format msgid "The configuration was not valid to start with - go back to step 2" msgstr "" #. Tag: para #, no-c-format msgid "The transformation failed - report a bug or email the project" msgstr "" #. Tag: para #, no-c-format msgid "The transformation was successful but produced an invalid result The most common reason is ID values being repeated or invalid. Pacemaker 1.0 is much stricter regarding this type of validation. " msgstr "" #. Tag: para #, no-c-format msgid "If the result of the transformation is invalid, you may see a number of errors from the validation library. If these are not helpful, visit http://clusterlabs.org/wiki/Validation_FAQ and/or try the procedure described below under " msgstr "" #. Tag: para #, no-c-format msgid "Check the changes" msgstr "" #. Tag: programlisting #, no-c-format msgid "# crm_shadow --diff" msgstr "" #. Tag: para #, no-c-format msgid "If at this point there is anything about the upgrade that you wish to fine-tune (for example, to change some of the automatic IDs) now is the time to do so. Since the shadow configuration is not in use by the cluster, it is safe to edit the file manually:" msgstr "" #. Tag: programlisting #, no-c-format msgid "# crm_shadow --edit" msgstr "" #. Tag: para #, no-c-format msgid "This will open the configuration in your favorite editor (whichever is specified by the standard $EDITOR environment variable)" msgstr "" #. Tag: para #, no-c-format msgid "Preview how the cluster will react" msgstr "" #. Tag: para #, no-c-format msgid "Test what the cluster will do when you upload the new configuration" msgstr "" #. Tag: programlisting #, no-c-format msgid "# crm_simulate --live-check --save-dotfile upgrade06.dot -S\n" "# graphviz upgrade06.dot" msgstr "" #. Tag: para #, no-c-format msgid "Verify that either no resource actions will occur or that you are happy with any that are scheduled. If the output contains actions you do not expect (possibly due to changes to the score calculations), you may need to make further manual changes. See for further details on how to interpret the output of crm_simulate" msgstr "" #. Tag: para #, no-c-format msgid "Upload the changes" msgstr "" #. Tag: programlisting #, no-c-format msgid "# crm_shadow --commit upgrade06 --force" msgstr "" #. Tag: para #, no-c-format msgid "If this step fails, something really strange has occurred. You should report a bug." msgstr "" #. Tag: title #, no-c-format msgid "Manually Upgrading the Configuration" msgstr "" #. Tag: para #, no-c-format msgid " ConfigurationUpgrade manually Upgrade manually It is also possible to perform the configuration upgrade steps manually. To do this" msgstr "" #. Tag: para #, no-c-format msgid "Locate the upgrade06.xsl conversion script or download the latest version from Git" msgstr "" #. Tag: para #, no-c-format msgid "Convert the XML blob: XMLConvert Convert " msgstr "" #. Tag: programlisting #, no-c-format msgid "# xsltproc /path/to/upgrade06.xsl config06.xml > config10.xml" msgstr "" #. Tag: para #, no-c-format msgid "Locate the pacemaker.rng script." msgstr "" #. Tag: para #, no-c-format msgid "Check the XML validity: Validate Configuration ConfigurationValidate XML Validate XML " msgstr "" #. Tag: programlisting #, no-c-format msgid "# xmllint --relaxng /path/to/pacemaker.rng config10.xml" msgstr "" #. Tag: para #, no-c-format msgid "The advantage of this method is that it can be performed without the cluster running and any validation errors should be more informative (despite being generated by the same library!) since they include line numbers." msgstr "" pacemaker-master/doc/Pacemaker_Explained/pot/Ap-Upgrade.pot000066400000000000000000000225541217637305600242220ustar00rootroot00000000000000# # AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: 0\n" "POT-Creation-Date: 2012-10-17T05:19:01\n" "PO-Revision-Date: 2012-10-17T05:19:01\n" "Last-Translator: Automatically generated\n" "Language-Team: None\n" "MIME-Version: 1.0\n" "Content-Type: application/x-publican; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. Tag: title #, no-c-format msgid "Upgrading Cluster Software" msgstr "" #. Tag: title #, no-c-format msgid "Version Compatibility" msgstr "" #. Tag: para #, no-c-format msgid "When releasing newer versions we take care to make sure we are backwards compatible with older versions. While you will always be able to upgrade from version x to x+1, in order to continue to produce high quality software it may occasionally be necessary to drop compatibility with older versions." msgstr "" #. Tag: para #, no-c-format msgid "There will always be an upgrade path from any series-2 release to any other series-2 release." msgstr "" #. Tag: para #, no-c-format msgid "There are three approaches to upgrading your cluster software:" msgstr "" #. Tag: para #, no-c-format msgid "Complete Cluster Shutdown" msgstr "" #. Tag: para #, no-c-format msgid "Rolling (node by node)" msgstr "" #. Tag: para #, no-c-format msgid "Disconnect and Reattach" msgstr "" #. Tag: para #, no-c-format msgid "Each method has advantages and disadvantages, some of which are listed in the table below, and you should chose the one most appropriate to your needs." msgstr "" #. Tag: title #, no-c-format msgid "Summary of Upgrade Methodologies" msgstr "" #. Tag: entry #, no-c-format msgid "Type" msgstr "" #. Tag: entry #, no-c-format msgid "Available between all software versions" msgstr "" #. Tag: entry #, no-c-format msgid "Service Outage During Upgrade" msgstr "" #. Tag: entry #, no-c-format msgid "Service Recovery During Upgrade" msgstr "" #. Tag: entry #, no-c-format msgid "Exercises Failover Logic/Configuration" msgstr "" #. Tag: entry #, no-c-format msgid "Allows change of cluster stack type ClusterSwitching between Stacks Switching between Stacks Changing Cluster Stack For example, switching from Heartbeat to Corosync. Consult the Heartbeat or Corosync documentation to see if upgrading them to a newer version is also supported. " msgstr "" #. Tag: para #, no-c-format msgid "Shutdown UpgradeShutdown Shutdown Shutdown Upgrade " msgstr "" #. Tag: para #, no-c-format msgid "yes" msgstr "" #. Tag: para #, no-c-format msgid "always" msgstr "" #. Tag: para #, no-c-format msgid "N/A" msgstr "" #. Tag: para #, no-c-format msgid "no" msgstr "" #. Tag: para #, no-c-format msgid "Rolling UpgradeRolling Rolling Rolling Upgrade " msgstr "" #. Tag: para #, no-c-format msgid "Reattach UpgradeReattach Reattach Reattach Upgrade " msgstr "" #. Tag: para #, no-c-format msgid "only due to failure" msgstr "" #. Tag: para #, no-c-format msgid "In this scenario one shuts down all cluster nodes and resources and upgrades all the nodes before restarting the cluster." msgstr "" #. Tag: title #, no-c-format msgid "Procedure" msgstr "" #. Tag: para #, no-c-format msgid "On each node:" msgstr "" #. Tag: para #, no-c-format msgid "Shutdown the cluster stack (Heartbeat or Corosync)" msgstr "" #. Tag: para #, no-c-format msgid "Upgrade the Pacemaker software. This may also include upgrading the cluster stack and/or the underlying operating system." msgstr "" #. Tag: para #, no-c-format msgid "Check the configuration manually or with the crm_verify tool if available." msgstr "" #. Tag: para #, no-c-format msgid "Start the cluster stack. This can be either Corosync or Heartbeat and does not need to be the same as the previous cluster stack." msgstr "" #. Tag: para #, no-c-format msgid "In this scenario each node is removed from the cluster, upgraded and then brought back online until all nodes are running the newest version." msgstr "" #. Tag: para #, no-c-format msgid "This method is currently broken between Pacemaker 0.6.x and 1.0.x." msgstr "" #. Tag: para #, no-c-format msgid "Measures have been put into place to ensure rolling upgrades always work for versions after 1.0.0. Please try one of the other upgrade strategies. Detach/Reattach is a particularly good option for most people." msgstr "" #. Tag: para #, no-c-format msgid "On each node: . Shutdown the cluster stack (Heartbeat or Corosync) . Upgrade the Pacemaker software. This may also include upgrading the cluster stack and/or the underlying operating system. .. On the first node, check the configuration manually or with the crm_verify tool if available. .. Start the cluster stack." msgstr "" #. Tag: para #, no-c-format msgid "+ This must be the same type of cluster stack (Corosync or Heartbeat) that the rest of the cluster is using. Upgrading Corosync/Heartbeat may also be possible, please consult the documentation for those projects to see if the two versions will be compatible." msgstr "" #. Tag: para #, no-c-format msgid "+ .. Repeat for each node in the cluster." msgstr "" #. Tag: title #, no-c-format msgid "Version Compatibility Table" msgstr "" #. Tag: entry #, no-c-format msgid "Version being Installed" msgstr "" #. Tag: entry #, no-c-format msgid "Oldest Compatible Version" msgstr "" #. Tag: para #, no-c-format msgid "Pacemaker 1.0.x" msgstr "" #. Tag: para #, no-c-format msgid "Pacemaker 1.0.0" msgstr "" #. Tag: para #, no-c-format msgid "Pacemaker 0.7.x" msgstr "" #. Tag: para #, no-c-format msgid "Pacemaker 0.6 or Heartbeat 2.1.3" msgstr "" #. Tag: para #, no-c-format msgid "Pacemaker 0.6.x" msgstr "" #. Tag: para #, no-c-format msgid "Heartbeat 2.0.8" msgstr "" #. Tag: para #, no-c-format msgid "Heartbeat 2.1.3 (or less)" msgstr "" #. Tag: para #, no-c-format msgid "Heartbeat 2.0.4" msgstr "" #. Tag: para #, no-c-format msgid "Heartbeat 2.0.4 (or less)" msgstr "" #. Tag: para #, no-c-format msgid "Heartbeat 2.0.0" msgstr "" #. Tag: para #, no-c-format msgid "None. Use an alternate upgrade strategy." msgstr "" #. Tag: title #, no-c-format msgid "Crossing Compatibility Boundaries" msgstr "" #. Tag: para #, no-c-format msgid "Rolling upgrades that cross compatibility boundaries must be preformed in multiple steps. For example, to perform a rolling update from Heartbeat 2.0.1 to Pacemaker 0.6.6 one must:" msgstr "" #. Tag: para #, no-c-format msgid "Perform a rolling upgrade from Heartbeat 2.0.1 to Heartbeat 2.0.4" msgstr "" #. Tag: para #, no-c-format msgid "Perform a rolling upgrade from Heartbeat 2.0.4 to Heartbeat 2.1.3" msgstr "" #. Tag: para #, no-c-format msgid "Perform a rolling upgrade from Heartbeat 2.1.3 to Pacemaker 0.6.6" msgstr "" #. Tag: para #, no-c-format msgid "A variant of a complete cluster shutdown, but the resources are left active and get re-detected when the cluster is restarted." msgstr "" #. Tag: para #, no-c-format msgid "Tell the cluster to stop managing services." msgstr "" #. Tag: para #, no-c-format msgid "This is required to allow the services to remain active after the cluster shuts down." msgstr "" #. Tag: programlisting #, no-c-format msgid "# crm_attribute -t crm_config -n is-managed-default -v false" msgstr "" #. Tag: para #, no-c-format msgid "For any resource that has a value for is-managed, make sure it is set to false (so that the cluster will not stop it)" msgstr "" #. Tag: programlisting #, no-c-format msgid "# crm_resource -t primitive -r $rsc_id -p is-managed -v false" msgstr "" #. Tag: para #, no-c-format msgid "Upgrade the cluster stack program - This may also include upgrading the underlying operating system." msgstr "" #. Tag: para #, no-c-format msgid "Start the cluster stack." msgstr "" #. Tag: para #, no-c-format msgid "This can be either Corosync or Heartbeat and does not need to be the same as the previous cluster stack." msgstr "" #. Tag: para #, no-c-format msgid "Verify that the cluster re-detected all resources correctly." msgstr "" #. Tag: para #, no-c-format msgid "Allow the cluster to resume managing resources again:" msgstr "" #. Tag: programlisting #, no-c-format msgid "# crm_attribute -t crm_config -n is-managed-default -v true" msgstr "" #. Tag: para #, no-c-format msgid "For any resource that has a value for is-managed reset it to true (so the cluster can recover the service if it fails) if desired:" msgstr "" #. Tag: programlisting #, no-c-format msgid "# crm_resource -t primitive -r $rsc_id -p is-managed -v true" msgstr "" #. Tag: title #, no-c-format msgid "Notes" msgstr "" #. Tag: para #, no-c-format msgid "Always check your existing configuration is still compatible with the version you are installing before starting the cluster." msgstr "" #. Tag: para #, no-c-format msgid "The oldest version of the CRM to support this upgrade type was in Heartbeat 2.0.4" msgstr "" pacemaker-master/doc/Pacemaker_Explained/pot/Author_Group.pot000066400000000000000000000035561217637305600247140ustar00rootroot00000000000000# # AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: 0\n" "POT-Creation-Date: 2012-10-17T05:19:01\n" "PO-Revision-Date: 2012-10-17T05:19:01\n" "Last-Translator: Automatically generated\n" "Language-Team: None\n" "MIME-Version: 1.0\n" "Content-Type: application/x-publican; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. Tag: firstname #, no-c-format msgid "Andrew" msgstr "" #. Tag: surname #, no-c-format msgid "Beekhof" msgstr "" #. Tag: orgname #, no-c-format msgid "Red Hat" msgstr "" #. Tag: contrib #, no-c-format msgid "Primary author" msgstr "" #. Tag: firstname #, no-c-format msgid "Dan" msgstr "" #. Tag: surname #, no-c-format msgid "Frîncu" msgstr "" #. Tag: contrib #, no-c-format msgid "Romanian translation" msgstr "" #. Tag: firstname #, no-c-format msgid "Philipp" msgstr "" #. Tag: surname #, no-c-format msgid "Marek" msgstr "" #. Tag: orgname #, no-c-format msgid "LINBit" msgstr "" #. Tag: contrib #, no-c-format msgid "Style and formatting updates. Indexing." msgstr "" #. Tag: firstname #, no-c-format msgid "Tanja" msgstr "" #. Tag: surname #, no-c-format msgid "Roth" msgstr "" #. Tag: orgname #, no-c-format msgid "SUSE" msgstr "" #. Tag: contrib #, no-c-format msgid "Utilization chapter" msgstr "" #. Tag: contrib #, no-c-format msgid "Resource Templates chapter" msgstr "" #. Tag: contrib #, no-c-format msgid "Multi-Site Clusters chapter" msgstr "" #. Tag: firstname #, no-c-format msgid "Lars" msgstr "" #. Tag: surname #, no-c-format msgid "Marowsky-Bree" msgstr "" #. Tag: firstname #, no-c-format msgid "Yan" msgstr "" #. Tag: surname #, no-c-format msgid "Gao" msgstr "" #. Tag: firstname #, no-c-format msgid "Thomas" msgstr "" #. Tag: surname #, no-c-format msgid "Schraitle" msgstr "" #. Tag: firstname #, no-c-format msgid "Dejan" msgstr "" #. Tag: surname #, no-c-format msgid "Muhamedagic" msgstr "" pacemaker-master/doc/Pacemaker_Explained/pot/Book_Info.pot000066400000000000000000000031541217637305600241350ustar00rootroot00000000000000# # AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: 0\n" "POT-Creation-Date: 2012-10-17T05:19:01\n" "PO-Revision-Date: 2012-10-17T05:19:01\n" "Last-Translator: Automatically generated\n" "Language-Team: None\n" "MIME-Version: 1.0\n" "Content-Type: application/x-publican; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. Tag: title #, no-c-format msgid "Configuration Explained" msgstr "" #. Tag: subtitle #, no-c-format msgid "An A-Z guide to Pacemaker's Configuration Options" msgstr "" #. Tag: productname #, no-c-format msgid "Pacemaker" msgstr "" #. Tag: para #, no-c-format msgid "The purpose of this document is to definitively explain the concepts used to configure Pacemaker. To achieve this, it will focus exclusively on the XML syntax used to configure the CIB." msgstr "" #. Tag: para #, no-c-format msgid "For those that are allergic to XML, there exist several unified shells and GUIs for Pacemaker. However these tools will not be covered at all in this document I hope, however, that the concepts explained here make the functionality of these tools more easily understood. , precisely because they hide the XML." msgstr "" #. Tag: para #, no-c-format msgid "Additionally, this document is NOT a step-by-step how-to guide for configuring a specific clustering scenario. Although such guides exist, the purpose of this document is to provide an understanding of the building blocks that can be used to construct any type of Pacemaker cluster. Try the Clusters from Scratch document instead." msgstr "" pacemaker-master/doc/Pacemaker_Explained/pot/Ch-Advanced-Options.pot000066400000000000000000001037171217637305600257640ustar00rootroot00000000000000# # AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: 0\n" "POT-Creation-Date: 2012-10-17T05:19:01\n" "PO-Revision-Date: 2012-10-17T05:19:01\n" "Last-Translator: Automatically generated\n" "Language-Team: None\n" "MIME-Version: 1.0\n" "Content-Type: application/x-publican; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. Tag: title #, no-c-format msgid "Advanced Configuration" msgstr "" #. Tag: title #, no-c-format msgid "Connecting from a Remote Machine" msgstr "" #. Tag: para #, no-c-format msgid " ClusterRemote connection Remote connection ClusterRemote administration Remote administration " msgstr "" #. Tag: para #, no-c-format msgid "Provided Pacemaker is installed on a machine, it is possible to connect to the cluster even if the machine itself is not in the same cluster. To do this, one simply sets up a number of environment variables and runs the same commands as when working on a cluster node." msgstr "" #. Tag: title #, no-c-format msgid "Environment Variables Used to Connect to Remote Instances of the CIB" msgstr "" #. Tag: entry #, no-c-format msgid "Environment Variable" msgstr "" #. Tag: entry #, no-c-format msgid "Description" msgstr "" #. Tag: para #, no-c-format msgid "CIB_user" msgstr "" #. Tag: para #, no-c-format msgid "The user to connect as. Needs to be part of the hacluster group on the target host. Defaults to $USER. Environment VariableCIB_user CIB_user " msgstr "" #. Tag: para #, no-c-format msgid "CIB_passwd" msgstr "" #. Tag: para #, no-c-format msgid "The user’s password. Read from the command line if unset. Environment VariableCIB_passwd CIB_passwd " msgstr "" #. Tag: para #, no-c-format msgid "CIB_server" msgstr "" #. Tag: para #, no-c-format msgid "The host to contact. Defaults to localhost. Environment VariableCIB_server CIB_server " msgstr "" #. Tag: para #, no-c-format msgid "CIB_port" msgstr "" #. Tag: para #, no-c-format msgid "The port on which to contact the server; required. Environment VariableCIB_port CIB_port " msgstr "" #. Tag: para #, no-c-format msgid "CIB_encrypted" msgstr "" #. Tag: para #, no-c-format msgid "Encrypt network traffic; defaults to true. Environment VariableCIB_encrypted CIB_encrypted " msgstr "" #. Tag: para #, no-c-format msgid "So, if c001n01 is an active cluster node and is listening on 1234 for connections, and someguy is a member of the hacluster group, then the following would prompt for someguy's password and return the cluster’s current configuration:" msgstr "" #. Tag: programlisting #, no-c-format msgid "# export CIB_port=1234; export CIB_server=c001n01; export CIB_user=someguy;\n" "# cibadmin -Q" msgstr "" #. Tag: para #, no-c-format msgid "For security reasons, the cluster does not listen for remote connections by default. If you wish to allow remote access, you need to set the remote-tls-port (encrypted) or remote-clear-port (unencrypted) top-level options (ie., those kept in the cib tag, like num_updates and epoch)." msgstr "" #. Tag: title #, no-c-format msgid "Extra top-level CIB options for remote access" msgstr "" #. Tag: entry #, no-c-format msgid "Field" msgstr "" #. Tag: para #, no-c-format msgid "remote-tls-port" msgstr "" #. Tag: para #, no-c-format msgid "Listen for encrypted remote connections on this port. Default: none remote-tls-portRemote Connection Option Remote Connection Option Remote ConnectionOptionremote-tls-port Optionremote-tls-port remote-tls-port " msgstr "" #. Tag: para #, no-c-format msgid "remote-clear-port" msgstr "" #. Tag: para #, no-c-format msgid "Listen for plaintext remote connections on this port. Default: none remote-clear-portRemote Connection Option Remote Connection Option Remote ConnectionOptionremote-clear-port Optionremote-clear-port remote-clear-port " msgstr "" #. Tag: title #, no-c-format msgid "Specifying When Recurring Actions are Performed" msgstr "" #. Tag: para #, no-c-format msgid "By default, recurring actions are scheduled relative to when the resource started. So if your resource was last started at 14:32 and you have a backup set to be performed every 24 hours, then the backup will always run at in the middle of the business day - hardly desirable." msgstr "" #. Tag: para #, no-c-format msgid "To specify a date/time that the operation should be relative to, set the operation’s interval-origin. The cluster uses this point to calculate the correct start-delay such that the operation will occur at origin + (interval * N)." msgstr "" #. Tag: para #, no-c-format msgid "So, if the operation’s interval is 24h, it’s interval-origin is set to 02:00 and it is currently 14:32, then the cluster would initiate the operation with a start delay of 11 hours and 28 minutes. If the resource is moved to another node before 2am, then the operation is of course cancelled." msgstr "" #. Tag: para #, no-c-format msgid "The value specified for interval and interval-origin can be any date/time conforming to the ISO8601 standard. By way of example, to specify an operation that would run on the first Monday of 2009 and every Monday after that you would add:" msgstr "" #. Tag: title #, no-c-format msgid "Specifying a Base for Recurring Action Intervals" msgstr "" #. Tag: programlisting #, no-c-format msgid "<op id=\"my-weekly-action\" name=\"custom-action\" interval=\"P7D\" interval-origin=\"2009-W01-1\"/>" msgstr "" #. Tag: title #, no-c-format msgid "Moving Resources" msgstr "" #. Tag: para #, no-c-format msgid " MovingResources Resources ResourceMoving Moving " msgstr "" #. Tag: title #, no-c-format msgid "Manual Intervention" msgstr "" #. Tag: para #, no-c-format msgid "There are primarily two occasions when you would want to move a resource from it’s current location: when the whole node is under maintenance, and when a single resource needs to be moved." msgstr "" #. Tag: para #, no-c-format msgid "Since everything eventually comes down to a score, you could create constraints for every resource to prevent them from running on one node. While the configuration can seem convoluted at times, not even we would require this of administrators." msgstr "" #. Tag: para #, no-c-format msgid "Instead one can set a special node attribute which tells the cluster \"don’t let anything run here\". There is even a helpful tool to help query and set it, called crm_standby. To check the standby status of the current machine, simply run:" msgstr "" #. Tag: programlisting #, no-c-format msgid "# crm_standby --get-value" msgstr "" #. Tag: para #, no-c-format msgid "A value of true indicates that the node is NOT able to host any resources, while a value of false says that it CAN." msgstr "" #. Tag: para #, no-c-format msgid "You can also check the status of other nodes in the cluster by specifying the --node-uname option:" msgstr "" #. Tag: programlisting #, no-c-format msgid "# crm_standby --get-value --node-uname sles-2" msgstr "" #. Tag: para #, no-c-format msgid "To change the current node’s standby status, use --attr-value instead of --get-value." msgstr "" #. Tag: programlisting #, no-c-format msgid "# crm_standby --attr-value" msgstr "" #. Tag: para #, no-c-format msgid "Again, you can change another host’s value by supplying a host name with --node-uname." msgstr "" #. Tag: para #, no-c-format msgid "When only one resource is required to move, we do this by creating location constraints. However, once again we provide a user friendly shortcut as part of the crm_resource command, which creates and modifies the extra constraints for you. If Email was running on sles-1 and you wanted it moved to a specific location, the command would look something like:" msgstr "" #. Tag: programlisting #, no-c-format msgid "# crm_resource -M -r Email -H sles-2" msgstr "" #. Tag: para #, no-c-format msgid "Behind the scenes, the tool will create the following location constraint:" msgstr "" #. Tag: programlisting #, no-c-format msgid "<rsc_location rsc=\"Email\" node=\"sles-2\" score=\"INFINITY\"/>" msgstr "" #. Tag: para #, no-c-format msgid "It is important to note that subsequent invocations of crm_resource -M are not cumulative. So, if you ran these commands" msgstr "" #. Tag: programlisting #, no-c-format msgid "# crm_resource -M -r Email -H sles-2\n" "# crm_resource -M -r Email -H sles-3" msgstr "" #. Tag: para #, no-c-format msgid "then it is as if you had never performed the first command." msgstr "" #. Tag: para #, no-c-format msgid "To allow the resource to move back again, use:" msgstr "" #. Tag: programlisting #, no-c-format msgid "# crm_resource -U -r Email" msgstr "" #. Tag: para #, no-c-format msgid "Note the use of the word allow. The resource can move back to its original location but, depending on resource-stickiness, it might stay where it is. To be absolutely certain that it moves back to sles-1, move it there before issuing the call to crm_resource -U:" msgstr "" #. Tag: programlisting #, no-c-format msgid "# crm_resource -M -r Email -H sles-1\n" "# crm_resource -U -r Email" msgstr "" #. Tag: para #, no-c-format msgid "Alternatively, if you only care that the resource should be moved from its current location, try" msgstr "" #. Tag: programlisting #, no-c-format msgid "# crm_resource -M -r Email`" msgstr "" #. Tag: para #, no-c-format msgid "Which will instead create a negative constraint, like" msgstr "" #. Tag: programlisting #, no-c-format msgid "<rsc_location rsc=\"Email\" node=\"sles-1\" score=\"-INFINITY\"/>" msgstr "" #. Tag: para #, no-c-format msgid "This will achieve the desired effect, but will also have long-term consequences. As the tool will warn you, the creation of a -INFINITY constraint will prevent the resource from running on that node until crm_resource -U is used. This includes the situation where every other cluster node is no longer available!" msgstr "" #. Tag: para #, no-c-format msgid "In some cases, such as when resource-stickiness is set to INFINITY, it is possible that you will end up with the problem described in . The tool can detect some of these cases and deals with them by also creating both a positive and negative constraint. Eg." msgstr "" #. Tag: para #, no-c-format msgid "Email prefers sles-1 with a score of -INFINITY" msgstr "" #. Tag: para #, no-c-format msgid "Email prefers sles-2 with a score of INFINITY" msgstr "" #. Tag: para #, no-c-format msgid "which has the same long-term consequences as discussed earlier." msgstr "" #. Tag: title #, no-c-format msgid "Moving Resources Due to Failure" msgstr "" #. Tag: para #, no-c-format msgid "New in 1.0 is the concept of a migration threshold. The naming of this option was perhaps unfortunate as it is easily confused with true migration, the process of moving a resource from one node to another without stopping it. Xen virtual guests are the most common example of resources that can be migrated in this manner. " msgstr "" #. Tag: para #, no-c-format msgid "Simply define migration-threshold=N for a resource and it will migrate to a new node after N failures. There is no threshold defined by default. To determine the resource’s current failure status and limits, use crm_mon --failcounts." msgstr "" #. Tag: para #, no-c-format msgid "By default, once the threshold has been reached, this node will no longer be allowed to run the failed resource until the administrator manually resets the resource’s failcount using crm_failcount (after hopefully first fixing the failure’s cause). However it is possible to expire them by setting the resource’s failure-timeout option." msgstr "" #. Tag: para #, no-c-format msgid "So a setting of migration-threshold=2 and failure-timeout=60s would cause the resource to move to a new node after 2 failures, and allow it to move back (depending on the stickiness and constraint scores) after one minute." msgstr "" #. Tag: para #, no-c-format msgid "There are two exceptions to the migration threshold concept; they occur when a resource either fails to start or fails to stop. Start failures cause the failcount to be set to INFINITY and thus always cause the resource to move immediately." msgstr "" #. Tag: para #, no-c-format msgid "Stop failures are slightly different and crucial. If a resource fails to stop and STONITH is enabled, then the cluster will fence the node in order to be able to start the resource elsewhere. If STONITH is not enabled, then the cluster has no way to continue and will not try to start the resource elsewhere, but will try to stop it again after the failure timeout." msgstr "" #. Tag: para #, no-c-format msgid "Please read before enabling this option." msgstr "" #. Tag: title #, no-c-format msgid "Moving Resources Due to Connectivity Changes" msgstr "" #. Tag: para #, no-c-format msgid "Setting up the cluster to move resources when external connectivity is lost is a two-step process." msgstr "" #. Tag: title #, no-c-format msgid "Tell Pacemaker to monitor connectivity" msgstr "" #. Tag: para #, no-c-format msgid "To do this, you need to add a ping resource to the cluster. The ping resource uses the system utility of the same name to a test if list of machines (specified by DNS hostname or IPv4/IPv6 address) are reachable and uses the results to maintain a node attribute normally called pingd. The attribute name is customizable; that allows multiple ping groups to be defined. " msgstr "" #. Tag: para #, no-c-format msgid "Older versions of Heartbeat required users to add ping nodes to ha.cf - this is no longer required." msgstr "" #. Tag: para #, no-c-format msgid "Older versions of Pacemaker used a custom binary called pingd for this functionality; this is now deprecated in favor of ping." msgstr "" #. Tag: para #, no-c-format msgid "If your version of Pacemaker does not contain the ping agent, you can download the latest version from https://github.com/ClusterLabs/pacemaker/tree/master/extra/resources/ping" msgstr "" #. Tag: para #, no-c-format msgid "Normally the resource will run on all cluster nodes, which means that you’ll need to create a clone. A template for this can be found below along with a description of the most interesting parameters." msgstr "" #. Tag: title #, no-c-format msgid "Common Options for a ping Resource" msgstr "" #. Tag: para #, no-c-format msgid "dampen" msgstr "" #. Tag: para #, no-c-format msgid "The time to wait (dampening) for further changes to occur. Use this to prevent a resource from bouncing around the cluster when cluster nodes notice the loss of connectivity at slightly different times. dampenPing Resource Option Ping Resource Option Ping ResourceOptiondampen Optiondampen dampen " msgstr "" #. Tag: para #, no-c-format msgid "multiplier" msgstr "" #. Tag: para #, no-c-format msgid "The number of connected ping nodes gets multiplied by this value to get a score. Useful when there are multiple ping nodes configured. multiplierPing Resource Option Ping Resource Option Ping ResourceOptionmultiplier Optionmultiplier multiplier " msgstr "" #. Tag: para #, no-c-format msgid "host_list" msgstr "" #. Tag: para #, no-c-format msgid "The machines to contact in order to determine the current connectivity status. Allowed values include resolvable DNS host names, IPv4 and IPv6 addresses. host_listPing Resource Option Ping Resource Option Ping ResourceOptionhost_list Optionhost_list host_list " msgstr "" #. Tag: title #, no-c-format msgid "An example ping cluster resource that checks node connectivity once every minute" msgstr "" #. Tag: programlisting #, no-c-format msgid "<clone id=\"Connected\">\n" " <primitive id=\"ping\" provider=\"pacemaker\" class=\"ocf\" type=\"ping\">\n" " <instance_attributes id=\"ping-attrs\">\n" " <nvpair id=\"pingd-dampen\" name=\"dampen\" value=\"5s\"/>\n" " <nvpair id=\"pingd-multiplier\" name=\"multiplier\" value=\"1000\"/>\n" " <nvpair id=\"pingd-hosts\" name=\"host_list\" value=\"my.gateway.com www.bigcorp.com\"/>\n" " </instance_attributes>\n" " <operations>\n" " <op id=\"ping-monitor-60s\" interval=\"60s\" name=\"monitor\"/>\n" " </operations>\n" " </primitive>\n" "</clone>" msgstr "" #. Tag: para #, no-c-format msgid "You’re only half done. The next section deals with telling Pacemaker how to deal with the connectivity status that ocf:pacemaker:ping is recording." msgstr "" #. Tag: title #, no-c-format msgid "Tell Pacemaker how to interpret the connectivity data" msgstr "" #. Tag: para #, no-c-format msgid "Before reading the following, please make sure you have read and understood above." msgstr "" #. Tag: para #, no-c-format msgid "There are a number of ways to use the connectivity data provided by Heartbeat. The most common setup is for people to have a single ping node, to prevent the cluster from running a resource on any unconnected node." msgstr "" #. Tag: title #, no-c-format msgid "Don’t run on unconnected nodes" msgstr "" #. Tag: programlisting #, no-c-format msgid "<rsc_location id=\"WebServer-no-connectivity\" rsc=\"Webserver\">\n" " <rule id=\"ping-exclude-rule\" score=\"-INFINITY\" >\n" " <expression id=\"ping-exclude\" attribute=\"pingd\" operation=\"not_defined\"/>\n" " </rule>\n" "</rsc_location>" msgstr "" #. Tag: para #, no-c-format msgid "A more complex setup is to have a number of ping nodes configured. You can require the cluster to only run resources on nodes that can connect to all (or a minimum subset) of them." msgstr "" #. Tag: title #, no-c-format msgid "Run only on nodes connected to three or more ping nodes; this assumes multiplier is set to 1000:" msgstr "" #. Tag: programlisting #, no-c-format msgid "<rsc_location id=\"WebServer-connectivity\" rsc=\"Webserver\">\n" " <rule id=\"ping-prefer-rule\" score=\"-INFINITY\" >\n" " <expression id=\"ping-prefer\" attribute=\"pingd\" operation=\"lt\" value=\"3000\"/>\n" " </rule>\n" "</rsc_location>" msgstr "" #. Tag: para #, no-c-format msgid "Instead you can tell the cluster only to prefer nodes with the best connectivity. Just be sure to set multiplier to a value higher than that of resource-stickiness (and don’t set either of them to INFINITY)." msgstr "" #. Tag: title #, no-c-format msgid "Prefer the node with the most connected ping nodes" msgstr "" #. Tag: programlisting #, no-c-format msgid "<rsc_location id=\"WebServer-connectivity\" rsc=\"Webserver\">\n" " <rule id=\"ping-prefer-rule\" score-attribute=\"pingd\" >\n" " <expression id=\"ping-prefer\" attribute=\"pingd\" operation=\"defined\"/>\n" " </rule>\n" "</rsc_location>" msgstr "" #. Tag: para #, no-c-format msgid "It is perhaps easier to think of this in terms of the simple constraints that the cluster translates it into. For example, if sles-1 is connected to all 5 ping nodes but sles-2 is only connected to 2, then it would be as if you instead had the following constraints in your configuration:" msgstr "" #. Tag: title #, no-c-format msgid "How the cluster translates the pingd constraint" msgstr "" #. Tag: programlisting #, no-c-format msgid "<rsc_location id=\"ping-1\" rsc=\"Webserver\" node=\"sles-1\" score=\"5000\"/>\n" "<rsc_location id=\"ping-2\" rsc=\"Webserver\" node=\"sles-2\" score=\"2000\"/>" msgstr "" #. Tag: para #, no-c-format msgid "The advantage is that you don’t have to manually update any constraints whenever your network connectivity changes." msgstr "" #. Tag: para #, no-c-format msgid "You can also combine the concepts above into something even more complex. The example below shows how you can prefer the node with the most connected ping nodes provided they have connectivity to at least three (again assuming that multiplier is set to 1000)." msgstr "" #. Tag: title #, no-c-format msgid "A more complex example of choosing a location based on connectivity" msgstr "" #. Tag: programlisting #, no-c-format msgid "<rsc_location id=\"WebServer-connectivity\" rsc=\"Webserver\">\n" " <rule id=\"ping-exclude-rule\" score=\"-INFINITY\" >\n" " <expression id=\"ping-exclude\" attribute=\"pingd\" operation=\"lt\" value=\"3000\"/>\n" " </rule>\n" " <rule id=\"ping-prefer-rule\" score-attribute=\"pingd\" >\n" " <expression id=\"ping-prefer\" attribute=\"pingd\" operation=\"defined\"/>\n" " </rule>\n" "</rsc_location>" msgstr "" #. Tag: title #, no-c-format msgid "Resource Migration" msgstr "" #. Tag: para #, no-c-format msgid "Some resources, such as Xen virtual guests, are able to move to another location without loss of state. We call this resource migration; this is different from the normal practice of stopping the resource on the first machine and starting it elsewhere." msgstr "" #. Tag: para #, no-c-format msgid "Not all resources are able to migrate, see the Migration Checklist below, and those that can, won’t do so in all situations. Conceptually there are two requirements from which the other prerequisites follow:" msgstr "" #. Tag: para #, no-c-format msgid "the resource must be active and healthy at the old location" msgstr "" #. Tag: para #, no-c-format msgid "everything required for the resource to run must be available on both the old and new locations" msgstr "" #. Tag: para #, no-c-format msgid "The cluster is able to accommodate both push and pull migration models by requiring the resource agent to support two new actions: migrate_to (performed on the current location) and migrate_from (performed on the destination)." msgstr "" #. Tag: para #, no-c-format msgid "In push migration, the process on the current location transfers the resource to the new location where is it later activated. In this scenario, most of the work would be done in the migrate_to action and, if anything, the activation would occur during migrate_from." msgstr "" #. Tag: para #, no-c-format msgid "Conversely for pull, the migrate_to action is practically empty and migrate_from does most of the work, extracting the relevant resource state from the old location and activating it." msgstr "" #. Tag: para #, no-c-format msgid "There is no wrong or right way to implement migration for your service, as long as it works." msgstr "" #. Tag: title #, no-c-format msgid "Migration Checklist" msgstr "" #. Tag: para #, no-c-format msgid "The resource may not be a clone." msgstr "" #. Tag: para #, no-c-format msgid "The resource must use an OCF style agent." msgstr "" #. Tag: para #, no-c-format msgid "The resource must not be in a failed or degraded state." msgstr "" #. Tag: para #, no-c-format msgid "The resource must not, directly or indirectly, depend on any primitive or group resources." msgstr "" #. Tag: para #, no-c-format msgid "The resource must support two new actions: migrate_to and migrate_from, and advertise them in its metadata." msgstr "" #. Tag: para #, no-c-format msgid "The resource must have the allow-migrate meta-attribute set to true (which is not the default)." msgstr "" #. Tag: para #, no-c-format msgid "If the resource depends on a clone, and at the time the resource needs to be move, the clone has instances that are stopping and instances that are starting, then the resource will be moved in the traditional manner. The Policy Engine is not yet able to model this situation correctly and so takes the safe (yet less optimal) path." msgstr "" #. Tag: title #, no-c-format msgid "Reusing Rules, Options and Sets of Operations" msgstr "" #. Tag: para #, no-c-format msgid "Sometimes a number of constraints need to use the same set of rules, and resources need to set the same options and parameters. To simplify this situation, you can refer to an existing object using an id-ref instead of an id." msgstr "" #. Tag: para #, no-c-format msgid "So if for one resource you have" msgstr "" #. Tag: para #, no-c-format msgid "Then instead of duplicating the rule for all your other resources, you can instead specify:" msgstr "" #. Tag: title #, no-c-format msgid "Referencing rules from other constraints" msgstr "" #. Tag: programlisting #, no-c-format msgid "<rsc_location id=\"WebDB-connectivity\" rsc=\"WebDB\">\n" " <rule id-ref=\"ping-prefer-rule\"/>\n" "</rsc_location>" msgstr "" #. Tag: para #, no-c-format msgid "The cluster will insist that the rule exists somewhere. Attempting to add a reference to a non-existing rule will cause a validation failure, as will attempting to remove a rule that is referenced elsewhere." msgstr "" #. Tag: para #, no-c-format msgid "The same principle applies for meta_attributes and instance_attributes as illustrated in the example below:" msgstr "" #. Tag: title #, no-c-format msgid "Referencing attributes, options, and operations from other resources" msgstr "" #. Tag: programlisting #, no-c-format msgid "<primitive id=\"mySpecialRsc\" class=\"ocf\" type=\"Special\" provider=\"me\">\n" " <instance_attributes id=\"mySpecialRsc-attrs\" score=\"1\" >\n" " <nvpair id=\"default-interface\" name=\"interface\" value=\"eth0\"/>\n" " <nvpair id=\"default-port\" name=\"port\" value=\"9999\"/>\n" " </instance_attributes>\n" " <meta_attributes id=\"mySpecialRsc-options\">\n" " <nvpair id=\"failure-timeout\" name=\"failure-timeout\" value=\"5m\"/>\n" " <nvpair id=\"migration-threshold\" name=\"migration-threshold\" value=\"1\"/>\n" " <nvpair id=\"stickiness\" name=\"resource-stickiness\" value=\"0\"/>\n" " </meta_attributes>\n" " <operations id=\"health-checks\">\n" " <op id=\"health-check\" name=\"monitor\" interval=\"60s\"/>\n" " <op id=\"health-check\" name=\"monitor\" interval=\"30min\"/>\n" " </operations>\n" "</primitive>\n" "<primitive id=\"myOtherlRsc\" class=\"ocf\" type=\"Other\" provider=\"me\">\n" " <instance_attributes id-ref=\"mySpecialRsc-attrs\"/>\n" " <meta_attributes id-ref=\"mySpecialRsc-options\"/>\n" " <operations id-ref=\"health-checks\"/>\n" "</primitive>" msgstr "" #. Tag: title #, no-c-format msgid "Reloading Services After a Definition Change" msgstr "" #. Tag: para #, no-c-format msgid "The cluster automatically detects changes to the definition of services it manages. However, the normal response is to stop the service (using the old definition) and start it again (with the new definition). This works well, but some services are smarter and can be told to use a new set of options without restarting." msgstr "" #. Tag: para #, no-c-format msgid "To take advantage of this capability, your resource agent must:" msgstr "" #. Tag: para #, no-c-format msgid "Accept the reload operation and perform any required actions. The steps required here depend completely on your application!" msgstr "" #. Tag: title #, no-c-format msgid "The DRBD Agent’s Control logic for Supporting the reload Operation" msgstr "" #. Tag: programlisting #, no-c-format msgid "case $1 in\n" " start)\n" " drbd_start\n" " ;;\n" " stop)\n" " drbd_stop\n" " ;;\n" " reload)\n" " drbd_reload\n" " ;;\n" " monitor)\n" " drbd_monitor\n" " ;;\n" " *)\n" " drbd_usage\n" " exit $OCF_ERR_UNIMPLEMENTED\n" " ;;\n" "esac\n" "exit $?" msgstr "" #. Tag: para #, no-c-format msgid "Advertise the reload operation in the actions section of its metadata" msgstr "" #. Tag: title #, no-c-format msgid "The DRBD Agent Advertising Support for the reload Operation" msgstr "" #. Tag: programlisting #, no-c-format msgid "<?xml version=\"1.0\"?>\n" " <!DOCTYPE resource-agent SYSTEM \"ra-api-1.dtd\">\n" " <resource-agent name=\"drbd\">\n" " <version>1.1</version>\n" "\n" " <longdesc>\n" " Master/Slave OCF Resource Agent for DRBD\n" " </longdesc>\n" "\n" " ...\n" "\n" " <actions>\n" " <action name=\"start\" timeout=\"240\" />\n" " <action name=\"reload\" timeout=\"240\" />\n" " <action name=\"promote\" timeout=\"90\" />\n" " <action name=\"demote\" timeout=\"90\" />\n" " <action name=\"notify\" timeout=\"90\" />\n" " <action name=\"stop\" timeout=\"100\" />\n" " <action name=\"meta-data\" timeout=\"5\" />\n" " <action name=\"validate-all\" timeout=\"30\" />\n" " </actions>\n" " </resource-agent>" msgstr "" #. Tag: para #, no-c-format msgid "Advertise one or more parameters that can take effect using reload." msgstr "" #. Tag: para #, no-c-format msgid "Any parameter with the unique set to 0 is eligible to be used in this way." msgstr "" #. Tag: title #, no-c-format msgid "Parameter that can be changed using reload" msgstr "" #. Tag: programlisting #, no-c-format msgid "<parameter name=\"drbdconf\" unique=\"0\">\n" " <longdesc>Full path to the drbd.conf file.</longdesc>\n" " <shortdesc>Path to drbd.conf</shortdesc>\n" " <content type=\"string\" default=\"${OCF_RESKEY_drbdconf_default}\"/>\n" "</parameter>" msgstr "" #. Tag: para #, no-c-format msgid "Once these requirements are satisfied, the cluster will automatically know to reload the resource (instead of restarting) when a non-unique fields changes." msgstr "" #. Tag: para #, no-c-format msgid "The metadata is re-read when the resource is started. This may mean that the resource will be restarted the first time, even though you changed a parameter with unique=0" msgstr "" #. Tag: para #, no-c-format msgid "If both a unique and non-unique field are changed simultaneously, the resource will still be restarted." msgstr "" pacemaker-master/doc/Pacemaker_Explained/pot/Ch-Advanced-Resources.pot000066400000000000000000001551171217637305600263040ustar00rootroot00000000000000# # AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: 0\n" "POT-Creation-Date: 2012-10-17T05:19:01\n" "PO-Revision-Date: 2012-10-17T05:19:01\n" "Last-Translator: Automatically generated\n" "Language-Team: None\n" "MIME-Version: 1.0\n" "Content-Type: application/x-publican; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. Tag: title #, no-c-format msgid "Advanced Resource Types" msgstr "" #. Tag: title #, no-c-format msgid "Groups - A Syntactic Shortcut" msgstr "" #. Tag: para #, no-c-format msgid " Group Resources ResourcesGroups Groups " msgstr "" #. Tag: para #, no-c-format msgid "One of the most common elements of a cluster is a set of resources that need to be located together, start sequentially, and stop in the reverse order. To simplify this configuration we support the concept of groups." msgstr "" #. Tag: title #, no-c-format msgid "An example group" msgstr "" #. Tag: programlisting #, no-c-format msgid "<group id=\"shortcut\">\n" " <primitive id=\"Public-IP\" class=\"ocf\" type=\"IPaddr\" provider=\"heartbeat\">\n" " <instance_attributes id=\"params-public-ip\">\n" " <nvpair id=\"public-ip-addr\" name=\"ip\" value=\"1.2.3.4\"/>\n" " </instance_attributes>\n" " </primitive>\n" " <primitive id=\"Email\" class=\"lsb\" type=\"exim\"/>\n" " </group>" msgstr "" #. Tag: para #, no-c-format msgid "Although the example above contains only two resources, there is no limit to the number of resources a group can contain. The example is also sufficient to explain the fundamental properties of a group:" msgstr "" #. Tag: para #, no-c-format msgid "Resources are started in the order they appear in (Public-IP first, then Email)" msgstr "" #. Tag: para #, no-c-format msgid "Resources are stopped in the reverse order to which they appear in (Email first, then Public-IP)" msgstr "" #. Tag: para #, no-c-format msgid "If a resource in the group can’t run anywhere, then nothing after that is allowed to run, too." msgstr "" #. Tag: para #, no-c-format msgid "If Public-IP can’t run anywhere, neither can Email;" msgstr "" #. Tag: para #, no-c-format msgid "but if Email can’t run anywhere, this does not affect Public-IP in any way" msgstr "" #. Tag: para #, no-c-format msgid "The group above is logically equivalent to writing:" msgstr "" #. Tag: title #, no-c-format msgid "How the cluster sees a group resource" msgstr "" #. Tag: programlisting #, no-c-format msgid "<configuration>\n" " <resources>\n" " <primitive id=\"Public-IP\" class=\"ocf\" type=\"IPaddr\" provider=\"heartbeat\">\n" " <instance_attributes id=\"params-public-ip\">\n" " <nvpair id=\"public-ip-addr\" name=\"ip\" value=\"1.2.3.4\"/>\n" " </instance_attributes>\n" " </primitive>\n" " <primitive id=\"Email\" class=\"lsb\" type=\"exim\"/>\n" " </resources>\n" " <constraints>\n" " <rsc_colocation id=\"xxx\" rsc=\"Email\" with-rsc=\"Public-IP\" score=\"INFINITY\"/>\n" " <rsc_order id=\"yyy\" first=\"Public-IP\" then=\"Email\"/>\n" " </constraints>\n" "</configuration>" msgstr "" #. Tag: para #, no-c-format msgid "Obviously as the group grows bigger, the reduced configuration effort can become significant." msgstr "" #. Tag: para #, no-c-format msgid "Another (typical) example of a group is a DRBD volume, the filesystem mount, an IP address, and an application that uses them." msgstr "" #. Tag: title #, no-c-format msgid "Group Properties" msgstr "" #. Tag: title #, no-c-format msgid "Properties of a Group Resource" msgstr "" #. Tag: entry #, no-c-format msgid "Field" msgstr "" #. Tag: entry #, no-c-format msgid "Description" msgstr "" #. Tag: para #, no-c-format msgid "id" msgstr "" #. Tag: para #, no-c-format msgid "Your name for the group idGroup Resource Property Group Resource Property ResourceGroup Propertyid Group Propertyid id " msgstr "" #. Tag: title #, no-c-format msgid "Group Options" msgstr "" #. Tag: para #, no-c-format msgid "Options inherited from primitive resources: priority, target-role, is-managed" msgstr "" #. Tag: title #, no-c-format msgid "Group Instance Attributes" msgstr "" #. Tag: para #, no-c-format msgid "Groups have no instance attributes, however any that are set here will be inherited by the group’s children." msgstr "" #. Tag: title #, no-c-format msgid "Group Contents" msgstr "" #. Tag: para #, no-c-format msgid "Groups may only contain a collection of cluster resources. To refer to the child of a group resource, just use the child’s id instead of the group’s." msgstr "" #. Tag: title #, no-c-format msgid "Group Constraints" msgstr "" #. Tag: para #, no-c-format msgid "Although it is possible to reference the group’s children in constraints, it is usually preferable to use the group’s name instead." msgstr "" #. Tag: title #, no-c-format msgid "Example constraints involving groups" msgstr "" #. Tag: programlisting #, no-c-format msgid "<constraints>\n" " <rsc_location id=\"group-prefers-node1\" rsc=\"shortcut\" node=\"node1\" score=\"500\"/>\n" " <rsc_colocation id=\"webserver-with-group\" rsc=\"Webserver\" with-rsc=\"shortcut\"/>\n" " <rsc_order id=\"start-group-then-webserver\" first=\"Webserver\" then=\"shortcut\"/>\n" "</constraints>" msgstr "" #. Tag: title #, no-c-format msgid "Group Stickiness" msgstr "" #. Tag: para #, no-c-format msgid " resource-stickinessGroups Groups " msgstr "" #. Tag: para #, no-c-format msgid "Stickiness, the measure of how much a resource wants to stay where it is, is additive in groups. Every active resource of the group will contribute its stickiness value to the group’s total. So if the default resource-stickiness is 100, and a group has seven members, five of which are active, then the group as a whole will prefer its current location with a score of 500." msgstr "" #. Tag: title #, no-c-format msgid "Clones - Resources That Get Active on Multiple Hosts" msgstr "" #. Tag: para #, no-c-format msgid " Clone Resources ResourcesClones Clones " msgstr "" #. Tag: para #, no-c-format msgid "Clones were initially conceived as a convenient way to start N instances of an IP resource and have them distributed throughout the cluster for load balancing. They have turned out to quite useful for a number of purposes including integrating with Red Hat’s DLM, the fencing subsystem, and OCFS2." msgstr "" #. Tag: para #, no-c-format msgid "You can clone any resource, provided the resource agent supports it." msgstr "" #. Tag: para #, no-c-format msgid "Three types of cloned resources exist:" msgstr "" #. Tag: para #, no-c-format msgid "Anonymous" msgstr "" #. Tag: para #, no-c-format msgid "Globally Unique" msgstr "" #. Tag: para #, no-c-format msgid "Stateful" msgstr "" #. Tag: para #, no-c-format msgid "Anonymous clones are the simplest type. These resources behave completely identically everywhere they are running. Because of this, there can only be one copy of an anonymous clone active per machine." msgstr "" #. Tag: para #, no-c-format msgid "Globally unique clones are distinct entities. A copy of the clone running on one machine is not equivalent to another instance on another node. Nor would any two copies on the same node be equivalent." msgstr "" #. Tag: para #, no-c-format msgid "Stateful clones are covered later in ." msgstr "" #. Tag: title #, no-c-format msgid "An example clone" msgstr "" #. Tag: programlisting #, no-c-format msgid "<clone id=\"apache-clone\">\n" " <meta_attributes id=\"apache-clone-meta\">\n" " <nvpair id=\"apache-unique\" name=\"globally-unique\" value=\"false\"/>\n" " </meta_attributes>\n" " <primitive id=\"apache\" class=\"lsb\" type=\"apache\"/>\n" "</clone>" msgstr "" #. Tag: title #, no-c-format msgid "Clone Properties" msgstr "" #. Tag: title #, no-c-format msgid "Properties of a Clone Resource" msgstr "" #. Tag: para #, no-c-format msgid "Your name for the clone idClone Property Clone Property ClonePropertyid Propertyid id " msgstr "" #. Tag: title #, no-c-format msgid "Clone Options" msgstr "" #. Tag: title #, no-c-format msgid "Clone specific configuration options" msgstr "" #. Tag: para #, no-c-format msgid "clone-max" msgstr "" #. Tag: para #, no-c-format msgid "How many copies of the resource to start. Defaults to the number of nodes in the cluster. clone-maxClone Option Clone Option CloneOptionclone-max Optionclone-max clone-max " msgstr "" #. Tag: para #, no-c-format msgid "clone-node-max" msgstr "" #. Tag: para #, no-c-format msgid "How many copies of the resource can be started on a single node; default 1. clone-node-maxClone Option Clone Option CloneOptionclone-node-max Optionclone-node-max clone-node-max " msgstr "" #. Tag: para #, no-c-format msgid "notify" msgstr "" #. Tag: para #, no-c-format msgid "When stopping or starting a copy of the clone, tell all the other copies beforehand and when the action was successful. Allowed values: false, true notifyClone Option Clone Option CloneOptionnotify Optionnotify notify " msgstr "" #. Tag: para #, no-c-format msgid "globally-unique" msgstr "" #. Tag: para #, no-c-format msgid "Does each copy of the clone perform a different function? Allowed values: false, true globally-uniqueClone Option Clone Option CloneOptionglobally-unique Optionglobally-unique globally-unique " msgstr "" #. Tag: para #, no-c-format msgid "ordered" msgstr "" #. Tag: para #, no-c-format msgid "Should the copies be started in series (instead of in parallel). Allowed values: false, true orderedClone Option Clone Option CloneOptionordered Optionordered ordered " msgstr "" #. Tag: para #, no-c-format msgid "interleave" msgstr "" #. Tag: para #, no-c-format msgid "Changes the behavior of ordering constraints (between clones/masters) so that instances can start/stop as soon as their peer instance has (rather than waiting for every instance of the other clone has). Allowed values: false, true interleaveClone Option Clone Option CloneOptioninterleave Optioninterleave interleave " msgstr "" #. Tag: title #, no-c-format msgid "Clone Instance Attributes" msgstr "" #. Tag: para #, no-c-format msgid "Clones have no instance attributes; however, any that are set here will be inherited by the clone’s children." msgstr "" #. Tag: title #, no-c-format msgid "Clone Contents" msgstr "" #. Tag: para #, no-c-format msgid "Clones must contain exactly one group or one regular resource." msgstr "" #. Tag: para #, no-c-format msgid "You should never reference the name of a clone’s child. If you think you need to do this, you probably need to re-evaluate your design." msgstr "" #. Tag: title #, no-c-format msgid "Clone Constraints" msgstr "" #. Tag: para #, no-c-format msgid "In most cases, a clone will have a single copy on each active cluster node. If this is not the case, you can indicate which nodes the cluster should preferentially assign copies to with resource location constraints. These constraints are written no differently to those for regular resources except that the clone’s id is used." msgstr "" #. Tag: para #, no-c-format msgid "Ordering constraints behave slightly differently for clones. In the example below, apache-stats will wait until all copies of the clone that need to be started have done so before being started itself. Only if no copies can be started apache-stats will be prevented from being active. Additionally, the clone will wait for apache-stats to be stopped before stopping the clone." msgstr "" #. Tag: para #, no-c-format msgid "Colocation of a regular (or group) resource with a clone means that the resource can run on any machine with an active copy of the clone. The cluster will choose a copy based on where the clone is running and the resource’s own location preferences." msgstr "" #. Tag: para #, no-c-format msgid "Colocation between clones is also possible. In such cases, the set of allowed locations for the clone is limited to nodes on which the clone is (or will be) active. Allocation is then performed as normally." msgstr "" #. Tag: title #, no-c-format msgid "Example constraints involving clones" msgstr "" #. Tag: programlisting #, no-c-format msgid "<constraints>\n" " <rsc_location id=\"clone-prefers-node1\" rsc=\"apache-clone\" node=\"node1\" score=\"500\"/>\n" " <rsc_colocation id=\"stats-with-clone\" rsc=\"apache-stats\" with=\"apache-clone\"/>\n" " <rsc_order id=\"start-clone-then-stats\" first=\"apache-clone\" then=\"apache-stats\"/>\n" "</constraints>" msgstr "" #. Tag: title #, no-c-format msgid "Clone Stickiness" msgstr "" #. Tag: para #, no-c-format msgid " resource-stickinessClones Clones " msgstr "" #. Tag: para #, no-c-format msgid "To achieve a stable allocation pattern, clones are slightly sticky by default. If no value for resource-stickiness is provided, the clone will use a value of 1. Being a small value, it causes minimal disturbance to the score calculations of other resources but is enough to prevent Pacemaker from needlessly moving copies around the cluster." msgstr "" #. Tag: title #, no-c-format msgid "Clone Resource Agent Requirements" msgstr "" #. Tag: para #, no-c-format msgid "Any resource can be used as an anonymous clone, as it requires no additional support from the resource agent. Whether it makes sense to do so depends on your resource and its resource agent." msgstr "" #. Tag: para #, no-c-format msgid "Globally unique clones do require some additional support in the resource agent. In particular, it must only respond with other probes for instances of the clone should result in they should return one of the other OCF error codes." msgstr "" #. Tag: para #, no-c-format msgid "Copies of a clone are identified by appending a colon and a numerical offset, eg. apache:2." msgstr "" #. Tag: para #, no-c-format msgid "Resource agents can find out how many copies there are by examining the OCF_RESKEY_CRM_meta_clone_max environment variable and which copy it is by examining OCF_RESKEY_CRM_meta_clone." msgstr "" #. Tag: para #, no-c-format msgid "You should not make any assumptions (based on OCF_RESKEY_CRM_meta_clone) about which copies are active. In particular, the list of active copies will not always be an unbroken sequence, nor always start at 0." msgstr "" #. Tag: title #, no-c-format msgid "Clone Notifications" msgstr "" #. Tag: para #, no-c-format msgid "Supporting notifications requires the notify action to be implemented. Once supported, the notify action will be passed a number of extra variables which, when combined with additional context, can be used to calculate the current state of the cluster and what is about to happen to it." msgstr "" #. Tag: title #, no-c-format msgid "Environment variables supplied with Clone notify actions" msgstr "" #. Tag: entry #, no-c-format msgid "Variable" msgstr "" #. Tag: para #, no-c-format msgid "OCF_RESKEY_CRM_meta_notify_type" msgstr "" #. Tag: para #, no-c-format msgid "Allowed values: pre, post Environment VariableOCF_RESKEY_CRM_meta_notify_type OCF_RESKEY_CRM_meta_notify_type type typeNotification Environment Variable Notification Environment Variable " msgstr "" #. Tag: para #, no-c-format msgid "OCF_RESKEY_CRM_meta_notify_operation" msgstr "" #. Tag: para #, no-c-format msgid "Allowed values: start, stop Environment VariableOCF_RESKEY_CRM_meta_notify_operation OCF_RESKEY_CRM_meta_notify_operation operation operationNotification Environment Variable Notification Environment Variable " msgstr "" #. Tag: para #, no-c-format msgid "OCF_RESKEY_CRM_meta_notify_start_resource" msgstr "" #. Tag: para #, no-c-format msgid "Resources to be started Environment VariableOCF_RESKEY_CRM_meta_notify_start_resource OCF_RESKEY_CRM_meta_notify_start_resource start_resource start_resourceNotification Environment Variable Notification Environment Variable " msgstr "" #. Tag: para #, no-c-format msgid "OCF_RESKEY_CRM_meta_notify_stop_resource" msgstr "" #. Tag: para #, no-c-format msgid "Resources to be stopped Environment VariableOCF_RESKEY_CRM_meta_notify_stop_resource OCF_RESKEY_CRM_meta_notify_stop_resource stop_resource stop_resourceNotification Environment Variable Notification Environment Variable " msgstr "" #. Tag: para #, no-c-format msgid "OCF_RESKEY_CRM_meta_notify_active_resource" msgstr "" #. Tag: para #, no-c-format msgid "Resources that are running Environment VariableOCF_RESKEY_CRM_meta_notify_active_resource OCF_RESKEY_CRM_meta_notify_active_resource active_resource active_resourceNotification Environment Variable Notification Environment Variable " msgstr "" #. Tag: para #, no-c-format msgid "OCF_RESKEY_CRM_meta_notify_inactive_resource" msgstr "" #. Tag: para #, no-c-format msgid "Resources that are not running Environment VariableOCF_RESKEY_CRM_meta_notify_inactive_resource OCF_RESKEY_CRM_meta_notify_inactive_resource inactive_resource inactive_resourceNotification Environment Variable Notification Environment Variable " msgstr "" #. Tag: para #, no-c-format msgid "OCF_RESKEY_CRM_meta_notify_start_uname" msgstr "" #. Tag: para #, no-c-format msgid "Nodes on which resources will be started Environment VariableOCF_RESKEY_CRM_meta_notify_start_uname OCF_RESKEY_CRM_meta_notify_start_uname start_uname start_unameNotification Environment Variable Notification Environment Variable " msgstr "" #. Tag: para #, no-c-format msgid "OCF_RESKEY_CRM_meta_notify_stop_uname" msgstr "" #. Tag: para #, no-c-format msgid "Nodes on which resources will be stopped Environment VariableOCF_RESKEY_CRM_meta_notify_stop_uname OCF_RESKEY_CRM_meta_notify_stop_uname stop_uname stop_unameNotification Environment Variable Notification Environment Variable " msgstr "" #. Tag: para #, no-c-format msgid "OCF_RESKEY_CRM_meta_notify_active_uname" msgstr "" #. Tag: para #, no-c-format msgid "Nodes on which resources are running Environment VariableOCF_RESKEY_CRM_meta_notify_active_uname OCF_RESKEY_CRM_meta_notify_active_uname active_uname active_unameNotification Environment Variable Notification Environment Variable " msgstr "" #. Tag: para #, no-c-format msgid "OCF_RESKEY_CRM_meta_notify_inactive_uname" msgstr "" #. Tag: para #, no-c-format msgid "Nodes on which resources are not running Environment VariableOCF_RESKEY_CRM_meta_notify_inactive_uname OCF_RESKEY_CRM_meta_notify_inactive_uname inactive_uname inactive_unameNotification Environment Variable Notification Environment Variable " msgstr "" #. Tag: para #, no-c-format msgid "The variables come in pairs, such as OCF_RESKEY_CRM_meta_notify_start_resource and OCF_RESKEY_CRM_meta_notify_start_uname and should be treated as an array of whitespace separated elements." msgstr "" #. Tag: para #, no-c-format msgid "Thus in order to indicate that clone:0 will be started on sles-1, clone:2 will be started on sles-3, and clone:3 will be started on sles-2, the cluster would set" msgstr "" #. Tag: title #, no-c-format msgid "Example notification variables" msgstr "" #. Tag: programlisting #, no-c-format msgid "OCF_RESKEY_CRM_meta_notify_start_resource=\"clone:0 clone:2 clone:3\"\n" "OCF_RESKEY_CRM_meta_notify_start_uname=\"sles-1 sles-3 sles-2\"" msgstr "" #. Tag: title #, no-c-format msgid "Proper Interpretation of Notification Environment Variables" msgstr "" #. Tag: title #, no-c-format msgid "Pre-notification (stop):" msgstr "" #. Tag: para #, no-c-format msgid "Active resources: $OCF_RESKEY_CRM_meta_notify_active_resource" msgstr "" #. Tag: para #, no-c-format msgid "Inactive resources: $OCF_RESKEY_CRM_meta_notify_inactive_resource" msgstr "" #. Tag: para #, no-c-format msgid "Resources to be started: $OCF_RESKEY_CRM_meta_notify_start_resource" msgstr "" #. Tag: para #, no-c-format msgid "Resources to be stopped: $OCF_RESKEY_CRM_meta_notify_stop_resource" msgstr "" #. Tag: title #, no-c-format msgid "Post-notification (stop) / Pre-notification (start):" msgstr "" #. Tag: para #, no-c-format msgid "Active resources" msgstr "" #. Tag: para #, no-c-format msgid "$OCF_RESKEY_CRM_meta_notify_active_resource" msgstr "" #. Tag: para #, no-c-format msgid "minus $OCF_RESKEY_CRM_meta_notify_stop_resource" msgstr "" #. Tag: para #, no-c-format msgid "Inactive resources" msgstr "" #. Tag: para #, no-c-format msgid "$OCF_RESKEY_CRM_meta_notify_inactive_resource" msgstr "" #. Tag: para #, no-c-format msgid "plus $OCF_RESKEY_CRM_meta_notify_stop_resource" msgstr "" #. Tag: para #, no-c-format msgid "Resources that were started: $OCF_RESKEY_CRM_meta_notify_start_resource" msgstr "" #. Tag: para #, no-c-format msgid "Resources that were stopped: $OCF_RESKEY_CRM_meta_notify_stop_resource" msgstr "" #. Tag: title #, no-c-format msgid "Post-notification (start):" msgstr "" #. Tag: para #, no-c-format msgid "Active resources:" msgstr "" #. Tag: para #, no-c-format msgid "plus $OCF_RESKEY_CRM_meta_notify_start_resource" msgstr "" #. Tag: para #, no-c-format msgid "Inactive resources:" msgstr "" #. Tag: para #, no-c-format msgid "minus $OCF_RESKEY_CRM_meta_notify_start_resource" msgstr "" #. Tag: title #, no-c-format msgid "Multi-state - Resources That Have Multiple Modes" msgstr "" #. Tag: para #, no-c-format msgid " Multi-state Resources ResourcesMulti-state Multi-state " msgstr "" #. Tag: para #, no-c-format msgid "Multi-state resources are a specialization of Clone resources; please ensure you understand the section on clones before continuing! They allow the instances to be in one of two operating modes; these are called Master and Slave, but can mean whatever you wish them to mean. The only limitation is that when an instance is started, it must come up in the Slave state." msgstr "" #. Tag: title #, no-c-format msgid "Multi-state Properties" msgstr "" #. Tag: title #, no-c-format msgid "Properties of a Multi-State Resource" msgstr "" #. Tag: para #, no-c-format msgid "Your name for the multi-state resource idMulti-State Property Multi-State Property Multi-StatePropertyid Propertyid id " msgstr "" #. Tag: title #, no-c-format msgid "Multi-state Options" msgstr "" #. Tag: para #, no-c-format msgid "Options inherited from primitive resources: priority, target-role, is-managed" msgstr "" #. Tag: para #, no-c-format msgid "Options inherited from clone resources: clone-max, clone-node-max, notify, globally-unique, ordered, interleave" msgstr "" #. Tag: title #, no-c-format msgid "Multi-state specific resource configuration options" msgstr "" #. Tag: para #, no-c-format msgid "master-max" msgstr "" #. Tag: para #, no-c-format msgid "How many copies of the resource can be promoted to master status; default 1. master-maxMulti-State Option Multi-State Option Multi-StateOptionmaster-max Optionmaster-max master-max " msgstr "" #. Tag: para #, no-c-format msgid "master-node-max" msgstr "" #. Tag: para #, no-c-format msgid "How many copies of the resource can be promoted to master status on a single node; default 1. master-node-maxMulti-State Option Multi-State Option Multi-StateOptionmaster-node-max Optionmaster-node-max master-node-max " msgstr "" #. Tag: title #, no-c-format msgid "Multi-state Instance Attributes" msgstr "" #. Tag: para #, no-c-format msgid "Multi-state resources have no instance attributes; however, any that are set here will be inherited by master’s children." msgstr "" #. Tag: title #, no-c-format msgid "Multi-state Contents" msgstr "" #. Tag: para #, no-c-format msgid "Masters must contain exactly one group or one regular resource." msgstr "" #. Tag: para #, no-c-format msgid "You should never reference the name of a master’s child. If you think you need to do this, you probably need to re-evaluate your design." msgstr "" #. Tag: title #, no-c-format msgid "Monitoring Multi-State Resources" msgstr "" #. Tag: para #, no-c-format msgid "The normal type of monitor actions are not sufficient to monitor a multi-state resource in the Master state. To detect failures of the Master instance, you need to define an additional monitor action with role=\"Master\"." msgstr "" #. Tag: para #, no-c-format msgid "It is crucial that every monitor operation has a different interval!" msgstr "" #. Tag: para #, no-c-format msgid "This is because Pacemaker currently differentiates between operations only by resource and interval; so if eg. a master/slave resource has the same monitor interval for both roles, Pacemaker would ignore the role when checking the status - which would cause unexpected return codes, and therefore unnecessary complications." msgstr "" #. Tag: title #, no-c-format msgid "Monitoring both states of a multi-state resource" msgstr "" #. Tag: programlisting #, no-c-format msgid "<master id=\"myMasterRsc\">\n" " <primitive id=\"myRsc\" class=\"ocf\" type=\"myApp\" provider=\"myCorp\">\n" " <operations>\n" " <op id=\"public-ip-slave-check\" name=\"monitor\" interval=\"60\"/>\n" " <op id=\"public-ip-master-check\" name=\"monitor\" interval=\"61\" role=\"Master\"/>\n" " </operations>\n" " </primitive>\n" "</master>" msgstr "" #. Tag: title #, no-c-format msgid "Multi-state Constraints" msgstr "" #. Tag: para #, no-c-format msgid "In most cases, a multi-state resources will have a single copy on each active cluster node. If this is not the case, you can indicate which nodes the cluster should preferentially assign copies to with resource location constraints. These constraints are written no differently to those for regular resources except that the master’s id is used." msgstr "" #. Tag: para #, no-c-format msgid "When considering multi-state resources in constraints, for most purposes it is sufficient to treat them as clones. The exception is when the rsc-role and/or with-rsc-role fields (for colocation constraints) and first-action and/or then-action fields (for ordering constraints) are used." msgstr "" #. Tag: title #, no-c-format msgid "Additional constraint options relevant to multi-state resources" msgstr "" #. Tag: para #, no-c-format msgid "rsc-role" msgstr "" #. Tag: para #, no-c-format msgid "An additional attribute of colocation constraints that specifies the role that rsc must be in. Allowed values: Started, Master, Slave. rsc-roleOrdering Constraints Ordering Constraints ConstraintsOrderingrsc-role Orderingrsc-role rsc-role " msgstr "" #. Tag: para #, no-c-format msgid "with-rsc-role" msgstr "" #. Tag: para #, no-c-format msgid "An additional attribute of colocation constraints that specifies the role that with-rsc must be in. Allowed values: Started, Master, Slave. with-rsc-roleOrdering Constraints Ordering Constraints ConstraintsOrderingwith-rsc-role Orderingwith-rsc-role with-rsc-role " msgstr "" #. Tag: para #, no-c-format msgid "first-action" msgstr "" #. Tag: para #, no-c-format msgid "An additional attribute of ordering constraints that specifies the action that the first resource must complete before executing the specified action for the then resource. Allowed values: start, stop, promote, demote. first-actionOrdering Constraints Ordering Constraints ConstraintsOrderingfirst-action Orderingfirst-action first-action " msgstr "" #. Tag: para #, no-c-format msgid "then-action" msgstr "" #. Tag: para #, no-c-format msgid "An additional attribute of ordering constraints that specifies the action that the then resource can only execute after the first-action on the first resource has completed. Allowed values: start, stop, promote, demote. Defaults to the value (specified or implied) of first-action. then-actionOrdering Constraints Ordering Constraints ConstraintsOrderingthen-action Orderingthen-action then-action " msgstr "" #. Tag: para #, no-c-format msgid "In the example below, myApp will wait until one of the database copies has been started and promoted to master before being started itself. Only if no copies can be promoted will apache-stats be prevented from being active. Additionally, the database will wait for myApp to be stopped before it is demoted." msgstr "" #. Tag: title #, no-c-format msgid "Example constraints involving multi-state resources" msgstr "" #. Tag: programlisting #, no-c-format msgid "<constraints>\n" " <rsc_location id=\"db-prefers-node1\" rsc=\"database\" node=\"node1\" score=\"500\"/>\n" " <rsc_colocation id=\"backup-with-db-slave\" rsc=\"backup\"\n" " with-rsc=\"database\" with-rsc-role=\"Slave\"/>\n" " <rsc_colocation id=\"myapp-with-db-master\" rsc=\"myApp\"\n" " with-rsc=\"database\" with-rsc-role=\"Master\"/>\n" " <rsc_order id=\"start-db-before-backup\" first=\"database\" then=\"backup\"/>\n" " <rsc_order id=\"promote-db-then-app\" first=\"database\" first-action=\"promote\"\n" " then=\"myApp\" then-action=\"start\"/>\n" "</constraints>" msgstr "" #. Tag: para #, no-c-format msgid "Colocation of a regular (or group) resource with a multi-state resource means that it can run on any machine with an active copy of the multi-state resource that is in the specified state (Master or Slave). In the example, the cluster will choose a location based on where database is running as a Master, and if there are multiple Master instances it will also factor in myApp's own location preferences when deciding which location to choose." msgstr "" #. Tag: para #, no-c-format msgid "Colocation with regular clones and other multi-state resources is also possible. In such cases, the set of allowed locations for the rsc clone is (after role filtering) limited to nodes on which the with-rsc multi-state resource is (or will be) in the specified role. Allocation is then performed as-per-normal." msgstr "" #. Tag: title #, no-c-format msgid "Multi-state Stickiness" msgstr "" #. Tag: para #, no-c-format msgid " resource-stickinessMulti-State Multi-State To achieve a stable allocation pattern, multi-state resources are slightly sticky by default. If no value for resource-stickiness is provided, the multi-state resource will use a value of 1. Being a small value, it causes minimal disturbance to the score calculations of other resources but is enough to prevent Pacemaker from needlessly moving copies around the cluster." msgstr "" #. Tag: title #, no-c-format msgid "Which Resource Instance is Promoted" msgstr "" #. Tag: para #, no-c-format msgid "During the start operation, most Resource Agent scripts should call the crm_master utility. This tool automatically detects both the resource and host and should be used to set a preference for being promoted. Based on this, master-max, and master-node-max, the instance(s) with the highest preference will be promoted." msgstr "" #. Tag: para #, no-c-format msgid "The other alternative is to create a location constraint that indicates which nodes are most preferred as masters." msgstr "" #. Tag: title #, no-c-format msgid "Manually specifying which node should be promoted" msgstr "" #. Tag: programlisting #, no-c-format msgid "<rsc_location id=\"master-location\" rsc=\"myMasterRsc\">\n" " <rule id=\"master-rule\" score=\"100\" role=\"Master\">\n" " <expression id=\"master-exp\" attribute=\"#uname\" operation=\"eq\" value=\"node1\"/>\n" " </rule>\n" "</rsc_location>" msgstr "" #. Tag: title #, no-c-format msgid "Multi-state Resource Agent Requirements" msgstr "" #. Tag: para #, no-c-format msgid "Since multi-state resources are an extension of cloned resources, all the requirements of Clones are also requirements of multi-state resources. Additionally, multi-state resources require two extra actions: demote and promote; these actions are responsible for changing the state of the resource. Like start and stop, they should return OCF_SUCCESS if they completed successfully or a relevant error code if they did not." msgstr "" #. Tag: para #, no-c-format msgid "The states can mean whatever you wish, but when the resource is started, it must come up in the mode called Slave. From there the cluster will then decide which instances to promote to Master." msgstr "" #. Tag: para #, no-c-format msgid "In addition to the Clone requirements for monitor actions, agents must also accurately report which state they are in. The cluster relies on the agent to report its status (including role) accurately and does not indicate to the agent what role it currently believes it to be in." msgstr "" #. Tag: title #, no-c-format msgid "Role implications of OCF return codes" msgstr "" #. Tag: entry #, no-c-format msgid "Monitor Return Code" msgstr "" #. Tag: para #, no-c-format msgid "OCF_NOT_RUNNING" msgstr "" #. Tag: para #, no-c-format msgid "Stopped Return CodeOCF_NOT_RUNNING OCF_NOT_RUNNING " msgstr "" #. Tag: para #, no-c-format msgid "OCF_SUCCESS" msgstr "" #. Tag: para #, no-c-format msgid "Running (Slave) Return CodeOCF_SUCCESS OCF_SUCCESS " msgstr "" #. Tag: para #, no-c-format msgid "OCF_RUNNING_MASTER" msgstr "" #. Tag: para #, no-c-format msgid "Running (Master) Return CodeOCF_RUNNING_MASTER OCF_RUNNING_MASTER " msgstr "" #. Tag: para #, no-c-format msgid "OCF_FAILED_MASTER" msgstr "" #. Tag: para #, no-c-format msgid "Failed (Master) Return CodeOCF_FAILED_MASTER OCF_FAILED_MASTER " msgstr "" #. Tag: para #, no-c-format msgid "Other" msgstr "" #. Tag: para #, no-c-format msgid "Failed (Slave)" msgstr "" #. Tag: title #, no-c-format msgid "Multi-state Notifications" msgstr "" #. Tag: para #, no-c-format msgid "Like clones, supporting notifications requires the notify action to be implemented. Once supported the notify action will be passed a number of extra variables which, when combined with additional context, can be used to calculate the current state of the cluster and what is about to happen to it." msgstr "" #. Tag: title #, no-c-format msgid "Environment variables supplied with Master notify actions Emphasized variables are specific to Master resources and all behave in the same manner as described for Clone resources." msgstr "" #. Tag: para #, no-c-format msgid "Resources the that are running Environment VariableOCF_RESKEY_CRM_meta_notify_active_resource OCF_RESKEY_CRM_meta_notify_active_resource active_resource active_resourceNotification Environment Variable Notification Environment Variable " msgstr "" #. Tag: para #, no-c-format msgid "Resources the that are not running Environment VariableOCF_RESKEY_CRM_meta_notify_inactive_resource OCF_RESKEY_CRM_meta_notify_inactive_resource inactive_resource inactive_resourceNotification Environment Variable Notification Environment Variable " msgstr "" #. Tag: para #, no-c-format msgid "OCF_RESKEY_CRM_meta_notify_master_resource" msgstr "" #. Tag: para #, no-c-format msgid "Resources that are running in Master mode Environment VariableOCF_RESKEY_CRM_meta_notify_master_resource OCF_RESKEY_CRM_meta_notify_master_resource master_resource master_resourceNotification Environment Variable Notification Environment Variable " msgstr "" #. Tag: para #, no-c-format msgid "OCF_RESKEY_CRM_meta_notify_slave_resource" msgstr "" #. Tag: para #, no-c-format msgid "Resources that are running in Slave mode Environment VariableOCF_RESKEY_CRM_meta_notify_slave_resource OCF_RESKEY_CRM_meta_notify_slave_resource slave_resource slave_resourceNotification Environment Variable Notification Environment Variable " msgstr "" #. Tag: para #, no-c-format msgid " Environment VariableOCF_RESKEY_CRM_meta_notify_stop_resource OCF_RESKEY_CRM_meta_notify_stop_resource stop_resource stop_resourceNotification Environment Variable Notification Environment Variable OCF_RESKEY_CRM_meta_notify_stop_resource" msgstr "" #. Tag: para #, no-c-format msgid "Resources to be stopped" msgstr "" #. Tag: para #, no-c-format msgid "OCF_RESKEY_CRM_meta_notify_promote_resource" msgstr "" #. Tag: para #, no-c-format msgid "Resources to be promoted Environment VariableOCF_RESKEY_CRM_meta_notify_promote_resource OCF_RESKEY_CRM_meta_notify_promote_resource promote_resource promote_resourceNotification Environment Variable Notification Environment Variable " msgstr "" #. Tag: para #, no-c-format msgid "OCF_RESKEY_CRM_meta_notify_demote_resource" msgstr "" #. Tag: para #, no-c-format msgid "Resources to be demoted Environment VariableOCF_RESKEY_CRM_meta_notify_demote_resource OCF_RESKEY_CRM_meta_notify_demote_resource demote_resource demote_resourceNotification Environment Variable Notification Environment Variable " msgstr "" #. Tag: para #, no-c-format msgid "OCF_RESKEY_CRM_meta_notify_promote_uname" msgstr "" #. Tag: para #, no-c-format msgid "Nodes on which resources will be promote Environment VariableOCF_RESKEY_CRM_meta_notify_promote_uname OCF_RESKEY_CRM_meta_notify_promote_uname promote_uname promote_unameNotification Environment Variable Notification Environment Variable " msgstr "" #. Tag: para #, no-c-format msgid "OCF_RESKEY_CRM_meta_notify_demote_uname" msgstr "" #. Tag: para #, no-c-format msgid "Nodes on which resources will be demoted Environment VariableOCF_RESKEY_CRM_meta_notify_demote_uname OCF_RESKEY_CRM_meta_notify_demote_uname demote_uname demote_unameNotification Environment Variable Notification Environment Variable " msgstr "" #. Tag: para #, no-c-format msgid "OCF_RESKEY_CRM_meta_notify_master_uname" msgstr "" #. Tag: para #, no-c-format msgid "Nodes on which resources are running in Master mode Environment VariableOCF_RESKEY_CRM_meta_notify_master_uname OCF_RESKEY_CRM_meta_notify_master_uname master_uname master_unameNotification Environment Variable Notification Environment Variable " msgstr "" #. Tag: para #, no-c-format msgid "OCF_RESKEY_CRM_meta_notify_slave_uname" msgstr "" #. Tag: para #, no-c-format msgid "Nodes on which resources are running in Slave mode Environment VariableOCF_RESKEY_CRM_meta_notify_slave_uname OCF_RESKEY_CRM_meta_notify_slave_uname slave_uname slave_unameNotification Environment Variable Notification Environment Variable " msgstr "" #. Tag: title #, no-c-format msgid "Multi-state - Proper Interpretation of Notification Environment Variables" msgstr "" #. Tag: title #, no-c-format msgid "Pre-notification (demote):" msgstr "" #. Tag: para #, no-c-format msgid "Active resources: $OCF_RESKEY_CRM_meta_notify_active_resource" msgstr "" #. Tag: para #, no-c-format msgid "Master resources: $OCF_RESKEY_CRM_meta_notify_master_resource" msgstr "" #. Tag: para #, no-c-format msgid "Slave resources: $OCF_RESKEY_CRM_meta_notify_slave_resource" msgstr "" #. Tag: para #, no-c-format msgid "Resources to be promoted: $OCF_RESKEY_CRM_meta_notify_promote_resource" msgstr "" #. Tag: para #, no-c-format msgid "Resources to be demoted: $OCF_RESKEY_CRM_meta_notify_demote_resource" msgstr "" #. Tag: title #, no-c-format msgid "Post-notification (demote) / Pre-notification (stop):" msgstr "" #. Tag: para #, no-c-format msgid "Master resources:" msgstr "" #. Tag: para #, no-c-format msgid "$OCF_RESKEY_CRM_meta_notify_master_resource" msgstr "" #. Tag: para #, no-c-format msgid "minus $OCF_RESKEY_CRM_meta_notify_demote_resource" msgstr "" #. Tag: para #, no-c-format msgid "Resources that were demoted: $OCF_RESKEY_CRM_meta_notify_demote_resource" msgstr "" #. Tag: title #, no-c-format msgid "Post-notification (stop) / Pre-notification (start)" msgstr "" #. Tag: para #, no-c-format msgid "Active resources:" msgstr "" #. Tag: para #, no-c-format msgid "Slave resources:" msgstr "" #. Tag: para #, no-c-format msgid "$OCF_RESKEY_CRM_meta_notify_slave_resource" msgstr "" #. Tag: title #, no-c-format msgid "Post-notification (start) / Pre-notification (promote)" msgstr "" #. Tag: title #, no-c-format msgid "Post-notification (promote)" msgstr "" #. Tag: para #, no-c-format msgid "plus $OCF_RESKEY_CRM_meta_notify_promote_resource" msgstr "" #. Tag: para #, no-c-format msgid "minus $OCF_RESKEY_CRM_meta_notify_promote_resource" msgstr "" #. Tag: para #, no-c-format msgid "Resources that were promoted: $OCF_RESKEY_CRM_meta_notify_promote_resource" msgstr "" pacemaker-master/doc/Pacemaker_Explained/pot/Ch-Basics.pot000066400000000000000000000453331217637305600240310ustar00rootroot00000000000000# # AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: 0\n" "POT-Creation-Date: 2012-10-17T05:19:02\n" "PO-Revision-Date: 2012-10-17T05:19:02\n" "Last-Translator: Automatically generated\n" "Language-Team: None\n" "MIME-Version: 1.0\n" "Content-Type: application/x-publican; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. Tag: title #, no-c-format msgid "Configuration Basics" msgstr "" #. Tag: title #, no-c-format msgid "Configuration Layout" msgstr "" #. Tag: para #, no-c-format msgid "The cluster is written using XML notation and divided into two main sections: configuration and status." msgstr "" #. Tag: para #, no-c-format msgid "The status section contains the history of each resource on each node and based on this data, the cluster can construct the complete current state of the cluster. The authoritative source for the status section is the local resource manager (lrmd) process on each cluster node and the cluster will occasionally repopulate the entire section. For this reason it is never written to disk and administrators are advised against modifying it in any way." msgstr "" #. Tag: para #, no-c-format msgid "The configuration section contains the more traditional information like cluster options, lists of resources and indications of where they should be placed. The configuration section is the primary focus of this document." msgstr "" #. Tag: para #, no-c-format msgid "The configuration section itself is divided into four parts:" msgstr "" #. Tag: para #, no-c-format msgid "Configuration options (called crm_config)" msgstr "" #. Tag: para #, no-c-format msgid "Nodes" msgstr "" #. Tag: para #, no-c-format msgid "Resources" msgstr "" #. Tag: para #, no-c-format msgid "Resource relationships (called constraints)" msgstr "" #. Tag: title #, no-c-format msgid "An empty configuration" msgstr "" #. Tag: programlisting #, no-c-format msgid " <cib admin_epoch=\"0\" epoch=\"0\" num_updates=\"0\" have-quorum=\"false\">\n" " <configuration>\n" " <crm_config/>\n" " <nodes/>\n" " <resources/>\n" " <constraints/>\n" " </configuration>\n" " <status/>\n" " </cib>" msgstr "" #. Tag: title #, no-c-format msgid "The Current State of the Cluster" msgstr "" #. Tag: para #, no-c-format msgid "Before one starts to configure a cluster, it is worth explaining how to view the finished product. For this purpose we have created the crm_mon utility that will display the current state of an active cluster. It can show the cluster status by node or by resource and can be used in either single-shot or dynamically-updating mode. There are also modes for displaying a list of the operations performed (grouped by node and resource) as well as information about failures." msgstr "" #. Tag: para #, no-c-format msgid "Using this tool, you can examine the state of the cluster for irregularities and see how it responds when you cause or simulate failures." msgstr "" #. Tag: para #, no-c-format msgid "Details on all the available options can be obtained using the crm_mon --help command." msgstr "" #. Tag: title #, no-c-format msgid "Sample output from crm_mon" msgstr "" #. Tag: screen #, no-c-format msgid " ============\n" " Last updated: Fri Nov 23 15:26:13 2007\n" " Current DC: sles-3 (2298606a-6a8c-499a-9d25-76242f7006ec)\n" " 3 Nodes configured.\n" " 5 Resources configured.\n" " ============\n" "\n" " Node: sles-1 (1186dc9a-324d-425a-966e-d757e693dc86): online\n" " 192.168.100.181 (heartbeat::ocf:IPaddr): Started sles-1\n" " 192.168.100.182 (heartbeat:IPaddr): Started sles-1\n" " 192.168.100.183 (heartbeat::ocf:IPaddr): Started sles-1\n" " rsc_sles-1 (heartbeat::ocf:IPaddr): Started sles-1\n" " child_DoFencing:2 (stonith:external/vmware): Started sles-1\n" " Node: sles-2 (02fb99a8-e30e-482f-b3ad-0fb3ce27d088): standby\n" " Node: sles-3 (2298606a-6a8c-499a-9d25-76242f7006ec): online\n" " rsc_sles-2 (heartbeat::ocf:IPaddr): Started sles-3\n" " rsc_sles-3 (heartbeat::ocf:IPaddr): Started sles-3\n" " child_DoFencing:0 (stonith:external/vmware): Started sles-3" msgstr "" #. Tag: title #, no-c-format msgid "Sample output from crm_mon -n" msgstr "" #. Tag: screen #, no-c-format msgid " ============\n" " Last updated: Fri Nov 23 15:26:13 2007\n" " Current DC: sles-3 (2298606a-6a8c-499a-9d25-76242f7006ec)\n" " 3 Nodes configured.\n" " 5 Resources configured.\n" " ============\n" "\n" " Node: sles-1 (1186dc9a-324d-425a-966e-d757e693dc86): online\n" " Node: sles-2 (02fb99a8-e30e-482f-b3ad-0fb3ce27d088): standby\n" " Node: sles-3 (2298606a-6a8c-499a-9d25-76242f7006ec): online\n" "\n" " Resource Group: group-1\n" " 192.168.100.181 (heartbeat::ocf:IPaddr): Started sles-1\n" " 192.168.100.182 (heartbeat:IPaddr): Started sles-1\n" " 192.168.100.183 (heartbeat::ocf:IPaddr): Started sles-1\n" " rsc_sles-1 (heartbeat::ocf:IPaddr): Started sles-1\n" " rsc_sles-2 (heartbeat::ocf:IPaddr): Started sles-3\n" " rsc_sles-3 (heartbeat::ocf:IPaddr): Started sles-3\n" " Clone Set: DoFencing\n" " child_DoFencing:0 (stonith:external/vmware): Started sles-3\n" " child_DoFencing:1 (stonith:external/vmware): Stopped\n" " child_DoFencing:2 (stonith:external/vmware): Started sles-1" msgstr "" #. Tag: para #, no-c-format msgid "The DC (Designated Controller) node is where all the decisions are made and if the current DC fails a new one is elected from the remaining cluster nodes. The choice of DC is of no significance to an administrator beyond the fact that its logs will generally be more interesting." msgstr "" #. Tag: title #, no-c-format msgid "How Should the Configuration be Updated?" msgstr "" #. Tag: para #, no-c-format msgid "There are three basic rules for updating the cluster configuration:" msgstr "" #. Tag: para #, no-c-format msgid "Rule 1 - Never edit the cib.xml file manually. Ever. I’m not making this up." msgstr "" #. Tag: para #, no-c-format msgid "Rule 2 - Read Rule 1 again." msgstr "" #. Tag: para #, no-c-format msgid "Rule 3 - The cluster will notice if you ignored rules 1 & 2 and refuse to use the configuration." msgstr "" #. Tag: para #, no-c-format msgid "Now that it is clear how NOT to update the configuration, we can begin to explain how you should." msgstr "" #. Tag: para #, no-c-format msgid "The most powerful tool for modifying the configuration is the cibadmin command which talks to a running cluster. With cibadmin, the user can query, add, remove, update or replace any part of the configuration; all changes take effect immediately, so there is no need to perform a reload-like operation." msgstr "" #. Tag: para #, no-c-format msgid "The simplest way of using cibadmin is to use it to save the current configuration to a temporary file, edit that file with your favorite text or XML editor and then upload the revised configuration." msgstr "" #. Tag: title #, no-c-format msgid "Safely using an editor to modify the cluster configuration" msgstr "" #. Tag: programlisting #, no-c-format msgid "# cibadmin --query > tmp.xml\n" "# vi tmp.xml\n" "# cibadmin --replace --xml-file tmp.xml" msgstr "" #. Tag: para #, no-c-format msgid "Some of the better XML editors can make use of a Relax NG schema to help make sure any changes you make are valid. The schema describing the configuration can normally be found in /usr/lib/heartbeat/pacemaker.rng on most systems." msgstr "" #. Tag: para #, no-c-format msgid "If you only wanted to modify the resources section, you could instead do" msgstr "" #. Tag: title #, no-c-format msgid "Safely using an editor to modify a subsection of the cluster configuration" msgstr "" #. Tag: programlisting #, no-c-format msgid "# cibadmin --query --obj_type resources > tmp.xml\n" "# vi tmp.xml\n" "# cibadmin --replace --obj_type resources --xml-file tmp.xml" msgstr "" #. Tag: para #, no-c-format msgid "to avoid modifying any other part of the configuration." msgstr "" #. Tag: title #, no-c-format msgid "Quickly Deleting Part of the Configuration" msgstr "" #. Tag: para #, no-c-format msgid "Identify the object you wish to delete. Eg. run" msgstr "" #. Tag: title #, no-c-format msgid "Searching for STONITH related configuration items" msgstr "" #. Tag: programlisting #, no-c-format msgid "# cibadmin -Q | grep stonith" msgstr "" #. Tag: programlisting #, no-c-format msgid " <nvpair id=\"cib-bootstrap-options-stonith-action\" name=\"stonith-action\" value=\"reboot\"/>\n" " <nvpair id=\"cib-bootstrap-options-stonith-enabled\" name=\"stonith-enabled\" value=\"1\"/>\n" " <primitive id=\"child_DoFencing\" class=\"stonith\" type=\"external/vmware\">\n" " <lrm_resource id=\"child_DoFencing:0\" type=\"external/vmware\" class=\"stonith\">\n" " <lrm_resource id=\"child_DoFencing:0\" type=\"external/vmware\" class=\"stonith\">\n" " <lrm_resource id=\"child_DoFencing:1\" type=\"external/vmware\" class=\"stonith\">\n" " <lrm_resource id=\"child_DoFencing:0\" type=\"external/vmware\" class=\"stonith\">\n" " <lrm_resource id=\"child_DoFencing:2\" type=\"external/vmware\" class=\"stonith\">\n" " <lrm_resource id=\"child_DoFencing:0\" type=\"external/vmware\" class=\"stonith\">\n" " <lrm_resource id=\"child_DoFencing:3\" type=\"external/vmware\" class=\"stonith\">" msgstr "" #. Tag: para #, no-c-format msgid "Next identify the resource’s tag name and id (in this case we’ll choose primitive and child_DoFencing). Then simply execute:" msgstr "" #. Tag: programlisting #, no-c-format msgid "# cibadmin --delete --crm_xml '<primitive id=\"child_DoFencing\"/>'" msgstr "" #. Tag: title #, no-c-format msgid "Updating the Configuration Without Using XML" msgstr "" #. Tag: para #, no-c-format msgid "Some common tasks can also be performed with one of the higher level tools that avoid the need to read or edit XML." msgstr "" #. Tag: para #, no-c-format msgid "To enable stonith for example, one could run:" msgstr "" #. Tag: programlisting #, no-c-format msgid "# crm_attribute --attr-name stonith-enabled --attr-value true" msgstr "" #. Tag: para #, no-c-format msgid "Or, to see if somenode is allowed to run resources, there is:" msgstr "" #. Tag: programlisting #, no-c-format msgid "# crm_standby --get-value --node-uname somenode" msgstr "" #. Tag: para #, no-c-format msgid "Or, to find the current location of my-test-rsc, one can use:" msgstr "" #. Tag: programlisting #, no-c-format msgid "# crm_resource --locate --resource my-test-rsc" msgstr "" #. Tag: title #, no-c-format msgid "Making Configuration Changes in a Sandbox" msgstr "" #. Tag: para #, no-c-format msgid "Often it is desirable to preview the effects of a series of changes before updating the configuration atomically. For this purpose we have created crm_shadow which creates a \"shadow\" copy of the configuration and arranges for all the command line tools to use it." msgstr "" #. Tag: para #, no-c-format msgid "To begin, simply invoke crm_shadow and give it the name of a configuration to create Shadow copies are identified with a name, making it possible to have more than one. ; be sure to follow the simple on-screen instructions." msgstr "" #. Tag: para #, no-c-format msgid "Read the above carefully, failure to do so could result in you destroying the cluster’s active configuration!" msgstr "" #. Tag: title #, no-c-format msgid "Creating and displaying the active sandbox" msgstr "" #. Tag: programlisting #, no-c-format msgid " # crm_shadow --create test\n" " Setting up shadow instance\n" " Type Ctrl-D to exit the crm_shadow shell\n" " shadow[test]:\n" " shadow[test] # crm_shadow --which\n" " test" msgstr "" #. Tag: para #, no-c-format msgid "From this point on, all cluster commands will automatically use the shadow copy instead of talking to the cluster’s active configuration. Once you have finished experimenting, you can either commit the changes, or discard them as shown below. Again, be sure to follow the on-screen instructions carefully." msgstr "" #. Tag: para #, no-c-format msgid "For a full list of crm_shadow options and commands, invoke it with the <parameter>--help</parameter> option." msgstr "" #. Tag: title #, no-c-format msgid "Using a sandbox to make multiple changes atomically" msgstr "" #. Tag: programlisting #, no-c-format msgid " shadow[test] # crm_failcount -G -r rsc_c001n01\n" " name=fail-count-rsc_c001n01 value=0\n" " shadow[test] # crm_standby -v on -n c001n02\n" " shadow[test] # crm_standby -G -n c001n02\n" " name=c001n02 scope=nodes value=on\n" " shadow[test] # cibadmin --erase --force\n" " shadow[test] # cibadmin --query\n" " <cib cib_feature_revision=\"1\" validate-with=\"pacemaker-1.0\" admin_epoch=\"0\" crm_feature_set=\"3.0\" have-quorum=\"1\" epoch=\"112\"\n" " dc-uuid=\"c001n01\" num_updates=\"1\" cib-last-written=\"Fri Jun 27 12:17:10 2008\">\n" " <configuration>\n" " <crm_config/>\n" " <nodes/>\n" " <resources/>\n" " <constraints/>\n" " </configuration>\n" " <status/>\n" " </cib>\n" " shadow[test] # crm_shadow --delete test --force\n" " Now type Ctrl-D to exit the crm_shadow shell\n" " shadow[test] # exit\n" " # crm_shadow --which\n" " No shadow instance provided\n" " # cibadmin -Q\n" " <cib cib_feature_revision=\"1\" validate-with=\"pacemaker-1.0\" admin_epoch=\"0\" crm_feature_set=\"3.0\" have-quorum=\"1\" epoch=\"110\"\n" " dc-uuid=\"c001n01\" num_updates=\"551\">\n" " <configuration>\n" " <crm_config>\n" " <cluster_property_set id=\"cib-bootstrap-options\">\n" " <nvpair id=\"cib-bootstrap-1\" name=\"stonith-enabled\" value=\"1\"/>\n" " <nvpair id=\"cib-bootstrap-2\" name=\"pe-input-series-max\" value=\"30000\"/>" msgstr "" #. Tag: para #, no-c-format msgid "Making changes in a sandbox and verifying the real configuration is untouched" msgstr "" #. Tag: title #, no-c-format msgid "Testing Your Configuration Changes" msgstr "" #. Tag: para #, no-c-format msgid "We saw previously how to make a series of changes to a \"shadow\" copy of the configuration. Before loading the changes back into the cluster (eg. crm_shadow --commit mytest --force), it is often advisable to simulate the effect of the changes with crm_simulate, eg." msgstr "" #. Tag: programlisting #, no-c-format msgid "# crm_simulate --live-check -VVVVV --save-graph tmp.graph --save-dotfile tmp.dot" msgstr "" #. Tag: para #, no-c-format msgid "The tool uses the same library as the live cluster to show what it would have done given the supplied input. It’s output, in addition to a significant amount of logging, is stored in two files tmp.graph and tmp.dot, both are representations of the same thing — the cluster’s response to your changes." msgstr "" #. Tag: para #, no-c-format msgid "In the graph file is stored the complete transition, containing a list of all the actions, their parameters and their pre-requisites. Because the transition graph is not terribly easy to read, the tool also generates a Graphviz dot-file representing the same information." msgstr "" #. Tag: title #, no-c-format msgid "Interpreting the Graphviz output" msgstr "" #. Tag: para #, no-c-format msgid "Arrows indicate ordering dependencies" msgstr "" #. Tag: para #, no-c-format msgid "Dashed-arrows indicate dependencies that are not present in the transition graph" msgstr "" #. Tag: para #, no-c-format msgid "Actions with a dashed border of any color do not form part of the transition graph" msgstr "" #. Tag: para #, no-c-format msgid "Actions with a green border form part of the transition graph" msgstr "" #. Tag: para #, no-c-format msgid "Actions with a red border are ones the cluster would like to execute but cannot run" msgstr "" #. Tag: para #, no-c-format msgid "Actions with a blue border are ones the cluster does not feel need to be executed" msgstr "" #. Tag: para #, no-c-format msgid "Actions with orange text are pseudo/pretend actions that the cluster uses to simplify the graph" msgstr "" #. Tag: para #, no-c-format msgid "Actions with black text are sent to the LRM" msgstr "" #. Tag: para #, no-c-format msgid "Resource actions have text of the form rsc_action_interval node" msgstr "" #. Tag: para #, no-c-format msgid "Any action depending on an action with a red border will not be able to execute." msgstr "" #. Tag: para #, no-c-format msgid "Loops are really bad. Please report them to the development team." msgstr "" #. Tag: title #, no-c-format msgid "Small Cluster Transition" msgstr "" #. Tag: phrase #, no-c-format msgid "An example transition graph as represented by Graphviz" msgstr "" #. Tag: para #, no-c-format msgid "In the above example, it appears that a new node, node2, has come online and that the cluster is checking to make sure rsc1, rsc2 and rsc3 are not already running there (Indicated by the *_monitor_0 entries). Once it did that, and assuming the resources were not active there, it would have liked to stop rsc1 and rsc2 on node1 and move them to node2. However, there appears to be some problem and the cluster cannot or is not permitted to perform the stop actions which implies it also cannot perform the start actions. For some reason the cluster does not want to start rsc3 anywhere." msgstr "" #. Tag: para #, no-c-format msgid "For information on the options supported by crm_simulate, use the --help option." msgstr "" #. Tag: title #, no-c-format msgid "Complex Cluster Transition" msgstr "" #. Tag: phrase #, no-c-format msgid "Another, slightly more complex, transition graph that you're not expected to be able to read" msgstr "" #. Tag: title #, no-c-format msgid "Do I Need to Update the Configuration on all Cluster Nodes?" msgstr "" #. Tag: para #, no-c-format msgid "No. Any changes are immediately synchronized to the other active members of the cluster." msgstr "" #. Tag: para #, no-c-format msgid "To reduce bandwidth, the cluster only broadcasts the incremental updates that result from your changes and uses MD5 checksums to ensure that each copy is completely consistent." msgstr "" pacemaker-master/doc/Pacemaker_Explained/pot/Ch-Constraints.pot000066400000000000000000001012641217637305600251300ustar00rootroot00000000000000# # AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: 0\n" "POT-Creation-Date: 2012-10-17T05:19:02\n" "PO-Revision-Date: 2012-10-17T05:19:02\n" "Last-Translator: Automatically generated\n" "Language-Team: None\n" "MIME-Version: 1.0\n" "Content-Type: application/x-publican; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. Tag: title #, no-c-format msgid "Resource Constraints" msgstr "" #. Tag: para #, no-c-format msgid " ResourceConstraints Constraints " msgstr "" #. Tag: title #, no-c-format msgid "Scores" msgstr "" #. Tag: para #, no-c-format msgid "Scores of all kinds are integral to how the cluster works. Practically everything from moving a resource to deciding which resource to stop in a degraded cluster is achieved by manipulating scores in some way." msgstr "" #. Tag: para #, no-c-format msgid "Scores are calculated on a per-resource basis and any node with a negative score for a resource can’t run that resource. After calculating the scores for a resource, the cluster then chooses the node with the highest one." msgstr "" #. Tag: title #, no-c-format msgid "Infinity Math" msgstr "" #. Tag: para #, no-c-format msgid "INFINITY is currently defined as 1,000,000 and addition/subtraction with it follows these three basic rules:" msgstr "" #. Tag: para #, no-c-format msgid "Any value + INFINITY = INFINITY" msgstr "" #. Tag: para #, no-c-format msgid "Any value - INFINITY = -INFINITY" msgstr "" #. Tag: para #, no-c-format msgid "INFINITY - INFINITY = -INFINITY" msgstr "" #. Tag: title #, no-c-format msgid "Deciding Which Nodes a Resource Can Run On" msgstr "" #. Tag: para #, no-c-format msgid " Location Constraints ResourceConstraintsLocation ConstraintsLocation Location There are two alternative strategies for specifying which nodes a resources can run on. One way is to say that by default they can run anywhere and then create location constraints for nodes that are not allowed. The other option is to have nodes \"opt-in\"… to start with nothing able to run anywhere and selectively enable allowed nodes." msgstr "" #. Tag: title #, no-c-format msgid "Options" msgstr "" #. Tag: title #, no-c-format msgid "Options for Simple Location Constraints" msgstr "" #. Tag: entry #, no-c-format msgid "Field" msgstr "" #. Tag: entry #, no-c-format msgid "Description" msgstr "" #. Tag: para #, no-c-format msgid "id" msgstr "" #. Tag: para #, no-c-format msgid "A unique name for the constraint idLocation Constraints Location Constraints ConstraintsLocationid Locationid id " msgstr "" #. Tag: para #, no-c-format msgid "rsc" msgstr "" #. Tag: para #, no-c-format msgid "A resource name rscLocation Constraints Location Constraints ConstraintsLocationrsc Locationrsc rsc " msgstr "" #. Tag: para #, no-c-format msgid "node" msgstr "" #. Tag: para #, no-c-format msgid "A node’s name nodeLocation Constraints Location Constraints ConstraintsLocationnode Locationnode node " msgstr "" #. Tag: para #, no-c-format msgid "score" msgstr "" #. Tag: para #, no-c-format msgid "Positive values indicate the resource should run on this node. Negative values indicate the resource should not run on this node." msgstr "" #. Tag: para #, no-c-format msgid "Values of +/- INFINITY change \"should\"/\"should not\" to \"must\"/\"must not\". scoreLocation Constraints Location Constraints ConstraintsLocationscore Locationscore score " msgstr "" #. Tag: title #, no-c-format msgid "Asymmetrical \"Opt-In\" Clusters" msgstr "" #. Tag: para #, no-c-format msgid " Asymmetrical Opt-In Clusters Cluster TypeAsymmetrical Opt-In Asymmetrical Opt-In " msgstr "" #. Tag: para #, no-c-format msgid "To create an opt-in cluster, start by preventing resources from running anywhere by default:" msgstr "" #. Tag: programlisting #, no-c-format msgid "# crm_attribute --attr-name symmetric-cluster --attr-value false" msgstr "" #. Tag: para #, no-c-format msgid "Then start enabling nodes. The following fragment says that the web server prefers sles-1, the database prefers sles-2 and both can fail over to sles-3 if their most preferred node fails." msgstr "" #. Tag: title #, no-c-format msgid "Example set of opt-in location constraints" msgstr "" #. Tag: programlisting #, no-c-format msgid "<constraints>\n" " <rsc_location id=\"loc-1\" rsc=\"Webserver\" node=\"sles-1\" score=\"200\"/>\n" " <rsc_location id=\"loc-2\" rsc=\"Webserver\" node=\"sles-3\" score=\"0\"/>\n" " <rsc_location id=\"loc-3\" rsc=\"Database\" node=\"sles-2\" score=\"200\"/>\n" " <rsc_location id=\"loc-4\" rsc=\"Database\" node=\"sles-3\" score=\"0\"/>\n" "</constraints>" msgstr "" #. Tag: title #, no-c-format msgid "Symmetrical \"Opt-Out\" Clusters" msgstr "" #. Tag: para #, no-c-format msgid " Symmetrical Opt-Out Clusters Cluster TypeSymmetrical Opt-Out Symmetrical Opt-Out " msgstr "" #. Tag: para #, no-c-format msgid "To create an opt-out cluster, start by allowing resources to run anywhere by default:" msgstr "" #. Tag: programlisting #, no-c-format msgid "# crm_attribute --attr-name symmetric-cluster --attr-value true" msgstr "" #. Tag: para #, no-c-format msgid "Then start disabling nodes. The following fragment is the equivalent of the above opt-in configuration." msgstr "" #. Tag: title #, no-c-format msgid "Example set of opt-out location constraints" msgstr "" #. Tag: programlisting #, no-c-format msgid "<constraints>\n" " <rsc_location id=\"loc-1\" rsc=\"Webserver\" node=\"sles-1\" score=\"200\"/>\n" " <rsc_location id=\"loc-2-dont-run\" rsc=\"Webserver\" node=\"sles-2\" score=\"-INFINITY\"/>\n" " <rsc_location id=\"loc-3-dont-run\" rsc=\"Database\" node=\"sles-1\" score=\"-INFINITY\"/>\n" " <rsc_location id=\"loc-4\" rsc=\"Database\" node=\"sles-2\" score=\"200\"/>\n" "</constraints>" msgstr "" #. Tag: para #, no-c-format msgid "Whether you should choose opt-in or opt-out depends both on your personal preference and the make-up of your cluster. If most of your resources can run on most of the nodes, then an opt-out arrangement is likely to result in a simpler configuration. On the other-hand, if most resources can only run on a small subset of nodes an opt-in configuration might be simpler." msgstr "" #. Tag: title #, no-c-format msgid "What if Two Nodes Have the Same Score" msgstr "" #. Tag: para #, no-c-format msgid "If two nodes have the same score, then the cluster will choose one. This choice may seem random and may not be what was intended, however the cluster was not given enough information to know any better." msgstr "" #. Tag: title #, no-c-format msgid "Example of two resources that prefer two nodes equally" msgstr "" #. Tag: programlisting #, no-c-format msgid "<constraints>\n" " <rsc_location id=\"loc-1\" rsc=\"Webserver\" node=\"sles-1\" score=\"INFINITY\"/>\n" " <rsc_location id=\"loc-2\" rsc=\"Webserver\" node=\"sles-2\" score=\"INFINITY\"/>\n" " <rsc_location id=\"loc-3\" rsc=\"Database\" node=\"sles-1\" score=\"500\"/>\n" " <rsc_location id=\"loc-4\" rsc=\"Database\" node=\"sles-2\" score=\"300\"/>\n" " <rsc_location id=\"loc-5\" rsc=\"Database\" node=\"sles-2\" score=\"200\"/>\n" "</constraints>" msgstr "" #. Tag: para #, no-c-format msgid "In the example above, assuming no other constraints and an inactive cluster, Webserver would probably be placed on sles-1 and Database on sles-2. It would likely have placed Webserver based on the node’s uname and Database based on the desire to spread the resource load evenly across the cluster. However other factors can also be involved in more complex configurations." msgstr "" #. Tag: title #, no-c-format msgid "Specifying in which Order Resources Should Start/Stop" msgstr "" #. Tag: para #, no-c-format msgid " ResourceConstraintsOrdering ConstraintsOrdering Ordering ResourceStart Order Start Order Ordering Constraints The way to specify the order in which resources should start is by creating rsc_order constraints." msgstr "" #. Tag: title #, no-c-format msgid "Properties of an Ordering Constraint" msgstr "" #. Tag: para #, no-c-format msgid "A unique name for the constraint idOrdering Constraints Ordering Constraints ConstraintsOrderingid Orderingid id " msgstr "" #. Tag: para #, no-c-format msgid "first" msgstr "" #. Tag: para #, no-c-format msgid "The name of a resource that must be started before the then resource is allowed to. firstOrdering Constraints Ordering Constraints ConstraintsOrderingfirst Orderingfirst first " msgstr "" #. Tag: para #, no-c-format msgid "then" msgstr "" #. Tag: para #, no-c-format msgid "The name of a resource. This resource will start after the first resource. thenOrdering Constraints Ordering Constraints ConstraintsOrderingthen Orderingthen then " msgstr "" #. Tag: para #, no-c-format msgid "kind" msgstr "" #. Tag: para #, no-c-format msgid "How to enforce the constraint. (Since 1.1.2)" msgstr "" #. Tag: para #, no-c-format msgid "* Optional - Just a suggestion. Only applies if both resources are starting/stopping." msgstr "" #. Tag: para #, no-c-format msgid "* Mandatory - Always. If first is stopping or cannot be started, then must be stopped." msgstr "" #. Tag: para #, no-c-format msgid "* Serialize - Ensure that no two stop/start actions occur concurrently for a set of resources." msgstr "" #. Tag: para #, no-c-format msgid " kindOrdering Constraints Ordering Constraints ConstraintsOrderingkind Orderingkind kind " msgstr "" #. Tag: para #, no-c-format msgid "symmetrical" msgstr "" #. Tag: para #, no-c-format msgid "If true, which is the default, stop the resources in the reverse order. Default value: true symmetricalOrdering Constraints Ordering Constraints Ordering Constraintssymmetrical symmetrical " msgstr "" #. Tag: title #, no-c-format msgid "Mandatory Ordering" msgstr "" #. Tag: para #, no-c-format msgid "When the then resource cannot run without the first resource being active, one should use mandatory constraints. To specify a constraint is mandatory, use scores greater than zero. This will ensure that the then resource will react when the first resource changes state." msgstr "" #. Tag: para #, no-c-format msgid "If the first resource was running and is stopped, the then resource will also be stopped (if it is running)." msgstr "" #. Tag: para #, no-c-format msgid "If the first resource was not running and cannot be started, the then resource will be stopped (if it is running)." msgstr "" #. Tag: para #, no-c-format msgid "If the first resource is (re)started while the then resource is running, the then resource will be stopped and restarted." msgstr "" #. Tag: title #, no-c-format msgid "Advisory Ordering" msgstr "" #. Tag: para #, no-c-format msgid "On the other hand, when score=\"0\" is specified for a constraint, the constraint is considered optional and only has an effect when both resources are stopping and/or starting. Any change in state by the first resource will have no effect on the then resource." msgstr "" #. Tag: title #, no-c-format msgid "Example of an optional and mandatory ordering constraint" msgstr "" #. Tag: programlisting #, no-c-format msgid "<constraints>\n" " <rsc_order id=\"order-1\" first=\"Database\" then=\"Webserver\" />\n" " <rsc_order id=\"order-2\" first=\"IP\" then=\"Webserver\" score=\"0\"/>\n" "</constraints>" msgstr "" #. Tag: para #, no-c-format msgid "Some additional information on ordering constraints can be found in the document Ordering Explained." msgstr "" #. Tag: title #, no-c-format msgid "Placing Resources Relative to other Resources" msgstr "" #. Tag: para #, no-c-format msgid " ResourceConstraintsColocation ConstraintsColocation Colocation ResourceLocation Relative to other Resources Location Relative to other Resources When the location of one resource depends on the location of another one, we call this colocation." msgstr "" #. Tag: para #, no-c-format msgid "There is an important side-effect of creating a colocation constraint between two resources: it affects the order in which resources are assigned to a node. If you think about it, it’s somewhat obvious. You can’t place A relative to B unless you know where B is. While the human brain is sophisticated enough to read the constraint in any order and choose the correct one depending on the situation, the cluster is not quite so smart. Yet. " msgstr "" #. Tag: para #, no-c-format msgid "So when you are creating colocation constraints, it is important to consider whether you should colocate A with B or B with A." msgstr "" #. Tag: para #, no-c-format msgid "Another thing to keep in mind is that, assuming A is collocated with B, the cluster will also take into account A’s preferences when deciding which node to choose for B." msgstr "" #. Tag: para #, no-c-format msgid "For a detailed look at exactly how this occurs, see the Colocation Explained document." msgstr "" #. Tag: title #, no-c-format msgid "Properties of a Collocation Constraint" msgstr "" #. Tag: para #, no-c-format msgid "A unique name for the constraint. idColocation Constraints Colocation Constraints ConstraintsColocationid Colocationid id " msgstr "" #. Tag: para #, no-c-format msgid "The colocation source. If the constraint cannot be satisfied, the cluster may decide not to allow the resource to run at all. rscColocation Constraints Colocation Constraints ConstraintsColocationrsc Colocationrsc rsc " msgstr "" #. Tag: para #, no-c-format msgid "with-rsc" msgstr "" #. Tag: para #, no-c-format msgid "The colocation target. The cluster will decide where to put this resource first and then decide where to put the resource in the rsc field. with-rscColocation Constraints Colocation Constraints ConstraintsColocationwith-rsc Colocationwith-rsc with-rsc " msgstr "" #. Tag: para #, no-c-format msgid "Positive values indicate the resource should run on the same node. Negative values indicate the resources should not run on the same node. Values of +/- INFINITY change \"should\" to \"must\". scoreColocation Constraints Colocation Constraints ConstraintsColocationscore Colocationscore score " msgstr "" #. Tag: title #, no-c-format msgid "Mandatory Placement" msgstr "" #. Tag: para #, no-c-format msgid "Mandatory placement occurs any time the constraint’s score is +INFINITY or -INFINITY. In such cases, if the constraint can’t be satisfied, then the rsc resource is not permitted to run. For score=INFINITY, this includes cases where the with-rsc resource is not active." msgstr "" #. Tag: para #, no-c-format msgid "If you need resource1 to always run on the same machine as resource2, you would add the following constraint:" msgstr "" #. Tag: title #, no-c-format msgid "An example colocation constraint" msgstr "" #. Tag: programlisting #, no-c-format msgid "<rsc_colocation id=\"colocate\" rsc=\"resource1\" with-rsc=\"resource2\" score=\"INFINITY\"/>" msgstr "" #. Tag: para #, no-c-format msgid "Remember, because INFINITY was used, if resource2 can’t run on any of the cluster nodes (for whatever reason) then resource1 will not be allowed to run." msgstr "" #. Tag: para #, no-c-format msgid "Alternatively, you may want the opposite… that resource1 cannot run on the same machine as resource2. In this case use score=\"-INFINITY\"" msgstr "" #. Tag: title #, no-c-format msgid "An example anti-colocation constraint" msgstr "" #. Tag: programlisting #, no-c-format msgid "<rsc_colocation id=\"anti-colocate\" rsc=\"resource1\" with-rsc=\"resource2\" score=\"-INFINITY\"/>" msgstr "" #. Tag: para #, no-c-format msgid "Again, by specifying -INFINTY, the constraint is binding. So if the only place left to run is where resource2 already is, then resource1 may not run anywhere." msgstr "" #. Tag: title #, no-c-format msgid "Advisory Placement" msgstr "" #. Tag: para #, no-c-format msgid "If mandatory placement is about \"must\" and \"must not\", then advisory placement is the \"I’d prefer if\" alternative. For constraints with scores greater than -INFINITY and less than INFINITY, the cluster will try and accommodate your wishes but may ignore them if the alternative is to stop some of the cluster resources." msgstr "" #. Tag: para #, no-c-format msgid "Like in life, where if enough people prefer something it effectively becomes mandatory, advisory colocation constraints can combine with other elements of the configuration to behave as if they were mandatory." msgstr "" #. Tag: title #, no-c-format msgid "An example advisory-only colocation constraint" msgstr "" #. Tag: programlisting #, no-c-format msgid "<rsc_colocation id=\"colocate-maybe\" rsc=\"resource1\" with-rsc=\"resource2\" score=\"500\"/>" msgstr "" #. Tag: title #, no-c-format msgid "Ordering Sets of Resources" msgstr "" #. Tag: para #, no-c-format msgid "A common situation is for an administrator to create a chain of ordered resources, such as:" msgstr "" #. Tag: title #, no-c-format msgid "A chain of ordered resources" msgstr "" #. Tag: programlisting #, no-c-format msgid "<constraints>\n" " <rsc_order id=\"order-1\" first=\"A\" then=\"B\" />\n" " <rsc_order id=\"order-2\" first=\"B\" then=\"C\" />\n" " <rsc_order id=\"order-3\" first=\"C\" then=\"D\" />\n" "</constraints>" msgstr "" #. Tag: title #, no-c-format msgid "Ordered Set" msgstr "" #. Tag: title #, no-c-format msgid "Visual representation of the four resources' start order for the above constraints" msgstr "" #. Tag: phrase #, no-c-format msgid "Ordered set" msgstr "" #. Tag: para #, no-c-format msgid "To simplify this situation, there is an alternate format for ordering constraints:" msgstr "" #. Tag: title #, no-c-format msgid "A chain of ordered resources expressed as a set" msgstr "" #. Tag: programlisting #, no-c-format msgid "<constraints>\n" " <rsc_order id=\"order-1\">\n" " <resource_set id=\"ordered-set-example\" sequential=\"true\">\n" " <resource_ref id=\"A\"/>\n" " <resource_ref id=\"B\"/>\n" " <resource_ref id=\"C\"/>\n" " <resource_ref id=\"D\"/>\n" " </resource_set>\n" " </rsc_order>\n" "</constraints>" msgstr "" #. Tag: para #, no-c-format msgid "Resource sets have the same ordering semantics as groups." msgstr "" #. Tag: title #, no-c-format msgid "A group resource with the equivalent ordering rules" msgstr "" #. Tag: programlisting #, no-c-format msgid "<group id=\"dummy\">\n" " <primitive id=\"A\" .../>\n" " <primitive id=\"B\" .../>\n" " <primitive id=\"C\" .../>\n" " <primitive id=\"D\" .../>\n" "</group>" msgstr "" #. Tag: para #, no-c-format msgid "While the set-based format is not less verbose, it is significantly easier to get right and maintain. It can also be expanded to allow ordered sets of (un)ordered resources. In the example below, rscA and rscB can both start in parallel, as can rscC and rscD, however rscC and rscD can only start once both rscA and rscB are active." msgstr "" #. Tag: title #, no-c-format msgid "Ordered sets of unordered resources" msgstr "" #. Tag: programlisting #, no-c-format msgid "<constraints>\n" " <rsc_order id=\"order-1\">\n" " <resource_set id=\"ordered-set-1\" sequential=\"false\">\n" " <resource_ref id=\"A\"/>\n" " <resource_ref id=\"B\"/>\n" " </resource_set>\n" " <resource_set id=\"ordered-set-2\" sequential=\"false\">\n" " <resource_ref id=\"C\"/>\n" " <resource_ref id=\"D\"/>\n" " </resource_set>\n" " </rsc_order>\n" " </constraints>" msgstr "" #. Tag: title #, no-c-format msgid "Two Sets of Unordered Resources" msgstr "" #. Tag: title #, no-c-format msgid "Visual representation of the start order for two ordered sets of unordered resources" msgstr "" #. Tag: phrase #, no-c-format msgid "Two ordered sets" msgstr "" #. Tag: para #, no-c-format msgid "Of course either set — or both sets — of resources can also be internally ordered (by setting sequential=\"true\") and there is no limit to the number of sets that can be specified." msgstr "" #. Tag: title #, no-c-format msgid "Advanced use of set ordering - Three ordered sets, two of which are internally unordered" msgstr "" #. Tag: programlisting #, no-c-format msgid "<constraints>\n" " <rsc_order id=\"order-1\">\n" " <resource_set id=\"ordered-set-1\" sequential=\"false\">\n" " <resource_ref id=\"A\"/>\n" " <resource_ref id=\"B\"/>\n" " </resource_set>\n" " <resource_set id=\"ordered-set-2\" sequential=\"true\">\n" " <resource_ref id=\"C\"/>\n" " <resource_ref id=\"D\"/>\n" " </resource_set>\n" " <resource_set id=\"ordered-set-3\" sequential=\"false\">\n" " <resource_ref id=\"E\"/>\n" " <resource_ref id=\"F\"/>\n" " </resource_set>\n" " </rsc_order>\n" "</constraints>" msgstr "" #. Tag: title #, no-c-format msgid "Three Resources Sets" msgstr "" #. Tag: title #, no-c-format msgid "Visual representation of the start order for the three sets defined above" msgstr "" #. Tag: phrase #, no-c-format msgid "Three ordered sets" msgstr "" #. Tag: title #, no-c-format msgid "Collocating Sets of Resources" msgstr "" #. Tag: para #, no-c-format msgid "Another common situation is for an administrator to create a set of collocated resources. Previously this was possible either by defining a resource group (See ) which could not always accurately express the design; or by defining each relationship as an individual constraint, causing a constraint explosion as the number of resources and combinations grew." msgstr "" #. Tag: title #, no-c-format msgid "A chain of collocated resources" msgstr "" #. Tag: programlisting #, no-c-format msgid "<constraints>\n" " <rsc_colocation id=\"coloc-1\" rsc=\"B\" with-rsc=\"A\" score=\"INFINITY\"/>\n" " <rsc_colocation id=\"coloc-2\" rsc=\"C\" with-rsc=\"B\" score=\"INFINITY\"/>\n" " <rsc_colocation id=\"coloc-3\" rsc=\"D\" with-rsc=\"C\" score=\"INFINITY\"/>\n" "</constraints>" msgstr "" #. Tag: para #, no-c-format msgid "To make things easier, we allow an alternate form of colocation constraints using resource_sets. Just like the expanded version, a resource that can’t be active also prevents any resource that must be collocated with it from being active. For example, if B was not able to run, then both C (+and by inference +D) must also remain stopped." msgstr "" #. Tag: title #, no-c-format msgid "The equivalent colocation chain expressed using resource_sets" msgstr "" #. Tag: programlisting #, no-c-format msgid "<constraints>\n" " <rsc_colocation id=\"coloc-1\" score=\"INFINITY\" >\n" " <resource_set id=\"collocated-set-example\" sequential=\"true\">\n" " <resource_ref id=\"A\"/>\n" " <resource_ref id=\"B\"/>\n" " <resource_ref id=\"C\"/>\n" " <resource_ref id=\"D\"/>\n" " </resource_set>\n" " </rsc_colocation>\n" "</constraints>" msgstr "" #. Tag: para #, no-c-format msgid "Resource sets have the same colocation semantics as groups." msgstr "" #. Tag: title #, no-c-format msgid "A group resource with the equivalent colocation rules" msgstr "" #. Tag: para #, no-c-format msgid "This notation can also be used in this context to tell the cluster that a set of resources must all be located with a common peer, but have no dependencies on each other. In this scenario, unlike the previous, B would be allowed to remain active even if A or C (or both) were inactive." msgstr "" #. Tag: title #, no-c-format msgid "Using colocation sets to specify a common peer." msgstr "" #. Tag: programlisting #, no-c-format msgid "<constraints>\n" " <rsc_colocation id=\"coloc-1\" score=\"INFINITY\" >\n" " <resource_set id=\"collocated-set-1\" sequential=\"false\">\n" " <resource_ref id=\"A\"/>\n" " <resource_ref id=\"B\"/>\n" " <resource_ref id=\"C\"/>\n" " </resource_set>\n" " <resource_set id=\"collocated-set-2\" sequential=\"true\">\n" " <resource_ref id=\"D\"/>\n" " </resource_set>\n" " </rsc_colocation>\n" "</constraints>" msgstr "" #. Tag: para #, no-c-format msgid "Of course there is no limit to the number and size of the sets used. The only thing that matters is that in order for any member of set N to be active, all the members of set N+1 must also be active (and naturally on the same node); and if a set has sequential=\"true\", then in order for member M to be active, member M+1 must also be active. You can even specify the role in which the members of a set must be in using the set’s role attribute." msgstr "" #. Tag: title #, no-c-format msgid "A colocation chain where the members of the middle set have no inter-dependencies and the last has master status." msgstr "" #. Tag: programlisting #, no-c-format msgid "<constraints>\n" " <rsc_colocation id=\"coloc-1\" score=\"INFINITY\" >\n" " <resource_set id=\"collocated-set-1\" sequential=\"true\">\n" " <resource_ref id=\"A\"/>\n" " <resource_ref id=\"B\"/>\n" " </resource_set>\n" " <resource_set id=\"collocated-set-2\" sequential=\"false\">\n" " <resource_ref id=\"C\"/>\n" " <resource_ref id=\"D\"/>\n" " <resource_ref id=\"E\"/>\n" " </resource_set>\n" " <resource_set id=\"collocated-set-2\" sequential=\"true\" role=\"Master\">\n" " <resource_ref id=\"F\"/>\n" " <resource_ref id=\"G\"/>\n" " </resource_set>\n" " </rsc_colocation>\n" "</constraints>" msgstr "" #. Tag: title #, no-c-format msgid "Another Three Resources Sets" msgstr "" #. Tag: title #, no-c-format msgid "Visual representation of a colocation chain where the members of the middle set have no inter-dependencies" msgstr "" #. Tag: phrase #, no-c-format msgid "Colocation chain" msgstr "" pacemaker-master/doc/Pacemaker_Explained/pot/Ch-Intro.pot000066400000000000000000000233161217637305600237150ustar00rootroot00000000000000# # AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: 0\n" "POT-Creation-Date: 2012-10-17T05:19:02\n" "PO-Revision-Date: 2012-10-17T05:19:02\n" "Last-Translator: Automatically generated\n" "Language-Team: None\n" "MIME-Version: 1.0\n" "Content-Type: application/x-publican; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. Tag: title #, no-c-format msgid "Read-Me-First" msgstr "" #. Tag: title #, no-c-format msgid "The Scope of this Document" msgstr "" #. Tag: para #, no-c-format msgid "The purpose of this document is to definitively explain the concepts used to configure Pacemaker. To achieve this, it will focus exclusively on the XML syntax used to configure the CIB." msgstr "" #. Tag: para #, no-c-format msgid "For those that are allergic to XML, there exist several unified shells and GUIs for Pacemaker. However these tools will not be covered at all in this document I hope, however, that the concepts explained here make the functionality of these tools more easily understood. , precisely because they hide the XML." msgstr "" #. Tag: para #, no-c-format msgid "Additionally, this document is NOT a step-by-step how-to guide for configuring a specific clustering scenario." msgstr "" #. Tag: para #, no-c-format msgid "Although such guides exist, the purpose of this document is to provide an understanding of the building blocks that can be used to construct any type of Pacemaker cluster." msgstr "" #. Tag: title #, no-c-format msgid "What Is Pacemaker?" msgstr "" #. Tag: para #, no-c-format msgid "Pacemaker is a cluster resource manager." msgstr "" #. Tag: para #, no-c-format msgid "It achieves maximum availability for your cluster services (aka. resources) by detecting and recovering from node and resource-level failures by making use of the messaging and membership capabilities provided by your preferred cluster infrastructure (either Corosync or Heartbeat." msgstr "" #. Tag: para #, no-c-format msgid "Pacemaker’s key features include:" msgstr "" #. Tag: para #, no-c-format msgid "Detection and recovery of node and service-level failures" msgstr "" #. Tag: para #, no-c-format msgid "Storage agnostic, no requirement for shared storage" msgstr "" #. Tag: para #, no-c-format msgid "Resource agnostic, anything that can be scripted can be clustered" msgstr "" #. Tag: para #, no-c-format msgid "Supports STONITH for ensuring data integrity" msgstr "" #. Tag: para #, no-c-format msgid "Supports large and small clusters" msgstr "" #. Tag: para #, no-c-format msgid "Supports both quorate and resource driven clusters" msgstr "" #. Tag: para #, no-c-format msgid "Supports practically any redundancy configuration" msgstr "" #. Tag: para #, no-c-format msgid "Automatically replicated configuration that can be updated from any node" msgstr "" #. Tag: para #, no-c-format msgid "Ability to specify cluster-wide service ordering, colocation and anti-colocation" msgstr "" #. Tag: para #, no-c-format msgid "Support for advanced services type" msgstr "" #. Tag: para #, no-c-format msgid "Clones: for services which need to be active on multiple nodes" msgstr "" #. Tag: para #, no-c-format msgid "Multi-state: for services with multiple modes (eg. master/slave, primary/secondary)" msgstr "" #. Tag: title #, no-c-format msgid "Types of Pacemaker Clusters" msgstr "" #. Tag: para #, no-c-format msgid "Pacemaker makes no assumptions about your environment, this allows it to support practically any redundancy configuration including Active/Active, Active/Passive, N+1, N+M, N-to-1 and N-to-N." msgstr "" #. Tag: title #, no-c-format msgid "Active/Passive Redundancy" msgstr "" #. Tag: para #, no-c-format msgid "Two-node Active/Passive clusters using Pacemaker and DRBD are a cost-effective solution for many High Availability situations." msgstr "" #. Tag: title #, no-c-format msgid "Shared Failover" msgstr "" #. Tag: para #, no-c-format msgid "By supporting many nodes, Pacemaker can dramatically reduce hardware costs by allowing several active/passive clusters to be combined and share a common backup node" msgstr "" #. Tag: title #, no-c-format msgid "N to N Redundancy" msgstr "" #. Tag: para #, no-c-format msgid "When shared storage is available, every node can potentially be used for failover. Pacemaker can even run multiple copies of services to spread out the workload." msgstr "" #. Tag: title #, no-c-format msgid "Pacemaker Architecture" msgstr "" #. Tag: para #, no-c-format msgid "At the highest level, the cluster is made up of three pieces:" msgstr "" #. Tag: para #, no-c-format msgid "Core cluster infrastructure providing messaging and membership functionality (illustrated in red)" msgstr "" #. Tag: para #, no-c-format msgid "Non-cluster aware components (illustrated in green)." msgstr "" #. Tag: para #, no-c-format msgid "In a Pacemaker cluster, these pieces include not only the scripts that knows how to start, stop and monitor resources, but also a local daemon that masks the differences between the different standards these scripts implement." msgstr "" #. Tag: para #, no-c-format msgid "A brain (illustrated in blue)" msgstr "" #. Tag: para #, no-c-format msgid "This component processes and reacts to events from the cluster (nodes leaving or joining) and resources (eg. monitor failures) as well as configuration changes from the administrator. In response to all of these events, Pacemaker will compute the ideal state of the cluster and plot a path to achieve it. This may include moving resources, stopping nodes and even forcing nodes offline with remote power switches." msgstr "" #. Tag: title #, no-c-format msgid "Conceptual Stack Overview" msgstr "" #. Tag: title #, no-c-format msgid "Conceptual overview of the cluster stack" msgstr "" #. Tag: para #, no-c-format msgid "When combined with Corosync, Pacemaker also supports popular open source cluster filesystems. footnote:[ Even though Pacemaker also supports Heartbeat, the filesystems need to use the stack for messaging and membership and Corosync seems to be what they’re standardizing on." msgstr "" #. Tag: para #, no-c-format msgid "Technically it would be possible for them to support Heartbeat as well, however there seems little interest in this. ]" msgstr "" #. Tag: para #, no-c-format msgid "Due to recent standardization within the cluster filesystem community, they make use of a common distributed lock manager which makes use of Corosync for its messaging capabilities and Pacemaker for its membership (which nodes are up/down) and fencing services." msgstr "" #. Tag: title #, no-c-format msgid "The Pacemaker stack when running on Corosync" msgstr "" #. Tag: title #, no-c-format msgid "Internal Components" msgstr "" #. Tag: para #, no-c-format msgid "Pacemaker itself is composed of four key components (illustrated below in the same color scheme as the previous diagram):" msgstr "" #. Tag: para #, no-c-format msgid "CIB (aka. Cluster Information Base)" msgstr "" #. Tag: para #, no-c-format msgid "CRMd (aka. Cluster Resource Management daemon)" msgstr "" #. Tag: para #, no-c-format msgid "PEngine (aka. PE or Policy Engine)" msgstr "" #. Tag: para #, no-c-format msgid "STONITHd" msgstr "" #. Tag: title #, no-c-format msgid "Subsystems of a Pacemaker cluster" msgstr "" #. Tag: para #, no-c-format msgid "The CIB uses XML to represent both the cluster’s configuration and current state of all resources in the cluster. The contents of the CIB are automatically kept in sync across the entire cluster and are used by the PEngine to compute the ideal state of the cluster and how it should be achieved." msgstr "" #. Tag: para #, no-c-format msgid "This list of instructions is then fed to the DC (Designated Controller). Pacemaker centralizes all cluster decision making by electing one of the CRMd instances to act as a master. Should the elected CRMd process (or the node it is on) fail… a new one is quickly established." msgstr "" #. Tag: para #, no-c-format msgid "The DC carries out PEngine’s instructions in the required order by passing them to either the LRMd (Local Resource Management daemon) or CRMd peers on other nodes via the cluster messaging infrastructure (which in turn passes them on to their LRMd process)." msgstr "" #. Tag: para #, no-c-format msgid "The peer nodes all report the results of their operations back to the DC and, based on the expected and actual results, will either execute any actions that needed to wait for the previous one to complete, or abort processing and ask the PEngine to recalculate the ideal cluster state based on the unexpected results." msgstr "" #. Tag: para #, no-c-format msgid "In some cases, it may be necessary to power off nodes in order to protect shared data or complete resource recovery. For this Pacemaker comes with STONITHd." msgstr "" #. Tag: para #, no-c-format msgid "STONITH is an acronym for Shoot-The-Other-Node-In-The-Head and is usually implemented with a remote power switch." msgstr "" #. Tag: para #, no-c-format msgid "In Pacemaker, STONITH devices are modeled as resources (and configured in the CIB) to enable them to be easily monitored for failure, however STONITHd takes care of understanding the STONITH topology such that its clients simply request a node be fenced and it does the rest." msgstr "" pacemaker-master/doc/Pacemaker_Explained/pot/Ch-Nodes.pot000066400000000000000000000241041217637305600236660ustar00rootroot00000000000000# # AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: 0\n" "POT-Creation-Date: 2012-10-17T05:19:02\n" "PO-Revision-Date: 2012-10-17T05:19:02\n" "Last-Translator: Automatically generated\n" "Language-Team: None\n" "MIME-Version: 1.0\n" "Content-Type: application/x-publican; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. Tag: title #, no-c-format msgid "Cluster Nodes" msgstr "" #. Tag: title #, no-c-format msgid "Defining a Cluster Node" msgstr "" #. Tag: para #, no-c-format msgid "Each node in the cluster will have an entry in the nodes section containing its UUID, uname, and type." msgstr "" #. Tag: title #, no-c-format msgid "Example cluster node entry" msgstr "" #. Tag: programlisting #, no-c-format msgid "<node id=\"1186dc9a-324d-425a-966e-d757e693dc86\" uname=\"pcmk-1\" type=\"normal\"/>" msgstr "" #. Tag: para #, no-c-format msgid "In normal circumstances, the admin should let the cluster populate this information automatically from the communications and membership data. However one can use the crm_uuid tool to read an existing UUID or define a value before the cluster starts." msgstr "" #. Tag: title #, no-c-format msgid "Describing a Cluster Node" msgstr "" #. Tag: para #, no-c-format msgid " Nodeattribute attribute Beyond the basic definition of a node the administrator can also describe the node’s attributes, such as how much RAM, disk, what OS or kernel version it has, perhaps even its physical location. This information can then be used by the cluster when deciding where to place resources. For more information on the use of node attributes, see ." msgstr "" #. Tag: para #, no-c-format msgid "Node attributes can be specified ahead of time or populated later, when the cluster is running, using crm_attribute." msgstr "" #. Tag: para #, no-c-format msgid "Below is what the node’s definition would look like if the admin ran the command:" msgstr "" #. Tag: title #, no-c-format msgid "The result of using crm_attribute to specify which kernel pcmk-1 is running" msgstr "" #. Tag: programlisting #, no-c-format msgid "# crm_attribute --type nodes --node-uname pcmk-1 --attr-name kernel --attr-value `uname -r`" msgstr "" #. Tag: programlisting #, no-c-format msgid "<node uname=\"pcmk-1\" type=\"normal\" id=\"1186dc9a-324d-425a-966e-d757e693dc86\">\n" " <instance_attributes id=\"nodes-1186dc9a-324d-425a-966e-d757e693dc86\">\n" " <nvpair id=\"kernel-1186dc9a-324d-425a-966e-d757e693dc86\" name=\"kernel\" value=\"2.6.16.46-0.4-default\"/>\n" " </instance_attributes>\n" "</node>" msgstr "" #. Tag: para #, no-c-format msgid "A simpler way to determine the current value of an attribute is to use crm_attribute command again:" msgstr "" #. Tag: programlisting #, no-c-format msgid "# crm_attribute --type nodes --node-uname pcmk-1 --attr-name kernel --get-value" msgstr "" #. Tag: para #, no-c-format msgid "By specifying --type nodes the admin tells the cluster that this attribute is persistent. There are also transient attributes which are kept in the status section which are \"forgotten\" whenever the node rejoins the cluster. The cluster uses this area to store a record of how many times a resource has failed on that node but administrators can also read and write to this section by specifying --type status." msgstr "" #. Tag: title #, no-c-format msgid "Adding a New Cluster Node" msgstr "" #. Tag: title #, no-c-format msgid "Corosync" msgstr "" #. Tag: para #, no-c-format msgid " CorosyncAdd Cluster Node Add Cluster Node Add Cluster NodeCorosync Corosync Adding a new node is as simple as installing Corosync and Pacemaker, and copying /etc/corosync/corosync.conf and /etc/ais/authkey (if it exists) from an existing node. You may need to modify the mcastaddr option to match the new node’s IP address." msgstr "" #. Tag: para #, no-c-format msgid "If a log message containing \"Invalid digest\" appears from Corosync, the keys are not consistent between the machines." msgstr "" #. Tag: title #, no-c-format msgid "Heartbeat" msgstr "" #. Tag: para #, no-c-format msgid " HeartbeatAdd Cluster Node Add Cluster Node Add Cluster NodeHeartbeat Heartbeat Provided you specified autojoin any in ha.cf, adding a new node is as simple as installing heartbeat and copying ha.cf and authkeys from an existing node." msgstr "" #. Tag: para #, no-c-format msgid "If you don’t want to use autojoin, then after setting up ha.cf and authkeys, you must use the hb_addnode command before starting the new node." msgstr "" #. Tag: title #, no-c-format msgid "Removing a Cluster Node" msgstr "" #. Tag: para #, no-c-format msgid " CorosyncRemove Cluster Node Remove Cluster Node Remove Cluster NodeCorosync Corosync Because the messaging and membership layers are the authoritative source for cluster nodes, deleting them from the CIB is not a reliable solution. First one must arrange for heartbeat to forget about the node (pcmk-1 in the example below)." msgstr "" #. Tag: para #, no-c-format msgid "On the host to be removed:" msgstr "" #. Tag: para #, no-c-format msgid "Find and record the node’s Corosync id: crm_node -i" msgstr "" #. Tag: para #, no-c-format msgid "Stop the cluster: /etc/init.d/corosync stop" msgstr "" #. Tag: para #, no-c-format msgid "Next, from one of the remaining active cluster nodes:" msgstr "" #. Tag: para #, no-c-format msgid "Tell the cluster to forget about the removed host:" msgstr "" #. Tag: programlisting #, no-c-format msgid "# crm_node -R $COROSYNC_ID" msgstr "" #. Tag: para #, no-c-format msgid "Only now is it safe to delete the node from the CIB with:" msgstr "" #. Tag: programlisting #, no-c-format msgid "# cibadmin --delete --obj_type nodes --crm_xml '<node uname=\"_pcmk-1_\"/>'\n" "# cibadmin --delete --obj_type status --crm_xml '<node_state uname=\"_pcmk-1_\"/>'" msgstr "" #. Tag: para #, no-c-format msgid " HeartbeatRemove Cluster Node Remove Cluster Node Remove Cluster NodeHeartbeat Heartbeat Because the messaging and membership layers are the authoritative source for cluster nodes, deleting them from the CIB is not a reliable solution." msgstr "" #. Tag: para #, no-c-format msgid "First one must arrange for heartbeat to forget about the node (pcmk-1 in the example below). To do this, shut down heartbeat on the node and then, from one of the remaining active cluster nodes, run:" msgstr "" #. Tag: programlisting #, no-c-format msgid "# hb_delnode pcmk-1" msgstr "" #. Tag: para #, no-c-format msgid "Only then is it safe to delete the node from the CIB with:" msgstr "" #. Tag: programlisting #, no-c-format msgid "# cibadmin --delete --obj_type nodes --crm_xml '<node uname=\"pcmk-1\"/>'\n" "# cibadmin --delete --obj_type status --crm_xml '<node_state uname=\"pcmk-1\"/>'" msgstr "" #. Tag: title #, no-c-format msgid "Replacing a Cluster Node" msgstr "" #. Tag: para #, no-c-format msgid " CorosyncReplace Cluster Node Replace Cluster Node Replace Cluster NodeCorosync Corosync The five-step guide to replacing an existing cluster node:" msgstr "" #. Tag: para #, no-c-format msgid "Make sure the old node is completely stopped" msgstr "" #. Tag: para #, no-c-format msgid "Give the new machine the same hostname and IP address as the old one" msgstr "" #. Tag: para #, no-c-format msgid "Install the cluster software :-)" msgstr "" #. Tag: para #, no-c-format msgid "Copy /etc/corosync/corosync.conf and /etc/ais/authkey (if it exists) to the new node" msgstr "" #. Tag: para #, no-c-format msgid "Start the new cluster node" msgstr "" #. Tag: para #, no-c-format msgid " HeartbeatReplace Cluster Node Replace Cluster Node Replace Cluster NodeHeartbeat Heartbeat The seven-step guide to replacing an existing cluster node:" msgstr "" #. Tag: para #, no-c-format msgid "Give the new machine the same hostname as the old one" msgstr "" #. Tag: para #, no-c-format msgid "Go to an active cluster node and look up the UUID for the old node in /var/lib/heartbeat/hostcache" msgstr "" #. Tag: para #, no-c-format msgid "Install the cluster software" msgstr "" #. Tag: para #, no-c-format msgid "Copy ha.cf and authkeys to the new node" msgstr "" #. Tag: para #, no-c-format msgid "On the new node, populate it’s UUID using crm_uuid -w and the UUID from step 2" msgstr "" pacemaker-master/doc/Pacemaker_Explained/pot/Ch-Options.pot000066400000000000000000000530221217637305600242520ustar00rootroot00000000000000# # AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: 0\n" "POT-Creation-Date: 2012-10-17T05:19:02\n" "PO-Revision-Date: 2012-10-17T05:19:02\n" "Last-Translator: Automatically generated\n" "Language-Team: None\n" "MIME-Version: 1.0\n" "Content-Type: application/x-publican; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. Tag: title #, no-c-format msgid "Cluster Options" msgstr "" #. Tag: title #, no-c-format msgid "Special Options" msgstr "" #. Tag: para #, no-c-format msgid "The reason for these fields to be placed at the top level instead of with the rest of cluster options is simply a matter of parsing. These options are used by the configuration database which is, by design, mostly ignorant of the content it holds. So the decision was made to place them in an easy to find location." msgstr "" #. Tag: title #, no-c-format msgid "Configuration Version" msgstr "" #. Tag: para #, no-c-format msgid " Configuration VersionCluster Cluster ClusterOptionConfiguration Version OptionConfiguration Version Configuration Version " msgstr "" #. Tag: para #, no-c-format msgid "When a node joins the cluster, the cluster will perform a check to see who has the best configuration based on the fields below. It then asks the node with the highest (admin_epoch, epoch, num_updates) tuple to replace the configuration on all the nodes - which makes setting them, and setting them correctly, very important." msgstr "" #. Tag: title #, no-c-format msgid "Configuration Version Properties" msgstr "" #. Tag: entry #, no-c-format msgid "Field" msgstr "" #. Tag: entry #, no-c-format msgid "Description" msgstr "" #. Tag: para #, no-c-format msgid "admin_epoch" msgstr "" #. Tag: para #, no-c-format msgid " admin_epochCluster Option Cluster Option ClusterOptionadmin_epoch Optionadmin_epoch admin_epoch Never modified by the cluster. Use this to make the configurations on any inactive nodes obsolete." msgstr "" #. Tag: para #, no-c-format msgid "Never set this value to zero, in such cases the cluster cannot tell the difference between your configuration and the \"empty\" one used when nothing is found on disk." msgstr "" #. Tag: para #, no-c-format msgid "epoch" msgstr "" #. Tag: para #, no-c-format msgid " epochCluster Option Cluster Option ClusterOptionepoch Optionepoch epoch Incremented every time the configuration is updated (usually by the admin)" msgstr "" #. Tag: para #, no-c-format msgid "num_updates" msgstr "" #. Tag: para #, no-c-format msgid " num_updatesCluster Option Cluster Option ClusterOptionnum_updates Optionnum_updates num_updates Incremented every time the configuration or status is updated (usually by the cluster)" msgstr "" #. Tag: title #, no-c-format msgid "Other Fields" msgstr "" #. Tag: title #, no-c-format msgid "Properties Controlling Validation" msgstr "" #. Tag: para #, no-c-format msgid "validate-with" msgstr "" #. Tag: para #, no-c-format msgid " validate-withCluster Option Cluster Option ClusterOptionvalidate-with Optionvalidate-with validate-with Determines the type of validation being done on the configuration. If set to \"none\", the cluster will not verify that updates conform to the DTD (nor reject ones that don’t). This option can be useful when operating a mixed version cluster during an upgrade." msgstr "" #. Tag: title #, no-c-format msgid "Fields Maintained by the Cluster" msgstr "" #. Tag: title #, no-c-format msgid "Properties Maintained by the Cluster" msgstr "" #. Tag: para #, no-c-format msgid "cib-last-written" msgstr "" #. Tag: para #, no-c-format msgid " cib-last-writtenCluster Property Cluster Property ClusterPropertycib-last-written Propertycib-last-written cib-last-written Indicates when the configuration was last written to disk. Informational purposes only." msgstr "" #. Tag: para #, no-c-format msgid "dc-uuid" msgstr "" #. Tag: para #, no-c-format msgid " dc-uuidCluster Property Cluster Property ClusterPropertydc-uuid Propertydc-uuid dc-uuid Indicates which cluster node is the current leader. Used by the cluster when placing resources and determining the order of some events." msgstr "" #. Tag: para #, no-c-format msgid "have-quorum" msgstr "" #. Tag: para #, no-c-format msgid " have-quorumCluster Property Cluster Property ClusterPropertyhave-quorum Propertyhave-quorum have-quorum Indicates if the cluster has quorum. If false, this may mean that the cluster cannot start resources or fence other nodes. See no-quorum-policy below." msgstr "" #. Tag: para #, no-c-format msgid "Note that although these fields can be written to by the admin, in most cases the cluster will overwrite any values specified by the admin with the \"correct\" ones. To change the admin_epoch, for example, one would use:" msgstr "" #. Tag: programlisting #, no-c-format msgid "# cibadmin --modify --crm_xml '<cib admin_epoch=\"42\"/>'" msgstr "" #. Tag: para #, no-c-format msgid "A complete set of fields will look something like this:" msgstr "" #. Tag: title #, no-c-format msgid "An example of the fields set for a cib object" msgstr "" #. Tag: programlisting #, no-c-format msgid "<cib have-quorum=\"true\" validate-with=\"pacemaker-1.0\"\n" " admin_epoch=\"1\" epoch=\"12\" num_updates=\"65\"\n" " dc-uuid=\"ea7d39f4-3b94-4cfa-ba7a-952956daabee\">" msgstr "" #. Tag: para #, no-c-format msgid "Cluster options, as you might expect, control how the cluster behaves when confronted with certain situations." msgstr "" #. Tag: para #, no-c-format msgid "They are grouped into sets and, in advanced configurations, there may be more than one. This will be described later in the section on where we will show how to have the cluster use different sets of options during working hours (when downtime is usually to be avoided at all costs) than it does during the weekends (when resources can be moved to the their preferred hosts without bothering end users) For now we will describe the simple case where each option is present at most once." msgstr "" #. Tag: title #, no-c-format msgid "Available Cluster Options" msgstr "" #. Tag: entry #, no-c-format msgid "Option" msgstr "" #. Tag: entry #, no-c-format msgid "Default" msgstr "" #. Tag: para #, no-c-format msgid "batch-limit" msgstr "" #. Tag: para #, no-c-format msgid "30" msgstr "" #. Tag: para #, no-c-format msgid " batch-limitCluster Option Cluster Option ClusterOptionbatch-limit Optionbatch-limit batch-limit The number of jobs that the TE is allowed to execute in parallel. The \"correct\" value will depend on the speed and load of your network and cluster nodes." msgstr "" #. Tag: para #, no-c-format msgid "migration-limit" msgstr "" #. Tag: para #, no-c-format msgid "-1 (unlimited)" msgstr "" #. Tag: para #, no-c-format msgid " migration-limitCluster Option Cluster Option ClusterOptionmigration-limit Optionmigration-limit migration-limit The number of migration jobs that the TE is allowed to execute in parallel on a node." msgstr "" #. Tag: para #, no-c-format msgid "no-quorum-policy" msgstr "" #. Tag: para #, no-c-format msgid "stop" msgstr "" #. Tag: para #, no-c-format msgid " no-quorum-policyCluster Option Cluster Option ClusterOptionno-quorum-policy Optionno-quorum-policy no-quorum-policy What to do when the cluster does not have quorum. Allowed values:" msgstr "" #. Tag: para #, no-c-format msgid "* ignore - continue all resource management" msgstr "" #. Tag: para #, no-c-format msgid "* freeze - continue resource management, but don’t recover resources from nodes not in the affected partition" msgstr "" #. Tag: para #, no-c-format msgid "* stop - stop all resources in the affected cluster partition" msgstr "" #. Tag: para #, no-c-format msgid "* suicide - fence all nodes in the affected cluster partition" msgstr "" #. Tag: para #, no-c-format msgid "symmetric-cluster" msgstr "" #. Tag: para #, no-c-format msgid "TRUE" msgstr "" #. Tag: para #, no-c-format msgid " symmetric-clusterCluster Option Cluster Option ClusterOptionsymmetric-cluster Optionsymmetric-cluster symmetric-cluster Can all resources run on any node by default?" msgstr "" #. Tag: para #, no-c-format msgid "stonith-enabled" msgstr "" #. Tag: para #, no-c-format msgid " stonith-enabledCluster Option Cluster Option ClusterOptionstonith-enabled Optionstonith-enabled stonith-enabled Should failed nodes and nodes with resources that can’t be stopped be shot? If you value your data, set up a STONITH device and enable this." msgstr "" #. Tag: para #, no-c-format msgid "If true, or unset, the cluster will refuse to start resources unless one or more STONITH resources have been configured also." msgstr "" #. Tag: para #, no-c-format msgid "stonith-action" msgstr "" #. Tag: para #, no-c-format msgid "reboot" msgstr "" #. Tag: para #, no-c-format msgid " stonith-actionCluster Option Cluster Option ClusterOptionstonith-action Optionstonith-action stonith-action Action to send to STONITH device. Allowed values: reboot, off. The value poweroff is also allowed, but is only used for legacy devices." msgstr "" #. Tag: para #, no-c-format msgid "cluster-delay" msgstr "" #. Tag: para #, no-c-format msgid "60s" msgstr "" #. Tag: para #, no-c-format msgid " cluster-delayCluster Option Cluster Option ClusterOptioncluster-delay Optioncluster-delay cluster-delay Round trip delay over the network (excluding action execution). The \"correct\" value will depend on the speed and load of your network and cluster nodes." msgstr "" #. Tag: para #, no-c-format msgid "stop-orphan-resources" msgstr "" #. Tag: para #, no-c-format msgid " stop-orphan-resourcesCluster Option Cluster Option ClusterOptionstop-orphan-resources Optionstop-orphan-resources stop-orphan-resources Should deleted resources be stopped?" msgstr "" #. Tag: para #, no-c-format msgid "stop-orphan-actions" msgstr "" #. Tag: para #, no-c-format msgid " stop-orphan-actionsCluster Option Cluster Option ClusterOptionstop-orphan-actions Optionstop-orphan-actions stop-orphan-actions Should deleted actions be cancelled?" msgstr "" #. Tag: para #, no-c-format msgid "start-failure-is-fatal" msgstr "" #. Tag: para #, no-c-format msgid " start-failure-is-fatalCluster Option Cluster Option ClusterOptionstart-failure-is-fatal Optionstart-failure-is-fatal start-failure-is-fatal When set to FALSE, the cluster will instead use the resource’s failcount and value for resource-failure-stickiness." msgstr "" #. Tag: para #, no-c-format msgid "pe-error-series-max" msgstr "" #. Tag: para #, no-c-format msgid "-1 (all)" msgstr "" #. Tag: para #, no-c-format msgid " pe-error-series-maxCluster Option Cluster Option ClusterOptionpe-error-series-max Optionpe-error-series-max pe-error-series-max The number of PE inputs resulting in ERRORs to save. Used when reporting problems." msgstr "" #. Tag: para #, no-c-format msgid "pe-warn-series-max" msgstr "" #. Tag: para #, no-c-format msgid " pe-warn-series-maxCluster Option Cluster Option ClusterOptionpe-warn-series-max Optionpe-warn-series-max pe-warn-series-max The number of PE inputs resulting in WARNINGs to save. Used when reporting problems." msgstr "" #. Tag: para #, no-c-format msgid "pe-input-series-max" msgstr "" #. Tag: para #, no-c-format msgid " pe-input-series-maxCluster Option Cluster Option ClusterOptionpe-input-series-max Optionpe-input-series-max pe-input-series-max The number of \"normal\" PE inputs to save. Used when reporting problems." msgstr "" #. Tag: para #, no-c-format msgid "You can always obtain an up-to-date list of cluster options, including their default values, by running the pengine metadata command." msgstr "" #. Tag: title #, no-c-format msgid "Querying and Setting Cluster Options" msgstr "" #. Tag: para #, no-c-format msgid " QueryingCluster Option Cluster Option SettingCluster Option Cluster Option ClusterQuerying Options Querying Options ClusterSetting Options Setting Options " msgstr "" #. Tag: para #, no-c-format msgid "Cluster options can be queried and modified using the crm_attribute tool. To get the current value of cluster-delay, simply use:" msgstr "" #. Tag: programlisting #, no-c-format msgid "# crm_attribute --attr-name cluster-delay --get-value" msgstr "" #. Tag: para #, no-c-format msgid "which is more simply written as" msgstr "" #. Tag: programlisting #, no-c-format msgid "# crm_attribute --get-value -n cluster-delay" msgstr "" #. Tag: para #, no-c-format msgid "If a value is found, you’ll see a result like this:" msgstr "" #. Tag: programlisting #, no-c-format msgid "# crm_attribute --get-value -n cluster-delay\n" " name=cluster-delay value=60s" msgstr "" #. Tag: para #, no-c-format msgid "However, if no value is found, the tool will display an error:" msgstr "" #. Tag: programlisting #, no-c-format msgid "# crm_attribute --get-value -n clusta-deway`\n" "name=clusta-deway value=(null)\n" "Error performing operation: The object/attribute does not exist" msgstr "" #. Tag: para #, no-c-format msgid "To use a different value, eg. 30, simply run:" msgstr "" #. Tag: programlisting #, no-c-format msgid "# crm_attribute --attr-name cluster-delay --attr-value 30s" msgstr "" #. Tag: para #, no-c-format msgid "To go back to the cluster’s default value you can delete the value, for example with this command:" msgstr "" #. Tag: programlisting #, no-c-format msgid "# crm_attribute --attr-name cluster-delay --delete-attr" msgstr "" #. Tag: title #, no-c-format msgid "When Options are Listed More Than Once" msgstr "" #. Tag: para #, no-c-format msgid "If you ever see something like the following, it means that the option you’re modifying is present more than once." msgstr "" #. Tag: title #, no-c-format msgid "Deleting an option that is listed twice" msgstr "" #. Tag: programlisting #, no-c-format msgid "# crm_attribute --attr-name batch-limit --delete-attr\n" "\n" "Multiple attributes match name=batch-limit in crm_config:\n" "Value: 50 (set=cib-bootstrap-options, id=cib-bootstrap-options-batch-limit)\n" "Value: 100 (set=custom, id=custom-batch-limit)\n" "Please choose from one of the matches above and supply the 'id' with --attr-id" msgstr "" #. Tag: para #, no-c-format msgid "In such cases follow the on-screen instructions to perform the requested action. To determine which value is currently being used by the cluster, please refer to ." msgstr "" pacemaker-master/doc/Pacemaker_Explained/pot/Ch-Resources.pot000066400000000000000000001172461217637305600246020ustar00rootroot00000000000000# # AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: 0\n" "POT-Creation-Date: 2012-10-17T05:19:02\n" "PO-Revision-Date: 2012-10-17T05:19:02\n" "Last-Translator: Automatically generated\n" "Language-Team: None\n" "MIME-Version: 1.0\n" "Content-Type: application/x-publican; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. Tag: title #, no-c-format msgid "Cluster Resources" msgstr "" #. Tag: title #, no-c-format msgid "What is a Cluster Resource" msgstr "" #. Tag: para #, no-c-format msgid " Resource " msgstr "" #. Tag: para #, no-c-format msgid "The role of a resource agent is to abstract the service it provides and present a consistent view to the cluster, which allows the cluster to be agnostic about the resources it manages." msgstr "" #. Tag: para #, no-c-format msgid "The cluster doesn’t need to understand how the resource works because it relies on the resource agent to do the right thing when given a start, stop or monitor command." msgstr "" #. Tag: para #, no-c-format msgid "For this reason it is crucial that resource agents are well tested." msgstr "" #. Tag: para #, no-c-format msgid "Typically resource agents come in the form of shell scripts, however they can be written using any technology (such as C, Python or Perl) that the author is comfortable with." msgstr "" #. Tag: title #, no-c-format msgid "Supported Resource Classes" msgstr "" #. Tag: para #, no-c-format msgid " Resourceclass class " msgstr "" #. Tag: para #, no-c-format msgid "There are five classes of agents supported by Pacemaker:" msgstr "" #. Tag: para #, no-c-format msgid "OCF" msgstr "" #. Tag: para #, no-c-format msgid "LSB" msgstr "" #. Tag: para #, no-c-format msgid "Upstart" msgstr "" #. Tag: para #, no-c-format msgid "Systemd" msgstr "" #. Tag: para #, no-c-format msgid "Fencing" msgstr "" #. Tag: para #, no-c-format msgid "Service" msgstr "" #. Tag: para #, no-c-format msgid " ResourceHeartbeat Heartbeat HeartbeatResources Resources " msgstr "" #. Tag: para #, no-c-format msgid "Version 1 of Heartbeat came with its own style of resource agents and it is highly likely that many people have written their own agents based on its conventions. See http://wiki.linux-ha.org/HeartbeatResourceAgent for more information " msgstr "" #. Tag: para #, no-c-format msgid "Although deprecated with the release of Heartbeat v2, they were supported by Pacemaker up until the release of 1.1.8 to enable administrators to continue to use these agents." msgstr "" #. Tag: title #, no-c-format msgid "Open Cluster Framework" msgstr "" #. Tag: para #, no-c-format msgid " ResourceOCF OCF OCFResources Resources Open Cluster FrameworkResources Resources " msgstr "" #. Tag: para #, no-c-format msgid "The OCF standard http://www.opencf.org/cgi-bin/viewcvs.cgi/specs/ra/resource-agent-api.txt?rev=HEAD - at least as it relates to resource agents. The Pacemaker implementation has been somewhat extended from the OCF Specs, but none of those changes are incompatible with the original OCF specification. is basically an extension of the Linux Standard Base conventions for init scripts to:" msgstr "" #. Tag: para #, no-c-format msgid "support parameters," msgstr "" #. Tag: para #, no-c-format msgid "make them self describing and" msgstr "" #. Tag: para #, no-c-format msgid "extensible" msgstr "" #. Tag: para #, no-c-format msgid "OCF specs have strict definitions of the exit codes that actions must return. Included with the cluster is the ocf-tester script, which can be useful in this regard. " msgstr "" #. Tag: para #, no-c-format msgid "The cluster follows these specifications exactly, and giving the wrong exit code will cause the cluster to behave in ways you will likely find puzzling and annoying. In particular, the cluster needs to distinguish a completely stopped resource from one which is in some erroneous and indeterminate state." msgstr "" #. Tag: para #, no-c-format msgid "Parameters are passed to the script as environment variables, with the special prefix OCF_RESKEY_. So, a parameter which the user thinks of as ip it will be passed to the script as OCF_RESKEY_ip. The number and purpose of the parameters is completely arbitrary, however your script should advertise any that it supports using the meta-data command." msgstr "" #. Tag: para #, no-c-format msgid "The OCF class is the most preferred one as it is an industry standard, highly flexible (allowing parameters to be passed to agents in a non-positional manner) and self-describing." msgstr "" #. Tag: para #, no-c-format msgid "For more information, see the reference and ." msgstr "" #. Tag: title #, no-c-format msgid "Linux Standard Base" msgstr "" #. Tag: para #, no-c-format msgid " ResourceLSB LSB LSBResources Resources Linux Standard BaseResources Resources " msgstr "" #. Tag: para #, no-c-format msgid "LSB resource agents are those found in /etc/init.d." msgstr "" #. Tag: para #, no-c-format msgid "Generally they are provided by the OS/distribution and, in order to be used with the cluster, they must conform to the LSB Spec. See http://refspecs.linux-foundation.org/LSB_3.0.0/LSB-Core-generic/LSB-Core-generic/iniscrptact.html for the LSB Spec (as it relates to init scripts). " msgstr "" #. Tag: para #, no-c-format msgid "Many distributions claim LSB compliance but ship with broken init scripts. For details on how to check if your init script is LSB-compatible, see . The most common problems are:" msgstr "" #. Tag: para #, no-c-format msgid "Not implementing the status operation at all" msgstr "" #. Tag: para #, no-c-format msgid "Not observing the correct exit status codes for start/stop/status actions" msgstr "" #. Tag: para #, no-c-format msgid "Starting a started resource returns an error (this violates the LSB spec)" msgstr "" #. Tag: para #, no-c-format msgid "Stopping a stopped resource returns an error (this violates the LSB spec)" msgstr "" #. Tag: para #, no-c-format msgid " ResourceSystemd Systemd SystemdResources Resources " msgstr "" #. Tag: para #, no-c-format msgid "Some newer distributions have replaced the old SYS-V style of initialization daemons (and scripts) with an alternative called Systemd." msgstr "" #. Tag: para #, no-c-format msgid "Pacemaker is able to manage these services if they are present." msgstr "" #. Tag: para #, no-c-format msgid "Instead of init scripts, systemd has unit files. Generally the services (or unit files) are provided by the OS/distribution but there are some instructions for converting from init scripts at: http://0pointer.de/blog/projects/systemd-for-admins-3.html" msgstr "" #. Tag: para #, no-c-format msgid "Remember to make sure the computer is not configured to start any services at boot time that should be controlled by the cluster." msgstr "" #. Tag: para #, no-c-format msgid " ResourceUpstart Upstart UpstartResources Resources " msgstr "" #. Tag: para #, no-c-format msgid "Some newer distributions have replaced the old SYS-V style of initialization daemons (and scripts) with an alternative called Upstart." msgstr "" #. Tag: para #, no-c-format msgid "Instead of init scripts, upstart has jobs. Generally the services (or jobs) are provided by the OS/distribution." msgstr "" #. Tag: title #, no-c-format msgid "System Services" msgstr "" #. Tag: para #, no-c-format msgid " ResourceSystem Services System Services System ServiceResources Resources " msgstr "" #. Tag: para #, no-c-format msgid "Since there are now many \"common\" types of system services (systemd, upstart, and lsb), Pacemaker supports a special alias which intelligently figures out which one applies to a given cluster node." msgstr "" #. Tag: para #, no-c-format msgid "This is particularly useful when the cluster contains a mix of systemd, upstart, and lsb." msgstr "" #. Tag: para #, no-c-format msgid "In order, Pacemaker will try to find the named service as:" msgstr "" #. Tag: para #, no-c-format msgid "an LSB (SYS-V) init script" msgstr "" #. Tag: para #, no-c-format msgid "a Systemd unit file" msgstr "" #. Tag: para #, no-c-format msgid "an Upstart job" msgstr "" #. Tag: title #, no-c-format msgid "STONITH" msgstr "" #. Tag: para #, no-c-format msgid " ResourceSTONITH STONITH STONITHResources Resources " msgstr "" #. Tag: para #, no-c-format msgid "There is also an additional class, STONITH, which is used exclusively for fencing related resources. This is discussed later in ." msgstr "" #. Tag: title #, no-c-format msgid "Resource Properties" msgstr "" #. Tag: para #, no-c-format msgid "These values tell the cluster which script to use for the resource, where to find that script and what standards it conforms to." msgstr "" #. Tag: title #, no-c-format msgid "Properties of a Primitive Resource" msgstr "" #. Tag: entry #, no-c-format msgid "Field" msgstr "" #. Tag: entry #, no-c-format msgid "Description" msgstr "" #. Tag: para #, no-c-format msgid "id" msgstr "" #. Tag: para #, no-c-format msgid "Your name for the resource idResource Resource ResourcePropertyid Propertyid id " msgstr "" #. Tag: para #, no-c-format msgid "class" msgstr "" #. Tag: para #, no-c-format msgid "The standard the script conforms to. Allowed values: ocf, service, upstart, systemd, lsb, stonith classResource Resource ResourcePropertyclass Propertyclass class " msgstr "" #. Tag: para #, no-c-format msgid "type" msgstr "" #. Tag: para #, no-c-format msgid "The name of the Resource Agent you wish to use. Eg. IPaddr or Filesystem typeResource Resource ResourcePropertytype Propertytype type " msgstr "" #. Tag: para #, no-c-format msgid "provider" msgstr "" #. Tag: para #, no-c-format msgid "The OCF spec allows multiple vendors to supply the same ResourceAgent. To use the OCF resource agents supplied with Heartbeat, you should specify heartbeat here. providerResource Resource ResourcePropertyprovider Propertyprovider provider " msgstr "" #. Tag: para #, no-c-format msgid "Resource definitions can be queried with the crm_resource tool. For example" msgstr "" #. Tag: programlisting #, no-c-format msgid "# crm_resource --resource Email --query-xml" msgstr "" #. Tag: para #, no-c-format msgid "might produce:" msgstr "" #. Tag: title #, no-c-format msgid "An example system resource" msgstr "" #. Tag: programlisting #, no-c-format msgid "<primitive id=\"Email\" class=\"service\" type=\"exim\"/>" msgstr "" #. Tag: para #, no-c-format msgid "One of the main drawbacks to system services (such as LSB, Systemd and Upstart) resources is that they do not allow any parameters!" msgstr "" #. Tag: title #, no-c-format msgid "An example OCF resource" msgstr "" #. Tag: programlisting #, no-c-format msgid "<primitive id=\"Public-IP\" class=\"ocf\" type=\"IPaddr\" provider=\"heartbeat\">\n" " <instance_attributes id=\"params-public-ip\">\n" " <nvpair id=\"public-ip-addr\" name=\"ip\" value=\"1.2.3.4\"/>\n" " </instance_attributes>\n" "</primitive>" msgstr "" #. Tag: title #, no-c-format msgid "Resource Options" msgstr "" #. Tag: para #, no-c-format msgid "Options are used by the cluster to decide how your resource should behave and can be easily set using the --meta option of the crm_resource command." msgstr "" #. Tag: title #, no-c-format msgid "Options for a Primitive Resource" msgstr "" #. Tag: entry #, no-c-format msgid "Default" msgstr "" #. Tag: para #, no-c-format msgid "priority" msgstr "" #. Tag: para #, no-c-format msgid "0" msgstr "" #. Tag: para #, no-c-format msgid "If not all resources can be active, the cluster will stop lower priority resources in order to keep higher priority ones active. priorityResource Option Resource Option ResourceOptionpriority Optionpriority priority " msgstr "" #. Tag: para #, no-c-format msgid "target-role" msgstr "" #. Tag: para #, no-c-format msgid "Started" msgstr "" #. Tag: para #, no-c-format msgid "What state should the cluster attempt to keep this resource in? Allowed values:" msgstr "" #. Tag: para #, no-c-format msgid "* Stopped - Force the resource to be stopped" msgstr "" #. Tag: para #, no-c-format msgid "* Started - Allow the resource to be started (In the case of multi-state resources, they will not promoted to master)" msgstr "" #. Tag: para #, no-c-format msgid "* Master - Allow the resource to be started and, if appropriate, promoted target-roleResource Option Resource Option ResourceOptiontarget-role Optiontarget-role target-role " msgstr "" #. Tag: para #, no-c-format msgid "is-managed" msgstr "" #. Tag: para #, no-c-format msgid "TRUE" msgstr "" #. Tag: para #, no-c-format msgid "Is the cluster allowed to start and stop the resource? Allowed values: true, false is-managedResource Option Resource Option ResourceOptionis-managed Optionis-managed is-managed " msgstr "" #. Tag: para #, no-c-format msgid "resource-stickiness" msgstr "" #. Tag: para #, no-c-format msgid "Calculated" msgstr "" #. Tag: para #, no-c-format msgid "How much does the resource prefer to stay where it is? Defaults to the value of resource-stickiness in the rsc_defaults section resource-stickinessResource Option Resource Option ResourceOptionresource-stickiness Optionresource-stickiness resource-stickiness " msgstr "" #. Tag: para #, no-c-format msgid "requires" msgstr "" #. Tag: para #, no-c-format msgid "Under what conditions can the resource be started. (Since 1.1.8)" msgstr "" #. Tag: para #, no-c-format msgid "Defaults to fencing unless stonith-enabled is false or class is stonith - under those conditions the default is quorum. Possible values:" msgstr "" #. Tag: para #, no-c-format msgid "* nothing - can always be started" msgstr "" #. Tag: para #, no-c-format msgid "* quorum - The cluster can only start this resource if a majority of the configured nodes are active" msgstr "" #. Tag: para #, no-c-format msgid "* fencing - The cluster can only start this resource if a majority of the configured nodes are active and any failed or unknown nodes have been powered off." msgstr "" #. Tag: para #, no-c-format msgid "* unfencing - The cluster can only start this resource if a majority of the configured nodes are active and any failed or unknown nodes have been powered off and only on nodes that have been unfenced indexterm: Option[requires,Resource] ResourceOptionrequires Optionrequires requires " msgstr "" #. Tag: para #, no-c-format msgid "migration-threshold" msgstr "" #. Tag: para #, no-c-format msgid "INFINITY (disabled)" msgstr "" #. Tag: para #, no-c-format msgid "How many failures may occur for this resource on a node, before this node is marked ineligible to host this resource. migration-thresholdResource Option Resource Option ResourceOptionmigration-threshold Optionmigration-threshold migration-threshold " msgstr "" #. Tag: para #, no-c-format msgid "failure-timeout" msgstr "" #. Tag: para #, no-c-format msgid "0 (disabled)" msgstr "" #. Tag: para #, no-c-format msgid "How many seconds to wait before acting as if the failure had not occurred, and potentially allowing the resource back to the node on which it failed. failure-timeoutResource Option Resource Option ResourceOptionfailure-timeout Optionfailure-timeout failure-timeout " msgstr "" #. Tag: para #, no-c-format msgid "multiple-active" msgstr "" #. Tag: para #, no-c-format msgid "stop_start" msgstr "" #. Tag: para #, no-c-format msgid "What should the cluster do if it ever finds the resource active on more than one node. Allowed values:" msgstr "" #. Tag: para #, no-c-format msgid "* block - mark the resource as unmanaged" msgstr "" #. Tag: para #, no-c-format msgid "* stop_only - stop all active instances and leave them that way" msgstr "" #. Tag: para #, no-c-format msgid "* stop_start - stop all active instances and start the resource in one location only" msgstr "" #. Tag: para #, no-c-format msgid " multiple-activeResource Option Resource Option ResourceOptionmultiple-active Optionmultiple-active multiple-active " msgstr "" #. Tag: para #, no-c-format msgid "If you performed the following commands on the previous LSB Email resource" msgstr "" #. Tag: programlisting #, no-c-format msgid "# crm_resource --meta --resource Email --set-parameter priority --property-value 100\n" "# crm_resource --meta --resource Email --set-parameter multiple-active --property-value block" msgstr "" #. Tag: para #, no-c-format msgid "the resulting resource definition would be" msgstr "" #. Tag: title #, no-c-format msgid "An LSB resource with cluster options" msgstr "" #. Tag: programlisting #, no-c-format msgid "<primitive id=\"Email\" class=\"lsb\" type=\"exim\">\n" " <meta_attributes id=\"meta-email\">\n" " <nvpair id=\"email-priority\" name=\"priority\" value=\"100\"/>\n" " <nvpair id=\"email-active\" name=\"multiple-active\" value=\"block\"/>\n" " </meta_attributes>\n" "</primitive>" msgstr "" #. Tag: title #, no-c-format msgid "Setting Global Defaults for Resource Options" msgstr "" #. Tag: para #, no-c-format msgid "To set a default value for a resource option, simply add it to the rsc_defaults section with crm_attribute. Thus," msgstr "" #. Tag: programlisting #, no-c-format msgid "# crm_attribute --type rsc_defaults --attr-name is-managed --attr-value false" msgstr "" #. Tag: para #, no-c-format msgid "would prevent the cluster from starting or stopping any of the resources in the configuration (unless of course the individual resources were specifically enabled and had is-managed set to true)." msgstr "" #. Tag: title #, no-c-format msgid "Instance Attributes" msgstr "" #. Tag: para #, no-c-format msgid "The scripts of some resource classes (LSB not being one of them) can be given parameters which determine how they behave and which instance of a service they control." msgstr "" #. Tag: para #, no-c-format msgid "If your resource agent supports parameters, you can add them with the crm_resource command. For instance" msgstr "" #. Tag: programlisting #, no-c-format msgid "# crm_resource --resource Public-IP --set-parameter ip --property-value 1.2.3.4" msgstr "" #. Tag: para #, no-c-format msgid "would create an entry in the resource like this:" msgstr "" #. Tag: title #, no-c-format msgid "An example OCF resource with instance attributes" msgstr "" #. Tag: para #, no-c-format msgid "For an OCF resource, the result would be an environment variable called OCF_RESKEY_ip with a value of 1.2.3.4." msgstr "" #. Tag: para #, no-c-format msgid "The list of instance attributes supported by an OCF script can be found by calling the resource script with the meta-data command. The output contains an XML description of all the supported attributes, their purpose and default values." msgstr "" #. Tag: title #, no-c-format msgid "Displaying the metadata for the Dummy resource agent template" msgstr "" #. Tag: programlisting #, no-c-format msgid "# export OCF_ROOT=/usr/lib/ocf\n" "# $OCF_ROOT/resource.d/pacemaker/Dummy meta-data" msgstr "" #. Tag: programlisting #, no-c-format msgid "<?xml version=\"1.0\"?>\n" " <!DOCTYPE resource-agent SYSTEM \"ra-api-1.dtd\">\n" " <resource-agent name=\"Dummy\" version=\"0.9\">\n" " <version>1.0</version>\n" "\n" " <longdesc lang=\"en-US\">\n" " This is a Dummy Resource Agent. It does absolutely nothing except\n" " keep track of whether its running or not.\n" " Its purpose in life is for testing and to serve as a template for RA writers.\n" " </longdesc>\n" " <shortdesc lang=\"en-US\">Dummy resource agent</shortdesc>\n" "\n" " <parameters>\n" " <parameter name=\"state\" unique=\"1\">\n" " <longdesc lang=\"en-US\">\n" " Location to store the resource state in.\n" " </longdesc>\n" " <shortdesc lang=\"en-US\">State file</shortdesc>\n" " <content type=\"string\" default=\"/var/run/Dummy-{OCF_RESOURCE_INSTANCE}.state\" />\n" " </parameter>\n" "\n" " <parameter name=\"dummy\" unique=\"0\">\n" " <longdesc lang=\"en-US\">\n" " Dummy attribute that can be changed to cause a reload\n" " </longdesc>\n" " <shortdesc lang=\"en-US\">Dummy attribute that can be changed to cause a reload</shortdesc>\n" " <content type=\"string\" default=\"blah\" />\n" " </parameter>\n" " </parameters>\n" "\n" " <actions>\n" " <action name=\"start\" timeout=\"90\" />\n" " <action name=\"stop\" timeout=\"100\" />\n" " <action name=\"monitor\" timeout=\"20\" interval=\"10\",height=\"0\" start-delay=\"0\" />\n" " <action name=\"reload\" timeout=\"90\" />\n" " <action name=\"migrate_to\" timeout=\"100\" />\n" " <action name=\"migrate_from\" timeout=\"90\" />\n" " <action name=\"meta-data\" timeout=\"5\" />\n" " <action name=\"validate-all\" timeout=\"30\" />\n" " </actions>\n" " </resource-agent>" msgstr "" #. Tag: title #, no-c-format msgid "Resource Operations" msgstr "" #. Tag: para #, no-c-format msgid " ResourceAction Action " msgstr "" #. Tag: title #, no-c-format msgid "Monitoring Resources for Failure" msgstr "" #. Tag: para #, no-c-format msgid "By default, the cluster will not ensure your resources are still healthy. To instruct the cluster to do this, you need to add a monitor operation to the resource’s definition." msgstr "" #. Tag: title #, no-c-format msgid "An OCF resource with a recurring health check" msgstr "" #. Tag: programlisting #, no-c-format msgid "<primitive id=\"Public-IP\" class=\"ocf\" type=\"IPaddr\" provider=\"heartbeat\">\n" " <operations>\n" " <op id=\"public-ip-check\" name=\"monitor\" interval=\"60s\"/>\n" " </operations>\n" " <instance_attributes id=\"params-public-ip\">\n" " <nvpair id=\"public-ip-addr\" name=\"ip\" value=\"1.2.3.4\"/>\n" " </instance_attributes>\n" "</primitive>" msgstr "" #. Tag: title #, no-c-format msgid "Properties of an Operation" msgstr "" #. Tag: para #, no-c-format msgid "Your name for the action. Must be unique. idAction Property Action Property ActionPropertyid Propertyid id " msgstr "" #. Tag: para #, no-c-format msgid "name" msgstr "" #. Tag: para #, no-c-format msgid "The action to perform. Common values: monitor, start, stop nameAction Property Action Property ActionPropertyname Propertyname name " msgstr "" #. Tag: para #, no-c-format msgid "interval" msgstr "" #. Tag: para #, no-c-format msgid "How frequently (in seconds) to perform the operation. Default value: 0, meaning never. intervalAction Property Action Property ActionPropertyinterval Propertyinterval interval " msgstr "" #. Tag: para #, no-c-format msgid "timeout" msgstr "" #. Tag: para #, no-c-format msgid "How long to wait before declaring the action has failed. timeoutAction Property Action Property ActionPropertytimeout Propertytimeout timeout " msgstr "" #. Tag: para #, no-c-format msgid "on-fail" msgstr "" #. Tag: para #, no-c-format msgid "The action to take if this action ever fails. Allowed values:" msgstr "" #. Tag: para #, no-c-format msgid "* ignore - Pretend the resource did not fail" msgstr "" #. Tag: para #, no-c-format msgid "* block - Don’t perform any further operations on the resource" msgstr "" #. Tag: para #, no-c-format msgid "* stop - Stop the resource and do not start it elsewhere" msgstr "" #. Tag: para #, no-c-format msgid "* restart - Stop the resource and start it again (possibly on a different node)" msgstr "" #. Tag: para #, no-c-format msgid "* fence - STONITH the node on which the resource failed" msgstr "" #. Tag: para #, no-c-format msgid "* standby - Move all resources away from the node on which the resource failed" msgstr "" #. Tag: para #, no-c-format msgid "The default for the stop operation is fence when STONITH is enabled and block otherwise. All other operations default to stop. on-failAction Property Action Property ActionPropertyon-fail Propertyon-fail on-fail " msgstr "" #. Tag: para #, no-c-format msgid "enabled" msgstr "" #. Tag: para #, no-c-format msgid "If false, the operation is treated as if it does not exist. Allowed values: true, false enabledAction Property Action Property ActionPropertyenabled Propertyenabled enabled " msgstr "" #. Tag: title #, no-c-format msgid "Setting Global Defaults for Operations" msgstr "" #. Tag: para #, no-c-format msgid "To set a default value for a operation option, simply add it to the op_defaults section with crm_attribute. Thus," msgstr "" #. Tag: programlisting #, no-c-format msgid "# crm_attribute --type op_defaults --attr-name timeout --attr-value 20s" msgstr "" #. Tag: para #, no-c-format msgid "would default each operation’s timeout to 20 seconds. If an operation’s definition also includes a value for timeout, then that value would be used instead (for that operation only)." msgstr "" #. Tag: title #, no-c-format msgid "When Resources Take a Long Time to Start/Stop" msgstr "" #. Tag: para #, no-c-format msgid "There are a number of implicit operations that the cluster will always perform - start, stop and a non-recurring monitor operation (used at startup to check the resource isn’t already active). If one of these is taking too long, then you can create an entry for them and simply specify a new value." msgstr "" #. Tag: title #, no-c-format msgid "An OCF resource with custom timeouts for its implicit actions" msgstr "" #. Tag: programlisting #, no-c-format msgid "<primitive id=\"Public-IP\" class=\"ocf\" type=\"IPaddr\" provider=\"heartbeat\">\n" " <operations>\n" " <op id=\"public-ip-startup\" name=\"monitor\" interval=\"0\" timeout=\"90s\"/>\n" " <op id=\"public-ip-start\" name=\"start\" interval=\"0\" timeout=\"180s\"/>\n" " <op id=\"public-ip-stop\" name=\"stop\" interval=\"0\" timeout=\"15min\"/>\n" " </operations>\n" " <instance_attributes id=\"params-public-ip\">\n" " <nvpair id=\"public-ip-addr\" name=\"ip\" value=\"1.2.3.4\"/>\n" " </instance_attributes>\n" "</primitive>" msgstr "" #. Tag: title #, no-c-format msgid "Multiple Monitor Operations" msgstr "" #. Tag: para #, no-c-format msgid "Provided no two operations (for a single resource) have the same name and interval you can have as many monitor operations as you like. In this way you can do a superficial health check every minute and progressively more intense ones at higher intervals." msgstr "" #. Tag: para #, no-c-format msgid "To tell the resource agent what kind of check to perform, you need to provide each monitor with a different value for a common parameter. The OCF standard creates a special parameter called OCF_CHECK_LEVEL for this purpose and dictates that it is \"made available to the resource agent without the normal OCF_RESKEY prefix\"." msgstr "" #. Tag: para #, no-c-format msgid "Whatever name you choose, you can specify it by adding an instance_attributes block to the op tag. Note that it is up to each resource agent to look for the parameter and decide how to use it." msgstr "" #. Tag: title #, no-c-format msgid "An OCF resource with two recurring health checks, performing different levels of checks - specified via OCF_CHECK_LEVEL." msgstr "" #. Tag: programlisting #, no-c-format msgid "<primitive id=\"Public-IP\" class=\"ocf\" type=\"IPaddr\" provider=\"heartbeat\">\n" " <operations>\n" " <op id=\"public-ip-health-60\" name=\"monitor\" interval=\"60\">\n" " <instance_attributes id=\"params-public-ip-depth-60\">\n" " <nvpair id=\"public-ip-depth-60\" name=\"OCF_CHECK_LEVEL\" value=\"10\"/>\n" " </instance_attributes>\n" " </op>\n" " <op id=\"public-ip-health-300\" name=\"monitor\" interval=\"300\">\n" " <instance_attributes id=\"params-public-ip-depth-300\">\n" " <nvpair id=\"public-ip-depth-300\" name=\"OCF_CHECK_LEVEL\" value=\"20\"/>\n" " </instance_attributes>\n" " </op>\n" " </operations>\n" " <instance_attributes id=\"params-public-ip\">\n" " <nvpair id=\"public-ip-level\" name=\"ip\" value=\"1.2.3.4\"/>\n" " </instance_attributes>\n" "</primitive>" msgstr "" #. Tag: title #, no-c-format msgid "Disabling a Monitor Operation" msgstr "" #. Tag: para #, no-c-format msgid "The easiest way to stop a recurring monitor is to just delete it. However, there can be times when you only want to disable it temporarily. In such cases, simply add enabled=\"false\" to the operation’s definition." msgstr "" #. Tag: title #, no-c-format msgid "Example of an OCF resource with a disabled health check" msgstr "" #. Tag: programlisting #, no-c-format msgid "<primitive id=\"Public-IP\" class=\"ocf\" type=\"IPaddr\" provider=\"heartbeat\">\n" " <operations>\n" " <op id=\"public-ip-check\" name=\"monitor\" interval=\"60s\" enabled=\"false\"/>\n" " </operations>\n" " <instance_attributes id=\"params-public-ip\">\n" " <nvpair id=\"public-ip-addr\" name=\"ip\" value=\"1.2.3.4\"/>\n" " </instance_attributes>\n" "</primitive>" msgstr "" #. Tag: para #, no-c-format msgid "This can be achieved from the command-line by executing" msgstr "" #. Tag: programlisting #, no-c-format msgid "# cibadmin -M -X '<op id=\"public-ip-check\" enabled=\"false\"/>'" msgstr "" #. Tag: para #, no-c-format msgid "Once you’ve done whatever you needed to do, you can then re-enable it with" msgstr "" pacemaker-master/doc/Pacemaker_Explained/pot/Ch-Rules.pot000066400000000000000000001043201217637305600237070ustar00rootroot00000000000000# # AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: 0\n" "POT-Creation-Date: 2012-10-17T05:19:02\n" "PO-Revision-Date: 2012-10-17T05:19:02\n" "Last-Translator: Automatically generated\n" "Language-Team: None\n" "MIME-Version: 1.0\n" "Content-Type: application/x-publican; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. Tag: title #, no-c-format msgid "Rules" msgstr "" #. Tag: para #, no-c-format msgid " ResourceConstraintRule ConstraintRule Rule " msgstr "" #. Tag: para #, no-c-format msgid "Rules can be used to make your configuration more dynamic. One common example is to set one value for resource-stickiness during working hours, to prevent resources from being moved back to their most preferred location, and another on weekends when no-one is around to notice an outage." msgstr "" #. Tag: para #, no-c-format msgid "Another use of rules might be to assign machines to different processing groups (using a node attribute) based on time and to then use that attribute when creating location constraints." msgstr "" #. Tag: para #, no-c-format msgid "Each rule can contain a number of expressions, date-expressions and even other rules. The results of the expressions are combined based on the rule’s boolean-op field to determine if the rule ultimately evaluates to true or false. What happens next depends on the context in which the rule is being used." msgstr "" #. Tag: title #, no-c-format msgid "Properties of a Rule" msgstr "" #. Tag: entry #, no-c-format msgid "Field" msgstr "" #. Tag: entry #, no-c-format msgid "Description" msgstr "" #. Tag: para #, no-c-format msgid "role" msgstr "" #. Tag: para #, no-c-format msgid "Limits the rule to apply only when the resource is in that role. Allowed values: Started, Slave, and Master. NOTE: A rule with role=\"Master\" can not determine the initial location of a clone instance. It will only affect which of the active instances will be promoted. roleConstraint Rule Constraint Rule ConstraintRulerole Rulerole role " msgstr "" #. Tag: para #, no-c-format msgid "score" msgstr "" #. Tag: para #, no-c-format msgid "The score to apply if the rule evaluates to true. Limited to use in rules that are part of location constraints. scoreConstraint Rule Constraint Rule ConstraintRulescore Rulescore score " msgstr "" #. Tag: para #, no-c-format msgid "score-attribute" msgstr "" #. Tag: para #, no-c-format msgid "The node attribute to look up and use as a score if the rule evaluates to true. Limited to use in rules that are part of location constraints. score-attributeConstraint Rule Constraint Rule ConstraintRulescore-attribute Rulescore-attribute score-attribute " msgstr "" #. Tag: para #, no-c-format msgid "boolean-op" msgstr "" #. Tag: para #, no-c-format msgid "How to combine the result of multiple expression objects. Allowed values: and and or. boolean-opConstraint Rule Constraint Rule ConstraintRuleboolean-op Ruleboolean-op boolean-op " msgstr "" #. Tag: title #, no-c-format msgid "Node Attribute Expressions" msgstr "" #. Tag: para #, no-c-format msgid " ResourceConstraintAttribute Expression ConstraintAttribute Expression Attribute Expression " msgstr "" #. Tag: para #, no-c-format msgid "Expression objects are used to control a resource based on the attributes defined by a node or nodes. In addition to any attributes added by the administrator, each node has a built-in node attribute called #uname that can also be used." msgstr "" #. Tag: title #, no-c-format msgid "Properties of an Expression" msgstr "" #. Tag: para #, no-c-format msgid "value" msgstr "" #. Tag: para #, no-c-format msgid "User supplied value for comparison valueConstraint Expression Constraint Expression ConstraintAttribute Expressionvalue Attribute Expressionvalue value " msgstr "" #. Tag: para #, no-c-format msgid "attribute" msgstr "" #. Tag: para #, no-c-format msgid "The node attribute to test attributeConstraint Expression Constraint Expression ConstraintAttribute Expressionattribute Attribute Expressionattribute attribute " msgstr "" #. Tag: para #, no-c-format msgid "type" msgstr "" #. Tag: para #, no-c-format msgid "Determines how the value(s) should be tested. Allowed values: string, integer, version typeConstraint Expression Constraint Expression ConstraintAttribute Expressiontype Attribute Expressiontype type " msgstr "" #. Tag: para #, no-c-format msgid "operation" msgstr "" #. Tag: para #, no-c-format msgid "The comparison to perform. Allowed values:" msgstr "" #. Tag: para #, no-c-format msgid "* lt - True if the node attribute’s value is less than value" msgstr "" #. Tag: para #, no-c-format msgid "* gt - True if the node attribute’s value is greater than value" msgstr "" #. Tag: para #, no-c-format msgid "* lte - True if the node attribute’s value is less than or equal to value" msgstr "" #. Tag: para #, no-c-format msgid "* gte - True if the node attribute’s value is greater than or equal to value" msgstr "" #. Tag: para #, no-c-format msgid "* eq - True if the node attribute’s value is equal to value" msgstr "" #. Tag: para #, no-c-format msgid "* ne - True if the node attribute’s value is not equal to value" msgstr "" #. Tag: para #, no-c-format msgid "* defined - True if the node has the named attribute" msgstr "" #. Tag: para #, no-c-format msgid "* not_defined - True if the node does not have the named attribute operationConstraint Expression Constraint Expression ConstraintAttribute Expressionoperation Attribute Expressionoperation operation " msgstr "" #. Tag: title #, no-c-format msgid "Time/Date Based Expressions" msgstr "" #. Tag: para #, no-c-format msgid " Time Based Expressions ResourceConstraintDate/Time Expression ConstraintDate/Time Expression Date/Time Expression " msgstr "" #. Tag: para #, no-c-format msgid "As the name suggests, date_expressions are used to control a resource or cluster option based on the current date/time. They can contain an optional date_spec and/or duration object depending on the context." msgstr "" #. Tag: title #, no-c-format msgid "Properties of a Date Expression" msgstr "" #. Tag: para #, no-c-format msgid "start" msgstr "" #. Tag: para #, no-c-format msgid "A date/time conforming to the ISO8601 specification. startConstraint Expression Constraint Expression ConstraintDate/Time Expressionstart Date/Time Expressionstart start " msgstr "" #. Tag: para #, no-c-format msgid "end" msgstr "" #. Tag: para #, no-c-format msgid "A date/time conforming to the ISO8601 specification. Can be inferred by supplying a value for start and a duration. endConstraint Expression Constraint Expression ConstraintDate/Time Expressionend Date/Time Expressionend end " msgstr "" #. Tag: para #, no-c-format msgid "Compares the current date/time with the start and/or end date, depending on the context. Allowed values:" msgstr "" #. Tag: para #, no-c-format msgid "* gt - True if the current date/time is after start" msgstr "" #. Tag: para #, no-c-format msgid "* lt - True if the current date/time is before end" msgstr "" #. Tag: para #, no-c-format msgid "* in-range - True if the current date/time is after start and before end" msgstr "" #. Tag: para #, no-c-format msgid "* date-spec - performs a cron-like comparison to the current date/time operationConstraint Expression Constraint Expression ConstraintDate/Time Expressionoperation Date/Time Expressionoperation operation " msgstr "" #. Tag: para #, no-c-format msgid "As these comparisons (except for date_spec) include the time, the eq, neq, gte and lte operators have not been implemented since they would only be valid for a single second." msgstr "" #. Tag: title #, no-c-format msgid "Date Specifications" msgstr "" #. Tag: para #, no-c-format msgid " Date Specification ResourceConstraintDate Specification ConstraintDate Specification Date Specification " msgstr "" #. Tag: para #, no-c-format msgid "date_spec objects are used to create cron-like expressions relating to time. Each field can contain a single number or a single range. Instead of defaulting to zero, any field not supplied is ignored." msgstr "" #. Tag: para #, no-c-format msgid "For example, monthdays=\"1\" matches the first day of every month and hours=\"09-17\" matches the hours between 9am and 5pm (inclusive). However, at this time one cannot specify weekdays=\"1,2\" or weekdays=\"1-2,5-6\" since they contain multiple ranges. Depending on demand, this may be implemented in a future release." msgstr "" #. Tag: title #, no-c-format msgid "Properties of a Date Spec" msgstr "" #. Tag: para #, no-c-format msgid "id" msgstr "" #. Tag: para #, no-c-format msgid "A unique name for the date idDate Specification Date Specification ConstraintDate Specificationid Date Specificationid id " msgstr "" #. Tag: para #, no-c-format msgid "hours" msgstr "" #. Tag: para #, no-c-format msgid "Allowed values: 0-23 hoursDate Specification Date Specification ConstraintDate Specificationhours Date Specificationhours hours " msgstr "" #. Tag: para #, no-c-format msgid "monthdays" msgstr "" #. Tag: para #, no-c-format msgid "Allowed values: 0-31 (depending on month and year) monthdaysDate Specification Date Specification ConstraintDate Specificationmonthdays Date Specificationmonthdays monthdays " msgstr "" #. Tag: para #, no-c-format msgid "weekdays" msgstr "" #. Tag: para #, no-c-format msgid "Allowed values: 1-7 (1=Monday, 7=Sunday) weekdaysDate Specification Date Specification ConstraintDate Specificationweekdays Date Specificationweekdays weekdays " msgstr "" #. Tag: para #, no-c-format msgid "yeardays" msgstr "" #. Tag: para #, no-c-format msgid "Allowed values: 1-366 (depending on the year) yeardaysDate Specification Date Specification ConstraintDate Specificationyeardays Date Specificationyeardays yeardays " msgstr "" #. Tag: para #, no-c-format msgid "months" msgstr "" #. Tag: para #, no-c-format msgid "Allowed values: 1-12 monthsDate Specification Date Specification ConstraintDate Specificationmonths Date Specificationmonths months " msgstr "" #. Tag: para #, no-c-format msgid "weeks" msgstr "" #. Tag: para #, no-c-format msgid "Allowed values: 1-53 (depending on weekyear) weeksDate Specification Date Specification ConstraintDate Specificationweeks Date Specificationweeks weeks " msgstr "" #. Tag: para #, no-c-format msgid "years" msgstr "" #. Tag: para #, no-c-format msgid "Year according the Gregorian calendar yearsDate Specification Date Specification ConstraintDate Specificationyears Date Specificationyears years " msgstr "" #. Tag: para #, no-c-format msgid "weekyears" msgstr "" #. Tag: para #, no-c-format msgid "May differ from Gregorian years; Eg. 2005-001 Ordinal is also 2005-01-01 Gregorian is also 2004-W53-6 Weekly weekyearsDate Specification Date Specification ConstraintDate Specificationweekyears Date Specificationweekyears weekyears " msgstr "" #. Tag: para #, no-c-format msgid "moon" msgstr "" #. Tag: para #, no-c-format msgid "Allowed values: 0-7 (0 is new, 4 is full moon). Seriously, you can use this. This was implemented to demonstrate the ease with which new comparisons could be added. moonDate Specification Date Specification ConstraintDate Specificationmoon Date Specificationmoon moon " msgstr "" #. Tag: title #, no-c-format msgid "Durations" msgstr "" #. Tag: para #, no-c-format msgid " Duration ResourceConstraintDuration ConstraintDuration Duration " msgstr "" #. Tag: para #, no-c-format msgid "Durations are used to calculate a value for end when one is not supplied to in_range operations. They contain the same fields as date_spec objects but without the limitations (ie. you can have a duration of 19 months). Like date_specs, any field not supplied is ignored." msgstr "" #. Tag: title #, no-c-format msgid "Sample Time Based Expressions" msgstr "" #. Tag: para #, no-c-format msgid "A small sample of how time based expressions can be used." msgstr "" #. Tag: title #, no-c-format msgid "True if now is any time in the year 2005" msgstr "" #. Tag: programlisting #, no-c-format msgid "<rule id=\"rule1\">\n" " <date_expression id=\"date_expr1\" start=\"2005-001\" operation=\"in_range\">\n" " <duration years=\"1\"/>\n" " </date_expression>\n" "</rule>" msgstr "" #. Tag: title #, no-c-format msgid "Equivalent expression" msgstr "" #. Tag: programlisting #, no-c-format msgid "<rule id=\"rule2\">\n" " <date_expression id=\"date_expr2\" operation=\"date_spec\">\n" " <date_spec years=\"2005\"/>\n" " </date_expression>\n" "</rule>" msgstr "" #. Tag: title #, no-c-format msgid "9am-5pm, Mon-Friday" msgstr "" #. Tag: programlisting #, no-c-format msgid "<rule id=\"rule3\">\n" " <date_expression id=\"date_expr3\" operation=\"date_spec\">\n" " <date_spec hours=\"9-16\" days=\"1-5\"/>\n" " </date_expression>\n" "</rule>" msgstr "" #. Tag: para #, no-c-format msgid "Please note that the 16 matches up to 16:59:59, as the numeric value (hour) still matches!" msgstr "" #. Tag: title #, no-c-format msgid "9am-6pm, Mon-Friday, or all day saturday" msgstr "" #. Tag: programlisting #, no-c-format msgid "<rule id=\"rule4\" boolean_op=\"or\">\n" " <date_expression id=\"date_expr4-1\" operation=\"date_spec\">\n" " <date_spec hours=\"9-16\" days=\"1-5\"/>\n" " </date_expression>\n" " <date_expression id=\"date_expr4-2\" operation=\"date_spec\">\n" " <date_spec days=\"6\"/>\n" " </date_expression>\n" "</rule>" msgstr "" #. Tag: title #, no-c-format msgid "9am-5pm or 9pm-12pm, Mon-Friday" msgstr "" #. Tag: programlisting #, no-c-format msgid "<rule id=\"rule5\" boolean_op=\"and\">\n" " <rule id=\"rule5-nested1\" boolean_op=\"or\">\n" " <date_expression id=\"date_expr5-1\" operation=\"date_spec\">\n" " <date_spec hours=\"9-16\"/>\n" " </date_expression>\n" " <date_expression id=\"date_expr5-2\" operation=\"date_spec\">\n" " <date_spec hours=\"21-23\"/>\n" " </date_expression>\n" " </rule>\n" " <date_expression id=\"date_expr5-3\" operation=\"date_spec\">\n" " <date_spec days=\"1-5\"/>\n" " </date_expression>\n" " </rule>" msgstr "" #. Tag: title #, no-c-format msgid "Mondays in March 2005" msgstr "" #. Tag: programlisting #, no-c-format msgid "<rule id=\"rule6\" boolean_op=\"and\">\n" " <date_expression id=\"date_expr6-1\" operation=\"date_spec\">\n" " <date_spec weekdays=\"1\"/>\n" " </date_expression>\n" " <date_expression id=\"date_expr6-2\" operation=\"in_range\"\n" " start=\"2005-03-01\" end=\"2005-04-01\"/>\n" " </rule>" msgstr "" #. Tag: para #, no-c-format msgid "Because no time is specified, 00:00:00 is implied." msgstr "" #. Tag: para #, no-c-format msgid "This means that the range includes all of 2005-03-01 but none of 2005-04-01. You may wish to write end=\"2005-03-31T23:59:59\" to avoid confusion." msgstr "" #. Tag: title #, no-c-format msgid "A full moon on Friday the 13th" msgstr "" #. Tag: programlisting #, no-c-format msgid "<rule id=\"rule7\" boolean_op=\"and\">\n" " <date_expression id=\"date_expr7\" operation=\"date_spec\">\n" " <date_spec weekdays=\"5\" monthdays=\"13\" moon=\"4\"/>\n" " </date_expression>\n" "</rule>" msgstr "" #. Tag: title #, no-c-format msgid "Using Rules to Determine Resource Location" msgstr "" #. Tag: para #, no-c-format msgid " RuleDetermine Resource Location Determine Resource Location ResourceLocationDetermine by Rules LocationDetermine by Rules Determine by Rules " msgstr "" #. Tag: para #, no-c-format msgid "If the constraint’s outer-most rule evaluates to false, the cluster treats the constraint as if it was not there. When the rule evaluates to true, the node’s preference for running the resource is updated with the score associated with the rule." msgstr "" #. Tag: para #, no-c-format msgid "If this sounds familiar, its because you have been using a simplified syntax for location constraint rules already. Consider the following location constraint:" msgstr "" #. Tag: title #, no-c-format msgid "Prevent myApacheRsc from running on c001n03" msgstr "" #. Tag: programlisting #, no-c-format msgid "<rsc_location id=\"dont-run-apache-on-c001n03\" rsc=\"myApacheRsc\"\n" " score=\"-INFINITY\" node=\"c001n03\"/>" msgstr "" #. Tag: para #, no-c-format msgid "This constraint can be more verbosely written as:" msgstr "" #. Tag: title #, no-c-format msgid "Prevent myApacheRsc from running on c001n03 - expanded version" msgstr "" #. Tag: programlisting #, no-c-format msgid "<rsc_location id=\"dont-run-apache-on-c001n03\" rsc=\"myApacheRsc\">\n" " <rule id=\"dont-run-apache-rule\" score=\"-INFINITY\">\n" " <expression id=\"dont-run-apache-expr\" attribute=\"#uname\"\n" " operation=\"eq\" value=\"c00n03\"/>\n" " </rule>\n" "</rsc_location>" msgstr "" #. Tag: para #, no-c-format msgid "The advantage of using the expanded form is that one can then add extra clauses to the rule, such as limiting the rule such that it only applies during certain times of the day or days of the week (this is discussed in subsequent sections)." msgstr "" #. Tag: para #, no-c-format msgid "It also allows us to match on node properties other than its name. If we rated each machine’s CPU power such that the cluster had the following nodes section:" msgstr "" #. Tag: title #, no-c-format msgid "A sample nodes section for use with score-attribute" msgstr "" #. Tag: programlisting #, no-c-format msgid "<nodes>\n" " <node id=\"uuid1\" uname=\"c001n01\" type=\"normal\">\n" " <instance_attributes id=\"uuid1-custom_attrs\">\n" " <nvpair id=\"uuid1-cpu_mips\" name=\"cpu_mips\" value=\"1234\"/>\n" " </instance_attributes>\n" " </node>\n" " <node id=\"uuid2\" uname=\"c001n02\" type=\"normal\">\n" " <instance_attributes id=\"uuid2-custom_attrs\">\n" " <nvpair id=\"uuid2-cpu_mips\" name=\"cpu_mips\" value=\"5678\"/>\n" " </instance_attributes>\n" " </node>\n" "</nodes>" msgstr "" #. Tag: para #, no-c-format msgid "then we could prevent resources from running on underpowered machines with the rule" msgstr "" #. Tag: programlisting #, no-c-format msgid "<rule id=\"need-more-power-rule\" score=\"-INFINITY\">\n" " <expression id=\" need-more-power-expr\" attribute=\"cpu_mips\"\n" " operation=\"lt\" value=\"3000\"/>\n" "</rule>" msgstr "" #. Tag: title #, no-c-format msgid "Using score-attribute Instead of score" msgstr "" #. Tag: para #, no-c-format msgid "When using score-attribute instead of score, each node matched by the rule has its score adjusted differently, according to its value for the named node attribute. Thus, in the previous example, if a rule used score-attribute=\"cpu_mips\", c001n01 would have its preference to run the resource increased by 1234 whereas c001n02 would have its preference increased by 5678." msgstr "" #. Tag: title #, no-c-format msgid "Using Rules to Control Resource Options" msgstr "" #. Tag: para #, no-c-format msgid "Often some cluster nodes will be different from their peers; sometimes these differences (the location of a binary or the names of network interfaces) require resources to be configured differently depending on the machine they’re hosted on." msgstr "" #. Tag: para #, no-c-format msgid "By defining multiple instance_attributes objects for the resource and adding a rule to each, we can easily handle these special cases." msgstr "" #. Tag: para #, no-c-format msgid "In the example below, mySpecialRsc will use eth1 and port 9999 when run on node1, eth2 and port 8888 on node2 and default to eth0 and port 9999 for all other nodes." msgstr "" #. Tag: title #, no-c-format msgid "Defining different resource options based on the node name" msgstr "" #. Tag: programlisting #, no-c-format msgid "<primitive id=\"mySpecialRsc\" class=\"ocf\" type=\"Special\" provider=\"me\">\n" " <instance_attributes id=\"special-node1\" score=\"3\">\n" " <rule id=\"node1-special-case\" score=\"INFINITY\" >\n" " <expression id=\"node1-special-case-expr\" attribute=\"#uname\"\n" " operation=\"eq\" value=\"node1\"/>\n" " </rule>\n" " <nvpair id=\"node1-interface\" name=\"interface\" value=\"eth1\"/>\n" " </instance_attributes>\n" " <instance_attributes id=\"special-node2\" score=\"2\" >\n" " <rule id=\"node2-special-case\" score=\"INFINITY\">\n" " <expression id=\"node2-special-case-expr\" attribute=\"#uname\"\n" " operation=\"eq\" value=\"node2\"/>\n" " </rule>\n" " <nvpair id=\"node2-interface\" name=\"interface\" value=\"eth2\"/>\n" " <nvpair id=\"node2-port\" name=\"port\" value=\"8888\"/>\n" " </instance_attributes>\n" " <instance_attributes id=\"defaults\" score=\"1\" >\n" " <nvpair id=\"default-interface\" name=\"interface\" value=\"eth0\"/>\n" " <nvpair id=\"default-port\" name=\"port\" value=\"9999\"/>\n" " </instance_attributes>\n" "</primitive>" msgstr "" #. Tag: para #, no-c-format msgid "The order in which instance_attributes objects are evaluated is determined by their score (highest to lowest). If not supplied, score defaults to zero and objects with an equal score are processed in listed order. If the instance_attributes object does not have a rule or has a rule that evaluates to true, then for any parameter the resource does not yet have a value for, the resource will use the parameter values defined by the instance_attributes object." msgstr "" #. Tag: title #, no-c-format msgid "Using Rules to Control Cluster Options" msgstr "" #. Tag: para #, no-c-format msgid " RuleControlling Cluster Options Controlling Cluster Options ClusterSetting Options with Rules Setting Options with Rules " msgstr "" #. Tag: para #, no-c-format msgid "Controlling cluster options is achieved in much the same manner as specifying different resource options on different nodes." msgstr "" #. Tag: para #, no-c-format msgid "The difference is that because they are cluster options, one cannot (or should not, because they won’t work) use attribute based expressions. The following example illustrates how to set a different resource-stickiness value during and outside of work hours. This allows resources to automatically move back to their most preferred hosts, but at a time that (in theory) does not interfere with business activities." msgstr "" #. Tag: title #, no-c-format msgid "Change resource-stickiness during working hours" msgstr "" #. Tag: programlisting #, no-c-format msgid "<rsc_defaults>\n" " <meta_attributes id=\"core-hours\" score=\"2\">\n" " <rule id=\"core-hour-rule\" score=\"0\">\n" " <date_expression id=\"nine-to-five-Mon-to-Fri\" operation=\"date_spec\">\n" " <date_spec id=\"nine-to-five-Mon-to-Fri-spec\" hours=\"9-16\" weekdays=\"1-5\"/>\n" " </date_expression>\n" " </rule>\n" " <nvpair id=\"core-stickiness\" name=\"resource-stickiness\" value=\"INFINITY\"/>\n" " </meta_attributes>\n" " <meta_attributes id=\"after-hours\" score=\"1\" >\n" " <nvpair id=\"after-stickiness\" name=\"resource-stickiness\" value=\"0\"/>\n" " </meta_attributes>\n" "</rsc_defaults>" msgstr "" #. Tag: title #, no-c-format msgid "Ensuring Time Based Rules Take Effect" msgstr "" #. Tag: para #, no-c-format msgid "A Pacemaker cluster is an event driven system. As such, it won’t recalculate the best place for resources to run in unless something (like a resource failure or configuration change) happens. This can mean that a location constraint that only allows resource X to run between 9am and 5pm is not enforced." msgstr "" #. Tag: para #, no-c-format msgid "If you rely on time based rules, it is essential that you set the cluster-recheck-interval option. This tells the cluster to periodically recalculate the ideal state of the cluster. For example, if you set cluster-recheck-interval=5m, then sometime between 9:00 and 9:05 the cluster would notice that it needs to start resource X, and between 17:00 and 17:05 it would realize that X needed to be stopped." msgstr "" #. Tag: para #, no-c-format msgid "Note that the timing of the actual start and stop actions depends on what else needs to be performed first ." msgstr "" pacemaker-master/doc/Pacemaker_Explained/pot/Ch-Status.pot000066400000000000000000000656121217637305600241120ustar00rootroot00000000000000# # AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: 0\n" "POT-Creation-Date: 2012-10-17T05:19:02\n" "PO-Revision-Date: 2012-10-17T05:19:02\n" "Last-Translator: Automatically generated\n" "Language-Team: None\n" "MIME-Version: 1.0\n" "Content-Type: application/x-publican; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. Tag: title #, no-c-format msgid "Status - Here be dragons" msgstr "" #. Tag: para #, no-c-format msgid "Most users never need to understand the contents of the status section and can be happy with the output from crm_mon." msgstr "" #. Tag: para #, no-c-format msgid "However for those with a curious inclination, this section attempts to provide an overview of its contents." msgstr "" #. Tag: title #, no-c-format msgid "Node Status" msgstr "" #. Tag: para #, no-c-format msgid " NodeStatus Status Status of a Node " msgstr "" #. Tag: para #, no-c-format msgid "In addition to the cluster’s configuration, the CIB holds an up-to-date representation of each cluster node in the status section." msgstr "" #. Tag: title #, no-c-format msgid "A bare-bones status entry for a healthy node called cl-virt-1" msgstr "" #. Tag: programlisting #, no-c-format msgid " <node_state id=\"cl-virt-1\" uname=\"cl-virt-2\" ha=\"active\" in_ccm=\"true\" crmd=\"online\" join=\"member\" expected=\"member\" crm-debug-origin=\"do_update_resource\">\n" " <transient_attributes id=\"cl-virt-1\"/>\n" " <lrm id=\"cl-virt-1\"/>\n" " </node_state>" msgstr "" #. Tag: para #, no-c-format msgid "Users are highly recommended not to modify any part of a node’s state directly. The cluster will periodically regenerate the entire section from authoritative sources. So any changes should be done with the tools for those subsystems." msgstr "" #. Tag: title #, no-c-format msgid "Authoritative Sources for State Information" msgstr "" #. Tag: entry #, no-c-format msgid "Dataset" msgstr "" #. Tag: entry #, no-c-format msgid "Authoritative Source" msgstr "" #. Tag: para #, no-c-format msgid "node_state fields" msgstr "" #. Tag: para #, no-c-format msgid "crmd" msgstr "" #. Tag: para #, no-c-format msgid "transient_attributes tag" msgstr "" #. Tag: para #, no-c-format msgid "attrd" msgstr "" #. Tag: para #, no-c-format msgid "lrm tag" msgstr "" #. Tag: para #, no-c-format msgid "lrmd" msgstr "" #. Tag: para #, no-c-format msgid "The fields used in the node_state objects are named as they are largely for historical reasons and are rooted in Pacemaker’s origins as the Heartbeat resource manager." msgstr "" #. Tag: para #, no-c-format msgid "They have remained unchanged to preserve compatibility with older versions." msgstr "" #. Tag: title #, no-c-format msgid "Node Status Fields" msgstr "" #. Tag: entry #, no-c-format msgid "Field" msgstr "" #. Tag: entry #, no-c-format msgid "Description" msgstr "" #. Tag: para #, no-c-format msgid "id" msgstr "" #. Tag: para #, no-c-format msgid " idNode Status Node Status NodeStatusid Statusid id Unique identifier for the node. Corosync based clusters use the uname of the machine, Heartbeat clusters use a human-readable (but annoying) UUID." msgstr "" #. Tag: para #, no-c-format msgid "uname" msgstr "" #. Tag: para #, no-c-format msgid " unameNode Status Node Status NodeStatusuname Statusuname uname The node’s machine name (output from uname -n)." msgstr "" #. Tag: para #, no-c-format msgid "ha" msgstr "" #. Tag: para #, no-c-format msgid " haNode Status Node Status NodeStatusha Statusha ha Flag specifying whether the cluster software is active on the node. Allowed values: active, dead." msgstr "" #. Tag: para #, no-c-format msgid "in_ccm" msgstr "" #. Tag: para #, no-c-format msgid " in_ccmNode Status Node Status NodeStatusin_ccm Statusin_ccm in_ccm Flag for cluster membership; allowed values: true, false." msgstr "" #. Tag: para #, no-c-format msgid "crmd" msgstr "" #. Tag: para #, no-c-format msgid " crmdNode Status Node Status NodeStatuscrmd Statuscrmd crmd Flag: is the crmd process active on the node? One of online, offline." msgstr "" #. Tag: para #, no-c-format msgid "join" msgstr "" #. Tag: para #, no-c-format msgid " joinNode Status Node Status NodeStatusjoin Statusjoin join Flag saying whether the node participates in hosting resources. Possible values: down, pending, member, banned." msgstr "" #. Tag: para #, no-c-format msgid "expected" msgstr "" #. Tag: para #, no-c-format msgid " expectedNode Status Node Status NodeStatusexpected Statusexpected expected Expected value for join." msgstr "" #. Tag: para #, no-c-format msgid "crm-debug-origin" msgstr "" #. Tag: para #, no-c-format msgid " crm-debug-originNode Status Node Status NodeStatuscrm-debug-origin Statuscrm-debug-origin crm-debug-origin Diagnostic indicator: the origin of the most recent change(s)." msgstr "" #. Tag: para #, no-c-format msgid "The cluster uses these fields to determine if, at the node level, the node is healthy or is in a failed state and needs to be fenced." msgstr "" #. Tag: title #, no-c-format msgid "Transient Node Attributes" msgstr "" #. Tag: para #, no-c-format msgid "Like regular node attributes, the name/value pairs listed here also help to describe the node. However they are forgotten by the cluster when the node goes offline. This can be useful, for instance, when you want a node to be in standby mode (not able to run resources) until the next reboot." msgstr "" #. Tag: para #, no-c-format msgid "In addition to any values the administrator sets, the cluster will also store information about failed resources here." msgstr "" #. Tag: title #, no-c-format msgid "Example set of transient node attributes for node \"cl-virt-1\"" msgstr "" #. Tag: programlisting #, no-c-format msgid " <transient_attributes id=\"cl-virt-1\">\n" " <instance_attributes id=\"status-cl-virt-1\">\n" " <nvpair id=\"status-cl-virt-1-pingd\" name=\"pingd\" value=\"3\"/>\n" " <nvpair id=\"status-cl-virt-1-probe_complete\" name=\"probe_complete\" value=\"true\"/>\n" " <nvpair id=\"status-cl-virt-1-fail-count-pingd:0\" name=\"fail-count-pingd:0\" value=\"1\"/>\n" " <nvpair id=\"status-cl-virt-1-last-failure-pingd:0\" name=\"last-failure-pingd:0\" value=\"1239009742\"/>\n" " </instance_attributes>\n" " </transient_attributes>" msgstr "" #. Tag: para #, no-c-format msgid "In the above example, we can see that the pingd:0 resource has failed once, at Mon Apr 6 11:22:22 2009. You can use the standard date command to print a human readable of any seconds-since-epoch value: # date -d @<parameter>number</parameter> We also see that the node is connected to three \"pingd\" peers and that all known resources have been checked for on this machine (probe_complete)." msgstr "" #. Tag: title #, no-c-format msgid "Operation History" msgstr "" #. Tag: para #, no-c-format msgid " Operation History " msgstr "" #. Tag: para #, no-c-format msgid "A node’s resource history is held in the lrm_resources tag (a child of the lrm tag). The information stored here includes enough information for the cluster to stop the resource safely if it is removed from the configuration section. Specifically the resource’s id, class, type and provider are stored." msgstr "" #. Tag: title #, no-c-format msgid "A record of the apcstonith resource" msgstr "" #. Tag: programlisting #, no-c-format msgid "<lrm_resource id=\"apcstonith\" type=\"apcmastersnmp\" class=\"stonith\"/>" msgstr "" #. Tag: para #, no-c-format msgid "Additionally, we store the last job for every combination of resource, action and interval. The concatenation of the values in this tuple are used to create the id of the lrm_rsc_op object." msgstr "" #. Tag: title #, no-c-format msgid "Contents of an lrm_rsc_op job" msgstr "" #. Tag: para #, no-c-format msgid " idAction Status Action Status ActionStatusid Statusid id " msgstr "" #. Tag: para #, no-c-format msgid "Identifier for the job constructed from the resource’s id, operation and interval." msgstr "" #. Tag: para #, no-c-format msgid "call-id" msgstr "" #. Tag: para #, no-c-format msgid " call-idAction Status Action Status ActionStatuscall-id Statuscall-id call-id " msgstr "" #. Tag: para #, no-c-format msgid "The job’s ticket number. Used as a sort key to determine the order in which the jobs were executed." msgstr "" #. Tag: para #, no-c-format msgid "operation" msgstr "" #. Tag: para #, no-c-format msgid " operationAction Status Action Status ActionStatusoperation Statusoperation operation " msgstr "" #. Tag: para #, no-c-format msgid "The action the resource agent was invoked with." msgstr "" #. Tag: para #, no-c-format msgid "interval" msgstr "" #. Tag: para #, no-c-format msgid " intervalAction Status Action Status ActionStatusinterval Statusinterval interval " msgstr "" #. Tag: para #, no-c-format msgid "The frequency, in milliseconds, at which the operation will be repeated. A one-off job is indicated by 0." msgstr "" #. Tag: para #, no-c-format msgid "op-status" msgstr "" #. Tag: para #, no-c-format msgid " op-statusAction Status Action Status ActionStatusop-status Statusop-status op-status " msgstr "" #. Tag: para #, no-c-format msgid "The job’s status. Generally this will be either 0 (done) or -1 (pending). Rarely used in favor of rc-code." msgstr "" #. Tag: para #, no-c-format msgid "rc-code" msgstr "" #. Tag: para #, no-c-format msgid " rc-codeAction Status Action Status ActionStatusrc-code Statusrc-code rc-code " msgstr "" #. Tag: para #, no-c-format msgid "The job’s result. Refer to for details on what the values here mean and how they are interpreted." msgstr "" #. Tag: para #, no-c-format msgid "last-run" msgstr "" #. Tag: para #, no-c-format msgid " last-runAction Status Action Status ActionStatuslast-run Statuslast-run last-run " msgstr "" #. Tag: para #, no-c-format msgid "Diagnostic indicator. Machine local date/time, in seconds since epoch, at which the job was executed." msgstr "" #. Tag: para #, no-c-format msgid "last-rc-change" msgstr "" #. Tag: para #, no-c-format msgid " last-rc-changeAction Status Action Status ActionStatuslast-rc-change Statuslast-rc-change last-rc-change " msgstr "" #. Tag: para #, no-c-format msgid "Diagnostic indicator. Machine local date/time, in seconds since epoch, at which the job first returned the current value of rc-code." msgstr "" #. Tag: para #, no-c-format msgid "exec-time" msgstr "" #. Tag: para #, no-c-format msgid " exec-timeAction Status Action Status ActionStatusexec-time Statusexec-time exec-time " msgstr "" #. Tag: para #, no-c-format msgid "Diagnostic indicator. Time, in milliseconds, that the job was running for." msgstr "" #. Tag: para #, no-c-format msgid "queue-time" msgstr "" #. Tag: para #, no-c-format msgid " queue-timeAction Status Action Status ActionStatusqueue-time Statusqueue-time queue-time " msgstr "" #. Tag: para #, no-c-format msgid "Diagnostic indicator. Time, in seconds, that the job was queued for in the LRMd." msgstr "" #. Tag: para #, no-c-format msgid "crm_feature_set" msgstr "" #. Tag: para #, no-c-format msgid " crm_feature_setAction Status Action Status ActionStatuscrm_feature_set Statuscrm_feature_set crm_feature_set " msgstr "" #. Tag: para #, no-c-format msgid "The version which this job description conforms to. Used when processing op-digest." msgstr "" #. Tag: para #, no-c-format msgid "transition-key" msgstr "" #. Tag: para #, no-c-format msgid " transition-keyAction Status Action Status ActionStatustransition-key Statustransition-key transition-key " msgstr "" #. Tag: para #, no-c-format msgid "A concatenation of the job’s graph action number, the graph number, the expected result and the UUID of the crmd instance that scheduled it. This is used to construct transition-magic (below)." msgstr "" #. Tag: para #, no-c-format msgid "transition-magic" msgstr "" #. Tag: para #, no-c-format msgid " transition-magicAction Status Action Status ActionStatustransition-magic Statustransition-magic transition-magic " msgstr "" #. Tag: para #, no-c-format msgid "A concatenation of the job’s op-status, rc-code and transition-key. Guaranteed to be unique for the life of the cluster (which ensures it is part of CIB update notifications) and contains all the information needed for the crmd to correctly analyze and process the completed job. Most importantly, the decomposed elements tell the crmd if the job entry was expected and whether it failed." msgstr "" #. Tag: para #, no-c-format msgid "op-digest" msgstr "" #. Tag: para #, no-c-format msgid " op-digestAction Status Action Status ActionStatusop-digest Statusop-digest op-digest " msgstr "" #. Tag: para #, no-c-format msgid "An MD5 sum representing the parameters passed to the job. Used to detect changes to the configuration, to restart resources if necessary." msgstr "" #. Tag: para #, no-c-format msgid " crm-debug-originAction Status Action Status ActionStatuscrm-debug-origin Statuscrm-debug-origin crm-debug-origin " msgstr "" #. Tag: para #, no-c-format msgid "Diagnostic indicator. The origin of the current values." msgstr "" #. Tag: title #, no-c-format msgid "Simple Example" msgstr "" #. Tag: title #, no-c-format msgid "A monitor operation (determines current state of the apcstonith resource)" msgstr "" #. Tag: programlisting #, no-c-format msgid "<lrm_resource id=\"apcstonith\" type=\"apcmastersnmp\" class=\"stonith\">\n" " <lrm_rsc_op id=\"apcstonith_monitor_0\" operation=\"monitor\" call-id=\"2\"\n" " rc-code=\"7\" op-status=\"0\" interval=\"0\"\n" " crm-debug-origin=\"do_update_resource\" crm_feature_set=\"3.0.1\"\n" " op-digest=\"2e3da9274d3550dc6526fb24bfcbcba0\"\n" " transition-key=\"22:2:7:2668bbeb-06d5-40f9-936d-24cb7f87006a\"\n" " transition-magic=\"0:7;22:2:7:2668bbeb-06d5-40f9-936d-24cb7f87006a\"\n" " last-run=\"1239008085\" last-rc-change=\"1239008085\" exec-time=\"10\" queue-time=\"0\"/>\n" "</lrm_resource>" msgstr "" #. Tag: para #, no-c-format msgid "In the above example, the job is a non-recurring monitor operation often referred to as a \"probe\" for the apcstonith resource." msgstr "" #. Tag: para #, no-c-format msgid "The cluster schedules probes for every configured resource on when a new node starts, in order to determine the resource’s current state before it takes any further action." msgstr "" #. Tag: para #, no-c-format msgid "From the transition-key, we can see that this was the 22nd action of the 2nd graph produced by this instance of the crmd (2668bbeb-06d5-40f9-936d-24cb7f87006a)." msgstr "" #. Tag: para #, no-c-format msgid "The third field of the transition-key contains a 7, this indicates that the job expects to find the resource inactive." msgstr "" #. Tag: para #, no-c-format msgid "By looking at the rc-code property, we see that this was the case." msgstr "" #. Tag: para #, no-c-format msgid "As that is the only job recorded for this node we can conclude that the cluster started the resource elsewhere." msgstr "" #. Tag: title #, no-c-format msgid "Complex Resource History Example" msgstr "" #. Tag: title #, no-c-format msgid "Resource history of a pingd clone with multiple jobs" msgstr "" #. Tag: programlisting #, no-c-format msgid "<lrm_resource id=\"pingd:0\" type=\"pingd\" class=\"ocf\" provider=\"pacemaker\">\n" " <lrm_rsc_op id=\"pingd:0_monitor_30000\" operation=\"monitor\" call-id=\"34\"\n" " rc-code=\"0\" op-status=\"0\" interval=\"30000\"\n" " crm-debug-origin=\"do_update_resource\" crm_feature_set=\"3.0.1\"\n" " transition-key=\"10:11:0:2668bbeb-06d5-40f9-936d-24cb7f87006a\"\n" " ...\n" " last-run=\"1239009741\" last-rc-change=\"1239009741\" exec-time=\"10\" queue-time=\"0\"/>\n" " <lrm_rsc_op id=\"pingd:0_stop_0\" operation=\"stop\"\n" " crm-debug-origin=\"do_update_resource\" crm_feature_set=\"3.0.1\" call-id=\"32\"\n" " rc-code=\"0\" op-status=\"0\" interval=\"0\"\n" " transition-key=\"11:11:0:2668bbeb-06d5-40f9-936d-24cb7f87006a\"\n" " ...\n" " last-run=\"1239009741\" last-rc-change=\"1239009741\" exec-time=\"10\" queue-time=\"0\"/>\n" " <lrm_rsc_op id=\"pingd:0_start_0\" operation=\"start\" call-id=\"33\"\n" " rc-code=\"0\" op-status=\"0\" interval=\"0\"\n" " crm-debug-origin=\"do_update_resource\" crm_feature_set=\"3.0.1\"\n" " transition-key=\"31:11:0:2668bbeb-06d5-40f9-936d-24cb7f87006a\"\n" " ...\n" " last-run=\"1239009741\" last-rc-change=\"1239009741\" exec-time=\"10\" queue-time=\"0\" />\n" " <lrm_rsc_op id=\"pingd:0_monitor_0\" operation=\"monitor\" call-id=\"3\"\n" " rc-code=\"0\" op-status=\"0\" interval=\"0\"\n" " crm-debug-origin=\"do_update_resource\" crm_feature_set=\"3.0.1\"\n" " transition-key=\"23:2:7:2668bbeb-06d5-40f9-936d-24cb7f87006a\"\n" " ...\n" " last-run=\"1239008085\" last-rc-change=\"1239008085\" exec-time=\"20\" queue-time=\"0\"/>\n" " </lrm_resource>" msgstr "" #. Tag: para #, no-c-format msgid "When more than one job record exists, it is important to first sort them by call-id before interpreting them." msgstr "" #. Tag: para #, no-c-format msgid "Once sorted, the above example can be summarized as:" msgstr "" #. Tag: para #, no-c-format msgid "A non-recurring monitor operation returning 7 (not running), with a call-id of 3" msgstr "" #. Tag: para #, no-c-format msgid "A stop operation returning 0 (success), with a call-id of 32" msgstr "" #. Tag: para #, no-c-format msgid "A start operation returning 0 (success), with a call-id of 33" msgstr "" #. Tag: para #, no-c-format msgid "A recurring monitor returning 0 (success), with a call-id of 34" msgstr "" #. Tag: para #, no-c-format msgid "The cluster processes each job record to build up a picture of the resource’s state. After the first and second entries, it is considered stopped and after the third it considered active." msgstr "" #. Tag: para #, no-c-format msgid "Based on the last operation, we can tell that the resource is currently active." msgstr "" #. Tag: para #, no-c-format msgid "Additionally, from the presence of a stop operation with a lower call-id than that of the start operation, we can conclude that the resource has been restarted. Specifically this occurred as part of actions 11 and 31 of transition 11 from the crmd instance with the key 2668bbeb…. This information can be helpful for locating the relevant section of the logs when looking for the source of a failure." msgstr "" pacemaker-master/doc/Pacemaker_Explained/pot/Ch-Stonith.pot000066400000000000000000000305141217637305600242500ustar00rootroot00000000000000# # AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: 0\n" "POT-Creation-Date: 2012-10-17T05:19:02\n" "PO-Revision-Date: 2012-10-17T05:19:02\n" "Last-Translator: Automatically generated\n" "Language-Team: None\n" "MIME-Version: 1.0\n" "Content-Type: application/x-publican; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. Tag: title #, no-c-format msgid "Configure STONITH" msgstr "" #. Tag: para #, no-c-format msgid " STONITHConfiguration Configuration " msgstr "" #. Tag: title #, no-c-format msgid "What Is STONITH" msgstr "" #. Tag: para #, no-c-format msgid "STONITH is an acronym for Shoot-The-Other-Node-In-The-Head and it protects your data from being corrupted by rogue nodes or concurrent access." msgstr "" #. Tag: para #, no-c-format msgid "Just because a node is unresponsive, this doesn’t mean it isn’t accessing your data. The only way to be 100% sure that your data is safe, is to use STONITH so we can be certain that the node is truly offline, before allowing the data to be accessed from another node." msgstr "" #. Tag: para #, no-c-format msgid "STONITH also has a role to play in the event that a clustered service cannot be stopped. In this case, the cluster uses STONITH to force the whole node offline, thereby making it safe to start the service elsewhere." msgstr "" #. Tag: title #, no-c-format msgid "What STONITH Device Should You Use" msgstr "" #. Tag: para #, no-c-format msgid "It is crucial that the STONITH device can allow the cluster to differentiate between a node failure and a network one." msgstr "" #. Tag: para #, no-c-format msgid "The biggest mistake people make in choosing a STONITH device is to use remote power switch (such as many on-board IMPI controllers) that shares power with the node it controls. In such cases, the cluster cannot be sure if the node is really offline, or active and suffering from a network fault." msgstr "" #. Tag: para #, no-c-format msgid "Likewise, any device that relies on the machine being active (such as SSH-based \"devices\" used during testing) are inappropriate." msgstr "" #. Tag: title #, no-c-format msgid "Configuring STONITH" msgstr "" #. Tag: para #, no-c-format msgid "Find the correct driver: stonith_admin --list-installed" msgstr "" #. Tag: para #, no-c-format msgid "Since every device is different, the parameters needed to configure it will vary. To find out the parameters associated with the device, run: stonith_admin --metadata --agent type" msgstr "" #. Tag: literallayout #, no-c-format msgid "The output should be XML formatted text containing additional\n" "parameter descriptions. We will endevor to make the output more\n" "friendly in a later version." msgstr "" #. Tag: para #, no-c-format msgid "Enter the shell crm Create an editable copy of the existing configuration cib new stonith Create a fencing resource containing a primitive resource with a class of stonith, a type of type and a parameter for each of the values returned in step 2: configure primitive …" msgstr "" #. Tag: para #, no-c-format msgid "If the device does not know how to fence nodes based on their uname, you may also need to set the special pcmk_host_map parameter. See man stonithd for details." msgstr "" #. Tag: para #, no-c-format msgid "If the device does not support the list command, you may also need to set the special pcmk_host_list and/or pcmk_host_check parameters. See man stonithd for details." msgstr "" #. Tag: para #, no-c-format msgid "If the device does not expect the victim to be specified with the port parameter, you may also need to set the special pcmk_host_argument parameter. See man stonithd for details." msgstr "" #. Tag: para #, no-c-format msgid "Upload it into the CIB from the shell: cib commit stonith" msgstr "" #. Tag: para #, no-c-format msgid "Once the stonith resource is running, you can test it by executing: stonith_admin --reboot nodename. Although you might want to stop the cluster on that machine first." msgstr "" #. Tag: title #, no-c-format msgid "Example" msgstr "" #. Tag: para #, no-c-format msgid "Assuming we have an chassis containing four nodes and an IPMI device active on 10.0.0.1, then we would chose the fence_ipmilan driver in step 2 and obtain the following list of parameters" msgstr "" #. Tag: title #, no-c-format msgid "Obtaining a list of STONITH Parameters" msgstr "" #. Tag: programlisting #, no-c-format msgid "# stonith_admin --metadata -a fence_ipmilan" msgstr "" #. Tag: programlisting #, no-c-format msgid "<?xml version=\"1.0\" ?>\n" "<resource-agent name=\"fence_ipmilan\" shortdesc=\"Fence agent for IPMI over LAN\">\n" "<longdesc>\n" "fence_ipmilan is an I/O Fencing agent which can be used with machines controlled by IPMI. This agent calls support software using ipmitool (http://ipmitool.sf.net/).\n" "\n" "To use fence_ipmilan with HP iLO 3 you have to enable lanplus option (lanplus / -P) and increase wait after operation to 4 seconds (power_wait=4 / -T 4)</longdesc>\n" "<parameters>\n" " <parameter name=\"auth\" unique=\"1\">\n" " <getopt mixed=\"-A\" />\n" " <content type=\"string\" />\n" " <shortdesc>IPMI Lan Auth type (md5, password, or none)</shortdesc>\n" " </parameter>\n" " <parameter name=\"ipaddr\" unique=\"1\">\n" " <getopt mixed=\"-a\" />\n" " <content type=\"string\" />\n" " <shortdesc>IPMI Lan IP to talk to</shortdesc>\n" " </parameter>\n" " <parameter name=\"passwd\" unique=\"1\">\n" " <getopt mixed=\"-p\" />\n" " <content type=\"string\" />\n" " <shortdesc>Password (if required) to control power on IPMI device</shortdesc>\n" " </parameter>\n" " <parameter name=\"passwd_script\" unique=\"1\">\n" " <getopt mixed=\"-S\" />\n" " <content type=\"string\" />\n" " <shortdesc>Script to retrieve password (if required)</shortdesc>\n" " </parameter>\n" " <parameter name=\"lanplus\" unique=\"1\">\n" " <getopt mixed=\"-P\" />\n" " <content type=\"boolean\" />\n" " <shortdesc>Use Lanplus</shortdesc>\n" " </parameter>\n" " <parameter name=\"login\" unique=\"1\">\n" " <getopt mixed=\"-l\" />\n" " <content type=\"string\" />\n" " <shortdesc>Username/Login (if required) to control power on IPMI device</shortdesc>\n" " </parameter>\n" " <parameter name=\"action\" unique=\"1\">\n" " <getopt mixed=\"-o\" />\n" " <content type=\"string\" default=\"reboot\"/>\n" " <shortdesc>Operation to perform. Valid operations: on, off, reboot, status, list, diag, monitor or metadata</shortdesc>\n" " </parameter>\n" " <parameter name=\"timeout\" unique=\"1\">\n" " <getopt mixed=\"-t\" />\n" " <content type=\"string\" />\n" " <shortdesc>Timeout (sec) for IPMI operation</shortdesc>\n" " </parameter>\n" " <parameter name=\"cipher\" unique=\"1\">\n" " <getopt mixed=\"-C\" />\n" " <content type=\"string\" />\n" " <shortdesc>Ciphersuite to use (same as ipmitool -C parameter)</shortdesc>\n" " </parameter>\n" " <parameter name=\"method\" unique=\"1\">\n" " <getopt mixed=\"-M\" />\n" " <content type=\"string\" default=\"onoff\"/>\n" " <shortdesc>Method to fence (onoff or cycle)</shortdesc>\n" " </parameter>\n" " <parameter name=\"power_wait\" unique=\"1\">\n" " <getopt mixed=\"-T\" />\n" " <content type=\"string\" default=\"2\"/>\n" " <shortdesc>Wait X seconds after on/off operation</shortdesc>\n" " </parameter>\n" " <parameter name=\"delay\" unique=\"1\">\n" " <getopt mixed=\"-f\" />\n" " <content type=\"string\" />\n" " <shortdesc>Wait X seconds before fencing is started</shortdesc>\n" " </parameter>\n" " <parameter name=\"verbose\" unique=\"1\">\n" " <getopt mixed=\"-v\" />\n" " <content type=\"boolean\" />\n" " <shortdesc>Verbose mode</shortdesc>\n" " </parameter>\n" "</parameters>\n" "<actions>\n" " <action name=\"on\" />\n" " <action name=\"off\" />\n" " <action name=\"reboot\" />\n" " <action name=\"status\" />\n" " <action name=\"diag\" />\n" " <action name=\"list\" />\n" " <action name=\"monitor\" />\n" " <action name=\"metadata\" />\n" "</actions>\n" "</resource-agent>" msgstr "" #. Tag: para #, no-c-format msgid "from which we would create a STONITH resource fragment that might look like this" msgstr "" #. Tag: title #, no-c-format msgid "Sample STONITH Resource" msgstr "" #. Tag: programlisting #, no-c-format msgid "# crm crm(live)# cib new stonith\n" "INFO: stonith shadow CIB created\n" "crm(stonith)# configure primitive impi-fencing stonith::fence_ipmilan \\\n" " params pcmk_host_list=\"pcmk-1 pcmk-2\" ipaddr=10.0.0.1 login=testuser passwd=abc123 \\\n" " op monitor interval=\"60s\"" msgstr "" #. Tag: para #, no-c-format msgid "And finally, since we disabled it earlier, we need to re-enable STONITH. At this point we should have the following configuration." msgstr "" #. Tag: para #, no-c-format msgid "Now push the configuration into the cluster." msgstr "" #. Tag: programlisting #, no-c-format msgid "crm(stonith)# configure property stonith-enabled=\"true\"\n" "crm(stonith)# configure shownode pcmk-1\n" "node pcmk-2\n" "primitive WebData ocf:linbit:drbd \\\n" " params drbd_resource=\"wwwdata\" \\\n" " op monitor interval=\"60s\"\n" "primitive WebFS ocf:heartbeat:Filesystem \\\n" " params device=\"/dev/drbd/by-res/wwwdata\" directory=\"/var/www/html\" fstype=\"gfs2\"\n" "primitive WebSite ocf:heartbeat:apache \\\n" " params configfile=\"/etc/httpd/conf/httpd.conf\" \\\n" " op monitor interval=\"1min\"\n" "primitive ClusterIP ocf:heartbeat:IPaddr2 \\\n" " params ip=\"192.168.122.101\" cidr_netmask=\"32\" clusterip_hash=\"sourceip\" \\\n" " op monitor interval=\"30s\"primitive ipmi-fencing stonith::fence_ipmilan \\ params pcmk_host_list=\"pcmk-1 pcmk-2\" ipaddr=10.0.0.1 login=testuser passwd=abc123 \\ op monitor interval=\"60s\"ms WebDataClone WebData \\\n" " meta master-max=\"2\" master-node-max=\"1\" clone-max=\"2\" clone-node-max=\"1\" notify=\"true\"\n" "clone WebFSClone WebFS\n" "clone WebIP ClusterIP \\\n" " meta globally-unique=\"true\" clone-max=\"2\" clone-node-max=\"2\"\n" "clone WebSiteClone WebSite\n" "colocation WebSite-with-WebFS inf: WebSiteClone WebFSClone\n" "colocation fs_on_drbd inf: WebFSClone WebDataClone:Master\n" "colocation website-with-ip inf: WebSiteClone WebIP\n" "order WebFS-after-WebData inf: WebDataClone:promote WebFSClone:start\n" "order WebSite-after-WebFS inf: WebFSClone WebSiteClone\n" "order apache-after-ip inf: WebIP WebSiteClone\n" "property $id=\"cib-bootstrap-options\" \\\n" " dc-version=\"1.1.5-bdd89e69ba545404d02445be1f3d72e6a203ba2f\" \\\n" " cluster-infrastructure=\"openais\" \\\n" " expected-quorum-votes=\"2\" \\\n" " stonith-enabled=\"true\" \\\n" " no-quorum-policy=\"ignore\"\n" "rsc_defaults $id=\"rsc-options\" \\\n" " resource-stickiness=\"100\"\n" "crm(stonith)# cib commit stonithINFO: commited 'stonith' shadow CIB to the cluster\n" "crm(stonith)# quit\n" "bye" msgstr "" pacemaker-master/doc/Pacemaker_Explained/pot/Ch-Utilization.pot000066400000000000000000000307021217637305600251320ustar00rootroot00000000000000# # AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: 0\n" "POT-Creation-Date: 2012-10-17T05:19:02\n" "PO-Revision-Date: 2012-10-17T05:19:02\n" "Last-Translator: Automatically generated\n" "Language-Team: None\n" "MIME-Version: 1.0\n" "Content-Type: application/x-publican; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. Tag: title #, no-c-format msgid "Utilization and Placement Strategy" msgstr "" #. Tag: title #, no-c-format msgid "Background" msgstr "" #. Tag: para #, no-c-format msgid "Pacemaker decides where to place a resource according to the resource allocation scores on every node. The resource will be allocated to the node where the resource has the highest score. If the resource allocation scores on all the nodes are equal, by the default placement strategy, Pacemaker will choose a node with the least number of allocated resources for balancing the load. If the number of resources on each node is equal, the first eligible node listed in cib will be chosen to run the resource." msgstr "" #. Tag: para #, no-c-format msgid "Though resources are different. They may consume different amounts of the capacities of the nodes. Actually, we cannot ideally balance the load just according to the number of resources allocated to a node. Besides, if resources are placed such that their combined requirements exceed the provided capacity, they may fail to start completely or run with degraded performance." msgstr "" #. Tag: para #, no-c-format msgid "To take these into account, Pacemaker allows you to specify the following configurations:" msgstr "" #. Tag: para #, no-c-format msgid "The capacity a certain node provides." msgstr "" #. Tag: para #, no-c-format msgid "The capacity a certain resource requires." msgstr "" #. Tag: para #, no-c-format msgid "An overall strategy for placement of resources." msgstr "" #. Tag: title #, no-c-format msgid "Utilization attributes" msgstr "" #. Tag: para #, no-c-format msgid "To configure the capacity a node provides and the resource’s requirements, use utilization attributes. You can name the utilization attributes according to your preferences and define as many name/value pairs as your configuration needs. However, the attribute’s values must be integers." msgstr "" #. Tag: para #, no-c-format msgid "First, specify the capacities the nodes provide:" msgstr "" #. Tag: programlisting #, no-c-format msgid "<node id=\"node1\" type=\"normal\" uname=\"node1\">\n" " <utilization id=\"node1-utilization\">\n" " <nvpair id=\"node1-utilization-cpu\" name=\"cpu\" value=\"2\"/>\n" " <nvpair id=\"node1-utilization-memory\" name=\"memory\" value=\"2048\"/>\n" " </utilization>\n" "</node>\n" "<node id=\"node2\" type=\"normal\" uname=\"node2\">\n" " <utilization id=\"node2-utilization\">\n" " <nvpair id=\"node2-utilization-cpu\" name=\"cpu\" value=\"4\"/>\n" " <nvpair id=\"node2-utilization-memory\" name=\"memory\" value=\"4096\"/>\n" " </utilization>\n" "</node>" msgstr "" #. Tag: para #, no-c-format msgid "Then, specify the capacities the resources require:" msgstr "" #. Tag: programlisting #, no-c-format msgid "<primitive id=\"rsc-small\" class=\"ocf\" provider=\"pacemaker\" type=\"Dummy\">\n" " <utilization id=\"rsc-small-utilization\">\n" " <nvpair id=\"rsc-small-utilization-cpu\" name=\"cpu\" value=\"1\"/>\n" " <nvpair id=\"rsc-small-utilization-memory\" name=\"memory\" value=\"1024\"/>\n" " </utilization>\n" "</primitive>\n" "<primitive id=\"rsc-medium\" class=\"ocf\" provider=\"pacemaker\" type=\"Dummy\">\n" " <utilization id=\"rsc-medium-utilization\">\n" " <nvpair id=\"rsc-medium-utilization-cpu\" name=\"cpu\" value=\"2\"/>\n" " <nvpair id=\"rsc-medium-utilization-memory\" name=\"memory\" value=\"2048\"/>\n" " </utilization>\n" "</primitive>\n" "<primitive id=\"rsc-large\" class=\"ocf\" provider=\"pacemaker\" type=\"Dummy\">\n" " <utilization id=\"rsc-large-utilization\">\n" " <nvpair id=\"rsc-large-utilization-cpu\" name=\"cpu\" value=\"3\"/>\n" " <nvpair id=\"rsc-large-utilization-memory\" name=\"memory\" value=\"3072\"/>\n" " </utilization>\n" "</primitive>" msgstr "" #. Tag: para #, no-c-format msgid "A node is considered eligible for a resource if it has sufficient free capacity to satisfy the resource’s requirements. The nature of the required or provided capacities is completely irrelevant for Pacemaker, it just makes sure that all capacity requirements of a resource are satisfied before placing a resource to a node." msgstr "" #. Tag: title #, no-c-format msgid "Placement Strategy" msgstr "" #. Tag: para #, no-c-format msgid "After you have configured the capacities your nodes provide and the capacities your resources require, you need to set the placement-strategy in the global cluster options, otherwise the capacity configurations have no effect." msgstr "" #. Tag: para #, no-c-format msgid "Four values are available for the placement-strategy:" msgstr "" #. Tag: term #, no-c-format msgid "default" msgstr "" #. Tag: para #, no-c-format msgid "Utilization values are not taken into account at all, per default. Resources are allocated according to allocation scores. If scores are equal, resources are evenly distributed across nodes." msgstr "" #. Tag: term #, no-c-format msgid "utilization" msgstr "" #. Tag: para #, no-c-format msgid "Utilization values are taken into account when deciding whether a node is considered eligible if it has sufficient free capacity to satisfy the resource’s requirements. However, load-balancing is still done based on the number of resources allocated to a node." msgstr "" #. Tag: term #, no-c-format msgid "balanced" msgstr "" #. Tag: para #, no-c-format msgid "Utilization values are taken into account when deciding whether a node is eligible to serve a resource; an attempt is made to spread the resources evenly, optimizing resource performance." msgstr "" #. Tag: term #, no-c-format msgid "minimal" msgstr "" #. Tag: para #, no-c-format msgid "Utilization values are taken into account when deciding whether a node is eligible to serve a resource; an attempt is made to concentrate the resources on as few nodes as possible, thereby enabling possible power savings on the remaining nodes." msgstr "" #. Tag: para #, no-c-format msgid "Set placement-strategy with crm_attribute:" msgstr "" #. Tag: programlisting #, no-c-format msgid "# crm_attribute --attr-name placement-strategy --attr-value balanced" msgstr "" #. Tag: para #, no-c-format msgid "Now Pacemaker will ensure the load from your resources will be distributed evenly throughout the cluster - without the need for convoluted sets of colocation constraints." msgstr "" #. Tag: title #, no-c-format msgid "Allocation Details" msgstr "" #. Tag: title #, no-c-format msgid "Which node is preferred to be chosen to get consumed first on allocating resources?" msgstr "" #. Tag: para #, no-c-format msgid "The node that is most healthy (which has the highest node weight) gets consumed first." msgstr "" #. Tag: para #, no-c-format msgid "If their weights are equal:" msgstr "" #. Tag: para #, no-c-format msgid "If placement-strategy=\"default|utilization\", the node that has the least number of allocated resources gets consumed first." msgstr "" #. Tag: para #, no-c-format msgid "If their numbers of allocated resources are equal, the first eligible node listed in cib gets consumed first." msgstr "" #. Tag: para #, no-c-format msgid "If placement-strategy=\"balanced\", the node that has more free capacity gets consumed first." msgstr "" #. Tag: para #, no-c-format msgid "If the free capacities of the nodes are equal, the node that has the least number of allocated resources gets consumed first." msgstr "" #. Tag: para #, no-c-format msgid "If placement-strategy=\"minimal\", the first eligible node listed in cib gets consumed first." msgstr "" #. Tag: title #, no-c-format msgid "Which node has more free capacity?" msgstr "" #. Tag: para #, no-c-format msgid "This will be quite clear if we only define one type of capacity. While if we define multiple types of capacity, for example:" msgstr "" #. Tag: para #, no-c-format msgid "If nodeA has more free cpus, nodeB has more free memory, their free capacities are equal." msgstr "" #. Tag: para #, no-c-format msgid "If nodeA has more free cpus, while nodeB has more free memory and storage, nodeB has more free capacity." msgstr "" #. Tag: title #, no-c-format msgid "Which resource is preferred to be chosen to get assigned first?" msgstr "" #. Tag: para #, no-c-format msgid "The resource that has the highest priority gets allocated first." msgstr "" #. Tag: para #, no-c-format msgid "If their priorities are equal, check if they are already running. The resource that has the highest score on the node where it’s running gets allocated first (to prevent resource shuffling)." msgstr "" #. Tag: para #, no-c-format msgid "If the scores above are equal or they are not running, the resource has the highest score on the preferred node gets allocated first." msgstr "" #. Tag: para #, no-c-format msgid "If the scores above are equal, the first runnable resource listed in cib gets allocated first." msgstr "" #. Tag: title #, no-c-format msgid "Limitations" msgstr "" #. Tag: para #, no-c-format msgid "This type of problem Pacemaker is dealing with here is known as the knapsack problem and falls into the NP-complete category of computer science problems - which is fancy way of saying \"it takes a really long time to solve\"." msgstr "" #. Tag: para #, no-c-format msgid "Clearly in a HA cluster, it’s not acceptable to spend minutes, let alone hours or days, finding an optional solution while services remain unavailable." msgstr "" #. Tag: para #, no-c-format msgid "So instead of trying to solve the problem completely, Pacemaker uses a best effort algorithm for determining which node should host a particular service. This means it arrives at a solution much faster than traditional linear programming algorithms, but by doing so at the price of leaving some services stopped." msgstr "" #. Tag: para #, no-c-format msgid "In the contrived example above:" msgstr "" #. Tag: para #, no-c-format msgid "rsc-small would be allocated to node1" msgstr "" #. Tag: para #, no-c-format msgid "rsc-medium would be allocated to node2" msgstr "" #. Tag: para #, no-c-format msgid "rsc-large would remain inactive" msgstr "" #. Tag: para #, no-c-format msgid "Which is not ideal." msgstr "" #. Tag: title #, no-c-format msgid "Strategies for Dealing with the Limitations" msgstr "" #. Tag: para #, no-c-format msgid "Ensure you have sufficient physical capacity. It might sounds obvious, but if the physical capacity of your nodes is (close to) maxed out by the cluster under normal conditions, then failover isn’t going to go well. Even without the Utilization feature, you’ll start hitting timeouts and getting secondary failures'." msgstr "" #. Tag: para #, no-c-format msgid "Build some buffer into the capabilities advertised by the nodes. Advertise slightly more resources than we physically have on the (usually valid) assumption that a resource will not use 100% of the configured number of cpu/memory/etc all the time. This practice is also known as over commit." msgstr "" #. Tag: para #, no-c-format msgid "Specify resource priorities. If the cluster is going to sacrifice services, it should be the ones you care (comparatively) about the least. Ensure that resource priorities are properly set so that your most important resources are scheduled first." msgstr "" pacemaker-master/doc/Pacemaker_Explained/pot/Pacemaker_Explained.pot000066400000000000000000000025371217637305600261550ustar00rootroot00000000000000# # AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: 0\n" "POT-Creation-Date: 2012-10-17T05:19:02\n" "PO-Revision-Date: 2012-10-17T05:19:02\n" "Last-Translator: Automatically generated\n" "Language-Team: None\n" "MIME-Version: 1.0\n" "Content-Type: application/x-publican; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. Tag: title #, no-c-format msgid "Receiving Notification for Cluster Events" msgstr "" #. Tag: title #, no-c-format msgid "Configuring Email Notifications" msgstr "" #. Tag: title #, no-c-format msgid "Configuring SNMP Notifications" msgstr "" #. Tag: title #, no-c-format msgid "Further Reading" msgstr "" #. Tag: para #, no-c-format msgid "Project Website " msgstr "" #. Tag: para #, no-c-format msgid "Project Documentation " msgstr "" #. Tag: para #, no-c-format msgid "A comprehensive guide to cluster commands has been written by Novell" msgstr "" #. Tag: para #, no-c-format msgid "Heartbeat configuration: " msgstr "" #. Tag: para #, no-c-format msgid "Corosync Configuration: " msgstr "" pacemaker-master/doc/Pacemaker_Explained/pot/Preface.pot000066400000000000000000000006271217637305600236370ustar00rootroot00000000000000# # AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: 0\n" "POT-Creation-Date: 2012-10-17T05:19:02\n" "PO-Revision-Date: 2012-10-17T05:19:02\n" "Last-Translator: Automatically generated\n" "Language-Team: None\n" "MIME-Version: 1.0\n" "Content-Type: application/x-publican; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. Tag: title #, no-c-format msgid "Preface" msgstr "" pacemaker-master/doc/Pacemaker_Explained/pot/Revision_History.pot000066400000000000000000000022361217637305600256070ustar00rootroot00000000000000# # AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: 0\n" "POT-Creation-Date: 2012-10-17T05:19:02\n" "PO-Revision-Date: 2012-10-17T05:19:02\n" "Last-Translator: Automatically generated\n" "Language-Team: None\n" "MIME-Version: 1.0\n" "Content-Type: application/x-publican; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. Tag: title #, no-c-format msgid "Revision History" msgstr "" #. Tag: firstname #, no-c-format msgid "Andrew" msgstr "" #. Tag: surname #, no-c-format msgid "Beekhof" msgstr "" #. Tag: member #, no-c-format msgid "Import from Pages.app" msgstr "" #. Tag: member #, no-c-format msgid "Cleanup and reformatting of docbook xml complete" msgstr "" #. Tag: member #, no-c-format msgid "Split book into chapters and pass validation" msgstr "" #. Tag: member #, no-c-format msgid "Re-organize book for use with Publican" msgstr "" #. Tag: member #, no-c-format msgid "Converted to asciidoc (which is converted to docbook for use with Publican)" msgstr "" pacemaker-master/doc/Pacemaker_Explained/publican.cfg.in000066400000000000000000000004001217637305600236140ustar00rootroot00000000000000# Config::Simple 4.59 # Tue Nov 10 22:28:47 2009 docname: Pacemaker_Explained version: @PACKAGE_SERIES@ xml_lang: en-US #edition: 1 type: Book brand: @PUBLICAN_BRAND@ product: Pacemaker chunk_first: 0 chunk_section_depth: 3 generate_section_toc_level: 4 pacemaker-master/doc/Pacemaker_Explained/ro-RO/000077500000000000000000000000001217637305600216755ustar00rootroot00000000000000pacemaker-master/doc/Pacemaker_Explained/ro-RO/Ap-Changes.po000066400000000000000000000232571217637305600241540ustar00rootroot00000000000000msgid "" msgstr "" "Project-Id-Version: Pacemaker 1.1\n" "POT-Creation-Date: 2012-10-17T05:19:01\n" "PO-Revision-Date: 2012-01-01T17:48:32\n" "Last-Translator: Dan Frîncu \n" "Language-Team: None\n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: application/x-publican; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. Tag: title #, no-c-format msgid "What Changed in 1.0" msgstr "Ce S-a Schimbat în 1.0" #. Tag: title #, no-c-format msgid "New" msgstr "Nou" #. Tag: para #, no-c-format msgid "Failure timeouts. See " msgstr "Intervale de așteptare înainte de a declara un eșec. Vedeţi " #. Tag: para #, no-c-format msgid "New section for resource and operation defaults. See and " msgstr "O nouă secţiune pentru valorile implicite ale resurselor şi operaţiunilor. Vedeţi şi " #. Tag: para #, no-c-format msgid "Tool for making offline configuration changes. See " msgstr "Utilitar pentru realizarea de modificări ale configuraţiei offline. Vedeţi " #. Tag: para #, no-c-format msgid "Rules, instance_attributes, meta_attributes and sets of operations can be defined once and referenced in multiple places. See " msgstr "Rules, instance_attributes, meta_atributes şi seturile de operaţiuni pot fi definite o dată iar apoi pot fi referenţiate în mai multe locuri. Vedeţi " #. Tag: para #, no-c-format msgid "The CIB now accepts XPath-based create/modify/delete operations. See the cibadmin help text." msgstr "CIB-ul acum acceptă operaţiuni de creare/modificare/ştergere bazate pe tipul XPath. Vedeţi ajutorul textual pentru cibadmin." #. Tag: para #, no-c-format msgid "Multi-dimensional colocation and ordering constraints. See and " msgstr "Restricţii de ordonare şi colocare multi-dimensională. Vedeţi şi " #. Tag: para #, no-c-format msgid "The ability to connect to the CIB from non-cluster machines. See " msgstr "Posibilitatea de conectare la CIB de pe maşini care nu fac parte din cluster. Vedeţi " #. Tag: para #, no-c-format msgid "Allow recurring actions to be triggered at known times. See " msgstr "Permite declanşarea de acţiuni recurente la intervale cunoscute de timp. Vedeţi " #. Tag: title #, no-c-format msgid "Changed" msgstr "Modificat" #. Tag: para #, no-c-format msgid "Syntax" msgstr "Sintaxă" #. Tag: para #, no-c-format msgid "All resource and cluster options now use dashes (-) instead of underscores (_)" msgstr "Toate opţiunile şi resursele cluster-ului folosesc acum cratime (-) în loc de underscore (_)" #. Tag: para #, no-c-format msgid "master_slave was renamed to master" msgstr "master_slave a fost redenumit în master" #. Tag: para #, no-c-format msgid "The attributes container tag was removed" msgstr "Tag-ul attributes a fost scos" #. Tag: para #, no-c-format msgid "The operation field pre-req has been renamed requires" msgstr "Câmpul operaţiunii pre-req fost redenumit în requires" #. Tag: para #, no-c-format msgid "All operations must have an interval, start/stop must have it set to zero" msgstr "Toate operaţiunile trebuie să aibe un interval, cele de start/stop trebuie să îl aibe setat la zero" #. Tag: para #, no-c-format msgid "The stonith-enabled option now defaults to true." msgstr "Opţiunea stonith-enabled are acum valoarea implicită setată pe true." #. Tag: para #, no-c-format msgid "The cluster will refuse to start resources if stonith-enabled is true (or unset) and no STONITH resources have been defined" msgstr "Clusterul va refuza să pornească resurse dacă stonith-enabled este true (sau nu este setat) şi nici o resursă STONITH nu a fost definită" #. Tag: para #, no-c-format msgid "The attributes of colocation and ordering constraints were renamed for clarity. See and " msgstr "Atributele restricţiilor de colocare şi ordonare au fost redenumite pentru o mai bună claritate. Vedeţi şi " #. Tag: para #, no-c-format msgid "resource-failure-stickiness has been replaced by migration-threshold. See " msgstr "resource-failure-stickiness a fost înlocuită de migration-threshold. Vedeţi " #. Tag: para #, no-c-format msgid "The parameters for command-line tools have been made consistent" msgstr "Argumentele pentru utilitarele folosite în linia de comandă au fost aduse la o formă consistentă" #. Tag: para #, no-c-format msgid "Switched to RelaxNG schema validation and libxml2 parser" msgstr "" #. Tag: para #, no-c-format msgid "id fields are now XML IDs which have the following limitations:" msgstr "câmpurile id sunt acum ID-uri XML care au următoarele limitări:" #. Tag: para #, fuzzy, no-c-format msgid "id’s cannot contain colons (:)" msgstr "id-urile nu pot conţine două puncte (:)" #. Tag: para #, fuzzy, no-c-format msgid "id’s cannot begin with a number" msgstr "id-urile nu pot începe cu un număr" #. Tag: para #, fuzzy, no-c-format msgid "id’s must be globally unique (not just unique for that tag)" msgstr "id-urile trebuie să fie unice la nivel global (nu unice doar pentru acel tag)" #. Tag: para #, no-c-format msgid "Some fields (such as those in constraints that refer to resources) are IDREFs." msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "This means that they must reference existing resources or objects in order for the configuration to be valid. Removing an object which is referenced elsewhere will therefore fail." msgstr "Unele câmpuri (cum ar fi acelea care fac parte din restricţii care fac referinţă la resurse) sunt IDREF-uri. Acest lucru înseamnă că ele trebuie să facă referinţă către resurse sau obiecte existente pentru a fi validă configurarea. Eliminarea unui obiect care este referenţiat altundeva prin urmare va eşua." #. Tag: para #, no-c-format msgid "The CIB representation, from which a MD5 digest is calculated to verify CIBs on the nodes, has changed." msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "This means that every CIB update will require a full refresh on any upgraded nodes until the cluster is fully upgraded to 1.0. This will result in significant performance degradation and it is therefore highly inadvisable to run a mixed 1.0/0.6 cluster for any longer than absolutely necessary." msgstr "Reprezentarea CIB-ului din care se generează hash-ul MD5 folosit pentru a verifica CIB-ul s-a schimbat. Acest lucru înseamnă că fiecare actualizare a CIB-ului va necesita o reîmprospătare completă pe oricare dintre nodurile îmbunătăţite până ce clusterul va fi modernizat complet la 1.0. Acest aspect va duce la o degradare semnificativă a performanţei şi prin urmare este total nerecomandată rularea unui cluster mixt 1.0.0.6 pentru o perioadă mai lungă decât este absolut necesar." #. Tag: para #, fuzzy, no-c-format msgid "Ping node information no longer needs to be added to ha.cf." msgstr "Informaţii despre noduri către care se pot efectua verificări de tip ICMP (ping) nu mai trebuie adăugate în ha.cf Pur şi simplu includeţi lista de host-uri în resursa(ele) de tip ping." #. Tag: para #, no-c-format msgid "Simply include the lists of hosts in your ping resource(s)." msgstr "" #. Tag: title #, no-c-format msgid "Removed" msgstr "Scoase" #. Tag: para #, no-c-format msgid "It is no longer possible to set resource meta options as top-level attributes. Use meta attributes instead." msgstr "Nu mai este posibil să fie setate meta opţiunile resursei ca attribute de nivel înalt. Folosiţi meta atributele în schimb." #. Tag: para #, no-c-format msgid "Resource and operation defaults are no longer read from crm_config. See and instead." msgstr "Valorile implicite ale resurselor si operaţiunilor nu mai sunt citite din crm_config. Vedeţi şi în schimb." #~ msgid "Switched to RelaxNGRelaxNG schema validation and libxml2libxml2 parser" #~ msgstr "Am trecut la RelaxNGRelaxNG pentru validarea schemei şi libxml2libxml2 ca parser." pacemaker-master/doc/Pacemaker_Explained/ro-RO/Ap-Debug.po000066400000000000000000000225471217637305600236330ustar00rootroot00000000000000msgid "" msgstr "" "Project-Id-Version: Pacemaker 1.1\n" "POT-Creation-Date: 2012-10-17T05:19:01\n" "PO-Revision-Date: 2012-01-01T17:48:32\n" "Last-Translator: Dan Frîncu \n" "Language-Team: None\n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: application/x-publican; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. Tag: title #, no-c-format msgid "Debugging Cluster Startup" msgstr "Depanarea Pornirii Clusterului" #. Tag: title #, no-c-format msgid "Corosync" msgstr "Corosync" #. Tag: title #, no-c-format msgid "Prerequisites" msgstr "Premise" #. Tag: title #, no-c-format msgid "Minimum logging configuration" msgstr "Configuraţia minim necesară pentru log-uri" #. Tag: programlisting #, fuzzy, no-c-format msgid "" "\n" " # /etc/init.d/openais start\n" " \n" " \n" " logging {\n" " to_syslog: yes\n" " syslog_facility: daemon\n" " }\n" " \n" " " msgstr "" "\n" " # /etc/init.d/openais start\n" "\t \n" "\t \n" " logging {\n" " to_syslog: yes\n" " syslog_facility: daemon\n" " }\n" "\t \n" "\t " #. Tag: caption #, no-c-format msgid "Whatever other logging you have, these two lines are required for Pacemaker clusters" msgstr "Indiferent de ce alte log-uri aveţi, aceste două linii sunt necesare pentru clusterele de tip Pacemaker" #. Tag: title #, no-c-format msgid "Confirm Corosync Started" msgstr "Confirmaţi că a Pornit Corosync" #. Tag: title #, no-c-format msgid "Expected output when starting openais" msgstr "Rezultatul aşteptat la pornirea openais" #. Tag: screen #, fuzzy, no-c-format msgid "" "\n" " # /etc/init.d/openais start\n" " \n" " \n" " Starting Corosync daemon (aisexec): starting... rc=0: OK\n" " \n" " " msgstr "" "\n" " # /etc/init.d/openais start\n" "\t \n" "\t \n" " Starting Corosync daemon (aisexec): starting... rc=0: OK\n" "\t \n" "\t " #. Tag: title #, no-c-format msgid "Expected log messages - startup" msgstr "Mesaje de log aşteptate - la pornire" #. Tag: screen #, fuzzy, no-c-format msgid "" "\n" " # grep -e \"openais.*network interface\" -e \"AIS Executive Service\" /var/log/messages\n" " \n" " \n" " Aug 27 16:23:37 test1 openais[26337]: [MAIN ] AIS Executive Service RELEASE 'subrev 1152 version 0.80'\n" " Aug 27 16:23:38 test1 openais[26337]: [MAIN ] AIS Executive Service: started and ready to provide service.\n" " Aug 27 16:23:38 test1 openais[26337]: [TOTEM] The network interface [192.168.9.41] is now up.\n" " \n" " " msgstr "" "\n" " # grep -e \"openais.*network interface\" -e \"AIS Executive Service\" /var/log/messages\n" "\t \n" "\t \n" " Aug 27 16:23:37 test1 openais[26337]: [MAIN ] AIS Executive Service RELEASE 'subrev 1152 version 0.80'\n" " Aug 27 16:23:38 test1 openais[26337]: [MAIN ] AIS Executive Service: started and ready to provide service.\n" " Aug 27 16:23:38 test1 openais[26337]: [TOTEM] The network interface [192.168.9.41] is now up.\n" "\t \n" "\t " #. Tag: caption #, no-c-format msgid "The versions may differ, but you should see Corosync indicate it started and sucessfully attached to the machine's network interface" msgstr "Versiunile pot fi diferite, însă ar trebui să vedeţi Corosync indicând că a pornit şi s-a ataşat cu succes la interfaţa de reţea a maşinii" #. Tag: title #, no-c-format msgid "Expected log messages - membership" msgstr "Mesaje de log aşteptate - apartenenţă" #. Tag: screen #, fuzzy, no-c-format msgid "" "\n" " # grep CLM /var/log/messages\n" " \n" " \n" " Aug 27 16:53:15 test1 openais[2166]: [CLM ] CLM CONFIGURATION CHANGE\n" " Aug 27 16:53:15 test1 openais[2166]: [CLM ] New Configuration:\n" " Aug 27 16:53:15 test1 openais[2166]: [CLM ] Members Left:\n" " Aug 27 16:53:15 test1 openais[2166]: [CLM ] Members Joined:\n" " Aug 27 16:53:15 test1 openais[2166]: [CLM ] CLM CONFIGURATION CHANGE\n" " Aug 27 16:53:15 test1 openais[2166]: [CLM ] New Configuration:\n" " Aug 27 16:53:15 test1 openais[2166]: [CLM ] r(0) ip(192.168.9.41)\n" " Aug 27 16:53:15 test1 openais[2166]: [CLM ] Members Left:\n" " Aug 27 16:53:15 test1 openais[2166]: [CLM ] Members Joined:\n" " Aug 27 16:53:15 test1 openais[2166]: [CLM ] r(0) ip(192.168.9.41)\n" " Aug 27 16:53:15 test1 openais[2166]: [CLM ] got nodejoin message 192.168.9.41\n" " \n" " " msgstr "" "\n" " # grep CLM /var/log/messages\n" "\t \n" "\t \n" " Aug 27 16:53:15 test1 openais[2166]: [CLM ] CLM CONFIGURATION CHANGE\n" " Aug 27 16:53:15 test1 openais[2166]: [CLM ] New Configuration:\n" " Aug 27 16:53:15 test1 openais[2166]: [CLM ] Members Left:\n" " Aug 27 16:53:15 test1 openais[2166]: [CLM ] Members Joined:\n" " Aug 27 16:53:15 test1 openais[2166]: [CLM ] CLM CONFIGURATION CHANGE\n" " Aug 27 16:53:15 test1 openais[2166]: [CLM ] New Configuration:\n" " Aug 27 16:53:15 test1 openais[2166]: [CLM ] r(0) ip(192.168.9.41) \n" " Aug 27 16:53:15 test1 openais[2166]: [CLM ] Members Left:\n" " Aug 27 16:53:15 test1 openais[2166]: [CLM ] Members Joined:\n" " Aug 27 16:53:15 test1 openais[2166]: [CLM ] r(0) ip(192.168.9.41) \n" " Aug 27 16:53:15 test1 openais[2166]: [CLM ] got nodejoin message 192.168.9.41\n" "\t \n" "\t " #. Tag: caption #, no-c-format msgid "The exact messages will differ, but you should see a new membership formed with the real IP address of your node" msgstr "Mesajele exacte vor fi diferite, însă ar trebui sa vedeţi o nouă apartenenţă formată cu adresa IP reală a nodului vostru" #. Tag: title #, no-c-format msgid "Checking Pacemaker" msgstr "Verificarea Pacemaker" #. Tag: para #, no-c-format msgid "Now that we have confirmed that Corosync is functional we can check the rest of the stack." msgstr "Acum că am confirmat că procesul Corosync este funcţional putem verifica restul stivei." #. Tag: title #, no-c-format msgid "Expected Pacemaker startup logging for Corosync" msgstr "Log-urile aşteptate la pornirea Pacemaker pentru Corosync" #. Tag: screen #, fuzzy, no-c-format msgid "" "\n" " # grep pcmk_plugin_init /var/log/messages\n" " \n" " \n" " Aug 27 16:53:15 test1 openais[2166]: [pcmk ] info: pcmk_plugin_init: CRM: Initialized\n" " Aug 27 16:53:15 test1 openais[2166]: [pcmk ] Logging: Initialized pcmk_plugin_init\n" " Aug 27 16:53:15 test1 openais[2166]: [pcmk ] info: pcmk_plugin_init: Service: 9\n" " Aug 27 16:53:15 test1 openais[2166]: [pcmk ] info: pcmk_plugin_init: Local hostname: test1\n" " \n" " " msgstr "" "\n" " # grep pcmk_plugin_init /var/log/messages\n" "\t \n" "\t \n" " Aug 27 16:53:15 test1 openais[2166]: [pcmk ] info: pcmk_plugin_init: CRM: Initialized\n" " Aug 27 16:53:15 test1 openais[2166]: [pcmk ] Logging: Initialized pcmk_plugin_init\n" " Aug 27 16:53:15 test1 openais[2166]: [pcmk ] info: pcmk_plugin_init: Service: 9\n" " Aug 27 16:53:15 test1 openais[2166]: [pcmk ] info: pcmk_plugin_init: Local hostname: test1\n" "\t \n" "\t " #. Tag: caption #, no-c-format msgid "If you don't see these messages, or some like them, there is likely a problem finding or loading the pacemaker plugin." msgstr "Dacă nu vedeţi aceste mesaje sau unele similare, este probabil o problemă în găsirea sau încărcarea plugin-ului pacemaker." #. Tag: title #, no-c-format msgid "Expected process listing on a 64-bit machine" msgstr "Lista de procese aşteptate pe o maşină pe 64 de biţi" #. Tag: screen #, fuzzy, no-c-format msgid "" "\n" " # ps axf\n" " \n" " \n" " 3718 ? Ssl 0:05 /usr/sbin/aisexec\n" " 3723 ? SLs 0:00 \\_ /usr/lib64/heartbeat/stonithd\n" " 3724 ? S 0:05 \\_ /usr/lib64/heartbeat/cib\n" " 3725 ? S 0:21 \\_ /usr/lib64/heartbeat/lrmd\n" " 3726 ? S 0:01 \\_ /usr/lib64/heartbeat/attrd\n" " 3727 ? S 0:00 \\_ /usr/lib64/heartbeat/pengine\n" " 3728 ? S 0:01 \\_ /usr/lib64/heartbeat/crmd\n" " \n" " " msgstr "" "\n" " # ps axf\n" "\t \n" "\t \n" " 3718 ? Ssl 0:05 /usr/sbin/aisexec\n" " 3723 ? SLs 0:00 \\_ /usr/lib64/heartbeat/stonithd\n" " 3724 ? S 0:05 \\_ /usr/lib64/heartbeat/cib\n" " 3725 ? S 0:21 \\_ /usr/lib64/heartbeat/lrmd\n" " 3726 ? S 0:01 \\_ /usr/lib64/heartbeat/attrd\n" " 3727 ? S 0:00 \\_ /usr/lib64/heartbeat/pengine\n" " 3728 ? S 0:01 \\_ /usr/lib64/heartbeat/crmd\n" "\t \n" "\t " #. Tag: caption #, no-c-format msgid "On 32-bit systems the exact path may differ, but all the above processes should be listed." msgstr "Pe sistemele pe 32 de biţi calea exactă poate fi diferită, dar toate procesele de mai sus ar trebui să fie listate." pacemaker-master/doc/Pacemaker_Explained/ro-RO/Ap-FAQ.po000066400000000000000000000167211217637305600232110ustar00rootroot00000000000000msgid "" msgstr "" "Project-Id-Version: Pacemaker 1.1\n" "POT-Creation-Date: 2012-10-17T05:19:01\n" "PO-Revision-Date: 2012-01-01T17:48:32\n" "Last-Translator: Dan Frîncu \n" "Language-Team: None\n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: application/x-publican; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. Tag: title #, no-c-format msgid "FAQ" msgstr "FAQ" #. Tag: title #, no-c-format msgid "History" msgstr "Istoric" #. Tag: para #, no-c-format msgid "Why is the Project Called PacemakernamingPacemaker?" msgstr "De ce este Proiectul Numit PacemakerdenumirePacemaker?" #. Tag: para #, no-c-format msgid "First of all, the reason its not called the CRM is because of the abundance of terms that are commonly abbreviated to those three letters." msgstr "În primul rând, motivul pentru care nu este denumit CRM este datorită abundenţei de termeni care sunt asociaţi în mod obişnuit cu acele trei litere." #. Tag: para #, no-c-format msgid "The Pacemaker name came from Kham, a good friend of mine, and was originally used by a Java GUI that I was prototyping in early 2007. Alas other commitments have prevented the GUI from progressing much and, when it came time to choose a name for this project, Lars suggested it was an even better fit for an independent CRM." msgstr "Numele de Pacemaker a provenit de la Kham, un bun prieten de-al meu, şi a fost folosit iniţial de către un GUI Java pentru care am creat prototipul în prima parte a anului 2007. Alte angajamente au împiedicat progresul semnificativ al GUI-ului şi când a venit momentul să alegem un nume pentru acest proiect, Lars a sugerat că ar fi o potrivire şi mai bună pentru un CRM independent." #. Tag: para #, no-c-format msgid "The idea stems from the analogy between the role of this software and that of the little device that keeps the human heart pumping. Pacemaker monitors the cluster and intervenes when necessary to ensure the smooth operation of the services it provides." msgstr "Ideea provine din analogia dintre rolul acestui software şi acela al micului dispozitiv care menţine inima umană pompând. Pacemaker monitorizează clusterul şi intervine când este necesar pentru a asigura operarea fluentă a serviciilor pe care le furnizează." #. Tag: para #, no-c-format msgid "There were a number of other names (and acronyms) tossed around, but suffice to say \"Pacemaker\" was the best" msgstr "Au existat un număr de alte nume (şi acronime) aruncate de colo, colo, dar este suficient să spun că \"Pacemaker\" a fost cel mai bun" #. Tag: para #, no-c-format msgid "Why was the Pacemaker Project Created?" msgstr "De ce a fost Creat Proiectul Pacemaker?" #. Tag: para #, no-c-format msgid "The decision was made to spin-off the CRM into its own project after the 2.1.3 Heartbeat release in order to" msgstr "Decizia a fost luată de a crea un produs secundar din CRM prin a avea proiectul propriu după lansarea Heartbeat 2.1.3 pentru a" #. Tag: para #, no-c-format msgid "support both the Corosync and Heartbeat cluster stacks equally" msgstr "suporta ambele stive de cluster, Corosync şi Heartbeat, în mod egal" #. Tag: para #, no-c-format msgid "decouple the release cycles of two projects at very different stages of their life-cycles" msgstr "decupla ciclurile de lansare ale celor două proiecte aflate la stadii foarte diferite ale ciclului vieţii acestora" #. Tag: para #, no-c-format msgid "foster the clearer package boundaries, thus leading to" msgstr "adopta graniţe mai clare legate de pachete, tinzând către" #. Tag: para #, no-c-format msgid "better and more stable interfaces" msgstr "interfeţe mai bune şi mai stabile" #. Tag: title #, no-c-format msgid "Setup" msgstr "Setup" #. Tag: para #, no-c-format msgid "What Messaging Layers Messaging Layers are Supported?" msgstr "Care Straturi de Mesagerie Straturi de Mesagerie sunt Suportate?" #. Tag: para #, no-c-format msgid "Corosync ()" msgstr "Corosync ()" #. Tag: para #, no-c-format msgid "Heartbeat ()" msgstr "Heartbeat ()" #. Tag: para #, no-c-format msgid "Can I Choose which Messaging Layer to use at Run Time?" msgstr "Pot Alege care Strat de Mesagerie să îl Folosesc la Momentul Rulării?" #. Tag: para #, no-c-format msgid "Yes. The CRM will automatically detect which started it and behave accordingly." msgstr "Da. CRM-ul va detecta în mod automat cine l-a pornit şi se va comporta în concordanţă." #. Tag: para #, no-c-format msgid "Can I Have a Mixed Heartbeat-Corosync Cluster?" msgstr "Pot Avea un Cluster Mixt Heartbeat-Corosync?" #. Tag: para #, no-c-format msgid "No." msgstr "Nu." #. Tag: para #, no-c-format msgid "Which Messaging Layer Should I Choose?" msgstr "Care Strat de Mesagerie ar trebui să îl aleg?" #. Tag: para #, no-c-format msgid "This is discussed in ." msgstr "Acest lucru este dscutat în ." #. Tag: para #, no-c-format msgid "Where Can I Get Pre-built Packages?" msgstr "De Unde Pot Obţine Pachete Pre-Compilate?" #. Tag: para #, no-c-format msgid "Official packages for most major .rpm and based distributions are available from the ClusterLabs Website." msgstr "Pachete oficiale pentru majoritatea distribuţiilor majore bazate pe .rpm sunt disponibile de pe WebSite-ul ClusterLabs." #. Tag: para #, no-c-format msgid "For Debian packages, building from source and details on using the above repositories, see our installation page." msgstr "Pentru pachete Debian, compilarea din sursă şi detalii asupra folosirii repositoarelor de mai sus, vedeți pagina noastră de instalare." #. Tag: para #, no-c-format msgid "What Versions of Pacemaker Are Supported?" msgstr "Care Versiuni de Pacemaker sunt Suportate?" #. Tag: para #, no-c-format msgid "Please refer to the Releases page for an up-to-date list of versions supported directly by the project." msgstr "Vă rugam să consultaţi pagina de Releases pentru o listă la zi a versiunilor suportate în mod direct de către proiect." #. Tag: para #, no-c-format msgid "When seeking assistance, please try to ensure you have one of these versions." msgstr "Când căutaţi asistenţă, vă rugăm să vă asiguraţi că aveţi una din versiunile acestea." pacemaker-master/doc/Pacemaker_Explained/ro-RO/Ap-Install.po000066400000000000000000000262231217637305600242060ustar00rootroot00000000000000msgid "" msgstr "" "Project-Id-Version: Pacemaker 1.1\n" "POT-Creation-Date: 2012-10-17T05:19:01\n" "PO-Revision-Date: 2012-01-01T17:48:32\n" "Last-Translator: Dan Frîncu \n" "Language-Team: None\n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: application/x-publican; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. Tag: title #, no-c-format msgid "Installation" msgstr "Instalare" #. Tag: para #, no-c-format msgid "The following text may no longer be accurate in some places." msgstr "" #. Tag: title #, no-c-format msgid "Choosing a Cluster Stack" msgstr "" #. Tag: para #, no-c-format msgid " ClusterChoosing Between Heartbeat and Corosync Choosing Between Heartbeat and Corosync Cluster StackCorosync Corosync Corosync Cluster StackHeartbeat Heartbeat Heartbeat " msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "Ultimately the choice of cluster stack is a personal decision that must be made in the context of you or your company’s needs and strategic direction. Pacemaker currently functions equally well with both stacks." msgstr "În ultimă instanţă alegerea unei stive de cluster este o decizie personală care trebuie realizată în contextul vostru sau al nevoilor şi direcţiei strategice ale companiei voastre. În momentul de faţă Pacemaker funcţionează la fel de bine cu ambele stive." #. Tag: para #, no-c-format msgid "Here are some factors that may influence the decision:" msgstr "În continuare sunt câţiva factori care ar putea influenţa decizia" #. Tag: para #, no-c-format msgid "SUSE/Novell, Red Hat and Oracle are all putting their collective weight behind the Corosync cluster stack." msgstr "SUSE/Novell, Red Hat şi Oracle îşi pun la contribuţie greutatea colectivă pentru a susţine stiva de cluster Corosync." #. Tag: para #, no-c-format msgid "Using Corosync gives your applications access to the following additional cluster services" msgstr "Folosirea Corosync oferă aplicaţiilor dvs. acces la următoarele servicii de cluster adiţionale" #. Tag: para #, no-c-format msgid "distributed locking service" msgstr "serviciu de blocare distribuit" #. Tag: para #, no-c-format msgid "extended virtual synchronization service" msgstr "serviciu de sincronie virtuală extinsă" #. Tag: para #, no-c-format msgid "cluster closed process group service" msgstr "serviciu de grup de procese închise de cluster" #. Tag: para #, no-c-format msgid "It is likely that Pacemaker, at some point in the future, will make use of some of these additional services not provided by Heartbeat" msgstr "Este probabil ca Pacemaker, la un moment dat în viitor, să utilizeze o parte din aceste servicii adiţionale care nu sunt furnizate de Heartbeat" #. Tag: title #, no-c-format msgid "Enabling Pacemaker" msgstr "Activarea Pacemaker" #. Tag: title #, no-c-format msgid "For Corosync" msgstr "Pentru Corosync" #. Tag: para #, fuzzy, no-c-format msgid "The Corosync configuration is normally located in /etc/corosync/corosync.conf and an example for a machine with an address of 1.2.3.4 in a cluster communicating on port 1234 (without peer authentication and message encryption) is shown below." msgstr "Fişierul de configurare al Corosync se găseşte în mod normal în /etc/corosync/corosync.conf şi un exemplu pentru o maşină cu adresa 1.2.3.4 într-un cluster care comunică pe portul 1234 (fără autentificarea partenerului sau criptarea mesajelor) este prezentată mai jos." #. Tag: title #, no-c-format msgid "An example Corosync configuration file" msgstr "Un exemplu de fişier de configurare al Corosync" #. Tag: programlisting #, fuzzy, no-c-format msgid "" " totem {\n" " version: 2\n" " secauth: off\n" " threads: 0\n" " interface {\n" " ringnumber: 0\n" " bindnetaddr: 1.2.3.4\n" " mcastaddr: 239.255.1.1\n" " mcastport: 1234\n" " }\n" " }\n" " logging {\n" " fileline: off\n" " to_syslog: yes\n" " syslog_facility: daemon\n" " }\n" " amf {\n" " mode: disabled\n" " }" msgstr "" "totem {\n" " version: 2\n" " secauth: off\n" " threads: 0\n" " interface {\n" " ringnumber: 0\n" " bindnetaddr: 1.2.3.4\n" " mcastaddr: 226.94.1.1\n" " mcastport: 1234\n" " }\n" " }\n" " logging {\n" " fileline: off\n" " to_syslog: yes\n" " syslog_facility: daemon\n" " }\n" " amf {\n" " mode: disabled\n" " }\n" "\t" #. Tag: para #, no-c-format msgid "The logging should be mostly obvious and the amf section refers to the Availability Management Framework and is not covered in this document." msgstr "Partea de loguri ar trebui să fie evidentă în cea mai mare parte şi secţiunea amf se referă la Availability Management Framework şi nu este acoperit în acest document." #. Tag: para #, fuzzy, no-c-format msgid "The interesting part of the configuration is the totem section. This is where we define how the node can communicate with the rest of the cluster and what protocol version and options (including encryption Please consult the Corosync website (http://www.corosync.org/) and documentation for details on enabling encryption and peer authentication for the cluster. ) it should use. Beginners are encouraged to use the values shown and modify the interface section based on their network." msgstr "Partea interesantă a configuraţiei o reprezintă secţiunea totem. Aici definim cum poate comunica un nod cu restul clusterului şi ce versiune de protocol şi opţiuni (incluzând criptarea Vă rugăm să consultaţi website-ul Corosync şi documentaţia pentru detalii despre activarea criptării şi a autentificării partenerului pentru cluster. ) ar trebui să folosească. Începătorii sunt încurajaţi să folosească valorile prezentate şi să modifice secţiunea referitoare la interfaţă pe baza reţelei acestora." #. Tag: para #, no-c-format msgid "It is also possible to configure Corosync for an IPv6 based environment. Simply configure bindnetaddr and mcastaddr with their IPv6 equivalents, eg." msgstr "Este totodată posibilă configurarea Corosync pentru un mediu bazat pe IPV6. Pur şi simplu configuraţi bindnetaddr şi mcastaddr cu echivalentele IPV6 ale acestora. ex." #. Tag: title #, no-c-format msgid "Example options for an IPv6 environment" msgstr "Exemple de opţiuni pentru un mediu IPV6" #. Tag: programlisting #, fuzzy, no-c-format msgid "" " bindnetaddr: fec0::1:a800:4ff:fe00:20\n" " mcastaddr: ff05::1" msgstr "" "bindnetaddr: fec0::1:a800:4ff:fe00:20 \n" " mcastaddr: ff05::1\n" "\t " #. Tag: para #, no-c-format msgid "To tell Corosync to use the Pacemaker cluster manager, add the following fragment to a functional Corosync configuration and restart the cluster." msgstr "Pentru a îi spune Corosync-ului să folosească Pacemaker ca şi manager al clusterului, adăugaţi următorul fragment la o configuraţie funcţională de Corosync şi reporniţi clusterul." #. Tag: title #, no-c-format msgid "Configuration fragment for enabling Pacemaker under Corosync" msgstr "Fragment de configurare pentru a activa Pacemaker sub Corosync" #. Tag: programlisting #, fuzzy, no-c-format msgid "" "aisexec {\n" " user: root\n" " group: root\n" "}\n" "service {\n" " name: pacemaker\n" " ver: 0\n" "}" msgstr "" "aisexec {\n" " user: root\n" " group: root\n" "}\n" "service {\n" " name: pacemaker\n" " ver: 0\n" "}\n" "\t " #. Tag: para #, fuzzy, no-c-format msgid "The cluster needs to be run as root so that its child processes (the lrmd in particular) have sufficient privileges to perform the actions requested of it. After all, a cluster manager that can’t add an IP address or start apache is of little use." msgstr "Clusterul trebuie să ruleze ca root pentru ca procesele copil ale acestuia (lrmd-ul în particular) să aibe suficiente privilegii pentru a îndeplini acţiunile care i s-au cerut. La urma urmei, un manager de cluster care nu poate să adauge o adresă IP sau să pornească apache este de puţin folos." #. Tag: para #, no-c-format msgid "The second directive is the one that actually instructs the cluster to run Pacemaker." msgstr "A doua directivă este cea care instruieşte de fapt clusterul să ruleze Pacemaker." #. Tag: title #, no-c-format msgid "For Heartbeat" msgstr "Pentru Heartbeat" #. Tag: para #, fuzzy, no-c-format msgid "Add the following to a functional ha.cf configuration file and restart Heartbeat:" msgstr "Adăugaţi următoarele la un fişier de configurare ha.cf funcţional şi reporniţi Heartbeat" #. Tag: title #, no-c-format msgid "Configuration fragment for enabling Pacemaker under Heartbeat" msgstr "Fragment de configurare pentru a activa Pacemaker sub Heartbeat" #. Tag: programlisting #, fuzzy, no-c-format msgid "crm respawn" msgstr "" "crm respawn\n" "\t " #~ msgid "Choosing a Cluster Stackchoosing oneCluster Stack" #~ msgstr "Alegerea unei Stive de Clusteralegerea uneiStive de Cluster" #~ msgid "Cluster StackCorosync CorosyncCorosync is an OSI Certified implementation of an industry standard (the Service Availability Forum Application Interface Specification)." #~ msgstr "Stivă de ClusterCorosync CorosyncCorosync este o implementare Certificată OSI a unui standard al industriei (Service Availability Forum Application Interface Specification)." #~ msgid "checkpoint service" #~ msgstr "serviciu punct de control" #~ msgid "To date, Pacemaker has received less real-world testing on Corosync than it has on Cluster StackHeartbeat HeartbeatHeartbeat." #~ msgstr "Până în acest moment, Pacemaker a avut parte de mai puţină testare \"real-world\" pe Corosync faţă de Stivă de ClusterHeartbeat HeartbeatHeartbeat" pacemaker-master/doc/Pacemaker_Explained/ro-RO/Ap-LSB.po000066400000000000000000000125231217637305600232160ustar00rootroot00000000000000msgid "" msgstr "" "Project-Id-Version: Pacemaker 1.1\n" "POT-Creation-Date: 2012-10-17T05:19:01\n" "PO-Revision-Date: 2012-01-01T17:48:32\n" "Last-Translator: Dan Frîncu \n" "Language-Team: None\n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: application/x-publican; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. Tag: title #, no-c-format msgid "init-Script LSB Compliance" msgstr "Este acest script de init compatibil LSB?" #. Tag: para #, fuzzy, no-c-format msgid "The relevant part of LSB spec includes a description of all the return codes listed here." msgstr "Partea relevantă a scripturi de init LSBscripturi de initcompatibilitatespecificaţiei LSB http://refspecs.freestandards.org/LSB_3.1.0/LSB-Core-generic/LSB-Core-generic/iniscrptact.html include o descriere a tuturor codurilor de ieşire listate aici." #. Tag: para #, no-c-format msgid "Assuming some_service is configured correctly and currently not active, the following sequence will help you determine if it is LSB compatible:" msgstr "Sub presupunerea că some_service este configurat corect şi nu este activ în momentul de faţă, următoarea secvenţă vă poate ajuta să determinaţi dacă este compatibil LSB:" #. Tag: para #, no-c-format msgid "Start (stopped):" msgstr "Porneşte (oprit):" #. Tag: programlisting #, fuzzy, no-c-format msgid "# /etc/init.d/some_service start ; echo \"result: $?\"" msgstr " /etc/init.d/some_service start ; echo \"rezultat: $?\" " #. Tag: para #, no-c-format msgid "Did the service start?" msgstr "A pornit serviciul?" #. Tag: para #, no-c-format msgid "Did the command print result: 0 (in addition to the regular output)?" msgstr "A printat comanda rezultatul de ieşire: 0 (suplimentar faţă de rezultatul contextual normal)?" #. Tag: para #, no-c-format msgid "Status (running):" msgstr "Status (rulând):" #. Tag: programlisting #, fuzzy, no-c-format msgid "# /etc/init.d/some_service status ; echo \"result: $?\"" msgstr "/etc/init.d/some_service status ; echo \"rezultat: $?\" " #. Tag: para #, no-c-format msgid "Did the script accept the command?" msgstr "A acceptat scriptul comanda?" #. Tag: para #, no-c-format msgid "Did the script indicate the service was running?" msgstr "A indicat scriptul dacă serviciul rula?" #. Tag: para #, no-c-format msgid "Start (running):" msgstr "Porneşte (rulând):" #. Tag: para #, no-c-format msgid "Is the service still running?" msgstr "Serviciul încă rulează?" #. Tag: para #, no-c-format msgid "Stop (running):" msgstr "Opreşte (rulând):" #. Tag: programlisting #, fuzzy, no-c-format msgid "# /etc/init.d/some_service stop ; echo \"result: $?\"" msgstr "/etc/init.d/some_service stop ; echo \"rezultat: $?\" " #. Tag: para #, no-c-format msgid "Was the service stopped?" msgstr "A fost oprit serviciul?" #. Tag: para #, no-c-format msgid "Status (stopped):" msgstr "Status (oprit):" #. Tag: para #, no-c-format msgid "Did the script indicate the service was not running?" msgstr "A indicat scriptul faptul că serviciul nu rula?" #. Tag: para #, no-c-format msgid "Did the command print result: 3 (in addition to the regular output)?" msgstr "A printat comanda rezultatul de ieşire: 3 (suplimentar faţă de rezultatul contextual normal)?" #. Tag: para #, no-c-format msgid "Stop (stopped):" msgstr "Opreşte (oprit):" #. Tag: para #, no-c-format msgid "Is the service still stopped?" msgstr "Este serviciul în continuare oprit?" #. Tag: para #, no-c-format msgid "Status (failed):" msgstr "Status (eşuat):" #. Tag: para #, no-c-format msgid "This step is not readily testable and relies on manual inspection of the script." msgstr "Acest pas nu este gata pentru a fi testat şi se bazează pe inspecţia manuală a scriptului." #. Tag: para #, no-c-format msgid "The script can use one of the error codes (other than 3) listed in the LSB spec to indicate that it is active but failed. This tells the cluster that before moving the resource to another node, it needs to stop it on the existing one first." msgstr "Scriptul poate folosi unul din codurile de eroare (altul decât 3) listate în specificaţia LSB pentru a indica faptul că este activ dar eşuat. Acesta îi spune clusterului ca înainte de a muta resursa pe alt nod, trebuie să o oprească mai întâi pe cel existent." #. Tag: para #, no-c-format msgid "If the answer to any of the above questions is no, then the script is not LSB compliant. Your options are then to either fix the script or write an OCF agent based on the existing script." msgstr "Dacă răspunsul la oricare din întrebările de mai sus este nu, atunci scriptul nu este compatibil LSB. Opţiunile disponibile în acel moment sunt fie de a repara scriptul fie de a scrie un agent OCF bazat pe scriptul existent." #~ msgid "/etc/init.d/some_service start ; echo \"result: $?\"" #~ msgstr "/etc/init.d/some_service start ; echo \"rezultat: $?\"" pacemaker-master/doc/Pacemaker_Explained/ro-RO/Ap-OCF.po000066400000000000000000001257271217637305600232200ustar00rootroot00000000000000msgid "" msgstr "" "Project-Id-Version: Pacemaker 1.1\n" "POT-Creation-Date: 2012-10-17T05:19:01\n" "PO-Revision-Date: 2012-01-01T17:48:32\n" "Last-Translator: Dan Frîncu \n" "Language-Team: None\n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: application/x-publican; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. Tag: title #, no-c-format msgid "More About OCF Resource Agents" msgstr "Mai Multe Despre Agenţii de Resursă OCF" #. Tag: title #, no-c-format msgid "Location of Custom Scripts" msgstr "Locaţia Scripturilor Personalizate" #. Tag: para #, fuzzy, no-c-format msgid " OCF Resource Agents OCF Resource Agents are found in /usr/lib/ocf/resource.d/provider." msgstr "Agenţii de Resursă OCFAgenţii de Resursă OCF se găsesc în /usr/lib/ocf/resource.d/furnizor." #. Tag: para #, fuzzy, no-c-format msgid "When creating your own agents, you are encouraged to create a new directory under /usr/lib/ocf/resource.d/ so that they are not confused with (or overwritten by) the agents shipped with Heartbeat." msgstr "Când vă creaţi proprii agenţi, sunteţi încurajaţi să creaţi un nou director sub /usr/lib/ocf/resource.d/ astfel încât aceştia să nu fie încurcaţi cu (sau suprascrişi de) agenţii livraţi împreună cu Heartbeat. Deci, de exemplu, dacă aţi fi ales numele de furnizor bigCorp şi aţi fi dorit o nouă resursă numită bigApp, aţi crea un script numit /usr/lib/ocf/resource.d/bigCorp/bigApp şi aţi defini o resursă:" #. Tag: para #, fuzzy, no-c-format msgid "So, for example, if you chose the provider name of bigCorp and wanted a new resource named bigApp, you would create a script called /usr/lib/ocf/resource.d/bigCorp/bigApp and define a resource:" msgstr "Când vă creaţi proprii agenţi, sunteţi încurajaţi să creaţi un nou director sub /usr/lib/ocf/resource.d/ astfel încât aceştia să nu fie încurcaţi cu (sau suprascrişi de) agenţii livraţi împreună cu Heartbeat. Deci, de exemplu, dacă aţi fi ales numele de furnizor bigCorp şi aţi fi dorit o nouă resursă numită bigApp, aţi crea un script numit /usr/lib/ocf/resource.d/bigCorp/bigApp şi aţi defini o resursă:" #. Tag: programlisting #, no-c-format msgid "<primitive id=\"custom-app\" class=\"ocf\" provider=\"bigCorp\" type=\"bigApp\"/>" msgstr "<primitive id=\"custom-app\" class=\"ocf\" provider=\"bigCorp\" type=\"bigApp\"/>" #. Tag: title #, no-c-format msgid "Actions" msgstr "Acţiuni" #. Tag: para #, no-c-format msgid "All OCF Resource Agents are required to implement the following actions" msgstr "Toţi Agenţii de Resursă OCF sunt obligaţi să implementeze următoarele acţiuni" #. Tag: title #, no-c-format msgid "Required Actions for OCF Agents" msgstr "Acţiuni Necesare pentru Agenţii OCF" #. Tag: entry #, no-c-format msgid "Action" msgstr "Acţiune" #. Tag: entry #, no-c-format msgid "Description" msgstr "Descriere" #. Tag: entry #, no-c-format msgid "Instructions" msgstr "Instrucţiuni" #. Tag: para #, no-c-format msgid "start" msgstr "" #. Tag: para #, no-c-format msgid "Start the resource" msgstr "Porneşte resursa" #. Tag: para #, fuzzy, no-c-format msgid "Return 0 on success and an appropriate error code otherwise. Must not report success until the resource is fully active. startOCF Action OCF Action OCFActionstart Actionstart start " msgstr "OCF_ERR_ARGS Environment VariableOCF_ERR_ARGS return codeOCF_ERR_ARGSOCF_ERR_ARGS" #. Tag: para #, no-c-format msgid "stop" msgstr "" #. Tag: para #, no-c-format msgid "Stop the resource" msgstr "Opreşte resursa" #. Tag: para #, fuzzy, no-c-format msgid "Return 0 on success and an appropriate error code otherwise. Must not report success until the resource is fully stopped. stopOCF Action OCF Action OCFActionstop Actionstop stop " msgstr "OCF_ERR_ARGS Environment VariableOCF_ERR_ARGS return codeOCF_ERR_ARGSOCF_ERR_ARGS" #. Tag: para #, no-c-format msgid "monitor" msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "Check the resource’s state" msgstr "Verifică starea resursei" #. Tag: para #, fuzzy, no-c-format msgid "Exit 0 if the resource is running, 7 if it is stopped, and anything else if it is failed. monitorOCF Action OCF Action OCFActionmonitor Actionmonitor monitor " msgstr "OCF_ERR_ARGS Environment VariableOCF_ERR_ARGS return codeOCF_ERR_ARGSOCF_ERR_ARGS" #. Tag: para #, no-c-format msgid "NOTE: The monitor script should test the state of the resource on the local machine only." msgstr "NOTĂ: Scriptul de monitorizare ar trebui să testeze starea resursei numai pe maşina locală." #. Tag: para #, no-c-format msgid "meta-data" msgstr "" #. Tag: para #, no-c-format msgid "Describe the resource" msgstr "Descrie resursa" #. Tag: para #, fuzzy, no-c-format msgid "Provide information about this resource as an XML snippet. Exit with 0. meta-dataOCF Action OCF Action OCFActionmeta-data Actionmeta-data meta-data " msgstr "OCF_ERR_ARGS Environment VariableOCF_ERR_ARGS return codeOCF_ERR_ARGSOCF_ERR_ARGS" #. Tag: para #, fuzzy, no-c-format msgid "NOTE: This is not performed as root." msgstr "NOTĂ: Acest aspect nu este efectuat ca root." #. Tag: para #, no-c-format msgid "validate-all" msgstr "" #. Tag: para #, no-c-format msgid "Verify the supplied parameters" msgstr "Verifică dacă parametrii furnizaţi sunt corecţi" #. Tag: para #, fuzzy, no-c-format msgid "Exit with 0 if parameters are valid, 2 if not valid, 6 if resource is not configured. validate-allOCF Action OCF Action OCFActionvalidate-all Actionvalidate-all validate-all " msgstr "OCF_ERR_ARGS Environment VariableOCF_ERR_ARGS return codeOCF_ERR_ARGSOCF_ERR_ARGS" #. Tag: para #, no-c-format msgid "Additional requirements (not part of the OCF specs) are placed on agents that will be used for advanced concepts like clones and multi-state resources." msgstr "Cerinţe suplimentare (care nu sunt parte din specificaţia OCF) sunt plasate pe agenţi care vor fi folosiţi pentru concepte avansate cum ar fi clone şi resurse multi-state." #. Tag: title #, no-c-format msgid "Optional Actions for OCF Agents" msgstr "Acţiuni Opţionale pentru Agenţi OCF" #. Tag: para #, no-c-format msgid "promote" msgstr "" #. Tag: para #, no-c-format msgid "Promote the local instance of a multi-state resource to the master/primary state." msgstr "Promovează instanţa locală a unei resurse multi-state la starea master/primară" #. Tag: para #, fuzzy, no-c-format msgid "Return 0 on success promoteOCF Action OCF Action OCFActionpromote Actionpromote promote " msgstr "OCF_ERR_ARGS Environment VariableOCF_ERR_ARGS return codeOCF_ERR_ARGSOCF_ERR_ARGS" #. Tag: para #, no-c-format msgid "demote" msgstr "" #. Tag: para #, no-c-format msgid "Demote the local instance of a multi-state resource to the slave/secondary state." msgstr "Retrogradează instanţa locală a unei resurse multi-state la starea slave/secundară" #. Tag: para #, fuzzy, no-c-format msgid "Return 0 on success demoteOCF Action OCF Action OCFActiondemote Actiondemote demote " msgstr "OCF_ERR_ARGS Environment VariableOCF_ERR_ARGS return codeOCF_ERR_ARGSOCF_ERR_ARGS" #. Tag: para #, no-c-format msgid "notify" msgstr "" #. Tag: para #, no-c-format msgid "Used by the cluster to send the agent pre and post notification events telling the resource what has happened and will happen." msgstr "Folosit de către cluster pentru a trimite agentului notificări pre şi post eveniment spunându-i resursei ceea ce se întâmplă sau ce tocmai s-a întâmplat" #. Tag: para #, fuzzy, no-c-format msgid "Must not fail. Must exit with 0 notifyOCF Action OCF Action OCFActionnotify Actionnotify notify " msgstr "OCF_ERR_ARGS Environment VariableOCF_ERR_ARGS return codeOCF_ERR_ARGSOCF_ERR_ARGS" #. Tag: para #, no-c-format msgid "One action specified in the OCF specs is not currently used by the cluster:" msgstr "O acţiune specificată în specificaţiile OCF nu este folosită de către cluster în mod curent" #. Tag: para #, no-c-format msgid "recover - a variant of the start action, this should try to recover a resource locally." msgstr "recover - o variantă a acţiunii start, aceasta ar trebui să recupereze o resursă local." #. Tag: para #, fuzzy, no-c-format msgid "Remember to use ocf-tester ocf-tester to verify that your new agent complies with the OCF standard properly." msgstr "Nu uitaţi să folosiţi ocf-testerocf-tester pentru a verifica dacă noul vostru agent este compatibil cu standardul OCF." #. Tag: title #, no-c-format msgid "How are OCF Return Codes Interpreted?" msgstr "Cum sunt Interpretate Codurile de Ieșire OCF?" #. Tag: para #, no-c-format msgid "The first thing the cluster does is to check the return code against the expected result. If the result does not match the expected value, then the operation is considered to have failed and recovery action is initiated." msgstr "Primul lucru pe care îl face clusterul este să verifice codul de ieşire faţă de rezultatul aşteptat. Dacă rezultatul nu se potriveşte cu valoarea aşteptată, atunci este considerat că operaţiunea a eşuat şi acţiunea de recuperare este iniţiată." #. Tag: para #, no-c-format msgid "There are three types of failure recovery:" msgstr "Sunt trei tipuri de recuperare în caz de eşec:" #. Tag: title #, no-c-format msgid "Types of recovery performed by the cluster" msgstr "Tipuri de recuperare realizate de către cluster" #. Tag: entry #, no-c-format msgid "Type" msgstr "Tip" #. Tag: entry #, no-c-format msgid "Action Taken by the Cluster" msgstr "Acţiunea Luată de către Cluster" #. Tag: para #, no-c-format msgid "soft" msgstr "" #. Tag: para #, no-c-format msgid "A transient error occurred" msgstr "O eroare tranzientă a avut loc" #. Tag: para #, fuzzy, no-c-format msgid "Restart the resource or move it to a new location softOCF error OCF error OCFerrorsoft errorsoft soft " msgstr "OCF_ERR_ARGS Environment VariableOCF_ERR_ARGS return codeOCF_ERR_ARGSOCF_ERR_ARGS" #. Tag: para #, no-c-format msgid "hard" msgstr "" #. Tag: para #, no-c-format msgid "A non-transient error that may be specific to the current node occurred" msgstr "O eroare non-tranzientă s-a produs care ar putea fi specifică nodului curent" #. Tag: para #, fuzzy, no-c-format msgid "Move the resource elsewhere and prevent it from being retried on the current node hardOCF error OCF error OCFerrorhard errorhard hard " msgstr "OCF_ERR_ARGS Environment VariableOCF_ERR_ARGS return codeOCF_ERR_ARGSOCF_ERR_ARGS" #. Tag: para #, no-c-format msgid "fatal" msgstr "" #. Tag: para #, no-c-format msgid "A non-transient error that will be common to all cluster nodes (eg. a bad configuration was specified)" msgstr "O eroare non-tranzientă care va fi comună pe toate nodurile clusterului (ex.: o configuraţie greşită a fost specificată)" #. Tag: para #, fuzzy, no-c-format msgid "Stop the resource and prevent it from being started on any cluster node fatalOCF error OCF error OCFerrorfatal errorfatal fatal " msgstr "OCF_ERR_ARGS Environment VariableOCF_ERR_ARGS return codeOCF_ERR_ARGSOCF_ERR_ARGS" #. Tag: para #, no-c-format msgid "Assuming an action is considered to have failed, the following table outlines the different OCF return codes and the type of recovery the cluster will initiate when it is received." msgstr "Plecând de la presupunerea că o acţiune este considerată că ar fi eşuat, următorul tabel evidenţiază diferitele coduri de ieşire OCF şi tipul de recuperare pe care o va iniţia clusterul când acest cod este primit." #. Tag: title #, fuzzy, no-c-format msgid "OCF Return Codes" msgstr "Cum sunt Interpretate Codurile de Ieșire OCF?" #. Tag: title #, no-c-format msgid "OCF Return Codes and their Recovery Types" msgstr "Codurile de Ieşire OCF şi Cum Sunt Ele Gestionate" #. Tag: entry #, no-c-format msgid "RC" msgstr "RC" #. Tag: entry #, no-c-format msgid "OCF Alias" msgstr "Alias OCF" #. Tag: entry #, no-c-format msgid "RT" msgstr "RT" #. Tag: para #, no-c-format msgid "0" msgstr "" #. Tag: para #, no-c-format msgid "OCF_SUCCESS" msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "Success. The command completed successfully. This is the expected result for all start, stop, promote and demote commands. Return CodeOCF_SUCCESS OCF_SUCCESS Return Code0OCF_SUCCESS 0OCF_SUCCESS OCF_SUCCESS " msgstr "OCF_ERR_CONFIGURED Environment VariableOCF_ERR_CONFIGURED return codeOCF_ERR_CONFIGUREDOCF_ERR_CONFIGURED" #. Tag: para #, no-c-format msgid "1" msgstr "" #. Tag: para #, no-c-format msgid "OCF_ERR_GENERIC" msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "Generic \"there was a problem\" error code. Return CodeOCF_ERR_GENERIC OCF_ERR_GENERIC Return Code1OCF_ERR_GENERIC 1OCF_ERR_GENERIC OCF_ERR_GENERIC " msgstr "OCF_ERR_GENERIC Environment VariableOCF_ERR_GENERIC return codeOCF_ERR_GENERIC OCF_ERR_GENERIC" #. Tag: para #, no-c-format msgid "2" msgstr "" #. Tag: para #, no-c-format msgid "OCF_ERR_ARGS" msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "The resource’s configuration is not valid on this machine. Eg. refers to a location/tool not found on the node. Return CodeOCF_ERR_ARGS OCF_ERR_ARGS Return Code2OCF_ERR_ARGS 2OCF_ERR_ARGS OCF_ERR_ARGS " msgstr "OCF_ERR_ARGS Environment VariableOCF_ERR_ARGS return codeOCF_ERR_ARGSOCF_ERR_ARGS" #. Tag: para #, no-c-format msgid "3" msgstr "" #. Tag: para #, no-c-format msgid "OCF_ERR_UNIMPLEMENTED" msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "The requested action is not implemented. Return CodeOCF_ERR_UNIMPLEMENTED OCF_ERR_UNIMPLEMENTED Return Code3OCF_ERR_UNIMPLEMENTED 3OCF_ERR_UNIMPLEMENTED OCF_ERR_UNIMPLEMENTED " msgstr "OCF_ERR_UNIMPLEMENTED Environment VariableOCF_ERR_UNIMPLEMENTED return codeOCF_ERR_UNIMPLEMENTEDOCF_ERR_UNIMPLEMENTED" #. Tag: para #, no-c-format msgid "4" msgstr "" #. Tag: para #, no-c-format msgid "OCF_ERR_PERM" msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "The resource agent does not have sufficient privileges to complete the task. Return CodeOCF_ERR_PERM OCF_ERR_PERM Return Code4OCF_ERR_PERM 4OCF_ERR_PERM OCF_ERR_PERM " msgstr "OCF_ERR_PERM Environment VariableOCF_ERR_PERM return codeOCF_ERR_PERMOCF_ERR_PERM" #. Tag: para #, no-c-format msgid "5" msgstr "" #. Tag: para #, no-c-format msgid "OCF_ERR_INSTALLED" msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "The tools required by the resource are not installed on this machine. Return CodeOCF_ERR_INSTALLED OCF_ERR_INSTALLED Return Code5OCF_ERR_INSTALLED 5OCF_ERR_INSTALLED OCF_ERR_INSTALLED " msgstr "OCF_ERR_INSTALLED Environment VariableOCF_ERR_INSTALLED return codeOCF_ERR_INSTALLEDOCF_ERR_INSTALLED" #. Tag: para #, no-c-format msgid "6" msgstr "" #. Tag: para #, no-c-format msgid "OCF_ERR_CONFIGURED" msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "The resource’s configuration is invalid. Eg. required parameters are missing. Return CodeOCF_ERR_CONFIGURED OCF_ERR_CONFIGURED Return Code6OCF_ERR_CONFIGURED 6OCF_ERR_CONFIGURED OCF_ERR_CONFIGURED " msgstr "OCF_ERR_CONFIGURED Environment VariableOCF_ERR_CONFIGURED return codeOCF_ERR_CONFIGUREDOCF_ERR_CONFIGURED" #. Tag: para #, no-c-format msgid "7" msgstr "" #. Tag: para #, no-c-format msgid "OCF_NOT_RUNNING" msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "The resource is safely stopped. The cluster will not attempt to stop a resource that returns this for any action. Return CodeOCF_NOT_RUNNING OCF_NOT_RUNNING Return Code7OCF_NOT_RUNNING 7OCF_NOT_RUNNING OCF_NOT_RUNNING " msgstr "OCF_ERR_CONFIGURED Environment VariableOCF_ERR_CONFIGURED return codeOCF_ERR_CONFIGUREDOCF_ERR_CONFIGURED" #. Tag: para #, no-c-format msgid "N/A" msgstr "" #. Tag: para #, no-c-format msgid "8" msgstr "" #. Tag: para #, no-c-format msgid "OCF_RUNNING_MASTER" msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "The resource is running in Master mode. Return CodeOCF_RUNNING_MASTER OCF_RUNNING_MASTER Return Code8OCF_RUNNING_MASTER 8OCF_RUNNING_MASTER OCF_RUNNING_MASTER " msgstr "OCF_RUNNING_MASTER Environment VariableOCF_RUNNING_MASTER return codeOCF_RUNNING_MASTEROCF_RUNNING_MASTER" #. Tag: para #, no-c-format msgid "9" msgstr "" #. Tag: para #, no-c-format msgid "OCF_FAILED_MASTER" msgstr "" #. Tag: para #, no-c-format msgid "The resource is in Master mode but has failed. The resource will be demoted, stopped and then started (and possibly promoted) again. Return CodeOCF_FAILED_MASTER OCF_FAILED_MASTER Return Code9OCF_FAILED_MASTER 9OCF_FAILED_MASTER OCF_FAILED_MASTER " msgstr "" #. Tag: para #, no-c-format msgid "other" msgstr "" #. Tag: para #, no-c-format msgid "NA" msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "Custom error code. Return Codeother other " msgstr "return code00" #. Tag: para #, no-c-format msgid "Although counterintuitive, even actions that return 0 (aka. OCF_SUCCESS) can be considered to have failed." msgstr "" #. Tag: title #, no-c-format msgid "Exceptions" msgstr "Excepţii" #. Tag: para #, no-c-format msgid "Non-recurring monitor actions (probes) that find a resource active (or in Master mode) will not result in recovery action unless it is also found active elsewhere" msgstr "Acţiunile de monitorizare nerecurente (probele) care găsesc o resursă activă (sau în starea Master) nu vor rezulta într-o acţiune de recuperare decât dacă este găsită activă în altă parte" #. Tag: para #, fuzzy, no-c-format msgid "The recovery action taken when a resource is found active more than once is determined by the multiple-active property of the resource" msgstr "Acţiunea de recuperare luată când o resursă este găsită activă mai mult de o dată este determinată de proprietatea multiple-active a resursei" #. Tag: para #, fuzzy, no-c-format msgid "Recurring actions that return OCF_ERR_UNIMPLEMENTED do not cause any type of recovery" msgstr "Acţiunile recurente care returnează OCF_ERR_UNIMPLEMENTED nu cauzează nici un fel de recuperare" #~ msgid "start action actionstartstart" #~ msgstr "start action actionstartstart" #~ msgid "Return 0 on success and an appropriate error code otherwise. Must not report success until the resource is fully active." #~ msgstr "Returnează 0 în caz de succes şi un cod de eroare potrivit în caz contrar. Nu trebuie să raporteze succes până ce resursa nu este complet activă." #~ msgid "stop action actionstopstop" #~ msgstr "stop action actionstopstop" #~ msgid "Return 0 on success and an appropriate error code otherwise. Must not report success until the resource is fully stopped." #~ msgstr "Returnează 0 în caz de succes şi un cod de eroare potrivit în caz contrar. Nu trebuie să raporteze succes până ce resursa nu este complet oprită." #~ msgid "monitor action actionmonitormonitor" #~ msgstr "monitor action actionmonitormonitor" #~ msgid "Exit 0 if the resource is running, 7 if it is stopped, and anything else if it is failed." #~ msgstr "Iese cu 0 dacă resursa rulează, 7 dacă este oprită şi orice altceva dacă a eşuat." #~ msgid "meta-data action actionmeta-datameta-data" #~ msgstr "meta-data action actionmeta-datameta-data" #~ msgid "Provide information about this resource as an XML snippet. Exit with 0." #~ msgstr "Furnizează informaţii despre această resursă ca un extras XML. Iese cu 0." #~ msgid "validate-all action actionvalidate-allvalidate-all" #~ msgstr "validate-all action actionvalidate-allvalidate-all" #~ msgid "Exit with 0 if parameters are valid, 2 if not valid, 6 if resource is not configured." #~ msgstr "Iese cu 0 dacă parametrii sunt valizi, 2 dacă nu sunt valizi, 6 dacă resursa nu este configurată." #~ msgid "promote action actionpromotepromote" #~ msgstr "promote action actionpromotepromote" #~ msgid "Return 0 on success." #~ msgstr "Returnează 0 în caz de succes." #~ msgid "demote action actiondemotedemote" #~ msgstr "demote action actiondemotedemote" #~ msgid "notify action actionnotifynotify" #~ msgstr "notify action actionnotifynotify" #~ msgid "Must not fail. Must exit with 0." #~ msgstr "Nu trebuie să fie eşueze. Trebuie să iasă cu 0" #~ msgid "soft error type error typesoftsoft" #~ msgstr "soft error type error typesoftsoft" #~ msgid "Restart the resource or move it to a new location" #~ msgstr "Reporneşte resursa sau mut-o într-o locaţie nouă" #~ msgid "hard error type error typehardhard" #~ msgstr "hard error type error typehardhard" #~ msgid "Move the resource elsewhere and prevent it from being retried on the current node" #~ msgstr "Mută resursa în altă parte şi previne reîncercarea acesteia pe nodul curent" #~ msgid "fatal error type error typefatalfatal" #~ msgstr "fatal error type error typefatalfatal" #~ msgid "Stop the resource and prevent it from being started on any cluster node" #~ msgstr "Opreşte resursa si împiedică pornirea acesteia pe oricare nod al clusterului" #~ msgid "OCF_SUCCESS Environment VariableOCF_SUCCESS return codeOCF_SUCCESSOCF_SUCCESS" #~ msgstr "OCF_SUCCESS Environment VariableOCF_SUCCESS return codeOCF_SUCCESSOCF_SUCCESS" #~ msgid "Success. The command completed successfully. This is the expected result for all start, stop, promote and demote commands." #~ msgstr "Succes. Comanda a fost rulată cu succes. Acesta este rezultatul aşteptat pentru toate comenzile start, stop, promote şi demote." #~ msgid "soft" #~ msgstr "soft" #~ msgid "return code11" #~ msgstr "return code11" #~ msgid "Generic \"there was a problem\" error code." #~ msgstr "Cod de eroare generic \"a fost o problemă\"" #~ msgid "return code22" #~ msgstr "return code22" #~ msgid "The resource's configuration is not valid on this machine. Eg. refers to a location/tool not found on the node." #~ msgstr "Configuraţia resursei nu este validă pe această maşină. Ex. Face referinţă la o/un locaţie/utilitar care nu a fost găsit/ă pe acest nod." #~ msgid "hard" #~ msgstr "hard" #~ msgid "return code33" #~ msgstr "return code33" #~ msgid "The requested action is not implemented." #~ msgstr "Acţiunea solicitată nu este implementată." #~ msgid "return code44" #~ msgstr "return code44" #~ msgid "The resource agent does not have sufficient privileges to complete the task." #~ msgstr "Agentul de resursă nu are suficiente privilegii pentru a îndeplini sarcina." #~ msgid "return code55" #~ msgstr "return code55" #~ msgid "The tools required by the resource are not installed on this machine." #~ msgstr "Utilitarele necesitate de către resursă nu sunt instalate pe această maşină." #~ msgid "return code66" #~ msgstr "return code66" #~ msgid "The resource's configuration is invalid. Eg. required parameters are missing." #~ msgstr "Configuraţia resursei este invalidă. Ex. Un parametru necesar lipseşte." #~ msgid "fatal" #~ msgstr "fatal" #~ msgid "return code77" #~ msgstr "return code77" #~ msgid "OCF_NOT_RUNNING Environment VariableOCF_NOT_RUNNING return codeOCF_NOT_RUNNINGOCF_NOT_RUNNING" #~ msgstr "OCF_NOT_RUNNING Environment VariableOCF_NOT_RUNNING return codeOCF_NOT_RUNNINGOCF_NOT_RUNNING" #~ msgid "The resource is safely stopped. The cluster will not attempt to stop a resource that returns this for any action." #~ msgstr "Resursa a fost oprită cu succes. Clusterul nu va încerca să oprească o resursă care returnează acest cod pentru orice acţiune." #~ msgid "N/A" #~ msgstr "N/A" #~ msgid "return code88" #~ msgstr "return code88" #~ msgid "The resource is running in Master mode." #~ msgstr "Resursa rulează în modul Master." #~ msgid "return code99" #~ msgstr "return code99" #~ msgid "OCF_FAILED_MASTER Environment VariableOCF_FAILED_MASTER return codeOCF_FAILED_MASTEROCF_FAILED_MASTER" #~ msgstr "OCF_FAILED_MASTER Environment VariableOCF_FAILED_MASTER return codeOCF_FAILED_MASTEROCF_FAILED_MASTER" #~ msgid "The resource is in Master mode but has failed. The resource will be demoted, stopped and then started (and possibly promoted) again." #~ msgstr "Resursa este în modul Master dar a eşuat. Resursa va fi retrogradată, oprită şi apoi pornită (şi posibil promovată) din nou." #~ msgid "other return codes return codeotherother" #~ msgstr "other return codes return codeotherother" #~ msgid "NA" #~ msgstr "NA" #~ msgid "Custom error code." #~ msgstr "Cod de eroare personalizat." #~ msgid "Although counterintuitive, even actions that return 0 (aka. OCF_SUCCESS) can be considered to have failed. This can happen when a resource that is expected to be in the Master state is found running as a Slave, or when a resource is found active on multiple machines." #~ msgstr "Deşi contra intuitiv, chiar şi acţiunile care returnează 0 (aka. OCF_SUCCESS) pot fi considerate că ar fi eşuat. Acest lucru se poate întâmpla când o resursă care este de aşteptat să fie în starea Master este găsită rulând ca Slave sau când o resursă este găsită activă pe mai multe maşini." pacemaker-master/doc/Pacemaker_Explained/ro-RO/Ap-Samples.po000066400000000000000000000323171217637305600242050ustar00rootroot00000000000000msgid "" msgstr "" "Project-Id-Version: Pacemaker 1.1\n" "POT-Creation-Date: 2012-10-17T05:19:01\n" "PO-Revision-Date: 2012-01-01T17:48:32\n" "Last-Translator: Dan Frîncu \n" "Language-Team: None\n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: application/x-publican; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. Tag: title #, no-c-format msgid "Sample Configurations" msgstr "Exemple de Configurare" #. Tag: title #, no-c-format msgid "Empty" msgstr "" #. Tag: title #, no-c-format msgid "An Empty Configuration" msgstr "O Configuraţie Goală" #. Tag: programlisting #, fuzzy, no-c-format msgid "" "<cib admin_epoch=\"0\" epoch=\"0\" num_updates=\"0\" have-quorum=\"false\">\n" " <configuration>\n" " <crm_config/>\n" " <nodes/>\n" " <resources/>\n" " <constraints/>\n" " </configuration>\n" " <status/>\n" "</cib>" msgstr "" "<cib admin_epoch=\"0\" epoch=\"0\" num_updates=\"0\" have-quorum=\"false\">\n" " <configuration>\n" " <crm_config/>\n" " <nodes/>\n" " <resources/>\n" " <constraints/>\n" " </configuration>\n" " <status/>\n" "</cib> " #. Tag: title #, no-c-format msgid "Simple" msgstr "" #. Tag: title #, fuzzy, no-c-format msgid "Simple Configuration - 2 nodes, some cluster options and a resource" msgstr "2 noduri, câteva opţiuni de cluster şi o resursă" #. Tag: programlisting #, fuzzy, no-c-format msgid "" "<cib admin_epoch=\"0\" epoch=\"1\" num_updates=\"0\" have-quorum=\"false\"\n" " validate-with=\"pacemaker-1.0\">\n" " <configuration>\n" " <crm_config>\n" " <nvpair id=\"option-1\" name=\"symmetric-cluster\" value=\"true\"/>\n" " <nvpair id=\"option-2\" name=\"no-quorum-policy\" value=\"stop\"/>\n" " </crm_config>\n" " <op_defaults>\n" " <nvpair id=\"op-default-1\" name=\"timeout\" value=\"30s\"/>\n" " </op_defaults>\n" " <rsc_defaults>\n" " <nvpair id=\"rsc-default-1\" name=\"resource-stickiness\" value=\"100\"/>\n" " <nvpair id=\"rsc-default-2\" name=\"migration-threshold\" value=\"10\"/>\n" " </rsc_defaults>\n" " <nodes>\n" " <node id=\"xxx\" uname=\"c001n01\" type=\"normal\"/>\n" " <node id=\"yyy\" uname=\"c001n02\" type=\"normal\"/>\n" " </nodes>\n" " <resources>\n" " <primitive id=\"myAddr\" class=\"ocf\" provider=\"heartbeat\" type=\"IPaddr\">\n" " <operations>\n" " <op id=\"myAddr-monitor\" name=\"monitor\" interval=\"300s\"/>\n" " </operations>\n" " <instance_attributes>\n" " <nvpair name=\"ip\" value=\"10.0.200.30\"/>\n" " </instance_attributes>\n" " </primitive>\n" " </resources>\n" " <constraints>\n" " <rsc_location id=\"myAddr-prefer\" rsc=\"myAddr\" node=\"c001n01\" score=\"INFINITY\"/>\n" " </constraints>\n" " </configuration>\n" " <status/>\n" "</cib>" msgstr "" "<cib admin_epoch=\"0\" epoch=\"1\" num_updates=\"0\" have-quorum=\"false\"\n" " validate-with=\"pacemaker-1.0\">\n" " <configuration>\n" " <crm_config>\n" " <nvpair id=\"option-1\" name=\"symmetric-cluster\" value=\"true\"/>\n" " <nvpair id=\"option-2\" name=\"no-quorum-policy\" value=\"stop\"/>\n" " </crm_config>\n" " <op_defaults>\n" " <nvpair id=\"op-default-1\" name=\"timeout\" value=\"30s\"/>\n" " </op_defaults>\n" " <rsc_defaults>\n" " <nvpair id=\"rsc-default-1\" name=\"resource-stickiness\" value=\"100\"/>\n" " <nvpair id=\"rsc-default-2\" name=\"migration-threshold\" value=\"10\"/>\n" " </rsc_defaults>\n" " <nodes>\n" " <node id=\"xxx\" uname=\"c001n01\" type=\"normal\"/>\n" " <node id=\"yyy\" uname=\"c001n02\" type=\"normal\"/>\n" " </nodes>\n" " <resources>\n" " <primitive id=\"myAddr\" class=\"ocf\" provider=\"heartbeat\" type=\"IPaddr\">\n" " <operations>\n" " <op id=\"myAddr-monitor\" name=\"monitor\" interval=\"300s\"/>\n" " </operations>\n" " <instance_attributes>\n" " <nvpair name=\"ip\" value=\"10.0.200.30\"/>\n" " </instance_attributes>\n" " </primitive>\n" " </resources>\n" " <constraints>\n" " <rsc_location id=\"myAddr-prefer\" rsc=\"myAddr\" node=\"c001n01\" score=\"INFINITY\"/>\n" " </constraints>\n" " </configuration>\n" " <status/>\n" "</cib> " #. Tag: para #, no-c-format msgid "In this example, we have one resource (an IP address) that we check every five minutes and will run on host c001n01 until either the resource fails 10 times or the host shuts down." msgstr "În acest exemplu, avem o resursă (o adresă IP) pe care o verificăm la fiecare cinci minute şi va rula pe host-ul c001n01 până fie resursa eşuează de 10 ori fie host-ul este închis." #. Tag: title #, fuzzy, no-c-format msgid "Advanced Configuration" msgstr "Exemple de Configurare" #. Tag: title #, fuzzy, no-c-format msgid "Advanced configuration - groups and clones with stonith" msgstr "grupuri şi clone cu stonith" #. Tag: programlisting #, fuzzy, no-c-format msgid "" "<cib admin_epoch=\"0\" epoch=\"1\" num_updates=\"0\" have-quorum=\"false\"\n" " validate-with=\"pacemaker-1.0\">\n" " <configuration>\n" " <crm_config>\n" " <nvpair id=\"option-1\" name=\"symmetric-cluster\" value=\"true\"/>\n" " <nvpair id=\"option-2\" name=\"no-quorum-policy\" value=\"stop\"/>\n" " <nvpair id=\"option-3\" name=\"stonith-enabled\" value=\"true\"/>\n" " </crm_config>\n" " <op_defaults>\n" " <nvpair id=\"op-default-1\" name=\"timeout\" value=\"30s\"/>\n" " </op_defaults>\n" " <rsc_defaults>\n" " <nvpair id=\"rsc-default-1\" name=\"resource-stickiness\" value=\"100\"/>\n" " <nvpair id=\"rsc-default-2\" name=\"migration-threshold\" value=\"10\"/>\n" " </rsc_defaults>\n" " <nodes>\n" " <node id=\"xxx\" uname=\"c001n01\" type=\"normal\"/>\n" " <node id=\"yyy\" uname=\"c001n02\" type=\"normal\"/>\n" " <node id=\"zzz\" uname=\"c001n03\" type=\"normal\"/>\n" " </nodes>\n" " <resources>\n" " <primitive id=\"myAddr\" class=\"ocf\" provider=\"heartbeat\" type=\"IPaddr\">\n" " <operations>\n" " <op id=\"myAddr-monitor\" name=\"monitor\" interval=\"300s\"/>\n" " </operations>\n" " <instance_attributes>\n" " <nvpair name=\"ip\" value=\"10.0.200.30\"/>\n" " </instance_attributes>\n" " </primitive>\n" " <group id=\"myGroup\">\n" " <primitive id=\"database\" class=\"lsb\" type=\"oracle\">\n" " <operations>\n" " <op id=\"database-monitor\" name=\"monitor\" interval=\"300s\"/>\n" " </operations>\n" " </primitive>\n" " <primitive id=\"webserver\" class=\"lsb\" type=\"apache\">\n" " <operations>\n" " <op id=\"webserver-monitor\" name=\"monitor\" interval=\"300s\"/>\n" " </operations>\n" " </primitive>\n" " </group>\n" " <clone id=\"STONITH\">\n" " <meta_attributes id=\"stonith-options\">\n" " <nvpair id=\"stonith-option-1\" name=\"globally-unique\" value=\"false\"/>\n" " </meta_attributes>\n" " <primitive id=\"stonithclone\" class=\"stonith\" type=\"external/ssh\">\n" " <operations>\n" " <op id=\"stonith-op-mon\" name=\"monitor\" interval=\"5s\"/>\n" " </operations>\n" " <instance_attributes id=\"stonith-attrs\">\n" " <nvpair id=\"stonith-attr-1\" name=\"hostlist\" value=\"c001n01,c001n02\"/>\n" " </instance_attributes>\n" " </primitive>\n" " </clone>\n" " </resources>\n" " <constraints>\n" " <rsc_location id=\"myAddr-prefer\" rsc=\"myAddr\" node=\"c001n01\"\n" " score=\"INFINITY\"/>\n" " <rsc_colocation id=\"group-with-ip\" rsc=\"myGroup\" with-rsc=\"myAddr\"\n" " score=\"INFINITY\"/>\n" " </constraints>\n" " </configuration>\n" " <status/>\n" "</cib>" msgstr "" " <cib admin_epoch=\"0\" epoch=\"1\" num_updates=\"0\" have-quorum=\"false\"\n" " validate-with=\"pacemaker-1.0\">\n" " <configuration>\n" " <crm_config>\n" " <nvpair id=\"option-1\" name=\"symmetric-cluster\" value=\"true\"/>\n" " <nvpair id=\"option-2\" name=\"no-quorum-policy\" value=\"stop\"/>\n" " <nvpair id=\"option-3\" name=\"stonith-enabled\" value=\"true\"/>\n" " </crm_config>\n" " <op_defaults>\n" " <nvpair id=\"op-default-1\" name=\"timeout\" value=\"30s\"/>\n" " </op_defaults>\n" " <rsc_defaults>\n" " <nvpair id=\"rsc-default-1\" name=\"resource-stickiness\" value=\"100\"/>\n" " <nvpair id=\"rsc-default-2\" name=\"migration-threshold\" value=\"10\"/>\n" " </rsc_defaults>\n" " <nodes>\n" " <node id=\"xxx\" uname=\"c001n01\" type=\"normal\"/>\n" " <node id=\"yyy\" uname=\"c001n02\" type=\"normal\"/>\n" " <node id=\"zzz\" uname=\"c001n03\" type=\"normal\"/>\n" " </nodes>\n" " <resources>\n" " <primitive id=\"myAddr\" class=\"ocf\" provider=\"heartbeat\" type=\"IPaddr\">\n" " <operations>\n" " <op id=\"myAddr-monitor\" name=\"monitor\" interval=\"300s\"/>\n" " </operations>\n" " <instance_attributes>\n" " <nvpair name=\"ip\" value=\"10.0.200.30\"/>\n" " </instance_attributes>\n" " </primitive>\n" " <group id=\"myGroup\">\n" " <primitive id=\"database\" class=\"lsb\" type=\"oracle\">\n" " <operations>\n" " <op id=\"database-monitor\" name=\"monitor\" interval=\"300s\"/>\n" " </operations>\n" " </primitive>\n" " <primitive id=\"webserver\" class=\"lsb\" type=\"apache\">\n" " <operations>\n" " <op id=\"webserver-monitor\" name=\"monitor\" interval=\"300s\"/>\n" " </operations>\n" " </primitive>\n" " </group>\n" " <clone id=\"STONITH\">\n" " <meta_attributes id=\"stonith-options\">\n" " <nvpair id=\"stonith-option-1\" name=\"globally-unique\" value=\"false\"/>\n" " </meta_attributes>\n" " <primitive id=\"stonithclone\" class=\"stonith\" type=\"external/ssh\">\n" " <operations>\n" " <op id=\"stonith-op-mon\" name=\"monitor\" interval=\"5s\"/>\n" " </operations>\n" " <instance_attributes id=\"stonith-attrs\">\n" " <nvpair id=\"stonith-attr-1\" name=\"hostlist\" value=\"c001n01,c001n02\"/>\n" " </instance_attributes>\n" " </primitive>\n" " </clone>\n" " </resources>\n" " <constraints>\n" " <rsc_location id=\"myAddr-prefer\" rsc=\"myAddr\" node=\"c001n01\"\n" " score=\"INFINITY\"/>\n" " <rsc_colocation id=\"group-with-ip\" rsc=\"myGroup\" with-rsc=\"myAddr\"\n" " score=\"INFINITY\"/>\n" " </constraints>\n" " </configuration>\n" " <status/>\n" "</cib> " #~ msgid "An Empty ConfigurationConfigurationEmptyempty configuration" #~ msgstr "O Configuraţie GoalăConfiguraţieGoală configuraţie goală" #~ msgid "A SimpleConfigurationConfigurationSimpleSimple Configuration" #~ msgstr "O ConfiguraţieSimplăConfiguraţieSimplă configuraţie simplă" #~ msgid "An AdvancedConfigurationConfigurationAdvancedAdvanced Configuration" #~ msgstr "O ConfiguraţieAvansatăConfiguraţieAvansată configuraţie avansată" pacemaker-master/doc/Pacemaker_Explained/ro-RO/Ap-Upgrade-Config.po000066400000000000000000000365311217637305600253750ustar00rootroot00000000000000msgid "" msgstr "" "Project-Id-Version: Pacemaker 1.1\n" "POT-Creation-Date: 2012-10-17T05:19:01\n" "PO-Revision-Date: 2012-01-01T17:48:32\n" "Last-Translator: Dan Frîncu \n" "Language-Team: None\n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: application/x-publican; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. Tag: title #, no-c-format msgid "Upgrading the Configuration from 0.6" msgstr "Actualizarea Configuraţiei de la 0.6" #. Tag: title #, no-c-format msgid "Preparation" msgstr "Pregătire" #. Tag: para #, fuzzy, no-c-format msgid " Upgrading the Configuration ConfigurationUpgrading Upgrading " msgstr "Verificați ValidațiXMLxmllintValidați XML-ulvaliditatea XML-ului:" #. Tag: para #, fuzzy, no-c-format msgid " DownloadDTD DTD DTDDownload Download " msgstr "Verificați ValidațiXMLxmllintValidați XML-ulvaliditatea XML-ului:" #. Tag: para #, no-c-format msgid "Download the latest DTD and ensure your configuration validates." msgstr "" #. Tag: title #, no-c-format msgid "Perform the upgrade" msgstr "Realizaţi actualizarea" #. Tag: title #, no-c-format msgid "Upgrade the software" msgstr "Actualizaţi software-ul" #. Tag: para #, no-c-format msgid "Refer to the appendix: " msgstr "Consultaţi anexa: " #. Tag: title #, no-c-format msgid "Upgrade the Configuration" msgstr "Actualizaţi Configuraţia" #. Tag: para #, no-c-format msgid "As XML is not the friendliest of languages, it is common for cluster administrators to have scripted some of their activities. In such cases, it is likely that those scripts will not work with the new 1.0 syntax." msgstr "Cum XML-ul nu este cel mai prietenos dintre limbaje, este obişnuit pentru administratorii de cluster să fi scriptat unele dintre activităţile acestora. În astfel de cazuri, este probabil ca acele scripturi să nu funcţioneze cu noua sintaxă 1.0." #. Tag: para #, no-c-format msgid "In order to support such environments, it is actually possible to continue using the old 0.6 syntax." msgstr "Pentru a suporta astfel de medii, este chiar posibilă continuarea folosirii sintaxei vechi de 0.6." #. Tag: para #, no-c-format msgid "The downside is, however, that not all the new features will be available and there is a performance impact since the cluster must do a non-persistent configuration upgrade before each transition. So while using the old syntax is possible, it is not advisable to continue using it indefinitely." msgstr "Partea nefastă însă, este că nu toate funcţionalităţile noi vor fi disponibile şi este un impact de performanţă din moment ce clusterul trebuie să execute o actualizare non-persistentă a configuraţiei înainte de fiecare tranziţie. Deci în timp ce folosirea sintaxei vechi este posibilă, nu este recomandată folosirea acesteia pe termen nelimitat." #. Tag: para #, no-c-format msgid "Even if you wish to continue using the old syntax, it is advisable to follow the upgrade procedure to ensure that the cluster is able to use your existing configuration (since it will perform much the same task internally)." msgstr "Chiar dacă doriţi să continuaţi folosirea sintaxei vechi, este recomandat să urmaţi procedura de actualizare pentru a vă asigura că clusterul este capabil să folosească configuraţia existentă (din moment ce va efectua în mare parte aceeaşi sarcină intern)." #. Tag: para #, no-c-format msgid "Create a shadow copy to work with" msgstr "" #. Tag: programlisting #, fuzzy, no-c-format msgid "# crm_shadow --create upgrade06" msgstr "crm_shadow --create upgrade06" #. Tag: para #, fuzzy, no-c-format msgid "Verify the configuration is valid ConfigurationVerify Verify VerifyConfiguration Configuration " msgstr "Verificați că, ConfigurațiaVerificațiVerificațiConfigurațiaconfiguraţia este validă" #. Tag: programlisting #, fuzzy, no-c-format msgid "# crm_verify --live-check" msgstr "crm_verify --live-check" #. Tag: para #, no-c-format msgid "Fix any errors or warnings" msgstr "Reparaţi orice erori sau avertismente" #. Tag: para #, no-c-format msgid "Perform the upgrade:" msgstr "Realizaţi actualizarea" #. Tag: programlisting #, fuzzy, no-c-format msgid "# cibadmin --upgrade" msgstr "cibadmin --upgrade" #. Tag: para #, no-c-format msgid "If this step fails, there are three main possibilities:" msgstr "Dacă acest pas eşuează, sunt trei posibilităţi principale" #. Tag: para #, no-c-format msgid "The configuration was not valid to start with - go back to step 2" msgstr "Configuraţia nu a fost validă de la început - mergeţi înapoi la pasul 2" #. Tag: para #, fuzzy, no-c-format msgid "The transformation failed - report a bug or email the project" msgstr "Transformarea a eşuat - raportaţi un bug sau trimite-ţi un email către proiect la pacemaker@oss.clusterlabs.org" #. Tag: para #, fuzzy, no-c-format msgid "The transformation was successful but produced an invalid result The most common reason is ID values being repeated or invalid. Pacemaker 1.0 is much stricter regarding this type of validation. " msgstr "Transformarea a reuşit dar a produs un rezultat invalid Cel mai comun motiv îl reprezintă valorile ID-ului fiind repetate sau invalide. Pacemaker 1.0 este mult mai strict în privinţa acestui tip de validare. " #. Tag: para #, fuzzy, no-c-format msgid "If the result of the transformation is invalid, you may see a number of errors from the validation library. If these are not helpful, visit http://clusterlabs.org/wiki/Validation_FAQ and/or try the procedure described below under " msgstr "Dacă rezultatul transformării este invalid, se pot observa un număr de erori de la biblioteca de validare. Dacă acestea nu sunt folositoare, vizitaţi şi/sau încercaţi următoarea procedură descrisă mai jos sub ." #. Tag: para #, no-c-format msgid "Check the changes" msgstr "Verificaţi modificările" #. Tag: programlisting #, fuzzy, no-c-format msgid "# crm_shadow --diff" msgstr "crm_shadow --diff" #. Tag: para #, no-c-format msgid "If at this point there is anything about the upgrade that you wish to fine-tune (for example, to change some of the automatic IDs) now is the time to do so. Since the shadow configuration is not in use by the cluster, it is safe to edit the file manually:" msgstr "Dacă la acest punct există orice legat de actualizare ce doriţi să reglaţi fin (de exemplu, să schimbaţi unele din ID-urile automate) acum este momentul să realizaţi acest lucru. Din moment ce configuraţia ascunsă nu este folosită de către cluster, este neprimejdios să editaţi fişierul manual:" #. Tag: programlisting #, fuzzy, no-c-format msgid "# crm_shadow --edit" msgstr "crm_shadow --edit" #. Tag: para #, fuzzy, no-c-format msgid "This will open the configuration in your favorite editor (whichever is specified by the standard $EDITOR environment variable)" msgstr "Va deschide configuraţia în editorul vostru preferat (sau oricare este specificat de variabila standard de mediu EDITOR)" #. Tag: para #, no-c-format msgid "Preview how the cluster will react" msgstr "Previzualizaţi cum va reacţiona clusterul" #. Tag: para #, no-c-format msgid "Test what the cluster will do when you upload the new configuration" msgstr "Testaţi ce va face clusterul când încărcaţi noua configuraţie" #. Tag: programlisting #, fuzzy, no-c-format msgid "" "# crm_simulate --live-check --save-dotfile upgrade06.dot -S\n" "# graphviz upgrade06.dot" msgstr "" "# ptest -VVVVV --live-check --save-dotfile upgrade06.dot\n" "# graphviz upgrade06.dot" #. Tag: para #, fuzzy, no-c-format msgid "Verify that either no resource actions will occur or that you are happy with any that are scheduled. If the output contains actions you do not expect (possibly due to changes to the score calculations), you may need to make further manual changes. See for further details on how to interpret the output of crm_simulate" msgstr "Verificaţi că fie nu vor avea loc acţiuni ale resurelor sau că sunteţi mulţumiţi cu cele care sunt programate. Dacă rezultatul conţine acţiuni pe care nu le aşteptaţi (posibil datorită modificărilor în calculul scorurilor), ar putea fi necesar să realizaţi modificări suplimentare manual. Vedeţi pentru detalii suplimentare despre cum să interpretaţi rezultatul de ieşire al ptest." #. Tag: para #, no-c-format msgid "Upload the changes" msgstr "Încărcaţi modificările" #. Tag: programlisting #, fuzzy, no-c-format msgid "# crm_shadow --commit upgrade06 --force" msgstr "crm_shadow --commit upgrade06 --force" #. Tag: para #, no-c-format msgid "If this step fails, something really strange has occurred. You should report a bug." msgstr "Dacă acest pas eşuează, ceva cu adevărat ciudat s-a întâmplat. Ar trebui să raportaţi bug-ul." #. Tag: title #, no-c-format msgid "Manually Upgrading the Configuration" msgstr "Actualizarea Manuală a Configuraţiei" #. Tag: para #, fuzzy, no-c-format msgid " ConfigurationUpgrade manually Upgrade manually It is also possible to perform the configuration upgrade steps manually. To do this" msgstr "Este de asemenea posibil să efectuaţi ConfigurațieActualizare manualăpaşii de actualizare ai configuraţiei manual. Pentru a realiza acest lucru" #. Tag: para #, fuzzy, no-c-format msgid "Locate the upgrade06.xsl conversion script or download the latest version from Git" msgstr "Localizaţi scriptul de conversie upgrade06.xsl sau descărcaţi cea mai recentă versiune de controlul versiunii" #. Tag: para #, fuzzy, no-c-format msgid "Convert the XML blob: XMLConvert Convert " msgstr "Convertiți XMLConvertițiXML-ul:" #. Tag: programlisting #, no-c-format msgid "# xsltproc /path/to/upgrade06.xsl config06.xml > config10.xml" msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "Locate the pacemaker.rng script." msgstr "Localizaţi scriptul pacemaker.rng." #. Tag: para #, fuzzy, no-c-format msgid "Check the XML validity: Validate Configuration ConfigurationValidate XML Validate XML " msgstr "Verificați ValidațiXMLxmllintValidați XML-ulvaliditatea XML-ului:" #. Tag: programlisting #, fuzzy, no-c-format msgid "# xmllint --relaxng /path/to/pacemaker.rng config10.xml" msgstr "xmllint --relaxng /calea/către/pacemaker.rng config10.xml" #. Tag: para #, no-c-format msgid "The advantage of this method is that it can be performed without the cluster running and any validation errors should be more informative (despite being generated by the same library!) since they include line numbers." msgstr "Avantajul acestei metode este acela că poate fi efectuată fară ca şi clusterul să funcţioneze şi orice erori de validare ar trebui să fie cu caracter mai informativ (în ciuda faptului că sunt generate de aceeaşi bibliotecă!) din moment ce includ numerele liniilor." #~ msgid "Upgrading the Configuration" #~ msgstr "Actualizarea Configuraţiei" #~ msgid "ConfigurationUpgrading" #~ msgstr "ActualizareaConfiguraţiei" #~ msgid "DownloadDTD DTDDownload Download the latest DTD and ensure your configuration validates." #~ msgstr "DescărcaţiDTD DTDDescărcaţi Descărcaţi cel mai recent DTD de la> şi asiguraţi-vă că, configuraţia voastră se validează." #~ msgid "Create a shadow copyexample for upgradingshadow copy to work with" #~ msgstr "Creaţi o copie ascunsăexemplu pentru actualizarecopie ascunsă pe care să lucraţi" #~ msgid "xsltproc /path/to/upgrade06.xsl config06.xml > config10.xml" #~ msgstr "xsltproc /calea/către/upgrade06.xsl config06.xml > config10.xml" pacemaker-master/doc/Pacemaker_Explained/ro-RO/Ap-Upgrade.po000066400000000000000000000403011217637305600241600ustar00rootroot00000000000000msgid "" msgstr "" "Project-Id-Version: Pacemaker 1.1\n" "POT-Creation-Date: 2012-10-17T05:19:01\n" "PO-Revision-Date: 2012-01-01T17:48:32\n" "Last-Translator: Dan Frîncu \n" "Language-Team: None\n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: application/x-publican; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. Tag: title #, no-c-format msgid "Upgrading Cluster Software" msgstr "Actualizarea Soft-ului de Cluster" #. Tag: title #, no-c-format msgid "Version Compatibility" msgstr "Compatibilitatea Versiunii" #. Tag: para #, no-c-format msgid "When releasing newer versions we take care to make sure we are backwards compatible with older versions. While you will always be able to upgrade from version x to x+1, in order to continue to produce high quality software it may occasionally be necessary to drop compatibility with older versions." msgstr "Când lansăm versiuni noi avem grijă că suntem compatibili invers cu versiunile anterioare. În timp ce veţi putea oricând să actualizaţi de la versiunea x la x+1, pentru a putea să continuăm producţia de soft de înaltă calitate ar putea fi necesar în mod ocazional să renunţăm la compatibilitatea cu versiunile mai vechi." #. Tag: para #, no-c-format msgid "There will always be an upgrade path from any series-2 release to any other series-2 release." msgstr "Întotdeauna va exista o cale de actualizare de la oricare produs lansat în seria-2 la oricare alt produs lansat în aceeaşi serie-2." #. Tag: para #, no-c-format msgid "There are three approaches to upgrading your cluster software:" msgstr "Sunt trei alternative în scopul actualizării soft-ului de cluster" #. Tag: para #, no-c-format msgid "Complete Cluster Shutdown" msgstr "Oprirea Completă a Clusterului" #. Tag: para #, no-c-format msgid "Rolling (node by node)" msgstr "Secvenţial (nod după nod)" #. Tag: para #, no-c-format msgid "Disconnect and Reattach" msgstr "Deconectează şi Reataşează" #. Tag: para #, no-c-format msgid "Each method has advantages and disadvantages, some of which are listed in the table below, and you should chose the one most appropriate to your needs." msgstr "Fiecare metodă are avantaje şi dezavantaje, unele dintre acestea sunt listate în tabelul de mai jos şi ar trebui să o alegeţi pe aceea cel mai apropiată de nevoile voastre." #. Tag: title #, no-c-format msgid "Summary of Upgrade Methodologies" msgstr "Sumar al Metodologiilor de Actualizare" #. Tag: entry #, no-c-format msgid "Type" msgstr "Tip" #. Tag: entry #, no-c-format msgid "Available between all software versions" msgstr "Disponibil între toate versiunile de soft" #. Tag: entry #, no-c-format msgid "Service Outage During Upgrade" msgstr "Indisponibilitatea Serviciului pe Durata Actualizării" #. Tag: entry #, no-c-format msgid "Service Recovery During Upgrade" msgstr "Recuperarea Serviciului pe Durata Actualizării" #. Tag: entry #, no-c-format msgid "Exercises Failover Logic/Configuration" msgstr "Exersează Logica/Configuraţia de Failover" #. Tag: entry #, fuzzy, no-c-format msgid "Allows change of cluster stack type ClusterSwitching between Stacks Switching between Stacks Changing Cluster Stack For example, switching from Heartbeat to Corosync. Consult the Heartbeat or Corosync documentation to see if upgrading them to a newer version is also supported. " msgstr "Permite schimbarea tipului de stivă de cluster Stivă de Clustertrecerea de la De exemplu, trecerea de la Heartbeat la Corosync. Consultaţi documentaţia de Heartbeat sau Corosync pentru vedea dacă actualizarea acestora la o versiune mai nouă este de asemenea suportată. " #. Tag: para #, fuzzy, no-c-format msgid "Shutdown UpgradeShutdown Shutdown Shutdown Upgrade " msgstr "ActualizareÎnchidere Închidere pentru Actualizare Închidere" #. Tag: para #, no-c-format msgid "yes" msgstr "da" #. Tag: para #, no-c-format msgid "always" msgstr "întotdeauna" #. Tag: para #, no-c-format msgid "N/A" msgstr "N/A" #. Tag: para #, no-c-format msgid "no" msgstr "nu" #. Tag: para #, fuzzy, no-c-format msgid "Rolling UpgradeRolling Rolling Rolling Upgrade " msgstr "ActualizareSecvenţială Actualizare Secvenţială Secvenţială" #. Tag: para #, fuzzy, no-c-format msgid "Reattach UpgradeReattach Reattach Reattach Upgrade " msgstr "ActualizareReatașare Actualizare cu Reatașare Reatașare" #. Tag: para #, no-c-format msgid "only due to failure" msgstr "doar din cauza eşecului" #. Tag: para #, no-c-format msgid "In this scenario one shuts down all cluster nodes and resources and upgrades all the nodes before restarting the cluster." msgstr "În acest scenariu se închid toate nodurile şi resursele clusterului şi se actualizează toate nodurile înainte de a reporni clusterul." #. Tag: title #, no-c-format msgid "Procedure" msgstr "Procedură" #. Tag: para #, no-c-format msgid "On each node:" msgstr "Pe fiecare nod:" #. Tag: para #, no-c-format msgid "Shutdown the cluster stack (Heartbeat or Corosync)" msgstr "Închideţi stiva de cluster (Heartbeat sau Corosync)" #. Tag: para #, no-c-format msgid "Upgrade the Pacemaker software. This may also include upgrading the cluster stack and/or the underlying operating system." msgstr "Actualizaţi soft-ul Pacemaker. Acest lucru poate include actualizarea stivei de cluster şi/sau a sistemului de operare de bază." #. Tag: para #, fuzzy, no-c-format msgid "Check the configuration manually or with the crm_verify tool if available." msgstr "Verificaţi configuraţia manual sau cu utilitarul crm_verify dacă este disponibil." #. Tag: para #, no-c-format msgid "Start the cluster stack. This can be either Corosync or Heartbeat and does not need to be the same as the previous cluster stack." msgstr "Porniţi stiva de cluster. Aceasta poate fi oricare dintre Corosync sau Heartbeat şi nu trebuie să fie aceeaşi ca stiva anterioară de cluster." #. Tag: para #, no-c-format msgid "In this scenario each node is removed from the cluster, upgraded and then brought back online until all nodes are running the newest version." msgstr "În acest scenariu fiecare nod este scos din cluster, actualizat şi apoi adus înapoi online până ce toate nodurile rulează pe cea mai recentă versiune." #. Tag: para #, no-c-format msgid "This method is currently broken between Pacemaker 0.6.x and 1.0.x." msgstr "Această metodă este în prezent nefuncţională între Pacemaker 0.6.x şi 1.0.x" #. Tag: para #, fuzzy, no-c-format msgid "Measures have been put into place to ensure rolling upgrades always work for versions after 1.0.0. Please try one of the other upgrade strategies. Detach/Reattach is a particularly good option for most people." msgstr "Măsuri au fost implementate pentru a asigura că actualizările secvenţiale vor funcţiona întotdeauna pentru versiunile după 1.0.0. Dacă există o cerere suficientă, munca necesară pentru a repara compatibilitatea între 0.6 -> 1.0 va fi dusă la final. În caz contrar, vă rugăm să încercaţi una din celelalte strategii de actualizare. Detaşare/Reataşare este o opţiune deosebit de bună pentru majoritatea persoanelor." #. Tag: para #, no-c-format msgid "On each node: . Shutdown the cluster stack (Heartbeat or Corosync) . Upgrade the Pacemaker software. This may also include upgrading the cluster stack and/or the underlying operating system. .. On the first node, check the configuration manually or with the crm_verify tool if available. .. Start the cluster stack." msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "+ This must be the same type of cluster stack (Corosync or Heartbeat) that the rest of the cluster is using. Upgrading Corosync/Heartbeat may also be possible, please consult the documentation for those projects to see if the two versions will be compatible." msgstr "Porniţi stiva de cluster. Aceasta trebuie să fie acelaşi tip de stivă de cluster (Corosync sau Heartbeat) care este folosită de către restul clusterului. Actualizarea Corosync/Heartbeat este posibilă de asemenea, vă rugăm să consultaţi documentaţia pentru acele proiecte pentru a vedea dacă cele două versiuni vor fi compatibile." #. Tag: para #, fuzzy, no-c-format msgid "+ .. Repeat for each node in the cluster." msgstr "Repetaţi pentru fiecare nod din cluster" #. Tag: title #, no-c-format msgid "Version Compatibility Table" msgstr "Tabel cu Compatibilitatea Versiunilor" #. Tag: entry #, no-c-format msgid "Version being Installed" msgstr "Versiunea care este Instalată" #. Tag: entry #, no-c-format msgid "Oldest Compatible Version" msgstr "Cea mai Veche Versiune Compatibilă" #. Tag: para #, no-c-format msgid "Pacemaker 1.0.x" msgstr "Pacemaker 1.0.x" #. Tag: para #, no-c-format msgid "Pacemaker 1.0.0" msgstr "Pacemaker 1.0.0" #. Tag: para #, no-c-format msgid "Pacemaker 0.7.x" msgstr "Pacemaker 0.7.x" #. Tag: para #, no-c-format msgid "Pacemaker 0.6 or Heartbeat 2.1.3" msgstr "Pacemaker 0.6 sau Heartbeat 2.1.3" #. Tag: para #, no-c-format msgid "Pacemaker 0.6.x" msgstr "Pacemaker 0.6.x" #. Tag: para #, no-c-format msgid "Heartbeat 2.0.8" msgstr "Heartbeat 2.0.8" #. Tag: para #, no-c-format msgid "Heartbeat 2.1.3 (or less)" msgstr "Heartbeat 2.1.3 (sau mai mică)" #. Tag: para #, no-c-format msgid "Heartbeat 2.0.4" msgstr "Heartbeat 2.0.4" #. Tag: para #, no-c-format msgid "Heartbeat 2.0.4 (or less)" msgstr "Heartbeat 2.0.4 (sau mai mică)" #. Tag: para #, no-c-format msgid "Heartbeat 2.0.0" msgstr "Heartbeat 2.0.0" #. Tag: para #, no-c-format msgid "None. Use an alternate upgrade strategy." msgstr "Niciuna. Folosiţi o strategie de actualizare alternativă." #. Tag: title #, no-c-format msgid "Crossing Compatibility Boundaries" msgstr "Trecerea Graniţelor de Compatibilitate" #. Tag: para #, no-c-format msgid "Rolling upgrades that cross compatibility boundaries must be preformed in multiple steps. For example, to perform a rolling update from Heartbeat 2.0.1 to Pacemaker 0.6.6 one must:" msgstr "Actualizările secvenţiale care trec de graniţele compatibilităţii trebuie efectuate în paşi multipli. De exemplu, pentru a efectua o actualizare secvenţială de la Heartbeat 2.0.1 la Pacemaker 0.6.6 trebuie să:" #. Tag: para #, no-c-format msgid "Perform a rolling upgrade from Heartbeat 2.0.1 to Heartbeat 2.0.4" msgstr "Efectueaze o actualizare secvenţială de la Heartbeat 2.0.1 la Heartbeat 2.0.4" #. Tag: para #, no-c-format msgid "Perform a rolling upgrade from Heartbeat 2.0.4 to Heartbeat 2.1.3" msgstr "Efectueaze o actualizare secvenţială de la Heartbeat 2.0.4 la Heartbeat 2.1.3" #. Tag: para #, no-c-format msgid "Perform a rolling upgrade from Heartbeat 2.1.3 to Pacemaker 0.6.6" msgstr "Efectueaze o actualizare secvenţială de la Heartbeat 2.1.3 la Pacemaker 0.6.6" #. Tag: para #, no-c-format msgid "A variant of a complete cluster shutdown, but the resources are left active and get re-detected when the cluster is restarted." msgstr "O variantă de închidere completă a clusterului, dar resursele sunt lăsate active şi re-detectate când clusterul este repornit." #. Tag: para #, fuzzy, no-c-format msgid "Tell the cluster to stop managing services." msgstr "Permiteţi clusterului să reia gestionarea resurselor" #. Tag: para #, fuzzy, no-c-format msgid "This is required to allow the services to remain active after the cluster shuts down." msgstr "Spune clusterului să se oprească din gestionarea serviciilor. Acest lucru este necesar pentru a permite serviciilor să rămână active după ce clusterul este oprit." #. Tag: programlisting #, fuzzy, no-c-format msgid "# crm_attribute -t crm_config -n is-managed-default -v false" msgstr "crm_attribute -t crm_config -n is-managed-default -v false " #. Tag: para #, no-c-format msgid "For any resource that has a value for is-managed, make sure it is set to false (so that the cluster will not stop it)" msgstr "Pentru orice resursă care are o valoare pentru is-managed, vă rugăm să vă asiguraţi că este setată pe false (astfel încât clusterul să nu o oprească)" #. Tag: programlisting #, fuzzy, no-c-format msgid "# crm_resource -t primitive -r $rsc_id -p is-managed -v false" msgstr "crm_resource -t primitive -r <rsc_id> -p is-managed -v false" #. Tag: para #, no-c-format msgid "Upgrade the cluster stack program - This may also include upgrading the underlying operating system." msgstr "Actualizaţi stiva de cluster - Acest lucru poate include actualizarea sistemului de operare de bază." #. Tag: para #, no-c-format msgid "Start the cluster stack." msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "This can be either Corosync or Heartbeat and does not need to be the same as the previous cluster stack." msgstr "Porniţi stiva de cluster. Aceasta poate fi oricare dintre Corosync sau Heartbeat şi nu trebuie să fie aceeaşi ca stiva anterioară de cluster." #. Tag: para #, no-c-format msgid "Verify that the cluster re-detected all resources correctly." msgstr "Verificaţi că, clusterul a re-detectat toate resursele în mod corect" #. Tag: para #, no-c-format msgid "Allow the cluster to resume managing resources again:" msgstr "Permiteţi clusterului să reia gestionarea resurselor" #. Tag: programlisting #, fuzzy, no-c-format msgid "# crm_attribute -t crm_config -n is-managed-default -v true" msgstr "crm_attribute -t crm_config -n is-managed-default -v true " #. Tag: para #, no-c-format msgid "For any resource that has a value for is-managed reset it to true (so the cluster can recover the service if it fails) if desired:" msgstr "Pentru orice resursă care are o valoare pentru is-managed resetaţi-o, dacă doriţi, pe true (astfel încât clusterul să poată recupera serviciul dacă acesta eşuează)" #. Tag: programlisting #, fuzzy, no-c-format msgid "# crm_resource -t primitive -r $rsc_id -p is-managed -v true" msgstr "crm_resource -t primitive -r <rsc_id> -p is-managed -v false" #. Tag: title #, no-c-format msgid "Notes" msgstr "Menţiuni" #. Tag: para #, no-c-format msgid "Always check your existing configuration is still compatible with the version you are installing before starting the cluster." msgstr "Întotdeauna verificaţi configuraţia existentă şi că este in continuare compatibilă cu versiunea pe care o instalaţi înainte de a porni clusterul." #. Tag: para #, no-c-format msgid "The oldest version of the CRM to support this upgrade type was in Heartbeat 2.0.4" msgstr "Cea mai veche versiune de CRM care suportă acest tip de actualizare a fost Heartbeat 2.0.4" #~ msgid "On the first node, check the configuration manually or with the crm_verify tool if available." #~ msgstr "Pe primul nod, verificaţi configuraţia manual sau cu utilitarul crm_verify dacă este disponibil." #~ msgid "crm_resource -t primitive -r <rsc_id> -p is-managed -v false " #~ msgstr "crm_resource -t primitive -r <rsc_id> -p is-managed -v false " pacemaker-master/doc/Pacemaker_Explained/ro-RO/Author_Group.po000066400000000000000000000036771217637305600246700ustar00rootroot00000000000000msgid "" msgstr "" "Project-Id-Version: Clusters from Scratch 1.1\n" "POT-Creation-Date: 2012-10-17T05:19:01\n" "PO-Revision-Date: 2012-01-01T17:48:32\n" "Last-Translator: Dan Frîncu \n" "Language-Team: None\n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: application/x-publican; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. Tag: firstname #, no-c-format msgid "Andrew" msgstr "Andrew" #. Tag: surname #, no-c-format msgid "Beekhof" msgstr "Beekhof" #. Tag: orgname #, no-c-format msgid "Red Hat" msgstr "Red Hat" #. Tag: contrib #, no-c-format msgid "Primary author" msgstr "" #. Tag: firstname #, no-c-format msgid "Dan" msgstr "Dan" #. Tag: surname #, no-c-format msgid "Frîncu" msgstr "Frîncu" #. Tag: contrib #, no-c-format msgid "Romanian translation" msgstr "Traducerea în limba română" #. Tag: firstname #, no-c-format msgid "Philipp" msgstr "" #. Tag: surname #, no-c-format msgid "Marek" msgstr "" #. Tag: orgname #, no-c-format msgid "LINBit" msgstr "" #. Tag: contrib #, no-c-format msgid "Style and formatting updates. Indexing." msgstr "" #. Tag: firstname #, no-c-format msgid "Tanja" msgstr "" #. Tag: surname #, no-c-format msgid "Roth" msgstr "" #. Tag: orgname #, no-c-format msgid "SUSE" msgstr "" #. Tag: contrib #, no-c-format msgid "Utilization chapter" msgstr "" #. Tag: contrib #, no-c-format msgid "Resource Templates chapter" msgstr "" #. Tag: contrib #, no-c-format msgid "Multi-Site Clusters chapter" msgstr "" #. Tag: firstname #, no-c-format msgid "Lars" msgstr "" #. Tag: surname #, no-c-format msgid "Marowsky-Bree" msgstr "" #. Tag: firstname #, fuzzy, no-c-format msgid "Yan" msgstr "Dan" #. Tag: surname #, no-c-format msgid "Gao" msgstr "" #. Tag: firstname #, no-c-format msgid "Thomas" msgstr "" #. Tag: surname #, no-c-format msgid "Schraitle" msgstr "" #. Tag: firstname #, no-c-format msgid "Dejan" msgstr "" #. Tag: surname #, no-c-format msgid "Muhamedagic" msgstr "" pacemaker-master/doc/Pacemaker_Explained/ro-RO/Book_Info.po000066400000000000000000000052451217637305600241100ustar00rootroot00000000000000msgid "" msgstr "" "Project-Id-Version: Pacemaker 1.1\n" "POT-Creation-Date: 2012-10-17T05:19:01\n" "PO-Revision-Date: 2012-01-01T17:48:32\n" "Last-Translator: Dan Frîncu \n" "Language-Team: None\n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: application/x-publican; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. Tag: title #, no-c-format msgid "Configuration Explained" msgstr "Configuration Explained" #. Tag: subtitle #, no-c-format msgid "An A-Z guide to Pacemaker's Configuration Options" msgstr "Un ghid de la A la Z despre Opţiunile de Configurare ale Pacemaker" #. Tag: productname #, no-c-format msgid "Pacemaker" msgstr "Pacemaker" #. Tag: para #, no-c-format msgid "The purpose of this document is to definitively explain the concepts used to configure Pacemaker. To achieve this, it will focus exclusively on the XML syntax used to configure the CIB." msgstr "Scopul acestui document este de a explica în mod definitiv conceptele folosite pentru a configura Pacemaker. Pentru a reuşi acest lucru în cel mai bun mod, se va concentra în mod exclusiv pe sintaxa XML folosită pentru a configura CIB-ul." #. Tag: para #, fuzzy, no-c-format msgid "For those that are allergic to XML, there exist several unified shells and GUIs for Pacemaker. However these tools will not be covered at all in this document I hope, however, that the concepts explained here make the functionality of these tools more easily understood. , precisely because they hide the XML." msgstr "Pentru aceeia dintre voi care sunt alergici la XML, Pacemaker vine cu un shell de cluster şi un GUI bazat pe Python există, de asemenea, însă aceste utilitare nu vor fi acoperite în vreun fel în acest document Eu sper că, totuși, conceptele explicate aici fac funcţionalitatea acestor utilitare să fie înteleasă mai ușor. , întocmai datorită faptului că acestea ascund XML-ul." #. Tag: para #, fuzzy, no-c-format msgid "Additionally, this document is NOT a step-by-step how-to guide for configuring a specific clustering scenario. Although such guides exist, the purpose of this document is to provide an understanding of the building blocks that can be used to construct any type of Pacemaker cluster. Try the Clusters from Scratch document instead." msgstr "Pe deasupra, acest document NU este un ghid pas-cu-pas pentru configurarea unui scenariu specific de cluster. Deşi astfel de ghiduri există, scopul acestui document este acela de a furniza o înţelegere a elementelor de bază care pot fi folosite pentru a construi orice tip de cluster Pacemaker." pacemaker-master/doc/Pacemaker_Explained/ro-RO/Ch-Advanced-Options.po000066400000000000000000002052371217637305600257340ustar00rootroot00000000000000msgid "" msgstr "" "Project-Id-Version: Pacemaker 1.1\n" "POT-Creation-Date: 2012-10-17T05:19:01\n" "PO-Revision-Date: 2012-01-01T17:48:32\n" "Last-Translator: Dan Frîncu \n" "Language-Team: None\n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: application/x-publican; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. Tag: title #, no-c-format msgid "Advanced Configuration" msgstr "Configuraţii Avansate" #. Tag: title #, no-c-format msgid "Connecting from a Remote Machine" msgstr "Conectarea de pe o Maşină la Distanţă" #. Tag: para #, fuzzy, no-c-format msgid " ClusterRemote connection Remote connection ClusterRemote administration Remote administration " msgstr "multiplicatorOpțiunea Resursei OpțiuneaResurseimultiplicator multiplicator" #. Tag: para #, fuzzy, no-c-format msgid "Provided Pacemaker is installed on a machine, it is possible to connect to the cluster even if the machine itself is not in the same cluster. To do this, one simply sets up a number of environment variables and runs the same commands as when working on a cluster node." msgstr " La distanță conectare La distanță administrare Cu condiţia ca Pacemaker să fie instalat pe o maşină, este posibilă conectarea la cluster chiar dacă maşina în sine nu este parte din el. Pentru a realiza acest lucru, nu trebuie decât să setaţi un număr de variabile de mediu şi să rulaţi aceleaşi comenzi ca şi când aţi lucra pe un nod din cluster." #. Tag: title #, no-c-format msgid "Environment Variables Used to Connect to Remote Instances of the CIB" msgstr "Variabile de Mediu Folosite pentru Conectare la Instanţe la Distanţă ale CIB-ului" #. Tag: entry #, no-c-format msgid "Environment Variable" msgstr "" #. Tag: entry #, no-c-format msgid "Description" msgstr "Descriere" #. Tag: para #, no-c-format msgid "CIB_user" msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "The user to connect as. Needs to be part of the hacluster group on the target host. Defaults to $USER. Environment VariableCIB_user CIB_user " msgstr "Userul sub care se va realiza conectarea. Trebuie să facă parte din grupul hacluster pe gazda destinaţie. Valoarea implicită este $USER." #. Tag: para #, no-c-format msgid "CIB_passwd" msgstr "" #. Tag: para #, no-c-format msgid "The user’s password. Read from the command line if unset. Environment VariableCIB_passwd CIB_passwd " msgstr "" #. Tag: para #, no-c-format msgid "CIB_server" msgstr "" #. Tag: para #, no-c-format msgid "The host to contact. Defaults to localhost. Environment VariableCIB_server CIB_server " msgstr "" #. Tag: para #, no-c-format msgid "CIB_port" msgstr "" #. Tag: para #, no-c-format msgid "The port on which to contact the server; required. Environment VariableCIB_port CIB_port " msgstr "" #. Tag: para #, no-c-format msgid "CIB_encrypted" msgstr "" #. Tag: para #, no-c-format msgid "Encrypt network traffic; defaults to true. Environment VariableCIB_encrypted CIB_encrypted " msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "So, if c001n01 is an active cluster node and is listening on 1234 for connections, and someguy is a member of the hacluster group, then the following would prompt for someguy's password and return the cluster’s current configuration:" msgstr "Deci dacă c001n01 este un nod activ de cluster şi ascultă pentru conexiuni pe 1234, iar someguy este un membru al grupului hacluster. Atunci următoarele ar cere parola lui someguy şi ar returna configuraţia curentă a clusterului:" #. Tag: programlisting #, fuzzy, no-c-format msgid "" "# export CIB_port=1234; export CIB_server=c001n01; export CIB_user=someguy;\n" "# cibadmin -Q" msgstr "" "\n" " export CIB_port=1234; export CIB_server=c001n01; export CIB_user=someguy;\n" " cibadmin -Q " #. Tag: para #, no-c-format msgid "For security reasons, the cluster does not listen for remote connections by default. If you wish to allow remote access, you need to set the remote-tls-port (encrypted) or remote-clear-port (unencrypted) top-level options (ie., those kept in the cib tag, like num_updates and epoch)." msgstr "Din motive de securitate, clusterul nu ascultă pentru conexiuni la distanţă în mod implicit. Dacă doriţi să permiteţi accesul de la distanţă, trebuie să setaţi opţiunile primare remote-tls-port (criptat) sau remote-clear-port (necriptat) (ex. acelea stocate în tag-ul cib, precum num_updates şi epoch)." #. Tag: title #, no-c-format msgid "Extra top-level CIB options for remote access" msgstr "" #. Tag: entry #, no-c-format msgid "Field" msgstr "Câmp" #. Tag: para #, no-c-format msgid "remote-tls-port" msgstr "" #. Tag: para #, no-c-format msgid "Listen for encrypted remote connections on this port. Default: none remote-tls-portRemote Connection Option Remote Connection Option Remote ConnectionOptionremote-tls-port Optionremote-tls-port remote-tls-port " msgstr "" #. Tag: para #, no-c-format msgid "remote-clear-port" msgstr "" #. Tag: para #, no-c-format msgid "Listen for plaintext remote connections on this port. Default: none remote-clear-portRemote Connection Option Remote Connection Option Remote ConnectionOptionremote-clear-port Optionremote-clear-port remote-clear-port " msgstr "" #. Tag: title #, no-c-format msgid "Specifying When Recurring Actions are Performed" msgstr "Specificând Când Acţiunile Recurente sunt Efectuate" #. Tag: para #, no-c-format msgid "By default, recurring actions are scheduled relative to when the resource started. So if your resource was last started at 14:32 and you have a backup set to be performed every 24 hours, then the backup will always run at in the middle of the business day - hardly desirable." msgstr "În mod implicit, acţiunile recurente sunt programate în mod relativ faţă de când a fost pornită resursa. Deci dacă resursa voastră a fost pornită la 14:32 şi aveţi un backup setat să fie executat la fiecare 24 de ore, atunci backup-ul va rula întotdeauna în mijlocul zilei de lucru - deloc de dorit." #. Tag: para #, fuzzy, no-c-format msgid "To specify a date/time that the operation should be relative to, set the operation’s interval-origin. The cluster uses this point to calculate the correct start-delay such that the operation will occur at origin + (interval * N)." msgstr "Pentru a specifica un/o timp/dată faţă de care ar trebui să fie relativă operaţiunea, setaţi interval-origin pentru operaţiune. Clusterul foloseşte acest punct pentru a calcula un start-delay corect astfel încât operaţiunea să se întâmple la origine + (interval * N)." #. Tag: para #, fuzzy, no-c-format msgid "So, if the operation’s interval is 24h, it’s interval-origin is set to 02:00 and it is currently 14:32, then the cluster would initiate the operation with a start delay of 11 hours and 28 minutes. If the resource is moved to another node before 2am, then the operation is of course cancelled." msgstr "Deci dacă intervalul operaţiunii este de 24 de ore, parametrul interval-origin este setat la 02:00 şi acum este 14:32, atunci clusterul va iniţia operaţiunea cu un start-delay de 11 ore şi 28 de minute. Dacă resursa este mutată pe un alt nod înainte de ora 2 dimineaţa, atunci operaţiunea este desigur anulată." #. Tag: para #, no-c-format msgid "The value specified for interval and interval-origin can be any date/time conforming to the ISO8601 standard. By way of example, to specify an operation that would run on the first Monday of 2009 and every Monday after that you would add:" msgstr "Valoarea specificată pentru interval şi interval-origin poate fi orice dată/timp ce se conformează cu standardul ISO8601. Spre exemplu, pentru a specifica o operaţiune care ar rula în prima zi de Luni din 2009 şi în fiecare zi de Luni de atunci înainte aţi adauga:" #. Tag: title #, no-c-format msgid "Specifying a Base for Recurring Action Intervals" msgstr "Specificând o Bază pentru Intervalele Acţiunilor Recurente" #. Tag: programlisting #, fuzzy, no-c-format msgid "<op id=\"my-weekly-action\" name=\"custom-action\" interval=\"P7D\" interval-origin=\"2009-W01-1\"/>" msgstr "<op id=\"my-weekly-action\" name=\"custom-action\" interval=\"P7D\" interval-origin=\"2009-W01-1\"/> " #. Tag: title #, no-c-format msgid "Moving Resources" msgstr "Mutarea Resurselor" #. Tag: para #, fuzzy, no-c-format msgid " MovingResources Resources ResourceMoving Moving " msgstr "atenuareOpțiunea Resursei OpțiuneaResurseiatenuare atenuare" #. Tag: title #, no-c-format msgid "Manual Intervention" msgstr "Intervenţie Manuală" #. Tag: para #, fuzzy, no-c-format msgid "There are primarily two occasions when you would want to move a resource from it’s current location: when the whole node is under maintenance, and when a single resource needs to be moved." msgstr "Sunt în principal două ocazii în care aţi vrea să mutaţi o resursă de pe locaţia ei curentă: când întregul nod este sub mentenanţă şi când o singură resursă trebuie mutată." #. Tag: para #, no-c-format msgid "Since everything eventually comes down to a score, you could create constraints for every resource to prevent them from running on one node. While the configuration can seem convoluted at times, not even we would require this of administrators." msgstr "În cazul în care totul trebuie mutat, din moment ce totul ajunge eventual să ţină de un scor, aţi putea crea restricţii pentru fiecare resursă pe care o aveţi împiedicând-o din a mai rula pe acel nod. În timp ce configuraţia poate părea complicată în anumite momente, nici chiar noi nu am solicita acest lucru de la administratori." #. Tag: para #, fuzzy, no-c-format msgid "Instead one can set a special node attribute which tells the cluster \"don’t let anything run here\". There is even a helpful tool to help query and set it, called crm_standby. To check the standby status of the current machine, simply run:" msgstr "În schimb aţi putea seta un atribut special de nod care îi spune clusterului \"nu lăsa nimic să ruleze aici\". Există chiar şi un utilitar pentru a ajuta la interogarea şi setarea acestuia numit crm_standby. Pentru a verifica status-ul stării de aşteptare pe maşina curentă, pur şi simplu rulaţi:" #. Tag: programlisting #, fuzzy, no-c-format msgid "# crm_standby --get-value" msgstr "crm_standby --get-value" #. Tag: para #, no-c-format msgid "A value of true indicates that the node is NOT able to host any resources, while a value of false says that it CAN." msgstr "O valoarea de true indică faptul că nodul NU poate găzdui nici un fel de resurse, în timp ce o valoare de false spune că acesta POATE." #. Tag: para #, fuzzy, no-c-format msgid "You can also check the status of other nodes in the cluster by specifying the --node-uname option:" msgstr "Puteţi să verificaţi de asemenea status-ul celorlalte noduri din cluster specificând opţiunea --node-uname:" #. Tag: programlisting #, fuzzy, no-c-format msgid "# crm_standby --get-value --node-uname sles-2" msgstr "crm_standby --get-value --node-uname sles-2" #. Tag: para #, fuzzy, no-c-format msgid "To change the current node’s standby status, use --attr-value instead of --get-value." msgstr "Pentru a schimba status-ul stării de aşteptare a nodului curent, folosiţi --attr-value în loc de --get-value." #. Tag: programlisting #, fuzzy, no-c-format msgid "# crm_standby --attr-value" msgstr "crm_standby --attr-value" #. Tag: para #, fuzzy, no-c-format msgid "Again, you can change another host’s value by supplying a host name with --node-uname." msgstr "Din nou, puteţi schimba valoarea altei gazde prin furnizarea unui hostname cu --node-uname." #. Tag: para #, fuzzy, no-c-format msgid "When only one resource is required to move, we do this by creating location constraints. However, once again we provide a user friendly shortcut as part of the crm_resource command, which creates and modifies the extra constraints for you. If Email was running on sles-1 and you wanted it moved to a specific location, the command would look something like:" msgstr "Când doar o resursă este necesar a fi mutată, realizăm acest lucru prin crearea de restricţii de locaţie. În schimb încă o dată furnizăm utilizatorului o scurtătură prietenoasă ca parte din comanda crm_resource care creează şi modifică restricţiile suplimentare pentru voi. Dacă Email rula pe sles-1 şi doreaţi mutarea acesteia pe o locaţie specifică, comanda ar arăta ceva de genul:" #. Tag: programlisting #, fuzzy, no-c-format msgid "# crm_resource -M -r Email -H sles-2" msgstr "crm_resource -M -r Email -H sles-2" #. Tag: para #, no-c-format msgid "Behind the scenes, the tool will create the following location constraint:" msgstr "În culise, utilitarul va crea următoarea restricţie de locaţie:" #. Tag: programlisting #, fuzzy, no-c-format msgid "<rsc_location rsc=\"Email\" node=\"sles-2\" score=\"INFINITY\"/>" msgstr "<rsc_location rsc=\"Email\" node=\"sles-2\" score=\"INFINITY\"/> " #. Tag: para #, fuzzy, no-c-format msgid "It is important to note that subsequent invocations of crm_resource -M are not cumulative. So, if you ran these commands" msgstr "Este important de menţionat că invocări ulterioare ale crm_resource -M nu sunt cumulative. Deci dacă aţi rula:" #. Tag: programlisting #, fuzzy, no-c-format msgid "" "# crm_resource -M -r Email -H sles-2\n" "# crm_resource -M -r Email -H sles-3" msgstr "" "crm_resource -M -r Email -H sles-2\n" " crm_resource -M -r Email -H sles-3" #. Tag: para #, no-c-format msgid "then it is as if you had never performed the first command." msgstr "atunci ar fi ca şi când nu aţi fi efectuat niciodată prima comandă." #. Tag: para #, no-c-format msgid "To allow the resource to move back again, use:" msgstr "Pentru a permite resursei să se mute înapoi, folosiţi:" #. Tag: programlisting #, fuzzy, no-c-format msgid "# crm_resource -U -r Email" msgstr "crm_resource -U -r Email" #. Tag: para #, fuzzy, no-c-format msgid "Note the use of the word allow. The resource can move back to its original location but, depending on resource-stickiness, it might stay where it is. To be absolutely certain that it moves back to sles-1, move it there before issuing the call to crm_resource -U:" msgstr "Luaţi aminte de folosirea cuvântului allow. Resursa se poate muta înapoi la locaţia originală a acesteia însă, în funcţie de resource-stickiness, ar putea să rămână acolo unde este. Pentru a fi absolut siguri că se mută înapoi pe sles-1, mutaţi-o acolo înainte de a apela crm_resource -U:" #. Tag: programlisting #, fuzzy, no-c-format msgid "" "# crm_resource -M -r Email -H sles-1\n" "# crm_resource -U -r Email" msgstr "" "crm_resource -M -r Email -H sles-1\n" " crm_resource -U -r Email" #. Tag: para #, no-c-format msgid "Alternatively, if you only care that the resource should be moved from its current location, try" msgstr "Ca alternativă, dacă vă pasă doar că resursa ar trebui să fie mutată din locaţia ei curentă, încercaţi" #. Tag: programlisting #, fuzzy, no-c-format msgid "# crm_resource -M -r Email`" msgstr "crm_resource -M -r Email" #. Tag: para #, no-c-format msgid "Which will instead create a negative constraint, like" msgstr "Care va crea în schimb o restricţie negativă, precum" #. Tag: programlisting #, no-c-format msgid "<rsc_location rsc=\"Email\" node=\"sles-1\" score=\"-INFINITY\"/>" msgstr "<rsc_location rsc=\"Email\" node=\"sles-1\" score=\"-INFINITY\"/>" #. Tag: para #, fuzzy, no-c-format msgid "This will achieve the desired effect, but will also have long-term consequences. As the tool will warn you, the creation of a -INFINITY constraint will prevent the resource from running on that node until crm_resource -U is used. This includes the situation where every other cluster node is no longer available!" msgstr "Acest lucru va atinge efectul scontat dar va avea consecinţe pe termen lung. Aşa cum utilitarul vă va avertiza de altfel, crearea unei restricţii cu -INFINITY va împiedica resursa de a mai rula pe acel nod până ce comanda crm_resource -U va fi folosită. Acesta include situaţia în care oricare alt nod din cluster nu mai este disponibil!" #. Tag: para #, no-c-format msgid "In some cases, such as when resource-stickiness is set to INFINITY, it is possible that you will end up with the problem described in . The tool can detect some of these cases and deals with them by also creating both a positive and negative constraint. Eg." msgstr "În anumite cazuri, precum cel în care resource-stickiness este setată la INFINITY, este posibil să ajungeţi la problema descrisă în . Utilitarul poate detecta unele din aceste cazuri şi le tratează prin crearea atât de restricţii pozitive cât şi negative. Ex." #. Tag: para #, no-c-format msgid "Email prefers sles-1 with a score of -INFINITY" msgstr "Email preferă sles-1 cu un scor de -INFINITY" #. Tag: para #, no-c-format msgid "Email prefers sles-2 with a score of INFINITY" msgstr "Email preferă sles-2 cu un scor de INFINITY" #. Tag: para #, no-c-format msgid "which has the same long-term consequences as discussed earlier." msgstr "care are aceleaşi consecinţe pe termen lung precum am discutat anterior." #. Tag: title #, no-c-format msgid "Moving Resources Due to Failure" msgstr "Mutarea Resurselor Datorită Eşecului" #. Tag: para #, fuzzy, no-c-format msgid "New in 1.0 is the concept of a migration threshold. The naming of this option was perhaps unfortunate as it is easily confused with true migration, the process of moving a resource from one node to another without stopping it. Xen virtual guests are the most common example of resources that can be migrated in this manner. " msgstr "Nou în 1.0 este conceptul unui prag de migrare Denumirea acestei opţiuni este nefericită deoarece este uşor confundată cu migrarea adevărată, procesul mutării unei resurse de pe un nod pe altul fără oprirea acesteia. Oaspeţii virtuali de Xen sunt cel mai comun exemplu de resurse care pot fi migrate în această manieră. . Pur şi simplu definiţi migration-threshold=N pentru o resursă şi aceasta va migra pe un nod nou după N eşecuri. Nu este definit nici un prag în mod implicit. Pentru a determina status-ul de eşec şi limitele curente ale resursei, folosiţi crm_mon --failcounts" #. Tag: para #, no-c-format msgid "Simply define migration-threshold=N for a resource and it will migrate to a new node after N failures. There is no threshold defined by default. To determine the resource’s current failure status and limits, use crm_mon --failcounts." msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "By default, once the threshold has been reached, this node will no longer be allowed to run the failed resource until the administrator manually resets the resource’s failcount using crm_failcount (after hopefully first fixing the failure’s cause). However it is possible to expire them by setting the resource’s failure-timeout option." msgstr "În mod implicit, odată ce pragul a fost atins, nodului nu îi va mai fi permisă rularea resursei care a eşuat până ce un administrator resetează manual failcount-ul resursei folosind crm_failcount (asta sperând după ce cauza eşecului resursei a fost reparată). Totodată este posibilă expirarea acestora prin setarea opţiunii failure-timeout resursei." #. Tag: para #, no-c-format msgid "So a setting of migration-threshold=2 and failure-timeout=60s would cause the resource to move to a new node after 2 failures, and allow it to move back (depending on the stickiness and constraint scores) after one minute." msgstr "Prin urmare setarea migration-threshold=2 şi failure-timeout=60s ar conduce resursa la mutarea pe un nod nou după 2 eşecuri şi potenţial îi va permite să se mute înapoi (în funcţie de scorurile de adezivitate şi restrictie) după un minut." #. Tag: para #, no-c-format msgid "There are two exceptions to the migration threshold concept; they occur when a resource either fails to start or fails to stop. Start failures cause the failcount to be set to INFINITY and thus always cause the resource to move immediately." msgstr "Sunt două excepţii la conceptul de prag de migrare şi se întâmplă atunci când o resursă fie eşuează să pornească sau eşuează să se oprească. Eşecurile de pornire fac failcount-ul să fie setat la INFINITY şi prin urmare provoacă mutarea imediată a resursei." #. Tag: para #, no-c-format msgid "Stop failures are slightly different and crucial. If a resource fails to stop and STONITH is enabled, then the cluster will fence the node in order to be able to start the resource elsewhere. If STONITH is not enabled, then the cluster has no way to continue and will not try to start the resource elsewhere, but will try to stop it again after the failure timeout." msgstr "Eşecurile la oprire sunt puţin diferite şi cruciale. Dacă o resursă eşuează de a se opri şi STONITH este activat, atunci clusterul va evacua nodul pentru a putea să pornească resursa în altă parte. Dacă STONITH nu este activat, atunci clusterul nu are nici o mod de a continua şi nu va încerca să pornească resursa în altă parte, dar va încerca să o oprească din nou după ce se depaşeşte timpul limită al eşecului." #. Tag: para #, no-c-format msgid "Please read before enabling this option." msgstr "Vă rugăm să citiţi înainte de activarea acestei opţiuni." #. Tag: title #, no-c-format msgid "Moving Resources Due to Connectivity Changes" msgstr "Mutarea Resurselor Din Cauza Schimbărilor de Conectivitate" #. Tag: para #, no-c-format msgid "Setting up the cluster to move resources when external connectivity is lost is a two-step process." msgstr "Setarea clusterului pentru a muta resursele când conectivitatea externă este pierdută, este un proces în doi paşi." #. Tag: title #, no-c-format msgid "Tell Pacemaker to monitor connectivity" msgstr "Spuneţi Pacemaker-ului să monitorizeze conectivitatea" #. Tag: para #, fuzzy, no-c-format msgid "To do this, you need to add a ping resource to the cluster. The ping resource uses the system utility of the same name to a test if list of machines (specified by DNS hostname or IPv4/IPv6 address) are reachable and uses the results to maintain a node attribute normally called pingd. The attribute name is customizable; that allows multiple ping groups to be defined. " msgstr "Pentru a realiza acest lucru, trebuie să adăugaţi o resursă ping la cluster. Resursa ping foloseşte utilitarul de sistem cu acelaşi nume pentru a testa dacă o listă de maşini (specificată după numele DNS sau adresa IPV4/IPV6) sunt accesibile şi foloseşte rezultatele pentru a menţine un atribut de nod numit în mod normal pingd Numele atributului este personalizabil ceea ce vă permite definirea de grupuri multiple de ping . " #. Tag: para #, fuzzy, no-c-format msgid "Older versions of Heartbeat required users to add ping nodes to ha.cf - this is no longer required." msgstr "Versiuni mai vechi de Heartbeat necesitau ca utilizatorii să adauge noduri de ping în ha.cf - acest lucru nu mai este necesar." #. Tag: para #, no-c-format msgid "Older versions of Pacemaker used a custom binary called pingd for this functionality; this is now deprecated in favor of ping." msgstr "" #. Tag: para #, no-c-format msgid "If your version of Pacemaker does not contain the ping agent, you can download the latest version from https://github.com/ClusterLabs/pacemaker/tree/master/extra/resources/ping" msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "Normally the resource will run on all cluster nodes, which means that you’ll need to create a clone. A template for this can be found below along with a description of the most interesting parameters." msgstr "În mod normal resursa va rula pe toate nodurile clusterului, ceea ce înseamnă că va trebui să creaţi o clonă. Un template pentru aceasta poate fi găsit mai jos împreună cu o descriere ale parametrilor cei mai interesanţi." #. Tag: title #, fuzzy, no-c-format msgid "Common Options for a ping Resource" msgstr "Opţiuni Obişnuite pentru o Resursă 'ping'" #. Tag: para #, no-c-format msgid "dampen" msgstr "" #. Tag: para #, no-c-format msgid "The time to wait (dampening) for further changes to occur. Use this to prevent a resource from bouncing around the cluster when cluster nodes notice the loss of connectivity at slightly different times. dampenPing Resource Option Ping Resource Option Ping ResourceOptiondampen Optiondampen dampen " msgstr "" #. Tag: para #, no-c-format msgid "multiplier" msgstr "" #. Tag: para #, no-c-format msgid "The number of connected ping nodes gets multiplied by this value to get a score. Useful when there are multiple ping nodes configured. multiplierPing Resource Option Ping Resource Option Ping ResourceOptionmultiplier Optionmultiplier multiplier " msgstr "" #. Tag: para #, no-c-format msgid "host_list" msgstr "" #. Tag: para #, no-c-format msgid "The machines to contact in order to determine the current connectivity status. Allowed values include resolvable DNS host names, IPv4 and IPv6 addresses. host_listPing Resource Option Ping Resource Option Ping ResourceOptionhost_list Optionhost_list host_list " msgstr "" #. Tag: title #, fuzzy, no-c-format msgid "An example ping cluster resource that checks node connectivity once every minute" msgstr "Un exemplu de resursă ping în cluster, verifică odată pe minut conectivatea nodului" #. Tag: programlisting #, fuzzy, no-c-format msgid "" "<clone id=\"Connected\">\n" " <primitive id=\"ping\" provider=\"pacemaker\" class=\"ocf\" type=\"ping\">\n" " <instance_attributes id=\"ping-attrs\">\n" " <nvpair id=\"pingd-dampen\" name=\"dampen\" value=\"5s\"/>\n" " <nvpair id=\"pingd-multiplier\" name=\"multiplier\" value=\"1000\"/>\n" " <nvpair id=\"pingd-hosts\" name=\"host_list\" value=\"my.gateway.com www.bigcorp.com\"/>\n" " </instance_attributes>\n" " <operations>\n" " <op id=\"ping-monitor-60s\" interval=\"60s\" name=\"monitor\"/>\n" " </operations>\n" " </primitive>\n" "</clone>" msgstr "" " <clone id=\"Connected\">\n" " <primitive id=\"ping\" provider=\"pacemaker\" class=\"ocf\" type=\"ping\">\n" " <instance_attributes id=\"ping-attrs\">\n" " <nvpair id=\"pingd-dampen\" name=\"dampen\" value=\"5s\"/>\n" " <nvpair id=\"pingd-multiplier\" name=\"multiplier\" value=\"1000\"/>\n" " <nvpair id=\"pingd-hosts\" name=\"host_list\" value=\"my.gateway.com www.bigcorp.com\"/>\n" " </instance_attributes>\n" " <operations>\n" " <op id=\"ping-monitor-60s\" interval=\"60s\" name=\"monitor\"/>\n" " </operations>\n" " </primitive>\n" " </clone> " #. Tag: para #, fuzzy, no-c-format msgid "You’re only half done. The next section deals with telling Pacemaker how to deal with the connectivity status that ocf:pacemaker:ping is recording." msgstr "Aţi terminat doar jumătate. Secţiunea următoare se ocupă cu informarea Pacemaker-ului despre cum să se comporte cu status-ul conectivităţii pe care ocf:pacemaker:ping îl înregistrează." #. Tag: title #, no-c-format msgid "Tell Pacemaker how to interpret the connectivity data" msgstr "Spuneţi Pacemaker-ului cum să interpreteze datele de conectivitate" #. Tag: para #, fuzzy, no-c-format msgid "Before reading the following, please make sure you have read and understood above." msgstr "NOTĂ: Înainte de a citi următoarele, vă rugăm să vă asiguraţi că aţi citit şi aţi înteles de mai sus." #. Tag: para #, fuzzy, no-c-format msgid "There are a number of ways to use the connectivity data provided by Heartbeat. The most common setup is for people to have a single ping node, to prevent the cluster from running a resource on any unconnected node." msgstr "Sunt un număr de feluri în care se pot folosi datele de conectivitate furnizate de Heartbeat. Cel mai întâlnit setup este ca oamenii să aibe un singur nod de ping şi să împiedice clusterul de a rula o resursă pe orice nod neconectat. TODO: este ideea că doar nodurile care pot ajunge ex. routerul ar trebui să aibe resurse active?" #. Tag: title #, fuzzy, no-c-format msgid "Don’t run on unconnected nodes" msgstr "Nu rula pe noduri neconectate" #. Tag: programlisting #, fuzzy, no-c-format msgid "" "<rsc_location id=\"WebServer-no-connectivity\" rsc=\"Webserver\">\n" " <rule id=\"ping-exclude-rule\" score=\"-INFINITY\" >\n" " <expression id=\"ping-exclude\" attribute=\"pingd\" operation=\"not_defined\"/>\n" " </rule>\n" "</rsc_location>" msgstr "" " <rsc_location id=\"WebServer-no-connectivity\" rsc=\"Webserver\">\n" " <rule id=\"ping-exclude-rule\" score=\"-INFINITY\" >\n" " <expression id=\"ping-exclude\" attribute=\"pingd\" operation=\"not_defined\"/>\n" " </rule>\n" " </rsc_location> " #. Tag: para #, no-c-format msgid "A more complex setup is to have a number of ping nodes configured. You can require the cluster to only run resources on nodes that can connect to all (or a minimum subset) of them." msgstr "Un setup mai complex este acela de a avea un număr de noduri de ping configurate. Poţi solicita clusterului să ruleze resursele pe nodurile care se pot conecta la toate (sau doar un subset din) acestea" #. Tag: title #, fuzzy, no-c-format msgid "Run only on nodes connected to three or more ping nodes; this assumes multiplier is set to 1000:" msgstr "Rulează doar pe noduri conectate la 3 sau mai multe noduri de ping (presupune că multiplier este setat la 1000)" #. Tag: programlisting #, fuzzy, no-c-format msgid "" "<rsc_location id=\"WebServer-connectivity\" rsc=\"Webserver\">\n" " <rule id=\"ping-prefer-rule\" score=\"-INFINITY\" >\n" " <expression id=\"ping-prefer\" attribute=\"pingd\" operation=\"lt\" value=\"3000\"/>\n" " </rule>\n" "</rsc_location>" msgstr "" " <rsc_location id=\"WebServer-connectivity\" rsc=\"Webserver\">\n" " <rule id=\"ping-prefer-rule\" score=\"-INFINITY\" >\n" " <expression id=\"ping-prefer\" attribute=\"pingd\" operation=\"lt\" value=\"3000\"/>\n" " </rule>\n" " </rsc_location> " #. Tag: para #, fuzzy, no-c-format msgid "Instead you can tell the cluster only to prefer nodes with the best connectivity. Just be sure to set multiplier to a value higher than that of resource-stickiness (and don’t set either of them to INFINITY)." msgstr "sau în schimb puteţi spune clusterului să prefere doar nodurile cu cea mai mare conectivitate. Doar să vă asiguraţi să setaţi multiplicatorul la o valoare mai mare decât cea a resource-stickiness (şi să nu setaţi oricare dintre acestea la INFINITY)." #. Tag: title #, no-c-format msgid "Prefer the node with the most connected ping nodes" msgstr "Preferă nodul cu cele mai multe noduri de ping conectate" #. Tag: programlisting #, fuzzy, no-c-format msgid "" "<rsc_location id=\"WebServer-connectivity\" rsc=\"Webserver\">\n" " <rule id=\"ping-prefer-rule\" score-attribute=\"pingd\" >\n" " <expression id=\"ping-prefer\" attribute=\"pingd\" operation=\"defined\"/>\n" " </rule>\n" "</rsc_location>" msgstr "" " <rsc_location id=\"WebServer-connectivity\" rsc=\"Webserver\">\n" " <rule id=\"ping-prefer-rule\" score-attribute=\"pingd\" >\n" " <expression id=\"ping-prefer\" attribute=\"pingd\" operation=\"defined\"/>\n" " </rule>\n" " </rsc_location> " #. Tag: para #, no-c-format msgid "It is perhaps easier to think of this in terms of the simple constraints that the cluster translates it into. For example, if sles-1 is connected to all 5 ping nodes but sles-2 is only connected to 2, then it would be as if you instead had the following constraints in your configuration:" msgstr "Este probabil mai simplu să vă gândiţi la acest lucru în termenii simplelor restricţii în care clusterul traduce acest lucru. De exemplu, dacă sles-1 este conectat la toate cele 5 noduri de ping dar sles-2 este conectat doar la 2, atunci ar fi la fel ca şi când aţi avea următoarele restricţii în configuraţia voastră:" #. Tag: title #, no-c-format msgid "How the cluster translates the pingd constraint" msgstr "Cum traduce clusterul restricţia pingd" #. Tag: programlisting #, fuzzy, no-c-format msgid "" "<rsc_location id=\"ping-1\" rsc=\"Webserver\" node=\"sles-1\" score=\"5000\"/>\n" "<rsc_location id=\"ping-2\" rsc=\"Webserver\" node=\"sles-2\" score=\"2000\"/>" msgstr "" " <rsc_location id=\"ping-1\" rsc=\"Webserver\" node=\"sles-1\" score=\"5000\"/>\n" " <rsc_location id=\"ping-2\" rsc=\"Webserver\" node=\"sles-2\" score=\"2000\"/> " #. Tag: para #, fuzzy, no-c-format msgid "The advantage is that you don’t have to manually update any constraints whenever your network connectivity changes." msgstr "Avantajul fiind că nu mai trebuie să le actualizaţi manual de fiecare dată când conectivitatea de reţea se schimbă." #. Tag: para #, no-c-format msgid "You can also combine the concepts above into something even more complex. The example below shows how you can prefer the node with the most connected ping nodes provided they have connectivity to at least three (again assuming that multiplier is set to 1000)." msgstr "Puteţi de asemenea să combinaţi conceptele de mai sus în ceva chiar mai complex de atât. Exemplul de mai jos arată cum puteţi prefera nodul cu cele mai multe noduri de ping conectate cu cerinţa că acestea trebuie să aibe conectivitate la minim trei (presupunând că multiplicatorul este setat la 1000)." #. Tag: title #, no-c-format msgid "A more complex example of choosing a location based on connectivity" msgstr "Un exemplu mai complex pentru alegerea locaţiei pe baza conectivităţii" #. Tag: programlisting #, fuzzy, no-c-format msgid "" "<rsc_location id=\"WebServer-connectivity\" rsc=\"Webserver\">\n" " <rule id=\"ping-exclude-rule\" score=\"-INFINITY\" >\n" " <expression id=\"ping-exclude\" attribute=\"pingd\" operation=\"lt\" value=\"3000\"/>\n" " </rule>\n" " <rule id=\"ping-prefer-rule\" score-attribute=\"pingd\" >\n" " <expression id=\"ping-prefer\" attribute=\"pingd\" operation=\"defined\"/>\n" " </rule>\n" "</rsc_location>" msgstr "" " <rsc_location id=\"WebServer-connectivity\" rsc=\"Webserver\">\n" " <rule id=\"ping-exclude-rule\" score=\"-INFINITY\" >\n" " <expression id=\"ping-exclude\" attribute=\"pingd\" operation=\"lt\" value=\"3000\"/>\n" " </rule>\n" " <rule id=\"ping-prefer-rule\" score-attribute=\"pingd\" >\n" " <expression id=\"ping-prefer\" attribute=\"pingd\" operation=\"defined\"/>\n" " </rule>\n" " </rsc_location> " #. Tag: title #, no-c-format msgid "Resource Migration" msgstr "Migrarea Resurselor" #. Tag: para #, no-c-format msgid "Some resources, such as Xen virtual guests, are able to move to another location without loss of state. We call this resource migration; this is different from the normal practice of stopping the resource on the first machine and starting it elsewhere." msgstr "Unele resurse, precum oaspeţii virtuali de Xen, sunt capabili să se mute în altă locaţie fără pierderea stării. Numim acest lucru migrarea resurselor şi este diferit de practica normală a opririi resurselor pe prima maşină şi apoi pornirea acestora în altă parte." #. Tag: para #, fuzzy, no-c-format msgid "Not all resources are able to migrate, see the Migration Checklist below, and those that can, won’t do so in all situations. Conceptually there are two requirements from which the other prerequisites follow:" msgstr "Nu toate resursele sunt capabile de migrare, vedeţi Lista de Migrare de mai jos, şi mai sunt cele care nu pot să facă acest lucru în toate situaţiile. În mod conceptual sunt două cerinţe din care celelalte necesităţi urmează:" #. Tag: para #, no-c-format msgid "the resource must be active and healthy at the old location" msgstr "resursa trebuie să fie activă şi sănătoasă în locaţia veche" #. Tag: para #, no-c-format msgid "everything required for the resource to run must be available on both the old and new locations" msgstr "tot ce este necesar pentru ca resursa să funcţioneze trebuie să fie disponibil atât la vechea cât şi la noua locaţie" #. Tag: para #, no-c-format msgid "The cluster is able to accommodate both push and pull migration models by requiring the resource agent to support two new actions: migrate_to (performed on the current location) and migrate_from (performed on the destination)." msgstr "Clusterul este capabil să acomodeze atât modele de migrare de tip push cât şi pull prin solicitarea ca agentul de resursă să suporte două noi acţiuni: migrate_to (efectuată pe locaţia curentă) şi migrate_from (efectuată pe destinaţie)." #. Tag: para #, no-c-format msgid "In push migration, the process on the current location transfers the resource to the new location where is it later activated. In this scenario, most of the work would be done in the migrate_to action and, if anything, the activation would occur during migrate_from." msgstr "În migrarea de tip push, procesul de pe locaţia curentă se transferă pe locaţia nouă unde este activat mai târziu. În acest scenariu, majoritatea muncii ar fi realizată în acţiunea migrate_to şi activarea ar avea loc în timpul migrate_from." #. Tag: para #, no-c-format msgid "Conversely for pull, the migrate_to action is practically empty and migrate_from does most of the work, extracting the relevant resource state from the old location and activating it." msgstr "În egală măsură pentru pull, acţiunea migrate_to este practic fără conţinut şi migrate_from realizează majoritatea muncii, extrăgând starea relevantă a resursei de la locaţia veche şi activând-o." #. Tag: para #, no-c-format msgid "There is no wrong or right way to implement migration for your service, as long as it works." msgstr "Nu există un mod greşit sau corect de a implementa migrarea serviciului vostru, atâta timp cât funcţionează." #. Tag: title #, no-c-format msgid "Migration Checklist" msgstr "Lista de Migrare" #. Tag: para #, no-c-format msgid "The resource may not be a clone." msgstr "Resursa nu poate fi o clonă." #. Tag: para #, no-c-format msgid "The resource must use an OCF style agent." msgstr "Resursa trebuie să folosească un agent de stilul OCF." #. Tag: para #, no-c-format msgid "The resource must not be in a failed or degraded state." msgstr "Resursa nu trebuie să fie într-o stare degradată sau să fi eşuat." #. Tag: para #, fuzzy, no-c-format msgid "The resource must not, directly or indirectly, depend on any primitive or group resources." msgstr "Resursa trebuie să nu depindă, în mod direct sau indirect, de orice primitivă sau grup de resurse." #. Tag: para #, no-c-format msgid "The resource must support two new actions: migrate_to and migrate_from, and advertise them in its metadata." msgstr "Resursa trebuie să suporte două noi acţiuni: migrate_to şi migrate_from şi trebuie să le anunţe în meta-informaţiile proprii." #. Tag: para #, no-c-format msgid "The resource must have the allow-migrate meta-attribute set to true (which is not the default)." msgstr "Resursa trebuie să aibe meta-atributul allow-migrate setat pe true (nu pe valoarea implicită)" #. Tag: para #, no-c-format msgid "If the resource depends on a clone, and at the time the resource needs to be move, the clone has instances that are stopping and instances that are starting, then the resource will be moved in the traditional manner. The Policy Engine is not yet able to model this situation correctly and so takes the safe (yet less optimal) path." msgstr "Dacă resursa depinde de o clonă, iar la momentul când resursa trebuie să fie mutată, clona are instanţe care se opresc şi instanţe care pornesc, atunci resursa va fi mutată în modul tradiţional. Policy Engine-ul nu este capabil încă să modeleze această situaţie în mod corect aşa că ia calea (mai puţin optimă) dar mai sigură." #. Tag: title #, no-c-format msgid "Reusing Rules, Options and Sets of Operations" msgstr "Refolosirea Regulilor, Opţiunilor şi a Setului de Operaţiuni" #. Tag: para #, no-c-format msgid "Sometimes a number of constraints need to use the same set of rules, and resources need to set the same options and parameters. To simplify this situation, you can refer to an existing object using an id-ref instead of an id." msgstr "Câteodată un număr de restricţii trebuie să folosească acelaşi set de reguli şi resursele trebuie sa seteze aceleaşi opţiuni şi parametri. Pentru a simplifica această situaţie, puteţi face referinţă la un obiect existent folosind un id-ref în loc de un id." #. Tag: para #, no-c-format msgid "So if for one resource you have" msgstr "Deci dacă pentru o resursă aveţi" #. Tag: para #, fuzzy, no-c-format msgid "Then instead of duplicating the rule for all your other resources, you can instead specify:" msgstr "Atunci în loc să duplicaţi regula pentru toate celelalte resurse, puteţi specifica în schimb" #. Tag: title #, no-c-format msgid "Referencing rules from other constraints" msgstr "Realizând referinţe către reguli din alte restricţii" #. Tag: programlisting #, fuzzy, no-c-format msgid "" "<rsc_location id=\"WebDB-connectivity\" rsc=\"WebDB\">\n" " <rule id-ref=\"ping-prefer-rule\"/>\n" "</rsc_location>" msgstr "" " <rsc_location id=\"WebDB-connectivity\" rsc=\"WebDB\">\n" " <rule id-ref=\"ping-prefer-rule\"/>\n" " </rsc_location> " #. Tag: para #, no-c-format msgid "The cluster will insist that the rule exists somewhere. Attempting to add a reference to a non-existing rule will cause a validation failure, as will attempting to remove a rule that is referenced elsewhere." msgstr "Clusterul va insista că regula există undeva. Încercând să adaugaţi o referinţă către o regulă ce nu există va cauza un eşec al validării, la fel ca şi încercarea de a înlătura regula care este referenţiată în altă parte." #. Tag: para #, fuzzy, no-c-format msgid "The same principle applies for meta_attributes and instance_attributes as illustrated in the example below:" msgstr "Acelaşi principiu se aplică pentru meta_attributes şi pentru instance_attributes după cum este prezentat în exemplul de mai jos" #. Tag: title #, no-c-format msgid "Referencing attributes, options, and operations from other resources" msgstr "Referenţierea atributelor, opţiunilor şi operaţiunilor din alte resurse" #. Tag: programlisting #, fuzzy, no-c-format msgid "" "<primitive id=\"mySpecialRsc\" class=\"ocf\" type=\"Special\" provider=\"me\">\n" " <instance_attributes id=\"mySpecialRsc-attrs\" score=\"1\" >\n" " <nvpair id=\"default-interface\" name=\"interface\" value=\"eth0\"/>\n" " <nvpair id=\"default-port\" name=\"port\" value=\"9999\"/>\n" " </instance_attributes>\n" " <meta_attributes id=\"mySpecialRsc-options\">\n" " <nvpair id=\"failure-timeout\" name=\"failure-timeout\" value=\"5m\"/>\n" " <nvpair id=\"migration-threshold\" name=\"migration-threshold\" value=\"1\"/>\n" " <nvpair id=\"stickiness\" name=\"resource-stickiness\" value=\"0\"/>\n" " </meta_attributes>\n" " <operations id=\"health-checks\">\n" " <op id=\"health-check\" name=\"monitor\" interval=\"60s\"/>\n" " <op id=\"health-check\" name=\"monitor\" interval=\"30min\"/>\n" " </operations>\n" "</primitive>\n" "<primitive id=\"myOtherlRsc\" class=\"ocf\" type=\"Other\" provider=\"me\">\n" " <instance_attributes id-ref=\"mySpecialRsc-attrs\"/>\n" " <meta_attributes id-ref=\"mySpecialRsc-options\"/>\n" " <operations id-ref=\"health-checks\"/>\n" "</primitive>" msgstr "" " <primitive id=\"mySpecialRsc\" class=\"ocf\" type=\"Special\" provider=\"me\">\n" " <instance_attributes id=\"mySpecialRsc-attrs\" score=\"1\" >\n" " <nvpair id=\"default-interface\" name=\"interface\" value=\"eth0\"/>\n" " <nvpair id=\"default-port\" name=\"port\" value=\"9999\"/>\n" " </instance_attributes>\n" " <meta_attributes id=\"mySpecialRsc-options\">\n" " <nvpair id=\"failure-timeout\" name=\"failure-timeout\" value=\"5m\"/>\n" " <nvpair id=\"migration-threshold\" name=\"migration-threshold\" value=\"1\"/>\n" " <nvpair id=\"stickiness\" name=\"resource-stickiness\" value=\"0\"/>\n" " </meta_attributes>\n" " <operations id=\"health-checks\">\n" " <op id=\"health-check\" name=\"monitor\" interval=\"60s\"/>\n" " <op id=\"health-check\" name=\"monitor\" interval=\"30min\"/>\n" " </operations>\n" " </primitive>\n" " <primitive id=\"myOtherlRsc\" class=\"ocf\" type=\"Other\" provider=\"me\">\n" " <instance_attributes id-ref=\"mySpecialRsc-attrs\"/>\n" " <meta_attributes id-ref=\"mySpecialRsc-options\"/>\n" " <operations id-ref=\"health-checks\"/>\n" " </primitive> " #. Tag: title #, no-c-format msgid "Reloading Services After a Definition Change" msgstr "Reîncărcarea Serviciilor După Schimbarea unei Definiţii" #. Tag: para #, no-c-format msgid "The cluster automatically detects changes to the definition of services it manages. However, the normal response is to stop the service (using the old definition) and start it again (with the new definition). This works well, but some services are smarter and can be told to use a new set of options without restarting." msgstr "Clusterul detectează în mod automat schimbări ale definiţiei serviciilor pe care le gestionează. Totuşi, răspunsul normal este să oprească serviciul (folosind definiţia veche) şi să îl pornească din nou (cu definiţia nouă). Acest lucru functionează bine, dar unele servicii sunt inteligente şi li se poate spune să folosească un set nou de opţiuni fară să repornească." #. Tag: para #, no-c-format msgid "To take advantage of this capability, your resource agent must:" msgstr "Pentru a profita de această capabilitate, agentul vostru de resursă trebuie să:" #. Tag: para #, fuzzy, no-c-format msgid "Accept the reload operation and perform any required actions. The steps required here depend completely on your application!" msgstr "Accepte operaţiunea reload şi să efectueze orice acţiuni necesare. Pașii necesari aici depind complet de aplicația voastră!" #. Tag: title #, fuzzy, no-c-format msgid "The DRBD Agent’s Control logic for Supporting the reload Operation" msgstr "Logica de Control pentru Suportarea Operaţiunii de reload a Agentului DRBD" #. Tag: programlisting #, fuzzy, no-c-format msgid "" "case $1 in\n" " start)\n" " drbd_start\n" " ;;\n" " stop)\n" " drbd_stop\n" " ;;\n" " reload)\n" " drbd_reload\n" " ;;\n" " monitor)\n" " drbd_monitor\n" " ;;\n" " *)\n" " drbd_usage\n" " exit $OCF_ERR_UNIMPLEMENTED\n" " ;;\n" "esac\n" "exit $?" msgstr "" " case $1 in\n" " start)\n" " drbd_start\n" " ;;\n" " stop)\n" " drbd_stop\n" " ;;\n" " reload)\n" " drbd_reload\n" " ;;\n" " monitor)\n" " drbd_monitor\n" " ;;\n" " *) \n" " drbd_usage\n" " exit $OCF_ERR_UNIMPLEMENTED\n" " ;;\n" " esac\n" " exit $? " #. Tag: para #, no-c-format msgid "Advertise the reload operation in the actions section of its metadata" msgstr "Anunţă operaţiunea reload în secţiunea de actions din meta-informaţiile proprii" #. Tag: title #, no-c-format msgid "The DRBD Agent Advertising Support for the reload Operation" msgstr "Anunţarea Suportului Operaţiunii de reload a Agentului DRBD" #. Tag: programlisting #, fuzzy, no-c-format msgid "" "<?xml version=\"1.0\"?>\n" " <!DOCTYPE resource-agent SYSTEM \"ra-api-1.dtd\">\n" " <resource-agent name=\"drbd\">\n" " <version>1.1</version>\n" "\n" " <longdesc>\n" " Master/Slave OCF Resource Agent for DRBD\n" " </longdesc>\n" "\n" " ...\n" "\n" " <actions>\n" " <action name=\"start\" timeout=\"240\" />\n" " <action name=\"reload\" timeout=\"240\" />\n" " <action name=\"promote\" timeout=\"90\" />\n" " <action name=\"demote\" timeout=\"90\" />\n" " <action name=\"notify\" timeout=\"90\" />\n" " <action name=\"stop\" timeout=\"100\" />\n" " <action name=\"meta-data\" timeout=\"5\" />\n" " <action name=\"validate-all\" timeout=\"30\" />\n" " </actions>\n" " </resource-agent>" msgstr "" " <?xml version=\"1.0\"?>\n" " <!DOCTYPE resource-agent SYSTEM \"ra-api-1.dtd\">\n" " <resource-agent name=\"drbd\">\n" " <version>1.1</version>\n" " \n" " <longdesc lang=\"en\">\n" " Master/Slave OCF Resource Agent for DRBD\n" " </longdesc>\n" " \n" " ...\n" " \n" " <actions>\n" " <action name=\"start\" timeout=\"240\" />\n" " <action name=\"reload\" timeout=\"240\" />\n" " <action name=\"promote\" timeout=\"90\" />\n" " <action name=\"demote\" timeout=\"90\" />\n" " <action name=\"notify\" timeout=\"90\" />\n" " <action name=\"stop\" timeout=\"100\" />\n" " <action name=\"meta-data\" timeout=\"5\" />\n" " <action name=\"validate-all\" timeout=\"30\" />\n" " </actions>\n" " </resource-agent> " #. Tag: para #, no-c-format msgid "Advertise one or more parameters that can take effect using reload." msgstr "Promovaţi unul sau mai mulţi parametri care pot intra în vigoare folosing reload." #. Tag: para #, no-c-format msgid "Any parameter with the unique set to 0 is eligible to be used in this way." msgstr "Orice parametru cu unique setat pe 0 este eligibil să fie folosit în acest fel." #. Tag: title #, no-c-format msgid "Parameter that can be changed using reload" msgstr "Parametru care poate fi schimbat folosind reload" #. Tag: programlisting #, fuzzy, no-c-format msgid "" "<parameter name=\"drbdconf\" unique=\"0\">\n" " <longdesc>Full path to the drbd.conf file.</longdesc>\n" " <shortdesc>Path to drbd.conf</shortdesc>\n" " <content type=\"string\" default=\"${OCF_RESKEY_drbdconf_default}\"/>\n" "</parameter>" msgstr "" " <parameter name=\"drbdconf\" unique=\"0\">\n" " <longdesc lang=\"en\">Full path to the drbd.conf file.</longdesc>\n" " <shortdesc lang=\"en\">Path to drbd.conf</shortdesc>\n" " <content type=\"string\" default=\"${OCF_RESKEY_drbdconf_default}\"/>\n" " </parameter> " #. Tag: para #, no-c-format msgid "Once these requirements are satisfied, the cluster will automatically know to reload the resource (instead of restarting) when a non-unique fields changes." msgstr "Odată ce aceste cerinţe au fost satisfăcute, clusterul automat va şti să reîncarce, în loc să restarteze, resursa când un câmp non-unic se schimbă." #. Tag: para #, no-c-format msgid "The metadata is re-read when the resource is started. This may mean that the resource will be restarted the first time, even though you changed a parameter with unique=0" msgstr "Meta-informaţiile sunt recitite când resursa este pornită. Acest lucru înseamnă că resursa va fi restartată prima data, deşi aţi schimbat un parametru cu unique=0" #. Tag: para #, no-c-format msgid "If both a unique and non-unique field are changed simultaneously, the resource will still be restarted." msgstr "Dacă atât un câmp unic si non-unic sunt schimbate simultan, resursa tot va fi restartată." #~ msgid "Environment VariableRemote Administration Environment Variable" #~ msgstr "Variabilă de MediuAdministrare la Distanță Variabilă de Mediu" #~ msgid "CIB_*, Env. Var. for Remote Conn.user Environment VariableCIB_user CIB_user" #~ msgstr "CIB_*, Env. Var. for Remote Conn.user Environment VariableCIB_user CIB_user" #~ msgid "CIB_*, Env. Var. for Remote Conn.passwd Environment VariableCIB_passwd CIB_passwd" #~ msgstr "CIB_*, Env. Var. pentru Conexiuni la Distanțăpasswd Variabilă de MediuCIB_passwd CIB_passwd" #~ msgid "The user's password. Read from the command line if unset." #~ msgstr "Parola utilizatorului. Este citită de la linia de comandă dacă nu este setată" #~ msgid "CIB_*, Env. Var. for Remote Conn.server Environment VariableCIB_server CIB_server" #~ msgstr "CIB_*, Env. Var. pentru Conexiuni la Distanțăserver Variabilă de MediuCIB_server CIB_server" #~ msgid "The host to contact. Defaults to localhost." #~ msgstr "Gazda care să fie contactată. Valoarea implicită este localhost." #~ msgid "CIB_*, Env. Var. for Remote Conn.port Environment VariableCIB_port CIB_port" #~ msgstr "CIB_*, Env. Var. pentru Conexiuni la Distanțăport Variabilă de MediuCIB_port CIB_port" #~ msgid "The port on which to contact the server; required." #~ msgstr "Portul pe care să contacteze serverul. Cerinţă obligatorie." #~ msgid "CIB_*, Env. Var. for Remote Conn.encrypted Environment VariableCIB_encrypted CIB_encrypted" #~ msgstr "CIB_*, Env. Var. pentru Conexiuni la Distanțăencrtpted Variabilă de MediuCIB_encrypted CIB_encrypted" #~ msgid "Encrypt network traffic; defaults to true." #~ msgstr "Criptează traficul de reţea. Valoarea implicită este true." #~ msgid "Remoteconnect, CIB options Extra top-level CIB options for remote access" #~ msgstr "La distanțăconectare, opțiuni CIB Opțiuni primare suplimentare pentru accesul la distanță" #~ msgid "remote-tls-port remote-tls-port" #~ msgstr "remote-tls-port remote-tls-port" #~ msgid "Listen for encrypted remote connections on this port. Default: none" #~ msgstr "Ascultă pentru conexiuni de la distanţă criptate pe acest port. Valoarea implicită: none" #~ msgid "remote-clear-port remote-clear-port" #~ msgstr "remote-clear-port remote-clear-port" #~ msgid "Listen for plaintext remote connections on this port. Default: none" #~ msgstr "Ascultă pentru conexiuni de la distanţă în clar pe acest port. Valoarea implicită: none" #~ msgid "Moving Resources" #~ msgstr "Mutarea Resurselor" #~ msgid "ResourceMoving" #~ msgstr "MutareaResurselor" #~ msgid "Older versions of Pacemaker used a custom binary called pingd for this functionality; this is now deprecated in favor of ping. If your version of Pacemaker does not contain the ping agent, you can download the latest version." #~ msgstr "Versiuni mai vechi de Pacemaker foloseau un binar special numit pingd pentru această funcţionalitate; acest lucru este acum depreciat în favoarea comenzii ping. Dacă versiunea voastră de Pacemaker nu conţine agentul ping, puteţi descărca cea mai recentă versiune de la ." #~ msgid "The time to wait (dampening) for further changes to occur. Use this to prevent a resource from bouncing around the cluster when cluster nodes notice the loss of connectivity at slightly different times." #~ msgstr "Timpul pe care să îl aştepte (atenuarea) pentru alte modificări să se întâmple. Folosiţi acesta pentru a preveni o resursă de a ricoşa de colo-colo prin cluster atunci când nodurile observă pierderea conectivităţii la intervale uşor diferite de timp." #~ msgid "The number of connected ping nodes gets multiplied by this value to get a score. Useful when there are multiple ping nodes configured." #~ msgstr "Numărul cu care să se multiplice numărul de noduri ping conectate. Folositor când sunt mai multe noduri ping configurate." #~ msgid "host_listResource Option ResourceOptionhost_list host_list" #~ msgstr "host_listOpțiunea Resursei OpțiuneaResurseihost_list host_list" #~ msgid "The machines to contact in order to determine the current connectivity status. Allowed values include resolvable DNS host names, IPv4 and IPv6 addresses." #~ msgstr "Maşinile pe care să le contacteze pentru a determina status-ul curent de conectivitate. Valorile permise includ hostname-uri DNS rezolvabile, adrese IPV4 şi IPV6." pacemaker-master/doc/Pacemaker_Explained/ro-RO/Ch-Advanced-Resources.po000066400000000000000000003425101217637305600262470ustar00rootroot00000000000000msgid "" msgstr "" "Project-Id-Version: Pacemaker 1.1\n" "POT-Creation-Date: 2012-10-17T05:19:01\n" "PO-Revision-Date: 2012-01-01T17:48:32\n" "Last-Translator: Dan Frîncu \n" "Language-Team: None\n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: application/x-publican; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. Tag: title #, no-c-format msgid "Advanced Resource Types" msgstr "Tipuri Avansate de Resurse" #. Tag: title #, no-c-format msgid "Groups - A Syntactic Shortcut" msgstr "" #. Tag: para #, fuzzy, no-c-format msgid " Group Resources ResourcesGroups Groups " msgstr "Grup de Resurse ResurseGrupuri Grupuri - A Scurtătură Sintactică" #. Tag: para #, no-c-format msgid "One of the most common elements of a cluster is a set of resources that need to be located together, start sequentially, and stop in the reverse order. To simplify this configuration we support the concept of groups." msgstr "Unul dintre cele mai comune elemente ale unui cluster este un set de resurse care trebuie plasate împreună, pornesc secvenţial şi se opres în ordine inversă. Pentru a simplifica această configuraţie suportăm conceptul de grupuri." #. Tag: title #, no-c-format msgid "An example group" msgstr "Un exemplu de grup" #. Tag: programlisting #, fuzzy, no-c-format msgid "" "<group id=\"shortcut\">\n" " <primitive id=\"Public-IP\" class=\"ocf\" type=\"IPaddr\" provider=\"heartbeat\">\n" " <instance_attributes id=\"params-public-ip\">\n" " <nvpair id=\"public-ip-addr\" name=\"ip\" value=\"1.2.3.4\"/>\n" " </instance_attributes>\n" " </primitive>\n" " <primitive id=\"Email\" class=\"lsb\" type=\"exim\"/>\n" " </group>" msgstr "" " <group id=\"shortcut\">\n" " <primitive id=\"Public-IP\" class=\"ocf\" type=\"IPaddr\" provider=\"heartbeat\">\n" " <instance_attributes id=\"params-public-ip\">\n" " <nvpair id=\"public-ip-addr\" name=\"ip\" value=\"1.2.3.4\"/>\n" " </instance_attributes>\n" " </primitive>\n" " <primitive id=\"Email\" class=\"lsb\" type=\"exim\"/>\n" " </group> " #. Tag: para #, no-c-format msgid "Although the example above contains only two resources, there is no limit to the number of resources a group can contain. The example is also sufficient to explain the fundamental properties of a group:" msgstr "Deşi exemplul de mai sus conţine doar două resurse, nu este nici o limită asupra numărului de resurse pe care le poate conţine un grup. Exemplul este de asemenea suficient pentru a explica proprietăţile fundamentale ale unui grup:" #. Tag: para #, no-c-format msgid "Resources are started in the order they appear in (Public-IP first, then Email)" msgstr "Resursele sunt pornite în ordinea în care apar (întâi Public-IP, apoi Email)" #. Tag: para #, no-c-format msgid "Resources are stopped in the reverse order to which they appear in (Email first, then Public-IP)" msgstr "Resursele sunt oprite în ordine inversă faţă de cea în care apar (întâi Email, apoi Public-IP)" #. Tag: para #, fuzzy, no-c-format msgid "If a resource in the group can’t run anywhere, then nothing after that is allowed to run, too." msgstr "Dacă o resursă din grup nu poate rula nicăieri, atunci nimic din ce urmează după aceasta nu îi este permis să ruleze" #. Tag: para #, fuzzy, no-c-format msgid "If Public-IP can’t run anywhere, neither can Email;" msgstr "Dacă Public-IP nu poate rula nicăieri, nici Email nu va putea;" #. Tag: para #, fuzzy, no-c-format msgid "but if Email can’t run anywhere, this does not affect Public-IP in any way" msgstr "dar dacă Email nu poate rula nicăieri, acest lucru nu afectează Public-IP în nici un fel" #. Tag: para #, no-c-format msgid "The group above is logically equivalent to writing:" msgstr "Grupul de deasupra este echivalent logic cu a scrie:" #. Tag: title #, no-c-format msgid "How the cluster sees a group resource" msgstr "Cum vede clusterul un grup de resurse" #. Tag: programlisting #, fuzzy, no-c-format msgid "" "<configuration>\n" " <resources>\n" " <primitive id=\"Public-IP\" class=\"ocf\" type=\"IPaddr\" provider=\"heartbeat\">\n" " <instance_attributes id=\"params-public-ip\">\n" " <nvpair id=\"public-ip-addr\" name=\"ip\" value=\"1.2.3.4\"/>\n" " </instance_attributes>\n" " </primitive>\n" " <primitive id=\"Email\" class=\"lsb\" type=\"exim\"/>\n" " </resources>\n" " <constraints>\n" " <rsc_colocation id=\"xxx\" rsc=\"Email\" with-rsc=\"Public-IP\" score=\"INFINITY\"/>\n" " <rsc_order id=\"yyy\" first=\"Public-IP\" then=\"Email\"/>\n" " </constraints>\n" "</configuration>" msgstr "" " <configuration>\n" " <resources>\n" " <primitive id=\"Public-IP\" class=\"ocf\" type=\"IPaddr\" provider=\"heartbeat\">\n" " <instance_attributes id=\"params-public-ip\">\n" " <nvpair id=\"public-ip-addr\" name=\"ip\" value=\"1.2.3.4\"/>\n" " </instance_attributes>\n" " </primitive>\n" " <primitive id=\"Email\" class=\"lsb\" type=\"exim\"/>\n" " </resources>\n" " <constraints>\n" " <rsc_colocation id=\"xxx\" rsc=\"Email\" with-rsc=\"Public-IP\" score=\"INFINITY\"/>\n" " <rsc_order id=\"yyy\" first=\"Public-IP\" then=\"Email\"/>\n" " </constraints>\n" " </configuration> " #. Tag: para #, no-c-format msgid "Obviously as the group grows bigger, the reduced configuration effort can become significant." msgstr "În mod evident pe măsură ce grupul creşte, efortul de configurare redus poate deveni semnificativ." #. Tag: para #, no-c-format msgid "Another (typical) example of a group is a DRBD volume, the filesystem mount, an IP address, and an application that uses them." msgstr "Un alt exemplu (tipi) al unui grup este un volum DBRD, un mount de sistem de fișiere, o adresă IP și o aplicație care le folosește." #. Tag: title #, fuzzy, no-c-format msgid "Group Properties" msgstr "Proprietăţi" #. Tag: title #, no-c-format msgid "Properties of a Group Resource" msgstr "Proprietăţile unui Grup de Resurse" #. Tag: entry #, no-c-format msgid "Field" msgstr "Câmp" #. Tag: entry #, no-c-format msgid "Description" msgstr "Descriere" #. Tag: para #, fuzzy, no-c-format msgid "id" msgstr "Resursele Active:" #. Tag: para #, fuzzy, no-c-format msgid "Your name for the group idGroup Resource Property Group Resource Property ResourceGroup Propertyid Group Propertyid id " msgstr "idProprietatea unei Resurse de Grup Proprietățile unei Resurse de Grupid ResursăProprietate de Grupid id" #. Tag: title #, fuzzy, no-c-format msgid "Group Options" msgstr "Opţiuni" #. Tag: para #, fuzzy, no-c-format msgid "Options inherited from primitive resources: priority, target-role, is-managed" msgstr "Opţiuni moştenite de la resurse simple: priority, target-role, is-managed" #. Tag: title #, fuzzy, no-c-format msgid "Group Instance Attributes" msgstr "Atributele Instanţelor" #. Tag: para #, fuzzy, no-c-format msgid "Groups have no instance attributes, however any that are set here will be inherited by the group’s children." msgstr "Grupurile nu au atribute de instanţă, totuşi oricare ar fi setate aici vor fi moştenite de către copiii grupului." #. Tag: title #, fuzzy, no-c-format msgid "Group Contents" msgstr "Conţinut" #. Tag: para #, fuzzy, no-c-format msgid "Groups may only contain a collection of cluster resources. To refer to the child of a group resource, just use the child’s id instead of the group’s." msgstr "Grupurile pot conţine numai o colecţie de resurse de cluster de tip primitive. Pentru a face referinţă la copilul unei resurse dintr-un grup, folosiţi pur şi simplu id-ul copilului în locul celui al grupului." #. Tag: title #, fuzzy, no-c-format msgid "Group Constraints" msgstr "Restricţii" #. Tag: para #, fuzzy, no-c-format msgid "Although it is possible to reference the group’s children in constraints, it is usually preferable to use the group’s name instead." msgstr "Deşi este posibil să referenţiezi copiii grupului în restricţii, este în mod uzual preferabil să folosiţi numele grupului în schimb." #. Tag: title #, no-c-format msgid "Example constraints involving groups" msgstr "Exemple de restricţii care implică grupuri" #. Tag: programlisting #, fuzzy, no-c-format msgid "" "<constraints>\n" " <rsc_location id=\"group-prefers-node1\" rsc=\"shortcut\" node=\"node1\" score=\"500\"/>\n" " <rsc_colocation id=\"webserver-with-group\" rsc=\"Webserver\" with-rsc=\"shortcut\"/>\n" " <rsc_order id=\"start-group-then-webserver\" first=\"Webserver\" then=\"shortcut\"/>\n" "</constraints>" msgstr "" " <constraints>\n" " <rsc_location id=\"group-prefers-node1\" rsc=\"shortcut\" node=\"node1\" score=\"500\"/>\n" " <rsc_colocation id=\"webserver-with-group\" rsc=\"Webserver\" with-rsc=\"shortcut\"/>\n" " <rsc_order id=\"start-group-then-webserver\" first=\"Webserver\" then=\"shortcut\"/>\n" " </constraints> " #. Tag: title #, fuzzy, no-c-format msgid "Group Stickiness" msgstr "Adezivitate" #. Tag: para #, fuzzy, no-c-format msgid " resource-stickinessGroups Groups " msgstr "resource-stickinessa unei Resurse de Grup Adezivitatea" #. Tag: para #, fuzzy, no-c-format msgid "Stickiness, the measure of how much a resource wants to stay where it is, is additive in groups. Every active resource of the group will contribute its stickiness value to the group’s total. So if the default resource-stickiness is 100, and a group has seven members, five of which are active, then the group as a whole will prefer its current location with a score of 500." msgstr "Adezivitatea, măsura a cât de mult vrea o resursă să rămână acolo unde este, este aditivă în grupuri. Fiecare membru activ al grupului va contribui cu valoarea adezivităţii acestuia la totalul grupului. Deci dacă valoarea implicită a resource-stickiness este 100 şi grupul are şapte membri, cinci din aceştia fiind activi, atunci grupul ca întreg va prefera locaţia curentă cu un scor de 500." #. Tag: title #, no-c-format msgid "Clones - Resources That Get Active on Multiple Hosts" msgstr "" #. Tag: para #, fuzzy, no-c-format msgid " Clone Resources ResourcesClones Clones " msgstr "Resursele Clonă ResurseleClone Clonele - Resursele Care Devin Active pe mai Multe Gazde" #. Tag: para #, fuzzy, no-c-format msgid "Clones were initially conceived as a convenient way to start N instances of an IP resource and have them distributed throughout the cluster for load balancing. They have turned out to quite useful for a number of purposes including integrating with Red Hat’s DLM, the fencing subsystem, and OCFS2." msgstr "Clonele au fost concepute iniţial ca o modalitate convenientă de a porni N instanţe ale unei resurse IP şi de a le avea distribuite de-a lungul clusterului pentru partajarea nivelului de încărcare. S-au dovedit a fi chiar utile pentru un număr de scopuri incluzând integrarea cu DLM-ul de la Red Hat, subsistemul de evacuare şi OCFS2." #. Tag: para #, no-c-format msgid "You can clone any resource, provided the resource agent supports it." msgstr "Puteţi clona orice resursă atâta timp cât agentul de resursă suportă acest lucru." #. Tag: para #, no-c-format msgid "Three types of cloned resources exist:" msgstr "Există trei tipuri de resurse clonate." #. Tag: para #, no-c-format msgid "Anonymous" msgstr "Anonime" #. Tag: para #, no-c-format msgid "Globally Unique" msgstr "Unice la nivel global" #. Tag: para #, no-c-format msgid "Stateful" msgstr "Stateful" #. Tag: para #, no-c-format msgid "Anonymous clones are the simplest type. These resources behave completely identically everywhere they are running. Because of this, there can only be one copy of an anonymous clone active per machine." msgstr "Clonele anonime sunt tipul cel mai simplu. Aceste resurse se comportă absolut identic oriunde rulează. Din această cauză, poate exista doar o copie a unei clone anonime activă per maşină." #. Tag: para #, no-c-format msgid "Globally unique clones are distinct entities. A copy of the clone running on one machine is not equivalent to another instance on another node. Nor would any two copies on the same node be equivalent." msgstr "Clonele unice la nivel global sunt entităţi distincte. O copie a unei clone rulând pe o maşină nu este echivalentă cu o altă instanţă pe alt nod. Nici nu ar fi echivalente oricare două copii pe acelaşi nod." #. Tag: para #, no-c-format msgid "Stateful clones are covered later in ." msgstr "Clonele stateful sunt discutate mai târziu în ." #. Tag: title #, no-c-format msgid "An example clone" msgstr "Un exemplu de clonă" #. Tag: programlisting #, fuzzy, no-c-format msgid "" "<clone id=\"apache-clone\">\n" " <meta_attributes id=\"apache-clone-meta\">\n" " <nvpair id=\"apache-unique\" name=\"globally-unique\" value=\"false\"/>\n" " </meta_attributes>\n" " <primitive id=\"apache\" class=\"lsb\" type=\"apache\"/>\n" "</clone>" msgstr "" " <clone id=\"apache-clone\">\n" " <meta_attributes id=\"apache-clone-meta\">\n" " <nvpair id=\"apache-unique\" name=\"globally-unique\" value=\"false\"/>\n" " </meta_attributes>\n" " <primitive id=\"apache\" class=\"lsb\" type=\"apache\"/>\n" " </clone> " #. Tag: title #, fuzzy, no-c-format msgid "Clone Properties" msgstr "Proprietăţi" #. Tag: title #, no-c-format msgid "Properties of a Clone Resource" msgstr "Proprietăţile unei Resurse Clonă" #. Tag: para #, fuzzy, no-c-format msgid "Your name for the clone idClone Property Clone Property ClonePropertyid Propertyid id " msgstr "idProprietatea unei Resurse Clonă Proprietățile Resurselor Clonăid ResurseProprietatea Cloneiid id" #. Tag: title #, fuzzy, no-c-format msgid "Clone Options" msgstr "Opţiuni" #. Tag: title #, no-c-format msgid "Clone specific configuration options" msgstr "Opţiuni de configurare specifice clonei" #. Tag: para #, fuzzy, no-c-format msgid "clone-max" msgstr "Resursele Slave:" #. Tag: para #, fuzzy, no-c-format msgid "How many copies of the resource to start. Defaults to the number of nodes in the cluster. clone-maxClone Option Clone Option CloneOptionclone-max Optionclone-max clone-max " msgstr "idProprietatea unei Resurse Clonă Proprietățile Resurselor Clonăid ResurseProprietatea Cloneiid id" #. Tag: para #, fuzzy, no-c-format msgid "clone-node-max" msgstr "Resursele Slave:" #. Tag: para #, fuzzy, no-c-format msgid "How many copies of the resource can be started on a single node; default 1. clone-node-maxClone Option Clone Option CloneOptionclone-node-max Optionclone-node-max clone-node-max " msgstr "clone-node-max Proprietatea unei Resurse Clonă Proprietățile Resursei Clonăclone-node-max ResursăProprietatea Cloneiclone-node-max clone-node-max" #. Tag: para #, fuzzy, no-c-format msgid "notify" msgstr "Resursele Active:" #. Tag: para #, no-c-format msgid "When stopping or starting a copy of the clone, tell all the other copies beforehand and when the action was successful. Allowed values: false, true notifyClone Option Clone Option CloneOptionnotify Optionnotify notify " msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "globally-unique" msgstr "Resursele Slave:" #. Tag: para #, no-c-format msgid "Does each copy of the clone perform a different function? Allowed values: false, true globally-uniqueClone Option Clone Option CloneOptionglobally-unique Optionglobally-unique globally-unique " msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "ordered" msgstr "Resurse Master:" #. Tag: para #, fuzzy, no-c-format msgid "Should the copies be started in series (instead of in parallel). Allowed values: false, true orderedClone Option Clone Option CloneOptionordered Optionordered ordered " msgstr "idProprietatea unei Resurse Clonă Proprietățile Resurselor Clonăid ResurseProprietatea Cloneiid id" #. Tag: para #, fuzzy, no-c-format msgid "interleave" msgstr "Resursele Slave:" #. Tag: para #, no-c-format msgid "Changes the behavior of ordering constraints (between clones/masters) so that instances can start/stop as soon as their peer instance has (rather than waiting for every instance of the other clone has). Allowed values: false, true interleaveClone Option Clone Option CloneOptioninterleave Optioninterleave interleave " msgstr "" #. Tag: title #, fuzzy, no-c-format msgid "Clone Instance Attributes" msgstr "Atributele Instanţelor" #. Tag: para #, fuzzy, no-c-format msgid "Clones have no instance attributes; however, any that are set here will be inherited by the clone’s children." msgstr "Clonele nu au atribute de instanţă, totuşi cele care sunt setate aici vor fi moştenite de copiii clonei." #. Tag: title #, fuzzy, no-c-format msgid "Clone Contents" msgstr "Conţinut" #. Tag: para #, no-c-format msgid "Clones must contain exactly one group or one regular resource." msgstr "Clonele trebuie să conţină fix un grup sau o resursă obişnuită." #. Tag: para #, fuzzy, no-c-format msgid "You should never reference the name of a clone’s child. If you think you need to do this, you probably need to re-evaluate your design." msgstr "Nu ar trebui să referenţiaţi niciodată numele copilului unei clone. Dacă se consideră că este necesar acest lucru, probabil trebuie sa re-evaluaţi design-ul vostru." #. Tag: title #, fuzzy, no-c-format msgid "Clone Constraints" msgstr "Restricţii" #. Tag: para #, fuzzy, no-c-format msgid "In most cases, a clone will have a single copy on each active cluster node. If this is not the case, you can indicate which nodes the cluster should preferentially assign copies to with resource location constraints. These constraints are written no differently to those for regular resources except that the clone’s id is used." msgstr "În majoritatea cazurilor, o clonă va avea o singură copie pe fiecare nod activ din cluster. Totuşi dacă nu este cazul, puteţi indica prin restricţii de locaţie a resursei către care noduri ar trebui clusterul să asigneze în mod preferenţial copiile. Aceste restricţii nu sunt scrise în mod diferit faţă de cele pentru resurse obişnuite cu excepţia faptului că id-ul clonei este folosit." #. Tag: para #, no-c-format msgid "Ordering constraints behave slightly differently for clones. In the example below, apache-stats will wait until all copies of the clone that need to be started have done so before being started itself. Only if no copies can be started apache-stats will be prevented from being active. Additionally, the clone will wait for apache-stats to be stopped before stopping the clone." msgstr "Restricţiile de ordonare se comportă uşor diferit în cazul clonelor. În exemplele de mai jos, apache-stats va aştepta până ce toate copiile clonelor care trebuie să fie pornite au făcut acest lucru înainte ca aceasta să fie pornită la rândul ei. Doar dacă nici o copie nu poate fi pornită va fi împiedicată apache-stats din a fi activă. În plus, clona va aştepta ca apache-stats să fie oprită înainte de a opri clona." #. Tag: para #, fuzzy, no-c-format msgid "Colocation of a regular (or group) resource with a clone means that the resource can run on any machine with an active copy of the clone. The cluster will choose a copy based on where the clone is running and the resource’s own location preferences." msgstr "Colocarea unei resurse obişnuite (sau a unui grup) cu o clonă înseamnă că resursa poate rula pe orice maşină cu o copie activă a clonei. Clusterul va alege o copie ţinând cont unde rulează în mod curent clona şi de preferinţele proprii de locaţie ale resursei." #. Tag: para #, no-c-format msgid "Colocation between clones is also possible. In such cases, the set of allowed locations for the clone is limited to nodes on which the clone is (or will be) active. Allocation is then performed as normally." msgstr "Colocarea între clone este posibilă de asemenea. În astfel de cazuri, setul de locaţii permise pentru clonă este limitat la nodurile pe care clona alături de care va fi colocată este (sau va fi) activă. Alocarea este mai apoi efectuată în mod normal." #. Tag: title #, no-c-format msgid "Example constraints involving clones" msgstr "Exemple de restricţii implicând clone" #. Tag: programlisting #, fuzzy, no-c-format msgid "" "<constraints>\n" " <rsc_location id=\"clone-prefers-node1\" rsc=\"apache-clone\" node=\"node1\" score=\"500\"/>\n" " <rsc_colocation id=\"stats-with-clone\" rsc=\"apache-stats\" with=\"apache-clone\"/>\n" " <rsc_order id=\"start-clone-then-stats\" first=\"apache-clone\" then=\"apache-stats\"/>\n" "</constraints>" msgstr "" " <constraints>\n" " <rsc_location id=\"clone-prefers-node1\" rsc=\"apache-clone\" node=\"node1\" score=\"500\"/>\n" " <rsc_colocation id=\"stats-with-clone\" rsc=\"apache-stats\" with=\"apache-clone\"/>\n" " <rsc_order id=\"start-clone-then-stats\" first=\"apache-clone\" then=\"apache-stats\"/>\n" " </constraints> " #. Tag: title #, fuzzy, no-c-format msgid "Clone Stickiness" msgstr "Adezivitate" #. Tag: para #, fuzzy, no-c-format msgid " resource-stickinessClones Clones " msgstr "resource-stickinessa unei Resurse de Grup Adezivitatea" #. Tag: para #, fuzzy, no-c-format msgid "To achieve a stable allocation pattern, clones are slightly sticky by default. If no value for resource-stickiness is provided, the clone will use a value of 1. Being a small value, it causes minimal disturbance to the score calculations of other resources but is enough to prevent Pacemaker from needlessly moving copies around the cluster." msgstr "resource-stickinessa unei Resurse Clonă Pentru a atinge un tipar de alocare stabil, clonele sunt uşor adezive în mod implicit. Dacă nu este furnizată nici o valoare pentru resource-stickiness, clona va folosi valoarea 1. Fiind o valoare mică, aceasta cauzează o perturbare minimală a calcului scorului celorlalte resurse dar este suficientă pentru a împiedica Pacemaker-ul de a muta inutil copiile prin cluster." #. Tag: title #, fuzzy, no-c-format msgid "Clone Resource Agent Requirements" msgstr "Cerinţele Agentului de Resursă" #. Tag: para #, no-c-format msgid "Any resource can be used as an anonymous clone, as it requires no additional support from the resource agent. Whether it makes sense to do so depends on your resource and its resource agent." msgstr "Orice resursă poate fi utilizată ca o clonă anonimă deoarece nu necesită vreun suport adiţional din partea agentului de resursă. Dacă are logică să facă acest lucru depinde de resursa voastră şi de agentul de resursă aferent." #. Tag: para #, fuzzy, no-c-format msgid "Globally unique clones do require some additional support in the resource agent. In particular, it must only respond with other probes for instances of the clone should result in they should return one of the other OCF error codes." msgstr "Clonele unice la nivel global necesită suport adiţional în agentul de resursă. În special, trebuie să răspundă doar cu ${OCF_SUCCESS} dacă nodul are exact acea instanţă activă. Tot restul de probe pentru instanţe ale clonei ar trebui să rezulte în ${OCF_NOT_RUNNING}. Cu excepţia cazului în care au eşuat, caz în care ar trebui să returneze unul din celelalte coduri de eroare OCF." #. Tag: para #, no-c-format msgid "Copies of a clone are identified by appending a colon and a numerical offset, eg. apache:2." msgstr "Copiile unei clone sunt identificate prin sufixarea a două puncte şi a unui delimitator numeric. Ex. apache:2" #. Tag: para #, fuzzy, no-c-format msgid "Resource agents can find out how many copies there are by examining the OCF_RESKEY_CRM_meta_clone_max environment variable and which copy it is by examining OCF_RESKEY_CRM_meta_clone." msgstr "Agenţii de resursă pot afla câte copii există prin examinarea variabilei de mediu OCF_RESKEY_CRM_meta_clone_max şi a cărei copii este cea curentă examinând OCF_RESKEY_CRM_meta_clone." #. Tag: para #, fuzzy, no-c-format msgid "You should not make any assumptions (based on OCF_RESKEY_CRM_meta_clone) about which copies are active. In particular, the list of active copies will not always be an unbroken sequence, nor always start at 0." msgstr "Nu ar trebui să faceţi presupuneri (pe baza OCF_RESKEY_CRM_meta_clone) în privinţa căror copii sunt active. În special, lista de copii active nu va fi întotdeauna o secvenţă continuă, nici nu va începe întotdeauna de la 0." #. Tag: title #, fuzzy, no-c-format msgid "Clone Notifications" msgstr "Notificări" #. Tag: para #, no-c-format msgid "Supporting notifications requires the notify action to be implemented. Once supported, the notify action will be passed a number of extra variables which, when combined with additional context, can be used to calculate the current state of the cluster and what is about to happen to it." msgstr "Suportarea notificărilor necesită acţiunea notify să fie implementată. Odată ce este suportată, acţiunii de notificare îi vor fi trimise un număr de variabile suplimentare care, atunci când sunt combinate cu un context adiţional, pot fi folosite pentru a calcula starea curentă a clusterului şi ceea ce urmează să i se întâmple." #. Tag: title #, no-c-format msgid "Environment variables supplied with Clone notify actions" msgstr "Variabile de mediu furnizate împreună cu acţiunile de notificare ale Clonei" #. Tag: entry #, no-c-format msgid "Variable" msgstr "Variabilă" #. Tag: para #, fuzzy, no-c-format msgid "OCF_RESKEY_CRM_meta_notify_type" msgstr "plus $OCF_RESKEY_CRM_meta_notify_stop_resource" #. Tag: para #, no-c-format msgid "Allowed values: pre, post Environment VariableOCF_RESKEY_CRM_meta_notify_type OCF_RESKEY_CRM_meta_notify_type type typeNotification Environment Variable Notification Environment Variable " msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "OCF_RESKEY_CRM_meta_notify_operation" msgstr "$OCF_RESKEY_CRM_meta_notify_active_resource" #. Tag: para #, no-c-format msgid "Allowed values: start, stop Environment VariableOCF_RESKEY_CRM_meta_notify_operation OCF_RESKEY_CRM_meta_notify_operation operation operationNotification Environment Variable Notification Environment Variable " msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "OCF_RESKEY_CRM_meta_notify_start_resource" msgstr "plus $OCF_RESKEY_CRM_meta_notify_start_resource" #. Tag: para #, fuzzy, no-c-format msgid "Resources to be started Environment VariableOCF_RESKEY_CRM_meta_notify_start_resource OCF_RESKEY_CRM_meta_notify_start_resource start_resource start_resourceNotification Environment Variable Notification Environment Variable " msgstr "Variabilă de MediuOCF_RESKEY_CRM__meta_notify_start_resource OCF_RESKEY_CRM_meta_notify_start_resource OCF_RESKEY_CRM_meta_notify_start_resource" #. Tag: para #, fuzzy, no-c-format msgid "OCF_RESKEY_CRM_meta_notify_stop_resource" msgstr "plus $OCF_RESKEY_CRM_meta_notify_stop_resource" #. Tag: para #, fuzzy, no-c-format msgid "Resources to be stopped Environment VariableOCF_RESKEY_CRM_meta_notify_stop_resource OCF_RESKEY_CRM_meta_notify_stop_resource stop_resource stop_resourceNotification Environment Variable Notification Environment Variable " msgstr "Variabilă de MediuOCF_RESKEY_CRM__meta_notify_stop_resource OCF_RESKEY_CRM_meta_notify_stop_resource OCF_RESKEY_CRM_meta_notify_stop_resource" #. Tag: para #, fuzzy, no-c-format msgid "OCF_RESKEY_CRM_meta_notify_active_resource" msgstr "$OCF_RESKEY_CRM_meta_notify_active_resource" #. Tag: para #, fuzzy, no-c-format msgid "Resources that are running Environment VariableOCF_RESKEY_CRM_meta_notify_active_resource OCF_RESKEY_CRM_meta_notify_active_resource active_resource active_resourceNotification Environment Variable Notification Environment Variable " msgstr "Variabilă de MediuOCF_RESKEY_CRM__meta_notify_active_resource OCF_RESKEY_CRM_meta_notify_active_resource OCF_RESKEY_CRM_meta_notify_active_resource" #. Tag: para #, fuzzy, no-c-format msgid "OCF_RESKEY_CRM_meta_notify_inactive_resource" msgstr "$OCF_RESKEY_CRM_meta_notify_inactive_resource" #. Tag: para #, fuzzy, no-c-format msgid "Resources that are not running Environment VariableOCF_RESKEY_CRM_meta_notify_inactive_resource OCF_RESKEY_CRM_meta_notify_inactive_resource inactive_resource inactive_resourceNotification Environment Variable Notification Environment Variable " msgstr "Variabilă de MediuOCF_RESKEY_CRM__meta_notify_inactive_resource OCF_RESKEY_CRM_meta_notify_inactive_resource OCF_RESKEY_CRM_meta_notify_inactive_resource" #. Tag: para #, fuzzy, no-c-format msgid "OCF_RESKEY_CRM_meta_notify_start_uname" msgstr "plus $OCF_RESKEY_CRM_meta_notify_start_resource" #. Tag: para #, fuzzy, no-c-format msgid "Nodes on which resources will be started Environment VariableOCF_RESKEY_CRM_meta_notify_start_uname OCF_RESKEY_CRM_meta_notify_start_uname start_uname start_unameNotification Environment Variable Notification Environment Variable " msgstr "Variabilă de MediuOCF_RESKEY_CRM__meta_notify_start_uname OCF_RESKEY_CRM_meta_notify_start_uname OCF_RESKEY_CRM_meta_notify_start_uname" #. Tag: para #, fuzzy, no-c-format msgid "OCF_RESKEY_CRM_meta_notify_stop_uname" msgstr "plus $OCF_RESKEY_CRM_meta_notify_stop_resource" #. Tag: para #, fuzzy, no-c-format msgid "Nodes on which resources will be stopped Environment VariableOCF_RESKEY_CRM_meta_notify_stop_uname OCF_RESKEY_CRM_meta_notify_stop_uname stop_uname stop_unameNotification Environment Variable Notification Environment Variable " msgstr "Variabilă de MediuOCF_RESKEY_CRM__meta_notify_stop_uname OCF_RESKEY_CRM_meta_notify_stop_uname OCF_RESKEY_CRM_meta_notify_stop_uname" #. Tag: para #, fuzzy, no-c-format msgid "OCF_RESKEY_CRM_meta_notify_active_uname" msgstr "$OCF_RESKEY_CRM_meta_notify_active_resource" #. Tag: para #, fuzzy, no-c-format msgid "Nodes on which resources are running Environment VariableOCF_RESKEY_CRM_meta_notify_active_uname OCF_RESKEY_CRM_meta_notify_active_uname active_uname active_unameNotification Environment Variable Notification Environment Variable " msgstr "Variabilă de MediuOCF_RESKEY_CRM__meta_notify_active_uname OCF_RESKEY_CRM_meta_notify_active_uname OCF_RESKEY_CRM_meta_notify_active_uname" #. Tag: para #, fuzzy, no-c-format msgid "OCF_RESKEY_CRM_meta_notify_inactive_uname" msgstr "$OCF_RESKEY_CRM_meta_notify_inactive_resource" #. Tag: para #, fuzzy, no-c-format msgid "Nodes on which resources are not running Environment VariableOCF_RESKEY_CRM_meta_notify_inactive_uname OCF_RESKEY_CRM_meta_notify_inactive_uname inactive_uname inactive_unameNotification Environment Variable Notification Environment Variable " msgstr "Variabilă de MediuOCF_RESKEY_CRM__meta_notify_inactive_uname OCF_RESKEY_CRM_meta_notify_inactive_uname OCF_RESKEY_CRM_meta_notify_inactive_uname" #. Tag: para #, fuzzy, no-c-format msgid "The variables come in pairs, such as OCF_RESKEY_CRM_meta_notify_start_resource and OCF_RESKEY_CRM_meta_notify_start_uname and should be treated as an array of whitespace separated elements." msgstr "Variabilele vin în perechi, cum ar fi OCF_RESKEY_CRM_meta_notify_start_resource şi OCF_RESKEY_CRM_meta_notify_start_uname şi ar trebui tratate ca un array de elemente separate de spaţiu." #. Tag: para #, no-c-format msgid "Thus in order to indicate that clone:0 will be started on sles-1, clone:2 will be started on sles-3, and clone:3 will be started on sles-2, the cluster would set" msgstr "Drept urmare pentru a indica faptul că, clone:0 va fi pornită pe sles-1, clone:2 va fi pornită pe sles-3 şi clone:3 va fi pornită pe sles-2, clusterul va seta" #. Tag: title #, no-c-format msgid "Example notification variables" msgstr "Exemple de variabile de notificare" #. Tag: programlisting #, fuzzy, no-c-format msgid "" "OCF_RESKEY_CRM_meta_notify_start_resource=\"clone:0 clone:2 clone:3\"\n" "OCF_RESKEY_CRM_meta_notify_start_uname=\"sles-1 sles-3 sles-2\"" msgstr "" "\n" "\t\tOCF_RESKEY_CRM_meta_notify_start_resource=\"clone:0 clone:2 clone:3\" \n" "\t\tOCF_RESKEY_CRM_meta_notify_start_uname=\"sles-1 sles-3 sles-2\"\n" "\t " #. Tag: title #, no-c-format msgid "Proper Interpretation of Notification Environment Variables" msgstr "Interpretarea Corespunzătoare a Variabilelor de Mediu de Notificare" #. Tag: title #, no-c-format msgid "Pre-notification (stop):" msgstr "Pre-notificare (oprire)" #. Tag: para #, fuzzy, no-c-format msgid "Active resources: $OCF_RESKEY_CRM_meta_notify_active_resource" msgstr "Resurse active: $OCF_RESKEY_CRM_meta_notify_active_resource" #. Tag: para #, fuzzy, no-c-format msgid "Inactive resources: $OCF_RESKEY_CRM_meta_notify_inactive_resource" msgstr "Resurse inactive: $OCF_RESKEY_CRM_meta_notify_inactive_resource" #. Tag: para #, fuzzy, no-c-format msgid "Resources to be started: $OCF_RESKEY_CRM_meta_notify_start_resource" msgstr "Resurse care vor fi pornite: $OCF_RESKEY_CRM_meta_notify_start_resource" #. Tag: para #, fuzzy, no-c-format msgid "Resources to be stopped: $OCF_RESKEY_CRM_meta_notify_stop_resource" msgstr "Resurse care vor fi oprite: $OCF_RESKEY_CRM_meta_notify_stop_resource" #. Tag: title #, no-c-format msgid "Post-notification (stop) / Pre-notification (start):" msgstr "Post-notificare (oprire) / Pre-notificare (pornire)" #. Tag: para #, no-c-format msgid "Active resources" msgstr "Resurse active:" #. Tag: para #, fuzzy, no-c-format msgid "$OCF_RESKEY_CRM_meta_notify_active_resource" msgstr "$OCF_RESKEY_CRM_meta_notify_active_resource" #. Tag: para #, fuzzy, no-c-format msgid "minus $OCF_RESKEY_CRM_meta_notify_stop_resource" msgstr "minus $OCF_RESKEY_CRM_meta_notify_stop_resource" #. Tag: para #, no-c-format msgid "Inactive resources" msgstr "Resurse inactive:" #. Tag: para #, fuzzy, no-c-format msgid "$OCF_RESKEY_CRM_meta_notify_inactive_resource" msgstr "$OCF_RESKEY_CRM_meta_notify_inactive_resource" #. Tag: para #, fuzzy, no-c-format msgid "plus $OCF_RESKEY_CRM_meta_notify_stop_resource" msgstr "plus $OCF_RESKEY_CRM_meta_notify_stop_resource" #. Tag: para #, fuzzy, no-c-format msgid "Resources that were started: $OCF_RESKEY_CRM_meta_notify_start_resource" msgstr "Resurse care au fost pornite: $OCF_RESKEY_CRM_meta_notify_start_resource" #. Tag: para #, fuzzy, no-c-format msgid "Resources that were stopped: $OCF_RESKEY_CRM_meta_notify_stop_resource" msgstr "Resurse care au fost oprite: $OCF_RESKEY_CRM_meta_notify_stop_resource" #. Tag: title #, no-c-format msgid "Post-notification (start):" msgstr "Post-notificare (pornire)" #. Tag: para #, no-c-format msgid "Active resources:" msgstr "Resurse active:" #. Tag: para #, fuzzy, no-c-format msgid "plus $OCF_RESKEY_CRM_meta_notify_start_resource" msgstr "plus $OCF_RESKEY_CRM_meta_notify_start_resource" #. Tag: para #, no-c-format msgid "Inactive resources:" msgstr "Resurse inactive:" #. Tag: para #, fuzzy, no-c-format msgid "minus $OCF_RESKEY_CRM_meta_notify_start_resource" msgstr "minus $OCF_RESKEY_CRM_meta_notify_start_resource" #. Tag: title #, no-c-format msgid "Multi-state - Resources That Have Multiple Modes" msgstr "" #. Tag: para #, fuzzy, no-c-format msgid " Multi-state Resources ResourcesMulti-state Multi-state " msgstr "Resurse Multi-state ResurseMulti-state Multi-state - Resurse Care Au Moduri Multiple" #. Tag: para #, no-c-format msgid "Multi-state resources are a specialization of Clone resources; please ensure you understand the section on clones before continuing! They allow the instances to be in one of two operating modes; these are called Master and Slave, but can mean whatever you wish them to mean. The only limitation is that when an instance is started, it must come up in the Slave state." msgstr "Resursele multi-state sunt o specializare a Clonelor (vă rugăm să vă asiguraţi că înţelegeţi secţiunea referitoare la clone înainte de a continua) care permite instanţelor să se afle în unul din două moduri operaţionale; aceste moduri sunt numite Master şi Slave dar pot însemna orice doriţi să însemne. Singura limitare este că atunci când o instanţă este pornită, trebuie să o facă în starea Slave." #. Tag: title #, fuzzy, no-c-format msgid "Multi-state Properties" msgstr "Proprietăţi" #. Tag: title #, no-c-format msgid "Properties of a Multi-State Resource" msgstr "Proprietăţile unei Resurse Multi-State" #. Tag: para #, fuzzy, no-c-format msgid "Your name for the multi-state resource idMulti-State Property Multi-State Property Multi-StatePropertyid Propertyid id " msgstr "idProprietatea Resursei Multi-State Proprietățile Resursei Multi-Stateid ResursăProprietatea Multi-Stateid id" #. Tag: title #, no-c-format msgid "Multi-state Options" msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "Options inherited from primitive resources: priority, target-role, is-managed" msgstr "Opţiunile moştenite de la resurse simple: priority, target-role, is-managed" #. Tag: para #, fuzzy, no-c-format msgid "Options inherited from clone resources: clone-max, clone-node-max, notify, globally-unique, ordered, interleave" msgstr "Opţiuni moştenite de la resursele clonate: clone-max, clone-node-max, notify, globally-unique, ordered, interleave" #. Tag: title #, no-c-format msgid "Multi-state specific resource configuration options" msgstr "Opţiuni specifice de configurare pentru resurse multi-state" #. Tag: para #, fuzzy, no-c-format msgid "master-max" msgstr "Resurse Master:" #. Tag: para #, fuzzy, no-c-format msgid "How many copies of the resource can be promoted to master status; default 1. master-maxMulti-State Option Multi-State Option Multi-StateOptionmaster-max Optionmaster-max master-max " msgstr "idProprietatea Resursei Multi-State Proprietățile Resursei Multi-Stateid ResursăProprietatea Multi-Stateid id" #. Tag: para #, fuzzy, no-c-format msgid "master-node-max" msgstr "Resurse Master:" #. Tag: para #, fuzzy, no-c-format msgid "How many copies of the resource can be promoted to master status on a single node; default 1. master-node-maxMulti-State Option Multi-State Option Multi-StateOptionmaster-node-max Optionmaster-node-max master-node-max " msgstr "master-node-max Proprietatea Resursei Multi-State Proprietățile Resursei Multi-Statemaster-node-max ResursăProprietatea Multi-Statemaster-node-max master-node-max" #. Tag: title #, fuzzy, no-c-format msgid "Multi-state Instance Attributes" msgstr "Atributele Instanţelor" #. Tag: para #, fuzzy, no-c-format msgid "Multi-state resources have no instance attributes; however, any that are set here will be inherited by master’s children." msgstr "Resursele multi-state nu au atribute de instanţă; însă, oricare ar fi setate aici vor fi moştenite de către copiii master-ului." #. Tag: title #, no-c-format msgid "Multi-state Contents" msgstr "" #. Tag: para #, no-c-format msgid "Masters must contain exactly one group or one regular resource." msgstr "Masterii trebuie să conţină exact un grup sau o resursă obişnuită." #. Tag: para #, fuzzy, no-c-format msgid "You should never reference the name of a master’s child. If you think you need to do this, you probably need to re-evaluate your design." msgstr "Nu ar trebui să referenţiaţi niciodată numele copilului unui master. Dacă credeți că trebuie sa faceți asta, atunci probabil trebuie să re-evaluați designul vostru." #. Tag: title #, no-c-format msgid "Monitoring Multi-State Resources" msgstr "Monitorizarea Resurselor Multi-State" #. Tag: para #, no-c-format msgid "The normal type of monitor actions are not sufficient to monitor a multi-state resource in the Master state. To detect failures of the Master instance, you need to define an additional monitor action with role=\"Master\"." msgstr "Tipul normal de acţiuni de monitorizare nu sunt suficiente pentru a monitoriza o resursă multi-state în starea Master. Pentru a detecta eşecurile instanţei Master, trebuie să definiţi o acţiune de monitorizare adiţională cu role=\"Master\"." #. Tag: para #, no-c-format msgid "It is crucial that every monitor operation has a different interval!" msgstr "Este imperativ ca fiecare operaţiune de monitorizare să aibă un interval diferit!" #. Tag: para #, no-c-format msgid "This is because Pacemaker currently differentiates between operations only by resource and interval; so if eg. a master/slave resource has the same monitor interval for both roles, Pacemaker would ignore the role when checking the status - which would cause unexpected return codes, and therefore unnecessary complications." msgstr "Acest lucru este necesar deoarece Pacemaker diferențiază în mod curent între operațiuni numai după resursă și interval; deci dacă de ex. o resursă master/slave are același interval de monitorizare pentru ambele roluri, Pacemaker ar ignora rolul când ar verifica statusul - fapt care ar cauza coduri de ieșire neașteptate și respectiv complicații inutile." #. Tag: title #, no-c-format msgid "Monitoring both states of a multi-state resource" msgstr "Monitorizarea ambelor stări ale unei resurse multi-state" #. Tag: programlisting #, fuzzy, no-c-format msgid "" "<master id=\"myMasterRsc\">\n" " <primitive id=\"myRsc\" class=\"ocf\" type=\"myApp\" provider=\"myCorp\">\n" " <operations>\n" " <op id=\"public-ip-slave-check\" name=\"monitor\" interval=\"60\"/>\n" " <op id=\"public-ip-master-check\" name=\"monitor\" interval=\"61\" role=\"Master\"/>\n" " </operations>\n" " </primitive>\n" "</master>" msgstr "" " <master id=\"myMasterRsc\">\n" " <primitive id=\"myRsc\" class=\"ocf\" type=\"myApp\" provider=\"myCorp\">\n" " <operations>\n" " <op id=\"public-ip-slave-check\" name=\"monitor\" interval=\"60\"/>\n" " <op id=\"public-ip-master-check\" name=\"monitor\" interval=\"61\" role=\"Master\"/>\n" " </operations>\n" " </primitive>\n" " </master> " #. Tag: title #, fuzzy, no-c-format msgid "Multi-state Constraints" msgstr "Restricţii" #. Tag: para #, fuzzy, no-c-format msgid "In most cases, a multi-state resources will have a single copy on each active cluster node. If this is not the case, you can indicate which nodes the cluster should preferentially assign copies to with resource location constraints. These constraints are written no differently to those for regular resources except that the master’s id is used." msgstr "În majoritatea cazurilor, o resursă multi-state va avea o singură copie pe fiecare nod activ din cluster. Dacă nu este cazul însă, puteţi indica pe care noduri ar trebui clusterul în mod preferențial să asigneze copii cu restricţii de locaţie ale resurselor. Aceste restricţii nu sunt scrise diferit faţă de cele pentru resursele obişnuite cu excepţia faptului că id-ul masterului este folosit." #. Tag: para #, no-c-format msgid "When considering multi-state resources in constraints, for most purposes it is sufficient to treat them as clones. The exception is when the rsc-role and/or with-rsc-role fields (for colocation constraints) and first-action and/or then-action fields (for ordering constraints) are used." msgstr "Când ţinem cont de resursele multi-state în restricţii, pentru majoritatea scopurilor este suficient să le tratăm ca pe clone. Excepţia survine atunci când sunt folosite câmpurile rsc-role şi/sau with-rsc-role (pentru restricţii de colocare) şi câmpurile first-action şi/sau then-action (pentru restricţii de ordonare)." #. Tag: title #, no-c-format msgid "Additional constraint options relevant to multi-state resources" msgstr "Opţiuni de restricţionare adiţionale relevante la resurse multi-state" #. Tag: para #, fuzzy, no-c-format msgid "rsc-role" msgstr "Resursele Slave:" #. Tag: para #, no-c-format msgid "An additional attribute of colocation constraints that specifies the role that rsc must be in. Allowed values: Started, Master, Slave. rsc-roleOrdering Constraints Ordering Constraints ConstraintsOrderingrsc-role Orderingrsc-role rsc-role " msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "with-rsc-role" msgstr "Resursele Slave:" #. Tag: para #, no-c-format msgid "An additional attribute of colocation constraints that specifies the role that with-rsc must be in. Allowed values: Started, Master, Slave. with-rsc-roleOrdering Constraints Ordering Constraints ConstraintsOrderingwith-rsc-role Orderingwith-rsc-role with-rsc-role " msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "first-action" msgstr "Resursele Active:" #. Tag: para #, fuzzy, no-c-format msgid "An additional attribute of ordering constraints that specifies the action that the first resource must complete before executing the specified action for the then resource. Allowed values: start, stop, promote, demote. first-actionOrdering Constraints Ordering Constraints ConstraintsOrderingfirst-action Orderingfirst-action first-action " msgstr "Un atribut adiţional al restricţiilor de ordonare care specifică acţiunea pe care resursa first trebuie să o termine înaintea executării acţiunii specificate pentru resursa then. Valori permise: start, stop, promote, demote." #. Tag: para #, fuzzy, no-c-format msgid "then-action" msgstr "Resursele Active:" #. Tag: para #, fuzzy, no-c-format msgid "An additional attribute of ordering constraints that specifies the action that the then resource can only execute after the first-action on the first resource has completed. Allowed values: start, stop, promote, demote. Defaults to the value (specified or implied) of first-action. then-actionOrdering Constraints Ordering Constraints ConstraintsOrderingthen-action Orderingthen-action then-action " msgstr "Un atribut adiţional al restricţiilor de ordonare care specifică acţiunea pe care resursa then o poate executa doar după ce first-action asupra resursei first a terminat. Valori permise: start, stop, promote, demote. Valoarea implicită (specificată sau subînțeleasă) a first-action." #. Tag: para #, no-c-format msgid "In the example below, myApp will wait until one of the database copies has been started and promoted to master before being started itself. Only if no copies can be promoted will apache-stats be prevented from being active. Additionally, the database will wait for myApp to be stopped before it is demoted." msgstr "În exemplul de mai jos, myApp va aştepta până când una din copiile bazei de date a fost pornită şi promovată la master înainte de a fi ea însăşi pornită. Doar dacă nici o copie nu poate fi promovată va fi împiedicată apache-stats de a fi activă. În mod adiţional, baza de date va aştepta ca myApp să fie oprită înainte să fie degradată." #. Tag: title #, no-c-format msgid "Example constraints involving multi-state resources" msgstr "Exemple de restricţii implicând resurse multi-state" #. Tag: programlisting #, fuzzy, no-c-format msgid "" "<constraints>\n" " <rsc_location id=\"db-prefers-node1\" rsc=\"database\" node=\"node1\" score=\"500\"/>\n" " <rsc_colocation id=\"backup-with-db-slave\" rsc=\"backup\"\n" " with-rsc=\"database\" with-rsc-role=\"Slave\"/>\n" " <rsc_colocation id=\"myapp-with-db-master\" rsc=\"myApp\"\n" " with-rsc=\"database\" with-rsc-role=\"Master\"/>\n" " <rsc_order id=\"start-db-before-backup\" first=\"database\" then=\"backup\"/>\n" " <rsc_order id=\"promote-db-then-app\" first=\"database\" first-action=\"promote\"\n" " then=\"myApp\" then-action=\"start\"/>\n" "</constraints>" msgstr "" " <constraints>\n" " <rsc_location id=\"db-prefers-node1\" rsc=\"database\" node=\"node1\" score=\"500\"/>\n" " <rsc_colocation id=\"backup-with-db-slave\" rsc=\"backup\"\n" " with-rsc=\"database\" with-rsc-role=\"Slave\"/>\n" " <rsc_colocation id=\"myapp-with-db-master\" rsc=\"myApp\"\n" " with-rsc=\"database\" with-rsc-role=\"Master\"/>\n" " <rsc_order id=\"start-db-before-backup\" first=\"database\" then=\"backup\"/>\n" " <rsc_order id=\"promote-db-then-app\" first=\"database\" first-action=\"promote\"\n" " then=\"myApp\" then-action=\"start\"/>\n" " </constraints> " #. Tag: para #, no-c-format msgid "Colocation of a regular (or group) resource with a multi-state resource means that it can run on any machine with an active copy of the multi-state resource that is in the specified state (Master or Slave). In the example, the cluster will choose a location based on where database is running as a Master, and if there are multiple Master instances it will also factor in myApp's own location preferences when deciding which location to choose." msgstr "Colocarea unei resurse obişnuite (sau a unui grup) cu o resursă multi-state înseamnă că poate rula pe orice maşină cu o copie activă a resursei multi-state care se alfă în starea specificată (Master sau Slave). În exemplu, clusterul va alege o locaţie în funcţie de unde rulează baza de date în mod curent ca Master, şi dacă sunt mai multe instanţe de Master va lua în considerare şi preferinţele proprii de locaţie ale myApp când va decide care locaţie să aleagă." #. Tag: para #, no-c-format msgid "Colocation with regular clones and other multi-state resources is also possible. In such cases, the set of allowed locations for the rsc clone is (after role filtering) limited to nodes on which the with-rsc multi-state resource is (or will be) in the specified role. Allocation is then performed as-per-normal." msgstr "Colocarea alături de clone obişnuite şi alte resurse multi-state este posibilă de asemenea. În astfel de cazuri, setul de locaţii permise pentru clona rsc este (după filtrarea rolului) limitat la nodurile pe care resursa multi-state with-rsc există (sau va exista) în rolul specificat. Alocarea este atunci efectuată în mod normal." #. Tag: title #, fuzzy, no-c-format msgid "Multi-state Stickiness" msgstr "Adezivitate" #. Tag: para #, fuzzy, no-c-format msgid " resource-stickinessMulti-State Multi-State To achieve a stable allocation pattern, multi-state resources are slightly sticky by default. If no value for resource-stickiness is provided, the multi-state resource will use a value of 1. Being a small value, it causes minimal disturbance to the score calculations of other resources but is enough to prevent Pacemaker from needlessly moving copies around the cluster." msgstr "resource-stickiness unei Resurse Multi-State Pentru a atinge un tipar de alocare stabil, resursele multi-state sunt uşor adezive în mod implicit. Dacă nu este furnizată nici o valoare pentru resource-stickiness, resursa multi-state va folosi valoarea 1. Fiind o valoare mică, aceasta cauzează o perturbare minimală a calcului scorului celorlalte resurse dar este suficientă pentru a împiedica Pacemaker-ul de a muta inutil copiile prin cluster." #. Tag: title #, no-c-format msgid "Which Resource Instance is Promoted" msgstr "Care Instanţă a Resursei este Promovată" #. Tag: para #, fuzzy, no-c-format msgid "During the start operation, most Resource Agent scripts should call the crm_master utility. This tool automatically detects both the resource and host and should be used to set a preference for being promoted. Based on this, master-max, and master-node-max, the instance(s) with the highest preference will be promoted." msgstr "În timpul operaţiunii de pornire, majoritatea scripturilor Agenţilor de Resursă ar trebui să apeleze utilitarul crm_master. Acesta detectează în mod automat atât resursa cât şi gazda şi ar trebui să fie folosit pentru a seta o preferinţă pentru a fi promovat. În funcţie de asta, de master-max şi de master-node-max, instanţa(ele) cu cea mai mare preferinţă va(vor) fi promovată(e)." #. Tag: para #, no-c-format msgid "The other alternative is to create a location constraint that indicates which nodes are most preferred as masters." msgstr "Cealaltă alternativă să se creeze o restricţie de locaţie care să indice care noduri sunt cele mai preferate ca masteri." #. Tag: title #, no-c-format msgid "Manually specifying which node should be promoted" msgstr "Specificând manual care nod ar trebui să fie promovat" #. Tag: programlisting #, fuzzy, no-c-format msgid "" "<rsc_location id=\"master-location\" rsc=\"myMasterRsc\">\n" " <rule id=\"master-rule\" score=\"100\" role=\"Master\">\n" " <expression id=\"master-exp\" attribute=\"#uname\" operation=\"eq\" value=\"node1\"/>\n" " </rule>\n" "</rsc_location>" msgstr "" " <rsc_location id=\"master-location\" rsc=\"myMasterRsc\">\n" " <rule id=\"master-rule\" score=\"100\" role=\"Master\">\n" " <expression id=\"master-exp\" attribute=\"#uname\" operation=\"eq\" value=\"node1\"/>\n" " </rule>\n" " </rsc_location> " #. Tag: title #, fuzzy, no-c-format msgid "Multi-state Resource Agent Requirements" msgstr "Cerinţele Agentului de Resursă" #. Tag: para #, fuzzy, no-c-format msgid "Since multi-state resources are an extension of cloned resources, all the requirements of Clones are also requirements of multi-state resources. Additionally, multi-state resources require two extra actions: demote and promote; these actions are responsible for changing the state of the resource. Like start and stop, they should return OCF_SUCCESS if they completed successfully or a relevant error code if they did not." msgstr "Din moment ce resursele multi-state sunt o extensie a resurselor clonate, toate cerinţele Clonelor sunt de asemenea cerinţe ale resurselor multi-state. Adiţional, resursele multi-state necesită două acţiuni suplimentare: promote şi demote; aceste acţiuni sunt responsabile pentru schimbarea stării resursei. Precum start şi stop, acestea ar trebui să returneze OCF_SUCCESS dacă au terminat cu succes sau un cod de eroare relevant în caz contrar." #. Tag: para #, no-c-format msgid "The states can mean whatever you wish, but when the resource is started, it must come up in the mode called Slave. From there the cluster will then decide which instances to promote to Master." msgstr "Stările pot însemna orice doriţi, dar atunci când resursa este pornită, trebuie să ajungă în modul numit Slave. De acolo clusterul va decide mai apoi care instanţe să promoveze într-un Master." #. Tag: para #, no-c-format msgid "In addition to the Clone requirements for monitor actions, agents must also accurately report which state they are in. The cluster relies on the agent to report its status (including role) accurately and does not indicate to the agent what role it currently believes it to be in." msgstr "În plus faţă de cerinţele Clonelor pentru acţiunile de monitorizare, agenţii trebuie să raporteze corespunzător starea în care sunt. Clusterul se bazează pe agent să-şi raporteze statusul (incluzând rolul) în mod corespunzător şi nu indică agentului în care rol crede acesta în mod curent că ar trebui să se afle." #. Tag: title #, no-c-format msgid "Role implications of OCF return codes" msgstr "Implicaţiile rolurilor codurilor returnate de OCF" #. Tag: entry #, no-c-format msgid "Monitor Return Code" msgstr "Cod de Monitorizare Returnat" #. Tag: para #, no-c-format msgid "OCF_NOT_RUNNING" msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "Stopped Return CodeOCF_NOT_RUNNING OCF_NOT_RUNNING " msgstr "cod de ieșireOCF_NOT_RUNNING Variabilă de MediuOCF_NOT_RUNNING OCF_NOT_RUNNING OCF_NOT_RUNNING" #. Tag: para #, no-c-format msgid "OCF_SUCCESS" msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "Running (Slave) Return CodeOCF_SUCCESS OCF_SUCCESS " msgstr "cod de ieșireOCF_SUCCESS Variabilă de MediuOCF_SUCCESS OCF_SUCCESS OCF_SUCCESS" #. Tag: para #, no-c-format msgid "OCF_RUNNING_MASTER" msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "Running (Master) Return CodeOCF_RUNNING_MASTER OCF_RUNNING_MASTER " msgstr "cod de ieșireOCF_RUNNING_MASTER Variabilă de MediuOCF_RUNNING_MASTER OCF_RUNNING_MASTER OCF_RUNNING_MASTER" #. Tag: para #, no-c-format msgid "OCF_FAILED_MASTER" msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "Failed (Master) Return CodeOCF_FAILED_MASTER OCF_FAILED_MASTER " msgstr "cod de ieșireOCF_FAILED_MASTER Variabilă de MediuOCF_FAILED_MASTER OCF_FAILED_MASTER OCF_FAILED_MASTER" #. Tag: para #, no-c-format msgid "Other" msgstr "Altul" #. Tag: para #, no-c-format msgid "Failed (Slave)" msgstr "Eşuat (Slave)" #. Tag: title #, fuzzy, no-c-format msgid "Multi-state Notifications" msgstr "Notificări" #. Tag: para #, no-c-format msgid "Like clones, supporting notifications requires the notify action to be implemented. Once supported the notify action will be passed a number of extra variables which, when combined with additional context, can be used to calculate the current state of the cluster and what is about to happen to it." msgstr "Ca şi în cazul clonelor, suportarea notificărilor necesită acţiunea notify să fie implementată. Odată ce este suportată, acţiunii notify îi vor fi trimise un număr de variabile suplimentare care, când sunt combinate cu un context suplimentar, pot fi folosite pentru a calcula starea curentă a clusterului şi ceea ce urmează să i se întâmple." #. Tag: title #, fuzzy, no-c-format msgid "Environment variables supplied with Master notify actions Emphasized variables are specific to Master resources and all behave in the same manner as described for Clone resources." msgstr "Variabilele de mediu furnizate cu acţiunile de notificare MasterVariabilele îngroşate sunt specifice resurselor Master şi se comportă toate în acelaşi fel ca şi cel descris pentru resursele Clonă." #. Tag: para #, fuzzy, no-c-format msgid "Resources the that are running Environment VariableOCF_RESKEY_CRM_meta_notify_active_resource OCF_RESKEY_CRM_meta_notify_active_resource active_resource active_resourceNotification Environment Variable Notification Environment Variable " msgstr "Variabilă de MediuOCF_RESKEY_CRM__meta_notify_active_resource OCF_RESKEY_CRM_meta_notify_active_resource OCF_RESKEY_CRM_meta_notify_active_resource" #. Tag: para #, fuzzy, no-c-format msgid "Resources the that are not running Environment VariableOCF_RESKEY_CRM_meta_notify_inactive_resource OCF_RESKEY_CRM_meta_notify_inactive_resource inactive_resource inactive_resourceNotification Environment Variable Notification Environment Variable " msgstr "Variabilă de MediuOCF_RESKEY_CRM__meta_notify_inactive_resource OCF_RESKEY_CRM_meta_notify_inactive_resource OCF_RESKEY_CRM_meta_notify_inactive_resource" #. Tag: para #, fuzzy, no-c-format msgid "OCF_RESKEY_CRM_meta_notify_master_resource" msgstr " OCF_RESKEY_CRM_meta_notify_master_resource" #. Tag: para #, no-c-format msgid "Resources that are running in Master mode Environment VariableOCF_RESKEY_CRM_meta_notify_master_resource OCF_RESKEY_CRM_meta_notify_master_resource master_resource master_resourceNotification Environment Variable Notification Environment Variable " msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "OCF_RESKEY_CRM_meta_notify_slave_resource" msgstr " OCF_RESKEY_CRM_meta_notify_slave_resource" #. Tag: para #, no-c-format msgid "Resources that are running in Slave mode Environment VariableOCF_RESKEY_CRM_meta_notify_slave_resource OCF_RESKEY_CRM_meta_notify_slave_resource slave_resource slave_resourceNotification Environment Variable Notification Environment Variable " msgstr "" #. Tag: para #, fuzzy, no-c-format msgid " Environment VariableOCF_RESKEY_CRM_meta_notify_stop_resource OCF_RESKEY_CRM_meta_notify_stop_resource stop_resource stop_resourceNotification Environment Variable Notification Environment Variable OCF_RESKEY_CRM_meta_notify_stop_resource" msgstr "Variabilă de MediuOCF_RESKEY_CRM__meta_notify_stop_resource OCF_RESKEY_CRM_meta_notify_stop_resource OCF_RESKEY_CRM_meta_notify_stop_resource" #. Tag: para #, no-c-format msgid "Resources to be stopped" msgstr "Resursele care vor fi oprite" #. Tag: para #, fuzzy, no-c-format msgid "OCF_RESKEY_CRM_meta_notify_promote_resource" msgstr " OCF_RESKEY_CRM_meta_notify_promote_resource" #. Tag: para #, fuzzy, no-c-format msgid "Resources to be promoted Environment VariableOCF_RESKEY_CRM_meta_notify_promote_resource OCF_RESKEY_CRM_meta_notify_promote_resource promote_resource promote_resourceNotification Environment Variable Notification Environment Variable " msgstr "Variabilă de MediuOCF_RESKEY_CRM__meta_notify_active_resource OCF_RESKEY_CRM_meta_notify_active_resource OCF_RESKEY_CRM_meta_notify_active_resource" #. Tag: para #, fuzzy, no-c-format msgid "OCF_RESKEY_CRM_meta_notify_demote_resource" msgstr " OCF_RESKEY_CRM_meta_notify_demote_resource" #. Tag: para #, fuzzy, no-c-format msgid "Resources to be demoted Environment VariableOCF_RESKEY_CRM_meta_notify_demote_resource OCF_RESKEY_CRM_meta_notify_demote_resource demote_resource demote_resourceNotification Environment Variable Notification Environment Variable " msgstr "Variabilă de MediuOCF_RESKEY_CRM__meta_notify_active_resource OCF_RESKEY_CRM_meta_notify_active_resource OCF_RESKEY_CRM_meta_notify_active_resource" #. Tag: para #, fuzzy, no-c-format msgid "OCF_RESKEY_CRM_meta_notify_promote_uname" msgstr " OCF_RESKEY_CRM_meta_notify_promote_uname" #. Tag: para #, fuzzy, no-c-format msgid "Nodes on which resources will be promote Environment VariableOCF_RESKEY_CRM_meta_notify_promote_uname OCF_RESKEY_CRM_meta_notify_promote_uname promote_uname promote_unameNotification Environment Variable Notification Environment Variable " msgstr "Variabilă de MediuOCF_RESKEY_CRM__meta_notify_inactive_uname OCF_RESKEY_CRM_meta_notify_inactive_uname OCF_RESKEY_CRM_meta_notify_inactive_uname" #. Tag: para #, fuzzy, no-c-format msgid "OCF_RESKEY_CRM_meta_notify_demote_uname" msgstr " OCF_RESKEY_CRM_meta_notify_demote_uname" #. Tag: para #, fuzzy, no-c-format msgid "Nodes on which resources will be demoted Environment VariableOCF_RESKEY_CRM_meta_notify_demote_uname OCF_RESKEY_CRM_meta_notify_demote_uname demote_uname demote_unameNotification Environment Variable Notification Environment Variable " msgstr "Variabilă de MediuOCF_RESKEY_CRM__meta_notify_inactive_uname OCF_RESKEY_CRM_meta_notify_inactive_uname OCF_RESKEY_CRM_meta_notify_inactive_uname" #. Tag: para #, fuzzy, no-c-format msgid "OCF_RESKEY_CRM_meta_notify_master_uname" msgstr " OCF_RESKEY_CRM_meta_notify_master_uname" #. Tag: para #, no-c-format msgid "Nodes on which resources are running in Master mode Environment VariableOCF_RESKEY_CRM_meta_notify_master_uname OCF_RESKEY_CRM_meta_notify_master_uname master_uname master_unameNotification Environment Variable Notification Environment Variable " msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "OCF_RESKEY_CRM_meta_notify_slave_uname" msgstr " OCF_RESKEY_CRM_meta_notify_slave_uname" #. Tag: para #, no-c-format msgid "Nodes on which resources are running in Slave mode Environment VariableOCF_RESKEY_CRM_meta_notify_slave_uname OCF_RESKEY_CRM_meta_notify_slave_uname slave_uname slave_unameNotification Environment Variable Notification Environment Variable " msgstr "" #. Tag: title #, fuzzy, no-c-format msgid "Multi-state - Proper Interpretation of Notification Environment Variables" msgstr "Interpretarea Corespunzătoare a Variabilelor de Mediu de Notificare" #. Tag: title #, no-c-format msgid "Pre-notification (demote):" msgstr "Pre-notificare (degradează)" #. Tag: para #, fuzzy, no-c-format msgid "Active resources: $OCF_RESKEY_CRM_meta_notify_active_resource" msgstr "Resursele Active: $OCF_RESKEY_CRM_meta_notify_active_resource" #. Tag: para #, fuzzy, no-c-format msgid "Master resources: $OCF_RESKEY_CRM_meta_notify_master_resource" msgstr "Resursele Master: $OCF_RESKEY_CRM_meta_notify_master_resource" #. Tag: para #, fuzzy, no-c-format msgid "Slave resources: $OCF_RESKEY_CRM_meta_notify_slave_resource" msgstr "Resursele Slave: $OCF_RESKEY_CRM_meta_notify_slave_resource" #. Tag: para #, fuzzy, no-c-format msgid "Resources to be promoted: $OCF_RESKEY_CRM_meta_notify_promote_resource" msgstr "Resursele care vor fi promovate: $OCF_RESKEY_CRM_meta_notify_promote_resource" #. Tag: para #, fuzzy, no-c-format msgid "Resources to be demoted: $OCF_RESKEY_CRM_meta_notify_demote_resource" msgstr "Resursele care vor fi degradate: $OCF_RESKEY_CRM_meta_notify_demote_resource" #. Tag: title #, no-c-format msgid "Post-notification (demote) / Pre-notification (stop):" msgstr "Post-notificare (degradează) / Pre-notificare (oprire)" #. Tag: para #, no-c-format msgid "Master resources:" msgstr "Resurse Master:" #. Tag: para #, fuzzy, no-c-format msgid "$OCF_RESKEY_CRM_meta_notify_master_resource" msgstr "$OCF_RESKEY_CRM_meta_notify_master_resource" #. Tag: para #, fuzzy, no-c-format msgid "minus $OCF_RESKEY_CRM_meta_notify_demote_resource" msgstr "minus $OCF_RESKEY_CRM_meta_notify_demote_resource" #. Tag: para #, fuzzy, no-c-format msgid "Resources that were demoted: $OCF_RESKEY_CRM_meta_notify_demote_resource" msgstr "Resurse care au fost degradate: $OCF_RESKEY_CRM_meta_notify_demote_resource" #. Tag: title #, no-c-format msgid "Post-notification (stop) / Pre-notification (start)" msgstr "Post-notificare (oprire) / Pre-notificare (pornire)" #. Tag: para #, no-c-format msgid "Active resources:" msgstr "Resursele Active:" #. Tag: para #, no-c-format msgid "Slave resources:" msgstr "Resursele Slave:" #. Tag: para #, fuzzy, no-c-format msgid "$OCF_RESKEY_CRM_meta_notify_slave_resource" msgstr "$OCF_RESKEY_CRM_meta_notify_slave_resource" #. Tag: title #, no-c-format msgid "Post-notification (start) / Pre-notification (promote)" msgstr "Post-notificare (pornire) / Pre-notificare (promovează)" #. Tag: title #, no-c-format msgid "Post-notification (promote)" msgstr "Post-notificare (promovează)" #. Tag: para #, fuzzy, no-c-format msgid "plus $OCF_RESKEY_CRM_meta_notify_promote_resource" msgstr "plus $OCF_RESKEY_CRM_meta_notify_promote_resource" #. Tag: para #, fuzzy, no-c-format msgid "minus $OCF_RESKEY_CRM_meta_notify_promote_resource" msgstr "minus $OCF_RESKEY_CRM_meta_notify_promote_resource" #. Tag: para #, fuzzy, no-c-format msgid "Resources that were promoted: $OCF_RESKEY_CRM_meta_notify_promote_resource" msgstr "Resursele care au fost promovate: $OCF_RESKEY_CRM_meta_notify_promote_resource" #~ msgid "Your name for the group" #~ msgstr "Numele pe care îl daţi grupului" #~ msgid "Your name for the clone" #~ msgstr "Numele dat clonei" #~ msgid "Options inherited from simple resources: priority, target-role, is-managed" #~ msgstr "Opţiunile moştenite de la resurse simple: priority, target-role, is-managed" #~ msgid "clone-max Clone Resource Property Clone Resource Propertiesclone-max ResourceClone Propertyclone-max clone-max" #~ msgstr "clone-max Proprietatea unei Resurse Clonă Proprietățile Resursei Clonăclone-max ResursăProprietatea Cloneiclone-max clone-max" #~ msgid "How many copies of the resource to start. Defaults to the number of nodes in the cluster." #~ msgstr "Câte copii ale resursei să pornească. Valoarea implicită este egală cu numărul de noduri din cluster." #~ msgid "How many copies of the resource can be started on a single node; default 1." #~ msgstr "Câte copii ale resursei pot fi pornite pe un singur nod; valoarea implicită este 1." #~ msgid "notify Clone Resource Property Clone Resource Propertiesnotify ResourceClone Propertynotify notify" #~ msgstr "notify Proprietatea unei Resurse Clonă Proprietățile Resursei Clonănotify ResursăProprietatea Cloneinotify" #~ msgid "When stopping or starting a copy of the clone, tell all the other copies beforehand and when the action was successful. Allowed values: false, true" #~ msgstr "Când este oprită sau pornită o copie a clonei, comunică tuturor celorlalte copii înainte şi după ce acţiunea a reuşit. Valori permise: false, true" #~ msgid "globally-unique Clone Resource Property Clone Resource Propertiesglobally-unique ResourceClone Propertyglobally-unique globally-unique" #~ msgstr "globally-unique Proprietatea unei Resurse Clonă Proprietățile unei Resurse Clonăglobally-unique ResursăProprietatea Cloneiglobally-unique globally-unique" #~ msgid "Does each copy of the clone perform a different function? Allowed values: false, true" #~ msgstr "Efectuează fiecare copie a unei clone o funcţie diferită? Valori permise: false, true" #~ msgid "ordered Clone Resource Property Clone Resource Propertiesordered ResourceClone Propertyordered ordered" #~ msgstr "ordered Proprietatea Resursei Clonă Proprietățile Resursei Clonăordered ResursăProprietatea Cloneiordered ordered" #~ msgid "Should the copies be started in series (instead of in parallel). Allowed values: false, true" #~ msgstr "Ar trebui copiile să fie pornite secvenţial (în loc de în paralel). Valori permise: false, true" #~ msgid "interleave Clone Resource Property Clone Resource Propertiesinterleave ResourceClone Propertyinterleave interleave" #~ msgstr "interleave Proprietatea Resursei Clonă Proprietățile Resursei Clonăinterleave ResursăProprietatea Cloneiinterleave" #~ msgid "Changes the behavior of ordering constraints (between clones/masters) so that instances can start/stop as soon as their peer instance has (rather than waiting for every instance of the other clone has). Allowed values: false, true" #~ msgstr "Schimbă comportamentul de ordonare al restricţiilor (între clone/masters) astfel încât instanţele să se poată porni/opri de îndată ce şi instanţa vecină a făcut-o (decât să aştepte pentru fiecare instanţă pe care o are clona cealaltă). Valori permise: false, true" #~ msgid "Environment VariableOCF_RESKEY_CRM_meta_notify_type OCF_RESKEY_CRM_meta_notify_type OCF_RESKEY_CRM_meta_notify_type" #~ msgstr "Variabilă de MediuOCF_RESKEY_CRM_meta_notify_type OCF_RESKEY_CRM_meta_notify_type OCF_RESKEY_CRM_meta_notify_type" #~ msgid "Allowed values: pre, post" #~ msgstr "Valori permise: pre, post" #~ msgid "Environment VariableOCF_RESKEY_CRM_meta_notify_operation OCF_RESKEY_CRM_meta_notify_operation OCF_RESKEY_CRM_meta_notify_operation" #~ msgstr "Variabilă de MediuOCF_RESKEY_CRM_meta_notify_operation OCF_RESKEY_CRM_meta_notify_operation OCF_RESKEY_CRM_meta_notify_operation" #~ msgid "Allowed values: start, stop" #~ msgstr "Valori permise: start, stop" #~ msgid "Environment VariableOCF_RESKEY_CRM_meta_notify_start_resource OCF_RESKEY_CRM_meta_notify_start_resource OCF_RESKEY_CRM_meta_notify_start_resource" #~ msgstr "Variabilă de MediuOCF_RESKEY_CRM_meta_notify_start_resource OCF_RESKEY_CRM_meta_notify_start_resource OCF_RESKEY_CRM_meta_notify_start_resource" #~ msgid "Resources to be started" #~ msgstr "Resursele care vor fi pornite" #~ msgid "Environment VariableOCF_RESKEY_CRM_meta_notify_stop_resource OCF_RESKEY_CRM_meta_notify_stop_resource OCF_RESKEY_CRM_meta_notify_stop_resource" #~ msgstr "Variabilă de MediuOCF_RESKEY_CRM_meta_notify_stop_resource OCF_RESKEY_CRM_meta_notify_stop_resource OCF_RESKEY_CRM_meta_notify_stop_resource" #~ msgid "Environment VariableOCF_RESKEY_CRM_meta_notify_active_resource OCF_RESKEY_CRM_meta_notify_active_resource OCF_RESKEY_CRM_meta_notify_active_resource" #~ msgstr "Variabilă de MediuOCF_RESKEY_CRM_meta_notify_active_resource OCF_RESKEY_CRM_meta_notify_active_resource OCF_RESKEY_CRM_meta_notify_active_resource" #~ msgid "Resources that are running" #~ msgstr "Resursele care rulează" #~ msgid "Environment VariableOCF_RESKEY_CRM_meta_notify_inactive_resource OCF_RESKEY_CRM_meta_notify_inactive_resource OCF_RESKEY_CRM_meta_notify_inactive_resource" #~ msgstr "Variabilă de MediuOCF_RESKEY_CRM_meta_notify_inactive_resource OCF_RESKEY_CRM_meta_notify_inactive_resource OCF_RESKEY_CRM_meta_notify_inactive_resource" #~ msgid "Resources that are not running" #~ msgstr "Resursele care nu rulează" #~ msgid "Environment VariableOCF_RESKEY_CRM_meta_notify_start_uname OCF_RESKEY_CRM_meta_notify_start_uname OCF_RESKEY_CRM_meta_notify_start_uname" #~ msgstr "Variabilă de MediuOCF_RESKEY_CRM_meta_notify_start_uname OCF_RESKEY_CRM_meta_notify_start_uname OCF_RESKEY_CRM_meta_notify_start_uname" #~ msgid "Nodes on which resources will be started" #~ msgstr "Nodurile pe care resursele vor fi pornite" #~ msgid "Environment VariableOCF_RESKEY_CRM_meta_notify_stop_uname OCF_RESKEY_CRM_meta_notify_stop_uname OCF_RESKEY_CRM_meta_notify_stop_uname" #~ msgstr "Variabilă de MediuOCF_RESKEY_CRM_meta_notify_stop_uname OCF_RESKEY_CRM_meta_notify_stop_uname OCF_RESKEY_CRM_meta_notify_stop_uname" #~ msgid "Nodes on which resources will be stopped" #~ msgstr "Nodurile pe care resursele vor fi oprite" #~ msgid "Environment VariableOCF_RESKEY_CRM_meta_notify_active_uname OCF_RESKEY_CRM_meta_notify_active_uname OCF_RESKEY_CRM_meta_notify_active_uname" #~ msgstr "Variabilă de MediuOCF_RESKEY_CRM_meta_notify_active_uname OCF_RESKEY_CRM_meta_notify_active_uname OCF_RESKEY_CRM_meta_notify_active_uname" #~ msgid "Nodes on which resources are running" #~ msgstr "Nodurile pe care rulează resursele" #~ msgid "Environment VariableOCF_RESKEY_CRM_meta_notify_inactive_uname OCF_RESKEY_CRM_meta_notify_inactive_uname OCF_RESKEY_CRM_meta_notify_inactive_uname" #~ msgstr "Variabilă de MediuOCF_RESKEY_CRM_meta_notify_inactive_uname OCF_RESKEY_CRM_meta_notify_inactive_uname OCF_RESKEY_CRM_meta_notify_inactive_uname" #~ msgid "Nodes on which resources are not running" #~ msgstr "Nodurile pe care nu rulează resursele" #~ msgid "Your name for the multi-state resource" #~ msgstr "Numele asignat pentru resursa multi-state" #~ msgid "master-max Multi-State Resource Property Multi-State Resource Propertiesmaster-max ResourceMulti-State Propertymaster-max master-max" #~ msgstr "master-max Proprietatea Resursei Multi-State Proprietățile Resursei Multi-Statemaster-max ResursăProprietatea Multi-Statemaster-max master-max" #~ msgid "How many copies of the resource can be promoted to master status; default 1." #~ msgstr "Câte copii ale resursei pot fi promovate la statutul de master; valoarea implicită este 1." #~ msgid "How many copies of the resource can be promoted to master status on a single node; default 1." #~ msgstr "Câte copii ale resursei pot fi promovate la statutul de master pe un singur nod; valoarea implicită este 1." #~ msgid "rsc-role Multi-State Resource Constraints Multi-State Resource Constraintsrsc-role ResourceMulti-State Constraintsrsc-role rsc-role" #~ msgstr "rsc-role Restricții Resursă Multi-State Restricții Resursă Multi-Statersc-role ResursăRestricții Multi-Statersc-role rsc-role" #~ msgid "An additional attribute of colocation constraints that specifies the role that rsc must be in. Allowed values: Started, Master, Slave." #~ msgstr "Un atribut adiţional al restricţiilor de colocare care specifică rolul în care trebuie să se alfe rsc. Valori permise: Started, Master, Slave." #~ msgid "with-rsc-role Multi-State Resource Constraints Multi-State Resource Constraintswith-rsc-role ResourceMulti-State Constraintswith-rsc-role with-rsc-role" #~ msgstr "with-rsc-role Restricții Resursă Multi-State Restricții Resursă Multi-Statewith-rsc-role ResursăRestricții Multi-Statewith-rsc-role with-rsc-role" #~ msgid "An additional attribute of colocation constraints that specifies the role that with-rsc must be in. Allowed values: Started, Master, Slave." #~ msgstr "Un atribut adiţional al restricţiilor de colocare care specifică rolul în care trebuie să se alfe with-rsc. Valori permise: Started, Master, Slave." #~ msgid "first-action Multi-State Resource Constraints Multi-State Resource Constraintsfirst-action ResourceMulti-State Constraintsfirst-action first-action" #~ msgstr "first-action Restricții Resursă Multi-State Restricții Resursă Multi-Statefirst-action ResursăRestricții Multi-Statefirst-action first-action" #~ msgid "then-action Multi-State Resource Constraints Multi-State Resource Constraintsthen-action ResourceMulti-State Constraintsthen-action then-action" #~ msgstr "then-action Restricții Resursă Multi-State Restricții Resursă Multi-Statethen-action ResursăRestricții Multi-Statethen-action then-action" #~ msgid "Stopped" #~ msgstr "Oprit" #~ msgid "Running (Slave)" #~ msgstr "Rulând (Slave)" #~ msgid "Running (Master)" #~ msgstr "Rulează (Master)" #~ msgid "Failed (Master)" #~ msgstr "Eşuat (Master)" #~ msgid "Environment VariableOCF_RESKEY_CRM__meta_notify_type OCF_RESKEY_CRM_meta_notify_type OCF_RESKEY_CRM_meta_notify_type" #~ msgstr "Variabilă de MediuOCF_RESKEY_CRM__meta_notify_type OCF_RESKEY_CRM_meta_notify_type OCF_RESKEY_CRM_meta_notify_type" #~ msgid "Environment VariableOCF_RESKEY_CRM__meta_notify_operation OCF_RESKEY_CRM_meta_notify_operationOCF_RESKEY_CRM_meta_notify_operation" #~ msgstr "Variabilă de MediuOCF_RESKEY_CRM__meta_notify_operation OCF_RESKEY_CRM_meta_notify_operationOCF_RESKEY_CRM_meta_notify_operation" #~ msgid "Resources the that are running" #~ msgstr "Resursele care rulează" #~ msgid "Resources the that are not running" #~ msgstr "Resursele care nu rulează" #~ msgid "Environment VariableOCF_RESKEY_CRM__meta_notify_master_resource" #~ msgstr "Variabilă de MediuOCF_RESKEY_CRM__meta_notify_master_resource" #~ msgid "OCF_RESKEY_CRM_meta_notify_master_resource" #~ msgstr "OCF_RESKEY_CRM_meta_notify_master_resource" #~ msgid "Resources that are running in Master mode" #~ msgstr "Resursele care funcţionează în mod Master" #~ msgid "Environment VariableOCF_RESKEY_CRM__meta_notify_slave_resource" #~ msgstr "Variabilă de MediuOCF_RESKEY_CRM__meta_notify_slave_resource" #~ msgid "OCF_RESKEY_CRM_meta_notify_slave_resource" #~ msgstr "OCF_RESKEY_CRM_meta_notify_slave_resource" #~ msgid "Resources that are running in Slave mode" #~ msgstr "Resursele care funcţionează în mod Slave" #~ msgid "Environment VariableOCF_RESKEY_CRM__meta_notify_promote_resource" #~ msgstr "Variabilă de MediuOCF_RESKEY_CRM__meta_notify_promote_resource" #~ msgid "OCF_RESKEY_CRM_meta_notify_promote_resource" #~ msgstr "OCF_RESKEY_CRM_meta_notify_promote_resource" #~ msgid "Resources to be promoted" #~ msgstr "Resursele care vor fi promovate" #~ msgid "Environment VariableOCF_RESKEY_CRM__meta_notify_demote_resource" #~ msgstr "Variabilă de MediuOCF_RESKEY_CRM__meta_notify_demote_resource" #~ msgid "OCF_RESKEY_CRM_meta_notify_demote_resource" #~ msgstr "OCF_RESKEY_CRM_meta_notify_demote_resource" #~ msgid "Resources to be demoted" #~ msgstr "Resursele care vor fi degradate" #~ msgid "Environment VariableOCF_RESKEY_CRM__meta_notify_promote_uname" #~ msgstr "Variabilă de MediuOCF_RESKEY_CRM__meta_notify_promote_uname" #~ msgid "OCF_RESKEY_CRM_meta_notify_promote_uname" #~ msgstr "OCF_RESKEY_CRM_meta_notify_promote_uname" #~ msgid "Nodes on which resources will be promoted" #~ msgstr "Nodurile pe care resursele vor fi promovate" #~ msgid "Environment VariableOCF_RESKEY_CRM__meta_notify_demote_uname" #~ msgstr "Variabilă de MediuOCF_RESKEY_CRM__meta_notify_demote_uname" #~ msgid "OCF_RESKEY_CRM_meta_notify_demote_uname" #~ msgstr "OCF_RESKEY_CRM_meta_notify_demote_uname" #~ msgid "Nodes on which resources will be demoted" #~ msgstr "Nodurile pe care resursele vor fi degradate" #~ msgid "Environment VariableOCF_RESKEY_CRM__meta_notify_master_uname" #~ msgstr "Variabilă de MediuOCF_RESKEY_CRM__meta_notify_master_uname" #~ msgid "OCF_RESKEY_CRM_meta_notify_master_uname" #~ msgstr "OCF_RESKEY_CRM_meta_notify_master_uname" #~ msgid "Nodes on which resources are running in Master mode" #~ msgstr "Nodurile pe care resursele rulează în modul Master" #~ msgid "Environment VariableOCF_RESKEY_CRM__meta_notify_slave_uname" #~ msgstr "Variabilă de MediuOCF_RESKEY_CRM__meta_notify_slave_uname" #~ msgid "OCF_RESKEY_CRM_meta_notify_slave_uname" #~ msgstr "OCF_RESKEY_CRM_meta_notify_slave_uname" #~ msgid "Nodes on which resources are running in Slave mode" #~ msgstr "Nodurile pe care resursele rulează în modul Slave" pacemaker-master/doc/Pacemaker_Explained/ro-RO/Ch-Basics.po000066400000000000000000001072771217637305600240070ustar00rootroot00000000000000msgid "" msgstr "" "Project-Id-Version: Pacemaker 1.1\n" "POT-Creation-Date: 2012-10-17T05:19:02\n" "PO-Revision-Date: 2012-01-01T17:48:32\n" "Last-Translator: Dan Frîncu \n" "Language-Team: None\n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: application/x-publican; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. Tag: title #, no-c-format msgid "Configuration Basics" msgstr "Bazele Configurării" #. Tag: title #, no-c-format msgid "Configuration Layout" msgstr "Aşezarea Configuraţiei" #. Tag: para #, no-c-format msgid "The cluster is written using XML notation and divided into two main sections: configuration and status." msgstr "Clusterul este scris folosind notaţie XML şi este împărţit în două secţiuni principale: configurare şi status." #. Tag: para #, no-c-format msgid "The status section contains the history of each resource on each node and based on this data, the cluster can construct the complete current state of the cluster. The authoritative source for the status section is the local resource manager (lrmd) process on each cluster node and the cluster will occasionally repopulate the entire section. For this reason it is never written to disk and administrators are advised against modifying it in any way." msgstr "Secţiunea de status conţine istoricul fiecărei resurse de pe fiecare nod şi pe baza acestor date, clusterul poate construi starea curentă completă a clusterului. Sursa autoritativă pentru secţiunea de status este procesul managerului de resurse local (lrmd) pe fiecare nod din cluster iar clusterul va repopula în mod ocazional întreaga secţiune. Din acest motiv nu este scris niciodată pe disc iar administratorii sunt sfătuiţi împotriva modificării în orice fel a acestuia." #. Tag: para #, no-c-format msgid "The configuration section contains the more traditional information like cluster options, lists of resources and indications of where they should be placed. The configuration section is the primary focus of this document." msgstr "Secţiunea de configurare conţine informaţiile mai tradiţionale precum opţiuni ale clusterului, liste de resurse şi indicaţii despre unde ar trebui acestea plasate. Secţiunea de configurare este scopul primar al acestui document." #. Tag: para #, no-c-format msgid "The configuration section itself is divided into four parts:" msgstr "Secţiunea de configurare în sine este împărţită în patru părţi:" #. Tag: para #, no-c-format msgid "Configuration options (called crm_config)" msgstr "Opţiuni de configurare (numite crm_config)" #. Tag: para #, no-c-format msgid "Nodes" msgstr "Noduri" #. Tag: para #, no-c-format msgid "Resources" msgstr "Resurse" #. Tag: para #, no-c-format msgid "Resource relationships (called constraints)" msgstr "Relaţii între resurse (numite restricţii)" #. Tag: title #, no-c-format msgid "An empty configuration" msgstr "O configuraţie goală" #. Tag: programlisting #, fuzzy, no-c-format msgid "" " <cib admin_epoch=\"0\" epoch=\"0\" num_updates=\"0\" have-quorum=\"false\">\n" " <configuration>\n" " <crm_config/>\n" " <nodes/>\n" " <resources/>\n" " <constraints/>\n" " </configuration>\n" " <status/>\n" " </cib>" msgstr "" "\n" " <cib admin_epoch=\"0\" epoch=\"0\" num_updates=\"0\" have-quorum=\"false\">\n" " <configuration>\n" " <crm_config/>\n" " <nodes/>\n" " <resources/>\n" " <constraints/>\n" " </configuration>\n" " <status/>\n" " </cib>\n" "\n" " " #. Tag: title #, no-c-format msgid "The Current State of the Cluster" msgstr "Starea Curentă a Clusterului" #. Tag: para #, fuzzy, no-c-format msgid "Before one starts to configure a cluster, it is worth explaining how to view the finished product. For this purpose we have created the crm_mon utility that will display the current state of an active cluster. It can show the cluster status by node or by resource and can be used in either single-shot or dynamically-updating mode. There are also modes for displaying a list of the operations performed (grouped by node and resource) as well as information about failures." msgstr "Înainte de a începe să configurăm clusterul, merită explicat cum să vizualizăm produsul finit. Pentru acest scop am creat utilitarul crm_mon care va arăta starea curentă a unui cluster activ. Poate arăta statusul clusterului după nod sau după resurse şi poate fi folosit fie în mod single-shot (o singură listare) sau dynamically-updating (updatându-se dinamic). Sunt de asemenea moduri pentru prezentarea unei liste de operaţiuni efectuate (grupată după nod si resursă) precum şi informaţii despre eşecuri." #. Tag: para #, no-c-format msgid "Using this tool, you can examine the state of the cluster for irregularities and see how it responds when you cause or simulate failures." msgstr "Folosind acest utilitar, puteţi examina starea clusterului pentru neconcordanţe şi pentru a vedea cum răspunde atunci când provocaţi sau simulaţi eşecuri." #. Tag: para #, fuzzy, no-c-format msgid "Details on all the available options can be obtained using the crm_mon --help command." msgstr "Detalii despre toate opţiunile disponibile pot fi obţinute folosind comanda crm_mon --help." #. Tag: title #, no-c-format msgid "Sample output from crm_mon" msgstr "Exemplu de rezultat obţinut din crm_mon" #. Tag: screen #, fuzzy, no-c-format msgid "" " ============\n" " Last updated: Fri Nov 23 15:26:13 2007\n" " Current DC: sles-3 (2298606a-6a8c-499a-9d25-76242f7006ec)\n" " 3 Nodes configured.\n" " 5 Resources configured.\n" " ============\n" "\n" " Node: sles-1 (1186dc9a-324d-425a-966e-d757e693dc86): online\n" " 192.168.100.181 (heartbeat::ocf:IPaddr): Started sles-1\n" " 192.168.100.182 (heartbeat:IPaddr): Started sles-1\n" " 192.168.100.183 (heartbeat::ocf:IPaddr): Started sles-1\n" " rsc_sles-1 (heartbeat::ocf:IPaddr): Started sles-1\n" " child_DoFencing:2 (stonith:external/vmware): Started sles-1\n" " Node: sles-2 (02fb99a8-e30e-482f-b3ad-0fb3ce27d088): standby\n" " Node: sles-3 (2298606a-6a8c-499a-9d25-76242f7006ec): online\n" " rsc_sles-2 (heartbeat::ocf:IPaddr): Started sles-3\n" " rsc_sles-3 (heartbeat::ocf:IPaddr): Started sles-3\n" " child_DoFencing:0 (stonith:external/vmware): Started sles-3" msgstr "" "# crm_mon\n" " ============\n" " Last updated: Fri Nov 23 15:26:13 2007\n" " Current DC: sles-3 (2298606a-6a8c-499a-9d25-76242f7006ec)\n" " 3 Nodes configured.\n" " 5 Resources configured.\n" " ============\n" "\n" " Node: sles-1 (1186dc9a-324d-425a-966e-d757e693dc86): online\n" " 192.168.100.181 (heartbeat::ocf:IPaddr): Started sles-1\n" " 192.168.100.182 (heartbeat:IPaddr): Started sles-1\n" " 192.168.100.183 (heartbeat::ocf:IPaddr): Started sles-1\n" " rsc_sles-1 (heartbeat::ocf:IPaddr): Started sles-1\n" " child_DoFencing:2 (stonith:external/vmware): Started sles-1\n" " Node: sles-2 (02fb99a8-e30e-482f-b3ad-0fb3ce27d088): standby\n" " Node: sles-3 (2298606a-6a8c-499a-9d25-76242f7006ec): online\n" " rsc_sles-2 (heartbeat::ocf:IPaddr): Started sles-3\n" " rsc_sles-3 (heartbeat::ocf:IPaddr): Started sles-3\n" " child_DoFencing:0 (stonith:external/vmware): Started sles-3" #. Tag: title #, no-c-format msgid "Sample output from crm_mon -n" msgstr "Exemplu de rezultat obţinut din crm_mon -n" #. Tag: screen #, fuzzy, no-c-format msgid "" " ============\n" " Last updated: Fri Nov 23 15:26:13 2007\n" " Current DC: sles-3 (2298606a-6a8c-499a-9d25-76242f7006ec)\n" " 3 Nodes configured.\n" " 5 Resources configured.\n" " ============\n" "\n" " Node: sles-1 (1186dc9a-324d-425a-966e-d757e693dc86): online\n" " Node: sles-2 (02fb99a8-e30e-482f-b3ad-0fb3ce27d088): standby\n" " Node: sles-3 (2298606a-6a8c-499a-9d25-76242f7006ec): online\n" "\n" " Resource Group: group-1\n" " 192.168.100.181 (heartbeat::ocf:IPaddr): Started sles-1\n" " 192.168.100.182 (heartbeat:IPaddr): Started sles-1\n" " 192.168.100.183 (heartbeat::ocf:IPaddr): Started sles-1\n" " rsc_sles-1 (heartbeat::ocf:IPaddr): Started sles-1\n" " rsc_sles-2 (heartbeat::ocf:IPaddr): Started sles-3\n" " rsc_sles-3 (heartbeat::ocf:IPaddr): Started sles-3\n" " Clone Set: DoFencing\n" " child_DoFencing:0 (stonith:external/vmware): Started sles-3\n" " child_DoFencing:1 (stonith:external/vmware): Stopped\n" " child_DoFencing:2 (stonith:external/vmware): Started sles-1" msgstr "" "\n" "# crm_mon -n\n" " ============\n" " Last updated: Fri Nov 23 15:26:13 2007\n" " Current DC: sles-3 (2298606a-6a8c-499a-9d25-76242f7006ec)\n" " 3 Nodes configured.\n" " 5 Resources configured.\n" " ============\n" "\n" " Node: sles-1 (1186dc9a-324d-425a-966e-d757e693dc86): online\n" " Node: sles-2 (02fb99a8-e30e-482f-b3ad-0fb3ce27d088): standby\n" " Node: sles-3 (2298606a-6a8c-499a-9d25-76242f7006ec): online\n" "\n" " Resource Group: group-1\n" " 192.168.100.181 (heartbeat::ocf:IPaddr): Started sles-1\n" " 192.168.100.182 (heartbeat:IPaddr): Started sles-1\n" " 192.168.100.183 (heartbeat::ocf:IPaddr): Started sles-1\n" " rsc_sles-1 (heartbeat::ocf:IPaddr): Started sles-1\n" " rsc_sles-2 (heartbeat::ocf:IPaddr): Started sles-3\n" " rsc_sles-3 (heartbeat::ocf:IPaddr): Started sles-3\n" " Clone Set: DoFencing\n" " child_DoFencing:0 (stonith:external/vmware): Started sles-3\n" " child_DoFencing:1 (stonith:external/vmware): Stopped\n" " child_DoFencing:2 (stonith:external/vmware): Started sles-1" #. Tag: para #, no-c-format msgid "The DC (Designated Controller) node is where all the decisions are made and if the current DC fails a new one is elected from the remaining cluster nodes. The choice of DC is of no significance to an administrator beyond the fact that its logs will generally be more interesting." msgstr "Nodul DC (Designated Controller - Controller Desemnat) este locul unde toate deciziile sunt luate şi dacă DC-ul curent eşuează unul nou este ales din nodurile rămase în cluster. Alegerea unui DC nu are nici o semnificaţie pentru administrator dincolo de faptul că logurile acestuia vor fi în general mai interesante." #. Tag: title #, no-c-format msgid "How Should the Configuration be Updated?" msgstr "Cum Ar Trebui să fie Actualizată Configuraţia" #. Tag: para #, no-c-format msgid "There are three basic rules for updating the cluster configuration:" msgstr "Sunt trei reguli de bază pentru actualizarea configuraţiei clusterului:" #. Tag: para #, fuzzy, no-c-format msgid "Rule 1 - Never edit the cib.xml file manually. Ever. I’m not making this up." msgstr "Regula 1 - Nu editaţi niciodată fişierul cib.xml manual. Niciodată. Nu inventez acest lucru." #. Tag: para #, no-c-format msgid "Rule 2 - Read Rule 1 again." msgstr "Regula 2 - Citiţi Regula 1 din nou." #. Tag: para #, no-c-format msgid "Rule 3 - The cluster will notice if you ignored rules 1 & 2 and refuse to use the configuration." msgstr "Regula 3 - Clusterul va detecta că aţi ignorat regulile 1 & 2 şi va refuza să folosească configuraţia." #. Tag: para #, no-c-format msgid "Now that it is clear how NOT to update the configuration, we can begin to explain how you should." msgstr "Acum că este clar cum să NU actualizăm configuraţia, putem începe să explicăm cum ar trebui să realizăm acest lucru." #. Tag: para #, no-c-format msgid "The most powerful tool for modifying the configuration is the cibadmin command which talks to a running cluster. With cibadmin, the user can query, add, remove, update or replace any part of the configuration; all changes take effect immediately, so there is no need to perform a reload-like operation." msgstr "Cea mai puternică unealtă pentru modificarea configuraţiei este comanda cibadmin care comunică cu un cluster funcţional. Cu cibadmin, utilizatorul poate interoga, adăuga, înlătura, actualiza sau înlocui orice parte a configuraţiei; toate modificările iau efect imediat aşa că nu este necesar să executaţi operaţiuni de tip reîncărcare." #. Tag: para #, no-c-format msgid "The simplest way of using cibadmin is to use it to save the current configuration to a temporary file, edit that file with your favorite text or XML editor and then upload the revised configuration." msgstr "Cel mai simplu mod de a folosi cibadmin este de a-l folosi pentru a salva configuraţia curentă într-un fişier temporar, să editaţi acel fişier cu editorul de text sau XML favorit şi apoi să încărcaţi configuraţia revizuită." #. Tag: title #, no-c-format msgid "Safely using an editor to modify the cluster configuration" msgstr "Folosind cu siguranţă un editor pentru a modifica configuraţia clusterului" #. Tag: programlisting #, fuzzy, no-c-format msgid "" "# cibadmin --query > tmp.xml\n" "# vi tmp.xml\n" "# cibadmin --replace --xml-file tmp.xml" msgstr "" "cibadmin --query > tmp.xml\n" " vi tmp.xml\n" " cibadmin --replace --xml-file tmp.xml\n" " " #. Tag: para #, fuzzy, no-c-format msgid "Some of the better XML editors can make use of a Relax NG schema to help make sure any changes you make are valid. The schema describing the configuration can normally be found in /usr/lib/heartbeat/pacemaker.rng on most systems." msgstr "Unele dintre editoarele mai bune de XML pot folosi schema Relax NG pentru a vă ajuta să fiţi siguri că modificările pe care le realizaţi sunt valide. Schema care descrie configuraţia poate fi găsită în mod normal în /usr/lib/heartbeat/pacemaker.rng pe majoritatea sistemelor." #. Tag: para #, no-c-format msgid "If you only wanted to modify the resources section, you could instead do" msgstr "Dacă aţi dorit să modificaţi doar secţiunea de resurse, aţi putea alternativ să executaţi" #. Tag: title #, no-c-format msgid "Safely using an editor to modify a subsection of the cluster configuration" msgstr "Folosind cu siguranţă un editor pentru a modifica o subsecţiune din configuraţia clusterlui" #. Tag: programlisting #, fuzzy, no-c-format msgid "" "# cibadmin --query --obj_type resources > tmp.xml\n" "# vi tmp.xml\n" "# cibadmin --replace --obj_type resources --xml-file tmp.xml" msgstr "" "cibadmin --query --obj_type resources > tmp.xml\n" " vi tmp.xml\n" " cibadmin --replace --obj_type resources --xml-file tmp.xml\n" " " #. Tag: para #, no-c-format msgid "to avoid modifying any other part of the configuration." msgstr "pentru a evita modificările survenite la orice altă parte a configuraţiei." #. Tag: title #, no-c-format msgid "Quickly Deleting Part of the Configuration" msgstr "Ştergerea Rapidă a unei Părţi din Configuraţie" #. Tag: para #, fuzzy, no-c-format msgid "Identify the object you wish to delete. Eg. run" msgstr "Identificaţi obiectul pe care doriţi să îl ştergeţi. ex." #. Tag: title #, no-c-format msgid "Searching for STONITH related configuration items" msgstr "Căutând pentru elemente de configurare legate de STONITH" #. Tag: programlisting #, no-c-format msgid "# cibadmin -Q | grep stonith" msgstr "" #. Tag: programlisting #, fuzzy, no-c-format msgid "" " <nvpair id=\"cib-bootstrap-options-stonith-action\" name=\"stonith-action\" value=\"reboot\"/>\n" " <nvpair id=\"cib-bootstrap-options-stonith-enabled\" name=\"stonith-enabled\" value=\"1\"/>\n" " <primitive id=\"child_DoFencing\" class=\"stonith\" type=\"external/vmware\">\n" " <lrm_resource id=\"child_DoFencing:0\" type=\"external/vmware\" class=\"stonith\">\n" " <lrm_resource id=\"child_DoFencing:0\" type=\"external/vmware\" class=\"stonith\">\n" " <lrm_resource id=\"child_DoFencing:1\" type=\"external/vmware\" class=\"stonith\">\n" " <lrm_resource id=\"child_DoFencing:0\" type=\"external/vmware\" class=\"stonith\">\n" " <lrm_resource id=\"child_DoFencing:2\" type=\"external/vmware\" class=\"stonith\">\n" " <lrm_resource id=\"child_DoFencing:0\" type=\"external/vmware\" class=\"stonith\">\n" " <lrm_resource id=\"child_DoFencing:3\" type=\"external/vmware\" class=\"stonith\">" msgstr "" "# cibadmin -Q | grep stonith\n" "\n" " <nvpair id=\"cib-bootstrap-options-stonith-action\" name=\"stonith-action\" value=\"reboot\"/>\n" " <nvpair id=\"cib-bootstrap-options-stonith-enabled\" name=\"stonith-enabled\" value=\"1\"/>\n" " <primitive id=\"child_DoFencing\" class=\"stonith\" type=\"external/vmware\">\n" " <lrm_resource id=\"child_DoFencing:0\" type=\"external/vmware\" class=\"stonith\">\n" " <lrm_resource id=\"child_DoFencing:0\" type=\"external/vmware\" class=\"stonith\">\n" " <lrm_resource id=\"child_DoFencing:1\" type=\"external/vmware\" class=\"stonith\">\n" " <lrm_resource id=\"child_DoFencing:0\" type=\"external/vmware\" class=\"stonith\">\n" " <lrm_resource id=\"child_DoFencing:2\" type=\"external/vmware\" class=\"stonith\">\n" " <lrm_resource id=\"child_DoFencing:0\" type=\"external/vmware\" class=\"stonith\">\n" " <lrm_resource id=\"child_DoFencing:3\" type=\"external/vmware\" class=\"stonith\">\n" #. Tag: para #, fuzzy, no-c-format msgid "Next identify the resource’s tag name and id (in this case we’ll choose primitive and child_DoFencing). Then simply execute:" msgstr "Apoi identificaţi numele tag-ului resursei şi id-ul (în acest caz vom alege primitive şi child_DoFencing). Apoi executaţi:" #. Tag: programlisting #, fuzzy, no-c-format msgid "# cibadmin --delete --crm_xml '<primitive id=\"child_DoFencing\"/>'" msgstr "cibadmin --delete --crm_xml '<primitive id=\"child_DoFencing\"/>'" #. Tag: title #, no-c-format msgid "Updating the Configuration Without Using XML" msgstr "Updatând Configuraţia Fără să Folosim XML" #. Tag: para #, no-c-format msgid "Some common tasks can also be performed with one of the higher level tools that avoid the need to read or edit XML." msgstr "Câteva task-uri comune pot fi efectuate de asemenea cu unul dintre utilitarele de nivel înalt pentru a evita nevoia de a citi sau edita XML." #. Tag: para #, no-c-format msgid "To enable stonith for example, one could run:" msgstr "Pentru a activa stonith de exemplu, aţi putea rula:" #. Tag: programlisting #, fuzzy, no-c-format msgid "# crm_attribute --attr-name stonith-enabled --attr-value true" msgstr "crm_attribute --attr-name stonith-enabled --attr-value true" #. Tag: para #, no-c-format msgid "Or, to see if somenode is allowed to run resources, there is:" msgstr "Sau pentru a vedea dacă somenode îi este permis să ruleze resurse, există:" #. Tag: programlisting #, fuzzy, no-c-format msgid "# crm_standby --get-value --node-uname somenode" msgstr "crm_standby --get-value --node-uname somenode" #. Tag: para #, no-c-format msgid "Or, to find the current location of my-test-rsc, one can use:" msgstr "Sau pentru a afla locaţia curentă a my-test-rsc, aţi putea folosi:" #. Tag: programlisting #, fuzzy, no-c-format msgid "# crm_resource --locate --resource my-test-rsc" msgstr "crm_resource --locate --resource my-test-rsc" #. Tag: title #, no-c-format msgid "Making Configuration Changes in a Sandbox" msgstr "Realizând Modificări de Configurare într-un Sandbox" #. Tag: para #, fuzzy, no-c-format msgid "Often it is desirable to preview the effects of a series of changes before updating the configuration atomically. For this purpose we have created crm_shadow which creates a \"shadow\" copy of the configuration and arranges for all the command line tools to use it." msgstr "Deseori este de dorit să previzualizaţi efectele unei serii de modificări înainte să actualizaţi configuraţia în mod atomic. Pentru acest scop am creat crm_shadow care creează o copie \"ascunsă\" a configuraţiei şi aranjează astfel încât toate utilitarele din linia de comandă să o folosească." #. Tag: para #, fuzzy, no-c-format msgid "To begin, simply invoke crm_shadow and give it the name of a configuration to create Shadow copies are identified with a name, making it possible to have more than one. ; be sure to follow the simple on-screen instructions." msgstr "Pentru a începe, invocaţi pur şi simplu crm_shadow şi daţi-i numele unei configuraţii pe care să o creeze Copiile ascunse sunt identificate cu un nume, fiind posibil să avem mai mult de una. ; asiguraţi-vă că urmaţi simplele instrucţiuni de pe ecran." #. Tag: para #, fuzzy, no-c-format msgid "Read the above carefully, failure to do so could result in you destroying the cluster’s active configuration!" msgstr "Citiţi cele de mai sus cu atenţie, nerespectarea acestora poate rezulta în distrugerea de către voi a configuraţiei active a clusterului!" #. Tag: title #, no-c-format msgid "Creating and displaying the active sandbox" msgstr "Crearea şi prezentarea sandbox-ului activ" #. Tag: programlisting #, fuzzy, no-c-format msgid "" " # crm_shadow --create test\n" " Setting up shadow instance\n" " Type Ctrl-D to exit the crm_shadow shell\n" " shadow[test]:\n" " shadow[test] # crm_shadow --which\n" " test" msgstr "" " # crm_shadow --create test\n" " Setting up shadow instance\n" " Type Ctrl-D to exit the crm_shadow shell\n" " shadow[test]: \n" " shadow[test] # crm_shadow --which\n" " test" #. Tag: para #, fuzzy, no-c-format msgid "From this point on, all cluster commands will automatically use the shadow copy instead of talking to the cluster’s active configuration. Once you have finished experimenting, you can either commit the changes, or discard them as shown below. Again, be sure to follow the on-screen instructions carefully." msgstr "Din acest punct înainte, toate comenzile clusterului vor folosi în mod automat copia ascunsă în loc să comunice cu copia activă a configuraţiei clusterului. Odată ce aţi terminat de experimentat, puteţi fie să aplicaţi modificările sau să le înlăturaţi după cum este prezentat mai jos. Din nou, asiguraţi-vă că urmaţi instrucţiunile de pe ecran cu grijă." #. Tag: para #, fuzzy, no-c-format msgid "For a full list of crm_shadow options and commands, invoke it with the <parameter>--help</parameter> option." msgstr "Pentru o listă completă de opţiuni şi comenzi ale crm_shadow, apelaţi-l cu opţiunea --help." #. Tag: title #, no-c-format msgid "Using a sandbox to make multiple changes atomically" msgstr "Folosirea unui sandbox pentru a realiza mai multe modificări în mod atomic" #. Tag: programlisting #, fuzzy, no-c-format msgid "" " shadow[test] # crm_failcount -G -r rsc_c001n01\n" " name=fail-count-rsc_c001n01 value=0\n" " shadow[test] # crm_standby -v on -n c001n02\n" " shadow[test] # crm_standby -G -n c001n02\n" " name=c001n02 scope=nodes value=on\n" " shadow[test] # cibadmin --erase --force\n" " shadow[test] # cibadmin --query\n" " <cib cib_feature_revision=\"1\" validate-with=\"pacemaker-1.0\" admin_epoch=\"0\" crm_feature_set=\"3.0\" have-quorum=\"1\" epoch=\"112\"\n" " dc-uuid=\"c001n01\" num_updates=\"1\" cib-last-written=\"Fri Jun 27 12:17:10 2008\">\n" " <configuration>\n" " <crm_config/>\n" " <nodes/>\n" " <resources/>\n" " <constraints/>\n" " </configuration>\n" " <status/>\n" " </cib>\n" " shadow[test] # crm_shadow --delete test --force\n" " Now type Ctrl-D to exit the crm_shadow shell\n" " shadow[test] # exit\n" " # crm_shadow --which\n" " No shadow instance provided\n" " # cibadmin -Q\n" " <cib cib_feature_revision=\"1\" validate-with=\"pacemaker-1.0\" admin_epoch=\"0\" crm_feature_set=\"3.0\" have-quorum=\"1\" epoch=\"110\"\n" " dc-uuid=\"c001n01\" num_updates=\"551\">\n" " <configuration>\n" " <crm_config>\n" " <cluster_property_set id=\"cib-bootstrap-options\">\n" " <nvpair id=\"cib-bootstrap-1\" name=\"stonith-enabled\" value=\"1\"/>\n" " <nvpair id=\"cib-bootstrap-2\" name=\"pe-input-series-max\" value=\"30000\"/>" msgstr "" "shadow[test] # crm_failcount -G -r rsc_c001n01\n" " name=fail-count-rsc_c001n01 value=0\n" " shadow[test] # crm_standby -v on -n c001n02\n" " shadow[test] # crm_standby -G -n c001n02\n" " name=c001n02 scope=nodes value=on\n" " shadow[test] # cibadmin --erase --force\n" " shadow[test] # cibadmin --query\n" "\n" " <cib cib_feature_revision=\"1\" validate-with=\"pacemaker-1.0\" admin_epoch=\"0\" crm_feature_set=\"3.0\" have-quorum=\"1\" epoch=\"112\"\n" " dc-uuid=\"c001n01\" num_updates=\"1\" cib-last-written=\"Fri Jun 27 12:17:10 2008\">\n" " <configuration>\n" " <crm_config/>\n" " <nodes/>\n" " <resources/>\n" " <constraints/>\n" " </configuration>\n" " <status/>\n" " </cib>\n" "\n" " shadow[test] # crm_shadow --delete test --force\n" " Now type Ctrl-D to exit the crm_shadow shell\n" " shadow[test] # exit\n" " # crm_shadow --which\n" " No shadow instance provided\n" " # cibadmin -Q\n" "\n" " <cib cib_feature_revision=\"1\" validate-with=\"pacemaker-1.0\" admin_epoch=\"0\" crm_feature_set=\"3.0\" have-quorum=\"1\" epoch=\"110\"\n" " dc-uuid=\"c001n01\" num_updates=\"551\">\n" " <configuration>\n" " <crm_config>\n" " <cluster_property_set id=\"cib-bootstrap-options\">\n" " <nvpair id=\"cib-bootstrap-1\" name=\"stonith-enabled\" value=\"1\"/>\n" " <nvpair id=\"cib-bootstrap-2\" name=\"pe-input-series-max\" value=\"30000\"/>\n" "\n" "\t" #. Tag: para #, no-c-format msgid "Making changes in a sandbox and verifying the real configuration is untouched" msgstr "Realizarea de modificări într-un sandbox şi apoi verificarea că, configuraţia reală nu este atinsă." #. Tag: title #, no-c-format msgid "Testing Your Configuration Changes" msgstr "Testarea Modificărilor Voastre de Configurare" #. Tag: para #, fuzzy, no-c-format msgid "We saw previously how to make a series of changes to a \"shadow\" copy of the configuration. Before loading the changes back into the cluster (eg. crm_shadow --commit mytest --force), it is often advisable to simulate the effect of the changes with crm_simulate, eg." msgstr "Am văzut anterior cum să realizăm o serie de modificări într-o copie \"ascunsă\" a configuraţiei. Înainte de a încărca modificările înapoi în cluster (ex. crm_shadow --commit mytest --force), este adeseori recomandat să simulaţi efectul modificărilor cu ptest, ex." #. Tag: programlisting #, fuzzy, no-c-format msgid "# crm_simulate --live-check -VVVVV --save-graph tmp.graph --save-dotfile tmp.dot" msgstr "ptest --live-check -VVVVV --save-graph tmp.graph --save-dotfile tmp.dot" #. Tag: para #, fuzzy, no-c-format msgid "The tool uses the same library as the live cluster to show what it would have done given the supplied input. It’s output, in addition to a significant amount of logging, is stored in two files tmp.graph and tmp.dot, both are representations of the same thing — the cluster’s response to your changes." msgstr "Utilitarul foloseşte aceeaşi bibliotecă precum clusterul activ pentru a arăta ce ar fi realizat cu informaţiile primite. Rezultatul de ieşire, suplimentar la o cantitate semnificativă de loguri, este stocat în două fişiere tmp.graph şi tmp.dot, ambele sunt reprezentări ale aceluiaşi lucru -- răspunsul clusterului la modificările voastre. În fişierul graf este stocată tranziţia completă, conţinând o listă cu toate acţiunile, parametrii acestora şi cerinţele premergătoare ale acestora. Pentru că graful de tranziţie nu este foarte uşor de citit, utilitarul generează un fişier Graphviz dot de asemenea reprezentând aceleaşi informaţii." #. Tag: para #, fuzzy, no-c-format msgid "In the graph file is stored the complete transition, containing a list of all the actions, their parameters and their pre-requisites. Because the transition graph is not terribly easy to read, the tool also generates a Graphviz dot-file representing the same information." msgstr "Utilitarul foloseşte aceeaşi bibliotecă precum clusterul activ pentru a arăta ce ar fi realizat cu informaţiile primite. Rezultatul de ieşire, suplimentar la o cantitate semnificativă de loguri, este stocat în două fişiere tmp.graph şi tmp.dot, ambele sunt reprezentări ale aceluiaşi lucru -- răspunsul clusterului la modificările voastre. În fişierul graf este stocată tranziţia completă, conţinând o listă cu toate acţiunile, parametrii acestora şi cerinţele premergătoare ale acestora. Pentru că graful de tranziţie nu este foarte uşor de citit, utilitarul generează un fişier Graphviz dot de asemenea reprezentând aceleaşi informaţii." #. Tag: title #, no-c-format msgid "Interpreting the Graphviz output" msgstr "Interpretarea rezultatului de ieşire al Graphviz" #. Tag: para #, no-c-format msgid "Arrows indicate ordering dependencies" msgstr "Săgeţile indică dependinţele de ordonare" #. Tag: para #, no-c-format msgid "Dashed-arrows indicate dependencies that are not present in the transition graph" msgstr "Săgeţile întrerupte de cratime indică dependinţe care nu sunt prezente în graful de tranziţie" #. Tag: para #, no-c-format msgid "Actions with a dashed border of any color do not form part of the transition graph" msgstr "Acţiunile cu o margine întreruptă cu cratime de orice culoare nu se formează ca parte a grafului de tranziţie" #. Tag: para #, no-c-format msgid "Actions with a green border form part of the transition graph" msgstr "Acţiunile cu o margine verde se formează ca parte a grafului de tranziţie" #. Tag: para #, no-c-format msgid "Actions with a red border are ones the cluster would like to execute but cannot run" msgstr "Acţiunile cu o margine roşie sunt cele pe care clusterul ar dori să le execute dar sunt neexecutabile" #. Tag: para #, no-c-format msgid "Actions with a blue border are ones the cluster does not feel need to be executed" msgstr "Acţiunile cu o margine albastră sunt cele pe care clusterul nu consideră că trebuie executate" #. Tag: para #, no-c-format msgid "Actions with orange text are pseudo/pretend actions that the cluster uses to simplify the graph" msgstr "Acţiunile cu text portocaliu sunt acţiuni pseudo/de prefacere pe care clusterul le foloseşte pentru a simplifica graful" #. Tag: para #, no-c-format msgid "Actions with black text are sent to the LRM" msgstr "Acţiunile cu text negru sunt trimise la LRM" #. Tag: para #, no-c-format msgid "Resource actions have text of the form rsc_action_interval node" msgstr "Acţiunile resurselor au textul de forma rsc_action_intervalnode" #. Tag: para #, no-c-format msgid "Any action depending on an action with a red border will not be able to execute." msgstr "Orice acţiune care depine de o acţiune cu o margine roşie nu va putea să se execute." #. Tag: para #, no-c-format msgid "Loops are really bad. Please report them to the development team." msgstr "Buclele de execuţie sunt foarte rele. Vă rugăm să le raportaţi echipei de dezvoltare." #. Tag: title #, no-c-format msgid "Small Cluster Transition" msgstr "Tranziţia unui Cluster Mic" #. Tag: phrase #, no-c-format msgid "An example transition graph as represented by Graphviz" msgstr "Un exemplu de graf de tranziţie aşa cum este reprezentat de Graphviz" #. Tag: para #, no-c-format msgid "In the above example, it appears that a new node, node2, has come online and that the cluster is checking to make sure rsc1, rsc2 and rsc3 are not already running there (Indicated by the *_monitor_0 entries). Once it did that, and assuming the resources were not active there, it would have liked to stop rsc1 and rsc2 on node1 and move them to node2. However, there appears to be some problem and the cluster cannot or is not permitted to perform the stop actions which implies it also cannot perform the start actions. For some reason the cluster does not want to start rsc3 anywhere." msgstr "În exemplul de mai sus, se pare că un nod nou, node2, a ajuns online şi clusterul verifică să se asigure că rsc1, rsc2 şi rsc3, nu rulează deja acolo (aspect indicat de intrările *_monitor_0). Odată ce a realizat acest lucru şi mergând pe presupunerea că resursele nu erau active acolo, ar fi preferat să oprească rsc1 şi rsc2 pe node1 şi să le mute pe node2. Totuşi se pare că există o problemă şi clusterul nu poate sau nu îi este permis să execute operaţiunile de oprire, fapt care implică neputinţa de a efectua acţiunile de pornire de asemenea. Pentru un motiv anume clusterul nu vrea să pornească rsc3 nicăieri." #. Tag: para #, fuzzy, no-c-format msgid "For information on the options supported by crm_simulate, use the --help option." msgstr "Pentru informaţii legate de opţiunile suportate de ptest, folosiţi ptest --help" #. Tag: title #, no-c-format msgid "Complex Cluster Transition" msgstr "Tranziţii Complexe ale Clusterului" #. Tag: phrase #, no-c-format msgid "Another, slightly more complex, transition graph that you're not expected to be able to read" msgstr "Un alt graf de tranziţie, ceva mai complex, pe care nu sunteţi aşteaptaţi să îl puteţi citi" #. Tag: title #, no-c-format msgid "Do I Need to Update the Configuration on all Cluster Nodes?" msgstr "Trebuie să Actualizez Configuraţia pe toate Nodurile Clusterului?" #. Tag: para #, no-c-format msgid "No. Any changes are immediately synchronized to the other active members of the cluster." msgstr "Nu. Orice modificări sunt sincronizate imediat către ceilalţi membri activi ai clusterului." #. Tag: para #, no-c-format msgid "To reduce bandwidth, the cluster only broadcasts the incremental updates that result from your changes and uses MD5 checksums to ensure that each copy is completely consistent." msgstr "Pentru a reduce consumul de lăţime de bandă, clusterul transmite numai actualizările incrementale care rezultă din modificările realizate de voi şi foloseşte hash-uri MD5 pentru a se asigura că fiecare copie este complet consistentă." pacemaker-master/doc/Pacemaker_Explained/ro-RO/Ch-Constraints.po000066400000000000000000001623101217637305600250770ustar00rootroot00000000000000msgid "" msgstr "" "Project-Id-Version: Pacemaker 1.1\n" "POT-Creation-Date: 2012-10-17T05:19:02\n" "PO-Revision-Date: 2012-01-01T17:48:32\n" "Last-Translator: Dan Frîncu \n" "Language-Team: None\n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: application/x-publican; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. Tag: title #, no-c-format msgid "Resource Constraints" msgstr "Restricţiile Resurselor" #. Tag: para #, fuzzy, no-c-format msgid " ResourceConstraints Constraints " msgstr "scorCâmp de Restricție Constraint Fieldscor scor" #. Tag: title #, no-c-format msgid "Scores" msgstr "Scoruri" #. Tag: para #, no-c-format msgid "Scores of all kinds are integral to how the cluster works. Practically everything from moving a resource to deciding which resource to stop in a degraded cluster is achieved by manipulating scores in some way." msgstr "Scorurile de toate tipurile sunt parte integrală din cum funcţionează clusterul. Practic orice de la mutarea unei resurse la a decide care resursă să fie oprită într-un cluster degradat este atinsă prin manipularea scorurilor în vreun fel." #. Tag: para #, fuzzy, no-c-format msgid "Scores are calculated on a per-resource basis and any node with a negative score for a resource can’t run that resource. After calculating the scores for a resource, the cluster then chooses the node with the highest one." msgstr "Scorurile sunt calculate la nivel de resursă şi orice nod cu un scor negativ pentru o resursă nu poate rula acea resursă. După calcularea scorurilor pentru o resursă, clusterul alege mai apoi nodul cu scorul cel mai mare." #. Tag: title #, no-c-format msgid "Infinity Math" msgstr "Matematica Infinitului" #. Tag: para #, no-c-format msgid "INFINITY is currently defined as 1,000,000 and addition/subtraction with it follows these three basic rules:" msgstr "INFINITY este definit în mod curent ca 1,000,000 şi adunarea/scăderea din acesta urmează următoarele 3 reguli de bază:" #. Tag: para #, no-c-format msgid "Any value + INFINITY = INFINITY" msgstr "Orice valoare + INFINITY = INFINITY " #. Tag: para #, no-c-format msgid "Any value - INFINITY = -INFINITY" msgstr "Orice valoare - INFINITY = -INFINITY" #. Tag: para #, no-c-format msgid "INFINITY - INFINITY = -INFINITY" msgstr "INFINITY - INFINITY = -INFINITY" #. Tag: title #, no-c-format msgid "Deciding Which Nodes a Resource Can Run On" msgstr "Decizând pe Care Noduri Poate Rula o Resursă" #. Tag: para #, fuzzy, no-c-format msgid " Location Constraints ResourceConstraintsLocation ConstraintsLocation Location There are two alternative strategies for specifying which nodes a resources can run on. One way is to say that by default they can run anywhere and then create location constraints for nodes that are not allowed. The other option is to have nodes \"opt-in\"… to start with nothing able to run anywhere and selectively enable allowed nodes." msgstr "Sunt două strategii alternative pentru specificarea nodurilor pe care poate rula o resursă. Un mod este acela de a spune că în mod implicit acestea pot rula oriunde şi apoi să se creeze restricţii de locaţie pentru nodurile pe care acestea nu sunt permise. Cealaltă opţiune este cea de a avea noduri care să \"opt-in\"... de a porni fără a permite la nimic de a rula nicăieri şi de a activa în mod selectiv nodurile permise." #. Tag: title #, no-c-format msgid "Options" msgstr "Opţiuni" #. Tag: title #, no-c-format msgid "Options for Simple Location Constraints" msgstr "Opţiuni pentru Restricţii Simple de Locaţie" #. Tag: entry #, no-c-format msgid "Field" msgstr "Câmp" #. Tag: entry #, no-c-format msgid "Description" msgstr "Descriere" #. Tag: para #, no-c-format msgid "id" msgstr "" #. Tag: para #, no-c-format msgid "A unique name for the constraint idLocation Constraints Location Constraints ConstraintsLocationid Locationid id " msgstr "" #. Tag: para #, no-c-format msgid "rsc" msgstr "" #. Tag: para #, no-c-format msgid "A resource name rscLocation Constraints Location Constraints ConstraintsLocationrsc Locationrsc rsc " msgstr "" #. Tag: para #, no-c-format msgid "node" msgstr "" #. Tag: para #, no-c-format msgid "A node’s name nodeLocation Constraints Location Constraints ConstraintsLocationnode Locationnode node " msgstr "" #. Tag: para #, no-c-format msgid "score" msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "Positive values indicate the resource should run on this node. Negative values indicate the resource should not run on this node." msgstr "Valorile pozitive indică faptul că resursa ar trebui să ruleze pe acelaşi nod. Valorile negative indică faptul că resursele ar trebui să nu ruleze pe acelaşi nod. Valorile +/- INFINITY schimbâ \"ar trebui\" în \"trebuie\"." #. Tag: para #, no-c-format msgid "Values of +/- INFINITY change \"should\"/\"should not\" to \"must\"/\"must not\". scoreLocation Constraints Location Constraints ConstraintsLocationscore Locationscore score " msgstr "" #. Tag: title #, no-c-format msgid "Asymmetrical \"Opt-In\" Clusters" msgstr "" #. Tag: para #, fuzzy, no-c-format msgid " Asymmetrical Opt-In Clusters Cluster TypeAsymmetrical Opt-In Asymmetrical Opt-In " msgstr "Clustere Opt-In Asimetrice Tip de ClusterOpt-In Asimetric Clustere \"Opt-In\" Asimetrice" #. Tag: para #, no-c-format msgid "To create an opt-in cluster, start by preventing resources from running anywhere by default:" msgstr "Pentru a crea un cluster opt-in, porniţi prin a împiedica resursele din a rula oriunde în mod implicit:" #. Tag: programlisting #, fuzzy, no-c-format msgid "# crm_attribute --attr-name symmetric-cluster --attr-value false" msgstr "crm_attribute --attr-name symmetric-cluster --attr-value false" #. Tag: para #, no-c-format msgid "Then start enabling nodes. The following fragment says that the web server prefers sles-1, the database prefers sles-2 and both can fail over to sles-3 if their most preferred node fails." msgstr "Apoi începeţi să activaţi noduri. Fragmentul următor spune că serverul web preferă sles-1, baza de date preferă sles-2 şi ambele pot face failover pe sles-3 dacă nodul lor cu cea mai mare preferinţă eşuează." #. Tag: title #, no-c-format msgid "Example set of opt-in location constraints" msgstr "Exemplu de restricţii de locaţie opt-in" #. Tag: programlisting #, fuzzy, no-c-format msgid "" "<constraints>\n" " <rsc_location id=\"loc-1\" rsc=\"Webserver\" node=\"sles-1\" score=\"200\"/>\n" " <rsc_location id=\"loc-2\" rsc=\"Webserver\" node=\"sles-3\" score=\"0\"/>\n" " <rsc_location id=\"loc-3\" rsc=\"Database\" node=\"sles-2\" score=\"200\"/>\n" " <rsc_location id=\"loc-4\" rsc=\"Database\" node=\"sles-3\" score=\"0\"/>\n" "</constraints>" msgstr "" "<constraints>\n" " <rsc_location id=\"loc-1\" rsc=\"Webserver\" node=\"sles-1\" score=\"200\"/>\n" " <rsc_location id=\"loc-2\" rsc=\"Webserver\" node=\"sles-3\" score=\"0\"/>\n" " <rsc_location id=\"loc-3\" rsc=\"Database\" node=\"sles-2\" score=\"200\"/>\n" " <rsc_location id=\"loc-4\" rsc=\"Database\" node=\"sles-3\" score=\"0\"/>\n" " </constraints> " #. Tag: title #, no-c-format msgid "Symmetrical \"Opt-Out\" Clusters" msgstr "" #. Tag: para #, fuzzy, no-c-format msgid " Symmetrical Opt-Out Clusters Cluster TypeSymmetrical Opt-Out Symmetrical Opt-Out " msgstr "Clustere Opt-Out Simetrice Tip de ClusterOpt-Out Simetrice Clustere \"Opt-Out\" Simetrice" #. Tag: para #, fuzzy, no-c-format msgid "To create an opt-out cluster, start by allowing resources to run anywhere by default:" msgstr "Pentru a crea un cluster opt-out, începeţi prin a permite resurselor să ruleze oriunde în mod implicit" #. Tag: programlisting #, fuzzy, no-c-format msgid "# crm_attribute --attr-name symmetric-cluster --attr-value true" msgstr "crm_attribute --attr-name symmetric-cluster --attr-value true" #. Tag: para #, no-c-format msgid "Then start disabling nodes. The following fragment is the equivalent of the above opt-in configuration." msgstr "Apoi începeţi să dezactivaţi noduri. Următorul fragment este echivalentul configuraţiei opt-in de mai sus." #. Tag: title #, no-c-format msgid "Example set of opt-out location constraints" msgstr "Exemplu de restricţii de locaţie opt-out" #. Tag: programlisting #, fuzzy, no-c-format msgid "" "<constraints>\n" " <rsc_location id=\"loc-1\" rsc=\"Webserver\" node=\"sles-1\" score=\"200\"/>\n" " <rsc_location id=\"loc-2-dont-run\" rsc=\"Webserver\" node=\"sles-2\" score=\"-INFINITY\"/>\n" " <rsc_location id=\"loc-3-dont-run\" rsc=\"Database\" node=\"sles-1\" score=\"-INFINITY\"/>\n" " <rsc_location id=\"loc-4\" rsc=\"Database\" node=\"sles-2\" score=\"200\"/>\n" "</constraints>" msgstr "" " <constraints>\n" " <rsc_location id=\"loc-1\" rsc=\"Webserver\" node=\"sles-1\" score=\"200\"/>\n" " <rsc_location id=\"loc-2-dont-run\" rsc=\"Webserver\" node=\"sles-2\" score=\"-INFINITY\"/>\n" " <rsc_location id=\"loc-3-dont-run\" rsc=\"Database\" node=\"sles-1\" score=\"-INFINITY\"/>\n" " <rsc_location id=\"loc-4\" rsc=\"Database\" node=\"sles-2\" score=\"200\"/>\n" " </constraints> " #. Tag: para #, no-c-format msgid "Whether you should choose opt-in or opt-out depends both on your personal preference and the make-up of your cluster. If most of your resources can run on most of the nodes, then an opt-out arrangement is likely to result in a simpler configuration. On the other-hand, if most resources can only run on a small subset of nodes an opt-in configuration might be simpler." msgstr "Fie că ar trebui să alegeţi opt-in sau opt-out depinde atât de preferinţele voastre personale cât şi de structura clusterului vostru. Dacă majoritatea resurselor pot rula pe majoritatea nodurilor, atunci un aranjament opt-out va rezulta într-o configuraţie mai simplă. Pe partea cealaltă, dacă majoritatea resurselor pot rula doar pe un subset mic de noduri o configuraţie opt-in ar putea fi mai simplă." #. Tag: title #, no-c-format msgid "What if Two Nodes Have the Same Score" msgstr "Dacă Două Noduri Au Acelaşi Scor" #. Tag: para #, no-c-format msgid "If two nodes have the same score, then the cluster will choose one. This choice may seem random and may not be what was intended, however the cluster was not given enough information to know any better." msgstr "Dacă două noduri au acelaşi scor, atunci clusterul va alege unul. Această alegere poate părea aleatorie şi ar putea să nu fie ceea ce s-a intenţionat, în schimb clusterului nu i-a fost dată suficientă informaţie pentru a şti care a fost intenţia." #. Tag: title #, no-c-format msgid "Example of two resources that prefer two nodes equally" msgstr "Exemplu de două resurse care preferă două noduri în mod egal" #. Tag: programlisting #, fuzzy, no-c-format msgid "" "<constraints>\n" " <rsc_location id=\"loc-1\" rsc=\"Webserver\" node=\"sles-1\" score=\"INFINITY\"/>\n" " <rsc_location id=\"loc-2\" rsc=\"Webserver\" node=\"sles-2\" score=\"INFINITY\"/>\n" " <rsc_location id=\"loc-3\" rsc=\"Database\" node=\"sles-1\" score=\"500\"/>\n" " <rsc_location id=\"loc-4\" rsc=\"Database\" node=\"sles-2\" score=\"300\"/>\n" " <rsc_location id=\"loc-5\" rsc=\"Database\" node=\"sles-2\" score=\"200\"/>\n" "</constraints>" msgstr "" " <constraints>\n" " <rsc_location id=\"loc-1\" rsc=\"Webserver\" node=\"sles-1\" score=\"INFINITY\"/>\n" " <rsc_location id=\"loc-2\" rsc=\"Webserver\" node=\"sles-2\" score=\"INFINITY\"/>\n" " <rsc_location id=\"loc-3\" rsc=\"Database\" node=\"sles-1\" score=\"500\"/>\n" " <rsc_location id=\"loc-4\" rsc=\"Database\" node=\"sles-2\" score=\"300\"/>\n" " <rsc_location id=\"loc-5\" rsc=\"Database\" node=\"sles-2\" score=\"200\"/>\n" " </constraints> " #. Tag: para #, fuzzy, no-c-format msgid "In the example above, assuming no other constraints and an inactive cluster, Webserver would probably be placed on sles-1 and Database on sles-2. It would likely have placed Webserver based on the node’s uname and Database based on the desire to spread the resource load evenly across the cluster. However other factors can also be involved in more complex configurations." msgstr "În exemplul de mai sus, mergând pe presupunerea că nu sunt alte restricţii şi un cluster inactiv, Webserver ar fi probabil plasat pe sles-1 şi Database pe sles-2. Este probabil să fi plasat Webserver pe baza uname-ului nodului şi Database bazat pe dorinţa de a împrăştia încărcarea cu resurse în mod egal de-a lungul clusterului. Totuşi alţi factori pot fi implicaţi de asemenea în configuraţii mai complexe." #. Tag: title #, no-c-format msgid "Specifying in which Order Resources Should Start/Stop" msgstr "Specificând Ordinea în care Resursele ar Trebui să Pornească/Oprească" #. Tag: para #, no-c-format msgid " ResourceConstraintsOrdering ConstraintsOrdering Ordering ResourceStart Order Start Order Ordering Constraints The way to specify the order in which resources should start is by creating rsc_order constraints." msgstr "" #. Tag: title #, no-c-format msgid "Properties of an Ordering Constraint" msgstr "Proprietăţile unei Restricţii de Ordonare" #. Tag: para #, no-c-format msgid "A unique name for the constraint idOrdering Constraints Ordering Constraints ConstraintsOrderingid Orderingid id " msgstr "" #. Tag: para #, no-c-format msgid "first" msgstr "" #. Tag: para #, no-c-format msgid "The name of a resource that must be started before the then resource is allowed to. firstOrdering Constraints Ordering Constraints ConstraintsOrderingfirst Orderingfirst first " msgstr "" #. Tag: para #, no-c-format msgid "then" msgstr "" #. Tag: para #, no-c-format msgid "The name of a resource. This resource will start after the first resource. thenOrdering Constraints Ordering Constraints ConstraintsOrderingthen Orderingthen then " msgstr "" #. Tag: para #, no-c-format msgid "kind" msgstr "" #. Tag: para #, no-c-format msgid "How to enforce the constraint. (Since 1.1.2)" msgstr "" #. Tag: para #, no-c-format msgid "* Optional - Just a suggestion. Only applies if both resources are starting/stopping." msgstr "" #. Tag: para #, no-c-format msgid "* Mandatory - Always. If first is stopping or cannot be started, then must be stopped." msgstr "" #. Tag: para #, no-c-format msgid "* Serialize - Ensure that no two stop/start actions occur concurrently for a set of resources." msgstr "" #. Tag: para #, no-c-format msgid " kindOrdering Constraints Ordering Constraints ConstraintsOrderingkind Orderingkind kind " msgstr "" #. Tag: para #, no-c-format msgid "symmetrical" msgstr "" #. Tag: para #, no-c-format msgid "If true, which is the default, stop the resources in the reverse order. Default value: true symmetricalOrdering Constraints Ordering Constraints Ordering Constraintssymmetrical symmetrical " msgstr "" #. Tag: title #, no-c-format msgid "Mandatory Ordering" msgstr "Ordonarea Obligatorie" #. Tag: para #, no-c-format msgid "When the then resource cannot run without the first resource being active, one should use mandatory constraints. To specify a constraint is mandatory, use scores greater than zero. This will ensure that the then resource will react when the first resource changes state." msgstr "Când resursa then nu poate rula fără ca resursa first să fie activă, ar trebui să folosiţi restricţii obligatorii. Pentru a specifica faptul că o restricţie este obligatorie, folosiţi scoruri mai mari decât zero. Acest lucru va asigura că resursa \"then\" va reacţiona atunci când resursa \"first\" îşi schimbă starea." #. Tag: para #, no-c-format msgid "If the first resource was running and is stopped, the then resource will also be stopped (if it is running)." msgstr "Dacâ resursa first rula şi este oprită, resursa then va fi oprită de asemenea (dacă rulează)" #. Tag: para #, no-c-format msgid "If the first resource was not running and cannot be started, the then resource will be stopped (if it is running)." msgstr "Dacă resursa first nu rula şi nu poate fi pornită, resursa then va fi oprită (dacă rulează)" #. Tag: para #, no-c-format msgid "If the first resource is (re)started while the then resource is running, the then resource will be stopped and restarted." msgstr "Dacă resursa first este (re)pornită în timp ce resursa then rulează, resursa then va fi oprită şi repornită" #. Tag: title #, no-c-format msgid "Advisory Ordering" msgstr "Ordonare Recomandată" #. Tag: para #, no-c-format msgid "On the other hand, when score=\"0\" is specified for a constraint, the constraint is considered optional and only has an effect when both resources are stopping and/or starting. Any change in state by the first resource will have no effect on the then resource." msgstr "Pe altă parte, când score=\"0\" este specificat pentru o restricţie, restricţia este considerată opţională şi are efect doar când ambele resurse sunt oprite sau pornite. Orice modificare a stării resursei first nu va avea nici un efect asupra resursei then." #. Tag: title #, no-c-format msgid "Example of an optional and mandatory ordering constraint" msgstr "Exemplu de restricţie de ordonare obligatorie şi recomandată" #. Tag: programlisting #, fuzzy, no-c-format msgid "" "<constraints>\n" " <rsc_order id=\"order-1\" first=\"Database\" then=\"Webserver\" />\n" " <rsc_order id=\"order-2\" first=\"IP\" then=\"Webserver\" score=\"0\"/>\n" "</constraints>" msgstr "" " <constraints>\n" " <rsc_order id=\"order-1\" first=\"Database\" then=\"Webserver\" />\n" " <rsc_order id=\"order-2\" first=\"IP\" then=\"Webserver\" score=\"0\"/>\n" " </constraints> " #. Tag: para #, no-c-format msgid "Some additional information on ordering constraints can be found in the document Ordering Explained." msgstr "Informaţii adiţionale despre restricţiile de ordonare pot fi găsite în documentul Ordonarea Explicată" #. Tag: title #, no-c-format msgid "Placing Resources Relative to other Resources" msgstr "Plasarea Resurselor Relativă la alte Resurse" #. Tag: para #, no-c-format msgid " ResourceConstraintsColocation ConstraintsColocation Colocation ResourceLocation Relative to other Resources Location Relative to other Resources When the location of one resource depends on the location of another one, we call this colocation." msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "There is an important side-effect of creating a colocation constraint between two resources: it affects the order in which resources are assigned to a node. If you think about it, it’s somewhat obvious. You can’t place A relative to B unless you know where B is. While the human brain is sophisticated enough to read the constraint in any order and choose the correct one depending on the situation, the cluster is not quite so smart. Yet. " msgstr "Există un efect secundar important ca urmare a creării unei restricţii de colocare între două resurse, şi anume acela că afectează ordinea în care resursele sunt asignate unui nod. Dacă stai să te gândeşti, este oarecum evident. Nu poţi plasa A relativ la B decât dacă ştii unde B este În timp ce creierul uman este destul de sofisticat pentru a citi o restricţie în orice ordine şi de a alege pe cea corectă în funcţie de situaţie, clusterul nu este atât de inteligent. Încă. . Aşa că atunci când creaţi restricţii de colocare, este important să ţineţi cont de dacă vreţi să colocaţi A cu B sau B cu A." #. Tag: para #, no-c-format msgid "So when you are creating colocation constraints, it is important to consider whether you should colocate A with B or B with A." msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "Another thing to keep in mind is that, assuming A is collocated with B, the cluster will also take into account A’s preferences when deciding which node to choose for B." msgstr "Un alt aspect care merită reţinut este acela că, presupunând că A este colocat cu B, clusterul va lua în considerare preferinţele lui A când va decide care nod să aleagă pentru B. Pentru o vedere detaliată asupra modului exact în care se întâmplă acest lucru, vedeţi documentul Colocarea Explicată." #. Tag: para #, fuzzy, no-c-format msgid "For a detailed look at exactly how this occurs, see the Colocation Explained document." msgstr "Un alt aspect care merită reţinut este acela că, presupunând că A este colocat cu B, clusterul va lua în considerare preferinţele lui A când va decide care nod să aleagă pentru B. Pentru o vedere detaliată asupra modului exact în care se întâmplă acest lucru, vedeţi documentul Colocarea Explicată." #. Tag: title #, no-c-format msgid "Properties of a Collocation Constraint" msgstr "Proprietăţile unei Restricţii de Colocare" #. Tag: para #, no-c-format msgid "A unique name for the constraint. idColocation Constraints Colocation Constraints ConstraintsColocationid Colocationid id " msgstr "" #. Tag: para #, no-c-format msgid "The colocation source. If the constraint cannot be satisfied, the cluster may decide not to allow the resource to run at all. rscColocation Constraints Colocation Constraints ConstraintsColocationrsc Colocationrsc rsc " msgstr "" #. Tag: para #, no-c-format msgid "with-rsc" msgstr "" #. Tag: para #, no-c-format msgid "The colocation target. The cluster will decide where to put this resource first and then decide where to put the resource in the rsc field. with-rscColocation Constraints Colocation Constraints ConstraintsColocationwith-rsc Colocationwith-rsc with-rsc " msgstr "" #. Tag: para #, no-c-format msgid "Positive values indicate the resource should run on the same node. Negative values indicate the resources should not run on the same node. Values of +/- INFINITY change \"should\" to \"must\". scoreColocation Constraints Colocation Constraints ConstraintsColocationscore Colocationscore score " msgstr "" #. Tag: title #, no-c-format msgid "Mandatory Placement" msgstr "Plasament Obligatoriu" #. Tag: para #, fuzzy, no-c-format msgid "Mandatory placement occurs any time the constraint’s score is +INFINITY or -INFINITY. In such cases, if the constraint can’t be satisfied, then the rsc resource is not permitted to run. For score=INFINITY, this includes cases where the with-rsc resource is not active." msgstr "Plasamentul obligatoriu se întâmplă oricând scorul restricţiei este +INFINITY sau -INFINITY. În astfel de cazuri, dacă restricţia poate fi satisfăcută, atunci resursei rsc nu îi este permis să ruleze. Pentru scor=INFINITY, acest aspect include cazuri în care resursa with-rsc nu este activă." #. Tag: para #, no-c-format msgid "If you need resource1 to always run on the same machine as resource2, you would add the following constraint:" msgstr "Dacă aveţi nevoie ca resource1 să ruleze întotdeauna pe aceeaşi maşină ca şi resource2, aţi adăuga următoarea restricţie:" #. Tag: title #, no-c-format msgid "An example colocation constraint" msgstr "Un exemplu de restricţie de colocare" #. Tag: programlisting #, fuzzy, no-c-format msgid "<rsc_colocation id=\"colocate\" rsc=\"resource1\" with-rsc=\"resource2\" score=\"INFINITY\"/>" msgstr "" " <rsc_colocation id=\"colocate\" rsc=\"resource1\" with-rsc=\"resource2\" score=\"INFINITY\"/>\n" "\t " #. Tag: para #, fuzzy, no-c-format msgid "Remember, because INFINITY was used, if resource2 can’t run on any of the cluster nodes (for whatever reason) then resource1 will not be allowed to run." msgstr "Ţineţi minte, datorită faptului că INFINITY a fost folosit, dacă resource2 nu poate rula pe nici unul din nodurile clusterului (indiferent de motiv) atunci resource1 nu îi va fi permis să ruleze." #. Tag: para #, fuzzy, no-c-format msgid "Alternatively, you may want the opposite… that resource1 cannot run on the same machine as resource2. In this case use score=\"-INFINITY\"" msgstr "Alternativ, aţi putea dori opusul... ca resource1 să nu poată rula pe aceeaşi maşină ca resource2. În acest caz folosiţi scor=\"-INFINITY\"" #. Tag: title #, no-c-format msgid "An example anti-colocation constraint" msgstr "Un exemplu de restricţie anti-colocare" #. Tag: programlisting #, fuzzy, no-c-format msgid "<rsc_colocation id=\"anti-colocate\" rsc=\"resource1\" with-rsc=\"resource2\" score=\"-INFINITY\"/>" msgstr "" "<rsc_colocation id=\"anti-colocate\"\n" " rsc=\"resource1\" with-rsc=\"resource2\" score=\"-INFINITY\"/> \n" "\t " #. Tag: para #, no-c-format msgid "Again, by specifying -INFINTY, the constraint is binding. So if the only place left to run is where resource2 already is, then resource1 may not run anywhere." msgstr "Din nou, specificând -INFINTY, restricţia este imutabilă. Deci singurul loc rămas pentru a rula este cel unde resource2 este deja, atunci resource1 nu poate rula nicăieri." #. Tag: title #, no-c-format msgid "Advisory Placement" msgstr "Plasament Recomandat" #. Tag: para #, fuzzy, no-c-format msgid "If mandatory placement is about \"must\" and \"must not\", then advisory placement is the \"I’d prefer if\" alternative. For constraints with scores greater than -INFINITY and less than INFINITY, the cluster will try and accommodate your wishes but may ignore them if the alternative is to stop some of the cluster resources." msgstr "Dacă plasamentul obligatoriu se referă la \"trebuie\" şi \"nu trebuie\", atunci plasamentul recomandat este alternativa \"aş prefera dacă\". Pentru restricţii cu scoruri mai mari decât -INFINITY şi mai mici decât INFINITY, clusterul va încerca să acomodeze dorinţele voastre dar le-ar putea ignora dacă alternativa este să oprească unele din resursele clusterului." #. Tag: para #, no-c-format msgid "Like in life, where if enough people prefer something it effectively becomes mandatory, advisory colocation constraints can combine with other elements of the configuration to behave as if they were mandatory." msgstr "Ca şi în viaţă, unde dacă destule persoane preferă ceva acest lucru devine obligatoriu, restricţiile de colocare recomandate se pot combina cu alte elemente ale configuraţiei pentru a se comporta ca şi cum ar fi obligatorii." #. Tag: title #, no-c-format msgid "An example advisory-only colocation constraint" msgstr "Un exemplu de restricţie de colocare doar recomandată" #. Tag: programlisting #, fuzzy, no-c-format msgid "<rsc_colocation id=\"colocate-maybe\" rsc=\"resource1\" with-rsc=\"resource2\" score=\"500\"/>" msgstr "" "<rsc_colocation id=\"colocate-maybe\" rsc=\"resource1\" with-rsc=\"resource2\" score=\"500\"/>\n" "\t " #. Tag: title #, no-c-format msgid "Ordering Sets of Resources" msgstr "Ordonarea Seturilor de Resurse" #. Tag: para #, no-c-format msgid "A common situation is for an administrator to create a chain of ordered resources, such as:" msgstr "O situaţie comună este ca un administrator să creeze un lanţ de resurse ordonate, precum:" #. Tag: title #, no-c-format msgid "A chain of ordered resources" msgstr "Un lanţ de resurse ordonate" #. Tag: programlisting #, fuzzy, no-c-format msgid "" "<constraints>\n" " <rsc_order id=\"order-1\" first=\"A\" then=\"B\" />\n" " <rsc_order id=\"order-2\" first=\"B\" then=\"C\" />\n" " <rsc_order id=\"order-3\" first=\"C\" then=\"D\" />\n" "</constraints>" msgstr "" " <constraints>\n" " <rsc_order id=\"order-1\" first=\"A\" then=\"B\" />\n" " <rsc_order id=\"order-2\" first=\"B\" then=\"C\" />\n" " <rsc_order id=\"order-3\" first=\"C\" then=\"D\" />\n" " </constraints> " #. Tag: title #, no-c-format msgid "Ordered Set" msgstr "Set Ordonat" #. Tag: title #, no-c-format msgid "Visual representation of the four resources' start order for the above constraints" msgstr "Reprezentarea vizuală a ordinii de pornire a celor patru resurse pentru restricţiile de mai sus" #. Tag: phrase #, fuzzy, no-c-format msgid "Ordered set" msgstr "Set Ordonat" #. Tag: para #, no-c-format msgid "To simplify this situation, there is an alternate format for ordering constraints:" msgstr "Pentru a simplifica această situaţie, există un format alternativ pentru ordonarea restricţiilor" #. Tag: title #, no-c-format msgid "A chain of ordered resources expressed as a set" msgstr "Un lanţ de resurse ordonate exprimate ca un set" #. Tag: programlisting #, fuzzy, no-c-format msgid "" "<constraints>\n" " <rsc_order id=\"order-1\">\n" " <resource_set id=\"ordered-set-example\" sequential=\"true\">\n" " <resource_ref id=\"A\"/>\n" " <resource_ref id=\"B\"/>\n" " <resource_ref id=\"C\"/>\n" " <resource_ref id=\"D\"/>\n" " </resource_set>\n" " </rsc_order>\n" "</constraints>" msgstr "" " <constraints>\n" " <rsc_order id=\"order-1\">\n" " <resource_set id=\"ordered-set-example\" sequential=\"true\">\n" " <resource_ref id=\"A\"/>\n" " <resource_ref id=\"B\"/>\n" " <resource_ref id=\"C\"/>\n" " <resource_ref id=\"D\"/>\n" " </resource_set>\n" " </rsc_order>\n" " </constraints> " #. Tag: para #, no-c-format msgid "Resource sets have the same ordering semantics as groups." msgstr "Seturile de resurse au aceeaşi semantică de ordonare ca şi grupurile." #. Tag: title #, no-c-format msgid "A group resource with the equivalent ordering rules" msgstr "Un grup de resurse cu regulile de ordonare echivalente" #. Tag: programlisting #, fuzzy, no-c-format msgid "" "<group id=\"dummy\">\n" " <primitive id=\"A\" .../>\n" " <primitive id=\"B\" .../>\n" " <primitive id=\"C\" .../>\n" " <primitive id=\"D\" .../>\n" "</group>" msgstr "" " <group id=\"dummy\">\n" " <primitive id=\"A\" .../>\n" " <primitive id=\"B\" .../>\n" " <primitive id=\"C\" .../>\n" " <primitive id=\"D\" .../>\n" " </group> " #. Tag: para #, no-c-format msgid "While the set-based format is not less verbose, it is significantly easier to get right and maintain. It can also be expanded to allow ordered sets of (un)ordered resources. In the example below, rscA and rscB can both start in parallel, as can rscC and rscD, however rscC and rscD can only start once both rscA and rscB are active." msgstr "În timp ce formatul bazat pe seturi nu este mai puţin verbose, este semnificativ mai uşor de a nimeri şi menţine. Poate fi extins pentru a permite seturi ordonate de resurse (ne)ordonate. În exemplul de mai jos, rscA şi rscB pot porni ambele în paralel, la fel pot si rscC şi rscD, însă rscC şi rscD pot porni doar odată ce ambele rscA şi rscB sunt active." #. Tag: title #, no-c-format msgid "Ordered sets of unordered resources" msgstr "Seturi ordonate de resurse neordonate" #. Tag: programlisting #, fuzzy, no-c-format msgid "" "<constraints>\n" " <rsc_order id=\"order-1\">\n" " <resource_set id=\"ordered-set-1\" sequential=\"false\">\n" " <resource_ref id=\"A\"/>\n" " <resource_ref id=\"B\"/>\n" " </resource_set>\n" " <resource_set id=\"ordered-set-2\" sequential=\"false\">\n" " <resource_ref id=\"C\"/>\n" " <resource_ref id=\"D\"/>\n" " </resource_set>\n" " </rsc_order>\n" " </constraints>" msgstr "" " <constraints>\n" " <rsc_order id=\"order-1\">\n" " <resource_set id=\"ordered-set-1\" sequential=\"false\">\n" " <resource_ref id=\"A\"/>\n" " <resource_ref id=\"B\"/>\n" " </resource_set>\n" " <resource_set id=\"ordered-set-2\" sequential=\"false\">\n" " <resource_ref id=\"C\"/>\n" " <resource_ref id=\"D\"/>\n" " </resource_set>\n" " </rsc_order>\n" " </constraints> " #. Tag: title #, no-c-format msgid "Two Sets of Unordered Resources" msgstr "Două Seturi de Resurse Neordonate" #. Tag: title #, no-c-format msgid "Visual representation of the start order for two ordered sets of unordered resources" msgstr "Reprezentarea vizuală a ordinii de pornire pentru două seturi de resurse neordonate" #. Tag: phrase #, fuzzy, no-c-format msgid "Two ordered sets" msgstr "Set Ordonat" #. Tag: para #, fuzzy, no-c-format msgid "Of course either set — or both sets — of resources can also be internally ordered (by setting sequential=\"true\") and there is no limit to the number of sets that can be specified." msgstr "Desigur că oricare set -- sau ambele seturi -- de resurse pot de asemenea să fie ordonate intern (prin setarea sequential=\"true\") şi nu este nici o limită asupra numărului de seturi care poate fi specificat." #. Tag: title #, no-c-format msgid "Advanced use of set ordering - Three ordered sets, two of which are internally unordered" msgstr "Utilizări avansate ale ordonării seturilor - Trei seturi ordonate, două din care sunt neordonate intern" #. Tag: programlisting #, fuzzy, no-c-format msgid "" "<constraints>\n" " <rsc_order id=\"order-1\">\n" " <resource_set id=\"ordered-set-1\" sequential=\"false\">\n" " <resource_ref id=\"A\"/>\n" " <resource_ref id=\"B\"/>\n" " </resource_set>\n" " <resource_set id=\"ordered-set-2\" sequential=\"true\">\n" " <resource_ref id=\"C\"/>\n" " <resource_ref id=\"D\"/>\n" " </resource_set>\n" " <resource_set id=\"ordered-set-3\" sequential=\"false\">\n" " <resource_ref id=\"E\"/>\n" " <resource_ref id=\"F\"/>\n" " </resource_set>\n" " </rsc_order>\n" "</constraints>" msgstr "" " <constraints>\n" " <rsc_order id=\"order-1\">\n" " <resource_set id=\"ordered-set-1\" sequential=\"false\">\n" " <resource_ref id=\"A\"/>\n" " <resource_ref id=\"B\"/>\n" " </resource_set>\n" " <resource_set id=\"ordered-set-2\" sequential=\"true\">\n" " <resource_ref id=\"C\"/>\n" " <resource_ref id=\"D\"/>\n" " </resource_set>\n" " <resource_set id=\"ordered-set-3\" sequential=\"false\">\n" " <resource_ref id=\"E\"/>\n" " <resource_ref id=\"F\"/>\n" " </resource_set>\n" " </rsc_order>\n" " </constraints> " #. Tag: title #, no-c-format msgid "Three Resources Sets" msgstr "Trei Seturi de Resurse" #. Tag: title #, no-c-format msgid "Visual representation of the start order for the three sets defined above" msgstr "Reprezentarea vizuală a ordinii de pornire pentru cele trei seturi definite mai sus" #. Tag: phrase #, fuzzy, no-c-format msgid "Three ordered sets" msgstr "Trei Seturi de Resurse" #. Tag: title #, no-c-format msgid "Collocating Sets of Resources" msgstr "Colocarea Seturilor de Resurse" #. Tag: para #, no-c-format msgid "Another common situation is for an administrator to create a set of collocated resources. Previously this was possible either by defining a resource group (See ) which could not always accurately express the design; or by defining each relationship as an individual constraint, causing a constraint explosion as the number of resources and combinations grew." msgstr "O altă situaţie comună este ca un administrator să creeze un set de resurse colocate. Anterior acest lucru era posibil fie prin definirea unui grup de resurse (Vedeţi ) care nu putea întotdeauna să exprime designul în mod corect; sau prin definirea fiecărei relaţii ca o restricţie individuală, cauzând o explozie de restricţii pe măsură ce numărul resurselor şi al combinaţiilor creştea." #. Tag: title #, no-c-format msgid "A chain of collocated resources" msgstr "Un lanţ de resurse colocate" #. Tag: programlisting #, fuzzy, no-c-format msgid "" "<constraints>\n" " <rsc_colocation id=\"coloc-1\" rsc=\"B\" with-rsc=\"A\" score=\"INFINITY\"/>\n" " <rsc_colocation id=\"coloc-2\" rsc=\"C\" with-rsc=\"B\" score=\"INFINITY\"/>\n" " <rsc_colocation id=\"coloc-3\" rsc=\"D\" with-rsc=\"C\" score=\"INFINITY\"/>\n" "</constraints>" msgstr "" " <constraints>\n" " <rsc_colocation id=\"coloc-1\" rsc=\"B\" with-rsc=\"A\" score=\"INFINITY\"/>\n" " <rsc_colocation id=\"coloc-2\" rsc=\"C\" with-rsc=\"B\" score=\"INFINITY\"/>\n" " <rsc_colocation id=\"coloc-3\" rsc=\"D\" with-rsc=\"C\" score=\"INFINITY\"/>\n" " </constraints> " #. Tag: para #, fuzzy, no-c-format msgid "To make things easier, we allow an alternate form of colocation constraints using resource_sets. Just like the expanded version, a resource that can’t be active also prevents any resource that must be collocated with it from being active. For example, if B was not able to run, then both C (+and by inference +D) must also remain stopped." msgstr "Pentru a face lucrurile mai uşoare, permitem o altă formă de restricţii de colocare folosind resource_sets (seturi de resurse). La fel ca şi versiunea extinsă, o resursă care nu poate fi activă împiedică de asemenea orice resursă care trebuie colocată cu aceasta de a fi activă. De exemplu dacă B nu era capabil să ruleze, atunci atât C (şi prin alianţă D) trebuie să rămână oprite." #. Tag: title #, no-c-format msgid "The equivalent colocation chain expressed using resource_sets" msgstr "Lanţul echivalent de restricţii de colocare exprimat folosind resource_sets" #. Tag: programlisting #, fuzzy, no-c-format msgid "" "<constraints>\n" " <rsc_colocation id=\"coloc-1\" score=\"INFINITY\" >\n" " <resource_set id=\"collocated-set-example\" sequential=\"true\">\n" " <resource_ref id=\"A\"/>\n" " <resource_ref id=\"B\"/>\n" " <resource_ref id=\"C\"/>\n" " <resource_ref id=\"D\"/>\n" " </resource_set>\n" " </rsc_colocation>\n" "</constraints>" msgstr "" " <constraints>\n" " <rsc_colocation id=\"coloc-1\" score=\"INFINITY\" >\n" " <resource_set id=\"collocated-set-example\" sequential=\"true\">\n" " <resource_ref id=\"A\"/>\n" " <resource_ref id=\"B\"/>\n" " <resource_ref id=\"C\"/>\n" " <resource_ref id=\"D\"/>\n" " </resource_set>\n" " </rsc_colocation>\n" " </constraints> " #. Tag: para #, no-c-format msgid "Resource sets have the same colocation semantics as groups." msgstr "Seturile de resurse au aceleaşi restricţii semantice ca şi grupurile." #. Tag: title #, no-c-format msgid "A group resource with the equivalent colocation rules" msgstr "O resursă de grup cu regulile echivalente de colocare" #. Tag: para #, fuzzy, no-c-format msgid "This notation can also be used in this context to tell the cluster that a set of resources must all be located with a common peer, but have no dependencies on each other. In this scenario, unlike the previous, B would be allowed to remain active even if A or C (or both) were inactive." msgstr "Această notaţie poate fi folosită de asemenea în acest context pentru a spune clusterului că un set de resurse trebuie să fie toate amplasate pe un nod comun, dar că nu au dependinţe unele de altele. În acest scenariu, contrar faţă de cel anterior, lui B i-ar fi permis să rămână activă chiar dacă A sau C (sau ambele) ar fi fost inactive." #. Tag: title #, no-c-format msgid "Using colocation sets to specify a common peer." msgstr "Folosirea seturilor de colocare pentru a specifica un nod comun." #. Tag: programlisting #, fuzzy, no-c-format msgid "" "<constraints>\n" " <rsc_colocation id=\"coloc-1\" score=\"INFINITY\" >\n" " <resource_set id=\"collocated-set-1\" sequential=\"false\">\n" " <resource_ref id=\"A\"/>\n" " <resource_ref id=\"B\"/>\n" " <resource_ref id=\"C\"/>\n" " </resource_set>\n" " <resource_set id=\"collocated-set-2\" sequential=\"true\">\n" " <resource_ref id=\"D\"/>\n" " </resource_set>\n" " </rsc_colocation>\n" "</constraints>" msgstr "" " <constraints>\n" " <rsc_colocation id=\"coloc-1\" score=\"INFINITY\" >\n" " <resource_set id=\"collocated-set-1\" sequential=\"false\">\n" " <resource_ref id=\"A\"/>\n" " <resource_ref id=\"B\"/>\n" " <resource_ref id=\"C\"/>\n" " </resource_set>\n" " <resource_set id=\"collocated-set-2\" sequential=\"true\">\n" " <resource_ref id=\"D\"/>\n" " </resource_set>\n" " </rsc_colocation>\n" " </constraints> " #. Tag: para #, fuzzy, no-c-format msgid "Of course there is no limit to the number and size of the sets used. The only thing that matters is that in order for any member of set N to be active, all the members of set N+1 must also be active (and naturally on the same node); and if a set has sequential=\"true\", then in order for member M to be active, member M+1 must also be active. You can even specify the role in which the members of a set must be in using the set’s role attribute." msgstr "Desigur nu există nici o limită asupra numărului şi mărimii seturilor folosite. Singurul lucru care contează este ca pentru orice membru al setului N să fie activ, toţi membrii setului N+1 trebuie să fie activi de asemenea (şi evident pe acelaşi nod) şi dacă un set are sequential=\"true\", atunci pentru ca membrul M să fie activ, membrul M+1 trebuie să fie activ de asemenea. Puteţi specifica chiar rolul în care membrii unui set trebuie să fie folosind atributele de rol ale setului." #. Tag: title #, no-c-format msgid "A colocation chain where the members of the middle set have no inter-dependencies and the last has master status." msgstr "Un lanţ de colocare unde membrii setului mijlociu nu au interdependenţe şi ultimul are statusul de master." #. Tag: programlisting #, fuzzy, no-c-format msgid "" "<constraints>\n" " <rsc_colocation id=\"coloc-1\" score=\"INFINITY\" >\n" " <resource_set id=\"collocated-set-1\" sequential=\"true\">\n" " <resource_ref id=\"A\"/>\n" " <resource_ref id=\"B\"/>\n" " </resource_set>\n" " <resource_set id=\"collocated-set-2\" sequential=\"false\">\n" " <resource_ref id=\"C\"/>\n" " <resource_ref id=\"D\"/>\n" " <resource_ref id=\"E\"/>\n" " </resource_set>\n" " <resource_set id=\"collocated-set-2\" sequential=\"true\" role=\"Master\">\n" " <resource_ref id=\"F\"/>\n" " <resource_ref id=\"G\"/>\n" " </resource_set>\n" " </rsc_colocation>\n" "</constraints>" msgstr "" " <constraints>\n" " <rsc_colocation id=\"coloc-1\" score=\"INFINITY\" >\n" " <resource_set id=\"collocated-set-1\" sequential=\"true\">\n" " <resource_ref id=\"A\"/>\n" " <resource_ref id=\"B\"/>\n" " </resource_set>\n" " <resource_set id=\"collocated-set-2\" sequential=\"false\">\n" " <resource_ref id=\"C\"/>\n" " <resource_ref id=\"D\"/>\n" " <resource_ref id=\"E\"/>\n" " </resource_set>\n" " <resource_set id=\"collocated-set-2\" sequential=\"true\" role=\"Master\">\n" " <resource_ref id=\"F\"/>\n" " <resource_ref id=\"G\"/>\n" " </resource_set>\n" " </rsc_colocation>\n" " </constraints> " #. Tag: title #, no-c-format msgid "Another Three Resources Sets" msgstr "Încă Trei Seturi de Resurse" #. Tag: title #, no-c-format msgid "Visual representation of a colocation chain where the members of the middle set have no inter-dependencies" msgstr "Reprezentarea vizuală a unui lanţ de colocare unde membrii setului mijlociu nu au interdependenţe" #. Tag: phrase #, no-c-format msgid "Colocation chain" msgstr "" #~ msgid "ResourceConstraints" #~ msgstr "RestricțiileResurselor" #~ msgid "Constraintsfor Resources" #~ msgstr "Restricțiipentru Resurse" #~ msgid "idConstraint Field Constraint Fieldid entry>id" #~ msgstr "idCâmp de Restricție Câmp de Restricțieid entry>id" #~ msgid "A unique name for the constraint" #~ msgstr "Un nume unic pentru restricţie" #~ msgid "rsc Constraint Field Constraint Fieldrsc rsc" #~ msgstr "rsc Câmp de Restricție Constraint Fieldrsc rsc" #~ msgid "A resource name" #~ msgstr "Un nume de resursă" #~ msgid "NodeConstraint Field Constraint Fieldnode node" #~ msgstr "NodCâmp de Restricție Constraint Fieldnod nod" #~ msgid "A node's uname" #~ msgstr "uname-ul unui nod" #~ msgid "Positive values indicate the resource should run on this node. Negative values indicate the resource should not run on this node. Values of +/- INFINITY change \"should\"/\"should not\" to \"must\"/\"must not\"." #~ msgstr "Valorile pozitive indică faptul că resursa ar trebui să ruleze pe acelaşi nod. Valorile negative indică faptul că resursele ar trebui să nu ruleze pe acelaşi nod. Valorile +/- INFINITY schimbă \"ar putea\"/\"nu ar putea\" în \"trebuie\"/\"nu trebuie\"." #~ msgid "The way to specify the order in which resources should start is by creating rsc_order constraints." #~ msgstr "Modul în care se poate specifica ordinea în care resursele ar trebui să pornească este prin crearea de restricţii rsc_order" #~ msgid "id" #~ msgstr "id" #~ msgid "first" #~ msgstr "first" #~ msgid "The name of a resource that must be started before the then resource is allowed to." #~ msgstr "Numele unei resurse care trebuie pornită înainte de a îi permite resursei then să pornească" #~ msgid "then" #~ msgstr "then" #~ msgid "The name of a resource. This resource will start after the first resource." #~ msgstr "Numele unei resurse. Această resursă va porni după resursa first." #~ msgid "score" #~ msgstr "scor" #~ msgid "If greater than zero, the constraint is mandatory. Otherwise it is only a suggestion. Default value: INFINITY" #~ msgstr "Dacă este mai mare decât zero, restricţia este obligatorie. Altfel este doar o sugestie. Valoarea implicită: INFINITY" #~ msgid "symmetrical" #~ msgstr "simetric" #~ msgid "If true, which is the default, stop the resources in the reverse order. Default value: true" #~ msgstr "Dacă este adevărat, care este şi valoarea implicită, opreşte resursele în ordine inversă. Valoarea implicită: true" #~ msgid "When the location of one resource depends on the location of another one, we call this colocation." #~ msgstr "Când locaţia unei resurse depinde de locaţia altei resurse, numim acest lucru colocare." #~ msgid "A unique name for the constraint." #~ msgstr "Un nume unic pentru restricţie" #~ msgid "rsc" #~ msgstr "rsc" #~ msgid "The colocation source. If the constraint cannot be satisfied, the cluster may decide not to allow the resource to run at all." #~ msgstr "Sursa colocării. Dacă restricţia nu poate fi satisfăcută, clusterul poate decide să nu permită resursei să ruleze deloc." #~ msgid "with-rsc" #~ msgstr "with-rsc" #~ msgid "The colocation target. The cluster will decide where to put this resource first and then decide where to put the resource in the rsc field." #~ msgstr "Destinaţia colocării. Clusterul va decide unde să plaseze această resursă mai întâi şi apoi va decide unde să plaseze resursa din câmpul rsc" pacemaker-master/doc/Pacemaker_Explained/ro-RO/Ch-Intro.po000066400000000000000000000447071217637305600236740ustar00rootroot00000000000000msgid "" msgstr "" "Project-Id-Version: Pacemaker 1.1\n" "POT-Creation-Date: 2012-10-17T05:19:02\n" "PO-Revision-Date: 2012-01-01T17:48:32\n" "Last-Translator: Dan Frîncu \n" "Language-Team: None\n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: application/x-publican; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. Tag: title #, no-c-format msgid "Read-Me-First" msgstr "Citeşte-mă-Întâi-pe-Mine" #. Tag: title #, no-c-format msgid "The Scope of this Document" msgstr "Domeniul de Aplicare al acestui Document" #. Tag: para #, no-c-format msgid "The purpose of this document is to definitively explain the concepts used to configure Pacemaker. To achieve this, it will focus exclusively on the XML syntax used to configure the CIB." msgstr "Scopul acestul document este să explice în mod definitiv conceptele folosite pentru a configura Pacemaker. Pentru a atinge acest lucru, se va concentra exclusiv pe sintaxa XML folosită pentru a configura CIB-ul." #. Tag: para #, fuzzy, no-c-format msgid "For those that are allergic to XML, there exist several unified shells and GUIs for Pacemaker. However these tools will not be covered at all in this document I hope, however, that the concepts explained here make the functionality of these tools more easily understood. , precisely because they hide the XML." msgstr "Pentru aceia dintre voi care sunt alergici la XML, Pacemaker vine cu un shell de cluster; un GUI bazat pe Python există, de asemenea, însă aceste utilitare nu vor fi acoperite în vreun fel în acest document Eu sper, totuşi, conceptele explicate aici să facă funcţionalitatea acestor utilitare mai ușor de înțeles. , întocmai datorită faptului că acestea ascund XML-ul." #. Tag: para #, no-c-format msgid "Additionally, this document is NOT a step-by-step how-to guide for configuring a specific clustering scenario." msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "Although such guides exist, the purpose of this document is to provide an understanding of the building blocks that can be used to construct any type of Pacemaker cluster." msgstr "Pe deasupra, acest document NU este un ghid pas-cu-pas pentru configurarea unui scenariu specific de cluster. Deşi astfel de ghiduri există, scopul acestui document este acela de a furniza o înţelegere a elementelor de bază care pot fi folosite pentru a construi orice tip de cluster Pacemaker." #. Tag: title #, no-c-format msgid "What Is Pacemaker?" msgstr "Ce este Pacemaker?" #. Tag: para #, no-c-format msgid "Pacemaker is a cluster resource manager." msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "It achieves maximum availability for your cluster services (aka. resources) by detecting and recovering from node and resource-level failures by making use of the messaging and membership capabilities provided by your preferred cluster infrastructure (either Corosync or Heartbeat." msgstr "Pacemaker este un manager de resurse de cluster. Atinge disponibilitatea maximă pentru serviciile voastre de cluster (a.k.a. resursele) prin detectarea şi recuperarea din eşecuri la nivel de nod sau de resursă prin folosirea capabilităţilor de mesagerie şi apartenenţă furnizate de infrastructura de cluster preferată (fie Corosync sau Heartbeat)." #. Tag: para #, fuzzy, no-c-format msgid "Pacemaker’s key features include:" msgstr "Caracteristicile cheie ale Pacemaker includ:" #. Tag: para #, no-c-format msgid "Detection and recovery of node and service-level failures" msgstr "Detectarea şi recuperarea eşecurilor la nivel de nod şi serviciu" #. Tag: para #, no-c-format msgid "Storage agnostic, no requirement for shared storage" msgstr "Agnostic d.p.d.v. al stocării, nu sunt cerinţe pentru spaţiu de stocare partajat" #. Tag: para #, no-c-format msgid "Resource agnostic, anything that can be scripted can be clustered" msgstr "Agnostic d.p.d.v. al resurselor, orice poate fi scriptat poate fi folosit într-un cluster" #. Tag: para #, no-c-format msgid "Supports STONITH for ensuring data integrity" msgstr "Suportă STONITH pentru asigurarea integrităţii datelor" #. Tag: para #, no-c-format msgid "Supports large and small clusters" msgstr "Suportă clustere mici şi mari" #. Tag: para #, fuzzy, no-c-format msgid "Supports both quorate and resource driven clusters" msgstr "Suportă atât quorate cât şi clustere conduse de resurse TODO: quorum-driven?" #. Tag: para #, no-c-format msgid "Supports practically any redundancy configuration" msgstr "Suportă practic orice configuraţie redundantă" #. Tag: para #, no-c-format msgid "Automatically replicated configuration that can be updated from any node" msgstr "Configuraţie replicată în mod automat care poate fi actualizată de pe orice nod" #. Tag: para #, no-c-format msgid "Ability to specify cluster-wide service ordering, colocation and anti-colocation" msgstr "Abilitatea de a specifica ordonare, colocare şi anti-colocare la nivelul întregului cluster" #. Tag: para #, no-c-format msgid "Support for advanced services type" msgstr "Suport pentru tipuri de servicii avansate" #. Tag: para #, no-c-format msgid "Clones: for services which need to be active on multiple nodes" msgstr "Clone: pentru servicii care trebuie să fie active pe mai multe noduri" #. Tag: para #, no-c-format msgid "Multi-state: for services with multiple modes (eg. master/slave, primary/secondary)" msgstr "Multi-state: pentru servicii cu mai multe moduri de operare (ex. master/slave, primar/secundar)" #. Tag: title #, no-c-format msgid "Types of Pacemaker Clusters" msgstr "Tipuri de Clustere Pacemaker" #. Tag: para #, no-c-format msgid "Pacemaker makes no assumptions about your environment, this allows it to support practically any redundancy configuration including Active/Active, Active/Passive, N+1, N+M, N-to-1 and N-to-N." msgstr "Pacemaker nu face nici un fel de presupuneri despre mediul vostru, acest aspect îi permite să suporte practic orice configuraţie redundantă incluzând Activ/Activ, Activ/Pasiv, N+1, N+M, N-la-1 şi N-la-N." #. Tag: title #, no-c-format msgid "Active/Passive Redundancy" msgstr "Redundanţă Activă/Pasivă" #. Tag: para #, no-c-format msgid "Two-node Active/Passive clusters using Pacemaker and DRBD are a cost-effective solution for many High Availability situations." msgstr "Clusterele Active/Pasive formate din două noduri care folosesc Pacemaker şi DRBD sunt o soluţie eficientă d.p.d.v. al costului pentru multe situaţii de High Availability." #. Tag: title #, no-c-format msgid "Shared Failover" msgstr "Failover Partajat" #. Tag: para #, no-c-format msgid "By supporting many nodes, Pacemaker can dramatically reduce hardware costs by allowing several active/passive clusters to be combined and share a common backup node" msgstr "Prin suportarea de multe noduri, Pacemaker poate reduce costurile hardware în mod dramatic permiţând mai multor clustere active/pasive să fie combinate şi să împartă un nod comun de backup" #. Tag: title #, no-c-format msgid "N to N Redundancy" msgstr "Redundanţă N la N" #. Tag: para #, no-c-format msgid "When shared storage is available, every node can potentially be used for failover. Pacemaker can even run multiple copies of services to spread out the workload." msgstr "Când un mediu de stocare partajat este disponibil, fiecare nod poate fi folosit în mod potenţial pentru failover. Pacemaker poate chiar rula mai multe copii ale serviciilor pentru a distribui sarcina de lucru." #. Tag: title #, no-c-format msgid "Pacemaker Architecture" msgstr "Arhitectura Pacemaker" #. Tag: para #, no-c-format msgid "At the highest level, the cluster is made up of three pieces:" msgstr "La cel mai înalt nivel, clusterul este compus din trei părţi:" #. Tag: para #, no-c-format msgid "Core cluster infrastructure providing messaging and membership functionality (illustrated in red)" msgstr "Nucleul infrastructurii de cluster care furnizează funcţionalitatea de mesagerie şi apartenenţă (ilustrată cu roşu)" #. Tag: para #, no-c-format msgid "Non-cluster aware components (illustrated in green)." msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "In a Pacemaker cluster, these pieces include not only the scripts that knows how to start, stop and monitor resources, but also a local daemon that masks the differences between the different standards these scripts implement." msgstr "Componente fără apartenenţă la cluster (ilustrate în albastru). Într-un cluster Pacemaker, aceste părţi includ nu numai scripturile care ştiu să pornească, oprească şi să monitorizeze resurse, dar şi un daemon local care maschează diferenţele între standardele diferite pe care aceste scripturi le implementează." #. Tag: para #, no-c-format msgid "A brain (illustrated in blue)" msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "This component processes and reacts to events from the cluster (nodes leaving or joining) and resources (eg. monitor failures) as well as configuration changes from the administrator. In response to all of these events, Pacemaker will compute the ideal state of the cluster and plot a path to achieve it. This may include moving resources, stopping nodes and even forcing nodes offline with remote power switches." msgstr "Un creier (ilustrat cu verde) care procesează şi reacţionează la evenimente din partea clusterului (noduri care pleacă sau se alătură) şi a resurselor (ex. eşecuri de monitorizare) la fel ca şi la schimbări de configuraţie din partea administratorului. Ca răspuns la aceste evenimente, Pacemaker va calcula starea ideală a clusterului şi va cartografia o cale de a atinge ţelul. Acest lucru ar putea include mutarea resurselor, oprirea nodurilor sau chiar oprirea acestora forţat cu switch-uri de curent la distanţă." #. Tag: title #, no-c-format msgid "Conceptual Stack Overview" msgstr "Vedere Conceptuală a Stivei" #. Tag: title #, no-c-format msgid "Conceptual overview of the cluster stack" msgstr "Vederea conceptuală a stivei de cluster" #. Tag: para #, no-c-format msgid "When combined with Corosync, Pacemaker also supports popular open source cluster filesystems. footnote:[ Even though Pacemaker also supports Heartbeat, the filesystems need to use the stack for messaging and membership and Corosync seems to be what they’re standardizing on." msgstr "" #. Tag: para #, no-c-format msgid "Technically it would be possible for them to support Heartbeat as well, however there seems little interest in this. ]" msgstr "" #. Tag: para #, no-c-format msgid "Due to recent standardization within the cluster filesystem community, they make use of a common distributed lock manager which makes use of Corosync for its messaging capabilities and Pacemaker for its membership (which nodes are up/down) and fencing services." msgstr "" #. Tag: title #, no-c-format msgid "The Pacemaker stack when running on Corosync" msgstr "Stiva Pacemaker atunci când rulează pe Corosync" #. Tag: title #, no-c-format msgid "Internal Components" msgstr "Componente Interne" #. Tag: para #, no-c-format msgid "Pacemaker itself is composed of four key components (illustrated below in the same color scheme as the previous diagram):" msgstr "Pacemaker însuşi este compus din patru componente cheie (ilustrate mai jos cu aceeaşi schemă de culori ca şi în diagrama anterioară):" #. Tag: para #, no-c-format msgid "CIB (aka. Cluster Information Base)" msgstr "CIB (Cluster Information Base)" #. Tag: para #, no-c-format msgid "CRMd (aka. Cluster Resource Management daemon)" msgstr "CRMd (aka. Cluster Resource Management daemon)" #. Tag: para #, no-c-format msgid "PEngine (aka. PE or Policy Engine)" msgstr "PEngine (aka. PE sau Policy Engine)" #. Tag: para #, no-c-format msgid "STONITHd" msgstr "STONITHd" #. Tag: title #, no-c-format msgid "Subsystems of a Pacemaker cluster" msgstr "Subsisteme ale unui cluster Pacemaker rulând pe Corosync" #. Tag: para #, fuzzy, no-c-format msgid "The CIB uses XML to represent both the cluster’s configuration and current state of all resources in the cluster. The contents of the CIB are automatically kept in sync across the entire cluster and are used by the PEngine to compute the ideal state of the cluster and how it should be achieved." msgstr "CIB-ul foloseşte XML pentru a reprezenta atât configuraţia clusterului cât şi starea curentă a tuturor resurselor din cluster. Conţinutul CIB-ului este ţinut sincronizat în mod automat pe tot clusterul şi este folosit de către PEngine pentru a calcula starea ideală a clusterului şi de a arăta cum poate fi atinsă." #. Tag: para #, fuzzy, no-c-format msgid "This list of instructions is then fed to the DC (Designated Controller). Pacemaker centralizes all cluster decision making by electing one of the CRMd instances to act as a master. Should the elected CRMd process (or the node it is on) fail… a new one is quickly established." msgstr "Această listă de instrucţiuni este apoi furnizată către DC (Designated Controller). Pacemaker centralizează toate deciziile clusterului prin alegerea uneia dintre instanţele de CRMd pentru a se comporta ca master. Dacă procesul ales de CRMd (sau nodul pe care se află acesta) eşuează ... unul nou este stabilit repede." #. Tag: para #, fuzzy, no-c-format msgid "The DC carries out PEngine’s instructions in the required order by passing them to either the LRMd (Local Resource Management daemon) or CRMd peers on other nodes via the cluster messaging infrastructure (which in turn passes them on to their LRMd process)." msgstr "DC-ul îndeplineşte instrucţiunile PEngine-ului în ordinea necesară prin pasarea acestora fie către LRMd (Local Resource Managemen daemon) fie altor noduri pe care rulează CRMd prin infrastructura de mesagerie a clusterului (care la rândul ei le pasează către procesul lor LRMd)." #. Tag: para #, no-c-format msgid "The peer nodes all report the results of their operations back to the DC and, based on the expected and actual results, will either execute any actions that needed to wait for the previous one to complete, or abort processing and ask the PEngine to recalculate the ideal cluster state based on the unexpected results." msgstr "Nodurile vecine raportează toate rezultatele operaţiunilor înapoi către DC şi pe baza rezultatelor aşteptate şi a rezultatelor actuale, fie va executa acţiuni care necesitau să aştepte ca şi cele anterioare să termine, sau va anula procesarea şi va ruga PEngine-ul să recalculeze starea ideală a clusterului pe baza rezultatelor neaşteptate." #. Tag: para #, no-c-format msgid "In some cases, it may be necessary to power off nodes in order to protect shared data or complete resource recovery. For this Pacemaker comes with STONITHd." msgstr "" #. Tag: para #, no-c-format msgid "STONITH is an acronym for Shoot-The-Other-Node-In-The-Head and is usually implemented with a remote power switch." msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "In Pacemaker, STONITH devices are modeled as resources (and configured in the CIB) to enable them to be easily monitored for failure, however STONITHd takes care of understanding the STONITH topology such that its clients simply request a node be fenced and it does the rest." msgstr "În anumite cazuri, ar putea fi necesar să oprească alimentarea nodurilor pentru a proteja datele partajate sau pentru a termina recuperarea de resurse. Pentru acest lucru Pacemaker vine cu STONITHd. STONITH este un acronim pentru Shoot-The-Other-Node-In-The-Head (împuşcă celălalt nod în cap) şi este implementat de obicei cu un switch de alimentare cu curent controlat de la distanţă. În Pacemaker, dispozitivele STONITH sunt modelate precum resursele (şi configurate în CIB) pentru a permite monitorizarea facilă a acestora în caz de eşec, totuşi STONITHd se ocupă de înţelegerea topologiei STONITH astfel încât clienţii acestuia să solicite pur şi simplu ca un nod să fie evacuat şi acesta se va ocupa de rest." #~ msgid "Unified, scriptable, cluster shell" #~ msgstr "Shell de cluster unificat, scriptabil" #~ msgid "When combined with Corosync, Pacemaker also supports popular open source cluster filesystems Even though Pacemaker also supports Heartbeat, the filesystems need to use the stack for messaging and membership and Corosync seems to be what they're standardizing on. Technically it would be possible for them to support Heartbeat as well, however there seems little interest in this. . Due to recent standardization within the cluster filesystem community, they make use of a common distributed lock manager which makes use of Corosync for its messaging capabilities and Pacemaker for its membership (which nodes are up/down) and fencing services." #~ msgstr "În combinaţie cu Corosync, Pacemaker suportă de asemenea sistemele de fişiere de cluster open source populare Deşi Pacemaker suportă şi Heartbeat, sistemele de fişiere care trebuie să folosească stiva pentru mesagerie şi apartenenţă şi Corosync pare să fie ţinta standardizării. Tehnic vorbind ar fi posibil ca acestea să suporte Heartbeat de asemenea, însă există puţin interes pentru acest aspect. . Datorită standardizării recente dinăuntrul comunităţii de sisteme de fişiere de cluster, acestea folosesc un manager de blocare distribuit care foloseşte la rândul său Corosync pentru capabilităţile acestuia de mesagerie şi Pacemaker pentru apartenenţă (care noduri sunt funcţionale şi care nu) şi pentru servicii de evacuare forțată." #~ msgid "The Pacemaker Stack" #~ msgstr "Stiva Pacemaker" pacemaker-master/doc/Pacemaker_Explained/ro-RO/Ch-Nodes.po000066400000000000000000000430361217637305600236430ustar00rootroot00000000000000msgid "" msgstr "" "Project-Id-Version: Pacemaker 1.1\n" "POT-Creation-Date: 2012-10-17T05:19:02\n" "PO-Revision-Date: 2012-01-01T17:48:32\n" "Last-Translator: Dan Frîncu \n" "Language-Team: None\n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: application/x-publican; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. Tag: title #, no-c-format msgid "Cluster Nodes" msgstr "Nodurile Clusterului" #. Tag: title #, no-c-format msgid "Defining a Cluster Node" msgstr "Definirea unui Nod de Cluster" #. Tag: para #, no-c-format msgid "Each node in the cluster will have an entry in the nodes section containing its UUID, uname, and type." msgstr "Fiecare nod în cluster va avea o intrare în secţiunea de noduri conţinând UUID-ul, uname-ul şi tipul acestuia." #. Tag: title #, no-c-format msgid "Example cluster node entry" msgstr "Exemplu de intrare de nod de cluster" #. Tag: programlisting #, fuzzy, no-c-format msgid "<node id=\"1186dc9a-324d-425a-966e-d757e693dc86\" uname=\"pcmk-1\" type=\"normal\"/>" msgstr "" "<node id=\"1186dc9a-324d-425a-966e-d757e693dc86\" uname=\"pcmk-1\" type=\"normal\"/>\n" "\t" #. Tag: para #, fuzzy, no-c-format msgid "In normal circumstances, the admin should let the cluster populate this information automatically from the communications and membership data. However one can use the crm_uuid tool to read an existing UUID or define a value before the cluster starts." msgstr "În circumstanţe normale, admin-ul ar trebui să lase clusterul să populeze această informaţie în mod automat din datele de comunicare şi apartenenţă. Totuşi cineva poate folosi utilitarul crm_uuid pentru a citi un UUID existent sau pentru a defini o valoare înainte să pornească clusterul." #. Tag: title #, no-c-format msgid "Describing a Cluster Node" msgstr "Descrierea unui Nod de Cluster" #. Tag: para #, fuzzy, no-c-format msgid " Nodeattribute attribute Beyond the basic definition of a node the administrator can also describe the node’s attributes, such as how much RAM, disk, what OS or kernel version it has, perhaps even its physical location. This information can then be used by the cluster when deciding where to place resources. For more information on the use of node attributes, see ." msgstr "Dincolo de definiţia de bază a unui nod, administratorul poate descrie de asemenea şi atributele nodului, cum ar fi cât de mult RAM, disc are, care OS sau versiune de kernel are, poate chiar şi locaţia fizică. Această informaţie poate fi utilizată mai apoi de către cluster când va decide unde să plaseze resursele. Pentru mai multe informaţii referitoare la folosirea atributelor nodului, vedeţi secţiunea despre ." #. Tag: para #, fuzzy, no-c-format msgid "Node attributes can be specified ahead of time or populated later, when the cluster is running, using crm_attribute." msgstr "Atributele nodului pot fi specificate în avans sau populate ulterior, când clusterul rulează, folosind crm_attribute." #. Tag: para #, fuzzy, no-c-format msgid "Below is what the node’s definition would look like if the admin ran the command:" msgstr "Mai jos este prezentat cum ar arăta definiţia nodului dacă administratorul ar executa comanda:" #. Tag: title #, no-c-format msgid "The result of using crm_attribute to specify which kernel pcmk-1 is running" msgstr "Rezultatul folosirii crm_attribute pentru a specifica pe ce kernel rulează pcmk-1" #. Tag: programlisting #, fuzzy, no-c-format msgid "# crm_attribute --type nodes --node-uname pcmk-1 --attr-name kernel --attr-value `uname -r`" msgstr " crm_attribute --type nodes --node-uname pcmk-1 --attr-name kernel --get-value" #. Tag: programlisting #, fuzzy, no-c-format msgid "" "<node uname=\"pcmk-1\" type=\"normal\" id=\"1186dc9a-324d-425a-966e-d757e693dc86\">\n" " <instance_attributes id=\"nodes-1186dc9a-324d-425a-966e-d757e693dc86\">\n" " <nvpair id=\"kernel-1186dc9a-324d-425a-966e-d757e693dc86\" name=\"kernel\" value=\"2.6.16.46-0.4-default\"/>\n" " </instance_attributes>\n" "</node>" msgstr "" "crm_attribute --type nodes --node-uname pcmk-1 --attr-name kernel --attr-value `uname -r` \n" "\n" " <node uname=\"pcmk-1\" type=\"normal\" id=\"1186dc9a-324d-425a-966e-d757e693dc86\">\n" " <instance_attributes id=\"nodes-1186dc9a-324d-425a-966e-d757e693dc86\">\n" " <nvpair id=\"kernel-1186dc9a-324d-425a-966e-d757e693dc86\" name=\"kernel\" value=\"2.6.16.46-0.4-default\"/>\n" " </instance_attributes>\n" " </node> " #. Tag: para #, fuzzy, no-c-format msgid "A simpler way to determine the current value of an attribute is to use crm_attribute command again:" msgstr "O metodă mai simplă de a determina valoarea curentă a unui atribut este de a folosi comanda crm_attribute din nou:" #. Tag: programlisting #, fuzzy, no-c-format msgid "# crm_attribute --type nodes --node-uname pcmk-1 --attr-name kernel --get-value" msgstr " crm_attribute --type nodes --node-uname pcmk-1 --attr-name kernel --get-value" #. Tag: para #, fuzzy, no-c-format msgid "By specifying --type nodes the admin tells the cluster that this attribute is persistent. There are also transient attributes which are kept in the status section which are \"forgotten\" whenever the node rejoins the cluster. The cluster uses this area to store a record of how many times a resource has failed on that node but administrators can also read and write to this section by specifying --type status." msgstr "Prin specificarea --type noduri administratorul îi spune clusterului că acest atribut este persistent. Există de asemenea atribute tranzitive care sunt păstrate în secţiunea de status şi care sunt \"uitate\" oricând nodul se realătură clusterului. Clusterul foloseşte această zonă pentru a stoca o înregistrare despre de câte ori a eşuat o resursă pe acel nod însâ administratorii pot citi şi scrie în această secţiune prin specificarea a --type status." #. Tag: title #, no-c-format msgid "Adding a New Cluster Node" msgstr "Adăugarea unui Nou Nod în Cluster" #. Tag: title #, no-c-format msgid "Corosync" msgstr "Corosync" #. Tag: para #, fuzzy, no-c-format msgid " CorosyncAdd Cluster Node Add Cluster Node Add Cluster NodeCorosync Corosync Adding a new node is as simple as installing Corosync and Pacemaker, and copying /etc/corosync/corosync.conf and /etc/corosync/authkey (if it exists) from an existing node. You may need to modify the mcastaddr option to match the new node’s IP address." msgstr "Adăugarea unui nou nod este la fel de simplă ca instalarea Corosync şi Pacemaker şi copierea /etc/corosync/corosync.conf şi a /etc/corosync/authkey (dacă există) de pe un nod existent. Ar putea fi necesar să modificaţi opţiunea mcastaddr pentru a se potrivi cu adresa IP a noului nod." #. Tag: para #, no-c-format msgid "If a log message containing \"Invalid digest\" appears from Corosync, the keys are not consistent between the machines." msgstr "Dacă apare în log-uri un mesaj de la Corosync conţinând \"Invalid digest\", cheile nu sunt consistente între maşini." #. Tag: title #, no-c-format msgid "Heartbeat" msgstr "Heartbeat" #. Tag: para #, no-c-format msgid " HeartbeatAdd Cluster Node Add Cluster Node Add Cluster NodeHeartbeat Heartbeat Provided you specified autojoin any in ha.cf, adding a new node is as simple as installing heartbeat and copying ha.cf and authkeys from an existing node." msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "If you don’t want to use autojoin, then after setting up ha.cf and authkeys, you must use the hb_addnode command before starting the new node." msgstr "În caz contrar, după setarea ha.cf şi a authkeys, trebuie să folosiţi comanda hb_addnode înainte de a porni noul nod." #. Tag: title #, no-c-format msgid "Removing a Cluster Node" msgstr "Înlăturarea unui Nod din Cluster" #. Tag: para #, fuzzy, no-c-format msgid " CorosyncRemove Cluster Node Remove Cluster Node Remove Cluster NodeCorosync Corosync Because the messaging and membership layers are the authoritative source for cluster nodes, deleting them from the CIB is not a reliable solution. First one must arrange for heartbeat to forget about the node (pcmk-1 in the example below)." msgstr "Datorită faptului că straturile de mesagerie şi apartenenţă sunt surse autoritative pentru nodurile clusterului, ştergerea acestoa din CIB nu este o soluţie de încredere. Întâi cineva trebuie să facă astfel încât heartbeat să uite de nod (pcmk-1 în exemplul de mai jos)." #. Tag: para #, no-c-format msgid "On the host to be removed:" msgstr "Pe gazda care va fi înlăturată:" #. Tag: para #, fuzzy, no-c-format msgid "Find and record the node’s Corosync id: crm_node -i" msgstr "Găsiţi şi înregistraţi id-ul Corosync al nodului: crm_node -i" #. Tag: para #, fuzzy, no-c-format msgid "Stop the cluster: /etc/init.d/corosync stop" msgstr "Opriţi clusterul: /etc/init.d/corosync stop" #. Tag: para #, no-c-format msgid "Next, from one of the remaining active cluster nodes:" msgstr "Ulterior, de pe unul din nodurile rămase active ale clusterului:" #. Tag: para #, no-c-format msgid "Tell the cluster to forget about the removed host:" msgstr "" #. Tag: programlisting #, no-c-format msgid "# crm_node -R $COROSYNC_ID" msgstr "" #. Tag: para #, no-c-format msgid "Only now is it safe to delete the node from the CIB with:" msgstr "Doar acum este în siguranţă să ştergeţi nodul din CIB cu:" #. Tag: programlisting #, fuzzy, no-c-format msgid "" "# cibadmin --delete --obj_type nodes --crm_xml '<node uname=\"_pcmk-1_\"/>'\n" "# cibadmin --delete --obj_type status --crm_xml '<node_state uname=\"_pcmk-1_\"/>'" msgstr "" "cibadmin --delete --obj_type nodes --crm_xml '<node uname=\"pcmk-1\"/>'\n" "\tcibadmin --delete --obj_type status --crm_xml '<node_state uname=\"pcmk-1\"/>'" #. Tag: para #, no-c-format msgid " HeartbeatRemove Cluster Node Remove Cluster Node Remove Cluster NodeHeartbeat Heartbeat Because the messaging and membership layers are the authoritative source for cluster nodes, deleting them from the CIB is not a reliable solution." msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "First one must arrange for heartbeat to forget about the node (pcmk-1 in the example below). To do this, shut down heartbeat on the node and then, from one of the remaining active cluster nodes, run:" msgstr "Datorită faptului că straturile de mesagerie şi apartenenţă sunt surse autoritative pentru nodurile clusterului, ştergerea acestoa din CIB nu este o soluţie de încredere. Întâi cineva trebuie să facă astfel încât heartbeat să uite de nod (pcmk-1 în exemplul de mai jos). Pentru a realiza acest lucru, opriţi heartbeat pe nod şi apoi, de pe unul din nodurile rămase active în cluster, rulaţi:" #. Tag: programlisting #, fuzzy, no-c-format msgid "# hb_delnode pcmk-1" msgstr "hb_delnode pcmk-1" #. Tag: para #, no-c-format msgid "Only then is it safe to delete the node from the CIB with:" msgstr "Doar acum este în siguranţă să ştergeţi nodul din CIB cu:" #. Tag: programlisting #, fuzzy, no-c-format msgid "" "# cibadmin --delete --obj_type nodes --crm_xml '<node uname=\"pcmk-1\"/>'\n" "# cibadmin --delete --obj_type status --crm_xml '<node_state uname=\"pcmk-1\"/>'" msgstr "" "cibadmin --delete --obj_type nodes --crm_xml '<node uname=\"pcmk-1\"/>'\n" "\tcibadmin --delete --obj_type status --crm_xml '<node_state uname=\"pcmk-1\"/>'" #. Tag: title #, no-c-format msgid "Replacing a Cluster Node" msgstr "Înlocuirea unui Nod din Cluster" #. Tag: para #, no-c-format msgid " CorosyncReplace Cluster Node Replace Cluster Node Replace Cluster NodeCorosync Corosync The five-step guide to replacing an existing cluster node:" msgstr "" #. Tag: para #, no-c-format msgid "Make sure the old node is completely stopped" msgstr "Asiguraţi-vă că nodul vechi este oprit de tot." #. Tag: para #, no-c-format msgid "Give the new machine the same hostname and IP address as the old one" msgstr "Daţi maşinii noi acelaşi hostname şi adresă IP ca celei vechi" #. Tag: para #, no-c-format msgid "Install the cluster software :-)" msgstr "Instalaţi soft-ul de cluster :-)" #. Tag: para #, fuzzy, no-c-format msgid "Copy /etc/corosync/corosync.conf and /etc/corosync/authkey (if it exists) to the new node" msgstr "Copiaţi /etc/corosync/corosync.conf şi /etc/corosync/authkey (dacă există) pe nodul nou" #. Tag: para #, no-c-format msgid "Start the new cluster node" msgstr "Porniţi noul nod în cluster" #. Tag: para #, no-c-format msgid " HeartbeatReplace Cluster Node Replace Cluster Node Replace Cluster NodeHeartbeat Heartbeat The seven-step guide to replacing an existing cluster node:" msgstr "" #. Tag: para #, no-c-format msgid "Give the new machine the same hostname as the old one" msgstr "Daţi maşinii noi acelaşi hostname ca şi celei vechi" #. Tag: para #, fuzzy, no-c-format msgid "Go to an active cluster node and look up the UUID for the old node in /var/lib/heartbeat/hostcache" msgstr "Mergeţi pe un nod activ din cluster şi căutaţi UUID-ul nodului vechi în /var/lib/heartbeat/hostcache" #. Tag: para #, no-c-format msgid "Install the cluster software" msgstr "Instalaţi soft-ul de cluster" #. Tag: para #, fuzzy, no-c-format msgid "Copy ha.cf and authkeys to the new node" msgstr "Copiaţi /etc/corosync/corosync.conf şi /etc/corosync/authkey (dacă există) pe nodul nou" #. Tag: para #, fuzzy, no-c-format msgid "On the new node, populate it’s UUID using crm_uuid -w and the UUID from step 2" msgstr "Pe nodul nou, populaţi UUID-ul acestuia folosind crm_uuid -w şi UUID-ul prelevat de la pasul 2" #~ msgid "Provided you specified autojoin any in ha.cf, adding a new node is as simple as installing heartbeat and copying ha.cf and authkeys from an existing node." #~ msgstr "Dacă aţi specificat autojoin any în ha.cf, adăugarea unui nod nou este la fel de simpla ca şi instalarea Heartbeat şi copierea ha.cf şi a authkeys de pe un nod existent." #~ msgid "Tell the cluster to forget about the removed host: crm_node -R COROSYNC_ID" #~ msgstr "Comunicaţi clusterului să uite despre gazda înlăturată: crm_node -R COROSYNC_ID" #~ msgid "" #~ "cibadmin --delete --obj_type nodes --crm_xml '<node uname=\"pcmk-1\"/>'\n" #~ "\t cibadmin --delete --obj_type status --crm_xml '<node_state uname=\"pcmk-1\"/>'" #~ msgstr "" #~ "cibadmin --delete --obj_type nodes --crm_xml '<node uname=\"pcmk-1\"/>'\n" #~ "\t cibadmin --delete --obj_type status --crm_xml '<node_state uname=\"pcmk-1\"/>'" #~ msgid "The five-step guide to replacing an existing cluster node:" #~ msgstr "Ghidul în cinci paşi pentru înlocuirea unui nod existent din cluster:" #~ msgid "The seven-step guide to replacing an existing cluster node:" #~ msgstr "Ghidul în şapte paşi pentru înlocuirea unui nod existent din cluster" pacemaker-master/doc/Pacemaker_Explained/ro-RO/Ch-Options.po000066400000000000000000001377641217637305600242420ustar00rootroot00000000000000msgid "" msgstr "" "Project-Id-Version: Pacemaker 1.1\n" "POT-Creation-Date: 2012-10-17T05:19:02\n" "PO-Revision-Date: 2012-01-01T17:48:32\n" "Last-Translator: Dan Frîncu \n" "Language-Team: None\n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: application/x-publican; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. Tag: title #, no-c-format msgid "Cluster Options" msgstr "Opţiunile Clusterului" #. Tag: title #, fuzzy, no-c-format msgid "Special Options" msgstr "Descriere" #. Tag: para #, no-c-format msgid "The reason for these fields to be placed at the top level instead of with the rest of cluster options is simply a matter of parsing. These options are used by the configuration database which is, by design, mostly ignorant of the content it holds. So the decision was made to place them in an easy to find location." msgstr "Motivul pentru care aceste câmpuri să fie plasate la nivelul cel mai înalt în loc să fie cu restul opţiunilor clusterului este pur şi simplu legat de parsare. Aceste opţiuni sunt folosite de către baza de date cu configuraţii care este, prin design, în principal ignorantă faţă de conţinutul pe care îl deţine. Aşa că decizia a fost luată de a le plasa într-o locaţie uşor de găsit." #. Tag: title #, fuzzy, no-c-format msgid "Configuration Version" msgstr "Proprietăţi ale Versiunii Configuraţiei" #. Tag: para #, fuzzy, no-c-format msgid " Configuration VersionCluster Cluster ClusterOptionConfiguration Version OptionConfiguration Version Configuration Version " msgstr "Interogarea Opțiunilor Clusterului Setarea Opțiunilor Clusterului Opțiunile ClusteruluiInterogarea Opțiunilor ClusteruluiSetarea Interogarea și Setarea Opțiunilor Clusterului" #. Tag: para #, fuzzy, no-c-format msgid "When a node joins the cluster, the cluster will perform a check to see who has the best configuration based on the fields below. It then asks the node with the highest (admin_epoch, epoch, num_updates) tuple to replace the configuration on all the nodes - which makes setting them, and setting them correctly, very important." msgstr "Când un nod aderă la cluster, clusterul va efectua o verificare pentru a vedea cine are cea mai bună configuraţie bazată pe câmpurile de mai jos. Apoi întreabă nodul cu cea mai mare tuplă (admin_epoch, epoch, num_updates) să înlocuiască configuraţia pe toate nodurile - fapt care face setarea acestora şi setarea lor corectă, foarte importantă." #. Tag: title #, no-c-format msgid "Configuration Version Properties" msgstr "Proprietăţi ale Versiunii Configuraţiei" #. Tag: entry #, no-c-format msgid "Field" msgstr "Câmp" #. Tag: entry #, no-c-format msgid "Description" msgstr "Descriere" #. Tag: para #, no-c-format msgid "admin_epoch" msgstr "" #. Tag: para #, fuzzy, no-c-format msgid " admin_epochCluster Option Cluster Option ClusterOptionadmin_epoch Optionadmin_epoch admin_epoch Never modified by the cluster. Use this to make the configurations on any inactive nodes obsolete." msgstr "Interogarea Opțiunilor Clusterului Setarea Opțiunilor Clusterului Opțiunile ClusteruluiInterogarea Opțiunilor ClusteruluiSetarea Interogarea și Setarea Opțiunilor Clusterului" #. Tag: para #, no-c-format msgid "Never set this value to zero, in such cases the cluster cannot tell the difference between your configuration and the \"empty\" one used when nothing is found on disk." msgstr "Nu setaţi niciodată această valoare la zero, în astfel de cazuri clusterul nu poate face diferenţa între configuraţia voastră şi cea \"goală\" folosită atunci când nu este găsit nimic pe disc." #. Tag: para #, no-c-format msgid "epoch" msgstr "" #. Tag: para #, fuzzy, no-c-format msgid " epochCluster Option Cluster Option ClusterOptionepoch Optionepoch epoch Incremented every time the configuration is updated (usually by the admin)" msgstr "Interogarea Opțiunilor Clusterului Setarea Opțiunilor Clusterului Opțiunile ClusteruluiInterogarea Opțiunilor ClusteruluiSetarea Interogarea și Setarea Opțiunilor Clusterului" #. Tag: para #, no-c-format msgid "num_updates" msgstr "" #. Tag: para #, fuzzy, no-c-format msgid " num_updatesCluster Option Cluster Option ClusterOptionnum_updates Optionnum_updates num_updates Incremented every time the configuration or status is updated (usually by the cluster)" msgstr "Interogarea Opțiunilor Clusterului Setarea Opțiunilor Clusterului Opțiunile ClusteruluiInterogarea Opțiunilor ClusteruluiSetarea Interogarea și Setarea Opțiunilor Clusterului" #. Tag: title #, no-c-format msgid "Other Fields" msgstr "Alte Câmpuri" #. Tag: title #, no-c-format msgid "Properties Controlling Validation" msgstr "Proprietăţi care Controlează Validarea" #. Tag: para #, no-c-format msgid "validate-with" msgstr "" #. Tag: para #, no-c-format msgid " validate-withCluster Option Cluster Option ClusterOptionvalidate-with Optionvalidate-with validate-with Determines the type of validation being done on the configuration. If set to \"none\", the cluster will not verify that updates conform to the DTD (nor reject ones that don’t). This option can be useful when operating a mixed version cluster during an upgrade." msgstr "" #. Tag: title #, no-c-format msgid "Fields Maintained by the Cluster" msgstr "Câmpuri Menţinute de către Cluster" #. Tag: title #, no-c-format msgid "Properties Maintained by the Cluster" msgstr "Proprietăţi Menţinute de către Cluster" #. Tag: para #, no-c-format msgid "cib-last-written" msgstr "" #. Tag: para #, no-c-format msgid " cib-last-writtenCluster Property Cluster Property ClusterPropertycib-last-written Propertycib-last-written cib-last-written Indicates when the configuration was last written to disk. Informational purposes only." msgstr "" #. Tag: para #, no-c-format msgid "dc-uuid" msgstr "" #. Tag: para #, no-c-format msgid " dc-uuidCluster Property Cluster Property ClusterPropertydc-uuid Propertydc-uuid dc-uuid Indicates which cluster node is the current leader. Used by the cluster when placing resources and determining the order of some events." msgstr "" #. Tag: para #, no-c-format msgid "have-quorum" msgstr "" #. Tag: para #, no-c-format msgid " have-quorumCluster Property Cluster Property ClusterPropertyhave-quorum Propertyhave-quorum have-quorum Indicates if the cluster has quorum. If false, this may mean that the cluster cannot start resources or fence other nodes. See no-quorum-policy below." msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "Note that although these fields can be written to by the admin, in most cases the cluster will overwrite any values specified by the admin with the \"correct\" ones. To change the admin_epoch, for example, one would use:" msgstr "Luaţi aminte că deşi aceste câmpuri pot fi scrise de către administrator, în majoritatea cazurilor clusterul va suprascrie orice valoare specificată de către administrator cu cele \"corecte\". Pentru a schimba admin_epoch de exemplu, cineva ar putea folosi:" #. Tag: programlisting #, fuzzy, no-c-format msgid "# cibadmin --modify --crm_xml '<cib admin_epoch=\"42\"/>'" msgstr "cibadmin --modify --crm_xml ‘<cib admin_epoch=\"42\"/>'" #. Tag: para #, no-c-format msgid "A complete set of fields will look something like this:" msgstr "Un set complet de câmpuri ar arăta ceva de genul acesta:" #. Tag: title #, no-c-format msgid "An example of the fields set for a cib object" msgstr "Un exemplu al câmpurilor setate pentru un obiect CIB" #. Tag: programlisting #, fuzzy, no-c-format msgid "" "<cib have-quorum=\"true\" validate-with=\"pacemaker-1.0\"\n" " admin_epoch=\"1\" epoch=\"12\" num_updates=\"65\"\n" " dc-uuid=\"ea7d39f4-3b94-4cfa-ba7a-952956daabee\">" msgstr "" "<cib have-quorum=\"true\" validate-with=\"pacemaker-1.0\"\n" " admin_epoch=\"1\" epoch=\"12\" num_updates=\"65\"\n" " dc-uuid=\"ea7d39f4-3b94-4cfa-ba7a-952956daabee\"> \n" "\t " #. Tag: para #, no-c-format msgid "Cluster options, as you might expect, control how the cluster behaves when confronted with certain situations." msgstr "Opţiunile clusterului, aşa cum v-aţi aştepta, controlează cum se comportă clusterul când se confruntă cu anumite situaţii." #. Tag: para #, fuzzy, no-c-format msgid "They are grouped into sets and, in advanced configurations, there may be more than one. This will be described later in the section on where we will show how to have the cluster use different sets of options during working hours (when downtime is usually to be avoided at all costs) than it does during the weekends (when resources can be moved to the their preferred hosts without bothering end users) For now we will describe the simple case where each option is present at most once." msgstr "Sunt grupate în seturi şi, în configuraţii avansate, ar putea fi mai mult de una Acest aspect va fi descris mai târziu în secţiunea despre unde vă vom arăta cum să punem clusterul să folosească diferite seturi de opţiuni în timpul orelor de lucru (când nefuncţionarea este de evitat cu orice preţ) faţă de cele folosite în timpul weekend-urilor (când resursele pot fi mutate pe gazdele preferate fără să deranjeze utilizatorii finali) . Momentan vom descrie cazul simplu în care fiecare opţiune este prezentă cel mult o dată." #. Tag: title #, no-c-format msgid "Available Cluster Options" msgstr "Opţiuni Disponibile ale Clusterului" #. Tag: entry #, no-c-format msgid "Option" msgstr "Opţiune" #. Tag: entry #, no-c-format msgid "Default" msgstr "Valoare implicită" #. Tag: para #, no-c-format msgid "batch-limit" msgstr "" #. Tag: para #, no-c-format msgid "30" msgstr "30" #. Tag: para #, no-c-format msgid " batch-limitCluster Option Cluster Option ClusterOptionbatch-limit Optionbatch-limit batch-limit The number of jobs that the TE is allowed to execute in parallel. The \"correct\" value will depend on the speed and load of your network and cluster nodes." msgstr "" #. Tag: para #, no-c-format msgid "migration-limit" msgstr "" #. Tag: para #, no-c-format msgid "-1 (unlimited)" msgstr "" #. Tag: para #, fuzzy, no-c-format msgid " migration-limitCluster Option Cluster Option ClusterOptionmigration-limit Optionmigration-limit migration-limit The number of migration jobs that the TE is allowed to execute in parallel on a node." msgstr "Interogarea Opțiunilor Clusterului Setarea Opțiunilor Clusterului Opțiunile ClusteruluiInterogarea Opțiunilor ClusteruluiSetarea Interogarea și Setarea Opțiunilor Clusterului" #. Tag: para #, no-c-format msgid "no-quorum-policy" msgstr "" #. Tag: para #, no-c-format msgid "stop" msgstr "stop" #. Tag: para #, fuzzy, no-c-format msgid " no-quorum-policyCluster Option Cluster Option ClusterOptionno-quorum-policy Optionno-quorum-policy no-quorum-policy What to do when the cluster does not have quorum. Allowed values:" msgstr "Interogarea Opțiunilor Clusterului Setarea Opțiunilor Clusterului Opțiunile ClusteruluiInterogarea Opțiunilor ClusteruluiSetarea Interogarea și Setarea Opțiunilor Clusterului" #. Tag: para #, fuzzy, no-c-format msgid "* ignore - continue all resource management" msgstr "ignore - continuă toată gestionarea resurselor" #. Tag: para #, fuzzy, no-c-format msgid "* freeze - continue resource management, but don’t recover resources from nodes not in the affected partition" msgstr "freeze - continuă gestionarea resurselor, dar nu recupera resurse de pe noduri care nu sunt în partiţia afectată" #. Tag: para #, fuzzy, no-c-format msgid "* stop - stop all resources in the affected cluster partition" msgstr "stop - opreşte toate resursele în partiţia de cluster afectată" #. Tag: para #, fuzzy, no-c-format msgid "* suicide - fence all nodes in the affected cluster partition" msgstr "suicide - evacuează forțat toate nodurile din partiţia de cluster afectată" #. Tag: para #, no-c-format msgid "symmetric-cluster" msgstr "" #. Tag: para #, no-c-format msgid "TRUE" msgstr "TRUE" #. Tag: para #, fuzzy, no-c-format msgid " symmetric-clusterCluster Option Cluster Option ClusterOptionsymmetric-cluster Optionsymmetric-cluster symmetric-cluster Can all resources run on any node by default?" msgstr "Interogarea Opțiunilor Clusterului Setarea Opțiunilor Clusterului Opțiunile ClusteruluiInterogarea Opțiunilor ClusteruluiSetarea Interogarea și Setarea Opțiunilor Clusterului" #. Tag: para #, no-c-format msgid "stonith-enabled" msgstr "" #. Tag: para #, no-c-format msgid " stonith-enabledCluster Option Cluster Option ClusterOptionstonith-enabled Optionstonith-enabled stonith-enabled Should failed nodes and nodes with resources that can’t be stopped be shot? If you value your data, set up a STONITH device and enable this." msgstr "" #. Tag: para #, no-c-format msgid "If true, or unset, the cluster will refuse to start resources unless one or more STONITH resources have been configured also." msgstr "Dacă este true, sau nu este setată, clusterul va refuza să pornească resurse decât dacă unul sau mai multe dispozitive STONITH au fost configurate de asemenea." #. Tag: para #, no-c-format msgid "stonith-action" msgstr "" #. Tag: para #, no-c-format msgid "reboot" msgstr "reboot" #. Tag: para #, no-c-format msgid " stonith-actionCluster Option Cluster Option ClusterOptionstonith-action Optionstonith-action stonith-action Action to send to STONITH device. Allowed values: reboot, off. The value poweroff is also allowed, but is only used for legacy devices." msgstr "" #. Tag: para #, no-c-format msgid "cluster-delay" msgstr "" #. Tag: para #, no-c-format msgid "60s" msgstr "60s" #. Tag: para #, no-c-format msgid " cluster-delayCluster Option Cluster Option ClusterOptioncluster-delay Optioncluster-delay cluster-delay Round trip delay over the network (excluding action execution). The \"correct\" value will depend on the speed and load of your network and cluster nodes." msgstr "" #. Tag: para #, no-c-format msgid "stop-orphan-resources" msgstr "" #. Tag: para #, fuzzy, no-c-format msgid " stop-orphan-resourcesCluster Option Cluster Option ClusterOptionstop-orphan-resources Optionstop-orphan-resources stop-orphan-resources Should deleted resources be stopped?" msgstr "Interogarea Opțiunilor Clusterului Setarea Opțiunilor Clusterului Opțiunile ClusteruluiInterogarea Opțiunilor ClusteruluiSetarea Interogarea și Setarea Opțiunilor Clusterului" #. Tag: para #, no-c-format msgid "stop-orphan-actions" msgstr "" #. Tag: para #, fuzzy, no-c-format msgid " stop-orphan-actionsCluster Option Cluster Option ClusterOptionstop-orphan-actions Optionstop-orphan-actions stop-orphan-actions Should deleted actions be cancelled?" msgstr "Interogarea Opțiunilor Clusterului Setarea Opțiunilor Clusterului Opțiunile ClusteruluiInterogarea Opțiunilor ClusteruluiSetarea Interogarea și Setarea Opțiunilor Clusterului" #. Tag: para #, no-c-format msgid "start-failure-is-fatal" msgstr "" #. Tag: para #, no-c-format msgid " start-failure-is-fatalCluster Option Cluster Option ClusterOptionstart-failure-is-fatal Optionstart-failure-is-fatal start-failure-is-fatal When set to FALSE, the cluster will instead use the resource’s failcount and value for resource-failure-stickiness." msgstr "" #. Tag: para #, no-c-format msgid "pe-error-series-max" msgstr "" #. Tag: para #, no-c-format msgid "-1 (all)" msgstr "-1 (all)" #. Tag: para #, fuzzy, no-c-format msgid " pe-error-series-maxCluster Option Cluster Option ClusterOptionpe-error-series-max Optionpe-error-series-max pe-error-series-max The number of PE inputs resulting in ERRORs to save. Used when reporting problems." msgstr "Interogarea Opțiunilor Clusterului Setarea Opțiunilor Clusterului Opțiunile ClusteruluiInterogarea Opțiunilor ClusteruluiSetarea Interogarea și Setarea Opțiunilor Clusterului" #. Tag: para #, no-c-format msgid "pe-warn-series-max" msgstr "" #. Tag: para #, fuzzy, no-c-format msgid " pe-warn-series-maxCluster Option Cluster Option ClusterOptionpe-warn-series-max Optionpe-warn-series-max pe-warn-series-max The number of PE inputs resulting in WARNINGs to save. Used when reporting problems." msgstr "Interogarea Opțiunilor Clusterului Setarea Opțiunilor Clusterului Opțiunile ClusteruluiInterogarea Opțiunilor ClusteruluiSetarea Interogarea și Setarea Opțiunilor Clusterului" #. Tag: para #, no-c-format msgid "pe-input-series-max" msgstr "" #. Tag: para #, fuzzy, no-c-format msgid " pe-input-series-maxCluster Option Cluster Option ClusterOptionpe-input-series-max Optionpe-input-series-max pe-input-series-max The number of \"normal\" PE inputs to save. Used when reporting problems." msgstr "Interogarea Opțiunilor Clusterului Setarea Opțiunilor Clusterului Opțiunile ClusteruluiInterogarea Opțiunilor ClusteruluiSetarea Interogarea și Setarea Opțiunilor Clusterului" #. Tag: para #, fuzzy, no-c-format msgid "You can always obtain an up-to-date list of cluster options, including their default values, by running the pengine metadata command." msgstr "Puteţi întotdeauna să obţineţi o listă actualizată a opţiunilor clusterului, incluzând valorile implicite ale acestora, prin rularea comenzii pengine metadata." #. Tag: title #, fuzzy, no-c-format msgid "Querying and Setting Cluster Options" msgstr "Opţiuni Disponibile ale Clusterului" #. Tag: para #, fuzzy, no-c-format msgid " QueryingCluster Option Cluster Option SettingCluster Option Cluster Option ClusterQuerying Options Querying Options ClusterSetting Options Setting Options " msgstr "Interogarea Opțiunilor Clusterului Setarea Opțiunilor Clusterului Opțiunile ClusteruluiInterogarea Opțiunilor ClusteruluiSetarea Interogarea și Setarea Opțiunilor Clusterului" #. Tag: para #, fuzzy, no-c-format msgid "Cluster options can be queried and modified using the crm_attribute tool. To get the current value of cluster-delay, simply use:" msgstr "Opţiunile clusterului pot fi interogate şi modificate folosind utilitarul crm_attribute. Pentru a obţine valoarea curentă a cluster-delay, pur şi simplu folosiţi:" #. Tag: programlisting #, fuzzy, no-c-format msgid "# crm_attribute --attr-name cluster-delay --get-value" msgstr "crm_attribute --attr-name cluster-delay --get-value" #. Tag: para #, no-c-format msgid "which is more simply written as" msgstr "care este scrisă mai simplu ca" #. Tag: programlisting #, fuzzy, no-c-format msgid "# crm_attribute --get-value -n cluster-delay" msgstr "crm_attribute --get-value -n cluster-delay" #. Tag: para #, fuzzy, no-c-format msgid "If a value is found, you’ll see a result like this:" msgstr "Dacă o valoare este găsită, atunci veţi vedea un rezultat ca acesta" #. Tag: programlisting #, fuzzy, no-c-format msgid "" "# crm_attribute --get-value -n cluster-delay\n" " name=cluster-delay value=60s" msgstr "" " # crm_attribute --get-value -n cluster-delay\n" " name=cluster-delay value=60s" #. Tag: para #, no-c-format msgid "However, if no value is found, the tool will display an error:" msgstr "Însă dacă nici o valoare nu este găsită, utilitarul va arăta o eroare:" #. Tag: programlisting #, fuzzy, no-c-format msgid "" "# crm_attribute --get-value -n clusta-deway`\n" "name=clusta-deway value=(null)\n" "Error performing operation: The object/attribute does not exist" msgstr "" "# crm_attribute --get-value -n clusta-deway\n" " name=clusta-deway value=(null)\n" " Error performing operation: The object/attribute does not exist" #. Tag: para #, fuzzy, no-c-format msgid "To use a different value, eg. 30, simply run:" msgstr "Pentru a folosi o altă valoare, ex. , pur şi simplu rulaţi:" #. Tag: programlisting #, fuzzy, no-c-format msgid "# crm_attribute --attr-name cluster-delay --attr-value 30s" msgstr "crm_attribute --attr-name cluster-delay --attr-value 30s" #. Tag: para #, fuzzy, no-c-format msgid "To go back to the cluster’s default value you can delete the value, for example with this command:" msgstr "Pentru a reveni la valoarea implicită a clusterului puteţi ştergeţi valoarea, de exemplu cu această comandă: " #. Tag: programlisting #, fuzzy, no-c-format msgid "# crm_attribute --attr-name cluster-delay --delete-attr" msgstr "crm_attribute --attr-name cluster-delay --delete-attr" #. Tag: title #, no-c-format msgid "When Options are Listed More Than Once" msgstr "Când Opţiunile sunt Listate Mai Mult De O Dată" #. Tag: para #, fuzzy, no-c-format msgid "If you ever see something like the following, it means that the option you’re modifying is present more than once." msgstr "Dacă vedeţi vreodată ceva precum următoarele, înseamnă că opţiunea pe care o modificaţi este prezentă mai mult de o dată." #. Tag: title #, no-c-format msgid "Deleting an option that is listed twice" msgstr "Ştergerea unei opţiuni care este listată de două ori" #. Tag: programlisting #, fuzzy, no-c-format msgid "" "# crm_attribute --attr-name batch-limit --delete-attr\n" "\n" "Multiple attributes match name=batch-limit in crm_config:\n" "Value: 50 (set=cib-bootstrap-options, id=cib-bootstrap-options-batch-limit)\n" "Value: 100 (set=custom, id=custom-batch-limit)\n" "Please choose from one of the matches above and supply the 'id' with --attr-id" msgstr "" "# crm_attribute --attr-name batch-limit --delete-attr\n" " Multiple attributes match name=batch-limit in crm_config:\n" " Value: 50 (set=cib-bootstrap-options, id=cib-bootstrap-options-batch-limit)\n" " Value: 100 (set=custom, id=custom-batch-limit)\n" " Please choose from one of the matches above and supply the 'id' with --attr-id" #. Tag: para #, fuzzy, no-c-format msgid "In such cases follow the on-screen instructions to perform the requested action. To determine which value is currently being used by the cluster, please refer to ." msgstr "În astfel de cazuri urmaţi instrucţiunile de pe ecran pentru a efectua acţiunea cerută. Pentru a determina care valoare este folosită în mod curent de către cluster, vă rugăm să faceţi referinţă la secţiunea despre ." #~ msgid "Special Cluster Options Cluster OptionsSpecial Options Special Options" #~ msgstr "Opțiunile Speciale ale Clusterului Opțiunile ClusteruluiOpțiuni Speciale Opțiuni Speciale" #~ msgid "Configuration Version, Cluster Option Cluster OptionsConfiguration Version Configuration Version" #~ msgstr "Versiunea Configurației, Opțiunea Clusterului Opțiunile ClusteruluiVersiunea Configurației Versiunea Configurației" #~ msgid "admin_epoch Cluster Option Cluster Optionsadmin_epoch admin_epoch" #~ msgstr "Opțiunea Clusterului admin_epoch Opțiunile Clusteruluiadmin_epoch admin_epoch" #~ msgid "Never modified by the cluster. Use this to make the configurations on any inactive nodes obsolete." #~ msgstr "Niciodată modificat de către cluster. Folosiţi acesta pentru a face configuraţiile pe nodurile inactive să fie învechite." #~ msgid "epoch Cluster Option Cluster Optionsepoch epoch" #~ msgstr "Opțiunea Clusterului epoch Opțiunile Clusteruluiepoch epoch" #~ msgid "Incremented every time the configuration is updated (usually by the admin)" #~ msgstr "Incrementată de fiecare dată când configuraţia este actualizată (de obicei de către administrator)" #~ msgid "num_updates Cluster Option Cluster Optionsnum_updates num_updates" #~ msgstr "Opțiunea Clusterului num_updates Opțiunile Clusteruluinum_updates num_updates" #~ msgid "Incremented every time the configuration or status is updated (usually by the cluster)" #~ msgstr "Incrementată de fiecare dată când configuraţia sau statusul este actualizat (de obicei de către cluster)" #~ msgid "validate-with Cluster Option Cluster Optionsvalidate-with validate-with" #~ msgstr "Opțiunea Clusterului validate-with Opțiunile Clusteruluivalidate-with validate-with" #~ msgid "Determines the type of validation being done on the configuration. If set to \"none\", the cluster will not verify that updates conform to the DTD (nor reject ones that don't). This option can be useful when operating a mixed version cluster during an upgrade." #~ msgstr "Determină tipul de validare care este realizat pe configuraţie. Dacă este setat pe \"none\", clusterul nu va verifica dacă actualizările sunt conforme cu DTD (nici nu le va respinge pe cele care nu sunt). Această opţiune poate fi utilă când lucraţi cu o versiune combinată a clusterului în timpul unei actualizări." #~ msgid "cib-last-written Cluster Fields Cluster Fieldscib-last-written cib-last-written" #~ msgstr "Câmpurile Clusterului cib-last-written Câmpurile Clusteruluicib-last-written cib-last-written" #~ msgid "Indicates when the configuration was last written to disk. Informational purposes only." #~ msgstr "Indică momentul când configuraţia a fost scrisă ultima oară pe disc. Numai cu scop informaţional." #~ msgid "dc-uuid Cluster Fields Cluster Fieldsdc-uuid dc-uuid" #~ msgstr "Câmpurile Clusterului dc-uuid Câmpurile Clusteruluidc-uuid dc-uuid" #~ msgid "Indicates which cluster node is the current leader. Used by the cluster when placing resources and determining the order of some events." #~ msgstr "Arată care dintre nodurile clusterului este conducătorul curent. Folosit de către cluster când plasează resurse şi determină ordinea anumitor evenimente." #~ msgid "have-quorum Cluster Fields Cluster Fieldshave-quorum have-quorum" #~ msgstr "Câmpurile Clusterului have-quorum Câmpurile Clusteruluihave-quorum have-quorum" #~ msgid "Indicates if the cluster has quorum. If false, this may mean that the cluster cannot start resources or fence other nodes. See no-quorum-policy below." #~ msgstr "Indică dacă clusterul are quorum. Dacă este fals, acest lucru ar putea însemna că, clusterul nu poate porni resurse sau evacua forțat alte noduri. Vedeţi no-quorum-policy mai jos." #~ msgid "batch-limit Cluster Options Cluster Optionsbatch-limit batch-limit" #~ msgstr "Opțiunea Clusterului batch-limit Opțiunile Clusteruluibatch-limit batch-limit" #~ msgid "The number of jobs that the TE is allowed to execute in parallel. The \"correct\" value will depend on the speed and load of your network and cluster nodes." #~ msgstr "Numărul de sarcini pe care TE-ul este permis să le execute în paralel. Valoarea \"corectă\" va depinde de viteza şi de încărcarea reţelei şi a nodurilor voastre din cluster." #~ msgid "no-quorum-policy Cluster Options Cluster Optionsno-quorum-policy no-quorum-policy" #~ msgstr "Opțiunea Clusterului no-quorum-policy Opțiunile Clusteruluino-quorum-policy no-quorum-policy" #~ msgid "What to do when the cluster does not have quorum. Allowed values:" #~ msgstr "Ce este de făcut atunci când clusterul nu are quorum. Valori permise:" #~ msgid "symmetric-cluster Cluster Options Cluster Optionssymmetric-cluster symmetric-cluster" #~ msgstr "Opțiunea Clusterului symmetric-cluster Opțiunile Clusteruluisymmetric-cluster symmetric-cluster" #~ msgid "Can all resources run on any node by default?" #~ msgstr "Pot rula toate resursele pe orice nod în mod implicit?" #~ msgid "stonith-enabled Cluster Options Cluster Optionsstonith-enabled stonith-enabled" #~ msgstr "Opțiunea Clusterului stonith-enabled Opțiunile Clusteruluistonith-enabled stonith-enabled" #~ msgid "Should failed nodes and nodes with resources that can't be stopped be shot? If you value your data, set up a STONITH device and enable this." #~ msgstr "Ar trebui nodurile care au eşuat şi nodurile cu resurse care nu pot fi oprite să fie împuşcate? Dacă ţineţi la datele voastre, setaţi un dispozitiv STONITH şi activaţi această opţiune." #~ msgid "stonith-action Cluster Options Cluster Optionsstonith-action stonith-action" #~ msgstr "Opțiunea Clusterului stonith-action Opțiunile Clusteruluistonith-action stonith-action" #~ msgid "Action to send to STONITH device. Allowed values: reboot, poweroff." #~ msgstr "Acţiunea care să fie trimisă către dispozitivul STONITH. Valori permise: reboot, poweroff." #~ msgid "cluster-delay Cluster Options Cluster Optionscluster-delay cluster-delay" #~ msgstr "Opțiunea Clusterului cluster-delay Opțiunile Clusteruluicluster-delay cluster-delay" #~ msgid "Round trip delay over the network (excluding action execution). The \"correct\" value will depend on the speed and load of your network and cluster nodes." #~ msgstr "Întârzierea dus-întors experimentată pe reţea (excluzând timpul necesar executării acţiunii). Valoarea \"corectă\" va depinde de viteza şi de nivelul de încărcare al reţelei şi al nodurilor voastre din cluster." #~ msgid "stop-orphan-resources Cluster Options Cluster Optionsstop-orphan-resources stop-orphan-resources" #~ msgstr "Opțiunea Clusterului stop-orphan-resources Opțiunile Clusteruluistop-orphan-resources stop-orphan-resources" #~ msgid "Should deleted resources be stopped?" #~ msgstr "Ar trebui să fie oprite resursele şterse?" #~ msgid "stop-orphan-actions Cluster Options Cluster Optionsstop-orphan-actions stop-orphan-actions" #~ msgstr "Opțiunea Clusterului stop-orphan-actions Opțiunile Clusteruluistop-orphan-actions stop-orphan-actions" #~ msgid "Should deleted actions be cancelled?" #~ msgstr "Ar trebui anulate acţiunile şterse?" #~ msgid "start-failure-is-fatal Cluster Options Cluster Optionsstart-failure-is-fatal start-failure-is-fatal" #~ msgstr "Opțiunea Clusterului start-failure-is-fatal Opțiunile Clusteruluistart-failure-is-fatal start-failure-is-fatal" #~ msgid "When set to FALSE, the cluster will instead use the resource's failcount and value for resource-failure-stickiness." #~ msgstr "Când este setat pe FALSE, clusterul va folosi în schimb failcount-ul şi valoarea resursei pentru resource-failure-stickiness." #~ msgid "pe-error-series-max Cluster Options Cluster Optionspe-error-series-max pe-error-series-max" #~ msgstr "Opțiunea Clusterului pe-error-series-max Opțiunile Clusteruluipe-error-series-max pe-error-series-max" #~ msgid "The number of PE inputs resulting in ERRORs to save. Used when reporting problems." #~ msgstr "Numărul de intrări PE care rezultă în ERROR(i) de a salva. Folosite când se raporteazâ probleme." #~ msgid "pe-warn-series-max Cluster Options Cluster Optionspe-warn-series-max pe-warn-series-max" #~ msgstr "Opțiunea Clusterului pe-warn-series-max Opțiunile Clusteruluipe-warn-series-max pe-warn-series-max" #~ msgid "The number of PE inputs resulting in WARNINGs to save. Used when reporting problems." #~ msgstr "Numărul de intrări PE care rezultă în WARNING-uri de a salva. Folosite când se raportează probleme." #~ msgid "pe-input-series-max Cluster Options Cluster Optionspe-input-series-max pe-input-series-max" #~ msgstr "Opțiunea Clusterului pe-input-series-max Opțiunile Clusteruluipe-input-series-max pe-input-series-max" #~ msgid "The number of \"normal\" PE inputs to save. Used when reporting problems." #~ msgstr "Numărul de intrări PE \"normale\" care să fie salvate. Folosite când se raportează probleme." pacemaker-master/doc/Pacemaker_Explained/ro-RO/Ch-Resources.po000066400000000000000000002237561217637305600245560ustar00rootroot00000000000000msgid "" msgstr "" "Project-Id-Version: Pacemaker 1.1\n" "POT-Creation-Date: 2012-10-17T05:19:02\n" "PO-Revision-Date: 2012-01-01T17:48:32\n" "Last-Translator: Dan Frîncu \n" "Language-Team: None\n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: application/x-publican; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. Tag: title #, no-c-format msgid "Cluster Resources" msgstr "Resursele Clusterului" #. Tag: title #, no-c-format msgid "What is a Cluster Resource" msgstr "Ce este o Resursă de Cluster" #. Tag: para #, fuzzy, no-c-format msgid " Resource " msgstr "id id" #. Tag: para #, fuzzy, no-c-format msgid "The role of a resource agent is to abstract the service it provides and present a consistent view to the cluster, which allows the cluster to be agnostic about the resources it manages." msgstr "Rolul agentului de resursă este de a abstractiza serviciul pe care îl furnizează şi de a prezenta o viziune consistentă clusterului, care îi permite clusterului să fie agnostic cu resursele pe care le gestionează. Clusterul nu trebuie să înţeleagă cum funcţionează resursa pentru că se bazează pe agentul de resursă să efectueze ceea ce trebuie atunci când îi este trimisă o comandă de start, stop sau monitor." #. Tag: para #, fuzzy, no-c-format msgid "The cluster doesn’t need to understand how the resource works because it relies on the resource agent to do the right thing when given a start, stop or monitor command." msgstr "Rolul agentului de resursă este de a abstractiza serviciul pe care îl furnizează şi de a prezenta o viziune consistentă clusterului, care îi permite clusterului să fie agnostic cu resursele pe care le gestionează. Clusterul nu trebuie să înţeleagă cum funcţionează resursa pentru că se bazează pe agentul de resursă să efectueze ceea ce trebuie atunci când îi este trimisă o comandă de start, stop sau monitor." #. Tag: para #, no-c-format msgid "For this reason it is crucial that resource agents are well tested." msgstr "Din acest motiv este imperativ ca agenţii de resursă să fie testaţi corespunzător." #. Tag: para #, no-c-format msgid "Typically resource agents come in the form of shell scripts, however they can be written using any technology (such as C, Python or Perl) that the author is comfortable with." msgstr "În mod normal agenţii de resursă vin sub forma de scripturi de shell, însă aceştia pot fi scrişi folosind orice limbaj de programare (cum ar fi C, Python sau Perl) cu care este confortabil autorul." #. Tag: title #, no-c-format msgid "Supported Resource Classes" msgstr "Clase de Resurse Suportate" #. Tag: para #, fuzzy, no-c-format msgid " Resourceclass class " msgstr "classCâmpul Resursei CâmpulResurseiclass class" #. Tag: para #, fuzzy, no-c-format msgid "There are five classes of agents supported by Pacemaker:" msgstr "Există trei clase de bază de agenţi suportate de Pacemaker. În ordinea în care este încurajată folosirea acestora ele sunt:" #. Tag: para #, no-c-format msgid "OCF" msgstr "" #. Tag: para #, no-c-format msgid "LSB" msgstr "" #. Tag: para #, no-c-format msgid "Upstart" msgstr "" #. Tag: para #, no-c-format msgid "Systemd" msgstr "" #. Tag: para #, no-c-format msgid "Fencing" msgstr "" #. Tag: para #, no-c-format msgid "Service" msgstr "" #. Tag: para #, fuzzy, no-c-format msgid " ResourceHeartbeat Heartbeat HeartbeatResources Resources " msgstr "classCâmpul Resursei CâmpulResurseiclass class" #. Tag: para #, fuzzy, no-c-format msgid "Version 1 of Heartbeat came with its own style of resource agents and it is highly likely that many people have written their own agents based on its conventions. See http://wiki.linux-ha.org/HeartbeatResourceAgent for more information " msgstr "Versiunea 1 de Heartbeat venea cu propriul stil de agenţi de resursă şi este foarte probabil că mulţi oameni şi-au scris proprii agenţi de resursă pe baza convenţiilor acestuia. Pentru a permite administratorilor să continue folosirea acestor agenţi, aceştia sunt suportaţi de către noul manager de cluster Vedeți pentru mai multe informații.." #. Tag: para #, no-c-format msgid "Although deprecated with the release of Heartbeat v2, they were supported by Pacemaker up until the release of 1.1.8 to enable administrators to continue to use these agents." msgstr "" #. Tag: title #, no-c-format msgid "Open Cluster Framework" msgstr "Open Cluster Framework" #. Tag: para #, no-c-format msgid " ResourceOCF OCF OCFResources Resources Open Cluster FrameworkResources Resources " msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "The OCF standard http://www.opencf.org/cgi-bin/viewcvs.cgi/specs/ra/resource-agent-api.txt?rev=HEAD - at least as it relates to resource agents. The Pacemaker implementation has been somewhat extended from the OCF Specs, but none of those changes are incompatible with the original OCF specification. is basically an extension of the Linux Standard Base conventions for init scripts to:" msgstr "Spec-ul OCF - cel puțin partea care se leagă de agenții de resursă.'Notă: Implementarea Pacemaker a fost oarecum extinsă din Specificațiile OCF, dar nici una din acele modificări nu sunt incompatibile cu specificația originală OCF. este în principiu o extensie a convențiilor Linux Standard Base folosite pentru scripturile de init ca să" #. Tag: para #, no-c-format msgid "support parameters," msgstr "suporte parametri" #. Tag: para #, no-c-format msgid "make them self describing and" msgstr "să îi facă auto descriptivi şi" #. Tag: para #, no-c-format msgid "extensible" msgstr "extensibili" #. Tag: para #, no-c-format msgid "OCF specs have strict definitions of the exit codes that actions must return. Included with the cluster is the ocf-tester script, which can be useful in this regard. " msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "The cluster follows these specifications exactly, and giving the wrong exit code will cause the cluster to behave in ways you will likely find puzzling and annoying. In particular, the cluster needs to distinguish a completely stopped resource from one which is in some erroneous and indeterminate state." msgstr "Specificaţiile OCF au definiţii stricte asupra căror coduri de ieşire trebuie să returneze acţiunile Inclus cu clusterul este scriptul ocf-tester care poate fi folositor în această privinţă. . Clusterul urmează aceste specificaţii întocmai, iar ieşirea din execuţie cu codul de eroare greşit va cauza clusterul să se comporte în feluri pe care le puteţi găsi enervante şi lipsite de sens. În mod special, clusterul trebuie să poată distinge între o resursă oprită complet şi una care se află într-o stare eronată sau nedeterminată." #. Tag: para #, fuzzy, no-c-format msgid "Parameters are passed to the script as environment variables, with the special prefix OCF_RESKEY_. So, a parameter which the user thinks of as ip it will be passed to the script as OCF_RESKEY_ip. The number and purpose of the parameters is completely arbitrary, however your script should advertise any that it supports using the meta-data command." msgstr "Parametrii sunt pasaţi scriptului ca variabile de mediu, cu prefixul special OCF_RESKEY_. Deci, un parametru pe care utilizatorul îl consideră ca fiind ip va fi pasat către script ca OCF_RESKEY_ip. Numărul şi scopul parametrilor este complet arbitrar, însă scriptul vostru ar trebui să îi anunţe pe toţi pe care îi suportă folosind comanda meta-data." #. Tag: para #, no-c-format msgid "The OCF class is the most preferred one as it is an industry standard, highly flexible (allowing parameters to be passed to agents in a non-positional manner) and self-describing." msgstr "Clasa OCF este cea mai preferată din moment ce este un standard al industriei, foarte flexibilă (permiţând parametrii să fie pasaţi agenţilor într-o manieră care nu ţine cont de poziţia acestora) şi auto-descriptivă." #. Tag: para #, fuzzy, no-c-format msgid "For more information, see the reference and ." msgstr "Pentru mai multe informaţii, vedeţi referința şi ." #. Tag: title #, no-c-format msgid "Linux Standard Base" msgstr "Linux Standard Base" #. Tag: para #, no-c-format msgid " ResourceLSB LSB LSBResources Resources Linux Standard BaseResources Resources " msgstr "" #. Tag: para #, no-c-format msgid "LSB resource agents are those found in /etc/init.d." msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "Generally they are provided by the OS/distribution and, in order to be used with the cluster, they must conform to the LSB Spec. See http://refspecs.linux-foundation.org/LSB_3.0.0/LSB-Core-generic/LSB-Core-generic/iniscrptact.html for the LSB Spec (as it relates to init scripts). " msgstr "Agenţii de resursă LSB sunt cei găsiţi în /etc/init.d. În mod normal aceştia sunt furnizaţi de către OS/distribuţie şi pentru a putea fi folosiţi împreună cu clusterul, trebuie să se conforme Specificaţiilor LSB Vedeți pentru Spec-ul LSB (partea care se leagă de scripturi de init). ." #. Tag: para #, fuzzy, no-c-format msgid "Many distributions claim LSB compliance but ship with broken init scripts. For details on how to check if your init script is LSB-compatible, see . The most common problems are:" msgstr "Multe distribuţii afirmă compatibilitatea LSB dar livrează scripturi de init nefuncţionale din acest punct de vedere. Pentru a vedea dacă scriptul vostru de init este compatibil LSB, vedeţi intrarea din FAQ referitoare la . Cele mai comune probleme sunt:" #. Tag: para #, no-c-format msgid "Not implementing the status operation at all" msgstr "Neimplementarea în vreun fel a operaţiunii status" #. Tag: para #, no-c-format msgid "Not observing the correct exit status codes for start/stop/status actions" msgstr "Neobservarea status-urilor corecte de ieşire pentru acţiuni start/stop/status" #. Tag: para #, no-c-format msgid "Starting a started resource returns an error (this violates the LSB spec)" msgstr "Pornirea unei resurse deja pornite returnează o eroare (acest aspect încalcă specificaţia LSB)" #. Tag: para #, no-c-format msgid "Stopping a stopped resource returns an error (this violates the LSB spec)" msgstr "Oprirea unei resurse deja oprită returnează o eroare (acest aspect încalcă specificaţia LSB)" #. Tag: para #, fuzzy, no-c-format msgid " ResourceSystemd Systemd SystemdResources Resources " msgstr "classCâmpul Resursei CâmpulResurseiclass class" #. Tag: para #, no-c-format msgid "Some newer distributions have replaced the old SYS-V style of initialization daemons (and scripts) with an alternative called Systemd." msgstr "" #. Tag: para #, no-c-format msgid "Pacemaker is able to manage these services if they are present." msgstr "" #. Tag: para #, no-c-format msgid "Instead of init scripts, systemd has unit files. Generally the services (or unit files) are provided by the OS/distribution but there are some instructions for converting from init scripts at: http://0pointer.de/blog/projects/systemd-for-admins-3.html" msgstr "" #. Tag: para #, no-c-format msgid "Remember to make sure the computer is not configured to start any services at boot time that should be controlled by the cluster." msgstr "" #. Tag: para #, fuzzy, no-c-format msgid " ResourceUpstart Upstart UpstartResources Resources " msgstr "classCâmpul Resursei CâmpulResurseiclass class" #. Tag: para #, no-c-format msgid "Some newer distributions have replaced the old SYS-V style of initialization daemons (and scripts) with an alternative called Upstart." msgstr "" #. Tag: para #, no-c-format msgid "Instead of init scripts, upstart has jobs. Generally the services (or jobs) are provided by the OS/distribution." msgstr "" #. Tag: title #, no-c-format msgid "System Services" msgstr "" #. Tag: para #, fuzzy, no-c-format msgid " ResourceSystem Services System Services System ServiceResources Resources " msgstr "classCâmpul Resursei CâmpulResurseiclass class" #. Tag: para #, no-c-format msgid "Since there are now many \"common\" types of system services (systemd, upstart, and lsb), Pacemaker supports a special alias which intelligently figures out which one applies to a given cluster node." msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "This is particularly useful when the cluster contains a mix of systemd, upstart, and lsb." msgstr "Acţiunea pe care să o execute. Valori obişnuite: monitor, start, stop" #. Tag: para #, no-c-format msgid "In order, Pacemaker will try to find the named service as:" msgstr "" #. Tag: para #, no-c-format msgid "an LSB (SYS-V) init script" msgstr "" #. Tag: para #, no-c-format msgid "a Systemd unit file" msgstr "" #. Tag: para #, no-c-format msgid "an Upstart job" msgstr "" #. Tag: title #, no-c-format msgid "STONITH" msgstr "STONITH" #. Tag: para #, fuzzy, no-c-format msgid " ResourceSTONITH STONITH STONITHResources Resources " msgstr "classCâmpul Resursei CâmpulResurseiclass class" #. Tag: para #, no-c-format msgid "There is also an additional class, STONITH, which is used exclusively for fencing related resources. This is discussed later in ." msgstr "Mai există o clasă adiţională, STONITH, care este folosită exclusiv pentru resurse relevante în procesul de evacuare forțată. Acest aspect este discutat mai târziu în ." #. Tag: title #, fuzzy, no-c-format msgid "Resource Properties" msgstr "Operaţiile Resurselor" #. Tag: para #, no-c-format msgid "These values tell the cluster which script to use for the resource, where to find that script and what standards it conforms to." msgstr "Aceste valori îi spun clusterului care script să îl folosească pentru resursă, unde să găsească acel script şi care sunt standardele la care acesta aderă." #. Tag: title #, no-c-format msgid "Properties of a Primitive Resource" msgstr "Proprietăţile unei Resurse Primitive" #. Tag: entry #, no-c-format msgid "Field" msgstr "Câmp" #. Tag: entry #, no-c-format msgid "Description" msgstr "Descriere" #. Tag: para #, fuzzy, no-c-format msgid "id" msgstr "0" #. Tag: para #, fuzzy, no-c-format msgid "Your name for the resource idResource Resource ResourcePropertyid Propertyid id " msgstr "priorityOpțiunea Resursei OpțiuneaResurseipriority priority" #. Tag: para #, fuzzy, no-c-format msgid "class" msgstr "0" #. Tag: para #, no-c-format msgid "The standard the script conforms to. Allowed values: ocf, service, upstart, systemd, lsb, stonith classResource Resource ResourcePropertyclass Propertyclass class " msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "type" msgstr "0" #. Tag: para #, no-c-format msgid "The name of the Resource Agent you wish to use. Eg. IPaddr or Filesystem typeResource Resource ResourcePropertytype Propertytype type " msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "provider" msgstr "0" #. Tag: para #, no-c-format msgid "The OCF spec allows multiple vendors to supply the same ResourceAgent. To use the OCF resource agents supplied with Heartbeat, you should specify heartbeat here. providerResource Resource ResourcePropertyprovider Propertyprovider provider " msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "Resource definitions can be queried with the crm_resource tool. For example" msgstr "Definiţiile resurselor pot fi interogate cu utilitarul crm_resource. De exemplu" #. Tag: programlisting #, fuzzy, no-c-format msgid "# crm_resource --resource Email --query-xml" msgstr "crm_resource --resource Email --query-xml" #. Tag: para #, fuzzy, no-c-format msgid "might produce:" msgstr "ar putea produce" #. Tag: title #, fuzzy, no-c-format msgid "An example system resource" msgstr "Un exemplu de resursă LSB" #. Tag: programlisting #, fuzzy, no-c-format msgid "<primitive id=\"Email\" class=\"service\" type=\"exim\"/>" msgstr "" "<primitive id=\"Email\" class=\"lsb\" type=\"exim\"/>\n" "\t" #. Tag: para #, fuzzy, no-c-format msgid "One of the main drawbacks to system services (such as LSB, Systemd and Upstart) resources is that they do not allow any parameters!" msgstr "Unul din principalele aspecte negative ale resurselor LSB este acela că nu permit parametri!" #. Tag: title #, no-c-format msgid "An example OCF resource" msgstr "Un exemplu de resursă OCF" #. Tag: programlisting #, fuzzy, no-c-format msgid "" "<primitive id=\"Public-IP\" class=\"ocf\" type=\"IPaddr\" provider=\"heartbeat\">\n" " <instance_attributes id=\"params-public-ip\">\n" " <nvpair id=\"public-ip-addr\" name=\"ip\" value=\"1.2.3.4\"/>\n" " </instance_attributes>\n" "</primitive>" msgstr "" " <primitive id=\"Public-IP\" class=\"ocf\" type=\"IPaddr\" provider=\"heartbeat\">\n" " <instance_attributes id=\"params-public-ip\">\n" " <nvpair id=\"public-ip-addr\" name=\"ip\" value=\"1.2.3.4\"/>\n" " </instance_attributes>\n" " </primitive> " #. Tag: title #, no-c-format msgid "Resource Options" msgstr "Opţiuni ale Resurselor" #. Tag: para #, fuzzy, no-c-format msgid "Options are used by the cluster to decide how your resource should behave and can be easily set using the --meta option of the crm_resource command." msgstr "Opţiunile sunt folosite de către cluster pentru a decide cum ar trebui să se comporte resursa voastră şi pot fi setate facil folosind opţiunea --meta a comenzii crm_resource." #. Tag: title #, no-c-format msgid "Options for a Primitive Resource" msgstr "Opţiuni pentru o Resursă Primitivă" #. Tag: entry #, no-c-format msgid "Default" msgstr "Valoarea implicită" #. Tag: para #, fuzzy, no-c-format msgid "priority" msgstr "0" #. Tag: para #, no-c-format msgid "0" msgstr "0" #. Tag: para #, no-c-format msgid "If not all resources can be active, the cluster will stop lower priority resources in order to keep higher priority ones active. priorityResource Option Resource Option ResourceOptionpriority Optionpriority priority " msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "target-role" msgstr "Started" #. Tag: para #, no-c-format msgid "Started" msgstr "Started" #. Tag: para #, no-c-format msgid "What state should the cluster attempt to keep this resource in? Allowed values:" msgstr "În ce stare ar trebui să încerce clusterul să menţină această resursă? Valori permise:" #. Tag: para #, fuzzy, no-c-format msgid "* Stopped - Force the resource to be stopped" msgstr "Stopped - Forţează resursa să fie oprită" #. Tag: para #, fuzzy, no-c-format msgid "* Started - Allow the resource to be started (In the case of multi-state resources, they will not promoted to master)" msgstr "Started - Permite resursei să fie pornită (În cazul resurselor cu multi-state, acestea nu vor fi promovate la master)" #. Tag: para #, fuzzy, no-c-format msgid "* Master - Allow the resource to be started and, if appropriate, promoted target-roleResource Option Resource Option ResourceOptiontarget-role Optiontarget-role target-role " msgstr "target-roleOpțiunea Resursei OpțiuneaResurseitarget-role target-role" #. Tag: para #, fuzzy, no-c-format msgid "is-managed" msgstr "Started" #. Tag: para #, fuzzy, no-c-format msgid "TRUE" msgstr "0" #. Tag: para #, no-c-format msgid "Is the cluster allowed to start and stop the resource? Allowed values: true, false is-managedResource Option Resource Option ResourceOptionis-managed Optionis-managed is-managed " msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "resource-stickiness" msgstr "Started" #. Tag: para #, no-c-format msgid "Calculated" msgstr "" #. Tag: para #, no-c-format msgid "How much does the resource prefer to stay where it is? Defaults to the value of resource-stickiness in the rsc_defaults section resource-stickinessResource Option Resource Option ResourceOptionresource-stickiness Optionresource-stickiness resource-stickiness " msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "requires" msgstr "0" #. Tag: para #, no-c-format msgid "Under what conditions can the resource be started. (Since 1.1.8)" msgstr "" #. Tag: para #, no-c-format msgid "Defaults to fencing unless stonith-enabled is false or class is stonith - under those conditions the default is quorum. Possible values:" msgstr "" #. Tag: para #, no-c-format msgid "* nothing - can always be started" msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "* quorum - The cluster can only start this resource if a majority of the configured nodes are active" msgstr "quorum - Clusterul poate porni această resursă dacă o majoritate a nodurilor configurate este activă" #. Tag: para #, fuzzy, no-c-format msgid "* fencing - The cluster can only start this resource if a majority of the configured nodes are active and any failed or unknown nodes have been powered off." msgstr "fencing - Clusterul poate porni această resursă doar dacă o majoritate a nodurilor configurate este activă şi orice noduri necunoscute sau defectate au fost deconectate de la reţeaua de alimentare." #. Tag: para #, no-c-format msgid "* unfencing - The cluster can only start this resource if a majority of the configured nodes are active and any failed or unknown nodes have been powered off and only on nodes that have been unfenced indexterm: Option[requires,Resource] ResourceOptionrequires Optionrequires requires " msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "migration-threshold" msgstr "Started" #. Tag: para #, no-c-format msgid "INFINITY (disabled)" msgstr "INFINITY (dezactivat)" #. Tag: para #, fuzzy, no-c-format msgid "How many failures may occur for this resource on a node, before this node is marked ineligible to host this resource. migration-thresholdResource Option Resource Option ResourceOptionmigration-threshold Optionmigration-threshold migration-threshold " msgstr "migration-thresholdOpțiunea Resursei OpțiuneaResurseimigration-threshold migration-threshold" #. Tag: para #, fuzzy, no-c-format msgid "failure-timeout" msgstr "Started" #. Tag: para #, no-c-format msgid "0 (disabled)" msgstr "0 (dezactivat)" #. Tag: para #, no-c-format msgid "How many seconds to wait before acting as if the failure had not occurred, and potentially allowing the resource back to the node on which it failed. failure-timeoutResource Option Resource Option ResourceOptionfailure-timeout Optionfailure-timeout failure-timeout " msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "multiple-active" msgstr "Started" #. Tag: para #, no-c-format msgid "stop_start" msgstr "stop_start" #. Tag: para #, no-c-format msgid "What should the cluster do if it ever finds the resource active on more than one node. Allowed values:" msgstr "Ce ar trebui să realizeze clusterul dacă găseşte vreodată o resursă activă pe mai mult de un nod. Valori permise:" #. Tag: para #, fuzzy, no-c-format msgid "* block - mark the resource as unmanaged" msgstr "block - marchează resursa ca fiind negestionată" #. Tag: para #, fuzzy, no-c-format msgid "* stop_only - stop all active instances and leave them that way" msgstr "stop_only - opreşte toate instanţele active şi lasă-le în acest fel" #. Tag: para #, fuzzy, no-c-format msgid "* stop_start - stop all active instances and start the resource in one location only" msgstr "stop_start - opreşte toate instanţele active şi porneşte resursa doar într-o singură locaţie" #. Tag: para #, fuzzy, no-c-format msgid " multiple-activeResource Option Resource Option ResourceOptionmultiple-active Optionmultiple-active multiple-active " msgstr "multiple-activeOpțiunea Resursei OpțiuneaResurseimultiple-active multiple-active" #. Tag: para #, no-c-format msgid "If you performed the following commands on the previous LSB Email resource" msgstr "Dacă aţi efectuat următoarele comenzi pe resursa LSB Email anterioară" #. Tag: programlisting #, fuzzy, no-c-format msgid "" "# crm_resource --meta --resource Email --set-parameter priority --property-value 100\n" "# crm_resource --meta --resource Email --set-parameter multiple-active --property-value block" msgstr "" "crm_resource --meta --resource Email --set-parameter priority --property-value 100\n" "\tcrm_resource --meta --resource Email --set-parameter multiple-active --property-value block\n" " " #. Tag: para #, no-c-format msgid "the resulting resource definition would be" msgstr "definiţia rezultantă a resursei ar fi" #. Tag: title #, no-c-format msgid "An LSB resource with cluster options" msgstr "O resursă LSB cu opţiuni ale clusterului" #. Tag: programlisting #, fuzzy, no-c-format msgid "" "<primitive id=\"Email\" class=\"lsb\" type=\"exim\">\n" " <meta_attributes id=\"meta-email\">\n" " <nvpair id=\"email-priority\" name=\"priority\" value=\"100\"/>\n" " <nvpair id=\"email-active\" name=\"multiple-active\" value=\"block\"/>\n" " </meta_attributes>\n" "</primitive>" msgstr "" "<primitive id=\"Email\" class=\"lsb\" type=\"exim\">\n" " <meta_attributes id=\"meta-email\">\n" " <nvpair id=\"email-priority\" name=\"priority\" value=\"100\"/>\n" " <nvpair id=\"email-active\" name=\"multiple-active\" value=\"block\"/>\n" " </meta_attributes>\n" " </primitive> " #. Tag: title #, no-c-format msgid "Setting Global Defaults for Resource Options" msgstr "Setarea de Valori Implicite Globale pentru Opţiunile Clusterului" #. Tag: para #, fuzzy, no-c-format msgid "To set a default value for a resource option, simply add it to the rsc_defaults section with crm_attribute. Thus," msgstr "Pentru a seta o valoare implicită pentru o opţiune a resursei, pur şi simplu adăugaţi-o la secţiunea rsc_defaults cu crm_attribute. Astfel," #. Tag: programlisting #, fuzzy, no-c-format msgid "# crm_attribute --type rsc_defaults --attr-name is-managed --attr-value false" msgstr "crm_attribute --type rsc_defaults --attr-name is-managed --attr-value false" #. Tag: para #, no-c-format msgid "would prevent the cluster from starting or stopping any of the resources in the configuration (unless of course the individual resources were specifically enabled and had is-managed set to true)." msgstr "ar preveni clusterul de a porni sau opri orice resurse din configuraţie (cu excepţia cazului când resursele individuale au fost activate în mod specific şi aveau is-managed setat pe true)." #. Tag: title #, no-c-format msgid "Instance Attributes" msgstr "Atributele Instanţelor" #. Tag: para #, no-c-format msgid "The scripts of some resource classes (LSB not being one of them) can be given parameters which determine how they behave and which instance of a service they control." msgstr "Scripturile unor clase de resurse (LSB nefiind una dintre acestea) pot primi parametri care determină cum se comportă şi care instanţe ale unui serviciu controlează acestea." #. Tag: para #, fuzzy, no-c-format msgid "If your resource agent supports parameters, you can add them with the crm_resource command. For instance" msgstr "Dacă agentul vostru de resursă suportă parametri, îi puteţi adăuga cu comanda crm_resource. De exemplu" #. Tag: programlisting #, fuzzy, no-c-format msgid "# crm_resource --resource Public-IP --set-parameter ip --property-value 1.2.3.4" msgstr "crm_resource --resource Public-IP --set-parameter ip --property-value 1.2.3.4" #. Tag: para #, no-c-format msgid "would create an entry in the resource like this:" msgstr "ar crea o intrare în resursă precum aceasta:" #. Tag: title #, no-c-format msgid "An example OCF resource with instance attributes" msgstr "Un exemplu de resursă OCF cu atribute de instanţă" #. Tag: para #, fuzzy, no-c-format msgid "For an OCF resource, the result would be an environment variable called OCF_RESKEY_ip with a value of 1.2.3.4." msgstr "Pentru o resursă OCF, rezultatul ar fi o variabilă de mediu numită OCF_RESKEY_ip cu o valoare de 1.2.3.4." #. Tag: para #, fuzzy, no-c-format msgid "The list of instance attributes supported by an OCF script can be found by calling the resource script with the meta-data command. The output contains an XML description of all the supported attributes, their purpose and default values." msgstr "Lista de atribute de instanţă suportate de un script OCF poate fi găsită apelând scriptul resursei cu comanda meta-data. Rezultatul de ieşire conţine o descriere XML a tuturor atributelor suportate, scopul acestora şi valori implicite." #. Tag: title #, no-c-format msgid "Displaying the metadata for the Dummy resource agent template" msgstr "Afişarea metadata pentru template-ul agentului de resursă Dummy" #. Tag: programlisting #, no-c-format msgid "" "# export OCF_ROOT=/usr/lib/ocf\n" "# $OCF_ROOT/resource.d/pacemaker/Dummy meta-data" msgstr "" #. Tag: programlisting #, fuzzy, no-c-format msgid "" "<?xml version=\"1.0\"?>\n" " <!DOCTYPE resource-agent SYSTEM \"ra-api-1.dtd\">\n" " <resource-agent name=\"Dummy\" version=\"0.9\">\n" " <version>1.0</version>\n" "\n" " <longdesc lang=\"en-US\">\n" " This is a Dummy Resource Agent. It does absolutely nothing except\n" " keep track of whether its running or not.\n" " Its purpose in life is for testing and to serve as a template for RA writers.\n" " </longdesc>\n" " <shortdesc lang=\"en-US\">Dummy resource agent</shortdesc>\n" "\n" " <parameters>\n" " <parameter name=\"state\" unique=\"1\">\n" " <longdesc lang=\"en-US\">\n" " Location to store the resource state in.\n" " </longdesc>\n" " <shortdesc lang=\"en-US\">State file</shortdesc>\n" " <content type=\"string\" default=\"/var/run/Dummy-{OCF_RESOURCE_INSTANCE}.state\" />\n" " </parameter>\n" "\n" " <parameter name=\"dummy\" unique=\"0\">\n" " <longdesc lang=\"en-US\">\n" " Dummy attribute that can be changed to cause a reload\n" " </longdesc>\n" " <shortdesc lang=\"en-US\">Dummy attribute that can be changed to cause a reload</shortdesc>\n" " <content type=\"string\" default=\"blah\" />\n" " </parameter>\n" " </parameters>\n" "\n" " <actions>\n" " <action name=\"start\" timeout=\"90\" />\n" " <action name=\"stop\" timeout=\"100\" />\n" " <action name=\"monitor\" timeout=\"20\" interval=\"10\",height=\"0\" start-delay=\"0\" />\n" " <action name=\"reload\" timeout=\"90\" />\n" " <action name=\"migrate_to\" timeout=\"100\" />\n" " <action name=\"migrate_from\" timeout=\"90\" />\n" " <action name=\"meta-data\" timeout=\"5\" />\n" " <action name=\"validate-all\" timeout=\"30\" />\n" " </actions>\n" " </resource-agent>" msgstr "" "export OCF_ROOT=/usr/lib/ocf; $OCF_ROOT/resource.d/pacemaker/Dummy meta-data\n" " <?xml version=\"1.0\"?>\n" " <!DOCTYPE resource-agent SYSTEM \"ra-api-1.dtd\">\n" " <resource-agent name=\"Dummy\" version=\"0.9\">\n" " <version>1.0</version>\n" " \n" " <longdesc lang=\"en-US\">\n" " This is a Dummy Resource Agent. It does absolutely nothing except \n" " keep track of whether its running or not.\n" " Its purpose in life is for testing and to serve as a template for RA writers.\n" " </longdesc>\n" " <shortdesc lang=\"en-US\">Dummy resource agent</shortdesc>\n" " \n" " <parameters>\n" " <parameter name=\"state\" unique=\"1\">\n" " <longdesc lang=\"en-US\">\n" " Location to store the resource state in.\n" " </longdesc>\n" " <shortdesc lang=\"en-US\">State file</shortdesc>\n" " <content type=\"string\" default=\"/var/run/Dummy-{OCF_RESOURCE_INSTANCE}.state\" />\n" " </parameter>\n" " \n" " <parameter name=\"dummy\" unique=\"0\">\n" " <longdesc lang=\"en-US\"> \n" " Dummy attribute that can be changed to cause a reload\n" " </longdesc>\n" " <shortdesc lang=\"en-US\">Dummy attribute that can be changed to cause a reload</shortdesc>\n" " <content type=\"string\" default=\"blah\" />\n" " </parameter>\n" " </parameters>\n" " \n" " <actions>\n" " <action name=\"start\" timeout=\"90\" />\n" " <action name=\"stop\" timeout=\"100\" />\n" " <action name=\"monitor\" timeout=\"20\" interval=\"10\" depth=\"0\" start-delay=\"0\" />\n" " <action name=\"reload\" timeout=\"90\" />\n" " <action name=\"migrate_to\" timeout=\"100\" />\n" " <action name=\"migrate_from\" timeout=\"90\" />\n" " <action name=\"meta-data\" timeout=\"5\" />\n" " <action name=\"validate-all\" timeout=\"30\" />\n" " </actions>\n" " </resource-agent> " #. Tag: title #, no-c-format msgid "Resource Operations" msgstr "Operaţiile Resurselor" #. Tag: para #, fuzzy, no-c-format msgid " ResourceAction Action " msgstr "priorityOpțiunea Resursei OpțiuneaResurseipriority priority" #. Tag: title #, no-c-format msgid "Monitoring Resources for Failure" msgstr "Monitorizarea Resurselor pentru Defecţiuni" #. Tag: para #, fuzzy, no-c-format msgid "By default, the cluster will not ensure your resources are still healthy. To instruct the cluster to do this, you need to add a monitor operation to the resource’s definition." msgstr "În mod implicit, clusterul nu va asigura că resursele voastre sunt încă sănătoase. Pentru a instrui clusterul să realizeze acest lucru, trebuie să adăugaţi o operaţiune monitor la definiţia resursei." #. Tag: title #, no-c-format msgid "An OCF resource with a recurring health check" msgstr "O resursă OCF cu o verificare recurentă a sănătăţii" #. Tag: programlisting #, fuzzy, no-c-format msgid "" "<primitive id=\"Public-IP\" class=\"ocf\" type=\"IPaddr\" provider=\"heartbeat\">\n" " <operations>\n" " <op id=\"public-ip-check\" name=\"monitor\" interval=\"60s\"/>\n" " </operations>\n" " <instance_attributes id=\"params-public-ip\">\n" " <nvpair id=\"public-ip-addr\" name=\"ip\" value=\"1.2.3.4\"/>\n" " </instance_attributes>\n" "</primitive>" msgstr "" " <primitive id=\"Public-IP\" class=\"ocf\" type=\"IPaddr\" provider=\"heartbeat\">\n" " <operations>\n" " <op id=\"public-ip-check\" name=\"monitor\" interval=\"60s\"/>\n" " </operations>\n" " <instance_attributes id=\"params-public-ip\">\n" " <nvpair id=\"public-ip-addr\" name=\"ip\" value=\"1.2.3.4\"/>\n" " </instance_attributes>\n" " </primitive> " #. Tag: title #, no-c-format msgid "Properties of an Operation" msgstr "Proprietăţile unei Operaţii" #. Tag: para #, no-c-format msgid "Your name for the action. Must be unique. idAction Property Action Property ActionPropertyid Propertyid id " msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "name" msgstr "0" #. Tag: para #, no-c-format msgid "The action to perform. Common values: monitor, start, stop nameAction Property Action Property ActionPropertyname Propertyname name " msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "interval" msgstr "0" #. Tag: para #, no-c-format msgid "How frequently (in seconds) to perform the operation. Default value: 0, meaning never. intervalAction Property Action Property ActionPropertyinterval Propertyinterval interval " msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "timeout" msgstr "0" #. Tag: para #, no-c-format msgid "How long to wait before declaring the action has failed. timeoutAction Property Action Property ActionPropertytimeout Propertytimeout timeout " msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "on-fail" msgstr "0" #. Tag: para #, no-c-format msgid "The action to take if this action ever fails. Allowed values:" msgstr "Acţiunea pe care să o execute dacă vreodată această acţiune eşuează. Valori permise:" #. Tag: para #, fuzzy, no-c-format msgid "* ignore - Pretend the resource did not fail" msgstr "ignore - Consideră că acţiunea nu a eşuat" #. Tag: para #, fuzzy, no-c-format msgid "* block - Don’t perform any further operations on the resource" msgstr "block - Nu mai efectua operaţiuni ulterioare pe resursă" #. Tag: para #, fuzzy, no-c-format msgid "* stop - Stop the resource and do not start it elsewhere" msgstr "stop - Opreşte resursa şi nu o mai porni în altă parte" #. Tag: para #, fuzzy, no-c-format msgid "* restart - Stop the resource and start it again (possibly on a different node)" msgstr "restart - Opreşte resursa şi porneşte-o din nou (posibil pe un nod diferit)" #. Tag: para #, fuzzy, no-c-format msgid "* fence - STONITH the node on which the resource failed" msgstr "fence - STONITH nodul pe care resursa a eşuat" #. Tag: para #, fuzzy, no-c-format msgid "* standby - Move all resources away from the node on which the resource failed" msgstr "standby - Mută toate resursele de pe nodul pe care resursa a eşuat" #. Tag: para #, no-c-format msgid "The default for the stop operation is fence when STONITH is enabled and block otherwise. All other operations default to stop. on-failAction Property Action Property ActionPropertyon-fail Propertyon-fail on-fail " msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "enabled" msgstr "Started" #. Tag: para #, no-c-format msgid "If false, the operation is treated as if it does not exist. Allowed values: true, false enabledAction Property Action Property ActionPropertyenabled Propertyenabled enabled " msgstr "" #. Tag: title #, no-c-format msgid "Setting Global Defaults for Operations" msgstr "Setarea de Valori Implicite Globale pentru Operaţiuni" #. Tag: para #, fuzzy, no-c-format msgid "To set a default value for a operation option, simply add it to the op_defaults section with crm_attribute. Thus," msgstr "Pentru a seta o valoare implicită pentru o opţiune a resursei, pur şi simplu adăugaţi-o la secţiunea rsc_defaults cu crm_attribute. Astfel," #. Tag: programlisting #, fuzzy, no-c-format msgid "# crm_attribute --type op_defaults --attr-name timeout --attr-value 20s" msgstr "crm_attribute --type op_defaults --attr-name timeout --attr-value 20s" #. Tag: para #, fuzzy, no-c-format msgid "would default each operation’s timeout to 20 seconds. If an operation’s definition also includes a value for timeout, then that value would be used instead (for that operation only)." msgstr "ar seta valoarea implicită a timeout-ului fiecărei operaţiuni la 20 de secunde. Dacă definiţia unei operaţiuni include de asemenea o valoare pentru timeout, atunci acea valoare ar fi folosită în schimb (numai pentru acea operaţiune)." #. Tag: title #, no-c-format msgid "When Resources Take a Long Time to Start/Stop" msgstr "Când Resursele Durează Mult Timp să Pornească/Oprească" #. Tag: para #, fuzzy, no-c-format msgid "There are a number of implicit operations that the cluster will always perform - start, stop and a non-recurring monitor operation (used at startup to check the resource isn’t already active). If one of these is taking too long, then you can create an entry for them and simply specify a new value." msgstr "Sunt un număr de operaţiuni implicite pe care clusterul pe va efectua întotdeauna - start, stop şi o operaţiune monitor nerecurentă (folosită la pornire pentru a verifica dacă resursa nu este deja activă). Dacă una din aceste operaţiuni durează prea mult, atunci puteţi crea o intrare pentru acestea şi să specificaţi o valoarea nouă." #. Tag: title #, no-c-format msgid "An OCF resource with custom timeouts for its implicit actions" msgstr "O resursă OCF cu intervale customizate pentru acţiunile implicite ale acesteia" #. Tag: programlisting #, fuzzy, no-c-format msgid "" "<primitive id=\"Public-IP\" class=\"ocf\" type=\"IPaddr\" provider=\"heartbeat\">\n" " <operations>\n" " <op id=\"public-ip-startup\" name=\"monitor\" interval=\"0\" timeout=\"90s\"/>\n" " <op id=\"public-ip-start\" name=\"start\" interval=\"0\" timeout=\"180s\"/>\n" " <op id=\"public-ip-stop\" name=\"stop\" interval=\"0\" timeout=\"15min\"/>\n" " </operations>\n" " <instance_attributes id=\"params-public-ip\">\n" " <nvpair id=\"public-ip-addr\" name=\"ip\" value=\"1.2.3.4\"/>\n" " </instance_attributes>\n" "</primitive>" msgstr "" " <primitive id=\"Public-IP\" class=\"ocf\" type=\"IPaddr\" provider=\"heartbeat\">\n" " <operations>\n" " <op id=\"public-ip-startup\" name=\"monitor\" interval=\"0\" timeout=\"90s\"/>\n" " <op id=\"public-ip-start\" name=\"start\" interval=\"0\" timeout=\"180s\"/>\n" " <op id=\"public-ip-stop\" name=\"stop\" interval=\"0\" timeout=\"15min\"/>\n" " </operations>\n" " <instance_attributes id=\"params-public-ip\">\n" " <nvpair id=\"public-ip-addr\" name=\"ip\" value=\"1.2.3.4\"/>\n" " </instance_attributes>\n" " </primitive> " #. Tag: title #, no-c-format msgid "Multiple Monitor Operations" msgstr "Operaţiuni de Monitorizare Multiple" #. Tag: para #, no-c-format msgid "Provided no two operations (for a single resource) have the same name and interval you can have as many monitor operations as you like. In this way you can do a superficial health check every minute and progressively more intense ones at higher intervals." msgstr "Atâta timp cât o pereche de două operaţiuni (pentru o singură resursă) nu au acelaşi nume sau acelaşi interval puteţi avea cât de multe operaţiuni de monitorizare pe cât doriţi. În acest fel puteţi realiza o verificare superficială a stării de sănătate la fiecare minut şi unele progresiv mai intense la intervale mai mari." #. Tag: para #, fuzzy, no-c-format msgid "To tell the resource agent what kind of check to perform, you need to provide each monitor with a different value for a common parameter. The OCF standard creates a special parameter called OCF_CHECK_LEVEL for this purpose and dictates that it is \"made available to the resource agent without the normal OCF_RESKEY prefix\"." msgstr "Pentru a spune agentului ce fel de verificare să efectueze, trebuie să furnizaţi fiecărei operaţiuni monitor o valoare diferită pentru un parametru comun. Standardul OCF creează un parametru special numit OCF_CHECK_LEVEL pentru acest scop şi dictează că este \"făcut disponibil agentului de resursă fără obişnuitul prefix OCF_RESKEY_ \"." #. Tag: para #, no-c-format msgid "Whatever name you choose, you can specify it by adding an instance_attributes block to the op tag. Note that it is up to each resource agent to look for the parameter and decide how to use it." msgstr "Indiferent de ce nume alegeţi, puteţi să îl specificaţi adăugând un bloc instance_attributes la tag-ul op. Ţineţi cont că acest lucru este datoria fiecărui agent de resursă să verifice dacă parametrul există şi să decidă cum să îl folosească." #. Tag: title #, no-c-format msgid "An OCF resource with two recurring health checks, performing different levels of checks - specified via OCF_CHECK_LEVEL." msgstr "O resursă OCF cu două verificări de sănătate recurente, efectuând nivele diferite de verificări - specificate via OCF_CHECK_LEVEL." #. Tag: programlisting #, fuzzy, no-c-format msgid "" "<primitive id=\"Public-IP\" class=\"ocf\" type=\"IPaddr\" provider=\"heartbeat\">\n" " <operations>\n" " <op id=\"public-ip-health-60\" name=\"monitor\" interval=\"60\">\n" " <instance_attributes id=\"params-public-ip-depth-60\">\n" " <nvpair id=\"public-ip-depth-60\" name=\"OCF_CHECK_LEVEL\" value=\"10\"/>\n" " </instance_attributes>\n" " </op>\n" " <op id=\"public-ip-health-300\" name=\"monitor\" interval=\"300\">\n" " <instance_attributes id=\"params-public-ip-depth-300\">\n" " <nvpair id=\"public-ip-depth-300\" name=\"OCF_CHECK_LEVEL\" value=\"20\"/>\n" " </instance_attributes>\n" " </op>\n" " </operations>\n" " <instance_attributes id=\"params-public-ip\">\n" " <nvpair id=\"public-ip-level\" name=\"ip\" value=\"1.2.3.4\"/>\n" " </instance_attributes>\n" "</primitive>" msgstr "" " <primitive id=\"Public-IP\" class=\"ocf\" type=\"IPaddr\" provider=\"heartbeat\">\n" " <operations>\n" " <op id=\"public-ip-health-60\" name=\"monitor\" interval=\"60\">\n" " <instance_attributes id=\"params-public-ip-depth-60\">\n" " <nvpair id=\"public-ip-depth-60\" name=\"OCF_CHECK_LEVEL\" value=\"10\"/>\n" " </instance_attributes>\n" " </op>\n" " <op id=\"public-ip-health-300\" name=\"monitor\" interval=\"300\">\n" " <instance_attributes id=\"params-public-ip-depth-300\">\n" " <nvpair id=\"public-ip-depth-300\" name=\"OCF_CHECK_LEVEL\" value=\"20\"/>\n" " </instance_attributes>\n" " </op>\n" " </operations>\n" " <instance_attributes id=\"params-public-ip\">\n" " <nvpair id=\"public-ip-level\" name=\"ip\" value=\"1.2.3.4\"/>\n" " </instance_attributes>\n" " </primitive> " #. Tag: title #, no-c-format msgid "Disabling a Monitor Operation" msgstr "Dezactivarea unei Operaţiuni de Monitorizare" #. Tag: para #, fuzzy, no-c-format msgid "The easiest way to stop a recurring monitor is to just delete it. However, there can be times when you only want to disable it temporarily. In such cases, simply add enabled=\"false\" to the operation’s definition." msgstr "Cel mai simplu mod de a opri un monitor recurent este să îl ştergeţi. Însă pot exista momente când vreţi doar să îl dezactivaţi temporar. În astfel de cazuri, pur şi simplu adăugaţi enabled=\"false\" la definiţia operaţiunii." #. Tag: title #, no-c-format msgid "Example of an OCF resource with a disabled health check" msgstr "Exemplu de resursă OCF cu o verificare a sănătăţii dezactivată" #. Tag: programlisting #, fuzzy, no-c-format msgid "" "<primitive id=\"Public-IP\" class=\"ocf\" type=\"IPaddr\" provider=\"heartbeat\">\n" " <operations>\n" " <op id=\"public-ip-check\" name=\"monitor\" interval=\"60s\" enabled=\"false\"/>\n" " </operations>\n" " <instance_attributes id=\"params-public-ip\">\n" " <nvpair id=\"public-ip-addr\" name=\"ip\" value=\"1.2.3.4\"/>\n" " </instance_attributes>\n" "</primitive>" msgstr "" " <primitive id=\"Public-IP\" class=\"ocf\" type=\"IPaddr\" provider=\"heartbeat\">\n" " <operations>\n" " <op id=\"public-ip-check\" name=\"monitor\" interval=\"60s\" enabled=\"false\"/>\n" " </operations>\n" " <instance_attributes id=\"params-public-ip\">\n" " <nvpair id=\"public-ip-addr\" name=\"ip\" value=\"1.2.3.4\"/>\n" " </instance_attributes>\n" " </primitive> " #. Tag: para #, no-c-format msgid "This can be achieved from the command-line by executing" msgstr "Acest lucru poate fi realizat din linia de comanda executând" #. Tag: programlisting #, fuzzy, no-c-format msgid "# cibadmin -M -X '<op id=\"public-ip-check\" enabled=\"false\"/>'" msgstr "cibadmin -M -X ‘<op id=\"public-ip-check\" enabled=\"false\"/>'" #. Tag: para #, fuzzy, no-c-format msgid "Once you’ve done whatever you needed to do, you can then re-enable it with" msgstr "Odată ce aţi făcut ceea ce aveaţi nevoie să faceţi, îl puteţi reactiva cu" #~ msgid "ResourceDescription" #~ msgstr "DescriereaResursei" #~ msgid "ResourceClasses" #~ msgstr "Clase deResurse" #~ msgid "ResourceOCF" #~ msgstr "ResursăOCF" #~ msgid "OCFResources" #~ msgstr "ResurseOCF" #~ msgid "Open Cluster FrameworkResources" #~ msgstr "ResurseOpen Cluster Framework" #~ msgid "ResourceLSB" #~ msgstr "ResursăLSB" #~ msgid "LSBResources" #~ msgstr "ResurseLSB" #~ msgid "Linus Standard BaseResources" #~ msgstr "ResurseLinus Standard Base" #~ msgid "Legacy Heartbeat" #~ msgstr "Depreciat Heartbeat" #~ msgid "ResourceHeartbeat (legacy)" #~ msgstr "ResursăHeartbeat (depreciat)" #~ msgid "HeartbeatLegacy Resources" #~ msgstr "Resurse DepreciateHeartbeat" #~ msgid "ResourceSTONITH" #~ msgstr "ResursăSTONITH" #~ msgid "STONITHResources" #~ msgstr "ResurseSTONITH" #~ msgid "Properties" #~ msgstr "Proprietăţi" #~ msgid "Your name for the resource" #~ msgstr "Numele pe care îl daţi resursei" #~ msgid "The standard the script conforms to. Allowed values: heartbeat, lsb, ocf, stonith" #~ msgstr "Standardul la care aderă scriptul. Valori permise: heartbeat, lsb, ocf, stonith" #~ msgid "typeResource Field ResourceFieldtype type" #~ msgstr "typeCâmpul Resursei CâmpulResurseitype type" #~ msgid "The name of the Resource Agent you wish to use. Eg. IPaddr or Filesystem" #~ msgstr "Numele Agentului de Resursă pe care doriţi să îl folosiţi. ex. IPaddr or Filesystem" #~ msgid "providerResource Field ResourceFieldprovider provider" #~ msgstr "providerCâmpul Resursei CâmpulResurseiprovider provider" #~ msgid "The OCF spec allows multiple vendors to supply the same ResourceAgent. To use the OCF resource agents supplied with Heartbeat, you should specify heartbeat here." #~ msgstr "Specificaţia OCF permite mai multor entităţi să furnizeze acelaşi Agent de Resursă. Pentru a folosi agenţii de resursă OCF furnizaţi împreună cu Heartbeat, ar trebui să specificaţi heartbeat aici." #~ msgid "Example for an OCF resource:" #~ msgstr "Exemplu pentru o resursă OCF:" #~ msgid "" #~ "<primitive id=\"Public-IP\" class=\"ocf\" type=\"IPaddr\" provider=\"heartbeat\">\n" #~ " <instance_attributes id=\"params-public-ip\">\n" #~ " <nvpair id=\"public-ip-addr\" name=\"ip\" value=\"1.2.3.4\"/>\n" #~ " </instance_attributes>\n" #~ " </primitive> " #~ msgstr "" #~ "<primitive id=\"Public-IP\" class=\"ocf\" type=\"IPaddr\" provider=\"heartbeat\">\n" #~ " <instance_attributes id=\"params-public-ip\">\n" #~ " <nvpair id=\"public-ip-addr\" name=\"ip\" value=\"1.2.3.4\"/>\n" #~ " </instance_attributes>\n" #~ " </primitive> " #~ msgid "Or, finally for the equivalent legacy Heartbeat resource:" #~ msgstr "sau în sfârşit pentru echivalentul unei resurse depreciate Heartbeat: " #~ msgid "An example Heartbeat resource" #~ msgstr "Un exemplu de resursă Heartbeat" #~ msgid "" #~ " <primitive id=\"Public-IP-legacy\" class=\"heartbeat\" type=\"IPaddr\">\n" #~ " <instance_attributes id=\"params-public-ip-legacy\">\n" #~ " <nvpair id=\"public-ip-addr-legacy\" name=\"1\" value=\"1.2.3.4\"/>\n" #~ " </instance_attributes>\n" #~ " </primitive> " #~ msgstr "" #~ " <primitive id=\"Public-IP-legacy\" class=\"heartbeat\" type=\"IPaddr\">\n" #~ " <instance_attributes id=\"params-public-ip-legacy\">\n" #~ " <nvpair id=\"public-ip-addr-legacy\" name=\"1\" value=\"1.2.3.4\"/>\n" #~ " </instance_attributes>\n" #~ " </primitive> " #~ msgid "Heartbeat resources take only ordered and unnamed parameters. The supplied name therefore indicates the order in which they are passed to the script. Only single digit values are allowed." #~ msgstr "Resursele Heartbeat primesc doar parametri ordonaţi şi fără denumire. Numele furnizat indică prin urmare ordinea în care sunt pasaţi către script. Doar valori formate dintr-o singură cifră sunt permise." #~ msgid "If not all resources can be active, the cluster will stop lower priority resources in order to keep higher priority ones active." #~ msgstr "Dacă nu pot fi active toate resursele, clusterul va opri resursele cu prioritate mai mică pentru a păstra resursele cu o prioritate mai mare active." #~ msgid "Master - Allow the resource to be started and, if appropriate, promoted" #~ msgstr "Master - Permite resursei să fie pornită, iar dacă este adecvat, promovată" #~ msgid "is-managedResource Option ResourceOptionis-managed is-managed" #~ msgstr "is-managedOpțiunea Resursei OpțiuneaResurseiis-managed is-managed" #~ msgid "TRUE" #~ msgstr "TRUE" #~ msgid "Is the cluster allowed to start and stop the resource? Allowed values: true, false" #~ msgstr "Îi este permis clusterului să pornească şi să oprească resursa? Valori permise: true, false" #~ msgid "resource-stickinessResource Option ResourceOptionresource-stickiness resource-stickiness" #~ msgstr "resource-stickinessOpțiunea Resursei OpțiuneaResurseiresource-stickiness resource-stickiness" #~ msgid "Inherited" #~ msgstr "Moştenită" #~ msgid "How much does the resource prefer to stay where it is? Defaults to the value of resource-stickiness in the rsc_defaults section" #~ msgstr "Cât de mult preferă resursa să rămână acolo unde este? Valoarea implicită este cea a resource-stickiness din secţiunea rsc_defaults" #~ msgid "How many failures may occur for this resource on a node, before this node is marked ineligible to host this resource." #~ msgstr "Câte eşecuri ar trebui să se întâmple acestei resurse pe un nod înainte de face nodul ineligibil de a mai găzdui această resursă." #~ msgid "failure-timeoutResource Option ResourceOptionfailure-timeout failure-timeout" #~ msgstr "failure-timeoutOpțiunea Resursei OpțiuneaResurseifailure-timeout failure-timeout" #~ msgid "How many seconds to wait before acting as if the failure had not occurred, and potentially allowing the resource back to the node on which it failed." #~ msgstr "Câte secunde să aştepte înainte să se comporte ca şi cum eşecul nu s-ar fi întâmplat (şi potenţial să permită resursei să revină pe nodul pe care a eşuat)." #~ msgid "id" #~ msgstr "id" #~ msgid "Your name for the action. Must be unique." #~ msgstr "Numele dat acţiunii. Trebuie să fie unic." #~ msgid "name" #~ msgstr "nume" #~ msgid "interval" #~ msgstr "interval" #~ msgid "How frequently (in seconds) to perform the operation. Default value: 0, meaning never." #~ msgstr "Cât de frecvent (în secunde) să efectueze operaţiunea. Valoarea implicită: 0, însemnând niciodată." #~ msgid "timeout" #~ msgstr "timeout" #~ msgid "How long to wait before declaring the action has failed." #~ msgstr "Cât de mult să aştepte înainte de a declara că acţiunea a eşuat." #~ msgid "requires" #~ msgstr "necesită" #~ msgid "What conditions need to be satisfied before this action occurs. Allowed values:" #~ msgstr "Care condiţii trebuie să fie satisfăcute înainte ca această acţiune să se întâmple. Valori permise:" #~ msgid "nothing - The cluster may start this resource at any time" #~ msgstr "nothing - Clusterul poate porni această resursă oricând" #~ msgid "STONITH resources default to nothing, and all others default to fencing if STONITH is enabled and quorum otherwise." #~ msgstr "Resursele STONITH au ca valoare implicită nimic, iar toate celelalte au ca valoare implicită fencing dacă STONITH este activat şi quorum în caz contrar." #~ msgid "on-fail" #~ msgstr "on-fail" #~ msgid "The default for the stop operation is fence when STONITH is enabled and block otherwise. All other operations default to stop." #~ msgstr "Valoarea implicită pentru operaţiunea stop este fence atunci când STONITH este activat şi block în caz contrar. Toate celelalte operaţiuni au valoarea implicită stop." #~ msgid "enabled" #~ msgstr "activat" #~ msgid "If false, the operation is treated as if it does not exist. Allowed values: true, false" #~ msgstr "Dacă este false, operaţiunea este tratată ca şi când nu ar exista. Valori permise: true, false" #~ msgid "cibadmin -M -X ‘<op id=\"public-ip-check\" enabled=\"true\"/>'" #~ msgstr "cibadmin -M -X ‘<op id=\"public-ip-check\" enabled=\"true\"/>'" pacemaker-master/doc/Pacemaker_Explained/ro-RO/Ch-Rules.po000066400000000000000000002023721217637305600236650ustar00rootroot00000000000000msgid "" msgstr "" "Project-Id-Version: Pacemaker 1.1\n" "POT-Creation-Date: 2012-10-17T05:19:02\n" "PO-Revision-Date: 2012-01-01T17:48:32\n" "Last-Translator: Dan Frîncu \n" "Language-Team: None\n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: application/x-publican; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. Tag: title #, no-c-format msgid "Rules" msgstr "Reguli" #. Tag: para #, fuzzy, no-c-format msgid " ResourceConstraintRule ConstraintRule Rule " msgstr "Proprietatea Regulii score ProprietățileReguliiscore score" #. Tag: para #, no-c-format msgid "Rules can be used to make your configuration more dynamic. One common example is to set one value for resource-stickiness during working hours, to prevent resources from being moved back to their most preferred location, and another on weekends when no-one is around to notice an outage." msgstr "Regulile pot fi folosite pentru a face configuraţia voastră mai dinamică. Un exemplu comun este de a seta o valoare pentru resource-stickiness în timpul orelor de program, pentru a împiedica resursele de a fi mutate înapoi la locaţia cea mai preferată a acestora, iar altă valoare în weekend-uri când nu este nimeni în preajmă să detecteze o întrerupere a serviciului." #. Tag: para #, no-c-format msgid "Another use of rules might be to assign machines to different processing groups (using a node attribute) based on time and to then use that attribute when creating location constraints." msgstr "O altă utilizare a regulilor ar putea fi pentru a asigna maşini la grupuri de procesare diferite (folosind un atribut de nod) bazat pe timp şi mai apoi să folosească acel atribut pentru a crea o restricţie de locaţie." #. Tag: para #, fuzzy, no-c-format msgid "Each rule can contain a number of expressions, date-expressions and even other rules. The results of the expressions are combined based on the rule’s boolean-op field to determine if the rule ultimately evaluates to true or false. What happens next depends on the context in which the rule is being used." msgstr "Fiecare regulă poate conţine un număr de expresii, expresii de dată şi chiar si alte reguli. Rezultatele expresiilor sunt combinate pe baza câmpului boolean-op al regulii pentru a determina dacă regula în ultimă instanţă este evaluată ca true sau false. Ce se întâmplă mai departe depinde de contextul în care regula este folosită." #. Tag: title #, no-c-format msgid "Properties of a Rule" msgstr "Proprietăţile unei Reguli" #. Tag: entry #, no-c-format msgid "Field" msgstr "Câmp" #. Tag: entry #, no-c-format msgid "Description" msgstr "Descriere" #. Tag: para #, no-c-format msgid "role" msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "Limits the rule to apply only when the resource is in that role. Allowed values: Started, Slave, and Master. NOTE: A rule with role=\"Master\" can not determine the initial location of a clone instance. It will only affect which of the active instances will be promoted. roleConstraint Rule Constraint Rule ConstraintRulerole Rulerole role " msgstr "Limitează regula pentru a se aplica numai când resursa se află în acel rol. Valori permise: Started, Slave, și Master. NOTĂ: O regulă cu role=\"Master\" nu poate determina locaţia iniţială a unei instanţe ale unei clone. Va afecta numai care dintre instanţele active va fi promovată." #. Tag: para #, no-c-format msgid "score" msgstr "" #. Tag: para #, no-c-format msgid "The score to apply if the rule evaluates to true. Limited to use in rules that are part of location constraints. scoreConstraint Rule Constraint Rule ConstraintRulescore Rulescore score " msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "score-attribute" msgstr "Folosind score-attribute în loc de score" #. Tag: para #, no-c-format msgid "The node attribute to look up and use as a score if the rule evaluates to true. Limited to use in rules that are part of location constraints. score-attributeConstraint Rule Constraint Rule ConstraintRulescore-attribute Rulescore-attribute score-attribute " msgstr "" #. Tag: para #, no-c-format msgid "boolean-op" msgstr "" #. Tag: para #, no-c-format msgid "How to combine the result of multiple expression objects. Allowed values: and and or. boolean-opConstraint Rule Constraint Rule ConstraintRuleboolean-op Ruleboolean-op boolean-op " msgstr "" #. Tag: title #, fuzzy, no-c-format msgid "Node Attribute Expressions" msgstr "Proprietăţile unei Expresii" #. Tag: para #, fuzzy, no-c-format msgid " ResourceConstraintAttribute Expression ConstraintAttribute Expression Attribute Expression " msgstr "RegulaControlarea Opțiunilor Clusterului Opțiunile ClusteruluiControlat de Reguli Folosirea Regulilor pentru a Controla Opțiunile Clusterului" #. Tag: para #, no-c-format msgid "Expression objects are used to control a resource based on the attributes defined by a node or nodes. In addition to any attributes added by the administrator, each node has a built-in node attribute called #uname that can also be used." msgstr "Obiectele de expresie sunt folosite pentru a controla o resursă pe baza atributelor definite de un nod sau de mai multe noduri. Adiţional la orice atribute adăugate de administrator, fiecare nod are un atribut de nod predefinit numit #uname care poate fi folosit de asemenea." #. Tag: title #, no-c-format msgid "Properties of an Expression" msgstr "Proprietăţile unei Expresii" #. Tag: para #, no-c-format msgid "value" msgstr "" #. Tag: para #, no-c-format msgid "User supplied value for comparison valueConstraint Expression Constraint Expression ConstraintAttribute Expressionvalue Attribute Expressionvalue value " msgstr "" #. Tag: para #, no-c-format msgid "attribute" msgstr "" #. Tag: para #, no-c-format msgid "The node attribute to test attributeConstraint Expression Constraint Expression ConstraintAttribute Expressionattribute Attribute Expressionattribute attribute " msgstr "" #. Tag: para #, no-c-format msgid "type" msgstr "" #. Tag: para #, no-c-format msgid "Determines how the value(s) should be tested. Allowed values: string, integer, version typeConstraint Expression Constraint Expression ConstraintAttribute Expressiontype Attribute Expressiontype type " msgstr "" #. Tag: para #, no-c-format msgid "operation" msgstr "" #. Tag: para #, no-c-format msgid "The comparison to perform. Allowed values:" msgstr "Comparaţia pe care să o efectueze. Valori permise:" #. Tag: para #, fuzzy, no-c-format msgid "* lt - True if the node attribute’s value is less than value" msgstr "lt - Adevărat dacă valoarea atributului nodului este mai mică decât value" #. Tag: para #, fuzzy, no-c-format msgid "* gt - True if the node attribute’s value is greater than value" msgstr "gt - Adevărat dacă valoarea atributului nodului este mai mare decât value" #. Tag: para #, fuzzy, no-c-format msgid "* lte - True if the node attribute’s value is less than or equal to value" msgstr "lte - Adevărat dacă valoarea atributului nodului este mai mică sau egală cu value" #. Tag: para #, fuzzy, no-c-format msgid "* gte - True if the node attribute’s value is greater than or equal to value" msgstr "gte - Adevărat dacă valoarea atributului nodului este mai mare sau egală cu value" #. Tag: para #, fuzzy, no-c-format msgid "* eq - True if the node attribute’s value is equal to value" msgstr "eq - Adevărat dacă valoarea atributului nodului este egală cu value" #. Tag: para #, fuzzy, no-c-format msgid "* ne - True if the node attribute’s value is not equal to value" msgstr "ne - Adevărat dacă valoarea atributului nodului nu este egală cu value" #. Tag: para #, fuzzy, no-c-format msgid "* defined - True if the node has the named attribute" msgstr "defined - Adevărat dacă nodul are un atribut numit" #. Tag: para #, no-c-format msgid "* not_defined - True if the node does not have the named attribute operationConstraint Expression Constraint Expression ConstraintAttribute Expressionoperation Attribute Expressionoperation operation " msgstr "" #. Tag: title #, fuzzy, no-c-format msgid "Time/Date Based Expressions" msgstr "Exemple de Expresii Bazate pe Timp" #. Tag: para #, fuzzy, no-c-format msgid " Time Based Expressions ResourceConstraintDate/Time Expression ConstraintDate/Time Expression Date/Time Expression " msgstr "Proprietatea Regulii score ProprietățileReguliiscore score" #. Tag: para #, no-c-format msgid "As the name suggests, date_expressions are used to control a resource or cluster option based on the current date/time. They can contain an optional date_spec and/or duration object depending on the context." msgstr "După cum sugerează numele, date_expressions sunt folosite pentru a controla o resursă sau opţiune a clusterului pe baza timpului/dăţii curente. Acestea pot conţine opţional obiecte date_spec şi/sau duration în funcţie de context." #. Tag: title #, no-c-format msgid "Properties of a Date Expression" msgstr "Proprietăţile unei Expresii de Dată" #. Tag: para #, no-c-format msgid "start" msgstr "" #. Tag: para #, no-c-format msgid "A date/time conforming to the ISO8601 specification. startConstraint Expression Constraint Expression ConstraintDate/Time Expressionstart Date/Time Expressionstart start " msgstr "" #. Tag: para #, no-c-format msgid "end" msgstr "" #. Tag: para #, no-c-format msgid "A date/time conforming to the ISO8601 specification. Can be inferred by supplying a value for start and a duration. endConstraint Expression Constraint Expression ConstraintDate/Time Expressionend Date/Time Expressionend end " msgstr "" #. Tag: para #, no-c-format msgid "Compares the current date/time with the start and/or end date, depending on the context. Allowed values:" msgstr "Compară data/ora curentă cu data de început şi/sau sfârşit, în funcţie de context. Valori permise:" #. Tag: para #, fuzzy, no-c-format msgid "* gt - True if the current date/time is after start" msgstr "gt - Adevărat dacă data/ora curentă este după start" #. Tag: para #, fuzzy, no-c-format msgid "* lt - True if the current date/time is before end" msgstr "lt - Adevărat dacă data/ora curentă este înainte de end" #. Tag: para #, fuzzy, no-c-format msgid "* in-range - True if the current date/time is after start and before end" msgstr "in-range - Adevărat dacă data/ora curentă este după start şi înainte de end" #. Tag: para #, no-c-format msgid "* date-spec - performs a cron-like comparison to the current date/time operationConstraint Expression Constraint Expression ConstraintDate/Time Expressionoperation Date/Time Expressionoperation operation " msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "As these comparisons (except for date_spec) include the time, the eq, neq, gte and lte operators have not been implemented since they would only be valid for a single second." msgstr "Deoarece comparaţiile (cu excepţia date_spec) includ timpul, operatorii eq, neq, gte şi lte nu au fost implementaţi." #. Tag: title #, no-c-format msgid "Date Specifications" msgstr "" #. Tag: para #, fuzzy, no-c-format msgid " Date Specification ResourceConstraintDate Specification ConstraintDate Specification Date Specification " msgstr "Proprietatea Regulii score ProprietățileReguliiscore score" #. Tag: para #, no-c-format msgid "date_spec objects are used to create cron-like expressions relating to time. Each field can contain a single number or a single range. Instead of defaulting to zero, any field not supplied is ignored." msgstr "Obiectele date_spec sunt folosite pentru a crea expresii similare cu cele create de cron în relaţie cu timpul. Fiecare câmp poate conţine un singur număr sau un singur şir. În loc să aibe valoarea implicită zero, orice câmp a cărui valoare nu este furnizată este ignorat." #. Tag: para #, no-c-format msgid "For example, monthdays=\"1\" matches the first day of every month and hours=\"09-17\" matches the hours between 9am and 5pm (inclusive). However, at this time one cannot specify weekdays=\"1,2\" or weekdays=\"1-2,5-6\" since they contain multiple ranges. Depending on demand, this may be implemented in a future release." msgstr "De exemplu, monthdays=\"1\" se potriveşte pentru prima zi din fiecare lună şi hours=\"09-17\" se potriveşte orelor între 9am şi 5pm (inclusiv). Însă la acest moment nu se poate specifica weekdays=\"1,2\" sau weekdays=\"1-2,5-6\" din moment ce conţin şiruri multiple. În funcţie de cerere, acest aspect ar putea fi implementat într-un release viitor." #. Tag: title #, no-c-format msgid "Properties of a Date Spec" msgstr "Proprietăţile unei Specificaţii de Dată" #. Tag: para #, no-c-format msgid "id" msgstr "" #. Tag: para #, no-c-format msgid "A unique name for the date idDate Specification Date Specification ConstraintDate Specificationid Date Specificationid id " msgstr "" #. Tag: para #, no-c-format msgid "hours" msgstr "" #. Tag: para #, no-c-format msgid "Allowed values: 0-23 hoursDate Specification Date Specification ConstraintDate Specificationhours Date Specificationhours hours " msgstr "" #. Tag: para #, no-c-format msgid "monthdays" msgstr "" #. Tag: para #, no-c-format msgid "Allowed values: 0-31 (depending on month and year) monthdaysDate Specification Date Specification ConstraintDate Specificationmonthdays Date Specificationmonthdays monthdays " msgstr "" #. Tag: para #, no-c-format msgid "weekdays" msgstr "" #. Tag: para #, no-c-format msgid "Allowed values: 1-7 (1=Monday, 7=Sunday) weekdaysDate Specification Date Specification ConstraintDate Specificationweekdays Date Specificationweekdays weekdays " msgstr "" #. Tag: para #, no-c-format msgid "yeardays" msgstr "" #. Tag: para #, no-c-format msgid "Allowed values: 1-366 (depending on the year) yeardaysDate Specification Date Specification ConstraintDate Specificationyeardays Date Specificationyeardays yeardays " msgstr "" #. Tag: para #, no-c-format msgid "months" msgstr "" #. Tag: para #, no-c-format msgid "Allowed values: 1-12 monthsDate Specification Date Specification ConstraintDate Specificationmonths Date Specificationmonths months " msgstr "" #. Tag: para #, no-c-format msgid "weeks" msgstr "" #. Tag: para #, no-c-format msgid "Allowed values: 1-53 (depending on weekyear) weeksDate Specification Date Specification ConstraintDate Specificationweeks Date Specificationweeks weeks " msgstr "" #. Tag: para #, no-c-format msgid "years" msgstr "" #. Tag: para #, no-c-format msgid "Year according the Gregorian calendar yearsDate Specification Date Specification ConstraintDate Specificationyears Date Specificationyears years " msgstr "" #. Tag: para #, no-c-format msgid "weekyears" msgstr "" #. Tag: para #, no-c-format msgid "May differ from Gregorian years; Eg. 2005-001 Ordinal is also 2005-01-01 Gregorian is also 2004-W53-6 Weekly weekyearsDate Specification Date Specification ConstraintDate Specificationweekyears Date Specificationweekyears weekyears " msgstr "" #. Tag: para #, no-c-format msgid "moon" msgstr "" #. Tag: para #, no-c-format msgid "Allowed values: 0-7 (0 is new, 4 is full moon). Seriously, you can use this. This was implemented to demonstrate the ease with which new comparisons could be added. moonDate Specification Date Specification ConstraintDate Specificationmoon Date Specificationmoon moon " msgstr "" #. Tag: title #, fuzzy, no-c-format msgid "Durations" msgstr "operaţiune" #. Tag: para #, fuzzy, no-c-format msgid " Duration ResourceConstraintDuration ConstraintDuration Duration " msgstr "Proprietatea Regulii score ProprietățileReguliiscore score" #. Tag: para #, no-c-format msgid "Durations are used to calculate a value for end when one is not supplied to in_range operations. They contain the same fields as date_spec objects but without the limitations (ie. you can have a duration of 19 months). Like date_specs, any field not supplied is ignored." msgstr "Duratele sunt folosite pentru a calcula valoarea pentru end atunci când una nu este furnizată în operaţiunile in_range. Acestea conţin aceleaşi câmpuri ca şi obiectele date_spec dar fără limitări (ex. puteţi avea o durată de 19 zile). Ca şi în cazul date_specs, orice câmp care nu este furnizat este ignorat." #. Tag: title #, no-c-format msgid "Sample Time Based Expressions" msgstr "Exemple de Expresii Bazate pe Timp" #. Tag: para #, no-c-format msgid "A small sample of how time based expressions can be used." msgstr "" #. Tag: title #, no-c-format msgid "True if now is any time in the year 2005" msgstr "Adevărat dacă acum este oricând în anul 2005" #. Tag: programlisting #, fuzzy, no-c-format msgid "" "<rule id=\"rule1\">\n" " <date_expression id=\"date_expr1\" start=\"2005-001\" operation=\"in_range\">\n" " <duration years=\"1\"/>\n" " </date_expression>\n" "</rule>" msgstr "" " <rule id=\"rule1\">\n" " <date_expression id=\"date_expr1\" start=\"2005-001\" operation=\"in_range\">\n" " <duration years=\"1\"/>\n" " </date_expression>\n" " </rule> " #. Tag: title #, fuzzy, no-c-format msgid "Equivalent expression" msgstr "Expresie echivalentă." #. Tag: programlisting #, fuzzy, no-c-format msgid "" "<rule id=\"rule2\">\n" " <date_expression id=\"date_expr2\" operation=\"date_spec\">\n" " <date_spec years=\"2005\"/>\n" " </date_expression>\n" "</rule>" msgstr "" " <rule id=\"rule2\">\n" " <date_expression id=\"date_expr2\" operation=\"date_spec\">\n" " <date_spec years=\"2005\"/>\n" " </date_expression>\n" " </rule> " #. Tag: title #, no-c-format msgid "9am-5pm, Mon-Friday" msgstr "9am-5pm, Lun-Vineri" #. Tag: programlisting #, fuzzy, no-c-format msgid "" "<rule id=\"rule3\">\n" " <date_expression id=\"date_expr3\" operation=\"date_spec\">\n" " <date_spec hours=\"9-16\" days=\"1-5\"/>\n" " </date_expression>\n" "</rule>" msgstr "" " <rule id=\"rule3\">\n" " <date_expression id=\"date_expr3\" operation=\"date_spec\">\n" " <date_spec hours=\"9-16\" days=\"1-5\"/>\n" " </date_expression>\n" " </rule> " #. Tag: para #, no-c-format msgid "Please note that the 16 matches up to 16:59:59, as the numeric value (hour) still matches!" msgstr "Vă rugăm să luați aminte că 16 se potrivește cu 16:59:59, deoarece valoarea numerică (ora) încă se potrivește!" #. Tag: title #, no-c-format msgid "9am-6pm, Mon-Friday, or all day saturday" msgstr "9am-6pm, Lun-Vineri sau toată ziua sâmbătă" #. Tag: programlisting #, fuzzy, no-c-format msgid "" "<rule id=\"rule4\" boolean_op=\"or\">\n" " <date_expression id=\"date_expr4-1\" operation=\"date_spec\">\n" " <date_spec hours=\"9-16\" days=\"1-5\"/>\n" " </date_expression>\n" " <date_expression id=\"date_expr4-2\" operation=\"date_spec\">\n" " <date_spec days=\"6\"/>\n" " </date_expression>\n" "</rule>" msgstr "" " <rule id=\"rule4\" boolean_op=\"or\">\n" " <date_expression id=\"date_expr4-1\" operation=\"date_spec\">\n" " <date_spec hours=\"9-16\" days=\"1-5\"/>\n" " </date_expression>\n" " <date_expression id=\"date_expr4-2\" operation=\"date_spec\">\n" " <date_spec days=\"6\"/>\n" " </date_expression>\n" " </rule> " #. Tag: title #, no-c-format msgid "9am-5pm or 9pm-12pm, Mon-Friday" msgstr "9am-5pm sau 9pm-12pm, Lun-Vineri" #. Tag: programlisting #, fuzzy, no-c-format msgid "" "<rule id=\"rule5\" boolean_op=\"and\">\n" " <rule id=\"rule5-nested1\" boolean_op=\"or\">\n" " <date_expression id=\"date_expr5-1\" operation=\"date_spec\">\n" " <date_spec hours=\"9-16\"/>\n" " </date_expression>\n" " <date_expression id=\"date_expr5-2\" operation=\"date_spec\">\n" " <date_spec hours=\"21-23\"/>\n" " </date_expression>\n" " </rule>\n" " <date_expression id=\"date_expr5-3\" operation=\"date_spec\">\n" " <date_spec days=\"1-5\"/>\n" " </date_expression>\n" " </rule>" msgstr "" " <rule id=\"rule5\" boolean_op=\"and\">\n" " <rule id=\"rule5-nested1\" boolean_op=\"or\">\n" " <date_expression id=\"date_expr5-1\" operation=\"date_spec\">\n" " <date_spec hours=\"9-16\"/>\n" " </date_expression>\n" " <date_expression id=\"date_expr5-2\" operation=\"date_spec\">\n" " <date_spec hours=\"21-23\"/>\n" " </date_expression>\n" " </rule>\n" " <date_expression id=\"date_expr5-3\" operation=\"date_spec\">\n" " <date_spec days=\"1-5\"/>\n" " </date_expression>\n" " </rule> " #. Tag: title #, no-c-format msgid "Mondays in March 2005" msgstr "Zilele de Luni în Martie 2005" #. Tag: programlisting #, fuzzy, no-c-format msgid "" "<rule id=\"rule6\" boolean_op=\"and\">\n" " <date_expression id=\"date_expr6-1\" operation=\"date_spec\">\n" " <date_spec weekdays=\"1\"/>\n" " </date_expression>\n" " <date_expression id=\"date_expr6-2\" operation=\"in_range\"\n" " start=\"2005-03-01\" end=\"2005-04-01\"/>\n" " </rule>" msgstr "" " <rule id=\"rule6\" boolean_op=\"and\">\n" " <date_expression id=\"date_expr6-1\" operation=\"date_spec\">\n" " <date_spec weekdays=\"1\"/>\n" " </date_expression>\n" " <date_expression id=\"date_expr6-2\" operation=\"in_range\"\n" " start=\"2005-03-01\" end=\"2005-04-01\"/>\n" " </rule> " #. Tag: para #, fuzzy, no-c-format msgid "Because no time is specified, 00:00:00 is implied." msgstr "NOTĂ: Pentru că nici un timp nu este specificat, 00:00:00 este subînţeles." #. Tag: para #, fuzzy, no-c-format msgid "This means that the range includes all of 2005-03-01 but none of 2005-04-01. You may wish to write end=\"2005-03-31T23:59:59\" to avoid confusion." msgstr "Aţi dori să scrieţi end=\"2005-03-31T23:59:59\" pentru a evita confuzia." #. Tag: title #, no-c-format msgid "A full moon on Friday the 13th" msgstr "O lună plină pe data de Vineri 13" #. Tag: programlisting #, fuzzy, no-c-format msgid "" "<rule id=\"rule7\" boolean_op=\"and\">\n" " <date_expression id=\"date_expr7\" operation=\"date_spec\">\n" " <date_spec weekdays=\"5\" monthdays=\"13\" moon=\"4\"/>\n" " </date_expression>\n" "</rule>" msgstr "" " <rule id=\"rule7\" boolean_op=\"and\">\n" " <date_expression id=\"date_expr7\" operation=\"date_spec\">\n" " <date_spec weekdays=\"5\" monthdays=\"13\" moon=\"4\"/>\n" " </date_expression>\n" " </rule> " #. Tag: title #, fuzzy, no-c-format msgid "Using Rules to Determine Resource Location" msgstr "Folosind Reguli pentru a Controla Opţiunile Resurselor" #. Tag: para #, fuzzy, no-c-format msgid " RuleDetermine Resource Location Determine Resource Location ResourceLocationDetermine by Rules LocationDetermine by Rules Determine by Rules " msgstr "RegulăDetermină Locația Resursei ResursăLocația, Determinată de Reguli Folosirea de Reguli pentru a Determina Locația Resursei" #. Tag: para #, fuzzy, no-c-format msgid "If the constraint’s outer-most rule evaluates to false, the cluster treats the constraint as if it was not there. When the rule evaluates to true, the node’s preference for running the resource is updated with the score associated with the rule." msgstr "Dacă regula cea mai exterioară a unei restricţii este evaluată la false, clusterul se poartă cu restricţia ca şi cum nu ar fi fost acolo. Când regula este evaluată ca true, preferinţa nodului pentru rularea resursei este actualizată cu scorul asociat cu această regulă." #. Tag: para #, no-c-format msgid "If this sounds familiar, its because you have been using a simplified syntax for location constraint rules already. Consider the following location constraint:" msgstr "Dacă acest lucru sună cunoscut, este datorită faptului că deja folosiţi o sintaxă simplificată pentru regulile de restricţie a locaţiei. Consideraţi următoarea restricţie de locaţie:" #. Tag: title #, no-c-format msgid "Prevent myApacheRsc from running on c001n03" msgstr "Împiedică myApacheRsc de a rula pe c001n03" #. Tag: programlisting #, fuzzy, no-c-format msgid "" "<rsc_location id=\"dont-run-apache-on-c001n03\" rsc=\"myApacheRsc\"\n" " score=\"-INFINITY\" node=\"c001n03\"/>" msgstr "" "<rsc_location id=\"dont-run-apache-on-c001n03\" rsc=\"myApacheRsc\"\n" " score=\"-INFINITY\" node=\"c001n03\"/> " #. Tag: para #, no-c-format msgid "This constraint can be more verbosely written as:" msgstr "Aceaastă restricţie poate fi scrisă mai elaborat ca:" #. Tag: title #, no-c-format msgid "Prevent myApacheRsc from running on c001n03 - expanded version" msgstr "Împiedică myApacheRsc de a rula pe c001n03 - versiunea extinsă" #. Tag: programlisting #, fuzzy, no-c-format msgid "" "<rsc_location id=\"dont-run-apache-on-c001n03\" rsc=\"myApacheRsc\">\n" " <rule id=\"dont-run-apache-rule\" score=\"-INFINITY\">\n" " <expression id=\"dont-run-apache-expr\" attribute=\"#uname\"\n" " operation=\"eq\" value=\"c00n03\"/>\n" " </rule>\n" "</rsc_location>" msgstr "" " <rsc_location id=\"dont-run-apache-on-c001n03\" rsc=\"myApacheRsc\">\n" " <rule id=\"dont-run-apache-rule\" score=\"-INFINITY\">\n" " <expression id=\"dont-run-apache-expr\" attribute=\"#uname\"\n" " operation=\"eq\" value=\"c00n03\"/>\n" " </rule>\n" " </rsc_location> " #. Tag: para #, no-c-format msgid "The advantage of using the expanded form is that one can then add extra clauses to the rule, such as limiting the rule such that it only applies during certain times of the day or days of the week (this is discussed in subsequent sections)." msgstr "Avantajul folosirii formei extinse este că se pot adăuga clauze suplimentare la regulă, cum ar fi limitarea regulii astfel încât să se aplice doar în momente specifice ale zilei sau zilelor săptămânii (acest lucru este discutat în secţiunile următoare)." #. Tag: para #, fuzzy, no-c-format msgid "It also allows us to match on node properties other than its name. If we rated each machine’s CPU power such that the cluster had the following nodes section:" msgstr "Este folosit de asemenea pentru a realiza potriviri pe proprietăţi ale nodului altele decât numele acestuia. Dacă am apreciat puterea procesorului fiecărei maşini astfel încât clusterul să aibe următoarea secţiune de noduri: " #. Tag: title #, no-c-format msgid "A sample nodes section for use with score-attribute" msgstr "Un exemplu de secţiune de noduri pentru utilizarea cu score-attribute" #. Tag: programlisting #, fuzzy, no-c-format msgid "" "<nodes>\n" " <node id=\"uuid1\" uname=\"c001n01\" type=\"normal\">\n" " <instance_attributes id=\"uuid1-custom_attrs\">\n" " <nvpair id=\"uuid1-cpu_mips\" name=\"cpu_mips\" value=\"1234\"/>\n" " </instance_attributes>\n" " </node>\n" " <node id=\"uuid2\" uname=\"c001n02\" type=\"normal\">\n" " <instance_attributes id=\"uuid2-custom_attrs\">\n" " <nvpair id=\"uuid2-cpu_mips\" name=\"cpu_mips\" value=\"5678\"/>\n" " </instance_attributes>\n" " </node>\n" "</nodes>" msgstr "" " <nodes>\n" " <node id=\"uuid1\" uname=\"c001n01\" type=\"normal\">\n" " <instance_attributes id=\"uuid1-custom_attrs\">\n" " <nvpair id=\"uuid1-cpu_mips\" name=\"cpu_mips\" value=\"1234\"/>\n" " </instance_attributes>\n" " </node>\n" " <node id=\"uuid2\" uname=\"c001n02\" type=\"normal\">\n" " <instance_attributes id=\"uuid2-custom_attrs\">\n" " <nvpair id=\"uuid2-cpu_mips\" name=\"cpu_mips\" value=\"5678\"/>\n" " </instance_attributes>\n" " </node>\n" " </nodes> " #. Tag: para #, no-c-format msgid "then we could prevent resources from running on underpowered machines with the rule" msgstr "atunci am putea împiedica resursele de a rula pe maşini fără nivelul de procesare cerut cu această regulă" #. Tag: programlisting #, fuzzy, no-c-format msgid "" "<rule id=\"need-more-power-rule\" score=\"-INFINITY\">\n" " <expression id=\" need-more-power-expr\" attribute=\"cpu_mips\"\n" " operation=\"lt\" value=\"3000\"/>\n" "</rule>" msgstr "" " <rule id=\"need-more-power-rule\" score=\"-INFINITY\">\n" " <expression id=\" need-more-power-expr\" attribute=\"cpu_mips\"\n" " operation=\"lt\" value=\"3000\"/>\n" " </rule> " #. Tag: title #, no-c-format msgid "Using score-attribute Instead of score" msgstr "Folosind score-attribute în loc de score" #. Tag: para #, no-c-format msgid "When using score-attribute instead of score, each node matched by the rule has its score adjusted differently, according to its value for the named node attribute. Thus, in the previous example, if a rule used score-attribute=\"cpu_mips\", c001n01 would have its preference to run the resource increased by 1234 whereas c001n02 would have its preference increased by 5678." msgstr "Când folosim score-attribute în loc de score, fiecare nod care se potriveşte regulii va avea scorul acestuia ajustat în mod diferit, în funcţie de valoarea sa pentru atributul numit de nod. Prin urmare în exemplul anterior, dacă o regulă folosea score-attribute=\"cpu_mips\", c001n01 ar avea preferinţa proprie de a rula resursa crescută cu 1234 în timp ce c001n02 ar avea preferinţa crescută cu 5678." #. Tag: title #, no-c-format msgid "Using Rules to Control Resource Options" msgstr "Folosind Reguli pentru a Controla Opţiunile Resurselor" #. Tag: para #, fuzzy, no-c-format msgid "Often some cluster nodes will be different from their peers; sometimes these differences (the location of a binary or the names of network interfaces) require resources to be configured differently depending on the machine they’re hosted on." msgstr "Adeseori unele noduri din cluster vor fi diferite de altele, câteodată aceste diferenţe (locaţia unui binar sau numele interfeţelor de reţea) necesită ca şi resursele să fie configurate diferit în funcţie de maşina pe care sunt găzduite." #. Tag: para #, no-c-format msgid "By defining multiple instance_attributes objects for the resource and adding a rule to each, we can easily handle these special cases." msgstr "Prin definirea de obiecte multiple instance_attributes pentru resursă şi prin adăugarea unei reguli pentru fiecare, putem gestiona facil aceste cazuri speciale." #. Tag: para #, no-c-format msgid "In the example below, mySpecialRsc will use eth1 and port 9999 when run on node1, eth2 and port 8888 on node2 and default to eth0 and port 9999 for all other nodes." msgstr "În exemplul de mai jos, mySpecialRsc va folosi eth1 şi portul 9999 când va rula pe node1, eth2 şi portul 8888 pe node2 şi va avea valorea implicită eth0 şi portul 9999 pentru toate celelalte noduri. " #. Tag: title #, no-c-format msgid "Defining different resource options based on the node name" msgstr "Definirea de opţiuni de resursă diferite pe baza numelui nodului" #. Tag: programlisting #, fuzzy, no-c-format msgid "" "<primitive id=\"mySpecialRsc\" class=\"ocf\" type=\"Special\" provider=\"me\">\n" " <instance_attributes id=\"special-node1\" score=\"3\">\n" " <rule id=\"node1-special-case\" score=\"INFINITY\" >\n" " <expression id=\"node1-special-case-expr\" attribute=\"#uname\"\n" " operation=\"eq\" value=\"node1\"/>\n" " </rule>\n" " <nvpair id=\"node1-interface\" name=\"interface\" value=\"eth1\"/>\n" " </instance_attributes>\n" " <instance_attributes id=\"special-node2\" score=\"2\" >\n" " <rule id=\"node2-special-case\" score=\"INFINITY\">\n" " <expression id=\"node2-special-case-expr\" attribute=\"#uname\"\n" " operation=\"eq\" value=\"node2\"/>\n" " </rule>\n" " <nvpair id=\"node2-interface\" name=\"interface\" value=\"eth2\"/>\n" " <nvpair id=\"node2-port\" name=\"port\" value=\"8888\"/>\n" " </instance_attributes>\n" " <instance_attributes id=\"defaults\" score=\"1\" >\n" " <nvpair id=\"default-interface\" name=\"interface\" value=\"eth0\"/>\n" " <nvpair id=\"default-port\" name=\"port\" value=\"9999\"/>\n" " </instance_attributes>\n" "</primitive>" msgstr "" " <primitive id=\"mySpecialRsc\" class=\"ocf\" type=\"Special\" provider=\"me\">\n" " <instance_attributes id=\"special-node1\" score=\"3\">\n" " <rule id=\"node1-special-case\" score=\"INFINITY\" >\n" " <expression id=\"node1-special-case-expr\" attribute=\"#uname\"\n" " operation=\"eq\" value=\"node1\"/>\n" " </rule>\n" " <nvpair id=\"node1-interface\" name=\"interface\" value=\"eth1\"/>\n" " </instance_attributes>\n" " <instance_attributes id=\"special-node2\" score=\"2\" >\n" " <rule id=\"node2-special-case\" score=\"INFINITY\">\n" " <expression id=\"node2-special-case-expr\" attribute=\"#uname\"\n" " operation=\"eq\" value=\"node2\"/>\n" " </rule>\n" " <nvpair id=\"node2-interface\" name=\"interface\" value=\"eth2\"/>\n" " <nvpair id=\"node2-port\" name=\"port\" value=\"8888\"/>\n" " </instance_attributes>\n" " <instance_attributes id=\"defaults\" score=\"1\" >\n" " <nvpair id=\"default-interface\" name=\"interface\" value=\"eth0\"/>\n" " <nvpair id=\"default-port\" name=\"port\" value=\"9999\"/>\n" " </instance_attributes>\n" " </primitive> " #. Tag: para #, no-c-format msgid "The order in which instance_attributes objects are evaluated is determined by their score (highest to lowest). If not supplied, score defaults to zero and objects with an equal score are processed in listed order. If the instance_attributes object does not have a rule or has a rule that evaluates to true, then for any parameter the resource does not yet have a value for, the resource will use the parameter values defined by the instance_attributes object." msgstr "Ordinea în care obiectele instance_attributes sunt evaluate este determinată de către scorul acestora (cel mai mare la cel mai mic). Dacă nu este furnizat, scorul va avea valoarea implicită zero şi obiectele cu un scor egal sunt procesate în ordinea listată. Dacă obiectul instance_attributes nu are o rule sau are o rule care este evaluată la true, atunci pentru orice parametru pentru care resursa nu are înca o valoare, resursa va folosi valorile parametrilor definite de obiectul instance_attributes." #. Tag: title #, fuzzy, no-c-format msgid "Using Rules to Control Cluster Options" msgstr "Folosind Reguli pentru a Controla Opţiunile Resurselor" #. Tag: para #, fuzzy, no-c-format msgid " RuleControlling Cluster Options Controlling Cluster Options ClusterSetting Options with Rules Setting Options with Rules " msgstr "RegulaControlarea Opțiunilor Clusterului Opțiunile ClusteruluiControlat de Reguli Folosirea Regulilor pentru a Controla Opțiunile Clusterului" #. Tag: para #, no-c-format msgid "Controlling cluster options is achieved in much the same manner as specifying different resource options on different nodes." msgstr "Controlarea opţiunilor clusterului este reuşită în mare parte prin aceeaşi manieră ca şi specificarea diverselor opţiuni pentru resurse pe noduri diferite." #. Tag: para #, fuzzy, no-c-format msgid "The difference is that because they are cluster options, one cannot (or should not, because they won’t work) use attribute based expressions. The following example illustrates how to set a different resource-stickiness value during and outside of work hours. This allows resources to automatically move back to their most preferred hosts, but at a time that (in theory) does not interfere with business activities." msgstr "Diferenţa este că din cauza că sunt opţiuni de cluster, nu ar trebui să puteţi (sau nu ar trebui să pentru că acestea nu funcţionează) să folosiţi expresii bazate pe atribute. Următorul exemplu ilustrează cum să setaţi o valoare resource-stickiness diferită în timpul şi în afara orelor de lucru. Acest lucru permite resurselor să se mute înapoi în mod automat la gazdele cele mai preferate, dar la un moment în care (teoretic) nu interferează cu activităţile de business." #. Tag: title #, no-c-format msgid "Change resource-stickiness during working hours" msgstr "Schimbarea resource-stickiness în timpul orelor de lucru" #. Tag: programlisting #, fuzzy, no-c-format msgid "" "<rsc_defaults>\n" " <meta_attributes id=\"core-hours\" score=\"2\">\n" " <rule id=\"core-hour-rule\" score=\"0\">\n" " <date_expression id=\"nine-to-five-Mon-to-Fri\" operation=\"date_spec\">\n" " <date_spec id=\"nine-to-five-Mon-to-Fri-spec\" hours=\"9-16\" weekdays=\"1-5\"/>\n" " </date_expression>\n" " </rule>\n" " <nvpair id=\"core-stickiness\" name=\"resource-stickiness\" value=\"INFINITY\"/>\n" " </meta_attributes>\n" " <meta_attributes id=\"after-hours\" score=\"1\" >\n" " <nvpair id=\"after-stickiness\" name=\"resource-stickiness\" value=\"0\"/>\n" " </meta_attributes>\n" "</rsc_defaults>" msgstr "" " <rsc_defaults>\n" " <meta_attributes id=\"core-hours\" score=\"2\">\n" " <rule id=\"core-hour-rule\" score=\"0\">\n" " <date_expression id=\"nine-to-five-Mon-to-Fri\" operation=\"date_spec\">\n" " <date_spec id=\"nine-to-five-Mon-to-Fri-spec\" hours=\"9-16\" weekdays=\"1-5\"/>\n" " </date_expression>\n" " </rule>\n" " <nvpair id=\"core-stickiness\" name=\"resource-stickiness\" value=\"INFINITY\"/>\n" " </meta_attributes>\n" " <meta_attributes id=\"after-hours\" score=\"1\" >\n" " <nvpair id=\"after-stickiness\" name=\"resource-stickiness\" value=\"0\"/>\n" " </meta_attributes>\n" " </rsc_defaults> " #. Tag: title #, no-c-format msgid "Ensuring Time Based Rules Take Effect" msgstr "Asigurarea că Regulile Bazate pe Timp Iau Efect" #. Tag: para #, fuzzy, no-c-format msgid "A Pacemaker cluster is an event driven system. As such, it won’t recalculate the best place for resources to run in unless something (like a resource failure or configuration change) happens. This can mean that a location constraint that only allows resource X to run between 9am and 5pm is not enforced." msgstr "Un cluster Pacemaker este un sistem condus de evenimente. Prin urmare, nu va recalcula cel mai bun loc pentru a rula resursele decât dacă ceva (cum ar fi eşecul unei resurse sau modificarea configuraţiei) se întâmplă. Asta poate însemna că o restricţie a locaţiei care permite resursei X să ruleze numai între 9am şi 5pm nu este aplicată în mod obligatoriu." #. Tag: para #, no-c-format msgid "If you rely on time based rules, it is essential that you set the cluster-recheck-interval option. This tells the cluster to periodically recalculate the ideal state of the cluster. For example, if you set cluster-recheck-interval=5m, then sometime between 9:00 and 9:05 the cluster would notice that it needs to start resource X, and between 17:00 and 17:05 it would realize that X needed to be stopped." msgstr "Dacă vă bazaţi pe reguli bazate pe timp, este esenţial să setaţi opţiunea cluster-recheck-interval. Aceasta spune clusterului să recalculeze periodic starea ideală a clusterului. De exemplu, dacă setaţi cluster-recheck-interval=5m, atunci cândva între 9:00 şi 9:05 clusterul va detecta că trebuie să pornească resursa X, iar între 17:00 şi 17:05 va realiza că trebuie să o oprească." #. Tag: para #, fuzzy, no-c-format msgid "Note that the timing of the actual start and stop actions depends on what else needs to be performed first ." msgstr "Ţineţi cont că momentul efectiv de pornire şi oprire al acţiunilor depinde de ce alte lucruri trebuie efectuate mai întâi." #~ msgid "role Rule Property RulePropertiesrole role" #~ msgstr "Proprietatea Regulii role ProprietățileReguliirole role" #~ msgid "The score to apply if the rule evaluates to true. Limited to use in rules that are part of location constraints." #~ msgstr "Scorul pe care să îl aplice în cazul în care regula este evaluată la true. Limitată la folosirea în reguli care sunt parte din restricţiile de locaţie." #~ msgid "score-attribute Rule Property RulePropertiesscore-attribute score-attribute" #~ msgstr "Proprietatea Regulii score-attribute ProprietățileReguliiscore-attribute score-attribute" #~ msgid "The node attribute to look up and use as a score if the rule evaluates to true. Limited to use in rules that are part of location constraints." #~ msgstr "Atributul nodului pe care să îl caute şi pe care să îl folosească drept scor dacă regula se evaluează la true. Limitată la folosirea în reguli care sunt parte din restricţii de locaţie." #~ msgid "boolean-op Rule Property RulePropertiesboolean-op boolean-op" #~ msgstr "Proprietatea Regulii boolean-op ProprietățileReguliiboolean-op boolean-op" #~ msgid "How to combine the result of multiple expression objects. Allowed values: and and or." #~ msgstr "Cum să combinaţi rezultatul mai multor obiecte de expresii. Valori permise: and și or." #~ msgid "NodeAttribute ExpressionsNode Attribute Expressions" #~ msgstr "Expresiile AtributelorNoduluiExpresiile Atributelor Nodului" #~ msgid "value Expression Property Expression Propertiesvalue value" #~ msgstr "Proprietatea Expresiei value Proprietățile Proprietățiivalue value" #~ msgid "User supplied value for comparison" #~ msgstr "Valorea furnizată de utilizator pentru comparaţie" #~ msgid "attribute Expression Property Expression Propertiesattribute attribute" #~ msgstr "Proprietatea Expresiei attribute Proprietățile Proprietățiiattribute attribute" #~ msgid "The node attribute to test" #~ msgstr "Atributul nodului care să fie testat" #~ msgid "typeExpression Property Expression Propertiestype type" #~ msgstr "Proprietatea Expresiei type Proprietățile Proprietățiitype type" #~ msgid "Determines how the value(s) should be tested. Allowed values: string, integer, version" #~ msgstr "Determină cum ar trebui să fie testate valorile. Valori permise: string, integer, version" #~ msgid "operation Expression Property Expression Propertiesoperation operation" #~ msgstr "Proprietatea Expresiei operation Proprietățile Proprietățiioperation operation" #~ msgid "not_defined - True if the node does not have the named attribute" #~ msgstr "not_defined - Adevărat dacă nodul nu are un atribut numit" #~ msgid "Time Based Expressions ExpressionTime/Date Based Time/Date Based Expressions" #~ msgstr "Expresii Bazate pe Timp ExpresiiBazate pe Timp/Dată Expresii Bazate pe Timp/Dată" #~ msgid "start" #~ msgstr "început" #~ msgid "A date/time conforming to the ISO8601 specification." #~ msgstr "O dată/oră conformă cu specificaţia ISO8601." #~ msgid "end" #~ msgstr "sfârşit" #~ msgid "A date/time conforming to the ISO8601 specification. Can be inferred by supplying a value for start and a duration." #~ msgstr "O dată/oră conformă cu specificaţia ISO8601. Poate fi omisă dacă se furnizează o valoare pentru start şi o duration." #~ msgid "date-spec - performs a cron-like comparison to the current date/time" #~ msgstr "date-spec - efectuează o comparaţie similară cron-ului față de ora/data curentă" #~ msgid "Date Specifications Date Specifications" #~ msgstr "Specificațiile Datei Specificațiile Datei" #~ msgid "idDate Spec Property Date Spec Propertiesid id" #~ msgstr "idProprietatea Specificației de Dată Proprietățile Specificației de Datăid id" #~ msgid "A unique name for the date" #~ msgstr "Un nume unic pentru dată" #~ msgid "hours Date Spec Property Date Spec Propertieshours hours" #~ msgstr "Proprietatea hours a Specificației de Dată Proprietățile Specificației de Datăhours hours" #~ msgid "Allowed values: 0-23" #~ msgstr "Valori permise: 0-23" #~ msgid "monthdays Date Spec Property Date Spec Propertiesmonthdays monthdays" #~ msgstr "Proprietatea monthdays a Specificației de Dată Proprietățile Specificației de Datămonthdays monthdays" #~ msgid "Allowed values: 0-31 (depending on month and year)" #~ msgstr "Valori permise: 0-31 (în funcţie de luna curentă şi an)" #~ msgid "weekdays Date Spec Property Date Spec Propertiesweekdays weekdays" #~ msgstr "Proprietatea weekdays a Specificației de Dată Proprietățile Specificației de Datăweekdays weekdays" #~ msgid "Allowed values: 1-7 (1=Monday, 7=Sunday)" #~ msgstr "Valori permise: 1-7 (1=Luni, 7=Duminică)" #~ msgid "yeardays Date Spec Property Date Spec Propertiesyeardays yeardays" #~ msgstr "Proprietatea yeardays a Specificației de Dată Proprietățile Specificației de Datăyeardays yeardays" #~ msgid "Allowed values: 1-366 (depending on the year)" #~ msgstr "Valori permise: 1-366 (în funcţie de anul curent)" #~ msgid "months Date Spec Property Date Spec Propertiesmonths months" #~ msgstr "Proprietatea months a Specificației de Dată Proprietățile Specificației de Datămonths months" #~ msgid "Allowed values: 1-12" #~ msgstr "Valori permise: 1-12" #~ msgid "weeks Date Spec Property Date Spec Propertiesweeks weeks" #~ msgstr "Proprietatea weeks a Specificației de Dată Proprietățile Specificației de Datăweeks weeks" #~ msgid "Allowed values: 1-53 (depending on weekyear)" #~ msgstr "Valori permise: 1-53 (în funcţie câte săptămâni are anul)" #~ msgid "years Date Spec Property Date Spec Propertiesyears years" #~ msgstr "Proprietatea years a Specificației de Dată Proprietățile Specificației de Datăyears years" #~ msgid "Year according the Gregorian calendar" #~ msgstr "Anul conform calendarului Gregorian" #~ msgid "weekyears Date Spec Property Date Spec Propertiesweekyears weekyears" #~ msgstr "Proprietatea weekyears a Specificației de Dată Proprietățile Specificației de Datăweekyears weekyears" #~ msgid "May differ from Gregorian years; Eg. 2005-001 Ordinal is also 2005-01-01 Gregorian is also 2004-W53-6 Weekly" #~ msgstr "Ar putea fi diferit față de anii Gregorieni; Ex. 2005-001 Ordinal este de asemenea 2005-01-01 Gregorian şi de asemenea 2004-W53-6 Weekly" #~ msgid "moon Date Spec Property Date Spec Propertiesmoon moon" #~ msgstr "Proprietatea moon a Specificației de Dată Proprietățile Specificației de Datămoon moon" #~ msgid "Allowed values: 0-7 (0 is new, 4 is full moon). Seriously, you can use this. This was implemented to demonstrate the ease with which new comparisons could be added." #~ msgstr "Valori permise: 0..7 (0 este pentru lună nouă, 4 pentru pentru lună plină). Nu glumesc, puteţi folosi asta. Acest lucru a fost implementat ca să demonstreze uşurinţa cu care se pot adăuga comparaţii noi." #~ msgid "Durations Expressions ExpressionsDurations Durations" #~ msgstr "Expresii de Durată Expresiide Durată de Durată" #~ msgid "This means that the range includes all of 2005-03-01 but none of 2005-04-01." #~ msgstr "Acest lucru înseamnă că şirul include tot din 2005-03-01 dar nimic din 2005-04-01." pacemaker-master/doc/Pacemaker_Explained/ro-RO/Ch-Status.po000066400000000000000000001457431217637305600240660ustar00rootroot00000000000000msgid "" msgstr "" "Project-Id-Version: Pacemaker 1.1\n" "POT-Creation-Date: 2012-10-17T05:19:02\n" "PO-Revision-Date: 2012-01-01T17:48:32\n" "Last-Translator: Dan Frîncu \n" "Language-Team: None\n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: application/x-publican; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. Tag: title #, no-c-format msgid "Status - Here be dragons" msgstr "Status - Aici sunt dragoni" #. Tag: para #, fuzzy, no-c-format msgid "Most users never need to understand the contents of the status section and can be happy with the output from crm_mon." msgstr "Majoritatea utilizatorilor nu trebuie niciodată să înţeleagă conţinutul secţiunii de status şi se pot mulţumi cu rezultatul de ieşire de la crm_mon. Totuşi pentru aceia dintre voi cu o înclinaţie către curiozitate, următoarele încearcă să furnizeze o vedere de ansamblu asupra conţinutului acestuia." #. Tag: para #, fuzzy, no-c-format msgid "However for those with a curious inclination, this section attempts to provide an overview of its contents." msgstr "Majoritatea utilizatorilor nu trebuie niciodată să înţeleagă conţinutul secţiunii de status şi se pot mulţumi cu rezultatul de ieşire de la crm_mon. Totuşi pentru aceia dintre voi cu o înclinaţie către curiozitate, următoarele încearcă să furnizeze o vedere de ansamblu asupra conţinutului acestuia." #. Tag: title #, fuzzy, no-c-format msgid "Node Status" msgstr "Câmpuri de Status ale Nodului" #. Tag: para #, fuzzy, no-c-format msgid " NodeStatus Status Status of a Node " msgstr "StatusulNodului Statusul unui Nod Statusul Nodului" #. Tag: para #, fuzzy, no-c-format msgid "In addition to the cluster’s configuration, the CIB holds an up-to-date representation of each cluster node in the status section." msgstr "În plus faţă de configuraţia clusterului, CIB-ul menţine o reprezentare cât mai actualizată a fiecărui nod din cluster în secţiunea de status." #. Tag: title #, no-c-format msgid "A bare-bones status entry for a healthy node called cl-virt-1" msgstr "O intrare iniţială de status pentru un nod sănătos numit cl-virt-1" #. Tag: programlisting #, fuzzy, no-c-format msgid "" " <node_state id=\"cl-virt-1\" uname=\"cl-virt-2\" ha=\"active\" in_ccm=\"true\" crmd=\"online\" join=\"member\" expected=\"member\" crm-debug-origin=\"do_update_resource\">\n" " <transient_attributes id=\"cl-virt-1\"/>\n" " <lrm id=\"cl-virt-1\"/>\n" " </node_state>" msgstr "" " <node_state id=\"cl-virt-1\" uname=\"cl-virt-2\" ha=\"active\" in_ccm=\"true\" crmd=\"online\" join=\"member\" expected=\"member\" crm-debug-origin=\"do_update_resource\">\n" " <transient_attributes id=\"cl-virt-1\"/>\n" " <lrm id=\"cl-virt-1\"/>\n" " </node_state> " #. Tag: para #, fuzzy, no-c-format msgid "Users are highly recommended not to modify any part of a node’s state directly. The cluster will periodically regenerate the entire section from authoritative sources. So any changes should be done with the tools for those subsystems." msgstr "Utilizatorilor li se recomandă stringent să nu modifice nici o parte din starea nodului în mod direct. Clusterul va regenera periodic întreaga secţiune din surse autoritative. Aşa că orice modificare ar trebui executată cu utilitarele pentru acele subsisteme." #. Tag: title #, no-c-format msgid "Authoritative Sources for State Information" msgstr "Surse Autoritative pentru Informaţia de Stare" #. Tag: entry #, no-c-format msgid "Dataset" msgstr "Dataset" #. Tag: entry #, no-c-format msgid "Authoritative Source" msgstr "Sursă Autoritativă" #. Tag: para #, fuzzy, no-c-format msgid "node_state fields" msgstr "câmpurile node_state" #. Tag: para #, no-c-format msgid "crmd" msgstr "crmd" #. Tag: para #, fuzzy, no-c-format msgid "transient_attributes tag" msgstr "tag-ul transient_attributes" #. Tag: para #, no-c-format msgid "attrd" msgstr "attrd" #. Tag: para #, no-c-format msgid "lrm tag" msgstr "" #. Tag: para #, no-c-format msgid "lrmd" msgstr "lrmd" #. Tag: para #, fuzzy, no-c-format msgid "The fields used in the node_state objects are named as they are largely for historical reasons and are rooted in Pacemaker’s origins as the Heartbeat resource manager." msgstr "Câmpurile folosite în obiectele node_state sunt denumite aşa cum sunt în mare parte din motive istorice şi sunt înrădăcinate în originile Pacemaker-ului ca manager de resurse pentru Heartbeat. Acestea au rămas neschimbate pentru a păstra compatibilitatea cu versiuni mai vechi." #. Tag: para #, no-c-format msgid "They have remained unchanged to preserve compatibility with older versions." msgstr "" #. Tag: title #, no-c-format msgid "Node Status Fields" msgstr "Câmpuri de Status ale Nodului" #. Tag: entry #, no-c-format msgid "Field" msgstr "Câmp" #. Tag: entry #, no-c-format msgid "Description" msgstr "Descriere" #. Tag: para #, fuzzy, no-c-format msgid "id" msgstr "Valoarea aşteptată pentru join." #. Tag: para #, no-c-format msgid " idNode Status Node Status NodeStatusid Statusid id Unique identifier for the node. Corosync based clusters use the uname of the machine, Heartbeat clusters use a human-readable (but annoying) UUID." msgstr "" #. Tag: para #, no-c-format msgid "uname" msgstr "" #. Tag: para #, no-c-format msgid " unameNode Status Node Status NodeStatusuname Statusuname uname The node’s machine name (output from uname -n)." msgstr "" #. Tag: para #, no-c-format msgid "ha" msgstr "" #. Tag: para #, no-c-format msgid " haNode Status Node Status NodeStatusha Statusha ha Flag specifying whether the cluster software is active on the node. Allowed values: active, dead." msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "in_ccm" msgstr "Valoarea aşteptată pentru join." #. Tag: para #, no-c-format msgid " in_ccmNode Status Node Status NodeStatusin_ccm Statusin_ccm in_ccm Flag for cluster membership; allowed values: true, false." msgstr "" #. Tag: para #, no-c-format msgid "crmd" msgstr "" #. Tag: para #, no-c-format msgid " crmdNode Status Node Status NodeStatuscrmd Statuscrmd crmd Flag: is the crmd process active on the node? One of online, offline." msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "join" msgstr "Valoarea aşteptată pentru join." #. Tag: para #, no-c-format msgid " joinNode Status Node Status NodeStatusjoin Statusjoin join Flag saying whether the node participates in hosting resources. Possible values: down, pending, member, banned." msgstr "" #. Tag: para #, no-c-format msgid "expected" msgstr "" #. Tag: para #, no-c-format msgid " expectedNode Status Node Status NodeStatusexpected Statusexpected expected Expected value for join." msgstr "" #. Tag: para #, no-c-format msgid "crm-debug-origin" msgstr "" #. Tag: para #, no-c-format msgid " crm-debug-originNode Status Node Status NodeStatuscrm-debug-origin Statuscrm-debug-origin crm-debug-origin Diagnostic indicator: the origin of the most recent change(s)." msgstr "" #. Tag: para #, no-c-format msgid "The cluster uses these fields to determine if, at the node level, the node is healthy or is in a failed state and needs to be fenced." msgstr "Clusterul foloseşte aceste câmpuri ca să determine dacă, la nivel de nod, nodul este sănătos sau este într-o stare defectuoasă şi trebuie evacuat forțat." #. Tag: title #, no-c-format msgid "Transient Node Attributes" msgstr "Atribute Tranziente ale Nodului" #. Tag: para #, no-c-format msgid "Like regular node attributes, the name/value pairs listed here also help to describe the node. However they are forgotten by the cluster when the node goes offline. This can be useful, for instance, when you want a node to be in standby mode (not able to run resources) until the next reboot." msgstr "Precum atributele nodului obişnuite, perechile nume/valoare listate aici ajută de asemenea la descrierea nodului. Totuşi acestea sunt uitate de către cluster atunci când nodul trece în mod offline. Acest lucru poate fi util, de exemplu, când vreţi un nod să se afle în mod standby (să nu poată rula resurse) până la următorul reboot." #. Tag: para #, no-c-format msgid "In addition to any values the administrator sets, the cluster will also store information about failed resources here." msgstr "În plus faţă de orice valori setează administratorul, clusterul va stoca de asemenea informaţii despre resursele eşuate aici." #. Tag: title #, no-c-format msgid "Example set of transient node attributes for node \"cl-virt-1\"" msgstr "Exemplu de atribute tranziente de nod pentru nodul \"cl-virt-1\"" #. Tag: programlisting #, fuzzy, no-c-format msgid "" " <transient_attributes id=\"cl-virt-1\">\n" " <instance_attributes id=\"status-cl-virt-1\">\n" " <nvpair id=\"status-cl-virt-1-pingd\" name=\"pingd\" value=\"3\"/>\n" " <nvpair id=\"status-cl-virt-1-probe_complete\" name=\"probe_complete\" value=\"true\"/>\n" " <nvpair id=\"status-cl-virt-1-fail-count-pingd:0\" name=\"fail-count-pingd:0\" value=\"1\"/>\n" " <nvpair id=\"status-cl-virt-1-last-failure-pingd:0\" name=\"last-failure-pingd:0\" value=\"1239009742\"/>\n" " </instance_attributes>\n" " </transient_attributes>" msgstr "" " <transient_attributes id=\"cl-virt-1\">\n" " <instance_attributes id=\"status-cl-virt-1\">\n" " <nvpair id=\"status-cl-virt-1-pingd\" name=\"pingd\" value=\"3\"/>\n" " <nvpair id=\"status-cl-virt-1-probe_complete\" name=\"probe_complete\" value=\"true\"/>\n" " <nvpair id=\"status-cl-virt-1-fail-count-pingd:0\" name=\"fail-count-pingd:0\" value=\"1\"/>\n" " <nvpair id=\"status-cl-virt-1-last-failure-pingd:0\" name=\"last-failure-pingd:0\"\n" " value=\"1239009742\"/>\n" " </instance_attributes>\n" " </transient_attributes> " #. Tag: para #, fuzzy, no-c-format msgid "In the above example, we can see that the pingd:0 resource has failed once, at Mon Apr 6 11:22:22 2009. You can use the standard date command to print a human readable of any seconds-since-epoch value: # date -d @<parameter>number</parameter> We also see that the node is connected to three \"pingd\" peers and that all known resources have been checked for on this machine (probe_complete)." msgstr "În exemplul de mai sus, putem vedea că resursa pingd:0 a eşuat o dată, pe Mon Apr 6 11:22:22 2009 Puteți folosi comanda standard date pentru a lista în format ușor de citit de oameni a oricărei valori a secundelor-de-la-epoch: # date -d @număr . Observăm de asemenea că nodul este conectat la trei noduri \"pingd\" şi că toate resursele cunoscute au fost verificate pe această maşină (probe_complete)." #. Tag: title #, no-c-format msgid "Operation History" msgstr "" #. Tag: para #, fuzzy, no-c-format msgid " Operation History " msgstr "Istoria Operațiunilor Istoria Operațiunilor" #. Tag: para #, fuzzy, no-c-format msgid "A node’s resource history is held in the lrm_resources tag (a child of the lrm tag). The information stored here includes enough information for the cluster to stop the resource safely if it is removed from the configuration section. Specifically the resource’s id, class, type and provider are stored." msgstr "Istoricul resurselor unui nod este ţinut în tag-ul lrm_resources (un copil al tag-ului lrm). Informaţia stocată aici include destulă informaţie pentru ca şi clusterul să oprească resursa în siguranţă dacă este îndepărtată din secţiunea de configurare. În mod specific stocăm id, class, type şi provider-ul resursei sunt stocate." #. Tag: title #, no-c-format msgid "A record of the apcstonith resource" msgstr "O înregistrare a resursei apcstonith" #. Tag: programlisting #, fuzzy, no-c-format msgid "<lrm_resource id=\"apcstonith\" type=\"apcmastersnmp\" class=\"stonith\"/>" msgstr "" "<lrm_resource id=\"apcstonith\" type=\"apcmastersnmp\" class=\"stonith\">\n" "\t" #. Tag: para #, no-c-format msgid "Additionally, we store the last job for every combination of resource, action and interval. The concatenation of the values in this tuple are used to create the id of the lrm_rsc_op object." msgstr "Suplimentar, stocăm ultimul job pentru fiecare combinaţie de resource, action şi interval. Concatenarea valorilor din această tuplă este folosită pentru a crea id-ul obiectului lrm_rsc_op." #. Tag: title #, fuzzy, no-c-format msgid "Contents of an lrm_rsc_op job" msgstr "Conţinutul unui job lrm_rsc_op." #. Tag: para #, fuzzy, no-c-format msgid " idAction Status Action Status ActionStatusid Statusid id " msgstr "idCâmp pentru Statusul Nodului Câmpul de Statusal Noduluiid id" #. Tag: para #, fuzzy, no-c-format msgid "Identifier for the job constructed from the resource’s id, operation and interval." msgstr "Identificatorul pentru job construit din id-ul resursei, operation şi interval." #. Tag: para #, no-c-format msgid "call-id" msgstr "" #. Tag: para #, no-c-format msgid " call-idAction Status Action Status ActionStatuscall-id Statuscall-id call-id " msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "The job’s ticket number. Used as a sort key to determine the order in which the jobs were executed." msgstr "Numărul tichetului job-ului. Folosit ca şi cheie de sortare pentru a determina ordinea în care job-urile au fost executate." #. Tag: para #, fuzzy, no-c-format msgid "operation" msgstr "Valoarea aşteptată pentru join." #. Tag: para #, no-c-format msgid " operationAction Status Action Status ActionStatusoperation Statusoperation operation " msgstr "" #. Tag: para #, no-c-format msgid "The action the resource agent was invoked with." msgstr "Acţiunea cu care a fost invocat agentul de resursă." #. Tag: para #, fuzzy, no-c-format msgid "interval" msgstr "Valoarea aşteptată pentru join." #. Tag: para #, no-c-format msgid " intervalAction Status Action Status ActionStatusinterval Statusinterval interval " msgstr "" #. Tag: para #, no-c-format msgid "The frequency, in milliseconds, at which the operation will be repeated. A one-off job is indicated by 0." msgstr "Frecvenţa, în milisecunde, la care va fi repetată operaţiunea. 0 indică un job unicat." #. Tag: para #, no-c-format msgid "op-status" msgstr "" #. Tag: para #, no-c-format msgid " op-statusAction Status Action Status ActionStatusop-status Statusop-status op-status " msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "The job’s status. Generally this will be either 0 (done) or -1 (pending). Rarely used in favor of rc-code." msgstr "Status-ul job-ului. În general acesta va fi ori 0 (completat) ori -1 (în aşteptare). Rareori folosit în favoarea a rc-code." #. Tag: para #, no-c-format msgid "rc-code" msgstr "" #. Tag: para #, no-c-format msgid " rc-codeAction Status Action Status ActionStatusrc-code Statusrc-code rc-code " msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "The job’s result. Refer to for details on what the values here mean and how they are interpreted." msgstr "Rezultatul job-ului. Faceţi referire la pentru detalii despre ce înseamnă valorile de aici şi cum sunt interpretate." #. Tag: para #, no-c-format msgid "last-run" msgstr "" #. Tag: para #, no-c-format msgid " last-runAction Status Action Status ActionStatuslast-run Statuslast-run last-run " msgstr "" #. Tag: para #, no-c-format msgid "Diagnostic indicator. Machine local date/time, in seconds since epoch, at which the job was executed." msgstr "Indicator de diagnostic. Ora/data locală a maşinii, în secunde de la epoch, la care job-ul a fost executat." #. Tag: para #, no-c-format msgid "last-rc-change" msgstr "" #. Tag: para #, no-c-format msgid " last-rc-changeAction Status Action Status ActionStatuslast-rc-change Statuslast-rc-change last-rc-change " msgstr "" #. Tag: para #, no-c-format msgid "Diagnostic indicator. Machine local date/time, in seconds since epoch, at which the job first returned the current value of rc-code." msgstr "Indicator de diagnostic. Ora/data locală a maşinii, în secunde de la epocă, la care job-ul a returnat prima oară valoarea rc-code." #. Tag: para #, no-c-format msgid "exec-time" msgstr "" #. Tag: para #, no-c-format msgid " exec-timeAction Status Action Status ActionStatusexec-time Statusexec-time exec-time " msgstr "" #. Tag: para #, no-c-format msgid "Diagnostic indicator. Time, in milliseconds, that the job was running for." msgstr "Indicator de diagnostic. Timpul, în milisecunde, pentru care a rulat job-ul" #. Tag: para #, no-c-format msgid "queue-time" msgstr "" #. Tag: para #, no-c-format msgid " queue-timeAction Status Action Status ActionStatusqueue-time Statusqueue-time queue-time " msgstr "" #. Tag: para #, no-c-format msgid "Diagnostic indicator. Time, in seconds, that the job was queued for in the LRMd." msgstr "Indicator de diagnostic. Timpul, în secunde, pentru care a fost pus job-ul în coada de aşteptare în LRMd" #. Tag: para #, no-c-format msgid "crm_feature_set" msgstr "" #. Tag: para #, no-c-format msgid " crm_feature_setAction Status Action Status ActionStatuscrm_feature_set Statuscrm_feature_set crm_feature_set " msgstr "" #. Tag: para #, no-c-format msgid "The version which this job description conforms to. Used when processing op-digest." msgstr "Versiunea la care se conformează această descriere a job-ului. Folosită când se procesează op-digest." #. Tag: para #, no-c-format msgid "transition-key" msgstr "" #. Tag: para #, no-c-format msgid " transition-keyAction Status Action Status ActionStatustransition-key Statustransition-key transition-key " msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "A concatenation of the job’s graph action number, the graph number, the expected result and the UUID of the crmd instance that scheduled it. This is used to construct transition-magic (below)." msgstr "O concatenare a numărului de acţiune al grafului job-ului, numărul grafului, rezultatul aşteptat şi UUID-ul instanţei de crmd care l-a programat. Acesta este folosit pentru a construi transition-magic (mai jos)." #. Tag: para #, no-c-format msgid "transition-magic" msgstr "" #. Tag: para #, no-c-format msgid " transition-magicAction Status Action Status ActionStatustransition-magic Statustransition-magic transition-magic " msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "A concatenation of the job’s op-status, rc-code and transition-key. Guaranteed to be unique for the life of the cluster (which ensures it is part of CIB update notifications) and contains all the information needed for the crmd to correctly analyze and process the completed job. Most importantly, the decomposed elements tell the crmd if the job entry was expected and whether it failed." msgstr "O concatenare a op-status-ului job-ului, rc-code-ului şi a transition-key. Garantat să fie unic pe perioada vieţii clusterului (fapt care asigură ca este parte din notificările de actualizări ale CIB-ului) şi conţine toată informaţia necesară ca şi crmd-ul să analizeze şi să proceseze corect job-ul terminat. Cel mai important, elementele descompuse îi spun crmd-ului dacă intrarea pentru job era aşteptată şi dacă aceasta a eşuat." #. Tag: para #, no-c-format msgid "op-digest" msgstr "" #. Tag: para #, no-c-format msgid " op-digestAction Status Action Status ActionStatusop-digest Statusop-digest op-digest " msgstr "" #. Tag: para #, no-c-format msgid "An MD5 sum representing the parameters passed to the job. Used to detect changes to the configuration, to restart resources if necessary." msgstr "Un hash MD5 reprezentând parametrii trimişi job-ului. Folosit pentru a detecta schimbările în configuraţie şi a reporni resursele dacă este necesar." #. Tag: para #, fuzzy, no-c-format msgid " crm-debug-originAction Status Action Status ActionStatuscrm-debug-origin Statuscrm-debug-origin crm-debug-origin " msgstr "Câmpul crm-debug-origin pentru Statusul Nodului Câmpul de Statusal Noduluicrm-debug-origin crm-debug-origin" #. Tag: para #, no-c-format msgid "Diagnostic indicator. The origin of the current values." msgstr "Indicator de diagnostic. Originea valorilor curente." #. Tag: title #, no-c-format msgid "Simple Example" msgstr "Exemplu Simplu" #. Tag: title #, no-c-format msgid "A monitor operation (determines current state of the apcstonith resource)" msgstr "O operaţiune de monitorizare (determina starea curentă a resursei apcstonith)" #. Tag: programlisting #, fuzzy, no-c-format msgid "" "<lrm_resource id=\"apcstonith\" type=\"apcmastersnmp\" class=\"stonith\">\n" " <lrm_rsc_op id=\"apcstonith_monitor_0\" operation=\"monitor\" call-id=\"2\"\n" " rc-code=\"7\" op-status=\"0\" interval=\"0\"\n" " crm-debug-origin=\"do_update_resource\" crm_feature_set=\"3.0.1\"\n" " op-digest=\"2e3da9274d3550dc6526fb24bfcbcba0\"\n" " transition-key=\"22:2:7:2668bbeb-06d5-40f9-936d-24cb7f87006a\"\n" " transition-magic=\"0:7;22:2:7:2668bbeb-06d5-40f9-936d-24cb7f87006a\"\n" " last-run=\"1239008085\" last-rc-change=\"1239008085\" exec-time=\"10\" queue-time=\"0\"/>\n" "</lrm_resource>" msgstr "" "<lrm_resource id=\"apcstonith\" type=\"apcmastersnmp\" class=\"stonith\"> \n" " <lrm_rsc_op id=\"apcstonith_monitor_0\" operation=\"monitor\" call-id=\"2\"\n" " rc-code=\"7\" op-status=\"0\" interval=\"0\" \n" " crm-debug-origin=\"do_update_resource\" crm_feature_set=\"3.0.1\" \n" " op-digest=\"2e3da9274d3550dc6526fb24bfcbcba0\"\n" " transition-key=\"22:2:7:2668bbeb-06d5-40f9-936d-24cb7f87006a\"\n" " transition-magic=\"0:7;22:2:7:2668bbeb-06d5-40f9-936d-24cb7f87006a\" \n" " last-run=\"1239008085\" last-rc-change=\"1239008085\" exec-time=\"10\" queue-time=\"0\"/>\n" " </lrm_resource> " #. Tag: para #, fuzzy, no-c-format msgid "In the above example, the job is a non-recurring monitor operation often referred to as a \"probe\" for the apcstonith resource." msgstr "În exemplul de mai sus, job-ul este un monitor non-recurent adeseori făcută referire la acesta sub numele de \"probă\" pentru resursa apcstonith. Clusterul programează probe pentru fiecare resursă configurată când un nou nod porneşte, în vederea determinării stării curente a resursei înainte de a urma orice acţiune ulterioară." #. Tag: para #, fuzzy, no-c-format msgid "The cluster schedules probes for every configured resource on when a new node starts, in order to determine the resource’s current state before it takes any further action." msgstr "În exemplul de mai sus, job-ul este un monitor non-recurent adeseori făcută referire la acesta sub numele de \"probă\" pentru resursa apcstonith. Clusterul programează probe pentru fiecare resursă configurată când un nou nod porneşte, în vederea determinării stării curente a resursei înainte de a urma orice acţiune ulterioară." #. Tag: para #, fuzzy, no-c-format msgid "From the transition-key, we can see that this was the 22nd action of the 2nd graph produced by this instance of the crmd (2668bbeb-06d5-40f9-936d-24cb7f87006a)." msgstr "Din transition-key, putem să vedem că aceasta a fost a 22-a acţiune a celui de-al 2-lea graf produs de această instanţă a crmd-ului (2668bbeb-06d5-40f9-936d-24cb7f87006a). Al treilea câmp al transition-key conţine un 7, acest lucru indică faptul că job-ul se aşteaptă să găsească resursa inactivă. Uitându-ne acum la proprietatea rc-code, putem vedea că aşa a şi fost." #. Tag: para #, no-c-format msgid "The third field of the transition-key contains a 7, this indicates that the job expects to find the resource inactive." msgstr "" #. Tag: para #, no-c-format msgid "By looking at the rc-code property, we see that this was the case." msgstr "" #. Tag: para #, no-c-format msgid "As that is the only job recorded for this node we can conclude that the cluster started the resource elsewhere." msgstr "Cum acela este singurul job înregistrat pentru acest nod putem concluziona că clusterul a pornit resursa în altă parte." #. Tag: title #, no-c-format msgid "Complex Resource History Example" msgstr "Exemplu Complex de Istoric al Resurselor" #. Tag: title #, no-c-format msgid "Resource history of a pingd clone with multiple jobs" msgstr "Istoricul resurselor unei clone pingd cu job-uri multiple" #. Tag: programlisting #, fuzzy, no-c-format msgid "" "<lrm_resource id=\"pingd:0\" type=\"pingd\" class=\"ocf\" provider=\"pacemaker\">\n" " <lrm_rsc_op id=\"pingd:0_monitor_30000\" operation=\"monitor\" call-id=\"34\"\n" " rc-code=\"0\" op-status=\"0\" interval=\"30000\"\n" " crm-debug-origin=\"do_update_resource\" crm_feature_set=\"3.0.1\"\n" " transition-key=\"10:11:0:2668bbeb-06d5-40f9-936d-24cb7f87006a\"\n" " ...\n" " last-run=\"1239009741\" last-rc-change=\"1239009741\" exec-time=\"10\" queue-time=\"0\"/>\n" " <lrm_rsc_op id=\"pingd:0_stop_0\" operation=\"stop\"\n" " crm-debug-origin=\"do_update_resource\" crm_feature_set=\"3.0.1\" call-id=\"32\"\n" " rc-code=\"0\" op-status=\"0\" interval=\"0\"\n" " transition-key=\"11:11:0:2668bbeb-06d5-40f9-936d-24cb7f87006a\"\n" " ...\n" " last-run=\"1239009741\" last-rc-change=\"1239009741\" exec-time=\"10\" queue-time=\"0\"/>\n" " <lrm_rsc_op id=\"pingd:0_start_0\" operation=\"start\" call-id=\"33\"\n" " rc-code=\"0\" op-status=\"0\" interval=\"0\"\n" " crm-debug-origin=\"do_update_resource\" crm_feature_set=\"3.0.1\"\n" " transition-key=\"31:11:0:2668bbeb-06d5-40f9-936d-24cb7f87006a\"\n" " ...\n" " last-run=\"1239009741\" last-rc-change=\"1239009741\" exec-time=\"10\" queue-time=\"0\" />\n" " <lrm_rsc_op id=\"pingd:0_monitor_0\" operation=\"monitor\" call-id=\"3\"\n" " rc-code=\"0\" op-status=\"0\" interval=\"0\"\n" " crm-debug-origin=\"do_update_resource\" crm_feature_set=\"3.0.1\"\n" " transition-key=\"23:2:7:2668bbeb-06d5-40f9-936d-24cb7f87006a\"\n" " ...\n" " last-run=\"1239008085\" last-rc-change=\"1239008085\" exec-time=\"20\" queue-time=\"0\"/>\n" " </lrm_resource>" msgstr "" " <lrm_resource id=\"pingd:0\" type=\"pingd\" class=\"ocf\" provider=\"pacemaker\">\n" " <lrm_rsc_op id=\"pingd:0_monitor_30000\" operation=\"monitor\" call-id=\"34\"\n" " rc-code=\"0\" op-status=\"0\" interval=\"30000\" \n" " crm-debug-origin=\"do_update_resource\" crm_feature_set=\"3.0.1\" \n" " transition-key=\"10:11:0:2668bbeb-06d5-40f9-936d-24cb7f87006a\" \n" " ...\n" " last-run=\"1239009741\" last-rc-change=\"1239009741\" exec-time=\"10\" queue-time=\"0\"/>\n" " <lrm_rsc_op id=\"pingd:0_stop_0\" operation=\"stop\" \n" " crm-debug-origin=\"do_update_resource\" crm_feature_set=\"3.0.1\" call-id=\"32\"\n" " rc-code=\"0\" op-status=\"0\" interval=\"0\" \n" " transition-key=\"11:11:0:2668bbeb-06d5-40f9-936d-24cb7f87006a\" \n" " ...\n" " last-run=\"1239009741\" last-rc-change=\"1239009741\" exec-time=\"10\" queue-time=\"0\"/>\n" " <lrm_rsc_op id=\"pingd:0_start_0\" operation=\"start\" call-id=\"33\"\n" " rc-code=\"0\" op-status=\"0\" interval=\"0\" \n" " crm-debug-origin=\"do_update_resource\" crm_feature_set=\"3.0.1\" \n" " transition-key=\"31:11:0:2668bbeb-06d5-40f9-936d-24cb7f87006a\" \n" " ...\n" " last-run=\"1239009741\" last-rc-change=\"1239009741\" exec-time=\"10\" queue-time=\"0\" />\n" " <lrm_rsc_op id=\"pingd:0_monitor_0\" operation=\"monitor\" call-id=\"3\"\n" " rc-code=\"0\" op-status=\"0\" interval=\"0\" \n" " crm-debug-origin=\"do_update_resource\" crm_feature_set=\"3.0.1\" \n" " transition-key=\"23:2:7:2668bbeb-06d5-40f9-936d-24cb7f87006a\" \n" " ...\n" " last-run=\"1239008085\" last-rc-change=\"1239008085\" exec-time=\"20\" queue-time=\"0\"/>\n" " </lrm_resource> " #. Tag: para #, fuzzy, no-c-format msgid "When more than one job record exists, it is important to first sort them by call-id before interpreting them." msgstr "Când există mai mult de o singură înregistrare a unui job, este important mai întâi să le sortăm după call-id înainte de a le interpreta. Odată sortate, exemplul de mai sus poate fi sumarizat ca:" #. Tag: para #, no-c-format msgid "Once sorted, the above example can be summarized as:" msgstr "" #. Tag: para #, no-c-format msgid "A non-recurring monitor operation returning 7 (not running), with a call-id of 3" msgstr "O operaţiune non-recurentă de monitorizare returnează 7 (nu rulează), cu un call-id de 3" #. Tag: para #, no-c-format msgid "A stop operation returning 0 (success), with a call-id of 32" msgstr "O operaţiune de oprire returnează 0 (succes), cu un call-id de 32" #. Tag: para #, no-c-format msgid "A start operation returning 0 (success), with a call-id of 33" msgstr "O operaţiune de pornire returnează 0 (succes), cu un call-id de 33" #. Tag: para #, no-c-format msgid "A recurring monitor returning 0 (success), with a call-id of 34" msgstr "Un monitor recurent returnează 0 (succes), cu un call-id de 34" #. Tag: para #, fuzzy, no-c-format msgid "The cluster processes each job record to build up a picture of the resource’s state. After the first and second entries, it is considered stopped and after the third it considered active." msgstr "Clusterul procesează fiecare înregistrare a unui job pentru a construi o imagine asupra stării resursei. După prima şi a doua intrare, este considerată oprită şi după a treia este considerată activă. Pe baza ultimelor operaţiuni, putem spune că resursa este activă în mod curent." #. Tag: para #, no-c-format msgid "Based on the last operation, we can tell that the resource is currently active." msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "Additionally, from the presence of a stop operation with a lower call-id than that of the start operation, we can conclude that the resource has been restarted. Specifically this occurred as part of actions 11 and 31 of transition 11 from the crmd instance with the key 2668bbeb…. This information can be helpful for locating the relevant section of the logs when looking for the source of a failure." msgstr "Suplimentar, din prezenţa unei operaţiuni stop cu un call-id mai mic decât cel al operaţiunii start, putem concluziona că resursa a fost repornită. În mod specific acest lucru s-a întâmplat ca parte a acţiunilor 11 şi 31 ale tranziţiei 11 de la instanţa crmd cu cheia 2668bbeb-06d5-40f9-936d-24cb7f87006a. Această informaţie poate fi utilă pentru localizarea secţiunii relevante din loguri când căutaţi sursa unei defecţiuni." #~ msgid "lrm tag" #~ msgstr "tag-ul lrm" #~ msgid "Unique identifier for the node. Corosync based clusters use the uname of the machine, Heartbeat clusters use a human-readable (but annoying) UUID." #~ msgstr "Identificator unic pentru nod. Clusterele bazate pe Corosync folosesc aceeaşi valoare ca uname, clusterele Heartbeat folosesc un UUID în format uşor de citit de oameni (dar enervant)." #~ msgid "uname Node Status Field NodeStatus Fielduname uname" #~ msgstr "Câmpul uname pentru Statusul Nodului Câmpul de Statusal Noduluiuname uname" #~ msgid "The node's machine name (output from uname -n)." #~ msgstr "Numele nodului (rezultat din uname -n)" #~ msgid "ha Node Status Field NodeStatus Fieldha ha" #~ msgstr "Câmpul ha pentru Statusul Nodului Câmpul de Statusal Noduluiha ha" #~ msgid "Flag specifying whether the cluster software is active on the node. Allowed values: active, dead." #~ msgstr "Flag care specifică dacă soft-ul de cluster activ pe nod. Valori permise: active, dead." #~ msgid "in_ccm Node Status Field NodeStatus Fieldin_ccm in_ccm" #~ msgstr "Câmpul in_ccm pentru Statusul Nodului Câmpul de Statusal Noduluiin_ccm in_ccm" #~ msgid "Flag for cluster membership; allowed values: true, false." #~ msgstr "Flag pentru apartenența la cluster; valori permise: true, false." #~ msgid "crmd Node Status Field NodeStatus Fieldcrmd crmd" #~ msgstr "Câmpul crmd pentru Statusul Nodului Câmpul de Statusal Noduluicrmd crmd" #~ msgid "Flag: is the crmd process active on the node? One of online, offline." #~ msgstr "Flag: este procesul crmd activ pe nod? Valori permise: online, offline." #~ msgid "join Node Status Field NodeStatus Fieldjoin join" #~ msgstr "Câmpul join pentru Statusul Nodului Câmpul de Statusal Noduluijoin join" #~ msgid "Flag saying whether the node participates in hosting resources. Possible values: down, pending, member, banned." #~ msgstr "Flag care spune dacă nodul participă în găzduirea de resurse. Valori permise: down, pending, member, banned." #~ msgid "expected Node Status Field NodeStatus Fieldexpected expected" #~ msgstr "Câmpul expected pentru Statusul Nodului Câmpul de Statusal Noduluiexpected expected" #~ msgid "Diagnostic indicator: the origin of the most recent change(s)." #~ msgstr "Indicator de diagnostic. Originea celei mai recente schimbări." #~ msgid "idJob Field Job Fieldid id" #~ msgstr "idCâmpul Job-ului Câmpul Job-uluiid id" #~ msgid "call-id Job Field Job Fieldcall-id call-id" #~ msgstr "Câmpul Job-ului call-id Câmpul Job-uluicall-id call-id" #~ msgid "operation Job Field Job Fieldoperation operation" #~ msgstr "Câmpul Job-ului operation Câmpul Job-uluioperation operation" #~ msgid "interval Job Field Job Fieldinterval interval" #~ msgstr "Câmpul Job-ului interval Câmpul Job-uluiinterval interval" #~ msgid "op-status Job Field Job Fieldop-status op-status" #~ msgstr "Câmpul Job-ului op-status Câmpul Job-uluiop-status op-status" #~ msgid "rc-code Job Field Job Fieldrc-code rc-code" #~ msgstr "Câmpul Job-ului rc-code Câmpul Job-uluirc-code rc-code" #~ msgid "last-run Job Field Job Fieldlast-run last-run" #~ msgstr "Câmpul Job-ului last-run Câmpul Job-uluilast-run last-run" #~ msgid "last-rc-change Job Field Job Fieldlast-rc-change last-rc-change" #~ msgstr "Câmpul Job-ului last-rc-change Câmpul Job-uluilast-rc-change last-rc-change" #~ msgid "exec-time Job Field Job Fieldexec-time exec-time" #~ msgstr "Câmpul Job-ului exec-time Câmpul Job-uluiexec-time exec-time" #~ msgid "queue-time Job Field Job Fieldqueue-time queue-time" #~ msgstr "Câmpul Job-ului queue-time Câmpul Job-uluiqueue-time queue-time" #~ msgid "crm_feature_set Job Field Job Fieldcrm_feature_set crm_feature_set" #~ msgstr "Câmpul Job-ului crm_feature_set Câmpul Job-uluicrm_feature_set crm_feature_set" #~ msgid "transition-key Job Field Job Fieldtransition-key transition-key" #~ msgstr "Câmpul Job-ului transition-key Câmpul Job-uluitransition-key transition-key" #~ msgid "transition-magic Job Field Job Fieldtransition-magic transition-magic" #~ msgstr "Câmpul Job-ului transition-magic Câmpul Job-uluitransition-magic transition-magic" #~ msgid "op-digest Job Field Job Fieldop-digest op-digest" #~ msgstr "Câmpul Job-ului op-digest Câmpul Job-uluiop-digest op-digest" #~ msgid "crm-debug-origin Job Field Job Fieldcrm-debug-origin crm-debug-origin" #~ msgstr "Câmpul Job-ului crm-debug-origin Câmpul Job-uluicrm-debug-origin crm-debug-origin" pacemaker-master/doc/Pacemaker_Explained/ro-RO/Ch-Stonith.po000066400000000000000000000556531217637305600242330ustar00rootroot00000000000000msgid "" msgstr "" "Project-Id-Version: Pacemaker 1.1\n" "POT-Creation-Date: 2012-10-17T05:19:02\n" "PO-Revision-Date: 2012-01-01T17:48:32\n" "Last-Translator: Dan Frîncu \n" "Language-Team: None\n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: application/x-publican; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. Tag: title #, fuzzy, no-c-format msgid "Configure STONITH" msgstr "Configurarea STONITH" #. Tag: para #, no-c-format msgid " STONITHConfiguration Configuration " msgstr "" #. Tag: title #, fuzzy, no-c-format msgid "What Is STONITH" msgstr "De Ce Aveţi Nevoie De STONITH" #. Tag: para #, fuzzy, no-c-format msgid "STONITH is an acronym for Shoot-The-Other-Node-In-The-Head and it protects your data from being corrupted by rogue nodes or concurrent access." msgstr "STONITH este un acronim pentru Shoot-The-Other-Node-In-The-Head şi protejează datele voastre de la a fi corupte de către noduri pribege sau de la acces simultan." #. Tag: para #, fuzzy, no-c-format msgid "Just because a node is unresponsive, this doesn’t mean it isn’t accessing your data. The only way to be 100% sure that your data is safe, is to use STONITH so we can be certain that the node is truly offline, before allowing the data to be accessed from another node." msgstr "Doar pentru că un nod nu mai răspunde, acest lucru nu înseamnă că acesta nu mai accesează datele voastre. Singura metodă de a fi 100% siguri că datele voastre sunt în siguranţă, este să folosiţi STONITH pentru a putea fi siguri că nodul este cu adevărat offline, înainte de a permite datelor să fie accesate de pe alt nod." #. Tag: para #, no-c-format msgid "STONITH also has a role to play in the event that a clustered service cannot be stopped. In this case, the cluster uses STONITH to force the whole node offline, thereby making it safe to start the service elsewhere." msgstr "STONITH mai are un rol pe care îl joacă în cazul în care un serviciu de pe cluster nu poate fi oprit. În acest caz, clusterul foloseşte STONITH pentru a forţa întregul nod offline, astfel făcând să fie sigurâ pornirea serviciului în altă parte." #. Tag: title #, no-c-format msgid "What STONITH Device Should You Use" msgstr "Ce Dispozitiv STONITH Ar Trebui Să Folosiţi" #. Tag: para #, fuzzy, no-c-format msgid "It is crucial that the STONITH device can allow the cluster to differentiate between a node failure and a network one." msgstr "Este imperativ ca dispozitivul STONITH să permită clusterului să facă diferenţa între o defecţiune a nodului şi una a reţelei." #. Tag: para #, fuzzy, no-c-format msgid "The biggest mistake people make in choosing a STONITH device is to use remote power switch (such as many on-board IMPI controllers) that shares power with the node it controls. In such cases, the cluster cannot be sure if the node is really offline, or active and suffering from a network fault." msgstr "Cea mai mare greşeală pe care o fac oamenii în alegerea unui dispozitiv STONITH este să folosească un switch de curent cu acces la distanţă (cum ar fi multe controlere IPMI integrate) care partajează curentul cu nodul pe care îl controlează. În astfel de cazuri, clusterul nu poate fi sigur dacă nodul este cu adevărat offline sau inactiv şi suferă din cauza unei probleme de reţea." #. Tag: para #, no-c-format msgid "Likewise, any device that relies on the machine being active (such as SSH-based \"devices\" used during testing) are inappropriate." msgstr "În mod similar, orice dispozitiv care se bazează pe maşină să fie activă (cum ar fi \"dispozitivele\" bazate pe SSH folosite în timpul testării) sunt nepotrivite." #. Tag: title #, no-c-format msgid "Configuring STONITH" msgstr "Configurarea STONITH" #. Tag: para #, fuzzy, no-c-format msgid "Find the correct driver: stonith_admin --list-installed" msgstr "Găsiţi driverul corect: stonith_admin --list-installed" #. Tag: para #, fuzzy, no-c-format msgid "Since every device is different, the parameters needed to configure it will vary. To find out the parameters associated with the device, run: stonith_admin --metadata --agent type" msgstr "Din moment ce fiecare dispozitiv este diferit, parametrii necesari să îl configureze vor varia. Pentru a afla parametrii asociaţi dispozitivului, rulaţi:" #. Tag: literallayout #, fuzzy, no-c-format msgid "" "The output should be XML formatted text containing additional\n" "parameter descriptions. We will endevor to make the output more\n" "friendly in a later version." msgstr "Rezultatul de ieşire ar trebui să fie un text formatat XML conţinând descrierile parametrilor adiţionali. Ne vom aventura să facem rezultatul de ieşire mai prietenos într-o versiune ulterioară." #. Tag: para #, fuzzy, no-c-format msgid "Enter the shell crm Create an editable copy of the existing configuration cib new stonith Create a fencing resource containing a primitive resource with a class of stonith, a type of type and a parameter for each of the values returned in step 2: configure primitive …" msgstr "Creaţi un fişier numit stonith.xml conţinând o resursă primitivă cu o clasă de stonith, un tip de type şi un parametru pentru fiecare dintre valorile returnate la pasul 2" #. Tag: para #, fuzzy, no-c-format msgid "If the device does not know how to fence nodes based on their uname, you may also need to set the special pcmk_host_map parameter. See man stonithd for details." msgstr "Dacă dispozitivul nu ştie să evacueze noduri pe baza uname-ului acestora, ar putea fi nevoie să setaţi parametrul special pcmk_host_map. Vedeţi man stonithd pentru detalii." #. Tag: para #, fuzzy, no-c-format msgid "If the device does not support the list command, you may also need to set the special pcmk_host_list and/or pcmk_host_check parameters. See man stonithd for details." msgstr "Dacă dispozitivul nu suportă comanda list, ar putea fi nevoie să setaţi parametrii speciali pcmk_host_list şi/sau pcmk_host_check. Vedeţi man stonithd pentru detalii." #. Tag: para #, fuzzy, no-c-format msgid "If the device does not expect the victim to be specified with the port parameter, you may also need to set the special pcmk_host_argument parameter. See man stonithd for details." msgstr "Dacă dispozitivul nu se aşteaptă ca victima să fie specificată cu parametrul port, ar putea fi nevoie să setaţi parametrul special pcmk_host_argument. Vedeţi man stonithd pentru detalii." #. Tag: para #, no-c-format msgid "Upload it into the CIB from the shell: cib commit stonith" msgstr "" #. Tag: para #, fuzzy, no-c-format msgid "Once the stonith resource is running, you can test it by executing: stonith_admin --reboot nodename. Although you might want to stop the cluster on that machine first." msgstr "Odată ce resursa stonith rulează, o puteţi testa executând: stonith_admin --reboot nodename. Deşi aţi putea dori să opriţi clusterul pe acea maşină mai întâi." #. Tag: title #, no-c-format msgid "Example" msgstr "Exemplu" #. Tag: para #, fuzzy, no-c-format msgid "Assuming we have an chassis containing four nodes and an IPMI device active on 10.0.0.1, then we would chose the fence_ipmilan driver in step 2 and obtain the following list of parameters" msgstr "Presupunând că avem un şasiu conţinând patru noduri şi un dispozitiv IPMI activ pe 10.0.0.1, atunci am alege driverul fence_ipmilan la pasul 2 şi am obţine următoarea listă de parametri" #. Tag: title #, no-c-format msgid "Obtaining a list of STONITH Parameters" msgstr "Obţinerea unei liste de Parametri STONITH" #. Tag: programlisting #, no-c-format msgid "# stonith_admin --metadata -a fence_ipmilan" msgstr "" #. Tag: programlisting #, fuzzy, no-c-format msgid "" "<?xml version=\"1.0\" ?>\n" "<resource-agent name=\"fence_ipmilan\" shortdesc=\"Fence agent for IPMI over LAN\">\n" "<longdesc>\n" "fence_ipmilan is an I/O Fencing agent which can be used with machines controlled by IPMI. This agent calls support software using ipmitool (http://ipmitool.sf.net/).\n" "\n" "To use fence_ipmilan with HP iLO 3 you have to enable lanplus option (lanplus / -P) and increase wait after operation to 4 seconds (power_wait=4 / -T 4)</longdesc>\n" "<parameters>\n" " <parameter name=\"auth\" unique=\"1\">\n" " <getopt mixed=\"-A\" />\n" " <content type=\"string\" />\n" " <shortdesc>IPMI Lan Auth type (md5, password, or none)</shortdesc>\n" " </parameter>\n" " <parameter name=\"ipaddr\" unique=\"1\">\n" " <getopt mixed=\"-a\" />\n" " <content type=\"string\" />\n" " <shortdesc>IPMI Lan IP to talk to</shortdesc>\n" " </parameter>\n" " <parameter name=\"passwd\" unique=\"1\">\n" " <getopt mixed=\"-p\" />\n" " <content type=\"string\" />\n" " <shortdesc>Password (if required) to control power on IPMI device</shortdesc>\n" " </parameter>\n" " <parameter name=\"passwd_script\" unique=\"1\">\n" " <getopt mixed=\"-S\" />\n" " <content type=\"string\" />\n" " <shortdesc>Script to retrieve password (if required)</shortdesc>\n" " </parameter>\n" " <parameter name=\"lanplus\" unique=\"1\">\n" " <getopt mixed=\"-P\" />\n" " <content type=\"boolean\" />\n" " <shortdesc>Use Lanplus</shortdesc>\n" " </parameter>\n" " <parameter name=\"login\" unique=\"1\">\n" " <getopt mixed=\"-l\" />\n" " <content type=\"string\" />\n" " <shortdesc>Username/Login (if required) to control power on IPMI device</shortdesc>\n" " </parameter>\n" " <parameter name=\"action\" unique=\"1\">\n" " <getopt mixed=\"-o\" />\n" " <content type=\"string\" default=\"reboot\"/>\n" " <shortdesc>Operation to perform. Valid operations: on, off, reboot, status, list, diag, monitor or metadata</shortdesc>\n" " </parameter>\n" " <parameter name=\"timeout\" unique=\"1\">\n" " <getopt mixed=\"-t\" />\n" " <content type=\"string\" />\n" " <shortdesc>Timeout (sec) for IPMI operation</shortdesc>\n" " </parameter>\n" " <parameter name=\"cipher\" unique=\"1\">\n" " <getopt mixed=\"-C\" />\n" " <content type=\"string\" />\n" " <shortdesc>Ciphersuite to use (same as ipmitool -C parameter)</shortdesc>\n" " </parameter>\n" " <parameter name=\"method\" unique=\"1\">\n" " <getopt mixed=\"-M\" />\n" " <content type=\"string\" default=\"onoff\"/>\n" " <shortdesc>Method to fence (onoff or cycle)</shortdesc>\n" " </parameter>\n" " <parameter name=\"power_wait\" unique=\"1\">\n" " <getopt mixed=\"-T\" />\n" " <content type=\"string\" default=\"2\"/>\n" " <shortdesc>Wait X seconds after on/off operation</shortdesc>\n" " </parameter>\n" " <parameter name=\"delay\" unique=\"1\">\n" " <getopt mixed=\"-f\" />\n" " <content type=\"string\" />\n" " <shortdesc>Wait X seconds before fencing is started</shortdesc>\n" " </parameter>\n" " <parameter name=\"verbose\" unique=\"1\">\n" " <getopt mixed=\"-v\" />\n" " <content type=\"boolean\" />\n" " <shortdesc>Verbose mode</shortdesc>\n" " </parameter>\n" "</parameters>\n" "<actions>\n" " <action name=\"on\" />\n" " <action name=\"off\" />\n" " <action name=\"reboot\" />\n" " <action name=\"status\" />\n" " <action name=\"diag\" />\n" " <action name=\"list\" />\n" " <action name=\"monitor\" />\n" " <action name=\"metadata\" />\n" "</actions>\n" "</resource-agent>" msgstr "" "# stonith_admin --metadata -a fence_ipmilan\n" "<?xml version=\"1.0\" ?>\n" "<resource-agent name=\"fence_ipmilan\" shortdesc=\"Fence agent for IPMI over LAN\">\n" "<longdesc>\n" "fence_ipmilan is an I/O Fencing agent which can be used with machines controlled by IPMI.\n" "This agent calls support software using ipmitool (http://ipmitool.sf.net/).\n" "\n" "To use fence_ipmilan with HP iLO 3 you have to enable lanplus option (lanplus / -P) and\n" "increase wait after operation to 4 seconds (power_wait=4 / -T 4)</longdesc>\n" "<parameters>\n" " <parameter name=\"auth\" unique=\"1\">\n" " <shortdesc lang=\"en\">IPMI Lan Auth type (md5, password, or none)</shortdesc>\n" " <getopt mixed=\"-A\" /> <content type=\"string\" /> </parameter>\n" " <parameter name=\"ipaddr\" unique=\"1\">\n" " <shortdesc lang=\"en\">IPMI Lan IP to talk to</shortdesc>\n" " <getopt mixed=\"-a\" /> <content type=\"string\" /> </parameter>\n" " <parameter name=\"passwd\" unique=\"1\">\n" " <shortdesc lang=\"en\">Password to control power on IPMI device</shortdesc>\n" " <getopt mixed=\"-p\" /> <content type=\"string\" /> </parameter>\n" " <parameter name=\"passwd_script\" unique=\"1\">\n" " <shortdesc lang=\"en\">Script to retrieve password (if required)</shortdesc>\n" " <getopt mixed=\"-S\" /> <content type=\"string\" /> </parameter>\n" " <parameter name=\"lanplus\" unique=\"1\">\n" " <shortdesc lang=\"en\">Use Lanplus</shortdesc>\n" " <getopt mixed=\"-P\" /> <content type=\"boolean\" /> </parameter>\n" " <parameter name=\"login\" unique=\"1\">\n" " <shortdesc lang=\"en\">Username/Login to control IPMI device</shortdesc>\n" " <getopt mixed=\"-l\" /> <content type=\"string\" /> </parameter>\n" " <parameter name=\"action\" unique=\"1\">\n" " <shortdesc lang=\"en\">Operation to perform. Valid operations:\n" " on, off, reboot, status, list, diag, monitor or metadata</shortdesc>\n" " <getopt mixed=\"-o\" /> <content type=\"string\" default=\"reboot\"/> </parameter>\n" " <parameter name=\"timeout\" unique=\"1\">\n" " <shortdesc lang=\"en\">Timeout (sec) for IPMI operation</shortdesc>\n" " <getopt mixed=\"-t\" /> <content type=\"string\" /> </parameter>\n" " <parameter name=\"cipher\" unique=\"1\">\n" " <shortdesc lang=\"en\">Ciphersuite to use (same as ipmitool -C parameter)</shortdesc>\n" " <getopt mixed=\"-C\" /> <content type=\"string\" /> </parameter>\n" " <parameter name=\"method\" unique=\"1\">\n" " <shortdesc lang=\"en\">Method to fence (onoff or cycle)</shortdesc>\n" " <getopt mixed=\"-M\" /> <content type=\"string\" default=\"onoff\"/> </parameter>\n" " <parameter name=\"power_wait\" unique=\"1\">\n" " <shortdesc lang=\"en\">Wait X seconds after on/off operation</shortdesc>\n" " <getopt mixed=\"-T\" /> <content type=\"string\" default=\"2\"/> </parameter>\n" " <parameter name=\"delay\" unique=\"1\">\n" " <shortdesc lang=\"en\">Wait X seconds before fencing is started</shortdesc>\n" " <getopt mixed=\"-f\" /> <content type=\"string\" /> </parameter>\n" " <parameter name=\"verbose\" unique=\"1\">\n" " <shortdesc lang=\"en\">Verbose mode</shortdesc>\n" " <getopt mixed=\"-v\" /> <content type=\"boolean\" /> </parameter>\n" "</parameters>\n" "<actions>\n" " <action name=\"on\" /> <action name=\"off\" /> \n" " <action name=\"reboot\" /> <action name=\"status\" /> \n" " <action name=\"diag\" /> <action name=\"list\" /> \n" " <action name=\"monitor\" /> <action name=\"metadata\" />\n" "</actions>\n" "</resource-agent>\n" " " #. Tag: para #, fuzzy, no-c-format msgid "from which we would create a STONITH resource fragment that might look like this" msgstr "Din această listă am putea crea un fragment de resursă STONITH care ar putea arăta aşa:" #. Tag: title #, no-c-format msgid "Sample STONITH Resource" msgstr "Exemplu de Resursă STONITH" #. Tag: programlisting #, no-c-format msgid "" "# crm crm(live)# cib new stonith\n" "INFO: stonith shadow CIB created\n" "crm(stonith)# configure primitive impi-fencing stonith::fence_ipmilan \\\n" " params pcmk_host_list=\"pcmk-1 pcmk-2\" ipaddr=10.0.0.1 login=testuser passwd=abc123 \\\n" " op monitor interval=\"60s\"" msgstr "" #. Tag: para #, no-c-format msgid "And finally, since we disabled it earlier, we need to re-enable STONITH. At this point we should have the following configuration." msgstr "" #. Tag: para #, no-c-format msgid "Now push the configuration into the cluster." msgstr "" #. Tag: programlisting #, no-c-format msgid "" "crm(stonith)# configure property stonith-enabled=\"true\"\n" "crm(stonith)# configure shownode pcmk-1\n" "node pcmk-2\n" "primitive WebData ocf:linbit:drbd \\\n" " params drbd_resource=\"wwwdata\" \\\n" " op monitor interval=\"60s\"\n" "primitive WebFS ocf:heartbeat:Filesystem \\\n" " params device=\"/dev/drbd/by-res/wwwdata\" directory=\"/var/www/html\" fstype=\"gfs2\"\n" "primitive WebSite ocf:heartbeat:apache \\\n" " params configfile=\"/etc/httpd/conf/httpd.conf\" \\\n" " op monitor interval=\"1min\"\n" "primitive ClusterIP ocf:heartbeat:IPaddr2 \\\n" " params ip=\"192.168.122.101\" cidr_netmask=\"32\" clusterip_hash=\"sourceip\" \\\n" " op monitor interval=\"30s\"primitive ipmi-fencing stonith::fence_ipmilan \\ params pcmk_host_list=\"pcmk-1 pcmk-2\" ipaddr=10.0.0.1 login=testuser passwd=abc123 \\ op monitor interval=\"60s\"ms WebDataClone WebData \\\n" " meta master-max=\"2\" master-node-max=\"1\" clone-max=\"2\" clone-node-max=\"1\" notify=\"true\"\n" "clone WebFSClone WebFS\n" "clone WebIP ClusterIP \\\n" " meta globally-unique=\"true\" clone-max=\"2\" clone-node-max=\"2\"\n" "clone WebSiteClone WebSite\n" "colocation WebSite-with-WebFS inf: WebSiteClone WebFSClone\n" "colocation fs_on_drbd inf: WebFSClone WebDataClone:Master\n" "colocation website-with-ip inf: WebSiteClone WebIP\n" "order WebFS-after-WebData inf: WebDataClone:promote WebFSClone:start\n" "order WebSite-after-WebFS inf: WebFSClone WebSiteClone\n" "order apache-after-ip inf: WebIP WebSiteClone\n" "property $id=\"cib-bootstrap-options\" \\\n" " dc-version=\"1.1.5-bdd89e69ba545404d02445be1f3d72e6a203ba2f\" \\\n" " cluster-infrastructure=\"openais\" \\\n" " expected-quorum-votes=\"2\" \\\n" " stonith-enabled=\"true\" \\\n" " no-quorum-policy=\"ignore\"\n" "rsc_defaults $id=\"rsc-options\" \\\n" " resource-stickiness=\"100\"\n" "crm(stonith)# cib commit stonithINFO: commited 'stonith' shadow CIB to the cluster\n" "crm(stonith)# quit\n" "bye" msgstr "" #~ msgid "Protecting Your Data - STONITH" #~ msgstr "Protejarea Datelor Voastre - STONITH" #~ msgid "" #~ "stonith_admin --metadata --agent type\n" #~ " " #~ msgstr "" #~ "stonith_admin --metadata --agent type\n" #~ " " #~ msgid "Upload it into the CIB using cibadmin: cibadmin -C -o resources --xml-file stonith.xml" #~ msgstr "Încărcaţi-l în CIB folosind cibadmin: cibadmin -C -o resources --xml-file stonith.xml" #~ msgid "" #~ " <primitive id=\"ipmi\" class=\"stonith\" type=\"fence_ipmilan\">\n" #~ " <operations>\n" #~ " <op id=\"ipmi-mon-1\" name=\"monitor\" interval=\"2h\"/>\n" #~ " </operations>\n" #~ " <instance_attributes id=\"ipmi-parameters\">\n" #~ " <nvpair id=\"ipmi-attr-1\" name=\"pcmk_host_list\" value=\"node1 node2 node3 node4\"/>\n" #~ " <nvpair id=\"ipmi-attr-1\" name=\"ipaddr\" value=\"10.0.0.1\"/>\n" #~ " <nvpair id=\"ipmi-attr-1\" name=\"login\" value=\"testuser\"/>\n" #~ " <nvpair id=\"ipmi-attr-1\" name=\"passwd\" value=\"abc123\"/>\n" #~ " </instance_attributes>\n" #~ " </primitive> " #~ msgstr "" #~ " <primitive id=\"ipmi\" class=\"stonith\" type=\"fence_ipmilan\">\n" #~ " <operations>\n" #~ " <op id=\"ipmi-mon-1\" name=\"monitor\" interval=\"2h\"/>\n" #~ " </operations>\n" #~ " <instance_attributes id=\"ipmi-parameters\">\n" #~ " <nvpair id=\"ipmi-attr-1\" name=\"pcmk_host_list\" value=\"node1 node2 node3 node4\"/>\n" #~ " <nvpair id=\"ipmi-attr-1\" name=\"ipaddr\" value=\"10.0.0.1\"/>\n" #~ " <nvpair id=\"ipmi-attr-1\" name=\"login\" value=\"testuser\"/>\n" #~ " <nvpair id=\"ipmi-attr-1\" name=\"passwd\" value=\"abc123\"/>\n" #~ " </instance_attributes>\n" #~ " </primitive> " #~ msgid "The monitor interval of two hours is explained by bugs in some IPMI implementations; see Monitoring the fencing devices." #~ msgstr "Intervalul de monitorizare de două ore este explicat de bug-uri în anumite implementări de IPMI; vedeți Monitorizarea dispozitivelor de evacuare forțată." pacemaker-master/doc/Pacemaker_Explained/ro-RO/Pacemaker_Explained.po000066400000000000000000000040031217637305600261130ustar00rootroot00000000000000msgid "" msgstr "" "Project-Id-Version: Pacemaker 1.1\n" "POT-Creation-Date: 2012-10-17T05:19:02\n" "PO-Revision-Date: 2012-01-01T17:48:32\n" "Last-Translator: Dan Frîncu \n" "Language-Team: None\n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: application/x-publican; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. Tag: title #, no-c-format msgid "Receiving Notification for Cluster Events" msgstr "Primirea de Notificări ale Evenimentelor Clusterului" #. Tag: title #, no-c-format msgid "Configuring Email Notifications" msgstr "Configurarea de Notificări pe Email" #. Tag: title #, no-c-format msgid "Configuring SNMP Notifications" msgstr "Configurarea de Notificări pe SNMP" #. Tag: title #, no-c-format msgid "Further Reading" msgstr "Documentaţie Adiţională" #. Tag: para #, no-c-format msgid "Project Website " msgstr "Site-ul Proiectului " #. Tag: para #, no-c-format msgid "Project Documentation " msgstr "Documentaţia Proiectului " #. Tag: para #, fuzzy, no-c-format msgid "A comprehensive guide to cluster commands has been written by Novell" msgstr "Un ghid comprehensiv al comenzilor clusterului a fost scris de Novell şi poate fi găsit la: " #. Tag: para #, no-c-format msgid "Heartbeat configuration: " msgstr "Configuraţia Heartbeat: " #. Tag: para #, no-c-format msgid "Corosync Configuration: " msgstr "Configuraţia Corosync: " pacemaker-master/doc/Pacemaker_Explained/ro-RO/Preface.po000066400000000000000000000007451217637305600236100ustar00rootroot00000000000000msgid "" msgstr "" "Project-Id-Version: Pacemaker 1.1\n" "POT-Creation-Date: 2012-10-17T05:19:02\n" "PO-Revision-Date: 2012-01-01T17:48:32\n" "Last-Translator: Dan Frîncu \n" "Language-Team: None\n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: application/x-publican; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. Tag: title #, no-c-format msgid "Preface" msgstr "Prefaţă" #~ msgid "translator-credits" #~ msgstr "genericul-traducătorului" pacemaker-master/doc/Pacemaker_Explained/ro-RO/Revision_History.po000066400000000000000000000035511217637305600255600ustar00rootroot00000000000000msgid "" msgstr "" "Project-Id-Version: Pacemaker 1.1\n" "POT-Creation-Date: 2012-10-17T05:19:02\n" "PO-Revision-Date: 2012-01-01T17:48:32\n" "Last-Translator: Dan Frîncu \n" "Language-Team: None\n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: application/x-publican; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. Tag: title #, no-c-format msgid "Revision History" msgstr "Istoricul Reviziilor" #. Tag: firstname #, no-c-format msgid "Andrew" msgstr "Andrew" #. Tag: surname #, no-c-format msgid "Beekhof" msgstr "Beekhof" #. Tag: member #, no-c-format msgid "Import from Pages.app" msgstr "Import din Pages.app" #. Tag: member #, no-c-format msgid "Cleanup and reformatting of docbook xml complete" msgstr "Curăţarea şi reformatarea xml-ului pentru docbook terminată" #. Tag: member #, no-c-format msgid "Split book into chapters and pass validation" msgstr "Împărţirea cărţii în capitole şi trecerea validării" #. Tag: member #, no-c-format msgid "Re-organize book for use with Publican" msgstr "" #. Tag: member #, no-c-format msgid "Converted to asciidoc (which is converted to docbook for use with Publican)" msgstr "" #~ msgid "1" #~ msgstr "1" #~ msgid "19 Oct 2009" #~ msgstr "19 Oct 2009" #~ msgid "andrew@beekhof.net" #~ msgstr "andrew@beekhof.net" #~ msgid "2" #~ msgstr "2" #~ msgid "26 Oct 2009" #~ msgstr "26 Oct 2009" #~ msgid "3" #~ msgstr "3" #~ msgid "Tue Nov 12 2009" #~ msgstr "Tue Nov 12 2009" #~ msgid "Publican" #~ msgstr "Publican" #~ msgid "Re-organize book for use with " #~ msgstr "Reorganizarea cărţii pentru folosirea cu " #~ msgid "translator-credits" #~ msgstr "genericul-traducătorului" pacemaker-master/doc/Pacemaker_Remote/000077500000000000000000000000001217637305600202615ustar00rootroot00000000000000pacemaker-master/doc/Pacemaker_Remote/en-US/000077500000000000000000000000001217637305600212105ustar00rootroot00000000000000pacemaker-master/doc/Pacemaker_Remote/en-US/Author_Group.xml000066400000000000000000000006341217637305600243530ustar00rootroot00000000000000 DavidVossel Red Hat Primary author dvossel@redhat.com pacemaker-master/doc/Pacemaker_Remote/en-US/Book_Info.xml000066400000000000000000000032311217637305600235760ustar00rootroot00000000000000 %BOOK_ENTITIES; ]> Pacemaker Remote Extending High Availablity into Virtual Nodes 1 0 The document exists as both a reference and deployment guide for the Pacemaker Remote service. The KVM and Linux Container walk-through tutorials will use: &DISTRO; &DISTRO_VERSION; as the host operating system Pacemaker Remote to perform resource management within virtual nodes libvirt to manage KVM and LXC virtual nodes Corosync to provide messaging and membership services on the host nodes Pacemaker to perform resource management on host nodes pacemaker-master/doc/Pacemaker_Remote/en-US/Ch-Example.txt000066400000000000000000000106421217637305600236770ustar00rootroot00000000000000= Quick Example = If you already know how to use pacemaker, you'll likely be able to grasp this new concept of remote-nodes by reading through this quick example without having to sort through all the detailed walk-through steps. Here are the key configuration ingredients that make this possible using libvirt and KVM virtual guests. These steps strip everything down to the very basics. == Mile High View of Configuration Steps == * +Put an authkey with this path, /etc/pacemaker/authkey, on every cluster-node and virtual machine+. This secures remote communication and authentication. Run this command if you want to make a somewhat random authkey. [source,C] ---- dd if=/dev/urandom of=/etc/pacemaker/authkey bs=4096 count=1 ---- * +Install pacemaker_remote packages every virtual machine, enable pacemaker_remote on startup, and poke hole in firewall for tcp port 3121.+ [source,C] ---- yum install pacemaker-remote resource-agents systemctl enable pacemaker_remote # If you just want to see this work, disable iptables and ip6tables on most distros. # You may have to put selinux in permissive mode as well for the time being. firewall-cmd --add-port 3121/tcp --permanent ---- * +Give each virtual machine a static network address and unique hostname+ * +Tell pacemaker to launch a virtual machine and that the virtual machine is a remote-node capable of running resources by using the "remote-node" meta-attribute.+ with pcs [source,C] ---- # pcs resource create vm-guest1 VirtualDomain hypervisor="qemu:///system" config="vm-guest1.xml" meta +remote-node=guest1+ ---- raw xml [source,XML] ---- ---- In the example above the meta-attribute 'remote-node=guest1' tells pacemaker that this resource is a remote-node with the hostname 'guest1' that is capable of being integrated into the cluster. The cluster will attempt to contact the virtual machine's pacemaker_remote service at the hostname 'guest1' after it launches. == What those steps just did == Those steps just told pacemaker to launch a virtual machine called vm-guest1 and integrate that virtual machine as a remote-node called 'guest1'. Example crm_mon output after guest1 is integrated into cluster. [source,C] ---- Last updated: Wed Mar 13 13:52:39 2013 Last change: Wed Mar 13 13:25:17 2013 via crmd on node1 Stack: corosync Current DC: node1 (24815808) - partition with quorum Version: 1.1.10 2 Nodes configured, unknown expected votes 2 Resources configured. Online: [ node1 guest1] vm-guest1 (ocf::heartbeat:VirtualDomain): Started node1 ---- Now, you could place a resource, such as a webserver on guest1. [source,C] ---- # pcs resource create webserver apache params configfile=/etc/httpd/conf/httpd.conf op monitor interval=30s # pcs constraint webserver prefers guest1 ---- Now the crm_mon output would show a webserver launched on the guest1 remote-node. [source,C] ---- Last updated: Wed Mar 13 13:52:39 2013 Last change: Wed Mar 13 13:25:17 2013 via crmd on node1 Stack: corosync Current DC: node1 (24815808) - partition with quorum Version: 1.1.10 2 Nodes configured, unknown expected votes 2 Resources configured. Online: [ node1 guest1] vm-guest1 (ocf::heartbeat:VirtualDomain): Started node1 webserver (ocf::heartbeat::apache): Started guest1 ---- == Accessing Cluster from Remote-node == It is worth noting that after 'guest1' is integrated into the cluster, all the pacemaker cli tools immediately become available to the remote node. This means things like crm_mon, crm_resource, and crm_attribute will work natively on the remote-node as long as the connection between the remote-node and cluster-node exists. This is particularly important for any master/slave resources executing on the remote-node that need access to crm_master to set the nodes transient attributes. pacemaker-master/doc/Pacemaker_Remote/en-US/Ch-Future.txt000066400000000000000000000033751217637305600235630ustar00rootroot00000000000000= Future Features = Basic KVM and Linux container integration was the first phase of development for pacemaker_remote and was completed for Pacemaker v1.1.10. Here are some planned features that expand upon this initial functionality. == Libvirt Sandbox Support == Once the libvirt-sandbox project is integrated with pacemaker_remote, we will gain the ability to preform per-resource linux container isolation with very little performance impact. This functionality will allow resources living on a single node to be isolated from one another. At that point CPU and memory limits could be set per-resource dynamically just using the cluster config. == Bare-metal Support == The pacemaker_remote daemon already has the ability to run on bare-metal hardware nodes, but the policy engine logic for integrating bare-metal nodes is not complete. There are some complications involved with understanding a bare-metal node's state that virtual nodes don't have. Once this logic is complete, pacemaker will be able to integrate bare-metal nodes in the same way virtual remote-nodes currently are. Some special considerations for fencing will need to be addressed. == KVM Migration Support == Pacemaker's policy engine is limited in its ability to perform live migrations of KVM resources when resource dependencies are involved. This limitation affects how resources living within a KVM remote-node are handled when a live migration takes place. Currently when a live migration is performed on a KVM remote-node, all the resources within that remote-node have to be stopped before the migration takes place and started once again after migration has finished. This policy engine limitation is fully explained in this bug report, http://bugs.clusterlabs.org/show_bug.cgi?id=5055#c3 pacemaker-master/doc/Pacemaker_Remote/en-US/Ch-Intro.txt000066400000000000000000000126301217637305600233760ustar00rootroot00000000000000= Extending High Availability Cluster into Virtual Nodes = == Overview == The recent addition of the +pacemaker_remote+ service supported by +Pacemaker version 1.1.10 and greater+ allows nodes not running the cluster stack (pacemaker+corosync) to integrate into the cluster and have the cluster manage their resources just as if they were a real cluster node. This means that pacemaker clusters are now capable of managing both launching virtual environments (KVM/LXC) as well as launching the resources that live within those virtual environments without requiring the virtual environments to run pacemaker or corosync. == Terms == +cluster-node+ - A baremetal hardware node running the High Availability stack (pacemaker + corosync) +remote-node+ - A virtual guest node running the pacemaker_remote service. +pacemaker_remote+ - A service daemon capable of performing remote application management within virtual guests (kvm and lxc) in both pacemaker cluster environments and standalone (non-cluster) environments. This service is an enhanced version of pacemaker's local resource manage daemon (LRMD) that is capable of managing and monitoring LSB, OCF, upstart, and systemd resources on a guest remotely. It also allows for most of pacemaker's cli tools (crm_mon, crm_resource, crm_master, crm_attribute, ect..) to work natively on remote-nodes. +LXC+ - A Linux Container defined by the libvirt-lxc Linux container driver. http://libvirt.org/drvlxc.html == Virtual Machine Use Case == The use of pacemaker_remote in virtual machines solves a deployment scenario that has traditionally been difficult to solve. +"I want a pacemaker cluster to manage virtual machine resources, but I also want pacemaker to be able to manage the resources that live within those virtual machines."+ In the past, users desiring this deployment had to make a decision. They would either have to sacrifice the ability of monitoring resources residing within virtual guests by running the cluster stack on the baremetal nodes, or run another cluster instance on the virtual guests where they potentially run into corosync scalability issues. There is a third scenario where the virtual guests run the cluster stack and join the same network as the baremetal nodes, but that can quickly hit issues with scalability as well. With the pacemaker_remote service we have a new option. * The baremetal cluster-nodes run the cluster stack (paceamaker+corosync). * The virtual remote-nodes run the pacemaker_remote service (nearly zero configuration required on the virtual machine side) * The cluster stack on the cluster-nodes launch the virtual machines and immediately connect to the pacemaker_remote service, allowing the virtual machines to integrate into the cluster just as if they were a real cluster-node. The key difference here between the virtual machine remote-nodes and the cluster-nodes is that the remote-nodes are not running the cluster stack. This means the remote nodes will never become the DC, and they do not take place in quorum. On the hand this also means that the remote-nodes are not bound to the scalability limits associated with the cluster stack either. +No 16 node corosync member limits+ to deal with. That isn't to say remote-nodes can scale indefinitely, but the expectation is that remote-nodes scale horizontally much further than cluster-nodes. Other than the quorum limitation, these remote-nodes behave just like cluster nodes in respects to resource management. The cluster is fully capable of managing and monitoring resources on each remote-node. You can build constraints against remote-nodes, put them in standby, or whatever else you'd expect to be able to do with normal cluster-nodes. They even show up in the crm_mon output as you would expect cluster-nodes to. To solidify the concept, an example cluster deployment integrating remote-nodes could look like this. * 16 cluster-nodes running corosync+pacemaker stack. * 64 pacemaker managed virtual machine resources running pacemaker_remote configured as remote-nodes. * 64 pacemaker managed webserver and database resources configured to run on the 64 remote-nodes. With this deployment you would have 64 webservers and databases running on 64 virtual machines on 16 hardware nodes all of which are managed and monitored by the same pacemaker deployment. == Linux Container Use Case == +I want to isolate and limit the system resources (cpu, memory, filesystem) a cluster resource can consume without using virtual machines.+ Using pacemaker_remote with Linux containers (libvirt-lxc) opens up some interesting possibilities for isolating resources in the cluster without the use of a hypervisor. We now have the ability to both define a contained environment with cpu and memory utilization limits and then assign resources to that contained environment all managed from within pacemaker. The LXC Walk-through section of this document outlines how pacemaker_remote can be used to bring Linux containers into the cluster as remote-nodes capable of executing resources. == Expanding the Cluster Stack == === Traditional HA Stack === image::images/pcmk-ha-cluster-stack.png["The Traditional Pacemaker Corosync HA Stack.",width="17cm",height="9cm",align="center"] === Remote-Node Enabled HA Stack === The stack grows one additional layer vertical so we can go further horizontal. image::images/pcmk-ha-remote-stack.png["Placing Pacemaker Remote into the Traditional HA Stack.",width="20cm",height="10cm",align="center"] pacemaker-master/doc/Pacemaker_Remote/en-US/Ch-KVM-Tutorial.txt000066400000000000000000000374541217637305600245540ustar00rootroot00000000000000= KVM Walk-through = +What this tutorial is:+ This tutorial is an in-depth walk-through of how to get pacemaker to manage a KVM guest instance and integrate that guest into the cluster as a remote-node. +What this tutorial is not:+ This tutorial is not a realistic deployment scenario. The steps shown here are meant to get users familiar with the concept of remote-nodes as quickly as possible. == Step 1: Setup the Host == This tutorial was created using Fedora 18 on the host and guest nodes. Anything that is capable of running libvirt and pacemaker v1.1.10 or greater will do though. An installation guide for installing Fedora 18 can be found here, http://docs.fedoraproject.org/en-US/Fedora/18/html/Installation_Guide/. Fedora 18 (or similar distro) host preparation steps. === SElinux and Firewall === In order to simply this tutorial we will disable the selinux and the firewall on the host. +WARNING:+ These actions will open a significant security threat to machines exposed to the outside world. [source,C] ---- # setenforce 0 # sed -i.bak "s/SELINUX=enforcing/SELINUX=permissive/g" /etc/selinux/config # systemctl disable iptables.service # systemctl disable ip6tables.service # rm '/etc/systemd/system/basic.target.wants/iptables.service' # rm '/etc/systemd/system/basic.target.wants/ip6tables.service' # systemctl stop iptables.service # systemctl stop ip6tables.service ---- === Install Cluster Software === [source,C] ---- # yum install -y pacemaker corosync pcs resource-agents ---- === Setup Corosync === Running the command below will attempt to detect the network address corosync should bind to. [source,C] ---- # export corosync_addr=`ip addr | grep "inet " | tail -n 1 | awk '{print $4}' | sed s/255/0/g` ---- Display and verify that address is correct [source,C] ---- # echo $corosync_addr ---- In many cases the address will be 192.168.1.0 if you are behind a standard home router. Now copy over the example corosync.conf. This code will inject your bindaddress and enable the vote quorum api which is required by pacemaker. [source,C] ---- # cp /etc/corosync/corosync.conf.example /etc/corosync/corosync.conf # sed -i.bak "s/.*\tbindnetaddr:.*/bindnetaddr:\ $corosync_addr/g" /etc/corosync/corosync.conf # cat << END >> /etc/corosync/corosync.conf quorum { provider: corosync_votequorum expected_votes: 2 } END ---- === Verify Cluster Software === Start the cluster [source,C] ---- # pcs cluster start ---- Verify corosync membership [source,C] ---- # pcs status corosync Membership information Nodeid Votes Name 1795270848 1 example-host (local) ---- Verify pacemaker status. At first the 'pcs cluster status' output will look like this. [source,C] ---- # pcs status Last updated: Thu Mar 14 12:26:00 2013 Last change: Thu Mar 14 12:25:55 2013 via crmd on example-host Stack: corosync Current DC: Version: 1.1.10 1 Nodes configured, unknown expected votes 0 Resources configured. ---- After about a minute you should see your host as a single node in the cluster. [source,C] ---- # pcs status Last updated: Thu Mar 14 12:28:23 2013 Last change: Thu Mar 14 12:25:55 2013 via crmd on example-host Stack: corosync Current DC: example-host (1795270848) - partition WITHOUT quorum Version: 1.1.8-9b13ea1 1 Nodes configured, unknown expected votes 0 Resources configured. Online: [ example-host ] ---- Go ahead and stop the cluster for now after verifying everything is in order. [source,C] ---- # pcs cluster stop ---- === Install Virtualization Software === [source,C] ---- # yum install -y kvm libvirt qemu-system qemu-kvm bridge-utils virt-manager # systemctl enable libvirtd.service ---- reboot the host == Step2: Create the KVM guest == I am not going to outline the installation steps required to create a kvm guest. There are plenty of tutorials available elsewhere that do that. I recommend using a Fedora 18 or greater distro as your guest as that is what I am testing this tutorial with. === Setup Guest Network === Run the commands below to set up a static ip address (192.168.122.10) and hostname (guest1). [source,C] ---- export remote_hostname=guest1 export remote_ip=192.168.122.10 export remote_gateway=192.168.122.1 yum remove -y NetworkManager rm -f /etc/hostname cat << END >> /etc/hostname $remote_hostname END hostname $remote_hostname cat << END >> /etc/sysconfig/network HOSTNAME=$remote_hostname GATEWAY=$remote_gateway END sed -i.bak "s/.*BOOTPROTO=.*/BOOTPROTO=none/g" /etc/sysconfig/network-scripts/ifcfg-eth0 cat << END >> /etc/sysconfig/network-scripts/ifcfg-eth0 IPADDR0=$remote_ip PREFIX0=24 GATEWAY0=$remote_gateway DNS1=$remote_gateway END systemctl restart network systemctl enable network.service systemctl enable sshd systemctl start sshd echo "checking connectivity" ping www.google.com ---- To simplify the tutorial we'll go ahead and disable selinux on the guest. We'll also need to poke a hole through the firewall on port 3121 (the default port for pacemaker_remote) so the host can contact the guest. [source,C] ---- # setenforce 0 # sed -i.bak "s/SELINUX=enforcing/SELINUX=permissive/g" /etc/selinux/config # firewall-cmd --add-port 3121/tcp --permanent ---- If you still encounter connection issues just disable iptables and ipv6tables on the guest like we did on the host to guarantee you'll be able to contact the guest from the host. At this point you should be able to ssh into the guest from the host. === Setup Pacemaker Remote === On the +HOST+ machine run these commands to generate an authkey and copy it to the /etc/pacemaker folder on both the host and guest. [source,C] ---- # mkdir /etc/pacemaker # dd if=/dev/urandom of=/etc/pacemaker/authkey bs=4096 count=1 # scp -r /etc/pacemaker root@192.168.122.10:/etc/ ---- Now on the +GUEST+ install pacemaker-remote package and enable the daemon to run at startup. In the commands below you will notice the 'pacemaker' and 'pacemaker_remote' packages are being installed. The 'pacemaker' package is not required. The only reason it is being installed for this tutorial is because it contains the a 'Dummy' resource agent we will be using later on to test the remote-node. [source,C] ---- # yum install -y pacemaker paceamaker-remote resource-agents # systemctl enable pacemaker_remote.service ---- Now start pacemaker_remote on the guest and verify the start was successful. [source,C] ---- # systemctl start pacemaker_remote.service # systemctl status pacemaker_remote pacemaker_remote.service - Pacemaker Remote Service Loaded: loaded (/usr/lib/systemd/system/pacemaker_remote.service; enabled) Active: active (running) since Thu 2013-03-14 18:24:04 EDT; 2min 8s ago Main PID: 1233 (pacemaker_remot) CGroup: name=systemd:/system/pacemaker_remote.service └─1233 /usr/sbin/pacemaker_remoted Mar 14 18:24:04 guest1 systemd[1]: Starting Pacemaker Remote Service... Mar 14 18:24:04 guest1 systemd[1]: Started Pacemaker Remote Service. Mar 14 18:24:04 guest1 pacemaker_remoted[1233]: notice: lrmd_init_remote_tls_server: Starting a tls listener on port 3121. ---- === Verify Host Connection to Guest === Before moving forward it's worth going ahead and verifying the host can contact the guest on port 3121. Here's a trick you can use. Connect using telnet from the host. The connection will get destroyed, but how it is destroyed tells you whether it worked or not. First add guest1 to the host machine's /etc/hosts file if you haven't already. This is required unless you have dns setup in a way where guest1's address can be discovered. [source,C] ---- # cat << END >> /etc/hosts 192.168.122.10 guest1 END ---- If running the telnet command on the host results in this output before disconnecting, the connection works. [source,C] ---- # telnet guest1 3121 Trying 192.168.122.10... Connected to guest1. Escape character is '^]'. Connection closed by foreign host. ---- If you see this, the connection is not working. [source,C] ---- # telnet guest1 3121 Trying 192.168.122.10... telnet: connect to address 192.168.122.10: No route to host ---- Once you can successfully connect to the guest from the host, shutdown the guest. Pacemaker will be managing the virtual machine from this point forward. == Step3: Integrate KVM guest into Cluster. == Now the fun part, integrating the virtual machine you've just created into the cluster. It is incredibly simple. === Start the Cluster === On the host, start pacemaker. [source,C] ---- # pcs cluster start ---- Wait for the host to become the DC. The output of 'pcs status' should look similar to this after about a minute. [source,C] ---- Last updated: Thu Mar 14 16:41:22 2013 Last change: Thu Mar 14 16:41:08 2013 via crmd on example-host Stack: corosync Current DC: example-host (1795270848) - partition WITHOUT quorum Version: 1.1.10 1 Nodes configured, unknown expected votes 0 Resources configured. Online: [ example-host ] ---- Now enable the cluster to work without quorum or stonith. This is required just for the sake of getting this tutorial to work with a single cluster-node. [source,C] ---- # pcs property set stonith-enabled=false # pcs property set no-quorum-policy=ignore ---- === Integrate KVM Guest as remote-node === If you didn't already do this earlier in the verify host to guest connection section, add the KVM guest's ip to the host's /etc/hosts file so we can connect by hostname. The command below will do that if you used the same ip address I used earlier. [source,C] ---- # cat << END >> /etc/hosts 192.168.122.10 guest1 END ---- We will use the +VirtualDomain+ resource agent for the management of the virtual machine. This agent requires the virtual machine's xml config to be dumped to a file on disk. To do this pick out the name of the virtual machine you just created from the output of this list. [source,C] ---- # virsh list --all Id Name State ______________________________________________ - guest1 shut off ---- In my case I named it guest1. Dump the xml to a file somewhere on the host using the following command. [source,C] ---- # virsh dumpxml guest1 > /root/guest1.xml ---- Now just register the resource with pacemaker and you're set! [source,C] ---- # pcs resource create vm-guest1 VirtualDomain hypervisor="qemu:///system" config="/root/guest1.xml" meta remote-node=guest1 ---- Once the 'vm-guest1' resource is started you will see 'guest1' appear in the 'pcs status' output as a node. The final 'pcs status' output should look something like this. [source,C] ---- Last updated: Fri Mar 15 09:30:30 2013 Last change: Thu Mar 14 17:21:35 2013 via cibadmin on example-host Stack: corosync Current DC: example-host (1795270848) - partition WITHOUT quorum Version: 1.1.10 2 Nodes configured, unknown expected votes 2 Resources configured. Online: [ example-host guest1 ] Full list of resources: vm-guest1 (ocf::heartbeat:VirtualDomain): Started example-host ---- === Starting Resources on KVM Guest === The commands below demonstrate how resources can be executed on both the remote-node and the cluster-node. Create a few Dummy resources. Dummy resources are real resource agents used just for testing purposes. They actually execute on the host they are assigned to just like an apache server or database would, except their execution just means a file was created. When the resource is stopped, that the file it created is removed. [source,C] ---- # pcs resource create FAKE1 ocf:pacemaker:Dummy # pcs resource create FAKE2 ocf:pacemaker:Dummy # pcs resource create FAKE3 ocf:pacemaker:Dummy # pcs resource create FAKE4 ocf:pacemaker:Dummy # pcs resource create FAKE5 ocf:pacemaker:Dummy ---- Now check your 'pcs status' output. In the resource section you should see something like the following, where some of the resources got started on the cluster-node, and some started on the remote-node. [source,C] ---- Full list of resources: vm-guest1 (ocf::heartbeat:VirtualDomain): Started example-host FAKE1 (ocf::pacemaker:Dummy): Started guest1 FAKE2 (ocf::pacemaker:Dummy): Started guest1 FAKE3 (ocf::pacemaker:Dummy): Started example-host FAKE4 (ocf::pacemaker:Dummy): Started guest1 FAKE5 (ocf::pacemaker:Dummy): Started example-host ---- The remote-node, 'guest1', reacts just like any other node in the cluster. For example, pick out a resource that is running on your cluster-node. For my purposes I am picking FAKE3 from the output above. We can force FAKE3 to run on 'guest1' in the exact same way we would any other node. [source,C] ---- # pcs constraint FAKE3 prefers guest1 ---- Now looking at the bottom of the 'pcs status' output you'll see FAKE3 is on 'guest1'. [source,C] ---- Full list of resources: vm-guest1 (ocf::heartbeat:VirtualDomain): Started example-host FAKE1 (ocf::pacemaker:Dummy): Started guest1 FAKE2 (ocf::pacemaker:Dummy): Started guest1 FAKE3 (ocf::pacemaker:Dummy): Started guest1 FAKE4 (ocf::pacemaker:Dummy): Started example-host FAKE5 (ocf::pacemaker:Dummy): Started example-host ---- === Testing Remote-node Recovery and Fencing === Pacemaker's policy engine is smart enough to know fencing remote-nodes associated with a virtual machine means shutting off/rebooting the virtual machine. No special configuration is necessary to make this happen. If you are interested in testing this functionality out, trying stopping the guest's pacemaker_remote daemon. This would be equivalent of abruptly terminating a cluster-node's corosync membership without properly shutting it down. ssh into the guest and run this command. [source,C] ---- # kill -9 `pidof pacemaker_remoted` ---- After a few seconds or so you'll see this in your 'pcs status' output. The 'guest1' node will be show as offline as it is being recovered. [source,C] ---- Last updated: Fri Mar 15 11:00:31 2013 Last change: Fri Mar 15 09:54:16 2013 via cibadmin on example-host Stack: corosync Current DC: example-host (1795270848) - partition WITHOUT quorum Version: 1.1.10 2 Nodes configured, unknown expected votes 7 Resources configured. Online: [ example-host ] OFFLINE: [ guest1 ] Full list of resources: vm-guest1 (ocf::heartbeat:VirtualDomain): Started example-host FAKE1 (ocf::pacemaker:Dummy): Stopped FAKE2 (ocf::pacemaker:Dummy): Stopped FAKE3 (ocf::pacemaker:Dummy): Stopped FAKE4 (ocf::pacemaker:Dummy): Started example-host FAKE5 (ocf::pacemaker:Dummy): Started example-host Failed actions: guest1_monitor_30000 (node=example-host, call=3, rc=7, status=complete): not running ---- Once recovery of the guest is complete, you'll see it automatically get re-integrated into the cluster. The final 'pcs status' output should look something like this. [source,C] ---- Last updated: Fri Mar 15 11:03:17 2013 Last change: Fri Mar 15 09:54:16 2013 via cibadmin on example-host Stack: corosync Current DC: example-host (1795270848) - partition WITHOUT quorum Version: 1.1.10 2 Nodes configured, unknown expected votes 7 Resources configured. Online: [ example-host guest1 ] Full list of resources: vm-guest1 (ocf::heartbeat:VirtualDomain): Started example-host FAKE1 (ocf::pacemaker:Dummy): Started guest1 FAKE2 (ocf::pacemaker:Dummy): Started guest1 FAKE3 (ocf::pacemaker:Dummy): Started guest1 FAKE4 (ocf::pacemaker:Dummy): Started example-host FAKE5 (ocf::pacemaker:Dummy): Started example-host Failed actions: guest1_monitor_30000 (node=example-host, call=3, rc=7, status=complete): not running ---- === Accessing Cluster Tools from Remote-node === Besides just allowing the cluster to manage resources on a remote-node, pacemaker_remote has one other trick. +The pacemaker_remote daemon allows nearly all the pacemaker tools (crm_resource, crm_mon, crm_attribute, crm_master) to work on remote nodes natively.+ Try it, run +crm_mon+ or +pcs status+ on the guest after pacemaker has integrated the remote-node into the cluster. These tools just work. These means resource agents such as master/slave resources which need access to tools like crm_master work seamlessly on the remote-nodes. pacemaker-master/doc/Pacemaker_Remote/en-US/Ch-LXC-Tutorial.txt000066400000000000000000000270721217637305600245400ustar00rootroot00000000000000= Linux Container (LXC) Walk-through = +What this tutorial is:+ This tutorial demonstrates how pacemaker_remote can be used with Linux containers (managed by libvirt-lxc) to run cluster resources in an isolated environment. +What this tutorial is not:+ This tutorial is not a realistic deployment scenario. The steps shown here are meant to introduce users to the concept of managing Linux container environments with Pacemaker. == Step 1: Setup LXC Host == This tutorial was tested with Fedora 18. Anything that is capable of running libvirt and pacemaker v1.1.10 or greater will do though. An installation guide for installing Fedora 18 can be found here, http://docs.fedoraproject.org/en-US/Fedora/18/html/Installation_Guide/. Fedora 18 (or similar distro) host preparation steps. === SElinux and Firewall Rules === In order to simply this tutorial we will disable the selinux and the firewall on the host. WARNING: These actions pose a significant security issues to machines exposed to the outside world. Basically, just don't do this on your production system. [source,C] ---- # setenforce 0 # sed -i.bak "s/SELINUX=enforcing/SELINUX=permissive/g" /etc/selinux/config # firewall-cmd --add-port 3121/tcp --permanent # systemctl disable iptables.service # systemctl disable ip6tables.service # rm '/etc/systemd/system/basic.target.wants/iptables.service' # rm '/etc/systemd/system/basic.target.wants/ip6tables.service' # systemctl stop iptables.service # systemctl stop ip6tables.service ---- === Install Cluster Software on Host === [source,C] ---- # yum install -y pacemaker pacemaker-remote corosync pcs resource-agents ---- === Configure Corosync === Running the command below will attempt to detect the network address corosync should bind to. [source,C] ---- # export corosync_addr=`ip addr | grep "inet " | tail -n 1 | awk '{print $4}' | sed s/255/0/g` ---- Display and verify the address is correct [source,C] ---- # echo $corosync_addr ---- In most cases the address will be 192.168.1.0 if you are behind a standard home router. Now copy over the example corosync.conf. This code will inject your bindaddress and enable the vote quorum api which is required by pacemaker. [source,C] ---- # cp /etc/corosync/corosync.conf.example /etc/corosync/corosync.conf # sed -i.bak "s/.*\tbindnetaddr:.*/bindnetaddr:\ $corosync_addr/g" /etc/corosync/corosync.conf # cat << END >> /etc/corosync/corosync.conf quorum { provider: corosync_votequorum expected_votes: 2 } END ---- === Verify Cluster === Start the cluster [source,C] ---- # pcs cluster start ---- Verify corosync membership [source,C] ---- # pcs status corosync Membership information Nodeid Votes Name 1795270848 1 example-host (local) ---- Verify pacemaker status. At first the 'pcs cluster status' output will look like this. [source,C] ---- # pcs status Last updated: Thu Mar 14 12:26:00 2013 Last change: Thu Mar 14 12:25:55 2013 via crmd on example-host Stack: corosync Current DC: Version: 1.1.10 1 Nodes configured, unknown expected votes 0 Resources configured. ---- After about a minute you should see your host as a single node in the cluster. [source,C] ---- # pcs status Last updated: Thu Mar 14 12:28:23 2013 Last change: Thu Mar 14 12:25:55 2013 via crmd on example-host Stack: corosync Current DC: example-host (1795270848) - partition WITHOUT quorum Version: 1.1.8-9b13ea1 1 Nodes configured, unknown expected votes 0 Resources configured. Online: [ example-host ] ---- Go ahead and stop the cluster for now after verifying everything is in order. [source,C] ---- # pcs cluster stop ---- == Step 2: Setup LXC Environment == === Install Libvirt LXC software === [source,C] ---- # yum install -y libvirt libvirt-daemon-lxc wget # systemctl enable libvirtd ---- At this point, restart the host. === Generate Libvirt LXC domains === I've attempted to simply this tutorial by creating a script to auto generate the libvirt-lxc xml domain definitions. Download the script to whatever directory you want the containers to live in. In this example I am using the /root/lxc/ directory. [source,C] ---- # mkdir /root/lxc/ # cd /root/lxc/ # wget https://raw.github.com/davidvossel/pcmk-lxc-autogen/master/lxc-autogen # chmod 755 lxc-autogen ---- Now execute the script. [source,C] ---- # ./lxc-autogen ---- After executing the script you will see a bunch of directories and xml files are generated. Those xml files are the libvirt-lxc domain definitions, and the directories are used as some special mount points for each container. If you open up one of the xml files you'll be able to see how the cpu, memory, and filesystem resources for the container are defined. You can use the libvirt-lxc driver's documentation found here, http://libvirt.org/drvlxc.html, as a reference to help understand all the parts of the xml file. The lxc-autogen script is not complicated and is worth exploring in order to grasp how the environment is generated. It is worth noting that this environment is dependent on use of libvirt's default network interface. Verify the commands below look the same as your environment. The default network address 192.168.122.1 should have been generated by automatically when you installed the virtualization software. [source,C] ---- # virsh net-list Name State Autostart Persistent ________________________________________________________ default active yes yes # virsh net-dumpxml default | grep -e "ip address=" ---- === Generate the Authkey === Generate the authkey used to secure connections between the host and the lxc guest pacemaker_remote instances. This is sort of a funny case because the lxc guests and the host will share the same key file in the /etc/pacemaker/ directory. If in a different deployment where the lxc guests do not share the host's /etc/pacemaker directory, this key will have to be copied into each lxc guest. [source,C] ---- # dd if=/dev/urandom of=/etc/pacemaker/authkey bs=4096 count=1 ---- == Step 3: Integrate LXC guests into Cluster. == === Start Cluster === On the host, start pacemaker. [source,C] ---- # pcs cluster start ---- Wait for the host to become the DC. The output of 'pcs status' should look similar to this after about a minute. [source,C] ---- Last updated: Thu Mar 14 16:41:22 2013 Last change: Thu Mar 14 16:41:08 2013 via crmd on example-host Stack: corosync Current DC: example-host (1795270848) - partition WITHOUT quorum Version: 1.1.10 1 Nodes configured, unknown expected votes 0 Resources configured. Online: [ example-host ] ---- Now enable the cluster to work without quorum or stonith. This is required just for the sake of getting this tutorial to work with a single cluster-node. [source,C] ---- # pcs property set stonith-enabled=false # pcs property set no-quorum-policy=ignore ---- === Integrate LXC Guests as remote-nodes === If you ran the 'lxc-autogen' script with default parameters, 3 lxc domain definitions were created as .xml files. If you used the same directory I used for the lxc environment, the config files will be located in /root/lxc. Replace the 'config' parameters in the following pcs commands if yours should be different. The pcs commands below each configure a lxc guest as a remote-node in pacemaker. Behind the scenes each lxc guest is launching an instance of pacemaker_remote allowing pacemaker to integrate the lxc guests as remote-nodes. The meta-attribute 'remote-node=' used in each command is what tells pacemaker that the lxc guest is both a resource and a remote-node capable of running resources. In this case, the 'remote-node' attribute also indicates to pacemaker that it can contact each lxc's pacemaker_remote service by using the remote-node name as the hostname. If you look in the /etc/hosts/ file you will see entries for each lxc guest. These entries were auto-generated earlier by the 'lxc-autogen' script. [source,C] ---- # pcs resource create container1 VirtualDomain force_stop="true" hypervisor="lxc:///" config="/root/lxc/lxc1.xml" meta remote-node=lxc1 # pcs resource create container2 VirtualDomain force_stop="true" hypervisor="lxc:///" config="/root/lxc/lxc2.xml" meta remote-node=lxc2 # pcs resource create container3 VirtualDomain force_stop="true" hypervisor="lxc:///" config="/root/lxc/lxc3.xml" meta remote-node=lxc3 ---- After creating the container resources you 'pcs status' should look like this. [source,C] ---- Last updated: Mon Mar 18 17:15:46 2013 Last change: Mon Mar 18 17:15:26 2013 via cibadmin on guest1 Stack: corosync Current DC: example-host (175810752) - partition WITHOUT quorum Version: 1.1.10 4 Nodes configured, unknown expected votes 6 Resources configured. Online: [ example-host lxc1 lxc2 lxc3 ] Full list of resources: container3 (ocf::heartbeat:VirtualDomain): Started example-host container1 (ocf::heartbeat:VirtualDomain): Started example-host container2 (ocf::heartbeat:VirtualDomain): Started example-host ---- === Starting Resources on LXC Guests === Now that the lxc guests are integrated into the cluster, lets generate some Dummy resources to run on them. Dummy resources are real resource agents used just for testing purposes. They actually execute on the node they are assigned to just like an apache server or database would, except their execution just means a file was created. When the resource is stopped, that the file it created is removed. [source,C] ---- # pcs resource create FAKE1 ocf:pacemaker:Dummy # pcs resource create FAKE2 ocf:pacemaker:Dummy # pcs resource create FAKE3 ocf:pacemaker:Dummy # pcs resource create FAKE4 ocf:pacemaker:Dummy # pcs resource create FAKE5 ocf:pacemaker:Dummy ---- After creating the Dummy resources you will see that the resource got distributed among all the nodes. The 'pcs status' output should look similar to this. [source,C] ---- Last updated: Mon Mar 18 17:31:54 2013 Last change: Mon Mar 18 17:31:05 2013 via cibadmin on example-host Stack: corosync Current DC: example=host (175810752) - partition WITHOUT quorum Version: 1.1.10 4 Nodes configured, unknown expected votes 11 Resources configured. Online: [ example-host lxc1 lxc2 lxc3 ] Full list of resources: container3 (ocf::heartbeat:VirtualDomain): Started example-host container1 (ocf::heartbeat:VirtualDomain): Started example-host container2 (ocf::heartbeat:VirtualDomain): Started example-host FAKE1 (ocf::pacemaker:Dummy): Started lxc1 FAKE2 (ocf::pacemaker:Dummy): Started lxc2 FAKE3 (ocf::pacemaker:Dummy): Started lxc3 FAKE4 (ocf::pacemaker:Dummy): Started lxc1 FAKE5 (ocf::pacemaker:Dummy): Started lxc2 ---- To witness that Dummy agents are running within the lxc guests browse one of the lxc domain's filesystem folders. Each lxc guest has a custom mount point for the '/var/run/'directory, which is the location the Dummy resources write their state files to. [source,C] ---- # ls lxc1-filesystem/var/run/ Dummy-FAKE4.state Dummy-FAKE.state ---- If you are curious, take a look at lxc1.xml to see how the filesystem is mounted. === Testing LXC Guest Failure === You will be able to see each pacemaker_remoted process running in each lxc guest from the host machine. [source,C] ---- # ps -A | grep -e pacemaker_remote* 9142 pts/2 00:00:00 pacemaker_remot 10148 pts/4 00:00:00 pacemaker_remot 10942 pts/6 00:00:00 pacemaker_remot ---- In order to see how the cluster reacts to a failed lxc guest. Try killing one of the pacemaker_remote instances. [source,C] ---- # kill -9 9142 ---- After a few moments the lxc guest that was running that instance of pacemaker_remote will be recovered along with all the resources running within that container. pacemaker-master/doc/Pacemaker_Remote/en-US/Ch-Options.txt000066400000000000000000000045611217637305600237420ustar00rootroot00000000000000= Configuration Explained = The walk-through examples use some of these options, but don't explain exactly what they mean or do. This section is meant to be the go-to resource for all the options available for configuring remote-nodes. == Resource Options == When configuring a virtual machine or lxc resource to act as a remote-node, these are the metadata options available to both enable the resource as a remote-node and define the connection parameters. .Metadata Options for configuring KVM/LXC resources as remote-nodes [width="95%",cols="1m,1,4<",options="header",align="center"] |========================================================= |Option |Default |Description |+remote-node+ | |The name of the remote-node this resource defines. This both enables the resource as a remote-node and defines the unique name used to identify the remote-node. If no other parameters are set, this value will also be assumed as the hostname to connect to at port 3121. +WARNING+ This value cannot overlap with any resource or node IDs. |+remote-port+ |3121 |Configure a custom port to use for the guest connection to pacemaker_remote. |+remote-addr+ |+remote-node+ value used as hostname |The ip address or hostname to connect to if remote-node's name is not the hostname of the guest. |+remote-connect-timeout+ |60s |How long before a pending guest connection will time out. |========================================================= == Host and Guest Authentication == Authentication and encryption of the connection between cluster-nodes (pacemaker) to remote-nodes (pacemaker_remote) is achieved using TLS with PSK encryption/authentication on +tcp port 3121+. This means both the cluster-node and remote-node must share the same private key. By default this +key must be placed at "/etc/pacemaker/authkey" on both cluster-nodes and remote-nodes+. == Pacemaker and pacemaker_remote Options == If you need to change the default port or authkey location for either pacemaker or pacemaker_remote, there are environment variables you can set that affect both of those daemons. These environment variables can be enabled by placing them in the /etc/sysconfig/pacemaker file. [source,C] ---- #==#==# Pacemaker Remote # Use a custom directory for finding the authkey. PCMK_authkey_location=/etc/pacemaker/authkey # # Specify a custom port for Pacemaker Remote connections PCMK_remote_port=3121 ---- pacemaker-master/doc/Pacemaker_Remote/en-US/Pacemaker_Remote.ent000066400000000000000000000002671217637305600251300ustar00rootroot00000000000000 pacemaker-master/doc/Pacemaker_Remote/en-US/Pacemaker_Remote.xml000066400000000000000000000016751217637305600251460ustar00rootroot00000000000000 %BOOK_ENTITIES; ]> pacemaker-master/doc/Pacemaker_Remote/en-US/Revision_History.xml000066400000000000000000000017641217637305600252610ustar00rootroot00000000000000 %BOOK_ENTITIES; ]> Revision History 1-0 Tue Mar 19 2013 DavidVosseldvossel@redhat.com Import from Pages.app 2-0 Tue May 13 2013 DavidVosseldvossel@redhat.com Added Future Features Section pacemaker-master/doc/Pacemaker_Remote/en-US/images/000077500000000000000000000000001217637305600224555ustar00rootroot00000000000000pacemaker-master/doc/Pacemaker_Remote/en-US/images/pcmk-ha-cluster-stack.png000066400000000000000000001025501217637305600272700ustar00rootroot00000000000000PNG  IHDRmM* pHYs+IDATx]w\TG^P{7((X D.V${Â{nXP1K K56 |ϷͼƲwsΝ9s̝;=%%Em A5xO>Uy һ2^MyfQ~;v(QBf]S5ҥה)SZl)M%55{III֫HC#6K45?OS^ZF c%۫.VXLL̳gϴ'ڴiw ,EEOSq_=忮Y3l WhTCZiUTI6ЦPn]Ak+T5{zڙJ|ի3j(Ir5ڥ? * ?u.8wߡdʏ(-[iӦٝ?AR{q$2 p`` .h'r$ʁUŋ]ڶknΜ9kxxׯu|2a۶msvvQp dJWng*L7ϟ߽{AAA[9s&y!,n[I935f̘۷ݼys N< 3dm +i7oFS1k׮{!/zРAX{V^{&x;1b :*THd&mrAˠ0Ej:AIllŋSRR`Ϝ9ʋdž % &O<r"%M$K`g!IeRӧO߽{q#Յb`SfT+IfϞlW[%A]<C L" d MA$=:u űc~XaaWyʑv#hݩvk)SвqJkNC3#c0]aYڒTWm޽keeվ} . .S |}}m#t,})jCSΦ*sJISh͛!ډh'nP;A=i8cZLFf!doh57[f|m2ٍ2ɚ.e˂qF޼yUٳg'%*dʕ|EGGӇiTص7nؤI,zzNY2$$JWpD ]UwjcLjGԩlZ}||/_WdEb1,Nt#,M\y \tI5_CgÆ ܩ\SکF?-N}9mtD08BSN& `ӦMރT۷շeZ[[Y&kb+vvv\IǸ:RUeݩPzTNBG}Ik3ԣ=zm۶'ONΆOO~͌!?}I&t 5W{tBW4z:)s-Ob~6mz PBgΜپ}֭[qɓ'%K-sss矵kf ߶m[Ν^*].坧'xtmn>i|HHH_sΉ>+W.8{qpp)ݯG+"[Qud ͛ġGR*GZ4M$~~٢E l~u4nz>`$/jժ]~=o޼ڵ4hݻ^zݼyS:Ytn_t %~Pmh `薥e@_t雎~ѯ2˗/1zA^ntI&#i~EL~:/00qwwG==<<-CCC`#1Dj˛1~[SL)ʤ[={ѽ{QFҸv)Tښڲe R bM4` ]vJ-& "/N\ojHa =2խ9UA5>1E˖-uNzFR1HIEx.M}J>ސPiaaabMLLjEVfpI=vEet~׭[uVk~D+|pIisZͯX*֟*ʊ#W4e˖V1ߛ5kr ,رc'g~i~ϝ;'9sC%ܯz@\ǎѱcGzph!Cp t eca.\8h 8$N:uދ/icY$.X~gƌ߿3gmEwޭP}5nܸ'O8qBkYoF);vPC?B<6lةSh9hq(A#&IIIG7o:5.@4|E_-,,}LqjE@XJF"iِ"֤tUΜ9QĜn~i7RB򡚭,Z...2^יvPjk- P_땪\à qdѯBd zϞ= Q} [niTcl+#[H˗O"G>V>iΝ:t?~0@OBy;w.dk֭ trrj׮OdVw DQFJڴiǷI+E[lYʕ+k֬I\#JK.UYNzBCC߼yӧO: 5Ls0 9Һu(IҲMbQ,ґڵk9jWkb$z%Ed< d=YnB6R%h`jjZRxJT'Ok9%:e˖I&'0V_q}fu dzTt.Ғ(ѣ ht_Â&QS/X :/~#zT+W.,@Vzq25g)오:{3tB]SՍ~0BF lM(w=qB 㙱!;fFO2 Gݒ0rY܊+M6p@Y2s9))TR7NTQthYB֭INܦ'Oѣlj'@Ǔ\7d9-...z;ėZ]֯_`~ŋϙ3-[h߆={ܹƘTK_Ϛ5kٲe}|| 1$ԻjՊ޸qc-ʗ/?hР!CϟÆ ȏ}2ڵ %27/S Tݻww@@/_>C@G5QaDOeu~E| DQvQhevSНt~w}=UBSSEA(?4pȟIlAϜ9j@6iҤgϞb2bŊsn׮,11C2B/G.lGzb0tPd@+UL#ﶶaaavvvܹs!OUTy&njCxu+73m֭III!!!qqq͚58W\Bk[n iKHH@ɴاLuի2PQݻˌseA{fUFH )S3|8R C"Nqo߾w)RnGV7Fښ IBh 2Tre~Mkwռ.Y鉑1F#1\[πY:u*G֥e˖aLC >aŊՙ08BG GΙJd"P0=EUUËu9ÐciV}>g `=|ݖ3:`Vŋ&L9s`d76nܸdɒc&8l޼_~[lqwwq2"#Zйsg'''N:lRos)ϢիWn9"""^|))Э[7"LBJ96jѣ/jwjx9?ݾ}{.]?G:UhZ+C; ,ֵEiyͅǔ 111og;vZmAaܹsU֧O|a%͈#8[:.x1޽ 0m۶U>& #9V>[ i˴KVGiM]̍u( E46l@V w_YXb]__\r!kkGȑ#!!2zb:F-=3 Y:@%iL>c)j,cqGmzJ_mtO<9j(NN7klȑ=z?6wRѴoرc,NV Q2Dsj=vO޽{wz0yi:w:uٳ>}BTa=(9s\x1}TvL N/<;w[j9s&oƌ߿Gx}Hy{{r[:'Nhy7i$3::`TxSm޼ySzusذaC%1VH{,XpAWWLuÇGp 0`Ud/˗/?tPDFYSYfaXy@>^&_hnntRSSSuٲeҩ;A}OΟ?'b]HAΞ=[Z[k׮Q (߹sfffNMVH" Ν#V&_H-Zd^;qD .BϸuǏ!ṕQQ4kB3 RJpO'O~* Q[> [ժUmll``3,3MS4􍰺=.SH)p yZɑo`NL &P^Z[J[#PnMKgp3 t^fv$OEk)O_Hƒ -f2!ԯ$!"NcB˜wziZ0)_~'OL[it͛7qԩm۶-ZHfDu qk@VW;A~zժUHQF^J.λv0gxw>yb1. u9)׬Y驡3 qqq4S:~xJ={6  !3mMVdɒǎC޽ SNrr2u:K.-k֬ ʕ Ct~&ri% ci&w )0][lپ}իW~Meiw133sssuW^q%z< ׯ_۷e'/NӧO3:lذaӦMoFdUlY77~)}ڴ+Jc-ebnzSʟ={u~9$$dB' RFzѥKb TǏI]S}PB!vZm?kРLLL)C߾} ?zGTϝ;wIVׯkjsh(O]|رcNNNꞂڜzڵk#>1ct޽t&''wرQFӦMb'OG>}Ըq[nΝ[]0x;vܹ = tURV?- pCCYrHS!.۶mSxjTi㬥 k)`-e0XK k)(-`B6QѤG`B޽+Vr L0D —طoʰ1cHG2҄6mxyyIVS2ƪ,4x| iբEj5k}ԭ[ʼn'DR6l fϞc:k˗/2D\0JJ+k珈~^xVZ߿'u۶m+\Hk![lzxPWUTTTŊܹYtupk /` ZhѡC'CbbbRR :MΜ9#∗#^4ի'΄4ֈWu"ϴe((GDmڴ ݼ#,xMLZ!xȬ0mY>}tڴi/_.WHZp-DbjnѢED7hMQJq{A4!CH:!T`A˗/ ҥجȀxaa;tv5lwhblh2ZtY\_C8tN`ϟ?WxXg[n# u'n֬LM)T?I.]JJC;JuN9ťBBuJ'05g3'脄r${*4-&&QH 4L$-Q^3WW>DEqīc۲eK0:8TE%J.!1>>>DLhOH07Ch)Gt%2.\r3YLKyCT&x0Hŋ23=M~hϩLhIМr%Zxy?ެ{|U dRU zAahhhlٲQ\Q6Nu666&M2n񪆯n~m.]mӧOJ433۱cݻwZcǎ͐]\\)s͚5 ~gggg*Օ򙘘'nݺ e8ie[, Pmҿg*8z耀~~~SLba]bbL?8:/W\|}}Ӡ *ԭ[Gyϔ *VX-͞=;TXh&Bb ȆAX 3M0BΝ;UK>ԬYS0g…fͺ~BBÑjAumCbd]9r9:xR%<>\dܹsϪ}nܸQJYf)MP J p >|Y&8҂###e===;hhʕ׮]C֥K5jׯ#{%b:wwjժ}C/Z>jjРA}%b!C enzƍ*TOg:yfذa!!!8>e,/ sέ_>W˗S%K@n*WLbcc+\ .yիSRRz fVX!1@MLLF!f1>}zRRR͛w}<.c쌎Hrva|B9ȆAP4U[_3bcǎ-YǙ3g.^[n( <~f]Eow]H4 1eS񞝺zC`ׯ_ߦMŋV׮] 6}TCYaM Cx!MqssꛔD8uT8iӦAHࢢĢd[ ) CdCcJMZ*GCxiRQuMʼ{58FشiS#2@!|haaѸqcɓMs* ,}vfȘyċ CI^7o^///J(<[N8Vҥ1jSqAK5xLet h2`0rH~1$àC)-J =r*+3GAǔy+o۩s'={vutf- k5uHLxK'ĨkUcGb$HWЁ0>CBۈqc FPQK1tRm9 &b"7..qdd$L0DZ11 ׯ_,X M~b_Og"Ux&'2}?^"۶mۂ=z3gڵkףG[ )>>>yuɓ'Ν;:x={"[HHȨQPEP-[ݻw/f>j:~8-+ӧsΕ+Wbb `ӧܹ˗&&&={(.LӫU KؠaÆ~PO)g&%Ug֙?,YeUV.s#^e]=<|8Zڷo~Q :{I-MC=#"")))R^*kҒYf_kԹàRg{Q2A]fM{ +?MKgTK  CGؠnj}E}K+Q ݄4K+9# A߹sg墪#FRwIe5@0m.;rL*Fp0 }׻wohn7#޿eoozj.uEj MR˼y,gj+++ I .03f̐>x"D<"-q͚5KNke)L)RFwRTXQz ܽ{K4U^d}b9ؒzN{;}xLA&    ϫWpCIIIrFR)B#?X@ͨ_>Qqܹs nw2tgΝE- @c'i7CA3sνqF9FFBBھk.~K>ƍ ՀWG ߤIYj͛7C"E򢥾E`L_C6c5yʕ+o< G;ԭQFʕ ѯBV H*0j(fen3{! 6ԕ:+.M'B+#MG$PWƱ4'@@*ךS!MYreu2hBҧWib~zmxpt[m}9sF#^r-c#xìӈ\ 7xi ȬEj izEв-nDFFr7~L0uT|)_H=eN1|.ӰWL0Ե`g C󳰰`F0zunjü`0<e0;e0 U(^8O>en4euCԮ]{߾}˳gٍ̙?TR"áC* "##_r>Kh>9/_L#F`Ʋ22BǏwttԐԩ={:t(ƍ=z􈉉yA.2oYE]N>|!oF??Õ+WVڴiS+++Q!PBll( N=zԠA>\e5ʔ)gssp'3h˗ȑ* לJ*={aÆ"TIqo%RRR ,x̙SNy{{ϟ?ntt4_Šwܹ ui9OVQCc1o<"r-ON:Į]h/777Jiٲe޽7n*Uŋ'NɓIC+[[[L0A&feʔ)~~~6mRPQRuޞ*j K// xT * ݀o@TQxH t钺;F`||<'ʀuPgzXE ^|ٳgE?fD \~-[@%K|GZ+Wֲ{0XEݻwWw҅c#G``̙3.]*oW4sذaϛ7PÇ (`a\|||XEYE6vQn֭DP Mu;rH&CMw}wITڵkk"Uax1'R:D7`U&_Ϡ/kkW^߿YfϯR \ݻǏ ^yWseoyԩBEȻw]x˗/S}*0Txzz!O%TѣG^|Vݼy~~3 CBBA7V Yزlٲ *x-1d5N$&&CʷmGRRgoݺ͛3f8qz/_QT"!:,, Hx`(-{5kիͅ6:u cZEhʕ+̶tU0HoiȦm (!ለi .M%4^-U`ed(\T V(`e0XE (`e0XE (*`0XE (*`0XEoREaU`jj-[6M*lb0,--ˁ.cQo٪h{{27҄UΙ3U`/`0XE=k֬jժzRJرD9N}N8!INN6lR{>< uȑ_ ?'P|###?Q~}̠ƍ)˗/]K[[[xWD".\@#]FQs9*Vx`[n!Gw2pݺuBEg͚ժU+\,X=YEO>ayiC]dɞ={ؕ84GGG???Gi2t&L#T?>4hp̙F14Ft&jXXʹ?~_~CT*P .u҅RDO )W^y&M 0(`e0XEF*`0XEuK+J.*j07̽R={,Y$>>~Ȑ!:tЦPp<7lذ .?>M"4bĈ]̙s۶m>>>ׯ_nѢED7hƆ^ 0ĉ'Ol߾A7n-i ;w&ѣǏCCChff/_ڵkGȌӧO3ۭ[GN:uܸq[~}MMMQjr… o=X҃(رcǏe2e>}LҢE 0ݻwM6͕+ƒ`-[>\T)[[[z 4ĽK.֭ >|@vaGթSB -ٳgׯǏPݱcǞ:uJ-[#Gغu+-> b d>,X*gsww7Ա(<~8h街XV/hޡCRRRZj[pΝ솓C(`. *A WE|RdI|~nnnÇ1cF˖-^V-9̙E%k̙3M6zQx:\xqH=dcǎ`r 0 o7o  W!TTfCUO"""K.#|2R$ᒖ[QB6TQE+Jt %͟#G饥%'"bժUp V\iqHdd!j7n$QF00LgF[`(+nذQP TJ^x* WެYʇ<H 9]I[&ӳO>J$ׯ/Z(\lаcK/SR*S2Á(::: {͚5%Jݻ4n1D̜9v38:iB (K[EO8#8 hy&~޽|C`a<2.O1VXx(RWu"N E7Q?0N@&EرO 81̼qf͚GSRRqDիWcL~^B $I4rQ}fMHi8FPH/4MaV~U|pCăR{{x] -^ƒIY-efJ]t!AN1 VQͫ(/g2 VQ] <{i(^5ׯWXs4= ìc"}{i۶u:Vѯ;w+VL&0lٲ ,8vDjժӗh S7o@ʹr T:#fhCyٳgKnC|sK"ӃR8 @fѳU`lْ\g2zVL~. -QQ}g0z(Y f612 VQU`dc6 F#G*GfC>#Ȗ-[[ZZƍ?Fю?#s#H?x,`X`2 VQU`2 ͤͤIzvBCCdh!cYg:th ,`fzk+Tm۶]]͛599Y&,pϞ=GtL"e ,]4** ;vl⒘C[Wߨ_իAӇvbݫVD ]IIIf?bauǺuu:!X|!Tn۶m˗/www:u_.d"!} YO<0`"rRwtMB&*g!g9r~mPŋAA@x-[D҆WTl͞=[ٳg G UY6#۷z=VQTp5k;vs<ԷoߎߣG~~D+++RQRڒ%K*rK.A13+WC6l̙37myF9ٲeڴcǎF5 j:&<{FfnnNAq)Ͷyfh³ y4K055r ̄Z޽ =,P@yulTW˝;7I&2Nt2x`2 j L6ƍ={Lk+W©Bi +V rIv #D."%K̝;7mTWU4C`W4#G W^0"GխXJM|YfYZpppdd$Zjyzz~C*:mڴ0hΝIE pՅ ֩S)^_33zMuԈ#-Àݻ7nXsذaÇϛ7/=)) )ͻ>_N.޽ !%GPir 9Νå!3? 0'L8j C: & uQ6B"a}2ahS`߿?s/ٳg`8,___w <ٿߵd,>xh:h51gbb"zcC'L0rȸ8???.wAӺvh)`D>zT@BB"a0 .ұk޶*UR'5kk)RD&_ Fo v$;АUV"GQjUxHڰiӦ*T=XTӧO'D^ta< Ƀ@~0>*UsdW)W[ 20j~"ɗзfDAKEEg̘Ceoo/_> Zk߾P@};;;Bie/PvmC0 UGi;vڅ ǘTB#"L2ۋk׮ݻ7lV#,.Ν;]3@;9(ZBߜn*/qz|I s֥tR`$ )bŊ  1 ^€P\B0@-VXTT` pIw)v0]=p3h>}`1/]Ja@}ī/P0H*y-/O<uRYEuٳǍӧR`% pq0pʋe *kݺ@S޽DÇG{Lp˖2T ȩn1ĘhԨQh}?N9ҙKeb\rժU )18A᲎UTw _|9b;R )m1BxQi5j! PB1ԄÜ6m(& 0 B eh(؟ |]zndJ"`[XX o? uK9B,MQ0 !)flڴI/Ң]Z55 (r2sMV-W r (XE"6p*0U2:VS ko>{,~1ڔCTwmXcvڭX2$1 @vԩI&NBߋ#ƣFO!?2Yq Uܹsg۶mˑ#GW^? A8)'[ 8| <СCC/9P+;dM ߿^̘1ݻƯ4݁(W<ߋaL[|@@@…# B|f͚~عsg|b\6q]G1mWϏvǿʕK|]6Gjڴi:u3hǃpa}<{`{+++r%A7>+jÇBYi۶Qiڂ  ;O.]fAs7C?)o1=ʕ+Q15qY;we}vJLh˗RbT#AhкB* sSVf͠{FA)˞=; vvvjA}ka4/J4ib1FbAAA&&&txVXCU &Lp5 oD'`jjgnz F?O> k̙31 )w˖-$[(BOzz۶m̙3=94T^D!B0,h:=U)c+U;䭄~( Oj4HN&%]>@FokhNijb nO=H|"*ȐKsU`e0 r^V"h f{QQ**]`0 EPQU`p`0XE VQ*`2 VQ*`2QѲe 〹yBBHHIIٰaý{ `)$*]FDq1vXf `0Z/**gu G `?`0 Q`0؏2 GťO>e0؏2iԫW֭V| iȣGfΜyd9MLLM!CsQ1؏2 .^-[o׼ywi?%%eeʔ9~uD C/0v۷oG?g?w\ƍq8p)K.R'ڴi2ϻw.*C8]v)cׯ_ܹӷnSt vڵTRڵk@GGGy4UT:uZn`I?_v=!(ae@@@b,XM){իg,VhѢQg^xr9.]h"\0`„ Ο?߷o_^[qqqϞ=;vԩSqzj mj6Q1F , cKܹm(}p+V_ƌ3ydqٱcGbT׼yzըQPBTU{_~q9|E\YfҤID/]Ç1=zT\.\*,ŋMɓ'˕+So޼yԨQ0<(#K (P9RRR:u${,Y"|._^blLJH)rfsss]l2{v]r9~R?믿J(n)8QH"82W\s網U]PPt9rZYf, cС?k׮-SSu%? g߾} yM 'KUt騨( ى2؏2_}7*,|uuuF}Ig0m'k׮-ZH:l>}իW.]e቉[~ʻO#>@uH/---e֯^"5k{lƍv#,lٲ~u;v9!!A&g.Y$|W^:u n^Z>KZQ?;wnKQ0zjjժM81էƏI1_zA~i7~ѓ'Ovܩnɏիw׮]Z&MMo`g\޹sE<>|p׵pBJ)(r|8 n)@.\МCC5kJ ,-0(`0G Fns~``0؏2 ~`0 `0؏2 ~`0 `e0 (`0L?)))mG,iq)))N~)))AuGNNNSx^S8S8S8+޼yϟ?gϞq p p }e޼y;EYs p p }ʽ{2l^9kp)1Y///C~xHה-^x۶m yn݊n3grac>e.4K״VzWzzzRJlٖ-[VZ]~iƍ%xxx1e<˂y]NaHIIo\1 `Ϟ=^^^0f̘ӧOO6 1 ^Vu9%S< 87&&oܸaaaRh:<~XȜ9s6mڴ~=z s||<ϰ e.T&#. =Z,xY  ;x^S2=j) >NɐqmԨч)RDO>.dbJ֭i9߫W}))b˗/_.X)NᔌMx^S2%e]8# `ee(V;w(]7Hx^Sx.u_Kx^WZ۶g8#us"ޕՔ1E 2e<3Sd4e+YbhaBlcWDQ ӆd13H}έR}*XT&v`llѦMt~RURQ<9@II׍9eʔZ%̂R,aݺu!!!7%'??;|ֿnqQ]]Yf][[[9r֭[ $xrf͚@(722ct(k񣉉_|SN:ĠXYY屏rNZ~ٌ3ʸ͛7qTwwwAwB~:&M;w.u O?~ÇٛY"pQJ5aٲe7nώ6 Zl{\FhU[[[&UXŏF4&995n$x$x%,g.Q/ CCq̙#}/D*T#Ceo;]7)[֋E*DEOCy]Aa P^,(E瀤 KP^:glllߚbꂁSCSLbb"-Nud---SSS-P^(K T C! $u2 (ui\)MXZZ:;;?|޼yleOuƌr3_IuT*>~xqqqAAA쬭qtǜΝ;>|Scǎ0Y.죮{Çv^Wz˖-]^^SlVMM͙3gihhcT!!!R::R^,hAXXԩScdd4z &N cVEa}H]ƽPoaays-\( hnn^XXCaÆ['/^}kPǏ_b$u$u%2[ʄ$~___ucJBI,&4h'O2/99a^ &++EaGUUU!mzz:d0b!bQv-IJ 1C 1܎u$b!,h(]Gb!b.1C 1S^(##\e"b!9fTUU>7yύ/ F 5H3l쥎Đ%R^o5iҤu֝;w됐 N>,(uiXQ)I.))yůbggGeH:(yf͚888XYYM<9<ݭ[7OON:yahhYzjVѣG"uΜ9۱cǁnPZ*fرSNxUrr2tT CX˖-}a@@7ovܹu3g흜,\\\XQ6ݝ֤Ixd(6YYP@34.{ci„ 2}c|y왒& oԴE([ș[VkѢE_jѣGa~~իd.t]|XPuMLL\9}tǣƎ;fAt+^|Y\\Â~h;OKK۷ouuu9MF Y7%da#d/u8f͚b+"Ѹq~+++vhllZTTBk={d;m۶}5]vٳYzyy ~+YxĈF! ;Z˱ +|OW__8++k"CCC߼y0 Iqa ˊ:tHp(+3ܺu [zJNN#qO<[( 'ŪUaŊ'NfY*++tҥ{=zkggǏ_xg[st.8ɋ/D߱ƃnݺNխ`p߿?11qǎ`/\} fhhP[C{J3>WD^ W%HHCw^Qʲ: ._\Y~ _f|fv7UJ0RLy: Y%$g^H9Oꂦz]ە+W۲e UUUΝ }ӦMp7(ÆQ\\ ߮1Z%WuQZӧhsQSSx_~w1G_~>>+!&&[SSӪ{:"33)ST沲.]Na Faa,ƟQJEn$?LFj: $x^(nT*(--Ϗu떶6$u$x+u%,h[cDOO R^W:to߶nݚO&**_Nv1i$E%777vwS+ bGׇb\^W$v;A 1C 1rB^,Qت C 18L-A&b!a>׎u$b!Fϵt!b!v(##\>e"b!9fTUU%av55ݽF!!!:::Wp^BetaAeeBر#((ŋ/_d V[eeela/ЮZ #GaǣGffΜ }v33eeea<(ٳg͛7 ;vhݡZ(}ѣYP?ӊ@}@5J-Wu#F.YƦdРAho՘ICPQMKKΝ;(_h׮](uCuYwܯ`}%'';vdAp\72'_^ 0u::K?YÇqese <x`\wbTg677g***nPn:'''=~T a## *ne3(Bʞ1ɬ) $"NɸQ#k|ᜅ1LPPPes-#Tz;:pV<==KJJ?,JNrppTܾ}?lmmj*8Fe<0Iu˖-L>l޽={6mڴϟ O{/R-<<c>00wwwɟ >p/ y]|8qիW9ӧO:[fݻw_mbvQ8O%KaNNNnժW?DIK42sLD׳gf?X۷111:u◙8q"jzR 6QFA o߾ׯ_KCz @L&M|FFFP <\Z!4/_dpҡȖ-[fll [UUX<۳fB!z}_ @BBxdn.]@e@!pR~3]TTTY>IMEܹs<*))|)|+Wܹ[߿{_'511hEYaJePͫ8ۦMx뮮Ǐ~[\\| G!h@rM888H6A+hѢĜ;wNGGwjjj͚5SVVoes%Iv Wl \  z]߻vĚO>Y:<ׯG4ہA`@ <È)V<}\|9?u@-CS$mN2hXII [#GbAQZ[[#\%ɥ5>]%ǎˬx~\ ? F"諬 &Ǎ7 Z`WWWGSO9tP?p00ެ_xJ`R^W63 /M0a? #RT_Сn.:wuVl2,@[[ɓ}0H&) O!j|LLLj5.  yĉRǏܼy-[y=²V֗!9`2,)Z-Z0|KQ---Bo_{PENn͞W2 {I W12B I~,SaG1>"ẄO^w͚5>|غuk333D|*˗/6lټyڴik3,, ![x1k&۷gΜ9p+_}UիW),EܫWZtX]WWM%K`ck׮!Egn]>?x;ܹ%Wm۶d}1˚5+ W}̙ׯ_b޷pB_ 2͛7/ʌ$˗/DdϞݻwK߾}Y&*K {OBBBlmmzħOXHk=ƤC !<'HARBR|&*y/$W%m$%\D FRz#tL+VjժTH{޽I&!-Bnݚ`Z B)faaagϞ8qiA\t AH[@=Zj͘1#7ӦM޽;lmzb˖-+ .\e/FAqv֭|:t@#-ZTs*!H &>|{\.xVVVC+B yZޱ@4T.Ƅ+W{@Tܼy(}J :::Rq,-M !6 cx`HOؼyLB2GDż|³犓|Lz_;fԋMRb_n 2ӷ9sey/G3NnchJͫ! * 5ƝvV,-2l6[Q1V^|6 ׁ*' ms &?ngSP$-k-KkzՊfifZwC#&l}ޡ #}́\G 94!Y3YF/,척 1k,L21)繍R OD7,3{bi㔷D;n…uCEB EY(;dbZӈHF */y`uU?yi4O<+"%. -`2Fyh8cjrF% R|0qiIԷICM:a|)DS0A?2n*(yBR zDD"/hJi×z1TŃUCKhIZI|uid.!$~ˤ>L2_pJSjN3*Un'-Z(WC Խ/[菁2eʐGΝ;ǻ˗/yq |M4)***IRʔwGLx(ѰaC֤p޽{9gm@"E:u믿۷M6t )“"SNCLM6 yT\Y"qgLRǖIt  f͚K.ըQC2gB!O> *e ^~-[6 пu뺻C]+ӧwE%K{{{~rJTٳg՛:emIq(D+CT Lֹ&)?:mcAL PsCe>&ŋIH> @'N={vʋs۷oWW+Nhr۶m aX70{-PN$Ŋ~=|=L呵Bj׮B8pUVpnݺ5W\;A 3JȇL{֭KΟ?ς ).$u IhlfĂrYEXVKֶ꣈_%K~YfݥE$ >ijjJYR^F Z[`AP 4_SNS[^z}/]{b!)&X'''% YD~9K$Ef@=([5DHVg¢⩩O_6+6+$$m~zooosss8Yf8?-Φ[8[n SL(']6gΜ\FFF3gp90Rp޾_akk.P~|>}޿Ș] C + S+Ww"?XG]lq6UiqE?f4}NR4Au}S",H& kJ۬m۶*TJ"E.]H鮖i1|]5k'euKE_`ipi+Sɗhp)J?4.bˇ+Zح\bf@max+5/Ƽ:^Νk.hԨQv֍ߧWVCk+/Կ6*!%*kgIE2yyOiNFjW'Bwme?Ɣja1P|$MKW]݊mILP ) TcZyx<-@Wn$&OiS*RtJSeaJR\E:^Pձ߄շo_랯/}J[ZZ)ڎؘ4iҍ7KzbsŊDGEEmۖJiٲ%=4OT_E>>|N ڄ;{n1IZgmK.BCC!7Imڴə3I|IѬ.](oYwmsvvf^,C__͆TBI7n|ڽ{wȵk̙ׄ3 ~AR bbcOIZaO${Óc^>bYD n?:<$ӵkWC$Pd\ҌI*YJ䩸] T7oS ߚO_$y{o*[\rrΛ7coK Ge&EX...zy䔑#G\js窌Fz5-TWQ(t2%͛7UΥ/ = $,,\@BXZ@Y0^!['߱cG7Qի޽;,,̙3ŋwwwp]`A|&;w٥Ĵ͖-I." X,~3f駟X8` ;#tO<חkaخ%bM 5k|UVdIХKH"~~~AUXXX<|---Qd˖>H3/_"<>9DbR7lؐr6ldcڴi,`֭I'u Q~j 6wKlM4Qy pGi֬dt: }6N۷oO۵܊+矒r%cqNct(U Gro(UƲ.|c+T+mK,>|ݻ/\tR|ҥKg ^nnnfff9sۉj de.!zxx1Tv Qz˗/S|G|riCT0ŕ!eΛ7W>ķOl*A >}2FDTY̙3K>0LSB2r>$A!|Ȑ!Rnu=w\vUJy$~ U(wĭCRreX'-r)+WWnܹU{yy^?v֥)*"Ӟ+B62z*U5P"d'LU D*8OgUWzaWId_]n,VmobOW!X. wCfC9^׷#ŕe#TX*+hڴ5k ,H'...-566uֈ#>|Yn7/MK6qr);*G$~z%9Z7T. `(HyBҀxK=!Kбba6䩂s=UuhǏ7i$7?oPPPϞ=ۧPn^qFLһw>f̘e"pmڴcǎ 4rHʁ!!!>>>ZJ(}ckk ,1x`!R U{^v)kNL5kիo߾}===˗/ P&PBt:#G P kժU-B6CV,t:p׀ 6H%!9vF< |-^XC{{{ I łm:9sߟ,)**6o.UT֭/ ~-addDQF0w؁l:6;Tp+~N< 8xx董#\lِ!CV^ px]SNgbŊt 0˘7o^$\tcZje 6U w޽VVVM6=zY 6sLt… rSѼ@sΞ=KŬP5Cp]0ӡ#%jժKcǎ_Ơ[=f', 3f 066:\ZZZTT q!"c 'aaa4( R ZJ;uCUaM;Zp^.v)K 7/;ďmK!|6UB߼7o}ʔ) n?K\+}hJ4_~ Ԯ][cCQ *r''•6}cwS et)fOJ,9s栠+WԬY3&&?ȓ')k׮gKhH(O`t]r@^| T$]Ju}d*.… 0m '`=[e0`+w֭[%wSZ릲b< 7ndϞ1X(J*[nB|}}*uT( ֭[jď?B-[H?eʔ~壮ãGLthuvvf Wjy N}},?½ .,"))D\\@;wnҥuUp'{^͛>@ \:ˉN0k9SK*eݘTpYӦwP* I&7oJíWmۖ,X }#h(ϟ1]70}XzxxkZ:+Ȣ0;>&9E]0%*| aвX3f 8~8MRŊ8}OI}||#G$̭6mڐBn"לc7-cǎe. p!;w$6UѢE֎DMSS",uY#́;:YN$X+-QW$TB6D -&`p{z' %` % b b boR up0 k=ztXGlll*U@QFG^O6;&M?~mr/^8l03gdRO<S@ȌHP>ifPf1f̘{|(=T.Gz**TR@h}˄ bӦMriˊ7 ⶲ K ܾ}&DWX2L!%ҥK5jsqq)P}bRTzG~?0])Snݓ/dCW,605ŴK%VIb@Z!bSR߽{7[ldʊ*gqDٻvӼys{{{L&N8{ ."$""VZݺuC=t3J֭[ݻws0v{jժ111,~5OK`\O>ٹs' @q(w۶m _'B#*V2Jr1Q5\xaڵ+fԺ6օ# ΋-Pga])&ATBy kX,r!8zر#qYtV:t钉 4!oذeBwTT.&ibu =݅>>tNf0H[:όʂzQhBJ:,޾y Ge˖3f hcc+bڏ^Ki?j{nLաC@T.2+PFr_|[ZU, h P`6k6%N>h˂갲[*W͛dtaذaNq2+r ZR5Vef3XB)8SN@X,XbS"6cs»gʗ;f+*r4¸Y~deyUiJXYyi}Ň?YOFzVkZ͡+‹RU.gA.ep*JT[2[OJ~f:i6 "Bȡ6-0f例>FSKlpnAO{ڊO3Xȣq9c<2nR~)RsGmլªM ,B<[Un1?,"r+I; J"0f&V9.N; ݲj|92uA ^q"xc(.ˤ@Χ'SnhN}m$U|PLo֋ Є364"ʐFFxgBFB!,!]̉Sw S,&dƎrYdk:򗔻vxSy*9"*4B;j9*]/7ѱW.:O9Wu2mnpI5ÚPxLV,C3ܺϋ|[Q>(W謎?[:*:V^[3]bk9me>[:vΎ;ůVqʮ?->LsT -aN!XB:LX\[yRosʗr+Rܿ~Z}F[?vzʊwjTck[/R /#mB@UY/QHh"XHBqjk^T%?V {=@հ_ @F(cPI*sbm6{=BJ)|VX&MbV <-onݺULP|yΜ9ckk Ŋ111ѠXnţ[¦pӊt1y Op+SQX"ҪZpWv3b›(5k>Px@h bC̙Ç'^Z.N %?`K<D1ղ\--VerV(I#"kPO?& !>yVA@3'1:9?٦VQ&fC+cEXB{ۙ;qcZ<l확Dޙ >7(~LJ5lذK&R} AU:4iȑ7nXbVxr3fA " ٳ}(EEGGO<y߫W/+W{>8^zժUI&͚5)Ç .,Q۷תUٳggB "pE#Kt-WZE;x١ g1bB E̙UO2~x300PO];Ţf>5f{)]p3Vڵk_[Xk&hDk׮55}ӦMajB3ѻwι#GŋKN2СCSP:w=z@%hDu+~}l8ZPZ޽{שSG\`߾}߾} q!r"E,Y&t6m`^~KKK7778Y/4hxx5k}}}A  BΝ;{,?6Lq2d$P5d͚5 tҪ(333q͛ .]z1ɒXڶmg UV5OԕI˔)O1k֬FBcCjՂM:>xw p]ZӪX'O9r$&B ksM vrrpD^h{UtwV_6mg`؞SLy BYr%b'NADO܄bTQ:8e?"T g;2Wn8HLP-yNqU 4MEiIeoy\'>n˿P(vK C/14E+22HbMio6iҤf͚~ll1m-tN@+Ţ9r(Y=ztz.^xС 333ڬJUܹ-b.m~Z=b(<DՀ3g*+*xy.]qRy:~uf͚xqBm&9$$iɒ%zƍ߽{qww>OOOޡCc:;;w0.B,W؈˗/jMλNO I\]]_~Mٳ'!CCr -Q/h:KVM2E(5"BЭ[487~B_"߿Oʇ@GG^zhB;u69f̘/^qT7h@Z6NDw $h$1 ě+իO< _j+W~S,6c/8l#nn+.xW@i9@P0:>vK@%K@(P,XiAMUHhaa1n8!CpΔP@@@@,}+soyxxЧ*T8|6l۶_{.ޅ СC>}Ǐݻj$)u|xEʕAl߾vښsԩRI"H$A`nnq76Oի fZFYt ai}X̙3KLMMlRZHoo[*Uɛ7/ݹsgV%VTr4ij2}:/Ǐ4J*Ǎ7tTBYf)R[n9rbaaᩄm cQzu ?622zE(Ṡ`;N>3gNWW'O #,X۷K*P.ʢ`m9Bćt6oެ#GܹSC[[,Yϟjȁ@DUV:f.v 1l9ux٢5!%ȊZ1Io-c޽C Q(K[.y͛71gi&ONNN>hߣG&d*TIveYNK(P>DCK\+4_d9u=SL7iϝ;&/bڵ@r,OիWaJкҾ}{X+dҒ a`6lh JNW=5jDX_~Қlu{r=5Hĉ$޴iSSMc)W^WBt… kժŇhR ˖-c?/^VSpyfl@;vlvqB*冚ӄZ˲睬վ}ȏvE[i)aKk~v%[M49~ԩ( W\Uj BI0JJJ,˗)9h~lC1VP`i?K _b:ܹ -|V1bBAC-1c]vӧOlLRBpG%P.yU%z+Ad7n@a4Ç'NDE0h)߇.^8H! ooo2HoǎtV_ƍas IYsnɟ?F7f\kn)y|t={@ݣ޾}5dQGW5Tb%4ѣ+ج5k):Е3Ih\JG%4Dș3'_|\%x˸k.IJhT(Wf+jh9;99IN⢄L]![J||LU^&ᅭDM5TO/ @:0X` % @1Xq<ĔP@@@@s[ ¬mpD?f3 3-Z̦KhX-[\dYfmۖ0~Æ 94h 3rɓ:t޽{ +ѸiYxvM6MufMK+ t|Ȋ+ׯ;wnUh`X"I QFժU_~ ѸiȆ `nI!KQ^=gggȜnK<ƍsEifkά0Xzl</ 3vet3Q V3ehbt;q^e˖;ةв491%L{ԩmI;%~+~~b/dҤIuԱ<|!OgV,ϗoFۖ[XX1f~-:c GG'O9R19qS:xʕ+Ç &iN `zv:88,X :g͚u1n?~A"hѢׯ[̙31ȳ~'Nطo_"EAAA3g2e "?^:ՙU(O]۷/8EouJ2.43~ԩS{_;w@O>gϦs.^mU &~#cƌ\BJtٸ 1tڕN2d#Gϟ?״iS l,z&AQG4`RcCmqE↑Up(,,PnK\;cSv%wܴ:uLd 0ګ̟E3fueCYxݲ'ND:hРk׮)uIŬBy6 ' Yu\:۷ @Tkgg>_xlR#<ݻ7t::9s8Dl/nbDАOH6K/t e_5J!0mmWԛcm*Cl̬.4YY~RR/:m@4n d-!M[[[[ kkk"uNri3 _]޾}{SN10P5-U7Ⳇ@rSSSL4*?@UV8`mֵkקOJ"è"$hA+ V޽{3g>|8a„7oHZq6m۷N:M67ns~TE,بsqiIA-W~[9;. 6&{k.܈&Y$j!2p'-;O l^12 J*Gm-TR~(x#2k2_$dH{bMQwd* kr{) cf 4$̄BXdYqF!AG693Y?k4s|qj%Mxn/S3Il^WGe0|Y`PW^ `YQ16Ʀ&v&~% gKRfjhfVRFwFq0XzbV¯‰W"+$9)]o8(~)KɀiA 'k)_}!@|̭׎^,t *bD+Q43k8&XVWfj:W]m%Eh`Ve!TUYa_٦%VHթPR ۷{O)Tٴi~[l߿Xط6AM߾}K޽ښ?GGN(QY7o1Wٳ'ۡT$`5#[-KE/EWgv"~a -[面i VR`ƏoeeթSҥK[NNN.\P|<ի_~mddD;hLDFFV^6}vM\e@)gv"""؆*_ܿ;.g˖k׮kWjrʅǏ_xi,ٹ|tXVZӧרQҥK|"ŏ>q)6U 'iZ69c8& ?;,ɓDGϟ6r;r$(A4[B65RHQ{6cw{Q3˳!bv^|;slOFkzI]Ia 1 ElcMc2b2bz50Go-;&^$t͇6ƊB% 2eK4~#[?4=rtSy~;Z|=U2+yX¬8֭K^%Ο?off?2 :(=ѵp 3hkT E`qtrJk[hQ{6 |0掷1 ܉0>$BD)Bc2.MҘ%o@t,{IG'V]fl+Q24uQX 3^(3@mRIA튯h#'&OZNְG{FH<3WU_ETe[Lafh`V9Uɬ9T`6ͧ4?fj. Qc VǬDuŬحA@@ M2:&9efi.#3_~2AF#KV/t[K8* 6XbQDFq444T4|:"`gg>>>*Uzp~B zx% f 0X Ep:$Bڷo֭[S^qJM0჻]޾}A洽ρ֯_OAod ߿ͣثW78plVZyɳ%޽-[uK,:tŌ *4a[[3f<}tذa'O |rk֬166bŊ|!a' J k:G;w޿eY2X0]Vi0th|%I&nnn9,e˖M@#‡m*S Ee4ÕB?3tܹ|&l hpV:ܽ]JFFFAAA7N?'No|DǏ'`)]T2d0:uݲeKMDGV\`>-Fyd[bEYl3e$+hm۶W^ýt,Ȳe $_~ݻ7F <0^OBNk׮Pjժ >ɓWNSBX3~ Uk<{)SЖ nWe ֊)kE$h bUP@rZ6Qq3g,|]"vrP 7-6n9 # `UkH > l?& 6m۶#-T3X-Zs`z5nܸ؉'b E֊E&"[{wo9HRJkUVŌfرnnn?rE$`M<ão߾AAAdسvpzq95wwǏ;uQC7o~x} *`5kҥK?gƏ_^=~Tb2gz᏿5UM@4n,xD7ɓZJd `D Iy+WHH-M+ PXѲ uD K@@@@Kl' <,a0\}i! C7XtYVӦM㗃  'ƍ0dLP@@@@X+aJ@`?E iZ4\Z]vK%^x1wϿ{.k֬իW8qbSؾh/9sXDf}43~޽{'~mBΜ9֭;c [[[Eit2`ԭ[BXf{t(Q/ a%/ N-v<<<6m$ \f tVzRiFyWr;vLF=|pe˖MC+ӧO'=yʕԩSTumPoڵ۷o}||@+Z;ƍ#kEinbITfGT8 nܸoկ__h`rS(>tӤITJ+J4؁9sfunJRJaC'n0C>yTa^:pȄ)SÇMpf]]]a-bh͡W"N:?ɉr+Ǻ+kI(D?~ԩS 6L$(P@LL93Udf͊ OzP[XW (@?RsY*Mia gȰ{GN9~ԍN|Y)QѣGk˗20&6VZm|O @;x`I$}/۸q#8Q/</R Agx]333{` #OͲQ+@C05ڋj@Z=0np(O>:Zm/ΆkԨhxEAt̙3r\ rG]YP A4Ԃ=uƌ,~?%$cϝ;f^a$D>HXX*RwtHV1旱6.'%ɓ5?!xzz2)z$|ʀ^MKəd f͚ϰ1U*fmmMUվ,-ygGLeG{QWbJ'F \޽y ӱ;wӁK``$SS4L0biϟ/۵kŊcϡ>~aeH;2Ƃ6-СC-Z ݻM'ǦbRߪU+Ek>O·JtJ9TTbѢE͠I:uUΜ9aYj(dɒ7oDfv@J%ʕ+w L$+U+ׯW|T9xLpjQ3iF$Z{={0Y+4f }ggB@3k۲lٲxBݜ9sUZiٳ5ܝ6mʯHi$XH`h!D?z;wE}իu9s{}O?8\JÇ$#D3M[Bm۲C2ŋcK!ϟoРAeKիWwCPBr=ڴi^1.,8yC_X+MXr%s~:?|H͛#Gm,Yg Y5<m`gg'ѣr 8uTf\]]$((H<:IRԍczM_Ρo߾e].AAmoߦʴk׎B>|J2 0׎l2&=z0QoߞBIp:l) VX wFɓ'9|0=(NǍƌ$ W\uYe! Y+mgPq="~_~F|,+Y7^KD'Ѵ斒G X8&$"Xߟ&T1ͤZ,.|+Wi/Ztؑm~IyZx+0d3g@5͒%KJ12eʔpB;{2L27}Y S/2L~~~f:-*={v {AT (BE}Ecf)4c6 f OJl& |+a"H{dL Z+!ABkY+!ABnX+! ABb&(AB: ͛˗/^ !!3e˾{b( Bҙ !5U߬͛7P!A 'O1 !f !f L0%'ec4o|pdj܌8T(O=I ܢE uuu8DA49C3lތ ոM3LP?ĉuE4$+"tpF9#bVĄ*`Bggpf=S|پo ><<5==S]]U=3ׯ_gԿ̙3#""N<ɝB… Z^Hwڵ9|۶m[^yiNBrRXӧ5k:t(+55AiNa%J8q} 8>;Ì@J*Aݻʋ y[[[///|]ƣ,ze[eeOL0Kamm%e1@3MLLm۶)SG7*I&e=2A?~s`mڴኍ3&((H֛ ']xxx߾}ɻg0+5LPrLHR&YIDmff|rgg{KryaÆcǎʼn vfe&(ˬZM\\\'S&m@$#G =T''W^=~Eu6fiii9sʞL`ϸA޽FH.^ory|}}5k~ {m)7[E{(1+L0K3}rl*|.\Udz\]Jlɔ hw(AC(ٳ'=W\b% rɒ%ك FbF",Hr1lѢœ'O~ZP!pJT\lnn.b̈*U0͛Wqf F ɳI^Xŋr?}d eɁhj5AP#, W6jٳg6m r׮]-Dʕ;w'M+5\aU.B~%$$|{xkU9sf-; 'KhMP@7nܷo8Z 7}@TG`V].X-]M;vF/D 61B?!(WL%J*m޼YE : +Y/]xq )}A/p Mc@^lFf޹s'-[0ݺuK6}Zr%'>^PQ^Ek fYR&V >_ Õ&UqܳgWGcǎPX7\PqvmllNjjX}_~ѬnVGhƍ P$@ [IjwM H(Y~޼yq1dE8&.n+WC"ye5ΗW,I&ef62̢`'XZZΜ9o߾Ed@}Xr]'''7b-[֪U= DEE5o?mٲnݺ;cD8p`ժUdH y@^YC ѺZQ._ضmb&'+,˖-9rdpp0&Yaa:t@r%m -WdėwǏGޱcGhh({a!eYب֚`a ׯNEA6)wULZZ6)+8Kf>VV(r*MfZTv{@.E=Y VEz5As j"S&(B8$]&Wؑ 6i$Oqrݤ0c&HD 12L"0P¸2A" 2A"  "($" 5kAD'[QAzVDAW[F!" #,ZhTT""B VZӧO@DQX15:ϟ?ɓ'h*J;AΝ[ї/_J(_r=!nIT>'s޼hgg'oJLXп[NXp ѿd÷q"{@{[ҹӠcF7[?@|ﲯ~u…(dH ΈOkMNIVf U/\ m6\/2P|bKwΤ r'l|_v/ǽLw=9ӥv%2LaPO|#hhDRyxNm+H75m,]gci~? s/?׸S:mQyƮc[[=:լ"~pj;h1/y6LL$.?Wrp\}ȽN9_*}a@K/$m(cokͩ'fx[?OL˝(P%\bke^q4nzXGk'R",wF7 .,o.kt0fZVvdVK^A[/ݘ0Um|m''o&(;t>ӏW,uT^Р,GzO.3geS>=_]Qخzg"}.=הSX57vN7=ݬ:.Ջ5z;(<Ayׂ[A7*5pMP-7 .$D^Uu=phѾ<ݝWp v_^2<`hw;{`\{#_ v"aeo)WRעd S-yPώfpUʛ=w=Sf\0lax|-;,ѺuJMHb?}_x n*sx&&pOgMHJS eեa\] *=QW'k1ȷÓJ7) E¶[yiRrKdéii. YVp+nPaUVv$kVW^َѭqf˽ fx-{2e>֡ư1NNkO'ZtX|:韑بD;@!h -hxi!CNru@6#(/{=2G>$.!YD%oyUV{Xѡ+8y'*_ؓD"T h0nˋaVKVW^َJ_^K'# F {&G-;]}U }osw7pX= gSv`r˕}LͲbCdX~#gydѡ8|9A=B垨ȀDޜː(V[mrU}|y7rgÉ * O*wHXUnp{6*wUQ-y9әYXdi'6J^.8ka5\Xw d21bP%ԪV{#)9]1DW(sdU.&I|e$H|*fލ7jR?ԉbDء~Q:e_8M lDuDYKYͪ *kNTzGhѢy18[4^U}RWXv'fXVX~7nbcb&xdlG*Y1`o*mk5Eߧ|mYA08>&jZآLΟcDof]#[gMDt5EWF}9GچPRYa7|2jsyfvfi`Z2!|y}Ĉ{Zpazv]x^z͚5kС!!! ,x- 1Bp~-[ 7cƌ1c;vĤcǎZn bY ŻNUİ6I%0E[n*&#[յ0u,kE-w3A1KS.lǶ_SLU X3aIdV~l{\ZªeI龹ey9dR2/ d[TKXxx)JXVXn5A?z(sΝ>}bРAp4T\ܹpFY;vHIOWzi)qT6|p +Ý@ Eeq&˕ KJI8)K׋9Ң51WV.^]X&s=X TqLdR)GOfsy ;'I-a5X*(f\DE`pŴ$R(ϴ&A ==r]T]#\ 4Ʋ m&QF ?~ܹ3b"2ڵkڴ)8 |0Cls?OOwĹVZu:ee&(7f|&G˶rMȭ̔\J]ߥV ;(w4Vݡ%Yh)Cy3lIsa%yOQ&CS %h֍e&ϸx{{شiGdIZ7n]׀Μ9s?~}>0yQH(788e 2C'N>ݩS'΄h#J/4L0O<_| 'DIЛ S.e R&HL@ e;ẅ\r >UVrGL2Amvhz͚5:h2AְQQQcǎG.]htLЀ3A8/82A!!!...[mڴJ(̝;͛}۷/,Z(<?~jjԩS':4dȐ۷S&H:tǏ_\9ii.[+@ہ@=ry^^^쫎sD}޽{dMJJ9rdttR&"]VLϞ=_x) kL4;7a4Aw޵kݻwÏkkkpO֭ۼy3… Ll2rرcǻwqDy j055B[\]]Đ 9 sLL l?PT)C {a\0`={H?1޽?n{kq˗/^˅l]ծ]VknnW >*~Z)!;TƆ:Xv-g <m66rڵkJ3fѣj.^xeV3?~Qذ7m4  ĉS[j$G@x f֩Sb@8vX\\ LPC/V^sp@KYb2i b""LJ]t)ހϟ6 ˈD{ƙ DmWP*YbĈ[lGG1LsF:qߟ7{lͪLPE,X˲e`~HӚ5kgg$%p:kF0 A & eVuV Td|Щ_fdΝ2 ,XM6իWõ2ҥKlAp|&5Au2PflçpYm 4̙'OhV-e*bʕR`NJJ[ATqb׮]pXCe>J"(Uԁ4=cǎF QP! 3A$hDkk .pNc{۶ma cB'N?(y3AEc&ѲѰj⯲Jo)P3AE-FVl&H!Bz[-+")F888lڴ 4+`MVa˗se0n3+(A ^; sV.%7ħ\2Apww믿*UyfYGPNjҤ ='HLm`-RBhhرcݻVr`檀%R߿?gΜ9r$ ɩXbSLH9@:u233;|3g|||f̘&e [ntҧOvؑiO>$<E]ZԆ8wϞ=6 (R)W癠df͚~ŋK,Yrƌv/N<#ӧO0iӦ"\-F;T3Af2eʬ[nʕ 41,K׮]<DT9ۊ+4˗ǔ.]MLLF=m4WdAAAGҜ>> r RW^Z7G;5jT6mΜ93rHXйǎ J{*ͰE˗۷o/h ƌ\2AR.e *ĦMNZpatږ-[у蚚ڽ{w۷?t; yAʕ1e˖HCʕ+Uۯ_?\xzznذa̙.l( )2AXrpp`tɒ%߾}hC 0r_;w͛ڠAÇwWs{3)W|ʥLPZ@p֬YgϞgNz-wq{ĉÆ swwW^R[XHq($R&HXp;99~z,Apuu7o%K̞=[p)r;?~.'?~bggSSt'8 tR(g\E ͛wݺu6l8 r,ZɓeC qUVBFH |%A~ǎ ˱2AR.e sOQbE |`H3fYڵ~U]JD )2A9r#uq+2A#A,Z/$R&ĆǏFKtԉAdܓfDAr2A}DDDAD!Q % 5 Dފ"s\rTT""} \w5 Doׯs/ DWf?&Bd\D0Lȓ'b"rr~"Bt=PetoW1!55i1֩SGB2@41"& sN֭|֭[{#Gϟe4jh߾}]t={vڵN<9`333߾};n8 T8p@Dsǎù3*ƽ >f 5ի/#~q˖--‰ 2dHΜ9qڵkwYdIpΝ;={ gرc{uʔ)'NԵL2Ah3Ag,7ׂƍ>~ػw͛7#? 9| FDUvKK˥K>D5k*խMd 8V#L o۶ aԏ?@7WZA֤IXݻ#hھ}!ӧ7ogtҥ#Gp D *Tx&H[Ue 8k U)Y,& BUaÆm"BDŠ׵k~ eVXW^廏Ӥ7nms8ŋCZ|kݺ55k PݛfE{_>Җ޽{Co֫Lw߿DófR:uG7f垮*rNp[nUP[jU4\85hh ;v\|9ʕ+W6Q!cڦM֡SRR($f&PjՙA۷oP M ٞлw7ni\3lM6_~U|ZZگR8::;wN0 ^|Rぷaøu!>077CB+Ǐ7o:t~zUTw)ڵ ksel-`p+0mڴ۱rvZӦMqݻѣGc8׸}C+Tչsg% ӧOɓRJh={֬A.\šW" JNi۶mݺuC XTr]FFW[nի XnS V]E𑚚&NC7hA-ZN%0cGnyc&zH7NT,Rȹs2/… dyf`` =<|8ٟΞ=-ZU18V\# E%*N_u҅;F6{^:-[4/,wJ@w8qwQq{?{n8p:{{{d27b 61c'%%8\r@/sW ͚5q3&&&ZlLf`C/_Fq^xn% XdLM#YH3T;o}:`d4iKyWtr$ |N~t!Cn`p#DOo޼eqݺukܸ1R;|Ef+֠J`ݐJ`H.\f 6`!ǹ&MOߗB08 DHS4j~Elގ?,_?F' .\ĉȭs̙+W.[[[4FEW  Hej 7]!""".]"crՇWY9q%.e "(')vߡo*&&c**(?dmm͆l6ܹS6A޽;;_vq2Ν;-Ϗ1ĺr,̩SeS4L6`&`С8/\m@trB{"`E\0m4EMAA/Ԅ?1ИnݺQ;D5j(E .;ڮ^ z`*n^yW~:m\߾}a :;;=TRϞ=iF ptt߿?䈽{L\ [~-^8gn?+Xt<$ugc+G@ʏTA#.ԩS𧅀]"T/wtA#4jH1b284 6K9:88ֺ\Z;DjEW,GR=zSPtEAqůu4@}qͪU-\F pJ']#Jт)M_~ZB^eu...EOEL4iƍqqqpժUOvo8\twZvAA3aXn3c >ٳgN`ztdd(qb{쁗8Çٳ'ø?ܴiSnC/4ɑCÕ =l bԨQ$P˖7n3̑#GbWZYr)Tڵk 6-[T߾}^~]T]wbb\7ov Ed9lذPݻyԩs:$$$H+%JGKŋp܊zT`A Tnnn'nsz7NwPA^WX[N*JR\em4hp ;ݣdɒab 6B ܛMz84 =oE@:ڤI'''n'Ӿ} of(r~Г۷o6 FGGWPTݺu!ڵkQ; AϱcAr_MAA76UREŐ%?#1 ruuUH?K8( +!Cΐ7-Z}|2DEE\vvvcbbl۶ ODD}666p  }k U.eF d+dk͛mHݥP^T)^W*kEYp4?0g~I+R8CE~E[Ca\v. A[2lfNAU5%V %#v&+@ EW_J M]Q!@@ EW@ ]@ ("@*""v!qC8Q8bO#qC8!"NqC8!UWC8!qThe8!qCG+Ebo޼)*qC8!qVZC8!qqtEE8!q GgC8!qT qC8! 8!qC qC8! s;vQ AܹsNcbbvA:t`ffIb2[hϤ\Ѡ^z ̖Vi` rr kkk%c. R\E01ޞځ`Y.5(3"Z4:!v?ԩ*T0mڴeΚ5ɓ2%J_5k6mN477߰aCr\\\>|_t-[<}511@-9&&FUET,W15gggG ">>֭[Æ |gRSS?>qīW>IIICY&5xxx,YEcǎ  W"Rq rlhe*Æӧl$IH}f̘0fg |}}a0/"BU&YP+>rlEYZACEbb;wﯨ3**jݺu^^^ ,?~Gװa/^l>22-@WUnrE\'kV#~ Ը~6nܘi„ ;rv믿܆Wdʕ3ddYZJX30͜91K,m6Oꄄŋ͛7=i%ʠ*UET,W15K+!Sq&JK0 U6Q ḧhe8WDinRv9:uG4-ȁ ` `n#88DLbW~DL,,ԭ[pXVC,pӐ\D7ongg'\VZg YTAR7/Y.iVSE-2ĉ 0nܸWr̆ 3f5j}+WjZj`?X뱱k֬رcȑ#޽+>{ֵw&lggAR.Y.)WR2 YLM1Sve:;;O2[nԩS&&& wQ 83`۰_B֭{W855q5j԰x/^({>>>fffK oٳUV}5WREQ?<˗/q/SLrrrxx8οЪUׯ߾}ϟ?+Am%J@1YժfUEf4jLff+zYnvYW!mdOA(ݺuk- Wё%ϝ;o߾ 8 }MMM=ڧOݻw߻wog̘S&MԿӧϛ7Ӯ];8f\n]Ro箎jZ?~`CYo˟?VP XQ\.ϟÜRXz5@G>E1J*)"o޼~I+V\v-:~$Lի죡\4))W\YV+V# gz1q_ N*UEjLj6 Ԛ5c0m6WOff^Rp~]t _133…  ʕŋksƍШ7wIp?CrP%K.44ӳpˆheP]<{ )tEg@BBBPP2$e֭/_dÇ̠S׮]CZ3glH2e`sppHNNBv>`֭[HH> oҤ 7fU.*W.{Iy۷Tep Z,ZR-YtϚ͂A2lT.Y,7+VO:5k,dz2 hڴ)( WаaW_`;8h c7݋jժ/ʚ,)d;0_sE8>'H˜IE>lMGUI,{[UK*jV3]h٬|"]+dbdܬX駟_|dɒ 0lwXF ȲsZ 4qR{ ֯XAjR#DC]_L m\M9gmrE9rjYc;6QZ2XlJO˥F}\E+Ʋ2H߂ L83I1[&͊e˖T ; `{{߿SkJ\ZJ?DѣG۱cǸ-l\z~rlrlEie8FU|yǏ{}S nZreY2)W|`+Y\R>2H3X Jnnn[lYva8a„#GZ N55uΝܾ}dɒs#Fܺu+1W^{\r͚5A+VرcG|8qD cҤI NJor㿉0@;-Zٳg١/^ :th.\޽{РA} >-[v%K܆\f(W~3<݀o+j(CKfk U)3g `0fΜyip`30QFn֬D)S?n׮m۶EO>ݹsgʕuѣG#1RrSNݻ7x([3۽jժm۶=z@HV߿hѢ/fcfʠrf+٧R7þd@vيlieV`f|Iby&Lr{{.)!Yw r7C~eePdfKKfk qTܠ 2hbX`RX5kz+J%7A㸹cdʥ'--,WiZCY.he8!qCGC 8!qChC+!qC8:VC8!qhe8!qCPVsaoo/~RJf qC8!,'ԖB0E8!qCYN+^!qC8rEW:!qC8U;w"::1_|I8!qC> -Z4%%r;C8!q+V&J8!qCo%ʜ` ADܗ+>2=[±c b,lEmba7-l:]H6Ɖ|-rI5,]ӒlيPQVϑ5 Y>1&(̨BQSgr_y" ~jRC)y&C _|"Zk\6Ą 2(j/om-{5ab^*-ߴjf\Mn _~051~7@U*la?4׎^$G?8gE;7(wnS]%NL-ՇKTcq|T'5Zcvͫ`L_RuUC-gS)M'n"*JVr7W+r)Roqӯ*,>}‡jVjLN5lAJ,@RɘK+F@ IwGCaڸ|<9Ygr:>a]Pn;&툟D}aĺK3,٫? x9FSRqK8y$ZT|կ\9=aeCa.;r˨_fvή+1Xu~Պ\[zZY\EfuV4]f횕@f+AZf5ƲןX};<)!)AS~!UڭM[-HY!:wU gzGta *VnY֥KrsZ:Mى ,U 4V̌cjИFJ&I|jE.+WʠƚյZ5lm6jV2[2[Z$JrUeWe }:01o|ЋS6[7DO-$ƏOL>OZVriV':WʥwfJKFիфDZ %;\Z.iV,V2 kgepĈOo޼O>eL+#9]?fϞ31lذ_377߸q#+6y .+AءCp%]]]2fA5?Jsџ@l?fŁ-x-RVziV$sWj/,\+6l@SN޽[zBAdc&ݢu֕+W1Vf? ٳ_|I>*]ɮ)AZ:t_ҥQ9P(VP-Zԭ[Q6D1nРw?u:U,@\cܣDbJ@K*!Q ZXX,[m?~ҥK---!JQ͈oRSS?~/_>ph׮]ll5jԬY3EUrʮqV||$!ŋHNN\ռ}vgΜ {.BÇƂ(nܸ(vlX ;loo/Z,ϰP2 k5j=}`"ZI=yjֳg={ן~wWN<v˗葓ӹs\+x1$$o߾ݻwVVVׯgt@@֭[TRÿ#G۷O$w\$x v1`pK Jogׯϭ g U8pIɺ}r劢I!~swuV?6!MR*xXݞ[_34Dߏ#+{y9_WQ OgK2&I+Hj@[+db\2[}@ GO9ZZcd\ַM^=,ľq(ULG>U;>fkYd,r2Hf?ծfne8jZ,+2ES&qf>wŅ%4âim~1ܔE<=ǨV2PgiV떫kU4ِhueP-:d2[%6WըQӓzfϪ_mʗnU=OΆVR>3/wD ]^[U64 ~!I[E+XoL٦,,N;WVjRQrwj3dtgkRq;̿M;>9>?.\:)x=(fU3fZUѬ*r>3Hff#^͒f Rll?{nVÇ>>>n*W\@@8(0ue˖!qիSSSޯ_?5k-Z*:tťwޣGFUTA \Q/_!&d7YB??"Eyuvz,,,du٠w.\ۻVZziiA߂ L/Ƙ mD7V_SLؤ+iJVHX*@kx9 sR(ZgxVߊ#^$ӝr1ƙroܹ^uYcͪV%Rr`mWVw6V%yOǙ"`*ț7/+ЧOUK>}4`aVޠA3g$%%5lJݺu (иqcDW8kt*W:qDܔRVٓ`ee !µzϟܸqK.3ⳝ;wP?{̙3Qg6s$(]4»UV5i҄ΔR;b&E=k!b?~|6l ClH[X2ZCl=a,u {eU2CYM̓?FY_0ؖOl"K\&qtwbjbፋBr3־6:_∼,~02}EwaQ\AA *?UD*Ċ]Vcر(H(XQ1x5y>>72 ޽m[[[Shhh= nDahSN׸ׯ_rrO>}zLLL -HHCJ Q',,Lk׮X UPa? TC1E 2dȐ!CF:3E 2dȐ!]F!C 2dȐɁҮܹ#ۊWի%K֭[mB7o Pr͛7_pMǣ}v"""ӧO;wn'?~o~Gggg,{ `ׯ_m6s\33pqqɔ ֙3g&&&*JbT/[Ab`Jbk^|dϟჼ NRu]|9r$H^ѣG۷o_}jŦMN:U^=`aN*Tڵ+<J裑43سgOlS03h,z*>kժ%1P gΜqttZI>4J\\LU 4HAڵKRWzVLfee%H=;`U {UWRj%K 5nXhQTThTQ =ѩS'85$5#B_~HD!4hw);+muɊSL5y޽V˗/P+SLv{+ujd:u8 fsfx%K]6♖-[ʋ-^r_}!*৴4ٷo_5k֔OܹsV &(Ċ&(HȩVn*TCq\,"ʕqn޼ ?.Sqp;x"ԕ7M6XR=r9bb.\PZY\Xn6Ќ...7 n6 bfP!C 前х2=#YYhҌDʓzVB~vuuKpttA̠vٲeW\6lҥK-ZLdTL( CӴ֪tׯgovƌWƍ29.Uէ`,3(`I2Ԑ,u "f͚ы9($IW{ 1D!D iӦzJ1isEWZFGG7h 矹:go%l۶ ѣׯ_ϞZ^L56lyvua⮑!y:t8qĮ]<9sf5D½[nih"((UV"c֭lٲ ͛[):L]A={tU*s5\ю;"UejjÇ˃ 믿nܸclf#K*<3z.x8P\vvv/_ϊ+8R<$٥KMz%ٳǏݶm[ԆSSSa5;w޽رcRy1_ަMI& 2d̘1"b΃ &LXjKwy[񌟟 <0#"=g7r d\`zӷo}#'''KKKxF͸HY_h\rIII ŋ'Nw/nzϺ13Hd k׮_^([lFT*| ޚ5kK;ѣNKKCDwo!}0=z7VReРA+rѓ۽?m޼1SP2zK03?䵛 5Lo5tJPRjYf S:Llː\Q-///eD[Ze9{f=`?}J5kVԩSsM[S#6HL1*& A 1FD\MA o A FFF\ɓ'e˖B2af wL1*g׭[uɓ'w1K :~-6Ə/ BDA0:03HJfرc&۷o(#ݻ7bĈtbŊm۶ZZ!Mc# ƹs缽MMM*Ǿh%""5ߺuK,h+_}||E˕+ː23H33Hh9p֭[$ 4g'|:u*Б#GĪO_V%`~ݻᠻw>fj(3g}a%OO˗5ƎۤI/˭f\`K5F] 3.ܺu ;vK.jjСr><<ԩSc`Ecb/_9[ ~wD\cժUkժUNzɯQ.^_7o.pЕ+W9r`_i& RK,o% i:7 fi\cdfTĂg^D#xp7NDcb'NlܸD`_]tink֬)VLKK/PDɈkz*>{{{3r}Af h֬BǏkNgb*^1U=lwEUjHQ5krڴiRW\tRThݻwS<3Z$ \Z1*f$tӧpݛ:uj2e6lؐҮ]ݻwn- w?|⭝jcw5EthZ"?~l2Ԇ# -k3 zQcBBBPPb^BFF)E*TTD \ws\~}Ϟ=ӹsg9{elw.>=)WM8c q03\Z`13 666sѿ|{5,&$6{8vVGG%M\Z1*f$ 222^|[nUX=I~3-#"f$ ӫTD$hh "TR2sf 2Dlr08ҒfKrTW13XXJ`4)2d !cDL62اaÆb53۷o!C 2dȐQ0ze)"/$!C 2dȐ!:3E 2dȐ!-]"C 2dȐџB]}A;wA 2dȐ!CF899>)))&Ȑ!C 2dșJ*dȐ!C 20\M 2dȐ!C`Lʕ(2dȐ!Cf 2dBDJ,fKb ^xA BN-fKl53hccӴiS|駟r¸̓@F\ f~$PKjO?Ag˵ \gǍw֭KLϞ=}||<<<ʔ)Sb{?vأG&M$įQlݺu-[F%JBhFDD̝;WѣGlț/**j„ ?~)yfqRP!v%8 cU 1Sfڿŋ˗/fJ,)5j>9F(0QO޽-[?@]a-Z899mٲ*22=AիWh6'*As .ľR%i`?00PQ*fL -++:u@Y^yз\jKʳ,g -kQgP jȑ#_~j*h(*wpp1$JKK~۷޽{! >|Tn𠠠T3fL ڶm+QM6mɥq%(<ygΞ=|r??ӧ|Ilmm+Vlݺnfbbbhjj!Ztt4<͛qG'G_k׮ +Wk޼Mr!V СCLbggSrNNN&f݇_h3\Z1FD\M,t@www8;͛m۶9::,ׯ_߶m_~_4ij*x(ci/ϟZX1|"H-_QCG'gϞ G*h2Ԑ3h$(J {rN Qn!<… ۗ'Lr W*n%9hL|:hРw}weCBBF%%OW6qKmèŋysr47t|P"S7LJO03H˥2j0^^^xʍ7ep (F#ͮpuuݽ{d={G*W%t?ؾ};Eׯ?gyjH̡CP#|fjպ>l陚z@Gys࢓wiذO)vr1"2pfpڴi{^.Vyt7lS{{{l֗_~+"W믿:88۷ov:x`Fdd9D')))Νȟ?>~ :_Q8cƌ/_q/^V\+TO0ٳgUT=ztΝ9Uȱm6Yf.]ZbsFDD pvv[O(… bl;aG%.]xȐ!041ۧRP'%\^"E0,?~۵k'i 4:bwww[[[׉'v؁/^xZZJoV\9 ri`ׯO:UkmoܸC}̒%KsH IJJ=v(/f͛;99AqO>]}޽SNa1c`ÑZxw(*.~ݲe VZ5jHOI]Uaee%qsfw8E˥2Xf… Z:ʘ n2d&;ӧO+ Q q$ņY[ɨ 2z\*#ԓf5Vի'vZ z ]xIf}n#-[ |*ԼIjdj5b}<2h}<|m֭+ -k3-z!CbbbJ*5yd/lvm2//), new LVM resources are created. Order and collocation constraints are created for those resources and new LVM resources to ensure proper start/stop order and resource placement. 7. Non-LVM EVMS2 Skip this in case you don't have EVMS2 resources. It is not possible to deal with this on a SLE11 system, so you should convert it to a compatibility volume on SLES10, which would turn the it into a LVM2 volume group. The CIB then should be modified accordingly. Enforcing conversion -------------------- There is a simple mechanism which prevents running the conversion process twice in a row. If you know what you are doing, it is possible to force the conversion using the -F option. After the conversion -------------------- Once the conversion has been finished, you may start the new cluster stack: # /etc/init.d/openais start (for SLE11 HAE >=SP1 too) or # /etc/init.d/corosync start Put resources back to the managed mode in case they were previously unmanaged. Backup ------ The conversion procedure also creates backup of all affected files. It is possible to revert to the version from the time of backup: # /usr/lib/heartbeat/hb2openais.sh revert Note that the revert process is executed only on the node on which the conversion took place. NB: hostcache and hb_uuid files (in /var/lib/heartbeat) are not removed. They are not used by Corosync/OpenAIS, hence, once you're content with the conversion, you may safely remove them. Affected files -------------- All file processing is done on the node where conversion runs. The CIB is the only file which is converted: /var/lib/heartbeat/crm/cib.xml The CIB is removed on all other nodes. The following files are generated: /etc/ais/openais.conf /etc/ais/authkey or /etc/corosync/corosync.conf /etc/corosync/authkey The following files are removed on all nodes: /var/lib/heartbeat/crm/cib.xml.sig /var/lib/heartbeat/crm/cib.xml.last /var/lib/heartbeat/crm/cib.xml.sig.last /var/lib/heartbeat/hostcache /var/lib/heartbeat/hb_uuid The Corosync/OpenAIS specific files are copied to all nodes using ssh. The CIB is automatically replicated by the CRM and it is not copied to other nodes. References ---------- http://www.clusterlabs.org/doc/en-US/Pacemaker/1.0/html/Pacemaker_Explained openais.conf(5) corosync.conf(5) pacemaker-master/doc/acls.txt000066400000000000000000000157621217637305600165540ustar00rootroot00000000000000Pacemaker Access Control Lists ============================== Tim Serong == Introduction The various tools for administering Pacemaker clusters (crm_mon, crm shell, cibadmin and friends, Python GUI, Hawk) can be used by the +root+ user, or any user in the +haclient+ group. By default, these users have full read/write access. Starting with Pacemaker version 1.1.5, flexible access control lists are introduced to provide different levels of administration to different users. == Prerequisites * Users are regular UNIX users, so the same user accounts must be present on all nodes in the cluster. * All user accounts must be in the +haclient+ group. * Pacemaker 1.1.5 or newer must be installed on all cluster nodes. * The CIB must be configured to use the pacemaker-1.1 or 1.2 schema. This can be set by running: cibadmin --modify --xml-text '' * The +enable-acl+ option must be set. If ACLs are not explicitly enabled, the previous behaviour will be used (i.e. all users in the +haclient+ group have full access): crm configure property enable-acl=true * Once this is done, ACLs can be configured as described below. * Note that the +root+ and +hacluster+ users will always have full access. * If nonprivileged users will be using the crm shell and CLI tools (as opposed to only using Hawk or the Python GUI) they will need to have +/usr/sbin+ added to their path. == Configuring ACLs Access control lists consist of an ordered set of access rules. Each rule allows read or write access or denies access completely to a part of the CIB. Rules are typically combined to produce a specific role, then users may be assigned to that role. It is also possible to configure ACLs directly for individual users. ACLs may be configured using the crm shell or the Python GUI. The shell syntax is documented here. Using the Python GUI should be reasonably straightforward once the concepts are understood. Note that rules are applied from first to last with the first matching rule being used. This means specific +write+ rules usually need to be listed before general +read+ rules. Any permission not explicitly granted is denied by default, but note that +write+ implies +read+, so there is no need to specicify both to allow full read/write access. === Minimum Required ACLs In order for the various tools to work correctly, a certain minimum amount of data must be readable by the user invoking the tool. In general, the safest thing to do is simply allow all users and roles read access to the entire CIB. === Role Syntax An ACL role is a set of rules which describe access rights to CIB. Rules consist of an access right +read+, +write+, or +deny+ and a specification denoting part of the configuration to which the access right applies. The specification can be an XPath or a combination of tag and id references. If an attribute is appended, then the specification applies only to that attribute of the matching element. ==== Usage ............... role rule [rule ...] rule :: acl-right cib-spec [attribute:] acl-right :: read | write | deny cib-spec :: xpath-spec | tag-ref-spec xpath-spec :: xpath: tag-ref-spec :: tag: | ref: | tag: ref: ............... ==== Example Role: Read-only Access ............... role monitor \ read xpath:"/cib" ............... This is a single rule which allows read-only access to the entire CIB. Users with this role will be able to view the status of the cluster, but not make any changes. ==== Example Role: ``Operator'' Access ............... role operator \ write xpath:"//crm_config//nvpair[@name='maintenance-mode']" \ write xpath:"//op_defaults//nvpair[@name='record-pending']" \ write xpath:"//nodes/node//nvpair[@name='standby']" \ write xpath:"//resources//nvpair[@name='target-role']" \ write xpath:"//resources//nvpair[@name='is-managed']" \ write xpath:"//constraints/rsc_location" \ read xpath:"/cib" ............... These rules specify that users with this role will be able to: . Turn maintenance mode on or off . Change whether pending operations are recorded . Put any node on standby, and bring any node back online . Start, stop, promote or demote any resource . Tell the cluster to manage, or not manage any resource . Migrate/move resources from node to note . View the status of the cluster Users with this role will not be able to reconfigure resources (change parameters, operations, etc.) or colocation or ordering constraints. ==== Example Role: Full Access ............... role administrator \ write xpath:"/cib" ............... This is a single rule which allows rull read-write access to the entirue CIB. Users with this role will have equivalent access to the +root+ and +hacluster+ users. === User Syntax ACLs can be defined for individual users using the same syntax as for roles. Alternately, users can simply be assigned a given role. The latter is considered best practice. ==== Usage ............... user {role:|rule [rule ...]} rule :: acl-right cib-spec [attribute:] acl-right :: read | write | deny cib-spec :: xpath-spec | tag-ref-spec xpath-spec :: xpath: tag-ref-spec :: tag: | ref: | tag: ref: ............... ==== Example ............... user alice role:monitor user bob role:operator ............... The above example assigns +alice+ the +monitor+ role and +bob+ the +operator+ role. == Advanced Usage Because ACLs can refer to elements and attributes in the CIB in a very granular way, it is possible to configure very specific rules. A refinement of the ``operator'' role above would be to allow manipulation of only a specific resource, for example: ............... role bigdb_admin \ write xpath:"//primitive[@id='bigdb']/meta_attributes/nvpair[@name='target-role']" \ write xpath:"//primitive[@id='bigdb']/meta_attributes/nvpair[@name='is-managed']" \ write xpath:"//constraints/rsc_location[@rsc='bigdb']" \ read ref:"bigdb" \ read xpath:"//nodes/node" uname \ read xpath:"//nodes/node" type \ read xpath:"//crm_config/cluster_property_set" \ read xpath:"/cib/status" ............... The first four rules are specific for the +bigdb+ resource. They allow modifying the +target-role+ and +is-managed+ meta attributes which effectively enables users in this role to stop/start and manage/unmanage the resource. The constraints write access rule allows moving the resource around. Finally, the user is granted read access to the resource definition. The bottom four rules are the absolute minimum read permissions necessary for proper operation of various Pacemaker tools, including `crm_mon` and the shell. This is fine for viewing cluster status, but there are some tools for which this will not be sufficient access (notably `ptest`), which is why it is generally recommened that read access be allowed to the entire CIB. pacemaker-master/doc/asciidoc.reference000066400000000000000000000015131217637305600205140ustar00rootroot00000000000000See also: http://powerman.name/doc/asciidoc Commands: `some-tool --with option` Files: '/tmp/file.name' Italic: _some text_ Mono: +some text+ Bold: *some text* Super: ^some text^ Sub: ~some text~ Quotes: ``double quoted'' `single quoted' Tool: command Literal: mono Varname: mono Option: italic Emphasis: italic bold Replaceable: italic mono .Title for Eaxmple ===== Some text ===== .Title for Eaxmple with XML Listing ===== [source,XML] ----- ----- ===== Naked code listing: (Use 'C' and a leading '#' instead of 'Bash' when commands are being show) [source,C] ----- # some command --here ----- Section anchors: [[s-name]] === Some Section Title === References to section anchors: <> or <>pacemaker-master/doc/cib-example-1.xml000066400000000000000000000071521217637305600201310ustar00rootroot00000000000000 pacemaker-master/doc/coding_guidelines.txt000066400000000000000000000055241217637305600213000ustar00rootroot00000000000000= Pacemaker Coding Guidelines = == Table of Contents == 1. Introduction 2. Formatting Guidelines 3. Naming Conventions 4. vim Settings == Introduction == The purpose of this document is to discuss guidelines about how to write code that will be a part of the Pacemaker project. == Formatting Guidelines == === Whitespace === - Indentation must be 4 spaces, no tabs. - Do not leave trailing whitespace. === Line Length === - Lines should be no longer than 80 characters unless limiting line length significantly impacts readability. === Pointers === - The '*' goes by the variable name, not the type: ``` char *foo; ``` - Use a space before the '*' and after the closing parenthesis in a cast: ``` char *foo = (char *) bar; ``` === Functions === - Put the return type on its own line: - Place the opening brace for a function on the next line: ``` static int foo(void) { ``` - For functions with enough arguments that they must break to the next line, align arguments with the first argument: ``` static int function_name(int bar, const char *a, const char *b, const char *c, const char *d) { ``` - If a function name gets really long, start the arguments on their own line with 8 spaces of indentation: ``` static int really_really_long_function_name_this_is_getting_silly_now( int bar, const char *a, const char *b, const char *c, const char *d) { ``` === Control statements (if, else, while, for, switch) === - Keyword is followed by one space, then left parenthesis witout space, condition, right parenthesis, space, opening bracket on the same line. - "else" and "else if" are on the same line with ending brace and opening brace, separated by space ``` if (condition1) { statement1; } else if (condition2) { statement2; } else { statement3; } ``` - Cases in switch statement have same indentation as switch. Body of cases is indented by one level. Opening brace is on the same line as switch. ``` switch (expression) { case 0: command0; break; case 1: command1; break; default: command; } ``` === Operators === - Operators have spaces from both sides. Do not rely on operator precedence, use brackets when mixing operators with different priority. - No space after opening bracked and before closing bracket. ``` x = a + b - (c * d); ``` == Naming Conventions == - Public C API calls and type names must begin with an API specific prefix, eg. "crm_", "pe_", "st_", "lrm_". == vim Settings == ```vim " This section contains settings that can be placed in the vimrc file that are " compatible with the Pacemaker coding guidelines. " Whitespace set ts=4 set sw=4 set expandtab let c_space_error=1 ``` pacemaker-master/doc/crm-flowchart.fig000066400000000000000000000275701217637305600203300ustar00rootroot00000000000000#FIG 3.2 Landscape Center Metric A4 59.40 Single -2 1200 2 6 1620 1665 2970 2430 2 4 0 2 0 7 50 0 -1 6.000 0 0 11 0 0 5 2925 2385 2925 1890 1845 1890 1845 2385 2925 2385 2 4 1 2 0 7 50 0 -1 6.000 0 0 11 0 0 5 2835 2295 1755 2295 1755 1800 2835 1800 2835 2295 2 4 1 2 0 7 50 0 -1 6.000 0 0 11 0 0 5 2745 2205 1665 2205 1665 1710 2745 1710 2745 2205 4 1 0 50 0 14 14 0.0000 4 120 360 2340 2115 RAs\001 -6 6 6255 2520 7785 3375 6 6345 2610 7695 3285 4 1 0 50 0 14 14 0.0000 4 135 840 7020 2745 Cluster\001 4 1 0 50 0 14 14 0.0000 4 135 1320 7020 3000 Information\001 4 1 0 50 0 14 14 0.0000 4 120 480 7020 3255 Base\001 -6 6 6255 2520 7785 3375 2 4 0 2 0 7 50 0 -1 0.000 0 0 11 0 0 5 7740 3330 7740 2565 6300 2565 6300 3330 7740 3330 -6 -6 6 7875 2520 8820 3150 6 7875 2520 8820 3150 2 4 0 2 0 7 50 0 -1 0.000 0 0 12 0 0 5 8773 3102 8773 2568 7922 2568 7922 3102 8773 3102 -6 4 1 0 50 0 14 14 0.0000 4 180 720 8348 2762 Policy\001 4 1 0 50 0 14 14 0.0000 4 180 720 8348 3037 Engine\001 -6 6 8910 2520 10665 2925 2 4 0 2 0 7 50 0 -1 0.000 0 0 11 0 0 5 10620 2880 10620 2565 8955 2565 8955 2880 10620 2880 4 1 0 50 0 14 14 0.0000 4 135 1440 9765 2790 Transitioner\001 -6 6 6480 1620 10305 2025 2 4 0 2 0 7 50 0 -1 0.000 0 0 11 0 0 5 10260 1980 10260 1665 6525 1665 6525 1980 10260 1980 4 1 0 50 0 14 16 0.0000 4 195 3600 8415 1890 Cluster Resource Manager\001 -6 6 7875 4725 9450 5130 2 4 0 2 0 7 50 0 -1 6.000 0 0 11 0 0 5 9405 5085 9405 4770 7920 4770 7920 5085 9405 5085 4 1 0 50 0 14 16 0.0000 4 150 1350 8685 4995 heartbeat\001 -6 6 8730 4095 9990 4455 2 4 0 2 0 7 50 0 -1 6.000 0 0 11 0 0 5 9945 4410 9945 4140 8775 4140 8775 4410 9945 4410 4 1 0 50 0 14 14 0.0000 4 180 1080 9360 4320 Messaging\001 -6 6 7200 3825 8640 4680 2 4 0 2 0 7 50 0 -1 6.000 0 0 11 0 0 5 8595 4635 8595 3870 7245 3870 7245 4635 8595 4635 4 1 0 50 0 14 14 0.0000 4 120 1080 7920 4050 Concensus\001 4 1 0 50 0 14 14 0.0000 4 135 840 7920 4305 Cluster\001 4 1 0 50 0 14 14 0.0000 4 180 1200 7920 4560 Membership\001 -6 6 12465 1575 13815 2340 2 4 0 2 0 7 50 0 -1 6.000 0 0 11 0 0 5 13770 2295 13770 1800 12690 1800 12690 2295 13770 2295 2 4 1 2 0 7 50 0 -1 6.000 0 0 11 0 0 5 13680 2205 12600 2205 12600 1710 13680 1710 13680 2205 2 4 1 2 0 7 50 0 -1 6.000 0 0 11 0 0 5 13590 2115 12510 2115 12510 1620 13590 1620 13590 2115 4 1 0 50 0 14 14 0.0000 4 120 360 13185 2025 RAs\001 -6 6 17325 1530 21150 1935 2 4 0 2 0 7 50 0 -1 0.000 0 0 11 0 0 5 21105 1890 21105 1575 17370 1575 17370 1890 21105 1890 4 1 0 50 0 14 16 0.0000 4 195 3600 19260 1800 Cluster Resource Manager\001 -6 6 18720 4635 20295 5040 2 4 0 2 0 7 50 0 -1 6.000 0 0 11 0 0 5 20250 4995 20250 4680 18765 4680 18765 4995 20250 4995 4 1 0 50 0 14 16 0.0000 4 150 1350 19530 4905 heartbeat\001 -6 6 19575 4005 20835 4365 2 4 0 2 0 7 50 0 -1 6.000 0 0 11 0 0 5 20790 4320 20790 4050 19620 4050 19620 4320 20790 4320 4 1 0 50 0 14 14 0.0000 4 180 1080 20205 4230 Messaging\001 -6 6 18045 3735 19485 4590 2 4 0 2 0 7 50 0 -1 6.000 0 0 11 0 0 5 19440 4545 19440 3780 18090 3780 18090 4545 19440 4545 4 1 0 50 0 14 14 0.0000 4 120 1080 18765 3960 Concensus\001 4 1 0 50 0 14 14 0.0000 4 135 840 18765 4215 Cluster\001 4 1 0 50 0 14 14 0.0000 4 180 1200 18765 4470 Membership\001 -6 6 18315 2115 19845 2970 6 18405 2205 19755 2880 4 1 0 50 0 14 14 0.0000 4 135 840 19080 2340 Cluster\001 4 1 0 50 0 14 14 0.0000 4 135 1320 19080 2595 Information\001 4 1 0 50 0 14 14 0.0000 4 120 480 19080 2850 Base\001 -6 6 18315 2115 19845 2970 2 4 0 2 0 7 50 0 -1 0.000 0 0 11 0 0 5 19800 2925 19800 2160 18360 2160 18360 2925 19800 2925 -6 -6 6 6750 8370 8010 9090 4 1 0 50 0 14 14 0.0000 4 120 1080 7380 8505 Concensus\001 4 1 0 50 0 14 14 0.0000 4 135 840 7380 8760 Cluster\001 4 1 0 50 0 14 14 0.0000 4 180 1200 7380 9015 Membership\001 -6 6 6300 9945 7830 10800 2 4 0 2 0 7 50 0 -1 0.000 0 0 11 0 0 5 6345 9990 6345 10755 7785 10755 7785 9990 6345 9990 -6 6 6390 10035 7740 10710 4 1 0 50 0 14 14 0.0000 4 135 840 7065 10170 Cluster\001 4 1 0 50 0 14 14 0.0000 4 135 1320 7065 10425 Information\001 4 1 0 50 0 14 14 0.0000 4 120 480 7065 10680 Base\001 -6 6 3240 1755 4905 2250 2 4 0 2 0 7 50 0 -1 6.000 0 0 15 0 0 5 4859 2222 4859 1783 3286 1783 3286 2222 4859 2222 4 1 0 50 0 14 14 0.0000 4 135 1320 4095 1980 Executioner\001 4 1 0 50 0 12 14 0.0000 4 165 1080 4095 2160 (STONITH)\001 -6 6 14085 1710 15750 2205 2 4 0 2 0 7 50 0 -1 6.000 0 0 15 0 0 5 15704 2177 15704 1738 14131 1738 14131 2177 15704 2177 4 1 0 50 0 14 14 0.0000 4 135 1320 14940 1935 Executioner\001 4 1 0 50 0 12 14 0.0000 4 165 1080 14940 2115 (STONITH)\001 -6 6 10485 10710 12150 11205 2 4 0 2 0 7 50 0 -1 6.000 0 0 15 0 0 5 12104 11177 12104 10738 10531 10738 10531 11177 12104 11177 4 1 0 50 0 14 14 0.0000 4 135 1320 11340 10935 Executioner\001 4 1 0 50 0 12 14 0.0000 4 165 1080 11340 11115 (STONITH)\001 -6 6 15300 4320 17415 4995 2 2 3 2 1 7 50 0 -1 6.000 0 0 -1 0 0 5 15345 4365 17370 4365 17370 4950 15345 4950 15345 4365 4 1 1 50 0 14 16 0.0000 4 150 1950 16380 4590 Adminstrative\001 4 1 1 50 0 14 16 0.0000 4 180 1050 16380 4875 request\001 -6 2 1 0 4 0 7 50 0 -1 10.000 0 0 -1 0 0 2 1350 6300 21600 6300 2 1 1 4 0 7 50 0 -1 10.000 0 0 -1 0 0 2 1845 6795 21780 6795 2 1 1 4 0 7 50 0 -1 10.000 0 0 -1 0 0 2 8775 6795 8775 5085 2 1 1 4 0 7 50 0 -1 10.000 0 0 -1 0 0 2 19755 4995 19755 6795 2 1 0 4 0 7 50 0 -1 10.000 0 0 -1 0 0 2 19350 6255 19350 4995 2 1 0 4 0 7 50 0 -1 10.000 0 0 -1 0 0 2 8415 6300 8415 5085 2 1 1 4 0 7 50 0 -1 10.000 0 0 -1 0 0 2 6750 7920 6750 6795 2 1 0 4 0 7 50 0 -1 10.000 0 0 -1 0 0 2 6390 7920 6390 6300 2 4 0 2 0 7 50 0 -1 6.000 0 0 11 0 0 5 5040 3195 5040 2880 1575 2880 1575 3195 5040 3195 2 1 1 2 0 7 50 0 -1 6.000 0 0 11 1 1 2 1 1 1.00 120.00 150.00 1 1 1.00 120.00 150.00 2430 2880 2430 2385 2 4 2 3 0 7 50 0 -1 2.000 0 0 11 0 0 5 5130 1620 5130 3285 1485 3285 1485 1620 5130 1620 2 4 2 3 0 7 50 0 -1 2.000 0 0 11 0 0 5 10710 3465 10710 1530 6165 1530 6165 3465 10710 3465 2 4 2 3 0 7 50 0 -1 2.000 0 0 11 0 0 5 10035 5175 10035 3780 7155 3780 7155 5175 10035 5175 2 4 0 2 0 7 50 0 -1 6.000 0 0 11 0 0 5 15885 3105 15885 2790 12420 2790 12420 3105 15885 3105 2 1 1 2 0 7 50 0 -1 6.000 0 0 11 1 1 2 1 1 1.00 120.00 150.00 1 1 1.00 120.00 150.00 13275 2790 13275 2295 2 1 1 2 0 7 50 0 -1 6.000 0 0 11 1 1 2 1 1 1.00 120.00 150.00 1 1 1.00 120.00 150.00 14850 2790 14850 2160 2 4 2 3 0 7 50 0 -1 2.000 0 0 11 0 0 5 15975 1530 15975 3195 12330 3195 12330 1530 15975 1530 2 4 2 3 0 7 50 0 -1 2.000 0 0 11 0 0 5 20880 5085 20880 3690 18000 3690 18000 5085 20880 5085 2 4 2 3 0 7 50 0 -1 2.000 0 0 11 0 0 5 21195 3015 21195 1485 17280 1485 17280 3015 21195 3015 2 4 2 3 0 7 50 0 -1 2.000 0 0 11 0 0 5 21375 5220 21375 900 12150 900 12150 5220 21375 5220 2 4 0 2 0 7 50 0 -1 6.000 0 0 11 0 0 5 10260 9810 10260 10125 13725 10125 13725 9810 10260 9810 2 1 1 2 0 7 50 0 -1 6.000 0 0 11 1 1 2 1 1 1.00 120.00 150.00 1 1 1.00 120.00 150.00 12870 10125 12870 10620 2 4 2 3 0 7 50 0 -1 2.000 0 0 11 0 0 5 10170 11385 10170 9720 13815 9720 13815 11385 10170 11385 2 4 2 3 0 7 50 0 -1 2.000 0 0 11 0 0 5 5265 7830 5265 9225 8145 9225 8145 7830 5265 7830 2 4 0 2 0 7 50 0 -1 6.000 0 0 11 0 0 5 5355 8595 5355 8865 6525 8865 6525 8595 5355 8595 2 4 0 2 0 7 50 0 -1 6.000 0 0 11 0 0 5 5895 7920 5895 8235 7380 8235 7380 7920 5895 7920 2 4 0 2 0 7 50 0 -1 6.000 0 0 11 0 0 5 6705 8370 6705 9135 8055 9135 8055 8370 6705 8370 2 4 2 3 0 7 50 0 -1 2.000 0 0 11 0 0 5 4725 7650 4725 11970 13950 11970 13950 7650 4725 7650 2 4 0 2 0 7 50 0 -1 0.000 0 0 11 0 0 5 5040 11025 5040 11340 8775 11340 8775 11025 5040 11025 2 4 2 3 0 7 50 0 -1 2.000 0 0 11 0 0 5 4950 11430 4950 9900 8865 9900 8865 11430 4950 11430 2 1 1 2 0 7 50 0 -1 6.000 0 0 11 1 1 2 1 1 1.00 120.00 150.00 1 1 1.00 120.00 150.00 11295 10125 11295 10755 2 4 0 2 0 7 50 0 -1 6.000 0 0 11 0 0 5 12375 10620 12375 11115 13455 11115 13455 10620 12375 10620 2 4 1 2 0 7 50 0 -1 6.000 0 0 11 0 0 5 12465 10710 13545 10710 13545 11205 12465 11205 12465 10710 2 4 1 2 0 7 50 0 -1 6.000 0 0 11 0 0 5 12555 10800 13635 10800 13635 11295 12555 11295 12555 10800 2 1 1 2 0 7 50 0 -1 6.000 0 0 11 1 1 2 1 1 1.00 120.00 150.00 1 1 1.00 120.00 150.00 4095 2925 4095 2295 2 2 3 2 1 7 50 0 -1 6.000 0 0 -1 0 0 5 12735 4185 14985 4185 14985 4815 12735 4815 12735 4185 2 4 2 3 2 7 50 0 -1 2.000 0 0 11 0 0 5 10935 5445 1305 5445 1305 855 10935 855 10935 5445 3 2 1 2 4 7 50 0 -1 6.000 0 1 1 3 1 1 1.00 120.00 150.00 1 1 1.00 120.00 150.00 7740 3150 14355 3780 18360 2790 0.000 -1.000 0.000 3 2 1 2 4 7 50 0 -1 6.000 0 1 0 2 1 1 1.00 120.00 150.00 10620 2745 12420 2970 0.000 0.000 3 2 1 2 4 7 50 0 -1 6.000 0 1 0 2 1 1 1.00 120.00 150.00 10125 2880 11250 9810 0.000 0.000 3 2 1 2 0 7 50 0 -1 6.000 0 1 0 3 1 1 1.00 120.00 150.00 7245 4365 5535 3375 6525 1845 0.000 -1.000 0.000 3 2 1 2 0 7 50 0 -1 6.000 0 1 1 2 1 1 1.00 120.00 150.00 1 1 1.00 120.00 150.00 5040 3060 6300 2925 0.000 0.000 3 2 1 2 0 7 50 0 -1 6.000 0 1 0 3 1 1 1.00 120.00 150.00 7245 4275 6930 4005 6930 3330 0.000 -1.000 0.000 3 2 1 2 0 7 50 0 -1 6.000 0 1 0 3 1 1 1.00 120.00 150.00 6975 2565 7740 2340 8325 2565 0.000 -1.000 0.000 3 2 1 2 0 7 50 0 -1 6.000 0 1 0 3 1 1 1.00 120.00 150.00 8325 2565 9000 2340 9765 2565 0.000 -1.000 0.000 3 2 1 2 4 7 50 0 -1 6.000 0 1 0 4 1 1 1.00 120.00 150.00 10035 2565 9450 2115 6480 2205 4905 2880 0.000 -1.000 -1.000 0.000 3 2 1 2 0 7 50 0 -1 6.000 0 1 0 3 1 1 1.00 120.00 150.00 18090 4275 16380 3285 17370 1755 0.000 -1.000 0.000 3 2 1 2 0 7 50 0 -1 6.000 0 1 1 2 1 1 1.00 120.00 150.00 1 1 1.00 120.00 150.00 15885 2970 18315 2565 0.000 0.000 3 2 1 2 0 7 50 0 -1 6.000 0 1 0 3 1 1 1.00 120.00 150.00 18090 4185 17820 3645 18405 2925 0.000 -1.000 0.000 3 2 1 2 0 7 50 0 -1 6.000 0 1 0 3 1 1 1.00 120.00 150.00 8055 8640 9765 9630 8775 11160 0.000 -1.000 0.000 3 2 1 2 0 7 50 0 -1 6.000 0 1 1 2 1 1 1.00 120.00 150.00 1 1 1.00 120.00 150.00 10260 9945 7830 10350 0.000 0.000 3 2 1 2 0 7 50 0 -1 6.000 0 1 0 3 1 1 1.00 120.00 150.00 8055 8730 8370 9000 7740 9990 0.000 -1.000 0.000 3 2 1 2 4 7 50 0 -1 6.000 0 1 0 5 1 1 1.00 120.00 150.00 6345 10575 3330 9765 2610 6165 3780 4095 6300 3060 0.000 -1.000 -1.000 -1.000 0.000 3 2 1 2 4 7 50 0 -1 6.000 0 0 1 5 1 1 1.00 120.00 150.00 6300 10305 4095 8460 3420 5850 4635 3825 6300 3195 0.000 -1.000 -1.000 -1.000 0.000 3 2 1 2 0 7 50 0 -1 6.000 0 1 0 3 1 1 1.00 120.00 150.00 8055 2610 7785 2475 7380 2565 0.000 -1.000 0.000 3 2 3 2 1 7 50 0 -1 6.000 0 1 0 4 1 1 1.00 120.00 150.00 16650 4365 17730 1755 13050 1350 10260 1800 0.000 -1.000 -1.000 0.000 3 2 3 2 1 7 50 0 -1 6.000 0 1 1 3 1 1 1.00 120.00 150.00 1 1 1.00 120.00 150.00 14940 4185 17730 1800 18810 2160 0.000 -1.000 0.000 4 1 0 50 0 14 16 0.0000 4 195 3300 3330 3105 Local Resource Manager\001 4 1 0 50 0 14 14 0.0000 4 120 720 5625 4050 Events\001 4 1 0 50 0 14 18 0.0000 4 240 4455 5850 1125 Designated Coordinator Node\001 4 1 0 50 0 14 16 0.0000 4 195 3300 14175 3015 Local Resource Manager\001 4 1 0 50 0 14 14 0.0000 4 120 720 16470 3960 Events\001 4 1 0 50 0 14 18 0.0000 4 240 5280 16650 1215 Any client node in the partition\001 4 1 0 50 0 14 14 0.0000 4 120 720 9675 8955 Events\001 4 1 0 50 0 14 16 0.0000 4 150 1350 6660 8145 heartbeat\001 4 1 0 50 0 14 14 0.0000 4 180 1080 5940 8775 Messaging\001 4 1 0 50 0 14 16 0.0000 4 195 3600 6885 11250 Cluster Resource Manager\001 4 1 0 50 0 14 16 0.0000 4 195 3300 12015 10035 Local Resource Manager\001 4 1 0 50 0 14 14 0.0000 4 120 360 13050 11025 RAs\001 4 1 0 50 0 14 18 0.0000 4 240 5280 9495 11700 Any client node in the partition\001 4 2 4 50 0 12 14 0.0000 4 120 720 2970 4920 status\001 4 2 4 50 0 12 14 0.0000 4 120 840 3105 4680 Gathers\001 4 0 4 50 0 12 14 0.0000 4 135 3000 10665 5940 Instructs and coordinates\001 4 0 4 50 0 12 14 0.0000 4 165 1200 3825 4905 Replicates\001 4 0 4 50 0 12 14 0.0000 4 165 1560 3735 5130 configuration\001 4 1 1 50 0 14 16 0.0000 4 150 1950 13860 4410 Adminstrative\001 4 1 1 50 0 14 16 0.0000 4 195 2100 13860 4695 status inquiry\001 pacemaker-master/doc/crm.txt000066400000000000000000000774261217637305600164200ustar00rootroot00000000000000DRAFT! DRAFT! DRAFT! DRAFT! DRAFT! DRAFT! DRAFT! DRAFT! DRAFT! DRAFT! DRAFT! NOTICE: Some ideas in this paper aren't yet well sorted. Some ideas aren't complete. Some phrasings I'm myself not happy with yet. Some ideas need further explanation. Most of the ideas presented are not final yet. It is mostly a braindump. And did I say yet that this is still a DRAFT!!!!!! ? Title: Design of a Cluster Resource Manager Revision: $Id: crm.txt,v 1.2 2003/12/01 14:10:14 lars Exp $ Author: Lars Marowsky-Bre Acknowledgements: Andrew Beekhof Luis Claudio R. Goncalves Fbio Oliv Leite Alan Robertson XX. Global TODO for this document In this section I keep track of tasks which I still want to perform on this document; probably of little interest to anyone else, and this section should be gone in the final version ;-) - Break out major parts (CIB, Policy Engine etc) into their own documents. - Add references to sub-features used and do not replicate too much information here. References should take the form of the feature id from the feature list. - Ensure unified use of words and terms when referring to the components. - Convert to docbook (not pressing) 0. Abstract This paper outlines the design of a clustered recovery/resource manager to be running on top of and enhancing the Open Clustering Framework (OCF) infrastructure provided by heartbeat. The goal is to allow flexible resource allocation and globally ordered actions in a cluster of N nodes and dynamic reallocation of resources in case of failures (ie, "fail-over") or administrative changes to the cluster ("switch-over"). This new Cluster Resource Manager is intended to be a replacement for the currently used "resource manager" of heartbeat. 1. Introduction 1.1. Requirements overview The CRM needs to provide the following functionality: - Secure. - Simple. heartbeat already provides these two properties; by no means may the new resource manager be more insecure. For sanity and stability - both of the developers, but in particular the users -, complexity needs to be kept at a minimum (but no simpler). - Support for more than 2 nodes. - Fault tolerant. (Failures can be node, network or resource failures.) - Ability to deal with complex policies for resource allocation and dependencies. Examples: - Support for globally ordered starting order, - Support for feedback in the allocation process to better support replicated resources, - Negated dependencies etc - Ability to make administrative requests for resource migration, adding new resources, removing resources et cetera while online. - Extensible framework. 1.2. Scenario description The design outlined in this document is aimed at a cluster with the following properties; some of them will be further specified later. - The cluster provides a Concensus Membership Layer, as outlined in the OCF documents and provided by the CCM implementation by Ram Pai. (This provides all nodes in a partition with a common and agreed upon view of cluster membership, which tries to compute the largest set of fully connected nodes.) - It is possible for the nodes in a given partition to order all nodes in the partition in the same way, without the need for a distributed decision. This can be either achieved by having the membership be returned in the same order on all nodes, or by attaching a distinguishing attribute to each node. - The cluster provides a communication mechanism for unicast as well as broadcast messaging. Messages don't necessarily satisfy any special ordering, but they are atomic. - Byzantine failures are rare and self-contained. Stable storage is stable and not otherwise corrupted; network packets aren't spuriously generated etc. These errors are self-contained to the respective components which take appropriate precautions to prevent them from propagating upwards. (Checksums, authentication, error recovery or fail-fast) - Time is synchronized cluster-wide. Even in the face of a network partition, an upper bound for time diversion can be safely assumed. This can be virtually guaranteed by running NTP across all nodes in the cluster. - An IO fencing mechanism is available in the cluster. The fencing mechanism provides definitive feedback on whether a given fencing request succeeded or not. - A node knows which resources itself currently holds and their state (running / failed / stopped); it can provide this information if queried and will inform the CRM of state changes. (This part will be provided by the Local Resource Manager.) 2.1. Basic algorithm The basic algorithm can be summarized as follows: a) Every partition elects a "Designated Coordinator"; this node will activate special logic to coordinate the recovery and administrative actions on all nodes in the cluster. a.1) The DC has the full state of the cluster available (or is able to retrieve it), as well as an uptodate copy of the administrative policies, information about fenced nodes etc; this shall further be referred to as "Cluster Information Base". b) Whenever a cluster event occurs, be it an adminstrative request, a node failure by membership services or a resource failure reported by a participating LRM, it is forwarded to the "Designated Coordinator". b1) For administrative requests, the DC arbitates whether or not they will be accepted into the CIB and serializes these updates. ie, policy changes which cannot be satisfied or would lead to an inconsistent state of the cluster will be rejected (unless explicitly overridden). c) It then computes via the Policy Engine: c.1) the new CIB c.2) The Transition Graph, an dependency-ordered graph of the actions necessary to go from the current cluster state as close as possible to the cluster state described by the CIB. d) Leading the transition to the target state: d1) Replicating the new CIB to all clients. d2) Executing each step of the transition graph in dependency order. (Potentially parallelized.) e) Exception handling if _any_ event or failure occurs: e1) The algorithm is aborted cleanly; pending operations are allowed to finish, but no new commands are issued to clients (in particular during phase d2) e2) The algorithm is invoked again from scratch. (It is obvious that there is room for optimization here by only recomputing smaller parts of the dependency tree or not broadcasting the full CIB every time, in particular if the DC has not been re-elected. However, these complicate the implementation and are not necessary for the first phase.) 2.2) Feature analysis This meets the requirements listed as follows: - It is reasonably simple to have a policy engine capable of dealing with more than two nodes as distributed decisions are avoided as far as possible; only a single node leads the transition and coordinates participating nodes. Local nodes are only required to know their own state; whenever the coordinator fails, the necessary state can simply be reconstructed by the DC. - An event can be anything from a failed node or a request to add a new policy rule (ie, a new resource, a change to an allocation policy etc); this satisfies the requirement to deal with adminstrative requests at runtime. - Support for new kinds of policies, types of resources, ... can be added via the policy engine. - The modular design keeps complexity in any single component down. 2.3. Stability of the algorithm This algorithm will eventually converge if no new events occur for a sufficiently long period of time. TODO: Add a discussion on factors affecting stability or kill the section entirely. 2.4. Components This approach neatly divides the task into various components: (see crm-flowchart.fig!) - Cluster infrastructure - heartbeat - Concensus Cluster Membership - Messaging - Cluster Resource Manager - Policy Engine - Cluster Information Base - Transitioner - Local Resource Manager - Executioner - Resource Agents 3. Local Resource Manager Note: This section only documents the requirements on the LRM from the point of view of the cluster-wide resource management. For a more detailled explanation, see the documentation by lclaudio. [ TODO: Add reference to lclaudio's document as soon as available ] This component knows which resources the node currently holds, their status (running, running/failed, stopping, stopped, stopped/failed, etc) and can provide this information to the CRM. It can start, restart and stop resources on demand. It can provide the CRM with a list of supported resource types. It will initiate any recovery action which is applicable and limitted to the local node and escalate all other events to the CRM. Any correct node in the cluster is running this service. Any node which fails to run this service will be evicted and fenced. It has access to the CIB for the resource parameters when starting a resource. NOTE: Because it might be necessary for the success of the monitoring operation that it is invoked with the same instance parameters as the resource was started with, it needs to keep a copy of that data, because the CIB might change at runtime. 4. Cluster Resource Manager The CRM coordinates all non-local interactions in the cluster. It interacts with: - The membership layer - The local resource managers - non-local CRMs - Administrative commands - Fencing functionality Only one node is running the "Designated Coordinator" CRM at any given time in any given partition. All other nodes forward their input to this node only, and will relay its decisions to the local LRM. The coordinator is a "primus inter pares"; in theory, any CRM can act in this fashion, but the arbitation algorithm will distinguish a designated node. 4.1. How to deal with failure of the designated CRM There are two major groups of failures here; if the entire node running the CRM fails, the underlaying membership algorithm shall take care of this. If the CRM logic fails, this shall be detected by internal consistency checks and local heartbeating to apphbd must stop immediately, effectively committing 'suicide' and providing a failfast mechanism. However, for now we will assume that the CRM does not fail. Coping with internal failures internally is always difficult. This can later be enhanced by providing 'peer monitoring' of the CRMs among eachother and initiating fencing if necessary; however this has many pitfalls and is not inherently better. 4.2. Election algorithm for the DC The election algorithm exploits the fact that there is a global ordering of the nodes in a given partition; it will simply select the first one. The node will know that it has been "distinguished" and take control. As the first action in the algorithm is to collect the status from all nodes, this will inform any node about the newly elected leader. Should any of them have been a DC until the new membership (in the case of cluster partitionings healing), he will cease operation and handover control in an orderly fashion. 4.3. Consistency audits The DC can perform a variety of consistency checks: - Exclusive allocation of resources - All nodes have the necessary Resource Agents for the resources which might be running on them - Adminstrative requests (ie, rule additions) can be rejected if it would prevent the policy engine from computing a valid target state Implementing any of the audits is optional. 4.4. Communication between the CRM and LRM - Every resource in the system is clearly identified in the CIB via a "UUID". This is the key passed around between CRM/LRM. (This avoids issues like with FailSafe, which used a "resource name / type" combination as the key; however, this made it very difficult to have, for example, two filesystems mounted at /usr/sap - production system and the test system - , because that is a key-clash. It is however a perfectly legal combination, as long as the resources are not activated on the same node; which can however be avoided by an appropriate negative dependency. Combined with "resource priority", the higher priority production system will push off the lower-priority test system and operation will continue) TODO: Protocol and channel need to be decided; based on the heartbeat IPC layer, wrapper library so they don't have to know all the gory details. AI lclaudio 4.4. Executing the Transition Graph It is also the task of the DC to execute the computed dependency graph. The graph will be traversed and evaluated in dependency-compliant order. Every node in the graph corresponds to a single action; the links between them correspond to the dependencies. Only nodes for which all dependencies have been satisfied will be executed; the CRM is allowed to parallelize these however. If a task cannot be successfully evaluated and has to be ultimately considered failed, this will be treated as a hard barrier - all currently pending tasks will run to completion, appropriate constraints added to the CIB (ie, "resource X cannot start on node N1", for example) and the graph execution will be aborted with a failure; this will escalate the recovery back to the higher level again. (ie, trigger a rerun of the recovery algorithm) TODO: This needs more thought. Especially the failure paths could simply be treated just as normal nodes in the graph, simplifying the logic here; and for some tasks where re-running the recovery algorithm is pointless, the Policy Engine could precompute alternate actions (like marking the resource hierarchy failed from that node upwards etc). Could be a possible future extension not implemented in v1.0. TODO: A pure dependency graph as outlined doesn't easily allow to express "OR" conditions, but only "AND". "OR" conditions might be helpful if a node could be fenced via multiple mechanisms, and if each one should be tried in order as a fallback; this could be implemented by allowing a node in the graph to be a _list_ of actions to be tried in order. 5. Cluster Information Base The CIB is also running on every node in the cluster. In essence, it provides a distributed database with weak transactional semantics, exploiting the fact that all updates are serialized by the DC and that each node itself knows its own latest status. 5.1. Contents of the CIB The CIB is divided into two major parts; the "configuration" data and the "runtime" data. a) The configuration part of the database is setup by the administrator. The configuration present on any given node is appropriately versioned; a combination of timestamps and generation counter seems sensible. Thus the most recent version available in a partition can always be clearly identified and selected. - Configured resources - Resource identifier - Resource instance parameters - Special node attributes - Administrative policies - Resource placement constraints - Resource dependencies b) Runtime information This includes: - Information about the currently participating nodes in the partition. - Resource Agents present on each node - Resources active on the node and their status - Operational status of the node itself - Fencing data - results: the timestamped result of a fencing request. - metadata: each nodes contributes the list of fencing devices available to it. TODO: Maybe this is part of the "static" configuration data? - Dynamic administrative policies and constraints: - Temporary constraints to deny placing a resource on a node, ie in response to failures etc. - Resource migration requests by the administrator. (These might be ignored by the policy engine if otherwise a consistent state cannot be computed or because they have a limitted life time, for example "until the node has booted again") The runtime data can be constructed by merging all available data in the partition by exploiting that every node holds authoritive data on itself. 5.2. Process of generating an uptodate CIB If necessary, the DC will retrieve the CIB from each node and compute the uptodate CIB from this data and broadcast the result to all nodes. The algorithm for merging the CIBs is rather straightforward: - Select the most recent configuration from all nodes. Note that this relies on the fact that an adminstrator has the wits to not force incompatible changes to separate cluster partitions; if he does, some configuration changes might be lost (or rather, overridden by the others), but that is a classical PEBKAC anyway. More complex merging algorithms could always be devised later for this step; the straightforward approach is to complain loudly about this problem as it can be clearly detected, and to also try to reject configuration changes in a degraded cluster unless forced. If any node in the cluster has a valid copy of the configuration, the cluster will be able to proceed. The case where this is not true is very unlikely; it requires at least a double failure to occur. The worstcase in this scenario is that some configuration changes might be reverted. - Merge the runtime data. - A node present in the partition is assumed to always have authoritive data on itself, its current status, resources it helds etc. This overrides any other data about it from other nodes. ("Normative power of facts" as opposed to rumours) - For nodes not present in the partition, their latest status can be identified from the partial information present on other nodes because it is timestamped. ie, it is possible to say whether they were cleanly shutdown, whether they have already been fenced cleanly or whether a fencing attempt has failed etc. - Update timestamps and generation counters as appropriate. - Commit locally and broadcast. 5.3. How are updates to the CIB handled? Any updates to the configuration will be serialized by the DC; they will be verified, committed to its own CIB and also broadcast to all nodes in the partition as an incremental update. Any updates pertaining to the runtime portion of the CIB can simply be broadcast to all nodes; the DC will receive them too, and all other nodes can save them for further reference so they will be available if the (new) DC needs to compute a new CIB. 6. Policy Engine 6.1. Functionality provided Even if only simple dependencies are supported at first (of the first two types, probably) which is straightforward to implement, the model can be easily extended. 6.1.1. Required constraints - To be started on the same node as resX after resX - To only be started on a node from the set {A, B, C} 6.1.2. Future extensions - To be started after resX, but without tieing them both to a given node, ie providing globally order - To NOT be run on the same node as resX (or generically, negated constraints) - To only be placed on a node with the attribute FOO (for example, connected to the FC-AL rack, or with at least XX mb of memory and others) 6.2. Thoughts about algorithm implementation The process of arriving at a target state / transition graph for the cluster from the set of rules and the current cluster state (basically, all information in the CIB is available) can be implemented by a "constraint solver". - Analyse dependency graph in the configuration; - Compute eligible nodes for each subtree (intersection of nodes configured for resources within a dependency subtree) - Order eligible nodes by priority, stickiness etc and select target node - All other eligible nodes either have to be part of the partition or must be fenced successfully. ... TODO: UNFINISHED TODO: Alternate implementation: Steal Finite Domain solver from GNU Prolog; steal constraint solver from http://www.cs.washington.edu/research/constraints/cassowary/ etc would allow policies to be expressed as intuitive constraints. Rather cool indeed. Evaluation. 6.4. Design considerations The following part should answer the most common questions regarding this approach: 6.4.1. Whether to deal with resource groups or "only" resources and dependencies? At the first glance, resource groups a la FailSafe are a welcome simplification. They can be treated as atomic units, resource allocation policy seems to become simpler, the CRM wouldn't even have to know about resources but simply allocate/reallocate resource groups. It seems natural to group resources in this fashion; all related resources are put into a resource group and done. However, it is also limitting. Resource groups become awkward if they stop being a logical mapping between resource and provided service; for example, the natural answer is to throw everything which should be running on a single node into a single resource group. If this becomes unnecessary later, resource group splitting is difficult. (Same for merging) Dependencies which spawn resource groups are also commonly requested; ie, a resource group should not run on the same node as a given other one. They are also cumbersome if one has to have a resource group for _everything_, even if it might only be a single resource or two. Then the abstraction gains little. Some decisions also spawn the boundary between single resources and resource groups, in which case the CRM has to know about both again. For example, the allocation policy of a resource group must be in line with how each resource itself can be allocated. In short, resource groups seem to fall short of easing bigger clusters and also lack some flexibility which can only be added at the expense of complexity. It seems more natural to me (by now) to only deal with resources and dependencies between them and to external constraints. I believe that in the end, both are just mindsets and that none is inherently harder to understand than the other, just one which is cleaner to implement. A very important point to keep in mind is that this document reflects the _internal_ representation of the configuration. An appropriate configuration wizard could (reasonably easily, although with limited features) present the user with a 'resource group'-style frontend. 6.4.2. Why a transition graph The dependency information in the graph will allow operations to be parallelized to speed up recovery. (All operations for which all requirements are satisfied can be carried out in parallel.) The graph is "global" (by virtue of being centralized at the DC) and thus even allows the possibility of "barriers"; ie, starting a resource only if a resource has been started on another node. 6.4.3. Who orders resource operations on a single node The LRM does not have enough information to order resource operations (start, stop etc) even for the local node, because it might - in theory - depend on non-local actions (resource operations, fencing etc). Only the transition graph as constructed by the DC contains such information. A possible optimisation here is that the DC transmits all operations which do not depend on external events as a single block to a given node, which can then proceed accordingly. Initially, just issueing the actions one by one shall suffice. 7. Executioner 7.1. Integration The Executioner is responsible for the fencing of nodes on request. It is a local component on each node and knows which fencing devices are available to it. This information is contributed to the CIB. On request of the CRM (relayed from the DC), it will carry out a fencing attempt and report the status back. The CRM might of course try to fence a given node from multiple nodes until one succeeds. See "executioner.txt" for details. 7.2. Fencing algorithm At the start of the recovery process, the CRM shall verify the list of devices reachable by each node; this shall be done as part of querying the current CIB from them. It will then retrieve the list of nodes fenceable via each device. If this list has already been retrieved in the past, it may be reused from cache appropriately. (Reloaded only when new nodes get added to the cluster, or something) For nodes which need to be fenced, appropriate dependencies will need to be added to the transition graph. These shall ensure that any given device is not concurrently accessed, and that fencing requests are appropriately retried on other devices if available. THOUGHT: Adding "meatware" as a ultima ratio fallback fencing would allow disaster resilient setups; if the one site failed completely, the administrator could flip the switch and the transition graph would proceed. This would neatly address this part of the requirements list. 7.3. Un-fencing Aborting an on-going fencing / STONITH operation is not supported. 7.3.1. After a successful fencing Okay, so a node has been fenced. How does it properly rejoin the cluster? For example, a node n1 can notice an unclean shutdown at startup, and must assume it has been STONITHed (in particular, if uptime very low ;-). When can it clear this flag and initiate recovery / startup actions on its own? The answer seems to relate to the "thought" under 6.2.; when is recovery action initiated for a resource group anyway. An additional option "Proceed if more than 50% of the nodes for the resource group are in our partition; if it is a tie, do not proceed to initiate recovery if the 'unclean' flag is set on any node." (This moves the unclean flag into the runtime portion of the CIB) The flag can be cleared once majority for all resources has been reached again. 7.3.2. Rejoining node while fencing requests are still pending Answer: Running fencing requests can not be aborted. In this rather unfortunate case, the node will most likely disappear soon because of the fencing request. Provisions might be made to consider this node as "down" already, to prevent resource pingpong. TODO: Ok, so n1 tried to fence n2 and vice-versa because of a partition, they failed via the STONITH device and have fallen back to meatware. The partition resolves. Shouldn't the system try to abort the meatware request? Maybe a special case for "meatware" requests? Or should meatware just notice this? 7.3.3. Rejoining node for which fencing has ultimately failed in the past Two options are basically possible; if a node has rejoined the cluster, the "fencing failed" flag could be cleared for it, and the cluster could proceed as normal. (This seems sensible) The other option would be to request the node to commit suicide. Again, this is difficult in the case of a resolving cluster partition; both sides would commit suicide. This doesn't seem sensible. If the failure was due to a local hang - ie, scheduler bug, power management running wild etc - this shall be considered outside the scope of this discussion. The local health monitoring on such a node shall be responsible for containing such failures and reacting to it appropriately. 8. Interaction with quorum TODO: Highly unfinished! Summary: CRM does not need quorum. However, the CRM could easily compute 'quorum' as just another resource. "Quorum" is in fact not necessary for this design. It is implicit in the policy engine / CRM which will only bring a resources for which all dependencies - including fencing - have been satisfied. This in fact is quorum with slightly finer granularity. It allows the cluster to proceed in a scenario like: - {a,b,c,d} form a cluster. {a,b} share resources (called R1) and {c,d} share resources (called R2). If the cluster is partitioned int {a,b} and {c,d}, no fencing has to carried out; cluster operation can proceed as normal. Of course, as soon as a global resource spawning {a,b,c,d} is added, this in fact translates to "global quorum". This makes me think that if global quorum is in fact required it can be best expressed in this design by mapping it to such a global ('configured on all nodes') resource and communicating to the partition that it has quorum if it was able to recover this resource (or failed to recover it, that is). However, it also allows for "sub-quorum"; ie, given the example of an application requiring quorum to operate, it will usually only be interested in quorum of the _nodes eligible for the related resources_. So quorum could potentially be different if reported to different clients... 8.1. Issues wrt quorum TODO: Certainly ;-) 10. Integration with other projects 10.1. Integration with heartbeat TODO: Elaborate. This component is supposed to replace the "resource manager" present in heartbeat currently. Issues which need to be addressed / kept in mind: - Start order; heartbeat should only join the cluster if the startup of CRM is successfully completed locally. - CRM makes extensive use of heartbeat's libraries (IPC, HBcomm, STONITH, PILS etc). ... 10.2. Integration with CCM TODO: Elaborate, if necessary. CRM is a client of CCM; CCM provides the set of nodes in the partition, CRM only operates on this data. It would be nice if CCM enforced policy before allowing a node to join a partition; ie, time not vastly desynchronized, CRM/LRM etc running and other ideas come to mind. 10.3. Integration with Group Services Should Group Services functionality - in particular, group messaging - be available one day, the exact semantics will of course have to be taken into account. The obvious simplification possible with this component would be that the CRM could form a distributed process group in the cluster; instead of building on top of node messaging primitives and filtering these. 10.4. Integration with non-heartbeat clusters In theory, the software should be able to run in any "compliant" environment; I'd safely assume that it should be reasonably easy to port on top of the Compaq CI, for example, or any Service-Availability Forum AIS. This would complement the respective feature lists as well as demonstrate that such interoperability is in fact possible, providing great leverage for OCF! TODO: Keep that in mind while designing the code. Encapsulate interactions with the lower levels cleanly. 10.5. Integration with cluster-aware applications Software like cluster-aware volume managers, filesystems or distributed applications (databases) need to be integrated into the 'recovery' tree just like Resource Agent based ones. This should be reasonably simple - because it is a matter of inserting the necessary trigger in the right order into the transition graph -, but these clients need to be aware that they don't need to provide any fencing themselves etc, because the external framework has already taken care of this. 10.6. Relation to OCF All applicable OCF specifications shall be implemented. Areas which OCF does not specify yet shall be implemented as prototypes, hopefully serving as a basis for OCF discussion. 11. Monitoring 11.1. Integration with health monitoring Health monitoring should prevent startup of cluster software on a "sick" node. ("Hey, I've rebooted 12 times within the last 60 minutes, maybe bringing the cluster software online wouldn't be so smart!") Should be handled by Local Resource Manager? Health monitoring can send events to DC: - I'm about to crash, migrate everything while you can - I'm overloaded, please migrate some resources if possible etc 11.2. Monitoring the CRM Monitoring software can query CIB to get access to all data. TODO: Should traps/events be triggered from inside the different components themselves, or might it be a good idea to allow clients to "subscribe" to certain parts of the CIB and be notified if a change occurs? This would be helpful for SNMP/CIM traps. (The later would be somewhat alike FailSafe's cdbd) XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX Attention: Here be dragons. Anything following these lines are unordered thoughts which haven't yet been incorporated into the grand scheme of things. XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX X. ... Question: Why isn't moving a resource to another node an basic operation? Answer: Because it involves more than one node and needs to be coordinated by the designated CRM. Question: How can this deal with disaster resilient setups, where one site may be physical separate and fencing the other side is not possible? Answer: See the "note" under "Hangman". pacemaker-master/doc/crm_fencing.txt000066400000000000000000000413221217637305600200730ustar00rootroot00000000000000Fencing and Stonith =================== Dejan_Muhamedagic v0.9 Fencing is a very important concept in computer clusters for HA (High Availability). Unfortunately, given that fencing does not offer a visible service to users, it is often neglected. Fencing may be defined as a method to bring an HA cluster to a known state. But, what is a "cluster state" after all? To answer that question we have to see what is in the cluster. == Introduction to HA clusters Any computer cluster may be loosely defined as a collection of cooperating computers or nodes. Nodes talk to each other over communication channels, which are typically standard network connections, such as Ethernet. The main purpose of an HA cluster is to manage user services. Typical examples of user services are an Apache web server or, say, a MySQL database. From the user's point of view, the services do some specific and hopefully useful work when ordered to do so. To the cluster, however, they are just things which may be started or stopped. This distinction is important, because the nature of the service is irrelevant to the cluster. In the cluster lingo, the user services are known as resources. Every resource has a state attached, for instance: "resource r1 is started on node1". In an HA cluster, such state implies that "resource r1 is stopped on all nodes but node1", because an HA cluster must make sure that every resource may be started on at most one node. A collection of resource states and node states is the cluster state. Every node must report every change that happens to resources. This may happen only for the running resources, because a node should not start resources unless told so by somebody. That somebody is the Cluster Resource Manager (CRM) in our case. So far so good. But what if, for whatever reason, we cannot establish with certainty a state of some node or resource? This is where fencing comes in. With fencing, even when the cluster doesn't know what is happening on some node, we can make sure that that node doesn't run any or certain important resources. If you wonder how this can happen, there may be many risks involved with computing: reckless people, power outages, natural disasters, rodents, thieves, software bugs, just to name a few. We are sure that at least a few times your computer failed unpredictably. == Fencing There are two kinds of fencing: resource level and node level. Using the resource level fencing the cluster can make sure that a node cannot access one or more resources. One typical example is a SAN, where a fencing operation changes rules on a SAN switch to deny access from a node. The resource level fencing may be achieved using normal resources on which the resource we want to protect would depend. Such a resource would simply refuse to start on this node and therefore resources which depend on it will be unrunnable on the same node as well. The node level fencing makes sure that a node does not run any resources at all. This is usually done in a very simple, yet brutal way: the node is simply reset using a power switch. This may ultimately be necessary because the node may not be responsive at all. The node level fencing is our primary subject below. == Node level fencing devices Before we get into the configuration details, you need to pick a fencing device for the node level fencing. There are quite a few to choose from. If you want to see the list of stonith devices which are supported just run: stonith -L Stonith devices may be classified into five categories: - UPS (Uninterruptible Power Supply) - PDU (Power Distribution Unit) - Blade power control devices - Lights-out devices - Testing devices The choice depends mainly on your budget and the kind of hardware. For instance, if you're running a cluster on a set of blades, then the power control device in the blade enclosure is the only candidate for fencing. Of course, this device must be capable of managing single blade computers. The lights-out devices (IBM RSA, HP iLO, Dell DRAC) are becoming increasingly popular and in future they may even become standard equipment of of-the-shelf computers. They are, however, inferior to UPS devices, because they share a power supply with their host (a cluster node). If a node stays without power, the device supposed to control it would be just as useless. Even though this is obvious to us, the cluster manager is not in the know and will try to fence the node in vain. This will continue forever because all other resource operations would wait for the fencing/stonith operation to succeed. The testing devices are used exclusively for testing purposes. They are usually more gentle on the hardware. Once the cluster goes into production, they must be replaced with real fencing devices. == STONITH (Shoot The Other Node In The Head) Stonith is our fencing implementation. It provides the node level fencing. .NB The stonith and fencing terms are often used interchangeably here as well as in other texts. The stonith subsystem consists of two components: - stonithd - stonith plugins === stonithd stonithd is a daemon which may be accessed by the local processes or over the network. It accepts commands which correspond to fencing operations: reset, power-off, and power-on. It may also check the status of the fencing device. stonithd runs on every node in the CRM HA cluster. The stonithd instance running on the DC node receives a fencing request from the CRM. It is up to this and other stonithd programs to carry out the desired fencing operation. === Stonith plugins For every supported fencing device there is a stonith plugin which is capable of controlling that device. A stonith plugin is the interface to the fencing device. All stonith plugins look the same to stonithd, but are quite different on the other side reflecting the nature of the fencing device. Some plugins support more than one device. A typical example is ipmilan (or external/ipmi) which implements the IPMI protocol and can control any device which supports this protocol. == CRM stonith configuration The fencing configuration consists of one or more stonith resources. A stonith resource is a resource of class stonith and it is configured just like any other resource. The list of parameters (attributes) depend on and are specific to a stonith type. Use the stonith(1) program to see the list: $ stonith -t ibmhmc -n ipaddr $ stonith -t ipmilan -n hostname ipaddr port auth priv login password reset_method .NB It is easy to guess the class of a fencing device from the set of attribute names. A short help text is also available: $ stonith -t ibmhmc -h STONITH Device: ibmhmc - IBM Hardware Management Console (HMC) Use for IBM i5, p5, pSeries and OpenPower systems managed by HMC Optional parameter name managedsyspat is white-space delimited list of patterns used to match managed system names; if last character is '*', all names that begin with the pattern are matched Optional parameter name password is password for hscroot if passwordless ssh access to HMC has NOT been setup (to do so, it is necessary to create a public/private key pair with empty passphrase - see "Configure the OpenSSH client" in the redbook for more details) For more information see http://publib-b.boulder.ibm.com/redbooks.nsf/RedbookAbstracts/SG247038.html .You just said that there is stonithd and stonith plugins. What's with these resources now? ************************** Resources of class stonith are just a representation of stonith plugins in the CIB. Well, a bit more: apart from the fencing operations, the stonith resources, just like any other, may be started and stopped and monitored. The start and stop operations are a bit of a misnomer: enable and disable would serve better, but it's too late to change that. So, these two are actually administrative operations and do not translate to any operation on the fencing device itself. Monitor, however, does translate to device status. ************************** A dummy stonith resource configuration, which may be used in some testing scenarios is very simple: configure primitive st-null stonith:null \ params hostlist="node1 node2" clone fencing st-null commit .NB ************************** All configuration examples are in the crm configuration tool syntax. To apply them, put the sample in a text file, say sample.txt and run: crm < sample.txt The configure and commit lines are omitted from further examples. ************************** An alternative configuration: primitive st-node1 stonith:null \ params hostlist="node1" primitive st-node2 stonith:null \ params hostlist="node2" location l-st-node1 st-node1 -inf: node1 location l-st-node2 st-node2 -inf: node2 This configuration is perfectly alright as far as the cluster software is concerned. The only difference to a real world configuration is that no fencing operation takes place. A more realistic, but still only for testing, is the following external/ssh configuration: primitive st-ssh stonith:external/ssh \ params hostlist="node1 node2" clone fencing st-ssh This one can also reset nodes. As you can see, this configuration is remarkably similar to the first one which features the null stonith device. .What is this clone thing? ************************** Clones are a CRM/Pacemaker feature. A clone is basically a shortcut: instead of defining _n_ identical, yet differently named resources, a single cloned resource suffices. By far the most common use of clones is with stonith resources if the stonith device is accessible from all nodes. ************************** The real device configuration is not much different, though some devices may require more attributes. For instance, an IBM RSA lights-out device might be configured like this: primitive st-ibmrsa-1 stonith:external/ibmrsa-telnet \ params nodename=node1 ipaddr=192.168.0.101 \ userid=USERID passwd=PASSW0RD primitive st-ibmrsa-2 stonith:external/ibmrsa-telnet \ params nodename=node2 ipaddr=192.168.0.102 \ userid=USERID passwd=PASSW0RD # st-ibmrsa-1 can run anywhere but on node1 location l-st-node1 st-ibmrsa-1 -inf: node1 # st-ibmrsa-2 can run anywhere but on node2 location l-st-node2 st-ibmrsa-2 -inf: node2 .Why those strange location constraints? ************************** There is always certain probability that the stonith operation is going to fail. Hence, a stonith operation on the node which is the executioner too is not reliable. If the node is reset, then it cannot send the notification about the fencing operation outcome. The only way to do that is to assume that the operation is going to succeed and send the notification beforehand. Then, if the operation fails, we are in trouble. Given all this, we decided that, by convention, stonithd refuses to kill its host. ************************** If you haven't already guessed, configuration of a UPS kind of fencing device is remarkably similar to all we have already shown. All UPS devices employ the same mechanics for fencing. What is, however, different is how the device itself is accessed. Old UPS devices, those that were considered professional, used to have just a serial port, typically connected at 1200baud using a special serial cable. Many new ones still come equipped with a serial port, but often they also sport a USB interface or an Ethernet interface. The kind of connection we may make use of depends on what the plugin supports. Let's see a few examples for the APC UPS equipment: $ stonith -t apcmaster -h STONITH Device: apcmaster - APC MasterSwitch (via telnet) NOTE: The APC MasterSwitch accepts only one (telnet) connection/session a time. When one session is active, subsequent attempts to connect to the MasterSwitch will fail. For more information see http://www.apc.com/ List of valid parameter names for apcmaster STONITH device: ipaddr login password $ stonith -t apcsmart -h STONITH Device: apcsmart - APC Smart UPS (via serial port - NOT USB!). Works with higher-end APC UPSes, like Back-UPS Pro, Smart-UPS, Matrix-UPS, etc. (Smart-UPS may have to be >= Smart-UPS 700?). See http://www.networkupstools.org/protocols/apcsmart.html for protocol compatibility details. For more information see http://www.apc.com/ List of valid parameter names for apcsmart STONITH device: ttydev hostlist The former plugin supports APC UPS with a network port and telnet protocol. The latter plugin uses the APC SMART protocol over the serial line which is supported by many different APC UPS product lines. .So, what do I use: clones, constraints, both? ************************** It depends. Depends on the nature of the fencing device. For example, if the device cannot serve more than one connection at the time, then clones won't do. Depends on how many hosts can the device manage. If it's only one, and that is always the case with lights-out devices, then again clones are right out. Depends also on the number of nodes in your cluster: the more nodes the more desirable to use clones. Finally, it is also a matter of personal preference. In short: if clones are safe to use with your configuration and if they reduce the configuration, then make cloned stonith resources. ************************** The CRM configuration is left as an exercise to the reader. == Monitoring the fencing devices Just like any other resource, the stonith class agents also support the monitor operation. Given that we have often seen monitor either not configured or configured in a wrong way, we have decided to devote a section to the matter. Monitoring stonith resources, which is actually checking status of the corresponding fencing devices, is strongly recommended. So strongly, that we should consider a configuration without it invalid. On the one hand, though an indispensable part of an HA cluster, a fencing device, being the last line of defense, is used seldom. Very seldom and preferably never. On the other, for whatever reason, the power management equipment is known to be rather fragile on the communication side. Some devices were known to give up if there was too much broadcast traffic on the wire. Some cannot handle more than ten or so connections per minute. Some get confused or depressed if two clients try to connect at the same time. Most cannot handle more than one session at the time. The bottom line: try not to exercise your fencing device too often. It may not like it. Use monitoring regularly, yet sparingly, say once every couple of hours. The probability that within those few hours there will be a need for a fencing operation and that the power switch would fail is usually low. == Odd plugins Apart from plugins which handle real devices, some stonith plugins are a bit out of line and deserve special attention. === external/kdumpcheck Sometimes, it may be important to get a kernel core dump. This plugin may be used to check if the dump is in progress. If that is the case, then it will return true, as if the node has been fenced, which is actually true given that it cannot run any resources at the time. kdumpcheck is typically used in concert with another, real, fencing device. See README_kdumpcheck.txt for more details. === external/sbd This is a self-fencing device. It reacts to a so-called "poison pill" which may be inserted into a shared disk. On shared storage connection loss, it also makes the node commit suicide. See http://www.linux-ha.org/wiki/SBD_Fencing for more details. === meatware Strange name and a simple concept. `meatware` requires help from a human to operate. Whenever invoked, `meatware` logs a CRIT severity message which should show up on the node's console. The operator should then make sure that the node is down and issue a `meatclient(8)` command to tell `meatware` that it's OK to tell the cluster that it may consider the node dead. See `README.meatware` for more information. === null This one is probably not of much importance to the general public. It is used in various testing scenarios. `null` is an imaginary device which always behaves and always claims that it has shot a node, but never does anything. Sort of a happy-go-lucky. Do not use it unless you know what you are doing. === suicide `suicide` is a software-only device, which can reboot a node it is running on. It depends on the operating system, so it should be avoided whenever possible. But it is OK on one-node clusters. `suicide` and `null` are the only exceptions to the "don't shoot my host" rule. .What about that stonithd? You forgot about it, eh? ************************** The stonithd daemon, though it is really the master of ceremony, requires no configuration itself. All configuration is stored in the CIB. ************************** == Resources http://www.linux-ha.org/wiki/STONITH http://www.clusterlabs.org/doc/crm_fencing.html http://www.clusterlabs.org/doc/en-US/Pacemaker/1.0/html/Pacemaker_Explained http://techthoughts.typepad.com/managing_computers/2007/10/split-brain-quo.html pacemaker-master/doc/executioner.txt000066400000000000000000000073621217637305600201610ustar00rootroot00000000000000DRAFT! DRAFT! DRAFT! DRAFT! DRAFT! DRAFT! DRAFT! DRAFT! DRAFT! DRAFT! DRAFT! NOTICE: Some ideas in this paper aren't yet well sorted. Some ideas aren't complete. Some phrasings I'm myself not happy with yet. Some ideas need further explanation. Most of the ideas presented are not final yet. It is mostly a braindump. And did I say yet that this is still a DRAFT!!!!!! ? Title: The Executioner Author: Lars Marowsky-Bre Acknowledgements: David Brower, Oracle Alan Robertson, IBM 1. Summary Every node runs an instance of the fencing daemon ("executioner"). This daemon knows which fencing devices are currently reachable and which nodes can be fenced by them - ie, the current topology of the fencing mechanisms - and will execute such requests on behalf of the CRM and report success or failure. A succesful fencing operation shall imply that the target node of the request can no longer access any shared resources in the cluster, until it has "properly rejoined the cluster". 2. Fencing topology information (Note: modelled after the STONITH model by alanr in heartbeat) 2.1. Static configuration data The mechanisms available for fencing need to be configured on each node. Provision should be made that this file can be the same on all nodes (to ease configuration deployment). It shall be made easy to configure a device for a list of nodes or all nodes. TODO: Can this configuration also be stored in the CIB configuration part? This would collide with the concept that every node is the authoritive source of information about itself. 2.2. Runtime topology Every device needs to support a low-latency "ping" operation, which shall verify whether it can currently be reached from the local node; this shall preferrably not be affected by concurrent access. The devices can either autodiscover their targets (ie, like via STONITH devices), or have to provide means of configuring this list; the list shall only be queried from the device on explicit request by the CRM. The CRM shall be allowed to assume that the same device can fence the same set of nodes for all clients. 3. Interaction with the CRM 3.1. Policies The CRM will be responsible for retrying failed commands; the Executioner shall only make exactly one attempt. It shall not retry the request on another device in particular; it is permissible to retry the command on the same device if it seems like an intermediate failure. 3.2. Queries/Commands issued 3.2.1. Device reachable The Executioner shall verify whether the given device is still reachable by the local node at this point in time. The verification shall be low-latency and low weight and allow for concurrent access from multiple nodes (if appropriate, ie for network switches). 3.2.2. Targets fenceable via device Y The node shall contact the device and return the list of nodes which it can fence. The CRM will ensure that no other node in the partition is accessing device Y right now. Results: 0 Success; list of targets included 1 Failed; device not reached 2 Failed; device failed to return list of targets 3.2.3. Fencing request to fence node X via device Y This is a blocking, synchronous call. The CRM will ensure that no other node in the partition is accessing device Y right now. (This is an issue for certain network powerswitches) The result code need to distinguish between: 0 Fencing request succeeded 1 Failed: device could not be reached, potential network issue 2 Failed: device tried, but failed to acknowledge success 3 Failed: interal device failure TODO: So much differentiation really necessary? Yes, it can help identify quickly whether it is sensible to retry the fencing request via another node to the same device, or whether the next fencing device should be tried immediately; maybe that is overkill. pacemaker-master/doc/index.php000066400000000000000000000063401217637305600167010ustar00rootroot00000000000000 pacemaker-master/doc/msg-schema.txt000066400000000000000000000145401217637305600176470ustar00rootroot00000000000000Background ################## First of all, go look at the diagram (comms.gif), read this, then look at the diagram again. Next, some terminology... Here I will use CRM to refer to the light blue section. That is, the entire collection of processes/daemons/modules on a node that, as a whole, manage resources in the cluster. CRMd refers to one of the dark blue boxes. It is the "master subsystem" if you like. Its role is to co-ordinate the actions of all the other pieces of the puzzle, including those on other nodes. Key points from the diagram: - All communications with the CRM are done with Heartbeat messages routed through the CRMd. These messages contain a text representation of an XML document, the schema of which is outlined at the end of this document. - All communications internal to the CRM (ie. between its subsystems) is performed with IPC messages. Again all messages are routed via the CRMd and contain the same XML documents as Heartbeat messages. - All admin clients (eventually) end up sending Heartbeat messages and are thus subject to existing HA client security is available. - The RPC layer allows the cluster to be controled from non-member hosts (subject to RPC security which is available for free). - The option of syncronous or asynchronous RPC calls will be provided. This will probably be in the form of a flag sent as part of the function call. Advantages: - The only source of "requests" is the CRMd which means it *never* has to forward on "request" messages for any of it sub-systems. This is useful for the security of the system (see security.txt). - Potentially, most CRM<-->CRM communications can be replaced with RPC calls. - We are able to re-use existing security mechanisms (IPC, HA, RPC, unix_auth via RPC) to protect the system. Message scenarios: ################## There are really only 3 messaging scenarios in this system (exluding broadcast vs. point-to-point). Again this is nice as it keeps down the number of "special cases". 1) Sub-system <--(IPC)--> CRM <--(IPC)--> Sub-system 2) Sub-system <--(IPC)--> Local CRM <--(Heartbeat)--> Remote CRM <--(IPC)--> Sub-system 3) Admin Client <--(Heartbeat Broadcast)--> Remote CRM <--(IPC)--> Sub-system Message examples: ################## 1.1) the DC telling the local LRM to start a resource 1.2) the LRM asking the CIB about a resource 2.1) the DC telling a remote LRM to start a resource 2.2) the DC asking (all) the CIB(s) to provide their view of the world 3.1) an admin request to add/remove/modify a resource 3.2) an admin request to force a failover of a resource or a recomputation of the resource dependancies. Message Notes: ################## Messages may be sent to the CRM from local sub-systems via IPC or from other HA clients via Heartbeat. It is then the responsibility of the CRM to unpack the message and pass it on to the correct sub-system. If the destination sub-system is the DC and the DC is not running on the current node, the message is discarded without error. Where the DC recieves a message from another node, it will also keep track of the sending host and the reference number so that it can direct the replies appropriately. The exception to this is where the message is from the DC. Messages to the DC are *always* sent as broadcast messages and the DC *must always* acknowledge the message with either the results of the message or a "thankyou" message. The reason for this is that the DC may change or a DC election may be in progress. The implication of this is that the sender should always set a timer and resend dc_messages if they have not been acknowledged. The DC will be able to detect duplicates by examining the destination sub-system and the reference number and we will rely on HA to ensure the delivery of DC responses. All messages are full crm_messages. I toyed with only sending the *_request or *_response piece of the message to and/or from the relevant sub-systems, but it just got messy. This way, the routing role of the CRM is much easier. And easier equals lower complexity, which means less bugs, which is good for everyone. Schema Notes: ################### Key Attributes =============== reference: provides the ability to track which request a responce is in relation to and where the local CRM should send it. *_filter: allow the operation to be limited to a particular type, id and/or priority timeout: allows the receiver to know how long the sender is expecting the task to take so we can act and report back accordingly. Attribute values ================= Where the list ends with |... , the complete list of possibilities will be fleshed out at a later date. Message Schema: ################### filter_type? #CDATA filter_id? #CDATA> pacemaker-master/doc/openstack.md000066400000000000000000000121161217637305600173700ustar00rootroot00000000000000# OpenStack CTS setup If we ever get the OpenStack networking sorted out to the point where Corosync can use it, this documents the process of getting a Pacemaker cluster set up for testing with CTS. ## Prep Install python-novaclient yum install -y python-novaclient Export your OpenStack credentials export OS_REGION_NAME=... export OS_TENANT_NAME=... export OS_AUTH_URL=... export OS_USERNAME=... export OS_PASSWORD=... export IMAGE_USER=fedora Allocate 5 floating IPs. For the purposes of the setup instructions (and probably your sanity), they need to be consecutive and to remain sane, should ideally start with a multiple of 10. Below we will assume 10.16.16.60-64 for n in `seq 1 5`; do nova floating-ip-create; done Create some variables based on the IP addresses nova created for you: export IP_BASE=10.16.16.60 and a function for calculating offsets function nth_ipaddr() { echo $IP_BASE | awk -F. -v offset=$1 '{ printf "%s.%s.%s.%s\n", $1, $2, $3, $4 + offset }' } function ip_net() { echo $IP_BASE | awk -F. '{ printf "%s.%s.%s.*\n", $1, $2, $3 }' } Upload a public key that we can use to log into the images we create. I created one especially for cluster testing and left it without a password. nova keypair-add --pub-key ~/.ssh/cluster Cluster Make sure it gets used when connecting to the CTS master cat << EOF >> ~/.ssh/config Host cts-master \`echo $IP_BASE | awk -F. '{ printf "%s.%s.%s.*", \$1, \$2, \$3 }'\` User root IdentityFile ~/.ssh/cluster UserKnownHostsFile ~/.ssh/known.openstack EOF Punch a hole in the firewall for SSH access and ping nova secgroup-add-rule default tcp 23 23 10.0.0.0/8 nova secgroup-add-rule default icmp -1 -1 0.0.0.0/0 Add the CTS master to /etc/hosts cat << EOF >> /etc/hosts `nth_ipaddr 0` cts-master EOF Create helper scripts on a local host cat << END > ./master.sh echo export OS_REGION_NAME=$OS_REGION_NAME >> ~/.bashrc echo export OS_TENANT_NAME=$OS_TENANT_NAME >> ~/.bashrc echo export OS_AUTH_URL=$OS_AUTH_URL >> ~/.bashrc echo export OS_USERNAME=$OS_USERNAME >> ~/.bashrc echo export OS_PASSWORD=$OS_PASSWORD >> ~/.bashrc function nth_ipaddr() { echo $IP_BASE | awk -F. -v offset=\$1 '{ printf "%s.%s.%s.%s\n", \$1, \$2, \$3, \$4 + offset }' } yum install -y python-novaclient git screen pdsh pdsh-mod-dshgroup git clone --depth 0 git://github.com/beekhof/fence_openstack.git ln -s /root/fence_openstack/fence_openstack /sbin mkdir -p /root/.dsh/group/ echo export cluster_name=openstack >> ~/.bashrc rm -f /root/.dsh/group/openstack for n in `seq 1 4`; do echo "cluster-\$n" >> /root/.dsh/group/openstack echo \`nth_ipaddr \$n\` cluster-\$n >> /etc/hosts done cat << EOF >> /root/.ssh/config Host cts-master \`echo $IP_BASE | awk -F. '{ printf "%s.%s.%s.*", \$1, \$2, \$3 }'\` User root IdentityFile ~/.ssh/cluster EOF END Some images do not allow root to log in by default and insist on a 'fedora' user. Create a script to disable this "feature": cat << EOF > fix-guest.sh #!/bin/bash # Re-allow root to log in sudo sed -i s/.*ssh-/ssh-/ /root/.ssh/authorized_keys EOF ## CTS master (Fedora-18) Create and update the master nova boot --poll --image "Fedora 18" --key_name Cluster --flavor m1.tiny cts-master nova add-floating-ip cts-master `nth_ipaddr 0` If your image does not allow root to log in by default, disable this "feature" with the script we created earlier: scp fix-guest.sh $IMAGE_USER@cts-master: ssh -l $IMAGE_USER -t cts-master -- bash ./fix-guest.sh Now we can set up the CTS master with the script we created earlier: scp ~/.ssh/cluster cts-master:.ssh/id_rsa scp master.sh cts-master: ssh cts-master -- bash ./master.sh ### Create the Guests First create the guests for n in `seq 1 4`; do nova boot --poll --image "Fedora 18" --key_name Cluster --flavor m1.tiny cluster-$n; nova add-floating-ip cluster-$n `nth_ipaddr $n` done Then wait for everything to settle sleep 10 ### Fix the Guests If your image does not allow root to log in by default, disable this "feature" with the script we created earlier: for n in `seq 1 4`; do scp fix-guest.sh $IMAGE_USER@`nth_ipaddr $n`: ssh -l $IMAGE_USER -t `nth_ipaddr $n` -- bash ./fix-guest.sh; done ## Run CTS ### Prep Switch to the CTS master ssh cts-master Clone Pacemaker for the latest version of CTS: git clone --depth 0 git://github.com/ClusterLabs/pacemaker.git echo 'export PATH=$PATH:/root/pacemaker/extra:/root/pacemaker/cts' >> ~/.bashrc echo alias c=\'cluster-helper\' >> ~/.bashrc . ~/.bashrc Now set up CTS to run from the local source tree cts local-init Configure a cluster (this will install all needed packages and configure corosync on the guests in the $cluster_name group) cluster-init -g openstack --yes --unicast --hosts fedora-18 ### Run cd pacemaker cts clean run --stonith openstackpacemaker-master/doc/pcs-crmsh-quick-ref.md000066400000000000000000000101331217637305600211610ustar00rootroot00000000000000## Display the configuration crmsh # crm configure show pcs # pcs cluster cib ## Display the current status crmsh # crm_mon -1 pcs # pcs status ## Node standby crmsh # crm node standby pcs # pcs cluster standby pcmk-1 crmsh # crm node online pcs # pcs cluster unstandby pcmk-1 ## Setting configuration options crmsh # crm configure property stonith-enabled=false pcs # pcs property set stonith-enabled=false ## Listing available resources crmsh # crm ra classes pcs # pcs resource standards crmsh # crm ra list ocf pacemaker pcs # pcs resource agents ocf:pacemaker ## Creating a resource crmsh # crm configure primitive ClusterIP ocf:heartbeat:IPaddr2 \ params ip=192.168.122.120 cidr_netmask=32 \ op monitor interval=30s pcs # pcs resource create ClusterIP IPaddr2 ip=192.168.0.120 cidr_netmask=32 The standard and provider (`ocf:heartbeat`) are determined automatically since `IPaddr2` is unique. The monitor operation is automatically created based on the agent's metadata. ## Start a resource crmsh # crm resource start ClusterIP pcs # pcs resource start ClusterIP ## Stop a resource crmsh # crm resource stop ClusterIP pcs # pcs resource stop ClusterIP ## Remove a resource crmsh # crm configure delete ClusterIP pcs # ## Update a resource crmsh # crm configure edit ClusterIP pcs # pcs resource update ClusterIP clusterip_hash=sourceip ## Display a resource crmsh # pcs # pcs resource show WebFS ## Resource defaults crmsh # crm configure rsc_defaults resource-stickiness=100 pcs # pcs rsc defaults resource-stickiness=100 Listing the current defaults: pcs # pcs rsc defaults ## Operation defaults crmsh # crm configure op_defaults timeout=240s pcs # pcs resource op defaults timeout=240s Listing the current defaults: pcs # pcs resource op defaults ## Colocation crmsh # crm configure colocation website-with-ip INFINITY: WebSite ClusterIP pcs # pcs constraint colocation add WebSite ClusterIP INFINITY With roles crmsh # pcs # ## Start/stop ordering crmsh # crm configure order apache-after-ip mandatory: ClusterIP WebSite pcs # pcs constraint order ClusterIP then WebSite With roles: crmsh # pcs # ## Preferred locations crmsh # crm configure location prefer-pcmk-1 WebSite 50: pcmk-1 pcs # pcs constraint location WebSite prefers pcmk-1=50 With roles: crmsh # pcs # ## Moving resources crmsh # crm resource move WebSite pcmk-1 pcs # pcs constraint location WebSite prefers pcmk-1=INFINITY crmsh # crm resource unmove WebSite pcs # pcs constraint rm location-WebSite-pcmk-1-INFINITY ## Creating a clone crmsh # configure clone WebIP ClusterIP meta globally-unique="true" clone-max="2" clone-node-max="2" pcs # pcs resource clone ClusterIP globally-unique=true clone-max=2 clone-node-max=2 ## Creating a master/slave clone crmsh # crm configure ms WebDataClone WebData \ meta master-max=1 master-node-max=1 \ clone-max=2 clone-node-max=1 notify=true pcs # resource master WebDataClone WebData \ master-max=1 master-node-max=1 clone-max=2 clone-node-max=1 \ notify=true ## ... crmsh # pcs # crmsh # pcs # ## Batch changes crmsh # crm crmsh # cib new drbd_cfg crmsh # configure primitive WebData ocf:linbit:drbd params drbd_resource=wwwdata \ op monitor interval=60s crmsh # configure ms WebDataClone WebData meta master-max=1 master-node-max=1 \ clone-max=2 clone-node-max=1 notify=true crmsh # cib commit drbd_cfg crmsh # quit pcs # pcs cluster cib drbd_cfg pcs # pcs -f drbd_cfg resource create WebData ocf:linbit:drbd drbd_resource=wwwdata \ op monitor interval=60s pcs # pcs -f drbd_cfg resource master WebDataClone WebData master-max=1 master-node-max=1 \ clone-max=2 clone-node-max=1 notify=true pcs # pcs cluster push cib drbd_cfg pacemaker-master/doc/publican-clusterlabs/000077500000000000000000000000001217637305600211745ustar00rootroot00000000000000pacemaker-master/doc/publican-clusterlabs/COPYING000066400000000000000000000000651217637305600222300ustar00rootroot00000000000000SETUP This file should contain your COPYRIGHT Licensepacemaker-master/doc/publican-clusterlabs/README000066400000000000000000000000001217637305600220420ustar00rootroot00000000000000pacemaker-master/doc/publican-clusterlabs/defaults.cfg000066400000000000000000000002171217637305600234640ustar00rootroot00000000000000# Config::Simple 4.59 # Thu Nov 12 09:56:27 2009 doc_url: http://www.clusterlabs.org/wiki/Documentation prod_url: http://www.clusterlabs.org pacemaker-master/doc/publican-clusterlabs/en-US/000077500000000000000000000000001217637305600221235ustar00rootroot00000000000000pacemaker-master/doc/publican-clusterlabs/en-US/Feedback.xml000066400000000000000000000020601217637305600243270ustar00rootroot00000000000000
We Need Feedback! feedback contact information for this manual If you find a typographical error in this manual, or if you have thought of a way to make this manual better, we would love to hear from you! Please submit a report in Bugzilla against the product &PRODUCT;. When submitting a bug report, be sure to mention the manual's identifier: &BOOKID; If you have a suggestion for improving the documentation, try to be as specific as possible when describing it. If you have found an error, please include the section number and some of the surrounding text so we can find it easily.
pacemaker-master/doc/publican-clusterlabs/en-US/Legal_Notice.xml000066400000000000000000000033171217637305600251760ustar00rootroot00000000000000 Copyright 2009-&YEAR; &HOLDER;. The text of and illustrations in this document are licensed under a Creative Commons Attribution–Share Alike 3.0 Unported license ("CC-BY-SA")An explanation of CC-BY-SA is available at . In accordance with CC-BY-SA, if you distribute this document or an adaptation of it, you must provide the URL for the original version. In addition to the requirements of this license, the following activities are looked upon favorably: If you are distributing Open Publication works on hardcopy or CD-ROM, you provide email notification to the authors of your intent to redistribute at least thirty days before your manuscript or media freeze, to give the authors time to provide updated documents. This notification should describe modifications, if any, made to the document. All substantive modifications (including deletions) be either clearly marked up in the document or else described in an attachment to the document. Finally, while it is not mandatory under this license, it is considered good form to offer a free copy of any hardcopy or CD-ROM expression of the author(s) work. pacemaker-master/doc/publican-clusterlabs/en-US/css/000077500000000000000000000000001217637305600227135ustar00rootroot00000000000000pacemaker-master/doc/publican-clusterlabs/en-US/css/overrides.css000066400000000000000000000012731217637305600254320ustar00rootroot00000000000000a:link { color:#0076d6; } a:visited { color:grey; } h1 { color:#172969; } .producttitle { background: #2C4081 url(../images/h1-bg.png) top left repeat; } .section h1.title { color:#2C4081; } h2,h3,h4,h5,h6 { color:#2C4081; } table { border:1px solid #732f2f; } table th { background-color:#2C4081; } table tr.even td { background-color: #e3e0d6; } #title a { height: 54px; } .term{ color:#172969; } .revhistory table th { color: #172969; } .edition { color: #172969; } span.remark{ background-color: #ffff00; } .example { border: 1px solid #732f2f; background-color: #e3e0d6; } .programlisting { border: 1px solid #732f2f; } .screen { border: 1px solid #732f2f; } pacemaker-master/doc/publican-clusterlabs/en-US/images/000077500000000000000000000000001217637305600233705ustar00rootroot00000000000000pacemaker-master/doc/publican-clusterlabs/en-US/images/1.png000066400000000000000000000026221217637305600242400ustar00rootroot00000000000000PNG  IHDR #ꦷbKGD X pHYsHHFk> vpAg HIDAThYALg~~`PnYHD-[(-&hb pZSwX6=aS{@t] 3)JElREMg L%Ev@os%?>?8Mm0 RO_3333έ=Nf]3\.R++++QG{{{;}xۖ J=`obbbbš!X$0GJR5a(PE`-p```yz04666=P|>ظ O8rJ$ _{l6e8:;;;od2ɞ'zU.܈/omnnn>+vX,D"47;GѼ"[Vkmrxbzu|||FFFF.W( K7A,l6-.TȖK'AEHP( ;SSSS0v,9888@! sud B} kkkk@6t5V5#k@٦<:YWh4e.={4wswwwm#s?g2L6-q*Tkuuu5tG՚ d]Yh]]]]pxQVR(1Wi7N֕5ӭ \~||| P)՛NRrq\n= k&PC|<''''r J`0O@m9#q}C\abI9O;hoHV/4{JPN3==myѕT___] )oz<O&d?~icvvvеFcO ~6L&%xܠkt p^\R,@텅@rDJRqF6qM"BK=J2 tC@A\?]tLJn`7 xVpM 0%tEXtdate:create2009-11-12T09:56:27+01:009*%tEXtdate:modify2009-11-12T09:56:27+01:00H]"gtEXtsvg:base-urifile:///mnt/Development/sources/pacemaker/publican/publican-clusterlabs/en-US/images/1.svgeKIENDB`pacemaker-master/doc/publican-clusterlabs/en-US/images/1.svg000066400000000000000000000013751217637305600242570ustar00rootroot00000000000000 1 pacemaker-master/doc/publican-clusterlabs/en-US/images/10.png000066400000000000000000000033721217637305600243230ustar00rootroot00000000000000PNG  IHDR #ꦷbKGD X pHYsHHFk> vpAg IDAThYILG}6`8`cpY\"aEnQDR @^85BzZ8pPp=@KNYŮ( '`zf!}|=̷s{\6/z#IiOOO ʖ?LIIIsp{(a xUYYY 87/,,,\\j@9pp8 yqqqP# f@" jxnnnnڏIz{{{}DN+J[`JR3333FxyO$x< q___BfҵZFJKKKK\`zۉ"H$&vuuuoz=py4e2 DĵaAAAsE,}~.*** 66669:----@\\ccc#b;qr^?;;;'oPIIII>gz|NyZp͛$ RTj;ᓸ~=###v->>>!9daY/l+Y@dtttxPŖ3+***#WCJLLL<bqVVVcF0L&B\.[wy tvvvg_v*㽕 pxz?6?kL;|pc??nN16`ݦ;gU(X, )loiozzz}ST@@@ AA+> wblZ($ϳ-2/3RR 0qtt0Z[&&&&//BbOXXyyy9^=NS˼aZ 7 x/IORf io|H6U"Qzzz:`4noooss5555V}/ KiP >U wtttrsssO!= ?Ko.0< qta١CKkMMMMQJU82+dZɫP l=]5и_uppp0͕ #5F^6/.{:000%R8ϴ4 G2i{~ojIg_ 9|nddd> Gzx )|Ɉ3yzԭ YAacppp ]Ǝ~'5eZe/[]i/ |5%tEXtdate:create2009-11-12T09:56:27+01:009*%tEXtdate:modify2009-11-12T09:56:27+01:00H]"htEXtsvg:base-urifile:///mnt/Development/sources/pacemaker/publican/publican-clusterlabs/en-US/images/10.svgvuNIENDB`pacemaker-master/doc/publican-clusterlabs/en-US/images/10.svg000066400000000000000000000014021217637305600243260ustar00rootroot00000000000000 10 pacemaker-master/doc/publican-clusterlabs/en-US/images/11.png000066400000000000000000000026431217637305600243240ustar00rootroot00000000000000PNG  IHDR #ꦷbKGD X pHYsHHFk> vpAg XIDAThKLcUƿv 5wXJu`I[UC" %Itո0 KXWB)7C% ãd$M&SxH{-Ý߶s9ߥFAW++++} @pkwwwFg@viii) hmmmowwww|ĽTKnؓ~}qhhhN V*À9P( [[[[ w/---qp> `t:kkkk=6gIKJJJ 3wf x<Gggg' -L&k$b]eoD]"H7Vv;`$p8*ֵjf _nwYxA"BPW####P(J[O#~xlL\. S-///l{rZVUI~wgjjjhb xFp3}d BRl=ր64BfUGNy H|>r}e brG;;;;|u8ˀ>WT*eqϑicyyy9r'jEEE d{$0+D".^]"Q*J@&(J$χ~3w_Ya(t:@B"wIv3Q!&"yʘ>HF{c :78nu%tEXtdate:create2009-11-12T09:56:27+01:009*%tEXtdate:modify2009-11-12T09:56:27+01:00H]"htEXtsvg:base-urifile:///mnt/Development/sources/pacemaker/publican/publican-clusterlabs/en-US/images/11.svgKgRIENDB`pacemaker-master/doc/publican-clusterlabs/en-US/images/11.svg000066400000000000000000000014021217637305600243270ustar00rootroot00000000000000 11 pacemaker-master/doc/publican-clusterlabs/en-US/images/12.png000066400000000000000000000034351217637305600243250ustar00rootroot00000000000000PNG  IHDR #ꦷbKGD X pHYsHHFk> vpAg IDAThYIL[W=6f&G qHn UL$$VDeCU fQnJ!cAEv`) ĐbAqL/_n1 88Qy<5aL _霶6====#}}}`i~hkkk p/O~ 4yK&,V6666W ڹ9% 8$EQ [,,,,s```xAuppp0 \>ruuud%xz3999`onnn^o<>%#VH$d~bX ,LG8l6p0\_ީ 9999@bRT7nOFFFF4퓒T* k.(%%%ESgܞĥf) BruuuuPXQQQ0 GzlwweeeI/nUUUU|~vvvv 3###CHMMMMQQdppºXYYY loϞ E___=/|q8RT <~r hVb 'OJC, 9;/ɲEJ8vv&&&&4\CK/I''|ZLOJ\.kOQffffgz_\offff) 5;;&;R(LpjPPPw8O%CJfw..d6W-2ғBFSփ5Slkkkkb@"yI x4h,)b'O"###riiix?ٙ[nnn.p! x1>>>~qpppxW9[[CCCC珯V Xm# ;E1L& >{{{{ױm8` EEEE34 ssU? r5ϗ.yyyyO`ߧqhpM``0 pjhj"=M#9lTcSSSS@Cr}x P Xoj:C1cuy:-@Z~AxLSUrsss 12 pacemaker-master/doc/publican-clusterlabs/en-US/images/13.png000066400000000000000000000035431217637305600243260ustar00rootroot00000000000000PNG  IHDR #ꦷbKGD X pHYsHHFk> vpAg IDAThYIL[W='L`0ɸ@ QAnX!TbX@ , h 15B Q@"2LHLb.^`D=9sG)0 @I4xgOOO]]]]ً?wP@x}0[.Uccc#EQQQ@vqqqD@60`0`;;;; #ٓZນ%0H.ˁg>?@ n~E2/K&>C]]]]\ETTT|VՆ#~_l6hooo/[offffTL !AR[****trB ikkkbbր} .nkkk J 1 888"OIIIєbҀ+)댌LLLL:׷ `x<O cc@g FDDDRiggg'`jJ`ϭ322240FFF'̡DM&\[2D{{ۀBQ\\\L?NɳyiÔvwwwxSSSS7NJ:888 &IH=::<<<X, \bnnn!NOhn}}Kxdܞ!- ma ~"F[*~NoC{$0VPgR/jjjj*ί}١ohjqvvv\4O T\oH8:::flw::::4HCo<#עo @w<,,, e^i;>g/g9||___ #}8/v2n覺.!]&0 B 0^L_cGcijT 1F&ϦX7%tEXtdate:create2009-11-12T09:56:27+01:009*%tEXtdate:modify2009-11-12T09:56:27+01:00H]"htEXtsvg:base-urifile:///mnt/Development/sources/pacemaker/publican/publican-clusterlabs/en-US/images/13.svg142IENDB`pacemaker-master/doc/publican-clusterlabs/en-US/images/13.svg000066400000000000000000000014021217637305600243310ustar00rootroot00000000000000 13 pacemaker-master/doc/publican-clusterlabs/en-US/images/14.png000066400000000000000000000031721217637305600243250ustar00rootroot00000000000000PNG  IHDR #ꦷbKGD X pHYsHHFk> vpAg /IDAThYKL[G=_ *>6@DmpXE`Q j*Z> E +E dlEv˦( Ғ_.U?\,ߛwy{sz X3888q|||kkkkyHR)pr?*** "݇ lP{OOO{xCCC \^^^fd@hiii4U6L&L@Kggg'p`~l4 ^}GG;|F xZPPPp8<<<qg- @АB=~bX=qvP*[[[[٠Hb֭@'OZ~nn倠tkkk9nTv `8DRRRRT*q§6rZ&VK L&c0x@ZZsss*^P___C$4 ,ɪ/H(zσ!;ϟlb@hlll_'೥%d h```}B")!!3;;;{$#u#'&&&@?BCCCj˯ p6 1^k nlllXL FZV+^Wh!!r\zPv a 3wwww}' \@ ϋ#ŘTYYYzܑ"&&&d*I$ 9mW񬮧5~^p/ Yaaas"H0ߋD@``\\\|?^WDNu: hQl iHBw4::::CWUWi#tm?111H6wwww;ZO])$t_ǻ%v4# ǓVFFFF:777^ ~%mpڞ5wsfQCp1ڇNNNNG<=>ޗ&TV]7C@;0a8$g:&LWeqe.xo%lα%tEXtdate:create2009-11-12T09:56:27+01:009*%tEXtdate:modify2009-11-12T09:56:27+01:00H]"htEXtsvg:base-urifile:///mnt/Development/sources/pacemaker/publican/publican-clusterlabs/en-US/images/14.svg"IENDB`pacemaker-master/doc/publican-clusterlabs/en-US/images/14.svg000066400000000000000000000014021217637305600243320ustar00rootroot00000000000000 14 pacemaker-master/doc/publican-clusterlabs/en-US/images/15.png000066400000000000000000000033531217637305600243270ustar00rootroot00000000000000PNG  IHDR #ꦷbKGD X pHYsHHFk> vpAg IDAThYIL[W= `h  )6n#a6p Pe$ FEH*. TP70Ӧ6C@i\ :C1]vbl,wywLw;n.H;b1L&׹ccccہ+yp*. 8jGIjlnj5DOggg ˷8&"tq 9@{tutttFH*R/E&RSk ȳ%)8w.555u֟޴FNӹRmmm-0;[QQQ(IIIIMMMMV≉?{6%%%}Vá++++`fH nnjuaaa! G )BaIII }xv*5NH$[mPPP1cYG03UхILC!!!!@ (...x<\.w|kF˻<GCo=D~~bXl;gΐÇe#/d 3ɓ@`{3   6mH{L?uJ$j|k*hݵ˦Jbbbb/Wr9)aw-hmeX, ((===)--- f3!w Fq޳焇VRL/Wү3333! ?'$$$_}"~+~&XGCAKAV___lI.PBfΆN6|+*** V5777[GOo([$uCKN,ju:t7?\&=] $|OJSj 15 pacemaker-master/doc/publican-clusterlabs/en-US/images/16.png000066400000000000000000000035621217637305600243320ustar00rootroot00000000000000PNG  IHDR #ꦷbKGD X pHYsHHFk> vpAg 'IDAThYIL[W=b8i0c0ZB0&JQ "M(n]P cA݄єy@ 1@0k˗k3ww6<@irlll f*zqqqQ才 `~7444ޏ|~?{h pXTΞ=<<<aQQQ1@h 3???y67AAAA@]]]]M HX,o&&&&g#~:KKKKs eGDDD|FD]]]]BYTTT@{:b ax0畜lKVVVT*_YYY w {{{{@L N B]IIII=GLZZZp)IP(t1<ܺUSSSTTTT ;94777kɩ06 \5@gFFFDZw5444\[]rܙ0K|>----^^kkkk!KMMMMRl)*???߰Ⴣ$4O.cJJJ fMmwW.ˁnu>,>o:ԗƟ_mtttJ$0o)YO(g$L+WD"H;Y^^^>'HFz:(o^Z; '_0.nkkk wobbb&g,KGҒ`08G;V*e2 JMMMf}\\\뇿_{heee䜧 ^$Ӏ{nnn0J3\.;osS*JWOW%O[qR`,,,,t>̣: 4@x{{$3ͧF]#)!T1]\@ />#Ѕ!ƂNgleOOOOl:9994<9999 xQ^^^h D둑QQT*`fİG)Tgoooǒ/ 3N-E%tEXtdate:create2009-11-12T09:56:27+01:009*%tEXtdate:modify2009-11-12T09:56:27+01:00H]"htEXtsvg:base-urifile:///mnt/Development/sources/pacemaker/publican/publican-clusterlabs/en-US/images/16.svg5BIENDB`pacemaker-master/doc/publican-clusterlabs/en-US/images/16.svg000066400000000000000000000014021217637305600243340ustar00rootroot00000000000000 16 pacemaker-master/doc/publican-clusterlabs/en-US/images/17.png000066400000000000000000000033271217637305600243320ustar00rootroot00000000000000PNG  IHDR #ꦷbKGD X pHYsHHFk> vpAg IDAThYIL[W=b̠Jvef m$J\EN XDLH tQQX"hUvb b*MYjC`Cj3@JqliL& ~w=Я)ހ?4H>=y~~~x\wp}DDD'JFfff&[PPP|4vp{#TWWWACCCpQzrNHHHSBqqq1@ŵ5@S^^^ffffN;P_*JDĜjZ h/{{{{gGm:bF2/ \4ܿVw߆C@ b z!OkZ-Mb$VUUUEQMkLլD"_BNs 2h~YYYp]ʕ6@.oiiix9Nk@` \`gVl),,,,8r;[߉o"FpBppp0]QQQEQ2)]r Ey`.W( DBD"C1u167l>)Z׼an1999 ^YYYa|nJiy<^ϴ"L&SSx+Cy{iii?!n1>WH&HP|WTTTL&;===k:[1cټC֤e(vZ[[[f+tg=QX ACzoz:o`h!G726ǝ :4#} YYYY/fggg?f j4 phˑgƇW''''e$WU'Άc2Ɓajwlll C2?H.Tfԓx_pƿ hɠ+%tEXtdate:create2009-11-12T09:56:27+01:009*%tEXtdate:modify2009-11-12T09:56:27+01:00H]"htEXtsvg:base-urifile:///mnt/Development/sources/pacemaker/publican/publican-clusterlabs/en-US/images/17.svgUIENDB`pacemaker-master/doc/publican-clusterlabs/en-US/images/17.svg000066400000000000000000000014021217637305600243350ustar00rootroot00000000000000 17 pacemaker-master/doc/publican-clusterlabs/en-US/images/18.png000066400000000000000000000036061217637305600243330ustar00rootroot00000000000000PNG  IHDR #ꦷbKGD X pHYsHHFk> vpAg ;IDAThYk,dg~ Vv}IJ62FR6/Q- VThBƽ2q v-nm6t0sz3Ŧϟ{}? i g壣&`뗞}h4:w΀񑝝` |t PUZ`Jvvv6 TSTpx< J4333tNIII,O0t_UVVV.COY?C⁁ TT*`8222a0 G0nL7)i`ZM\.OOOObcu:ut"WJeggg'E_ʎʕ7襾@oQ.Tp5:999د!@hiii <~1 DžXD 񌌌 @ bƍ\\\\<{bLy%_,///H-x]r>***ښe Amq0iC$"e0QHFH喿C<`o('=Ca>9ֱxd,FYc}d!d2<++~mmddd[eѼGGGG8onnnXYyyyy1KR)M⇡VR)=L2kBBBBP yq4/F9Lހzjjj]{{{{{MF (˾4av|||,(((߷zbbbPEH}&]I Λ=!zDcԂANEGIiʹk]PMMM zhғ+:3AnF7/~iݾfc·'i$'g amCCCC@@/o] P}W}}}}q?NoHOz"-/S] '3C5"t+oTelInG\J`|aߙ\r7~ _u`%tEXtdate:create2009-11-12T09:56:27+01:009*%tEXtdate:modify2009-11-12T09:56:27+01:00H]"htEXtsvg:base-urifile:///mnt/Development/sources/pacemaker/publican/publican-clusterlabs/en-US/images/18.svgF#IENDB`pacemaker-master/doc/publican-clusterlabs/en-US/images/18.svg000066400000000000000000000014021217637305600243360ustar00rootroot00000000000000 18 pacemaker-master/doc/publican-clusterlabs/en-US/images/19.png000066400000000000000000000035771217637305600243430ustar00rootroot00000000000000PNG  IHDR #ꦷbKGD X pHYsHHFk> vpAg 4IDAThYIL[W= Ay0c حV@$ADXjt-@YT] "Na (%v.^~jzv9wSځe<Osڀ?z{{{õ5D;8zDEEEqIIII^pXQ\\\ ]{K`iii)3bXW  [CCCCGX߄1'^^^^F`L&/DiiiiaKvg_ ^V썃#~G\. x=oooo7\Q/y ==ssssTP([**** 'bkH$DptHJ '''ktc.?3333`kkkKKKKK@$:(((Hṕ!b'g<(:;E"8>h4rsss G___eɸdMMMMO0222;$g'N߿&(U]]]03S^^^{{{{Mppp0Lig[ZZZ߫%㋊;>8HFwwDDDppr{~j5 OMMMfK>CK ;;dEaffoooOj\.מTcf3333M~j 𴵵 \X,SSSS]N cas@q\㹹ihJZ[[[뷿P7/-`~;88NEpx<=>p$'kFL_ׯI&79YPPP@w''''Ju yL]9L6[[[[P(KK$ߧ%R Z푌pwwwrNK&8pvvv6>a0///p>A 66? -mF绻vv--}|||Ś-u 3111pl3333Ow*u3#'''ptnb@,獏*~?_USpMu@@@`a=;;;l85,6J=>>:::8~⒚ ʊt(;;LYYYlX¦|Kxd;B3 @AvC[ߒ f GT*=N՝IWMp(#3Ԃurx,V+(?^S|u嗟]<<<<38zl::::fUvtttϜ H$ ga@{ܵՇ^S. h/[ g TjD(zzzzTeLO![J`\;>\r)%tEXtdate:create2009-11-12T09:56:27+01:009*%tEXtdate:modify2009-11-12T09:56:27+01:00H]"htEXtsvg:base-urifile:///mnt/Development/sources/pacemaker/publican/publican-clusterlabs/en-US/images/19.svg{e,IENDB`pacemaker-master/doc/publican-clusterlabs/en-US/images/19.svg000066400000000000000000000014021217637305600243370ustar00rootroot00000000000000 19 pacemaker-master/doc/publican-clusterlabs/en-US/images/2.png000066400000000000000000000032431217637305600242410ustar00rootroot00000000000000PNG  IHDR #ꦷbKGD X pHYsHHFk> vpAg YIDAThY]L[e~- BA~CU"ɮ0r!^KĨ72ïcB `X¤l^|;6;.{iy9>uxK 6/<O_ffffś󻣣G6lccc񭀀;;===^PPP\ȼS&,wuuu^ڗKIddd$EEEE(7Z]]]dI[T@<2L>>ܿkbuuuul{{d N`r#"""qy Adz_\llllzF1<===MF|w\ZZZԱ\> oo>7]t*JUQ"*\.q x1999t_immme.2cg0Z\. ^+ރY!羾;uu9????uZNN{RRRR~}}}x/&||||t:}ƻA[!/LQl6 w]\cLPPP |.~>6ry^^^7===:z/$$$8Ct}L!%(D"RZ@TTT/y*A %IIII P\AJ)b.ǛM; SP(dNwhs4, i"Ǜ _XXXhtSvbbbtl6[1c-ya㶶6]s7-PDBkUG( @d=@%4͕Р=6CCCC&3ݠÀZFFF}2$Z~&68mO5 B$ݤK47RBC,/[%8}2d Cz@鶶,̑ 嘇qg2N&;%tEXtdate:create2009-11-12T09:56:27+01:009*%tEXtdate:modify2009-11-12T09:56:27+01:00H]"gtEXtsvg:base-urifile:///mnt/Development/sources/pacemaker/publican/publican-clusterlabs/en-US/images/2.svg"1)IENDB`pacemaker-master/doc/publican-clusterlabs/en-US/images/2.svg000066400000000000000000000013751217637305600242600ustar00rootroot00000000000000 2 pacemaker-master/doc/publican-clusterlabs/en-US/images/20.png000066400000000000000000000040241217637305600243170ustar00rootroot00000000000000PNG  IHDR #ꦷbKGD X pHYsHHFk> vpAg IDAThYKLTgf`)@[- D] j +hZXtQؔ"j"eD"Jy802sC鷙;s?+)kmZrR wfq @ٳgU#7/`,ٰa.yǎ;{ |zy֭[W?&]uuu50RXXXTɓ'O@<~1sobbbb @ <ܷo>؇s*7777 39!MMMMϩ𯹹sF++++ @f?C8pߡCɝ@FNz^$'߻w痕oT*@z4{74qdg(/()hr\NQUUw`FF\r)#;;;W>|ajP([nݢ(ja}*--->U*JFO{BPp[wlll,8w@sӅ .o߾ȁ3gΜ&&'OJKKK/Z[[[|;w n۶meGGG02RWWW0R)6vڀ.]tnV6ZPPPW$ݍ#` byy1ÇGh8:JR)}C%+#O:u Z@ D m4 %222߼!g0999/gO}@y~ͅCOM.' Myƍ7J*R趫T*\]Zmyyy9_$rrrrZ:"#?L~ l^ybB,-qЗ#k]!KPhmmmgn㣣wjݺu뀰'Nz-===]zFyr\~z;,7,XZZZ--$tr[gtEINNNᑔYD i,}Xzyyyc>}fҦTv߹sz;&9;;;/&g:0s@o2HLJϟgސLF*B>\t';vNNaaaa MJ$>f/={x"/g/jpurˋȑ# FSTTTd~## \#]CGG^z\\d2 s>ݴi&@e˖-9z||pW]x"x:###c rq\\\`͛7o;CwحPa,쐳={,0ns My !^"H`uUUU3z+DO6a z&9Nnkz֠xF@=>>>|%² W2$mF뗥aٽ=Wh@J v2Ғ[ +2zC"t/ZZZZʸ>Q]f'[.`Juá%tEXtdate:create2009-11-12T09:56:27+01:009*%tEXtdate:modify2009-11-12T09:56:27+01:00H]"htEXtsvg:base-urifile:///mnt/Development/sources/pacemaker/publican/publican-clusterlabs/en-US/images/20.svg 20 pacemaker-master/doc/publican-clusterlabs/en-US/images/21.png000066400000000000000000000034401217637305600243210ustar00rootroot00000000000000PNG  IHDR #ꦷbKGD X pHYsHHFk> vpAg IDAThYIL[W=6f&G qH0T*D + EJ7@%Pn";aP&15!2.^ql}G>P=cc 40 `mlllܯVVVVZ[[[Ȑ8? /u K ڕf~~~pUwwww콋DEQ-...giiiic```pAu``` >QSSS8}| >JRͤ$۶uqO pdଡ଼ D"K}? 5.uBWϔ&q0333 HLT*J 2rlll  3222t'$egggݸQZZZ"5.3 @/ncSSSSd\.g'VWWWhnnn.p/pVeee% feee1p8|>ܾ][[[ mnnnpܥM@WzzzH%А****qӲ2@.Uᑗ|>2|6ySM BԔjÔ'H sl3333Հ2YUUU 2t^ X}d5?/*LdNj;F8>kiii \^TTT($^__|||5mC/b)pǏ#"""byyyk#?KNNNp!<>111alt| ٧mjOOLLL =<<O/탃lg>}tH=?[ {ߓIpX\2byp!MڈPȻj4wDRn`] /[}:U Њ%tEXtdate:create2009-11-12T09:56:27+01:009*%tEXtdate:modify2009-11-12T09:56:27+01:00H]"htEXtsvg:base-urifile:///mnt/Development/sources/pacemaker/publican/publican-clusterlabs/en-US/images/21.svǵIENDB`pacemaker-master/doc/publican-clusterlabs/en-US/images/21.svg000066400000000000000000000014021217637305600243300ustar00rootroot00000000000000 21 pacemaker-master/doc/publican-clusterlabs/en-US/images/22.png000066400000000000000000000032561217637305600243270ustar00rootroot00000000000000PNG  IHDR #ꦷbKGD X pHYsHHFk> vpAg cIDAThY],dg~eZf7fl߬PiȆ4d4uQhZ.I/M7"-2Q0C"ֈݱ;fыoONvәa~v9s3}:{ psuބg I xx(V p>b;!4448xe17 k/u)@',uuuu TIddd$EEEE(ᱶ^CKt_v '<<< (d2T\\\ p1 @d^bJR`\c%n+.GjTiiii|~eee%T*@aNEEz^dg|~EEE(rrIII 3E-=/+++K49(}t Hdn*5555Kqqqq----_UUU8 C"H=5 /u,+f>!!!d,[ //>gZJr>*T0@wC./8\hmmmu>Dq _aadf\.88 9jAäszxxxh{pZVgg''''))))N</&jZݻA|blì,%L?N$TWWWW@GFrrrrOc CLPPPl=/ccI*1BBBBLL=bD별X, H%g QQQQ1n˼bEPujIRRRe)]]1k / })sTJGOB^7m8 ~,4C' NLLL:롻KFXsޡv~A 8~\eq~("^%Ԣ# RXO踄z2uC~y:4hMcF2<<< nddddX'CL gbAoƠBPI6h%Ī7RnbX^usɐ9 mD4####14v6Gjv2cVxS֟ DHb=p[%tEXtdate:create2009-11-12T09:56:27+01:009*%tEXtdate:modify2009-11-12T09:56:27+01:00H]"htEXtsvg:base-urifile:///mnt/Development/sources/pacemaker/publican/publican-clusterlabs/en-US/images/22.svg!o,IENDB`pacemaker-master/doc/publican-clusterlabs/en-US/images/22.svg000066400000000000000000000014021217637305600243310ustar00rootroot00000000000000 22 pacemaker-master/doc/publican-clusterlabs/en-US/images/23.png000066400000000000000000000041131217637305600243210ustar00rootroot00000000000000PNG  IHDR #ꦷbKGD X pHYsHHFk> vpAg IDAThmLSW&HQ % l-)h hbBL>,h!q.1_|F!DEE f[һǓ^[rNy8ss+`ހ/E q2 )}s˗/}m`Q gי~'<===ׯt Jddd@0#@џ;wQYWWWmԘ-dT~ѣ@rKfff& @ ,Ǐ?jvڵ pjjjj?m1666Hn++++|~~~~[@,@xcttt)>sD"_T%'''kjjj?ҀE&ɴpĺ\( ?JRoQ7====@OΝ;wrݽ{n 5z 3h4<|}ssssE+V]v زehhhؾbXtNbI|||;y;v`Mj2LIB`J̿ իW2LU՚5k0ݻǕVٳg^ cidblVJR-``e2_űz5ϟ?8y57776doӧOcc'N:ܹs\PPAAAwĄFZ-Ԩ|9H$Rr:{ŋ84 8pmŧH*Ύ]\ٱ4666+ݮd lzp -Q8yرc^jŋ/fVl6cٳgπ"z͍;?9iÇ@G_7.]tɶ`{qvemCwI 23 pacemaker-master/doc/publican-clusterlabs/en-US/images/24.png000066400000000000000000000034771217637305600243360ustar00rootroot00000000000000PNG  IHDR #ꦷbKGD X pHYsHHFk> vpAg IDAThY[,g~12eu`LWvVVj48elD:$^4F4Q Aef:feu5BŎA?wvf]{{c=\5ؗ uzzzX >>~y AMXXX  0@T*G7RSSSNΛ#~'mNNNNoKRk`"@P(ڸ8#~s85^_,///ˢt&q '''ffffdVrNdY@ 6"I 5l[ppmmm-д4E/,22224Fa7666Laaa!`oܼwsKIII$D{m@gVVVd{?!jCCC7777<~\___h4####{~~EEEEg,---++++g0::: <(6JJJJ Otp@]籿????O?x>>>>+WBuuu5ժj5ʊ~>==9991]KK.Ⲳ2@*///7]]\\\|tuuu>>RT .(ww.dHÀĩv-444]njjj?L&3s1^Qͅl6;IG}ooaok*,y8GGGG:jt{IIIIcK ʈuՠDBvbl`` 666j􏣂e)Ϟ"H*/^F*՜w~~~>PSSS rYX=5E{T?H:<ozԾ(qcqz͍;I# U!ܺJgl  iA T @ay8^ ^bbτ!****0O( g[[bjoď`~ppp03:0(((~2CH]lTQX8666vt7IBwH4777Ǟ|>մ Zg 5M v 24 pacemaker-master/doc/publican-clusterlabs/en-US/images/25.png000066400000000000000000000037721217637305600243350ustar00rootroot00000000000000PNG  IHDR #ꦷbKGD X pHYsHHFk> vpAg IDAThkLg-cRB"% ؈pPb˒I`XƇe/*de #P1&Һr/$@*BPjRi݇7 0˛<9,xOak g@Nׯ/vǏܯFGGG-̟ݲe59...wG7o߾} ZOx`d~bbb[02L&ɀ_SSSS)yO.jjjj0nZ?3|>[Q}け qqdܳg&$aaAcU|pWST*Kp GF$~j*I<^@@@޾}6P$'''3bnqsss>x͊R)apb޽{Dq2=O,56mJkeo^^^^$Uٳ&Eb-L3G/-{1nݺuIFt:̘H?~ 3333m?~sQjscP(n T}LDEUVVV, φ hU gxxf|~_(-2@_ZZZ©SN1D&H$ F#zjx\VرcWW????RPΜ9sCDX-d&f")^"#KKKK;|}>|x$22YLLL@L̼ Bí#H14wA+W?;`(*%E̺[ZZZZ1\"rEz67Dŋ/~@j1C˹[JzLMSD(@DgKb$KE4#z$5"58 K{IjJW5JR 8J/Ƶ݇ѐD\mm3?Ir5eblAw`FaRP(ѣGlI:G\N`l];\{U%tEXtdate:create2009-11-12T09:56:27+01:009*%tEXtdate:modify2009-11-12T09:56:27+01:00H]"htEXtsvg:base-urifile:///mnt/Development/sources/pacemaker/publican/publican-clusterlabs/en-US/images/25.svg8<IENDB`pacemaker-master/doc/publican-clusterlabs/en-US/images/25.svg000066400000000000000000000014021217637305600243340ustar00rootroot00000000000000 25 pacemaker-master/doc/publican-clusterlabs/en-US/images/26.png000066400000000000000000000041151217637305600243260ustar00rootroot00000000000000PNG  IHDR #ꦷbKGD X pHYsHHFk> vpAg IDAThYYLTWFq3;8JA$ B@4M틡,e(,## ΰ(5~/ss;{Lih{w ԙ t_,++++kkkkM)####AfONNNN]v,Î9r;yI_xkT*]aaa!0ڵk󼾾Tp_~:xx @mٳgrٳgˊStyyyyThV*JX@x|||)nkkkk+b?͊*`爈`_ssss!mBp,///7Q@SNΟ? ST* :Z逘^ž222 miiibbfgggHbqAA>|H$r\\U@gΜ9i4 { azffhhh"wSr`}s@&KJJJ/JKKK>P*IThmMNNNo,-}3!!!c(9c޼ikkk?}m@gyxכI$ 흙_X W [V" Q8}ƍxffffxqq~~~=ĉ'7ʼ`t)~vt'wo`i)dxb=oB`33'G'H "@wn/gEV盛ܹs'3#'5999 +%'g*S׋E *@ ŀVKj tjZ 46>}4Rg(xyyy~~ـCTTT $@pիWVPcǎ޽^Okh r)_QF 77nKu/}} x@Ԅ:˗/_rjZfD"{Dwww73޺umU"[F..$A jj=zx)qRPK2a'Etppp0]m ($,?~8>~h4KX|ug+fgIg {Yyh!x|>djݻwLD-an"T*r{ bw"TŮ@`eeeXYyxxx5h*$Ѳ a#u7o޼i\Nb4ڳgbKooo/Ʊ'.ɡ+===.\pؼX)iiiiheee%{ff 纺L BC!Mi||+...3W@)19я=z="wo;\`nFeT_+445I....{sAAAz'WEت =6KL3rAOM_Tط#(((i{c7.eeXu-@ j'7v8V@'äŕ&-/SM k2ځMػ6[.S {`|*(k%tEXtdate:create2009-11-12T09:56:27+01:009*%tEXtdate:modify2009-11-12T09:56:27+01:00H]"htEXtsvg:base-urifile:///mnt/Development/sources/pacemaker/publican/publican-clusterlabs/en-US/images/26.svgIENDB`pacemaker-master/doc/publican-clusterlabs/en-US/images/26.svg000066400000000000000000000014021217637305600243350ustar00rootroot00000000000000 26 pacemaker-master/doc/publican-clusterlabs/en-US/images/27.png000066400000000000000000000036501217637305600243320ustar00rootroot00000000000000PNG  IHDR #ꦷbKGD X pHYsHHFk> vpAg ]IDAThY[LSgR:f ^hM - p qbd}Baa0m/% L0Pn@Qnk+PA{ryrl+(3^|>y|m z d@VWɓ';hϳJR@ig7ןjG5XC_r xkYYYSÇ맨ۈ 8̙3gU_vvv6@(jڧs vD@5P[[[ tZٓn̼?X'ŀ T*; @[h_޿6Ͷq;be@ aC kX,f:2ucǎcahfyjZl{]jy>;.D"a>u=3 έ9ѣGoL&=00999 h4l[{VWWW2Ǐ ڟӀ;///n8 j^zZ*ٳ~`|0EFsˡi^?qeeqqq0/^xY~GGGpׯ{@dziiik_ __!HP(VDԤT*[QQQQckkZZZ@Q< .]ĭܛp"WwgϞ=k_9GP]9G WTTT/_~X X,0po L7npm e2_( ;N8q0V\"Kmmmmk7ض-!!!^_SSS㹼P|????h#=XWˉ^k]aH$fR}TW QezZܗzIg!v>}]ю#G\JSSSS__+pٵՠRIV|>hn>t! sy EQQQG]vmuKx.(< 27 pacemaker-master/doc/publican-clusterlabs/en-US/images/28.png000066400000000000000000000042121217637305600243260ustar00rootroot00000000000000PNG  IHDR #ꦷbKGD X pHYsHHFk> vpAg ?IDAThY]LY "FW( VF1هu5>6[~bU4QXXbA#VJUimt[e2q(k{i3{9#&)>>&] rIKrrrr>A4 ݯyyyyv>s D5444[7` 6ڲe@V((l6@ =[.ڵk׀1WzU 00%%% G&Ҧ_~=EyAqI9N'Er9E֒ٮ:JRQxҥKظhѢEѱ}l֭[\(JpX, 3kΝ;)f`g479s ooooNWQQQ'N8xq̼͛R|dƍ7B?[Ǐ3^^+|j5psq } ޽{7㣣3p<űDq>222LJ.V#{߽{СCժ////t8aH$BX,KǏq```_b;.|}g=`8}i0ff\"Q( 4TT*qd2ԩSK$,*l] u͞ƌUUUUJS<+˗_L2>|`|h4+%~wB&+***B????d"}8gܹs\RLEBHK#ւ(ޮ=8 ɓ'Sw;(((XS׭[ HJڻw^gΜ9sI4K @Ҽ5k֬n(}~9WhG=@"!i зV[^^^ί?>rϟܻw©ɑJI'1q׮]YZc`Ç=?6_bOBzٳ@1' U2r򶶶v}XO$|whgՀ}D"̴[: DHf5LڮٺeoaS iF4OZe˲ݗ`*K 'ӟ{4HFÔk_'-`IWS|'2*֓΅2C7"/ZZZZTe\ƨn}_T LRŋO`?Y O?%tEXtdate:create2009-11-12T09:56:27+01:009*%tEXtdate:modify2009-11-12T09:56:27+01:00H]"htEXtsvg:base-urifile:///mnt/Development/sources/pacemaker/publican/publican-clusterlabs/en-US/images/28.svgwIENDB`pacemaker-master/doc/publican-clusterlabs/en-US/images/28.svg000066400000000000000000000014021217637305600243370ustar00rootroot00000000000000 28 pacemaker-master/doc/publican-clusterlabs/en-US/images/29.png000066400000000000000000000041541217637305600243340ustar00rootroot00000000000000PNG  IHDR #ꦷbKGD X pHYsHHFk> vpAg !IDAThYkLSg~J rGQݮFA PbQC\@,c[2&%!lXIf2a ıJ@AH[ɑN?w}综#^)\VڀhR <>f{]O> y߇֭[xeܹs' '/?&cuuu50ٳg3qttt4"p SP(`й?zrYQf$?~=?6ӧܹsi=ǵ qvZr8!0b--{8K.]ɌI"Dcnn|||e`- ^ (hݻ={H&9,^gv pdaI]aÆ f ӷl!eJ;'2d2n9N1>ȯ.}u`]H# U_~BHHzUyo2c//X,fZV)Mڵk;_eɦzqN(&gOLLL <.}t&&&&bFԩSylll_!# 5...0b19d2Ymmm-kIG>t!`h_in͛I3F~@s\MMM 0i|Tݸq]NNN"rqjjj*M[[[J 29 pacemaker-master/doc/publican-clusterlabs/en-US/images/3.png000066400000000000000000000033541217637305600242450ustar00rootroot00000000000000PNG  IHDR #ꦷbKGD X pHYsHHFk> vpAg IDATh[Lwǿh(VZ/8/Td[5z|蓋1{X6}uɲd&ަiLS`ĩ!z6j-2!2D}sΗ90^8gs/| O1`n{{{;~xuuu`....3|/=////=!...*SSSS pt Pꛚ?=JKKKV}~b<###``0 aG_NNNNBH\xaېF")(((0 BCCC}t"5Ǣ 3 " $´PNKKK֡$.s,2E|FtDFFFWVVV/d2O K( jAaQ5|r载rbbbp'Ojjjj|ǿ8p8M;Lm //R<{M=.W*JM5F^7vsϏ# 8~LJ>b1)Md럻xU_:~W$N { " \wuelǓrӧ$_ҫ)))) 2ҥPMr+Pӕg_:,8nxk(L&n|Ҷ./'*** ߟv @zny*4C_9֔8@KKK d+?g3444pN'wdkmvhP?P~~p-6 +DkMW!ٺ}}}}m?wJI>2 # _&WSG|||<#S7 eWIJ舻_N PsAwDRӜ $cu<y4խ?C֠&0 B0vWVVV5RKjvH*S{QL v<ۻH%tEXtdate:create2009-11-12T09:56:27+01:009*%tEXtdate:modify2009-11-12T09:56:27+01:00H]"gtEXtsvg:base-urifile:///mnt/Development/sources/pacemaker/publican/publican-clusterlabs/en-US/images/3.svgIENDB`pacemaker-master/doc/publican-clusterlabs/en-US/images/3.svg000066400000000000000000000013751217637305600242610ustar00rootroot00000000000000 3 pacemaker-master/doc/publican-clusterlabs/en-US/images/4.png000066400000000000000000000027471217637305600242530ustar00rootroot00000000000000PNG  IHDR #ꦷbKGD X pHYsHHFk> vpAg IDAThMLbW@v&XEN"mbE혔#641:q5MlZ?Ƥ΢).h! j!T`63L.'c淄ws=\ xIڀTs1O6 |Ⱥyyyyѭl P}T___}}ΚT3dY݀x<BP2U?[1FK6Qkkk+>x>tl6zQQQ98}r&윟h J$ $T8pt-z^ H$V#qG=~zK$][\\\L&ZjbI@ȉ]w")zjЏۤ6  2Yccc#h4a f9#iCCCC@ڛp'@YY___{M0777ܻ=222.S ڀ'OH`8hX,T`u}^|mmm  wtttb]ZZZnU%Ha! Ƒ!BaFFFTvvvvuuuu 4 pacemaker-master/doc/publican-clusterlabs/en-US/images/5.png000066400000000000000000000031671217637305600242510ustar00rootroot00000000000000PNG  IHDR #ꦷbKGD X pHYsHHFk> vpAg -IDAThYKLcenRBBu`#SaR7ҸqL0V@B Fe E myf`B)Lb\4PnZB!~s{]? N4~!H>ahsss}ubbb"pE\\\V,dR_rrrr':kmmm|-,,,Azzz: Z(PEՐe@oz&&&& >:N\z^,-///xOvvvv./pDGGG# Bq ϾQ*Jt: 8by<H1vwwwOOV (rwOFvE^qrrr2grLLL ?>>>v2g,68{ 3jjZ'&0A@[[[*d5>???{rZylll x{GGGpT4c2222+gjp!!!!l?#qhf0=333~n|2777|𤳳3ncH}?222r.p8PT4555ܿolJEWu}뻏Nˋ:,/7666fsmmm-r9ysss'pB=hx kq EJ%9s4bo=%<W`&xqtJҋE[P(dr"g\o&8%73,WUUU"F0r#"""<baϏD"BD`әq&5hlmg{r\^HU*}D"2>Ǔ Dde5444aadTWWWǞ}q1Mefff7"ݙ @xX,\nddd$vA`vٌFM>0L&?&]WČNA ?B?'uOoDe }:h?ߔЗhtCKKKGzj;MNJJJ}ߝ ~# -YOf qVXGAAA=i]iyAەw p3]]$"emNL>[%΄sbB@6666?FzH* $-+++}b/+0]v{Ko%tEXtdate:create2009-11-12T09:56:27+01:009*%tEXtdate:modify2009-11-12T09:56:27+01:00H]"gtEXtsvg:base-urifile:///mnt/Development/sources/pacemaker/publican/publican-clusterlabs/en-US/images/5.svg9IENDB`pacemaker-master/doc/publican-clusterlabs/en-US/images/5.svg000066400000000000000000000013751217637305600242630ustar00rootroot00000000000000 5 pacemaker-master/doc/publican-clusterlabs/en-US/images/6.png000066400000000000000000000033741217637305600242520ustar00rootroot00000000000000PNG  IHDR #ꦷbKGD X pHYsHHFk> vpAg IDAThYIL[W=Ǝ19i0a $*&1G"M(ݠvAHeFSfLe2@\LH t?(gwο{g~|p858L5?ijJmooo6yzX@|;%%%{ɼ,{E,~TZZZ ꦧ[ G\^^^HU ,uyܐ8w1G(꺺:@$?}r\<p07 B!O Rs?%&&&ؿrv!<}>333̄deee1G+999ys|||HOGX,@ͺ2333-zbGrnnn.p.h4'~2y_LL[[[f;999r9JeAAApbTTT|͝[YYYd2{'B9@ ëJeaaa!BP 9놇Rl!~|}GG XY|g2L';yX$B/U*s3)))xAXNG{{${buDDD}dK$ =Z\\\dގ5hBHFzn 2ݝ 1111 nlllnMLLL" bLa,p^XXX`^6ɤhNNNR`(QQ5555wjjj*߮= ļ{{䜧9777Gǂga4XTTTd}kN61ϭt:=pTVgOOOO zE2J \s=p ?f^ rxw0V^c2 D%000|H$.I}8/ WH45x`l6H****Kql6J틟ˢR_BCCCSSSS bq8VVVV^Tj@.... !$$$pAZ\_IVW YՁ&c?Z'U_c"9qe*_ g^w&pJ%tEXtdate:create2009-11-12T09:56:27+01:009*%tEXtdate:modify2009-11-12T09:56:27+01:00H]"gtEXtsvg:base-urifile:///mnt/Development/sources/pacemaker/publican/publican-clusterlabs/en-US/images/6.svg IENDB`pacemaker-master/doc/publican-clusterlabs/en-US/images/6.svg000066400000000000000000000013751217637305600242640ustar00rootroot00000000000000 6 pacemaker-master/doc/publican-clusterlabs/en-US/images/7.png000066400000000000000000000030671217637305600242520ustar00rootroot00000000000000PNG  IHDR #ꦷbKGD X pHYsHHFk> vpAg IDAThYKLg=PSi#__cӦFFCYu.ƥvѴ]vJ:,fFV)*& b_ @1=[{~߽;" _xRO+?.,,,{ÀI`www~fZﹿMKKK_b1|X^^^ȪkkkkEEEE uNFnWWWWKINNN*<,6666^ccc#rG8%Z2333A^(J% |}/ӗd%r\u:xBPn;r/›( @HB[>'T^j4uwH$ee3333@++++y6H/񚆆Љ_?/|fl~^Ry u@twNbNO].9!s8`0' wH׸#@S];S*^x01118>_Q #H$BAޣG9{Ex~3L&}ӏfsWWW;q xr~~~>to|a6ۄW` qGbisahnnn?ٰG&Ҁ8˦ ɥ%Vk___wx|uR'-;kggg(Uw`@p WUUU 6^_x//''%%%?pl,iobquuu5GFXxYrrrrxKIII R)9NjjjjDۈ.DEISSSpzt:6bJ@QSSSDhbbbbmVNN#|qeky -,,,ssssKIj |@&-(((:/$ː7)U]B^ZZZ DE$o/ČeY|hxA|xLӀuTrd6ӫWݴ/ZAOc˺?:::znFFeQx(Ԟnи#Fܹ.@}xezzzH}RPgGTF,& -u6\!6PNlelNfv攔2`U6n "G_]4i%tEXtdate:create2009-11-12T09:56:27+01:009*%tEXtdate:modify2009-11-12T09:56:27+01:00H]"gtEXtsvg:base-urifile:///mnt/Development/sources/pacemaker/publican/publican-clusterlabs/en-US/images/7.svg@YIENDB`pacemaker-master/doc/publican-clusterlabs/en-US/images/7.svg000066400000000000000000000013751217637305600242650ustar00rootroot00000000000000 7 pacemaker-master/doc/publican-clusterlabs/en-US/images/8.png000066400000000000000000000034141217637305600242470ustar00rootroot00000000000000PNG  IHDR #ꦷbKGD X pHYsHHFk> vpAg IDAThYKLW=yL J 06( `R@@ @(aU袴  ԟĂJPPſ@| 8+>6_`>ص t2(gcܹ{p^(\=g@a nggg'mxxxp)>h4X,}|||D@z3===žGMxpXP\\\ T*n"iyyy98p8'𔷼 (} @3`RTͳ#~f//// C1* ` >%%%ph4G8wsss.SKKKK$'''q/rt̯\\msygggg3K,Fmlll,NMMMOD"ys~~~r=<<<Օ( (+++LG"HB܉YZ`kkki2i5555ruuu53~'cwZ?n>37RTTT8q>>l:cg2ۿ|0mxV___/ iY=Ϗ^D( N67773yhLcƯ<&k7l?u*|R&Hrv=}֠&NNNNw_>~',,,}IoPp<%-/[C2d tnD8*ih/I( Jddd$¾1_As%tEXtdate:create2009-11-12T09:56:27+01:009*%tEXtdate:modify2009-11-12T09:56:27+01:00H]"gtEXtsvg:base-urifile:///mnt/Development/sources/pacemaker/publican/publican-clusterlabs/en-US/images/8.svgh)IENDB`pacemaker-master/doc/publican-clusterlabs/en-US/images/8.svg000066400000000000000000000013751217637305600242660ustar00rootroot00000000000000 8 pacemaker-master/doc/publican-clusterlabs/en-US/images/9.png000066400000000000000000000034241217637305600242510ustar00rootroot00000000000000PNG  IHDR #ꦷbKGD X pHYsHHFk> vpAg IDAThYIL[G -2 v0#6lLJ Q PJ8 M%J @*RS 78!D6(%A1ltBl׀ $wf__=E;p` ɯv`~:)X^^^fuuuux4e{MMMMRn~~~|> ~~~~ ^iDVVVyu~߄ H$;ϥR <%999߿8op'h 18$$A324L&www㿗5Qvvv6sDo?EFFF\wpb KKkkkk`t4777lzzzꊈZcbbb[⁁×l:q !y}}}=07WYYY h4cHHHAIkmmm5iƞ ڿry[A.!BcMSkllldZOo_A*rt5ؙ 4#/ vuuuk_TXgBBB[C=}ޠv;ƀۧ_N] >ͥAIM';P(yk ?C@;0xkkkkN%[&0⸩83n7O-Ĕ%tEXtdate:create2009-11-12T09:56:27+01:009*%tEXtdate:modify2009-11-12T09:56:27+01:00H]"gtEXtsvg:base-urifile:///mnt/Development/sources/pacemaker/publican/publican-clusterlabs/en-US/images/9.svgUp8IENDB`pacemaker-master/doc/publican-clusterlabs/en-US/images/9.svg000066400000000000000000000013751217637305600242670ustar00rootroot00000000000000 9 pacemaker-master/doc/publican-clusterlabs/en-US/images/Pacemaker-stack.svg000066400000000000000000001470501217637305600271130ustar00rootroot00000000000000 image/svg+xml OpenAIS LRM SBD dlm_controld ocfs2_controld clvmd Pacemaker CIB PolicyEngine ext3, XFS OCFS2 cLVM2 DRBD Multipath IO Local disks SANFC(oE), iSCSI DLM SCTP TCP Ethernet Infiniband Bonding UDPmulticast Fat GUI CRM Shell Web GUI Filesystems IP address DRBD iSCSI Apache SAP OCF agents Xen libvirt MySQL LSB STONITH iLO DRAC ... Fencing Linux kernel pacemaker-master/doc/publican-clusterlabs/en-US/images/dot.png000066400000000000000000000002551217637305600246660ustar00rootroot00000000000000PNG  IHDR TKbKGD pHYs  tIME :IDATuɱ AuPF> 4H|yIc{$ N$$(=w$Aݵ^ _ )d6IENDB`pacemaker-master/doc/publican-clusterlabs/en-US/images/dot.svg000066400000000000000000000012461217637305600247020ustar00rootroot00000000000000 dot pacemaker-master/doc/publican-clusterlabs/en-US/images/dot2.png000066400000000000000000000002001217637305600247360ustar00rootroot00000000000000PNG  IHDR TKGIDATm˱ 0> p@Jmq#" d1qT/aǑnxz IENDB`pacemaker-master/doc/publican-clusterlabs/en-US/images/dot2.svg000066400000000000000000000012531217637305600247620ustar00rootroot00000000000000 dot2 pacemaker-master/doc/publican-clusterlabs/en-US/images/h1-bg.png000066400000000000000000000003361217637305600247760ustar00rootroot00000000000000PNG  IHDRdNsBIT|d pHYs B(xtEXtSoftwarewww.inkscape.org<[IDATHcI? ! :lڱEjgoqs<:]QǓrH{s0:߱hw&FåIENDB`pacemaker-master/doc/publican-clusterlabs/en-US/images/h1-bg.svg000066400000000000000000000054571217637305600250220ustar00rootroot00000000000000 image/svg+xml h1-bg pacemaker-master/doc/publican-clusterlabs/en-US/images/image_left.png000066400000000000000000000200371217637305600261740ustar00rootroot00000000000000PNG  IHDR2osBIT|d pHYs B(xtEXtSoftwarewww.inkscape.org<IDATx}yp]y;xJ@pDQۖz=J6qZc5&$d:Lv;m&dQcKn+ũv[ŝ @,{KdE=BvKTJLu)i@JabHd)X3?Ct7b7٩X 0`3AAI&f8, R3'f+=u5L I@}C|v7*0"|id~̺. 4_gfr(J$Ci7,.lȅ m?k&y HDnzmM0s|f(|z<9NeisSӉZ_vp A J<~!gnY.?frEH^Y vb ^6)3 $;oιg {=7oBcoab~(B,-0^c65߲灋x[A-Jzմ #8Hv'Ј 3:`CpHhGK 1-aB:'ohҁZKsgjMϝ x0Ί:!R(1uU {\f4?Xk, Y{;,BF.E7LҼ}J'>iF*] J}}h=ذPK`aF8t[,L R޲Ѵ5͙8ִbYC|bqy6(\dee4З}5;e2̒ !Wy2,J2r2 `W3a8V 0,$b7X0Bmn {j5_e`eL п8sb/o^wQvz0:e3Z=rڸ! QM3SA$YU ˨rXVCh Xvk[1#Mju el2al39DJUݳvRlxƲPQnDoPGj R\| sco50ۥG7aVa@i ˨eUU쀫pٱגޜdZ-rBn.X9#MlcMBx9a3RG[򹩺bn>fp9l;73\f*:ўL5tu ɮ#L {Bv&>= ц)8y~NillcH1 k٤]H' 3Df;6t**/ (m@5d nxs!hV1Bn).l"ʅcɱ^5Zlj )Z#񶾏f[6iZa 32wOO·RdXދ?ګh !7/Zߙk: 'N6yunjzHguvaKV͗N͌4q3t*gl|/5[W0Kit,No>h;AYf.#IC X'})7? `v❻:oycjE5`fJM;1_&:ߎ&:d0<3։gI+őO_O[>YLj?} }nͧ.va%=ԂVVaȧB9;z$i[1"MŞ??VLm:&O4@-h1/ S3Sř-V~>:z';wQafFwL < `#lG:#ui9N!43.p_pە"''3H'w] d\ryoCG7+}vxv"H}ԩ=Ҙ} sGq$H._ PkKlOn3G_ktg,B=6ȑݷ&"Q%_ԵYd65aZ&[#m˥Xnrs#H tV:U&k|#vv}j 'eO +c̍ ޅ}`񹑓O찋ȫaBo3;X2^慣/fGJO]R&&odhύ_|CeS>qO\xw_ HO?h>3v7nxf¶_}0cpf\z}yF;uxfLB[oG#umU/oפ,Ƨ^hrӞGW.O͗SL#KR3M Ⳋ![|;Ynbq o>-}n6mQ! [5BcHd;<ᣱEq.?6eXV}a&$fXQB8l5uOh kFPM|edS#qa%4w2SM P4\R]0fF^dXS[nVOT3ǏvqLf7)n Ôdo}i_X'I꛶@} 5 #j@{Sy:v8}>ox2‘diq Kp9:YDA&g{[*lp)iݏ`o ϺSS'~ص}^u6H`D뫟?-7,eansKm J'!P1:G+W E{5!r]z`"FBۃh2o|ԝ׈̝oHu1Zߕ .5}CPDRR&5ԡ] Š3[߾AJǜ{:xk)R7I hcm9`CGaw<q-k]h]{}t2lbe-wy󣶕ٜ:};{gZ4g,d}u?Hnq=}8̂%?,?,X(PlPfΓ*tH$U:(f 3/X_i}H]P‘KKik+{U<8H]{Ftp1;B3 3R<|)eX G}`ÌؐKC%DjǓ{K4 <" I!")H_!Jz7>)beA,%U 0<F@}+obu]r]H%ݺ}.,`=@»`>ND=ߖFQ_}PϦv8tq OO|!,,/31;bfj ̀Js$`o/+zK;Owr_`Pdf)?!8@ lc`y?VCuð:*<>NEpLb)dИQ& 1_7¬8?˺O|bBpIL vHun a0WYD!eR$@pzpm/#aC݇dA!T[-H&X.$l DC8,Da>+ҸJ$ ]*u^?L]P6q<ʹ\k-{<뼓5*uf>_5=zfZ ^.sK: xXDD;*Q?/8=_OQJD1"z~6U˕kQ_HD'~%șDDG#HD&[V2X!*W~:1գPql0U\ICDQI jwwt ࡀ ]~pc"*d" v נ <7"[_ .@Da"`hJD-W11=HDO@AyA"*Et2sC "/Du"p'|?ftN/D qW$ ΁"D}}S_ѯQNCD_RxCDx~ !(z;ڼt`.΢V*CA8+()'Q/) e7jw ͠JmLec3x ( ` @Wz8UmsVl8̺VDt/o(u)?ay"xK4}d cf ]"9 WjHoC4<{C=Dtgb|OK@@&pyU^%":v{ig!433×@#Q jgS*?̝e޺ ?% "3uZ89"2\J̖^ӛl",5],ZK(i@7f@4 pܷNo^ӳN0sŁ5A ~x P}\ X3ɠjj1ډ PrׂP"vnA( O +Ԭ5`F-FbPDPLP퇡vtb|QBIp'u~/P̜""vBI^s&=$SȺ7ܨ$3*$$JPm{tz,7@I[(͕ZZJ(DW1`tz(pO/]P=d|xbPW=&(&h}N(bOCH"*P{ J6zCf.z6|Nbc\f;ze}PyY_F(Fj#xV=c<+7 GiP1+ePлG_] (? `2`#PڽF5zK<>\-PbG'a/B1q'=Ҡ]Glne DaP23}P ̇]:4 -m{p޿ JZ㫸5}PEf| j1ZK3`36uP(};CV(pU^@I!(iЋJimNBڝPi3C+<}%&(B>@mOJ>FCSAĭ NCojK3v S2sP&ChJu>:3Ҍ`i$Eh^FE$}PUNx%4CIaI3TȔ"4\zYRܵ",KP>W*,I;"ReZtX < X>ǩmO@g/2A}bfҠe;_q&V(7=}ҽB5F!(j(?R5i\ihZ3vq{#CI [Kz' P7CI(:hkVRބdŰ{$aWxPu2f(">ZkWy/*w AwB1)/8&"Rr<\+,ת [Ћh)uE2,U,ruբ%lie9(-u@8x˫x4Ap3Hhv=<׫_uV'ʧA7oByG9Ǜ̼3=P?fA1}Zf2̠w"|*P^IxPj ѷ A6@s6@0T wgA=VkJYC}zf=΋P"r̍MD7@yu\50P#q77N(U)%NxL(gͥOņK@W5EOf( ;t;HBSa3kJ]&H@O^uzDxU@MRBP%>h5x\HCS5 >ef[PF\fnE7㹪Đns{ 嗀n"Ri(FӒ Wxи/2UY6JB1n{_b7Pv&rF-9[ޕIENDB`pacemaker-master/doc/publican-clusterlabs/en-US/images/image_left.svg000066400000000000000000000215411217637305600262100ustar00rootroot00000000000000 image/svg+xml Pacemaker Pacemaker pacemaker-master/doc/publican-clusterlabs/en-US/images/image_right.png000066400000000000000000000055361217637305600263660ustar00rootroot00000000000000PNG  IHDRX(z=sBIT|d pHYs B(xtEXtSoftwarewww.inkscape.org< IDATh{}? ًeE֪33)8ZmGl ]!6h 4ę&8Fڦ? FUrUߧv]6F&?{sys==m1p>ix1(cPƠA0` 5k~I9]8c6-2Is9qO\vhXn Q Ѽ(╇;F$S5[бθUhfAӁmݍ@x޴eS 5ӮrZ5\8OlM4L-3ѝ=:vo˰=fԥilo(9@xK+&R+BvM;TSsI~]ٕ .]bnڶFez&^I6hɋht>91%JC+F_Lkˉ'u͠OPeNLR-2ۯ)DS@oTn굵D_. > F51ws@O5zZxwOFaa,ѫTw"@D =  gsTєknxٺtvy' ҨStb_- )ǰORZ7Ƥʠc!]bmڙ%E oԺoB??uNPtPoYbPGhX+>yI>_UQt!;.,:rrNkP`X4rY!8X݈2aZֿduN%azkm^ÆV6*AEd1oTU;2\ ݏi%Zt5x:1ђ^VT 7t wrM'oXYrl N̓Q/r~N6?燧V֮ǂC$`xaMݤ'k0%w/.rÆ,ockỎ5Y$\e|k_TR=0WD_ѫ1kmK3^ Kh~C@FF[AnA*H-5y?) N/z)IɜI4SRǍmYu&BtIE'S.>L 9 ]6@r8@Տ <mIp, ʁa\MJe$PW|/&A<`\ݬ>*6I弤bl`wu48ont0  \U'v%$凶 gX<,^€撜EWl"3B+Cm5Yw$}E|k p.$YCB,w_7, uׇ'ՁwS/ne lI~p/BG#7ˁOR0)k!x- n7A..vnIV.ӁC90&!=Yx^I),#Y$ [ 4t0:Iۀ/v8J3IHfMɑ@!^ofDH1,,YL fJ)"SE_:dk#+3n.IAY 91$+:nV9$mþ;y0OnBlt뼏dƋH^ mIeJHrB*I%]-%MTJzC{GIL'7 m:$JIV`P?d3; IAH pAdDH^'~#vʘﲽ-0Wm7K >EaۛCՃNԛ."9 ϗ~1?bPƠAtvIENDB`pacemaker-master/doc/publican-clusterlabs/en-US/images/image_right.svg000066400000000000000000000064121217637305600263730ustar00rootroot00000000000000 image/svg+xml clusterlabs documentation pacemaker-master/doc/publican-clusterlabs/en-US/images/important.png000066400000000000000000000044161217637305600261200ustar00rootroot00000000000000PNG  IHDR00WsBIT|d pHYs B(xtEXtSoftwarewww.inkscape.org<IDATh՚klwvmzw 1 /%e"0%`ҒDIC!HmE@JP!T% FR5(JEJ uWJll퇙ڻH#̽sΜRLʷm@__5(fw~#Å4NAQk]BXViQkE9FvX>Z2yyN`e,[47NtTSnxO.,`TitÓ+9X P=鵺=&=n\ UaK2DPEM7&BiNh=`>O;F|;J k5s3M7򀵀R:óON2ކ ^$TY ֱ¾ ҟp%@=Gk$n_tcD_ %3kN`ZAkHrqy.ݾRBӍ!`*(P)g{ Qf؉SAxƀ{g,X)1phQ`S1$ܢϠfMr H#F5d;ujYm]?d&[N !(f1ܯWQQ1\YA6A}Iހn/sBJ@~bV`5ypb5#GV(1yXUZZۣh@2r$(Np"c}:аDF&(Ёqxt&}Wg|jwYJzz$cϋUK^Yu_% x F (F u%iEDB.eoCsjRt8ݑdž)v$)c1$zPR߶&K޽dn<l*]&A(K8I _$G~_Kb3[mZij uLBE)öuA|bub0e_h~)II/Hfp">~]) 7w`:p1+cF lHy,'5ğ-"Qc2%,H̝rb9FI6K !\QiI8 .; ڹs1` F\H+Ov$).U 7 T P@H!\B:S[hBnWGE*nO+ N#[DF:oD w5B-OD|+e~ ;4 "CzX)GK#E.g 8fC`/P$iS + |--S8 n846A^MPU@GPhpjI<0Fϧ|M zHMrhYyd|.+EG1E^5}  v~Q?>N]t/oq!?ȽҶL@_ j<^v逋mR*=f)Rl>ʨ(&1>".z  .`>#RJ5$_s/9Y񡇕[3wba6[1{{sݖ_WI`#5WKIENDB`pacemaker-master/doc/publican-clusterlabs/en-US/images/important.svg000066400000000000000000000047441217637305600261370ustar00rootroot00000000000000 pacemaker-master/doc/publican-clusterlabs/en-US/images/note.png000066400000000000000000000040461217637305600250470ustar00rootroot00000000000000PNG  IHDR00WsBIT|d pHYs B(xtEXtSoftwarewww.inkscape.org<IDAThՙmTޙ;3˲tyKI"5DcM?4jci-64m-451jK475\o;3sg;.LO99* !jGS)d**pеs_#0 :0}8qxеJ+ I@8<(Ujm !,kf# @(TǢEXd LaVƾtKmm߻w;H:ㆮmjH`-7ޕ+QUYPY% /@pqq cl{m+۶Γt‘Msqu%S\Au\RYz)N8o4tm#ч,"?~iB ckT"^ vD?\KKQ>C׶( |͟φښCJd]I2b՜< @pkg }˭P0buƇE3K bR("I| ~%?>Yb|ׅ{Տ<6/ (Hf`C~ '2VCq=&=i`.Bv\2CҞHs)i,1VeqzD*x׳|Jд.Ӥ-W0b.5~cP__߇ۀzc9wD$|yW:˅DM}#mYB+( Gˍ퀤U/P"B'e\NeFx9BKdl"+zG>rn U sz25XOa\#S}5/g G'`MBP~g*KvJ=,iR}B0o~3`"YQ}2$a"?C\kI#IW$n1:0K4kDs⦅Vu=YoeK0fk6k~Ej{p ̐^] ]8~Xovn蚀灃1 YGG%xR:vxwatl+Wx?JmXr`nl%tP ۿg/3Cځ7مe$#{p&Qkr#7W8UxمNy^($ZRku nT.ٽ=еc #I}o˸4ozlH)Pk{uhq,l{?0tT`k1`h m];;.1G+@ LSS3 N/wyYQ&0b™SL=wĈql>5vlLg,)~XaZzz h!q k==֓  _\\]\n~ 7t-[ ]Ñ`GJ5ogOx8 1tmo%Ε<,4w9qMG!ݓ_rX@kr%6 !5׬ҷڤ)SkЁ-YC׆}Tr/ݻe+SU v`**zf1tzu^{99<6b(Dӻ?ͳq>6='y =Dg(2;|@ef̞D:}/? f* Cז " @}a$7`~е-WKp0 K@8k"+@kuGPp$ZFN2zfCV]ue0" D <; 6IENDB`pacemaker-master/doc/publican-clusterlabs/en-US/images/note.svg000066400000000000000000000052541217637305600250640ustar00rootroot00000000000000 pacemaker-master/doc/publican-clusterlabs/en-US/images/pacemaker-logo.png000066400000000000000000000346101217637305600267700ustar00rootroot00000000000000PNG  IHDR<q IDATx} U}O@@QAEA}ő]q̢3"8"1"K"` @Y:['ݝ;U:$$uꪺ{9{n=SO>| )SO>| )SO>| )SO>| )SO>| )SO>| )SO>| )SO>| )SO>Nw pI ? l_xNg}ѷU7z=R˩X=Ldfj&imf/3k!C%V|5KKXĉyYq'-0,`凓u@c Zh,y~<5Q(J*E1\rp,eLV}5U7nk@Qhf* d础yD@V`afbT|5Q(U*H^ d础yBQ]L'*$C6f~8i ZTeD5 s5w6â-(,u6ѿ8!|tM@;q[$/XQ,_(j,ps)k.= V,q"L;D}{k"[dj@ЉcX K(*{CCǚDgX SXNr&qY&q(k~sYI L:V M{k!L2TuTo: 7m:sM}1f6 ʂg793~R]w{OmqSʴ`0b MU#ռ;FYRPIˀ8iHְlerN%7Zy=ϧ%n})w[-03/ACU\͘L yX%  ~[]0v\~̆/J;#U kl'=㛮i}t^Y^Wʨ\øu | )SyPSb%f:x&?i4L'* Jxu:VsDO~݋GzW%*p.Kܥ܄<ЄT¹xXG#~f'] K-f8IHGlnfu}̼)N`A}fnoÈ.E~2a tvӜx/ g2S;I@; :G,Jb^<ѯ`Wڼpo@I!9B.]Zap}L`` >pō{y ې0SE M%n% -A:BIC.jiX?ŗgضd2es{ƍ8`U|=ŋW<|/ܦ?ý$],\I$sx8cg@#?!( MlhH8vJ6.Siw[er.e㦌eўZK?sRmx%Li::' C?SGi/%i-zS7< Gw9#a@S5RRvN7>_TBfۺ:o+q b]_^L}Qp"`+kp60CKSɯoNH/`l;.-kߌM+GʟuOGl:6 4)٭rv! ؑK:(@ , ڵ-aG4Q22M-F2ǩ߭IEmNa)7M[@h'i *̗3ioK'j/=P4ݮݽm:_cԞTT$IeqG K4$LLvEʱ K%ؖr1bhFg]) C r Rc H@Gdѱh vlYZցP5KejsM.7x~9y̑8jG@)@Ek'I 4ڌa=?el(RRP+¾~$ᅼ~Q5@ʳ#2g6DY?k'Lp''D}ek$M!`AV ,Z[[0[}VZߊ뻿}paKX$kΌ&^[99pf$@ U6_rΤ%)%!ɒ@ȀdP-H5S$ AJ,P 0Sb۸H1卨[+aᶄĐ4/#r),Ѵgmp׮<pSFbr=(79s?"nDk˸ٿˢpnY#4)`l]L3wt;.@OXzOd*A"pK˪XH|˘_ŌwVXR.\IsE[qf,rƐšNvLѶrJ5^.?C*a+ސ fJSv̏0Z7ljʨ̯ 42&܏8#nE^]\:?(oۜ,۷Og}}=źj_z^\-z0G+V,+eί`P Ѱ?ZMMlߖ;?Vrc5buؤcYٜ>ܸrfqP-:-pЋ0ɱtRml IXu.zB>Ol(L̔R71i؟ؓ(7\weד.U,P'BwVNd䠾m{*R%Ѵk<'$Թ;i0  ~@Kۂs!.QEJK`yZws?AaSSu| E-laY9J \"Xk^NQ S64 ٹshc ;V, 1z !k#+׮Z%Ix E˴a(xC"}IΊ*^2ٷ3['ћhժk$=ޤׯLwY,.:kϾ3^y*hQٖ kFPtj'-6@!h9q/:vp $՘+K™ WvT`b30,<1(6aCCᡨe5 WD[w &C)ԏFZV4*iyZjq4 EٖYmp_bԄnS-XY&*A+ hhm+/;)  K|eW%E I$Y@Mzw6~=?'068A*&&jQaUdgbeՄxpJrdnK[.t4YuU mHEhDDLTp*OMmEѲ %:C0{VT^m_ơ^jY"~BIT:u>L5NN6ꬕw8)Z5kg kb ; iW_-pKyygoR峑Ζr慐\ʚgZoٽLg4P0&6Ό+X $@2[vpڏs|,P׸tbw<h-+d}̚=JzTd7Lw*8gɜ!g]` /PgI)P*S`=sIz`eAazG[YmCP0RL]*E):U(O(B)d!=f@^;F fzzuW E`qF:@187 cۖtƀ=%ޅֆ+B؆ y}RЩ٦kr/ nAdz}ܲvІeXX(5N5ug=;*R,L˔D6;VČʎQ1nX7S:1+mK?YcPu-Cj}ruJVi-q3u_Mff<})@4*)pWExWd[tЉ")uH' >S%hYH53r.)VUdmKG HPt-pTI* X5Sm^G TdYt@./¦Og<]NK&6WkFGS=F4*MŒ~_d4ch}؁V.IlXfimyeIl Ua[I("<>I TPtPl҈]p GzY.K4%~_inݽo\hj̘2DqO-⌥(/`˻;'}=5yy\- Z':%^]c]t<~ńM:NP ]Q# b:R} #^V|MMkD#ϽoT lٗZ[?6.%f-p>H4~w_xI&DK 3pFH ,o-o<+sXO CZTp,k_gM$9@Յ$N6@ժ+xV϶#ϱe-(R@ {3Py *5P%2ۮ&Z"IO@Ȥ! I~ED\``T˪Rvr,HYVR+5 M oaX6/7`NB'lTu3690Ѱ,W2ʜJ)yyGU_,Pٜ$ŒB8301oȘ@Kw 棼 *`:-SIR\b-9NKgU nI$v  Y@ГRd( XįltƇ}!n^ )xlZ&IuPʱ۫!un1}}l$HBV/}Ŋm!SŪx:ۿH~DTAڤ nV w^~l3KFƷϜ> !rurRPHO*l4\]rɱxUΒUugRB9X ]TmCHKzJe~~!-ŀ3f]&)MJf{Um3ry׳L$P `W|HW,9 פO #*K:.3WW낹6a@b?WCIDAT#ϙbjY 1U}͌_uUX~_Gc=?^P&`J8o֭B2|UeRޠψa`wMej4x_8E_@a;dE٘ E X#f SD;ScX[41DA8$7uSA`[=UlLHΉpbLeߓvъkԫ]-3Xs~S@Mj$lvrp=eL453s `Ùݱ2e-3#< ] /zzY@uAA8<< }4E:v]0NiL>c֡?ˢQ1?nyk&uxnܗFV0O$C|pL#׌k40W'UhiZ !] \JZڳ⒮-M8˙]?[1!B\RQqs\_;61_>,LG ƪ(/olêE1?~SlRwh\\eMu,>u|ΛIԖ*]8r,S,Koo'2Ϛ[|q\Au( a⠶m=Ϊ.Okx*92r##ԇ__eKդl\0~x(Yc5]I1WBf!VSp@@ smcsOs<]0ۄ^nС( I[ pcݱtuy&Fm-VʋfA;Ypb/L% C, W'6:kM).,J: \'.Il]Ev>[)UiјI(퓓q>Fw`3188aR 4/TygMR W2Vklk >"6\^p[ [U|@=lmFĉPK)Ѥ4'({H9j!qj'< JNmхQqXrܺQ;tɁT0H9}uHD*],I:(5nf$5=-\nBbi/ =%?QaR6}Ӻch nR֜룞PWh|xD"PʱM}n1ԑu:9zo)Mg.5H< n4ȈEp*t>P{xҜ%Ģ ( nI'RI8p sNըWӖ¢ ]_Q>NK=GuЫF)0`,9Q5#{fZEWvO>Y3$LC`*_=0ZFq'}ŗ)q?9:N!.MX!!Bg;٥$JIЄelYe`*ryHs4I΄)hbN KN*H f9q%/wIT-bn!f^U'F]֤\5Pve񫣶?#?=v_0p#/'ƋEg'AyNh57ٓeHi3% mVuGZL<LŎŶhds[+kJ:pByp5zC N `[bvP{XhS~]Y*He'qls=.fAv:Yޑ{&:t}b&3(95JZZfL4BGf6`:L0Թey@{p7fE7e({M;I6RSofbz#_؜_"fL0nZ I?!1y+7lvO|2iL$˚1t_8 ᕑvo8)hMzᨂ/^1#pEӪY'Iҹ$EC"@vRprl(G@?4' ^nh!q%8Gnp-ɋFǚ7O|)Ztt%tSԯR̩2s[& dTٝ';Sv<j6,)PR ur9!I f/\ICKRĐhb'DYw9y D`9y [̖T$Y B:RT|vuYM)9VjNjǰMb^XܦH vq8Je@n,ks6.`p]FHs^<|,/?dNnFev736<_dQhb[ܟX&ⱈynҴ&,=Sx#?IwtUc`^IyMJZ|Ize`5H):7%teCb|p>s sWH!hgL,WǬqpt"X䰋{/7Nqzυ qYc:[ Tarra#z}(xSoH| "^Ttq{'\: @r[u؇YF3۠h%Hpn0`Ē΍~lՂ#叺%} =I.XأPNBy>g9>|GhR6R>8fڧTϹBN &5<[%웫fg ;ң·7! a6$†}Z9XU~tnHMRg5+9/=*%-1lbya^ļBc2*2ͭ !;:f%OKA3db&}e(ܔKYaZ;N^0/<'UQ<+c%,# x)r7[M~V^n ?,rza)`zCql] Zײ Cul'3nj*~+R~;Cܗ,O懧օ<䪏o]K%M6<[,R_< `pɽ e `$72L5@C[D:ROs~P , ľCl]Mtu'ْ؏wޮdAb~T|?vI3#YEU는ޏi$s AhTnʧG 3Pz)؟zky4)c$h(94+x/+` U.0lPî"|Ƕ6-RRjM<6`7*ω >xUJ^~껄%32(eGMN-Ћ]%'!@/-֮^ cҪ[`óV)6cBE`> ^2kkHulf$SXsi`( dBAndh3;!Z9^$t +2\ry!]LY(V|"0V9_TcG4]"D&TL: (x]l3p9iCnoɄL,żt`!CD[2rcn oLk=TK0\g_7V_ml^Ǧm?}9Nry613+u|:6^^e5-Z!B) l"qB1[,,eX(j 2|if3Ё&Rd{5Z1YiLAF캜Wc5Xn4$~9qZ٘zձ'#6ޛwlc}b:%!c\d`|]@ RsG y2 0xRTT8iKď`rO> ?tk[mx8q xy0? -_|W59co]Ua34A4sn=h)/ B3% VOnT7AhWŵbHnT8g%:W#cWoxq tqQK(pg 93{çx &F` 6O }>ց {\,Sѩg,GuQم5yk[[âu*^E ,o;T7|+p5{F?Ǎ>`*`t̀[;'رHy 0(iR6tkyKmGK9P;nvEEJ+w`r}w5xq|t<%TIF܃LX&,AD2DPn#eD#}(.|5ؙtdVb_aۃVh<2aY1dtS (=C<GYR.j!]Xe./gBxʭ}fϑ=޿Erf*ze/Kc殇1[!ؙaMQʼnϑxg`Hc#CKGb>6`k""'S>h< KmRGYѾshBz=vt ^y d=UOn^#$?+%p4>TT8׀| `U)9J:aB.xEf-Ev.lnЭ3؃z]i/ExpީCj@2qw˓>EإWMef~9[{nTDZ)nߒrNSO)O+wZt]|K oc9>LD~ Tuơ”*Ɲ|aS:rF["H+˺ Zl QJIT$dkAЃ%t.\TSG]cgReQ vʇSX᫹v)~a=>HԊЏGD(bN^Uj(!R'd| u ۩ݭf;Ю|蔱Qy\l"oo]b ;m` -:, h&Gάνs3 %8цI`$򕇡8yF nd90֙\:xW`TU=w%|fFƦ!I^e{زS6oD wQџɃJ6 +o!!SOc746 1GAlS:VrjX[5rzDdU\5y;ع%BH*'Ck4 hyQhCs}?ۦ'+85w8>pI!V|G]TG*E}2*7*b˙ѿ)SO>| )SO>| )SO>| )SO>| )SO>| )SO>| )SO>| )SO>| )SO>| )I lIENDB`pacemaker-master/doc/publican-clusterlabs/en-US/images/shine.png000066400000000000000000000002221217637305600252000ustar00rootroot00000000000000PNG  IHDR1bKGD pHYs  tIME  IDATcD&L &7FfU2 IENDB`pacemaker-master/doc/publican-clusterlabs/en-US/images/stock-go-back.png000066400000000000000000000014261217637305600265250ustar00rootroot00000000000000PNG  IHDRĴl;sRGBbKGD pHYs  tIME+yIDAT8˵?HQǿGG/Y*ĸH\77 bR Bb^dY&^Z^Ÿ {MQPJ%8 :;;/ӷ%\~:550MnkK?4)ز,EuG|Y<Cu@0M!E &20Jbi?T6锴zLsp Uq U5sVRg6\"0IENDB`pacemaker-master/doc/publican-clusterlabs/en-US/images/stock-go-back.svg000066400000000000000000000013321217637305600265340ustar00rootroot00000000000000 stock-go-back pacemaker-master/doc/publican-clusterlabs/en-US/images/stock-go-forward.png000066400000000000000000000015341217637305600272710ustar00rootroot00000000000000PNG  IHDRĴl;sRGBbKGD pHYs  tIME*0jIDAT8˵OHW?3lgkHC/ ɭ=EJDņ](ȡP$SN9U (Z^BЊ)BŅUOq77Cge]w}彙w~қFz7~N*ٙ{_l\\Bx>VIno$j UkJ}(Cn''$IENDB`pacemaker-master/doc/publican-clusterlabs/en-US/images/stock-go-forward.svg000066400000000000000000000013511217637305600273010ustar00rootroot00000000000000 stock-go-forward pacemaker-master/doc/publican-clusterlabs/en-US/images/stock-go-up.png000066400000000000000000000013611217637305600262470ustar00rootroot00000000000000PNG  IHDRĴl;sRGBbKGD pHYs  tIME*;%`qIDAT8˭?kSQ{{sScB]JJE NLBKҬ7pRpA nT u*$!)(Ѷ'76Mڛ4Q {? hT*]5rWc 8numqYԪ/GC.zB@4}&7XjuW~cc#ܜt]?VI`7F\eoozm%ÿKt:}mffzeYl6fB`U O&hWU|guu5JnKB T*etxZ8tZVV!!DennRxgZ )%SaLOO?XYYضM4uݳCϧ)g~~qH$"J]vk,s ضmommYfFA/߳\@ |cVk0`#PH<>::t lJQ)b ^l%T)"vTp<608"ݽ]wJTl7 ]wL xVuۀcr܅{MP.G)d7Q华ZgIENDB`pacemaker-master/doc/publican-clusterlabs/en-US/images/stock-go-up.svg000066400000000000000000000013201217637305600262550ustar00rootroot00000000000000 stock-go-up pacemaker-master/doc/publican-clusterlabs/en-US/images/stock-home.png000066400000000000000000000014631217637305600261530ustar00rootroot00000000000000PNG  IHDRĴl;sRGBbKGD pHYs  tIMEVIDAT8˭UKA}3**i+X $HA 7рn1gI,"=xYo-$%@lat?ۋ 1&>]fgo߼.KڜJRJ~?aW>s$BAVAn"f25R}Yt755E+lnnbkk ǵc}YXX#aqq1F_qE>mnnNF1#LFGG!mH9Y>ˁ14 B$wr_>GTS㠿n6M&=EQw^r {oU*LNN`6]WO&eY0NNN:*m.۶Q,1==MBP@UեX,7IRy?@ދiiHmj3 a%4QIxǡ~!`Ύ@i²,1aG)f26neY .˲t]A4MXӴ{;uݞ0MA 8^E#fr 8<'d @Sj7ƍVn=IENDB`pacemaker-master/doc/publican-clusterlabs/en-US/images/stock-home.svg000066400000000000000000000013131217637305600261600ustar00rootroot00000000000000 stock-home pacemaker-master/doc/publican-clusterlabs/en-US/images/title_logo.png000066400000000000000000000236541217637305600262510ustar00rootroot00000000000000PNG  IHDR-sBIT|d pHYs B(xtEXtSoftwarewww.inkscape.org< IDATxyM{d%K %I-G$5{D*BQv-?ݹs;3Ιy^{9y}GW^b&;EPNPQ @:Sqmɍtn Xb91R?m@?\d %0nLE⹫`jK-XñXL?qz"Ansl ҾRp,)o(/TW$SHC,^ >S p,ɚSODL]Dn--%Y1iUDydosJXñ$yM9VDsA3 ,/t69^McXX$&K/Q[킌G{ NXñ$x4Í .9 4|m.jHqXñJ G3K<4hds[&Av9-$a ǒ@CQ}:5yвWgcI-LImMnӶDk8_KzЧC.7*Xñ^/*ACDA-'>rt[Hj%h<5Hn e}BR p, #=%:9Wge)$"p,ÕA}$&Kg:m!rX]G*+Qm-qdN#Zc .#h鶖x1жc˓~)1HRnvldnqk8tz񗌈q_S||s7b1Xñ$Q(z_#/tγm!cF ᶖp hBi~xH-8pR8p`Pm-A`hbpR(< `D{@n "z/̷m!c '%m=Af`X|'bpRvink ˁÞB,N ų?_.IOsbeS.-Ē0$s?+@~#{ q[%8XI46u"GK𰆓h%4' GFm!b 'ѤIY95ޜ~:X5d@>2K&eh=n 4n N>jہ\ jߚM Ɩp( w0^ZBؾ׺-zl ' ҠOaFKf PޚMp{&񚠹ZB?@uXk8IO117wB pXk8.S"f,~7;XqzMcb$m=!O+޸m!wuz-- Tu[K" x7t[}$"wH(spxfs7KN"Q[Dy@y+tm15SkD:Cn 1Sɶ@YBju('y'W_(pm15P˞4B$r |m@cIX 25; 1m-!f}vKX w?G2y5cBN`Q3_Xp@'j%^1f)lpHN"LʙBכ8郭X5xR%f 긭%DDʹC w[%e` 'qw$zcDhfh\ā;ؕ_h&ZB1`,0}ΰBh,!NTījbJk3Fc -pPo%\^Q6o[k8Pi@n?yԷFK*wۙ xMR+̂ Kl$1s[K |hL5nX5*ٙ1Ym- d?0띗k8@6; ]m- xk[s[Tm8ߑM0Aғnke̲re=_RobPm-q;,p|3nXB3,+zd! E-b/p rGiU蟍YF?sX{l{%E1̿GI 7ِ^H$[)|[M|D!'Ȇ GB~?dH{O@iܾ'F+)N =>lKl;̎HBHvS֌B#%zTBa8$+hRyuz-( r2Tb8NB2pD aIDyhky2N$p~+Z]#J.[nP505m6=rj5D0D/!sIr,ajvsP c0%N m !Z!.yI$o8nxSd8l]P&jtڝ"K0J&k8A5uFxsqm-'IN&[;I&/> %-L _TfC|4c2]5+" g;c @4䑘#07T2sK⢥J]%$L i_B+_~DKBIrSJN7c gLλ;)P}R۝$Ij((|i 'v [Y/$-}K$x F[ED24c]v[nI ǭfg^ADC2ٸnRk8)p<,׫]mKH2sc-}0͂:{^HReE:5Th8J,67%$ ps'I30"{eݞ %ͱ݌泆 'j?$-I,x['NHJ$ )qTRk@I*@8d[&p<5,D:rW ';0_w< 't8'J_&%Kʀe g2HJ/Ȁ^6q\ ;?vC 6N@/7A!"D$[# Sdﱿ2$L(?KGD~̿aB%0Cf$7É| L0GNHf8l./3B32=H{@_N3o>!) Q6N%aW=2x\0KI*Y:JJ^QEZfIb8ܜ |˘ /LI>{֟vS çR 3R)]6~F#S}[S 2;%66H^"&T~FA {SYyZ%DH$Ӷ!%2GMs!c,[WN+joؙ g@TʘW˂m_nΫ)p~,X.XfF ;6ogS*{P5 {"NԺ%Lk,_x@< `m,vVɈ\(K1q4@YI[*ÉN!& ^{l)ELFJfs#~vIצ)dJ41Édɭf#O7pp >NsY*8Tx/% ڛgI4h,%uϟELxIlCe㍐a8K,Vl_:ži,gڂ  5yKp>xer!ĿՂIpNIZ$Xظ6-0_S#)=pٯ%~Q.^qp ƺd8%c:-ݺLOȲ$oGRkL} I i0.Zpp2 If8%, _Tad DcHh8QO%f4k%Y&[F W `ļoݜ'hI]g̠o$ &p"?.pBR~sIih8%>͕X+-P2m%ֿK"^ l`d8oqI[m8;d2 ,.w܅SXVA =AMgҥSIpnl%`D/exd8oKr\;%,\V>a8Q<]Ip(xK`By} _{me$k}t.Ds~ܞH=ջ}WN"xR"Id8 bI<#Pzn):+0+{Y%b8ӬAK5P  `t(`Պ9bßjίR*0 n, DCf>/E@ q{+/<Rq>p]XSe?\UUke7bPgcX,>hR?3n&X Zu!Szp./ ZYy0kq:IY,8иu'ջp+0'O^uPE.#~I@L%*K(:=jVo"Q#yDb׶e~~u-ۑ JQPиϾA%X>y@FAU]Fw׏)" fN|.Kl<f~+J Fxc̊9?rȌ},NtװuVj ܁W_hUތ_ZU<P @v _ j_?>hDyb;3GT8W%Gj-x-sK< QGU7nyt@#zbwU̜Z%9?"4hnϽK$=p-oɷj$z\c$>_tZ>s'1XMbQc~Qtz03 4#D8ԁ9Hvs7=~{x+ؾ'94@`% ױ'oD"WRۂnk}5x#$ y\ϗ% F4F;;ʞdB MS%*]{b\p߽ƅR*8{9Msߔ>OMc/;< lɖ@F)2`0O ahӁ=V+OjFju";p/V׈ɵFk@sL}݁0KK?@?g}K@-:m<>`?/Ձm<<(rkz>R#cc hlFO?(xc1Y^1qiU o 11D-,fG:UČFjū\*- 8{ݴx= m|iU=g`PX_fN_V&-`~ σ4@/ nq} ^1ų? ,o :X O =s 4s+'N> 0S@ݡ=b'Ҏz;#4L8l{r5Iu2[LS1Tl?^{1$ɼ '~vz0ƅ4@\"0AXTΚļ 8 `^n@8X 46:-0Э7(5`ұ*bb3O>6)8YY sXmVك utڙaJⴥ k^l22ߤ7Jy-!WMe|̍_h):w\onm-~L  t|^Z1\i`yܸ0c&=1U,'*x8L8J;|ux1&+zGLaS(7K_kJ~WYy3%{{.ff.ɚ]| |@w#>jj_9/^ӉŮiwt`K[{g_{t׺:͑c!#by1^}ԑ&y 9qÞʷiN&fx#P'sG{ 0rœ^lN0o.CtF;[)fL?>E6\ u\k5Ywca._Vq±ec4YRܑ%:bJffw`6}ۂ2EnJa6!f`&5K,'Y0ځqb:}J˘/:,n6Q88b=io@C :V, ^G1Po*X6TZ?;Vƚ]/ \^RmV9:+VlpK=1غX. jw@`&Leqq8ҸhL 8p(~3<#RaE年o흮JK3N7`9p/.kĊKwo/WXC{ݺu^= 0?H~//wßTW֟H^rH tc-!*ծ'3cbmIbεN|ʤ%xX8Q!c8V#S)Ы]Nh)KԪoڋ^ . nݥFի˟_Rd8{X7-|pn#ř;LGYqğy8eH2NIbGf -M lvG h1.RI6q{2*.7~}S@3Sh:Yo'Υ`_<3X=ԿU|(I`EyCp@Cbn&gjޓ=w<)!G.v7TK19}v, ~UW.bic#u}PR"&*AD8w#z?c$2vbSjIDAT.eE; %ìB6.o`վ4AS5+_?,,w~T `wo/}GJLE+]@! 1k^Xs M-/y9%l"Ms4J8 ' KU"ѧҘ7C$zst:2;?:ePvf><}#z-nZy|-q׭)h;}1\XS??ʾl{U4*{pslQH`٫[-Hxwo;SK8 ^~r/vG1HQbo߈ɋ%+ِWVu9`Z@gcb;z,n|+NM<| 6 hI6`aGZ/'c]N+{bo.{r%bx>{'Qrvl:G@ɿhi$b}ZO8R13N@`œi_sĹN{:~~t`S=?^Q$s;.bRl k_ hKm@-㻺{U"Jޣt<]eVoc!CLކmwy>xXVA;=dyO3LpSL"V+Mˡ<[ޓuoƼ4伱3OE5~4f. &6cҼ3m&;HHZtU-,/Qq{7x !>¹M&L׃Cn>  lvX~&p̣ۏaZy[PNosx3vo%w?'уukw$U/tUژs]Gs}G.O0tLL|on>N#Z&L5uj˳N}6=T ӓO-yWfB_q$I3 q 31L}{j:͌1F_oI yH(7&QD݇y 8PwwC;ӝrgv%LIM-^MuJ0 zrhv [{+[r1w7oy?- ܓ]Ozxӊ{Wɒ4s:łc?\țHy;,"i>DRy 蒧6| yÔ?>JNTu([77{-%f|oD*]{pLL>-8̗GTJس܂T Z t<1[ $ sW0CD+i!9Xb; =qa%8^,Cab~@aL-S#ky/VL̸O#{]r 1b4Ei۸JELfpG=) _IENDB`pacemaker-master/doc/publican-clusterlabs/en-US/images/title_logo.svg000066400000000000000000000773031217637305600262640ustar00rootroot00000000000000 image/svg+xml pacemaker-master/doc/publican-clusterlabs/en-US/images/warning.png000066400000000000000000000036251217637305600255510ustar00rootroot00000000000000PNG  IHDR00WsBIT|d pHYs B(xtEXtSoftwarewww.inkscape.org<IDATh]lWww޵wg㴉T؎Ǝ !4 8Pߚ`C RT}!g) }HHRBRQƖ? "Bhשϙ쮽3; 4{{sW}֊HІ[JB˅z:Xu͟f2+Wᡂ }{%i S1Zl}rQrQyo5ޥTQ28=>g?&| XM~0t?ҫE:'qɏ>!b@Qc=Oھ%to۾;x'z/,1xEd^<&?vbl&i m֓ %=BaϾsO?Dx4<zӶCB݇wMOX" js|<a4F[]ca6x޶}w֎2lcaJ obC2RDj{ w| %jԵ+ox h |u5zޑ<bU@gGobD|d.n"V ޾]GGȋ(Qqt^4Jl`N`,7D{N־zv,FÌ`}W ErKK'񂖱DMlE:D8]/*@BM~l2V,KK{FLz'涌է9IJZ'cEXA 6YZȗ歷Nu&=#n(}WEyz B"_AwLc-Bzɤ}8F6`/R;>E@Kyd: ۪m PO5wo2'Oha:Hˑ 'y`Ʃ&@!ܙ>hאMy@t _ >LʻNԇj6-x@ˤc>`$&9@Kx-vT)!nT$1Ed"F4A kRȆI6`؇} ޿ݤ,=!\?dk<ځ\eqC.G|ɹG p % ع8cph˒/Vehk,Nbfw(*e d ??Ɯ ټ1ټTX;5q[Fgo<,piw-ߜsaR;–}(O{㋭nhk@T#ǖLޟG%Qe{,R._%: bK95q*W%.͖}i*(tsՂ S%JTtg {kWްE+Hfg"V_/0Ƈ ^G{Tڪ۹8]9}%y{h}R-b*?Ce÷In6"–M'BH͟a~֌'UnjnH^=TbG(FhA͏`,1w % Q-P' *ePP-З¿kKEx1{f[+3Ց0|' o_oH.<8#[-CQTQ<8#%@S\忮$TY~i#foFVw:pCL((g&00EXZ^ռsOǵɰYukAțoOƫ3bIENDB`pacemaker-master/doc/publican-clusterlabs/en-US/images/warning.svg000066400000000000000000000127441217637305600255660ustar00rootroot00000000000000 image/svg+xml pacemaker-master/doc/publican-clusterlabs/en-US/images/watermark-draft.png000066400000000000000000000614251217637305600272010ustar00rootroot00000000000000PNG  IHDRߊbKGD pHYs B(xtIME !? IDATxu%ewYt%۾! Np $$Xp.I  C^,NpiXpfx xx)}V !_?VO]//f/%B!Z'+[#lZ_.13}룀7W׀ׁՁ݀U|ST`6VwD.6!=p^ 毥ϻlR:L5~enq`A:5o,0e*緽, BԾ>lAuv fIЅB/ ͪ>88>ѝ !Dop#R6n[t!-B7x;/_Wn>}·T?Ip3@!Z./K샀#2fbJwY3t!B>8ذϳFtI콒] lQKN] ]!zb< w)+kQOw2ڮ.,t%B|,]70fg/wrJνE:g5&k ]V%q1_8X̟/')A.x<ߛV9(``zES!DCB>7|N,׃f@.J"a(n~.%a4-Y+! !Dх|j4ʯM'oUCx +kr=h]!Z)ۤY99'p^0{3H`&`vz]!&KTD|`i7(IN9X/!B.Z+y'=׺/}&Y``6NmM!/pM(``ZW9@0;_x [O +$B%3/J܎~uQx6z  fOٗc7aYsW- !|p=S;ډs6pheC` 8˒-z lG0Ѕ5ssIM361Oq3;q%]-j`6hWTO !Dy؝)] :%ƣ,)z h,[,F KЅU[l)h- _. fKπ]<$BJ we f``vpʲfUq;xHr BGJkzz zgMh=T_ f$n\|! B>}0 pf0ۿ1V8X`` = .(,_6Yx3;U9S1"mlkB.Z*e{NfḂ  1ْϳ̪;ꡚ !D%7@ۺ̟?f;OSz'<4\y~쭂I~l*kEud`vz]! 4xJJiMf'7+Ob4[n_N~W.MlRڣ[C,~$n5J0LNclb.:|F0{ϤsxHމzʣHqBfx41kne1;j,}oWCV 6$/ (裁𭇕ً{b6㯇1TӴ[淋i.hp-f붨opc=ǼV5|woeε*q5"6σ ..ILfŗCg|ԯZrcv<R풿OGe㎸ZX}X$)P<Ҡ9Y !:x]ė/k7XXׄq-G[ZÁ,$musOQm-xZړҎ,+8YY1cfBvI* /\gi6YҚf V,=i4sJЅe}s*rR>)`{\BӚV`Sڶ\DNA$B$˲;86m355C^Gs fcxu`ς^~۟gw bY7(CE|9*(4`p?9qڂi^Lx4CB! n;[cOH3Zfm57~mpjă_Ux_N xɆ̎(X{Bv;h ' y?`Zr:xur̺ef_ʋ=QFp|npe6߽e 1l}pn)f|Y NTIvt!Dd ꙩ*Jf}sq';ٲD¿#bM㱸1 b l f/=g1n-Pm: 10qh`ɹ֢oY W3y~t}}Fߗ\gQX/s~ |[T*&Uٺ7wMkp&`m}%ՍO?БڸlT֎a#\vpMbۦVg{#`vWӠ^>& 5C )ɕy>˸{Je줢y,;=k+fϦ˸ygׁ>YmB ߩg0K[U g\gQ8ݯz7%B_gb,3uBɿۖSm>.X{,Ƴ`¢K+_ge1OY 35~{47wB6k"m4D;t!D ׀,ƃq_Syl`zgz,nrfbOЯENo?VJ"pE罒*'FFkiu 7 !J6^^:G)ڮx6)_vj5.l+8$!mAջo8-Tu^gQ8?_/ ㆌ(p-"c)QGI{̏S/ e1 zIw{)LKuKj˒Wp xz> !Z=X5ִ^^Ӛ>P. $2,i@߽ Qg{ܜ~QZ=,3>m`vZOG$Bt Ռ9䢂5j<|L ̀[—~jُ 4w3*w;3Y.e5@4ʃlPcl~,Uq ߺ=n fwK}2w0̾J+#KТti||_^.h)ă|7%H0;pI~(mkj}l{`&_U8``6:of'xn21EUk J4<-USn+껞:6IЅM6ӚZ2P~R2?WMVGX}H0hiMS\\Hu -`k.r"U[〛(\]Z1lf Νv^&̵*kۘ*yZ.h/f1ޝD`v^sv9 O0{O Vvu V:f``ߗnóuc v/v Ytߏpm}pz,xJӃir*=`{g{ϲKeCfiyF1x,}F~ԵLt&o{䑪vlzQ:!}uމg6mt!,aVhB}CZXv+^ST5lj8rWOPn+Ocrt0{ s+YC e
    #>;PI*]m9ꐴy>3x=("mL0[?[C=I(.*G Ѝ hвK_!/YW[W9wNb b1 8 !Sz<tS|LwkpJ~EIYy8s w%ss.wwrL|⯂x{8%w݅|$X쿁kp*}"d1 1M~Hɳ_d1P~~L[W_ fP_Ewx6+/1y0۬Hb8]㉸v}S$]ͩIl{0ou';*i6/2T/ÁM:au9LYGf1n,AB7q<>m%d0@m'qG(P:)TϺl$ޞGO#xZk9hTr/LY،'Sk[<>â<Ŭ Fi|ԒNb&p63_-]Vpl,KqxZV)UG݅9۬S/.0$R`iZfWj(Nt!_ Yknoǭld$%wQl!o~-G18[$1b2`TU Mxr*r$Gu>V@o1`#1뾋<'>Ʒ\>J~=.Ng$3/;%+%%XUnVP3 ͨm03k^R`vh'uχbyHk㡙ma1_(ӡ]pό[J~t6{XU^Nrß3p;V1N0{Y.+w?q?-iݧrUh8-djƗQb@ س>})qc|8\.{}sQZX||p0h9ʻ`Jh)Q9_ۦ)쨨9~0e|XKE^,pK!9{3``mi X倧S̀V7~M,b'g}e<:%l9yl~E?_vWp{`{.-"cZx?#͑ixolS[tڇ{ <9Uzyqi׾t & nrf%eu,?Z,< \̾Exir*<З hs,a֭H3Ÿ-ϗ%/UYV+s^mTͩȏ}5i%袵|x`-r,ҋj`nPxW['x-8 +B f{h\ _Y="'vGC<Ӧs Cl nRυdzo> xؼ×ӫe:|jϜ~7^'It0| G욡>}Ó9s*[|_eB˱ݷj;߶^KuOi^OK;Q{HwS|TDWK/ =EG3K +9E|~t|4Y1"'`I/oaik5Ã,۵Jzh˖v%fO/S]IYU&T`vroõZO>o/ҋÅ2-h]Tzg*GpOcPUʵEu zxC7 f6Z`6)q?:]٥Uz&JY|N~: vV n4C-|L3r*C w#^-A}7NȩQ)9q{rv0[0tc&2A#4ZjpWO<OY_(d]㩖 fg&6l֡%-=cA9p8.sBjy[om:9+`/m< L6+ ?\yLhs,tl_">>'X.Z[.Scs?u =ݾv fn]#u5ҪaErJ~N:2D2=1} žpt|0Rq7ySw{YcG~ 2 _!S=Sgx;a"F͢}oLWpY#p@/˕5C5{#k5+@H`o~*^Ktr)v f.ۦѸD}bzyπ| 8q$qxR7*C=]| y&v"X}f]iM'דcŸI0{^ ^x5otv0Sg}jho`r4OO hTOݑO..yg—Ld/`o ˳/Oe1n[[ &Utzi_5"iTfj=STx .!LsBfx`scf^ f;硸t;rY7na _z,L4j=`&f-t|4++"KYEG,i~&&ooy Y_e6qF8ptW؊{)GP[F(>bI8ƭ/ fGT(kqRs},[TK _i܁z3%0gyz.*R8,Ax܀=ڍsyF(d!Ab ^r,>bI{[iҤSXdLTK nSlSZ} H<<ؗPl 6Ʀ@h\oyn/X^_ ۴II\'!A-{1y-/KB#IHXbgۿG%b/F}[as4nt ,Ҡ޿}ltS194+op󊔓;d htnK%=5,^<9hNEK㊴XyG"Z>e?2B_3`=|iټ֠? ̮b||\NÃ#mH|MdzWM/7ݗ,}]~w\V.Z/mc1 7/4i_`}Z$6 fNNmݪ7P#X`GoAl"(X^9.[׿J"~G0c۶FSH=-w==Խ/1ǔx#/V,^orm 4jw pV0{9w&<ʩT[9``62qL|"0cgGY⁄>nN%wП|.bF,x Yqۃkp5JE>[щ4bӌ/EG,i HX{Э>?v^ʚ3]mRݚnL nh|+B"nNb `)``vyVfy~xefi>KnT<ő躪=#ao\,kb{Km+>f1OL?]=fN+䴴U{|H`vtVrw=ƜUB^H! _6b[X1oO8 {%L[xN b- qt|#Kg#K88`PNifs ps0 !A-}]rkw }xaYO`tZYC}-S0<\oµ6ۘToY܎ֿʽxKmK .§oȱŲ49k-G%?kbXܭ(UƜmCށ>KgG9;$}TCL)_f$yDJ,nQG.'j<|7^1gs[' yWO?/>Qf-{Sو O}ZQuiaX1Y~%ܗzjԾudAz|::xV 잂9'2ٸsB޺+Z"ͩ=~/RW>ĭ5[>q+R]0aPy/NXдKq-`sO3&e1/^y?NlT㻸V#+2K x`Uu_`7ܘ'9.nzFZQ) = g1ޅfMwU\G;9ʏăt M0~ka.kBmq7D0۫`b3<_ss\H[pK&_LB\`mw]Ix"r*)``c0F[Q+C[73RQ[8qܭ7G q_c6,مesFG!T'þhr-FgC7io'KÊ,=½fϩ؏Cˋf*$=QJ;8d4#m㯔O`G6p{;wJ؎/-+m) 4#|I4?'Q:<, 8/y{-+su_BNfiЯDeD{%-C.LJve KB~{7mei2u.mYEO/bWQ5{9 fk?0'[y~_6|ɽ/fP=ު3/й5s29i^c⍸e=}$ոl'Byv`vk2>D~b|XU[ Bqwfg1۩Ui=w'Cr;NTK)I0Of WH+1Tiu>hɽ}n:s_Ԣ#1ofG'O{ORKRo7gݞZ/cδWz!bAnAQ`rfphj`hos`nE}65n$@0[3om84_mb\!,< Ь94tmYg1vOjbnvFNb>8/ۚ|g;lŀUo48Ңb'?^ oH*-PQ+/MPܿ{\TO k`M;e%g/+U`yQ^dWWnbc. IDAT_/s9YgGs\h^_M:CnrSV 9Ti4}f?ޤy[ݑ`^ msy-)\ohfh,ƽhy } fOt^p׫[qngË򚸝99 885Tw U36x-cڇ{ gASoԟ> "z,?fSՀm--&V_-+Xy^fk zDhO%zw5MK/6IDvf:!o)]̩p3٘dӜ,x,U0B^P1GcKk t]}p%=8ŏ1O7&}Fz4Io!h_G#b?. f5YVj\O`0 wLق VDB+-'ٓ{VWģ-Scq{?ό(_`2) fWZ6je"`}s*p8`6@xƪ[(oo[ zE,J4og>op ][X7}`rZ7[d<oqffm;^D^x5ݿuGZYUz0{$&z!y m.}G y< mE<}+EO7&gw w\3z)LpQ):TAx7o<@@4} u}A#}ӂ(6 Բd19YVy>z^L9lT0;w!ۏɻ>O(r$B{5%qt)UW<`4n'[&A Y| ,̮+i4J0.}GIH{,aY!7O>OQw눅ފ0LJmH0;-qW' kO@KG5 =Ҡ[+G,s&r}7ZQ+##k,ƾR/p]7 ?}ZE’{ 6n.p=pc0Ԃ='} <-s{ܓ>Mc˗MOc KoBjA^xZc_g1~f!<,y ve0:'g,-3UsʴjPs`$Pv`(xMqW tv&sC&oXMx24l !A':E``v{ M3Er/f{>IiB`8 |ո^7]̶nWZ} EĂ5o)Nɍ<=WT5ub^Y`6**7`pA < p@u}l,+o{{VD zA 1^e.`w}0k7~V~oN~yוM:mK/wYm F6c1]pͧz~,r,yRrqZW},jû[S75\אQHB/qoM`Ϝ-``\ zt=#s:~D^uю3Ŗ^֤T?b=`d+YK;U5hVƷ[Wne(1_xwECↂBHkbiv9ej:|T153aըYS%Z|{\5BMQKtT_7M|p-]xV3 `vj m{GK02~[īҬrNNu]YYvn^" ~g0s9kBq_,9w`3|?y~~wLŃY} 3G٪}C@kCܸ* B^_כj098vNm7wʓ-j<cx8E7fmYX⣁?TWÓ='1[ z?.d`[R&˧.M<_v]CN4G*}`619 #5d/Q~?U^P+u~}40o0r;\9ƍj4[Yg͝-= m5o$s^p;6H9Si~ގx'HC1E/滁qu~wjglB0"i6J`W``c07+ u.ϱKLN/7{;_|; ਜԿ z^ݕu~`p5 Dj&xH<yֻŸ`<`m 29ugLeաJFN?C"`As㒭B38΀[7`#p|Uj tfO&$wŀ;ll3ن{p/zߙX|;8!HF#8ʠ:f]Y 0("" k \"[$J{}h:UUUsNNz~wH _Tf`.5{%EҧkS2cK*";YN2ڃc(R:Hi:0Hi"Ӏ-|Ypj?&V`&fZm<&c6,RFD3nY?祈ېӖsKs}b>DUFHPDIxe( t,UOtV{9͌n֤luڟFL|QeV_{X_N.Rzoz)RHDrFMov\\t{-0|- Oh6ѪYϝ28ֳAT}{wν̫eMAH8d@}6q9<2m:9G˥j9Z4ހs-k1 thKֆ9jRmV 䫕9P:KM- 'Fug_-sn%_jGG$84'9'GUxW]C%UDg)-@|G)ѝ|EeTt{.WU~P}oR1J0P|1 ܷf_C1f?3z[-N`f"0qՒII'*Fo9:;H5 <֒ו9Z[h2痶OW=vKj%FyػL0/s~euvMOM0K_1׮Jx_x[ݦkZpEuH2j:H#-no;g/$?vlBTLH:֦9{eMo!f_]2/ Ab p1F)m:X{܌{k+6ػ9C=Aȍ-lLD_7ָ"=&1Wu7Y@Lzl$)G['9侤S9Φcs˜6I?iƫ 37%j赚&?Hibs'ҁUeļt=f KMQ?=tvt[m]H{+S#L1&9Uu0Q}XXزHsI8mO1@ n6*u{KҵUFSܿv%.'U 2IljÁۈkt?)]'T/?O*Rz{iu"5Oߕ< ]&"i ڟc9bݗ>GƎf5߁5߀/'VY$ɀ|݊.n6} 8}O-ĐI:&n%,DnX@ Z$8/SdJ?Z/}Kv*R6Dս7vɅuc]O沵|HT_mަCf1s'y˜GTO0?^lZt\=|/lD\o5zy10H6n.E v2pY`jJl"̿yDYKtI2/@2a~+`:Hi6=>U*Rz=RONRJGK`4-R:m-ވΆn 2D峡mg2'`MwED#"ɀ_} ?)ĄicqPEJ[4+VAIJO6i*Rޓ{I.'oS!ɀ߁} ')^ϱ)6V$R~^ +^Ìj`.5{l~ $'V`_vM;9|h&&ivFuUttC+cI0XpJҳ j4`CdkcUpS$=52㩿 k>pLzhl\wAపB$t:X3ߖcɔׁo̹"/%*=gVIݴ`+Rӫ[=V1m.4S`^/ɀ/m x0U lץ~1|^;6R :4HZZro_9 wO$Ey ^U9Xc-)O$kwkiN,R:WnB0Kʜ2jx͸pG$ 3\ZHd't8Hiv倽 vLj{)Rr]Rz{|شſ_XZ{[_MDB+zii.5\Pd}j.T*s}'hqDn)epIe+ *MV~SX2&f)s6mj"=O_D\#?op'%ՒzCP&5db9[#~B@Ku[q::}=v1{_lwZT=tu3@̺nfGEJ:b=["tEJOxdI2kiҜH)kY "mҰӹ2WeMohԏwL ,4"]ύ49GwD0x]Π{/GNsItuңp V"|-/#.+l|b" =t$;'2ϒ&֓_ԃ{2O$Ŝ1<K䠟#ɀ^Z"o~KʜW>'͗5HssU$ɀ_v*wEJ,by#DYӵ; 1ap("AHIt'ImEH k}#oѡ&tIrN\wBIt# ^9E eUJ鵯I_꙯ԡ`"3ʜŲ P`{p[PZիy Y`NҹeWuL{z5qZ)_LF x2O9oG]ķwgǁ 撖ErTѓxwuNEJ` Na=> SW/I*ܗN|Ab]=|q1DZn6kKjhwzTIZ9tNIeU{.uNwMs7"] d@_j-R|.pOY2 z=3hBߏsi``"_x$I󼆾t9ՍjNm4i;2Á/YuTbLsEJyHҒޣʜ'9ˇ h)^DK|S jYYĒP!֧oXM1C~18:gw)-}F syarߏ-sMuxHiζJ imbWo}Ryi')=!I)/Od8۫[l ukd5,5,BL[PժrcDZʜ KE7êWG$5\H <`RI$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$I$IZܫmB{IENDB`pacemaker-master/doc/publican-clusterlabs/en-US/images/watermark-draft.svg000066400000000000000000000013521217637305600272050ustar00rootroot00000000000000 watermark-draft pacemaker-master/doc/publican-clusterlabs/overrides.cfg000066400000000000000000000000751217637305600236610ustar00rootroot00000000000000# Config::Simple 4.59 # Thu Nov 12 09:56:27 2009 strict: 0 pacemaker-master/doc/publican-clusterlabs/publican-clusterlabs.spec000066400000000000000000000020501217637305600261630ustar00rootroot00000000000000%define brand clusterlabs Name: publican-clusterlabs Summary: Common documentation files for %{brand} Version: 0.1 Release: 0%{?dist} License: SETUP: Set This Group: Applications/Text Buildroot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) Buildarch: noarch Source: https://www.SETUP.set.me.example.com/source/%{name}-%{version}.tgz Requires: publican >= 1.0 BuildRequires: publican >= 1.0 URL: https://www.SETUP.set.me.example.com %description This package provides common files and templates needed to build documentation for %{brand} with publican. %prep %setup -q %build publican build --formats=xml --langs=all --publish %install rm -rf $RPM_BUILD_ROOT mkdir -p -m755 $RPM_BUILD_ROOT%{_datadir}/publican/Common_Content publican install_brand --path=$RPM_BUILD_ROOT%{_datadir}/publican/Common_Content %clean rm -rf $RPM_BUILD_ROOT %files %defattr(-,root,root,-) %doc README %doc COPYING %{_datadir}/publican/Common_Content/%{brand} %changelog * Thu Nov 12 2009 SETUP:YourName 0.1 - Created Brand pacemaker-master/doc/publican-clusterlabs/publican.cfg000066400000000000000000000001721217637305600234520ustar00rootroot00000000000000# Config::Simple 4.59 # Thu Nov 12 09:56:27 2009 version: 0.1 xml_lang: en-US release: 0 type: brand brand: clusterlabs pacemaker-master/doc/publican-clusterlabs/xsl/000077500000000000000000000000001217637305600220025ustar00rootroot00000000000000pacemaker-master/doc/publican-clusterlabs/xsl/common.xsl000066400000000000000000000027041217637305600240250ustar00rootroot00000000000000 ]> #2C4081 appendix toc,title article/appendix nop article toc,title book toc,title,figure,table,example,equation chapter toc,title part toc,title preface toc,title qandadiv nop qandaset nop reference toc,title sect1 nop sect2 nop sect3 nop sect4 nop sect5 nop section nop set toc,title even pacemaker-master/doc/publican-clusterlabs/xsl/header.html000066400000000000000000000006551217637305600241260ustar00rootroot00000000000000 pacemaker-master/doc/publican-clusterlabs/xsl/html-single.xsl000066400000000000000000000014741217637305600247630ustar00rootroot00000000000000 ]> pacemaker-master/doc/publican-clusterlabs/xsl/html.xsl000066400000000000000000000022401217637305600234740ustar00rootroot00000000000000 ]> pacemaker-master/doc/publican-clusterlabs/xsl/pdf.xsl000066400000000000000000000015621217637305600233070ustar00rootroot00000000000000 ]> pacemaker-master/doc/security.txt000066400000000000000000000130241217637305600174660ustar00rootroot00000000000000Points of Entry ################## Inter CRM Messaging ======================= Security relies on the existing systems in place for sending HA Messages. The assumption here is that once a member node has been compromised, you've pretty much had it anyway. CRM Internal Messaging ======================= Security relies on the existing systems in place for sending IPC Messages. Remember, once a member node has been compromised, you've pretty much had it anyway. Admin client X, Y ======================= Security replies on standard RPC mechanisms of hosts.allow/hosts.deny etc. It is likely that this would be augmented by adding an identity store (leading candidates would be the CIB and /etc/passwd) and authorization mechanisms to the CRM RPC Server processes. To achieve a moderatly sensible level of security granularity, the API should at least be split up into the following list of RPC Servers: cib_delete cib_update cib_create crm_admin Admin client Z ======================= See: Inter CRM Messaging Potential Exploits ======================= These exclude things like faking HA Messages, hacking IPC fifo's and for the moment packet sniffing of RPC requests. The "Measures" section is intended to contain messures to prevent the attack or to at least raise the bar for potential intruders. Exploit Class #1 Desc: Impersonate the DC Requires: Access to the DC Ability to register with heartbeat as it is currently running[1] Measures: 1, 2, 3, 4, 5 Exploit Class #2 Desc: Impersonate the local CRMd Requires: Access to the member node Ability to reconfigure and restart heartbeat Measures: 4, 5, 7 Notes: This attack is pretty much limited to the local node (and any shared resources :cringe:) which is no more than they could do with access to the node anyway. Exploit Class #3 Desc: Impersonate a local CRMd client Requires: Access to a member node Measures: 1, 6 Exploit Class #4 Desc: Rogue Admin client (Type Z) Requires: Access to a member node Ability to construct valid XML message a) Ability to reconfigure and restart heartbeat, or b) Ability to register with Heartbeat with a currently unused client name Measures: 8, ? Notes: This is probably the second worst scenario, about all we could potentially do is implement behavioural pattern recognition and that is :definitly: not going to be in 1.0 :) Exploit Class #5 Desc: Rogue Admin client (Type X or Y) Requires: Access to the CRM RPC API Access to a host with sufficient RPC permissions Measures: 8, 9 Notes: This :is: the worst scenario, attackers dont even need access to a member node or modify/interrogate the Heartbeat config. Again, about all we could potentially do is implement behavioural pattern recognition. Exploit Class #6 Desc: Data interception - Rogue Admin client (Type Y) Requires: Access to the RPC API Knowledge of a current, valid and unchecked ticket ID[5] Measures: 8, 9, 10 Exploit Class #7 Desc: Malicious user (Using a Known Admin Client) Requires: Access to a host with sufficient RPC permissions Access to an existing admin client a) Access to an identity that the RPC servers deem to have sufficient permissions, or b) Access to an admin client that passes a pre-defined set of credentials, not the users Measures: 8, 9, 10, 11 List of Measures ================= Measure 1: As the CRMd, verify the "type" attribute when routing IPC messages from sub-systems and discard if it is not a response[2] Measure 2: As the CRMd, verfiy the "from" field on incomming messages and discard if it is not "admin" or "dc" Measure 3: As the CRMd, Verfiy F_ORIG against known value for the DC. Only the DC should be sending us messages[3] Measure 4: As Heartbeat, only allow clients registered as "crmd" to send messages with F_TYPE="CRM" Measure 5: Respawn the CRMd if it is stopped and drop out of the cluster if multiple HA clients are trying to register as "crmd"[4] Measure 6: As CRMd, cause Heartbeat tp drop out of the cluster if multiple clients are trying to register as the same sub-system. Measure 7: As the CIB, detect multiple active registrations and shutdown when this is detected. Measure 8: Require the admin clients to provide a credential which must be matched against an identity store.[6][7] Measure 9: Configure RPC security appropriatly Measure 10: Invalidate the ticket and the result set once the ticket has been used. Measure 11: Dont create admin clients that pass a pre-defined set of credentials [1] Shutting down Heartbeat to change permissions would mean the DC is assigned elsewhere anyway [2] Sub-systems other than the CRMs/DC should not be making requests [3] If not implemented, then this exploit would only require acess to any member node [4] This is currently reported as an error and the second attempt is denied [5] It is envisioned that in the case of asyncronous RPC calls, that a "ticket" would be issued that the client would use to ask for a result, or perhaps set up a callback. A second async call would be made to retrieve the result. Syncronous RPC calls would internally use a different call that would block on this ticket until a result was available. [6] Depending on the type of client and where it takes its credentials from, this would either prevent unknown clients or unknown users accessing the CRM (at least until the ID store is hacked) [7] After the ID store is decided on, we obviously then need to consider the security surrounding it also pacemaker-master/doc/stonith-ng.conf.example000066400000000000000000000040461217637305600214550ustar00rootroot00000000000000# Using Standalone Configuration # # The standalone configuration can only be applied to the # stonithd process while in standalone mode. This is achieved # by using the --stand-alone option when launching stonithd. # When in standalone mode, stonithd will look for a config # file named stonith-ng.conf in the /etc/pacemaker directory. # If the config file is present, it will be applied on startup. # # Below are examples of how to configure stonithd in standalone # mode using this configuration file. # # Example 1: Standalone fence_ipmilan configuration # for 2 hosts device stonith-1 fence_ipmilan auth=md5 lanplus=true method=onoff \ power_wait=5 ipaddr=v02-a-control login=abc passwd=def # Since there are no ports in fence_ipmilan, just give it # the host(s) that is controlled by stonith-1. fence_ipmilan # happens to only be able to control 1 host at a time. ports stonith-1 v02-a # There is no host checker for ipmilan and there is no host # or port argument really, tell stonithd this. options stonith-1 host_argument=none # # Example 2: fence_apc controlling 4 hosts, 1 port each # # Port assignment implies connection to device # device stonith-2 fence_apc ipaddr=north-apc login=apc passwd=apc ports stonith-2 north-01=2 north-02=3 north-03=4 north-04=5 # # Example 3: fence_wti controlling 2 hosts, 2 ports each # device stonith-3 fence_wti ipaddr=10.1.1.2 login=admin passwd=admin ports stonith-3 v02-a="1,5" v02-b="2,6" # # Example 4: fence_xvm with special option # device stonith-4 fence_xvm # Non-fencing agent option to give stonithd hints options stonith-4 pcmk_arg_map="domain:uname" # # Example 5: external/ssh # device stonith-5 "external/ssh" livedangerously=yes ports stonith-5 v02-a v02-b # # Example 6: Fence_scsi # # fence_scsi has no ports and no host list, so all we do is # tell stonith what hosts it controls # device stonith-6 fence_scsi ports stonith-6 v02-a v02-b # Try to fence v02-a using stonith-6 and stonith-3. If either # fails, move on to stonith-5. priority v02-a 1 stonith-6 stonith-3 priority v02-a 2 stonith-5 pacemaker-master/extra/000077500000000000000000000000001217637305600154345ustar00rootroot00000000000000pacemaker-master/extra/Makefile.am000066400000000000000000000015751217637305600175000ustar00rootroot00000000000000# # Copyright (C) 2004-2009 Andrew Beekhof # # 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 2 # of the License, 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. # MAINTAINERCLEANFILES = Makefile.in SUBDIRS = resources rgmanager mibdir = $(datadir)/snmp/mibs mib_DATA = PCMK-MIB.txt pacemaker-master/extra/PCMK-MIB.txt000066400000000000000000000054221217637305600173370ustar00rootroot00000000000000PACEMAKER-MIB DEFINITIONS ::= BEGIN -- -- MIB objects for the pacemaker cluster manager implementation -- IMPORTS MODULE-IDENTITY, OBJECT-TYPE, Integer32, NOTIFICATION-TYPE, enterprises FROM SNMPv2-SMI SnmpAdminString FROM SNMP-FRAMEWORK-MIB netSnmp FROM NET-SNMP-MIB RowStatus, StorageType FROM SNMPv2-TC InetAddressType, InetAddress FROM INET-ADDRESS-MIB ; pacemaker MODULE-IDENTITY LAST-UPDATED "200901051115Z" ORGANIZATION "www.clusterlabs.org" CONTACT-INFO "name: Michael Schwartzkopff email: pacemaker@oss.clusterlabs.org" DESCRIPTION "MIB objects for the pacemaker cluster manager implementation" REVISION "200910051115Z" DESCRIPTION "First draft" REVISION "200910062115Z" DESCRIPTION "Corrections after feedback from beekhof" ::= { enterprises 32723 } -- -- top level structure -- pacemakerNotification OBJECT IDENTIFIER ::= { pacemaker 1 } -- -- pacemaker Notifications -- pacemakerNotificationNode OBJECT-TYPE SYNTAX OCTET STRING (SIZE(1..64)) MAX-ACCESS accessible-for-notify STATUS current DESCRIPTION "The node on which the status change happened." ::= { pacemakerNotification 1 } pacemakerNotificationResource OBJECT-TYPE SYNTAX OCTET STRING (SIZE(1..256)) MAX-ACCESS accessible-for-notify STATUS current DESCRIPTION "The name of the resource that changed the status." ::= { pacemakerNotification 2 } pacemakerNotificationOperation OBJECT-TYPE SYNTAX OCTET STRING (SIZE(1..64)) MAX-ACCESS accessible-for-notify STATUS current DESCRIPTION "The operation that caused the status change." ::= { pacemakerNotification 3 } pacemakerNotificationDescription OBJECT-TYPE SYNTAX OCTET STRING (SIZE(1..256)) MAX-ACCESS accessible-for-notify STATUS current DESCRIPTION "The textual output relevant error code of the operation (if any) that caused the status change." ::= { pacemakerNotification 4 } pacemakerNotificationStatus OBJECT-TYPE SYNTAX Integer32 MAX-ACCESS accessible-for-notify STATUS current DESCRIPTION "The numerical representation of the status of the operation." ::= { pacemakerNotification 5 } pacemakerNotificationReturnCode OBJECT-TYPE SYNTAX Integer32 MAX-ACCESS accessible-for-notify STATUS current DESCRIPTION "The return code of the operation." ::= { pacemakerNotification 6 } pacemakerNotificationTargetReturnCode OBJECT-TYPE SYNTAX Integer32 MAX-ACCESS accessible-for-notify STATUS current DESCRIPTION "The expected return code of the operation." ::= { pacemakerNotification 7 } END pacemaker-master/extra/buildbot.helper000077500000000000000000000007541217637305600204520ustar00rootroot00000000000000#!/bin/bash set -x self=`basename $0` if [ x$1 = xinstall ]; then # Basic test phase mock --configdir=$PWD --root=mock --resultdir=./mock -v --install ./mock/*.rpm nano sudo valgrind lcov elif [ x$1 = xdownloads ]; then # Extra test phase mock --configdir=$PWD --root=mock --resultdir=./mock -v --install ./downloads/*.rpm nano sudo valgrind lcov elif [ x$1 = xlint ]; then rpmlint -i -f rpmlintrc ./mock/*.rpm else echo "Unknown sub-command: $1" exit 1 fi pacemaker-master/extra/cluster-clean000077500000000000000000000046241217637305600201310ustar00rootroot00000000000000#!/bin/bash hosts= group= kill=0 while true; do case "$1" in -x) set -x; shift;; -w) for h in $2; do hosts="$hosts -w $h"; done shift; shift;; -g) group=$2; shift; shift;; --kill) kill=1; shift;; --kill-only) kill=2; shift;; "") break;; *) echo "unknown option: $1"; exit 1;; esac done if [ x"$group" = x -a x"$hosts" = x ]; then group=$CTS_GROUP fi if [ x"$hosts" != x ]; then echo `date` ": Cleaning up hosts:" target=$hosts elif [ x"$group" != x ]; then echo `date` ": Cleaning up group: $group" target="-g $group" else echo "You didn't specify any nodes to clean up" exit 1 fi cluster-helper --list bullet $target if [ $kill != 0 ]; then echo "Cleaning processes" # Bah. Force systemd to actually look at the process and realize its dead" cluster-helper $target -- "service corosync stop" &> /dev/null & cluster-helper $target -- "service pacemaker stop" &> /dev/null & cluster-helper $target -- "killall -q -9 corosync aisexec heartbeat pacemakerd pacemaker-remoted ccm stonithd ha_logd lrmd crmd pengine attrd pingd mgmtd cib fenced dlm_controld gfs_controld" &> /dev/null cluster-helper $target -- 'kill -9 `pidof valgrind`' &> /dev/null if [ $kill == 2 ]; then exit 0 fi fi #logrotate -f $cluster_rotate echo "Cleaning files" log_files="" log_files="$log_files 'messages*'" log_files="$log_files 'localmessages*'" log_files="$log_files 'cluster*.log'" log_files="$log_files corosync.log" log_files="$log_files pacemaker.log" state_files="" state_files="$state_files 'cib.xml*'" state_files="$state_files 'valgrind-*'" state_files="$state_files 'cib-*'" state_files="$state_files 'core.*'" state_files="$state_files hostcache" state_files="$state_files 'cts.*'" state_files="$state_files 'pe*.bz2'" for f in $log_files; do cluster-helper $target -- "find /var/log -name '$f' -exec rm -f \{\} \;" done for f in $state_files; do cluster-helper $target -- "find /var/lib -name '$f' -exec rm -f \{\} \;" done cluster-helper $target -- "find /dev/shm -name 'qb-*' -exec rm -f \{\} \;" cluster-helper $target -- "find /var/lib/pacemaker/blackbox -name '*.*' -exec rm -f \{\} \;" cluster-helper $target -- "find /tmp -name '*.valgrind' -exec rm -f \{\} \;" cluster-helper $target -- service rsyslog restart 2>&1 > /dev/null cluster-helper $target -- logger -i -p daemon.info __clean_logs__ #touch $cluster_log echo `date` ": Clean complete" pacemaker-master/extra/cluster-helper000077500000000000000000000112221217637305600203160ustar00rootroot00000000000000#!/bin/bash hosts= group=$cluster_name user=root pdsh=`which pdsh 2>/dev/null` ssh=`which qarsh 2>/dev/null` scp=`which qacp 2>/dev/null` command=list format=oneline replace="{}" if [ x$ssh = "x" ]; then ssh=ssh scp=scp fi function helptext() { echo "cluster-helper - A tool for running commands on multiple hosts" echo "" echo "Attempt to use pdsh, qarsh, or ssh (in that order) to execute commands" echo "on mutiple hosts" echo "" echo "DSH groups can be configured and specified with -g instead of listing" echo "the individual hosts every time" echo "" echo "Usage: cluster-helper [options] [command]" echo "" echo "Options:" echo "--ssh Force the use of ssh instead of qarsh even if it available" echo "-g, --group Specify the group to operate on/with" echo "-w, --host Specify a host to operate on/with. May be specified multiple times" echo "-f, --format Specifiy the output format When listing hosts or group contents" echo " Allowed values: [oneline], long, short, pdsh, bullet" echo "" echo "" echo "Commands:" echo "--list format List the contents of a group in the specified format" echo "--add name Add supplied (-w) hosts to the named group" echo "--create name Create the named group with the supplied (-w) hosts" echo "--run, -- Treat all subsequent arguments as a command to perform on" echo " the specified command on the hosts or group" echo "--xargs Run the supplied command having replaced any occurances" echo " of {} with the node name" echo "" echo "--copy file(s) host:file Pass subsequent arguments to scp or qacp" echo " Any occurances of {} are replaced with the node name" echo "" exit $1 } while true ; do case "$1" in --help|-h|-\?) helptext 0;; -x) set -x; shift;; --ssh) ssh="ssh"; scp="scp"; shift;; -g|--group) group="$2"; shift; shift;; -w|--host) for h in $2; do hosts="$hosts -w $h"; done shift; shift;; -f|--format) format=$2; shift; shift;; -I) replace=$2; shift; shift;; --list|list) format=$2; command=list; shift; shift;; --add|add) command=group-add; shift;; --create|create) group="$2", command=group-create; shift; shift;; --run|run) command=run; shift;; --copy|copy) command=copy; shift; break ;; --xargs) command=xargs; shift; break ;; --) command=run; shift; break ;; "") break;; *) helptext 1;; esac done if [ x"$group" = x -a x"$hosts" = x ]; then group=$CTS_GROUP fi function expand() { fmt=$1 if [ x$group != x -a -f ~/.dsh/group/$group ]; then hosts=`cat ~/.dsh/group/$group` elif [ x$group != x ]; then echo "Unknown group: $group" >&2 exit 1 fi if [ "x$hosts" != x -a $fmt = oneline ]; then echo $hosts elif [ "x$hosts" != x -a $fmt = short ]; then ( for h in $hosts; do echo $h | sed 's:\..*::' done ) | tr '\n' ' ' echo "" elif [ "x$hosts" != x -a $fmt = pdsh ]; then ( for h in $hosts; do echo "-w $h" done ) | tr '\n' ' ' echo "" elif [ "x$hosts" != x -a $fmt = long ]; then for h in $hosts; do echo $h done elif [ "x$hosts" != x -a $fmt = bullet ]; then for h in $hosts; do echo " * $h" done elif [ "x$hosts" != x ]; then echo "Unknown format: $fmt" >&2 fi } if [ $command = list ]; then expand $format elif [ $command = group-create ]; then f=`mktemp` mkdir -p ~/.dsh/group if [ -f ~/.dsh/group/$group ]; then echo "Overwriting existing group $group" fi for h in $hosts; do echo $h >> $f done echo "Creating group $group in ~/.dsh/group" sort -u $f > ~/.dsh/group/$group rm -f $f elif [ $command = group-add ]; then if [ x$group = x ]; then echo "Please specify a group to append to" exit 1 fi f=`mktemp` mkdir -p ~/.dsh/group if [ -f ~/.dsh/group/$group ]; then cat ~/.dsh/group/$group > $f fi for h in $hosts; do echo $h >> $f done echo "Appending hosts to group $group in ~/.dsh/group" sort -u $f > ~/.dsh/group/$group rm -f $f elif [ $command = run ]; then if [ x$pdsh != x ]; then hosts=`expand pdsh` $pdsh -l $user $hosts -- $* else hosts=`expand oneline` for n in $hosts; do $ssh -l $user $n -- $* < /dev/null done if [ x"$hosts" = x ]; then echo "No hosts specified" fi fi elif [ $command = copy ]; then hosts=`expand oneline` for n in $hosts; do $scp `echo $* | sed 's@'$replace'@'$n'@'` done elif [ $command = xargs ]; then hosts=`expand oneline` for n in $hosts; do eval `echo $* | sed 's@'$replace'@'$n'@'` done fi pacemaker-master/extra/cluster-init000077500000000000000000000476111217637305600200150ustar00rootroot00000000000000#!/bin/bash accept_defaults=0 do_raw=0 ETCHOSTS=0 CMAN=0 do_heartbeat=0 plugin_ver=-1 pcmk_ver=11 nodelist=0 pkgs="corosync xinetd nmap abrt-cli fence-agents perl-TimeDate gdb" transport="multicast" inaddr_any="no" INSTALL= cs_conf= fence_conf= rpm_repo= distro= dsh_group=0 cluster=dummy0 # Corosync/OpenAIS Settings cs_port=666 # Settings that work great on nXX join=60 #token=3000 consensus=1500 # Official settings join=2000 token=5000 consensus=2500 # Testing join=1000 consensus=7500 do_debug=off function ip_for_node() { ping -c 1 $1 | grep "bytes from" | head -n 1 | sed -e 's/.*bytes from//' -e 's/: icmp.*//' | awk '{print $NF}' | sed 's:(::' | sed 's:)::' # if [ $do_raw = 1 ]; then # echo $1 # else # #host $1 | grep "has address" | head -n 1 | awk '{print $NF}' | sed 's:(::' | sed 's:)::' # fi } function id_for_node() { ip_for_node $* | tr '.' ' ' | awk '{print $4}' } function name_for_node() { echo $1 | awk -F. '{print $1}' } function helptext() { echo "cluster-init - Configure cluster communication for the different infrastructures supported by Pacemaker" echo "" echo "-g, --group Specify the group to operate on/with" echo "-w, --host Specify a host to operate on/with. May be specified multiple times" echo "-r, --raw-ip Supplied nodes were listed as their IP addresses" echo "" echo "-h, --heartbeat configure for heartbeat" echo "-c, --corosync configure for corosync" echo "-C, --nodelist configure for corosync with a node list" echo "-o, --openais configure for openais" echo "--cman configure for cman" echo "-p, --plugin version" echo "-u, --unicast configure point-to-point communication instead of multicast (corosync only)" echo "" echo "-I, --install Install packages" echo "-R, --repo name Setup and update/install Pacemaker from the named clusterlabs.org repo" echo " Known values: rpm, rpm-test, rpm-next, rpm-test-next, rpm-test-rhel" echo "-D, --distro The distro within the --repo. Defaults to fedora-15" echo "" echo "-d, --debug Enable debug logging for the cluster" echo "-10 install stable-1.0 packages, implies: -p 0 -R rpm-test -I" echo "--hosts Copy /etc/hosts from the test master to the nodes" echo "-e, --extra package-list" echo " Extra packages to install" exit $1 } host_input="" while true; do case "$1" in -g) cluster=$2; dsh_group=`echo $cluster | sed s/[a-zA-Z]*//` host_input="-g $cluster" shift; shift;; -w|--host) for h in $2; do host_input="$host_input -w $h"; done shift; shift;; -w) host_input="$host_input -w $2" shift; shift;; -r|--raw-ip) do_raw=1; shift;; -D) distro=$2; shift; shift;; -d|--debug) do_debug=on; shift;; -R|--repo) rpm_repo=$2; shift; shift;; -I|--install) INSTALL=Yes; shift;; --hosts) ETCHOSTS=1; shift;; cman|--cman) CTYPE=cman; shift;; -h|--heartbeat) CTYPE=heartbeat; shift;; -c|--corosync) CTYPE=corosync; shift;; -C|--nodelist) CTYPE=corosync; nodelist=1; shift;; -o|--openais) CTYPE=openais; shift;; --plugin|-p) CTYPE=plugin; plugin_ver=$2; shift; shift;; -u|--unicast) nodelist=1; transport=udpu; inaddr_any="yes"; shift;; -e|--extra) pkgs="$pkgs $2"; shift; shift;; -t|--test) rpm_repo=rpm-test-next; pkgs="$pkgs valgrind"; shift;; r*[0-9]) rhel=`echo $1 | sed -e s/rhel// -e s/-// -e s/r//` distro="rhel-$rhel"; pkgs="$pkgs qarsh-server"; case $rhel in 6) CTYPE=cman;; 7) CTYPE=corosync;; esac shift ;; f*[0-9][0-9]) distro="fedora-`echo $1 | sed -e s/fedora// -e s/-// -e s/f//`"; CTYPE=corosync; shift ;; p0|10) pcmk_ver=10; plugin_ver=0; rpm_repo="rpm-test"; install=1; shift;; -y|--yes|--defaults) accept_defaults=1; shift;; -x) set -x; shift;; -\?|--help) helptext 0; shift;; "") break;; *) echo "unknown option: $1"; exit 1;; esac done if [ x = "x$host_input" -a x = "x$cluster_name" ]; then if [ -d $HOME/.dsh/group ]; then read -p "Please specify a dsh group you'd like to configure as a cluster? [] " -t 60 cluster_name else read -p "Please specify a whitespace delimetered list of nodes you'd like to configure as a cluster? [] " -t 60 host_list for h in $2; do host_input="$host_input -w $h"; done fi fi if [ ! -z $cluster_name ]; then host_input="-g $cluster_name" dsh_group=`echo $cluster_name | sed s/[a-zA-Z]*//` fi if [ -z "$host_input" ]; then echo "You didn't specify any nodes or groups to configure" exit 1 fi host_list=`cluster-helper --list short $host_input` num_hosts=`echo $host_list | wc -w` if [ -z $dsh_group ]; then dsh_group=1 fi if [ -z $CTYPE ]; then echo "" read -p "Where should Pacemaker obtain membership and quorum from? [corosync] (corosync, cman, plugin, openais, heartbeat) " -t 60 CTYPE fi case $CTYPE in cman) CMAN=1; cs_conf=/etc/cluster/cluster.conf;; corosync) cs_conf=/etc/corosync/corosync.conf;; heartbeat) do_heartbeat=1;; openais) cs_conf=/etc/ais/openais.conf;; plugin) cs_conf=/etc/corosync/corosync.conf if [ -z $plugin_ver ]; then echo "" read -p "Should corosync start Pacemaker? [No]" -t 60 PTYPE case $PTYPE in [Yy][Ee][Ss]|[Yy]) plugin_ver=0;; *) plugin_ver=1;; esac fi ;; esac function get_defaults() { if [ -z $SSH ]; then SSH="No" fi if [ -z $SELINUX ]; then SELINUX="Yes" fi if [ -z $IPTABLES ]; then IPTABLES="Yes" fi if [ -z $DOMAIN ]; then DOMAIN="No" fi if [ -z $INSTALL ]; then INSTALL="Yes" fi if [ -z $DATE ]; then DATE="Yes" fi } get_defaults if [ $accept_defaults = 0 ]; then echo "" read -p "Shall I install an ssh key to cluster nodes? [$SSH] " -t 60 SSH echo "" echo "SELinux prevent many things, including password-less ssh logins" read -p "Shall I disable selinux? [$SELINUX] " -t 60 SELINUX echo "" echo "Incorrectly configured firewalls will prevent corosync from starting up" read -p "Shall I disable iptables? [$IPTABLES] " -t 60 IPTABLES if [ $CMAN = 1 ]; then echo "" echo "Without a default domain, cman probably wont start because it can't look up the IP for hosts" read -p "Shall I set one? [No] (domain.name) " -t 60 DOMAIN elif [ $pcmk_ver = 10 ]; then echo "" echo "Without a default domain, external/ssh fencing probably wont work because it can't find its peers" read -p "Shall I set one? [No] (domain.name) " -t 60 DOMAIN fi echo "" read -p "Shall I install/update the relevant packages? [$INSTALL] " -t 60 INSTALL case $INSTALL in [Yy][Ee][Ss]|[Yy]|"") if [ -z $rpm_repo ]; then echo "" read -p "Would you like to install packages from ClusterLabs.org? [No] (rpm, rpm-next, rpm-test-next) " -t 60 rpm_repo fi if [ ! -z $rpm_repo ]; then if [ -z $distro ]; then distro=fedora-18 echo "" read -p "Which distro are you installing for? [$distro] (eg. fedora-17, rhel-6) " -t 60 distro fi fi ;; esac echo "" read -p "Shall I sync the date/time? [$DATE] " -t 60 DATE fi get_defaults echo "" echo "Detecting possible fencing options" if [ -e /etc/cluster/fence_xvm.key ]; then echo "* Found fence_xvm" fence_conf=/etc/cluster/fence_xvm.key pkgs="$pkgs fence-virt" fi if [ ! -z ${OS_AUTH_URL} ]; then echo "* Found openstack credentials" fence_conf=/sbin/fence_openstack pkgs="$pkgs python-novaclient" fi echo "" echo "Beginning cluster configuration" echo "" case $SSH in [Yy][Ee][Ss]|[Yy]) for host in $host_list; do echo "Installing our ssh key on ${host}" ssh-copy-id root@${host} >/dev/null 2>&1 # Fix selinux labeling ssh -l root ${host} -- restorecon -R -v . done ;; esac case $DATE in [Yy][Ee][Ss]|[Yy]) for host in $host_list; do echo "Setting time on ${host}" scp /etc/localtime root@${host}:/etc now=`date` ssh -l root ${host} -- date -s "'$now'" echo "" done ;; esac REPO= if [ ! -z $rpm_repo ]; then REPO=$rpm_repo/$distro fi if [ $do_heartbeat = 1 ]; then pkgs="$pkgs heartbeat" fi if [ $CMAN = 1 ]; then pkgs="$pkgs cman" fi init=`mktemp` cat<<-END>$init verbose=0 pkgs="$pkgs" lhost=\`uname -n\` lshort=\`echo \$lhost | awk -F. '{print \$1}'\` log() { printf "%-10s \$*\n" "\$lshort:" 1>&2 } debug() { if [ \$verbose -gt 0 ]; then log "Debug: \$*" fi } info() { log "\$*" } warning() { log "WARN: \$*" } fatal() { log "ERROR: \$*" exit 1 } case $SELINUX in [Yy][Ee][Ss]|[Yy]|"") sed -i.sed "s/enforcing/disabled/g" /etc/selinux/config ;; esac case $IPTABLES in [Yy][Ee][Ss]|[Yy]|"") service iptables stop chkconfig iptables off service firewalld stop chkconfig firewalld off ;; esac case $DOMAIN in [Nn][Oo]|"") ;; *.*) if ! grep domain /etc/resolv.conf then sed -i.sed "s/nameserver/domain\ $DOMAIN\\\nnameserver/g" /etc/resolv.conf fi ;; *) echo "Unknown domain: $DOMAIN";; esac case $INSTALL in [Yy][Ee][Ss]|[Yy]|"") if [ ! -z $REPO ]; then info Configuring Clusterlabs repo: $REPO yum install -y wget rm -f /etc/yum.repos.d/clusterlabs.repo wget -O /etc/yum.repos.d/clusterlabs.repo http://www.clusterlabs.org/$REPO/clusterlabs.repo &>/dev/null yum clean all fi info Installing cluster software if [ $pcmk_ver = 10 ]; then yum install -y $pkgs at service atd start systemctl enable atd.service yum install -y "pacemaker < 1.1" else yum install -y $pkgs pacemaker fi ;; esac info "Configuring services" chkconfig xinetd on service xinetd start &>/dev/null chkconfig corosync off &> /dev/null chkconfig heartbeat off &> /dev/null mkdir -p /etc/cluster info "Turning on core files" grep -q "unlimited" /etc/bashrc if [ $? = 1 ]; then sed -i.sed "s/bashrc/bashrc\\\nulimit\ -c\ unlimited/g" /etc/bashrc fi if [ $CMAN = 1 ]; then grep -q "logger" /etc/init.d/cman if [ $? = 1 ]; then info "Turning on CMAN init-script logging" sed -i.sed "s/function=/logger\ -p\ daemon.info\ cman\ init\ \\\$1\\\nfunction=/g" /etc/init.d/cman fi sed -i.sed "s/.*CMAN_QUORUM_TIMEOUT=.*/CMAN_QUORUM_TIMEOUT=0/g" /etc/sysconfig/cman fi END function create_hb_config() { cat <<-END >/tmp/lha.$$ auth 1 1 crc END printf "%-10s Installing authkeys\n" ${host} scp -q /tmp/lha.$$ root@${host}:/etc/ha.d/authkeys ssh -l root ${host} -- chmod 600 /etc/ha.d/authkeys cat <<-END >/tmp/lha.$$ traditional_compression off compression bz2 realtime yes conn_logd_time 120 coredumps true udpport $cs_port$dsh_group bcast eth0 autojoin any logfacility daemon crm respawn # 8-node version debug 0 keepalive 1 warntime 6 deadtime 10 initdead 15 END printf "%-10s Installing ha.cf\n" ${host} scp -q /tmp/lha.$$ root@${host}:/etc/ha.d/ha.cf } function patch_cs_config() { test $num_hosts != 2 two_node=$? priority="info" if [ $do_debug = 1 ]; then priority="debug" fi ssh -l root ${host} -- sed -i.sed "s/.*mcastaddr:.*/mcastaddr:\ 226.94.1.1/g" $cs_conf ssh -l root ${host} -- sed -i.sed "s/.*mcastport:.*/mcastport:\ $cs_port$dsh_group/g" $cs_conf ssh -l root ${host} -- sed -i.sed "s/.*bindnetaddr:.*/bindnetaddr:\ $ip/g" $cs_conf ssh -l root ${host} -- sed -i.sed "s/.*syslog_facility:.*/syslog_facility:\ daemon/g" $cs_conf ssh -l root ${host} -- sed -i.sed "s/.*logfile_priority:.*/logfile_priority:\ $priority/g" $cs_conf if [ ! -z $token ]; then ssh -l root ${host} -- sed -i.sed "s/.*token:.*/token:\ $token/g" $cs_conf fi if [ ! -z $consensus ]; then ssh -l root ${host} -- sed -i.sed "s/.*consensus:.*/consensus:\ $consensus/g" $cs_conf fi if [ ! -z $join ]; then ssh -l root ${host} -- sed -i.sed "s/^join:.*/join:\ $join/g" $cs_conf ssh -l root ${host} -- sed -i.sed "s/\\\Wjoin:.*/join:\ $join/g" $cs_conf fi if [ $plugin_ver -ge 0 ]; then ssh -l root ${host} -- grep -q "name: pacemaker" $cs_conf 2>&1 > /dev/null if [ $? = 0 ]; then ssh -l root ${host} -- sed -i.sed "s/.*ver:.*/ver:\ $plugin_ver/g" $cs_conf else printf "%-10s Wrong quorum provider: installing $cs_conf for plugin v${plugin_ver} instead\n" ${host} create_cs_config fi elif [ $CMAN = 1 ]; then ssh -l root ${host} -- grep -q "quorum_cman" $cs_conf 2>&1 > /dev/null if [ $? = 0 ]; then ssh -l root ${host} -- sed -i.sed "s/\\\Wexpected_votes:.*/expected_votes:\ $num_hosts/g" $cs_conf ssh -l root ${host} -- sed -i.sed "s/\\\Wtwo_node:.*/two_node:\ $two_node/g" $cs_conf else printf "%-10s Wrong quorum provider: installing $cs_conf for cman instead\n" ${host} create_cs_config fi else ssh -l root ${host} -- grep -q "corosync_votequorum" $cs_conf 2>&1 > /dev/null if [ $? = 0 ]; then ssh -l root ${host} -- sed -i.sed "s/\\\Wexpected_votes:.*/expected_votes:\ $num_hosts/g" $cs_conf ssh -l root ${host} -- sed -i.sed "s/\\\Wtwo_node:.*/two_node:\ $two_node/g" $cs_conf else printf "%-10s Wrong quorum provider: installing $cs_conf for corosync instead\n" ${host} create_cs_config fi fi } function create_cs_config() { cs_tmp=/tmp/cs_conf.$$ test $num_hosts != 2 two_node=$? # Base config priority="info" if [ $do_debug = 1 ]; then priority="debug" fi cat <<-END >$cs_tmp # Please read the corosync.conf.5 manual page totem { version: 2 # cypto_cipher and crypto_hash: Used for mutual node authentication. # If you choose to enable this, then do remember to create a shared # secret with "corosync-keygen". crypto_cipher: none crypto_hash: none # Assign a fixed node id nodeid: $id # Disable encryption secauth: off transport: $transport inaddr_any: $inaddr_any # interface: define at least one interface to communicate # over. If you define more than one interface stanza, you must # also set rrp_mode. interface { # Rings must be consecutively numbered, starting at 0. ringnumber: 0 # This is normally the *network* address of the # interface to bind to. This ensures that you can use # identical instances of this configuration file # across all your cluster nodes, without having to # modify this option. bindnetaddr: $ip # However, if you have multiple physical network # interfaces configured for the same subnet, then the # network address alone is not sufficient to identify # the interface Corosync should bind to. In that case, # configure the *host* address of the interface # instead: # bindnetaddr: 192.168.1.1 # When selecting a multicast address, consider RFC # 2365 (which, among other things, specifies that # 239.255.x.x addresses are left to the discretion of # the network administrator). Do not reuse multicast # addresses across multiple Corosync clusters sharing # the same network. # Corosync uses the port you specify here for UDP # messaging, and also the immediately preceding # port. Thus if you set this to 5405, Corosync sends # messages over UDP ports 5405 and 5404. mcastport: $cs_port$dsh_group # Time-to-live for cluster communication packets. The # number of hops (routers) that this ring will allow # itself to pass. Note that multicast routing must be # specifically enabled on most network routers. ttl: 1 mcastaddr: 226.94.1.1 } } logging { debug: off fileline: off to_syslog: yes to_stderr: no syslog_facility: daemon timestamp: on to_logfile: yes logfile: /var/log/corosync.log logfile_priority: $priority } amf { mode: disabled } END # Corosync Variant if [ $plugin_ver -ge 0 ]; then cat <<-END >>$cs_tmp service { name: pacemaker ver: $plugin_ver } END elif [ $CMAN = 1 ]; then cat <<-END >>$cs_tmp cluster { name: $cluster clusternodes { END for peer in $host_list; do p_name=`name_for_node $peer` p_id=`id_for_node $peer` cat <<-END >>$cs_tmp clusternode { votes: 1 nodeid: $p_id name: $p_name } END done cat <<-END >>$cs_tmp } cman { expected_votes: $num_hosts cluster_id: $dsh_group nodename: $cs_short_host two_node: $two_node max_queued: 10 } } service { name: corosync_cman ver: 0 } quorum { provider: quorum_cman } END elif [ $nodelist = 1 ]; then cat <<-END >>$cs_tmp nodelist { END for peer in $host_list; do p_name=`name_for_node $peer` p_id=`id_for_node $peer` p_ip=`ip_for_node $peer` cat <<-END >>$cs_tmp node { ring0_addr: $p_ip nodeid: $p_id quorum_votes: 1 name: $peer } END done cat <<-END >>$cs_tmp } quorum { provider: corosync_votequorum expected_votes: $num_hosts votes: 1 two_node: $two_node wait_for_all: 0 last_man_standing: 0 auto_tie_breaker: 0 } END else cat <<-END >>$cs_tmp quorum { provider: corosync_votequorum expected_votes: $num_hosts votes: 1 two_node: $two_node wait_for_all: 0 last_man_standing: 0 auto_tie_breaker: 0 } END fi scp -q $cs_tmp root@${host}:$cs_conf rm -f $cs_tmp } function create_cman_config() { cs_tmp=/tmp/cs_conf.$$ cat <<-END >$cs_tmp END lpc=1 for h in $host_list; do short_h=`name_for_node $h` cat <<-END >>$cs_tmp END lpc=`expr $lpc + 1` done test $num_hosts != 2 two_node=$? extra="" if [ $two_node = 1 ]; then extra="\n " fi cat <<-END >>$cs_tmp $extra END scp -q $cs_tmp root@${host}:$cs_conf rm -f $cs_tmp } for host in $host_list; do echo "" echo "" echo "* Configuring $host" cs_short_host=`name_for_node $host` ip=`ip_for_node $host` id=`id_for_node $host` echo $ip | grep -qis NXDOMAIN if [ $? = 0 ]; then echo "Couldn't find resolve $host to an IP address" exit 1 fi if [ `uname -n` = $host ]; then bash $init else cat $init | ssh -l root -T $host -- "cat > $init; bash $init" fi if [ "x$fence_conf" != x ]; then if [ -e $fence_conf ]; then scp $fence_conf root@${host}:$fence_conf fi fi if [ $ETCHOSTS = 1 ]; then scp /etc/hosts root@${host}:/etc/hosts fi if [ $pcmk_ver = 10 ]; then scp /etc/hosts root@${host}:/etc/hosts scp ~/.ssh/id_dsa.suse root@${host}:.ssh/id_dsa scp ~/.ssh/known_hosts root@${host}:.ssh/known_hosts fi if [ $do_heartbeat = 1 ]; then create_hb_config ${host} elif [ $CMAN = 1 ]; then create_cman_config printf "%-10s Installed $cs_conf\n" ${host}: else ssh -l root ${host} -- grep -q "token:" $cs_conf 2>&1 > /dev/null new_config=$? new_config=1 if [ $new_config = 0 ]; then printf "%-10s Updating $cs_conf\n" ${host}: patch_cs_config else printf "%-10s Installing $cs_conf\n" ${host}: create_cs_config fi fi done pacemaker-master/extra/pcmk_snmp_helper.sh000066400000000000000000000046551217637305600213300ustar00rootroot00000000000000#!/bin/bash # # Copyright (C) 2013 Florian CROUZAT # # 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 2 of the License, or (at your option) any later version. # # This software 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 library; if not, write to the Free Software # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA # Resources: # crm ra meta ocf:pacemaker:ClusterMon # man 8 crm_mon # Sample configuration # ================================ # primitive ClusterMon ocf:pacemaker:ClusterMon \ # params user="root" update="30" extra_options="-E /path/to/pcmk_snmp_helper.sh -e 192.168.1.2" \ # op monitor on-fail="restart" interval="10" # # clone ClusterMon-clone ClusterMon \ # meta target-role="Started" # ================================ # The external agent is fed with environment variables allowing us to know # what transition happened and to react accordingly: # http://clusterlabs.org/doc/en-US/Pacemaker/1.1-crmsh/html/Pacemaker_Explained/s-notification-external.html # Generates SNMP alerts for any failing monitor operation # OR # for any operations (even successful) that are not a monitor if [[ ${CRM_notify_rc} != 0 && ${CRM_notify_task} == "monitor" ]] || [[ ${CRM_notify_task} != "monitor" ]] ; then # This trap is compliant with PACEMAKER MIB # https://github.com/ClusterLabs/pacemaker/blob/master/extra/PCMK-MIB.txt /usr/bin/snmptrap -v 2c -c public ${CRM_notify_recipient} "" PACEMAKER-MIB::pacemakerNotification \ PACEMAKER-MIB::pacemakerNotificationNode s "${CRM_notify_node}" \ PACEMAKER-MIB::pacemakerNotificationResource s "${CRM_notify_rsc}" \ PACEMAKER-MIB::pacemakerNotificationOperation s "${CRM_notify_task}" \ PACEMAKER-MIB::pacemakerNotificationDescription s "${CRM_notify_desc}" \ PACEMAKER-MIB::pacemakerNotificationStatus i "${CRM_notify_status}" \ PACEMAKER-MIB::pacemakerNotificationReturnCode i ${CRM_notify_rc} \ PACEMAKER-MIB::pacemakerNotificationTargetReturnCode i ${CRM_notify_target_rc} && exit 0 || exit 1 fi exit 0 pacemaker-master/extra/resources/000077500000000000000000000000001217637305600174465ustar00rootroot00000000000000pacemaker-master/extra/resources/ClusterMon000066400000000000000000000157721217637305600215000ustar00rootroot00000000000000#!/bin/sh # # # ClusterMon OCF RA. # Starts crm_mon in background which logs cluster status as # html to the specified file. # # Copyright (c) 2004 SUSE LINUX AG, Lars Marowsky-Bre # All Rights Reserved. # # This program is free software; you can redistribute it and/or modify # it under the terms of version 2 of the GNU General Public License as # published by the Free Software Foundation. # # This program is distributed in the hope that it would be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # # Further, this software is distributed without any warranty that it is # free of the rightful claim of any third person regarding infringement # or the like. Any license provided herein, whether implied or # otherwise, applies only to this software file. Patent licenses, if # any, provided herein do not apply to combinations of this program with # other software, or any other product whatsoever. # # You should have received a copy of the GNU General Public License # along with this program; if not, write the Free Software Foundation, # Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. # # OCF instance parameters: # OCF_RESKEY_user # OCF_RESKEY_pidfile # OCF_RESKEY_update # OCF_RESKEY_extra_options # OCF_RESKEY_htmlfile ####################################################################### # Initialization: : ${OCF_FUNCTIONS=${OCF_ROOT}/resource.d/heartbeat/.ocf-shellfuncs} . ${OCF_FUNCTIONS} : ${__OCF_ACTION=$1} ####################################################################### meta_data() { cat < 1.0 This is a ClusterMon Resource Agent. It outputs current cluster status to the html. Runs crm_mon in the background, recording the cluster status to an HTML file The user we want to run crm_mon as The user we want to run crm_mon as How frequently should we update the cluster status Update interval Additional options to pass to crm_mon. Eg. -n -r Extra options PID file location to ensure only one instance is running PID file Location to write HTML output to. HTML output END } ####################################################################### ClusterMon_usage() { cat </dev/null 2>&1; rc=$? case $rc in 0) exit $OCF_SUCCESS;; 1) exit $OCF_NOT_RUNNING;; *) exit $OCF_ERR_GENERIC;; esac fi fi exit $OCF_NOT_RUNNING } CheckOptions() { while getopts Vi:nrh:cdp: OPTION do case $OPTION in V|n|r|c|d);; i) ocf_log warn "You should not have specified the -i option, since OCF_RESKEY_update is set already!";; h) ocf_log warn "You should not have specified the -h option, since OCF_RESKEY_htmlfile is set already!";; p) ocf_log warn "You should not have specified the -p option, since OCF_RESKEY_pidfile is set already!";; *) return $OCF_ERR_ARGS;; esac done if [ $? -ne 0 ]; then return $OCF_ERR_ARGS fi # We should have eaten all options at this stage shift $(($OPTIND -1)) if [ $# -gt 0 ]; then false else true fi } ClusterMon_validate() { # Existence of the user if [ ! -z $OCF_RESKEY_user ]; then getent passwd "$OCF_RESKEY_user" >/dev/null if [ $? -eq 0 ]; then : Yes, user exists. We can further check his permission on crm_mon if necessary else ocf_log err "The user $OCF_RESKEY_user does not exist!" exit $OCF_ERR_ARGS fi fi # Pidfile better be an absolute path case $OCF_RESKEY_pidfile in /*) ;; *) ocf_log warn "You should have pidfile($OCF_RESKEY_pidfile) of absolute path!" ;; esac # Check the update interval if ocf_is_decimal "$OCF_RESKEY_update" && [ $OCF_RESKEY_update -gt 0 ]; then : else ocf_log err "Invalid update interval $OCF_RESKEY_update. It should be positive integer!" exit $OCF_ERR_ARGS fi if CheckOptions $OCF_RESKEY_extra_options; then : else ocf_log err "Invalid options $OCF_RESKEY_extra_options!" exit $OCF_ERR_ARGS fi # Htmlfile better be an absolute path case $OCF_RESKEY_htmlfile in /*) ;; *) ocf_log warn "You should have htmlfile($OCF_RESKEY_htmlfile) of absolute path!" ;; esac echo "Validate OK" return $OCF_SUCCESS } if [ $# -ne 1 ]; then ClusterMon_usage exit $OCF_ERR_ARGS fi : ${OCF_RESKEY_update:="15000"} : ${OCF_RESKEY_pidfile:="/tmp/ClusterMon_${OCF_RESOURCE_INSTANCE}.pid"} : ${OCF_RESKEY_htmlfile:="/tmp/ClusterMon_${OCF_RESOURCE_INSTANCE}.html"} OCF_RESKEY_update=`expr $OCF_RESKEY_update / 1000` case $__OCF_ACTION in meta-data) meta_data exit $OCF_SUCCESS ;; start) ClusterMon_start ;; stop) ClusterMon_stop ;; monitor) ClusterMon_monitor ;; validate-all) ClusterMon_validate ;; usage|help) ClusterMon_usage exit $OCF_SUCCESS ;; *) ClusterMon_usage exit $OCF_ERR_UNIMPLEMENTED ;; esac exit $? pacemaker-master/extra/resources/Dummy000066400000000000000000000136501217637305600204710ustar00rootroot00000000000000#!/bin/sh # # # Dummy OCF RA. Does nothing but wait a few seconds, can be # configured to fail occassionally. # # Copyright (c) 2004 SUSE LINUX AG, Lars Marowsky-Bre # All Rights Reserved. # # This program is free software; you can redistribute it and/or modify # it under the terms of version 2 of the GNU General Public License as # published by the Free Software Foundation. # # This program is distributed in the hope that it would be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # # Further, this software is distributed without any warranty that it is # free of the rightful claim of any third person regarding infringement # or the like. Any license provided herein, whether implied or # otherwise, applies only to this software file. Patent licenses, if # any, provided herein do not apply to combinations of this program with # other software, or any other product whatsoever. # # You should have received a copy of the GNU General Public License # along with this program; if not, write the Free Software Foundation, # Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. # ####################################################################### # Initialization: : ${OCF_FUNCTIONS=${OCF_ROOT}/resource.d/heartbeat/.ocf-shellfuncs} . ${OCF_FUNCTIONS} : ${__OCF_ACTION=$1} ####################################################################### meta_data() { cat < 1.0 This is a Dummy Resource Agent. It does absolutely nothing except keep track of whether its running or not. Its purpose in life is for testing and to serve as a template for RA writers. NB: Please pay attention to the timeouts specified in the actions section below. They should be meaningful for the kind of resource the agent manages. They should be the minimum advised timeouts, but they shouldn't/cannot cover _all_ possible resource instances. So, try to be neither overly generous nor too stingy, but moderate. The minimum timeouts should never be below 10 seconds. Example stateless resource agent Location to store the resource state in. State file Fake attribute that can be changed to cause a reload Fake attribute that can be changed to cause a reload Number of seconds to sleep during operations. This can be used to test how the cluster reacts to operation timeouts. Operation sleep duration in seconds. END } ####################################################################### # don't exit on TERM, to test that lrmd makes sure that we do exit trap sigterm_handler TERM sigterm_handler() { ocf_log info "They use TERM to bring us down. No such luck." return } dummy_usage() { cat < 0.1 Systhem health agent that measures the CPU idling and updates the #health-cpu attribute. System health CPU usage Location to store the resource state in. State file Lower (!) limit of idle percentage to switch the health attribute to yellow. I.e. the #health-cpu will go yellow if the %idle of the CPU falls below 50%. Lower limit for yellow health attribute Lower (!) limit of idle percentage to switch the health attribute to red. I.e. the #health-cpu will go red if the %idle of the CPU falls below 10%. Lower limit for red health attribute END } ####################################################################### # don't exit on TERM, to test that lrmd makes sure that we do exit trap sigterm_handler TERM sigterm_handler() { ocf_log info "They use TERM to bring us down. No such luck." return } dummy_usage() { cat < 0.1 Systhem health agent that checks the S.M.A.R.T. status of the given drives and updates the #health-smart attribute. SMART health status Location to store the resource state in. State file The drive(s) to check as a SPACE separated list. Enter the full path to the device, e.g. "/dev/sda". Drives to check The device type(s) to assume for the drive(s) being tested as a SPACE separated list. Device types Lower limit of the temperature in deg C of the drive(s). Below this limit the status will be red. Lower limit for the red smart attribute Upper limit of the temperature if deg C of the drives(s). If the drive reports a temperature higher than this value the status of #health-smart will be red. Upper limit for red smart attribute Number of deg C below/above the upper/lower temp limits at which point the status of #health-smart will change to yellow. Deg C below/above the upper limits for yellow smart attribute END } ####################################################################### check_temperature() { if [ $1 -lt ${lower_red_limit} ] ; then ocf_log info "Drive ${DRIVE} ${DEVICE} too cold: ${1} C" $ATTRDUP -n "#health-smart" -U "red" -d "5s" return 1 fi if [ $1 -gt ${upper_red_limit} ] ; then ocf_log info "Drive ${DRIVE} ${DEVICE} too hot: ${1} C" $ATTRDUP -n "#health-smart" -U "red" -d "5s" return 1 fi if [ $1 -lt ${lower_yellow_limit} ] ; then ocf_log info "Drive ${DRIVE} ${DEVICE} quite cold: ${1} C" $ATTRDUP -n "#health-smart" -U "yellow" -d "5s" return 1 fi if [ $1 -gt ${upper_yellow_limit} ] ; then ocf_log info "Drive ${DRIVE} ${DEVICE} quite hot: ${1} C" $ATTRDUP -n "#health-smart" -U "yellow" -d "5s" return 1 fi } init_smart() { #Set temperature defaults if [ -z ${OCF_RESKEY_temp_warning} ]; then yellow_threshold=5 else yellow_threshold=${OCF_RESKEY_temp_warning} fi if [ -z ${OCF_RESKEY_temp_lower_limit} ] ; then lower_red_limit=0 else lower_red_limit=${OCF_RESKEY_temp_lower_limit} fi lower_yellow_limit=$((${lower_red_limit}+${yellow_threshold})) if [ -z ${OCF_RESKEY_temp_upper_limit} ] ; then upper_red_limit=60 else upper_red_limit=${OCF_RESKEY_temp_upper_limit} fi upper_yellow_limit=$((${upper_red_limit}-${yellow_threshold})) #Set disk defaults if [ -z ${OCF_RESKEY_drives} ] ; then DRIVES="/dev/sda" else DRIVES=${OCF_RESKEY_drives} fi #Test for presence of smartctl if [ ! -x $SMARTCTL ] ; then ocf_log err "${SMARTCTL} not installed." exit $OCF_ERR_INSTALLED fi for DRIVE in $DRIVES; do if [ "${OCF_RESKEY_devices}" ]; then for DEVICE in ${OCF_RESKEY_devices}; do $SMARTCTL -d $DEVICE -i ${DRIVE} | grep -q "SMART support is: Enabled" if [ $? -ne "0" ] ; then ocf_log err "S.M.A.R.T. not enabled for drive "${DRIVE} exit $OCF_ERR_INSTALLED fi done else $SMARTCTL -i ${DRIVE} | grep -q "SMART support is: Enabled" if [ $? -ne "0" ] ; then ocf_log err "S.M.A.R.T. not enabled for drive "${DRIVE} exit $OCF_ERR_INSTALLED fi fi done } HealthSMART_usage() { cat < $@ ocf_pacemaker_%.7: %.xml $(XSLTPROC) $(MANPAGE_XSLT) $(top_builddir)/extra/resources/$< endif clean-generic: rm -f $(man7_MANS) $(ocf_SCRIPTS:%=%.xml) *~ pacemaker-master/extra/resources/Stateful000066400000000000000000000123611217637305600211630ustar00rootroot00000000000000#!/bin/sh # # # Example of a stateful OCF Resource Agent. # # Copyright (c) 2006 Andrew Beekhof # # This program is free software; you can redistribute it and/or modify # it under the terms of version 2 of the GNU General Public License as # published by the Free Software Foundation. # # This program is distributed in the hope that it would be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # # Further, this software is distributed without any warranty that it is # free of the rightful claim of any third person regarding infringement # or the like. Any license provided herein, whether implied or # otherwise, applies only to this software file. Patent licenses, if # any, provided herein do not apply to combinations of this program with # other software, or any other product whatsoever. # # You should have received a copy of the GNU General Public License # along with this program; if not, write the Free Software Foundation, # Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. # ####################################################################### # Initialization: : ${OCF_FUNCTIONS=${OCF_ROOT}/resource.d/heartbeat/.ocf-shellfuncs} . ${OCF_FUNCTIONS} : ${__OCF_ACTION=$1} CRM_MASTER="${HA_SBIN_DIR}/crm_master -l reboot" ####################################################################### meta_data() { cat < 1.0 This is an example resource agent that impliments two states Example stateful resource agent Location to store the resource state in State file END exit $OCF_SUCCESS } ####################################################################### stateful_usage() { cat < ${OCF_RESKEY_state} } stateful_check_state() { target=$1 if [ -f ${OCF_RESKEY_state} ]; then state=`cat ${OCF_RESKEY_state}` if [ "x$target" = "x$state" ]; then return 0 fi else if [ "x$target" = "x" ]; then return 0 fi fi return 1 } stateful_start() { stateful_check_state master if [ $? = 0 ]; then # CRM Error - Should never happen return $OCF_RUNNING_MASTER fi stateful_update slave $CRM_MASTER -v ${slave_score} return 0 } stateful_demote() { stateful_check_state if [ $? = 0 ]; then # CRM Error - Should never happen return $OCF_NOT_RUNNING fi stateful_update slave $CRM_MASTER -v ${slave_score} return 0 } stateful_promote() { stateful_check_state if [ $? = 0 ]; then return $OCF_NOT_RUNNING fi stateful_update master $CRM_MASTER -v ${master_score} return 0 } stateful_stop() { $CRM_MASTER -D stateful_check_state master if [ $? = 0 ]; then # CRM Error - Should never happen return $OCF_RUNNING_MASTER fi if [ -f ${OCF_RESKEY_state} ]; then rm ${OCF_RESKEY_state} fi return 0 } stateful_monitor() { stateful_check_state "master" if [ $? = 0 ]; then if [ $OCF_RESKEY_CRM_meta_interval = 0 ]; then # Restore the master setting during probes $CRM_MASTER -v ${master_score} fi return $OCF_RUNNING_MASTER fi stateful_check_state "slave" if [ $? = 0 ]; then if [ $OCF_RESKEY_CRM_meta_interval = 0 ]; then # Restore the master setting during probes $CRM_MASTER -v ${slave_score} fi return $OCF_SUCCESS fi if [ -f ${OCF_RESKEY_state} ]; then echo "File '${OCF_RESKEY_state}' exists but contains unexpected contents" cat ${OCF_RESKEY_state} return $OCF_ERR_GENERIC fi return 7 } stateful_validate() { exit $OCF_SUCCESS } : ${slave_score=5} : ${master_score=10} : ${OCF_RESKEY_CRM_meta_interval=0} : ${OCF_RESKEY_CRM_meta_globally_unique:="true"} if [ "x$OCF_RESKEY_state" = "x" ]; then if [ ${OCF_RESKEY_CRM_meta_globally_unique} = "false" ]; then state="${HA_VARRUN}/Stateful-${OCF_RESOURCE_INSTANCE}.state" # Strip off the trailing clone marker OCF_RESKEY_state=`echo $state | sed s/:[0-9][0-9]*\.state/.state/` else OCF_RESKEY_state="${HA_VARRUN}/Stateful-${OCF_RESOURCE_INSTANCE}.state" fi fi case $__OCF_ACTION in meta-data) meta_data;; start) stateful_start;; promote) stateful_promote;; demote) stateful_demote;; stop) stateful_stop;; monitor) stateful_monitor;; validate-all) stateful_validate;; usage|help) stateful_usage $OCF_SUCCESS;; *) stateful_usage $OCF_ERR_UNIMPLEMENTED;; esac exit $? pacemaker-master/extra/resources/SysInfo000066400000000000000000000235671217637305600210000ustar00rootroot00000000000000#!/bin/sh # # # SysInfo OCF Resource Agent # It records (in the CIB) various attributes of a node # # Copyright (c) 2004 SUSE LINUX AG, Lars Marowsky-Bre # All Rights Reserved. # # This program is free software; you can redistribute it and/or modify # it under the terms of version 2 of the GNU General Public License as # published by the Free Software Foundation. # # This program is distributed in the hope that it would be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # # Further, this software is distributed without any warranty that it is # free of the rightful claim of any third person regarding infringement # or the like. Any license provided herein, whether implied or # otherwise, applies only to this software file. Patent licenses, if # any, provided herein do not apply to combinations of this program with # other software, or any other product whatsoever. # # You should have received a copy of the GNU General Public License # along with this program; if not, write the Free Software Foundation, # Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. # ####################################################################### # Initialization: : ${OCF_FUNCTIONS=${OCF_ROOT}/resource.d/heartbeat/.ocf-shellfuncs} . ${OCF_FUNCTIONS} : ${__OCF_ACTION=$1} ####################################################################### meta_data() { cat < 1.0 This is a SysInfo Resource Agent. It records (in the CIB) various attributes of a node Sample Linux output: arch: i686 os: Linux-2.4.26-gentoo-r14 free_swap: 1999 cpu_info: Intel(R) Celeron(R) CPU 2.40GHz cpu_speed: 4771.02 cpu_cores: 1 cpu_load: 0.00 ram_total: 513 ram_free: 117 root_free: 2.4 Sample Darwin output: arch: i386 os: Darwin-8.6.2 cpu_info: Intel Core Duo cpu_speed: 2.16 cpu_cores: 2 cpu_load: 0.18 ram_total: 2016 ram_free: 787 root_free: 13 Units: free_swap: Mb ram_*: Mb cpu_speed (Linux): bogomips cpu_speed (Darwin): Ghz *_free: GB (or user-defined: disk_unit) SysInfo resource agent PID file PID file Interval to allow values to stabilize Dampening Delay Filesystems or Paths to be queried for free disk space as a SPACE separated list - e.g "/dev/sda1 /tmp". Results will be written to an attribute with leading slashes removed, and other slashes replaced with underscore, and the word 'free' appended - e.g for /dev/sda1 it would be 'dev_sda1_free'. Note: The root filesystem '/' is always queried to an attribute named 'root_free' List of Filesytems/Paths to query for free disk space Unit to report disk free space in. Can be one of: B, K, M, G, T, P (case-insensitive) Unit to report disk free space in The amount of free space required in monitored disks. If any of the monitored disks has less than this amount of free space, all resources will move away from the node. Set the node-health-strategy property appropriately for this to take effect. If the unit is not specified, it defaults to disk_unit. minimum disk free space required END } ####################################################################### UpdateStat() { name=$1; shift value="$*" printf "%s:\t%s\n" "$name" "$value" ${HA_SBIN_DIR}/attrd_updater ${OCF_RESKEY_delay} -S status -n $name -v "$value" } SysInfoStats() { UpdateStat arch "`uname -m`" UpdateStat os "`uname -s`-`uname -r`" case `uname -s` in "Darwin") mem=`top -l 1 | grep Mem: | awk '{print $10}'` mem_used=`top -l 1 | grep Mem: | awk '{print $8}'` mem=`SysInfo_mem_units $mem` mem_used=`SysInfo_mem_units $mem_used` mem_total=`expr $mem_used + $mem` cpu_type=`system_profiler SPHardwareDataType | awk -F': ' '/^CPU Type/ {print $2; exit}'` cpu_speed=`system_profiler SPHardwareDataType | awk -F': ' '/^CPU Speed/ {print $2; exit}'` cpu_cores=`system_profiler SPHardwareDataType | awk -F': ' '/^Number Of/ {print $2; exit}'` ;; "Linux") if [ -f /proc/cpuinfo ]; then cpu_type=`awk -F': ' '/model name/ {print $2; exit}' /proc/cpuinfo` cpu_speed=`awk -F': ' '/bogomips/ {print $2; exit}' /proc/cpuinfo` cpu_cores=`grep "^processor" /proc/cpuinfo | wc -l` fi if [ -f /proc/meminfo ]; then # meminfo results are in kB mem=`grep "SwapFree" /proc/meminfo | awk '{print $2"k"}'` if [ ! -z $mem ]; then UpdateStat free_swap `SysInfo_mem_units $mem` fi mem=`grep "Inactive" /proc/meminfo | awk '{print $2"k"}'` mem_total=`grep "MemTotal" /proc/meminfo | awk '{print $2"k"}'` else mem=`top -n 1 | grep Mem: | awk '{print $7}'` fi ;; *) esac if [ x != x"$cpu_type" ]; then UpdateStat cpu_info "$cpu_type" fi if [ x != x"$cpu_speed" ]; then UpdateStat cpu_speed "$cpu_speed" fi if [ x != x"$cpu_cores" ]; then UpdateStat cpu_cores "$cpu_cores" fi loads=`uptime` load15=`echo ${loads} | awk '{print $10}'` UpdateStat cpu_load $load15 if [ ! -z "$mem" ]; then # Massage the memory values UpdateStat ram_total `SysInfo_mem_units $mem_total` UpdateStat ram_free `SysInfo_mem_units $mem` fi # Portability notes: # o tail: explicit "-n" not available in Solaris; instead simplify # 'tail -n ' to the equivalent 'tail -'. for disk in "/" ${OCF_RESKEY_disks}; do unset disk_free disk_label disk_free=`df -h ${disk} | tail -1 | awk '{print $4}'` if [ x != x"$disk_free" ]; then disk_label=`echo $disk | sed -e 's#^/$#root#;s#^/*##;s#/#_#g'` disk_free=`SysInfo_hdd_units $disk_free` UpdateStat ${disk_label}_free $disk_free if [ -n "$MIN_FREE" ]; then test $disk_free -le $MIN_FREE && UpdateStat "#health_disk" "red" fi fi done } SysInfo_megabytes() { # Size in megabytes echo $1 | awk '{ n = $0; sub(/[0-9]+(.[0-9]+)?/, ""); split(n, a, $0); n=a[1]; if ($0 == "G" || $0 == "") { n *= 1024 }; if (/^kB?/) { n /= 1024 }; printf "%d\n", n }' # Intentionaly round to an integer } SysInfo_mem_units() { mem=$1 if [ -z $1 ]; then return fi mem=$(SysInfo_megabytes "$1") # Round to the next multiple of 50 r=$(($mem % 50)) if [ $r != 0 ]; then mem=$(($mem + 50 - $r)) fi echo $mem } SysInfo_hdd_units() { # Defauts to size in gigabytes case $OCF_RESKEY_disk_unit in [Pp]) echo $(($(SysInfo_megabytes "$1") / 1024 / 1024 / 1024));; [Tt]) echo $(($(SysInfo_megabytes "$1") / 1024 / 1024));; [Gg]) echo $(($(SysInfo_megabytes "$1") / 1024));; [Mm]) echo $(SysInfo_megabytes "$1");; [Kk]) echo $(($(SysInfo_megabytes "$1") * 1024));; [Bb]) echo $(($(SysInfo_megabytes "$1") * 1024 * 1024));; *) ocf_log err "Invalid value for disk_unit: $OCF_RESKEY_disk_unit" echo $(($(SysInfo_megabytes "$1") / 1024));; esac } SysInfo_usage() { cat < $OCF_RESKEY_pidfile SysInfoStats exit $OCF_SUCCESS } SysInfo_stop() { rm $OCF_RESKEY_pidfile exit $OCF_SUCCESS } SysInfo_monitor() { if [ -f $OCF_RESKEY_pidfile ]; then clone=`cat $OCF_RESKEY_pidfile` fi if [ x$clone = x ]; then rm $OCF_RESKEY_pidfile exit $OCF_NOT_RUNNING elif [ $clone = $OCF_RESKEY_clone ]; then SysInfoStats exit $OCF_SUCCESS elif [ x$OCF_RESKEY_CRM_meta_globally_unique = xtrue -o x$OCF_RESKEY_CRM_meta_globally_unique = xTrue -o x$OCF_RESKEY_CRM_meta_globally_unique = xyes -o x$OCF_RESKEY_CRM_meta_globally_unique = xYes ]; then SysInfoStats exit $OCF_SUCCESS fi exit $OCF_NOT_RUNNING } SysInfo_validate() { return $OCF_SUCCESS } if [ $# -ne 1 ]; then SysInfo_usage exit $OCF_ERR_ARGS fi : ${OCF_RESKEY_pidfile:="$HA_VARRUN/SysInfo-${OCF_RESOURCE_INSTANCE}"} : ${OCF_RESKEY_disk_unit:="G"} : ${OCF_RESKEY_clone:="0"} if [ x != x${OCF_RESKEY_delay} ]; then OCF_RESKEY_delay="-d ${OCF_RESKEY_delay}" fi MIN_FREE="" if [ -n "$OCF_RESKEY_min_disk_free" ]; then ocf_is_decimal "$OCF_RESKEY_min_disk_free" && OCF_RESKEY_min_disk_free="$OCF_RESKEY_min_disk_free$OCF_RESKEY_disk_unit" MIN_FREE=`SysInfo_hdd_units $OCF_RESKEY_min_disk_free` fi case $__OCF_ACTION in meta-data) meta_data exit $OCF_SUCCESS ;; start) SysInfo_start ;; stop) SysInfo_stop ;; monitor) SysInfo_monitor ;; validate-all) SysInfo_validate ;; usage|help) SysInfo_usage exit $OCF_SUCCESS ;; *) SysInfo_usage exit $OCF_ERR_UNIMPLEMENTED ;; esac exit $? pacemaker-master/extra/resources/SystemHealth000066400000000000000000000135671217637305600220170ustar00rootroot00000000000000#!/bin/sh # # SystemHealth OCF RA. # # Copyright (c) 2009 International Business Machines (IBM), Mark Hamzy # All Rights Reserved. # # This program is free software; you can redistribute it and/or modify # it under the terms of version 2 of the GNU General Public License as # published by the Free Software Foundation. # # This program is distributed in the hope that it would be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # # Further, this software is distributed without any warranty that it is # free of the rightful claim of any third person regarding infringement # or the like. Any license provided herein, whether implied or # otherwise, applies only to this software file. Patent licenses, if # any, provided herein do not apply to combinations of this program with # other software, or any other product whatsoever. # # You should have received a copy of the GNU General Public License # along with this program; if not, write the Free Software Foundation, # Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. # ####################################################################### # Initialization: : ${OCF_FUNCTIONS=${OCF_ROOT}/resource.d/heartbeat/.ocf-shellfuncs} . ${OCF_FUNCTIONS} : ${__OCF_ACTION=$1} ####################################################################### meta_data() { cat < 0.1 This is a SystemHealth Resource Agent. It is used to monitor the health of a system via IPMI. SystemHealth resource agent END } ####################################################################### SystemHealth_usage() { cat < /dev/null 2>&1 RC=$? if [ $RC != 0 ]; then ocf_log err "servicelog_notify not found!" return $OCF_ERR_INSTALLED fi which ipmiservicelogd > /dev/null 2>&1 RC=$? if [ $RC != 0 ]; then ocf_log err "ipmiservicelogd not found!" return $OCF_ERR_INSTALLED fi test -x $OCF_RESKEY_program RC=$? if [ $RC != 0 ]; then ocf_log err "$OCF_RESKEY_program not found!" return $OCF_ERR_INSTALLED fi } SystemHealth_start() { SystemHealth_monitor RC=$? if [ $RC = $OCF_ERR_GENERIC ]; then return $OCF_ERR_GENERIC elif [ $RC = $OCF_SUCCESS ]; then ocf_log warn "starting an already started SystemHealth" return $OCF_SUCCESS fi service ipmi start > /dev/null 2>&1 RC=$? if [ $RC != 0 ]; then ocf_log err "Could not start service IPMI!" return $OCF_ERR_GENERIC fi ipmiservicelogd smi 0 > /dev/null 2>&1 & RC=$? if [ $RC != 0 ]; then ocf_log err "Could not start ipmiservicelogd!" return $OCF_ERR_GENERIC fi servicelog_notify --add --type=EVENT --command="$OCF_RESKEY_program" --method=num_arg --match='type=4' > /dev/null 2>&1 RC=$? if [ $RC != 0 ]; then ocf_log err "servicelog_notify register handler failed!" return $OCF_ERR_GENERIC fi return $OCF_SUCCESS } SystemHealth_stop() { SystemHealth_monitor RC=$? if [ $RC = $OCF_ERR_GENERIC ]; then return $OCF_ERR_GENERIC elif [ $RC = $OCF_SUCCESS ]; then killall ipmiservicelogd RC1=$? if [ $RC1 != 0 ]; then ocf_log err "Could not stop ipmiservicelogd!" fi servicelog_notify --remove --command="$OCF_RESKEY_program" > /dev/null 2>&1 RC2=$? if [ $RC2 != 0 ]; then ocf_log err "servicelog_notify remove handler failed!" fi if [ $RC1 = 0 -a $RC2 = 0 ]; then return $OCF_SUCCESS else return $OCF_ERR_GENERIC fi elif [ $RC = $OCF_NOT_RUNNING ]; then ocf_log warn "stopping an already stopped SystemHealth" return $OCF_SUCCESS else ocf_log err "SystemHealth_stop: should not be here!" return $OCF_ERR_GENERIC fi } SystemHealth_monitor() { # Monitor _MUST!_ differentiate correctly between running # (SUCCESS), failed (ERROR) or _cleanly_ stopped (NOT RUNNING). # That is THREE states, not just yes/no. if [ ! -f /var/run/ipmiservicelogd.pid0 ]; then ocf_log debug "ipmiservicelogd is not running!" return $OCF_NOT_RUNNING fi ps -p `cat /var/run/ipmiservicelogd.pid0` > /dev/null 2>&1 RC=$? if [ $RC != 0 ]; then ocf_log debug "ipmiservicelogd's pid `cat /var/run/ipmiservicelogd.pid0` is not running!" rm /var/run/ipmiservicelogd.pid0 return $OCF_ERR_GENERIC fi servicelog_notify --list --command="$OCF_RESKEY_program" > /dev/null 2>&1 RC=$? if [ $RC = 0 ]; then return $OCF_SUCCESS else return $OCF_NOT_RUNNING fi } SystemHealth_validate() { SystemHealth_check_tools RC=$? if [ $RC != 0 ]; then return $RC fi return $OCF_SUCCESS } : ${OCF_RESKEY_program=/usr/sbin/notifyServicelogEvent} case $__OCF_ACTION in meta-data) meta_data exit $OCF_SUCCESS ;; usage|help) SystemHealth_usage exit $OCF_SUCCESS ;; esac SystemHealth_check_tools RC=$? if [ $RC != 0 ]; then case $__OCF_ACTION in stop) exit $OCF_SUCCESS;; *) exit $RC;; esac fi case $__OCF_ACTION in start) SystemHealth_start;; stop) SystemHealth_stop;; monitor) SystemHealth_monitor;; reload) ocf_log info "Reloading..." SystemHealth_start ;; validate-all) ;; *) SystemHealth_usage exit $OCF_ERR_UNIMPLEMENTED ;; esac rc=$? ocf_log debug "${OCF_RESOURCE_INSTANCE} $__OCF_ACTION : $rc" exit $rc pacemaker-master/extra/resources/controld000066400000000000000000000144421217637305600212220ustar00rootroot00000000000000#!/bin/sh # # Resource Agent for managing the DLM controld process. # # Copyright (c) 2009 Novell, Inc # All Rights Reserved. # # This program is free software; you can redistribute it and/or modify # it under the terms of version 2 of the GNU General Public License as # published by the Free Software Foundation. # # This program is distributed in the hope that it would be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # # Further, this software is distributed without any warranty that it is # free of the rightful claim of any third person regarding infringement # or the like. Any license provided herein, whether implied or # otherwise, applies only to this software file. Patent licenses, if # any, provided herein do not apply to combinations of this program with # other software, or any other product whatsoever. # # You should have received a copy of the GNU General Public License # along with this program; if not, write the Free Software Foundation, # Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. # ####################################################################### # Initialization: : ${OCF_FUNCTIONS=${OCF_ROOT}/resource.d/heartbeat/.ocf-shellfuncs} . ${OCF_FUNCTIONS} : ${__OCF_ACTION=$1} ####################################################################### meta_data() { cat < 1.0 This Resource Agent can control the dlm_controld services needed by ocfs2. It assumes that dlm_controld is in your default PATH. In most cases, it should be run as an anonymous clone. DLM Agent for OCFS2 Any additional options to start the dlm_controld service with DLM Options The location where configfs is or should be mounted Location of configfs The daemon to start - supports gfs_controld(.pcmk) and dlm_controld(.pcmk) The daemon to start END } ####################################################################### controld_usage() { cat < /dev/null if [ $? != 0 ]; then mount -t configfs none $OCF_RESKEY_configdir fi if [ ! -e $OCF_RESKEY_configdir/dlm ]; then modprobe dlm if [ ! -e $OCF_RESKEY_configdir/dlm ]; then ocf_log err "$OCF_RESKEY_configdir/dlm not available" return $OCF_NOT_INSTALLED fi fi ${OCF_RESKEY_daemon} $OCF_RESKEY_args while true do sleep 1 controld_monitor; rc=$? case $rc in $OCF_SUCCESS) check_dir=/sys/kernel/config/dlm/cluster/comms if grep 1 $check_dir/*/local >/dev/null 2>&1; then return $OCF_SUCCESS fi ;; $OCF_NOT_RUNNING) return $OCF_NOT_RUNNING ;; *) return $OCF_ERR_GENERIC ;; esac ocf_log debug "Waiting for ${OCF_RESKEY_daemon} to be ready" done } controld_stop() { controld_monitor; rc=$? if [ $rc = $OCF_NOT_RUNNING ]; then return $OCF_SUCCESS fi killall -TERM ${OCF_RESKEY_daemon}; rc=$? if [ $rc != 0 ]; then return $OCF_ERR_GENERIC fi rc=$OCF_SUCCESS while [ $rc = $OCF_SUCCESS ]; do controld_monitor; rc=$? sleep 1 done if [ $rc = $OCF_NOT_RUNNING ]; then rc=$OCF_SUCCESS fi return $rc } controld_monitor() { killall -0 ${OCF_RESKEY_daemon} >/dev/null 2>&1 ; rc=$? case $rc in 0) return $OCF_SUCCESS;; 1) return $OCF_NOT_RUNNING;; *) return $OCF_ERR_GENERIC;; esac } controld_validate() { check_binary ${OCF_RESKEY_daemon} case ${OCF_RESKEY_CRM_meta_globally_unique} in yes|Yes|true|True|1) ocf_log err "$OCF_RESOURCE_INSTANCE must be configured with the globally_unique=false meta attribute" exit $OCF_ERR_CONFIGURED ;; esac [ -d /var/run/cluster ] || mkdir /var/run/cluster return $OCF_SUCCESS } : ${OCF_RESKEY_sctp=false} : ${OCF_RESKEY_configdir=/sys/kernel/config} : ${OCF_RESKEY_CRM_meta_globally_unique:="false"} case "$HA_quorum_type" in cman|corosync) daemon_ext="";; *) daemon_ext=".pcmk";; esac case "$OCF_RESOURCE_INSTANCE" in *[gG][fF][sS]*) : ${OCF_RESKEY_args=-g 0} : ${OCF_RESKEY_daemon=gfs_controld${daemon_ext}} ;; *[dD][lL][mM]*) : ${OCF_RESKEY_args=-q 0} : ${OCF_RESKEY_daemon=dlm_controld${daemon_ext}} ;; *) : ${OCF_RESKEY_args=-q 0} : ${OCF_RESKEY_daemon=dlm_controld${daemon_ext}} esac case $__OCF_ACTION in meta-data) meta_data exit $OCF_SUCCESS ;; start) controld_validate; controld_start;; stop) controld_stop;; monitor) controld_validate; controld_monitor;; validate-all) controld_validate;; usage|help) controld_usage exit $OCF_SUCCESS ;; *) controld_usage exit $OCF_ERR_UNIMPLEMENTED ;; esac rc=$? exit $rc pacemaker-master/extra/resources/ifspeed000066400000000000000000000303761217637305600210210ustar00rootroot00000000000000#!/bin/bash # # OCF resource agent which monitors state of network interface and records it # as a value in CIB based on summ of speeds of its active (up, link detected, # not blocked) underlying interfaces. # # Copyright (c) 2011 Vladislav Bogdanov # Partially based on 'ping' RA by Andrew Beekhof # # OCF instance parameters: # OCF_RESKEY_name: name of attribute to set in CIB # OCF_RESKEY_iface: network interface to monitor # OCF_RESKEY_bridge_ports: if not null and OCF_RESKEY_iface is a bridge, list of # bridge ports to consider. # Default is all ports which have designated_bridge=root_id # OCF_RESKEY_weight_base: Relative weight of 1Gbps. This can be used to tune # value of resulting CIB attribute. # # Initialization: : ${OCF_FUNCTIONS=${OCF_ROOT}/resource.d/heartbeat/.ocf-shellfuncs} . ${OCF_FUNCTIONS} : ${__OCF_ACTION=$1} # Defaults OCF_RESKEY_name_default="ifspeed" OCF_RESKEY_bridge_ports_default="detect" OCF_RESKEY_weight_base_default=1000 OCF_RESKEY_dampen_default=5 : ${OCF_RESKEY_name=${OCF_RESKEY_name_default}} : ${OCF_RESKEY_bridge_ports=${OCF_RESKEY_bridge_ports_default}} : ${OCF_RESKEY_weight_base=${OCF_RESKEY_weight_base_default}} : ${OCF_RESKEY_dampen=${OCF_RESKEY_dampen_default}} meta_data() { cat < 1.0 Every time the monitor action is run, this resource agent records (in the CIB) (relative) speed of network interface it monitors. This RA can monitor physical interfaces, bonds, bridges, vlans and (hopefully) any combination of them. Examples: *) Bridge on top of one 10Gbps interface (eth2) and 802.3ad bonding (bond0) built on two 1Gbps interfaces (eth0 and eth1). *) Active-backup bonding built on top of one physical interface and one vlan on another interface. For STP-enabled bridges this RA tries to some-how guess network topology and by default looks only on ports which are connected to upstream switch. This can be overriden by 'bridge_ports' parameter. Active interfaces in this case are those in "forwarding" state. For balancing bonds this RA summs speeds of underlying "up" slave interfaces (and applies coefficient 0.8 to result). For non-balancing bonds ('active-backup' and probably 'brodcast') only speed of now active slave is used. Network interface speed monitor The name of the attribute to set. This is the name to be used in the constraints. Attribute name Network interface to monitor. Network interface If not null and OCF_RESKEY_iface is a bridge, list of bridge ports to consider. Default is all ports which have designated_bridge=root_id. Bridge ports Relative weight of 1Gbps in interface speed. Can be used to tune how big attribute value will be. Weight of 1Gbps The time to wait (dampening) for further changes to occur. Dampening interval Log what have been done more verbosely. Verbose logging END } usage() { cat </dev/null)" if [ -z "$SP_OUT" ] then modprobe -s ocfs2_stack_user if [ $? != 0 ]; then ocf_log err "Could not load ocfs2_stack_user" return $OCF_ERR_INSTALLED fi fi SP_OUT="$(awk '/^'user'$/{print; exit}' "$LOADED_PLUGINS_FILE" 2>/dev/null)" if [ -z "$SP_OUT" ]; then ocf_log err "Switch to userspace stack unsuccessful" return $OCF_ERR_INSTALLED fi if [ -f "$CLUSTER_STACK_FILE" ]; then echo "$OCF_RESKEY_stack" >"$CLUSTER_STACK_FILE" if [ $? != 0 ]; then ocf_log err "Userspace stack '$OCF_RESKEY_stack' not supported" return $OCF_ERR_INSTALLED fi else ocf_log err "Switch to userspace stack not supported" return $OCF_ERR_INSTALLED fi driver_filesystem ocfs2; rc=$? if [ $rc != 0 ]; then modprobe -s ocfs2 if [ "$?" != 0 ]; then ocf_log err "Unable to load ocfs2 module" return $OCF_ERR_INSTALLED fi fi bringup_daemon return $? } o2cb_stop() { o2cb_monitor; rc=$? case $rc in $OCF_NOT_RUNNING) return $OCF_SUCCESS;; esac ocf_log info "Stopping $OCF_RESOURCE_INSTANCE" kill_daemon if [ $? != 0 ]; then ocf_log err "Unable to unload modules: the cluster is still online" return $OCF_ERR_GENERIC fi unload_filesystem ocfs2 if [ $? = 1 ]; then ocf_log err "Unable to unload ocfs2 module" return $OCF_ERR_GENERIC fi # If we can't find the stack glue, we have nothing to do. [ ! -e "$LOADED_PLUGINS_FILE" ] && return $OCF_SUCCESS while read plugin do unload_module "ocfs2_stack_${plugin}" if [ $? = 1 ]; then ocf_log err "Unable to unload ocfs2_stack_${plugin}" return $OCF_ERR_GENERIC fi done <"$LOADED_PLUGINS_FILE" unload_module "ocfs2_stackglue" if [ $? = 1 ]; then ocf_log err "Unable to unload ocfs2_stackglue" return $OCF_ERR_GENERIC fi # Dont unmount configfs - its always in use by libdlm } o2cb_monitor() { o2cb_validate # Assume that ocfs2_controld will terminate if any of the conditions below are met driver_filesystem configfs; rc=$? if [ $rc != 0 ]; then ocf_log info "configfs not loaded" return $OCF_NOT_RUNNING fi check_filesystem configfs "${OCF_RESKEY_configfs}"; rc=$? if [ $rc != 0 ]; then ocf_log info "configfs not mounted" return $OCF_NOT_RUNNING fi if [ ! -e "$LOADED_PLUGINS_FILE" ]; then ocf_log info "Stack glue driver not loaded" return $OCF_NOT_RUNNING fi grep user "$LOADED_PLUGINS_FILE" >/dev/null 2>&1; rc=$? if [ $rc != 0 ]; then ocf_log err "Wrong stack `cat $LOADED_PLUGINS_FILE`" return $OCF_ERR_INSTALLED fi driver_filesystem ocfs2; rc=$? if [ $rc != 0 ]; then ocf_log info "ocfs2 not loaded" return $OCF_NOT_RUNNING fi status_daemon return $? } o2cb_usage() { echo "usage: $0 {start|stop|monitor|validate-all|meta-data}" echo " Expects to have a fully populated OCF RA-compliant environment set." echo " In particualr, a value for OCF_ROOT" } o2cb_validate() { check_binary ${DAEMON} case ${OCF_RESKEY_CRM_meta_globally_unique} in yes|Yes|true|True|1) ocf_log err "$OCF_RESOURCE_INSTANCE must be configured with the globally_unique=false meta attribute" exit $OCF_ERR_CONFIGURED ;; esac return $OCF_SUCCESS } meta_data() { cat < 1.0 OCFS2 daemon resource agent This Resource Agent controls the userspace daemon needed by OCFS2. Location where sysfs is mounted Sysfs location Location where configfs is mounted Configfs location Which userspace stack to use. Known values: pcmk, cman Userspace stack Number of seconds to allow the control daemon to come up Daemon Timeout END } case $__OCF_ACTION in meta-data) meta_data exit $OCF_SUCCESS ;; start) o2cb_start ;; stop) o2cb_stop ;; monitor) o2cb_monitor ;; validate-all) o2cb_validate ;; usage|help) o2cb_usage exit $OCF_SUCCESS ;; *) o2cb_usage exit $OCF_ERR_UNIMPLEMENTED ;; esac exit $? pacemaker-master/extra/resources/ping000077500000000000000000000241121217637305600203310ustar00rootroot00000000000000#!/bin/sh # # # Ping OCF RA that utilizes the system ping # # Copyright (c) 2009 Andrew Beekhof # All Rights Reserved. # # This program is free software; you can redistribute it and/or modify # it under the terms of version 2 of the GNU General Public License as # published by the Free Software Foundation. # # This program is distributed in the hope that it would be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # # Further, this software is distributed without any warranty that it is # free of the rightful claim of any third person regarding infringement # or the like. Any license provided herein, whether implied or # otherwise, applies only to this software file. Patent licenses, if # any, provided herein do not apply to combinations of this program with # other software, or any other product whatsoever. # # You should have received a copy of the GNU General Public License # along with this program; if not, write the Free Software Foundation, # Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. # ####################################################################### # Initialization: : ${OCF_FUNCTIONS=${OCF_ROOT}/resource.d/heartbeat/.ocf-shellfuncs} . ${OCF_FUNCTIONS} : ${__OCF_ACTION=$1} ####################################################################### meta_data() { cat < 1.0 Every time the monitor action is run, this resource agent records (in the CIB) the current number of ping nodes the host can connect to. It is essentially the same as pingd except that it uses the system ping tool to obtain the results. node connectivity PID file PID file The time to wait (dampening) further changes occur Dampening interval The name of the attributes to set. This is the name to be used in the constraints. Attribute name The number by which to multiply the number of connected ping nodes by Value multiplier The list of ping nodes to count. Host list Number of ping attempts, per host, before declaring it dead no. of ping attempts How long, in seconds, to wait before declaring a ping lost ping timeout in seconds A catch all for any other options that need to be passed to ping. Extra Options Resource is failed if the score is less than failure_score. Default never fails. failure_score Enables to use default attrd_updater verbose logging on every call. Verbose logging END } ####################################################################### ping_conditional_log() { level=$1; shift if [ ${OCF_RESKEY_debug} = "true" ]; then ocf_log $level "$*" fi } ping_usage() { cat <$f_out 2>$f_err; rc=$? active=`grep alive $f_out|wc -l` case $rc in 0) ;; 1) for h in `grep unreachable $f_out | awk '{print $1}'`; do ping_conditional_log warn "$h is inactive" done ;; *) ocf_log err "Unexpected result for '$cmd' $rc: `tr '\n' ';' < $f_err`" ;; esac rm -f $f_out $f_err return $active } ping_check() { active=0 for host in $OCF_RESKEY_host_list; do p_exe=ping case `uname` in Linux) p_args="-n -q -W $OCF_RESKEY_timeout -c $OCF_RESKEY_attempts";; Darwin) p_args="-n -q -t $OCF_RESKEY_timeout -c $OCF_RESKEY_attempts -o";; *) ocf_log err "Unknown host type: `uname`"; exit $OCF_ERR_INSTALLED;; esac case $host in *:*) p_exe=ping6 esac p_out=`$p_exe $p_args $OCF_RESKEY_options $host 2>&1`; rc=$? case $rc in 0) active=`expr $active + 1`;; 1) ping_conditional_log warn "$host is inactive: $p_out";; *) ocf_log err "Unexpected result for '$p_exe $p_args $OCF_RESKEY_options $host' $rc: $p_out";; esac done return $active } ping_update() { if have_binary fping; then fping_check active=$? else ping_check active=$? fi score=`expr $active \* $OCF_RESKEY_multiplier` attrd_updater -n $OCF_RESKEY_name -v $score -d $OCF_RESKEY_dampen $attrd_options rc=$? case $rc in 0) ping_conditional_log debug "Updated $OCF_RESKEY_name = $score" ;; *) ocf_log warn "Could not update $OCF_RESKEY_name = $score: rc=$rc";; esac if [ $rc -ne 0 ]; then return $rc fi if [ -n "$OCF_RESKEY_failure_score" -a "$score" -lt "$OCF_RESKEY_failure_score" ]; then ocf_log warn "$OCF_RESKEY_name is less than failure_score($OCF_RESKEY_failure_score)" return 1 fi return 0 } : ${OCF_RESKEY_name:="pingd"} : ${OCF_RESKEY_dampen:="5s"} : ${OCF_RESKEY_attempts:="3"} : ${OCF_RESKEY_multiplier:="1"} : ${OCF_RESKEY_debug:="false"} : ${OCF_RESKEY_failure_score:="0"} : ${OCF_RESKEY_CRM_meta_timeout:="20000"} : ${OCF_RESKEY_CRM_meta_globally_unique:="true"} integer=`echo ${OCF_RESKEY_timeout} | egrep -o '[0-9]*'` case ${OCF_RESKEY_timeout} in *[0-9]ms|*[0-9]msec) OCF_RESKEY_timeout=`expr $integer / 1000`;; *[0-9]m|*[0-9]min) OCF_RESKEY_timeout=`expr $integer \* 60`;; *[0-9]h|*[0-9]hr) OCF_RESKEY_timeout=`expr $integer \* 60 \* 60`;; *) OCF_RESKEY_timeout=$integer;; esac if [ -z ${OCF_RESKEY_timeout} ]; then if [ x"$OCF_RESKEY_host_list" != x ]; then host_count=`echo $OCF_RESKEY_host_list | awk '{print NF}'` OCF_RESKEY_timeout=`expr $OCF_RESKEY_CRM_meta_timeout / $host_count / $OCF_RESKEY_attempts` OCF_RESKEY_timeout=`expr $OCF_RESKEY_timeout / 1100` # Convert to seconds and finish 10% early else OCF_RESKEY_timeout=5 fi fi if [ ${OCF_RESKEY_timeout} -lt 1 ]; then OCF_RESKEY_timeout=5 elif [ ${OCF_RESKEY_timeout} -gt 1000 ]; then # ping actually complains if this value is too high, 5 minutes is plenty OCF_RESKEY_timeout=300 fi if [ ${OCF_RESKEY_CRM_meta_globally_unique} = "false" ]; then : ${OCF_RESKEY_pidfile:="$HA_VARRUN/ping-${OCF_RESKEY_name}"} else : ${OCF_RESKEY_pidfile:="$HA_VARRUN/ping-${OCF_RESOURCE_INSTANCE}"} fi attrd_options='-q' if ocf_is_true ${OCF_RESKEY_debug} ; then attrd_options='' fi # Check the debug option case "${OCF_RESKEY_debug}" in true|True|TRUE|1) OCF_RESKEY_debug=true;; false|False|FALSE|0) OCF_RESKEY_debug=false;; *) ocf_log warn "Value for 'debug' is incorrect. Please specify 'true' or 'false' not: ${OCF_RESKEY_debug}" OCF_RESKEY_debug=false ;; esac case $__OCF_ACTION in meta-data) meta_data exit $OCF_SUCCESS ;; start) ping_start;; stop) ping_stop;; monitor) ping_monitor;; reload) ping_start;; validate-all) ping_validate;; usage|help) ping_usage exit $OCF_SUCCESS ;; *) ping_usage exit $OCF_ERR_UNIMPLEMENTED ;; esac exit $? pacemaker-master/extra/resources/pingd000066400000000000000000000156251217637305600205030ustar00rootroot00000000000000#!/bin/sh # # # pingd OCF Resource Agent # Records (in the CIB) the current number of ping nodes a # cluster node can connect to. # # Copyright (c) 2006 Andrew Beekhof # All Rights Reserved. # # This program is free software; you can redistribute it and/or modify # it under the terms of version 2 of the GNU General Public License as # published by the Free Software Foundation. # # This program is distributed in the hope that it would be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # # Further, this software is distributed without any warranty that it is # free of the rightful claim of any third person regarding infringement # or the like. Any license provided herein, whether implied or # otherwise, applies only to this software file. Patent licenses, if # any, provided herein do not apply to combinations of this program with # other software, or any other product whatsoever. # # You should have received a copy of the GNU General Public License # along with this program; if not, write the Free Software Foundation, # Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. # ####################################################################### # Initialization: : ${OCF_FUNCTIONS=${OCF_ROOT}/resource.d/heartbeat/.ocf-shellfuncs} . ${OCF_FUNCTIONS} : ${__OCF_ACTION=$1} : ${OCF_RESKEY_name:="pingd"} : ${OCF_RESKEY_interval:="1"} : ${OCF_RESKEY_CRM_meta_interval:=0} upgrade1="This agent (ocf:pacemaker:pingd) has been replaced by the more reliable ocf:pacemaker:ping." upgrade2="Attempting automated conversion, run 'crm ra info ocf:pacemaker:ping' for all configuration options" upgrade3="You will need to remove the existing resource and replace it with one that uses 'ocf:pacemaker:ping' directly" case $__OCF_ACTION in start|monitor) if [ "x" != "x$OCF_RESKEY_host_list" ]; then ocf_log err "$upgrade1" ocf_log err "$upgrade2" ocf_log err "Automatic conversion to ocf:pacemaker:ping failed: no hosts were configured to check for connectivity" ocf_log err "$upgrade3" exit $OCF_ERR_ARGS fi recurring=`crm configure show $OCF_RESOURCE_INSTANCE | grep "op monitor.*interval=\"[1-9]" | sed s/.*interval=// | awk -F\" '{print $2}' | sed s/.*interval=// | awk -F\" '{print $2}' | sort | head -n 1` if [ -z $recurring ]; then ocf_log err "$upgrade1" ocf_log err "$upgrade2" ocf_log err "Automatic conversion to ocf:pacemaker:ping failed: no monitor operation configured" ocf_log err "Without an explicit monitor operation for '$OCF_RESOURCE_INSTANCE', connectivity changes will not be noticed" ocf_log err "Preventing startup to ensure the issue is addressed before it matters" exit $OCF_ERR_ARGS fi if [ $OCF_RESKEY_CRM_meta_interval = 0 ]; then ocf_log warn "$upgrade1" ocf_log warn "$upgrade2" if [ $recurring != $OCF_RESKEY_interval ]; then ocf_log warn "Your monitor operation happens every $recurring, which means that the $OCF_RESKEY_name attribute will be updated with a different frequency than the previously configured ( $OCF_RESKEY_interval )" ocf_log warn "Either change the monitor interval to match or, ideally, switch to the ocf:pacemaker:ping agent and avoid all this compatibility nonsense." fi fi ;; meta-data) cat < 1.0 This agent (ocf:pacemaker:pingd) has been replaced by the more reliable ocf:pacemaker:ping. It records (in the CIB) the current number of ping nodes (specified in the 'host_list' parameter) a cluster node can connect to. pingd resource agent PID file PID file The user we want to run pingd as The user we want to run pingd as The time to wait (dampening) further changes occur Dampening interval The name of the instance_attributes set to place the value in. Rarely needs to be specified. Set name The name of the attributes to set. This is the name to be used in the constraints. Attribute name The section place the value in. Rarely needs to be specified. Section name The number by which to multiply the number of connected ping nodes by Value multiplier The list of ping nodes to count. Defaults to all configured ping nodes. Rarely needs to be specified. Host list How often, in seconds, to check for node liveliness ping interval in seconds Number of ping attempts, per host, before declaring it dead no. of ping attempts How long, in seconds, to wait before declaring a ping lost ping timeout in seconds A catch all for any other options that need to be passed to pingd. Extra Options END exit $OCF_SUCCESS ;; esac ${OCF_ROOT}/resource.d/pacemaker/ping $1 exit $? pacemaker-master/extra/resources/remote000066400000000000000000000065561217637305600207000ustar00rootroot00000000000000#!/bin/sh # # # remote OCF RA. This script provides metadata for the internal # pacemaker remote lrmd connection agent. Outside of acting # as a place holder so the remote ra script can be indexed and # providing metadata, this script should never be invoked. The # actual functionality behind the remote lrmd connection lives # within pacemaker's crmd component. # # Copyright (c) 2013 David Vossel # # This program is free software; you can redistribute it and/or modify # it under the terms of version 2 of the GNU General Public License as # published by the Free Software Foundation. # # This program is distributed in the hope that it would be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # # Further, this software is distributed without any warranty that it is # free of the rightful claim of any third person regarding infringement # or the like. Any license provided herein, whether implied or # otherwise, applies only to this software file. Patent licenses, if # any, provided herein do not apply to combinations of this program with # other software, or any other product whatsoever. # # You should have received a copy of the GNU General Public License # along with this program; if not, write the Free Software Foundation, # Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. # ####################################################################### # Initialization: : ${OCF_FUNCTIONS=${OCF_ROOT}/resource.d/heartbeat/.ocf-shellfuncs} . ${OCF_FUNCTIONS} : ${__OCF_ACTION=$1} ####################################################################### meta_data() { cat < 0.1 Server location to connect to. This can be an ip address or hostname. Server location tcp port to connect to. tcp port END } ####################################################################### remote_usage() { cat < $@ echo >> $@ echo XSL_FILE=\"$(pkgdatadir)/cluconf2cib.xsl\" >> $@ echo SAXON_JAR=\"$(datadir)/java/saxon.jar\" >> $@ echo >> $@ cat $^ >> $@ chmod +x $@ endif pacemaker-master/extra/rgmanager/README000066400000000000000000000004421217637305600202570ustar00rootroot00000000000000Linux-cluster cluster.conf to Pacemaker CIB translation utility. Development is on Fedora 14+ 2 phases: Step 1: Flatten tree Step 2: Convert Requires: resource-agents libxml2 java saxon >= 9.1 java-1.6.0-openjdk TODO: * Fencing * Resource-defaults [ skipping ] ... * Profit pacemaker-master/extra/rgmanager/ccs2cib.in000066400000000000000000000067061217637305600212500ustar00rootroot00000000000000# Above is autogenerated; DEBUG here is run-time DEBUG=0 export XSL_FILE SAXON_JAR DEBUG die() { echo "$*" exit 1 } _validate() { if [ $DEBUG -eq 1 ]; then echo "debug: adding . to $PATH" export PATH="$PATH:." fi which ccs_flatten &> /dev/null || die "Can't find ccs_flatten in path!" which java &> /dev/null || die "Can not find java in path!" if [ -z "$XSL_FILE" ]; then if [ $DEBUG -eq 1 ]; then XSL_FILE=./cluconf2cib.xsl echo "debug: using $XSL_FILE" else die "Please specify path to XSLT script using -X ." fi fi if [ -z "$SAXON_JAR" ]; then if [ $DEBUG -eq 1 ]; then SAXON_JAR=/usr/share/java/saxon.jar echo "debug: using $SAXON_JAR" else die "Please specify path to saxon.jar using -J ." fi fi [ -d /usr/share/cluster ] || die "/usr/share/cluster does not exist." [ -f /usr/share/cluster/service.sh ] || die "Missing rgmanager resource agents?" [ -f "$XSL_FILE" ] || die "$XSL_FILE does not exist!" [ -f "$SAXON_JAR" ] || die "$SAXON_JAR does not exist!" [ -f "$1" ] || die "Input file $1 not found" if [ -f "$2" ]; then [ $3 -ne 0 ] || die "Output file $2 exists; please remove or use -f" fi return 0 } help() { cat < Specify path to XSLT script -J Specify path to Saxon jar file -h This message EOT } # main declare conf_in cib_out xsl_file saxon_jar conf_out opt do_update tmp declare force_update no_verify # defaults conf_in="/etc/cluster/cluster.conf" cib_out="cib-converted.xml" conf_out="" do_update=0 no_verify=0 force_update=0 tmp=$(mktemp /tmp/ccs2cib.tmp.XXXXXX) while getopts i:o:X:J:Rr:dnhf opt; do case $opt in d) DEBUG=1 ;; i) conf_in="$OPTARG" ;; o) cib_out="$OPTARG" ;; R) do_update=1 ;; r) do_update=1 conf_out="$OPTARG" ;; n) no_verify=1 ;; f) force_update=1 ;; X) XSL_FILE="$OPTARG" ;; J) SAXON_JAR="$OPTARG" ;; h) help $0 exit 0 ;; *) echo "Error parsing $opt" help $0 exit 1 ;; esac done [ -z "$conf_out" ] && conf_out="$conf_in" _validate "$conf_in" "$cib_out" $force_update echo " * Converting configuration" if ! ccs_flatten "$conf_in" > $tmp; then rm -f $tmp die "Flattening of configuration file failed." fi if ! java -jar $SAXON_JAR -xsl:$XSL_FILE $tmp > $cib_out; then rm -f $tmp die "Conversion failed." fi echo " * Calling crm_verify to validate the configuration." if [ $no_verify -eq 0 ]; then crm_verify --xml-file $cib_out -V || die "Validation failed." fi if [ $do_update -ne 0 ]; then echo " * Disabling rgmanager in $conf_out" rm -f $tmp disable_rgmanager "$conf_in" > "$tmp" || die "Failed to disable rgmanager" mv "$tmp" "$conf_out" if [ "$conf_out" = "/etc/cluster/cluster.conf" ]; then if clustat -Q &> /dev/null; then echo " * Calling cman_tool to update cluster.conf" cman_tool version -r else echo " * You will need to manually copy $conf_out to the other cluster" echo " nodes using scp, ccs_sync, or some other utility." fi fi fi echo " * Proposed cib stored in $cib_out" exit 0 pacemaker-master/extra/rgmanager/cluconf2cib.xsl000066400000000000000000000171561217637305600223320ustar00rootroot00000000000000 500000 1000000 INFINITY -INFINITY pacemaker-master/extra/rgmanager/disable_rgmanager.c000066400000000000000000000055021217637305600231730ustar00rootroot00000000000000/* Copyright Red Hat, Inc. 2004-2006 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 2, 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; see the file COPYING. If not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include #include #include #include #include #include #define shift() {++argv; --argc;} static int disable_rgmanager(xmlDocPtr doc) { char buf[32]; xmlNodePtr n, o; char *a; int x; if (!doc) return 0; n = xmlDocGetRootElement(doc); if (!n) return 0; if (strcmp((char *)n->name, "cluster")) { fprintf(stderr, "Expected cluster tag, got %s\n", (char *)n->name); return 0; } a = (char *)xmlGetProp(n, (xmlChar *) "config_version"); if (!a) { fprintf(stderr, "No config_version found on cluster tag\n"); return 0; } x = atoi(a); if (x == 0) { fprintf(stderr, "config_version was invalid\n"); return 0; } ++x; snprintf(buf, sizeof(buf), "%d", x); if (xmlSetProp(n, (xmlChar *) "config_version", (xmlChar *) buf) == NULL) { fprintf(stderr, "Failed to update config_version\n"); return 0; } for (o = n->xmlChildrenNode; o; o = o->next) { if (o->type != XML_ELEMENT_NODE) continue; if (!strcmp((char *)o->name, "rm")) break; } if (!o) return 0; if (xmlSetProp(o, (xmlChar *) "disabled", (xmlChar *) "1") == NULL) { fprintf(stderr, "Failed to disable rgmanager\n"); return 0; } return 1; } static void usage(const char *arg0, int ret) { fprintf(stderr, "usage: %s [output.conf]\n", arg0); exit(ret); } int main(int argc, char **argv) { char *arg0 = basename(argv[0]); int ret = 0; xmlDocPtr doc = NULL; if (argc < 2) { usage(arg0, 1); } if (!strcasecmp(argv[1], "-h") || !strcasecmp(argv[1], "-?")) { usage(arg0, 0); } xmlInitParser(); xmlIndentTreeOutput = 1; xmlKeepBlanksDefault(0); shift(); doc = xmlParseFile(argv[0]); if (disable_rgmanager(doc)) { xmlDocFormatDump(stdout, doc, 1); } if (doc) xmlFreeDoc(doc); xmlCleanupParser(); return ret; } pacemaker-master/extra/rgmanager/flatten.c000066400000000000000000000125071217637305600212050ustar00rootroot00000000000000/* Copyright Red Hat, Inc. 2004-2006 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 2, 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; see the file COPYING. If not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include #include #include #include #include #include #include #include #include #include #include #define shift() {++argv; --argc;} const char *agentpath = RESOURCE_ROOTDIR; static xmlNode * get_rm_node(xmlDocPtr doc) { xmlNodePtr n, o; if (!doc) return NULL; n = xmlDocGetRootElement(doc); if (!n) return NULL; if (strcmp((char *)n->name, "cluster")) { fprintf(stderr, "Expected cluster tag, got %s\n", (char *)n->name); return NULL; } for (o = n->xmlChildrenNode; o; o = o->next) { if (o->type != XML_ELEMENT_NODE) continue; if (!strcmp((char *)o->name, "rm")) return o; } return NULL; } static void remove_resources_block(xmlNodePtr rm) { xmlNodePtr o, r = NULL; for (o = rm->xmlChildrenNode; o; o = o->next) { if (o->type != XML_ELEMENT_NODE) continue; if (!strcmp((char *)o->name, "resources")) { r = o; break; } } if (!r) return; xmlUnlinkNode(r); xmlFreeNode(r); } static int replace_resource(xmlNodePtr rm, char *restype, char *primattr, char *ident, xmlNodePtr n) { xmlNodePtr o, r = NULL; char *p; for (o = rm->xmlChildrenNode; o; o = o->next) { if (o->type != XML_ELEMENT_NODE) continue; if (!strcmp((char *)o->name, restype)) { p = (char *)xmlGetProp(o, (xmlChar *) primattr); if (!strcmp(p, ident)) { r = o; break; } } } if (!r) return -1; xmlUnlinkNode(r); xmlFreeNode(r); xmlAddChild(rm, n); return 0; } static int flatten(int argc, char **argv, xmlDocPtr * doc) { xmlDocPtr d = NULL; xmlNode *n = NULL, *rm = NULL, *new_rb = NULL; resource_rule_t *rulelist = NULL; resource_t *reslist = NULL, *curres; resource_node_t *tree = NULL, *rn; FILE *f = stdout; int ret = 0; conf_setconfig(argv[0]); if (conf_open() < 0) { xmlFree(new_rb); goto out; } while (argc >= 2) { shift(); if (!strcmp(argv[0], "-r")) { if (!new_rb) new_rb = xmlNewNode(NULL, (xmlChar *) "rm"); } else { if (f == stdout) f = fopen(argv[0], "w+"); } } d = conf_get_doc(); rm = get_rm_node(d); load_resource_rules(agentpath, &rulelist); if (!rulelist) { fprintf(stderr, "No resource rules available\n"); goto out; } load_resources(&reslist, &rulelist); build_resource_tree(&tree, &rulelist, &reslist); if (!tree) { fprintf(stderr, "No resource trees defined; nothing to do\n"); goto out; } #ifdef DEBUG fprintf(stderr, "Resources %p tree %p\n", reslist, tree); #endif shift(); list_do(&tree, rn) { n = NULL; curres = rn->rn_resource; #ifdef DEBUG fprintf(stderr, "Flatten %s:%s ... \n", curres->r_rule->rr_type, curres->r_attrs[0].ra_value); #endif if (res_flatten(&n, new_rb, &tree, curres)) { fprintf(stderr, "FAIL 1\n"); ret = -1; goto out; } if (replace_resource(rm, curres->r_rule->rr_type, curres->r_attrs[0].ra_name, curres->r_attrs[0].ra_value, n) != 0) { fprintf(stderr, "FAIL 2\n"); ret = -1; goto out; } } while (!list_done(&tree, rn)) ; remove_resources_block(rm); if (new_rb) { xmlAddChild(rm, new_rb); } xmlDocFormatDump(f, d, 1); if (f != stdout) fclose(f); out: if (ret < 0) { xmlFreeDoc(d); } else { *doc = d; } conf_close(); destroy_resource_tree(&tree); destroy_resources(&reslist); destroy_resource_rules(&rulelist); return ret; } static void usage(const char *arg0, int ret) { fprintf(stderr, "usage: %s [output.conf] [-r]\n", arg0); exit(ret); } int main(int argc, char **argv) { char *arg0 = basename(argv[0]); int ret = 0; xmlDocPtr doc = NULL; if (argc < 2) { usage(arg0, 1); } if (!strcasecmp(argv[1], "-h") || !strcasecmp(argv[1], "-?")) { usage(arg0, 0); } xmlInitParser(); xmlIndentTreeOutput = 1; xmlKeepBlanksDefault(0); shift(); ret = flatten(argc, argv, &doc); //if (doc) //xmlFreeDoc(doc); xmlCleanupParser(); return ret; } pacemaker-master/extra/rgmanager/list.h000066400000000000000000000044061217637305600205270ustar00rootroot00000000000000#ifndef _LIST_H # define _LIST_H /** Simple list handlig macros. Needs rewrite or inclusion of /usr/include/linux/list.h as a replacement. */ /* Must be first if structure is going to use it. */ struct list_entry { struct list_entry *le_next, *le_prev; }; # define list_head() struct list_entry _list_head # define le(p) (&((*p)._list_head)) # define list_insert(list, newnode) \ do { \ if (!(*list)) { \ le(newnode)->le_next = \ le(newnode)->le_prev = le(newnode); \ *list = (void *)le(newnode); \ } else { \ le(*list)->le_prev->le_next = le(newnode); \ le(newnode)->le_next = le(*list); \ le(newnode)->le_prev = le(*list)->le_prev; \ le(*list)->le_prev = le(newnode); \ } \ } while (0) # define list_prepend(list, newnode) \ do { \ list_insert(list, newnode); \ *list = newnode; \ } while (0) # define list_remove(list, oldnode) \ do { \ if (le(oldnode) == le(*list)) { \ *list = (void *)le(*list)->le_next; \ } \ if (le(oldnode) == le(*list)) { \ le(oldnode)->le_next = NULL; \ le(oldnode)->le_prev = NULL; \ *list = NULL; \ } else { \ le(oldnode)->le_next->le_prev = le(oldnode)->le_prev; \ le(oldnode)->le_prev->le_next = le(oldnode)->le_next; \ le(oldnode)->le_prev = NULL; \ le(oldnode)->le_next = NULL; \ } \ } while (0) /* list_do(list, node) { stuff; } while (!list_done(list, node)); */ # define list_do(list, curr) \ if (*list && (curr = *list)) do # define list_done(list, curr) \ (curr && (((curr = (void *)le(curr)->le_next)) && (curr == *list))) /* * list_for(list, tmp, counter) { * stuff; * } * * counter = # of items in list when done. * * sets cnt to 0 before even checking list; * * checks for valid list * * traverses list, incrementing counter. If we get to the for loop, * there must be at least one item in the list */ # define list_for(list, curr, cnt) \ if (!(cnt=0) && (list != NULL) && (*list != NULL)) \ for (curr = *list; \ (cnt == 0) || (curr != *list); \ curr = (void*)le(curr)->le_next, \ cnt++) # define list_for_rev(list, curr, cnt) \ if (!(cnt=0) && list && *list) \ for (curr = (void *)(le(*list)->le_prev); \ (cnt == 0) || ((void *)curr != le(*list)->le_prev); \ curr = (void*)(le(curr)->le_prev), \ cnt++) #endif pacemaker-master/extra/rgmanager/resgroup.h000066400000000000000000000100471217637305600214200ustar00rootroot00000000000000#ifndef __RESGROUP_H # define __RESGROUP_H # include # include # include # include # include # include # include # include /* Requests */ # define RG_SUCCESS 0 # define RG_FAIL 1 # define RG_START 2 # define RG_STOP 3 # define RG_STATUS 4 # define RG_DISABLE 5 # define RG_STOP_RECOVER 6 # define RG_START_RECOVER 7 # define RG_RESTART 8 # define RG_EXITING 9 # define RG_INIT 10 # define RG_ENABLE 11 # define RG_STATUS_NODE 12 # define RG_RELOCATE 13 # define RG_CONDSTOP 14 # define RG_CONDSTART 15 # define RG_START_REMOTE 16 /* Part of a relocate */ # define RG_STOP_USER 17 /* User-stop request */ # define RG_STOP_EXITING 18 /* Exiting. */ # define RG_LOCK 19 # define RG_UNLOCK 20 # define RG_QUERY_LOCK 21 # define RG_MIGRATE 22 # define RG_FREEZE 23 # define RG_UNFREEZE 24 # define RG_STATUS_INQUIRY 25 # define RG_CONVALESCE 26 # define RG_NONE 999 /* Resource group states (for now) */ # define RG_STATE_BASE 110 # define RG_STATE_STOPPED 110 /** Resource group is stopped */ # define RG_STATE_STARTING 111 /** Resource is starting */ # define RG_STATE_STARTED 112 /** Resource is started */ # define RG_STATE_STOPPING 113 /** Resource is stopping */ # define RG_STATE_FAILED 114 /** Resource has failed */ # define RG_STATE_UNINITIALIZED 115 /** Thread not running yet */ # define RG_STATE_CHECK 116 /** Checking status */ # define RG_STATE_ERROR 117 /** Recoverable error */ # define RG_STATE_RECOVER 118 /** Pending recovery */ # define RG_STATE_DISABLED 119 /** Resource not allowd to run */ # define RG_STATE_MIGRATE 120 /** Resource migrating */ # define DEFAULT_CHECK_INTERVAL 10 /* Resource group flags (for now) */ # define RG_FLAG_FROZEN (1<<0) /** Resource frozen */ # define RG_FLAG_PARTIAL (1<<1) /** One or more non-critical resources offline */ /* Return codes */ # define RG_EEXCL -16 /* Service not runnable due to the fact that it is tagged exclusive and there are no empty nodes. */ # define RG_EDOMAIN -15 /* Service not runnable given the set of nodes and its failover domain */ # define RG_ESCRIPT -14 /* S/Lang script failed */ # define RG_EFENCE -13 /* Fencing operation pending */ # define RG_ENODE -12 /* Node is dead/nonexistent */ # define RG_EFROZEN -11 /* Forward compat. with -HEAD */ # define RG_ERUN -10 /* Service is already running */ # define RG_EQUORUM -9 /* Operation requires quorum */ # define RG_EINVAL -8 /* Invalid operation for resource */ # define RG_EDEPEND -7 /* Operation violates dependency */ # define RG_EAGAIN -6 /* Try again */ # define RG_EDEADLCK -5 /* Aborted - would deadlock */ # define RG_ENOSERVICE -4 /* Service does not exist */ # define RG_EFORWARD -3 /* Service not mastered locally */ # define RG_EABORT -2 /* Abort; service unrecoverable */ # define RG_EFAIL -1 /* Generic failure */ # define RG_ESUCCESS 0 # define RG_YES 1 # define RG_NO 2 const char *rg_strerror(int val); /* * Fail-over domain states */ # define FOD_ILLEGAL 0 # define FOD_GOOD 1 # define FOD_BETTER 2 # define FOD_BEST 3 /* Fail-over domain flags */ # define FOD_ORDERED (1<<0) # define FOD_RESTRICTED (1<<1) # define FOD_NOFAILBACK (1<<2) /* Status tree flags */ # define SFL_FAILURE (1<<0) # define SFL_RECOVERABLE (1<<1) # define SFL_PARTIAL (1<<2) #endif pacemaker-master/extra/rgmanager/reslist.c000066400000000000000000000326161217637305600212400ustar00rootroot00000000000000/* Copyright Red Hat, Inc. 2004 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 2, 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; see the file COPYING. If not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include #include #include #include #include #include #include #include #include #include #include void res_build_name(char *buf, size_t buflen, resource_t * res) { snprintf(buf, buflen, "%s:%s", res->r_rule->rr_type, res->r_attrs[0].ra_value); } /** Find and determine an attribute's value. @param res Resource node to look examine @param attrname Attribute to retrieve. @return value of attribute or NULL if not found */ char * res_attr_value(resource_t * res, const char *attrname) { resource_attr_t *ra; int x; for (x = 0; res->r_attrs && res->r_attrs[x].ra_name; x++) { if (strcmp(attrname, res->r_attrs[x].ra_name)) continue; ra = &res->r_attrs[x]; if (ra->ra_flags & RA_INHERIT) /* Can't check inherited resources */ return NULL; return ra->ra_value; } return NULL; } /** Find and determine an attribute's value. Takes into account inherited attribute flag, and append attribute flag, which isn't implemented yet. @param node Resource tree node to look examine @param attrname Attribute to retrieve. @param ptype Resource type to look for (if inheritance) @return value of attribute or NULL if not found */ static char * _attr_value(resource_node_t * node, const char *attrname, const char *ptype) { resource_t *res; resource_attr_t *ra; char *c, p_type[32]; ssize_t len; int x; if (!node) return NULL; res = node->rn_resource; /* Go up the tree if it's not the right parent type */ if (ptype && strcmp(res->r_rule->rr_type, ptype)) return _attr_value(node->rn_parent, attrname, ptype); for (x = 0; res->r_attrs && res->r_attrs[x].ra_name; x++) { if (strcmp(attrname, res->r_attrs[x].ra_name)) continue; ra = &res->r_attrs[x]; if (!(ra->ra_flags & RA_INHERIT)) return ra->ra_value; /* Handle resource_type%field to be more precise, so we don't have to worry about this being a child of an unexpected type. E.g. lots of things have the "name" attribute. */ c = strchr(ra->ra_value, '%'); if (!c) { /* Someone doesn't care or uses older semantics on inheritance */ return _attr_value(node->rn_parent, ra->ra_value, NULL); } len = (c - ra->ra_value); memset(p_type, 0, sizeof(p_type)); memcpy(p_type, ra->ra_value, len); /* Skip the "%" and recurse */ return _attr_value(node->rn_parent, ++c, p_type); } return NULL; } char * attr_value(resource_node_t * node, const char *attrname) { return _attr_value(node, attrname, NULL); } char * primary_attr_value(resource_t * res) { int x; resource_attr_t *ra; for (x = 0; res->r_attrs && res->r_attrs[x].ra_name; x++) { ra = &res->r_attrs[x]; if (!(ra->ra_flags & RA_PRIMARY)) continue; return ra->ra_value; } return NULL; } /** Find a resource given its reference. A reference is the value of the primary attribute. @param reslist List of resources to traverse. @param type Type of resource to look for. @param ref Reference @return Resource matching type/ref or NULL if none. */ resource_t * find_resource_by_ref(resource_t ** reslist, char *type, char *ref) { resource_t *curr; int x; list_do(reslist, curr) { if (strcmp(curr->r_rule->rr_type, type)) continue; /* This should be one operation - the primary attr is generally at the head of the array. */ for (x = 0; curr->r_attrs && curr->r_attrs[x].ra_name; x++) { if (!(curr->r_attrs[x].ra_flags & RA_PRIMARY)) continue; if (strcmp(ref, curr->r_attrs[x].ra_value)) continue; return curr; } } while (!list_done(reslist, curr)) ; return NULL; } /** Store a resource in the resource list if it's legal to do so. Otherwise, don't store it. Note: This function needs to be rewritten; it's way too long and way too indented. @param reslist Resource list to store the new resource. @param newres Resource to store @return 0 on succes; nonzero on failure. */ int store_resource(resource_t ** reslist, resource_t * newres) { resource_t *curr; int x, y; if (!*reslist) { /* first resource */ list_insert(reslist, newres); return 0; } list_do(reslist, curr) { if (strcmp(curr->r_rule->rr_type, newres->r_rule->rr_type)) continue; for (x = 0; newres->r_attrs && newres->r_attrs[x].ra_name; x++) { /* Look for conflicting primary/unique keys */ if (!(newres->r_attrs[x].ra_flags & (RA_PRIMARY | RA_UNIQUE))) continue; for (y = 0; curr->r_attrs[y].ra_name; y++) { if (curr->r_attrs[y].ra_flags & RA_INHERIT) continue; if (strcmp(curr->r_attrs[y].ra_name, newres->r_attrs[x].ra_name)) continue; if (!strcmp(curr->r_attrs[y].ra_value, newres->r_attrs[x].ra_value)) { /* Unique/primary is not unique */ fprintf(stderr, "%s attribute collision. " "type=%s attr=%s value=%s\n", (newres->r_attrs[x].ra_flags & RA_PRIMARY) ? "Primary" : "Unique", newres->r_rule->rr_type, newres->r_attrs[x].ra_name, newres->r_attrs[x].ra_value); return -1; } break; } } } while (!list_done(reslist, curr)) ; list_insert(reslist, newres); return 0; } /** Obliterate a resource_t structure. @param res Resource to free. */ void destroy_resource(resource_t * res) { int x; if (res->r_name) free(res->r_name); if (res->r_attrs) { for (x = 0; res->r_attrs && res->r_attrs[x].ra_name; x++) { free(res->r_attrs[x].ra_name); free(res->r_attrs[x].ra_value); } free(res->r_attrs); } if (res->r_actions) { /* Don't free the strings; they're part of the rule */ free(res->r_actions); } free(res); } /** Obliterate a resource_t list. @param list Resource list to free. */ void destroy_resources(resource_t ** list) { resource_t *res; while ((res = *list)) { list_remove(list, res); destroy_resource(res); } } void * act_dup(resource_act_t * acts) { int x; resource_act_t *newacts; for (x = 0; acts[x].ra_name; x++) ; ++x; x *= sizeof(resource_act_t); newacts = malloc(x); if (!newacts) return NULL; memcpy(newacts, acts, x); return newacts; } /* Copied from resrules.c -- _get_actions */ static void _get_actions_ccs(const char *base, resource_t * res) { char xpath[256]; int idx = 0; char *act, *ret; int interval, timeout, depth; do { /* setting these to -1 prevents overwriting with 0 */ interval = -1; depth = -1; act = NULL; timeout = -1; snprintf(xpath, sizeof(xpath), "%s/action[%d]/@name", base, ++idx); if (conf_get(xpath, &act) != 0) break; snprintf(xpath, sizeof(xpath), "%s/action[%d]/@timeout", base, idx); if (conf_get(xpath, &ret) == 0 && ret) { timeout = expand_time(ret); if (timeout < 0) timeout = 0; free(ret); } snprintf(xpath, sizeof(xpath), "%s/action[%d]/@interval", base, idx); if (conf_get(xpath, &ret) == 0 && ret) { interval = expand_time(ret); if (interval < 0) interval = 0; free(ret); } if (!strcmp(act, "status") || !strcmp(act, "monitor")) { snprintf(xpath, sizeof(xpath), "%s/action[%d]/@depth", base, idx); if (conf_get(xpath, &ret) == 0 && ret) { depth = atoi(ret); if (depth < 0) depth = 0; /* */ if (ret[0] == '*') depth = -1; free(ret); } } if (store_action(&res->r_actions, act, depth, timeout, interval) != 0) free(act); } while (1); } /** Try to load all the attributes in our rule set. If none are found, or an error occurs, return NULL and move on to the next one. @param rule Resource rule set to use when looking for data @param base Base XPath path to start with. @return New resource if legal or NULL on failure/error */ resource_t * load_resource(resource_rule_t * rule, const char *base) { resource_t *res; char ccspath[1024]; char *attrname, *attr; int x, found = 0, flags; res = malloc(sizeof(*res)); if (!res) { fprintf(stderr, "Out of memory\n"); return NULL; } memset(res, 0, sizeof(*res)); res->r_rule = rule; for (x = 0; res->r_rule->rr_attrs && res->r_rule->rr_attrs[x].ra_name; x++) { flags = rule->rr_attrs[x].ra_flags; attrname = strdup(rule->rr_attrs[x].ra_name); if (!attrname) { destroy_resource(res); return NULL; } /* Ask CCS for the respective attribute */ attr = NULL; snprintf(ccspath, sizeof(ccspath), "%s/@%s", base, attrname); if (conf_get(ccspath, &attr) != 0) { if (flags & (RA_REQUIRED | RA_PRIMARY)) { /* Missing required attribute. We're done. */ free(attrname); destroy_resource(res); return NULL; } if (!(flags & RA_INHERIT)) { /* If we don't have the inherit flag, see if we have a value anyway. If we do, this value is the default value, and should be used. */ if (!rule->rr_attrs[x].ra_value) { free(attrname); continue; } /* Copy default value from resource rule */ attr = strdup(rule->rr_attrs[x].ra_value); } } found = 1; /* If we are supposed to inherit and we don't have an instance of the specified attribute in CCS, then we keep the inherit flag and use it as the attribute. However, if we _do_ have the attribute for this instance, we drop the inherit flag and use the attribute. */ if (flags & RA_INHERIT) { if (attr) { flags &= ~RA_INHERIT; } else { attr = strdup(rule->rr_attrs[x].ra_value); if (!attr) { destroy_resource(res); free(attrname); return NULL; } } } /* Store the attribute. We'll ensure all required attributes are present soon. */ if (attrname && attr) store_attribute(&res->r_attrs, attrname, attr, flags); } if (!found) { destroy_resource(res); return NULL; } res->r_actions = act_dup(rule->rr_actions); _get_actions_ccs(base, res); return res; } /** Read all resources in the resource manager block in CCS. @param reslist Empty list to fill with resources. @param rulelist List of rules to use when searching CCS. @return 0 on success, nonzero on failure. */ int load_resources(resource_t ** reslist, resource_rule_t ** rulelist) { int resID = 0; resource_t *newres; resource_rule_t *currule; char tok[256]; list_do(rulelist, currule) { for (resID = 1;; resID++) { snprintf(tok, sizeof(tok), RESOURCE_BASE "/%s[%d]", currule->rr_type, resID); newres = load_resource(currule, tok); if (!newres) break; if (store_resource(reslist, newres) != 0) { fprintf(stderr, "Error storing %s resource\n", newres->r_rule->rr_type); destroy_resource(newres); } /* Just information */ newres->r_flags = RF_DEFINED; } } while (!list_done(rulelist, currule)) ; return 0; } pacemaker-master/extra/rgmanager/reslist.h000066400000000000000000000140141217637305600212350ustar00rootroot00000000000000/* Copyright Red Hat, Inc. 2004 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 2, 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; see the file COPYING. If not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef _RESLIST_H # define _RESLIST_H # include # include # include # include # define RA_PRIMARY (1<<0) /** Primary key */ # define RA_UNIQUE (1<<1) /** Unique for given type */ # define RA_REQUIRED (1<<2) /** Required (or an error if not present */ # define RA_INHERIT (1<<3) /** Inherit a parent resource's attr */ # define RA_RECONFIG (1<<4) /** Allow inline reconfiguration */ # define RF_INLINE (1<<0) # define RF_DEFINED (1<<1) # define RF_NEEDSTART (1<<2) /** Used when adding/changing resources */ # define RF_NEEDSTOP (1<<3) /** Used when deleting/changing resources */ # define RF_COMMON (1<<4) /** " */ # define RF_INDEPENDENT (1<<5) /** Define this for a resource if it is otherwise an independent subtree */ # define RF_RECONFIG (1<<6) # define RF_INIT (1<<7) /** Resource rule: Initialize this resource class on startup */ # define RF_DESTROY (1<<8) /** Resource rule flag: Destroy this resource class if you delete it from the configuration */ # define RF_ENFORCE_TIMEOUTS (1<<9) /** Enforce timeouts for this node */ # define RF_NON_CRITICAL (1<<10) /** stop this resource if it fails */ # define RF_QUIESCE (1<<11) /** don't restart this resource */ # define RES_STOPPED (0) # define RES_STARTED (1) # define RES_FAILED (2) # define RES_DISABLED (3) # ifndef SHAREDIR # define SHAREDIR "/usr/share/cluster" # endif # define RESOURCE_ROOTDIR SHAREDIR # define RESOURCE_TREE_ROOT "//rm" # define RESOURCE_BASE RESOURCE_TREE_ROOT "/resources" # define RESOURCE_ROOT_FMT RESOURCE_TREE_ROOT "/%s[%d]" # define RESOURCE_MAX_LEVELS 100 /* Include OCF definitions */ //#include typedef struct _resource_attribute { char *ra_name; char *ra_value; int ra_flags; int _pad_; } resource_attr_t; typedef struct _resource_child { char *rc_name; int rc_startlevel; int rc_stoplevel; int rc_forbid; int rc_flags; } resource_child_t; typedef struct _resource_act { char *ra_name; time_t ra_timeout; time_t ra_last; time_t ra_interval; int ra_depth; int _pad_; } resource_act_t; typedef struct _resource_rule { list_head(); char *rr_type; char *rr_agent; char *rr_version; /** agent XML spec version; OCF-ism */ int rr_flags; int rr_maxrefs; resource_attr_t *rr_attrs; resource_child_t *rr_childtypes; resource_act_t *rr_actions; } resource_rule_t; typedef struct _resource { list_head(); resource_rule_t *r_rule; char *r_name; resource_attr_t *r_attrs; resource_act_t *r_actions; int r_flags; int r_refs; int r_incarnations; /** Number of instances running locally */ int _pad_; /* align */ } resource_t; typedef struct _rg_node { list_head(); struct _rg_node *rn_child, *rn_parent; resource_t *rn_resource; resource_act_t *rn_actions; int rn_state; /* State of this instance of rn_resource */ int rn_flags; int rn_last_status; int rn_last_depth; int rn_checked; int rn_pad; } resource_node_t; typedef struct _fod_node { list_head(); char *fdn_name; int fdn_prio; int fdn_nodeid; /* on rhel4 this will be 64-bit int */ } fod_node_t; typedef struct _fod { list_head(); char *fd_name; fod_node_t *fd_nodes; int fd_flags; int _pad_; /* align */ } fod_t; /* Exported Functions */ int res_flatten(xmlNode ** n, xmlNode * r, resource_node_t ** tree, resource_t * res); int expand_time(char *val); int store_action(resource_act_t ** actsp, char *name, int depth, int timeout, int interval); /* Load/kill resource rule sets */ int load_resource_rules(const char *rpath, resource_rule_t ** rules); void destroy_resource_rules(resource_rule_t ** rules); /* Load/kill resource sets */ int load_resources(resource_t ** reslist, resource_rule_t ** rulelist); void dump_resources(FILE * fp, resource_t ** reslist); void destroy_resources(resource_t ** list); /* Construct/deconstruct resource trees */ int build_resource_tree(resource_node_t ** tree, resource_rule_t ** rulelist, resource_t ** reslist); void destroy_resource_tree(resource_node_t ** tree); /* Construct/deconstruct failover domains */ int construct_domains(fod_t ** domains); void deconstruct_domains(fod_t ** domains); /* Handy functions */ resource_t *find_resource_by_ref(resource_t ** reslist, char *type, char *ref); resource_rule_t *find_rule_by_type(resource_rule_t ** rulelist, char *type); void res_build_name(char *, size_t, resource_t *); /* Internal functions; shouldn't be needed. */ int store_attribute(resource_attr_t ** attrsp, char *name, char *value, int flags); resource_t *load_resource(resource_rule_t * rule, const char *base); int store_resource(resource_t ** reslist, resource_t * newres); void destroy_resource(resource_t * res); char *attr_value(resource_node_t * node, const char *attrname); char *res_attr_value(resource_t * res, const char *attrname); char *primary_attr_value(resource_t *); void *act_dup(resource_act_t * acts); #endif /* _RESLIST_H */ pacemaker-master/extra/rgmanager/resrules.c000066400000000000000000000606301217637305600214140ustar00rootroot00000000000000/* Copyright Red Hat, Inc. 2004-2010 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 2, 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; see the file COPYING. If not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include /** Store a new resource rule in the given rule list. @param rulelist List of rules to store new rule in. @param newrule New rule to store. @return 0 on success or -1 if rule with same name already exists in rulelist */ static int store_rule(resource_rule_t ** rulelist, resource_rule_t * newrule) { resource_rule_t *curr; list_do(rulelist, curr) { if (!strcmp(newrule->rr_type, curr->rr_type)) { fprintf(stderr, "Error storing %s: Duplicate\n", newrule->rr_type); return -1; } } while (!list_done(rulelist, curr)) ; list_insert(rulelist, newrule); return 0; } /** Obliterate a resource_rule_t structure. @param rr Resource rule to free. */ static void destroy_resource_rule(resource_rule_t * rr) { int x; if (rr->rr_type) free(rr->rr_type); if (rr->rr_agent) free(rr->rr_agent); if (rr->rr_version) free(rr->rr_version); if (rr->rr_attrs) { for (x = 0; rr->rr_attrs && rr->rr_attrs[x].ra_name; x++) { free(rr->rr_attrs[x].ra_name); if (rr->rr_attrs[x].ra_value) free(rr->rr_attrs[x].ra_value); } free(rr->rr_attrs); } if (rr->rr_actions) { for (x = 0; rr->rr_actions && rr->rr_actions[x].ra_name; x++) { free(rr->rr_actions[x].ra_name); } free(rr->rr_actions); } if (rr->rr_childtypes) { for (x = 0; rr->rr_childtypes && rr->rr_childtypes[x].rc_name; x++) free(rr->rr_childtypes[x].rc_name); free(rr->rr_childtypes); } free(rr); } /** Destroy a list of resource rules. @param rules List of rules to destroy. */ void destroy_resource_rules(resource_rule_t ** rules) { resource_rule_t *rr; while ((rr = *rules)) { list_remove(rules, rr); destroy_resource_rule(rr); } } /** Get and store the maxparents (max instances) attribute for a given resource rule set. @param doc Pre-parsed XML document pointer. @param ctx Pre-allocated XML XPath context pointer. @param base XPath prefix to search @param rr Resource rule to store new information in. */ static void _get_maxparents(xmlDocPtr doc, xmlXPathContextPtr ctx, char *base, resource_rule_t * rr) { char xpath[256]; char *ret = NULL; snprintf(xpath, sizeof(xpath), "%s/attributes/@maxinstances", base); ret = xpath_get_one(doc, ctx, xpath); if (ret) { rr->rr_maxrefs = atoi(ret); if (rr->rr_maxrefs < 0) rr->rr_maxrefs = 0; free(ret); } } /** Get and store a bit field. @param doc Pre-parsed XML document pointer. @param ctx Pre-allocated XML XPath context pointer. @param base XPath prefix to search @param rr Resource rule to store new information in. */ static void _get_rule_flag(xmlDocPtr doc, xmlXPathContextPtr ctx, const char *base, resource_rule_t * rr, const char *flag, int bit) { char xpath[256]; char *ret = NULL; snprintf(xpath, sizeof(xpath), "%s/attributes/@%s", base, flag); ret = xpath_get_one(doc, ctx, xpath); if (ret) { if (atoi(ret)) { rr->rr_flags |= bit; } else { rr->rr_flags &= ~bit; } free(ret); } } /** Get and store the version @param doc Pre-parsed XML document pointer. @param ctx Pre-allocated XML XPath context pointer. @param base XPath prefix to search @param rr Resource rule to store new information in. */ static void _get_version(xmlDocPtr doc, xmlXPathContextPtr ctx, char *base, resource_rule_t * rr) { char xpath[256]; char *ret = NULL; snprintf(xpath, sizeof(xpath), "%s/@version", base); ret = xpath_get_one(doc, ctx, xpath); if (ret) { rr->rr_version = ret; free(ret); } rr->rr_version = NULL; } int expand_time(char *val) { int curval, len; int ret = 0; char *start = val, ival[16]; if (!val) return (time_t) 0; while (start[0]) { len = 0; curval = 0; memset(ival, 0, sizeof(ival)); while (isdigit(start[len])) { ival[len] = start[len]; len++; } if (len) { curval = atoi(ival); } else { len = 1; } switch (start[len]) { case 0: case 'S': case 's': break; case 'M': case 'm': curval *= 60; break; case 'h': case 'H': curval *= 3600; break; case 'd': case 'D': curval *= 86400; break; case 'w': case 'W': curval *= 604800; break; case 'y': case 'Y': curval *= 31536000; break; default: curval = 0; } ret += (time_t) curval; start += len; } return ret; } /** * Store a resource action * @param actsp Action array; may be modified and returned! * @param name Name of the action * @param depth Resource depth (status/monitor; -1 means *ALL LEVELS* * ... this means that only the highest-level check depth * will ever be performed!) * @param timeout Timeout (not used) * @param interval Time interval for status/monitor * @return 0 on success, -1 on failure * */ int store_action(resource_act_t ** actsp, char *name, int depth, int timeout, int interval) { int x = 0, replace = 0; resource_act_t *acts = *actsp; if (!name) return -1; if (depth < 0 && timeout < 0 && interval < 0) return -1; if (!acts) { /* Can't create with anything < 0 */ if (depth < 0 || timeout < 0 || interval < 0) return -1; acts = malloc(sizeof(resource_act_t) * 2); if (!acts) return -1; acts[0].ra_name = name; acts[0].ra_depth = depth; acts[0].ra_timeout = timeout; acts[0].ra_interval = interval; acts[0].ra_last = 0; acts[1].ra_name = NULL; *actsp = acts; return 0; } for (x = 0; acts[x].ra_name; x++) { if (!strcmp(acts[x].ra_name, name) && (depth == acts[x].ra_depth || depth == -1)) { fprintf(stderr, "Replacing action '%s' depth %d: ", name, acts[x].ra_depth); if (timeout >= 0) { fprintf(stderr, "timeout: %d->%d ", (int)acts[x].ra_timeout, (int)timeout); acts[x].ra_timeout = timeout; } if (interval >= 0) { fprintf(stderr, "interval: %d->%d", (int)acts[x].ra_interval, (int)interval); acts[x].ra_interval = interval; } fprintf(stderr, "\n"); replace = 1; } } if (replace) /* If we replaced something, we're done */ return 1; /* Can't create with anything < 0 */ if (depth < 0 || timeout < 0 || interval < 0) return -1; acts = realloc(acts, sizeof(resource_act_t) * (x + 2)); if (!acts) return -1; acts[x].ra_name = name; acts[x].ra_depth = depth; acts[x].ra_timeout = timeout; acts[x].ra_interval = interval; acts[x].ra_last = 0; acts[x + 1].ra_name = NULL; *actsp = acts; return 0; } static void _get_actions(xmlDocPtr doc, xmlXPathContextPtr ctx, char *base, resource_rule_t * rr) { char xpath[256]; int idx = 0; char *act, *ret; int interval, timeout, depth; do { interval = 0; depth = 0; act = NULL; timeout = 0; snprintf(xpath, sizeof(xpath), "%s/action[%d]/@name", base, ++idx); act = xpath_get_one(doc, ctx, xpath); if (!act) break; snprintf(xpath, sizeof(xpath), "%s/action[%d]/@timeout", base, idx); ret = xpath_get_one(doc, ctx, xpath); if (ret) { timeout = expand_time(ret); if (timeout < 0) timeout = 0; free(ret); } snprintf(xpath, sizeof(xpath), "%s/action[%d]/@interval", base, idx); ret = xpath_get_one(doc, ctx, xpath); if (ret) { interval = expand_time(ret); if (interval < 0) interval = 0; free(ret); } if (!strcmp(act, "status") || !strcmp(act, "monitor")) { snprintf(xpath, sizeof(xpath), "%s/action[%d]/@depth", base, idx); ret = xpath_get_one(doc, ctx, xpath); if (ret) { depth = atoi(ret); if (depth < 0) depth = 0; free(ret); } } if (store_action(&rr->rr_actions, act, depth, timeout, interval) != 0) free(act); } while (1); } /** Store an attribute with the given name, value, and flags in a resource_t structure. XXX This could be rewritten to use the list macros. @param attrsp Attribute array to store new attribute in. @param name Name of attribute (must be non-null) @param value Value of attribute @param flags Attribute flags, or 0 if none. @return 0 on success, nonzero on error/failure */ int store_attribute(resource_attr_t ** attrsp, char *name, char *value, int flags) { int x = 0; resource_attr_t *attrs = *attrsp; if (!name) return -1; if (!attrs) { attrs = malloc(sizeof(resource_attr_t) * 2); if (!attrs) return -1; attrs[0].ra_name = name; attrs[0].ra_value = value; attrs[0].ra_flags = flags; attrs[1].ra_name = NULL; attrs[1].ra_value = NULL; *attrsp = attrs; return 0; } for (x = 0; attrs[x].ra_name; x++) ; attrs = realloc(attrs, sizeof(resource_attr_t) * (x + 2)); if (!attrs) return -1; /* Primary attribute goes first. This makes this interaction with CCS work way faster. */ if (flags & RA_PRIMARY) { attrs[x].ra_name = attrs[0].ra_name; attrs[x].ra_value = attrs[0].ra_value; attrs[x].ra_flags = attrs[0].ra_flags; attrs[0].ra_name = name; attrs[0].ra_value = value; attrs[0].ra_flags = flags; } else { attrs[x].ra_name = name; attrs[x].ra_value = value; attrs[x].ra_flags = flags; } attrs[x + 1].ra_name = NULL; attrs[x + 1].ra_value = NULL; *attrsp = attrs; return 0; } /** Store a child type in the child array of a resource rule. XXX Could be rewritten to use list macros. @param childp Child array. Might be modified. @param name Name of child type @param start Start level @param stop Stop level @param forbid Do NOT allow this child type to exist @param flags set to 1 to note that it was defined inline @return 0 on success, nonzero on failure */ static int store_childtype(resource_child_t ** childp, char *name, int start, int stop, int forbid, int flags) { int x = 0; resource_child_t *child = *childp; if (!name) return -1; if (!child) { child = malloc(sizeof(resource_child_t) * 2); if (!child) return -1; child[0].rc_name = name; child[0].rc_startlevel = start; child[0].rc_stoplevel = stop; child[0].rc_forbid = forbid; child[0].rc_flags = flags; child[1].rc_name = NULL; *childp = child; return 0; } for (x = 0; child[x].rc_name; x++) ; child = realloc(child, sizeof(resource_child_t) * (x + 2)); if (!child) return -1; child[x].rc_name = name; child[x].rc_startlevel = start; child[x].rc_stoplevel = stop; child[x].rc_forbid = forbid; child[x].rc_flags = flags; child[x + 1].rc_name = NULL; *childp = child; return 0; } /** Get and store attributes for a given instance of a resource rule. @param doc Pre-parsed XML document pointer. @param ctx Pre-allocated XML XPath context pointer. @param base XPath prefix to search @param rr Resource rule to store new information in. @return 0 */ static int _get_rule_attrs(xmlDocPtr doc, xmlXPathContextPtr ctx, const char *base, resource_rule_t * rr) { char *ret, *attrname, *dflt = NULL, xpath[256]; int x, flags, primary_found = 0; for (x = 1; 1; x++) { snprintf(xpath, sizeof(xpath), "%s/parameter[%d]/@name", base, x); ret = xpath_get_one(doc, ctx, xpath); if (!ret) break; flags = 0; attrname = ret; /* See if there's a default value. */ snprintf(xpath, sizeof(xpath), "%s/parameter[%d]/content/@default", base, x); dflt = xpath_get_one(doc, ctx, xpath); /* See if this is either the primary identifier or a required field. */ snprintf(xpath, sizeof(xpath), "%s/parameter[%d]/@required", base, x); if ((ret = xpath_get_one(doc, ctx, xpath))) { if ((atoi(ret) != 0) || (ret[0] == 'y')) flags |= RA_REQUIRED; free(ret); } /* See if this is supposed to be unique */ snprintf(xpath, sizeof(xpath), "%s/parameter[%d]/@unique", base, x); if ((ret = xpath_get_one(doc, ctx, xpath))) { if ((atoi(ret) != 0) || (ret[0] == 'y')) flags |= RA_UNIQUE; free(ret); } snprintf(xpath, sizeof(xpath), "%s/parameter[%d]/@primary", base, x); if ((ret = xpath_get_one(doc, ctx, xpath))) { if ((atoi(ret) != 0) || (ret[0] == 'y')) { if (primary_found) { free(ret); fprintf(stderr, "Multiple primary " "definitions for " "resource type %s\n", rr->rr_type); return -1; } flags |= RA_PRIMARY; primary_found = 1; } free(ret); } /* See if this can be reconfigured on the fly without a stop/start */ snprintf(xpath, sizeof(xpath), "%s/parameter[%d]/@reconfig", base, x); if ((ret = xpath_get_one(doc, ctx, xpath))) { if ((atoi(ret) != 0) || (ret[0] == 'y')) flags |= RA_RECONFIG; free(ret); } /* See if this is supposed to be inherited */ snprintf(xpath, sizeof(xpath), "%s/parameter[%d]/@inherit", base, x); if ((ret = xpath_get_one(doc, ctx, xpath))) { flags |= RA_INHERIT; if (flags & (RA_REQUIRED | RA_PRIMARY | RA_UNIQUE)) { free(ret); fprintf(stderr, "Can not inherit and be primary, " "unique, or required\n"); return -1; } /* don't free ret. Store as attr value. If we had a default value specified from above, free it; inheritance supercedes a specified default value. */ if (dflt) free(dflt); } else { /* Use default value, if specified, as the attribute value. */ ret = dflt; } /* Store the attribute. We'll ensure all required attributes are present soon. */ if (attrname) store_attribute(&rr->rr_attrs, attrname, ret, flags); } return 0; } /** Get and store attributes for a given instance of a resource. @param doc Pre-parsed XML document pointer. @param ctx Pre-allocated XML XPath context pointer. @param base XPath prefix to search @param rr Resource rule to store new information in. @return 0 */ static int _get_childtypes(xmlDocPtr doc, xmlXPathContextPtr ctx, char *base, resource_rule_t * rr) { char *ret, *childname, xpath[256]; int x, startlevel = 0, stoplevel = 0, forbid = 0; for (x = 1; 1; x++) { snprintf(xpath, sizeof(xpath), "%s/child[%d]/@type", base, x); ret = xpath_get_one(doc, ctx, xpath); if (!ret) break; startlevel = stoplevel = forbid = 0; childname = ret; /* Try to get the start level if it exists */ snprintf(xpath, sizeof(xpath), "%s/child[%d]/@start", base, x); if ((ret = xpath_get_one(doc, ctx, xpath))) { startlevel = atoi(ret); free(ret); } /* Try to get the stop level if it exists */ snprintf(xpath, sizeof(xpath), "%s/child[%d]/@stop", base, x); if ((ret = xpath_get_one(doc, ctx, xpath))) { stoplevel = atoi(ret); free(ret); } /* Get the 'forbidden' flag if it exists */ snprintf(xpath, sizeof(xpath), "%s/child[%d]/@forbid", base, x); if ((ret = xpath_get_one(doc, ctx, xpath))) { forbid = atoi(ret); free(ret); } /* Store the attribute. We'll ensure all required attributes are present soon. */ if (childname) store_childtype(&rr->rr_childtypes, childname, startlevel, stoplevel, forbid, 0); } return 0; } /** Read a file from a stdout pipe. */ static int read_pipe(int fd, char **file, size_t * length) { char buf[4096]; int n, done = 0; *file = NULL; *length = 0; while (!done) { n = read(fd, buf, sizeof(buf)); if (n < 0) { if (errno == EINTR) continue; if (*file) free(*file); return -1; } if (n == 0 && (!*length)) return 0; if (n == 0) { done = 1; } if (*file) *file = realloc(*file, (*length) + n + done); else *file = malloc(n + done); if (!*file) return -1; memcpy((*file) + (*length), buf, n); *length += (done + n); } /* Null terminator */ (*file)[(*length) - 1] = 0; return 0; } static xmlDocPtr read_resource_agent_metadata(char *filename) { int pid; int _pipe[2]; char *data; size_t size; xmlDocPtr doc; if (pipe(_pipe) == -1) return NULL; pid = fork(); if (pid == -1) { close(_pipe[0]); close(_pipe[1]); } if (pid == 0) { /* child */ close(0); close(1); close(2); close(_pipe[0]); dup2(_pipe[1], 1); close(_pipe[1]); /* exec */ execl(filename, filename, "meta-data", NULL); exit(1); } close(_pipe[1]); /* parent */ if (read_pipe(_pipe[0], &data, &size) == -1) { close(_pipe[0]); return NULL; } waitpid(pid, NULL, 0); close(_pipe[0]); if (!size) return NULL; doc = xmlParseMemory(data, size); free(data); return doc; } /** Load the XML rule set for a resource and store attributes, constructing a new resource_t structure. @param filename File name to load rules from @param rules Rule list to add new rules to @return 0 */ static int load_resource_rulefile(char *filename, resource_rule_t ** rules) { resource_rule_t *rr = NULL; xmlDocPtr doc = NULL; xmlXPathContextPtr ctx = NULL; int ruleid = 0; char *type; char base[256]; doc = read_resource_agent_metadata(filename); if (!doc) return 0; ctx = xmlXPathNewContext(doc); do { /* Look for resource types */ snprintf(base, sizeof(base), "/resource-agent[%d]/@name", ++ruleid); type = xpath_get_one(doc, ctx, base); if (!type) break; if (!strcasecmp(type, "action")) { fprintf(stderr, "Error: Resource type '%s' is reserved", type); free(type); break; } rr = malloc(sizeof(*rr)); if (!rr) break; memset(rr, 0, sizeof(*rr)); rr->rr_flags = RF_INIT | RF_DESTROY; rr->rr_type = type; snprintf(base, sizeof(base), "/resource-agent[%d]", ruleid); /* First, grab the global attributes if existent */ _get_version(doc, ctx, base, rr); snprintf(base, sizeof(base), "/resource-agent[%d]/special[@tag=\"rgmanager\"]", ruleid); _get_maxparents(doc, ctx, base, rr); _get_rule_flag(doc, ctx, base, rr, "init_on_add", RF_INIT); _get_rule_flag(doc, ctx, base, rr, "destroy_on_delete", RF_DESTROY); rr->rr_agent = strdup(filename); /* Second, add the children fields */ _get_childtypes(doc, ctx, base, rr); /* Get the OCF status check intervals/monitor. */ snprintf(base, sizeof(base), "/resource-agent[%d]/actions", ruleid); _get_actions(doc, ctx, base, rr); /* Last, load the attributes from our XML file and their respective instantiations from CCS */ snprintf(base, sizeof(base), "/resource-agent[%d]/parameters", ruleid); if (_get_rule_attrs(doc, ctx, base, rr) < 0) { destroy_resource_rule(rr); rr = NULL; } if (!rr) continue; if (store_rule(rules, rr) != 0) { destroy_resource_rule(rr); rr = NULL; } } while (1); if (ctx) xmlXPathFreeContext(ctx); if (doc) xmlFreeDoc(doc); return 0; } /** Load all the resource rules we can find from our resource root directory. @param rules Rule list to create/add to @return 0 on success, -1 on failure. Sucess does not imply any rules have been found; only that no errors were encountered. */ int load_resource_rules(const char *rpath, resource_rule_t ** rules) { DIR *dir; struct dirent *de; char *fn, *dot; char path[2048]; struct stat st_buf; dir = opendir(rpath); if (!dir) return -1; xmlInitParser(); while ((de = readdir(dir))) { fn = basename(de->d_name); if (!fn) continue; /* Ignore files with common backup extension */ if ((fn != NULL) && (strlen(fn) > 0) && (fn[strlen(fn) - 1] == '~')) continue; /* Ignore hidden files */ if (*fn == '.') continue; dot = strrchr(fn, '.'); if (dot) { /* Ignore RPM installed save files, patches, diffs, etc. */ if (!strncasecmp(dot, ".rpm", 4)) { fprintf(stderr, "Warning: " "Ignoring %s/%s: Bad extension %s\n", rpath, de->d_name, dot); continue; } } snprintf(path, sizeof(path), "%s/%s", rpath, de->d_name); if (stat(path, &st_buf) < 0) continue; if (S_ISDIR(st_buf.st_mode)) continue; if (st_buf.st_mode & (S_IXUSR | S_IXOTH | S_IXGRP)) { //printf("Loading resource rule from %s\n", path); load_resource_rulefile(path, rules); } } closedir(dir); return 0; } /** Find a resource rule given its type. @param rulelist Rule list to search @param type Rule type identifier @return Resource rule or NULL if not found. */ resource_rule_t * find_rule_by_type(resource_rule_t ** rulelist, char *type) { resource_rule_t *curr = NULL; list_do(rulelist, curr) { if (!strcmp(curr->rr_type, type)) return curr; } while (!list_done(rulelist, curr)) ; return NULL; } pacemaker-master/extra/rgmanager/restree.c000066400000000000000000000521561217637305600212250ustar00rootroot00000000000000/* Copyright Red Hat, Inc. 2004-2006 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 2, 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; see the file COPYING. If not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Fix for #193859 - relocation of a service w/o umounting file-systems by Navid Sheikhol-Eslami [ navid at redhat dot com ] */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include /* XXX from resrules.c */ int store_childtype(resource_child_t ** childp, char *name, int start, int stop, int forbid, int flags); int _res_op(xmlNode ** xpp, xmlNode * rmp, resource_node_t ** tree, resource_t * first, char *type); static inline int _res_op_internal(xmlNode ** xpp, xmlNode * rmp, resource_node_t ** tree, resource_t * first, char *type, resource_node_t * node); /* XXX from reslist.c */ void *act_dup(resource_act_t * acts); /** Fold a resource into an XML node. @param xpp XML node pp @param rmp resources block pp @param node Resource tree node we're dealing with @param op Operation to perform (stop/start/etc.) @param depth OCF Check level/depth @return Return value of script. @see build_env */ static int res_do_flatten(xmlNode ** xpp, xmlNode * rmp, resource_node_t * node, const char *arg, int depth) { xmlNode *n, *r; resource_attr_t *ra; resource_t *res = node->rn_resource; char *val; char buf[256]; int x, y; n = xmlNewNode(NULL, (xmlChar *) node->rn_resource->r_rule->rr_type); xmlSetProp(n, (xmlChar *) "rgmanager-meta-agent", (xmlChar *) basename(node->rn_resource->r_rule->rr_agent)); /* Multiple-instance resources must be decomposed into separate resources */ if (node->rn_resource->r_refs > 1) { snprintf(buf, sizeof(buf), "%s_%d", primary_attr_value(node->rn_resource), node->rn_resource->r_incarnations); ++node->rn_resource->r_incarnations; } else { snprintf(buf, sizeof(buf), "%s", primary_attr_value(node->rn_resource)); } for (x = 0; node->rn_resource->r_attrs && node->rn_resource->r_attrs[x].ra_name; x++) { ra = &node->rn_resource->r_attrs[x]; if (ra->ra_flags & RA_PRIMARY) { xmlSetProp(n, (xmlChar *) ra->ra_name, (xmlChar *) buf); } else { val = attr_value(node, res->r_attrs[x].ra_name); if (!val) continue; for (y = 0; res->r_rule->rr_attrs[y].ra_name; y++) { if (strcmp(ra->ra_name, res->r_rule->rr_attrs[y].ra_name)) continue; if (!res->r_rule->rr_attrs[y].ra_value || strcmp(val, res->r_rule->rr_attrs[y].ra_value)) xmlSetProp(n, (xmlChar *) ra->ra_name, (xmlChar *) val); } } } if (!*xpp) { /* Add top-level container */ *xpp = n; } else { if (!rmp) { xmlAddChild(*xpp, n); } else { r = xmlNewNode(NULL, (xmlChar *) node->rn_resource->r_rule->rr_type); xmlSetProp(r, (xmlChar *) "ref", (xmlChar *) primary_attr_value(node->rn_resource)); xmlAddChild(rmp, n); xmlAddChild(*xpp, r); } } return 0; } static inline void assign_restart_policy(resource_t * curres, resource_node_t * parent, resource_node_t * node, char *base) { char *val; int max_restarts = 0; time_t restart_expire_time = 0; char tok[1024]; if (!curres || !node) return; if (parent && !(node->rn_flags & RF_INDEPENDENT)) return; if (node->rn_flags & RF_INDEPENDENT) { /* per-resource-node failures / expire times */ snprintf(tok, sizeof(tok), "%s/@__max_restarts", base); if (conf_get(tok, &val) == 0) { max_restarts = atoi(val); if (max_restarts <= 0) max_restarts = 0; free(val); } snprintf(tok, sizeof(tok), "%s/@__restart_expire_time", base); if (conf_get(tok, &val) == 0) { restart_expire_time = (time_t) expand_time(val); if ((int64_t) restart_expire_time <= 0) restart_expire_time = 0; free(val); } //if (restart_expire_time == 0 || max_restarts == 0) return; //goto out_assign; } val = (char *)res_attr_value(curres, "max_restarts"); if (!val) return; max_restarts = atoi(val); if (max_restarts <= 0) return; val = res_attr_value(curres, "restart_expire_time"); if (val) { restart_expire_time = (time_t) expand_time(val); if ((int64_t) restart_expire_time < 0) return; } //out_assign: return; } static inline int do_load_resource(char *base, resource_rule_t * rule, resource_node_t ** tree, resource_t ** reslist, resource_node_t * parent, resource_node_t ** newnode) { char tok[512]; char *ref; resource_node_t *node; resource_t *curres; time_t failure_expire = 0; int max_failures = 0; snprintf(tok, sizeof(tok), "%s/@ref", base); if (conf_get(tok, &ref) != 0) { /* There wasn't an existing resource. See if there is one defined inline */ curres = load_resource(rule, base); if (!curres) { /* No ref and no new one inline == no more of the selected type */ return 1; } if (store_resource(reslist, curres) != 0) { fprintf(stderr, "Error storing %s resource\n", curres->r_rule->rr_type); destroy_resource(curres); return -1; } curres->r_flags = RF_INLINE; } else { curres = find_resource_by_ref(reslist, rule->rr_type, ref); if (!curres) { fprintf(stderr, "Error: Reference to nonexistent " "resource %s (type %s)\n", ref, rule->rr_type); free(ref); return -1; } if (curres->r_flags & RF_INLINE) { fprintf(stderr, "Error: Reference to inlined " "resource %s (type %s) is illegal\n", ref, rule->rr_type); free(ref); return -1; } free(ref); } /* Load it if its max refs hasn't been exceeded */ if (rule->rr_maxrefs && (curres->r_refs >= rule->rr_maxrefs)) { fprintf(stderr, "Warning: Max references exceeded for resource" " %s (type %s)\n", curres->r_attrs[0].ra_name, rule->rr_type); return -1; } node = malloc(sizeof(*node)); if (!node) return -1; memset(node, 0, sizeof(*node)); //printf("New resource tree node: %s:%s \n", curres->r_rule->rr_type,curres->r_attrs->ra_value); node->rn_child = NULL; node->rn_parent = parent; node->rn_resource = curres; node->rn_state = RES_STOPPED; node->rn_flags = 0; node->rn_actions = (resource_act_t *) act_dup(curres->r_actions); if (parent) { /* Independent subtree / non-critical for top-level is * not useful and can interfere with restart thresholds for * non critical resources */ snprintf(tok, sizeof(tok), "%s/@__independent_subtree", base); if (conf_get(tok, &ref) == 0) { if (atoi(ref) == 1 || strcasecmp(ref, "yes") == 0) node->rn_flags |= RF_INDEPENDENT; if (atoi(ref) == 2 || strcasecmp(ref, "non-critical") == 0) { curres->r_flags |= RF_NON_CRITICAL; } free(ref); } } snprintf(tok, sizeof(tok), "%s/@__enforce_timeouts", base); if (conf_get(tok, &ref) == 0) { if (atoi(ref) > 0 || strcasecmp(ref, "yes") == 0) node->rn_flags |= RF_ENFORCE_TIMEOUTS; free(ref); } /* per-resource-node failures / expire times */ snprintf(tok, sizeof(tok), "%s/@__max_failures", base); if (conf_get(tok, &ref) == 0) { max_failures = atoi(ref); if (max_failures < 0) max_failures = 0; free(ref); } snprintf(tok, sizeof(tok), "%s/@__failure_expire_time", base); if (conf_get(tok, &ref) == 0) { failure_expire = (time_t) expand_time(ref); if ((int64_t) failure_expire < 0) failure_expire = 0; free(ref); } if (max_failures && failure_expire) { /* node->rn_failure_counter = restart_init(failure_expire, max_failures); */ } curres->r_refs++; if (curres->r_refs > 1 && (curres->r_flags & RF_NON_CRITICAL)) { res_build_name(tok, sizeof(tok), curres); fprintf(stderr, "Non-critical flag for %s is being cleared due to multiple references.\n", tok); curres->r_flags &= ~RF_NON_CRITICAL; } if (curres->r_flags & RF_NON_CRITICAL) { /* Independent subtree is implied if a * resource is non-critical */ node->rn_flags |= RF_NON_CRITICAL | RF_INDEPENDENT; } assign_restart_policy(curres, parent, node, base); *newnode = node; list_insert(tree, node); return 0; } /** Build the resource tree. If a new resource is defined inline, add it to the resource list. All rules, however, must have already been read in. @param tree Tree to modify/insert on to @param parent Parent node, if one exists. @param rule Rule surrounding the new node @param rulelist List of all rules allowed in the tree. @param reslist List of all currently defined resources @param base Base CCS path. @see destroy_resource_tree */ #define RFL_FOUND 0x1 #define RFL_FORBID 0x2 static int build_tree(resource_node_t ** tree, resource_node_t * parent, resource_rule_t * rule, resource_rule_t ** rulelist, resource_t ** reslist, char *base) { char tok[512]; resource_rule_t *childrule; resource_node_t *node; char *ref; char *tmp; int ccount = 0, x = 0, y = 0, flags = 0; //printf("DESCEND: %s / %s\n", rule?rule->rr_type:"(none)", base); /* Pass 1: typed / defined children */ for (y = 0; rule && rule->rr_childtypes && rule->rr_childtypes[y].rc_name; y++) { flags = 0; list_for(rulelist, childrule, x) { if (strcmp(rule->rr_childtypes[y].rc_name, childrule->rr_type)) continue; flags |= RFL_FOUND; if (rule->rr_childtypes[y].rc_forbid) flags |= RFL_FORBID; break; } if (flags & RFL_FORBID) /* Allow all *but* forbidden */ continue; if (!(flags & RFL_FOUND)) /* Not found? Wait for pass 2 */ continue; //printf("looking for %s %s @ %s\n", //rule->rr_childtypes[y].rc_name, //childrule->rr_type, base); for (x = 1;; x++) { /* Search for base/type[x]/@ref - reference an existing resource */ snprintf(tok, sizeof(tok), "%s/%s[%d]", base, childrule->rr_type, x); flags = 1; switch (do_load_resource(tok, childrule, tree, reslist, parent, &node)) { case -1: continue; case 1: /* 1 == no more */ //printf("No resource found @ %s\n", tok); flags = 0; break; case 0: break; } if (!flags) break; /* Got a child :: bump count */ snprintf(tok, sizeof(tok), "%s/%s[%d]", base, childrule->rr_type, x); /* Kaboom */ build_tree(&node->rn_child, node, childrule, rulelist, reslist, tok); } } /* Pass 2: untyped children */ for (ccount = 1;; ccount++) { snprintf(tok, sizeof(tok), "%s/child::*[%d]", base, ccount); if (conf_get(tok, &ref) != 0) { /* End of the line. */ //printf("End of the line: %s\n", tok); break; } tmp = strchr(ref, '='); if (tmp) { *tmp = 0; } else { /* no = sign... bad */ free(ref); continue; } /* Find the resource rule */ flags = 0; list_for(rulelist, childrule, x) { if (!strcasecmp(childrule->rr_type, ref)) { /* Ok, matching rule found */ flags = 1; break; } } /* No resource rule matching the child? Press on... */ if (!flags) { free(ref); continue; } flags = 0; /* Don't descend on anything we should have already picked up on in the above loop */ for (y = 0; rule && rule->rr_childtypes && rule->rr_childtypes[y].rc_name; y++) { /* SKIP defined child types of any type */ if (strcmp(rule->rr_childtypes[y].rc_name, ref)) continue; if (rule->rr_childtypes[y].rc_flags == 0) { /* 2 = defined as a real child */ flags = 2; break; } flags = 1; break; } free(ref); if (flags == 2) continue; x = 1; switch (do_load_resource(tok, childrule, tree, reslist, parent, &node)) { case -1: continue; case 1: /* no more found */ x = 0; fprintf(stderr, "No resource found @ %s\n", tok); break; case 0: /* another is found */ break; } if (!x) /* no more found */ break; /* childrule = rule set of this child at this point */ /* tok = set above; if we got this far, we're all set */ /* Kaboom */ build_tree(&node->rn_child, node, childrule, rulelist, reslist, tok); } //printf("ASCEND: %s / %s\n", rule?rule->rr_type:"(none)", base); return 0; } /** Set up to call build_tree. Hides the nastiness from the user. @param tree Tree pointer. Should start as a pointer to NULL. @param rulelist List of all rules allowed @param reslist List of all currently defined resources @return 0 @see build_tree destroy_resource_tree */ int build_resource_tree(resource_node_t ** tree, resource_rule_t ** rulelist, resource_t ** reslist) { resource_node_t *root = NULL; char tok[512]; snprintf(tok, sizeof(tok), "%s", RESOURCE_TREE_ROOT); /* Find and build the list of root nodes */ build_tree(&root, NULL, NULL /*curr */ , rulelist, reslist, tok); if (root) *tree = root; return 0; } /** Deconstruct a resource tree. @param tree Tree to obliterate. @see build_resource_tree */ void destroy_resource_tree(resource_node_t ** tree) { resource_node_t *node; while ((node = *tree)) { if ((*tree)->rn_child) destroy_resource_tree(&(*tree)->rn_child); list_remove(tree, node); if (node->rn_actions) { free(node->rn_actions); } free(node); } } static inline int _do_child_levels(xmlNode ** xpp, xmlNode * rmp, resource_node_t ** tree, resource_t * first) { resource_node_t *node = *tree; resource_t *res = node->rn_resource; resource_rule_t *rule = res->r_rule; int l, lev, x, rv = 0; for (l = 1; l <= RESOURCE_MAX_LEVELS; l++) { for (x = 0; rule->rr_childtypes && rule->rr_childtypes[x].rc_name; x++) { lev = rule->rr_childtypes[x].rc_startlevel; if (!lev || lev != l) continue; /* Do op on all children at our level */ rv |= _res_op(xpp, rmp, &node->rn_child, first, rule->rr_childtypes[x].rc_name); if (rv & SFL_FAILURE) return rv; } if (rv != 0) return rv; } return rv; } static inline int _xx_child_internal(xmlNode ** xpp, xmlNode * rmp, resource_node_t * node, resource_t * first, resource_node_t * child) { int x; resource_rule_t *rule = node->rn_resource->r_rule; for (x = 0; rule->rr_childtypes && rule->rr_childtypes[x].rc_name; x++) { if (!strcmp(child->rn_resource->r_rule->rr_type, rule->rr_childtypes[x].rc_name)) { if (rule->rr_childtypes[x].rc_startlevel || rule->rr_childtypes[x].rc_stoplevel) { return 0; } } } return _res_op_internal(xpp, rmp, &child, first, child->rn_resource->r_rule->rr_type, child); } static inline int _do_child_default_level(xmlNode ** xpp, xmlNode * rmp, resource_node_t ** tree, resource_t * first) { resource_node_t *node = *tree, *child; int y, rv = 0; list_for(&node->rn_child, child, y) { rv |= _xx_child_internal(xpp, rmp, node, first, child); if (rv & SFL_FAILURE) return rv; } return rv; } /** Nasty codependent function. Perform an operation by numerical level at some point in the tree. This allows indirectly-dependent resources (such as IP addresses and user scripts) to have ordering without requiring a direct dependency. @param tree Resource tree to search/perform operations on @param first Resource we're looking to perform the operation on, if one exists. @param ret Unused, but will be used to store status information such as resources consumed, etc, in the future. @param op Operation to perform if either first is found, or no first is declared (in which case, all nodes in the subtree). @see _res_op res_exec */ static int _res_op_by_level(xmlNode ** xpp, xmlNode * rmp, resource_node_t ** tree, resource_t * first) { resource_node_t *node = *tree; resource_t *res = node->rn_resource; resource_rule_t *rule = res->r_rule; int rv = 0; if (!rule->rr_childtypes) return _res_op(xpp, rmp, &node->rn_child, first, NULL); rv |= _do_child_levels(xpp, rmp, tree, first); if (rv & SFL_FAILURE) return rv; /* default level after specified ones */ rv |= _do_child_default_level(xpp, rmp, tree, first); return rv; } /** Nasty codependent function. Perform an operation by type for all siblings at some point in the tree. This allows indirectly-dependent resources (such as IP addresses and user scripts) to have ordering without requiring a direct dependency. @param tree Resource tree to search/perform operations on @param first Resource we're looking to perform the operation on, if one exists. @param type Type to look for. @see _res_op_by_level res_exec */ static inline int _res_op_internal(xmlNode ** xpp, xmlNode * rmp, resource_node_t __attribute__ ((unused)) ** tree, resource_t * first, char *type, resource_node_t * node) { int rv = 0, me; /* Restore default operation. */ /* If we're starting by type, do that funky thing. */ if (type && strlen(type) && strcmp(node->rn_resource->r_rule->rr_type, type)) return 0; /* If the resource is found, all nodes in the subtree must have the operation performed as well. */ me = !first || (node->rn_resource == first); /* Start starts before children */ if (me) { rv = res_do_flatten(xpp, rmp, node, NULL, 0); } if (node->rn_child) { rv |= _res_op_by_level(xpp, rmp, &node, me ? NULL : first); } return rv; } /** Nasty codependent function. Perform an operation by type for all siblings at some point in the tree. This allows indirectly-dependent resources (such as IP addresses and user scripts) to have ordering without requiring a direct dependency. @param tree Resource tree to search/perform operations on @param first Resource we're looking to perform the operation on, if one exists. @param type Type to look for. @see _res_op_by_level res_exec */ int _res_op(xmlNode ** xpp, xmlNode * rmp, resource_node_t ** tree, resource_t * first, char *type) { resource_node_t *node; int count = 0, rv = 0; list_for(tree, node, count) { rv |= _res_op_internal(xpp, rmp, tree, first, type, node); if (rv & SFL_FAILURE) return rv; } return rv; } /** Flatten resources for a service and return the pointer to it. @param tree Tree to search for our resource. @param res Resource to start/stop @param ret Unused */ int res_flatten(xmlNode ** xpp, xmlNode * rmp, resource_node_t ** tree, resource_t * res) { return _res_op(xpp, rmp, tree, res, NULL); } pacemaker-master/extra/rgmanager/tests/000077500000000000000000000000001217637305600205415ustar00rootroot00000000000000pacemaker-master/extra/rgmanager/tests/test1.conf000066400000000000000000000021461217637305600224530ustar00rootroot00000000000000

The following Pacemaker documentation was generated from the upstream sources

  • Version: $version
    "; foreach (glob("build-$version.txt") as $filename) { readfile($filename); } echo "
      "; foreach (glob("$base/*/Pacemaker/$version") as $item) { $lang = basename(dirname(dirname($item))); $books = array(); foreach (glob("$base/$lang/Pacemaker/$version/pdf/*") as $filename) { $books[] = basename($filename); } foreach ($books as $b) { echo "
    • ".str_replace("_", " ", $b)." ($lang)"; foreach (glob("$base/$lang/Pacemaker/$version/epub/$b/*.epub") as $filename) { echo " [epub]"; } foreach (glob("$base/$lang/Pacemaker/$version/pdf/$b/*.pdf") as $filename) { echo " [pdf]"; } foreach (glob("$base/$lang/Pacemaker/$version/html/$b/index.html") as $filename) { echo " [html]"; } foreach (glob("$base/$lang/Pacemaker/$version/html-single/$b/index.html") as $filename) { echo " [html-single]"; } foreach (glob("$base/$lang/Pacemaker/$version/txt/$b/*.txt") as $filename) { echo " [txt]"; } } echo "

    • "; } echo "
    "; } $docs = array(); foreach (glob("*.html") as $file) { $fields = explode(".", $file, -1); $docs[] = implode(".", $fields); } foreach (glob("*.pdf") as $file) { $fields = explode(".", $file, -1); $docs[] = implode(".", $fields); } echo "
      "; foreach(array_unique($docs) as $doc) { echo "
    • $doc"; foreach (glob("$doc.pdf") as $filename) { echo " [pdf]"; } foreach (glob("$doc.html") as $filename) { echo " [html]"; } foreach (glob("$doc.txt") as $filename) { echo " [txt]"; } echo "
    • "; } foreach(get_versions(".") as $v) { docs_for_version(".", $v); } echo "
    "; ?>

    You can find additional documentation and details about the Pacemaker project at http://www.clusterlabs.org.

  • -Czj:I\+]tlƎ}v/X6j~rdiwOOwA-i뱾r~[A:\#CC䯟˶3XW6@FX`k5@`}]wu{~tr&sLǜaf sUlOiRoS UXTfXnMyv]w_;ܨ=^i6ҜJLpj{]YytWn!8Õʼn߫ /ty$i7>T46rgxzǻJ,ym%>+wOCnKOgilw®SDRz27fnm&`tI] FFh)b{0 X!b > Mz${};BA[Q?Jy*m.peBb?cf*D3g4C@?oq=꽺\XznlӃ[&$ݯ`aJH{9q%g/؀ړ-S9a^ea ComwOYR` dJV= 쾙kg^*`#ېH̙3<`P]B8c͢Mږ<slg!/f}"p]O|ДAشI{=*Ϥz.h{v\wSuHLY;񃕰NoqVFuڔ WZ20Pw9:VYz2RR:x.:Q 9Q V_po8_+kĦ?Q*"6,aPPE{X=g* p#y^H 6ÇNH+@bKM[ Ϻ9=[+vzT 'AK]S >̐l,#}FU'ވz7grCҨLҢQB}7w2xkG}Y%׌7 #~$P_:HL& _]Ue2@n[Ӗއ&n&+Q[-/w88O?xH6>ind8ЍQ%>1<*{ٻ ۦc`y}ӹSjcMՍw '{.l+w1rݫ[ ٧c39*O.מl.Z}39x.ێO8ß+?=Wou`z?YW[]53Mrm抁nwyLC4D}ӏ|THF×|;O?nX|#_N$YHRK7}dr)zoO,U[6~SjsHn8@ȣxM!_Uٮ Nv49fN\t`qtr-w BG(䴒|LSE3vN`_S"kڀ~j;)Wz+ tW6d_#>ߡJrǃ]>N_lGnWYGqF4GƞnӧV_Qiї(Ws' .)[ Yppe"N9~脋W-n on3@ȑ N[zAZu7ޓ};p/F_@/ !q׮6 wQ\JU_5/e =Vñ>A#ʮzOgIIx"s_axm4SuL)Y-NWN5R_I^V\^9ǔWi4C4c]ךЍ9h<@BQpP0TuAx')>)aօKjl3\u]Ͻ[GY`?IfBȠ}̣n(wNݼ^T= \;~ЦRCl?qb#9:s&}x}y^ބyXJ۷o7+h"Q~{$7$ܷ XOO=ZAPzbƈΔJOs5V_"pRh#q]?5{/7hvxlޗX:nڼC__n#9 vοq@ˍ:26mӑ]xm/l#uT݇32=a}4Mg}Tܣo;T7${#S &d |UtzgX/ 'rGʏ3Jpv*[6Õ>vfnlr[nTk19M%c9#oe8q1r&9n'A}[Ϧv,G{Yv=u9׺_vo 0dJHJAH R P"!2 4 ANl2cMNKS}r; f9>kkm}Wxx'jjKte$ ҭ6۞_η>֖fD+8\q \1>2GҀgЖN|yL eq-Jn♫/>|_p=g:#.wto6,r͗f73y4'e?\: z]g;?,v4#Εg#:I&G=S&MLgTxftS9c]wv #` 2»G7gNޱ3Ñal,QLm{ؔ9U?yS5 94nQ2"X=J`gS/Vhh5f^) ]rD8aMDsk+;-0]oƳ&m9smWp2)@,oNӛW)i=Ar9t2ֶ)0,3mPD29d*K(7}W#d>cfF ʕ; d3ttIm ҍQ(ԇkdDԣs<ݛ3sKq+(uydѺjj=/3JOTNp]gGX9`eYÓAK6O `MQL .`پ+=9~lIe@+޻'*[ 'ǥҎ7w ~zGsJ"8z"=zª0~u l}ƀ]Ms"}~)>o/-L2 8q"''[}fҲOLg(ۄ]snCaQԘp{9w)3z2TGjޭf`Q03K/ڽy tqT麝7mj:?| ںጄCè#f2U:K9Έ] } 3GbAW.VFj87.pb@V/<.̠i CVAik:|#3.SH4w9VkUf1}:l&ƾQط9_0p g#,'^6gT_6N|;q$ ~kp?,7ñMy@&ӆ/or5G[P7`/_#W98|M!X?SZw$Ĝc({nHsikmɽjN餛%*,m jYpRo]GЃ;X.qP`JWYBA({θS.lMYYF@'D:qN LR~)KQ 'veA1IA4R9+džN/ nY-{񙦠aV,+ifNnyCl3Ec:G޻e0m}qi G<;xI1st,_8'۔O}lBE<5']mgfcA')0􄂻N* (էuo9f^|Mw{F`Wy#w7zXd_~G weѨ/ġGq8mSRCwM,*vq:_hW:lxģT9de~/dKr)tTTlHvv֥͉'eL;9c7#UR4|N j͐#hꟘecP{@y*|#}t0z_Y+;kOc ^WFQ=Z6mVs/lr3#L\xoP[ݙw _jA1OQx%ibT6Y]pٞf}ؾ"7 rԟ =@Z.uWp"I !Ǚ'dkOqrl׺OȮ\fөj(|~%PP!]g<{,}  H&Vlځ bO݅(: gƫB4[v__^W UZsa-0owNPVqFڭ_\\fw/^rɡVCNqCqi,'l{\MrF=.n*I<~^Hrď#F?HO4R?'qC`Q"sBQ"z~ࡄQypk` vJczaz2?e0R{|k0>ȡLµ`q>h"Zwj 1G:WϦͼB/&5NS]d/Yzl߃̤'bpl=ht0`kLoJYJ|YU^8Yq f?h.a}8Oʌ9}zāGā:9:hEAy GAO,2*yΎ>}"HS9Iz|܋s1=~cJ#Z!c@A흲 r W3!'гJ_kꤾVCLJxu^vKk*<kaPUwʜ>?Kx R%é< ;|_p':|@6~9g&cWsiY P}#faÊ[=vR7 ^Dh n0_kjH[}.z1ămtJG|%pZk >=9Ыg>V"FqۋfKD*itQS_Q8 =. S2#Mt2,9?f߽#1/ ӍA&M'~uӄs}%#CmҲl0Io:16ՅG0lmD{pov5s0lcKg╲cҨTSdOtaNȪBk'\)q;|#O0@99*GM`~&_׹n+ 1^Hc/x0FMt 7my_߳1!w25%G;)BnGq~p`z/}(F^6[FQL~OV1y/ qLtehJQCd݈G3 ,^noŽ6S8E顯1&RoG?F|xm j+S/R .@G{[Fʳ8w 811Sp^ZnjCmR#t%HVG۷d4PjրU&~ LA-aX5ˈ1eݳc9nDF5ag(áA5X UggqT|{A8.wdz2{oW;G=f"T.Y_~\h㮡noM1_E]8߯QU"{rH ~KnJ~d!R(~x9,Y :~7~Oך}AIgiϳ-ixAӱn#Y4qݹ^9泯3'isѝëBkm$S`x7',8\ 7#f43z=u}F,r9Ȩ1}e( '`{Rp?xstvc46kKGL?[7.os/}8:3 s~ F]NKe"'gvП1w;XpT8i@o.R1/k|}x ?|JkԩٙMoi"cMB33K)҇n-r+[2\ϱkA/y 0n ǃɯ,AwFV߽Y5d.>4`M|F2&&fM=M؍^G!^Wا e [&@ Q29u^>΍7C؏~s y RG{ `jO}WڋLf} X[ߚ[T,Eь;3brI6h<"QGݳ_z[MzZC-}T#Ѳ=|:`֑Wdjt??Ne]fk?vS3Z~4{rB焇U?-ٳ ʯl9kCӫ-Z`J --1bigN <_8:qw NEFoG^q |jO4+Ka֖_O prѝn|^Mma}rJ08gfwk;fipW*WZFFi=+p~AI~ GIR19>:Xi"a̙8; /x_LX\A<;`_\^}({nҨ`HqabQg_N9_F؜J?(x.(lQc{O,q{ץܣJ3ςq+P5j^I>bPS{*{f898p+=\t͙VO4S6g*XX0!c=0?}GnC@<^Mk]8T8DAzc^_7=99Ky͌M9RjL 1cUIt<_;>NƑfJx:edD/xP>G>9 ZQGNӝg; Ye8xdA3&{RFsp8͟1Lq4GcicĈX8l.xӨp"H_~ߩ'"|}f8eeH16(c_d$^è>u4BL _9p쒊s7HJ?y]ɞdq1*?΋gA:׾ (qyfQL crY?9&sj?\azmCXXH߿Sk9QL+Y>G=~xv\4 a6`+ޛ>ٽQ@9t<~}s!']se@ n;­r:\^AΨ}lz#.3h8{n=ok2R+pn}ty1N^VmE O.x%90g: >5Y){eG~uYn'vLQJwk?9U&:QBG`rv{ɲ6 ІHG_} i\h&P9o5ଡ଼uOd &k#7O Ypx-3.3nHw?=.;1>߬`OE}2Oc ZS{ xP2PIb _>!7@U=*`/1w~hxa3YW`æ(JPX"ѐcdPEvG~ 2 8p@w+W`4[橘~g<"],b10t׌2-C>$2 IֲnOۍZ7iPԼg cZUpj~WaJg<}IZg;G{/{DޔI<:s7ݷ VFop 1kꋑZ6.{i%m];`U?M! ]3lܸpugۦG'/)#]jg=ͣGxā?~eR@pAftԱS~U9֒>"]،:{=gnqS?!G{F@>/;CN۬osܳN ?]y6zsXǎg3 p6U`,1l =xfl=:C+#1#3ŽF"(c8]ϞibAQ3W!9EeOY1JEJXὑύ6Ib-1힞<~}2c0eUKFxgmvle1!,V]8s2Xqv6˰u8|>V>NL} F<Ι_~hz1aHr81,N.A(4luݧki`exp&Zѿ${?cUi1ÇH%#2u T-Q 篞޺+*ḣ<+~3-76M\CZCͱkD|"F$f.̡(foz> 4fGuG,27YM$6l<+U#X!Oxqk^5Jٹwr*ר0̬(={>нZGjC1Pzr,oDQl1ww[;R^BnfK|%!^ʫߣ n޻,o+:Ri~2rdS2]a>rv,Ϋ=Qe27AvpH=;lЉVuű_S c7erhQ9*Pdz1gZ>lFNio|{߯\/v{i)KGcqϨ{R CZN3ZCxF:xGWeC?Wy4Q>'7aԖ_'-;d/t1ɦ{yeû𙃍_]ьc#ubʉ3ĨSS/靷,o˔GKy>p g@*5+w@ujs逐Yg+W{ȳ>2,晖Ps[`ɂ@x֗jj. l6?4Fq 뮞[cWX=?1x.p^jo&|ֵ(&F3E@cYd{xHɎ'ݜ]sOx:I/!|> We]oU7{XWC2g@%J kۤB՗wGJ(m8t])cxީ"[^^)p_me#Bp ԡܮ[$|Q_gZ>4=I}Vs ,Oش7bʣpB=V')1O:^ٕyxt=F\#b*F]fxN'-O\~ xSM3 @v( \r˩~]$fVɁZ8<o 5ٳ^H7u{?㬠mv^ez@i20g*WC8+$ׇGBVu=l==)n6c(/Q( Q }0-Weqg3+WF?]6Ѳ3ܔ!5'oiG5\Z?T3h8d;w< `ƃhd4 k˨8~QN]x/:f>ai9 {;ǒ&o<fAl3?\!~@0Ӟ;vG7U{ჷ$~-ũ[oM.*W fpD [OH4*l<% \:~o2#0Ww(~_ʘiX \hP'sɡrbKAT'$>1c|Z 7q!S:>\;@v;pIs1%b4؜8h3 H+[.׽MU<_d5 ]p;tT*y2Fk%jp#݈ Thip@suV qշ]d8.3!b<Ƴk8{G S W#\ ,nh~[sVy o$[q\.]=TFE'f>Kn8Q2tz𧰉 Yty僇聟 Xۄ!sen}T~Kwڄ|ə7[+a` Ȁ= Ut 8\چƻN[ O8KdvzvlT@KEwKk*)zqkOuf$G*]8%w8_0{$R#0vUt@{$m`Y9Gc'dP]@Z_1B&GEl:ȼe6<}W~GW%JWI㠏 5)Z{oz޿O {@f|^)?p?Ӱr?FyƃtECX0zg7+<$D ?A(ڌ {6eQ  }#!5KdSz|M t@3\gjӍ?"m[P9LGGgxg7BY]yte=+)CJOc.P`ǟz&]>Zd}fˌs:y'H[YE}ϨзLs&2rCçxݽ$SfXve69Tcǻ֝^G3rBapͩ,ǏW@׹Y %\i;9y,4gh3}i z=3b:,@>)d[}kmԡ7 ұtz>V Ӂh?|~T(/v㣶}\(/j/^[-.2h%X;^K;$VGaj {_of7M{c<;Csjɲ.dզ &% 7^L'mXvţh5 -ם n_*AGڿڠz vT3Y;c}AJq;mԿicwu5'7?Tuu{?xḀ%=t.rmHqK҂g[{ Z:G_ ^\͆G(OV'W zЋhDGiL¥΂kcp/9x [{pÃA1##(WeM Q"S+pρ7^9ꜱ Ҕt*;é0Rla$q5a=YcwpŪj .`w{*FTXyhz{#=;}1ߺon}Iy6eڈyz`ik 4zb@U/YRDtb IDAT1l\E\L3d8?US+#7SgTr3Fgӑ'+ (FNŎVjyr0;IǞ]`ih+~N0B8`A݌VxfVʆC}<瀒Oϊ Dsor ^'I;3+m(9-vryO8gi[J?nWYCy"#{Ό$ߍo_%%Lezpɾi@H#<}_7V*_]'M|K`A{g[?&C/?c#Y@< Y.][l<AKA򕎃/fP9;#9n[^sM3N.8J0+>hA]mI];tpŷ{x4UOMx{e+@mG\27~5BijULbSרN ]#8@qRWq4 d[]=',֙]}$`Ҝp(KH~p7JJ(_2:FQ>x[Oوed~;+4Ǜ~gk"zGЙrү:ѠeUeYo>_YRg x\8FWg_4۽r0M"L f4W& &.j`6ANZËO`+׳my[w?Qzi9~N[o3O~og[n??'3Lտg}q9_3/7TWܤ;Q >AޒAM')W:utJyLe@2XCI,ަ{o^Ͱ{,)fnS*өY gz6]NL̠9i9ݦ7rڷ3/}N}ifłK_] CulX#wrLiW*Ywѵ3r1bb2=PXp񦟉u6B[?9Y7LB.c{Wx'>bхT\s]3: ^=eSy^w[LX9!UV(7,N/(..';;8ϩ5[w=Юp{I t0@$t͑<>&`ty:p:xΈ_]L`]7e .Cv1P^-~}=|}XG:dMNc$' ukwOo X#."}05Sh3v<3EUӍ[|Ma 3:Tg6Q <UaDWAAkOL kdn!ݿsU -k)#Vy 1>J4,yk;nM''0=Ӫ]mV?Rw/iR7hx!.MPoɒ%E?>{;;O& }\ 1HS'%(֟܂*ڡTھ2xgۓgws Ydr \|o9`yO{h@=p;]x{r#L-~ϖW`JwMv|̙- 'o#Ou`C>3-:O>5AՏ s1 'b~pn2PUiŗK4l۳zh,y;)"^ޭƞ7e_9>3b˫/ӤWfx'Aצ+8:Ahb>U3@pw\m2n aW+tc07%G" qIIsZ++v37ƂkvvK3iwt 3S峹ݥ"_dẺ&4J< sNwBŨF#F~S Wo.?kMW2i3M/=|'4,EIa}b=ne`8Qy:I~r܎#ugo:eV%axB xf|2qAѤ2L3_xtůAh2.:0sxvqA^OW^N_g^?zoxۧq:?N/ן~]w9}~r+寜>-p |3 {qKzKuCէg;g%ުߜp#ػ6OXkj':ӡڋ$Ev%C~ZiD`ն :hf:ރcD5=L įd(Hf=WM!L_^Ng^=sխ@R(>qP}06vҫǦ26u_-+@ѝirN &_:)FAH7#9P誐gQ YzyftFĘ0D-"@.ٗm C;Jf4c1 ]g?\Q0n4jOž*3fUT$}4]x!Dw-q-*|!xg-@P#1ə%0D \i$O(b-8;h%ʏ,\ : 'xП;(eux*QoǻEV/1<[?G9_{ޗO>YoWNE> Ŀv[~o9[Q@|?oq oE 3v@ oxʌש^{f##zc薔OS}QOx?goʈ>)}u\p]3CA{|ӿ=Q p S=غ tpìz"]F,k0oϖD/i?wY묟Y"s,v@p>Aش 2aFL/~43a]<6#~xl3{_6jp٦Cp3lƨ'( )z~Ե>B u]( 67Bس<gNo74xh23҇ `d*'o/\Ɏ)qʹbl$qjQx^FM}@9ucd!'X:uI{PkwMf6$]Gt Fo1 ZT5)%FM~/Vȋ>l-M@wMw%T0h`+㽌uxbGp8 lS=hGA3e7>; ֔bF>9Hx_{$tC^@@X qg>|@<=_5uـ?e=fŏ#8~r*u)YЖGD;d~@zXtb>(f<7 2)ot takGxǘ,1 GVԏWHFӵQxBlٞ3I*\K 6w2Th/Ë V+gK =hj\gќYYw.!^GPY"J9]¯\>*w8̑.:Er2Z<>x A"|8B/҅g`R,:*F|*rQr8w0hu]f)uM^~OI2 j3`>X2<,x/?9yNoߥt:/N?wsϝ/^{Mo߂|iG#<;l=]s 3>ktQ䐂RB'm|9#kH ]K=Ef>ZU:28:tSx@z/w2@9 `>{/J&g(҉`Y 9w7km)4+>0,HO4rgzKOEкHaQ_i=d0œ>^^:6zY s 3Ms:7#P^p8}Ҳ>^p 5:p9 cB/|cl9?*k}Őr۬wI+GmfA{&U%Y_ʑx=F R{k433.P@1)\J}NQOEuQb)k$FD^m4Czpqbr2p.o3c^;k߮7Nfdq(鯹yKN7tM(بEA=.dr.:(U~Cx>!E>(ϻ\`ۂF bTKgɴa<7;ɂ59zs5{8D Hc̛mlO<_wkN|r: FGsvShZq|>gAke6぀ovVyz\5*~zz5O 1ξ\SنNu@uAN<ڟ<_Lwg4[@I͐[`2x$dB[ڮL7z]օ gyߓWsN0t^ Ag}!z6 $!-])U<ǫc|}N| N & _^@@7?3ntvz+;ͻv$? q^ٱ} ɔ7VѴ~ h_e\^X)h8~eCTpǣm8 zSC0YA|QNJ|G?))BZF'LOfl$ݿyP|+SSK#oH[9U>|#FVVoc=Ζiy L4ȃMf4"_X\'o=1xy> rdfs_tڗ2fr#oy]}M˫5eKHյ }\G=pY Ҍw`Q$ 5:Y`E>\'M9YMq+;ϱ9`R+#5~ 9˛.,`!Ì!6뛎 $]:{f:z:;1n}7 b&9ś`Ff ƉsW펽2L<{~B>S `@#9hF혞w0FhG@鎩dven4 w|uB CVzo kz}OKVt2\7}>FNnƻR!`z{ vInW4h$3]Ec/ 1#Wda#5X>ɭi)d=0i/.F3׍tBc$nqP_W/٫hlf87΂*Wxܫ9f͜%o^FAQdžke8)fTL*Cnj\yZ*Z@2͔qCddsGs9xƛeB^iHcыmh}~U{þ:lj]>FJ`Ym:é;*ko6=[oą'r,)Hm;*ӯI"KV[KYSK IDATu?Ld_sz,yDLh).S6M͡{;P7^W*I53vnL%QfgL R~ظíߡwVՆǛNOmd>V2hO<5--xsD wBC\|w~Gߟg?zo_pe_kN-\ E96q[_όO"Dq6xoYt+:7}F鞡s7^PdOpzԚ&~dVm0&:ً͔K\12A'@Y]ՂSqs~+ \!9#k4݈c鼍d}t9MS9TҙL_pqèq3G4X̘9Go-J^csmsN挑L̀y_nL0xѿw/l1s01GmGdwյgk6_';=S)Pm`u*Ϧ{dX[O d Wuw)&D9ù2Vdzx)su}o{r>%uϰ V-ا 7Ipd# d!:w-i?6cE:]ۋ֒ 'Z]2ډ#ȟ ݿܛo)䢼xQ"~LdN8N (9vPpLgiF8pүaup f `'ʌa[Wv%ڿ}=fwChJ~:~?waK M4ZP:x7jM#; XpY_H@L+˒ܵRɱny돕|nL63- .* U(W3aV [C^_6Ug"(]05`N  1q%> n(8]I3hpg\^5bM^\rUF<\~ʗ?Z=;i[%]|d*8TȅWLa=\I }4 kl!e򣣴aQI[ቧGjW?ܬ {,)>OFx-OX94xķE}ongJ\ '̛+S4/px/}"ox9N.t52==\HW}f ݿww:Wٲ\@~!{T?g`d|~_s 5Yx b;Fm_?ٷ3%/哠p"/C_$~qoӍ-Ңa}k:\A礳-s,t67S (0tQ κ7|o v'f(u3`[ӫZF"38g6j9`?~AlD}tK?C:z蚩R0*@D'Pf+qY=ۈo/|{i9`*qD>Sa^X$FFO. Õw^ʂkd 2 /e?{w= F6\uV0=zMnR6q(/̗3sQ#]wI<8[_ Yc71ʨ#3v´znzɍ5$ÑduRQ[wqp*7;*>|c6+%ݧM olrSM\dvMM>˘/ALzwq$iW˷9gʵ Ҵ}Kw;"S g06Z~現u8Q{q:Cӧ8bI|Z؟݋/X%R? VL˘vCp|ł`Ȭ`hWJ(`j9۵kiz4:Tlv&*6& t-stDniD CܷUmZ9OX5[t2okϕ;y^&R7-IXVA S0ifsTd {2ڏw/t\I{tdž+rD f}Nzezweѕlo,#~ǚ>"# S7{ꦋ3翑McU!fMч *n$CQ[lݷ,(vU<*tVap{QcZhP}zWAɓpfAPZU5Q#?d5S/"z}ryeǍBfÇx#<KݪNw 6$^]3d=!}γNOV7?P}n5+daAͳq~'~bH`3]PO"pEnE_h-dNp+?=g/|ۿۗȽӟf.|۷}ۖ.؏XVm+._K8}h/7_f)|E~%NMO#\ {4_+q컾NW;K<{v@?C?ѳˍM};1Mt'>qM7{p4K>g|_Wo'BK?@cv4߼mfуzNp)@kE'ρH)eai6 pt7Ŷ`}*щ'rJ~|Lu C+хGE^JzSC+p2h)sR@H0kaq19r~,7uv|/˦{чPu1>OLJp:Ϯɖ&A0(]W>C41 O = 7g+O?+x(~[>M\LOzW81|&c*]K$˪-q{uz{v eI^EuF *E zZzֳznjY@zy}A'ZSZ:wP%+~ \mii[,Àe3P$"gF;;{p+xy ,RYЩtӑ?--`w .ݟ-=^rݟb.gpi18 C";#f3#D:mG+:gs8 AFy[ӴQIZ Y{׻ѯNo~O79?SۿO߻|(O]ߵ__0Yo,1[xg|g[;/ˀ|?^W{IW{ԉOnrtQְB_M?6qNh{|Y.UGg:nxY~nzVgm}rΞ+ft*1DvI?l*4KO+3P^ӑ/˥سM[zG ZSA#CSlց͍T1B&a?c0iFQvx_occ(oi7!u^$q/ss Hm8 uش8:PѷH_ %{F`bĈṕiFJ~My1ɍFPϯ U^QQu鰫҄5tV~IT 2 nTherN>srL>ӭ~!ߥg GCZYFe]1; O]i: `{w Of`%OsZbuF\{67Is &*zu! &>wyxڜNK>w;"Ov.`-vh^6Ufu @Ė?pzg!X= o՜ΐS[!nI֑+ <;V?]chpgJQGsܬRX6(9ѥM_|S& Vz_ɠz\FrUb}ŕT^#`KY"AQoOSdW` {7;2:_@=;o}*+? z?̘' HY,Ύ77G{| /6(}bwKu ^DGg6TʒpW]|*pZ%݃-y`ܑv9g yeGFeI̱'Ug{ʊ㹙!9ƿgyGSgyw瀿M!<~cWg+q^_6G=MU㫰|gu֪?g-oyӣ]owOO_s+N_~מ~omwVuP[~ows23|$Խ7Moz_?'er˿U?'^WYwwL7H7U*ׇݿ9/( IDAT$p>ᣑ举oӯݜ]Fy/4r?Gxe_e_[G0Z>hw'<` W>>nc{r^ǂt3URg$twڟs}蝰MoX=?0ݴΕ#l~Tzìν[*A1 g:ߪ_l$<ߌ*]9t'T/1}h$T*4X̩,ԟP%FtfS~FG/SXt8WlDK΢g ML0Jzt2L72qc.d.=!gQfXޖqk-n7R\le|v M4c+Pq2kw (O?'y9i`HSZwκ6i7]9aYzEQyPp3}S 762s _9| >!*”rS9-₌g91#qvL׾3jMY) _YϵYByGў >fJm#F5g ߬KnV7Ÿs5' OIՆCr=J,oGJNN[ljKig7_bg Sq=|G9>$pN쇛Pgggj8sOyQ$P [O^Z+*((bE07E=h@Ϯh}}ǎ1=xOīm6R֭mGOT?fr As08\db[v#;4QHdg[ʒZ뺞=?9=7tcڱڭ1;ew"VE|;qf#[}wtJ9? _U$qGh [v3a%JKGOƬK>Wp|z%^8ߝo&zJWhh0kBݮ H:嗷v=v+r<#spGGOpz˧G?ѲB&sw^3 7^h@3͒kb8s+_ .[\] *k 4{$CP!47 rCo(,ҬvPi>TT>sh6|[La:H T*m3=Sfg;޺ڕ1U8Er%M'48zòpeN0"0:RGLbH]Ƣ;C@sL'aʋAb,Zc:*/ATt 6QH}8$!nSKG;Qa5?  ;[e|nV>TޝeO~܈C `/9[UN[>oc4IB\gN_ t✚>jgP#S8__y2ݴp׷|˷雾i8ϿK:/8/d] ]f HR29.}gmJǻDͿ77ojQu"Y'䟜s^ i:,wbO&9L):X'>},>܏~jڻot?fB8CΏKGL̩?ޔDzfjN[_#p^3=yQ*ht/M骥J~'E鞩x%/O:1mt~SOll9hotro^HOG:.qo#7R(_3LkMW~v3PY̯_W(r3Gd4|r8Ex ~|w5|WNdlsv_jGK"vcx 9=sm]Pf v0TqG xhT5af XQ3}vwLjZNjx`>,a-F=ECy-#Fu|ƴ6%RT'4+\- ]  v;_bHT ..C]Á[@6pU,ŏG&T\`MbFWF:PN[&]"Ǜڈ`C3ҩ덆}G:FOo86`yBiJ,ٸ#aM;@o##gK&+74򸻍̂8s+ NdΝʹ KSsʨ>Ղa˒͙<6{)=?#zZ?@}^!H1*eA܎k6h c2Q8N1Gߣ_m;w? T'ʈGUh\@߳Yɡ qh͝o%꫓0r>-O1~zz!sKd樕x"}[H&Gozv>M -8-:ڔV;nNJ=l}"NO4(| CWwU.p%U7D" Ts9BؐzY1oMn-(JP @ G9_S.Уe|G 2b:G#oʌm)J:eKEĪLYeo4Wi3TL@Ir9 &sHʒޣߵhwQӻf_ ]3JWpQfTΦgeJ?񌒗/kx7B6 *#.A6`h <)(q_ƳFPӥ4W{u:[GKwO{S?OO4};G֖y%/u4_o{7UC迵e?gF___jʜ?hs?s,{|= ߯Fw??Xo;~tyW}Wm/K|kk&Ok᭑ٞѨ džj_L>O{o{AoV'>},>܏~jڻooo'"֋iH:^l"`H/A+e$}WzE}DkL'7 &}\~ O} ѵCuFt/'%758:|g4Dqm]9!KM=ex-\`˶a1b0I`J)+ ]M?(q /~ AN< T&=C)T~ÏzvNWZGv"4|0ՆVtqZ*n2xyw X7{^}q2|nplzꦬʹ]1%KܣFG#:1bѝlB#39Z|Ћ G쓭6wE<@J/rtypU>L[5eI=q.5iTN&4osLJSam|sUQpzÜ:"EGUwXr始X}VFLG4]Sœx]$Q;/Px3VzeD;bmd#1k=)dZSl޹"o2A@|gDz/ڴg03?w tFҠᦥh.A*w XgԨ7hǟ Ypt&E)p1H:IBtF /+1d~5#b6aߎchH JFDru,hM{oѤl#L>z~.\Țo|KΑ_*ڵ'T@ɨ,|9yc9>m+ rt^n?`ʹ5#ᆡr^:7 I: wNey:OOl-oR1:O6?M7Ӹh;OOm56`}~c] >C)_{'s9}<OO.+z׻)8W{Y/a}؏ئ;]|$lOγ{N78W hxқoo>toyߺpy|,h0_M>X΀xlWÿ~r^'_yfh12)?tۨgpKW)1,CN)#aAusne3$!03,2ჿNhy6k6> }Pɢw{#!G.q0f9e;f^mou?|nóO'|ǔ1~++Ǡگ,trNJdro#ǻ9ˈiJu5Q1{ꈱ R;D/MWht |j{ |A.y?MHTM.=ޠo!.KBku`yUS³və-`sD9 #vAosp\"rѣH֌)7 G6YR76@[x"gZ9S'pf< ]JLj6Xorpr(ٴF1s˰F}s9O> tL=Ԭ0Mg}Ps9fØPeXp1s,CMMFpADAYlzvR'oū'YqhJ ,T Z,6ǜCy)):=_Fk{ XG\aCCrh4lBg`n~NN/v|.2n}oe~O6D ɁWI=ol0}x`v4;ӟZwǟ$\ٹv/5C*C]!6teZ/wtTCo6s=wJ+wK ܩ_/VZP9^ڨa!z7o VGw|U3+ (AleFO_,p3Y@V)\U¡Ú1Qj@i}_LYhsts+EM˻<;*{ݭ~d ؑeh$c}v^\u3!̜YUjO)}ʍ·:~q1ye* nē5Zs*&Cp )-^*T#c̙{9O~ɍ<v?(b{T f1cO He|sQD⓵lWQFKgʏ/_O>yU-؆s4ܑCeF;cSG@9o֭xot|{"7@i.v7[ȻSlgi(B;g'9l6z5x߾((ӱ|+VΫd+Mk&Ђ%YtmnKPԻ cz~`#^s+`saz,hC)  37Txح«  ԯM2fHp4e(/P74u H3Mc $yrFd#?Tke{W% U@׹N6ޗ;^ ^/?g:Xː{34||Wn稫"Nd)'/?PxD7(6U|]}b_n:#Q$40-ل]? ;}?Ʒu~=}㧄[I: Mx?b5Txco;E=?MAc xupH_醷hn>X88t1߿)=ew6FӋ>ҧN_;O?Q+WvzgG/;t#?#p)/Cj89`Ȼ⿨l1`:U.xqHeP)O޳iӝ5^^ӽFfA{{y~f]3u /[Gݐ5WZ>F ?PPv关>)=؛8TՆAqOy 4uլr1)F`O 0@|XX6X CC>=>eY? О]  ˔+~+y]C+_3:΢eZv9y{z>HQ^NNr) d<\%HWqM(q<홞,re2Ʉ:Z='ghqUl.Û٬@Ep&L<c9.)8nĜG.9GԎQnxmcv#gmS&=64* Ѧ:FBu1kON7`e3|Iػ_`)a|NvpD_(lwj<@Ӧ_<>)쓧=)fZ)tù8㺴<֌f`xT-/ |'C?Ӈ"8p,}܇x?#9|LGOU"]̓E;0C~R`w˧qN׿&Lwnzoot}܋7N=kO4ׂ<)5͟tP,U1r?DQKMLektFOn=]zfө_*)7z.HiE:i{τì|c ws@+]?88e_73bemr,uяaEDR} {FB3GsK#t ay⑴5fvce_. M gȍWd̉lz|+ؑRE|^..SH+k3 ^ghYAPSaTެY 22$ANkŗ!QdLY~3mxcӵ sfGP&k3yAG3Tn7CPWhտ{Hzrr >.7{q8 3]˹y ގ_X4g} DNTsa9 ^2Gw98F>9P_ 8owszqAhk4+yWc/| 7pe^ ub2ϔUN*p`x'GLqLgC>l|[~MlInna)—J?:4k?'3ȵ8^Nx.F1v/mϞ9!+a4TƲncbt69ls 2(]WyxbV M.6'FlH˒"v7M? GA0]'_ )Ɯ?uV^y&7%/CeVICע:1M^[|(!Ln39~o|awd&N {-<^,6kۍ\[r#[}x,@#pjq1X=l6,/+Wx oT-TIA=q N)u|yݥ _kƃ).f,@wLjsz-ؾ ޅQȟk߮N}PyHotx5j O^+ Nd}3Iq>Y4X=x#+"ή./ܾ}nO}M9-G;DW닦%G!RڬƟxm o+<9 5d7r cHߦbQcZ}&9)F&dfmJ|5ʕKElJpJ`Vs@R*:ѫ!P N+(nÅ8ۍgh~铼0_`i8&l_x&Vah)`̽s/*P4E_O qxzƱ{EC[0azó3~sI-O e{WuL^)>VlAXx|z'@x8-ǻng#N}O/\|??~Oӧ|OO;}}?9?:}|Ύ(H$w"fێJl Qߕ;NuItU D>KhjejǔA \?l,]KC1G fl7_{%ʳs#|q} l.} o؇t|flFfۍ (֨,p 1<}=e m t)垔Og8p4;9^#1]bg 7"?ȹʂ;F>v߮ h[?Q=[^G3OU alTk5lM=2bn8gu FT%Ż9̝_F9 *7g[nވL?8.a]3lF??iSZ4.Yh"jp\ F[wyM}X04@7muesc\|;Oӷ;c;=Kc?xY#L?~z?"r1}7|W nP^?fpHdEhv:A&fsa:.zMnv.~NHE4cdAe6xY9N08}\'_/zרNH,M4ʬgt3HH4C`z* t.kzϳn0 =N" U$y/Ɗ-X>fymd*h#%Rʜm^tBxƏ3R7?7nfOtd~ni]%#Xd*=|7xhVH^l*f?$<8g09s0J0HvCjeMK>1Y.|~NU4>Yx>k4 k ʞooT~-`m̙M.~ plΎ<J4}?8N^g.GAfႯGVpbmw5#IwufӿF)WO?f*3 f  أb:%Fo4S,m6cεu)r2*8XS_}kfj1gmGg\yxp_uPdIZٽx8گh".h>to0\nD+HW;L? GzN.y]s)x|Gy pWE[n/P&`+É p<mףF}&U3z̠F*uǽޅ6Z lYsn@: 6@k+ewL0;NA%,r׽2oDjD=Ć/63}Ѵ*}8)-U[YAw  >ўt F`z(/_9ņ & 6^w3]v0ZySDg`E3|/:=5]{0՗Σ]x4֦xEw2sYFmɇKpuѷfBfKL%џ ZܬI>eT߷|V?t;Oo{Nz׻Sٝs[]x~Ԧ]q5Fs7?ptG3ҫS?Wvp@n0tg@$GO;9ei\[NmJ W^ˣ6c+Y=Lr0{N9e=αOf)K_F[ým}P .Ic ~N}|cp#^uÝ3~77gKU6rKa^2kz߭p1VgSόΝ F\+w.eB`ÁG`x%wk ;^o#UncSaj 6ƹ)}7s8=oǜU(t{s931='"*h'wq+8U8鍝 :TGs`]`or;Q$Oomcb/kNoJm )?F1'j# GEd>UѸMair|*?$`c4cYNm kJ ^ )劺uOu ̀9<ҊSl.iZq8c2t˕0'4k-Wr\Gmx_' pzIдv] zy 03I$ PXMz~GqkZ._IB05KF^xIt?F-S];YAda4Y iz޸爛RA:`_6k9t ~{~Wmozi\'f.p7D]R.d ַ 7 az{3z[b|CL^h}kT_|_{~TqlrIiPaIɱ.'elvz\[Si꽾ͮxb6UG%;,G ,h+7/ʽfwO||;_n3#nnea0Zq"RO<UQ_N߼lcFmcdFt\t vBYLi/a FbGRJ`lpG|`pc\vUagĄ;"Sb t~^T2 itUMWL <4.7 |  = OGI9 g]Z_* cAK2zkdo_? %xq-&vw5vv IDATZre(ֿ "MEV<`̐ٻҝյzBk;~witg=9m`_` EQ"_$ Th{̳r_Ovc|;{NF=;ӗ?g+w}w9mN?R`5Ɓ}ޡ3:ƳFן9ƾzFONr|BLxhx fmT}uAꧭ[tMk$m"}KfTL0t؝AR3VyvвӯGjkxXu o$V ¡ͤo}\jtiQ9|eHƏXt}\E7 Gq"s*Qc@-l7>C8fȂ3 _f7OrXvcl=#6Vtd/lYF:Ww9*ócc=SH(3{kY8JH8[ HɏQV~wׇqdߍ錼x˩})mH?gdr,^It6"^x޺b1f\L8^r\ۭcs v8*-|C%=AQMܯR =cF{h@NCR.ʦwKymVz 29ߖJpًS-epo9=V}Wі&G79f3Hk(J'*;w֊o&/p\tjDK-Nf{ZjS8]i'~ۉ?q0`+>nGlu7`<2ݞ󭲱|O5k!=?V|bS f2q!~3{ͫ^r's`;}>< ^^k7s>z>`w-2+kGӃtKO(7S3MGv=ozTtRe7nS{QIo\~']@X=;v[mj3F{`TTveq Aұ15q׻mއǎѹFPr#Ѥ_΀ooszF58B*< wf-eXmi8456S0^2̲188lV5QFehM8>[X32і"QIm25'B|j̵p2Ù\`#ˠ~`Z>C 0oyI|1`ǝ%Бolflh9ntB;=紾_5c<~2R_`u2XG#hN=?xѿ9|`Je9 KssAI[?6WhϴGΦ kW9񁜇h6=Y w,Pw0оh=٭4Mwp4~55ʖxxN[?<7unN<~gҔUkCךl3*L?vu1ƍWcGNΛwxު9bwQh~|x U26(DZnJ8#| 1'{)dGdVBf'6k @ۦЗ3{. O\M~lNp}EW$|; 3?^' fvC6mnȩ@Wa'ߔ3[?蒴h0x&nVL|s5[׮>p{l9un#A6Lt\=s;&h. &=z\hNlv?S>NN: =|> 1}KK/HǑ5:hrT6iF+/4c!a ѻU"GV3] G+H?1?xn0l ,XZ&` ЉG0|ɲt\P/:͠iȉ GfQ/Y )k?b?ۡF !>b|tcF'U:N'Oj0gxit׮=:436"0LN9GNd mAy3Zs#1]љ13c>mho#8a2cƦ06G kY+@ G+=Cm#3GKtQnu#eC`foCBplV804`X)@Ɂ78q{᭼I;%9C[=t[r钙sLΡY2t_Ptb:ˈf@F\;6@(#rͦ0͸ Ͷ ?e#U_':!# w l͌Aʙ(ç G#ݭnޣ?G>gD1~9]GEbS EMWg!gmu\F,I=@vL3s7Qu$pW; c8$jrYbֿЁU|=_9T3C|_=_0cJupBقkق"[~XB&8γI&Όm3xjH-Ԏ;͖`yW:J6k#7~7 hO^4. JLlÄ"rO}sPxy?C0K(vf@nZzO_YI ͅԁ<˿XShVɽbt^xmG #hc>9 fߩl cތD.6 0<`o]?Qql8}8C;^Hn~'^CŋK!sޯtQ_ oq lx͈Lb=ȿՔ{gʏ\C9lgq ͌ G  vi*(u!':ڿh o3/Ф T;B ^@9!`4+ϜƌcHxt-pxGz$F/|y' Y5b;0<lu+dgV߭#';T7?^}qzǣqyUp]@ G/}O9 ]sr0^ofC@r1whi_~ pes QϗVnO9d'7E]vJx]75q/%$pb SA]s\ xt&k1I9]n<{'\?o}Õn9}8WmbiWdž~ǽzT_倿MI7 ȑQ{x^Nuct{/LLV7Ž](moR> gxk=ٽ]8OJ9 msӠv#+F/'NtzFX4缘 v^8>C~r7W :oArN,rx% '08t;:{0Z}<3{?LٯmB jGG,9n җ፱]ïۃ[e($0KGƞL|5AJD1l^}W8[tEPE.*KϦ\ᤣ1Pn_^n0 _)ʷh_Wy`4Qpa$g՗fRIx*oϘQh=b#S\s:?OO7T{Oe7À+tSu6`:}!$c ]j^{(7jL}{IڕsTC =uD*o t'[ive)F>|~ {^9w^2{(pUCQ N;IjYh2{a*(@p{taH<؏ aU6֗ޞ.3b2cAræ-VƎ^:7kЇ㷾-}]grY^dpAOewQƠӻR;hAgוYھ?0j@;< }:70ѫK401tm][7uCCX(+( ܧk?q]ѻ=uҏX:,q̟uAv8>iS78W;shWfܲ-Sm؅W[py@dR4ȎQ-9cꐁ^GǨ]0yx6Xy:d7坽 86N4B4hu͜=|myi#R5 ߂'{ss'%o#U0=WdqQ힫ɼO05*w &땹BW66KO>s!s:p Քt;m y,[e4oFC8mG{V<z6٫; }+V]}[f:$9$X]i;/՛R{+@n׾۾6dyGH{5Ძ4gN!:\ܹyH;<ֶP]K"pVjFUw7\ݩ PgڰL=ÙN'Km[gno>'Y#_`\&4!KΕFɍxn#<8^H£V<|ϨkJJ7N!)hCq@x7gTZzA^3U:ꮲw+ tmO &s'9n+ Zpm%~6zF^8wZ10{`8藗ZF.?@x׳m4;Ou~, 3ؕ!T1.]q5S{2ئ4};oZ%# t_m6=/o -'._0|ҿ}}Ӏq Wɨ1]8P&۷^θYrzsZĚ< ,-cbݍg޲WO79.V+qk4xRe ? ;?; ֌]6#ݳ-MX#^_r8`| [F}:^տPsl8xn~|u| 1>xs-C`hnXlӽ/fgOoEil..ӈoG߽FUxrf"6Q#oz|{8ƚpAxVsF_;G[ָ@6ssl%=u2B݌oOGugvK9~ Rz gW Ml$uYyF+ h>9^@i:{TV4 \*~{w!BFoeρ9R[PPGDcr~hsy>oA ؾY;(yqzŻ]Ґ~H7/f\/*QWܜO+_; O>IOs pqrhG<#K*ES)];@YsMooHvo9W=NP_nZX``H hq&+3yXVn֮hS|^C$?}1 77kh >sե~Jck0>Ol֎g T`los:{xxmeX֏h4Pxpih.֧"#6SOM1}6(£[XP`x:Z09HHm8g$O#dޤ0V kV3'[M;XxvA#| =f}L3ؚ 4ΦQ܃u49ǓwG)c4Q9*bj .S L\~ǗtrnYʬ,ݨ__N ~lj{yf8py:WL%"ӷxh {6xz[?leuk<t_o?(g0.0GCy'J/?!gqt }NVFe2>36Lid,ajuDpW|Q~ R9PON{? kkxp`GqOzOF(/rAH:_``J<~#=;C@|ZGֺVXK+X@L[7iFgԏݷ| R̈Sχ r&8wIhD7@~ŶQHӿsnPԾ'f~̹adV wphCi :\#lao9l}2Ν T.4*3X_#83Zs9\cf-Q:Soh<ߏ6]N|]]I%n!+ WQˁad߳43p{Kc& qum։+>myYRkUuUWo4݈  @#,#26Ġ#k3:H o B(I+! "kӵܪ}oUAuFx{߳'3Od,5t30Gg`p{7_QÀn!udU-/> \&_Inz')QNN3 8'> "FCRTڕoN>1;-_Բ xr>*3fFk0dzwHr>{yyܖpiǽ?RdlH?6V$ %~w࿐~;Q7Fŷ)gl=5W1N_6e;I;xDW1`}P:?znRJW~h.9*w&hI+ Tk6 Z9HvzKw*eBrUE~R̝kcc/>ӌ7\kxgB2 o8=i. vNYk{{r=::|mj(0%/NrD!f7{>pUgx ?{nΦ|C GSdžu|0afUrƣ.& ٠Y/o?{8`mpAϛ \G߭ʋLeOKgost}:VW76pdg۸H }q͗n]oDs?‘EZt6nκlF{=uZ>+iSn-, bxT:ime=iWs$;գD쉙^^{{ ۝[5KU42AW،*<6AQlov!tI@tԍ:@I:v1U)c(aaRzV`!Ho7|v_a>Ag!Xa^3F&(< %DQl0T084<xu3HBTd&H?)}Cc9d=|Fs#FnrЏe6 [S T+v(%}Usq*~psdf1N Njg㌪MS03U~-cƁ诘qfKk1}AU ԡkyx>׋5RIU?J-]yyx@z uEFSu;lf]YڷxG /kMO&&1w ̀a{nRοa.h0xM֨x(kvcD8ojeT϶Y<&+ų^臺ãWW{0>\Qc3lGq1TpGf{?WN/=xTc94ϡ+8B8 ofM~LCuo-k5m*j|q&oV/bg\誌٨/U~=XҡLx ru|2k) oFszOhα1FTp7s`6܏Lx=g .dl~9ɢ9z±][S 5f275u?G8{y!ٴ4|2E%SY^:rs8ӷ ͆K|Tϣ#{Ƒt"y4|+Ҫģm8^U諮W,Lar?:BR`L(s(ˇ׋eK_x龬ui6,$0b-u3ěW8 %nxџ~cRp:P4Sk9>s~Oϧmw6m 7#o6s>U%xxeѼ#Jw>&7nIEa؟xݿ}.DtJUut WL.á'j%_ cQ 28*ep >~xm> 7vq⼊XbuO?~/E",u(#!4a)q _GcWc4t0# U: c[GOh(2j`70_iPFèެ27sj3,3G.Qpxݿs`ͬD]cHQU'ZG#g}ƙ0aLSRcY2I{zJgN??F"'ћgFU'H %cs ZFDZbp`HqֻhbZdl}s1BOMϘ|5K3 f\gpLR 20SRt^9GTӂ7?,Q0C~pUx>:b M2+/CXHͺٮ4ҭ@F=f~ߔ|vt$L! ΛմzφeDA@xJd(# D/s0~/̧b?#dt3ˑ"m8uKVH^XV0첑y4Wj.#[#O4/t;aD7ئsӋB4f;S38vx#Lٳ`ʭly[{Lطq+kT 4Ό"6\tG#; ׯǕQ˦W '`׵J;W=2B[猪X}ue/*] %qp9c@ىwjT OYO_7|`LD]n3 ;NLS-Sh BB )NVt#K9N̰V:f])¯?=n7|jCdc)+ʈG_Aؖ$ךOo2]p{3|\3#ZL l\bz/{6z|ӽX~8!ՋK'(z3"f Dӵ̏Y1חԦ@M,@^Gt|su0/mu|@ B{}XE|@Nuz$0DGDGF@(4ϵ1)}?Ǘ~1MɝFw<|zy7bDJ2Grr+g$?FC& 轍9tV^Q[Bw35ԍYζʪ/¿P,= 'n|!GD4c"(ZHitLjʛ )vRA ;$hW(q+^_D aZͲeyÏNQɋ^"0{Fs*+80jTϴK#-y#\(x=7 $L$_8f׷Qɺ ;QK͌#Bh o)=/93|X3 rLyp~|MƯWc:Y0z~ ]Ug6#Cw^|w^ﳡfl]Zԙonݯol[ݭ@G085 ߮-0*7eV76{y7xo=n04U^~fszuq 7?Gxj)"FqD&01+io2t)%[rp<7d»q@ I^v 1<uߥ#Ϻh·19leS#N0&3^8}=wÝG?px_V_h3,R/j'K$nSg&6xW/?+-=9^̪Z7\sj3]?Y/Ã6(/pX}s6iJ{o_10T[dWW.<,L򪫓>ck տS~]4*?##ڄDN,h# ڙmR⒊.V*fdY.50;.$oa^j22yJ S1F/ՌcLM{o0pYY 3rn^3ĝ#ȉy?3qa-k⧼/'_e9+OϭAD&">BKgl/w2?$:4FнeË2 x]oz;US!+nvDk<Vwp,JWiQcʈFmd W4L>;g/ &CcDk,ޫoS{f[NkX;q_ H hNߓ^,.V?Gϴ9=l}2T<]%bѷs'Q>{U:w㖾.|Zz~=F:G>u7 1](̣?e#l0nTesJSzF t?ˉfM[S&r:gD_}F؛{n 8v*wYVf(o1ںU~0W37CN d~6Sp. V]C| K׷KM}1q< B+Vo<`,mxѭ>63u{ b`,rrΟ?+Mnt09ZfO-S3ˉUeWk`;\ikmzܱD L|qaFz1%/c(ja4<3]{|7pIgCF|5334NەF`5 \\g1a2Y"5gVlCFL 3/GΒ>/Lr,y琉) Ks~ulZg7&^ۖο. 02:}Ώ?vZxas?ׂ΋)ewAH]<9]*Nm]'?]͘;ukTz,%;dࠇ3ܗ ot:CZ}'O>di5W~?>${Bt F:Rj/0 =蔾ysԙY(뢳9`N4;VU{w.AIwyK9d4i`hs5RYeH'U.'Yn(#0Ҩ|JF e`Gh]8.=ƿ%`؛6{?ʉ6J2_eMeUt>SYswxQzj`KsŏuŎwf&"eIeቆe4%؊sM}]}{7^_0'>t=}1\nd{!Mqfʓ2yIx3 IDATmىzyû.rw =}Cz̤ݥ9o-;4NҀ8,Cp)xp򞵖+~LjmKqkMW`^]?#ʗ;5]tF{6viGgI&2gC1^6IٹcdLy?St_ad^p%gc}^m2Ktsgx?8GoF;O3~-ƨqg l&v8t ?QǑlv`QH%+69:pP= W <1_dQ0vo9xO0z.9Lރd̻sMQy1 p>#tĤ+x#8ཞu(K p]`|k;r/7K*2u^:UYgm쪮*|6ܹ_t#,$mFD`&?p7ڮi{y*P=c"K4E2BQpB+|͌~"N,ɇ,7c;O@AVP^_vhςSfUk&}}*uXś.mdrBYx,?*g.F/ة^5x ,ܗGr.?Տ#'As< s381۳C>çfnlˮG4j_ Y'F&m+Au D[f ;2IO)uȒ ,}|(LiAgt8W 3~~V&}y`ҌoW(X J>#TFNÀ*q5j&Qk++ BL䭩4=:a@ hAcʂyS3O0t*b򁛞,7NΝ?U.:T$ҟj}骴و7],]e3S!~1̇X?X3F^SCU &re90<1^nsaJ%Q!0<ÎP6-F/A#97MU̝r{=X8`ϒ'ɫ 0;lD'jn҃3X7QJNnyZ⑽q~!rܣ}## S5,C{{hy}?'6۾>Ohw],9>EtYN$>'3"IOM?kS}SD2*]:I;5C>fzIS̒>[>`V3#;N :h4î>sFGHی[X)xb[_003돨xd5G}v Fc8g-<4'PF@vQO#on'{tW6ϋ3}wM;nٌ$B KLTz򌭰^FR ݜ5?K4e=5x1u?9=P}39d]21Z`#Bj ш p N=>kNB3~c8x>xz~stY=8S>z8dyAf>*ٚ֌#gns]٩ [An୔ҕsʹ4oưWKhyw#Q&+>G&9 J8;d2VHp̈́9G~xT;*jQip6Cl߄c~xnf5f?ifrF5#3SSFZsV} +̋jb5PfS2K>doK :hx{oKJ|Zd L"5z!^E>#?'@>gTug7so3+ig&t0Ü[N]p1ٹTC>K&!Y-襌]Pڈ *݆cDo϶4|;ˇv-)H3F_8l˺y^?z>I l 2x"o&Տ%AW Է,-Dmn9=|߷I3~/aӖ.͸or4md9Ξ=T!>8' f!#(#' H=)J1CMNJ,o.9_%sT_L6,-~RSGO.Ob쪞͒ ;v`rC|len=J<4aQ+yilz9X`ũ{js cFc3zmD`<^FshF}񅍐<:RAc3/ެ)9Ks?8(cmu gHB"1aUsFǫ^=nA,-g3ɴB]IGM*Ї1͌6y[#ʛW] EѮ^頸9Nx埪% O<OV\ "p~|%YLJ bt?^Jns~+!ɧM|8N7 'gʮh+3d8|?ys:زKǫxl͈a?ڞe/WT N.]mܯ-U5.ؙOsKhچYќAEm6LwvŇ QH%>5XP3ǂu|pY˹GaHqV@mJ@㵃L`0+ϕ ޲, ~Ãi:>u@_)V"DP‡~ )DL#1үw=jv=/ºVՂLu`v$;43xdpX 1Y |)Z9E/h]B)G=N @K3((4("t饍-.?~.!,N(sU9.{@x{BCt T..VяȰA[AeZfޗn糱H:yGFiIyu c><0~g- 41=J.kxFEͽ6}f\u-wKF?>>)Sa)PZS/&g><> `i3J.L+hЬJJ׺qWcLk Px^Ӿc&_('_}m(+SO6c9v=)'uFK' t[%m WjRs,2{] olU_ae9`Y}Vgud'sg<0ʘ̙J_,̠3h{8_9`AUT6;ofTJ8ns{eY +zvWK֣)sF(_ Dȕ|fonOKYtJC|N>YsM!R5Y-ލ j'*㣄;Ƈ.a7%GOqxlLv1T3$:^^K~;b3gSVJ+uezlR/)2htyx:Y@xη?Xbt wi+i#njMm&81L-_).ѳ;R_<-_o owE=O,vA` *YŪ+ pow6t>xdގJ𧿜wFB.T_ՙg K0xٞsf=)㩾_t9SbCWG H¡R #)Z;f-1f`~ +?g]I'(#5+˦c\P(Q8i5r"z [Q׆NSZjqz=mmpFOjpFD#=w gxn0$8xZ8_ޑ,(DSgի<ٵ{A]s{Pf j "cݯAŒ:vz 4+4m3Od"xx_~yt?_nuK~wGyg?x۾glxۧOgm__ݜw9pG~P7 : TO_$k#)e*cHKiXSA7,QoT<)]Zc2P9Gdy[[:6] gxП6˥ ץ# uMЙՓ9FߧAX^SoφJ.U42aӿV5;F7OqW̋(}07KѦޮ_Qg78 xvlAH-G~Ϫ{lf֨pQE*lݬOC(FcDZwgI!oPncߙ!׈To SflU "}FOW>[pn5P31#*}h0oSvr8cq#s~o~䬲elW[n gHiG`ǾPLs:9s 5Ê.(>XZe1p3ͤwqkDlFm%U@{eD;J=$Y-(c9?_FwSd&3wNɵ]= 61MY9y吭4ᓜڽo_da1g{Fgg!!No`f|zz4f F_|?x 7} vc :g$P´xʋ')焏|q֋^Bvo2t&ySY6\L{_X3lFQRA7A)k%Y=^-|ϢCݣݲ9➍0W6<,͵h RY`yK35GxTDK jY.N O˧ W7WGy6.벿= #t1BTqBdrI!UDH/8s`DՂWy#o+̫TKYM9J;ǂ76vzܹ@==sPϱz*Wx5R!s|"Wp'Uy ˼';s Stix z39،qߩxq;I( F$<0W DÃLPbG(S^dr#?H gHS`WO (ouړwǽ/m!ozq5o=p7 o__ۃ>8 --v&b~`/$߹s~衇~[4;ܟ;u/w|w|Vp:8\m=x6g+xo}Ww.rĽ藞9^4z)%3QECFMpNFhn\#N5B3FD:6X,i)4ƆNWMu29wkF(O&1`p0I5#̼N'˪ |H4Qrĥ3m9 ѻ RsWF:g8֗.>=2ȵc8㎅{Z 1Np{5l:^`Ճ7 >%;w|" q0] <Qlӟ-c+K?l#Y-ò{{?|I>x+͘b,sNyS8-5t.pÑI|8i.FVMy:<؁{b( i0؜c0Vqd2"U%dsD90:le̯W`J̓C֌SOGMv֗c7%>"6|TuO@܍&LݿP@xqƓ}6!G7z͉Z2pٖC Φ8%h̨:h;AC@ zMUoՏ\$8hZ ;1 IDATtύdf2z `#{og@[rD'!cC*H &J| ǩd-Mu( R,TZ{vtrږƁ џDE4lkKZmxdYQ cqAеL*,;3kz_f4>8he~>J7M'BHu,UmF3ZnYWN@ʹO4L:<lq!|a0r%]9\y\r;b=ZWbjg]x>m59;)5xA_SSd&]%. `k1jM :Y 5P0Jik]DlxlA&Hr x7ڢ 폝5b4ݯ 'v9+ֳʙJLU3Fɦ !{P`޵AO>'λO/7 DA#^9"l:E`F Ra)>[5xZ}vo9= gDEoÐ op v8GAz ;lmLNowx1\`E{pCaf94['8KI9,uݙB^qX7u_uy^0ҁg?}u}^۾>}?zvW7m{~8V$|؇}{??4?|wm,oggn k^<'3>3WUw'w̻@r7AkLEwjt!f"EGot/;ևGuү ̂G,>(G)\z. @J;!WQ5>N?/g̞72;cWQ 1.nξ_71oWPQ~2]:(0 .Mtp ,;M( =AG3yXnraNP1J3LgG뱂5r JO3r9E>ev>8 ҋب۽;Fnc&7su 5ɛA<<$L`xOTOCl$(#}F$:w[ EC!CS?{!N5d-uwlSr h׵Q_U8C4<8AgdܮL_|"_(` ēˈ6CYy;3J˗SX-G~lcȦzjeVB܉vyvp v̐LǰG8O5:9}:[/HC;}Fg 'u46hisN^ٟrW</9;N_.9Gɟ9YӻXW_4w8Y{wkgd88=GWEHAH7: z8g{ONd0Rڻ~FIf$wGx̮y apM.pv钄o '֫U l=[O!F/ytk~߼/=!`:)aϮc@t=#]hS'k9;&=!vr pbz[Rv_˲lp?}ȕzH2yz1r 9Uf1qF֝`=RyGU;l= ! >{c 9) * H\WetDJ$'EvqEK< gk)@zF(b(igXe9G5RBK'"Nʰ2.+Vy5]t%T,?#O pƋo=M]{xAowTM:O );x_LLOg*S"m\x S WZ7?ݾ˿|_|lF?Vӏ{lC??}g}Wr;u..ۗ|ɗ4DTϞ=qmަuqٞ|g~gR;h#>#_M~=vYGlֲ>:ߺ~n_]]Gy[Я|./׹30?>~؏m>fl'wNr_+}^ YxC?CM1;?73>>#?rop{6>MtҔNpDudL(a z?F# 0ʢ)KBӯg?SۨIo_bٌ:@XCoFj:wׯ(y'ch3Rx$ x1}=f]Q} QZGC8*˨B?״(3ka xз*aҗ3F֬홾EXd ٖspⳍ6^|0n6ḰЭC]υM X/}y3u֖LD\nzm9PPq2oZbeu٥L_}8y xAA\Uq{>ة[P v7 J7ZpeՒ]iޖ_K,9Xk9GXEK[1s fɆyF}N))(ʱ[ |88WJ5f$]?]p9;W/»F6Z(U r;#4|Aio*N5nZ}3xDDGJnl ǣOA/oAy.38tٖlX`Ƃ/Q㨆i_noƿS9pWg3^yᨘBrJ`|\m=szΉG~:8S}kYSl'9`{OnE3'ٔ#G+w[tR*nd.0JMN{lWlm``i5ʌo@X[_lzBjsD&_NzOUb m_N~m&|u|.WpL:IG'_%Ne7-ʷ=nzmv礗陾2Q0wkM)qrI33F{^Z8ӓgN צ\-.U/3$*?4F},'m K,yel2XqϩOHZYOv>Y OO=N}DߑVx@_מqgI@u;A zF]PgYvtx2<9q,q Y-|Naءtr8rVa-} JyBe)#q{!w.ixjj"}rb(AX;wƸTg {hܼzzVvʻTT~%ۗ_>۟r3gqqse*;,8d+qܭS˿k?3}}OOپzIϺ>toqt?|<'cl^o̙ϙ׿|_dx5y">>op9~_~/_HtNoKΝ;7p++׽uثk>?Oo6$φs[[Ɛ1Ӯo78:2W;UYCAQsj{݊'h5=!3?}^6 I/N-_k6x-8he xK%V1 . {MxhcA`tVa\z,ʁ W/^VtQl}KFt8win<5ByS9sLp!z%s ]ʓ|ӳ볯0昴>36n3=x5 :䈎;#v Ge fZ1 SV2P]Cl%%{m5oYT$ȉřA[~haG̨!wMقQjAp`~a{o4x[|Se d^VKdF^F|9]G/ώ9i3]dz˗qp )*wN 3&Q,1 %ZW+oAUi5Z=pzW'32G ^M ܻTp@%~3@ ;F̫Ҩ7DZd}9.zq×3vա ?(GNJ HN-uę03yZ:шEjI0,*7ݍ;'ڮz&h,۞nQ\`>16n/Lu0nl =gsV MVn"9l خ^:uƁ>tޑYN/'GdHqѯn \m= t, Y}[JCaOce<5ఫf~k5~Yo md(%^̚~c@!ԣ}oͧ)0 d Di7c'OH4@}_3fDTFAÅ9+w&l2"{~ -cdmvV&Pٍ4 GBkFVø9uy&U 8Y a3Frz]eMM97iTH8S0ֳ3ɺר}!p е|O҃=J{88T2, oRQ>V+8 UZͨ6:ÖWRz>;X9GOߗ {Q]0#VG֜O+U|Z^ׁ؝[ h%KmX~.3)IpW Rat$=#q[ U Lky]9Op"]fTeOؽyfDț^-@>"4]vW 'tW@2+)3țc,}^+;c_/ \t[ݔ?U's98f $x!_x3WvX(f9/(zZZ{ewC]ѹ|{} l޻}>o6)o\6^߲'V*0{Lj8? ~2zRzwFo>Ғ) ʩmv5]F9M \86H#~Qfg.|k.'{Y"#<٪ꫳ:KIr#nECl7:|n1ϴhţ r'< aF~ 0ۥ7ꯝ cPSv ҂Qv%>Ѓ_ݏRK']Wٲʥσ=pѮm) |Yl†f5M5S^DJ0~fAR /o8& r],3c3A2{bJh#6YX o]}mt(zSP0v2.b&|· F+wMcĪM>r>A;?Wo G5$QsQJ4P/LuMt6gvf iNALƞ%E_¡v4A聺 c cˬU` UKsucsxXҷE_r}ujiıg3Z/ n3Ŧ 9|cǔ>bpOEo`)[aw;G~xO;耛hlK%nD` 2XjWnzۗ~CK_|oGm{ G;?-ˋ~ߵ5Oxӧozի_rt^ 0?)~inF|M _8_+'}'=ex^v'Y 4AOO>?WrQ`9?tl*e oo=#˿3z/)Aeׯ_; ğw`< zwpۧ}:gwχ)hХp`f$CrKz&5:Jח^=rv=Wng:$_qO}AkcMNszvSFŠ1 JtxP3nޑŌazN2tњ9&$*Q0\>  DI׼,ʲ/`@qD@Ō*1_3?c?Y`cgʺ4*`X_@u%vU?.D&ٻ|*hʬId%xWzǏ^x5ZeWr){x6|+Gw=)ˤw(Lvuc咽2p-Şp&GSî!yv@x?tّ:FP?ݏ.[+wu\%HAQ`xӽ*͵sH3zgn%4Gګctt`']ve?6wfJnM sЇqA:0,PQ~FcP icgeeJn3VVB\o& .]+*gtn3)Sq@9%>C56GsV$y[^a #x`]1Zvs&}I͐?lԳkw3U\ou-@829;7jm~2x`htRs +i*%3 F7g4b|Qtj3,)OP}NZfDzt&'{9(ڟ:狝V^W F.NWI{k{608wWC 񞼦dC L=v>L%_c\`"k{FVd￷W$k3%0t*`[ /m-u8mQh5k& {?||:ЄGK UgL)ɍ&n@ ʑUiO583vծ;𤛶\ pHU3}x8څv4/'TPd5M@3g +x]&Mf߀ D0edpp#q#}lЇxFW1uH?K S>KNr+=kxi'Vn^=Wg٘JL 'iĔQqt+ó h#Sdy/=jY!fY_tYܮR H `8OC_ba0R~N|9pbE_[ELw𱔱|v [ovfVYHBeuOϾJ볕6Sh3@7 ~ eߑMLp+A2{2inw'F1|!h'8Z`@6+ vrFp)&biwFmnUeOfN=RDFx=$nrPS C^g4yxew$cp.N(vo4/1>xTGN޳%7KE8p g g4cЪx.=$l<,lF^@2./amXj0}}Wj_ _EοaE^0୷?Y>7~݅ ~7I_Wo??1kԭɷ{>G?x6|E׾_7{a#=#ӯo*Qq8xA_+8>?|3y_e_}}lpRO%Ώf)ZO?[o`WiA2)f: zZ<nwϿ30H졉ӷ':>Ln]:X53 .+wz>m Y\Zeώ9)`.3:kchen6J;O@ʜ/D >s+o ^FǸȈ;3ğl?y:sQd'w2qv:2pb6- Z8c G2?;cq >=Y!lԇN\]V2+=7'n.cv 8ChӃV՞'Fh댌vSƤ+ aS=q:#qsy(>eb@xԽwzip#@uq+7>ぺJnp;g'_f搴ytF3e|hq F(+Zm|0zȌ>zt8 ^c'΍|`_idc"~A"'y[M&iF+Ɉn͞ 0FAQeNUbwk:؎#E=.'],Oо ]rb|>r_M#E-~L6?7ze jtN׶mt=v͈Neg, d_)޶/d9p3.:(@ e‘,hЋq596 =^_U>\ :)dؠ>'!׌9>;4ϑgL~@.vnS9k=Μ,abL=ٲq/N" V*y8:ȷzhDkׯgp=Qق3l 2_=_6+5DWr=5ج$0N֖.e d֙J, nQI/Rz(Į!]9ku+ߚv? e𺮜)g+ώ;iki!ZzY?V_?8kzGr|_~|^y{}/̅7^e"^;Ҵu`o.&(\FƒO÷CP[11qHÕ5Rx\ZQ`v];lvg`ݹG֥wܡeOxm{6oa|v߯N_$Fu{(}Moھf-Owm*L;Jɶ L//u>K=̘L@}m7x.+BWj_7;]ߵ}W}5>S?u6g|p~w`*yxp{s`tkfԪ`ȡ>qrK9=LG.B~!_7-Rm l}>.ssoyS^p`vǣ7ӷYh)c_ƎKuǭYw/[۶wq<^uBr-bQTrwB$71Q4`,rѐ V !-"P MEکjk18ϯܻRBm)*;Oﭷz뭷I#cElt|{)L8pC;?3;Ntv}^lAh52̰pTϫ NʗΆ8nWwoxhՙ=8dT+'/kL4So,Vp0Ɠw9(/3u%Ҍbqhl9<61lhO21;2>x4l 0m`E#]sn=@*`^;ISû${90"9s$%C9tͱ[ҍxqueLu=̄aQ:|36p#1?yGl+HCs?3Xf?ћ+sޯ_<چa^# RmާYysOb+vAˣ3~9z[#=_?GwN?Q!lҽuc%Dap-uU^T3QE6Sg5qO{!_9Ϧ<[=hCr 4!5 `%L)N 5t $>QkWc꺤!G\Z8 ˄⮾ng꠩{O>yHܔGK7A6ZEx]N},Qa FyԽ>3O~p/N=t4FC/eJ3siY𹻵G.>R>|v?>gd[OC/ f@#L)V_p6Ȓq`ct,;6=R}o& xgr^33j=30Qt6<͠q6C18*nWōf~~{}5#̦r,j mͶ-QOzh$S!NՏ!CV|ƥ,Yt*bĞڳO@|!m Uss$oe^pZ86]Zʮm5qIn[a/v>8oT̡o5ۡh, .t9TqTxkIuA͖ $G~|֜x3o%1Yvo pZ} v{ۇ^ofU+ӻ"C} 99fRwMN;,oƲ{+cxrXjݝA00e rBds:)3X>M4qʶ=YCKL=/e={kNvUKh--Ze ~4w*9J`BǓ!+lPmA8_ytȻYX?~<|< :# ~Xص7As=_#-xge/.)Ѧ1Џ,"o/'g}Бg;]:Αp2^GU-W (+;!^O#BxLD8@7EZn(}xԾ18ͶH|_ǧS˷Uhs+|@3 ]f簦ʧͮgߡ 34z^g0輡 }ҁcq < x\ceF{>cE) *LIbmV{%|5~9ĈQ3rgt^|ˆð=-މ}cVziguZIG ~aqz5t0z]W_]ѳU:ū_t `~{CmmVm[ d3\}~. WN-ڿM&Z::C8z|O#oK<4NnK35wCxsn PQ;j^G{<9ޥ,DGfƽ}ىk5xR'0{?xM'TQ\C9.ߌ\W]Qٻ/(:h )٠@ۂ:/8G:F1$H>X<4 h6C " ~6rCt_IT?!o%“uyjOq~7vFqȿv?zW7ܟo_埸ݏn~7!|8<]~ m9Wsgq1qˁhPxCPA7YQF?.--3 <1~_)$W_^qqXo\6%̈rƎ͸R=tfP:3*OGt\\u1ipIz N㇙hf0z>QںT,~6?j3N} 8Ct <qo3bU@D=ʁԟ`1v3U"ෛcX[_ vTm|84\$u_gWs$Vz K5Vm0Vt;?kU Y,[[x$eo ke3Kes8@mwC=?- ÐXn>v KH> t4U{D8ԗ0?K0rh'8z̊sf2<GwXe8}3z 䬦^[gPo7,~g89Cx3pҤ?~o~ٖT OsW4|Q9~=juos-Sˉrxl(P-#_>t79Ɂƒ.|nڐMmV]wY#gqP; ;9 neֳf@دZm:89W1Aյttڵ*tnƟ.ms?oWUErׄ#4mmͼ <Вw Nl.mDhLiGO~f":Uݷ^2U5b#yU+s&eVg8w}]Z4f2 ẍA "-I8u fC ^]x]sUFL9FAʱ`Q(@toOgU aסpN3JiH;#7hxxPQ?^xaHdPk9I\K_gGx ch_& =;u.X%?)E*}^}h kE߿??'ī|7?ӛ??n/w_ˇ8qr[o$N'lGJwsM~,f倿{e,<1XdLnQ:0`{tVo>V}XcϽ1~,Ckʔ4D3.p1?߸e-T/Ӏl)ntވb#8x?mf%^xm 3-cmƕ @,ChcGp 1{Y +Oe1veK16Ůp`ܡ7E{|2dCƹ ۰ˀW0YaƵ8THrxn3{rf8f;9?4 m2znvZ1'2ʡ'؁[`kD£<, 6[ӡxawMQy8AgAj '\xЩ3N6smV1Z;uGlSN&}uФÜ2U+~C<*+^uMFK.K^3g7Mmt=ЩGϒ_3 cZ~N\xlALc;r8t|RB{Ⳃ|A8)}:s[='3Ɨ4Atzpt}2j%Y_@WUkY5'H&ivIm6&0hsEy_UCIIJ-O^MrYڣ}Nʠ2tu_oſͿoo?zQ<}O;zYx™N 9/ -u|ȤW|qoIlske#IWm>ִ2rVvgu[wD.c :p[z6f XJluOY^o7w163msO|,aNiO=|+ľ-Wyߓ VV5nKgЮɠb8u" Z~,BH ߛB  /,=|32g#c ƻrRr(iLɍ-Ƶ;C2̞ͮhlfy9v2G<$9cnO%Cd7y͌s򯾪߹A %(מxyؖù{~ro>,L6F4pm, pũk΢o"\NqYߵ!.鞛oF~ kA._Pd}#f/ha!_k_@1w~ e7=7T1}ȿ uxS >+? u7|Ux4]ܓGWGfgldsa [PޙtPG3 V>#?d~sl*}WT{U/,\n6O[ہkmHM" 4A{ݲ :zGx`f}|'\k`oX]-n+f<}et 74<;̼~xW:\X`!$[$[>'}jօ' :uƂ /w~Љ_گdL m8̽z .҇ll_Cxޏ/\|<Ջd*՚ kd e}u;@Qd֥ /س}־ |>Vm]W"[s/0K38?poOQܲ?5TC ==4=,unH|i=<-߶$VvCƯ=y-:2n-JN6gVo<ظKVSˊpd]hocZNlWCf@+ZB!e sfpMG_d_Gs*VYϿpwf, Nuzfߦ3匦=18e:iO;P9٪/YG6jAaQ].{`G`g+=8) -z;XJ3|g ;/!26݅ y=Vs9_= ƶQ|bc[9@U-΁]hl#>lfos`NgwrVg,ּ>3z8CȗBi ?@Y=d @Zή&79x`Bo<?cpYҜh2fQw `[<˷9W~N_z$~w*dvwq)2Vo%8_EARW3{(@P@ aqhf|roz=N~V@e*@68M.p Ŝ2_aEƋydz򖟾x[9_Dq`JڝOev K0!Naf8Jx#xɱeDh!s쫶Py#؛ N-MT\en>zfJX˫,*Px,×kYqt۷"'n܂t:iIS?hG!%n>Uཿ^rft=W[_ٛ.4o*<9!xKgZ;Ʃpo4-ըkWkd==`,nXL@J%769}h"^MHQ}*\T9  foMv"Ne/j7DqџU/1F;nDfÄ gsf0`FNY0 TW9GmHܺsc0˻Db>&cBD,:2^Tkuޯ'?Ɗ3CAty44-Rk,Ƥ}0P'i.`I7.hlJ/vGR+2fu<8Qxmj99OQpo3Sshv ~_; o3pcUw6lTߞ,s6|Ѻ}Eζʁ$|?w}ϕGe(wy?nүͿw㵀r@fg u0 N_wZ|KީԖ;vS/{TFSz,ۘpK38v|4pr?"V0 M_0B=/(1:5U$1^E<$ʨQp2n5 ǴzdUM Sgfʻe^~ai5Vo֒k3^Y'8>_Fuy,8#2Rw8y۪Q /SRc{Ud,|)+LYRjeNoMm ngZ~=W"]9C(/B[#Cn4o] i[Fm:܏?^G7Oߜn+AhZ'Q_ .ǎgYSuLF+6Dz=CpAqڬ4F6'\(1,6V92-?'d/o|9oYC8@f˷ @MޜnNxp𽴲[ (DtfY8hxSr+k;$~lpy}JF߭^ 7zՓaև17<OcOt.UweLYU!_78yF_\pYz鳲e$Y1<wl9e/g|n|Û)?`Hoƫ g Wf f̫7l6kh,^ʓ'NS|Xdi* zK7[.m2e+B0\]g9C.ǜSU*fkڥ^sRkpf+QèϬhICXdqg[KT9&oSTǽm!=0<\dž;|W?kwݶX[riyM JbJ'oݗ)S H η*x`_emʘV2'J@9gt(1gBGJxu.s'gʛ`k 9x5Օ,PM9{jKX~~1(hhk:y+ϼ[sv͹"#%M?toAvV>وUL._x:J5볝bPYDtrp~<'#]x~> 3k(x_1Җfl[Z`j?Ⱥ>OZO6 Up\U+Ə5F=] q`s_#ךh+A>6y8ΐ4[)ȣz%  0-H I_:۝hN%Ёp@զ)X+ bҖ,m#7v9?_qQ[. ._;~EV8WKP[~!p.?]J/:B*{O&:|oOf*ǜ1>& 9ڪm:#krv6\v S+/rAinAYz_F*ж\D4*ƋV*wdw'J!sb,*9*!tu3'ߠ}NcΡc|S}P5Dy v'_]KG= :̑}u8Wn}y2heNT;C^@aA'hʉ@I_mѺ[tE=J^x=[\u[_M*:ʳ~q#` Q:!9d4^:g_U^ۗU:ۖƓ+#D/;=U_Ԩ._he#8?/8^XOWNG0 L*`߇q~L*+>yr\u `Krb&|+snBs0Wʎr4W}ߜs>lw~|5>*'F8sgf!su{!0 ڳp)Y9ss8Ȑ5Sv T,:cZho3ouGh Ѝnя'E ?ٮ{[/;Ȏ~)̖J{| V(s%γc%sv9eDȫ]+2?vYK]^d6Ap{ |=2':,YQOPT{?=v N>D(MS_~-GvË.Y颾E m8Oit~ 'ou#L5s<3SvxMqd c vr@;ޫ v=9XASgGw~$lum%BEC ,Y D $vNY_ْQ^t j{-RHɧ: yZׅ1r|G.zTiфhc.Rh3h$!c4a68TjX AU=cr'zHBnUAx-ȃ-Һ3D8}u\reg-?6$&`յAPJxiy#7Xx~{Cu5G[gzO.xфV0Z:@o=2եmEt$7ׯH:Œ]r-um~ܳ\ ~ {wm]Q3хTy#ŁfVn?[)9/b:bEø2}r}tj~zzZ25z]O:qsHMg{;JBXa:}W 6K(cH_.n{IϜ?q'[A5NfX}pG1hY^Y1b/=ykji$Yy3s0gχgtgGP n/=csF|83u'Ffp?r GghwAW?ooU66Ln992{vќOe6Κ4݇cﻹ.U^@Yp)|J9\O?:?E'^_ee(3w _U "y]E7/|TPAUd ޳ihë)3-<ݱku8 L3G 4ɴׯ}?_v3pыD:k w/yˎ=.%j'#&k=1>gk]g^::v ?4 |xA#KxE5p]Ao<猿rs^s1U : ~7Zv||-(_m1ܮnu(>C<5e$'W%7o>vÜ0V; p1/?jFY 4fԿ-@@Q0{Xa2rt|uOxpp%o &p-7_(]-O/w1.79%-3`.@QC XHo@t[R-_?9tDz7"[2FnwyK"sLv`,B y[-ܬ{~ y`Ca~Wq2>>.oZ'MV%kH߼ :Vp~hw__}Y`|F#|K~VcH!?QVT,ǧ]} v6xv?k}>(H$K$9K6Vr:  > 6M}pfm՗m0xz)zW %6v!KMߦs))tq/U0ܜtecyOǿty\Vm:|yyێV ?'ۏw‹nzӱꡳ vL7AOǣgl5IdwK*d;Xg,%O+rN7 F3<qAlc_97z9*}0KwWsr9DI%ZEB*_󗪼vr`|St> Ioq<,=mDvxgKf= >Wc[^{ZЪUϧѶUޫߦ?踵i Z`'QB&(DXwm~/f̉ ? DLɾqH,ΛrXqodl wZtc`*Xo4bUjpkx > | {d/V:;&p[9ߗa∥q)Sp_81[:.>*'2xJۥ%xia_,98a'? juU<{`b@)SO0K౧gD˫rŇ}x8];\n$Cks)Y[ ȔdONr| H?nެj5btn;:2KITO'D3z#Hz #}>G|p{ {߶hX l~8 `W6[E/p4>q 5vzU;xĂ8T"aFo4q/jeg {E+<˕-jh6>H[Fx4Ti k ;]Zekó_8(/f6b<>q TELQCYe >ohdIxT,Cל $%ykQ(S)۔A_-_2`(؊hx\%7?wPdb+i\WU  tekI}GnX|r3~xr6?9 3,[8|۲qcoY=5+8HVberrz&~3Ν0< x<*yg#OD=^9d/|07hc|D7?uDhwu/_vsX_ W:>[O4h?6Oڶɪ׵;ԮK=^7d 39V? )\f/pdRk5BI-xaV6s:|jg}_ e$9~mY t wΓAy o [g`X[Lx+rI3ՁBrJ^C6Y~םU5/O=1"8"oV /].K}3.ΆH0*9#tKW~_;z~m&~i0TwkOJ ݱW&+T@`mL8aVgj*oDQW+>pЏ<_ޅG8ƌX x99ap@n $! ZCXZNi56Z`>2 }a+a:*/2ƫ=W_tf.-Cf6[&Hʶ'$N`x}IUه>p:_A1 9ۀYƝ?KWcF47j./tKOO'eڗ~TQ#ه s t{{ZjA[6>AV,H04$@eW@Dǐ_w_'͠ .X FJ73G#1U%zRWcAA\ef_ f+1S!U'soL–;{mYk Çp`-hf L1Ȓ8ov۸%UԚcb<ӳ_/G6ِ~Y/Xiڡa#457}C~(zXhfIl"~pixP}˂ߌty*"i*]۟ʵM['VEsJ}G8C .T #YP=X_U:Ld`u:vV_+g2@ɢGgh_pL`is0xExw\91:ڪ/xoˣMgv{Y}櫖Sy; 0Yx^@jd1zNQ|Aڨcݶijda+.ίO% xG]/5J X://lkY3=SgL/[d[cj3i!RSOz{N?ke$3dWm P LBW>sJoM8f7Y;3+%fP=ç49Y;o°z=u84= Pg 7ɟp]ݝ_?Ys. ~9@NTGpԳA+ިk7g_?8@ <@Wy p֩PVyӨ sk+ 7H}ex 0[}B R-U*dTZ꫍ltVxK xH8=dKH򒭢P$Cu:N|׽}cwTxfڝ,`w X{4P ҶsVzߜNe깼5Xq;FiwUcRXrL `>u[/ʻ B)wK=CXڅ> c#JT`wy9?yGGN IqAVcQ jm @+N)$UWh(HgJWgVsLG7~@ז|yխCMzg ɢK=B<`J=?8{9~/cӟ9^Ay9ԖΒXjmv]0#ƶelIcQuum:.DẀ)ƶ sW\=]hI]ޜ m@Ff.~7vt`~Wx h{uct9z6*;W[3[hAibeL,fS'Q}`^9\l~xOfM!_>_ʫ ^+a ޜ` Q xl/6.O>n-Hc&|ՄKd%΄{Tf:ɎzVFNVUb+lnj<)`w0#U,#*sZ%PALФnmƆ-B*3O,vE{.0dYB d_snj]1!7Q n·~ى c(k2r]{xgNKDoѽ7\2~iq<ȩĚj=\xi (⁲u/}鳂/C\-C97Zڑ;$M-=@Ȃ9v4 NN_4Gg<DRxhW= t£ӖR͸YGwL>mPpXq,=z(͒knpٴ6[58d di;rȺ\uxk9Y#9(,IquTo`OfɑkG 8'=$|qL &t 䋡G`~gp'vv^)L0/>݇O~ݘ3x~V%%|8(`w8ryJ Ň. rtWEOjr8n?jxC|ֹ9j?}7C WxKۧk-_xM~*B C` /p_ɉAf;4g JztfwwtUh<;M c+-Ln[-oce,Ky`9a97p1h)ո8/I'̾`Ҍ`_g6K i\M Ap N5YtHA>a pnx-r{V(= AϞL9  ?5 *sshw@7(6Fk r58P sN*4-VwoA€༷rf~zȹ(t=ÃXt+4_+%-7ˆ^wF`tx8\p_(lqtC{*tnt>NnNeJÂ{rW. YΫnsbȠ03߬PN4@tzmcX2#%DbJl=Cn2Rл8īKPD'/ӷrOp%3(g]pʄf[1;%o08{;KxrqV{~X}TR hٽq!]n1вr/;h v\-5oܷ"@yw|`0ge[ZUv8A |䢼K*c]}US~ơJ:~U`ՌXg&И3{1v>ĩX/Pez:7n{͕QdP{a a]͈e'%v`fgD>;fMdA~kgo e[@af+;] wy>.Kdž`\K m~$*Ϟڛ'.$9=_`vٍWu3rKc0KsRhJ~gmØ[Q8[,N=yd~?kOp~9Vdח*ΜJd:rT }Evߖ{sO>HL6J[2­o4"Ӳ^-s?ݽ~='[5var,Uuxss<$k mupA`7mҗ†\%@L2or7 Y2P=oj@ x=1Ͻ}KNYYB_\!O NvPAE iR_jqڂ enBozEdLUs34܍Gfm+Ơۛ+l*z7{W>8\]2{'ҽ1l*CޮߔLGWEߏF^ e4?p`LJݛW;oMG8s½J7 ԠD|諟UP[of=xVѼܪ< [m)ƨCt[Dl[[tg_΂铝RہuN*H_ C7FazxS[WȽ,@k0~8uesnyH(6<_p8\ pTц`X A~A`Jtjţ6$p^,B1ԡd(R͞[s_Eݖ:d]K3v@fG5ȠC眿'5KRWE8gu/OY+0v)޿3%>_Gy| -WKfBh}9H1/\<~^fJ:,p}cҗcc?{e8SƂÏ/)Cv{ {_'@,m[QevRq4fT:34nu0_GO3~fp$v_z7+s: P?Ӂ~{L@Y:?Cm>9Ts(|S{lKODlDw%A9 V%/_A'{#߯sV^ǩ?8=kԭo b)LDV[nҦiz|?swR;XU]>[Cb>el>d5$͞c#+gݻ.irj-ɷJxg`S71L<:RR%@$'cyDU/_Basԡ scB-? '\`P<R.jʎƒ=[ `0;~E_͸eqx;3%歚H8Dc+AAujUi{;Ĩ=,:hAÅjw70rX;u`C$"d.yS: z^ZE+9}p^k<_]p`|Kx&)wJ;|.~x; 3 ;X^]ٸ)t Jһ w6/鸆, i>tS&f=& 3//'tn7@я{{sKg{2x>-8 @F\SʕݪZ-oW7Vz@3nwpbcR7,\dnȒ!ط'^ķQ1^> 102Ċ5NYzbT7Z ދ+kZiۋ/z]pМʗ_V0Ƭ x(am+j'UT2.w{1b]=158U`N G# "G[n\N0o5DZ7Fk;N㡽2H!+~Vm93^gЎV}`שwQ|!M3㫗v /8%zn >3M2R_/r<B -su+7JV2:P}x⫗9z[_ ;>i[L>T/G‹JF{8ݬ4\N}&ʙLA+873<+Y.ڨ4k~WөȒMg3>ȪʷI gG{rO[ G;>֎V [L]:G[Sm@y\m?Z-8'*Xmj׺rmw$k~" R6ƏF}y6HOP=c8#V|Ӛ =38-^]#MXlY#s9Uf^8.H/`W}C=HK=TWt۲q^0Aeu+:1f7(M+GLdOyHSJPNC$Qv SO9.Η]=^qN@9{]xw| a8 Ac|3|pnmlVeu`+w~ۘQ=cWiپoSe/m43a p)nkeÉXVwó xL9)oVҷ Kܒl|K rt*:ߡbfݳ?n-g2xk Ռ 3N} PH`q_^؎]3>|7tnYslahf˵c"|N?N:ЬcmwVtD)zc2!n.zcVwmgg ڐU_#hhpy@ͤ~[_^Eg8|㛟{86EeaVUts漎v9f7PۜJ|O>qcrbI26Yw^/{OK3x^{YQ9U.9l%n?vNyENF \Km`+ʽ`I&ۜ Nv~~lA8㢋$SlIMK9ei孲UF nIgUn8/LV>֛F[Q]ዕ.m.V`Oo~&o. ?uğ؂[]1 )/r|\!d MhG.q9p`G'to5Bdޑ+~d Jgr8!YlRQWrvSK0 Vѧm!O\@ogs$ D~gL>Oqˢe5KG_L\ ¢_s趷&9Kǟnw t&mqeD|V |0և1?N\~&DPYpF݌cT̹w#A*zbwz嘳(.<}2: GѬ Qf,W{up$R]PQ$-]),\x T#o}}GwHVt@JN|3K:]WvV ѯ=" lVgI|?uR7ۚ F3 . N}y x9öR+{M{u8G߫@#K6 ܺ(h`X+[ c|Y??µ?q 5")lc`~g 84?i:"s8}`LgLwoY,U IDAT)= q ۀr"+je}8Pt;vcPyIc˳_r$[7E}{ TaK$$]w`qYg0Q9y#={H8>tvp:idfЧ7F3Ɣ5Bq 8c 6v.Ɩ3x!72s6[5cvγ6n\͡]Y+VV0XNxPu_1dW[ƒ6m6<+.K7r^gkƵ`ρVotL珛My Q"G.ou9mpz%W%WjosfWD?疚30af]xO1ʁ33LT 9A;k!x|!EG&X~]cTоisz-~FOL#yWl $y3sr/yf]ﹻ߷' tAD14<1F#`q  ``A@d`p ~{ڻO;cl̽~wVZjU nr|Á^^q:y1'g Nׇ£E*c^ov8 N|1FA#5qf- G;s\e㿋i!g@2!J3x7,!W'L.j$ʤhvL?kv;{dtO6{;;p< 쇒Ck^:O2N r^l{Cs쓩HmɮU!ݞ;l-1+ڧ8MnNs+R N}y8٢G/'h!i{DK-{,ȹ{C>YB^ev@[v׌gF_/Vb-H #`}L˖ˇ{Vz J]Oֆkt6.]oT+f}bfqF]ɦ҇^;ѣ>33ސ:7rJԖD$XQ94e h7 *pj{FTD^|x$"T$h7Ph|-;0};kU> #%lO)B{um{ U}}1~2+NUhNrż9nFlZV7(r29O}a}5`YVT>'P+k, Zj'bhHÕxw rt=mwߟ.]y*q h8m2\utyй|Bsh\ֈ9χW٣-:m[`w3J{g~C#P z#4H,viKW援U+,v\opSu_pFk9u:ρ€{<:0}m/pٿrG-%7?G_0 U-ŁT܌%s9tltdGLY Zy)NEwh]N^-NԍK9:CH ~fRNY9`t?'Iz:ŧcH-ƍ6Y`gWnH ^cѦ״O(c붗|F@ 46Rh@3X{}DtTro3y(/~_\K?d9mamϼ df6n]R9ag豖꾜z 3|":,U2.2'gyK9F䜻pF3?3iV0{5YTtϊx&1vFy*6#cs'ڪJ H[{2/ ə :T]T8PpuHsT, Ǻ {][mܵ4Rt#'Oy3}O&ukFDFO~L}~)diSV<(XGGYu~Q] l&VVkp~Aq/i{U!x*|O/׏8V};slۍ? AyMsdoX<ت˹wcpk-/e:gw[/Sf}~C)u.Efx;r>'۽҂;$X'Z#l0s/!^=W5Ljђ ^ ]ۧ4U~RC!-ɗ _8zVNzC>r8[n.;|ro7l P3 ΐ!Z=,t̋OGи2_)/ؓoO_&Feҳ{9EP/l_|ϮP{XblLy,`3RƐ9O{q9F,MpqR'xc!FiF{j1S^H5zBKW0R^Tdqۛm)1>.X`܃}t xRy VXs6 "]bCSgCG4{@?yGY kK+ڦ֩H_ڀZoȻlE;,)<Ю-vHev҆)ۅmv3.cLsϦ(  nо)c˗z|Əy}˗?//_/_>~;?O/}p̷8ˁ- wz^* pVoοJXr8{3lL͂/|nPhtub=ҌK kQ9`xq퀾3vzel\4&%J9/p0akgܸۘb].HЁE/eҁ 4 vp>;n R<<~9_Z9ȽP˖].O˳Dy r8wucNf4SXftƆڨčܘQ9ͪKZ_d9HGM,@˖cKmfT;[>+nu׌kcI 7g,xSӴ%g!CVK4_ ÿʃlHzcFÏj Ļ [N| pA@ů=^KЬe/ޫ#=ժ{T:g}7C8|fM=*"= 7f^K|lC^M]p5xxuL\O{mD.ĹFmz7Ѡi>+s:k}-9vxMif?Gg¿G[Yk~j/FΒ#9ַx5'~kr;;g38orׯj1adHmN;[&Q}z١OÊ:͒V$؀p1'Ҩ_<NA.9]4mwY- ClιgG*tWZprIwsXH8OhV{;[NR<wcx3, 28oե^;U A^Ç'I0l jwӏטˑ'ɐs2N  Z‡[u]F'eh4G&kJnz|.}K g9>a|{ IN478OřK54_eIPߣ|\=ݥZ >~ݯ<|};x}ʧ|_/>?qa?쇭M꫾&}+-n}#~ƬhdqB2(IʠGf6P2*}NgOoә8PƤʿӹqØ0$ʁk̛܇Wg(јSWe߸3 }px|V#\VTfd4tuiT3V%߸P=TANmW:+l{]ƴpU豏ӸuTL'x3ft)g`6=h9WsfΓpfXmq2Fk7CBtOnʌwUڃ!ɗɳ@ϙ/~ܕu3Iஜqy<~p vX  Rwuɳ*g*Ƕp:TMWIBکGM(x<+?̟j8& %E*i&+{55Z|xaسVq7}/`G_9sm~9י&[Q_!(`e~Iݭн*;ۄ.=\2~ xm;<p?B毒hx:rvdDWkgOfV-%ɻng+!z*zqo+.~#k; L.mx[Nc f#URH#H =2ti@HƸs{fHeqDHqNMH<[`l]]IQ`#pHx H}s`+1 HLpf?~wXם_׾G.)dN-ֆ8??O)W/_soͿy/˯տ[(G<?_ٷȟS2oqp`P}ۘK_z@A@#Bktd04䞉[@Q68'JwVtdϨy$33,ns8$c‹nա>LZM9xV++{]a3еYpc,н^o TvB WZUaY`?8Xs^V;OW{Fge<)7ٶz*Q󊘑'tb6Ӭ/k --fW~kgs:#OxYnWyf}kfLˏ_jOYSGprZiѱh OˡYn)N`Շm1 Z Cu}{\iL9^MṙvO|{5y#?^-яoWm'ip§#-K'3εLݭ_,L^ܟ> l=Waoo ,ߌ[]ʞ=,WKq9䈁ۑaVԵ왫,r3yJ%|!˵7 ;LNx;t>St;]\p3dZ#ǣ`tMAG9^M/oCmZ1%Jᖐλ`%:w. X nH7>R`}VhCMATOrfrە瞧B^n57):>3}f"K=[_ Ot +X4}3}i{]sD}8כaޞݾ_lοW~o|~j|g}?;D_k~_z+ ?~_']~o[t7,q?bu?_3e~-E~d3wXz~Oz㗟~駟~h0w_|7u81 TǎJglȸEK~i8h^M):zw L6F/X.kBKdw1nzK3j9sMl0_C'oWǯ7LGs^pC˿pfdA}8SL' _XhpFfдM-Ot b%1ĴoO IDATt-ػF̨gbqKCyԩ}is2~ǻ i%=z]d1T= $̦h y ]?J^;:~oNguj9EB-eEF*f$w.&?='c'lKv?xxĈ!xsOo4¯@sVKCA_"Dj,v"w1'H8wr`$mQw[uTxd&x"^Nh{ z,G&R0fsv:~Ow[p]k ='_D7Fﵝ Bp!r0}_Gl+6n%K<ZW.|]P?`Ip6۬JsjoҹW(`Gx9G67撣ɳM(\wU<뇟~q0#,x2OoT晶iY:[U=;Y衱<`5VB'AN !,gׯk3cK\$`ٜҰe:3>N*#Xoz~!+<'r6{ mf4 ̧3"7_^=>\{&1p"gz::P@f[wƦ>7]ZU`Ɠ{sOCn}΁In|Oց}o1l34dM_q]O#I{/׎/ Gz|PV LIwV(}~皌ǭI&tbk˟vX׷l=P]Zϻ0}V/wx*_Ҹ'`_ĞR'WTsWA?+ObYDP9JRz%b9?upz.B҇blsZ'3^as_֓xA_1k/ G/<9ux+J{ `Vzp^^/"ߡ}<Fd=7د\.VЄD^%)u z(.҄8\M8YmԌOFnR/>7FJ_r}iw Gg@?NGZ_>ז^|x?;}u'^/':?c<|?Ͻ_/O/e~?9oE!=p=|}/c?n~o{OO.?˳>{<./E_EoW~WNoX~wY0[ ~/nV1g̟_ u_uS~{4 4% ^/˾)]5/?z[ou}nqNYƠclX@qutuzŵ|O8`+>(70-09p˧z6-sԍWAdXO琀+xg܍pS=xp! o)ظ.,١d 7Gb˅@ˏ6y\ Qޥy)s80)3X|sf<_uVV?Ψg7V` vo Oi= w+]| \i=Hʴc5 =`V؟I<9>~6;xO3۪:=h\@Yщ$ŷZΙ76Afk2pMJQ}卶mu 끜:eg3x|zP +seRhF *#mC|u2٫mx8 e3']U&TYށ\Wjq`P!Vsۇs*mR,.$O`f" v:mߝ:8eF΋2{^E0gJ(-im+ Ĝw#[xqgȒ:@LLJ) \_ڷ?Q^Nз@<9b`+DW! d~hQ`;4jGOERW~_}_>Euzo1ƘC]GYg0 :^KtWխR{%#N_{=h{-O w}?8MhѦzPN62_}e/{` ߂khYCȴ߂ O P1oB/6T- x)RxT-0U|gD]Ze5@1B30%Hsl 5"O}ef=?SYs5v%* =\sWH4Uߝf48Bio"dV+cZԁ@-pf 5\}[B , G1=&ջAaիc:fNm_y6+A|8m4^r:~Q Wv`QV~p+^y٢c.(֮L}]e%[wQJNq:>Pn=y7ё=;a}gj<҉O~OgALGUfCNx鹍?%%W}[iNt`z$[9v꣧znNbG7n#ɸx5h+UoNMc>n 3uJGe(z^]Ng *1h 0ѳ~CnT#i;̑2fMr l=/VX^chmp6`v7ll/9`LfmzTA Ao 49v^1d0viNf{ ^̩v7yFֈ-NKx͡8Ui^V:9Q<͜G~$Wz9u"O* <:x۲ f7Mly+%,|?0it0ԧrpsm3d'r8x(ii|z ~Oo>>=Y>k;5sq}U''ƟxY{F#z$(#; J Vyi[xMJ_}{ڀ,ETٽW:Lm>Hx hrxIs_9|oyȒΰ^Uqpŀolv.Imw|`c \g+gax| z~ܭmS7 wSdΤ mȤ~\j 2)/ڒzvɺVw/|CGkԇ2w҈~ۊy.H6؆ոfoD B} U5$cd`\#~@_agx& U yxsbC;4/fEdU~!zUbz{ģmM:v}HY#̫cPLptp4Jl9԰νg?8̸Yzuomx2˳'PZ4}m8~$dkW]n <R= ǂSuWzzvu(~qWkgޣKwk)̥+^??Ejukuy?|f\;>=u_ҫ']˗/?_?sen'G( 0O?nmekK-c?{w߹m??[kk6OO3ˊM߷o~]mR |mv $ܮ7=h~΁!ݺ.^tF:n诫pt|=XQ=sU_[¿XNo @Z1|Nw8-}ir zNFHJ _*2cլk -8\WVB(Yc?*f '9Xspݖ(|^q,S={1DbAbgټG1^t;v)Z<Bg _o GNamYޭ=ţ8m,2, OP7'kc m4~G:59Y0|^rؘs>g,W+f+"US虃V\Sղ| ̼.0]]5G^dZNNMLnmO6A$;2CGǖ)!On$Ve3x>`E8GLs9sޒ 6sLg4!U2zl8+*zx%f~]ki Uf7D#ͤxٴ3zv`Y>=՟[j?5uyYz|]v>WZ8xL>@hSɁD&ۑ, <8ny T+933* J{f' ./Wlk]m>,ج}(=`vAzg;^Dh;Ӿ >(O̒m12}&G&[x sOn5::1c¹VIŕ<)YG,t}^v<8my+򃕼Cӗ72_Y U:ݬmH)m3`pTC/2y!OPpo<\GqtNe@.ỹ1pJf葵V 7}a_'N- Ɨ31yŌ9-p3&`U$A5W_!vpOD_^_ٍʠ561-SH-{-J-=i7z5&gSp[Gǁ3x"Zb dY~UcO$)<p{`V/3 k{<7U*6B`@B)\TV |@`vy'{.,uy/-|y3!?˻#?|_b'd3ʓoJWSOO6ݿ}9?\,v++6_;3/=}ݾw$_[v|ߑm.3|4ʯ/no? C;{:gi0#PsZM6>GW}߂9!f&/SldUSzq/ӫBM15c߭ӣ{p=ݥ͍ɍY9/<\Da81d Lt3z:zlN1sfQ֙>/4c ٸm)N,AGgkؚ9>i!ڍØ.6L1m p}9m8˷ '[ d pwL}4ؔ"Kͺ{%ق*<~-Tg<;|i 1:^<83:o2_*Gg_qUK{mʕͰ <#q$ YΡYK˪qq?"uu8gOK&9v}ZU0WhlʌN7ȕC߭,Gxf+s[",]_5MIO pxPbƗEVǂi埓j.foG9f!E<9}4< X 0fH/ͫVQ XЯ#j}ܫ|^'z! !r7u P0K.Uy3#';{ڀ2nOe;^ Z>z9'glj\G+^wD|Jn,=s03&|wH#} =r"+I^/?( ǎz9ZQNL(3p_lEmUA&zzU`xg.T8hZs@*7vp"wfJhL.m;t0E[ p {U'95f ʀUضq~y ~tR`17bƕt^ ?9jCr!kfaL5 :­`@7<J!Mc !6+;>,;gpeh\/ij_}4u< pҮ(ѩBwfyۻC7A8WFƚ6@=၏z(-Nߓ{K: hjY]'` v'+wnmR0ޏ&X=oEn3ljE׍fցUǯte%asV#ġ#ч>٬[|xђĵiJ#sF7Ʉtuf,ps{/{//`3'|/\>ޖC|]?G%}N˷7߾_k~d~o, {[0A'O~O 7sȗ{A//|>o~Oj?W?9o΄V9?Nw: =>H?ԁη0(;دOz4 6V1_X={xɮ(vU IDAT<3h>"\2>DP|v+ʣq/c]Km j+imSo\(cYۖ<`X"!qf\;'fLodHt(g5D4)ukwo[-?Kkn~?_ny69}d 3gv/( ʅGp~S9M=%eSj_U> 9i5u? ֨+[[͜?W.m 8J[벫* vt9_xuPlrʀ^m@SIj;/UGspV!~W|,gF gM* 6qgÞGxp1g8͌́nxs='؏}T'b>A 6:ցߩw2s'u*{>κW3ΉNGzX@#og!\ yۓŇW?('@k '[zU_h/H7a "ח>}bӧS)Ow]<4Jʐ6њL6x< W6e_)h{٫Bf*4G9xq#`\]dV_$Y?@S豄?쒹p-a8q?6;\fP[ǣgm|q0;vi|sC[][_+  |P嫟:eX7%A 01֞n L3bC'%\8R=%8h}Õv:| ('8Yg_zT]=tQ]lJsV$fƟrwƽV< BBXuq =:t;'x. ['!+k`kuy)s!.]:3Fzɾ̔7;'@eW|ݢR?ޞiy}C/^哿S!O2ޮ7ü=}7#o~^w{)3s%\~ď;U}'//zo}ou4 _+nSm:7w^sG2|~7{S-G~3]Y0?Z]o=}CWql]4=!I縌#'k3|;2.w\{^3f;@7lj1NXXܧrwԝ8z'cqiW--532"3Z*X@hb ˻ا:ƅנQ!6ïz+kÍ('t.z3 lcGe`6ߏ>e ;@cho{_VfPj{YFc&'8(11AD,":TVVl a_8[ʧ6{M^]z ,_<\D3<_^NL'EQuݛiv|)ݴS弝)UKݦ~r2Ðlrfo?\ ջԦѿUqk#AQtY\?@H8>[FmAu{, cĂo~X6&_84~_weNk[j/|Wh h͙ǣN_o[/*:Aab?\O:;4- ' JjCUO:۷\ֻ ? ,@3_HYWz+Wo-CӶgvLicurןNz%er]:ɍ&V1d>]0wŻMS@'2`vBtrqŤX1lʼ#i V@Gp?-?[-c1p-. U)FCywccbUd(ωFƁ,g:uuo:2/ۣ΁|թm2FLXV֞JIoy F(]6 ϫB g"tGIcg<򎏽{DF g+.rsdeJm=mrKeS*a:xe=o|*hG_^|~VҖxL |z>ӾA|oN{q߼E_E9ޛ|n n?<ڞ+nn3o~sF^V=/\|v `=qw-0 :`Rt^ёg`)WeeL?l5ʑʽ3馞Mu 沂׍3ң{_t͞w=^~^s06^];A Ǿ7|t ̠ՓyC[=,vqny 2FG=v5p?zF`u-|h,Ȭύ+hES_ï[fǾ W\f6(\Y#n[ZK0<3zkfA#x;íIbbl-a! ImUmC =~W+^i&š6i}㘶i6fz$ݘ_X_y0+ ~*19E{sϴ^vE(3)3cjģQcti zjȦtA|-C=~'݋9x37[KãX96 ]rǣtY ǫ,E?yA H BrN8F$Nǁ_uɏ.2ӦK[s͎Dtj@[W85Y_1:1\H/R3d]0 r[Cv\}/]v:+398;qK+<>SxPhhmwyTϮ8gФ^dV` ~hr`Ae\+N =aA)-d&+{E[Ud`N뜶p>]s5 ^(7z]h9ꍿӊ~~ 0KO#4C1&p6PX`(:'ڮ:Q>u g{ pϪ/b +d\o|k[!i4wj<+8OŁ֗8`x 9ƕEo2#f{ѧG F3xK7>/hg(xnu˂݂ wS+-J;҅ ~߇^c\eHqhVfpè-_-PVt D]l92L9Otehrsu:"ڴٚzH3]>bF#Aqw?fo_8/.- toZaNzܜuAmHi.`Z+_E|/l5| &7W^>ǭ{9!7 :ۘsr%\SXYL=="o=tkكkeWes͇\=T~>c0ќF1I$ mBT~e zN0n($l:'c^p@C:SjE:JYިp}Wz7oBp:At%!mXw#;^@9A`k jL]+Mj158ތwJ~x\o3.`~{ᙱ?MNzoq^@-u?Msf6:n+j&i1d3]Wt$6]N3:9rN5cz)e>+нs^ [u0rcX0>(a|$ѹ 9c]D#"z]LӦJs8劃`d 80CpTo{^mV}~(^) ] 9F̱f[>X})1]«̢  *3@#b^Y0 )xVE?wQtP=)N-3׶G/tJo oګ|"i2_~]GsP,8^{*p̡f g<;f]vjϟ;9` ݍOD U' ~AL e8 eܡ zWRj1J08|I.| W?!Vv'o}Nm`hx2=,v?31YDt_IF~4=';t3 ]s"&PPwOuHvXa7NhG'/`]= 0(4|]*V_}| yd;o2w?i=jp9alPd`"V/ZtF3JDT]m*BP}JkO)B΀DVuN%C-Dr:RF3[rdg^е`&6"9vs +7WbշhB軬16rˣwHƞߝ gFEk;JGDk7s]ye@lK>uO#vP6+sV k"ufe VoěL|h,ߌcBNl8AuƗ"oV dKe#e >9NU-#tO)\f9(V͹-o7uŁ8} acn{<jۿtݧ($jr:>Bw3H{t{h_[y{oyniƯ%~` s1ગg{xA 15TUK\6WL6.Qo@q3c @t|c 121əwbG՞5 9uڶeūfXlkYa6xp{j}y3?x 8APȚUśnuNO|aҽ {ϽRfBA.y_{yVP6vGZ!#Y3߾l&9ի;7#| m/]g C- Qr8d6S/iΪ񠀛|) IDATO{sNĢ p86yE%`w..oVuT»/*]/pP/4w?u9jO9 {HWDWo-p'bE{?X<|$C|r98;o/92Ν G 'zu|/xe܋SS~c93|n2d[^.>;^ a/F#hMoعURѬnA}Q3}|tZ5~f+=Ol-"'_/bUkMga6v|#U_E-W -sz-hH͙#="*]WhOk~vg<浫T:&b}egW<}gNGW`ļS&O]=  @`RN3C{5YbU~W@INIt0:k#ŏ<wq s">t3,Ɣt|%}VG_A`g o8^yt#ysNŋ_)0o9 ;gL-ʢ l;H4_ڔmpN$Luh]}oȷ[[N怙钣;vN qe hzm-,:Elgt FT2̸(_Fe֮G%Zc`gH ̖3@mW`XW17>ݻKK\Zn%æõ1{1qm;ý P?+ /`ۿȩYC5\'${10֗㑜rr`cؼ^3V]|42V'["k#c-\4JG-5 bRKVs߭c]2l⏼٪sti5#khۘ L^VQ3\= M^9Ood3$Y/O{CJe<"]32}߶h1.'צPLJٸKc/}z 2U=xJ̜{*#Ȩݫ9xk7tTٍ. mo:z˳sbOv&\ywˋ7 \2+Xh+tv= /~mXG`BN݁k7^ `f+W[P^-V=ظcR:MV7oT($ۛ >^Mu}.|z&آ] 0]S8`كq+F~\s>ʼ{LU.0}0C@SaZ?؃7& Gpmuy:B$}Ƃ@ 6p _16SAu %@^J7~`:~ 8cP3oӞTo'W1!{_+V]:.x5#L㻨Z i&(4&xP#2ċQv[݇=s1>~$Q fn(ׯ%_%B( ɗe=o>P,oq-QKAb7܏}/?Lװ\WKV)S='pFϣWn |MQy@=p72ctpNKfXAqƋtUzK ,ϸcuAGh]ƞ$?Yx9y#@3o!<ӷSe4~MpZf #dU<= oK{l1?'%o89ka3̂5phc{ٶhyY|Aưkp9L\φ=D5Kf[˰ 1wmG2XoF8Dd,|Y*s "q|X3LMۇ J53*ԫM-3(҃?'(6;Uŏ$/Ń9p+l[9 hODlՀ5NBhybe焗o7w{NFl8 ?9S̮S)qsV;b's{st8>тGzMB7ߨZW8usv1翌 0|"yi[]f+ T~jbro[!<*j4f8;{{@i?2oUb.f9݂бAuCl)pGvڊ&trB6M|AtjoэHu~zkɄ/9<3-NG{]VX\ 6Gxٯom c hU,޲[!Y>;:{*W}4E^MͿueet b 4D@W_]vE{DVPi@A{aX`@<1Z~`.&^v8VDs 1 1PRڶ' m_^n|,!E{r.>*Xu}#O'@hUm#SkS_gZ~+zdat4V&>^Tض P^\dNFx DZ{:Cx 1)&G>?II%׷1Io]oq-- CpӅC~ ,>rWzAUt+H7&ZoYƻ scXoaڳ|-|gOfl#wxq-ӭ436-N>ݣ끌R0VsyN~d5nY>8毴Xp&2 wxNJHjgZƌ\fXyp-stf|uwinu!1[9o<P0r3D?k6p9s|Nȗe9#&,}c݌%##zۊ37{͜9ff)>|x8&#xg "kIr{~l73\z\ڊ`d?pӿQYR"M8%;g{I[w9rٔiec0*& $lFf,Ā%b(1a ٦UX!+[{L'Y)*{wwg=z]z QX K1_]~ uˋl`؅7?۾o[Aj&:.OoŻgtO;Y NOSjwė׵5x6 ooV(=Oh< êW9ثs3&/4,K췢+zx^QY[ 7bp?[Tw1R̶lf\<DG:Q Le|. ebݞo0e}LտGhgצ1yDWϏNe +MZy{+d<@8| ngx2 E{)Kqh@|fLKs 5F2WJQY+$WR3[-k{@JҞ-<91c~PzYguRNj!`Q9R`:s+iձK!Þz<ߊe8Y, !Q2yЂ:>_}ee *?y|rfub]S(8GFJͪٯ/m<%I-YW CP𾁍x6%F2ι._^/2_Svзu1p/g{?{dp:_٫nՌo#pԧb?1C8φe`3}]gyzҳGz)hȀyn=>ے,|u?9{ث9Mv-pifn+  f?o?,8=olxmv}C>W>YFM6W>*kXXA<8l _|tu:~k cxoE@3^`,8g^P1ޚy /Z,l֬glW/E=9uc7g>#p9]qr̥:' }^=xQk J*<V6ײ2-^*23W&MWۧ_s?5:7a/z#`C/) ˴!&1anp:B.=Gݳ11<$Ϸ dY6Ke/ :8Nhu˂ !}*ڗz3Bfك JB .[m%+sg/ U2 >YҺ53w̆ͣ?1N/4,}>Vpm]ZpsX[ f4D 50 ~a‘ D1ۭ/ڻ{z#}^u 499:4m.~yerW<.A@C;<I,]ܢfA +gFL'Ou |s8][^+qќ!ehUF~Xʩ{ޖr 7yҜYclex <3tKW6/ٽAšhJYe-nЁsU2sҳ< e<볳k K:Gaes5K7^I?譳1=^"g;  48p_xNƣS\/U|0Щ}{D̻"_D1=Nԙ 7m[! m}B+=Vn_0}.D^Jv7_ulxklixOhᅢ HԒNnkeٜ i#(5r.jҦgp:tvrlѣr/P?J4rxtV`E[Bϓc~LKۥܿբx`}w8 ty Gui{@&9p$vgl2koI7T7,CS@'}F67{0c0.j" U J˜H`B[0{r_9p80ʋhw #͜>(φ=%lsJxuàv6L#o>bWI^f}>j+^ĝ]{&c-}JunF}00vdf;2ϩFKwt4ܚ>e哎/ښe2^7ӄ&! %GI奔[8;`B^SccDKv.v}I ${oJ }|;hxtlhy聛ҕ, wIV,] :& ԾN_DyR@&*G>C{L>%pto]ͪxEV(`t 3S|- PJ(Zu`ۆzVJrހυHxc`ivOנ΋g%fT`ԋd LGs!GXO.a2E \efeN&o dnuUڰ` U V\\U+hOm⇶$G>F-,'ӕćtv vCڀå--To ]+pa"_?H[xVw;fLU~> >& 07o.X/UkQ& zbp&8}sZh9-_ Yƞq= z}4~Knt)7Y݊ģ՛l؅G૷1;@B'ɥzƣ5+vp),\heH=~W>c(jg@#U|2S~KNmu8NZB\\u7~ DF\e9w%lNflx-M H{YVwtzu=<;RygMM;okwnV8mV07u()e N&vϻg}X}6亁끇[z9p _`=Ds-̆ǠHps O|Y[34h}캾2 i C¡^skgFr}}f{ҕ=urx ;2k h߼ >⧃8w ^Щq"Zszj]$ 73 @7q/+Kls˻m%sO}k\MtOmW=;mސѿkM`}+,TU4hym{[F+<1iz%p qzg96v@V`c\pF>.}epyU6;WO0lP!X68LyH. iہrkI~-Z |d7Str^#ot?AGt29\A?˧-'3[ FJ ;.D/X [ЮTj`v M`7bw8=5\/KW ~Α&1f[=^~%Aks>|6Ϋr!{骁={q3`P~ϵ ?xt?v>ByepMg+Kod6ve^|wތ蛇s_!>K{7*xoz#x{qh(U%8v@u*OvHI($uj)a'ŀ߰*#~RQ4NΘ7}W߭oϧ$pC7=]s|gU_  a+ʏ5(+ eGʣ}_g(|8z(}/߾H^ChC7ZT!τpT ԡuRoeա:JGGK]N%Sm*:wސ/ǿ&; 8Ga+1W^`Jhûs?+$8xρ?،NԳMD-ۜcb;#ۊK̂V[,ػNm%A{/?ogrC.ٱMYq4ٻ+S`3N_?[աpV<ݬ tvSgQ =\] +ZHՠYqVap7̩A^.x>#uo8Q#/cA 8WY}0\@ 檼K0i¥o+<'9ѷؖ ?sx+Ȧ#gp;4K9>TJ4I5\jԌO/]9ý)as.+&vR X ?P{O_ҽ,&C{Zh&3<[r Fyڳfn5$O?Y< .<8ݾwCGÓ#JQWޘ^ko9<?cn =~3K0܀h7{k5Mz`CU|+5;Kw~{iʑmT(ހ{ͬk+Ü463^ ZSM#n8$Ia o?jެ,]t́{ܲ}x,45 m';/ MrgM& ZUf`#lMNpvK+A`mK ]))rL:L3=f^}eU.3A3jM%-! UzXކNLKvb3P ^({vVkW LM)B۠m%oEJ ZN@U/&e %ğ~ʻao.}ޭpf@ ҵJ~aFzӦh *]ۤȩVp۔s{2jz@E98!Gt4& L=x{q}ȧ| &2.66Hu#^g1vw$f!^KioZ8[) L$ KNN̙Oqh2 F12ʏpL .K=<.Hɕюh> u^gPFk'{8t 7G?˟s| d?ꞁ<1OFHɇhw8?P]Z15f띮#L77%xxρ97فKgG؋ٰlOs8`^pesRLc &p ;d9j{7_K=b3s8.AvYFqY*Yzf Ze ɭr.Z,E B7]^8wU~L $Ӷn֯S zy=*>C%Kf'[-h~n:8ОeVD?{ G yax]ֳъZ6ڼjnK_> .~`"4M_c.U'vAǑ&Nk ޜ`3{mu0cVZ}*SVڻ=o@s 9; E$}Wf?_x&XdPpXm 4k,<ÁYD3 罡s̪ ht_ʷ_׵ۂ{n7jfu􈼇t/9:PrIOq|*d8?ÇhM=ᓛ\5kE{a)%^ @8v8MN<ʏm'<؂C`qp'E=v@|]Tyr[^,3=~ڨG=nS1E=wV7={?(1tfUܯ{3mw[amd_^L" .ZZL!>=Ao4lKH &%γ#(^U;9<5|_m%U旞:4٪p5A O`q3ē*,_r7-ߤgЁ-\Q/'?Vˢ]l6%olN6tvcQxUKx]+Cz ]X1Ix>tb'QFA^]W9?Q ზt~?I aG2֯$c4k;Cxo }-y/<x\U緀fՇ'ko=* > ߏ~xسV@^AݧV_4U3Jd9:q ;!݃{ǘ k͢7pJNל=b۳]m I03] gUM$aio[ufu.Upp]lقꜽl  "sxŔp΂>3o6'xKXlUW}V>:ϸmE mƣw) V8_z~}^K LM»K`J|dtHRsMl0F ױ`'=yLyvu ~n㌮ *M9VPǩ^ eiչ2fErG]pC瓯 _B{kV6gu=3ز>JrwW:ҽm-8`p hYk~Cg)yiƥó=Ss<|tiAQAޑm_>tG|E|{у_H ǻs?@Eߏ+q:GZ`q+(==)`UobOgjϓ]"4Ht֝M[TИxr{ 1I AO/[5+sA=]љ|mv<0=Qx%Q'^ ~^KKOZJyx<- HB<"[r*\Gk`U_Y;s¯p#0}ٹc(MWPnUyopk0·ٵ^lP*e#=XY7$:6teɱ?V_ዶq=%Ϸߜ~]P'3cik6Hq`!N_}y}ܖ[+Z9fd'8<$g f\:'2}frX+Qp B@b0y3'O 6Ii@}]dV2UsnBy ~د  &6 7Qx ޜjK`^YMt^oCN6gb6?jFl?p g}9Ȟf҃1^%<љy&-&s/+H_r䆯xwzēNOyI!] L.@Dta F^k[N_aRxQCX=8opo\A.yGaYx JW J|= t &EpV,h=ѦM>KEn7uAPil&0 HJ`~ao~Y޶Ѵgw \ C5x{+|揖o!zmT%9e1$C"(tPr6̩llٟ7*Mwq]n~ogL 7l9|:U;w蓏0;]p I5Y9vh>y1 xFn6A> +~~*gK!_%0M%N?ӞebZS(E[=NkCgo/+|ZP\5=+7X٧z⧑=\@}xYZ`>z# ίjoݤIKxxi [Ӈ5z}Pow2Ou-%V_Lx@xˡ.Q!E*^l,ُzbnf_9$ "qkA3'fe;!y7ax8\F[tz}.A}OufB9U~4i,ʨoN>h`@ʼnOL&e3Rtϔ+E.mV,+a·e#)6d,XuotST= _PΪ|^0ϽCT IDATzmpt+[۳rE" %/}=sq]>Fv&-ˎl>`vnf)5)JOTϭf&T`t$}^?侴+{A|# 9ߕ=h?wmv3'X?fO@Gx?Q_ǭx_*k|9^LDNև.`dbeW{2gͽHn)ndKٛC~f~#+yc{fāMNpLe9[W9x5ނ菞`h\ 8&=י/p}MfÖ8_)Ӗ '[{%?Aٳ l`9܃Y ՃVQ/~ߥs- XV 8:odϞNR t aw36(v9vধS{3j̻nrjP`tS[|<~ -F ^=6^m9'&h^@A.?=`|!A>MQ\f+b^^^PZ'3?5=דdL {v ȌZy7o hYq- !l+ҚEg5876$mmvy+,mRApf%C й|k×^$ ă_ܧ/?V<NfẟX(~9{>TyyS'rZD.bGU֏_A>Pid(:r=F s$$T8gx d0X]f'T.[`x0x'e̖#!,>n!R"]\nQG4Z['+/o_agS(–}uUZ9=Z+>l&[>Oxx#Vn#_=b5*å=ghSxM\+G6ׇKDzρ+`,}/ e{f9llU]fSGg{@^93VI4fGo~uu)A7ԕ[:m4 GjuXBT"Nv/6' '7#KVr8n`Ͷ(a#M0sb9y> sZ7| iegE4rp䨋7f6 z.B^i:]&ˡ1鬆fw?MMpϧ?:XrdUqJt6с hCTZl{xUf Uzme쩞T;:=A*Gy ud0-'oF> )z+7OJ4m>e>sG~񓛿k_6[J4-nWo~A΍hBԶMm$ ~O:boJlӂi>xi CI³n@o`W? .v -فOKNKs?;ܠ&\_W;[U'Xշ͠2tf^O>Asl `\㎗ao}o 2>leڭ ѯL|J2-ϲ/ҳ#>lky̍6^eSizNFгbPZoQ^}9s.PgG1oJT@&$X8>gPǣO>k@˽bZlO_CN FPP:ؔq7B=\(5qrs 8u~6d}2:#, :!>ĭ$Hc).!f0U6V)- HC鮣{7L?ۄ{![)d5[_lRױ4݂(g_d yl~6f3DkʧW6,,&2.65mo ([`idv;+)g@{lj1 ld87⅕Z$͊'f53G}X7W?ڃ;Y+m{0JH\_S^}OHb>Bdj ~kb>MoQ:hP#_ gp$U R ̕r+W^;a-`u Nߧz׵s=W&X6ʂVx-V^[ W>ar?i3|!Nefީ|щ7 +ÌOڽ5 aK@ S wQ\?سoe7|{@81C@{J:+lEʌ=Cͯ|-?l}ܡlV([rο)}+1mצA "7nYn>Ϛ)4SQ~G Iz=Dx §A ‚,Ȏ\ m.:+'؋Kai~T,1lG? & 2'$G"&̘' 7<%2StO֮92{C88Z(9DOەS6zԽ.WQ.yKև/ fJtͺO 0FVxV^DY d? '"}b[sFi7:΋VF^KNhyCʂ5hOKw2L)?,͐oF!#Gm1gꡛ~6|ꀊoxŹY#;š.?\?ڌvr?o~'zρ9>&{5{FڌzVO=!Wy[J3WĿU+5cUroxu^vQ~<4@ᛜfQo g!=l7Z޽3}3&x5׵I70\fk.T,zh@3[=R;ٖxM*[}r't t%HғHɘu< r#| {P=م-׆\c/4}e痨}3m6K[.}eUy\s@V;xQgM3z ?)~ُFmoF|@xM`|Ϭ+Oigu%"C'[]|(?`"~&3A ;sӱh W :Ch/V[ԹԓUt^#ٽVZ`a{ ZK] G ϾEe/8F~ HOHfCAif9ZUt%%< p ۍ–# CJNSQ=>*Bg7WH<) Ry-ǫp>8G(-S?L?8nOD;v8%^CkP/T@>O9p:@]#Jq(%uU r{溇(Osغݍ)e5YU_t)C܏ce-ϥ.)xN~M.%^?H7ԟZ {9ݖ^٤:lRiիtJ74=iև 4 XvUG-rȗ={ ~F9M\곲WF1þ[/9/lssttް{}~s4n`c?~&mlm{>Z9aѩwhP0|;dI}Wٳz5@wy͓i $Gv s_B*gcA^W gO?>"Os-"S؊ʗp~[p] uo+Z VYN<~߫:]P4.hBG͌kE vT[ Ih w+Ш8v2Gkmio&q`l p{/o!7 Gkt[ɵgy2Z+ePE >`+70ZP 9 {C=xHr=O8̜r/x5,A@ |9  TvQWpo QUWJ*ʘM>A-#21LF OA( Ƃv+гG$ݫ o̰n*j jdG:=< y̙-Wu-%^7B>^'h`Vd[e'Ӏ8gi+t zRޯxR~4-pes[-:L [:GQdKZѩ6,LLf~&"ۙh ap"?Af^8uMMy<\ ^ Eylwy p:#meC{;Ǐ,وVgI{e{]sY~}B:' M֡)dsh೭ߪo+tx=y {)uhl / z G]#vbF{H.\43ހ `^D?rAzEOЃ5>}"_͞ٻ8L":z[>+wzgy.u*vwFH+Uʘ00*inf!s uAr1'[LNVQ:/m K22͖`]քLD)ePcL1VLs.u!^!!w\c^Y߷~(l?ց8{ oHz8o)²Qig@Ovty}FzCKU{Wy6b|f -o:\5 f8]a3Nn5pi9 Ck \ߓHb4u~e.nY Yk%[2xvg-|z_P_޿W==yda=sW|ʁ}/ 5ԙ<|μ$wgH7Q'ef 3ٽh*جri/q ~?xZΉ**1RvhGаڂʡkiUU l.2v} o[Ah wSvefC wavl=3: l]ۂó@6 eex.ptɢ?LM79~a@Co4m+Ӳsc-W''wPFȽJo N7K.(~#0~@RG|8P]v3![`>(pu*iCJZŰ +]P~7k_^ fT_ȹ!} 9feͦˍPMu?n~׬;˾vQ=$]x17 3qImL-_R^=wHE_~lf-'*_-v0~cn-uMSa U:Y`I3ý=\ )4vnFI9Vk>,(z~G# ٚ~Pj_-֭Ґ]pL?4/@lI93o,o)E0Ioi$ہ IDATԞ쭐z^ Tş(ьK˶].ڏ2ҭ>JOZ 8Xt[em{;]fǶɄvo`pvqf^fo];5;zKCnۍ^?0%^ [nA>z}/%YPQIZ­ԓU \کA(4'^}bZd>+G}'0 7}|M%t`&'L1Y٘͢?|gcO Mk}FZ]~xtquMO?:Lcg!=9M@꥗__)|^}Rvnɝ,/fa]\u%)^G\ș᫁mSSA,;24B0πOk-_6(}f;oӖwh*[UXƵ8Hwp. |[n`. K*1 E'Y֖Pֱ^pO+B2iQ9ygfI8F4A EKu<@ǻþ9diSx$#w~ b/DQ)xw8bW9Sn^p{f0BG)t i-ӶwOhcWhYIG{{ޅ}|i _n{¿f5*?!G(:/]_G}wy[;w~oo!~_?}C~_=s`ٛa6A`˱cCo,dlzOS0e7,Y͛tC]B3ٰ;94[+ƯfPQ62+bfo}Nte ֚A>sPSyn}a~*(_Solk@Q4 _=@Zt@^ןn"{ñڵٞawK 7oB=^")X\ [Psc~`Kt3l}Q:[ke.x>[o xDΜQ2ؠp2wf<,.{n8h#?P bH@/Pzoʸ %Sp (Ḿ [7'[.r-Wo-?GG5lwʞ{fz1I3UbSPu ,kћ,8?eKbNAa0?9y~df+=n6_WFfz2>h٥w/>Vi;a wEY $xAG/|M\96щw:sBƒ*r!= z%73[1a`$ăFUh :sM'HչrW$S^_N`WxoË|Ƃb(U;tmv)mh: d/Mn7miQf@/.Ig9EvMNһnPuJSE`}z+:$ BI0Gލ~tGXRdl?PgKgt@UNL[{'tn{D?Ŝfzf}vauh(Jg+5]Mne]҉^oe{ռpHWv8Kף$q q/@]Wi)ߜr} 71``62iLaњIܳh51 |Xo+R 7Z7Cfeb,A.q*uof;z#-Iٯ d: ~kW {JDyFoJu :)Wzތr~t&eshJ2ٟ54#Xh/8&O<0r0)U. gyS Y s_ 6Bݵ:4+/5]QO?y7JQϧj?N yh`y?~ K^W\N}?ˡ7_?8 ^ Ł|m\=.sCrFm=P}\2sICWxN{X, ˱\lfgԙc/ەtv@wk@lxmŠɁjl:f?v7wU-q͖f}0So}pV-r0EO`9N@a3~*[neˣ[:L` ʷ| [8 ^)KJBCGu3@q#;[9f){Ro/w(4R-`̴nO=k{f={^i  gk{}@Kcx_jU*ȿa.3X/|Hm;2 9ޞn?\< @bn|ʀp[AW-Nr'70{dz}^|.ĿpW f&ܟϸR[q h>ٟ-4/Vm3V:'7,|IL\<N$=Ƈ V}r_ rfW.8WA4XpOL>8.Ujwk,߭"am:v 86xi6 (+nm@+:00|^_|iwGx-NJձx3:M~_,}MF<`e$Sޭ.zfյrFq2v!8 Ri_ i. )QiQ ,Gmw_w)LT~Éjg,/f@"WLY}~gx�Sch#E+#蹭y>3xg~a ֌hQ>:?ҙ'OUQ| ƣk{7át\gʟ`qN؏QCw +8,8{_pXK]KB6'޷b g BNp)a{l*CyI߽ONCu,Wuz%hN}˳읧^yq-ˠßӖUՙoo/Η7?}g#_7[7o|q?+-kou~~~?K77ӛs~ŋy^oo}x#|u˿O/F?9wp B ӴvQCȦ-{ٕgz.OVN2MCeo]8vtdf~7 nU"' =XY0~?:ye;K-C.} pᴥ@%3o7kT_,{ꯀxoFʘ?\^I}rfoq@crgm?kɈ|BJ$<>3H/@e=!k G%Y6HxA˾kg W[ o}+K§V/yStƣڒg%V?|3~_7L [Sf|{K =DÑg:x՗tۖ[VoPy[nddލYy';QQYH ]@>m&G? Vf<:nrDZH?V%tCCm0R7z6dUϞk.UΆר9T3/a |3Ol**.o賏uAr| #:}znYZ<'%O6D'bY:d9V/weailz &]ݯ / Ih~pN. 9x  (ȧ=@/[i O {{(66WY%Ŏj҆/ 򓕁 _^CV5ć| ηK凼j>:O|r~y[!qdҥgא%HQncZ(E<7z .&A:_7?O?~Û7?_Oݹ_ |S}+x=n`&e! 8v1C`l{=ͮpLl4<ϖ pTUl-lW-- <|鬞K+|Wl>9%_>l}\D_Q8p&T9#;6Gxufʿ2BvA nn;zCoxwoV~Cx we8 53U˙vU;-ϻE#= `_p/Wmڢ"[de<^po&"uҩ=;VXOm; B"gxU z:oK1zV8œh!cf\}}|7~H=NiˇsBl͐qm<憐ճNӝaZ|׍x!]ݽ|?|<|uGO:wh^YL+88ëWxMc\ QG:| X\+3${N#JHCI7[⚑b'F+ă 4 m:«s@| ݟ% :Hީɲzb ҳvH +ݢ< ?| DiPr:Ϫc<^,cXm.?O *<%dڷ= qd'OdG1>NY_34oɣ u)P剆S#3q᪾7Uisa̰}/<^C/G`3"Hͻ5o;4l<?Wɿ-@>xDUF淾zŇ 9/wڸ W3.~RgddDԵŖ_zͯ^le7_?_rG W<}_:>S'`ysok3:svZ?C+=SroZ@!͑܀@?>ì?c({lg%nwPחIi5=+#ZW7qh&uUh@+N`YEr8g~fvQ IDAT/_ AI8:Ԫm'!kEVy.~ݶzeyo t `=hc'}U0] p6^xlc LKV9hs'yB2؄{V/\ӥ2 $=wM[V;\dJ ##qĩs hg?yT6իi~3pSŬ+j][62;Ar{ˎ7%h6D_Ox >۶.myF;h%kA3QiVW4zR6R*7\vO>o-oj-~Р7CPT'nUĵN\jm)GHt`ANݛlc`E\eav~p_ cW">5`6ޓٜbp4-X0dfE|xӯk &KVS ٿ0Wۙq 6%̼o:b.7XG[90Zo7x J.eR#π' [ekQ LU]ʲo yTotz:9 ~⃐\O{.EQZL9 / (9mwXĄ Q+6ʼn86KtihSd922h8~RN|x{=t.2r|f93&l=Df!vI Ά іc]IF7]W[W=7WS(p5Zl!(=YQ >y${3iឨeOt۟ϳnKU.cNPmIv2^XON Ƴt}΅hrCv}X'[Q}F'gx_R낂ɡr.rپ֞NF?ˌ(.s "rw~Hl=m9X^z4rȏ_dA~^.Xi-.A3|2§h,2Uz~1ih#7aY~AיVYͱM|*3r'#) LG+}kN}Ueu[Yj$TnG; &:ދ lѸ)k`n~q?ɏ+HLj^qbDA(#@ SI#&TKp$ڠ7͟?EY75V.6Mth4h}v UٕN :žl#`ю7kn ѳ%YpU68 UlC4 mrh|0;.%?| coGXOxKoa^ 9"ot6ӷN 40]@WzAģlљOO{}GkDC3=[Sole1l!5ʞwE;&cˁbb3§fvLXw+diJ09%^/X%Sΐ{PyU~>K {(_DMXh?bLu'9 ɀ;xʲt]JʰWj l\6~_ߞʵ`BoE2Бpl5F0x-S9kv[$r`X _:+.LZ:րT ξҎ1̎?kvr+^.@ly]Q3{ݹ6WOʳl`pWw6ș_BkѻUp.Bu [(},􋖾7)v}h9z?v"gf{ó\;;.>6 !pKcS{Su՘K@h(>p34n2ҴGmuimУ-{X YV? gݒ79\M* o &9>zlW` :W}GhxӾyIz(׈!κ#KСOsR ,]zzz[nVGqO$3ʹ~աk?P7{u}`[.| \;0'^54E ٽ/ze괒 QO ؾ'~=å3@#K5@͊4}G: C4W[zJ??8}|N^>Im̳.;Z _ @`[{Ts>:Y=t&W[QɨgٿsfZ6iPy 73h^0][)k}%X&#{! Ay?zpGc0.&Wy[ bL4 VuKc YG5i7}5Pt mP?YWc@Q0+ciNݾrN8QTQ"H(qSCgs,)#RGCSS!* +W)}FJ(s߱XԞCg+p:)y7K 2{ I!Ïn>, z[ь[9^zFsDlԋo@oRlp}[v sj[~oga?pN-86ER`ԡuvRԳ[/:,J,XAγVEo|A}dz9^7_f$bɄ7ۖ eެ?6W Y {ox@sn4z/{͇Pǿ2ڵ@O VW4*KՋBxUd_ .@S[fLirůr}M .Y[ᣂ׷μ.WW/ۡ}g9݊A8zq|Z. 7_ 'c2L Y F`6ns~ACmVgQkGu-)&L- ?Tܫb+忀}O e`3[P/ʆgt7s,1y{؂!rKt:q?zVaI&(A|U7YsrD&$as@}qЕ~fl\U@51 H.g ,\ }@3𕋷wYn7 1|89Eos;Ca_x5Q;FWf\$5p閲? 𣏶rE3 [ LƜp0/g\ ?wy~=Cpp|[ w{+r>Y|u胛w}qWoY]z/?;h7ٰV`aEL#s 0{T lɵ/<͸tY3Ûݲ]?¦e?6m9[8آ\dwy 4cR~lxXpCp-'omC_Pf Jc̮n}8;ܿ{p0+B0=`!_N;zǮ/qtJ.x4]P6'8G #9$K:̩T76\ :rTo/8AVY÷`Op`NV |YVЫW~N_s͠ r樇u65BK퓟ҧ+d^?Y괏0HE8[}u6N^GY-x6q ( oxsd/wmvs³,9Nز\[>i)=9|+!^Y_ +ȃig®x:lE.C鵷^~A\]?vl8 8ԱYР}oV9=7kyt"h/8١gߞ|tD M8=_y` zX];wDA|&N5|tk{+B78F/:69wx,7`k1 +eX{)4:#פwdV~~gr0V:-''~'ziU?A3jMR0O92n`La+uNMF` пNfl%?W?1lƗVu.G =4ݷM+. Oe[pm{36arvJ*bKt|ε luy(h}Jjyi[ONo*K<`{$FkO3\GOJB }t_g/m1OGV`eݛVwQ|"\@7Wտ6㉭-VMo], 5. (RqtϪUw yPz}\9et4TJ_=q aoxUt=ʹ3;.I>NO0L-\לU`|ű] Br(]d-v`|f ; \g6 Ŝ ~SffWڣoe& m ^tbes +͟9V%`D[@;=-[s{9^ kus_*k@z`ze߹s½ P\>B6/<H̠G|p^'O(Ndue?'zԁm_u5d}ץZO7 ҅gv8#ZM7=u%ы({oY_o,H7c#,mV.q"_]7OLP=۠#>}<$G " Xlyjdt.,2a=h#jq1Ώ ҃Y|ڲ`a`F-ZЊk7$ + ^GBm(OR/9|^U{2 !vYm]wK[œϕOu-tK}VR4|ֿ8N#߬`de[|%ёncBPM2Q4+rL~ǀ '@|||Ya~ d_0aTh3E^ 2m|m A@0ӗ/+s;K-W`?-Y6~6d+R>߳GXxOكIsg"(+=ݯ-J?[/N3M3X8Z' ܩ.2hma>':u|o }c3bMvdCʣ}y" ]HYCB> ZIٶR IDAT%Sr VX^SyL'd `+,_#o$72zޠ![!xdS1?p҉7Bv CmId^4ni{88ԛ.@k\B7p9;-컄S|2&o+ߞ,"ٗIw?5@m! 2S}~ >WgU}x/?5 d_tR٥hm/\,1̉^|^]Y{r f'wu0Bݳh ~  ufNk0TN?ovvRDCTLϱ8ep9w'6q ^UocJY.UZ䢩&pIF!nSAud GZŎ &N^ ~ܼ}~|ή"ۖ$}{h_ڏVCl{[-{gVLwy}ן&So*7@ r{ A蟹|gf8> D\vPӏiPb 5[`l*h;GWN)Ot}z~9;.('p8çr. \dI_/$^`R/#2hK'sRY+q61:`uKpՉwC/z_Uy!zҒO||{ur( ڥģ?|/?C?;:…LD#oB"dRN+ m4ϲ AJY(fpƠJg0_0eU`Տ zP+-N 6^/OϵSʄ*9M|fӹ>O@w$[[]>i+mbf>NN)zM<`-\VnmlU6- >=6PFGkd}y@Vi2m3@FUQ蓧2/k[ T݀X2 JhK&Ы x+ ώ%Cv^Z_6xs:/#Yli uSߍw3!9tVX?^4c码H>  xq]ɲhkk}oBvz}?K2]6.mGWVWst1FUXlur['+Un$@[QN߿V}ph~&A@L]JP[2j.ȡ0Z~ (;&He~AhEVX@0mfGp' }Q />2 lў`.8,cg`#}}CʭU04q$kѭ%7y/?\hZm?rA}ikv%鹼5 #U='taS9)(Ïp0F)ԌDiFdžɛR6߿ScK,GF tB:MFFhC?W6tJ&C }x/` ^P`S\ϛLmyeJ3h㔻PsA~Qwx,;Nsq,^tj=/ʩX$b1K>hy4oꏢ@x-{by)]g]YfxsvYaZYʞMA{7*P!4's~QqIdǦ+;G׏@Y­8*d;TN`~BYs3|~W7gs+IfIN8^q/X3PSѭ%Et"|BH8< 'g} |36cps@V2C`)fנGoId.<sb9[: q KeY*?@4g3S1?Rh'aZfn̶`lC0Po{mq.8`Bi_:9 ֽ@C% W[ ԗ\g,/|hwZyue^i׎/5R1Ӎ"# 1\\f﯃DkG#(V%xPƾkv+9 i9}o姟= 6,_//zŪmΨWKqD|,(h9%^!_4`]ۮWd9nLz*a(:/zn`أ35d@(cHJ^ ,ΠGN< :O6%遷`Ljz!)5ݭ2nO̒$dp8ˀtiѰ VMG n9_}:U^M >OO$NOW*rt@DtN"2CZh@EI~RU٣d کy3{Pac3{o+*,3`]kpWbk4l߰2h ĻVm)\ɄޘH`Y31g|, qiWuzwO!o'kܓ22sXCMj<`,3oAPJѲ̷Z$T8 5=p՜~=N`]Dީ);`oDsz  vWi[ &Vb ]sCDUat\u4 `4"}&&h||k _b,D`>*}gխttIguE6σGҖ7B-AZh7h%?`vl# dhoZ=ٔɥ[q%ie:wSDョGӃ & {uM<hо34#?.> K֖Ji zT]G:躁L4{P1]Lf`%Fu믪#]"Jkv oV/dn FWf*؁(:B9ʆ׷-L FJt.^pRu  ) s 5*lεȾP^9W8qX8µl} }&lVvg @*0?ZJo~hH OHC2$G&KN&uNtC.Ce88 O?4@*DLsʙ/_ut^+:8 1aKH!D(EM4YnhB_fh&\CưW[0TW&>a^PLA./]/6R? ? %^}$Yiճ%[v,}gvkg9A]/IAgy) ]boiٚ@VIJ!L ,ߘ>seo3ý>0'SS]yw-݀}.g] `̦; lC4I}Ka4i7z훘@hp(aӑw5TAHҧLTnr'9^φ4ߵ>oUYPg*qY`0p c';x6kNm`y}Nl͖F <9٬ oV*>vX\:ZaY6#/usX9V$G-Kd8fllV-G owtm0HXp<Tv2w#ap@|EOבֿwu~mZ܎mP|oV\ y Gpـ?OZҾYj[tn{NtO;nwrW39 U[!@܁#i x_6HA}*y؊ l*mQ no B{4[*F2dzՍ~:`\ v C \ }x T^O_!\C/.fcy(} =bt^6ôtMv/>VRB=Otc}ا'zpmͳo~9:c@Cny9@9<ҳwA.*iJvB{ _E ^C!zJ'7kC)/ðۃw$<Y ;a0X#OU.ۓ@LqJ{N1)[=ZL/4 uw ӠGQI.ON'ФeÓ}ɉ܎LrŅg/4YWFeǏr/:5N+ѻ[rCgtaAo}qOW@%MG ݾ/]aggx(>{ $0`Tm {iz]ן3[E29 ?gY>Cppecj1䖯{6l3+_hu pl:ŦF[Iilgrgf#//2Í5[^~aTk /zCw.qc3e3;VugX{}~`O!}an;m?~8_q}"88}u/9b8x d-d~$PlkKKL .w>KrW}'`jeF֦ceh$m7z>ASveJ[yw2cwVUOy=v* vt-H:8*#'ur 6|o|ʈɴv0G]< jTj6}o_$\$'FggkV #hme}MSϢk˿̓OjJ`{ /+_x[aY//lYAVtHwG!!Z,N:c0^9TO8y&RP`=k7vutt]b=@~mt&yTN./{}:oenی|;Y1^*_Um{]`zB|:kR_:uO|%ӑW`iS.˩~⥩o %n`s+-Ku${C 5<PWQ(l$Tz(Y%"5Wb[ow8՛u?zUu"Qi"#oxU\k "=M)B'NF{ecJ\'GŤE;rt)GF>TKFpc M$/']"ʎW0& ŷ8Fm`:_yТ>6 A$)ytק7{'/g9O?YK~0횣=|͂Z |Q?TZu:66gMu Z psʢ(z[6h^my%7sO8E1g(>agwٯܡm:-#7[%p!Z[igK<[ppXCGY#LY=N@7q{[>_6=/l B}9NOzL&ןg%w+;t-/σߟ<>oEwrĚYn`dM(.2~ lbWm u3삽zs<`=MѲQxP0i/Qpu<+:]mU=fNt!lz4^$}OVv*zƟU1޳?#oL+DߠKrU&+pDU*h%1Cu Jv;VC=8OwfodY-+b2nE>+ɔ06P ?($ Ga~y_tXt;OI}l7C6o>lҶ% }N̯*u ']Y/#͂3 oxezf+z|.|ͶG:n>}Axݷ|K'6uQj0oˠ{ٛ2"h/5=1M!| !|2>S߱.U@>A,u;@EM)֡ʑ,~O<5cf虓4 ufvYbX8:ĥ;O:6!PH#ʬ?W{ |=ݯ}yz5{o^P At]Ev)vu^Teؓl̛aVfnLɾsy(hC8;d;KsaS l[T glǎ @3M]_!i}0;1$:NI;9`LF+jN=&ݒTfN%S Fɸg 2-kes*Ιx~lׯCK݃i<Δot(1cR<} gYB➙&OnPrz|f]|u>oWw9)x@N f*!mN3, D= ]rvu.x6yNk=Y0ɐ(?l+D". uZBJwz7ob 듫 T׵dw 5>Gj;G\6pXW4[9M;Ջ$2k+ yF =V0S]o ʗ7Ao ,hoxyrl9Z/ȷ g&(`S_%c6^JnЯrx <~hc[ vh~@p Ƅ?c p WZ [{X9BP `vf~C|[W"3=y sÿvQNd`Tp,bKpUH_n~?J]$qaNӌwYG&X;A!*ۉ9iz1M ,Fy9>Wf³7 ט[>ABȬ~gy~wt0"[x2Cj0X NH+.__1<(9K2&+^ qT2%'#"Dy&#EQ$\42 2y$}[)dDY}4|pr!uQCʾ~ dy`U71==8H88:Kldk0 Ѥ3)_x/$$0Qth{]ElBr=em{.fؚ+,y߭?ҙSŎU䐼3P d*{?gZgSGk04Я+a}X qE7ُ4ur˺vN4^c%B}g?k_ah^~7?qK׭\fɈ|ǞQoLBlكEsJj͚Y%aBgfV?H4k9|ދ9ss@79k4Ǭ:!m9g&OB]);GKT9sS+YDuqP 2˯(_fD0q @/_fNmt,н^58zu|9` HB߂ZFmU^7U_.*^:0b-KUy\_U7[boI|)O> ,%;ɢfcO=$`Apy"^cS==I{:ȱ2oy02kc8\ũƧ/=t nnN|p+u @3 Խg'+C@{U9-'(LxN @3Gj+u1UB^_^@[ziө/+s`7R<ɹ/ɺt)r J 3|A5tZ+ k0o"%sN&lADzCi }Bhof_ ok\Ky,V.Ew& A,GUb'/39dyuݺF?PLңk HhDϜ\08! {Ei-(Ɉ׈:}g蒧)Ex_ '%^߻?c,g\ooyvQ?3~dcl:E:ʾ5Yq.%O :sʫn/<(h܀4g^ΙMDl`h]l~2'h8X'eы6٭MS"\I9&^]<? V9'Jp8. 4 p9WHm?{ŷOT^ҧ~tij}қ& $hdp=h{cĂHR`_ɫb@~u9ƝmlSK.*>f/Nu8 Hx>7ㅈ8Âen07No4wp&:oȓ`YV+=d`[` drW #et,x'7tL~|dIon>Pm\*X tr:,2hga1XN)R߂;2/9R=ixuJUwx^'ͯzl˿#}| G??~+3/xe9za|JߖAS4 P~훬+K/'>ǫ]G.+dJc~;{r`zC"xxk) Ǩ}[;g jVm1O{'C~mxW)Wl:.Y?650? !GM'p [, y(w'Ƶ ExCPJR靶{;P?h @?M'_V?k;ŀӖGVDS7ɻ 4 26ٍJ78 Tr1PtngIOkўl̪u"}E\dEVM8nI6n19#]r:z9z(*؆ɟ/<6}?|ǖE&M 8oyn.gO_D 4*5ܟA~Ct:dY&#-n*v-7jcpW*3!~v=Г&􌧌})E&ctwɤ| 2^n#e1hW^~7z2{qCmqXR`yzy+}:g]~K tfcՖJ'kl5ڱ8?aCH_l}q{ѳQY_iupfSQl2;!b2X;s~ogKgsl;Fo)o'57?i9b&7@!W~_oҽ>,T2288O3`E23!*Ȅ#/ĝ sf{9a`vG š ,lMM/?of׾vfMU~z,%G[@G퐭r M>Hyywɪв ^ğkY`a@bʷV?ȶWڌ[ H:}D N< =e|ʄB\rj~l;`ᬾ0i0|7:5:&9DhBg #k HHC]VW/?nՇӇV,8HZi).y*]}/0Nտ7̅{"z4Yy >Ρ~^~[}!=;w oMm+}?/Z^YL8M _v8.MR;tϾ^_^{6_ R` 8?GY;ԓVj'D?pu@,W/) Y prޣ4V'vX$V iZz~lIWrTC߷Wi]#F@9dY6Y5C@ i)o59y/@p2!0c๿sR:1,ײ?Thٳp}8LAo^bCqŧT~tCB"SZ4OF B7<<;ƑQۗn$G>rGkz]4(-@0..4{ ѷ3RxrW}zıt2k :"uգw$pҴa ` d\ \.PCd2~kPhbЌ8_W-ѫɨ#yП%t /::k,zôcQ;:A3zmv!f Ci_ Wy'}2MuF$Sz+j~O-^ f^/:spdw OM𶺄͸H\Nu'{XZLɜ,գ>7'kK  bt70r#!L}Gs|Nfqt:@އo۔eW~]{fLe!7opRuhk?: o'/^z"oy;) #y+F vwv;\>|"+ ,/*|ڝTM]/ݬ:ɭvƁ|/N.z$/-{)(bݤ_x1;iN2 cE?V\ﵟT@ӊ_"2{eّkK&8AYq2zn9c:r0<*Ó zCpތr7U}hx쬲ٲ>vmN{5}/G_}+،Se1B[byҁO>hLp2[2e2'XnSɝ]>6vH#WINݪ:DTE\ZZ.;8ɬ) (lҫ h&J k9\?o:lsUH*:bnшc%Z#ٸ3Q !'#v+"^+.X3_UFSagzx~7Z}HΞݻ{7_7(5-uV$D"3ifE/ Nhl9 2@A"g I= P{V9|!g@>3/{_~]>ˏ;ѼK]G} 4k<q|'Z!;ynӐL'a/> f)ZȄ[b~@>꜃]:{8ϿDmg_Կb֮{7^~$2hvչWef7h׆+Tz_et8 śUs\;Acvz[> `ӧDcs/{E;oD.:k)8PM: ]}iנK n|m;+& { IDATM&G53֖Bǎȯ]\WC\ݲDIcuR)N,$(M*ʏ@N'oyO~BnĔ<$94=Ճ:::+KY Z]jW]l0O9hl4W ( 0tOV3T0t4'F)F< or i0VlV\iJWN=<NGDVC4j5Z^ )Pj/=OrĴo6{y?(&B=XzEn?|R!T֙ĵlqWg8zv85B ]K bt$K{W0ooNFw&7 o+g;cA8yzl ʄkr rKfeSrv nz ZI=L[/هn+ؕtczN?.NlJce_`Dy=$d3o+:*;8m6OJwvG;JF4 gt=@i n G/46ZpG?|rȬ=zu Jfs. f@i>쌟pO3u!;ƉOڬY8 u͞pzq;$p !ǞsmX].q^r>-Ŷ̹<\jldNH"9@7;8/|Ж1 G>g?Go)`#!z?=X~ A[&t}>8ʁ Ek<חlّ*b_2 i)il0@3F 8ѵVfN?çznA.<&ёЅ*|/}AmOp{X| ~OK Dm3*,M@zT- +O?ܡo w&GtMO|պ  *'w8moM:2^Y_zGW [4B.6:}~{{Op1{^_ZG_A#xޖd}Dx2߄ +7$s]*iByԏz`Yt3@ir2@!vJ`;}QD#/  {a~S"u9\=|Wԩ:] ?X3e4 3R>0Gg27z߅} vCF_{.Hc7}e.3nP&QV-d)iC{V m"g<.$_0)x 艺5o7K7p0^,;G]d:V}pGc< 2֬{htH^1m4C 8u/b}RV%O7I~N{_\^2 'p!ʀhĂmV`"ӵxnKL 'm=} џ +»mg(Kzx ![Gڍ=aWmy2} p]f',x$ftKֽ |]y`}<hFt6upO#%%mzV ~gbeoMI ]ֱz!/Py*IW|eeHeMAVs}iUHtvl8uFqgkO_|VE7lY9xڥߣ_dD"=jۿ6ݳDؑO<]W_(ߩӷ{B\}F*W2#啹B'/qa:˃\ x㄀G=kV#eܟ3sf2 $@bBL (`rEH Rb mU@ @ABmU+ @")^zܕ d&3sn9{s|g&$|n~>#-&]; 0!S~o(Dw <̝{\Mp9EW +8ۀǀSU&0#EKc;UcKaG$JOd5|d-s{,2:qE rd=#?'R}J88IvWpEġ95pS(pNpF7PS63I+ɯ:h l{2+ ǾG,|hzzO06 q][NX'ԵRz>Lvቖ>- ]dQ}?V =A?z>MhܝKJ D̮}o0m :zh_\{Z`җ "F9l{-:nNķ%dϽyS2d~ >]鎡 I86Ac]G`َA*T7v2 ^etVjCt}4ұ, o\'lrzd$w8.puMw'Wvw:ȑbt$QU=vtZ']NFv 1 ZЫjwfj Gf@` FtDJApi)Ivf/ggf ߵ55w*Wܫ-hlLw!D| Y0 z (h. hE/z>2󡶛i%,hrkzA J9,&>$~>W{戎[y,mpbdeQʰCB?5*KB{J(IHw{,00Z*Efchpo+S߭IpMWI]#7t@o4}$C-d@vL>4wf78%GzXf5n^j0Ƈ|NRoÌ]'{l\^SM{z=Kקd_| f#BT#}g\S{iD~2JVV&pDE"cT/z 6Yqt4:BU=9ó%\;j%HTfJd9d챢7l]V[b~=]%u,#X'?XFꥣ}xgQKOd]}Tښya}@~ٞ~{+UE`؃)#Yϣ/\} z{IG%0L_| _9`3 3Q :%3ǟjgYɘ?ǾoGIA+~m7 f|T\;62g6T]zW=zZ, m)Nݧ r<#9ݾB#=,\e@?_HNICc6W^ (%:ͩLZ ;ś&3[ HGe`?lVCV ߡ~GɑjDĬg+9Xuō֛9UL=GANW]^8u:0GOFCp OpE, FNԍJR hd%#quF!ӌU; >W\;k%FavqLD>uMudޠS4adg.a(I]62f\dk4398uK 7>TFK86 X_9rL\ᬠV 0{Ͽer@ߍ;e_ry T|$@~__N niz=u&͈|MgT}<앀xD di[ؿrQv+aqؖ2 \յ(}T"oDWeIؒa✙ZA o߸s9[2ڊ{Qг &|E4xԣ`%bI%_ 8g|-*}UCݻL-W}m 5C>4з\՘\V܈ %u7@O?߉GhD;=:+=c1==r}5=)GF#^\wУ5Zan?BQ5mu?y֮Pe?HVx,BAVT~ ;}Հ-եׄ)&>)x*dJѷM-ƣ[CގK w׽ Ŀv˺3@{oOGí{1׊&c~0PcT&;7PK&xw O5f7p9\ 2Q?EAS>L#8z6}i9OE\\Mu`st3"%:s]#Q(woncWܽIkpAY|2(Xo-M0fpr%Rf{^cJt-K A) L1}_Õ3ns]pi.EcIx;sz}̓* $Lx@u؞OðK4Gcm磩`dzWǺ6 T|0@8'8JsZJl-]h[|6 PhǼ}Wjt>oskXwaE}3I9yo986(0gvUlH&# 1zm`<$6#.GdAk;ܹϽ|ɗ~1?V_Gm(>Syf4坯`/O:*N? E3ydh>Jz78pVwgw)\|>EV68wڟ%ۑ ƛ6Y:Bt$NUXlrdwCz]FB#wŞ3ɗy3= I;@v'[VOgkMh'6 2q}6,zmAhՏy j7xai"8^ȝ+FvWgpx ֒pViy]]6U}듃 4=i!x6?t^ɿGf֮7Y}cûVϘWgoW5=JF٨ wvN`d&Yt/.N{\m$U*oKgm7ʷz낷G,+]UCM |LoVUmj|ut}h=Z|ۭpO xOG w<4mUi ?pyY*F@ jnTt EpH*{ʸw+ @.ƫ'@2-S$D@N@+>4mD% 9S&<8~1}}gbht3>*f2 's*jm gW/n @gSG潟[,#'ֱ̦1}G{VTFTpg0%O>b"^ٯlSO̫$],^$߫?ydMho>P{bE y5`xkK4 -^BZ;]BP&` 'meAgr;OS2SvLYɤ*]GSfnvުV$\smL |oXbL o|hC_,*iA=˫maU F/pGgw-{Ax%/أ]7l/ͨ1'%VXU]# ^;qV`ZbhW{]Fɀ>whێx:y̷T#=\n{Bl+蕲qOѷ%ȉq]zMͲuDy,ZA}U-40k.o#0 t9[=`zFuO2 CKVտB 9D#K%f`թ̒~#t(sl$ <~NI᧻v镇wi+`I}ϋd~>%;"@A͟SvOͷ;}+c`mтg97l:b%B U\19g{M}/a!ʧ&pAfrO?З[ ?/rJ5ӈQg/ c;z%lĺ8>l HXl6Cv(L D +$҃@$KVǞa֑Q魢{ Z=ȉY~=ayxE$=_% е[;\Iohal&8]iGHN+c}F O^WMpA^e`U~VA > ^#h AMblv{gְYО`GG}rh rжpMmX35d€bo[d?s[ Ҝڪ 0xyڧdo ^tl(3-=&tzOC{oWA~MXm?8#hOY=Р&I^[\|ǜk`MMBoŃ{N$ݔNK*Z_̸]')?^ۄve{<9kJN`Lxb@]Z't= poCYzCb|7pR_s6\*\`L>;>*|-O[*)؍o5ntʀd+h=pN~1⪷:mr\_tq蔨@:+t ?2l4" >XXpV1l%%qҠJU)2F[ՕEo:{#'@TƭcYuFRAh&)U߷c*9yn02u#ӟ Ne+,GGemP@%KFlYO+X"K'-A\s qD˓g B#ג^{/?ZmiY[8Yko/3k{I7:;VLgL&4wGyuKnO KF%9K:rrfGigG~b}:t]ԑ}L:d͎w.UsfgŠ>* e p6@vp! nt3Y6 @,`w"X>4v2<_1H@F5p/: Y>,83%2ς;Q>|p1W→klo@g f.ӂﲠkɜk ѠnovQ '򏕽 __hA79?3t[/8ըGW rJ޲2{r,]^_vjpd>'=׮,w O@wO}$[Rs/Kk QDFt{fT& *Ú$~pb./P$=qmA1}Po{e[>\rYd8=BѰz{*-r W]uTR ۨPjy6ɲ+eJDTd?ӊ%:u4IKL#!Ann%K з= X؄uu4oNK{糭8:m&+`3ɠg%K:J|9E&dFʁ.A ;^;6ʹCg[2r4Lp%"sIu4{%^ܤO\uvIK삿MLtRz @r` RN[^CI?|D *.%-&;y 3cӬ[1,Y~;\ֹ*$}2WNt(|Oo0"q}m }˧c-1uϵ|葸0a&lכU9.ȅKʣ+ܴ zF!\{f<~HnlP> yGR=~|mub-یSL?=GY.>H::im UQro];g=[zӀpv%?63Q<'/Wlt?p6<;\䠼-"LZ+k_o'7_D}LO;6$Pp}Iέ r F&wݲr=BRy̝eFvg@pV){hb' d ']42< P)Uz8!~9adTwLDF>+ ^0o,J#הWGZ|&T36ܣ+,rzǧ@5Jt=\YNp 0f38hCph(W3^a7e}A$[ov:* T>Y H6="?ܱ`Ί->6l+]ͿC_OAnylA@[5O6>O*gJF׷O;;^ofW/U>^C x L4\O-h6xG|Zux %aCnGO>K,)~'! FQ2xѷ) :Yj-:^pֿk!a_wI]@ȷtdӯJ lA{/<1}y2/~NIytk;$TpL?@ ߾ Jr/Ea6oZ#Tl +8=MV#e ir^BѹP"͘{?䞰{̓^l6:=yΦNtm8yLx8= M 1'#٤ͣiLKlvs?轗x;Bio3Ub/J8$/7POֵ-aI$j+o尊&\K_=R;rk>D:?Gd*Jm5+`Ȧq!_?{>y'}$mIVV gyAN&+}PpJ:Λ3ުͬ4 o 3nylf%gt/_{$+֎h!z|1ޢs`ԾQn_/kBݧ{V]{oT#Clj^Zޭ+u_ ٻw̓KbF7QuK Lt8Qɒnm?KymՁMϞѲ>~\媿ludg觛6y@ zL'gD}^wG\U`l"]"fɼkSԡ\Yئ9>O0˿l%\"]t84˿Xו㳪tw -gb vd8%U^E*TtДιܤE}uMh PKFږ@7:d鳃kGocn^;8Gz`{zT`?v2O|yLS ;DGʹtA2rPU;92^8x䃴jO#_ x gbfo Ou%~nKmËnfS&)(Bwt=<2hh\*֨9*\]q 4#'0t\ix-6p^'~`:qmا`;\O8}d_A[~}VSÌ:Rl{{O,I6,n.߫fuW?Gm$tvb6Vq;L㣜}-yWmS\WGYׄpfBn'AYOFWv[.4Σn%֫'[r'uΓ%.ǩO7P3W O+'CCm7]r2߷h&arP;uȧʌ&u|D˫xAg>oGx@P_`>}᳽v%#9ލ3])k;o[Nm3 DU]z Ǭ&o2J䱲Nvr=ǛK^eA,2dU^+:Am @?}v^vrA \46|kCd#X8+"ͲaG?BRؖ\׷ 8@W:D;WFnp`ɣqUlRՄ`2!(vpS FI3f L qWӪgN,g_?+zuئ'6>2φn`wFvf%{zd!M*WTqmyx'&]8h5,i{W-4Xb|KX̜V(iVMd@>]}0[/azͮ%ŕ.y\策Уvm:<5o 7nP)yoȄp7^z˫p /7<Ľ=@Hhf0C~?`I$_gՊ7_;fW-5XozA϶Z l$:̤>QNK/l~R?4LFk;g+,)FlQ{#L@G Ոnƹ{tzok  $Km"hsV;-XBpkñ7Oatrd)="K2½%ê t7U_i w}{68Q%>L<|<Q"N,цL^ >wڷg,}_+:Wwn 6?eGN|F9AD5¾BȔxԝ*2zawt} Jtoܾ+/2Ƭ1lO߂ky>Hǣ+W9L 5dMF_U$^=b$z'{1ށ :%}08E%|xd{4]#6δAjG:pVI }6;,uJ>C>N٪~u[<ٟ9>wnA^;'?6 5Y)mg{W^~W:>S׵owa/'`]XfZӫhت G77 5};xΆ־s Bw e x,zvydٔ l^-nJ%B,1`IlV$_Ad\81T)!ŗ$bqG'PRPm5IϽo y[&^ u4dAWNSY fvɖG.G{`2{ɫ6%P{ {|z"6@%.WRÿlBcBX 6dlgР2p;MF~9KOJcx \ʗyܒ@ Ihq`!WȆo3dރ s-oӯ ^īrO'K6h<fooٯfK A'Se h(X$XO &[9h䛦_ׁW9M{lⱄ ǿIxٚ|vT bm o剁ƳOKu`A taf+Ĝ۳?sOg^z^Z"%QFt^ 7h hlq]K>ו^ M6/2k'o->qw+ "@K/2 $"cv;> T$alt՜vPS™M?Q=On $wrp=:qtx&'ӎ?hϺm`qp`"Z0tC~̵_o_dj`paZ`@wo&+xw w,zuBFA׆INaB=pePq* >4m[O()+zfջp"}hDo%֣DV خeNe&- U걌V63B X+]~miU zZ'uy '({.2U?V0;-HpvO`3%:d7:wc>V3oeg #;9w' *r}Y٘D3B+3cL|d<Û iW^hp[0yjNwKGtex?ن"Wm!`{t\׮ѳd~?xS4zd x 8* џse{]cSЋ69vw~c}|~7fӱ;ux=Ag:sq>:tZgzJa>SH&O=3{A%V/`}+(+(5>͌G{V|hopqX[ UcF /ʈ-KIrldmZ90 JA^?W{Z(b.cv?FÓ=> }72ЪͪOF{W[q6[O3/<ɻzUOymI>MM=u ۂ]6+Ê? 힝_`_\*1Z".90‡hz#߿^ůk?w}xCk` S>z/J_R ;+qRF{^ϓp;$`e|D^9=_/z6<$;{nXc, o[Зe^w 6xV$'%f}{k &# s| ;W#/z g }6PP9r;%^|yՙ瞗$\ы[mm\fq7;;bڳYރ#%~ĕ_L]޽ ˇKx=/]6`S'/$ě0= 9~*=])mƻZK_. v$tvIj_K} {sq iw'뺪Ʒ_8.*_|}+^vz1pCzTsP#̫Qef{1am*X}Y\p@ZӍpGJᏖL'~'#0薓 l]}2<2]}E1$5NEkj J*O@0  3Z胑 1 (FceL0!(O@dVNKURϧ-ގ#OWë́1((7x}?grʭ1Xr!#wu+`kt0ʨsh|u4- ^;K4ꖄN6pUo5O.lw>B#ē*S%N9KM,j?-xMw¿:C9zǘ_,s7bNu~2sEG]rNpMd)dzMWɟߒBKu^8wN,7h$reڛÀ@?`OʲC4⓿+P^07>+CKg?U<_#wqAcη?Rxy;芦;l˯$Gfܫ|xC駪79KRSXFx#SA|m;9a@L柪4Z*oɾ-<#ۣc2j/Kf ķzȼ%}]ýdx*:ͶNێsn>qщG}ZzQ |aIAm6鴇Eh~yjr<~қg_-K'!_Ό5pSzX׽{}ZB< o dݢa-ٛx{=cv}VlHmB6{w-arכ]oA~oA]SKڟt[H&3Gūe8&x=ohMM[,\|aRmlXed^Y8e22HRtz O?lFvs8/&!8Ӡg_k}| `1:.r^9ߤ2wO]rlJXw`D`*[:m S2K.W:vU0_ci vwa#^|5xw*r)M dd8z|o;lt2Ц`kuZ{rFn9jؔ.]K F@T־~ =J:tL ѽ %}Vv{OA!~2έc dF\rmMj#εe• @u̠1VG3n?:W˗~ч._ӗ?gP//?y7ӖK_?[/u_be~ ?w{r??z}׏G'}?C/|o /]_//.?l0>*ާ.Wew{+ Fv|_KhY?~Eӯ^g"Oi'?j)#M;ۜ~MqKPn~=p׳KpWo(=L l3p5;3]2)o@>ƇX_f=v0\}_׮4nA|6q† ?Tm@2Yۮr=ݫo G#*3^]fp$ޖP͟HJ?M)Y~h+'|?ZiZ=y%(z+睷m:"g+sQ~2H~QWQ6 C"9AtBPe$xVƁ:X ̼}w$An:!#o TȈ{ĤkЉ{u,; I*oߵ-9i۵x٠A;KԒ*$ ++gdb 7pl)Ty\+66R#?ٮc=ϞI/YpVd'<6US{KX, e>3onr<%;zy5> ׊<޽Ed3Z6OfnC^~ʏ_ x8}tz L9[2{LOFc=Uۖӣk[mԯ;^&cOӛĸkDp BQm4dVlc ے.G9MHy DҐDN#u0F] ~]} fYeʣW%#ɭQlxCk)Qb\M(-977gaN5}7Tϔ DU|64@C9PYyQ4HH7:[mut/xB p*h½.k{ρ==@Sm:Gq\/BNhskr["5ow]?~;G]~ZW}O/[?r|o?~߿_~AeO?1qO˟3/\w6yo?.嗿\~U.r?_~Wcm,}YM?g5k/_5oq= -+EϿ{z _~o-_o|S/_/.Y~N{w;g[\ DuL6sc|2{ )$' ~MR_:2Mǫ "fl:FߟxـXuNWArHܞd<뻢g6Φ޹:6?h `p[l T2\!XltOej'¯VUǒGdr9|k;[H>yr1hl| CM]| ~^`V%>.tmXCfdهŗ%?%KÙE7<V)i dfPقfԶVȜڻh]/ N_K#\}>x!t Ҍk{scɰ5돢~ By||xYoBR FSq*GowJK$MHOܔ+ w3A^v7o3dz;{,a IDATo1[zGH f\'8s%fl9=Ff;cj2-Smt|( nW_~\e|\fӴkf[mIUWQN6 l 6f ^o=4~>]70rXO;jhe`ޢ`)wn 2"W{dTuħnKޫx'o׶I%ҵ tf{k/tW>֦(l^|o{'ul'G=sm7{@|xk(_Lf4dս Ek}~'g_ᑘYPSN%ЮۀIKhM$g%¸>)jo5vm=:$Gϓ Ik+Vhgp?F?,'{- ūL~8F{>`ܾVh[;}Qįm=X[j,'ƫ;R}D>SopB]m)?; >`oQBzP,HO!M%'Hf?}mw(7LDLWwwaَ> q?f9W3:G#QuظKgQW-A hTrAzC2f"x&d)~4ԧP re"<}vo<!'7^Mݯ x]5 ^ǿc׷1#F~MaN#Z͖@n2Rݜd NhʭGSg\NW̸OSv83Nڮp#%Fpw B a#?:_N-q/72=/s=]~//_-Q~?{1?6;.__U+~?|uN y{쟸|o͏E/[~Oܵ?K :|RٞO_~W\T3BۍɎ_M^\~lڠ%}g#?e/S g"z跙{Ͻ}h&:WĮtR]:2_>NWuV7#{ fGDАo۳o%IlkbuG|ʲM6 ^O~`:=KԽ^p -x3x=?~ mmUlgg/˧ n :dtl@a3?g*kg\׊CS&T]^7Wf5~Y3_YBh`xcpw/T/_r@Je4JߠGA8N^}Ц#싄ң[?W^y 776+F~x'hd^'}6Ec3g./{R}zrlA'Aˣv\SکP!|YqסtiKxs]E,OVga:ۥ5e_*iܻ+W{w5~e+^=h)'L5 =,s$vK`j -x8ϥ|?6.Y(@d!ˆf֗l'gP {4Ɖk /Kͧ|-!Ԣ}ݎ^=K)A"/%Y$ \36kԮ[AQ|/ᴓtW2\G+x Od*Xz;}#m)9Sw2Fo]Z }|=ë0 3owVZ2’z:_6ʠOddے=cO{7sZgpm{T̮եI6Swv/)@&,:}/% $JObϪϴ m[W&8K#q ix3h me*6+ =j@s Xb=mT0п*>^:'׶6֮c7| \)}Β~ eW !E;E6h- T%sXtwlRzEAxZ7o'?*8Ծ $fϝ |. o~( :2tw6?ьw/Ȃ܉0` { ]/vpȋCt뫺3upaϫ$@*u \N ق Z#t:pFM0^u3Hӏ13eC4ŰNSyFk:ZApeN `xTi_f] C% ~[?[{?$w꣍x'zCg(tZE)X7&wr v:>.ț|/` 9 հ\)JeM`$S$Q;zVt\]st,wNGOoFvY~p3RG*L8MOW4 1F_ ,(ϾEPյţZ[0ȃ tmɢ*OtcQ 2\<9]?ao9Wdv[t?']~տk//^.?w|][16σEϿ>Y$ ܿm{ʟa_I_Eߒߎ۵ ~=҃O9>ߎ|ׇ/_v9&2^[ld dZDjwPG(Iq=|i6:-^6/"+}cKv;suѳOF{]mi:x?o>nW?OO]^iIFw- f-!щF80{d֌|X|[0釢vax~|(OW1t.}$_om࢈ߵ?F4VGp&gׇw_ M0oe޿v@VfQW9#mƽjo{5O?lbjVBo!1y]Oç / uO@N$,ө ~Sg= :y>u63{l=o)`ĕ_tmnsG%۾%g6pŪwfzGx'pI¯vG?04wH^PUIl*!ܫ%4؊7߸>^=ɾ{D eׄz/#O [gI=m'yaɊ ,yb~|"վfϯ}4ldzVIWb'OX h^6<_ ta25nmϞô&S9du3/c}V%g7[]v^yYbO2He0@roCK*uͪ 2uL(6F'N1R]~=vd0/VрSoi?eK Wmp1Ut,_Ps'=Ҧ[Z5J1y_gt*&_=^hgu^mr7Ɉ[ҠXkzO|lL|CT:9dCwi^{ ai[Yv\xܫ\ltۨOG>G>Y>7|K#:{{X+QBIOչS;r1V t}2|%uGhu R}p:x# r{G[`ci )% k:U?g4GptQϒ: 'ŵ8XSf_EGaGf]I0txFpY[]5:|`Ju6Lj>|WQ<)Cm1Z7PP".,eDK'vqCk!Ȩ2<2B`t;M$EyvfJPXhުӳu{]Vㆃӎ᮴ ~mW\#wk$2q@p'+ εϵgG臯יx9$!G?]ws9?4Ō/?gʇ/ϻx woknO/~؇'zqi囿iVoowwGk|ge/}㧕oK}3(t޾{HEQ~?ʐ=f޽J̌Oб]J-!oU2||yx.D-h[Qצ9<|?$wJb lm8BG[9wڛ֏} Z^۪GWꄕNp!w$ ᕄ#3Ȯx56[}o{g_?|dd_KyC蚕+ yWi| Z>nfGĔx,Jn"w`S%o4C9=6r "詝jY ǕceóeN.f0#vKv&d0cuK O/Yf.1KMeR /G c3GW4k|Dl [FKwuo Yߙ'Y^q4N|x{P|Uc nmF?wm>3ЗEI7f6FVlZ pZ"|ޜQNUbB3Fm_hʯjooXy (?}oY3;{sS}+ onIu xdWә?U4{{]\qSnCD+O7~C:,aԶ,\WP6zI|(&wdm |UF'b(t]o&:۹`  ZJF43jH1*f?dTiG#^"J;<#ߕLgk9}y#%,dl[kZUw1&E F =DQDQT(\h#Fl`""A1EAE9gկj~~cηa{Y|FciMeU ޞW=ÿɍ̡`w[Pi=Sά&owU "ZpF0MN<ߙMPS}+ȵ`ൢfrV#ӎv<< >z&G.{l!;%ɚ>U[L/!l:9|*/`v0X;hX?||o ̞L^=(-o%y}.vvD(q2?j%:/ ¼\7Xw ]]۫=yL,fg3&-crJnݵiu`]Yq+Vuϭj>0`B|v=[芦Wۊ ko=K~ml%dMl#h3a||N[FD0qh`@>'FvxdMXm"ѮM48gC[2XI?%!mQ?LsNt?䳛wu'O_~=T>';UpAO†wmt N%.U99t ӎ{EA禮K-}) W_jHڻ UJtH:hv]H0=}hxE#JP0q7h@:bᜰNT^Z #0' $M m*/ه\?pt$=U^1{PWFc4OdĞ3Ѯ(>+M+v\6">|8 DBLɣ1Wrz'3!<Ɵv'Nkß_ oK{n?[ɇ_9_W5_/_߉/pC~o7~?[?~~?G_W% {>?z~?{K_7[t=?7.zo+kLO3op`Yg9NϮm٨`l}~kGku|0?2!kgMl P]~oˏ.4l+I贋oKA7mק<~Ꙭxst,#i\v#&]5@?' KޛHE~^9Db7 ^ &EN{>9usXrUm"Jyx$&l\~xzj` vgoeSۡ1;7yAg}s(ny ^35P6{(kFNgUC^/׊6}I a 8 öG3657ko& (|*N4ֶң+n-8et<*\Cb[oӝd%1}oE󞡵GM scmRx[vnJ[v[ o(}ZU 6z.ܪsࣿ~N''lF1I:ͶRݞɀghOvj,vDl'9ǟnV8uy4 ||87FG98tMQS̑se6ietcrsMmLΥ//zL֐|yxr댌LSow=_ \0;cJ7kug#:_Yr-3 ͗{ &H}Z{66<3IJ?p d9~c%1x^|oɥm,{ #hIQLF>!n{6H^''`] +Fڽ~]exw LM8E҃{x ͯ]u6сV£ !f3Q-"1%:=֎#{q&||2?r |Ofp_U|Lf&+zEstk7B|& >eG:h)7ۿv_-o;2O{{'+lOSZ[>uR7g1 `ba."Oի1eQQWXI(8H'")n'm=tOدAV~,v 2Bޅ/+IL(KOdT C[жrrJFÉ&k2hGCp6Vqån㢇@gHI]tÉD9\èG-,:>Rp9 .Q&Jݶ`o.8E'cCaUat?냞~ݓXT;Y'o|&d/h&o46H)ݜ-S)GU\U,9S]ɖepqHWAe;_&UAp7PV'?GFۮo}֭4C :S-Pj˄_]} gCYN~D_DP`L^l/Z!c1<*cw1otxh<3pׯխ aysv< K[6ݽqnvOg;"EKMov Q&?9 TVƪ>4շY ֖n?{P92j:Su1w|i]2AI[@ a7\s:O+M.ylle0i-VM0Hcuver@3tC ӭ@vm0㑟ԟ &Q@ gVKGN4ח[(?-o"4F1&)ME"=~K |6 Vmw`eOzsg *iO@(]]+|;::4e?,K6K UetJsdWA[Gͻmh"{U&KnM<=?jF}!] zz.!hVtx n ȹ\ô6E *o>a.!+g [wv:-ٕ![LƹAc``"o|WOJ.j>zү!xWY[?%^@mCvm"^'@MR {cG&ȈlaV_IazCINju,e&9pXA&7Q 8$޵[MU7~v-(ki";m`9kUUf`Aopa< hl?50cr}ѽsNwhU~\xm ڣ_?~HM `ʘypOg곉8񸱁.}Dh xn@g ^ NU{y)]e'{b`Jhr6o hZ-!a_dG9$Yp}ۂBƟ|IO,- w29x'$0HN?>ߣ ;AZw_pN#CgP?`@4m!;M$=XImgOC/}YW>oibqgy_0Pk;FJ+&e<LH{1R$6;B^؊5b/ʯ)@+`LybAro'J ?ڝ-@ |'um~x'"W櫛Ƈ1?9G6gޙLh7^-MvZ! f?V/OYoM'@; |I+ ?+mc2I4-V6@;ʃ+5l_+Pm?LиMd87Qt!cVb,m巃0${2 8滴NN{09# E뿣ń(Xjy'7+;4=lR:`Q mJ9;"՝e|}xf]uYBW23F8*c@'㗷 7S'X3̋Rп ӀG=d`_~$>ؔ癌` _~Rǔ|xɟ65sfOYֵ|N=vIl7mT*叭>@YWȹ;SjbQ?"[[xkj@8Q}g0-o t+8WP;?&oU=/c3O;ԏg HMvwf&-n8}~S+ To2B)rnxJ7`p-YNkq&֧ә|Ci2V'@>YѮlneEκn+d˖>m rۙoT<>AfUcӸcg]Ror~Ҷ[ddS{Żo @Xw,`_dC}2a{=6I`>iPNZ^;V.~NJQm`2 ,vi nm5J;Hzt6 Vϛ=.sVړg '(2C>&o/Yi [=1(fSOen§-WlUx ߡ|VO*EP=d7b pTwAĮl$1ػhΈY1lw9^+6QYmB:ݫ9J}hlcLGdZc٥Q8``/o|O~*[ /v&5H)|M8O~ |lG}s9 CkcoleNңX'O$!vCfkwmc-e Zf0K^е_ O|\}4?h;l+[eD6m2,^D/{~~mYoBt[j 0Yn^מm='ge7  w s{Q?6 !yF+FsFO'xSޙ q5W8d4E&%3 |;x$ >vi͟68lo ):~?'s2&+o-jB|#7ni`BLf7slP:z+sUV>m ' c,?dS iw?p z~ʛNe3dtb(lCp`yHWi~V|Ȩ7>.g㥱Yu곇vc 1Rdf6!o'sv r{-]Mb[A B%]`T2d~Gc%^{F@"0REMdF1~W?z^k!CAVP@&SmpwN@ɖN޳zj&ceuJkz OtWIOvzǖ~vqbWx^YaSnUD_m99IfHɸ4ֆdpvV9en[ÏׁW;Do:px~~;LMb^7S].;v:c:|^=d+yZ9M`N0տ]P]t?`n_ɵ˂_;ec˳䘼>MDS[O籅&ؑ?_S}Kw'h3SпٕI׽/}`5n)ǝc쐽uow3zت= .޹y]vl!ZW ~Xcd;?蛇w~O5ԙc]5e+ä؏[j=I0 q-\5ě*V<6yЭB'#8_ L!7Wz.թKVVI}2xG1<'?WN@~rDQ's'ڗeᯍ=^}+T3X~f̖~#\LͿUN-dPi;dM1#ܷ ~Ig׷igH]>m7mOuѽ6ZZ8j+e2|ځP_^GlX (FB>I?f 3H?ߣIfݚH077'.tWqt[ث(]asU.C s:O9oEwRn?̖xۤ;Yqry(<<2qamjZnHi-,L|>/;j_gp|)#'͞*I (2wW{:vv3]>{Nɚ@;Yo芏љY |t+XcDxآ*R G0F[U}7?:vF%>9̘õI0gGp.mCP{O(࿺ْ1Vo1@7ʎ+.C0X`s+XPpi/=^L 4v4Nih&Tp#@ xDlL:4H4{>j"3Er3N>]b閭o/ (g>ypI;Oѿp>ؤ/:DAfY`AM8 D8G~[I|0lOro:]4 h ]⅜)ZUg7uAq+y\Y>|辉*\`@wфd騗NMxOF4PҔ{NŶəWk5*[c7Ό@ǁs?F>'6EOkUc"CNe0!Dʪk{>t+h:5:uݹȊvSA\wo8m,J}{|$3aJF%]iyx!!(1Lz50zaޤGz`͕bٌ7ag9O&B8YT2:x}nL2+}p˃ =pN0Їҏ$r? & ;,L ޿cDpx DkRCmq_Uޥl6oeT`;/fHs)G9)v @ZndR*V.=C/qK*^;Tw1FylYQ} GF -sH-',g{kW#C 7;\GFH蹘'نD1@t] o5utOVu[s2ho8:2z3 IAk-+6X&c05}3ٝ:gee~jM)}Le5-#X9xJWQ<>< 4_q?zx\?܇wj=``v(t\t~v(}|oqY?[P~yUͯW:᪍}jϞqNο~xt:m.WzF| Mv|ai:UhCXW]72"ܺijP?Z_־?7ʒQJH@=, N␡xMg[UAw09 9qo 4}ox\*^!w*юkSvNB0s'z`{3h VmծC%wZj w`M /ˈcߴ`θgrN :I t[mX%O~<[mЮxU ‹:|IPU8bN88mY}g3;RNm`bC hoU f2|nus$>VpW}@,Og`G;rȆD`mVgV ژ%[>?'vf܁2הECI ~KC RIu%م`s ^ƫ.K 77@Dmck . ]__$Ìlx|  E0߉ڑBĘALmyMXCm([gG?{ _wӥp5c%Cd!>)<rWNH*8[H%QvVR:鞒ୢdyTUАRD7+xJu`yL7Y))[v֨m2d2<¢1Y*5»Auj郗.ݡkxoȗ34kʏ.}z.!΀h .{ eTu&^VFKz w};.=9hóS}pdC~m >F\;llyٖhNo.8|a<}~omP~uJ ?H ~G~[î`gZf6`m!'H=n@M` kpkQg^O޵M|1oWN[HÂBP V{?JVޮ|B t!tpUUػۚm|*XEI/?^>#zCo/?=r0nlϹ@W[&[߄ 3H{.(L0%ߞ-lz &=>=ώ]5lY=`m G`o!;S=疿 ͬ{<߃owps,Sƈe݆ [Fדmnrwo5 ;ٛiu4dѷI|d\c}'l+Ppm;&!Mh6@=*:'(i9?qhv,H'u lC0h4t{C_+ x)^ڕ.HxĄ:['2-0>M7^] W n"0=Y6HVnR!HAyo=|OC> Zgbмs 3%h~0xmTtC;Ptջ:*K&]ԙ-% ]}tDYM6!LO7 ɚ^@ vbh=ǿ)RovOF6Qv" sc@{r96= +)}+M/vC׳{ub/u[>K%E=zZbĎ=Rn۹t{܍? Oa&@*CC.]'ܫy\YnÝL4sS]r/}D%FMbx4,zvnqѨIhJ]_h%=K%ube ZBpELB+_@L>1DZ,_~c"NѐR)hG7`C9)xlL7 uk^}03Ń E%RU-((8eBdC1@{7M!G~KCh]=i+޾T{$ʗы6}Vd:`7Oד6ʡq+RlCትgmGfϖobXߠd =FFzrPZ׷eP-~ 2]US_읅C/Uo&fCow ?^.q{/=+0<'K  -ӛ>1yd>-PTpLy* Zz?-AON{ϟ6Tn2`׮g+msm͟ZUoz_M 4i‚hpee?|gK(/`δI/xU$&z[\p*cReA{?jg{@%k+YIe_~vy|hVv,T6 k!XfoUݓY}.W_=U; R}.zcͫ/ӎoA;Zt2kiI4~F{;lPt2"U[k3р21W 犐$KCBBPrj6Ȩ~'੫` p 'z~Qvq$NN+:rG12 `J#U,dH522긶z$sO\3{Tk+^:ۡ} [H[V ܬlο .7M5ڪ_9r=' b+ 9_}Qt7(5)\7 ll^Yx9[9ev]2H'T_A: ؃wrv2S;| eő9vV|1p΁@~2'*7QQ7z\K0_O IDAT҃AA^[t:=Uh=m6:[[kws쯎syC8|S~MK@.:4Wl[6˳>lHdzCGks;_|]Bxh5tMW3'2 0njE:Npxт:eC#3V 㳊QiY!XoNro@cep[q&0cT]l'p)ޡa/?kUtɰo ~7Mx8^gb0ZjʂoBhBIyܫKةnT|JӮ6ӷݙ%lߵ lG;NJ3ټnwadzW;cGC]=J1 ogM~2yM} ֍#Nlmo_Jvةmѷ3!k̎l8g}Ӽ:Ძ :vQޱ5,6 /V6k| staVnӓ(l̅C(|M}plq @<{l'oa59?{p]y_G42 t?|$oz~,~c2x[I=>IUa[U|[.7FL|\0e~zV,V4pꢫk?ْA[hml נm|p8ƣzlg,nw~&2Y9 WcW[lml ҲeNf}dž#\w5+hn /ʨv0ob2 >My浕K@j+ x5p-: #,W+/夏 n*>x& ;@|]+V֠2zx+~!_n|ui}.@?/гBԿ]տ rCJO#[^.P,oLQr *Gyg%L6-V '>%sv F$K ;I3yp#G )`;1ԆG[1N_t0/ܡfF.; 6}vs 1C2ŷ'3>\!@OTk#Y)4qP4 Z4챉7l$_30Kvڮͳr٣ ϤX4Giɜ ^#)SK&#{G-֎_mv~;?"t[/~~|m:ΗCJݢBP接I&gv[o\p|/O=ɧ 3&:cLx#4*b[6Xq%#u*)8:(<}?ASSt 2zI_N燐|__< yNfNM:^IR >rkҊ{R^ Rl7cm@j,ʪd!ߟ{`rH ׾G@  P&c,h]}~L>ᎧΠB}J-tU?k YђfKu*^xM^'' jG Rxwq;e#cwt[@|Λ ߅>Z>L(CH_}VqGDW`k뗎u{ S]wّv3;9vk𱶎v]~ c([},r z ~ p%ظdy&p[m#[r_t݄4ʯ]* r}M|Xh/>S~l/ vOyDǏ]~cu##uZ!(>Aٱ=:1X5;:~s.fk&6qdAޖ5..lj/߾h[b^v3V|౧#W#]I>ٌW:݀Th}<=_NFGlpNj dz2027u;RiLlدx+pzjbH*p`WMTDl 駝lfzT8tۮ*^CKp[&jO<=:kvҬW-\2HMg2%03R"~ɈLd_krzoGf tةOůvֳoR]@Ex!xҪA&3u^N`0[}-$E߳' GGvPc1|~=*PDO4o:w n-Nw $㍮'sr:< n0} 'X\p`P`B`ʃI\PdNG~PR`Ih(,pnN7a4~քU^X` n۰{vjo($}NƴMllE:ǡVzQ\E~;Ε+u03nfnGy;:k+{DФpH'iԳ;:(MO 룸@܄t@NG7`fv.71ñz̭KuJ ]HޓGFFl)" Ɉl= MKa tVWQD%ONx/2:0=[mKVwﱥ#^ş4uoc yC+^ᓇ־/n},pӓ;~A~gKg+nLruTfDSP~Վ~\h~9 'd:>K_>:>ktS[$krEk}Lzg ^@.Y9_VsoC+Sf RzZdt2=!3z4\82ZȬuB6Z]7|mO_'dasQ]n; d8ׇ?Kj˃_zAu8N[;.ySb? K{{?y6~";7-Ϻ챚vw {_;l>ϾunpTG]yvgۣW=ߎ&u]6v]]+u ]_15;{ Ʀ?V`kwhZǣ-fχUN{,PtRy8ph02rؿ3<蹼h.lI'φR|NgG~!v* )w<NAd-wm8yX1L⑁%JO-_V=xAsDLu?9Y=kc[aL u?{2 O&GnՌ_m*j\ה81=pM<%%]ɸ@B#)jct0Y~J .lpn|𿉲ZCt/곅G-?h*_x4hݚscw>*,lJ0xѶAPyAaJ_t# }ư`.6hg9]Q<2f7g 5{.^GI?x~pMҽIawPWEVoQ<Ww|e,]8xμ ǞhɓB8wǽ?S  zI硫G& {/Y%9fte6Փ:M# mk4 ߬G|7.|;2Z呺s"$ 5rrڠs/>-( 8ZɌ΋ҫ&+5+}mk>0AA9P%XWՂ䂓/7PZzäm;xh/V^JݓW4_s9< -LمfyL,vB2U7{p׍Ud\>dj2]~2hU'C; /3S䤎~] &# ܶWr年⋝YS,-gm]P K;m"%)N2guV"3{ 7"_})Rn/G0Qr?D`4]pBUa2Zh._h XEB(xe2!LL}*WSNý 9L>^߷:9n}R ɳ{80ի>S0)YFKc_xG!SzO xȦhr |#r]AϕE0 eQid\q]7-m2_ Vd[݃Cn1rcN)hrVOy Lw./xGFV/y}zlq4Wf^mNfW9;ҵ6VWp4^约ﻼoΊNO^8Ż5doG`SV!A+欦L3߽7~x7@})6p]Ȅ m2`$4n\V;V/4#<ӱio6;N]ٓ>rxϹ|`v ~?Zέ^:m1>u `tpg2W_ds1I'ɂu޷b;_:k@:tX}ߤQW4cNzn<^^Y!7ig ]#szl9mSWwMFGtvn힘F9Ȁg'RmM^q:_Kg JO[mf'AЄK9S ›LxgP>7?)o|~i=I =G å/^\/=vzՑgeQ0vZUѧ"C 욽 T:XsXk~Mld4A]grYzu{=YBO` <;dhmEE{-@#m?fJ|ϩke񼮕V}UC1EѶ<{ kOpe=:_IJwd|^~4PORȂ%תKۘ I : 3yc͢SVBL. WOf%ӗ?G{y:ܳI; t;DflZ:дl* ?/~Bk0 ʩ<siK*-[4ӏ 0[o X&ؠGC H 6m,׾A,st}#݀FVQ@x`VՏN0܌$O5U?;(dk[?P%Cr&N<~ʇ|G\up&|؈I `6#Md)*q?}RY(Qy(Wч<=2TyxgBʓ2V$QjJn[d]wy=`%]i ,}c-F=+o?+6T~tÞN)t`ܭ%tc eGrYu)KQ+7٪~ĤI{VF[7vw޸.ya=: o*FC }D7r/ذA1WDSUa\9;x (Ոx&||:oF{э<l<}Y<:x>TxP,=:N&vX} <~͗0YO rO` +:@ʎ8r[8Zopi9=ǿVǭVpˍ΋T IDATlKqz mle4y!|ُM#.1ztvf{!i8VkpFE79-']|*RƣoHktFlƊz|Gٝ:Vz`/^` %h!+>t=N-'? 2t<][m )*WoQhh/x>( "$;\I6Q0IxoNl_rQ-jC݃M/|ˉG6O!>&^ztnl4Q%rcmǏ\;#!97$Fz}0/v3Ů,˸_t^n묿Ng`|xl i4Yd}i݀ o:WoB=.:T{E99$[ 7_̆_O`SZu7u ]4/X?WI,+krO5wd9MRhd'D8'LҮ[ #5) kHX{dD76? s(go!{.@7=2 iyv׭#xON{imx;Co㷣u [.a|z&#^ms}+OuwL,T~Y{$(:^`. J- Idl ^!L q,} 0X 7.e[Vf_Di쉬k;x /ܛv 7Ph[1 ^;:m٭ࣸ^} Mv.8V y!?5=&ヽ=w,gkS>V&BY;BV$,ٰt7GJ7|vIC˭ڜZ"+M頾# f{חސe|AvO2ƑeHM/2/]Ɏ쀮_ho.GS/N;4=rkBaY=*6T2@#+Wd1g1[VEg·AOkG܃M :::-eDEpr La)Р yNDLZlfvh<5xhd2cshZoK# u?"X>cWSt 5Uf<_eNi+0PkƉ{Ѧ~i}xv>'l q07eHG_ oZQ2}\_:e{uFӍae|(z9@y7X'Md!  d!s|WZMK9ҤKyKj.yIikH^{0%#diၛ>B1K#śt?jpSGAp\8]s2 B9ꍏ~kgeȍ`PLl2qv[NX9|G8;0Fj6,0 ;Xwln糒e(M+Y}Km^Bu;LW'?<4^vtF>i0l5gk-zXgɐ-EЍ#XA,N=zu[1w]k|>i+ h{hk:!_:De|ܣ q-y>ٿ| ȶgSd3;9r[eXWo2k<`1ڒ:~?>DDM,ٓlӄRмǪMЖٺ6S{hrr2S1g=^Vgp9=7X9{_? n"O?L M&8k" F]AqZ6 ڴӟdVDUWr⛬~}Ѡkig_x+\,ae25Z<;[r'ȃ-~I \&vcWUW[ڲ~`\!xx#Ih-n`_Lw>֡~~vzb"##w}M]JAݪ+vuĄYl ܗ?dç6M^2| MI%V-". Ʀ^xUG3|pQ{-=céxQ^%tuBHysL~MJ DZɫV̎V>pPV|?:;{\Y] )Y+|60ڈ1pa<^ԝԛ|N mqBTi;jcvt?w#vC~(_ar~>ͻ@86DHW!(';pA־ϩސ}c<>Wo69LF~-^?rՙtqb/96VƧzN5ut纯տ' g7DN:ʥmnbS.1twd0 F¿|(ᤴ |9~_T>yRxWw\ީ-=ْ䦋vz`^hx4٠q͇u8/Kr8kQ / nGhctnvס^ Ʀ<(Qi^p] Eg_vOV] TU:F{Vf~D&HavѸB?6c{+J} ,ڸlKeK%g-gвHĖ > ZZ|ܝ|Cc4;pȊ„rΗM]'vB:Ok5Z qɈG##}4X'x|TGPs< |#\ϕ#BP~D AI>Qw:8K|Eti.7|1Â+eqS>WgNM#ؗ7G%@>?R {]c,WD%LG}7y*u@4Y_i/w_x;ZM%]yɒw5cՉn_1/6)7Hvꑁ{OhW:kꊺ<M<_W2L<%ߞ>BYQЩN+o:5XgZ>lO]::-Ѿ4AkT m ۻQ(>Sh/rf?ë=B0=ul<`.ǞV[WYK@ {i7aϞNcǝ/`ݞ%MGKiT.u$G kO-v-l`#w}*X1Y,W*a;It}mV_qZ7'(o2Ƶϲe'He,7k -o,DTQ-e߫q/q.lF'w7M~9xm,yd|,-U~{T o=FCKvcb`[.=1; >^=OA5Qb!ZKSp:缶ʑkOAqf}S3Gq؟5*YR_{cr fQ`8q*G38:C*@幾Ep0<~@1^wFv{qP ''ѐN||xPQ|,hN %#9JdtXh%/? #|?5JcW:T%|>N'9G6q]x vӾ'|0śߞ@W:'H :F6t josZ ^~ JŖ7FEn+G'+?/3 +ד M7N_tR|Hpv:0сSzpJ ):t|t})ۻ6;≾ Z|O58zF+k4Ѽt4Un ~!HO}wt$m&f.{Y嗤\Y,lK]dF+5l4_v\c/+_w YUӭEr褜(::?>lS>=h\)u/4FK30ʚ|i::ņ[" LA|KWOd=Oy.40 }NO@?Wټ{Ȅ+\ ݓ!1'xoSJ7m&`|Uкq(#ɣъvw:kMgB ߶؏h^~^>$IW6(Խe-6^38{lN԰ oyU&,N9M&͎Sl՛x>{[#۲M <5g`Sҭ{2x5q,]xV9 (' (C@e 7gB4WwmHu&MtK}=GY|pCtS`ӱڭM[%u)R:2 2Y"g~C/O߶靧?ؼKOF;x`K b4ֆ;_'Ӌоll៞+CV?rnHv=6Iy?e|!3^)Ⱥil>Mb?>,rvlp&8ygU@I%rʲ{>^&kkճ9kꌑQ#|doTeO{`*6Qɭ`lJtk2-Z?5'FdU'}s䂶 G<(Ս#Eہp?6}_/WO ʂ_-Nl :_9^#)Ͽe\l O]Dm\=|=q]`0^]|w}@FbfB &?|o{$;=X .h6$[-hOv,/.'6fO yf#}Ҧ#E_| 97^U80ѠNSwx.޼Vibq0l_ó~vuy+zO$&^\t9bz^V+Jk(Fסo&J/%X!Qa:lTpʆT؎Uoi 5#Z 4t9Eqx9y:^|r:NDλ_yғUdw? J0f zdRƀ'.2TVqAߞב gS2>kKnNacӒ {o݀p6nCh@YpoN!&+{lu+g_*A8yzv0xT"m`˶=-mOq   u>tgGGtoXCyToJZl>A5MjNz:g:]cv,G'*'r޵]ss`ēږxElE|˫Nl|`.@V>sΏw`w9t:awuxk,% /._Y2am1\OjE}{ +P,1t_252Y!ß6ad,|dxZF-rrg3&ɠG' }-`Md;GGC6~ZgxڄB<O{ 7M'(w߷˧k40JXVG6We~!uY IDATp3L(Horo'<s /])t4~ ^|_[藎SpPIe uīkkOې .۽C{ $٪Gэj'mw:MT, e G~dȏ KxLu;wIibAzT\ﵠmx=z"߄? \7c3z&-? hlG(V xޫ|` Iڼ[\rp=5n2u;Fr/Ha|"|HCKJ ~n, /nd{ʧ,_|:Ͽ l:s^GnQܯY.kfuӘafƝ}C.S½ o| fxo70ꋴO~tDɵIљφ  ?Xy>emV}-#6'xQv2?*w64Fgx&C6i#f *?[n<Ņs1 č`v+*I.(vnvMlq?ƺaRSv|g;PZ(CgRa&Ii+Y~4K^uYp'EF:w;J{O?txw@:2h&V&f+^6& v xfi'@5˺J6NW{o:^7gy=LlrwmmZ y~lʇ]ގWk"LlnopuׅK 0Vp:ELN|{0~bΘ88N_C|1NҾyc=c|0g'&Gǧ?p1|Nǫc}@̞xy>H dJ@OK|Fܑ H'Aй/{~ا[ 37xIs8̨K'AVror5<=ANrMJ(̮EA b<+߫rOkz[ny>sѹ}!=ќ-*8\47/#T}bbi|m+]EtimAbY{*Y]6]ņS`8.ٲדȗŷze\ )~I[}&PM'o({.|}Ml[>-O4c.|]07=mYw8LDͻFl^kſ/fa:} _<&#ح3Jfß~ -*xO6W[ml3S;:PϦɛ?gm?_{u>G.rXdS:~'M̷cj7Nދ~ۤ8׭<=:qw~,bgiӄQ{z҄\::u=ڝ35ܧ c ?o@D/ޒ)(j7g&rmKK$(Vx2 |S#QmH~XW*JXtZѶ8 `G;'@S3` gnC3| 9 v/ HKĭґ *OH'_iV;hg&w M;ǮBd|tx= 2Ł [WJh )߫hyO_{S\6hG{P@JRCDA&(H΄RWk`]pV8[IM8Hg{O.z>6T_oht]ԡXo_ m!|kEd\C2Sxpt/ށGmUi&+poݿ@lOq ;=A?'| RL"Ohm~I} s~?AW9AO ACb+Dvow?ǯ9>TsדQM ,wtT{8 _e|>޵q1 ~m`5WkNG6PVb>)O~&J>y@G S?|Loe*\]06߽&.Jᔒ3Yu< a VEׯhYIE\]~C.7j8bni.8lacT,^xzlP+{ȏ9]!.} ˘.M18T /e,N%;V>M2JJQIQ]i v/z{bx9NrC}>p9%>K?Yq*Y -8vpZ]9{L3\ttN{% p%|u/ѕ|`8냧lZ eEeO:Z<`), t\xu@lVO-wvU {zAY*gek ^5>Y@NCIG#sᯆr x8|`mzy:ڠÿ~Aљ-·YA{uDy y|ߑ sUJ A-UK{ju鑷@ hw q/jИ%85)sB6]:v}W`Av><\qRU b|L}5O怤㇭a$,:̏odkGpd-mPג|GwM;|y W/tս?kIp{ 7 R.},i43l` *m:y\[fuhҟ\}Ք}Sﬣϖbc#Fd~or]y~TgIJ|_Ii;^Y9Ѡks%ڏ @fm/xx'YhWp>>]V|xWrZ iC3 "xl@ { VS٬ɺvՕa@|od3Xb+ > @ҙ ߬4p,hEqcbrl!=%&O܊K}+wgҋ15\5ǣLXyo|o[[N'_o-۫5|tdmRu`/ƝvtT}fؼ L}vqd2.=4l~sV7ț^#\'zܸ5y1!uכt JG>)_T81oKʦsW~6mgϣ ϓGq( koSAIq=0&|^7' -W/##&m wqDKS,.;IhڟuFw1l#N M5b?jӠxt~O&t(>*zr8($E79sD!>~SHGQ]IctA{0* &2uf[[kFOМ3{.,6,mO-w0 udЯNH_~p\\s78. .ah&ާEw !{J9> ;W5~`ݮOu5M,O%~}@]r] ȆFώt>iW V:8%w Ϲ;m`z#a9d 0ֱ%tOc5Rw!|ށ5IDyUohn#&cbxiP2󗵏ɞ:߫^LtWvS`GC}eEf[`OХ>,PUftp,Kh 3^܄2?Շvmѹ? z:~7[pm ߢ|M`}O$O萅p>G& ljdQn2c6R̅N)kJw5ojގo,>D2,:?Ե7۸'=yN*[} CM>g~D~)M յg:%2Y}c|'||O{/t,ȵ:nL~A/Z~ ޻6]U.DD1I=Pfp%'Y_>P~|CSN2ʆoK8Z/0>;^kTo'~:hթ٬?5y&%Pn@y*W;Q%p&840]*;^?&[M_z=G"H& 6AweYRtq]f{!pm 7~+^6B!=_.tH\NM&£gK WYuM$E^@o߉ L}&XY_(<N]Ymڤw//W<^g .`k~xh5=#ɮMhAsa Z _;qꂺ<79bir4qm#Pflp?f*ʤ_? A恃N_]$ -7^$=p+cuIz;UKipLJ[?Wوyo"9ි"W/v{Dtz/8'&)eL5~JI{OQH? v6 va6hءAIFin<L 4"S|4zkqxv&4G@ȁu]>eh j<#E8Yg{Ӝ[a,G8ftQ .㻼G])w bFjP\t<7ubA-!OQdCnu S0AwS<:'yZ?uOu+ .eGSvA]pk0z&VʿlpxZdN a<2En3G{Cڵ@Wږ/Y||ݲj;L!QnI3~I4 Ll$.0~3[%?oU@%w y59Ϯ=6s[v͵'ř`: :ؓE]}q=ќ?36UO,g* ~M6_OiuoO0OX D6sS(ˎ]ADA勺r$L k &Ap?]_`fO |,4|hoA[{:S鵤P//}h[Y! tlDL{VVjWnUANGUĐ IDATgO65L R:>V4v4er[qPG+WyΒd|3ѥVrx⯙Q>{<];o'lL<|$=@­|g\ >Ӌ%*!viwx3I[fSVltRŞn=?:P|TM,%P8E~%N8I5>6dxGKF.?ӫ<<?o"U:rL w2 WMPV_#]L+.9КDd;h kgpe8Axu;V(mxGgx s l~KEgmGo}O=;>FUWɮiG_Pn6wx2o`L !W&Snn~bMxQo'~ٓ^gG~zy˼|G xd4 0hwG[ .6 {" _ykW2Ξ@/K|&]3$< H@O}]O>.*\pt= MbcM^d(:|o9Kΐ}x4q'ݓnDI&حM8DtlWt+Or#&9Er|cq{7Ut{}RvubT `}~nSqXOIT\˭թ[/ ÿy=KV*ʰiKEYtLF~yp@÷ h;u ߾Q6oܾ3D7}9z'~ГwzjFፕP#&Lj'y2h3|Aɨ=dNsA}駭U$WCQRo!L&,/]̙f_0nAĦ{87ܻ~FֆkǑvmn::} R׸kAVKiu6p]w@?} nv?$o,q=]p]><;F>ϯrǗh<*d]8rEzfʚAظ"Ƒ_14-N[6:ДLj! t'4`J*8 9"7+f?C@-/ϠBjCE8WiOV|3 ,~Զ4g o󠧯N9vN*DG?NP ne12L dSэggx׿ T ]kz' Nr\eDS"6we 8K;:QkᎯpӡ>{YdDՕk3X:uM=!b(NVQ}yV- -Cb,=#wM?İ5yt3ьΣO&xZ@zN~? 5<+;m0a a)o޾~wʇ*1]Ãne}Y薿/KہvOO8脦`ZR`I{8:tu^ v #x$>қ6g-\Ë'X ;~3[(3{Զ`H§[\>H n6EnGhE]>wIÞ w_U%3oZ݃w6*X+A&w|x(Ij#߱'J?ߨ^ᕁ|?i{=<߷i*|bq > ~. 6 wFQX0>UӓW=/ xzdmK>GG 3^TzB[K{3ap&Sb*xOj7R˜aONBU6KE[ D#gH >;>hٌnlRG];1Br[e _t_?ͪkcb`~L{)SJ aW?ᗽֶg++;?ʇ{֧n |y67cȼ2X,|zٹphil xS'eǯ/kd[_O1+&lAc$:Ll<wOh5+q"b h~zxc/!YTvE&y+׊+M>]ߢ,%k\}{8BBp=tWJ?EtgKG7.L1mg{ JBcw6$Hi?ĄZP@~ܥuރ 0Ӝ V93?ʄtktVY`^9UB ,Fp;F}R\p6>,y5:p12 l8f׈ܰv ?rR jA!_3_"kxw9O wxn '?#_]y>뜳מ¯VL&1IGFҁ{mG||Y@~2鬓|& 'czcӤ-ͺO_q)kc^w=i0.6@\PXAaOF/9aG̨'ixJ۲U4a:3h4?t2N"9N{y/0[dF$Sul:]6}}KGMٯbxb|vWNvx۸%=Ob/*DmTh+"Rnki|B c:>ɋ?QUN:N _Y'{>2?בܾF't7ylM_;Ri'k Ȱo3vd <'@2R o⋂D??W`_^3NHZ07{PO <#"iT#bo;'MȦL|.$VSDK,:i)9BsKᐻ5/؍&u痥>6Gt`ƳveeSlcm 34==я6x0؊/O06m1{PtM| -ߑꊶj l]ٺMEӖX'*{ >pNd 닦 [YwټM|5y"s6G6U_}⤾`+.NA']ï<W8)dž#]bw׀&sLP^٠/ό{bJ]86Mxeq,AWp@por(.=capfΞAWiln59#i *==DD0l7<דKN6GSrsui.ɗQ2xC9ϖ1H5JG8w]07I&yo x}Ii[>pѻ?ە!ʿhDه_ނ'/Mvrp$8<8r IwP>M*8]0jeF_pW~?Guרy:}hc:Z vk݃r/Vw0?Q&@Mq-5Ф|Lۯd[cgӇ P_Dnzz ?k2;WNkKЎM>?~7KWo$w[/]gAxDW?$3_O|7=;Vk@K/&M&잼3~#-;䴍#+¯ZBɟ/N94we Pְ}bqh٩dvg S@K&A #ئcK% W7f~ #xC!~I<trWo|)Q2k@7RS,ltAX^'bkHFm੻6=^K'BAe&k, fu6[?&+Ɛ.k^!&uammHLdt(~.sǘWW_; D '6zxLBqtV卥H^=zSmOv !xc4MzGF,K=}Ic >M\ډ=bnߊƇe&#zBkpǎyd*T;?O.?Ս6Iw6=.`&7wӃtSj&}T2BW`nݹ#p(pi:m`ch4x0<^ğ"]Xn^ W<lm|[P:ˆ 6t@T+6bꉳ>:QDh>>'?lI3<Ȏ1qw7A=s}jP_଀wm|5:B;՝01 *pE\zZ+*OM(T6D2~v}\ڑʞ6|Y_mtLA ui7>*s|&&|W 7{^?4ߨ<k?2=Bǀ`?Fb1y KG@ pL!e߸Jq v%Ŕ AK&c]3E =cWx8:(a5 v2+ϙ5dQs O Z~`;p5Kuoޢg=uF=i,X{2*i`濖uz( .H)OӒZ5fB ia=|pB模k߄O[{ cݣJAi|Lq:W.y *8h8Wq4:lypg78[!>n5~s5Gr[z=7?UڤLJg7qڠa{IOc1g^#iu_|?tn8&売/{f;,09݃ͮO&=b|lZrtm$Oוhˏ@W7r.K7OX?kH(g 8|{{9#-Dz3<@?\{Zop6\2dӗrMxtGа#_j"WsWYQMʭ߻ud2X=t G'vt\~4|4IO.xTX\sڹ'k[G.?pW"O:?,rz; h,$(M7aYXajg?.I>IӆV"ڞf!z{^م: k*g/7 h*c{0?xAI.zcm`l>ل@g9~kto`~ݧɿӑʱw7 }_>\*D򮭇ʷÛӵc}TDߴo%ѷAgO~,Xy"T~o}h#˙ LytL:tʆ! z}E䲄6fcx݆(qt_[-}IiLL>1|f`S3T p{m_4{J6kn|͛׽zlp gD^|wll72I?l5Ce|A7a IDAT#lk xj`ҵkvؗi톷r{ \+~<&}L2 Fx$! nU**xބ}όttVt̵& ."gb/3ռڊod'B>jt e`C`bS{_t ]-2 ,=] zDw➔@?6:N"&2O~Hɣ{u(WA| {T|#6"D(c?w,_d}]QJñi6i'sx;o/w([tV'0b@7)hFmp]K*.' Ϙ  8jhm׭' [mdepu?oltz:tX=W+12tOХx9 m0wCN Ϟpt`\rO*2e_=] &) ct: V p`tZW9|yt}U;S .1d@xӲd}v9}0 l1O)GalpT^9]lP宲]yT^~]p~}}~D]_*DW2٦TAѨ̸CzXtFh|mbL5pGG5.cgPaJEp >| 5 LrיOjt1ɲ rchyGw.r׽-+%ϥ? Bw(j҆>rméaM݆lT{^c;]3p&dX=`;-o~g~d N]Ƃ< ll~w6k 9=^.}A^Ddt^gT'ځK~LT8-X5چYُWg Dӡ~>z,>Af)bG9W|OxD=%j07>&`V7NwO~9 J#~g3 '{DƖK댴oD;&Le^0_ #pF{ܤl J.zOk<[}Oo BgMOY乮]{גeO㗱^m:|u Mh+navNk01bw2LM􌥫W_>kP~2 5}%=dtѓ4Lgo  -ck'fO竞$ >gq6 !Z|eskDSt)_Gl?'}W6)I~_z! ֯W~+$ v~gmS-zX3$]zx"m󞤾~Fx_;{ ]c*++1ȯ' u\M|`X {68;KN\] mVv_Lw7X(x> >_C<2cG}˓45 wo?]KI·=IdP8F60-OpiK4vڀ~p?dx}\pRミ7Z|& {=iduխ*Vs5z@gBQ'͑JG٬~h|gO)|2My#Hm M]=;sLoᓸzs F~&8~he;V!Tz!]3A"2^ĂzЙl$1 `=c+.ұv> j/:Is'i9e霯 Lr,LnGKlB.s8}8?e?Z_^OZ& Vuh>KmKgZVǔx0*؍CܵRvMэYgd>z0^&jy}-:Ha.SiI[\L0yr>.9t9+d¡hSTշoeں+%=PociO! ^ 7x8sg-`ẞʓ>! )^,G4Gt9h9a\ьht-9TեciL9E]8w!5uS=7 :_6>EC-Vg!FN[GS%.P'w7nZtNwIhlL1$m]4ʡ6 ,+@>.'-5<^S&|HG/CCy'tp*ÿ:fI_w| v͟/K%{$ςdMfsO;ڛٿm~p@-a1<iJ(6cr^E`u=N􎽯LL-׋>etUf x[OG_.@yU+;c+_邎6?U}_V:&|lfmI!9pDG}&A^cm/M>w$4COڼJ+`hIi$u|Kl 3AK$'M5'KOr/O,Z^]ׂkQofVtN!Jlݷd0ˏl{<6I@Z&|1AZ;讀03xtZ :DS{oү&$>5ћl64kY}4Y@l`:#Zi1}*s4pqwcVd\'PBwlYEOw|7 Eوޣ᚞Օp?}8`_&G3xxg{D9t# WF 7tg&%ViO`<_l&ūn҆NfxCYD&1sto3t=MXH:de6fBק+56\`5 &&kKhp/ X& Ao%ۄ61m|uvfq~ 2ꈪ$uty?Qֆ4>a6a9~_{wmH~9_ )IAJV=4@GkWMxe[zN.Enzz6窓k=OγKx6._5/ \$#t|ku{><~ߤ+G}Ҧ+ԕxYt.~ڱO^~;Q| "]ozlyxS= ls/ph䟞H`[ɷwd}|:_4\zƃvo}~%gm/ɸOBɡd%F8DFÎ5~ښ_gux%mP@~vtv:}*uΟϫHe>X{SkEZ!oj,M6zU3ɏz0f{jdO68M$Pn/ p} Jϟ~l7?R am"]Ipr26\_|tCuڬ32ɗθ}ocopɮY1b7ɿz:JVҴ;3]Ԯҹ9þ1GE$myo{0?N)vBςCθN>C`s{mlgOw'zĝwJE=X* Xkw_$gy~r65߇1 l"7-9Oۀr&:m8Go <>U=4LR6<-T&Jomg!I{Nppѳ1v;`zW?,-12ygOu،Թ*pG˻ӱQhxN2ovBh q19*dNWOxsd-_d#Pq0XE p~lb8saO!XaBmx8.?Y讲 am06m ^kpxhF[xN0ڤg]%gQa̖v `d| #>8-dTO 8ڠywK+i'?"q+đ8U(NI?-SHm٠_忺Q]]mCo>0C>Q<ãt48>&G:=sgIφ&y{A?u;aoe/##W5liՍ[,s>ɕH^^cSjijQr:sWP}ig:K'{6s8-#>xǯ MV]&>귑U4|{ecڤU4tiPTrS3-M/]Y\_j7oUN~èδEsAxTnD t;?gON['q>}>q5WD#//?cWʇ3*TM:ͺx'Xӛo+kb.FJh'Wwxǽտ2 O?&n7Ab9Fu_5\7aڠ{FMYn/դC(s;:B'LKNyMrCYpgJ++W~ J oi%8&@7Qš:U@cwWFv%:]M'W)&L  ,au(^FWIk'qݻԈ}YBZѷlYXe}xOKm bO_عO=|nbyȊT-;MRcY槵!{!Y*OF ^x˖}'?,|[DE { !~_Vgg0~.zlBbVC<vڧ>)?/'sI?qftIWQo}鉍O>8Ϳޯ :>_>W Z;%q$x)x\yYpS 8nRבʭ g@?t<79 l@Zp̶l/ &heg+J dT .èl~M3J|: ʗN)ou~~cIK~ |VՄcYB nWX MfFtr!}òr;[`>Y]Y|m}D?17_ 'c6"+ MWѮ3`78CnTj,Uskhv5N|g'&PϾMakοnfo8`?è-;q(wkvT|>#0EŲ3H_٫{bLbRSn@+| f FZYurW@Nb 9V-=dK(9ÃꟅφoAyl5 MMyqo7hj{Q=&_&Yd=:L|ی=Alh;-ul^Hya:Ot O$_+WiڪﮁCFX:e˧V׎ fDJ> IDATg89W -uol|XM:?-=wyнyWe/Mjyߧ7ïA?]bt6_b  oR.&ϻjOr/=t,YOlӠT-LO[|btHv7_8 VSδGWK`]Y#R?k= |jsgafr~}8pa'y>J$5ȡD!y|vn=clӣaxMqw󄑅0^ܭDW>M2N$"]RXސw[?k/7Iaok7O3/mO}ҭ?];?awe,aJS7ړޤ$$ed0mdZ7$MFAHlzo2ڹIk3? - mei #9>7Jg3hsJM3f+m\p>8u,b;,iL '}r.ť;_?b9v}Ӱ>ڄ t0zE8z\-ԄNF (Jб0Q$o!&zdĻ^]]l` hZ|OW;&5)c-| 1Hy8"}; 1_TpWK@WV^Lk(1Y_ 8ן63wwSvq]>I(5]_ Lzv=mt~_ cxxdmO./̷>iegՕ6]Db$ıvPnEȊ {W_ѾS#PMK-v3rأ+.0ʢJwk7c1ty/RiFS8Ql\0mu!,͵76#6a =w!smqn6t_%ށ _}GCjOa`@CγhPbL\v #D u49/g$ã['EQ\}L+Tq|&F5Ax9xϝKfap8=/!D8t+sq&X{"kq]gMWE u&sb$Fwx1ɂP;tW:I9^l K"8<* [z0Js'-;E؛\UrKz'A(vTD+@7/@qc #8>d\Guk={*ک&A&'*|W7 etm&l=sw$poCL*_0FI~(`bu 5sWm9N?MpV dA^rWdOጇ8ZJR&ó&c|#_.[c>*2\{9d5)5..N  O4at E0]s- &Ë;OL\+<XS5C.ft_W;K#i4gܕXYMjMk{Jg#?Y;LWi#. lc{g'~W@EܤEǿ~0KKV{xvgmDyc /+;N AW}YwwL|nVz==\ 7ZH޵QȞʜ䖦/'#G *S|}.[,oS\^~ gsѭDO˫T|fMuA]r[?'[qOg1t%0 xBcw5c勰I F]abp ǟuG߹q[f>/gwӹ6;Ž<7o^~U$0޿udÔg,!IC;JW//πh7Y2(ߊ ?秱"砂o|oA' g#~J'/} pmx1 VH A{D>!mMM܉|E|1RG;FU$hrTlY_ԥs0{o-qaǓb|l6'>vNo<̴M/a + ۪u8(vv, ?=u`} @r l| dFL؄y4)Shyq!>q€7V|W@e'l=;y ?ScBz>gMsenX;ax\ʸLL%?:JӕWu,ӿO"%c~vdܧZ}7b‚;_W5 f{p] rpC]t>CcDŽUt|me/_V}mBR#ݞ+'n1_ldz0\tw4_Ux <>!dޝ-^Ľ i)dNخ M/7 hC [ĀłF^z't} ?1m:U\iϞIw٤`v>v2e/g/go7% ?W.|y1:1wK&xSBý{Yn($9 ݧ OEnRm2ߗKMu|K[1]ڴ&3ѨxT)9^:ALu 3ܒ&?{rv;!Qn96@4bp tG:9dP@`m`ri,^& $(qĻ*?xnu6m0(~ABU{a yqLZm6@ +O"Oa;;Ay-c٥MF<{uCSޟmtꞍ0ؤrcyt"kr\W|u2a2e_J~M&+߁Xg__"OEm^4ldKCz[ʈ(+f}bu>WLƏo煻ۍBV678-VO6_{ L 7آwn{+yyO>;ab^XLp R}q[}#^8gw,دQt^Eg>ZtH///|DNFk0 ?7W٧O|I"KENa?Yxr/> n]\:d~֮ ;|?Tkc_+*Z#88%ׇU}+ޫ> = zXwG!t˻OtZ[#ć?MO:;5:_lKueR]qg(WJaʩd]% fX;%q$UO6V&gΝ PrHl/NytKXZ> 8&c% ʻVٷMbd{&+?mwU_bX\jMn~ЂK 'e|m*fi2wu1PW?/z\&9Wf yoޙtNǮ J/anяtZbÀI~C|^h59$S#v+Fl-03Zqʬ aB1&7Aכ9HK6 m%gctڕ``=i&.Cw;UfۯM;Ȃn=H[Wgދx͖ gw3Tdy b@{<9S~N4t] ӑ $R2|Eɶ7OqWMwxigDBWvzy8ǂ>ӧv<գY1>Lm)T솩8=쎎(w6vf2QYzF%xz {4=y+'[~qHDs>iÿԧmiK82ֶә^6LdVpI==#IYmk@No<)?VHEՋǾs  : `tux3pTnWi~tBg_|xko%ە.#b]{ <%֓Lozgn_x_փ'l R)=voL3Ww;vU1F&,ou3iUg#îC[|lb#Vՙlnd h;[} խdWuwrQLIq{? }\m@6L}WKFBOQ;L-́\-a++=11x{ϴ<5@ zSE=wYv>./Rjg] od$[lA5:OyٲbQ{ʙ`D8&##߸68؄(:__]+7. f jr@t0KsO[W%:x^$LĊ bN;.Mgxzm$߫?okKT ɩ 3{LNmXpxaqlŠ ˢ;2Й>^`g$#;?5{Niҙ_L, {KύY 1”F_(;Ti㇥>c6h۽)ӤŢGgg=<~WD|}l%{Ɇ\\eE\wɹXT_j |mcb ]vExqUrG7w.?jlmcronregĕ%߸^v; kܰ8foɖަ]0lwTWCٸpF,~|I'b[?=ʗà2ȼ9162M2Mg1ocY>4WhlJKr(i)VX'2ZZaDJDqPg+ޒ&7CFTdyǼcE<(x2;?gH:q-n^D)Otl5_2ᒥW Ƈ=Mxѓ7$]چurnPaU@1AO'|aC?: q<ȭ 'ݕn<5Jaat1ôa}GB*mbl=[)|xp^)6OEyo@SLѹ0PVt0s+2M IDATouM>C *&`X*a>cړx5@[yu]5}|7:E=}Ήt/P7[gkqV >J=9n 6|A^7hY4qӫ6KGdz[G[&qG<6F;l@xu-熁;L_ LLEWEd~}bl[viƖ fؐ:^_B{:3ѹ?ƿÝǯf=SU/agzNt땹+䁉?[$P:~1R:q`ɘֱۧAx>xޏ{ }iͥ}]yvB۰ѢH?'WC)L~>mR]it7 лG{aTfa[zzKzc eُm@A%}C u&$ ,⏄͋a(qdȎ-Nկf{(b' }k~Vӎ]8Lٺ'&@0_}4/KMk:ohâ0 * ]?=> ´w F&r&~p?/[ uMzo R'#o@fyc7MH?f)ȏhtӷ[mw+r/g絻Ea/{ O.4a„LT2}qqc}lЂ~~[9mgXSO/V;Nm_w:l|)6gp8qj?ct(u [Lb>G|39Z ׫#ҧ=&|$q5p9^>líqmb`t%7 7)+gؠ ~Sv4^Xmwcd&Ms=ǰA*V3_6qgM<e>[>lAמHz &ܐ@Ѧ_BMgd^B3&+:1c䏖彘<ʫp7igH{[4DkOꚲ]ԉW8!#g킲Ťw l&$Sc[V0}@]ɘX6> b)Ow8_i<[Tcӊ:ſJ}ٿ T?qZg6C&Dgk(|rCW`n|$ʕ{'-tx/vmkP ˜OצFI}1a=J/]_Q:~ӽcB_ɬf7(ubo+/z|>$v??ZHo>mpNabq 1]쟄g=G-.TR]Y Kl=.nڱn-A:mbƼvuxD0Jfc.xwu Xio8qO쿫b2n.o^|Lb_YJi]uҧcn<ɦomsʓ=ѯH2?1/` T.5HWbNٕn{G{oVw w OLmM//FG*|?W_p%ݍ1ԕ ڙƝ yvd ->dӞ`bJܙ؂Ɔ31CVIjgaE]k7$>MWFxF˟&A:ѥË]pt0cJu\Y`|KH&~D|U c[cSx /Mx'gvaƤ!mpU"_Yh**[?AGn 17:)H?t1?ǸlST2Kovџbˤ x>\V*Z 04qJuNy: q4{QA4ND 2# G* 4ώu 6GiBUH>M&Y,0P&yGvɆ݊5d_?nKcXoa4؃Nt8P-X=p[ $< 2A|wzSylg履=;gùаy }u_%\ ti:G_^'o7N lD2#J_cџqԩQq~Yj[:OCbPeyym0)Fl·7=ҕ'=*s1ÆxHchi!_d봾p#@=&âM>п_УZ+DFĤ$IUtoCůjwh+;vY|Ue-P&}^OxW}w, W"Jic`>u I7I`<`Z}v?)伺Hr-<48{K'Vٝ.ld[ݎL{4?30x|MҭNo$ -FS#~۶|9wu[`=*go-͏Y&+lT& n # mXLWXۯ}3+*W0G:QZyWKJ4g;3J&L5@hf# hۙ  ܶŁOntpU 1x>C1Fb&XYܠ`]U,x]w!#\X< 8S~y LM< wUߞʛ(BFw~lA0<=G=`|fb8@L.v-S}d]T`q/A# Y| xUN+s[abUk_gJT25g$ӹQ* ʳ-bV8ddܠ=&Z٪V)q+c%<*oO56䊕WEc7D蒷z]9#)Mzr+ĵ6v7B=FPjQ_)Mnz8oRWWY n4=/ =knR|zŊ qme c#q{>81|Fr ]/|{XۤRGg1vWhW߂}>6鼉sǃ2/LMҜOzhT '_/O57!|a/pI/=*3{MaQg6#^}%> U[(X,/"ϰ5~#79 '/`}sO߷%_yO|-fgŏs\ b.lO-`糤6y$?әy H;_~:"d8׀g}Co-z`yG=&(Xi*~a&Ϟ읻JIN:clpI {p0h5/~׸c~t0&s!OƧ_v X(K褋m|wwEJbm+os] {W7DGi$rK'c|Q0M8}@@?yѓR>_S+*㡇bM"QPj菮GwG&虈I;O\<+8zr+yuF .e70C7(/F=zctVGgSt/ys(c_`.9ֶ2ˏ6(R__|Có?Ql>l=݁E\+KO>_wW˩sG<=aXh');St&1|bDY7Oc,);qO4T'ӻ}?umwe0_,[՜AÓb+ހHiKw`[qاӵ0vz9i6"<u`@aY\ 3>S'GGV6&O7ek63aP']~b \ِ:et&ÃQ&&͑8<fI[ڷLbVneNMb&g{ަ~#!x 12ūI2FO[]VM.v66*Xd֮/hvĩ`٥B|]ylaQAIU:WW4.xmgΈ/mv=&?]/[e7+1>o9YFy&vЇ{  ۄ [zwk~|? Ì؈vxNh-|$'g#;h!LѰg1!.d0'jNʢQWț$6`Ԧ/܍Wɷ}&ӷʨ|xK$L~{J#cw.h0s3GvwwWV.Ü-d|ҳke`\LUse,Vm.}&?k-llx?ݤ .z W;@D7ap>-Nh}sYQ}>So>Gu֖GHY|b?,>w|N6}f,4L[<߄N'y )tc͊}7[O|ľdRԕx,-;fo&=koQp&4 #)iђM@* Gn빚SJs:R\I zhP5n@ .eة=؊0&g.yj%_o{㎋˛{n91`ON]}G{8}`0{%eAr4r=WpFFsC=ѕ vWWOgvٖ$oc?J3}l[@d{n0ld#@SI}|<'[,QhҹW| ` VXPjnd2@m>YH1 ?@`T IDATb1^k%ipNzxӋRm0U=8;{\=pIC2G#NؔN LLJOJuMc}uFpw-Ol-/(;RN_Yښp"[xW&^G<@O!MDxUf4[?Lٻ<>莪@d땍Nw8-γo 4Զd㏶rŁ LpgwzLGʾ,G{u}_{PS<Lǃ=>:EݡCT<wU/GCʺbMo,n~"O{}m`gӎlr|z<FNjʮF?zf u˘G_/-ߢu`,zFھV~XyNoE@4.6$\ԕ_?*̿|\|Ug ^ sok~#Λ@^uy'l)?z7o/LWrߥ[a[G!{]Olr]Wl^-Ն~_{q _d3KcvR⫚5_.\_{ׂDm+(];8~0g$gtA'c! +z1ƇlT S{<~/O}@C6wd:%Nc~T #"Cgc.hu|2^7d9GxhevwЕCbx{tH4Agx~d2-l/jt+ǯ2W\Wx7}ew7\tޑ='MwGܧVK] orc P"׆*H@'4l#y|6[G͓_6d bm+XFⳎ*G{BxɆYgtڌ)&f>'ū+6iǮ^=ԝu>%R l?,ۅ'=6>a4r5GӮ5/l:txOiAWB̆g.tH'| NGw/iFR~ >-ʇꍲbaAOqbYg΀S4&>h-n@]mE";I/;^ڂnm?[ʏz[ҹg߀_&ӣN>>$OVrC-,]{\OU4~L:z{2*sJ4ly]UF~_5 ٤6\IFڣ$EbFSzezH[^#OcⵟX~&Dюm"@l w۹t|md>=eWǯsW|dDN'c_}݋[g|+zi+^x8fɽbS|hs?6vM(w:wl;]r_(gӵ w~柬}Bp{}w_Nn'd`] ݱf؏ 6~$y<w,ݻB:-%x]S:̦Y}(;c fvF7%ݭ^w* MÛ^w&d}^lzZLpZ;%Nɿ2C$=5 Mh~vM$'m:lf{m~~ҍ p].' tx;}myA|Wߵa۔;]_k?ub'}ƗGAw5~1PMw}leMw Bw%c6f-8;0gGZ?|-e'[+A O?jd;a PWݵ`gu'Љy;MQ*@Kh E^TFɄuL`m肐r@Bwv> MV;q1їUbB'#`0PVUF\~&΋lBp=ex:TD >B>IkÁt{b㋗E$зh4}h,&۟vIگounv1j~Rtk{c&o#dy=vmyW'a6 I iرA(yBjK.L+忛`DR>eWm2vK"^3L]e_>|B78gi aX:g{`&Qy@-suxUҡ^dw|z˷>j* j8l} `f䟵[dZ+{ߕ}_\΍-F黗YRJ؊w~,;FkCH,uY?C3֋ݝ#^kZWٌok/ ֯*9=͟LMMiMv)Zgy,Qp,rVax., O򏱉8 Qg"-"6>l_#Y#ka|ȸ=[BG6īBCP-:fvLOP׷"^:K0d*}0B&h|dߥ#3WVE $e{[c<ƳۀC:cQY'Lol]H.gU^AtnGϱtnIx5&d\`?mΚlsbG:5vKOls)MI~ԙ͓pS*o%W|,Y@]zag?`XFb sҋERf>.hEC&yOUlfgU6q|N^xxetioSm(NvED?$f?{bsX>>2F1<{ W??ptS1hFt]\`?ᬓ؞2pvTћ?xOtaV|~pDW}sձ>,n!Nϳee׮'GO>os&󃸲qL ɗ̓ăWO_o8Ǧہd=[]8FT.E`kfa4$[9)s7ت8v oY[ rϻfu%gMIB`Wn $@3*UOc]hn2TT} [$ͱbh>:tYb{k-?3~w;aEA}RvJQ|gp[W<2/u6e/MW?Wɿ x:dZt/i=.[?[ʋGExyޯY3O}[S[eΗ[ᑏgөhﺙ/oK| 'HTڴX>RgX}3ySikLM͋6@Vb_{;e`t1p?bO1Gסo?veLv_Jv ߵm&OP^g-]?&rdү=v?]6 sI]F"!o}E]ow0b?Vn=S[`_zO'|󥻟=9bH*?k#X|1K/<."?ol+]ܷ Q}bIN߅ŇT箓&߷c[3ITlq83f.s}XLւpw,(p]ywRy tT^RI,m_4Nxۑ԰j8n)kņ7_~gl o6l)cyoZ8iHCl|뫉lwg-b[\k=m8b)]b|?6z=ƕ㻨RԣZ]{_ZW09߂q0~`re?~_n,j۵wbոB?7gz (69N 'GFNn Юq』-O|8bM0@PLBEnI~wR I:!=Vq\p!5Сˣ+{{gaN)w{mUl=?ޠ]CT@Ա g'GFrg`C%wpUHi|IFh KW]gU"$׶usKsXZ\vub=pێ%&~,aXXĤr\"WW"MJ=7( `f0jguƥA|q|o-^/\h3ԛʨkGy:0mrvtOgs"ҋ:EF"`a>-x gcm,拭)3]Cb`i:~yȘRR('{qv2ú}h DQq!}_1IaV2{ڗkj+t.AFF5gsoU&+[< W?ǿڦ3?-V\U_1@5d&W}Rya|;g3HY̓[yN|8߂Ay\~تKpXP'zD( [GOV__ޔl2^UO!LȌ3& GWWy<$lM Rf+؎Osq?7 t&x_rwF($,lD|ጰ[ߴţnR<&I}'.fΧSg+x}nu&]/!&o?oR.zxjēxڝ5ՍU'S?~X.'htFpCga.p~g }]_/ZtC~-n:=_v K_1@e瑽ò,}s$׾i Ͻx&b/|_9\ ח),S^kcsqmɟ>rxb]tbb *!_>$Tt/ɜx8dž~|myD15F$>aHwr*ta`\w5n??ƨ;>?V '~OI*0 E*Wcy%R[ Pbx J[`V=d~lD Fµ {b_? 9N5aayjN{vrZx-1Ve.aaMqg~XULsJ]>{ ٓ7ɮJ3~pE*V0̏h]| S"K51Ҟm񫋹2Ϡ5"g/=.ֽ IDATM2&(mp7]'C=lcqM7 vW 3ۨW,>_TFnw%*E<&3?7]Gw5qK|q|Vƫ{֧%#y7˜p Cʟ̄My[W-vDbﳭY^YzW~ۻK! j}r0N{'5=Fw._y{CuzWp7h:Yt˖gZ+bE{BgpW@z͸A}+Y{ֶn+:bFx93C58އ"anli]n;ߨ8ѭ;XLzis^buϾVD?;ݝze.rYfo?ih P6'm)VQX}*`K9[)y[&^yM|hh߷ɧ0;{_|htF>9Rȹ3i~poRp:g26W2y4gve$#aGU3m#+M_~\Qg<=gtUs 7m>G79to~M׵gu.L} &7=YYc fvv \?e<О_#% Xba`:SW2>k;boWƋ.(kǻcI]&̕$q0?t->|Xzn" '; ?͖ͅ;}~rO|߼3t I`bS*cO|}/d_>F},Ho #7*/[^paaؑM;v/$Xs*t}kgݑ3(9fvͱ2@+2cR]I`RTGOL202~k('gC'^zG/l =:so?ҍ.E!F4A|y$6&?]JJ4[ G Рf'rG㍗÷[>H5 y,%_]ׅ0i;?/&$ljV1:ȯhUܪd=.&|*Ia. [Y,z_xɫ} CŽc}RzDb×̐] =Ý:) &aj|O#?н~l57P޶M)ή=M^g[~gŞ#^o),y͟ElI8~L˜Q">ryrW@p|Ea]5Vv߶-v>7ɧUr~ $#nebA, Vg1pope 6D?zvNۑPnZPY!OG|;ZmEZ@=^^ԧonOB2gt>Exl rAz(za2Rm*}߄Z*&ixWݶMFgN`x|N=/m[>-;xYdzrk?-h+ϧ>'F&j8,V.́ԥS\} scb% ѐ4D&&!pZrG;o#&{t[q8]Z10ւz&y|+|ȅ3ɣ<ov(JaDquhV?c*NU֮\13C1<~&ߣSuCi8ZM'cӂjl2X#wH_>1NG Y# ð&Ķx0|4 f=6E2q n1b` 2È|[|L6Kiyqɨ.nwIͿ&I471:[_'>wxc~Z0WԹGi}X'yǢW=?)Ϳ(0WCyiç4NŻesn50-O&iu3Ys'q@%8GEc(g A) "Xt A6@'xG>:Zs;*]{4{v mtݑ Cɛ!9LU( "iʟ<Ag[;g_}*<:lrñ5!/^5@q Q*v m^,}ˆ|/mmwRɴ$=KgT'ON #& zKX][ "St`䘊 d8G>JCGѤ) =f})<)e􇭶@WoϚ( 3`B76t072aٗכ1l&h&ɠ&ϤV z;ʟBQ%+]Koϴ?#oe Wؒmםf7IL7&&$ݿEt3b26YS]d>phhZ4QL@nbpJ;Mgy?cC/ cF;J| UXFLVt|r[z\waHG\Lud8v2^"ŝmQ5~BSڝs[1g˻ZY aV7n¤m U;|œ_ϥ]iv(PNŦ3G/k{g;ɨπF1ƛӛ-hCc&'=F,j)|~ ]d)ecϊ,0{h|WnkűHآx7l׿1 =Jt,~p)~[,?Fan5/&}o]5%hw8}=yh}vGGI2v1į`EW;PhZ/3YAX)W3o죎Gz~w w@i}hyO~|bs*v:s-b Xu:$esѝx2%mos@D;='_Qs=tՉؓtr껃_<~ PC5?vd 2^v4إ?xpĹAϞk7gu9]K|H*6ʤIm& N :Ѧ IrV3;*b5|s2nt,>OJV"#s>s}IA2Ct*,ze<جYe݄ !*$m[O._ud]W.ө@W>QP.b@tL$@gt`OSAAQ~&jq7]lŌo.isto:?Uʇ⻁$l{~r/r$_ԳZXc_ST u0xEb^m=`0|#]'Djn/zV dIEROEu0V&ezGCtWč_Ͼ?{wGl-`|Ǐ>Y?)W?*'}q^G._>>{F,5Y`_3>U}a@$K|?sA:ث{Y|:O9 Be-qbN¢E4Q[v}Ȯ ޗNY9,K{W0y*L|61xU_{bmEїr w (l@UU1xVy^|ǀ NӃ}lLQ}Xnⶅ md6ZŷbǧW8bom7 #Dy;*PttJv"&n qTOc%:zi2}ej@{UB@[;C0ys0M0W1I%_atPө ΍k_{o\uM'X_;VxψG8$MLLah7=Wqe `z~R}MǖNt*ߤoɇG-(*O`:W]}`NtgE-ٳI];wGlR?LdBa蔹 tISk[K'|&'/\{ŢQxŘ_lUc[M'1/M%lwXI>ԌX#E9%]<\yOŶj_eԄ5cxd62u奣7Jb'-&h_~ϴ=/ {7e,[OLqH&ߊ(fqD-O$N>SS`[߷0>t+ ÎQĉQ?GS^[ծ8`K)]IZnpC}1BLw ;c,8#䨚NŬ[p{T~0~oN߸]a߅{+1tۇomo8 }iPлC q< {N5 ؑF|GuC1JT_Y菧s|OV;byKȜ?FOKtVQ1: /<&9R~N[?UɈ[Dqu3ψS%׋K{rN*D9M+Kv h8$|s?( ev1vNt-IFN!`gy@>vwYK2"GOѥ ,HMTo.g_3ѿF8&eX[(QڥQ7f/`_{!^r;ӯ~qèozTw/Mj.no5|.j7xV[xhxy^Y휸'_"4y.ĈWᑜOX2hM=&,{ˡb |g#80ur!<_Q'4FcG v0 koD#7:PJgΟb&x:{ŊČ~ioLη| _\6vW~g=Xh:uhdZƆYkdɉ-1hnهlOydBGx> Ǟe{dtW#yIdmQnp}Y>-u*ev?;L tl.—e\3؆}?9w '`vLWLotfwԟdӫI/_}gHnO$x[JGΗ/zٔ~ݑ j ˾[\\{C[7#7ɥYST&:@Y{ATXmv]&/owɨE˾Q?#hSd-i>mM^Zjcw᎖c6QG対Ol~քg nwƶdUfMMvIȞ$T=\!c@=[O`mɊcm[u6j1d?][kI &ZLBj];E'E=ه|4mۏW菿=L#4ŴlǷ;]&NoR,Y9: eVp+tMXg ֣τM!cx;lb-;'|oB ^z¨oc)9Cuaw,*L%~{ -$W&>cwvEvÀk(>]䋥t-&×Vd#]ЄG4N:?(}=t]X}Kg~YٍCro҇w6RXdwũgG?xdP}#W=N$[(V?_7'k-Xmw?dSp*>=暭WJ)ܬo;[<..Nv:vY| 6_*/iDZ:%w#/aGnT%i' &d:sDhqJ)W52eюxEp(}Yf IDATs&}&ˬb0Qv9hxtpz8=M rOf d[:5fz.?0&YM${#1Lpq~%mDeG\:biy u10/G㑫̻긮>iե eN>< ^ &p)N95OQB+#y3@Ƿ6z1ڤ_G.z]&:huOK|h &@m{~#-:e&&d7]$}aHzEJ|Wާr|٦W6ãujJMɯ\6.r-V6 ǰ/&Ԋ|Dv CGdHW_&dLW>ſ[){l|Si2 R>n{DqVaTyx:7!{њlU]wx@/tGߋaթMΜ8WvDN7tumîK.b4]x>A,zg̾;OOwֆ즭}.xmI C2;ԁy< C(Y_áZ5_(:dmd}"LX]< Ô=Dvw?, ~ZMyujd psmw&>`5xůџ~{=ӌϞMY &Q`tzuD>nb-ݓr@ˤ߿yxļdűMVL_w'$OYEe9LLS:;&U2M,*m1 7/owy|w. ]%Ib넸 |5r[ -d;*6!#?@<|'~s U7{>o>?S wgw:ߐB#'~KE#0!_[߆:RǷL7#R_ $[wlb?/ɰsuls?ϧǮ(eJZ l^ nOڬ2*ۉ?x>7A^d~3?KTзtԗ8*1SlsOُ0+|>:Mp_EdfGl&U~[ʸ830eq>~ׄ+T keQ\@,grLϋ+VI2Ζ}#>p^a||ZTHfo̜#\^!'$6/iP dYuJ0O?|o`[hh;&Cg۫unh+8 /m8A.p02kWl|fNn;dmeЄm{`Z~/{qQ[OOM6*#lvOuʽ?l#Xl?F|&uu9!OtDVuahmr4<.Juv&`އkKhG$'/ȎSu_“7~;۞vd5z@Ǐ10$S$I;F#zzuMR K7|iǯ;E[)m:1^{E2eweJ~jߓo1)ʿm^Tdp)wE|J;b1S-$F]ŋ b `&-lݡ^'S:K~鲂qtɗ]ڕ8 ȟ|x٣ `|&Wn%<%@0lל|OSMV2=|vykkwRфe8l+6$}0—; ʟTxaȽwMtҎVq&|4滋i3^Tv>һIw:G~~]0K/ #\ӄo]WNض8Q,gGuLl\%פݶ&ֹIΣ{\vM&pPo\k'"P~F%GK!=*]D%ɇNDNh3;wabKE,L龘ӑ,&@ٽDlM.5.w|〰Kv/XK wlѩ0I0 d,MKraDM|MԵa:M1oά-&{vh,.4#`xh/ʼuá*'[:Oh K&scm&[N Y2#'}=ǏߝK&f aaWt]).fwϺ11^~z Fo=Ѱpyi_O'Jz=<S /URavم}c(ݔw<;~hNmoT~mlx2~صfg׆0ZߵxZW/Z7fb +3 oRr{*yc#ghmorQoSqܤu7F `ghH01π=л`dp"q1b ~< >4ma7mMfr/?ճtw XpPSi4]k{AȓG{Lp&L0TnP0Ͻ13_ x:)"br SkIJ>7?~M72#gIU?pr<$)M{ _lTn &{)ZNxtEM OS"?=2mWw1iHu;LZEgo>>ϾYHt߷C@V99?2}:F{Bd]a~#ǫœq!Ÿ{]&)Jl/WO|*4"cy^(y.y-4hiwڙ1_!tݺm6M4Kew,l}Z_aѵk`/X?Ŝ"^"uȕ9\^;KNOʮC6ȧfm隣^dv71}_N[w ZϏ#]_5@;6y0vOMGכ[܇~\}0o@;\v[Sgm2^uṢ&}"]uޤ'=bd]ٔ,7"AAR$e>뺺u،{"󱇾Z<$_::S %smawBmcRQ_Wֵg7^D)Eܝ^o '|1ѣpG+ ]^Z%+=4 #zo 0l*M*_!oզ<}e/9l,<|0Go[&xЉTwgԯbOH)!VËmIdqOdoj@|l_]& 0v>_6ˆ̛|pnn%~W]Q @DPǿh9_H98bS~u@|- DD|?i>'jߟT>:Gu׺]KG1Gt1ks;/,XؤW\W˧-+xQNq:yOpG>?kϡ][(a8{$s:/6gm=?K;Hǟđʯ/=0Bڈ#xc6~9D+ Q#^ d>T$bW*w>)WQCw'3fiE2uR*ètWhLקnӱ`yBI1mWG@'Oxhn &NHNd:Mߑ)ƧdЁޝ&SXQWVO+; |uz:_d}4d>u[;'+;ؖ:L|@8X>2ؼ#4^R89.}r>I6i@~n;;ՐDXo,_wmd噘}܋cbs߱ Bhc>B;'˷5~ ؋lNvM{;;i_A`jym gʎ> u7٤z-IÈ,=Uo_7()Hʇe-X!KÅ\|yl$V|D! ](UqE[ 59!:=Y4#}LCO仝ʈZyi`Ue:`Qqb{~žFaz_M[3!cwij%|}w&^{LĶ կzǰN-DtaMg>OLi?QF&|cѼ҉z/!7s|b2l#swdcKu9 nh)cM8On@yvxy[yxUyڶ'q箯y~cUSK~S'|[?6IJƇؾE7w-ϏȐPq|]kSbmЅM}" u.O˶KZ.HBKsosKop*ia^[8y o`]aaTqOcmߝiPkWEۦ)11BA/c\;m5AwM\K~;Ao y8ؖ`;ϥq#7I }Grqqxs^TضoډLpov2x<"=yҺܢxeMNLMtb'Y77;:??DeqkiEc2YuwkZ{Bۋ{]1}%g'FО;c0xtƆ|_Y&Vthvv=f'$'-V[t36П o ~|s2ؘ.Rյg]2-|4%x-NA `?dfoGk"LaxEbɵ'v7y_!@*!3ڟ `ch?{Bμ`ҐM9s!c&íR)5лraq'?9> h2M;?5nok6 / ]{Wu0}/<:0*IOqd f?Sx3@e;| g ,u*8Wd]iޛ0<{ 77MӱF]'*`^uOܢd:.k7I( Wų- >Yr#36J'g. aN'M'WޒN=uNx0B6cOgd>&+DwMx~'w*|&OAGky|&Jp篷wTy8?:g/h4b':H(QH^9m&K+ص}/ڂTg#/]ɿ* ]a~Gӿ3j{ɗ-DĞ`m1<1:O:|w!Fzr]\'=G,Vtb Vz+2֏3dxE-#-|䚝zj4eW}`züX,ɫ{l%vE|yԎgx3(ghbx $U ]㉾_~xҠmv]LfɴrѤ j"8}L, &wmAP?, Ry>68$,{lo]p&l ,Dĝg@/C"_MTkd3;J_ .goO&Xw0nkid3x!&~g]ِ}ڢO^=Rs=Z%:Ppwg \䦸Fv:q&~30#uq*-J+{Q[ttr-*oҟX8gbL7A߸%')"&;ʪd]~惕+P$wՙ:-&XpLa ЩcJ>iw'dB󝮭D~t ;BzS~lW_X, `$mUgzlpNdjw0}[;?qrm"K񋗶&և[_EfϟfkrI'%T?0Ӯ\\Arx7Yv}/4 ^S~l쿀O.+M[=@{Ƕ3XU;yɥ6cDH~J(bb3Y~(mv=B%oI}~~bGi:J#"V~drGwXUߢw4৽laQ>n:t}һ L6UFصu6<9B4ѯ](r*w2D^\<dm{5lY `T =J~k?iv{]e\DoӵjUH?1L,(u/C3߄6w}N&Qg Z 5 Q2;}JK0Ɏ:ɂǻSa T!x.+oB}_G}$ ś苳oԏ;`&8: ,w3gG\|?vvIGMang4Umy_7ߢ{&: s&,{.9ȝxgm o)+tmcwsdVۿ16> dqi "uwv3&Uy|Cqen9nmߙ.{_Deٟ#_M-}7UzeNXV_°?^0اKi ݞ_.KO_]? "=o=Eo7v}FS08>ݨ< eY uUe8 [;+S52gRq~a2.EbtH6/q]lW/D G^,|[h'0+aW, 1t!Nm̦=b4՛ hMy>hݎhDS,04O<9>ݻ0.d? L{3=9 GBK?n9eneJ5}: 7C!\Nў꼙*y=tzț1{|?7TK#@ASf t*s;۝z>Y\t${݁-n8\iBtw'}el.O2vwkH`5$Xaq؝]D!}r9PH9 ?F{œ/$5+? ؛n|k@ A}G':jUdϏ"Sn.ӗΧ4M~1G_Jiè0==ԗPYrQ4z&L/ &w7kWt~nA3#>undX'cbw/=]rYG|E3aIvL=;?V/<7WkI>?ɷ)go2pdjR5QCۼ7HZB{'Hts)Uyq6jPrm?` ц6!-;ǖ}h}F"I8U_XwO懘jPxot{wt KM< Ŋ(]C4zlTK@[E^+\7'vy}l;sL:=_xT&-64ð{ڡg}3!/mڝ؁ʧ'DoR0Ƕ݇Z / \6 L#6qGEĒ|̮Mz į,Tuz[r UL@[x1ʛOEmw'|6J Dl yL Z'-X4_G&l"I@!P`OlE{8IAɪhŘ}ѤŬ/iJ2CmܼI=QM;O:I'ݭk>a1R,`/}0Rw!=*;'ndS.9Cg$F07d?YӑLQ+HWMOaA 6'[2^ nKI`Q K춅3z1ܳd?O"-E8|+?tN9Msc *Gcct/B=![_[ނjdY12vXƏdr`n<3G\]⁙6ޢvaXŊ zt7vSq{Nƨ Fqؽ \FߕYnj_\Ysk  5~U">S2)Zkh^6Iy-|MVit6WW4\5h[ B~d c7nDzpSIuGюezsV)Z&V HK~ٛ4cG|g;2u6ldv(JPf]*xٝ?雙Dq %Qi}>~8|u!!]b]H}Yu\ȰI<" :zmMu0 ߪ-Z7MGs+Mv# TF^=1M<}-/{Bi˓|oXHxLd篿}L5b&GtW2TI;u;N)4DVw\8$x>O]ؖ@r6W1ouUwG""ZYNkIMw6X V"ZG~'=+Kzy`qU8uv ? t%?Ę9hxnjR`9ؠ v P% m7 W'9ֿ'nG mޟ~ O ?tg{noqQMkKΘ [GOn4n^Aj͊?ގHe8lIOh+qWD?95AnBDѾo \wxI>o 5y%k:&Gd>]c?} /V_iNs $_|!5磌יGhA2(ggXdcS Fѝhk M`1?kHjr?Q}odIޣ;޽`Ȕu/쳾m*G$,ʼn RZPgXg;B?̞I<ǮǞzЏW?j^޶6{ !Qim\?dMxXŃ;*餱OV8]ʝt͆gهK>Q&ͤ|eᆞ]EnxVz}ltioOš8#nQmEt%w}ȡ_w`!?r?Y*<3W Qj߃>qS'{5z/W؊*;_kRVZe_ד+.أǜ|z;bfuldaG_4pn/?#bxi1b^l0̐G~Kp^/o~CfʖW^hбD?ě@܅хwm V1pre.nTV/3r^0Z#?N^\:\PN>dc|:L;Ԏ|aZUހ9zoHooq!HZ{E"O[,zf8GGzIOV_MHcrl+0E9lȲKmݤ#Q$v^e>vw ^?u^,n@b}tC `>&>S{w?,3 6Eɟ6QƗH16$aqm9r#/џۣ4avh)D~7ONhFD[Dae!h蔼u^QڔTyXG1*cnq%Y/.J_?1^Տǽ| ,gYװ]HNI{FsD$N6:5,'pO8ۊyIcйvc9~Fȝ ߮8Ut ;av\cnW73# y 9]W!?-eQ,kmnM}כ0YX~D?M=۟;=tѫb ٽԺKvwǛ,kM 5߰}Û~[#pd55QdM<_,[2Y?gi;?ϋ7wU#Az64Q0Ywp[5iM޷Dt_[g6񝗼ťb]w\1}O-\0X{Q7A~Z 8Y;7,ۅPqڂ,̓j}/(O&6G,p"Am^ζrԢZ&4pͮC>Wb?jk䱋'fpX_ۓVI?Lx8e=7Fu;'';?1iUO![ xO=+kdrO_vPKiö8-g $\6AlGv߉F;]דn|)d*Rci\\CyX֧4'Xi][y`!ofk[<r|_?</!~䟤/);% Nqi5 S"p=נU/hqQ oR?i@56<(!{Eu'('R&A;M~p]Le:>V{rpSs08aC9#Va5qXU']w$ݡ.l!5P><{ѓ>?Mͫ;=~1ʯlc@ûر@3#fQFw RI~Vz[4tw^ZO^&vq+s\Փ| ]O:zqΟJ#E?a3k_T!+yAtA1hD?;[X^[am DxLr<?3{D =` 39ݥ%=eɓ_`_İC^wg]|O ϕ;M~e22壡N8\:#3>?:FeMw^:tqMz Cgczl*mX(+^Ea N.6b?|*_TXnyON$N Jo~G?)I'wm/7xbX>Oςlt"w߾0AWmD,[A-[ca>/bEe0߷R;շeEU5:2~xa`z*[P>]=>z}2AXmf|ob/ЦF&^??zODmmF7Iv p_goQH~[ejksxlVܩN60P2D~t8n}y a ,ŬoրKItnQe?Aezɳݡ|!'O݀A,;K_!`رm8~4IeS렮R{A^i^A8qx嗆kϯ6() Oޖ7OI*j[|kyUXűWø|g#G\uI^׆]6>h#KMN7!1̱ok2Tî<;+k{-3yȡп"nyXO0/'Vb4awuc:{׋-|L*SN)m}m1+K\|w\K֖1e&{ '9gjoI]% odnehZ$a;Eȯ,AYx'dbr0>yvySd2_$# ]=(ȟwi2s_Lmt]+(o:-s8[R4bk՝Pd'pEg}~5p] IDAT}bh&_AȣG8cƩ˟Ӊ){L#^yOE8d#LRிN.9:%1#!,PXGKdXC UK s8L^RmH戕"6Y_ ؎F9[v%'#%hCrDwJ]-me6 o=b!S`~UDMPd]9|i) Ȱ2VOP~1zDF[%?L9ӕl!:0r 9#\ʦ#W/FÔ-Fu_(hRzD\uʊI_ҙF[ҧOG73a6Qc e?}C{2y0)F?.!EsNuvŕ__i oL˴c{f@yMT`4s)3py teXGgv ߤa{mTIVi;>ԛL2+7JnQtCk>οE~g|Ng̟%VG,w, Ä?~4)t<2+Ado\~mW;J+{=:N/tƱKd8ɟMqGL;t.z!Eؤ6 O|cFS}hh^.IM'׶>Z~IbҢ#. tF UѮr.Jk@MIDmo յ@šOtGp@^UM(]tQbI;2TT#L&YgC,"|͗v!_Jv-ўFv߻xdk.]Mx3.Av1L|Ãct)NwPh[mAIkWP4]fy[ю}hg]Rcy6bՏ+ k-Gc#)5:0{y:ad{`?ydcunm`&(]}H~)FtW;6kmoG瑽6\,bTˎi 0PZKkJF?Nea,G#eG@:c+SpL|ԖH1? o8c~o 0Q|E\X.>mm9]?~ ]-`-Vjm}X _ەĉ*k72*?aDE~{4Wŵ_A*U=L<_0aq[]Dikgw)9g~#RLSFҪ]@˼Aߓ@aa:1g7brmA &*k2Yo]lٸxA`~D,1^M.L%W 'G& a^P߶ mD R hԖ;e{/2ڎzۭ.0-`$`00\rڜx&"IJ0sp8 lM|O62nxizn 9[<_tG0J0o'Dw;}`9K#y {2ó+<޴ u Df"@w?GMu*urhc 2ˮSj0"=NQd{ ~h1`25vx? M k 2:񜀇7œpb4[kp^rlPoR_X4:H߸&&xöEv@ޤiv -ɰ L'*|"x]l(3"(Ȱ! [&ɖaLZ7hInۆ)"̈kH뜽Z7Xz *sW ;c~5Mq+oU a)m'~Kb*!8n7WTxgWGIǻ(6nH4pI6qclK3U7^gyt:YЀf8¡tO>|oeٴm1jv|pq򵯼˕0fUgA_*괙}_]b:/caI8{^j\fLes\26wPu5t*;u` Xtlnu6#pRlN |%16i)Y},ឍ1Feh ?~8mF1u,qrc,~0z08.Lev!ήH>  ϿJVU}C跴٭NWm9SIHil6Vst&HDwKxhz-B93ntWNM׭K] {Ax=|,Yt$ Hn`$7=7=dĈHg_&ߥӻ=&N ? tHޭ޲;oL#쩓0tekFtKË{ r@P%7}4 1R{G.waIW:*vnBwmF[Ol+?a+j:Z396x}>d<<,#9M~2~<]WC(oRYݤFk 1H[aM,ԃ MLh_]z>כygM uns9={{촲WOQw c~V~[r-RN|/46Rem>7h'M0uwbLtznaq-V/bڮ M.ʷ&jC`?_]ħL 'd&o<%'}MPD&_:YJ11$TkrDC}~.eC2g$mS1ICnȱ׹/$~vf2{-I56k_le}0PJXfN }Ō5K̺+WppRŸ{6 sDdӏ tm*A t1 k/Gcgy˨wsŒWᾪ^xDH|9W*l+? ߽hËW<3<WfE6\&Îg"?&͜6m%`0(l9`w SӔ_|OzsRF>~ku&X31Xa`Gcg`XZkqڜ9IS Oy:VMWhgzO.Bσ:7XKc?MqpI ergOY:==q])6M;o|6@:jM8z 5D]X2ހhn]]r ]Zbmy@cNʸ8]ބSg{Iz~o1ЫVJnє`˛F䭿3jv{` OՁel}{[79% xr? ?g2ߛ\Rp~FE}^dN‚N񼼪k˭*B`+Wc'HZ EtV\MH` Km1~5|[ l'C"GGgF/Q%C³vѻ Q+]pL u| Gst;.7#㣷F 'c1M-W2];ؕ!=Њ$@/[-l+L7iJ ~ڏM"Y/FEmq_^\xE3Hg9(aow|ml/8q4g!}ir1N41/#![ڱ9P'9fȓO$`8^ȴ-&q.[I3׷TdIX5ilQϟ =V0o{3>~v@%#uFy:P뛎'ZŁ>)g #CS.v07i 2[@Q'_|MyU d'c:G=KAyvj£k o~{?oiG/ɠL.mqn\;تdM/8o#_Ol^,V)6Q\[#R/ߞF~:.c+rfk/dM3|;YFEvg>w,>TVW\^E Ϗ1?^Iu1r-ևMR>ݮe4}ʭ ߕ3uO4#li-ݯ`Q=uys]Sc~m am[1f9PPt gHלJ5E)5k[Y&]Ϫ7]lXi?mkFqO:$ψdG&y!as(vΉ_4.eGŰK'OEO]m{ jOr$ B5+lG X0ά/̛"?gx K0GP6w4ݝ/:E>V_no9g{?+6ig |Dw+~kҝ_H=Vm)T93+㬎 up(m|d!4lquj:|~(ɰKk >Ht`e=y2]ޓCO{vFﻏ6](dZ{sb:UX~r|M!WMtA]5kqF%h02AGk(}* nmLkۄ$&-0 <>™!I- 2WR.M>>q8þ:bpiy~ ?p2عGA|&.YWb❅HVxU<[ɧm^0 K>6Cݳ7w-(f=H3~%pMaYS.k/b]t.dNg]ڽ\NXn UzW[_`冣]Dtd _w}ȿ1o)3KX2jك)OR^6:z^~>,sWy& ,lFb*j#t߶-^&or>NɐʺULFß/tfOc_} &=hj^U}}~b 3i/-Nm]"v1vB]޲/~Vn9u˰F{2'ȑu+cm| enjL;p";#mvjj!bWzFgvz0gx/f{;>ZXFo<W IDAT񠾶6ńSG#|_91dm0٪=4=}W8>8eq7TIެ5_JZ]%|>ܢbd6X|xkcS07dvkw>w|f xG{Japr<>فq~TaA&##?Fw2V+=!pF)!q2HYZE[BfHg|;5 ߠ!O<&bAPF9CotFkBfcVXzr{s: M֝ 7qsߎ+I+aĸÈ ;ǜؽJK[2&ptJM\Cc"[/.O#s{L? )eW*ԗb`o5꩛'ZE^O8[f'cFЎ#0& {]EϿ ZxBgj5ݢAm:~0ľKok{S=[ry d,M^77Hx>;iI .%Jσt#tee>'yםn@KG/~}!MҦ XA{4PAkӾ ml.$ Ph=ڋ#&TS ݺgO$Цϛ=ď=bMrzr×ʛ>ե+9)}tKH`;ղeJp C5]1^ =AVafr~xG-ܔ=e͙*]~ .fȵhC5K-=iw\h(enc3/k}/~(W=vm;mr8o21bF:m$|ȱ"^he)v:#H|}}[Po l}mt+HW>Omma7 QEj)+|OrKx' In__`zm VY zH{[DT1Mkr¢U:7MLr?0ڙ/j_/7)weҥf&NԄ{g:)lMϋ&?{M&Z>M$yx!hFg $k3sA˿zgW,c 1,u,ǷVϭ{k nL,v*;|Ӥlvp1ŶAszlq4MŶEǀֹwqfO?xm!4Ya/aF|6]Px(U{mxlH{ +I90#}%4N6AO[CmU*]tqɺXx}ѢR{]rMֵk좏]<Ǟv\0{'/q;|8!kd޴x%Ti-&5}þ k~ؕorVl@#{; +Y'UF1"_#{u-`Z$x>=똬&}eW}痿@=eԹ\XLso OMhYMߋ2逾ѾE|I~/:97*s ٘߅īruâE.^>H*0]FQ[ۥ[:fC⬒e Z6!V氀[Hry-9x,3OܶW^\1ldc7ŗ'`gN>e .u8\x^7mZ_C>W~&F o|y886 lc7!Sw69E"qfà=rV^0G8v>_~,azy#_r(Oɤl4|6CMv q/A]_]f4,Vg]9d~ Cx+ &Oާ PX$&3Nt|S,g[Yu҅9LKv}AaWa< vO 1o1TOdK䢻I\k,eNJ2Ns`Fl|=uVg)IlGt+~~gu%" F^ǫ>+I&'ʲ4`r:cYed8}aVH"hu`2;x0v ud>}֓;#ێe{,Pp`t#_џ?8@aA{r 0`%ExlE#H |T^[n7t#?L)Vp( R+|,t)0F:`\p^ W>~l &WOAI9jS,Fe~-v+v0J60hx:[n0:tnwi̘<~ŷ-@}6\e-ych0 `.3,NFT_܆v)9~Z>gֿ}:sVfDB'IFhWkkP/يt,Kd$ t*>ñ T&_It!~0Hvr6ȷ`x;nҺk7*MV7|1$>u ޒ7n XhJb.&X%l`fBWtW4_yu.3޾wDub@ k0[KxLc66=p$8zfj?ɽ3;>{F@sM1d_Dc kGs"i`\YiǗ~mQEh[4W4o]} dD,~ O}WfHګp6+Xk'&۪G{E69^>Ky#G*/Rޓb>|gm⭤>Ə_6O^=}x [x'C^-aP}1m2>7eD]k]KmӍJAl:tXUDx4YՁa/b:LƇYȪޞm;F~k~F\P͟r~__ۿ.[O~ɪ_EmťcU6Ngx`*voU.Yiîxʾx%bLO1_MN̕\s:)7[;+_6 gnrt=K_q\jxkڏ6A:q ely6 n^Ax^x|TV]Ű[3ػ86%RΎhEXF/ GdUz'l@;wH1eʬK: Tlh< wvcp =yԁ5dcXy)X:Y<ђeAipjN#:lώ\%8'{cW=³3<8+9u+L4x0 pKSa8a.̦#]ɞh_=}n2$ߓ5w2iXG-6?ZxtV=l'իCTwOljza 8nR\9t&3?d9cF ÂH쇟R0AEi*0_@3R?\ ,,V _M'G}z #W+BF&nUqL]^l tLqhOӺ'tnBFQzsuj(Yﳞӱ76ivu֐$):84ĚlF֙:2Pܪ3`ݯYC v/X)B \Ҵw8SwPc4IWȇ/ZV.(}9O=qN?vqNw8tu ilm.~pTm+Y} {Wj@6tb[^zӓ/ROWH(֟6 a͈j; F>ex.|Od?wnMٞpc[[6g\]`2ʸ]@w8 3:0p%}ȷM] ?2Ýa[19iiC^.ܠ 7 &(r>FpWIgf+7lS_Al5;|D*uMxvvgـ?9>D7^ x.]f؊wP쉅L6{/}^!bNXx[>h+$o|x=C:vOZ*aLSuV_O+Ĩ[~^lna!A9ɘ}Ujb+DU&\kg@ov 8ēm$ֆ=>xK;NҵSkz_WRO.ΉW zx< rwuE&0õ֮//Z3WEw쇏pG-Iɬw[eV6eWi'+y{ՏtLܦ{g Wn,>5!;=_NaɟJɎm{9`qmYn#oN3P)IQmQc:U/: E):h=%yŃGn.ЁI~ &LI埴~ѝ|&Z줆Lǐ&z]%u9~it&0  Pc2ˡ8鶷 (=?)z%ddaAR&]:Ll飜\e㧡utN-Jwo6"otDf2FHuړ/vNt{aOW0 ª={m3;|pb烑+ y&χbtXKa4n( f}&+}Wn 6 GKL.ڠiA.01n#_C?fnIs׀<݆?+xJ'`wdɇ*?[|Q'\?+YgiJ+ۋ]o[' #|Mx6yK.;s}lWkL:}K6=ǮG6>*'l=)|* zȚn&\o\,XA}_z^{g:Po1]V {FGoqg&x鴋Y?a\>@u `uRNl-mpb1?Tm~Þ':|W@k[ d_ W{[gD1",nQyYr<, *|VNs_|?_x:rbK~Q9oq.{|&JS۲9V.]4J޿_?]On⊹d?u߬8[6sZ$p:178]ai;&JWuHt%gƮ#b{`;nuw3< b釆Ih7'I X0Jg>AhD|]ᓿ96*7T?\n }s6wDV>J?-࿁zrGF^`Tۏ]A_xIqu<d%ULhGrP2څEtx2Qs;K Yg5cJkX7]c>Fᐼjz&o!Ʊ= m1u%Tv~1)IPy*V|N4X,w2b|o]A|{W\/&IoZϺ;a|ڽzU}qtL(>z7`Vm>o1.x~|鸧WLw%]Μ3֔P2t {*5vC.X i#>v5Z`"Z;=[j}~~kI\D'akf~|:!?FFڣЅoST_Yjc2:Vg~@vX'lM6ޅMѹgb?{v-эkä@lҕF !VU ջ{pm*DEO*9ٗx_ S]?C|$3\9:~D\elzG)5ߠi*P,f0zʯL|e;զ˨g_xʒ1itѻNjǾ2.`we a )w qH>*c4)m|d[:5_, FM0bMxPItS9;GC՝.L[ '# N9>z|Iޯ5N;^J6<9̪Xyv J5:=/)@|%G|O6RG`5L;:u!}!KvV 7*M lʓi2VbZEA_/: ?R>١=D [[&N]{qFM?l.Z8g6a}{TMG;S[&)=Uü*\ٳ9Y`b%e0$ IDATلk~: p.e=è[ S;ÎzGnڛ?/., zːw@gCa-N>4CF+Oy&T9Oc׵+mWk {[ەtk䟼6ym/-vUghW'Ƙ}$ Ϸ,~y&WP~TSv͏ʁQpmut= ~ѿnY[$Y~cl>xW+Gyڳ^pTT0(%  ]6jĥ&r1 KAWWE+10h.\Ey,= IH?Wf1De?Yǡ0`2.߶3Ͼ㬟7 =:hfd>]`4]>a3gsO&=+OWt==ᅆ|הN.(FZQznSv6`5ʓs+KIIAE*|l;+ _y{f2B3$->gЭ;#DS:V96Yu,ڜ"vf:LR͊)uOB',SHV$Mn}'sJ69-*fh[ s{}&\%˔ bn4!Klw&~Y"O:D?jD?56o&qMl\Nan@C+z2^/fF/yg"٢ur6gMvN[X_kɝ)Hg=Ps?]ž,$SNVAM'4_}UySV87\s&hx4[&%#܃<-f"8Q,"GϳCp o`: AE>L~z +&qnA(et7Q( |n1^>]ꡃW)'<:V |vv^Lǖ1Ov&2k7Jq8itDS23J!_a2d!-VwEKdV&*=VBu?Kbv&xg+wӇKj ~~ċyxu~ll8q6Z} ?;$Tef\%]:->Eꇽ}l۸XgSwŘKr r gMVŋ]/ "X:O;ٺ[+yi?i:0j UϰlGvS:߾A(60R RGx=ɮc՗6^=MFMn";KQrMpLsqh<^7&QO:h:\SILF2@;RL~/q'Kb(6c6{5%#Ӄ?o'SiGL;c!1EecJU6>#+)4m7)F48g@ Rԫ1^ E:49\Vgήwk̿og^#K+|^Mk@=5;oX=|'5 ~>rzpkACОʼ^L^tV&"/2>a.'j7iHYNUg&G#MP{w<l5^mw-$K_cS*(Ж1N'՝}m}8hLNxIN佴w3ic?gD(ÅI#oWO26<n5vt>2ꡏέ6|`=W}wet LXOXT ؽb_RW8gչ<SjY~Sʯݧ֋CE߭xS_Ru|xKmcV|:/[YڹPKbH4K~ G6y7vx܃Ͳ׿' &ףҖ6H N-/5ą  :sT#b|bvLh7Q(/~|zgeؤ83ߠ9bdX5kג|d+05lSr|)$l.ԩښg: ],d.+L~vm}YvWnqyQߋ荆k>ϯ_z>d"0.K#ߵ1wXAg},mE`W肯4VntGԺ2iGr`#RP3(WkoĎ>=ΏQmz?=zoVvƟhdK+&^w}pW?JIBNVР4)b{Ep Rk5qGow5 ZѾ]U92&H댷zk9*,Xã`lUXswp"E3:^mpnxDh=,h=+W'f`:zљ\ȑ&Ƿ&yzĜ顳c,hQW.]"KO ǯn}oPgD (ELh O d }W[燫L7[x/t㿅 }h}%68V/~Re MȷHU9>!l +7ՐF6^d%Lw?zr3ƈn8x oGh;<7h+uuޮHve]@X]gzq?|]ޠt]]Dz>'ULb|)Ld{XM_1 ڿCMô0=ܢ'z| YÿcPk.G" ['_&l L+h|h=GW0[6?+]r@pv)nNx|vMwV>D<@ vS(s#M8,m+#d\0ŻlWOFl8X5]7'kx[t룒ſcޝ~m'&{: 9Q;k&lGgc&l&?:pg= `◅ʑk h 2!?4=">m1:wU4ҶKm)n [hXhkxWǠhwgH6IpIzJϪj~{G ;v36|?}d# c}U:ln߃O%K|[gOWnC+;ꑕ[YgaDǗ}E*r_PC 9V4d_7kIlXW60[_h-=K[~|sRiɽxK-271O~#{W+^kO"o3c ѦO4>^RM5Շ1:Y]W+6**X<0G`$6o+& A.tm6>5u&pȬz'a f^lkU_]lDsp=6 &\29.`&~YTe0ֳdfnWAQ+^ Wfҭ4ȟ6[EuuuP=ҝS)M91]"n&ξ~Oؤy~yc?WʯGCr;-N!y^(TdU_+&mk#q`0*͡,'fO_?Jݡp졫]SB??Wg +T@ C0#V 6P(} `PEŞF*j`vJg!M2r. V $; K4}lDM}.1J l `UC7Qvߣ٦Pm!nѠȾF?X A\̆adQ罕LSwNЭ8TCY]ܔ,ndz{bq$n@g+Gٜp;{֯G)VaM.v]._q2m$ճ 迸a k&ӓn:wOѻGd͖~bIcħc:&q4+^Ym/:Qm:d53$~~̤/f7_v|,z6>9\*ߋFWݎ TXjAEAgM+[-˓Ad5?4ѿhf0O'7e.WooVot-Q2ULl VmPZ4]vܹsm?K3ٲmz\5{,9g-<㛼EkB襧3GuUTM*zj;ӏIn$Q b*b|΄?!G ܁hY[,&tH*=w9=8Yb zo m|b';\}U?LɛLK>U d:1\O6;v39g~KaݛEGl|W:3?7dǰ8zy?O5KXOȕ,]{GlXY9se4}9$1o_fEMwt?-@ds__}7"bE n&}ǒO[<\3,v~NJA`$8I.>bGG\y@g{a>n#f#noRpY}e8e[>yGR=kL>8W;lYv `L53pTVc8+ŷ;P^p&WXqЇYGGZ#V&`>I2H#90K֑;tf64M`=ƪ_wPr^G;dד7`֓o~ H.mg[tfg?ʭVg]c^MjK&8 K|6V(fr}ǰtgGq:tQ vI:l_i/. ]_zhcB,dž?E&w9w6Q? ?^[G"MIn6!/ko({򴿭Ī_}L.?u].9:o0~E@179e|w?__rGJcç:)mnXRg؀ Ť4VM 4|Lw:euJ=1ڵŐ>Osg;`W|_]G$[;b t'fl\F{Q2[̊ h{}Zޤsظ~ x?DfxFɵM#|BoDw{8҇ Z~tklbOڴ'?WF5`6˯!?]a& u&&{u @Vz%%8Y M 3ͮ`07(TλD{9{=E^3GZ#3Lito?cO`ỏ=?x^Mjv/yI :&dA1ܘJZĠ_:kSOoXdGX3;0>[&X6RjK߉?\|cG7 _{@ʭ^K[[9sáJf~j7ȒocHP"җ-y~ї[~0ڕxj_G8'ۗū 1&df~ #9ܐNY{K}a|Ndo13 Vrlu۔+EzJ?vE蕮1Xl[Y[?/?'c3#=&C){8($qLi)eH& +ojE*be!qԀ04}VYZ?Fuy!S2կOë˖^Z4iМ^E'/26ҫOkq= w2>xlw?IWѮܣ+Rp6 9ty/Tb%.Ȯ@=aِޗWс ]98S#Μ;Զ[!BَNpp,hޢ D!l0ѝ-?%JV!Z[_DŁ=_A?l ܶMy,!(BKҴ10-yN}cTޕ<&xy{^GNJTh$ @7zџ-BOvugp\b}iyv9*[e\YwdMF[Q]\bR)ξ􀝽o/|UwxtM]"bHq7[~t4٦:l.0YCeSssؖ nyh\㏈O>Km1OY?\wNM ydAܕ:=dBi2ZzN}1^t]Jyg1=ost7ڋWK7Wٖ>6YAqӗ kL`/(neTqta'?-c{I%H3T|=T`Ͻ׿i=t{>:\y OiYXH .A0yMT?P<˞_J 6tۥ/HG\)&0ˉvNhCX ݞὂ`e Cѧ.jFO˵&GLe^;{ Zځ鱄~&;e|mm$ykgl>&[hSTZh ږE%+X3;t7!N${h:%&_5OLJNL|z('[4#%Orl|6`dH+G*-󍏫J!~"6z,bF[8,Үߔ&7Mi~yTn^]c0Xzv?OKGIZ 0/~A36ғO/F]Z:ᖆF3zu22s2OWuaQp5]o&*珰rɮse+rϰzAU.CL\J97Cm2ͣSE6atL7c2ww}ڵOV, IddQmmJ;2Ag#9MTlɁTatykGwu lu,awڸ }Xܫ\l;UFKszO0v,W~` cKa s:8tnc~/C瑗$v_}N+1Ӱ>Hchy&/~lz^=mpjg%=*l{_8|E0//: VmS?z棏?񺲓܏ɟE>q62kpFuL4Q佭F-< DwfWF&[ 7Du8ǶLGzȟ.ڜaVA<(N1Hqdr1ic>i2&a|&za>[L?:Xnx^}To1flmLΧ?Oat8]? ˟3*J/vh\iA}xXLƇ}+<'\wO%CvxOj_tF /~.;coWPYRA|lO{@L9 ͔AS-u$ưA)3aX@02pƫXs2,@Wv띪=dhVolSÐJ0c>>]|[#,l`[u0dAҶ L4GmXt]y5^ cKGK&1'[/FC ' >dhS:g->tU}g~AďTVkXNNx?·>: on0$FOL XOd_uԏM%tO߯?,%:26!#"~p?2.ԣ~ϯat ;-OΣr6ֶؿwӭ\U4X A7<< Q-HQ<0qL:db=m-8^* N|&&rCl}x~c%qY?a3?C@yUөsV=brs9V0z/U`ATT@CkMj|Ioˋ×3d&>d,}6ɩNe(az⃴>ڳ΄#Wm|E}g&>7 mƱ x芁ע 7<43nӋ}锖R3$K r`@}Xbc[8ӤAϮxHi|oAjW0 qFfO;`֓&xeTտ3piB!- `{$K_+KG_gO}]򋯻8}Ő/oWn@7vIneN9Mi#_&]*N'6ж֤n'I+Tقk;ƺML#~W[FbߪpIRaO4:(O.2ߦ_Kep[NiϣHm#N'|$jtv⿘tT7+xiUOa9fKZӕ}%{ / [[:!nX9C~ʥ7ZKgKtY,kg6}eO?w VT p@NHCMQ C>3?Y^Iè6v1vQwQ8I˨h?Z>&т)}8|JcsIA:Ng얌fOp:]К_7l l饝On1-yA(įɻRkەf3f.hNv++ܮ0T*Ll9L*/АI'pP,-Dx|lSgǛϞoLZ|]ݳĕ?_-ߢПxQ N߀e^fjeׁ$gWw9[ނg`_J|֥woctx'''SnKQlfr˖] +(CҒM |dqJdzͣ;:8& Vk:<:v$J`|0M&vzp^YL`O}S'~Wjg׶"OLD,|Ѿ3`dp $RŠ@{+ў&4~ BGr0бMt$? 9Cnа3QNv\B_k;W?X kmWL۞5L,=AJT68< M֎#vGd%}GWN*y=u.ayKL +ӽ#^ppX,8'9oG&c Ÿn}uW\\M.o 1!ݑJ﵏۟Cgs;A/eu&:$?E2ݦǗv?[&;Ȍ)3rJ*3 @`w5I+Uܟq^Z{זqr@o2;`m勋+x߇l>s_\Eyp,vYh̘xJg0d:} WMWxkm+M[Gx跁f8ŔV;^G|p#l<پkBg^8lpmS|Ϣh &7hΞofx]Mk?^;L/ΊLd>n2y}Hb&_uKGm=/v#Ǔx7>V^`vv7OfM]|ML<ޫ%ESbL.K aZ;bRFMpw"%/;Y|uZ$&|GbJ~כ燃׏+Wd}ůXg'( og7]?[ .lb4mW^|O*&7<,k2Iѷ>x7Vcg|ǚvGI=+-PJG#8NYF1*fc6ᠣŘ6gp@x0;q">B|i<\ s0|D]M+ $;h3X[5㝛#X g0$1Gox^JYپ1 :4A/g1KGK=މ/{u]=ȱE+xءvuは17Y/? 5ex89`?>[y|⥟?~GhSIRжRi c XV5%!-!S1Vc a]O(K;BGgGTV / OH~>;I|q.1ys{ۇ졙[>~M}31ަQw:ڕ̞EHv xb?3sNn%]=/dҏZ'{W?V){'9Ep tnp|LR=Џos-WO8{Wk^֞}"x篍/Ny|q8\!W ;ORQviWz]Yu+ 0>?sOybۛ\؞k~苷}m8=EP{NX{:ϺX|uzyO\dkKGPu DcPT%[9Kt#NrX{~=stKa oyol$:7 :}8k_\U]#A|$g/Jfu-˒t:j?%wh#k޳i;!gx"]N?u)lEێ߶r4π;oCNJ?XS<B_6 e}q}pU>~]>|&>T4\i ==ޠkk~ PЯ ? z|= 0"s*?/Mk JŀP]IKɞL-sw)H?XlEf@Sld^[ڣW'~Ы\۟}8>Ymb8t=e|۵`8%z'`l]) Iٿ=z&U IIܓi,<}ŕ];VvU_!2d#{s IDAT3;1ݢ3]~[ w3bһ~~/CBvLGO?JA;"=; 刨c DgNXm^^Tq3kA{jƎ^_?Q.7#>3ƪ{5y>wGfmLiGQCN!UјÜD* :鼫hJ6݄8gt7bo?ɝ?eNO :M|M`=ׁ yrO~jk!T}U+IT`u/d_G筒I6hq$cpWvdмv`~ʞpwYGol&?ph71ƣwt:O2ߟ]\vpV~Ӈ+K G5`yx[g[-m,toW~L}J7aq |N8ۤTA:޹oeڴ1~gws|i>Xx  PuqӖDC^Gd_n2y8S΁O>f2nA*uxS T ƴ蟶!>/qS?\=po|:J?r @Hk$tNb M?]x,`:&6h.+~M Jv= w sl९ wcO(m|On`5 /=|{Pѵ=M+n )-Yv'M⎏L, M맷丫 >qa:"=Glo:/S7 w P| pAkOINߕ1t*{\ٶ+x`Ϳz&|?1;\l] ܀oBOtp! {{-r+.bkq0\g&rw|ӳa0N-4a>%xw?d|<:kCxW君"9 &S/O6Hϗ&XmLN*[~rʍjxo{C_]2}^,7ϿW >Sc>>_a`Wq59Gw?:vi6_;kQ]kkÞ+7]?JrMm˂X2/]; W̕/]}{D^B{=GPZS^6]wo= mdt7yc}An〶vt q'}oc^<5{p̧1ӶEIBL9fѧ޳ک/غMO/ {]c$z˓: s+8u ;|ͷx&CVBO 1'H6}ړI#k3+ɸ"Yp[0_C .RL"Z;g.p/712PJq~~?k{{'(}W-[?#)?aqMn8Y/ nWA0ORDQ ~`4x 3{/%MQЏs @.WA䊆:hHn ]"+>X;.ɩn٠o?# n-vm{i6kױ&,qMuIUW~N~`^d)6~ :ds& .y:ev{z_X;^@61_Q!Ox0ڠĿQ(JH?LϦ$.eMa=;T饃eMg-Vï0O~1Tڋl&bfW-&gnwŊm4.]!o{^vc X }0og`4Ѧ߮LG .̝o{t0=o$U1':}l(n:F,yi{CB+C'=3YY$/KAjCHw;?գ,.Ju^|,^O&ɽ6Q;:ܪOkv~sޗ{E +sP9yRn}PϺKv>G%|ď V%S}[C5[- n7:#?`O?_Au?2\O#ן'>g ~!ri 76~][gQ7B\O}*+X S|mKOe4dt煁?'pG<7@{9]g|YPidUw~[آ{y|Ǟ&Q%T㓟.'Q8 /JxM÷ؐ#qI~A򒻦- ; M_h1/^]_i}x8g|ޝJQ9x-,>Fc&oBwP݂Y.ӧ@2n^ȥ|:Iʢ'i{Qxk.r63-eLhqƞɷH>| .lq」Ǥ⭂50D7'Oyq_H~䓡r< w9$ڶן4` `?`,P/p\m.m>}0k~r`Op|s$hEgto~dw7^agr[+u[ ۙ<8dʈϾg%!L79{j:rD'I>W%M~) x8oa5r+b_C1>1lKʶz6 WZ 8i-9'߂7 S:3Gҷ9P0p4 '\!%/Y89E'p:pHY]4-@D㬳}يk~t)/QmIޓSryyOMh%#]}t޴s HBvX&Jt;_r<b{dۖ_}>I߶|,k~cǿbO\[M?b~4^jGG&y?6d謰r4dOOȒLwNWG;~l4~\|v| x;bQtwf:=xH%w|MEkzo+Vw~;g7H8bbxj:C2F7,o7H4ը{m9]1v po0*=CأGdޏvqYh9 /y\rbw%[NPP^ѪGlNg\dwMyiM7H?_9]o=U\?>9ζ#|MVoiC,m_M׿M a}K|fj$ϧTt"! Lb2.pmӁF]u'ۋ́xy€w?o|/hr;veߪ|mKG-*yCbՍ}?ٿ JNҩ<^tD.paw sGεo|!lX!7gM!?gg `]ZŇ;0,mR단dg [hOħ#PG`m5Ys<$ooe:hB_/6>fsjx[^{LJ;>򘘞WC vw(É7ޡhU\-F| ᗿ+06^vk~r9k>u9#%h<ɟ֗7<9Vv2/٘P.w$;w@68LbzhkmQK6~S(ȏw}x oۀs8%%B{ 2=r |뼖pQyL  &w$ ܟW}ڏs% skӞ"֡¿mhD g'd+~;>^7!Lv@Gg`ɠb`m2Vh=R6'zC#5Xi?/~|)݂`~:M,r.Tfa =Qru'H&谘~!@:0<ʄ2Cs|6:O?^+m⧝]':#Cȧ/_Uy%N/ݮ=.ym\ԡnnot_^vn|)^:# `W t,'wVQzW@_4 VnMG|"~!lr䟞<\^4*8]᫽^%o v+g-55p[ThɿMrlqw+b<6Y|6"_[mNuh` ~R|}^}q|O-rOU+`ʏ9Ĝxr⍍ ~<֣ċE׽ ԠONKw̄iA/FHW ȶťf].9rW#ςm|Iܙ2jwėeɇ?`7{ lAg d~_g.ZÕm b+I-0yDa*: 'Hɓm'g['|v?OaSlvs  2=b`nGɑ/onζɄH_X 6٤M~{ԄMfh׷-J-ȃ{<XΧ x?9N26vGt yx^䆗T0qpn1->ispMw|b|_nF0`Θ|$> I/7{k{b~>qxIy~5H| #"_Tig;0\N͚G;8|t}~ G6~0_7pxUk8xS8=1}zmgPA Qw*QL8W|q;e P¾m O~QZdE$&)Ѻ- r:œtsx :ëS@m\gikv ,7|p/Dل 7>'2u>=e)4$ t6;dґ٧=۪)f^F!X$ZS_*h(|s抶)԰IMyU+z4ۃ@] ok?"smw_G}|k~n%Ԟ=r2ti{Ibzv:yeɵ_rp:iWD6T~s [xc<2-w/>QۄߟxxPo"}>} ,\OD4eg 8ɟK<ާAFt=G~StdW\8~ i帳Cؘ%& ']c z0}<_C}6/Ί\,M8/W5/^ݱFtˍ}#z}kwB4yo6$ATvA-2Mxvz$O5h&`,775B FKYgl?4xK~}}m{DŽұəZaથ ].a?_$?>mn(Ǿ\N,߿C+_`EpWhœ\] k2[nW ,ЍE$y~* {klx#:/dUG]W4 X,GLUp 5}/qy/˿ǖ\^L ,S~JM ȳ]~ń?Z8(-Tk OrxB|MϾ(FLx3}8-&ds_Ȧbw<Wx ]QA{z6xǖ>E/DxM6#4oAt)ݩaz'e!{Yx\ru>A!'w-C2v}Bӝ<1:$g/Nru4n,}Lbl[$k86^tc#l8 :t~Wc Ew'rX HxЇuұXYx#?.(Z#2>tmxoy&ؐnЄ IDAT{G?- /z|KO_4~k5nʴٓ_џyirY{wp7G" |n՟LM{|6t<mp/OՉ[ G|6=4/fý R*K!aٹI9NSF97朼{ejk麟@(R Af sp@:)i;WWc_(7I 9ے 90Q<šj8sJ2~d __M㣎k\W~σCExfl6@_{xB=gErl`'!'|K N@~Ak h‡.^;]M7Osxh<|t4CFN~[m6nHР*pSyz_yDfE+=>fOl?u8נ+C}r d #]'y~y|WL+0YFܕݪ>_Kد7=8= G3I1l٧tu80Bv{'$ru{OmPC7d (<C }ڧF/79{Uw1*M/:KK4,[Wb.(4|Q6#NN7 mg ?DYAt>EYg=g+ '.nK6/18u71dmr;q|>#Hd O:ESt3C1NAO]_ҭ[`*IƂ t 2'~WmӮl|xn߀z 7 G'?s"_H`9TS[) X zW+jPG~UIy1䠼Nݷ]6`1oJʑh9\Dۮtۭ/ξ&LP/OȞ`N#;wldjw't?g:C*_5L1;%gob"> fWk;Yk 0NoFwGK7ᐗ)hbLaC c}Sd,,.nWvdp'LegGi|绷xG9_X>g ~s#xIJ?]@Y>=[L*=1֏W,VM~q4~ ҩ8 be>Yo-ze/He4Flc]/8 oB__'c|xɵAB 1z:ր/,/~#GqhUk:(=t*Y<ɇ;[8>A5G']pcL炒\`^@&.(\eļdC> Kx?Nyiщÿ@`y ?C#Ǟ Ek  D%L jݟet01guܒ?jȷ2e4Z۞ޝc'oO/V@Uϒg(n͆a0r4<|:/ #3Kٮ:nZ.Z sV/4HoTp?~m =ς'S(dO~ӧN:y|xO @6F6^6/k~/ :;#EhoQŏ=^v<^\s/c?O/>+߂|÷mnԕ`Ƞfo^:[ 4O\|TܤT4y5<^2 E9`vok(&c|.ndA)$ҪzhӑE?wSeJajn{Jp1(Z󌲺QF xoď6f \k8ϝgWUE> 2a5 #Ű>ﮆnBbJ.hƃKDO7Y[![O4峀fd_щOY⧳|LDۮ._h}[w=oY8 5ᣯσ Bc],U"R>ܹ1_sK8+cڱq>V܄*hoܭ LZ!v^EWߗ{˼Т ߋvሟbH\bi6gv1#?&]M&_i8z˿? \e9ѻ~Pgvq'ŋ}/o{zn&k|P/3&b?}vG1hlXlGߵ;^;EKNjlqܨp:ƃEBptG1뻊]Շ_ިÇnVjb6>C62nۻ&_|_Ϟ_#)31 !wЕWnJ| :>q[8ӧ=hp_L3ҜZ(ǰ0t|?YW8_cuD4I[8듨`?Y5ipU9/ d(F∣=^7,vGOdOȄ/=zp>D: _?"cljm;z-xy" W7vǎKr =%ڑet09EK;)i{>نpm[zNABjb;yCWk9쒚ċM(]eֳh(}7yśsmР?O_vd|}8mh8zd<|xzڑGI^{&_@hAtrY`hEC8ldL6}Р>wxc8w@ Buj[ёgt l}uc>$DN)L зo#Z~̫oW,pͿD7)øw5#^m-g;Wv&AM2~K O';ц<6/*#3blMm7SOCw1- F/z^ȹ_7pK%x_'DHۤ&KZpExr}`- *+Vϖrx'?؛މg3#> o =ٯMm˟/w. ~{ْ?&h 7]W~B /}ܬ^wWw \pf-H$߻r/|p=ۍd C?3~ho=AV6擟& uWgFOYlDD?7YB%ӧ;CLh6^` W [qoIË'on?6 >󎿋уߏL{N?|g6u_[g?箊3_vvC8\&7A>L'jDQVCGȴZx+[Ye ÿ&vA ~UGQ%ExDOwJ+d@6Wt?ir=D?^Ln0Xq6A]d@ C@+?]txR3·-?7:oOEcvsj>g٫v9$;9S亸Ej1f(椺HQh$)#`ZҨi`L1N2;tt*e;R8N9C N`fXE%yy_nƽT]>₝c`>u_:¯7oh:z&um}uе}6PPv c«w} m ./ѫ$tj/ݶ I//E4t0 g+$ve=:x;9cILi V[kT/imO@o_#b۱Nz5ُN_"[8 ɫl2e!F/Lxս>Gw5ego׋uGcS``<{nA9(7`urFfR>qzp<g!eGש;?\drZ)^tk𑣲t_ΛmMƓ^t}2+T ҧ;GM]V~U!wXxE\~x4g3ؕ~&Dϧ=+t7"Z Ѥ;';^_~wGO:ڭ| =Hp;-]UNÿ=Z3`ow+zgQN#aF8d`vWIW F>)|< VSDz9?ɝWcQm-h#{L/NרviN|sW9Ahk ݼUp9y7CVL΀𴺵kd& *xwT|Q%1Agk;o+pyρsz+Q+Ydow$D|mଌ_ 3#X:wߡS w>k+^5\Xm!7 O̦ XT"KoG1=9wpY>/7?:;ϲOL&;]q_I6[nX rt('|r:=/Lt "oǗe|?kdmr!{t7yg# <8E~qTz+rÀW}h{oxK) Kiʫc:wwO UDwO?mCtufex0ڋrY>~Η'/Qˣ4? jl,ǼµC!o˿1QlO/wgYhzCyR\#n^ I&(o &^>c2x y8Y̖6j3_I0}ZpІ}'oÇ ?G'Y=m+Ozw;6o]/(LYY6xd]F}?x-:y٭qUuN8 kmta'nN"-c0z8Y1h j?\&6P kRc䜱,IO=S=ulOVg' RO+n0Kwt&NN*+A98?ֹD.}hwt@=`d2@v& _^|#[۪SngY~D19:j鄍l`| !8|Kg`w *W!pcݠSxl&b< kdUum-3w{C;Y]둕N!W=W,_5=7HP՛g 8eq%\t0 ЉM<vx A>mE<弟_D2_t@>>=z~b&eϗ,[.2D/o/&.BVgȅ/|`٢ :k^P'4?te$ zo1yv!ڈb\Lv~u%It4ңdbv6(t6~j/˻ނt}Ջ뮔zWfpN'mbc>'la~4bdLos$KdR@O0&i;` O<շ_SX+KNv1Y߻clGGv\w C&o0-*jGphِ ȗv??_nW/z&^Ř txgAStE拓h=_(Yh!m79m#GɆ>{M^N^˾/}LBqkcfx ル-\GTwL@_#O.[Um˩[(兣8'XO_~MOwm|,AC\<`c`t5NpYl/-B8y1"XTX9O] `'6$QqUnKS\4>Bћھs\M~~ḻgd8p/C|Cww~zM/f<#ݿ_Hvٿy ŋCm m\]4 p(>`(gxⴺL{sÇNwNǝc _pӦ Q̏Q(#xaU'=ѻUZ|gw:]7Nw.dQeS=!RbVFCp|.p|l#Ah}zIrPzd_>h3~++ IDAT뎧;x:r`'誰 ] [R ` M5|aҺ IωB`fanxL.(~#&%dbiD"!v+`E\89_G$] lkЧ!DxýVSɡZJuBSTa4\]d+_q+ <<8cHFaL$@6_ep;^FEXy$l{tq Kk~6/gkǿs/D8Ym>k'<~7G :=u k4J\ y@dѤ3vqW+} sxrE``ƃ#D?d 8_:BMo:yB|t򥽊.l.>hE0dSz̏/O\LۘCHIv'Xw5788S6}hǿ5dnPd:Z0|葋#w`,}~ɲ1dVg7G'OM"i=¤Uq B8aWrſ\<S.O0{0~M`տ1 :#e/?K%ce:4>At,\ئnzf3dcx4 ?|ö6cT{}s c ?^Bo)Nl@Wȃ߭ONqA`ɑ Ӭ+*uSg?䗿82yD3W_l_o~ՕG?`O/%;$% ^<"W_mஷh/`2~&WD蘱Or} 8ﮏ}ne]X[MGdb2Dkgj] =n™7ymn#&a˵ue2K{$\ہv{<(’^^ZCMAƶ8 "F+y|~xSncDS:B/)v %ە{}ɸYO_Đs5z@:}<1?#C1eBUd`Ga3őy|{4"Է~!6! O{rm0[8~|5_\tm>u{"nWPaO=*%"|_Wݹ0 l/Gg hhtع[o݂佶0^Y~ ʯ_rL9c$::}7uGHumm1(,g_kӇ/QL黍.KOwn2 %⍿tsg.2N>^O'X\E:'_NXOTax@XOM1X<{TLvgL&6|>~?Ĕ1v9=r ~JaQBgLP6H'L(lЂbsyI{~0/>Z^ f:ȑoUfh~ƃأ$xHΧ|ݗș!/өF?1:g& G~">^ozpg4s2g:/z3wPs[` [Kw$#䔜ʶUKsL Ǡ@ CQҌN/O(G`w"~ `umJK:G$>8QF2ٻ`Lx́v`Vkxݏ7f൫l?ppU/Y g9EI~:Enˆ|ƫǔ7fuN"Ѯcޗ9d{|ζ&rM[%0;'+Hg^15|6AEOJz_Wv-uP~}M |K[upG \x|t:3 d?s?=Gߧȉ' I,vՎlwwz;%r /_8-nۓz:w>*,5³\[u9zyg}[Ug{W=OvZ߄-Ï+5zv;_oβ+ A:;BYP/ ;Q G/{[y p}Kƿ6?]&q8ڪ?ܭ}F48}"X)z7~gvEsb~dLO>L Pc w `G]>6RO!UF.|X|NjMP?߸Qxg"T{/ɌFF;tt!V']v M ~ʓó[N?n7E=muc9񊍳+^^k?4n[~Oed\ /3qy[s_4y7] \wq^ \ O]6Csx* buIwnGd :>o&xNG_d}wdt/o>K,E.w[xW|:./\խ]ԤNÉ-IoWt ]9TU;)X>0[p"C}5&y[|ܤ9[[agX띃@1Y\?'GxxDɰ1iɃd#wx\hz^x~fvnh7 BڇW<܀s)>`}-+=~Op?|,hW/ut?{ xoF}6ɬMҙ_<OΎ7yt>Hm?_Q~Gǒ/}P0n1k}4d$w: +g8Zp.;?W;\Z]6:>Y:gmj:oWnW Pm|OLE xMctdD V+F{v?Mwy3|xgwjPPwiKߥO__%4|pLm^H/f6وVȃs[ϞCdfzų|m;?x}ݪ;_p w3g.?2v/~c-o+7-6׎XS=$/.X|x> >&*j4q%#o_A$C :ۼƁ\Gl.ЕˏV 3]Q /'ŀm Sp''}o-嘧?>ncT`m:~Ꞃ.՗1isrMp.^n[PΗF^CG,Cn+>Bx'J;pyVq*3dx`WF:t>xgfB~1|`~8j.e7RMm^ 8Pygڠ>Wo~p]s:T\>>/Z3'R2}$sHc>FJ*GϮp*wo*jy4'k7Gl7!0bS Y6)̗+6: #ut;u4~*D.Ý_`c m6xAŘ_ 3:UH N_h$؋,"Mfӕ +t/?/g9_A_<ەUk#:~7!_t]gxwShwe˿mP>xwUQi>}33 |&ɩ.tG\?`/ Dߧ3K?sH8&w]c2d_=]/'b1}r/A 7VBP@ W+BvPmX.ͤ`w6>yb.>¦]_ Yzy%f%?d-c/エo!6٥뵙#fiϷ ?;tw=>7vyl,֒!{Xk;0E)G ny*&e-f>7&4R%jWk\q2rWqG]'i{l,v`Lƈs/ |W>}`;VT=U|l3A mtkp/M؃`?4NG[D tNՍDG|8:lQ UtkL^/[ݸNQoYy % ?t~Hq|2/9%Hј,@rS`Ͼ: V@L0-G#{z>ȐN7<Dx[gh53<=Lu*R z|}f/zmt?&-LOů[̾uo1/4,fa{0ݿ:NTpj'W'_ex&mtƏ@)泳l<=_Ջ=Z$E|ƺ+@(nr #žWf$/v=b|y~j#cxoPǾ&'M:A3yCTKrZ]RB_ԖYLԵo~g$-?"~ $k):ۤo"sexO-8-/wkomb;r9>ȸI M+O'hx.]1.,/C$O0xͶm~].>\M;>y[9>[7}ϼ'GPN2M:l䋍e(5h9SvОObV8Y/+[ۣ|a'?/0G[T2!Ro \ 'xGkn^ ]?5YӢ&`~:"f̢xk9Sv-ne{o14trN>_y}g@|$^F4Nd+K`tS:>0ٟMDLOkD9 E<=ޡkSnt11oNL'b?Y8Mۧ#&_Jgˏ*iKgKPx"~dq'W>Y#]Nj#|sû0658?p[b Ȱ l6>|xt=Z7Yq^؞'<\!w-붰W5S˩`wز_zXtma'{ d˧cX,隟ȯ^[]42 IDAT Nyo*+8+ B; ~' \6h~tʵ!c`2DW’uT1I8aqw8'jDyێCoভ@m Zt26՟|sey~+ɗI朕5dl,J;5/K0nugUWUIfL{52ù gho@>T6ڇ<0O;ً,:x3W5#5-tnȪ(|qu5m7a_6lZn|3?G+~4c "d :~p>G@7*GOC4^GgPOe7{x}ڈe6a+5 пx{,mI79]Qu*غޯ~wl #7oc;IpO<..j~3nrN`^,;V:#ڂv!׎ TZ::,f|%=Kyʹ<A? [sʮ3xނi1 0>N JOVlq 6LP4×Eo77 O01?SX4D+/G O֣G@9,_g=W=O7XGӝv-$E.&Vx+~7&w< O468ַ~gC'^#imp{V߀``_/Rnnr*ߺ~x:MW˷b_c!Yl鳟{We7+-QW?o?b^ίNƀOãDC?>;]z2'6 zf:&|}#@O/Mހڞ?} Bb<:\s`l;r͵ӫI:~9Aqls];z麽c Bq5Z&T×,55˅)> `r` w{\6v-e75b;f2f>즰 bMYmPtl~G+ݵ`xqtdDn>b;xSC|>}⹟/fx7|okcTb>)jr(7 {]lU%񁗴wrt8y1T|Nn2 [h5+gPٛwyI@v^5ŕ]i4ó?ԅ׆#+'ҍIg']Nw8&Šj_gWrynFSs1:=o#Srﮯ+mN>G/i>Vx|~bO-&Y=!8% /'a^mxwv@[$鴸M݉2}x>j! rQP=ɳQ{%剛=fߴu@Hҏ78= '|ʃQn{`VdV˜߅Y\sȵ߀[OW/?5 xz?񓰴%1tȀ+97fGiޣ#|/>t(TV;?-n>b2hZxVioRОMx႓<[+mi: s(WIP)'P #-'Y۽:$f?)i/T>6_5jkJCSИFn`Gsdzɗ[thfg˝* Bh_b}?+wqrV}~qwXy8t5g=WjFOg+_l~IsnM%oٺFpfC V!XUUOhVk-LKχ~>(n޺Hmv=|쵼ͮTfv|kj|t2&vTry]cBnp^ű U6QBlqWD~:[@ 0oby>z~0{tbr6xBi|oQ @7Li?le_W1btN|dʢE J-:`=ܯX+{@0ӑ1d!JhYf@wRw)}7C |'[6hk[Q<9g]SwBLO崰ݥ!oGx_],tc`uxtr V[M/dn=k/,/ѿZv&Uv8?,F[~r}ēk=o{wD =HכT&1ON9nt?IZL_ov^//v \ #40bJq~%]Mgھ9XȋmἼIw1KGdϳ*Xg<)qQ=>#L` ؂x? }WdH>4q6p~$"pB Sk9?٢0uن7ob"y<1琯=X;7wr=m[p}#h}YГxwjk4-tv>&ꣽ+Mo{jmMtVȌxfF'd%dl7~bes~4!*0ykL|| y_ZKߏ_91=&&| EMFU?-piCMkw<[GmҸ1`@w.?i?Y! T~tG[uBtc dJ;]Qzߐ?IeD2FNO*KTF~[d899lO^A& Atr6?UGo7 &GqyE寞|XnIWqΗ_c?;ᇎU-t3կsz~ :vwz;}@#8 Gd+U5L>HډMXݦ;*V-.5`D;_Lkt==v6uzy.O-[8G R7^Q ݟzOMb+Zˀ?qz{9}/:}Ug Z|Rbj &"ZW]iQaJt] Ed]>~/z⋄B}:&\=X>f(>emgţhd;4PxO#AYT)G̗֖U ;B{Iȇ:u) V8wuh`N*wq,j.34apGrܓ^E=gS1nv%Nś;1ɏХ1v3@WVT=kE?GF:MZ勎PnV9;wr𭲌10ot}7)CCrܕ[ݽ ZapgqO.o;0f}bVlfXGS_2Tt@ Үn/vM/ɽ x:c#~ xьowl)NgAUQ DvrHoPXD턢Sh:$`kHdxaq^+xI ~c_YWd%W)nԣćߪ~l䢤ol:O@yIɽj/L_hZW=ꬎ+Afׇ8~{ç_M{+Em?{ݧPΦ89/}kxe?ɏ }t$Yhuu| ~:]=O=ɹ@?G|(mW4 3+}=Z3=^w*62mx^ S^yj +o?ݢg˓f GOp9zOlEwb mmmpFd=߇w,W7xt|,v[{vO&~˫$'VdN_ d':ZUmηB#zhE'7>~s4.侼<[ӕxѱDgpӳ+ jɷFo[XGtSe=7W.7aG~lptj?-vp{z3'#?J?(\Û^Ȍss域O}=մOǂVf?->Px?.c`>Mƭ[\08/ѹ>bRm\@Leޣ)·陌m lφU'&t~σ؀P:޳A?}ګ.\"9L:~Xs%Z|CK^7-Ϸև 2O٠?U 3޵btG;Y$^?WOኛ(1r}~[ % ŗ?{˪ʇqnuȇDbaWcW l4鴳ݭTͮ*t/lܟnW\77C2nmX>|ݗ8T]ȯ!fUޘ^<5fÀ?ޗѳ}?S0A1qnb(ٓ._vpxyF~kR]8ͧOj-2d&Z'-cLqeB>]o)ݭclqs~@GE!@#G׏g. ! }hqc @ӵS'mG'kyq,Qm>wRǩ}?D$tc' ^w'rybwO].'ۗ+ģr"_La xQA4"&|s=͗[dڝ!\=Wʧ&ՇU_W=-iu) MzX~ GY>3:Ŷ2xWu1QMW?wvW/N/ L 3]j}}&>=O,0cw}Y@6G+XǸJCD{Fc+5: ;Acq S)δm9gUβh,9OVvIf/ ~R.\-8q%P6p&ijgag:)9_+ՇBexeN$~7S}w܁ 9L7Oxl )YbqB2 LzYt"u`rB[9ě@NI 6$Ṅg:cr@ %uׇ^6ňqϞ," ] w{ OL?QN#@~mNqN6 ^=[OGvKzptĻ$mCx)kgڧKa8b?>Rz}:> vBxҔܠ׀'%ᢣ$T9m9iWj[ ,`щ^4:xBG&}yAosuMx|9n >n郎.6Zib^'chvx Չ9IFBw)GRF%u{tpƉq!}M14ח_>A~/tI$ ]$gIz+W=D㯲STMn2&~Oğ/&מe?+&m\1 G_ug{L.'=\dx59A2_]c |]g>nb˥FMxB%GUNg4_Ϗgc'o~7lVhyZhl# =LGS;u ?[ggmV__ (">g_eg̉h{ .F}x*#ϟVɟm/~˃dyc/M=5{ %#[$&eჇ\6gh Ba]0g % OvE[o˕㧿;#or+6ꞗ0PC=/Ӊ.o09yvտ1χgk!#[#g9 vm ,o6Dv:Nq{+) ֒z IDATYлh1`͑']چޛu *{XchpPh 'ŏڐq<DNilaϮt}%_Ej7 hS.Ǥ?9Nt`aC{9>%!F4Zsd;ݟDE,X'_M֤&tdٕ ϶pDDwpf [闿M*?KP_tO[0ULŅ`b窀I)h%ùN6=&/][gb-d=֞'Y|1[hb6h'ģ vUR|qV^ȱv &!f_}࿅b,C7ξѫnWN pZ=I"׆5򋗯&s[@y$oO"IӏIch;9 T7~i&Nw5Y$߲Q6_opcO_Pل;9Ȉ `#vcR\]=gŚ_w7>$h#Χ7ٳ![l۷Eex1SV??ΧWZYƓu|OdہDɋ/j_wrEgp9x/6 p\ e~/9DA$ӷtE#&7_u|_C9ۘ$냊#Ş9O=qy'vqsNO>;`l;#Ttf 2/vY;0?& {kwXcO6OGrZ7΍grv@Ԏj2o=xhad.+<`{xfGc?~O> kUr SeZp s^! q 2EGxޅ `5S^l[Eu!ӧu:K_Ar`ޮ>u± q1o/9t:z5Ngi+^Ea#t=| *:;'?Lh w09d]'+.N݂z9 ٶ5_M7 ;WW-) %q zՑuOV<&G96?~7܌'87gK{x?@|hϗAOMh;`eNLh V|mEWNG0ڊt?~5Mtv;>1ĵ #S+u.+OF3|wRBG~b+?5 txXve,ڕ3b7|rbw\$K>)nPꊟ{,bZ<0YmOϡlq~01}'tų+\nsFnS3r dNQ,otwO'_ lhlA:ʯ W:db.G'{:6Dhmqv_I_Y?W2 f~ݒ?eWMtwƻۈ_#<]dos_xEOS6/'Q>=:>zzsR6ZUgrH[pbtԟ]r~]Ekd1;laX=љ.g#t~jehLb'w4^ wMn1מ&nWٯ6=#± -O%[l(v,"go?ni"|1{A bg|ؕ] ܮO\n:8aOgW>c8FRNyY[{y?bj(`r(zRN=gHnDcC`7|k2ñS>& E>Yv4,t5푇δ!vxMv-gc=8qs}^<p}ݣ|9{:hIw`=*>[+&pW{p;Ṁn?_ɩn:b#b?;cv$soxP6ɫ7oK_vLw|*mlenv7R>xê/ GBZ?6?[ X.'>~^yByy-wPW9K,b,nÕ۫K~k]kȸlMV0{tG?`%坋{zHC.& /}o]ϗL݅bQ_?`70;w֝n],\]",̾🎣bNG!zy|!+;&PӜgaqlf*zH!cNx/ћok3^:j@)PTXo(/n`^xʦ!6+G7)6Cyb^,@:co‰,NGk8jqkmdr xv")n;EÒYwtKJ؃ݗXނ3#tE懎U\2D=aoAHP8:Fkj|с<ګc$fg]AcWw@{ h8/}ss:kI B?|ZK"v<{nTU1M-]~TYdNy<_ܳ@+60ЎGzqt[`_wA\-$٦oδ |Qc1#Ep3; B~N85|*cn~ 0%^HʕѹRљ?,"fD7N6yͯ,Y| S#w/&&q@Z/<n\ 8ɯ?O([ay&|a94?s?:˯^MP9ǿto'Ù~Ň`E Ưw|ۦGGzlCݽɍuƜ F|2[-ffx!yn|"-1I{ P=sb| ]^MQ;Ccuw8#0TRbKllDŽ&tpy~?Cuf !}` ~|njpdNu> (1JxOC?z ew Gm޼N?~skd[D Ϗl.+ft|o}x5gdQ_oz19vLgtE|MAݙV|&}?6?Vn>*}lmJnKV9.{mM0֏~w{0ڄ/} %1H9)~HcqA(FU%[UQd&K߽dphVqnh7ĀSuťuZmjFx܌InYȌR.T'œexfczNA#S.^Q2"Q='}(_@"j:l@g͡rD:}qi~;9=6Y=:ҕ?0x*GcKdll͑o)g56>/ϮxOOGhCAwVS^?] ܠ9ĕ-Ed&&@5xS`,̧줙 ~nCɐl[jt$ ._rBG1Tt,|7_H ~i<@>-QJf1<[bx<1g_t,=ۯY 7}ݣ(rAq>>Kq]G->_h&1ᮥ4gg*睴q 3~׋& VfkN\u:N?q|Eks~_\Fa`&(1xw0j .XwP}߻@In@pˤb+}܋ 廳; Iݢ~$H7(`s7y)߽ 73?*Ѝ:&"3]l],~/w:ޤL'|Ɨ>h^3Ig-uzȱ7&796j!^nxJI[tu'|I{ {lQJ,^>2|>> V2˵x/C[ۢZ,̏nG o`~#6tx9/ĘkOYGc;.1&7Y9^5[-%t7i;_џxԧn9trv@l/6| 9;~m>z<~j&H8Egb[4\.t'Z/&TwdecAl<^mNʇ'Oϡh"7MGGNU}Eg-#F @'7ۆ"Xm"UsI*)GZ{x!86%isVDx]Z}uxؤVCykk@a_J f4:8^+7pc@=Kؐxޟ5y'OvFt>t@h O+<) y.bVIgpGGNz VU3Ým)}g+w*|7{5`'S3y v<-+_h-R-:z#C i~K*ǖO}N?5;Ү~u]JGrC'{}_LXv~B(jperU[l;Ksuƿ1O9A!g_m,ϢkNG*}[x4hvMx=:2pb} cVGWF>S{,l[q/A>z0xg,&W|^+|&Ck =xJWKd'k%/.7cH LGP_c9=n\IugM4ОgA".o8vm=~qQOo2&trv~DG7"3`iXnx[Lfw ɱ_IRr]CoqDN?) h)G36 _|~3ğo/~ۊ v;#ޞ.Q/t}ȲIHgtHV}b 8:a>?`O<*!KࣳGM\ oO S_,w֛gx/u$ϣ5h/?&k|Pw]#Q*9cq X/L}| ݣu}fM]t0Nnnӆ_._qة37V3$|1OGgΖb_ >*_x6_9ؔ\G\mtF ٴ{d1?}V0C_~  ChZiLc<ѕ)'ǂKNaǩl&Sќ; XjDIb) uR֔X IDAT`|NZmx%^>Jz;< KIxx&FH5Pttט!M;mȆO6GGrp1SFGm`]!Y+Eo\ !nmr-V=3P~(i82Op_-sU-6I9e[x2tKOyvdw,iD׵Cg'C~.3T[O qcCO|ڏ-ho/F?.I.oĄR|x8&E,^^c;>`/ ~:]/wY\?f|lN|#-Zӫ%fW~ayo>^p{u@ٙm]WPuwhwϏEPp ׵v޻d![db{x;P܊:~\/7}`,D?ܤgvi29{ vk7ٓy}83?l2㋞nqc,h~򁻒0F8X{8=j`o␝ӳ⋌O.>GN%{_biuR"U~LP K?DIb`.h/?nM`{=gxhRg)ǒ^#׎<l.Ɍɠ3|WFÌO9Ѫ:F moc6}p-=xF5xK]tƣ6rZ8KlKÙT=xcKo5 '{zQ77`yߛROG'& .ב\g tp8?&4ͻ*%P?/}Yӎ?X{u؟2<хN{u݁0?{ =Wdz{oJ Lo 3\[{:1^ڶ+KatUwIɭ?w( qg ~xuݶxr ͯkd:_/$T>]]{'qM|GFPG }:RM񽲎WύZ}^GQ[1=WAh}<UԻ{ B .*zyN]_'I9gOX&೧ؔ|/U[/out@GO=m~]ޏQyT9)\o#f wom`_rېO^uԽs/%1_& DtgWO9`M3\nOlXylXGG/zJ:s6>#cBl̛ d]FtVqy6'×[<N6S p7RwUM{ﰣE/]!N^d={P|""V?-T2_+c<%b#tL_uݝHng} 3> _UṜ/rtH~&ŁG G/?vd'^'̕I~6vzr|Mtzno.ֳtű&Zd2ʂ MfdU6^nk/ڃ7IONǗAn0Pkos,Ə1:&2bD|[4ɰ8W1i?e_Y\`]^mi/xAl6#6; ,.Q:/*ď1m? rEz;.-_Q|+?G<ƭ*C;/f|uSl}PfcٯZdgߟZ 3jɅG~Sm>1RU?; +ۂR˽t.c-c`|/_.s86ox|O?;tNmf6#y E= Вd_|u&F,'/ܠv(ha ؕibwj9缁לwO9I+ S9^m{ FcrFvW2y"_^bm&ZUwv~d?^Y?hN@?x2V\@Wum)G۟/N7Pf_?V&!p*#  ?LPz> 2z{dqb`gOv6Cz|4Ul-4s$ k ~@yl8KL+9ԫ&5 [pTG6e~V&?Mϯ+S%M6Ǖ/ ~+";X-&goW6;o3v,IGr|1O邯=2|nWfrD?3 鴣,>@mrG]\ XтI !|OU|r%uWE|cBmxGH.bsW@<{G:rGb+:M\QK厓%ѧ鐭+دkF M'GlJmJn>X8\A,Lm&b˚_!$wSB+v$?I-zDxOpdn9Qչ[9gt88qC-ec'ۻsrm}Om(ww0*;K 5Ꮭ}MF$-/gW9< WK#kۢػ.L tCO{;O_DJNVdK't nWcs~L/03to*XM =_? yaޕ/&6UYd~5d!o9m79>i[hA內Lűŕ+䔋5/Pc0sOUOu~p[]WwxZ=X<^. 5M'x{`V;K/#ה@1f53#PPHqYӾ #yώo&ϐtt2[* Sjp/G1uk-n6Oт($ ,K +ao@N?*`AQs[VkxU l/T>:p<'/~`?A>mgen@w;~bW+8om%>ٞ`OɶB24~E`_y m2jOf؀tN>W'sӗq1{M .(Vߞ|0O}vcr*{><+0+;`+?6NuD_=S9'=+}-wU__QxƟ!$# M&L'k!Y6RMў`Kd V>>+H'tفKґ+z}4k$K~|mdzuԄc;8}iǏ#+ og8+5蝝&{T:N:QBLrN5H^*_2yxa'C|_[+;P{Ϡ#{@mG|l5NwbLGox0]g7}B?Ɵ= ;ӽ oۢkџ~xVv:=8vx~h h΄Z<ƾo{ kӳEPwݪ}1޾>n{GY͇#3GZD;r\{@7H3Oi<4#XBPGzܪ?拏N(oreÍyMZM}GC^nXo2\.{l;G2o.Nʖ nLLw =Z!îǣZE}#(Aa,8m0vcAkGds|\ʲ}i(OQ Xxl㍒+S66ǠxExoT<+n:Gz6fG`zYPZb`5"de[W*|X)!S(iQL=*|iwx&cxܕ'x)8dsp< L2vy:PF#䚑G3#v hOwp[8Qd1|nrKI8۴\[[~ʏk$!k /y&1¦SiV TIv} N X3H~kү~/ɗ:il1D9|oo~oSRO(ٹr2銇+ >({uQ2lFTXJʏ?fa&ڷ=|m|OYJF\VsFC{̿0l?2Z,頽v5\Z<ѩb tPWh_e6t]94LoR|4<&D?L{p^:>o=+~ۿkφC>tgvxNgڽ9p'ҙi;Ծ{Ӈ"Z35[TϬ3›ÿT.i?{ׯD/a1fiax}BuK6/WÕ,냣4c\ܽ(gxȆ~>jU?3`]?ZNgnbSms"d9?$:>#6V:u_vgd?<Qʿ! ?'ps_LGs jЙ_.?7|y |p~/ y vZ>{n&lw׵kl~-)iu;>UKx;t4˿!-}wzxuBG&g @Ŧpmrba* k ºgA#4*wޝ hh<:JE3rڰsTy v,wF, ec8\XgW[5K)pNgcl9ٵ0)pG`yC: أL1ht߸s QƟ7{0d*sr36@\42ŹXuxrͿX ?8fr~kz юtڑ}{GȤmG54<7݄0m]jk߶|W>>Od"d⺉0pEp.C82T(7jJ7<Ae#YYmg;߳ g;G3eOpxc˳tGĶ+Þ ?CsK:E.׆$r  \I=ۂz>n9N*K=L=5r/7I]39C\/='wxeOK'\Y;goi6SS[.GOֶGWgne'(q0ކkxm dAo]̞ U|{toWDw /I4mhoM»: viuMr֢2tؙmW؋ a%pٖXr1?cp2ϜQ ?@d #:GN:=Qrx[~jS*9>7u(fd6j_4t |#t@|}lN* ?=e t:Ux+wΗ]qO-,ٲ>PA3W| pc P ݋ IDAT iml iЇohϒAΖ鍬tWH↋3=[u#0𭜎quR]G~:yp&AR9БU]ydћH=xٕ,j`ֶMzjq@G|a&W^c(}'^˿m.~_lp2Pob%27p9|czSm>5b97c鑌V:sv WW;_gG\tS6bp9A[4$~T:XSyEWOu]$|.)LT>yo+lbwXϽ8q ȵnkGG `Ml7:~[>|&?{MMd.6w(o2_GGdX<~44_ '-L/V]L )_Plȳ)e;?\U޳ICf%C7 K/^ r s~p2K&D847q7[t8Y5+oΜ]|M M{: {bOz'b[D>6he>nM_Z ʶ]`{wԅs;\tVmlR$vdxGw=OrjɎt?fapx?OO__>]_;"@~1WaNHwK{Gh;͎tTi%fUB_"&b{dY ''jr򅷅% }|֋q d>tOp>|To?v*'Y%2hyo[k> #N3ٺ#d3vHIR+C4Q.]m_7- c/{ӿ~sD1s\OÛ\oTf:Kmz*g`eԞl絵-OG=v3W; $}pw~WsиnI'\dHߩ,F/0Ҡ'[HU1ܧG?C8ǿEcIˆpݜKAtMz7!xΟ-|w]6ʑy|9xEcvz[$}`|aBwV/(X\t]Va6A*?&knP~CLh!OnrW~B/nc:mKt!FN>{FەLvvN/Gu:tw>FtGr~cj.f6?k_m|s8f{ur=n)G+? p}JevpW=߀*.uyj2k\X^;\A!t& DwDxR:Y:|+ӓ۹}m/\>;y[Wtg4ǻIF~&>;Ośgsm7C'sPkf>a?0&Z` udZ7.G|v|񽗟.>9{(A 3 [ ,np}|7W3] axyxoZo}z=_c}w1F yn 6r- - l2dGN iu|>vT+F-n H>hϯF}-xʟ_2h千цRܾq^N22~wMyq'lrQ;v<ўζ/O!#r_{rt{?p~t}ۮrj[{`AbvdɊ|GI+Xk6|* [ON_)w=m05gC'~UۮN#x'מiwBJ᧯`~tq:z6>x{vDxyclߝѧnq_~jĕw2?1?CMDGКgk9cck^mo°I U` q|N|]L;RQ[Ͼ[|/:ܛ$.lΏ-~Ԗ:_cV>pp뵱 2}ٵzT`t|o[r-`:6q@ Kű+۴7>CE mkv1evuf͓5z8c.\9>b-%va mljUG/7_~عE,8/ e;蠟<>*ЎUH>.Ewtt>6PN' _yƻO*&곘>=u|.J-fW0\}Ï|`d_=3>8OQe'_j(6)hG]?٘0[኏sh fgTJ=ecӯ,]EW?:2*Ⴣݭ l;ʆ~uBkOY4gp UEeZKmڨq %L_FnF&#MVW׀phnVgf;xD@Y {~@;ծ6;DAQ7oWo8k{& @ƫ*~dr.eȶ#~pE͛A-Mnv?E8m"na˫W<P4a> r)͘nɊKy |6I1Ice2LMþ3kc=[R-Gk+#l}s9IM+gB0=+x+4v õ;jebB5,`Omry*U <_DD.%zV1MT֟h1]nz%Z/-<_0J}m'Ќ}ɡx6O'i tOue~ bp$۟]Qnbe^>&7MM}M2wg8hfO_ȧ꺘ztњ7נ$/}ǖAGEzK7︚tJ:Y޻/_y4a}StHy6`X؁!kGFͯyA+׼qsOىE{?|FM/LLj9A80ן=o_0odozٕ_6VQП{]xg͖dg@Ek[oL*>\̯'RG?ͬtk835ώJj_+ 0hg7'Gd'}=bVї@t_\m/]@xJʰ[tf2xswC!ҭx/)ccNlhqvxbq4oMK7ѷp>w23΋b.a=>-k_gѫʼnv %ݢ# ?E {+ݿis}^ Ftn9d\ԱpwȷNh֯H;Y͋jv§)-[iEVX+/;$mlx$Fu@ u ֔[`_x^@0 v42['.p[}})q% Utm&7^gZ\Zo@S^O6mK&(a`6v/a#E9~p3:ogv0WdJN~Aѫ7@Nk}+85&/]߮Rk?G:󩞼wF=ss>\,fxo䠧'vϔ{%%OqKHdi$*ZGD?H0C^;xG7M$l?|X, JөL} 'Ovv_L7eğx U7ў<Iz]j(pWR|Vhdܶ]1n*ڝאDGp98{wuh  T~Pֳ}Ӄ?#b}C罏Ink5X[o"o>hعo6& rP&ܶI#xvyuNNРYbݙ!`̄}cYOBv &&]=џ|:.ټ #%_Io|zN<)ldv&gll{83_wQr/ҍ mFoU\,#>6\;/&`NM6 {yX;-na,_ 5bưNymT6i'<jX$'ۤ*vґ> 55|=UWv:'wylscc|n3V~#x%WZ*gZ \K\E4,O_fo'|:'Y$IX-A3FGrob~\㮒nӯ s$ Qn=|^z: `WEX wI,33٢t9`o5:X;s /} OcN9 %{YR_ՖnvНa[l\j_8Y`D=*}6gs*XIÿqD|yb!|ǜ7ֵsvAxQ(h%v_C.gN̮s86=]ˆ7 xcɗ?.'RY:N76ӷFS*;j;8|txqA(tq|'D1ho_Oi:y͍sJcΒM jڄ3Y)H2_mXշ[mѴD~D Qꔻ s/ Cbݓ"m Krԟh&4bhyTsrS22 COv|2Cm9l(Shm'1=u-A_\X'~՛lb>b.Q Whx+_0?]lّ5ѿQ%áU|ޫ-Ys<]K}wJez ܷ.<ɮ?ЯݣMh)@? #'uWEeqoZ?>>Nn)ξ1m$ڟ.J'c0{pE\klB_~Ƕi[cZ=>Djlۗh(['9=v8 _y`fu-8|wVʰݟ(MRbuW16 ϞO?O˳ll|<ͧ}@GOBXf'1'a%ض>.:鼱bRt:>Ƥb#Sʮ~.^#BW'y6~NW]%[;䳽³wd YwR-grjvjxSQ/s}Wݸ:jtk%=/ohcqd7.Y1YރwR>aɚ>>t~8<ߛ;%9ҵ+Ͻ^[*awV]Lg"ќ▎G@Ypʄ~,XOɳu)8Mڷ}g.vI<mMW'Яs>I]9U.dXȤUtZ5G=7kv" ene՗ :2W^})x|TOPڙPOxK}zRտNJ0/mgX$C0u^I@;RBXIԮ-lDpOQlSx7t,n}:)Y:x1켫LC;Ă"s:}3m=젻 m>9N&^ՆMn%93>S`wPAu1}Pq qە-6xOEX&jA_G;]/GArqbq3?ѯfXx׏gxb= IDATJN M <1p'ޑ'/኎٦eZђj[lnq_(bsgݗp ɉú]6':5E7nQ=ͦ䌖o[}=:o4ǫ}-6.I?gټ*t߶I|z7wPs[?]c Dt~X~rfo#eK~]~xq!+;͟[0ݧS50=_~PMڞA}ʇ^si-jGmO}ǧ7tLwv*|:d部&&66 fc6|X\G6ɗLҲD?$^|$qgMa4g+1r K}`'>w\~?wArַ9If'3HZܣq b˳уaINb|zg/FgOɮlw8pGM OwhS8O2M]p9rNfP}fxƲ4v]w%]7]HNIVGǟ^[[/2/|<QM0v5۶tp''7{C5IzUOW?xG⢘X gr㖻!_9,?{?+5x& ʻɵ~}o,I}O~>)#_ΰx̦GdMgtwW81ɳ=0gf=x/OGs /"Ie#(Kg$`zLwy>}5M_c%~/*^dOoO};=ev_ޜma>G]N7ctY.2z|8I]|M[>~I=xf>ypoҚ?\{~@.|>DnsHl=3'} ܁ L?<ԯ6 H 4)6xFl6,?1!f^p (A>_IWV-+ŏ[0B~:Tr'sh|/ (_z3sG8"#}M2~C 2[\yv";u>V{'D3d3O]x6ZӦ?ѠÐ\]1^{~uӶwb;"u2Z^]oXkx 3Ek'G(ٜ6 lc_aE;`?wvOo/.7Vɡ֠[~W_wax|&>Mԭߴ͡'p9?/;a@w/%狝I>+lE_HfocR;޻W\5^4[/La}}EBGgU`J?Z1?V:2OQÅ6fW%e{rY2xZ;AŰ77-o2G,-9UTy&C(+y-@b+79REYt&Ox[!D _BjC-%>#/NY< *KxIlNp0Ւ:z8C:DV0 Y~8qNN/rZF[akK6Wgq{W0Lv#_=k]9U!LL:Guʎt'A'!';5^ѵm?+lP$-hhkëF~iM|6ڞMg!8WNէ~[E~Sɭ^,-u[4{`xc}rcn /6)'Sr{=$EKwV] NzѝP5V&y/D.yL_,؊(~".ژKh*>ajӆ_ l=Lp٤l◎Gծ:s%+o.nM]|f. *ezFr&>FCL MH s7`>BYT;UaڨLSc[g,z'ok6G_[X$]5 ?JxtwGTs&&gVo¢ \ʌqKE``r;&ҋ Oߘ_C\m/bΖ޶1{&qV^? NMvA7}WS4yX7!O?8NٹpV=M0\qkxe(n{υ>14lz'fvkNb.n \3x^L)0"Hd㽜N6\߁3bmr:cүo{t{\E_rkCφdye^@ >/>pRDx4$E~e'ϪKqz<ץf6vq_HR[t2-''w'`+v8{jx5^lh8<τ1*^_~ ^E|!I?y ҟ _;1fNL<زtV1Zl?e Ac<)`N;\w{t߿t]6{rS?Z#e15b~z-Pv>Z'y6K㿩Mg*df}:t~Ih*x`ahy:ZNZ`qnm2*1zʲH nY}69r$&x?<Cg65.dl{6o8 @V3 .X fExhl0Zy[|x0[?'ώd\9vÓ(zq=-o̴Swvt279 & ә-/SٰƓxB+|IrϚֶD;nƈ-)6 'N hm?ut9)Ӫn.Wv(vޛrƴ2:&?Ƴ^-A,ޅON);:D {.FAN&=:= l賍=|S~T6=2>\_W7LM0/TTU)oK~.-Us|N@>juL6ڣ ( È~|.Iq#:Hl=jW0%v"#g1Wݍt+g}_ Mž젇 '8+>^hP|O$r"}]t~/Gr3ߘ3DŬ k~-L,N/ }`Հ3{~I'mL♾<6.[k_# hzl7Nf[>>?Z:*?h[Wףۛ[h[wbFJ˳v_(&7;aʌ&aRۊo;UH9`gW+\7vϘGzͿם]FWTri؎$wuLMoK| ~;gW5}lO_OF\gBȯRGOAtQ,a_\>}t b[Z_vys#?^$~uS\cr,ٽ+OćO4\TMk:=cv09G|p9φC]d( twR\]AG{&:8L1(WΜOGK+{d8NAĞ M ~>˯_#բ}Cqx _zο=kgy8{+{&ͧ} Sa7 \DN( &s7>t|dܒ^p_>~8_ۗn]>bC24c۝t{6d%E>@45񆑸ۙN/w{g@2Gh_?v㹓q5L:Й; e~8:?[%xD;MXfyԩqd_mvbbWo1꜔tmœ'nggZ&1؊|GٝbvR׿$slkJ}7yDC;@zgy]mNd[F1Uػ皈!Qy໮AYpMN`[bܑH9N}w_^e;Eb_\]Nf.&jnEê7[;AI<9mYYlI=WXg"Z/o >ԕ6w 6-O0ўQ rս~޳|= MN]~8̀~ƀ?Swp1-fK'}~L|W?}kj?+n٧߃+YHoOwG2w%ezؤ:j+ O#Õ?}Wvm;N*ǸHܤ=(.L)J_ݘă3yL0%ϝa\Wa~K~#`~0x=-@_?J3v=l_~3o}q+[g .or?Ô0beX?&Ct\VwrON ǧ/Y+Frzt9GBZ׽`|~x=^w2 kXp>UѲ"n`D0h[|.trN3&53'k!N`EG~%n~_/8}Z;?ôM.み*NjxAW2+<6;!M/F٥H{1FwcɎ#g6pmo}=hϽTgL8uhm{W?0>\]zs@1ˊNLF9Xt%nmgl\^_ߎ܉lo k)8#ǟto^O;g]eNduM_x-%=J+ѝ81c_:?{s rvu:A#i6+;|.G2R O٬a*[7E.. @)x`őͭ6?/%E?SsNdљ? V=oӍV_1OS"8+2䈣Fyba =iϾ_nìQj)FňYxς~@N6`_鴘{tgt= />7 Q,|9l¿;~rr6'@a'GNxfg_LC|e<`MIm:_.ȡ3~A'f>:N4$/*['U+F܀n/nݥD._W^go.n?FOݚ-~Un='ұV#]8o+$Q̏ZS0)V;gt9;zM7aLqWW'sx @)@7=t6L='^۠sNe|"}`۳۩\ _}rvV5\񻁾+3?}`81KPz%B^T>8yylzm\臇toIA#nle^@p?ydJƛlX\> +Y&M:I/-_T*5`hbMa [dL+*~! y$<b67^ZnSGo-O78QF' [`ny处^rKM_L}m D} 1|fhvϵk4Jg oڷNlLIZ_:k#f«;`t,X`LO:-eFLk1٤P'g"+ɯz^~ɗYwR&oWԧeL5 )ϧ#-.ω^s^ufl|\nǭm"Rh_w,ٹ7 ^߄&aЯˡG7]leruW9ÚVmA]a豃O$q,U \HNtWE&wLirq} o909I|/}%t_7wqGlZ:/>0F1؜5GC^<×hLOJLQaesB;;Wc՟h YM~<)8k>xN_rm8Ω | Z{k2}&zж}o9>6'9xwt&%]O`:gpa[.v:[MggdѤ0?Z;LM?ŕ7'_`` M ǟ)/6f=KOOvy- LQ?:(F߯]mH?ﮈxAH4 Y;UwP:{[2'ՓwK`UT{oev.gG^>lMƴx텟/ѿ_яyj7o2+73'ٱ>}8m@IIAW6fDxVueְ';GmXh`h{tUuO9з=α;\~7$ *Lì+- ؁σQmï)|eh7^ÈMo{b_{_ i[!ϻa#L l@>Μ} rs;޺z>y9>|~#vV9@w~\sBcH=6ۖFǷ@hٓ7k/l"$'({q:G q-7C<=n.Zxr7ծ~uXEj K~kV!k$cIh ^?8m,3L-ƈcXtߛo<߫cm>r'%cjQoϞt7-&_gؔ\x /s5,6) @(IlfM+/18b_u۩tbu>:}ud쿉njfڝ3>llG\oOC8PHݶyDN.${t+1|g]ޠت =2^PA?vG+qs ƾӿ_uP~.n;ypO2VZrfõǫbEp'y! Km/~OrrP̱>=O~MlٲGy{3͙ ~ .  ".ڸ;k vMf.~|X{9(MqLMV!bͅ]+ _F2@J!_|d. R;:@ŭ/eNv\?Vw =dnF= 0ݝhNAr8G~ʰG)x|TO7FS|H m&ŷ7<*ӳq>s:#ݗ'P"bw(:d=䜬O}\ŏ{z}@ꗿyt=AK10Ib}Td#ƣѡ)ж-}*FOYW`A(猶y{c8unq#٫Naf{}W&X_?튴4g*"G]Uן}'6}:mv ›rIfX*OU4%u|6яgh< %]28b @d  #r2T$e2o\oK4'?n3 VmSt~Cmq>տhc'01i/:1O,/y(^_;lnE6=+. ^b9\ͶݶF6F͏`*ҋ%?v̷;pxmӔkFqdy~Vq<&rmMFhW=}G 6dž=vQ6tQsĖ6t T-듭 Խx7 tnLh"lw&7`>&k|gKG0(.Tc|m2W 9lξaÿIħE0~lSQDUoZTomtKS'04{08ajtOӑ=3ECZ L`cHoN};nFO; ue3.ؘnb_Y~3=ϧ6h2I{dkx/ȫpV'hNj0WX JچAMAڥΆ,fGT_ۉx0fro#>Կ4=,Le6l}oD?gÍpZ(cľ s}P]aM Vt~e?gW[wDs.7'h-Z{m?Fso6QxIɨm7~Sg3c և vC&OlMw|KZ;n?W;(.lfOQ _^2YŅ˕ODl>ٛɃ-'gy#Džp6%Ow#& Dp| XiAc*E7Ͷɇ00|U8fs|lvel~d~3?\$YE.ɪG;-!+a3=^be'ήls%t!7^k=i]9_Fz'w>uyxC>X'=7gp&R yz?qķ?- ;d~}Ms7AloWE6dWb}>bVmz&U;Ln;9e랺5JXl1u` 2~z>bHi{=hnWgg)vw'rMc/h@/JLr [m\5cw"XFƿۉZ}N'_ ַt0Ę,yx=7>Ï?gKGfr=-Ą8w" ڮJo uZ^-Όć<+XkPv|B>Y?Y]?s0h7dBy o>MMjab.=6@_L@uỶo.UBlׯ~ fA0bG|nb-;`&wc1_v8 H_Uw5;ɟaakmuwdop.:V;`em拯hON~W~kdc?;N [+wuIYWp aB+'uq~Ngh _|b_)6$_+#'$AlXq:0i6ɥ+I'oMd`ύ)'t;0O֧A{|q=^| '?$g}.OǮI-'$+f|4l<nEWF6}r3C;`؝6;17VF?ok'clm~QY+WY9ym%:g{o@-,?듑WxcZ>JqbcB$:Mـc"GWvm#1{t0&V?_xٟ̳aka/mޟcg:~٣8vӡvvhtx]9Xp"89TN,turf9Y,԰hHڪ+63/1ykay$ XSKA!CgD,'Mܢ.ɖt81"|(+. /@s =Tmx~ ?uBO`.fm/ibX}x=~J>Y&iiFg8m)Hp+:M?0|Kz>~KȰXoA0wӾFÇvvr -tz/+Mϝ7,OfOMT~IE7OS+B;Y'Fy8oTw%o@8ן睘8]vP,nWONG=E8di?&a^ZL~Nrf*gù]>z)Xy0[ہ:C{pkXkۿmxvRNzU,g>狽OS2FH\peρv%swdn?Ճ'}F?>f Yb|CGSyk-B Ȇtz'ao+acEIG0'.V#* ý簝Y*"NM6[m{,a8;? Gތ^çlw`Oc&<ɏ-\T_//Qpc(q\gٳlƿ{P*]~A44~] ŕ8 iS:u;`rﯶao/)l IDAT!> f?}mxl_?l/v[/_g"N a銢4jr֕uzgcs;K=YLUIt;ɐZ|,> :x7hww07߈dx)~`]eLS2scv勁k`C?6$LÂ\_a-G;G+|bӯ{<9)7^rb b-h/G&Cp|ciW>]͗avJ\Pӛ]Cg||iGGbԝ8c-[-K-a(綿l-Yy:>}D)|)EהAV]ÛtmqqY?!n$Chg{esrzbOκ`͵u}p.m6ln'3{1G<:-cWv#l4$W,QLdחrNhNxR,Vc$/{WrDuloeS;S4+t:LaХ<F -d=Gx➆i<%4W2F*V{ڬ07Gkf>AMGg!>gMN QGjw|m#-um6Ac s r;p&Idh[oH#LxGK٤}ؗ?Bn~FPr_r:`|K$3tyNfo&^ Cro06ݽX婈[ ,=`5xI3$.|ZG{)^tw ڼ:n'^"QFv`V ɰ׷)E&vo[M+ogAL-ö']?wUν2?itgG 鯹$}L8Gf{koIL.9><_ӫ hA%Ym~?\HY?ʿP^+.ɫxb}}MR;&mۄ->IUdd3,FTv۽?booKU2zbc"hѲ]?x{?rqwjZ?+mwyOݵr0omnl|HZ_|a)}|FM/~֖e/,ϛ:A5mrGGlGeffJlY&wR^pUdmϭ㻾xN?}?Q8UKSQ_ߖ Tya2}St6ᵓ9x*׿/6 CL6lAFUm o_9c?񂯸2j^.p|o)8nU dW;/]ͼa .~Kѽti8'8mC;t,vq#Lu*M lyxyw8h?%n'&O~WIa`tFr'WQg8?GfhOS,c8lO O>92e̙TIE|ox5x5Z;/PT>QXX8^XI]Wo k>PU-X qwT-񙏷C6?UBR8%FvB,}(+*:L&':'r8"$ER~eUQPV3Sg2g`oRDj؞{氝!-xwlJΗ_uzӨkK:XWS3` xћq~ml hܑp 1,ڕ7]d-;)>vW=X*uOI8$ΏӉOڳomNqm20h6ƦH|f`=L_ЃM&C:f&GG^$mqvW7=]aٸDvqp]{Ij?"g44z0j_?#$!Z1{ ;fgm Z?;̵qe=[ѵD_&>7aFֈMՓYs oװmq5uQO'gb— 7>5v f>GaGy{d*W/GL8^U vo40`+^FUz&GoISAW8l>SI [?sP00Dq$,D?G??֤wհؙ_廧o.4^ް~͗eemeQbB;K X0;ٶcɠQl9$[[&>PfύA&d%Q'?;P6L*P&QMɁggbu&}mc*b"ݗ}Mˡ_}OF6}bkgo:-w?9j L@o&t)l&l8?7ϔL_q+N`,n~F^\g/ĕ˅F1_\^?1]1d/>]Qlt#QT]mk#G'Vwve13]e+^;W jWY%֊߆E~_'WGn4_~-0gZOP=q3Xth?ewN~'ayvw(̫}Od^ b~'Ezor9Gw/q=b/;86ZOɛ]Y_fkw,8}|8݉_h޾P}Gs>c V]ĎϿ7E,zژZS$*Ψvӳmcw$N㵀ѱ%p4%9 &7o9r"߼_$E ]ܕ!xU*xABکA6!m18㔗'L9ހCtZq /o}Ǔ܄g. c`]v۩Ka9cxkO&ۤXfUv^ޫQ=}_btL>?z6IiNo=A;yt0Qv0S.n}ݚ%qMѡb}c艳~,5{K8{$g?-xt2Zݒ0mŖ& ۦj$V}^|TA %}ܖ h U/F7!4nv},y/cfd۷Z_t!/Fb,m_mg󞅗[kuyn>چx0ۉ6p_d1$籝 *?Neզh#}wj삟Yq2dާ;rYbdoRE?~ Wkp:iEOW*Gpۛ?#y& :|h]di~Z~ʰ+x?|*~S`V~f}I} kL_x\]ί^p1|gwteKˮrm#9{;&7b.Oqm<IJڳUp|}t 0r ;fNk L+'<r|'I=~if ki{h:rO4̒nkt577srϮ^]z/7/ײm5FaWq\>ϕ>N[Bxga fw$E|_ȺB-]ܻKr{:$~"YM'y2e'.^Aqҁd@O)мd|^|sA ;Pv}>'4Z2ۇ9۫tqg4?5,G/~6f`On“ ,rAO:HpMD7?vJ/}S}}⨽m-PA6|w22n9x*vn+o9I᷾ ɚkծl7>p/a?aƶ7|}\pZ<J?cdENșǏ>h[P9{ҭ%ioO}Tg3L)5 zNOdXW%f/x(%v% )Uh[PW/Z&`ځmݛUV_;/~K8J 7:1|Pt]|/fu0!9>Za ~dߟ `ؒ߃=^Ol_;M&9Ҿ^RZR`X 0&00J5HgUs9G] &l[* ,՗?{sMjbwUQݖvX;"cG}1CGˮkfdnp2{䯢ٓ~>AhCS,4v.< 6\o{yV0I8.V)v4AsAF?w%.O% _b#]M??mX;ڛ^\'nb[ϔ; ^$"{ k,ᙏhNNm]LJ[F^#'vŏJ `X_un6oS]݋ p|;z܊sw%|9w)bn]LԹ| MeI}://n6M#5޾KYח__/Qf";}wb/o?4M .:+Ջ7=oϬH4B [ɫ|?Um'ѳ2oY|5>xp l>/n۶lZ=ظGb+7|}(S>o6׿ Kzٸ?-Hӳb3k&b -/;0ڝ:ݤ~ǻ6/NݫکѢ'P0rh0诫ϼu$Ku:H%6O)ߖWmbovH*']>&_͕ڶ'|ڭH`qJ=% EMbn~stۉtbvU;9{do?9q6zCo/(8:p( ;iri _>/+7|m03}PGM~{W٧/@4k{խ㵏vW+yi;!IW :sLszr~/a H} ='{|9~vœ|#mlOul0 0{ԙϫ]7߹w$هχOCpOӏ ;ӟ rtI>= 0‡y}/o,{`ml0oxH`F?^ذ6͖|v-McrMV -<>0r"i(?^Ӎ>7n#v/ʇ8!p43+&3[4H 裲v| ~_I9WF l6R6kmdʓ7??T;2}쑱:: ~}7QaﷱG2=6fѷ%?4mhÀjS}gW371jw]!K<Ta~1;k4Ѳݣ {JqHßuդrNlbowxkhel -\#6Ðmwt-?_O1_Pۨ+/vBzeFٹۄ ZI߽+'0 Cz-sX =O.?r"g'Zat/dۉӗR6՝.'W?;9t3wb(;w||wr\<[j>z~J_6}K"j" IDATn3f4O}鏟|9#/ס8?կw F<,#kwb$^b?!Ϣk#2~ar,{9$w-Wg[^S`=}#W7n-="Bm-'σd%a3`._[z2:e׭UߚWVs94ڰO~axg#-MQ볰#}h̳{ ;N:qAGt$Ә{-;q찛.զrS,Wuen7ПE#Opn\yؼq?vDSW _`T~g!yAMM暨&;7/"fcX- qi|q Q@ǚ $lk!d"IޛuQȶ/ }3D? IA`ޑt )zqe1=> *A$a2֨Vt/`E[8vv)wtDkrl<>&gϳk!~&L|X^81.xOʣ߂o g"6}Q|"@+lNp/[WO@Mhzb30H܉¤Z'86){E͟O{R6>n7q=%m{mvd-F^Z,.~ 'x^,Ueo'ҹ{u[r^]U3_u>& 3¨/'{7y!w[bwrF]{R~أd׎qjFvW}g&& 5bi?$3*+;Oos9ϧ~}Qcm1,{d5Z2 J{a{W7tanuwŝpC~|&\| km~tq; Ѿ8]ܶ9-Xxc.VVqÛF~6^Q'.~ࣅ\*'"i s#ƍVHb%MhyXz(/᳿,}b/'bRp|0;W7+N~M&0gb̝m?4 [8mמ[7~F|/{7Zbq?qE]{Kƶڞ\tBub{W6(c|+£\O??}0 stz+w'oLm$WQ|mtOY1c8EY$}vmsգiT,_b[«w <#F ۫݁GfUx'yqw~}ҸgQv}_uw2t<B r'O^_ j]p'}lHH,;ޓh k'F0$s'w1YNԹ }jtju i%)X }}\E{u{u߉C'\ L"8v@{QE6v{ Q:8n4nBr|J&]%{漶3?ݳ$&=IiPIg0b_O~&Q +/1}mryo dgb?w'^rH赻$xwʞEt"{XwgII~ 5)~y}NZ.&.a|^e[U#đ~; v$6Y쯞\HDM+o,=\~|bD3o^tG2 =FBtW^ꇽ>ھuoY}_ù/mkz1u`*ܐZkv [&|56zO,~ݩlYw yY(ӂt}Gitn}k[Lfȇ_~ TW?E-l}6]SxvD&xmB1G[,: Vxm].I;Xb p~6L΀J301mBc[grפx}evU<7È=0M]IO9NEƂk9Ծ O8&xkFn8&o:>8e&]<:f#ɞ~!x']KrGMk<8uWVF8=vӪn&_t"^n݂e>;:v7DczyqoAk&[=g;mcf&H +{L"D[ܵaO=0Ǿ\B vJҥ{Xy)߂nB`v~Eڄp>}0r; `^Ϻ{'0 hw_&' 8ߞ6DY^;rSQk2rC:}vo+>1|3&*>ɜ\ '|K  0fDO\:7 裻)> )ц]5f(]]4|;MY:>9JG?tÃ|Quww^'x6·=Dŭ`nzGpvraDѢgWաɍ12 .~̀_L~ql!Ks}>8g_s^Ã}Om+`ɋ'=Rم0~ʜ=[ZGζm2a;#NucbbұGu:Öꌗ8϶d!?& IGI|.n?O|~xmp_q"+쏮/Cq#{-oJ_olԯήz) 4 B2#=pG0\`vP0 㵁SYĤ6;wm[Dv WⱎW .k_^T^VzzHzw' x SY@-uU$/WH99ʖX%a"!DK>è2YtpzlJ-j6HVH+d' 16IJbW~[|t,J2}i#vd!~xdW06̫/n0MHp)yڢmWV o1;V:ecN\YFyDGcB3/N4#677)zI8<KbmwJ}:ߤmt:Nӕ6ڑK6K0OֱDaG1vyj<9닏=K-&w+7\@p\ޚL^j4Ld8)>x'VdrAge˹b*'vW%͖bvtFG_I3}?{;t;ѦL/z;:7=ymć +hޤVWt$E0Ҹn{n-z|Ds'ϮP}GkͿ [H"6͖X- 4r;8H}ő퍅M ]!,s"wx>0Axq0wSB[GaacnN?xIőD?w {j;>w.ky)aŀ8k;Qj_v;^>Y,'z:!̓߱ϧwT]t`>x ]pVx?ufWbU=_;Lo8?XcK9r (DvS);c4&E]9&h qX3u1+;<w)}Н%tk|"C-Ռ1xاxb>ыb!7Ōw D,מ b&'| #!6@mg~|T1}qes2V|~@総RV\G886<.6Dpeӱ2:xL`8Sa[dH0}_cWXb`q~<{ i5dˁ&;LDŽRR(g{ڲROj.\+u]?>ɞ~\Gx6;XdMVd-}ʉp"1V|86cC +cD}L`!c,>m:$^ƒMIwA/zƣW m{ȳp!_E3?#+tڥd/XNg[T0Trtxəw'dR>dφgڂ*MnDR[*,Ζk\Ye/LK4lM6?bmJ7S'҅=U4۹ v@ng?{~.ݟ 39^N9b1ϻ7A$.&:][o_g&߬i$6|B<ȷեN"j)O:>'NW( Nک}6nN&,N˕)G gtY_\jcN_~d{5k} h{8][mz^Q񸸆N F{٤ ~τʲ#f}o`$mNЌQ3|{c( - uxM0'|qv+TC?`aN%Q"dY#p\  9auʧs %k9a›23DN5pnKZɐta 2i\Dv4x2` _{Ꚙj =<&'~Wq8l3N):i >:dUOzƒ.v>OEr;_58"_$`{mѦM=_ak7;~~I8y pJ6=yOÃD6:qG֋m&\W'e;!䆿vѶm?O>;.!L 7/H`JֶcӇ=*]Qycy%88_^?_Ῐ;ablm;KnW@D&Ի5>>rŨ8^[߳N1 Yj3ݡxa'Ó`{:zOyۨeϦG\z; Mq>m}р=|f?wU~43+@s2*~#hNGXl{CHՀ{6/+U} fNH"R! IDAT_s T>@-uWHYߏOl? xtV[6މ7Sk"/kdZ} KapbI☟ToJzY|vhbb U>ܗYNd-j35uLΰmK2KᦏTF2hme J_g}0[|o;᧪6qϋ_E?;N||COoJ&fKq!mGbat0ov'>~N<\"u jCW[8kNm6NwwU6>YUhC_?^G|\?8!X.^:}6d@?g#Z칈g-=sy|V&ȓw0~N7ŏnؚ/ɱ\ {ytKCa oڑ^^F:$s`1o<5Ϟ HǷ]W;\⩯{'׌?RݙB9<~p}bf_ "=ȩr#իHBmWɊF0_;v_ڡi/BlקwWOq6I?}y'JPӳQ4h ;A.7OK%RAB2~@1#6em`+g@{xI$Ld袍щP@|b,l,$>--٠\L|Lf zP d2*Cԋ$tTtI(9ɉ9跤7awD>/t-Xծ?v`Ѩ0?lUI]\2ߢdDL] טZdb89U&Nlfp49 V֠I o9{ >?,mawC}>d?z\˪Z%U C*<-tukg}b N_% yc>2E+G V1_߯=ٖL66}K6QsҦv r?:ht&s).'}Ѝ yH|Nmkw*|~3}lMء1|%wǛ7?'ӄrk bwsz;>=m9EكQ{(i"9̧{B#qb~[C'0aux$w>cx#N<EwyjL},h1i[h{ &Nd잘 }#H1Bse. *&#z :XO&Mm;R\b%Q={Oˢ\?IOI#-0?71+2Y<_Hxޛ"[nl;~َ^Eسgy߄_Mw9*A~B_W]4ɖ?rD9!?X+] 'Qy(~aظ~Q G4n&igKws,mHgWGG'Ű~<`[r<## ^:++|dM#&+>Obٞw]7˙O7H/05SN 1ڶ]輠;EG' ?F> G0|3dLL2x,8OҬl3Dgϟ`Eg #9 c/ \ dtm AaUtT#X_B`@3{{6I+=lcm"qneA~x%c4n}wlp_1 1ҾڧCfjxgt^6mxwC^r] ?).lJl #sl㭿F OA:}ȭ*ɱМ~wCa/w²b_>}1J|Y޸(>AoNu=wqM'OB`;=o{lbkXI9}[=D޵g6 '㴲tC鷆BӴ X,7v':LNM/<4v,^}8 No&' kǷvn"uֆL:Ÿ.fcGಡe +N񉘄>/ѽ xNۼ&KZT~gV$-6orןfslg kz: :=}9?-oؖ6dZeEt\?2s>t>Ґ%ǖ 9#CjD{wR@1ڽm~hjL`jmEu|WA >P&"q jmd.v14@r`~~9ŸIO/1s}d=d[ģvGclo[߉V]~ 6!DW*z9C{&졏x# h,r鴷Bo2Hli|;1K XPg=Y[}g j濵;w:3_ImLj?&hI.\w׶;I^jA'?m3^lDKMtO OM?Ƶ>q9obL\9ዾL6r4.Lldq25]Ͻs|7֖De|g6%wUٙONJvvmps8|p9.3㑇 װg]_Ov$qY8?k m:~]yۤ?,$>._0̟lO}7LgzV3b|wԽ3l?7Mi @n-ۯxO]maDNHl&D/,'H~m'.b?o,9kRLfs⫍xA ,Fglgz~%_.$"nQ}uz.]Fٓvj i?AjcD7T˝4˶CN凭^O_,Ά8 lt=ۚF%4/O+߸0|HNLJO>,棝~^leKc:~rGoH8^/-"ToIeW jCY/1[ə^O"U9RSd{\='{,C;};c '.st7 G ݙV:ksXǫ$oK/U,\9_vU Cy;}B`vƨÖe9/_sk/Nx %@CBI &>ztI^Ӗ\G=1UQ._ <њLy{\`W}N\2™\~UаcmDO3~wctÿ]Çx_xӃ^ӤN'?Ԇ{-,Y†)|gj v=?{٨ش/>WD|.d1g+;=.ij}M k[| -h0dCK S9N;r_b豅gϾOɞk|r rEFߓox"Nӡvhu'[u'ty@7f01:} Y/]-d#/x҃>{tv?km\}oVw,%yZ).DŽhi}'o/bk+߼'#$ w2oѾ'B fOr+rlDYp~/Fv6rJLW.nlƄӀ|-mdi[M#Ve?_<>/rv2w1i} m왼靿oBpB~zO\|r/.G_9Jsw\L>gu#'^jz]†+z0K^q4:v[^_s2$hWd~dRNjam%_ϖÎM/3} Ax0Y*7>؝\,*X۱h x|6Fk~؅Ƈދq7GiM.'n {]6 jP5O,/FP'p}fP}([# ] L/9?oQ5ͬ-Mʇ00P:uSDw`} IDAT|?tu 6O28d_dN%kMUty죄;~k+pMr /s;i~擨C?qkfz#{f|I{dp|.^ֆX%\l p3`h$klz;[ۉ/7z/"mmv; _.~h 00O\Pb,ɩİ J6WDP;IgVj? 6[FȮLlc6Qg͔*A0lqև{D>N F3w7h-^cEkөx1}GNPtN|V;7IޏfOgT=;9ɯx0 8'7Y equ{vY{'X k9(4|n"dI}y)-Ioݚ_+(j7ľc8>Xpܦ?o,}󻚿Rnip/S6qwrB8,f;;,[s9 r0\NknQ0;"-j<g}G_/n~{<5Ax *%G lw'#door!8X"wvBmxT8fd)鳼 Dƌ%kܹdxG[οALFe[L&O|[$/AKb#_&+4Jhk)cl?]=xy;NIZMzЯ?qq>]<=C%.R狋j-ίxԧz@N;nZ=?/gs'f_< kE: X`hRހ&![Ykwz''4^F[ym)\fml^ ^r >n4ٸaܰ( 8(`$0]`U]qmW1.E!f}vW/|8XxUx,ڴAjm~%0zEïho{4V}ư5a#t%q>omχ OuIN3ex*(55Cg,AE 8g\χmOliLܞ Enm?Rb9î+"$|(E>P5 g󰉷+)w"Q{lOsT!rCx7)FS=.cr|&d8\^.5KƪXt>+pEG_>+?mۆk':1}`C<[:U۰P !;Ϡ=FW}c|jG|VM#y YPqTl|GkW=>v.ƈ_] mqP;_\G2ޫɌ6z⡯cOeᏠ]#Llqdі-jww o ᫟^Up#/Qxd&k!}0ŃNYW?6ԬXTyxjw4ȗ6n-,̹q*\{O-xn\&]'uЬOL&5>0r|lj7B㾮&yNZ Ӌve8qca#ݸO=vѣ #qCsx(YeG1ۜ(~4pBMy}/@Ϟv~y`O}}/}9@clx_e뫵|vǰSg]ߟ.i @oئ[6kk{;3zxC:=&)8MBݙ%%'y  &[iSQM'K%:r,'׋K'9r65Ū8}\~n!oLa,P KH ^ʨRdY7ӏ?}m-ck?z˨ߟ{E}կ?\v O~xtf?D7p]%|uMt {1-ޖP^ppr˶Zɾ w]L ߂OyĻ>myQgLȾIo$n1S- e}(VdW=&d//@ hlnώ>۞d>GWؐ'֏4j`Upw&nPEMS0N0 V=`؛]b|%nv×]N cWF|ZIa]l_F|ߋ~|-\Q58) ǗllI-'{M1MM*#k;jeڲ]_{1$7AOzG2zS9Wp7> /~W|{x6ihW4y0UYݮMKiXaLgu@}[{ 'عxHߎN/'ObB)'7s9f1!ƌl{v ܪKMp6{}qb=-H2MbųN/{^]̬a4)e~=,֧z/b/iBdP}~h|v,qsxOG'iwv~ ݧ}}`4Dח=^x9]6f`¯vw0v:x{=_iln]qn{^,_3xd1널^ބm˧{"dYO?둢>c۫s.Élofc<޻i\WN?᭍]Eq8|@~1pֿ(1E] :6;%{IMNXN[Ng.K?cIm3|ai +;YLg/+KcΉ^)q;b-t;A_ϗNϕlIa8[|Bh+DӶϞ}1^_f3ʳcn03Q27IRdvA~X02v7'KeY]D-؝|n'"jlz ?_Ǯֵv27u)I J"}F&lF+SV19NWILt0,G];eV0Pq^ON\.8a?Ƿ%?z'hsd6V6$w(Gpï[?/ˇ'އ1/Ȅŵ=_~[Kj<_EǕ;wB鑳2} '.&,bvF5:[kivvl:j.}+ v%*m_i͑A,h4l^m1hIj,@_N:7Y^9fN#==ֆt˙7wӿ\q9~ qT l[ϷYq9m=]X'_Kϯ?1Er"Y[ !<bg?*/זD_K'h=^xb9ŃaXEt'`&OqBtXJ?oy =YM>Ced|م=5TOו?QEW{\9Zzܶ3zAI%։%D#kbJxbkz"{:ka`P&C@16s _'h¾I9Di'wbC"DH.ے=ѳu^]h8ϳ&oKy K?aR$CwL1n!6~'Uoo1tD29ճe^ۮ3)? .|ٶ"Kmd 7)=r4ˆh<6t77)wpgA׏u0q$ӣ-wwoM'huhnd|뿛72+;ƏX+cp?<.o+LחKү|061xa tak2잌+oA?!cA;hl\,ѩ?܉󮔣[?t%@M{0뎎b/ZNIߛ™}[ G?◱i!+>0j2,Ty xy=8$V.6vo{hק<3ܘ0j]$p:A<1:#{Mf?{,Y귓 =ws+DEY;{92[Mo5Ma,.e|tϙ>%^i,%{'g8ۖ<>{ЧmqWC_Znce,wNMÒxˇ8c?]}:'M^14"߂{j/^fup}뇫At-(/ WeϞ^ϼ Qu^x;Rۧh2bVpḓc'k1!/ubݼGlI|sG? r;w^<`I-`yg}M89 ?k6ԳԖߨiwzYY-PT,F^z}W owT}Q<CséQmN{L}gpA"%{+i?,6{9{;tt΁(ؿ~\9;6o6>l:AEnM [TTGl ?=&~ofjg|y.ӱ52}EީU1zm|IM7ć9Z3ڬX H,|?Doo0pm3&\64HٱosS :q>}Ɔtglz7ہhri!1ꮍ}/fhu{b}R<}Z-N:ίo8r~e{%9Ɖ%+/,o3؇WۮѱjNT/< }o7[ ]\10CmY koO &$kq˶G%G:d>t`l 9P|!o2*f7tݭ dl.]gԗAɋ5L 3:?7p )G&$^rO?X;}#>sa1n߷@f#t0| r~]8x=hL%zr黏c)P|P{U/:@/g'{vh51c>߉O IDATNalX~t#ϒ-Ȯ/$D"3IF=jU* |*4#MIRښEI&If&HD~#~9k7ޜÍH%'[Xfх'o7ox=: N%e7'p|lqf]̀'J_~;mfD#U/Nc;Wo-;^h&)ؑϠtC{VإW^<#8Bg]ݶrܫ'WvJǤ4l [vؤkv{s&I2x쀭!{!v7 cmגcez{z ֡O8o &lU&!Ir?<~yyFQ—n񝻖&WM4_ 9}(ݬWg"~qr}G<k`o4}o_y}7ǛN4>?F"m:A)?OWֵi<4b>/mvI>dCnbc~Xj2{m9m7}0Bom 5x3;?ޞ//eWrR_Hs|}X}*˞lo{Cnb6m3C޹>o|a φӢ IVt|SӾ+~zdgoy{D ⬉IO1#; 6TNkdJϾ[\+ }{iʢb/yX`kF]rw1Wc4|{4Ӈo0?>&t!Δ|ʟ|l'MǛm y4Mv@>M7QK}l169k9(.?m{q U٬۾32%PV+ #df*w;~䧻Wp̞3be;n (p B^"]bΥϣ[=;=CֶIY=;mH$_ zq# CW=+G~zvmlh6袝n>$~c?#,.g5XG"6NM]!u\|©|I3{4;B o./[Is;PÖ+; u+ Ug C)J~݄TWWk,w[d M?=tx`cۻϢ+n*Zg5#u\,t/NޕeFO<'h|~tZ~06'+?^ilV^I ON UAIm|j۵ՉJ/'Wr2v>'֮_<+n?}wq2g&8 CX\ȆY>譋Ǯ~}49g^Y}ٜOܦSǿUzzل\z3đ %CBo"G&B =kGL͞`*nm :ݢ7;Etœ':W~Wu 7n~Ŏѣ;c#ݤtcOx9~td-iAT.%^MҎήP `WldFcA/qOgxx:o~6bhPshw!K y~TZx"ML7XfO&p: Se3yX[i?|نlriy-2)CoqEʽޤor%owdks!϶.(=m*k&M~Mތ#iBIxpd%V'@8tpO[lµ\b;)=S|Q7')|f{D5#:ߋʍwEFq_._CYxS"3A7vJSnxc{e.}4*b tO˷{X48(Bx`وՉdZN,9=ɵ^̙;>vx_}NjnLapm@{m? dOqP$S{49kZSc]w? 2lH}D;[X秓/.>.̻3H{p_$pF;5#v)UpH؇1;Ó!Aw[]ت(pK2L 5apo fvÂolx4UV^f 4G}\<(yǛ|mtZg1E f QY8:ALF],6q‚t},a[4΃u&]8{Ng2T1yA^sH?i-U68UGuFNjqވ vL.x/G>6}#B-]H]gtkh /t6!R|n]6 _ʏ#E'@W>cg>G/$ː%Vq_;lՍCkUC LƎ;s&:$fG>vr%WWy:u@*_*Zl7֯'OT'ǛSt0xjw17h[t‡̳ig7bת&lAN y% j\x.'Yar=qA' gG+L\yl&F:>`gA˂^+{}=zNp+';}.69v1+9v qxp$ r/ކwlse4?Egw'Ye'^d֢|{o#gOʧ#ZbE#Hv}t j+ʾOrkG/N(K?k/e<߼wpk{iM%ǰg~}4M2T~6jp/_L;$rB6y&{ ks|xGq<'v%P&X{bd9&o*Gcnqh_&my=a1-_E 2ƕӯnp,mC>+h mrǯ~7~7>6H2"5Ek *o҄klabxMpå:cCU|'NjP}@G||f!y 0Z4ݓqn^㓵|BN_}mU+:h'Myw8(~LPֶtU i/SQ&4;'_3bJߠ~;$}UREұI8/{eyz=䰏ZYa1Kd;[7]~w>FvՇ|'wRXE/Ϗ,(H%at]1N6QfCͣq?&dp]K #?Xu#l'pKg4&8ܨb_\]>6$o{?pJVN %E xzrm!K@/t;18]Vi3. w6F{WW:){NXQࡏ6ѕD,Hw ctH\"%+ytx`qJ tIC'ÇX ^ҏ5c0 n p @opxA~K09e|l^H$QNdtp' '; ]iP W2 ^C :PEd~ &ϘR$GF{0#:^ћk ~τ?6!6³M~>`b٘?cAIDo vWz~]ztCw+>ډ *c%6 ==҉>r:^uK\c>!cM+LhiJ};<}`|-vShDcǁG1Io~>`EN6o.~zhMPGpn)WG%[zښx{V#N dv/:S|vw,7\nדuӃ~wz & wN.vP;|BFl&l ?G'dvޟ<Y\tGa2V;={hז9Kt|>\<{I|Mvr0nwDnGl|v?҅ NGro[V/~I UpApwG+t> ,_ vvN-@ܓGM6t1]=BT$S6qd})6Ȥ\ޚ H=`.yL w,oS4dged 4oOp>Sl1fw>ݘ?8>mvg Jamm&w$vW}q m!:&Uŕ)tcγO]tG(W2sy> Z n׎\bْ\@N61*O~1@NP 9*XǗ#-Oͧ>mor^0]= v7φŢdvƗO^Oqh~{G:wܝM-xml&>?za<.j[/d[Ūv2af ˣ,|![DO}aJ>$M:NX4-l0: wdpKClS](>ketz(~gS~LO?uK2;^G_bz'vjl0@G4W;\m>gCqXy.ӈD|lՈ),8_L:ecYB!'[&Ǫ #yIQ@64 ~m{Eb6m~]{:_2.17a#v`N֡wx~H=M;xg1b#kztv6pg{v>Zzxq+G+єG:>|+cPSݠГW!WɅ3X2Atч31Qm6Wbmhw+' b .*cףaNJK[&:%#T]G>[3: va7>-}*/L7[̭ vX[X=F ;1yOΫ?Տ6UO.VwI|W|h xK4emL6ZBx} {M&-؁MY=軻TG tO|G>piuM\|5՘3B^%PG+{N xix7kWH5ՙԖ39} l8%/)yLDHh⨓ Oٱqdϯ!wC61,#ik|u#g?l ^I׺z+M0gjGOxh/"kD'#+3@/ߍ`9һ1:f]Dί6x!EV6 Lm⓭>χ_T-ԝ|_&c<(o\}[eyd3w8g}<7]y^oӆ wx~{']:NvgV7sl7%OڛoqdbewD#_.-&SFj6;]:X㝨/Լ9WsY,ă\k'aqzGwjsVwm\.ѸkS6ڴb{*/}>n 3]J$[2>]`ٖOAt0!Xa{|"$n?=7Hؼ>!;N>pZVh/뮎,(N w:0L൹B,]N&G%w6M?]cs$AH f ߁||޹!_{9"xh+_<8{[:ӫ4ϡd:͔1cJ1K,F{}_-ؑ W%}րM! @{nʛh Ơ^ 2Gm@v}9 \r`zgq;؇>cIFbHd?5&-i % 8 ׯBA01 /l"=[ |ؕWft.Ff<֔a ߬ t wG#L?ijO[\7&#>/Nɗ̝(\!C{r )Dʷ;;߬}dtꍉ"y ЧE6+:U?.l/j Xd"f'~&WeW\:N6!jmX:*=[!Suw{"ft3@=L8 IDAT8+x÷̿s^yQϾF_oY/.MW#9?|ͧ?Xn[3tqLj:'t#Frw)v}=79Zx6C|==~Z{ti`lMzl{Ŀmq29eqwm|O?g1p;%M'lGLNےQ_1{ } zFn9Q tecvbg*K}]/#D ѯ~y޸:֕g/;Nvr){w̧3101cճp չ\>2=m޿~ I`.knW=_]c,;]0-DZ,lɞ\gMpή?tesW1o:'/o(_F=G] }mڤs}C4ͦ6#GGNW茕C_w!-.-Lf:51Ej߸/lDLtcw~_k{nɑol?{.2ѨO~7ۤ7Z_6ݍ+X~OIu#Mw UW'vU7˕PHwLy9/bkpc*g9R8$ 唉Qu MrdX:8%րѿM_2.Ӳcq6cj_M6 ރ? ?x >y|x^95QھI z8{ϫ|uKn[a>E$>|Ix;O$Hlg3b%(t&m8ދ֖arW39Jklx.$mC>վP%:0>lAkGGd&g;߭#|}'{4Wn^)9 BߖgQF^\Z/c󱍿U~J'_?8zï錷h/n|x,.1Vx2xx'mẺjےqx:Nѓlu+NV;!Wꥂ ?=uP 7u GGuBxDG վ]e86 dHvYf} ]<|NWoEf:*mxb&?j0ߌCL iX 4QC|7&_i> p{A?zr)->N0646*fW]QЁ,?s,:i>+"x.Z&.2;:B0٘ѿ1gEsWafʾAџp~>,޳Q$Y2;3b犲=fq?7t0^p9AH10F`|/.'X/Jbrdn-nm5jR76Q/|ۤlx壽QMw4OzqScw࿜_T ] wAecW{c UoB~aώ3 n>8ޛtY !g<渌Iv |LyHvrNBG~ޡ.H?lfcx~h`H}A~[Wy#r _1Uٮ0?[(dg'y{^A78݁zɥ$ }S/l#:Uǿb yu:ބڢнE)d]<t":Tʉ_EO*0W [@2i]S7{f勍:6q#Bȣz#$|yqKh"H1{m5xN|tl :<}er[㉉i?2Rxo_.P輰εI9ѳ8v{p@-uA>t)bLJ'<~WٔR7M'iW% !k03([PDp: 3;\e13A˵=I3J6s()'%j Z̆YvOGZ_"X5n,@x} /zDD>`\8m):wƮ'wnЗLt {B:L~DѶ=ٲ5 vSs:o56zY [f m0?{gjuA M3QKQ~ow|F?2m̟w9ыOdYg*(ڳGs$ -lØlg?f*#e^K7ַ%x~{xcB84~u:{ 7Lۋ*#l4\DNA'hLU`y%,q0HWVӡzlNS]'ZZnζ[gCA*R괯ʡvb0!WMWSl/nR|*=9xF#vgY:|]} ?T?[҇_=uq>?X-y߇ |ί(hMW<y^6jnE'&+[_PA'h>N7W'.?rtP8c*qw^\˧~svVhj{3&6njGr.8r)7xϻ*0>dXot|l}6]ܼ6]9[,woO*mc9>]U㷾3E³]XOq~4Q% !39Y\Nɦy']m''gUax{qwL71슯|&<< p·'?Vimh! VN]Jw!r#l&nի{M_\b6e49_*;'_" {Lf|)Ƈ=XZ -FOmk5k;;ބv%Txq#'/K'ߑ7ݍH cqt>{bX<4pM㿍=¿mWR2>oH}/V-P(#/?j:SfS]bɗm!XNiSǹEǕOf0! Al 9pU&g 0(1Vi&!\%p|lFmL\~f)z dl&9x~86%scc4??[5,Qf/N؄SF. ȏctiD~Ĺ?t(hqȸ[I*-k`'z9t;"ݗU@pbn3={`χӹCǟhU ~FnqTA!MIuՎQ{Lv-]A {|2}VhdK<%x1w%2ɖlnjמ4bp6ɻjq/ytO^߄y1 qfg˶ ?/9?b s,_-ɸ;>uS/8ѝlJdZgZ]2Ycg+)\pw3/%2NǨo.ܭ^>#99>2qwN {8 +Yl_li/||F1;ÏӆbD-^۟tц{,oࣽݺjgqzdH|g"2_O>'Q^ ^cq:}~5A!`6y,P/*/|CO_yh1l+;kH^ﯽz]~Cn:WGԎ%)+ q,5K~Uh`*מk R,o2<׎Ц5 M0hI Fզ;_=0L8`|4͢ Gfgqa3g/{b9^['4.?VOWkxmn "~﵋->;,fuV\\/-)>"W>st㠞ϲh`H'Yf|fDQ*yǚɌDG_Jŵlg3hmϟК.)צ@skZ\n2fd/}Or|G޾kC[cO7\ ı*ߛOoapCGXEo1\_s^0+bB::F2k)f6'ٙ[_ЯAkbqHFdb%6IyU?Z܂nb1H ?lo?:< &̝;OH9鬬۪!+[.-kËC?G$M bO8GH'2W;*a35 A0ƫ UAm3ݜ)}%1%#|wMЦz b4.'$H{BuݕV9=Bs_4򁁳 V_x\#kah`:l $@I?wEn6zH(l[VqrҺnKGEG#Ivة}tƏ~>(gU?xk<ף[T?07TrŒIEq"b=2+l4;}lK%0=g;ȻM1BҰؓ~ :^]!mN٭Nѧtߴ׎OFnmMvCxer(HwU9Dj_^jNBdeGŗ2AϮNU5\4RF0bd|$ikkWN"|m@ӱd#<b]6>_WNWB$Xc&3U@w-Am*`|;ӫbdH0s&iȝ}>h;d taWnF^ɵ#)Tat+ }/o+T1?{4¿Þ g[vKlϠ?WW+o'w6Ot_ M= 6D?s^E{^]^p9X2&.6Ma=?[#ٕn񖏟GAG0صlqb"3 G\I{?9g ew&7A8zcT}yaZCMKo,Xg1 /s[٤ڋ&7zbB>.UsOFo7^0;kO})N-b6ZncTVWtY4o 5 ct0}J\&6,d+orbW2pE 7k<s:)Ddxm/M]]mC^q7[OI? hˏg4SZ{$?GX^'bHc7Fsx${=sD߇?07%MZۣ":'<2Mhx;xͯD\_w18;و+1] ˜ȟW NkK%ϺOqͮLJ&d\՛Lδ|Uw{#?2T41=ַFzh~mqlrD V_c;{(7v'/0'qD^wnX]S%VkxO݊3|>z: ~ >uuPXYDiwdkis^H#Cc\Ϡy,gsE8'N&8L@Ħ&8߉m"[7Q0N.밊h۬=iCdOG%k_cDŜ7q!Wϛ8|L) IDATo*?=K-)f+,9L>Kپ"6䥊1"b@D xΏ&nQ{3Y_z|i};|d|О*;S76T֦>&g[q)n>ÿ\;Znȗ˛Foſ\, ;Fl:{m~ᑐ6_Q<3Sᗿm(<ZLolŝ:,C#vbU$d+e1%rFy"co|ޞd@p# ({r~>Q.6uyv^Ϙ:x&K}nr/5کX>-w\z-Fj;5,(]?ߍ}')^:t%U٧rX6* ~/بr8 >_2HoOP;}=thO6no]L#Թ0 "ƋSqGhU\pu *qY;|ĸ$8G s5$kG |'k,2kлV>xy)=N@$S4^Cٻ$ : lf|r~G=!;i%hv_=>޸08D|ږ%6A~ۆyB8„^gCu !/%#Q]Ge(M`3E ˶}6|6ґ&N@hgG_uE Vݝžpc'ГLA_rEbƒf,uא#-\Gu /[ے-cN >``X/!O$ 1::6srbh үZl":;G:9]bD O%Ϻ# rsF; bik{l\QFQuxNUK.4M>2u>:'+h*.8x~fzr"2~v0M?.N|vNUo-=<{؉cCFW%!&ǴrlS=Y/{~Fv=\aGOF qttPM_f`ӓ V>ʎ69&N-/O2]@0L`q[-2 &2:t7vlcq#ɁWp:;Fp1X#{m[/ٿ'J'mCnEBvI^9nV 6Te:LtN09_ٍ|.9rf  .j66֣kCÆOEWk(o}dݧZ,񷘌bTC4 p4jkUnfU|6/|~B72|ZGg{k<mMkヮl_"ċ; ,xc{㭽{J3&ߪ h2u9y UGBh|+^Ȑ.u)zcL>V|dJ_zp'.=&WNXq1F:N /@yh`^HGoL,P+~_1j Qǹ4 -qxN 1&0ZR `^r} ~ vt yX`d֡R25/lgsw"fpuU9߾?tPG=:ѣ2 @LCmkO5J%Gw[_o7Op;/uB&+4;v79}Ճ#ܢ_,:`s+KÃK&o|N}؎Gf&z@ Dvk{0K>/NhIo|wvI;o_G1ݣ5& S^8~[x۠|>Yk7T\ճՏyn:?Qta~='9xPCgk `l 8TsNGgۀo'/~|vP,_Q}-F,=_x=m@m}=}(*]_;܀0k'm6}w]o@3Ukwn T2y%lBٵe3?RNóǓ 8bS'.fұ\g?9#9ب8Z;^1ƹmq 6iQjo{! ] aοFo>YK'|䥅_&o<6ڝy r;UnQINWrHTz6~2Hsdvp>c46wbBqDٱz/:*GwDOLE M]z,d`c5`3Tv.|o1W*O༱1聢no9)б%~_דsG ^@ɞcp=l,xo2C}ς~զ|̧9_{| Wjc&YebUw(?|eS<Xq9J@*'$Gh 5^`dup-;}У3UH΀aIv(+Dڤj 28_K8qԁ_EM8M^ !& n-;P0*גȡaoGml#[*o6Gl?X }1 6;={@cg,/6%) ]_c7[C` KGCۿ/>^ 8gdY,{%I*o̾t'wc6⧣ߊˣDs:x'+_)vA#E?S&d$ }&'xhNRTvmӃ[dqR ?,{qD5Ew8gZlۋX~be:Nq,} `yvGN*m_,΋Gb:e3Ń΋PQ'cW̵WrTUgXM T:\V/˽;.O+ L2v)kz41QLo~rn*#c+?*,Y]Ucu+7\bDسwO/+lX%fe/2Y|6#pcMjnp Z>w?8o{f_Koݭ2"!>'졲CvB2mCумF\d۷U;-?[mf _9_/5>0e?96Uٲظ&ZGoW *dfx,Ppǯ1R LHx^~(YA$s|̯U\3K{4wH-ԘaIZg6G?G JaDW169qQN7\{aNP\.Dcぽ$k3aBZ-(K=5fjON|>#㙜(v<=;tʫN }| 'YO {LRJ="(/ `_CC1P> ){F{~*AM,p֔n<ʞ |bpr]nzi.G8^ =NX=#c[LlC=[}SOFcp#! ]σ;ߊu*U6nN /뛬sonOp|(QW[c37nDSl}47䳇.ԫ#p<X`T6+[Lx69G)΂]gb_Bnړ7Yt1+kC\g'l4 @ P>I#GEkI[b:>'c?_wuQ]oa1$>I#ӆSmk_7^a %9K*7|*6m=ѱM;>UL,.w2y8oydxq#˵u%I0s<-wܹ0bgな:xMxX2zS;7~G_f'lO-wnLJ=~sh^N=_{)GvㅅOڒxw8Ε{T?zNRKp?۪~t|pq!ɏ׶j1&l])%c}lfe+=X*&SqQܷ0!#`xmk/+[.f6`RAﲉ_[%d W'LϠA$/OXMXJ̶v7E]c:?,6|q=6wzygі(N^5wq$4 wwi ^6\gО3Johm=:F0K!w_̺> Տ=vrmdj்ȸh^fp#vN[7]gז`U4d,T7{/!xT2ʿnQetn/=|GBh/ %1Fә'ބ8Ȭ.+:5XxK j83r~ʆ3pӛܣhPׇMɱ_~C%}GϻZhGW4n1!\2s9O '$NuCFLlgg'?_'aq?)В璡AE6K~+_?Ec6n!a'<_|WV9dܖ YY/hhC؇ UG A;c.}kSk7 vM.&ᤛg/:Ŷ'?{*_f/=dvGrOWx}`#Z{lw]gg"5{Nk6г~F~JI_9B~x%Ϟ񕓒a`w408}V۲ʕ`ppIl4w+^rux){~v4EcJwh3d}sQGH{R˛8d㈐ɣF'O/&p-4tp{s/GaW=ITu+FŞL|:_#t_U2Zoŧןv(u%[|K1}1Lƶ9MKveh#_dQ [m#2xzg`P|m&iu^8 ו*?MSþ?Xx&aJ ֍˭ Cw~6TIw QgWO=| -ݮnnqv98$l#cߩs UnM&\NW}ZJM IDATFPuU| 3[E+^Xb$}Q߿2EJ[+lۇ#uE6ZwhwQq?u,feLxrҗګC#>?,BW\2Ǐx:}Gt¿"$>r;v3;. kq(ҭwV05ѵ-MtoG~v]IY-ZWЋh ]|S^z9~-Pm_̒A,%=f$ άlXeO/7{&gyR)bx>VR桎*B{{~u|#|c:=kߕ]1r ='Ww6J>1/&狣gݷ._?&J "rcg>7 #$ƬQ]Ʊze2<>]>{f\ؠYDy- J+bW7IN ^Đl;fKO`#@k8K =2@(Qmc\L9fI,&߁r8^:?ؾ+⻠TP}aϠa5o *32RXM6@cR]avg'"np]0 4W0y'!]'PhB{x4>GֳcG'.㳲Lt?Dq/ъX3~-bNVq}}8XW2|d#7j#FL4jCPKN/iSgu̳}UDNW{9T\^/ߕ?G򯭽iYmD³%v;O鹜ǏߖuHVȧ7\͕~yWfyUm:2-_̜AB\/وbþ;nЦ&xed::ί`~KНIH^GuᝨC+O?ܕWQ ՛݀HpLw%À#rR3}4fo2Xؾdz%o-)ݝEMޞ1=-q3u:t]NnD]K=6OBZ]4Ekxt(Eؠ}4'V];c ;q=]x| p8@:݈hKg:yt]X19 㸾)O;仾⅏v4\x6fقJ["V6}" |}v'`w9"b=5pC!"[`~_{ח-??v];(z;:,g1Tݻ?_B" ?/Ά$x3(u̇7vJglqE6ӓo2؋+6QߵhbK=6L~$bddA'FEo=P) $'_;=.sh_JeYj}faJtB'gGH1HdwN|_l[ش͏])#Rks/f0;c>S>n\DsK5^4X ;g}'rgr+ )Τ0o/+8uX hlO.lgu:o`I~>xFD~FɸSD/0w2tv4s`\OG%X\2I6dᅡѽ :6Kq8d/4,vW%˛T0#\%(! _9ոu$>rm{d t>=}q L2V Q Gs">&}&7_aiq3C_:0x?{.V'yXYXC#=mxEg"ړg*?t ni?=v8fvUw# ȷhvm\x=VU Vm&wk=/%i&9ivK 2Er-q6LɴI(BK.iF3 *.|ZsgFxrmrd,0t S%&J;®nNjK?}VG/扡D69=V ~|,iYLϽ;Lͪyx">귿orN w0OX*h%73ٶpcrxpU?ȥ÷Ŕqh11viD)XcۼDcpaMq,.2щVelw0Z^[}qN"x7bs4~FΆ˱(a+_ &cq& vCI\L_?O^rl?/]mѧ|.XФ|%EM1^5&U,n,ŗ/\u/[:9í]otpwO}Xz:w[:F7^mp%anP6шv} tz@OoB׿,ovN"pG7-YbY>r$X>,hwC ژwȧNn=%{$lD IA~ß]4$Yh`,,HWBI|^T츻`81!O]2tx'~A`ck {I"'D+b6cxF#YP*JwtwRe'䱸{}08߅'+d OʞOÿohӏ`.8's11؎-̼"ׂ@,< Dʭ8kks="$]a[O>Sj-V#Zn'^$F}L"I>?U6]:؆!CYjBh ݽL< #Of;J4m6sG:y,cwa[o9>b~ -"knHA$~y`v7w⨲b8g{ͽm7n OWs62+=+os.m&SX0K/s;lzkfP-h! O\`ַ]5_e}.Pl|ޘQtOg4zH>b9${3e/l/)t0)Fi3 "1k`TcF IݮӀIӿM2׫,ШO+OOux ѯ3)tpefzr8XgͱFШG/4s8{Ka|IK*}0Kplz 4I;lmW (nQa .x/&D-1us%::&8V~6[ *]w–$2 ٩'}u|þ]9>0c"[l*x0' &mhɆIuGM扴n| jv'+k3Y%dzIU{kdxIbfaϛ4h+‿Ǧ ;SVL}_x}wU}4V#gMmyg~f1 qLd(fTGŏ-.A}3orazD~v[`h}9aelo%FQA>g^t[_[>x̓ݦy&LՋq,L]Vo/y‘z}53{pzZqr&=Yy'H BE5jrIB|L%talQ<}qoϼ}m/`gqmÐjbE.ٵE)Y CwmÇURMa l -N@MvЊa<X߮t5!%kI-_j`aLU_ĿI9~F~q7w_l758I[Myo=}~xbdrֿ|Xk䅲ʎlX˰CU7^y&7铞^2f6n5Ѹ~x|p^?Gpv},rϻ}_|I-\r5o~y76X*>ކ7:qz[/kt“}nUnA&u`{\O/;q^a#Ϩ7k*;0ló2pW*#uĊx9̒y+9#gew[w"]iקƩr^S[ƃmџkO[wBHtGkұq<]3=]W;3q?-ӹEb@_e#=amtѥܹ93۶&J~賥ؗ4<~8a:\]F[Dh +| ''N>L0h٧ a'.jNįo|xaGkk](pkKI$/:`A΍cb6En.az#sH7@@<=Y^zGq)~NZsr>ђxq O٢+22~Drd$$ڕOlzO,eW- |WY#y^ARŬL*h2bN:9Hz?@\ ]h(^04*#hG{aқ)i 3mJMUg'C^TxxcK=X>N ̕XlGlxFV$LW٢S:?O_\#}3#n'kXp5]^ϠK7{闘_2SE6 OGّ>MJü2tOfGq P/kGߏ~p;1_x6nGಗla]FaE~F8 .&xHt_jt';*soԞL6/cT g\ߕ_5ld3zXP-Tl쐸ɪr>A^Z%hm߄dAK=/V7f'Ϻ`n0yvؐ>/FS6d ;m1 vlnrN֤MѲ193k>'ɢh8;1~ ˹d&lغձI]}6zKt59bvSelOzR7k$H^\xlHעmxo7ϿM}Jrt o< ?:'&X>5&S^XYeNw[7:x8|~bƟ| ؿ1yu}^l$rx8ħ9_?8k7ҍ>I !.6&O~ҙ M~ǾMҁ=㸓c Z'7Lƃ1Oj'0.:nnK7NoWҳ 4N$w`HT~N_b'vnDW3ʞ<п藻a4ɹo,XԘ_с5Uצ->Or'p8rcss?,@eMgryڏm0>G{nF~>Zxʥ釗vv%x[jKz/+Yߋ_‡ƶP4}džm%76gu񺘉>/?eboqy {/̣sĬz6o[SfStoq2՟Lut/w}tWFYNUOT86sNMw.nL$_o<|tE坩v}􃰙tcTl쳻ڪ}{q99>t_ʇd__'?QO D(8:pL}z1zȍ~2⣋6>gTs y^V}P'B,;>=jN_}E@?|gG+|{1J^qϯmH;6fp?+#^*69W9ٽ`=>~I{= |x<yKIl|v[3Plq};P'kW_r79O[ ] g F=8`:13窓WD}ƣG} ~G>gk7K4o,׿R4!>o"3!{X3 ̋;^mg:-]+1"~[^o>9"b7>|tΞxCt1JtN}uOea~yؔ=a+]/.L+ZYxo8B_ى| J]!vCyyfKMk>m{t7ޕ3꠶,71=!zp.0ZE0#.^~I~&ۧȣdsyO SoyX'W^:]A'?=l3Oƃ*V內=},A&o$sے@5icDŽdv<+ĴvM܊368嗉hk3GsbJ72Aioqq6ݭ1/[Dv lӵ{}GFr^_؉1BrlHG LY?I?=x'ml12)ɛCNQ)ۮ'nvz\Uؤl~lv>>^{:츓~s޿ww Vl' ǯX 7&~9_<.nk:FpMtΦ~1x~8UQcQx긱t:GX9ΫM+pLPMבVdO>wkQ8n '[<]MƋ/{6Ż7=ǰZG}W&c9`6""\}#pG{qtptsY?~oȕ}s{}'&I^{"^gOO(З@b?q`s0Zlcb2 IDAT/(kt}VSBaߣwOvi9)aOHG[+}V~&up(ٚ٢[>A:^aZaѵv_d'o+FEɣ&]-/sۨ''Wv|o17mt#ލbmFφTbkFwAֳMtKyۛ|UM;[|}>/;;wUZiLt:sJO/vr@c:<7cCUZiY:#ەm4;:5@o]c9}WFOGW ؤ`0 x,ј ~!rJ]Ӂڥ:TAl[:m{xVXN$z?AW̆k&9~j?_ br5L-C'J_gc\CHo1XZT>ydzՆN*ɉt"bF㷂C{L}WOz$g}CQ61Sk~䓟䓿9%֣N;~MdKQ4>;~ukO&zN8G0X#/yyDaWK/ƵD:zzp+bE{Xg#{7V{M&623~mbVpjTU_i+BʬeFO`=VLHv xmLqmw;^!F2USG`,Ԩ믱i>!aĘxqI;SgMw_i,k+lZ+|4g]"Il{+<ʚ~g=W$'AS2[!^f솟6xt{b|EgDLЫ ǖr ݯ|^:3֖(Y|>Rbw'8g xGv~?Sbqx6dn͞etvĿULF{}O~NWl>,$|01&tr4<+d}mឈHbv{GxH|_u^aEωF'G}_Q?8,G!x+8^IFOOU;NhphSWTlr򑼢{CY/I+Ͼ|s;CpKxkrErzA;o>+ۣʾ+Khm)c;@,گQKA*n<חU=>#?YhI'X˶;vq3lKRNV4GRj <ҎIGqRgMd㕳v {_n jp8H%C}ױfo;d 1 xB?N?A?[QװvCYr-ٶ]#'` #?GB9.YlJl+KfJ$nO6ɳ%$;@6ou7[ߓv?9}_6|WX~+%QSTu,h;&acШÚ)G^؋zK{/gwf;U1)RO?Czq183"vM^%c&|' ~7%`]}ߖ'bNʒeo8E!mt]ebHsG7۫%pw;x,-JL̹7NxX7<1Y}j) ؏9|xevGMgQҿbl"x'4O_/Fmbg8i>4{dڹ Ij =~j^V8N$;[~?U+yv,G>|SFU`w_M t}r.?<-O.=ʇ~L2r0psB-7/#d))o3ml;gϑMGOw˭6/qm8o - x=oN6"Nr_ݿ # 喢¸G^oQN9OϛPq_jOaXv& ;$ ws;Zvrb$Ȩ_G7nńJm]{cpآ~4{|5>.Bwx,<*x?H{?(qМrW8g.ZOvI_♫?ɱEKPF󜏼}}6yߊ>/^:}Σa$c=mc=Ȏg#rc z$A,6p'X%e _XOLXxd6xL7Ṫu>yɽ%dža[' _'c^ٚ~dMo")z*;=fʜ=8fw/Sl0淿dy< }$[<|E_Rf+Q 箌;ߊ7 Ąo~w,($m-S6hE?gqy>Nɨ+&5:-[jJX}&t~TqSkѕȞ>ckЬϪnz쉵Jn;N?Rr1!\Kơ<@D*LF3XdO&O }t\s'6Y]`^};c7)H"=ijyvx郬v˯S6ێu1Sr<| }a#=ACc>; l>f_[?)x6OGȃæyjr; {x/f\ň×o'aE_k+>/#~ȈOkx4>7;\ 7c,/{q}dc-9 Jhġx}BQY]UUU8JT ,rlUEś{,='\t4fw -Qh>T;}7{H~r#1Ldm=3DNy?<_\bY^\c9y@fvs ۳_<:V۾Bk)ˑ8otb4-\!͏پZ]DOmzwxhMMt~Nr}},nwZˎˏ߿w˾xgw;b9 )=\[$x*8cbZW026ӗ^Ul;0xd~\Yw/j9s`qMXߛ tvK3(Q-vFfK /(g(o:ޕq&;^8R+l9V?>v0(caewBg͉|.Z<^OڲQzm7RA6nR,Q2,K>g"{2ɘ_kfw %`Da` [">~4I6 'ݚJ:tvmt}d luB2N~'[x섃I4߾j0ig:'KO3npL^C44P,0k"`+am2ԙv;zIEg V6tzMnK8A9@]-dhp|ݾke&d<1rI0>j.lOGp>zeOږ^ۘ..|ԋ>4r{0h>rw"~z)#_lRM{BȎnjx&a@͎1;^} eS7;m U/"ś10>xӋ9Re;'O Nw'Uьjη3q]o:s{Eb:8Avu-?,ޓ)`y`CyAH,nWdtդJM*s4'wl6c&܆܌"<,97F.tNG7[?0?FO 'pa'}rPoqUp _급/9|8;~LG>WLjϋ{7&l&[w %i0LI)~FBϹ+?,4 5xh-?5ao`=&6wN@`=1xX:2"q^ +yKatk[aWɇ;T? #zT\LXV9+s+ݭ8(8COJG B!s(τ"3^0 hs"",&V7S+&Ӊ[$>۶O2s5igrn&"ovmsnot{@?Cw, }=~\ ʯ5l"mճ|fθ! K ZS:0x~ *՟ooXU§;{';q$-,w'dGKd'#=6˕⍼W':/'>Qzcl(ȋ>Da2q w\nƤg?<{3q8|ǃdx]ӯ("Olo̱pMS^rJwLd vc6/>>K8a҇5eX/CvRT =:n|S7p??7a~76Ɨ?/_2a.Z8"o3Ϸn );|!ߊ# Z]v*~8A?y~^17Glq1}/Lfh('IfǕ;uvy~k?qK8037G?M.a/wv&Qe]_ ݢl `dnfUa//#g W4|K@ױɒ<ɸ#oݦ;>eG8m^DYc*C~5^? m FE Oj6>y+[QtgP3ykb}ڻ#ѵu5c4;Ȼ'-o8tv#~SlƿêrN޹;'KPfq~YwPx[%"N}pc"}!l's&CfW/FVxTVk@  IDATv\Lt66H#KK VP2~9wlA^ }+588~gMp]q@wɒ=:*Jxܞۭ/ NήMl@wےC6>>xӯ/,6ҁ} :@[[So1$AmxtMhBz|;:L6~+ەSÛʾ󿭵SVlIZ+ĊeOܖ]oH}Vٟ%Eİ5 dM2&oAr:& Ua5x^y +uaB~McD~bdϺ} n\baq<#V==/Ȝg“M[MbqU-~$cW W|klv%o1)|6-Sў}8;DsNn_&Mv?'>P?:>G<@Pwr쇿.v'@59t}L>ܕ?>MV}L,+ͦo` ò'F'oT֝j˧$cyʓ&qjQ|V]lL>B2$/h4{qO|V>\~i?p~&칉7w!f}~Ŗ;L6>a *E~Q_@ov=y>|ĭ;Ux ūÛ0[ys~n?6Ĵ嚣=`5=tY 0Wykxp[ N'#;;@G| z?OOߢ獗bz|8~ŘrnQvgƧӲuX4fRC1'ƋW [Ic2ʎ}i1f좣rcuUڌ]r\ N [D 𑋆95L2dmN2oZ(w&="a|-1Et,6 ր=~o &5K .17zdJr\>"m}ZlgM])[ɼ}aMr?oxʋAzb-(n/Akem Yr4@Oա} M\N,?ՕeSMxޝw}tc>:V-?6\Kq&A.)Ι~,:(wW}`ЙaT~ϯ 82KM 1>OuaN>'+6Imd!?m{M0Wƿ&qq'n 6䱩= :_aU:V5ji`Mo l66-fҩC2?:Z.*̝PNWN<|B0<./n7jʆ]Im0لcBivg-dS=픱gq5|vU?>縲Dz"ǟ×kM<*r c-qc-G&I!j퐝. ]?䷿Ǖ⳴I;JPxy[t\gq\\9aS>uo/ڞ;n3Q'DcП__ogmlrAmrȘQ?N&oAWZ>U8O{6[omNl(<˟]Pƒ~ >Air< jDpnom#V~7']pZ ݤ7noޝgRe&[ؗ.;iiWG>?w*DAݮW,[^o^JA|-Ǘq Jؓ{^;`_q((aڶ]Ǟ]xV Q?ŷ䧳E04f;|(|ѯGl'rdL'[vH^_,Z=i81l&8u\;t Mr/0q'->Ʌe^RqGte_շi>۶œC[dvjx#)T,&ɩ(wi4SE<a{znXSl_uN|xw;X[9rq-оy vŁrS 2ħ ,&gem1#|R=ǜ2VR>㊸^!%InjREjj0DQؠ=w[]Y ۶D9s|'cM"cJ6r9} 0rXsC?^0(p5f>:^YW9m{Qx7:]à`_69 |> VSf .ӘR<}$Ol%O_W/ї&gr3]M=rJ\쿰&VFIv,I GMwP|S;&FWi/A|ѱK'&ʲ?+=޳MU őg>|<MM+ܪ<]+wO[T#qзܷdxZ>lF±1w6b+-0o+%ޣ_:kq\H-ЖU:u|7NR; Fov+CP9N`LiI&wh{t-envJQ_ngvW1765mBmtWT8¡vG2~BoBZy>mGt{WAc̮UsÒOڶwF;r^@swvDcbG;?y Jw|%'|pF0.r;7=Otegvc'<mj;o~q[lϟ/hsA ]PGX_TgĂ7~eDXvRtJobͻ}?Sm֧pm!છG7wMkIǻ-%϶x~Wg;/IzX׶Wd}ޢHt4]Ny</:"ֿN2mNvu^Q;ktʷ9{tbW;|ɮ;n Mo e}}{1 'O?~նss!)=䇝wX#' GLŌb;jƚT9gwSsߍmP%G.w}%[xs\vQtig_ Co:'.^ɩ|} W( C\lk %s3܌v%Fbw6ddNي=Dz1M{sO_Otݣ%9'ʦO2 #??>ɷo?{f-%&wQ}te/]9;g$I:`40z' nY3O ttYItu{O?j77dif61s;{4}>_J4OGB&Kag>3A%)v?͋,17$Sev}H'&Edqb` F>k_X4/zJԢ%&<k'?񈷤^"tLm߾uNWlLDadu2~1lvv'] Az66چꛈ~vgK2Ydk~A\c|qS;r<3Ӎ%]CȕL{Y:Ic#f;{ 86]5xYм6>JNl #|^\/a{9gy1-N7r*K zp72Hx/=`vXKߛX w<>ԯb5vo?[ mo\܀!P7{m?B|lUM `m&PN#~@&_Cs:o᠍|~X \m}Dmt-nn<>ồ'qNx]V1[,W| 2g[ye?NG187:ѶZN>r.Sm㥑;>\v>;JFaܱ=?ݯzwOW'{N#g g>{SW_ݒ"N7+߶/xEe )z~+~:zY8UFD͇tw?}9c.=";JrzLf[hҽT*^hA]0\ʷ ,â֗?qφvg;9 WQ,a{,a$&QTUxō*ܣdo~`XT/<~{u'G1Z gk%Ngx2<ђ={NxOBG'T=*^Nh^vsLbni\WQŠ}HdwlRQǠ: O0֖ZN"<ǃ|s$u""SlW:x Pt_vz1`MIItfϵ@Q9Hf]t0MS h t[@_uT{W\37qf׳DE6L.&hXƤK:fbV/qC7ǫXq{kO.xTQg6u@߻:muh\g=M*+/\*^ L=y939\w4Gc2Ei=;>-7 #4J&&x&O~8CߙN.}ldћ.}_vm7o*ʷjsV~c? ؈#~w#~~;|&hҩUx׾?4xKGDU٣8Q?O^7J4d/!~l _v} ~v퓑v|26q%>P$Э1x ozMo҈Nbo8;?|Wz b+FOfDmltC6vA=};3%ro3gֳ_?lF×a_4nōm9iq./2qWUmMdo>x?lk~'wjrksχ?_?l΄>].aNbb5@_:՟_ '002n?^zM)ίNK؁%^l2_ӻٽ;̎e9c,Ϯ KٽGl?'3ӕn,K"]u^f_q>Nj7wkG;vظm|nLld);-0 튴 2? l+?=Z;[O*}v8;!tgau7bewqڷEq91J'b E[ ; ߢ? |e, Od'3ˆn*Qe.`hvYm`P/7o .MxvC1?Oo~ibޑW߉p{FtU|~.zso~͓GM-c8ln|&7߿|1hs'Ijc/TzЍM|/eWfkE+7h/9G%\1Q:N<X@tOʾG:\ZGGB}__X.'l֟Nw~CwJPa%ӿӨ8E+W y}>{,oG>I\4)fч]A;r]l/zqv~rZ-`:Mh˿,~=-6z6_b"M JaMp/턁3p>쥑U3Ytvq O5z~ # >j`ѵM7i്wl .?tI}v X%TD{4Ή\I2,X`2MP!npFo{0@'gڵ{^ IDAT%It8=:F=9X][ UUSWl}wZL^h:d1⽉L2 Oᔌ=-2ldr{l:gqР6?{ıb>>FG_촱v"se~JWmJ%OLɧEǂ>ncn/_\/.Kf*Y]b{pcWoaXթ>[ >jb׶ %+Gy$7MZ7ؕg 3^Ǜ<8X?]zNl}12TX=D!6@ٶ|]e_<9>a$rm7%ÉNOvN߰9o+֗ږ9_O"W btb #xfo9ۧ^[Ƿm <ǯߪZ& >s<ʓwS(o'Gp'$xr^n qX_N tk[?d)>?1} b|#d=ʜZnOͯōqkw9[`Ad 㳡o[ho,Œ,n狧I O@>/]C$%z3C+6E$g:Ͱu,$$CkŻ<6Qd/Aq4`o^*qS?h#|c2c?l/~4ڽkv 0ٽm=<'&oԢ=oodiD |ַd:a#>TC;=&iLrL=*MPo~!x?Ѣ_evɋQY\N}GK{Np'.6p~Q6?oy',b;Ƴp,xbWܟҞ]KdvW=z}?'ļgr5k`ʶfQ5:^?mNq?1kcx&nnV,en[<*% ,<Fw}u˿6o%~g_{a>Q{M(as>x+t]A|Tn})@/e'aWg wcwo DggW}>/{䃈Tܢ:qpel8Gٮ7ǃU&k6f[hRd <>hl[~֢;? qUSw;pоWƧp87u/@m{ 9)Ц?Nu 읤llLl-vPz(D$:!VPe7l}et(/蜰6k#Mvۉ؄ B !Cٰ }$ʢ">$c7V(h / _}׾Oti︯a;m&F__=mn%m N2%Z+??r> meDG#ov9=vTY_|eo@i6aNT);;Md$ A0ۭ[S45Ro One"+uoD3ĮƈmZm€Oڳ}[Vp}(7 hw&> ߄\ܒS[} 0Ib=}4nNO1!""h1b#f_<7,ڛKxצmwqcc;:[f}?vg~ &Ț?qr9 v,&͠w "k_U_uŨ>5 5M<־z5ۏ7;F=}[ ڟ1hƞX,?#,`\v1bПgb/~dmk*NW_'o}'uEsƨ+3bl{7:..oFĝ61w<'NyOe 5wg,l2-?ً7|#;iae8W2kb /&NP!r;GFSQo:~٢÷}NhR+=8Ew/M?ۿ6w2N/I߇+/#/bPߛϪU_r@&o=y@1+ķ6BE&¯̵HO6_^ ji9^Y|ϧV칦ΓFpqnM/'䤛++Λh}͢V,X!eڦz 9'*ڏNF]& k UvkS}G=ZoBxA;z)g#t,2uh}n`N:>ӻv@hN8;8O%Xf1]9xg SnbM(pAlkA{ ¾}O BT<l& feSW [l0IUt̳W6=[VHN}r%䊏'^R2򱒔; qXJvJ3=Q9av7v}3|`2;)Ndb#\]uBX?Ol6 Qξ6ly0r Q/>yǜ1Ȥ{4 ft m}hvO[WN;#&H阴%xqLt\,%xp#,v4>4lmp~4zll3A߻5xVbxdnFW/6!N$>& /v@ξ!7㍾BW!n`ȍ 䵵ѣ>~Yg78'#k$7='^xY}rs!CulU}T, Yݕ2$t '7?ҾaN3ّ$m揟ڪ;ۇ.!E|UM×'} X_ m75}q@tsXgڇwS<_!ݧ-YQ]z|[jo"Dy|M?0JM"Z~<9]m,6o,wM[/#ԏ{'MxfCVn8[X:,z>z/IcaXjb6zO7ڭصQ7殾=]r:S'T/nml±9wSq;/zܕ@gG6 ̈pI|s>sJ'D>9گ?h}0[ʼDNqȳߝ $?|߭|䤗̋hjbxkx]̉~|қ?nڽ퇍x̦>]paT]OLt1B m0ELmo<[>U9d6zUGjVu'싻h0+_Y'.TcW7^~f5=m1v1o@]FЙc1N@hS'v`}hӏ[v~;^Zn0joӆQ9 Ƅk ,b&:x[gBf|H6,?Ӑtx~x,t<+H|#<|Ss}Tt_H4cutSܰ߂r~7RN~,:&kwƈWz|/EӾ-wG8=_K/5bZ&C ϕ$,Zl`!re߶翺}a&®fzƇn鳉1W'Od3A$o2'q8iCl{;:<~*&(:>^;>=n7[݀Xb=v/Q]|⇝YeeV#;aek>|G~eGcd(շO;|;&d뷃g{9^oup~t~}]칈 X=iE9r틣j-z[^V&`jG?e"`\]>YoK%tVBhm*|V@F> &:Hd:ج|~_RSF`D?J/nA:&x6\W:sʟiS>ϙ)?e:H`z =P_<md~-:??xۍW;!VFOd? RkSIsel`OTN:E:`W`8eH_: >nS<3FQ@IХOudI/3CGh}V_`C`;өrÑۀx|A3S~8:_׹*0k&"U7 7 +jwy*-KBBE )wC_^߂5"Tni]SN8Yϰw~(" =+اCxy}6;9G#/{1LD[wWNp&Zi$*c~ߣ|tcLc-'/2G8YKԁ#,u|I:}N3Jo#6KK{?TH{rv}@d蝈:%hB6?x9f]0ȨPGB z;.bOp tt(6p:ENq$~p< 2x\ Th8#(s_.D*$* au}wSwy غӈ!|]<~e_Pѹӊ|hB;h vMkI F'V53<$Vt$= d3 +؁ArEPsI a4T%hi9?)LG2-Gy@|rm3I'cvd8/fP%{#*.=՗gi5@,B~THʥ]7WS~N99: V4υIWqAMI~Rv ILc ^#*7pP$#/E 4COe>(J__ st 70|G9x(#Eo3R>Z.pxK\?)K( )SX/W*29\QDtODБJҮT8GF Цu xվyӎ" F?'XDV?c3$J.z9* +-QtL4'Ň{9t إˡe`L-`n/&y` )װ z&:hr$w/'N#tt '^h˨ԗ~M!X'~$ D$r=)X햨ِMFyKEvPK.gB٨%zX%uHlOG/؂_/>}*:b@)":'u "u9q(oDl?Q6zKFʿxAFx2eGARw$ YNO KKb6>^O?PIrHFh-'E2@e L!UR'Å>j#DEA.sxC\^&c Rۜ@M h`&UЉAPj(V7M< FDʩGQiU48P';_'4CڟMjh\|. oCPK&e+t`G<SD -)<RvV~ 02?DPI~apם؀I/W@8r߱OS] IDAT{Nac*d+pLwTfǕ=9ҩMS_OؒځHo䜋.t^"t]G(Nx샹d27~g`!L9Cv6q :=i(_|%>CȒv -iUXJHu@G*#2"{yձS~D!oj4$bA(̅'N'`xޭr|3UC?69!SQ]_WMcAt$I'Lsށ" O2y'S&$ ](!]NQ/U'`<|Ui\@iW62=K/P/'~!D \@ X}sK tA |44h%}u'LlT>0q""8>?HNxʇC0#5qIA4 3i:\ǢQzcI&X$? 8 tRQV>ÍuC0do{ k[IR5Rz'/|-^>@:J0EToe剟1Ãlx X@丏P;sţN4ٗ&뚥Rul'Ϭ8(V|h@h)~ 7}& RJ uҟ  nWR)=bȓ>Po8oB3^nvEWM'&sntPDM?:AU -z4 ޽v\_KzN=e%6mt:F[̹c3C:f3Cx6h#aA!1|!tl!-=1OCg{%@;9uNg x9 ޓWʁ{D //&~wN ;\gCCy5nv?X-L|8ĀQDy&]{ytSD~!?e+]xO>Cx;U;~u*ڻ] OrSx N'#O?ma ϡϟ` ڰDK6:K@h6cbsƼG;y(?5~ _8pQo/CJv˚Ks"`K:Oe2@Y׹TOt1m,~MP*tݿ;ȢOX)c;x' Ϡq` yOCzm \ c$;' }3R7qSנЕ~@GY+(HF'Cڟ}Ct:"@1($7X 3Q0M +=);7I *iif1 :(:yp/AH!Ur\!L@*Y ♀gܱR=8"6ΦIEE6]NA .㈮T,W| F@Q*pLU>g(B:s#mJ<JUyKZJGG̈4ȑK6WVN3qǩ#]IEA9vtq!PWɎzZ^6ʫNxxB8ȓ9t(X}*ɉZZI~|[:sY;N}̮N8'O`rTJN>|F2"˃PF*Z@ѕ]w:‘#Je:Ia&(ʬ!|?b>^ :O)6JO'aH'4DzyS&A8&be>_\p)녟$_]|I}< n3%U&~t!D)8=7YKp m;It>9y^z: q!smʏYok ;Z-)$2\'0%`~`<'Y +HYp`":&fi 6#'3lff;(2|O.xu| +Xb7 &]~v-Y:SqߠJ6 X{H~CۃA*~Si |H9/Y`V2¾2.!G'D$R|k킇B?np}ep~Q^QP;KD".\C{@*={6:i9%"թAffC;u?OK?&ў #GOhNfkjzg]|FkV?/ =;_%6BYi^: )SvgψWgtܻl~e̒hH8I[rB C'NP!(/ pNy5UrEK#Si{-C]S4]+=^i|l؏o+8=|k"yiv# ҇xnOՏ;$R}myZSXz= .\? %3|KO/'CYGNk2F>ȋ7:tdOyP¥ X}/YXπy6mGhuk!Ď X71o(&m& 7v\pvqrjw}{e$ryɵxd!NCL\ʐ6ܢ fQ#ZqK@`Ґ8i2@ONW~:ɂӤ`9qgŁxMAmf Fuu,=vzWx6(.'wsƿwq! S,:BO~('ta F9r]f>N(HVN+/T4@5TaPԞWD4r&FO~{Ѩ2#LdWM+9xcL<ו7]E1!n).՗8M}6ZQ.0zr > xC?X&_BKgsN}CYUYIEv*?IJ|E>qB蛄D&q>{S7Y|7>PÆ' |, ?0M{q^ BݥW%WKF[o 2C:q4Ag?.Le#^' ;?3:%?~A7}f2Fwdl3~x̱s ^иRs/3Pobp@72\QCHYx"{.n~HJ1b,'doCBbw( ˞,x^oIH(D&buw(b(X<(H+(4?S:%?y^6 #uJ9y}NHHi}x,·$v,#c27cq D(oxAx^ _v1*) >Aݓ/coh!|K=lyxXTux8UM֢(::J>m'|E@>66⪲ P.qV[:_?Afb|'y%ٟ<x e N+ NFs^t pt^>rUgGC+W =v쐾da[36p0?AfeJǧ]ot~gC(zsA_;:yxYH9Onv9.dM+.ŮssHߔGNt2)Fh"<ট;BBp,gNtCO60>vP1$Au|SoLvrn(*8} O߫2s4F6 l)à{YlBয়x~ags@05Cj<'v̽}^ z7IG/j}Ys7L\%?Kx` ގm$a@jI24E 裴 [7h^OmtMd:'醗NV뺪,v=3XAGχtR_ >EQ^OI^b3=?8Ly[Gw tt?%8}ܵڊ.`BҩS&C;Ž~N]Dj @D "D"@D "|(ݵS9D"@D "D"th\D "D"@D "|ض=ڰ࣭h Bg-?syZ'z˶nn۶o۷{۶ٮ>.ѳz:NzV:~| 21."D"@D "D ;2Y?UDηڠ5CnO.U?t>'ݻw2P3kz}ۻw~5cN{뭷mN:#CxD"@D "D"c3a'w|dŮ~?}:nAV=0{f3vێ][u@Wvmn_:Gf\ܮ>ɑ},gD"@D "D"@; 7nqmyMu/`rg /d#F~ţm3kmeړKY Ld]tnvPdlӸxD"@D "D"@{"~³=y~x.ݻfjI}*rQڋ/dc\d>5b~iSOA5Rҵk3 04.#@D "D"@D "8:Ç[O|Ц~vرz-`ס>qvJSzd+)):@ڵӬɎ`'s"@D "D"@D "8jDo{-> b5!u 'pwVm[m w>;p=n o ر^} Lj@D "D"@D "DRGʫozZ}IK.A,?3;e=zj;6o~g7#"@D "D"@D "hW*l!6Ynݽc؎߷=_Zzuҧ{cnn5{N-fzWA#"@D "D"@D "Aw;XnynVZYqvхY;3m{Ν֥s{kgk"geLR#@D "D"@D "Z :i=+l6d`[t9VwvgmYm6p@{筗kUV iheuD "D"@D "D"@Wc={W_O˗ux u(ʕs |wo=+vx_k6y1""D"@D "D"vEΝ;w7[5>ҥVYy' ηիV'?y‹>o߾VUUeU݊^}ޮEf@D "D"@D "4C[Sl>r^  ‹.?z;<[ vְ/nzyi {4 Vd/>o1^G"@D "D"@D "оiMoczf/Xj5V?ZvΧζ \g W@^=-m:߱bg7#"@D "D"@D "hwzjSuu|i`{gktlgXՆ״b֛v\I ̩Se9sȈ@D "D"@D "DÇ[mmU:Tg{]v81SVgsw\ŀ}5V__g{W^ڃ ~١4 Mϛ@D "D"@D "DͶ냝K\j;={lf8`a;SK dikV'mo؀SN 쟙39ID "D"@D "Dk8X֮j;d~–@o~ci5޽g #@D "D"@D@|ovcgbxzt_y_m7]dN}_u;!u:[m^{C?٠O/]E;kװ@A;oR@@D "D"@D "8_w $-__=15{Ezgݲ^.5VN|<1,hRD "D"@D "D[ 7"D"@D "@`֭i&{>SN9zeZYs=g6>Om޼9&rÆ ѣG7GgNAG)ֱcǣĽml|M\TO(cIo>;IRю@D "D"G7x֮]띩cڤ#+I/6+.rZ~}h;< k:Ϸm۶1w}מ~i[x͛7GZk5W|;-k>kGU^\pT#@D "D"f_}Ud;s ]v5~ЬWV0 A <# :MJ!ͪ IDAT쪫={1޽{f۰a 5cBo%Lv@l{=m/}-yD "p43E۽#o[mȐ!VQQеUl].#Cw$N8W\_5/^z$,yD ܡCc} 6JҗZgg`<ņ.8L| GG)#W{_,2``Я vJ1Pn7L4;מoнM_lvtESv>l'fЄزelŪ6J!٢l͞` 5Zfco=M3ozTiK j6Fb=pw6mYY@tNh% j=۾w >V=jc6gNd,Of&5|[ـH^7̊<w9l]^QkK i!ΧA>XW ,'nJbM(n:LEi,KZĠ%z{V$g>wꕜED>K 5tZ d_Yf;|28y[V] ǦK[^` ?{)/x8'.;=.8|M(1z 8Z]wFZ*#/QB[2:/.W'. ze8Z9z{5MWlbW&4/h556oݮWp]Q׷ghә[4b9}{Qz2sqvM2Ksׂu9;e+wVѭzvGdwS*׻"t뷯Y^MM-?2`ڬ&Usz[tVF+/;COfJWK`wnQ[=lƆNĦn'MVo Ӷ5Zq$-j T5ճi okwL&ݹ$o]q0YlnHWy ]3~jP7~ Qu=zϭIleC4{V~1y?<ƺXIYuh/m2e+?ozgjw >bW-k̮66UR7ՊIeݶ6Dȅ+335Uk5|ZÊiWyBX6Ơp(whlVQc7&bc3 \uyvp]vMK'm`nK=oݵ`u+jR%[jILlIwmNY!(WgV ݺY>ݴ}*Fp052X5OjR1gژį6w6O~.[9+m(Ow9Q@Ds{nDG(;פ-?E?OY.]SRY-momh?OH~l?Kγ85XRH?\Xo,eBC1rNꫯ̕qAS _ip{e? l TG}0vY-AsZKV>nlЬ'եEՑC߹&JnjfY+BgIg2tOTlOկ>es߅7뺻^bڕ le6'3v.'/kgz-ټj6%lma_ @|ov]+lHU6k-{*m;ޅZEh}Smaoج mղE6熳{%ՋmU?lU̴eكsnYLu5bZrM̰fwfk!+_i3!o ٬nsײ^f3n͟Ͱ'^Xi ڋgb O79XNˏۈSqsHi\_u<{ClssJn,_r{۠o6fpo8Z ٕ# |ZQ:f \frzԂ~xMpj[Ay/o%>;n%>ԯjyCV"ZZef+~U0}V,]9j|leV>hO$pyWJ*:=Uv\ \5B"5|mHǦYal0^ i}pel ߶W׫I㒁[gÌk쫗Kk}.W[P>ͯ^.vfg+m -QT~.Ŷza=zӋmʮ Gޢ}/ h7wژƯPSl lnEv};:&s;d殯 ,"'~zϞ=S}fn#ē]k39<^߯`CgYۋ'3Mo< y;hdϦi#?Ή#-;4͛}D#@翟5s:Oȓ#'g>o| !'=F H|HX!& _jZ`?_vmXsy&ux' 9#FؗHҙOQ~Ru>ӮS/lZh㴢Վʅf/0ơym!δY>ڊzV#i1߆6"l[TtY96ͅ}>%6cLD "h,Ҿ+/ϴW'3;NZ>|pSOB[hl.-4s}G'wLӴ__#׿M'ʸږxqX8 GvU Tx *ws1v6[K;dVϱA]1}]7  цrt+I8nӃݔMS6eHnޖ RvMecڦo+4×֥\n>0Þo6q@ PoS1VחD^:^y&bϲŅ?olVb+/Kڷ~iò(Z:-Sk,v -:c.vZK7`ݘ$: ׫mβmޘU媽#; -)jE3'+~5h)Ovz!-/.C5Q-e$ݮ߻rK-wK'~gNNe|2Ʃw|prg !ڨML.k#߽fU\kli Ӗ_##lD6ul/dP:C=s pɟmh6Q\mm&r&2"+,?餓~r)^yZ|5w]g mɳs'^K[@ {)f8p`f|'t^~_tE6Aµ%Uk&w-_UmM«}Z `;,ts G3&L47 ̻%շ5߶LSd3x2!~D&znvxlWfg_9ޯLҗC uV{8/Q_]gجGk}ߴeOyOiVQ런Ys/J?jWWo{35 s hb+W]uv|mu:.PtFH"+_Poht{|vV^bHVjt޴xm:R$B~}{tv&q߱Dkm˺Gʵ43Df|߲ݪϲ 3ĴD(mYiS~͹ UYjMl]ZTeAi <~Q>R] vӏئMU.oe'N[*Sg]n疪[ߍir%kvlӐ66]`co/6dW!V1xrh pd|mH[!|֫^r|!{m}y,RlW~`oU翱40l';7W-{ :ԆТQ~fz5eTX9[r];NVճ6QЈo6Yk.P]_B-k6]]j$^E"V!@zz68#ķ̤>օ V)Hy!*G}[ߴf ,yOGZY M+$!{N}sh-:=~OUғYڛO۷M?/#=nݺGDӴs>ε#|Gmvq2@2BIKm9Vw0uB|VpƅWr~ u\la~me}ꉕ6 &ېa͞}r9wÿj S>n"I笿tͺpm"&[!mm+SilųCbd[ap"t9X<:ڸ<lOLSk2*4j84ѝpʣtb3yAߤW.nε\cS7ra ˾)j Ȍ[+gس?R7j3B n<{5v pLq oYe\ۍ?e]1ŮGY/*B-ܞ i3Ŗ>پ1yMX("fϘtѲ 9ɑـ]6ԥgQygWvJ|/e; W$|Y6!Bl%yD "hVG(;4Nk936=N>d;p l ƴG3{Y~cw {ӹLF}ƏB>}|FzƠAφcaV6 $Fb3A+rb:_:#&M~oW u`Էo_ iJ}ۍ7X=vey2*7i:Ʉk. ֠k:JCe2k`k=>u=jNTy9kF{@APO\h#I@:=3/hUdl4N\͙|Jsa&d rr[[9lPWf\Oj4)9O\=V_bI[Bھ!`.ֹ=|$ť9q2]P~gܯZB3&TZqG*܆H7UR󲌾yY)X^X>ԗ%mV}r~)s+R[sE4fƔj#@[sf[Nh|l6mfřWvc4xf?9e | MIDAT_|VO~?yZbBG >J< D!Է6 ;/o^[~پjwwoo󔆄N?7n?@Tel?"L4Щo1iGCJX"N()`BA>©8sk8F4.5_|ьE7",#q)^3Z m(|E-ݍ t>HFmtkGc{ItkKOڢ#,TZB>4hLګ^{aZm#}D "8zj^{&Y>#x4xBM2>>4dw fi\܎<RǞ\?[h%!o),~KWd4Mi=7~gV|dj`D"@D "|ȞoiӴ'Zcu6gcvϦuv>k'hW]:iفeC6+vrw%ټϋɦ?K_*ߖæ\6LW # @{yD"@D "D"=X]lhک͕wY0Z盹><[ߑgV>q? v[$w7Ѿwr}!m:TD;Nǎ.&+Hf## m;u4>3ٝO1qHJ'D"@D "D9p_kKy;W8V\ifOD "D"@D "8BȷV]ڒ hmG?/|;tO?OWicD "D"@D "D>tVIENDB`pacemaker-master/doc/Clusters_from_Scratch/en-US/images/f-13.2-devices.png000066400000000000000000004211221217637305600265060ustar00rootroot00000000000000PNG  IHDR i1 iCCPICC ProfilexXgPMX`w9%眓sFrPQHV""HT  |﫺nW3==sByOtt8n{o& |~hw^ydOEƲ~ѱ`ƣagƃ8<}89Dc K}`(!`{6F:""j_1? =}|~QH\tO߇[DxliH?YiEyXڮc!ngX -Ͱ0{L _|l?v;4 ~8a4 *zX[>AD2AT4K= QLY@* 6!B$ qB($)Bd YA; AP<eAPTBU&tAF  /B !PG#,N/D"FD!{aK,b D$R)TG"m{Xd2YC!Y2 P2(-凊Ae*PMsjMBКhs:A/o/tO ÆǨa0PL*8sӋyǬaXNVk`˱wcX:vGq&Ha\)׃-6xQ&OƟ7Ot&L'hLBO"|'BD =1xXFB$1P$ <N2422L0|'Hb$=^IR3>iHee4ggڵڳ:::tfuu}tt ][ԗտ@ aa(hĘbl\a=HkcNlΫZGC 96['?Q|~iqN((;s2)S5ȂB¦"rQJiy?J *=C8f̪\|"eA*ܪjg>ruimGX]i=>~a \/l7F6694=hVknni9Պhop%K]m2m._W|}u嵾E۫nPou@]]nZqKVmەwX!dMݻ|/|n_<0o?ڃ4n>R9:X'*Ontw,+!vw'VNn` )Ei2%R3\e r%sZv_PXDy M -J*.i3l~5!7";b:cbntG |ǧU=> %Ň ?|"8my9 Wү&hMONθ72 7Kbb>Y&~Ҽ v|8ٲm? r qtEQ ht3F3݇N $hf-2*JZ{ZktJtO08aX`tƸʤٴŲf5gpӠ+uWپYo!o BVPdpUpF8-5XTGb,ρD$䒔}ά<ܙ5rSű/8~ĭN-"aP+v( ->S]v^HD\5~vtx.nnm^jt Uk%ڥnvwv޴v!NaOݾ{=Pwx3P8xihc ƺ}:kfZqm썹y ߖt?nYs j7u~15g@ ! (MQxF!QZ ]!b0o.8g#Db!y"S(6sY|bCyOMaN%3_BrUr+s? EO%)#T+l$ +*#L,^]-")E%!#$J@J'?pTLAiTX]_uAM=^CCQsUk|O]'=i}Aa1;63SsVyk\ulmv+o`\RZV^G~oyр `carVtvL]쭸 'RRoO?w0Pdfa,l#9zG5)K?!~RJ~]Q%JY)gЪʯ^VΥ>yz#oKܗn\A^uvxÿAͬ=^˾'=&?5;O}b9k1 @)\py S%Cv$xL@ _+@dC"HGd9r%:E3mq4bNK8<.ׇ kD^b.q!ɘ(XDecS˔`"5%;k2`gfoPtĕMny B5BZBEEzD}b-4@k('% d؛˦ʽTpVdVQ*TvRTyڢ1٢BS{BL]OoI1ɢٸ )E_6,vŎ.ܮnWNYhY◈O_YXH5ud{l@ː h!鎬AQD}4탾g{1Wx.[TBaEc`#n13v1i2Y0ّ% `вp(BC,D\P|V*+V򐔀Ԁt 9[rEK*e_ߪj!ښ̚Z={JuTuzmG Md9LP&V̿XYnYclm-<]nθ#JxX{yU{1 ಐa#Q)+qf ]IeLiYF?Wc'NvΟN*VwUU:\Xl( lbb׶k;:oR=ۓK7|?G O`610B« 7w?M;^޻ht/.+W}qwۺІݯg7_f#퓡eD\I@C9w0ژ{XK. Wt KǘdLb 7SҨ, p'^psvp>s7/[QBHWX]DETYLI\f(-)!&(ɑU+ijkQOD ^ÏT S_\V'Q6vfnNG\\Ϲ;1}n?o_0|ʫ'1E F)D7݈7Mx䑼(;$ٝe=v5bœO. <<Quxt-|E#wSmPk%Ͷ+.WG\va\?7x>(2T4xd l3/S_|4mlJmZt2+Ec ŧKe>}TlՕV_'=ڏkkQks?>\W]`Hݠ2wMͩ-խ[sǶ'ߵ\n\~.ͺz8ـJo?fRvQnbޥ|^ pHYs   IDATx ]E7~^$} .j@YqQgdt ~.ç7:fe#NTdW!J}#$;Nz_wgUVֽV{KJEO-JCb92@F #d2p PCCkѣ-aqZ\booGFF #d2@F #`"MMMF \ӓd2@F #dNt`B=^WڱcDzcl+#dtzC~aܹs@F #NnjQ<Cɖ-[z 3fq'&Lf Z>lJ ԩSog',Tjg??3WBps5׸$8ns#X8+Vwܡ1;we˖i4 8(6N9zSN4A]sͻKmr@4eojl@gzF #8XfuQ:o"1^criɘ1czL8`N-#df4 UnyGuӧ,,` l޼YgE8#QF h6WZ3˴iM&&NP;P{7oQh?>N Yem%?@fd2~%TDt5LRgΜ%K4x&K r"-ݻdIO(Gk)GVmIrɅ=ɩ@F #q2*pXzɇ} mmmK{[[[f`MD v-6k,wwɓ'RY@69pڴi*(X"P_'N}ڥ f,ˮ _$'MѣFi(?*+3utʶe,7Hh:G9Ms @awɽrm3JƎjv鐻?% VrY5TTJR)ʜɗ.?A9b{X9@F #__}ɶm䤓N>2W91_/pVK|9q?.z!g@֯_r(< bƋ u @aڵ:hMV:}xV[U&-IlnذA&MyOΚNcR@gzF #x* оG߾K.~2_=(w]Z&Oh1d f 1t+k&{.>Yb/w 6Lof+_FYc[:d2#ooڴI9]}s9`vB"7:,t2φ;!Apv,z1`trRSɖ mr`aϞ='}G|0 L!Ciyd'vHS+ҷn%].MuhƗa VJOp쾅?V;;;;q s%2{hu(CF # 3\m4g#w✭}h}t4M5$5BC#(,,_K|W>bB'n*~zCtF #x!+[lo5r؂cg6,:gP2@F``+^^;R>mMگ=l*vwIK/0ej,.|kYߐQSQ^}Ld2aG&[Q$pcol q s>Pν;=; ]&z6sPCY fsر*J > CTd2O1\s2ͣqoډ:4e筇uxk › !Mϯa֣l2Lȗ)Ie5,9µ\Cީgu`w s6|i,6 `} Kkǁ߃s:#<hK?UZ͕'0+Lֵѱq";wI 2א2^zL>d6#w,1sCF #`i.g ,M.c˖-jXӳggyq~,.㢟\۶~Vd2 *G~Vu }xm:m`>ޞCF #<p7 5uu77yɝq㵅2]-b^]3-#pd_3 j)g2@F`pj& u<~tsd2@F #?C.JMF3Tbszd~F #d2@F #04?1~d2@F #d2{kKY0#d2@F # @d2@F #d<>,@F #d2@F`%XGN/s_O7A}QYlcc6fʉ'7|f3Ø{.,3d2@F``}Fߜ M~{$7ϭu_HwF̊p;&.@v@~<Ox`+ghpg@F #3kNo{ vM>Z{{ U}3&)=utTCPF)um-֛.7X~`rʛ0a?OAF{κ1 "vz'>$T%n\rv<#md2@F #C7m^,ԑ֎2wޡҍA_; C ]|BƍEy(9y\`A]K[w=g'h0O4 rg{E֮*K=o#_ ɩG>t'M$۶o7?Rm>@+-W]т@ &Ph>XwuE/_G{08| ORK(CF #d2OOM nҷGF6 IiEy)ЉKeH{{qqc\ =,{( :8Rʵrh=LI=Ҙ^Zm/s0JL0/X@^L1"֜%"8MZe9٧@F #dt<**hXx46i_LӁ(Œm,*J*y7k ;x>2x:˦n[>w6ˣҕ}#W^K:\@ 37v84aG4R)@6xٍi{?.(-O mGtc.%y_m۷U8Ƹč1% ͕ KF #d2&ɮsiIz: oE`:D?3!}wI9ga2a℺ z^n[ eV-{ڔ}I,8U>ݟ4c6waaǍ].ir-[ BFРw0Na`|B|=#lO^+޼0w6r$ވ6g.-֌O4Yxt!qgG`$2O<9uϦo9ӵ2@F #x#˼/ )A뵇bک9iVKJGG'_uDxn ;e⎮<yIX%}h9jWwkh_|}"fQ*2sJY>f 6`WN;oxp?Laʨ߲}|up"ߋn4-A֑obcg9% ,&My6ɆeQ{ڤytz&ڷ^z'Ikى;vi8pG0)g@71R+>cz,Ȭ\ [._L02뮓 /p9ĝ;ȎZ96wG͗-1QZ5#BGdҷ˶ PeG)Hb2\Zř%Ė-[bɁ[N1">G+{d2p#U0a߉g?*xIڥҗ#M3\āH#^NGkc[g~8i3]].͓6af@qȰ˰ET[ ۮR+h#rXڮq@\pn@|bxWeg86^QnRY+=rͿN&b)ViixO5CGOl/3φ6>c֟3 cz27!<RR笛d2XRž(L6aT閦N @U)>^+olZ~BޏN#Xo?1e04'RF6;;˫jXOBnLQБ#g?Xy~.b#buCi^ocҴ oTL`ҊNuc#.<< :){ bj~V|?;D<8 9s㉂XXB )eZl CZ@F #<G {"@hi fG;WyQ译U:r+~\#[^Xr6oޕ掝?bҔC ?8t[k~ъri)Ϗub;pq 7ȫ_;OoX|FǤo)/ XbM;p`&6@D0"˻K_^pT%2a1apcmm|6I1AVie۰x"`'@ڕrd2ģ·Ai@TLWp#vLO@ y>|q]oⴑ"?OyCǒ|C=6twd -\8Tc(ti6Gb`|~ks8H%ArԑRei(fz)k0,2m+əCo"ݸ/}PlF t4$ q4 s`@挈'ΞCF #d2O?Ы >}O$Zwߪc?˯x1ʱ);'+4Wȧ,vwZSd庲LY ^Evu4AWϟ7·!7=$wf@Xaf?n<ģ# s \x025 c<82k,Y%WzH&<2ai!jG|#uWEuqPq34Xvc>%WB_^àЧPnR]%~$$IN#s8Hx^G'6fϔUJkf@pYv<;ct_z9|VIƀ{;\LEN?`% ;-QôUz0Y;p3l}skեX|(z @ IDAT o,}l#=X4Z0C"yQ y}Bl绻9`ˮynu~]d2@F``|ޱeĻH5 ]  }=X-DWO?eY,waL>+o>d6}(߻Me0:z(^j~eʔ)qըQ'@o(@{"=4Ap޼y#Vi ҙg)~g;8S͙"fy{dTa:J'=FWCukN+4:2{lޔ:~$E:uB#OPv8{©.x&@o6[SN9E^vYsоwF2|  )/:L?6|;Хl3gΌ3 Hp39Yc Q^(Nb{2BwO~l8kcn1=b'z姏ڍhx#2ȐnlܸQ;|qcQ9{lC17xכN4u07e@&N?t}0oZPukʾY4Xhd%yiJ`im۶I #ѣF7qՍ;B5?GY.}Ny:/Ǐu쮻իW\gjI5CfζnwRlYpst?k#|*b_9)Mi(t?x9d3@F #g ؇Ӷ\Ě鬒 0v8RrY L{w.4צwɫ}j&N/qsC9@,_8lGa!khm#&ϒygǻ6}@կ"> fLG ē/@F #d2Crc3r~Ǚͦ:U'ry axƬD9bǎrm ݱ#jLr@F #d) \gF #d2@F # d2@F #<اwlq}>Nr.zi-Z4(wl7sYĺ _;./$au@F #dF'V/^Y>Y>@_ }&C/Xbg@:ˢo|Unh8= tˮF[{˿,KT|T3˾ϑ6"W~Q>s?7M˒Eߒ#·>kDH>B'ʕo@?{ݷ˷:EՉC?d2@F #Gw|ŗAfc]rnC_{?|SɅ f`k| {\_D>rzo%VV(4N{Juf Wr6}w@{nɎj ws&ܵ[ayxgi-oM,]no\ʨ2^%dmhzz>_$_ޱZ~t\?"ӛ%mҰ61_E_mê 9/+|y:R?5|Ku7dϗ[e~L}T}[N:_oA۲oIYXZ;I_gsY'#d2MRiǰA ߳*xh`W} M͏_- >as or\rD|>4⭨=9\9MićDk[|\nVI/|t ]MZ/VڰI6n);mQxիHEX5lLco.\( ^m"ޢ嚯}ևIETم߼U"_|,v+H: *_چ/4OfOWz\|]-ҋtgw'?{rL6#bY;fv& wrX*x{UC Yq;^ujum[,w ]]n-\=Yb ߓ_(6\͆5vh[Xmo_~ ؋>a{]"[*m2} z/Qtr4~_4ɕrїʽ(_q./wʯb.ȴˍ -_ɻƻkK+7#>፺$n!#d2"yoBfVƞ^Y?kX(X.[xMg% <*Sik/R FV^P.0`藢$Xoh>]{O/R30޵L|B_x7oByۍW_(_6p?ptnsT4S_.goIo+HQ.|_6ݲ :i\sgP~qa9/>%G_TdoXt՗=R~xϺB!].-?xHϝ.}\/kPPu/X `}Ee鯓*/k~ FrTv|{E2__.6[+oWO7ROȢW42]*5C.O]Wˆ.\n%_B:xo|r$o~(?Qk=+cղiw*r+CC_3N{\!|Hߑ_x.y⾟/V#}軮S5 eK̎w/gߖ6]/]ܵn,(_tMWM7|U8 HOe\[ϟ(szW9x*˔fz_ܾRzˆ%.z7AZ9Y^(ʍ(wR6-ȿ[m)5&̙l|^9%'HKni>W='dy_ͿOJǎخZx^!s2X#Q/[1(7j9zܳ;r5&]H^4J*fb4Na~n;+ɱhwL{~-O}.JsքgT޾j4=-{'Y+ln|qHKSWmzϮ["$-ʥ?\"(|N<#c"=V&rwEƎ$'y2 a}K VE.[/r*t99SһYx_uT#O?GA(!9ߍmHAVgm@F #CQ]eʱϓ"ٴ˟W=}sj}կc0xc7lw%u9Klkm7zDF7B@Z uس+/{w?xpxf@^t+׼]-9'Js9D cڀC]>ipe ÉL c,dF^pdenu~3@F #x gu5eb>QZ+vY`dF;MfZ"nѯ[mAk&yݛ&=д(M~ԁ =ɷN/7M!qn>]Ί;;kEy׼},2؀*s/Fk{Bn?ʍA;o]=پK:{qy9~yd#^c +e"Tm7ʄg?x:Шl wwGQS&ȑg$+&cϔӦɘfo C%>g̔_!0d%@).н{k>_yC!X-G\~;}E/У9(zdCdڴ)СBtܾ]ϘDK37Q*ji~k&' (=J: seV4omYLwȭA.y䎕2sh)7)k?2r<1MtpLX(0[K?2x{uI}&Yf\+q q7-v~܁d2@FIB=ʕj=dѻk J.h}pr8$zKe٫'7&}=;HpF,IxptU>dRLnG,]xNynZkiX9sE\$ʽ.joN;NN:9qRi=V_urqv t0 70vZ$_n=,#2K./_g*'Oŀ@o2#7}N>-@o[LRab \ڰj[A7bxgk&uzW˳g4Pr!e2r? )zvє,`k~@$F9cE rͽsO;_ |K_YLNdǿ$ג3v|:Z?^۾S*2f(bO<}عxbO ʥ7 ;ƌ+z|Da[__un=Oz|KSYvlw_cAuȣ-x^}ʨxoj@S#ٻس-^i8Q1r߃ɘQ2$}ha;cǷHniĒ7ŧ|DxN`^14˨^{3WƷT䡫Z^o\FC+ 2@bnR@F #(MmcdLCt`IBJK~^ꮴx:wD_j_KDj}Wx|E3|n >],i= 7-{Џ>Mҕ68=xtR޳mC۱@dVtrGg&EoۍnlѾkl6 =;a!-[x]MXsd@$-uz |"E'M v͌ZzِŃ@0·RNFniMܸn'|b<m} x}ڽM%Iw}~C:"T_L%`Zlv)/FŪ6AH |#O!*$dd.d%4T缴Z)k̒,b*^-b#\/†*YcQ)P+|XPhᨃ)@idex"|W-ITBu&/kT,!|n[~DQ*Kʫk>AikMh,ƅԆo^|\(Cb|UHXAW3XCL]>0:.A5ne 2?Z@UH X5Dz슊u ?0Ynjc$:f+K}%ߖxM|oy$QΏ4*h7fkB@?PA!S c w&IwAx7CEM(D\8Gyix/R8)Pu Ffa(TǠ(q&YYNw6Zl@^Y;"͊RITiǒ:B:ndV1uT2Q?1hqSƌ" 'zޖI6wlU|*ڱm)Q(Z4m4~Z3 8ިbfF5T o_f[Q ]jT+Lx$%ZM B?aF#biڠ< IWQ]嬘s3A.3&dŤث#Hu{:羃Hܝ SU& ZYKUIz,bA< Kƭ]F! H7m9l=$xW~EYP܎hZ8~ЋkT$WpI*jtoQ?r A4b֭UkKrum t٘O@$_NJt dK!Qe@FUDQ~Ruu У7hTilK! <:YLPH02Jٔ4SdDbV"ZT6mDD]!+JF̘,IG6m6Y)Hi{%Ap2(4R+@]"i`[i>" DU;T]|u.-O"2SuB=NBʹC%9vG3@KiνI^QGA*JpA؅&t/mwdžJ݄ 3N:eaK'y z TiC6hL h<˹^2JWE&Bm$zz%LBG)siYI:3z xJQb,7q]!C Z\~UCCg@ȏ]EPѢLSz.Pm_7ٙ jN7j)r]ANY]Y\>mQX)GT :!R5FgY73)D5IbY!qD1UQm3,qU2HM!JB t>MH\:5 Z 6J2)Z54s&<&zl&x `ƃ]9aPa5A6gTEj~+.QRJSY3tyR!MMD UX`;֪I6ft -gm%,rj.$3S:Ɠt0x olPZ/K'P"(B:%U#ÙVKRU@"H|fJ.!$aA.7M\aϜR@!:^?1rgfd.#0y-rC3҃L^+ P[ 5T!`64Ta $b]?fbQr0t5"_LYk(e)BVh$ ڜ6tds/\1M*im1&=r̾k-ҺS4 9OYehA8!E$jBRAu} v&TO7Q?v)vnHMg܏ =_)tYu't;{t*i0* }K<StNM>D[S6i ["Mr)j"ŏ8Kڋ2Ev"b'HV1uG P29ľUWh"IPe>u6Y i'<G*_Lَu^2{<Ӷ+C*Ѹ".u?>Sҭ7sUT{2 s 'kZˢ %9PP%PFhmk9=6=֍IūNLMOLW ZF)D"fH0Fʥ ni>a$H0[M3H0]'SdmP{̳ܸy`e>FT2E̤QHL/*c"ëS7=QN1;uTD9"@ipY}nj; hv1Rs)Ɣë4T6+sT$g)#0L۩$v4L;Jiw>whQEnT fA&zE2-SZ!EueU \g`yZ@2oWb3 6B$mDnNˏ;Dw2BkcBbVQaL (f T=+Uu"f#LJT, 3;&E:"QG+1\LPyup 6'VFPjRb̈́MCY*Դ,5]%`Cs9("5MuhG;Gw(׀zs th4isDp濄65<2 }Êʁb ,VVn6P0׎T1!*m>l7Z2+MrS7p~h4hՃymcEMYmHbE0fPOIm2Q4`ЙTc ?jɲ͞<Kr}*Q̫BP+qgq/_1ۡvHJ1mltt :R( r9خ !J ҧNIP,$Mt}'x8uFT@!c'P- 2S5惛f!TdYi!L\tӌJeص@.}}/T&%A11C&Zb< J僘E`$2..P n<-NnT! LՉ YۚRQ^ZtIHΠzE DŽSڪ|%)f Q-&+tʫs 1pL V{(j lXrfAFrJd,h !0+y*YMS OUޡ|6]iD/SyGRTc.:BJǔaZ1SLX!C^mHi_s%3YI$zB$]U7j/t]RB=ِK \y;gOw -pvJjQ^d&BAႈc-_OC;Tt,왕͝)UUHBW :1t504 /҂BCBwaDqU |'&0 VqzqI# [m5UM$4+زNd1 'аAIt@Aܵ<EmJv~E1/CʨrdyPʑb>h nȱDȘ $O)o "* ( "f.:q 81SI~F9Sui竬T"O!^0 Kh6^!kۇ%!W,`݃D؝vzNjUU:3c<ֽZƋbi Ro~]QkHs@/Jw(_j߂=tr&9 ߯45ψ_) ` yD '@A-A=} pTcJ' ABg@ۗ [ =hN\'@\9Bt&S(Ҫ2$ P #u:*m[XaԎ!8nL&\c` (fCp5f&!v`, tX֜6gU?vQ). t@U|ǫ*}h=ƱL Xp6Yy.f=~?Z0&%\ڳ#O U$S;^˫ x%$n29y,)m\\9I%o Ɉ]IOA[RR.mPiCDJIAPb~,=RۮF4RJgݥ d&$seSX =_$[̀VE P $Vq=V-PkSEJĉAa\7?P3񪂯g'r;tV * v+<X+Tyr7.g@K@rQtC%]Lc˘ ;A=% 3Ap^hœf˶VoyzC] 4S[<ۯwbf3L;_K¨u ';M& 3S"E(^Wz}Ge%'- IDAT+u6B #q\a-jhq4Hlr#{I~U"P0.y++`BC۵2lʥLcCxʮv|Kp=8&x.c@+<LF2~6JQ,IpUŠf{i>Qȭ :| Q,t5Ȩ?-TFrjBp#5y<]c)4ruq1$1c3c΃D<IOtA7?D:*&/p3fQˡY;lf t EiFn֘^ 2&j8uZ ES.7s) XR9&fDbV- \Q yT 6$EE?M9 = -#F]@`* sL;Rp0s'Q>CuPA 1#' vJV€w| ji&eY4C)E)Jw&bWMHlD! 'rVRBdzćX;S:f= ciݭr*#P`ݍ- 0fܘklW[i׋[޾i|cf3C":bbŶ1PVƤ"8IJTJ.*O0 ʒh6 :8KzW(lB̈́r!Ì`-EIBM&c>LbTp^S i~dPXR5w}M)lu<(6&jLj(lQKoLR0 m*Vs_o17|0UJJUbO 5#< FJŽ}f I XRDP{*iNl _NwqƵΧҾkܬƩ3\!Ҙ7uUPq:n9#dlXKI>H*SE^%>z2LG:6i:̘]m ⒡E%c͆X c) Q vMϺkwYk>:vi Hi#2B@wlh;$ `4@tM A)mSӯYfZ]8:?8y[6130ض\/ʮaI/ᒟq9xO"B>]q,dvG}t_s,URgܱ*dq9H)aG4~ZXtacm!' G!D断qOPvb~47>3bvCl6ң^Ğ/!8g=.գC<>KN~kvJӿsνvqX { ^f?T?po}Sp+zw*㮪 ɹdCJX^,ZkAUq%!ob3@Rͭt_|&QTH }e8vq\k N90&Пn L|AsIkI.nW4hΕ` Y38W3⮫P'k^MZrq54KӪylp| ]>ό+气r"NmIq)el@0`:u#Q\Hwq(s<&/;O_^P`D'3q&[ =uda T)"R<`Ƒ8v"$jVt ctp9MLTsaciLl4EHPCId|Պ*\b0Wlޕ™yj#.H=ޔC{KcWύVka+ÛĉpRs`0%~)p;up}b|{ ޴!8Ľԥ7bbC%Aڳ@S1Hj6Bl/ac [c[8 0W ˸hQv8 nPiP~(mY6'[Dz$6WLRL@%*+ꀱ eC#Y($' 4FMRCߝx!;k͆۾Ofj)zbu* (RYN/1 pu$;mÁ?r7pyegJqeI S>`Xm8:!^:~pMWu3b[`c*WĄʛg>5hD_\AX5Uw,%NKp\>0gL7~1>\0;uxR@ɺ趍@b: U#}kЏ^YǝC&/dr~^'K͎^wBWnL j؆J`"ZެG+B8ĕȶ] y(@q3M-56֝ @ɞl8ǽTS2&2s#^x]\T p}!ξ)X:191ӎqQq-D~7Zr&l4n U,l0 ?V{=I{ } цpI5 iZ|ű+~x8]KAQ%«s^\Qk'%g=Js tT;վ^Et>iG)@01DŽX+ڀy͇_͐sWYץυƋhCEޠ WE]xZV[]|E.^Oo 8̗Y垫e%Uן~M}O^|WtC'@4y,g=3D XسybԧzNTEF~%j^t ɋ(Xǹjb&d2CGgؼ{ݣ ʤEs;1#C6| 7KҩvxJ)A_ уαsqk[J&pԐl筽ga;DGՐ} vlh?옮Wv${up):gO*9:78d_V!r<=%HoY&PGkwGY1uBO{g8WcG\9*o̭hP۶qk+WÙw!]1&O3GBnL 29ƒɛ%7GVLZ"0u6*~4n%Ad hMu%d ށ'zn p{3Gd2{B{e0rsY|tHKJ-Ӏx,ewa!(h`^P(+{X ∕H,a9e3-\Ds-~v%sn 00x@-zmoJ\9=X5Soœ @Sl=&W7?$Waa8f9ӆQYm pET蜌G'rZc̸quI8~Y .40dsS8l0;,tڠg;³&B:汙x_3&&k $v);cp8cTl)TWA`CSɆE 8W`<}A/>&7|և Cl))hWKS{l v߸{T + `:і|nZ f^F٘jk\'FqΐhI#1mM '!Ǜ#=Oym―{ !Orqa Q^tv$1!F:;gdRei-.f9eI6! 3䕤e9%cVr[89;UښH }[}O9A"_HAɼ]`rrvWm6tA=O@EB-t1J sR|-uf%D.tµ[}60o IP0#swnT 55W5l!녈`ãW;[9P&zH.5;·KS/ĻMKs `Csj!JxYO]靚qć^dh@ dޢܓ׵dom+ςIXr1!#MlX ,3'L0dZ'=xYmN臇b |2 X9 wāio5:;sp%:cvo&q^dEj .Gs|j'9g{SLVy&~70>k$H>2 %m] :S]3_X d!cZ&o ޳WX _*'vgCwDoߖ\IݪQ𳆌1_zex~/@L8il|1jb<7^x(. dV9%&9h#xË0/Jc+Ћn3!8a *uRsm!B u#Q8obagSwW͚c^'cg[ydv:}|c馷l^嶽4GZ/ZtR>WD;"U|JgnAEep4ls5vJpS;ڙq2KXd $ZU@k{=HۤPso2!6C}(;΁wl Z$'ގۀ=FBA c[%Nם:°-LAX?2 jZG9ДY&$?ئ p>y%k].k' 5xq,% v|^_3y*Tpzd*ӋRј6yK?>?l6Iψ.G_'ml];'>Cuavn.odZ1{||v?wİͺ024ol Ne toFW^6bYBjPӏ5\Yڽ#c8k@۸`۬& qy%d x:T8NID< DfSCdcXat]Țs"lN sA1\W"vO\K_9570inFJaŋ=ռ>?P~5owNFe'"]Q+T%zmG`%!'\muڈ9x̴P݆_Lvu=d,n\vkve{~o.xJbvv9K1yaQ  Mq,Si'r=5q0|W7hkę!c_C9HSE7YL'TOA.Q8L#nt:ܡqq v>j t;u 2[’T(ޖs3m.K<{*R mS!!!4(9 hj[).73jǜ?Hʕ l·7O v hHOnCKc} vLۣ+ۚk1Fe/7մښ?sS/>:WI\b\+.I<)(څZ`o$& uYWd/W7w:]TKHAjaß$PiE b֧a)#a0eÙdd*8qW4J܄ߨy{[7L"ne 07e};ء/u Ix30COה(Yt°gr$1't<~@3!O+=S\[2fG]F9AfauP^0aKgɄ`<Lfĕ|'[C8ںyVŖ;5N&?ˇ&gck3hGVeπ0{ & X}7cc睅˾byb$ݸtbi->[>ŬwNTh+,3 _xQ+f"> Yu|12UN$u P"};mfэ|$/ %k:qnl`=ȐW_Qr$^4Y0I^w䟅.eTf,eؽGxђPt'QK͸eBe0W4\#ރ M;,` .^ Hv5&xf1cB" +FXJ cH1s_<' IDATK&QLWܼfn ME+tbI̩[v_=\V-]AGK [}F;}OqoD߃ rW\}gy#6N64*b޳:@Y3!nZńY!?1֘>yȊmhSJq^VXG8|#y .R17^_o~{{{?p{˚vadOzs2OyȁSZ 3gSؠw;;evg鉠 Xֻc.4Vs5Bny#z&?71y!#2h`rhxud^s x$ o^ָǓzkM bM<"H^ٿA:unh%;0P6$O !J(Y4oܲc5{?;v ߔ y~k'mActi^LڪǹKyTZ-CiC}faЉޱ/%ar5Sl bA>/J1V?nYgt,ݟZF E7|*,u>P{ 6ϣRC46QҚlTM%Ѿ2vNv ۟+6?aS֧Qܦ4|H;5-پZHs<}\t)zjŇ0c9ˢ}# J'Vpf3<6CrXsI carWTF ff#0r ҃ގ+.2,<ϰgх_ڵ$V5.ٷ ~3`FՑ[G stݲ58:Ρi7_pCrg71&.vP[\<6сqYrLh:KikWQy z;Koe L~#Ĩ1*4x<^wBuٳstUˆfj͵wWGYo5D昊nH3!"ˮ$HP'y6l,\* 5Xj.\[!:Q2UG\}gjɆs?5iί֕0 T8'1;#Ys*2~3+!XlU֚\vtx(òbP0Of` f4]IƩqjy9R:R:%^FF8hqS]|C:6XmnjHqv mJ@8l]ih,Gcߎ^BۤeȮ,e+z%=uShGqa?uL2uGY:g柉9T )隴ngѠ2LaQzk3ܩK?ܾ_ʛ|/ß|SC=coZP0>3O u:Jx*`Rvt 5i+z'cYFp}wh}8x֬0^lS9raKCu b KS{{9&h.@G; {5|f BTs{9{3Ek 1L'N>Z{[iض 00Gy )3| \"m~Cgk 0rB [Wo&Dyf-l$169V#!%{f "wFRy<%n|al&8? M|UPn(x3uFkz<(J8ɕsɦ~ ANo,rٽ1ڳk5O،pܒFAM5pxO{Kyd3ul:l3x:O{Jbo&g|+_o=u9g6EExuɗ{C6^t\`9w}>QsyѸ~G_^m+"Iy/? ^[`80{H|[!CI'ڐ_WuGW.t?nw~÷/~/﷿WW^9C$XkN`ș-%UuL;  %>֐Wц hy “t]:a On;LȣZƹQ[LJ,GtnW?5ūATna,)xHˉH KI/%.~eHZ[S6Ǻ '1bX aq'=^2,.!RI.Mf0!c8SE`vO2fG޾9/mIel|ȚS|JEϧa!Ͽ[!t^#zmfXFqc7tu?5\rLs+qȵ7}g:6S 㜼38IBS9dO!́JаN#.b346 ҟ :|E3^(a%C|΋k5Y5Q8o꓏S?۟C#?KWo}wdЁ)G5g؜O%rZ^bwteRa_FԘlw26W'~YGbLÐAk\Dk8(33,]`UgH Kkd8AO kB*7Ch6Hb ?`|p,&Uϯs@m7M*.O6S1y᫉f8O'یI_'vv7O>}~T4|L!fyeȧ,yYRP-7ssD9oH?cJ3 ފ}"t{+6-*>VPyR1R'WMF$N$gs/puQ^\o?hjm%xqYGmfJȬ {.8=/ `gT/pvD 59rs.8+݄(s>S|0k.gM{Qq+$cS);[/r<ꏭ n}^x+_{Mgpz~&=1tDK.|*b| 1Qp f!G\ :w3"edD.~RMҸƖwܸGWUFŲEAw44o^9aϐ\Z jl{ ++)Z)Xɞ}X%Ajܢ k'Jh>w濻g>{{o|o|_|ʷy?z{)ԡc˝#`ٕޤs[=.cvliљb(/@R@0};Iw,/4FO~A#UI $h.wGe3s5"}as”(' *:`c U=ӿhg+,M/u9Ƿ"fiv^"ʻ\6ਸ/CGeRU9ָV0T*, +uEIp`;bq=9Ń($t HLX%O7Bbʎ5 ,~I8<ְ'8R}׾tү|1e%8?s{Ӌ'^O'Ft^rRs1U *hTj,1LjO@pNp5)&biUr}e1u:J[lg,øpK:/+ r>4́^K:h=E6Y#1Gj(r L'IY9q5w_P&"ٳC3d­zEO"~zS*i\/F (Dž\!Zmak uX=1f;un_ s;Qg,d؋'pABaK/'6)g6xQhh^>'=O'5rxZƼMtZm.@6F/q,FFX!lMsDn',W^>(FPs˅,3sZRa<EF쫠N ~!c6$}Pg]U,jӛQkSf0=ڡ9ř@9.YOp 9Ԋ>̖y¹&m ag]U(|dIZfX91wa=-=|$Yu lWձeىy Bh!+rKQ&# OvZg&.wMN'屩ޕ"e4+3F-W X3 rr;cUK9nMNya?㬥Wn<*}_\g Sag>{?uf_K!}xkrժޫ?׸eryXC. 5]Ϟ▰e@֣]zspEXEzdrͫ-K~mfI:R΁$~bL/< m%NMe1RBIFH: k"E ۳z9ʃwLzN#C +z[ؑ'-a+yq[PXSAzRb G27ȐY=H8i[.. `tn#qo|y}iu`χsZ1ų;}APLơ;"#ʜEi( <<6Ӳ\>'dGl'Sڣld 1r:GHSՀO uLw 9+ƹ&Jŵ1ҷexݍL{<σ[Y͆f=4*0yA<[Kfr{z6,w{I>ww~o|ۺ^~k_n} KnT-s;'QdSOOmið=XY`ݎPQZOڪMoS0n[r60I]rh|lbSƖ(?!,8p1yVj|h CSck$nJ=1prЖUzrO%˘Х]%8_R8/1gp#&Cg٫+]'x67gy|tw67v:Lqhf22ZͮgQ|ZَFl4r&N;{u&F"3+ybbؤ) 9/=q&^gYLKҸ-Zd|OBtSaXz=dTPSYـѝ`G R\U~ˎG^El@lٕrPQ˃V v56)/,a30s ka·l25dMBTh\wXvn%# e O1WHT^:I6ӵD~—y ?6.$6og{o(%y/!3>b i-|#c]b>πl1upZ⺀ DZvԙ`63# @=qq,`΅u&J@A"Q#6؋ڦ;JģQ;n8oA]w]h2I`r657^%pgC"GE7NdλZI׸Z5c`ّTq刷B1uO߼{>p{W_~ C?[C?_ODzḱ-yt&gן2 4SKPg@#$ړ:AUB~Q1Ǚ R퇊nLQG@bG3w]%͋bClLlwNe PM' ΣǡX)kxc^^>PA[N){P7r2)'k\$ =mS!0?z@X^ji"ւ<+n%ͧ<3Byރ8-fW[2C_ZyNdU .\>LFB0YvÊ2CƁf`ԤbM/B fF@(D2>9Aϗ+y+|Bi SK<#c,x1O-3@O? >iVwgy#xד2$wʈxZ׬ =ĄA^IFT6sかΧn5;Lb\|b'Mc3gT ldd"F']؝ʻWOz 2{nxh1YN`yM\+<A6:_Rzn zQǘA`o?>^ޙI4soWh+,q${55SaVt&5?Yx Ε F Ȳ:Jw67J`/rv>/'w2GYK_~r{AK_}Cs3FRHV[eQ}/y(Ӳ+YΩ5- ty߻_}5_qʗr)})6cq{Pe7CƨabS[Ÿ虭9\IoMaK~^o}#;=2G䗼V?3~|{w@[OGThU]OHK|r\L %$L DEaYҶ 똢0 M‹䯄Lf<X3h\= c/BYgxӭv׉Y0ZVClkrܛV+hj2Źj;`؟SE ;v򤀅_Ʋ*vsTStѾ$SdĄ.nWfa@vfd(Kl{τ2'ѩ9!WG cY]t|KHƠ5/5 WEB(` ~EQ%sH͝@ a["l{g6*뎰:an6b{V_ɢ0A_c'bkZ֝-?_F?x1 +s 7Z/==H'۟c?tr? ?g% DN3&5rV/N\믯؃ط3ُP׃[zN[>`/|_?{Q;ͷnWbOSϐ|C}}ut+2CAe _/Jɼ~ V.@]7\a#'cBcC 1|D8hyBⲞd=ú>ژx7KeX&%( fg[Z3^DSLN8LUP52"9(ڈmmsW +\ 0X4.PYgi9D4biϞ Wn<~Wp<٤D{U^^|^埽Yޏ~^K$ʷɝ,=^s)% O@ϮXj%Ee* G${H͌\ ~DǞ* Z'+̄J-$rat K=Q(m`nGM'&,|z˥Xޡ%CYWgX&1K' 3iE:C;Ps4E<60]9 ދ2/Ob9p DOşn>RY  ={u|ӌ?ᑨ\} REzxva xA()yR9I]g yp3t k OP%+wsH1y|[: +jrNxjݪџ8ZX5!麯Ak)dC ?<-8cQ!?' bt[pq]P"> ݘHm{oX{qTi@0.?*߱Q{X5k/B>aon8*NBw3*U޸$= g1#P_! ԊߡRȍc_7,uIPMu̻uS<Ϯ8 k"'Ïn_mfxO>|bSyA L~ccFvzL9-aaRP2Fkq>sml5B[|A޾[('!z|2~#yQwJ9^$2Cࡲg&VN/k530㙤V' <}~ }2u7\#;_x /KWf&R˸6hz}qmPYߩ/Z1,S?VI)Yt;v{a ч<)iΏ&szƬꁽ; \aPDlz(18׺+EɅ Po$}{^]gX#ۙ,xXޔ+B^~_Wh92q}DDZYQpV~z&xa{|m_pgGӻQ8?jxh:l-}rԿe!z {ut49oK)Z>o{;$9WG5A -slNOk)ܯbw#/KZ Hu>y_}4v_0zV/|5-CR5I>H^{G&E>tIEn;cLwF"G\2xfp ` oHmW05_ss*wr0{7b 2, =`nr@q];"u3 1 ǃi;`}I^?]2&׳%lq?FL٨50J].ິ/ PgìZNkkqmv3yu%eԦ҃gbB}^X*}G8<[\㺱OȒk΅'"cc[-'PchDul=.\]e*LGlzp6p @;],[+~[ 9?Ӂ̈́O"mMJnryAޗkv4dLe#!}mOPk}tyƨ osAfDyIS|]?;?T>!_K/>ߧܪԐ7$U/g]򈪨?0mv\3+4Am8cԫDBCsk'zT*=73a\0B{M<|y>hc>0eX֤b ]<c$ D=dʳITg=#ɹ$ӄρ !LmP6dt %>QŸ&'m4o49R*bDj9r9`.R\L?PB&mpy=<䚸egG]@<ιu_.I|+́x*:V6$ M*H\uPK7QB>رYQ8xcSd1ScLeURf+ᨣ!1}zCV빲ӬdHmnY{:e"A)xhWapHS>~o'_;9T|A+~@M;<ٟ95FǦ0 cSf_#7$"f$]}Y. ]T^N?8j7@|#L681*A[ xkvWؓڲ RŴWƦT@Ƀ:Z`:+pω y~~I~勯?7~9ymPQqqb : -sBNc-}Lc˳f´a.6ģggX:^7SWbG])sbo~ޞ|~֕륗nMI?_7>#/D`}Sh|dݿ+Le־%< a=4pq-@ܖdc:}l_B@N-zf!2%#ުyh" Ǧw>y>R[搭'CRbܬ)=W=~<ޮ2gMc.n {nȣd:[^HP.'w}xɹrT^\;. SeN};2&obQ?ބ!Eی["e&znjܬp^UJXBLe6<ͅү}y=ڙd-sjJ&ie=%f&n=Gxr}ƴ4LxO},^$$}pLRifcc,CP ĸ[b&w+ׁ?,ly2BJ9nو1#㊳A027V"4dɅ-ӛj**Eh3{)lD#A)߮ln jmfѤfolYd~ބ=;h6wzCM'N}$] {.f] 6zr)8E`( ?Ծ9֜wb ҝ"9T[( r`r%XY\F7eYiGаvexR1a/ʷd=(jwʗktG揝=9 IDATx'FYiP̉%fv;A{7̒s#One$p !0uu9Ɂ@S ak;0j~nDB &ofI쵊Ksh\ؐc22K#獃`{N#V32?hGVs1|w'9~W^JР% %eƸ"]65cC!v3Au_;ѐ F#/t'aua%#@Ķ{Ju]93Znd']'O|{?GCu~(}[/س5] !g:YЙ0!a o)Ԍ3¨$g?`8%P'q|Gĕ~0 |y>n&Z*gRN=Ex2lͰp=gfu[51gDD:B:43KH 0l1P9ӤɎkbe0't3h8itpO~㛇?1nk*.!r;:QLN,"3߉%~c ʳ);!z̳kHPp>`ܖoO^xWoo۫ow_}s__?_t']G>o/?_wys ^)yKX}~d't>~rBzL]T,_L>D\Odط>-5 erRCW[C՚ka*lWanh%l0v~]8sRzhAA.C'|;ӠS_ksJmzh0ujx w+ t]$4&Z1VT~>ܸ ?Vkѯ|Pէ^ CC n&JN?9T(A m0b@]'j$vό;hE [F6kVA8fߡ#忠}-_ {&k k!LT&w2ȯbFpGV tj]?iLAm#> Az1dc8e Ğ2jI:u;:&st7ew9Rc A\.`G݈pG}H g#(J`6\sx  >Os x]tEO iXB 1pnM(Jrw:tQ%'lH.6r~/]f u8p!d&)Yh%C ' r!) 8ossP3d= aSruqPs ݚʻO{G?ڛGe}sN&229B JE8`QպtY媫NX ]U]F[VDEƄBB朜sz}뾞N]}w~~{G>gA™TY/xㅏ~sz[1ks沏~ Q_G^^\~'uy{>?|[x'}}zG&]pm_hҤ[T3dO|#|޹H~ң/}:c'MoՅ=_ *j GOz#;&ZO.ȽB4pV˻c~}?f[vwk~ {/?Ɵ<|.D<<jVL9IiNHtɄ~KN}TX#`n:r9G|>>'ޖW)ř,'Rɺ"7m֓΍h'%4h; :cSءC}o$RVl cia0A :wM^CtJ7`cl 9m";X8z-xuc.q5`S7ଠ}Y(e :|}B,ŬͫÙsK<̑GQmc8ƆIwxfāvnשԟ/VL!|[]2Gƭ7kNw#n>_oDXbCugn+! a,"c2t#YҳKF#=$DWT2)9ր8Tf\1_azQ\ fCJК#mBX2ξWA_.~j,y ܩHw*Q/ XM쏴C؎ OR;NJx @J#'Fz֊Iw`!dUO>Ό)Ꝋ_ LEǮYqԸ{Hr+DsEap: *xfgg=Qm1ZL  ]B!?%Ұ`(A ?nRڡYDxh O)vqҿn  }H{s|s w<2CI;N:Hv[g=mRkΩ 0@1jQwLg^ÙXG%sH{k"Rh@ClV QgGs.=1Dw1x'94Kqn [q6U4&r]T~SF܈7$[n]tôˆhɘ꯱mub (mc:}|`j ֟jftg0ܱ$V| /ZW>K&ϟnk l{j]y \\ǟ=MH7(@}*]~W~,{_Ͽ{N\U|'+O- `|'>~Kױ@F~Sw'zE@/_"gO~?z%)orsG@uktyk֒i{ӏ [z/Aoh?pȽ|ޫƫ!)z+r6c7{6<*=ttQᤌRvNz$; )غrĽ4夺"\Qnڑ{m~G^!g$[p1ܛ}hmqj&鈲b۫W#B)Q͍~|9HwiX퇏ac֋S9J? hK4SR"7 l?F"-?4';al |b0pQ=)Жop\Y1M1 $NЍ1RD:wi\_=I7 ׺p7z=Wy/[7!ꑓ{l''5a6sփ<#"Sy ?&Be`(a4g:m]pٓ[Z B:[-kӹMʃ9`+ /oQSy?u fmy,9472n7yֵ}ڦ ~,zD3K*/ xt<2"NDǒcVǩt\Lpz G햭mݖI&2怋wx8rrhV>:m 9B ujLK:@\Wێ6'F1NvޯD'r^AX&P,RړTFR0 Ǣ"ۼ))G^tcGO|^gJo7]~z+>_M_S?>߰|ޑngW;gzCMPBˍG= En@NVo_|LT\,-|nnkޮbmPs>Q7UЏ[?[nަ}'._^q/}>P~G߼iE>!_m)K,¦r\7#y=Bmi֩@h?I=&ejhp+uZ> )r7#f(.i=ִ&9?q0lF擔A[Lڨģ[VV `훻|&t+zHlḴ Rr58Ģ= ;- UNNֵn3}nk4"kBclLj>N'rCբkߣrDz`eŮ ˹UO>15E*a,kϧQ(+rMނE֍G01}9Tvwq^o|ߏ> ~ͯx+/!z}%O_ŪSnoK?tKzD7_aE_K>UC>|~;^ӗyӻܫ>+_tJ>=u򳗟=뉗eϽş(9W~ׯ}iz%a/߭zy~ݯσ<˯u\xk^vSU>ǝoAߪW;>pYE_g+쮗?q{TUOL|Əϧx_пxʅt&fIKdͼ8OSr3Hj z䫿94X/HI@ڜ9MَG jOڽ)تLV^PEpb!7S[5d#+n<̟5q?.U]:u2#q!4e$kCi}jg+}AGT4K?[}iM>8d^z]P Qp .Lɣ'K'ɲ=D\[nӊjiRnll!տ7xsTZ(##5]XfK{g!Gjo<q|'Q'<WQ؞FG{&3YӠraz[*V8$`;rxo BRS1;7 SPä4ؤl7vr ޚqЛ \69zuΈwd_mǓ 9"<:8*pd8d4i ؂vƀ, q=TD&TNfkLѪWeW6? s.Gs0. DdEc <'h?\\1$6'P#ob8;s"rmϳjgl6sgS7Atu^[zޯoMzK>i#'/_#?ߑ>gk _˗mGߠ3K#}qx?4@>]f=sV9sy'R.^_>u+Ыoܫ|!3;ޟ9s^_9kA*o[?py?|゛^70^{.Wx'= P^Ի.[~=}? Rx} Sv?ψyy/ Q}{~g./\xuOwi zDhc,Yg2&۽Z) `>.x NPpsdZ{˱Aj VmCuNyH/} bxGD pvƪUgs4j.0ʭlLK݋mAvxRRa!*nhHѳ9 fL%]m&2Hd㱤vWڵt:P&16i#EՆ=TC) O(3$37+&6yg5^4&SONd֟C/9Ʃ>kf^aa Eҵ01=d Wb>1~Z{kd88Au ]ȬQH=,@K2z32ޖŇvMK:D;n^oՒKㅴ1pmbNAI: fUukO Ɖ+W#;rp^{:}$&~RBg&`wu e9VCYp~`T'1簓ւߧ4ٝ^ouƽgCsпw߅-c4RekxD0|FNsBotl!؅junq#ޯm6畡jNŨ6.r5;1> j܄4vlR_ʠ6NMŚt&| ø\˜=Nj\&xI%?!oкI)gN+ZZ\`.[\>>M'=Ưh,w_wsXG䕑||.ew,;|_cۺ蕏c&7H:oOOuI݀}+!I y1 _%;۲ҷc D6Fozv-e9fsqRGLi1vzAFX %.~Ĝ㋋ޞ/f 밣Var)&c9*XSOJv3u]w!\h?3oŇjZ u 8@4wc+J g;}]MT7h}*+ Iekjyĩ;.$8fLj:xh IDAT[qdip6X[\奋G_/oJDŎ{lÖ5)aBf=Y\t5'nH)kx{>&Zn1cxKKxz?Ƅ2Т7Z.f˹[ i][2gy25YoσGp<{z[k`nFK@量[xホ~f1youqn{){|! - R)h1ZݸM@} bd\1qH|d9d^L:_.9Y'flʱR`ktR_ږYZ),KϢ&z̥̞o|m d5 !QTQGu˞BFߌu]Qaa1/eZt6Wz6rnyA>^Kiq )[z@o\Z[& Nۻcֿ .Q3b.;0er6XjYTycR̎83o|^ylݼNO{/.2Z}-\r,|ǫV ]@Ozm^M.AxCuܶÏc>_W~w6'Lxʼ]yVz Շ<@Y#Ez^{偏e7vW]̮+~ScQSZնOٺG2Wou7>>Ode{׺prmC7\Yj)LIizx:r)C+C2 <a-s@;/0uB V* cBXĽA+DBDN41-9\c+_QR#6񨵰|@o_kNzUn"DTGndMY=Nr8EfrkvVb'"].Ub% >Hv'kyQ&4KrފcN?IE'fh 66B{qK >QL=l Z+xO`ϗ9re㐸| i,mB\ӗwXMz&;=*v)й0fnEÊ5ƥslcݞ|1Y-a7;0=}$a1OMA{ࡋ mMUǎE95@ 7і-Ys[9JxUPr]OImZgpF޶b}+(_ K $c>6~Ap֣,@XMwd\}Bv-`Z\ku!ad:4]Z(:8e/\sދ.{7'_pL#8)|Dl.6o֙V?zbR&3.>{F] 7*?]zo7Sd^_iǣOՇ[|##c7{?GDU-~*@1Q?Z&wٲnQjomn5h1*ۇУX{J=<0PKzXQup^[bsRb)Bx!ޣ <:|v)]/>^~ϩx'|R>~[ᕏw A/QgUc*#7 J.EVaa}sPn?=c:Mx)C)#7$'ƛ>hpXv}JNqS(m&!KbbK֍$ThM֯>Y!өJǓdo ӟL "ӍTSȶ0hbgރ3`9R9e,^QTiz<`b5YfY̱4y ޜG]kz DMqF5PPK'"n,R5B3}D; c^؃iVrA]hmS+V:)i}1":֪u֩AF #\xs]1&oz0M?mQkHIV"9=dtg>ԓrH}o:s|nivKB=UUUd5.&!RCelrbHFA۹kKn]0XN_:.#W1j[Tiƭc7xG8tU6 0j_I<}ɺ ^:7+x iu3K{C'@NAǶͩ h;n*98<&uvۻlnvנ9 i/7BuYxZ J<f8QnjzH&ʼ"zV|#([Tҏ}uE>1 >Y1OA iiYw }#ysǨ9;"'44,ªfr̒Pil~e@<)eA'M'%e"^2:<-a]kǏt|XL%O,W!D<@L|0ڵTy,O2%r9T^MbzMSk"Cimy' +Jt'+G>ɬ)[kGUAlE=밁2EL]7gRhB4{Hfsu g%:c5Fp<-Y-.Sphw0Rɢ^{k~i^>y>9NRWw/m-k0z/d*bRY[1Yk6H%WV_ҁ#bĆpk6Y}wݵm߲7^ƓAZ!};.}0u"ҾONW?Bh?|Ts & v2(гC{y[;滱$YOۻgh~9ޯ:A9:GL~ru;ty`l@G<715Ccv}0~HqT` fĢQāAIg`*Ii;2Aoϑ`{@!p̹etIԨi2F{j}d:ՕY'?~pNYr Cu'pg;t 99BY*T}̯'@`p4 #VP…(9F6sc!/Fρq3ҵ-8)pP<"/q[ƌ(;sߏ&yxv&I&f@~LC@(~Bq)M=_8֢׾|Mi{ Ƅz¯Xlä~,Xe"`*FA0eTqMX1Usм-Ъ4Ѵ-.vm\ mHidã13Q#YUM52cӵIAo8ml~bAm;m^[ln`N ¼R= &Y,A-%݁U9|LI1@Mxd=_>ń.3>{@ O? ~c~ƃ5<-=۲a5=Y^uSN){/|H_ax~0Oˋ粲'|zg K?闿=oN:92.m[_>e"$봪knmɈ@V.UD+LQcȎ"*I!XU;lUs=U&Xc܏N=ia;{<߹Y;{rH&__`pY6j$㆗sj h/[(gB?t\2$񵰖<vD3xs.|W|7*Q 0"f=D 1BH`jI]vƆ/8wHI Hrƅ[~H³_uQjK/g\~WY+ ش? 8Z$_imN=>K?B5/MiѷH)W-$r~H zr|W>BoZCoW ?#Sk q1J΅i75>"|ΓaL]Qu dZ=^$Z,7Ta!Vޛ,څ:3蛐M)IS;K{x!φ^䦓>C7Mi.7 mKN^VNp&ml B~DO[4t5._@d?ׯ'GHʈqbG5w1yx缲aѮ/S-8gp8scf?ZV8>8VF~-J]]D9\m H35Q[;M%ha1 _أ_>3>E p:O|#/?~^8! HźQ/V'<ǟ}5y{e ˟V>}~xq/MHx/|v++fw|ϿDW0hxR5H?wy_D5\spAv꯵} +%~ YIc}YghWNY(YT57EY~IIPatI٨]jH _ݙN$w1ρ@*{?o7O/tF1<GjF dqؽg 2 lu[8\۠~rMvf\XOkDHW+ܘ0.GaMj7ςiW7UUE$mc"(3hRڎF^#Q0u t!AJgjLʂI1 `ÕNEYe 5w98 Zc&JȔ cw%cDVlƞ*Ζ5kЎͭ@4Wg^Փ󓎩=(e=qi=x! |@_ nm. m{t^WWp[~}uyRjz zǯҷ|/s_DZ5_mVw\ޤ`|~o> ͕e˻ noEU]>%O/RƷ{1FYr]?~Z8|Q[\>/7g/so#_t~/| |~] (ٽz+>rݭ}y?x<Ífߣ1hNNk#x-M8<1J~*zYPlETtwFI2i?эvJfe^Oc,ʭp ^KPH< ܢS`](N5K{ڐv|{шQɞy]% BWiz.k=+ ̃JxυЎ3$4J`wÊ0- Sb]n\8GR5YvR 'n\̻9~@F#᪠['x@kR뎨=$ޱH{Kjøɻ3)v Fsm|n!`a(=Kw?Gj*M )VьNCk7I_O^ 7Jpv#?דXغ  cw[`!ߑd7NrgA0ȷ94v0T`{$` !JXnJz^S  u}FZ.ъHT%1V}UW\7 &musfK0t^8d5<c7 *d%nyB촎p( IDAT%ʷT x6VX:2D?YAɣ[|H巂^W C/ΝX!(QvL"7 Yj._KbLF'*JR /~|NgϾe^~-x~7"?~L~R}W| Ǟt?;^ç@o/}緌x7_=ї]+;?+gc%Z7-t;OIo0z&1Vyw-}IY}.= y`$߷-,cdޕz7Ɔө[Yjy3x3?Hś]ر InY%^bU.=8- IF.jj$ȎjfYiߚVrR[?݄u`P􁍢"4KnπjoeOuL t]W?VenuBELԬ)t#a{lTe?3_GvO%?lZ^h0kf:7v+ю +*橩|N"$˹ӵ@$4s`6%M;FN}5@}r{Nt5Y⺄9! VC;Ip v"3=cJz=:9Mͺo) v(yC@v7 jf尷}sW's8ˆ740ot5.W8cx|, k?s*7N=x }. {Ko>3w/_W/|яo:Ǥ')X_yu]o.3>T֫$^Wos+8/~μjr\AussN!m56º$.`{aZv*쉗_o@RiRIJv1Ă)ڣ~Cq0nqi35@ocF}?k`?l3ʳ(}4UٟŦڷ@[z~Cv;- 9kg &1}|vא$yC|l3uaxK/_jFZkzۚ 벶AVvH7p2Cb|L |\4 aWb]mƇ]ocGT;f)gi;fFR[= kG Cxc(j$[>t d:&N&o\x`\3 8'!TxWU`:6Hʓ:Xt֎B۶mw 3Ix68v7;`Ǧ$wQUVXC6w;~,7rn*_ۘn}w)&Ex4^/*{@\Loy|۫~/~g CN/y~‡)Yz>;k^_WY_:d92CAzcz3v;o|_{t?oѫo;?D6m=zj)Bë׾^[>蛲nVr3.oy.ߡǫ> 95ˏż>xɺi?+@y?j/zS.o׏2M~*:0Ik03#ӽI dF5jj]~@:GyҟQY!dr[3)زaχd3oi_Xˠ&Cf.NM.ĢqlgY-|;|1/ϵ$Z+N`HήV\:XL\!9/\ịrW0E, ?Y%)Igp&#J\` BL>ju*qs$]TX x;@ ͇$|T?3i,ɑA (o݁H`z/prebw=lo2S訚kTO=kⰕW cя)s) Vx+W<&l :4m7/T!/85ҹ:ѯ=[s!&/I\M]5q;"tU`?)>w~՜^qR oŮJp/X zbJ9G%|h`sun-I4fBzN.,MYQWh2{m0 )G #"LJ[iGĞCCq֊}|ꠁѷ_ tgsgLn1t(Z/:+g,: +¬4.;&s; gT(z:GǺ`o߯ ]-(CZ]|vywȽo{|DyXe?JP0{4| 'qA; Z8+x/q*7#lwD_6|e[>znFU emn17~m J}nROv4I]W ?k1y,ւ?>[54cj5Dm㮰ceo1s sY m^8l0|ڝ%nFЃ.R·*FG*Bi~oU,Ne^kLf9zHII@,MΣ2hijn@1~D1o!n+ͫ=֙yO"K`'|W ?0;Cƛv0WG"aU躼c~}h4u7Xw2fF-`h*v?ܼRp327"0) HE!\ɦ5&zwS[gQrq6GupNL07Yo!9wŲ%tskMcODc1j\HzDsqx6dձ䑃3yFY2CMWҹ _ m ^]n02,=ls|,غ ]ǯAs?&藟ui}Z`E ϙ#?D0tȩTM\rbUT*E5/쭼bF9~tJ'5 6)1=慳0Zik!Ru \ʸ͞鰀WCx E&ƩpݒY%Fdk M]mk%hA5cշ~0F*Xf[JV(R{aǂQ-Xyo泽c6$i1=#O9 >H!ggzV,ul9F4VC>relO} 'H\]3kҭ L րŮC{>>%'e+kW p"g0< pC(d!';#؃6fG'4.`w|l7|Ʉ-^p#9b9fNwiaeqvP506g޶5XYwg|J((wvxZ#7:')nR 7N&-6Ԍ"$ȃ+>Whts Pۜ1FCl#ZsA/ >#5|t's?PXܚ>!3nۉ<0 #;e>qG ne2M9{ZU5@mG~Y0Bt'bѐ;Tϭ',rtby F<9w0M<`2 0WM^iIrf"ڍm2|.g܁÷qMRgޖBn* хv7 ߪh!ՍcYvV]hev$h+Nkh}ԉy Z3TΙ 0`6g?Ce0HHkڝ" ltg=8nޢ!ym&X(XmR{*͟,CsJ(3 Qo:ôg.JK)\|4 !e4K܆U]@6F掠<,<$tc&wh(7208YU`6aS€(5Ww:FVgTF /2=kͿ`vp9pYQٮIJ1OkH±jc"sYμZW2 qLL,)1MC[ 6D |xb⣽hQ_z͌+(SdNaș\6- ϡCnl鰏BDL_׌^MrbsNfd1!jz7x~ݖ\!ըrt\qKvylrݞFuNÇNINɞY:oImᕽm<#~x'&?8 (k: 4lD]eyEraNWd;&qq$$;hߖM8di }s56ý}5cdtp]jm|7R|,R˫8!3(Σn{su]Mfd11(Tn.<Q=jXG:b;pNY/9Lduy@ ihNL60 F+4P2rI¥wi i0 yX7%/US 6՘pјc4q]ˁ@N7 yqoZp <#Mj1.bam0< AD&g{0.ǴsxVq=C q~#J^EaL7Q46֑s)2(GX/b@ f5:p876Q+ՍX*Uhi'^rx xqSrV1D^^Q m %(#1GJ.(I87'Xv _XX t^> K pD7i ec[XdqW6<0Hc4gdákT yz}[Ӽ{hWs櫞OK'y۠m&NNSӨ8meu"CIF_ؕ[_GZ=RQ_^k|ܙ.T>+օmW&C^; I(gkH`ajwe)|EVvkᬢFo|U{6\}j+ RYy-. !PWVLDqp 9sv# ݢ_z 7˘0kXdo,Wv5וP_iomHn۝z:BۭŁ\Κ}l;FLjqp#A͘Z"R/OE08Q"ч=ju3\n@HIcM$rvv:M_Id6 H,򰌞 7_ȑGa>|`bB0#$SfL`ᴼqT6]$_IIMf' K쉃RiZ.F>@;Ʋ1|{jzsw썧(S #zY} :䱒؁Ǭ3$GIܶD&EZnZDz'L{8|t{ Lj"f̓<9d-me:ի-T[zT?yQQP;LSвDlmOP,0Bbz3|ߞE3q&ȒҀ#RT[5 |0RJ<9H߄7I!o/4إ1{N@05ߝvf8)&a j>RUN *ѢI\bGj`Q 5`mHxf b7|aR83#9[H yъ+:uw9JtVMŖa9qGi%|҂koO& IDATV뺃nj[iz<biGT8) 3GkT.t+͑O!I.51hL3UEEs:0j6<޷҃|ǦȋV Ҵn-16C[uRأ;!o-Ix@h+uS, ڥ6gmI GXB O]Y<})Fpy?kj .wO jnM: K2ioK2o+k,66Ɩr>}-XZ_פph"H.h|EPsMBܓd(`Z1lVT0l{1+3TJ^>D;N" v$s:hpYBsuV:axţ<7(|kS ^T6v993{3@Tx-s юY랾6!}rǐvѩR'/aUmFd C7cTd< 9uweDV)hX+5u0 k'kr_^]adN:9rffv}n׮ʴ)N2ۖ\.~zu-( _gߔ7lK5SH +n,ug=ɣ&=Y8(&Қm#'m-?*|cY'.${r o[C(܀݈}Er8=y¨棷#r[5Σ.uƆTD;h~mOj:cx\ ilm늺A`Oз,'%eu4Z] I۔y#sf{fͷQvԃcVkDrDRmɂ rԎ'2b3V;(R*QQzҢاz;^9mH5F; 6iH$Z>hIÛ~W&+h9M!SF~RLfa`Hs ?z) b ˃|4(372Wپ TO  `°ŁajRa.jD9xd (`Q]jθ"ZG_XiW|CTbJqFm/Lk cb.%o%)yN!11fW)~ܥqZ~xL3 I?2ExψHZpLox rDH? 7ܴ&nZkM't bDߐI3t{$eBQKA1X: һ?"3:܄DGZ~Xxn} H /&d#S5P'Ki53c]<8-p5b|NLMk.VOW&fpOd}T>h^~[s/SX*_DN軡Sӎ]3s'yx~sV;c چ Fɩ5R5%'ȽT|>:R(t>J_5MSt؁PSVTۺ>!*ahHT9Q5X8X(2D}2}Rj  OIk9Jh[ 'S2SoT]1@>{nזRz(GE!pZG1 ҁA݊c[ MQ94RHK.߉bp2)>TVf+;݂ ԶÇӒcU¯'o=Vr/G* ]SebFv~ؗ]pwSe =`"jl`>mjdow +5.iagM=jvp!u:YWK;qu4!KSm8Σyp_gt#f5.ޥُp{c¨Dc`j֟nGw,2(Cm/IX߰n6tkЉ?A'LR0R*M4}`ȳjq 5bդ9HOFqRNĺkeR[7==s5&姄kgm+tye `~&=0Tb?L9[#l>Q.Ewڛ ڵ52hWY$=Zk(2l)u-%Ex1bfn.kZ4F+EE.YH9{%'z)o5( أnm6 o{brFۃ*m/{wGQ} " PB=tБ =A)& nlT){' )/=ΝW;ۙ;gf}=16Y 4P"wH9lu9b5h)).hA@CNj6 ؗC)Beڕ[f{R[qibvKIټ@_2sBNqӖ6XIN@0΁dL<%A(vD{KYV kk 1d#K Pd@m Gp +AEK1o&X4 T4t?dߌ)J&C?k Af?9xl@iV1pۡ ,9}lm5A%GE;R =LJ֤f8Q aZ4E&'Z6 _I`Vɉ]9)KbQD%ƃ]#"of&Z9YA4;bX[J# i3aT?KgʠXXf}כ`ƅd2ūmda`<[-MiG@TE6-q5]t[zm7"8IX\q!J:`D(i@6}Jd E^q!iy GQdt86  +Jq Ukі,FIրmTT*/0:▝mԡ20>S8h 2Au932MMVߢFXBn(`Hy/i"?3R3#iTцrF(A覕^T>kgUV`nVƩǁUVUDEQdD"j6߂I"Z(װ=*0P[_ `bI2m,ºXp V\Ёֶ_RD8I44M2R}k6G-y:=CcWcSӴq1(-p7S(Jd"]@) sl=lc,X>d`Ŏds-WA:D.8@b R~$X,'3(V}cL$ګE dQnT \="Ņl`*f8yNHCTFF"ؼhM^:&.#Y$8N+Bqr쨕!9/v5G%5gmކa"P$ 'mNȫÀES%phÎɄ"g,LyRU JkPfϊZ芀wFaBtԌ)/[@M4uM3QbNTrC/b LO'߂'1;DP ϩ0OA`>&FBl^\^w}UTs0:Jŵ }̫b0^*F)q`dt~,]TM 6~6 1udx%d4rCsVڼVR11=j d(dhV`U/$+#'!LDY#Eem:aY(20YX #[LxIPElE%`ZLohh USEh7AtX-좌ږdlƎONQ}Sp#JAfjbQmLolGUO4eaESĥF: ɬVn!3;He7 Rf Eh@a8+uz"Z#4PRE V@!#}u5mQM90ט0UBE/}q[] QLc1a I@)w#I(Ml,O%m1rBWO2H\ ʄF3+ܢBB!7!B1PhM<Y1=^ HkQIRЎ" "GMeh:C-"Rǎ.N-MDF1\[c$I1K- ;UL= E yaWmDQlā5 Q!^([FGG5"d:PlV-FIIS,8 &A )7s~cY@DX~+-܁9G9N-D$>F4H! ćqfE_LS^H4ꉷ36{;D&IT"wj:dKcnD-Y4mAYڒoRlA(}e!Hm< `137$ t%߀{Fxdc58* B0&SURls2H*d(Vk϶/2nܚUaBe-x(JUV(~>v31R`}}taeܖgX)0~Bܰafcl&lGIf.0XDfm*;\eQjls `0zBV7YM**O[8G$J#UixCO2x֌͢-}մLJQ;Dt؟b5cXXNLdVE1C[]*z^Jx^ Rq~T{(ѻI1X%#4j( Ⴝ`0Bh[@c-PÊʆ㍶YeKxUEH$Ke\uvp}CKxn L #(2Y ̢R͜2d%?!B p@k&5䅾h)S@r-&Jr5$i?"LqꙈ+E6YԕH9.my5 [5`$vQ/.m+ly&-8!ܓ.`0EXcB\%QI|n,1 ܦ5k6v5TdjF.ֲyXO#RBMlt~q_ CWec:#VGA$qKJ1MV[ɜCNjv OfCdQ>Q7[ cU5I G(G*вRId%Z,AIY]8Yɺ6?c2 jˆz}ƚri[WT7>nLj&M̶cEor>F`dKWRإ8>Q=0SJN*ӥJ"b}U.shf-q)s0Q/,ݓ~V?BqD̀}cP!MX<Qe9`.E 1G~%(w 00<SM]ڴMAuJoª0tZ(:"^=5T(f.T ʊ b(Ќ]E(\V]8'88aʜ[;%UTQ Rf"DYanƖ#Dp4K ueX5ʹe9#@̈́cA :E.G9n(j965yChXp->:0-XE0BI̺f7mc4 )R`0[E7VT4d7٣(Vk/W䞹+a$/JPQW14WȢvcd>aQ>cKc5MȸEp,F$ i?ҷ"RJrгbGТo-#3RS,,lˣ3ʐX18QiI5)&/ `EK(U!.Zj\nkcO * ;|W|ytڀ%X-PuaF/%uJM'OzЛ-*닊eBj(OJ+dh˚RǛ3"τą- Xb Hv58gfe*|?:KKDEb" Ow۱e%&8@ُ31 GJc"6acP6hUPFbe`ezV-yc9F;C1%DW'?dȃ( z.;8Ƈ%t:Kt㤛#ȘԨ=V $?xgx8D ,htzVx]ա xGVZxc:f&be)Ъ٩F6p:pT\ ,˕Rl.Ճ/Uzpsn0gNJ)V9]poUyɉ.>tsxz>(m=U-lͿK ls }/I-sqD&rU;l5M̭&L4nq ff1IwL3FL+ epj$]j#]H —YW #%}jhr$GXnlzI@CV-3o$I+*G*rRQ±ӧ_h'MeNeX[|L|.MPD`#RZL/ IDATIuդ?c) E@@jQplhbnS_VveK3CiR+$*Z9 (gwqƜiGVA6=U8WSKR˥J?XMX\^2 b)6kV xl>5]|:I$@K޴VBŇD1K@@ VC!4}gcx_39ڰ>c@$,h1Ou'Qm6iX՜5XP7`]F0PX- )&m@fHRirQzLv2H+Fό)/ck/4bX QbrR)ahЪ*Xǘc!sH>Gw<8-&Ҍtlq 6 jRU60ơ;̶͙C4U@חI26]16$"Dz]h ' k]@H6b iKMA4W먡gyiNbdT褰1*cQJlcBc?0 Jbūr_iwK ?鉘zPBkٴV>q6G3#tmIKtm툀.&WYY 46~!Pk/BC4:6Ăj kxG @ -NK kTc]fZFPN 0F3J^6ZŮS8&+;<39T%G5 P1cUHq~4π _lM buӱ^+ nVHR@ORZFTT_KkvN*v^|lnopJ)%Еz Ց7:y\^4俍G CjG.cP(3`VcF촛D]U"'x9YƅU^b{ Xm5QQ X#|KyN>҉D/建^#41*DF[Q HZM\y`+>QmB7CC7]:od")qg#vh:FPPFy?cssyGry$b%m T慮2xLu}Jxܧ(c1 @aayb^ 1aɡ ̱͍qpє2٠r}HM90=*R2TVD.1'҈v9 Pe*k$0SH$JZ(8>;"żO0Mt G.F+,E|XL:hRIo>ȫCаaWxE"G[|"XI9%)n"E0SqkPf,6]E_m~晇'6`. J17FR]0y)"*.UWEɖ7ml%'Y5hK*i!cD]dN!weɚL2ZRT]'k\}LqVk;ߖuX(ƾ R[ltT[@—lJYT6_j +u7#thR_>؀[34RWяk֬.AqkPS b[sDb&2љG"UITK5PۄZDI`I 1bve" 2AS'l8" H"HNj]āKJbeySjV.@,`}u DetdJ#H°Nc#!~ 8=?^yÓ@‚ǀb @Aa+qQ@^HXͰ-^*S LILK"\m)2@\V=l!Ѥ Zj[#bps˝a$;uW)34N\j6K2BzrWێd,5Ƌ>u,K\8UXs|)hg&Ȧ%o*ìi#Nj! 3Oi[ 4SM:B]?idE~of[Tҿ^fo'܁@,Cc+r@6Q'#YPN,N "0b}9MҭvbnXq%Jdwn\ffFR1BXߐ4r~z\IA2?LцLѶREFth4{I-2s*Y(lMϲHGV6R&/\Km qDB"3:zMJ9s&/V_=Luc:mj&,!`" JG;6 ̍|%pYZx]L/e!hŲUUlj;r4yô$ǏEVoLucp z )cVZIPt!5k"P w+/&+3"FsIN1;*}4!T^³a:bM-_ba0)dcG)4klZL(t~f + PҲG' sIhKQ7\O '&\,*okI,,eL%Z?d,qP\}x4i5eBENX!8ă:P$`@`jXi,+^|ĽP2`Cb͠eȋ9b.b)vCeR#oR{ 6 "Mu"O23N AVu K"4Җw5؍[bl=q-"&I^3mm'LzK2>;Tfce-r}CFC:/Rj6H ^t  ad*K%ij0 G,- pRi$"LM+e(ñAh٤L&lXAV,@*'t&^k=(fm*B}kj̽abmگy=vVy6+ cut_ĂKݻ g .Rl]m&g?ja,1YɆCYhIG?B,60#Cz3ѸsCЊB8Ʊ] +\~-n%3 YAH@p 44cұ&Y)H䋝$;D7V yWYs\Ʉ~+/(8d/E00&Knt̢$ligSZYEQ]H$"֘D/F(Oр@"ԝX {YIJ&GbVuY_D^~*\6'BYMljYuk8謕|f FDmkMŵ+R,/$Kav&EctME56Q4)DG[bQ0z:i:}v _DVc0C&ښM'Px,\_mWq_ȴeہ~k< ذSD|rRs2zǷ2b#)Toĉz,NE,)FvĆ˪7a`cɐ  Vna莬BiU1c<3K*kYRoMa9S,t j;-Ab?R%ceAi. U]lj1FO_Ecim#VWՄFRJ,|=܄Voi6Y N8{(4oҷ&ՙ, C2VNE4G\7ǂDh[hj`2ljE"P!&VT}xs3XEJNnY!oFu`kZFsm NPLHEM!4 Rl -hiJ&AlZë4t=+(^H[`ɯ4gmk SŚL)Heәf>.}w\Bfl?r6FƵ #<AYKEwz`k:KcdXi TمV")DWh0PψK{$, t64JR4JVU!mS>u2jH 0oKKS4^mD3>ra.G\QvD**]fTȫr\Ջq\`W4niL&_zѪLYNF8¦<qhK 'Vǖ#l(b-2fiJbn\b$5wѰԖIci-봀X:`w8$yv<J#$RJf MXʑvҌR^ǐzp9f-5 'LNIlÇ.ژI]LB*ԞdQ. k3* kQ6&@3%8yӔH,j V8L͔iyN(e,vR$bQO 13`B J:Cj# FcRhcN1w)@)lX-hAifH'XDfUu#蒼-nVXJ9/8V:jM=ۈJ*b/ jP X/cK"5*ڎkЍr̟<_˩,,LeCCkѮ&;*5/Q8AQVH?K4(d%alM b}8񁋥+B>Հ# fud5Mq`_Bi0WFm~ Uʺ|ak3*ւ^֢k~fSIQ"mIhJɩI1I8Hޘ(u87Qئ yB\o#kgMCkx1VPꨮ-Gp]lURҦ[T**?YhDON8b$Ϩc=P"Ԣ;x 'E-XC+XhD#r_`Uyk&Ea٨ ty;F,8qR[I*=v5ru`a~dp< acGlDCuJ  m4~H1 XF6UbUZִfl1h F 4\ Yr..2(XW@tPg1rbUfkqJZh [tܵŎQ( ю90EQ<9΁. ~2c\" `0ؖ< Qc򖢦f߬"@j$7;Be X3k57ȓYU;Q :a Km)/ U 9qF[چ />KFD(sd2Hh@ul BY LRk:`mh"> N "an| </1l$.No~jk*Jы3b(!a=6V 'fiX+m|S!کa䶐<$&U"GiVQ/yYH7`Pu[Eda<$})4 krI,3kg1rئP,R֠ڨ֌WbVۑ͖.V-\$/O &q ୅vjMBc -I}* VTk&?O !ʁQ#Ł 3[ۙ@i͚|3iSX%9L$ "dg?FL^j϶ >LT+R~ C| _eH떲:ň!imQ^tFSIQC-dvl(QvaB7&Ö`1$nTSY ^]I,qMxC.I'BJ,H#(.Kc")Y,hQ`JZčdu+?4L$o8΀3 8΀3 8΀3 {=΀3 8΀3 8΀3  2sgpgpd/@z\vgpgp2~R{΀3 8΀3 8΀3Ѓ H΀3 8΀3 8΀3Pf/@|xpgpgpz9@ IDATArpgpgp H9΀3 8΀3 8@2 =HC;΀3 8΀3 8@)=gpgpgAuhgpgpg(3 e> 8΀3 8΀3 8=Ȁ_  8΀3 8΀3 8ėgpgpg $סgpgpg̀_3 8΀3 8΀3 ~҃:3 8΀3 8΀3  2sgpgpd/@z\vgpgp2~R{΀3 8΀3 8΀3Ѓ H΀3 8΀3 8΀3Pf/@|xpgpgpzArpgpgp H9΀3 8΀3 8@2 =HC;΀3 8΀3 8@)=gpgpgAuhgpgpg(30Y/@xз_^bqK,I~yIިa~ǍL:$7)}<;4d:Bքs5tN=]79cUc{pgZg|[o'w~Iۄ㒬;Ah焻#ͧ;>&;&<٧;4hPx'׿,ޒgXߍbvz*_ua s5wXm0{'GX 8΀3 L td!^ /J܄{'[NH>,a!I / c037AO fuސ'^loȻpWOb9.=#ᧇ4LxoXqȑ{u ϝgp@/@Yf0,{N 콷&&^{C&E;s=0l&G]rɥaצn{wx(sw[HWN 뮻^_g=]^sJ+S~N(rUW\]nP8ēxmc=Gy?,a̘% 6܈癗c};vQ.r m;=93OwyǟpB8]wnpA%cnj pz*vI饗Q!<.Ԩ4nĈēOgy&b_~ qg oe]3:+ٟrʩ_ÃƝufd\$jcSO?0Ww'9V{x}?裼3nmۙVsN0\z)a\۷Kw FIk3lFq qjc;3V[mӇ΀3 8@dKqWc} ,O^-]nH񫣎[Z{;s2.`}/Baglhh]u`j?2jʯYLjF6fu#VV;?ÁZDmgpg@.@s/b آF'^_AKb] f&}?A7mva?9,&Lo] }9yʠA˅^zN< '2ÆoǩH^{Ux UK;2x8Uû9n^[lE⊿ _'wdrKI5>ð\\+[lxѰFQfE'.<[r뮻pMSȡJi61Gm9i'FCGcuv?_];jnl}m7ϳ.kgpg`J`so%nL3Ļ x\fmf\!?y\"fC>wS}7=iͱmw(}/%Fb>}E5ޑCcv9Fݼ6w¡4y 8΀3 L t'Zx$N"K-dxw1}#8A[K8)Ci.94ţ1x/?v}7sK5>@:c,*]W^y5 w1) i01o7uO@^V waauOYda^`}a-60n7ƽ| ~]¹)=fkJqwe=ˣm3mJi6&C]l|'K3vz9(f׊ܶ'wGskc-7'΀3 8@obK (N8L zUV!6`8p{avOoak'ȿ}gMR;lǨW$|еޕwOܓ850ᣏ?cAxDK/D]J"6o-6:k@ g;մam6A /0w$/$"wϡ$0ioF9D,`: ᭷ ?7~x R\:\⛮{=|?_qEe}L ]9r$/pǭѼ#| 9`~볫kُ8nǯQL@݊ܶڍwgrk(o)_{mE3 8T@>ֆ>L?!5ޱwMެƅ駟{γ!y߿|0py)*.[|\]jŻWcn(_YQ򙎝vI-6dC Ywu֕ s9g)s'%ߍ.jrf1֗ |HqkamSW_}!z|ȣ +Ra_y9ٷ>\,aȐc7*ke}.d?,Vyo6Gãc>`SQC V5ZGmǯQ*^3=o;[3V| wڹsk>^;΀3 8_Uy7'}Uj\kVoq2o ^ӣ6I^@y8΀3 8΀3 #X`uS7,^ff݄F.1R3 8΀3 2 _"1SOJtw_΀3 8΀3 | LՏ`}{tgpgpg`cB(;΀3 8΀3 8@g 2~΀3 8΀3 8΀3aÔ3 8΀3 8΀3 t,s 8΀3 8΀3 8f/@:L;8΀3 8΀3 8@g 2~΀3 8΀3 8΀3aÔ3 8΀3 8΀3 t,s 8΀3 8΀3 8f/@:L;8΀3 8΀3 8@g :?uѺ0[ftgp^sb'V7aÍ6W_}uJ+0`.aC K-L0ǜa뮻^8餓K6\s K,T[K.4L4Gwuk+qgpgazg]7߼_ Nvi]wXbnu'\~ZtE ?BXveÍ7\~v-ɻOŒ3Un1bfm/s>|0Wr.%8΀3 8΀3 L ; >{͓;︝/"<@dM".:l'Gy$ y/9aW tpd0bx'~ mzk!~&;A. ?l8Js!2nc7aXB@SO=&p;wkpwG󩧝Vχ~>Š+eƌ>v [nEDŽ " /3=a"ӟ7x#:;yT Jwg^b߼P{},馛.Ȱц]̺n m1lxMᣏ> >{MYMyl'60;~2gpgpFz%lp[oݰ~v¹?3 ][@;(u]l+G[o O?dK(k>Ӱ"G~(p=v؞G}4laQ,N8D^(ڪkUWēN ;|zP. n?ԷɸϦ-.,b-V¿!.npwdygJtLg}u;1Xc0s?8p+Yo!O^T6汝؀]gpgpZz%Xp9ixcO>4aCxT> N`QaUV]- yGYyᇩ^»(3+Zh!m;6/yW'Ÿ㢏qm^}16xЧO6dy*2,1(pOvM4.zBuY;:ap( h+/0N+w>nfv[֍6汝i˝gpgAѣ p~ \L<s>ycۆƍGn+>li7Z?9΀3 8΀30%3d;oV?1o}EYIȑ{_o|;f+\(}Y;;&=5ZgufZj}!)1hr^{ b],2,CqCTfxсu|| ]-?D`ʹe |qne%.>4~QGwm!͂7vcwf4u΀3 8΀3 LM 4~{ ez_?+\U(뭷^v 9)}o gy Ig74/ 80ӻI59[>_aE~m:(,~z Ys⋂G_,<ēN W]}MȁG縫J+B^W֎5֤'{;%N8x\ _s+[>} /"zV>2L3.5m%^Ư a׮Bێ!cތsRߑ.?\lo.r ͯ;?SO?<>hCQ|-j)AF *w6{|bu WO|y|Xzx_ +K>;=o6ېANi-"g?_;[WN|yz΀3 8΀3 8΀3zkx?/lsιx;L_ڐzafO<<5}΀3 8΀3 8΀3 O?$<3apرcyw,~_PFx}_\o<4" MSXy߯ 8XtŻuhzo]aÇ[u]9v8.8'_8j~(q\w뮮naX]!Z9t!޼&kgM.[g;ph]ueop3Л Wkk7`[";5cv/jTN).6&w2bc|trׯ_ꫭۭuwحI5ïON'ibYVuu_Z,㽞\CF=:;׎箮)mM}/WVWRSީaW wyg2=3*\k-Z5gF-?Ɲ`ðk 6(< Qv=W_}5la!Chj}1 LoB?ymmLC=$1$|{ 1[l6 x=ؓ1!9QhY)T10*;_Ӎwqf|#;]{k IDATqT5|uw88ƾ1|e[ ֛8Ł8Z4Ztv]|)᠃IP8!YxE֙ǔP\qkۙf b5Z'#o(ds+7qYdv=-٢oc3]g6xз_+b{\8S-l7foF;VA_qʯv;Xŭ7gjy1#`˫:^c 3UfG.@;ݦnZá`3 aEr2~} 'pM7d=ws8~;nqhww~pȡ?14m{&#r ^fi9rOUwXwAʏ/yᖛo 3edMh[m6ލ};,{y #?|A w~.y06^}1I~\2v92{lճ:k&^zYm~+8ZięQ?_N0q ht6⼫7Nvb5݊te]80,+_q7W\rI-wUjk#noۙv0绚c#kSWƳ qW^yE#qac /_Ɯh]V;sjsFsX;'nv<3yZQU,;_ez;b-?|.8y@; -/2UM2tӅ/&Mbw{,<(#+裏{ 7\}XzհdݺάkL8L3\+矕c1Q?r@^F4 3Ԥ՝ՀXp>yHPէ\UqLS 涺owU69b5f~+]yȝW_}-:5P+FvRTAg":r|ltgY#qyZ{:K/=_r5eC߃vh!vm|_VݙY}$3yu?l9@n~|㍇Gy8 <ƀ Υn>;X< A®~za{v>ȐgaWwT6ϛS?= 뮻"< [(x~ 7pW_} zfǻ /pqEvGc*lv'?O0LU磣U|%}3xArdҰq!VX>\pIw̚q 4+⼣Whnhf6[ӭxߕu MmXHV7S5*FVНFKku|jc+Փʱ&:3m^>d欕_ovҷo_^> ORF~%#4],9gpgp\z(ÇY!CWkܙ8#iǒƌ96l6d+6[Rg;5xtiזNN<ܤ.wgpg= L[o>G4揓~}ѣoJkүՖ[vfۢT/d@=g]gpgp\zg@x0bv3=˻1|FK0Ss3:3 8΀3 8bW\xgpgpgzg@zGugpgpŀ_L.=3 8΀3 8΀3 E 8΀3 8΀3 8lT{ gpgpg _΀3 8΀3 8΀30 Frgpgp5 8΀3 8΀3 8lT{ gpgpg _΀3 8΀3 8΀30 Frgpgp5 8΀3 8΀3 8lT{ gpgpg _΀3 8΀3 8΀30 Frgpgp5 8΀3 8΀3 8lT{ gpgpg _΀3 8΀3 8΀30 Frgpgpۯ .B=zv9[dd樣kl2衜gpg0>zhXje€9 .pXwI'AwJ+0`.u'V|j8Q1ka% |p%I&eu_sJ]7BGrgp>eУF.r袋~0 3Qø-fwbu[Res'e~2|f={nuavRŔ43 8΀3 >5}} sφ#?,EwqWd=Gy?,sK6h|裏 +bsò cƌ o^È 24\}4X1<@dM".l5zX&W@8s|/~$ i.r!}n Æ癗M y'};Si.w>8O=|,-o[n|nN<9\uC@2\ @n]%KHvLrlÜ9sAxBY;^߶_}rA)W|x|L^3gWմ9VZe㩣vRX1IJJӦƍg[7[ˎ/vOZܯjK}衮zĈCj" #p /l(d?;:͚5Yڗ~a{Go`/yW-^~^t佝KJG(SݺE9s^ #i|-yc;쀷<.NJ#glڀIjJ" \d\`O]trgQYx\ۼYr6r+x,xXu; CKSq3ӧϰ[nžG/vOZ@:襊ժאN+@@@x2=wm_zʈ#MeNs+.:l.4x;Z^ʕvYݑ[pѯh.ʑ3M>Xzi'?\OHDû*2x?W`Qv9^,&4$jͥe:xg[6[Kf dhҥJx`:t̛?Yb/O3f̜1].x#  &S H^.ivׯXr>IHrr1ܡHJ**G_.`.y\Ӹ56_*U:z Zf;KL/啗ONdsM#>jf:-w ꟢#]r+جˬ0iR|kgt3đ.2II~YRxx\/[)Sm=z܄#7.]E;{Pv6{u\j[ޜ)N:d|KjߐhF.[ϊur|`:0AxgP4@@ o^C}_vtΟ/^:ߙ zN#AYĻ|,dɒvm]z[\[mhygN!^'tdΫ~d,j`Mj=֣ܹn#:N3^3:xS zi sކW;:._Ͽbo7xuh'He'kr .,%JM6V=0axfj # -pʜyJ;cݻOz=0\]wTzT{ :F|Yݙ\vKO>)y?d4avRݕ*EKj.29l"e9^;(;zQKǻmL^۷oիK"b+ SE{Aom]Ghh'm۶m|xy#z ޽̓!^V-N:xw,R;t D6{^ҤqM7: 7D.;~Gٵk }#8@@ N3 ,y#GS_@6 NzM7b>wȜK  @2z}^ s !K`n d@@=I1%%楗kN$[sYmm+'O\vωˊkP"{   '`@#?\֭_kRoK]9Rt%Y$k6㠓CV   p hx'e| MsÝwe|=+3{L4Q.R;xo%L5yٷo_%Nʕ+L6.:b&8BXiӧ˹+J/h#-fz7Eهzu=#\>`wԨseC)ʯSQ#BtETY]g'Ui '/j7!y _zI6FT*71`T^գ|9 8Hk/@l eΝ(X6zT^|ΗZP8+o{ ^:.RtZN pm W?붬Gu.m_oӲ}oZyucwڵkɘ1cSõ+Vl\vUhuC?E,_ž]3gM?‹ҿksYڤC.Ot7 g;y?pxӍXۍWWcEjWV{UV-sSg^W_ꌴxֿcי3JՆ 3||56X-t{ Mkip:-HpHy=O/gϛ7?V۷mM׆u?ѿoץ֯[HٿacgRf3(J*kRf͚2k׬6Ôztpϑ ~VZJ^nٜrs=o@ש5]`Ag|`O1i΋/8Pկׯ2bǁ:0 5tF˨F3顯qS *lKiz9]5jTOyuY~HVm^jM'w"Mӑ}6+㡮]wA)?PʸqcNˠG[^>#mZOun93;dɒ)mG ^pU~$[L3K9c]|)&@{GUL6~Nd=xuvQv=eˈw;QS^jOmև,ZƌRf@;<7=oN[35v{x0j9rk6]yal~DwI5l(U|h> QOkG":ϟi7a8;I}.rmǎӣx7ݘzT0tXi`IflZ6mzڵiZ(.H˯[fM; g ޶[_eN1<2k1{zXD se2eTQ?X7gB=¿x2n# 2dHm%w"t4iGjS2z!\ڴŜd3u{nstnW3&=b۬y svQln'=Mڿ_@Scm7և,Z{Ͽ!-gYrʗi&67rxD۩Vxۚ6^HmN^GxF7==ߣFt%. cǎծ*ܠv%_^\"'\|oȒ%NL2/]Tˈy駼}.2uTu-C֝O?dn.2Gm:]}4кm۶_5~RV-ћL8*7:Nwlk֨a~+J=vGnY^.p.yr7*m$VܾXuDX@|6oZ~m{&%<*~|n 3 p ΀Fί|b 1Q#_;sU<D4h/\Q?]W?z$.99.A?)rM6<G*;t| zN463*T^fΆ{v1c䪚5g=:_L:uMO01x6sϟ?-[6Pǘ3lW;/e-[ܖ ^-2zg4ݑ  jT,^NgA$h?R CuMPpg͑ҥJ٬]m;nBCς]pA,/}M8QF'V\Ngt'>gHuzBu#o>WjRjש-VצLmLIw-VTڛ3|N{{gcm7pfڥkGpCZ\•ϸn#ɨ:bm^}{zCty~zýj{!ś7Qh{H#prDqfjp~wd$M֭eǕWV7AILhACǻeU3g2GJW`.y#y͏3gn 3$CbHew?LC ;UyjH27oEwˣy^~s)B.(z v'ժ]i/U ~2-ސ.? Lպu*lͬoK*U;DYZۨmѳ7כ,v~hwyv`;OM駞HSM;t9ևh>R• sa&57Zhy3t9 f/ _b)\̘1C.3ʏв͛7`CXڙC[@y󶳯t߿}Cv*zӥgb[P4nlGGn]fѶo]`4miu -'V:=HYGmЫ{Vo5i݋hCemIțwN7_!Դ~CzD;\S[0rF=[ܯX6/#8UO57Ŝ3z' !@BA 5kge;=Gߥ3UYz|>D D-Z?πE&@@8|~/8C@@/@rͩ@@3V],8  _ @ZleA)jo_qYu)L/|`H5=#37mm}5 l4nTVZ(/-x,0Im?>~%iR̞=z{v%Z;syUW}>^he=j{u==ˮg}֭浕­X{p_ g ʖPt]{f:-;kb׶];k]YCWW/(il0ZM̙#/ExCZ-z@NS"g̝;W]yeTY} |޺u >jv2<|tѺ6;XChիW3</ӧcܯ;9mjǣ'S?u;C&Nd/8-$y:|AfGR"1 g֮D|}rK[dYs˃/yTֿ͓#f}i۫ JT]gYݨQC}x G[c叴m۶cghY٧{e{ij۠>D^xC:uNj9cCnvVex^1qpZ(  p Œصk$/ Y4yðåفq6n5kHrl={/|3O,Y";C#^Yu(QB~ 3/\}O'NLwMo>|0E4jѼ1R:uG?X>hȑCb:h[ݰ!0-Cv[ףL‘`pa,+[lrӍGϰe͚U5kf뻡ukiӶ]мބH1exGZv/22ejR>cyܜ 7/O0~͚9sfzm"/"թuU;״I;7Iϲ@NyS"WyoRŊ6O%[v~%Y=z+Pd"ȆVղurWQ:Aw4H$Yov.]* -GuG_>q]uSHJW-k(3҇Νŋy# ;ޠ#RX튷RiPUewz OYryE{Wp/\io4MР%ƍ5.>9r2|VNs]9s nһlB )q nvpK^Gy2~ϵeȑ,]7|o.UKZfK:˽OFPB6Xz,eʔ! .iaÇ˯+V 3fy~4GksRL{@`Xuho]`ϿGĻ'.?tY-*):֣g%R̙32JW7}1onCgK_sD;X_w]')= wɳa;g˖ծoM.T)4.P`.Y*kvJerh_yEg!C?.i=jDO4p{_/,v~𤨟mja6N=F9i]p5jɊ ')s)SʘcsХ6CC2d{^=z\r 7Tm m] ?zGXv@@S .v~ͷdÆ_Ogn%\+WGW͛YrVO>9J@@NSS ib!  pF zFq     A@@ S@@@ q8H    ~R6  8  @@SO]F@@G   ~ K   8$@@@O?u)@@  )@.e#  #@p@@@?@ԥl@@p@     A@@ S@@@ q8H    ~R6  8  @@SO]F@@G   ~ K   8$@@@O?u)@@  )@.e#  #@p@@@?@ԥl@@p@     A@@ S@@@ q8H    ~R6  8  @@SO]F@@G   ~ K   8$@@@O?u)@@  )@.e#  #@p@@@?@ԥl@@p@     A@@ S@@@ q8H    ~R6  8  @@SO]F@@G   ~ K   8$@@@O?u)@@  )@.e#  #@p@@@?@ԥl@@p@     A@@ S@@@ q8H    ~R6  8  @@SO]F@@G   ~ K   8$@@@O?u)@@  )@.e#  #@p@@@?@ԥl@@p@     A@@ S@@@ q8H    ~R6  8  @@SO]F@@G   ~ K   8$@@@O?u)@@  )@.e#  #@p@@KUi IDAT@?@ԥl@@p@     A@@ S@@@ q8H    ~R6  8  @@SO]F@@G   ~ K   8$@@@O?u)@@  )@.e#  #@p@@@?@ԥl@@p@     A@@ S@@@ q8H    ~R6  8  @@SO]F@@G   ~ K   8$@@@O?u)@@  )@.e#  #@p@@@?@ԥl@@p@     A@@ S@@@ q8H    ~R6  8  @@SO]F@@G   ~ K   8$@@@O?u)@@  )@.e#  #@p@@@?@ԥl@@p@     A@@ S@@@ q8H    ~R6  8  @@SO]F@@G   ~ K   8$@@@O?u)@@  )@.e#  #@p@@@?@ԥl@@p@     A@@ S@@@ q8H    ~R6  8  @@SO]F@@G   ~ K   8$@@@O?u)@@  )@.e#  #@p@@@?@ԥl@@p@     A@@ S@@@ q8H    ~R6  8  @@SO]F@@G   ~ K   8$@@@O?u)@@  )@.e#  #@p@@@?@ԥl@@p@     A@@ S@@@ q8H    ~R6  8  @@SO]F@@G   ~ K   8$@@@O?u)@@  )@.e#  #@p@@@?@ԥl@@p@     A@@ S@@@ q8H    ~R6  8  @@SO]F@@G   ~ K   8$@@@O?u)@@  )@.e#  #@p@@@?@ԥl@@p@     A@@ S@@@ q8H    ~R6  8  @@SO]F@@G   ~ K   8$@@@O?u)@@  )@.e#  #@p@@@?@ԥl@@p@     A@@ S@@@ q8H    ~R6  8  @@SO]F@@G   ~ K   8$@@@O?u)@@  )@.e#  #@p@@@?@ԥl@@p@     A@@ S@@@ q8H    ~R6  8  @@SO]F@@G   ~ K   8$@@@O?u)@@  )@.e#  #@p@@@?@ԥl@@p@     A@@ S@@@ q8H    ~R6  8  @@SO]F@@G   ~ K   8$@@@O?u)@@  )@.e#  #@p@@@?@ԥl@@p@     A@@ S@@@ q8H    ~R6  8  @@SO]F@@G   ~ K   8$@@@O?u)@@  )@.e#  #@p@@@?@ԥl@@p@     A@@ S@@@H  dC$ټ$%%ˮ)ƤLHZe2  :8Ͽyzadh:LC@N"?ȖxRe+ggnS˚+dӦ JI)[bɝ;ϙ eI  "gnrLxq%iZ{ke˖,;ڡ_ekOLPXTZY*//_|> ##ۛeuU@@$_\ֿF98(eݵ84&#)Q<ٿokaҢu]y£4n ic6@@ 1HK Acɕ,ٻwyts&9Dt޼y={ݾXiW aٸq]^]Gg_:eڵ#i_՞$ṙ , >6 Yͳ1|xTxi-?d͚5:쳥QF|:g W,sΖdl@1wrӍmdѲS%_ҨA'7ʉg|FOV9C@|/KFM3^19ҬuR6aժUFY`˗Oڶm֢NU?O^keYG߮M;8SٹsTf*&yK*+'wļȍ $$__L4%=6ws}47G||Y.9c0^t~EC ^{ "UTOB}矦S9'?W\RdIygӵ/-[+N:ybk9 f=<0#_gg&_~.m\՘4vȭmo1GȎi`bpB@oyF`ܠʕ/"Je啗zˡdL$K kR\iS9 c4nXUp~ɟ'}!$ṙ  g|>E6n&M?c >k#|!|| Ѿ:SM_IS&ػ0jd̘16@Ȝ计~۷Ove ׫W/y^+WʨQL2އ?^UF 4h7'zɲeɌdɒoe }_\cvd65mJϜ&ٶmnwveЗt}YnL8>0]{yyAˢ%+dʈKW_y/.//Ov\~7X)( yFo)KVl_^Bѭ, 33   @ ٻGϘ"6na"NdP릠3eRPaY)R4^zK.bEBN[#]3ȃ]lٳns$OmEK[;|ArМлgwҧw/uYެÇLmzKl̑#/P)3sV3 U@@ c_qN>;U{;׍6[n!=Krtjjh'!zl=5k\-zD޵Ԫ~ogQڗD;k]vIl2u;lٲsY”}^Ңuу5^k36S~)SQ6n]&M(E_jPrsoQ\rv:?t-Y/'Lec ;u 6ӹl޼ٜ)e'h{˘R 6C_ʮٻ\<&+;S 6eu HZ@)3[Pgk4 rkI1s&M%vwȇCM7,4ll_ެC7o^i: }N}OqԀ@^wZ~<\/iҤgX~ o5P:th/?vv'gΜY=9v`ߺuɷT.-[ɓl='(e#%dA\ ș,͠ʕGըk_:~2a{&O,mu4g [2-S_I}lu:.9'IW3etKgsNgB1}Is:W#wwl{nIL$uֳ,8r@8=H|ZȗF G\wǶmNJK/LʕFb47ADU߶,XP|K &U^a;î?gyZvj.zZ.RiӦ6"G3g P1wmKZ!0Vi }s>ƍX\.GVYeuh6:p:61y֑fHmu)o k^)MՕAoen\en>^Wf3AZGoϧ%xZ*_R^.P.PWO|f4 oj0/  ńn IDAT8dt4B:,'El1Gtv:OHq{[ݲJ zm;fbvfweVCj.Ÿ!?vPwKF.sjm__yn/i ҹZ.J  @ps-w[Q>lԫSON+W(]xjZf~1^93ڵ3ltsM2jXheN1}4~iYs'&R\l}kF5CrB@NgG 7". 7bŋ+̎n^YfMBx9:Nt=5^BnkVVC/۰A|L2w[ >XL @NA[@@4HIowһS]QGPn%K7ԋ˶[m 3 oJu?9dY˹fZ2u@C{G*L7_>{WHIRϤͲ" G#߱NUɱ{9h[QtYy2eT)zNQZG>ː@:׍WӾ}fOJ(-kB sݲe*vݶ#~Y]XGFm=# ,ޣz[ݳ͓)"$ӹzru{$]oɪnr8.Փuls]SUas2bII3X4ȑ#u.J}'q=H! '`dD`;4dD>]k }JF }1 t   =CDa0.Ň@"7  >oż3M9C%Ke撵={I(LQ'L>,ꘖ$-j̃ D0;fii ؾ>h1S 2}ϖ!UO[ØS0 B I܌9@@Y2gK/L}=WרinZ ) {jQk9}'63m" /V5_rd˕EW(}+I5gBX7LN+7 MMjH܉oۚ{R! gv8>t0YNV\i1']3g.B~'[7o _E_癳ܹ̑s't&$P%K^zYG 7"3'N-ZHѢE͢^};VL\|K]rM7`!QU;5SME'B'd?puY] . tqOp\zK{{;}+!o4o_Z$F.t ,4[=;fh:]g3rgRڴi# Hۯ"LW̜)S& dҤILΤQF >g@Ewhܸ@iN!Rm~d 6B_-MIWB3hb$h^dE>5^v%l+?HIZmCWWd̙2k,P Yse7srk$j|-YsHҹ+=7L0;iݧHze ~"xs}?aݙ+ uH$GbyJ]mFO[Fw"O -e/sgMob9lM%Ix&++f,y$Ea_%ɴu*|6<ۦ䅛lO}r$z$([Q,4UxdpYŽ+gonq -E/k|"W"4v]Կoāͬ5dY7b?Kn,v-R+}u/ѡlٲr7e <|NGimK1߇h_EN~cnj}5j'u~AyRZ5jRGstq:-AӧOtWGLa&D >4ch G\\ Ci\_ "Vm%d!PoҺ2HKIHeSwtڡMlHkdG}+O޼-u&Ul9$[jLEWcO]16ӏX{Q>#Α{R`)ZH,$%"fܹERÏC[` ޡ-_zUϠt8MLS dŴTB8i؞zz߆9Þ-N=pY7t?AMeں;1#vȼMGTM0;i%ZU)Tc]e%2GI#eӑa{hjix;#$uk=Yu10.z!wM]eؙ/D`m;itg);dɑC )#5ԔZnjR7PzddΌ̒^ni!yk}럙(c &z{Y$E?3ඕ([捗Ԑ#Jgԫ2sL1ԣND$4b3`uverhSxwޟenfH>S*2xSRޜ==egKIs&)9y4کg,Lzf'cH6u1mlfOE7IȹXk7[KgLl9F418=w#w-w~?W7K-j)I޿ӸwtK^ۖoUJ7h3?Cz-?6c;ҢYWUd$2!bTDM0I4 Red qfauR[gRJ9)*dUFcD(fq,nq͌M~ロ^w޻O{t>yHi-SV{>W kFͻZlщ!"h|`"8Y6HEپ^`:Z~2p,j\w=w{ŅɎcSZ\W L'^pIvw N`yjWWsi'/nvz{*L ZZZ '$8LTWWg5y;+5_kaȸ08^JVFTB?.MMM{4uOk!}``v*-g0P.^9eV&3[nNFwk;R~w&=ocɔЬoqXa7w,+Ŋ2%RB?R]ز)̽ZR̩ʐ2X|py߮lv'cFSetb.tsb%Xf; %ݫOK'KQa#ʨ0NNV+\<,ErK)*yS( }rLJ\\ǹIr Їc$?2Ffʘ`- *LuhvZq/*L27xk_ߠL͟#%|k>+WJQr9FsmɱHr:+ȷ׶-JȤH$#1:tb^PY-*#^,*MYQ]L*lsl̆nxq ;GExoQ{1s5J3U8^h,4  P:AN PJ4NcwJ8[(EJ*đPtFB|@-{X>8 pDIv!+-ʙR0Vyp\,]*׆AV/92^헕{3-z{3}0NUh"ij|<{`c@M8ar5רg5470٦'^qO`eߋ<O9N8͓7|S%gÙ^?>iGB*Gpڗ Ӽu^ٿ IJ9*Mx ,y2U&|N.4SzizV G`Ll5ȿ[o޵Fm+EV"fD3t"1(sh-gZ+8{Rem"8>/?&?9&|N-t/Sw['#uk;$d6? G`e^V̇I& vDUj3Q a)k;H*Sxr=j/Ejm{!F(h;8lb?8iR Fs֏kx s[Dvugn铹s *#8E:[_C)>Ҽ*M4WɹDMV ÎYճp422zsā%#,\OyPȁ0Gu46 KjD/på"Q,)^lYdc.mKXF:q$ 3'Gy CS󳠯!*̋?]Hѿ?B)WSqA9W ^f<Ӊ 'qR|CJI dϬ|;5v4N30+O?R;riub㜾DmI\Aˇ)Sg=z\ K.D+]*o*eɒՋ(4Ògdǽác}y~eX*WCAɁCI=#'kbFDHEҍ^*&cJsB*WW['ɩ"ist*9uYlmF{O32B} h#%-2ZV|CWVQѿIs+䃖XůŬGe8fEqM HE~27^3yieNq Ȩlb ,2G03s%t*`c0];#[Jε݃ slB. !_#6V^ͯ=s!yf[MF;(EY+ۛ_BC籭[mgiFy5/^#rE@0&DހdoYU>c0ZWXncjF9yd2Vtܝ-n|'.|] ɂByEv;?+,j9bɔv<Ƀȳp$H0w#yʺu+wqQ$:B?S11ܢcNOJ,W c7?:UWg̘&dQ9Qm8o2J0h$QH&sez1Ԃo|hyWƙͧ~M7$KNX6ˤ9wAwS7K2e3Ov?iC?e/4i:ȜJ|:_t*T'x@[); DF,Z8_8g˙s^%cBaD=Sf/ Ӟx$o")_̯lLSzMΟ+iRd=WIݞ0·δˉSDcsfٴtA=sUۉ N f/m=j,C-9pO8pB:{rm4U#iίSe&r-%5W?s2 .IDATjK`#7LT g[]>;=Z_wop`S+[G:?.v ^)90E8#mMuRZcUŤT\wB#?_ ȜۤL`1:+cPw/;EprSVYr[Lm]|j#cs]4uh;2ޫU)BSwqOuȩ#˜յd"?, V*oAnxNcoTo/ ywJOY?}޲WZ>$&|!. s 'NUuB?w5_>f)G>o|_cO}ZVdMy3zRNJ 3gGy CK$D'o_aP-8~\' QG;0 3>YJ^=; T~<&/سgB ?9w:@\:9l1y=51S1Њ̨XawO)N>*ڮ(o4wߕ|P,8PU`y3o{1жVfGv͕os1%3RcMZfYP<2Y-e+ ɺ X\rj1a;So-Q葽 ?"GJוEO W,O3M4y;"_NKH[^6|(NsR:H ˮ'{ ȘPY]^Lш*,aݏaHr 9dC#QH$%?U?ʊaT19R畢+&^R6Ah|;hŬ$3Dı媂T/5*9LgRY_ղuv,.)jѐ,v͖O+,̶X$k!/4&yOfNi*}R:^/: {Ȉ+{"[݇_.wVőo[ǩkkK5(Mn/ղQ*J9y32nUk$oS;6?A Շd᭒?XhMe0UpD4пLDj><fɪ;d֗bܓatq1dLt=d,XYA` Z/RUST5g_(G>Dռ7+s+3MP5 Mb:e4࿟:!F{u 3HQ 3,2j|,%KtW|QJm7 13XDp;|W$7/OkމҸ͖4wF}p烓[˕[x fQ_}BI/)Ϳ;tl۶MH}O>!N ֗εq'(GzZ +mһrp})8! رc__˖_,zԉ$+Ջ2xbPκ"l|ne`/!AuH8]"H@'H7HzYX^/g[#A8Ov <ํ>7gO\I`tc &`pW2ԍ=鸂S}dG:|!pH\/'qw|7S|@rDI!+/.GLALr !:B:y Z_GRI%|S|wYe Owodo@ju<OXvch8[9a0߮}`i R(U PxƑ6Mծ g}Vπ^0ޜd]) *䮻<&-TxBZ@Fpy(JѨ4CrLOH dAxW:v0>֭@܃ķ ԮN 9b}UF&8/ ʔ'$~dֳdOqXn4+9>nMݡHYevBxLQҾqE>ƱM6lU>soGwB$LKq ŁRHq Łpaŷ%#B)Ct[b Mk X~]W^)G)/$Hct} -)+}h}0ɔcʰrwR>9H`0N a `ͱOx@ Yߡ㬵3+ S @Z'7ŁRHq Łr(g; v U0P 45r&{ٗ6d'~'C%+YڃNٰ* ±Zcj@)8@)\ dAHfuI&`(, FzS;':[{*zg$bmT8ŁRHq ŁRHq Ł ުt9aVIENDB`pacemaker-master/doc/Clusters_from_Scratch/en-US/images/f-13.3-hostname.png000066400000000000000000003762511217637305600267170ustar00rootroot00000000000000PNG  IHDR i1 iCCPICC ProfilexXgPMX`w9%眓sFrPQHV""HT  |﫺nW3==sByOtt8n{o& |~hw^ydOEƲ~ѱ`ƣagƃ8<}89Dc K}`(!`{6F:""j_1? =}|~QH\tO߇[DxliH?YiEyXڮc!ngX -Ͱ0{L _|l?v;4 ~8a4 *zX[>AD2AT4K= QLY@* 6!B$ qB($)Bd YA; AP<eAPTBU&tAF  /B !PG#,N/D"FD!{aK,b D$R)TG"m{Xd2YC!Y2 P2(-凊Ae*PMsjMBКhs:A/o/tO ÆǨa0PL*8sӋyǬaXNVk`˱wcX:vGq&Ha\)׃-6xQ&OƟ7Ot&L'hLBO"|'BD =1xXFB$1P$ <N2422L0|'Hb$=^IR3>iHee4ggڵڳ:::tfuu}tt ][ԗտ@ aa(hĘbl\a=HkcNlΫZGC 96['?Q|~iqN((;s2)S5ȂB¦"rQJiy?J *=C8f̪\|"eA*ܪjg>ruimGX]i=>~a \/l7F6694=hVknni9Պhop%K]m2m._W|}u嵾E۫nPou@]]nZqKVmەwX!dMݻ|/|n_<0o?ڃ4n>R9:X'*Ontw,+!vw'VNn` )Ei2%R3\e r%sZv_PXDy M -J*.i3l~5!7";b:cbntG |ǧU=> %Ň ?|"8my9 Wү&hMONθ72 7Kbb>Y&~Ҽ v|8ٲm? r qtEQ ht3F3݇N $hf-2*JZ{ZktJtO08aX`tƸʤٴŲf5gpӠ+uWپYo!o BVPdpUpF8-5XTGb,ρD$䒔}ά<ܙ5rSű/8~ĭN-"aP+v( ->S]v^HD\5~vtx.nnm^jt Uk%ڥnvwv޴v!NaOݾ{=Pwx3P8xihc ƺ}:kfZqm썹y ߖt?nYs j7u~15g@ ! (MQxF!QZ ]!b0o.8g#Db!y"S(6sY|bCyOMaN%3_BrUr+s? EO%)#T+l$ +*#L,^]-")E%!#$J@J'?pTLAiTX]_uAM=^CCQsUk|O]'=i}Aa1;63SsVyk\ulmv+o`\RZV^G~oyр `carVtvL]쭸 'RRoO?w0Pdfa,l#9zG5)K?!~RJ~]Q%JY)gЪʯ^VΥ>yz#oKܗn\A^uvxÿAͬ=^˾'=&?5;O}b9k1 @)\py S%Cv$xL@ _+@dC"HGd9r%:E3mq4bNK8<.ׇ kD^b.q!ɘ(XDecS˔`"5%;k2`gfoPtĕMny B5BZBEEzD}b-4@k('% d؛˦ʽTpVdVQ*TvRTyڢ1٢BS{BL]OoI1ɢٸ )E_6,vŎ.ܮnWNYhY◈O_YXH5ud{l@ː h!鎬AQD}4탾g{1Wx.[TBaEc`#n13v1i2Y0ّ% `вp(BC,D\P|V*+V򐔀Ԁt 9[rEK*e_ߪj!ښ̚Z={JuTuzmG Md9LP&V̿XYnYclm-<]nθ#JxX{yU{1 ಐa#Q)+qf ]IeLiYF?Wc'NvΟN*VwUU:\Xl( lbb׶k;:oR=ۓK7|?G O`610B« 7w?M;^޻ht/.+W}qwۺІݯg7_f#퓡eD\I@C9w0ژ{XK. Wt KǘdLb 7SҨ, p'^psvp>s7/[QBHWX]DETYLI\f(-)!&(ɑU+ijkQOD ^ÏT S_\V'Q6vfnNG\\Ϲ;1}n?o_0|ʫ'1E F)D7݈7Mx䑼(;$ٝe=v5bœO. <<Quxt-|E#wSmPk%Ͷ+.WG\va\?7x>(2T4xd l3/S_|4mlJmZt2+Ec ŧKe>}TlՕV_'=ڏkkQks?>\W]`Hݠ2wMͩ-խ[sǶ'ߵ\n\~.ͺz8ـJo?fRvQnbޥ|^ pHYs   IDATx ]E7~^$} .j@YqQgdt ~.ç7:fe#NTdW!J}#$;Nz_wgUVֽV{KJEO-JCb92@F #d2p PCCkѣ-aqZ\booGFF #d2@F #`"MMMF \ӓd2@F #dNt`B=^WڱcDzcl+#dtzC~aܹs@F #NnjQ<Cɖ-[z 3fq'&Lf Z>lJ ԩSog',Tjg??3WBps5׸$8ns#X8+Vwܡ1;we˖i4 8(6N9zSN4A]sͻKmr@4eojl@gzF #8XfuQ:o"1^criɘ1czL8`N-#df4 UnyGuӧ,,` l޼YgE8#QF h6WZ3˴iM&&NP;P{7oQh?>N Yem%?@fd2~%TDt5LRgΜ%K4x&K r"-ݻdIO(Gk)GVmIrɅ=ɩ@F #q2*pXzɇ} mmmK{[[[f`MD v-6k,wwɓ'RY@69pڴi*(X"P_'N}ڥ f,ˮ _$'MѣFi(?*+3utʶe,7Hh:G9Ms @awɽrm3JƎjv鐻?% VrY5TTJR)ʜɗ.?A9b{X9@F #__}ɶm䤓N>2W91_/pVK|9q?.z!g@֯_r(< bƋ u @aڵ:hMV:}xV[U&-IlnذA&MyOΚNcR@gzF #x* оG߾K.~2_=(w]Z&Oh1d f 1t+k&{.>Yb/w 6Lof+_FYc[:d2#ooڴI9]}s9`vB"7:,t2φ;!Apv,z1`trRSɖ mr`aϞ='}G|0 L!Ciyd'vHS+ҷn%].MuhƗa VJOp쾅?V;;;;q s%2{hu(CF # 3\m4g#w✭}h}t4M5$5BC#(,,_K|W>bB'n*~zCtF #x!+[lo5r؂cg6,:gP2@F``+^^;R>mMگ=l*vwIK/0ej,.|kYߐQSQ^}Ld2aG&[Q$pcol q s>Pν;=; ]&z6sPCY fsر*J > CTd2O1\s2ͣqoډ:4e筇uxk › !Mϯa֣l2Lȗ)Ie5,9µ\Cީgu`w s6|i,6 `} Kkǁ߃s:#<hK?UZ͕'0+Lֵѱq";wI 2א2^zL>d6#w,1sCF #`i.g ,M.c˖-jXӳggyq~,.㢟\۶~Vd2 *G~Vu }xm:m`>ޞCF #<p7 5uu77yɝq㵅2]-b^]3-#pd_3 j)g2@F`pj& u<~tsd2@F #?C.JMF3Tbszd~F #d2@F #04?1~d2@F #d2{kKY0#d2@F # @d2@F #d<>,@F #d2@F`%XGN/s_O7A}QYlcc6fʉ'7|f3Ø{.,3d2@F``}Fߜ M~{$7ϭu_HwF̊p;&.@v@~<Ox`+ghpg@F #3kNo{ vM>Z{{ U}3&)=utTCPF)um-֛.7X~`rʛ0a?OAF{κ1 "vz'>$T%n\rv<#md2@F #C7m^,ԑ֎2wޡҍA_; C ]|BƍEy(9y\`A]K[w=g'h0O4 rg{E֮*K=o#_ ɩG>t'M$۶o7?Rm>@+-W]т@ &Ph>XwuE/_G{08| ORK(CF #d2OOM nҷGF6 IiEy)ЉKeH{{qqc\ =,{( :8Rʵrh=LI=Ҙ^Zm/s0JL0/X@^L1"֜%"8MZe9٧@F #dt<**hXx46i_LӁ(Œm,*J*y7k ;x>2x:˦n[>w6ˣҕ}#W^K:\@ 37v84aG4R)@6xٍi{?.(-O mGtc.%y_m۷U8Ƹč1% ͕ KF #d2&ɮsiIz: oE`:D?3!}wI9ga2a℺ z^n[ eV-{ڔ}I,8U>ݟ4c6waaǍ].ir-[ BFРw0Na`|B|=#lO^+޼0w6r$ވ6g.-֌O4Yxt!qgG`$2O<9uϦo9ӵ2@F #x#˼/ )A뵇bک9iVKJGG'_uDxn ;e⎮<yIX%}h9jWwkh_|}"fQ*2sJY>f 6`WN;oxp?Laʨ߲}|up"ߋn4-A֑obcg9% ,&My6ɆeQ{ڤytz&ڷ^z'Ikى;vi8pG0)g@71R+>cz,Ȭ\ [._L02뮓 /p9ĝ;ȎZ96wG͗-1QZ5#BGdҷ˶ PeG)Hb2\Zř%Ė-[bɁ[N1">G+{d2p#U0a߉g?*xIڥҗ#M3\āH#^NGkc[g~8i3]].͓6af@qȰ˰ET[ ۮR+h#rXڮq@\pn@|bxWeg86^QnRY+=rͿN&b)ViixO5CGOl/3φ6>c֟3 cz27!<RR笛d2XRž(L6aT閦N @U)>^+olZ~BޏN#Xo?1e04'RF6;;˫jXOBnLQБ#g?Xy~.b#buCi^ocҴ oTL`ҊNuc#.<< :){ bj~V|?;D<8 9s㉂XXB )eZl CZ@F #<G {"@hi fG;WyQ译U:r+~\#[^Xr6oޕ掝?bҔC ?8t[k~ъri)Ϗub;pq 7ȫ_;OoX|FǤo)/ XbM;p`&6@D0"˻K_^pT%2a1apcmm|6I1AVie۰x"`'@ڕrd2ģ·Ai@TLWp#vLO@ y>|q]oⴑ"?OyCǒ|C=6twd -\8Tc(ti6Gb`|~ks8H%ArԑRei(fz)k0,2m+əCo"ݸ/}PlF t4$ q4 s`@挈'ΞCF #d2O?Ы >}O$Zwߪc?˯x1ʱ);'+4Wȧ,vwZSd庲LY ^Evu4AWϟ7·!7=$wf@Xaf?n<ģ# s \x025 c<82k,Y%WzH&<2ai!jG|#uWEuqPq34Xvc>%WB_^àЧPnR]%~$$IN#s8Hx^G'6fϔUJkf@pYv<;ct_z9|VIƀ{;\LEN?`% ;-QôUz0Y;p3l}skեX|(z @ IDAT o,}l#=X4Z0C"yQ y}Bl绻9`ˮynu~]d2@F``|ޱeĻH5 ]  }=X-DWO?eY,waL>+o>d6}(߻Me0:z(^j~eʔ)qըQ'@o(@{"=4Ap޼y#Vi ҙg)~g;8S͙"fy{dTa:J'=FWCukN+4:2{lޔ:~$E:uB#OPv8{©.x&@o6[SN9E^vYsоwF2|  )/:L?6|;Хl3gΌ3 Hp39Yc Q^(Nb{2BwO~l8kcn1=b'z姏ڍhx#2ȐnlܸQ;|qcQ9{lC17xכN4u07e@&N?t}0oZPukʾY4Xhd%yiJ`im۶I #ѣF7qՍ;B5?GY.}Ny:/Ǐu쮻իW\gjI5CfζnwRlYpst?k#|*b_9)Mi(t?x9d3@F #g ؇Ӷ\Ě鬒 0v8RrY L{w.4צwɫ}j&N/qsC9@,_8lGa!khm#&ϒygǻ6}@կ"> fLG ē/@F #d2Crc3r~Ǚͦ:U'ry axƬD9bǎrm ݱ#jLr@F #d) \gF #d2@F # d2@F #<اwlq}>Nr.zi-Z4(wl7sYĺ _;./$au@F #dF'V/^Y>Y>@_ }&C/Xbg@:ˢo|Unh8= tˮF[{˿,KT|T3˾ϑ6"W~Q>s?7M˒Eߒ#·>kDH>B'ʕo@?{ݷ˷:EՉC?d2@F #Gw|ŗAfc]rnC_{?|SɅ f`k| {\_D>rzo%VV(4N{Juf Wr6}w@{nɎj ws&ܵ[ayxgi-oM,]no\ʨ2^%dmhzz>_$_ޱZ~t\?"ӛ%mҰ61_E_mê 9/+|y:R?5|Ku7dϗ[e~L}T}[N:_oA۲oIYXZ;I_gsY'#d2MRiǰA ߳*xh`W} M͏_- >as or\rD|>4⭨=9\9MićDk[|\nVI/|t ]MZ/VڰI6n);mQxիHEX5lLco.\( ^m"ޢ嚯}ևIETم߼U"_|,v+H: *_چ/4OfOWz\|]-ҋtgw'?{rL6#bY;fv& wrX*x{UC Yq;^ujum[,w ]]n-\=Yb ߓ_(6\͆5vh[Xmo_~ ؋>a{]"[*m2} z/Qtr4~_4ɕrїʽ(_q./wʯb.ȴˍ -_ɻƻkK+7#>፺$n!#d2"yoBfVƞ^Y?kX(X.[xMg% <*Sik/R FV^P.0`藢$Xoh>]{O/R30޵L|B_x7oByۍW_(_6p?ptnsT4S_.goIo+HQ.|_6ݲ :i\sgP~qa9/>%G_TdoXt՗=R~xϺB!].-?xHϝ.}\/kPPu/X `}Ee鯓*/k~ FrTv|{E2__.6[+oWO7ROȢW42]*5C.O]Wˆ.\n%_B:xo|r$o~(?Qk=+cղiw*r+CC_3N{\!|Hߑ_x.y⾟/V#}軮S5 eK̎w/gߖ6]/]ܵn,(_tMWM7|U8 HOe\[ϟ(szW9x*˔fz_ܾRzˆ%.z7AZ9Y^(ʍ(wR6-ȿ[m)5&̙l|^9%'HKni>W='dy_ͿOJǎخZx^!s2X#Q/[1(7j9zܳ;r5&]H^4J*fb4Na~n;+ɱhwL{~-O}.JsքgT޾j4=-{'Y+ln|qHKSWmzϮ["$-ʥ?\"(|N<#c"=V&rwEƎ$'y2 a}K VE.[/r*t99SһYx_uT#O?GA(!9ߍmHAVgm@F #CQ]eʱϓ"ٴ˟W=}sj}կc0xc7lw%u9Klkm7zDF7B@Z uس+/{w?xpxf@^t+׼]-9'Js9D cڀC]>ipe ÉL c,dF^pdenu~3@F #x gu5eb>QZ+vY`dF;MfZ"nѯ[mAk&yݛ&=д(M~ԁ =ɷN/7M!qn>]Ί;;kEy׼},2؀*s/Fk{Bn?ʍA;o]=پK:{qy9~yd#^c +e"Tm7ʄg?x:Шl wwGQS&ȑg$+&cϔӦɘfo C%>g̔_!0d%@).н{k>_yC!X-G\~;}E/У9(zdCdڴ)СBtܾ]ϘDK37Q*ji~k&' (=J: seV4omYLwȭA.y䎕2sh)7)k?2r<1MtpLX(0[K?2x{uI}&Yf\+q q7-v~܁d2@FIB=ʕj=dѻk J.h}pr8$zKe٫'7&}=;HpF,IxptU>dRLnG,]xNynZkiX9sE\$ʽ.joN;NN:9qRi=V_urqv t0 70vZ$_n=,#2K./_g*'Oŀ@o2#7}N>-@o[LRab \ڰj[A7bxgk&uzW˳g4Pr!e2r? )zvє,`k~@$F9cE rͽsO;_ |K_YLNdǿ$ג3v|:Z?^۾S*2f(bO<}عxbO ʥ7 ;ƌ+z|Da[__un=Oz|KSYvlw_cAuȣ-x^}ʨxoj@S#ٻس-^i8Q1r߃ɘQ2$}ha;cǷHniĒ7ŧ|DxN`^14˨^{3WƷT䡫Z^o\FC+ 2@bnR@F #(MmcdLCt`IBJK~^ꮴx:wD_j_KDj}Wx|E3|n >],i= 7-{Џ>Mҕ68=xtR޳mC۱@dVtrGg&EoۍnlѾkl6 =;a!-[x]MXsd@$-uz |"E'M v͌ZzِŃ@0·RNFniMܸn'|b<m} x}ڽM%Iw}~C:"T_L%`Zlv)/FŪ6AH |#O!*$dd.d%4T缴Z)k̒,b*^-b#\/†*YcQ)P+|XPhᨃ)@idex"|W-ITBu&/kT,!|n[~DQ*Kʫk>AikMh,ƅԆo^|\(Cb|UHXAW3XCL]>0:.A5ne 2?Z@UH X5Dz슊u ?0Ynjc$:f+K}%ߖxM|oy$QΏ4*h7fkB@?PA!S c w&IwAx7CEM(D\8Gyix/R8)Pu Ffa(TǠ(q&YYNw6Zl@^Y;"͊RITiǒ:B:ndV1uT2Q?1hqSƌ" 'zޖI6wlU|*ڱm)Q(Z4m4~Z3 8ިbfF5T o_f[Q ]jT+Lx$%ZM B?aF#biڠ< IWQ]嬘s3A.3&dŤث#Hu{:羃Hܝ SU& ZYKUIz,bA< Kƭ]F! H7m9l=$xW~EYP܎hZ8~ЋkT$WpI*jtoQ?r A4b֭UkKrum t٘O@$_NJt dK!Qe@FUDQ~Ruu У7hTilK! <:YLPH02Jٔ4SdDbV"ZT6mDD]!+JF̘,IG6m6Y)Hi{%Ap2(4R+@]"i`[i>" DU;T]|u.-O"2SuB=NBʹC%9vG3@KiνI^QGA*JpA؅&t/mwdžJ݄ 3N:eaK'y z TiC6hL h<˹^2JWE&Bm$zz%LBG)siYI:3z xJQb,7q]!C Z\~UCCg@ȏ]EPѢLSz.Pm_7ٙ jN7j)r]ANY]Y\>mQX)GT :!R5FgY73)D5IbY!qD1UQm3,qU2HM!JB t>MH\:5 Z 6J2)Z54s&<&zl&x `ƃ]9aPa5A6gTEj~+.QRJSY3tyR!MMD UX`;֪I6ft -gm%,rj.$3S:Ɠt0x olPZ/K'P"(B:%U#ÙVKRU@"H|fJ.!$aA.7M\aϜR@!:^?1rgfd.#0y-rC3҃L^+ P[ 5T!`64Ta $b]?fbQr0t5"_LYk(e)BVh$ ڜ6tds/\1M*im1&=r̾k-ҺS4 9OYehA8!E$jBRAu} v&TO7Q?v)vnHMg܏ =_)tYu't;{t*i0* }K<StNM>D[S6i ["Mr)j"ŏ8Kڋ2Ev"b'HV1uG P29ľUWh"IPe>u6Y i'<G*_Lَu^2{<Ӷ+C*Ѹ".u?>Sҭ7sUT{2 s 'kZˢ %9PP%PFhmk9=6=֍IūNLMOLW ZF)D"fH0Fʥ ni>a$H0[M3H0]'SdmP{̳ܸy`e>FT2E̤QHL/*c"ëS7=QN1;uTD9"@ipY}nj; hv1Rs)Ɣë4T6+sT$g)#0L۩$v4L;Jiw>whQEnT fA&zE2-SZ!EueU \g`yZ@2oWb3 6B$mDnNˏ;Dw2BkcBbVQaL (f T=+Uu"f#LJT, 3;&E:"QG+1\LPyup 6'VFPjRb̈́MCY*Դ,5]%`Cs9("5MuhG;Gw(׀zs th4isDp濄65<2 }Êʁb ,VVn6P0׎T1!*m>l7Z2+MrS7p~h4hՃymcEMYmHbE0fPOIm2Q4`ЙTc ?jɲ͞<Kr}*Q̫BP+qgq/_1ۡvHJ1mltt :R( r9خ !J ҧNIP,$Mt}'x8uFT@!c'P- 2S5惛f!TdYi!L\tӌJeص@.}}/T&%A11C&Zb< J僘E`$2..P n<-NnT! LՉ YۚRQ^ZtIHΠzE DŽSڪ|%)f Q-&+tʫs 1pL V{(j lXrfAFrJd,h !0+y*YMS OUޡ|6]iD/SyGRTc.:BJǔaZ1SLX!C^mHi_s%3YI$zB$]U7j/t]RB=ِK \y;gOw -pvJjQ^d&BAႈc-_OC;Tt,왕͝)UUHBW :1t504 /҂BCBwaDqU |'&0 VqzqI# [m5UM$4+زNd1 'аAIt@Aܵ<EmJv~E1/CʨrdyPʑb>h nȱDȘ $O)o "* ( "f.:q 81SI~F9Sui竬T"O!^0 Kh6^!kۇ%!W,`݃D؝vzNjUU:3c<ֽZƋbi Ro~]QkHs@/Jw(_j߂=tr&9 ߯45ψ_) ` yD '@A-A=} pTcJ' ABg@ۗ [ =hN\'@\9Bt&S(Ҫ2$ P #u:*m[XaԎ!8nL&\c` (fCp5f&!v`, tX֜6gU?vQ). t@U|ǫ*}h=ƱL Xp6Yy.f=~?Z0&%\ڳ#O U$S;^˫ x%$n29y,)m\\9I%o Ɉ]IOA[RR.mPiCDJIAPb~,=RۮF4RJgݥ d&$seSX =_$[̀VE P $Vq=V-PkSEJĉAa\7?P3񪂯g'r;tV * v+<X+Tyr7.g@K@rQtC%]Lc˘ ;A=% 3Ap^hœf˶VoyzC] 4S[<ۯwbf3L;_K¨u ';M& 3S"E(^Wz}Ge%'- IDAT+u6B #q\a-jhq4Hlr#{I~U"P0.y++`BC۵2lʥLcCxʮv|Kp=8&x.c@+<LF2~6JQ,IpUŠf{i>Qȭ :| Q,t5Ȩ?-TFrjBp#5y<]c)4ruq1$1c3c΃D<IOtA7?D:*&/p3fQˡY;lf t EiFn֘^ 2&j8uZ ES.7s) XR9&fDbV- \Q yT 6$EE?M9 = -#F]@`* sL;Rp0s'Q>CuPA 1#' vJV€w| ji&eY4C)E)Jw&bWMHlD! 'rVRBdzćX;S:f= ciݭr*#P`ݍ- 0fܘklW[i׋[޾i|cf3C":bbŶ1PVƤ"8IJTJ.*O0 ʒh6 :8KzW(lB̈́r!Ì`-EIBM&c>LbTp^S i~dPXR5w}M)lu<(6&jLj(lQKoLR0 m*Vs_o17|0UJJUbO 5#< FJŽ}f I XRDP{*iNl _NwqƵΧҾkܬƩ3\!Ҙ7uUPq:n9#dlXKI>H*SE^%>z2LG:6i:̘]m ⒡E%c͆X c) Q vMϺkwYk>:vi Hi#2B@wlh;$ `4@tM A)mSӯYfZ]8:?8y[6130ض\/ʮaI/ᒟq9xO"B>]q,dvG}t_s,URgܱ*dq9H)aG4~ZXtacm!' G!D断qOPvb~47>3bvCl6ң^Ğ/!8g=.գC<>KN~kvJӿsνvqX { ^f?T?po}Sp+zw*㮪 ɹdCJX^,ZkAUq%!ob3@Rͭt_|&QTH }e8vq\k N90&Пn L|AsIkI.nW4hΕ` Y38W3⮫P'k^MZrq54KӪylp| ]>ό+气r"NmIq)el@0`:u#Q\Hwq(s<&/;O_^P`D'3q&[ =uda T)"R<`Ƒ8v"$jVt ctp9MLTsaciLl4EHPCId|Պ*\b0Wlޕ™yj#.H=ޔC{KcWύVka+ÛĉpRs`0%~)p;up}b|{ ޴!8Ľԥ7bbC%Aڳ@S1Hj6Bl/ac [c[8 0W ˸hQv8 nPiP~(mY6'[Dz$6WLRL@%*+ꀱ eC#Y($' 4FMRCߝx!;k͆۾Ofj)zbu* (RYN/1 pu$;mÁ?r7pyegJqeI S>`Xm8:!^:~pMWu3b[`c*WĄʛg>5hD_\AX5Uw,%NKp\>0gL7~1>\0;uxR@ɺ趍@b: U#}kЏ^YǝC&/dr~^'K͎^wBWnL j؆J`"ZެG+B8ĕȶ] y(@q3M-56֝ @ɞl8ǽTS2&2s#^x]\T p}!ξ)X:191ӎqQq-D~7Zr&l4n U,l0 ?V{=I{ } цpI5 iZ|ű+~x8]KAQ%«s^\Qk'%g=Js tT;վ^Et>iG)@01DŽX+ڀy͇_͐sWYץυƋhCEޠ WE]xZV[]|E.^Oo 8̗Y垫e%Uן~M}O^|WtC'@4y,g=3D XسybԧzNTEF~%j^t ɋ(Xǹjb&d2CGgؼ{ݣ ʤEs;1#C6| 7KҩvxJ)A_ уαsqk[J&pԐl筽ga;DGՐ} vlh?옮Wv${up):gO*9:78d_V!r<=%HoY&PGkwGY1uBO{g8WcG\9*o̭hP۶qk+WÙw!]1&O3GBnL 29ƒɛ%7GVLZ"0u6*~4n%Ad hMu%d ށ'zn p{3Gd2{B{e0rsY|tHKJ-Ӏx,ewa!(h`^P(+{X ∕H,a9e3-\Ds-~v%sn 00x@-zmoJ\9=X5Soœ @Sl=&W7?$Waa8f9ӆQYm pET蜌G'rZc̸quI8~Y .40dsS8l0;,tڠg;³&B:汙x_3&&k $v);cp8cTl)TWA`CSɆE 8W`<}A/>&7|և Cl))hWKS{l v߸{T + `:і|nZ f^F٘jk\'FqΐhI#1mM '!Ǜ#=Oym―{ !Orqa Q^tv$1!F:;gdRei-.f9eI6! 3䕤e9%cVr[89;UښH }[}O9A"_HAɼ]`rrvWm6tA=O@EB-t1J sR|-uf%D.tµ[}60o IP0#swnT 55W5l!녈`ãW;[9P&zH.5;·KS/ĻMKs `Csj!JxYO]靚qć^dh@ dޢܓ׵dom+ςIXr1!#MlX ,3'L0dZ'=xYmN臇b |2 X9 wāio5:;sp%:cvo&q^dEj .Gs|j'9g{SLVy&~70>k$H>2 %m] :S]3_X d!cZ&o ޳WX _*'vgCwDoߖ\IݪQ𳆌1_zex~/@L8il|1jb<7^x(. dV9%&9h#xË0/Jc+Ћn3!8a *uRsm!B u#Q8obagSwW͚c^'cg[ydv:}|c馷l^嶽4GZ/ZtR>WD;"U|JgnAEep4ls5vJpS;ڙq2KXd $ZU@k{=HۤPso2!6C}(;΁wl Z$'ގۀ=FBA c[%Nם:°-LAX?2 jZG9ДY&$?ئ p>y%k].k' 5xq,% v|^_3y*Tpzd*ӋRј6yK?>?l6Iψ.G_'ml];'>Cuavn.odZ1{||v?wİͺ024ol Ne toFW^6bYBjPӏ5\Yڽ#c8k@۸`۬& qy%d x:T8NID< DfSCdcXat]Țs"lN sA1\W"vO\K_9570inFJaŋ=ռ>?P~5owNFe'"]Q+T%zmG`%!'\muڈ9x̴P݆_Lvu=d,n\vkve{~o.xJbvv9K1yaQ  Mq,Si'r=5q0|W7hkę!c_C9HSE7YL'TOA.Q8L#nt:ܡqq v>j t;u 2[’T(ޖs3m.K<{*R mS!!!4(9 hj[).73jǜ?Hʕ l·7O v hHOnCKc} vLۣ+ۚk1Fe/7մښ?sS/>:WI\b\+.I<)(څZ`o$& uYWd/W7w:]TKHAjaß$PiE b֧a)#a0eÙdd*8qW4J܄ߨy{[7L"ne 07e};ء/u Ix30COה(Yt°gr$1't<~@3!O+=S\[2fG]F9AfauP^0aKgɄ`<Lfĕ|'[C8ںyVŖ;5N&?ˇ&gck3hGVeπ0{ & X}7cc睅˾byb$ݸtbi->[>ŬwNTh+,3 _xQ+f"> Yu|12UN$u P"};mfэ|$/ %k:qnl`=ȐW_Qr$^4Y0I^w䟅.eTf,eؽGxђPt'QK͸eBe0W4\#ރ M;,` .^ Hv5&xf1cB" +FXJ cH1s_<' IDATK&QLWܼfn ME+tbI̩[v_=\V-]AGK [}F;}OqoD߃ rW\}gy#6N64*b޳:@Y3!nZńY!?1֘>yȊmhSJq^VXG8|#y .R17^_o~{{{?p{˚vadOzs2OyȁSZ 3gSؠw;;evg鉠 Xֻc.4Vs5Bny#z&?71y!#2h`rhxud^s x$ o^ָǓzkM bM<"H^ٿA:unh%;0P6$O !J(Y4oܲc5{?;v ߔ y~k'mActi^LڪǹKyTZ-CiC}faЉޱ/%ar5Sl bA>/J1V?nYgt,ݟZF E7|*,u>P{ 6ϣRC46QҚlTM%Ѿ2vNv ۟+6?aS֧Qܦ4|H;5-پZHs<}\t)zjŇ0c9ˢ}# J'Vpf3<6CrXsI carWTF ff#0r ҃ގ+.2,<ϰgх_ڵ$V5.ٷ ~3`FՑ[G stݲ58:Ρi7_pCrg71&.vP[\<6сqYrLh:KikWQy z;Koe L~#Ĩ1*4x<^wBuٳstUˆfj͵wWGYo5D昊nH3!"ˮ$HP'y6l,\* 5Xj.\[!:Q2UG\}gjɆs?5iί֕0 T8'1;#Ys*2~3+!XlU֚\vtx(òbP0Of` f4]IƩqjy9R:R:%^FF8hqS]|C:6XmnjHqv mJ@8l]ih,Gcߎ^BۤeȮ,e+z%=uShGqa?uL2uGY:g柉9T )隴ngѠ2LaQzk3ܩK?ܾ_ʛ|/ß|SC=coZP0>3O u:Jx*`Rvt 5i+z'cYFp}wh}8x֬0^lS9raKCu b KS{{9&h.@G; {5|f BTs{9{3Ek 1L'N>Z{[iض 00Gy )3| \"m~Cgk 0rB [Wo&Dyf-l$169V#!%{f "wFRy<%n|al&8? M|UPn(x3uFkz<(J8ɕsɦ~ ANo,rٽ1ڳk5O،pܒFAM5pxO{Kyd3ul:l3x:O{Jbo&g|+_o=u9g6EExuɗ{C6^t\`9w}>QsyѸ~G_^m+"Iy/? ^[`80{H|[!CI'ڐ_WuGW.t?nw~÷/~/﷿WW^9C$XkN`ș-%UuL;  %>֐Wц hy “t]:a On;LȣZƹQ[LJ,GtnW?5ūATna,)xHˉH KI/%.~eHZ[S6Ǻ '1bX aq'=^2,.!RI.Mf0!c8SE`vO2fG޾9/mIel|ȚS|JEϧa!Ͽ[!t^#zmfXFqc7tu?5\rLs+qȵ7}g:6S 㜼38IBS9dO!́JаN#.b346 ҟ :|E3^(a%C|΋k5Y5Q8o꓏S?۟C#?KWo}wdЁ)G5g؜O%rZ^bwteRa_FԘlw26W'~YGbLÐAk\Dk8(33,]`UgH Kkd8AO kB*7Ch6Hb ?`|p,&Uϯs@m7M*.O6S1y᫉f8O'یI_'vv7O>}~T4|L!fyeȧ,yYRP-7ssD9oH?cJ3 ފ}"t{+6-*>VPyR1R'WMF$N$gs/puQ^\o?hjm%xqYGmfJȬ {.8=/ `gT/pvD 59rs.8+݄(s>S|0k.gM{Qq+$cS);[/r<ꏭ n}^x+_{Mgpz~&=1tDK.|*b| 1Qp f!G\ :w3"edD.~RMҸƖwܸGWUFŲEAw44o^9aϐ\Z jl{ ++)Z)Xɞ}X%Ajܢ k'Jh>w濻g>{{o|o|_|ʷy?z{)ԡc˝#`ٕޤs[=.cvliљb(/@R@0};Iw,/4FO~A#UI $h.wGe3s5"}as”(' *:`c U=ӿhg+,M/u9Ƿ"fiv^"ʻ\6ਸ/CGeRU9ָV0T*, +uEIp`;bq=9Ń($t HLX%O7Bbʎ5 ,~I8<ְ'8R}׾tү|1e%8?s{Ӌ'^O'Ft^rRs1U *hTj,1LjO@pNp5)&biUr}e1u:J[lg,øpK:/+ r>4́^K:h=E6Y#1Gj(r L'IY9q5w_P&"ٳC3d­zEO"~zS*i\/F (Dž\!Zmak uX=1f;un_ s;Qg,d؋'pABaK/'6)g6xQhh^>'=O'5rxZƼMtZm.@6F/q,FFX!lMsDn',W^>(FPs˅,3sZRa<EF쫠N ~!c6$}Pg]U,jӛQkSf0=ڡ9ř@9.YOp 9Ԋ>̖y¹&m ag]U(|dIZfX91wa=-=|$Yu lWձeىy Bh!+rKQ&# OvZg&.wMN'屩ޕ"e4+3F-W X3 rr;cUK9nMNya?㬥Wn<*}_\g Sag>{?uf_K!}xkrժޫ?׸eryXC. 5]Ϟ▰e@֣]zspEXEzdrͫ-K~mfI:R΁$~bL/< m%NMe1RBIFH: k"E ۳z9ʃwLzN#C +z[ؑ'-a+yq[PXSAzRb G27ȐY=H8i[.. `tn#qo|y}iu`χsZ1ų;}APLơ;"#ʜEi( <<6Ӳ\>'dGl'Sڣld 1r:GHSՀO uLw 9+ƹ&Jŵ1ҷexݍL{<σ[Y͆f=4*0yA<[Kfr{z6,w{I>ww~o|ۺ^~k_n} KnT-s;'QdSOOmið=XY`ݎPQZOڪMoS0n[r60I]rh|lbSƖ(?!,8p1yVj|h CSck$nJ=1prЖUzrO%˘Х]%8_R8/1gp#&Cg٫+]'x67gy|tw67v:Lqhf22ZͮgQ|ZَFl4r&N;{u&F"3+ybbؤ) 9/=q&^gYLKҸ-Zd|OBtSaXz=dTPSYـѝ`G R\U~ˎG^El@lٕrPQ˃V v56)/,a30s ka·l25dMBTh\wXvn%# e O1WHT^:I6ӵD~—y ?6.$6og{o(%y/!3>b i-|#c]b>πl1upZ⺀ DZvԙ`63# @=qq,`΅u&J@A"Q#6؋ڦ;JģQ;n8oA]w]h2I`r657^%pgC"GE7NdλZI׸Z5c`ّTq刷B1uO߼{>p{W_~ C?[C?_ODzḱ-yt&gן2 4SKPg@#$ړ:AUB~Q1Ǚ R퇊nLQG@bG3w]%͋bClLlwNe PM' ΣǡX)kxc^^>PA[N){P7r2)'k\$ =mS!0?z@X^ji"ւ<+n%ͧ<3Byރ8-fW[2C_ZyNdU .\>LFB0YvÊ2CƁf`ԤbM/B fF@(D2>9Aϗ+y+|Bi SK<#c,x1O-3@O? >iVwgy#xד2$wʈxZ׬ =ĄA^IFT6sかΧn5;Lb\|b'Mc3gT ldd"F']؝ʻWOz 2{nxh1YN`yM\+<A6:_Rzn zQǘA`o?>^ޙI4soWh+,q${55SaVt&5?Yx Ε F Ȳ:Jw67J`/rv>/'w2GYK_~r{AK_}Cs3FRHV[eQ}/y(Ӳ+YΩ5- ty߻_}5_qʗr)})6cq{Pe7CƨabS[Ÿ虭9\IoMaK~^o}#;=2G䗼V?3~|{w@[OGThU]OHK|r\L %$L DEaYҶ 똢0 M‹䯄Lf<X3h\= c/BYgxӭv׉Y0ZVClkrܛV+hj2Źj;`؟SE ;v򤀅_Ʋ*vsTStѾ$SdĄ.nWfa@vfd(Kl{τ2'ѩ9!WG cY]t|KHƠ5/5 WEB(` ~EQ%sH͝@ a["l{g6*뎰:an6b{V_ɢ0A_c'bkZ֝-?_F?x1 +s 7Z/==H'۟c?tr? ?g% DN3&5rV/N\믯؃ط3ُP׃[zN[>`/|_?{Q;ͷnWbOSϐ|C}}ut+2CAe _/Jɼ~ V.@]7\a#'cBcC 1|D8hyBⲞd=ú>ژx7KeX&%( fg[Z3^DSLN8LUP52"9(ڈmmsW +\ 0X4.PYgi9D4biϞ Wn<~Wp<٤D{U^^|^埽Yޏ~^K$ʷɝ,=^s)% O@ϮXj%Ee* G${H͌\ ~DǞ* Z'+̄J-$rat K=Q(m`nGM'&,|z˥Xޡ%CYWgX&1K' 3iE:C;Ps4E<60]9 ދ2/Ob9p DOşn>RY  ={u|ӌ?ᑨ\} REzxva xA()yR9I]g yp3t k OP%+wsH1y|[: +jrNxjݪџ8ZX5!麯Ak)dC ?<-8cQ!?' bt[pq]P"> ݘHm{oX{qTi@0.?*߱Q{X5k/B>aon8*NBw3*U޸$= g1#P_! ԊߡRȍc_7,uIPMu̻uS<Ϯ8 k"'Ïn_mfxO>|bSyA L~ccFvzL9-aaRP2Fkq>sml5B[|A޾[('!z|2~#yQwJ9^$2Cࡲg&VN/k530㙤V' <}~ }2u7\#;_x /KWf&R˸6hz}qmPYߩ/Z1,S?VI)Yt;v{a ч<)iΏ&szƬꁽ; \aPDlz(18׺+EɅ Po$}{^]gX#ۙ,xXޔ+B^~_Wh92q}DDZYQpV~z&xa{|m_pgGӻQ8?jxh:l-}rԿe!z {ut49oK)Z>o{;$9WG5A -slNOk)ܯbw#/KZ Hu>y_}4v_0zV/|5-CR5I>H^{G&E>tIEn;cLwF"G\2xfp ` oHmW05_ss*wr0{7b 2, =`nr@q];"u3 1 ǃi;`}I^?]2&׳%lq?FL٨50J].ິ/ PgìZNkkqmv3yu%eԦ҃gbB}^X*}G8<[\㺱OȒk΅'"cc[-'PchDul=.\]e*LGlzp6p @;],[+~[ 9?Ӂ̈́O"mMJnryAޗkv4dLe#!}mOPk}tyƨ osAfDyIS|]?;?T>!_K/>ߧܪԐ7$U/g]򈪨?0mv\3+4Am8cԫDBCsk'zT*=73a\0B{M<|y>hc>0eX֤b ]<c$ D=dʳITg=#ɹ$ӄρ !LmP6dt %>QŸ&'m4o49R*bDj9r9`.R\L?PB&mpy=<䚸egG]@<ιu_.I|+́x*:V6$ M*H\uPK7QB>رYQ8xcSd1ScLeURf+ᨣ!1}zCV빲ӬdHmnY{:e"A)xhWapHS>~o'_;9T|A+~@M;<ٟ95FǦ0 cSf_#7$"f$]}Y. ]T^N?8j7@|#L681*A[ xkvWؓڲ RŴWƦT@Ƀ:Z`:+pω y~~I~勯?7~9ymPQqqb : -sBNc-}Lc˳f´a.6ģggX:^7SWbG])sbo~ޞ|~֕륗nMI?_7>#/D`}Sh|dݿ+Le־%< a=4pq-@ܖdc:}l_B@N-zf!2%#ުyh" Ǧw>y>R[搭'CRbܬ)=W=~<ޮ2gMc.n {nȣd:[^HP.'w}xɹrT^\;. SeN};2&obQ?ބ!Eی["e&znjܬp^UJXBLe6<ͅү}y=ڙd-sjJ&ie=%f&n=Gxr}ƴ4LxO},^$$}pLRifcc,CP ĸ[b&w+ׁ?,ly2BJ9nو1#㊳A027V"4dɅ-ӛj**Eh3{)lD#A)߮ln jmfѤfolYd~ބ=;h6wzCM'N}$] {.f] 6zr)8E`( ?Ծ9֜wb ҝ"9T[( r`r%XY\F7eYiGаvexR1a/ʷd=(jwʗktG揝=9 IDATx'FYiP̉%fv;A{7̒s#One$p !0uu9Ɂ@S ak;0j~nDB &ofI쵊Ksh\ؐc22K#獃`{N#V32?hGVs1|w'9~W^JР% %eƸ"]65cC!v3Au_;ѐ F#/t'aua%#@Ķ{Ju]93Znd']'O|{?GCu~(}[/س5] !g:YЙ0!a o)Ԍ3¨$g?`8%P'q|Gĕ~0 |y>n&Z*gRN=Ex2lͰp=gfu[51gDD:B:43KH 0l1P9ӤɎkbe0't3h8itpO~㛇?1nk*.!r;:QLN,"3߉%~c ʳ);!z̳kHPp>`ܖoO^xWoo۫ow_}s__?_t']G>o/?_wys ^)yKX}~d't>~rBzL]T,_L>D\Odط>-5 erRCW[C՚ka*lWanh%l0v~]8sRzhAA.C'|;ӠS_ksJmzh0ujx w+ t]$4&Z1VT~>ܸ ?Vkѯ|Pէ^ CC n&JN?9T(A m0b@]'j$vό;hE [F6kVA8fߡ#忠}-_ {&k k!LT&w2ȯbFpGV tj]?iLAm#> Az1dc8e Ğ2jI:u;:&st7ew9Rc A\.`G݈pG}H g#(J`6\sx  >Os x]tEO iXB 1pnM(Jrw:tQ%'lH.6r~/]f u8p!d&)Yh%C ' r!) 8ossP3d= aSruqPs ݚʻO{G?ڛGe}sN&229B JE8`QպtY媫NX ]U]F[VDEƄBB朜sz}뾞N]}w~~{G>gA™TY/xㅏ~sz[1ks沏~ Q_G^^\~'uy{>?|[x'}}zG&]pm_hҤ[T3dO|#|޹H~ң/}:c'MoՅ=_ *j GOz#;&ZO.ȽB4pV˻c~}?f[vwk~ {/?Ɵ<|.D<<jVL9IiNHtɄ~KN}TX#`n:r9G|>>'ޖW)ř,'Rɺ"7m֓΍h'%4h; :cSءC}o$RVl cia0A :wM^CtJ7`cl 9m";X8z-xuc.q5`S7ଠ}Y(e :|}B,ŬͫÙsK<̑GQmc8ƆIwxfāvnשԟ/VL!|[]2Gƭ7kNw#n>_oDXbCugn+! a,"c2t#YҳKF#=$DWT2)9ր8Tf\1_azQ\ fCJК#mBX2ξWA_.~j,y ܩHw*Q/ XM쏴C؎ OR;NJx @J#'Fz֊Iw`!dUO>Ό)Ꝋ_ LEǮYqԸ{Hr+DsEap: *xfgg=Qm1ZL  ]B!?%Ұ`(A ?nRڡYDxh O)vqҿn  }H{s|s w<2CI;N:Hv[g=mRkΩ 0@1jQwLg^ÙXG%sH{k"Rh@ClV QgGs.=1Dw1x'94Kqn [q6U4&r]T~SF܈7$[n]tôˆhɘ꯱mub (mc:}|`j ֟jftg0ܱ$V| /ZW>K&ϟnk l{j]y \\ǟ=MH7(@}*]~W~,{_Ͽ{N\U|'+O- `|'>~Kױ@F~Sw'zE@/_"gO~?z%)orsG@uktyk֒i{ӏ [z/Aoh?pȽ|ޫƫ!)z+r6c7{6<*=ttQᤌRvNz$; )غrĽ4夺"\Qnڑ{m~G^!g$[p1ܛ}hmqj&鈲b۫W#B)Q͍~|9HwiX퇏ac֋S9J? hK4SR"7 l?F"-?4';al |b0pQ=)Жop\Y1M1 $NЍ1RD:wi\_=I7 ׺p7z=Wy/[7!ꑓ{l''5a6sփ<#"Sy ?&Be`(a4g:m]pٓ[Z B:[-kӹMʃ9`+ /oQSy?u fmy,9472n7yֵ}ڦ ~,zD3K*/ xt<2"NDǒcVǩt\Lpz G햭mݖI&2怋wx8rrhV>:m 9B ujLK:@\Wێ6'F1NvޯD'r^AX&P,RړTFR0 Ǣ"ۼ))G^tcGO|^gJo7]~z+>_M_S?>߰|ޑngW;gzCMPBˍG= En@NVo_|LT\,-|nnkޮbmPs>Q7UЏ[?[nަ}'._^q/}>P~G߼iE>!_m)K,¦r\7#y=Bmi֩@h?I=&ejhp+uZ> )r7#f(.i=ִ&9?q0lF擔A[Lڨģ[VV `훻|&t+zHlḴ Rr58Ģ= ;- UNNֵn3}nk4"kBclLj>N'rCբkߣrDz`eŮ ˹UO>15E*a,kϧQ(+rMނE֍G01}9Tvwq^o|ߏ> ~ͯx+/!z}%O_ŪSnoK?tKzD7_aE_K>UC>|~;^ӗyӻܫ>+_tJ>=u򳗟=뉗eϽş(9W~ׯ}iz%a/߭zy~ݯσ<˯u\xk^vSU>ǝoAߪW;>pYE_g+쮗?q{TUOL|Əϧx_пxʅt&fIKdͼ8OSr3Hj z䫿94X/HI@ڜ9MَG jOڽ)تLV^PEpb!7S[5d#+n<̟5q?.U]:u2#q!4e$kCi}jg+}AGT4K?[}iM>8d^z]P Qp .Lɣ'K'ɲ=D\[nӊjiRnll!տ7xsTZ(##5]XfK{g!Gjo<q|'Q'<WQ؞FG{&3YӠraz[*V8$`;rxo BRS1;7 SPä4ؤl7vr ޚqЛ \69zuΈwd_mǓ 9"<:8*pd8d4i ؂vƀ, q=TD&TNfkLѪWeW6? s.Gs0. DdEc <'h?\\1$6'P#ob8;s"rmϳjgl6sgS7Atu^[zޯoMzK>i#'/_#?ߑ>gk _˗mGߠ3K#}qx?4@>]f=sV9sy'R.^_>u+Ыoܫ|!3;ޟ9s^_9kA*o[?py?|゛^70^{.Wx'= P^Ի.[~=}? Rx} Sv?ψyy/ Q}{~g./\xuOwi zDhc,Yg2&۽Z) `>.x NPpsdZ{˱Aj VmCuNyH/} bxGD pvƪUgs4j.0ʭlLK݋mAvxRRa!*nhHѳ9 fL%]m&2Hd㱤vWڵt:P&16i#EՆ=TC) O(3$37+&6yg5^4&SONd֟C/9Ʃ>kf^aa Eҵ01=d Wb>1~Z{kd88Au ]ȬQH=,@K2z32ޖŇvMK:D;n^oՒKㅴ1pmbNAI: fUukO Ɖ+W#;rp^{:}$&~RBg&`wu e9VCYp~`T'1簓ւߧ4ٝ^ouƽgCsпw߅-c4RekxD0|FNsBotl!؅junq#ޯm6畡jNŨ6.r5;1> j܄4vlR_ʠ6NMŚt&| ø\˜=Nj\&xI%?!oкI)gN+ZZ\`.[\>>M'=Ưh,w_wsXG䕑||.ew,;|_cۺ蕏c&7H:oOOuI݀}+!I y1 _%;۲ҷc D6Fozv-e9fsqRGLi1vzAFX %.~Ĝ㋋ޞ/f 밣Var)&c9*XSOJv3u]w!\h?3oŇjZ u 8@4wc+J g;}]MT7h}*+ Iekjyĩ;.$8fLj:xh IDAT[qdip6X[\奋G_/oJDŎ{lÖ5)aBf=Y\t5'nH)kx{>&Zn1cxKKxz?Ƅ2Т7Z.f˹[ i][2gy25YoσGp<{z[k`nFK@量[xホ~f1youqn{){|! - R)h1ZݸM@} bd\1qH|d9d^L:_.9Y'flʱR`ktR_ږYZ),KϢ&z̥̞o|m d5 !QTQGu˞BFߌu]Qaa1/eZt6Wz6rnyA>^Kiq )[z@o\Z[& Nۻcֿ .Q3b.;0er6XjYTycR̎83o|^ylݼNO{/.2Z}-\r,|ǫV ]@Ozm^M.AxCuܶÏc>_W~w6'Lxʼ]yVz Շ<@Y#Ez^{偏e7vW]̮+~ScQSZնOٺG2Wou7>>Ode{׺prmC7\Yj)LIizx:r)C+C2 <a-s@;/0uB V* cBXĽA+DBDN41-9\c+_QR#6񨵰|@o_kNzUn"DTGndMY=Nr8EfrkvVb'"].Ub% >Hv'kyQ&4KrފcN?IE'fh 66B{qK >QL=l Z+xO`ϗ9re㐸| i,mB\ӗwXMz&;=*v)й0fnEÊ5ƥslcݞ|1Y-a7;0=}$a1OMA{ࡋ mMUǎE95@ 7і-Ys[9JxUPr]OImZgpF޶b}+(_ K $c>6~Ap֣,@XMwd\}Bv-`Z\ku!ad:4]Z(:8e/\sދ.{7'_pL#8)|Dl.6o֙V?zbR&3.>{F] 7*?]zo7Sd^_iǣOՇ[|##c7{?GDU-~*@1Q?Z&wٲnQjomn5h1*ۇУX{J=<0PKzXQup^[bsRb)Bx!ޣ <:|v)]/>^~ϩx'|R>~[ᕏw A/QgUc*#7 J.EVaa}sPn?=c:Mx)C)#7$'ƛ>hpXv}JNqS(m&!KbbK֍$ThM֯>Y!өJǓdo ӟL "ӍTSȶ0hbgރ3`9R9e,^QTiz<`b5YfY̱4y ޜG]kz DMqF5PPK'"n,R5B3}D; c^؃iVrA]hmS+V:)i}1":֪u֩AF #\xs]1&oz0M?mQkHIV"9=dtg>ԓrH}o:s|nivKB=UUUd5.&!RCelrbHFA۹kKn]0XN_:.#W1j[Tiƭc7xG8tU6 0j_I<}ɺ ^:7+x iu3K{C'@NAǶͩ h;n*98<&uvۻlnvנ9 i/7BuYxZ J<f8QnjzH&ʼ"zV|#([Tҏ}uE>1 >Y1OA iiYw }#ysǨ9;"'44,ªfr̒Pil~e@<)eA'M'%e"^2:<-a]kǏt|XL%O,W!D<@L|0ڵTy,O2%r9T^MbzMSk"Cimy' +Jt'+G>ɬ)[kGUAlE=밁2EL]7gRhB4{Hfsu g%:c5Fp<-Y-.Sphw0Rɢ^{k~i^>y>9NRWw/m-k0z/d*bRY[1Yk6H%WV_ҁ#bĆpk6Y}wݵm߲7^ƓAZ!};.}0u"ҾONW?Bh?|Ts & v2(гC{y[;滱$YOۻgh~9ޯ:A9:GL~ru;ty`l@G<715Ccv}0~HqT` fĢQāAIg`*Ii;2Aoϑ`{@!p̹etIԨi2F{j}d:ՕY'?~pNYr Cu'pg;t 99BY*T}̯'@`p4 #VP…(9F6sc!/Fρq3ҵ-8)pP<"/q[ƌ(;sߏ&yxv&I&f@~LC@(~Bq)M=_8֢׾|Mi{ Ƅz¯Xlä~,Xe"`*FA0eTqMX1Usм-Ъ4Ѵ-.vm\ mHidã13Q#YUM52cӵIAo8ml~bAm;m^[ln`N ¼R= &Y,A-%݁U9|LI1@Mxd=_>ń.3>{@ O? ~c~ƃ5<-=۲a5=Y^uSN){/|H_ax~0Oˋ粲'|zg K?闿=oN:92.m[_>e"$봪knmɈ@V.UD+LQcȎ"*I!XU;lUs=U&Xc܏N=ia;{<߹Y;{rH&__`pY6j$㆗sj h/[(gB?t\2$񵰖<vD3xs.|W|7*Q 0"f=D 1BH`jI]vƆ/8wHI Hrƅ[~H³_uQjK/g\~WY+ ش? 8Z$_imN=>K?B5/MiѷH)W-$r~H zr|W>BoZCoW ?#Sk q1J΅i75>"|ΓaL]Qu dZ=^$Z,7Ta!Vޛ,څ:3蛐M)IS;K{x!φ^䦓>C7Mi.7 mKN^VNp&ml B~DO[4t5._@d?ׯ'GHʈqbG5w1yx缲aѮ/S-8gp8scf?ZV8>8VF~-J]]D9\m H35Q[;M%ha1 _أ_>3>E p:O|#/?~^8! HźQ/V'<ǟ}5y{e ˟V>}~xq/MHx/|v++fw|ϿDW0hxR5H?wy_D5\spAv꯵} +%~ YIc}YghWNY(YT57EY~IIPatI٨]jH _ݙN$w1ρ@*{?o7O/tF1<GjF dqؽg 2 lu[8\۠~rMvf\XOkDHW+ܘ0.GaMj7ςiW7UUE$mc"(3hRڎF^#Q0u t!AJgjLʂI1 `ÕNEYe 5w98 Zc&JȔ cw%cDVlƞ*Ζ5kЎͭ@4Wg^Փ󓎩=(e=qi=x! |@_ nm. m{t^WWp[~}uyRjz zǯҷ|/s_DZ5_mVw\ޤ`|~o> ͕e˻ noEU]>%O/RƷ{1FYr]?~Z8|Q[\>/7g/so#_t~/| |~] (ٽz+>rݭ}y?x<Ífߣ1hNNk#x-M8<1J~*zYPlETtwFI2i?эvJfe^Oc,ʭp ^KPH< ܢS`](N5K{ڐv|{шQɞy]% BWiz.k=+ ̃JxυЎ3$4J`wÊ0- Sb]n\8GR5YvR 'n\̻9~@F#᪠['x@kR뎨=$ޱH{Kjøɻ3)v Fsm|n!`a(=Kw?Gj*M )VьNCk7I_O^ 7Jpv#?דXغ  cw[`!ߑd7NrgA0ȷ94v0T`{$` !JXnJz^S  u}FZ.ъHT%1V}UW\7 &musfK0t^8d5<c7 *d%nyB촎p( IDAT%ʷT x6VX:2D?YAɣ[|H巂^W C/ΝX!(QvL"7 Yj._KbLF'*JR /~|NgϾe^~-x~7"?~L~R}W| Ǟt?;^ç@o/}緌x7_=ї]+;?+gc%Z7-t;OIo0z&1Vyw-}IY}.= y`$߷-,cdޕz7Ɔө[Yjy3x3?Hś]ر InY%^bU.=8- IF.jj$ȎjfYiߚVrR[?݄u`P􁍢"4KnπjoeOuL t]W?VenuBELԬ)t#a{lTe?3_GvO%?lZ^h0kf:7v+ю +*橩|N"$˹ӵ@$4s`6%M;FN}5@}r{Nt5Y⺄9! VC;Ip v"3=cJz=:9Mͺo) v(yC@v7 jf尷}sW's8ˆ740ot5.W8cx|, k?s*7N=x }. {Ko>3w/_W/|яo:Ǥ')X_yu]o.3>T֫$^Wos+8/~μjr\AussN!m56º$.`{aZv*쉗_o@RiRIJv1Ă)ڣ~Cq0nqi35@ocF}?k`?l3ʳ(}4UٟŦڷ@[z~Cv;- 9kg &1}|vא$yC|l3uaxK/_jFZkzۚ 벶AVvH7p2Cb|L |\4 aWb]mƇ]ocGT;f)gi;fFR[= kG Cxc(j$[>t d:&N&o\x`\3 8'!TxWU`:6Hʓ:Xt֎B۶mw 3Ix68v7;`Ǧ$wQUVXC6w;~,7rn*_ۘn}w)&Ex4^/*{@\Loy|۫~/~g CN/y~‡)Yz>;k^_WY_:d92CAzcz3v;o|_{t?oѫo;?D6m=zj)Bë׾^[>蛲nVr3.oy.ߡǫ> 95ˏż>xɺi?+@y?j/zS.o׏2M~*:0Ik03#ӽI dF5jj]~@:GyҟQY!dr[3)زaχd3oi_Xˠ&Cf.NM.ĢqlgY-|;|1/ϵ$Z+N`HήV\:XL\!9/\ịrW0E, ?Y%)Igp&#J\` BL>ju*qs$]TX x;@ ͇$|T?3i,ɑA (o݁H`z/prebw=lo2S訚kTO=kⰕW cя)s) Vx+W<&l :4m7/T!/85ҹ:ѯ=[s!&/I\M]5q;"tU`?)>w~՜^qR oŮJp/X zbJ9G%|h`sun-I4fBzN.,MYQWh2{m0 )G #"LJ[iGĞCCq֊}|ꠁѷ_ tgsgLn1t(Z/:+g,: +¬4.;&s; gT(z:GǺ`o߯ ]-(CZ]|vywȽo{|DyXe?JP0{4| 'qA; Z8+x/q*7#lwD_6|e[>znFU emn17~m J}nROv4I]W ?k1y,ւ?>[54cj5Dm㮰ceo1s sY m^8l0|ڝ%nFЃ.R·*FG*Bi~oU,Ne^kLf9zHII@,MΣ2hijn@1~D1o!n+ͫ=֙yO"K`'|W ?0;Cƛv0WG"aU躼c~}h4u7Xw2fF-`h*v?ܼRp327"0) HE!\ɦ5&zwS[gQrq6GupNL07Yo!9wŲ%tskMcODc1j\HzDsqx6dձ䑃3yFY2CMWҹ _ m ^]n02,=ls|,غ ]ǯAs?&藟ui}Z`E ϙ#?D0tȩTM\rbUT*E5/쭼bF9~tJ'5 6)1=慳0Zik!Ru \ʸ͞鰀WCx E&ƩpݒY%Fdk M]mk%hA5cշ~0F*Xf[JV(R{aǂQ-Xyo泽c6$i1=#O9 >H!ggzV,ul9F4VC>relO} 'H\]3kҭ L րŮC{>>%'e+kW p"g0< pC(d!';#؃6fG'4.`w|l7|Ʉ-^p#9b9fNwiaeqvP506g޶5XYwg|J((wvxZ#7:')nR 7N&-6Ԍ"$ȃ+>Whts Pۜ1FCl#ZsA/ >#5|t's?PXܚ>!3nۉ<0 #;e>qG ne2M9{ZU5@mG~Y0Bt'bѐ;Tϭ',rtby F<9w0M<`2 0WM^iIrf"ڍm2|.g܁÷qMRgޖBn* хv7 ߪh!ՍcYvV]hev$h+Nkh}ԉy Z3TΙ 0`6g?Ce0HHkڝ" ltg=8nޢ!ym&X(XmR{*͟,CsJ(3 Qo:ôg.JK)\|4 !e4K܆U]@6F掠<,<$tc&wh(7208YU`6aS€(5Ww:FVgTF /2=kͿ`vp9pYQٮIJ1OkH±jc"sYμZW2 qLL,)1MC[ 6D |xb⣽hQ_z͌+(SdNaș\6- ϡCnl鰏BDL_׌^MrbsNfd1!jz7x~ݖ\!ըrt\qKvylrݞFuNÇNINɞY:oImᕽm<#~x'&?8 (k: 4lD]eyEraNWd;&qq$$;hߖM8di }s56ý}5cdtp]jm|7R|,R˫8!3(Σn{su]Mfd11(Tn.<Q=jXG:b;pNY/9Lduy@ ihNL60 F+4P2rI¥wi i0 yX7%/US 6՘pјc4q]ˁ@N7 yqoZp <#Mj1.bam0< AD&g{0.ǴsxVq=C q~#J^EaL7Q46֑s)2(GX/b@ f5:p876Q+ՍX*Uhi'^rx xqSrV1D^^Q m %(#1GJ.(I87'Xv _XX t^> K pD7i ec[XdqW6<0Hc4gdákT yz}[Ӽ{hWs櫞OK'y۠m&NNSӨ8meu"CIF_ؕ[_GZ=RQ_^k|ܙ.T>+օmW&C^; I(gkH`ajwe)|EVvkᬢFo|U{6\}j+ RYy-. !PWVLDqp 9sv# ݢ_z 7˘0kXdo,Wv5וP_iomHn۝z:BۭŁ\Κ}l;FLjqp#A͘Z"R/OE08Q"ч=ju3\n@HIcM$rvv:M_Id6 H,򰌞 7_ȑGa>|`bB0#$SfL`ᴼqT6]$_IIMf' K쉃RiZ.F>@;Ʋ1|{jzsw썧(S #zY} :䱒؁Ǭ3$GIܶD&EZnZDz'L{8|t{ Lj"f̓<9d-me:ի-T[zT?yQQP;LSвDlmOP,0Bbz3|ߞE3q&ȒҀ#RT[5 |0RJ<9H߄7I!o/4إ1{N@05ߝvf8)&a j>RUN *ѢI\bGj`Q 5`mHxf b7|aR83#9[H yъ+:uw9JtVMŖa9qGi%|҂koO& IDATV뺃nj[iz<biGT8) 3GkT.t+͑O!I.51hL3UEEs:0j6<޷҃|ǦȋV Ҵn-16C[uRأ;!o-Ix@h+uS, ڥ6gmI GXB O]Y<})Fpy?kj .wO jnM: K2ioK2o+k,66Ɩr>}-XZ_פph"H.h|EPsMBܓd(`Z1lVT0l{1+3TJ^>D;N" v$s:hpYBsuV:axţ<7(|kS ^T6v993{3@Tx-s юY랾6!}rǐvѩR'/aUmFd C7cTd< 9uweDV)hX+5u0 k'kr_^]adN:9rffv}n׮ʴ)N2ۖ\.~zu-( _gߔ7lK5SH +n,ug=ɣ&=Y8(&Қm#'m-?*|cY'.${r o[C(܀݈}Er8=y¨棷#r[5Σ.uƆTD;h~mOj:cx\ ilm늺A`Oз,'%eu4Z] I۔y#sf{fͷQvԃcVkDrDRmɂ rԎ'2b3V;(R*QQzҢاz;^9mH5F; 6iH$Z>hIÛ~W&+h9M!SF~RLfa`Hs ?z) b ˃|4(372Wپ TO  `°ŁajRa.jD9xd (`Q]jθ"ZG_XiW|CTbJqFm/Lk cb.%o%)yN!11fW)~ܥqZ~xL3 I?2ExψHZpLox rDH? 7ܴ&nZkM't bDߐI3t{$eBQKA1X: һ?"3:܄DGZ~Xxn} H /&d#S5P'Ki53c]<8-p5b|NLMk.VOW&fpOd}T>h^~[s/SX*_DN軡Sӎ]3s'yx~sV;c چ Fɩ5R5%'ȽT|>:R(t>J_5MSt؁PSVTۺ>!*ahHT9Q5X8X(2D}2}Rj  OIk9Jh[ 'S2SoT]1@>{nזRz(GE!pZG1 ҁA݊c[ MQ94RHK.߉bp2)>TVf+;݂ ԶÇӒcU¯'o=Vr/G* ]SebFv~ؗ]pwSe =`"jl`>mjdow +5.iagM=jvp!u:YWK;qu4!KSm8Σyp_gt#f5.ޥُp{c¨Dc`j֟nGw,2(Cm/IX߰n6tkЉ?A'LR0R*M4}`ȳjq 5bդ9HOFqRNĺkeR[7==s5&姄kgm+tye `~&=0Tb?L9[#l>Q.Ewڛ ڵ52hWY$=Zk(2l)u-%Ex1bfn.kZ4F+EE.YH9{%'z)o5( أnm6 o{brFۃ*m/{hWQ $B %H(4Yx*RޛA(JT@Jh"B"-֬ٳ=& dMr̬5ߞ}>=mM ̪0rf㶍u=b6Xۜ'G2! !h }Q5bh^jjƀpmGRn¥kN &u,Zwq \%cP¨ 8w'f-+|}lFsѩPe@m뛥'p a~ҫAU˲qo&Z4 T48dߌd)j׏.Ch+Af?=x@i66p?*<9e}l}6AcDE컍~ ćpViLO|'֓;]K''Ov,UtrvI\U7Uʉ͖M##6)Ig4vSH|nJ%K¿Lz 'K-y TvqLørn_|q`mۇ`:Fءɨ'hvIS UMje jl?`tf-Rπ~%@ e[<.}!I xZ祎e,B ]0"T,XxS6VA2W\HZ_zϴ?z@|SCɷHOSZp oN8)_ h1_X<3upX4K>Ifcl85 W器.F道-ǧXM++XmY)u9L^au­;ۤC`|p6>e۸aK,f |1S nzk]C7 u3#|kx|6%$OLZY/bйYR/'[ڔ칂( !m.7P7Svǂq2]}W8ΔIyZkrFA}d tDb~iX? S8Nd {A N{m(~Q8(C/Œ[l)ۆI8Te - j0;i⛐CC;ZAŒYҿl0(o2Մ a6wakLTɆyr0ahn8I1^Hf\2OVfcv(&YJ͢"e9a8Y(r0.YY*#[M~؆Ji--ŁOcqfc-TN#B},-=d6\+.ɘ_orMSK$I}g۹qæIq-|z-ncL>*4ʗ >M% 2j-ԥP\Im A.aJa_4k&x(B{exxiE:@?nnA߹g*Y*iYk{"٤AsM S NTt>ˀB7sHX\V̓ѐWL7sxA˗*[ 8ahf[0VR; ԑ i<$նj[?)/rmyA| kh(9c릭[n!T^ނ![aS7;C#/f+f''Vmm|j WP6||@ᘚQK),ArU 3V[߮(-ls `lngI4)kP9d6pM/UfȮsTV6SB[8]´ŎlIz뙈E>Էh3-cA}`#帬YF lH{Cǹsi'煴XpϺ$r,IJsy 36Yk&*S7Ju0(ufrubl^4ͳ>D~@Wǂհq GAdqJ5WM2l} /mV8U9@V| pK*&purlp Y dicBCK&R/f-7& j*[ a {PnX0ꄞb&\UUMnO敚CS:1c~ʱޢ7r9B_bY d#p2erYqԾ=0sJ*,ӥJ}Mڡ-\l'uEoZ0yF[{Xu$BCaI"VB.&)ļNc@<1重Eublkpj.)tXUK ZPFfNjY{M2ƈ}[= 04rԗyk962r@{ ,hd6JN F* [7Iy{*eh~v҉*L]EK(68g4H8c>vN2ٛ:GH OGdS}OA,+Z4AV䤎ܟ4 tWjfyCi"jhE$/moEm"græ!z!^K]X|  Rl"hj]7Pٛ) ᦄ z cHq* RWJMv/\0E%վ0VW{xm_a$wKC6_idX]S2| 2ϥ HV=J1Һ:;hQ}) L~{Q& ?d8Uh|HqRxS@Wz[j*K%sCW-3HFjnSͶ I/?U_;@?mR|>8gf;8T0,t֖֩Ĵ7L7y319~򰜉&f8Rj} l>ar'[̂4w33wj 5otE0͏; ,Y[eޢP`~4Av=/\a.&Ws@0,6A!]>XğcZD< #cZp;N$WKzeKxn =8x7A3[FRheck!rіհo]*|eo' A9Рm6hރ4+[XD)=a8ٻrKp`&OYblheR ?%=3цcB3ybnc5?e,L.@M[ٲ 4l~ʈ ;MIk4]*/ ZmQsc&bK9M*sTLJX$?&WyXǘc t9i$ĖYз{z*{cn`TiLJ&m*5]u)4dr0BDtȍ68lѱG!Q9"I9FBk4bhZf Y' =뛤$FIϝ VxJX[1u+t/M L8J_mOK?뉘{0Jgsٵ^>q6_iOfе'j ,!LQ,gfԨQBK{b=kG,8ꫥ#a}QC& UvJMօ0ui<0uho2clinU2Z9FR4̾Ԕ*Ukq+;TbB7t͛LN Ud e)jChxjORDtM"S]C /E;61*TŊv$vԬʋ.f‡U[7^dԚjd аF ͔8賑jk܍ `E;,O%^M{qP/t`jЧTxP&/e Sn.PTz*=̒2OBHFأr  Bh[%/ JwlP,mIUm︛{O_d]1bu.fIi2czH̽i6L0Vk'ݔrۈ 1b\7AibvJܿ\pKǂT,O`( )fv1^%ʹFػ1+dGT5TA; OSIɎbY[{@*)(ȩD.C2wB#,j pzٕ]萵e,(5p .p}co܍Ku-GElʁQASֽ} ԥދإ?6]9EvG%CChZ#I]IۛN ǎʱ׿y 濊rPćʴc.~AN胍x(3\ %,*gHj >jo*XI;%9n&EYd|֡!Y0 6672 ݳ LV&1 ]+tF7 3p/u]D0Q̥@ll7>瓭Zi4SKi!ǟc\t&Cʴ9A9kj08ER=-%mۄRHh0u+msJ HM- kMva@tnc64Zh}1TSfLiN5 עzJ2P*ȥ -BlD&ʫj5$H{0_Cjؗf`P@#b8)fl%?"x- e280^GO*q("G1,t;H%j`ƶMF߻9r &{ 9F3wM8˵f(3 lm4Ƈe>6S`}IXSnnpUr=9cWW (' дN9JH*_ ;nQޗcdҪ&Ph^_.6dP%ۍػesW7% !|Nla97=#!K[d?h'nڗf7{YW!A(CdFGRFNf57Orx)B +F?neRюʣpcñ|gwP#KZ_K, Xa ޛl1xeC q{Nz.OzdƛMsN4EO!5b*؜Tj#Jr 꺝b`ZzmHETG}yݖWɺJkLȶ\tlSʎ cMHuyzN&K/0`)t; W"7hna%l"ROg綖Am%O{t0'fscЦ-pR zAm ɖI2kWfQKSdr !A4PJc>#ꜧ *xXs$+U^#v+J- l*X0k;Tf5r.:7` \gd34i5İ&LS9mm1S>ݹ*, G?bʱ(lT -`ivmQͷ, HKƓ^g*;|UnRhhPN DKNZ` \C%{0%] Ӫ89vTU~NPih&^Ah䷙ MfMwݰv21(x$+UNPޛ[9\60@I5HmWAGKTC{MdlRL۶:v/mqUҳj7V ϊ"϶JA#a:95b -~̥GFوng?ia1YCоXbѓR[O~rYmrc>Z3[5/Hqx;ZMP9NݠW>PY#m@g@$ȃ;1`ZkǛ";_4I\|4 GJLbiz\qW4L9"^.Ir3*`e9 q,Fj4{ z~;ؘWU[mDiIRĄ B;ȫU,@hzF]&QΟviSY] 5<<4l>Oz"eH6U/<.nkcvdBă&A$ëT|z-ln$dzj F;qfꨶqUYW3&/6g,pAEKzOR[Cnh=2ؙKeeG)FW2klmDux@il8)JrTBE>SK:yO1tAdJSNԣfwU|sNZ*αrPu]U |p;R$eV|[gkf0kZu2eހbSb&_vn0AˆvP[eO\m`Pz GU,Ax*S}נ{1eoT0q :ķ7Bz5[ZM(*㻁 kmvfK!đUsM[#[bWM4-5c3pz~z_UP!+.<[аQKZ{ RߪI<81% :% DxjJ* jV4<&//|: M/&LܭԛmA19Xm{Rk; 0T ǤY?Fl"F5 |e-Ӗ&ΤEՓ,tJȉjBtB ¤6Ջ5fi!lXZ_C\kB~{2Hcc|, *l(P)V`i:ܨBޖ) %մLVÛ0$8A@ 0mR4i2*K-le)Gyov t;-BWƳ?9QM ݙ?Mt2ذ ,l7.lv J[6(j7e&̷!TKli | 8 +ǝ<=0cTyk<xm8\Ӗ|Ve5{i X,K+ɩ96Eɘa3&:(j =X" a8G%$vL0 \Ċv-T8)[ 9D0{Q|.2mHjT&*T&1%=5w7JY1yȒ!qYQ P7i>؅/TRHPY` a &E61bh>!!GDCnP)i Ȗ5mi0mlrQ -by~Yʀ\Me`G.*,别:NHU$Tї@V }5b\*9 [ ,|rQ2.hK wD,0b[7d b1*+ɨTInd_3M[vBmܤ,ŲLp WŽoH&ڭMBr$._lRBv-*:5Rt2 VV>4n8`4&6Yx`rG; -&:, ;6bb *sFuk5ySf~un|bcEsRn4ML̪!&ʠeJc,IjΛ /"Qb`v9~ЭS7N?eS]1x.ʇ/]rִP~TajOBVƷ!ۏAx]ɇ:eqۢΠESp,ʌ{TWW.q-ZzV9EXsfuK*⸟քTvY?2M&ԶeC%ZW]2`e o3qJB4f3r׆{շU2z N+|%VXsmJ9@bL07FT댣Fz:;G1>U/V>yߘዏpxRdj :mт5=%Ɉ6J>*YշRL_SjǨ%{Q! 1%/mݤgAm뙗,$AJi٠:/ne\@B( 諛ݤ'n{b_ ke4corMLi (|29ыwFasZ!b$4깁Ds-r =L O~Ex N]em+ z9^K44?R>nUy6ePHQ~'7S!ߩT2M8VE3N[Xf,C;t[/ãe?XpE;Y7*}vc̺W\;2>dAfd4{cM`ؿK~H@WNǏڴ )%0/nfI7!K5ED%UWQ` d*iL:VyW3"%]7J=|4'gN2.l8&oڀafYqrTgte0U*H8 vu*F֞/̡tBp@V%]Ujzr>ЪǁGHr;}I>kS궰6-6ȴz75pcǭG 33H)âOql (2eB1)a1+@MBFnA},|ZX3 4vkw ^j:|.9W ,"*U`gd3 nRO R0@Y !na"Ѹ: q1!)?ꊧ'w88"+fDq'xR[pD^[j}J٫5$l Dl',(O]wAu9:iܮ3ڞTWklmpE2*BI؋\9 hN [GRg$CV5mt64*ݿNn/|,2 /1l".өUWgPpAxw`a{h \ChJ8HZ'mzΟ-^J9>\ ~&ie -\(v"J4ۮi#5%lPU,r֠ک挿ĥ [6[r '}YX7}6bx25 [oMb>6Dlu_*ųp#&mϮ&5:ʲܠ_e#1PKEbyKYjĐt :S虤!J2o P«2zqʀ ݔ #o [Z Ԑ$θIS1zjb.r:2V_eGA4wIGg^RĂi)y]LĜlZ>N6F0 @0 @0   @0 @0 @X^0 @0 @0 t#Fr:` `  G` w_ IDAT` `H7@0 @0 @0Pg  u> @0 @0 @,@܀` ` :` ` ` Fbҍt0 @0 @0 H@0 @0 @72 n$7` ` `@,@|D/` ` Xt# @0 @0 ubR#z@0 @0 @0Ѝ  ` ` ` 3 : ` ` nd  Hn@@0 @0 @X^0 @0 @0 t#Fr:` `  G` ` `H7@0 @0 @0Pg  u> @0 @0 @,@܀` ` :` ` ` Fbҍt0 @0 @0 H@0 @0 @72 n$7` ` `@,@|D/` ` Xt# @0 @0 ubR#z@0 @0 @0Ѝ  ` ` ` 3 : ` ` nd  HnG.Yb`y7;b6]`=w!dt]$.܂` 'TXdŠ+{#J7GwyS;v}t( ,w|U{ 0bQ` `@\yAx;n89wFe֗Æcg)gW\ql&/Hg}_.\Ʈ Ē2z uh_eM6ḙF|lV>뭷f\ !jky'ͷR8!{ggD2 1v 4_9g;nueɡdѫ 'M_koYjedŕV?!Kn뮗'#ZZƏ?X@qxjwߍ6ޘ\ ݑ zZlEr8h+G:` >  >}o֬|"Zptrr] &}O*9묳Y>㏗v\~eGI?/?^s_~Oegߎgqkgʭ~[=Ьm+7:SN , {챧wȩ,'W!;07yWv(n?Ns=GR.OdeuLp<_Z.?\xG_ R+oMqJ[w7uطlC}')ye΍3|` ``2π[>[Eh~mYs5}챩m?]Mۯf̘!`rʉ',<o^MqJ+$묳oijdm[:_ :2*d8~G4o3w=zoʠ %;hm {[vhOF5mf5jFe-mXw)1ǎ#Ov2CeWUP뮕r-뮻N.htWiQqfdskVԭWv[T,f2p Ugͪrfugx<;cw@0 @0u> )z?>ןg ח5y]]vނ+@g4}W_g>WpSYPr-DVuo9JGK;OGpJT>_v'+0R7vm۷_neX=m;e okzuAy/ϫ\4m< JYZ㩫0~0 @0ag#cCt)w#yṅ/ 3ޙ!>or}OP7\ >OY ؉a @0 GbO{#k~y]lEݗ8WQp: Izz?A5jo 'x qǑz5_^xI|N_QM{ٰ L 9x`9#uKܗ% -_w?}Y,>q&F__eXp{yud/Y ;[3v>c- } Ww%0C @0 > ߂u.zϒ]MKS~<.sl'y ?;vCD :ƀKT-W ` ` > |]#}+2Us魟EGW^\!{cG?` ` =-,]`!l\TFAoKoƒ,@\hŇ/@t%` ` &߭A[~, F~37&fx[Myo-)k,آoӢkꪇ]tωYsdȿ^zSy5w괦p! >h 7N\ ~2J0 @0 Fz SF,>}"trwq5Woų]飸L͒鯼#>0;GoHs@0 @0 d3ykԩͿ<ܿͻÆ6\.@[ 6+^ W\+o͔3g Yx6=J0 @0 @0  -Xo~CU?yeܺ|oke^mVo;G^{kY Xe]x O뫿W9×0[k]4X|ͮB|%*xRKRK/#?r)q˼J}` ` 1c ' pzyyg l+f̜\Ɨ^b^hc۲pDq}R<;v{.`  F_=_TO}SMo6ݶ~ {jK.EjZg̺+X<ɆcޘG_t2db(T+gŕV?җ]v]cM%e|? e~1n ?)j+R6֓k#e}Rz뭲٧7'gZxIe-aSO=M\|Ųzw1c3ά8~{+"_׈fGgiv[w{!33[12.զrs[Ŧܤ9rqMrK:LVp≮\Kmټt;3?뮗[Ə?8}. 9qN6xci4Ghjk8k~0 @000W@Sp\axGJdh= ;2c 媟u%(w]~`'avz;ϙ"(z\}Ut0yMv%wm@?^NGNO.'MW^y|+_)ޣ5Xp2rHygG){n)*v,b{ʂʩLف$v >'隆|2a촲p!s$^?fQg?ۻヒcɵ'^.;񺽼S{x>G?eܸ&mK7߿@.kn:ח^fi9H8(Xsܿ8KG־hq` `@/@sA_;3+ 5SNo@X`wߓΒO?Gρoꋗ.`p;"B\]瘣O}fvok+.UWM'h?WK[o,R|9&]]lZ\8frQGɞ{U[}zr:vXܔDz~c9s뮽FƌCaÆq#zX ||7Ը}娣&Vgw{!t77}Grio,}ّ\8h7I;\~S9Zk޼n:3?P]dx^Hku#nw[˱qQ@0  H?p]-iԯ1vLg3&,~ W 5!ܖUV! -Nv҄{J^Zs|J+$묳ouJ!llgy۪[;{ēNx@m.tpW7ePxh[(AQecS'p~nQܖXݯ^۶5n#k̯1uw}F5ayNSu'xnߑ#q|q[8K[Y[C#N` Roj,[p'˯4Oa7XOvya]z֭z%߂K}az\,~ Y XhZ G/x@뮕r-뮻NeYޒ/}yG5Ce_fdqsV\{ͯdteLW kූc p.:qn]cz#4b~kd'R]KoS3| n H 9ʸ1z=>` ``~a ]_fv9mcye7T|H92x!2՗j'6EسW=o^ ѫCޑ7~Wޜ񮼡?`]eeW ߯l s)|.Op[[v2y΅2tsۭ;l_n/e  ʹ󃀏D6m::x6,qJ\oqwqF @0 |H_Ai/Mc*^q^wgVaQ!>32tP9n '~~9@`2]]aJGoҁ>m!GyG;}PW=,}xU;l{q2iy?/rb;&m)EՈ#ؾQ`D싷p,|-MȅZk)ӦMwމ_;ּlLpiR}NQW8hs{c3dq/t@0 gstЃOʨWoe5s ̙v_xr n<)\aJ55=oR^jEHz.<Ջ6SfkX->fm\Զ9;gq>}l6>0]v'e8!ȍFp%E^套^SӧVk,RqL҇s&G|~zL[SU|5&:  v,^[|`~֔M'n*;IOE W 74;O?dj"  @0 i_]n);v_^x邇ɛ6`V p;֟2c,ѻwl;߀V\p\ [X&,FF0 @0 @0 tDj{2֡=orJ" onۖ4@{UXt`8` ` 3 \xWoyxbƌwТF3 oLzZa/G"1_/6g @0 -;|R'` `T~o2]p=I.#jY)zY}eqMUi Wd]`@wi8nB=|xۺ8q;V{,>` ` hꌾmy-W5џ, i/j  W@~.<.JY2c3l}OV[}u9S[<^yudž1 ` `  fx_&oXد!72@vh1q9j Ok7[,:\^,ҿBj_k.{}+*gL@0 @0 Y{Ђ Q3u[^hdM8j(ς -(. Z~+VKиg?Z-7rBGoop 7^/O>XLwcdʃ5S/(}2W,Aտo[}3`?^"o;o1k3kzb/F{nge W^؏D c` ` ``^2c?D3GowhL. K*+>'2][g,pyt?վW?W@*}# >W\Eԇ7XoVJ_}1G寙O|,2/~p<3Eo|2~w% ζ7 p rG=wۃ0]vp]-m_nrݵȚk):u~e+.?^yr~ mqR/~Iƌ#}vs:` ` h I ~S꺘[KEYĻmS{\8`."V\aTQoҚYȬ,SN? ++_L-X뭿<ӂ+=CWY|;mk(&"aI ..v%XBw93Xlň_|Qv/'7@N?4.` ` ` d<~W.txπ:uo^y8No*3-FvU0b^x}Q}Fkv3gΔs=W(ƌCٰacC=L s)(C -@aW*_.{[i:o!Rph??-@+"/L{Nβ[I'HYl` ` 0c $}*?nJK~ӮR]}4h[Ǧ ~n&LaFH~շ|ՌRg ǧz"nߔs;CēO-`cZz[ǟP[B(i㿾E̖[$%@0 @0 ]bG ]ʸNx}饗G6bZ|at5jze2`uqU뮻oZne{;vuۉlzUZngtN@0 @0 ]aG+~}V\aYhr-ⅯF~٭d믿>0Z(]r%o۩[vYފu{L#G{Kۉ' m)^ 6mZF0 @0 @0YbY˄C&At| ?./3ʑF*f5}=\կ ]cرgmP^xaac;9_|}]okjW/|ꫯtvŬ ` ` ?H8@Mu[_q3/gM̙ l|y+3tc՞!i$@0 @0 ==; =A@0 @0 @002W@ÝC` ` zX7` ` |c@0 @0 @O1 b>@0 @0 !wz 9` ` )bSG` ` ``>d  N!@0 @0 =@,@z @0 @0 ̇ d>1` ` `HO1q` ` Ẋ;= @0 @0 )#n0 @0 @002 pǐ` ` boO_s47i0 |$ۧ,EdGɚ+ H) @0 tXtOM~aue%O@>Qasfˋ/NcN8ZfC ` zXļl% zb` 30gȿ/$oWmb@0 @G;d_[4&IP<(@0 @,@>@{YwqO"`;"<(@0 @,@= ` ` > "` ` ``~a  ˞8>|曝𚷦ZQgrmkB @0 Gy뮻dA[wޙk%\'C=T>+̼|.3C ` ` > ȇ@xd &t1Κ5냞&0 4 ` y@-@^ukeWZY?=&.\Ʈ Ē2z ۰=l^m2?Q6dS:lɧ+R6d[~Ͼ\P[o>3[m-O<}ݲ[0ń쩧o.bYwrgvnA>O + vA.H6pCYfed5הSO=j,[o,}NJ^g?+-eO?]O>]>:,c=dv6.} -a.W^yKs E(;n-ë,\rlFʸqs87|lxKwe-Qs ?\odWV[MN>vs}e]va?>PW|lQ@0 @ xXnW^o,?/?^9h<^{+|2{dYN?]:LYdEtUWQݧOo9eȑ3#^d+e.F6osOq /"W6P5֨w+Xu]Ȱ,iO;R5ݑ@>_rK1b_](͗w}W&M$?eWСCH]r2qK_R{,Hk36p\wuc=NVYeOʅۖM7ݤW(|` `d XxAʱ [ mX+:i+]lmg;|*vA$]( Oqщ',<\̘1Cp2eh;^A ̩Mᶟ|h,_~ڪ՝h?">8pU[O>a+M(y‚ |֢n)ˣ>Zv;hC> 0,Bp6l|* _}WV_3Δ)SNz6Z/_grms,sB zV|9qV` ` zn[,2[pUc))oӧ\ݵ{o[n>ɍMM2so|;򶮉*=os fds+^+ޞӘP߾⒟跧o3ftpɵc?1 N=GyoCӦMkǫmz[xan<] \Z/> c+r/q<=X^Y'<]3yccr#b|ӟgre>_|N57g}6[G,zp}ɕ'5`%}9c,C8^g0@0 @0S d^=8mU?|>([Z.[{pjذp珓6izee;pV+5ydyg? :ۚ?2 |!_ YޝGU@l . &-EQ(^"H-;TW@DЈ, "f$J ynrd&z8g.}{ι{NuI_aJ/"u eS:nAn&v??kg߻ήL키~]_6o,W_}gMvޘ ջ2:_"W^M0Ub ,PhFI tČ3dl3>i\yBjٚZ7=~p˩fFg҉vŊfvfOY7LUVycHt'}g   ?rQ{ ~Dn0}˖-%w}W^hirupk~Lt0}{7իW^g4<)/NxQ~cƙB޶m[15QYǏEqʯ&L7y2:" PEv[N(&:fD73a(cwX@@ ) uΉ@! aEL{XgbA@B(ԣ8άW0vE ]@hѢϼA@RHf*sn@@(:rR%< 0>@wߺ>T  P\zEQr1{,I΂ Nx>  E1 Eo[.'OZ5K zc2UrgZ6! `,:kKʮ}$9e: _A*ҳ]sY*r@^QA@@;%  X/@b}   KZ  $ և "  ;%  X/@b}   KZ  $ և "  ;%  X/@b}   KZ  $ և "  ;%  X/@b}   KZ  $ և "  ;%  X/@b}   KZ  $ և "  ;%  X/@b}   KZ  $ և "  ;%  X/@b}   KZ  $ և "  ;%  X/@b}   KZ  $ և "  ;%  X/@b}   KZ  $ և "  ;%  X/@b}   KZ  $ և "  ;%  X/@b}   KZ  $ և "  ;%  X/@b}   KZ  $ և "  ;%  X/@b}   KZ  $ և "  ;%  X/@b}   KZ  $ և "  ;%  X/@b}   KZ  $ և "  ;%  X/@b}   KZ  $ և "  ;%  X/@b}   KZ  $ և "  ;%  X/@b}   KZ  $ և "  ;%  X/@b}   KZ  $ և "  ;%  X/@b}   KZ  $ և "  ;%  X/@b}   KZ  $ և "  ;%  X/@b}   KZ  $ և "  ;%  X/@b}   KZ  $ և "  ;%  X/@b}   KZ  $ և "  ;%  X/@b}   KZ  $ և "  ;%  X/@b}   KZ  $ և "  ;%  X/@b}   KZ  $ և "] IDAT  ;%  X/@b}   KZ  $ և "  ;%  X/@b}   KZ  $ և "  ;%  X/@b}   KZ  $ և "  ;%  X/@b}   KZ  $ և "  ;%  X/@b}   KZ  $ և "  ;%  X/@b}   KZ  $ և "  ;%  X/@b}   KZ  $ և "  ;%  X/@b}   KZ  $ և "  ;%  X/@b}   KZ  $ և "  ;%  X/@b}   KZ  $ և "  ;%  X/@b}   KZ  $ և "  ;%  X/@b}   KZ  $ և "  ;%  X/@b}   KZ  $ և "  ;%  X/@b}   KZ  $ և "  ;%  X/@b}   KZ  $ և "  ;%  X/@b}   KZ  $ և "  ;%  X/@b}   KZ  $ և "  ;%  X/@b}   KZ  $ և "  ;%  X/@b}   KZ  $ և "  ;%  X/@b}   KZ  $ և "  ;%  X/@b}   KZ  $ և "  ;%  X/@b}   KZ  $ և "  ;%  X/@b}   KZ  $ և "  ;%  X/@b}   KZ  $ և "  ;%  X/@b}   KZ  $ և "  ;%  X/@b}   KZ  $ և "  ;%  X/@b}   KZ  $ և "  ;%  X/@b}   KZ  $ և "  ;%  X/@b}   KZ  $ և "  ;%  X/@b}   KZ  $ և "  ;%  X/@b}   KZ  $ և "  ;%  X/@b}   KZ  $ և "  ;%  X/@b}   KZ  $ և "  ;%  X/@b}   KZ  $ և "  ;%  X/@b}   KZ  $ և "  ;%  X/@b}   KZ  $ և "  ;%  X/@b}   KZ  $ և "  ;%  X/@b}   KZ  $ և "  ;%  X/@b}   KZ  $ և "  ;%  X/@b}   KZ  $ և "  ;%  X/@b}   KZ  $ և "  ;%  X/@b}   KZ  $ և "  ;%  X/@b}   KZ  $ և "  ;%  X/@b}   KZ  $ և "  ;%  X/@b}   KZ  $ և "  ;%  X/@b}   KZ  $ և "  ;%  X/@b}   KZ  $ և "  ;%  X/@b}   KZ  $ և "  ;%  X/@b}   KZ  $ և " +믿ӧE_Y(h|@@rYb$&&zեzg @ Uɓҽ{Yl9r$$ H%Kĉc/$!Ĺ@RT@T j"+"Wo/W'NX?۫c{  @ 5HII3gJz+'mڴ5n /PJ.7D"@  HvҹsgydԩXbTTIJŔ2eH }1%:k>E1  gN۠a#)Q}^wjժ/˗7>Vʌwޑ+TPOeJɒ?C^US@G~'Ȃ ̴;y7+S]ʕ+{ ɇ=;jBr&E" (xb7oTZEO%&&F^~e֖-[X.$ 4@I@n̙3Gj׮%]vRY 2d:tH6l _~a,ٞгa+  ༀv:miڤ4=RnU´J6m*_|y X B/xc΀ X-,^wrʥ,g}07U֭M"Dbccn[P;@@,X/NrxY/gf*cf ߗW" VR 8*xzC /k^H@DZ  @1 (A.&2 V!bs*@@ Hq~@@ Q9  ]h?  (@R؜ @@.@Rܿ@@B )DlN  @q )ڏ  @! "6B@@ oG@@H@ S!  PH@7#  P$ ͩ@@($ @@@(DBT  w    H!bs*@@@Lq  @A NId'ZPp%T`.WM:yMD4P@@SNw˦_ѣG]hRdɒRReiѲ4hHJ.&6̏ؐޟ#@@/ȵ^+ ib~/r_VfaŋTL)iР'?b;5h@@@]mXNQ1Ktzǣi&(-?Ljժ%EWHMWGl!6!  1G17v*P~9Q9u*9ܮ!6t\^bC  @>}nWy_SRN1XRÉMf|Kl肕qA@""*݈MI@Ɲ" Q O<.6):y](ʖ'NW[6wI:yRB?%ˁ @p_য়Ҫyru7xSnܸ!-ܸiUGmL>X0ό_9vԾpIRޜ @Z $>XT0fv}uYP0K>8T20zÍ9rπ ' 3  O: ?&(>H:^{+W^O%Kɞ={\~^+VxYs9QWiʕWbEСlڴ)8 C /ϖ-^'7|wd+"F1ɯ ʌn$ h/  PH||ɇr};~tFOnm6nϥrү_qFRJrCOeތ$B\~r6l ~;ѣ  `@nh-;vh/طW,],]MQr\wQ:{x{MHRr%xOe?ogi*'{͝O|b~])UT׬FΑ+y'X34> M+~I*UxݯK&w0`\wu/W]uPv$$<}=\Ex yvǪZw} ލ\4Y|g7ߔN:ywW?r-^wwz1߿t5}ԪU˴ސ2@@"_9*!7ەxI>tٱiҸR󬚲-۶Hf-ujב_XdYf]/zێ^ڻh=uU/GSN_-?\zܹ\s5^jnI$Cͫ㻝S Tȍ5֟eb}7^":ʬ3%L)+%̝-Z #FȮ]d֬YnrzKMn͌;?`„ 1?V$t+@%@@ESq淲RRc~.vU?MMU{5uիQFrdc\\(ח?&Mz+pI&Ly4l;%w9Tn$&&J.]w2r3]w˺uq Z' m7x띏 ik}~E9ԬU$tFqӗR$xM'RVmYcbc-tN;垻K2e$Ww2x|3ˡq>^y'd„:{w‚NN1eVoذދsVllJ2InߕHz(x 䯀fPoŊ̬W@OexJ\\yt3 K/=mI1۴w^a~9)$H+q~Qݣu~15ꯢ]4i,4ixkxҾҭۍѣk߯Ʀe/|_N/8b IDAT=w,3f#SNKKژU䭩oɠ} ԏo]oa իy-L˰aLOygA=6mj qݑƍ12鎺宻?ϦVg?Nc}'E8WD+  @nvLε̝7GJ{7w;-ț_3 ~' J*I7zف&:{^~'qf‹/NAʗ_~)/wlٲY=7Cf ݁ep)Ǐ/>Dw!WIVoN|I_"Lk?]6m}Gپk/;MAK5d/'5O41>3|wӟ57wN>3Df]e!>c?sGx3]vY3?&ۮ8ϝ;t{3’<  Pie$+U]'fvKll9n׷ޯ߷hs}[ ?kN@\ps4-L0$/y '(SLK/m 5j?{ヲ֟/}Ν;۫;뾚NիW~99z'-66W}>^~mp۳;̣ͮG6ukd5a)q5p  @ɤ$>m 0'?uE(=zvuU̘:޴MiuK2[(W^=zHym@~&eoO!ˣ~@| & >LL:uG@_s[IrWdiҾ]{co4;K{ݱ"-_ˋd9vh$56_j mG|e7Yd5|J|~.nq! -`  ~7M{͠ʵ\'Ԗ_o6dy^HGHhʌ<ɏkMf|h]f9+䘏[\H@2b;@@ A .Sծ=:;U/yfW6~:ᅫ:x{>%?#ŧK.u$ Hk:q;VAR^@@q#C|zNUɑ2shڨ,_̦@jUK.o^V\9p>g'E1jܰ,_̛|89y;O|1 ! *`&zTuZ݊5k֔'N%I6lll7n;R8t ?w`=\/FzWDb+e~%'@@ @H 4пpK~#\ήϧ>ȗ$g#@@r%sU  )@lBJBa$  PRʼN   N؅#  Pt$ Egϙ@@(v$ .4@@ ):{Ό  @ )v!   Hsf@@ H 9 F@@H@Ξ3#  PH@]i0  E'@Rt@@b'+F`@@(_}կEsjΊ  M.X-@@")ssj@@'v풽{ѣGjժRNiРԮ];]V/x)YԫWOv-O,Z/XMf:w%!ڼys޺(3y&SL+Wʄ nNEhrŊ}_aɲpĥh@+w>l"Wk'+UJ߯J*]O,dޔ*UJڴiWrԩ]~_eF]|̛7Ou&jՊ̻׌3drĉL7m$z)}L;6ӥ^%&Xp|"Y}!xѸs9 s$I)%_%99YV9[Ԍ˼O{$I8(!&6N*Z!r`Ypn8$%Dj꟒(G~LժIJa'@NӋ/M>8 [n;wJÆ yRfMoMW֦{']t| 9KA:ew^]F/, MBݢɴiӼswqGI& .6k5ݽؿ0~dw'tjmv.#T /d*+܇{7ܦ|Yc$t)MߢǙvGϐgʗS.Y3MF-owVE0QF!}X*瀽y(3R 7OXRKlĿ2Dꒅ zEZ^}Uouhˢwʕ+IѮ3*Vv}hQ-2s],QIHl3sc4Qf~{W}KsMO>tGte |h4y-\pa*n:.Ir!kL+y+0If X0[޽Y.Oa排Ο^)T(~=Љd)[Aת)q\ɦًgz`a$>r, ,?lt@jͺ4k1I;Ur73K=Rv&x6~t9m(|[r&\&Fـ\ d9iN^XXY(iٲąr Ƥ]Ace޾7'xXJ;~'n%1!%Ӷ%JҎfbzKҮ2XّeGe<ԥdI+֬Yzy4jO-o]+ɠ4u_'|o/5k[hA;Yx۔qwGw^ؘr`L4J c#sʽϕEƦn7%MSuL_5ɇtVvRdbcZrK0)-!C}#fyKkݏu|\˗¹s_gJ5yլFZs  hrq1ovun^,W5_xRreV~,3.4h(Sm/:8\k7,ݦwrZ>st:iO~ޯ#E/NFd f-Tٚ|C?mlꪫ?GnW1w uŋMY^d5bٶ-:PYxY|[6/lz''r"_k+c&&Վ͓۰dҶ֧uJ٧Ce 9y_l-KZO엕[OtS?ux:G'S.hazx= ^VL:*7u!e6ai:#Lg*K_&;6i&u).3rջ5ݵ2G.%'Gߦ{/{NӷI dXxDbLMbd2H${G &?MY*ZWSG$~#|L:I?T\i>i=ލ)צ&_`SdgY YuHN:OO"Z1·'IdΣ=dc$#{ob>Q 9&㇎—*V=3T7|Vy`]0jcڽŬ,{ϜOa-~7ENdD}k5N~<)ϷsenU^7uimp`= @]sgN-DǀЮf_w}'_twDѩxul鎥S&$EUf_#F]qvh|hBɇndٸq?I6|w1cm}.lNYzbiC|d7GwGpwB4Wct{w} } 6Ȳed( 1e8q7_\O@zFJV<>el|Z(G:50ױh"ꔕLڛ3[ͼ ,S_x't0RH(S!;2aI@Z⽉tYm<лw#L oUPsD!K6~d#só1z2iېs$_|d#eI>tjy\>}48tK0^ym l[fpY0)IPO/?FV?$ni3Nm'GK&fE-bj"$km"111Ҭ9ќLdڥ_g|? (81^6A/=G/i'(/[ggײҺujyZDjdRSWKT*j=Gtd& x ɢ>/O>I ^]n?g$ Oǎeȑ^ ׺XX/!^cƹhWA]>74I.)E_+lo]#ӷfc?O)RMʪUFR|/uNMU.` Mp]t>%7粴Y7彟ͥl^j @㼌"NjzhYzUV6[/wE(P6y+Uidnnx-z6j86Pƌ}j;Q.дq9E٦ I݋̻Id7MF_%NCFL h fIҿ fBji1uIEvs_#&9[NO ~."xm_͖Sh#u1[r3F8=g<83Ⴙf}zU1L(͗ۯz7$}fY~{F2#2ҏ~M]pHQWMYݯ/^'7zw2CZ@vح_?33w>m[k xݯ-'p(3ڻzscI+ix1w6g|v;a:AxuBw2HM@ ٫WdOϫzgïv ^ՋowTh}g3mtlmNKƍ+nk,g^*:ޤ U  /ﺛWIHKi.rN`v7=l:ߍs7Kby~yבԃʘb뷲@$ 10;ˎ{dךi~p] d:_\|Ps=Tyes\.=Z\~U昱#Nu8"ܶ\yxy cXB6Hz$`<3e$[j6ϗM^torlB&+ˇx}g̺֬"m#C1dWB$&0vN_=KdXdL.h2Lw) >$Y/ }eE ޤIa7z-/p+4|_f`f҄$sez64#/hh73M,?VvǪ'Aw=5תfѻ>]#[Z,%8'723t[ѥPBPRw0KqIsDI+-T&W0O7dԕ2vz{3wd|˘rOoC d9dc29[sm\:;_ ctH4&ѷ)ƦO[eƳ##$>-={jvsƳ`#ߏvJ+92w5R굼Yo#2npih ]FwA&1in!EdC^ity=^k&N[3p k/f}vvh vh2[sDH{[0Y07t3&c3x?HO}W:Ω|/2Tgbڧޖ6nik4q[̓nag@  쯏Um+yGӼ-OK~ܜ7c˙?CgVҋ1!Lëc>5ݢ~%Jl%׿uMwɓ'Е:VSꝋX$/h\v$ɇI<]ˇJ6fIDAT.oK Ez$tn5kOJ.-~cs7eU,ٜSیEȮu|c@JۄjI2