From f4fb66d7d919c40f18dfd1aeaa2ae3dc0421e719 Mon Sep 17 00:00:00 2001 From: moodler Date: Mon, 18 Jul 2005 08:06:16 +0000 Subject: [PATCH] Added new structure for iplookups (ie called from logs). ipatlas is now just a plugin, and we can add other plugins to the same job better. --- iplookup/README.txt | 18 + iplookup/hostip/lib.php | 22 + iplookup/index.php | 19 + iplookup/ipatlas/COPYING | 340 +++++++++++++++ iplookup/ipatlas/MOODLECHANGES | 7 + iplookup/ipatlas/README | 60 +++ iplookup/ipatlas/README.MOODLE.txt | 4 + iplookup/ipatlas/countries.txt | 243 +++++++++++ iplookup/ipatlas/earth_620.jpg | Bin 0 -> 42938 bytes iplookup/ipatlas/footer.inc | 4 + iplookup/ipatlas/hr.gif | Bin 0 -> 35 bytes iplookup/ipatlas/ip-atlas.css | 5 + iplookup/ipatlas/ip-atlas_prefs.php | 252 +++++++++++ iplookup/ipatlas/languages/messages.blank.inc | 182 ++++++++ iplookup/ipatlas/languages/messages.it.inc | 185 ++++++++ iplookup/ipatlas/lib.php | 13 + iplookup/ipatlas/plot.inc | 398 ++++++++++++++++++ iplookup/ipatlas/plot.php | 145 +++++++ iplookup/ipatlas/plotconf.inc | 61 +++ iplookup/ipatlas/plotimage.php | 91 ++++ iplookup/ipatlas/plotlog.txt | 13 + iplookup/ipatlas/reddot.gif | Bin 0 -> 53 bytes iplookup/ipatlas/translate.inc | 14 + iplookup/ipatlas/yellowdot.gif | Bin 0 -> 53 bytes 24 files changed, 2076 insertions(+) create mode 100644 iplookup/README.txt create mode 100644 iplookup/hostip/lib.php create mode 100644 iplookup/index.php create mode 100644 iplookup/ipatlas/COPYING create mode 100644 iplookup/ipatlas/MOODLECHANGES create mode 100644 iplookup/ipatlas/README create mode 100644 iplookup/ipatlas/README.MOODLE.txt create mode 100644 iplookup/ipatlas/countries.txt create mode 100644 iplookup/ipatlas/earth_620.jpg create mode 100644 iplookup/ipatlas/footer.inc create mode 100644 iplookup/ipatlas/hr.gif create mode 100644 iplookup/ipatlas/ip-atlas.css create mode 100644 iplookup/ipatlas/ip-atlas_prefs.php create mode 100644 iplookup/ipatlas/languages/messages.blank.inc create mode 100644 iplookup/ipatlas/languages/messages.it.inc create mode 100644 iplookup/ipatlas/lib.php create mode 100644 iplookup/ipatlas/plot.inc create mode 100644 iplookup/ipatlas/plot.php create mode 100644 iplookup/ipatlas/plotconf.inc create mode 100644 iplookup/ipatlas/plotimage.php create mode 100644 iplookup/ipatlas/plotlog.txt create mode 100644 iplookup/ipatlas/reddot.gif create mode 100644 iplookup/ipatlas/translate.inc create mode 100644 iplookup/ipatlas/yellowdot.gif diff --git a/iplookup/README.txt b/iplookup/README.txt new file mode 100644 index 00000000000..2a80b38db57 --- /dev/null +++ b/iplookup/README.txt @@ -0,0 +1,18 @@ +iplookup +-------- + +These plugins will show you something about an IP address. + +Moodle scripts call the index.php in this directory like this: + + /iplookup/index.php?ip=222.222.222.222&user=1 + +Both parameters are optional, they default to the current user. + +index.php loads the lib.php from a specified subdirectory +to actually display some sort of map or description. + +The current plugin is selected using $CFG->iplookup. + +Cheers, +Martin diff --git a/iplookup/hostip/lib.php b/iplookup/hostip/lib.php new file mode 100644 index 00000000000..39e4ec7a254 --- /dev/null +++ b/iplookup/hostip/lib.php @@ -0,0 +1,22 @@ +city, $user->country", 'center', '4'); + } + } + + echo 'Search results: '; + + echo ''; + + close_window_button(); + print_footer('none'); +} + +?> diff --git a/iplookup/index.php b/iplookup/index.php new file mode 100644 index 00000000000..46ddc4833da --- /dev/null +++ b/iplookup/index.php @@ -0,0 +1,19 @@ +id); + + if (empty($CFG->iplookup)) { + set_config('iplookup', 'ipatlas'); + } + + require("$CFG->dirroot/iplookup/$CFG->iplookup/lib.php"); + + iplookup_display($ip, $user); + +?> diff --git a/iplookup/ipatlas/COPYING b/iplookup/ipatlas/COPYING new file mode 100644 index 00000000000..d60c31a97a5 --- /dev/null +++ b/iplookup/ipatlas/COPYING @@ -0,0 +1,340 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 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 Library 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 + + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 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 Library General +Public License instead of this License. diff --git a/iplookup/ipatlas/MOODLECHANGES b/iplookup/ipatlas/MOODLECHANGES new file mode 100644 index 00000000000..1bba99f209f --- /dev/null +++ b/iplookup/ipatlas/MOODLECHANGES @@ -0,0 +1,7 @@ +To make this program fit into Moodle, I: + + - deleted the black and white earth image + - modified plotconf.inc slightly to use Moodle configs + - modified plot.php slightly to use Moodle's background colour + +Martin Dougiamas, 26/8/2002 diff --git a/iplookup/ipatlas/README b/iplookup/ipatlas/README new file mode 100644 index 00000000000..1487d259441 --- /dev/null +++ b/iplookup/ipatlas/README @@ -0,0 +1,60 @@ +IP-Atlas version 1.0 +-=----=- + +Description +----------- +This script uses NetGeo to plot a host on the globe. + +Requirements +------------ +PHP 4 and GD (Optional). + +The GD library is available at http://www.boutell.com/gd/ and PHP is at +http://www.php.net/ + +Installation +------------ +Put these files somewhere on your webserver, and point your browser to plot.php + +Note: You can symlink "ln -s plot.php index.php" if you need to. If you +have any problems running it, send an email to ivan@xpenguin.com + +Configuration +------------- +All options can be edited in plotconf.inc. + +If you want to integrate IP-Atlas into your website, open up plot.php and +ip-atlas_prefs.php and edit the parts where it starts writing the html +(find for "") and where it ends (). You should replace theses +with your site template headers/footers. + +You can create a new language file for IP-Atlas if you follow the directions +inside any language file in the languages/ directory. + +If you create a new language file, please email it to ivan@xpenguin.com so +it can be included in the next version. + +Bugs +---- +1. The famous windows bug (also happens in other cirumstances) + +If nothing appears when running the script on windows, open up plotconf.inc +and change the $trygd variable to "0". + +Contributions +------------- +Thanks to Sten Kalenda (sten@ipjam.com) for adding security features and +cleaning up the code. + +Thanks to Armin Kunaschik (Armin.Kunaschik@varetis.de) for his proxy patch +that enables this program to run behind a firewall. + +Thanks to Daniel Quinlan (daniel@chaosengine.net) for a patch that fixes +many problems on windows. + +Also thanks to many users for reporting bugs. + +Copyright +--------- +IP-Atlas is Copyright (c) 2002 Ivan Kozik, and can be redistributed under +the GPL. diff --git a/iplookup/ipatlas/README.MOODLE.txt b/iplookup/ipatlas/README.MOODLE.txt new file mode 100644 index 00000000000..31e5835bcea --- /dev/null +++ b/iplookup/ipatlas/README.MOODLE.txt @@ -0,0 +1,4 @@ +The database for this is REALLY old now and this service is +next to useless. + +Included here for backward compatibility. diff --git a/iplookup/ipatlas/countries.txt b/iplookup/ipatlas/countries.txt new file mode 100644 index 00000000000..d827611489f --- /dev/null +++ b/iplookup/ipatlas/countries.txt @@ -0,0 +1,243 @@ +AD Andorra +AE United Arab Emirates +AF Afghanistan +AG Antigua and Barbuda +AI Anguilla +AL Albania +AM Armenia +AN Netherlands Antilles +AO Angola +AQ Antarctica +AR Argentina +AS American Samoa +AT Austria +AU Australia +AW Aruba +AZ Azerbaijan +BA Bosnia and Herzegovina +BB Barbados +BD Bangladesh +BE Belgium +BF Burkina Faso +BG Bulgaria +BH Bahrain +BI Burundi +BJ Benin +BM Bermuda +BN Brunei Darussalam +BO Bolivia +BR Brazil +BS Bahamas +BT Bhutan +BV Bouvet Island +BW Botswana +BY Belarus +BZ Belize +CA Canada +CC Cocos (Keeling) Islands +CF Central African Republic +CG Congo +CH Switzerland +CI Cote D'Ivoire (Ivory Coast) +CK Cook Islands +CL Chile +CM Cameroon +CN China +CO Colombia +CR Costa Rica +CS Czechoslovakia (former) +CU Cuba +CV Cape Verde +CX Christmas Island +CY Cyprus +CZ Czech Republic +DE Germany +DJ Djibouti +DK Denmark +DM Dominica +DO Dominican Republic +DZ Algeria +EC Ecuador +EE Estonia +EG Egypt +EH Western Sahara +ER Eritrea +ES Spain +ET Ethiopia +FI Finland +FJ Fiji +FK Falkland Islands (Malvinas) +FM Micronesia +FO Faroe Islands +FR France +FX France, Metropolitan +GA Gabon +GB Great Britain (UK) +GD Grenada +GE Georgia +GF French Guiana +GH Ghana +GI Gibraltar +GL Greenland +GM Gambia +GN Guinea +GP Guadeloupe +GQ Equatorial Guinea +GR Greece +GS S. Georgia and S. Sandwich Isls. +GT Guatemala +GU Guam +GW Guinea-Bissau +GY Guyana +HK Hong Kong +HM Heard and McDonald Islands +HN Honduras +HR Croatia (Hrvatska) +HT Haiti +HU Hungary +ID Indonesia +IE Ireland +IL Israel +IN India +IO British Indian Ocean Territory +IQ Iraq +IR Iran +IS Iceland +IT Italy +JM Jamaica +JO Jordan +JP Japan +KE Kenya +KG Kyrgyzstan +KH Cambodia +KI Kiribati +KM Comoros +KN Saint Kitts and Nevis +KP Korea (North) +KR Korea (South) +KW Kuwait +KY Cayman Islands +KZ Kazakhstan +LA Laos +LB Lebanon +LC Saint Lucia +LI Liechtenstein +LK Sri Lanka +LR Liberia +LS Lesotho +LT Lithuania +LU Luxembourg +LV Latvia +LY Libya +MA Morocco +MC Monaco +MD Moldova +MG Madagascar +MH Marshall Islands +MK Macedonia +ML Mali +MM Myanmar +MN Mongolia +MO Macau +MP Northern Mariana Islands +MQ Martinique +MR Mauritania +MS Montserrat +MT Malta +MU Mauritius +MV Maldives +MW Malawi +MX Mexico +MY Malaysia +MZ Mozambique +NA Namibia +NC New Caledonia +NE Niger +NF Norfolk Island +NG Nigeria +NI Nicaragua +NL Netherlands +NO Norway +NP Nepal +NR Nauru +NT Neutral Zone +NU Niue +NZ New Zealand (Aotearoa) +OM Oman +PA Panama +PE Peru +PF French Polynesia +PG Papua New Guinea +PH Philippines +PK Pakistan +PL Poland +PM St. Pierre and Miquelon +PN Pitcairn +PR Puerto Rico +PT Portugal +PW Palau +PY Paraguay +QA Qatar +RE Reunion +RO Romania +RU Russian Federation +RW Rwanda +SA Saudi Arabia +Sb Solomon Islands +SC Seychelles +SD Sudan +SE Sweden +SG Singapore +SH St. Helena +SI Slovenia +SJ Svalbard and Jan Mayen Islands +SK Slovak Republic +SL Sierra Leone +SM San Marino +SN Senegal +SO Somalia +SR Suriname +ST Sao Tome and Principe +SU USSR (former) +SV El Salvador +SY Syria +SZ Swaziland +TC Turks and Caicos Islands +TD Chad +TF French Southern Territories +TG Togo +TH Thailand +TJ Tajikistan +TK Tokelau +TM Turkmenistan +TN Tunisia +TO Tonga +TP East Timor +TR Turkey +TT Trinidad and Tobago +TV Tuvalu +TW Taiwan +TZ Tanzania +UA Ukraine +UG Uganda +UK United Kingdom +UM US Minor Outlying Islands +US United States +UY Uruguay +UZ Uzbekistan +VA Vatican City State (Holy See) +VC Saint Vincent and the Grenadines +VE Venezuela +VG Virgin Islands (British) +VI Virgin Islands (U.S.) +VN Viet Nam +VU Vanuatu +WF Wallis and Futuna Islands +WS Samoa +YE Yemen +YT Mayotte +YU Yugoslavia +ZA South Africa +ZM Zambia +ZR Zaire +ZW Zimbabwe diff --git a/iplookup/ipatlas/earth_620.jpg b/iplookup/ipatlas/earth_620.jpg new file mode 100644 index 0000000000000000000000000000000000000000..fcb2743ccccf0bdb668929e044e382d165538436 GIT binary patch literal 42938 zcmb4qRa6|$6Yipm6Wrb1-N_FR?oN;p+#P}jU1V`x+}$<7-8HzoyUXSObYJevtvP2N zx~jWs&Y7OBs_&bR#g9$E7kOzpX#f-y6hQX#0(`s!@V+`*e0Q}lC-<;&{YkFz(}G+^ zPEqA!1@ILB2LlTW3j_CggM)*E2cjSVKLs5b84(2o9TO7+9RmXkmlzKVn-B*B1D^t) zkc5Pcj0_8plA4l~nwXS~^nZ&$eNF|!1JMu=&`7Z{uu1>F<)aILfdIt|Z3_cM34q3c zg290L=mU@d007|s9^?NC6f_L%XOswtpK8S~0B9%}80i1S4-XB5hXsCW0k9Zwm=qim z@K~zfDV+krKy1!j$=YrNDz)jYOB_>NYOb&9&R2Lr@p(Nn_%z)ANt>Cwh9uN|E=L3f zfQI>hdizvzVE~|^pga?+3R@`eE|A_etK1SO0F#lb}vk4)dKYgKv0aLz!AsZjNm9XWX^}_a{AritAk_q zmS?Z#LXt=wt5igj#RcIO!UtgVu7r0ANX(Z3O$`nJA}Kk&OcVL3FmX*Hfn2-aTFdo) z%H8?9mw_rR{n+JLUk+ouHi=Q@_}Cd@lAPQNI|X}*9XZ9ErD$ByS(-&|XZXHB!;3uP z6yU*@<@b1zHmt~)_i>kutd|YOHnN<$swos3==bmQ^m5*I5jbSYp!$;<67D(ud&!S& zDPKvj-?c-(yeC1GZPoyLFo20j5I+EnB7JeH$u?)=xF3KD!K=VHM=|SInzbp%4?w0a zFfWsAm+5E8DLhh(FzAbaYKb;PvT1ncOY89nyk9H++mTN=eU8lzIe`rI&FI0C8jUJB zT7515#BA(!`49_pfvIBI*#`jAB=Afjv*tVdw)O zZ$e!mA0jaLi%Bm6Hc*@#;APAPe87J0wIy=|!HdrGWWmqkUQVFDC0u%MZb#!vD)%fs zY2}@0Po1sJ9H`g*PM}Gan|C)cKcEAlS+m@CZjJJXG~-<|Cf$4~KWELcWCYS3DLjWi zp;nYBcrE##W*-*?*0xho0tZL3XI`zg?4;Fkit-6tn2{9PgfadJ)kbEyl&^%V`KVhs zR)X7atn&ezJAealr16|gmz@Pg&>p|1f$!WDBFB)1vtMBG{*}(_V$d?O+-0%*N(wCd z`xoJkyJK%8`;&e(X^7g<^r&A=YlLN=YT#0VIV@=wUg`79dl|hC{!-{J=t<3Kz|o49 zDFo2q40VnwnKCGQP9FTVBi=+s9%`A28I98&f`*0&AQg1a6jnqC+PLv1dE`SG`i733 zYi?BL{#RMpQ8YL`evXzUA1<6O(?xC=SbZV4aKWNSo4mfEC%r1J{OIFOc4Jm0l%5l3 zJyVZBdWi`mU2Q+2Pkl8DQ|t_+N^cS{{b!mlsT+Icbd#^zS4>>9Le59`8kcTyjfA10IPBQ-GhiGdxPxoWeV?2)Xt4I~aFLmBJcqT|r@WzRr zoIjSEjgW<4RfI@GyLaR3*Hc97x6-(nYN8t%=k@iX_%UUI?T+IQK=ebctQHX-Sp4{g zp85@5v@w6ypYT?tY&mHTj0+<~?v8vG#~`fsUw&ynYk|9@JUBQKE<%9WCSC6r*CXL( z98XXIO4j`~+l^kTKdvxtZ3J37+Uz0~);)51%!0yN*oYuzb{4&W$hb>{7``uBfTg~A z_T`Ga|Fczu7@;ppSo9B>L3~{255T=@<16q_?7QqSAoEg@ALOU#y!AM{8NpGn1r~L8 z&VElPd$G85ilhHWEpcqS3-h4IJGv=y>Q8^%KEyw{p40-l8_#*wx&)g5!_Ub0->gSO z9}Cxhu|4uG1tjP<+54a8#~XhDb_sbq10I}S^Yd`&if;-q{gKmRp*t?r zqwh8tzt~(#41NI8?mhs|UY?(G@@@aZYsz-ME{q(9~m(um;)&E*>h*?HmrX}WX@beo((y$UR z@UPeVPfy8SJP*Io2tV#Sg$(Dw$Kd#`E`!-gd#KRiSj9AA@>3j_<-p z10oNkcndh{cXe-f9pD8ZG#g%RH^OObY0?P-V?e1nZ@YH&HPAB zfE2~c0ZYr$gcb5in3sRo1#o&O1(W^x+Idy|+cra|I^{7vI;A(fe*C#x}p1Qs$Wa(xra32`_V0OB4GqndYqytAwUU7pYBa z9AITAM}M=-SydDEjijN~Yna1vx$zbg;RS+2U1$1<*fQC|G3K(~5dOh)YhiEPB7&%; za?k@HP)qIU%k!}1zO7BW$>JL`yYfsyVTWCG9`JU%Z2L0nwI0(Jl(v~DUf^R6u|A&d zeGaGOy~$m9r`beL9mia5GYKK0`99tt9&7gQ+8sJY%t;CU2OE2$-PC5DJ7(trzq8^5 z`^KTBln4e5W25;voV?6ozwhL8?Jmc_Jlsv*7Nd4}!s(N{Goo4V>)2vyVoKQy`2;Hu z79U-o3q&KFjT_V>fgWRsx01!0=)F{S!Y9X_^x$VU$?jdu_5vksxW1?zJIcUTaj89M z2ikGj*J47;avhE;$WB4aeZ4F92wI9+!m<(u4r2Q!V#vh>RBg;uIH>q9knr#2+`=qT5dlo>|=%P8@yl8#^1_|iZf1a+D6?04*<3lsbR4oofkaN2YNFsjk2zz(P{%sM+2r!KEHL%$*yw+M9}5IEPD<7n4*aMkJ8?+ zZEEh+Q#Vo#uP{dtdU~f?&B=wFVT=Q?MthtN8#QIT(@|{kb;0T}qV->Aee55bWzt;WW0yhW zB(>vr-pe1E$VQ&|5=gt%d{@bLr^*fwWPv2viD5ig{|;@aSIJlN z8P_vb0%59>6>Gv0*L4z_pQ_RlT_&8~J|+;Ce&?0!J~q6^6{FBm{e_KdJj~)O+l0yn z3hjM_hXVo8MsvsEV!9qFta(XJRfFbB?+<{=6@082GS65P#`ic?kJ{U#%$ZYRxWLV{1Veo333_x*+IcPMZ^h8;`*K!xK>N#CaC&voTe zU27oS2BieCQ-p3%sNIwBPV2A$75{#%&s7Rjb@!j|zm#grY?fE26N;?ZF-LR>&c!iJ zHh&Kr+>?WXAvrUzLRF&qKfCvuAm=bmM=VtYJsgJ!lfdF{|HK+PE?w4oY3ASmSW(f( z^jJm>v|(E_elI*IAT(x&l+9h*FXshR{_lc*qRYxj0JYlkLnR*}K6U}$x|gzGE} zb>8;2zDFz>0!Pp{#i3nz<0Fp(R&cqe(ng=^VRXsUp8HBaTgL7e-W?mVV0-qFs5qAZ zFP=#^RQu%>HFdTS%0NsHzG>>ZhLH-SAaD&V6I1|i4B{qMWM)%YHMNKli_-WH_8A?MrwgWzf6efx|_s-7|ZYa_~xNDR^{2U6#SRGRjAC4(1X9!O&%Pt zzZg8re-g(F!E2pi=@6lAi)m@nKB0*Gsc#j;Ocp{e{F@4xu+e0bef;@0#o+Y~%GX}8 z6!vz>JX97vMH9u&4-_jh1c?%sbdT}i>Zt$J}?$OYq-Er_?g1K za*S?`U)ENR4TNyb3X|0q8t^t38Rkzs+}GPdk)(pEZFwDKj39UTM`kne%-&0yBh1gN z_4<8z+~%4_(ACyI6y?_>-V{#)jig@%UVkpwNmZqk_p>|?Kr=^ODNqJ(h{%$>>|7i= zpgd+s{WH;O_#>4<+)J@S{#1JKcJ;NlahBU`lsIy__5%>P0)GC?gF->p?r#syK1k)) zFZZH}guS*!h5<$vM!%hyY;r5j0QlA-YC`6 zMrc8)4+kY#q9Vv9U;2;PSB%(BG~dQ%pL55B@{OdvHT1C78U$S+^UJW zqbREku{M=}S!)E{db4p9sc=}ocMy@G2+L+b(}K&N2oWa;$7~JHq(!{+WJ=fFAkVDw zZ_DhlxuW}9S!%Qv=+xw&a~K`wFLRdCrXCz(T(Z}4hrfEF$n%1!ISz~WB$Q^mo$hid z$PefuweZ?^U)1sp&g$;~b$9Ae?fDe*v8_%-=`S$1st-H4%8h`Jf|-b5@*eSn_?Ax8q( zs8vI=VwaFyrshi>_clJ4@ZPee6oyDxeLGGm6c&zwvDETC{6OT_nic3}I>vfgAt-cZ zucmuIT*Q-GCqHkT15JW^O7xM&GvigZk8HU>x%8N8zzlM2r2+cB;&D^rJClgnEj}y^ zU}R;uo~B`7#UhJ&e`YCUqci-&L9w0erYJA2ev`uLk{L?<_B_|_$BMuLcb<1%3c(P} z&Mw4mTRkjd5#??S%UKqsx~q8KwPXyj?|5We-2U6Dy;!YNwa>5f!&zCpU_WMm`iXkrd0?YVgZSdnjo%1?BIgf`7I>uq+Mc@zyI&`h{{h1qH_pOhi_q=X9* zlm0iI*s0jPfo%C$mc;4If^TSCmo;WD>i%hInaQmg_MS*x{_=hVsmY)bjUDn4O_v*T zjr>ZFZn{uTgTD%7@Sgdamoa7br)Qg%?=&re20M%37IZMqD!0Sn2I?p_oyJVHU9k%1 z^gvbG{bS%@qoaV`@&%&Ecw2zDdfec}$xMbJsUyBuc&-xg=|wC2*lF^PJ0#iG*KE&k z((sTB^b79_ZduoAISRR$48_j8i`ebt-ObNsM-gdynW$3XTd1jkmN`oCu8R?E%&2Ok z-~A1aDbl&j3i#%>WFt9Yn@bj)Bz%4#W;>VB)w-%^?Oa9dC6eIrn6Oon^*y7njr2hb zA(@AcbWaB>?%6#+{`vluQw-z3v7Fr&8QxDCoi-<+=Ec zKdbbX`sebzPsXo!b4F}Cr1FLkd!E$KCr5+FW#wKyibiVxmKHVb^o+WG$HN@=YH2eSdNX zF0&0nxU?#6agr{g&V$CE3^^@+ARukXG{zQpj`H|f!IwlchJ{%z7$J zr2C8FKQ;H+R3i3Ay|DORx;RXT3C-RO`A zs!#Pp)J=J7vQMm+#6dGwVVcLPlaKE$T{afq<^7Af3gZ2^O?3M?zY4s6gtpj3zMZ>1 zfwV!frPw9kj(?zVk<1j$sS7GYU*c=wZ&`G*7C!LLchdweQPwl>$bx()BUXAHS z`h|TQPqRe*UB^}!MvfpZ&;i6*8QxFtsfS4(<>yPEh4kvn^P9EJ$?r2=%1L3&29q0u2&QCDmpT_G@@JL-C}JV?09g-u}{ zsnsv9b>ur`)n7R=pi3IQ{{SRZBVG-@k>D9*@hFmVRCxYwpDj>$zIz@Jylq4y?=qk&OUzhMWK5j`D+>GvA}ssSI3BdaUp?ISO4Zzmpf+0 zR4o)jB>4(-VenzHdSM_!E~*dCtQp4b*gFL6R-9FaWC}m%d~1VOO@2Q;l#J)Ebf=M? z6^1z)M^}J}yV(nwChLru1# z76%ag82HsGUlaQ+dGptIeQ(Q7Iv$0gs>7*b-g1vO60*w&J$>Cx8-IMmBdsE}3wt|r zM(1BFW$jb7#Mc5Z3m<^~>YB(dya1i6J8}yYm;i|g)>nWE;x*L0-v1bAS8Z_gY#DjG!muB&R&>37 zR{4!yM*6YFkt?%CO?F41N_s)HFPb*jky3VoU|Rk+!47ro!JBox%9V7mdEN5z^6KhH z&hJ$DcKl3lG#RqiawnhGPDxz3?V#47mB-JnRJ~_}es2m^Q~LC&M@yEP1pTT$+Aiy= z9n7&8tcD*^7b*J{UKs8C?H}hEx0ubZ*kq~j7KdbPEz-OP{0EeE?$1?V+N|$1iSb6( zFGK0n&72J(B>nfDJ$S@une;;wauxHh#$~@Oz6U+7E)V{}ARdFIh+&sLYY*i_m_S!b zt>kx|arPiPwHz)V$b;n=WKC|u!8gjrcRR7qJeS5wzZujrAlh*I?e(5dX9cCYCh z(6OwWQZV(An`(5^l0satCph_?;zl7)wjh)AgN1dTdF~9MO3q$+-htcV{S7pl79^L( zj8gRpnXg*QN}ZM!>>%TJMFOx|k0b^`*w@U>Y)PrF%$(f@+OReIgYgT_r zVf>L1PHp_~r<-c~^CUuDGZX14yx(LPcRcy<0+Y7!40AsQ;pm&3`l!e+oyP4OqQ>RK zXiARKovlU*P^hKdyMcE>@Z$Kpn9f4lVqEle33`*zk8%1fGex|T3}hU`PDstki(-8e z{B(`3Zb(YF?J`VqG{lJ;DE9|p_WmM;`m0ZYec|}*=Li#C{W{n@hMV+f8$HXm$y2>3 zc6J09{XKL&{4iBOB`Z>qE82uDLyC(=g~n#1D9D{+e)UY*8+544&8@gNBEtVA?;dl(DLh#V?Ycygt$~1E}tn!syi0*1hj`PdkS;k&pFP_!~BO zeDB1wRj#G1RES)EmQu!G0_4FBWN}qKShZq!R5KM7tlNz(y42Am-q@~MJE9Wk>?OJh%IQmGL)rbc*CDv4GRM#|=Z^HFW ztHdXK?r{9K%GBzD+A_FJT#s@7F`E*z*Q>-_dR0 z0Q31dH^(WU^=IC!Uka-rlVUULUL)>P6T z;{`kSWi6Gj!@8tP;r1RLC7Z+iH@05bbp04HsYv?*bFYJUB@evXxF>B=L@v=I&W!th z@b)xKS!QZnHBAURD^G;p$TW@1*Ru9xwN9BZH~f{HcQ{d>HN7_Nw^RzvrtIB<oFRm>sKB`pKG;hw@}(SeD(gq#eeb5;E(^Yp-l9 zbM^~J62z#Q_irM`ti<(@imr7y7_#(JdyB$NW^2+I%<SJBbsWtFu34=}%22?-eqa z9v<-8oK0!wQizkYbpr$dm-FAXxCp)nLZrQsDo>n8gnpdMZ&*-YKwT0&16K<{J^wuKLA4J>MWh*$d!}> z6{!q_oxf-@Wht4l&FB`Q)z~?)F*39D^4;!ras1-B z??T;}m@Ska!2^un+Wayo1B_wd>bwf9YS~e!)UuxMimS}8=b$?gh@C(h8f6BUJHx7_ zOU(SZPv2L~Nc^m6&*Ctc;RY?#wVX$3ZyEy7#Wzk=iZjEOM>g*sm2vVo4ROvK64`IY zSus_p?!Qj?mHwn5O6EMqze!jqU`yV>z@J2tKj6N}D<#H?afHJh>Yym$gw~Uzbz!P~ z$d8;K4dIFp*@3E6PfRhXEr%A21fwv9@cnf}_b&GzQV3k)j>2b-uo%r&hgfF}BaKl? z{)v#M?9D8z^hX$s6;D8 z#o1~`uD$$ z|CY~8ax<)p6V#Te|6lM_4tDU?ixo*0D?P7+}nn2vqfL zL|-Y@{>^`M%0E^Q(R}R-Kb-({4O^K0x*M%l-V5CaOWv=xzRa6H7c5-t^|36oi(*ze zMRwx)KD8ZO4@)}@v}jn8x2xrkQS}BL|)hRm;0% z{zB$v#K(n=HT%RtT)&ol|4nS!a!@^y+gBghW&-^Ih!~Q1nbEr+;iV`-^TXpWtJ@g_ zYqXLImKImjd`s*UIRttP+8w1l%bVWe+#P=l7R?NN!%kk?> zV#1+~t80sOQ{u}Ko={9>@h{rLW?UP~@<%r11V)T1v!uTA?olSpUzBpfnLZvRbuzhz z4bm&x0dkaK+OFpR@tdl)Y+i~;D;M)jsBGSrCa0icVOI8{u-})}d;emnE>vd@ZKo!i zAK~$6!c!HJq339abESrs2gkV_oeN&6aj)^Iw708bM{$)rYX3r$QC*pRE#nOUtovz=LyuKIf8~!&vj^Kv8t{4WK+Wj@p$^KBEHGmvdv5TmT7T_`)=l6;I zIq!Q?Mo`2mu#0(*mp@>r95EzK(ixd)b}$IQ$0 zVB6Ov)9fGd0u0qcJ59s%h%RlTWC(F6vDqxJiQ}v4jH{hIN$hu+S^(ZsZK7p8(#g*^ zRg=h&{K3WUl9`SfXHcsp@nE9>vH%l8#;A-NOKZ5ejHJ_1!b4?M`KCU*^MLKnS(RXi?QcVIJcIl@F?--Z7<>ki1 zsLKl9e*_Nb)~Bol2Cn)%YZ>0J{wg+M#(Ns2EGnN__ zc7oeDgZ{1v<0&)VkKk}FCc2D=~!kfAwsOI#5@0|fTl_(hD2E}pXsUp?6^Zy%YB zzdnNx+||$v$unJ6UG!rKJb^k>6nHMu_O|k&uVV_o0huVlLuU^a=9g#0n4>2~QKUK+ zF^BCklq$)5P4a1_m(|;r(ZT}7qFDteF5T9TtHA_2)3r&@7~0w4WKnI^pbjD2SU;HG zv7@~iL48RRa+~Ja>K7Zu9Ge_N`3Bk6Myno%xIXpEJHF`l;{t>S)Rzo}Ca410TW4BD zmOph8*^bWE<7X_>znZv+e_>Y^6O3z$>HGa8jIOR+Kvi}VYyF>nJ0BluPo{RVZ-G33 zL{@Ae2!;Q8^0!2KI(bVLwh&ht8-WPkEZyqtU*c)jMn!ocA?Hxb2`Cf5ppoKFVVQzh zRBI01%7X*k|CmQggM_@Zvn(b{RebO`&nRDYnptMHeAAo*;ip=-&nlwf#?-6$sKN;D z1)2oi$AvA-t#rO9v#;**H`KwdEdHU0&nK)L zdOND`qtyt(X|)jWKPLi;Kn)#$R}Qol)Wgu=h??&$9B22&Gh8$*4;r$*M`$fmA&Vl2 z?^dgE1>d~=krI1SweUb)9d#oV_FTq>_0OFU@~Aw6#OcvxN{F^;moMjzJgk zJkfamlL}Vdi<`i3hqVXnR61K!Bs?os+>R3e`j(vQ8j=!3f$zwdX%YT#C#K)goZ>aF7h`imTTwSCEGXDjMN}}B#Rv&@|ic! z6zFT<&(-WWSSL8wO1B3mI!N)qCm~EA*Kw?3U+Py%@;=jHK+g-0g;M?HNQZ#Gvee}| z%*ct};qpjItdGf*ZdcfS09dE;7~@XG$CZ7gGD<=goFG)E(tG3Nx?grJVL&gjO4j@5 z_$-zfLZwNGUo>t@F5CbH4L)Gpn zct|PadElUpUF(?-fNbq-AD@K9&#^Sd3C*CLde=|PZ8@JgX^HzxHyc75Lz67@y}8`> z!0O?Xz!)fytO5X%h7m86>(?aDQ>1Tft^WOvP7aq;+Y`qD4*rKDTT4{anGge1y{t>= zp7eEEC`PtEjBVsS%x~djM}q!+e6X-*8 zC*P@hR<>ik=uA*Su`a4^zELZ|*VL=RDi%l}w1P`U$WFg%KkK}g1;8W;hTwVDdp<0@ z5jnYDK}*A+_P;HJvnyir7pLor!agi<^fato6pc_d0TL;9?q6A<)(1>4v_B?GM$stK zrPCd-B~LzCJ!|1dE$9bw#+ZF0hFb_b#oi-`a>oqfp_LziSFMaP|KXJ9iod$w-TeIg z8AQ!P+z`?LTJfV_ef&|IN-Njolh28U8loa-$w}o1dV;&@Hb_uqE;}4aC@tas8*^%H z_j#GOjOdUw4Ln`g9cOq%<`&Oq<%sFujEJ*XEO!SajF=Z82YdW6RTgrz6 zP^Ad@JEFfQMs(is zZR40WQNB%T9rq$```gy)H@hl(aG+S(7hvY&cSHl-M9eS34y3w>)axcf9i;%=Grc!f zaey=_n~kLVPq&=fpw1~_--Zf?-CTFzj{-gbiEt&YJAu+@*4R-;6#vU1Urj->QsX!uWuu2#(3ooi^4GELG&nVe<47+aHd z&_lHxO~gvbO1@J*4bz+tb082VE9ZP=MYOSIMpz0Z-A8YArQbQ%*$jNoezz#o$rB+7 z=zdmT7{p>l6FAfO(M?>t%VC+!;Am~1z996w?Q=)*)R2r22Q!iiCY?-@scKExxCl!x zUm@ezVs?>+-5-0sm396X12=a@C^PimO_r($X4fX#A5Y*4j$4(%aM=>in4mjFNXbUC zO~Nc4NsRcjcGAc@#%fSvZp-wMQVOB14{!Z%q%}FJ=G#&X`a?-O5vWNcu36FddEH!H z1=1v%)gr@+&+OYJt2cH&(=4Xb*gD0G2(L?%>yH^wQ?p zPWreNZZmH>b4t@fU80*-Bwb?d_Xz|jPdZ_=r%Jj|R#x-be=6C^=?hB%u4${-PLPA< zuP1RbqRo4u--I&BNc>;XecbG&6Z%kDvuqsT8fOS@u3*K}cAcFzNZ!h%Vsb5blekkZ zrKy|3d^$p)fd+R6jU2A7`n&oIEiqcmSk7Xp1(&jq-dC^vmUoYpJDJ0XgDF=8KYZbg zvP6w1YD!n+sua=Hc7}nfS4vg2LFv914ul_o>ld=v+v57Lt_ zNA%w#6?}y~E0Sox0r+Glca&;mDXyA?T~O;DoX+w@FiP4n6F?rsp|El&@uW8IB!y+G zLX?s-IT9y9nynWH-ZY;wUlkypWm=WC#aPa4YVnLvktT}qQIiKaN-Gy)0Ep54JaPkn zWcTXLpT|1iEE-6spb~(ZrurC8Ky#^VRct((t)215_XZ{a*chKp`yrCaue$hKoHaVV zTyC3=jCQ$mc82Dvym&><9M>XcrCT8xNlexiSn+bk!2g=s7VcnU=(!ssd4vegsR8jo z^(3;I($X#byyp08x_FyJf~?fvnr3sXGNmQ!Pz%MaP01sBq&rsVM7T8Fw{-kn{Xbc0 zgNCSv2p-^*X74yXcD2Ft3bfhGwPtd^gx{6^5?c*$oqqsovm4R(Ips(?EHZChCl}d-4Sp#^lMlC-MfQD9^@}gh~_jJ-&2y+|Ly7@)4QK8V}=!jYuP-5Z~@V>kAfKzc|&vAVmsQi5H~>zt+vEUPeM9gz<4Zb%hh~9&~31a3AOyB#K?(kV5XHi;aPhYCUW7O z(trAh%q@DCR#Gm(3_4Ww&P zs3z}P$9>Sc|54!LE?U)fls5?1jj?|Rt|>-|>r7d(_#toA+c0IXmslNS{&E~y$*YCZ zN``Uj^P}2!+v{BX6W|Sj8JuWK6h*I1`_{~RHRy~dwb>!^t6Db4&8Ld%bpVdQ_G zKS@9mE8Cd4LL+TTdwDgH;91c}bDlLf5b-_?Rsz)j#IkYBA*#X{|>GE8`m7CC)pgKg&xX`jzOxyukzk_36}^!w#~34$oN zZW(I#$!|NY74<8mYTTPM()OogdY+WD$pk+T85=TS?5q&*`5#>-ZOxiRYSr(Ip;ng+ zSjJ50Da7$xP}=>J1S+|mmwW7H%;V`mOjI5Jo!ySQ^6zBcm)mLUL@LtkcLX7qf9=aA zodSM4f687icge88?oUiqfo7%=y}z-t-=qznNvqQ%gSUuoAZ zx`SzBToRlFG!w54vPM1tNVf)iZ5l&%jv46$Suwn4B4VR&OqI%yW(6$Zme8qO0|3S% zp9rV2>ZEmE+a+#oaZa)bv&B1ZoD$KN2%2CO@MS;efWV6p5=QN>{*LmcE^?nCFh+I_ zTdw6{((Fi$Tam&XusSp{=Be15K6|u|G9O}`7(XMEwuhSO6qDsAH20?5{XnQka1Oue zRC5lf=HK-=(@@BeOY1Bcre4EXnCKCq`K(Yd><4rXW~WG#pa*)c3N-b-urYdTx=5cY zNi%*1nW|tO=a@jk-mJA+sTYHZ>PeH z*A8cWsfan)R6jfPqmA!^%*zidHtzoAP68rt4Tv-P5b~{bfzEI`@i7lD<{s#RDbrDUlW9~%aptAH2-m%L|N)scIe+#Y|Jus1uJ~v z2;x{gI2rdc)Iv1P0Ck$p9C9+pZ6>(D7tOi z!0FD#@~CKmnc*sP6(p1-*xe66q54n0^boEm7s+zM-7|?GuHoTH5vSWqH3OJpMHk)+ z=2DE91G0z%!f?42oT(5+dy{^EhXvG4yuX8p(I2LSPgtV%2*nGb14Be&!W?sUUe6 zoMyyi|Ah+oFwFNo`%Gd;l1DqZc+%m4B1QB#QbQTCJt;n`I5$pM@C`kIlyi)u>kJ}s zvfkPWdewEPEYmN{-czGp75l?#+}z*w0Z_8KAX|%IHCmoI{nP3~JL8EC!W7Lq!9NUe zcD7k~RxUIHQ9-PCpR_l-vxQP-+R*kl!Qm1Qw7DZR_7!7)(@GI?CA#x$-46~7--^sn z@<^u}?w(XjEeO;!o+I75PL_kByKaI6ofaZ#T5NHghE4tV^O%AMyV|6ppad`{PZjJm9BES3G6uy?!_k%A+qB3ryCK>b~h@>kLikzO-9*ouTgmcHu{ zgz*}TOHjgDzgsL^&5V|K&S>ap`cmuN+Sa zKWLHS(#a@~uo(MU$881S=sJ2Wk2qfBGDMCg#Io{TV!n zcR(?MJJo-_H|2i^qlv08AFr&Rpwo5WsxLM-3dTEvtXF9?4tT z^LRkfTZ@mEPdMzn`8-t(370L?V&tTuG|U7Bybl`XKiPojJcg=@eYi6`EdvMC^y)`3 zjS>!}VuJ^v;+ zd%a;J9M$pIAMsxH2LW7VkZ7UXDi2xA4OWf|m2i_&%*T!C-)TT-@@V}T*BmIO0wX*4Eu zi)qq<^)dOi-4E4r-Tu{9_RpgXLQPx!egp1wz(soVKJ4NR?`oFqH|hF;}w#jl~zi+Zfmk` z4$2Xyy`+Q~CjWrk2LO=(TT4%Ipwh#t0#yrpE{_KLFLl&+Q_0lp0*p*(5upW}PjdgE zFcw+Z9f=6vAnRkArB0SMvE|QRUOD2d)lIjeS233=t5AAf*6k+yuY!o|eNI8WMM8e9 zg(ZtCi;ui!!*mE05m{{Nt+g2{cC;FJc#f{KJXJ?DvMUVGaQ_d-lYv>;Qkss9#lp3E-Ey%%HEo?>;1SokgjCK*ir zima2pf)uDLF<-x(5e(B9d-S2n-Q5pWTC=J){OB$YJ+bcw2EXzVquO(uL{TvA?K1C> z@Yd|AgCB+DvC8$AmZk7Fg9u_L-95#;8s5-@(Ex|95;=gvC<6xVKyt^E8PZ+q8e_;D(3d*Y{wzL=R$vtsTZepkTbBH@- z7^H*C@60tk2vdEgS8#<3#;mIxW1&OpPeA^cNm>jMO)~WHFE}3i-jT@C(Ta?TDR4&z zak<^jy!MT7>JDqTEUX+s4!29oUxnsR@fgFHx__Bph$eh=l)vhQ;gYL0(q<1)Uj=X~ zH;E<5$0`K(p1YC2d;GK;dOd3&8ISY7;ElCgz1<{sQh$~3+j^59nb@arpt;?E`#%80 zKs&#(klzV7V~{!MKb2Q3u3hvA#VhHRb9kRzv`MG`0EZ-iIQYE$0uSlN?4HJ<-1zfQ zzE-q@PmX3I;#3=oj^}o80Kw~4TCS0Qd!yUi-?gk)$W_wWZbP_pz$cM_2JX4-!K?2G zcv|;I@Xwb#Q5i<&ML1!GIp+f%DwiaeL|bjrd>Ff5#ZUM>q;{7Pq?1nDVvaUObCMUI ziwpH4pkDa8+WTA)-Rdy;Vj`~$ZXMBp$v7NjW1LlA;&zMST@ja3z0-`hSBS|CwXB9X zgKi|sSPs07KWgSWe6zu;EZSs#RF3;2L5Dae8+jbpXHV&vwHSB8*B!qs;A(Z*Fl2b; zU$=B^yi53pb*9@~$EHq#_FM>9#kj=3<0Rl@gTUt<>zLi@`u?S8*0-9~?DoaCG;&PE zN%s}fzZX0?rs>efc?IlEe)H^>+sq8;yK}gK&}3tuZnccE@Xn=u60~;eRnNj+MNP-I z3_-4kr(n}!z@*Yw<^27QUa93-92Y-=gGqp`{4OI&0ysNZWlufFdXcW)-N5D5_Ojz{ z2GX4N$Dyr^dS0EQOuw2Xrc?y50ID`Q2J+g^UfZZgKXe3gQK0zXem1dlCL=WsbV?M{L-`b9d4<|8ikPzLOJ(s8n0 z;v$&I=c@7Z#wyBNc2s6{;SL)F98`UQh-DN|DG-XUr3FAc zRHuw*(wp+|MJgWQuPia(QHaiY;+)zuOI%W+*vO1}(S!rGY0{i=NgkiI6c#tMcUl<7 zPL#58a&beU%_Ki@?FAXBv-KE`I+2W3O4y7`S-sy!Vw8U|9)Z zMmmNaNXB}1=}*{d5gA3h{1HYl$Vb8teD^1w^_9Mo+V;##6~eO_l*$o;JW4Ql$px}= z)3?7%3!On?@V=veV{rhvgdDTTGFUb;0qfVH!Od~9>7_ZwG4kk^rS0W(jOM$jK{fP| zi6RGfR}2SEaq4(K%Co=mm%F+RF38can>TI5dy5W!x$jgLnv9cOOEmB1O6*yj_b07K zlHk5Z0+Kq8_3AMH0ON6tQk=iB=4G#Z(mFlVntk4r9E*C4|n-S1FeInQre^le#0Ujn1rr{Yq; zj+w{%6n5%5;Di7HNTz*&Y0+!Bqk;#5(hvy1Ky$>vvMc~Q_1W6 zscVjUeJUeJQhYz80#B_xz{ugYq-uI9^!|CGfEuaHtP) zB7zD(*PI&p$XC(-^OQbw-mPx2ZTV;2IH0xWvWh1-XQB<)Cxy^Ln26$aA^~80u ze<23tR*1MA@^Zj^xapeLXkG%b({)0&mPsX;+61Ow?+F;)xZ|Nch6f(`u8lp#mXM+- zw4yhF08^ZCf=?X!`q!1$Y96B{#`dotWO^(P%W z@z%6jU5r+^NFz|aP6s)v*dw_A0EIQ(zxQ&uEOy{v{{UQ7GV0T5*B)i|p}C}Tp%4;D z=mt+2Keb{}OQWXLq@N}3ziAD{oYu_@N{zWnl^a1L6~}eY!ygUmcW*2Ot!921E#H8D z#1xDVm2^A(dcyM5S;-~Lb4YnjrB7Vs9D91yb<>vOe=gQLm69|L%z(0yo-)}SkPbl4 z9M!8nOm5=Z6tH5+8pxA8{jYu#c(TOHHLZ{QN(FoaYeKN50Kw+XWAI;EfnG~3PQu|sl~jWMG0w%XI@E zKt1cFTX@e-xruDFt7ehVDVgV76W69Xo(KEshgXXt$mK5IKgqvEEK3@WK9?WBjZgj~ zq%8Ak)?c58hFAs`MZf?7&;UP`BSO}6-Dc^n?xV!Okvu`jWjtrFJ%HU>TQah!OzmbF z>C@|6+s7Uk)ciBzmGMS^qIHnTB(RnER|~nbf-(*X$6SsxMw?HMGjVREW@%uG zlw)zee#_++ekJhZ=&;EmOEkJ>cLpGp0FZXJ1{8zezDGhi$47T@E~~cQXm(tdM8Htn zj|4Yv1~5+*w6pw4(sh3hO=BjHsL6b>v%GNNs;FGEZ_f%b+*Ts`*H7{qEgsf8o0&L{ zXs_eMfw=-m@txlh2asyX=rc!|M9#I?XImthz0$lJp-VePZ=Gg)b>A5QL$Sv@y5p`u z$3JSO)?${%*3(Y4fupy!y;QiBR0fe4<8UB?yb^fsc_h|Y$%c6OlHk!7k0tCm z2ES(=z1v>t3o?kK0c1tsWPD0aFhJyU=~jLi*EFp{;!JLeR#{$Qhoo#?e64b62587=JY-JF#+?qZX1vHY|AF zBv&7#o}lBmewA^o_+LnhOVzp3qqS9pv}q)!MpL(q$G^ps+cihwQwEyYe zBtHrgK+ZR0oOC!G)SR*TW-PO*^34R7x}mbVy0tPA6ML{HYoHwGY3Bg+=jGm$;V%#A zX<*Unma$JO$kMuu7~<>jqA()>lg>WFiq~7;ML&e&vTI8*Zn+I2E>r^Kg)5Fa1NF^g zyf3KC+LXF(pn%#zE5{i{+a}OX(9AGc0mnUuN)wDzNVgk`X-mmv;45U4#ZYP1vDsbP z!mQ!HCebKBcq6FDJ^0V1ZT0^E5Vn}`+T1CS79wYYP&}cG{6Vq6_0Q6?c9AxpdlsP& zn*<|!`H>K-kMJHw2hZwzntQvug_Bm*md-OR#Ii;n;2((qAEk5Ze`?JsMe@l@KeZl5 zJV~i&UMtcr^tO2#C;0r><1F!za;z5_Z%htIC)T(e(L570QYlwLRfBZ|S5Vir8N4}X z47Tutb#y5#1{oeE-|2mSlgs+1qB*9U zUsC@7)IX)m0J?K_f#Y;w#~i63;fEuk=Buu?tK@Q)v$eVh+!`~3ka9l6Qt86(?S0t9sNUJti2#S{_P+w3;GzuJNZA*B^ zB}$M#!obsI8JB_eqKR0D-Z;o@oc!sDhnU$k{{WT;2RWly#yTIJ8$!sUFlpF^*8L!k z<2cPaRY>W@0-&A+B@o;wZwG3zP=AO0XsU3$P{KrZ&AY+ppXXG*bxc#Xz z?kWku&tXk;?@^#6q%lfVEUK(~KLb9Q_4(jacTvd{hACs(AP13jrhNa`uYQaQyc9f(!$idarZr8yd@10tOA*RDR4)JVAx=~s8UZNRy) zxOiV1PSe9F>Im*Vs^S~tJhHRL98p|xG$=??Ki}G_BLE!W9CkGP2OMxg_o3m0lTCI; zStOSaqpJQLT?J!ne(g1)600Yd)B(UG4tsI_RbAq9G_R^6qoI_m1jZGWPB$qW9u-dq zxvZ_8wQ+3e<|vsI5x9IV0mpIIr}@^$P4O0=s94LVgSDMXLML!cY{H(a%;EdA8>RI42z|L!QM^sBqcR>Q(?ZEl-Tp;&_)mnR)@+>F;tRqKg3 zLll0d*K37m8X7jO&!e0u)2;93Tj^(wqsZF=2FqurdI9bM`Bd9kG@Hp4Ev{~DXDkB# zXOupl9tJ+66;3Q~0cUuEZvH7V$@+Bq(Hlai`|F7c4xtV|ab1Z)+)i@(nzaiIy)-oNsvrQ z+{S#bwig-n?@7PXa>dH2nEV{(!L@m{d}3%atC@S9Dx)Yr^-T2PU%8A9wqVbeUGYmw^{am2ae z&bOm4^`92#+}P>Ob7s$MOln3xIGJ}JQJfrSzeW~^;>OBo<(jF(Kkxo{NmUo}s*v?Ffh>*sO9z`E|$W1Yt*} zdRB5>A`i^XEr|0Nuw~xFjP=j&+OKsB%SX2o1}+zncAlO6`cy43tYb!4WL@|NE%4-E zd;5>QM|Bc~khFasPcc^e$(XKC4Wod4JB**@R`&5doDE@Yq%4{E*x;wI`gHkKd#0r> zqa2n zq`Idc5E)=|oqVrGmfi_5I)ryx^!qgiJW5^(Y3iIi^7$XE4()eaeRGDw) zo)}=fNM?=*#^A-n1`0F4R~YY)N}1w~J}qX+(KnC*4w=A@<=6e1=Q=FY==$5~9$;u5 zWf8mNd2gSE#t#Pv2d`7;E3XLu09Ap-eyINdbaC@f`aMdQ`(@wR{Ql>E(5>V%F=-@d zK==!sa5z6M!|7L-_O{xEn_JHpn*@om(Z}isgH*qVI*7c{SYD$Glw+1<$t&1y?~D=j ztLU#HnVhB-RO6G+&mNV=Q`;*#&ZQb;4KKrbCZ7exwVs=AZw(1UH)^7FvV&_-BDsFBVGlg6Mz#I>ydS6PxsCgbqwwK?@<~?6gruNn> zX*c%pMM8nPZeVydyYN5a2CJd@P^6L16akDeN-~O1%c$p}u70hKl(?j5+&Ynw+t#~! zjWjhF+$Os`{tZS=G}PevI)910Yd*Cb&i3#5mH|nO^cl$>-974)Nxi+E>EgGa$t-!^ z#N>LKqJr!!Sl_i|AxI-QJoCk9ya}Y-O>=jDd;qgm9$c*3LrLfca&ywWRi0 z44i?IbH^sR{-ffXZ6`|njz!$)2#FPs!r9JT`+9#W!CvYYm-CtLZX})iZ)}D31F-fL zcc%IzwJ&~NBmLO*-m@J%c4FpV%12GR@n8KRhFv`jimL&U%N%cE&?x!$KeazDfew)^ zh1RJx!!6CCKHOzvk-CGAZgOjsTU<*F=`1W&(SZaUb6sBYdtFCQwNt9cCB%_LQWGF{ zM^HOh-sI}1Unn>ibx179T!>)J)?(g#$ z;~lY9OQcz8Ms0fTc;bsCu4IwH+)3+?Q=T!;HAmrul`m~j9|i zS9iJ%pNFHdvb2uTnn#gSYskPHmnW&~{`jnw*qb4X{3MXL92)gnZ$Z;0!!Y8P@q=>(44MTMft+Z1f%fshCs1M@XcsoTai3$3!NDoV-<@*4#5E3t+cqmjZ3nqR@r zo5`_CT{g;~g+MCYp1qxUAAKs>XanG~8Gm91?uvj;**?gb3G$idWZ_ZY=Zy;c_rWBov6k<@WbNF!h| zBOG9EDti9_zpX}zCNN{;IZzKmSYXf*mLuZa4?~O!1Z`qD=i8{IuI%kO86D`NT#OjV zC)$Vso|PkhGt;Iq#R#QD+zflk=t1d41+doKG7s+*G3S%Or2brg42Z+mB9Iue~`PzTm{L0D96@2q6CeI&>Bn#19}3Y7Cr{w~tD7 zL%9bek;f*VNZL#c0^K@sMGJ8QXvTU{f>gJ+Wd(3}{i&^mMrRM{M-=ClDB33>rBR-g>Zl-d$fYWJ z8gvW{RFWXrh|q(YaT5mufM7GvPg*_aJmZRKA}+^(0eL4hnF!m00Un2%E!i3Lq>?>q zc8bvTjorph&tCm+H&Q}Y$7()@Ac##2$VW@EsS8-eaY9=^D&fFR?FHNZI?YaXjX zr_}zq{^i*7&mTzxv5Aa#(cFAjhZPea$!`ubNlyOVoma7gd{F;==>t0k?c zrViR5B>D&+mD(r*mkq-xATV+fRl!xd87M(lJsBaXPPi8qD+0O-8d zw(;Gp&3h&l)dQreND5Q}a-?q=KGmX*(m5r%jOqsM3&*-h$Vm7Y!m9M$gUBT1PXie^ zb$+|;&8SAw`SNVX>Fuwn(>OBN+$_K%hZ)904E?jkPx53`lg*5Ua=djQ4*vkZ?_Hxr z(Y!wQ&?c>K4Ux8*H_MeiVBL_MgMv?9PJfk`jrP&R0+VZk{V2j@)~$>6BRu&V+Uy8wN~A)wDpHAiSE5Q6RX$n~e~?xln>AyTdS zl&Co#hLm9(@CV9`Avx($alRQX!fn)v6!F*RU5>}bw+*7$*?=Mz@hT4}?9Sdg5A&`` zx62`r42qv+s4}?|ZABv)1lBK5(Ek8Yj+5nbjaofiw9~cI?CSRZFVv;DEN1xefIuJm zeQRi%@<*q{(is`I0#zRb(O@YbEoM`AYItZb`+x&HuFL)H9f*6}OZ zHMGpGJlNmiC2@m-GsxiQ2Y^R<+$$&PoGUQ}-3Ppv_N#0)16sr}-v%n|y&l;WIx zj#(phBzGCSaU6ukZVVxLW*9jgv5rWhPZLEh`7GxWyKt$~pMKz143kk~AaS@h1~NhB ztgLmHhb1O;Vsc+Rnr%MGM)?%0XgT6 zgWs)D_?8&1C;sl-EP^p1lzyy_=~kW}8<icvyIa0 zP%858z$qG@NdW%<697Jk+PfM(Mj2&{abo56-#?R=uG43ZDN80_rF4?7!Nso{D56%5 z?%rp7?u|DSAErqd=h&Kq=Ce0E3X1_H#z+3OIb#d~?ma8ht30bo0b3%Jt%ekmxT9W3 zsiZ-_1*|NpQzL_e^{$Uveii)fK6M>Km$lVRAn1hD70rB^W zv9prW2W4x92uW;&Q`CXj^sXPP`h2w#j!5^@{Cu51OV%tKqb{HQl$T6DH7hA%3z7?U z>rI9^>r=Jsb+^3u7&18Cq;pl(+QT@@99(*%mzFY&+I^EOz-DGA8&@Mfy{f}Pyl8c6 zdys-b6sp@nz+s+7YO>6OA%%_vgBc#RGfFYXbrVUrMkG?j22KIz9`v(8N)n6a(6PE{ zokITr#1UC|qGel$j^!hcIGBJz$P9NL$AAVp=C@uNlJ@2{y1tQtKL9Me6OuR>9l_@V z^!isE@w^E>u_m))=gnn$eASiH8(q0%&rS~*>@nA^A};iR#t?j2Zrl!jRqC-~criu|-6XH@ zjwVdL$1P(~Z8O0~W`Y@WtY2dYMd2LWjDnG(P zcM&* zzSWacFJ@ly;`{tB!KVyfSo?3sMGx)$y3mZ62=lnK)|Z80FFlnpSOesXDql2 z)Q~gs&sym!YRsNSkxLQVoKuT&ZjK`j=Q^K>6P72_+N21h8b2*vK^TlF z;IHWa07_KYTJl!N(#r2N<7+YD2O&q#{r=R^1oS60Y#_FBL6aqi7#!4jZQ&}-32s>6 zF&P8iqt^tJ@<9r5xSsuc{pskUm7`_|N}$eqU}qo9kG(uCS(_2!LKk-(xXJra8B_zf z9-XMKf?I^Gtg=SZBqh;C<^zxiOq27d^Txvs{vpR0sg~YP0(grlCy>}9jt@@9ns!*D zk`_R*i6S4V7y#p(pL5ftMYf+KOsZ1BNZK>&ibh9#{i;JQ4_s4i8O=(EXpo9JoRR68 zTPVgj$E743K09~fiGeIaWc-Cprh)K|l;X(Bz~|~Ij9};b(T&5tK2#E-XaaQ`Mr0jS z4x*#TGuo0JhfMtFGY~-s8K{Cm?IX4`>qBV%DoJyUaY!Vdr}w2}+C7CB82i$J8O=ue z(v^tdQDbP6xcbpEaZF_AIW$=(y%sH_f?OJOKNT8_CW{{1ByQYsM2>UEN?;NxL5?v| zvF#*>I63J+l6V;V(+bBNngzY6+%2S}8S32oQkM#HO+yUJ$UM~R>FgPSv|EHy2g2YI z4}L`_K4><18kR!Mlfd+;8g-r4seKKFgcDp`O2JhV;w*iIK;ItkiHKCe?87@XO5p99O0MAKhgTh26{D*oQm zHqxw;-sb6T#Ii<0ZFurKsV$xe1P;|ZUY|p`W`fe+^C3qpvUyR0Pe1|x0GN-jO2^sW z&u4Y!xnQiw!;W2X@9UCJT%Nh97IW>qUm-*hG=PKyI03Q;KA%k2&U0r|n{4jKH7%%W zbY;|+MEO{)Wnfv-LcKZQ@B#L~ zIix(dQ-!fcNYdf{B`UkJdzL4TefjOyqiV^h$!g04vooPW3vEKVAE*L)5I$Ub3X7f4 zqx8wkv5Wi5d#SBidMU^9s^(C6V19Mgrtl=U zPa|1hruXFA+>j3A&N4dp#sREXhKc7Q`X-zB z@^PLFkXF|QbS@A1(~uA6LB6rZQT;4f>If z!rw~2yz%zAJZl^+4YXi>kh{qqgr2`@$hvJm=}8Phswbtvl3S$|*?ct_p$)N~cFujk_g@ttt0cExl%;GC3BaNnd{Is+ zDJCgq$l8;Wv~J(UEvZhC8)c1IfE!69l4<-vREWsWO~cl*{vDPBdRkcuZ9-5C;E~%s zyPCMMI1+q8gAM}mpQU+!Siz4B(#ETUucX!G$eWwKO9K-e0NG=nYGsm;z-DK7c#~KQ3LTYJY){vI?;_hxl|&#W~Hdd z6z47y6?x*jZ6+zM^#L3)L~yFD@yW*k4Dx^9O5xrx*RH%vuFtDpaU_QbnaGU?0Y}oJ z>spQ0r+oK!lJAkpJPZXMfOZuCHaV|jp!E3ZR_Dx_<-JGLXR3Qw5kli%h#yXsCNf4k z0rIBfI2i+<*KFk+s70 zWj#kquTh2Mg+;XfP-2>dlWNh~{1a?!zct~#UMOUOb`nPYQdM9BC?_8l0+2d_I%gHm zuApcxW`;#EG)_>X{-J}6R@*|kwA8fso<)XO;rK2>G5+yS2{d4g@pCc;Fv@n63||=5f^IhDS}+uMPa8r>(-C7|tA}{g>RUhRyCL z@~x1}PF+C*^p5AAD|z^Hr&#ItqV71>Yt@Xhxo?IxJp4Rl5IghK)ISYs7Omm&XCEfw% z_h#=;(Bgy^X77vq9OLl^SG&3K4eCc^mIur#=?LVIc{v<)tnQk#2_*|Gk)cz)Ll7H- zjE?-8-Dz-YdhGYw$DIsrCshwT0rsKJKpRNtN2xf#^sMfycw}R39qqAFa_F$EO}G=m zz#M(6y{5|*1%{QRllvTeu#pv~lb&ZlKNhlxquzHX8*wYdXzyJUPp{-TL z<&E4LY!V0jv=D@pmFIc=L^e4cDZB3v+sCJ+{8wgZl{4AhBE$kYzLx#q5Kd^f3B!41Tax0g0dTi0ti7~~GU{=C!$gu9e-Bgb9f@${>q zni)S!vbp1&9Z6AK7?6EWb3)v)e2%>dAR4oiO;H-iZX;B4fI$b5{{Sc?fl=hJySA9` zL9}zbkUe{VMNZJU3(MLF8NsIBFb5re;-&$)0X&mY?o^S-K~9LKMhHhChuV!D{KWy7 zXW{C49^WcZ8OZC!Ck0p)BrxO}O%g*hNAWTcLwoh6b{d&B*%!HlXW3 z*xd?o!tLM+KwQwl0aqv5oC*hO3Id7_*q}U!EsiNYPg+Y7O$Ff6BpIQ|6b}QgDGt~j zc{I2IGBz8nb^idt+3YU-GZmC33wx+0dyB^qw36&z6|g-wU}GQ?oM(~89OUy>{tMS1 zLGc6^nPUlUvZz0)4-7uvxE0U!9W&Hmaf_$_0K6J>nN~cBwZYjnJLo08X(CviV<01< z{1PtER~hTiUcD-^Yqv>~HerT2JBS$PA3Bq%TdWboByOLTXan0$I7t*U5V-(zwC&0N z00`!*ZWW|x)JKxQj-ZAf#C796IIo@L#MJ5ZZp|4+PRo_Mm56^nL~IU0+wpfibHzv( za;h^dm}Ui7>|BN1NFL)Is-2iAEVv2>1oC?0{JYcAG1#s8m5(3+oYs42hUSSES5sa% z{Msy;UJgLUJ;#2%DT5;kRxzrpf!(%~|xf;H!200NJG z0IysB0FLC;OLCKL3+LzTW%Zb8<4z0eef|nJG~NbiGi3UEQci2tS;HRya0X2}gPakM zV^QN~AaVsth1g`|?LBecf-M3-r>1l5QQtiA_orlVNAVF%y8+w!QDBn>00gsBVY5hi z2|3OP>CGfRbInH4Dkj2quwY7&(2COOrKLrf$(K{{f1PCDlQpaGdt1HJLo{yN(+h$| z2)7BOnvGsY$n{L!n+ItKZN!^o$6v*TNRQ>H#D2_%-sA-k&*N`$m%M& zMN>p21f9o$R}UDBNia}bfVc-e#~AhR+OS?Uxw*K%#lvUIK^hG37pTYHwiYsruo=RZ zS7^_sRk8HxS-&3Xt8aA`(##oW1QgHdE05`l?D{0sbz5cKHT#%7QMutwbeW4`pPds1 z+7G@eTf))EL0^b*+MDu(N?usphXf!s>)SX8k!Ns-1Z@(?tT`ld549A_uCWBm42xdNPvRJ zmN=+6!RtceOuwx%WXZ-U*eDVe$jBJxoQ1!=UT||!6rZ4{tyr{!2kK1$jRk*O>*&#HXp%(}GUufRNrfY@f5L(?x$?-cv3lE-Gtwxge{wrB69%%$kg2>&+ZoK1~ z&RJ`E#k&`R>gF69pIy8ztua}4jACnbe_rd)b4zAM?<7-S+*KH=gqr=$ z2Aiv!3t4U9l6JW=$24F#z}QJVd*}A5pAp_ceXKqFNbtzSJ0R#EsUYN@xu*2}V%Auu z{Kc$ZaUTO4WN7;IAgCjZ^OATKai;1Pwzh^>vWo8YoBOtS#Bjv87$HyxXY17C=Sf9I zZzN;O3wu;txJ3ir>JpO4JmrZycQMIh=re=Y_p6;g>iXNt-8Ro87I+;2LdO{ZdViPB zkpPqy=o(=P587FL%wtQ`U9Mk+eenk45aM{e~%TbvmL5z*d!TOB#6-TM+x=ps6H0?Ddzsv7?r&f$8;|m%w z9kZN)*N)XH!^Kw5r?#E1M>YIP!J(a8d6D}Z^&W#YS#~trhht?uoS0F!%sU^BzJu4V z@7B857G5KryIy#w@Xmf$kC|dipXCak-GEtb0lJ0INFFn|fO|0Nq!Es4CDf7ca{w(E zZVL<_wF^tzn>3U1_bIi<#5V2(`i?kZkJLFHwC1aS4c)rP@c9=22Hu;TN)HFO7{+<` z_zNN#`ja2{_>Qri?_6y!wO9 zTBT%m(2?;Ilh1B5NFkTAbI(e2Tgnvvl1E^}KWdW=rt}6`Vp2E(hU1T&Cc$zlMB040 z6r&C}Oqj$RoN}jYlPvWq`+_sekapC8(O$6R9}(SQ0*BtCr!`CX8S! z5J(^%N4_YMNeAhbmz;r|eScw4d%Q8F@=ACWR~v@m)B+7LxDrQ0N9UO~?%J#gJGy86 z<3CeD%N165z7x^LdHVOMC-N#1PrVqy9GYn3wJ1}uIE&+qb4nj7Kr4<-C^r}sStNku zfyFjSr7^`ZBV=Gy8?l5~=NwUI)u|=%%T@%E< zABgGgC8%p#v|lm-5m$~)*}w-Jsq98^lg9@hU2+?S8-eSZ>R*A{)}u6+-X3Yput#ie zZ3D@J3x`tMPi(I5Y~b~;Kk7c29&<(0?W47#)vSqN$s13L@@Q-?V}!{J(Yl!1W@TIk zY@da)I6mIp@lRX6`8MDwTxCaJzh2d8P|`ci34fIJ;CSNyv}S6oRNI=jyyMMbYER065dU=AsWf>H#@hE zzMXq?sHp@|Nwzq^3UYU3oO@@bIbtN5_T?hp>k%7RjzB6KjQskKdMQ~%EXo+;zA^|k zpOweSQiNpFVM{NRBw_HDLc9-Ajw;JYy-2i?5E+#+?udVfBc7S+N3CZrZa0uK@d1Dj zW9vt!-o+!lEu2Te1muC)y-3e*Z>?PjR|f1dP~jE-0E~K#^!N7mZ+7o)v8(w(u%-F< zw)*?mJYnA^v_2}-*HFKa#EKO_MI;3qM`88ms2C6NAJYf~vh@#j5(r`3QMX6BA-d#LYy)QlBWXW6 zW=R{%#y}pKrz8Uz%|(&2PoSk>gf{^5nnvOQ8KpA}ds0*q-7`g!p~&B-71BHpW8`Sd ze&`F_$W}Adguk-e< zcc{j4!6g%+>BG*1#Uv{dGbYkVSbH8fT|?X##3eV-UYz>M_!)Qh=oza=9qs%9tj05URtdQm6~*`(P^WdVhxRUZqv zah}_WC-*1sRDXzq*^i(=sfJQ#W4={IkvL^=hSsBHKss{-LP6KxH9w`q=P2efm|W;tiFZ zmW^c;I1L++3C>&)2|q*p>i+=3MrH8yWX3~afHBJg-G6Guej?tRjb&}Q3jzU*pVWCj z(yzy>%cCZ z`_koL50-@O7$*&poL7Hw&uCDlX0t+k6J z&k}`jz;4e$pL*c>pR7j|c42AB`S?2io#`{pJ=v2{{{XX%_>b`6bPYi+V!js^gaWGL z4jUc&W73(r2voxaYL0p%3}lY=*LB@7H4u@`$8P=GlZ~WSOT>D8wT0Yq%#hBda#(fe z`Ey=pF0UqbrIFi5qh6nf5^4&QIF6-nc?HXUayMBICp_l2`d^2JyWkr;7sMHFI7zoB ztA8+aS_`c%(8SYEXfCbg!n(*eDjuKZRx)|;*k;}}Fvc*dpZ9ByFg-C{4OgpAHYi3a zr5AR(;Khg0mMKb2+Gz9T^^9>{O=?(%ibhS~b;0Y3g*~jXd_xXBM_TC~Ht@~F*E8!7 z%&w(($ru=Q!hlb|O2XX3AdQ$a5WVxodW{yc8mvl5^XKf(FQ~yhIU16$f*LfetGM7V z-jOZAW(s~Fqa609tx!!eEX1m3lD?jlyIAewyNT`)Np7!+K^b7Z&H)+w*2d_eE8vl! z#U1_IKpFutjEK_=Jj0R48RQJNzS29?1_c?0NML#Osd|o)G#3T!UOR*b%!Sb8NWDWS zJ$iCG9t}skl_zmJZrtEAt79R*i}%md6$ndotv(qkMwKulHb5UtRkfypuH8Vh+UVEP z#N4YSZG-Zvi%Y3(E@HWbw!AJKNgM(XdYP(gmwJWSxGWo^+ zpHeC=BjulSfk-L`aDKF|{7@_b;B)U$BqT1}FzcS?nqWyM zIXUZ|w4yS4b3o@EP7i7c2?_utkUy<-f51kH4R=+%c@`&ILlQeKP;Lhx@;eTh=DEQm zo;j}H{hn-=-@*FEv|}6E;YQ~KZYh9@4{%G6Mh{H^>8{qb;;LhrO~C~$H{Jq|r;F0p-W8U;xi*qo9Z z2tYXHha7Xzk;Pe98x2>&W#mn*BCurG3rB|Na!)@G9^CO+`K>&SL_=%{v_Qg7Gbaa* zjKe%0zdomm$qa5>d>Nje)vk=@tE$SAG;v1hBDOcl$-wj(!O8DbpPQCB8dP#*eC~b6 zzi*X0;v1;tyMH9Fl)nUJS7<6dz3P>wAat)~q4fMXv8hTwQ|`|zv1#9qliq&Vll`Zb=kz;l&Sg{H);A4#7@$72b#Tw+YY0DLr!aUo6-Ub(L4ssis z@>%dWNvGNFaAt;FYH{hA{c})Jf3;%@%aQQ#2>$?Lqubuw`SLuDsGe~BcIWN@wvGuB(jb149>6Z=W&NirHj1GjK+*EL2d8VMem~}e1;!?Is{6N+0 zbvv6;Vhbz~?0E{2yzVFM&1C%1yBR!t(k`5|1p1nY7>)tt*RR8lII*ZMk>oN?S!U+@ zXL9hCui?e;oH~Z9tHtJs{I|Cci4lV1A$y(%IK^?jUib5Qg!gVRW|5@EbBvtPLRn+L z3!HLD%|f|lX$}WH{&km2p~t42vL|j|*t<5OSyW=zLWHWz^5{(gFa*;W<0?V-qm6%v z^!2UQQM7zNIpln)#5o-FsK!t*0?_kMPRG)g;MzWT#}y@DVtWvJ;*7$o>JC8f#TFb4 z1Z9Xb3>M{SYb%ykk;&WblZq)o4#x+ROtS+;j;yq_jv41)h!p;H-MkrNr%(8Lk=Zmx z`45>OX!f%m$KlB5fza2Tt>$>84upa~dhFkW+SHO-&G|&%djQVHBm2cYhqyWW*CW=W zDQWILA16oBoME1%yHsfONbYSfWRC9Yb@eJK?mg~Xo(?< zmBtixANtl>_gb>Jy_8--EH{dLu#zqgF_ZCo^!n78qkH*nt+ttWW;Fq~XPkqd^RFE# zH2FuPhFbb#$+bQrvYdI1EQz@WNPWZ-InF!QUsv__D=^JY%g5Pe{49 zoo(c>xK~gWT&7jC?lV>PuuEyECBqQ}OMu6AWQ_MDbQL(oNgBDxw#%bir)k%=_D;oEXgl#8{6Q86~uQJGAMAv2MT&JpKsc+UOdpw zp7P$Inov2H9A;;B?MG;-GlfPzOi5j_Hd={{Rvbfr2*R ze5+rkXUT_A6&J&4GtFxDWybfex;ePG2P?O09&ir^qzBv&#gci=S4838H~?b@H8LQ< zM&pxS_Rl)d{k7E527pL>mOJ)mfJbrYed;aKe|TOtU|aQV#t+_`LVWIc9OvahO0nRE z`qH#IVj4!z#Oz0GntCz{=M@%QE3hM{N_HjOnE-w0u%fE&Q!T?B{3tez(p9nnJ0`^0 zdY*XVos|@h2QT6P18D@|yL-}pv{<%^B++j;p}}6GG@N7jsIc0{ z1My1T?NQE0G_Az*MUQCql^p0t2}YD*9eJ0nAzxuV=@lGr)P%^JBUAI^&& z);c(%W12156qAm<=>V^#5g>OzK}pEZUT7AebP+f?!N;NC*J}J3@e^2hKJ&w~SVeFy z7+gf{A;@UmPQt#0yXU_{isM$wUf~BFbCc4#Pl27K)MnGf>k=)jNxd6x;s)X~>z8Kv zisgEyN`i;aCsWd6{d~g=$B+;x9PRbO7^sOrRm&2N6j1%5o z%@x#;2UL+xNZdgiRZ8_zJwpenqPYgQwUPq_6R&qvi zd($m3>}ok;$NAB-0bT1kN+atl2FPM5#-2h?#=st+9<>i};($E+(y{F&GXkIkp7a6r zG{)cuQV-6Sr-742i)$X<0RyL{FL+VUT47E(+(4z4UUN>xKz7`D=7|^RJxwH)EOGXv z$-?dH=e-1!2SGfJ)Uf0M(xZpsml-GZ z912!FhPS~Qymoi&W|iYtiKDLCB>WVbU3ZeJG*k{rAJePQV^(&vE{ueBH}mGx6+m7Y(k@r-Dw1pdGAT)f$a-`+mvAX zfle&*DE(!z({Rl%UQn&?(zV}* zx3<JX}@fXB8hS=^kd##JmWGDyeQ?$<)YQk`4zLs6s8{M);zdRb|{2DbSc~&C_ zJQ~$4CJ9Gw)W2d2K6NYH{{WM?=sqXAxzrKkog|h9Zy{7{Es=&J(>MaQ4SV^k2`!{1 z+IbMh^QK#2Im(Lju7|E%Y5Ig0GN7GeaK(CV9l`mE={CMN(&VycwMn9IcL+SC+7GTl z{r>=+aCN?$I7xeHw9d|t)Y5}loqv;Ar)dporpswM#_HtmbT~446VFpzr^i}^-<^Fq z-Cd(4OD|>50FPW_HEpYSuIZ!_q~3gM@p)l3s`2i6=lNC=>T_{(EyD~nj#z?yYX1OB z^w~o%yODlBCqG-P$B}KsxCvM(=t-*!d4s3~<*}1h4*BS5P`id4f)A;$M`taf%}7$O~M1&a;TLJOc%VU`c7*Q7Tv3M4N*ibZ zDRMha3kQz0YQP-P0h&-1E=X9gLH__MQuf9v3NStCz%hzsY;k&0Tdrtl0+FA31ek1T zz1X15=}nVL$qtDPC^#aR%^I*%&mx5ED3Ayvr2&pO%`&Vy{?y_z2Y@Mvz3_OnI@C>i zRbf!ysxu&F+IFtcMsnLnQP#S*jC>n?;T?F#eW(kWwHV=ZaIPC@KMr5lArfWspv zid!;~(xU^%G~%%D%{{~@QDS;A9-}nV1Dx;$J&}$-YHh(i0sB$d2?Z48m7nX1OOQz_ z3Xe({ZlqBaJad|jl1T#?>Us3V8pzAQIQJcX^sR^#0tj!PT4;d_K_{G3Qn5HBNQp8tj-Bb?#XnC| z#}yaPBeqATXvNEez)|c*Y3?g=WBa5$oa5$c4%r=P9(kinov2jAjJeKFS}Zn*l1@5P zWctvNgK`EvsUwq1aWxTYdE<&&wrO#|Hx2xcQC60ERQIq;C8ebEBmgw65*FAAz$YC! z;-r}eBC&So;y50|G@!%|c%zynR`^)`Mkx&64k)nfTDZ1IRtaG-Eh4aj66mo;|2&S7pu3>@RA{ssl3+ zxIFFcnyHb1_;L+8tplhIaNV&{=8U6Y^!2D?g2t&aaM*bm&uSn+q#ira1oo>3NSA7M z$^sM59V=hq-8$J-wGCy8SfF4wk-49;<2m&|O3difeqKQ-jxxiN923P))U`Xi*dn!J z7TOY7BVK@>Prq|nbH^;&gm_Q4=k^G^aeJRH;C}N_k>R?tv~{+zoz;p3%Qn%0ll9I$ zYOl$M{{R?$sSKoyWPwTY6aN4hk8QPlAs8x1skZxNR^|#o=|rUW6kr@;fXVlu)4~=A z$678=G(b{-?N5?67Blms+Cb@%>q=2h0n(ijY-9sV3z1HNp4p&6j)V86E3v;Vh&U92 zj6a7o=wPR%10W}^K6I@Qk)SYo;+CTaJ*X4tX(hqU1?MgCdVUl!6aZF`j5-j`Zqrikoi=7X!vqU&02wQm~DHl2323mY760E~>|Bd1Z*uWG!}Z7(HR zR@(E-f*6`bblw3N{a96FfJo071HEE|halvFJJg#?>zjSTH!2&Gw1Mf*OlN`ita^+d z>)jJppHVDJYc3})WM+0PBQY$*sw7L7AYoucAQft05iCd!`M{2JKMWiM3z@l!u>u6#(j-3JDFQ_%8cLgu0NG0 z%Nn#Z!kmWYfg!nG4{=IZEtuh>Y#u%qJW?c$?WHlX+`NEDpAVq3&stKNZ`&v3 zO2PjCTv1@+JcLuqz>H)3sv@x;#ZC!;>cj6+Qb>z~W93G2*goAUETrdP8U9qkoZ|t& zA3908A$H^tImU86)H$G7*y&Oa#KMMS9*5^qo_9U*^u;&kXRq_9Z$+Nl@=YNRN=ZZ+ z8>%|Lu>gC~`GW_7O+Cn48XO@ki$AReREr&wzj_CiIpySTPlS8SpwSvQYEj-!)RsM}6R&#|XLftVf6 zhyMUBN8dFiBDqHV7IBq$%MzIG2^srTTZqDjbZ$KlT5T{6BW7dV;+_cPVZA*ncV$~^ zq8xyO$i`_P;+Hf}87CQEQB86^>J679njBUg>1y8jrZOnO^roaoX#QwsncRJ7w|mpx zg|U(|ib-tKIW$CpOK|oMmd-F~JB=fC0^Zd3k6`-900W9pZ1fcub~{n4dT~badt|`M zMh(}^w*H7)3agF&_f5ypKekIOV=gK{yEM9gu}{V3dkNl-}sRC!b! z09bnVG?ikmq-1l{(i;Qk?ae1DB%@`WlaUE5xo0^nbDDjMj&}@qs%5yDMgtG1rsa2# z=0`2;dQhf_`z^jnmzO(^*qed;K=r7s@1A6n{{V>62NZZTuFE3?xE%}aO4>8qK9sG% z4p(U(Y63t<7@=3$9)y}YEwvkDl0XfE?en56bHStALv1cea3>~) zGfKe&triU`W3(1Mg$_+CX+3&S#yHIs!qALjhaTS;T;q?I(z}m>zW_D;MW&Nmy0_9Jf<;zED=~HIek5!UPW8I+ zH-S6{_<7;GzY?~K{{R<~1PGDb;nRCJ9|7Y4o~I`R=}l23j&*N?%YX3K49mOCDl*13 z$OGq0%L<_QQbKX*$KJHM{{V>fO=@lT4Fo8;+ZC({3~D$S+JFPozH2pfNMn{`^x~OI ze2u~(4t&LR_fm2xQVUV>EV4Ux40HZf9D;kAPSH_iiC>ZPI)jt6`T#LWGlFxqPqshS znJNL`iXsX3rEF>_cw7}30e;!0x02hKv!7PQCmz&3l(}S*LcGET02!o~W1R44#R4-? zV@OXYsiO7fm5flveQ2SHqTB6Gs0zT5)7v!b$+>t{9^_L|BIR8oDIE084*2g*h1_x6 z(}opM@dnKs2fZRUB95FZ=ng2h(X=-R`q2T7f}IF{wB!&pjsP5YIO#^#4rwAjJ*aJ| z62-NcC?pQ}#T0QlzzR-%1sg@V3~eX14Yhk?;mv01;9J}2SJO&!{n}f*Hv=btGt-}y zZ2TwqH{$Jn_86Z}Z8{l{NVDBW>YGo<6Q1}WQ`!nm^p0Rhtr#C_^iux-W$ju^R-JrN zr{O^-bPfm7uwFF$7xAx#uG%rDzNu}3%W+{F%Da8WG7q&SS5`@>C2btgDDp)KupKHqH)yL{v$1tJq5{_OirRuJj`xI>W?XyV!Mxv{{RB-^rcAjyM1F;d8J*m#}q;+<0RxT z-MN?ybAUS4uZKUgZT0S_aUQF!t)-Gk76~JOJd%uLlDn{;olieZr%70Boz)(BDkuf7 zR57S{{{Utf#iN@K6I+{uFCUqNqAY(UVs{U* z^c4;9`6caS_&mL|lf@36xvxRre`bwhIGDrYO)^<=@S%=H1pff$!Twd3)&Bqh{CQ+g zlVxjsxxi>HkZ0)SO-)nigN)Z`r(R2+Cf%jm*Jn7Vt@JHYdzh``vXDt51W?0h$?1}K6sT%eRpT@7CcAlz#{mszJ4^gvqYJ5Nane}_-{{XG{pG=KF_`fcXAye28cJc2?(&dv; zlj$4+fK#7Z^?i@_Wbo7yM7R3Zqaz^=ApsIO2N?r`MtSevrQiPmXFmhaD*jsMR<&P? zDwhh`J%=c9^UW>MCGAY|Kvq4e&nWg#ezoi*`~dJ0T0;@G)I8K(tsuI?N&f&d3}Zhm z3fX9$1n`cLqsODcpy{)~i_hjDNnTG<%)_rV_b&oir2A)sRxkemm!Fvb03%BLu_N?t z{{Y_pn6GPJ{u=%sU6PV`UciJUf4FChX*~5pGxg0?N%%GRZzQB07I>Mk0wvtI9{ja2 zdouYvefd`%2%`L>XOqXbHSAbF1$-A{sKarmwxw#zjmVd$WSBYl!zsu(h9PjBK&i`Z^3OfLyV3_pwY5Kaa< zcCLwUb#SU$RT6*Yr6l`AO4Ut8);E%EQK7EUL zf5K1Jowu^{pJW#AD*#(+g2w~C2Ws}Gh`$ZI39IcB_}p#K2yzS4e~tWK@r{dY-`lTy+zZAk9$uv79l!K*01<0aZN zZEY~@aZNN#I;pE}M|@Eg2d)hiB{qtJ4HgOQR*f88*X>F2qCdiZ^tO}t3fy~8BOR+n zrg(Q#)Z706%XDk&!<-)`29OV)2Nl(P3HTFzs7z(?HOgt0tq^#`1AMH<9}6iT45B~rQd@bP^FZ zC#yC-bXTwuf7zc!QpV%NnuBAYj@br2e4f=Z*ZVy9PAjDI?zMZUkc_XGim&s+ z0td+EyKWGkg!|@<5Eu=de)QCs);N3|hg19m{6D(3*>7omV#A}uc1siTeZ%&w#pm{Q z@bFM!*R>cq#$*vm_24afFC%6de`;x=ib0bapXWlzyr6K4@Oj41`#xv_bz7ekUPz#v z?15v>53e=8(?14038z{|3h9YF%0n4$WNBH5^%)9&SjWz~V7G}d6#ycG#&eycH7)DG z6$tzoyYB$_4&v=?T(80QB!wdP`VmS}lT?dhqwqI`%yDE<7oO-TX`heGjc3`UgQg&f|;G5!mpg54@Ii^=b26f1do+4&n$xm z23&e`Q;shsc21h%5ekDFkNJQfy-?h15zBb?!Wi}_<&)y%c06^b=F`08`24}1+s!9W z(=4>+W`-iH+_N`1@BK|*2*NAmIVmsv1L3a|PcEaaXqL@9z$uWXC15xNk%QCgPk0yb z+rqvNypr=su~)i&4AZxm@s4;xe@|R-*S%>&=Ky0Trxg9PSZHNJqe*b5yrr_U7fa*`yL(QR>pr8xfpT6=VO z=uIblOZ*hlu7R^JefVwQE8A%;?)){Tg_S~=f)Ny)dNSaH?kgdx{{Uy70?VdJEwR-t zrd1_;nfGVYA%Xp|T{`_?y@8-6c*Z~O+i5>hRkn7kro%GDb#m@-+a+;=0pxM>>rAiRjuR*ps)$MGm! z`);oB_><$;@P3Axj8+SK=1H(1$W>sZlEp)97!|}d&&Tfh8)s{TGRgt} z0GYV|0OhFM-$hf7IB?ES;x7*Bx(=fHez9pKozh^mZorTaAn;EIwN?2o{x90DH7o1Q zO8RT-`#7 zGH?F?hS7ij04jg}`qa-Q*pL3N15DY#UBG`jRB-Byx%{*%$48eR$QqN1?#_nDzR{FF zgdc{aapCCk{{Z(h{{Z*Zjj!R~;r)=zUKG8=goo$xXC|)NOQ?<}w2@aFvf+UH z9MYn=hC!I+RyoGdr$1~`abF~qA>j;Z78+iNvZjxvY5H=@g8u-Pfg;{VLUxXElh&QQ z)Fq8nlrym4WR|9zQn3@X2H||fI4g$Ee$XFUn z3l0u5@E`T1CyFJGM%!%ZBja{(xyRF*TWS!MVjKknpNnoN?Pv3knGA0E{yn9?dXtPR zn1y}EZ1s6>U4)CVm!K`4ze<_svYo4f*vK6-Q4g4|u2Mij=r>^e#wl#_GPdZ5Ub)(M z`&1f_ganf;q%beBhfd(oYmK3Bxo_e=wG3Pc*N5ZKDJS_-#lT_!SIOiJgnvqo#1uHf zGrRPKW5^t4ja3&5!1e-*EEhgg5%;FrSM3XD+!~TZT0`tra0F~~=}n!aa9KyW6oqFz zx*+?~S(xx5Q}v-CP@;)}x%Xn7Sz}S~pv@*Yq+$q<{{WQ#0F^)GP5e=D>J-#lUPVJf zUo(KC>rFfnw{g3v10(rVuPuQ6EPa3<=Sh?S*FXF;C-4+Uky&C`#@(y>OEJj$(+bn0 z5~OYJGs*j6mp_Gba}!I`qhz01D;YCF=izC@@gZ_?8Fco&*~Lb0GOK85O3FNtQAMawx~DigWT)kg z5CGJH47vURp7|7BT)}}GNFMZ@kPgN#cHs(rNBUFH8A&T}jh|H+AIhSGa+oixSZ!*YE>~0>FTGL%H$yVd(P3B-uLuc8LUqUJSXbIx)9qD5EK^0iR$68A{9q9I=$rh&Z4>%e5Q8n5grm72` zct2`Sn8mp)7uqw=){kili)Oe}(9%TM91)L7t9c5hell^;DW+q%xhEplL-Rep)g_21 zxSC>A{8%3>(`#@e#&CAOT>&j zntPE&mmkBLRunWMW7i^_NO9O_7ROmhsfcvNh=`egyxNjfn)iCIyOG0mHDRs0L0*WRdVkfl*#T0%{s1B zaGd*!PZ|Nq?h70YpK(opd)EgZ)aLhY3J;|i$i@j6p>fa%%N6b@!m;jYd1K%9quPCF zvCx$vM<$UZ@QzHMLr(d5q?nZd01BU&qk$FIdWFnVe{%xLhq{BGu5pS$TU+TCOUO`6 zqX4UnkCqKhmdTismlDQ*qIQqJe>V#P@{VR zUzJZm_o8b^v-%XDdK4+!0KX?6Wl={V2a74_&MFp+cj+Umzdk;~an}eo-5O1qu{zm&p(d7*ACcKPM18DErW%L!7=q zF=~R8kS}g1P^WB&enN^f0`{Roqim2~LId81ksrMZ6)RvFf-H12MhJ&R`_Q3LwgD_L z4ypE~2;%49=|Y7Tz#Aja=pSkxQW5$`+Jy=&k`Q2z{3Go|ZQ}GlY7{C-uoL-s{pi0g zo~DHgm9i)X*$?qG56dP$Q&6E!*Z|uvbNf&h$HftE6t^*l z0kMik4g%-dg0_KP1m)3;}Er4H@U-24G + + +
IP-Atlas
diff --git a/iplookup/ipatlas/hr.gif b/iplookup/ipatlas/hr.gif new file mode 100644 index 0000000000000000000000000000000000000000..56203a0b1ca32933ed28bec387e0bc2cdb670361 GIT binary patch literal 35 ncmZ?wbhEHbWMp7uXkcJCbLPzd|NnIufB+=Iz{KRj$Y2csuEPjE literal 0 HcmV?d00001 diff --git a/iplookup/ipatlas/ip-atlas.css b/iplookup/ipatlas/ip-atlas.css new file mode 100644 index 00000000000..a00970df6b3 --- /dev/null +++ b/iplookup/ipatlas/ip-atlas.css @@ -0,0 +1,5 @@ +A:link { font-weight: bold; text-decoration: none; color: #005177; } +A:visited { text-decoration: none; color: #005177; font-weight: bold; } +A:hover { text-decoration: underline; } +BODY { font-family: Verdana, Helvetica, Arial, sans-serif; font-size:12px; } +TD { font-family: Verdana, Helvetica, Arial, sans-serif; color: #000000; font-size: 12px; } diff --git a/iplookup/ipatlas/ip-atlas_prefs.php b/iplookup/ipatlas/ip-atlas_prefs.php new file mode 100644 index 00000000000..8c752ae0aa7 --- /dev/null +++ b/iplookup/ipatlas/ip-atlas_prefs.php @@ -0,0 +1,252 @@ +debug > 1) { + error_reporting(E_ALL); +} else { + error_reporting(E_ERROR); +} + +if (isset($HTTP_GET_VARS["lastquery"])){ + $HTTP_GET_VARS["lastquery"] = clean_param($HTTP_GET_VARS["lastquery"], PARAM_HOST); +} + +?> + + + + +<?php echo t("IP-Atlas Preferences") ?> + + + + + + + +

+ +
">"."

"; +} + + +?> + +
" method="POST"> + +

"; + +} else { + + print ""; + +} + +?> + +
+ + + + +
'.t("Shape:").'
".t("Size:")."
".t("Color:")."
+"; + +} elseif($drawmode == "CSS") { + +print t("Pointer:")."
"; + +print ' + + + +'; + +} + +?> + +
+ + + +
+  + +

+"> + +
+[ "> ]

+
+ + diff --git a/iplookup/ipatlas/languages/messages.blank.inc b/iplookup/ipatlas/languages/messages.blank.inc new file mode 100644 index 00000000000..11a5f78b550 --- /dev/null +++ b/iplookup/ipatlas/languages/messages.blank.inc @@ -0,0 +1,182 @@ +.inc. + +please email new language files to ivan@xpenguin.com +copy a language file to messages..inc and \ +edit what $p is on encountering an english phrase. + +please notice the punctuation and capitilization. + +change the $language variable in plotconf.inc after +creating a language file. + +*/ + +function lookup($phrase) { + switch($phrase) { + + # start translating the $p here + + case "Plotting" : + $p = ""; break; + + case "preferences" : + $p = ""; break; + + case "locate me" : + $p = ""; break; + + case "IP/Hostname:" : + $p = ""; break; + + case "You at" : + $p = ""; break; + + case "Submit" : + $p = ""; break; + + case "main" : + $p = ""; break; + +# Used in context "(host) is located in" + case "is" : + $p = ""; break; + +# Used in context "You at (host) are located in" + case "are" : + $p = ""; break; + + case "located in" : + $p = ""; break; + + case "cannot be located." : + $p = ""; break; + + case "cannot be resolved." : + $p = ""; break; + + case "is a host in the private IP address range." : + $p = ""; break; + + case "does not resolve." : + $p = ""; break; + + case "is not a valid IP address." : + $p = ""; break; + + case "Temporary lookup failure." : + $p = ""; break; + + case "IP-Atlas Preferences" : + $p = ""; break; + +# make the 'p' lowercase if possible in your language + + case "IP-Atlas preferences" : + $p = ""; break; + + case "(cookie based)" : + $p = ""; break; + + case "Draw mode (defaults guessed for your browser):" : + $p = ""; break; + + // next two phrases are combined + case "Your settings have been saved. You can now try" : + $p = ""; break; + + case "plotting something." : + $p = ""; break; + + case "Pointer Preferences (the dot that marks lat/lon):" : + $p = ""; break; + + case "Shape:" : + $p = ""; break; + + case "Size:" : + $p = ""; break; + + case "Color:" : + $p = ""; break; + + case "Pointer:" : + $p = ""; break; + + case "Other Preferences:" : + $p = ""; break; + + case "Earth Image:" : + $p = ""; break; + + case "Color" : + $p = ""; break; + + case "Grayscale" : + $p = ""; break; + + case "Save" : + $p = ""; break; + +# shape names: + case "Diamond" : + $p = ""; break; + + case "Diamond Outline" : + $p = ""; break; + + case "Square" : + $p = ""; break; + + case "Square Outline" : + $p = ""; break; + + case "Cross" : + $p = ""; break; + +# colors: + + case "red" : + $p = ""; break; + + case "white" : + $p = ""; break; + + case "yellow" : + $p = ""; break; + + case "magenta" : + $p = ""; break; + + case "cyan" : + $p = ""; break; + + case "green" : + $p = ""; break; + + case "violet" : + $p = ""; break; + + # stop here + + // return in english if the phrase couldn't be found + default: + $p = $phrase; break; + + + } + + // return english if match was blank + if($p == "") { $p = $phrase; } + + return $p; + +} + +?> diff --git a/iplookup/ipatlas/languages/messages.it.inc b/iplookup/ipatlas/languages/messages.it.inc new file mode 100644 index 00000000000..b460ffddb05 --- /dev/null +++ b/iplookup/ipatlas/languages/messages.it.inc @@ -0,0 +1,185 @@ +.inc and \ +edit what $p is on encountering an english phrase. + +you can start off with messages.blank.inc + +please notice the punctuation and capitilization. + +change the $language variable in plotconf.inc after +creating a language file. + +*/ + +function lookup($phrase) { + switch($phrase) { + + # start translating the $p here + + case "Plotting" : + $p = "Mappa di"; break; + + case "preferences" : + $p = "preferenze"; break; + + case "locate me" : + $p = "localizzami"; break; + + case "IP/Hostname:" : + $p = "IP/Nome host:"; break; + + case "You at" : + $p = "Tu"; break; + + case "Submit" : + $p = ""; break; + + case "main" : + $p = ""; break; + +# Used in context "(host) is located in" + case "is" : + $p = "è"; break; + +# Used in context "You at (host) are located in" + case "are" : + $p = "sei"; break; + + case "located in" : + $p = "stato localizzato in"; break; + + case "cannot be located." : + $p = "non può essere localizzato."; break; + + case "cannot be resolved." : + $p = "non può essere risolto."; break; + + case "is a host in the private IP address range." : + $p = "è un host in un range di IP privati."; break; + + case "does not resolve." : + $p = "irrisolvibile."; break; + + case "is not a valid IP address." : + $p = "non è un indirizzo IP valido."; break; + + case "Temporary lookup failure." : + $p = "Errore temporaneo di lookup."; break; + + case "IP-Atlas Preferences" : + $p = "Preferenze IP-Atlas"; break; + +# make the 'p' lowercase if possible in your language + + case "IP-Atlas preferences" : + $p = "Preferenze IP-Atlas"; break; + + case "(cookie based)" : + $p = "(basato su cookie)"; break; + + case "Draw mode (defaults guessed for your browser):" : + $p = ""; break; + + // next two phrases are combined + case "Your settings have been saved. You can now try" : + $p = "Le tue impostazioni sono state salvate "; break; + + case "plotting something." : + $p = "torna indietro."; break; + + case "Pointer Preferences (the dot that marks lat/lon):" : + $p = "Preferenze puntatore (il simbolo che indica la lat/lon):"; break; + + case "Shape:" : + $p = "Forma:"; break; + + case "Size:" : + $p = "Dimensione:"; break; + + case "Color:" : + $p = "Colore:"; break; + + case "Pointer:" : + $p = "Puntatore:"; break; + +# any help here? + + case "Other Preferences:" : + $p = ""; break; + + case "Earth Image:" : + $p = ""; break; + + case "Color" : + $p = "Colore"; break; + + case "Grayscale" : + $p = ""; break; + + case "Save" : + $p = ""; break; + +# shape names: + case "Diamond" : + $p = ""; break; + + case "Diamond Outline" : + $p = ""; break; + + case "Square" : + $p = ""; break; + + case "Square Outline" : + $p = ""; break; + + case "Cross" : + $p = ""; break; + +# colors: + + case "red" : + $p = ""; break; + + case "white" : + $p = ""; break; + + case "yellow" : + $p = ""; break; + + case "magenta" : + $p = ""; break; + + case "cyan" : + $p = ""; break; + + case "green" : + $p = ""; break; + + case "violet" : + $p = ""; break; + + # stop here + + // return in english if the phrase couldn't be found + default: + $p = $phrase; break; + + + } + + if($p == "") { $p = $phrase; } + + return $p; + +} + +?> diff --git a/iplookup/ipatlas/lib.php b/iplookup/ipatlas/lib.php new file mode 100644 index 00000000000..2d64512c664 --- /dev/null +++ b/iplookup/ipatlas/lib.php @@ -0,0 +1,13 @@ +wwwroot.'/iplookup/ipatlas/plot.php?address='.$ip.'&user='.$user); +} + +?> diff --git a/iplookup/ipatlas/plot.inc b/iplookup/ipatlas/plot.inc new file mode 100644 index 00000000000..32aaac9d460 --- /dev/null +++ b/iplookup/ipatlas/plot.inc @@ -0,0 +1,398 @@ + 15) and ($part[2] < 32)) { + return TRUE; + } + } + + return FALSE; + +} + +function stuffanalyze($stuff) { + +$stuff2[0] = array_values(preg_grep ("/CITY:/", $stuff)) or die("Sorry, but the lookup for this IP address failed! (CITY)"); +$stuff2[1] = array_values(preg_grep ("/STATE:/", $stuff)) or die("Sorry, but the lookup for this IP address failed! (STATE)"); +$stuff2[2] = array_values(preg_grep ("/COUNTRY:/", $stuff)) or die("Sorry, but the lookup for this IP address failed! (COUNTRY)"); +$stuff2[3] = array_values(preg_grep ("/LAT:/", $stuff)) or die("Sorry, but the lookup for this IP address failed! (LAT)"); +$stuff2[4] = array_values(preg_grep ("/LONG:/", $stuff)) or die("Sorry, but the lookup for this IP address failed! (LONG)"); + +// all the stuff2 values are actually arrays, making the following code look like crap + +// the power of $count + + if(isset($stuff2[0][0])) { + +for ($count = 0; $count < count($stuff2); $count++) { + $stuff2[$count] = $stuff2[$count][0]; + $stuff2[$count] = ucwords(strtolower(trim(substr(substr($stuff2[$count], 15), 0, -5)))); +} + + } else { + + // if no data was found + $stuff2 = array("bad", "bad", "bad", "bad", "bad"); + + } + +$count = 0; + + return $stuff2; + +} + +function getlatdata($ip) { + +global $firewall_host; +global $firewall_port; +global $use_firewall; + + + $data = array(""); + +if ($use_firewall) { + + $fp = fsockopen ($firewall_host, $firewall_port, $errno, $errstr, 30) or die("Could not open socket to proxy"); + if (!$fp) { + echo "$errstr ($errno)
\n"; + } else { + fputs ($fp, "GET http://netgeo.caida.org/perl/netgeo.cgi?target=$ip HTTP/1.0\r\nHost: netgeo.caida.org\r\n\r\n") or die("Could not write to socket"); + while (!feof($fp)) { + $packet = fgets ($fp,128) or die("Could not read from socket"); + array_push($data, $packet) or die("Could not push data into array"); + } + fclose ($fp); + } + +} else { + +$fp = fsockopen ("netgeo.caida.org", 80, $errno, $errstr, 30) or die("Could not open socket to caida.org"); +if (!$fp) { + echo "$errstr ($errno)
\n"; +} else { + fputs ($fp, "GET /perl/netgeo.cgi?target=$ip HTTP/1.0\r\nHost: netgeo.caida.org\r\n\r\n") or die("Could not write to socket"); + while (!feof($fp)) { + $packet = fgets ($fp,128) or die("Could not read from socket"); + array_push($data, $packet) or die("Could not push socket data into array"); + } + fclose ($fp); +} + +} + + // make it an array + +return $data; + +} + +function finddot($name, $cssdots, $defaultdot) { + foreach($cssdots as $x) { + list($filename, , $width, $height) = split(":", $x); + if($filename == $name) { $found = 1; $return = array($name, $width, $height); } + } +if(isset($found)) { +return $return; +} else { +$dott = $cssdots[$defaultdot]; +list($dott, , $width, $height) = split(":", $dott); +return array($dott, $width, $height); +} +} + +function getlocationcoords($lat, $lon, $width, $height) { + // some cartographers weren't mathematicians, up is apparently negative to them + $lat = ($lat * -1); + + $lat = ($lat + 90); + $lon = ($lon + 180); + $x = ($lon * ($width / 360)); + $y = ($lat * ($height / 180)); + + $x = round($x); + $y = round($y); + return array($x, $y); +} + +function getimagecoords($earthimages, $image) { + foreach($earthimages as $x) { + list($file, , $width, $height) = split(":", $x); + if($file == $image) { + $coords = array("$width", "$height"); + return $coords; + } + } +} + +function validcookie($cookie) { + if(preg_match("/.*.:.*.:.*.:.*.:.*./", $cookie)) { + return TRUE; + } else { + return FALSE; + } +} + +function isvalidimage($cookie, $earthimages, $defaultimage) { +# list(, , , $setearthimage) = split(":", $cookie); + $setearthimage = $cookie; + if(isset($setearthimage)) { + // check if the image is one actually defined, not a cookie edit + foreach($earthimages as $image) { + list($testearthimage, , , ) = split(":", $image); + if($testearthimage == $setearthimage) { + $found = 1; + } + } + if(isset($found)) { + return $setearthimage; + } else { + return $earthimages[$defaultimage]; + } + } else { + return $earthimages[$defaultimage]; + } +} + + + +function istheregd() { + global $trygd; + if($trygd == 1) { + if (@ImageTypes() & IMG_PNG) { + return TRUE; + } else { + return FALSE; + } + } else { + return FALSE; + } +} + +function checkbrowser($agent) { + if (strstr($agent, "Mozilla/4.7") || strstr($agent, "Opera 6") || strstr($agent, "Opera/6")) { + return FALSE; + } else { + return TRUE; + } +} + +function shouldrun($agent) { + + // could cause probs... dunno + global $HTTP_COOKIE_VARS; + + // check for new format of cookie with 6 parameters + if(@preg_match("/.*.:.*.:.*.:.*.:.*.:.*./", $HTTP_COOKIE_VARS["atlasprefs"])) { + list( , , , , , $drawmode) = split(":", $HTTP_COOKIE_VARS["atlasprefs"]); + } else { + $drawmode = ""; + } + + // don't try to understand below, it figures out whether + // to run it in css or gd based of prefs, server ability, and user agent. + + if(istheregd() && ($drawmode == "1")) { + return TRUE; + } elseif($drawmode == "0") { + return FALSE; + } elseif(checkbrowser($agent) && istheregd()) { + return TRUE; + } elseif(!checkbrowser($agent)) { + return FALSE; + } elseif (!istheregd()) { + return FALSE; + } + + +} + +function s10_validate_ip($in) { + if (is_string($in) && ereg('^([0-9]{1,3})\.([0-9]{1,3})\.' . + '([0-9]{1,3})\.([0-9]{1,3})$' , + $in, $part)) { + if ($part[1] <= 255 && $part[2] <= 255 && + $part[3] <= 255 && $part[4] <= 255) + return TRUE; + } + return FALSE; + } + +function getstuff($address, $local) { + + $address = trim($address); + +# some people still think that urls are hostnames +$address = str_replace("http://", "", $address); +$address = preg_replace("/\/.*$/", "", $address); + +// Security checks +$address = escapeshellcmd($address); + +$values = array(); + +$values["address"] = $address; + +if(eregi("[a-z]", $address)){ +$ipaddress = gethostbyname($address); + + if($ipaddress == $address) { + +$values["validity"] = "no"; + + } + +$values["hostname"] = $address; + +$values["ishost"] = "yes"; + +} else { + +if(s10_validate_ip($address)) { + +$ipaddress = $address; + $values["hostname"] = ""; +} else { +$values["validity"] = "no"; +} + +} + + if(!isset($values["validity"])) { + if(s10_rfc_1918_ip($ipaddress)) { + $private = "yes"; + } else { + $private = "no"; + } + } else { + $private = "no"; + } + + if(!isset($ipaddress)) { $ipaddress = ""; } + +$values["ipaddress"] = $ipaddress; + +if(!isset($values["validity"]) && ($private == "no")) { + +$stuff = getlatdata($ipaddress); + +list( + + $values["city"], + $values["state"], + $values["country"], + $values["lat"], + $values["lon"] + +) = stuffanalyze($stuff); + +$desc = ""; + +// check if it is the user's ip address +if($local == 1) { $desc .= t("You at"); } + +// add the ip address and hostname +$desc .= "$values[hostname] ($values[ipaddress]) "; + +// use "are" if it is the user's ip address +if($local == 1) { $desc .= t("are"); } else { $desc .= t("is"); } + +$desc .= " ".t("located in")." "; + +// add the city if it's there +if($values["city"]) { +$desc .= "$values[city], "; +} + +// add the state if its there +if($values["state"]) { +$desc .= "$values[state], "; +} + +if($values["country"]) { +// make the country code capital so its ready for lookup +$values["country"] = strtoupper($values["country"]); +// convert the country code to a country name +$countries = file("countries.txt") or die("Could not open countries file"); +$precountry = array_values(preg_grep("/$values[country] /", $countries)); +$values["country"] = trim(substr($precountry[0], 4)); +$desc .= "$values[country]."; +} + + $desc .= " ($values[lat], $values[lon])"; + + $state = $values["state"]; + $city = $values["city"]; + +// decide if address can't resolve, be located, or if it's fine +if($values["lat"] == "0.00" && $values["lon"] == "0.00" && (@($state != "bad" && $city != "bad"))) { + $values["desc"] = "$values[address] ".t("cannot be located."); +$values["lat"] = ""; +$values["lon"] = ""; +} elseif($values["lat"] == "" && $values["lon"] == "") { + $values["desc"] = "$values[address] ".t("cannot be located."); +} else { +$values["desc"] = $desc; +} + +} else { + +// check if it was a host before and decide on an error message + +if($private == "yes") { + $values["desc"] = "$address ".t("is a host in the private IP address range."); +} elseif(@($values["state"] == "bad" && $values["city"] == "bad")) { +$values["desc"] = t("Temporary lookup failure."); +} elseif(isset($values["ishost"])) { +$values["desc"] = "$address ".t("does not resolve."); +} else { +$values["desc"] = "$address ".t("is not a valid IP address."); +} + +// some blank lat/lon for the image script or it will plot us in the center +$values["lon"] = ""; +$values["lat"] = ""; + +} + +return($values); +} + +?> diff --git a/iplookup/ipatlas/plot.php b/iplookup/ipatlas/plot.php new file mode 100644 index 00000000000..721d88aa498 --- /dev/null +++ b/iplookup/ipatlas/plot.php @@ -0,0 +1,145 @@ +$fullname [$user->city, $user->country] : "; +} else { + $username = ""; +} + +if ($CFG->debug > 1) { +error_reporting(E_ALL); +} else { +error_reporting(E_ERROR); +} + +// cleanup +if (isset($HTTP_GET_VARS["lastquery"])) { + $HTTP_GET_VARS["lastquery"] = clean_param($HTTP_GET_VARS["lastquery"], PARAM_HOST); +} + +// check if it is the user's ip, or another host + +if(!isset($HTTP_GET_VARS["address"]) || ($HTTP_GET_VARS["address"] == "")) { + $address = $HTTP_SERVER_VARS['REMOTE_ADDR']; + $local = 1; +} else { + $HTTP_GET_VARS["address"] = clean_param($HTTP_GET_VARS["address"], PARAM_HOST); + $address = $HTTP_GET_VARS["address"]; + $local = 0; +} + +// this is the most important function, gets lat/lon and description of location +$values = getstuff($address, $local) or die("Error in plot.inc"); + +if(isset($logging) && is_writable("plotlog.txt")) { + $log = @fopen("plotlog.txt", "a") or print ""; + @fputs($log, $HTTP_SERVER_VARS["REMOTE_ADDR"] ."\t". date("F j, Y, g:i a") . "\t$address\t$values[address]\t$values[lat]\t$values[lon]\n") or print ""; +@fclose($log); +} + +if(isset($HTTP_COOKIE_VARS["atlasprefs"]) && validcookie($HTTP_COOKIE_VARS["atlasprefs"])) { +list( , , , $imagething) = split(":", $HTTP_COOKIE_VARS["atlasprefs"]); +$imagething = clean_param($imagething, PARAM_FILE); +$earthimage = isvalidimage($imagething, $earthimages, $defaultimage); +} else { +$earthimage = $earthimages[$defaultimage]; +} + +if(strstr($earthimage, ":")) { + list($earthimage, , , ) = split(":", $earthimage); +} + +// check if we need to run it in css mode +if(!shouldrun($HTTP_SERVER_VARS['HTTP_USER_AGENT'])) { + +list($width, $height) = getimagecoords($earthimages, $earthimage); + + // make sure some coords were found + if($values["lat"] == "" || $values["lon"] == "") { + + $display = " "; + $extracss = ""; + +} else { + +list($x, $y) = getlocationcoords($values["lat"], $values["lon"], $width, $height); + +if(isset($HTTP_COOKIE_VARS["atlasprefs"])) { +list( , , , , $dotname) = split(":", $HTTP_COOKIE_VARS["atlasprefs"]); +$dotname = clean_param($dotname, PARAM_FILE); +list($thedot, $dotwidth, $dotheight) = finddot($dotname, $cssdots, $defaultdot); +} else { +$dotname = $cssdots[$defaultdot]; +list($dotname, , , ) = split(":", $dotname); +$dotname = clean_param($dotname, PARAM_FILE); +list($thedot, $dotwidth, $dotheight) = finddot($dotname, $cssdots, $defaultdot); +} + +// magical formula for placing the css dot +$x = ($x - floor($dotwidth / 2)); +$y = ($y - floor($dotheight / 2)); + +$extracss = ""; +$display = "
"; + + } + +} else { + + // gd mode + +list($width, $height) = getimagecoords($earthimages, $earthimage) or die("Unable to find width/height for image $earthimage in config file"); +$extracss = ""; +$display = "\"\""; + +} + +# START HTML + +print ' + +'.t("Plotting").' '.$values["address"].' +'.$extracss.' + + + + + + + + +
'.$display.'
+ + +
+'; + +if(isset($address)) { +print "$username $values[desc]"; +} + +$PHP_SELF = 'plot.php'; + +print ' +

+ +
+'.t("IP/Hostname:").' +[ '.t("preferences").' ] +[ '.t("locate me").' ] +
+ +'; + +include("footer.inc"); + +print ""; + +?> diff --git a/iplookup/ipatlas/plotconf.inc b/iplookup/ipatlas/plotconf.inc new file mode 100644 index 00000000000..c627e9709b2 --- /dev/null +++ b/iplookup/ipatlas/plotconf.inc @@ -0,0 +1,61 @@ +gdversion == 1 or $CFG->gdversion == 2) { + $trygd = "1"; +} else { + $trygd = "0"; +} + +# language (look in language/ dir for language files) +$language = "en"; global $language; + +include("translate.inc"); + +# display warnings? set to "0" if there are warnings +# on the screen. report these to ivan@xpenguin.com so +# this option will become unnessessary. +$warnings = "1"; + +# earth images +# url path:name:width:height +# everything must be accurate! +# take new image names out of the t() + +$earthimages = array(); +$earthimages[0] = "earth_620.jpg:".t("Color").":620:310"; + +# which image out of those is the default? +$defaultimage = 0; + +# css dots for netscape 4 users and systems without GD +# url path:name:width:height +$cssdots = array(); +$cssdots[0] = "reddot.gif:Red 7x7:7:7"; +$cssdots[1] = "yellowdot.gif:Yellow 7x7:7:7"; +$defaultdot = 0; + +# block user agents "libwww-perl" "lwp-trivial" "LWP::Simple" "PHP/" +$blockbadagents = 1; + +# log entries? comment the line to disable. +$logging = "yes"; + +# path to the cookie +$cookiepath = "/"; + +# set $use_firewall to "1" if behind a proxy +if ($CFG->proxyhost and $CFG->proxyport) { + $use_firewall="1"; + $firewall_host=$CFG->proxyhost; + $firewall_port=$CFG->proxyport; +} else { + $use_firewall=""; + $firewall_host="localhost"; + $firewall_port=3128; +} + +?> diff --git a/iplookup/ipatlas/plotimage.php b/iplookup/ipatlas/plotimage.php new file mode 100644 index 00000000000..3ceecb01939 --- /dev/null +++ b/iplookup/ipatlas/plotimage.php @@ -0,0 +1,91 @@ + 8 || $setsize < 2) { + $setsize = 2; +} + +$im = @ImageCreate ($width, $height) + or die ("Cannot Initialize new GD image stream"); +$background_color = ImageColorAllocate ($im, 255, 255, 255); + + +// color table +if($setcolor == "red") { $r = "255"; $g = "0"; $b = "0"; } +elseif($setcolor == "white") { $r = "255"; $g = "255"; $b = "254"; } +elseif($setcolor == "yellow") { $r = "255"; $g = "255"; $b = "0"; } +elseif($setcolor == "magenta") { $r = "255"; $g = "0"; $b = "255"; } +elseif($setcolor == "cyan") { $r = "0"; $g = "255"; $b = "255"; } +elseif($setcolor == "green") { $r = "0"; $g = "225"; $b = "0"; } +elseif($setcolor == "violet") { $r = "191"; $g = "0"; $b = "255"; } +else { $r = "255"; $g = "0"; $b = "0"; } + +$loc_color = ImageColorAllocate ($im, $r, $g, $b); + +if($lat == "" && $lon == "") { } else { + +list($x, $y) = getlocationcoords($lat, $lon, $width, $height); + +if($setshape == "Diamond") { + ImageLine($im, ($x - $setsize), $y, $x, ($y + $setsize), $loc_color); + ImageLine($im, ($x - $setsize), $y, $x, ($y - $setsize), $loc_color); + ImageLine($im, ($x + $setsize), $y, $x, ($y + $setsize), $loc_color); + ImageLine($im, ($x + $setsize), $y, $x, ($y - $setsize), $loc_color); + ImageFill($im, $x, $y, $loc_color); +} elseif($setshape == "Diamond Outline") { + ImageLine($im, ($x - $setsize), $y, $x, ($y + $setsize), $loc_color); + ImageLine($im, ($x - $setsize), $y, $x, ($y - $setsize), $loc_color); + ImageLine($im, ($x + $setsize), $y, $x, ($y + $setsize), $loc_color); + ImageLine($im, ($x + $setsize), $y, $x, ($y - $setsize), $loc_color); +} elseif($setshape == "Square") { + ImageFilledRectangle($im, ($x - $setsize), ($y - $setsize), ($x + $setsize), ($y + $setsize), $loc_color); +} elseif($setshape == "Square Outline") { + ImageRectangle($im, ($x - $setsize), ($y - $setsize), ($x + $setsize), ($y + $setsize), $loc_color); +} elseif($setshape == "Cross") { + ImageLine($im, ($x - $setsize), $y, ($x + $setsize), $y, $loc_color); + ImageLine($im, $x, ($y - $setsize), $x, ($y + $setsize), $loc_color); +} else { +// draw a diamond if error + ImageLine($im, ($x - $setsize), $y, $x, ($y + $setsize), $loc_color); + ImageLine($im, ($x - $setsize), $y, $x, ($y - $setsize), $loc_color); + ImageLine($im, ($x + $setsize), $y, $x, ($y + $setsize), $loc_color); + ImageLine($im, ($x + $setsize), $y, $x, ($y - $setsize), $loc_color); + ImageFill($im, $x, $y, $loc_color); +} + +} + + +ImageColorTransparent ($im, $background_color); +Header("Pragma: no-cache"); +Header("Expires: Thu, 26-Oct-1972 12:00:00"); +Header("Content-type: image/png"); +ImagePng ($im); +ImageDestroy($im); + + +?> diff --git a/iplookup/ipatlas/plotlog.txt b/iplookup/ipatlas/plotlog.txt new file mode 100644 index 00000000000..7259e3fd14e --- /dev/null +++ b/iplookup/ipatlas/plotlog.txt @@ -0,0 +1,13 @@ +192.168.19.1 August 26, 2002, 4:45 pm 192.168.19.1 192.168.19.1 +192.168.19.1 August 26, 2002, 4:45 pm dougiamas.com dougiamas.com -31.97 115.82 +192.168.19.1 August 26, 2002, 4:46 pm dougiamas.com dougiamas.com -31.97 115.82 +192.168.19.1 August 26, 2002, 4:46 pm 192.168.19.1 192.168.19.1 +192.168.19.1 August 26, 2002, 4:48 pm hungry.com hungry.com 46.73 -116.99 +192.168.19.1 August 26, 2002, 4:50 pm yahoo.com yahoo.com 37.40 -122.00 +192.168.19.1 August 26, 2002, 4:55 pm 192.168.19.1 192.168.19.1 +192.168.19.1 August 26, 2002, 4:55 pm 192.168.19.1 192.168.19.1 +192.168.19.1 August 26, 2002, 4:56 pm hungry.com hungry.com 46.73 -116.99 +192.168.19.1 August 26, 2002, 4:56 pm hungry.com hungry.com 46.73 -116.99 +192.168.19.1 August 26, 2002, 4:56 pm washington.com washington.com +192.168.19.1 August 26, 2002, 4:56 pm amazon.com amazon.com 47.55 -122.31 +192.168.19.1 August 26, 2002, 4:57 pm nytimes.com nytimes.com 37.40 -122.00 diff --git a/iplookup/ipatlas/reddot.gif b/iplookup/ipatlas/reddot.gif new file mode 100644 index 0000000000000000000000000000000000000000..680195710307eaf174e36641978b718cebd20264 GIT binary patch literal 53 zcmZ?wbhEHbWM^P!XkcLY4@Cd}EB<6*eGD8F72u_xfrYg DQC17^ literal 0 HcmV?d00001 diff --git a/iplookup/ipatlas/translate.inc b/iplookup/ipatlas/translate.inc new file mode 100644 index 00000000000..7b9197190fe --- /dev/null +++ b/iplookup/ipatlas/translate.inc @@ -0,0 +1,14 @@ + \ No newline at end of file diff --git a/iplookup/ipatlas/yellowdot.gif b/iplookup/ipatlas/yellowdot.gif new file mode 100644 index 0000000000000000000000000000000000000000..b43029def79f6b1579c29f6c18899e344bbc9ee2 GIT binary patch literal 53 zcmZ?wbhEHbWM^P!XkcLY{~w6{EB<6*eGD8F72u_xfrYg DcrOg^ literal 0 HcmV?d00001